diff --git a/one-and-half-nibble/Backend/README.md b/one-and-half-nibble/Backend/README.md new file mode 100644 index 00000000..300c862d --- /dev/null +++ b/one-and-half-nibble/Backend/README.md @@ -0,0 +1 @@ +#This is Backend \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/.gitignore b/one-and-half-nibble/Backend/fanex-admin-app/.gitignore new file mode 100644 index 00000000..5a77255e --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/.gitignore @@ -0,0 +1,2 @@ +flow.json +.env \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/README.md b/one-and-half-nibble/Backend/fanex-admin-app/README.md new file mode 100644 index 00000000..dcd88552 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/README.md @@ -0,0 +1,10 @@ +# Flas app for admin panel of Dapp Rewards(Fanex) + +## create virtual env +- `virtualenv -p python3 venv` +- `source /venv/bin/activate` +## install flow cli (mac) +- `brew install flow-cli` +## run flask project port 5000 +- `python run.py` + diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/__init__.py b/one-and-half-nibble/Backend/fanex-admin-app/app/__init__.py new file mode 100644 index 00000000..e6ccfd13 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/__init__.py @@ -0,0 +1,11 @@ +import os +from flask import Flask + +project_dir = os.path.dirname(os.path.abspath(__file__)) + +app = Flask(__name__) + + +from app.rewards.controller import * +from app.social_rewards.controller import * +from app.airdrop.controller import * diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/__init__.py b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/controller.py b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/controller.py new file mode 100644 index 00000000..37db96da --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/controller.py @@ -0,0 +1,30 @@ + +from flask import Response, request +from app.airdrop.service import AirDropService +from flask_restful import Resource, Api +from app import app +import json +from http import HTTPStatus + +api = Api(app) + +@api.resource('/airdrop') +class AirDropController(Resource): + def post(self): + request_json = request.json + print('airdrop request: ', request_json) + + response = AirDropService().assign_token_to_wallet(request_json) + error_msg = { + "status": "error" + } + if response: + + return Response( + response=json.dumps(response,sort_keys=True, default=str), + status=HTTPStatus.OK, + content_type='application/json') + else: + return Response(response=json.dumps(error_msg), + status=HTTPStatus.NOT_FOUND, + content_type='application/json') diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/models.py b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/models.py new file mode 100644 index 00000000..b95187fe --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/models.py @@ -0,0 +1,16 @@ +from datetime import datetime +from app.db.mongo_db import MongoAPI +from bson.objectid import ObjectId +import uuid + +db_data = { + "collection": "airdrop_audit" +} +class AirDropAudit: + + def create(self, data): + + mongo_api = MongoAPI(db_data) + + response = mongo_api.write(data) + return response \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/service.py b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/service.py new file mode 100644 index 00000000..6a28c771 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/airdrop/service.py @@ -0,0 +1,50 @@ + +from app.airdrop.models import AirDropAudit +import subprocess +from datetime import datetime + +db_data = { + "collection": "airdrop" +} + +flow_cmd = """flow transactions send /Users/livspace/Documents/web3/Dapp-Rewards/SmartContract/transactions/add-token-to-vault.cdc {no_of_token} {wallet_address} --authorizer "my-testnet-account" --gas-limit 50 --payer "my-testnet-account" --proposer "my-testnet-account" -n testnet -f /Users/livspace/Documents/web3/Dapp-Rewards/backend/fanex-admin-app/flow.json""" + +class AirDropService: + def audit_airdrop(self, data): + audit = AirDropAudit().create({"Document":data}) + print('audit log:', audit) + return + + def run_flow_cmd(self, flow_cmd): + """ + add token to wallet + cmd to run flow API from cli + """ + print('start flow cmd: ', datetime.now()) + p1 = subprocess.run([flow_cmd], shell=True) + print('end flow cmd: ', datetime.now()) + + print(p1) + + def assign_token_to_wallet(self, request_data): + + wallet_address = request_data["wallet_address"] + no_of_token = request_data["no_of_token"] + + try: + + # audit log + self.audit_airdrop(request_data) + + flow_cmd_modified = flow_cmd.format(no_of_token=no_of_token, wallet_address=wallet_address) + + # call SDK + self.run_flow_cmd(flow_cmd_modified) + + except Exception as e: + print('Exception in assign_token_to_wallet: ', e) + return + + return { + "status": "success" + } diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/db/__init__.py b/one-and-half-nibble/Backend/fanex-admin-app/app/db/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/db/mongo_db.py b/one-and-half-nibble/Backend/fanex-admin-app/app/db/mongo_db.py new file mode 100644 index 00000000..a63c14be --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/db/mongo_db.py @@ -0,0 +1,53 @@ +# from logging import log +from pymongo import MongoClient +from settings import MONGO_URI, DB_NAME +import datetime +class MongoAPI: + def __init__(self, data): + self.client = MongoClient(MONGO_URI) + + database = DB_NAME + collection = data['collection'] + cursor = self.client[database] + self.collection = cursor[collection] + self.data = data + + + def delete(self, data): + filt = data['Document'] + response = self.collection.delete_one(filt) + output = {'Status': 'Successfully Deleted' if response.deleted_count > 0 else "Document not found."} + return output + + def update(self): + filt = self.data['Filter'] + updated_data = {"$set": self.data['DataToBeUpdated']} + response = self.collection.update_one(filt, updated_data) + output = {'Status': 'Successfully Updated' if response.modified_count > 0 else "Nothing was updated."} + return output + + def read_all(self, filter=None): + if filter: + print(filter) + documents = self.collection.find(filter) + + else: + documents = self.collection.find() + + list_documents = list(documents) + return list_documents + + def read(self): + documents = self.collection.find() + print(documents) + output = [{item: data[item] for item in data if item != '_id'} + for data in documents] + return output + + def write(self, data): + print('Writing Data') + new_document = data['Document'] + + response = self.collection.insert_one(new_document) + + return response diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/__init__.py b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/const.py b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/const.py new file mode 100644 index 00000000..9dda22ab --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/const.py @@ -0,0 +1,27 @@ + +from enum import Enum + +class RewardStatus(Enum): + REDEEMED = 1 + NOT_REDEEMED = 2 + IN_PROGRESS = 3 + EXPIRED = 4 + +class Events(Enum): + ONBOARDING = 1 + SOCIAL_MEDIA_TWITTER = 2 + QR_SCAN = 3 + + +ONBOARDING_EVENT = "ONBOARDING" +SOCIAL_MEDIA_TWITTER_EVENT = "SOCIAL_MEDIA_TWITTER" +QR_SCAN_EVENT = "QR_SCAN" +DEFAULT_EVENT = "DEFAULT_EVENT" + + +EVENTS_CONSTANT = { + 'onboarding': ONBOARDING_EVENT, + 'twitter': SOCIAL_MEDIA_TWITTER_EVENT, + 'qr_scan': QR_SCAN_EVENT, + 'default': DEFAULT_EVENT +} \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/controller.py b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/controller.py new file mode 100644 index 00000000..efe89340 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/controller.py @@ -0,0 +1,84 @@ +from flask import Response, request +from app.rewards.service import RewardsService +from flask_restful import Resource, Api +from app import app +import json +from http import HTTPStatus + +api = Api(app) + +# TODO: add autherization +@api.resource('/reward') +class Reward(Resource): + def get(self, id): + print(id) + response = RewardsService().get_reward(id) + if response: + return Response(response=json.dumps(response), + status=HTTPStatus.OK, + content_type='application/json') + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + + def get(self): + response = dict() + try: + response = RewardsService().get_all_rewards() + except Exception as e: + print("Exception in get all: ", e) + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + + if response: + print('****', type(response)) + + return Response( + response=json.dumps(response,sort_keys=True, default=str), + status=HTTPStatus.OK, + content_type='application/json') + else: + return Response(response="No data found", + status=HTTPStatus.NOT_FOUND, + content_type='application/json') + + def post(self): + """ + reward object: { + 'reward_id': get_uuid(), + 'created_at': datetime.now(), + 'updated_at': datetime.now(), + 'wallet_address': data['wallet_address'], + 'no_of_tokens': data['no_of_tokens'], + 'status': data['status'], + 'event': data['event'] + } + """ + # validate request + request_json = request.json + + print('Reward request: ', request_json) + + wallet_address = request_json.get("wallet_address") + expiry_datetime = request_json.get("expiry_datetime") + no_of_tokens = request_json.get("no_of_tokens") + event = request_json.get("event") + + if (not all([wallet_address, expiry_datetime, no_of_tokens, event])): + return Response(status=HTTPStatus.BAD_REQUEST) + + request_data = { + "wallet_address": wallet_address, + "no_of_tokens": no_of_tokens, + "expiry_datetime": expiry_datetime, + "event": event + } + + response = RewardsService().create_reward(request_data) + + if response: + return Response(response=json.dumps(response), + status=HTTPStatus.CREATED, + content_type='application/json') + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + +# api.add_resource(Drop, '/drop/', '/drop') +# api.add_resource(Drop, '/drop/') +# api.add_resource(Drop, '/drop') \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/models.py b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/models.py new file mode 100644 index 00000000..8f709ca9 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/models.py @@ -0,0 +1,38 @@ +from datetime import datetime +from app.db.mongo_db import MongoAPI +from bson.objectid import ObjectId +import uuid + +class BaseModel: + # TODO: add common fields here date time etc + pass + +def get_uuid(): + return str(uuid.uuid4()); + +db_data = { + "collection": "rewards" +} + +class Reward: + + def create(self, data): + reward = { + 'reward_id': get_uuid(), + 'created_at': datetime.now(), + 'updated_at': datetime.now(), + 'expiry_datetime': data['expiry_datetime'], + 'wallet_address': data['wallet_address'], + 'no_of_tokens': data['no_of_tokens'], + 'status': data['status'], + 'event': data['event'] + } + mongo_api = MongoAPI(db_data) + response = mongo_api.write({"Document": reward}) + return response + + def get(self, id): + print("id", id) + mongo_api = MongoAPI(db_data) + response = mongo_api.read_all({"reward_id": {"$eq": id}}) + return response diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/service.py b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/service.py new file mode 100644 index 00000000..f71b0bce --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/rewards/service.py @@ -0,0 +1,44 @@ +from app.db.mongo_db import MongoAPI +from app.rewards.models import Reward +from app.rewards.const import RewardStatus, EVENTS_CONSTANT + + + +db_data = { + "collection": "rewards" +} +class RewardsService: + + # def __init__(self) -> None: + # MongoAPI(db_data) + + def get_all_rewards(self): + obj1 = MongoAPI(db_data) + response = obj1.read_all() + print(response) + return response + + def get_reward(self, id): + obj1 = MongoAPI(db_data) + db_data["id"] = id + response = obj1.read() + print(response) + return response + + + + def create_reward(self, request_data): + + status = RewardStatus.NOT_REDEEMED.name + event = EVENTS_CONSTANT.get(request_data['event']) + request_data['status'] = status + request_data['event'] = event if event else EVENTS_CONSTANT['default'] + + reward = Reward().create(request_data) + + response = { + 'status': 'Successfully Inserted', + 'document_id': str(reward.inserted_id) + } + + return response diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/__init__.py b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/controller.py b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/controller.py new file mode 100644 index 00000000..b146ab7d --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/controller.py @@ -0,0 +1,60 @@ +from flask import Response, request +from app.social_rewards.service import SocialRewardsService +from flask_restful import Resource, Api +from app import app +from http import HTTPStatus +import json + +api = Api(app) +api.init_app(app) + +@api.resource('/social-rewards') +class SocialReward(Resource): + + def get(self): + # TODO: implement this + return + + def post(self): + request_json = request.json + print('SocialReward request: ', request_json) + + try: + response = SocialRewardsService().create_social_reward(request_json) + + if response: + return Response(response=json.dumps(response), + status=HTTPStatus.CREATED, + content_type='application/json') + else: + return Response(response="reward_id not found", + status=HTTPStatus.NOT_FOUND, + content_type='application/json') + except Exception as e: + print(e) + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + + +@app.route('/get_all_social_rewards/') +def get(wallet_address): + if not wallet_address: + return Response(status=HTTPStatus.BAD_REQUEST) + + response = dict() + try: + response = SocialRewardsService().get_all_active_social_rewards("twitter", wallet_address) + + except Exception as e: + print("Exception in get_all_active_social_rewards: ", e) + return Response(status=HTTPStatus.INTERNAL_SERVER_ERROR) + + if response: + return Response( + response=json.dumps(response,sort_keys=True, default=str), + status=HTTPStatus.OK, + content_type='application/json') + else: + return Response(response="No data found get_all_active_social_rewards", + status=HTTPStatus.NOT_FOUND, + content_type='application/json') + diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/models.py b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/models.py new file mode 100644 index 00000000..026fd76c --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/models.py @@ -0,0 +1,42 @@ +from app.db.mongo_db import MongoAPI +from datetime import datetime +import uuid + + +def get_uuid(): + return str(uuid.uuid4()); + +db_data = { + "collection": "social_rewards" +} + +class SocialReward: + def create(self, data): + social_reward = { + "social_reward_id": get_uuid(), + 'created_at': datetime.now(), + 'updated_at': datetime.now(), + "reward": data["reward"], + "tweet_id": data["tweet_id"], + } + print(social_reward) + mongo_api = MongoAPI(db_data) + response = mongo_api.write({"Document": social_reward}) + return response + + def get_all(self, filter=None): + mongo_api = MongoAPI(db_data) + + if filter: + print("filter: ",filter) + response = mongo_api.read_all(filter) + else: + response = mongo_api.read_all() + + return list(response) + + + # def get_all_by_filter(self, filter): + # mongo_api = MongoAPI(db_data) + + # return response \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/service.py b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/service.py new file mode 100644 index 00000000..32afd5df --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/app/social_rewards/service.py @@ -0,0 +1,57 @@ +from app.social_rewards.models import SocialReward +from app.rewards.models import Reward +from datetime import datetime +from app.rewards.const import RewardStatus + +class SocialRewardsService: + + def get_all_active_social_rewards(self, social_platform, wallet_address): + """ + not expired + not reedemed + """ + print('get_all_active_social_rewards, platform: ', social_platform, wallet_address) + # "expiry_datetime" : { + # "$gte" : datetime.now() + # }, + all_social_rewards = SocialReward().get_all( + filter={ + + "reward.wallet_address": { + "$eq": wallet_address + }, + "reward.status": { + "$eq": RewardStatus.NOT_REDEEMED.name + } + } + ) + + + return all_social_rewards + + def create_social_reward(self, request_data): + """ + social_reward = { + "reward_id": data["reward_id"], + "tweet_id": data["tweet_id"] + } + """ + + social_reward_data = dict() + social_reward_data["tweet_id"] = request_data["tweet_id"] + + reward = Reward().get(request_data["reward_id"]) + # print("got reward",reward, type(reward), type(reward[0])) + if not (reward): + return + + social_reward_data["reward"] = reward[0] + # print("social_reward_data", social_reward_data) + social_reward = SocialReward().create(social_reward_data) + # print('created') + response = { + 'status': 'Successfully Inserted Tweet and Reward', + 'document_id': str(social_reward.inserted_id) + } + + return response \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/flow_terminal_cmd.sh b/one-and-half-nibble/Backend/fanex-admin-app/flow_terminal_cmd.sh new file mode 100644 index 00000000..547da6ad --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/flow_terminal_cmd.sh @@ -0,0 +1,5 @@ +# /bin/sh +flow transactions send ./transactions/add-token-to-vault.cdc 25 0xb5c96cfc0a3e42a8 --authorizer "my-testnet-account" --gas-limit 50 --payer "my-testnet-account" --proposer "my-testnet-account" -n testnet -f ./Users/livspace/Documents/web3/Dapp-Rewards/backend/fanex-admin-app/flow.json + +# wallet id: +# 0x18242b040b7d7253 \ No newline at end of file diff --git a/one-and-half-nibble/Backend/fanex-admin-app/requirement.txt b/one-and-half-nibble/Backend/fanex-admin-app/requirement.txt new file mode 100644 index 00000000..0cdfcaf4 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/requirement.txt @@ -0,0 +1,22 @@ +alembic==1.9.4 +aniso8601==9.0.1 +click==8.1.3 +dnspython==2.3.0 +Flask==2.2.3 +Flask-Migrate==4.0.4 +Flask-RESTful==0.3.9 +Flask-SQLAlchemy==3.0.3 +importlib-metadata==6.0.0 +importlib-resources==5.12.0 +itsdangerous==2.1.2 +Jinja2==3.1.2 +Mako==1.2.4 +MarkupSafe==2.1.2 +pymongo==4.3.3 +python-dotenv==1.0.0 +pytz==2022.7.1 +six==1.16.0 +SQLAlchemy==2.0.4 +typing_extensions==4.5.0 +Werkzeug==2.2.3 +zipp==3.14.0 diff --git a/one-and-half-nibble/Backend/fanex-admin-app/run.py b/one-and-half-nibble/Backend/fanex-admin-app/run.py new file mode 100644 index 00000000..08eea1a8 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/run.py @@ -0,0 +1,2 @@ +from app import app +app.run(debug=True, host='127.0.0.1', port=5000) diff --git a/one-and-half-nibble/Backend/fanex-admin-app/settings.py b/one-and-half-nibble/Backend/fanex-admin-app/settings.py new file mode 100644 index 00000000..c50069d6 --- /dev/null +++ b/one-and-half-nibble/Backend/fanex-admin-app/settings.py @@ -0,0 +1,7 @@ +import os +from dotenv import load_dotenv + +load_dotenv() + +MONGO_URI = os.getenv('MONGO_URI') +DB_NAME = 'fanex_test_db' \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Podfile b/one-and-half-nibble/MobileApp/Podfile new file mode 100644 index 00000000..ad7f52c6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Podfile @@ -0,0 +1,27 @@ +# Uncomment the next line to define a global platform for your project + platform :ios, '15.0' + +target 'fanex' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for fanex + + pod 'FCL-SDK', '~> 0.3.3' + pod 'MercariQRScanner' + pod 'PopupDialog', '~> 1.1' + pod "DynamicBlurView" + pod 'SVProgressHUD' + pod 'SDWebImage', '~> 5.0' + target 'fanexTests' do + inherit! :search_paths + # Pods for testing + end + + target 'fanexUITests' do + # Pods for testing + end + +end + + diff --git a/one-and-half-nibble/MobileApp/Podfile.lock b/one-and-half-nibble/MobileApp/Podfile.lock new file mode 100644 index 00000000..3629c2df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Podfile.lock @@ -0,0 +1,279 @@ +PODS: + - _NIODataStructures (2.40.0) + - BigInt (5.2.0) + - BloctoSDK/Core (0.5.0) + - BloctoSDK/Flow (0.5.0): + - BloctoSDK/Core (~> 0.5.0) + - FlowSDK (~> 0.5.0) + - Cadence (0.5.0): + - BigInt (~> 5.2.0) + - CryptoSwift (~> 1.5.1) + - CGRPCZlibp (1.8.2) + - CNIOAtomics (2.40.0) + - CNIOBoringSSL (2.19.0) + - CNIOBoringSSLShims (2.19.0): + - CNIOBoringSSL (= 2.19.0) + - CNIODarwin (2.40.0) + - CNIOHTTPParser (2.40.0) + - CNIOLinux (2.40.0) + - CNIOWindows (2.40.0) + - CryptoSwift (1.5.1) + - DynamicBlurView (4.1.0) + - FCL-SDK (0.3.3): + - BloctoSDK/Flow (~> 0.5.0) + - SwiftyJSON + - FlowSDK (0.5.0): + - FlowSDK/FlowSDK (= 0.5.0) + - FlowSDK/FlowSDK (0.5.0): + - BigInt (~> 5.2.0) + - Cadence (~> 0.5.0) + - CryptoSwift (~> 1.5.1) + - gRPC-Swiftp (~> 1.8.2) + - secp256k1Swift (~> 0.7.4) + - gRPC-Swiftp (1.8.2): + - CGRPCZlibp (= 1.8.2) + - Logging (< 2.0.0, >= 1.4.0) + - SwiftNIO (< 3.0.0, >= 2.32.0) + - SwiftNIOExtras (< 2.0.0, >= 1.4.0) + - SwiftNIOHTTP2 (< 2.0.0, >= 1.18.2) + - SwiftNIOSSL (< 3.0.0, >= 2.14.0) + - SwiftNIOTransportServices (< 2.0.0, >= 1.11.1) + - SwiftProtobuf (< 2.0.0, >= 1.9.0) + - Logging (1.4.0) + - MercariQRScanner (1.9.0) + - PopupDialog (1.1.1): + - DynamicBlurView (~> 4.0) + - SDWebImage (5.12.5): + - SDWebImage/Core (= 5.12.5) + - SDWebImage/Core (5.12.5) + - secp256k1Swift (0.7.4): + - secp256k1Wrapper (~> 0.0.5) + - secp256k1Wrapper (0.0.5) + - SVProgressHUD (2.2.5) + - SwiftNIO (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOConcurrencyHelpers (2.40.0): + - CNIOAtomics (= 2.40.0) + - SwiftNIOCore (2.40.0): + - CNIOAtomics (= 2.40.0) + - CNIOLinux (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOEmbedded (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIOLinux (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOExtras (1.11.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOFoundationCompat (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOHPACK (1.22.0): + - _NIODataStructures (< 3, >= 2.35.0) + - CNIOAtomics (< 3, >= 2.35.0) + - CNIODarwin (< 3, >= 2.35.0) + - CNIOHTTPParser (< 3, >= 2.35.0) + - CNIOLinux (< 3, >= 2.35.0) + - CNIOWindows (< 3, >= 2.35.0) + - SwiftNIO (< 3, >= 2.35.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) + - SwiftNIOCore (< 3, >= 2.35.0) + - SwiftNIOEmbedded (< 3, >= 2.35.0) + - SwiftNIOHTTP1 (< 3, >= 2.35.0) + - SwiftNIOPosix (< 3, >= 2.35.0) + - SwiftNIOHTTP1 (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOHTTPParser (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOHTTP2 (1.22.0): + - _NIODataStructures (< 3, >= 2.35.0) + - CNIOAtomics (< 3, >= 2.35.0) + - CNIODarwin (< 3, >= 2.35.0) + - CNIOHTTPParser (< 3, >= 2.35.0) + - CNIOLinux (< 3, >= 2.35.0) + - CNIOWindows (< 3, >= 2.35.0) + - SwiftNIO (< 3, >= 2.35.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) + - SwiftNIOCore (< 3, >= 2.35.0) + - SwiftNIOEmbedded (< 3, >= 2.35.0) + - SwiftNIOHPACK (= 1.22.0) + - SwiftNIOHTTP1 (< 3, >= 2.35.0) + - SwiftNIOPosix (< 3, >= 2.35.0) + - SwiftNIOTLS (< 3, >= 2.35.0) + - SwiftNIOPosix (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOSSL (2.19.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIOBoringSSL (= 2.19.0) + - CNIOBoringSSLShims (= 2.19.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOTLS (< 3, >= 2.32.0) + - SwiftNIOTLS (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOTransportServices (1.12.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOFoundationCompat (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOTLS (< 3, >= 2.32.0) + - SwiftProtobuf (1.20.3) + - SwiftyJSON (5.0.1) + +DEPENDENCIES: + - DynamicBlurView + - FCL-SDK (~> 0.3.3) + - MercariQRScanner + - PopupDialog (~> 1.1) + - SDWebImage (~> 5.0) + - SVProgressHUD + +SPEC REPOS: + trunk: + - _NIODataStructures + - BigInt + - BloctoSDK + - Cadence + - CGRPCZlibp + - CNIOAtomics + - CNIOBoringSSL + - CNIOBoringSSLShims + - CNIODarwin + - CNIOHTTPParser + - CNIOLinux + - CNIOWindows + - CryptoSwift + - DynamicBlurView + - FCL-SDK + - FlowSDK + - gRPC-Swiftp + - Logging + - MercariQRScanner + - PopupDialog + - SDWebImage + - secp256k1Swift + - secp256k1Wrapper + - SVProgressHUD + - SwiftNIO + - SwiftNIOConcurrencyHelpers + - SwiftNIOCore + - SwiftNIOEmbedded + - SwiftNIOExtras + - SwiftNIOFoundationCompat + - SwiftNIOHPACK + - SwiftNIOHTTP1 + - SwiftNIOHTTP2 + - SwiftNIOPosix + - SwiftNIOSSL + - SwiftNIOTLS + - SwiftNIOTransportServices + - SwiftProtobuf + - SwiftyJSON + +SPEC CHECKSUMS: + _NIODataStructures: 3d45d8e70a1d17a15b1dc59d102c63dbc0525ffd + BigInt: f668a80089607f521586bbe29513d708491ef2f7 + BloctoSDK: ee7b4dfe3fe249fb27254d42d6cdb3de4b268544 + Cadence: f354a678487ab17716acd61ddbb637130e9642b8 + CGRPCZlibp: 2f3e1e7a6d6cb481d4d1a26d3ec09aefacf09cbb + CNIOAtomics: 8edf08644e5e6fa0f021c239be9e8beb1cd9ef18 + CNIOBoringSSL: 2c9c96c2e95f15e83fb8d26b9738d939cc39ae33 + CNIOBoringSSLShims: c5c9346e7bbd1040f4f8793a35441dda7487539a + CNIODarwin: 93850990d29f2626b05306c6c9309f9be0d74c2f + CNIOHTTPParser: 8ce395236fa1d09ac3b4f4bcfba79b849b2ac684 + CNIOLinux: 62e3505f50de558c393dc2f273dde71dcce518da + CNIOWindows: 3047f2d8165848a3936a0a755fee27c6b5ee479b + CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 + DynamicBlurView: 58e18fae80bb614e34681a4486870e7d257b62e8 + FCL-SDK: 43fff0a39d8cf2981dee0f640482ea18fd9e4f05 + FlowSDK: 08c8b36cdc7b1c0d7017504592e8d13042e71bd0 + gRPC-Swiftp: 1f5a05ce5b544bff3dce93223e72829daac26113 + Logging: beeb016c9c80cf77042d62e83495816847ef108b + MercariQRScanner: e5aea873969af59b09b4cc411fc1c5b6293dba44 + PopupDialog: 720c92befd8bc23c13442254945213db5612f149 + SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e + secp256k1Swift: ea49d2b06724444a03cf7938a2d3fc7acc4c0f08 + secp256k1Wrapper: 0378417cd06d51187bbc9e178ec318e7902e2120 + SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 + SwiftNIO: 829958aab300642625091f82fc2f49cb7cf4ef24 + SwiftNIOConcurrencyHelpers: 697370136789b1074e4535eaae75cbd7f900370e + SwiftNIOCore: 473fdfe746534d7aa25766916459eeaf6f92ef49 + SwiftNIOEmbedded: ffcb5147db67d9686c8366b7f8427b36132f2c8a + SwiftNIOExtras: 481f74d6bf0b0ef699905ed66439cb019c4975c9 + SwiftNIOFoundationCompat: b9cdbea4806e4a12e9f66d9696fa3b98c4c3232b + SwiftNIOHPACK: e7d3ff5bd671528adfb11cd4e0c84ddfdc3c4453 + SwiftNIOHTTP1: ef56706550a1dc135ea69d65215b9941e643c23b + SwiftNIOHTTP2: cc81d7a6ba70d2ddc5376f471904b27ef5d2b7b8 + SwiftNIOPosix: b49af4bdbecaadfadd5c93dfe28594d6722b75e4 + SwiftNIOSSL: d153c5a6fc5b2301b0519b4c4d037a9414212da6 + SwiftNIOTLS: 598af547490133e9aac52aed0c23c4a90c31dcfc + SwiftNIOTransportServices: 0b2b407819d82eb63af558c5396e33c945759503 + SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 + SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e + +PODFILE CHECKSUM: 2ee197391bce94760f2e151ebb997bc78b137bd2 + +COCOAPODS: 1.11.2 diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/LICENSE.md b/one-and-half-nibble/MobileApp/Pods/BigInt/LICENSE.md new file mode 100644 index 00000000..18cefd11 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/LICENSE.md @@ -0,0 +1,20 @@ + +Copyright (c) 2016-2017 Károly Lőrentey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/README.md b/one-and-half-nibble/MobileApp/Pods/BigInt/README.md new file mode 100644 index 00000000..2256249c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/README.md @@ -0,0 +1,430 @@ +[![BigInt](https://github.com/attaswift/BigInt/raw/master/images/banner.png)](https://github.com/attaswift/BigInt) + +* [Overview](#overview) +* [API Documentation](#api) +* [License](#license) +* [Requirements and Integration](#integration) +* [Implementation Notes](#notes) + * [Full-width multiplication and division primitives](#fullwidth) + * [Why is there no generic `BigInt` type?](#generics) +* [Calculation Samples](#samples) + * [Obligatory factorial demo](#factorial) + * [RSA Cryptography](#rsa) + * [Calculating the Digits of π](#pi) + +[![Swift 3](https://img.shields.io/badge/Swift-5-blue.svg)](https://developer.apple.com/swift/) +[![License](https://img.shields.io/badge/licence-MIT-blue.svg)](http://cocoapods.org/pods/BigInt) +[![Platform](https://img.shields.io/cocoapods/p/BigInt.svg)](http://cocoapods.org/pods/BigInt) + +[![Build Status](https://travis-ci.org/attaswift/BigInt.svg?branch=master)](https://travis-ci.org/attaswift/BigInt) +[![Code Coverage](https://codecov.io/github/attaswift/BigInt/coverage.svg?branch=master)](https://codecov.io/github/attaswift/BigInt?branch=master) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage) +[![Version](https://img.shields.io/cocoapods/v/BigInt.svg)](http://cocoapods.org/pods/BigInt) + +## Overview + +This repository provides [integer types of arbitrary width][wiki] implemented +in 100% pure Swift. The underlying representation is in base 2^64, using `Array`. + +[wiki]: https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic + +This module is handy when you need an integer type that's wider than `UIntMax`, but +you don't want to add [The GNU Multiple Precision Arithmetic Library][GMP] +as a dependency. + +[GMP]: https://gmplib.org + +Two big integer types are included: [`BigUInt`][BigUInt] and [`BigInt`][BigInt], +the latter being the signed variant. +Both of these are Swift structs with copy-on-write value semantics, and they can be used much +like any other integer type. + +The library provides implementations for some of the most frequently useful functions on +big integers, including + +- All functionality from [`Comparable`][comparison] and [`Hashable`][hashing] + +- [The full set of arithmetic operators][addition]: `+`, `-`, `*`, `/`, `%`, `+=`, `-=`, `*=`, `/=`, `%=` + - [Addition][addition] and [subtraction][subtraction] have variants that allow for + shifting the digits of the second operand on the fly. + - Unsigned subtraction will trap when the result would be negative. + ([There are variants][subtraction] that return an overflow flag.) + - [Multiplication][mul] uses brute force for numbers up to 1024 digits, then switches to Karatsuba's recursive method. + (This limit is configurable, see `BigUInt.directMultiplicationLimit`.) + - A [fused multiply-add][fused] method is also available, along with other [special-case variants][multiplication]. + - [Division][division] uses Knuth's Algorithm D, with its 3/2 digits wide quotient approximation. + It will trap when the divisor is zero. + - [`BigUInt.divide`][divide] returns the quotient and + remainder at once; this is faster than calculating them separately. + +- [Bitwise operators][bitwise]: `~`, `|`, `&`, `^`, `|=`, `&=`, `^=`, plus the following read-only properties: + - [`width`][width]: the minimum number of bits required to store the integer, + - [`trailingZeroBitCount`][trailingZeroBitCount]: the number of trailing zero bits in the binary representation, + - [`leadingZeroBitCount`][leadingZeroBitCount]: the number of leading zero bits (when the last digit isn't full), + +- [Shift operators][shift]: `>>`, `<<`, `>>=`, `<<=` + +- Methods to [convert `NSData` to big integers][data] and vice versa. + +- Support for [generating random integers][random] of specified maximum width or magnitude. + +- Radix conversion to/from [`String`s][radix1] and [big integers][radix2] up to base 36 (using repeated divisions). + - Big integers use this to implement `StringLiteralConvertible` (in base 10). + +- [`sqrt(n)`][sqrt]: The square root of an integer (using Newton's method). + +- [`BigUInt.gcd(n, m)`][GCD]: The greatest common divisor of two integers (Stein's algorithm). + +- [`base.power(exponent, modulus)`][powmod]: Modular exponentiation (right-to-left binary method). + [Vanilla exponentiation][power] is also available. +- [`n.inverse(modulus)`][inverse]: Multiplicative inverse in modulo arithmetic (extended Euclidean algorithm). +- [`n.isPrime()`][prime]: Miller–Rabin primality test. + +The implementations are intended to be reasonably efficient, but they are unlikely to be +competitive with GMP at all, even when I happened to implement an algorithm with same asymptotic +behavior as GMP. (I haven't performed a comparison benchmark, though.) + +The library has 100% unit test coverage. Sadly this does not imply that there are no bugs +in it. + +## API Documentation + +Generated API docs are available at http://attaswift.github.io/BigInt/. + +## License + +BigInt can be used, distributed and modified under [the MIT license][license]. + +## Requirements and Integration + +BigInt 4.0.0 requires Swift 4.2 (The last version with support for Swift 3.x was BigInt 2.1.0. +The last version with support for Swift 2 was BigInt 1.3.0.) + +| Swift Version | last BigInt Version| +| ------------- |:-------------------| +| 3.x | 2.1.0 | +| 4.0 | 3.1.0 | +| 4.2 | 4.0.0 | +| 5.0 | 5.0.0 | + +BigInt deploys to macOS 10.10, iOS 9, watchOS 2 and tvOS 9. +It has been tested on the latest OS releases only---however, as the module uses very few platform-provided APIs, +there should be very few issues with earlier versions. + +BigInt uses no APIs specific to Apple platforms, so +it should be easy to port it to other operating systems. + +Setup instructions: + +- **Swift Package Manager:** + Although the Package Manager is still in its infancy, BigInt provides experimental support for it. + Add this to the dependency section of your `Package.swift` manifest: + + ```Swift + .package(url: "https://github.com/attaswift/BigInt.git", from: "5.0.0") + ``` + +- **CocoaPods:** Put this in your `Podfile`: + + ```Ruby + pod 'BigInt', '~> 5.0' + ``` + +- **Carthage:** Put this in your `Cartfile`: + + ``` + github "attaswift/BigInt" ~> 5.0 + ``` + +## Implementation notes + +[`BigUInt`][BigUInt] is a `MutableCollectionType` of its 64-bit digits, with the least significant +digit at index 0. As a convenience, [`BigUInt`][BigUInt] allows you to subscript it with indexes at +or above its `count`. [The subscript operator][subscript] returns 0 for out-of-bound `get`s and +automatically extends the array on out-of-bound `set`s. This makes memory management simpler. + +[`BigInt`][BigInt] is just a tiny wrapper around a `BigUInt` [absolute value][abs] and a +[sign bit][negative], both of which are accessible as public read-write properties. + +### Why is there no generic `BigInt` type? + +The types provided by `BigInt` are not parametric—this is very much intentional, as +Swift generics cost us dearly at runtime in this use case. In every approach I tried, +making arbitrary-precision arithmetic operations work with a generic `Digit` type parameter +resulted in code that was literally *ten times slower*. If you can make the algorithms generic +without such a huge performance hit, [please enlighten me][twitter]! + +This is an area that I plan to investigate more, as it would be useful to have generic +implementations for arbitrary-width arithmetic operations. (Polynomial division and decimal bases +are two examples.) The library already implements double-digit multiplication and division as +extension methods on a protocol with an associated type requirement; this has not measurably affected +performance. Unfortunately, the same is not true for `BigUInt`'s methods. + +Of course, as a last resort, we could just duplicate the code to create a separate +generic variant that was slower but more flexible. + +[license]: https://github.com/attaswift/BigInt/blob/master/LICENSE.md +[twitter]: https://twitter.com/lorentey +[BigUInt]: http://attaswift.github.io/BigInt/Structs/BigUInt.html +[BigInt]: http://attaswift.github.io/BigInt/Structs/BigInt.html +[comparison]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Comparison +[hashing]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Hashing +[addition]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Addition +[subtraction]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Subtraction +[mul]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:ZFV6BigInt7BigUIntoi1mFTS0_S0__S0_ +[fused]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt14multiplyAndAddFTS0_Vs6UInt6410atPositionSi_T_ +[multiplication]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Multiplication +[division]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Division +[divide]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt7dividedFT2byS0__T8quotientS0_9remainderS0__ +[bitwise]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Bitwise%20Operations +[width]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt5widthSi +[leadingZeroBitCount]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt13leadingZeroBitCountSi +[trailingZeroBitCount]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt14trailingZeroBitCountSi +[shift]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Shift%20Operators +[data]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/NSData%20Conversion +[random]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Random%20Integers +[radix1]: http://attaswift.github.io/BigInt/Extensions/String.html#/s:FE6BigIntSScFTVS_7BigUInt5radixSi9uppercaseSb_SS +[radix2]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUIntcFTSS5radixSi_GSqS0__ +[sqrt]: http://attaswift.github.io/BigInt/Functions.html#/s:F6BigInt4sqrtFVS_7BigUIntS0_ +[GCD]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:ZFV6BigInt7BigUInt3gcdFTS0_S0__S0_ +[powmod]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt5powerFTS0_7modulusS0__S0_ +[power]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt5powerFSiS0_ +[inverse]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt7inverseFS0_GSqS0__ +[prime]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Primality%20Testing +[abs]: http://attaswift.github.io/BigInt/Structs/BigInt.html#/s:vV6BigInt6BigInt3absVS_7BigUInt +[negative]: http://attaswift.github.io/BigInt/Structs/BigInt.html#/s:vV6BigInt6BigInt8negativeSb +[subscript]: https://github.com/attaswift/BigInt/blob/v2.0.0/Sources/BigUInt.swift#L216-L239 +[fullmuldiv]: https://github.com/attaswift/BigInt/blob/v2.0.0/Sources/BigDigit.swift#L96-L167 + + +## Calculation Samples + +### Obligatory Factorial Demo + +It is easy to use `BigInt` to calculate the factorial function for any integer: + +```Swift +import BigInt + +func factorial(_ n: Int) -> BigInt { + return (1 ... n).map { BigInt($0) }.reduce(BigInt(1), *) +} + +print(factorial(10)) +==> 362880 + +print(factorial(100)) +==> 93326215443944152681699238856266700490715968264381621468592963895217599993229915 + 6089414639761565182862536979208272237582511852109168640000000000000000000000 + +print(factorial(1000)) +==> 40238726007709377354370243392300398571937486421071463254379991042993851239862902 + 05920442084869694048004799886101971960586316668729948085589013238296699445909974 + 24504087073759918823627727188732519779505950995276120874975462497043601418278094 + 64649629105639388743788648733711918104582578364784997701247663288983595573543251 + 31853239584630755574091142624174743493475534286465766116677973966688202912073791 + 43853719588249808126867838374559731746136085379534524221586593201928090878297308 + 43139284440328123155861103697680135730421616874760967587134831202547858932076716 + 91324484262361314125087802080002616831510273418279777047846358681701643650241536 + 91398281264810213092761244896359928705114964975419909342221566832572080821333186 + 11681155361583654698404670897560290095053761647584772842188967964624494516076535 + 34081989013854424879849599533191017233555566021394503997362807501378376153071277 + 61926849034352625200015888535147331611702103968175921510907788019393178114194545 + 25722386554146106289218796022383897147608850627686296714667469756291123408243920 + 81601537808898939645182632436716167621791689097799119037540312746222899880051954 + 44414282012187361745992642956581746628302955570299024324153181617210465832036786 + 90611726015878352075151628422554026517048330422614397428693306169089796848259012 + 54583271682264580665267699586526822728070757813918581788896522081643483448259932 + 66043367660176999612831860788386150279465955131156552036093988180612138558600301 + 43569452722420634463179746059468257310379008402443243846565724501440282188525247 + 09351906209290231364932734975655139587205596542287497740114133469627154228458623 + 77387538230483865688976461927383814900140767310446640259899490222221765904339901 + 88601856652648506179970235619389701786004081188972991831102117122984590164192106 + 88843871218556461249607987229085192968193723886426148396573822911231250241866493 + 53143970137428531926649875337218940694281434118520158014123344828015051399694290 + 15348307764456909907315243327828826986460278986432113908350621709500259738986355 + 42771967428222487575867657523442202075736305694988250879689281627538488633969099 + 59826280956121450994871701244516461260379029309120889086942028510640182154399457 + 15680594187274899809425474217358240106367740459574178516082923013535808184009699 + 63725242305608559037006242712434169090041536901059339838357779394109700277534720 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000 +``` + +Well, I guess that's all right, but it's not very interesting. Let's try something more useful. + +### RSA Cryptography + +The `BigInt` module provides all necessary parts to implement an (overly) +simple [RSA cryptography system][RSA]. + +[RSA]: https://en.wikipedia.org/wiki/RSA_(cryptosystem) + +Let's start with a simple function that generates a random n-bit prime. The module +includes a function to generate random integers of a specific size, and also an +`isPrime` method that performs the Miller–Rabin primality test. These are all we need: + +```Swift +func generatePrime(_ width: Int) -> BigUInt { + while true { + var random = BigUInt.randomInteger(withExactWidth: width) + random |= BigUInt(1) + if random.isPrime() { + return random + } + } +} + +let p = generatePrime(1024) +==> 13308187650642192396256419911012544845370493728424936791561478318443071617242872 + 81980956747087187419914435169914161116601678883358611076800743580556055714173922 + 08406194264346635072293912609713085260354070700055888678514690878149253177960273 + 775659537560220378850112471985434373425534121373466492101182463962031 + +let q = generatePrime(1024) +==> 17072954422657145489547308812333368925007949054501204983863958355897172093173783 + 10108226596943999553784252564650624766276133157586733504784616138305701168410157 + 80784336308507083874651158029602582993233111593356512531869546706885170044355115 + 669728424124141763799008880327106952436883614887277350838425336156327 +``` + +Cool! Now that we have two large primes, we can produce an RSA public/private keypair +out of them. + +```Swift +typealias Key = (modulus: BigUInt, exponent: BigUInt) + +let n = p * q +==> 22721008120758282530010953362926306641542233757318103044313144976976529789946696 + 15454966720907712515917481418981591379647635391260569349099666410127279690367978 + 81184375533755888994370640857883754985364288413796100527262763202679037134021810 + 57933883525572232242690805678883227791774442041516929419640051653934584376704034 + 63953169772816907280591934423237977258358097846511079947337857778137177570668391 + 57455417707100275487770399281417352829897118140972240757708561027087217205975220 + 02207275447810167397968435583004676293892340103729490987263776871467057582629588 + 916498579594964478080508868267360515953225283461208420137 + +let e: BigUInt = 65537 +let phi = (p - 1) * (q - 1) +let d = e.inverse(phi)! // d * e % phi == 1 +==> 13964664343869014759736350480776837992604500903989703383202366291905558996277719 + 77822086142456362972689566985925179681282432115598451765899180050962461295573831 + 37069237934291884106584820998146965085531433195106686745474222222620986858696591 + 69836532468835154412554521152103642453158895363417640676611704542784576974374954 + 45789456921660619938185093118762690200980720312508614337759620606992462563490422 + 76669559556568917533268479190948959560397579572761529852891246283539604545691244 + 89999692877158676643042118662613875863504016129837099223040687512684532694527109 + 80742873307409704484365002175294665608486688146261327793 + +let publicKey: Key = (n, e) +let privateKey: Key = (n, d) +``` + +In RSA, modular exponentiation is used to encrypt (and decrypt) messages. + +```Swift +func encrypt(_ message: BigUInt, key: Key) -> BigUInt { + return message.power(key.exponent, modulus: key.modulus) +} +``` + +Let's try out our new keypair by converting a string into UTF-8, interpreting +the resulting binary representation as a big integer, and encrypting it with the +public key. `BigUInt` has an initializer that takes an `NSData`, so this is pretty +easy to do: + +```Swift +let secret: BigUInt = BigUInt("Arbitrary precision arithmetic is fun!".dataUsingEncoding(NSUTF8StringEncoding)!) +==> 83323446846105976078466731524728681905293067701804838925389198929123912971229457 + 68818568737 + +let cyphertext = encrypt(secret, key: publicKey) +==> 95186982543485985200666516508066093880038842892337880561554910904277290917831453 + 54854954722744805432145474047391353716305176389470779020645959135298322520888633 + 61674945129099575943384767330342554525120384485469428048962027149169876127890306 + 77028183904699491962050888974524603226290836984166164759586952419343589385279641 + 47999991283152843977988979846238236160274201261075188190509539751990119132013021 + 74866638595734222867005089157198503204192264814750832072844208520394603054901706 + 06024394731371973402595826456435944968439153664617188570808940022471990638468783 + 49208193955207336172861151720299024935127021719852700882 +``` + +Well, it looks encrypted all right, but can we get the original message back? +In theory, encrypting the cyphertext with the private key returns the original message. +Let's see: + +```Swift +let plaintext = encrypt(cyphertext, key: privateKey) +==> 83323446846105976078466731524728681905293067701804838925389198929123912971229457 + 68818568737 + +let received = String(data: plaintext.serialize(), encoding: NSUTF8StringEncoding) +==> "Arbitrary precision arithmetic is fun!" +``` + +Yay! This is truly terrific, but please don't use this example code in an actual +cryptography system. RSA has lots of subtle (and some not so subtle) complications +that we ignored to keep this example short. + +### Calculating the Digits of π + +Another fun activity to try with `BigInt`s is to generate the digits of π. +Let's try implementing [Jeremy Gibbon's spigot algorithm][spigot]. +This is a rather slow algorithm as π-generators go, but it makes up for it with its grooviness +factor: it's remarkably short, it only uses (big) integer arithmetic, and every iteration +produces a single new digit in the base-10 representation of π. This naturally leads to an +implementation as an infinite `GeneratorType`: + +[spigot]: http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf + +```Swift +func digitsOfPi() -> AnyGenerator { + var q: BigUInt = 1 + var r: BigUInt = 180 + var t: BigUInt = 60 + var i: UInt64 = 2 // Does not overflow until digit #826_566_842 + return AnyIterator { + let u: UInt64 = 3 * (3 * i + 1) * (3 * i + 2) + let y = (q.multiplied(byDigit: 27 * i - 12) + 5 * r) / (5 * t) + (q, r, t) = ( + 10 * q.multiplied(byDigit: i * (2 * i - 1)), + 10 * (q.multiplied(byDigit: 5 * i - 2) + r - y * t).multiplied(byDigit: u), + t.multiplied(byDigit: u)) + i += 1 + return Int(y[0]) + } +} +``` + +Well, that was surprisingly easy. But does it work? Of course it does! + +```Swift +var digits = "π ≈ " +var count = 0 +for digit in digitsOfPi() { + assert(digit < 10) + digits += String(digit) + count += 1 + if count == 1 { digits += "." } + if count == 1000 { break } +} + +digits +==> π ≈ 3.14159265358979323846264338327950288419716939937510582097494459230781640628 + 62089986280348253421170679821480865132823066470938446095505822317253594081284811 + 17450284102701938521105559644622948954930381964428810975665933446128475648233786 + 78316527120190914564856692346034861045432664821339360726024914127372458700660631 + 55881748815209209628292540917153643678925903600113305305488204665213841469519415 + 11609433057270365759591953092186117381932611793105118548074462379962749567351885 + 75272489122793818301194912983367336244065664308602139494639522473719070217986094 + 37027705392171762931767523846748184676694051320005681271452635608277857713427577 + 89609173637178721468440901224953430146549585371050792279689258923542019956112129 + 02196086403441815981362977477130996051870721134999999837297804995105973173281609 + 63185950244594553469083026425223082533446850352619311881710100031378387528865875 + 33208381420617177669147303598253490428755468731159562863882353787593751957781857 + 780532171226806613001927876611195909216420198 +``` + +Now go and have some fun with big integers on your own! diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Addition.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Addition.swift new file mode 100644 index 00000000..34f4d44e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Addition.swift @@ -0,0 +1,126 @@ +// +// Addition.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + //MARK: Addition + + /// Add `word` to this integer in place. + /// `word` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, shift)) + internal mutating func addWord(_ word: Word, shiftedBy shift: Int = 0) { + precondition(shift >= 0) + var carry = word + var i = shift + while carry > 0 { + let (d, c) = self[i].addingReportingOverflow(carry) + self[i] = d + carry = (c ? 1 : 0) + i += 1 + } + } + + /// Add the digit `d` to this integer and return the result. + /// `d` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, shift)) + internal func addingWord(_ word: Word, shiftedBy shift: Int = 0) -> BigUInt { + var r = self + r.addWord(word, shiftedBy: shift) + return r + } + + /// Add `b` to this integer in place. + /// `b` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, b.count + shift)) + internal mutating func add(_ b: BigUInt, shiftedBy shift: Int = 0) { + precondition(shift >= 0) + var carry = false + var bi = 0 + let bc = b.count + while bi < bc || carry { + let ai = shift + bi + let (d, c) = self[ai].addingReportingOverflow(b[bi]) + if carry { + let (d2, c2) = d.addingReportingOverflow(1) + self[ai] = d2 + carry = c || c2 + } + else { + self[ai] = d + carry = c + } + bi += 1 + } + } + + /// Add `b` to this integer and return the result. + /// `b` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, b.count + shift)) + internal func adding(_ b: BigUInt, shiftedBy shift: Int = 0) -> BigUInt { + var r = self + r.add(b, shiftedBy: shift) + return r + } + + /// Increment this integer by one. If `shift` is non-zero, it selects + /// the word that is to be incremented. + /// + /// - Complexity: O(count + shift) + internal mutating func increment(shiftedBy shift: Int = 0) { + self.addWord(1, shiftedBy: shift) + } + + /// Add `a` and `b` together and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func +(a: BigUInt, b: BigUInt) -> BigUInt { + return a.adding(b) + } + + /// Add `a` and `b` together, and store the sum in `a`. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func +=(a: inout BigUInt, b: BigUInt) { + a.add(b, shiftedBy: 0) + } +} + +extension BigInt { + /// Add `a` to `b` and return the result. + public static func +(a: BigInt, b: BigInt) -> BigInt { + switch (a.sign, b.sign) { + case (.plus, .plus): + return BigInt(sign: .plus, magnitude: a.magnitude + b.magnitude) + case (.minus, .minus): + return BigInt(sign: .minus, magnitude: a.magnitude + b.magnitude) + case (.plus, .minus): + if a.magnitude >= b.magnitude { + return BigInt(sign: .plus, magnitude: a.magnitude - b.magnitude) + } + else { + return BigInt(sign: .minus, magnitude: b.magnitude - a.magnitude) + } + case (.minus, .plus): + if b.magnitude >= a.magnitude { + return BigInt(sign: .plus, magnitude: b.magnitude - a.magnitude) + } + else { + return BigInt(sign: .minus, magnitude: a.magnitude - b.magnitude) + } + } + } + + /// Add `b` to `a` in place. + public static func +=(a: inout BigInt, b: BigInt) { + a = a + b + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigInt.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigInt.swift new file mode 100644 index 00000000..11318ffc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigInt.swift @@ -0,0 +1,74 @@ +// +// BigInt.swift +// BigInt +// +// Created by Károly Lőrentey on 2015-12-27. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: BigInt + +/// An arbitary precision signed integer type, also known as a "big integer". +/// +/// Operations on big integers never overflow, but they might take a long time to execute. +/// The amount of memory (and address space) available is the only constraint to the magnitude of these numbers. +/// +/// This particular big integer type uses base-2^64 digits to represent integers. +/// +/// `BigInt` is essentially a tiny wrapper that extends `BigUInt` with a sign bit and provides signed integer +/// operations. Both the underlying absolute value and the negative/positive flag are available as read-write +/// properties. +/// +/// Not all algorithms of `BigUInt` are available for `BigInt` values; for example, there is no square root or +/// primality test for signed integers. When you need to call one of these, just extract the absolute value: +/// +/// ```Swift +/// BigInt(255).abs.isPrime() // Returns false +/// ``` +/// +public struct BigInt: SignedInteger { + public enum Sign { + case plus + case minus + } + + public typealias Magnitude = BigUInt + + /// The type representing a digit in `BigInt`'s underlying number system. + public typealias Word = BigUInt.Word + + public static var isSigned: Bool { + return true + } + + /// The absolute value of this integer. + public var magnitude: BigUInt + + /// True iff the value of this integer is negative. + public var sign: Sign + + /// Initializes a new big integer with the provided absolute number and sign flag. + public init(sign: Sign, magnitude: BigUInt) { + self.sign = (magnitude.isZero ? .plus : sign) + self.magnitude = magnitude + } + + /// Return true iff this integer is zero. + /// + /// - Complexity: O(1) + public var isZero: Bool { + return magnitude.isZero + } + + /// Returns `-1` if this value is negative and `1` if it’s positive; otherwise, `0`. + /// + /// - Returns: The sign of this number, expressed as an integer of the same type. + public func signum() -> BigInt { + switch sign { + case .plus: + return isZero ? 0 : 1 + case .minus: + return -1 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigUInt.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigUInt.swift new file mode 100644 index 00000000..81aa9a83 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/BigUInt.swift @@ -0,0 +1,386 @@ +// +// BigUInt.swift +// BigInt +// +// Created by Károly Lőrentey on 2015-12-26. +// Copyright © 2016-2017 Károly Lőrentey. +// + +/// An arbitary precision unsigned integer type, also known as a "big integer". +/// +/// Operations on big integers never overflow, but they may take a long time to execute. +/// The amount of memory (and address space) available is the only constraint to the magnitude of these numbers. +/// +/// This particular big integer type uses base-2^64 digits to represent integers; you can think of it as a wrapper +/// around `Array`. (In fact, `BigUInt` only uses an array if there are more than two digits.) +public struct BigUInt: UnsignedInteger { + /// The type representing a digit in `BigUInt`'s underlying number system. + public typealias Word = UInt + + /// The storage variants of a `BigUInt`. + enum Kind { + /// Value consists of the two specified words (low and high). Either or both words may be zero. + case inline(Word, Word) + /// Words are stored in a slice of the storage array. + case slice(from: Int, to: Int) + /// Words are stored in the storage array. + case array + } + + internal fileprivate (set) var kind: Kind // Internal for testing only + internal fileprivate (set) var storage: [Word] // Internal for testing only; stored separately to prevent COW copies + + /// Initializes a new BigUInt with value 0. + public init() { + self.kind = .inline(0, 0) + self.storage = [] + } + + internal init(word: Word) { + self.kind = .inline(word, 0) + self.storage = [] + } + + internal init(low: Word, high: Word) { + self.kind = .inline(low, high) + self.storage = [] + } + + /// Initializes a new BigUInt with the specified digits. The digits are ordered from least to most significant. + public init(words: [Word]) { + self.kind = .array + self.storage = words + normalize() + } + + internal init(words: [Word], from startIndex: Int, to endIndex: Int) { + self.kind = .slice(from: startIndex, to: endIndex) + self.storage = words + normalize() + } +} + +extension BigUInt { + public static var isSigned: Bool { + return false + } + + /// Return true iff this integer is zero. + /// + /// - Complexity: O(1) + var isZero: Bool { + switch kind { + case .inline(0, 0): return true + case .array: return storage.isEmpty + default: + return false + } + } + + /// Returns `1` if this value is, positive; otherwise, `0`. + /// + /// - Returns: The sign of this number, expressed as an integer of the same type. + public func signum() -> BigUInt { + return isZero ? 0 : 1 + } +} + +extension BigUInt { + mutating func ensureArray() { + switch kind { + case let .inline(w0, w1): + kind = .array + storage = w1 != 0 ? [w0, w1] + : w0 != 0 ? [w0] + : [] + case let .slice(from: start, to: end): + kind = .array + storage = Array(storage[start ..< end]) + case .array: + break + } + } + + var capacity: Int { + guard case .array = kind else { return 0 } + return storage.capacity + } + + mutating func reserveCapacity(_ minimumCapacity: Int) { + switch kind { + case let .inline(w0, w1): + kind = .array + storage.reserveCapacity(minimumCapacity) + if w1 != 0 { + storage.append(w0) + storage.append(w1) + } + else if w0 != 0 { + storage.append(w0) + } + case let .slice(from: start, to: end): + kind = .array + var words: [Word] = [] + words.reserveCapacity(Swift.max(end - start, minimumCapacity)) + words.append(contentsOf: storage[start ..< end]) + storage = words + case .array: + storage.reserveCapacity(minimumCapacity) + } + } + + /// Gets rid of leading zero digits in the digit array and converts slices into inline digits when possible. + internal mutating func normalize() { + switch kind { + case .slice(from: let start, to: var end): + assert(start >= 0 && end <= storage.count && start <= end) + while start < end, storage[end - 1] == 0 { + end -= 1 + } + switch end - start { + case 0: + kind = .inline(0, 0) + storage = [] + case 1: + kind = .inline(storage[start], 0) + storage = [] + case 2: + kind = .inline(storage[start], storage[start + 1]) + storage = [] + case storage.count: + assert(start == 0) + kind = .array + default: + kind = .slice(from: start, to: end) + } + case .array where storage.last == 0: + while storage.last == 0 { + storage.removeLast() + } + default: + break + } + } + + /// Set this integer to 0 without releasing allocated storage capacity (if any). + mutating func clear() { + self.load(0) + } + + /// Set this integer to `value` by copying its digits without releasing allocated storage capacity (if any). + mutating func load(_ value: BigUInt) { + switch kind { + case .inline, .slice: + self = value + case .array: + self.storage.removeAll(keepingCapacity: true) + self.storage.append(contentsOf: value.words) + } + } +} + +extension BigUInt { + //MARK: Collection-like members + + /// The number of digits in this integer, excluding leading zero digits. + var count: Int { + switch kind { + case let .inline(w0, w1): + return w1 != 0 ? 2 + : w0 != 0 ? 1 + : 0 + case let .slice(from: start, to: end): + return end - start + case .array: + return storage.count + } + } + + /// Get or set a digit at a given index. + /// + /// - Note: Unlike a normal collection, it is OK for the index to be greater than or equal to `endIndex`. + /// The subscripting getter returns zero for indexes beyond the most significant digit. + /// Setting these extended digits automatically appends new elements to the underlying digit array. + /// - Requires: index >= 0 + /// - Complexity: The getter is O(1). The setter is O(1) if the conditions below are true; otherwise it's O(count). + /// - The integer's storage is not shared with another integer + /// - The integer wasn't created as a slice of another integer + /// - `index < count` + subscript(_ index: Int) -> Word { + get { + precondition(index >= 0) + switch (kind, index) { + case (.inline(let w0, _), 0): return w0 + case (.inline(_, let w1), 1): return w1 + case (.slice(from: let start, to: let end), _) where index < end - start: + return storage[start + index] + case (.array, _) where index < storage.count: + return storage[index] + default: + return 0 + } + } + set(word) { + precondition(index >= 0) + switch (kind, index) { + case let (.inline(_, w1), 0): + kind = .inline(word, w1) + case let (.inline(w0, _), 1): + kind = .inline(w0, word) + case let (.slice(from: start, to: end), _) where index < end - start: + replace(at: index, with: word) + case (.array, _) where index < storage.count: + replace(at: index, with: word) + default: + extend(at: index, with: word) + } + } + } + + private mutating func replace(at index: Int, with word: Word) { + ensureArray() + precondition(index < storage.count) + storage[index] = word + if word == 0, index == storage.count - 1 { + normalize() + } + } + + private mutating func extend(at index: Int, with word: Word) { + guard word != 0 else { return } + reserveCapacity(index + 1) + precondition(index >= storage.count) + storage.append(contentsOf: repeatElement(0, count: index - storage.count)) + storage.append(word) + } + + /// Returns an integer built from the digits of this integer in the given range. + internal func extract(_ bounds: Range) -> BigUInt { + switch kind { + case let .inline(w0, w1): + let bounds = bounds.clamped(to: 0 ..< 2) + if bounds == 0 ..< 2 { + return BigUInt(low: w0, high: w1) + } + else if bounds == 0 ..< 1 { + return BigUInt(word: w0) + } + else if bounds == 1 ..< 2 { + return BigUInt(word: w1) + } + else { + return BigUInt() + } + case let .slice(from: start, to: end): + let s = Swift.min(end, start + Swift.max(bounds.lowerBound, 0)) + let e = Swift.max(s, (bounds.upperBound > end - start ? end : start + bounds.upperBound)) + return BigUInt(words: storage, from: s, to: e) + case .array: + let b = bounds.clamped(to: storage.startIndex ..< storage.endIndex) + return BigUInt(words: storage, from: b.lowerBound, to: b.upperBound) + } + } + + internal func extract(_ bounds: Bounds) -> BigUInt where Bounds.Bound == Int { + return self.extract(bounds.relative(to: 0 ..< Int.max)) + } +} + +extension BigUInt { + internal mutating func shiftRight(byWords amount: Int) { + assert(amount >= 0) + guard amount > 0 else { return } + switch kind { + case let .inline(_, w1) where amount == 1: + kind = .inline(w1, 0) + case .inline(_, _): + kind = .inline(0, 0) + case let .slice(from: start, to: end): + let s = start + amount + if s >= end { + kind = .inline(0, 0) + } + else { + kind = .slice(from: s, to: end) + normalize() + } + case .array: + if amount >= storage.count { + storage.removeAll(keepingCapacity: true) + } + else { + storage.removeFirst(amount) + } + } + } + + internal mutating func shiftLeft(byWords amount: Int) { + assert(amount >= 0) + guard amount > 0 else { return } + guard !isZero else { return } + switch kind { + case let .inline(w0, 0) where amount == 1: + kind = .inline(0, w0) + case let .inline(w0, w1): + let c = (w1 == 0 ? 1 : 2) + storage.reserveCapacity(amount + c) + storage.append(contentsOf: repeatElement(0, count: amount)) + storage.append(w0) + if w1 != 0 { + storage.append(w1) + } + kind = .array + case let .slice(from: start, to: end): + var words: [Word] = [] + words.reserveCapacity(amount + count) + words.append(contentsOf: repeatElement(0, count: amount)) + words.append(contentsOf: storage[start ..< end]) + storage = words + kind = .array + case .array: + storage.insert(contentsOf: repeatElement(0, count: amount), at: 0) + } + } +} + +extension BigUInt { + //MARK: Low and High + + /// Split this integer into a high-order and a low-order part. + /// + /// - Requires: count > 1 + /// - Returns: `(low, high)` such that + /// - `self == low.add(high, shiftedBy: middleIndex)` + /// - `high.width <= floor(width / 2)` + /// - `low.width <= ceil(width / 2)` + /// - Complexity: Typically O(1), but O(count) in the worst case, because high-order zero digits need to be removed after the split. + internal var split: (high: BigUInt, low: BigUInt) { + precondition(count > 1) + let mid = middleIndex + return (self.extract(mid...), self.extract(.. 1 + internal var low: BigUInt { + return self.extract(0 ..< middleIndex) + } + + /// The high-order half of this BigUInt. + /// + /// - Returns: `self[middleIndex ..< count]` + /// - Requires: count > 1 + internal var high: BigUInt { + return self.extract(middleIndex ..< count) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Bitwise Ops.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Bitwise Ops.swift new file mode 100644 index 00000000..0d00148b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Bitwise Ops.swift @@ -0,0 +1,121 @@ +// +// Bitwise Ops.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Bitwise Operations + +extension BigUInt { + /// Return the ones' complement of `a`. + /// + /// - Complexity: O(a.count) + public static prefix func ~(a: BigUInt) -> BigUInt { + return BigUInt(words: a.words.map { ~$0 }) + } + + /// Calculate the bitwise OR of `a` and `b`, and store the result in `a`. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func |= (a: inout BigUInt, b: BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] |= b[i] + } + } + + /// Calculate the bitwise AND of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func &= (a: inout BigUInt, b: BigUInt) { + for i in 0 ..< Swift.max(a.count, b.count) { + a[i] &= b[i] + } + } + + /// Calculate the bitwise XOR of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func ^= (a: inout BigUInt, b: BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] ^= b[i] + } + } +} + +extension BigInt { + public static prefix func ~(x: BigInt) -> BigInt { + switch x.sign { + case .plus: + return BigInt(sign: .minus, magnitude: x.magnitude + 1) + case .minus: + return BigInt(sign: .plus, magnitude: x.magnitude - 1) + } + } + + public static func &(lhs: inout BigInt, rhs: BigInt) -> BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] & right[i]) + } + if lhs.sign == .minus && rhs.sign == .minus { + words.twosComplement() + return BigInt(sign: .minus, magnitude: BigUInt(words: words)) + } + return BigInt(sign: .plus, magnitude: BigUInt(words: words)) + } + + public static func |(lhs: inout BigInt, rhs: BigInt) -> BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] | right[i]) + } + if lhs.sign == .minus || rhs.sign == .minus { + words.twosComplement() + return BigInt(sign: .minus, magnitude: BigUInt(words: words)) + } + return BigInt(sign: .plus, magnitude: BigUInt(words: words)) + } + + public static func ^(lhs: inout BigInt, rhs: BigInt) -> BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] ^ right[i]) + } + if (lhs.sign == .minus) != (rhs.sign == .minus) { + words.twosComplement() + return BigInt(sign: .minus, magnitude: BigUInt(words: words)) + } + return BigInt(sign: .plus, magnitude: BigUInt(words: words)) + } + + public static func &=(lhs: inout BigInt, rhs: BigInt) { + lhs = lhs & rhs + } + + public static func |=(lhs: inout BigInt, rhs: BigInt) { + lhs = lhs | rhs + } + + public static func ^=(lhs: inout BigInt, rhs: BigInt) { + lhs = lhs ^ rhs + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Codable.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Codable.swift new file mode 100644 index 00000000..b53b30be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Codable.swift @@ -0,0 +1,155 @@ +// +// Codable.swift +// BigInt +// +// Created by Károly Lőrentey on 2017-8-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + + +// Little-endian to big-endian +struct Units: RandomAccessCollection +where Words.Element: FixedWidthInteger, Words.Index == Int { + typealias Word = Words.Element + let words: Words + init(of type: Unit.Type, _ words: Words) { + precondition(Word.bitWidth % Unit.bitWidth == 0 || Unit.bitWidth % Word.bitWidth == 0) + self.words = words + } + var count: Int { return (words.count * Word.bitWidth + Unit.bitWidth - 1) / Unit.bitWidth } + var startIndex: Int { return 0 } + var endIndex: Int { return count } + subscript(_ index: Int) -> Unit { + let index = count - 1 - index + if Unit.bitWidth == Word.bitWidth { + return Unit(words[index]) + } + else if Unit.bitWidth > Word.bitWidth { + let c = Unit.bitWidth / Word.bitWidth + var unit: Unit = 0 + var j = 0 + for i in (c * index) ..< Swift.min(c * (index + 1), words.endIndex) { + unit |= Unit(words[i]) << j + j += Word.bitWidth + } + return unit + } + // Unit.bitWidth < Word.bitWidth + let c = Word.bitWidth / Unit.bitWidth + let i = index / c + let j = index % c + return Unit(truncatingIfNeeded: words[i] >> (j * Unit.bitWidth)) + } +} + +extension Array where Element: FixedWidthInteger { + // Big-endian to little-endian + init(count: Int?, generator: () throws -> Unit?) rethrows { + typealias Word = Element + precondition(Word.bitWidth % Unit.bitWidth == 0 || Unit.bitWidth % Word.bitWidth == 0) + self = [] + if Unit.bitWidth == Word.bitWidth { + if let count = count { + self.reserveCapacity(count) + } + while let unit = try generator() { + self.append(Word(unit)) + } + } + else if Unit.bitWidth > Word.bitWidth { + let wordsPerUnit = Unit.bitWidth / Word.bitWidth + if let count = count { + self.reserveCapacity(count * wordsPerUnit) + } + while let unit = try generator() { + var shift = Unit.bitWidth - Word.bitWidth + while shift >= 0 { + self.append(Word(truncatingIfNeeded: unit >> shift)) + shift -= Word.bitWidth + } + } + } + else { + let unitsPerWord = Word.bitWidth / Unit.bitWidth + if let count = count { + self.reserveCapacity((count + unitsPerWord - 1) / unitsPerWord) + } + var word: Word = 0 + var c = 0 + while let unit = try generator() { + word <<= Unit.bitWidth + word |= Word(unit) + c += Unit.bitWidth + if c == Word.bitWidth { + self.append(word) + word = 0 + c = 0 + } + } + if c > 0 { + self.append(word << c) + var shifted: Word = 0 + for i in self.indices { + let word = self[i] + self[i] = shifted | (word >> c) + shifted = word << (Word.bitWidth - c) + } + } + } + self.reverse() + } +} + +extension BigInt: Codable { + public init(from decoder: Decoder) throws { + var container = try decoder.unkeyedContainer() + + // Decode sign + let sign: BigInt.Sign + switch try container.decode(String.self) { + case "+": + sign = .plus + case "-": + sign = .minus + default: + throw DecodingError.dataCorrupted(.init(codingPath: container.codingPath, + debugDescription: "Invalid big integer sign")) + } + + // Decode magnitude + let words = try [UInt](count: container.count?.advanced(by: -1)) { () -> UInt64? in + guard !container.isAtEnd else { return nil } + return try container.decode(UInt64.self) + } + let magnitude = BigUInt(words: words) + + self.init(sign: sign, magnitude: magnitude) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.unkeyedContainer() + try container.encode(sign == .plus ? "+" : "-") + let units = Units(of: UInt64.self, self.magnitude.words) + if units.isEmpty { + try container.encode(0 as UInt64) + } + else { + try container.encode(contentsOf: units) + } + } +} + +extension BigUInt: Codable { + public init(from decoder: Decoder) throws { + let value = try BigInt(from: decoder) + guard value.sign == .plus else { + throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, + debugDescription: "BigUInt cannot hold a negative value")) + } + self = value.magnitude + } + + public func encode(to encoder: Encoder) throws { + try BigInt(sign: .plus, magnitude: self).encode(to: encoder) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Comparable.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Comparable.swift new file mode 100644 index 00000000..d9ab87e7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Comparable.swift @@ -0,0 +1,63 @@ +// +// Comparable.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +import Foundation + +extension BigUInt: Comparable { + //MARK: Comparison + + /// Compare `a` to `b` and return an `NSComparisonResult` indicating their order. + /// + /// - Complexity: O(count) + public static func compare(_ a: BigUInt, _ b: BigUInt) -> ComparisonResult { + if a.count != b.count { return a.count > b.count ? .orderedDescending : .orderedAscending } + for i in (0 ..< a.count).reversed() { + let ad = a[i] + let bd = b[i] + if ad != bd { return ad > bd ? .orderedDescending : .orderedAscending } + } + return .orderedSame + } + + /// Return true iff `a` is equal to `b`. + /// + /// - Complexity: O(count) + public static func ==(a: BigUInt, b: BigUInt) -> Bool { + return BigUInt.compare(a, b) == .orderedSame + } + + /// Return true iff `a` is less than `b`. + /// + /// - Complexity: O(count) + public static func <(a: BigUInt, b: BigUInt) -> Bool { + return BigUInt.compare(a, b) == .orderedAscending + } +} + +extension BigInt { + /// Return true iff `a` is equal to `b`. + public static func ==(a: BigInt, b: BigInt) -> Bool { + return a.sign == b.sign && a.magnitude == b.magnitude + } + + /// Return true iff `a` is less than `b`. + public static func <(a: BigInt, b: BigInt) -> Bool { + switch (a.sign, b.sign) { + case (.plus, .plus): + return a.magnitude < b.magnitude + case (.plus, .minus): + return false + case (.minus, .plus): + return true + case (.minus, .minus): + return a.magnitude > b.magnitude + } + } +} + + diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Data Conversion.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Data Conversion.swift new file mode 100644 index 00000000..25c65521 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Data Conversion.swift @@ -0,0 +1,179 @@ +// +// Data Conversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +import Foundation + +extension BigUInt { + //MARK: NSData Conversion + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + + var word: Word = 0 + for byte in buffer { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + assert(c == 0 && word == 0 && index == -1) + } + + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order. + public init(_ data: Data) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = data.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + let word: Word = data.withUnsafeBytes { buffPtr in + var word: Word = 0 + let p = buffPtr.bindMemory(to: UInt8.self) + for byte in p { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + return word + } + assert(c == 0 && word == 0 && index == -1) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order. + public func serialize() -> Data { + // This assumes Digit is binary. + precondition(Word.bitWidth % 8 == 0) + + let byteCount = (self.bitWidth + 7) / 8 + + guard byteCount > 0 else { return Data() } + + var data = Data(count: byteCount) + data.withUnsafeMutableBytes { buffPtr in + let p = buffPtr.bindMemory(to: UInt8.self) + var i = byteCount - 1 + for var word in self.words { + for _ in 0 ..< Word.bitWidth / 8 { + p[i] = UInt8(word & 0xFF) + word >>= 8 + if i == 0 { + assert(word == 0) + break + } + i -= 1 + } + } + } + return data + } +} + +extension BigInt { + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer, + /// where the first byte indicates sign (0 for positive, 1 for negative) + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard length > 1, let firstByte = buffer.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + self.magnitude = BigUInt(UnsafeRawBufferPointer(rebasing: buffer.dropFirst(1))) + } + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order with a first + /// byte to represent the sign (0 for positive, 1 for negative) + public init(_ data: Data) { + // This assumes Word is binary. + // This is the same assumption made when initializing BigUInt from Data + precondition(Word.bitWidth % 8 == 0) + + self.init() + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard data.count > 1, let firstByte = data.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + // The remaining bytes are read and stored as the magnitude + self.magnitude = BigUInt(data.dropFirst(1)) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order and a prepended byte to indicate the sign (0 for positive, 1 for negative) + public func serialize() -> Data { + // Create a data object for the magnitude portion of the BigInt + let magnitudeData = self.magnitude.serialize() + + // Similar to BigUInt, a value of 0 should return an initialized, empty Data struct + guard magnitudeData.count > 0 else { return magnitudeData } + + // Create a new Data struct for the signed BigInt value + var data = Data(capacity: magnitudeData.count + 1) + + // The first byte should be 0 for a positive value, or 1 for a negative value + // i.e., the sign bit is the LSB + data.append(self.sign == .plus ? 0 : 1) + + data.append(magnitudeData) + return data + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Division.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Division.swift new file mode 100644 index 00000000..4393f52e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Division.swift @@ -0,0 +1,374 @@ +// +// Division.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Full-width multiplication and division + +extension FixedWidthInteger where Magnitude == Self { + private var halfShift: Self { + return Self(Self.bitWidth / 2) + + } + private var high: Self { + return self &>> halfShift + } + + private var low: Self { + let mask: Self = 1 &<< halfShift - 1 + return self & mask + } + + private var upshifted: Self { + return self &<< halfShift + } + + private var split: (high: Self, low: Self) { + return (self.high, self.low) + } + + private init(_ value: (high: Self, low: Self)) { + self = value.high.upshifted + value.low + } + + /// Divide the double-width integer `dividend` by `self` and return the quotient and remainder. + /// + /// - Requires: `dividend.high < self`, so that the result will fit in a single digit. + /// - Complexity: O(1) with 2 divisions, 6 multiplications and ~12 or so additions/subtractions. + internal func fastDividingFullWidth(_ dividend: (high: Self, low: Self.Magnitude)) -> (quotient: Self, remainder: Self) { + // Division is complicated; doing it with single-digit operations is maddeningly complicated. + // This is a Swift adaptation for "divlu2" in Hacker's Delight, + // which is in turn a C adaptation of Knuth's Algorithm D (TAOCP vol 2, 4.3.1). + precondition(dividend.high < self) + + // This replaces the implementation in stdlib, which is much slower. + // FIXME: Speed up stdlib. It should use full-width idiv on Intel processors, and + // fall back to a reasonably fast algorithm elsewhere. + + // The trick here is that we're actually implementing a 4/2 long division using half-words, + // with the long division loop unrolled into two 3/2 half-word divisions. + // Luckily, 3/2 half-word division can be approximated by a single full-word division operation + // that, when the divisor is normalized, differs from the correct result by at most 2. + + /// Find the half-word quotient in `u / vn`, which must be normalized. + /// `u` contains three half-words in the two halves of `u.high` and the lower half of + /// `u.low`. (The weird distribution makes for a slightly better fit with the input.) + /// `vn` contains the normalized divisor, consisting of two half-words. + /// + /// - Requires: u.high < vn && u.low.high == 0 && vn.leadingZeroBitCount == 0 + func quotient(dividing u: (high: Self, low: Self), by vn: Self) -> Self { + let (vn1, vn0) = vn.split + // Get approximate quotient. + let (q, r) = u.high.quotientAndRemainder(dividingBy: vn1) + let p = q * vn0 + // q is often already correct, but sometimes the approximation overshoots by at most 2. + // The code that follows checks for this while being careful to only perform single-digit operations. + if q.high == 0 && p <= r.upshifted + u.low { return q } + let r2 = r + vn1 + if r2.high != 0 { return q - 1 } + if (q - 1).high == 0 && p - vn0 <= r2.upshifted + u.low { return q - 1 } + //assert((r + 2 * vn1).high != 0 || p - 2 * vn0 <= (r + 2 * vn1).upshifted + u.low) + return q - 2 + } + /// Divide 3 half-digits by 2 half-digits to get a half-digit quotient and a full-digit remainder. + /// + /// - Requires: u.high < v && u.low.high == 0 && vn.width = width(Digit) + func quotientAndRemainder(dividing u: (high: Self, low: Self), by v: Self) -> (quotient: Self, remainder: Self) { + let q = quotient(dividing: u, by: v) + // Note that `uh.low` masks off a couple of bits, and `q * v` and the + // subtraction are likely to overflow. Despite this, the end result (remainder) will + // still be correct and it will fit inside a single (full) Digit. + let r = Self(u) &- q &* v + assert(r < v) + return (q, r) + } + + // Normalize the dividend and the divisor (self) such that the divisor has no leading zeroes. + let z = Self(self.leadingZeroBitCount) + let w = Self(Self.bitWidth) - z + let vn = self << z + + let un32 = (z == 0 ? dividend.high : (dividend.high &<< z) | (dividend.low &>> w)) // No bits are lost + let un10 = dividend.low &<< z + let (un1, un0) = un10.split + + // Divide `(un32,un10)` by `vn`, splitting the full 4/2 division into two 3/2 ones. + let (q1, un21) = quotientAndRemainder(dividing: (un32, un1), by: vn) + let (q0, rn) = quotientAndRemainder(dividing: (un21, un0), by: vn) + + // Undo normalization of the remainder and combine the two halves of the quotient. + let mod = rn >> z + let div = Self((q1, q0)) + return (div, mod) + } + + /// Return the quotient of the 3/2-word division `x/y` as a single word. + /// + /// - Requires: (x.0, x.1) <= y && y.0.high != 0 + /// - Returns: The exact value when it fits in a single word, otherwise `Self`. + static func approximateQuotient(dividing x: (Self, Self, Self), by y: (Self, Self)) -> Self { + // Start with q = (x.0, x.1) / y.0, (or Word.max on overflow) + var q: Self + var r: Self + if x.0 == y.0 { + q = Self.max + let (s, o) = x.0.addingReportingOverflow(x.1) + if o { return q } + r = s + } + else { + (q, r) = y.0.fastDividingFullWidth((x.0, x.1)) + } + // Now refine q by considering x.2 and y.1. + // Note that since y is normalized, q * y - x is between 0 and 2. + let (ph, pl) = q.multipliedFullWidth(by: y.1) + if ph < r || (ph == r && pl <= x.2) { return q } + + let (r1, ro) = r.addingReportingOverflow(y.0) + if ro { return q - 1 } + + let (pl1, so) = pl.subtractingReportingOverflow(y.1) + let ph1 = (so ? ph - 1 : ph) + + if ph1 < r1 || (ph1 == r1 && pl1 <= x.2) { return q - 1 } + return q - 2 + } +} + +extension BigUInt { + //MARK: Division + + /// Divide this integer by the word `y`, leaving the quotient in its place and returning the remainder. + /// + /// - Requires: y > 0 + /// - Complexity: O(count) + internal mutating func divide(byWord y: Word) -> Word { + precondition(y > 0) + if y == 1 { return 0 } + + var remainder: Word = 0 + for i in (0 ..< count).reversed() { + let u = self[i] + (self[i], remainder) = y.fastDividingFullWidth((remainder, u)) + } + return remainder + } + + /// Divide this integer by the word `y` and return the resulting quotient and remainder. + /// + /// - Requires: y > 0 + /// - Returns: (quotient, remainder) where quotient = floor(x/y), remainder = x - quotient * y + /// - Complexity: O(x.count) + internal func quotientAndRemainder(dividingByWord y: Word) -> (quotient: BigUInt, remainder: Word) { + var div = self + let mod = div.divide(byWord: y) + return (div, mod) + } + + /// Divide `x` by `y`, putting the quotient in `x` and the remainder in `y`. + /// Reusing integers like this reduces the number of allocations during the calculation. + static func divide(_ x: inout BigUInt, by y: inout BigUInt) { + // This is a Swift adaptation of "divmnu" from Hacker's Delight, which is in + // turn a C adaptation of Knuth's Algorithm D (TAOCP vol 2, 4.3.1). + + precondition(!y.isZero) + + // First, let's take care of the easy cases. + if x < y { + (x, y) = (0, x) + return + } + if y.count == 1 { + // The single-word case reduces to a simpler loop. + y = BigUInt(x.divide(byWord: y[0])) + return + } + + // In the hard cases, we will perform the long division algorithm we learned in school. + // It works by successively calculating the single-word quotient of the top y.count + 1 + // words of x divided by y, replacing the top of x with the remainder, and repeating + // the process one word lower. + // + // The tricky part is that the algorithm needs to be able to do n+1/n word divisions, + // but we only have a primitive for dividing two words by a single + // word. (Remember that this step is also tricky when we do it on paper!) + // + // The solution is that the long division can be approximated by a single full division + // using just the most significant words. We can then use multiplications and + // subtractions to refine the approximation until we get the correct quotient word. + // + // We could do this by doing a simple 2/1 full division, but Knuth goes one step further, + // and implements a 3/2 division. This results in an exact approximation in the + // vast majority of cases, eliminating an extra subtraction over big integers. + // + // The function `approximateQuotient` above implements Knuth's 3/2 division algorithm. + // It requires that the divisor's most significant word is larger than + // Word.max / 2. This ensures that the approximation has tiny error bounds, + // which is what makes this entire approach viable. + // To satisfy this requirement, we will normalize the division by multiplying + // both the divisor and the dividend by the same (small) factor. + let z = y.leadingZeroBitCount + y <<= z + x <<= z // We'll calculate the remainder in the normalized dividend. + var quotient = BigUInt() + assert(y.leadingZeroBitCount == 0) + + // We're ready to start the long division! + let dc = y.count + let d1 = y[dc - 1] + let d0 = y[dc - 2] + var product: BigUInt = 0 + for j in (dc ... x.count).reversed() { + // Approximate dividing the top dc+1 words of `remainder` using the topmost 3/2 words. + let r2 = x[j] + let r1 = x[j - 1] + let r0 = x[j - 2] + let q = Word.approximateQuotient(dividing: (r2, r1, r0), by: (d1, d0)) + + // Multiply the entire divisor with `q` and subtract the result from remainder. + // Normalization ensures the 3/2 quotient will either be exact for the full division, or + // it may overshoot by at most 1, in which case the product will be greater + // than the remainder. + product.load(y) + product.multiply(byWord: q) + if product <= x.extract(j - dc ..< j + 1) { + x.subtract(product, shiftedBy: j - dc) + quotient[j - dc] = q + } + else { + // This case is extremely rare -- it has a probability of 1/2^(Word.bitWidth - 1). + x.add(y, shiftedBy: j - dc) + x.subtract(product, shiftedBy: j - dc) + quotient[j - dc] = q - 1 + } + } + // The remainder's normalization needs to be undone, but otherwise we're done. + x >>= z + y = x + x = quotient + } + + /// Divide `x` by `y`, putting the remainder in `x`. + mutating func formRemainder(dividingBy y: BigUInt, normalizedBy shift: Int) { + precondition(!y.isZero) + assert(y.leadingZeroBitCount == 0) + if y.count == 1 { + let remainder = self.divide(byWord: y[0] >> shift) + self.load(BigUInt(remainder)) + return + } + self <<= shift + if self >= y { + let dc = y.count + let d1 = y[dc - 1] + let d0 = y[dc - 2] + var product: BigUInt = 0 + for j in (dc ... self.count).reversed() { + let r2 = self[j] + let r1 = self[j - 1] + let r0 = self[j - 2] + let q = Word.approximateQuotient(dividing: (r2, r1, r0), by: (d1, d0)) + product.load(y) + product.multiply(byWord: q) + if product <= self.extract(j - dc ..< j + 1) { + self.subtract(product, shiftedBy: j - dc) + } + else { + self.add(y, shiftedBy: j - dc) + self.subtract(product, shiftedBy: j - dc) + } + } + } + self >>= shift + } + + + /// Divide this integer by `y` and return the resulting quotient and remainder. + /// + /// - Requires: `y > 0` + /// - Returns: `(quotient, remainder)` where `quotient = floor(self/y)`, `remainder = self - quotient * y` + /// - Complexity: O(count^2) + public func quotientAndRemainder(dividingBy y: BigUInt) -> (quotient: BigUInt, remainder: BigUInt) { + var x = self + var y = y + BigUInt.divide(&x, by: &y) + return (x, y) + } + + /// Divide `x` by `y` and return the quotient. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func /(x: BigUInt, y: BigUInt) -> BigUInt { + return x.quotientAndRemainder(dividingBy: y).quotient + } + + /// Divide `x` by `y` and return the remainder. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func %(x: BigUInt, y: BigUInt) -> BigUInt { + var x = x + let shift = y.leadingZeroBitCount + x.formRemainder(dividingBy: y << shift, normalizedBy: shift) + return x + } + + /// Divide `x` by `y` and store the quotient in `x`. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func /=(x: inout BigUInt, y: BigUInt) { + var y = y + BigUInt.divide(&x, by: &y) + } + + /// Divide `x` by `y` and store the remainder in `x`. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func %=(x: inout BigUInt, y: BigUInt) { + let shift = y.leadingZeroBitCount + x.formRemainder(dividingBy: y << shift, normalizedBy: shift) + } +} + +extension BigInt { + /// Divide this integer by `y` and return the resulting quotient and remainder. + /// + /// - Requires: `y > 0` + /// - Returns: `(quotient, remainder)` where `quotient = floor(self/y)`, `remainder = self - quotient * y` + /// - Complexity: O(count^2) + public func quotientAndRemainder(dividingBy y: BigInt) -> (quotient: BigInt, remainder: BigInt) { + var a = self.magnitude + var b = y.magnitude + BigUInt.divide(&a, by: &b) + return (BigInt(sign: self.sign == y.sign ? .plus : .minus, magnitude: a), + BigInt(sign: self.sign, magnitude: b)) + } + + /// Divide `a` by `b` and return the quotient. Traps if `b` is zero. + public static func /(a: BigInt, b: BigInt) -> BigInt { + return BigInt(sign: a.sign == b.sign ? .plus : .minus, magnitude: a.magnitude / b.magnitude) + } + + /// Divide `a` by `b` and return the remainder. The result has the same sign as `a`. + public static func %(a: BigInt, b: BigInt) -> BigInt { + return BigInt(sign: a.sign, magnitude: a.magnitude % b.magnitude) + } + + /// Return the result of `a` mod `b`. The result is always a nonnegative integer that is less than the absolute value of `b`. + public func modulus(_ mod: BigInt) -> BigInt { + let remainder = self.magnitude % mod.magnitude + return BigInt( + self.sign == .minus && !remainder.isZero + ? mod.magnitude - remainder + : remainder) + } +} + +extension BigInt { + /// Divide `a` by `b` storing the quotient in `a`. + public static func /=(a: inout BigInt, b: BigInt) { a = a / b } + /// Divide `a` by `b` storing the remainder in `a`. + public static func %=(a: inout BigInt, b: BigInt) { a = a % b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Exponentiation.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Exponentiation.swift new file mode 100644 index 00000000..9d7ee85d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Exponentiation.swift @@ -0,0 +1,119 @@ +// +// Exponentiation.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + //MARK: Exponentiation + + /// Returns this integer raised to the power `exponent`. + /// + /// This function calculates the result by [successively squaring the base while halving the exponent][expsqr]. + /// + /// [expsqr]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// - Note: This function can be unreasonably expensive for large exponents, which is why `exponent` is + /// a simple integer value. If you want to calculate big exponents, you'll probably need to use + /// the modulo arithmetic variant. + /// - Returns: 1 if `exponent == 0`, otherwise `self` raised to `exponent`. (This implies that `0.power(0) == 1`.) + /// - SeeAlso: `BigUInt.power(_:, modulus:)` + /// - Complexity: O((exponent * self.count)^log2(3)) or somesuch. The result may require a large amount of memory, too. + public func power(_ exponent: Int) -> BigUInt { + if exponent == 0 { return 1 } + if exponent == 1 { return self } + if exponent < 0 { + precondition(!self.isZero) + return self == 1 ? 1 : 0 + } + if self <= 1 { return self } + var result = BigUInt(1) + var b = self + var e = exponent + while e > 0 { + if e & 1 == 1 { + result *= b + } + e >>= 1 + b *= b + } + return result + } + + /// Returns the remainder of this integer raised to the power `exponent` in modulo arithmetic under `modulus`. + /// + /// Uses the [right-to-left binary method][rtlb]. + /// + /// [rtlb]: https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method + /// + /// - Complexity: O(exponent.count * modulus.count^log2(3)) or somesuch + public func power(_ exponent: BigUInt, modulus: BigUInt) -> BigUInt { + precondition(!modulus.isZero) + if modulus == (1 as BigUInt) { return 0 } + let shift = modulus.leadingZeroBitCount + let normalizedModulus = modulus << shift + var result = BigUInt(1) + var b = self + b.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + for var e in exponent.words { + for _ in 0 ..< Word.bitWidth { + if e & 1 == 1 { + result *= b + result.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + } + e >>= 1 + b *= b + b.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + } + } + return result + } +} + +extension BigInt { + /// Returns this integer raised to the power `exponent`. + /// + /// This function calculates the result by [successively squaring the base while halving the exponent][expsqr]. + /// + /// [expsqr]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// - Note: This function can be unreasonably expensive for large exponents, which is why `exponent` is + /// a simple integer value. If you want to calculate big exponents, you'll probably need to use + /// the modulo arithmetic variant. + /// - Returns: 1 if `exponent == 0`, otherwise `self` raised to `exponent`. (This implies that `0.power(0) == 1`.) + /// - SeeAlso: `BigUInt.power(_:, modulus:)` + /// - Complexity: O((exponent * self.count)^log2(3)) or somesuch. The result may require a large amount of memory, too. + public func power(_ exponent: Int) -> BigInt { + return BigInt(sign: self.sign == .minus && exponent & 1 != 0 ? .minus : .plus, + magnitude: self.magnitude.power(exponent)) + } + + /// Returns the remainder of this integer raised to the power `exponent` in modulo arithmetic under `modulus`. + /// + /// Uses the [right-to-left binary method][rtlb]. + /// + /// [rtlb]: https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method + /// + /// - Complexity: O(exponent.count * modulus.count^log2(3)) or somesuch + public func power(_ exponent: BigInt, modulus: BigInt) -> BigInt { + precondition(!modulus.isZero) + if modulus.magnitude == 1 { return 0 } + if exponent.isZero { return 1 } + if exponent == 1 { return self.modulus(modulus) } + if exponent < 0 { + precondition(!self.isZero) + guard magnitude == 1 else { return 0 } + guard sign == .minus else { return 1 } + guard exponent.magnitude[0] & 1 != 0 else { return 1 } + return BigInt(modulus.magnitude - 1) + } + let power = self.magnitude.power(exponent.magnitude, + modulus: modulus.magnitude) + if self.sign == .plus || exponent.magnitude[0] & 1 == 0 || power.isZero { + return BigInt(power) + } + return BigInt(modulus.magnitude - power) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Floating Point Conversion.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Floating Point Conversion.swift new file mode 100644 index 00000000..6c2395a3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Floating Point Conversion.swift @@ -0,0 +1,73 @@ +// +// Floating Point Conversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + public init?(exactly source: T) { + guard source.isFinite else { return nil } + guard !source.isZero else { self = 0; return } + guard source.sign == .plus else { return nil } + let value = source.rounded(.towardZero) + guard value == source else { return nil } + assert(value.floatingPointClass == .positiveNormal) + assert(value.exponent >= 0) + let significand = value.significandBitPattern + self = (BigUInt(1) << value.exponent) + BigUInt(significand) >> (T.significandBitCount - Int(value.exponent)) + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension BigInt { + public init?(exactly source: T) { + switch source.sign{ + case .plus: + guard let magnitude = BigUInt(exactly: source) else { return nil } + self = BigInt(sign: .plus, magnitude: magnitude) + case .minus: + guard let magnitude = BigUInt(exactly: -source) else { return nil } + self = BigInt(sign: .minus, magnitude: magnitude) + } + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension BinaryFloatingPoint where RawExponent: FixedWidthInteger, RawSignificand: FixedWidthInteger { + public init(_ value: BigInt) { + guard !value.isZero else { self = 0; return } + let v = value.magnitude + let bitWidth = v.bitWidth + var exponent = bitWidth - 1 + let shift = bitWidth - Self.significandBitCount - 1 + var significand = value.magnitude >> (shift - 1) + if significand[0] & 3 == 3 { // Handle rounding + significand >>= 1 + significand += 1 + if significand.trailingZeroBitCount >= Self.significandBitCount { + exponent += 1 + } + } + else { + significand >>= 1 + } + let bias = 1 << (Self.exponentBitCount - 1) - 1 + guard exponent <= bias else { self = Self.infinity; return } + significand &= 1 << Self.significandBitCount - 1 + self = Self.init(sign: value.sign == .plus ? .plus : .minus, + exponentBitPattern: RawExponent(bias + exponent), + significandBitPattern: RawSignificand(significand)) + } + + public init(_ value: BigUInt) { + self.init(BigInt(sign: .plus, magnitude: value)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/GCD.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/GCD.swift new file mode 100644 index 00000000..d55605dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/GCD.swift @@ -0,0 +1,80 @@ +// +// GCD.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + //MARK: Greatest Common Divisor + + /// Returns the greatest common divisor of `self` and `b`. + /// + /// - Complexity: O(count^2) where count = max(self.count, b.count) + public func greatestCommonDivisor(with b: BigUInt) -> BigUInt { + // This is Stein's algorithm: https://en.wikipedia.org/wiki/Binary_GCD_algorithm + if self.isZero { return b } + if b.isZero { return self } + + let az = self.trailingZeroBitCount + let bz = b.trailingZeroBitCount + let twos = Swift.min(az, bz) + + var (x, y) = (self >> az, b >> bz) + if x < y { swap(&x, &y) } + + while !x.isZero { + x >>= x.trailingZeroBitCount + if x < y { swap(&x, &y) } + x -= y + } + return y << twos + } + + /// Returns the [multiplicative inverse of this integer in modulo `modulus` arithmetic][inverse], + /// or `nil` if there is no such number. + /// + /// [inverse]: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers + /// + /// - Returns: If `gcd(self, modulus) == 1`, the value returned is an integer `a < modulus` such that `(a * self) % modulus == 1`. If `self` and `modulus` aren't coprime, the return value is `nil`. + /// - Requires: modulus > 1 + /// - Complexity: O(count^3) + public func inverse(_ modulus: BigUInt) -> BigUInt? { + precondition(modulus > 1) + var t1 = BigInt(0) + var t2 = BigInt(1) + var r1 = modulus + var r2 = self + while !r2.isZero { + let quotient = r1 / r2 + (t1, t2) = (t2, t1 - BigInt(quotient) * t2) + (r1, r2) = (r2, r1 - quotient * r2) + } + if r1 > 1 { return nil } + if t1.sign == .minus { return modulus - t1.magnitude } + return t1.magnitude + } +} + +extension BigInt { + /// Returns the greatest common divisor of `a` and `b`. + /// + /// - Complexity: O(count^2) where count = max(a.count, b.count) + public func greatestCommonDivisor(with b: BigInt) -> BigInt { + return BigInt(self.magnitude.greatestCommonDivisor(with: b.magnitude)) + } + + /// Returns the [multiplicative inverse of this integer in modulo `modulus` arithmetic][inverse], + /// or `nil` if there is no such number. + /// + /// [inverse]: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers + /// + /// - Returns: If `gcd(self, modulus) == 1`, the value returned is an integer `a < modulus` such that `(a * self) % modulus == 1`. If `self` and `modulus` aren't coprime, the return value is `nil`. + /// - Requires: modulus.magnitude > 1 + /// - Complexity: O(count^3) + public func inverse(_ modulus: BigInt) -> BigInt? { + guard let inv = self.magnitude.inverse(modulus.magnitude) else { return nil } + return BigInt(self.sign == .plus || inv.isZero ? inv : modulus.magnitude - inv) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Hashable.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Hashable.swift new file mode 100644 index 00000000..c5dc0e64 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Hashable.swift @@ -0,0 +1,26 @@ +// +// Hashable.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt: Hashable { + //MARK: Hashing + + /// Append this `BigUInt` to the specified hasher. + public func hash(into hasher: inout Hasher) { + for word in self.words { + hasher.combine(word) + } + } +} + +extension BigInt: Hashable { + /// Append this `BigInt` to the specified hasher. + public func hash(into hasher: inout Hasher) { + hasher.combine(sign) + hasher.combine(magnitude) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Integer Conversion.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Integer Conversion.swift new file mode 100644 index 00000000..9a210e4a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Integer Conversion.swift @@ -0,0 +1,89 @@ +// +// Integer Conversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + public init?(exactly source: T) { + guard source >= (0 as T) else { return nil } + if source.bitWidth <= 2 * Word.bitWidth { + var it = source.words.makeIterator() + self.init(low: it.next() ?? 0, high: it.next() ?? 0) + precondition(it.next() == nil, "Length of BinaryInteger.words is greater than its bitWidth") + } + else { + self.init(words: source.words) + } + } + + public init(_ source: T) { + precondition(source >= (0 as T), "BigUInt cannot represent negative values") + self.init(exactly: source)! + } + + public init(truncatingIfNeeded source: T) { + self.init(words: source.words) + } + + public init(clamping source: T) { + if source <= (0 as T) { + self.init() + } + else { + self.init(words: source.words) + } + } +} + +extension BigInt { + public init() { + self.init(sign: .plus, magnitude: 0) + } + + /// Initializes a new signed big integer with the same value as the specified unsigned big integer. + public init(_ integer: BigUInt) { + self.magnitude = integer + self.sign = .plus + } + + public init(_ source: T) where T : BinaryInteger { + if source >= (0 as T) { + self.init(sign: .plus, magnitude: BigUInt(source)) + } + else { + var words = Array(source.words) + words.twosComplement() + self.init(sign: .minus, magnitude: BigUInt(words: words)) + } + } + + public init?(exactly source: T) where T : BinaryInteger { + self.init(source) + } + + public init(clamping source: T) where T : BinaryInteger { + self.init(source) + } + + public init(truncatingIfNeeded source: T) where T : BinaryInteger { + self.init(source) + } +} + +extension BigUInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: UInt64) { + self.init(value) + } +} + +extension BigInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: Int64) { + self.init(value) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Multiplication.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Multiplication.swift new file mode 100644 index 00000000..635c36a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Multiplication.swift @@ -0,0 +1,165 @@ +// +// Multiplication.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + + //MARK: Multiplication + + /// Multiply this big integer by a single word, and store the result in place of the original big integer. + /// + /// - Complexity: O(count) + public mutating func multiply(byWord y: Word) { + guard y != 0 else { self = 0; return } + guard y != 1 else { return } + var carry: Word = 0 + let c = self.count + for i in 0 ..< c { + let (h, l) = self[i].multipliedFullWidth(by: y) + let (low, o) = l.addingReportingOverflow(carry) + self[i] = low + carry = (o ? h + 1 : h) + } + self[c] = carry + } + + /// Multiply this big integer by a single Word, and return the result. + /// + /// - Complexity: O(count) + public func multiplied(byWord y: Word) -> BigUInt { + var r = self + r.multiply(byWord: y) + return r + } + + /// Multiply `x` by `y`, and add the result to this integer, optionally shifted `shift` words to the left. + /// + /// - Note: This is the fused multiply/shift/add operation; it is more efficient than doing the components + /// individually. (The fused operation doesn't need to allocate space for temporary big integers.) + /// - Returns: `self` is set to `self + (x * y) << (shift * 2^Word.bitWidth)` + /// - Complexity: O(count) + public mutating func multiplyAndAdd(_ x: BigUInt, _ y: Word, shiftedBy shift: Int = 0) { + precondition(shift >= 0) + guard y != 0 && x.count > 0 else { return } + guard y != 1 else { self.add(x, shiftedBy: shift); return } + var mulCarry: Word = 0 + var addCarry = false + let xc = x.count + var xi = 0 + while xi < xc || addCarry || mulCarry > 0 { + let (h, l) = x[xi].multipliedFullWidth(by: y) + let (low, o) = l.addingReportingOverflow(mulCarry) + mulCarry = (o ? h + 1 : h) + + let ai = shift + xi + let (sum1, so1) = self[ai].addingReportingOverflow(low) + if addCarry { + let (sum2, so2) = sum1.addingReportingOverflow(1) + self[ai] = sum2 + addCarry = so1 || so2 + } + else { + self[ai] = sum1 + addCarry = so1 + } + xi += 1 + } + } + + /// Multiply this integer by `y` and return the result. + /// + /// - Note: This uses the naive O(n^2) multiplication algorithm unless both arguments have more than + /// `BigUInt.directMultiplicationLimit` words. + /// - Complexity: O(n^log2(3)) + public func multiplied(by y: BigUInt) -> BigUInt { + // This method is mostly defined for symmetry with the rest of the arithmetic operations. + return self * y + } + + /// Multiplication switches to an asymptotically better recursive algorithm when arguments have more words than this limit. + public static var directMultiplicationLimit: Int = 1024 + + /// Multiply `a` by `b` and return the result. + /// + /// - Note: This uses the naive O(n^2) multiplication algorithm unless both arguments have more than + /// `BigUInt.directMultiplicationLimit` words. + /// - Complexity: O(n^log2(3)) + public static func *(x: BigUInt, y: BigUInt) -> BigUInt { + let xc = x.count + let yc = y.count + if xc == 0 { return BigUInt() } + if yc == 0 { return BigUInt() } + if yc == 1 { return x.multiplied(byWord: y[0]) } + if xc == 1 { return y.multiplied(byWord: x[0]) } + + if Swift.min(xc, yc) <= BigUInt.directMultiplicationLimit { + // Long multiplication. + let left = (xc < yc ? y : x) + let right = (xc < yc ? x : y) + var result = BigUInt() + for i in (0 ..< right.count).reversed() { + result.multiplyAndAdd(left, right[i], shiftedBy: i) + } + return result + } + + if yc < xc { + let (xh, xl) = x.split + var r = xl * y + r.add(xh * y, shiftedBy: x.middleIndex) + return r + } + else if xc < yc { + let (yh, yl) = y.split + var r = yl * x + r.add(yh * x, shiftedBy: y.middleIndex) + return r + } + + let shift = x.middleIndex + + // Karatsuba multiplication: + // x * y = * = (ignoring carry) + let (a, b) = x.split + let (c, d) = y.split + + let high = a * c + let low = b * d + let xp = a >= b + let yp = c >= d + let xm = (xp ? a - b : b - a) + let ym = (yp ? c - d : d - c) + let m = xm * ym + + var r = low + r.add(high, shiftedBy: 2 * shift) + r.add(low, shiftedBy: shift) + r.add(high, shiftedBy: shift) + if xp == yp { + r.subtract(m, shiftedBy: shift) + } + else { + r.add(m, shiftedBy: shift) + } + return r + } + + /// Multiply `a` by `b` and store the result in `a`. + public static func *=(a: inout BigUInt, b: BigUInt) { + a = a * b + } +} + +extension BigInt { + /// Multiply `a` with `b` and return the result. + public static func *(a: BigInt, b: BigInt) -> BigInt { + return BigInt(sign: a.sign == b.sign ? .plus : .minus, magnitude: a.magnitude * b.magnitude) + } + + /// Multiply `a` with `b` in place. + public static func *=(a: inout BigInt, b: BigInt) { a = a * b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Prime Test.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Prime Test.swift new file mode 100644 index 00000000..7f187110 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Prime Test.swift @@ -0,0 +1,153 @@ +// +// Prime Test.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +/// The first several [prime numbers][primes]. +/// +/// [primes]: https://oeis.org/A000040 +let primes: [BigUInt.Word] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] + +/// The ith element in this sequence is the smallest composite number that passes the strong probable prime test +/// for all of the first (i+1) primes. +/// +/// This is sequence [A014233](http://oeis.org/A014233) on the [Online Encyclopaedia of Integer Sequences](http://oeis.org). +let pseudoPrimes: [BigUInt] = [ + /* 2 */ 2_047, + /* 3 */ 1_373_653, + /* 5 */ 25_326_001, + /* 7 */ 3_215_031_751, + /* 11 */ 2_152_302_898_747, + /* 13 */ 3_474_749_660_383, + /* 17 */ 341_550_071_728_321, + /* 19 */ 341_550_071_728_321, + /* 23 */ 3_825_123_056_546_413_051, + /* 29 */ 3_825_123_056_546_413_051, + /* 31 */ 3_825_123_056_546_413_051, + /* 37 */ "318665857834031151167461", + /* 41 */ "3317044064679887385961981", +] + +extension BigUInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: BigUInt) -> Bool { + precondition(base > (1 as BigUInt)) + precondition(self > (0 as BigUInt)) + let dec = self - 1 + + let r = dec.trailingZeroBitCount + let d = dec >> r + + var test = base.power(d, modulus: self) + if test == 1 || test == dec { return true } + + if r > 0 { + let shift = self.leadingZeroBitCount + let normalized = self << shift + for _ in 1 ..< r { + test *= test + test.formRemainder(dividingBy: normalized, normalizedBy: shift) + if test == 1 { + return false + } + if test == dec { return true } + } + } + return false + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if count <= 1 && self[0] < 2 { return false } + if count == 1 && self[0] < 4 { return true } + + // Even numbers above 2 aren't prime. + if self[0] & 1 == 0 { return false } + + // Quickly check for small primes. + for i in 1 ..< primes.count { + let p = primes[i] + if self.count == 1 && self[0] == p { + return true + } + if self.quotientAndRemainder(dividingByWord: p).remainder == 0 { + return false + } + } + + /// Give an exact answer when we can. + if self < pseudoPrimes.last! { + for i in 0 ..< pseudoPrimes.count { + guard isStrongProbablePrime(BigUInt(primes[i])) else { + break + } + if self < pseudoPrimes[i] { + // `self` is below the lowest pseudoprime corresponding to the prime bases we tested. It's a prime! + return true + } + } + return false + } + + /// Otherwise do as many rounds of random SPPT as required. + for _ in 0 ..< rounds { + let random = BigUInt.randomInteger(lessThan: self - 2) + 2 + guard isStrongProbablePrime(random) else { + return false + } + } + + // Well, it smells primey to me. + return true + } +} + +extension BigInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: BigInt) -> Bool { + precondition(base.sign == .plus) + if self.sign == .minus { return false } + return self.magnitude.isStrongProbablePrime(base.magnitude) + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if self.sign == .minus { return false } + return self.magnitude.isPrime(rounds: rounds) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Random.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Random.swift new file mode 100644 index 00000000..bea98caf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Random.swift @@ -0,0 +1,101 @@ +// +// Random.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + /// Create a big unsigned integer consisting of `width` uniformly distributed random bits. + /// + /// - Parameter width: The maximum number of one bits in the result. + /// - Parameter generator: The source of randomness. + /// - Returns: A big unsigned integer less than `1 << width`. + public static func randomInteger(withMaximumWidth width: Int, using generator: inout RNG) -> BigUInt { + var result = BigUInt.zero + var bitsLeft = width + var i = 0 + let wordsNeeded = (width + Word.bitWidth - 1) / Word.bitWidth + if wordsNeeded > 2 { + result.reserveCapacity(wordsNeeded) + } + while bitsLeft >= Word.bitWidth { + result[i] = generator.next() + i += 1 + bitsLeft -= Word.bitWidth + } + if bitsLeft > 0 { + let mask: Word = (1 << bitsLeft) - 1 + result[i] = (generator.next() as Word) & mask + } + return result + } + + /// Create a big unsigned integer consisting of `width` uniformly distributed random bits. + /// + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Parameter width: The maximum number of one bits in the result. + /// - Returns: A big unsigned integer less than `1 << width`. + public static func randomInteger(withMaximumWidth width: Int) -> BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(withMaximumWidth: width, using: &rng) + } + + /// Create a big unsigned integer consisting of `width-1` uniformly distributed random bits followed by a one bit. + /// + /// - Note: If `width` is zero, the result is zero. + /// + /// - Parameter width: The number of bits required to represent the answer. + /// - Parameter generator: The source of randomness. + /// - Returns: A random big unsigned integer whose width is `width`. + public static func randomInteger(withExactWidth width: Int, using generator: inout RNG) -> BigUInt { + // width == 0 -> return 0 because there is no room for a one bit. + // width == 1 -> return 1 because there is no room for any random bits. + guard width > 1 else { return BigUInt(width) } + var result = randomInteger(withMaximumWidth: width - 1, using: &generator) + result[(width - 1) / Word.bitWidth] |= 1 << Word((width - 1) % Word.bitWidth) + return result + } + + /// Create a big unsigned integer consisting of `width-1` uniformly distributed random bits followed by a one bit. + /// + /// - Note: If `width` is zero, the result is zero. + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Returns: A random big unsigned integer whose width is `width`. + public static func randomInteger(withExactWidth width: Int) -> BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(withExactWidth: width, using: &rng) + } + + /// Create a uniformly distributed random unsigned integer that's less than the specified limit. + /// + /// - Precondition: `limit > 0`. + /// + /// - Parameter limit: The upper bound on the result. + /// - Parameter generator: The source of randomness. + /// - Returns: A random big unsigned integer that is less than `limit`. + public static func randomInteger(lessThan limit: BigUInt, using generator: inout RNG) -> BigUInt { + precondition(limit > 0, "\(#function): 0 is not a valid limit") + let width = limit.bitWidth + var random = randomInteger(withMaximumWidth: width, using: &generator) + while random >= limit { + random = randomInteger(withMaximumWidth: width, using: &generator) + } + return random + } + + /// Create a uniformly distributed random unsigned integer that's less than the specified limit. + /// + /// - Precondition: `limit > 0`. + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Parameter limit: The upper bound on the result. + /// - Returns: A random big unsigned integer that is less than `limit`. + public static func randomInteger(lessThan limit: BigUInt) -> BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(lessThan: limit, using: &rng) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Shifts.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Shifts.swift new file mode 100644 index 00000000..e676e414 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Shifts.swift @@ -0,0 +1,211 @@ +// +// Shifts.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + + //MARK: Shift Operators + + internal func shiftedLeft(by amount: Word) -> BigUInt { + guard amount > 0 else { return self } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let up = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let down = Word(Word.bitWidth) - up + + var result = BigUInt() + if up > 0 { + var i = 0 + var lowbits: Word = 0 + while i < self.count || lowbits > 0 { + let word = self[i] + result[i + ext] = word << up | lowbits + lowbits = word >> down + i += 1 + } + } + else { + for i in 0 ..< self.count { + result[i + ext] = self[i] + } + } + return result + } + + internal mutating func shiftLeft(by amount: Word) { + guard amount > 0 else { return } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let up = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let down = Word(Word.bitWidth) - up + + if up > 0 { + var i = 0 + var lowbits: Word = 0 + while i < self.count || lowbits > 0 { + let word = self[i] + self[i] = word << up | lowbits + lowbits = word >> down + i += 1 + } + } + if ext > 0 && self.count > 0 { + self.shiftLeft(byWords: ext) + } + } + + internal func shiftedRight(by amount: Word) -> BigUInt { + guard amount > 0 else { return self } + guard amount < self.bitWidth else { return 0 } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let down = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let up = Word(Word.bitWidth) - down + + var result = BigUInt() + if down > 0 { + var highbits: Word = 0 + for i in (ext ..< self.count).reversed() { + let word = self[i] + result[i - ext] = highbits | word >> down + highbits = word << up + } + } + else { + for i in (ext ..< self.count).reversed() { + result[i - ext] = self[i] + } + } + return result + } + + internal mutating func shiftRight(by amount: Word) { + guard amount > 0 else { return } + guard amount < self.bitWidth else { self.clear(); return } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let down = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let up = Word(Word.bitWidth) - down + + if ext > 0 { + self.shiftRight(byWords: ext) + } + if down > 0 { + var i = self.count - 1 + var highbits: Word = 0 + while i >= 0 { + let word = self[i] + self[i] = highbits | word >> down + highbits = word << up + i -= 1 + } + } + } + + public static func >>=(lhs: inout BigUInt, rhs: Other) { + if rhs < (0 as Other) { + lhs <<= (0 - rhs) + } + else if rhs >= lhs.bitWidth { + lhs.clear() + } + else { + lhs.shiftRight(by: UInt(rhs)) + } + } + + public static func <<=(lhs: inout BigUInt, rhs: Other) { + if rhs < (0 as Other) { + lhs >>= (0 - rhs) + return + } + lhs.shiftLeft(by: Word(exactly: rhs)!) + } + + public static func >>(lhs: BigUInt, rhs: Other) -> BigUInt { + if rhs < (0 as Other) { + return lhs << (0 - rhs) + } + if rhs > Word.max { + return 0 + } + return lhs.shiftedRight(by: UInt(rhs)) + } + + public static func <<(lhs: BigUInt, rhs: Other) -> BigUInt { + if rhs < (0 as Other) { + return lhs >> (0 - rhs) + } + return lhs.shiftedLeft(by: Word(exactly: rhs)!) + } +} + +extension BigInt { + func shiftedLeft(by amount: Word) -> BigInt { + return BigInt(sign: self.sign, magnitude: self.magnitude.shiftedLeft(by: amount)) + } + + mutating func shiftLeft(by amount: Word) { + self.magnitude.shiftLeft(by: amount) + } + + func shiftedRight(by amount: Word) -> BigInt { + let m = self.magnitude.shiftedRight(by: amount) + return BigInt(sign: self.sign, magnitude: self.sign == .minus && m.isZero ? 1 : m) + } + + mutating func shiftRight(by amount: Word) { + magnitude.shiftRight(by: amount) + if sign == .minus, magnitude.isZero { + magnitude.load(1) + } + } + + public static func &<<(left: BigInt, right: BigInt) -> BigInt { + return left.shiftedLeft(by: right.words[0]) + } + + public static func &<<=(left: inout BigInt, right: BigInt) { + left.shiftLeft(by: right.words[0]) + } + + public static func &>>(left: BigInt, right: BigInt) -> BigInt { + return left.shiftedRight(by: right.words[0]) + } + + public static func &>>=(left: inout BigInt, right: BigInt) { + left.shiftRight(by: right.words[0]) + } + + public static func <<(lhs: BigInt, rhs: Other) -> BigInt { + guard rhs >= (0 as Other) else { return lhs >> (0 - rhs) } + return lhs.shiftedLeft(by: Word(rhs)) + } + + public static func <<=(lhs: inout BigInt, rhs: Other) { + if rhs < (0 as Other) { + lhs >>= (0 - rhs) + } + else { + lhs.shiftLeft(by: Word(rhs)) + } + } + + public static func >>(lhs: BigInt, rhs: Other) -> BigInt { + guard rhs >= (0 as Other) else { return lhs << (0 - rhs) } + return lhs.shiftedRight(by: Word(rhs)) + } + + public static func >>=(lhs: inout BigInt, rhs: Other) { + if rhs < (0 as Other) { + lhs <<= (0 - rhs) + } + else { + lhs.shiftRight(by: Word(rhs)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Square Root.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Square Root.swift new file mode 100644 index 00000000..68db0691 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Square Root.swift @@ -0,0 +1,41 @@ +// +// Square Root.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Square Root + +extension BigUInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> BigUInt { + // This implementation uses Newton's method. + guard !self.isZero else { return BigUInt() } + var x = BigUInt(1) << ((self.bitWidth + 1) / 2) + var y: BigUInt = 0 + while true { + y.load(self) + y /= x + y += x + y >>= 1 + if x == y || x == y - 1 { break } + x = y + } + return x + } +} + +extension BigInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Requires: self >= 0 + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> BigInt { + precondition(self.sign == .plus) + return BigInt(sign: .plus, magnitude: self.magnitude.squareRoot()) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Strideable.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Strideable.swift new file mode 100644 index 00000000..2b79babd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Strideable.swift @@ -0,0 +1,38 @@ +// +// Strideable.swift +// BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt: Strideable { + /// A type that can represent the distance between two values ofa `BigUInt`. + public typealias Stride = BigInt + + /// Adds `n` to `self` and returns the result. Traps if the result would be less than zero. + public func advanced(by n: BigInt) -> BigUInt { + return n.sign == .minus ? self - n.magnitude : self + n.magnitude + } + + /// Returns the (potentially negative) difference between `self` and `other` as a `BigInt`. Never traps. + public func distance(to other: BigUInt) -> BigInt { + return BigInt(other) - BigInt(self) + } +} + +extension BigInt: Strideable { + public typealias Stride = BigInt + + /// Returns `self + n`. + public func advanced(by n: Stride) -> BigInt { + return self + n + } + + /// Returns `other - self`. + public func distance(to other: BigInt) -> Stride { + return other - self + } +} + + diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/String Conversion.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/String Conversion.swift new file mode 100644 index 00000000..d6f340c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/String Conversion.swift @@ -0,0 +1,236 @@ +// +// String Conversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + + //MARK: String Conversion + + /// Calculates the number of numerals in a given radix that fit inside a single `Word`. + /// + /// - Returns: (chars, power) where `chars` is highest that satisfy `radix^chars <= 2^Word.bitWidth`. `power` is zero + /// if radix is a power of two; otherwise `power == radix^chars`. + fileprivate static func charsPerWord(forRadix radix: Int) -> (chars: Int, power: Word) { + var power: Word = 1 + var overflow = false + var count = 0 + while !overflow { + let (p, o) = power.multipliedReportingOverflow(by: Word(radix)) + overflow = o + if !o || p == 0 { + count += 1 + power = p + } + } + return (count, power) + } + + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string consisting of characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + precondition(radix > 1) + let (charsPerWord, power) = BigUInt.charsPerWord(forRadix: radix) + + var words: [Word] = [] + var end = text.endIndex + var start = end + var count = 0 + while start != text.startIndex { + start = text.index(before: start) + count += 1 + if count == charsPerWord { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + end = start + count = 0 + } + } + if start != end { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + } + + if power == 0 { + self.init(words: words) + } + else { + self.init() + for d in words.reversed() { + self.multiply(byWord: power) + self.addWord(d) + } + } + } +} + +extension BigInt { + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string optionally starting with "-" or "+" followed by characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + var magnitude: BigUInt? + var sign: Sign = .plus + if text.first == "-" { + sign = .minus + let text = text.dropFirst() + magnitude = BigUInt(text, radix: radix) + } + else if text.first == "+" { + let text = text.dropFirst() + magnitude = BigUInt(text, radix: radix) + } + else { + magnitude = BigUInt(text, radix: radix) + } + guard let m = magnitude else { return nil } + self.magnitude = m + self.sign = sign + } +} + +extension String { + /// Initialize a new string with the base-10 representation of an unsigned big integer. + /// + /// - Complexity: O(v.count^2) + public init(_ v: BigUInt) { self.init(v, radix: 10, uppercase: false) } + + /// Initialize a new string representing an unsigned big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ v: BigUInt, radix: Int, uppercase: Bool = false) { + precondition(radix > 1) + let (charsPerWord, power) = BigUInt.charsPerWord(forRadix: radix) + + guard !v.isZero else { self = "0"; return } + + var parts: [String] + if power == 0 { + parts = v.words.map { String($0, radix: radix, uppercase: uppercase) } + } + else { + parts = [] + var rest = v + while !rest.isZero { + let mod = rest.divide(byWord: power) + parts.append(String(mod, radix: radix, uppercase: uppercase)) + } + } + assert(!parts.isEmpty) + + self = "" + var first = true + for part in parts.reversed() { + let zeroes = charsPerWord - part.count + assert(zeroes >= 0) + if !first && zeroes > 0 { + // Insert leading zeroes for mid-Words + self += String(repeating: "0", count: zeroes) + } + first = false + self += part + } + } + + /// Initialize a new string representing a signed big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ value: BigInt, radix: Int = 10, uppercase: Bool = false) { + self = String(value.magnitude, radix: radix, uppercase: uppercase) + if value.sign == .minus { + self = "-" + self + } + } +} + +extension BigUInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = BigUInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = BigUInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = BigUInt(value, radix: 10)! + } +} + +extension BigInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = BigInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = BigInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = BigInt(value, radix: 10)! + } +} + +extension BigUInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension BigInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension BigUInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.bitWidth) bits)" + } +} + +extension BigInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.magnitude.bitWidth) bits)" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Subtraction.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Subtraction.swift new file mode 100644 index 00000000..5ac872e6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Subtraction.swift @@ -0,0 +1,169 @@ +// +// Subtraction.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension BigUInt { + //MARK: Subtraction + + /// Subtract `word` from this integer in place, returning a flag indicating if the operation + /// caused an arithmetic overflow. `word` is shifted `shift` words to the left before being subtracted. + /// + /// - Note: If the result indicates an overflow, then `self` becomes the two's complement of the absolute difference. + /// - Complexity: O(count) + internal mutating func subtractWordReportingOverflow(_ word: Word, shiftedBy shift: Int = 0) -> Bool { + precondition(shift >= 0) + var carry: Word = word + var i = shift + let count = self.count + while carry > 0 && i < count { + let (d, c) = self[i].subtractingReportingOverflow(carry) + self[i] = d + carry = (c ? 1 : 0) + i += 1 + } + return carry > 0 + } + + /// Subtract `word` from this integer, returning the difference and a flag that is true if the operation + /// caused an arithmetic overflow. `word` is shifted `shift` words to the left before being subtracted. + /// + /// - Note: If `overflow` is true, then the returned value is the two's complement of the absolute difference. + /// - Complexity: O(count) + internal func subtractingWordReportingOverflow(_ word: Word, shiftedBy shift: Int = 0) -> (partialValue: BigUInt, overflow: Bool) { + var result = self + let overflow = result.subtractWordReportingOverflow(word, shiftedBy: shift) + return (result, overflow) + } + + /// Subtract a digit `d` from this integer in place. + /// `d` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= d * 2^shift + /// - Complexity: O(count) + internal mutating func subtractWord(_ word: Word, shiftedBy shift: Int = 0) { + let overflow = subtractWordReportingOverflow(word, shiftedBy: shift) + precondition(!overflow) + } + + /// Subtract a digit `d` from this integer and return the result. + /// `d` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= d * 2^shift + /// - Complexity: O(count) + internal func subtractingWord(_ word: Word, shiftedBy shift: Int = 0) -> BigUInt { + var result = self + result.subtractWord(word, shiftedBy: shift) + return result + } + + /// Subtract `other` from this integer in place, and return a flag indicating if the operation caused an + /// arithmetic overflow. `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Note: If the result indicates an overflow, then `self` becomes the twos' complement of the absolute difference. + /// - Complexity: O(count) + public mutating func subtractReportingOverflow(_ b: BigUInt, shiftedBy shift: Int = 0) -> Bool { + precondition(shift >= 0) + var carry = false + var bi = 0 + let bc = b.count + let count = self.count + while bi < bc || (shift + bi < count && carry) { + let ai = shift + bi + let (d, c) = self[ai].subtractingReportingOverflow(b[bi]) + if carry { + let (d2, c2) = d.subtractingReportingOverflow(1) + self[ai] = d2 + carry = c || c2 + } + else { + self[ai] = d + carry = c + } + bi += 1 + } + return carry + } + + /// Subtract `other` from this integer, returning the difference and a flag indicating arithmetic overflow. + /// `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Note: If `overflow` is true, then the result value is the twos' complement of the absolute value of the difference. + /// - Complexity: O(count) + public func subtractingReportingOverflow(_ other: BigUInt, shiftedBy shift: Int) -> (partialValue: BigUInt, overflow: Bool) { + var result = self + let overflow = result.subtractReportingOverflow(other, shiftedBy: shift) + return (result, overflow) + } + + /// Subtracts `other` from `self`, returning the result and a flag indicating arithmetic overflow. + /// + /// - Note: When the operation overflows, then `partialValue` is the twos' complement of the absolute value of the difference. + /// - Complexity: O(count) + public func subtractingReportingOverflow(_ other: BigUInt) -> (partialValue: BigUInt, overflow: Bool) { + return self.subtractingReportingOverflow(other, shiftedBy: 0) + } + + /// Subtract `other` from this integer in place. + /// `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= other * 2^shift + /// - Complexity: O(count) + public mutating func subtract(_ other: BigUInt, shiftedBy shift: Int = 0) { + let overflow = subtractReportingOverflow(other, shiftedBy: shift) + precondition(!overflow) + } + + /// Subtract `b` from this integer, and return the difference. + /// `b` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= b * 2^shift + /// - Complexity: O(count) + public func subtracting(_ other: BigUInt, shiftedBy shift: Int = 0) -> BigUInt { + var result = self + result.subtract(other, shiftedBy: shift) + return result + } + + /// Decrement this integer by one. + /// + /// - Requires: !isZero + /// - Complexity: O(count) + public mutating func decrement(shiftedBy shift: Int = 0) { + self.subtract(1, shiftedBy: shift) + } + + /// Subtract `b` from `a` and return the result. + /// + /// - Requires: a >= b + /// - Complexity: O(a.count) + public static func -(a: BigUInt, b: BigUInt) -> BigUInt { + return a.subtracting(b) + } + + /// Subtract `b` from `a` and store the result in `a`. + /// + /// - Requires: a >= b + /// - Complexity: O(a.count) + public static func -=(a: inout BigUInt, b: BigUInt) { + a.subtract(b) + } +} + +extension BigInt { + public mutating func negate() { + guard !magnitude.isZero else { return } + self.sign = self.sign == .plus ? .minus : .plus + } + + /// Subtract `b` from `a` and return the result. + public static func -(a: BigInt, b: BigInt) -> BigInt { + return a + -b + } + + /// Subtract `b` from `a` in place. + public static func -=(a: inout BigInt, b: BigInt) { a = a - b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Words and Bits.swift b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Words and Bits.swift new file mode 100644 index 00000000..4543c1bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BigInt/Sources/Words and Bits.swift @@ -0,0 +1,202 @@ +// +// Words and Bits.swift +// BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension Array where Element == UInt { + mutating func twosComplement() { + var increment = true + for i in 0 ..< self.count { + if increment { + (self[i], increment) = (~self[i]).addingReportingOverflow(1) + } + else { + self[i] = ~self[i] + } + } + } +} + +extension BigUInt { + public subscript(bitAt index: Int) -> Bool { + get { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + return self[i] & (1 << j) != 0 + } + set { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + if newValue { + self[i] |= 1 << j + } + else { + self[i] &= ~(1 << j) + } + } + } +} + +extension BigUInt { + /// The minimum number of bits required to represent this integer in binary. + /// + /// - Returns: floor(log2(2 * self + 1)) + /// - Complexity: O(1) + public var bitWidth: Int { + guard count > 0 else { return 0 } + return count * Word.bitWidth - self[count - 1].leadingZeroBitCount + } + + /// The number of leading zero bits in the binary representation of this integer in base `2^(Word.bitWidth)`. + /// This is useful when you need to normalize a `BigUInt` such that the top bit of its most significant word is 1. + /// + /// - Note: 0 is considered to have zero leading zero bits. + /// - Returns: A value in `0...(Word.bitWidth - 1)`. + /// - SeeAlso: width + /// - Complexity: O(1) + public var leadingZeroBitCount: Int { + guard count > 0 else { return 0 } + return self[count - 1].leadingZeroBitCount + } + + /// The number of trailing zero bits in the binary representation of this integer. + /// + /// - Note: 0 is considered to have zero trailing zero bits. + /// - Returns: A value in `0...width`. + /// - Complexity: O(count) + public var trailingZeroBitCount: Int { + guard count > 0 else { return 0 } + let i = self.words.firstIndex { $0 != 0 }! + return i * Word.bitWidth + self[i].trailingZeroBitCount + } +} + +extension BigInt { + public var bitWidth: Int { + guard !magnitude.isZero else { return 0 } + return magnitude.bitWidth + 1 + } + + public var trailingZeroBitCount: Int { + // Amazingly, this works fine for negative numbers + return magnitude.trailingZeroBitCount + } +} + +extension BigUInt { + public struct Words: RandomAccessCollection { + private let value: BigUInt + + fileprivate init(_ value: BigUInt) { self.value = value } + + public var startIndex: Int { return 0 } + public var endIndex: Int { return value.count } + + public subscript(_ index: Int) -> Word { + return value[index] + } + } + + public var words: Words { return Words(self) } + + public init(words: Words) where Words.Element == Word { + let uc = words.underestimatedCount + if uc > 2 { + self.init(words: Array(words)) + } + else { + var it = words.makeIterator() + guard let w0 = it.next() else { + self.init() + return + } + guard let w1 = it.next() else { + self.init(word: w0) + return + } + if let w2 = it.next() { + var words: [UInt] = [] + words.reserveCapacity(Swift.max(3, uc)) + words.append(w0) + words.append(w1) + words.append(w2) + while let word = it.next() { + words.append(word) + } + self.init(words: words) + } + else { + self.init(low: w0, high: w1) + } + } + } +} + +extension BigInt { + public struct Words: RandomAccessCollection { + public typealias Indices = CountableRange + + private let value: BigInt + private let decrementLimit: Int + + fileprivate init(_ value: BigInt) { + self.value = value + switch value.sign { + case .plus: + self.decrementLimit = 0 + case .minus: + assert(!value.magnitude.isZero) + self.decrementLimit = value.magnitude.words.firstIndex(where: { $0 != 0 })! + } + } + + public var count: Int { + switch value.sign { + case .plus: + if let high = value.magnitude.words.last, high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + case .minus: + let high = value.magnitude.words.last! + if high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + } + } + + public var indices: Indices { return 0 ..< count } + public var startIndex: Int { return 0 } + public var endIndex: Int { return count } + + public subscript(_ index: Int) -> UInt { + // Note that indices above `endIndex` are accepted. + if value.sign == .plus { + return value.magnitude[index] + } + if index <= decrementLimit { + return ~(value.magnitude[index] &- 1) + } + return ~value.magnitude[index] + } + } + + public var words: Words { + return Words(self) + } + + public init(words: S) where S.Element == Word { + var words = Array(words) + if (words.last ?? 0) >> (Word.bitWidth - 1) == 0 { + self.init(sign: .plus, magnitude: BigUInt(words: words)) + } + else { + words.twosComplement() + self.init(sign: .minus, magnitude: BigUInt(words: words)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/LICENSE b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/LICENSE new file mode 100644 index 00000000..02de8f49 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/README.md b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/README.md new file mode 100644 index 00000000..a8a0799d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/README.md @@ -0,0 +1,93 @@ +# BloctoSDK + +[![CI Status](https://dl.circleci.com/status-badge/img/gh/portto/blocto-ios-sdk/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/portto/blocto-ios-sdk/tree/main) +[![Version](https://img.shields.io/cocoapods/v/BloctoSDK.svg?style=flat)](https://cocoapods.org/pods/BloctoSDK) +[![License](https://img.shields.io/cocoapods/l/BloctoSDK.svg?style=flat)](https://cocoapods.org/pods/BloctoSDK) +[![Platform](https://img.shields.io/cocoapods/p/BloctoSDK.svg?style=flat)](https://cocoapods.org/pods/BloctoSDK) + +## Example + +To run the example project, clone the repo, and run +``` +bundle install +bundle exec pod install +``` +or (if Bundler not installed) +``` +pod install +``` +from the Example directory first. + +## Installation + +### CocoaPods + +BloctoSDK is available through [CocoaPods](https://cocoapods.org). You can only include specific subspec to install, simply add the following line to your Podfile: + +```ruby +pod 'BloctoSDK', '~> 0.5.0' + +# or + +pod 'BloctoSDK/Solana', '~> 0.5.0' + +# or + +pod 'BloctoSDK/EVMBase', '~> 0.5.0' + +# or + +pod 'BloctoSDK/Flow', '~> 0.5.0' +``` + +### Swift Package Manager + + +```swift +.package(url: "https://github.com/portto/blocto-ios-sdk.git", .upToNextMinor(from: "0.5.0")) +``` + +and then specify `"BloctoSDK"` as a dependency of the Target in which you wish to use. +Here's an example `PackageDescription`: + +```swift +// swift-tools-version: 5.6 +import PackageDescription + +let package = Package( + name: "MyPackage", + products: [ + .library( + name: "MyPackage", + targets: ["MyPackage"] + ), + ], + dependencies: [ + .package(url: "https://github.com/portto/blocto-ios-sdk.git", .upToNextMinor(from: "0.5.0")) + ], + targets: [ + .target( + name: "MyPackage", + dependencies: [ + .product(name: "BloctoSDK", package: "blocto-ios-sdk"), + ] + ) + ] +) +``` + +## Usage +Currently support + * Solana SDK + * EVMBase SDK (Ethereum, Avalanche, BSC, Polygon) + * Flow SDK + +For further instructions please refer to [Blocto Docs](https://docs.blocto.app/blocto-ios-sdk/overview) + +## Author + +Dawson, dawson@portto.com, Scott, scott@portto.com + +## License + +BloctoSDK is available under the MIT license. See the LICENSE file for more info. diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoEnvironment.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoEnvironment.swift new file mode 100644 index 00000000..ed80c2e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoEnvironment.swift @@ -0,0 +1,13 @@ +// +// BloctoEnvironment.swift +// BloctoSDK +// +// Created by Scott on 2022/10/4. +// + +import Foundation + +public enum BloctoEnvironment { + case prod + case dev +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoSDK.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoSDK.swift new file mode 100644 index 00000000..dc107943 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/BloctoSDK.swift @@ -0,0 +1,352 @@ +// +// BloctoSDK.swift +// Alamofire +// +// Created by Andrew Wang on 2022/3/10. +// + +import UIKit +import AuthenticationServices + +func log(enable: Bool, message: String) { + guard enable else { return } + print("BloctoSDK: " + message) +} + +let responsePath: String = "/blocto" +let responseScheme: String = "blocto" + +func customScheme(appId: String) -> String { + responseScheme + appId +} + +public class BloctoSDK { + + public static let shared: BloctoSDK = BloctoSDK() + + var bloctoApiBaseURLString: String { + switch environment { + case .prod: + return "https://api.blocto.app" + case .dev: + return "https://api-dev.blocto.app" + } + } + + private var bloctoAssociatedDomain: String { + switch environment { + case .prod: + return "https://blocto.app/" + case .dev: + return "https://dev.blocto.app/" + } + } + + private var webBaseURLString: String { + switch environment { + case .prod: + return "https://wallet.blocto.app/" + case .dev: + return "https://wallet-testnet.blocto.app/" + } + } + + private let requestPath: String = "sdk" + + var requestBloctoBaseURLString: String { + bloctoAssociatedDomain + requestPath + } + + var webRequestBloctoBaseURLString: String { + webBaseURLString + requestPath + } + + var webCallbackURLScheme: String { + "blocto" + } + + var uuidToMethod: [UUID: Method] = [:] + + var appId: String = "" + + private var getWindow: (() throws -> UIWindow)? + + var logging: Bool = true + + var environment: BloctoEnvironment = .prod + + var urlOpening: URLOpening = UIApplication.shared + + var sessioningType: AuthenticationSessioning.Type = ASWebAuthenticationSession.self + + /// initialize Blocto SDK + /// - Parameters: + /// - appId: Registed id in https://developers.blocto.app/ + /// - window: PresentationContextProvider of web SDK authentication. + /// - logging: Enabling log message, default is true. + /// - testnet: Determine which blockchain environment. e.g. testnet (Ethereum testnet, Solana devnet), mainnet (Ethereum mannet, Solana mainnet Beta) + /// - urlOpening: Handling url which opened app, default is UIApplication.shared, testing purpose. + /// - sessioningType: Type that handles web SDK authentication session, default is ASWebAuthenticationSession, testing purpose. + public func initialize( + with appId: String, + getWindow: (() throws -> UIWindow)?, + logging: Bool = true, + environment: BloctoEnvironment = .prod, + urlOpening: URLOpening = UIApplication.shared, + sessioningType: AuthenticationSessioning.Type = ASWebAuthenticationSession.self + ) { + self.appId = appId + self.getWindow = getWindow + self.logging = logging + self.environment = environment + self.urlOpening = urlOpening + self.sessioningType = sessioningType + } + + /// To simply update blockchain network. + /// - Parameter environment: Blocto Environment + public func updateEnvironment(_ environment: BloctoEnvironment) { + self.environment = environment + } + + /// Entry of Universal Links + /// - Parameter userActivity: the same userActivity from UIApplicationDelegate + public func `continue`(_ userActivity: NSUserActivity) { + guard let url = userActivity.webpageURL else { + log( + enable: logging, + message: "webpageURL not found." + ) + return + } + guard url.path == responsePath else { + log( + enable: logging, + message: "url path should be \(responsePath) rather than \(url.path)." + ) + return + } + log( + enable: logging, + message: "App get called by Universal Links: \(url)" + ) + methodResolve(url: url) + } + + /// Entry of custom scheme + /// - Parameters: + /// - url: custom scheme URL + public func application( + open url: URL + ) { + if let scheme = url.scheme?.lowercased(), + scheme.hasPrefix("blocto") || scheme.hasPrefix("blocto-dev") { + log( + enable: true, + message: "❗️❗️Universal link should be implemented to prevent from potential attack." + ) + } + do { + try checkConfigration() + guard url.scheme == customScheme(appId: appId) else { + log( + enable: logging, + message: "url scheme should be \(responseScheme) rather than \(String(describing: url.scheme))." + ) + return + } + log( + enable: logging, + message: "App get called by custom scheme: \(url)" + ) + methodResolve(url: url) + } catch { + log( + enable: logging, + message: "error: \(error) when opened by \(url)" + ) + } + } + + /// Send pre-defined method + /// - Parameters: + /// - method: Any method which conform to Method protocol + /// - fallbackToWebSDK: Whether to fallback to WebSDK if native Blocto app not install. + public func send( + method: Method, + fallbackToWebSDK: Bool = true + ) { + let send = { [weak self] in + guard let self = self else { + method.handleError(error: BloctoSDKError.callbackSelfNotfound) + return + } + do { + try self.checkConfigration() + guard let requestURL = try method.encodeToURL( + appId: self.appId, + baseURLString: self.requestBloctoBaseURLString + ) else { + method.handleError(error: BloctoSDKError.encodeToURLFailed) + return + } + self.uuidToMethod[method.id] = method + self.urlOpening.open( + requestURL, + options: [.universalLinksOnly: true], + completionHandler: { [weak self] opened in + guard let self = self else { return } + if opened { + log( + enable: self.logging, + message: "open universal link \(requestURL) successfully." + ) + } else { + log( + enable: self.logging, + message: "can't open universal link \(requestURL)." + ) + if fallbackToWebSDK { + do { + self.routeToWebSDK(window: try self.getWindow?(), method: method) + } catch { + log( + enable: self.logging, + message: "Window not found." + ) + } + } else { + log( + enable: self.logging, + message: "Not fallback to WebSDK for \(method.type)." + ) + } + } + } + ) + } catch { + method.handleError(error: error) + do { + self.routeToWebSDK(window: try self.getWindow?(), method: method) + } catch { + log( + enable: self.logging, + message: "Window not found." + ) + } + } + } + if Thread.isMainThread { + send() + } else { + DispatchQueue.main.async { + send() + } + } + } + + private func checkConfigration() throws { + guard appId.isEmpty == false else { throw BloctoSDKError.appIdNotSet } + } + + private func routeToWebSDK( + window: UIWindow? = nil, + method: Method + ) { + do { + guard let requestURL = try method.encodeToURL( + appId: appId, + baseURLString: webRequestBloctoBaseURLString + ) else { + method.handleError(error: BloctoSDKError.encodeToURLFailed) + return + } + + var session: AuthenticationSessioning? + + session = sessioningType.init( + url: requestURL, + callbackURLScheme: webCallbackURLScheme, + completionHandler: { [weak self] callbackURL, error in + guard let self = self else { return } + if let error = error { + log( + enable: self.logging, + message: error.localizedDescription + ) + if let error = error as? ASWebAuthenticationSessionError { + if error.code == ASWebAuthenticationSessionError.Code.canceledLogin { + method.handleError(error: BloctoSDKError.userCancel) + } else { + method.handleError(error: BloctoSDKError.sessionError(code: error.code.rawValue)) + } + } + } else if let callbackURL = callbackURL { + self.methodResolve(expectHost: nil, url: callbackURL) + } else { + log( + enable: self.logging, + message: "callback URL not found." + ) + method.handleError(error: BloctoSDKError.redirectURLNotFound) + } + session = nil + } + ) + + session?.presentationContextProvider = window + + log( + enable: logging, + message: "About to route to Web SDK \(requestURL)." + ) + let startsSuccessfully = session?.start() + if startsSuccessfully == false { + method.handleError(error: BloctoSDKError.webSDKSessionFailed) + } + } catch { + method.handleError(error: error) + } + } + + private func methodResolve( + expectHost: String? = nil, + url: URL + ) { + if let expectHost = expectHost { + guard url.host == expectHost else { + log( + enable: logging, + message: "\(url.host ?? "host is nil") should be \(expectHost)" + ) + return + } + } + guard let urlComponents = URLComponents( + url: url, + resolvingAgainstBaseURL: false + ) else { + log( + enable: logging, + message: "urlComponents not found." + ) + return + } + guard let uuid = urlComponents.getRequestId() else { + log( + enable: logging, + message: "\(QueryName.requestId.rawValue) not found." + ) + return + } + guard let method = uuidToMethod[uuid] else { + log( + enable: logging, + message: "\(QueryName.method.rawValue) not found." + ) + return + } + method.resolve(components: urlComponents, logging: logging) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BloctoSDKCompatible.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BloctoSDKCompatible.swift new file mode 100644 index 00000000..683e7e02 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BloctoSDKCompatible.swift @@ -0,0 +1,24 @@ +// +// BloctoSDKCompatible.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/5/26. +// + +import Foundation + +public protocol BloctoSDKCompatible { + associatedtype someType + var bloctoSDK: someType { get } +} + +public extension BloctoSDKCompatible { + var bloctoSDK: BloctoSDKHelper { BloctoSDKHelper(self) } +} + +public struct BloctoSDKHelper { + let base: Base + init(_ base: Base) { + self.base = base + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BundleExtension.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BundleExtension.swift new file mode 100644 index 00000000..5fa3a6c4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/BundleExtension.swift @@ -0,0 +1,22 @@ +// +// BundleExtension.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/4/26. +// + +import Foundation + +extension Bundle { + + static var resouceBundle: Bundle? { + #if COCOAPODS + return Bundle(identifier: "org.cocoapods.BloctoSDK") + #elseif SWIFT_PACKAGE + return nil + #else + return nil + #endif + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/DataExtensions.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/DataExtensions.swift new file mode 100644 index 00000000..649d38d1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/DataExtensions.swift @@ -0,0 +1,78 @@ +// +// DataExtensions.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/4/15. +// + +import Foundation +import CommonCrypto + +extension Data { + + public init?(hexString: String) { + let string: String + if hexString.hasPrefix("0x") { + string = String(hexString.dropFirst(2)) + } else { + string = hexString + } + + // Check odd length hex string + if string.count % 2 != 0 { + return nil + } + + // Convert the string to bytes for better performance + guard let stringData = string.data(using: .ascii, allowLossyConversion: true) else { + return nil + } + + self.init(capacity: string.count / 2) + let stringBytes = Array(stringData) + for i in stride(from: 0, to: stringBytes.count, by: 2) { + guard let high = Data.value(of: stringBytes[i]) else { + return nil + } + if i < stringBytes.count - 1, let low = Data.value(of: stringBytes[i + 1]) { + append((high << 4) | low) + } else { + append(high) + } + } + } + + /// Converts an ASCII byte to a hex value. + private static func value(of nibble: UInt8) -> UInt8? { + guard let letter = String(bytes: [nibble], encoding: .ascii) else { return nil } + return UInt8(letter, radix: 16) + } + +} + +// MARK: - Data + BloctoSDKCompatible + +extension Data: BloctoSDKCompatible {} + +extension BloctoSDKHelper where Base == Data { + + public var hexStringWith0xPrefix: String { + "0x" + hexString + } + + /// Returns the hex string representation of the data. + public var hexString: String { + base.map { String(format: "%02x", $0) }.joined() + } + + public var sha256: Data { + var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) + + base.withUnsafeBytes { buffer in + _ = CC_SHA256(buffer.baseAddress, CC_LONG(buffer.count), &hash) + } + + return Data(hash) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/KeyedDecodingContainerProtocolExtension.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/KeyedDecodingContainerProtocolExtension.swift new file mode 100644 index 00000000..be1ee0dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/KeyedDecodingContainerProtocolExtension.swift @@ -0,0 +1,28 @@ +// +// KeyedDecodingContainerProtocolExtension.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/4/15. +// + +import Foundation + +public extension KeyedDecodingContainerProtocol { + + // MARK: - Dictionary + + func decodeStringDataDictionary(forKey key: Self.Key) throws -> [String: Data] { + let stringDataDict = try decode([String: String].self, forKey: key) + + var result: [String: Data] = [:] + for (string, hexString) in stringDataDict { + guard let data = Data(hexString: hexString) else { + throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected hexadecimal string") + } + result[string] = data + } + + return result + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/NSNumber.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/NSNumber.swift new file mode 100644 index 00000000..b7c7eba6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/NSNumber.swift @@ -0,0 +1,18 @@ +// +// NSNumber.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/30. +// + +import Foundation + +extension NSNumber { + + var isBool: Bool { + // Use Obj-C type encoding to check whether the underlying type is a `Bool`, as it's guaranteed as part of + // swift-corelibs-foundation, per [this discussion on the Swift forums](https://forums.swift.org/t/alamofire-on-linux-possible-but-not-release-ready/34553/22). + String(cString: objCType) == "c" + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/StringExtensions.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/StringExtensions.swift new file mode 100644 index 00000000..bd55293e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/StringExtensions.swift @@ -0,0 +1,72 @@ +// +// StringExtensions.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/4/18. +// + +import Foundation + +// MARK: - String + BloctoSDKCompatible + +extension String: BloctoSDKCompatible {} + +extension BloctoSDKHelper where Base == String { + + public var drop0x: String { + if base.hasPrefix("0x") { + return String(base.dropFirst(2)) + } + return base + } + + public var add0x: String { + if base.hasPrefix("0x") { + return base + } + return "0x" + base + } + + public var hexDecodedData: Data { + // Convert to a CString and make sure it has an even number of characters (terminating 0 is included, so we + // check for uneven!) + guard let cString = base.cString(using: .ascii), (cString.count % 2) == 1 else { + return Data() + } + + var result = Data(capacity: (cString.count - 1) / 2) + for i in stride(from: 0, to: cString.count - 1, by: 2) { + guard let l = hexCharToByte(cString[i]), let r = hexCharToByte(cString[i + 1]) else { + return Data() + } + var value: UInt8 = (l << 4) | r + result.append(&value, count: MemoryLayout.size(ofValue: value)) + } + return result + } + + public func hexConvertToString() -> String { + if base.prefix(2) == "0x" { + return String( + data: String(base.dropFirst(2)).bloctoSDK.hexDecodedData, + encoding: .utf8 + ) ?? base + } else { + return base + } + } + + private func hexCharToByte(_ c: CChar) -> UInt8? { + if c >= 48 && c <= 57 { // 0 - 9 + return UInt8(c - 48) + } + if c >= 97 && c <= 102 { // a - f + return UInt8(10) + UInt8(c - 97) + } + if c >= 65 && c <= 70 { // A - F + return UInt8(10) + UInt8(c - 65) + } + return nil + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/UIWindowExtension.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/UIWindowExtension.swift new file mode 100644 index 00000000..ca8dfd61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/UIWindowExtension.swift @@ -0,0 +1,17 @@ +// +// UIWindowExtension.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/30. +// + +import Foundation +import AuthenticationServices + +extension UIWindow: ASWebAuthenticationPresentationContextProviding { + + public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { + self + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLComponents.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLComponents.swift new file mode 100644 index 00000000..5ceae247 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLComponents.swift @@ -0,0 +1,23 @@ +// +// URLComponents.swift +// Alamofire +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +extension URLComponents { + + func getRequestId() -> UUID? { + guard let uuidString = queryItems?.first(where: { $0.name == QueryName.requestId.rawValue })?.value else { + return nil + } + return UUID(uuidString: uuidString) + } + + func queryItem(for queryName: QueryName) -> String? { + queryItems?.first(where: { $0.name == queryName.rawValue })?.value + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLQueryItem.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLQueryItem.swift new file mode 100644 index 00000000..ed7d9f70 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Extensions/URLQueryItem.swift @@ -0,0 +1,16 @@ +// +// URLQueryItem.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +extension URLQueryItem { + + init(name: QueryName, value: String?) { + self.init(name: name.rawValue, value: value) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Methods/RequestAccountMethod.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Methods/RequestAccountMethod.swift new file mode 100644 index 00000000..d610030a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Methods/RequestAccountMethod.swift @@ -0,0 +1,72 @@ +// +// RequestAccountMethod.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +public struct RequestAccountMethod: CallbackMethod { + public typealias Response = String + + public let id: UUID + public let type: String = MethodName.requestAccount.rawValue + public let callback: Callback + + let blockchain: Blockchain + + /// initialize request account method + /// - Parameters: + /// - id: Used to find a stored callback. No need to pass if there is no specific requirement, for example, testing. + /// - blockchain: pre-defined blockchain in BloctoSDK + /// - callback: callback will be called by either from blocto native app or web SDK after getting account or reject. + /// + /// Supports for request account only in Flow Blockchain. + /// For receiving account proof along with request account use AuthenticateMethod instead. + public init( + id: UUID = UUID(), + blockchain: Blockchain, + callback: @escaping Callback + ) { + self.id = id + self.blockchain = blockchain + self.callback = callback + } + + public func encodeToURL(appId: String, baseURLString: String) throws -> URL? { + guard let baseURL = URL(string: baseURLString), + var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: true) else { + return nil + } + var queryItems = URLEncoding.queryGeneralItems( + appId: appId, + requestId: id.uuidString, + blockchain: blockchain + ) + queryItems.append(QueryItem(name: .method, value: type)) + components.queryItems = URLEncoding.encode(queryItems) + return components.url + } + + public func resolve(components: URLComponents, logging: Bool) { + if let errorCode = components.queryItem(for: .error) { + callback(.failure(BloctoSDKError(code: errorCode))) + return + } + let targetQueryName = QueryName.address + guard let address = components.queryItem(for: targetQueryName) else { + log( + enable: logging, + message: "\(targetQueryName.rawValue) not found." + ) + callback(.failure(BloctoSDKError.invalidResponse)) + return + } + callback(.success(address)) + } + + public func handleError(error: Swift.Error) { + callback(.failure(error)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Blockchain.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Blockchain.swift new file mode 100644 index 00000000..5d4e7ccb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Blockchain.swift @@ -0,0 +1,17 @@ +// +// Blockchain.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/15. +// + +import Foundation + +public enum Blockchain: String { + case solana + case ethereum + case binanceSmartChain = "bsc" + case polygon + case avalanche + case flow +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/CallbackMethod.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/CallbackMethod.swift new file mode 100644 index 00000000..d7f804cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/CallbackMethod.swift @@ -0,0 +1,15 @@ +// +// CallbackMethod.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +public protocol CallbackMethod: Method { + associatedtype Response + typealias Callback = (Result) -> Void + + var callback: Callback { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Error.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Error.swift new file mode 100644 index 00000000..5a665be9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Error.swift @@ -0,0 +1,101 @@ +// +// Error.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +public enum BloctoSDKError: Swift.Error { + // internal + case callbackSelfNotfound + case encodeToURLFailed + case webSDKSessionFailed + case decodeFailed + case responseUnexpected + case urlNotFound + case feePayerNotFound + + // info check + case appIdNotSet + + // query + case userRejected + case forbiddenBlockchain + case invalidResponse + case userNotMatch + + // format check + case ethSignInvalidHexString + + // web SDK + case userCancel + case redirectURLNotFound + case sessionError(code: Int) + + case other(code: String) + + init(code: String) { + switch code { + case Self.appIdNotSet.rawValue: + self = .appIdNotSet + case Self.userRejected.rawValue: + self = .userRejected + case Self.forbiddenBlockchain.rawValue: + self = .forbiddenBlockchain + case Self.invalidResponse.rawValue: + self = .invalidResponse + case Self.userNotMatch.rawValue: + self = .userNotMatch + case Self.ethSignInvalidHexString.rawValue: + self = .ethSignInvalidHexString + case Self.userCancel.rawValue: + self = .userCancel + case Self.redirectURLNotFound.rawValue: + self = .redirectURLNotFound + default: + self = .other(code: code) + } + } + + var rawValue: String { + switch self { + case .callbackSelfNotfound: + return "" + case .encodeToURLFailed: + return "" + case .webSDKSessionFailed: + return "" + case .decodeFailed: + return "" + case .responseUnexpected: + return "" + case .urlNotFound: + return "" + case .feePayerNotFound: + return "" + case .appIdNotSet: + return "app_id_not_set" + case .userRejected: + return "user_rejected" + case .forbiddenBlockchain: + return "forbidden_blockchain" + case .invalidResponse: + return "invalid_response" + case .userNotMatch: + return "user_not_match" + case .ethSignInvalidHexString: + return "eth_sign_invalid_hex_string" + case .userCancel: + return "webSDK_user_cancel" + case .redirectURLNotFound: + return "webSDK_redirect_url_not_found" + case let .sessionError(code): + return "webSDK_session_error_\(code)" + case let .other(code): + return code + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Method.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Method.swift new file mode 100644 index 00000000..0bae67bd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/Method.swift @@ -0,0 +1,17 @@ +// +// Method.swift +// Alamofire +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +public protocol Method { + var id: UUID { get } + var type: String { get } + + func encodeToURL(appId: String, baseURLString: String) throws -> URL? + func resolve(components: URLComponents, logging: Bool) + func handleError(error: Swift.Error) +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/MethodName.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/MethodName.swift new file mode 100644 index 00000000..73641c96 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/MethodName.swift @@ -0,0 +1,12 @@ +// +// MethodName.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/5/16. +// + +import Foundation + +public enum MethodName: String { + case requestAccount = "request_account" +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryEscape.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryEscape.swift new file mode 100644 index 00000000..0c67ad3f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryEscape.swift @@ -0,0 +1,16 @@ +// +// QueryEscape.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/5/13. +// + +import Foundation + +enum QueryEscape { + + static func escape(_ string: String) -> String { + string.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed) ?? string + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryItem.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryItem.swift new file mode 100644 index 00000000..a7283f6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryItem.swift @@ -0,0 +1,29 @@ +// +// QueryItem.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/16. +// + +import Foundation + +public struct QueryItem { + + let name: String + let value: Any + + init(name: QueryName, value: Any) { + self.name = name.rawValue + self.value = value + } + + init(nameString: String, value: Any) { + self.name = nameString + self.value = value + } + + var getQueryComponents: [URLQueryItem] { + URLEncoding.queryComponents(fromKey: name, value: value) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryName.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryName.swift new file mode 100644 index 00000000..84044e4f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Models/QueryName.swift @@ -0,0 +1,45 @@ +// +// QueryName.swift +// Alamofire +// +// Created by Andrew Wang on 2022/3/14. +// + +import Foundation + +public enum QueryName: String { + // request + case appId = "app_id" + case requestId = "request_id" + case blockchain + case method + case from + case to + case value + case data + case message + case signType = "type" + case isInvokeWrapped = "is_invoke_wrapped" + case appendTx = "append_tx" + case publicKeySignaturePairs = "public_key_signature_pairs" + + // flow only + case flowAppId = "flow_app_id" + case flowNonce = "flow_nonce" + case accountProof = "account_proof" + case userSignature = "user_signature" + case flowTransaction = "flow_transaction" + + // response + case address + case signature + case txHash = "tx_hash" + + // flow account proof + case keyId = "key_id" + + // error + case error + + case platform +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/AuthenticationSessioning.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/AuthenticationSessioning.swift new file mode 100644 index 00000000..b5e5a5cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/AuthenticationSessioning.swift @@ -0,0 +1,27 @@ +// +// AuthenticationSessioning.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/25. +// + +import Foundation +import AuthenticationServices + +public protocol AuthenticationSessioning { + + var presentationContextProvider: ASWebAuthenticationPresentationContextProviding? { get set } + + init( + url URL: URL, + callbackURLScheme: String?, + completionHandler: @escaping (URL?, Swift.Error?) -> Void + ) + + func start() -> Bool + +} + +// MARK: - ASWebAuthenticationSession + AuthenticationSessioning + +extension ASWebAuthenticationSession: AuthenticationSessioning {} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLOpening.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLOpening.swift new file mode 100644 index 00000000..16677ab5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLOpening.swift @@ -0,0 +1,20 @@ +// +// URLOpening.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/21. +// + +import UIKit + +public protocol URLOpening { + func open( + _ url: URL, + options: [UIApplication.OpenExternalURLOptionsKey: Any], + completionHandler completion: ((Bool) -> Void)? + ) +} + +// MARK: - UIApplication + URLOpening + +extension UIApplication: URLOpening {} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLSessionProtocol.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLSessionProtocol.swift new file mode 100644 index 00000000..c086380f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Protocols/URLSessionProtocol.swift @@ -0,0 +1,18 @@ +// +// URLSessionProtocol.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/8/22. +// + +import Foundation +import UIKit + +public protocol URLSessionProtocol { + func dataTask( + with request: URLRequest, + completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void + ) -> URLSessionDataTask +} + +extension URLSession: URLSessionProtocol {} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/QueryDecoding.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/QueryDecoding.swift new file mode 100644 index 00000000..bf5235a4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/QueryDecoding.swift @@ -0,0 +1,127 @@ +// +// QueryDecoding.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/4/6. +// + +import Foundation + +public enum QueryDecoding { + + static func decodeArray( + param: [String: String], + queryName: QueryName + ) -> [T] { + do { + let array = try decodeArray( + param: param, + target: queryName.rawValue + ) + switch T.self { + case is String.Type: + if let value = array as? [T] { + return value + } else { + return [T]() + } + case is Data.Type: + return array.reduce([T]()) { partialResult, value in + var result = partialResult + if let data = value + .bloctoSDK.drop0x + .bloctoSDK.hexDecodedData as? T { + result.append(data) + } + return result + } + default: + return [T]() + } + } catch { + return [T]() + } + } + + static func decodeDictionary( + param: [String: String], + queryName: QueryName + ) -> [String: T] { + do { + let dictionary = try decodeDictionary( + param: param, + target: queryName.rawValue + ) + switch T.self { + case is String.Type: + if let value = dictionary[queryName.rawValue] as? [String: T] { + return value + } else { + return [String: T]() + } + case is Data.Type: + if let value = dictionary[queryName.rawValue] as? [String: String] { + return value.reduce([String: T]()) { partialResult, value in + var result = partialResult + result[value.key] = value.value + .bloctoSDK.drop0x + .bloctoSDK.hexDecodedData as? T + return result + } + } else { + return [String: T]() + } + default: + return [String: T]() + } + } catch { + return [String: T]() + } + } + + private static func decodeArray( + param: [String: String], + target: String + ) throws -> [String] { + let leftBrackets = "[" + let rightBrackets = "]" + let array: [String] = param.reduce([]) { + if $1.key == (target + leftBrackets + rightBrackets) { + var copied = $0 + copied.append($1.value) + return copied + } + return $0 + } + return array + } + + private static func decodeDictionary( + param: [String: String], + target: String + ) throws -> [String: Any] { + let leftBrackets = "[" + let rightBrackets = "]" + let targets: [String: String] = param.reduce([:]) { + var copied = $0 + copied[$1.key] = ($1.key.contains(target) ? $1.value : nil) + return copied + } + let regex = try NSRegularExpression(pattern: #"(?<=\\#(leftBrackets))(.*?)(?=\\#(rightBrackets))"#) + let value = targets.reduce([:]) { result, target -> [String: String] in + var finalResult = result + if let result: NSTextCheckingResult = regex.firstMatch( + in: target.key, + range: NSRange(target.key.startIndex..., in: target.key) + ), + let range = Range(result.range, in: target.key) { + finalResult[String(target.key[range])] = target.value + return finalResult + } else { + return finalResult + } + } + return [target: value] + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/RequestBuilder.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/RequestBuilder.swift new file mode 100644 index 00000000..1894045c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/RequestBuilder.swift @@ -0,0 +1,36 @@ +// +// RequestBuilder.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/8/19. +// + +import Foundation + +enum RequestBuilder { + + enum Method: String { + case get = "GET" + case post = "POST" + } + + static func build( + baseURLString: String, + path: String, + method: Method, + bodyParam: [String: Value] + ) throws -> URLRequest where Value: Encodable { + guard let requestURL = URL(string: BloctoSDK.shared.bloctoApiBaseURLString + path) else { + throw BloctoSDKError.urlNotFound + } + var request = URLRequest(url: requestURL) + request.httpMethod = method.rawValue + if bodyParam.isEmpty == false { + let encoder = JSONEncoder() + let encodedData = try encoder.encode(bodyParam) + request.httpBody = encodedData + } + return request + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/URLEncoding.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/URLEncoding.swift new file mode 100644 index 00000000..5f037233 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Core/Utilities/URLEncoding.swift @@ -0,0 +1,153 @@ +// +// URLEncoding.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/3/21. +// + +import Foundation + +public enum URLEncoding { + + static func queryGeneralItems( + appId: String, + requestId: String, + blockchain: Blockchain + ) -> [QueryItem] { + + let platform: String = "sdk_ios" + + let queryItems = [ + QueryItem(name: .appId, value: appId), + QueryItem(name: .requestId, value: requestId), + QueryItem(name: .blockchain, value: blockchain.rawValue), + QueryItem(name: .platform, value: platform) + ] + return queryItems + } + + static func encode(_ queryItems: [QueryItem]) -> [URLQueryItem] { + queryItems.flatMap(\.getQueryComponents) + } + + static func queryComponents(fromKey key: String, value: Any) -> [URLQueryItem] { + var components: [URLQueryItem] = [] + switch value { + case let dictionary as [String: Any]: + for (nestedKey, value) in dictionary { + components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value) + } + case let array as [Any]: + let arrayEncoding = ArrayEncoding() + for value in array { + components += queryComponents(fromKey: arrayEncoding.encode(key: key), value: value) + } + case let number as NSNumber: + if number.isBool { + let boolEncoding = BoolEncoding() + components.append( + .init( + name: key, + value: escape(boolEncoding.encode(value: number.boolValue)) + )) + } else { + components.append( + .init( + name: key, + value: escape("\(number)") + )) + } + case let bool as Bool: + let boolEncoding = BoolEncoding() + components.append( + .init( + name: key, + value: escape(boolEncoding.encode(value: bool)) + )) + case let data as Data: + components.append( + .init( + name: key, + value: data.bloctoSDK.hexStringWith0xPrefix + )) + case let string as String: + components.append( + .init( + name: key, + value: string + )) + default: + components.append( + .init( + name: key, + value: "\(value)" + )) + } + return components + } + + static func solanaAppendMessagesQueryItems(dictionary: [String: Data]) -> [URLQueryItem] { + var components: [URLQueryItem] = [] + for (nestedKey, value) in dictionary { + components.append( + .init( + name: "\(QueryName.appendTx.rawValue)[\(nestedKey)]", + value: escape(value.bloctoSDK.hexString) + )) + } + return components + } + + private static func escape(_ string: String) -> String { + QueryEscape.escape(string) + } + +} + +struct ArrayEncoding { + + func encode(key: String) -> String { + "\(key)[]" + } + +} + +struct DictionaryEncoding { + + func encode( + key: String, + value: [String: Any] + ) -> String { + "\(key)[]" + } + +} + +struct BoolEncoding { + + func encode(value: Bool) -> String { + value ? "true" : "false" + } + +} + +extension CharacterSet { + /// Creates a CharacterSet from RFC 3986 allowed characters. + /// + /// RFC 3986 states that the following characters are "reserved" characters. + /// + /// - General Delimiters: ":", "#", "[", "]", "@", "?", "/" + /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" + /// + /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow + /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" + /// should be percent-escaped in the query string. + public static let afURLQueryAllowed: CharacterSet = { + let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 + let subDelimitersToEncode = "!$&'()*+,;=" + let encodableDelimiters = CharacterSet(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") + + return CharacterSet.urlQueryAllowed.subtracting(encodableDelimiters) + }() + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/BloctoFlowSDK.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/BloctoFlowSDK.swift new file mode 100644 index 00000000..aa195b3c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/BloctoFlowSDK.swift @@ -0,0 +1,123 @@ +// +// BloctoFlowSDK.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation +import FlowSDK +import Cadence + +private var associateKey: Void? + +extension BloctoSDK { + + public var flow: BloctoFlowSDK { + if let flowSDK = objc_getAssociatedObject(self, &associateKey) as? BloctoFlowSDK { + return flowSDK + } else { + let flowSDK = BloctoFlowSDK(base: self) + objc_setAssociatedObject(self, &associateKey, flowSDK, .OBJC_ASSOCIATION_RETAIN) + return flowSDK + } + } + +} + +public class BloctoFlowSDK { + + private let base: BloctoSDK + + init(base: BloctoSDK) { + self.base = base + } + + /// Ask for User's authantication to request Flow account address + /// - Parameters: + /// - id: The id to identify this request, you can pass your owned uuid here. + /// - accountProofData: accountProofData to be sign along with authantication + /// - completion: completion handler for this methods. Please note this completion might not be called in some circumstances. e.g. SDK version incompatible with Blocto Wallet app. + /// - Completion: The successful result is a tuple of address String with accountProof for Flow. + public func authanticate( + id: UUID = UUID(), + accountProofData: FlowAccountProofData?, + completion: @escaping (Result<(address: String, accountProof: [FlowCompositeSignature]), Swift.Error>) -> Void + ) { + let method = AuthenticateMethod( + id: id, + accountProofData: accountProofData, + callback: completion + ) + base.send( + method: method, + fallbackToWebSDK: false + ) + } + + /// To sign Flow message + /// - Parameters: + /// - uuid: The id to identify this request, you can pass your owned uuid here. + /// - from: send from which address. + /// - message: message needs to be sign in String format. + /// - signType: pre-defined signType in BloctoSDK/EVMBase + /// - completion: completion handler for this methods. Please note this completion might not be called in some circumstances. e.g. SDK version incompatible with Blocto Wallet app. + public func signMessage( + uuid: UUID = UUID(), + from: String, + message: String, + completion: @escaping (Result<[FlowCompositeSignature], Swift.Error>) -> Void + ) { + let method = SignFlowMessageMethod( + id: uuid, + from: from, + message: message, + callback: completion + ) + base.send( + method: method, + fallbackToWebSDK: false + ) + } + + /// To sign Flow transaction and then send transaction. + /// - Parameters: + /// - uuid: The id to identify this request, you can pass your owned uuid here. + /// - from: Send from which address. + /// - transaction: Pre-defined Flow Transaction. + /// - completion: completion handler for this methods. Please note this completion might not be called in some circumstances. e.g. SDK version incompatible with Blocto Wallet app. + /// The successful result is Tx hash of Flow. + public func sendTransaction( + uuid: UUID = UUID(), + from: Cadence.Address, + transaction: Transaction, + completion: @escaping (Result) -> Void + ) { + let method = SendFlowTransactionMethod( + id: uuid, + from: from, + transaction: transaction, + callback: completion + ) + base.send( + method: method, + fallbackToWebSDK: false + ) + } + + public func getFeePayerAddress() async throws -> Cadence.Address { + guard let url = URL(string: base.bloctoApiBaseURLString + "/flow/feePayer") else { + throw BloctoSDKError.urlNotFound + } + + let feePayerRequest = URLRequest(url: url) + + let response: [String: String] = try await URLSession(configuration: .default) + .dataDecode(for: feePayerRequest) + guard let address = response["address"] else { + throw BloctoSDKError.feePayerNotFound + } + return Address(hexString: address) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLComponentsExtensions.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLComponentsExtensions.swift new file mode 100644 index 00000000..8ca19e2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLComponentsExtensions.swift @@ -0,0 +1,51 @@ +// +// URLComponents.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation + +extension URLComponents { + + func getSignatures(type: FlowSignatureType) -> [FlowCompositeSignature] { + let keyword: String + switch type { + case .accountProof: + keyword = QueryName.accountProof.rawValue + case .userSignature: + keyword = QueryName.userSignature.rawValue + } + let items = queryItems?.filter { $0.name.contains(keyword) } ?? [] + let dic = items.reduce([String: String]()) { + var result = $0 + result[$1.name.removingPercentEncoding ?? $1.name] = $1.value + return result + } + precondition(items.count % 3 == 0, "AcountProof query item should be multiple of 3.") + let signatureCount = items.count / 3 + if signatureCount > 0 { + var result: [FlowCompositeSignature] = [] + for index in 0 ... (signatureCount - 1) { + if let address = dic[keyword + "[\(index)]" + "[\(QueryName.address.rawValue)]"], + let keyIdString = dic[keyword + "[\(index)]" + "[\(QueryName.keyId.rawValue)]"], + let keyId = Int(keyIdString), + let signature = dic[keyword + "[\(index)]" + "[\(QueryName.signature.rawValue)]"] { + result.append( + FlowCompositeSignature( + address: address, + keyId: keyId, + signature: signature + ) + ) + } + } + precondition(result.count == signatureCount, "AcountProof query item should be multiple of 3.") + return result + } else { + return [] + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLSessionExtension.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLSessionExtension.swift new file mode 100644 index 00000000..5567ec36 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Extensions/URLSessionExtension.swift @@ -0,0 +1,43 @@ +// +// URLSessionExtension.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/8/18. +// + +import UIKit + +extension URLSession { + + static let decoder = JSONDecoder() + + func dataDecode(for request: URLRequest) async throws -> Model { + let data = try await data(for: request) + return try Self.decoder.decode(Model.self, from: data) + } + + private func data(for request: URLRequest) async throws -> Data { + try await withCheckedThrowingContinuation { continuation in + dataTask(with: request) { data, response, error in + guard let response = response as? HTTPURLResponse, + (200 ..< 300) ~= response.statusCode else { + log(enable: BloctoSDK.shared.logging, message: "error: \(error.debugDescription)") + if let data = data, + let text = String(data: data, encoding: .utf8) { + log(enable: BloctoSDK.shared.logging, message: "response: \(text)") + } + continuation.resume(with: .failure(BloctoSDKError.responseUnexpected)) + return + } + if let error = error { + continuation.resume(with: .failure(error)) + } else if let data = data { + continuation.resume(with: .success(data)) + } else { + continuation.resume(with: .failure(BloctoSDKError.responseUnexpected)) + } + }.resume() + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/AuthenticateMethod.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/AuthenticateMethod.swift new file mode 100644 index 00000000..5e9468c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/AuthenticateMethod.swift @@ -0,0 +1,87 @@ +// +// AuthenticateMethod.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation + +public struct AuthenticateMethod: CallbackMethod { + public typealias Response = (address: String, accountProof: [FlowCompositeSignature]) + + public let id: UUID + public let type: String = FlowMethodType.authenticate.rawValue + public let callback: Callback + + let blockchain: Blockchain = .flow + let accountProofData: FlowAccountProofData? + + /// initialize request account method + /// - Parameters: + /// - id: Used to find a stored callback. No need to pass if there is no specific requirement, for example, testing. + /// - callback: callback will be called by either from blocto native app or web SDK after getting account or reject. + public init( + id: UUID = UUID(), + accountProofData: FlowAccountProofData?, + callback: @escaping Callback + ) { + self.id = id + self.accountProofData = accountProofData + self.callback = callback + } + + public func encodeToURL(appId: String, baseURLString: String) throws -> URL? { + guard let baseURL = URL(string: baseURLString), + var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: true) else { + return nil + } + var queryItems = URLEncoding.queryGeneralItems( + appId: appId, + requestId: id.uuidString, + blockchain: blockchain + ) + queryItems.append( + QueryItem( + name: .method, + value: type + ) + ) + if let accountProofData = accountProofData { + queryItems.append(contentsOf: [ + QueryItem( + name: .flowAppId, + value: accountProofData.appId + ), + QueryItem( + name: .flowNonce, + value: accountProofData.nonce + ), + ]) + } + components.queryItems = URLEncoding.encode(queryItems) + return components.url + } + + public func resolve(components: URLComponents, logging: Bool) { + if let errorCode = components.queryItem(for: .error) { + callback(.failure(BloctoSDKError(code: errorCode))) + return + } + let targetQueryName = QueryName.address + guard let address = components.queryItem(for: targetQueryName) else { + log( + enable: logging, + message: "\(targetQueryName.rawValue) not found." + ) + callback(.failure(BloctoSDKError.invalidResponse)) + return + } + let signatures = components.getSignatures(type: .accountProof) + callback(.success((address: address, accountProof: signatures))) + } + + public func handleError(error: Swift.Error) { + callback(.failure(error)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SendFlowTransactionMethod.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SendFlowTransactionMethod.swift new file mode 100644 index 00000000..614ed7e7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SendFlowTransactionMethod.swift @@ -0,0 +1,84 @@ +// +// SendFlowTransactionMethod.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/8/3. +// + +import Foundation +import Cadence +import FlowSDK + +public struct SendFlowTransactionMethod: CallbackMethod { + public typealias Response = String + + public let id: UUID + public let type: String = FlowMethodType.sendTransaction.rawValue + public let from: Address + public let transaction: Transaction + public let callback: Callback + + let blockchain: Blockchain = .flow + + /// initialize request account method + /// - Parameters: + /// - id: Used to find a stored callback. No need to pass if there is no specific requirement, for example, testing. + /// - from: Pre-defined Cadence Address. + /// - transactionInfo: Elements describe Flow transaction. + /// - callback: callback will be called by either from blocto native app or web SDK after getting account or reject. + public init( + id: UUID = UUID(), + from: Address, + transaction: Transaction, + callback: @escaping Callback + ) { + self.id = id + self.from = from + self.transaction = transaction + self.callback = callback + } + + public func encodeToURL(appId: String, baseURLString: String) throws -> URL? { + guard let baseURL = URL(string: baseURLString), + var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: false) else { + return nil + } + var queryItems: [QueryItem] = URLEncoding.queryGeneralItems( + appId: appId, + requestId: id.uuidString, + blockchain: blockchain + ) + + let transactionDataHex = transaction.encode().bloctoSDK.hexString + + queryItems.append(contentsOf: [ + QueryItem(name: .method, value: type), + QueryItem(name: .from, value: from.hexStringWithPrefix), + QueryItem(name: .flowTransaction, value: transactionDataHex), + ]) + + components.queryItems = URLEncoding.encode(queryItems) + return components.url + } + + public func resolve(components: URLComponents, logging: Bool) { + if let errorCode = components.queryItem(for: .error) { + callback(.failure(BloctoSDKError(code: errorCode))) + return + } + let targetQueryName = QueryName.txHash + guard let txHash = components.queryItem(for: targetQueryName) else { + log( + enable: logging, + message: "\(targetQueryName.rawValue) not found." + ) + callback(.failure(BloctoSDKError.invalidResponse)) + return + } + callback(.success(txHash)) + } + + public func handleError(error: Swift.Error) { + callback(.failure(error)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SignFlowMessageMethod.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SignFlowMessageMethod.swift new file mode 100644 index 00000000..57e4d46b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Methods/SignFlowMessageMethod.swift @@ -0,0 +1,73 @@ +// +// SignFlowMessageMethod.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/13. +// + +import Foundation + +public struct SignFlowMessageMethod: CallbackMethod { + + public typealias Response = [FlowCompositeSignature] + + public let id: UUID + public let type: String = FlowMethodType.userSignature.rawValue + public let callback: Callback + + let blockchain: Blockchain = .flow + let from: String + let message: String + + /// initialize sign EVMBase message method + /// - Parameters: + /// - id: Used to find a stored callback. No need to pass if there is no specific requirement, for example, testing. + /// - from: send from which address. + /// - message: message needs to be sign in String format. + /// - signType: pre-defined signType in BloctoSDK/EVMBase + /// - blockchain: pre-defined blockchain in BloctoSDK + /// - callback: callback will be called by either from blocto native app or web SDK after getting account or reject. + public init( + id: UUID = UUID(), + from: String, + message: String, + callback: @escaping SignFlowMessageMethod.Callback + ) { + self.id = id + self.from = from + self.message = message + self.callback = callback + } + + public func encodeToURL(appId: String, baseURLString: String) throws -> URL? { + guard let baseURL = URL(string: baseURLString), + var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: true) else { + return nil + } + var queryItems = URLEncoding.queryGeneralItems( + appId: appId, + requestId: id.uuidString, + blockchain: blockchain + ) + queryItems.append(contentsOf: [ + QueryItem(name: .method, value: type), + QueryItem(name: .from, value: from), + ]) + queryItems.append(QueryItem(name: .message, value: message)) + components.queryItems = URLEncoding.encode(queryItems) + return components.url + } + + public func resolve(components: URLComponents, logging: Bool) { + if let errorCode = components.queryItem(for: .error) { + callback(.failure(BloctoSDKError(code: errorCode))) + return + } + let signatures = components.getSignatures(type: .userSignature) + callback(.success(signatures)) + } + + public func handleError(error: Swift.Error) { + callback(.failure(error)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowAccountProofData.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowAccountProofData.swift new file mode 100644 index 00000000..96ae8938 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowAccountProofData.swift @@ -0,0 +1,25 @@ +// +// FlowAccountProofData.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation + +public struct FlowAccountProofData { + + /// A human-readable string e.g. "Blocto", "NBA Top Shot" + public let appId: String + /// minimum 32-byte random nonce + public let nonce: String + + public init( + appId: String, + nonce: String + ) { + self.appId = appId + self.nonce = nonce + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowCompositeSignature.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowCompositeSignature.swift new file mode 100644 index 00000000..2660636b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowCompositeSignature.swift @@ -0,0 +1,46 @@ +// +// FlowCompositeSignature.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation + +public struct FlowCompositeSignature: Decodable { + + public let address: String + public let keyId: Int + /// hex string + public let signature: String + + public init( + address: String, + keyId: Int, + signature: String + ) { + self.address = address + self.keyId = keyId + self.signature = signature + } +} + +extension FlowCompositeSignature { + + init?(param: [String: String]) { + guard let address = param["address"] else { + return nil + } + guard let keyIdString = param["keyId"], + let keyId = Int(keyIdString) else { + return nil + } + guard let signature = param["signature"] else { + return nil + } + self.address = address + self.keyId = keyId + self.signature = signature + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodContentType.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodContentType.swift new file mode 100644 index 00000000..737bf332 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodContentType.swift @@ -0,0 +1,19 @@ +// +// FlowMethodContentType.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation +import FlowSDK + +public enum FlowMethodContentType { + + case authenticate(accountProofData: FlowAccountProofData?) + + case userSignature(from: String, message: String) + + case sendTransaction(from: String, transaction: Transaction) + +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodType.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodType.swift new file mode 100644 index 00000000..54a049c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowMethodType.swift @@ -0,0 +1,15 @@ +// +// FlowMethodType.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/7. +// + +import Foundation + +public enum FlowMethodType: String { + case requestAccount = "request_account" + case authenticate = "authn" + case userSignature = "user_signature" + case sendTransaction = "flow_send_transaction" +} diff --git a/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowSignatureType.swift b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowSignatureType.swift new file mode 100644 index 00000000..c51407d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/BloctoSDK/Sources/Flow/Models/FlowSignatureType.swift @@ -0,0 +1,13 @@ +// +// FlowSignatureType.swift +// BloctoSDK +// +// Created by Andrew Wang on 2022/7/20. +// + +import Foundation + +public enum FlowSignatureType { + case accountProof + case userSignature +} diff --git a/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/LICENSE b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/README.md b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/README.md new file mode 100644 index 00000000..04083746 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/README.md @@ -0,0 +1,166 @@ +[![CI](https://img.shields.io/github/workflow/status/grpc/grpc-swift/CI?event=push)](https://github.com/grpc/grpc-swift/actions/workflows/ci.yaml) +[![Latest Version](https://img.shields.io/github/v/release/grpc/grpc-swift?include_prereleases&sort=semver)](https://img.shields.io/github/v/release/grpc/grpc-swift?include_prereleases&sort=semver) +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# gRPC Swift + +This repository contains a gRPC Swift API and code generator. + +It is intended for use with Apple's [SwiftProtobuf][swift-protobuf] support for +Protocol Buffers. Both projects contain code generation plugins for `protoc`, +Google's Protocol Buffer compiler, and both contain libraries of supporting code +that is needed to build and run the generated code. + +APIs and generated code is provided for both gRPC clients and servers, and can +be built either with Xcode or the Swift Package Manager. Support is provided for +all four gRPC API styles (Unary, Server Streaming, Client Streaming, and +Bidirectional Streaming) and connections can be made either over secure (TLS) or +insecure channels. + +## Versions + +gRPC Swift has recently been rewritten on top of [SwiftNIO][swift-nio] as +opposed to the core library provided by the [gRPC project][grpc]. + +Version | Implementation | Branch | `protoc` Plugin | Support +--------|----------------|------------------------|-------------------------|----------------------------------------- +1.x | SwiftNIO | [`main`][branch-new] | `protoc-gen-grpc-swift` | Actively developed and supported +0.x | gRPC C library | [`cgrpc`][branch-old] | `protoc-gen-swiftgrpc` | No longer developed; security fixes only + +The remainder of this README refers to the 1.x version of gRPC Swift. + + +## Supported Platforms + +gRPC Swift's platform support is identical to the [platform support of Swift +NIO][swift-nio-platforms]. + +The earliest supported Swift version for gRPC Swift 1.8.x and newer is 5.4. +For 1.7.x and earlier the oldest supported Swift version is 5.2. + +Versions of clients and services which are use Swift's Concurrency support +are available from gRPC Swift 1.8.0 and require Swift 5.6 and newer. + +## Getting gRPC Swift + +There are two parts to gRPC Swift: the gRPC library and an API code generator. + +### Getting the gRPC library + +#### Swift Package Manager + +The Swift Package Manager is the preferred way to get gRPC Swift. Simply add the +package dependency to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0") +] +``` + +...and depend on `"GRPC"` in the necessary targets: + +```swift +.target( + name: ..., + dependencies: [.product(name: "GRPC", package: "grpc-swift")] +] +``` + +##### Xcode + +From Xcode 11 it is possible to [add Swift Package dependencies to Xcode +projects][xcode-spm] and link targets to products of those packages; this is the +easiest way to integrate gRPC Swift with an existing `xcodeproj`. + +##### Manual Integration + +Alternatively, gRPC Swift can be manually integrated into a project: + +1. Build an Xcode project: `swift package generate-xcodeproj`, +1. Add the generated project to your own project, and +1. Add a build dependency on `GRPC`. + +### Getting the `protoc` Plugins + +Binary releases of `protoc`, the Protocol Buffer Compiler, are available on +[GitHub][protobuf-releases]. + +To build the plugins, run `make plugins` in the main directory. This uses the +Swift Package Manager to build both of the necessary plugins: +`protoc-gen-swift`, which generates Protocol Buffer support code and +`protoc-gen-grpc-swift`, which generates gRPC interface code. + +To install these plugins, just copy the two executables (`protoc-gen-swift` and +`protoc-gen-grpc-swift`) that show up in the main directory into a directory +that is part of your `PATH` environment variable. Alternatively the full path to +the plugins can be specified when using `protoc`. + +#### Homebrew + +The plugins are available from [homebrew](https://brew.sh) and can be installed with: +```bash + $ brew install swift-protobuf grpc-swift +``` + +## Examples + +gRPC Swift has a number of tutorials and examples available. They are split +across two directories: + +- [`/Sources/Examples`][examples-in-source] contains examples which do not + require additional dependencies and may be built using the Swift Package + Manager. +- [`/Examples`][examples-out-of-source] contains examples which rely on + external dependencies or may not be built by the Swift Package Manager (such + as an iOS app). + +Some of the examples are accompanied by tutorials, including: +- A [quick start guide][docs-quickstart] for creating and running your first + gRPC service. +- A [basic tutorial][docs-tutorial] covering the creation and implementation of + a gRPC service using all four call types as well as the code required to setup + and run a server and make calls to it using a generated client. +- An [interceptors][docs-interceptors-tutorial] tutorial covering how to create + and use interceptors with gRPC Swift. + +## Documentation + +The `docs` directory contains documentation, including: + +- Options for the `protoc` plugin in [`docs/plugin.md`][docs-plugin] +- How to configure TLS in [`docs/tls.md`][docs-tls] +- How to configure keepalive in [`docs/keepalive.md`][docs-keepalive] +- Support for Apple Platforms and NIO Transport Services in + [`docs/apple-platforms.md`][docs-apple] + +## Security + +Please see [SECURITY.md](SECURITY.md). + +## License + +gRPC Swift is released under the same license as [gRPC][grpc], repeated in +[LICENSE](LICENSE). + +## Contributing + +Please get involved! See our [guidelines for contributing](CONTRIBUTING.md). + +[docs-apple]: ./docs/apple-platforms.md +[docs-plugin]: ./docs/plugin.md +[docs-quickstart]: ./docs/quick-start.md +[docs-tls]: ./docs/tls.md +[docs-keepalive]: ./docs/keepalive.md +[docs-tutorial]: ./docs/basic-tutorial.md +[docs-interceptors-tutorial]: ./docs/interceptors-tutorial.md +[grpc]: https://github.com/grpc/grpc +[protobuf-releases]: https://github.com/protocolbuffers/protobuf/releases +[swift-nio-platforms]: https://github.com/apple/swift-nio#supported-platforms +[swift-nio]: https://github.com/apple/swift-nio +[swift-protobuf]: https://github.com/apple/swift-protobuf +[xcode-spm]: https://help.apple.com/xcode/mac/current/#/devb83d64851 +[branch-new]: https://github.com/grpc/grpc-swift/tree/main +[branch-old]: https://github.com/grpc/grpc-swift/tree/cgrpc +[examples-out-of-source]: https://github.com/grpc/grpc-swift/tree/main/Examples +[examples-in-source]: https://github.com/grpc/grpc-swift/tree/main/Sources/Examples diff --git a/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/empty.c b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/empty.c new file mode 100644 index 00000000..13f77e71 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/empty.c @@ -0,0 +1,19 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Xcode's Archive builds with Xcode's Package support struggle with empty .c files +// (https://bugs.swift.org/browse/SR-12939). +void CGRPCZlib_i_do_nothing_just_working_around_a_darwin_toolchain_bug(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/include/CGRPCZlib.h b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/include/CGRPCZlib.h new file mode 100644 index 00000000..3cea97af --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CGRPCZlibp/Sources/CGRPCZlib/include/CGRPCZlib.h @@ -0,0 +1,62 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef C_GRPC_ZLIB_H_ +#define C_GRPC_ZLIB_H_ + +#include + +static inline int CGRPCZlib_deflateInit2(z_streamp stream, int level, int method, int windowBits, + int memLevel, int strategy) { + return deflateInit2(stream, level, method, windowBits, memLevel, strategy); +} + +static inline unsigned long CGRPCZlib_deflateBound(z_streamp strm, unsigned long sourceLen) { + return deflateBound(strm, sourceLen); +} + +static inline int CGRPCZlib_deflate(z_streamp strm, int flush) { + return deflate(strm, flush); +} + +static inline int CGRPCZlib_deflateReset(z_streamp strm) { + return deflateReset(strm); +} + +static inline int CGRPCZlib_deflateEnd(z_streamp strm) { + return deflateEnd(strm); +} + +static inline int CGRPCZlib_inflateInit2(z_streamp stream, int windowBits) { + return inflateInit2(stream, windowBits); +} + +static inline int CGRPCZlib_inflate(z_streamp strm, int flush) { + return inflate(strm, flush); +} + +static inline int CGRPCZlib_inflateReset(z_streamp strm) { + return inflateReset(strm); +} + +static inline int CGRPCZlib_inflateEnd(z_streamp strm) { + return inflateEnd(strm); +} + +static inline Bytef *CGRPCZlib_castVoidToBytefPointer(void *in) { + return (Bytef *) in; +} + +#endif // C_GRPC_ZLIB_H_ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/include/CNIOAtomics.h b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/include/CNIOAtomics.h new file mode 100644 index 00000000..2f353c7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/include/CNIOAtomics.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#include +#include + +#define DECLARE_ATOMIC_OPERATIONS(type, name) \ + struct catmc_atomic_ ## name; \ + \ + struct catmc_atomic_ ## name * _Nonnull catmc_atomic_ ## name ## _create(type value); \ + void catmc_atomic_ ## name ## _destroy(struct catmc_atomic_ ## name * _Nonnull); \ + bool catmc_atomic_ ## name ## _compare_and_exchange(struct catmc_atomic_ ## name * _Nonnull, type expected, type desired); \ + type catmc_atomic_ ## name ## _add(struct catmc_atomic_ ## name * _Nonnull, type value); \ + type catmc_atomic_ ## name ## _sub(struct catmc_atomic_ ## name * _Nonnull, type value); \ + type catmc_atomic_ ## name ## _exchange(struct catmc_atomic_ ## name * _Nonnull, type value); \ + type catmc_atomic_ ## name ## _load(struct catmc_atomic_ ## name * _Nonnull); \ + void catmc_atomic_ ## name ## _store(struct catmc_atomic_ ## name * _Nonnull, type value); \ + \ + struct catmc_nio_atomic_ ## name { \ + _Atomic type value; \ + }; \ + \ + void catmc_nio_atomic_ ## name ## _create_with_existing_storage(struct catmc_nio_atomic_ ## name * _Nonnull, type value); \ + bool catmc_nio_atomic_ ## name ## _compare_and_exchange(struct catmc_nio_atomic_ ## name * _Nonnull, type expected, type desired); \ + type catmc_nio_atomic_ ## name ## _add(struct catmc_nio_atomic_ ## name * _Nonnull, type value); \ + type catmc_nio_atomic_ ## name ## _sub(struct catmc_nio_atomic_ ## name * _Nonnull, type value); \ + type catmc_nio_atomic_ ## name ## _exchange(struct catmc_nio_atomic_ ## name * _Nonnull, type value); \ + type catmc_nio_atomic_ ## name ## _load(struct catmc_nio_atomic_ ## name * _Nonnull); \ + void catmc_nio_atomic_ ## name ## _store(struct catmc_nio_atomic_ ## name * _Nonnull, type value); \ + +DECLARE_ATOMIC_OPERATIONS(_Bool, _Bool) +DECLARE_ATOMIC_OPERATIONS(char, char) +DECLARE_ATOMIC_OPERATIONS(short, short) +DECLARE_ATOMIC_OPERATIONS(int, int) +DECLARE_ATOMIC_OPERATIONS(long, long) +DECLARE_ATOMIC_OPERATIONS(long long, long_long) + +DECLARE_ATOMIC_OPERATIONS(signed char, signed_char) +DECLARE_ATOMIC_OPERATIONS(signed short, signed_short) +DECLARE_ATOMIC_OPERATIONS(signed int, signed_int) +DECLARE_ATOMIC_OPERATIONS(signed long, signed_long) +DECLARE_ATOMIC_OPERATIONS(signed long long, signed_long_long) + +DECLARE_ATOMIC_OPERATIONS(unsigned char, unsigned_char) +DECLARE_ATOMIC_OPERATIONS(unsigned short, unsigned_short) +DECLARE_ATOMIC_OPERATIONS(unsigned int, unsigned_int) +DECLARE_ATOMIC_OPERATIONS(unsigned long, unsigned_long) +DECLARE_ATOMIC_OPERATIONS(unsigned long long, unsigned_long_long) + +DECLARE_ATOMIC_OPERATIONS(int_least8_t, int_least8_t) +DECLARE_ATOMIC_OPERATIONS(uint_least8_t, uint_least8_t) + +DECLARE_ATOMIC_OPERATIONS(int_least16_t, int_least16_t) +DECLARE_ATOMIC_OPERATIONS(uint_least16_t, uint_least16_t) + +DECLARE_ATOMIC_OPERATIONS(int_least32_t, int_least32_t) +DECLARE_ATOMIC_OPERATIONS(uint_least32_t, uint_least32_t) + +DECLARE_ATOMIC_OPERATIONS(int_least64_t, int_least64_t) +DECLARE_ATOMIC_OPERATIONS(uint_least64_t, uint_least64_t) + +DECLARE_ATOMIC_OPERATIONS(intptr_t, intptr_t) +DECLARE_ATOMIC_OPERATIONS(uintptr_t, uintptr_t) + +#undef DECLARE_ATOMIC_OPERATIONS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-atomics.c b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-atomics.c new file mode 100644 index 00000000..f946e9ae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-atomics.c @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include + +#include "../include/CNIOAtomics.h" +#include "cpp_magic.h" + +#define MAKE(type) /* +*/ struct catmc_atomic_##type { /* +*/ _Atomic type value; /* +*/ }; /* +*/ /* +*/ struct catmc_atomic_##type *catmc_atomic_##type##_create(type value) { /* +*/ struct catmc_atomic_##type *wrapper = malloc(sizeof(*wrapper)); /* +*/ atomic_init(&wrapper->value, value); /* +*/ return wrapper; /* +*/ } /* +*/ /* +*/ void catmc_atomic_##type##_destroy(struct catmc_atomic_##type *wrapper) { /* +*/ free(wrapper); /* +*/ } /* +*/ /* +*/ bool catmc_atomic_##type##_compare_and_exchange(struct catmc_atomic_##type *wrapper, type expected, type desired) { /* +*/ type expected_copy = expected; /* +*/ return atomic_compare_exchange_strong(&wrapper->value, &expected_copy, desired); /* +*/ } /* +*/ /* +*/ type catmc_atomic_##type##_add(struct catmc_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_add_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_atomic_##type##_sub(struct catmc_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_sub_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_atomic_##type##_exchange(struct catmc_atomic_##type *wrapper, type value) { /* +*/ return atomic_exchange_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_atomic_##type##_load(struct catmc_atomic_##type *wrapper) { /* +*/ return atomic_load_explicit(&wrapper->value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ void catmc_atomic_##type##_store(struct catmc_atomic_##type *wrapper, type value) { /* +*/ atomic_store_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } + +typedef signed char signed_char; +typedef signed short signed_short; +typedef signed int signed_int; +typedef signed long signed_long; +typedef signed long long signed_long_long; +typedef unsigned char unsigned_char; +typedef unsigned short unsigned_short; +typedef unsigned int unsigned_int; +typedef unsigned long unsigned_long; +typedef unsigned long long unsigned_long_long; +typedef long long long_long; + +MAP(MAKE,EMPTY, + bool, + char, short, int, long, long_long, + signed_char, signed_short, signed_int, signed_long, signed_long_long, + unsigned_char, unsigned_short, unsigned_int, unsigned_long, unsigned_long_long, + int_least8_t, uint_least8_t, + int_least16_t, uint_least16_t, + int_least32_t, uint_least32_t, + int_least64_t, uint_least64_t, + intptr_t, uintptr_t + ) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-nioatomics.c b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-nioatomics.c new file mode 100644 index 00000000..b306df6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/c-nioatomics.c @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include + +#include "../include/CNIOAtomics.h" +#include "cpp_magic.h" + +#define MAKE(type) /* +*/ void catmc_nio_atomic_##type##_create_with_existing_storage(struct catmc_nio_atomic_##type *storage, type value) { /* +*/ atomic_init(&storage->value, value); /* +*/ } /* +*/ /* +*/ bool catmc_nio_atomic_##type##_compare_and_exchange(struct catmc_nio_atomic_##type *wrapper, type expected, type desired) { /* +*/ type expected_copy = expected; /* +*/ return atomic_compare_exchange_strong(&wrapper->value, &expected_copy, desired); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_add(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_add_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_sub(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_fetch_sub_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_exchange(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ return atomic_exchange_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ type catmc_nio_atomic_##type##_load(struct catmc_nio_atomic_##type *wrapper) { /* +*/ return atomic_load_explicit(&wrapper->value, memory_order_relaxed); /* +*/ } /* +*/ /* +*/ void catmc_nio_atomic_##type##_store(struct catmc_nio_atomic_##type *wrapper, type value) { /* +*/ atomic_store_explicit(&wrapper->value, value, memory_order_relaxed); /* +*/ } + +typedef signed char signed_char; +typedef signed short signed_short; +typedef signed int signed_int; +typedef signed long signed_long; +typedef signed long long signed_long_long; +typedef unsigned char unsigned_char; +typedef unsigned short unsigned_short; +typedef unsigned int unsigned_int; +typedef unsigned long unsigned_long; +typedef unsigned long long unsigned_long_long; +typedef long long long_long; + +MAP(MAKE,EMPTY, + bool, + char, short, int, long, long_long, + signed_char, signed_short, signed_int, signed_long, signed_long_long, + unsigned_char, unsigned_short, unsigned_int, unsigned_long, unsigned_long_long, + int_least8_t, uint_least8_t, + int_least16_t, uint_least16_t, + int_least32_t, uint_least32_t, + int_least64_t, uint_least64_t, + intptr_t, uintptr_t + ) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/cpp_magic.h b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/cpp_magic.h new file mode 100644 index 00000000..66f9f789 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOAtomics/Sources/CNIOAtomics/src/cpp_magic.h @@ -0,0 +1,452 @@ +// +// this is https://github.com/18sg/uSHET/blob/master/lib/cpp_magic.h +// LICENSE: MIT +// +// + +/** + * This header file contains a library of advanced C Pre-Processor (CPP) macros + * which implement various useful functions, such as iteration, in the + * pre-processor. + * + * Though the file name (quite validly) labels this as magic, there should be + * enough documentation in the comments for a reader only casually familiar + * with the CPP to be able to understand how everything works. + * + * The majority of the magic tricks used in this file are based on those + * described by pfultz2 in his "Cloak" library: + * + * https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms + * + * Major differences are a greater level of detailed explanation in this + * implementation and also a refusal to include any macros which require a O(N) + * macro definitions to handle O(N) arguments (with the exception of DEFERn). + */ + +#ifndef CPP_MAGIC_H +#define CPP_MAGIC_H + +/** + * Force the pre-processor to expand the macro a large number of times. Usage: + * + * EVAL(expression) + * + * This is useful when you have a macro which evaluates to a valid macro + * expression which is not subsequently expanded in the same pass. A contrived, + * but easy to understand, example of such a macro follows. Note that though + * this example is contrived, this behaviour is abused to implement bounded + * recursion in macros such as FOR. + * + * #define A(x) x+1 + * #define EMPTY + * #define NOT_QUITE_RIGHT(x) A EMPTY (x) + * NOT_QUITE_RIGHT(999) + * + * Here's what happens inside the C preprocessor: + * + * 1. It sees a macro "NOT_QUITE_RIGHT" and performs a single macro expansion + * pass on its arguments. Since the argument is "999" and this isn't a macro, + * this is a boring step resulting in no change. + * 2. The NOT_QUITE_RIGHT macro is substituted for its definition giving "A + * EMPTY() (x)". + * 3. The expander moves from left-to-right trying to expand the macro: + * The first token, A, cannot be expanded since there are no brackets + * immediately following it. The second token EMPTY(), however, can be + * expanded (recursively in this manner) and is replaced with "". + * 4. Expansion continues from the start of the substituted test (which in this + * case is just empty), and sees "(999)" but since no macro name is present, + * nothing is done. This results in a final expansion of "A (999)". + * + * Unfortunately, this doesn't quite meet expectations since you may expect that + * "A (999)" would have been expanded into "999+1". Unfortunately this requires + * a second expansion pass but luckily we can force the macro processor to make + * more passes by abusing the first step of macro expansion: the preprocessor + * expands arguments in their own pass. If we define a macro which does nothing + * except produce its arguments e.g.: + * + * #define PASS_THROUGH(...) __VA_ARGS__ + * + * We can now do "PASS_THROUGH(NOT_QUITE_RIGHT(999))" causing "NOT_QUITE_RIGHT" to be + * expanded to "A (999)", as described above, when the arguments are expanded. + * Now when the body of PASS_THROUGH is expanded, "A (999)" gets expanded to + * "999+1". + * + * The EVAL defined below is essentially equivalent to a large nesting of + * "PASS_THROUGH(PASS_THROUGH(PASS_THROUGH(..." which results in the + * preprocessor making a large number of expansion passes over the given + * expression. + */ +#define EVAL(...) EVAL1024(__VA_ARGS__) +#define EVAL1024(...) EVAL512(EVAL512(__VA_ARGS__)) +#define EVAL512(...) EVAL256(EVAL256(__VA_ARGS__)) +#define EVAL256(...) EVAL128(EVAL128(__VA_ARGS__)) +#define EVAL128(...) EVAL64(EVAL64(__VA_ARGS__)) +#define EVAL64(...) EVAL32(EVAL32(__VA_ARGS__)) +#define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__)) +#define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__)) +#define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__)) +#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__)) +#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__)) +#define EVAL1(...) __VA_ARGS__ + + +/** + * Macros which expand to common values + */ +#define PASS(...) __VA_ARGS__ +#define EMPTY() +#define COMMA() , +#define PLUS() + +#define ZERO() 0 +#define ONE() 1 + +/** + * Causes a function-style macro to require an additional pass to be expanded. + * + * This is useful, for example, when trying to implement recursion since the + * recursive step must not be expanded in a single pass as the pre-processor + * will catch it and prevent it. + * + * Usage: + * + * DEFER1(IN_NEXT_PASS)(args, to, the, macro) + * + * How it works: + * + * 1. When DEFER1 is expanded, first its arguments are expanded which are + * simply IN_NEXT_PASS. Since this is a function-style macro and it has no + * arguments, nothing will happen. + * 2. The body of DEFER1 will now be expanded resulting in EMPTY() being + * deleted. This results in "IN_NEXT_PASS (args, to, the macro)". Note that + * since the macro expander has already passed IN_NEXT_PASS by the time it + * expands EMPTY() and so it won't spot that the brackets which remain can be + * applied to IN_NEXT_PASS. + * 3. At this point the macro expansion completes. If one more pass is made, + * IN_NEXT_PASS(args, to, the, macro) will be expanded as desired. + */ +#define DEFER1(id) id EMPTY() + +/** + * As with DEFER1 except here n additional passes are required for DEFERn. + * + * The mechanism is analogous. + * + * Note that there doesn't appear to be a way of combining DEFERn macros in + * order to achieve exponentially increasing defers e.g. as is done by EVAL. + */ +#define DEFER2(id) id EMPTY EMPTY()() +#define DEFER3(id) id EMPTY EMPTY EMPTY()()() +#define DEFER4(id) id EMPTY EMPTY EMPTY EMPTY()()()() +#define DEFER5(id) id EMPTY EMPTY EMPTY EMPTY EMPTY()()()()() +#define DEFER6(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()() +#define DEFER7(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()()() +#define DEFER8(id) id EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY EMPTY()()()()()()()() + + +/** + * Indirection around the standard ## concatenation operator. This simply + * ensures that the arguments are expanded (once) before concatenation. + */ +#define CAT(a, ...) a ## __VA_ARGS__ +#define CAT3(a, b, ...) a ## b ## __VA_ARGS__ + + +/** + * Get the first argument and ignore the rest. + */ +#define FIRST(a, ...) a + +/** + * Get the second argument and ignore the rest. + */ +#define SECOND(a, b, ...) b + +/** + * Expects a single input (not containing commas). Returns 1 if the input is + * PROBE() and otherwise returns 0. + * + * This can be useful as the basis of a NOT function. + * + * This macro abuses the fact that PROBE() contains a comma while other valid + * inputs must not. + */ +#define IS_PROBE(...) SECOND(__VA_ARGS__, 0) +#define PROBE() ~, 1 + + +/** + * Logical negation. 0 is defined as false and everything else as true. + * + * When 0, _NOT_0 will be found which evaluates to the PROBE. When 1 (or any other + * value) is given, an appropriately named macro won't be found and the + * concatenated string will be produced. IS_PROBE then simply checks to see if + * the PROBE was returned, cleanly converting the argument into a 1 or 0. + */ +#define NOT(x) IS_PROBE(CAT(_NOT_, x)) +#define _NOT_0 PROBE() + +/** + * Macro version of C's famous "cast to bool" operator (i.e. !!) which takes + * anything and casts it to 0 if it is 0 and 1 otherwise. + */ +#define BOOLIFY(x) NOT(NOT(x)) + +/** + * Logical OR. Simply performs a lookup. + */ +#define OR(a,b) CAT3(_OR_, a, b) +#define _OR_00 0 +#define _OR_01 1 +#define _OR_10 1 +#define _OR_11 1 + +/** + * Logical AND. Simply performs a lookup. + */ +#define AND(a,b) CAT3(_AND_, a, b) +#define _AND_00 0 +#define _AND_01 0 +#define _AND_10 0 +#define _AND_11 1 + + +/** + * Macro if statement. Usage: + * + * IF(c)(expansion when true) + * + * Here's how: + * + * 1. The preprocessor expands the arguments to _IF casting the condition to '0' + * or '1'. + * 2. The casted condition is concatencated with _IF_ giving _IF_0 or _IF_1. + * 3. The _IF_0 and _IF_1 macros either returns the argument or doesn't (e.g. + * they implement the "choice selection" part of the macro). + * 4. Note that the "true" clause is in the extra set of brackets; thus these + * become the arguments to _IF_0 or _IF_1 and thus a selection is made! + */ +#define IF(c) _IF(BOOLIFY(c)) +#define _IF(c) CAT(_IF_,c) +#define _IF_0(...) +#define _IF_1(...) __VA_ARGS__ + +/** + * Macro if/else statement. Usage: + * + * IF_ELSE(c)( \ + * expansion when true, \ + * expansion when false \ + * ) + * + * The mechanism is analogous to IF. + */ +#define IF_ELSE(c) _IF_ELSE(BOOLIFY(c)) +#define _IF_ELSE(c) CAT(_IF_ELSE_,c) +#define _IF_ELSE_0(t,f) f +#define _IF_ELSE_1(t,f) t + + +/** + * Macro which checks if it has any arguments. Returns '0' if there are no + * arguments, '1' otherwise. + * + * Limitation: HAS_ARGS(,1,2,3) returns 0 -- this check essentially only checks + * that the first argument exists. + * + * This macro works as follows: + * + * 1. _END_OF_ARGUMENTS_ is concatenated with the first argument. + * 2. If the first argument is not present then only "_END_OF_ARGUMENTS_" will + * remain, otherwise "_END_OF_ARGUMENTS something_here" will remain. This + * remaining argument can start with parentheses. + * 3. In the former case, the _END_OF_ARGUMENTS_(0) macro expands to a + * 0 when it is expanded. In the latter, a non-zero result remains. If the + * first argument started with parentheses these will mostly not contain + * only a single 0, but e.g a C cast or some arithmetic operation that will + * cause the BOOLIFY in _END_OF_ARGUMENTS_ to be one. + * 4. BOOLIFY is used to force non-zero results into 1 giving the clean 0 or 1 + * output required. + */ +#define HAS_ARGS(...) BOOLIFY(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)(0)) +#define _END_OF_ARGUMENTS_(...) BOOLIFY(FIRST(__VA_ARGS__)) + + +/** + * Macro map/list comprehension. Usage: + * + * MAP(op, sep, ...) + * + * Produces a 'sep()'-separated list of the result of op(arg) for each arg. + * + * Example Usage: + * + * #define MAKE_HAPPY(x) happy_##x + * #define COMMA() , + * MAP(MAKE_HAPPY, COMMA, 1,2,3) + * + * Which expands to: + * + * happy_1 , happy_2 , happy_3 + * + * How it works: + * + * 1. The MAP macro simply maps the inner MAP_INNER function in an EVAL which + * forces it to be expanded a large number of times, thus enabling many steps + * of iteration (see step 6). + * 2. The MAP_INNER macro is substituted for its body. + * 3. In the body, op(cur_val) is substituted giving the value for this + * iteration. + * 4. The IF macro expands according to whether further iterations are required. + * This expansion either produces _IF_0 or _IF_1. + * 5. Since the IF is followed by a set of brackets containing the "if true" + * clause, these become the argument to _IF_0 or _IF_1. At this point, the + * macro in the brackets will be expanded giving the separator followed by + * _MAP_INNER EMPTY()()(op, sep, __VA_ARGS__). + * 5. If the IF was not taken, the above will simply be discarded and everything + * stops. If the IF is taken, The expression is then processed a second time + * yielding "_MAP_INNER()(op, sep, __VA_ARGS__)". Note that this call looks + * very similar to the essentially the same as the original call except the + * first argument has been dropped. + * 6. At this point expansion of MAP_INNER will terminate. However, since we can + * force more rounds of expansion using EVAL1. In the argument-expansion pass + * of the EVAL1, _MAP_INNER() is expanded to MAP_INNER which is then expanded + * using the arguments which follow it as in step 2-5. This is followed by a + * second expansion pass as the substitution of EVAL1() is expanded executing + * 2-5 a second time. This results in up to two iterations occurring. Using + * many nested EVAL1 macros, i.e. the very-deeply-nested EVAL macro, will in + * this manner produce further iterations, hence the outer MAP macro doing + * this for us. + * + * Important tricks used: + * + * * If we directly produce "MAP_INNER" in an expansion of MAP_INNER, a special + * case in the preprocessor will prevent it being expanded in the future, even + * if we EVAL. As a result, the MAP_INNER macro carefully only expands to + * something containing "_MAP_INNER()" which requires a further expansion step + * to invoke MAP_INNER and thus implementing the recursion. + * * To prevent _MAP_INNER being expanded within the macro we must first defer its + * expansion during its initial pass as an argument to _IF_0 or _IF_1. We must + * then defer its expansion a second time as part of the body of the _IF_0. As + * a result hence the DEFER2. + * * _MAP_INNER seemingly gets away with producing itself because it actually only + * produces MAP_INNER. It just happens that when _MAP_INNER() is expanded in + * this case it is followed by some arguments which get consumed by MAP_INNER + * and produce a _MAP_INNER. As such, the macro expander never marks + * _MAP_INNER as expanding to itself and thus it will still be expanded in + * future productions of itself. + */ +#define MAP(...) \ + IF(HAS_ARGS(__VA_ARGS__))(EVAL(MAP_INNER(__VA_ARGS__))) +#define MAP_INNER(op,sep,cur_val, ...) \ + op(cur_val) \ + IF(HAS_ARGS(__VA_ARGS__))( \ + sep() DEFER2(_MAP_INNER)()(op, sep, ##__VA_ARGS__) \ + ) +#define _MAP_INNER() MAP_INNER + + +/** + * This is a variant of the MAP macro which also includes as an argument to the + * operation a valid C variable name which is different for each iteration. + * + * Usage: + * MAP_WITH_ID(op, sep, ...) + * + * Where op is a macro op(val, id) which takes a list value and an ID. This ID + * will simply be a unary number using the digit "I", that is, I, II, III, IIII, + * and so on. + * + * Example: + * + * #define MAKE_STATIC_VAR(type, name) static type name; + * MAP_WITH_ID(MAKE_STATIC_VAR, EMPTY, int, int, int, bool, char) + * + * Which expands to: + * + * static int I; static int II; static int III; static bool IIII; static char IIIII; + * + * The mechanism is analogous to the MAP macro. + */ +#define MAP_WITH_ID(op,sep,...) \ + IF(HAS_ARGS(__VA_ARGS__))(EVAL(MAP_WITH_ID_INNER(op,sep,I, ##__VA_ARGS__))) +#define MAP_WITH_ID_INNER(op,sep,id,cur_val, ...) \ + op(cur_val,id) \ + IF(HAS_ARGS(__VA_ARGS__))( \ + sep() DEFER2(_MAP_WITH_ID_INNER)()(op, sep, CAT(id,I), ##__VA_ARGS__) \ + ) +#define _MAP_WITH_ID_INNER() MAP_WITH_ID_INNER + + +/** + * This is a variant of the MAP macro which iterates over pairs rather than + * singletons. + * + * Usage: + * MAP_PAIRS(op, sep, ...) + * + * Where op is a macro op(val_1, val_2) which takes two list values. + * + * Example: + * + * #define MAKE_STATIC_VAR(type, name) static type name; + * MAP_PAIRS(MAKE_STATIC_VAR, EMPTY, char, my_char, int, my_int) + * + * Which expands to: + * + * static char my_char; static int my_int; + * + * The mechanism is analogous to the MAP macro. + */ +#define MAP_PAIRS(op,sep,...) \ + IF(HAS_ARGS(__VA_ARGS__))(EVAL(MAP_PAIRS_INNER(op,sep,__VA_ARGS__))) +#define MAP_PAIRS_INNER(op,sep,cur_val_1, cur_val_2, ...) \ + op(cur_val_1,cur_val_2) \ + IF(HAS_ARGS(__VA_ARGS__))( \ + sep() DEFER2(_MAP_PAIRS_INNER)()(op, sep, __VA_ARGS__) \ + ) +#define _MAP_PAIRS_INNER() MAP_PAIRS_INNER + +/** + * This is a variant of the MAP macro which iterates over a two-element sliding + * window. + * + * Usage: + * MAP_SLIDE(op, last_op, sep, ...) + * + * Where op is a macro op(val_1, val_2) which takes the two list values + * currently in the window. last_op is a macro taking a single value which is + * called for the last argument. + * + * Example: + * + * #define SIMON_SAYS_OP(simon, next) IF(NOT(simon()))(next) + * #define SIMON_SAYS_LAST_OP(val) last_but_not_least_##val + * #define SIMON_SAYS() 0 + * + * MAP_SLIDE(SIMON_SAYS_OP, SIMON_SAYS_LAST_OP, EMPTY, wiggle, SIMON_SAYS, dance, move, SIMON_SAYS, boogie, stop) + * + * Which expands to: + * + * dance boogie last_but_not_least_stop + * + * The mechanism is analogous to the MAP macro. + */ +#define MAP_SLIDE(op,last_op,sep,...) \ + IF(HAS_ARGS(__VA_ARGS__))(EVAL(MAP_SLIDE_INNER(op,last_op,sep,__VA_ARGS__))) +#define MAP_SLIDE_INNER(op,last_op,sep,cur_val, ...) \ + IF(HAS_ARGS(__VA_ARGS__))(op(cur_val,FIRST(__VA_ARGS__))) \ + IF(NOT(HAS_ARGS(__VA_ARGS__)))(last_op(cur_val)) \ + IF(HAS_ARGS(__VA_ARGS__))( \ + sep() DEFER2(_MAP_SLIDE_INNER)()(op, last_op, sep, __VA_ARGS__) \ + ) +#define _MAP_SLIDE_INNER() MAP_SLIDE_INNER + + +/** + * Strip any excess commas from a set of arguments. + */ +#define REMOVE_TRAILING_COMMAS(...) \ + MAP(PASS, COMMA, __VA_ARGS__) + + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/README.md new file mode 100644 index 00000000..9a91146f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/README.md @@ -0,0 +1,53 @@ +# SwiftNIO SSL + +SwiftNIO SSL is a Swift package that contains an implementation of TLS based on BoringSSL. This package allows users of [SwiftNIO](https://github.com/apple/swift-nio) to write protocol clients and servers that use TLS to secure data in flight. + +The name is inspired primarily by the names of the library this package uses (BoringSSL), and not because we don't know the name of the protocol. We know the protocol is TLS! + +To get started, check out the [API docs](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html). + +## Using SwiftNIO SSL + +SwiftNIO SSL provides two `ChannelHandler`s to use to secure a data stream: the `NIOSSLClientHandler` and the `NIOSSLServerHandler`. Each of these can be added to a `Channel` to secure the communications on that channel. + +Additionally, we provide a number of low-level primitives for configuring your TLS connections. These will be shown below. + +To secure a server connection, you will need a X.509 certificate chain in a file (either PEM or DER, but PEM is far easier), and the associated private key for the leaf certificate. These objects can then be wrapped up in a `TLSConfiguration` object that is used to initialize the `ChannelHandler`. + +For example: + +```swift +let configuration = TLSConfiguration.makeServerConfiguration( + certificateChain: try NIOSSLCertificate.fromPEMFile("cert.pem").map { .certificate($0) }, + privateKey: .file("key.pem") +) +let sslContext = try NIOSSLContext(configuration: configuration) + +let server = ServerBootstrap(group: group) + .childChannelInitializer { channel in + // important: The handler must be initialized _inside_ the `childChannelInitializer` + let handler = try NIOSSLServerHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` + +For clients, it is a bit simpler as there is no need to have a certificate chain or private key (though clients *may* have these things). Setup for clients may be done like this: + +```swift +let configuration = TLSConfiguration.makeClientConfiguration() +let sslContext = try NIOSSLContext(configuration: configuration) + +let client = ClientBootstrap(group: group) + .channelInitializer { channel in + // important: The handler must be initialized _inside_ the `channelInitializer` + let handler = try NIOSSLClientHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` +Note that SwiftNIO SSL currently requires Swift 5.4 and above. Release 2.13.x and prior support Swift 5.0 and 5.1, Release 2.18.x and prior supports Swift 5.2 and 5.3. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c new file mode 100644 index 00000000..5a771a9b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c @@ -0,0 +1,284 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" +#include "internal.h" + + +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d, int len) +{ + return ASN1_STRING_set(x, d, len); +} + +int asn1_bit_string_length(const ASN1_BIT_STRING *str, + uint8_t *out_padding_bits) { + int len = str->length; + if (str->flags & ASN1_STRING_FLAG_BITS_LEFT) { + // If the string is already empty, it cannot have padding bits. + *out_padding_bits = len == 0 ? 0 : str->flags & 0x07; + return len; + } + + // TODO(https://crbug.com/boringssl/447): If we move this logic to + // |ASN1_BIT_STRING_set_bit|, can we remove this representation? + while (len > 0 && str->data[len - 1] == 0) { + len--; + } + uint8_t padding_bits = 0; + if (len > 0) { + uint8_t last = str->data[len - 1]; + assert(last != 0); + for (; padding_bits < 7; padding_bits++) { + if (last & (1 << padding_bits)) { + break; + } + } + } + *out_padding_bits = padding_bits; + return len; +} + +int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, size_t *out) { + uint8_t padding_bits; + int len = asn1_bit_string_length(str, &padding_bits); + if (padding_bits != 0) { + return 0; + } + *out = len; + return 1; +} + +int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) +{ + if (a == NULL) { + return 0; + } + + uint8_t bits; + int len = asn1_bit_string_length(a, &bits); + int ret = 1 + len; + if (pp == NULL) { + return ret; + } + + uint8_t *p = *pp; + *(p++) = bits; + OPENSSL_memcpy(p, a->data, len); + if (len > 0) { + p[len - 1] &= (0xff << bits); + } + p += len; + *pp = p; + return (ret); +} + +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) +{ + ASN1_BIT_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + int padding; + + if (len < 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + goto err; + } + + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + goto err; + } + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_BIT_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + padding = *(p++); + len--; + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + goto err; + } + + /* Unused bits in a BIT STRING must be zero. */ + uint8_t padding_mask = (1 << padding) - 1; + if (padding != 0 && + (len < 1 || (p[len - 1] & padding_mask) != 0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); + goto err; + } + + /* + * We do this to preserve the settings. If we modify the settings, via + * the _set_bit function, we will recalculate on output + */ + ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ + ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */ + + if (len > 0) { + s = OPENSSL_memdup(p, len); + if (s == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + p += len; + } else { + s = NULL; + } + + ret->length = (int)len; + OPENSSL_free(ret->data); + ret->data = s; + ret->type = V_ASN1_BIT_STRING; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_BIT_STRING_free(ret); + return (NULL); +} + +/* + * These next 2 functions from Goetz Babin-Ebell + */ +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) +{ + int w, v, iv; + unsigned char *c; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + iv = ~v; + if (!value) + v = 0; + + if (a == NULL) + return 0; + + a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ + + if ((a->length < (w + 1)) || (a->data == NULL)) { + if (!value) + return (1); /* Don't need to set */ + if (a->data == NULL) + c = (unsigned char *)OPENSSL_malloc(w + 1); + else + c = (unsigned char *)OPENSSL_realloc(a->data, w + 1); + if (c == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + if (w + 1 - a->length > 0) + OPENSSL_memset(c + a->length, 0, w + 1 - a->length); + a->data = c; + a->length = w + 1; + } + a->data[w] = ((a->data[w]) & iv) | v; + while ((a->length > 0) && (a->data[a->length - 1] == 0)) + a->length--; + return (1); +} + +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) +{ + int w, v; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) + return (0); + return ((a->data[w] & v) != 0); +} + +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, + const unsigned char *flags, int flags_len) +{ + int i, ok; + /* Check if there is one bit set at all. */ + if (!a || !a->data) + return 1; + + /* + * Check each byte of the internal representation of the bit string. + */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c new file mode 100644 index 00000000..8b6346db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_bool.c @@ -0,0 +1,122 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **pp) +{ + int r; + unsigned char *p, *allocated = NULL; + + r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); + if (pp == NULL) + return (r); + + if (*pp == NULL) { + if ((p = allocated = OPENSSL_malloc(r)) == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + } else { + p = *pp; + } + + ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); + *p = a ? 0xff : 0x00; + + /* + * If a new buffer was allocated, just return it back. + * If not, return the incremented buffer pointer. + */ + *pp = allocated != NULL ? allocated : p + 1; + return r; +} + +ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *a, const unsigned char **pp, + long length) { + const unsigned char *p = *pp; + long len; + int inf, tag, xclass; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); + return -1; + } + + if (inf & V_ASN1_CONSTRUCTED) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return -1; + } + + if (tag != V_ASN1_BOOLEAN || xclass != V_ASN1_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_BOOLEAN); + return -1; + } + + if (len != 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + return -1; + } + ASN1_BOOLEAN ret = (ASN1_BOOLEAN)*(p++); + if (a != NULL) { + (*a) = ret; + } + *pp = p; + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_d2i_fp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_d2i_fp.c new file mode 100644 index 00000000..d23d048a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_d2i_fp.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include + + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + uint8_t *data; + size_t len; + // Historically, this function did not impose a limit in OpenSSL and is used + // to read CRLs, so we leave this without an external bound. + if (!BIO_read_asn1(in, &data, &len, INT_MAX)) { + return NULL; + } + const uint8_t *ptr = data; + void *ret = ASN1_item_d2i(x, &ptr, len, it); + OPENSSL_free(data); + return ret; +} + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + BIO *b = BIO_new_fp(in, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); + return NULL; + } + void *ret = ASN1_item_d2i_bio(it, b, x); + BIO_free(b); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c new file mode 100644 index 00000000..6a536ab6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_dup.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +/* + * ASN1_ITEM version of dup: this follows the model above except we don't + * need to allocate the buffer. At some point this could be rewritten to + * directly dup the underlying structure instead of doing and encode and + * decode. + */ +void *ASN1_item_dup(const ASN1_ITEM *it, void *x) +{ + unsigned char *b = NULL; + const unsigned char *p; + long i; + void *ret; + + if (x == NULL) + return (NULL); + + i = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return (ret); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c new file mode 100644 index 00000000..48197a85 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c @@ -0,0 +1,266 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) +{ + static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_GENERALIZEDTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + /* + * GENERALIZEDTIME is similar to UTCTIME except the year is represented + * as YYYY. This stuff treats everything as a two digit field so make + * first two fields 00 to 99 + */ + if (l < 13) + goto err; + for (i = 0; i < 7; i++) { + if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + if (tm) + tm->tm_sec = 0; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + switch (i) { + case 0: + tm->tm_year = n * 100 - 1900; + break; + case 1: + tm->tm_year += n; + break; + case 2: + tm->tm_mon = n - 1; + break; + case 3: + tm->tm_mday = n; + break; + case 4: + tm->tm_hour = n; + break; + case 5: + tm->tm_min = n; + break; + case 6: + tm->tm_sec = n; + break; + } + } + } + /* + * Optional fractional seconds: decimal point followed by one or more + * digits. + */ + if (a[o] == '.') { + if (++o > l) + goto err; + i = o; + while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) + o++; + /* Must have at least one digit after decimal point */ + if (i == o) + goto err; + } + + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + int offsign = a[o] == '-' ? 1 : -1, offset = 0; + o++; + if (o + 4 > l) + goto err; + for (i = 7; i < 9; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + if (i == 7) + offset = n * 3600; + else if (i == 8) + offset += n * 60; + } + o++; + } + if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) + return 0; + } else if (a[o]) { + /* Missing time zone information. */ + goto err; + } + return (o == l); + err: + return (0); +} + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) +{ + return asn1_generalizedtime_to_tm(NULL, d); +} + +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) +{ + ASN1_GENERALIZEDTIME t; + + t.type = V_ASN1_GENERALIZEDTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_GENERALIZEDTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_GENERALIZEDTIME; + } + return (1); + } else + return (0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t) +{ + return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + ASN1_GENERALIZEDTIME *tmps = NULL; + + if (s == NULL) + tmps = ASN1_GENERALIZEDTIME_new(); + else + tmps = s; + if (tmps == NULL) + return NULL; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + goto err; + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + goto err; + } + + if (ts->tm_year < 0 - 1900 || ts->tm_year > 9999 - 1900) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); + goto err; + } + + p = (char *)tmps->data; + if ((p == NULL) || ((size_t)tmps->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(tmps->data); + tmps->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + tmps->length = strlen(p); + tmps->type = V_ASN1_GENERALIZEDTIME; + return tmps; + err: + if (s == NULL) + ASN1_GENERALIZEDTIME_free(tmps); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c new file mode 100644 index 00000000..7d1d456f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c @@ -0,0 +1,88 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +{ + BIO *b = BIO_new_fp(out, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); + return 0; + } + int ret = ASN1_item_i2d_bio(it, b, x); + BIO_free(b); + return ret; +} + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +{ + unsigned char *b = NULL; + int n = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = BIO_write_all(out, b, n); + OPENSSL_free(b); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_int.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_int.c new file mode 100644 index 00000000..66947de7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_int.c @@ -0,0 +1,462 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" + + +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) +{ + return ASN1_STRING_dup(x); +} + +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) +{ + /* Compare signs. */ + int neg = x->type & V_ASN1_NEG; + if (neg != (y->type & V_ASN1_NEG)) { + return neg ? -1 : 1; + } + + int ret = ASN1_STRING_cmp(x, y); + if (neg) { + /* This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from + * returning |INT_MIN|. */ + if (ret < 0) { + return 1; + } else if (ret > 0) { + return -1; + } else { + return 0; + } + } + + return ret; +} + +/* negate_twos_complement negates |len| bytes from |buf| in-place, interpreted + * as a signed, big-endian two's complement value. */ +static void negate_twos_complement(uint8_t *buf, size_t len) +{ + uint8_t borrow = 0; + for (size_t i = len - 1; i < len; i--) { + uint8_t t = buf[i]; + buf[i] = 0u - borrow - t; + borrow |= t != 0; + } +} + +static int is_all_zeros(const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; i++) { + if (in[i] != 0) { + return 0; + } + } + return 1; +} + +int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) +{ + if (in == NULL) { + return 0; + } + + /* |ASN1_INTEGER|s should be represented minimally, but it is possible to + * construct invalid ones. Skip leading zeros so this does not produce an + * invalid encoding or break invariants. */ + int start = 0; + while (start < in->length && in->data[start] == 0) { + start++; + } + + int is_negative = (in->type & V_ASN1_NEG) != 0; + int pad; + if (start >= in->length) { + /* Zero is represented as a single byte. */ + is_negative = 0; + pad = 1; + } else if (is_negative) { + /* 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff + * through 0x00...01 and need an extra byte to be negative. + * 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff + * through 0x80...00 and can be negated as-is. */ + pad = in->data[start] > 0x80 || + (in->data[start] == 0x80 && + !is_all_zeros(in->data + start + 1, in->length - start - 1)); + } else { + /* If the high bit is set, the signed representation needs an extra + * byte to be positive. */ + pad = (in->data[start] & 0x80) != 0; + } + + if (in->length - start > INT_MAX - pad) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + int len = pad + in->length - start; + assert(len > 0); + if (outp == NULL) { + return len; + } + + if (pad) { + (*outp)[0] = 0; + } + OPENSSL_memcpy(*outp + pad, in->data + start, in->length - start); + if (is_negative) { + negate_twos_complement(*outp, len); + assert((*outp)[0] >= 0x80); + } else { + assert((*outp)[0] < 0x80); + } + *outp += len; + return len; +} + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, + long len) +{ + /* + * This function can handle lengths up to INT_MAX - 1, but the rest of the + * legacy ASN.1 code mixes integer types, so avoid exposing it to + * ASN1_INTEGERS with larger lengths. + */ + if (len < 0 || len > INT_MAX / 2) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + int is_negative; + if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return NULL; + } + + ASN1_INTEGER *ret = NULL; + if (out == NULL || *out == NULL) { + ret = ASN1_INTEGER_new(); + if (ret == NULL) { + return NULL; + } + } else { + ret = *out; + } + + /* Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First, + * determine the size needed for a minimal result. */ + if (is_negative) { + /* 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff + * through 0x000100...001 and need one leading zero removed. 0x8000...00 + * through 0xff00...00 have a two's complement of 0x8000...00 through + * 0x0100...00 and will be minimally-encoded as-is. */ + if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff && + !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) { + CBS_skip(&cbs, 1); + } + } else { + /* Remove the leading zero byte, if any. */ + if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) { + CBS_skip(&cbs, 1); + } + } + + if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) { + goto err; + } + + if (is_negative) { + ret->type = V_ASN1_NEG_INTEGER; + negate_twos_complement(ret->data, ret->length); + } else { + ret->type = V_ASN1_INTEGER; + } + + /* The value should be minimally-encoded. */ + assert(ret->length == 0 || ret->data[0] != 0); + /* Zero is not negative. */ + assert(!is_negative || ret->length > 0); + + *inp += len; + if (out != NULL) { + *out = ret; + } + return ret; + + err: + if (ret != NULL && (out == NULL || *out != ret)) { + ASN1_INTEGER_free(ret); + } + return NULL; +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + if (v >= 0) { + return ASN1_INTEGER_set_uint64(a, (uint64_t) v); + } + + if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) { + return 0; + } + + a->type = V_ASN1_NEG_INTEGER; + return 1; +} + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) +{ + if (v >= 0) { + return ASN1_ENUMERATED_set_uint64(a, (uint64_t) v); + } + + if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t) v)) { + return 0; + } + + a->type = V_ASN1_NEG_ENUMERATED; + return 1; +} + +static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) +{ + uint8_t buf[sizeof(uint64_t)]; + CRYPTO_store_u64_be(buf, v); + size_t leading_zeros; + for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) { + if (buf[leading_zeros] != 0) { + break; + } + } + + if (!ASN1_STRING_set(out, buf + leading_zeros, + sizeof(buf) - leading_zeros)) { + return 0; + } + out->type = type; + return 1; +} + +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) +{ + return asn1_string_set_uint64(out, v, V_ASN1_INTEGER); +} + +int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) +{ + return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED); +} + +static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a, + int type) +{ + if ((a->type & ~V_ASN1_NEG) != type) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE); + return 0; + } + uint8_t buf[sizeof(uint64_t)] = {0}; + if (a->length > (int)sizeof(buf)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return 0; + } + OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length); + *out = CRYPTO_load_u64_be(buf); + return 1; +} + +static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a, int type) +{ + if (!asn1_string_get_abs_uint64(out, a, type)) { + return 0; + } + if (a->type & V_ASN1_NEG) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return 0; + } + return 1; +} + +int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) +{ + return asn1_string_get_uint64(out, a, V_ASN1_INTEGER); +} + +int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) +{ + return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED); +} + +static long asn1_string_get_long(const ASN1_STRING *a, int type) +{ + if (a == NULL) { + return 0; + } + + uint64_t v; + if (!asn1_string_get_abs_uint64(&v, a, type)) { + goto err; + } + + int64_t i64; + int fits_in_i64; + /* Check |v != 0| to handle manually-constructed negative zeros. */ + if ((a->type & V_ASN1_NEG) && v != 0) { + i64 = (int64_t)(0u - v); + fits_in_i64 = i64 < 0; + } else { + i64 = (int64_t)v; + fits_in_i64 = i64 >= 0; + } + OPENSSL_STATIC_ASSERT(sizeof(long) <= sizeof(int64_t), "long is too big"); + + if (fits_in_i64 && LONG_MIN <= i64 && i64 <= LONG_MAX) { + return (long)i64; + } + +err: + /* This function's return value does not distinguish overflow from -1. */ + ERR_clear_error(); + return -1; +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + return asn1_string_get_long(a, V_ASN1_INTEGER); +} + +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) +{ + return asn1_string_get_long(a, V_ASN1_ENUMERATED); +} + +static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, + int type) +{ + ASN1_INTEGER *ret; + if (ai == NULL) { + ret = ASN1_STRING_type_new(type); + } else { + ret = ai; + } + if (ret == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + if (BN_is_negative(bn) && !BN_is_zero(bn)) { + ret->type = type | V_ASN1_NEG; + } else { + ret->type = type; + } + + int len = BN_num_bytes(bn); + if (!ASN1_STRING_set(ret, NULL, len) || + !BN_bn2bin_padded(ret->data, len, bn)) { + goto err; + } + return ret; + + err: + if (ret != ai) { + ASN1_STRING_free(ret); + } + return NULL; +} + +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) +{ + return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER); +} + +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) +{ + return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED); +} + +static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) +{ + if ((ai->type & ~V_ASN1_NEG) != type) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE); + return NULL; + } + + BIGNUM *ret; + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + else if (ai->type & V_ASN1_NEG) + BN_set_negative(ret, 1); + return (ret); +} + +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) +{ + return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER); +} + +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) +{ + return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c new file mode 100644 index 00000000..0da1dece --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" + +/* + * These functions take a string in UTF8, ASCII or multibyte form and a mask + * of permissible ASN1 string types. It then works out the minimal type + * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and + * creates a string of the correct type with the supplied data. Yes this is + * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum + * size limits too. + */ + +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask) +{ + return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); +} + +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_BMPSTRING) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UNIVERSALSTRING) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UTF8STRING) + +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize) +{ + int str_type; + char free_out; + ASN1_STRING *dest; + size_t nchar = 0; + char strbuf[32]; + if (len == -1) + len = strlen((const char *)in); + if (!mask) + mask = DIRSTRING_TYPE; + + int (*decode_func)(CBS *, uint32_t*); + int error; + switch (inform) { + case MBSTRING_BMP: + decode_func = cbs_get_ucs2_be; + error = ASN1_R_INVALID_BMPSTRING; + break; + + case MBSTRING_UNIV: + decode_func = cbs_get_utf32_be; + error = ASN1_R_INVALID_UNIVERSALSTRING; + break; + + case MBSTRING_UTF8: + decode_func = cbs_get_utf8; + error = ASN1_R_INVALID_UTF8STRING; + break; + + case MBSTRING_ASC: + decode_func = cbs_get_latin1; + error = ERR_R_INTERNAL_ERROR; // Latin-1 inputs are never invalid. + break; + + default: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + /* Check |minsize| and |maxsize| and work out the minimal type, if any. */ + CBS cbs; + CBS_init(&cbs, in, len); + size_t utf8_len = 0; + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!decode_func(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, error); + return -1; + } + if (nchar == 0 && + (inform == MBSTRING_BMP || inform == MBSTRING_UNIV) && + c == 0xfeff) { + /* Reject byte-order mark. We could drop it but that would mean + * adding ambiguity around whether a BOM was included or not when + * matching strings. + * + * For a little-endian UCS-2 string, the BOM will appear as 0xfffe + * and will be rejected as noncharacter, below. */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + /* Update which output formats are still possible. */ + if ((mask & B_ASN1_PRINTABLESTRING) && !asn1_is_printable(c)) { + mask &= ~B_ASN1_PRINTABLESTRING; + } + if ((mask & B_ASN1_IA5STRING) && (c > 127)) { + mask &= ~B_ASN1_IA5STRING; + } + if ((mask & B_ASN1_T61STRING) && (c > 0xff)) { + mask &= ~B_ASN1_T61STRING; + } + if ((mask & B_ASN1_BMPSTRING) && (c > 0xffff)) { + mask &= ~B_ASN1_BMPSTRING; + } + if (!mask) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + nchar++; + utf8_len += cbb_get_utf8_len(c); + } + + if (minsize > 0 && nchar < (size_t)minsize) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize); + ERR_add_error_data(2, "minsize=", strbuf); + return -1; + } + + if (maxsize > 0 && nchar > (size_t)maxsize) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); + ERR_add_error_data(2, "maxsize=", strbuf); + return -1; + } + + /* Now work out output format and string type */ + int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1; + size_t size_estimate = nchar; + int outform = MBSTRING_ASC; + if (mask & B_ASN1_PRINTABLESTRING) { + str_type = V_ASN1_PRINTABLESTRING; + } else if (mask & B_ASN1_IA5STRING) { + str_type = V_ASN1_IA5STRING; + } else if (mask & B_ASN1_T61STRING) { + str_type = V_ASN1_T61STRING; + } else if (mask & B_ASN1_BMPSTRING) { + str_type = V_ASN1_BMPSTRING; + outform = MBSTRING_BMP; + encode_func = cbb_add_ucs2_be; + size_estimate = 2 * nchar; + } else if (mask & B_ASN1_UNIVERSALSTRING) { + str_type = V_ASN1_UNIVERSALSTRING; + encode_func = cbb_add_utf32_be; + size_estimate = 4 * nchar; + outform = MBSTRING_UNIV; + } else if (mask & B_ASN1_UTF8STRING) { + str_type = V_ASN1_UTF8STRING; + outform = MBSTRING_UTF8; + encode_func = cbb_add_utf8; + size_estimate = utf8_len; + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + if (!out) + return str_type; + if (*out) { + free_out = 0; + dest = *out; + if (dest->data) { + dest->length = 0; + OPENSSL_free(dest->data); + dest->data = NULL; + } + dest->type = str_type; + } else { + free_out = 1; + dest = ASN1_STRING_type_new(str_type); + if (!dest) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + *out = dest; + } + + /* If both the same type just copy across */ + if (inform == outform) { + if (!ASN1_STRING_set(dest, in, len)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + return str_type; + } + + CBB cbb; + if (!CBB_init(&cbb, size_estimate + 1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + CBS_init(&cbs, in, len); + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!decode_func(&cbs, &c) || + !encode_func(&cbb, c)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + goto err; + } + } + uint8_t *data = NULL; + size_t data_len; + if (/* OpenSSL historically NUL-terminated this value with a single byte, + * even for |MBSTRING_BMP| and |MBSTRING_UNIV|. */ + !CBB_add_u8(&cbb, 0) || + !CBB_finish(&cbb, &data, &data_len) || + data_len < 1 || + data_len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + OPENSSL_free(data); + goto err; + } + dest->length = (int)(data_len - 1); + dest->data = data; + return str_type; + + err: + if (free_out) + ASN1_STRING_free(dest); + CBB_cleanup(&cbb); + return -1; +} + +int asn1_is_printable(uint32_t value) +{ + if (value > 0x7f) { + return 0; + } + /* Note we cannot use |isalnum| because it is locale-dependent. */ + return ('a' <= value && value <= 'z') || // + ('A' <= value && value <= 'Z') || // + ('0' <= value && value <= '9') || // + value == ' ' || value == '\'' || value == '(' || value == ')' || + value == '+' || value == ',' || value == '-' || value == '.' || + value == '/' || value == ':' || value == '=' || value == '?'; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_object.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_object.c new file mode 100644 index 00000000..3bb38736 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_object.c @@ -0,0 +1,299 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) +{ + if (a == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (a->length == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + return -1; + } + + int objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); + if (pp == NULL || objsize == -1) { + return objsize; + } + + unsigned char *p, *allocated = NULL; + if (*pp == NULL) { + if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + } else { + p = *pp; + } + + ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + OPENSSL_memcpy(p, a->data, a->length); + + /* + * If a new buffer was allocated, just return it back. + * If not, return the incremented buffer pointer. + */ + *pp = allocated != NULL ? allocated : p + a->length; + return objsize; +} + +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) +{ + return OBJ_obj2txt(buf, buf_len, a, 0); +} + +static int write_str(BIO *bp, const char *str) +{ + int len = strlen(str); + return BIO_write(bp, str, len) == len ? len : -1; +} + +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) +{ + if (a == NULL || a->data == NULL) { + return write_str(bp, "NULL"); + } + + char buf[80], *allocated = NULL; + const char *str = buf; + int len = i2t_ASN1_OBJECT(buf, sizeof(buf), a); + if (len > (int)sizeof(buf) - 1) { + /* The input was truncated. Allocate a buffer that fits. */ + allocated = OPENSSL_malloc(len + 1); + if (allocated == NULL) { + return -1; + } + len = i2t_ASN1_OBJECT(allocated, len + 1, a); + str = allocated; + } + if (len <= 0) { + str = ""; + } + + int ret = write_str(bp, str); + OPENSSL_free(allocated); + return ret; +} + +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length) +{ + long len; + int tag, xclass; + const unsigned char *p = *pp; + int inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); + return NULL; + } + + if (inf & V_ASN1_CONSTRUCTED) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return NULL; + } + + if (tag != V_ASN1_OBJECT || xclass != V_ASN1_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_AN_OBJECT); + return NULL; + } + ASN1_OBJECT *ret = c2i_ASN1_OBJECT(a, &p, len); + if (ret) { + *pp = p; + } + return ret; +} + +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) +{ + ASN1_OBJECT *ret = NULL; + const unsigned char *p; + unsigned char *data; + int i, length; + + /* + * Sanity check OID encoding. Need at least one content octet. MSB must + * be clear in the last octet. can't have leading 0x80 in subidentifiers, + * see: X.690 8.19.2 + */ + if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || + p[len - 1] & 0x80) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + /* Now 0 < len <= INT_MAX, so the cast is safe. */ + length = (int)len; + for (i = 0; i < length; i++, p++) { + if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + } + + if ((a == NULL) || ((*a) == NULL) || + !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + if ((ret = ASN1_OBJECT_new()) == NULL) + return (NULL); + } else { + ret = (*a); + } + + p = *pp; + /* detach data from object */ + data = (unsigned char *)ret->data; + ret->data = NULL; + /* once detached we can change it */ + if ((data == NULL) || (ret->length < length)) { + ret->length = 0; + if (data != NULL) + OPENSSL_free(data); + data = (unsigned char *)OPENSSL_malloc(length); + if (data == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; + } + OPENSSL_memcpy(data, p, length); + /* If there are dynamic strings, free them here, and clear the flag */ + if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) { + OPENSSL_free((char *)ret->sn); + OPENSSL_free((char *)ret->ln); + ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS; + } + /* reattach data to object, after which it remains const */ + ret->data = data; + ret->length = length; + ret->sn = NULL; + ret->ln = NULL; + p += length; + + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + OPENSSL_PUT_ERROR(ASN1, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_OBJECT_free(ret); + return (NULL); +} + +ASN1_OBJECT *ASN1_OBJECT_new(void) +{ + ASN1_OBJECT *ret; + + ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->data = NULL; + ret->nid = 0; + ret->sn = NULL; + ret->ln = NULL; + ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; + return (ret); +} + +void ASN1_OBJECT_free(ASN1_OBJECT *a) +{ + if (a == NULL) + return; + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { + OPENSSL_free((void *)a->sn); + OPENSSL_free((void *)a->ln); + a->sn = a->ln = NULL; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { + OPENSSL_free((void *)a->data); + a->data = NULL; + a->length = 0; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) + OPENSSL_free(a); +} + +ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, int len, + const char *sn, const char *ln) +{ + ASN1_OBJECT o; + + o.sn = sn; + o.ln = ln; + o.data = data; + o.nid = nid; + o.length = len; + o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; + return (OBJ_dup(&o)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_octet.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_octet.c new file mode 100644 index 00000000..9882e20b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_octet.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) +{ + return ASN1_STRING_dup(x); +} + +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b) +{ + return ASN1_STRING_cmp(a, b); +} + +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, + int len) +{ + return ASN1_STRING_set(x, d, len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_print.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_print.c new file mode 100644 index 00000000..5580b6f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_print.c @@ -0,0 +1,83 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include "internal.h" + + +int ASN1_PRINTABLE_type(const unsigned char *s, int len) +{ + if (len < 0) { + len = strlen((const char *)s); + } + + int printable = 1; + for (int i = 0; i < len; i++) { + unsigned char c = s[i]; + if (c & 0x80) { + /* No need to continue iterating. */ + return V_ASN1_T61STRING; + } + if (!asn1_is_printable(c)) { + printable = 0; + } + } + + return printable ? V_ASN1_PRINTABLESTRING : V_ASN1_IA5STRING; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c new file mode 100644 index 00000000..3bb68451 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strex.c @@ -0,0 +1,651 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include + +#include "charmap.h" +#include "internal.h" + + +// These flags must be distinct from |ESC_FLAGS| and fit in a byte. + +// Character is a valid PrintableString character +#define CHARTYPE_PRINTABLESTRING 0x10 +// Character needs escaping if it is the first character +#define CHARTYPE_FIRST_ESC_2253 0x20 +// Character needs escaping if it is the last character +#define CHARTYPE_LAST_ESC_2253 0x40 + +#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) + +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) + +static int maybe_write(BIO *out, const void *buf, int len) +{ + /* If |out| is NULL, ignore the output but report the length. */ + return out == NULL || BIO_write(out, buf, len) == len; +} + +/* + * This function handles display of strings, one character at a time. It is + * passed an unsigned long for each character because it could come from 2 or + * even 4 byte forms. + */ + +#define HEX_SIZE(type) (sizeof(type)*2) + +static int do_esc_char(uint32_t c, unsigned char flags, char *do_quotes, + BIO *out) +{ + unsigned char chflgs, chtmp; + char tmphex[HEX_SIZE(uint32_t) + 3]; + + if (c > 0xffff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\W%08" PRIX32, c); + if (!maybe_write(out, tmphex, 10)) + return -1; + return 10; + } + if (c > 0xff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\U%04" PRIX32, c); + if (!maybe_write(out, tmphex, 6)) + return -1; + return 6; + } + chtmp = (unsigned char)c; + if (chtmp > 0x7f) + chflgs = flags & ASN1_STRFLGS_ESC_MSB; + else + chflgs = char_type[chtmp] & flags; + if (chflgs & CHARTYPE_BS_ESC) { + /* If we don't escape with quotes, signal we need quotes */ + if (chflgs & ASN1_STRFLGS_ESC_QUOTE) { + if (do_quotes) + *do_quotes = 1; + if (!maybe_write(out, &chtmp, 1)) + return -1; + return 1; + } + if (!maybe_write(out, "\\", 1)) + return -1; + if (!maybe_write(out, &chtmp, 1)) + return -1; + return 2; + } + if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) { + BIO_snprintf(tmphex, 11, "\\%02X", chtmp); + if (!maybe_write(out, tmphex, 3)) + return -1; + return 3; + } + /* + * If we get this far and do any escaping at all must escape the escape + * character itself: backslash. + */ + if (chtmp == '\\' && flags & ESC_FLAGS) { + if (!maybe_write(out, "\\\\", 2)) + return -1; + return 2; + } + if (!maybe_write(out, &chtmp, 1)) + return -1; + return 1; +} + +#define BUF_TYPE_WIDTH_MASK 0x7 +#define BUF_TYPE_CONVUTF8 0x8 + +/* + * This function sends each character in a buffer to do_esc_char(). It + * interprets the content formats and converts to or from UTF8 as + * appropriate. + */ + +static int do_buf(unsigned char *buf, int buflen, + int type, unsigned char flags, char *quotes, BIO *out) +{ + int i, outlen, len, charwidth; + unsigned char orflags, *p, *q; + uint32_t c; + p = buf; + q = buf + buflen; + outlen = 0; + charwidth = type & BUF_TYPE_WIDTH_MASK; + + switch (charwidth) { + case 4: + if (buflen & 3) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); + return -1; + } + break; + case 2: + if (buflen & 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); + return -1; + } + break; + default: + break; + } + + while (p != q) { + if (p == buf && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_FIRST_ESC_2253; + else + orflags = 0; + /* TODO(davidben): Replace this with |cbs_get_ucs2_be|, etc., to check + * for invalid codepoints. */ + switch (charwidth) { + case 4: + c = ((uint32_t)*p++) << 24; + c |= ((uint32_t)*p++) << 16; + c |= ((uint32_t)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((uint32_t)*p++) << 8; + c |= *p++; + break; + + case 1: + c = *p++; + break; + + case 0: + i = UTF8_getc(p, buflen, &c); + if (i < 0) + return -1; /* Invalid UTF8String */ + buflen -= i; + p += i; + break; + default: + return -1; /* invalid width */ + } + if (p == q && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_LAST_ESC_2253; + if (type & BUF_TYPE_CONVUTF8) { + unsigned char utfbuf[6]; + int utflen; + utflen = UTF8_putc(utfbuf, sizeof utfbuf, c); + for (i = 0; i < utflen; i++) { + /* + * We don't need to worry about setting orflags correctly + * because if utflen==1 its value will be correct anyway + * otherwise each character will be > 0x7f and so the + * character will never be escaped on first and last. + */ + len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), + quotes, out); + if (len < 0) + return -1; + outlen += len; + } + } else { + len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, out); + if (len < 0) + return -1; + outlen += len; + } + } + return outlen; +} + +/* This function hex dumps a buffer of characters */ + +static int do_hex_dump(BIO *out, unsigned char *buf, int buflen) +{ + static const char hexdig[] = "0123456789ABCDEF"; + unsigned char *p, *q; + char hextmp[2]; + if (out) { + p = buf; + q = buf + buflen; + while (p != q) { + hextmp[0] = hexdig[*p >> 4]; + hextmp[1] = hexdig[*p & 0xf]; + if (!maybe_write(out, hextmp, 2)) + return -1; + p++; + } + } + return buflen << 1; +} + +/* + * "dump" a string. This is done when the type is unknown, or the flags + * request it. We can either dump the content octets or the entire DER + * encoding. This uses the RFC 2253 #01234 format. + */ + +static int do_dump(unsigned long lflags, BIO *out, const ASN1_STRING *str) +{ + if (!maybe_write(out, "#", 1)) { + return -1; + } + + /* If we don't dump DER encoding just dump content octets */ + if (!(lflags & ASN1_STRFLGS_DUMP_DER)) { + int outlen = do_hex_dump(out, str->data, str->length); + if (outlen < 0) { + return -1; + } + return outlen + 1; + } + + /* + * Placing the ASN1_STRING in a temporary ASN1_TYPE allows the DER encoding + * to readily obtained. + */ + ASN1_TYPE t; + t.type = str->type; + /* Negative INTEGER and ENUMERATED values are the only case where + * |ASN1_STRING| and |ASN1_TYPE| types do not match. + * + * TODO(davidben): There are also some type fields which, in |ASN1_TYPE|, do + * not correspond to |ASN1_STRING|. It is unclear whether those are allowed + * in |ASN1_STRING| at all, or what the space of allowed types is. + * |ASN1_item_ex_d2i| will never produce such a value so, for now, we say + * this is an invalid input. But this corner of the library in general + * should be more robust. */ + if (t.type == V_ASN1_NEG_INTEGER) { + t.type = V_ASN1_INTEGER; + } else if (t.type == V_ASN1_NEG_ENUMERATED) { + t.type = V_ASN1_ENUMERATED; + } + t.value.asn1_string = (ASN1_STRING *)str; + unsigned char *der_buf = NULL; + int der_len = i2d_ASN1_TYPE(&t, &der_buf); + if (der_len < 0) { + return -1; + } + int outlen = do_hex_dump(out, der_buf, der_len); + OPENSSL_free(der_buf); + if (outlen < 0) { + return -1; + } + return outlen + 1; +} + +/* + * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is + * used for non string types otherwise it is the number of bytes per + * character + */ + +static const signed char tag2nbyte[] = { + -1, -1, -1, -1, -1, /* 0-4 */ + -1, -1, -1, -1, -1, /* 5-9 */ + -1, -1, 0, -1, /* 10-13 */ + -1, -1, -1, -1, /* 15-17 */ + 1, 1, 1, /* 18-20 */ + -1, 1, 1, 1, /* 21-24 */ + -1, 1, -1, /* 25-27 */ + 4, -1, 2 /* 28-30 */ +}; + +/* + * This is the main function, print out an ASN1_STRING taking note of various + * escape and display options. Returns number of characters written or -1 if + * an error occurred. + */ + +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long lflags) +{ + int outlen, len; + int type; + char quotes; + unsigned char flags; + quotes = 0; + /* Keep a copy of escape flags */ + flags = (unsigned char)(lflags & ESC_FLAGS); + + type = str->type; + + outlen = 0; + + if (lflags & ASN1_STRFLGS_SHOW_TYPE) { + const char *tagname; + tagname = ASN1_tag2str(type); + outlen += strlen(tagname); + if (!maybe_write(out, tagname, outlen) || !maybe_write(out, ":", 1)) + return -1; + outlen++; + } + + /* Decide what to do with type, either dump content or display it */ + + /* Dump everything */ + if (lflags & ASN1_STRFLGS_DUMP_ALL) + type = -1; + /* Ignore the string type */ + else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) + type = 1; + else { + /* Else determine width based on type */ + if ((type > 0) && (type < 31)) + type = tag2nbyte[type]; + else + type = -1; + if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) + type = 1; + } + + if (type == -1) { + len = do_dump(lflags, out, str); + if (len < 0) + return -1; + outlen += len; + return outlen; + } + + if (lflags & ASN1_STRFLGS_UTF8_CONVERT) { + /* + * Note: if string is UTF8 and we want to convert to UTF8 then we + * just interpret it as 1 byte per character to avoid converting + * twice. + */ + if (!type) + type = 1; + else + type |= BUF_TYPE_CONVUTF8; + } + + len = do_buf(str->data, str->length, type, flags, "es, NULL); + if (len < 0) + return -1; + outlen += len; + if (quotes) + outlen += 2; + if (!out) + return outlen; + if (quotes && !maybe_write(out, "\"", 1)) + return -1; + if (do_buf(str->data, str->length, type, flags, NULL, out) < 0) + return -1; + if (quotes && !maybe_write(out, "\"", 1)) + return -1; + return outlen; +} + +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, + unsigned long flags) +{ + BIO *bio = NULL; + if (fp != NULL) { + /* If |fp| is NULL, this function returns the number of bytes without + * writing. */ + bio = BIO_new_fp(fp, BIO_NOCLOSE); + if (bio == NULL) { + return -1; + } + } + int ret = ASN1_STRING_print_ex(bio, str, flags); + BIO_free(bio); + return ret; +} + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in) +{ + ASN1_STRING stmp, *str = &stmp; + int mbflag, type, ret; + if (!in) + return -1; + type = in->type; + if ((type < 0) || (type > 30)) + return -1; + mbflag = tag2nbyte[type]; + if (mbflag == -1) + return -1; + mbflag |= MBSTRING_FLAG; + stmp.data = NULL; + stmp.length = 0; + stmp.flags = 0; + ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, + B_ASN1_UTF8STRING); + if (ret < 0) + return ret; + *out = stmp.data; + return stmp.length; +} + +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) +{ + int i, n; + char buf[80]; + const char *p; + + if (v == NULL) + return (0); + n = 0; + p = (const char *)v->data; + for (i = 0; i < v->length; i++) { + if ((p[i] > '~') || ((p[i] < ' ') && + (p[i] != '\n') && (p[i] != '\r'))) + buf[n] = '.'; + else + buf[n] = p[i]; + n++; + if (n >= 80) { + if (BIO_write(bp, buf, n) <= 0) + return (0); + n = 0; + } + } + if (n > 0) + if (BIO_write(bp, buf, n) <= 0) + return (0); + return (1); +} + +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) +{ + if (tm->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_print(bp, tm); + if (tm->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_print(bp, tm); + BIO_write(bp, "Bad time value", 14); + return (0); +} + +static const char *const mon[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) +{ + char *v; + int gmt = 0; + int i; + int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; + char *f = NULL; + int f_len = 0; + + i = tm->length; + v = (char *)tm->data; + + if (i < 12) + goto err; + if (v[i - 1] == 'Z') + gmt = 1; + for (i = 0; i < 12; i++) + if ((v[i] > '9') || (v[i] < '0')) + goto err; + y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] - + '0'); + M = (v[4] - '0') * 10 + (v[5] - '0'); + if ((M > 12) || (M < 1)) + goto err; + d = (v[6] - '0') * 10 + (v[7] - '0'); + h = (v[8] - '0') * 10 + (v[9] - '0'); + m = (v[10] - '0') * 10 + (v[11] - '0'); + if (tm->length >= 14 && + (v[12] >= '0') && (v[12] <= '9') && + (v[13] >= '0') && (v[13] <= '9')) { + s = (v[12] - '0') * 10 + (v[13] - '0'); + /* Check for fractions of seconds. */ + if (tm->length >= 15 && v[14] == '.') { + int l = tm->length; + f = &v[14]; /* The decimal point. */ + f_len = 1; + while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') + ++f_len; + } + } + + if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", + mon[M - 1], d, h, m, s, f_len, f, y, + (gmt) ? " GMT" : "") <= 0) + return (0); + else + return (1); + err: + BIO_write(bp, "Bad time value", 14); + return (0); +} + +// consume_two_digits is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, has two leading digits, updates |*out| with +// their value, updates |v| and |len|, and returns one. Otherwise, returns +// zero. +static int consume_two_digits(int* out, const char **v, int *len) { + if (*len < 2 || !isdigit((unsigned char)((*v)[0])) || + !isdigit((unsigned char)((*v)[1]))) { + return 0; + } + *out = ((*v)[0] - '0') * 10 + ((*v)[1] - '0'); + *len -= 2; + *v += 2; + return 1; +} + +// consume_zulu_timezone is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, starts with "Z" then it updates |*v| and +// |*len| and returns one. Otherwise returns zero. +static int consume_zulu_timezone(const char **v, int *len) { + if (*len == 0 || (*v)[0] != 'Z') { + return 0; + } + + *len -= 1; + *v += 1; + return 1; +} + +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) { + const char *v = (const char *)tm->data; + int len = tm->length; + int Y = 0, M = 0, D = 0, h = 0, m = 0, s = 0; + + // YYMMDDhhmm are required to be present. + if (!consume_two_digits(&Y, &v, &len) || + !consume_two_digits(&M, &v, &len) || + !consume_two_digits(&D, &v, &len) || + !consume_two_digits(&h, &v, &len) || + !consume_two_digits(&m, &v, &len)) { + goto err; + } + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires seconds + // to be present, but historically this code has forgiven its absence. + consume_two_digits(&s, &v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, specifies this + // interpretation of the year. + if (Y < 50) { + Y += 2000; + } else { + Y += 1900; + } + if (M > 12 || M == 0) { + goto err; + } + if (D > 31 || D == 0) { + goto err; + } + if (h > 23 || m > 59 || s > 60) { + goto err; + } + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires the "Z" + // to be present, but historically this code has forgiven its absence. + const int is_gmt = consume_zulu_timezone(&v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, does not permit + // the specification of timezones using the +hhmm / -hhmm syntax, which is + // the only other thing that might legitimately be found at the end. + if (len) { + goto err; + } + + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", mon[M - 1], D, h, m, s, Y, + is_gmt ? " GMT" : "") > 0; + +err: + BIO_write(bp, "Bad time value", 14); + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strnid.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strnid.c new file mode 100644 index 00000000..3100edb1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_strnid.c @@ -0,0 +1,266 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "../internal.h" +#include "../lhash/internal.h" +#include "internal.h" + + +DEFINE_LHASH_OF(ASN1_STRING_TABLE) + +static LHASH_OF(ASN1_STRING_TABLE) *string_tables = NULL; +static struct CRYPTO_STATIC_MUTEX string_tables_lock = CRYPTO_STATIC_MUTEX_INIT; + +void ASN1_STRING_set_default_mask(unsigned long mask) +{ +} + +unsigned long ASN1_STRING_get_default_mask(void) +{ + return B_ASN1_UTF8STRING; +} + +int ASN1_STRING_set_default_mask_asc(const char *p) +{ + return 1; +} + +static const ASN1_STRING_TABLE *asn1_string_table_get(int nid); + +/* + * The following function generates an ASN1_STRING based on limits in a + * table. Frequently the types and length of an ASN1_STRING are restricted by + * a corresponding OID. For example certificates and certificate requests. + */ + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, + int len, int inform, int nid) +{ + ASN1_STRING *str = NULL; + int ret; + if (!out) { + out = &str; + } + const ASN1_STRING_TABLE *tbl = asn1_string_table_get(nid); + if (tbl != NULL) { + unsigned long mask = tbl->mask; + if (!(tbl->flags & STABLE_NO_MASK)) { + mask &= B_ASN1_UTF8STRING; + } + ret = ASN1_mbstring_ncopy(out, in, len, inform, mask, tbl->minsize, + tbl->maxsize); + } else { + ret = ASN1_mbstring_copy(out, in, len, inform, B_ASN1_UTF8STRING); + } + if (ret <= 0) { + return NULL; + } + return *out; +} + +/* + * Now the tables and helper functions for the string table: + */ + +/* See RFC 5280. */ +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_email_address 128 +#define ub_serial_number 64 + +/* This table must be kept in NID order */ + +static const ASN1_STRING_TABLE tbl_standard[] = { + {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, + {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, + {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, + {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, + {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, + 0}, + {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, + STABLE_NO_MASK}, + {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0}, + {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, + STABLE_NO_MASK}, + {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, + {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, + {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK} +}; + +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) +{ + if (a->nid < b->nid) { + return -1; + } + if (a->nid > b->nid) { + return 1; + } + return 0; +} + +static int table_cmp_void(const void *a, const void *b) +{ + return table_cmp(a, b); +} + +static uint32_t table_hash(const ASN1_STRING_TABLE *tbl) +{ + return OPENSSL_hash32(&tbl->nid, sizeof(tbl->nid)); +} + +static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) +{ + ASN1_STRING_TABLE key; + key.nid = nid; + const ASN1_STRING_TABLE *tbl = + bsearch(&key, tbl_standard, OPENSSL_ARRAY_SIZE(tbl_standard), + sizeof(ASN1_STRING_TABLE), table_cmp_void); + if (tbl != NULL) { + return tbl; + } + + CRYPTO_STATIC_MUTEX_lock_read(&string_tables_lock); + if (string_tables != NULL) { + tbl = lh_ASN1_STRING_TABLE_retrieve(string_tables, &key); + } + CRYPTO_STATIC_MUTEX_unlock_read(&string_tables_lock); + /* Note returning |tbl| without the lock is only safe because + * |ASN1_STRING_TABLE_add| cannot modify or delete existing entries. If we + * wish to support that, this function must copy the result under a lock. */ + return tbl; +} + +int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, + unsigned long mask, unsigned long flags) +{ + /* Existing entries cannot be overwritten. */ + if (asn1_string_table_get(nid) != NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + int ret = 0; + CRYPTO_STATIC_MUTEX_lock_write(&string_tables_lock); + + if (string_tables == NULL) { + string_tables = lh_ASN1_STRING_TABLE_new(table_hash, table_cmp); + if (string_tables == NULL) { + goto err; + } + } else { + /* Check again for an existing entry. One may have been added while + * unlocked. */ + ASN1_STRING_TABLE key; + key.nid = nid; + if (lh_ASN1_STRING_TABLE_retrieve(string_tables, &key) != NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + } + + ASN1_STRING_TABLE *tbl = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (tbl == NULL) { + goto err; + } + tbl->nid = nid; + tbl->flags = flags; + tbl->minsize = minsize; + tbl->maxsize = maxsize; + tbl->mask = mask; + ASN1_STRING_TABLE *old_tbl; + if (!lh_ASN1_STRING_TABLE_insert(string_tables, &old_tbl, tbl)) { + OPENSSL_free(tbl); + goto err; + } + assert(old_tbl == NULL); + ret = 1; + +err: + CRYPTO_STATIC_MUTEX_unlock_write(&string_tables_lock); + return ret; +} + +void ASN1_STRING_TABLE_cleanup(void) +{ +} + +void asn1_get_string_table_for_testing(const ASN1_STRING_TABLE **out_ptr, + size_t *out_len) { + *out_ptr = tbl_standard; + *out_len = OPENSSL_ARRAY_SIZE(tbl_standard); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_time.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_time.c new file mode 100644 index 00000000..be731c52 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_time.c @@ -0,0 +1,212 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" + +/* + * This is an implementation of the ASN1 Time structure which is: Time ::= + * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve + * Henson. + */ + +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) + +IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_TIME) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) +{ + return ASN1_TIME_adj(s, t, 0, 0); +} + +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec) +{ + struct tm *ts; + struct tm data; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME); + return NULL; + } + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + if ((ts->tm_year >= 50) && (ts->tm_year < 150)) + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); +} + +int ASN1_TIME_check(const ASN1_TIME *t) +{ + if (t->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_check(t); + else if (t->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_check(t); + return 0; +} + +/* Convert an ASN1_TIME structure to GeneralizedTime */ +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out) +{ + ASN1_GENERALIZEDTIME *ret = NULL; + char *str; + int newlen; + + if (!ASN1_TIME_check(t)) + return NULL; + + if (!out || !*out) { + if (!(ret = ASN1_GENERALIZEDTIME_new())) + goto err; + } else { + ret = *out; + } + + /* If already GeneralizedTime just copy across */ + if (t->type == V_ASN1_GENERALIZEDTIME) { + if (!ASN1_STRING_set(ret, t->data, t->length)) + goto err; + goto done; + } + + /* grow the string */ + if (!ASN1_STRING_set(ret, NULL, t->length + 2)) + goto err; + /* ASN1_STRING_set() allocated 'len + 1' bytes. */ + newlen = t->length + 2 + 1; + str = (char *)ret->data; + /* Work out the century and prepend */ + if (t->data[0] >= '5') + OPENSSL_strlcpy(str, "19", newlen); + else + OPENSSL_strlcpy(str, "20", newlen); + + OPENSSL_strlcat(str, (char *)t->data, newlen); + + done: + if (out != NULL && *out == NULL) + *out = ret; + return ret; + + err: + if (out == NULL || *out != ret) + ASN1_GENERALIZEDTIME_free(ret); + return NULL; +} + + +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) +{ + ASN1_TIME t; + + t.length = strlen(str); + t.data = (unsigned char *)str; + t.flags = 0; + + t.type = V_ASN1_UTCTIME; + + if (!ASN1_TIME_check(&t)) { + t.type = V_ASN1_GENERALIZEDTIME; + if (!ASN1_TIME_check(&t)) + return 0; + } + + if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) + return 0; + + return 1; +} + +static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t) +{ + if (t == NULL) { + time_t now_t; + time(&now_t); + if (OPENSSL_gmtime(&now_t, tm)) + return 1; + return 0; + } + + if (t->type == V_ASN1_UTCTIME) + return asn1_utctime_to_tm(tm, t); + else if (t->type == V_ASN1_GENERALIZEDTIME) + return asn1_generalizedtime_to_tm(tm, t); + + return 0; +} + +int ASN1_TIME_diff(int *out_days, int *out_seconds, + const ASN1_TIME *from, const ASN1_TIME *to) +{ + struct tm tm_from, tm_to; + if (!asn1_time_to_tm(&tm_from, from)) + return 0; + if (!asn1_time_to_tm(&tm_to, to)) + return 0; + return OPENSSL_gmtime_diff(out_days, out_seconds, &tm_from, &tm_to); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_type.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_type.c new file mode 100644 index 00000000..ab72b56d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_type.c @@ -0,0 +1,163 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include + +#include "internal.h" + + +int ASN1_TYPE_get(const ASN1_TYPE *a) +{ + if (a->type == V_ASN1_BOOLEAN || a->type == V_ASN1_NULL || + a->value.ptr != NULL) { + return a->type; + } + return 0; +} + +const void *asn1_type_value_as_pointer(const ASN1_TYPE *a) +{ + if (a->type == V_ASN1_BOOLEAN) { + return a->value.boolean ? (void *)0xff : NULL; + } + if (a->type == V_ASN1_NULL) { + return NULL; + } + return a->value.ptr; +} + +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) +{ + ASN1_TYPE **tmp_a = &a; + ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); + a->type = type; + if (type == V_ASN1_BOOLEAN) + a->value.boolean = value ? 0xff : 0; + else + a->value.ptr = value; +} + +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) +{ + if (!value || (type == V_ASN1_BOOLEAN)) { + void *p = (void *)value; + ASN1_TYPE_set(a, type, p); + } else if (type == V_ASN1_OBJECT) { + ASN1_OBJECT *odup; + odup = OBJ_dup(value); + if (!odup) + return 0; + ASN1_TYPE_set(a, type, odup); + } else { + ASN1_STRING *sdup; + sdup = ASN1_STRING_dup(value); + if (!sdup) + return 0; + ASN1_TYPE_set(a, type, sdup); + } + return 1; +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + + switch (a->type) { + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; + case V_ASN1_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + break; + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + case V_ASN1_BIT_STRING: + case V_ASN1_OCTET_STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + default: + result = ASN1_STRING_cmp(a->value.asn1_string, b->value.asn1_string); + break; + } + + return result; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c new file mode 100644 index 00000000..43b2b768 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c @@ -0,0 +1,264 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + + +int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) +{ + static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_UTCTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + + if (l < 11) + goto err; + for (i = 0; i < 6; i++) { + if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + if (tm) + tm->tm_sec = 0; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + switch (i) { + case 0: + tm->tm_year = n < 50 ? n + 100 : n; + break; + case 1: + tm->tm_mon = n - 1; + break; + case 2: + tm->tm_mday = n; + break; + case 3: + tm->tm_hour = n; + break; + case 4: + tm->tm_min = n; + break; + case 5: + tm->tm_sec = n; + break; + } + } + } + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + int offsign = a[o] == '-' ? 1 : -1, offset = 0; + o++; + if (o + 4 > l) + goto err; + for (i = 6; i < 8; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + if (i == 6) + offset = n * 3600; + else if (i == 7) + offset += n * 60; + } + o++; + } + if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) + return 0; + } + return o == l; + err: + return 0; +} + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) +{ + return asn1_utctime_to_tm(NULL, d); +} + +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) +{ + ASN1_UTCTIME t; + + t.type = V_ASN1_UTCTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_UTCTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_UTCTIME; + } + return (1); + } else + return (0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) +{ + return ASN1_UTCTIME_adj(s, t, 0, 0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + int free_s = 0; + + if (s == NULL) { + free_s = 1; + s = ASN1_UTCTIME_new(); + } + if (s == NULL) + goto err; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + goto err; + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + goto err; + } + + if ((ts->tm_year < 50) || (ts->tm_year >= 150)) + goto err; + + p = (char *)s->data; + if ((p == NULL) || ((size_t)s->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + if (s->data != NULL) + OPENSSL_free(s->data); + s->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + s->length = strlen(p); + s->type = V_ASN1_UTCTIME; + return (s); + err: + if (free_s && s) + ASN1_UTCTIME_free(s); + return NULL; +} + +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) +{ + struct tm stm, ttm; + int day, sec; + + if (!asn1_utctime_to_tm(&stm, s)) + return -2; + + if (!OPENSSL_gmtime(&t, &ttm)) + return -2; + + if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) + return -2; + + if (day > 0) + return 1; + if (day < 0) + return -1; + if (sec > 0) + return 1; + if (sec < 0) + return -1; + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utf8.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utf8.c new file mode 100644 index 00000000..70547262 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/a_utf8.c @@ -0,0 +1,236 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "internal.h" + +/* UTF8 utilities */ + +/* + * This parses a UTF8 string one character at a time. It is passed a pointer + * to the string and the length of the string. It sets 'value' to the value + * of the current character. It returns the number of characters read or a + * negative error code: -1 = string too short -2 = illegal character -3 = + * subsequent characters not of the form 10xxxxxx -4 = character encoded + * incorrectly (not minimal length). + */ + +int UTF8_getc(const unsigned char *str, int len, uint32_t *val) +{ + const unsigned char *p; + uint32_t value; + int ret; + if (len <= 0) + return 0; + p = str; + + /* Check syntax and work out the encoded value (if correct) */ + if ((*p & 0x80) == 0) { + value = *p++ & 0x7f; + ret = 1; + } else if ((*p & 0xe0) == 0xc0) { + if (len < 2) + return -1; + if ((p[1] & 0xc0) != 0x80) + return -3; + value = (*p++ & 0x1f) << 6; + value |= *p++ & 0x3f; + if (value < 0x80) + return -4; + ret = 2; + } else if ((*p & 0xf0) == 0xe0) { + if (len < 3) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80)) + return -3; + value = (*p++ & 0xf) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x800) + return -4; + ret = 3; + } else if ((*p & 0xf8) == 0xf0) { + if (len < 4) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80)) + return -3; + value = ((uint32_t)(*p++ & 0x7)) << 18; + value |= (*p++ & 0x3f) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x10000) + return -4; + ret = 4; + } else if ((*p & 0xfc) == 0xf8) { + if (len < 5) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80)) + return -3; + value = ((uint32_t)(*p++ & 0x3)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x200000) + return -4; + ret = 5; + } else if ((*p & 0xfe) == 0xfc) { + if (len < 6) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80) + || ((p[5] & 0xc0) != 0x80)) + return -3; + value = ((uint32_t)(*p++ & 0x1)) << 30; + value |= ((uint32_t)(*p++ & 0x3f)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x4000000) + return -4; + ret = 6; + } else + return -2; + *val = value; + return ret; +} + +/* + * This takes a character 'value' and writes the UTF8 encoded value in 'str' + * where 'str' is a buffer containing 'len' characters. Returns the number of + * characters written or -1 if 'len' is too small. 'str' can be set to NULL + * in which case it just returns the number of characters. It will need at + * most 6 characters. + */ + +int UTF8_putc(unsigned char *str, int len, uint32_t value) +{ + if (!str) + len = 6; /* Maximum we will need */ + else if (len <= 0) + return -1; + if (value < 0x80) { + if (str) + *str = (unsigned char)value; + return 1; + } + if (value < 0x800) { + if (len < 2) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 2; + } + if (value < 0x10000) { + if (len < 3) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 3; + } + if (value < 0x200000) { + if (len < 4) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 4; + } + if (value < 0x4000000) { + if (len < 5) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 5; + } + if (len < 6) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); + *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 6; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c new file mode 100644 index 00000000..81b9bb21 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c @@ -0,0 +1,405 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +/* Cross-module errors from crypto/x509/i2d_pr.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE) + +/* Cross-module errors from crypto/x509/algorithm.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE) +/* + * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove + * these once asn1_gen.c is gone. + */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR) +OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE) + +static void asn1_put_length(unsigned char **pp, int length); + +int ASN1_get_object(const unsigned char **inp, long *out_len, int *out_tag, + int *out_class, long in_len) +{ + if (in_len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + return 0x80; + } + + /* TODO(https://crbug.com/boringssl/354): This should use |CBS_get_asn1| to + * reject non-minimal lengths, which are only allowed in BER. However, + * Android sometimes needs allow a non-minimal length in certificate + * signature fields (see b/18228011). Make this only apply to that field, + * while requiring DER elsewhere. Better yet, it should be limited to an + * preprocessing step in that part of Android. */ + unsigned tag; + size_t header_len; + int indefinite; + CBS cbs, body; + CBS_init(&cbs, *inp, (size_t)in_len); + if (!CBS_get_any_ber_asn1_element(&cbs, &body, &tag, &header_len, + /*out_ber_found=*/NULL, &indefinite) || + indefinite || + !CBS_skip(&body, header_len) || + /* Bound the length to comfortably fit in an int. Lengths in this + * module often switch between int and long without overflow checks. */ + CBS_len(&body) > INT_MAX / 2) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + return 0x80; + } + + /* Convert between tag representations. */ + int tag_class = (tag & CBS_ASN1_CLASS_MASK) >> CBS_ASN1_TAG_SHIFT; + int constructed = (tag & CBS_ASN1_CONSTRUCTED) >> CBS_ASN1_TAG_SHIFT; + int tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + + /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */ + if (tag_class == V_ASN1_UNIVERSAL && tag_number > V_ASN1_MAX_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + return 0x80; + } + + *inp = CBS_data(&body); + *out_len = CBS_len(&body); + *out_tag = tag_number; + *out_class = tag_class; + return constructed; +} + +/* + * class 0 is constructed constructed == 2 for indefinite length constructed + */ +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, + int xclass) +{ + unsigned char *p = *pp; + int i, ttag; + + i = (constructed) ? V_ASN1_CONSTRUCTED : 0; + i |= (xclass & V_ASN1_PRIVATE); + if (tag < 31) + *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); + else { + *(p++) = i | V_ASN1_PRIMITIVE_TAG; + for (i = 0, ttag = tag; ttag > 0; i++) + ttag >>= 7; + ttag = i; + while (i-- > 0) { + p[i] = tag & 0x7f; + if (i != (ttag - 1)) + p[i] |= 0x80; + tag >>= 7; + } + p += ttag; + } + if (constructed == 2) + *(p++) = 0x80; + else + asn1_put_length(&p, length); + *pp = p; +} + +int ASN1_put_eoc(unsigned char **pp) +{ + /* This function is no longer used in the library, but some external code + * uses it. */ + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; +} + +static void asn1_put_length(unsigned char **pp, int length) +{ + unsigned char *p = *pp; + int i, l; + if (length <= 127) + *(p++) = (unsigned char)length; + else { + l = length; + for (i = 0; l > 0; i++) + l >>= 8; + *(p++) = i | 0x80; + l = i; + while (i-- > 0) { + p[i] = length & 0xff; + length >>= 8; + } + p += l; + } + *pp = p; +} + +int ASN1_object_size(int constructed, int length, int tag) +{ + int ret = 1; + if (length < 0) + return -1; + if (tag >= 31) { + while (tag > 0) { + tag >>= 7; + ret++; + } + } + if (constructed == 2) { + ret += 3; + } else { + ret++; + if (length > 127) { + int tmplen = length; + while (tmplen > 0) { + tmplen >>= 8; + ret++; + } + } + } + if (ret >= INT_MAX - length) + return -1; + return ret + length; +} + +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) +{ + if (str == NULL) + return 0; + if (!ASN1_STRING_set(dst, str->data, str->length)) + return 0; + dst->type = str->type; + dst->flags = str->flags; + return 1; +} + +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) +{ + ASN1_STRING *ret; + if (!str) + return NULL; + ret = ASN1_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_STRING_copy(ret, str)) { + ASN1_STRING_free(ret); + return NULL; + } + return ret; +} + +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) +{ + unsigned char *c; + const char *data = _data; + + if (len < 0) { + if (data == NULL) + return (0); + else + len = strlen(data); + } + if ((str->length <= len) || (str->data == NULL)) { + c = str->data; + if (c == NULL) + str->data = OPENSSL_malloc(len + 1); + else + str->data = OPENSSL_realloc(c, len + 1); + + if (str->data == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + str->data = c; + return (0); + } + } + str->length = len; + if (data != NULL) { + OPENSSL_memcpy(str->data, data, len); + /* an allowance for strings :-) */ + str->data[len] = '\0'; + } + return (1); +} + +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) +{ + OPENSSL_free(str->data); + str->data = data; + str->length = len; +} + +ASN1_STRING *ASN1_STRING_new(void) +{ + return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); +} + +ASN1_STRING *ASN1_STRING_type_new(int type) +{ + ASN1_STRING *ret; + + ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->type = type; + ret->data = NULL; + ret->flags = 0; + return (ret); +} + +void ASN1_STRING_free(ASN1_STRING *str) +{ + if (str == NULL) + return; + OPENSSL_free(str->data); + OPENSSL_free(str); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + /* Capture padding bits and implicit truncation in BIT STRINGs. */ + int a_length = a->length, b_length = b->length; + uint8_t a_padding = 0, b_padding = 0; + if (a->type == V_ASN1_BIT_STRING) { + a_length = asn1_bit_string_length(a, &a_padding); + } + if (b->type == V_ASN1_BIT_STRING) { + b_length = asn1_bit_string_length(b, &b_padding); + } + + if (a_length < b_length) { + return -1; + } + if (a_length > b_length) { + return 1; + } + /* In a BIT STRING, the number of bits is 8 * length - padding. Invert this + * comparison so we compare by lengths. */ + if (a_padding > b_padding) { + return -1; + } + if (a_padding < b_padding) { + return 1; + } + + int ret = OPENSSL_memcmp(a->data, b->data, a_length); + if (ret != 0) { + return ret; + } + + /* Comparing the type first is more natural, but this matches OpenSSL. */ + if (a->type < b->type) { + return -1; + } + if (a->type > b->type) { + return 1; + } + return 0; +} + +int ASN1_STRING_length(const ASN1_STRING *str) +{ + return str->length; +} + +int ASN1_STRING_type(const ASN1_STRING *str) +{ + return str->type; +} + +unsigned char *ASN1_STRING_data(ASN1_STRING *str) +{ + return str->data; +} + +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str) +{ + return str->data; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_par.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_par.c new file mode 100644 index 00000000..6b3c1594 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn1_par.c @@ -0,0 +1,80 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +const char *ASN1_tag2str(int tag) +{ + static const char *const tag2str[] = { + "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ + "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ + "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ + "", "", "SEQUENCE", "SET", /* 15-17 */ + "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ + "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 + */ + "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ + "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ + }; + + if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) + tag &= ~V_ASN1_NEG; + + if (tag < 0 || tag > 30) + return "(unknown)"; + return tag2str[tag]; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c new file mode 100644 index 00000000..fd78fd60 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c @@ -0,0 +1,101 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **out) +{ + uint8_t *new_data = NULL; + int len = ASN1_item_i2d(obj, &new_data, it); + if (len <= 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR); + return NULL; + } + + ASN1_STRING *ret = NULL; + if (out == NULL || *out == NULL) { + ret = ASN1_STRING_new(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + OPENSSL_free(new_data); + return NULL; + } + } else { + ret = *out; + } + + ASN1_STRING_set0(ret, new_data, len); + if (out != NULL) { + *out = ret; + } + return ret; +} + +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) +{ + const unsigned char *p = oct->data; + void *ret = ASN1_item_d2i(NULL, &p, oct->length, it); + if (ret == NULL || p != oct->data + oct->length) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + ASN1_item_free(ret, it); + return NULL; + } + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/charmap.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/charmap.h new file mode 100644 index 00000000..3305ad14 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/charmap.h @@ -0,0 +1,15 @@ +/* + * Auto generated with chartype.pl script. Mask of various character + * properties + */ + +static const unsigned char char_type[] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2 +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_int.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_int.c new file mode 100644 index 00000000..df4fa1bb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_int.c @@ -0,0 +1,102 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->type & V_ASN1_NEG) { + if (BIO_write(bp, "-", 1) != 1) + goto err; + n = 1; + } + + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) + goto err; + n += 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a) +{ + return i2a_ASN1_INTEGER(bp, a); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_string.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_string.c new file mode 100644 index 00000000..d8a1c843 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/f_string.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->length == 0) { + if (BIO_write(bp, "0", 1) != 1) + goto err; + n = 1; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/internal.h new file mode 100644 index 00000000..36d49db5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/internal.h @@ -0,0 +1,224 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Wrapper functions for time functions. */ + +/* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */ +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); + +/* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec| + * seconds. */ +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); + +/* OPENSSL_gmtime_diff calculates the difference between |from| and |to| and + * outputs the difference as a number of days and seconds in |*out_days| and + * |*out_secs|. */ +int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, + const struct tm *to); + + +/* Internal ASN1 structures and functions: not for application use */ + +/* These are used internally in the ASN1_OBJECT to keep track of + * whether the names and data need to be free()ed */ +#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ +#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */ +#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */ + +/* An asn1_object_st (aka |ASN1_OBJECT|) represents an ASN.1 OBJECT IDENTIFIER. + * Note: Mutating an |ASN1_OBJECT| is only permitted when initializing it. The + * library maintains a table of static |ASN1_OBJECT|s, which may be referenced + * by non-const |ASN1_OBJECT| pointers. Code which receives an |ASN1_OBJECT| + * pointer externally must assume it is immutable, even if the pointer is not + * const. */ +struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +}; + +ASN1_OBJECT *ASN1_OBJECT_new(void); + +// ASN1_ENCODING structure: this is used to save the received +// encoding of an ASN1 type. This is useful to get round +// problems with invalid encodings which can break signatures. +typedef struct ASN1_ENCODING_st { + unsigned char *enc; // DER encoding + long len; // Length of encoding + int modified; // set to 1 if 'enc' is invalid + // alias_only is zero if |enc| owns the buffer that it points to + // (although |enc| may still be NULL). If one, |enc| points into a + // buffer that is owned elsewhere. + unsigned alias_only : 1; + // alias_only_on_next_parse is one iff the next parsing operation + // should avoid taking a copy of the input and rather set + // |alias_only|. + unsigned alias_only_on_next_parse : 1; +} ASN1_ENCODING; + +int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); +int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); + +int UTF8_getc(const unsigned char *str, int len, uint32_t *val); +int UTF8_putc(unsigned char *str, int len, uint32_t value); + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +/* ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the + * i2d output convention. It returns a non-zero length on success and -1 on + * error. If |tag| is -1. the tag and class come from |it|. Otherwise, the tag + * number is |tag| and the class is |aclass|. This is used for implicit tagging. + * This function treats a missing value as an error, not an optional field. */ +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); + +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +/* asn1_get_choice_selector returns the CHOICE selector value for |*pval|, which + * must of type |it|. */ +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); + +/* asn1_get_field_ptr returns a pointer to the field in |*pval| corresponding to + * |tt|. */ +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +/* asn1_do_adb returns the |ASN1_TEMPLATE| for the ANY DEFINED BY field |tt|, + * based on the selector INTEGER or OID in |*pval|. If |tt| is not an ADB field, + * it returns |tt|. If the selector does not match any value, it returns NULL. + * If |nullerr| is non-zero, it will additionally push an error to the error + * queue when there is no match. */ +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr); + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +/* asn1_enc_restore, if |*pval| has a saved encoding, writes it to |out| under + * the i2d output convention, sets |*len| to the length, and returns one. If it + * has no saved encoding, it returns zero. */ +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it); + +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it); + +/* asn1_type_value_as_pointer returns |a|'s value in pointer form. This is + * usually the value object but, for BOOLEAN values, is 0 or 0xff cast to + * a pointer. */ +const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); + +/* asn1_is_printable returns one if |value| is a valid Unicode codepoint for an + * ASN.1 PrintableString, and zero otherwise. */ +int asn1_is_printable(uint32_t value); + +/* asn1_bit_string_length returns the number of bytes in |str| and sets + * |*out_padding_bits| to the number of padding bits. + * + * This function should be used instead of |ASN1_STRING_length| to correctly + * handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. */ +int asn1_bit_string_length(const ASN1_BIT_STRING *str, + uint8_t *out_padding_bits); + +typedef struct { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +/* asn1_get_string_table_for_testing sets |*out_ptr| and |*out_len| to the table + * of built-in |ASN1_STRING_TABLE| values. It is exported for testing. */ +OPENSSL_EXPORT void asn1_get_string_table_for_testing( + const ASN1_STRING_TABLE **out_ptr, size_t *out_len); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_ASN1_ASN1_LOCL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c new file mode 100644 index 00000000..60ba9633 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c @@ -0,0 +1,938 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +/* + * Constructed types with a recursive definition (such as can be found in PKCS7) + * could eventually exceed the stack given malicious input with excessive + * recursion. Therefore we limit the stack depth. This is the maximum number of + * recursive invocations of asn1_item_embed_d2i(). + */ +#define ASN1_MAX_CONSTRUCTED_NEST 30 + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *cst, const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx); + +static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth); +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, const ASN1_ITEM *it); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, + ASN1_TLC *ctx); + +/* Table to convert tags to bit values, used for MSTRING type */ +static const unsigned long tag2bit[32] = { + 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ + B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */ + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 8-11 */ + B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 12-15 + */ + B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags + * 16-19 + */ + B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */ + B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ + B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags + * 25-27 */ + B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags + * 28-31 + */ +}; + +unsigned long ASN1_tag2bit(int tag) +{ + if ((tag < 0) || (tag > 30)) + return 0; + return tag2bit[tag]; +} + +/* Macro to initialize and invalidate the cache */ + +#define asn1_tlc_clear(c) if (c) (c)->valid = 0 +/* Version to avoid compiler warning about 'c' always non-NULL */ +#define asn1_tlc_clear_nc(c) (c)->valid = 0 + +/* + * Decode an ASN1 item, this currently behaves just like a standard 'd2i' + * function. 'in' points to a buffer to read the data from, in future we + * will have more advanced versions that can input data a piece at a time and + * this will simply be a special case. + */ + +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it) +{ + ASN1_TLC c; + ASN1_VALUE *ptmpval = NULL; + if (!pval) + pval = &ptmpval; + asn1_tlc_clear_nc(&c); + if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + return *pval; + return NULL; +} + +/* + * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and + * tag mismatch return -1 to handle OPTIONAL + */ + +static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx, int depth) +{ + const ASN1_TEMPLATE *tt, *errtt = NULL; + const ASN1_EXTERN_FUNCS *ef; + const unsigned char *p = NULL, *q; + unsigned char oclass; + char cst, isopt; + int i; + int otag; + int ret = 0; + ASN1_VALUE **pchptr; + int combine = aclass & ASN1_TFLG_COMBINE; + aclass &= ~ASN1_TFLG_COMBINE; + if (!pval) + return 0; + + /* + * Bound |len| to comfortably fit in an int. Lengths in this module often + * switch between int and long without overflow checks. + */ + if (len > INT_MAX/2) { + len = INT_MAX/2; + } + + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP); + goto err; + } + + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + /* + * tagging or OPTIONAL is currently illegal on an item template + * because the flags can't get passed down. In practice this + * isn't a problem: we include the relevant flags from the item + * template in the template itself. + */ + if ((tag != -1) || opt) { + OPENSSL_PUT_ERROR(ASN1, + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + goto err; + } + return asn1_template_ex_d2i(pval, in, len, + it->templates, opt, ctx, depth); + } + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); + break; + + case ASN1_ITYPE_MSTRING: + /* + * It never makes sense for multi-strings to have implicit tagging, so + * if tag != -1, then this looks like an error in the template. + */ + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } + + p = *in; + /* Just read in tag and class */ + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, + &p, len, -1, 0, 1, ctx); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Must be UNIVERSAL class */ + if (oclass != V_ASN1_UNIVERSAL) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL); + goto err; + } + /* Check tag matches bit map */ + if (!(ASN1_tag2bit(otag) & it->utype)) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG); + goto err; + } + return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); + + case ASN1_ITYPE_EXTERN: + /* Use new style d2i */ + ef = it->funcs; + return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); + + case ASN1_ITYPE_CHOICE: { + /* + * It never makes sense for CHOICE types to have implicit tagging, so if + * tag != -1, then this looks like an error in the template. + */ + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } + + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + + if (*pval) { + /* Free up and zero CHOICE value if initialised */ + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + tt = it->templates + i; + pchptr = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchptr, tt); + asn1_set_choice_selector(pval, -1, it); + } + } else if (!ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + /* CHOICE type, try each possibility in turn */ + p = *in; + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + pchptr = asn1_get_field_ptr(pval, tt); + /* + * We mark field as OPTIONAL so its absence can be recognised. + */ + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + /* If field not present, try the next one */ + if (ret == -1) + continue; + /* If positive return, read OK, break loop */ + if (ret > 0) + break; + /* Otherwise must be an ASN1 parsing error */ + errtt = tt; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Did we fall off the end without reading anything? */ + if (i == it->tcount) { + /* If OPTIONAL, this is OK */ + if (opt) { + /* Free and zero it */ + ASN1_item_ex_free(pval, it); + return -1; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); + goto err; + } + + asn1_set_choice_selector(pval, i, it); + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + } + + case ASN1_ITYPE_SEQUENCE: { + p = *in; + + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + /* Get SEQUENCE length and update len, p */ + ret = asn1_check_tlen(&len, NULL, NULL, &cst, + &p, len, tag, aclass, opt, ctx); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + + /* Free up and zero any ADB found */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + if (tt->flags & ASN1_TFLG_ADB_MASK) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (seqtt == NULL) + continue; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + } + + /* Get each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) + goto err; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* Have we ran out of data? */ + if (!len) + break; + q = p; + /* + * This determines the OPTIONAL flag value. The field cannot be + * omitted if it is the last of a SEQUENCE and there is still + * data to be read. This isn't strictly necessary but it + * increases efficiency in some cases. + */ + if (i == (it->tcount - 1)) + isopt = 0; + else + isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); + /* + * attempt to read in field, allowing each to be OPTIONAL + */ + + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, + depth); + if (!ret) { + errtt = seqtt; + goto err; + } else if (ret == -1) { + /* + * OPTIONAL component absent. Free and zero the field. + */ + ASN1_template_free(pseqval, seqtt); + continue; + } + /* Update length */ + len -= p - q; + } + + /* Check all data read */ + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + goto err; + } + + /* + * If we get here we've got no more data in the SEQUENCE, however we + * may not have read all fields so check all remaining are OPTIONAL + * and clear any that are. + */ + for (; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) + goto err; + if (seqtt->flags & ASN1_TFLG_OPTIONAL) { + ASN1_VALUE **pseqval; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } else { + errtt = seqtt; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING); + goto err; + } + } + /* Save encoding */ + if (!asn1_enc_save(pval, *in, p - *in, it)) + goto auxerr; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + } + + default: + return 0; + } + auxerr: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); + err: + if (combine == 0) + ASN1_item_ex_free(pval, it); + if (errtt) + ERR_add_error_data(4, "Field=", errtt->field_name, + ", Type=", it->sname); + else + ERR_add_error_data(2, "Type=", it->sname); + return 0; +} + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); +} + +/* + * Templates are handled with two separate functions. One handles any + * EXPLICIT tag and the other handles the rest. + */ + +static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth) +{ + int flags, aclass; + int ret; + long len; + const unsigned char *p, *q; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + /* Check if EXPLICIT tag expected */ + if (flags & ASN1_TFLG_EXPTAG) { + char cst; + /* + * Need to work out amount of data available to the inner content and + * where it starts: so read in EXPLICIT header to get the info. + */ + ret = asn1_check_tlen(&len, NULL, NULL, &cst, + &p, inlen, tt->tag, aclass, opt, ctx); + q = p; + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + return 0; + } + /* We've found the field so it can't be OPTIONAL now */ + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + /* We read the field in OK so update length */ + len -= p - q; + /* Check for trailing data. */ + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH); + goto err; + } + } else + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth) +{ + int flags, aclass; + int ret; + const unsigned char *p; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + int sktag, skaclass; + /* First work out expected inner tag value */ + if (flags & ASN1_TFLG_IMPTAG) { + sktag = tt->tag; + skaclass = aclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (flags & ASN1_TFLG_SET_OF) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + /* Get the tag */ + ret = asn1_check_tlen(&len, NULL, NULL, NULL, + &p, len, sktag, skaclass, opt, ctx); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!*val) + *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); + else { + /* + * We've got a valid STACK: free up any items present + */ + STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; + ASN1_VALUE *vtmp; + while (sk_ASN1_VALUE_num(sktmp) > 0) { + vtmp = sk_ASN1_VALUE_pop(sktmp); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + } + } + + if (!*val) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read as many items as we can */ + while (len > 0) { + ASN1_VALUE *skfield; + const unsigned char *q = p; + skfield = NULL; + if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), + -1, 0, 0, ctx, depth)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + len -= p - q; + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } else if (flags & ASN1_TFLG_IMPTAG) { + /* IMPLICIT tagging */ + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, + aclass, opt, ctx, depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } else { + /* Nothing special */ + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), + -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, + depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long inlen, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + int ret = 0, utype; + long plen; + char cst; + const unsigned char *p; + const unsigned char *cont = NULL; + long len; + if (!pval) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); + return 0; /* Should never happen */ + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + utype = tag; + tag = -1; + } else + utype = it->utype; + + if (utype == V_ASN1_ANY) { + /* If type is ANY need to figure out type from tag */ + unsigned char oclass; + if (tag >= 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); + return 0; + } + p = *in; + ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, + &p, inlen, -1, 0, 0, ctx); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + if (oclass != V_ASN1_UNIVERSAL) + utype = V_ASN1_OTHER; + } + if (tag == -1) { + tag = utype; + aclass = V_ASN1_UNIVERSAL; + } + p = *in; + /* Check header */ + ret = asn1_check_tlen(&plen, NULL, NULL, &cst, + &p, inlen, tag, aclass, opt, ctx); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + ret = 0; + /* SEQUENCE, SET and "OTHER" are left in encoded form */ + if ((utype == V_ASN1_SEQUENCE) + || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { + /* + * Clear context cache for type OTHER because the auto clear when we + * have a exact match wont work + */ + if (utype == V_ASN1_OTHER) { + asn1_tlc_clear(ctx); + } + /* SEQUENCE and SET must be constructed */ + else if (!cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + + cont = *in; + len = p - cont + plen; + p += plen; + } else if (cst) { + /* This parser historically supported BER constructed strings. We no + * longer do and will gradually tighten this parser into a DER + * parser. BER types should use |CBS_asn1_ber_to_der|. */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } else { + cont = p; + len = plen; + p += plen; + } + + /* We now have content length and type: translate into a structure */ + if (!asn1_ex_c2i(pval, cont, len, utype, it)) + goto err; + + *in = p; + ret = 1; + err: + return ret; +} + +/* Translate ASN1 content octets into a structure */ + +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, const ASN1_ITEM *it) +{ + ASN1_VALUE **opval = NULL; + ASN1_STRING *stmp; + ASN1_TYPE *typ = NULL; + int ret = 0; + ASN1_INTEGER **tint; + + /* Historically, |it->funcs| for primitive types contained an + * |ASN1_PRIMITIVE_FUNCS| table of callbacks. */ + assert(it->funcs == NULL); + + /* If ANY type clear type and set pointer to internal value */ + if (it->utype == V_ASN1_ANY) { + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) + goto err; + *pval = (ASN1_VALUE *)typ; + } else + typ = (ASN1_TYPE *)*pval; + + if (utype != typ->type) + ASN1_TYPE_set(typ, utype, NULL); + opval = pval; + pval = &typ->value.asn1_value; + } + switch (utype) { + case V_ASN1_OBJECT: + if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_NULL: + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; + + case V_ASN1_BOOLEAN: + if (len != 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + goto err; + } else { + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = *cont; + } + break; + + case V_ASN1_BIT_STRING: + if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + tint = (ASN1_INTEGER **)pval; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) + goto err; + /* Fixup type to match the expected form */ + (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + case V_ASN1_SET: + case V_ASN1_SEQUENCE: + default: + if (utype == V_ASN1_BMPSTRING && (len & 1)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + goto err; + } + if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); + goto err; + } + /* All based on ASN1_STRING and handled the same */ + if (!*pval) { + stmp = ASN1_STRING_type_new(utype); + if (!stmp) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + *pval = (ASN1_VALUE *)stmp; + } else { + stmp = (ASN1_STRING *)*pval; + stmp->type = utype; + } + if (!ASN1_STRING_set(stmp, cont, len)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(stmp); + *pval = NULL; + goto err; + } + break; + } + /* If ASN1_ANY and NULL type fix up value */ + if (typ && (utype == V_ASN1_NULL)) + typ->value.ptr = NULL; + + ret = 1; + err: + if (!ret) { + ASN1_TYPE_free(typ); + if (opval) + *opval = NULL; + } + return ret; +} + +/* + * Check an ASN1 tag and length: a bit like ASN1_get_object but it handles + * the ASN1_TLC cache and checks the expected tag. + */ + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *cst, const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx) +{ + int i; + int ptag, pclass; + long plen; + const unsigned char *p, *q; + p = *in; + q = p; + + if (ctx && ctx->valid) { + i = ctx->ret; + plen = ctx->plen; + pclass = ctx->pclass; + ptag = ctx->ptag; + p += ctx->hdrlen; + } else { + i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); + if (ctx) { + ctx->ret = i; + ctx->plen = plen; + ctx->pclass = pclass; + ctx->ptag = ptag; + ctx->hdrlen = p - q; + ctx->valid = 1; + /* + * If no error, length + header can't exceed total amount of data + * available. + * + * TODO(davidben): Is this check necessary? |ASN1_get_object| + * should already guarantee this. + */ + if (!(i & 0x80) && ((plen + ctx->hdrlen) > len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } + } + } + + if (i & 0x80) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); + asn1_tlc_clear(ctx); + return 0; + } + if (exptag >= 0) { + if ((exptag != ptag) || (expclass != pclass)) { + /* + * If type is OPTIONAL, not an error: indicate missing type. + */ + if (opt) + return -1; + asn1_tlc_clear(ctx); + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG); + return 0; + } + /* + * We have a tag and class match: assume we are going to do something + * with it + */ + asn1_tlc_clear(ctx); + } + + if (cst) + *cst = i & V_ASN1_CONSTRUCTED; + + if (olen) + *olen = plen; + + if (oclass) + *oclass = pclass; + + if (otag) + *otag = ptag; + + *in = p; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c new file mode 100644 index 00000000..3fde3d70 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c @@ -0,0 +1,710 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass, + int optional); +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass, + int optional); +static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit, + int *putype, const ASN1_ITEM *it); +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, int do_sort); +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int aclass); + +/* + * Top level i2d equivalents + */ + +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) +{ + if (out && !*out) { + unsigned char *p, *buf; + int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0); + if (len <= 0) { + return len; + } + buf = OPENSSL_malloc(len); + if (!buf) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + p = buf; + int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0); + if (len2 <= 0) { + return len2; + } + assert(len == len2); + *out = buf; + return len; + } + + return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0); +} + +/* + * Encode an item, taking care of IMPLICIT tagging (if any). This function + * performs the normal item handling: it can be used in external types. + */ + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0); + assert(ret != 0); + return ret; +} + +/* asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is + * non-zero and |*pval| is omitted, it returns zero and writes no bytes. */ +int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass, + int optional) +{ + const ASN1_TEMPLATE *tt = NULL; + int i, seqcontlen, seqlen; + + /* Historically, |aclass| was repurposed to pass additional flags into the + * encoding process. */ + assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass); + /* If not overridding the tag, |aclass| is ignored and should be zero. */ + assert(tag != -1 || aclass == 0); + + /* All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s. + * Optional primitives are handled later. */ + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) { + if (optional) { + return 0; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (it->templates->flags & ASN1_TFLG_OPTIONAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass); + } + return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional); + + case ASN1_ITYPE_MSTRING: + /* + * It never makes sense for multi-strings to have implicit tagging, so + * if tag != -1, then this looks like an error in the template. + */ + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional); + + case ASN1_ITYPE_CHOICE: { + /* + * It never makes sense for CHOICE types to have implicit tagging, so if + * tag != -1, then this looks like an error in the template. + */ + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + i = asn1_get_choice_selector(pval, it); + if (i < 0 || i >= it->tcount) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); + return -1; + } + const ASN1_TEMPLATE *chtt = it->templates + i; + if (chtt->flags & ASN1_TFLG_OPTIONAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt); + return asn1_template_ex_i2d(pchval, out, chtt, -1, 0); + } + + case ASN1_ITYPE_EXTERN: { + /* If new style i2d it does all the work */ + const ASN1_EXTERN_FUNCS *ef = it->funcs; + int ret = ef->asn1_ex_i2d(pval, out, it, tag, aclass); + if (ret == 0) { + /* |asn1_ex_i2d| should never return zero. We have already checked + * for optional values generically, and |ASN1_ITYPE_EXTERN| fields + * must be pointers. */ + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return -1; + } + return ret; + } + + case ASN1_ITYPE_SEQUENCE: { + i = asn1_enc_restore(&seqcontlen, out, pval, it); + /* An error occurred */ + if (i < 0) + return -1; + /* We have a valid cached encoding... */ + if (i > 0) + return seqcontlen; + /* Otherwise carry on */ + seqcontlen = 0; + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + /* First work out sequence content length */ + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + int tmplen; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return -1; + pseqval = asn1_get_field_ptr(pval, seqtt); + tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0); + if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) + return -1; + seqcontlen += tmplen; + } + + seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag); + if (!out || seqlen == -1) + return seqlen; + /* Output SEQUENCE header */ + ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return -1; + pseqval = asn1_get_field_ptr(pval, seqtt); + if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0) < 0) { + return -1; + } + } + return seqlen; + } + + default: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } +} + +/* asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an + * |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an + * |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. Instead of + * taking an |optional| parameter, it uses the |ASN1_TFLG_OPTIONAL| flag. */ +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int iclass) +{ + int i, ret, flags, ttag, tclass; + size_t j; + flags = tt->flags; + + /* Historically, |iclass| was repurposed to pass additional flags into the + * encoding process. */ + assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass); + /* If not overridding the tag, |iclass| is ignored and should be zero. */ + assert(tag != -1 || iclass == 0); + + /* + * Work out tag and class to use: tagging may come either from the + * template or the arguments, not both because this would create + * ambiguity. + */ + if (flags & ASN1_TFLG_TAG_MASK) { + /* Error if argument and template tagging */ + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + /* Get tagging from template */ + ttag = tt->tag; + tclass = flags & ASN1_TFLG_TAG_CLASS; + } else if (tag != -1) { + /* No template tagging, get from arguments */ + ttag = tag; + tclass = iclass & ASN1_TFLG_TAG_CLASS; + } else { + ttag = -1; + tclass = 0; + } + + const int optional = (flags & ASN1_TFLG_OPTIONAL) != 0; + + /* + * At this point 'ttag' contains the outer tag to use, and 'tclass' is the + * class. + */ + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + int isset, sktag, skaclass; + int skcontlen, sklen; + ASN1_VALUE *skitem; + + if (!*pval) { + if (optional) { + return 0; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + if (flags & ASN1_TFLG_SET_OF) { + isset = 1; + /* Historically, types with both bits set were mutated when + * serialized to apply the sort. We no longer support this. */ + assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0); + } else { + isset = 0; + } + + /* + * Work out inner tag value: if EXPLICIT or no tagging use underlying + * type. + */ + if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { + sktag = ttag; + skaclass = tclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (isset) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + + /* Determine total length of items */ + skcontlen = 0; + for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) { + int tmplen; + skitem = sk_ASN1_VALUE_value(sk, j); + tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), + -1, 0); + if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) + return -1; + skcontlen += tmplen; + } + sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag); + if (sklen == -1) + return -1; + /* If EXPLICIT need length of surrounding tag */ + if (flags & ASN1_TFLG_EXPTAG) + ret = ASN1_object_size(/*constructed=*/1, sklen, ttag); + else + ret = sklen; + + if (!out || ret == -1) + return ret; + + /* Now encode this lot... */ + /* EXPLICIT tag */ + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass); + /* SET or SEQUENCE and IMPLICIT tag */ + ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass); + /* And the stuff itself */ + if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), + isset)) { + return -1; + } + return ret; + } + + if (flags & ASN1_TFLG_EXPTAG) { + /* EXPLICIT tagging */ + /* Find length of tagged item */ + i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0, + optional); + if (i <= 0) + return i; + /* Find length of EXPLICIT tag */ + ret = ASN1_object_size(/*constructed=*/1, i, ttag); + if (out && ret != -1) { + /* Output tag and item */ + ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass); + if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, + 0) < 0) { + return -1; + } + } + return ret; + } + + /* Either normal or IMPLICIT tagging */ + return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item), + ttag, tclass, optional); + +} + +/* Temporary structure used to hold DER encoding of items for SET OF */ + +typedef struct { + unsigned char *data; + int length; +} DER_ENC; + +static int der_cmp(const void *a, const void *b) +{ + const DER_ENC *d1 = a, *d2 = b; + int cmplen, i; + cmplen = (d1->length < d2->length) ? d1->length : d2->length; + i = OPENSSL_memcmp(d1->data, d2->data, cmplen); + if (i) + return i; + return d1->length - d2->length; +} + +/* asn1_set_seq_out writes |sk| to |out| under the i2d output convention, + * excluding the tag and length. It returns one on success and zero on error. + * |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the + * elements are sorted for a SET OF type. Each element of |sk| has type + * |item|. */ +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, int do_sort) +{ + /* No need to sort if there are fewer than two items. */ + if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) { + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); + if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) { + return 0; + } + } + return 1; + } + + if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + + int ret = 0; + unsigned char *const buf = OPENSSL_malloc(skcontlen); + DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded)); + if (encoded == NULL || buf == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode all the elements into |buf| and populate |encoded|. */ + unsigned char *p = buf; + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); + encoded[i].data = p; + encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0); + if (encoded[i].length < 0) { + goto err; + } + assert(p - buf <= skcontlen); + } + + qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp); + + /* Output the elements in sorted order. */ + p = *out; + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + OPENSSL_memcpy(p, encoded[i].data, encoded[i].length); + p += encoded[i].length; + } + *out = p; + + ret = 1; + +err: + OPENSSL_free(encoded); + OPENSSL_free(buf); + return ret; +} + +/* asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a + * a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|. */ +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass, + int optional) +{ + /* Get length of content octets and maybe find out the underlying type. */ + int omit; + int utype = it->utype; + int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it); + if (len < 0) { + return -1; + } + if (omit) { + if (optional) { + return 0; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + /* + * If SEQUENCE, SET or OTHER then header is included in pseudo content + * octets so don't include tag+length. We need to check here because the + * call to asn1_ex_i2c() could change utype. + */ + int usetag = utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET && + utype != V_ASN1_OTHER; + + /* If not implicitly tagged get tag from underlying type */ + if (tag == -1) + tag = utype; + + /* Output tag+length followed by content octets */ + if (out) { + if (usetag) { + ASN1_put_object(out, /*constructed=*/0, len, tag, aclass); + } + int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it); + if (len2 < 0) { + return -1; + } + assert(len == len2); + assert(!omit); + *out += len; + } + + if (usetag) { + return ASN1_object_size(/*constructed=*/0, len, tag); + } + return len; +} + +/* asn1_ex_i2c writes the |*pval| to |cout| under the i2d output convention, + * excluding the tag and length. It returns the number of bytes written, + * possibly zero, on success or -1 on error. If |*pval| should be omitted, it + * returns zero and sets |*out_omit| to true. + * + * If |it| is an MSTRING or ANY type, it gets the underlying type from |*pval|, + * which must be an |ASN1_STRING| or |ASN1_TYPE|, respectively. It then updates + * |*putype| with the tag number of type used, or |V_ASN1_OTHER| if it was not a + * universal type. If |*putype| is set to |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or + * |V_ASN1_OTHER|, it additionally outputs the tag and length, so the caller + * must not do so. + * + * Otherwise, |*putype| must contain |it->utype|. + * + * WARNING: Unlike most functions in this file, |asn1_ex_i2c| can return zero + * without omitting the element. ASN.1 values may have empty contents. */ +static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit, + int *putype, const ASN1_ITEM *it) +{ + ASN1_BOOLEAN *tbool = NULL; + ASN1_STRING *strtmp; + ASN1_OBJECT *otmp; + int utype; + const unsigned char *cont; + unsigned char c; + int len; + + /* Historically, |it->funcs| for primitive types contained an + * |ASN1_PRIMITIVE_FUNCS| table of callbacks. */ + assert(it->funcs == NULL); + + *out_omit = 0; + + /* Should type be omitted? */ + if ((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) { + if (!*pval) { + *out_omit = 1; + return 0; + } + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + /* If MSTRING type set the underlying type */ + strtmp = (ASN1_STRING *)*pval; + utype = strtmp->type; + if (utype < 0 && utype != V_ASN1_OTHER) { + /* MSTRINGs can have type -1 when default-constructed. */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return -1; + } + /* Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values + * that do not match their corresponding utype values. INTEGERs cannot + * participate in MSTRING types, but ENUMERATEDs can. + * + * TODO(davidben): Is this a bug? Although arguably one of the MSTRING + * types should contain more values, rather than less. See + * https://crbug.com/boringssl/412. But it is not possible to fit all + * possible ANY values into an |ASN1_STRING|, so matching the spec here + * is somewhat hopeless. */ + if (utype == V_ASN1_NEG_INTEGER) { + utype = V_ASN1_INTEGER; + } else if (utype == V_ASN1_NEG_ENUMERATED) { + utype = V_ASN1_ENUMERATED; + } + *putype = utype; + } else if (it->utype == V_ASN1_ANY) { + /* If ANY set type and pointer to value */ + ASN1_TYPE *typ; + typ = (ASN1_TYPE *)*pval; + utype = typ->type; + if (utype < 0 && utype != V_ASN1_OTHER) { + /* |ASN1_TYPE|s can have type -1 when default-constructed. */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return -1; + } + *putype = utype; + pval = &typ->value.asn1_value; + } else + utype = *putype; + + switch (utype) { + case V_ASN1_OBJECT: + otmp = (ASN1_OBJECT *)*pval; + cont = otmp->data; + len = otmp->length; + if (len == 0) { + /* Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized. */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + return -1; + } + break; + + case V_ASN1_NULL: + cont = NULL; + len = 0; + break; + + case V_ASN1_BOOLEAN: + tbool = (ASN1_BOOLEAN *)pval; + if (*tbool == -1) { + *out_omit = 1; + return 0; + } + if (it->utype != V_ASN1_ANY) { + /* + * Default handling if value == size field then omit + */ + if ((*tbool && (it->size > 0)) || + (!*tbool && !it->size)) { + *out_omit = 1; + return 0; + } + } + c = *tbool ? 0xff : 0x00; + cont = &c; + len = 1; + break; + + case V_ASN1_BIT_STRING: { + int ret = i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, + cout ? &cout : NULL); + /* |i2c_ASN1_BIT_STRING| returns zero on error instead of -1. */ + return ret <= 0 ? -1 : ret; + } + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: { + /* |i2c_ASN1_INTEGER| also handles ENUMERATED. */ + int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + /* |i2c_ASN1_INTEGER| returns zero on error instead of -1. */ + return ret <= 0 ? -1 : ret; + } + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + default: + /* All based on ASN1_STRING and handled the same */ + strtmp = (ASN1_STRING *)*pval; + cont = strtmp->data; + len = strtmp->length; + + break; + + } + if (cout && len) + OPENSSL_memcpy(cout, cont, len); + return len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c new file mode 100644 index 00000000..289a6691 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include + +#include "internal.h" + +/* Free up an ASN1 structure */ + +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) +{ + asn1_item_combine_free(&val, it, 0); +} + +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + asn1_item_combine_free(pval, it, 0); +} + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) +{ + const ASN1_TEMPLATE *tt = NULL, *seqtt; + const ASN1_EXTERN_FUNCS *ef; + int i; + if (!pval) + return; + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return; + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + ASN1_template_free(pval, it->templates); + else + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_CHOICE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + tt = it->templates + i; + pchval = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchval, tt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + } + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_free) + ef->asn1_ex_free(pval, it); + break; + + case ASN1_ITYPE_SEQUENCE: { + if (!asn1_refcount_dec_and_test_zero(pval, it)) + return; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + asn1_enc_free(pval, it); + /* + * If we free up as normal we will invalidate any ANY DEFINED BY + * field and we wont be able to determine the type of the field it + * defines. So free up in reverse order. + */ + tt = it->templates + it->tcount - 1; + for (i = 0; i < it->tcount; tt--, i++) { + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (!seqtt) + continue; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + } + } +} + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + size_t i; + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *vtmp; + vtmp = sk_ASN1_VALUE_value(sk, i); + asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); + } + sk_ASN1_VALUE_free(sk); + *pval = NULL; + } else + asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), + tt->flags & ASN1_TFLG_COMBINE); +} + +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + /* Historically, |it->funcs| for primitive types contained an + * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ + assert(it == NULL || it->funcs == NULL); + /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ + if (!it) { + ASN1_TYPE *typ = (ASN1_TYPE *)*pval; + utype = typ->type; + pval = &typ->value.asn1_value; + if (utype != V_ASN1_BOOLEAN && !*pval) + return; + } else if (it->itype == ASN1_ITYPE_MSTRING) { + utype = -1; + if (!*pval) + return; + } else { + utype = it->utype; + if ((utype != V_ASN1_BOOLEAN) && !*pval) + return; + } + + switch (utype) { + case V_ASN1_OBJECT: + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + break; + + case V_ASN1_BOOLEAN: + if (it) + *(ASN1_BOOLEAN *)pval = it->size; + else + *(ASN1_BOOLEAN *)pval = -1; + return; + + case V_ASN1_NULL: + break; + + case V_ASN1_ANY: + ASN1_primitive_free(pval, NULL); + OPENSSL_free(*pval); + break; + + default: + ASN1_STRING_free((ASN1_STRING *)*pval); + *pval = NULL; + break; + } + *pval = NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c new file mode 100644 index 00000000..21e6d94c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c @@ -0,0 +1,332 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); +static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); + +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) +{ + ASN1_VALUE *ret = NULL; + if (ASN1_item_ex_new(&ret, it) > 0) + return ret; + return NULL; +} + +/* Allocate an ASN1 structure */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + return asn1_item_ex_combine_new(pval, it, 0); +} + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine) +{ + const ASN1_TEMPLATE *tt = NULL; + const ASN1_EXTERN_FUNCS *ef; + ASN1_VALUE **pseqval; + int i; + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_new) { + if (!ef->asn1_ex_new(pval, it)) + goto memerr; + } + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (!ASN1_template_new(pval, it->templates)) + goto memerr; + } else if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_MSTRING: + if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_CHOICE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + OPENSSL_memset(*pval, 0, it->size); + } + asn1_set_choice_selector(pval, -1, it); + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr2; + break; + } + + case ASN1_ITYPE_SEQUENCE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + OPENSSL_memset(*pval, 0, it->size); + asn1_refcount_set_one(pval, it); + asn1_enc_init(pval, it); + } + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + pseqval = asn1_get_field_ptr(pval, tt); + if (!ASN1_template_new(pseqval, tt)) + goto memerr2; + } + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr2; + break; + } + } + return 1; + + memerr2: + asn1_item_combine_free(pval, it, combine); + memerr: + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + + auxerr2: + asn1_item_combine_free(pval, it, combine); + auxerr: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); + return 0; + +} + +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const ASN1_EXTERN_FUNCS *ef; + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_clear) + ef->asn1_ex_clear(pval, it); + else + *pval = NULL; + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + asn1_template_clear(pval, it->templates); + else + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_SEQUENCE: + *pval = NULL; + break; + } +} + +static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); + int ret; + if (tt->flags & ASN1_TFLG_OPTIONAL) { + asn1_template_clear(pval, tt); + return 1; + } + /* If ANY DEFINED BY nothing to do */ + + if (tt->flags & ASN1_TFLG_ADB_MASK) { + *pval = NULL; + return 1; + } + /* If SET OF or SEQUENCE OF, its a STACK */ + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *skval; + skval = sk_ASN1_VALUE_new_null(); + if (!skval) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + ret = 0; + goto done; + } + *pval = (ASN1_VALUE *)skval; + ret = 1; + goto done; + } + /* Otherwise pass it back to the item routine */ + ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); + done: + return ret; +} + +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + /* If ADB or STACK just NULL the field */ + if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) + *pval = NULL; + else + asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); +} + +/* + * NB: could probably combine most of the real XXX_new() behaviour and junk + * all the old functions. + */ + +static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_TYPE *typ; + int utype; + + if (!it) + return 0; + + /* Historically, |it->funcs| for primitive types contained an + * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ + assert(it->funcs == NULL); + + if (it->itype == ASN1_ITYPE_MSTRING) + utype = -1; + else + utype = it->utype; + switch (utype) { + case V_ASN1_OBJECT: + *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); + return 1; + + case V_ASN1_BOOLEAN: + *(ASN1_BOOLEAN *)pval = it->size; + return 1; + + case V_ASN1_NULL: + *pval = (ASN1_VALUE *)1; + return 1; + + case V_ASN1_ANY: + typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); + if (!typ) + return 0; + typ->value.ptr = NULL; + typ->type = -1; + *pval = (ASN1_VALUE *)typ; + break; + + default: + *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); + break; + } + if (*pval) + return 1; + return 0; +} + +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + /* Historically, |it->funcs| for primitive types contained an + * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ + assert(it == NULL || it->funcs == NULL); + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) + utype = -1; + else + utype = it->utype; + if (utype == V_ASN1_BOOLEAN) + *(ASN1_BOOLEAN *)pval = it->size; + else + *pval = NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c new file mode 100644 index 00000000..36aceb88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c @@ -0,0 +1,131 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +/* Declarations for string types */ + +#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ + IMPLEMENT_ASN1_TYPE(sname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \ + sname *sname##_new(void) \ + { \ + return ASN1_STRING_type_new(V_##sname); \ + } \ + void sname##_free(sname *x) \ + { \ + ASN1_STRING_free(x); \ + } + +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_NULL) +IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_NULL) + +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) + +IMPLEMENT_ASN1_TYPE(ASN1_ANY) + +/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ +IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) + +IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +/* Multistring types */ + +IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) +IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, ASN1_PRINTABLE, + ASN1_PRINTABLE) + +IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT) +IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, DISPLAYTEXT, DISPLAYTEXT) + +IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) +IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, DIRECTORYSTRING, + DIRECTORYSTRING) + +/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) + +/* Special, OCTET STRING with indefinite length constructed support */ + +ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) + +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c new file mode 100644 index 00000000..731b49a0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c @@ -0,0 +1,277 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +/* Utility functions for manipulating fields and offsets */ + +/* Add 'offset' to 'addr' */ +#define offset2ptr(addr, offset) (void *)(((char *)(addr)) + (offset)) + +/* Given an ASN1_ITEM CHOICE type return the selector value */ +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) { + int *sel = offset2ptr(*pval, it->utype); + return *sel; +} + +/* Given an ASN1_ITEM CHOICE type set the selector value, return old value. */ +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it) { + int *sel, ret; + sel = offset2ptr(*pval, it->utype); + ret = *sel; + *sel = value; + return ret; +} + +static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval, + const ASN1_ITEM *it) { + if (it->itype != ASN1_ITYPE_SEQUENCE) { + return NULL; + } + const ASN1_AUX *aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) { + return NULL; + } + return offset2ptr(*pval, aux->ref_offset); +} + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + *references = 1; + } +} + +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + return CRYPTO_refcount_dec_and_test_zero(references); + } + return 1; +} + +static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { + assert(it->itype == ASN1_ITYPE_SEQUENCE); + const ASN1_AUX *aux; + if (!pval || !*pval) { + return NULL; + } + aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) { + return NULL; + } + return offset2ptr(*pval, aux->enc_offset); +} + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + enc->enc = NULL; + enc->len = 0; + enc->alias_only = 0; + enc->alias_only_on_next_parse = 0; + enc->modified = 1; + } +} + +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + if (enc->enc && !enc->alias_only) { + OPENSSL_free(enc->enc); + } + enc->enc = NULL; + enc->len = 0; + enc->alias_only = 0; + enc->alias_only_on_next_parse = 0; + enc->modified = 1; + } +} + +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it) { + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc) { + return 1; + } + + if (!enc->alias_only) { + OPENSSL_free(enc->enc); + } + + enc->alias_only = enc->alias_only_on_next_parse; + enc->alias_only_on_next_parse = 0; + + if (enc->alias_only) { + enc->enc = (uint8_t *) in; + } else { + enc->enc = OPENSSL_malloc(inlen); + if (!enc->enc) { + return 0; + } + OPENSSL_memcpy(enc->enc, in, inlen); + } + + enc->len = inlen; + enc->modified = 0; + + return 1; +} + +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it) { + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc || enc->modified) { + return 0; + } + if (out) { + OPENSSL_memcpy(*out, enc->enc, enc->len); + *out += enc->len; + } + if (len) { + *len = enc->len; + } + return 1; +} + +/* Given an ASN1_TEMPLATE get a pointer to a field */ +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { + ASN1_VALUE **pvaltmp; + if (tt->flags & ASN1_TFLG_COMBINE) { + return pval; + } + pvaltmp = offset2ptr(*pval, tt->offset); + /* NOTE for BOOLEAN types the field is just a plain int so we can't return + * int **, so settle for (int *). */ + return pvaltmp; +} + +/* Handle ANY DEFINED BY template, find the selector, look up the relevant + * ASN1_TEMPLATE in the table and return it. */ +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr) { + const ASN1_ADB *adb; + const ASN1_ADB_TABLE *atbl; + ASN1_VALUE **sfld; + int i; + if (!(tt->flags & ASN1_TFLG_ADB_MASK)) { + return tt; + } + + /* Else ANY DEFINED BY ... get the table */ + adb = ASN1_ADB_ptr(tt->item); + + /* Get the selector field */ + sfld = offset2ptr(*pval, adb->offset); + + /* Check if NULL */ + if (*sfld == NULL) { + if (!adb->null_tt) { + goto err; + } + return adb->null_tt; + } + + /* Convert type to a NID: + * NB: don't check for NID_undef here because it + * might be a legitimate value in the table */ + assert(tt->flags & ASN1_TFLG_ADB_OID); + int selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); + + /* Try to find matching entry in table Maybe should check application types + * first to allow application override? Might also be useful to have a flag + * which indicates table is sorted and we can do a binary search. For now + * stick to a linear search. */ + + for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) { + if (atbl->value == selector) { + return &atbl->tt; + } + } + + /* FIXME: need to search application table too */ + + /* No match, return default type */ + if (!adb->default_tt) { + goto err; + } + return adb->default_tt; + +err: + /* FIXME: should log the value or OID of unsupported type */ + if (nullerr) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + } + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/time_support.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/time_support.c new file mode 100644 index 00000000..e748ad75 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/asn1/time_support.c @@ -0,0 +1,206 @@ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2008. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 201410L /* for gmtime_r */ +#endif + +#include "internal.h" + +#include + + +#define SECS_PER_DAY (24 * 60 * 60) + +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result) { +#if defined(OPENSSL_WINDOWS) + if (gmtime_s(result, time)) { + return NULL; + } + return result; +#else + return gmtime_r(time, result); +#endif +} + +/* Convert date to and from julian day Uses Fliegel & Van Flandern algorithm */ +static long date_to_julian(int y, int m, int d) { + return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + + (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - + (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; +} + +static void julian_to_date(long jd, int *y, int *m, int *d) { + long L = jd + 68569; + long n = (4 * L) / 146097; + long i, j; + + L = L - (146097 * n + 3) / 4; + i = (4000 * (L + 1)) / 1461001; + L = L - (1461 * i) / 4 + 31; + j = (80 * L) / 2447; + *d = L - (2447 * j) / 80; + L = j / 11; + *m = j + 2 - (12 * L); + *y = 100 * (n - 49) + i + L; +} + +/* Convert tm structure and offset into julian day and seconds */ +static int julian_adj(const struct tm *tm, int off_day, long offset_sec, + long *pday, int *psec) { + int offset_hms, offset_day; + long time_jd; + int time_year, time_month, time_day; + /* split offset into days and day seconds */ + offset_day = offset_sec / SECS_PER_DAY; + /* Avoid sign issues with % operator */ + offset_hms = offset_sec - (offset_day * SECS_PER_DAY); + offset_day += off_day; + /* Add current time seconds to offset */ + offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + /* Adjust day seconds if overflow */ + if (offset_hms >= SECS_PER_DAY) { + offset_day++; + offset_hms -= SECS_PER_DAY; + } else if (offset_hms < 0) { + offset_day--; + offset_hms += SECS_PER_DAY; + } + + /* Convert date of time structure into a Julian day number. */ + + time_year = tm->tm_year + 1900; + time_month = tm->tm_mon + 1; + time_day = tm->tm_mday; + + time_jd = date_to_julian(time_year, time_month, time_day); + + /* Work out Julian day of new date */ + time_jd += offset_day; + + if (time_jd < 0) { + return 0; + } + + *pday = time_jd; + *psec = offset_hms; + return 1; +} + +int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { + int time_sec, time_year, time_month, time_day; + long time_jd; + + /* Convert time and offset into julian day and seconds */ + if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec)) { + return 0; + } + + /* Convert Julian day back to date */ + + julian_to_date(time_jd, &time_year, &time_month, &time_day); + + if (time_year < 1900 || time_year > 9999) { + return 0; + } + + /* Update tm structure */ + + tm->tm_year = time_year - 1900; + tm->tm_mon = time_month - 1; + tm->tm_mday = time_day; + + tm->tm_hour = time_sec / 3600; + tm->tm_min = (time_sec / 60) % 60; + tm->tm_sec = time_sec % 60; + + return 1; +} + +int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, + const struct tm *to) { + int from_sec, to_sec, diff_sec; + long from_jd, to_jd, diff_day; + + if (!julian_adj(from, 0, 0, &from_jd, &from_sec)) { + return 0; + } + if (!julian_adj(to, 0, 0, &to_jd, &to_sec)) { + return 0; + } + + diff_day = to_jd - from_jd; + diff_sec = to_sec - from_sec; + /* Adjust differences so both positive or both negative */ + if (diff_day > 0 && diff_sec < 0) { + diff_day--; + diff_sec += SECS_PER_DAY; + } + if (diff_day < 0 && diff_sec > 0) { + diff_day++; + diff_sec -= SECS_PER_DAY; + } + + if (out_days) { + *out_days = (int)diff_day; + } + if (out_secs) { + *out_secs = diff_sec; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/base64/base64.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/base64/base64.c new file mode 100644 index 00000000..79e5e053 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/base64/base64.c @@ -0,0 +1,482 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include + +#include "../internal.h" + + +// constant_time_lt_args_8 behaves like |constant_time_lt_8| but takes |uint8_t| +// arguments for a slightly simpler implementation. +static inline uint8_t constant_time_lt_args_8(uint8_t a, uint8_t b) { + crypto_word_t aw = a; + crypto_word_t bw = b; + // |crypto_word_t| is larger than |uint8_t|, so |aw| and |bw| have the same + // MSB. |aw| < |bw| iff MSB(|aw| - |bw|) is 1. + return constant_time_msb_w(aw - bw); +} + +// constant_time_in_range_8 returns |CONSTTIME_TRUE_8| if |min| <= |a| <= |max| +// and |CONSTTIME_FALSE_8| otherwise. +static inline uint8_t constant_time_in_range_8(uint8_t a, uint8_t min, + uint8_t max) { + a -= min; + return constant_time_lt_args_8(a, max - min + 1); +} + +// Encoding. + +static uint8_t conv_bin2ascii(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we encode base64 data + // itself in constant-time. + a &= 0x3f; + uint8_t ret = constant_time_select_8(constant_time_eq_8(a, 62), '+', '/'); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 62), a - 52 + '0', ret); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 52), a - 26 + 'a', ret); + ret = constant_time_select_8(constant_time_lt_args_8(a, 26), a + 'A', ret); + return ret; +} + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0, + "data length must be a multiple of base64 chunk size"); + +int EVP_EncodedLength(size_t *out_len, size_t len) { + if (len + 2 < len) { + return 0; + } + len += 2; + len /= 3; + + if (((len << 2) >> 2) != len) { + return 0; + } + len <<= 2; + + if (len + 1 < len) { + return 0; + } + len++; + + *out_len = len; + return 1; +} + +EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void) { + EVP_ENCODE_CTX *ret = OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EVP_ENCODE_CTX)); + return ret; +} + +void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) { + OPENSSL_free(ctx); +} + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + size_t total = 0; + + *out_len = 0; + if (in_len == 0) { + return; + } + + assert(ctx->data_used < sizeof(ctx->data)); + + if (sizeof(ctx->data) - ctx->data_used > in_len) { + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len); + ctx->data_used += (unsigned)in_len; + return; + } + + if (ctx->data_used != 0) { + const size_t todo = sizeof(ctx->data) - ctx->data_used; + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo); + in += todo; + in_len -= todo; + + size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data)); + ctx->data_used = 0; + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + total = encoded + 1; + } + + while (in_len >= sizeof(ctx->data)) { + size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data)); + in += sizeof(ctx->data); + in_len -= sizeof(ctx->data); + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + if (total + encoded + 1 < total) { + *out_len = 0; + return; + } + + total += encoded + 1; + } + + if (in_len != 0) { + OPENSSL_memcpy(ctx->data, in, in_len); + } + + ctx->data_used = (unsigned)in_len; + + if (total > INT_MAX) { + // We cannot signal an error, but we can at least avoid making *out_len + // negative. + total = 0; + } + *out_len = (int)total; +} + +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->data_used == 0) { + *out_len = 0; + return; + } + + size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used); + out[encoded++] = '\n'; + out[encoded] = '\0'; + ctx->data_used = 0; + + // ctx->data_used is bounded by sizeof(ctx->data), so this does not + // overflow. + assert(encoded <= INT_MAX); + *out_len = (int)encoded; +} + +size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + uint32_t l; + size_t remaining = src_len, ret = 0; + + while (remaining) { + if (remaining >= 3) { + l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2]; + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = conv_bin2ascii(l >> 6L); + *(dst++) = conv_bin2ascii(l); + remaining -= 3; + } else { + l = ((uint32_t)src[0]) << 16L; + if (remaining == 2) { + l |= ((uint32_t)src[1] << 8L); + } + + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(dst++) = '='; + remaining = 0; + } + ret += 4; + src += 3; + } + + *dst = '\0'; + return ret; +} + + +// Decoding. + +int EVP_DecodedLength(size_t *out_len, size_t len) { + if (len % 4 != 0) { + return 0; + } + + *out_len = (len / 4) * 3; + return 1; +} + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +static uint8_t base64_ascii_to_bin(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we decode base64 data + // itself in constant-time. + const uint8_t is_upper = constant_time_in_range_8(a, 'A', 'Z'); + const uint8_t is_lower = constant_time_in_range_8(a, 'a', 'z'); + const uint8_t is_digit = constant_time_in_range_8(a, '0', '9'); + const uint8_t is_plus = constant_time_eq_8(a, '+'); + const uint8_t is_slash = constant_time_eq_8(a, '/'); + const uint8_t is_equals = constant_time_eq_8(a, '='); + + uint8_t ret = 0; + ret |= is_upper & (a - 'A'); // [0,26) + ret |= is_lower & (a - 'a' + 26); // [26,52) + ret |= is_digit & (a - '0' + 52); // [52,62) + ret |= is_plus & 62; + ret |= is_slash & 63; + // Invalid inputs, 'A', and '=' have all been mapped to zero. Map invalid + // inputs to 0xff. Note '=' is padding and handled separately by the caller. + const uint8_t is_valid = + is_upper | is_lower | is_digit | is_plus | is_slash | is_equals; + ret |= ~is_valid; + return ret; +} + +// base64_decode_quad decodes a single “quad” (i.e. four characters) of base64 +// data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the +// number of bytes written, which will be less than three if the quad ended +// with padding. It returns one on success or zero on error. +static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes, + const uint8_t *in) { + const uint8_t a = base64_ascii_to_bin(in[0]); + const uint8_t b = base64_ascii_to_bin(in[1]); + const uint8_t c = base64_ascii_to_bin(in[2]); + const uint8_t d = base64_ascii_to_bin(in[3]); + if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) { + return 0; + } + + const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 | + ((uint32_t)c) << 6 | (uint32_t)d; + + const unsigned padding_pattern = (in[0] == '=') << 3 | + (in[1] == '=') << 2 | + (in[2] == '=') << 1 | + (in[3] == '='); + + switch (padding_pattern) { + case 0: + // The common case of no padding. + *out_num_bytes = 3; + out[0] = v >> 16; + out[1] = v >> 8; + out[2] = v; + break; + + case 1: // xxx= + *out_num_bytes = 2; + out[0] = v >> 16; + out[1] = v >> 8; + break; + + case 3: // xx== + *out_num_bytes = 1; + out[0] = v >> 16; + break; + + default: + return 0; + } + + return 1; +} + +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (ctx->error_encountered) { + return -1; + } + + size_t bytes_out = 0, i; + for (i = 0; i < in_len; i++) { + const char c = in[i]; + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + continue; + } + + if (ctx->eof_seen) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data[ctx->data_used++] = c; + if (ctx->data_used == 4) { + size_t num_bytes_resulting; + if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data_used = 0; + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + + if (num_bytes_resulting < 3) { + ctx->eof_seen = 1; + } + } + } + + if (bytes_out > INT_MAX) { + ctx->error_encountered = 1; + *out_len = 0; + return -1; + } + *out_len = (int)bytes_out; + + if (ctx->eof_seen) { + return 0; + } + + return 1; +} + +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + *out_len = 0; + if (ctx->error_encountered || ctx->data_used != 0) { + return -1; + } + + return 1; +} + +int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (in_len % 4 != 0) { + return 0; + } + + size_t max_len; + if (!EVP_DecodedLength(&max_len, in_len) || + max_out < max_len) { + return 0; + } + + size_t i, bytes_out = 0; + for (i = 0; i < in_len; i += 4) { + size_t num_bytes_resulting; + + if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) { + return 0; + } + + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + if (num_bytes_resulting != 3 && i != in_len - 4) { + return 0; + } + } + + *out_len = bytes_out; + return 1; +} + +int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + // Trim spaces and tabs from the beginning of the input. + while (src_len > 0) { + if (src[0] != ' ' && src[0] != '\t') { + break; + } + + src++; + src_len--; + } + + // Trim newlines, spaces and tabs from the end of the line. + while (src_len > 0) { + switch (src[src_len-1]) { + case ' ': + case '\t': + case '\r': + case '\n': + src_len--; + continue; + } + + break; + } + + size_t dst_len; + if (!EVP_DecodedLength(&dst_len, src_len) || + dst_len > INT_MAX || + !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) { + return -1; + } + + // EVP_DecodeBlock does not take padding into account, so put the + // NULs back in... so the caller can strip them back out. + while (dst_len % 3 != 0) { + dst[dst_len++] = '\0'; + } + assert(dst_len <= INT_MAX); + + return (int)dst_len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio.c new file mode 100644 index 00000000..7c24ff32 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio.c @@ -0,0 +1,702 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" + + +BIO *BIO_new(const BIO_METHOD *method) { + BIO *ret = OPENSSL_malloc(sizeof(BIO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BIO)); + ret->method = method; + ret->shutdown = 1; + ret->references = 1; + + if (method->create != NULL && !method->create(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +int BIO_free(BIO *bio) { + BIO *next_bio; + + for (; bio != NULL; bio = next_bio) { + if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) { + return 0; + } + + next_bio = BIO_pop(bio); + + if (bio->method != NULL && bio->method->destroy != NULL) { + bio->method->destroy(bio); + } + + OPENSSL_free(bio); + } + return 1; +} + +int BIO_up_ref(BIO *bio) { + CRYPTO_refcount_inc(&bio->references); + return 1; +} + +void BIO_vfree(BIO *bio) { + BIO_free(bio); +} + +void BIO_free_all(BIO *bio) { + BIO_free(bio); +} + +int BIO_read(BIO *bio, void *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bread == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bread(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_gets(BIO *bio, char *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bgets == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bgets(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_write(BIO *bio, const void *in, int inl) { + if (bio == NULL || bio->method == NULL || bio->method->bwrite == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (inl <= 0) { + return 0; + } + int ret = bio->method->bwrite(bio, in, inl); + if (ret > 0) { + bio->num_write += ret; + } + return ret; +} + +int BIO_write_all(BIO *bio, const void *data, size_t len) { + const uint8_t *data_u8 = data; + while (len > 0) { + int ret = BIO_write(bio, data_u8, len > INT_MAX ? INT_MAX : (int)len); + if (ret <= 0) { + return 0; + } + data_u8 += ret; + len -= ret; + } + return 1; +} + +int BIO_puts(BIO *bio, const char *in) { + return BIO_write(bio, in, strlen(in)); +} + +int BIO_flush(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); +} + +long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + + return bio->method->ctrl(bio, cmd, larg, parg); +} + +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) { + char *p = NULL; + + if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) { + return NULL; + } + + return p; +} + +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { + int i = iarg; + + return BIO_ctrl(b, cmd, larg, (void *)&i); +} + +int BIO_reset(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); +} + +int BIO_eof(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); +} + +void BIO_set_flags(BIO *bio, int flags) { + bio->flags |= flags; +} + +int BIO_test_flags(const BIO *bio, int flags) { + return bio->flags & flags; +} + +int BIO_should_read(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_READ); +} + +int BIO_should_write(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_WRITE); +} + +int BIO_should_retry(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY); +} + +int BIO_should_io_special(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL); +} + +int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; } + +void BIO_set_retry_reason(BIO *bio, int reason) { bio->retry_reason = reason; } + +void BIO_clear_flags(BIO *bio, int flags) { + bio->flags &= ~flags; +} + +void BIO_set_retry_read(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY; +} + +void BIO_set_retry_write(BIO *bio) { + bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY; +} + +static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY; + +int BIO_get_retry_flags(BIO *bio) { + return bio->flags & kRetryFlags; +} + +void BIO_clear_retry_flags(BIO *bio) { + bio->flags &= ~kRetryFlags; + bio->retry_reason = 0; +} + +int BIO_method_type(const BIO *bio) { return bio->method->type; } + +void BIO_copy_next_retry(BIO *bio) { + BIO_clear_retry_flags(bio); + BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio)); + bio->retry_reason = bio->next_bio->retry_reason; +} + +long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->callback_ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + return bio->method->callback_ctrl(bio, cmd, fp); +} + +size_t BIO_pending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +size_t BIO_ctrl_pending(const BIO *bio) { + return BIO_pending(bio); +} + +size_t BIO_wpending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +int BIO_set_close(BIO *bio, int close_flag) { + return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); +} + +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { + return bio->num_read; +} + +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) { + return bio->num_write; +} + +BIO *BIO_push(BIO *bio, BIO *appended_bio) { + BIO *last_bio; + + if (bio == NULL) { + return bio; + } + + last_bio = bio; + while (last_bio->next_bio != NULL) { + last_bio = last_bio->next_bio; + } + + last_bio->next_bio = appended_bio; + return bio; +} + +BIO *BIO_pop(BIO *bio) { + BIO *ret; + + if (bio == NULL) { + return NULL; + } + ret = bio->next_bio; + bio->next_bio = NULL; + return ret; +} + +BIO *BIO_next(BIO *bio) { + if (!bio) { + return NULL; + } + return bio->next_bio; +} + +BIO *BIO_find_type(BIO *bio, int type) { + int method_type, mask; + + if (!bio) { + return NULL; + } + mask = type & 0xff; + + do { + if (bio->method != NULL) { + method_type = bio->method->type; + + if (!mask) { + if (method_type & type) { + return bio; + } + } else if (method_type == type) { + return bio; + } + } + bio = bio->next_bio; + } while (bio != NULL); + + return NULL; +} + +int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) { + if (indent > max_indent) { + indent = max_indent; + } + + while (indent--) { + if (BIO_puts(bio, " ") != 1) { + return 0; + } + } + return 1; +} + +static int print_bio(const char *str, size_t len, void *bio) { + return BIO_write((BIO *)bio, str, len); +} + +void ERR_print_errors(BIO *bio) { + ERR_print_errors_cb(print_bio, bio); +} + +// bio_read_all reads everything from |bio| and prepends |prefix| to it. On +// success, |*out| is set to an allocated buffer (which should be freed with +// |OPENSSL_free|), |*out_len| is set to its length and one is returned. The +// buffer will contain |prefix| followed by the contents of |bio|. On failure, +// zero is returned. +// +// The function will fail if the size of the output would equal or exceed +// |max_len|. +static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, + const uint8_t *prefix, size_t prefix_len, + size_t max_len) { + static const size_t kChunkSize = 4096; + + size_t len = prefix_len + kChunkSize; + if (len > max_len) { + len = max_len; + } + if (len < prefix_len) { + return 0; + } + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, prefix, prefix_len); + size_t done = prefix_len; + + for (;;) { + if (done == len) { + OPENSSL_free(*out); + return 0; + } + const size_t todo = len - done; + assert(todo < INT_MAX); + const int n = BIO_read(bio, *out + done, todo); + if (n == 0) { + *out_len = done; + return 1; + } else if (n == -1) { + OPENSSL_free(*out); + return 0; + } + + done += n; + if (len < max_len && len - done < kChunkSize / 2) { + len += kChunkSize; + if (len < kChunkSize || len > max_len) { + len = max_len; + } + uint8_t *new_buf = OPENSSL_realloc(*out, len); + if (new_buf == NULL) { + OPENSSL_free(*out); + return 0; + } + *out = new_buf; + } + } +} + +// bio_read_full reads |len| bytes |bio| and writes them into |out|. It +// tolerates partial reads from |bio| and returns one on success or zero if a +// read fails before |len| bytes are read. On failure, it additionally sets +// |*out_eof_on_first_read| to whether the error was due to |bio| returning zero +// on the first read. |out_eof_on_first_read| may be NULL to discard the value. +static int bio_read_full(BIO *bio, uint8_t *out, int *out_eof_on_first_read, + size_t len) { + int first_read = 1; + while (len > 0) { + int todo = len <= INT_MAX ? (int)len : INT_MAX; + int ret = BIO_read(bio, out, todo); + if (ret <= 0) { + if (out_eof_on_first_read != NULL) { + *out_eof_on_first_read = first_read && ret == 0; + } + return 0; + } + out += ret; + len -= (size_t)ret; + first_read = 0; + } + + return 1; +} + +// For compatibility with existing |d2i_*_bio| callers, |BIO_read_asn1| uses +// |ERR_LIB_ASN1| errors. +OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_DECODE_ERROR) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_HEADER_TOO_LONG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_NOT_ENOUGH_DATA) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_TOO_LONG) + +int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { + uint8_t header[6]; + + static const size_t kInitialHeaderLen = 2; + int eof_on_first_read; + if (!bio_read_full(bio, header, &eof_on_first_read, kInitialHeaderLen)) { + if (eof_on_first_read) { + // Historically, OpenSSL returned |ASN1_R_HEADER_TOO_LONG| when + // |d2i_*_bio| could not read anything. CPython conditions on this to + // determine if |bio| was empty. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + } + return 0; + } + + const uint8_t tag = header[0]; + const uint8_t length_byte = header[1]; + + if ((tag & 0x1f) == 0x1f) { + // Long form tags are not supported. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + size_t len, header_len; + if ((length_byte & 0x80) == 0) { + // Short form length. + len = length_byte; + header_len = kInitialHeaderLen; + } else { + const size_t num_bytes = length_byte & 0x7f; + + if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) { + // indefinite length. + if (!bio_read_all(bio, out, out_len, header, kInitialHeaderLen, + max_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + return 0; + } + return 1; + } + + if (num_bytes == 0 || num_bytes > 4) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + if (!bio_read_full(bio, header + kInitialHeaderLen, NULL, num_bytes)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + return 0; + } + header_len = kInitialHeaderLen + num_bytes; + + uint32_t len32 = 0; + for (unsigned i = 0; i < num_bytes; i++) { + len32 <<= 8; + len32 |= header[kInitialHeaderLen + i]; + } + + if (len32 < 128) { + // Length should have used short-form encoding. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + len = len32; + } + + if (len + header_len < len || + len + header_len > max_len || + len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return 0; + } + len += header_len; + *out_len = len; + + *out = OPENSSL_malloc(len); + if (*out == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_memcpy(*out, header, header_len); + if (!bio_read_full(bio, (*out) + header_len, NULL, len - header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + OPENSSL_free(*out); + return 0; + } + + return 1; +} + +void BIO_set_retry_special(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL; +} + +int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; } + +static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT; +static int g_index = BIO_TYPE_START; + +int BIO_get_new_index(void) { + CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock); + // If |g_index| exceeds 255, it will collide with the flags bits. + int ret = g_index > 255 ? -1 : g_index++; + CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock); + return ret; +} + +BIO_METHOD *BIO_meth_new(int type, const char *name) { + BIO_METHOD *method = OPENSSL_malloc(sizeof(BIO_METHOD)); + if (method == NULL) { + return NULL; + } + OPENSSL_memset(method, 0, sizeof(BIO_METHOD)); + method->type = type; + method->name = name; + return method; +} + +void BIO_meth_free(BIO_METHOD *method) { + OPENSSL_free(method); +} + +int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)) { + method->create = create; + return 1; +} + +int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)) { + method->destroy = destroy; + return 1; +} + +int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)) { + method->bwrite = write; + return 1; +} + +int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)) { + method->bread = read; + return 1; +} + +int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)) { + method->bgets = gets; + return 1; +} + +int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)) { + method->ctrl = ctrl; + return 1; +} + +void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; } + +void *BIO_get_data(BIO *bio) { return bio->ptr; } + +void BIO_set_init(BIO *bio, int init) { bio->init = init; } + +int BIO_get_init(BIO *bio) { return bio->init; } + +void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; } + +int BIO_get_shutdown(BIO *bio) { return bio->shutdown; } + +int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) { + // Ignore the parameter. We implement |BIO_puts| using |BIO_write|. + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c new file mode 100644 index 00000000..f03985d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/bio_mem.c @@ -0,0 +1,324 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "../internal.h" + + +BIO *BIO_new_mem_buf(const void *buf, int len) { + BIO *ret; + BUF_MEM *b; + const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len; + + if (!buf && len != 0) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER); + return NULL; + } + + ret = BIO_new(BIO_s_mem()); + if (ret == NULL) { + return NULL; + } + + b = (BUF_MEM *)ret->ptr; + // BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. + b->data = (void *)buf; + b->length = size; + b->max = size; + + ret->flags |= BIO_FLAGS_MEM_RDONLY; + + // |num| is used to store the value that this BIO will return when it runs + // out of data. If it's negative then the retry flags will also be set. Since + // this is static data, retrying wont help + ret->num = 0; + + return ret; +} + +static int mem_new(BIO *bio) { + BUF_MEM *b; + + b = BUF_MEM_new(); + if (b == NULL) { + return 0; + } + + // |shutdown| is used to store the close flag: whether the BIO has ownership + // of the BUF_MEM. + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + bio->ptr = (char *)b; + + return 1; +} + +static int mem_free(BIO *bio) { + if (!bio->shutdown || !bio->init || bio->ptr == NULL) { + return 1; + } + + BUF_MEM *b = (BUF_MEM *)bio->ptr; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data = NULL; + } + BUF_MEM_free(b); + bio->ptr = NULL; + return 1; +} + +static int mem_read(BIO *bio, char *out, int outl) { + int ret; + BUF_MEM *b = (BUF_MEM*) bio->ptr; + + BIO_clear_retry_flags(bio); + ret = outl; + if (b->length < INT_MAX && ret > (int)b->length) { + ret = b->length; + } + + if (ret > 0) { + OPENSSL_memcpy(out, b->data, ret); + b->length -= ret; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data += ret; + } else { + OPENSSL_memmove(b->data, &b->data[ret], b->length); + } + } else if (b->length == 0) { + ret = bio->num; + if (ret != 0) { + BIO_set_retry_read(bio); + } + } + return ret; +} + +static int mem_write(BIO *bio, const char *in, int inl) { + int ret = -1; + int blen; + BUF_MEM *b; + + b = (BUF_MEM *)bio->ptr; + + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); + goto err; + } + + BIO_clear_retry_flags(bio); + blen = b->length; + if (INT_MAX - blen < inl) { + goto err; + } + if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) { + goto err; + } + OPENSSL_memcpy(&b->data[blen], in, inl); + ret = inl; + +err: + return ret; +} + +static int mem_gets(BIO *bio, char *buf, int size) { + int i, j; + char *p; + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + BIO_clear_retry_flags(bio); + j = b->length; + if (size - 1 < j) { + j = size - 1; + } + if (j <= 0) { + if (size > 0) { + *buf = 0; + } + return 0; + } + + p = b->data; + for (i = 0; i < j; i++) { + if (p[i] == '\n') { + i++; + break; + } + } + + // i is now the max num of bytes to copy, either j or up to and including the + // first newline + + i = mem_read(bio, buf, i); + if (i > 0) { + buf[i] = '\0'; + } + return i; +} + +static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { + long ret = 1; + char **pptr; + + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->data != NULL) { + // For read only case reset to the start again + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data -= b->max - b->length; + b->length = b->max; + } else { + OPENSSL_memset(b->data, 0, b->max); + b->length = 0; + } + } + break; + case BIO_CTRL_EOF: + ret = (long)(b->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + bio->num = (int)num; + break; + case BIO_CTRL_INFO: + ret = (long)b->length; + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)&b->data[0]; + } + break; + case BIO_C_SET_BUF_MEM: + mem_free(bio); + bio->shutdown = (int)num; + bio->ptr = ptr; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)b; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)b->length; + break; + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD mem_method = { + BIO_TYPE_MEM, "memory buffer", + mem_write, mem_read, + NULL /* puts */, mem_gets, + mem_ctrl, mem_new, + mem_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_mem(void) { return &mem_method; } + +int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, + size_t *out_len) { + const BUF_MEM *b; + if (bio->method != &mem_method) { + return 0; + } + + b = (BUF_MEM *)bio->ptr; + *out_contents = (uint8_t *)b->data; + *out_len = b->length; + return 1; +} + +long BIO_get_mem_data(BIO *bio, char **contents) { + return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents); +} + +int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { + return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); +} + +int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); +} + +int BIO_set_mem_eof_return(BIO *bio, int eof_value) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/connect.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/connect.c new file mode 100644 index 00000000..72b5dad2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/connect.c @@ -0,0 +1,541 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#if !defined(OPENSSL_TRUSTY) + +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include + +#include "internal.h" +#include "../internal.h" + + +enum { + BIO_CONN_S_BEFORE, + BIO_CONN_S_BLOCKED_CONNECT, + BIO_CONN_S_OK, +}; + +typedef struct bio_connect_st { + int state; + + char *param_hostname; + char *param_port; + int nbio; + + unsigned short port; + + struct sockaddr_storage them; + socklen_t them_length; + + // the file descriptor is kept in bio->num in order to match the socket + // BIO. + + // info_callback is called when the connection is initially made + // callback(BIO,state,ret); The callback should return 'ret', state is for + // compatibility with the SSL info_callback. + int (*info_callback)(const BIO *bio, int state, int ret); +} BIO_CONNECT; + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +// split_host_and_port sets |*out_host| and |*out_port| to the host and port +// parsed from |name|. It returns one on success or zero on error. Even when +// successful, |*out_port| may be NULL on return if no port was specified. +static int split_host_and_port(char **out_host, char **out_port, const char *name) { + const char *host, *port = NULL; + size_t host_len = 0; + + *out_host = NULL; + *out_port = NULL; + + if (name[0] == '[') { // bracketed IPv6 address + const char *close = strchr(name, ']'); + if (close == NULL) { + return 0; + } + host = name + 1; + host_len = close - host; + if (close[1] == ':') { // [IP]:port + port = close + 2; + } else if (close[1] != 0) { + return 0; + } + } else { + const char *colon = strchr(name, ':'); + if (colon == NULL || strchr(colon + 1, ':') != NULL) { // IPv6 address + host = name; + host_len = strlen(name); + } else { // host:port + host = name; + host_len = colon - name; + port = colon + 1; + } + } + + *out_host = OPENSSL_strndup(host, host_len); + if (*out_host == NULL) { + return 0; + } + if (port == NULL) { + *out_port = NULL; + return 1; + } + *out_port = OPENSSL_strdup(port); + if (*out_port == NULL) { + OPENSSL_free(*out_host); + *out_host = NULL; + return 0; + } + return 1; +} + +static int conn_state(BIO *bio, BIO_CONNECT *c) { + int ret = -1, i; + int (*cb)(const BIO *, int, int) = NULL; + + if (c->info_callback != NULL) { + cb = c->info_callback; + } + + for (;;) { + switch (c->state) { + case BIO_CONN_S_BEFORE: + // If there's a hostname and a port, assume that both are + // exactly what they say. If there is only a hostname, try + // (just once) to split it into a hostname and port. + + if (c->param_hostname == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + + if (c->param_port == NULL) { + char *host, *port; + if (!split_host_and_port(&host, &port, c->param_hostname) || + port == NULL) { + OPENSSL_free(host); + OPENSSL_free(port); + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED); + ERR_add_error_data(2, "host=", c->param_hostname); + goto exit_loop; + } + + OPENSSL_free(c->param_port); + c->param_port = port; + OPENSSL_free(c->param_hostname); + c->param_hostname = host; + } + + if (!bio_ip_and_port_to_socket_and_addr( + &bio->num, &c->them, &c->them_length, c->param_hostname, + c->param_port)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + if (c->nbio) { + if (!bio_socket_nbio(bio->num, 1)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + goto exit_loop; + } + } + + i = 1; + ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (ret < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + BIO_clear_retry_flags(bio); + ret = connect(bio->num, (struct sockaddr*) &c->them, c->them_length); + if (ret < 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + } else { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = bio_sock_error(bio->num); + if (i) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + ret = -1; + } else { + BIO_clear_retry_flags(bio); + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + ret = 0; + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + assert(0); + goto exit_loop; + } + + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + if (ret == 0) { + goto end; + } + } + } + +exit_loop: + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + } + +end: + return ret; +} + +static BIO_CONNECT *BIO_CONNECT_new(void) { + BIO_CONNECT *ret = OPENSSL_malloc(sizeof(BIO_CONNECT)); + + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BIO_CONNECT)); + + ret->state = BIO_CONN_S_BEFORE; + return ret; +} + +static void BIO_CONNECT_free(BIO_CONNECT *c) { + if (c == NULL) { + return; + } + + OPENSSL_free(c->param_hostname); + OPENSSL_free(c->param_port); + OPENSSL_free(c); +} + +static int conn_new(BIO *bio) { + bio->init = 0; + bio->num = -1; + bio->flags = 0; + bio->ptr = BIO_CONNECT_new(); + return bio->ptr != NULL; +} + +static void conn_close_socket(BIO *bio) { + BIO_CONNECT *c = (BIO_CONNECT *) bio->ptr; + + if (bio->num == -1) { + return; + } + + // Only do a shutdown if things were established + if (c->state == BIO_CONN_S_OK) { + shutdown(bio->num, 2); + } + closesocket(bio->num); + bio->num = -1; +} + +static int conn_free(BIO *bio) { + if (bio->shutdown) { + conn_close_socket(bio); + } + + BIO_CONNECT_free((BIO_CONNECT*) bio->ptr); + + return 1; +} + +static int conn_read(BIO *bio, char *out, int out_len) { + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = recv(bio->num, out, out_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(bio); + } + } + + return ret; +} + +static int conn_write(BIO *bio, const char *in, int in_len) { + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = send(bio->num, in, in_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_write(bio); + } + } + + return ret; +} + +static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) { + int *ip; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(bio); + bio->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + // use this one to start the connection + if (data->state != BIO_CONN_S_OK) { + ret = (long)conn_state(bio, data); + } else { + ret = 1; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + bio->init = 1; + if (num == 0) { + OPENSSL_free(data->param_hostname); + data->param_hostname = OPENSSL_strdup(ptr); + if (data->param_hostname == NULL) { + ret = 0; + } + } else if (num == 1) { + OPENSSL_free(data->param_port); + data->param_port = OPENSSL_strdup(ptr); + if (data->param_port == NULL) { + ret = 0; + } + } else { + ret = 0; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (bio->init) { + ip = (int *)ptr; + if (ip != NULL) { + *ip = bio->num; + } + ret = bio->num; + } else { + ret = -1; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_CTRL_GET_CALLBACK: { + int (**fptr)(const BIO *bio, int state, int xret); + fptr = (int (**)(const BIO *bio, int state, int xret))ptr; + *fptr = data->info_callback; + } break; + default: + ret = 0; + break; + } + return ret; +} + +static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + data->info_callback = (int (*)(const struct bio_st *, int, int))fp; + break; + default: + ret = 0; + break; + } + return ret; +} + +BIO *BIO_new_connect(const char *hostname) { + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) { + return NULL; + } + if (!BIO_set_conn_hostname(ret, hostname)) { + BIO_free(ret); + return NULL; + } + return ret; +} + +static const BIO_METHOD methods_connectp = { + BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read, + NULL /* puts */, NULL /* gets */, conn_ctrl, conn_new, + conn_free, conn_callback_ctrl, +}; + +const BIO_METHOD *BIO_s_connect(void) { return &methods_connectp; } + +int BIO_set_conn_hostname(BIO *bio, const char *name) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); +} + +int BIO_set_conn_port(BIO *bio, const char *port_str) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); +} + +int BIO_set_conn_int_port(BIO *bio, const int *port) { + char buf[DECIMAL_SIZE(int) + 1]; + BIO_snprintf(buf, sizeof(buf), "%d", *port); + return BIO_set_conn_port(bio, buf); +} + +int BIO_set_nbio(BIO *bio, int on) { + return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); +} + +int BIO_do_connect(BIO *bio) { + return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/fd.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/fd.c new file mode 100644 index 00000000..cf111766 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/fd.c @@ -0,0 +1,275 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#if !defined(OPENSSL_TRUSTY) + +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#else +#include +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int bio_fd_non_fatal_error(int err) { + if ( +#ifdef EWOULDBLOCK + err == EWOULDBLOCK || +#endif +#ifdef WSAEWOULDBLOCK + err == WSAEWOULDBLOCK || +#endif +#ifdef ENOTCONN + err == ENOTCONN || +#endif +#ifdef EINTR + err == EINTR || +#endif +#ifdef EAGAIN + err == EAGAIN || +#endif +#ifdef EPROTO + err == EPROTO || +#endif +#ifdef EINPROGRESS + err == EINPROGRESS || +#endif +#ifdef EALREADY + err == EALREADY || +#endif + 0) { + return 1; + } + return 0; +} + +#if defined(OPENSSL_WINDOWS) + #define BORINGSSL_ERRNO (int)GetLastError() + #define BORINGSSL_CLOSE _close + #define BORINGSSL_LSEEK _lseek + #define BORINGSSL_READ _read + #define BORINGSSL_WRITE _write +#else + #define BORINGSSL_ERRNO errno + #define BORINGSSL_CLOSE close + #define BORINGSSL_LSEEK lseek + #define BORINGSSL_READ read + #define BORINGSSL_WRITE write +#endif + +int bio_fd_should_retry(int i) { + if (i == -1) { + return bio_fd_non_fatal_error(BORINGSSL_ERRNO); + } + return 0; +} + +BIO *BIO_new_fd(int fd, int close_flag) { + BIO *ret = BIO_new(BIO_s_fd()); + if (ret == NULL) { + return NULL; + } + BIO_set_fd(ret, fd, close_flag); + return ret; +} + +static int fd_new(BIO *bio) { + // num is used to store the file descriptor. + bio->num = -1; + return 1; +} + +static int fd_free(BIO *bio) { + if (bio->shutdown) { + if (bio->init) { + BORINGSSL_CLOSE(bio->num); + } + bio->init = 0; + } + return 1; +} + +static int fd_read(BIO *b, char *out, int outl) { + int ret = 0; + + ret = BORINGSSL_READ(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(b); + } + } + + return ret; +} + +static int fd_write(BIO *b, const char *in, int inl) { + int ret = BORINGSSL_WRITE(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_write(b); + } + } + + return ret; +} + +static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) { + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET); + } + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR); + } + break; + case BIO_C_SET_FD: + fd_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) { + *ip = b->num; + } + return b->num; + } else { + ret = -1; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static int fd_gets(BIO *bp, char *buf, int size) { + char *ptr = buf; + char *end = buf + size - 1; + + if (size <= 0) { + return 0; + } + + while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') { + ptr++; + } + + ptr[0] = '\0'; + + return ptr - buf; +} + +static const BIO_METHOD methods_fdp = { + BIO_TYPE_FD, "file descriptor", fd_write, fd_read, NULL /* puts */, + fd_gets, fd_ctrl, fd_new, fd_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; } + +int BIO_set_fd(BIO *bio, int fd, int close_flag) { + return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); +} + +int BIO_get_fd(BIO *bio, int *out_fd) { + return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/file.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/file.c new file mode 100644 index 00000000..1f20f680 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/file.c @@ -0,0 +1,317 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#if defined(__linux) || defined(__sun) || defined(__hpux) +// Following definition aliases fopen to fopen64 on above mentioned +// platforms. This makes it possible to open and sequentially access +// files larger than 2GB from 32-bit application. It does not allow to +// traverse them beyond 2GB with fseek/ftell, but on the other hand *no* +// 32-bit platform permits that, not with fseek/ftell. Not to mention +// that breaking 2GB limit for seeking would require surgery to *our* +// API. But sequential access suffices for practical cases when you +// can run into large files, such as fingerprinting, so we can let API +// alone. For reference, the list of 32-bit platforms which allow for +// sequential access of large files without extra "magic" comprise *BSD, +// Darwin, IRIX... +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#endif + +#include + +#if !defined(OPENSSL_TRUSTY) + +#include +#include +#include + +#include +#include + +#include "../internal.h" + + +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 + +BIO *BIO_new_file(const char *filename, const char *mode) { + BIO *ret; + FILE *file; + + file = fopen(filename, mode); + if (file == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + + ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + if (errno == ENOENT) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE); + } else { + OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB); + } + return NULL; + } + + ret = BIO_new_fp(file, BIO_CLOSE); + if (ret == NULL) { + fclose(file); + return NULL; + } + + return ret; +} + +BIO *BIO_new_fp(FILE *stream, int close_flag) { + BIO *ret = BIO_new(BIO_s_file()); + + if (ret == NULL) { + return NULL; + } + + BIO_set_fp(ret, stream, close_flag); + return ret; +} + +static int file_free(BIO *bio) { + if (!bio->shutdown) { + return 1; + } + + if (bio->init && bio->ptr != NULL) { + fclose(bio->ptr); + bio->ptr = NULL; + } + bio->init = 0; + + return 1; +} + +static int file_read(BIO *b, char *out, int outl) { + if (!b->init) { + return 0; + } + + size_t ret = fread(out, 1, outl, (FILE *)b->ptr); + if (ret == 0 && ferror((FILE *)b->ptr)) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + return -1; + } + + // fread reads at most |outl| bytes, so |ret| fits in an int. + return (int)ret; +} + +static int file_write(BIO *b, const char *in, int inl) { + int ret = 0; + + if (!b->init) { + return 0; + } + + ret = fwrite(in, inl, 1, (FILE *)b->ptr); + if (ret > 0) { + ret = inl; + } + return ret; +} + +static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = ftell(fp); + break; + case BIO_C_SET_FILE_PTR: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + b->ptr = ptr; + b->init = 1; + break; + case BIO_C_SET_FILENAME: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + if (num & BIO_FP_APPEND) { + if (num & BIO_FP_READ) { + OPENSSL_strlcpy(p, "a+", sizeof(p)); + } else { + OPENSSL_strlcpy(p, "a", sizeof(p)); + } + } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) { + OPENSSL_strlcpy(p, "r+", sizeof(p)); + } else if (num & BIO_FP_WRITE) { + OPENSSL_strlcpy(p, "w", sizeof(p)); + } else if (num & BIO_FP_READ) { + OPENSSL_strlcpy(p, "r", sizeof(p)); + } else { + OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } + fp = fopen(ptr, p); + if (fp == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + break; + case BIO_C_GET_FILE_PTR: + // the ptr parameter is actually a FILE ** in this case. + if (ptr != NULL) { + fpp = (FILE **)ptr; + *fpp = (FILE *)b->ptr; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_FLUSH: + ret = 0 == fflush((FILE *)b->ptr); + break; + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + default: + ret = 0; + break; + } + return ret; +} + +static int file_gets(BIO *bp, char *buf, int size) { + int ret = 0; + + if (size == 0) { + return 0; + } + + if (!fgets(buf, size, (FILE *)bp->ptr)) { + buf[0] = 0; + goto err; + } + ret = strlen(buf); + +err: + return ret; +} + +static const BIO_METHOD methods_filep = { + BIO_TYPE_FILE, "FILE pointer", + file_write, file_read, + NULL /* puts */, file_gets, + file_ctrl, NULL /* create */, + file_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_file(void) { return &methods_filep; } + + +int BIO_get_fp(BIO *bio, FILE **out_file) { + return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file); +} + +int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { + return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file); +} + +int BIO_read_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, + (char *)filename); +} + +int BIO_write_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, + (char *)filename); +} + +int BIO_append_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, + (char *)filename); +} + +int BIO_rw_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); +} + +long BIO_tell(BIO *bio) { return BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL); } + +long BIO_seek(BIO *bio, long offset) { + return BIO_ctrl(bio, BIO_C_FILE_SEEK, offset, NULL); +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/hexdump.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/hexdump.c new file mode 100644 index 00000000..f42c95c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/hexdump.c @@ -0,0 +1,192 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "../internal.h" + + +// hexdump_ctx contains the state of a hexdump. +struct hexdump_ctx { + BIO *bio; + char right_chars[18]; // the contents of the right-hand side, ASCII dump. + unsigned used; // number of bytes in the current line. + size_t n; // number of bytes total. + unsigned indent; +}; + +static void hexbyte(char *out, uint8_t b) { + static const char hextable[] = "0123456789abcdef"; + out[0] = hextable[b>>4]; + out[1] = hextable[b&0x0f]; +} + +static char to_char(uint8_t b) { + if (b < 32 || b > 126) { + return '.'; + } + return b; +} + +// hexdump_write adds |len| bytes of |data| to the current hex dump described by +// |ctx|. +static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data, + size_t len) { + char buf[10]; + unsigned l; + + // Output lines look like: + // 00000010 2e 2f 30 31 32 33 34 35 36 37 38 ... 3c 3d // |./0123456789:;<=| + // ^ offset ^ extra space ^ ASCII of line + + for (size_t i = 0; i < len; i++) { + if (ctx->used == 0) { + // The beginning of a line. + BIO_indent(ctx->bio, ctx->indent, UINT_MAX); + + hexbyte(&buf[0], ctx->n >> 24); + hexbyte(&buf[2], ctx->n >> 16); + hexbyte(&buf[4], ctx->n >> 8); + hexbyte(&buf[6], ctx->n); + buf[8] = buf[9] = ' '; + if (BIO_write(ctx->bio, buf, 10) < 0) { + return 0; + } + } + + hexbyte(buf, data[i]); + buf[2] = ' '; + l = 3; + if (ctx->used == 7) { + // There's an additional space after the 8th byte. + buf[3] = ' '; + l = 4; + } else if (ctx->used == 15) { + // At the end of the line there's an extra space and the bar for the + // right column. + buf[3] = ' '; + buf[4] = '|'; + l = 5; + } + + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + ctx->right_chars[ctx->used] = to_char(data[i]); + ctx->used++; + ctx->n++; + if (ctx->used == 16) { + ctx->right_chars[16] = '|'; + ctx->right_chars[17] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, sizeof(ctx->right_chars)) < 0) { + return 0; + } + ctx->used = 0; + } + } + + return 1; +} + +// finish flushes any buffered data in |ctx|. +static int finish(struct hexdump_ctx *ctx) { + // See the comments in |hexdump| for the details of this format. + const unsigned n_bytes = ctx->used; + unsigned l; + char buf[5]; + + if (n_bytes == 0) { + return 1; + } + + OPENSSL_memset(buf, ' ', 4); + buf[4] = '|'; + + for (; ctx->used < 16; ctx->used++) { + l = 3; + if (ctx->used == 7) { + l = 4; + } else if (ctx->used == 15) { + l = 5; + } + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + } + + ctx->right_chars[n_bytes] = '|'; + ctx->right_chars[n_bytes + 1] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, n_bytes + 2) < 0) { + return 0; + } + return 1; +} + +int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) { + struct hexdump_ctx ctx; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + ctx.bio = bio; + ctx.indent = indent; + + if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) { + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/internal.h new file mode 100644 index 00000000..00e59724 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/internal.h @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_BIO_INTERNAL_H +#define OPENSSL_HEADER_BIO_INTERNAL_H + +#include + +#if !defined(OPENSSL_WINDOWS) +#if defined(OPENSSL_PNACL) +// newlib uses u_short in socket.h without defining it. +typedef unsigned short u_short; +#endif +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +typedef int socklen_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO_ip_and_port_to_socket_and_addr creates a socket and fills in |*out_addr| +// and |*out_addr_length| with the correct values for connecting to |hostname| +// on |port_str|. It returns one on success or zero on error. +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str); + +// BIO_socket_nbio sets whether |sock| is non-blocking. It returns one on +// success and zero otherwise. +int bio_socket_nbio(int sock, int on); + +// BIO_clear_socket_error clears the last system socket error. +// +// TODO(fork): remove all callers of this. +void bio_clear_socket_error(void); + +// BIO_sock_error returns the last socket error on |sock|. +int bio_sock_error(int sock); + +// BIO_fd_should_retry returns non-zero if |return_value| indicates an error +// and |errno| indicates that it's non-fatal. +int bio_fd_should_retry(int return_value); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BIO_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/pair.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/pair.c new file mode 100644 index 00000000..3dabfc28 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/pair.c @@ -0,0 +1,483 @@ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" + + +struct bio_bio_st { + BIO *peer; // NULL if buf == NULL. + // If peer != NULL, then peer->ptr is also a bio_bio_st, + // and its "peer" member points back to us. + // peer != NULL iff init != 0 in the BIO. + + // This is for what we write (i.e. reading uses peer's struct): + int closed; // valid iff peer != NULL + size_t len; // valid iff buf != NULL; 0 if peer == NULL + size_t offset; // valid iff buf != NULL; 0 if len == 0 + size_t size; + uint8_t *buf; // "size" elements (if != NULL) + + size_t request; // valid iff peer != NULL; 0 if len != 0, + // otherwise set by peer to number of bytes + // it (unsuccessfully) tried to read, + // never more than buffer space (size-len) warrants. +}; + +static int bio_new(BIO *bio) { + struct bio_bio_st *b; + + b = OPENSSL_malloc(sizeof *b); + if (b == NULL) { + return 0; + } + OPENSSL_memset(b, 0, sizeof(struct bio_bio_st)); + + b->size = 17 * 1024; // enough for one TLS record (just a default) + bio->ptr = b; + return 1; +} + +static void bio_destroy_pair(BIO *bio) { + struct bio_bio_st *b = bio->ptr; + BIO *peer_bio; + struct bio_bio_st *peer_b; + + if (b == NULL) { + return; + } + + peer_bio = b->peer; + if (peer_bio == NULL) { + return; + } + + peer_b = peer_bio->ptr; + + assert(peer_b != NULL); + assert(peer_b->peer == bio); + + peer_b->peer = NULL; + peer_bio->init = 0; + assert(peer_b->buf != NULL); + peer_b->len = 0; + peer_b->offset = 0; + + b->peer = NULL; + bio->init = 0; + assert(b->buf != NULL); + b->len = 0; + b->offset = 0; +} + +static int bio_free(BIO *bio) { + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + if (b->peer) { + bio_destroy_pair(bio); + } + + OPENSSL_free(b->buf); + OPENSSL_free(b); + + return 1; +} + +static int bio_read(BIO *bio, char *buf, int size_) { + size_t size = size_; + size_t rest; + struct bio_bio_st *b, *peer_b; + + BIO_clear_retry_flags(bio); + + if (!bio->init) { + return 0; + } + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; // will be set in "retry_read" situation + + if (buf == NULL || size == 0) { + return 0; + } + + if (peer_b->len == 0) { + if (peer_b->closed) { + return 0; // writer has closed, and no data is left + } else { + BIO_set_retry_read(bio); // buffer is empty + if (size <= peer_b->size) { + peer_b->request = size; + } else { + // don't ask for more than the peer can + // deliver in one write + peer_b->request = peer_b->size; + } + return -1; + } + } + + // we can read + if (peer_b->len < size) { + size = peer_b->len; + } + + // now read "size" bytes + rest = size; + + assert(rest > 0); + // one or two iterations + do { + size_t chunk; + + assert(rest <= peer_b->len); + if (peer_b->offset + rest <= peer_b->size) { + chunk = rest; + } else { + // wrap around ring buffer + chunk = peer_b->size - peer_b->offset; + } + assert(peer_b->offset + chunk <= peer_b->size); + + OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk); + + peer_b->len -= chunk; + if (peer_b->len) { + peer_b->offset += chunk; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) { + peer_b->offset = 0; + } + buf += chunk; + } else { + // buffer now empty, no need to advance "buf" + assert(chunk == rest); + peer_b->offset = 0; + } + rest -= chunk; + } while (rest); + + return size; +} + +static int bio_write(BIO *bio, const char *buf, int num_) { + size_t num = num_; + size_t rest; + struct bio_bio_st *b; + + BIO_clear_retry_flags(bio); + + if (!bio->init || buf == NULL || num == 0) { + return 0; + } + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + // we already closed + OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); // buffer is full + return -1; + } + + // we can write + if (num > b->size - b->len) { + num = b->size - b->len; + } + + // now write "num" bytes + rest = num; + + assert(rest > 0); + // one or two iterations + do { + size_t write_offset; + size_t chunk; + + assert(b->len + rest <= b->size); + + write_offset = b->offset + b->len; + if (write_offset >= b->size) { + write_offset -= b->size; + } + // b->buf[write_offset] is the first byte we can write to. + + if (write_offset + rest <= b->size) { + chunk = rest; + } else { + // wrap around ring buffer + chunk = b->size - write_offset; + } + + OPENSSL_memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } while (rest); + + return num; +} + +static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, + size_t writebuf2_len) { + struct bio_bio_st *b1, *b2; + + assert(bio1 != NULL); + assert(bio2 != NULL); + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (b1->peer != NULL || b2->peer != NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + if (writebuf1_len) { + b1->size = writebuf1_len; + } + b1->buf = OPENSSL_malloc(b1->size); + if (b1->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + if (writebuf2_len) { + b2->size = writebuf2_len; + } + b2->buf = OPENSSL_malloc(b2->size); + if (b2->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + b2->len = 0; + b2->offset = 0; + } + + b1->peer = bio2; + b1->closed = 0; + b1->request = 0; + b2->peer = bio1; + b2->closed = 0; + b2->request = 0; + + bio1->init = 1; + bio2->init = 1; + + return 1; +} + +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) { + long ret; + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + switch (cmd) { + // specific CTRL codes + + case BIO_C_GET_WRITE_BUF_SIZE: + ret = (long)b->size; + break; + + case BIO_C_GET_WRITE_GUARANTEE: + // How many bytes can the caller feed to the next write + // without having to keep any? + if (b->peer == NULL || b->closed) { + ret = 0; + } else { + ret = (long)b->size - b->len; + } + break; + + case BIO_C_GET_READ_REQUEST: + // If the peer unsuccessfully tried to read, how many bytes + // were requested? (As with BIO_CTRL_PENDING, that number + // can usually be treated as boolean.) + ret = (long)b->request; + break; + + case BIO_C_RESET_READ_REQUEST: + // Reset request. (Can be useful after read attempts + // at the other side that are meant to be non-blocking, + // e.g. when probing SSL_read to see if any data is + // available.) + b->request = 0; + ret = 1; + break; + + case BIO_C_SHUTDOWN_WR: + // similar to shutdown(..., SHUT_WR) + b->closed = 1; + ret = 1; + break; + + // standard CTRL codes follow + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + ret = 1; + break; + + case BIO_CTRL_PENDING: + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; + ret = (long)peer_b->len; + } else { + ret = 0; + } + break; + + case BIO_CTRL_WPENDING: + ret = 0; + if (b->buf != NULL) { + ret = (long)b->len; + } + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: { + BIO *other_bio = ptr; + + if (other_bio) { + struct bio_bio_st *other_b = other_bio->ptr; + assert(other_b != NULL); + ret = other_b->len == 0 && other_b->closed; + } else { + ret = 1; + } + } break; + + default: + ret = 0; + } + return ret; +} + + +static const BIO_METHOD methods_biop = { + BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */, + NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */, +}; + +static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; } + +int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len, + BIO** bio2_p, size_t writebuf2_len) { + BIO *bio1 = BIO_new(bio_s_bio()); + BIO *bio2 = BIO_new(bio_s_bio()); + if (bio1 == NULL || bio2 == NULL || + !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) { + BIO_free(bio1); + BIO_free(bio2); + *bio1_p = NULL; + *bio2_p = NULL; + return 0; + } + + *bio1_p = bio1; + *bio2_p = bio2; + return 1; +} + +size_t BIO_ctrl_get_read_request(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} + +size_t BIO_ctrl_get_write_guarantee(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} + +int BIO_shutdown_wr(BIO *bio) { + return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/printf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/printf.c new file mode 100644 index 00000000..1c118186 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/printf.c @@ -0,0 +1,103 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include + +int BIO_printf(BIO *bio, const char *format, ...) { + va_list args; + char buf[256], *out, out_malloced = 0; + int out_len, ret; + + va_start(args, format); + out_len = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + if (out_len < 0) { + return -1; + } + + if ((size_t) out_len >= sizeof(buf)) { + const int requested_len = out_len; + // The output was truncated. Note that vsnprintf's return value + // does not include a trailing NUL, but the buffer must be sized + // for it. + out = OPENSSL_malloc(requested_len + 1); + out_malloced = 1; + if (out == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + va_start(args, format); + out_len = vsnprintf(out, requested_len + 1, format, args); + va_end(args); + assert(out_len == requested_len); + } else { + out = buf; + } + + ret = BIO_write(bio, out, out_len); + if (out_malloced) { + OPENSSL_free(out); + } + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket.c new file mode 100644 index 00000000..f65b3b53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket.c @@ -0,0 +1,192 @@ +/* crypto/bio/bss_sock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#if !defined(OPENSSL_TRUSTY) + +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib")) +#endif + +#include "internal.h" + + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +static int sock_free(BIO *bio) { + if (bio->shutdown) { + if (bio->init) { + closesocket(bio->num); + } + bio->init = 0; + bio->flags = 0; + } + return 1; +} + +static int sock_read(BIO *b, char *out, int outl) { + if (out == NULL) { + return 0; + } + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + int ret = recv(b->num, out, outl, 0); +#else + int ret = read(b->num, out, outl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(b); + } + } + return ret; +} + +static int sock_write(BIO *b, const char *in, int inl) { + int ret; + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + ret = send(b->num, in, inl, 0); +#else + ret = write(b->num, in, inl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_write(b); + } + } + return ret; +} + +static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) { + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_C_SET_FD: + sock_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) { + *ip = b->num; + } + ret = b->num; + } else { + ret = -1; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD methods_sockp = { + BIO_TYPE_SOCKET, "socket", + sock_write, sock_read, + NULL /* puts */, NULL /* gets, */, + sock_ctrl, NULL /* create */, + sock_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_socket(void) { return &methods_sockp; } + +BIO *BIO_new_socket(int fd, int close_flag) { + BIO *ret; + + ret = BIO_new(BIO_s_socket()); + if (ret == NULL) { + return NULL; + } + BIO_set_fd(ret, fd, close_flag); + return ret; +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket_helper.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket_helper.c new file mode 100644 index 00000000..a892690c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bio/socket_helper.c @@ -0,0 +1,122 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L + +#include +#include + +#if !defined(OPENSSL_TRUSTY) + +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" +#include "../internal.h" + + +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str) { + struct addrinfo hint, *result, *cur; + int ret; + + *out_sock = -1; + + OPENSSL_memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo(hostname, port_str, &hint, &result); + if (ret != 0) { + OPENSSL_PUT_ERROR(SYS, 0); +#if defined(OPENSSL_WINDOWS) + ERR_add_error_data(1, gai_strerrorA(ret)); +#else + ERR_add_error_data(1, gai_strerror(ret)); +#endif + return 0; + } + + ret = 0; + + for (cur = result; cur; cur = cur->ai_next) { + if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) { + continue; + } + OPENSSL_memset(out_addr, 0, sizeof(struct sockaddr_storage)); + OPENSSL_memcpy(out_addr, cur->ai_addr, cur->ai_addrlen); + *out_addr_length = cur->ai_addrlen; + + *out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (*out_sock < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + goto out; + } + + ret = 1; + break; + } + +out: + freeaddrinfo(result); + return ret; +} + +int bio_socket_nbio(int sock, int on) { +#if defined(OPENSSL_WINDOWS) + u_long arg = on; + + return 0 == ioctlsocket(sock, FIONBIO, &arg); +#else + int flags = fcntl(sock, F_GETFL, 0); + if (flags < 0) { + return 0; + } + if (!on) { + flags &= ~O_NONBLOCK; + } else { + flags |= O_NONBLOCK; + } + return fcntl(sock, F_SETFL, flags) == 0; +#endif +} + +void bio_clear_socket_error(void) {} + +int bio_sock_error(int sock) { + int error; + socklen_t error_size = sizeof(error); + + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &error_size) < 0) { + return 1; + } + return error; +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/blake2/blake2.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/blake2/blake2.c new file mode 100644 index 00000000..87dba54b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/blake2/blake2.c @@ -0,0 +1,156 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "../internal.h" + +// https://tools.ietf.org/html/rfc7693#section-2.6 +static const uint64_t kIV[8] = { + UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), + UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), + UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), + UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179), +}; + +// https://tools.ietf.org/html/rfc7693#section-2.7 +static const uint8_t kSigma[10 * 16] = { + // clang-format off + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + // clang-format on +}; + +// https://tools.ietf.org/html/rfc7693#section-3.1 +static void blake2b_mix(uint64_t v[16], int a, int b, int c, int d, uint64_t x, + uint64_t y) { + v[a] = v[a] + v[b] + x; + v[d] = CRYPTO_rotr_u64(v[d] ^ v[a], 32); + v[c] = v[c] + v[d]; + v[b] = CRYPTO_rotr_u64(v[b] ^ v[c], 24); + v[a] = v[a] + v[b] + y; + v[d] = CRYPTO_rotr_u64(v[d] ^ v[a], 16); + v[c] = v[c] + v[d]; + v[b] = CRYPTO_rotr_u64(v[b] ^ v[c], 63); +} + +static void blake2b_transform( + BLAKE2B_CTX *b2b, + const uint64_t block_words[BLAKE2B_CBLOCK / sizeof(uint64_t)], + size_t num_bytes, int is_final_block) { + // https://tools.ietf.org/html/rfc7693#section-3.2 + uint64_t v[16]; + OPENSSL_STATIC_ASSERT(sizeof(v) == sizeof(b2b->h) + sizeof(kIV), ""); + OPENSSL_memcpy(v, b2b->h, sizeof(b2b->h)); + OPENSSL_memcpy(&v[8], kIV, sizeof(kIV)); + + b2b->t_low += num_bytes; + if (b2b->t_low < num_bytes) { + b2b->t_high++; + } + v[12] ^= b2b->t_low; + v[13] ^= b2b->t_high; + + if (is_final_block) { + v[14] = ~v[14]; + } + + for (int round = 0; round < 12; round++) { + const uint8_t *const s = &kSigma[16 * (round % 10)]; + blake2b_mix(v, 0, 4, 8, 12, block_words[s[0]], block_words[s[1]]); + blake2b_mix(v, 1, 5, 9, 13, block_words[s[2]], block_words[s[3]]); + blake2b_mix(v, 2, 6, 10, 14, block_words[s[4]], block_words[s[5]]); + blake2b_mix(v, 3, 7, 11, 15, block_words[s[6]], block_words[s[7]]); + blake2b_mix(v, 0, 5, 10, 15, block_words[s[8]], block_words[s[9]]); + blake2b_mix(v, 1, 6, 11, 12, block_words[s[10]], block_words[s[11]]); + blake2b_mix(v, 2, 7, 8, 13, block_words[s[12]], block_words[s[13]]); + blake2b_mix(v, 3, 4, 9, 14, block_words[s[14]], block_words[s[15]]); + } + + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(b2b->h); i++) { + b2b->h[i] ^= v[i]; + b2b->h[i] ^= v[i + 8]; + } +} + +void BLAKE2B256_Init(BLAKE2B_CTX *b2b) { + OPENSSL_memset(b2b, 0, sizeof(BLAKE2B_CTX)); + + OPENSSL_STATIC_ASSERT(sizeof(kIV) == sizeof(b2b->h), ""); + OPENSSL_memcpy(&b2b->h, kIV, sizeof(kIV)); + + // https://tools.ietf.org/html/rfc7693#section-2.5 + b2b->h[0] ^= 0x01010000 | BLAKE2B256_DIGEST_LENGTH; +} + +void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) { + const uint8_t *data = (const uint8_t *)in_data; + + size_t todo = sizeof(b2b->block.bytes) - b2b->block_used; + if (todo > len) { + todo = len; + } + OPENSSL_memcpy(&b2b->block.bytes[b2b->block_used], data, todo); + b2b->block_used += todo; + data += todo; + len -= todo; + + if (!len) { + return; + } + + // More input remains therefore we must have filled |b2b->block|. + assert(b2b->block_used == BLAKE2B_CBLOCK); + blake2b_transform(b2b, b2b->block.words, BLAKE2B_CBLOCK, + /*is_final_block=*/0); + b2b->block_used = 0; + + while (len > BLAKE2B_CBLOCK) { + uint64_t block_words[BLAKE2B_CBLOCK / sizeof(uint64_t)]; + OPENSSL_memcpy(block_words, data, sizeof(block_words)); + blake2b_transform(b2b, block_words, BLAKE2B_CBLOCK, /*is_final_block=*/0); + data += BLAKE2B_CBLOCK; + len -= BLAKE2B_CBLOCK; + } + + OPENSSL_memcpy(b2b->block.bytes, data, len); + b2b->block_used = len; +} + +void BLAKE2B256_Final(uint8_t out[BLAKE2B256_DIGEST_LENGTH], BLAKE2B_CTX *b2b) { + OPENSSL_memset(&b2b->block.bytes[b2b->block_used], 0, + sizeof(b2b->block.bytes) - b2b->block_used); + blake2b_transform(b2b, b2b->block.words, b2b->block_used, + /*is_final_block=*/1); + OPENSSL_STATIC_ASSERT(BLAKE2B256_DIGEST_LENGTH <= sizeof(b2b->h), ""); + memcpy(out, b2b->h, BLAKE2B256_DIGEST_LENGTH); +} + +void BLAKE2B256(const uint8_t *data, size_t len, + uint8_t out[BLAKE2B256_DIGEST_LENGTH]) { + BLAKE2B_CTX ctx; + BLAKE2B256_Init(&ctx); + BLAKE2B256_Update(&ctx, data, len); + BLAKE2B256_Final(out, &ctx); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/bn_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/bn_asn1.c new file mode 100644 index 00000000..6a095aaa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/bn_asn1.c @@ -0,0 +1,57 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + + +int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) { + CBS child; + int is_negative; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) || + !CBS_is_valid_asn1_integer(&child, &is_negative)) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return 0; + } + + if (is_negative) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL; +} + +int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) { + // Negative numbers are unsupported. + if (BN_is_negative(bn)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) || + // The number must be padded with a leading zero if the high bit would + // otherwise be set or if |bn| is zero. + (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) || + !BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c new file mode 100644 index 00000000..49667c61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bn_extra/convert.c @@ -0,0 +1,470 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" + + +int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) { + uint8_t *ptr; + return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in); +} + +static const char hextable[] = "0123456789abcdef"; + +char *BN_bn2hex(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ + + width * BN_BYTES * 2 + 1 /* trailing NUL */); + if (buf == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + char *p = buf; + if (bn->neg) { + *(p++) = '-'; + } + + if (BN_is_zero(bn)) { + *(p++) = '0'; + } + + int z = 0; + for (int i = width - 1; i >= 0; i--) { + for (int j = BN_BITS2 - 8; j >= 0; j -= 8) { + // strip leading zeros + int v = ((int)(bn->d[i] >> (long)j)) & 0xff; + if (z || v != 0) { + *(p++) = hextable[v >> 4]; + *(p++) = hextable[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + + return buf; +} + +// decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. +static int decode_hex(BIGNUM *bn, const char *in, int in_len) { + if (in_len > INT_MAX/4) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + // |in_len| is the number of hex digits. + if (!bn_expand(bn, in_len * 4)) { + return 0; + } + + int i = 0; + while (in_len > 0) { + // Decode one |BN_ULONG| at a time. + int todo = BN_BYTES * 2; + if (todo > in_len) { + todo = in_len; + } + + BN_ULONG word = 0; + int j; + for (j = todo; j > 0; j--) { + char c = in[in_len - j]; + + BN_ULONG hex; + if (c >= '0' && c <= '9') { + hex = c - '0'; + } else if (c >= 'a' && c <= 'f') { + hex = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + hex = c - 'A' + 10; + } else { + hex = 0; + // This shouldn't happen. The caller checks |isxdigit|. + assert(0); + } + word = (word << 4) | hex; + } + + bn->d[i++] = word; + in_len -= todo; + } + assert(i <= bn->dmax); + bn->width = i; + return 1; +} + +// decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. +static int decode_dec(BIGNUM *bn, const char *in, int in_len) { + int i, j; + BN_ULONG l = 0; + + // Decode |BN_DEC_NUM| digits at a time. + j = BN_DEC_NUM - (in_len % BN_DEC_NUM); + if (j == BN_DEC_NUM) { + j = 0; + } + l = 0; + for (i = 0; i < in_len; i++) { + l *= 10; + l += in[i] - '0'; + if (++j == BN_DEC_NUM) { + if (!BN_mul_word(bn, BN_DEC_CONV) || + !BN_add_word(bn, l)) { + return 0; + } + l = 0; + j = 0; + } + } + return 1; +} + +typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len); +typedef int (*char_test_func) (int c); + +static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) { + BIGNUM *ret = NULL; + int neg = 0, i; + int num; + + if (in == NULL || *in == 0) { + return 0; + } + + if (*in == '-') { + neg = 1; + in++; + } + + for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {} + + num = i + neg; + if (outp == NULL) { + return num; + } + + // in is the start of the hex digits, and it is 'i' long + if (*outp == NULL) { + ret = BN_new(); + if (ret == NULL) { + return 0; + } + } else { + ret = *outp; + BN_zero(ret); + } + + if (!decode(ret, in, i)) { + goto err; + } + + bn_set_minimal_width(ret); + if (!BN_is_zero(ret)) { + ret->neg = neg; + } + + *outp = ret; + return num; + +err: + if (*outp == NULL) { + BN_free(ret); + } + + return 0; +} + +int BN_hex2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_hex, isxdigit); +} + +char *BN_bn2dec(const BIGNUM *a) { + // It is easier to print strings little-endian, so we assemble it in reverse + // and fix at the end. + BIGNUM *copy = NULL; + CBB cbb; + if (!CBB_init(&cbb, 16) || + !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { + goto cbb_err; + } + + if (BN_is_zero(a)) { + if (!CBB_add_u8(&cbb, '0')) { + goto cbb_err; + } + } else { + copy = BN_dup(a); + if (copy == NULL) { + goto err; + } + + while (!BN_is_zero(copy)) { + BN_ULONG word = BN_div_word(copy, BN_DEC_CONV); + if (word == (BN_ULONG)-1) { + goto err; + } + + const int add_leading_zeros = !BN_is_zero(copy); + for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { + if (!CBB_add_u8(&cbb, '0' + word % 10)) { + goto cbb_err; + } + word /= 10; + } + assert(word == 0); + } + } + + if (BN_is_negative(a) && + !CBB_add_u8(&cbb, '-')) { + goto cbb_err; + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&cbb, &data, &len)) { + goto cbb_err; + } + + // Reverse the buffer. + for (size_t i = 0; i < len/2; i++) { + uint8_t tmp = data[i]; + data[i] = data[len - 1 - i]; + data[len - 1 - i] = tmp; + } + + BN_free(copy); + return (char *)data; + +cbb_err: + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); +err: + BN_free(copy); + CBB_cleanup(&cbb); + return NULL; +} + +int BN_dec2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_dec, isdigit); +} + +int BN_asc2bn(BIGNUM **outp, const char *in) { + const char *const orig_in = in; + if (*in == '-') { + in++; + } + + if (in[0] == '0' && (in[1] == 'X' || in[1] == 'x')) { + if (!BN_hex2bn(outp, in+2)) { + return 0; + } + } else { + if (!BN_dec2bn(outp, in)) { + return 0; + } + } + + if (*orig_in == '-' && !BN_is_zero(*outp)) { + (*outp)->neg = 1; + } + + return 1; +} + +int BN_print(BIO *bp, const BIGNUM *a) { + int i, j, v, z = 0; + int ret = 0; + + if (a->neg && BIO_write(bp, "-", 1) != 1) { + goto end; + } + + if (BN_is_zero(a) && BIO_write(bp, "0", 1) != 1) { + goto end; + } + + for (i = bn_minimal_width(a) - 1; i >= 0; i--) { + for (j = BN_BITS2 - 4; j >= 0; j -= 4) { + // strip leading zeros + v = ((int)(a->d[i] >> (long)j)) & 0x0f; + if (z || v != 0) { + if (BIO_write(bp, &hextable[v], 1) != 1) { + goto end; + } + z = 1; + } + } + } + ret = 1; + +end: + return ret; +} + +int BN_print_fp(FILE *fp, const BIGNUM *a) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + return 0; + } + + int ret = BN_print(b, a); + BIO_free(b); + return ret; +} + + +size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) { + const size_t bits = BN_num_bits(in); + const size_t bytes = (bits + 7) / 8; + // If the number of bits is a multiple of 8, i.e. if the MSB is set, + // prefix with a zero byte. + int extend = 0; + if (bytes != 0 && (bits & 0x07) == 0) { + extend = 1; + } + + const size_t len = bytes + extend; + if (len < bytes || + 4 + len < len || + (len & 0xffffffff) != len) { + // If we cannot represent the number then we emit zero as the interface + // doesn't allow an error to be signalled. + if (out) { + OPENSSL_memset(out, 0, 4); + } + return 4; + } + + if (out == NULL) { + return 4 + len; + } + + out[0] = len >> 24; + out[1] = len >> 16; + out[2] = len >> 8; + out[3] = len; + if (extend) { + out[4] = 0; + } + BN_bn2bin(in, out + 4 + extend); + if (in->neg && len > 0) { + out[4] |= 0x80; + } + return len + 4; +} + +BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) { + if (len < 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + const size_t in_len = ((size_t)in[0] << 24) | + ((size_t)in[1] << 16) | + ((size_t)in[2] << 8) | + ((size_t)in[3]); + if (in_len != len - 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + + int out_is_alloced = 0; + if (out == NULL) { + out = BN_new(); + if (out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out_is_alloced = 1; + } + + if (in_len == 0) { + BN_zero(out); + return out; + } + + in += 4; + if (BN_bin2bn(in, in_len, out) == NULL) { + if (out_is_alloced) { + BN_free(out); + } + return NULL; + } + out->neg = ((*in) & 0x80) != 0; + if (out->neg) { + BN_clear_bit(out, BN_num_bits(out) - 1); + } + return out; +} + +int BN_bn2binpad(const BIGNUM *in, uint8_t *out, int len) { + if (len < 0 || + !BN_bn2bin_padded(out, (size_t)len, in)) { + return -1; + } + return len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/buf/buf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/buf/buf.c new file mode 100644 index 00000000..28ee7455 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/buf/buf.c @@ -0,0 +1,172 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include + +#include "../internal.h" + + +BUF_MEM *BUF_MEM_new(void) { + BUF_MEM *ret; + + ret = OPENSSL_malloc(sizeof(BUF_MEM)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BUF_MEM)); + return ret; +} + +void BUF_MEM_free(BUF_MEM *buf) { + if (buf == NULL) { + return; + } + + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) { + if (buf->max >= cap) { + return 1; + } + + size_t n = cap + 3; + if (n < cap) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + n = n / 3; + size_t alloc_size = n * 4; + if (alloc_size / 4 != n) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + char *new_buf = OPENSSL_realloc(buf->data, alloc_size); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + buf->data = new_buf; + buf->max = alloc_size; + return 1; +} + +size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) { + if (!BUF_MEM_reserve(buf, len)) { + return 0; + } + if (buf->length < len) { + OPENSSL_memset(&buf->data[buf->length], 0, len - buf->length); + } + buf->length = len; + return len; +} + +size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) { + return BUF_MEM_grow(buf, len); +} + +int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) { + // Work around a C language bug. See https://crbug.com/1019588. + if (len == 0) { + return 1; + } + size_t new_len = buf->length + len; + if (new_len < len) { + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); + return 0; + } + if (!BUF_MEM_reserve(buf, new_len)) { + return 0; + } + OPENSSL_memcpy(buf->data + buf->length, in, len); + buf->length = new_len; + return 1; +} + +char *BUF_strdup(const char *str) { return OPENSSL_strdup(str); } + +size_t BUF_strnlen(const char *str, size_t max_len) { + return OPENSSL_strnlen(str, max_len); +} + +char *BUF_strndup(const char *str, size_t size) { + return OPENSSL_strndup(str, size); +} + +size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size) { + return OPENSSL_strlcpy(dst, src, dst_size); +} + +size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) { + return OPENSSL_strlcat(dst, src, dst_size); +} + +void *BUF_memdup(const void *data, size_t size) { + return OPENSSL_memdup(data, size); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/asn1_compat.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/asn1_compat.c new file mode 100644 index 00000000..1073ac38 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/asn1_compat.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { + assert(cbb->base->can_resize); + + uint8_t *der; + size_t der_len; + if (!CBB_finish(cbb, &der, &der_len)) { + CBB_cleanup(cbb); + return -1; + } + if (der_len > INT_MAX) { + OPENSSL_free(der); + return -1; + } + if (outp != NULL) { + if (*outp == NULL) { + *outp = der; + der = NULL; + } else { + OPENSSL_memcpy(*outp, der, der_len); + *outp += der_len; + } + } + OPENSSL_free(der); + return (int)der_len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/ber.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/ber.c new file mode 100644 index 00000000..2033b5f8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/ber.c @@ -0,0 +1,266 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// kMaxDepth is a just a sanity limit. The code should be such that the length +// of the input being processes always decreases. None the less, a very large +// input could otherwise cause the stack to overflow. +static const unsigned kMaxDepth = 2048; + +// is_string_type returns one if |tag| is a string type and zero otherwise. It +// ignores the constructed bit. +static int is_string_type(unsigned tag) { + // While BER supports constructed BIT STRINGS, OpenSSL misparses them. To + // avoid acting on an ambiguous input, we do not support constructed BIT + // STRINGS. See https://github.com/openssl/openssl/issues/12810. + switch (tag & ~CBS_ASN1_CONSTRUCTED) { + case CBS_ASN1_OCTETSTRING: + case CBS_ASN1_UTF8STRING: + case CBS_ASN1_NUMERICSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_VIDEOTEXSTRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_GRAPHICSTRING: + case CBS_ASN1_VISIBLESTRING: + case CBS_ASN1_GENERALSTRING: + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_BMPSTRING: + return 1; + default: + return 0; + } +} + +// cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| +// depending on whether an indefinite length element or constructed string was +// found. The value of |orig_in| is not changed. It returns one on success (i.e. +// |*ber_found| was set) and zero on error. +static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) { + CBS in; + + if (depth > kMaxDepth) { + return 0; + } + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + *ber_found = 0; + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned tag; + size_t header_len; + int indefinite; + if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len, + ber_found, &indefinite)) { + return 0; + } + if (*ber_found) { + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (is_string_type(tag)) { + // Constructed strings are only legal in BER and require conversion. + *ber_found = 1; + return 1; + } + if (!CBS_skip(&contents, header_len) || + !cbs_find_ber(&contents, ber_found, depth + 1)) { + return 0; + } + } + } + + return 1; +} + +// cbs_get_eoc returns one if |cbs| begins with an "end of contents" (EOC) value +// and zero otherwise. If an EOC was found, it advances |cbs| past it. +static int cbs_get_eoc(CBS *cbs) { + if (CBS_len(cbs) >= 2 && + CBS_data(cbs)[0] == 0 && CBS_data(cbs)[1] == 0) { + return CBS_skip(cbs, 2); + } + return 0; +} + +// cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If +// |string_tag| is non-zero, then all elements must match |string_tag| up to the +// constructed bit and primitive element bodies are written to |out| without +// element headers. This is used when concatenating the fragments of a +// constructed string. If |looking_for_eoc| is set then any EOC elements found +// will cause the function to return after consuming it. It returns one on +// success and zero on error. +static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, + char looking_for_eoc, unsigned depth) { + assert(!(string_tag & CBS_ASN1_CONSTRUCTED)); + + if (depth > kMaxDepth) { + return 0; + } + + while (CBS_len(in) > 0) { + if (looking_for_eoc && cbs_get_eoc(in)) { + return 1; + } + + CBS contents; + unsigned tag, child_string_tag = string_tag; + size_t header_len; + int indefinite; + CBB *out_contents, out_contents_storage; + if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len, + /*out_ber_found=*/NULL, &indefinite)) { + return 0; + } + + if (string_tag != 0) { + // This is part of a constructed string. All elements must match + // |string_tag| up to the constructed bit and get appended to |out| + // without a child element. + if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) { + return 0; + } + out_contents = out; + } else { + unsigned out_tag = tag; + if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) { + // If a constructed string, clear the constructed bit and inform + // children to concatenate bodies. + out_tag &= ~CBS_ASN1_CONSTRUCTED; + child_string_tag = out_tag; + } + if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) { + return 0; + } + out_contents = &out_contents_storage; + } + + if (indefinite) { + if (!cbs_convert_ber(in, out_contents, child_string_tag, + /*looking_for_eoc=*/1, depth + 1) || + !CBB_flush(out)) { + return 0; + } + continue; + } + + if (!CBS_skip(&contents, header_len)) { + return 0; + } + + if (tag & CBS_ASN1_CONSTRUCTED) { + // Recurse into children. + if (!cbs_convert_ber(&contents, out_contents, child_string_tag, + /*looking_for_eoc=*/0, depth + 1)) { + return 0; + } + } else { + // Copy primitive contents as-is. + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) { + return 0; + } + } + + if (!CBB_flush(out)) { + return 0; + } + } + + return looking_for_eoc == 0; +} + +int CBS_asn1_ber_to_der(CBS *in, CBS *out, uint8_t **out_storage) { + CBB cbb; + + // First, do a quick walk to find any indefinite-length elements. Most of the + // time we hope that there aren't any and thus we can quickly return. + int conversion_needed; + if (!cbs_find_ber(in, &conversion_needed, 0)) { + return 0; + } + + if (!conversion_needed) { + if (!CBS_get_any_asn1_element(in, out, NULL, NULL)) { + return 0; + } + *out_storage = NULL; + return 1; + } + + size_t len; + if (!CBB_init(&cbb, CBS_len(in)) || + !cbs_convert_ber(in, &cbb, 0, 0, 0) || + !CBB_finish(&cbb, out_storage, &len)) { + CBB_cleanup(&cbb); + return 0; + } + + CBS_init(out, *out_storage, len); + return 1; +} + +int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, + unsigned outer_tag, unsigned inner_tag) { + assert(!(outer_tag & CBS_ASN1_CONSTRUCTED)); + assert(!(inner_tag & CBS_ASN1_CONSTRUCTED)); + assert(is_string_type(inner_tag)); + + if (CBS_peek_asn1_tag(in, outer_tag)) { + // Normal implicitly-tagged string. + *out_storage = NULL; + return CBS_get_asn1(in, out, outer_tag); + } + + // Otherwise, try to parse an implicitly-tagged constructed string. + // |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep + // of nesting. + CBB result; + CBS child; + if (!CBB_init(&result, CBS_len(in)) || + !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) { + goto err; + } + + while (CBS_len(&child) > 0) { + CBS chunk; + if (!CBS_get_asn1(&child, &chunk, inner_tag) || + !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) { + goto err; + } + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&result, &data, &len)) { + goto err; + } + + CBS_init(out, data, len); + *out_storage = data; + return 1; + +err: + CBB_cleanup(&result); + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c new file mode 100644 index 00000000..c4e3792b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbb.c @@ -0,0 +1,728 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include + +#include "../internal.h" + + +void CBB_zero(CBB *cbb) { + OPENSSL_memset(cbb, 0, sizeof(CBB)); +} + +static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { + // This assumes that |cbb| has already been zeroed. + struct cbb_buffer_st *base; + + base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); + if (base == NULL) { + return 0; + } + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + base->error = 0; + + cbb->base = base; + cbb->is_child = 0; + return 1; +} + +int CBB_init(CBB *cbb, size_t initial_capacity) { + CBB_zero(cbb); + + uint8_t *buf = OPENSSL_malloc(initial_capacity); + if (initial_capacity > 0 && buf == NULL) { + return 0; + } + + if (!cbb_init(cbb, buf, initial_capacity)) { + OPENSSL_free(buf); + return 0; + } + + return 1; +} + +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { + CBB_zero(cbb); + + if (!cbb_init(cbb, buf, len)) { + return 0; + } + + cbb->base->can_resize = 0; + return 1; +} + +void CBB_cleanup(CBB *cbb) { + // Child |CBB|s are non-owning. They are implicitly discarded and should not + // be used with |CBB_cleanup| or |ScopedCBB|. + assert(!cbb->is_child); + if (cbb->is_child) { + return; + } + + if (cbb->base) { + if (cbb->base->can_resize) { + OPENSSL_free(cbb->base->buf); + } + OPENSSL_free(cbb->base); + } + cbb->base = NULL; +} + +static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + size_t newlen; + + if (base == NULL) { + return 0; + } + + newlen = base->len + len; + if (newlen < base->len) { + // Overflow + goto err; + } + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) { + goto err; + } + + if (newcap < base->cap || newcap < newlen) { + newcap = newlen; + } + newbuf = OPENSSL_realloc(base->buf, newcap); + if (newbuf == NULL) { + goto err; + } + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) { + *out = base->buf + base->len; + } + + return 1; + +err: + base->error = 1; + return 0; +} + +static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + if (!cbb_buffer_reserve(base, out, len)) { + return 0; + } + // This will not overflow or |cbb_buffer_reserve| would have failed. + base->len += len; + return 1; +} + +static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint64_t v, + size_t len_len) { + if (len_len == 0) { + return 1; + } + + uint8_t *buf; + if (!cbb_buffer_add(base, &buf, len_len)) { + return 0; + } + + for (size_t i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + + if (v != 0) { + base->error = 1; + return 0; + } + + return 1; +} + +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { + if (cbb->is_child) { + return 0; + } + + if (!CBB_flush(cbb)) { + return 0; + } + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { + // |out_data| and |out_len| can only be NULL if the CBB is fixed. + return 0; + } + + if (out_data != NULL) { + *out_data = cbb->base->buf; + } + if (out_len != NULL) { + *out_len = cbb->base->len; + } + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +// CBB_flush recurses and then writes out any pending length prefix. The +// current length of the underlying base is taken to be the length of the +// length-prefixed data. +int CBB_flush(CBB *cbb) { + size_t child_start, i, len; + + // If |cbb->base| has hit an error, the buffer is in an undefined state, so + // fail all following calls. In particular, |cbb->child| may point to invalid + // memory. + if (cbb->base == NULL || cbb->base->error) { + return 0; + } + + if (cbb->child == NULL || cbb->child->pending_len_len == 0) { + return 1; + } + + child_start = cbb->child->offset + cbb->child->pending_len_len; + + if (!CBB_flush(cbb->child) || + child_start < cbb->child->offset || + cbb->base->len < child_start) { + goto err; + } + + len = cbb->base->len - child_start; + + if (cbb->child->pending_is_asn1) { + // For ASN.1 we assume that we'll only need a single byte for the length. + // If that turned out to be incorrect, we have to move the contents along + // in order to make space. + uint8_t len_len; + uint8_t initial_length_byte; + + assert (cbb->child->pending_len_len == 1); + + if (len > 0xfffffffe) { + // Too large. + goto err; + } else if (len > 0xffffff) { + len_len = 5; + initial_length_byte = 0x80 | 4; + } else if (len > 0xffff) { + len_len = 4; + initial_length_byte = 0x80 | 3; + } else if (len > 0xff) { + len_len = 3; + initial_length_byte = 0x80 | 2; + } else if (len > 0x7f) { + len_len = 2; + initial_length_byte = 0x80 | 1; + } else { + len_len = 1; + initial_length_byte = (uint8_t)len; + len = 0; + } + + if (len_len != 1) { + // We need to move the contents along in order to make space. + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { + goto err; + } + OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->child->offset++] = initial_length_byte; + cbb->child->pending_len_len = len_len - 1; + } + + for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; + i--) { + cbb->base->buf[cbb->child->offset + i] = (uint8_t)len; + len >>= 8; + } + if (len != 0) { + goto err; + } + + cbb->child->base = NULL; + cbb->child = NULL; + + return 1; + +err: + cbb->base->error = 1; + return 0; +} + +const uint8_t *CBB_data(const CBB *cbb) { + assert(cbb->child == NULL); + return cbb->base->buf + cbb->offset + cbb->pending_len_len; +} + +size_t CBB_len(const CBB *cbb) { + assert(cbb->child == NULL); + assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); + + return cbb->base->len - cbb->offset - cbb->pending_len_len; +} + +static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, + uint8_t len_len) { + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { + return 0; + } + + OPENSSL_memset(prefix_bytes, 0, len_len); + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + out_contents->is_child = 1; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = len_len; + cbb->child->pending_is_asn1 = 0; + + return 1; +} + +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +// add_base128_integer encodes |v| as a big-endian base-128 integer where the +// high bit of each byte indicates where there is more data. This is the +// encoding used in DER for both high tag number form and OID components. +static int add_base128_integer(CBB *cbb, uint64_t v) { + unsigned len_len = 0; + uint64_t copy = v; + while (copy > 0) { + len_len++; + copy >>= 7; + } + if (len_len == 0) { + len_len = 1; // Zero is encoded with one byte. + } + for (unsigned i = len_len - 1; i < len_len; i--) { + uint8_t byte = (v >> (7 * i)) & 0x7f; + if (i != 0) { + // The high bit denotes whether there is more data. + byte |= 0x80; + } + if (!CBB_add_u8(cbb, byte)) { + return 0; + } + } + return 1; +} + +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { + if (!CBB_flush(cbb)) { + return 0; + } + + // Split the tag into leading bits and tag number. + uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0; + unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + if (tag_number >= 0x1f) { + // Set all the bits in the tag number to signal high tag number form. + if (!CBB_add_u8(cbb, tag_bits | 0x1f) || + !add_base128_integer(cbb, tag_number)) { + return 0; + } + } else if (!CBB_add_u8(cbb, tag_bits | tag_number)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) { + return 0; + } + + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + out_contents->is_child = 1; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = 1; + cbb->child->pending_is_asn1 = 1; + + return 1; +} + +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { + uint8_t *dest; + + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, &dest, len)) { + return 0; + } + OPENSSL_memcpy(dest, data, len); + return 1; +} + +int CBB_add_zeros(CBB *cbb, size_t len) { + uint8_t *out; + if (!CBB_add_space(cbb, &out, len)) { + return 0; + } + OPENSSL_memset(out, 0, len); + return 1; +} + +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_reserve(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_did_write(CBB *cbb, size_t len) { + size_t newlen = cbb->base->len + len; + if (cbb->child != NULL || + newlen < cbb->base->len || + newlen > cbb->base->cap) { + return 0; + } + cbb->base->len = newlen; + return 1; +} + +int CBB_add_u8(CBB *cbb, uint8_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 1); +} + +int CBB_add_u16(CBB *cbb, uint16_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 2); +} + +int CBB_add_u16le(CBB *cbb, uint16_t value) { + return CBB_add_u16(cbb, CRYPTO_bswap2(value)); +} + +int CBB_add_u24(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 3); +} + +int CBB_add_u32(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 4); +} + +int CBB_add_u32le(CBB *cbb, uint32_t value) { + return CBB_add_u32(cbb, CRYPTO_bswap4(value)); +} + +int CBB_add_u64(CBB *cbb, uint64_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + return cbb_buffer_add_u(cbb->base, value, 8); +} + +int CBB_add_u64le(CBB *cbb, uint64_t value) { + return CBB_add_u64(cbb, CRYPTO_bswap8(value)); +} + +void CBB_discard_child(CBB *cbb) { + if (cbb->child == NULL) { + return; + } + + cbb->base->len = cbb->child->offset; + + cbb->child->base = NULL; + cbb->child = NULL; +} + +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { + CBB child; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + return 0; + } + + for (size_t i = 0; i < 8; i++) { + uint8_t byte = (value >> 8*(7-i)) & 0xff; + if (!started) { + if (byte == 0) { + // Don't encode leading zeros. + continue; + } + // If the high bit is set, add a padding byte to make it + // unsigned. + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { + return 0; + } + started = 1; + } + if (!CBB_add_u8(&child, byte)) { + return 0; + } + } + + // 0 is encoded as a single 0, not the empty string. + if (!started && !CBB_add_u8(&child, 0)) { + return 0; + } + + return CBB_flush(cbb); +} + +int CBB_add_asn1_int64(CBB *cbb, int64_t value) { + if (value >= 0) { + return CBB_add_asn1_uint64(cbb, value); + } + + union { + int64_t i; + uint8_t bytes[sizeof(int64_t)]; + } u; + u.i = value; + int start = 7; + // Skip leading sign-extension bytes unless they are necessary. + while (start > 0 && (u.bytes[start] == 0xff && (u.bytes[start - 1] & 0x80))) { + start--; + } + + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + return 0; + } + for (int i = start; i >= 0; i--) { + if (!CBB_add_u8(&child, u.bytes[i])) { + return 0; + } + } + return CBB_flush(cbb); +} + +int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&child, data, data_len) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +int CBB_add_asn1_bool(CBB *cbb, int value) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) || + !CBB_add_u8(&child, value != 0 ? 0xff : 0) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +// parse_dotted_decimal parses one decimal component from |cbs|, where |cbs| is +// an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the +// component and the dot, so |cbs| may be passed into the function again for the +// next value. +static int parse_dotted_decimal(CBS *cbs, uint64_t *out) { + *out = 0; + int seen_digit = 0; + for (;;) { + // Valid terminators for a component are the end of the string or a + // non-terminal dot. If the string ends with a dot, this is not a valid OID + // string. + uint8_t u; + if (!CBS_get_u8(cbs, &u) || + (u == '.' && CBS_len(cbs) > 0)) { + break; + } + if (u < '0' || u > '9' || + // Forbid stray leading zeros. + (seen_digit && *out == 0) || + // Check for overflow. + *out > UINT64_MAX / 10 || + *out * 10 > UINT64_MAX - (u - '0')) { + return 0; + } + *out = *out * 10 + (u - '0'); + seen_digit = 1; + } + // The empty string is not a legal OID component. + return seen_digit; +} + +int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, (const uint8_t *)text, len); + + // OIDs must have at least two components. + uint64_t a, b; + if (!parse_dotted_decimal(&cbs, &a) || + !parse_dotted_decimal(&cbs, &b)) { + return 0; + } + + // The first component is encoded as 40 * |a| + |b|. This assumes that |a| is + // 0, 1, or 2 and that, when it is 0 or 1, |b| is at most 39. + if (a > 2 || + (a < 2 && b > 39) || + b > UINT64_MAX - 80 || + !add_base128_integer(cbb, 40u * a + b)) { + return 0; + } + + // The remaining components are encoded unmodified. + while (CBS_len(&cbs) > 0) { + if (!parse_dotted_decimal(&cbs, &a) || + !add_base128_integer(cbb, a)) { + return 0; + } + } + + return 1; +} + +static int compare_set_of_element(const void *a_ptr, const void *b_ptr) { + // See X.690, section 11.6 for the ordering. They are sorted in ascending + // order by their DER encoding. + const CBS *a = a_ptr, *b = b_ptr; + size_t a_len = CBS_len(a), b_len = CBS_len(b); + size_t min_len = a_len < b_len ? a_len : b_len; + int ret = OPENSSL_memcmp(CBS_data(a), CBS_data(b), min_len); + if (ret != 0) { + return ret; + } + if (a_len == b_len) { + return 0; + } + // If one is a prefix of the other, the shorter one sorts first. (This is not + // actually reachable. No DER encoding is a prefix of another DER encoding.) + return a_len < b_len ? -1 : 1; +} + +int CBB_flush_asn1_set_of(CBB *cbb) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + size_t num_children = 0; + CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb)); + while (CBS_len(&cbs) != 0) { + if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) { + return 0; + } + num_children++; + } + + if (num_children < 2) { + return 1; // Nothing to do. This is the common case for X.509. + } + if (num_children > ((size_t)-1) / sizeof(CBS)) { + return 0; // Overflow. + } + + // Parse out the children and sort. We alias them into a copy of so they + // remain valid as we rewrite |cbb|. + int ret = 0; + size_t buf_len = CBB_len(cbb); + uint8_t *buf = OPENSSL_memdup(CBB_data(cbb), buf_len); + CBS *children = OPENSSL_malloc(num_children * sizeof(CBS)); + if (buf == NULL || children == NULL) { + goto err; + } + CBS_init(&cbs, buf, buf_len); + for (size_t i = 0; i < num_children; i++) { + if (!CBS_get_any_asn1_element(&cbs, &children[i], NULL, NULL)) { + goto err; + } + } + qsort(children, num_children, sizeof(CBS), compare_set_of_element); + + // Rewind |cbb| and write the contents back in the new order. + cbb->base->len = cbb->offset + cbb->pending_len_len; + for (size_t i = 0; i < num_children; i++) { + if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) { + goto err; + } + } + assert(CBB_len(cbb) == buf_len); + + ret = 1; + +err: + OPENSSL_free(buf); + OPENSSL_free(children); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c new file mode 100644 index 00000000..dcc51cc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/cbs.c @@ -0,0 +1,725 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { + cbs->data = data; + cbs->len = len; +} + +static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) { + if (cbs->len < n) { + return 0; + } + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +int CBS_skip(CBS *cbs, size_t len) { + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t *CBS_data(const CBS *cbs) { + return cbs->data; +} + +size_t CBS_len(const CBS *cbs) { + return cbs->len; +} + +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) { + OPENSSL_free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) { + return 1; + } + *out_ptr = OPENSSL_memdup(cbs->data, cbs->len); + if (*out_ptr == NULL) { + return 0; + } + *out_len = cbs->len; + return 1; +} + +int CBS_strdup(const CBS *cbs, char **out_ptr) { + if (*out_ptr != NULL) { + OPENSSL_free(*out_ptr); + } + *out_ptr = OPENSSL_strndup((const char*)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int CBS_contains_zero_byte(const CBS *cbs) { + return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL; +} + +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) { + if (len != cbs->len) { + return 0; + } + return CRYPTO_memcmp(cbs->data, data, len) == 0; +} + +static int cbs_get_u(CBS *cbs, uint64_t *out, size_t len) { + uint64_t result = 0; + const uint8_t *data; + + if (!cbs_get(cbs, &data, len)) { + return 0; + } + for (size_t i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int CBS_get_u8(CBS *cbs, uint8_t *out) { + const uint8_t *v; + if (!cbs_get(cbs, &v, 1)) { + return 0; + } + *out = *v; + return 1; +} + +int CBS_get_u16(CBS *cbs, uint16_t *out) { + uint64_t v; + if (!cbs_get_u(cbs, &v, 2)) { + return 0; + } + *out = v; + return 1; +} + +int CBS_get_u16le(CBS *cbs, uint16_t *out) { + if (!CBS_get_u16(cbs, out)) { + return 0; + } + *out = CRYPTO_bswap2(*out); + return 1; +} + +int CBS_get_u24(CBS *cbs, uint32_t *out) { + uint64_t v; + if (!cbs_get_u(cbs, &v, 3)) { + return 0; + } + *out = v; + return 1; +} + +int CBS_get_u32(CBS *cbs, uint32_t *out) { + uint64_t v; + if (!cbs_get_u(cbs, &v, 4)) { + return 0; + } + *out = v; + return 1; +} + +int CBS_get_u32le(CBS *cbs, uint32_t *out) { + if (!CBS_get_u32(cbs, out)) { + return 0; + } + *out = CRYPTO_bswap4(*out); + return 1; +} + +int CBS_get_u64(CBS *cbs, uint64_t *out) { + return cbs_get_u(cbs, out, 8); +} + +int CBS_get_u64le(CBS *cbs, uint64_t *out) { + if (!cbs_get_u(cbs, out, 8)) { + return 0; + } + *out = CRYPTO_bswap8(*out); + return 1; +} + +int CBS_get_last_u8(CBS *cbs, uint8_t *out) { + if (cbs->len == 0) { + return 0; + } + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + CBS_init(out, v, len); + return 1; +} + +int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + OPENSSL_memcpy(out, v, len); + return 1; +} + +static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) { + uint64_t len; + if (!cbs_get_u(cbs, &len, len_len)) { + return 0; + } + // If |len_len| <= 3 then we know that |len| will fit into a |size_t|, even on + // 32-bit systems. + assert(len_len <= 3); + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 1); +} + +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 2); +} + +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 3); +} + +int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) { + const uint8_t *split = OPENSSL_memchr(CBS_data(cbs), c, CBS_len(cbs)); + if (split == NULL) { + return 0; + } + return CBS_get_bytes(cbs, out, split - CBS_data(cbs)); +} + +// parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets +// |*out| to the result. This is the encoding used in DER for both high tag +// number form and OID components. +static int parse_base128_integer(CBS *cbs, uint64_t *out) { + uint64_t v = 0; + uint8_t b; + do { + if (!CBS_get_u8(cbs, &b)) { + return 0; + } + if ((v >> (64 - 7)) != 0) { + // The value is too large. + return 0; + } + if (v == 0 && b == 0x80) { + // The value must be minimally encoded. + return 0; + } + v = (v << 7) | (b & 0x7f); + + // Values end at an octet with the high bit cleared. + } while (b & 0x80); + + *out = v; + return 1; +} + +static int parse_asn1_tag(CBS *cbs, unsigned *out) { + uint8_t tag_byte; + if (!CBS_get_u8(cbs, &tag_byte)) { + return 0; + } + + // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag + // number no greater than 30. + // + // If the number portion is 31 (0x1f, the largest value that fits in the + // allotted bits), then the tag is more than one byte long and the + // continuation bytes contain the tag number. + unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; + unsigned tag_number = tag_byte & 0x1f; + if (tag_number == 0x1f) { + uint64_t v; + if (!parse_base128_integer(cbs, &v) || + // Check the tag number is within our supported bounds. + v > CBS_ASN1_TAG_NUMBER_MASK || + // Small tag numbers should have used low tag number form, even in BER. + v < 0x1f) { + return 0; + } + tag_number = (unsigned)v; + } + + tag |= tag_number; + + // Tag [UNIVERSAL 0] is reserved for use by the encoding. Reject it here to + // avoid some ambiguity around ANY values and BER indefinite-length EOCs. See + // https://crbug.com/boringssl/455. + if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) { + return 0; + } + + *out = tag; + return 1; +} + +static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len, int *out_ber_found, + int *out_indefinite, int ber_ok) { + CBS header = *cbs; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + if (ber_ok) { + *out_ber_found = 0; + *out_indefinite = 0; + } else { + assert(out_ber_found == NULL); + assert(out_indefinite == NULL); + } + + unsigned tag; + if (!parse_asn1_tag(&header, &tag)) { + return 0; + } + if (out_tag != NULL) { + *out_tag = tag; + } + + uint8_t length_byte; + if (!CBS_get_u8(&header, &length_byte)) { + return 0; + } + + size_t header_len = CBS_len(cbs) - CBS_len(&header); + + size_t len; + // The format for the length encoding is specified in ITU-T X.690 section + // 8.1.3. + if ((length_byte & 0x80) == 0) { + // Short form length. + len = ((size_t) length_byte) + header_len; + if (out_header_len != NULL) { + *out_header_len = header_len; + } + } else { + // The high bit indicate that this is the long form, while the next 7 bits + // encode the number of subsequent octets used to encode the length (ITU-T + // X.690 clause 8.1.3.5.b). + const size_t num_bytes = length_byte & 0x7f; + uint64_t len64; + + if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { + // indefinite length + if (out_header_len != NULL) { + *out_header_len = header_len; + } + *out_ber_found = 1; + *out_indefinite = 1; + return CBS_get_bytes(cbs, out, header_len); + } + + // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be + // used as the first byte of the length. If this parser encounters that + // value, num_bytes will be parsed as 127, which will fail this check. + if (num_bytes == 0 || num_bytes > 4) { + return 0; + } + if (!cbs_get_u(&header, &len64, num_bytes)) { + return 0; + } + // ITU-T X.690 section 10.1 (DER length forms) requires encoding the + // length with the minimum number of octets. BER could, technically, have + // 125 superfluous zero bytes. We do not attempt to handle that and still + // require that the length fit in a |uint32_t| for BER. + if (len64 < 128) { + // Length should have used short-form encoding. + if (ber_ok) { + *out_ber_found = 1; + } else { + return 0; + } + } + if ((len64 >> ((num_bytes - 1) * 8)) == 0) { + // Length should have been at least one byte shorter. + if (ber_ok) { + *out_ber_found = 1; + } else { + return 0; + } + } + len = len64; + if (len + header_len + num_bytes < len) { + // Overflow. + return 0; + } + len += header_len + num_bytes; + if (out_header_len != NULL) { + *out_header_len = header_len + num_bytes; + } + } + + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) { + return 0; + } + + if (!CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len) { + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL, + /*ber_ok=*/0); +} + +int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len, int *out_ber_found, + int *out_indefinite) { + int ber_found_temp; + return cbs_get_any_asn1_element( + cbs, out, out_tag, out_header_len, + out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite, + /*ber_ok=*/1); +} + +static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, + int skip_header) { + size_t header_len; + unsigned tag; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) { + return 0; + } + + if (skip_header && !CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { + if (CBS_len(cbs) < 1) { + return 0; + } + + CBS copy = *cbs; + unsigned actual_tag; + return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag; +} + +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) || + !CBS_is_unsigned_asn1_integer(&bytes)) { + return 0; + } + + *out = 0; + const uint8_t *data = CBS_data(&bytes); + size_t len = CBS_len(&bytes); + for (size_t i = 0; i < len; i++) { + if ((*out >> 56) != 0) { + // Too large to represent as a uint64_t. + return 0; + } + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int CBS_get_asn1_int64(CBS *cbs, int64_t *out) { + int is_negative; + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER) || + !CBS_is_valid_asn1_integer(&bytes, &is_negative)) { + return 0; + } + const uint8_t *data = CBS_data(&bytes); + const size_t len = CBS_len(&bytes); + if (len > sizeof(int64_t)) { + return 0; + } + union { + int64_t i; + uint8_t bytes[sizeof(int64_t)]; + } u; + memset(u.bytes, is_negative ? 0xff : 0, sizeof(u.bytes)); // Sign-extend. + for (size_t i = 0; i < len; i++) { + u.bytes[i] = data[len - i - 1]; + } + *out = u.i; + return 1; +} + +int CBS_get_asn1_bool(CBS *cbs, int *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || + CBS_len(&bytes) != 1) { + return 0; + } + + const uint8_t value = *CBS_data(&bytes); + if (value != 0 && value != 0xff) { + return 0; + } + + *out = !!value; + return 1; +} + +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { + int present = 0; + + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) { + return 0; + } + present = 1; + } + + if (out_present != NULL) { + *out_present = present; + } + + return 1; +} + +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned tag) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + assert(out); + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + return 0; + } + } else { + CBS_init(out, NULL, 0); + } + if (out_present) { + *out_present = present; + } + return 1; +} + +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, + uint64_t default_value) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value) { + CBS child, child2; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || + CBS_len(&child) != 0) { + return 0; + } + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) { + *out = 0; + } else if (boolean == 0xff) { + *out = 1; + } else { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_is_valid_asn1_bitstring(const CBS *cbs) { + CBS in = *cbs; + uint8_t num_unused_bits; + if (!CBS_get_u8(&in, &num_unused_bits) || + num_unused_bits > 7) { + return 0; + } + + if (num_unused_bits == 0) { + return 1; + } + + // All num_unused_bits bits must exist and be zeros. + uint8_t last; + if (!CBS_get_last_u8(&in, &last) || + (last & ((1 << num_unused_bits) - 1)) != 0) { + return 0; + } + + return 1; +} + +int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) { + if (!CBS_is_valid_asn1_bitstring(cbs)) { + return 0; + } + + const unsigned byte_num = (bit >> 3) + 1; + const unsigned bit_num = 7 - (bit & 7); + + // Unused bits are zero, and this function does not distinguish between + // missing and unset bits. Thus it is sufficient to do a byte-level length + // check. + return byte_num < CBS_len(cbs) && + (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0; +} + +int CBS_is_valid_asn1_integer(const CBS *cbs, int *out_is_negative) { + CBS copy = *cbs; + uint8_t first_byte, second_byte; + if (!CBS_get_u8(©, &first_byte)) { + return 0; // INTEGERs may not be empty. + } + if (out_is_negative != NULL) { + *out_is_negative = (first_byte & 0x80) != 0; + } + if (!CBS_get_u8(©, &second_byte)) { + return 1; // One byte INTEGERs are always minimal. + } + if ((first_byte == 0x00 && (second_byte & 0x80) == 0) || + (first_byte == 0xff && (second_byte & 0x80) != 0)) { + return 0; // The value is minimal iff the first 9 bits are not all equal. + } + return 1; +} + +int CBS_is_unsigned_asn1_integer(const CBS *cbs) { + int is_negative; + return CBS_is_valid_asn1_integer(cbs, &is_negative) && !is_negative; +} + +static int add_decimal(CBB *out, uint64_t v) { + char buf[DECIMAL_SIZE(uint64_t) + 1]; + BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v); + return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf)); +} + +char *CBS_asn1_oid_to_text(const CBS *cbs) { + CBB cbb; + if (!CBB_init(&cbb, 32)) { + goto err; + } + + CBS copy = *cbs; + // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2. + uint64_t v; + if (!parse_base128_integer(©, &v)) { + goto err; + } + + if (v >= 80) { + if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) || + !add_decimal(&cbb, v - 80)) { + goto err; + } + } else if (!add_decimal(&cbb, v / 40) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v % 40)) { + goto err; + } + + while (CBS_len(©) != 0) { + if (!parse_base128_integer(©, &v) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v)) { + goto err; + } + } + + uint8_t *txt; + size_t txt_len; + if (!CBB_add_u8(&cbb, '\0') || + !CBB_finish(&cbb, &txt, &txt_len)) { + goto err; + } + + return (char *)txt; + +err: + CBB_cleanup(&cbb); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/internal.h new file mode 100644 index 00000000..f0a0e524 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/internal.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_INTERNAL_H +#define OPENSSL_HEADER_BYTESTRING_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CBS_asn1_ber_to_der reads a BER element from |in|. If it finds +// indefinite-length elements or constructed strings then it converts the BER +// data to DER, sets |out| to the converted contents and |*out_storage| to a +// buffer which the caller must release with |OPENSSL_free|. Otherwise, it sets +// |out| to the original BER element in |in| and |*out_storage| to NULL. +// Additionally, |*in| will be advanced over the BER element. +// +// This function should successfully process any valid BER input, however it +// will not convert all of BER's deviations from DER. BER is ambiguous between +// implicitly-tagged SEQUENCEs of strings and implicitly-tagged constructed +// strings. Implicitly-tagged strings must be parsed with +// |CBS_get_ber_implicitly_tagged_string| instead of |CBS_get_asn1|. The caller +// must also account for BER variations in the contents of a primitive. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, CBS *out, + uint8_t **out_storage); + +// CBS_get_asn1_implicit_string parses a BER string of primitive type +// |inner_tag| implicitly-tagged with |outer_tag|. It sets |out| to the +// contents. If concatenation was needed, it sets |*out_storage| to a buffer +// which the caller must release with |OPENSSL_free|. Otherwise, it sets +// |*out_storage| to NULL. +// +// This function does not parse all of BER. It requires the string be +// definite-length. Constructed strings are allowed, but all children of the +// outermost element must be primitive. The caller should use +// |CBS_asn1_ber_to_der| before running this function. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, + uint8_t **out_storage, + unsigned outer_tag, + unsigned inner_tag); + +// CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized +// with |CBB_init|. If |outp| is not NULL then the result is written to |*outp| +// and |*outp| is advanced just past the output. It returns the number of bytes +// in the result, whether written or not, or a negative value on error. On +// error, it calls |CBB_cleanup| on |cbb|. +// +// This function may be used to help implement legacy i2d ASN.1 functions. +int CBB_finish_i2d(CBB *cbb, uint8_t **outp); + + +// Unicode utilities. + +// The following functions read one Unicode code point from |cbs| with the +// corresponding encoding and store it in |*out|. They return one on success and +// zero on error. +OPENSSL_EXPORT int cbs_get_utf8(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int cbs_get_latin1(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int cbs_get_ucs2_be(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int cbs_get_utf32_be(CBS *cbs, uint32_t *out); + +// cbb_get_utf8_len returns the number of bytes needed to represent |u| in +// UTF-8. +OPENSSL_EXPORT size_t cbb_get_utf8_len(uint32_t u); + +// The following functions encode |u| to |cbb| with the corresponding +// encoding. They return one on success and zero on error. +OPENSSL_EXPORT int cbb_add_utf8(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int cbb_add_latin1(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int cbb_add_ucs2_be(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int cbb_add_utf32_be(CBB *cbb, uint32_t u); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/unicode.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/unicode.c new file mode 100644 index 00000000..88f7af45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/bytestring/unicode.c @@ -0,0 +1,155 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include "internal.h" + + +static int is_valid_code_point(uint32_t v) { + // References in the following are to Unicode 9.0.0. + if (// The Unicode space runs from zero to 0x10ffff (3.4 D9). + v > 0x10ffff || + // Values 0x...fffe, 0x...ffff, and 0xfdd0-0xfdef are permanently reserved + // (3.4 D14) + (v & 0xfffe) == 0xfffe || + (v >= 0xfdd0 && v <= 0xfdef) || + // Surrogate code points are invalid (3.2 C1). + (v >= 0xd800 && v <= 0xdfff)) { + return 0; + } + return 1; +} + +// BOTTOM_BITS returns a byte with the bottom |n| bits set. +#define BOTTOM_BITS(n) (uint8_t)((1u << (n)) - 1) + +// TOP_BITS returns a byte with the top |n| bits set. +#define TOP_BITS(n) ((uint8_t)~BOTTOM_BITS(8 - (n))) + +int cbs_get_utf8(CBS *cbs, uint32_t *out) { + uint8_t c; + if (!CBS_get_u8(cbs, &c)) { + return 0; + } + if (c <= 0x7f) { + *out = c; + return 1; + } + uint32_t v, lower_bound; + size_t len; + if ((c & TOP_BITS(3)) == TOP_BITS(2)) { + v = c & BOTTOM_BITS(5); + len = 1; + lower_bound = 0x80; + } else if ((c & TOP_BITS(4)) == TOP_BITS(3)) { + v = c & BOTTOM_BITS(4); + len = 2; + lower_bound = 0x800; + } else if ((c & TOP_BITS(5)) == TOP_BITS(4)) { + v = c & BOTTOM_BITS(3); + len = 3; + lower_bound = 0x10000; + } else { + return 0; + } + for (size_t i = 0; i < len; i++) { + if (!CBS_get_u8(cbs, &c) || + (c & TOP_BITS(2)) != TOP_BITS(1)) { + return 0; + } + v <<= 6; + v |= c & BOTTOM_BITS(6); + } + if (!is_valid_code_point(v) || + v < lower_bound) { + return 0; + } + *out = v; + return 1; +} + +int cbs_get_latin1(CBS *cbs, uint32_t *out) { + uint8_t c; + if (!CBS_get_u8(cbs, &c)) { + return 0; + } + *out = c; + return 1; +} + +int cbs_get_ucs2_be(CBS *cbs, uint32_t *out) { + // Note UCS-2 (used by BMPString) does not support surrogates. + uint16_t c; + if (!CBS_get_u16(cbs, &c) || + !is_valid_code_point(c)) { + return 0; + } + *out = c; + return 1; +} + +int cbs_get_utf32_be(CBS *cbs, uint32_t *out) { + return CBS_get_u32(cbs, out) && is_valid_code_point(*out); +} + +size_t cbb_get_utf8_len(uint32_t u) { + if (u <= 0x7f) { + return 1; + } + if (u <= 0x7ff) { + return 2; + } + if (u <= 0xffff) { + return 3; + } + return 4; +} + +int cbb_add_utf8(CBB *cbb, uint32_t u) { + if (!is_valid_code_point(u)) { + return 0; + } + if (u <= 0x7f) { + return CBB_add_u8(cbb, (uint8_t)u); + } + if (u <= 0x7ff) { + return CBB_add_u8(cbb, TOP_BITS(2) | (u >> 6)) && + CBB_add_u8(cbb, TOP_BITS(1) | (u & BOTTOM_BITS(6))); + } + if (u <= 0xffff) { + return CBB_add_u8(cbb, TOP_BITS(3) | (u >> 12)) && + CBB_add_u8(cbb, TOP_BITS(1) | ((u >> 6) & BOTTOM_BITS(6))) && + CBB_add_u8(cbb, TOP_BITS(1) | (u & BOTTOM_BITS(6))); + } + if (u <= 0x10ffff) { + return CBB_add_u8(cbb, TOP_BITS(4) | (u >> 18)) && + CBB_add_u8(cbb, TOP_BITS(1) | ((u >> 12) & BOTTOM_BITS(6))) && + CBB_add_u8(cbb, TOP_BITS(1) | ((u >> 6) & BOTTOM_BITS(6))) && + CBB_add_u8(cbb, TOP_BITS(1) | (u & BOTTOM_BITS(6))); + } + return 0; +} + +int cbb_add_latin1(CBB *cbb, uint32_t u) { + return u <= 0xff && CBB_add_u8(cbb, (uint8_t)u); +} + +int cbb_add_ucs2_be(CBB *cbb, uint32_t u) { + return u <= 0xffff && is_valid_code_point(u) && CBB_add_u16(cbb, (uint16_t)u); +} + +int cbb_add_utf32_be(CBB *cbb, uint32_t u) { + return is_valid_code_point(u) && CBB_add_u32(cbb, u); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S new file mode 100644 index 00000000..15de9034 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S @@ -0,0 +1,1505 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. + + +.text +#if defined(__thumb2__) || defined(__clang__) +.syntax unified +#endif +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif + +#if defined(__thumb2__) || defined(__clang__) +#define ldrhsb ldrbhs +#endif + +.align 5 +Lsigma: +.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral +Lone: +.long 1,0,0,0 +#if __ARM_MAX_ARCH__>=7 +LOPENSSL_armcap: +.word OPENSSL_armcap_P-LChaCha20_ctr32 +#else +.word -1 +#endif + +.globl _ChaCha20_ctr32 +.private_extern _ChaCha20_ctr32 +#ifdef __thumb2__ +.thumb_func _ChaCha20_ctr32 +#endif +.align 5 +_ChaCha20_ctr32: +LChaCha20_ctr32: + ldr r12,[sp,#0] @ pull pointer to counter and nonce + stmdb sp!,{r0,r1,r2,r4-r11,lr} +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r14,pc,#16 @ _ChaCha20_ctr32 +#else + adr r14,LChaCha20_ctr32 +#endif + cmp r2,#0 @ len==0? +#ifdef __thumb2__ + itt eq +#endif + addeq sp,sp,#4*3 + beq Lno_data +#if __ARM_MAX_ARCH__>=7 + cmp r2,#192 @ test len + bls Lshort + ldr r4,[r14,#-32] + ldr r4,[r14,r4] +# ifdef __APPLE__ + ldr r4,[r4] +# endif + tst r4,#ARMV7_NEON + bne LChaCha20_neon +Lshort: +#endif + ldmia r12,{r4,r5,r6,r7} @ load counter and nonce + sub sp,sp,#4*(16) @ off-load area + sub r14,r14,#64 @ Lsigma + stmdb sp!,{r4,r5,r6,r7} @ copy counter and nonce + ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key + ldmia r14,{r0,r1,r2,r3} @ load sigma + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} @ copy key + stmdb sp!,{r0,r1,r2,r3} @ copy sigma + str r10,[sp,#4*(16+10)] @ off-load "rx" + str r11,[sp,#4*(16+11)] @ off-load "rx" + b Loop_outer_enter + +.align 4 +Loop_outer: + ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material + str r11,[sp,#4*(32+2)] @ save len + str r12, [sp,#4*(32+1)] @ save inp + str r14, [sp,#4*(32+0)] @ save out +Loop_outer_enter: + ldr r11, [sp,#4*(15)] + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + ldr r10, [sp,#4*(13)] + ldr r14,[sp,#4*(14)] + str r11, [sp,#4*(16+15)] + mov r11,#10 + b Loop + +.align 4 +Loop: + subs r11,r11,#1 + add r0,r0,r4 + mov r12,r12,ror#16 + add r1,r1,r5 + mov r10,r10,ror#16 + eor r12,r12,r0,ror#16 + eor r10,r10,r1,ror#16 + add r8,r8,r12 + mov r4,r4,ror#20 + add r9,r9,r10 + mov r5,r5,ror#20 + eor r4,r4,r8,ror#20 + eor r5,r5,r9,ror#20 + add r0,r0,r4 + mov r12,r12,ror#24 + add r1,r1,r5 + mov r10,r10,ror#24 + eor r12,r12,r0,ror#24 + eor r10,r10,r1,ror#24 + add r8,r8,r12 + mov r4,r4,ror#25 + add r9,r9,r10 + mov r5,r5,ror#25 + str r10,[sp,#4*(16+13)] + ldr r10,[sp,#4*(16+15)] + eor r4,r4,r8,ror#25 + eor r5,r5,r9,ror#25 + str r8,[sp,#4*(16+8)] + ldr r8,[sp,#4*(16+10)] + add r2,r2,r6 + mov r14,r14,ror#16 + str r9,[sp,#4*(16+9)] + ldr r9,[sp,#4*(16+11)] + add r3,r3,r7 + mov r10,r10,ror#16 + eor r14,r14,r2,ror#16 + eor r10,r10,r3,ror#16 + add r8,r8,r14 + mov r6,r6,ror#20 + add r9,r9,r10 + mov r7,r7,ror#20 + eor r6,r6,r8,ror#20 + eor r7,r7,r9,ror#20 + add r2,r2,r6 + mov r14,r14,ror#24 + add r3,r3,r7 + mov r10,r10,ror#24 + eor r14,r14,r2,ror#24 + eor r10,r10,r3,ror#24 + add r8,r8,r14 + mov r6,r6,ror#25 + add r9,r9,r10 + mov r7,r7,ror#25 + eor r6,r6,r8,ror#25 + eor r7,r7,r9,ror#25 + add r0,r0,r5 + mov r10,r10,ror#16 + add r1,r1,r6 + mov r12,r12,ror#16 + eor r10,r10,r0,ror#16 + eor r12,r12,r1,ror#16 + add r8,r8,r10 + mov r5,r5,ror#20 + add r9,r9,r12 + mov r6,r6,ror#20 + eor r5,r5,r8,ror#20 + eor r6,r6,r9,ror#20 + add r0,r0,r5 + mov r10,r10,ror#24 + add r1,r1,r6 + mov r12,r12,ror#24 + eor r10,r10,r0,ror#24 + eor r12,r12,r1,ror#24 + add r8,r8,r10 + mov r5,r5,ror#25 + str r10,[sp,#4*(16+15)] + ldr r10,[sp,#4*(16+13)] + add r9,r9,r12 + mov r6,r6,ror#25 + eor r5,r5,r8,ror#25 + eor r6,r6,r9,ror#25 + str r8,[sp,#4*(16+10)] + ldr r8,[sp,#4*(16+8)] + add r2,r2,r7 + mov r10,r10,ror#16 + str r9,[sp,#4*(16+11)] + ldr r9,[sp,#4*(16+9)] + add r3,r3,r4 + mov r14,r14,ror#16 + eor r10,r10,r2,ror#16 + eor r14,r14,r3,ror#16 + add r8,r8,r10 + mov r7,r7,ror#20 + add r9,r9,r14 + mov r4,r4,ror#20 + eor r7,r7,r8,ror#20 + eor r4,r4,r9,ror#20 + add r2,r2,r7 + mov r10,r10,ror#24 + add r3,r3,r4 + mov r14,r14,ror#24 + eor r10,r10,r2,ror#24 + eor r14,r14,r3,ror#24 + add r8,r8,r10 + mov r7,r7,ror#25 + add r9,r9,r14 + mov r4,r4,ror#25 + eor r7,r7,r8,ror#25 + eor r4,r4,r9,ror#25 + bne Loop + + ldr r11,[sp,#4*(32+2)] @ load len + + str r8, [sp,#4*(16+8)] @ modulo-scheduled store + str r9, [sp,#4*(16+9)] + str r12,[sp,#4*(16+12)] + str r10, [sp,#4*(16+13)] + str r14,[sp,#4*(16+14)] + + @ at this point we have first half of 512-bit result in + @ rx and second half at sp+4*(16+8) + + cmp r11,#64 @ done yet? +#ifdef __thumb2__ + itete lo +#endif + addlo r12,sp,#4*(0) @ shortcut or ... + ldrhs r12,[sp,#4*(32+1)] @ ... load inp + addlo r14,sp,#4*(0) @ shortcut or ... + ldrhs r14,[sp,#4*(32+0)] @ ... load out + + ldr r8,[sp,#4*(0)] @ load key material + ldr r9,[sp,#4*(1)] + +#if __ARM_ARCH__>=6 || !defined(__ARMEB__) +# if __ARM_ARCH__<7 + orr r10,r12,r14 + tst r10,#3 @ are input and output aligned? + ldr r10,[sp,#4*(2)] + bne Lunaligned + cmp r11,#64 @ restore flags +# else + ldr r10,[sp,#4*(2)] +# endif + ldr r11,[sp,#4*(3)] + + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + + add r2,r2,r10 + add r3,r3,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r0,r0,r8 @ xor with input + eorhs r1,r1,r9 + add r8,sp,#4*(4) + str r0,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r2,r2,r10 + eorhs r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r1,[r14,#-12] + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + add r6,r6,r10 + add r7,r7,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r4,r4,r8 + eorhs r5,r5,r9 + add r8,sp,#4*(8) + str r4,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r6,r6,r10 + eorhs r7,r7,r11 + str r5,[r14,#-12] + ldmia r8,{r8,r9,r10,r11} @ load key material + str r6,[r14,#-8] + add r0,sp,#4*(16+8) + str r7,[r14,#-4] + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] +# ifdef __thumb2__ + itt hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it + strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it + add r2,r2,r10 + add r3,r3,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r0,r0,r8 + eorhs r1,r1,r9 + add r8,sp,#4*(12) + str r0,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r2,r2,r10 + eorhs r3,r3,r11 + str r1,[r14,#-12] + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 +# ifdef __thumb2__ + itt hi +# endif + addhi r8,r8,#1 @ next counter value + strhi r8,[sp,#4*(12)] @ save next counter value +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + add r6,r6,r10 + add r7,r7,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r4,r4,r8 + eorhs r5,r5,r9 +# ifdef __thumb2__ + it ne +# endif + ldrne r8,[sp,#4*(32+2)] @ re-load len +# ifdef __thumb2__ + itt hs +# endif + eorhs r6,r6,r10 + eorhs r7,r7,r11 + str r4,[r14],#16 @ store output + str r5,[r14,#-12] +# ifdef __thumb2__ + it hs +# endif + subhs r11,r8,#64 @ len-=64 + str r6,[r14,#-8] + str r7,[r14,#-4] + bhi Loop_outer + + beq Ldone +# if __ARM_ARCH__<7 + b Ltail + +.align 4 +Lunaligned:@ unaligned endian-neutral path + cmp r11,#64 @ restore flags +# endif +#endif +#if __ARM_ARCH__<7 + ldr r11,[sp,#4*(3)] + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 + add r2,r2,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r3,r3,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r0,r8,r0 @ xor with input (or zero) + eor r1,r9,r1 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r2,r10,r2 + strb r0,[r14],#16 @ store output + eor r3,r11,r3 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r1,[r14,#-12] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-8] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r3,[r14,#-4] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-15] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r1,[r14,#-11] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-7] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r3,[r14,#-3] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-14] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r1,[r14,#-10] + strb r2,[r14,#-6] + eor r0,r8,r0,lsr#8 + strb r3,[r14,#-2] + eor r1,r9,r1,lsr#8 + strb r0,[r14,#-13] + eor r2,r10,r2,lsr#8 + strb r1,[r14,#-9] + eor r3,r11,r3,lsr#8 + strb r2,[r14,#-5] + strb r3,[r14,#-1] + add r8,sp,#4*(4+0) + ldmia r8,{r8,r9,r10,r11} @ load key material + add r0,sp,#4*(16+8) + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 + add r6,r6,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r7,r7,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r4,r8,r4 @ xor with input (or zero) + eor r5,r9,r5 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r6,r10,r6 + strb r4,[r14],#16 @ store output + eor r7,r11,r7 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r5,[r14,#-12] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-8] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r7,[r14,#-4] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-15] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r5,[r14,#-11] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-7] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r7,[r14,#-3] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-14] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r5,[r14,#-10] + strb r6,[r14,#-6] + eor r4,r8,r4,lsr#8 + strb r7,[r14,#-2] + eor r5,r9,r5,lsr#8 + strb r4,[r14,#-13] + eor r6,r10,r6,lsr#8 + strb r5,[r14,#-9] + eor r7,r11,r7,lsr#8 + strb r6,[r14,#-5] + strb r7,[r14,#-1] + add r8,sp,#4*(4+4) + ldmia r8,{r8,r9,r10,r11} @ load key material + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half +# ifdef __thumb2__ + itt hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" + strhi r11,[sp,#4*(16+11)] @ copy "rx" + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 + add r2,r2,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r3,r3,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r0,r8,r0 @ xor with input (or zero) + eor r1,r9,r1 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r2,r10,r2 + strb r0,[r14],#16 @ store output + eor r3,r11,r3 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r1,[r14,#-12] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-8] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r3,[r14,#-4] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-15] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r1,[r14,#-11] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-7] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r3,[r14,#-3] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-14] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r1,[r14,#-10] + strb r2,[r14,#-6] + eor r0,r8,r0,lsr#8 + strb r3,[r14,#-2] + eor r1,r9,r1,lsr#8 + strb r0,[r14,#-13] + eor r2,r10,r2,lsr#8 + strb r1,[r14,#-9] + eor r3,r11,r3,lsr#8 + strb r2,[r14,#-5] + strb r3,[r14,#-1] + add r8,sp,#4*(4+8) + ldmia r8,{r8,r9,r10,r11} @ load key material + add r4,r4,r8 @ accumulate key material +# ifdef __thumb2__ + itt hi +# endif + addhi r8,r8,#1 @ next counter value + strhi r8,[sp,#4*(12)] @ save next counter value + add r5,r5,r9 + add r6,r6,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r7,r7,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r4,r8,r4 @ xor with input (or zero) + eor r5,r9,r5 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r6,r10,r6 + strb r4,[r14],#16 @ store output + eor r7,r11,r7 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r5,[r14,#-12] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-8] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r7,[r14,#-4] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-15] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r5,[r14,#-11] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-7] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r7,[r14,#-3] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-14] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r5,[r14,#-10] + strb r6,[r14,#-6] + eor r4,r8,r4,lsr#8 + strb r7,[r14,#-2] + eor r5,r9,r5,lsr#8 + strb r4,[r14,#-13] + eor r6,r10,r6,lsr#8 + strb r5,[r14,#-9] + eor r7,r11,r7,lsr#8 + strb r6,[r14,#-5] + strb r7,[r14,#-1] +# ifdef __thumb2__ + it ne +# endif + ldrne r8,[sp,#4*(32+2)] @ re-load len +# ifdef __thumb2__ + it hs +# endif + subhs r11,r8,#64 @ len-=64 + bhi Loop_outer + + beq Ldone +#endif + +Ltail: + ldr r12,[sp,#4*(32+1)] @ load inp + add r9,sp,#4*(0) + ldr r14,[sp,#4*(32+0)] @ load out + +Loop_tail: + ldrb r10,[r9],#1 @ read buffer on stack + ldrb r11,[r12],#1 @ read input + subs r8,r8,#1 + eor r11,r11,r10 + strb r11,[r14],#1 @ store output + bne Loop_tail + +Ldone: + add sp,sp,#4*(32+3) +Lno_data: + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} + +#if __ARM_MAX_ARCH__>=7 + + + +#ifdef __thumb2__ +.thumb_func ChaCha20_neon +#endif +.align 5 +ChaCha20_neon: + ldr r12,[sp,#0] @ pull pointer to counter and nonce + stmdb sp!,{r0,r1,r2,r4-r11,lr} +LChaCha20_neon: + adr r14,Lsigma + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI spec says so + stmdb sp!,{r0,r1,r2,r3} + + vld1.32 {q1,q2},[r3] @ load key + ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key + + sub sp,sp,#4*(16+16) + vld1.32 {q3},[r12] @ load counter and nonce + add r12,sp,#4*8 + ldmia r14,{r0,r1,r2,r3} @ load sigma + vld1.32 {q0},[r14]! @ load sigma + vld1.32 {q12},[r14] @ one + vst1.32 {q2,q3},[r12] @ copy 1/2key|counter|nonce + vst1.32 {q0,q1},[sp] @ copy sigma|1/2key + + str r10,[sp,#4*(16+10)] @ off-load "rx" + str r11,[sp,#4*(16+11)] @ off-load "rx" + vshl.i32 d26,d24,#1 @ two + vstr d24,[sp,#4*(16+0)] + vshl.i32 d28,d24,#2 @ four + vstr d26,[sp,#4*(16+2)] + vmov q4,q0 + vstr d28,[sp,#4*(16+4)] + vmov q8,q0 + vmov q5,q1 + vmov q9,q1 + b Loop_neon_enter + +.align 4 +Loop_neon_outer: + ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material + cmp r11,#64*2 @ if len<=64*2 + bls Lbreak_neon @ switch to integer-only + vmov q4,q0 + str r11,[sp,#4*(32+2)] @ save len + vmov q8,q0 + str r12, [sp,#4*(32+1)] @ save inp + vmov q5,q1 + str r14, [sp,#4*(32+0)] @ save out + vmov q9,q1 +Loop_neon_enter: + ldr r11, [sp,#4*(15)] + vadd.i32 q7,q3,q12 @ counter+1 + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + vmov q6,q2 + ldr r10, [sp,#4*(13)] + vmov q10,q2 + ldr r14,[sp,#4*(14)] + vadd.i32 q11,q7,q12 @ counter+2 + str r11, [sp,#4*(16+15)] + mov r11,#10 + add r12,r12,#3 @ counter+3 + b Loop_neon + +.align 4 +Loop_neon: + subs r11,r11,#1 + vadd.i32 q0,q0,q1 + add r0,r0,r4 + vadd.i32 q4,q4,q5 + mov r12,r12,ror#16 + vadd.i32 q8,q8,q9 + add r1,r1,r5 + veor q3,q3,q0 + mov r10,r10,ror#16 + veor q7,q7,q4 + eor r12,r12,r0,ror#16 + veor q11,q11,q8 + eor r10,r10,r1,ror#16 + vrev32.16 q3,q3 + add r8,r8,r12 + vrev32.16 q7,q7 + mov r4,r4,ror#20 + vrev32.16 q11,q11 + add r9,r9,r10 + vadd.i32 q2,q2,q3 + mov r5,r5,ror#20 + vadd.i32 q6,q6,q7 + eor r4,r4,r8,ror#20 + vadd.i32 q10,q10,q11 + eor r5,r5,r9,ror#20 + veor q12,q1,q2 + add r0,r0,r4 + veor q13,q5,q6 + mov r12,r12,ror#24 + veor q14,q9,q10 + add r1,r1,r5 + vshr.u32 q1,q12,#20 + mov r10,r10,ror#24 + vshr.u32 q5,q13,#20 + eor r12,r12,r0,ror#24 + vshr.u32 q9,q14,#20 + eor r10,r10,r1,ror#24 + vsli.32 q1,q12,#12 + add r8,r8,r12 + vsli.32 q5,q13,#12 + mov r4,r4,ror#25 + vsli.32 q9,q14,#12 + add r9,r9,r10 + vadd.i32 q0,q0,q1 + mov r5,r5,ror#25 + vadd.i32 q4,q4,q5 + str r10,[sp,#4*(16+13)] + vadd.i32 q8,q8,q9 + ldr r10,[sp,#4*(16+15)] + veor q12,q3,q0 + eor r4,r4,r8,ror#25 + veor q13,q7,q4 + eor r5,r5,r9,ror#25 + veor q14,q11,q8 + str r8,[sp,#4*(16+8)] + vshr.u32 q3,q12,#24 + ldr r8,[sp,#4*(16+10)] + vshr.u32 q7,q13,#24 + add r2,r2,r6 + vshr.u32 q11,q14,#24 + mov r14,r14,ror#16 + vsli.32 q3,q12,#8 + str r9,[sp,#4*(16+9)] + vsli.32 q7,q13,#8 + ldr r9,[sp,#4*(16+11)] + vsli.32 q11,q14,#8 + add r3,r3,r7 + vadd.i32 q2,q2,q3 + mov r10,r10,ror#16 + vadd.i32 q6,q6,q7 + eor r14,r14,r2,ror#16 + vadd.i32 q10,q10,q11 + eor r10,r10,r3,ror#16 + veor q12,q1,q2 + add r8,r8,r14 + veor q13,q5,q6 + mov r6,r6,ror#20 + veor q14,q9,q10 + add r9,r9,r10 + vshr.u32 q1,q12,#25 + mov r7,r7,ror#20 + vshr.u32 q5,q13,#25 + eor r6,r6,r8,ror#20 + vshr.u32 q9,q14,#25 + eor r7,r7,r9,ror#20 + vsli.32 q1,q12,#7 + add r2,r2,r6 + vsli.32 q5,q13,#7 + mov r14,r14,ror#24 + vsli.32 q9,q14,#7 + add r3,r3,r7 + vext.8 q2,q2,q2,#8 + mov r10,r10,ror#24 + vext.8 q6,q6,q6,#8 + eor r14,r14,r2,ror#24 + vext.8 q10,q10,q10,#8 + eor r10,r10,r3,ror#24 + vext.8 q1,q1,q1,#4 + add r8,r8,r14 + vext.8 q5,q5,q5,#4 + mov r6,r6,ror#25 + vext.8 q9,q9,q9,#4 + add r9,r9,r10 + vext.8 q3,q3,q3,#12 + mov r7,r7,ror#25 + vext.8 q7,q7,q7,#12 + eor r6,r6,r8,ror#25 + vext.8 q11,q11,q11,#12 + eor r7,r7,r9,ror#25 + vadd.i32 q0,q0,q1 + add r0,r0,r5 + vadd.i32 q4,q4,q5 + mov r10,r10,ror#16 + vadd.i32 q8,q8,q9 + add r1,r1,r6 + veor q3,q3,q0 + mov r12,r12,ror#16 + veor q7,q7,q4 + eor r10,r10,r0,ror#16 + veor q11,q11,q8 + eor r12,r12,r1,ror#16 + vrev32.16 q3,q3 + add r8,r8,r10 + vrev32.16 q7,q7 + mov r5,r5,ror#20 + vrev32.16 q11,q11 + add r9,r9,r12 + vadd.i32 q2,q2,q3 + mov r6,r6,ror#20 + vadd.i32 q6,q6,q7 + eor r5,r5,r8,ror#20 + vadd.i32 q10,q10,q11 + eor r6,r6,r9,ror#20 + veor q12,q1,q2 + add r0,r0,r5 + veor q13,q5,q6 + mov r10,r10,ror#24 + veor q14,q9,q10 + add r1,r1,r6 + vshr.u32 q1,q12,#20 + mov r12,r12,ror#24 + vshr.u32 q5,q13,#20 + eor r10,r10,r0,ror#24 + vshr.u32 q9,q14,#20 + eor r12,r12,r1,ror#24 + vsli.32 q1,q12,#12 + add r8,r8,r10 + vsli.32 q5,q13,#12 + mov r5,r5,ror#25 + vsli.32 q9,q14,#12 + str r10,[sp,#4*(16+15)] + vadd.i32 q0,q0,q1 + ldr r10,[sp,#4*(16+13)] + vadd.i32 q4,q4,q5 + add r9,r9,r12 + vadd.i32 q8,q8,q9 + mov r6,r6,ror#25 + veor q12,q3,q0 + eor r5,r5,r8,ror#25 + veor q13,q7,q4 + eor r6,r6,r9,ror#25 + veor q14,q11,q8 + str r8,[sp,#4*(16+10)] + vshr.u32 q3,q12,#24 + ldr r8,[sp,#4*(16+8)] + vshr.u32 q7,q13,#24 + add r2,r2,r7 + vshr.u32 q11,q14,#24 + mov r10,r10,ror#16 + vsli.32 q3,q12,#8 + str r9,[sp,#4*(16+11)] + vsli.32 q7,q13,#8 + ldr r9,[sp,#4*(16+9)] + vsli.32 q11,q14,#8 + add r3,r3,r4 + vadd.i32 q2,q2,q3 + mov r14,r14,ror#16 + vadd.i32 q6,q6,q7 + eor r10,r10,r2,ror#16 + vadd.i32 q10,q10,q11 + eor r14,r14,r3,ror#16 + veor q12,q1,q2 + add r8,r8,r10 + veor q13,q5,q6 + mov r7,r7,ror#20 + veor q14,q9,q10 + add r9,r9,r14 + vshr.u32 q1,q12,#25 + mov r4,r4,ror#20 + vshr.u32 q5,q13,#25 + eor r7,r7,r8,ror#20 + vshr.u32 q9,q14,#25 + eor r4,r4,r9,ror#20 + vsli.32 q1,q12,#7 + add r2,r2,r7 + vsli.32 q5,q13,#7 + mov r10,r10,ror#24 + vsli.32 q9,q14,#7 + add r3,r3,r4 + vext.8 q2,q2,q2,#8 + mov r14,r14,ror#24 + vext.8 q6,q6,q6,#8 + eor r10,r10,r2,ror#24 + vext.8 q10,q10,q10,#8 + eor r14,r14,r3,ror#24 + vext.8 q1,q1,q1,#12 + add r8,r8,r10 + vext.8 q5,q5,q5,#12 + mov r7,r7,ror#25 + vext.8 q9,q9,q9,#12 + add r9,r9,r14 + vext.8 q3,q3,q3,#4 + mov r4,r4,ror#25 + vext.8 q7,q7,q7,#4 + eor r7,r7,r8,ror#25 + vext.8 q11,q11,q11,#4 + eor r4,r4,r9,ror#25 + bne Loop_neon + + add r11,sp,#32 + vld1.32 {q12,q13},[sp] @ load key material + vld1.32 {q14,q15},[r11] + + ldr r11,[sp,#4*(32+2)] @ load len + + str r8, [sp,#4*(16+8)] @ modulo-scheduled store + str r9, [sp,#4*(16+9)] + str r12,[sp,#4*(16+12)] + str r10, [sp,#4*(16+13)] + str r14,[sp,#4*(16+14)] + + @ at this point we have first half of 512-bit result in + @ rx and second half at sp+4*(16+8) + + ldr r12,[sp,#4*(32+1)] @ load inp + ldr r14,[sp,#4*(32+0)] @ load out + + vadd.i32 q0,q0,q12 @ accumulate key material + vadd.i32 q4,q4,q12 + vadd.i32 q8,q8,q12 + vldr d24,[sp,#4*(16+0)] @ one + + vadd.i32 q1,q1,q13 + vadd.i32 q5,q5,q13 + vadd.i32 q9,q9,q13 + vldr d26,[sp,#4*(16+2)] @ two + + vadd.i32 q2,q2,q14 + vadd.i32 q6,q6,q14 + vadd.i32 q10,q10,q14 + vadd.i32 d14,d14,d24 @ counter+1 + vadd.i32 d22,d22,d26 @ counter+2 + + vadd.i32 q3,q3,q15 + vadd.i32 q7,q7,q15 + vadd.i32 q11,q11,q15 + + cmp r11,#64*4 + blo Ltail_neon + + vld1.8 {q12,q13},[r12]! @ load input + mov r11,sp + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 @ xor with input + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + vst1.8 {q0,q1},[r14]! @ store output + veor q5,q5,q13 + vld1.8 {q12,q13},[r12]! + veor q6,q6,q14 + vst1.8 {q2,q3},[r14]! + veor q7,q7,q15 + vld1.8 {q14,q15},[r12]! + + veor q8,q8,q12 + vld1.32 {q0,q1},[r11]! @ load for next iteration + veor d25,d25,d25 + vldr d24,[sp,#4*(16+4)] @ four + veor q9,q9,q13 + vld1.32 {q2,q3},[r11] + veor q10,q10,q14 + vst1.8 {q4,q5},[r14]! + veor q11,q11,q15 + vst1.8 {q6,q7},[r14]! + + vadd.i32 d6,d6,d24 @ next counter value + vldr d24,[sp,#4*(16+0)] @ one + + ldmia sp,{r8,r9,r10,r11} @ load key material + add r0,r0,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + vst1.8 {q8,q9},[r14]! + add r1,r1,r9 + ldr r9,[r12,#-12] + vst1.8 {q10,q11},[r14]! + add r2,r2,r10 + ldr r10,[r12,#-8] + add r3,r3,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif + eor r0,r0,r8 @ xor with input + add r8,sp,#4*(4) + eor r1,r1,r9 + str r0,[r14],#16 @ store output + eor r2,r2,r10 + str r1,[r14,#-12] + eor r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + add r5,r5,r9 + ldr r9,[r12,#-12] + add r6,r6,r10 + ldr r10,[r12,#-8] + add r7,r7,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + eor r4,r4,r8 + add r8,sp,#4*(8) + eor r5,r5,r9 + str r4,[r14],#16 @ store output + eor r6,r6,r10 + str r5,[r14,#-12] + eor r7,r7,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r6,[r14,#-8] + add r0,sp,#4*(16+8) + str r7,[r14,#-4] + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + add r1,r1,r9 + ldr r9,[r12,#-12] +# ifdef __thumb2__ + it hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it + add r2,r2,r10 + ldr r10,[r12,#-8] +# ifdef __thumb2__ + it hi +# endif + strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it + add r3,r3,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif + eor r0,r0,r8 + add r8,sp,#4*(12) + eor r1,r1,r9 + str r0,[r14],#16 @ store output + eor r2,r2,r10 + str r1,[r14,#-12] + eor r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r8,r8,#4 @ next counter value + add r5,r5,r9 + str r8,[sp,#4*(12)] @ save next counter value + ldr r8,[r12],#16 @ load input + add r6,r6,r10 + add r4,r4,#3 @ counter+3 + ldr r9,[r12,#-12] + add r7,r7,r11 + ldr r10,[r12,#-8] + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + eor r4,r4,r8 +# ifdef __thumb2__ + it hi +# endif + ldrhi r8,[sp,#4*(32+2)] @ re-load len + eor r5,r5,r9 + eor r6,r6,r10 + str r4,[r14],#16 @ store output + eor r7,r7,r11 + str r5,[r14,#-12] + sub r11,r8,#64*4 @ len-=64*4 + str r6,[r14,#-8] + str r7,[r14,#-4] + bhi Loop_neon_outer + + b Ldone_neon + +.align 4 +Lbreak_neon: + @ harmonize NEON and integer-only stack frames: load data + @ from NEON frame, but save to integer-only one; distance + @ between the two is 4*(32+4+16-32)=4*(20). + + str r11, [sp,#4*(20+32+2)] @ save len + add r11,sp,#4*(32+4) + str r12, [sp,#4*(20+32+1)] @ save inp + str r14, [sp,#4*(20+32+0)] @ save out + + ldr r12,[sp,#4*(16+10)] + ldr r14,[sp,#4*(16+11)] + vldmia r11,{d8,d9,d10,d11,d12,d13,d14,d15} @ fulfill ABI requirement + str r12,[sp,#4*(20+16+10)] @ copy "rx" + str r14,[sp,#4*(20+16+11)] @ copy "rx" + + ldr r11, [sp,#4*(15)] + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + ldr r10, [sp,#4*(13)] + ldr r14,[sp,#4*(14)] + str r11, [sp,#4*(20+16+15)] + add r11,sp,#4*(20) + vst1.32 {q0,q1},[r11]! @ copy key + add sp,sp,#4*(20) @ switch frame + vst1.32 {q2,q3},[r11] + mov r11,#10 + b Loop @ go integer-only + +.align 4 +Ltail_neon: + cmp r11,#64*3 + bhs L192_or_more_neon + cmp r11,#64*2 + bhs L128_or_more_neon + cmp r11,#64*1 + bhs L64_or_more_neon + + add r8,sp,#4*(8) + vst1.8 {q0,q1},[sp] + add r10,sp,#4*(0) + vst1.8 {q2,q3},[r8] + b Loop_tail_neon + +.align 4 +L64_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + veor q2,q2,q14 + veor q3,q3,q15 + vst1.8 {q0,q1},[r14]! + vst1.8 {q2,q3},[r14]! + + beq Ldone_neon + + add r8,sp,#4*(8) + vst1.8 {q4,q5},[sp] + add r10,sp,#4*(0) + vst1.8 {q6,q7},[r8] + sub r11,r11,#64*1 @ len-=64*1 + b Loop_tail_neon + +.align 4 +L128_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + veor q5,q5,q13 + vst1.8 {q0,q1},[r14]! + veor q6,q6,q14 + vst1.8 {q2,q3},[r14]! + veor q7,q7,q15 + vst1.8 {q4,q5},[r14]! + vst1.8 {q6,q7},[r14]! + + beq Ldone_neon + + add r8,sp,#4*(8) + vst1.8 {q8,q9},[sp] + add r10,sp,#4*(0) + vst1.8 {q10,q11},[r8] + sub r11,r11,#64*2 @ len-=64*2 + b Loop_tail_neon + +.align 4 +L192_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + veor q5,q5,q13 + vld1.8 {q12,q13},[r12]! + veor q6,q6,q14 + vst1.8 {q0,q1},[r14]! + veor q7,q7,q15 + vld1.8 {q14,q15},[r12]! + + veor q8,q8,q12 + vst1.8 {q2,q3},[r14]! + veor q9,q9,q13 + vst1.8 {q4,q5},[r14]! + veor q10,q10,q14 + vst1.8 {q6,q7},[r14]! + veor q11,q11,q15 + vst1.8 {q8,q9},[r14]! + vst1.8 {q10,q11},[r14]! + + beq Ldone_neon + + ldmia sp,{r8,r9,r10,r11} @ load key material + add r0,r0,r8 @ accumulate key material + add r8,sp,#4*(4) + add r1,r1,r9 + add r2,r2,r10 + add r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + + add r4,r4,r8 @ accumulate key material + add r8,sp,#4*(8) + add r5,r5,r9 + add r6,r6,r10 + add r7,r7,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + stmia sp,{r0,r1,r2,r3,r4,r5,r6,r7} + add r0,sp,#4*(16+8) + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + add r8,sp,#4*(12) + add r1,r1,r9 + add r2,r2,r10 + add r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + + add r4,r4,r8 @ accumulate key material + add r8,sp,#4*(8) + add r5,r5,r9 + add r4,r4,#3 @ counter+3 + add r6,r6,r10 + add r7,r7,r11 + ldr r11,[sp,#4*(32+2)] @ re-load len +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + stmia r8,{r0,r1,r2,r3,r4,r5,r6,r7} + add r10,sp,#4*(0) + sub r11,r11,#64*3 @ len-=64*3 + +Loop_tail_neon: + ldrb r8,[r10],#1 @ read buffer on stack + ldrb r9,[r12],#1 @ read input + subs r11,r11,#1 + eor r8,r8,r9 + strb r8,[r14],#1 @ store output + bne Loop_tail_neon + +Ldone_neon: + add sp,sp,#4*(32+4) + vldmia sp,{d8,d9,d10,d11,d12,d13,d14,d15} + add sp,sp,#4*(16+3) + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} + +.comm _OPENSSL_armcap_P,4 +.non_lazy_symbol_pointer +OPENSSL_armcap_P: +.indirect_symbol _OPENSSL_armcap_P +.long 0 +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S new file mode 100644 index 00000000..824ca6b6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S @@ -0,0 +1,1500 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. +.arch armv7-a + +.text +#if defined(__thumb2__) || defined(__clang__) +.syntax unified +#endif +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif + +#if defined(__thumb2__) || defined(__clang__) +#define ldrhsb ldrbhs +#endif + +.align 5 +.Lsigma: +.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral +.Lone: +.long 1,0,0,0 +#if __ARM_MAX_ARCH__>=7 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.LChaCha20_ctr32 +#else +.word -1 +#endif + +.globl ChaCha20_ctr32 +.hidden ChaCha20_ctr32 +.type ChaCha20_ctr32,%function +.align 5 +ChaCha20_ctr32: +.LChaCha20_ctr32: + ldr r12,[sp,#0] @ pull pointer to counter and nonce + stmdb sp!,{r0,r1,r2,r4-r11,lr} +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r14,pc,#16 @ ChaCha20_ctr32 +#else + adr r14,.LChaCha20_ctr32 +#endif + cmp r2,#0 @ len==0? +#ifdef __thumb2__ + itt eq +#endif + addeq sp,sp,#4*3 + beq .Lno_data +#if __ARM_MAX_ARCH__>=7 + cmp r2,#192 @ test len + bls .Lshort + ldr r4,[r14,#-32] + ldr r4,[r14,r4] +# ifdef __APPLE__ + ldr r4,[r4] +# endif + tst r4,#ARMV7_NEON + bne .LChaCha20_neon +.Lshort: +#endif + ldmia r12,{r4,r5,r6,r7} @ load counter and nonce + sub sp,sp,#4*(16) @ off-load area + sub r14,r14,#64 @ .Lsigma + stmdb sp!,{r4,r5,r6,r7} @ copy counter and nonce + ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key + ldmia r14,{r0,r1,r2,r3} @ load sigma + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} @ copy key + stmdb sp!,{r0,r1,r2,r3} @ copy sigma + str r10,[sp,#4*(16+10)] @ off-load "rx" + str r11,[sp,#4*(16+11)] @ off-load "rx" + b .Loop_outer_enter + +.align 4 +.Loop_outer: + ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material + str r11,[sp,#4*(32+2)] @ save len + str r12, [sp,#4*(32+1)] @ save inp + str r14, [sp,#4*(32+0)] @ save out +.Loop_outer_enter: + ldr r11, [sp,#4*(15)] + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + ldr r10, [sp,#4*(13)] + ldr r14,[sp,#4*(14)] + str r11, [sp,#4*(16+15)] + mov r11,#10 + b .Loop + +.align 4 +.Loop: + subs r11,r11,#1 + add r0,r0,r4 + mov r12,r12,ror#16 + add r1,r1,r5 + mov r10,r10,ror#16 + eor r12,r12,r0,ror#16 + eor r10,r10,r1,ror#16 + add r8,r8,r12 + mov r4,r4,ror#20 + add r9,r9,r10 + mov r5,r5,ror#20 + eor r4,r4,r8,ror#20 + eor r5,r5,r9,ror#20 + add r0,r0,r4 + mov r12,r12,ror#24 + add r1,r1,r5 + mov r10,r10,ror#24 + eor r12,r12,r0,ror#24 + eor r10,r10,r1,ror#24 + add r8,r8,r12 + mov r4,r4,ror#25 + add r9,r9,r10 + mov r5,r5,ror#25 + str r10,[sp,#4*(16+13)] + ldr r10,[sp,#4*(16+15)] + eor r4,r4,r8,ror#25 + eor r5,r5,r9,ror#25 + str r8,[sp,#4*(16+8)] + ldr r8,[sp,#4*(16+10)] + add r2,r2,r6 + mov r14,r14,ror#16 + str r9,[sp,#4*(16+9)] + ldr r9,[sp,#4*(16+11)] + add r3,r3,r7 + mov r10,r10,ror#16 + eor r14,r14,r2,ror#16 + eor r10,r10,r3,ror#16 + add r8,r8,r14 + mov r6,r6,ror#20 + add r9,r9,r10 + mov r7,r7,ror#20 + eor r6,r6,r8,ror#20 + eor r7,r7,r9,ror#20 + add r2,r2,r6 + mov r14,r14,ror#24 + add r3,r3,r7 + mov r10,r10,ror#24 + eor r14,r14,r2,ror#24 + eor r10,r10,r3,ror#24 + add r8,r8,r14 + mov r6,r6,ror#25 + add r9,r9,r10 + mov r7,r7,ror#25 + eor r6,r6,r8,ror#25 + eor r7,r7,r9,ror#25 + add r0,r0,r5 + mov r10,r10,ror#16 + add r1,r1,r6 + mov r12,r12,ror#16 + eor r10,r10,r0,ror#16 + eor r12,r12,r1,ror#16 + add r8,r8,r10 + mov r5,r5,ror#20 + add r9,r9,r12 + mov r6,r6,ror#20 + eor r5,r5,r8,ror#20 + eor r6,r6,r9,ror#20 + add r0,r0,r5 + mov r10,r10,ror#24 + add r1,r1,r6 + mov r12,r12,ror#24 + eor r10,r10,r0,ror#24 + eor r12,r12,r1,ror#24 + add r8,r8,r10 + mov r5,r5,ror#25 + str r10,[sp,#4*(16+15)] + ldr r10,[sp,#4*(16+13)] + add r9,r9,r12 + mov r6,r6,ror#25 + eor r5,r5,r8,ror#25 + eor r6,r6,r9,ror#25 + str r8,[sp,#4*(16+10)] + ldr r8,[sp,#4*(16+8)] + add r2,r2,r7 + mov r10,r10,ror#16 + str r9,[sp,#4*(16+11)] + ldr r9,[sp,#4*(16+9)] + add r3,r3,r4 + mov r14,r14,ror#16 + eor r10,r10,r2,ror#16 + eor r14,r14,r3,ror#16 + add r8,r8,r10 + mov r7,r7,ror#20 + add r9,r9,r14 + mov r4,r4,ror#20 + eor r7,r7,r8,ror#20 + eor r4,r4,r9,ror#20 + add r2,r2,r7 + mov r10,r10,ror#24 + add r3,r3,r4 + mov r14,r14,ror#24 + eor r10,r10,r2,ror#24 + eor r14,r14,r3,ror#24 + add r8,r8,r10 + mov r7,r7,ror#25 + add r9,r9,r14 + mov r4,r4,ror#25 + eor r7,r7,r8,ror#25 + eor r4,r4,r9,ror#25 + bne .Loop + + ldr r11,[sp,#4*(32+2)] @ load len + + str r8, [sp,#4*(16+8)] @ modulo-scheduled store + str r9, [sp,#4*(16+9)] + str r12,[sp,#4*(16+12)] + str r10, [sp,#4*(16+13)] + str r14,[sp,#4*(16+14)] + + @ at this point we have first half of 512-bit result in + @ rx and second half at sp+4*(16+8) + + cmp r11,#64 @ done yet? +#ifdef __thumb2__ + itete lo +#endif + addlo r12,sp,#4*(0) @ shortcut or ... + ldrhs r12,[sp,#4*(32+1)] @ ... load inp + addlo r14,sp,#4*(0) @ shortcut or ... + ldrhs r14,[sp,#4*(32+0)] @ ... load out + + ldr r8,[sp,#4*(0)] @ load key material + ldr r9,[sp,#4*(1)] + +#if __ARM_ARCH__>=6 || !defined(__ARMEB__) +# if __ARM_ARCH__<7 + orr r10,r12,r14 + tst r10,#3 @ are input and output aligned? + ldr r10,[sp,#4*(2)] + bne .Lunaligned + cmp r11,#64 @ restore flags +# else + ldr r10,[sp,#4*(2)] +# endif + ldr r11,[sp,#4*(3)] + + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + + add r2,r2,r10 + add r3,r3,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r0,r0,r8 @ xor with input + eorhs r1,r1,r9 + add r8,sp,#4*(4) + str r0,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r2,r2,r10 + eorhs r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r1,[r14,#-12] + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + add r6,r6,r10 + add r7,r7,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r4,r4,r8 + eorhs r5,r5,r9 + add r8,sp,#4*(8) + str r4,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r6,r6,r10 + eorhs r7,r7,r11 + str r5,[r14,#-12] + ldmia r8,{r8,r9,r10,r11} @ load key material + str r6,[r14,#-8] + add r0,sp,#4*(16+8) + str r7,[r14,#-4] + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] +# ifdef __thumb2__ + itt hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it + strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it + add r2,r2,r10 + add r3,r3,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r0,r0,r8 + eorhs r1,r1,r9 + add r8,sp,#4*(12) + str r0,[r14],#16 @ store output +# ifdef __thumb2__ + itt hs +# endif + eorhs r2,r2,r10 + eorhs r3,r3,r11 + str r1,[r14,#-12] + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 +# ifdef __thumb2__ + itt hi +# endif + addhi r8,r8,#1 @ next counter value + strhi r8,[sp,#4*(12)] @ save next counter value +# ifdef __thumb2__ + itt hs +# endif + ldrhs r8,[r12],#16 @ load input + ldrhs r9,[r12,#-12] + add r6,r6,r10 + add r7,r7,r11 +# ifdef __thumb2__ + itt hs +# endif + ldrhs r10,[r12,#-8] + ldrhs r11,[r12,#-4] +# if __ARM_ARCH__>=6 && defined(__ARMEB__) + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif +# ifdef __thumb2__ + itt hs +# endif + eorhs r4,r4,r8 + eorhs r5,r5,r9 +# ifdef __thumb2__ + it ne +# endif + ldrne r8,[sp,#4*(32+2)] @ re-load len +# ifdef __thumb2__ + itt hs +# endif + eorhs r6,r6,r10 + eorhs r7,r7,r11 + str r4,[r14],#16 @ store output + str r5,[r14,#-12] +# ifdef __thumb2__ + it hs +# endif + subhs r11,r8,#64 @ len-=64 + str r6,[r14,#-8] + str r7,[r14,#-4] + bhi .Loop_outer + + beq .Ldone +# if __ARM_ARCH__<7 + b .Ltail + +.align 4 +.Lunaligned:@ unaligned endian-neutral path + cmp r11,#64 @ restore flags +# endif +#endif +#if __ARM_ARCH__<7 + ldr r11,[sp,#4*(3)] + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 + add r2,r2,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r3,r3,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r0,r8,r0 @ xor with input (or zero) + eor r1,r9,r1 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r2,r10,r2 + strb r0,[r14],#16 @ store output + eor r3,r11,r3 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r1,[r14,#-12] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-8] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r3,[r14,#-4] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-15] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r1,[r14,#-11] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-7] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r3,[r14,#-3] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-14] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r1,[r14,#-10] + strb r2,[r14,#-6] + eor r0,r8,r0,lsr#8 + strb r3,[r14,#-2] + eor r1,r9,r1,lsr#8 + strb r0,[r14,#-13] + eor r2,r10,r2,lsr#8 + strb r1,[r14,#-9] + eor r3,r11,r3,lsr#8 + strb r2,[r14,#-5] + strb r3,[r14,#-1] + add r8,sp,#4*(4+0) + ldmia r8,{r8,r9,r10,r11} @ load key material + add r0,sp,#4*(16+8) + add r4,r4,r8 @ accumulate key material + add r5,r5,r9 + add r6,r6,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r7,r7,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r4,r8,r4 @ xor with input (or zero) + eor r5,r9,r5 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r6,r10,r6 + strb r4,[r14],#16 @ store output + eor r7,r11,r7 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r5,[r14,#-12] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-8] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r7,[r14,#-4] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-15] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r5,[r14,#-11] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-7] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r7,[r14,#-3] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-14] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r5,[r14,#-10] + strb r6,[r14,#-6] + eor r4,r8,r4,lsr#8 + strb r7,[r14,#-2] + eor r5,r9,r5,lsr#8 + strb r4,[r14,#-13] + eor r6,r10,r6,lsr#8 + strb r5,[r14,#-9] + eor r7,r11,r7,lsr#8 + strb r6,[r14,#-5] + strb r7,[r14,#-1] + add r8,sp,#4*(4+4) + ldmia r8,{r8,r9,r10,r11} @ load key material + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half +# ifdef __thumb2__ + itt hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" + strhi r11,[sp,#4*(16+11)] @ copy "rx" + add r0,r0,r8 @ accumulate key material + add r1,r1,r9 + add r2,r2,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r3,r3,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r0,r8,r0 @ xor with input (or zero) + eor r1,r9,r1 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r2,r10,r2 + strb r0,[r14],#16 @ store output + eor r3,r11,r3 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r1,[r14,#-12] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-8] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r3,[r14,#-4] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-15] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r1,[r14,#-11] + eor r0,r8,r0,lsr#8 + strb r2,[r14,#-7] + eor r1,r9,r1,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r3,[r14,#-3] + eor r2,r10,r2,lsr#8 + strb r0,[r14,#-14] + eor r3,r11,r3,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r1,[r14,#-10] + strb r2,[r14,#-6] + eor r0,r8,r0,lsr#8 + strb r3,[r14,#-2] + eor r1,r9,r1,lsr#8 + strb r0,[r14,#-13] + eor r2,r10,r2,lsr#8 + strb r1,[r14,#-9] + eor r3,r11,r3,lsr#8 + strb r2,[r14,#-5] + strb r3,[r14,#-1] + add r8,sp,#4*(4+8) + ldmia r8,{r8,r9,r10,r11} @ load key material + add r4,r4,r8 @ accumulate key material +# ifdef __thumb2__ + itt hi +# endif + addhi r8,r8,#1 @ next counter value + strhi r8,[sp,#4*(12)] @ save next counter value + add r5,r5,r9 + add r6,r6,r10 +# ifdef __thumb2__ + itete lo +# endif + eorlo r8,r8,r8 @ zero or ... + ldrhsb r8,[r12],#16 @ ... load input + eorlo r9,r9,r9 + ldrhsb r9,[r12,#-12] + + add r7,r7,r11 +# ifdef __thumb2__ + itete lo +# endif + eorlo r10,r10,r10 + ldrhsb r10,[r12,#-8] + eorlo r11,r11,r11 + ldrhsb r11,[r12,#-4] + + eor r4,r8,r4 @ xor with input (or zero) + eor r5,r9,r5 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-15] @ load more input + ldrhsb r9,[r12,#-11] + eor r6,r10,r6 + strb r4,[r14],#16 @ store output + eor r7,r11,r7 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-7] + ldrhsb r11,[r12,#-3] + strb r5,[r14,#-12] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-8] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-14] @ load more input + ldrhsb r9,[r12,#-10] + strb r7,[r14,#-4] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-15] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-6] + ldrhsb r11,[r12,#-2] + strb r5,[r14,#-11] + eor r4,r8,r4,lsr#8 + strb r6,[r14,#-7] + eor r5,r9,r5,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r8,[r12,#-13] @ load more input + ldrhsb r9,[r12,#-9] + strb r7,[r14,#-3] + eor r6,r10,r6,lsr#8 + strb r4,[r14,#-14] + eor r7,r11,r7,lsr#8 +# ifdef __thumb2__ + itt hs +# endif + ldrhsb r10,[r12,#-5] + ldrhsb r11,[r12,#-1] + strb r5,[r14,#-10] + strb r6,[r14,#-6] + eor r4,r8,r4,lsr#8 + strb r7,[r14,#-2] + eor r5,r9,r5,lsr#8 + strb r4,[r14,#-13] + eor r6,r10,r6,lsr#8 + strb r5,[r14,#-9] + eor r7,r11,r7,lsr#8 + strb r6,[r14,#-5] + strb r7,[r14,#-1] +# ifdef __thumb2__ + it ne +# endif + ldrne r8,[sp,#4*(32+2)] @ re-load len +# ifdef __thumb2__ + it hs +# endif + subhs r11,r8,#64 @ len-=64 + bhi .Loop_outer + + beq .Ldone +#endif + +.Ltail: + ldr r12,[sp,#4*(32+1)] @ load inp + add r9,sp,#4*(0) + ldr r14,[sp,#4*(32+0)] @ load out + +.Loop_tail: + ldrb r10,[r9],#1 @ read buffer on stack + ldrb r11,[r12],#1 @ read input + subs r8,r8,#1 + eor r11,r11,r10 + strb r11,[r14],#1 @ store output + bne .Loop_tail + +.Ldone: + add sp,sp,#4*(32+3) +.Lno_data: + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} +.size ChaCha20_ctr32,.-ChaCha20_ctr32 +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.type ChaCha20_neon,%function +.align 5 +ChaCha20_neon: + ldr r12,[sp,#0] @ pull pointer to counter and nonce + stmdb sp!,{r0,r1,r2,r4-r11,lr} +.LChaCha20_neon: + adr r14,.Lsigma + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI spec says so + stmdb sp!,{r0,r1,r2,r3} + + vld1.32 {q1,q2},[r3] @ load key + ldmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} @ load key + + sub sp,sp,#4*(16+16) + vld1.32 {q3},[r12] @ load counter and nonce + add r12,sp,#4*8 + ldmia r14,{r0,r1,r2,r3} @ load sigma + vld1.32 {q0},[r14]! @ load sigma + vld1.32 {q12},[r14] @ one + vst1.32 {q2,q3},[r12] @ copy 1/2key|counter|nonce + vst1.32 {q0,q1},[sp] @ copy sigma|1/2key + + str r10,[sp,#4*(16+10)] @ off-load "rx" + str r11,[sp,#4*(16+11)] @ off-load "rx" + vshl.i32 d26,d24,#1 @ two + vstr d24,[sp,#4*(16+0)] + vshl.i32 d28,d24,#2 @ four + vstr d26,[sp,#4*(16+2)] + vmov q4,q0 + vstr d28,[sp,#4*(16+4)] + vmov q8,q0 + vmov q5,q1 + vmov q9,q1 + b .Loop_neon_enter + +.align 4 +.Loop_neon_outer: + ldmia sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9} @ load key material + cmp r11,#64*2 @ if len<=64*2 + bls .Lbreak_neon @ switch to integer-only + vmov q4,q0 + str r11,[sp,#4*(32+2)] @ save len + vmov q8,q0 + str r12, [sp,#4*(32+1)] @ save inp + vmov q5,q1 + str r14, [sp,#4*(32+0)] @ save out + vmov q9,q1 +.Loop_neon_enter: + ldr r11, [sp,#4*(15)] + vadd.i32 q7,q3,q12 @ counter+1 + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + vmov q6,q2 + ldr r10, [sp,#4*(13)] + vmov q10,q2 + ldr r14,[sp,#4*(14)] + vadd.i32 q11,q7,q12 @ counter+2 + str r11, [sp,#4*(16+15)] + mov r11,#10 + add r12,r12,#3 @ counter+3 + b .Loop_neon + +.align 4 +.Loop_neon: + subs r11,r11,#1 + vadd.i32 q0,q0,q1 + add r0,r0,r4 + vadd.i32 q4,q4,q5 + mov r12,r12,ror#16 + vadd.i32 q8,q8,q9 + add r1,r1,r5 + veor q3,q3,q0 + mov r10,r10,ror#16 + veor q7,q7,q4 + eor r12,r12,r0,ror#16 + veor q11,q11,q8 + eor r10,r10,r1,ror#16 + vrev32.16 q3,q3 + add r8,r8,r12 + vrev32.16 q7,q7 + mov r4,r4,ror#20 + vrev32.16 q11,q11 + add r9,r9,r10 + vadd.i32 q2,q2,q3 + mov r5,r5,ror#20 + vadd.i32 q6,q6,q7 + eor r4,r4,r8,ror#20 + vadd.i32 q10,q10,q11 + eor r5,r5,r9,ror#20 + veor q12,q1,q2 + add r0,r0,r4 + veor q13,q5,q6 + mov r12,r12,ror#24 + veor q14,q9,q10 + add r1,r1,r5 + vshr.u32 q1,q12,#20 + mov r10,r10,ror#24 + vshr.u32 q5,q13,#20 + eor r12,r12,r0,ror#24 + vshr.u32 q9,q14,#20 + eor r10,r10,r1,ror#24 + vsli.32 q1,q12,#12 + add r8,r8,r12 + vsli.32 q5,q13,#12 + mov r4,r4,ror#25 + vsli.32 q9,q14,#12 + add r9,r9,r10 + vadd.i32 q0,q0,q1 + mov r5,r5,ror#25 + vadd.i32 q4,q4,q5 + str r10,[sp,#4*(16+13)] + vadd.i32 q8,q8,q9 + ldr r10,[sp,#4*(16+15)] + veor q12,q3,q0 + eor r4,r4,r8,ror#25 + veor q13,q7,q4 + eor r5,r5,r9,ror#25 + veor q14,q11,q8 + str r8,[sp,#4*(16+8)] + vshr.u32 q3,q12,#24 + ldr r8,[sp,#4*(16+10)] + vshr.u32 q7,q13,#24 + add r2,r2,r6 + vshr.u32 q11,q14,#24 + mov r14,r14,ror#16 + vsli.32 q3,q12,#8 + str r9,[sp,#4*(16+9)] + vsli.32 q7,q13,#8 + ldr r9,[sp,#4*(16+11)] + vsli.32 q11,q14,#8 + add r3,r3,r7 + vadd.i32 q2,q2,q3 + mov r10,r10,ror#16 + vadd.i32 q6,q6,q7 + eor r14,r14,r2,ror#16 + vadd.i32 q10,q10,q11 + eor r10,r10,r3,ror#16 + veor q12,q1,q2 + add r8,r8,r14 + veor q13,q5,q6 + mov r6,r6,ror#20 + veor q14,q9,q10 + add r9,r9,r10 + vshr.u32 q1,q12,#25 + mov r7,r7,ror#20 + vshr.u32 q5,q13,#25 + eor r6,r6,r8,ror#20 + vshr.u32 q9,q14,#25 + eor r7,r7,r9,ror#20 + vsli.32 q1,q12,#7 + add r2,r2,r6 + vsli.32 q5,q13,#7 + mov r14,r14,ror#24 + vsli.32 q9,q14,#7 + add r3,r3,r7 + vext.8 q2,q2,q2,#8 + mov r10,r10,ror#24 + vext.8 q6,q6,q6,#8 + eor r14,r14,r2,ror#24 + vext.8 q10,q10,q10,#8 + eor r10,r10,r3,ror#24 + vext.8 q1,q1,q1,#4 + add r8,r8,r14 + vext.8 q5,q5,q5,#4 + mov r6,r6,ror#25 + vext.8 q9,q9,q9,#4 + add r9,r9,r10 + vext.8 q3,q3,q3,#12 + mov r7,r7,ror#25 + vext.8 q7,q7,q7,#12 + eor r6,r6,r8,ror#25 + vext.8 q11,q11,q11,#12 + eor r7,r7,r9,ror#25 + vadd.i32 q0,q0,q1 + add r0,r0,r5 + vadd.i32 q4,q4,q5 + mov r10,r10,ror#16 + vadd.i32 q8,q8,q9 + add r1,r1,r6 + veor q3,q3,q0 + mov r12,r12,ror#16 + veor q7,q7,q4 + eor r10,r10,r0,ror#16 + veor q11,q11,q8 + eor r12,r12,r1,ror#16 + vrev32.16 q3,q3 + add r8,r8,r10 + vrev32.16 q7,q7 + mov r5,r5,ror#20 + vrev32.16 q11,q11 + add r9,r9,r12 + vadd.i32 q2,q2,q3 + mov r6,r6,ror#20 + vadd.i32 q6,q6,q7 + eor r5,r5,r8,ror#20 + vadd.i32 q10,q10,q11 + eor r6,r6,r9,ror#20 + veor q12,q1,q2 + add r0,r0,r5 + veor q13,q5,q6 + mov r10,r10,ror#24 + veor q14,q9,q10 + add r1,r1,r6 + vshr.u32 q1,q12,#20 + mov r12,r12,ror#24 + vshr.u32 q5,q13,#20 + eor r10,r10,r0,ror#24 + vshr.u32 q9,q14,#20 + eor r12,r12,r1,ror#24 + vsli.32 q1,q12,#12 + add r8,r8,r10 + vsli.32 q5,q13,#12 + mov r5,r5,ror#25 + vsli.32 q9,q14,#12 + str r10,[sp,#4*(16+15)] + vadd.i32 q0,q0,q1 + ldr r10,[sp,#4*(16+13)] + vadd.i32 q4,q4,q5 + add r9,r9,r12 + vadd.i32 q8,q8,q9 + mov r6,r6,ror#25 + veor q12,q3,q0 + eor r5,r5,r8,ror#25 + veor q13,q7,q4 + eor r6,r6,r9,ror#25 + veor q14,q11,q8 + str r8,[sp,#4*(16+10)] + vshr.u32 q3,q12,#24 + ldr r8,[sp,#4*(16+8)] + vshr.u32 q7,q13,#24 + add r2,r2,r7 + vshr.u32 q11,q14,#24 + mov r10,r10,ror#16 + vsli.32 q3,q12,#8 + str r9,[sp,#4*(16+11)] + vsli.32 q7,q13,#8 + ldr r9,[sp,#4*(16+9)] + vsli.32 q11,q14,#8 + add r3,r3,r4 + vadd.i32 q2,q2,q3 + mov r14,r14,ror#16 + vadd.i32 q6,q6,q7 + eor r10,r10,r2,ror#16 + vadd.i32 q10,q10,q11 + eor r14,r14,r3,ror#16 + veor q12,q1,q2 + add r8,r8,r10 + veor q13,q5,q6 + mov r7,r7,ror#20 + veor q14,q9,q10 + add r9,r9,r14 + vshr.u32 q1,q12,#25 + mov r4,r4,ror#20 + vshr.u32 q5,q13,#25 + eor r7,r7,r8,ror#20 + vshr.u32 q9,q14,#25 + eor r4,r4,r9,ror#20 + vsli.32 q1,q12,#7 + add r2,r2,r7 + vsli.32 q5,q13,#7 + mov r10,r10,ror#24 + vsli.32 q9,q14,#7 + add r3,r3,r4 + vext.8 q2,q2,q2,#8 + mov r14,r14,ror#24 + vext.8 q6,q6,q6,#8 + eor r10,r10,r2,ror#24 + vext.8 q10,q10,q10,#8 + eor r14,r14,r3,ror#24 + vext.8 q1,q1,q1,#12 + add r8,r8,r10 + vext.8 q5,q5,q5,#12 + mov r7,r7,ror#25 + vext.8 q9,q9,q9,#12 + add r9,r9,r14 + vext.8 q3,q3,q3,#4 + mov r4,r4,ror#25 + vext.8 q7,q7,q7,#4 + eor r7,r7,r8,ror#25 + vext.8 q11,q11,q11,#4 + eor r4,r4,r9,ror#25 + bne .Loop_neon + + add r11,sp,#32 + vld1.32 {q12,q13},[sp] @ load key material + vld1.32 {q14,q15},[r11] + + ldr r11,[sp,#4*(32+2)] @ load len + + str r8, [sp,#4*(16+8)] @ modulo-scheduled store + str r9, [sp,#4*(16+9)] + str r12,[sp,#4*(16+12)] + str r10, [sp,#4*(16+13)] + str r14,[sp,#4*(16+14)] + + @ at this point we have first half of 512-bit result in + @ rx and second half at sp+4*(16+8) + + ldr r12,[sp,#4*(32+1)] @ load inp + ldr r14,[sp,#4*(32+0)] @ load out + + vadd.i32 q0,q0,q12 @ accumulate key material + vadd.i32 q4,q4,q12 + vadd.i32 q8,q8,q12 + vldr d24,[sp,#4*(16+0)] @ one + + vadd.i32 q1,q1,q13 + vadd.i32 q5,q5,q13 + vadd.i32 q9,q9,q13 + vldr d26,[sp,#4*(16+2)] @ two + + vadd.i32 q2,q2,q14 + vadd.i32 q6,q6,q14 + vadd.i32 q10,q10,q14 + vadd.i32 d14,d14,d24 @ counter+1 + vadd.i32 d22,d22,d26 @ counter+2 + + vadd.i32 q3,q3,q15 + vadd.i32 q7,q7,q15 + vadd.i32 q11,q11,q15 + + cmp r11,#64*4 + blo .Ltail_neon + + vld1.8 {q12,q13},[r12]! @ load input + mov r11,sp + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 @ xor with input + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + vst1.8 {q0,q1},[r14]! @ store output + veor q5,q5,q13 + vld1.8 {q12,q13},[r12]! + veor q6,q6,q14 + vst1.8 {q2,q3},[r14]! + veor q7,q7,q15 + vld1.8 {q14,q15},[r12]! + + veor q8,q8,q12 + vld1.32 {q0,q1},[r11]! @ load for next iteration + veor d25,d25,d25 + vldr d24,[sp,#4*(16+4)] @ four + veor q9,q9,q13 + vld1.32 {q2,q3},[r11] + veor q10,q10,q14 + vst1.8 {q4,q5},[r14]! + veor q11,q11,q15 + vst1.8 {q6,q7},[r14]! + + vadd.i32 d6,d6,d24 @ next counter value + vldr d24,[sp,#4*(16+0)] @ one + + ldmia sp,{r8,r9,r10,r11} @ load key material + add r0,r0,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + vst1.8 {q8,q9},[r14]! + add r1,r1,r9 + ldr r9,[r12,#-12] + vst1.8 {q10,q11},[r14]! + add r2,r2,r10 + ldr r10,[r12,#-8] + add r3,r3,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif + eor r0,r0,r8 @ xor with input + add r8,sp,#4*(4) + eor r1,r1,r9 + str r0,[r14],#16 @ store output + eor r2,r2,r10 + str r1,[r14,#-12] + eor r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + add r5,r5,r9 + ldr r9,[r12,#-12] + add r6,r6,r10 + ldr r10,[r12,#-8] + add r7,r7,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + eor r4,r4,r8 + add r8,sp,#4*(8) + eor r5,r5,r9 + str r4,[r14],#16 @ store output + eor r6,r6,r10 + str r5,[r14,#-12] + eor r7,r7,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r6,[r14,#-8] + add r0,sp,#4*(16+8) + str r7,[r14,#-4] + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + ldr r8,[r12],#16 @ load input + add r1,r1,r9 + ldr r9,[r12,#-12] +# ifdef __thumb2__ + it hi +# endif + strhi r10,[sp,#4*(16+10)] @ copy "rx" while at it + add r2,r2,r10 + ldr r10,[r12,#-8] +# ifdef __thumb2__ + it hi +# endif + strhi r11,[sp,#4*(16+11)] @ copy "rx" while at it + add r3,r3,r11 + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 +# endif + eor r0,r0,r8 + add r8,sp,#4*(12) + eor r1,r1,r9 + str r0,[r14],#16 @ store output + eor r2,r2,r10 + str r1,[r14,#-12] + eor r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + str r2,[r14,#-8] + str r3,[r14,#-4] + + add r4,r4,r8 @ accumulate key material + add r8,r8,#4 @ next counter value + add r5,r5,r9 + str r8,[sp,#4*(12)] @ save next counter value + ldr r8,[r12],#16 @ load input + add r6,r6,r10 + add r4,r4,#3 @ counter+3 + ldr r9,[r12,#-12] + add r7,r7,r11 + ldr r10,[r12,#-8] + ldr r11,[r12,#-4] +# ifdef __ARMEB__ + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + eor r4,r4,r8 +# ifdef __thumb2__ + it hi +# endif + ldrhi r8,[sp,#4*(32+2)] @ re-load len + eor r5,r5,r9 + eor r6,r6,r10 + str r4,[r14],#16 @ store output + eor r7,r7,r11 + str r5,[r14,#-12] + sub r11,r8,#64*4 @ len-=64*4 + str r6,[r14,#-8] + str r7,[r14,#-4] + bhi .Loop_neon_outer + + b .Ldone_neon + +.align 4 +.Lbreak_neon: + @ harmonize NEON and integer-only stack frames: load data + @ from NEON frame, but save to integer-only one; distance + @ between the two is 4*(32+4+16-32)=4*(20). + + str r11, [sp,#4*(20+32+2)] @ save len + add r11,sp,#4*(32+4) + str r12, [sp,#4*(20+32+1)] @ save inp + str r14, [sp,#4*(20+32+0)] @ save out + + ldr r12,[sp,#4*(16+10)] + ldr r14,[sp,#4*(16+11)] + vldmia r11,{d8,d9,d10,d11,d12,d13,d14,d15} @ fulfill ABI requirement + str r12,[sp,#4*(20+16+10)] @ copy "rx" + str r14,[sp,#4*(20+16+11)] @ copy "rx" + + ldr r11, [sp,#4*(15)] + ldr r12,[sp,#4*(12)] @ modulo-scheduled load + ldr r10, [sp,#4*(13)] + ldr r14,[sp,#4*(14)] + str r11, [sp,#4*(20+16+15)] + add r11,sp,#4*(20) + vst1.32 {q0,q1},[r11]! @ copy key + add sp,sp,#4*(20) @ switch frame + vst1.32 {q2,q3},[r11] + mov r11,#10 + b .Loop @ go integer-only + +.align 4 +.Ltail_neon: + cmp r11,#64*3 + bhs .L192_or_more_neon + cmp r11,#64*2 + bhs .L128_or_more_neon + cmp r11,#64*1 + bhs .L64_or_more_neon + + add r8,sp,#4*(8) + vst1.8 {q0,q1},[sp] + add r10,sp,#4*(0) + vst1.8 {q2,q3},[r8] + b .Loop_tail_neon + +.align 4 +.L64_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + veor q2,q2,q14 + veor q3,q3,q15 + vst1.8 {q0,q1},[r14]! + vst1.8 {q2,q3},[r14]! + + beq .Ldone_neon + + add r8,sp,#4*(8) + vst1.8 {q4,q5},[sp] + add r10,sp,#4*(0) + vst1.8 {q6,q7},[r8] + sub r11,r11,#64*1 @ len-=64*1 + b .Loop_tail_neon + +.align 4 +.L128_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + veor q5,q5,q13 + vst1.8 {q0,q1},[r14]! + veor q6,q6,q14 + vst1.8 {q2,q3},[r14]! + veor q7,q7,q15 + vst1.8 {q4,q5},[r14]! + vst1.8 {q6,q7},[r14]! + + beq .Ldone_neon + + add r8,sp,#4*(8) + vst1.8 {q8,q9},[sp] + add r10,sp,#4*(0) + vst1.8 {q10,q11},[r8] + sub r11,r11,#64*2 @ len-=64*2 + b .Loop_tail_neon + +.align 4 +.L192_or_more_neon: + vld1.8 {q12,q13},[r12]! + vld1.8 {q14,q15},[r12]! + veor q0,q0,q12 + veor q1,q1,q13 + vld1.8 {q12,q13},[r12]! + veor q2,q2,q14 + veor q3,q3,q15 + vld1.8 {q14,q15},[r12]! + + veor q4,q4,q12 + veor q5,q5,q13 + vld1.8 {q12,q13},[r12]! + veor q6,q6,q14 + vst1.8 {q0,q1},[r14]! + veor q7,q7,q15 + vld1.8 {q14,q15},[r12]! + + veor q8,q8,q12 + vst1.8 {q2,q3},[r14]! + veor q9,q9,q13 + vst1.8 {q4,q5},[r14]! + veor q10,q10,q14 + vst1.8 {q6,q7},[r14]! + veor q11,q11,q15 + vst1.8 {q8,q9},[r14]! + vst1.8 {q10,q11},[r14]! + + beq .Ldone_neon + + ldmia sp,{r8,r9,r10,r11} @ load key material + add r0,r0,r8 @ accumulate key material + add r8,sp,#4*(4) + add r1,r1,r9 + add r2,r2,r10 + add r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + + add r4,r4,r8 @ accumulate key material + add r8,sp,#4*(8) + add r5,r5,r9 + add r6,r6,r10 + add r7,r7,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + stmia sp,{r0,r1,r2,r3,r4,r5,r6,r7} + add r0,sp,#4*(16+8) + + ldmia r0,{r0,r1,r2,r3,r4,r5,r6,r7} @ load second half + + add r0,r0,r8 @ accumulate key material + add r8,sp,#4*(12) + add r1,r1,r9 + add r2,r2,r10 + add r3,r3,r11 + ldmia r8,{r8,r9,r10,r11} @ load key material + + add r4,r4,r8 @ accumulate key material + add r8,sp,#4*(8) + add r5,r5,r9 + add r4,r4,#3 @ counter+3 + add r6,r6,r10 + add r7,r7,r11 + ldr r11,[sp,#4*(32+2)] @ re-load len +# ifdef __ARMEB__ + rev r0,r0 + rev r1,r1 + rev r2,r2 + rev r3,r3 + rev r4,r4 + rev r5,r5 + rev r6,r6 + rev r7,r7 +# endif + stmia r8,{r0,r1,r2,r3,r4,r5,r6,r7} + add r10,sp,#4*(0) + sub r11,r11,#64*3 @ len-=64*3 + +.Loop_tail_neon: + ldrb r8,[r10],#1 @ read buffer on stack + ldrb r9,[r12],#1 @ read input + subs r11,r11,#1 + eor r8,r8,r9 + strb r8,[r14],#1 @ store output + bne .Loop_tail_neon + +.Ldone_neon: + add sp,sp,#4*(32+4) + vldmia sp,{d8,d9,d10,d11,d12,d13,d14,d15} + add sp,sp,#4*(16+3) + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} +.size ChaCha20_neon,.-ChaCha20_neon +.comm OPENSSL_armcap_P,4,4 +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S new file mode 100644 index 00000000..22a2fae5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S @@ -0,0 +1,1999 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + + +.private_extern _OPENSSL_armcap_P + +.section __TEXT,__const + +.align 5 +Lsigma: +.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral +Lone: +.long 1,0,0,0 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +.text + +.globl _ChaCha20_ctr32 +.private_extern _ChaCha20_ctr32 + +.align 5 +_ChaCha20_ctr32: + AARCH64_VALID_CALL_TARGET + cbz x2,Labort +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x5,:pg_hi21_nc:_OPENSSL_armcap_P +#else + adrp x5,_OPENSSL_armcap_P@PAGE +#endif + cmp x2,#192 + b.lo Lshort + ldr w17,[x5,_OPENSSL_armcap_P@PAGEOFF] + tst w17,#ARMV7_NEON + b.ne ChaCha20_neon + +Lshort: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,Lsigma@PAGE + add x5,x5,Lsigma@PAGEOFF + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ldp x28,x30,[x4] // load counter +#ifdef __AARCH64EB__ + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + +Loop_outer: + mov w5,w22 // unpack key block + lsr x6,x22,#32 + mov w7,w23 + lsr x8,x23,#32 + mov w9,w24 + lsr x10,x24,#32 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#10 + subs x2,x2,#64 +Loop: + sub x4,x4,#1 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + ror w21,w21,#16 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#20 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + ror w21,w21,#24 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#25 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#16 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + ror w9,w9,#20 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#24 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + ror w9,w9,#25 + cbnz x4,Loop + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + b.lo Ltail + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + + b.hi Loop_outer + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER +Labort: + ret + +.align 4 +Ltail: + add x2,x2,#64 +Less_than_64: + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + stp x5,x7,[sp,#0] + stp x9,x11,[sp,#16] + stp x13,x15,[sp,#32] + stp x17,x20,[sp,#48] + +Loop_tail: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,Loop_tail + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + + + +.align 5 +ChaCha20_neon: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,Lsigma@PAGE + add x5,x5,Lsigma@PAGEOFF + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + cmp x2,#512 + b.hs L512_or_more_neon + + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ld1 {v24.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v25.4s,v26.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v27.4s},[x4] + ld1 {v31.4s},[x5] +#ifdef __AARCH64EB__ + rev64 v24.4s,v24.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + add v27.4s,v27.4s,v31.4s // += 1 + add v28.4s,v27.4s,v31.4s + add v29.4s,v28.4s,v31.4s + shl v31.4s,v31.4s,#2 // 1 -> 4 + +Loop_outer_neon: + mov w5,w22 // unpack key block + lsr x6,x22,#32 + mov v0.16b,v24.16b + mov w7,w23 + lsr x8,x23,#32 + mov v4.16b,v24.16b + mov w9,w24 + lsr x10,x24,#32 + mov v16.16b,v24.16b + mov w11,w25 + mov v1.16b,v25.16b + lsr x12,x25,#32 + mov v5.16b,v25.16b + mov w13,w26 + mov v17.16b,v25.16b + lsr x14,x26,#32 + mov v3.16b,v27.16b + mov w15,w27 + mov v7.16b,v28.16b + lsr x16,x27,#32 + mov v19.16b,v29.16b + mov w17,w28 + mov v2.16b,v26.16b + lsr x19,x28,#32 + mov v6.16b,v26.16b + mov w20,w30 + mov v18.16b,v26.16b + lsr x21,x30,#32 + + mov x4,#10 + subs x2,x2,#256 +Loop_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + eor v3.16b,v3.16b,v0.16b + add w8,w8,w12 + eor v7.16b,v7.16b,v4.16b + eor w17,w17,w5 + eor v19.16b,v19.16b,v16.16b + eor w19,w19,w6 + rev32 v3.8h,v3.8h + eor w20,w20,w7 + rev32 v7.8h,v7.8h + eor w21,w21,w8 + rev32 v19.8h,v19.8h + ror w17,w17,#16 + add v2.4s,v2.4s,v3.4s + ror w19,w19,#16 + add v6.4s,v6.4s,v7.4s + ror w20,w20,#16 + add v18.4s,v18.4s,v19.4s + ror w21,w21,#16 + eor v20.16b,v1.16b,v2.16b + add w13,w13,w17 + eor v21.16b,v5.16b,v6.16b + add w14,w14,w19 + eor v22.16b,v17.16b,v18.16b + add w15,w15,w20 + ushr v1.4s,v20.4s,#20 + add w16,w16,w21 + ushr v5.4s,v21.4s,#20 + eor w9,w9,w13 + ushr v17.4s,v22.4s,#20 + eor w10,w10,w14 + sli v1.4s,v20.4s,#12 + eor w11,w11,w15 + sli v5.4s,v21.4s,#12 + eor w12,w12,w16 + sli v17.4s,v22.4s,#12 + ror w9,w9,#20 + add v0.4s,v0.4s,v1.4s + ror w10,w10,#20 + add v4.4s,v4.4s,v5.4s + ror w11,w11,#20 + add v16.4s,v16.4s,v17.4s + ror w12,w12,#20 + eor v20.16b,v3.16b,v0.16b + add w5,w5,w9 + eor v21.16b,v7.16b,v4.16b + add w6,w6,w10 + eor v22.16b,v19.16b,v16.16b + add w7,w7,w11 + ushr v3.4s,v20.4s,#24 + add w8,w8,w12 + ushr v7.4s,v21.4s,#24 + eor w17,w17,w5 + ushr v19.4s,v22.4s,#24 + eor w19,w19,w6 + sli v3.4s,v20.4s,#8 + eor w20,w20,w7 + sli v7.4s,v21.4s,#8 + eor w21,w21,w8 + sli v19.4s,v22.4s,#8 + ror w17,w17,#24 + add v2.4s,v2.4s,v3.4s + ror w19,w19,#24 + add v6.4s,v6.4s,v7.4s + ror w20,w20,#24 + add v18.4s,v18.4s,v19.4s + ror w21,w21,#24 + eor v20.16b,v1.16b,v2.16b + add w13,w13,w17 + eor v21.16b,v5.16b,v6.16b + add w14,w14,w19 + eor v22.16b,v17.16b,v18.16b + add w15,w15,w20 + ushr v1.4s,v20.4s,#25 + add w16,w16,w21 + ushr v5.4s,v21.4s,#25 + eor w9,w9,w13 + ushr v17.4s,v22.4s,#25 + eor w10,w10,w14 + sli v1.4s,v20.4s,#7 + eor w11,w11,w15 + sli v5.4s,v21.4s,#7 + eor w12,w12,w16 + sli v17.4s,v22.4s,#7 + ror w9,w9,#25 + ext v2.16b,v2.16b,v2.16b,#8 + ror w10,w10,#25 + ext v6.16b,v6.16b,v6.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w10 + add v4.4s,v4.4s,v5.4s + add w6,w6,w11 + add v16.4s,v16.4s,v17.4s + add w7,w7,w12 + eor v3.16b,v3.16b,v0.16b + add w8,w8,w9 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w5 + eor v19.16b,v19.16b,v16.16b + eor w17,w17,w6 + rev32 v3.8h,v3.8h + eor w19,w19,w7 + rev32 v7.8h,v7.8h + eor w20,w20,w8 + rev32 v19.8h,v19.8h + ror w21,w21,#16 + add v2.4s,v2.4s,v3.4s + ror w17,w17,#16 + add v6.4s,v6.4s,v7.4s + ror w19,w19,#16 + add v18.4s,v18.4s,v19.4s + ror w20,w20,#16 + eor v20.16b,v1.16b,v2.16b + add w15,w15,w21 + eor v21.16b,v5.16b,v6.16b + add w16,w16,w17 + eor v22.16b,v17.16b,v18.16b + add w13,w13,w19 + ushr v1.4s,v20.4s,#20 + add w14,w14,w20 + ushr v5.4s,v21.4s,#20 + eor w10,w10,w15 + ushr v17.4s,v22.4s,#20 + eor w11,w11,w16 + sli v1.4s,v20.4s,#12 + eor w12,w12,w13 + sli v5.4s,v21.4s,#12 + eor w9,w9,w14 + sli v17.4s,v22.4s,#12 + ror w10,w10,#20 + add v0.4s,v0.4s,v1.4s + ror w11,w11,#20 + add v4.4s,v4.4s,v5.4s + ror w12,w12,#20 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#20 + eor v20.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v21.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v22.16b,v19.16b,v16.16b + add w7,w7,w12 + ushr v3.4s,v20.4s,#24 + add w8,w8,w9 + ushr v7.4s,v21.4s,#24 + eor w21,w21,w5 + ushr v19.4s,v22.4s,#24 + eor w17,w17,w6 + sli v3.4s,v20.4s,#8 + eor w19,w19,w7 + sli v7.4s,v21.4s,#8 + eor w20,w20,w8 + sli v19.4s,v22.4s,#8 + ror w21,w21,#24 + add v2.4s,v2.4s,v3.4s + ror w17,w17,#24 + add v6.4s,v6.4s,v7.4s + ror w19,w19,#24 + add v18.4s,v18.4s,v19.4s + ror w20,w20,#24 + eor v20.16b,v1.16b,v2.16b + add w15,w15,w21 + eor v21.16b,v5.16b,v6.16b + add w16,w16,w17 + eor v22.16b,v17.16b,v18.16b + add w13,w13,w19 + ushr v1.4s,v20.4s,#25 + add w14,w14,w20 + ushr v5.4s,v21.4s,#25 + eor w10,w10,w15 + ushr v17.4s,v22.4s,#25 + eor w11,w11,w16 + sli v1.4s,v20.4s,#7 + eor w12,w12,w13 + sli v5.4s,v21.4s,#7 + eor w9,w9,w14 + sli v17.4s,v22.4s,#7 + ror w10,w10,#25 + ext v2.16b,v2.16b,v2.16b,#8 + ror w11,w11,#25 + ext v6.16b,v6.16b,v6.16b,#8 + ror w12,w12,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + cbnz x4,Loop_neon + + add w5,w5,w22 // accumulate key block + add v0.4s,v0.4s,v24.4s + add x6,x6,x22,lsr#32 + add v4.4s,v4.4s,v24.4s + add w7,w7,w23 + add v16.4s,v16.4s,v24.4s + add x8,x8,x23,lsr#32 + add v2.4s,v2.4s,v26.4s + add w9,w9,w24 + add v6.4s,v6.4s,v26.4s + add x10,x10,x24,lsr#32 + add v18.4s,v18.4s,v26.4s + add w11,w11,w25 + add v3.4s,v3.4s,v27.4s + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add v7.4s,v7.4s,v28.4s + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add v19.4s,v19.4s,v29.4s + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add v1.4s,v1.4s,v25.4s + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add v5.4s,v5.4s,v25.4s + add x21,x21,x30,lsr#32 + add v17.4s,v17.4s,v25.4s + + b.lo Ltail_neon + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor v0.16b,v0.16b,v20.16b + eor x15,x15,x16 + eor v1.16b,v1.16b,v21.16b + eor x17,x17,x19 + eor v2.16b,v2.16b,v22.16b + eor x20,x20,x21 + eor v3.16b,v3.16b,v23.16b + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#4 // increment counter + stp x9,x11,[x0,#16] + add v27.4s,v27.4s,v31.4s // += 4 + stp x13,x15,[x0,#32] + add v28.4s,v28.4s,v31.4s + stp x17,x20,[x0,#48] + add v29.4s,v29.4s,v31.4s + add x0,x0,#64 + + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + + eor v4.16b,v4.16b,v20.16b + eor v5.16b,v5.16b,v21.16b + eor v6.16b,v6.16b,v22.16b + eor v7.16b,v7.16b,v23.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + + eor v16.16b,v16.16b,v0.16b + eor v17.16b,v17.16b,v1.16b + eor v18.16b,v18.16b,v2.16b + eor v19.16b,v19.16b,v3.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + + b.hi Loop_outer_neon + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +Ltail_neon: + add x2,x2,#256 + cmp x2,#64 + b.lo Less_than_64 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#4 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + b.eq Ldone_neon + sub x2,x2,#64 + cmp x2,#64 + b.lo Less_than_128 + + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor v0.16b,v0.16b,v20.16b + eor v1.16b,v1.16b,v21.16b + eor v2.16b,v2.16b,v22.16b + eor v3.16b,v3.16b,v23.16b + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + b.eq Ldone_neon + sub x2,x2,#64 + cmp x2,#64 + b.lo Less_than_192 + + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor v4.16b,v4.16b,v20.16b + eor v5.16b,v5.16b,v21.16b + eor v6.16b,v6.16b,v22.16b + eor v7.16b,v7.16b,v23.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + b.eq Ldone_neon + sub x2,x2,#64 + + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[sp] + b Last_neon + +Less_than_128: + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[sp] + b Last_neon +Less_than_192: + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[sp] + b Last_neon + +.align 4 +Last_neon: + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + +Loop_tail_neon: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,Loop_tail_neon + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + +Ldone_neon: + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.align 5 +ChaCha20_512_neon: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,Lsigma@PAGE + add x5,x5,Lsigma@PAGEOFF + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + +L512_or_more_neon: + sub sp,sp,#128+64 + + ldp x22,x23,[x5] // load sigma + ld1 {v24.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v25.4s,v26.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v27.4s},[x4] + ld1 {v31.4s},[x5] +#ifdef __AARCH64EB__ + rev64 v24.4s,v24.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + add v27.4s,v27.4s,v31.4s // += 1 + stp q24,q25,[sp,#0] // off-load key block, invariant part + add v27.4s,v27.4s,v31.4s // not typo + str q26,[sp,#32] + add v28.4s,v27.4s,v31.4s + add v29.4s,v28.4s,v31.4s + add v30.4s,v29.4s,v31.4s + shl v31.4s,v31.4s,#2 // 1 -> 4 + + stp d8,d9,[sp,#128+0] // meet ABI requirements + stp d10,d11,[sp,#128+16] + stp d12,d13,[sp,#128+32] + stp d14,d15,[sp,#128+48] + + sub x2,x2,#512 // not typo + +Loop_outer_512_neon: + mov v0.16b,v24.16b + mov v4.16b,v24.16b + mov v8.16b,v24.16b + mov v12.16b,v24.16b + mov v16.16b,v24.16b + mov v20.16b,v24.16b + mov v1.16b,v25.16b + mov w5,w22 // unpack key block + mov v5.16b,v25.16b + lsr x6,x22,#32 + mov v9.16b,v25.16b + mov w7,w23 + mov v13.16b,v25.16b + lsr x8,x23,#32 + mov v17.16b,v25.16b + mov w9,w24 + mov v21.16b,v25.16b + lsr x10,x24,#32 + mov v3.16b,v27.16b + mov w11,w25 + mov v7.16b,v28.16b + lsr x12,x25,#32 + mov v11.16b,v29.16b + mov w13,w26 + mov v15.16b,v30.16b + lsr x14,x26,#32 + mov v2.16b,v26.16b + mov w15,w27 + mov v6.16b,v26.16b + lsr x16,x27,#32 + add v19.4s,v3.4s,v31.4s // +4 + mov w17,w28 + add v23.4s,v7.4s,v31.4s // +4 + lsr x19,x28,#32 + mov v10.16b,v26.16b + mov w20,w30 + mov v14.16b,v26.16b + lsr x21,x30,#32 + mov v18.16b,v26.16b + stp q27,q28,[sp,#48] // off-load key block, variable part + mov v22.16b,v26.16b + str q29,[sp,#80] + + mov x4,#5 + subs x2,x2,#512 +Loop_upper_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v11.16b,v11.16b,v11.16b,#12 + ext v15.16b,v15.16b,v15.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v23.16b,v23.16b,v23.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v11.16b,v11.16b,v11.16b,#4 + ext v15.16b,v15.16b,v15.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v23.16b,v23.16b,v23.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + cbnz x4,Loop_upper_neon + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + mov w5,w22 // unpack key block + lsr x6,x22,#32 + stp x9,x11,[x0,#16] + mov w7,w23 + lsr x8,x23,#32 + stp x13,x15,[x0,#32] + mov w9,w24 + lsr x10,x24,#32 + stp x17,x20,[x0,#48] + add x0,x0,#64 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#5 +Loop_lower_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v11.16b,v11.16b,v11.16b,#12 + ext v15.16b,v15.16b,v15.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v23.16b,v23.16b,v23.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v11.16b,v11.16b,v11.16b,#4 + ext v15.16b,v15.16b,v15.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v23.16b,v23.16b,v23.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + cbnz x4,Loop_lower_neon + + add w5,w5,w22 // accumulate key block + ldp q24,q25,[sp,#0] + add x6,x6,x22,lsr#32 + ldp q26,q27,[sp,#32] + add w7,w7,w23 + ldp q28,q29,[sp,#64] + add x8,x8,x23,lsr#32 + add v0.4s,v0.4s,v24.4s + add w9,w9,w24 + add v4.4s,v4.4s,v24.4s + add x10,x10,x24,lsr#32 + add v8.4s,v8.4s,v24.4s + add w11,w11,w25 + add v12.4s,v12.4s,v24.4s + add x12,x12,x25,lsr#32 + add v16.4s,v16.4s,v24.4s + add w13,w13,w26 + add v20.4s,v20.4s,v24.4s + add x14,x14,x26,lsr#32 + add v2.4s,v2.4s,v26.4s + add w15,w15,w27 + add v6.4s,v6.4s,v26.4s + add x16,x16,x27,lsr#32 + add v10.4s,v10.4s,v26.4s + add w17,w17,w28 + add v14.4s,v14.4s,v26.4s + add x19,x19,x28,lsr#32 + add v18.4s,v18.4s,v26.4s + add w20,w20,w30 + add v22.4s,v22.4s,v26.4s + add x21,x21,x30,lsr#32 + add v19.4s,v19.4s,v31.4s // +4 + add x5,x5,x6,lsl#32 // pack + add v23.4s,v23.4s,v31.4s // +4 + add x7,x7,x8,lsl#32 + add v3.4s,v3.4s,v27.4s + ldp x6,x8,[x1,#0] // load input + add v7.4s,v7.4s,v28.4s + add x9,x9,x10,lsl#32 + add v11.4s,v11.4s,v29.4s + add x11,x11,x12,lsl#32 + add v15.4s,v15.4s,v30.4s + ldp x10,x12,[x1,#16] + add v19.4s,v19.4s,v27.4s + add x13,x13,x14,lsl#32 + add v23.4s,v23.4s,v28.4s + add x15,x15,x16,lsl#32 + add v1.4s,v1.4s,v25.4s + ldp x14,x16,[x1,#32] + add v5.4s,v5.4s,v25.4s + add x17,x17,x19,lsl#32 + add v9.4s,v9.4s,v25.4s + add x20,x20,x21,lsl#32 + add v13.4s,v13.4s,v25.4s + ldp x19,x21,[x1,#48] + add v17.4s,v17.4s,v25.4s + add x1,x1,#64 + add v21.4s,v21.4s,v25.4s + +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64 + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor v0.16b,v0.16b,v24.16b + eor x15,x15,x16 + eor v1.16b,v1.16b,v25.16b + eor x17,x17,x19 + eor v2.16b,v2.16b,v26.16b + eor x20,x20,x21 + eor v3.16b,v3.16b,v27.16b + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#7 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + eor v4.16b,v4.16b,v24.16b + eor v5.16b,v5.16b,v25.16b + eor v6.16b,v6.16b,v26.16b + eor v7.16b,v7.16b,v27.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor v8.16b,v8.16b,v0.16b + ldp q24,q25,[sp,#0] + eor v9.16b,v9.16b,v1.16b + ldp q26,q27,[sp,#32] + eor v10.16b,v10.16b,v2.16b + eor v11.16b,v11.16b,v3.16b + st1 {v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64 + + ld1 {v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64 + eor v12.16b,v12.16b,v4.16b + eor v13.16b,v13.16b,v5.16b + eor v14.16b,v14.16b,v6.16b + eor v15.16b,v15.16b,v7.16b + st1 {v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64 + + ld1 {v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64 + eor v16.16b,v16.16b,v8.16b + eor v17.16b,v17.16b,v9.16b + eor v18.16b,v18.16b,v10.16b + eor v19.16b,v19.16b,v11.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + + shl v0.4s,v31.4s,#1 // 4 -> 8 + eor v20.16b,v20.16b,v12.16b + eor v21.16b,v21.16b,v13.16b + eor v22.16b,v22.16b,v14.16b + eor v23.16b,v23.16b,v15.16b + st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64 + + add v27.4s,v27.4s,v0.4s // += 8 + add v28.4s,v28.4s,v0.4s + add v29.4s,v29.4s,v0.4s + add v30.4s,v30.4s,v0.4s + + b.hs Loop_outer_512_neon + + adds x2,x2,#512 + ushr v0.4s,v31.4s,#2 // 4 -> 1 + + ldp d8,d9,[sp,#128+0] // meet ABI requirements + ldp d10,d11,[sp,#128+16] + ldp d12,d13,[sp,#128+32] + ldp d14,d15,[sp,#128+48] + + stp q24,q31,[sp,#0] // wipe off-load area + stp q24,q31,[sp,#32] + stp q24,q31,[sp,#64] + + b.eq Ldone_512_neon + + cmp x2,#192 + sub v27.4s,v27.4s,v0.4s // -= 1 + sub v28.4s,v28.4s,v0.4s + sub v29.4s,v29.4s,v0.4s + add sp,sp,#128 + b.hs Loop_outer_neon + + eor v25.16b,v25.16b,v25.16b + eor v26.16b,v26.16b,v26.16b + eor v27.16b,v27.16b,v27.16b + eor v28.16b,v28.16b,v28.16b + eor v29.16b,v29.16b,v29.16b + eor v30.16b,v30.16b,v30.16b + b Loop_outer + +Ldone_512_neon: + ldp x19,x20,[x29,#16] + add sp,sp,#128+64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S new file mode 100644 index 00000000..f6adadcc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S @@ -0,0 +1,2002 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + + +.hidden OPENSSL_armcap_P + +.section .rodata + +.align 5 +.Lsigma: +.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral +.Lone: +.long 1,0,0,0 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +.text + +.globl ChaCha20_ctr32 +.hidden ChaCha20_ctr32 +.type ChaCha20_ctr32,%function +.align 5 +ChaCha20_ctr32: + AARCH64_VALID_CALL_TARGET + cbz x2,.Labort +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x5,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x5,OPENSSL_armcap_P +#endif + cmp x2,#192 + b.lo .Lshort + ldr w17,[x5,:lo12:OPENSSL_armcap_P] + tst w17,#ARMV7_NEON + b.ne ChaCha20_neon + +.Lshort: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,.Lsigma + add x5,x5,:lo12:.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ldp x28,x30,[x4] // load counter +#ifdef __AARCH64EB__ + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + +.Loop_outer: + mov w5,w22 // unpack key block + lsr x6,x22,#32 + mov w7,w23 + lsr x8,x23,#32 + mov w9,w24 + lsr x10,x24,#32 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#10 + subs x2,x2,#64 +.Loop: + sub x4,x4,#1 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + ror w21,w21,#16 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#20 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + ror w21,w21,#24 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#25 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#16 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + ror w9,w9,#20 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#24 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + ror w9,w9,#25 + cbnz x4,.Loop + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + b.lo .Ltail + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + + b.hi .Loop_outer + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER +.Labort: + ret + +.align 4 +.Ltail: + add x2,x2,#64 +.Less_than_64: + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + stp x5,x7,[sp,#0] + stp x9,x11,[sp,#16] + stp x13,x15,[sp,#32] + stp x17,x20,[sp,#48] + +.Loop_tail: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,.Loop_tail + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ChaCha20_ctr32,.-ChaCha20_ctr32 + +.type ChaCha20_neon,%function +.align 5 +ChaCha20_neon: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,.Lsigma + add x5,x5,:lo12:.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + cmp x2,#512 + b.hs .L512_or_more_neon + + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ld1 {v24.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v25.4s,v26.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v27.4s},[x4] + ld1 {v31.4s},[x5] +#ifdef __AARCH64EB__ + rev64 v24.4s,v24.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + add v27.4s,v27.4s,v31.4s // += 1 + add v28.4s,v27.4s,v31.4s + add v29.4s,v28.4s,v31.4s + shl v31.4s,v31.4s,#2 // 1 -> 4 + +.Loop_outer_neon: + mov w5,w22 // unpack key block + lsr x6,x22,#32 + mov v0.16b,v24.16b + mov w7,w23 + lsr x8,x23,#32 + mov v4.16b,v24.16b + mov w9,w24 + lsr x10,x24,#32 + mov v16.16b,v24.16b + mov w11,w25 + mov v1.16b,v25.16b + lsr x12,x25,#32 + mov v5.16b,v25.16b + mov w13,w26 + mov v17.16b,v25.16b + lsr x14,x26,#32 + mov v3.16b,v27.16b + mov w15,w27 + mov v7.16b,v28.16b + lsr x16,x27,#32 + mov v19.16b,v29.16b + mov w17,w28 + mov v2.16b,v26.16b + lsr x19,x28,#32 + mov v6.16b,v26.16b + mov w20,w30 + mov v18.16b,v26.16b + lsr x21,x30,#32 + + mov x4,#10 + subs x2,x2,#256 +.Loop_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + eor v3.16b,v3.16b,v0.16b + add w8,w8,w12 + eor v7.16b,v7.16b,v4.16b + eor w17,w17,w5 + eor v19.16b,v19.16b,v16.16b + eor w19,w19,w6 + rev32 v3.8h,v3.8h + eor w20,w20,w7 + rev32 v7.8h,v7.8h + eor w21,w21,w8 + rev32 v19.8h,v19.8h + ror w17,w17,#16 + add v2.4s,v2.4s,v3.4s + ror w19,w19,#16 + add v6.4s,v6.4s,v7.4s + ror w20,w20,#16 + add v18.4s,v18.4s,v19.4s + ror w21,w21,#16 + eor v20.16b,v1.16b,v2.16b + add w13,w13,w17 + eor v21.16b,v5.16b,v6.16b + add w14,w14,w19 + eor v22.16b,v17.16b,v18.16b + add w15,w15,w20 + ushr v1.4s,v20.4s,#20 + add w16,w16,w21 + ushr v5.4s,v21.4s,#20 + eor w9,w9,w13 + ushr v17.4s,v22.4s,#20 + eor w10,w10,w14 + sli v1.4s,v20.4s,#12 + eor w11,w11,w15 + sli v5.4s,v21.4s,#12 + eor w12,w12,w16 + sli v17.4s,v22.4s,#12 + ror w9,w9,#20 + add v0.4s,v0.4s,v1.4s + ror w10,w10,#20 + add v4.4s,v4.4s,v5.4s + ror w11,w11,#20 + add v16.4s,v16.4s,v17.4s + ror w12,w12,#20 + eor v20.16b,v3.16b,v0.16b + add w5,w5,w9 + eor v21.16b,v7.16b,v4.16b + add w6,w6,w10 + eor v22.16b,v19.16b,v16.16b + add w7,w7,w11 + ushr v3.4s,v20.4s,#24 + add w8,w8,w12 + ushr v7.4s,v21.4s,#24 + eor w17,w17,w5 + ushr v19.4s,v22.4s,#24 + eor w19,w19,w6 + sli v3.4s,v20.4s,#8 + eor w20,w20,w7 + sli v7.4s,v21.4s,#8 + eor w21,w21,w8 + sli v19.4s,v22.4s,#8 + ror w17,w17,#24 + add v2.4s,v2.4s,v3.4s + ror w19,w19,#24 + add v6.4s,v6.4s,v7.4s + ror w20,w20,#24 + add v18.4s,v18.4s,v19.4s + ror w21,w21,#24 + eor v20.16b,v1.16b,v2.16b + add w13,w13,w17 + eor v21.16b,v5.16b,v6.16b + add w14,w14,w19 + eor v22.16b,v17.16b,v18.16b + add w15,w15,w20 + ushr v1.4s,v20.4s,#25 + add w16,w16,w21 + ushr v5.4s,v21.4s,#25 + eor w9,w9,w13 + ushr v17.4s,v22.4s,#25 + eor w10,w10,w14 + sli v1.4s,v20.4s,#7 + eor w11,w11,w15 + sli v5.4s,v21.4s,#7 + eor w12,w12,w16 + sli v17.4s,v22.4s,#7 + ror w9,w9,#25 + ext v2.16b,v2.16b,v2.16b,#8 + ror w10,w10,#25 + ext v6.16b,v6.16b,v6.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w10 + add v4.4s,v4.4s,v5.4s + add w6,w6,w11 + add v16.4s,v16.4s,v17.4s + add w7,w7,w12 + eor v3.16b,v3.16b,v0.16b + add w8,w8,w9 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w5 + eor v19.16b,v19.16b,v16.16b + eor w17,w17,w6 + rev32 v3.8h,v3.8h + eor w19,w19,w7 + rev32 v7.8h,v7.8h + eor w20,w20,w8 + rev32 v19.8h,v19.8h + ror w21,w21,#16 + add v2.4s,v2.4s,v3.4s + ror w17,w17,#16 + add v6.4s,v6.4s,v7.4s + ror w19,w19,#16 + add v18.4s,v18.4s,v19.4s + ror w20,w20,#16 + eor v20.16b,v1.16b,v2.16b + add w15,w15,w21 + eor v21.16b,v5.16b,v6.16b + add w16,w16,w17 + eor v22.16b,v17.16b,v18.16b + add w13,w13,w19 + ushr v1.4s,v20.4s,#20 + add w14,w14,w20 + ushr v5.4s,v21.4s,#20 + eor w10,w10,w15 + ushr v17.4s,v22.4s,#20 + eor w11,w11,w16 + sli v1.4s,v20.4s,#12 + eor w12,w12,w13 + sli v5.4s,v21.4s,#12 + eor w9,w9,w14 + sli v17.4s,v22.4s,#12 + ror w10,w10,#20 + add v0.4s,v0.4s,v1.4s + ror w11,w11,#20 + add v4.4s,v4.4s,v5.4s + ror w12,w12,#20 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#20 + eor v20.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v21.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v22.16b,v19.16b,v16.16b + add w7,w7,w12 + ushr v3.4s,v20.4s,#24 + add w8,w8,w9 + ushr v7.4s,v21.4s,#24 + eor w21,w21,w5 + ushr v19.4s,v22.4s,#24 + eor w17,w17,w6 + sli v3.4s,v20.4s,#8 + eor w19,w19,w7 + sli v7.4s,v21.4s,#8 + eor w20,w20,w8 + sli v19.4s,v22.4s,#8 + ror w21,w21,#24 + add v2.4s,v2.4s,v3.4s + ror w17,w17,#24 + add v6.4s,v6.4s,v7.4s + ror w19,w19,#24 + add v18.4s,v18.4s,v19.4s + ror w20,w20,#24 + eor v20.16b,v1.16b,v2.16b + add w15,w15,w21 + eor v21.16b,v5.16b,v6.16b + add w16,w16,w17 + eor v22.16b,v17.16b,v18.16b + add w13,w13,w19 + ushr v1.4s,v20.4s,#25 + add w14,w14,w20 + ushr v5.4s,v21.4s,#25 + eor w10,w10,w15 + ushr v17.4s,v22.4s,#25 + eor w11,w11,w16 + sli v1.4s,v20.4s,#7 + eor w12,w12,w13 + sli v5.4s,v21.4s,#7 + eor w9,w9,w14 + sli v17.4s,v22.4s,#7 + ror w10,w10,#25 + ext v2.16b,v2.16b,v2.16b,#8 + ror w11,w11,#25 + ext v6.16b,v6.16b,v6.16b,#8 + ror w12,w12,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + cbnz x4,.Loop_neon + + add w5,w5,w22 // accumulate key block + add v0.4s,v0.4s,v24.4s + add x6,x6,x22,lsr#32 + add v4.4s,v4.4s,v24.4s + add w7,w7,w23 + add v16.4s,v16.4s,v24.4s + add x8,x8,x23,lsr#32 + add v2.4s,v2.4s,v26.4s + add w9,w9,w24 + add v6.4s,v6.4s,v26.4s + add x10,x10,x24,lsr#32 + add v18.4s,v18.4s,v26.4s + add w11,w11,w25 + add v3.4s,v3.4s,v27.4s + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add v7.4s,v7.4s,v28.4s + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add v19.4s,v19.4s,v29.4s + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add v1.4s,v1.4s,v25.4s + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add v5.4s,v5.4s,v25.4s + add x21,x21,x30,lsr#32 + add v17.4s,v17.4s,v25.4s + + b.lo .Ltail_neon + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor v0.16b,v0.16b,v20.16b + eor x15,x15,x16 + eor v1.16b,v1.16b,v21.16b + eor x17,x17,x19 + eor v2.16b,v2.16b,v22.16b + eor x20,x20,x21 + eor v3.16b,v3.16b,v23.16b + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#4 // increment counter + stp x9,x11,[x0,#16] + add v27.4s,v27.4s,v31.4s // += 4 + stp x13,x15,[x0,#32] + add v28.4s,v28.4s,v31.4s + stp x17,x20,[x0,#48] + add v29.4s,v29.4s,v31.4s + add x0,x0,#64 + + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + + eor v4.16b,v4.16b,v20.16b + eor v5.16b,v5.16b,v21.16b + eor v6.16b,v6.16b,v22.16b + eor v7.16b,v7.16b,v23.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + + eor v16.16b,v16.16b,v0.16b + eor v17.16b,v17.16b,v1.16b + eor v18.16b,v18.16b,v2.16b + eor v19.16b,v19.16b,v3.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + + b.hi .Loop_outer_neon + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.Ltail_neon: + add x2,x2,#256 + cmp x2,#64 + b.lo .Less_than_64 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#4 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + b.eq .Ldone_neon + sub x2,x2,#64 + cmp x2,#64 + b.lo .Less_than_128 + + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor v0.16b,v0.16b,v20.16b + eor v1.16b,v1.16b,v21.16b + eor v2.16b,v2.16b,v22.16b + eor v3.16b,v3.16b,v23.16b + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + b.eq .Ldone_neon + sub x2,x2,#64 + cmp x2,#64 + b.lo .Less_than_192 + + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor v4.16b,v4.16b,v20.16b + eor v5.16b,v5.16b,v21.16b + eor v6.16b,v6.16b,v22.16b + eor v7.16b,v7.16b,v23.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + b.eq .Ldone_neon + sub x2,x2,#64 + + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[sp] + b .Last_neon + +.Less_than_128: + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[sp] + b .Last_neon +.Less_than_192: + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[sp] + b .Last_neon + +.align 4 +.Last_neon: + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + +.Loop_tail_neon: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,.Loop_tail_neon + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + +.Ldone_neon: + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ChaCha20_neon,.-ChaCha20_neon +.type ChaCha20_512_neon,%function +.align 5 +ChaCha20_512_neon: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adrp x5,.Lsigma + add x5,x5,:lo12:.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + +.L512_or_more_neon: + sub sp,sp,#128+64 + + ldp x22,x23,[x5] // load sigma + ld1 {v24.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v25.4s,v26.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v27.4s},[x4] + ld1 {v31.4s},[x5] +#ifdef __AARCH64EB__ + rev64 v24.4s,v24.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + add v27.4s,v27.4s,v31.4s // += 1 + stp q24,q25,[sp,#0] // off-load key block, invariant part + add v27.4s,v27.4s,v31.4s // not typo + str q26,[sp,#32] + add v28.4s,v27.4s,v31.4s + add v29.4s,v28.4s,v31.4s + add v30.4s,v29.4s,v31.4s + shl v31.4s,v31.4s,#2 // 1 -> 4 + + stp d8,d9,[sp,#128+0] // meet ABI requirements + stp d10,d11,[sp,#128+16] + stp d12,d13,[sp,#128+32] + stp d14,d15,[sp,#128+48] + + sub x2,x2,#512 // not typo + +.Loop_outer_512_neon: + mov v0.16b,v24.16b + mov v4.16b,v24.16b + mov v8.16b,v24.16b + mov v12.16b,v24.16b + mov v16.16b,v24.16b + mov v20.16b,v24.16b + mov v1.16b,v25.16b + mov w5,w22 // unpack key block + mov v5.16b,v25.16b + lsr x6,x22,#32 + mov v9.16b,v25.16b + mov w7,w23 + mov v13.16b,v25.16b + lsr x8,x23,#32 + mov v17.16b,v25.16b + mov w9,w24 + mov v21.16b,v25.16b + lsr x10,x24,#32 + mov v3.16b,v27.16b + mov w11,w25 + mov v7.16b,v28.16b + lsr x12,x25,#32 + mov v11.16b,v29.16b + mov w13,w26 + mov v15.16b,v30.16b + lsr x14,x26,#32 + mov v2.16b,v26.16b + mov w15,w27 + mov v6.16b,v26.16b + lsr x16,x27,#32 + add v19.4s,v3.4s,v31.4s // +4 + mov w17,w28 + add v23.4s,v7.4s,v31.4s // +4 + lsr x19,x28,#32 + mov v10.16b,v26.16b + mov w20,w30 + mov v14.16b,v26.16b + lsr x21,x30,#32 + mov v18.16b,v26.16b + stp q27,q28,[sp,#48] // off-load key block, variable part + mov v22.16b,v26.16b + str q29,[sp,#80] + + mov x4,#5 + subs x2,x2,#512 +.Loop_upper_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v11.16b,v11.16b,v11.16b,#12 + ext v15.16b,v15.16b,v15.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v23.16b,v23.16b,v23.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v11.16b,v11.16b,v11.16b,#4 + ext v15.16b,v15.16b,v15.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v23.16b,v23.16b,v23.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + cbnz x4,.Loop_upper_neon + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + mov w5,w22 // unpack key block + lsr x6,x22,#32 + stp x9,x11,[x0,#16] + mov w7,w23 + lsr x8,x23,#32 + stp x13,x15,[x0,#32] + mov w9,w24 + lsr x10,x24,#32 + stp x17,x20,[x0,#48] + add x0,x0,#64 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#5 +.Loop_lower_neon: + sub x4,x4,#1 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#12 + ext v7.16b,v7.16b,v7.16b,#12 + ext v11.16b,v11.16b,v11.16b,#12 + ext v15.16b,v15.16b,v15.16b,#12 + ext v19.16b,v19.16b,v19.16b,#12 + ext v23.16b,v23.16b,v23.16b,#12 + ext v1.16b,v1.16b,v1.16b,#4 + ext v5.16b,v5.16b,v5.16b,#4 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + add v0.4s,v0.4s,v1.4s + add w5,w5,w9 + add v4.4s,v4.4s,v5.4s + add w6,w6,w10 + add v8.4s,v8.4s,v9.4s + add w7,w7,w11 + add v12.4s,v12.4s,v13.4s + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + eor v3.16b,v3.16b,v0.16b + eor w20,w20,w7 + eor v7.16b,v7.16b,v4.16b + eor w21,w21,w8 + eor v11.16b,v11.16b,v8.16b + ror w17,w17,#16 + eor v15.16b,v15.16b,v12.16b + ror w19,w19,#16 + eor v19.16b,v19.16b,v16.16b + ror w20,w20,#16 + eor v23.16b,v23.16b,v20.16b + ror w21,w21,#16 + rev32 v3.8h,v3.8h + add w13,w13,w17 + rev32 v7.8h,v7.8h + add w14,w14,w19 + rev32 v11.8h,v11.8h + add w15,w15,w20 + rev32 v15.8h,v15.8h + add w16,w16,w21 + rev32 v19.8h,v19.8h + eor w9,w9,w13 + rev32 v23.8h,v23.8h + eor w10,w10,w14 + add v2.4s,v2.4s,v3.4s + eor w11,w11,w15 + add v6.4s,v6.4s,v7.4s + eor w12,w12,w16 + add v10.4s,v10.4s,v11.4s + ror w9,w9,#20 + add v14.4s,v14.4s,v15.4s + ror w10,w10,#20 + add v18.4s,v18.4s,v19.4s + ror w11,w11,#20 + add v22.4s,v22.4s,v23.4s + ror w12,w12,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w9 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w10 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w11 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w12 + eor v28.16b,v17.16b,v18.16b + eor w17,w17,w5 + eor v29.16b,v21.16b,v22.16b + eor w19,w19,w6 + ushr v1.4s,v24.4s,#20 + eor w20,w20,w7 + ushr v5.4s,v25.4s,#20 + eor w21,w21,w8 + ushr v9.4s,v26.4s,#20 + ror w17,w17,#24 + ushr v13.4s,v27.4s,#20 + ror w19,w19,#24 + ushr v17.4s,v28.4s,#20 + ror w20,w20,#24 + ushr v21.4s,v29.4s,#20 + ror w21,w21,#24 + sli v1.4s,v24.4s,#12 + add w13,w13,w17 + sli v5.4s,v25.4s,#12 + add w14,w14,w19 + sli v9.4s,v26.4s,#12 + add w15,w15,w20 + sli v13.4s,v27.4s,#12 + add w16,w16,w21 + sli v17.4s,v28.4s,#12 + eor w9,w9,w13 + sli v21.4s,v29.4s,#12 + eor w10,w10,w14 + add v0.4s,v0.4s,v1.4s + eor w11,w11,w15 + add v4.4s,v4.4s,v5.4s + eor w12,w12,w16 + add v8.4s,v8.4s,v9.4s + ror w9,w9,#25 + add v12.4s,v12.4s,v13.4s + ror w10,w10,#25 + add v16.4s,v16.4s,v17.4s + ror w11,w11,#25 + add v20.4s,v20.4s,v21.4s + ror w12,w12,#25 + eor v24.16b,v3.16b,v0.16b + add w5,w5,w10 + eor v25.16b,v7.16b,v4.16b + add w6,w6,w11 + eor v26.16b,v11.16b,v8.16b + add w7,w7,w12 + eor v27.16b,v15.16b,v12.16b + add w8,w8,w9 + eor v28.16b,v19.16b,v16.16b + eor w21,w21,w5 + eor v29.16b,v23.16b,v20.16b + eor w17,w17,w6 + ushr v3.4s,v24.4s,#24 + eor w19,w19,w7 + ushr v7.4s,v25.4s,#24 + eor w20,w20,w8 + ushr v11.4s,v26.4s,#24 + ror w21,w21,#16 + ushr v15.4s,v27.4s,#24 + ror w17,w17,#16 + ushr v19.4s,v28.4s,#24 + ror w19,w19,#16 + ushr v23.4s,v29.4s,#24 + ror w20,w20,#16 + sli v3.4s,v24.4s,#8 + add w15,w15,w21 + sli v7.4s,v25.4s,#8 + add w16,w16,w17 + sli v11.4s,v26.4s,#8 + add w13,w13,w19 + sli v15.4s,v27.4s,#8 + add w14,w14,w20 + sli v19.4s,v28.4s,#8 + eor w10,w10,w15 + sli v23.4s,v29.4s,#8 + eor w11,w11,w16 + add v2.4s,v2.4s,v3.4s + eor w12,w12,w13 + add v6.4s,v6.4s,v7.4s + eor w9,w9,w14 + add v10.4s,v10.4s,v11.4s + ror w10,w10,#20 + add v14.4s,v14.4s,v15.4s + ror w11,w11,#20 + add v18.4s,v18.4s,v19.4s + ror w12,w12,#20 + add v22.4s,v22.4s,v23.4s + ror w9,w9,#20 + eor v24.16b,v1.16b,v2.16b + add w5,w5,w10 + eor v25.16b,v5.16b,v6.16b + add w6,w6,w11 + eor v26.16b,v9.16b,v10.16b + add w7,w7,w12 + eor v27.16b,v13.16b,v14.16b + add w8,w8,w9 + eor v28.16b,v17.16b,v18.16b + eor w21,w21,w5 + eor v29.16b,v21.16b,v22.16b + eor w17,w17,w6 + ushr v1.4s,v24.4s,#25 + eor w19,w19,w7 + ushr v5.4s,v25.4s,#25 + eor w20,w20,w8 + ushr v9.4s,v26.4s,#25 + ror w21,w21,#24 + ushr v13.4s,v27.4s,#25 + ror w17,w17,#24 + ushr v17.4s,v28.4s,#25 + ror w19,w19,#24 + ushr v21.4s,v29.4s,#25 + ror w20,w20,#24 + sli v1.4s,v24.4s,#7 + add w15,w15,w21 + sli v5.4s,v25.4s,#7 + add w16,w16,w17 + sli v9.4s,v26.4s,#7 + add w13,w13,w19 + sli v13.4s,v27.4s,#7 + add w14,w14,w20 + sli v17.4s,v28.4s,#7 + eor w10,w10,w15 + sli v21.4s,v29.4s,#7 + eor w11,w11,w16 + ext v2.16b,v2.16b,v2.16b,#8 + eor w12,w12,w13 + ext v6.16b,v6.16b,v6.16b,#8 + eor w9,w9,w14 + ext v10.16b,v10.16b,v10.16b,#8 + ror w10,w10,#25 + ext v14.16b,v14.16b,v14.16b,#8 + ror w11,w11,#25 + ext v18.16b,v18.16b,v18.16b,#8 + ror w12,w12,#25 + ext v22.16b,v22.16b,v22.16b,#8 + ror w9,w9,#25 + ext v3.16b,v3.16b,v3.16b,#4 + ext v7.16b,v7.16b,v7.16b,#4 + ext v11.16b,v11.16b,v11.16b,#4 + ext v15.16b,v15.16b,v15.16b,#4 + ext v19.16b,v19.16b,v19.16b,#4 + ext v23.16b,v23.16b,v23.16b,#4 + ext v1.16b,v1.16b,v1.16b,#12 + ext v5.16b,v5.16b,v5.16b,#12 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + cbnz x4,.Loop_lower_neon + + add w5,w5,w22 // accumulate key block + ldp q24,q25,[sp,#0] + add x6,x6,x22,lsr#32 + ldp q26,q27,[sp,#32] + add w7,w7,w23 + ldp q28,q29,[sp,#64] + add x8,x8,x23,lsr#32 + add v0.4s,v0.4s,v24.4s + add w9,w9,w24 + add v4.4s,v4.4s,v24.4s + add x10,x10,x24,lsr#32 + add v8.4s,v8.4s,v24.4s + add w11,w11,w25 + add v12.4s,v12.4s,v24.4s + add x12,x12,x25,lsr#32 + add v16.4s,v16.4s,v24.4s + add w13,w13,w26 + add v20.4s,v20.4s,v24.4s + add x14,x14,x26,lsr#32 + add v2.4s,v2.4s,v26.4s + add w15,w15,w27 + add v6.4s,v6.4s,v26.4s + add x16,x16,x27,lsr#32 + add v10.4s,v10.4s,v26.4s + add w17,w17,w28 + add v14.4s,v14.4s,v26.4s + add x19,x19,x28,lsr#32 + add v18.4s,v18.4s,v26.4s + add w20,w20,w30 + add v22.4s,v22.4s,v26.4s + add x21,x21,x30,lsr#32 + add v19.4s,v19.4s,v31.4s // +4 + add x5,x5,x6,lsl#32 // pack + add v23.4s,v23.4s,v31.4s // +4 + add x7,x7,x8,lsl#32 + add v3.4s,v3.4s,v27.4s + ldp x6,x8,[x1,#0] // load input + add v7.4s,v7.4s,v28.4s + add x9,x9,x10,lsl#32 + add v11.4s,v11.4s,v29.4s + add x11,x11,x12,lsl#32 + add v15.4s,v15.4s,v30.4s + ldp x10,x12,[x1,#16] + add v19.4s,v19.4s,v27.4s + add x13,x13,x14,lsl#32 + add v23.4s,v23.4s,v28.4s + add x15,x15,x16,lsl#32 + add v1.4s,v1.4s,v25.4s + ldp x14,x16,[x1,#32] + add v5.4s,v5.4s,v25.4s + add x17,x17,x19,lsl#32 + add v9.4s,v9.4s,v25.4s + add x20,x20,x21,lsl#32 + add v13.4s,v13.4s,v25.4s + ldp x19,x21,[x1,#48] + add v17.4s,v17.4s,v25.4s + add x1,x1,#64 + add v21.4s,v21.4s,v25.4s + +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64 + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor v0.16b,v0.16b,v24.16b + eor x15,x15,x16 + eor v1.16b,v1.16b,v25.16b + eor x17,x17,x19 + eor v2.16b,v2.16b,v26.16b + eor x20,x20,x21 + eor v3.16b,v3.16b,v27.16b + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#7 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + st1 {v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64 + + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + eor v4.16b,v4.16b,v24.16b + eor v5.16b,v5.16b,v25.16b + eor v6.16b,v6.16b,v26.16b + eor v7.16b,v7.16b,v27.16b + st1 {v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64 + + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor v8.16b,v8.16b,v0.16b + ldp q24,q25,[sp,#0] + eor v9.16b,v9.16b,v1.16b + ldp q26,q27,[sp,#32] + eor v10.16b,v10.16b,v2.16b + eor v11.16b,v11.16b,v3.16b + st1 {v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64 + + ld1 {v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64 + eor v12.16b,v12.16b,v4.16b + eor v13.16b,v13.16b,v5.16b + eor v14.16b,v14.16b,v6.16b + eor v15.16b,v15.16b,v7.16b + st1 {v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64 + + ld1 {v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64 + eor v16.16b,v16.16b,v8.16b + eor v17.16b,v17.16b,v9.16b + eor v18.16b,v18.16b,v10.16b + eor v19.16b,v19.16b,v11.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + + shl v0.4s,v31.4s,#1 // 4 -> 8 + eor v20.16b,v20.16b,v12.16b + eor v21.16b,v21.16b,v13.16b + eor v22.16b,v22.16b,v14.16b + eor v23.16b,v23.16b,v15.16b + st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64 + + add v27.4s,v27.4s,v0.4s // += 8 + add v28.4s,v28.4s,v0.4s + add v29.4s,v29.4s,v0.4s + add v30.4s,v30.4s,v0.4s + + b.hs .Loop_outer_512_neon + + adds x2,x2,#512 + ushr v0.4s,v31.4s,#2 // 4 -> 1 + + ldp d8,d9,[sp,#128+0] // meet ABI requirements + ldp d10,d11,[sp,#128+16] + ldp d12,d13,[sp,#128+32] + ldp d14,d15,[sp,#128+48] + + stp q24,q31,[sp,#0] // wipe off-load area + stp q24,q31,[sp,#32] + stp q24,q31,[sp,#64] + + b.eq .Ldone_512_neon + + cmp x2,#192 + sub v27.4s,v27.4s,v0.4s // -= 1 + sub v28.4s,v28.4s,v0.4s + sub v29.4s,v29.4s,v0.4s + add sp,sp,#128 + b.hs .Loop_outer_neon + + eor v25.16b,v25.16b,v25.16b + eor v26.16b,v26.16b,v26.16b + eor v27.16b,v27.16b,v27.16b + eor v28.16b,v28.16b,v28.16b + eor v29.16b,v29.16b,v29.16b + eor v30.16b,v30.16b,v30.16b + b .Loop_outer + +.Ldone_512_neon: + ldp x19,x20,[x29,#16] + add sp,sp,#128+64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ChaCha20_512_neon,.-ChaCha20_512_neon +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S new file mode 100644 index 00000000..6f261878 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S @@ -0,0 +1,982 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl ChaCha20_ctr32 +.hidden ChaCha20_ctr32 +.type ChaCha20_ctr32,@function +.align 16 +ChaCha20_ctr32: +.L_ChaCha20_ctr32_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl %eax,%eax + cmpl 28(%esp),%eax + je .L000no_data + call .Lpic_point +.Lpic_point: + popl %eax + leal OPENSSL_ia32cap_P-.Lpic_point(%eax),%ebp + testl $16777216,(%ebp) + jz .L001x86 + testl $512,4(%ebp) + jz .L001x86 + jmp .Lssse3_shortcut +.L001x86: + movl 32(%esp),%esi + movl 36(%esp),%edi + subl $132,%esp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,80(%esp) + movl %ebx,84(%esp) + movl %ecx,88(%esp) + movl %edx,92(%esp) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,96(%esp) + movl %ebx,100(%esp) + movl %ecx,104(%esp) + movl %edx,108(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + subl $1,%eax + movl %eax,112(%esp) + movl %ebx,116(%esp) + movl %ecx,120(%esp) + movl %edx,124(%esp) + jmp .L002entry +.align 16 +.L003outer_loop: + movl %ebx,156(%esp) + movl %eax,152(%esp) + movl %ecx,160(%esp) +.L002entry: + movl $1634760805,%eax + movl $857760878,4(%esp) + movl $2036477234,8(%esp) + movl $1797285236,12(%esp) + movl 84(%esp),%ebx + movl 88(%esp),%ebp + movl 104(%esp),%ecx + movl 108(%esp),%esi + movl 116(%esp),%edx + movl 120(%esp),%edi + movl %ebx,20(%esp) + movl %ebp,24(%esp) + movl %ecx,40(%esp) + movl %esi,44(%esp) + movl %edx,52(%esp) + movl %edi,56(%esp) + movl 92(%esp),%ebx + movl 124(%esp),%edi + movl 112(%esp),%edx + movl 80(%esp),%ebp + movl 96(%esp),%ecx + movl 100(%esp),%esi + addl $1,%edx + movl %ebx,28(%esp) + movl %edi,60(%esp) + movl %edx,112(%esp) + movl $10,%ebx + jmp .L004loop +.align 16 +.L004loop: + addl %ebp,%eax + movl %ebx,128(%esp) + movl %ebp,%ebx + xorl %eax,%edx + roll $16,%edx + addl %edx,%ecx + xorl %ecx,%ebx + movl 52(%esp),%edi + roll $12,%ebx + movl 20(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,(%esp) + roll $8,%edx + movl 4(%esp),%eax + addl %edx,%ecx + movl %edx,48(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + movl %ecx,32(%esp) + roll $16,%edi + movl %ebx,16(%esp) + addl %edi,%esi + movl 40(%esp),%ecx + xorl %esi,%ebp + movl 56(%esp),%edx + roll $12,%ebp + movl 24(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,4(%esp) + roll $8,%edi + movl 8(%esp),%eax + addl %edi,%esi + movl %edi,52(%esp) + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + movl %esi,36(%esp) + roll $16,%edx + movl %ebp,20(%esp) + addl %edx,%ecx + movl 44(%esp),%esi + xorl %ecx,%ebx + movl 60(%esp),%edi + roll $12,%ebx + movl 28(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,8(%esp) + roll $8,%edx + movl 12(%esp),%eax + addl %edx,%ecx + movl %edx,56(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + roll $16,%edi + movl %ebx,24(%esp) + addl %edi,%esi + xorl %esi,%ebp + roll $12,%ebp + movl 20(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,12(%esp) + roll $8,%edi + movl (%esp),%eax + addl %edi,%esi + movl %edi,%edx + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + roll $16,%edx + movl %ebp,28(%esp) + addl %edx,%ecx + xorl %ecx,%ebx + movl 48(%esp),%edi + roll $12,%ebx + movl 24(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,(%esp) + roll $8,%edx + movl 4(%esp),%eax + addl %edx,%ecx + movl %edx,60(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + movl %ecx,40(%esp) + roll $16,%edi + movl %ebx,20(%esp) + addl %edi,%esi + movl 32(%esp),%ecx + xorl %esi,%ebp + movl 52(%esp),%edx + roll $12,%ebp + movl 28(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,4(%esp) + roll $8,%edi + movl 8(%esp),%eax + addl %edi,%esi + movl %edi,48(%esp) + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + movl %esi,44(%esp) + roll $16,%edx + movl %ebp,24(%esp) + addl %edx,%ecx + movl 36(%esp),%esi + xorl %ecx,%ebx + movl 56(%esp),%edi + roll $12,%ebx + movl 16(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,8(%esp) + roll $8,%edx + movl 12(%esp),%eax + addl %edx,%ecx + movl %edx,52(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + roll $16,%edi + movl %ebx,28(%esp) + addl %edi,%esi + xorl %esi,%ebp + movl 48(%esp),%edx + roll $12,%ebp + movl 128(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,12(%esp) + roll $8,%edi + movl (%esp),%eax + addl %edi,%esi + movl %edi,56(%esp) + xorl %esi,%ebp + roll $7,%ebp + decl %ebx + jnz .L004loop + movl 160(%esp),%ebx + addl $1634760805,%eax + addl 80(%esp),%ebp + addl 96(%esp),%ecx + addl 100(%esp),%esi + cmpl $64,%ebx + jb .L005tail + movl 156(%esp),%ebx + addl 112(%esp),%edx + addl 120(%esp),%edi + xorl (%ebx),%eax + xorl 16(%ebx),%ebp + movl %eax,(%esp) + movl 152(%esp),%eax + xorl 32(%ebx),%ecx + xorl 36(%ebx),%esi + xorl 48(%ebx),%edx + xorl 56(%ebx),%edi + movl %ebp,16(%eax) + movl %ecx,32(%eax) + movl %esi,36(%eax) + movl %edx,48(%eax) + movl %edi,56(%eax) + movl 4(%esp),%ebp + movl 8(%esp),%ecx + movl 12(%esp),%esi + movl 20(%esp),%edx + movl 24(%esp),%edi + addl $857760878,%ebp + addl $2036477234,%ecx + addl $1797285236,%esi + addl 84(%esp),%edx + addl 88(%esp),%edi + xorl 4(%ebx),%ebp + xorl 8(%ebx),%ecx + xorl 12(%ebx),%esi + xorl 20(%ebx),%edx + xorl 24(%ebx),%edi + movl %ebp,4(%eax) + movl %ecx,8(%eax) + movl %esi,12(%eax) + movl %edx,20(%eax) + movl %edi,24(%eax) + movl 28(%esp),%ebp + movl 40(%esp),%ecx + movl 44(%esp),%esi + movl 52(%esp),%edx + movl 60(%esp),%edi + addl 92(%esp),%ebp + addl 104(%esp),%ecx + addl 108(%esp),%esi + addl 116(%esp),%edx + addl 124(%esp),%edi + xorl 28(%ebx),%ebp + xorl 40(%ebx),%ecx + xorl 44(%ebx),%esi + xorl 52(%ebx),%edx + xorl 60(%ebx),%edi + leal 64(%ebx),%ebx + movl %ebp,28(%eax) + movl (%esp),%ebp + movl %ecx,40(%eax) + movl 160(%esp),%ecx + movl %esi,44(%eax) + movl %edx,52(%eax) + movl %edi,60(%eax) + movl %ebp,(%eax) + leal 64(%eax),%eax + subl $64,%ecx + jnz .L003outer_loop + jmp .L006done +.L005tail: + addl 112(%esp),%edx + addl 120(%esp),%edi + movl %eax,(%esp) + movl %ebp,16(%esp) + movl %ecx,32(%esp) + movl %esi,36(%esp) + movl %edx,48(%esp) + movl %edi,56(%esp) + movl 4(%esp),%ebp + movl 8(%esp),%ecx + movl 12(%esp),%esi + movl 20(%esp),%edx + movl 24(%esp),%edi + addl $857760878,%ebp + addl $2036477234,%ecx + addl $1797285236,%esi + addl 84(%esp),%edx + addl 88(%esp),%edi + movl %ebp,4(%esp) + movl %ecx,8(%esp) + movl %esi,12(%esp) + movl %edx,20(%esp) + movl %edi,24(%esp) + movl 28(%esp),%ebp + movl 40(%esp),%ecx + movl 44(%esp),%esi + movl 52(%esp),%edx + movl 60(%esp),%edi + addl 92(%esp),%ebp + addl 104(%esp),%ecx + addl 108(%esp),%esi + addl 116(%esp),%edx + addl 124(%esp),%edi + movl %ebp,28(%esp) + movl 156(%esp),%ebp + movl %ecx,40(%esp) + movl 152(%esp),%ecx + movl %esi,44(%esp) + xorl %esi,%esi + movl %edx,52(%esp) + movl %edi,60(%esp) + xorl %eax,%eax + xorl %edx,%edx +.L007tail_loop: + movb (%esi,%ebp,1),%al + movb (%esp,%esi,1),%dl + leal 1(%esi),%esi + xorb %dl,%al + movb %al,-1(%ecx,%esi,1) + decl %ebx + jnz .L007tail_loop +.L006done: + addl $132,%esp +.L000no_data: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ChaCha20_ctr32,.-.L_ChaCha20_ctr32_begin +.globl ChaCha20_ssse3 +.hidden ChaCha20_ssse3 +.type ChaCha20_ssse3,@function +.align 16 +ChaCha20_ssse3: +.L_ChaCha20_ssse3_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +.Lssse3_shortcut: + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl %esp,%ebp + subl $524,%esp + andl $-64,%esp + movl %ebp,512(%esp) + leal .Lssse3_data-.Lpic_point(%eax),%eax + movdqu (%ebx),%xmm3 + cmpl $256,%ecx + jb .L0081x + movl %edx,516(%esp) + movl %ebx,520(%esp) + subl $256,%ecx + leal 384(%esp),%ebp + movdqu (%edx),%xmm7 + pshufd $0,%xmm3,%xmm0 + pshufd $85,%xmm3,%xmm1 + pshufd $170,%xmm3,%xmm2 + pshufd $255,%xmm3,%xmm3 + paddd 48(%eax),%xmm0 + pshufd $0,%xmm7,%xmm4 + pshufd $85,%xmm7,%xmm5 + psubd 64(%eax),%xmm0 + pshufd $170,%xmm7,%xmm6 + pshufd $255,%xmm7,%xmm7 + movdqa %xmm0,64(%ebp) + movdqa %xmm1,80(%ebp) + movdqa %xmm2,96(%ebp) + movdqa %xmm3,112(%ebp) + movdqu 16(%edx),%xmm3 + movdqa %xmm4,-64(%ebp) + movdqa %xmm5,-48(%ebp) + movdqa %xmm6,-32(%ebp) + movdqa %xmm7,-16(%ebp) + movdqa 32(%eax),%xmm7 + leal 128(%esp),%ebx + pshufd $0,%xmm3,%xmm0 + pshufd $85,%xmm3,%xmm1 + pshufd $170,%xmm3,%xmm2 + pshufd $255,%xmm3,%xmm3 + pshufd $0,%xmm7,%xmm4 + pshufd $85,%xmm7,%xmm5 + pshufd $170,%xmm7,%xmm6 + pshufd $255,%xmm7,%xmm7 + movdqa %xmm0,(%ebp) + movdqa %xmm1,16(%ebp) + movdqa %xmm2,32(%ebp) + movdqa %xmm3,48(%ebp) + movdqa %xmm4,-128(%ebp) + movdqa %xmm5,-112(%ebp) + movdqa %xmm6,-96(%ebp) + movdqa %xmm7,-80(%ebp) + leal 128(%esi),%esi + leal 128(%edi),%edi + jmp .L009outer_loop +.align 16 +.L009outer_loop: + movdqa -112(%ebp),%xmm1 + movdqa -96(%ebp),%xmm2 + movdqa -80(%ebp),%xmm3 + movdqa -48(%ebp),%xmm5 + movdqa -32(%ebp),%xmm6 + movdqa -16(%ebp),%xmm7 + movdqa %xmm1,-112(%ebx) + movdqa %xmm2,-96(%ebx) + movdqa %xmm3,-80(%ebx) + movdqa %xmm5,-48(%ebx) + movdqa %xmm6,-32(%ebx) + movdqa %xmm7,-16(%ebx) + movdqa 32(%ebp),%xmm2 + movdqa 48(%ebp),%xmm3 + movdqa 64(%ebp),%xmm4 + movdqa 80(%ebp),%xmm5 + movdqa 96(%ebp),%xmm6 + movdqa 112(%ebp),%xmm7 + paddd 64(%eax),%xmm4 + movdqa %xmm2,32(%ebx) + movdqa %xmm3,48(%ebx) + movdqa %xmm4,64(%ebx) + movdqa %xmm5,80(%ebx) + movdqa %xmm6,96(%ebx) + movdqa %xmm7,112(%ebx) + movdqa %xmm4,64(%ebp) + movdqa -128(%ebp),%xmm0 + movdqa %xmm4,%xmm6 + movdqa -64(%ebp),%xmm3 + movdqa (%ebp),%xmm4 + movdqa 16(%ebp),%xmm5 + movl $10,%edx + nop +.align 16 +.L010loop: + paddd %xmm3,%xmm0 + movdqa %xmm3,%xmm2 + pxor %xmm0,%xmm6 + pshufb (%eax),%xmm6 + paddd %xmm6,%xmm4 + pxor %xmm4,%xmm2 + movdqa -48(%ebx),%xmm3 + movdqa %xmm2,%xmm1 + pslld $12,%xmm2 + psrld $20,%xmm1 + por %xmm1,%xmm2 + movdqa -112(%ebx),%xmm1 + paddd %xmm2,%xmm0 + movdqa 80(%ebx),%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm0,-128(%ebx) + pshufb 16(%eax),%xmm6 + paddd %xmm6,%xmm4 + movdqa %xmm6,64(%ebx) + pxor %xmm4,%xmm2 + paddd %xmm3,%xmm1 + movdqa %xmm2,%xmm0 + pslld $7,%xmm2 + psrld $25,%xmm0 + pxor %xmm1,%xmm7 + por %xmm0,%xmm2 + movdqa %xmm4,(%ebx) + pshufb (%eax),%xmm7 + movdqa %xmm2,-64(%ebx) + paddd %xmm7,%xmm5 + movdqa 32(%ebx),%xmm4 + pxor %xmm5,%xmm3 + movdqa -32(%ebx),%xmm2 + movdqa %xmm3,%xmm0 + pslld $12,%xmm3 + psrld $20,%xmm0 + por %xmm0,%xmm3 + movdqa -96(%ebx),%xmm0 + paddd %xmm3,%xmm1 + movdqa 96(%ebx),%xmm6 + pxor %xmm1,%xmm7 + movdqa %xmm1,-112(%ebx) + pshufb 16(%eax),%xmm7 + paddd %xmm7,%xmm5 + movdqa %xmm7,80(%ebx) + pxor %xmm5,%xmm3 + paddd %xmm2,%xmm0 + movdqa %xmm3,%xmm1 + pslld $7,%xmm3 + psrld $25,%xmm1 + pxor %xmm0,%xmm6 + por %xmm1,%xmm3 + movdqa %xmm5,16(%ebx) + pshufb (%eax),%xmm6 + movdqa %xmm3,-48(%ebx) + paddd %xmm6,%xmm4 + movdqa 48(%ebx),%xmm5 + pxor %xmm4,%xmm2 + movdqa -16(%ebx),%xmm3 + movdqa %xmm2,%xmm1 + pslld $12,%xmm2 + psrld $20,%xmm1 + por %xmm1,%xmm2 + movdqa -80(%ebx),%xmm1 + paddd %xmm2,%xmm0 + movdqa 112(%ebx),%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm0,-96(%ebx) + pshufb 16(%eax),%xmm6 + paddd %xmm6,%xmm4 + movdqa %xmm6,96(%ebx) + pxor %xmm4,%xmm2 + paddd %xmm3,%xmm1 + movdqa %xmm2,%xmm0 + pslld $7,%xmm2 + psrld $25,%xmm0 + pxor %xmm1,%xmm7 + por %xmm0,%xmm2 + pshufb (%eax),%xmm7 + movdqa %xmm2,-32(%ebx) + paddd %xmm7,%xmm5 + pxor %xmm5,%xmm3 + movdqa -48(%ebx),%xmm2 + movdqa %xmm3,%xmm0 + pslld $12,%xmm3 + psrld $20,%xmm0 + por %xmm0,%xmm3 + movdqa -128(%ebx),%xmm0 + paddd %xmm3,%xmm1 + pxor %xmm1,%xmm7 + movdqa %xmm1,-80(%ebx) + pshufb 16(%eax),%xmm7 + paddd %xmm7,%xmm5 + movdqa %xmm7,%xmm6 + pxor %xmm5,%xmm3 + paddd %xmm2,%xmm0 + movdqa %xmm3,%xmm1 + pslld $7,%xmm3 + psrld $25,%xmm1 + pxor %xmm0,%xmm6 + por %xmm1,%xmm3 + pshufb (%eax),%xmm6 + movdqa %xmm3,-16(%ebx) + paddd %xmm6,%xmm4 + pxor %xmm4,%xmm2 + movdqa -32(%ebx),%xmm3 + movdqa %xmm2,%xmm1 + pslld $12,%xmm2 + psrld $20,%xmm1 + por %xmm1,%xmm2 + movdqa -112(%ebx),%xmm1 + paddd %xmm2,%xmm0 + movdqa 64(%ebx),%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm0,-128(%ebx) + pshufb 16(%eax),%xmm6 + paddd %xmm6,%xmm4 + movdqa %xmm6,112(%ebx) + pxor %xmm4,%xmm2 + paddd %xmm3,%xmm1 + movdqa %xmm2,%xmm0 + pslld $7,%xmm2 + psrld $25,%xmm0 + pxor %xmm1,%xmm7 + por %xmm0,%xmm2 + movdqa %xmm4,32(%ebx) + pshufb (%eax),%xmm7 + movdqa %xmm2,-48(%ebx) + paddd %xmm7,%xmm5 + movdqa (%ebx),%xmm4 + pxor %xmm5,%xmm3 + movdqa -16(%ebx),%xmm2 + movdqa %xmm3,%xmm0 + pslld $12,%xmm3 + psrld $20,%xmm0 + por %xmm0,%xmm3 + movdqa -96(%ebx),%xmm0 + paddd %xmm3,%xmm1 + movdqa 80(%ebx),%xmm6 + pxor %xmm1,%xmm7 + movdqa %xmm1,-112(%ebx) + pshufb 16(%eax),%xmm7 + paddd %xmm7,%xmm5 + movdqa %xmm7,64(%ebx) + pxor %xmm5,%xmm3 + paddd %xmm2,%xmm0 + movdqa %xmm3,%xmm1 + pslld $7,%xmm3 + psrld $25,%xmm1 + pxor %xmm0,%xmm6 + por %xmm1,%xmm3 + movdqa %xmm5,48(%ebx) + pshufb (%eax),%xmm6 + movdqa %xmm3,-32(%ebx) + paddd %xmm6,%xmm4 + movdqa 16(%ebx),%xmm5 + pxor %xmm4,%xmm2 + movdqa -64(%ebx),%xmm3 + movdqa %xmm2,%xmm1 + pslld $12,%xmm2 + psrld $20,%xmm1 + por %xmm1,%xmm2 + movdqa -80(%ebx),%xmm1 + paddd %xmm2,%xmm0 + movdqa 96(%ebx),%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm0,-96(%ebx) + pshufb 16(%eax),%xmm6 + paddd %xmm6,%xmm4 + movdqa %xmm6,80(%ebx) + pxor %xmm4,%xmm2 + paddd %xmm3,%xmm1 + movdqa %xmm2,%xmm0 + pslld $7,%xmm2 + psrld $25,%xmm0 + pxor %xmm1,%xmm7 + por %xmm0,%xmm2 + pshufb (%eax),%xmm7 + movdqa %xmm2,-16(%ebx) + paddd %xmm7,%xmm5 + pxor %xmm5,%xmm3 + movdqa %xmm3,%xmm0 + pslld $12,%xmm3 + psrld $20,%xmm0 + por %xmm0,%xmm3 + movdqa -128(%ebx),%xmm0 + paddd %xmm3,%xmm1 + movdqa 64(%ebx),%xmm6 + pxor %xmm1,%xmm7 + movdqa %xmm1,-80(%ebx) + pshufb 16(%eax),%xmm7 + paddd %xmm7,%xmm5 + movdqa %xmm7,96(%ebx) + pxor %xmm5,%xmm3 + movdqa %xmm3,%xmm1 + pslld $7,%xmm3 + psrld $25,%xmm1 + por %xmm1,%xmm3 + decl %edx + jnz .L010loop + movdqa %xmm3,-64(%ebx) + movdqa %xmm4,(%ebx) + movdqa %xmm5,16(%ebx) + movdqa %xmm6,64(%ebx) + movdqa %xmm7,96(%ebx) + movdqa -112(%ebx),%xmm1 + movdqa -96(%ebx),%xmm2 + movdqa -80(%ebx),%xmm3 + paddd -128(%ebp),%xmm0 + paddd -112(%ebp),%xmm1 + paddd -96(%ebp),%xmm2 + paddd -80(%ebp),%xmm3 + movdqa %xmm0,%xmm6 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm6 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm6,%xmm3 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + movdqu -128(%esi),%xmm4 + movdqu -64(%esi),%xmm5 + movdqu (%esi),%xmm2 + movdqu 64(%esi),%xmm7 + leal 16(%esi),%esi + pxor %xmm0,%xmm4 + movdqa -64(%ebx),%xmm0 + pxor %xmm1,%xmm5 + movdqa -48(%ebx),%xmm1 + pxor %xmm2,%xmm6 + movdqa -32(%ebx),%xmm2 + pxor %xmm3,%xmm7 + movdqa -16(%ebx),%xmm3 + movdqu %xmm4,-128(%edi) + movdqu %xmm5,-64(%edi) + movdqu %xmm6,(%edi) + movdqu %xmm7,64(%edi) + leal 16(%edi),%edi + paddd -64(%ebp),%xmm0 + paddd -48(%ebp),%xmm1 + paddd -32(%ebp),%xmm2 + paddd -16(%ebp),%xmm3 + movdqa %xmm0,%xmm6 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm6 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm6,%xmm3 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + movdqu -128(%esi),%xmm4 + movdqu -64(%esi),%xmm5 + movdqu (%esi),%xmm2 + movdqu 64(%esi),%xmm7 + leal 16(%esi),%esi + pxor %xmm0,%xmm4 + movdqa (%ebx),%xmm0 + pxor %xmm1,%xmm5 + movdqa 16(%ebx),%xmm1 + pxor %xmm2,%xmm6 + movdqa 32(%ebx),%xmm2 + pxor %xmm3,%xmm7 + movdqa 48(%ebx),%xmm3 + movdqu %xmm4,-128(%edi) + movdqu %xmm5,-64(%edi) + movdqu %xmm6,(%edi) + movdqu %xmm7,64(%edi) + leal 16(%edi),%edi + paddd (%ebp),%xmm0 + paddd 16(%ebp),%xmm1 + paddd 32(%ebp),%xmm2 + paddd 48(%ebp),%xmm3 + movdqa %xmm0,%xmm6 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm6 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm6,%xmm3 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + movdqu -128(%esi),%xmm4 + movdqu -64(%esi),%xmm5 + movdqu (%esi),%xmm2 + movdqu 64(%esi),%xmm7 + leal 16(%esi),%esi + pxor %xmm0,%xmm4 + movdqa 64(%ebx),%xmm0 + pxor %xmm1,%xmm5 + movdqa 80(%ebx),%xmm1 + pxor %xmm2,%xmm6 + movdqa 96(%ebx),%xmm2 + pxor %xmm3,%xmm7 + movdqa 112(%ebx),%xmm3 + movdqu %xmm4,-128(%edi) + movdqu %xmm5,-64(%edi) + movdqu %xmm6,(%edi) + movdqu %xmm7,64(%edi) + leal 16(%edi),%edi + paddd 64(%ebp),%xmm0 + paddd 80(%ebp),%xmm1 + paddd 96(%ebp),%xmm2 + paddd 112(%ebp),%xmm3 + movdqa %xmm0,%xmm6 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm6 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm6,%xmm3 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + movdqu -128(%esi),%xmm4 + movdqu -64(%esi),%xmm5 + movdqu (%esi),%xmm2 + movdqu 64(%esi),%xmm7 + leal 208(%esi),%esi + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm5 + pxor %xmm2,%xmm6 + pxor %xmm3,%xmm7 + movdqu %xmm4,-128(%edi) + movdqu %xmm5,-64(%edi) + movdqu %xmm6,(%edi) + movdqu %xmm7,64(%edi) + leal 208(%edi),%edi + subl $256,%ecx + jnc .L009outer_loop + addl $256,%ecx + jz .L011done + movl 520(%esp),%ebx + leal -128(%esi),%esi + movl 516(%esp),%edx + leal -128(%edi),%edi + movd 64(%ebp),%xmm2 + movdqu (%ebx),%xmm3 + paddd 96(%eax),%xmm2 + pand 112(%eax),%xmm3 + por %xmm2,%xmm3 +.L0081x: + movdqa 32(%eax),%xmm0 + movdqu (%edx),%xmm1 + movdqu 16(%edx),%xmm2 + movdqa (%eax),%xmm6 + movdqa 16(%eax),%xmm7 + movl %ebp,48(%esp) + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movl $10,%edx + jmp .L012loop1x +.align 16 +.L013outer1x: + movdqa 80(%eax),%xmm3 + movdqa (%esp),%xmm0 + movdqa 16(%esp),%xmm1 + movdqa 32(%esp),%xmm2 + paddd 48(%esp),%xmm3 + movl $10,%edx + movdqa %xmm3,48(%esp) + jmp .L012loop1x +.align 16 +.L012loop1x: + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm1,%xmm1 + pshufd $147,%xmm3,%xmm3 + nop + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm1,%xmm1 + pshufd $57,%xmm3,%xmm3 + decl %edx + jnz .L012loop1x + paddd (%esp),%xmm0 + paddd 16(%esp),%xmm1 + paddd 32(%esp),%xmm2 + paddd 48(%esp),%xmm3 + cmpl $64,%ecx + jb .L014tail + movdqu (%esi),%xmm4 + movdqu 16(%esi),%xmm5 + pxor %xmm4,%xmm0 + movdqu 32(%esi),%xmm4 + pxor %xmm5,%xmm1 + movdqu 48(%esi),%xmm5 + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm3 + leal 64(%esi),%esi + movdqu %xmm0,(%edi) + movdqu %xmm1,16(%edi) + movdqu %xmm2,32(%edi) + movdqu %xmm3,48(%edi) + leal 64(%edi),%edi + subl $64,%ecx + jnz .L013outer1x + jmp .L011done +.L014tail: + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + xorl %eax,%eax + xorl %edx,%edx + xorl %ebp,%ebp +.L015tail_loop: + movb (%esp,%ebp,1),%al + movb (%esi,%ebp,1),%dl + leal 1(%ebp),%ebp + xorb %dl,%al + movb %al,-1(%edi,%ebp,1) + decl %ecx + jnz .L015tail_loop +.L011done: + movl 512(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ChaCha20_ssse3,.-.L_ChaCha20_ssse3_begin +.align 64 +.Lssse3_data: +.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 +.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 +.long 1634760805,857760878,2036477234,1797285236 +.long 0,1,2,3 +.long 4,4,4,4 +.long 1,0,0,0 +.long 4,0,0,0 +.long 0,-1,-1,-1 +.align 64 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54 +.byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 +.byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 +.byte 114,103,62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S new file mode 100644 index 00000000..2853c30b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S @@ -0,0 +1,1640 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + +.align 64 +.Lzero: +.long 0,0,0,0 +.Lone: +.long 1,0,0,0 +.Linc: +.long 0,1,2,3 +.Lfour: +.long 4,4,4,4 +.Lincy: +.long 0,2,4,6,1,3,5,7 +.Leight: +.long 8,8,8,8,8,8,8,8 +.Lrot16: +.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd +.Lrot24: +.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe +.Lsigma: +.byte 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0 +.align 64 +.Lzeroz: +.long 0,0,0,0, 1,0,0,0, 2,0,0,0, 3,0,0,0 +.Lfourz: +.long 4,0,0,0, 4,0,0,0, 4,0,0,0, 4,0,0,0 +.Lincz: +.long 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +.Lsixteen: +.long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.globl ChaCha20_ctr32 +.hidden ChaCha20_ctr32 +.type ChaCha20_ctr32,@function +.align 64 +ChaCha20_ctr32: +.cfi_startproc + cmpq $0,%rdx + je .Lno_data + movq OPENSSL_ia32cap_P+4(%rip),%r10 + testl $512,%r10d + jnz .LChaCha20_ssse3 + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset r15,-56 + subq $64+24,%rsp +.cfi_adjust_cfa_offset 88 +.Lctr32_body: + + + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa .Lone(%rip),%xmm4 + + + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq %rdx,%rbp + jmp .Loop_outer + +.align 32 +.Loop_outer: + movl $0x61707865,%eax + movl $0x3320646e,%ebx + movl $0x79622d32,%ecx + movl $0x6b206574,%edx + movl 16(%rsp),%r8d + movl 20(%rsp),%r9d + movl 24(%rsp),%r10d + movl 28(%rsp),%r11d + movd %xmm3,%r12d + movl 52(%rsp),%r13d + movl 56(%rsp),%r14d + movl 60(%rsp),%r15d + + movq %rbp,64+0(%rsp) + movl $10,%ebp + movq %rsi,64+8(%rsp) +.byte 102,72,15,126,214 + movq %rdi,64+16(%rsp) + movq %rsi,%rdi + shrq $32,%rdi + jmp .Loop + +.align 32 +.Loop: + addl %r8d,%eax + xorl %eax,%r12d + roll $16,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $16,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $12,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $12,%r9d + addl %r8d,%eax + xorl %eax,%r12d + roll $8,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $8,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $7,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $7,%r9d + movl %esi,32(%rsp) + movl %edi,36(%rsp) + movl 40(%rsp),%esi + movl 44(%rsp),%edi + addl %r10d,%ecx + xorl %ecx,%r14d + roll $16,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $16,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $12,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $12,%r11d + addl %r10d,%ecx + xorl %ecx,%r14d + roll $8,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $8,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $7,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $7,%r11d + addl %r9d,%eax + xorl %eax,%r15d + roll $16,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $16,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $12,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $12,%r10d + addl %r9d,%eax + xorl %eax,%r15d + roll $8,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $8,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $7,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $7,%r10d + movl %esi,40(%rsp) + movl %edi,44(%rsp) + movl 32(%rsp),%esi + movl 36(%rsp),%edi + addl %r11d,%ecx + xorl %ecx,%r13d + roll $16,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $16,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $12,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $12,%r8d + addl %r11d,%ecx + xorl %ecx,%r13d + roll $8,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $8,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $7,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $7,%r8d + decl %ebp + jnz .Loop + movl %edi,36(%rsp) + movl %esi,32(%rsp) + movq 64(%rsp),%rbp + movdqa %xmm2,%xmm1 + movq 64+8(%rsp),%rsi + paddd %xmm4,%xmm3 + movq 64+16(%rsp),%rdi + + addl $0x61707865,%eax + addl $0x3320646e,%ebx + addl $0x79622d32,%ecx + addl $0x6b206574,%edx + addl 16(%rsp),%r8d + addl 20(%rsp),%r9d + addl 24(%rsp),%r10d + addl 28(%rsp),%r11d + addl 48(%rsp),%r12d + addl 52(%rsp),%r13d + addl 56(%rsp),%r14d + addl 60(%rsp),%r15d + paddd 32(%rsp),%xmm1 + + cmpq $64,%rbp + jb .Ltail + + xorl 0(%rsi),%eax + xorl 4(%rsi),%ebx + xorl 8(%rsi),%ecx + xorl 12(%rsi),%edx + xorl 16(%rsi),%r8d + xorl 20(%rsi),%r9d + xorl 24(%rsi),%r10d + xorl 28(%rsi),%r11d + movdqu 32(%rsi),%xmm0 + xorl 48(%rsi),%r12d + xorl 52(%rsi),%r13d + xorl 56(%rsi),%r14d + xorl 60(%rsi),%r15d + leaq 64(%rsi),%rsi + pxor %xmm1,%xmm0 + + movdqa %xmm2,32(%rsp) + movd %xmm3,48(%rsp) + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + movdqu %xmm0,32(%rdi) + movl %r12d,48(%rdi) + movl %r13d,52(%rdi) + movl %r14d,56(%rdi) + movl %r15d,60(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rbp + jnz .Loop_outer + + jmp .Ldone + +.align 16 +.Ltail: + movl %eax,0(%rsp) + movl %ebx,4(%rsp) + xorq %rbx,%rbx + movl %ecx,8(%rsp) + movl %edx,12(%rsp) + movl %r8d,16(%rsp) + movl %r9d,20(%rsp) + movl %r10d,24(%rsp) + movl %r11d,28(%rsp) + movdqa %xmm1,32(%rsp) + movl %r12d,48(%rsp) + movl %r13d,52(%rsp) + movl %r14d,56(%rsp) + movl %r15d,60(%rsp) + +.Loop_tail: + movzbl (%rsi,%rbx,1),%eax + movzbl (%rsp,%rbx,1),%edx + leaq 1(%rbx),%rbx + xorl %edx,%eax + movb %al,-1(%rdi,%rbx,1) + decq %rbp + jnz .Loop_tail + +.Ldone: + leaq 64+24+48(%rsp),%rsi + movq -48(%rsi),%r15 +.cfi_restore r15 + movq -40(%rsi),%r14 +.cfi_restore r14 + movq -32(%rsi),%r13 +.cfi_restore r13 + movq -24(%rsi),%r12 +.cfi_restore r12 + movq -16(%rsi),%rbp +.cfi_restore rbp + movq -8(%rsi),%rbx +.cfi_restore rbx + leaq (%rsi),%rsp +.cfi_adjust_cfa_offset -136 +.Lno_data: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_ctr32,.-ChaCha20_ctr32 +.type ChaCha20_ssse3,@function +.align 32 +ChaCha20_ssse3: +.LChaCha20_ssse3: +.cfi_startproc + movq %rsp,%r9 +.cfi_def_cfa_register r9 + cmpq $128,%rdx + ja .LChaCha20_4x + +.Ldo_sse3_after_all: + subq $64+8,%rsp + movdqa .Lsigma(%rip),%xmm0 + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa .Lrot16(%rip),%xmm6 + movdqa .Lrot24(%rip),%xmm7 + + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq $10,%r8 + jmp .Loop_ssse3 + +.align 32 +.Loop_outer_ssse3: + movdqa .Lone(%rip),%xmm3 + movdqa 0(%rsp),%xmm0 + movdqa 16(%rsp),%xmm1 + movdqa 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + movq $10,%r8 + movdqa %xmm3,48(%rsp) + jmp .Loop_ssse3 + +.align 32 +.Loop_ssse3: + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm1,%xmm1 + pshufd $147,%xmm3,%xmm3 + nop + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm1,%xmm1 + pshufd $57,%xmm3,%xmm3 + decq %r8 + jnz .Loop_ssse3 + paddd 0(%rsp),%xmm0 + paddd 16(%rsp),%xmm1 + paddd 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + + cmpq $64,%rdx + jb .Ltail_ssse3 + + movdqu 0(%rsi),%xmm4 + movdqu 16(%rsi),%xmm5 + pxor %xmm4,%xmm0 + movdqu 32(%rsi),%xmm4 + pxor %xmm5,%xmm1 + movdqu 48(%rsi),%xmm5 + leaq 64(%rsi),%rsi + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm3 + + movdqu %xmm0,0(%rdi) + movdqu %xmm1,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rdx + jnz .Loop_outer_ssse3 + + jmp .Ldone_ssse3 + +.align 16 +.Ltail_ssse3: + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + xorq %r8,%r8 + +.Loop_tail_ssse3: + movzbl (%rsi,%r8,1),%eax + movzbl (%rsp,%r8,1),%ecx + leaq 1(%r8),%r8 + xorl %ecx,%eax + movb %al,-1(%rdi,%r8,1) + decq %rdx + jnz .Loop_tail_ssse3 + +.Ldone_ssse3: + leaq (%r9),%rsp +.cfi_def_cfa_register rsp +.Lssse3_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_ssse3,.-ChaCha20_ssse3 +.type ChaCha20_4x,@function +.align 32 +ChaCha20_4x: +.LChaCha20_4x: +.cfi_startproc + movq %rsp,%r9 +.cfi_def_cfa_register r9 + movq %r10,%r11 + shrq $32,%r10 + testq $32,%r10 + jnz .LChaCha20_8x + cmpq $192,%rdx + ja .Lproceed4x + + andq $71303168,%r11 + cmpq $4194304,%r11 + je .Ldo_sse3_after_all + +.Lproceed4x: + subq $0x140+8,%rsp + movdqa .Lsigma(%rip),%xmm11 + movdqu (%rcx),%xmm15 + movdqu 16(%rcx),%xmm7 + movdqu (%r8),%xmm3 + leaq 256(%rsp),%rcx + leaq .Lrot16(%rip),%r10 + leaq .Lrot24(%rip),%r11 + + pshufd $0x00,%xmm11,%xmm8 + pshufd $0x55,%xmm11,%xmm9 + movdqa %xmm8,64(%rsp) + pshufd $0xaa,%xmm11,%xmm10 + movdqa %xmm9,80(%rsp) + pshufd $0xff,%xmm11,%xmm11 + movdqa %xmm10,96(%rsp) + movdqa %xmm11,112(%rsp) + + pshufd $0x00,%xmm15,%xmm12 + pshufd $0x55,%xmm15,%xmm13 + movdqa %xmm12,128-256(%rcx) + pshufd $0xaa,%xmm15,%xmm14 + movdqa %xmm13,144-256(%rcx) + pshufd $0xff,%xmm15,%xmm15 + movdqa %xmm14,160-256(%rcx) + movdqa %xmm15,176-256(%rcx) + + pshufd $0x00,%xmm7,%xmm4 + pshufd $0x55,%xmm7,%xmm5 + movdqa %xmm4,192-256(%rcx) + pshufd $0xaa,%xmm7,%xmm6 + movdqa %xmm5,208-256(%rcx) + pshufd $0xff,%xmm7,%xmm7 + movdqa %xmm6,224-256(%rcx) + movdqa %xmm7,240-256(%rcx) + + pshufd $0x00,%xmm3,%xmm0 + pshufd $0x55,%xmm3,%xmm1 + paddd .Linc(%rip),%xmm0 + pshufd $0xaa,%xmm3,%xmm2 + movdqa %xmm1,272-256(%rcx) + pshufd $0xff,%xmm3,%xmm3 + movdqa %xmm2,288-256(%rcx) + movdqa %xmm3,304-256(%rcx) + + jmp .Loop_enter4x + +.align 32 +.Loop_outer4x: + movdqa 64(%rsp),%xmm8 + movdqa 80(%rsp),%xmm9 + movdqa 96(%rsp),%xmm10 + movdqa 112(%rsp),%xmm11 + movdqa 128-256(%rcx),%xmm12 + movdqa 144-256(%rcx),%xmm13 + movdqa 160-256(%rcx),%xmm14 + movdqa 176-256(%rcx),%xmm15 + movdqa 192-256(%rcx),%xmm4 + movdqa 208-256(%rcx),%xmm5 + movdqa 224-256(%rcx),%xmm6 + movdqa 240-256(%rcx),%xmm7 + movdqa 256-256(%rcx),%xmm0 + movdqa 272-256(%rcx),%xmm1 + movdqa 288-256(%rcx),%xmm2 + movdqa 304-256(%rcx),%xmm3 + paddd .Lfour(%rip),%xmm0 + +.Loop_enter4x: + movdqa %xmm6,32(%rsp) + movdqa %xmm7,48(%rsp) + movdqa (%r10),%xmm7 + movl $10,%eax + movdqa %xmm0,256-256(%rcx) + jmp .Loop4x + +.align 32 +.Loop4x: + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,199 +.byte 102,15,56,0,207 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm6 + pslld $12,%xmm12 + psrld $20,%xmm6 + movdqa %xmm13,%xmm7 + pslld $12,%xmm13 + por %xmm6,%xmm12 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm13 + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm7 + pslld $7,%xmm12 + psrld $25,%xmm7 + movdqa %xmm13,%xmm6 + pslld $7,%xmm13 + por %xmm7,%xmm12 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm13 + movdqa %xmm4,0(%rsp) + movdqa %xmm5,16(%rsp) + movdqa 32(%rsp),%xmm4 + movdqa 48(%rsp),%xmm5 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,215 +.byte 102,15,56,0,223 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm6 + pslld $12,%xmm14 + psrld $20,%xmm6 + movdqa %xmm15,%xmm7 + pslld $12,%xmm15 + por %xmm6,%xmm14 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm15 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm7 + pslld $7,%xmm14 + psrld $25,%xmm7 + movdqa %xmm15,%xmm6 + pslld $7,%xmm15 + por %xmm7,%xmm14 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm15 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,223 +.byte 102,15,56,0,199 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm6 + pslld $12,%xmm13 + psrld $20,%xmm6 + movdqa %xmm14,%xmm7 + pslld $12,%xmm14 + por %xmm6,%xmm13 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm14 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,222 +.byte 102,15,56,0,198 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm7 + pslld $7,%xmm13 + psrld $25,%xmm7 + movdqa %xmm14,%xmm6 + pslld $7,%xmm14 + por %xmm7,%xmm13 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm14 + movdqa %xmm4,32(%rsp) + movdqa %xmm5,48(%rsp) + movdqa 0(%rsp),%xmm4 + movdqa 16(%rsp),%xmm5 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm6 + pslld $12,%xmm15 + psrld $20,%xmm6 + movdqa %xmm12,%xmm7 + pslld $12,%xmm12 + por %xmm6,%xmm15 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm12 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm7 + pslld $7,%xmm15 + psrld $25,%xmm7 + movdqa %xmm12,%xmm6 + pslld $7,%xmm12 + por %xmm7,%xmm15 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm12 + decl %eax + jnz .Loop4x + + paddd 64(%rsp),%xmm8 + paddd 80(%rsp),%xmm9 + paddd 96(%rsp),%xmm10 + paddd 112(%rsp),%xmm11 + + movdqa %xmm8,%xmm6 + punpckldq %xmm9,%xmm8 + movdqa %xmm10,%xmm7 + punpckldq %xmm11,%xmm10 + punpckhdq %xmm9,%xmm6 + punpckhdq %xmm11,%xmm7 + movdqa %xmm8,%xmm9 + punpcklqdq %xmm10,%xmm8 + movdqa %xmm6,%xmm11 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm10,%xmm9 + punpckhqdq %xmm7,%xmm11 + paddd 128-256(%rcx),%xmm12 + paddd 144-256(%rcx),%xmm13 + paddd 160-256(%rcx),%xmm14 + paddd 176-256(%rcx),%xmm15 + + movdqa %xmm8,0(%rsp) + movdqa %xmm9,16(%rsp) + movdqa 32(%rsp),%xmm8 + movdqa 48(%rsp),%xmm9 + + movdqa %xmm12,%xmm10 + punpckldq %xmm13,%xmm12 + movdqa %xmm14,%xmm7 + punpckldq %xmm15,%xmm14 + punpckhdq %xmm13,%xmm10 + punpckhdq %xmm15,%xmm7 + movdqa %xmm12,%xmm13 + punpcklqdq %xmm14,%xmm12 + movdqa %xmm10,%xmm15 + punpcklqdq %xmm7,%xmm10 + punpckhqdq %xmm14,%xmm13 + punpckhqdq %xmm7,%xmm15 + paddd 192-256(%rcx),%xmm4 + paddd 208-256(%rcx),%xmm5 + paddd 224-256(%rcx),%xmm8 + paddd 240-256(%rcx),%xmm9 + + movdqa %xmm6,32(%rsp) + movdqa %xmm11,48(%rsp) + + movdqa %xmm4,%xmm14 + punpckldq %xmm5,%xmm4 + movdqa %xmm8,%xmm7 + punpckldq %xmm9,%xmm8 + punpckhdq %xmm5,%xmm14 + punpckhdq %xmm9,%xmm7 + movdqa %xmm4,%xmm5 + punpcklqdq %xmm8,%xmm4 + movdqa %xmm14,%xmm9 + punpcklqdq %xmm7,%xmm14 + punpckhqdq %xmm8,%xmm5 + punpckhqdq %xmm7,%xmm9 + paddd 256-256(%rcx),%xmm0 + paddd 272-256(%rcx),%xmm1 + paddd 288-256(%rcx),%xmm2 + paddd 304-256(%rcx),%xmm3 + + movdqa %xmm0,%xmm8 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm8 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm8,%xmm3 + punpcklqdq %xmm7,%xmm8 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + cmpq $256,%rdx + jb .Ltail4x + + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 48(%rsp),%xmm6 + pxor %xmm15,%xmm11 + pxor %xmm9,%xmm2 + pxor %xmm3,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + + subq $256,%rdx + jnz .Loop_outer4x + + jmp .Ldone4x + +.Ltail4x: + cmpq $192,%rdx + jae .L192_or_more4x + cmpq $128,%rdx + jae .L128_or_more4x + cmpq $64,%rdx + jae .L64_or_more4x + + + xorq %r10,%r10 + + movdqa %xmm12,16(%rsp) + movdqa %xmm4,32(%rsp) + movdqa %xmm0,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L64_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je .Ldone4x + + movdqa 16(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm13,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm5,32(%rsp) + subq $64,%rdx + movdqa %xmm1,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L128_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + je .Ldone4x + + movdqa 32(%rsp),%xmm6 + leaq 128(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm10,16(%rsp) + leaq 128(%rdi),%rdi + movdqa %xmm14,32(%rsp) + subq $128,%rdx + movdqa %xmm8,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L192_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je .Ldone4x + + movdqa 48(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm15,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm9,32(%rsp) + subq $192,%rdx + movdqa %xmm3,48(%rsp) + +.Loop_tail4x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz .Loop_tail4x + +.Ldone4x: + leaq (%r9),%rsp +.cfi_def_cfa_register rsp +.L4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_4x,.-ChaCha20_4x +.type ChaCha20_8x,@function +.align 32 +ChaCha20_8x: +.LChaCha20_8x: +.cfi_startproc + movq %rsp,%r9 +.cfi_def_cfa_register r9 + subq $0x280+8,%rsp + andq $-32,%rsp + vzeroupper + + + + + + + + + + + vbroadcasti128 .Lsigma(%rip),%ymm11 + vbroadcasti128 (%rcx),%ymm3 + vbroadcasti128 16(%rcx),%ymm15 + vbroadcasti128 (%r8),%ymm7 + leaq 256(%rsp),%rcx + leaq 512(%rsp),%rax + leaq .Lrot16(%rip),%r10 + leaq .Lrot24(%rip),%r11 + + vpshufd $0x00,%ymm11,%ymm8 + vpshufd $0x55,%ymm11,%ymm9 + vmovdqa %ymm8,128-256(%rcx) + vpshufd $0xaa,%ymm11,%ymm10 + vmovdqa %ymm9,160-256(%rcx) + vpshufd $0xff,%ymm11,%ymm11 + vmovdqa %ymm10,192-256(%rcx) + vmovdqa %ymm11,224-256(%rcx) + + vpshufd $0x00,%ymm3,%ymm0 + vpshufd $0x55,%ymm3,%ymm1 + vmovdqa %ymm0,256-256(%rcx) + vpshufd $0xaa,%ymm3,%ymm2 + vmovdqa %ymm1,288-256(%rcx) + vpshufd $0xff,%ymm3,%ymm3 + vmovdqa %ymm2,320-256(%rcx) + vmovdqa %ymm3,352-256(%rcx) + + vpshufd $0x00,%ymm15,%ymm12 + vpshufd $0x55,%ymm15,%ymm13 + vmovdqa %ymm12,384-512(%rax) + vpshufd $0xaa,%ymm15,%ymm14 + vmovdqa %ymm13,416-512(%rax) + vpshufd $0xff,%ymm15,%ymm15 + vmovdqa %ymm14,448-512(%rax) + vmovdqa %ymm15,480-512(%rax) + + vpshufd $0x00,%ymm7,%ymm4 + vpshufd $0x55,%ymm7,%ymm5 + vpaddd .Lincy(%rip),%ymm4,%ymm4 + vpshufd $0xaa,%ymm7,%ymm6 + vmovdqa %ymm5,544-512(%rax) + vpshufd $0xff,%ymm7,%ymm7 + vmovdqa %ymm6,576-512(%rax) + vmovdqa %ymm7,608-512(%rax) + + jmp .Loop_enter8x + +.align 32 +.Loop_outer8x: + vmovdqa 128-256(%rcx),%ymm8 + vmovdqa 160-256(%rcx),%ymm9 + vmovdqa 192-256(%rcx),%ymm10 + vmovdqa 224-256(%rcx),%ymm11 + vmovdqa 256-256(%rcx),%ymm0 + vmovdqa 288-256(%rcx),%ymm1 + vmovdqa 320-256(%rcx),%ymm2 + vmovdqa 352-256(%rcx),%ymm3 + vmovdqa 384-512(%rax),%ymm12 + vmovdqa 416-512(%rax),%ymm13 + vmovdqa 448-512(%rax),%ymm14 + vmovdqa 480-512(%rax),%ymm15 + vmovdqa 512-512(%rax),%ymm4 + vmovdqa 544-512(%rax),%ymm5 + vmovdqa 576-512(%rax),%ymm6 + vmovdqa 608-512(%rax),%ymm7 + vpaddd .Leight(%rip),%ymm4,%ymm4 + +.Loop_enter8x: + vmovdqa %ymm14,64(%rsp) + vmovdqa %ymm15,96(%rsp) + vbroadcasti128 (%r10),%ymm15 + vmovdqa %ymm4,512-512(%rax) + movl $10,%eax + jmp .Loop8x + +.align 32 +.Loop8x: + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $12,%ymm0,%ymm14 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $12,%ymm1,%ymm15 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $7,%ymm0,%ymm15 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $7,%ymm1,%ymm14 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vmovdqa %ymm12,0(%rsp) + vmovdqa %ymm13,32(%rsp) + vmovdqa 64(%rsp),%ymm12 + vmovdqa 96(%rsp),%ymm13 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $12,%ymm2,%ymm14 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $12,%ymm3,%ymm15 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $7,%ymm2,%ymm15 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $7,%ymm3,%ymm14 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $12,%ymm1,%ymm14 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $12,%ymm2,%ymm15 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $7,%ymm1,%ymm15 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $7,%ymm2,%ymm14 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vmovdqa %ymm12,64(%rsp) + vmovdqa %ymm13,96(%rsp) + vmovdqa 0(%rsp),%ymm12 + vmovdqa 32(%rsp),%ymm13 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $12,%ymm3,%ymm14 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $12,%ymm0,%ymm15 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $7,%ymm3,%ymm15 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $7,%ymm0,%ymm14 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + decl %eax + jnz .Loop8x + + leaq 512(%rsp),%rax + vpaddd 128-256(%rcx),%ymm8,%ymm8 + vpaddd 160-256(%rcx),%ymm9,%ymm9 + vpaddd 192-256(%rcx),%ymm10,%ymm10 + vpaddd 224-256(%rcx),%ymm11,%ymm11 + + vpunpckldq %ymm9,%ymm8,%ymm14 + vpunpckldq %ymm11,%ymm10,%ymm15 + vpunpckhdq %ymm9,%ymm8,%ymm8 + vpunpckhdq %ymm11,%ymm10,%ymm10 + vpunpcklqdq %ymm15,%ymm14,%ymm9 + vpunpckhqdq %ymm15,%ymm14,%ymm14 + vpunpcklqdq %ymm10,%ymm8,%ymm11 + vpunpckhqdq %ymm10,%ymm8,%ymm8 + vpaddd 256-256(%rcx),%ymm0,%ymm0 + vpaddd 288-256(%rcx),%ymm1,%ymm1 + vpaddd 320-256(%rcx),%ymm2,%ymm2 + vpaddd 352-256(%rcx),%ymm3,%ymm3 + + vpunpckldq %ymm1,%ymm0,%ymm10 + vpunpckldq %ymm3,%ymm2,%ymm15 + vpunpckhdq %ymm1,%ymm0,%ymm0 + vpunpckhdq %ymm3,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm10,%ymm1 + vpunpckhqdq %ymm15,%ymm10,%ymm10 + vpunpcklqdq %ymm2,%ymm0,%ymm3 + vpunpckhqdq %ymm2,%ymm0,%ymm0 + vperm2i128 $0x20,%ymm1,%ymm9,%ymm15 + vperm2i128 $0x31,%ymm1,%ymm9,%ymm1 + vperm2i128 $0x20,%ymm10,%ymm14,%ymm9 + vperm2i128 $0x31,%ymm10,%ymm14,%ymm10 + vperm2i128 $0x20,%ymm3,%ymm11,%ymm14 + vperm2i128 $0x31,%ymm3,%ymm11,%ymm3 + vperm2i128 $0x20,%ymm0,%ymm8,%ymm11 + vperm2i128 $0x31,%ymm0,%ymm8,%ymm0 + vmovdqa %ymm15,0(%rsp) + vmovdqa %ymm9,32(%rsp) + vmovdqa 64(%rsp),%ymm15 + vmovdqa 96(%rsp),%ymm9 + + vpaddd 384-512(%rax),%ymm12,%ymm12 + vpaddd 416-512(%rax),%ymm13,%ymm13 + vpaddd 448-512(%rax),%ymm15,%ymm15 + vpaddd 480-512(%rax),%ymm9,%ymm9 + + vpunpckldq %ymm13,%ymm12,%ymm2 + vpunpckldq %ymm9,%ymm15,%ymm8 + vpunpckhdq %ymm13,%ymm12,%ymm12 + vpunpckhdq %ymm9,%ymm15,%ymm15 + vpunpcklqdq %ymm8,%ymm2,%ymm13 + vpunpckhqdq %ymm8,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm12,%ymm9 + vpunpckhqdq %ymm15,%ymm12,%ymm12 + vpaddd 512-512(%rax),%ymm4,%ymm4 + vpaddd 544-512(%rax),%ymm5,%ymm5 + vpaddd 576-512(%rax),%ymm6,%ymm6 + vpaddd 608-512(%rax),%ymm7,%ymm7 + + vpunpckldq %ymm5,%ymm4,%ymm15 + vpunpckldq %ymm7,%ymm6,%ymm8 + vpunpckhdq %ymm5,%ymm4,%ymm4 + vpunpckhdq %ymm7,%ymm6,%ymm6 + vpunpcklqdq %ymm8,%ymm15,%ymm5 + vpunpckhqdq %ymm8,%ymm15,%ymm15 + vpunpcklqdq %ymm6,%ymm4,%ymm7 + vpunpckhqdq %ymm6,%ymm4,%ymm4 + vperm2i128 $0x20,%ymm5,%ymm13,%ymm8 + vperm2i128 $0x31,%ymm5,%ymm13,%ymm5 + vperm2i128 $0x20,%ymm15,%ymm2,%ymm13 + vperm2i128 $0x31,%ymm15,%ymm2,%ymm15 + vperm2i128 $0x20,%ymm7,%ymm9,%ymm2 + vperm2i128 $0x31,%ymm7,%ymm9,%ymm7 + vperm2i128 $0x20,%ymm4,%ymm12,%ymm9 + vperm2i128 $0x31,%ymm4,%ymm12,%ymm4 + vmovdqa 0(%rsp),%ymm6 + vmovdqa 32(%rsp),%ymm12 + + cmpq $512,%rdx + jb .Ltail8x + + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + leaq 128(%rsi),%rsi + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm12,%ymm12 + vpxor 32(%rsi),%ymm13,%ymm13 + vpxor 64(%rsi),%ymm10,%ymm10 + vpxor 96(%rsi),%ymm15,%ymm15 + leaq 128(%rsi),%rsi + vmovdqu %ymm12,0(%rdi) + vmovdqu %ymm13,32(%rdi) + vmovdqu %ymm10,64(%rdi) + vmovdqu %ymm15,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm14,%ymm14 + vpxor 32(%rsi),%ymm2,%ymm2 + vpxor 64(%rsi),%ymm3,%ymm3 + vpxor 96(%rsi),%ymm7,%ymm7 + leaq 128(%rsi),%rsi + vmovdqu %ymm14,0(%rdi) + vmovdqu %ymm2,32(%rdi) + vmovdqu %ymm3,64(%rdi) + vmovdqu %ymm7,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm11,%ymm11 + vpxor 32(%rsi),%ymm9,%ymm9 + vpxor 64(%rsi),%ymm0,%ymm0 + vpxor 96(%rsi),%ymm4,%ymm4 + leaq 128(%rsi),%rsi + vmovdqu %ymm11,0(%rdi) + vmovdqu %ymm9,32(%rdi) + vmovdqu %ymm0,64(%rdi) + vmovdqu %ymm4,96(%rdi) + leaq 128(%rdi),%rdi + + subq $512,%rdx + jnz .Loop_outer8x + + jmp .Ldone8x + +.Ltail8x: + cmpq $448,%rdx + jae .L448_or_more8x + cmpq $384,%rdx + jae .L384_or_more8x + cmpq $320,%rdx + jae .L320_or_more8x + cmpq $256,%rdx + jae .L256_or_more8x + cmpq $192,%rdx + jae .L192_or_more8x + cmpq $128,%rdx + jae .L128_or_more8x + cmpq $64,%rdx + jae .L64_or_more8x + + xorq %r10,%r10 + vmovdqa %ymm6,0(%rsp) + vmovdqa %ymm8,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L64_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + je .Ldone8x + + leaq 64(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm1,0(%rsp) + leaq 64(%rdi),%rdi + subq $64,%rdx + vmovdqa %ymm5,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L128_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + je .Ldone8x + + leaq 128(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm12,0(%rsp) + leaq 128(%rdi),%rdi + subq $128,%rdx + vmovdqa %ymm13,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L192_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + je .Ldone8x + + leaq 192(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm10,0(%rsp) + leaq 192(%rdi),%rdi + subq $192,%rdx + vmovdqa %ymm15,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L256_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + je .Ldone8x + + leaq 256(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm14,0(%rsp) + leaq 256(%rdi),%rdi + subq $256,%rdx + vmovdqa %ymm2,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L320_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + je .Ldone8x + + leaq 320(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm3,0(%rsp) + leaq 320(%rdi),%rdi + subq $320,%rdx + vmovdqa %ymm7,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L384_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + je .Ldone8x + + leaq 384(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm11,0(%rsp) + leaq 384(%rdi),%rdi + subq $384,%rdx + vmovdqa %ymm9,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L448_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vpxor 384(%rsi),%ymm11,%ymm11 + vpxor 416(%rsi),%ymm9,%ymm9 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + vmovdqu %ymm11,384(%rdi) + vmovdqu %ymm9,416(%rdi) + je .Ldone8x + + leaq 448(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm0,0(%rsp) + leaq 448(%rdi),%rdi + subq $448,%rdx + vmovdqa %ymm4,32(%rsp) + +.Loop_tail8x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz .Loop_tail8x + +.Ldone8x: + vzeroall + leaq (%r9),%rsp +.cfi_def_cfa_register rsp +.L8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_8x,.-ChaCha20_8x +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S new file mode 100644 index 00000000..ad277500 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S @@ -0,0 +1,1632 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + +.p2align 6 +L$zero: +.long 0,0,0,0 +L$one: +.long 1,0,0,0 +L$inc: +.long 0,1,2,3 +L$four: +.long 4,4,4,4 +L$incy: +.long 0,2,4,6,1,3,5,7 +L$eight: +.long 8,8,8,8,8,8,8,8 +L$rot16: +.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd +L$rot24: +.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe +L$sigma: +.byte 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0 +.p2align 6 +L$zeroz: +.long 0,0,0,0, 1,0,0,0, 2,0,0,0, 3,0,0,0 +L$fourz: +.long 4,0,0,0, 4,0,0,0, 4,0,0,0, 4,0,0,0 +L$incz: +.long 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +L$sixteen: +.long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.globl _ChaCha20_ctr32 +.private_extern _ChaCha20_ctr32 + +.p2align 6 +_ChaCha20_ctr32: + + cmpq $0,%rdx + je L$no_data + movq _OPENSSL_ia32cap_P+4(%rip),%r10 + testl $512,%r10d + jnz L$ChaCha20_ssse3 + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $64+24,%rsp + +L$ctr32_body: + + + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa L$one(%rip),%xmm4 + + + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq %rdx,%rbp + jmp L$oop_outer + +.p2align 5 +L$oop_outer: + movl $0x61707865,%eax + movl $0x3320646e,%ebx + movl $0x79622d32,%ecx + movl $0x6b206574,%edx + movl 16(%rsp),%r8d + movl 20(%rsp),%r9d + movl 24(%rsp),%r10d + movl 28(%rsp),%r11d + movd %xmm3,%r12d + movl 52(%rsp),%r13d + movl 56(%rsp),%r14d + movl 60(%rsp),%r15d + + movq %rbp,64+0(%rsp) + movl $10,%ebp + movq %rsi,64+8(%rsp) +.byte 102,72,15,126,214 + movq %rdi,64+16(%rsp) + movq %rsi,%rdi + shrq $32,%rdi + jmp L$oop + +.p2align 5 +L$oop: + addl %r8d,%eax + xorl %eax,%r12d + roll $16,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $16,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $12,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $12,%r9d + addl %r8d,%eax + xorl %eax,%r12d + roll $8,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $8,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $7,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $7,%r9d + movl %esi,32(%rsp) + movl %edi,36(%rsp) + movl 40(%rsp),%esi + movl 44(%rsp),%edi + addl %r10d,%ecx + xorl %ecx,%r14d + roll $16,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $16,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $12,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $12,%r11d + addl %r10d,%ecx + xorl %ecx,%r14d + roll $8,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $8,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $7,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $7,%r11d + addl %r9d,%eax + xorl %eax,%r15d + roll $16,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $16,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $12,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $12,%r10d + addl %r9d,%eax + xorl %eax,%r15d + roll $8,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $8,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $7,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $7,%r10d + movl %esi,40(%rsp) + movl %edi,44(%rsp) + movl 32(%rsp),%esi + movl 36(%rsp),%edi + addl %r11d,%ecx + xorl %ecx,%r13d + roll $16,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $16,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $12,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $12,%r8d + addl %r11d,%ecx + xorl %ecx,%r13d + roll $8,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $8,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $7,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $7,%r8d + decl %ebp + jnz L$oop + movl %edi,36(%rsp) + movl %esi,32(%rsp) + movq 64(%rsp),%rbp + movdqa %xmm2,%xmm1 + movq 64+8(%rsp),%rsi + paddd %xmm4,%xmm3 + movq 64+16(%rsp),%rdi + + addl $0x61707865,%eax + addl $0x3320646e,%ebx + addl $0x79622d32,%ecx + addl $0x6b206574,%edx + addl 16(%rsp),%r8d + addl 20(%rsp),%r9d + addl 24(%rsp),%r10d + addl 28(%rsp),%r11d + addl 48(%rsp),%r12d + addl 52(%rsp),%r13d + addl 56(%rsp),%r14d + addl 60(%rsp),%r15d + paddd 32(%rsp),%xmm1 + + cmpq $64,%rbp + jb L$tail + + xorl 0(%rsi),%eax + xorl 4(%rsi),%ebx + xorl 8(%rsi),%ecx + xorl 12(%rsi),%edx + xorl 16(%rsi),%r8d + xorl 20(%rsi),%r9d + xorl 24(%rsi),%r10d + xorl 28(%rsi),%r11d + movdqu 32(%rsi),%xmm0 + xorl 48(%rsi),%r12d + xorl 52(%rsi),%r13d + xorl 56(%rsi),%r14d + xorl 60(%rsi),%r15d + leaq 64(%rsi),%rsi + pxor %xmm1,%xmm0 + + movdqa %xmm2,32(%rsp) + movd %xmm3,48(%rsp) + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + movdqu %xmm0,32(%rdi) + movl %r12d,48(%rdi) + movl %r13d,52(%rdi) + movl %r14d,56(%rdi) + movl %r15d,60(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rbp + jnz L$oop_outer + + jmp L$done + +.p2align 4 +L$tail: + movl %eax,0(%rsp) + movl %ebx,4(%rsp) + xorq %rbx,%rbx + movl %ecx,8(%rsp) + movl %edx,12(%rsp) + movl %r8d,16(%rsp) + movl %r9d,20(%rsp) + movl %r10d,24(%rsp) + movl %r11d,28(%rsp) + movdqa %xmm1,32(%rsp) + movl %r12d,48(%rsp) + movl %r13d,52(%rsp) + movl %r14d,56(%rsp) + movl %r15d,60(%rsp) + +L$oop_tail: + movzbl (%rsi,%rbx,1),%eax + movzbl (%rsp,%rbx,1),%edx + leaq 1(%rbx),%rbx + xorl %edx,%eax + movb %al,-1(%rdi,%rbx,1) + decq %rbp + jnz L$oop_tail + +L$done: + leaq 64+24+48(%rsp),%rsi + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$no_data: + .byte 0xf3,0xc3 + + + +.p2align 5 +ChaCha20_ssse3: +L$ChaCha20_ssse3: + + movq %rsp,%r9 + + cmpq $128,%rdx + ja L$ChaCha20_4x + +L$do_sse3_after_all: + subq $64+8,%rsp + movdqa L$sigma(%rip),%xmm0 + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa L$rot16(%rip),%xmm6 + movdqa L$rot24(%rip),%xmm7 + + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq $10,%r8 + jmp L$oop_ssse3 + +.p2align 5 +L$oop_outer_ssse3: + movdqa L$one(%rip),%xmm3 + movdqa 0(%rsp),%xmm0 + movdqa 16(%rsp),%xmm1 + movdqa 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + movq $10,%r8 + movdqa %xmm3,48(%rsp) + jmp L$oop_ssse3 + +.p2align 5 +L$oop_ssse3: + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm1,%xmm1 + pshufd $147,%xmm3,%xmm3 + nop + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm1,%xmm1 + pshufd $57,%xmm3,%xmm3 + decq %r8 + jnz L$oop_ssse3 + paddd 0(%rsp),%xmm0 + paddd 16(%rsp),%xmm1 + paddd 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + + cmpq $64,%rdx + jb L$tail_ssse3 + + movdqu 0(%rsi),%xmm4 + movdqu 16(%rsi),%xmm5 + pxor %xmm4,%xmm0 + movdqu 32(%rsi),%xmm4 + pxor %xmm5,%xmm1 + movdqu 48(%rsi),%xmm5 + leaq 64(%rsi),%rsi + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm3 + + movdqu %xmm0,0(%rdi) + movdqu %xmm1,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rdx + jnz L$oop_outer_ssse3 + + jmp L$done_ssse3 + +.p2align 4 +L$tail_ssse3: + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + xorq %r8,%r8 + +L$oop_tail_ssse3: + movzbl (%rsi,%r8,1),%eax + movzbl (%rsp,%r8,1),%ecx + leaq 1(%r8),%r8 + xorl %ecx,%eax + movb %al,-1(%rdi,%r8,1) + decq %rdx + jnz L$oop_tail_ssse3 + +L$done_ssse3: + leaq (%r9),%rsp + +L$ssse3_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +ChaCha20_4x: +L$ChaCha20_4x: + + movq %rsp,%r9 + + movq %r10,%r11 + shrq $32,%r10 + testq $32,%r10 + jnz L$ChaCha20_8x + cmpq $192,%rdx + ja L$proceed4x + + andq $71303168,%r11 + cmpq $4194304,%r11 + je L$do_sse3_after_all + +L$proceed4x: + subq $0x140+8,%rsp + movdqa L$sigma(%rip),%xmm11 + movdqu (%rcx),%xmm15 + movdqu 16(%rcx),%xmm7 + movdqu (%r8),%xmm3 + leaq 256(%rsp),%rcx + leaq L$rot16(%rip),%r10 + leaq L$rot24(%rip),%r11 + + pshufd $0x00,%xmm11,%xmm8 + pshufd $0x55,%xmm11,%xmm9 + movdqa %xmm8,64(%rsp) + pshufd $0xaa,%xmm11,%xmm10 + movdqa %xmm9,80(%rsp) + pshufd $0xff,%xmm11,%xmm11 + movdqa %xmm10,96(%rsp) + movdqa %xmm11,112(%rsp) + + pshufd $0x00,%xmm15,%xmm12 + pshufd $0x55,%xmm15,%xmm13 + movdqa %xmm12,128-256(%rcx) + pshufd $0xaa,%xmm15,%xmm14 + movdqa %xmm13,144-256(%rcx) + pshufd $0xff,%xmm15,%xmm15 + movdqa %xmm14,160-256(%rcx) + movdqa %xmm15,176-256(%rcx) + + pshufd $0x00,%xmm7,%xmm4 + pshufd $0x55,%xmm7,%xmm5 + movdqa %xmm4,192-256(%rcx) + pshufd $0xaa,%xmm7,%xmm6 + movdqa %xmm5,208-256(%rcx) + pshufd $0xff,%xmm7,%xmm7 + movdqa %xmm6,224-256(%rcx) + movdqa %xmm7,240-256(%rcx) + + pshufd $0x00,%xmm3,%xmm0 + pshufd $0x55,%xmm3,%xmm1 + paddd L$inc(%rip),%xmm0 + pshufd $0xaa,%xmm3,%xmm2 + movdqa %xmm1,272-256(%rcx) + pshufd $0xff,%xmm3,%xmm3 + movdqa %xmm2,288-256(%rcx) + movdqa %xmm3,304-256(%rcx) + + jmp L$oop_enter4x + +.p2align 5 +L$oop_outer4x: + movdqa 64(%rsp),%xmm8 + movdqa 80(%rsp),%xmm9 + movdqa 96(%rsp),%xmm10 + movdqa 112(%rsp),%xmm11 + movdqa 128-256(%rcx),%xmm12 + movdqa 144-256(%rcx),%xmm13 + movdqa 160-256(%rcx),%xmm14 + movdqa 176-256(%rcx),%xmm15 + movdqa 192-256(%rcx),%xmm4 + movdqa 208-256(%rcx),%xmm5 + movdqa 224-256(%rcx),%xmm6 + movdqa 240-256(%rcx),%xmm7 + movdqa 256-256(%rcx),%xmm0 + movdqa 272-256(%rcx),%xmm1 + movdqa 288-256(%rcx),%xmm2 + movdqa 304-256(%rcx),%xmm3 + paddd L$four(%rip),%xmm0 + +L$oop_enter4x: + movdqa %xmm6,32(%rsp) + movdqa %xmm7,48(%rsp) + movdqa (%r10),%xmm7 + movl $10,%eax + movdqa %xmm0,256-256(%rcx) + jmp L$oop4x + +.p2align 5 +L$oop4x: + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,199 +.byte 102,15,56,0,207 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm6 + pslld $12,%xmm12 + psrld $20,%xmm6 + movdqa %xmm13,%xmm7 + pslld $12,%xmm13 + por %xmm6,%xmm12 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm13 + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm7 + pslld $7,%xmm12 + psrld $25,%xmm7 + movdqa %xmm13,%xmm6 + pslld $7,%xmm13 + por %xmm7,%xmm12 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm13 + movdqa %xmm4,0(%rsp) + movdqa %xmm5,16(%rsp) + movdqa 32(%rsp),%xmm4 + movdqa 48(%rsp),%xmm5 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,215 +.byte 102,15,56,0,223 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm6 + pslld $12,%xmm14 + psrld $20,%xmm6 + movdqa %xmm15,%xmm7 + pslld $12,%xmm15 + por %xmm6,%xmm14 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm15 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm7 + pslld $7,%xmm14 + psrld $25,%xmm7 + movdqa %xmm15,%xmm6 + pslld $7,%xmm15 + por %xmm7,%xmm14 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm15 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,223 +.byte 102,15,56,0,199 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm6 + pslld $12,%xmm13 + psrld $20,%xmm6 + movdqa %xmm14,%xmm7 + pslld $12,%xmm14 + por %xmm6,%xmm13 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm14 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,222 +.byte 102,15,56,0,198 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm7 + pslld $7,%xmm13 + psrld $25,%xmm7 + movdqa %xmm14,%xmm6 + pslld $7,%xmm14 + por %xmm7,%xmm13 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm14 + movdqa %xmm4,32(%rsp) + movdqa %xmm5,48(%rsp) + movdqa 0(%rsp),%xmm4 + movdqa 16(%rsp),%xmm5 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm6 + pslld $12,%xmm15 + psrld $20,%xmm6 + movdqa %xmm12,%xmm7 + pslld $12,%xmm12 + por %xmm6,%xmm15 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm12 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm7 + pslld $7,%xmm15 + psrld $25,%xmm7 + movdqa %xmm12,%xmm6 + pslld $7,%xmm12 + por %xmm7,%xmm15 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm12 + decl %eax + jnz L$oop4x + + paddd 64(%rsp),%xmm8 + paddd 80(%rsp),%xmm9 + paddd 96(%rsp),%xmm10 + paddd 112(%rsp),%xmm11 + + movdqa %xmm8,%xmm6 + punpckldq %xmm9,%xmm8 + movdqa %xmm10,%xmm7 + punpckldq %xmm11,%xmm10 + punpckhdq %xmm9,%xmm6 + punpckhdq %xmm11,%xmm7 + movdqa %xmm8,%xmm9 + punpcklqdq %xmm10,%xmm8 + movdqa %xmm6,%xmm11 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm10,%xmm9 + punpckhqdq %xmm7,%xmm11 + paddd 128-256(%rcx),%xmm12 + paddd 144-256(%rcx),%xmm13 + paddd 160-256(%rcx),%xmm14 + paddd 176-256(%rcx),%xmm15 + + movdqa %xmm8,0(%rsp) + movdqa %xmm9,16(%rsp) + movdqa 32(%rsp),%xmm8 + movdqa 48(%rsp),%xmm9 + + movdqa %xmm12,%xmm10 + punpckldq %xmm13,%xmm12 + movdqa %xmm14,%xmm7 + punpckldq %xmm15,%xmm14 + punpckhdq %xmm13,%xmm10 + punpckhdq %xmm15,%xmm7 + movdqa %xmm12,%xmm13 + punpcklqdq %xmm14,%xmm12 + movdqa %xmm10,%xmm15 + punpcklqdq %xmm7,%xmm10 + punpckhqdq %xmm14,%xmm13 + punpckhqdq %xmm7,%xmm15 + paddd 192-256(%rcx),%xmm4 + paddd 208-256(%rcx),%xmm5 + paddd 224-256(%rcx),%xmm8 + paddd 240-256(%rcx),%xmm9 + + movdqa %xmm6,32(%rsp) + movdqa %xmm11,48(%rsp) + + movdqa %xmm4,%xmm14 + punpckldq %xmm5,%xmm4 + movdqa %xmm8,%xmm7 + punpckldq %xmm9,%xmm8 + punpckhdq %xmm5,%xmm14 + punpckhdq %xmm9,%xmm7 + movdqa %xmm4,%xmm5 + punpcklqdq %xmm8,%xmm4 + movdqa %xmm14,%xmm9 + punpcklqdq %xmm7,%xmm14 + punpckhqdq %xmm8,%xmm5 + punpckhqdq %xmm7,%xmm9 + paddd 256-256(%rcx),%xmm0 + paddd 272-256(%rcx),%xmm1 + paddd 288-256(%rcx),%xmm2 + paddd 304-256(%rcx),%xmm3 + + movdqa %xmm0,%xmm8 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm8 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm8,%xmm3 + punpcklqdq %xmm7,%xmm8 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + cmpq $256,%rdx + jb L$tail4x + + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 48(%rsp),%xmm6 + pxor %xmm15,%xmm11 + pxor %xmm9,%xmm2 + pxor %xmm3,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + + subq $256,%rdx + jnz L$oop_outer4x + + jmp L$done4x + +L$tail4x: + cmpq $192,%rdx + jae L$192_or_more4x + cmpq $128,%rdx + jae L$128_or_more4x + cmpq $64,%rdx + jae L$64_or_more4x + + + xorq %r10,%r10 + + movdqa %xmm12,16(%rsp) + movdqa %xmm4,32(%rsp) + movdqa %xmm0,48(%rsp) + jmp L$oop_tail4x + +.p2align 5 +L$64_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je L$done4x + + movdqa 16(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm13,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm5,32(%rsp) + subq $64,%rdx + movdqa %xmm1,48(%rsp) + jmp L$oop_tail4x + +.p2align 5 +L$128_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + je L$done4x + + movdqa 32(%rsp),%xmm6 + leaq 128(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm10,16(%rsp) + leaq 128(%rdi),%rdi + movdqa %xmm14,32(%rsp) + subq $128,%rdx + movdqa %xmm8,48(%rsp) + jmp L$oop_tail4x + +.p2align 5 +L$192_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je L$done4x + + movdqa 48(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm15,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm9,32(%rsp) + subq $192,%rdx + movdqa %xmm3,48(%rsp) + +L$oop_tail4x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz L$oop_tail4x + +L$done4x: + leaq (%r9),%rsp + +L$4x_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +ChaCha20_8x: +L$ChaCha20_8x: + + movq %rsp,%r9 + + subq $0x280+8,%rsp + andq $-32,%rsp + vzeroupper + + + + + + + + + + + vbroadcasti128 L$sigma(%rip),%ymm11 + vbroadcasti128 (%rcx),%ymm3 + vbroadcasti128 16(%rcx),%ymm15 + vbroadcasti128 (%r8),%ymm7 + leaq 256(%rsp),%rcx + leaq 512(%rsp),%rax + leaq L$rot16(%rip),%r10 + leaq L$rot24(%rip),%r11 + + vpshufd $0x00,%ymm11,%ymm8 + vpshufd $0x55,%ymm11,%ymm9 + vmovdqa %ymm8,128-256(%rcx) + vpshufd $0xaa,%ymm11,%ymm10 + vmovdqa %ymm9,160-256(%rcx) + vpshufd $0xff,%ymm11,%ymm11 + vmovdqa %ymm10,192-256(%rcx) + vmovdqa %ymm11,224-256(%rcx) + + vpshufd $0x00,%ymm3,%ymm0 + vpshufd $0x55,%ymm3,%ymm1 + vmovdqa %ymm0,256-256(%rcx) + vpshufd $0xaa,%ymm3,%ymm2 + vmovdqa %ymm1,288-256(%rcx) + vpshufd $0xff,%ymm3,%ymm3 + vmovdqa %ymm2,320-256(%rcx) + vmovdqa %ymm3,352-256(%rcx) + + vpshufd $0x00,%ymm15,%ymm12 + vpshufd $0x55,%ymm15,%ymm13 + vmovdqa %ymm12,384-512(%rax) + vpshufd $0xaa,%ymm15,%ymm14 + vmovdqa %ymm13,416-512(%rax) + vpshufd $0xff,%ymm15,%ymm15 + vmovdqa %ymm14,448-512(%rax) + vmovdqa %ymm15,480-512(%rax) + + vpshufd $0x00,%ymm7,%ymm4 + vpshufd $0x55,%ymm7,%ymm5 + vpaddd L$incy(%rip),%ymm4,%ymm4 + vpshufd $0xaa,%ymm7,%ymm6 + vmovdqa %ymm5,544-512(%rax) + vpshufd $0xff,%ymm7,%ymm7 + vmovdqa %ymm6,576-512(%rax) + vmovdqa %ymm7,608-512(%rax) + + jmp L$oop_enter8x + +.p2align 5 +L$oop_outer8x: + vmovdqa 128-256(%rcx),%ymm8 + vmovdqa 160-256(%rcx),%ymm9 + vmovdqa 192-256(%rcx),%ymm10 + vmovdqa 224-256(%rcx),%ymm11 + vmovdqa 256-256(%rcx),%ymm0 + vmovdqa 288-256(%rcx),%ymm1 + vmovdqa 320-256(%rcx),%ymm2 + vmovdqa 352-256(%rcx),%ymm3 + vmovdqa 384-512(%rax),%ymm12 + vmovdqa 416-512(%rax),%ymm13 + vmovdqa 448-512(%rax),%ymm14 + vmovdqa 480-512(%rax),%ymm15 + vmovdqa 512-512(%rax),%ymm4 + vmovdqa 544-512(%rax),%ymm5 + vmovdqa 576-512(%rax),%ymm6 + vmovdqa 608-512(%rax),%ymm7 + vpaddd L$eight(%rip),%ymm4,%ymm4 + +L$oop_enter8x: + vmovdqa %ymm14,64(%rsp) + vmovdqa %ymm15,96(%rsp) + vbroadcasti128 (%r10),%ymm15 + vmovdqa %ymm4,512-512(%rax) + movl $10,%eax + jmp L$oop8x + +.p2align 5 +L$oop8x: + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $12,%ymm0,%ymm14 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $12,%ymm1,%ymm15 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $7,%ymm0,%ymm15 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $7,%ymm1,%ymm14 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vmovdqa %ymm12,0(%rsp) + vmovdqa %ymm13,32(%rsp) + vmovdqa 64(%rsp),%ymm12 + vmovdqa 96(%rsp),%ymm13 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $12,%ymm2,%ymm14 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $12,%ymm3,%ymm15 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $7,%ymm2,%ymm15 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $7,%ymm3,%ymm14 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $12,%ymm1,%ymm14 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $12,%ymm2,%ymm15 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $7,%ymm1,%ymm15 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $7,%ymm2,%ymm14 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vmovdqa %ymm12,64(%rsp) + vmovdqa %ymm13,96(%rsp) + vmovdqa 0(%rsp),%ymm12 + vmovdqa 32(%rsp),%ymm13 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $12,%ymm3,%ymm14 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $12,%ymm0,%ymm15 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $7,%ymm3,%ymm15 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $7,%ymm0,%ymm14 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + decl %eax + jnz L$oop8x + + leaq 512(%rsp),%rax + vpaddd 128-256(%rcx),%ymm8,%ymm8 + vpaddd 160-256(%rcx),%ymm9,%ymm9 + vpaddd 192-256(%rcx),%ymm10,%ymm10 + vpaddd 224-256(%rcx),%ymm11,%ymm11 + + vpunpckldq %ymm9,%ymm8,%ymm14 + vpunpckldq %ymm11,%ymm10,%ymm15 + vpunpckhdq %ymm9,%ymm8,%ymm8 + vpunpckhdq %ymm11,%ymm10,%ymm10 + vpunpcklqdq %ymm15,%ymm14,%ymm9 + vpunpckhqdq %ymm15,%ymm14,%ymm14 + vpunpcklqdq %ymm10,%ymm8,%ymm11 + vpunpckhqdq %ymm10,%ymm8,%ymm8 + vpaddd 256-256(%rcx),%ymm0,%ymm0 + vpaddd 288-256(%rcx),%ymm1,%ymm1 + vpaddd 320-256(%rcx),%ymm2,%ymm2 + vpaddd 352-256(%rcx),%ymm3,%ymm3 + + vpunpckldq %ymm1,%ymm0,%ymm10 + vpunpckldq %ymm3,%ymm2,%ymm15 + vpunpckhdq %ymm1,%ymm0,%ymm0 + vpunpckhdq %ymm3,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm10,%ymm1 + vpunpckhqdq %ymm15,%ymm10,%ymm10 + vpunpcklqdq %ymm2,%ymm0,%ymm3 + vpunpckhqdq %ymm2,%ymm0,%ymm0 + vperm2i128 $0x20,%ymm1,%ymm9,%ymm15 + vperm2i128 $0x31,%ymm1,%ymm9,%ymm1 + vperm2i128 $0x20,%ymm10,%ymm14,%ymm9 + vperm2i128 $0x31,%ymm10,%ymm14,%ymm10 + vperm2i128 $0x20,%ymm3,%ymm11,%ymm14 + vperm2i128 $0x31,%ymm3,%ymm11,%ymm3 + vperm2i128 $0x20,%ymm0,%ymm8,%ymm11 + vperm2i128 $0x31,%ymm0,%ymm8,%ymm0 + vmovdqa %ymm15,0(%rsp) + vmovdqa %ymm9,32(%rsp) + vmovdqa 64(%rsp),%ymm15 + vmovdqa 96(%rsp),%ymm9 + + vpaddd 384-512(%rax),%ymm12,%ymm12 + vpaddd 416-512(%rax),%ymm13,%ymm13 + vpaddd 448-512(%rax),%ymm15,%ymm15 + vpaddd 480-512(%rax),%ymm9,%ymm9 + + vpunpckldq %ymm13,%ymm12,%ymm2 + vpunpckldq %ymm9,%ymm15,%ymm8 + vpunpckhdq %ymm13,%ymm12,%ymm12 + vpunpckhdq %ymm9,%ymm15,%ymm15 + vpunpcklqdq %ymm8,%ymm2,%ymm13 + vpunpckhqdq %ymm8,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm12,%ymm9 + vpunpckhqdq %ymm15,%ymm12,%ymm12 + vpaddd 512-512(%rax),%ymm4,%ymm4 + vpaddd 544-512(%rax),%ymm5,%ymm5 + vpaddd 576-512(%rax),%ymm6,%ymm6 + vpaddd 608-512(%rax),%ymm7,%ymm7 + + vpunpckldq %ymm5,%ymm4,%ymm15 + vpunpckldq %ymm7,%ymm6,%ymm8 + vpunpckhdq %ymm5,%ymm4,%ymm4 + vpunpckhdq %ymm7,%ymm6,%ymm6 + vpunpcklqdq %ymm8,%ymm15,%ymm5 + vpunpckhqdq %ymm8,%ymm15,%ymm15 + vpunpcklqdq %ymm6,%ymm4,%ymm7 + vpunpckhqdq %ymm6,%ymm4,%ymm4 + vperm2i128 $0x20,%ymm5,%ymm13,%ymm8 + vperm2i128 $0x31,%ymm5,%ymm13,%ymm5 + vperm2i128 $0x20,%ymm15,%ymm2,%ymm13 + vperm2i128 $0x31,%ymm15,%ymm2,%ymm15 + vperm2i128 $0x20,%ymm7,%ymm9,%ymm2 + vperm2i128 $0x31,%ymm7,%ymm9,%ymm7 + vperm2i128 $0x20,%ymm4,%ymm12,%ymm9 + vperm2i128 $0x31,%ymm4,%ymm12,%ymm4 + vmovdqa 0(%rsp),%ymm6 + vmovdqa 32(%rsp),%ymm12 + + cmpq $512,%rdx + jb L$tail8x + + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + leaq 128(%rsi),%rsi + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm12,%ymm12 + vpxor 32(%rsi),%ymm13,%ymm13 + vpxor 64(%rsi),%ymm10,%ymm10 + vpxor 96(%rsi),%ymm15,%ymm15 + leaq 128(%rsi),%rsi + vmovdqu %ymm12,0(%rdi) + vmovdqu %ymm13,32(%rdi) + vmovdqu %ymm10,64(%rdi) + vmovdqu %ymm15,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm14,%ymm14 + vpxor 32(%rsi),%ymm2,%ymm2 + vpxor 64(%rsi),%ymm3,%ymm3 + vpxor 96(%rsi),%ymm7,%ymm7 + leaq 128(%rsi),%rsi + vmovdqu %ymm14,0(%rdi) + vmovdqu %ymm2,32(%rdi) + vmovdqu %ymm3,64(%rdi) + vmovdqu %ymm7,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm11,%ymm11 + vpxor 32(%rsi),%ymm9,%ymm9 + vpxor 64(%rsi),%ymm0,%ymm0 + vpxor 96(%rsi),%ymm4,%ymm4 + leaq 128(%rsi),%rsi + vmovdqu %ymm11,0(%rdi) + vmovdqu %ymm9,32(%rdi) + vmovdqu %ymm0,64(%rdi) + vmovdqu %ymm4,96(%rdi) + leaq 128(%rdi),%rdi + + subq $512,%rdx + jnz L$oop_outer8x + + jmp L$done8x + +L$tail8x: + cmpq $448,%rdx + jae L$448_or_more8x + cmpq $384,%rdx + jae L$384_or_more8x + cmpq $320,%rdx + jae L$320_or_more8x + cmpq $256,%rdx + jae L$256_or_more8x + cmpq $192,%rdx + jae L$192_or_more8x + cmpq $128,%rdx + jae L$128_or_more8x + cmpq $64,%rdx + jae L$64_or_more8x + + xorq %r10,%r10 + vmovdqa %ymm6,0(%rsp) + vmovdqa %ymm8,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$64_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + je L$done8x + + leaq 64(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm1,0(%rsp) + leaq 64(%rdi),%rdi + subq $64,%rdx + vmovdqa %ymm5,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$128_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + je L$done8x + + leaq 128(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm12,0(%rsp) + leaq 128(%rdi),%rdi + subq $128,%rdx + vmovdqa %ymm13,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$192_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + je L$done8x + + leaq 192(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm10,0(%rsp) + leaq 192(%rdi),%rdi + subq $192,%rdx + vmovdqa %ymm15,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$256_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + je L$done8x + + leaq 256(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm14,0(%rsp) + leaq 256(%rdi),%rdi + subq $256,%rdx + vmovdqa %ymm2,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$320_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + je L$done8x + + leaq 320(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm3,0(%rsp) + leaq 320(%rdi),%rdi + subq $320,%rdx + vmovdqa %ymm7,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$384_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + je L$done8x + + leaq 384(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm11,0(%rsp) + leaq 384(%rdi),%rdi + subq $384,%rdx + vmovdqa %ymm9,32(%rsp) + jmp L$oop_tail8x + +.p2align 5 +L$448_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vpxor 384(%rsi),%ymm11,%ymm11 + vpxor 416(%rsi),%ymm9,%ymm9 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + vmovdqu %ymm11,384(%rdi) + vmovdqu %ymm9,416(%rdi) + je L$done8x + + leaq 448(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm0,0(%rsp) + leaq 448(%rdi),%rdi + subq $448,%rdx + vmovdqa %ymm4,32(%rsp) + +L$oop_tail8x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz L$oop_tail8x + +L$done8x: + vzeroall + leaq (%r9),%rsp + +L$8x_epilogue: + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha.c new file mode 100644 index 00000000..e9f4a0d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/chacha.c @@ -0,0 +1,173 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Adapted from the public domain, estream code by D. Bernstein. + +#include + +#include +#include + +#include "../internal.h" +#include "internal.h" + + +// sigma contains the ChaCha constants, which happen to be an ASCII string. +static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', + '2', '-', 'b', 'y', 't', 'e', ' ', 'k' }; + +// QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. +#define QUARTERROUND(a, b, c, d) \ + x[a] += x[b]; \ + x[d] = CRYPTO_rotl_u32(x[d] ^ x[a], 16); \ + x[c] += x[d]; \ + x[b] = CRYPTO_rotl_u32(x[b] ^ x[c], 12); \ + x[a] += x[b]; \ + x[d] = CRYPTO_rotl_u32(x[d] ^ x[a], 8); \ + x[c] += x[d]; \ + x[b] = CRYPTO_rotl_u32(x[b] ^ x[c], 7); + +void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32], + const uint8_t nonce[16]) { + uint32_t x[16]; + OPENSSL_memcpy(x, sigma, sizeof(sigma)); + OPENSSL_memcpy(&x[4], key, 32); + OPENSSL_memcpy(&x[12], nonce, 16); + + for (size_t i = 0; i < 20; i += 2) { + QUARTERROUND(0, 4, 8, 12) + QUARTERROUND(1, 5, 9, 13) + QUARTERROUND(2, 6, 10, 14) + QUARTERROUND(3, 7, 11, 15) + QUARTERROUND(0, 5, 10, 15) + QUARTERROUND(1, 6, 11, 12) + QUARTERROUND(2, 7, 8, 13) + QUARTERROUND(3, 4, 9, 14) + } + + OPENSSL_memcpy(out, &x[0], sizeof(uint32_t) * 4); + OPENSSL_memcpy(&out[16], &x[12], sizeof(uint32_t) * 4); +} + +#if defined(CHACHA20_ASM) + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t counter_nonce[4]; + counter_nonce[0] = counter; + counter_nonce[1] = CRYPTO_load_u32_le(nonce + 0); + counter_nonce[2] = CRYPTO_load_u32_le(nonce + 4); + counter_nonce[3] = CRYPTO_load_u32_le(nonce + 8); + + const uint32_t *key_ptr = (const uint32_t *)key; +#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) + // The assembly expects the key to be four-byte aligned. + uint32_t key_u32[8]; + if ((((uintptr_t)key) & 3) != 0) { + key_u32[0] = CRYPTO_load_u32_le(key + 0); + key_u32[1] = CRYPTO_load_u32_le(key + 4); + key_u32[2] = CRYPTO_load_u32_le(key + 8); + key_u32[3] = CRYPTO_load_u32_le(key + 12); + key_u32[4] = CRYPTO_load_u32_le(key + 16); + key_u32[5] = CRYPTO_load_u32_le(key + 20); + key_u32[6] = CRYPTO_load_u32_le(key + 24); + key_u32[7] = CRYPTO_load_u32_le(key + 28); + + key_ptr = key_u32; + } +#endif + + ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce); +} + +#else + +// chacha_core performs 20 rounds of ChaCha on the input words in +// |input| and writes the 64 output bytes to |output|. +static void chacha_core(uint8_t output[64], const uint32_t input[16]) { + uint32_t x[16]; + int i; + + OPENSSL_memcpy(x, input, sizeof(uint32_t) * 16); + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12) + QUARTERROUND(1, 5, 9, 13) + QUARTERROUND(2, 6, 10, 14) + QUARTERROUND(3, 7, 11, 15) + QUARTERROUND(0, 5, 10, 15) + QUARTERROUND(1, 6, 11, 12) + QUARTERROUND(2, 7, 8, 13) + QUARTERROUND(3, 4, 9, 14) + } + + for (i = 0; i < 16; ++i) { + x[i] += input[i]; + } + for (i = 0; i < 16; ++i) { + CRYPTO_store_u32_le(output + 4 * i, x[i]); + } +} + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t input[16]; + uint8_t buf[64]; + size_t todo, i; + + input[0] = CRYPTO_load_u32_le(sigma + 0); + input[1] = CRYPTO_load_u32_le(sigma + 4); + input[2] = CRYPTO_load_u32_le(sigma + 8); + input[3] = CRYPTO_load_u32_le(sigma + 12); + + input[4] = CRYPTO_load_u32_le(key + 0); + input[5] = CRYPTO_load_u32_le(key + 4); + input[6] = CRYPTO_load_u32_le(key + 8); + input[7] = CRYPTO_load_u32_le(key + 12); + + input[8] = CRYPTO_load_u32_le(key + 16); + input[9] = CRYPTO_load_u32_le(key + 20); + input[10] = CRYPTO_load_u32_le(key + 24); + input[11] = CRYPTO_load_u32_le(key + 28); + + input[12] = counter; + input[13] = CRYPTO_load_u32_le(nonce + 0); + input[14] = CRYPTO_load_u32_le(nonce + 4); + input[15] = CRYPTO_load_u32_le(nonce + 8); + + while (in_len > 0) { + todo = sizeof(buf); + if (in_len < todo) { + todo = in_len; + } + + chacha_core(buf, input); + for (i = 0; i < todo; i++) { + out[i] = in[i] ^ buf[i]; + } + + out += todo; + in += todo; + in_len -= todo; + + input[12]++; + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/internal.h new file mode 100644 index 00000000..97719f67 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/chacha/internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CHACHA_INTERNAL +#define OPENSSL_HEADER_CHACHA_INTERNAL + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CRYPTO_hchacha20 computes the HChaCha20 function, which should only be used +// as part of XChaCha20. +void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32], + const uint8_t nonce[16]); + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define CHACHA20_ASM + +// ChaCha20_ctr32 is defined in asm/chacha-*.pl. +void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len, + const uint32_t key[8], const uint32_t counter[4]); +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CHACHA_INTERNAL diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S new file mode 100644 index 00000000..37877d7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S @@ -0,0 +1,3086 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.data + +.align 16 +one: +.quad 1,0 +two: +.quad 2,0 +three: +.quad 3,0 +four: +.quad 4,0 +five: +.quad 5,0 +six: +.quad 6,0 +seven: +.quad 7,0 +eight: +.quad 8,0 + +OR_MASK: +.long 0x00000000,0x00000000,0x00000000,0x80000000 +poly: +.quad 0x1, 0xc200000000000000 +mask: +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d +con1: +.long 1,1,1,1 +con2: +.long 0x1b,0x1b,0x1b,0x1b +con3: +.byte -1,-1,-1,-1,-1,-1,-1,-1,4,5,6,7,4,5,6,7 +and_mask: +.long 0,0xffffffff, 0xffffffff, 0xffffffff +.text +.type GFMUL,@function +.align 16 +GFMUL: +.cfi_startproc + vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2 + vpclmulqdq $0x11,%xmm1,%xmm0,%xmm5 + vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3 + vpclmulqdq $0x01,%xmm1,%xmm0,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm3,%xmm5,%xmm5 + + vpclmulqdq $0x10,poly(%rip),%xmm2,%xmm3 + vpshufd $78,%xmm2,%xmm4 + vpxor %xmm4,%xmm3,%xmm2 + + vpclmulqdq $0x10,poly(%rip),%xmm2,%xmm3 + vpshufd $78,%xmm2,%xmm4 + vpxor %xmm4,%xmm3,%xmm2 + + vpxor %xmm5,%xmm2,%xmm0 + .byte 0xf3,0xc3 +.cfi_endproc +.size GFMUL, .-GFMUL +.globl aesgcmsiv_htable_init +.hidden aesgcmsiv_htable_init +.type aesgcmsiv_htable_init,@function +.align 16 +aesgcmsiv_htable_init: +.cfi_startproc + vmovdqa (%rsi),%xmm0 + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm0,(%rdi) + call GFMUL + vmovdqa %xmm0,16(%rdi) + call GFMUL + vmovdqa %xmm0,32(%rdi) + call GFMUL + vmovdqa %xmm0,48(%rdi) + call GFMUL + vmovdqa %xmm0,64(%rdi) + call GFMUL + vmovdqa %xmm0,80(%rdi) + call GFMUL + vmovdqa %xmm0,96(%rdi) + call GFMUL + vmovdqa %xmm0,112(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aesgcmsiv_htable_init, .-aesgcmsiv_htable_init +.globl aesgcmsiv_htable6_init +.hidden aesgcmsiv_htable6_init +.type aesgcmsiv_htable6_init,@function +.align 16 +aesgcmsiv_htable6_init: +.cfi_startproc + vmovdqa (%rsi),%xmm0 + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm0,(%rdi) + call GFMUL + vmovdqa %xmm0,16(%rdi) + call GFMUL + vmovdqa %xmm0,32(%rdi) + call GFMUL + vmovdqa %xmm0,48(%rdi) + call GFMUL + vmovdqa %xmm0,64(%rdi) + call GFMUL + vmovdqa %xmm0,80(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aesgcmsiv_htable6_init, .-aesgcmsiv_htable6_init +.globl aesgcmsiv_htable_polyval +.hidden aesgcmsiv_htable_polyval +.type aesgcmsiv_htable_polyval,@function +.align 16 +aesgcmsiv_htable_polyval: +.cfi_startproc + testq %rdx,%rdx + jnz .Lhtable_polyval_start + .byte 0xf3,0xc3 + +.Lhtable_polyval_start: + vzeroall + + + + movq %rdx,%r11 + andq $127,%r11 + + jz .Lhtable_polyval_no_prefix + + vpxor %xmm9,%xmm9,%xmm9 + vmovdqa (%rcx),%xmm1 + subq %r11,%rdx + + subq $16,%r11 + + + vmovdqu (%rsi),%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + + vpclmulqdq $0x01,(%rdi,%r11,1),%xmm0,%xmm5 + vpclmulqdq $0x00,(%rdi,%r11,1),%xmm0,%xmm3 + vpclmulqdq $0x11,(%rdi,%r11,1),%xmm0,%xmm4 + vpclmulqdq $0x10,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + leaq 16(%rsi),%rsi + testq %r11,%r11 + jnz .Lhtable_polyval_prefix_loop + jmp .Lhtable_polyval_prefix_complete + + +.align 64 +.Lhtable_polyval_prefix_loop: + subq $16,%r11 + + vmovdqu (%rsi),%xmm0 + + vpclmulqdq $0x00,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x01,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x10,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + testq %r11,%r11 + + leaq 16(%rsi),%rsi + + jnz .Lhtable_polyval_prefix_loop + +.Lhtable_polyval_prefix_complete: + vpsrldq $8,%xmm5,%xmm6 + vpslldq $8,%xmm5,%xmm5 + + vpxor %xmm6,%xmm4,%xmm9 + vpxor %xmm5,%xmm3,%xmm1 + + jmp .Lhtable_polyval_main_loop + +.Lhtable_polyval_no_prefix: + + + + + vpxor %xmm1,%xmm1,%xmm1 + vmovdqa (%rcx),%xmm9 + +.align 64 +.Lhtable_polyval_main_loop: + subq $0x80,%rdx + jb .Lhtable_polyval_out + + vmovdqu 112(%rsi),%xmm0 + + vpclmulqdq $0x01,(%rdi),%xmm0,%xmm5 + vpclmulqdq $0x00,(%rdi),%xmm0,%xmm3 + vpclmulqdq $0x11,(%rdi),%xmm0,%xmm4 + vpclmulqdq $0x10,(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 96(%rsi),%xmm0 + vpclmulqdq $0x01,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + + vmovdqu 80(%rsi),%xmm0 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm7 + vpalignr $8,%xmm1,%xmm1,%xmm1 + + vpclmulqdq $0x01,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm7,%xmm1,%xmm1 + + vmovdqu 64(%rsi),%xmm0 + + vpclmulqdq $0x01,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 48(%rsi),%xmm0 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm7 + vpalignr $8,%xmm1,%xmm1,%xmm1 + + vpclmulqdq $0x01,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm7,%xmm1,%xmm1 + + vmovdqu 32(%rsi),%xmm0 + + vpclmulqdq $0x01,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm9,%xmm1,%xmm1 + + vmovdqu 16(%rsi),%xmm0 + + vpclmulqdq $0x01,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 0(%rsi),%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + + vpclmulqdq $0x01,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpsrldq $8,%xmm5,%xmm6 + vpslldq $8,%xmm5,%xmm5 + + vpxor %xmm6,%xmm4,%xmm9 + vpxor %xmm5,%xmm3,%xmm1 + + leaq 128(%rsi),%rsi + jmp .Lhtable_polyval_main_loop + + + +.Lhtable_polyval_out: + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm6 + vpalignr $8,%xmm1,%xmm1,%xmm1 + vpxor %xmm6,%xmm1,%xmm1 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm6 + vpalignr $8,%xmm1,%xmm1,%xmm1 + vpxor %xmm6,%xmm1,%xmm1 + vpxor %xmm9,%xmm1,%xmm1 + + vmovdqu %xmm1,(%rcx) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size aesgcmsiv_htable_polyval,.-aesgcmsiv_htable_polyval +.globl aesgcmsiv_polyval_horner +.hidden aesgcmsiv_polyval_horner +.type aesgcmsiv_polyval_horner,@function +.align 16 +aesgcmsiv_polyval_horner: +.cfi_startproc + testq %rcx,%rcx + jnz .Lpolyval_horner_start + .byte 0xf3,0xc3 + +.Lpolyval_horner_start: + + + + xorq %r10,%r10 + shlq $4,%rcx + + vmovdqa (%rsi),%xmm1 + vmovdqa (%rdi),%xmm0 + +.Lpolyval_horner_loop: + vpxor (%rdx,%r10,1),%xmm0,%xmm0 + call GFMUL + + addq $16,%r10 + cmpq %r10,%rcx + jne .Lpolyval_horner_loop + + + vmovdqa %xmm0,(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aesgcmsiv_polyval_horner,.-aesgcmsiv_polyval_horner +.globl aes128gcmsiv_aes_ks +.hidden aes128gcmsiv_aes_ks +.type aes128gcmsiv_aes_ks,@function +.align 16 +aes128gcmsiv_aes_ks: +.cfi_startproc + vmovdqu (%rdi),%xmm1 + vmovdqa %xmm1,(%rsi) + + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + + movq $8,%rax + +.Lks128_loop: + addq $16,%rsi + subq $1,%rax + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + jne .Lks128_loop + + vmovdqa con2(%rip),%xmm0 + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,16(%rsi) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,32(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_aes_ks,.-aes128gcmsiv_aes_ks +.globl aes256gcmsiv_aes_ks +.hidden aes256gcmsiv_aes_ks +.type aes256gcmsiv_aes_ks,@function +.align 16 +aes256gcmsiv_aes_ks: +.cfi_startproc + vmovdqu (%rdi),%xmm1 + vmovdqu 16(%rdi),%xmm3 + vmovdqa %xmm1,(%rsi) + vmovdqa %xmm3,16(%rsi) + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + vpxor %xmm14,%xmm14,%xmm14 + movq $6,%rax + +.Lks256_loop: + addq $32,%rsi + subq $1,%rax + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpsllq $32,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpshufb con3(%rip),%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vmovdqa %xmm3,16(%rsi) + jne .Lks256_loop + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpsllq $32,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,32(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.globl aes128gcmsiv_aes_ks_enc_x1 +.hidden aes128gcmsiv_aes_ks_enc_x1 +.type aes128gcmsiv_aes_ks_enc_x1,@function +.align 16 +aes128gcmsiv_aes_ks_enc_x1: +.cfi_startproc + vmovdqa (%rcx),%xmm1 + vmovdqa 0(%rdi),%xmm4 + + vmovdqa %xmm1,(%rdx) + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,16(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,32(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,48(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,64(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,80(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,96(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,112(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,128(%rdx) + + + vmovdqa con2(%rip),%xmm0 + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,144(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenclast %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,160(%rdx) + + + vmovdqa %xmm4,0(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_aes_ks_enc_x1,.-aes128gcmsiv_aes_ks_enc_x1 +.globl aes128gcmsiv_kdf +.hidden aes128gcmsiv_kdf +.type aes128gcmsiv_kdf,@function +.align 16 +aes128gcmsiv_kdf: +.cfi_startproc + + + + + vmovdqa (%rdx),%xmm1 + vmovdqa 0(%rdi),%xmm9 + vmovdqa and_mask(%rip),%xmm12 + vmovdqa one(%rip),%xmm13 + vpshufd $0x90,%xmm9,%xmm9 + vpand %xmm12,%xmm9,%xmm9 + vpaddd %xmm13,%xmm9,%xmm10 + vpaddd %xmm13,%xmm10,%xmm11 + vpaddd %xmm13,%xmm11,%xmm12 + + vpxor %xmm1,%xmm9,%xmm9 + vpxor %xmm1,%xmm10,%xmm10 + vpxor %xmm1,%xmm11,%xmm11 + vpxor %xmm1,%xmm12,%xmm12 + + vmovdqa 16(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 32(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 48(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 64(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 80(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 96(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 112(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 128(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 144(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 160(%rdx),%xmm2 + vaesenclast %xmm2,%xmm9,%xmm9 + vaesenclast %xmm2,%xmm10,%xmm10 + vaesenclast %xmm2,%xmm11,%xmm11 + vaesenclast %xmm2,%xmm12,%xmm12 + + + vmovdqa %xmm9,0(%rsi) + vmovdqa %xmm10,16(%rsi) + vmovdqa %xmm11,32(%rsi) + vmovdqa %xmm12,48(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_kdf,.-aes128gcmsiv_kdf +.globl aes128gcmsiv_enc_msg_x4 +.hidden aes128gcmsiv_enc_msg_x4 +.type aes128gcmsiv_enc_msg_x4,@function +.align 16 +aes128gcmsiv_enc_msg_x4: +.cfi_startproc + testq %r8,%r8 + jnz .L128_enc_msg_x4_start + .byte 0xf3,0xc3 + +.L128_enc_msg_x4_start: + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 + + shrq $4,%r8 + movq %r8,%r10 + shlq $62,%r10 + shrq $62,%r10 + + + vmovdqa (%rdx),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + + vmovdqu four(%rip),%xmm4 + vmovdqa %xmm15,%xmm0 + vpaddd one(%rip),%xmm15,%xmm1 + vpaddd two(%rip),%xmm15,%xmm2 + vpaddd three(%rip),%xmm15,%xmm3 + + shrq $2,%r8 + je .L128_enc_msg_x4_check_remainder + + subq $64,%rsi + subq $64,%rdi + +.L128_enc_msg_x4_loop1: + addq $64,%rsi + addq $64,%rdi + + vmovdqa %xmm0,%xmm5 + vmovdqa %xmm1,%xmm6 + vmovdqa %xmm2,%xmm7 + vmovdqa %xmm3,%xmm8 + + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqu 32(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm1,%xmm1 + vmovdqu 48(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm2,%xmm2 + vmovdqu 64(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm3,%xmm3 + + vmovdqu 80(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 96(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 112(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 128(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 144(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm12 + vaesenclast %xmm12,%xmm5,%xmm5 + vaesenclast %xmm12,%xmm6,%xmm6 + vaesenclast %xmm12,%xmm7,%xmm7 + vaesenclast %xmm12,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm5,%xmm5 + vpxor 16(%rdi),%xmm6,%xmm6 + vpxor 32(%rdi),%xmm7,%xmm7 + vpxor 48(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm5,0(%rsi) + vmovdqu %xmm6,16(%rsi) + vmovdqu %xmm7,32(%rsi) + vmovdqu %xmm8,48(%rsi) + + jne .L128_enc_msg_x4_loop1 + + addq $64,%rsi + addq $64,%rdi + +.L128_enc_msg_x4_check_remainder: + cmpq $0,%r10 + je .L128_enc_msg_x4_out + +.L128_enc_msg_x4_loop2: + + + vmovdqa %xmm0,%xmm5 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm5,%xmm5 + vaesenc 16(%rcx),%xmm5,%xmm5 + vaesenc 32(%rcx),%xmm5,%xmm5 + vaesenc 48(%rcx),%xmm5,%xmm5 + vaesenc 64(%rcx),%xmm5,%xmm5 + vaesenc 80(%rcx),%xmm5,%xmm5 + vaesenc 96(%rcx),%xmm5,%xmm5 + vaesenc 112(%rcx),%xmm5,%xmm5 + vaesenc 128(%rcx),%xmm5,%xmm5 + vaesenc 144(%rcx),%xmm5,%xmm5 + vaesenclast 160(%rcx),%xmm5,%xmm5 + + + vpxor (%rdi),%xmm5,%xmm5 + vmovdqu %xmm5,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + subq $1,%r10 + jne .L128_enc_msg_x4_loop2 + +.L128_enc_msg_x4_out: + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_enc_msg_x4,.-aes128gcmsiv_enc_msg_x4 +.globl aes128gcmsiv_enc_msg_x8 +.hidden aes128gcmsiv_enc_msg_x8 +.type aes128gcmsiv_enc_msg_x8,@function +.align 16 +aes128gcmsiv_enc_msg_x8: +.cfi_startproc + testq %r8,%r8 + jnz .L128_enc_msg_x8_start + .byte 0xf3,0xc3 + +.L128_enc_msg_x8_start: + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-32 + movq %rsp,%rbp +.cfi_def_cfa_register rbp + + + subq $128,%rsp + andq $-64,%rsp + + shrq $4,%r8 + movq %r8,%r10 + shlq $61,%r10 + shrq $61,%r10 + + + vmovdqu (%rdx),%xmm1 + vpor OR_MASK(%rip),%xmm1,%xmm1 + + + vpaddd seven(%rip),%xmm1,%xmm0 + vmovdqu %xmm0,(%rsp) + vpaddd one(%rip),%xmm1,%xmm9 + vpaddd two(%rip),%xmm1,%xmm10 + vpaddd three(%rip),%xmm1,%xmm11 + vpaddd four(%rip),%xmm1,%xmm12 + vpaddd five(%rip),%xmm1,%xmm13 + vpaddd six(%rip),%xmm1,%xmm14 + vmovdqa %xmm1,%xmm0 + + shrq $3,%r8 + je .L128_enc_msg_x8_check_remainder + + subq $128,%rsi + subq $128,%rdi + +.L128_enc_msg_x8_loop1: + addq $128,%rsi + addq $128,%rdi + + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm9,%xmm2 + vmovdqa %xmm10,%xmm3 + vmovdqa %xmm11,%xmm4 + vmovdqa %xmm12,%xmm5 + vmovdqa %xmm13,%xmm6 + vmovdqa %xmm14,%xmm7 + + vmovdqu (%rsp),%xmm8 + + vpxor (%rcx),%xmm1,%xmm1 + vpxor (%rcx),%xmm2,%xmm2 + vpxor (%rcx),%xmm3,%xmm3 + vpxor (%rcx),%xmm4,%xmm4 + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu (%rsp),%xmm14 + vpaddd eight(%rip),%xmm14,%xmm14 + vmovdqu %xmm14,(%rsp) + vmovdqu 32(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpsubd one(%rip),%xmm14,%xmm14 + vmovdqu 48(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm0,%xmm0 + vmovdqu 64(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm9,%xmm9 + vmovdqu 80(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm10,%xmm10 + vmovdqu 96(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm11,%xmm11 + vmovdqu 112(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm12,%xmm12 + vmovdqu 128(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm13,%xmm13 + vmovdqu 144(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm15 + vaesenclast %xmm15,%xmm1,%xmm1 + vaesenclast %xmm15,%xmm2,%xmm2 + vaesenclast %xmm15,%xmm3,%xmm3 + vaesenclast %xmm15,%xmm4,%xmm4 + vaesenclast %xmm15,%xmm5,%xmm5 + vaesenclast %xmm15,%xmm6,%xmm6 + vaesenclast %xmm15,%xmm7,%xmm7 + vaesenclast %xmm15,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm1,%xmm1 + vpxor 16(%rdi),%xmm2,%xmm2 + vpxor 32(%rdi),%xmm3,%xmm3 + vpxor 48(%rdi),%xmm4,%xmm4 + vpxor 64(%rdi),%xmm5,%xmm5 + vpxor 80(%rdi),%xmm6,%xmm6 + vpxor 96(%rdi),%xmm7,%xmm7 + vpxor 112(%rdi),%xmm8,%xmm8 + + decq %r8 + + vmovdqu %xmm1,0(%rsi) + vmovdqu %xmm2,16(%rsi) + vmovdqu %xmm3,32(%rsi) + vmovdqu %xmm4,48(%rsi) + vmovdqu %xmm5,64(%rsi) + vmovdqu %xmm6,80(%rsi) + vmovdqu %xmm7,96(%rsi) + vmovdqu %xmm8,112(%rsi) + + jne .L128_enc_msg_x8_loop1 + + addq $128,%rsi + addq $128,%rdi + +.L128_enc_msg_x8_check_remainder: + cmpq $0,%r10 + je .L128_enc_msg_x8_out + +.L128_enc_msg_x8_loop2: + + + vmovdqa %xmm0,%xmm1 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm1,%xmm1 + vaesenc 16(%rcx),%xmm1,%xmm1 + vaesenc 32(%rcx),%xmm1,%xmm1 + vaesenc 48(%rcx),%xmm1,%xmm1 + vaesenc 64(%rcx),%xmm1,%xmm1 + vaesenc 80(%rcx),%xmm1,%xmm1 + vaesenc 96(%rcx),%xmm1,%xmm1 + vaesenc 112(%rcx),%xmm1,%xmm1 + vaesenc 128(%rcx),%xmm1,%xmm1 + vaesenc 144(%rcx),%xmm1,%xmm1 + vaesenclast 160(%rcx),%xmm1,%xmm1 + + + vpxor (%rdi),%xmm1,%xmm1 + + vmovdqu %xmm1,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + decq %r10 + jne .L128_enc_msg_x8_loop2 + +.L128_enc_msg_x8_out: + movq %rbp,%rsp +.cfi_def_cfa_register %rsp + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_enc_msg_x8,.-aes128gcmsiv_enc_msg_x8 +.globl aes128gcmsiv_dec +.hidden aes128gcmsiv_dec +.type aes128gcmsiv_dec,@function +.align 16 +aes128gcmsiv_dec: +.cfi_startproc + testq $~15,%r9 + jnz .L128_dec_start + .byte 0xf3,0xc3 + +.L128_dec_start: + vzeroupper + vmovdqa (%rdx),%xmm0 + movq %rdx,%rax + + leaq 32(%rax),%rax + leaq 32(%rcx),%rcx + + + vmovdqu (%rdi,%r9,1),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + andq $~15,%r9 + + + cmpq $96,%r9 + jb .L128_dec_loop2 + + + subq $96,%r9 + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vpxor (%r8),%xmm7,%xmm7 + vpxor (%r8),%xmm8,%xmm8 + vpxor (%r8),%xmm9,%xmm9 + vpxor (%r8),%xmm10,%xmm10 + vpxor (%r8),%xmm11,%xmm11 + vpxor (%r8),%xmm12,%xmm12 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vaesenclast %xmm4,%xmm8,%xmm8 + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm4,%xmm10,%xmm10 + vaesenclast %xmm4,%xmm11,%xmm11 + vaesenclast %xmm4,%xmm12,%xmm12 + + + vpxor 0(%rdi),%xmm7,%xmm7 + vpxor 16(%rdi),%xmm8,%xmm8 + vpxor 32(%rdi),%xmm9,%xmm9 + vpxor 48(%rdi),%xmm10,%xmm10 + vpxor 64(%rdi),%xmm11,%xmm11 + vpxor 80(%rdi),%xmm12,%xmm12 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + addq $96,%rdi + addq $96,%rsi + jmp .L128_dec_loop1 + + +.align 64 +.L128_dec_loop1: + cmpq $96,%r9 + jb .L128_dec_finish_96 + subq $96,%r9 + + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vmovdqa (%r8),%xmm4 + vpxor %xmm4,%xmm7,%xmm7 + vpxor %xmm4,%xmm8,%xmm8 + vpxor %xmm4,%xmm9,%xmm9 + vpxor %xmm4,%xmm10,%xmm10 + vpxor %xmm4,%xmm11,%xmm11 + vpxor %xmm4,%xmm12,%xmm12 + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vmovdqa 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm6 + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor 0(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vpxor 16(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm8,%xmm8 + vpxor 32(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm9,%xmm9 + vpxor 48(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm10,%xmm10 + vpxor 64(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm11,%xmm11 + vpxor 80(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm12,%xmm12 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + vpxor %xmm5,%xmm0,%xmm0 + + leaq 96(%rdi),%rdi + leaq 96(%rsi),%rsi + jmp .L128_dec_loop1 + +.L128_dec_finish_96: + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor %xmm5,%xmm0,%xmm0 + +.L128_dec_loop2: + + + + cmpq $16,%r9 + jb .L128_dec_out + subq $16,%r9 + + vmovdqa %xmm15,%xmm2 + vpaddd one(%rip),%xmm15,%xmm15 + + vpxor 0(%r8),%xmm2,%xmm2 + vaesenc 16(%r8),%xmm2,%xmm2 + vaesenc 32(%r8),%xmm2,%xmm2 + vaesenc 48(%r8),%xmm2,%xmm2 + vaesenc 64(%r8),%xmm2,%xmm2 + vaesenc 80(%r8),%xmm2,%xmm2 + vaesenc 96(%r8),%xmm2,%xmm2 + vaesenc 112(%r8),%xmm2,%xmm2 + vaesenc 128(%r8),%xmm2,%xmm2 + vaesenc 144(%r8),%xmm2,%xmm2 + vaesenclast 160(%r8),%xmm2,%xmm2 + vpxor (%rdi),%xmm2,%xmm2 + vmovdqu %xmm2,(%rsi) + addq $16,%rdi + addq $16,%rsi + + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa -32(%rcx),%xmm1 + call GFMUL + + jmp .L128_dec_loop2 + +.L128_dec_out: + vmovdqu %xmm0,(%rdx) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_dec, .-aes128gcmsiv_dec +.globl aes128gcmsiv_ecb_enc_block +.hidden aes128gcmsiv_ecb_enc_block +.type aes128gcmsiv_ecb_enc_block,@function +.align 16 +aes128gcmsiv_ecb_enc_block: +.cfi_startproc + vmovdqa (%rdi),%xmm1 + + vpxor (%rdx),%xmm1,%xmm1 + vaesenc 16(%rdx),%xmm1,%xmm1 + vaesenc 32(%rdx),%xmm1,%xmm1 + vaesenc 48(%rdx),%xmm1,%xmm1 + vaesenc 64(%rdx),%xmm1,%xmm1 + vaesenc 80(%rdx),%xmm1,%xmm1 + vaesenc 96(%rdx),%xmm1,%xmm1 + vaesenc 112(%rdx),%xmm1,%xmm1 + vaesenc 128(%rdx),%xmm1,%xmm1 + vaesenc 144(%rdx),%xmm1,%xmm1 + vaesenclast 160(%rdx),%xmm1,%xmm1 + + vmovdqa %xmm1,(%rsi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size aes128gcmsiv_ecb_enc_block,.-aes128gcmsiv_ecb_enc_block +.globl aes256gcmsiv_aes_ks_enc_x1 +.hidden aes256gcmsiv_aes_ks_enc_x1 +.type aes256gcmsiv_aes_ks_enc_x1,@function +.align 16 +aes256gcmsiv_aes_ks_enc_x1: +.cfi_startproc + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + vmovdqa (%rdi),%xmm8 + vmovdqa (%rcx),%xmm1 + vmovdqa 16(%rcx),%xmm3 + vpxor %xmm1,%xmm8,%xmm8 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm1,(%rdx) + vmovdqu %xmm3,16(%rdx) + vpxor %xmm14,%xmm14,%xmm14 + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,32(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,48(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,64(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,80(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,96(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,112(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,128(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,144(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,160(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,176(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,192(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,208(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenclast %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,224(%rdx) + + vmovdqa %xmm8,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes256gcmsiv_aes_ks_enc_x1,.-aes256gcmsiv_aes_ks_enc_x1 +.globl aes256gcmsiv_ecb_enc_block +.hidden aes256gcmsiv_ecb_enc_block +.type aes256gcmsiv_ecb_enc_block,@function +.align 16 +aes256gcmsiv_ecb_enc_block: +.cfi_startproc + vmovdqa (%rdi),%xmm1 + vpxor (%rdx),%xmm1,%xmm1 + vaesenc 16(%rdx),%xmm1,%xmm1 + vaesenc 32(%rdx),%xmm1,%xmm1 + vaesenc 48(%rdx),%xmm1,%xmm1 + vaesenc 64(%rdx),%xmm1,%xmm1 + vaesenc 80(%rdx),%xmm1,%xmm1 + vaesenc 96(%rdx),%xmm1,%xmm1 + vaesenc 112(%rdx),%xmm1,%xmm1 + vaesenc 128(%rdx),%xmm1,%xmm1 + vaesenc 144(%rdx),%xmm1,%xmm1 + vaesenc 160(%rdx),%xmm1,%xmm1 + vaesenc 176(%rdx),%xmm1,%xmm1 + vaesenc 192(%rdx),%xmm1,%xmm1 + vaesenc 208(%rdx),%xmm1,%xmm1 + vaesenclast 224(%rdx),%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes256gcmsiv_ecb_enc_block,.-aes256gcmsiv_ecb_enc_block +.globl aes256gcmsiv_enc_msg_x4 +.hidden aes256gcmsiv_enc_msg_x4 +.type aes256gcmsiv_enc_msg_x4,@function +.align 16 +aes256gcmsiv_enc_msg_x4: +.cfi_startproc + testq %r8,%r8 + jnz .L256_enc_msg_x4_start + .byte 0xf3,0xc3 + +.L256_enc_msg_x4_start: + movq %r8,%r10 + shrq $4,%r8 + shlq $60,%r10 + jz .L256_enc_msg_x4_start2 + addq $1,%r8 + +.L256_enc_msg_x4_start2: + movq %r8,%r10 + shlq $62,%r10 + shrq $62,%r10 + + + vmovdqa (%rdx),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + + vmovdqa four(%rip),%xmm4 + vmovdqa %xmm15,%xmm0 + vpaddd one(%rip),%xmm15,%xmm1 + vpaddd two(%rip),%xmm15,%xmm2 + vpaddd three(%rip),%xmm15,%xmm3 + + shrq $2,%r8 + je .L256_enc_msg_x4_check_remainder + + subq $64,%rsi + subq $64,%rdi + +.L256_enc_msg_x4_loop1: + addq $64,%rsi + addq $64,%rdi + + vmovdqa %xmm0,%xmm5 + vmovdqa %xmm1,%xmm6 + vmovdqa %xmm2,%xmm7 + vmovdqa %xmm3,%xmm8 + + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqu 32(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm1,%xmm1 + vmovdqu 48(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm2,%xmm2 + vmovdqu 64(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm3,%xmm3 + + vmovdqu 80(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 96(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 112(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 128(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 144(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 176(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 192(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 208(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 224(%rcx),%xmm12 + vaesenclast %xmm12,%xmm5,%xmm5 + vaesenclast %xmm12,%xmm6,%xmm6 + vaesenclast %xmm12,%xmm7,%xmm7 + vaesenclast %xmm12,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm5,%xmm5 + vpxor 16(%rdi),%xmm6,%xmm6 + vpxor 32(%rdi),%xmm7,%xmm7 + vpxor 48(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm5,0(%rsi) + vmovdqu %xmm6,16(%rsi) + vmovdqu %xmm7,32(%rsi) + vmovdqu %xmm8,48(%rsi) + + jne .L256_enc_msg_x4_loop1 + + addq $64,%rsi + addq $64,%rdi + +.L256_enc_msg_x4_check_remainder: + cmpq $0,%r10 + je .L256_enc_msg_x4_out + +.L256_enc_msg_x4_loop2: + + + + vmovdqa %xmm0,%xmm5 + vpaddd one(%rip),%xmm0,%xmm0 + vpxor (%rcx),%xmm5,%xmm5 + vaesenc 16(%rcx),%xmm5,%xmm5 + vaesenc 32(%rcx),%xmm5,%xmm5 + vaesenc 48(%rcx),%xmm5,%xmm5 + vaesenc 64(%rcx),%xmm5,%xmm5 + vaesenc 80(%rcx),%xmm5,%xmm5 + vaesenc 96(%rcx),%xmm5,%xmm5 + vaesenc 112(%rcx),%xmm5,%xmm5 + vaesenc 128(%rcx),%xmm5,%xmm5 + vaesenc 144(%rcx),%xmm5,%xmm5 + vaesenc 160(%rcx),%xmm5,%xmm5 + vaesenc 176(%rcx),%xmm5,%xmm5 + vaesenc 192(%rcx),%xmm5,%xmm5 + vaesenc 208(%rcx),%xmm5,%xmm5 + vaesenclast 224(%rcx),%xmm5,%xmm5 + + + vpxor (%rdi),%xmm5,%xmm5 + + vmovdqu %xmm5,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + subq $1,%r10 + jne .L256_enc_msg_x4_loop2 + +.L256_enc_msg_x4_out: + .byte 0xf3,0xc3 +.cfi_endproc +.size aes256gcmsiv_enc_msg_x4,.-aes256gcmsiv_enc_msg_x4 +.globl aes256gcmsiv_enc_msg_x8 +.hidden aes256gcmsiv_enc_msg_x8 +.type aes256gcmsiv_enc_msg_x8,@function +.align 16 +aes256gcmsiv_enc_msg_x8: +.cfi_startproc + testq %r8,%r8 + jnz .L256_enc_msg_x8_start + .byte 0xf3,0xc3 + +.L256_enc_msg_x8_start: + + movq %rsp,%r11 + subq $16,%r11 + andq $-64,%r11 + + movq %r8,%r10 + shrq $4,%r8 + shlq $60,%r10 + jz .L256_enc_msg_x8_start2 + addq $1,%r8 + +.L256_enc_msg_x8_start2: + movq %r8,%r10 + shlq $61,%r10 + shrq $61,%r10 + + + vmovdqa (%rdx),%xmm1 + vpor OR_MASK(%rip),%xmm1,%xmm1 + + + vpaddd seven(%rip),%xmm1,%xmm0 + vmovdqa %xmm0,(%r11) + vpaddd one(%rip),%xmm1,%xmm9 + vpaddd two(%rip),%xmm1,%xmm10 + vpaddd three(%rip),%xmm1,%xmm11 + vpaddd four(%rip),%xmm1,%xmm12 + vpaddd five(%rip),%xmm1,%xmm13 + vpaddd six(%rip),%xmm1,%xmm14 + vmovdqa %xmm1,%xmm0 + + shrq $3,%r8 + jz .L256_enc_msg_x8_check_remainder + + subq $128,%rsi + subq $128,%rdi + +.L256_enc_msg_x8_loop1: + addq $128,%rsi + addq $128,%rdi + + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm9,%xmm2 + vmovdqa %xmm10,%xmm3 + vmovdqa %xmm11,%xmm4 + vmovdqa %xmm12,%xmm5 + vmovdqa %xmm13,%xmm6 + vmovdqa %xmm14,%xmm7 + + vmovdqa (%r11),%xmm8 + + vpxor (%rcx),%xmm1,%xmm1 + vpxor (%rcx),%xmm2,%xmm2 + vpxor (%rcx),%xmm3,%xmm3 + vpxor (%rcx),%xmm4,%xmm4 + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqa (%r11),%xmm14 + vpaddd eight(%rip),%xmm14,%xmm14 + vmovdqa %xmm14,(%r11) + vmovdqu 32(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpsubd one(%rip),%xmm14,%xmm14 + vmovdqu 48(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm0,%xmm0 + vmovdqu 64(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm9,%xmm9 + vmovdqu 80(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm10,%xmm10 + vmovdqu 96(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm11,%xmm11 + vmovdqu 112(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm12,%xmm12 + vmovdqu 128(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm13,%xmm13 + vmovdqu 144(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 176(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 192(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 208(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 224(%rcx),%xmm15 + vaesenclast %xmm15,%xmm1,%xmm1 + vaesenclast %xmm15,%xmm2,%xmm2 + vaesenclast %xmm15,%xmm3,%xmm3 + vaesenclast %xmm15,%xmm4,%xmm4 + vaesenclast %xmm15,%xmm5,%xmm5 + vaesenclast %xmm15,%xmm6,%xmm6 + vaesenclast %xmm15,%xmm7,%xmm7 + vaesenclast %xmm15,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm1,%xmm1 + vpxor 16(%rdi),%xmm2,%xmm2 + vpxor 32(%rdi),%xmm3,%xmm3 + vpxor 48(%rdi),%xmm4,%xmm4 + vpxor 64(%rdi),%xmm5,%xmm5 + vpxor 80(%rdi),%xmm6,%xmm6 + vpxor 96(%rdi),%xmm7,%xmm7 + vpxor 112(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm1,0(%rsi) + vmovdqu %xmm2,16(%rsi) + vmovdqu %xmm3,32(%rsi) + vmovdqu %xmm4,48(%rsi) + vmovdqu %xmm5,64(%rsi) + vmovdqu %xmm6,80(%rsi) + vmovdqu %xmm7,96(%rsi) + vmovdqu %xmm8,112(%rsi) + + jne .L256_enc_msg_x8_loop1 + + addq $128,%rsi + addq $128,%rdi + +.L256_enc_msg_x8_check_remainder: + cmpq $0,%r10 + je .L256_enc_msg_x8_out + +.L256_enc_msg_x8_loop2: + + + vmovdqa %xmm0,%xmm1 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm1,%xmm1 + vaesenc 16(%rcx),%xmm1,%xmm1 + vaesenc 32(%rcx),%xmm1,%xmm1 + vaesenc 48(%rcx),%xmm1,%xmm1 + vaesenc 64(%rcx),%xmm1,%xmm1 + vaesenc 80(%rcx),%xmm1,%xmm1 + vaesenc 96(%rcx),%xmm1,%xmm1 + vaesenc 112(%rcx),%xmm1,%xmm1 + vaesenc 128(%rcx),%xmm1,%xmm1 + vaesenc 144(%rcx),%xmm1,%xmm1 + vaesenc 160(%rcx),%xmm1,%xmm1 + vaesenc 176(%rcx),%xmm1,%xmm1 + vaesenc 192(%rcx),%xmm1,%xmm1 + vaesenc 208(%rcx),%xmm1,%xmm1 + vaesenclast 224(%rcx),%xmm1,%xmm1 + + + vpxor (%rdi),%xmm1,%xmm1 + + vmovdqu %xmm1,(%rsi) + + addq $16,%rdi + addq $16,%rsi + subq $1,%r10 + jnz .L256_enc_msg_x8_loop2 + +.L256_enc_msg_x8_out: + .byte 0xf3,0xc3 + +.cfi_endproc +.size aes256gcmsiv_enc_msg_x8,.-aes256gcmsiv_enc_msg_x8 +.globl aes256gcmsiv_dec +.hidden aes256gcmsiv_dec +.type aes256gcmsiv_dec,@function +.align 16 +aes256gcmsiv_dec: +.cfi_startproc + testq $~15,%r9 + jnz .L256_dec_start + .byte 0xf3,0xc3 + +.L256_dec_start: + vzeroupper + vmovdqa (%rdx),%xmm0 + movq %rdx,%rax + + leaq 32(%rax),%rax + leaq 32(%rcx),%rcx + + + vmovdqu (%rdi,%r9,1),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + andq $~15,%r9 + + + cmpq $96,%r9 + jb .L256_dec_loop2 + + + subq $96,%r9 + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vpxor (%r8),%xmm7,%xmm7 + vpxor (%r8),%xmm8,%xmm8 + vpxor (%r8),%xmm9,%xmm9 + vpxor (%r8),%xmm10,%xmm10 + vpxor (%r8),%xmm11,%xmm11 + vpxor (%r8),%xmm12,%xmm12 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 176(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 192(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 208(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 224(%r8),%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vaesenclast %xmm4,%xmm8,%xmm8 + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm4,%xmm10,%xmm10 + vaesenclast %xmm4,%xmm11,%xmm11 + vaesenclast %xmm4,%xmm12,%xmm12 + + + vpxor 0(%rdi),%xmm7,%xmm7 + vpxor 16(%rdi),%xmm8,%xmm8 + vpxor 32(%rdi),%xmm9,%xmm9 + vpxor 48(%rdi),%xmm10,%xmm10 + vpxor 64(%rdi),%xmm11,%xmm11 + vpxor 80(%rdi),%xmm12,%xmm12 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + addq $96,%rdi + addq $96,%rsi + jmp .L256_dec_loop1 + + +.align 64 +.L256_dec_loop1: + cmpq $96,%r9 + jb .L256_dec_finish_96 + subq $96,%r9 + + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vmovdqa (%r8),%xmm4 + vpxor %xmm4,%xmm7,%xmm7 + vpxor %xmm4,%xmm8,%xmm8 + vpxor %xmm4,%xmm9,%xmm9 + vpxor %xmm4,%xmm10,%xmm10 + vpxor %xmm4,%xmm11,%xmm11 + vpxor %xmm4,%xmm12,%xmm12 + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vmovdqa 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 176(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 192(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 208(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 224(%r8),%xmm6 + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor 0(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vpxor 16(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm8,%xmm8 + vpxor 32(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm9,%xmm9 + vpxor 48(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm10,%xmm10 + vpxor 64(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm11,%xmm11 + vpxor 80(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm12,%xmm12 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + vpxor %xmm5,%xmm0,%xmm0 + + leaq 96(%rdi),%rdi + leaq 96(%rsi),%rsi + jmp .L256_dec_loop1 + +.L256_dec_finish_96: + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor %xmm5,%xmm0,%xmm0 + +.L256_dec_loop2: + + + + cmpq $16,%r9 + jb .L256_dec_out + subq $16,%r9 + + vmovdqa %xmm15,%xmm2 + vpaddd one(%rip),%xmm15,%xmm15 + + vpxor 0(%r8),%xmm2,%xmm2 + vaesenc 16(%r8),%xmm2,%xmm2 + vaesenc 32(%r8),%xmm2,%xmm2 + vaesenc 48(%r8),%xmm2,%xmm2 + vaesenc 64(%r8),%xmm2,%xmm2 + vaesenc 80(%r8),%xmm2,%xmm2 + vaesenc 96(%r8),%xmm2,%xmm2 + vaesenc 112(%r8),%xmm2,%xmm2 + vaesenc 128(%r8),%xmm2,%xmm2 + vaesenc 144(%r8),%xmm2,%xmm2 + vaesenc 160(%r8),%xmm2,%xmm2 + vaesenc 176(%r8),%xmm2,%xmm2 + vaesenc 192(%r8),%xmm2,%xmm2 + vaesenc 208(%r8),%xmm2,%xmm2 + vaesenclast 224(%r8),%xmm2,%xmm2 + vpxor (%rdi),%xmm2,%xmm2 + vmovdqu %xmm2,(%rsi) + addq $16,%rdi + addq $16,%rsi + + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa -32(%rcx),%xmm1 + call GFMUL + + jmp .L256_dec_loop2 + +.L256_dec_out: + vmovdqu %xmm0,(%rdx) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes256gcmsiv_dec, .-aes256gcmsiv_dec +.globl aes256gcmsiv_kdf +.hidden aes256gcmsiv_kdf +.type aes256gcmsiv_kdf,@function +.align 16 +aes256gcmsiv_kdf: +.cfi_startproc + + + + + vmovdqa (%rdx),%xmm1 + vmovdqa 0(%rdi),%xmm4 + vmovdqa and_mask(%rip),%xmm11 + vmovdqa one(%rip),%xmm8 + vpshufd $0x90,%xmm4,%xmm4 + vpand %xmm11,%xmm4,%xmm4 + vpaddd %xmm8,%xmm4,%xmm6 + vpaddd %xmm8,%xmm6,%xmm7 + vpaddd %xmm8,%xmm7,%xmm11 + vpaddd %xmm8,%xmm11,%xmm12 + vpaddd %xmm8,%xmm12,%xmm13 + + vpxor %xmm1,%xmm4,%xmm4 + vpxor %xmm1,%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm1,%xmm11,%xmm11 + vpxor %xmm1,%xmm12,%xmm12 + vpxor %xmm1,%xmm13,%xmm13 + + vmovdqa 16(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 32(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 48(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 64(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 80(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 96(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 112(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 128(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 144(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 160(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 176(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 192(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 208(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 224(%rdx),%xmm2 + vaesenclast %xmm2,%xmm4,%xmm4 + vaesenclast %xmm2,%xmm6,%xmm6 + vaesenclast %xmm2,%xmm7,%xmm7 + vaesenclast %xmm2,%xmm11,%xmm11 + vaesenclast %xmm2,%xmm12,%xmm12 + vaesenclast %xmm2,%xmm13,%xmm13 + + + vmovdqa %xmm4,0(%rsi) + vmovdqa %xmm6,16(%rsi) + vmovdqa %xmm7,32(%rsi) + vmovdqa %xmm11,48(%rsi) + vmovdqa %xmm12,64(%rsi) + vmovdqa %xmm13,80(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size aes256gcmsiv_kdf, .-aes256gcmsiv_kdf +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S new file mode 100644 index 00000000..f0000f5c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S @@ -0,0 +1,3075 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.data + +.p2align 4 +one: +.quad 1,0 +two: +.quad 2,0 +three: +.quad 3,0 +four: +.quad 4,0 +five: +.quad 5,0 +six: +.quad 6,0 +seven: +.quad 7,0 +eight: +.quad 8,0 + +OR_MASK: +.long 0x00000000,0x00000000,0x00000000,0x80000000 +poly: +.quad 0x1, 0xc200000000000000 +mask: +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d +con1: +.long 1,1,1,1 +con2: +.long 0x1b,0x1b,0x1b,0x1b +con3: +.byte -1,-1,-1,-1,-1,-1,-1,-1,4,5,6,7,4,5,6,7 +and_mask: +.long 0,0xffffffff, 0xffffffff, 0xffffffff +.text + +.p2align 4 +GFMUL: + + vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2 + vpclmulqdq $0x11,%xmm1,%xmm0,%xmm5 + vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3 + vpclmulqdq $0x01,%xmm1,%xmm0,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm3,%xmm5,%xmm5 + + vpclmulqdq $0x10,poly(%rip),%xmm2,%xmm3 + vpshufd $78,%xmm2,%xmm4 + vpxor %xmm4,%xmm3,%xmm2 + + vpclmulqdq $0x10,poly(%rip),%xmm2,%xmm3 + vpshufd $78,%xmm2,%xmm4 + vpxor %xmm4,%xmm3,%xmm2 + + vpxor %xmm5,%xmm2,%xmm0 + .byte 0xf3,0xc3 + + +.globl _aesgcmsiv_htable_init +.private_extern _aesgcmsiv_htable_init + +.p2align 4 +_aesgcmsiv_htable_init: + + vmovdqa (%rsi),%xmm0 + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm0,(%rdi) + call GFMUL + vmovdqa %xmm0,16(%rdi) + call GFMUL + vmovdqa %xmm0,32(%rdi) + call GFMUL + vmovdqa %xmm0,48(%rdi) + call GFMUL + vmovdqa %xmm0,64(%rdi) + call GFMUL + vmovdqa %xmm0,80(%rdi) + call GFMUL + vmovdqa %xmm0,96(%rdi) + call GFMUL + vmovdqa %xmm0,112(%rdi) + .byte 0xf3,0xc3 + + +.globl _aesgcmsiv_htable6_init +.private_extern _aesgcmsiv_htable6_init + +.p2align 4 +_aesgcmsiv_htable6_init: + + vmovdqa (%rsi),%xmm0 + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm0,(%rdi) + call GFMUL + vmovdqa %xmm0,16(%rdi) + call GFMUL + vmovdqa %xmm0,32(%rdi) + call GFMUL + vmovdqa %xmm0,48(%rdi) + call GFMUL + vmovdqa %xmm0,64(%rdi) + call GFMUL + vmovdqa %xmm0,80(%rdi) + .byte 0xf3,0xc3 + + +.globl _aesgcmsiv_htable_polyval +.private_extern _aesgcmsiv_htable_polyval + +.p2align 4 +_aesgcmsiv_htable_polyval: + + testq %rdx,%rdx + jnz L$htable_polyval_start + .byte 0xf3,0xc3 + +L$htable_polyval_start: + vzeroall + + + + movq %rdx,%r11 + andq $127,%r11 + + jz L$htable_polyval_no_prefix + + vpxor %xmm9,%xmm9,%xmm9 + vmovdqa (%rcx),%xmm1 + subq %r11,%rdx + + subq $16,%r11 + + + vmovdqu (%rsi),%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + + vpclmulqdq $0x01,(%rdi,%r11,1),%xmm0,%xmm5 + vpclmulqdq $0x00,(%rdi,%r11,1),%xmm0,%xmm3 + vpclmulqdq $0x11,(%rdi,%r11,1),%xmm0,%xmm4 + vpclmulqdq $0x10,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + leaq 16(%rsi),%rsi + testq %r11,%r11 + jnz L$htable_polyval_prefix_loop + jmp L$htable_polyval_prefix_complete + + +.p2align 6 +L$htable_polyval_prefix_loop: + subq $16,%r11 + + vmovdqu (%rsi),%xmm0 + + vpclmulqdq $0x00,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x01,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x10,(%rdi,%r11,1),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + testq %r11,%r11 + + leaq 16(%rsi),%rsi + + jnz L$htable_polyval_prefix_loop + +L$htable_polyval_prefix_complete: + vpsrldq $8,%xmm5,%xmm6 + vpslldq $8,%xmm5,%xmm5 + + vpxor %xmm6,%xmm4,%xmm9 + vpxor %xmm5,%xmm3,%xmm1 + + jmp L$htable_polyval_main_loop + +L$htable_polyval_no_prefix: + + + + + vpxor %xmm1,%xmm1,%xmm1 + vmovdqa (%rcx),%xmm9 + +.p2align 6 +L$htable_polyval_main_loop: + subq $0x80,%rdx + jb L$htable_polyval_out + + vmovdqu 112(%rsi),%xmm0 + + vpclmulqdq $0x01,(%rdi),%xmm0,%xmm5 + vpclmulqdq $0x00,(%rdi),%xmm0,%xmm3 + vpclmulqdq $0x11,(%rdi),%xmm0,%xmm4 + vpclmulqdq $0x10,(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 96(%rsi),%xmm0 + vpclmulqdq $0x01,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,16(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + + vmovdqu 80(%rsi),%xmm0 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm7 + vpalignr $8,%xmm1,%xmm1,%xmm1 + + vpclmulqdq $0x01,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,32(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm7,%xmm1,%xmm1 + + vmovdqu 64(%rsi),%xmm0 + + vpclmulqdq $0x01,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,48(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 48(%rsi),%xmm0 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm7 + vpalignr $8,%xmm1,%xmm1,%xmm1 + + vpclmulqdq $0x01,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,64(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm7,%xmm1,%xmm1 + + vmovdqu 32(%rsi),%xmm0 + + vpclmulqdq $0x01,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,80(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpxor %xmm9,%xmm1,%xmm1 + + vmovdqu 16(%rsi),%xmm0 + + vpclmulqdq $0x01,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,96(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vmovdqu 0(%rsi),%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + + vpclmulqdq $0x01,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x00,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm3,%xmm3 + vpclmulqdq $0x11,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm4,%xmm4 + vpclmulqdq $0x10,112(%rdi),%xmm0,%xmm6 + vpxor %xmm6,%xmm5,%xmm5 + + + vpsrldq $8,%xmm5,%xmm6 + vpslldq $8,%xmm5,%xmm5 + + vpxor %xmm6,%xmm4,%xmm9 + vpxor %xmm5,%xmm3,%xmm1 + + leaq 128(%rsi),%rsi + jmp L$htable_polyval_main_loop + + + +L$htable_polyval_out: + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm6 + vpalignr $8,%xmm1,%xmm1,%xmm1 + vpxor %xmm6,%xmm1,%xmm1 + + vpclmulqdq $0x10,poly(%rip),%xmm1,%xmm6 + vpalignr $8,%xmm1,%xmm1,%xmm1 + vpxor %xmm6,%xmm1,%xmm1 + vpxor %xmm9,%xmm1,%xmm1 + + vmovdqu %xmm1,(%rcx) + vzeroupper + .byte 0xf3,0xc3 + + +.globl _aesgcmsiv_polyval_horner +.private_extern _aesgcmsiv_polyval_horner + +.p2align 4 +_aesgcmsiv_polyval_horner: + + testq %rcx,%rcx + jnz L$polyval_horner_start + .byte 0xf3,0xc3 + +L$polyval_horner_start: + + + + xorq %r10,%r10 + shlq $4,%rcx + + vmovdqa (%rsi),%xmm1 + vmovdqa (%rdi),%xmm0 + +L$polyval_horner_loop: + vpxor (%rdx,%r10,1),%xmm0,%xmm0 + call GFMUL + + addq $16,%r10 + cmpq %r10,%rcx + jne L$polyval_horner_loop + + + vmovdqa %xmm0,(%rdi) + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_aes_ks +.private_extern _aes128gcmsiv_aes_ks + +.p2align 4 +_aes128gcmsiv_aes_ks: + + vmovdqu (%rdi),%xmm1 + vmovdqa %xmm1,(%rsi) + + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + + movq $8,%rax + +L$ks128_loop: + addq $16,%rsi + subq $1,%rax + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + jne L$ks128_loop + + vmovdqa con2(%rip),%xmm0 + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,16(%rsi) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslldq $4,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpslldq $4,%xmm3,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,32(%rsi) + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_aes_ks +.private_extern _aes256gcmsiv_aes_ks + +.p2align 4 +_aes256gcmsiv_aes_ks: + + vmovdqu (%rdi),%xmm1 + vmovdqu 16(%rdi),%xmm3 + vmovdqa %xmm1,(%rsi) + vmovdqa %xmm3,16(%rsi) + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + vpxor %xmm14,%xmm14,%xmm14 + movq $6,%rax + +L$ks256_loop: + addq $32,%rsi + subq $1,%rax + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpsllq $32,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpshufb con3(%rip),%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vmovdqa %xmm3,16(%rsi) + jne L$ks256_loop + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpsllq $32,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm1,32(%rsi) + .byte 0xf3,0xc3 + +.globl _aes128gcmsiv_aes_ks_enc_x1 +.private_extern _aes128gcmsiv_aes_ks_enc_x1 + +.p2align 4 +_aes128gcmsiv_aes_ks_enc_x1: + + vmovdqa (%rcx),%xmm1 + vmovdqa 0(%rdi),%xmm4 + + vmovdqa %xmm1,(%rdx) + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,16(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,32(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,48(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,64(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,80(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,96(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,112(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,128(%rdx) + + + vmovdqa con2(%rip),%xmm0 + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenc %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,144(%rdx) + + vpshufb %xmm15,%xmm1,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpsllq $32,%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpshufb con3(%rip),%xmm1,%xmm3 + vpxor %xmm3,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + + vaesenclast %xmm1,%xmm4,%xmm4 + vmovdqa %xmm1,160(%rdx) + + + vmovdqa %xmm4,0(%rsi) + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_kdf +.private_extern _aes128gcmsiv_kdf + +.p2align 4 +_aes128gcmsiv_kdf: + + + + + + vmovdqa (%rdx),%xmm1 + vmovdqa 0(%rdi),%xmm9 + vmovdqa and_mask(%rip),%xmm12 + vmovdqa one(%rip),%xmm13 + vpshufd $0x90,%xmm9,%xmm9 + vpand %xmm12,%xmm9,%xmm9 + vpaddd %xmm13,%xmm9,%xmm10 + vpaddd %xmm13,%xmm10,%xmm11 + vpaddd %xmm13,%xmm11,%xmm12 + + vpxor %xmm1,%xmm9,%xmm9 + vpxor %xmm1,%xmm10,%xmm10 + vpxor %xmm1,%xmm11,%xmm11 + vpxor %xmm1,%xmm12,%xmm12 + + vmovdqa 16(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 32(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 48(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 64(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 80(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 96(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 112(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 128(%rdx),%xmm2 + vaesenc %xmm2,%xmm9,%xmm9 + vaesenc %xmm2,%xmm10,%xmm10 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + + vmovdqa 144(%rdx),%xmm1 + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + + vmovdqa 160(%rdx),%xmm2 + vaesenclast %xmm2,%xmm9,%xmm9 + vaesenclast %xmm2,%xmm10,%xmm10 + vaesenclast %xmm2,%xmm11,%xmm11 + vaesenclast %xmm2,%xmm12,%xmm12 + + + vmovdqa %xmm9,0(%rsi) + vmovdqa %xmm10,16(%rsi) + vmovdqa %xmm11,32(%rsi) + vmovdqa %xmm12,48(%rsi) + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_enc_msg_x4 +.private_extern _aes128gcmsiv_enc_msg_x4 + +.p2align 4 +_aes128gcmsiv_enc_msg_x4: + + testq %r8,%r8 + jnz L$128_enc_msg_x4_start + .byte 0xf3,0xc3 + +L$128_enc_msg_x4_start: + pushq %r12 + + pushq %r13 + + + shrq $4,%r8 + movq %r8,%r10 + shlq $62,%r10 + shrq $62,%r10 + + + vmovdqa (%rdx),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + + vmovdqu four(%rip),%xmm4 + vmovdqa %xmm15,%xmm0 + vpaddd one(%rip),%xmm15,%xmm1 + vpaddd two(%rip),%xmm15,%xmm2 + vpaddd three(%rip),%xmm15,%xmm3 + + shrq $2,%r8 + je L$128_enc_msg_x4_check_remainder + + subq $64,%rsi + subq $64,%rdi + +L$128_enc_msg_x4_loop1: + addq $64,%rsi + addq $64,%rdi + + vmovdqa %xmm0,%xmm5 + vmovdqa %xmm1,%xmm6 + vmovdqa %xmm2,%xmm7 + vmovdqa %xmm3,%xmm8 + + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqu 32(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm1,%xmm1 + vmovdqu 48(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm2,%xmm2 + vmovdqu 64(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm3,%xmm3 + + vmovdqu 80(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 96(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 112(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 128(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 144(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm12 + vaesenclast %xmm12,%xmm5,%xmm5 + vaesenclast %xmm12,%xmm6,%xmm6 + vaesenclast %xmm12,%xmm7,%xmm7 + vaesenclast %xmm12,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm5,%xmm5 + vpxor 16(%rdi),%xmm6,%xmm6 + vpxor 32(%rdi),%xmm7,%xmm7 + vpxor 48(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm5,0(%rsi) + vmovdqu %xmm6,16(%rsi) + vmovdqu %xmm7,32(%rsi) + vmovdqu %xmm8,48(%rsi) + + jne L$128_enc_msg_x4_loop1 + + addq $64,%rsi + addq $64,%rdi + +L$128_enc_msg_x4_check_remainder: + cmpq $0,%r10 + je L$128_enc_msg_x4_out + +L$128_enc_msg_x4_loop2: + + + vmovdqa %xmm0,%xmm5 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm5,%xmm5 + vaesenc 16(%rcx),%xmm5,%xmm5 + vaesenc 32(%rcx),%xmm5,%xmm5 + vaesenc 48(%rcx),%xmm5,%xmm5 + vaesenc 64(%rcx),%xmm5,%xmm5 + vaesenc 80(%rcx),%xmm5,%xmm5 + vaesenc 96(%rcx),%xmm5,%xmm5 + vaesenc 112(%rcx),%xmm5,%xmm5 + vaesenc 128(%rcx),%xmm5,%xmm5 + vaesenc 144(%rcx),%xmm5,%xmm5 + vaesenclast 160(%rcx),%xmm5,%xmm5 + + + vpxor (%rdi),%xmm5,%xmm5 + vmovdqu %xmm5,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + subq $1,%r10 + jne L$128_enc_msg_x4_loop2 + +L$128_enc_msg_x4_out: + popq %r13 + + popq %r12 + + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_enc_msg_x8 +.private_extern _aes128gcmsiv_enc_msg_x8 + +.p2align 4 +_aes128gcmsiv_enc_msg_x8: + + testq %r8,%r8 + jnz L$128_enc_msg_x8_start + .byte 0xf3,0xc3 + +L$128_enc_msg_x8_start: + pushq %r12 + + pushq %r13 + + pushq %rbp + + movq %rsp,%rbp + + + + subq $128,%rsp + andq $-64,%rsp + + shrq $4,%r8 + movq %r8,%r10 + shlq $61,%r10 + shrq $61,%r10 + + + vmovdqu (%rdx),%xmm1 + vpor OR_MASK(%rip),%xmm1,%xmm1 + + + vpaddd seven(%rip),%xmm1,%xmm0 + vmovdqu %xmm0,(%rsp) + vpaddd one(%rip),%xmm1,%xmm9 + vpaddd two(%rip),%xmm1,%xmm10 + vpaddd three(%rip),%xmm1,%xmm11 + vpaddd four(%rip),%xmm1,%xmm12 + vpaddd five(%rip),%xmm1,%xmm13 + vpaddd six(%rip),%xmm1,%xmm14 + vmovdqa %xmm1,%xmm0 + + shrq $3,%r8 + je L$128_enc_msg_x8_check_remainder + + subq $128,%rsi + subq $128,%rdi + +L$128_enc_msg_x8_loop1: + addq $128,%rsi + addq $128,%rdi + + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm9,%xmm2 + vmovdqa %xmm10,%xmm3 + vmovdqa %xmm11,%xmm4 + vmovdqa %xmm12,%xmm5 + vmovdqa %xmm13,%xmm6 + vmovdqa %xmm14,%xmm7 + + vmovdqu (%rsp),%xmm8 + + vpxor (%rcx),%xmm1,%xmm1 + vpxor (%rcx),%xmm2,%xmm2 + vpxor (%rcx),%xmm3,%xmm3 + vpxor (%rcx),%xmm4,%xmm4 + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu (%rsp),%xmm14 + vpaddd eight(%rip),%xmm14,%xmm14 + vmovdqu %xmm14,(%rsp) + vmovdqu 32(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpsubd one(%rip),%xmm14,%xmm14 + vmovdqu 48(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm0,%xmm0 + vmovdqu 64(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm9,%xmm9 + vmovdqu 80(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm10,%xmm10 + vmovdqu 96(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm11,%xmm11 + vmovdqu 112(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm12,%xmm12 + vmovdqu 128(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm13,%xmm13 + vmovdqu 144(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm15 + vaesenclast %xmm15,%xmm1,%xmm1 + vaesenclast %xmm15,%xmm2,%xmm2 + vaesenclast %xmm15,%xmm3,%xmm3 + vaesenclast %xmm15,%xmm4,%xmm4 + vaesenclast %xmm15,%xmm5,%xmm5 + vaesenclast %xmm15,%xmm6,%xmm6 + vaesenclast %xmm15,%xmm7,%xmm7 + vaesenclast %xmm15,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm1,%xmm1 + vpxor 16(%rdi),%xmm2,%xmm2 + vpxor 32(%rdi),%xmm3,%xmm3 + vpxor 48(%rdi),%xmm4,%xmm4 + vpxor 64(%rdi),%xmm5,%xmm5 + vpxor 80(%rdi),%xmm6,%xmm6 + vpxor 96(%rdi),%xmm7,%xmm7 + vpxor 112(%rdi),%xmm8,%xmm8 + + decq %r8 + + vmovdqu %xmm1,0(%rsi) + vmovdqu %xmm2,16(%rsi) + vmovdqu %xmm3,32(%rsi) + vmovdqu %xmm4,48(%rsi) + vmovdqu %xmm5,64(%rsi) + vmovdqu %xmm6,80(%rsi) + vmovdqu %xmm7,96(%rsi) + vmovdqu %xmm8,112(%rsi) + + jne L$128_enc_msg_x8_loop1 + + addq $128,%rsi + addq $128,%rdi + +L$128_enc_msg_x8_check_remainder: + cmpq $0,%r10 + je L$128_enc_msg_x8_out + +L$128_enc_msg_x8_loop2: + + + vmovdqa %xmm0,%xmm1 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm1,%xmm1 + vaesenc 16(%rcx),%xmm1,%xmm1 + vaesenc 32(%rcx),%xmm1,%xmm1 + vaesenc 48(%rcx),%xmm1,%xmm1 + vaesenc 64(%rcx),%xmm1,%xmm1 + vaesenc 80(%rcx),%xmm1,%xmm1 + vaesenc 96(%rcx),%xmm1,%xmm1 + vaesenc 112(%rcx),%xmm1,%xmm1 + vaesenc 128(%rcx),%xmm1,%xmm1 + vaesenc 144(%rcx),%xmm1,%xmm1 + vaesenclast 160(%rcx),%xmm1,%xmm1 + + + vpxor (%rdi),%xmm1,%xmm1 + + vmovdqu %xmm1,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + decq %r10 + jne L$128_enc_msg_x8_loop2 + +L$128_enc_msg_x8_out: + movq %rbp,%rsp + + popq %rbp + + popq %r13 + + popq %r12 + + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_dec +.private_extern _aes128gcmsiv_dec + +.p2align 4 +_aes128gcmsiv_dec: + + testq $~15,%r9 + jnz L$128_dec_start + .byte 0xf3,0xc3 + +L$128_dec_start: + vzeroupper + vmovdqa (%rdx),%xmm0 + movq %rdx,%rax + + leaq 32(%rax),%rax + leaq 32(%rcx),%rcx + + + vmovdqu (%rdi,%r9,1),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + andq $~15,%r9 + + + cmpq $96,%r9 + jb L$128_dec_loop2 + + + subq $96,%r9 + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vpxor (%r8),%xmm7,%xmm7 + vpxor (%r8),%xmm8,%xmm8 + vpxor (%r8),%xmm9,%xmm9 + vpxor (%r8),%xmm10,%xmm10 + vpxor (%r8),%xmm11,%xmm11 + vpxor (%r8),%xmm12,%xmm12 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vaesenclast %xmm4,%xmm8,%xmm8 + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm4,%xmm10,%xmm10 + vaesenclast %xmm4,%xmm11,%xmm11 + vaesenclast %xmm4,%xmm12,%xmm12 + + + vpxor 0(%rdi),%xmm7,%xmm7 + vpxor 16(%rdi),%xmm8,%xmm8 + vpxor 32(%rdi),%xmm9,%xmm9 + vpxor 48(%rdi),%xmm10,%xmm10 + vpxor 64(%rdi),%xmm11,%xmm11 + vpxor 80(%rdi),%xmm12,%xmm12 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + addq $96,%rdi + addq $96,%rsi + jmp L$128_dec_loop1 + + +.p2align 6 +L$128_dec_loop1: + cmpq $96,%r9 + jb L$128_dec_finish_96 + subq $96,%r9 + + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vmovdqa (%r8),%xmm4 + vpxor %xmm4,%xmm7,%xmm7 + vpxor %xmm4,%xmm8,%xmm8 + vpxor %xmm4,%xmm9,%xmm9 + vpxor %xmm4,%xmm10,%xmm10 + vpxor %xmm4,%xmm11,%xmm11 + vpxor %xmm4,%xmm12,%xmm12 + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vmovdqa 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm6 + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor 0(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vpxor 16(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm8,%xmm8 + vpxor 32(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm9,%xmm9 + vpxor 48(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm10,%xmm10 + vpxor 64(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm11,%xmm11 + vpxor 80(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm12,%xmm12 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + vpxor %xmm5,%xmm0,%xmm0 + + leaq 96(%rdi),%rdi + leaq 96(%rsi),%rsi + jmp L$128_dec_loop1 + +L$128_dec_finish_96: + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor %xmm5,%xmm0,%xmm0 + +L$128_dec_loop2: + + + + cmpq $16,%r9 + jb L$128_dec_out + subq $16,%r9 + + vmovdqa %xmm15,%xmm2 + vpaddd one(%rip),%xmm15,%xmm15 + + vpxor 0(%r8),%xmm2,%xmm2 + vaesenc 16(%r8),%xmm2,%xmm2 + vaesenc 32(%r8),%xmm2,%xmm2 + vaesenc 48(%r8),%xmm2,%xmm2 + vaesenc 64(%r8),%xmm2,%xmm2 + vaesenc 80(%r8),%xmm2,%xmm2 + vaesenc 96(%r8),%xmm2,%xmm2 + vaesenc 112(%r8),%xmm2,%xmm2 + vaesenc 128(%r8),%xmm2,%xmm2 + vaesenc 144(%r8),%xmm2,%xmm2 + vaesenclast 160(%r8),%xmm2,%xmm2 + vpxor (%rdi),%xmm2,%xmm2 + vmovdqu %xmm2,(%rsi) + addq $16,%rdi + addq $16,%rsi + + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa -32(%rcx),%xmm1 + call GFMUL + + jmp L$128_dec_loop2 + +L$128_dec_out: + vmovdqu %xmm0,(%rdx) + .byte 0xf3,0xc3 + + +.globl _aes128gcmsiv_ecb_enc_block +.private_extern _aes128gcmsiv_ecb_enc_block + +.p2align 4 +_aes128gcmsiv_ecb_enc_block: + + vmovdqa (%rdi),%xmm1 + + vpxor (%rdx),%xmm1,%xmm1 + vaesenc 16(%rdx),%xmm1,%xmm1 + vaesenc 32(%rdx),%xmm1,%xmm1 + vaesenc 48(%rdx),%xmm1,%xmm1 + vaesenc 64(%rdx),%xmm1,%xmm1 + vaesenc 80(%rdx),%xmm1,%xmm1 + vaesenc 96(%rdx),%xmm1,%xmm1 + vaesenc 112(%rdx),%xmm1,%xmm1 + vaesenc 128(%rdx),%xmm1,%xmm1 + vaesenc 144(%rdx),%xmm1,%xmm1 + vaesenclast 160(%rdx),%xmm1,%xmm1 + + vmovdqa %xmm1,(%rsi) + + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_aes_ks_enc_x1 +.private_extern _aes256gcmsiv_aes_ks_enc_x1 + +.p2align 4 +_aes256gcmsiv_aes_ks_enc_x1: + + vmovdqa con1(%rip),%xmm0 + vmovdqa mask(%rip),%xmm15 + vmovdqa (%rdi),%xmm8 + vmovdqa (%rcx),%xmm1 + vmovdqa 16(%rcx),%xmm3 + vpxor %xmm1,%xmm8,%xmm8 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm1,(%rdx) + vmovdqu %xmm3,16(%rdx) + vpxor %xmm14,%xmm14,%xmm14 + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,32(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,48(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,64(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,80(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,96(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,112(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,128(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,144(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,160(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,176(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslld $1,%xmm0,%xmm0 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenc %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,192(%rdx) + + vpshufd $0xff,%xmm1,%xmm2 + vaesenclast %xmm14,%xmm2,%xmm2 + vpslldq $4,%xmm3,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpxor %xmm2,%xmm3,%xmm3 + vaesenc %xmm3,%xmm8,%xmm8 + vmovdqu %xmm3,208(%rdx) + + vpshufb %xmm15,%xmm3,%xmm2 + vaesenclast %xmm0,%xmm2,%xmm2 + vpslldq $4,%xmm1,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpslldq $4,%xmm4,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpxor %xmm2,%xmm1,%xmm1 + vaesenclast %xmm1,%xmm8,%xmm8 + vmovdqu %xmm1,224(%rdx) + + vmovdqa %xmm8,(%rsi) + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_ecb_enc_block +.private_extern _aes256gcmsiv_ecb_enc_block + +.p2align 4 +_aes256gcmsiv_ecb_enc_block: + + vmovdqa (%rdi),%xmm1 + vpxor (%rdx),%xmm1,%xmm1 + vaesenc 16(%rdx),%xmm1,%xmm1 + vaesenc 32(%rdx),%xmm1,%xmm1 + vaesenc 48(%rdx),%xmm1,%xmm1 + vaesenc 64(%rdx),%xmm1,%xmm1 + vaesenc 80(%rdx),%xmm1,%xmm1 + vaesenc 96(%rdx),%xmm1,%xmm1 + vaesenc 112(%rdx),%xmm1,%xmm1 + vaesenc 128(%rdx),%xmm1,%xmm1 + vaesenc 144(%rdx),%xmm1,%xmm1 + vaesenc 160(%rdx),%xmm1,%xmm1 + vaesenc 176(%rdx),%xmm1,%xmm1 + vaesenc 192(%rdx),%xmm1,%xmm1 + vaesenc 208(%rdx),%xmm1,%xmm1 + vaesenclast 224(%rdx),%xmm1,%xmm1 + vmovdqa %xmm1,(%rsi) + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_enc_msg_x4 +.private_extern _aes256gcmsiv_enc_msg_x4 + +.p2align 4 +_aes256gcmsiv_enc_msg_x4: + + testq %r8,%r8 + jnz L$256_enc_msg_x4_start + .byte 0xf3,0xc3 + +L$256_enc_msg_x4_start: + movq %r8,%r10 + shrq $4,%r8 + shlq $60,%r10 + jz L$256_enc_msg_x4_start2 + addq $1,%r8 + +L$256_enc_msg_x4_start2: + movq %r8,%r10 + shlq $62,%r10 + shrq $62,%r10 + + + vmovdqa (%rdx),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + + vmovdqa four(%rip),%xmm4 + vmovdqa %xmm15,%xmm0 + vpaddd one(%rip),%xmm15,%xmm1 + vpaddd two(%rip),%xmm15,%xmm2 + vpaddd three(%rip),%xmm15,%xmm3 + + shrq $2,%r8 + je L$256_enc_msg_x4_check_remainder + + subq $64,%rsi + subq $64,%rdi + +L$256_enc_msg_x4_loop1: + addq $64,%rsi + addq $64,%rdi + + vmovdqa %xmm0,%xmm5 + vmovdqa %xmm1,%xmm6 + vmovdqa %xmm2,%xmm7 + vmovdqa %xmm3,%xmm8 + + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqu 32(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm1,%xmm1 + vmovdqu 48(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm2,%xmm2 + vmovdqu 64(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vpaddd %xmm4,%xmm3,%xmm3 + + vmovdqu 80(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 96(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 112(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 128(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 144(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 176(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 192(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 208(%rcx),%xmm12 + vaesenc %xmm12,%xmm5,%xmm5 + vaesenc %xmm12,%xmm6,%xmm6 + vaesenc %xmm12,%xmm7,%xmm7 + vaesenc %xmm12,%xmm8,%xmm8 + + vmovdqu 224(%rcx),%xmm12 + vaesenclast %xmm12,%xmm5,%xmm5 + vaesenclast %xmm12,%xmm6,%xmm6 + vaesenclast %xmm12,%xmm7,%xmm7 + vaesenclast %xmm12,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm5,%xmm5 + vpxor 16(%rdi),%xmm6,%xmm6 + vpxor 32(%rdi),%xmm7,%xmm7 + vpxor 48(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm5,0(%rsi) + vmovdqu %xmm6,16(%rsi) + vmovdqu %xmm7,32(%rsi) + vmovdqu %xmm8,48(%rsi) + + jne L$256_enc_msg_x4_loop1 + + addq $64,%rsi + addq $64,%rdi + +L$256_enc_msg_x4_check_remainder: + cmpq $0,%r10 + je L$256_enc_msg_x4_out + +L$256_enc_msg_x4_loop2: + + + + vmovdqa %xmm0,%xmm5 + vpaddd one(%rip),%xmm0,%xmm0 + vpxor (%rcx),%xmm5,%xmm5 + vaesenc 16(%rcx),%xmm5,%xmm5 + vaesenc 32(%rcx),%xmm5,%xmm5 + vaesenc 48(%rcx),%xmm5,%xmm5 + vaesenc 64(%rcx),%xmm5,%xmm5 + vaesenc 80(%rcx),%xmm5,%xmm5 + vaesenc 96(%rcx),%xmm5,%xmm5 + vaesenc 112(%rcx),%xmm5,%xmm5 + vaesenc 128(%rcx),%xmm5,%xmm5 + vaesenc 144(%rcx),%xmm5,%xmm5 + vaesenc 160(%rcx),%xmm5,%xmm5 + vaesenc 176(%rcx),%xmm5,%xmm5 + vaesenc 192(%rcx),%xmm5,%xmm5 + vaesenc 208(%rcx),%xmm5,%xmm5 + vaesenclast 224(%rcx),%xmm5,%xmm5 + + + vpxor (%rdi),%xmm5,%xmm5 + + vmovdqu %xmm5,(%rsi) + + addq $16,%rdi + addq $16,%rsi + + subq $1,%r10 + jne L$256_enc_msg_x4_loop2 + +L$256_enc_msg_x4_out: + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_enc_msg_x8 +.private_extern _aes256gcmsiv_enc_msg_x8 + +.p2align 4 +_aes256gcmsiv_enc_msg_x8: + + testq %r8,%r8 + jnz L$256_enc_msg_x8_start + .byte 0xf3,0xc3 + +L$256_enc_msg_x8_start: + + movq %rsp,%r11 + subq $16,%r11 + andq $-64,%r11 + + movq %r8,%r10 + shrq $4,%r8 + shlq $60,%r10 + jz L$256_enc_msg_x8_start2 + addq $1,%r8 + +L$256_enc_msg_x8_start2: + movq %r8,%r10 + shlq $61,%r10 + shrq $61,%r10 + + + vmovdqa (%rdx),%xmm1 + vpor OR_MASK(%rip),%xmm1,%xmm1 + + + vpaddd seven(%rip),%xmm1,%xmm0 + vmovdqa %xmm0,(%r11) + vpaddd one(%rip),%xmm1,%xmm9 + vpaddd two(%rip),%xmm1,%xmm10 + vpaddd three(%rip),%xmm1,%xmm11 + vpaddd four(%rip),%xmm1,%xmm12 + vpaddd five(%rip),%xmm1,%xmm13 + vpaddd six(%rip),%xmm1,%xmm14 + vmovdqa %xmm1,%xmm0 + + shrq $3,%r8 + jz L$256_enc_msg_x8_check_remainder + + subq $128,%rsi + subq $128,%rdi + +L$256_enc_msg_x8_loop1: + addq $128,%rsi + addq $128,%rdi + + vmovdqa %xmm0,%xmm1 + vmovdqa %xmm9,%xmm2 + vmovdqa %xmm10,%xmm3 + vmovdqa %xmm11,%xmm4 + vmovdqa %xmm12,%xmm5 + vmovdqa %xmm13,%xmm6 + vmovdqa %xmm14,%xmm7 + + vmovdqa (%r11),%xmm8 + + vpxor (%rcx),%xmm1,%xmm1 + vpxor (%rcx),%xmm2,%xmm2 + vpxor (%rcx),%xmm3,%xmm3 + vpxor (%rcx),%xmm4,%xmm4 + vpxor (%rcx),%xmm5,%xmm5 + vpxor (%rcx),%xmm6,%xmm6 + vpxor (%rcx),%xmm7,%xmm7 + vpxor (%rcx),%xmm8,%xmm8 + + vmovdqu 16(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqa (%r11),%xmm14 + vpaddd eight(%rip),%xmm14,%xmm14 + vmovdqa %xmm14,(%r11) + vmovdqu 32(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpsubd one(%rip),%xmm14,%xmm14 + vmovdqu 48(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm0,%xmm0 + vmovdqu 64(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm9,%xmm9 + vmovdqu 80(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm10,%xmm10 + vmovdqu 96(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm11,%xmm11 + vmovdqu 112(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm12,%xmm12 + vmovdqu 128(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vpaddd eight(%rip),%xmm13,%xmm13 + vmovdqu 144(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 160(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 176(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 192(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 208(%rcx),%xmm15 + vaesenc %xmm15,%xmm1,%xmm1 + vaesenc %xmm15,%xmm2,%xmm2 + vaesenc %xmm15,%xmm3,%xmm3 + vaesenc %xmm15,%xmm4,%xmm4 + vaesenc %xmm15,%xmm5,%xmm5 + vaesenc %xmm15,%xmm6,%xmm6 + vaesenc %xmm15,%xmm7,%xmm7 + vaesenc %xmm15,%xmm8,%xmm8 + + vmovdqu 224(%rcx),%xmm15 + vaesenclast %xmm15,%xmm1,%xmm1 + vaesenclast %xmm15,%xmm2,%xmm2 + vaesenclast %xmm15,%xmm3,%xmm3 + vaesenclast %xmm15,%xmm4,%xmm4 + vaesenclast %xmm15,%xmm5,%xmm5 + vaesenclast %xmm15,%xmm6,%xmm6 + vaesenclast %xmm15,%xmm7,%xmm7 + vaesenclast %xmm15,%xmm8,%xmm8 + + + + vpxor 0(%rdi),%xmm1,%xmm1 + vpxor 16(%rdi),%xmm2,%xmm2 + vpxor 32(%rdi),%xmm3,%xmm3 + vpxor 48(%rdi),%xmm4,%xmm4 + vpxor 64(%rdi),%xmm5,%xmm5 + vpxor 80(%rdi),%xmm6,%xmm6 + vpxor 96(%rdi),%xmm7,%xmm7 + vpxor 112(%rdi),%xmm8,%xmm8 + + subq $1,%r8 + + vmovdqu %xmm1,0(%rsi) + vmovdqu %xmm2,16(%rsi) + vmovdqu %xmm3,32(%rsi) + vmovdqu %xmm4,48(%rsi) + vmovdqu %xmm5,64(%rsi) + vmovdqu %xmm6,80(%rsi) + vmovdqu %xmm7,96(%rsi) + vmovdqu %xmm8,112(%rsi) + + jne L$256_enc_msg_x8_loop1 + + addq $128,%rsi + addq $128,%rdi + +L$256_enc_msg_x8_check_remainder: + cmpq $0,%r10 + je L$256_enc_msg_x8_out + +L$256_enc_msg_x8_loop2: + + + vmovdqa %xmm0,%xmm1 + vpaddd one(%rip),%xmm0,%xmm0 + + vpxor (%rcx),%xmm1,%xmm1 + vaesenc 16(%rcx),%xmm1,%xmm1 + vaesenc 32(%rcx),%xmm1,%xmm1 + vaesenc 48(%rcx),%xmm1,%xmm1 + vaesenc 64(%rcx),%xmm1,%xmm1 + vaesenc 80(%rcx),%xmm1,%xmm1 + vaesenc 96(%rcx),%xmm1,%xmm1 + vaesenc 112(%rcx),%xmm1,%xmm1 + vaesenc 128(%rcx),%xmm1,%xmm1 + vaesenc 144(%rcx),%xmm1,%xmm1 + vaesenc 160(%rcx),%xmm1,%xmm1 + vaesenc 176(%rcx),%xmm1,%xmm1 + vaesenc 192(%rcx),%xmm1,%xmm1 + vaesenc 208(%rcx),%xmm1,%xmm1 + vaesenclast 224(%rcx),%xmm1,%xmm1 + + + vpxor (%rdi),%xmm1,%xmm1 + + vmovdqu %xmm1,(%rsi) + + addq $16,%rdi + addq $16,%rsi + subq $1,%r10 + jnz L$256_enc_msg_x8_loop2 + +L$256_enc_msg_x8_out: + .byte 0xf3,0xc3 + + + +.globl _aes256gcmsiv_dec +.private_extern _aes256gcmsiv_dec + +.p2align 4 +_aes256gcmsiv_dec: + + testq $~15,%r9 + jnz L$256_dec_start + .byte 0xf3,0xc3 + +L$256_dec_start: + vzeroupper + vmovdqa (%rdx),%xmm0 + movq %rdx,%rax + + leaq 32(%rax),%rax + leaq 32(%rcx),%rcx + + + vmovdqu (%rdi,%r9,1),%xmm15 + vpor OR_MASK(%rip),%xmm15,%xmm15 + andq $~15,%r9 + + + cmpq $96,%r9 + jb L$256_dec_loop2 + + + subq $96,%r9 + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vpxor (%r8),%xmm7,%xmm7 + vpxor (%r8),%xmm8,%xmm8 + vpxor (%r8),%xmm9,%xmm9 + vpxor (%r8),%xmm10,%xmm10 + vpxor (%r8),%xmm11,%xmm11 + vpxor (%r8),%xmm12,%xmm12 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 176(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 192(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 208(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 224(%r8),%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vaesenclast %xmm4,%xmm8,%xmm8 + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm4,%xmm10,%xmm10 + vaesenclast %xmm4,%xmm11,%xmm11 + vaesenclast %xmm4,%xmm12,%xmm12 + + + vpxor 0(%rdi),%xmm7,%xmm7 + vpxor 16(%rdi),%xmm8,%xmm8 + vpxor 32(%rdi),%xmm9,%xmm9 + vpxor 48(%rdi),%xmm10,%xmm10 + vpxor 64(%rdi),%xmm11,%xmm11 + vpxor 80(%rdi),%xmm12,%xmm12 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + addq $96,%rdi + addq $96,%rsi + jmp L$256_dec_loop1 + + +.p2align 6 +L$256_dec_loop1: + cmpq $96,%r9 + jb L$256_dec_finish_96 + subq $96,%r9 + + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqa %xmm15,%xmm7 + vpaddd one(%rip),%xmm7,%xmm8 + vpaddd two(%rip),%xmm7,%xmm9 + vpaddd one(%rip),%xmm9,%xmm10 + vpaddd two(%rip),%xmm9,%xmm11 + vpaddd one(%rip),%xmm11,%xmm12 + vpaddd two(%rip),%xmm11,%xmm15 + + vmovdqa (%r8),%xmm4 + vpxor %xmm4,%xmm7,%xmm7 + vpxor %xmm4,%xmm8,%xmm8 + vpxor %xmm4,%xmm9,%xmm9 + vpxor %xmm4,%xmm10,%xmm10 + vpxor %xmm4,%xmm11,%xmm11 + vpxor %xmm4,%xmm12,%xmm12 + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 32(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 48(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 64(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 96(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 112(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vmovdqa 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 128(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vmovdqu 144(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 160(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 176(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 192(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 208(%r8),%xmm4 + vaesenc %xmm4,%xmm7,%xmm7 + vaesenc %xmm4,%xmm8,%xmm8 + vaesenc %xmm4,%xmm9,%xmm9 + vaesenc %xmm4,%xmm10,%xmm10 + vaesenc %xmm4,%xmm11,%xmm11 + vaesenc %xmm4,%xmm12,%xmm12 + + vmovdqu 224(%r8),%xmm6 + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor 0(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm7,%xmm7 + vpxor 16(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm8,%xmm8 + vpxor 32(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm9,%xmm9 + vpxor 48(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm10,%xmm10 + vpxor 64(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm11,%xmm11 + vpxor 80(%rdi),%xmm6,%xmm4 + vaesenclast %xmm4,%xmm12,%xmm12 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vmovdqu %xmm7,0(%rsi) + vmovdqu %xmm8,16(%rsi) + vmovdqu %xmm9,32(%rsi) + vmovdqu %xmm10,48(%rsi) + vmovdqu %xmm11,64(%rsi) + vmovdqu %xmm12,80(%rsi) + + vpxor %xmm5,%xmm0,%xmm0 + + leaq 96(%rdi),%rdi + leaq 96(%rsi),%rsi + jmp L$256_dec_loop1 + +L$256_dec_finish_96: + vmovdqa %xmm12,%xmm6 + vmovdqa %xmm11,16-32(%rax) + vmovdqa %xmm10,32-32(%rax) + vmovdqa %xmm9,48-32(%rax) + vmovdqa %xmm8,64-32(%rax) + vmovdqa %xmm7,80-32(%rax) + + vmovdqu 0-32(%rcx),%xmm4 + vpclmulqdq $0x10,%xmm4,%xmm6,%xmm1 + vpclmulqdq $0x11,%xmm4,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm4,%xmm6,%xmm3 + vpclmulqdq $0x01,%xmm4,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu -16(%rax),%xmm6 + vmovdqu -16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 0(%rax),%xmm6 + vmovdqu 0(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 16(%rax),%xmm6 + vmovdqu 16(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vmovdqu 32(%rax),%xmm6 + vmovdqu 32(%rcx),%xmm13 + + vpclmulqdq $0x10,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x11,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x01,%xmm13,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + + vmovdqu 80-32(%rax),%xmm6 + vpxor %xmm0,%xmm6,%xmm6 + vmovdqu 80-32(%rcx),%xmm5 + vpclmulqdq $0x11,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + vpclmulqdq $0x10,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x01,%xmm5,%xmm6,%xmm4 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm2,%xmm5 + vpslldq $8,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm0 + + vmovdqa poly(%rip),%xmm3 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpalignr $8,%xmm0,%xmm0,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm2,%xmm0 + + vpxor %xmm5,%xmm0,%xmm0 + +L$256_dec_loop2: + + + + cmpq $16,%r9 + jb L$256_dec_out + subq $16,%r9 + + vmovdqa %xmm15,%xmm2 + vpaddd one(%rip),%xmm15,%xmm15 + + vpxor 0(%r8),%xmm2,%xmm2 + vaesenc 16(%r8),%xmm2,%xmm2 + vaesenc 32(%r8),%xmm2,%xmm2 + vaesenc 48(%r8),%xmm2,%xmm2 + vaesenc 64(%r8),%xmm2,%xmm2 + vaesenc 80(%r8),%xmm2,%xmm2 + vaesenc 96(%r8),%xmm2,%xmm2 + vaesenc 112(%r8),%xmm2,%xmm2 + vaesenc 128(%r8),%xmm2,%xmm2 + vaesenc 144(%r8),%xmm2,%xmm2 + vaesenc 160(%r8),%xmm2,%xmm2 + vaesenc 176(%r8),%xmm2,%xmm2 + vaesenc 192(%r8),%xmm2,%xmm2 + vaesenc 208(%r8),%xmm2,%xmm2 + vaesenclast 224(%r8),%xmm2,%xmm2 + vpxor (%rdi),%xmm2,%xmm2 + vmovdqu %xmm2,(%rsi) + addq $16,%rdi + addq $16,%rsi + + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa -32(%rcx),%xmm1 + call GFMUL + + jmp L$256_dec_loop2 + +L$256_dec_out: + vmovdqu %xmm0,(%rdx) + .byte 0xf3,0xc3 + + +.globl _aes256gcmsiv_kdf +.private_extern _aes256gcmsiv_kdf + +.p2align 4 +_aes256gcmsiv_kdf: + + + + + + vmovdqa (%rdx),%xmm1 + vmovdqa 0(%rdi),%xmm4 + vmovdqa and_mask(%rip),%xmm11 + vmovdqa one(%rip),%xmm8 + vpshufd $0x90,%xmm4,%xmm4 + vpand %xmm11,%xmm4,%xmm4 + vpaddd %xmm8,%xmm4,%xmm6 + vpaddd %xmm8,%xmm6,%xmm7 + vpaddd %xmm8,%xmm7,%xmm11 + vpaddd %xmm8,%xmm11,%xmm12 + vpaddd %xmm8,%xmm12,%xmm13 + + vpxor %xmm1,%xmm4,%xmm4 + vpxor %xmm1,%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm1,%xmm11,%xmm11 + vpxor %xmm1,%xmm12,%xmm12 + vpxor %xmm1,%xmm13,%xmm13 + + vmovdqa 16(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 32(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 48(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 64(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 80(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 96(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 112(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 128(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 144(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 160(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 176(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 192(%rdx),%xmm2 + vaesenc %xmm2,%xmm4,%xmm4 + vaesenc %xmm2,%xmm6,%xmm6 + vaesenc %xmm2,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vaesenc %xmm2,%xmm12,%xmm12 + vaesenc %xmm2,%xmm13,%xmm13 + + vmovdqa 208(%rdx),%xmm1 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + + vmovdqa 224(%rdx),%xmm2 + vaesenclast %xmm2,%xmm4,%xmm4 + vaesenclast %xmm2,%xmm6,%xmm6 + vaesenclast %xmm2,%xmm7,%xmm7 + vaesenclast %xmm2,%xmm11,%xmm11 + vaesenclast %xmm2,%xmm12,%xmm12 + vaesenclast %xmm2,%xmm13,%xmm13 + + + vmovdqa %xmm4,0(%rsi) + vmovdqa %xmm6,16(%rsi) + vmovdqa %xmm7,32(%rsi) + vmovdqa %xmm11,48(%rsi) + vmovdqa %xmm12,64(%rsi) + vmovdqa %xmm13,80(%rsi) + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S new file mode 100644 index 00000000..eae90202 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S @@ -0,0 +1,8929 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + +chacha20_poly1305_constants: + +.align 64 +.Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.Lrol16: +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +.Lavx2_init: +.long 0,0,0,0 +.Lsse_inc: +.long 1,0,0,0 +.Lavx2_inc: +.long 2,0,0,0,2,0,0,0 +.Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC +.quad 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +.align 16 +.Land_masks: +.byte 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + +.type poly_hash_ad_internal,@function +.align 64 +poly_hash_ad_internal: +.cfi_startproc +.cfi_def_cfa rsp, 8 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + cmpq $13,%r8 + jne .Lhash_ad_loop +.Lpoly_fast_tls_ad: + + movq (%rcx),%r10 + movq 5(%rcx),%r11 + shrq $24,%r11 + movq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + .byte 0xf3,0xc3 +.Lhash_ad_loop: + + cmpq $16,%r8 + jb .Lhash_ad_tail + addq 0+0(%rcx),%r10 + adcq 8+0(%rcx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rcx),%rcx + subq $16,%r8 + jmp .Lhash_ad_loop +.Lhash_ad_tail: + cmpq $0,%r8 + je .Lhash_ad_done + + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + addq %r8,%rcx +.Lhash_ad_tail_loop: + shldq $8,%r13,%r14 + shlq $8,%r13 + movzbq -1(%rcx),%r15 + xorq %r15,%r13 + decq %rcx + decq %r8 + jne .Lhash_ad_tail_loop + + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +.Lhash_ad_done: + .byte 0xf3,0xc3 +.cfi_endproc +.size poly_hash_ad_internal, .-poly_hash_ad_internal + +.globl chacha20_poly1305_open +.hidden chacha20_poly1305_open +.type chacha20_poly1305_open,@function +.align 64 +chacha20_poly1305_open: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + + pushq %r9 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r9,-64 + subq $288 + 0 + 32,%rsp +.cfi_adjust_cfa_offset 288 + 32 + + leaq 32(%rsp),%rbp + andq $-32,%rbp + + movq %rdx,%rbx + movq %r8,0+0+32(%rbp) + movq %rbx,8+0+32(%rbp) + + movl OPENSSL_ia32cap_P+8(%rip),%eax + andl $288,%eax + xorl $288,%eax + jz chacha20_poly1305_open_avx2 + + cmpq $128,%rbx + jbe .Lopen_sse_128 + + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqu 0(%r9),%xmm4 + movdqu 16(%r9),%xmm8 + movdqu 32(%r9),%xmm12 + + movdqa %xmm12,%xmm7 + + movdqa %xmm4,0+48(%rbp) + movdqa %xmm8,0+64(%rbp) + movdqa %xmm12,0+96(%rbp) + movq $10,%r10 +.Lopen_sse_init_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %r10 + jne .Lopen_sse_init_rounds + + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + + pand .Lclamp(%rip),%xmm0 + movdqa %xmm0,0+0(%rbp) + movdqa %xmm4,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal +.Lopen_sse_main_loop: + cmpq $256,%rbx + jb .Lopen_sse_tail + + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd .Lsse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + + + + movq $4,%rcx + movq %rsi,%r8 +.Lopen_sse_main_loop_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + + leaq 16(%r8),%r8 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %rcx + jge .Lopen_sse_main_loop_rounds + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + cmpq $-6,%rcx + jg .Lopen_sse_main_loop_rounds + paddd .Lchacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqa %xmm12,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm12 + pxor %xmm3,%xmm12 + movdqu %xmm12,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm12 + pxor %xmm7,%xmm12 + movdqu %xmm12,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm12 + pxor %xmm11,%xmm12 + movdqu %xmm12,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm12 + pxor %xmm15,%xmm12 + movdqu %xmm12,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + movdqu 0 + 192(%rsi),%xmm3 + movdqu 16 + 192(%rsi),%xmm7 + movdqu 32 + 192(%rsi),%xmm11 + movdqu 48 + 192(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor 0+80(%rbp),%xmm15 + movdqu %xmm0,0 + 192(%rdi) + movdqu %xmm4,16 + 192(%rdi) + movdqu %xmm8,32 + 192(%rdi) + movdqu %xmm15,48 + 192(%rdi) + + leaq 256(%rsi),%rsi + leaq 256(%rdi),%rdi + subq $256,%rbx + jmp .Lopen_sse_main_loop +.Lopen_sse_tail: + + testq %rbx,%rbx + jz .Lopen_sse_finalize + cmpq $192,%rbx + ja .Lopen_sse_tail_256 + cmpq $128,%rbx + ja .Lopen_sse_tail_192 + cmpq $64,%rbx + ja .Lopen_sse_tail_128 + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa 0+96(%rbp),%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + + xorq %r8,%r8 + movq %rbx,%rcx + cmpq $16,%rcx + jb .Lopen_sse_tail_64_rounds +.Lopen_sse_tail_64_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx +.Lopen_sse_tail_64_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + cmpq $16,%rcx + jae .Lopen_sse_tail_64_rounds_and_x1hash + cmpq $160,%r8 + jne .Lopen_sse_tail_64_rounds + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + jmp .Lopen_sse_tail_64_dec_loop + +.Lopen_sse_tail_128: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa 0+96(%rbp),%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + + movq %rbx,%rcx + andq $-16,%rcx + xorq %r8,%r8 +.Lopen_sse_tail_128_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +.Lopen_sse_tail_128_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + + cmpq %rcx,%r8 + jb .Lopen_sse_tail_128_rounds_and_x1hash + cmpq $160,%r8 + jne .Lopen_sse_tail_128_rounds + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 0(%rdi) + movdqu %xmm5,16 + 0(%rdi) + movdqu %xmm9,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + + subq $64,%rbx + leaq 64(%rsi),%rsi + leaq 64(%rdi),%rdi + jmp .Lopen_sse_tail_64_dec_loop + +.Lopen_sse_tail_192: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa 0+96(%rbp),%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + + movq %rbx,%rcx + movq $160,%r8 + cmpq $160,%rcx + cmovgq %r8,%rcx + andq $-16,%rcx + xorq %r8,%r8 +.Lopen_sse_tail_192_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +.Lopen_sse_tail_192_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + cmpq %rcx,%r8 + jb .Lopen_sse_tail_192_rounds_and_x1hash + cmpq $160,%r8 + jne .Lopen_sse_tail_192_rounds + cmpq $176,%rbx + jb .Lopen_sse_tail_192_finish + addq 0+160(%rsi),%r10 + adcq 8+160(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + cmpq $192,%rbx + jb .Lopen_sse_tail_192_finish + addq 0+176(%rsi),%r10 + adcq 8+176(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +.Lopen_sse_tail_192_finish: + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + subq $128,%rbx + leaq 128(%rsi),%rsi + leaq 128(%rdi),%rdi + jmp .Lopen_sse_tail_64_dec_loop + +.Lopen_sse_tail_256: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd .Lsse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + + xorq %r8,%r8 +.Lopen_sse_tail_256_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movdqa %xmm11,0+80(%rbp) + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm4 + pxor %xmm11,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm4 + pxor %xmm11,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm5 + pxor %xmm11,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm5 + pxor %xmm11,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm6 + pxor %xmm11,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm6 + pxor %xmm11,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + movdqa 0+80(%rbp),%xmm11 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa %xmm9,0+80(%rbp) + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb .Lrol16(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $12,%xmm9 + psrld $20,%xmm7 + pxor %xmm9,%xmm7 + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb .Lrol8(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $7,%xmm9 + psrld $25,%xmm7 + pxor %xmm9,%xmm7 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 + movdqa 0+80(%rbp),%xmm9 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + movdqa %xmm11,0+80(%rbp) + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm4 + pxor %xmm11,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm4 + pxor %xmm11,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm5 + pxor %xmm11,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm5 + pxor %xmm11,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm6 + pxor %xmm11,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm6 + pxor %xmm11,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + movdqa 0+80(%rbp),%xmm11 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + movdqa %xmm9,0+80(%rbp) + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb .Lrol16(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $12,%xmm9 + psrld $20,%xmm7 + pxor %xmm9,%xmm7 + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb .Lrol8(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $7,%xmm9 + psrld $25,%xmm7 + pxor %xmm9,%xmm7 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 + movdqa 0+80(%rbp),%xmm9 + + addq $16,%r8 + cmpq $160,%r8 + jb .Lopen_sse_tail_256_rounds_and_x1hash + + movq %rbx,%rcx + andq $-16,%rcx +.Lopen_sse_tail_256_hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + addq $16,%r8 + cmpq %rcx,%r8 + jb .Lopen_sse_tail_256_hash + paddd .Lchacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqa %xmm12,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm12 + pxor %xmm3,%xmm12 + movdqu %xmm12,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm12 + pxor %xmm7,%xmm12 + movdqu %xmm12,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm12 + pxor %xmm11,%xmm12 + movdqu %xmm12,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm12 + pxor %xmm15,%xmm12 + movdqu %xmm12,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + movdqa 0+80(%rbp),%xmm12 + subq $192,%rbx + leaq 192(%rsi),%rsi + leaq 192(%rdi),%rdi + + +.Lopen_sse_tail_64_dec_loop: + cmpq $16,%rbx + jb .Lopen_sse_tail_16_init + subq $16,%rbx + movdqu (%rsi),%xmm3 + pxor %xmm3,%xmm0 + movdqu %xmm0,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movdqa %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + jmp .Lopen_sse_tail_64_dec_loop +.Lopen_sse_tail_16_init: + movdqa %xmm0,%xmm1 + + +.Lopen_sse_tail_16: + testq %rbx,%rbx + jz .Lopen_sse_finalize + + + + pxor %xmm3,%xmm3 + leaq -1(%rsi,%rbx,1),%rsi + movq %rbx,%r8 +.Lopen_sse_tail_16_compose: + pslldq $1,%xmm3 + pinsrb $0,(%rsi),%xmm3 + subq $1,%rsi + subq $1,%r8 + jnz .Lopen_sse_tail_16_compose + +.byte 102,73,15,126,221 + pextrq $1,%xmm3,%r14 + + pxor %xmm1,%xmm3 + + +.Lopen_sse_tail_16_extract: + pextrb $0,%xmm3,(%rdi) + psrldq $1,%xmm3 + addq $1,%rdi + subq $1,%rbx + jne .Lopen_sse_tail_16_extract + + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +.Lopen_sse_finalize: + addq 0+0+32(%rbp),%r10 + adcq 8+0+32(%rbp),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movq %r10,%r13 + movq %r11,%r14 + movq %r12,%r15 + subq $-5,%r10 + sbbq $-1,%r11 + sbbq $3,%r12 + cmovcq %r13,%r10 + cmovcq %r14,%r11 + cmovcq %r15,%r12 + + addq 0+0+16(%rbp),%r10 + adcq 8+0+16(%rbp),%r11 + +.cfi_remember_state + addq $288 + 0 + 32,%rsp +.cfi_adjust_cfa_offset -(288 + 32) + + popq %r9 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r9 + movq %r10,(%r9) + movq %r11,8(%r9) + popq %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + popq %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp + .byte 0xf3,0xc3 + +.Lopen_sse_128: +.cfi_restore_state + movdqu .Lchacha20_consts(%rip),%xmm0 + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqu 0(%r9),%xmm4 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqu 16(%r9),%xmm8 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqu 32(%r9),%xmm12 + movdqa %xmm12,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa %xmm13,%xmm15 + movq $10,%r10 + +.Lopen_sse_128_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + decq %r10 + jnz .Lopen_sse_128_rounds + paddd .Lchacha20_consts(%rip),%xmm0 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd %xmm7,%xmm4 + paddd %xmm7,%xmm5 + paddd %xmm7,%xmm6 + paddd %xmm11,%xmm9 + paddd %xmm11,%xmm10 + paddd %xmm15,%xmm13 + paddd .Lsse_inc(%rip),%xmm15 + paddd %xmm15,%xmm14 + + pand .Lclamp(%rip),%xmm0 + movdqa %xmm0,0+0(%rbp) + movdqa %xmm4,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal +.Lopen_sse_128_xor_hash: + cmpq $16,%rbx + jb .Lopen_sse_tail_16 + subq $16,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + + + movdqu 0(%rsi),%xmm3 + pxor %xmm3,%xmm1 + movdqu %xmm1,0(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movdqa %xmm5,%xmm1 + movdqa %xmm9,%xmm5 + movdqa %xmm13,%xmm9 + movdqa %xmm2,%xmm13 + movdqa %xmm6,%xmm2 + movdqa %xmm10,%xmm6 + movdqa %xmm14,%xmm10 + jmp .Lopen_sse_128_xor_hash +.size chacha20_poly1305_open, .-chacha20_poly1305_open +.cfi_endproc + + + + + + + +.globl chacha20_poly1305_seal +.hidden chacha20_poly1305_seal +.type chacha20_poly1305_seal,@function +.align 64 +chacha20_poly1305_seal: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + + pushq %r9 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r9,-64 + subq $288 + 0 + 32,%rsp +.cfi_adjust_cfa_offset 288 + 32 + leaq 32(%rsp),%rbp + andq $-32,%rbp + + movq 56(%r9),%rbx + addq %rdx,%rbx + movq %r8,0+0+32(%rbp) + movq %rbx,8+0+32(%rbp) + movq %rdx,%rbx + + movl OPENSSL_ia32cap_P+8(%rip),%eax + andl $288,%eax + xorl $288,%eax + jz chacha20_poly1305_seal_avx2 + + cmpq $128,%rbx + jbe .Lseal_sse_128 + + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqu 0(%r9),%xmm4 + movdqu 16(%r9),%xmm8 + movdqu 32(%r9),%xmm12 + + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqa %xmm8,%xmm11 + movdqa %xmm12,%xmm15 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm14 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm13 + paddd .Lsse_inc(%rip),%xmm12 + + movdqa %xmm4,0+48(%rbp) + movdqa %xmm8,0+64(%rbp) + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + movq $10,%r10 +.Lseal_sse_init_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %r10 + jnz .Lseal_sse_init_rounds + paddd .Lchacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + + pand .Lclamp(%rip),%xmm3 + movdqa %xmm3,0+0(%rbp) + movdqa %xmm7,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + cmpq $192,%rbx + ja .Lseal_sse_main_init + movq $128,%rcx + subq $128,%rbx + leaq 128(%rsi),%rsi + jmp .Lseal_sse_128_tail_hash +.Lseal_sse_main_init: + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor %xmm12,%xmm15 + movdqu %xmm0,0 + 128(%rdi) + movdqu %xmm4,16 + 128(%rdi) + movdqu %xmm8,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + movq $192,%rcx + subq $192,%rbx + leaq 192(%rsi),%rsi + movq $2,%rcx + movq $8,%r8 + cmpq $64,%rbx + jbe .Lseal_sse_tail_64 + cmpq $128,%rbx + jbe .Lseal_sse_tail_128 + cmpq $192,%rbx + jbe .Lseal_sse_tail_192 + +.Lseal_sse_main_loop: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd .Lsse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + +.align 32 +.Lseal_sse_main_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa .Lrol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa .Lrol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + leaq 16(%rdi),%rdi + decq %r8 + jge .Lseal_sse_main_rounds + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + decq %rcx + jg .Lseal_sse_main_rounds + paddd .Lchacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + movdqa %xmm14,0+80(%rbp) + movdqa %xmm14,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm14 + pxor %xmm3,%xmm14 + movdqu %xmm14,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm14 + pxor %xmm7,%xmm14 + movdqu %xmm14,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm14 + pxor %xmm11,%xmm14 + movdqu %xmm14,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm14 + pxor %xmm15,%xmm14 + movdqu %xmm14,48 + 0(%rdi) + + movdqa 0+80(%rbp),%xmm14 + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + cmpq $256,%rbx + ja .Lseal_sse_main_loop_xor + + movq $192,%rcx + subq $192,%rbx + leaq 192(%rsi),%rsi + jmp .Lseal_sse_128_tail_hash +.Lseal_sse_main_loop_xor: + movdqu 0 + 192(%rsi),%xmm3 + movdqu 16 + 192(%rsi),%xmm7 + movdqu 32 + 192(%rsi),%xmm11 + movdqu 48 + 192(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor %xmm12,%xmm15 + movdqu %xmm0,0 + 192(%rdi) + movdqu %xmm4,16 + 192(%rdi) + movdqu %xmm8,32 + 192(%rdi) + movdqu %xmm15,48 + 192(%rdi) + + leaq 256(%rsi),%rsi + subq $256,%rbx + movq $6,%rcx + movq $4,%r8 + cmpq $192,%rbx + jg .Lseal_sse_main_loop + movq %rbx,%rcx + testq %rbx,%rbx + je .Lseal_sse_128_tail_hash + movq $6,%rcx + cmpq $128,%rbx + ja .Lseal_sse_tail_192 + cmpq $64,%rbx + ja .Lseal_sse_tail_128 + +.Lseal_sse_tail_64: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa 0+96(%rbp),%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + +.Lseal_sse_tail_64_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_sse_tail_64_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + decq %rcx + jg .Lseal_sse_tail_64_rounds_and_x2hash + decq %r8 + jge .Lseal_sse_tail_64_rounds_and_x1hash + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + jmp .Lseal_sse_128_tail_xor + +.Lseal_sse_tail_128: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa 0+96(%rbp),%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + +.Lseal_sse_tail_128_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_sse_tail_128_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + + leaq 16(%rdi),%rdi + decq %rcx + jg .Lseal_sse_tail_128_rounds_and_x2hash + decq %r8 + jge .Lseal_sse_tail_128_rounds_and_x1hash + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 0(%rdi) + movdqu %xmm5,16 + 0(%rdi) + movdqu %xmm9,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + + movq $64,%rcx + subq $64,%rbx + leaq 64(%rsi),%rsi + jmp .Lseal_sse_128_tail_hash + +.Lseal_sse_tail_192: + movdqa .Lchacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa 0+96(%rbp),%xmm14 + paddd .Lsse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + +.Lseal_sse_tail_192_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_sse_tail_192_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + leaq 16(%rdi),%rdi + decq %rcx + jg .Lseal_sse_tail_192_rounds_and_x2hash + decq %r8 + jge .Lseal_sse_tail_192_rounds_and_x1hash + paddd .Lchacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd .Lchacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + movq $128,%rcx + subq $128,%rbx + leaq 128(%rsi),%rsi + +.Lseal_sse_128_tail_hash: + cmpq $16,%rcx + jb .Lseal_sse_128_tail_xor + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx + leaq 16(%rdi),%rdi + jmp .Lseal_sse_128_tail_hash + +.Lseal_sse_128_tail_xor: + cmpq $16,%rbx + jb .Lseal_sse_tail_16 + subq $16,%rbx + + movdqu 0(%rsi),%xmm3 + pxor %xmm3,%xmm0 + movdqu %xmm0,0(%rdi) + + addq 0(%rdi),%r10 + adcq 8(%rdi),%r11 + adcq $1,%r12 + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movdqa %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + movdqa %xmm1,%xmm12 + movdqa %xmm5,%xmm1 + movdqa %xmm9,%xmm5 + movdqa %xmm13,%xmm9 + jmp .Lseal_sse_128_tail_xor + +.Lseal_sse_tail_16: + testq %rbx,%rbx + jz .Lprocess_blocks_of_extra_in + + movq %rbx,%r8 + movq %rbx,%rcx + leaq -1(%rsi,%rbx,1),%rsi + pxor %xmm15,%xmm15 +.Lseal_sse_tail_16_compose: + pslldq $1,%xmm15 + pinsrb $0,(%rsi),%xmm15 + leaq -1(%rsi),%rsi + decq %rcx + jne .Lseal_sse_tail_16_compose + + + pxor %xmm0,%xmm15 + + + movq %rbx,%rcx + movdqu %xmm15,%xmm0 +.Lseal_sse_tail_16_extract: + pextrb $0,%xmm0,(%rdi) + psrldq $1,%xmm0 + addq $1,%rdi + subq $1,%rcx + jnz .Lseal_sse_tail_16_extract + + + + + + + + + movq 288 + 0 + 32(%rsp),%r9 + movq 56(%r9),%r14 + movq 48(%r9),%r13 + testq %r14,%r14 + jz .Lprocess_partial_block + + movq $16,%r15 + subq %rbx,%r15 + cmpq %r15,%r14 + + jge .Lload_extra_in + movq %r14,%r15 + +.Lload_extra_in: + + + leaq -1(%r13,%r15,1),%rsi + + + addq %r15,%r13 + subq %r15,%r14 + movq %r13,48(%r9) + movq %r14,56(%r9) + + + + addq %r15,%r8 + + + pxor %xmm11,%xmm11 +.Lload_extra_load_loop: + pslldq $1,%xmm11 + pinsrb $0,(%rsi),%xmm11 + leaq -1(%rsi),%rsi + subq $1,%r15 + jnz .Lload_extra_load_loop + + + + + movq %rbx,%r15 + +.Lload_extra_shift_loop: + pslldq $1,%xmm11 + subq $1,%r15 + jnz .Lload_extra_shift_loop + + + + + leaq .Land_masks(%rip),%r15 + shlq $4,%rbx + pand -16(%r15,%rbx,1),%xmm15 + + + por %xmm11,%xmm15 + + + +.byte 102,77,15,126,253 + pextrq $1,%xmm15,%r14 + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +.Lprocess_blocks_of_extra_in: + + movq 288+32+0 (%rsp),%r9 + movq 48(%r9),%rsi + movq 56(%r9),%r8 + movq %r8,%rcx + shrq $4,%r8 + +.Lprocess_extra_hash_loop: + jz process_extra_in_trailer + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rsi),%rsi + subq $1,%r8 + jmp .Lprocess_extra_hash_loop +process_extra_in_trailer: + andq $15,%rcx + movq %rcx,%rbx + jz .Ldo_length_block + leaq -1(%rsi,%rcx,1),%rsi + +.Lprocess_extra_in_trailer_load: + pslldq $1,%xmm15 + pinsrb $0,(%rsi),%xmm15 + leaq -1(%rsi),%rsi + subq $1,%rcx + jnz .Lprocess_extra_in_trailer_load + +.Lprocess_partial_block: + + leaq .Land_masks(%rip),%r15 + shlq $4,%rbx + pand -16(%r15,%rbx,1),%xmm15 +.byte 102,77,15,126,253 + pextrq $1,%xmm15,%r14 + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +.Ldo_length_block: + addq 0+0+32(%rbp),%r10 + adcq 8+0+32(%rbp),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movq %r10,%r13 + movq %r11,%r14 + movq %r12,%r15 + subq $-5,%r10 + sbbq $-1,%r11 + sbbq $3,%r12 + cmovcq %r13,%r10 + cmovcq %r14,%r11 + cmovcq %r15,%r12 + + addq 0+0+16(%rbp),%r10 + adcq 8+0+16(%rbp),%r11 + +.cfi_remember_state + addq $288 + 0 + 32,%rsp +.cfi_adjust_cfa_offset -(288 + 32) + + popq %r9 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r9 + movq %r10,(%r9) + movq %r11,8(%r9) + popq %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + popq %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp + .byte 0xf3,0xc3 + +.Lseal_sse_128: +.cfi_restore_state + movdqu .Lchacha20_consts(%rip),%xmm0 + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqu 0(%r9),%xmm4 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqu 16(%r9),%xmm8 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqu 32(%r9),%xmm14 + movdqa %xmm14,%xmm12 + paddd .Lsse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm13 + paddd .Lsse_inc(%rip),%xmm13 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa %xmm12,%xmm15 + movq $10,%r10 + +.Lseal_sse_128_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb .Lrol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb .Lrol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb .Lrol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + decq %r10 + jnz .Lseal_sse_128_rounds + paddd .Lchacha20_consts(%rip),%xmm0 + paddd .Lchacha20_consts(%rip),%xmm1 + paddd .Lchacha20_consts(%rip),%xmm2 + paddd %xmm7,%xmm4 + paddd %xmm7,%xmm5 + paddd %xmm7,%xmm6 + paddd %xmm11,%xmm8 + paddd %xmm11,%xmm9 + paddd %xmm15,%xmm12 + paddd .Lsse_inc(%rip),%xmm15 + paddd %xmm15,%xmm13 + + pand .Lclamp(%rip),%xmm2 + movdqa %xmm2,0+0(%rbp) + movdqa %xmm6,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal + jmp .Lseal_sse_128_tail_xor +.size chacha20_poly1305_seal, .-chacha20_poly1305_seal +.cfi_endproc + + +.type chacha20_poly1305_open_avx2,@function +.align 64 +chacha20_poly1305_open_avx2: +.cfi_startproc + + +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r9,-64 +.cfi_adjust_cfa_offset 288 + 32 + + vzeroupper + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vbroadcasti128 0(%r9),%ymm4 + vbroadcasti128 16(%r9),%ymm8 + vbroadcasti128 32(%r9),%ymm12 + vpaddd .Lavx2_init(%rip),%ymm12,%ymm12 + cmpq $192,%rbx + jbe .Lopen_avx2_192 + cmpq $320,%rbx + jbe .Lopen_avx2_320 + + vmovdqa %ymm4,0+64(%rbp) + vmovdqa %ymm8,0+96(%rbp) + vmovdqa %ymm12,0+160(%rbp) + movq $10,%r10 +.Lopen_avx2_init_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + decq %r10 + jne .Lopen_avx2_init_rounds + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand .Lclamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + + movq %r8,%r8 + call poly_hash_ad_internal + + xorq %rcx,%rcx +.Lopen_avx2_init_hash: + addq 0+0(%rsi,%rcx,1),%r10 + adcq 8+0(%rsi,%rcx,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + addq $16,%rcx + cmpq $64,%rcx + jne .Lopen_avx2_init_hash + + vpxor 0(%rsi),%ymm0,%ymm0 + vpxor 32(%rsi),%ymm4,%ymm4 + + vmovdqu %ymm0,0(%rdi) + vmovdqu %ymm4,32(%rdi) + leaq 64(%rsi),%rsi + leaq 64(%rdi),%rdi + subq $64,%rbx +.Lopen_avx2_main_loop: + + cmpq $512,%rbx + jb .Lopen_avx2_main_loop_done + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + xorq %rcx,%rcx +.Lopen_avx2_main_loop_rounds: + addq 0+0(%rsi,%rcx,1),%r10 + adcq 8+0(%rsi,%rcx,1),%r11 + adcq $1,%r12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + addq %rax,%r15 + adcq %rdx,%r9 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + addq 0+16(%rsi,%rcx,1),%r10 + adcq 8+16(%rsi,%rcx,1),%r11 + adcq $1,%r12 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + addq %rax,%r15 + adcq %rdx,%r9 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq 0+32(%rsi,%rcx,1),%r10 + adcq 8+32(%rsi,%rcx,1),%r11 + adcq $1,%r12 + + leaq 48(%rcx),%rcx + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq %rax,%r15 + adcq %rdx,%r9 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + cmpq $60*8,%rcx + jne .Lopen_avx2_main_loop_rounds + vpaddd .Lchacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + addq 0+60*8(%rsi),%r10 + adcq 8+60*8(%rsi),%r11 + adcq $1,%r12 + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + addq 0+60*8+16(%rsi),%r10 + adcq 8+60*8+16(%rsi),%r11 + adcq $1,%r12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm4 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm8 + vpxor 0+384(%rsi),%ymm3,%ymm3 + vpxor 32+384(%rsi),%ymm0,%ymm0 + vpxor 64+384(%rsi),%ymm4,%ymm4 + vpxor 96+384(%rsi),%ymm8,%ymm8 + vmovdqu %ymm3,0+384(%rdi) + vmovdqu %ymm0,32+384(%rdi) + vmovdqu %ymm4,64+384(%rdi) + vmovdqu %ymm8,96+384(%rdi) + + leaq 512(%rsi),%rsi + leaq 512(%rdi),%rdi + subq $512,%rbx + jmp .Lopen_avx2_main_loop +.Lopen_avx2_main_loop_done: + testq %rbx,%rbx + vzeroupper + je .Lopen_sse_finalize + + cmpq $384,%rbx + ja .Lopen_avx2_tail_512 + cmpq $256,%rbx + ja .Lopen_avx2_tail_384 + cmpq $128,%rbx + ja .Lopen_avx2_tail_256 + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + + xorq %r8,%r8 + movq %rbx,%rcx + andq $-16,%rcx + testq %rcx,%rcx + je .Lopen_avx2_tail_128_rounds +.Lopen_avx2_tail_128_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +.Lopen_avx2_tail_128_rounds: + addq $16,%r8 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + cmpq %rcx,%r8 + jb .Lopen_avx2_tail_128_rounds_and_x1hash + cmpq $160,%r8 + jne .Lopen_avx2_tail_128_rounds + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + jmp .Lopen_avx2_tail_128_xor + +.Lopen_avx2_tail_256: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + + movq %rbx,0+128(%rbp) + movq %rbx,%rcx + subq $128,%rcx + shrq $4,%rcx + movq $10,%r8 + cmpq $10,%rcx + cmovgq %r8,%rcx + movq %rsi,%rbx + xorq %r8,%r8 +.Lopen_avx2_tail_256_rounds_and_x1hash: + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx +.Lopen_avx2_tail_256_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + + incq %r8 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + cmpq %rcx,%r8 + jb .Lopen_avx2_tail_256_rounds_and_x1hash + cmpq $10,%r8 + jne .Lopen_avx2_tail_256_rounds + movq %rbx,%r8 + subq %rsi,%rbx + movq %rbx,%rcx + movq 0+128(%rbp),%rbx +.Lopen_avx2_tail_256_hash: + addq $16,%rcx + cmpq %rbx,%rcx + jg .Lopen_avx2_tail_256_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + jmp .Lopen_avx2_tail_256_hash +.Lopen_avx2_tail_256_done: + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm1,%ymm1 + vpxor 64+0(%rsi),%ymm5,%ymm5 + vpxor 96+0(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm1,32+0(%rdi) + vmovdqu %ymm5,64+0(%rdi) + vmovdqu %ymm9,96+0(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 128(%rsi),%rsi + leaq 128(%rdi),%rdi + subq $128,%rbx + jmp .Lopen_avx2_tail_128_xor + +.Lopen_avx2_tail_384: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + + movq %rbx,0+128(%rbp) + movq %rbx,%rcx + subq $256,%rcx + shrq $4,%rcx + addq $6,%rcx + movq $10,%r8 + cmpq $10,%rcx + cmovgq %r8,%rcx + movq %rsi,%rbx + xorq %r8,%r8 +.Lopen_avx2_tail_384_rounds_and_x2hash: + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx +.Lopen_avx2_tail_384_rounds_and_x1hash: + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx + incq %r8 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + cmpq %rcx,%r8 + jb .Lopen_avx2_tail_384_rounds_and_x2hash + cmpq $10,%r8 + jne .Lopen_avx2_tail_384_rounds_and_x1hash + movq %rbx,%r8 + subq %rsi,%rbx + movq %rbx,%rcx + movq 0+128(%rbp),%rbx +.Lopen_avx2_384_tail_hash: + addq $16,%rcx + cmpq %rbx,%rcx + jg .Lopen_avx2_384_tail_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + jmp .Lopen_avx2_384_tail_hash +.Lopen_avx2_384_tail_done: + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm2,%ymm2 + vpxor 64+0(%rsi),%ymm6,%ymm6 + vpxor 96+0(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm2,32+0(%rdi) + vmovdqu %ymm6,64+0(%rdi) + vmovdqu %ymm10,96+0(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm1,%ymm1 + vpxor 64+128(%rsi),%ymm5,%ymm5 + vpxor 96+128(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm1,32+128(%rdi) + vmovdqu %ymm5,64+128(%rdi) + vmovdqu %ymm9,96+128(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 256(%rsi),%rsi + leaq 256(%rdi),%rdi + subq $256,%rbx + jmp .Lopen_avx2_tail_128_xor + +.Lopen_avx2_tail_512: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + xorq %rcx,%rcx + movq %rsi,%r8 +.Lopen_avx2_tail_512_rounds_and_x2hash: + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 +.Lopen_avx2_tail_512_rounds_and_x1hash: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + addq 0+16(%r8),%r10 + adcq 8+16(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%r8),%r8 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + incq %rcx + cmpq $4,%rcx + jl .Lopen_avx2_tail_512_rounds_and_x2hash + cmpq $10,%rcx + jne .Lopen_avx2_tail_512_rounds_and_x1hash + movq %rbx,%rcx + subq $384,%rcx + andq $-16,%rcx +.Lopen_avx2_tail_512_hash: + testq %rcx,%rcx + je .Lopen_avx2_tail_512_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + subq $16,%rcx + jmp .Lopen_avx2_tail_512_hash +.Lopen_avx2_tail_512_done: + vpaddd .Lchacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 384(%rsi),%rsi + leaq 384(%rdi),%rdi + subq $384,%rbx +.Lopen_avx2_tail_128_xor: + cmpq $32,%rbx + jb .Lopen_avx2_tail_32_xor + subq $32,%rbx + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + leaq 32(%rdi),%rdi + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + jmp .Lopen_avx2_tail_128_xor +.Lopen_avx2_tail_32_xor: + cmpq $16,%rbx + vmovdqa %xmm0,%xmm1 + jb .Lopen_avx2_exit + subq $16,%rbx + + vpxor (%rsi),%xmm0,%xmm1 + vmovdqu %xmm1,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + vperm2i128 $0x11,%ymm0,%ymm0,%ymm0 + vmovdqa %xmm0,%xmm1 +.Lopen_avx2_exit: + vzeroupper + jmp .Lopen_sse_tail_16 + +.Lopen_avx2_192: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd .Lavx2_inc(%rip),%ymm12,%ymm13 + vmovdqa %ymm12,%ymm11 + vmovdqa %ymm13,%ymm15 + movq $10,%r10 +.Lopen_avx2_192_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + + decq %r10 + jne .Lopen_avx2_192_rounds + vpaddd %ymm2,%ymm0,%ymm0 + vpaddd %ymm2,%ymm1,%ymm1 + vpaddd %ymm6,%ymm4,%ymm4 + vpaddd %ymm6,%ymm5,%ymm5 + vpaddd %ymm10,%ymm8,%ymm8 + vpaddd %ymm10,%ymm9,%ymm9 + vpaddd %ymm11,%ymm12,%ymm12 + vpaddd %ymm15,%ymm13,%ymm13 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand .Lclamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 +.Lopen_avx2_short: + movq %r8,%r8 + call poly_hash_ad_internal +.Lopen_avx2_short_hash_and_xor_loop: + cmpq $32,%rbx + jb .Lopen_avx2_short_tail_32 + subq $32,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rsi),%r10 + adcq 8+16(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + leaq 32(%rdi),%rdi + + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + vmovdqa %ymm1,%ymm12 + vmovdqa %ymm5,%ymm1 + vmovdqa %ymm9,%ymm5 + vmovdqa %ymm13,%ymm9 + vmovdqa %ymm2,%ymm13 + vmovdqa %ymm6,%ymm2 + jmp .Lopen_avx2_short_hash_and_xor_loop +.Lopen_avx2_short_tail_32: + cmpq $16,%rbx + vmovdqa %xmm0,%xmm1 + jb .Lopen_avx2_short_tail_32_exit + subq $16,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + vpxor (%rsi),%xmm0,%xmm3 + vmovdqu %xmm3,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + vextracti128 $1,%ymm0,%xmm1 +.Lopen_avx2_short_tail_32_exit: + vzeroupper + jmp .Lopen_sse_tail_16 + +.Lopen_avx2_320: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd .Lavx2_inc(%rip),%ymm12,%ymm13 + vpaddd .Lavx2_inc(%rip),%ymm13,%ymm14 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + movq $10,%r10 +.Lopen_avx2_320_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + decq %r10 + jne .Lopen_avx2_320_rounds + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd %ymm7,%ymm4,%ymm4 + vpaddd %ymm7,%ymm5,%ymm5 + vpaddd %ymm7,%ymm6,%ymm6 + vpaddd %ymm11,%ymm8,%ymm8 + vpaddd %ymm11,%ymm9,%ymm9 + vpaddd %ymm11,%ymm10,%ymm10 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand .Lclamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm9 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm13 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm6 + jmp .Lopen_avx2_short +.size chacha20_poly1305_open_avx2, .-chacha20_poly1305_open_avx2 +.cfi_endproc + + +.type chacha20_poly1305_seal_avx2,@function +.align 64 +chacha20_poly1305_seal_avx2: +.cfi_startproc + + +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r9,-64 +.cfi_adjust_cfa_offset 288 + 32 + + vzeroupper + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vbroadcasti128 0(%r9),%ymm4 + vbroadcasti128 16(%r9),%ymm8 + vbroadcasti128 32(%r9),%ymm12 + vpaddd .Lavx2_init(%rip),%ymm12,%ymm12 + cmpq $192,%rbx + jbe .Lseal_avx2_192 + cmpq $320,%rbx + jbe .Lseal_avx2_320 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm4,0+64(%rbp) + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm8,0+96(%rbp) + vmovdqa %ymm12,%ymm15 + vpaddd .Lavx2_inc(%rip),%ymm15,%ymm14 + vpaddd .Lavx2_inc(%rip),%ymm14,%ymm13 + vpaddd .Lavx2_inc(%rip),%ymm13,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm15,0+256(%rbp) + movq $10,%r10 +.Lseal_avx2_init_rounds: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + decq %r10 + jnz .Lseal_avx2_init_rounds + vpaddd .Lchacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vperm2i128 $0x02,%ymm3,%ymm7,%ymm15 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm3 + vpand .Lclamp(%rip),%ymm15,%ymm15 + vmovdqa %ymm15,0+0(%rbp) + movq %r8,%r8 + call poly_hash_ad_internal + + vpxor 0(%rsi),%ymm3,%ymm3 + vpxor 32(%rsi),%ymm11,%ymm11 + vmovdqu %ymm3,0(%rdi) + vmovdqu %ymm11,32(%rdi) + vperm2i128 $0x02,%ymm2,%ymm6,%ymm15 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+64(%rsi),%ymm15,%ymm15 + vpxor 32+64(%rsi),%ymm2,%ymm2 + vpxor 64+64(%rsi),%ymm6,%ymm6 + vpxor 96+64(%rsi),%ymm10,%ymm10 + vmovdqu %ymm15,0+64(%rdi) + vmovdqu %ymm2,32+64(%rdi) + vmovdqu %ymm6,64+64(%rdi) + vmovdqu %ymm10,96+64(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm15 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+192(%rsi),%ymm15,%ymm15 + vpxor 32+192(%rsi),%ymm1,%ymm1 + vpxor 64+192(%rsi),%ymm5,%ymm5 + vpxor 96+192(%rsi),%ymm9,%ymm9 + vmovdqu %ymm15,0+192(%rdi) + vmovdqu %ymm1,32+192(%rdi) + vmovdqu %ymm5,64+192(%rdi) + vmovdqu %ymm9,96+192(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm15 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm15,%ymm8 + + leaq 320(%rsi),%rsi + subq $320,%rbx + movq $320,%rcx + cmpq $128,%rbx + jbe .Lseal_avx2_short_hash_remainder + vpxor 0(%rsi),%ymm0,%ymm0 + vpxor 32(%rsi),%ymm4,%ymm4 + vpxor 64(%rsi),%ymm8,%ymm8 + vpxor 96(%rsi),%ymm12,%ymm12 + vmovdqu %ymm0,320(%rdi) + vmovdqu %ymm4,352(%rdi) + vmovdqu %ymm8,384(%rdi) + vmovdqu %ymm12,416(%rdi) + leaq 128(%rsi),%rsi + subq $128,%rbx + movq $8,%rcx + movq $2,%r8 + cmpq $128,%rbx + jbe .Lseal_avx2_tail_128 + cmpq $256,%rbx + jbe .Lseal_avx2_tail_256 + cmpq $384,%rbx + jbe .Lseal_avx2_tail_384 + cmpq $512,%rbx + jbe .Lseal_avx2_tail_512 + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + + subq $16,%rdi + movq $9,%rcx + jmp .Lseal_avx2_main_loop_rounds_entry +.align 32 +.Lseal_avx2_main_loop: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + movq $10,%rcx +.align 32 +.Lseal_avx2_main_loop_rounds: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + addq %rax,%r15 + adcq %rdx,%r9 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +.Lseal_avx2_main_loop_rounds_entry: + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + addq %rax,%r15 + adcq %rdx,%r9 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq 0+32(%rdi),%r10 + adcq 8+32(%rdi),%r11 + adcq $1,%r12 + + leaq 48(%rdi),%rdi + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq %rax,%r15 + adcq %rdx,%r9 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + decq %rcx + jne .Lseal_avx2_main_loop_rounds + vpaddd .Lchacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm4 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm8 + vpxor 0+384(%rsi),%ymm3,%ymm3 + vpxor 32+384(%rsi),%ymm0,%ymm0 + vpxor 64+384(%rsi),%ymm4,%ymm4 + vpxor 96+384(%rsi),%ymm8,%ymm8 + vmovdqu %ymm3,0+384(%rdi) + vmovdqu %ymm0,32+384(%rdi) + vmovdqu %ymm4,64+384(%rdi) + vmovdqu %ymm8,96+384(%rdi) + + leaq 512(%rsi),%rsi + subq $512,%rbx + cmpq $512,%rbx + jg .Lseal_avx2_main_loop + + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + movq $10,%rcx + xorq %r8,%r8 + + cmpq $384,%rbx + ja .Lseal_avx2_tail_512 + cmpq $256,%rbx + ja .Lseal_avx2_tail_384 + cmpq $128,%rbx + ja .Lseal_avx2_tail_256 + +.Lseal_avx2_tail_128: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + +.Lseal_avx2_tail_128_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_avx2_tail_128_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg .Lseal_avx2_tail_128_rounds_and_3xhash + decq %r8 + jge .Lseal_avx2_tail_128_rounds_and_2xhash + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + jmp .Lseal_avx2_short_loop + +.Lseal_avx2_tail_256: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + +.Lseal_avx2_tail_256_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_avx2_tail_256_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg .Lseal_avx2_tail_256_rounds_and_3xhash + decq %r8 + jge .Lseal_avx2_tail_256_rounds_and_2xhash + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm1,%ymm1 + vpxor 64+0(%rsi),%ymm5,%ymm5 + vpxor 96+0(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm1,32+0(%rdi) + vmovdqu %ymm5,64+0(%rdi) + vmovdqu %ymm9,96+0(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $128,%rcx + leaq 128(%rsi),%rsi + subq $128,%rbx + jmp .Lseal_avx2_short_hash_remainder + +.Lseal_avx2_tail_384: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + +.Lseal_avx2_tail_384_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_avx2_tail_384_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + leaq 32(%rdi),%rdi + decq %rcx + jg .Lseal_avx2_tail_384_rounds_and_3xhash + decq %r8 + jge .Lseal_avx2_tail_384_rounds_and_2xhash + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm2,%ymm2 + vpxor 64+0(%rsi),%ymm6,%ymm6 + vpxor 96+0(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm2,32+0(%rdi) + vmovdqu %ymm6,64+0(%rdi) + vmovdqu %ymm10,96+0(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm1,%ymm1 + vpxor 64+128(%rsi),%ymm5,%ymm5 + vpxor 96+128(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm1,32+128(%rdi) + vmovdqu %ymm5,64+128(%rdi) + vmovdqu %ymm9,96+128(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $256,%rcx + leaq 256(%rsi),%rsi + subq $256,%rbx + jmp .Lseal_avx2_short_hash_remainder + +.Lseal_avx2_tail_512: + vmovdqa .Lchacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa .Lavx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + +.Lseal_avx2_tail_512_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +.Lseal_avx2_tail_512_rounds_and_2xhash: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq %rax,%r15 + adcq %rdx,%r9 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa .Lrol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa .Lrol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + + + + + + + + + + + + + + + + addq %rax,%r15 + adcq %rdx,%r9 + + + + + + + + + + + + + + + + + + + + + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg .Lseal_avx2_tail_512_rounds_and_3xhash + decq %r8 + jge .Lseal_avx2_tail_512_rounds_and_2xhash + vpaddd .Lchacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $384,%rcx + leaq 384(%rsi),%rsi + subq $384,%rbx + jmp .Lseal_avx2_short_hash_remainder + +.Lseal_avx2_320: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd .Lavx2_inc(%rip),%ymm12,%ymm13 + vpaddd .Lavx2_inc(%rip),%ymm13,%ymm14 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + movq $10,%r10 +.Lseal_avx2_320_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb .Lrol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + decq %r10 + jne .Lseal_avx2_320_rounds + vpaddd .Lchacha20_consts(%rip),%ymm0,%ymm0 + vpaddd .Lchacha20_consts(%rip),%ymm1,%ymm1 + vpaddd .Lchacha20_consts(%rip),%ymm2,%ymm2 + vpaddd %ymm7,%ymm4,%ymm4 + vpaddd %ymm7,%ymm5,%ymm5 + vpaddd %ymm7,%ymm6,%ymm6 + vpaddd %ymm11,%ymm8,%ymm8 + vpaddd %ymm11,%ymm9,%ymm9 + vpaddd %ymm11,%ymm10,%ymm10 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand .Lclamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm9 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm13 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm6 + jmp .Lseal_avx2_short + +.Lseal_avx2_192: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd .Lavx2_inc(%rip),%ymm12,%ymm13 + vmovdqa %ymm12,%ymm11 + vmovdqa %ymm13,%ymm15 + movq $10,%r10 +.Lseal_avx2_192_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb .Lrol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb .Lrol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + + decq %r10 + jne .Lseal_avx2_192_rounds + vpaddd %ymm2,%ymm0,%ymm0 + vpaddd %ymm2,%ymm1,%ymm1 + vpaddd %ymm6,%ymm4,%ymm4 + vpaddd %ymm6,%ymm5,%ymm5 + vpaddd %ymm10,%ymm8,%ymm8 + vpaddd %ymm10,%ymm9,%ymm9 + vpaddd %ymm11,%ymm12,%ymm12 + vpaddd %ymm15,%ymm13,%ymm13 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand .Lclamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 +.Lseal_avx2_short: + movq %r8,%r8 + call poly_hash_ad_internal + xorq %rcx,%rcx +.Lseal_avx2_short_hash_remainder: + cmpq $16,%rcx + jb .Lseal_avx2_short_loop + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx + addq $16,%rdi + jmp .Lseal_avx2_short_hash_remainder +.Lseal_avx2_short_loop: + cmpq $32,%rbx + jb .Lseal_avx2_short_tail + subq $32,%rbx + + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + vmovdqa %ymm1,%ymm12 + vmovdqa %ymm5,%ymm1 + vmovdqa %ymm9,%ymm5 + vmovdqa %ymm13,%ymm9 + vmovdqa %ymm2,%ymm13 + vmovdqa %ymm6,%ymm2 + jmp .Lseal_avx2_short_loop +.Lseal_avx2_short_tail: + cmpq $16,%rbx + jb .Lseal_avx2_exit + subq $16,%rbx + vpxor (%rsi),%xmm0,%xmm3 + vmovdqu %xmm3,(%rdi) + leaq 16(%rsi),%rsi + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + vextracti128 $1,%ymm0,%xmm0 +.Lseal_avx2_exit: + vzeroupper + jmp .Lseal_sse_tail_16 +.cfi_endproc +.size chacha20_poly1305_seal_avx2, .-chacha20_poly1305_seal_avx2 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S new file mode 100644 index 00000000..e8b57901 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S @@ -0,0 +1,8885 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +chacha20_poly1305_constants: + +.p2align 6 +L$chacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +L$rol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +L$rol16: +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +L$avx2_init: +.long 0,0,0,0 +L$sse_inc: +.long 1,0,0,0 +L$avx2_inc: +.long 2,0,0,0,2,0,0,0 +L$clamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC +.quad 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +.p2align 4 +L$and_masks: +.byte 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + + +.p2align 6 +poly_hash_ad_internal: + + + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + cmpq $13,%r8 + jne L$hash_ad_loop +L$poly_fast_tls_ad: + + movq (%rcx),%r10 + movq 5(%rcx),%r11 + shrq $24,%r11 + movq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + .byte 0xf3,0xc3 +L$hash_ad_loop: + + cmpq $16,%r8 + jb L$hash_ad_tail + addq 0+0(%rcx),%r10 + adcq 8+0(%rcx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rcx),%rcx + subq $16,%r8 + jmp L$hash_ad_loop +L$hash_ad_tail: + cmpq $0,%r8 + je L$hash_ad_done + + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + addq %r8,%rcx +L$hash_ad_tail_loop: + shldq $8,%r13,%r14 + shlq $8,%r13 + movzbq -1(%rcx),%r15 + xorq %r15,%r13 + decq %rcx + decq %r8 + jne L$hash_ad_tail_loop + + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +L$hash_ad_done: + .byte 0xf3,0xc3 + + + +.globl _chacha20_poly1305_open +.private_extern _chacha20_poly1305_open + +.p2align 6 +_chacha20_poly1305_open: + + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + + + pushq %r9 + + subq $288 + 0 + 32,%rsp + + + leaq 32(%rsp),%rbp + andq $-32,%rbp + + movq %rdx,%rbx + movq %r8,0+0+32(%rbp) + movq %rbx,8+0+32(%rbp) + + movl _OPENSSL_ia32cap_P+8(%rip),%eax + andl $288,%eax + xorl $288,%eax + jz chacha20_poly1305_open_avx2 + + cmpq $128,%rbx + jbe L$open_sse_128 + + movdqa L$chacha20_consts(%rip),%xmm0 + movdqu 0(%r9),%xmm4 + movdqu 16(%r9),%xmm8 + movdqu 32(%r9),%xmm12 + + movdqa %xmm12,%xmm7 + + movdqa %xmm4,0+48(%rbp) + movdqa %xmm8,0+64(%rbp) + movdqa %xmm12,0+96(%rbp) + movq $10,%r10 +L$open_sse_init_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %r10 + jne L$open_sse_init_rounds + + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + + pand L$clamp(%rip),%xmm0 + movdqa %xmm0,0+0(%rbp) + movdqa %xmm4,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal +L$open_sse_main_loop: + cmpq $256,%rbx + jb L$open_sse_tail + + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd L$sse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + + + + movq $4,%rcx + movq %rsi,%r8 +L$open_sse_main_loop_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + + leaq 16(%r8),%r8 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %rcx + jge L$open_sse_main_loop_rounds + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + cmpq $-6,%rcx + jg L$open_sse_main_loop_rounds + paddd L$chacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqa %xmm12,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm12 + pxor %xmm3,%xmm12 + movdqu %xmm12,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm12 + pxor %xmm7,%xmm12 + movdqu %xmm12,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm12 + pxor %xmm11,%xmm12 + movdqu %xmm12,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm12 + pxor %xmm15,%xmm12 + movdqu %xmm12,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + movdqu 0 + 192(%rsi),%xmm3 + movdqu 16 + 192(%rsi),%xmm7 + movdqu 32 + 192(%rsi),%xmm11 + movdqu 48 + 192(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor 0+80(%rbp),%xmm15 + movdqu %xmm0,0 + 192(%rdi) + movdqu %xmm4,16 + 192(%rdi) + movdqu %xmm8,32 + 192(%rdi) + movdqu %xmm15,48 + 192(%rdi) + + leaq 256(%rsi),%rsi + leaq 256(%rdi),%rdi + subq $256,%rbx + jmp L$open_sse_main_loop +L$open_sse_tail: + + testq %rbx,%rbx + jz L$open_sse_finalize + cmpq $192,%rbx + ja L$open_sse_tail_256 + cmpq $128,%rbx + ja L$open_sse_tail_192 + cmpq $64,%rbx + ja L$open_sse_tail_128 + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa 0+96(%rbp),%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + + xorq %r8,%r8 + movq %rbx,%rcx + cmpq $16,%rcx + jb L$open_sse_tail_64_rounds +L$open_sse_tail_64_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx +L$open_sse_tail_64_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + cmpq $16,%rcx + jae L$open_sse_tail_64_rounds_and_x1hash + cmpq $160,%r8 + jne L$open_sse_tail_64_rounds + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + jmp L$open_sse_tail_64_dec_loop + +L$open_sse_tail_128: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa 0+96(%rbp),%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + + movq %rbx,%rcx + andq $-16,%rcx + xorq %r8,%r8 +L$open_sse_tail_128_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +L$open_sse_tail_128_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + + cmpq %rcx,%r8 + jb L$open_sse_tail_128_rounds_and_x1hash + cmpq $160,%r8 + jne L$open_sse_tail_128_rounds + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 0(%rdi) + movdqu %xmm5,16 + 0(%rdi) + movdqu %xmm9,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + + subq $64,%rbx + leaq 64(%rsi),%rsi + leaq 64(%rdi),%rdi + jmp L$open_sse_tail_64_dec_loop + +L$open_sse_tail_192: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa 0+96(%rbp),%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + + movq %rbx,%rcx + movq $160,%r8 + cmpq $160,%rcx + cmovgq %r8,%rcx + andq $-16,%rcx + xorq %r8,%r8 +L$open_sse_tail_192_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +L$open_sse_tail_192_rounds: + addq $16,%r8 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + cmpq %rcx,%r8 + jb L$open_sse_tail_192_rounds_and_x1hash + cmpq $160,%r8 + jne L$open_sse_tail_192_rounds + cmpq $176,%rbx + jb L$open_sse_tail_192_finish + addq 0+160(%rsi),%r10 + adcq 8+160(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + cmpq $192,%rbx + jb L$open_sse_tail_192_finish + addq 0+176(%rsi),%r10 + adcq 8+176(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +L$open_sse_tail_192_finish: + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + subq $128,%rbx + leaq 128(%rsi),%rsi + leaq 128(%rdi),%rdi + jmp L$open_sse_tail_64_dec_loop + +L$open_sse_tail_256: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd L$sse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + + xorq %r8,%r8 +L$open_sse_tail_256_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movdqa %xmm11,0+80(%rbp) + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm4 + pxor %xmm11,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm4 + pxor %xmm11,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm5 + pxor %xmm11,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm5 + pxor %xmm11,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm6 + pxor %xmm11,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm6 + pxor %xmm11,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + movdqa 0+80(%rbp),%xmm11 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa %xmm9,0+80(%rbp) + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb L$rol16(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $12,%xmm9 + psrld $20,%xmm7 + pxor %xmm9,%xmm7 + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb L$rol8(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $7,%xmm9 + psrld $25,%xmm7 + pxor %xmm9,%xmm7 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 + movdqa 0+80(%rbp),%xmm9 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + movdqa %xmm11,0+80(%rbp) + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm4 + pxor %xmm11,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm4 + pxor %xmm11,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm5 + pxor %xmm11,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm5 + pxor %xmm11,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $12,%xmm11 + psrld $20,%xmm6 + pxor %xmm11,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm11 + pslld $7,%xmm11 + psrld $25,%xmm6 + pxor %xmm11,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + movdqa 0+80(%rbp),%xmm11 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + movdqa %xmm9,0+80(%rbp) + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb L$rol16(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $12,%xmm9 + psrld $20,%xmm7 + pxor %xmm9,%xmm7 + paddd %xmm7,%xmm3 + pxor %xmm3,%xmm15 + pshufb L$rol8(%rip),%xmm15 + paddd %xmm15,%xmm11 + pxor %xmm11,%xmm7 + movdqa %xmm7,%xmm9 + pslld $7,%xmm9 + psrld $25,%xmm7 + pxor %xmm9,%xmm7 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 + movdqa 0+80(%rbp),%xmm9 + + addq $16,%r8 + cmpq $160,%r8 + jb L$open_sse_tail_256_rounds_and_x1hash + + movq %rbx,%rcx + andq $-16,%rcx +L$open_sse_tail_256_hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + addq $16,%r8 + cmpq %rcx,%r8 + jb L$open_sse_tail_256_hash + paddd L$chacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqa %xmm12,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm12 + pxor %xmm3,%xmm12 + movdqu %xmm12,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm12 + pxor %xmm7,%xmm12 + movdqu %xmm12,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm12 + pxor %xmm11,%xmm12 + movdqu %xmm12,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm12 + pxor %xmm15,%xmm12 + movdqu %xmm12,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + movdqa 0+80(%rbp),%xmm12 + subq $192,%rbx + leaq 192(%rsi),%rsi + leaq 192(%rdi),%rdi + + +L$open_sse_tail_64_dec_loop: + cmpq $16,%rbx + jb L$open_sse_tail_16_init + subq $16,%rbx + movdqu (%rsi),%xmm3 + pxor %xmm3,%xmm0 + movdqu %xmm0,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movdqa %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + jmp L$open_sse_tail_64_dec_loop +L$open_sse_tail_16_init: + movdqa %xmm0,%xmm1 + + +L$open_sse_tail_16: + testq %rbx,%rbx + jz L$open_sse_finalize + + + + pxor %xmm3,%xmm3 + leaq -1(%rsi,%rbx,1),%rsi + movq %rbx,%r8 +L$open_sse_tail_16_compose: + pslldq $1,%xmm3 + pinsrb $0,(%rsi),%xmm3 + subq $1,%rsi + subq $1,%r8 + jnz L$open_sse_tail_16_compose + +.byte 102,73,15,126,221 + pextrq $1,%xmm3,%r14 + + pxor %xmm1,%xmm3 + + +L$open_sse_tail_16_extract: + pextrb $0,%xmm3,(%rdi) + psrldq $1,%xmm3 + addq $1,%rdi + subq $1,%rbx + jne L$open_sse_tail_16_extract + + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +L$open_sse_finalize: + addq 0+0+32(%rbp),%r10 + adcq 8+0+32(%rbp),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movq %r10,%r13 + movq %r11,%r14 + movq %r12,%r15 + subq $-5,%r10 + sbbq $-1,%r11 + sbbq $3,%r12 + cmovcq %r13,%r10 + cmovcq %r14,%r11 + cmovcq %r15,%r12 + + addq 0+0+16(%rbp),%r10 + adcq 8+0+16(%rbp),%r11 + + + addq $288 + 0 + 32,%rsp + + + popq %r9 + + movq %r10,(%r9) + movq %r11,8(%r9) + popq %r15 + + popq %r14 + + popq %r13 + + popq %r12 + + popq %rbx + + popq %rbp + + .byte 0xf3,0xc3 + +L$open_sse_128: + + movdqu L$chacha20_consts(%rip),%xmm0 + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqu 0(%r9),%xmm4 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqu 16(%r9),%xmm8 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqu 32(%r9),%xmm12 + movdqa %xmm12,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa %xmm13,%xmm15 + movq $10,%r10 + +L$open_sse_128_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + decq %r10 + jnz L$open_sse_128_rounds + paddd L$chacha20_consts(%rip),%xmm0 + paddd L$chacha20_consts(%rip),%xmm1 + paddd L$chacha20_consts(%rip),%xmm2 + paddd %xmm7,%xmm4 + paddd %xmm7,%xmm5 + paddd %xmm7,%xmm6 + paddd %xmm11,%xmm9 + paddd %xmm11,%xmm10 + paddd %xmm15,%xmm13 + paddd L$sse_inc(%rip),%xmm15 + paddd %xmm15,%xmm14 + + pand L$clamp(%rip),%xmm0 + movdqa %xmm0,0+0(%rbp) + movdqa %xmm4,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal +L$open_sse_128_xor_hash: + cmpq $16,%rbx + jb L$open_sse_tail_16 + subq $16,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + + + movdqu 0(%rsi),%xmm3 + pxor %xmm3,%xmm1 + movdqu %xmm1,0(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movdqa %xmm5,%xmm1 + movdqa %xmm9,%xmm5 + movdqa %xmm13,%xmm9 + movdqa %xmm2,%xmm13 + movdqa %xmm6,%xmm2 + movdqa %xmm10,%xmm6 + movdqa %xmm14,%xmm10 + jmp L$open_sse_128_xor_hash + + + + + + + + + +.globl _chacha20_poly1305_seal +.private_extern _chacha20_poly1305_seal + +.p2align 6 +_chacha20_poly1305_seal: + + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + + + pushq %r9 + + subq $288 + 0 + 32,%rsp + + leaq 32(%rsp),%rbp + andq $-32,%rbp + + movq 56(%r9),%rbx + addq %rdx,%rbx + movq %r8,0+0+32(%rbp) + movq %rbx,8+0+32(%rbp) + movq %rdx,%rbx + + movl _OPENSSL_ia32cap_P+8(%rip),%eax + andl $288,%eax + xorl $288,%eax + jz chacha20_poly1305_seal_avx2 + + cmpq $128,%rbx + jbe L$seal_sse_128 + + movdqa L$chacha20_consts(%rip),%xmm0 + movdqu 0(%r9),%xmm4 + movdqu 16(%r9),%xmm8 + movdqu 32(%r9),%xmm12 + + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqa %xmm8,%xmm11 + movdqa %xmm12,%xmm15 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm14 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm13 + paddd L$sse_inc(%rip),%xmm12 + + movdqa %xmm4,0+48(%rbp) + movdqa %xmm8,0+64(%rbp) + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + movq $10,%r10 +L$seal_sse_init_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + decq %r10 + jnz L$seal_sse_init_rounds + paddd L$chacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + + pand L$clamp(%rip),%xmm3 + movdqa %xmm3,0+0(%rbp) + movdqa %xmm7,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + cmpq $192,%rbx + ja L$seal_sse_main_init + movq $128,%rcx + subq $128,%rbx + leaq 128(%rsi),%rsi + jmp L$seal_sse_128_tail_hash +L$seal_sse_main_init: + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor %xmm12,%xmm15 + movdqu %xmm0,0 + 128(%rdi) + movdqu %xmm4,16 + 128(%rdi) + movdqu %xmm8,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + movq $192,%rcx + subq $192,%rbx + leaq 192(%rsi),%rsi + movq $2,%rcx + movq $8,%r8 + cmpq $64,%rbx + jbe L$seal_sse_tail_64 + cmpq $128,%rbx + jbe L$seal_sse_tail_128 + cmpq $192,%rbx + jbe L$seal_sse_tail_192 + +L$seal_sse_main_loop: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa %xmm0,%xmm3 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa 0+96(%rbp),%xmm15 + paddd L$sse_inc(%rip),%xmm15 + movdqa %xmm15,%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + movdqa %xmm15,0+144(%rbp) + +.p2align 5 +L$seal_sse_main_rounds: + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 +.byte 102,15,58,15,255,4 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,12 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + movdqa %xmm8,0+80(%rbp) + movdqa L$rol16(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $20,%xmm8 + pslld $32-20,%xmm4 + pxor %xmm8,%xmm4 + movdqa L$rol8(%rip),%xmm8 + paddd %xmm7,%xmm3 + paddd %xmm6,%xmm2 + paddd %xmm5,%xmm1 + paddd %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pxor %xmm2,%xmm14 + pxor %xmm1,%xmm13 + pxor %xmm0,%xmm12 +.byte 102,69,15,56,0,248 +.byte 102,69,15,56,0,240 +.byte 102,69,15,56,0,232 +.byte 102,69,15,56,0,224 + movdqa 0+80(%rbp),%xmm8 + paddd %xmm15,%xmm11 + paddd %xmm14,%xmm10 + paddd %xmm13,%xmm9 + paddd %xmm12,%xmm8 + pxor %xmm11,%xmm7 + pxor %xmm10,%xmm6 + pxor %xmm9,%xmm5 + pxor %xmm8,%xmm4 + movdqa %xmm8,0+80(%rbp) + movdqa %xmm7,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm7 + pxor %xmm8,%xmm7 + movdqa %xmm6,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm6 + pxor %xmm8,%xmm6 + movdqa %xmm5,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm5 + pxor %xmm8,%xmm5 + movdqa %xmm4,%xmm8 + psrld $25,%xmm8 + pslld $32-25,%xmm4 + pxor %xmm8,%xmm4 + movdqa 0+80(%rbp),%xmm8 +.byte 102,15,58,15,255,12 +.byte 102,69,15,58,15,219,8 +.byte 102,69,15,58,15,255,4 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + + leaq 16(%rdi),%rdi + decq %r8 + jge L$seal_sse_main_rounds + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + decq %rcx + jg L$seal_sse_main_rounds + paddd L$chacha20_consts(%rip),%xmm3 + paddd 0+48(%rbp),%xmm7 + paddd 0+64(%rbp),%xmm11 + paddd 0+144(%rbp),%xmm15 + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + movdqa %xmm14,0+80(%rbp) + movdqa %xmm14,0+80(%rbp) + movdqu 0 + 0(%rsi),%xmm14 + pxor %xmm3,%xmm14 + movdqu %xmm14,0 + 0(%rdi) + movdqu 16 + 0(%rsi),%xmm14 + pxor %xmm7,%xmm14 + movdqu %xmm14,16 + 0(%rdi) + movdqu 32 + 0(%rsi),%xmm14 + pxor %xmm11,%xmm14 + movdqu %xmm14,32 + 0(%rdi) + movdqu 48 + 0(%rsi),%xmm14 + pxor %xmm15,%xmm14 + movdqu %xmm14,48 + 0(%rdi) + + movdqa 0+80(%rbp),%xmm14 + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 64(%rdi) + movdqu %xmm6,16 + 64(%rdi) + movdqu %xmm10,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + movdqu 0 + 128(%rsi),%xmm3 + movdqu 16 + 128(%rsi),%xmm7 + movdqu 32 + 128(%rsi),%xmm11 + movdqu 48 + 128(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 128(%rdi) + movdqu %xmm5,16 + 128(%rdi) + movdqu %xmm9,32 + 128(%rdi) + movdqu %xmm15,48 + 128(%rdi) + + cmpq $256,%rbx + ja L$seal_sse_main_loop_xor + + movq $192,%rcx + subq $192,%rbx + leaq 192(%rsi),%rsi + jmp L$seal_sse_128_tail_hash +L$seal_sse_main_loop_xor: + movdqu 0 + 192(%rsi),%xmm3 + movdqu 16 + 192(%rsi),%xmm7 + movdqu 32 + 192(%rsi),%xmm11 + movdqu 48 + 192(%rsi),%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm7,%xmm4 + pxor %xmm11,%xmm8 + pxor %xmm12,%xmm15 + movdqu %xmm0,0 + 192(%rdi) + movdqu %xmm4,16 + 192(%rdi) + movdqu %xmm8,32 + 192(%rdi) + movdqu %xmm15,48 + 192(%rdi) + + leaq 256(%rsi),%rsi + subq $256,%rbx + movq $6,%rcx + movq $4,%r8 + cmpq $192,%rbx + jg L$seal_sse_main_loop + movq %rbx,%rcx + testq %rbx,%rbx + je L$seal_sse_128_tail_hash + movq $6,%rcx + cmpq $128,%rbx + ja L$seal_sse_tail_192 + cmpq $64,%rbx + ja L$seal_sse_tail_128 + +L$seal_sse_tail_64: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa 0+96(%rbp),%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + +L$seal_sse_tail_64_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_sse_tail_64_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + decq %rcx + jg L$seal_sse_tail_64_rounds_and_x2hash + decq %r8 + jge L$seal_sse_tail_64_rounds_and_x1hash + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + + jmp L$seal_sse_128_tail_xor + +L$seal_sse_tail_128: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa 0+96(%rbp),%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + +L$seal_sse_tail_128_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_sse_tail_128_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + + leaq 16(%rdi),%rdi + decq %rcx + jg L$seal_sse_tail_128_rounds_and_x2hash + decq %r8 + jge L$seal_sse_tail_128_rounds_and_x1hash + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 0(%rdi) + movdqu %xmm5,16 + 0(%rdi) + movdqu %xmm9,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + + movq $64,%rcx + subq $64,%rbx + leaq 64(%rsi),%rsi + jmp L$seal_sse_128_tail_hash + +L$seal_sse_tail_192: + movdqa L$chacha20_consts(%rip),%xmm0 + movdqa 0+48(%rbp),%xmm4 + movdqa 0+64(%rbp),%xmm8 + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm5 + movdqa %xmm8,%xmm9 + movdqa %xmm0,%xmm2 + movdqa %xmm4,%xmm6 + movdqa %xmm8,%xmm10 + movdqa 0+96(%rbp),%xmm14 + paddd L$sse_inc(%rip),%xmm14 + movdqa %xmm14,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm13,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,0+96(%rbp) + movdqa %xmm13,0+112(%rbp) + movdqa %xmm14,0+128(%rbp) + +L$seal_sse_tail_192_rounds_and_x2hash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_sse_tail_192_rounds_and_x1hash: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + leaq 16(%rdi),%rdi + decq %rcx + jg L$seal_sse_tail_192_rounds_and_x2hash + decq %r8 + jge L$seal_sse_tail_192_rounds_and_x1hash + paddd L$chacha20_consts(%rip),%xmm2 + paddd 0+48(%rbp),%xmm6 + paddd 0+64(%rbp),%xmm10 + paddd 0+128(%rbp),%xmm14 + paddd L$chacha20_consts(%rip),%xmm1 + paddd 0+48(%rbp),%xmm5 + paddd 0+64(%rbp),%xmm9 + paddd 0+112(%rbp),%xmm13 + paddd L$chacha20_consts(%rip),%xmm0 + paddd 0+48(%rbp),%xmm4 + paddd 0+64(%rbp),%xmm8 + paddd 0+96(%rbp),%xmm12 + movdqu 0 + 0(%rsi),%xmm3 + movdqu 16 + 0(%rsi),%xmm7 + movdqu 32 + 0(%rsi),%xmm11 + movdqu 48 + 0(%rsi),%xmm15 + pxor %xmm3,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm11,%xmm10 + pxor %xmm14,%xmm15 + movdqu %xmm2,0 + 0(%rdi) + movdqu %xmm6,16 + 0(%rdi) + movdqu %xmm10,32 + 0(%rdi) + movdqu %xmm15,48 + 0(%rdi) + movdqu 0 + 64(%rsi),%xmm3 + movdqu 16 + 64(%rsi),%xmm7 + movdqu 32 + 64(%rsi),%xmm11 + movdqu 48 + 64(%rsi),%xmm15 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm5 + pxor %xmm11,%xmm9 + pxor %xmm13,%xmm15 + movdqu %xmm1,0 + 64(%rdi) + movdqu %xmm5,16 + 64(%rdi) + movdqu %xmm9,32 + 64(%rdi) + movdqu %xmm15,48 + 64(%rdi) + + movq $128,%rcx + subq $128,%rbx + leaq 128(%rsi),%rsi + +L$seal_sse_128_tail_hash: + cmpq $16,%rcx + jb L$seal_sse_128_tail_xor + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx + leaq 16(%rdi),%rdi + jmp L$seal_sse_128_tail_hash + +L$seal_sse_128_tail_xor: + cmpq $16,%rbx + jb L$seal_sse_tail_16 + subq $16,%rbx + + movdqu 0(%rsi),%xmm3 + pxor %xmm3,%xmm0 + movdqu %xmm0,0(%rdi) + + addq 0(%rdi),%r10 + adcq 8(%rdi),%r11 + adcq $1,%r12 + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movdqa %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + movdqa %xmm1,%xmm12 + movdqa %xmm5,%xmm1 + movdqa %xmm9,%xmm5 + movdqa %xmm13,%xmm9 + jmp L$seal_sse_128_tail_xor + +L$seal_sse_tail_16: + testq %rbx,%rbx + jz L$process_blocks_of_extra_in + + movq %rbx,%r8 + movq %rbx,%rcx + leaq -1(%rsi,%rbx,1),%rsi + pxor %xmm15,%xmm15 +L$seal_sse_tail_16_compose: + pslldq $1,%xmm15 + pinsrb $0,(%rsi),%xmm15 + leaq -1(%rsi),%rsi + decq %rcx + jne L$seal_sse_tail_16_compose + + + pxor %xmm0,%xmm15 + + + movq %rbx,%rcx + movdqu %xmm15,%xmm0 +L$seal_sse_tail_16_extract: + pextrb $0,%xmm0,(%rdi) + psrldq $1,%xmm0 + addq $1,%rdi + subq $1,%rcx + jnz L$seal_sse_tail_16_extract + + + + + + + + + movq 288 + 0 + 32(%rsp),%r9 + movq 56(%r9),%r14 + movq 48(%r9),%r13 + testq %r14,%r14 + jz L$process_partial_block + + movq $16,%r15 + subq %rbx,%r15 + cmpq %r15,%r14 + + jge L$load_extra_in + movq %r14,%r15 + +L$load_extra_in: + + + leaq -1(%r13,%r15,1),%rsi + + + addq %r15,%r13 + subq %r15,%r14 + movq %r13,48(%r9) + movq %r14,56(%r9) + + + + addq %r15,%r8 + + + pxor %xmm11,%xmm11 +L$load_extra_load_loop: + pslldq $1,%xmm11 + pinsrb $0,(%rsi),%xmm11 + leaq -1(%rsi),%rsi + subq $1,%r15 + jnz L$load_extra_load_loop + + + + + movq %rbx,%r15 + +L$load_extra_shift_loop: + pslldq $1,%xmm11 + subq $1,%r15 + jnz L$load_extra_shift_loop + + + + + leaq L$and_masks(%rip),%r15 + shlq $4,%rbx + pand -16(%r15,%rbx,1),%xmm15 + + + por %xmm11,%xmm15 + + + +.byte 102,77,15,126,253 + pextrq $1,%xmm15,%r14 + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +L$process_blocks_of_extra_in: + + movq 288+32+0 (%rsp),%r9 + movq 48(%r9),%rsi + movq 56(%r9),%r8 + movq %r8,%rcx + shrq $4,%r8 + +L$process_extra_hash_loop: + jz process_extra_in_trailer + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rsi),%rsi + subq $1,%r8 + jmp L$process_extra_hash_loop +process_extra_in_trailer: + andq $15,%rcx + movq %rcx,%rbx + jz L$do_length_block + leaq -1(%rsi,%rcx,1),%rsi + +L$process_extra_in_trailer_load: + pslldq $1,%xmm15 + pinsrb $0,(%rsi),%xmm15 + leaq -1(%rsi),%rsi + subq $1,%rcx + jnz L$process_extra_in_trailer_load + +L$process_partial_block: + + leaq L$and_masks(%rip),%r15 + shlq $4,%rbx + pand -16(%r15,%rbx,1),%xmm15 +.byte 102,77,15,126,253 + pextrq $1,%xmm15,%r14 + addq %r13,%r10 + adcq %r14,%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + +L$do_length_block: + addq 0+0+32(%rbp),%r10 + adcq 8+0+32(%rbp),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + movq %r10,%r13 + movq %r11,%r14 + movq %r12,%r15 + subq $-5,%r10 + sbbq $-1,%r11 + sbbq $3,%r12 + cmovcq %r13,%r10 + cmovcq %r14,%r11 + cmovcq %r15,%r12 + + addq 0+0+16(%rbp),%r10 + adcq 8+0+16(%rbp),%r11 + + + addq $288 + 0 + 32,%rsp + + + popq %r9 + + movq %r10,(%r9) + movq %r11,8(%r9) + popq %r15 + + popq %r14 + + popq %r13 + + popq %r12 + + popq %rbx + + popq %rbp + + .byte 0xf3,0xc3 + +L$seal_sse_128: + + movdqu L$chacha20_consts(%rip),%xmm0 + movdqa %xmm0,%xmm1 + movdqa %xmm0,%xmm2 + movdqu 0(%r9),%xmm4 + movdqa %xmm4,%xmm5 + movdqa %xmm4,%xmm6 + movdqu 16(%r9),%xmm8 + movdqa %xmm8,%xmm9 + movdqa %xmm8,%xmm10 + movdqu 32(%r9),%xmm14 + movdqa %xmm14,%xmm12 + paddd L$sse_inc(%rip),%xmm12 + movdqa %xmm12,%xmm13 + paddd L$sse_inc(%rip),%xmm13 + movdqa %xmm4,%xmm7 + movdqa %xmm8,%xmm11 + movdqa %xmm12,%xmm15 + movq $10,%r10 + +L$seal_sse_128_rounds: + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,4 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,12 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,4 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,12 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,4 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,12 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol16(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm4 + pxor %xmm3,%xmm4 + paddd %xmm4,%xmm0 + pxor %xmm0,%xmm12 + pshufb L$rol8(%rip),%xmm12 + paddd %xmm12,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,15,228,12 +.byte 102,69,15,58,15,192,8 +.byte 102,69,15,58,15,228,4 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol16(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm5 + pxor %xmm3,%xmm5 + paddd %xmm5,%xmm1 + pxor %xmm1,%xmm13 + pshufb L$rol8(%rip),%xmm13 + paddd %xmm13,%xmm9 + pxor %xmm9,%xmm5 + movdqa %xmm5,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm5 + pxor %xmm3,%xmm5 +.byte 102,15,58,15,237,12 +.byte 102,69,15,58,15,201,8 +.byte 102,69,15,58,15,237,4 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol16(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $12,%xmm3 + psrld $20,%xmm6 + pxor %xmm3,%xmm6 + paddd %xmm6,%xmm2 + pxor %xmm2,%xmm14 + pshufb L$rol8(%rip),%xmm14 + paddd %xmm14,%xmm10 + pxor %xmm10,%xmm6 + movdqa %xmm6,%xmm3 + pslld $7,%xmm3 + psrld $25,%xmm6 + pxor %xmm3,%xmm6 +.byte 102,15,58,15,246,12 +.byte 102,69,15,58,15,210,8 +.byte 102,69,15,58,15,246,4 + + decq %r10 + jnz L$seal_sse_128_rounds + paddd L$chacha20_consts(%rip),%xmm0 + paddd L$chacha20_consts(%rip),%xmm1 + paddd L$chacha20_consts(%rip),%xmm2 + paddd %xmm7,%xmm4 + paddd %xmm7,%xmm5 + paddd %xmm7,%xmm6 + paddd %xmm11,%xmm8 + paddd %xmm11,%xmm9 + paddd %xmm15,%xmm12 + paddd L$sse_inc(%rip),%xmm15 + paddd %xmm15,%xmm13 + + pand L$clamp(%rip),%xmm2 + movdqa %xmm2,0+0(%rbp) + movdqa %xmm6,0+16(%rbp) + + movq %r8,%r8 + call poly_hash_ad_internal + jmp L$seal_sse_128_tail_xor + + + + + +.p2align 6 +chacha20_poly1305_open_avx2: + + + + + + + + + + + + + vzeroupper + vmovdqa L$chacha20_consts(%rip),%ymm0 + vbroadcasti128 0(%r9),%ymm4 + vbroadcasti128 16(%r9),%ymm8 + vbroadcasti128 32(%r9),%ymm12 + vpaddd L$avx2_init(%rip),%ymm12,%ymm12 + cmpq $192,%rbx + jbe L$open_avx2_192 + cmpq $320,%rbx + jbe L$open_avx2_320 + + vmovdqa %ymm4,0+64(%rbp) + vmovdqa %ymm8,0+96(%rbp) + vmovdqa %ymm12,0+160(%rbp) + movq $10,%r10 +L$open_avx2_init_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + decq %r10 + jne L$open_avx2_init_rounds + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand L$clamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + + movq %r8,%r8 + call poly_hash_ad_internal + + xorq %rcx,%rcx +L$open_avx2_init_hash: + addq 0+0(%rsi,%rcx,1),%r10 + adcq 8+0(%rsi,%rcx,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + addq $16,%rcx + cmpq $64,%rcx + jne L$open_avx2_init_hash + + vpxor 0(%rsi),%ymm0,%ymm0 + vpxor 32(%rsi),%ymm4,%ymm4 + + vmovdqu %ymm0,0(%rdi) + vmovdqu %ymm4,32(%rdi) + leaq 64(%rsi),%rsi + leaq 64(%rdi),%rdi + subq $64,%rbx +L$open_avx2_main_loop: + + cmpq $512,%rbx + jb L$open_avx2_main_loop_done + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + xorq %rcx,%rcx +L$open_avx2_main_loop_rounds: + addq 0+0(%rsi,%rcx,1),%r10 + adcq 8+0(%rsi,%rcx,1),%r11 + adcq $1,%r12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + addq %rax,%r15 + adcq %rdx,%r9 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + addq 0+16(%rsi,%rcx,1),%r10 + adcq 8+16(%rsi,%rcx,1),%r11 + adcq $1,%r12 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + addq %rax,%r15 + adcq %rdx,%r9 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq 0+32(%rsi,%rcx,1),%r10 + adcq 8+32(%rsi,%rcx,1),%r11 + adcq $1,%r12 + + leaq 48(%rcx),%rcx + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq %rax,%r15 + adcq %rdx,%r9 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + cmpq $60*8,%rcx + jne L$open_avx2_main_loop_rounds + vpaddd L$chacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + addq 0+60*8(%rsi),%r10 + adcq 8+60*8(%rsi),%r11 + adcq $1,%r12 + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + addq 0+60*8+16(%rsi),%r10 + adcq 8+60*8+16(%rsi),%r11 + adcq $1,%r12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm4 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm8 + vpxor 0+384(%rsi),%ymm3,%ymm3 + vpxor 32+384(%rsi),%ymm0,%ymm0 + vpxor 64+384(%rsi),%ymm4,%ymm4 + vpxor 96+384(%rsi),%ymm8,%ymm8 + vmovdqu %ymm3,0+384(%rdi) + vmovdqu %ymm0,32+384(%rdi) + vmovdqu %ymm4,64+384(%rdi) + vmovdqu %ymm8,96+384(%rdi) + + leaq 512(%rsi),%rsi + leaq 512(%rdi),%rdi + subq $512,%rbx + jmp L$open_avx2_main_loop +L$open_avx2_main_loop_done: + testq %rbx,%rbx + vzeroupper + je L$open_sse_finalize + + cmpq $384,%rbx + ja L$open_avx2_tail_512 + cmpq $256,%rbx + ja L$open_avx2_tail_384 + cmpq $128,%rbx + ja L$open_avx2_tail_256 + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + + xorq %r8,%r8 + movq %rbx,%rcx + andq $-16,%rcx + testq %rcx,%rcx + je L$open_avx2_tail_128_rounds +L$open_avx2_tail_128_rounds_and_x1hash: + addq 0+0(%rsi,%r8,1),%r10 + adcq 8+0(%rsi,%r8,1),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +L$open_avx2_tail_128_rounds: + addq $16,%r8 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + cmpq %rcx,%r8 + jb L$open_avx2_tail_128_rounds_and_x1hash + cmpq $160,%r8 + jne L$open_avx2_tail_128_rounds + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + jmp L$open_avx2_tail_128_xor + +L$open_avx2_tail_256: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + + movq %rbx,0+128(%rbp) + movq %rbx,%rcx + subq $128,%rcx + shrq $4,%rcx + movq $10,%r8 + cmpq $10,%rcx + cmovgq %r8,%rcx + movq %rsi,%rbx + xorq %r8,%r8 +L$open_avx2_tail_256_rounds_and_x1hash: + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx +L$open_avx2_tail_256_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + + incq %r8 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + cmpq %rcx,%r8 + jb L$open_avx2_tail_256_rounds_and_x1hash + cmpq $10,%r8 + jne L$open_avx2_tail_256_rounds + movq %rbx,%r8 + subq %rsi,%rbx + movq %rbx,%rcx + movq 0+128(%rbp),%rbx +L$open_avx2_tail_256_hash: + addq $16,%rcx + cmpq %rbx,%rcx + jg L$open_avx2_tail_256_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + jmp L$open_avx2_tail_256_hash +L$open_avx2_tail_256_done: + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm1,%ymm1 + vpxor 64+0(%rsi),%ymm5,%ymm5 + vpxor 96+0(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm1,32+0(%rdi) + vmovdqu %ymm5,64+0(%rdi) + vmovdqu %ymm9,96+0(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 128(%rsi),%rsi + leaq 128(%rdi),%rdi + subq $128,%rbx + jmp L$open_avx2_tail_128_xor + +L$open_avx2_tail_384: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + + movq %rbx,0+128(%rbp) + movq %rbx,%rcx + subq $256,%rcx + shrq $4,%rcx + addq $6,%rcx + movq $10,%r8 + cmpq $10,%rcx + cmovgq %r8,%rcx + movq %rsi,%rbx + xorq %r8,%r8 +L$open_avx2_tail_384_rounds_and_x2hash: + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx +L$open_avx2_tail_384_rounds_and_x1hash: + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq 0+0(%rbx),%r10 + adcq 8+0(%rbx),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rbx),%rbx + incq %r8 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + + cmpq %rcx,%r8 + jb L$open_avx2_tail_384_rounds_and_x2hash + cmpq $10,%r8 + jne L$open_avx2_tail_384_rounds_and_x1hash + movq %rbx,%r8 + subq %rsi,%rbx + movq %rbx,%rcx + movq 0+128(%rbp),%rbx +L$open_avx2_384_tail_hash: + addq $16,%rcx + cmpq %rbx,%rcx + jg L$open_avx2_384_tail_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + jmp L$open_avx2_384_tail_hash +L$open_avx2_384_tail_done: + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm2,%ymm2 + vpxor 64+0(%rsi),%ymm6,%ymm6 + vpxor 96+0(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm2,32+0(%rdi) + vmovdqu %ymm6,64+0(%rdi) + vmovdqu %ymm10,96+0(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm1,%ymm1 + vpxor 64+128(%rsi),%ymm5,%ymm5 + vpxor 96+128(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm1,32+128(%rdi) + vmovdqu %ymm5,64+128(%rdi) + vmovdqu %ymm9,96+128(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 256(%rsi),%rsi + leaq 256(%rdi),%rdi + subq $256,%rbx + jmp L$open_avx2_tail_128_xor + +L$open_avx2_tail_512: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + xorq %rcx,%rcx + movq %rsi,%r8 +L$open_avx2_tail_512_rounds_and_x2hash: + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 +L$open_avx2_tail_512_rounds_and_x1hash: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + addq 0+16(%r8),%r10 + adcq 8+16(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%r8),%r8 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + incq %rcx + cmpq $4,%rcx + jl L$open_avx2_tail_512_rounds_and_x2hash + cmpq $10,%rcx + jne L$open_avx2_tail_512_rounds_and_x1hash + movq %rbx,%rcx + subq $384,%rcx + andq $-16,%rcx +L$open_avx2_tail_512_hash: + testq %rcx,%rcx + je L$open_avx2_tail_512_done + addq 0+0(%r8),%r10 + adcq 8+0(%r8),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%r8),%r8 + subq $16,%rcx + jmp L$open_avx2_tail_512_hash +L$open_avx2_tail_512_done: + vpaddd L$chacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + leaq 384(%rsi),%rsi + leaq 384(%rdi),%rdi + subq $384,%rbx +L$open_avx2_tail_128_xor: + cmpq $32,%rbx + jb L$open_avx2_tail_32_xor + subq $32,%rbx + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + leaq 32(%rdi),%rdi + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + jmp L$open_avx2_tail_128_xor +L$open_avx2_tail_32_xor: + cmpq $16,%rbx + vmovdqa %xmm0,%xmm1 + jb L$open_avx2_exit + subq $16,%rbx + + vpxor (%rsi),%xmm0,%xmm1 + vmovdqu %xmm1,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + vperm2i128 $0x11,%ymm0,%ymm0,%ymm0 + vmovdqa %xmm0,%xmm1 +L$open_avx2_exit: + vzeroupper + jmp L$open_sse_tail_16 + +L$open_avx2_192: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd L$avx2_inc(%rip),%ymm12,%ymm13 + vmovdqa %ymm12,%ymm11 + vmovdqa %ymm13,%ymm15 + movq $10,%r10 +L$open_avx2_192_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + + decq %r10 + jne L$open_avx2_192_rounds + vpaddd %ymm2,%ymm0,%ymm0 + vpaddd %ymm2,%ymm1,%ymm1 + vpaddd %ymm6,%ymm4,%ymm4 + vpaddd %ymm6,%ymm5,%ymm5 + vpaddd %ymm10,%ymm8,%ymm8 + vpaddd %ymm10,%ymm9,%ymm9 + vpaddd %ymm11,%ymm12,%ymm12 + vpaddd %ymm15,%ymm13,%ymm13 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand L$clamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 +L$open_avx2_short: + movq %r8,%r8 + call poly_hash_ad_internal +L$open_avx2_short_hash_and_xor_loop: + cmpq $32,%rbx + jb L$open_avx2_short_tail_32 + subq $32,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rsi),%r10 + adcq 8+16(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + leaq 32(%rdi),%rdi + + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + vmovdqa %ymm1,%ymm12 + vmovdqa %ymm5,%ymm1 + vmovdqa %ymm9,%ymm5 + vmovdqa %ymm13,%ymm9 + vmovdqa %ymm2,%ymm13 + vmovdqa %ymm6,%ymm2 + jmp L$open_avx2_short_hash_and_xor_loop +L$open_avx2_short_tail_32: + cmpq $16,%rbx + vmovdqa %xmm0,%xmm1 + jb L$open_avx2_short_tail_32_exit + subq $16,%rbx + addq 0+0(%rsi),%r10 + adcq 8+0(%rsi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + vpxor (%rsi),%xmm0,%xmm3 + vmovdqu %xmm3,(%rdi) + leaq 16(%rsi),%rsi + leaq 16(%rdi),%rdi + vextracti128 $1,%ymm0,%xmm1 +L$open_avx2_short_tail_32_exit: + vzeroupper + jmp L$open_sse_tail_16 + +L$open_avx2_320: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd L$avx2_inc(%rip),%ymm12,%ymm13 + vpaddd L$avx2_inc(%rip),%ymm13,%ymm14 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + movq $10,%r10 +L$open_avx2_320_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + decq %r10 + jne L$open_avx2_320_rounds + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd %ymm7,%ymm4,%ymm4 + vpaddd %ymm7,%ymm5,%ymm5 + vpaddd %ymm7,%ymm6,%ymm6 + vpaddd %ymm11,%ymm8,%ymm8 + vpaddd %ymm11,%ymm9,%ymm9 + vpaddd %ymm11,%ymm10,%ymm10 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand L$clamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm9 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm13 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm6 + jmp L$open_avx2_short + + + + + +.p2align 6 +chacha20_poly1305_seal_avx2: + + + + + + + + + + + + + vzeroupper + vmovdqa L$chacha20_consts(%rip),%ymm0 + vbroadcasti128 0(%r9),%ymm4 + vbroadcasti128 16(%r9),%ymm8 + vbroadcasti128 32(%r9),%ymm12 + vpaddd L$avx2_init(%rip),%ymm12,%ymm12 + cmpq $192,%rbx + jbe L$seal_avx2_192 + cmpq $320,%rbx + jbe L$seal_avx2_320 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm4,0+64(%rbp) + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm8,0+96(%rbp) + vmovdqa %ymm12,%ymm15 + vpaddd L$avx2_inc(%rip),%ymm15,%ymm14 + vpaddd L$avx2_inc(%rip),%ymm14,%ymm13 + vpaddd L$avx2_inc(%rip),%ymm13,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm15,0+256(%rbp) + movq $10,%r10 +L$seal_avx2_init_rounds: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + decq %r10 + jnz L$seal_avx2_init_rounds + vpaddd L$chacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vperm2i128 $0x02,%ymm3,%ymm7,%ymm15 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm3 + vpand L$clamp(%rip),%ymm15,%ymm15 + vmovdqa %ymm15,0+0(%rbp) + movq %r8,%r8 + call poly_hash_ad_internal + + vpxor 0(%rsi),%ymm3,%ymm3 + vpxor 32(%rsi),%ymm11,%ymm11 + vmovdqu %ymm3,0(%rdi) + vmovdqu %ymm11,32(%rdi) + vperm2i128 $0x02,%ymm2,%ymm6,%ymm15 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+64(%rsi),%ymm15,%ymm15 + vpxor 32+64(%rsi),%ymm2,%ymm2 + vpxor 64+64(%rsi),%ymm6,%ymm6 + vpxor 96+64(%rsi),%ymm10,%ymm10 + vmovdqu %ymm15,0+64(%rdi) + vmovdqu %ymm2,32+64(%rdi) + vmovdqu %ymm6,64+64(%rdi) + vmovdqu %ymm10,96+64(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm15 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+192(%rsi),%ymm15,%ymm15 + vpxor 32+192(%rsi),%ymm1,%ymm1 + vpxor 64+192(%rsi),%ymm5,%ymm5 + vpxor 96+192(%rsi),%ymm9,%ymm9 + vmovdqu %ymm15,0+192(%rdi) + vmovdqu %ymm1,32+192(%rdi) + vmovdqu %ymm5,64+192(%rdi) + vmovdqu %ymm9,96+192(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm15 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm15,%ymm8 + + leaq 320(%rsi),%rsi + subq $320,%rbx + movq $320,%rcx + cmpq $128,%rbx + jbe L$seal_avx2_short_hash_remainder + vpxor 0(%rsi),%ymm0,%ymm0 + vpxor 32(%rsi),%ymm4,%ymm4 + vpxor 64(%rsi),%ymm8,%ymm8 + vpxor 96(%rsi),%ymm12,%ymm12 + vmovdqu %ymm0,320(%rdi) + vmovdqu %ymm4,352(%rdi) + vmovdqu %ymm8,384(%rdi) + vmovdqu %ymm12,416(%rdi) + leaq 128(%rsi),%rsi + subq $128,%rbx + movq $8,%rcx + movq $2,%r8 + cmpq $128,%rbx + jbe L$seal_avx2_tail_128 + cmpq $256,%rbx + jbe L$seal_avx2_tail_256 + cmpq $384,%rbx + jbe L$seal_avx2_tail_384 + cmpq $512,%rbx + jbe L$seal_avx2_tail_512 + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + + subq $16,%rdi + movq $9,%rcx + jmp L$seal_avx2_main_loop_rounds_entry +.p2align 5 +L$seal_avx2_main_loop: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + + movq $10,%rcx +.p2align 5 +L$seal_avx2_main_loop_rounds: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + addq %rax,%r15 + adcq %rdx,%r9 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + +L$seal_avx2_main_loop_rounds_entry: + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + addq %rax,%r15 + adcq %rdx,%r9 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq 0+32(%rdi),%r10 + adcq 8+32(%rdi),%r11 + adcq $1,%r12 + + leaq 48(%rdi),%rdi + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + addq %rax,%r15 + adcq %rdx,%r9 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + decq %rcx + jne L$seal_avx2_main_loop_rounds + vpaddd L$chacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm4 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm8 + vpxor 0+384(%rsi),%ymm3,%ymm3 + vpxor 32+384(%rsi),%ymm0,%ymm0 + vpxor 64+384(%rsi),%ymm4,%ymm4 + vpxor 96+384(%rsi),%ymm8,%ymm8 + vmovdqu %ymm3,0+384(%rdi) + vmovdqu %ymm0,32+384(%rdi) + vmovdqu %ymm4,64+384(%rdi) + vmovdqu %ymm8,96+384(%rdi) + + leaq 512(%rsi),%rsi + subq $512,%rbx + cmpq $512,%rbx + jg L$seal_avx2_main_loop + + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + movq $10,%rcx + xorq %r8,%r8 + + cmpq $384,%rbx + ja L$seal_avx2_tail_512 + cmpq $256,%rbx + ja L$seal_avx2_tail_384 + cmpq $128,%rbx + ja L$seal_avx2_tail_256 + +L$seal_avx2_tail_128: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + +L$seal_avx2_tail_128_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_avx2_tail_128_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg L$seal_avx2_tail_128_rounds_and_3xhash + decq %r8 + jge L$seal_avx2_tail_128_rounds_and_2xhash + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + jmp L$seal_avx2_short_loop + +L$seal_avx2_tail_256: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + +L$seal_avx2_tail_256_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_avx2_tail_256_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg L$seal_avx2_tail_256_rounds_and_3xhash + decq %r8 + jge L$seal_avx2_tail_256_rounds_and_2xhash + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm1,%ymm1 + vpxor 64+0(%rsi),%ymm5,%ymm5 + vpxor 96+0(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm1,32+0(%rdi) + vmovdqu %ymm5,64+0(%rdi) + vmovdqu %ymm9,96+0(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $128,%rcx + leaq 128(%rsi),%rsi + subq $128,%rbx + jmp L$seal_avx2_short_hash_remainder + +L$seal_avx2_tail_384: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + +L$seal_avx2_tail_384_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_avx2_tail_384_rounds_and_2xhash: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + leaq 32(%rdi),%rdi + decq %rcx + jg L$seal_avx2_tail_384_rounds_and_3xhash + decq %r8 + jge L$seal_avx2_tail_384_rounds_and_2xhash + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+0(%rsi),%ymm3,%ymm3 + vpxor 32+0(%rsi),%ymm2,%ymm2 + vpxor 64+0(%rsi),%ymm6,%ymm6 + vpxor 96+0(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+0(%rdi) + vmovdqu %ymm2,32+0(%rdi) + vmovdqu %ymm6,64+0(%rdi) + vmovdqu %ymm10,96+0(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm1,%ymm1 + vpxor 64+128(%rsi),%ymm5,%ymm5 + vpxor 96+128(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm1,32+128(%rdi) + vmovdqu %ymm5,64+128(%rdi) + vmovdqu %ymm9,96+128(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $256,%rcx + leaq 256(%rsi),%rsi + subq $256,%rbx + jmp L$seal_avx2_short_hash_remainder + +L$seal_avx2_tail_512: + vmovdqa L$chacha20_consts(%rip),%ymm0 + vmovdqa 0+64(%rbp),%ymm4 + vmovdqa 0+96(%rbp),%ymm8 + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm10 + vmovdqa %ymm0,%ymm3 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa L$avx2_inc(%rip),%ymm12 + vpaddd 0+160(%rbp),%ymm12,%ymm15 + vpaddd %ymm15,%ymm12,%ymm14 + vpaddd %ymm14,%ymm12,%ymm13 + vpaddd %ymm13,%ymm12,%ymm12 + vmovdqa %ymm15,0+256(%rbp) + vmovdqa %ymm14,0+224(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm12,0+160(%rbp) + +L$seal_avx2_tail_512_rounds_and_3xhash: + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + addq %rax,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi +L$seal_avx2_tail_512_rounds_and_2xhash: + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $4,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $12,%ymm15,%ymm15,%ymm15 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $4,%ymm4,%ymm4,%ymm4 + addq %rax,%r15 + adcq %rdx,%r9 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vmovdqa %ymm8,0+128(%rbp) + vmovdqa L$rol16(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $20,%ymm7,%ymm8 + vpslld $32-20,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $20,%ymm6,%ymm8 + vpslld $32-20,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $20,%ymm5,%ymm8 + vpslld $32-20,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $20,%ymm4,%ymm8 + vpslld $32-20,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa L$rol8(%rip),%ymm8 + vpaddd %ymm7,%ymm3,%ymm3 + vpaddd %ymm6,%ymm2,%ymm2 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + vpaddd %ymm5,%ymm1,%ymm1 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm3,%ymm15,%ymm15 + vpxor %ymm2,%ymm14,%ymm14 + vpxor %ymm1,%ymm13,%ymm13 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb %ymm8,%ymm15,%ymm15 + vpshufb %ymm8,%ymm14,%ymm14 + vpshufb %ymm8,%ymm13,%ymm13 + vpshufb %ymm8,%ymm12,%ymm12 + vpaddd %ymm15,%ymm11,%ymm11 + vpaddd %ymm14,%ymm10,%ymm10 + vpaddd %ymm13,%ymm9,%ymm9 + vpaddd 0+128(%rbp),%ymm12,%ymm8 + vpxor %ymm11,%ymm7,%ymm7 + vpxor %ymm10,%ymm6,%ymm6 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa %ymm8,0+128(%rbp) + vpsrld $25,%ymm7,%ymm8 + movq 0+0+0(%rbp),%rdx + movq %rdx,%r15 + mulxq %r10,%r13,%r14 + mulxq %r11,%rax,%rdx + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + vpslld $32-25,%ymm7,%ymm7 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $25,%ymm6,%ymm8 + vpslld $32-25,%ymm6,%ymm6 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $25,%ymm5,%ymm8 + vpslld $32-25,%ymm5,%ymm5 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $25,%ymm4,%ymm8 + vpslld $32-25,%ymm4,%ymm4 + vpxor %ymm8,%ymm4,%ymm4 + vmovdqa 0+128(%rbp),%ymm8 + vpalignr $12,%ymm7,%ymm7,%ymm7 + vpalignr $8,%ymm11,%ymm11,%ymm11 + vpalignr $4,%ymm15,%ymm15,%ymm15 + vpalignr $12,%ymm6,%ymm6,%ymm6 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpalignr $8,%ymm9,%ymm9,%ymm9 + movq 8+0+0(%rbp),%rdx + mulxq %r10,%r10,%rax + addq %r10,%r14 + mulxq %r11,%r11,%r9 + adcq %r11,%r15 + adcq $0,%r9 + imulq %r12,%rdx + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm12,%ymm12,%ymm12 + + + + + + + + + + + + + + + + + addq %rax,%r15 + adcq %rdx,%r9 + + + + + + + + + + + + + + + + + + + + + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + decq %rcx + jg L$seal_avx2_tail_512_rounds_and_3xhash + decq %r8 + jge L$seal_avx2_tail_512_rounds_and_2xhash + vpaddd L$chacha20_consts(%rip),%ymm3,%ymm3 + vpaddd 0+64(%rbp),%ymm7,%ymm7 + vpaddd 0+96(%rbp),%ymm11,%ymm11 + vpaddd 0+256(%rbp),%ymm15,%ymm15 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd 0+64(%rbp),%ymm6,%ymm6 + vpaddd 0+96(%rbp),%ymm10,%ymm10 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd 0+64(%rbp),%ymm5,%ymm5 + vpaddd 0+96(%rbp),%ymm9,%ymm9 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd 0+64(%rbp),%ymm4,%ymm4 + vpaddd 0+96(%rbp),%ymm8,%ymm8 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + + vmovdqa %ymm0,0+128(%rbp) + vperm2i128 $0x02,%ymm3,%ymm7,%ymm0 + vperm2i128 $0x13,%ymm3,%ymm7,%ymm7 + vperm2i128 $0x02,%ymm11,%ymm15,%ymm3 + vperm2i128 $0x13,%ymm11,%ymm15,%ymm11 + vpxor 0+0(%rsi),%ymm0,%ymm0 + vpxor 32+0(%rsi),%ymm3,%ymm3 + vpxor 64+0(%rsi),%ymm7,%ymm7 + vpxor 96+0(%rsi),%ymm11,%ymm11 + vmovdqu %ymm0,0+0(%rdi) + vmovdqu %ymm3,32+0(%rdi) + vmovdqu %ymm7,64+0(%rdi) + vmovdqu %ymm11,96+0(%rdi) + + vmovdqa 0+128(%rbp),%ymm0 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm3 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm6 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm10 + vpxor 0+128(%rsi),%ymm3,%ymm3 + vpxor 32+128(%rsi),%ymm2,%ymm2 + vpxor 64+128(%rsi),%ymm6,%ymm6 + vpxor 96+128(%rsi),%ymm10,%ymm10 + vmovdqu %ymm3,0+128(%rdi) + vmovdqu %ymm2,32+128(%rdi) + vmovdqu %ymm6,64+128(%rdi) + vmovdqu %ymm10,96+128(%rdi) + vperm2i128 $0x02,%ymm1,%ymm5,%ymm3 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm5 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm9 + vpxor 0+256(%rsi),%ymm3,%ymm3 + vpxor 32+256(%rsi),%ymm1,%ymm1 + vpxor 64+256(%rsi),%ymm5,%ymm5 + vpxor 96+256(%rsi),%ymm9,%ymm9 + vmovdqu %ymm3,0+256(%rdi) + vmovdqu %ymm1,32+256(%rdi) + vmovdqu %ymm5,64+256(%rdi) + vmovdqu %ymm9,96+256(%rdi) + vperm2i128 $0x13,%ymm0,%ymm4,%ymm3 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x02,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm12 + vmovdqa %ymm3,%ymm8 + + movq $384,%rcx + leaq 384(%rsi),%rsi + subq $384,%rbx + jmp L$seal_avx2_short_hash_remainder + +L$seal_avx2_320: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd L$avx2_inc(%rip),%ymm12,%ymm13 + vpaddd L$avx2_inc(%rip),%ymm13,%ymm14 + vmovdqa %ymm4,%ymm7 + vmovdqa %ymm8,%ymm11 + vmovdqa %ymm12,0+160(%rbp) + vmovdqa %ymm13,0+192(%rbp) + vmovdqa %ymm14,0+224(%rbp) + movq $10,%r10 +L$seal_avx2_320_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $12,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $4,%ymm6,%ymm6,%ymm6 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol16(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpsrld $20,%ymm6,%ymm3 + vpslld $12,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpaddd %ymm6,%ymm2,%ymm2 + vpxor %ymm2,%ymm14,%ymm14 + vpshufb L$rol8(%rip),%ymm14,%ymm14 + vpaddd %ymm14,%ymm10,%ymm10 + vpxor %ymm10,%ymm6,%ymm6 + vpslld $7,%ymm6,%ymm3 + vpsrld $25,%ymm6,%ymm6 + vpxor %ymm3,%ymm6,%ymm6 + vpalignr $4,%ymm14,%ymm14,%ymm14 + vpalignr $8,%ymm10,%ymm10,%ymm10 + vpalignr $12,%ymm6,%ymm6,%ymm6 + + decq %r10 + jne L$seal_avx2_320_rounds + vpaddd L$chacha20_consts(%rip),%ymm0,%ymm0 + vpaddd L$chacha20_consts(%rip),%ymm1,%ymm1 + vpaddd L$chacha20_consts(%rip),%ymm2,%ymm2 + vpaddd %ymm7,%ymm4,%ymm4 + vpaddd %ymm7,%ymm5,%ymm5 + vpaddd %ymm7,%ymm6,%ymm6 + vpaddd %ymm11,%ymm8,%ymm8 + vpaddd %ymm11,%ymm9,%ymm9 + vpaddd %ymm11,%ymm10,%ymm10 + vpaddd 0+160(%rbp),%ymm12,%ymm12 + vpaddd 0+192(%rbp),%ymm13,%ymm13 + vpaddd 0+224(%rbp),%ymm14,%ymm14 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand L$clamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 + vperm2i128 $0x02,%ymm2,%ymm6,%ymm9 + vperm2i128 $0x02,%ymm10,%ymm14,%ymm13 + vperm2i128 $0x13,%ymm2,%ymm6,%ymm2 + vperm2i128 $0x13,%ymm10,%ymm14,%ymm6 + jmp L$seal_avx2_short + +L$seal_avx2_192: + vmovdqa %ymm0,%ymm1 + vmovdqa %ymm0,%ymm2 + vmovdqa %ymm4,%ymm5 + vmovdqa %ymm4,%ymm6 + vmovdqa %ymm8,%ymm9 + vmovdqa %ymm8,%ymm10 + vpaddd L$avx2_inc(%rip),%ymm12,%ymm13 + vmovdqa %ymm12,%ymm11 + vmovdqa %ymm13,%ymm15 + movq $10,%r10 +L$seal_avx2_192_rounds: + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $12,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $4,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $12,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $4,%ymm5,%ymm5,%ymm5 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol16(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $20,%ymm4,%ymm3 + vpslld $12,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpaddd %ymm4,%ymm0,%ymm0 + vpxor %ymm0,%ymm12,%ymm12 + vpshufb L$rol8(%rip),%ymm12,%ymm12 + vpaddd %ymm12,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpslld $7,%ymm4,%ymm3 + vpsrld $25,%ymm4,%ymm4 + vpxor %ymm3,%ymm4,%ymm4 + vpalignr $4,%ymm12,%ymm12,%ymm12 + vpalignr $8,%ymm8,%ymm8,%ymm8 + vpalignr $12,%ymm4,%ymm4,%ymm4 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol16(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpsrld $20,%ymm5,%ymm3 + vpslld $12,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpaddd %ymm5,%ymm1,%ymm1 + vpxor %ymm1,%ymm13,%ymm13 + vpshufb L$rol8(%rip),%ymm13,%ymm13 + vpaddd %ymm13,%ymm9,%ymm9 + vpxor %ymm9,%ymm5,%ymm5 + vpslld $7,%ymm5,%ymm3 + vpsrld $25,%ymm5,%ymm5 + vpxor %ymm3,%ymm5,%ymm5 + vpalignr $4,%ymm13,%ymm13,%ymm13 + vpalignr $8,%ymm9,%ymm9,%ymm9 + vpalignr $12,%ymm5,%ymm5,%ymm5 + + decq %r10 + jne L$seal_avx2_192_rounds + vpaddd %ymm2,%ymm0,%ymm0 + vpaddd %ymm2,%ymm1,%ymm1 + vpaddd %ymm6,%ymm4,%ymm4 + vpaddd %ymm6,%ymm5,%ymm5 + vpaddd %ymm10,%ymm8,%ymm8 + vpaddd %ymm10,%ymm9,%ymm9 + vpaddd %ymm11,%ymm12,%ymm12 + vpaddd %ymm15,%ymm13,%ymm13 + vperm2i128 $0x02,%ymm0,%ymm4,%ymm3 + + vpand L$clamp(%rip),%ymm3,%ymm3 + vmovdqa %ymm3,0+0(%rbp) + + vperm2i128 $0x13,%ymm0,%ymm4,%ymm0 + vperm2i128 $0x13,%ymm8,%ymm12,%ymm4 + vperm2i128 $0x02,%ymm1,%ymm5,%ymm8 + vperm2i128 $0x02,%ymm9,%ymm13,%ymm12 + vperm2i128 $0x13,%ymm1,%ymm5,%ymm1 + vperm2i128 $0x13,%ymm9,%ymm13,%ymm5 +L$seal_avx2_short: + movq %r8,%r8 + call poly_hash_ad_internal + xorq %rcx,%rcx +L$seal_avx2_short_hash_remainder: + cmpq $16,%rcx + jb L$seal_avx2_short_loop + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + subq $16,%rcx + addq $16,%rdi + jmp L$seal_avx2_short_hash_remainder +L$seal_avx2_short_loop: + cmpq $32,%rbx + jb L$seal_avx2_short_tail + subq $32,%rbx + + vpxor (%rsi),%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + leaq 32(%rsi),%rsi + + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + addq 0+16(%rdi),%r10 + adcq 8+16(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 32(%rdi),%rdi + + vmovdqa %ymm4,%ymm0 + vmovdqa %ymm8,%ymm4 + vmovdqa %ymm12,%ymm8 + vmovdqa %ymm1,%ymm12 + vmovdqa %ymm5,%ymm1 + vmovdqa %ymm9,%ymm5 + vmovdqa %ymm13,%ymm9 + vmovdqa %ymm2,%ymm13 + vmovdqa %ymm6,%ymm2 + jmp L$seal_avx2_short_loop +L$seal_avx2_short_tail: + cmpq $16,%rbx + jb L$seal_avx2_exit + subq $16,%rbx + vpxor (%rsi),%xmm0,%xmm3 + vmovdqu %xmm3,(%rdi) + leaq 16(%rsi),%rsi + addq 0+0(%rdi),%r10 + adcq 8+0(%rdi),%r11 + adcq $1,%r12 + movq 0+0+0(%rbp),%rax + movq %rax,%r15 + mulq %r10 + movq %rax,%r13 + movq %rdx,%r14 + movq 0+0+0(%rbp),%rax + mulq %r11 + imulq %r12,%r15 + addq %rax,%r14 + adcq %rdx,%r15 + movq 8+0+0(%rbp),%rax + movq %rax,%r9 + mulq %r10 + addq %rax,%r14 + adcq $0,%rdx + movq %rdx,%r10 + movq 8+0+0(%rbp),%rax + mulq %r11 + addq %rax,%r15 + adcq $0,%rdx + imulq %r12,%r9 + addq %r10,%r15 + adcq %rdx,%r9 + movq %r13,%r10 + movq %r14,%r11 + movq %r15,%r12 + andq $3,%r12 + movq %r15,%r13 + andq $-4,%r13 + movq %r9,%r14 + shrdq $2,%r9,%r15 + shrq $2,%r9 + addq %r13,%r15 + adcq %r14,%r9 + addq %r15,%r10 + adcq %r9,%r11 + adcq $0,%r12 + + leaq 16(%rdi),%rdi + vextracti128 $1,%ymm0,%xmm0 +L$seal_avx2_exit: + vzeroupper + jmp L$seal_sse_tail_16 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/cipher_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/cipher_extra.c new file mode 100644 index 00000000..f7056db1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/cipher_extra.c @@ -0,0 +1,127 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static const struct { + int nid; + const char *name; + const EVP_CIPHER *(*func)(void); +} kCiphers[] = { + {NID_aes_128_cbc, "aes-128-cbc", EVP_aes_128_cbc}, + {NID_aes_128_ctr, "aes-128-ctr", EVP_aes_128_ctr}, + {NID_aes_128_ecb, "aes-128-ecb", EVP_aes_128_ecb}, + {NID_aes_128_gcm, "aes-128-gcm", EVP_aes_128_gcm}, + {NID_aes_128_ofb128, "aes-128-ofb", EVP_aes_128_ofb}, + {NID_aes_192_cbc, "aes-192-cbc", EVP_aes_192_cbc}, + {NID_aes_192_ctr, "aes-192-ctr", EVP_aes_192_ctr}, + {NID_aes_192_ecb, "aes-192-ecb", EVP_aes_192_ecb}, + {NID_aes_192_gcm, "aes-192-gcm", EVP_aes_192_gcm}, + {NID_aes_192_ofb128, "aes-192-ofb", EVP_aes_192_ofb}, + {NID_aes_256_cbc, "aes-256-cbc", EVP_aes_256_cbc}, + {NID_aes_256_ctr, "aes-256-ctr", EVP_aes_256_ctr}, + {NID_aes_256_ecb, "aes-256-ecb", EVP_aes_256_ecb}, + {NID_aes_256_gcm, "aes-256-gcm", EVP_aes_256_gcm}, + {NID_aes_256_ofb128, "aes-256-ofb", EVP_aes_256_ofb}, + {NID_des_cbc, "des-cbc", EVP_des_cbc}, + {NID_des_ecb, "des-ecb", EVP_des_ecb}, + {NID_des_ede_cbc, "des-ede-cbc", EVP_des_ede_cbc}, + {NID_des_ede_ecb, "des-ede", EVP_des_ede}, + {NID_des_ede3_cbc, "des-ede3-cbc", EVP_des_ede3_cbc}, + {NID_rc2_cbc, "rc2-cbc", EVP_rc2_cbc}, + {NID_rc4, "rc4", EVP_rc4}, +}; + +const EVP_CIPHER *EVP_get_cipherbynid(int nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { + if (kCiphers[i].nid == nid) { + return kCiphers[i].func(); + } + } + return NULL; +} + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { + if (name == NULL) { + return NULL; + } + + // This is not a name used by OpenSSL, but tcpdump registers it with + // |EVP_add_cipher_alias|. Our |EVP_add_cipher_alias| is a no-op, so we + // support the name here. + if (OPENSSL_strcasecmp(name, "3des") == 0) { + name = "des-ede3-cbc"; + } + + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { + if (OPENSSL_strcasecmp(kCiphers[i].name, name) == 0) { + return kCiphers[i].func(); + } + } + + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/derive_key.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/derive_key.c new file mode 100644 index 00000000..8c5442d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/derive_key.c @@ -0,0 +1,152 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include + + +#define PKCS5_SALT_LEN 8 + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, size_t data_len, + unsigned count, uint8_t *key, uint8_t *iv) { + EVP_MD_CTX c; + uint8_t md_buf[EVP_MAX_MD_SIZE]; + unsigned niv, nkey, addmd = 0; + unsigned mds = 0, i; + int rv = 0; + + nkey = type->key_len; + niv = type->iv_len; + + assert(nkey <= EVP_MAX_KEY_LENGTH); + assert(niv <= EVP_MAX_IV_LENGTH); + + if (data == NULL) { + return nkey; + } + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) { + goto err; + } + if (addmd++) { + if (!EVP_DigestUpdate(&c, md_buf, mds)) { + goto err; + } + } + if (!EVP_DigestUpdate(&c, data, data_len)) { + goto err; + } + if (salt != NULL) { + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) { + goto err; + } + } + if (!EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + + for (i = 1; i < count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL) || + !EVP_DigestUpdate(&c, md_buf, mds) || + !EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + } + + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0 || i == mds) { + break; + } + if (key != NULL) { + *(key++) = md_buf[i]; + } + nkey--; + i++; + } + } + + if (niv && i != mds) { + for (;;) { + if (niv == 0 || i == mds) { + break; + } + if (iv != NULL) { + *(iv++) = md_buf[i]; + } + niv--; + i++; + } + } + if (nkey == 0 && niv == 0) { + break; + } + } + rv = type->key_len; + +err: + EVP_MD_CTX_cleanup(&c); + OPENSSL_cleanse(md_buf, EVP_MAX_MD_SIZE); + return rv; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesccm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesccm.c new file mode 100644 index 00000000..3d9912a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesccm.c @@ -0,0 +1,446 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include + +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +struct ccm128_context { + block128_f block; + ctr128_f ctr; + unsigned M, L; +}; + +struct ccm128_state { + union { + uint64_t u[2]; + uint8_t c[16]; + } nonce, cmac; +}; + +static int CRYPTO_ccm128_init(struct ccm128_context *ctx, const AES_KEY *key, + block128_f block, ctr128_f ctr, unsigned M, + unsigned L) { + if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) { + return 0; + } + ctx->block = block; + ctx->ctr = ctr; + ctx->M = M; + ctx->L = L; + return 1; +} + +static size_t CRYPTO_ccm128_max_input(const struct ccm128_context *ctx) { + return ctx->L >= sizeof(size_t) ? (size_t)-1 + : (((size_t)1) << (ctx->L * 8)) - 1; +} + +static int ccm128_init_state(const struct ccm128_context *ctx, + struct ccm128_state *state, const AES_KEY *key, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *aad, size_t aad_len, + size_t plaintext_len) { + const block128_f block = ctx->block; + const unsigned M = ctx->M; + const unsigned L = ctx->L; + + // |L| determines the expected |nonce_len| and the limit for |plaintext_len|. + if (plaintext_len > CRYPTO_ccm128_max_input(ctx) || + nonce_len != 15 - L) { + return 0; + } + + // Assemble the first block for computing the MAC. + OPENSSL_memset(state, 0, sizeof(*state)); + state->nonce.c[0] = (uint8_t)((L - 1) | ((M - 2) / 2) << 3); + if (aad_len != 0) { + state->nonce.c[0] |= 0x40; // Set AAD Flag + } + OPENSSL_memcpy(&state->nonce.c[1], nonce, nonce_len); + for (unsigned i = 0; i < L; i++) { + state->nonce.c[15 - i] = (uint8_t)(plaintext_len >> (8 * i)); + } + + (*block)(state->nonce.c, state->cmac.c, key); + size_t blocks = 1; + + if (aad_len != 0) { + unsigned i; + // Cast to u64 to avoid the compiler complaining about invalid shifts. + uint64_t aad_len_u64 = aad_len; + if (aad_len_u64 < 0x10000 - 0x100) { + state->cmac.c[0] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[1] ^= (uint8_t)aad_len_u64; + i = 2; + } else if (aad_len_u64 <= 0xffffffff) { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xfe; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[5] ^= (uint8_t)aad_len_u64; + i = 6; + } else { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xff; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 56); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 48); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 40); + state->cmac.c[5] ^= (uint8_t)(aad_len_u64 >> 32); + state->cmac.c[6] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[7] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[8] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[9] ^= (uint8_t)aad_len_u64; + i = 10; + } + + do { + for (; i < 16 && aad_len != 0; i++) { + state->cmac.c[i] ^= *aad; + aad++; + aad_len--; + } + (*block)(state->cmac.c, state->cmac.c, key); + blocks++; + i = 0; + } while (aad_len != 0); + } + + // Per RFC 3610, section 2.6, the total number of block cipher operations done + // must not exceed 2^61. There are two block cipher operations remaining per + // message block, plus one block at the end to encrypt the MAC. + size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1; + if (plaintext_len + 15 < plaintext_len || + remaining_blocks + blocks < blocks || + (uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) { + return 0; + } + + // Assemble the first block for encrypting and decrypting. The bottom |L| + // bytes are replaced with a counter and all bit the encoding of |L| is + // cleared in the first byte. + state->nonce.c[0] &= 7; + return 1; +} + +static int ccm128_encrypt(const struct ccm128_context *ctx, + struct ccm128_state *state, const AES_KEY *key, + uint8_t *out, const uint8_t *in, size_t len) { + // The counter for encryption begins at one. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + state->nonce.c[15] = 1; + + uint8_t partial_buf[16]; + unsigned num = 0; + if (ctx->ctr != NULL) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf, + &num, ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num, + ctx->block); + } + return 1; +} + +static int ccm128_compute_mac(const struct ccm128_context *ctx, + struct ccm128_state *state, const AES_KEY *key, + uint8_t *out_tag, size_t tag_len, + const uint8_t *in, size_t len) { + block128_f block = ctx->block; + if (tag_len != ctx->M) { + return 0; + } + + // Incorporate |in| into the MAC. + union { + uint64_t u[2]; + uint8_t c[16]; + } tmp; + while (len >= 16) { + OPENSSL_memcpy(tmp.c, in, 16); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + (*block)(state->cmac.c, state->cmac.c, key); + in += 16; + len -= 16; + } + if (len > 0) { + for (size_t i = 0; i < len; i++) { + state->cmac.c[i] ^= in[i]; + } + (*block)(state->cmac.c, state->cmac.c, key); + } + + // Encrypt the MAC with counter zero. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + (*block)(state->nonce.c, tmp.c, key); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + + OPENSSL_memcpy(out_tag, state->cmac.c, tag_len); + return 1; +} + +static int CRYPTO_ccm128_encrypt(const struct ccm128_context *ctx, + const AES_KEY *key, uint8_t *out, + uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, + const uint8_t *aad, size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) && + ccm128_encrypt(ctx, &state, key, out, in, len); +} + +static int CRYPTO_ccm128_decrypt(const struct ccm128_context *ctx, + const AES_KEY *key, uint8_t *out, + uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, + const uint8_t *aad, size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_encrypt(ctx, &state, key, out, in, len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len); +} + +#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16 + +struct aead_aes_ccm_ctx { + union { + double align; + AES_KEY ks; + } ks; + struct ccm128_context ccm; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_ccm_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_ccm_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_aes_ccm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, unsigned M, + unsigned L) { + assert(M == EVP_AEAD_max_overhead(ctx->aead)); + assert(M == EVP_AEAD_max_tag_len(ctx->aead)); + assert(15 - L == EVP_AEAD_nonce_length(ctx->aead)); + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = M; + } + + if (tag_len != M) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_ccm_ctx *ccm_ctx = (struct aead_aes_ccm_ctx *)&ctx->state; + + block128_f block; + ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len); + ctx->tag_len = tag_len; + if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, M, L)) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +static void aead_aes_ccm_cleanup(EVP_AEAD_CTX *ctx) {} + +static int aead_aes_ccm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = + (struct aead_aes_ccm_ctx *)&ctx->state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, out_tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + *out_tag_len = ctx->tag_len; + return 1; +} + +static int aead_aes_ccm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = + (struct aead_aes_ccm_ctx *)&ctx->state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + uint8_t tag[EVP_AEAD_AES_CCM_MAX_TAG_LEN]; + assert(ctx->tag_len <= EVP_AEAD_AES_CCM_MAX_TAG_LEN); + if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 4, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth = { + 16, // key length (AES-128) + 13, // nonce length + 4, // overhead + 4, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void) { + return &aead_aes_128_ccm_bluetooth; +} + +static int aead_aes_ccm_bluetooth_8_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 8, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth_8 = { + 16, // key length (AES-128) + 13, // nonce length + 8, // overhead + 8, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_8_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void) { + return &aead_aes_128_ccm_bluetooth_8; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesctrhmac.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesctrhmac.c new file mode 100644 index 00000000..88ea5b34 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesctrhmac.c @@ -0,0 +1,283 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH +#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12 + +struct aead_aes_ctr_hmac_sha256_ctx { + union { + double align; + AES_KEY ks; + } ks; + ctr128_f ctr; + block128_f block; + SHA256_CTX inner_init_state; + SHA256_CTX outer_init_state; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_ctr_hmac_sha256_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_ctr_hmac_sha256_ctx), + "AEAD state has insufficient alignment"); +#endif + +static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer, + const uint8_t hmac_key[32]) { + static const size_t hmac_key_len = 32; + uint8_t block[SHA256_CBLOCK]; + OPENSSL_memcpy(block, hmac_key, hmac_key_len); + OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len); + + unsigned i; + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= 0x36; + } + + SHA256_Init(out_inner); + SHA256_Update(out_inner, block, sizeof(block)); + + OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len); + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= (0x36 ^ 0x5c); + } + + SHA256_Init(out_outer); + SHA256_Update(out_outer, block, sizeof(block)); +} + +static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = + (struct aead_aes_ctr_hmac_sha256_ctx *)&ctx->state; + static const size_t hmac_key_len = 32; + + if (key_len < hmac_key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + const size_t aes_key_len = key_len - hmac_key_len; + if (aes_key_len != 16 && aes_key_len != 32) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + aes_ctx->ctr = + aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len); + ctx->tag_len = tag_len; + hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state, + key + aes_key_len); + + return 1; +} + +static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) {} + +static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) { + unsigned i; + uint8_t bytes[8]; + + for (i = 0; i < sizeof(bytes); i++) { + bytes[i] = value & 0xff; + value >>= 8; + } + SHA256_Update(sha256, bytes, sizeof(bytes)); +} + +static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH], + const SHA256_CTX *inner_init_state, + const SHA256_CTX *outer_init_state, + const uint8_t *ad, size_t ad_len, + const uint8_t *nonce, const uint8_t *ciphertext, + size_t ciphertext_len) { + SHA256_CTX sha256; + OPENSSL_memcpy(&sha256, inner_init_state, sizeof(sha256)); + hmac_update_uint64(&sha256, ad_len); + hmac_update_uint64(&sha256, ciphertext_len); + SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + SHA256_Update(&sha256, ad, ad_len); + + // Pad with zeros to the end of the SHA-256 block. + const unsigned num_padding = + (SHA256_CBLOCK - ((sizeof(uint64_t)*2 + + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) % + SHA256_CBLOCK)) % + SHA256_CBLOCK; + uint8_t padding[SHA256_CBLOCK]; + OPENSSL_memset(padding, 0, num_padding); + SHA256_Update(&sha256, padding, num_padding); + + SHA256_Update(&sha256, ciphertext, ciphertext_len); + + uint8_t inner_digest[SHA256_DIGEST_LENGTH]; + SHA256_Final(inner_digest, &sha256); + + OPENSSL_memcpy(&sha256, outer_init_state, sizeof(sha256)); + SHA256_Update(&sha256, inner_digest, sizeof(inner_digest)); + SHA256_Final(out, &sha256); +} + +static void aead_aes_ctr_hmac_sha256_crypt( + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out, + const uint8_t *in, size_t len, const uint8_t *nonce) { + // Since the AEAD operation is one-shot, keeping a buffer of unused keystream + // bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. + uint8_t partial_block_buffer[AES_BLOCK_SIZE]; + unsigned partial_block_offset = 0; + OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer)); + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + OPENSSL_memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4); + + if (aes_ctx->ctr) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->block); + } +} + +static int aead_aes_ctr_hmac_sha256_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = + (struct aead_aes_ctr_hmac_sha256_ctx *) &ctx->state; + const uint64_t in_len_64 = in_len; + + if (in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) { + // This input is so large it would overflow the 32-bit block counter. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len); + OPENSSL_memcpy(out_tag, hmac_result, ctx->tag_len); + *out_tag_len = ctx->tag_len; + + return 1; +} + +static int aead_aes_ctr_hmac_sha256_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = + (struct aead_aes_ctr_hmac_sha256_ctx *) &ctx->state; + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, in, + in_len); + if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + return 1; +} + +static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = { + 16 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = { + 32 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) { + return &aead_aes_128_ctr_hmac_sha256; +} + +const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) { + return &aead_aes_256_ctr_hmac_sha256; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesgcmsiv.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesgcmsiv.c new file mode 100644 index 00000000..445402c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesgcmsiv.c @@ -0,0 +1,884 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" + + +#define EVP_AEAD_AES_GCM_SIV_NONCE_LEN 12 +#define EVP_AEAD_AES_GCM_SIV_TAG_LEN 16 + +// TODO(davidben): AES-GCM-SIV assembly is not correct for Windows. It must save +// and restore xmm6 through xmm15. +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(OPENSSL_WINDOWS) +#define AES_GCM_SIV_ASM + +// Optimised AES-GCM-SIV + +struct aead_aes_gcm_siv_asm_ctx { + alignas(16) uint8_t key[16*15]; + int is_128_bit; +}; + +// The assembly code assumes 8-byte alignment of the EVP_AEAD_CTX's state, and +// aligns to 16 bytes itself. +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) + 8 >= + sizeof(struct aead_aes_gcm_siv_asm_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= 8, + "AEAD state has insufficient alignment"); +#endif + +// asm_ctx_from_ctx returns a 16-byte aligned context pointer from |ctx|. +static struct aead_aes_gcm_siv_asm_ctx *asm_ctx_from_ctx( + const EVP_AEAD_CTX *ctx) { + // ctx->state must already be 8-byte aligned. Thus, at most, we may need to + // add eight to align it to 16 bytes. + const uintptr_t offset = ((uintptr_t)&ctx->state) & 8; + return (struct aead_aes_gcm_siv_asm_ctx *)(&ctx->state.opaque[offset]); +} + +// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to +// |out_expanded_key|. +extern void aes128gcmsiv_aes_ks( + const uint8_t key[16], uint8_t out_expanded_key[16*15]); + +// aes256gcmsiv_aes_ks writes an AES-256 key schedule for |key| to +// |out_expanded_key|. +extern void aes256gcmsiv_aes_ks( + const uint8_t key[32], uint8_t out_expanded_key[16*15]); + +static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = asm_ctx_from_ctx(ctx); + assert((((uintptr_t)gcm_siv_ctx) & 15) == 0); + + if (key_bits == 128) { + aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 1; + } else { + aes256gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 0; + } + + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_asm_cleanup(EVP_AEAD_CTX *ctx) {} + +// aesgcmsiv_polyval_horner updates the POLYVAL value in |in_out_poly| to +// include a number (|in_blocks|) of 16-byte blocks of data from |in|, given +// the POLYVAL key in |key|. +extern void aesgcmsiv_polyval_horner(const uint8_t in_out_poly[16], + const uint8_t key[16], const uint8_t *in, + size_t in_blocks); + +// aesgcmsiv_htable_init writes powers 1..8 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable_init(uint8_t out_htable[16 * 8], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable6_init writes powers 1..6 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable6_init(uint8_t out_htable[16 * 6], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable_polyval updates the POLYVAL value in |in_out_poly| to +// include |in_len| bytes of data from |in|. (Where |in_len| must be a multiple +// of 16.) It uses the precomputed powers of the key given in |htable|. +extern void aesgcmsiv_htable_polyval(const uint8_t htable[16 * 8], + const uint8_t *in, size_t in_len, + uint8_t in_out_poly[16]); + +// aes128gcmsiv_dec decrypts |in_len| & ~15 bytes from |out| and writes them to +// |in|. (The full value of |in_len| is still used to find the authentication +// tag appended to the ciphertext, however, so must not be pre-masked.) +// +// |in| and |out| may be equal, but must not otherwise overlap. +// +// While decrypting, it updates the POLYVAL value found at the beginning of +// |in_out_calculated_tag_and_scratch| and writes the updated value back before +// return. During executation, it may use the whole of this space for other +// purposes. In order to decrypt and update the POLYVAL value, it uses the +// expanded key from |key| and the table of powers in |htable|. +extern void aes128gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_dec acts like |aes128gcmsiv_dec|, but for AES-256. +extern void aes256gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_kdf performs the AES-GCM-SIV KDF given the expanded key from +// |key_schedule| and the nonce in |nonce|. Note that, while only 12 bytes of +// the nonce are used, 16 bytes are read and so the value must be +// right-padded. +extern void aes128gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[8], + const uint8_t *key_schedule); + +// aes256gcmsiv_kdf acts like |aes128gcmsiv_kdf|, but for AES-256. +extern void aes256gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[12], + const uint8_t *key_schedule); + +// aes128gcmsiv_aes_ks_enc_x1 performs a key expansion of the AES-128 key in +// |key|, writes the expanded key to |out_expanded_key| and encrypts a single +// block from |in| to |out|. +extern void aes128gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[2]); + +// aes256gcmsiv_aes_ks_enc_x1 acts like |aes128gcmsiv_aes_ks_enc_x1|, but for +// AES-256. +extern void aes256gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[4]); + +// aes128gcmsiv_ecb_enc_block encrypts a single block from |in| to |out| using +// the expanded key in |expanded_key|. +extern void aes128gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes256gcmsiv_ecb_enc_block acts like |aes128gcmsiv_ecb_enc_block|, but for +// AES-256. +extern void aes256gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes128gcmsiv_enc_msg_x4 encrypts |in_len| bytes from |in| to |out| using the +// expanded key from |key|. (The value of |in_len| must be a multiple of 16.) +// The |in| and |out| buffers may be equal but must not otherwise overlap. The +// initial counter is constructed from the given |tag| as required by +// AES-GCM-SIV. +extern void aes128gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x4 acts like |aes128gcmsiv_enc_msg_x4|, but for +// AES-256. +extern void aes256gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_enc_msg_x8 acts like |aes128gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes128gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x8 acts like |aes256gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes256gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// gcm_siv_asm_polyval evaluates POLYVAL at |auth_key| on the given plaintext +// and AD. The result is written to |out_tag|. +static void gcm_siv_asm_polyval(uint8_t out_tag[16], const uint8_t *in, + size_t in_len, const uint8_t *ad, size_t ad_len, + const uint8_t auth_key[16], + const uint8_t nonce[12]) { + OPENSSL_memset(out_tag, 0, 16); + const size_t ad_blocks = ad_len / 16; + const size_t in_blocks = in_len / 16; + int htable_init = 0; + alignas(16) uint8_t htable[16*8]; + + if (ad_blocks > 8 || in_blocks > 8) { + htable_init = 1; + aesgcmsiv_htable_init(htable, auth_key); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, ad, ad_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, ad, ad_blocks); + } + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, in, in_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, in, in_blocks); + } + + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + aesgcmsiv_polyval_horner(out_tag, auth_key, length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + out_tag[i] ^= nonce[i]; + } + + out_tag[15] &= 0x7f; +} + +// aead_aes_gcm_siv_asm_crypt_last_block handles the encryption/decryption +// (same thing in CTR mode) of the final block of a plaintext/ciphertext. It +// writes |in_len| & 15 bytes to |out| + |in_len|, based on an initial counter +// derived from |tag|. +static void aead_aes_gcm_siv_asm_crypt_last_block( + int is_128_bit, uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t tag[16], + const struct aead_aes_gcm_siv_asm_ctx *enc_key_expanded) { + alignas(16) union { + uint8_t c[16]; + uint32_t u32[4]; + } counter; + OPENSSL_memcpy(&counter, tag, sizeof(counter)); + counter.c[15] |= 0x80; + counter.u32[0] += in_len / 16; + + if (is_128_bit) { + aes128gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } else { + aes256gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } + + const size_t last_bytes_offset = in_len & ~15; + const size_t last_bytes_len = in_len & 15; + uint8_t *last_bytes_out = &out[last_bytes_offset]; + const uint8_t *last_bytes_in = &in[last_bytes_offset]; + for (size_t i = 0; i < last_bytes_len; i++) { + last_bytes_out[i] = last_bytes_in[i] ^ counter.c[i]; + } +} + +// aead_aes_gcm_siv_kdf calculates the record encryption and authentication +// keys given the |nonce|. +static void aead_aes_gcm_siv_kdf( + int is_128_bit, const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx, + uint64_t out_record_auth_key[2], uint64_t out_record_enc_key[4], + const uint8_t nonce[12]) { + alignas(16) uint8_t padded_nonce[16]; + OPENSSL_memcpy(padded_nonce, nonce, 12); + + alignas(16) uint64_t key_material[12]; + if (is_128_bit) { + aes128gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + } else { + aes256gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + out_record_enc_key[2] = key_material[8]; + out_record_enc_key[3] = key_material[10]; + } + + out_record_auth_key[0] = key_material[0]; + out_record_auth_key[1] = key_material[2]; +} + +static int aead_aes_gcm_siv_asm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = asm_ctx_from_ctx(ctx); + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + alignas(16) uint8_t tag[16] = {0}; + gcm_siv_asm_polyval(tag, in, in_len, ad, ad_len, + (const uint8_t *)record_auth_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx enc_key_expanded; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes128gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes128gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } else { + aes256gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes256gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes256gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } + + if (in_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + in_len, tag, &enc_key_expanded); + } + + OPENSSL_memcpy(out_tag, tag, sizeof(tag)); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +// TODO(martinkr): Add aead_aes_gcm_siv_asm_open_gather. N.B. aes128gcmsiv_dec +// expects ciphertext and tag in a contiguous buffer. + +static int aead_aes_gcm_siv_asm_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = asm_ctx_from_ctx(ctx); + const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + const uint8_t *const given_tag = in + plaintext_len; + + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx expanded_key; + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } else { + aes256gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } + // calculated_tag is 16*8 bytes, rather than 16 bytes, because + // aes[128|256]gcmsiv_dec uses the extra as scratch space. + alignas(16) uint8_t calculated_tag[16 * 8] = {0}; + + OPENSSL_memset(calculated_tag, 0, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + const size_t ad_blocks = ad_len / 16; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, ad, + ad_blocks); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + alignas(16) uint8_t htable[16 * 6]; + aesgcmsiv_htable6_init(htable, (const uint8_t *)record_auth_key); + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } else { + aes256gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } + + if (plaintext_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + plaintext_len, given_tag, + &expanded_key); + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, out + (plaintext_len & ~15), plaintext_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = plaintext_len * 8; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + calculated_tag[i] ^= nonce[i]; + } + + calculated_tag[15] &= 0x7f; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } else { + aes256gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } + + if (CRYPTO_memcmp(calculated_tag, given_tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN) != + 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + *out_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv_asm = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv_asm = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#endif // X86_64 && !NO_ASM && !WINDOWS + +struct aead_aes_gcm_siv_ctx { + union { + double align; + AES_KEY ks; + } ks; + block128_f kgk_block; + unsigned is_256:1; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_siv_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_siv_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = + (struct aead_aes_gcm_siv_ctx *)&ctx->state; + OPENSSL_memset(gcm_siv_ctx, 0, sizeof(struct aead_aes_gcm_siv_ctx)); + + aes_ctr_set_key(&gcm_siv_ctx->ks.ks, NULL, &gcm_siv_ctx->kgk_block, key, + key_len); + gcm_siv_ctx->is_256 = (key_len == 32); + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) {} + +// gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from +// |in| to |out|, using the block function |enc_block| with |key| in counter +// mode, starting at |initial_counter|. This differs from the traditional +// counter mode code in that the counter is handled little-endian, only the +// first four bytes are used and the GCM-SIV tweak to the final byte is +// applied. The |in| and |out| pointers may be equal but otherwise must not +// alias. +static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t initial_counter[AES_BLOCK_SIZE], + block128_f enc_block, const AES_KEY *key) { + union { + uint32_t w[4]; + uint8_t c[16]; + } counter; + + OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE); + counter.c[15] |= 0x80; + + for (size_t done = 0; done < in_len;) { + uint8_t keystream[AES_BLOCK_SIZE]; + enc_block(counter.c, keystream, key); + counter.w[0]++; + + size_t todo = AES_BLOCK_SIZE; + if (in_len - done < todo) { + todo = in_len - done; + } + + for (size_t i = 0; i < todo; i++) { + out[done + i] = keystream[i] ^ in[done + i]; + } + + done += todo; + } +} + +// gcm_siv_polyval evaluates POLYVAL at |auth_key| on the given plaintext and +// AD. The result is written to |out_tag|. +static void gcm_siv_polyval( + uint8_t out_tag[16], const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len, const uint8_t auth_key[16], + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + struct polyval_ctx polyval_ctx; + CRYPTO_POLYVAL_init(&polyval_ctx, auth_key); + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, ad, ad_len & ~15); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, in, in_len & ~15); + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c, + sizeof(length_block)); + + CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag); + for (size_t i = 0; i < EVP_AEAD_AES_GCM_SIV_NONCE_LEN; i++) { + out_tag[i] ^= nonce[i]; + } + out_tag[15] &= 0x7f; +} + +// gcm_siv_record_keys contains the keys used for a specific GCM-SIV record. +struct gcm_siv_record_keys { + uint8_t auth_key[16]; + union { + double align; + AES_KEY ks; + } enc_key; + block128_f enc_block; +}; + +// gcm_siv_keys calculates the keys for a specific GCM-SIV record with the +// given nonce and writes them to |*out_keys|. +static void gcm_siv_keys( + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx, + struct gcm_siv_record_keys *out_keys, + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + const AES_KEY *const key = &gcm_siv_ctx->ks.ks; + uint8_t key_material[(128 /* POLYVAL key */ + 256 /* max AES key */) / 8]; + const size_t blocks_needed = gcm_siv_ctx->is_256 ? 6 : 4; + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memset(counter, 0, AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + OPENSSL_memcpy(counter + AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN, + nonce, EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + for (size_t i = 0; i < blocks_needed; i++) { + counter[0] = i; + + uint8_t ciphertext[AES_BLOCK_SIZE]; + gcm_siv_ctx->kgk_block(counter, ciphertext, key); + OPENSSL_memcpy(&key_material[i * 8], ciphertext, 8); + } + + OPENSSL_memcpy(out_keys->auth_key, key_material, 16); + // Note the |ctr128_f| function uses a big-endian couner, while AES-GCM-SIV + // uses a little-endian counter. We ignore the return value and only use + // |block128_f|. This has a significant performance cost for the fallback + // bitsliced AES implementations (bsaes and aes_nohw). + // + // We currently do not consider AES-GCM-SIV to be performance-sensitive on + // client hardware. If this changes, we can write little-endian |ctr128_f| + // functions. + aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block, + key_material + 16, gcm_siv_ctx->is_256 ? 32 : 16); +} + +static int aead_aes_gcm_siv_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = + (struct aead_aes_gcm_siv_ctx *)&ctx->state; + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN < in_len || + in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + uint8_t tag[16]; + gcm_siv_polyval(tag, in, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(tag, tag, &keys.enc_key.ks); + + gcm_siv_crypt(out, in, in_len, tag, keys.enc_block, &keys.enc_key.ks); + + OPENSSL_memcpy(out_tag, tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +static int aead_aes_gcm_siv_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, + size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = + (struct aead_aes_gcm_siv_ctx *)&ctx->state; + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + gcm_siv_crypt(out, in, in_len, in_tag, keys.enc_block, &keys.enc_key.ks); + + uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN]; + gcm_siv_polyval(expected_tag, out, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks); + + if (CRYPTO_memcmp(expected_tag, in_tag, sizeof(expected_tag)) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#if defined(AES_GCM_SIV_ASM) + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + if (CRYPTO_is_AVX_capable() && CRYPTO_is_AESNI_capable()) { + return &aead_aes_128_gcm_siv_asm; + } + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + if (CRYPTO_is_AVX_capable() && CRYPTO_is_AESNI_capable()) { + return &aead_aes_256_gcm_siv_asm; + } + return &aead_aes_256_gcm_siv; +} + +#else + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + return &aead_aes_256_gcm_siv; +} + +#endif // AES_GCM_SIV_ASM diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c new file mode 100644 index 00000000..87b1c08b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c @@ -0,0 +1,343 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../chacha/internal.h" +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" + +struct aead_chacha20_poly1305_ctx { + uint8_t key[32]; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_chacha20_poly1305_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_chacha20_poly1305_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_chacha20_poly1305_ctx *c20_ctx = + (struct aead_chacha20_poly1305_ctx *)&ctx->state; + + if (tag_len == 0) { + tag_len = POLY1305_TAG_LEN; + } + + if (tag_len > POLY1305_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (key_len != sizeof(c20_ctx->key)) { + return 0; // internal error - EVP_AEAD_CTX_init should catch this. + } + + OPENSSL_memcpy(c20_ctx->key, key, key_len); + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) {} + +static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) { + uint8_t length_bytes[8]; + + for (unsigned i = 0; i < sizeof(length_bytes); i++) { + length_bytes[i] = data_len; + data_len >>= 8; + } + + CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); +} + +// calc_tag fills |tag| with the authentication tag for the given inputs. +static void calc_tag(uint8_t tag[POLY1305_TAG_LEN], const uint8_t *key, + const uint8_t nonce[12], const uint8_t *ad, size_t ad_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *ciphertext_extra, + size_t ciphertext_extra_len) { + alignas(16) uint8_t poly1305_key[32]; + OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key, nonce, + 0); + + static const uint8_t padding[16] = { 0 }; // Padding is all zeros. + poly1305_state ctx; + CRYPTO_poly1305_init(&ctx, poly1305_key); + CRYPTO_poly1305_update(&ctx, ad, ad_len); + if (ad_len % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16)); + } + CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len); + CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len); + const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len; + if (ciphertext_total % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, + sizeof(padding) - (ciphertext_total % 16)); + } + poly1305_update_length(&ctx, ad_len); + poly1305_update_length(&ctx, ciphertext_total); + CRYPTO_poly1305_finish(&ctx, tag); +} + +static int chacha20_poly1305_seal_scatter( + const uint8_t *key, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len, size_t tag_len) { + if (extra_in_len + tag_len < tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < tag_len + extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + // The the extra input is given, it is expected to be very short and so is + // encrypted byte-by-byte first. + if (extra_in_len) { + static const size_t kChaChaBlockSize = 64; + uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + size_t offset = in_len % kChaChaBlockSize; + uint8_t block[64 /* kChaChaBlockSize */]; + + for (size_t done = 0; done < extra_in_len; block_counter++) { + memset(block, 0, sizeof(block)); + CRYPTO_chacha_20(block, block, sizeof(block), key, nonce, + block_counter); + for (size_t i = offset; i < sizeof(block) && done < extra_in_len; + i++, done++) { + out_tag[done] = extra_in[done] ^ block[i]; + } + offset = 0; + } + } + + union chacha20_poly1305_seal_data data; + if (chacha20_poly1305_asm_capable()) { + OPENSSL_memcpy(data.in.key, key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + data.in.extra_ciphertext = out_tag; + data.in.extra_ciphertext_len = extra_in_len; + chacha20_poly1305_seal(out, in, in_len, ad, ad_len, &data); + } else { + CRYPTO_chacha_20(out, in, in_len, key, nonce, 1); + calc_tag(data.out.tag, key, nonce, ad, ad_len, out, in_len, out_tag, + extra_in_len); + } + + OPENSSL_memcpy(out_tag + extra_in_len, data.out.tag, tag_len); + *out_tag_len = extra_in_len + tag_len; + return 1; +} + +static int aead_chacha20_poly1305_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = + (struct aead_chacha20_poly1305_ctx *)&ctx->state; + + return chacha20_poly1305_seal_scatter( + c20_ctx->key, out, out_tag, out_tag_len, max_out_tag_len, nonce, + nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len, ctx->tag_len); +} + +static int aead_xchacha20_poly1305_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = + (struct aead_chacha20_poly1305_ctx *)&ctx->state; + + if (nonce_len != 24) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + alignas(4) uint8_t derived_key[32]; + alignas(4) uint8_t derived_nonce[12]; + CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce); + OPENSSL_memset(derived_nonce, 0, 4); + OPENSSL_memcpy(&derived_nonce[4], &nonce[16], 8); + + return chacha20_poly1305_seal_scatter( + derived_key, out, out_tag, out_tag_len, max_out_tag_len, + derived_nonce, sizeof(derived_nonce), in, in_len, extra_in, extra_in_len, + ad, ad_len, ctx->tag_len); +} + +static int chacha20_poly1305_open_gather( + const uint8_t *key, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len, size_t tag_len) { + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + if (in_tag_len != tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + union chacha20_poly1305_open_data data; + if (chacha20_poly1305_asm_capable()) { + OPENSSL_memcpy(data.in.key, key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + chacha20_poly1305_open(out, in, in_len, ad, ad_len, &data); + } else { + calc_tag(data.out.tag, key, nonce, ad, ad_len, in, in_len, NULL, 0); + CRYPTO_chacha_20(out, in, in_len, key, nonce, 1); + } + + if (CRYPTO_memcmp(data.out.tag, in_tag, tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static int aead_chacha20_poly1305_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = + (struct aead_chacha20_poly1305_ctx *)&ctx->state; + + return chacha20_poly1305_open_gather(c20_ctx->key, out, nonce, nonce_len, in, + in_len, in_tag, in_tag_len, ad, ad_len, + ctx->tag_len); +} + +static int aead_xchacha20_poly1305_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = + (struct aead_chacha20_poly1305_ctx *)&ctx->state; + + if (nonce_len != 24) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + alignas(4) uint8_t derived_key[32]; + alignas(4) uint8_t derived_nonce[12]; + CRYPTO_hchacha20(derived_key, c20_ctx->key, nonce); + OPENSSL_memset(derived_nonce, 0, 4); + OPENSSL_memcpy(&derived_nonce[4], &nonce[16], 8); + + return chacha20_poly1305_open_gather( + derived_key, out, derived_nonce, sizeof(derived_nonce), in, in_len, + in_tag, in_tag_len, ad, ad_len, ctx->tag_len); +} + +static const EVP_AEAD aead_chacha20_poly1305 = { + 32, // key len + 12, // nonce len + POLY1305_TAG_LEN, // overhead + POLY1305_TAG_LEN, // max tag length + 1, // seal_scatter_supports_extra_in + + aead_chacha20_poly1305_init, + NULL, // init_with_direction + aead_chacha20_poly1305_cleanup, + NULL /* open */, + aead_chacha20_poly1305_seal_scatter, + aead_chacha20_poly1305_open_gather, + NULL, // get_iv + NULL, // tag_len +}; + +static const EVP_AEAD aead_xchacha20_poly1305 = { + 32, // key len + 24, // nonce len + POLY1305_TAG_LEN, // overhead + POLY1305_TAG_LEN, // max tag length + 1, // seal_scatter_supports_extra_in + + aead_chacha20_poly1305_init, + NULL, // init_with_direction + aead_chacha20_poly1305_cleanup, + NULL /* open */, + aead_xchacha20_poly1305_seal_scatter, + aead_xchacha20_poly1305_open_gather, + NULL, // get_iv + NULL, // tag_len +}; + +const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { + return &aead_chacha20_poly1305; +} + +const EVP_AEAD *EVP_aead_xchacha20_poly1305(void) { + return &aead_xchacha20_poly1305; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_des.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_des.c new file mode 100644 index 00000000..669fef80 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_des.c @@ -0,0 +1,258 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include + +#include "internal.h" + + +typedef struct { + union { + double align; + DES_key_schedule ks; + } ks; +} EVP_DES_KEY; + +static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_set_key(deskey, &dat->ks.ks); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_ncbc_encrypt(in, out, in_len, &dat->ks.ks, (DES_cblock *)ctx->iv, + ctx->encrypt); + + return 1; +} + +static const EVP_CIPHER evp_des_cbc = { + /* nid = */ NID_des_cbc, + /* block_size = */ 8, + /* key_len = */ 8, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(EVP_DES_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_init_key, + /* cipher = */ des_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_cbc(void) { return &evp_des_cbc; } + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), + &dat->ks.ks, ctx->encrypt); + } + return 1; +} + +static const EVP_CIPHER evp_des_ecb = { + /* nid = */ NID_des_ecb, + /* block_size = */ 8, + /* key_len = */ 8, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(EVP_DES_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_init_key, + /* cipher = */ des_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ecb(void) { return &evp_des_ecb; } + +typedef struct { + union { + double align; + DES_key_schedule ks[3]; + } ks; +} DES_EDE_KEY; + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[2], &dat->ks.ks[2]); + + return 1; +} + +static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; + + DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], + &dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); + + return 1; +} + +static const EVP_CIPHER evp_des_ede3_cbc = { + /* nid = */ NID_des_ede3_cbc, + /* block_size = */ 8, + /* key_len = */ 24, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_ede3_init_key, + /* cipher = */ des_ede3_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &evp_des_ede3_cbc; } + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[0], &dat->ks.ks[2]); + + return 1; +} + +static const EVP_CIPHER evp_des_ede_cbc = { + /* nid = */ NID_des_ede_cbc, + /* block_size = */ 8, + /* key_len = */ 16, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_ede_init_key, + /* cipher = */ des_ede3_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede_cbc(void) { return &evp_des_ede_cbc; } + +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2], + ctx->encrypt); + } + return 1; +} + +static const EVP_CIPHER evp_des_ede = { + /* nid = */ NID_des_ede_ecb, + /* block_size = */ 8, + /* key_len = */ 16, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_ede_init_key, + /* cipher = */ des_ede_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede(void) { return &evp_des_ede; } + +static const EVP_CIPHER evp_des_ede3 = { + /* nid = */ NID_des_ede3_ecb, + /* block_size = */ 8, + /* key_len = */ 24, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_ede3_init_key, + /* cipher = */ des_ede_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede3(void) { return &evp_des_ede3; } + +const EVP_CIPHER *EVP_des_ede3_ecb(void) { return EVP_des_ede3(); } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_null.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_null.c new file mode 100644 index 00000000..5d576fb7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_null.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "../internal.h" + + +static int null_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + return 1; +} + +static int null_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in != out) { + OPENSSL_memcpy(out, in, in_len); + } + return 1; +} + +static const EVP_CIPHER n_cipher = { + NID_undef, 1 /* block size */, 0 /* key_len */, 0 /* iv_len */, + 0 /* ctx_size */, 0 /* flags */, NULL /* app_data */, null_init_key, + null_cipher, NULL /* cleanup */, NULL /* ctrl */, +}; + +const EVP_CIPHER *EVP_enc_null(void) { return &n_cipher; } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc2.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc2.c new file mode 100644 index 00000000..a6fb29b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc2.c @@ -0,0 +1,462 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +#include "../internal.h" + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \ + } while (0) + +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + } \ + } while (0) + +typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY; + +static void RC2_encrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(l >> 16L); + + n = 3; + i = 5; + + p0 = p1 = &key->data[0]; + for (;;) { + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; + x0 = (t << 1) | (t >> 15); + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; + x1 = (t << 2) | (t >> 14); + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; + x2 = (t << 3) | (t >> 13); + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; + x3 = (t << 5) | (t >> 11); + + if (--i == 0) { + if (--n == 0) { + break; + } + i = (n == 2) ? 6 : 5; + + x0 += p1[x3 & 0x3f]; + x1 += p1[x0 & 0x3f]; + x2 += p1[x1 & 0x3f]; + x3 += p1[x2 & 0x3f]; + } + } + + d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_decrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(l >> 16L); + + n = 3; + i = 5; + + p0 = &key->data[63]; + p1 = &key->data[0]; + for (;;) { + t = ((x3 << 11) | (x3 >> 5)) & 0xffff; + x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; + t = ((x2 << 13) | (x2 >> 3)) & 0xffff; + x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; + t = ((x1 << 14) | (x1 >> 2)) & 0xffff; + x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; + t = ((x0 << 15) | (x0 >> 1)) & 0xffff; + x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; + + if (--i == 0) { + if (--n == 0) { + break; + } + i = (n == 2) ? 6 : 5; + + x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; + x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; + x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; + x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; + } + } + + d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + RC2_KEY *ks, uint8_t *iv, int encrypt) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + long l = length; + uint32_t tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin[0] = tin[1] = 0; +} + +static const uint8_t key_table[256] = { + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, + 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, + 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, + 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f, + 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, + 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde, + 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, + 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85, + 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, + 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b, + 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, + 0xfe, 0x7f, 0xc1, 0xad, +}; + +static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) { + int i, j; + uint8_t *k; + uint16_t *ki; + unsigned int c, d; + + k = (uint8_t *)&key->data[0]; + *k = 0; // for if there is a zero length key + + if (len > 128) { + len = 128; + } + if (bits <= 0) { + bits = 1024; + } + if (bits > 1024) { + bits = 1024; + } + + for (i = 0; i < len; i++) { + k[i] = data[i]; + } + + // expand table + d = k[len - 1]; + j = 0; + for (i = len; i < 128; i++, j++) { + d = key_table[(k[j] + d) & 0xff]; + k[i] = d; + } + + // hmm.... key reduction to 'bits' bits + + j = (bits + 7) >> 3; + i = 128 - j; + c = (0xff >> (-bits & 0x07)); + + d = key_table[k[i] & c]; + k[i] = d; + while (i--) { + d = key_table[k[i + j] ^ d]; + k[i] = d; + } + + // copy from bytes into uint16_t's + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) { + *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; + } +} + +typedef struct { + int key_bits; // effective key bits + RC2_KEY ks; // key schedule +} EVP_RC2_KEY; + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data; + RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key, + rc2_key->key_bits); + return 1; +} + +static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + static const size_t kChunkSize = 0x10000; + + while (inl >= kChunkSize) { + RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt); + inl -= kChunkSize; + in += kChunkSize; + out += kChunkSize; + } + if (inl) { + RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt); + } + return 1; +} + +static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + return 1; + case EVP_CTRL_SET_RC2_KEY_BITS: + // Should be overridden by later call to |EVP_CTRL_INIT|, but + // people call it, so it may as well work. + key->key_bits = arg; + return 1; + + default: + return -1; + } +} + +static const EVP_CIPHER rc2_40_cbc = { + NID_rc2_40_cbc, + 8 /* block size */, + 5 /* 40 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_40_cbc(void) { + return &rc2_40_cbc; +} + +static const EVP_CIPHER rc2_cbc = { + NID_rc2_cbc, + 8 /* block size */, + 16 /* 128 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_cbc(void) { + return &rc2_cbc; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc4.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc4.c new file mode 100644 index 00000000..5963f56d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc4.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +#include +#include +#include + + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4_set_key(rc4key, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int rc4_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4(rc4key, in_len, in, out); + return 1; +} + +static const EVP_CIPHER rc4 = { + NID_rc4, 1 /* block_size */, 16 /* key_size */, + 0 /* iv_len */, sizeof(RC4_KEY), EVP_CIPH_VARIABLE_LENGTH, + NULL /* app_data */, rc4_init_key, rc4_cipher, + NULL /* cleanup */, NULL /* ctrl */, }; + +const EVP_CIPHER *EVP_rc4(void) { return &rc4; } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_tls.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_tls.c new file mode 100644 index 00000000..67c79187 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/e_tls.c @@ -0,0 +1,601 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" +#include "internal.h" + + +typedef struct { + EVP_CIPHER_CTX cipher_ctx; + HMAC_CTX hmac_ctx; + // mac_key is the portion of the key used for the MAC. It is retained + // separately for the constant-time CBC code. + uint8_t mac_key[EVP_MAX_MD_SIZE]; + uint8_t mac_key_len; + // implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit + // IV. + char implicit_iv; +} AEAD_TLS_CTX; + +OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, + "mac_key_len does not fit in uint8_t"); + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(AEAD_TLS_CTX), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(AEAD_TLS_CTX), + "AEAD state has insufficient alignment"); +#endif + +static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); + HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); +} + +static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir, + const EVP_CIPHER *cipher, const EVP_MD *md, + char implicit_iv) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && + tag_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); + return 0; + } + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; + } + + size_t mac_key_len = EVP_MD_size(md); + size_t enc_key_len = EVP_CIPHER_key_length(cipher); + assert(mac_key_len + enc_key_len + + (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); + + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); + HMAC_CTX_init(&tls_ctx->hmac_ctx); + assert(mac_key_len <= EVP_MAX_MD_SIZE); + OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len); + tls_ctx->mac_key_len = (uint8_t)mac_key_len; + tls_ctx->implicit_iv = implicit_iv; + + if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], + implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, + dir == evp_aead_seal) || + !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { + aead_tls_cleanup(ctx); + return 0; + } + EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0); + + return 1; +} + +static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, + const size_t extra_in_len) { + assert(extra_in_len == 0); + const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + + const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx); + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { + // The NULL cipher. + return hmac_len; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + // An overflow of |in_len + hmac_len| doesn't affect the result mod + // |block_size|, provided that |block_size| is a smaller power of two. + assert(block_size != 0 && (block_size & (block_size - 1)) == 0); + const size_t pad_len = block_size - (in_len + hmac_len) % block_size; + return hmac_len + pad_len; +} + +static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + const size_t max_out_tag_len, + const uint8_t *nonce, const size_t nonce_len, + const uint8_t *in, const size_t in_len, + const uint8_t *extra_in, + const size_t extra_in_len, const uint8_t *ad, + const size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + + if (!tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < aead_tls_tag_len(ctx, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_extra[2]; + ad_extra[0] = (uint8_t)(in_len >> 8); + ad_extra[1] = (uint8_t)(in_len & 0xff); + + // Compute the MAC. This must be first in case the operation is being done + // in-place. + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Encrypt the input. + int len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + + unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + + // Feed the MAC into the cipher in two steps. First complete the final partial + // block from encrypting the input and split the result between |out| and + // |out_tag|. Then feed the rest. + + const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + if (early_mac_len != 0) { + assert(len + block_size - early_mac_len == in_len); + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + int buf_len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, buf, &buf_len, mac, + (int)early_mac_len)) { + return 0; + } + assert(buf_len == (int)block_size); + OPENSSL_memcpy(out + len, buf, block_size - early_mac_len); + OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len); + } + size_t tag_len = early_mac_len; + + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + mac + tag_len, mac_len - tag_len)) { + return 0; + } + tag_len += len; + + if (block_size > 1) { + assert(block_size <= 256); + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE); + + // Compute padding and feed that into the cipher. + uint8_t padding[256]; + unsigned padding_len = block_size - ((in_len + mac_len) % block_size); + OPENSSL_memset(padding, padding_len - 1, padding_len); + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + padding, (int)padding_len)) { + return 0; + } + tag_len += len; + } + + if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len)) { + return 0; + } + assert(len == 0); // Padding is explicit. + assert(tag_len == aead_tls_tag_len(ctx, in_len, extra_in_len)); + + *out_tag_len = tag_len; + return 1; +} + +static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + + if (tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (max_out_len < in_len) { + // This requires that the caller provide space for the MAC, even though it + // will always be removed on return. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Decrypt to get the plaintext + MAC + padding. + size_t total = 0; + int len; + if (!EVP_DecryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + total += len; + if (!EVP_DecryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) { + return 0; + } + total += len; + assert(total == in_len); + + CONSTTIME_SECRET(out, total); + + // Remove CBC padding. Code from here on is timing-sensitive with respect to + // |padding_ok| and |data_plus_mac_len| for CBC ciphers. + size_t data_plus_mac_len; + crypto_word_t padding_ok; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { + if (!EVP_tls_cbc_remove_padding( + &padding_ok, &data_plus_mac_len, out, total, + EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), + HMAC_size(&tls_ctx->hmac_ctx))) { + // Publicly invalid. This can be rejected in non-constant time. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } else { + padding_ok = CONSTTIME_TRUE_W; + data_plus_mac_len = total; + // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has + // already been checked against the MAC size at the top of the function. + assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); + } + size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + + // At this point, if the padding is valid, the first |data_plus_mac_len| bytes + // after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is + // still large enough to extract a MAC, but it will be irrelevant. + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_fixed[13]; + OPENSSL_memcpy(ad_fixed, ad, 11); + ad_fixed[11] = (uint8_t)(data_len >> 8); + ad_fixed[12] = (uint8_t)(data_len & 0xff); + ad_len += 2; + + // Compute the MAC and extract the one in the record. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len; + uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; + uint8_t *record_mac; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + ad_fixed, out, data_len, total, + tls_ctx->mac_key, tls_ctx->mac_key_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + + record_mac = record_mac_tmp; + EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); + } else { + // We should support the constant-time path for all CBC-mode ciphers + // implemented. + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); + + unsigned mac_len_u; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { + return 0; + } + mac_len = mac_len_u; + + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + record_mac = &out[data_len]; + } + + // Perform the MAC check and the padding check in constant-time. It should be + // safe to simply perform the padding check first, but it would not be under a + // different choice of MAC location on padding failure. See + // EVP_tls_cbc_remove_padding. + crypto_word_t good = + constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0); + good &= padding_ok; + CONSTTIME_DECLASSIFY(&good, sizeof(good)); + if (!good) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + CONSTTIME_DECLASSIFY(&data_len, sizeof(data_len)); + CONSTTIME_DECLASSIFY(out, data_len); + + // End of timing-sensitive code. + + *out_len = data_len; + return 1; +} + +static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_128_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 1); +} + +static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_256_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 1); +} + +static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 0); +} + +static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 1); +} + +static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_iv_len) { + const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx); + if (iv_len <= 1) { + return 0; + } + + *out_iv = tls_ctx->cipher_ctx.iv; + *out_iv_len = iv_len; + return 1; +} + +static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), + EVP_sha1(), 1 /* implicit iv */); +} + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 16, // key len (SHA1 + AES128) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 16 + 16, // key len (SHA1 + AES128 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 32, // key len (SHA1 + AES256) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 32 + 16, // key len (SHA1 + AES256 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 24, // key len (SHA1 + 3DES) + 8, // nonce len (IV) + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 24 + 8, // key len (SHA1 + 3DES + IV) + 0, // nonce len + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_null_sha1_tls = { + SHA_DIGEST_LENGTH, // key len + 0, // nonce len + SHA_DIGEST_LENGTH, // overhead (SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_null_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) { + return &aead_aes_128_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_128_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) { + return &aead_aes_256_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_256_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) { + return &aead_des_ede3_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) { + return &aead_des_ede3_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/internal.h new file mode 100644 index 00000000..1ef3978a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/internal.h @@ -0,0 +1,224 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H + +#include + +#include +#include + +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC +// record in |in|. This decrypted record should not include any "decrypted" +// explicit IV. If the record is publicly invalid, it returns zero. Otherwise, +// it returns one and sets |*out_padding_ok| to all ones (0xfff..f) if the +// padding is valid and zero otherwise. It then sets |*out_len| to the length +// with the padding removed or |in_len| if invalid. +// +// If the function returns one, it runs in time independent of the contents of +// |in|. It is also guaranteed that |*out_len| >= |mac_size|, satisfying +// |EVP_tls_cbc_copy_mac|'s precondition. +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size); + +// EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first +// |in_len| bytes of |in| to |out| in constant time (independent of the concrete +// value of |in_len|, which may vary within a 256-byte window). |in| must point +// to a buffer of |orig_len| bytes. +// +// On entry: +// orig_len >= in_len >= md_size +// md_size <= EVP_MAX_MD_SIZE +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len); + +// EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function +// which EVP_tls_cbc_digest_record supports. +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md); + +// EVP_sha1_final_with_secret_suffix computes the result of hashing |len| bytes +// from |in| to |ctx| and writes the resulting hash to |out|. |len| is treated +// as secret and must be at most |max_len|, which is treated as public. |in| +// must point to a buffer of at least |max_len| bytes. It returns one on success +// and zero if inputs are too long. +// +// This function is exported for unit tests. +OPENSSL_EXPORT int EVP_sha1_final_with_secret_suffix( + SHA_CTX *ctx, uint8_t out[SHA_DIGEST_LENGTH], const uint8_t *in, size_t len, + size_t max_len); + +// EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS +// record. +// +// md: the hash function used in the HMAC. +// EVP_tls_cbc_record_digest_supported must return true for this hash. +// md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. +// md_out_size: the number of output bytes is written here. +// header: the 13-byte, TLS record header. +// data: the record data itself +// data_size: the secret, reported length of the data once the padding and MAC +// have been removed. +// data_plus_mac_plus_padding_size: the public length of the whole +// record, including padding. +// +// On entry: by virtue of having been through one of the remove_padding +// functions, above, we know that data_plus_mac_size is large enough to contain +// a padding byte and MAC. (If the padding was invalid, it might contain the +// padding too. ) +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length); + +#define POLY1305_TAG_LEN 16 + +// For convenience (the x86_64 calling convention allows only six parameters in +// registers), the final parameter for the assembly functions is both an input +// and output parameter. +union chacha20_poly1305_open_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +union chacha20_poly1305_seal_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + const uint8_t *extra_ciphertext; + size_t extra_ciphertext_len; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +OPENSSL_STATIC_ASSERT(sizeof(union chacha20_poly1305_open_data) == 48, + "wrong chacha20_poly1305_open_data size"); +OPENSSL_STATIC_ASSERT(sizeof(union chacha20_poly1305_seal_data) == 48 + 8 + 8, + "wrong chacha20_poly1305_seal_data size"); + +OPENSSL_INLINE int chacha20_poly1305_asm_capable(void) { + return CRYPTO_is_SSE4_1_capable(); +} + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It decrypts +// |plaintext_len| bytes from |ciphertext| and writes them to |out_plaintext|. +// Additional input parameters are passed in |aead_data->in|. On exit, it will +// write calculated tag value to |aead_data->out.tag|, which the caller must +// check. +extern void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, + union chacha20_poly1305_open_data *data); + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It encrypts +// |plaintext_len| bytes from |plaintext| and writes them to |out_ciphertext|. +// Additional input parameters are passed in |aead_data->in|. The calculated tag +// value is over the computed ciphertext concatenated with |extra_ciphertext| +// and written to |aead_data->out.tag|. +extern void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, + union chacha20_poly1305_seal_data *data); +#else + +OPENSSL_INLINE int chacha20_poly1305_asm_capable(void) { return 0; } + +OPENSSL_INLINE void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, + union chacha20_poly1305_open_data *data) { + abort(); +} + +OPENSSL_INLINE void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, + union chacha20_poly1305_seal_data *data) { + abort(); +} +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/tls_cbc.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/tls_cbc.c new file mode 100644 index 00000000..eb3b79f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cipher_extra/tls_cbc.c @@ -0,0 +1,338 @@ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" +#include "../fipsmodule/cipher/internal.h" + + +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size) { + const size_t overhead = 1 /* padding length byte */ + mac_size; + + // These lengths are all public so we can test them in non-constant time. + if (overhead > in_len) { + return 0; + } + + size_t padding_length = in[in_len - 1]; + + crypto_word_t good = constant_time_ge_w(in_len, overhead + padding_length); + // The padding consists of a length byte at the end of the record and + // then that many bytes of padding, all with the same value as the + // length byte. Thus, with the length byte included, there are i+1 + // bytes of padding. + // + // We can't check just |padding_length+1| bytes because that leaks + // decrypted information. Therefore we always have to check the maximum + // amount of padding possible. (Again, the length of the record is + // public information so we can use it.) + size_t to_check = 256; // maximum amount of padding, inc length byte. + if (to_check > in_len) { + to_check = in_len; + } + + for (size_t i = 0; i < to_check; i++) { + uint8_t mask = constant_time_ge_8(padding_length, i); + uint8_t b = in[in_len - 1 - i]; + // The final |padding_length+1| bytes should all have the value + // |padding_length|. Therefore the XOR should be zero. + good &= ~(mask & (padding_length ^ b)); + } + + // If any of the final |padding_length+1| bytes had the wrong value, + // one or more of the lower eight bits of |good| will be cleared. + good = constant_time_eq_w(0xff, good & 0xff); + + // Always treat |padding_length| as zero on error. If, assuming block size of + // 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16 + // and returned -1, distinguishing good MAC and bad padding from bad MAC and + // bad padding would give POODLE's padding oracle. + padding_length = good & (padding_length + 1); + *out_len = in_len - padding_length; + *out_padding_ok = good; + return 1; +} + +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len) { + uint8_t rotated_mac1[EVP_MAX_MD_SIZE], rotated_mac2[EVP_MAX_MD_SIZE]; + uint8_t *rotated_mac = rotated_mac1; + uint8_t *rotated_mac_tmp = rotated_mac2; + + // mac_end is the index of |in| just after the end of the MAC. + size_t mac_end = in_len; + size_t mac_start = mac_end - md_size; + + assert(orig_len >= in_len); + assert(in_len >= md_size); + assert(md_size <= EVP_MAX_MD_SIZE); + assert(md_size > 0); + + // scan_start contains the number of bytes that we can ignore because + // the MAC's position can only vary by 255 bytes. + size_t scan_start = 0; + // This information is public so it's safe to branch based on it. + if (orig_len > md_size + 255 + 1) { + scan_start = orig_len - (md_size + 255 + 1); + } + + size_t rotate_offset = 0; + uint8_t mac_started = 0; + OPENSSL_memset(rotated_mac, 0, md_size); + for (size_t i = scan_start, j = 0; i < orig_len; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + crypto_word_t is_mac_start = constant_time_eq_w(i, mac_start); + mac_started |= is_mac_start; + uint8_t mac_ended = constant_time_ge_8(i, mac_end); + rotated_mac[j] |= in[i] & mac_started & ~mac_ended; + // Save the offset that |mac_start| is mapped to. + rotate_offset |= j & is_mac_start; + } + + // Now rotate the MAC. We rotate in log(md_size) steps, one for each bit + // position. + for (size_t offset = 1; offset < md_size; offset <<= 1, rotate_offset >>= 1) { + // Rotate by |offset| iff the corresponding bit is set in + // |rotate_offset|, placing the result in |rotated_mac_tmp|. + const uint8_t skip_rotate = (rotate_offset & 1) - 1; + for (size_t i = 0, j = offset; i < md_size; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + rotated_mac_tmp[i] = + constant_time_select_8(skip_rotate, rotated_mac[i], rotated_mac[j]); + } + + // Swap pointers so |rotated_mac| contains the (possibly) rotated value. + // Note the number of iterations and thus the identity of these pointers is + // public information. + uint8_t *tmp = rotated_mac; + rotated_mac = rotated_mac_tmp; + rotated_mac_tmp = tmp; + } + + OPENSSL_memcpy(out, rotated_mac, md_size); +} + +int EVP_sha1_final_with_secret_suffix(SHA_CTX *ctx, + uint8_t out[SHA_DIGEST_LENGTH], + const uint8_t *in, size_t len, + size_t max_len) { + // Bound the input length so |total_bits| below fits in four bytes. This is + // redundant with TLS record size limits. This also ensures |input_idx| below + // does not overflow. + size_t max_len_bits = max_len << 3; + if (ctx->Nh != 0 || + (max_len_bits >> 3) != max_len || // Overflow + ctx->Nl + max_len_bits < max_len_bits || + ctx->Nl + max_len_bits > UINT32_MAX) { + return 0; + } + + // We need to hash the following into |ctx|: + // + // - ctx->data[:ctx->num] + // - in[:len] + // - A 0x80 byte + // - However many zero bytes are needed to pad up to a block. + // - Eight bytes of length. + size_t num_blocks = (ctx->num + len + 1 + 8 + SHA_CBLOCK - 1) >> 6; + size_t last_block = num_blocks - 1; + size_t max_blocks = (ctx->num + max_len + 1 + 8 + SHA_CBLOCK - 1) >> 6; + + // The bounds above imply |total_bits| fits in four bytes. + size_t total_bits = ctx->Nl + (len << 3); + uint8_t length_bytes[4]; + length_bytes[0] = (uint8_t)(total_bits >> 24); + length_bytes[1] = (uint8_t)(total_bits >> 16); + length_bytes[2] = (uint8_t)(total_bits >> 8); + length_bytes[3] = (uint8_t)total_bits; + + // We now construct and process each expected block in constant-time. + uint8_t block[SHA_CBLOCK] = {0}; + uint32_t result[5] = {0}; + // input_idx is the index into |in| corresponding to the current block. + // However, we allow this index to overflow beyond |max_len|, to simplify the + // 0x80 byte. + size_t input_idx = 0; + for (size_t i = 0; i < max_blocks; i++) { + // Fill |block| with data from the partial block in |ctx| and |in|. We copy + // as if we were hashing up to |max_len| and then zero the excess later. + size_t block_start = 0; + if (i == 0) { + OPENSSL_memcpy(block, ctx->data, ctx->num); + block_start = ctx->num; + } + if (input_idx < max_len) { + size_t to_copy = SHA_CBLOCK - block_start; + if (to_copy > max_len - input_idx) { + to_copy = max_len - input_idx; + } + OPENSSL_memcpy(block + block_start, in + input_idx, to_copy); + } + + // Zero any bytes beyond |len| and add the 0x80 byte. + for (size_t j = block_start; j < SHA_CBLOCK; j++) { + // input[idx] corresponds to block[j]. + size_t idx = input_idx + j - block_start; + // The barriers on |len| are not strictly necessary. However, without + // them, GCC compiles this code by incorporating |len| into the loop + // counter and subtracting it out later. This is still constant-time, but + // it frustrates attempts to validate this. + uint8_t is_in_bounds = constant_time_lt_8(idx, value_barrier_w(len)); + uint8_t is_padding_byte = constant_time_eq_8(idx, value_barrier_w(len)); + block[j] &= is_in_bounds; + block[j] |= 0x80 & is_padding_byte; + } + + input_idx += SHA_CBLOCK - block_start; + + // Fill in the length if this is the last block. + crypto_word_t is_last_block = constant_time_eq_w(i, last_block); + for (size_t j = 0; j < 4; j++) { + block[SHA_CBLOCK - 4 + j] |= is_last_block & length_bytes[j]; + } + + // Process the block and save the hash state if it is the final value. + SHA1_Transform(ctx, block); + for (size_t j = 0; j < 5; j++) { + result[j] |= is_last_block & ctx->h[j]; + } + } + + // Write the output. + for (size_t i = 0; i < 5; i++) { + CRYPTO_store_u32_be(out + 4 * i, result[i]); + } + return 1; +} + +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { + return EVP_MD_type(md) == NID_sha1; +} + +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { + if (EVP_MD_type(md) != NID_sha1) { + // EVP_tls_cbc_record_digest_supported should have been called first to + // check that the hash function is supported. + assert(0); + *md_out_size = 0; + return 0; + } + + if (mac_secret_length > SHA_CBLOCK) { + // HMAC pads small keys with zeros and hashes large keys down. This function + // should never reach the large key case. + assert(0); + return 0; + } + + // Compute the initial HMAC block. + uint8_t hmac_pad[SHA_CBLOCK]; + OPENSSL_memset(hmac_pad, 0, sizeof(hmac_pad)); + OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); + for (size_t i = 0; i < SHA_CBLOCK; i++) { + hmac_pad[i] ^= 0x36; + } + + SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, hmac_pad, SHA_CBLOCK); + SHA1_Update(&ctx, header, 13); + + // There are at most 256 bytes of padding, so we can compute the public + // minimum length for |data_size|. + size_t min_data_size = 0; + if (data_plus_mac_plus_padding_size > SHA_DIGEST_LENGTH + 256) { + min_data_size = data_plus_mac_plus_padding_size - SHA_DIGEST_LENGTH - 256; + } + + // Hash the public minimum length directly. This reduces the number of blocks + // that must be computed in constant-time. + SHA1_Update(&ctx, data, min_data_size); + + // Hash the remaining data without leaking |data_size|. + uint8_t mac_out[SHA_DIGEST_LENGTH]; + if (!EVP_sha1_final_with_secret_suffix( + &ctx, mac_out, data + min_data_size, data_size - min_data_size, + data_plus_mac_plus_padding_size - min_data_size)) { + return 0; + } + + // Complete the HMAC in the standard manner. + SHA1_Init(&ctx); + for (size_t i = 0; i < SHA_CBLOCK; i++) { + hmac_pad[i] ^= 0x6a; + } + + SHA1_Update(&ctx, hmac_pad, SHA_CBLOCK); + SHA1_Update(&ctx, mac_out, SHA_DIGEST_LENGTH); + SHA1_Final(md_out, &ctx); + *md_out_size = SHA_DIGEST_LENGTH; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cmac/cmac.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cmac/cmac.c new file mode 100644 index 00000000..286c7003 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cmac/cmac.c @@ -0,0 +1,278 @@ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include + +#include +#include +#include + +#include "../internal.h" + + +struct cmac_ctx_st { + EVP_CIPHER_CTX cipher_ctx; + // k1 and k2 are the CMAC subkeys. See + // https://tools.ietf.org/html/rfc4493#section-2.3 + uint8_t k1[AES_BLOCK_SIZE]; + uint8_t k2[AES_BLOCK_SIZE]; + // Last (possibly partial) scratch + uint8_t block[AES_BLOCK_SIZE]; + // block_used contains the number of valid bytes in |block|. + unsigned block_used; +}; + +static void CMAC_CTX_init(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_init(&ctx->cipher_ctx); +} + +static void CMAC_CTX_cleanup(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(&ctx->cipher_ctx); + OPENSSL_cleanse(ctx->k1, sizeof(ctx->k1)); + OPENSSL_cleanse(ctx->k2, sizeof(ctx->k2)); + OPENSSL_cleanse(ctx->block, sizeof(ctx->block)); +} + +int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len) { + const EVP_CIPHER *cipher; + switch (key_len) { + case 16: + cipher = EVP_aes_128_cbc(); + break; + case 32: + cipher = EVP_aes_256_cbc(); + break; + default: + return 0; + } + + size_t scratch_out_len; + CMAC_CTX ctx; + CMAC_CTX_init(&ctx); + + const int ok = CMAC_Init(&ctx, key, key_len, cipher, NULL /* engine */) && + CMAC_Update(&ctx, in, in_len) && + CMAC_Final(&ctx, out, &scratch_out_len); + + CMAC_CTX_cleanup(&ctx); + return ok; +} + +CMAC_CTX *CMAC_CTX_new(void) { + CMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); + if (ctx != NULL) { + CMAC_CTX_init(ctx); + } + return ctx; +} + +void CMAC_CTX_free(CMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + CMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) { + if (!EVP_CIPHER_CTX_copy(&out->cipher_ctx, &in->cipher_ctx)) { + return 0; + } + OPENSSL_memcpy(out->k1, in->k1, AES_BLOCK_SIZE); + OPENSSL_memcpy(out->k2, in->k2, AES_BLOCK_SIZE); + OPENSSL_memcpy(out->block, in->block, AES_BLOCK_SIZE); + out->block_used = in->block_used; + return 1; +} + +// binary_field_mul_x_128 treats the 128 bits at |in| as an element of GF(2¹²⁸) +// with a hard-coded reduction polynomial and sets |out| as x times the input. +// +// See https://tools.ietf.org/html/rfc4493#section-2.3 +static void binary_field_mul_x_128(uint8_t out[16], const uint8_t in[16]) { + unsigned i; + + // Shift |in| to left, including carry. + for (i = 0; i < 15; i++) { + out[i] = (in[i] << 1) | (in[i+1] >> 7); + } + + // If MSB set fixup with R. + const uint8_t carry = in[0] >> 7; + out[i] = (in[i] << 1) ^ ((0 - carry) & 0x87); +} + +// binary_field_mul_x_64 behaves like |binary_field_mul_x_128| but acts on an +// element of GF(2⁶⁴). +// +// See https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf +static void binary_field_mul_x_64(uint8_t out[8], const uint8_t in[8]) { + unsigned i; + + // Shift |in| to left, including carry. + for (i = 0; i < 7; i++) { + out[i] = (in[i] << 1) | (in[i+1] >> 7); + } + + // If MSB set fixup with R. + const uint8_t carry = in[0] >> 7; + out[i] = (in[i] << 1) ^ ((0 - carry) & 0x1b); +} + +static const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0}; + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine) { + uint8_t scratch[AES_BLOCK_SIZE]; + + size_t block_size = EVP_CIPHER_block_size(cipher); + if ((block_size != AES_BLOCK_SIZE && block_size != 8 /* 3-DES */) || + EVP_CIPHER_key_length(cipher) != key_len || + !EVP_EncryptInit_ex(&ctx->cipher_ctx, cipher, NULL, key, kZeroIV) || + !EVP_Cipher(&ctx->cipher_ctx, scratch, kZeroIV, block_size) || + // Reset context again ready for first data. + !EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV)) { + return 0; + } + + if (block_size == AES_BLOCK_SIZE) { + binary_field_mul_x_128(ctx->k1, scratch); + binary_field_mul_x_128(ctx->k2, ctx->k1); + } else { + binary_field_mul_x_64(ctx->k1, scratch); + binary_field_mul_x_64(ctx->k2, ctx->k1); + } + ctx->block_used = 0; + + return 1; +} + +int CMAC_Reset(CMAC_CTX *ctx) { + ctx->block_used = 0; + return EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV); +} + +int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) { + size_t block_size = EVP_CIPHER_CTX_block_size(&ctx->cipher_ctx); + assert(block_size <= AES_BLOCK_SIZE); + uint8_t scratch[AES_BLOCK_SIZE]; + + if (ctx->block_used > 0) { + size_t todo = block_size - ctx->block_used; + if (in_len < todo) { + todo = in_len; + } + + OPENSSL_memcpy(ctx->block + ctx->block_used, in, todo); + in += todo; + in_len -= todo; + ctx->block_used += todo; + + // If |in_len| is zero then either |ctx->block_used| is less than + // |block_size|, in which case we can stop here, or |ctx->block_used| is + // exactly |block_size| but there's no more data to process. In the latter + // case we don't want to process this block now because it might be the last + // block and that block is treated specially. + if (in_len == 0) { + return 1; + } + + assert(ctx->block_used == block_size); + + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, ctx->block, block_size)) { + return 0; + } + } + + // Encrypt all but one of the remaining blocks. + while (in_len > block_size) { + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, in, block_size)) { + return 0; + } + in += block_size; + in_len -= block_size; + } + + OPENSSL_memcpy(ctx->block, in, in_len); + ctx->block_used = in_len; + + return 1; +} + +int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) { + size_t block_size = EVP_CIPHER_CTX_block_size(&ctx->cipher_ctx); + assert(block_size <= AES_BLOCK_SIZE); + + *out_len = block_size; + if (out == NULL) { + return 1; + } + + const uint8_t *mask = ctx->k1; + + if (ctx->block_used != block_size) { + // If the last block is incomplete, terminate it with a single 'one' bit + // followed by zeros. + ctx->block[ctx->block_used] = 0x80; + OPENSSL_memset(ctx->block + ctx->block_used + 1, 0, + block_size - (ctx->block_used + 1)); + + mask = ctx->k2; + } + + for (unsigned i = 0; i < block_size; i++) { + out[i] = ctx->block[i] ^ mask[i]; + } + + return EVP_Cipher(&ctx->cipher_ctx, out, out, block_size); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf.c new file mode 100644 index 00000000..52960c45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf.c @@ -0,0 +1,821 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "conf_def.h" +#include "internal.h" +#include "../internal.h" +#include "../lhash/internal.h" + + +DEFINE_LHASH_OF(CONF_VALUE) + +struct conf_st { + LHASH_OF(CONF_VALUE) *data; +}; + +static const char kDefaultSectionName[] = "default"; + +// The maximum length we can grow a value to after variable expansion. 64k +// should be more than enough for all reasonable uses. +#define MAX_CONF_VALUE_LENGTH 65536 + +static uint32_t conf_value_hash(const CONF_VALUE *v) { + const uint32_t section_hash = v->section ? OPENSSL_strhash(v->section) : 0; + const uint32_t name_hash = v->name ? OPENSSL_strhash(v->name) : 0; + return (section_hash << 2) ^ name_hash; +} + +static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) { + int i; + + if (a->section != b->section) { + i = strcmp(a->section, b->section); + if (i) { + return i; + } + } + + if (a->name != NULL && b->name != NULL) { + return strcmp(a->name, b->name); + } else if (a->name == b->name) { + return 0; + } else { + return (a->name == NULL) ? -1 : 1; + } +} + +CONF *NCONF_new(void *method) { + CONF *conf; + + if (method != NULL) { + return NULL; + } + + conf = OPENSSL_malloc(sizeof(CONF)); + if (conf == NULL) { + return NULL; + } + + conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); + if (conf->data == NULL) { + OPENSSL_free(conf); + return NULL; + } + + return conf; +} + +CONF_VALUE *CONF_VALUE_new(void) { + CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE)); + if (!v) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(v, 0, sizeof(CONF_VALUE)); + return v; +} + +static void value_free_contents(CONF_VALUE *value) { + if (value->section) { + OPENSSL_free(value->section); + } + if (value->name) { + OPENSSL_free(value->name); + if (value->value) { + OPENSSL_free(value->value); + } + } else { + if (value->value) { + sk_CONF_VALUE_free((STACK_OF(CONF_VALUE)*)value->value); + } + } +} + +static void value_free(CONF_VALUE *value) { + value_free_contents(value); + OPENSSL_free(value); +} + +static void value_free_arg(CONF_VALUE *value, void *arg) { value_free(value); } + +void NCONF_free(CONF *conf) { + if (conf == NULL || conf->data == NULL) { + return; + } + + lh_CONF_VALUE_doall_arg(conf->data, value_free_arg, NULL); + lh_CONF_VALUE_free(conf->data); + OPENSSL_free(conf); +} + +static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) { + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0; + CONF_VALUE *v = NULL, *old_value; + + sk = sk_CONF_VALUE_new_null(); + v = CONF_VALUE_new(); + if (sk == NULL || v == NULL) { + goto err; + } + v->section = OPENSSL_strdup(section); + if (v->section == NULL) { + goto err; + } + + v->name = NULL; + v->value = (char *)sk; + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, v)) { + goto err; + } + if (old_value) { + value_free(old_value); + } + ok = 1; + +err: + if (!ok) { + if (sk != NULL) { + sk_CONF_VALUE_free(sk); + } + if (v != NULL) { + OPENSSL_free(v); + } + v = NULL; + } + return v; +} + +static int str_copy(CONF *conf, char *section, char **pto, char *from) { + int q, r, rr = 0, to = 0, len = 0; + char *s, *e, *rp, *rrp, *np, *cp, v; + const char *p; + BUF_MEM *buf; + + buf = BUF_MEM_new(); + if (buf == NULL) { + return 0; + } + + len = strlen(from) + 1; + if (!BUF_MEM_grow(buf, len)) { + goto err; + } + + for (;;) { + if (IS_QUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from) && (*from != q)) { + if (IS_ESC(conf, *from)) { + from++; + if (IS_EOF(conf, *from)) { + break; + } + } + buf->data[to++] = *(from++); + } + if (*from == q) { + from++; + } + } else if (IS_DQUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from)) { + if (*from == q) { + if (*(from + 1) == q) { + from++; + } else { + break; + } + } + buf->data[to++] = *(from++); + } + if (*from == q) { + from++; + } + } else if (IS_ESC(conf, *from)) { + from++; + v = *(from++); + if (IS_EOF(conf, v)) { + break; + } else if (v == 'r') { + v = '\r'; + } else if (v == 'n') { + v = '\n'; + } else if (v == 'b') { + v = '\b'; + } else if (v == 't') { + v = '\t'; + } + buf->data[to++] = v; + } else if (IS_EOF(conf, *from)) { + break; + } else if (*from == '$') { + // try to expand it + rrp = NULL; + s = &(from[1]); + if (*s == '{') { + q = '}'; + } else if (*s == '(') { + q = ')'; + } else { + q = 0; + } + + if (q) { + s++; + } + cp = section; + e = np = s; + while (IS_ALPHA_NUMERIC(conf, *e)) { + e++; + } + if (e[0] == ':' && e[1] == ':') { + cp = np; + rrp = e; + rr = *e; + *rrp = '\0'; + e += 2; + np = e; + while (IS_ALPHA_NUMERIC(conf, *e)) { + e++; + } + } + r = *e; + *e = '\0'; + rp = e; + if (q) { + if (r != q) { + OPENSSL_PUT_ERROR(CONF, CONF_R_NO_CLOSE_BRACE); + goto err; + } + e++; + } + // So at this point we have + // np which is the start of the name string which is + // '\0' terminated. + // cp which is the start of the section string which is + // '\0' terminated. + // e is the 'next point after'. + // r and rr are the chars replaced by the '\0' + // rp and rrp is where 'r' and 'rr' came from. + p = NCONF_get_string(conf, cp, np); + if (rrp != NULL) { + *rrp = rr; + } + *rp = r; + if (p == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + size_t newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + while (*p) { + buf->data[to++] = *(p++); + } + + /* Since we change the pointer 'from', we also have + to change the perceived length of the string it + points at. /RL */ + len -= e - from; + from = e; + + /* In case there were no braces or parenthesis around + the variable reference, we have to put back the + character that was replaced with a '\0'. /RL */ + *rp = r; + } else { + buf->data[to++] = *(from++); + } + } + + buf->data[to] = '\0'; + if (*pto != NULL) { + OPENSSL_free(*pto); + } + *pto = buf->data; + OPENSSL_free(buf); + return 1; + +err: + if (buf != NULL) { + BUF_MEM_free(buf); + } + return 0; +} + +static CONF_VALUE *get_section(const CONF *conf, const char *section) { + CONF_VALUE template; + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + return lh_CONF_VALUE_retrieve(conf->data, &template); +} + +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { + CONF_VALUE *section_value = get_section(conf, section); + if (section_value == NULL) { + return NULL; + } + return (STACK_OF(CONF_VALUE)*) section_value->value; +} + +const char *NCONF_get_string(const CONF *conf, const char *section, + const char *name) { + CONF_VALUE template, *value; + + if (section == NULL) { + section = kDefaultSectionName; + } + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + template.name = (char *) name; + value = lh_CONF_VALUE_retrieve(conf->data, &template); + if (value == NULL) { + return NULL; + } + return value->value; +} + +static int add_string(const CONF *conf, CONF_VALUE *section, + CONF_VALUE *value) { + STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value; + CONF_VALUE *old_value; + + value->section = OPENSSL_strdup(section->section); + if (!sk_CONF_VALUE_push(section_stack, value)) { + return 0; + } + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, value)) { + return 0; + } + if (old_value != NULL) { + (void)sk_CONF_VALUE_delete_ptr(section_stack, old_value); + value_free(old_value); + } + + return 1; +} + +static char *eat_ws(CONF *conf, char *p) { + while (IS_WS(conf, *p) && !IS_EOF(conf, *p)) { + p++; + } + return p; +} + +#define scan_esc(conf, p) (((IS_EOF((conf), (p)[1])) ? ((p) + 1) : ((p) + 2))) + +static char *eat_alpha_numeric(CONF *conf, char *p) { + for (;;) { + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) { + return p; + } + p++; + } +} + +static char *scan_quote(CONF *conf, char *p) { + int q = *p; + + p++; + while (!IS_EOF(conf, *p) && *p != q) { + if (IS_ESC(conf, *p)) { + p++; + if (IS_EOF(conf, *p)) { + return p; + } + } + p++; + } + if (*p == q) { + p++; + } + return p; +} + + +static char *scan_dquote(CONF *conf, char *p) { + int q = *p; + + p++; + while (!(IS_EOF(conf, *p))) { + if (*p == q) { + if (*(p + 1) == q) { + p++; + } else { + break; + } + } + p++; + } + if (*p == q) { + p++; + } + return p; +} + +static void clear_comments(CONF *conf, char *p) { + for (;;) { + if (IS_FCOMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (!IS_WS(conf, *p)) { + break; + } + p++; + } + + for (;;) { + if (IS_COMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (IS_DQUOTE(conf, *p)) { + p = scan_dquote(conf, p); + continue; + } + if (IS_QUOTE(conf, *p)) { + p = scan_quote(conf, p); + continue; + } + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (IS_EOF(conf, *p)) { + return; + } else { + p++; + } + } +} + +static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { + static const size_t CONFBUFSIZE = 512; + int bufnum = 0, i, ii; + BUF_MEM *buff = NULL; + char *s, *p, *end; + int again; + long eline = 0; + char btmp[DECIMAL_SIZE(eline) + 1]; + CONF_VALUE *v = NULL, *tv; + CONF_VALUE *sv = NULL; + char *section = NULL, *buf; + char *start, *psection, *pname; + + if ((buff = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB); + goto err; + } + + section = OPENSSL_strdup(kDefaultSectionName); + if (section == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = NCONF_new_section(conf, section); + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB); + goto err; + } + p = &(buff->data[bufnum]); + *p = '\0'; + BIO_gets(in, p, CONFBUFSIZE - 1); + p[CONFBUFSIZE - 1] = '\0'; + ii = i = strlen(p); + if (i == 0 && !again) { + break; + } + again = 0; + while (i > 0) { + if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) { + break; + } else { + i--; + } + } + // we removed some trailing stuff so there is a new + // line on the end. + if (ii && i == ii) { + again = 1; // long line + } else { + p[i] = '\0'; + eline++; // another input line + } + + // we now have a line with trailing \r\n removed + + // i is the number of bytes + bufnum += i; + + v = NULL; + // check for line continuation + if (bufnum >= 1) { + // If we have bytes and the last char '\\' and + // second last char is not '\\' + p = &(buff->data[bufnum - 1]); + if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { + bufnum--; + again = 1; + } + } + if (again) { + continue; + } + bufnum = 0; + buf = buff->data; + + clear_comments(conf, buf); + s = eat_ws(conf, buf); + if (IS_EOF(conf, *s)) { + continue; // blank line + } + if (*s == '[') { + char *ss; + + s++; + start = eat_ws(conf, s); + ss = start; + again: + end = eat_alpha_numeric(conf, ss); + p = eat_ws(conf, end); + if (*p != ']') { + if (*p != '\0' && ss != p) { + ss = p; + goto again; + } + OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) { + goto err; + } + if ((sv = get_section(conf, section)) == NULL) { + sv = NCONF_new_section(conf, section); + } + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + continue; + } else { + pname = s; + psection = NULL; + end = eat_alpha_numeric(conf, s); + if ((end[0] == ':') && (end[1] == ':')) { + *end = '\0'; + end += 2; + psection = pname; + pname = end; + end = eat_alpha_numeric(conf, end); + } + p = eat_ws(conf, end); + if (*p != '=') { + OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_EQUAL_SIGN); + goto err; + } + *end = '\0'; + p++; + start = eat_ws(conf, p); + while (!IS_EOF(conf, *p)) { + p++; + } + p--; + while ((p != start) && (IS_WS(conf, *p))) { + p--; + } + p++; + *p = '\0'; + + if (!(v = CONF_VALUE_new())) { + goto err; + } + if (psection == NULL) { + psection = section; + } + v->name = OPENSSL_strdup(pname); + if (v->name == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!str_copy(conf, psection, &(v->value), start)) { + goto err; + } + + if (strcmp(psection, section) != 0) { + if ((tv = get_section(conf, psection)) == NULL) { + tv = NCONF_new_section(conf, psection); + } + if (tv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else { + tv = sv; + } + if (add_string(conf, tv, v) == 0) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + v = NULL; + } + } + if (buff != NULL) { + BUF_MEM_free(buff); + } + if (section != NULL) { + OPENSSL_free(section); + } + return 1; + +err: + if (buff != NULL) { + BUF_MEM_free(buff); + } + if (section != NULL) { + OPENSSL_free(section); + } + if (out_error_line != NULL) { + *out_error_line = eline; + } + BIO_snprintf(btmp, sizeof btmp, "%ld", eline); + ERR_add_error_data(2, "line ", btmp); + + if (v != NULL) { + if (v->name != NULL) { + OPENSSL_free(v->name); + } + if (v->value != NULL) { + OPENSSL_free(v->value); + } + if (v != NULL) { + OPENSSL_free(v); + } + } + return 0; +} + +int NCONF_load(CONF *conf, const char *filename, long *out_error_line) { + BIO *in = BIO_new_file(filename, "rb"); + int ret; + + if (in == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, out_error_line); + BIO_free(in); + + return ret; +} + +int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) { + return def_load_bio(conf, bio, out_error_line); +} + +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg) { + int ret; + const char *lstart, *tmpend, *p; + + if (list == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list; + for (;;) { + if (remove_whitespace) { + while (*lstart && isspace((unsigned char)*lstart)) { + lstart++; + } + } + p = strchr(lstart, sep); + if (p == lstart || !*lstart) { + ret = list_cb(NULL, 0, arg); + } else { + if (p) { + tmpend = p - 1; + } else { + tmpend = lstart + strlen(lstart) - 1; + } + if (remove_whitespace) { + while (isspace((unsigned char)*tmpend)) { + tmpend--; + } + } + ret = list_cb(lstart, tmpend - lstart + 1, arg); + } + if (ret <= 0) { + return ret; + } + if (p == NULL) { + return 1; + } + lstart = p + 1; + } +} + +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) { + return 1; +} + +void CONF_modules_free(void) {} + +void OPENSSL_config(const char *config_name) {} + +void OPENSSL_no_config(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf_def.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf_def.h new file mode 100644 index 00000000..b1e6ba63 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/conf_def.h @@ -0,0 +1,127 @@ +/* crypto/conf/conf_def.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* THIS FILE WAS AUTOMAGICALLY GENERATED! + Please modify and use keysets.pl to regenerate it. */ + +#define CONF_NUMBER 1 +#define CONF_UPPER 2 +#define CONF_LOWER 4 +#define CONF_UNDER 256 +#define CONF_PUNCTUATION 512 +#define CONF_WS 16 +#define CONF_ESC 32 +#define CONF_QUOTE 64 +#define CONF_DQUOTE 1024 +#define CONF_COMMENT 128 +#define CONF_FCOMMENT 2048 +#define CONF_EOF 8 +#define CONF_HIGHBIT 4096 +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ + CONF_PUNCTUATION) + +#define KEYTYPES(c) CONF_type_default +#define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +#define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) + +static const unsigned short CONF_type_default[256]={ + 0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0010,0x0010,0x0000,0x0000,0x0010,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0010,0x0200,0x0040,0x0080,0x0000,0x0200,0x0200,0x0040, + 0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, + 0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001, + 0x0001,0x0001,0x0000,0x0200,0x0000,0x0000,0x0000,0x0200, + 0x0200,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002, + 0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002, + 0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002, + 0x0002,0x0002,0x0002,0x0000,0x0020,0x0000,0x0200,0x0100, + 0x0040,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004, + 0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004, + 0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004, + 0x0004,0x0004,0x0004,0x0000,0x0200,0x0000,0x0200,0x0000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + 0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, + }; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/internal.h new file mode 100644 index 00000000..3e0e57df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/conf/internal.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. +CONF_VALUE *CONF_VALUE_new(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_apple.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_apple.c new file mode 100644 index 00000000..465c68a4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_apple.c @@ -0,0 +1,72 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_APPLE) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include + +#include + + +extern uint32_t OPENSSL_armcap_P; + +static int has_hw_feature(const char *name) { + int value; + size_t len = sizeof(value); + if (sysctlbyname(name, &value, &len, NULL, 0) != 0) { + return 0; + } + if (len != sizeof(int)) { + // This should not happen. All the values queried should be integer-valued. + assert(0); + return 0; + } + + // Per sys/sysctl.h: + // + // Selectors that return errors are not support on the system. Supported + // features will return 1 if they are recommended or 0 if they are supported + // but are not expected to help performance. Future versions of these + // selectors may return larger values as necessary so it is best to test for + // non zero. + return value != 0; +} + +void OPENSSL_cpuid_setup(void) { + // Apple ARM64 platforms have NEON and cryptography extensions available + // statically, so we do not need to query them. In particular, there sometimes + // are no sysctls corresponding to such features. See below. +#if !defined(__ARM_NEON) || !defined(__ARM_FEATURE_AES) || \ + !defined(__ARM_FEATURE_SHA2) +#error "NEON and crypto extensions should be statically available." +#endif + OPENSSL_armcap_P = + ARMV7_NEON | ARMV8_AES | ARMV8_PMULL | ARMV8_SHA1 | ARMV8_SHA256; + + // macOS has sysctls named both like "hw.optional.arm.FEAT_SHA512" and like + // "hw.optional.armv8_2_sha512". There does not appear to be documentation on + // which to use. The "armv8_2_sha512" style omits statically-available + // features, while the "FEAT_SHA512" style includes them. However, the + // "FEAT_SHA512" style was added in macOS 12, so we use the older style for + // better compatibility and handle static features above. + if (has_hw_feature("hw.optional.armv8_2_sha512")) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_APPLE && !OPENSSL_STATIC_ARMCAP diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_fuchsia.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_fuchsia.c new file mode 100644 index 00000000..93a347e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_fuchsia.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FUCHSIA) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include + +#include + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + uint32_t hwcap; + zx_status_t rc = zx_system_get_features(ZX_FEATURE_KIND_CPU, &hwcap); + if (rc != ZX_OK || (hwcap & ZX_ARM64_FEATURE_ISA_ASIMD) == 0) { + // If NEON/ASIMD is missing, don't report other features either. This + // matches OpenSSL, and the other features depend on SIMD registers. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & ZX_ARM64_FEATURE_ISA_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA256) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_FUCHSIA && !OPENSSL_STATIC_ARMCAP diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_linux.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_linux.c new file mode 100644 index 00000000..1ba9812c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_linux.c @@ -0,0 +1,64 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + +#include + + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + + // See /usr/include/asm/hwcap.h on an aarch64 installation for the source of + // these values. + static const unsigned long kNEON = 1 << 1; + static const unsigned long kAES = 1 << 3; + static const unsigned long kPMULL = 1 << 4; + static const unsigned long kSHA1 = 1 << 5; + static const unsigned long kSHA256 = 1 << 6; + static const unsigned long kSHA512 = 1 << 21; + + if ((hwcap & kNEON) == 0) { + // Matching OpenSSL, if NEON is missing, don't report other features + // either. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & kAES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & kPMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & kSHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & kSHA256) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + if (hwcap & kSHA512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_win.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_win.c new file mode 100644 index 00000000..dbc3b25b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_aarch64_win.c @@ -0,0 +1,41 @@ +/* Copyright (c) 2018, Google Inc. + * Copyright (c) 2020, Arm Ltd. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_WINDOWS) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + +#include + +extern uint32_t OPENSSL_armcap_P; +void OPENSSL_cpuid_setup(void) { + // We do not need to check for the presence of NEON, as Armv8-A always has it + OPENSSL_armcap_P |= ARMV7_NEON; + + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) { + // These are all covered by one call in Windows + OPENSSL_armcap_P |= ARMV8_AES; + OPENSSL_armcap_P |= ARMV8_PMULL; + OPENSSL_armcap_P |= ARMV8_SHA1; + OPENSSL_armcap_P |= ARMV8_SHA256; + } + // As of writing, Windows does not have a |PF_*| value for ARMv8.2 SHA-512 + // extensions. When it does, add it here. +} + +#endif // OPENSSL_AARCH64 && OPENSSL_WINDOWS && !OPENSSL_STATIC_ARMCAP diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm.c new file mode 100644 index 00000000..06f47752 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + + +extern uint32_t OPENSSL_armcap_P; + +int CRYPTO_is_NEON_capable_at_runtime(void) { + return (OPENSSL_armcap_P & ARMV7_NEON) != 0; +} + +int CRYPTO_is_ARMv8_AES_capable_at_runtime(void) { + return (OPENSSL_armcap_P & ARMV8_AES) != 0; +} + +int CRYPTO_is_ARMv8_PMULL_capable_at_runtime(void) { + return (OPENSSL_armcap_P & ARMV8_PMULL) != 0; +} + +#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && + !defined(OPENSSL_STATIC_ARMCAP) */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c new file mode 100644 index 00000000..5cf66d9f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) +#include +#include +#include +#include + +#include +#include + +#include "cpu_arm_linux.h" + +#define AT_HWCAP 16 +#define AT_HWCAP2 26 + +// |getauxval| is not available on Android until API level 20. Link it as a weak +// symbol and use other methods as fallback. +unsigned long getauxval(unsigned long type) __attribute__((weak)); + +static int open_eintr(const char *path, int flags) { + int ret; + do { + ret = open(path, flags); + } while (ret < 0 && errno == EINTR); + return ret; +} + +static ssize_t read_eintr(int fd, void *out, size_t len) { + ssize_t ret; + do { + ret = read(fd, out, len); + } while (ret < 0 && errno == EINTR); + return ret; +} + +// read_full reads exactly |len| bytes from |fd| to |out|. On error or end of +// file, it returns zero. +static int read_full(int fd, void *out, size_t len) { + char *outp = out; + while (len > 0) { + ssize_t ret = read_eintr(fd, outp, len); + if (ret <= 0) { + return 0; + } + outp += ret; + len -= ret; + } + return 1; +} + +// read_file opens |path| and reads until end-of-file. On success, it returns +// one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the +// contents. Otherwise, it returns zero. +static int read_file(char **out_ptr, size_t *out_len, const char *path) { + int fd = open_eintr(path, O_RDONLY); + if (fd < 0) { + return 0; + } + + static const size_t kReadSize = 1024; + int ret = 0; + size_t cap = kReadSize, len = 0; + char *buf = OPENSSL_malloc(cap); + if (buf == NULL) { + goto err; + } + + for (;;) { + if (cap - len < kReadSize) { + size_t new_cap = cap * 2; + if (new_cap < cap) { + goto err; + } + char *new_buf = OPENSSL_realloc(buf, new_cap); + if (new_buf == NULL) { + goto err; + } + buf = new_buf; + cap = new_cap; + } + + ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize); + if (bytes_read < 0) { + goto err; + } + if (bytes_read == 0) { + break; + } + len += bytes_read; + } + + *out_ptr = buf; + *out_len = len; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + close(fd); + return ret; +} + +// getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. +static unsigned long getauxval_proc(unsigned long type) { + int fd = open_eintr("/proc/self/auxv", O_RDONLY); + if (fd < 0) { + return 0; + } + + struct { + unsigned long tag; + unsigned long value; + } entry; + + for (;;) { + if (!read_full(fd, &entry, sizeof(entry)) || + (entry.tag == 0 && entry.value == 0)) { + break; + } + if (entry.tag == type) { + close(fd); + return entry.value; + } + } + close(fd); + return 0; +} + +extern uint32_t OPENSSL_armcap_P; + +static int g_has_broken_neon, g_needs_hwcap2_workaround; + +void OPENSSL_cpuid_setup(void) { + // We ignore the return value of |read_file| and proceed with an empty + // /proc/cpuinfo on error. If |getauxval| works, we will still detect + // capabilities. There may be a false positive due to + // |crypto_cpuinfo_has_broken_neon|, but this is now rare. + char *cpuinfo_data = NULL; + size_t cpuinfo_len = 0; + read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo"); + STRING_PIECE cpuinfo; + cpuinfo.data = cpuinfo_data; + cpuinfo.len = cpuinfo_len; + + // |getauxval| is not available on Android until API level 20. If it is + // unavailable, read from /proc/self/auxv as a fallback. This is unreadable + // on some versions of Android, so further fall back to /proc/cpuinfo. + // + // See + // https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2 + // and b/13679666 (Google-internal) for details. + unsigned long hwcap = 0; + if (getauxval != NULL) { + hwcap = getauxval(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = getauxval_proc(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = crypto_get_arm_hwcap_from_cpuinfo(&cpuinfo); + } + + // Clear NEON support if known broken. Note, if NEON is available statically, + // the non-NEON code is dropped and this workaround is a no-op. + // + // TODO(davidben): The Android NDK now builds with NEON statically available + // by default. Cronet still has some consumers that support NEON-less devices + // (b/150371744). Get metrics on whether they still see this CPU and, if not, + // remove this check entirely. + g_has_broken_neon = crypto_cpuinfo_has_broken_neon(&cpuinfo); + if (g_has_broken_neon) { + hwcap &= ~HWCAP_NEON; + } + + // Matching OpenSSL, only report other features if NEON is present. + if (hwcap & HWCAP_NEON) { + OPENSSL_armcap_P |= ARMV7_NEON; + + // Some ARMv8 Android devices don't expose AT_HWCAP2. Fall back to + // /proc/cpuinfo. See https://crbug.com/boringssl/46. As of February 2021, + // this is now rare (see Chrome's Net.NeedsHWCAP2Workaround metric), but AES + // and PMULL extensions are very useful, so we still carry the workaround + // for now. + unsigned long hwcap2 = 0; + if (getauxval != NULL) { + hwcap2 = getauxval(AT_HWCAP2); + } + if (hwcap2 == 0) { + hwcap2 = crypto_get_arm_hwcap2_from_cpuinfo(&cpuinfo); + g_needs_hwcap2_workaround = hwcap2 != 0; + } + + if (hwcap2 & HWCAP2_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap2 & HWCAP2_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap2 & HWCAP2_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap2 & HWCAP2_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + } + + OPENSSL_free(cpuinfo_data); +} + +int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; } + +int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; } + +#endif // OPENSSL_ARM && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h new file mode 100644 index 00000000..35e3e9ec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h @@ -0,0 +1,201 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H +#define OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H + +#include + +#include + +#include "internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The cpuinfo parser lives in a header file so it may be accessible from +// cross-platform fuzzers without adding code to those platforms normally. + +#define HWCAP_NEON (1 << 12) + +// See /usr/include/asm/hwcap.h on an ARM installation for the source of +// these values. +#define HWCAP2_AES (1 << 0) +#define HWCAP2_PMULL (1 << 1) +#define HWCAP2_SHA1 (1 << 2) +#define HWCAP2_SHA2 (1 << 3) + +typedef struct { + const char *data; + size_t len; +} STRING_PIECE; + +static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) { + size_t b_len = strlen(b); + return a->len == b_len && OPENSSL_memcmp(a->data, b, b_len) == 0; +} + +// STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found, +// sets |*out_left| and |*out_right| to |in| split before and after it. It +// returns one if |sep| was found and zero otherwise. +static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right, + const STRING_PIECE *in, char sep) { + const char *p = (const char *)OPENSSL_memchr(in->data, sep, in->len); + if (p == NULL) { + return 0; + } + // |out_left| or |out_right| may alias |in|, so make a copy. + STRING_PIECE in_copy = *in; + out_left->data = in_copy.data; + out_left->len = p - in_copy.data; + out_right->data = in_copy.data + out_left->len + 1; + out_right->len = in_copy.len - out_left->len - 1; + return 1; +} + +// STRING_PIECE_get_delimited reads a |sep|-delimited entry from |s|, writing it +// to |out| and updating |s| to point beyond it. It returns one on success and +// zero if |s| is empty. If |s| is has no copies of |sep| and is non-empty, it +// reads the entire string to |out|. +static int STRING_PIECE_get_delimited(STRING_PIECE *s, STRING_PIECE *out, char sep) { + if (s->len == 0) { + return 0; + } + if (!STRING_PIECE_split(out, s, s, sep)) { + // |s| had no instances of |sep|. Return the entire string. + *out = *s; + s->data += s->len; + s->len = 0; + } + return 1; +} + +// STRING_PIECE_trim removes leading and trailing whitespace from |s|. +static void STRING_PIECE_trim(STRING_PIECE *s) { + while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) { + s->data++; + s->len--; + } + while (s->len != 0 && + (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) { + s->len--; + } +} + +// extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from +// |in|. If found, it sets |*out| to the value and returns one. Otherwise, it +// returns zero. +static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in, + const char *field) { + // Process |in| one line at a time. + STRING_PIECE remaining = *in, line; + while (STRING_PIECE_get_delimited(&remaining, &line, '\n')) { + STRING_PIECE key, value; + if (!STRING_PIECE_split(&key, &value, &line, ':')) { + continue; + } + STRING_PIECE_trim(&key); + if (STRING_PIECE_equals(&key, field)) { + STRING_PIECE_trim(&value); + *out = value; + return 1; + } + } + + return 0; +} + +static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field, + const char *value) { + STRING_PIECE extracted; + return extract_cpuinfo_field(&extracted, cpuinfo, field) && + STRING_PIECE_equals(&extracted, value); +} + +// has_list_item treats |list| as a space-separated list of items and returns +// one if |item| is contained in |list| and zero otherwise. +static int has_list_item(const STRING_PIECE *list, const char *item) { + STRING_PIECE remaining = *list, feature; + while (STRING_PIECE_get_delimited(&remaining, &feature, ' ')) { + if (STRING_PIECE_equals(&feature, item)) { + return 1; + } + } + return 0; +} + +// crypto_get_arm_hwcap_from_cpuinfo returns an equivalent ARM |AT_HWCAP| value +// from |cpuinfo|. +static unsigned long crypto_get_arm_hwcap_from_cpuinfo( + const STRING_PIECE *cpuinfo) { + if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) { + // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always + // available on ARMv8. Linux omits required features, so reading the + // "Features" line does not work. (For simplicity, use strict equality. We + // assume everything running on future ARM architectures will have a + // working |getauxval|.) + return HWCAP_NEON; + } + + STRING_PIECE features; + if (extract_cpuinfo_field(&features, cpuinfo, "Features") && + has_list_item(&features, "neon")) { + return HWCAP_NEON; + } + return 0; +} + +// crypto_get_arm_hwcap2_from_cpuinfo returns an equivalent ARM |AT_HWCAP2| +// value from |cpuinfo|. +static unsigned long crypto_get_arm_hwcap2_from_cpuinfo( + const STRING_PIECE *cpuinfo) { + STRING_PIECE features; + if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) { + return 0; + } + + unsigned long ret = 0; + if (has_list_item(&features, "aes")) { + ret |= HWCAP2_AES; + } + if (has_list_item(&features, "pmull")) { + ret |= HWCAP2_PMULL; + } + if (has_list_item(&features, "sha1")) { + ret |= HWCAP2_SHA1; + } + if (has_list_item(&features, "sha2")) { + ret |= HWCAP2_SHA2; + } + return ret; +} + +// crypto_cpuinfo_has_broken_neon returns one if |cpuinfo| matches a CPU known +// to have broken NEON unit and zero otherwise. See https://crbug.com/341598. +static int crypto_cpuinfo_has_broken_neon(const STRING_PIECE *cpuinfo) { + return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") && + cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") && + cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") && + cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") && + cpuinfo_field_equals(cpuinfo, "CPU revision", "0"); +} + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_intel.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_intel.c new file mode 100644 index 00000000..f74ef4b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_intel.c @@ -0,0 +1,290 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) + +#include +#include +#include +#include + +#if defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +// OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX +// is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through +// |*out_edx|. +static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx, + uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) { +#if defined(_MSC_VER) + int tmp[4]; + __cpuid(tmp, (int)leaf); + *out_eax = (uint32_t)tmp[0]; + *out_ebx = (uint32_t)tmp[1]; + *out_ecx = (uint32_t)tmp[2]; + *out_edx = (uint32_t)tmp[3]; +#elif defined(__pic__) && defined(OPENSSL_32_BIT) + // Inline assembly may not clobber the PIC register. For 32-bit, this is EBX. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "mov %%ebx, %%edi\n" + "cpuid\n" + "xchg %%edi, %%ebx\n" + : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#else + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "cpuid\n" + : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#endif +} + +// OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR). +// Currently only XCR0 is defined by Intel so |xcr| should always be zero. +static uint64_t OPENSSL_xgetbv(uint32_t xcr) { +#if defined(_MSC_VER) + return (uint64_t)_xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (((uint64_t)edx) << 32) | eax; +#endif +} + +// handle_cpu_env applies the value from |in| to the CPUID values in |out[0]| +// and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. +static void handle_cpu_env(uint32_t *out, const char *in) { + const int invert = in[0] == '~'; + const int or = in[0] == '|'; + const int skip_first_byte = invert || or; + const int hex = in[skip_first_byte] == '0' && in[skip_first_byte+1] == 'x'; + + int sscanf_result; + uint64_t v; + if (hex) { + sscanf_result = sscanf(in + invert + 2, "%" PRIx64, &v); + } else { + sscanf_result = sscanf(in + invert, "%" PRIu64, &v); + } + + if (!sscanf_result) { + return; + } + + if (invert) { + out[0] &= ~v; + out[1] &= ~(v >> 32); + } else if (or) { + out[0] |= v; + out[1] |= (v >> 32); + } else { + out[0] = v; + out[1] = v >> 32; + } +} + +void OPENSSL_cpuid_setup(void) { + // Determine the vendor and maximum input value. + uint32_t eax, ebx, ecx, edx; + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0); + + uint32_t num_ids = eax; + + int is_intel = ebx == 0x756e6547 /* Genu */ && + edx == 0x49656e69 /* ineI */ && + ecx == 0x6c65746e /* ntel */; + int is_amd = ebx == 0x68747541 /* Auth */ && + edx == 0x69746e65 /* enti */ && + ecx == 0x444d4163 /* cAMD */; + + uint32_t extended_features[2] = {0}; + if (num_ids >= 7) { + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7); + extended_features[0] = ebx; + extended_features[1] = ecx; + } + + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1); + + if (is_amd) { + // See https://www.amd.com/system/files/TechDocs/25481.pdf, page 10. + const uint32_t base_family = (eax >> 8) & 15; + const uint32_t base_model = (eax >> 4) & 15; + + uint32_t family = base_family; + uint32_t model = base_model; + if (base_family == 0xf) { + const uint32_t ext_family = (eax >> 20) & 255; + family += ext_family; + const uint32_t ext_model = (eax >> 16) & 15; + model |= ext_model << 4; + } + + if (family < 0x17 || (family == 0x17 && 0x70 <= model && model <= 0x7f)) { + // Disable RDRAND on AMD families before 0x17 (Zen) due to reported + // failures after suspend. + // https://bugzilla.redhat.com/show_bug.cgi?id=1150286 + // Also disable for family 0x17, models 0x70–0x7f, due to possible RDRAND + // failures there too. + ecx &= ~(1u << 30); + } + } + + // Force the hyper-threading bit so that the more conservative path is always + // chosen. + edx |= 1u << 28; + + // Reserved bit #20 was historically repurposed to control the in-memory + // representation of RC4 state. Always set it to zero. + edx &= ~(1u << 20); + + // Reserved bit #30 is repurposed to signal an Intel CPU. + if (is_intel) { + edx |= (1u << 30); + + // Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables + // some Silvermont-specific codepaths which perform better. See OpenSSL + // commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ || + (eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) { + ecx &= ~(1u << 26); + } + } else { + edx &= ~(1u << 30); + } + + // The SDBG bit is repurposed to denote AMD XOP support. Don't ever use AMD + // XOP code paths. + ecx &= ~(1u << 11); + + uint64_t xcr0 = 0; + if (ecx & (1u << 27)) { + // XCR0 may only be queried if the OSXSAVE bit is set. + xcr0 = OPENSSL_xgetbv(0); + } + // See Intel manual, volume 1, section 14.3. + if ((xcr0 & 6) != 6) { + // YMM registers cannot be used. + ecx &= ~(1u << 28); // AVX + ecx &= ~(1u << 12); // FMA + ecx &= ~(1u << 11); // AMD XOP + // Clear AVX2 and AVX512* bits. + // + // TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream + // doesn't clear those. + extended_features[0] &= + ~((1u << 5) | (1u << 16) | (1u << 21) | (1u << 30) | (1u << 31)); + } + // See Intel manual, volume 1, section 15.2. + if ((xcr0 & 0xe6) != 0xe6) { + // Clear AVX512F. Note we don't touch other AVX512 extensions because they + // can be used with YMM. + extended_features[0] &= ~(1u << 16); + } + + // Disable ADX instructions on Knights Landing. See OpenSSL commit + // 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((ecx & (1u << 26)) == 0) { + extended_features[0] &= ~(1u << 19); + } + + OPENSSL_ia32cap_P[0] = edx; + OPENSSL_ia32cap_P[1] = ecx; + OPENSSL_ia32cap_P[2] = extended_features[0]; + OPENSSL_ia32cap_P[3] = extended_features[1]; + + const char *env1, *env2; + env1 = getenv("OPENSSL_ia32cap"); + if (env1 == NULL) { + return; + } + + // OPENSSL_ia32cap can contain zero, one or two values, separated with a ':'. + // Each value is a 64-bit, unsigned value which may start with "0x" to + // indicate a hex value. Prior to the 64-bit value, a '~' or '|' may be given. + // + // If the '~' prefix is present: + // the value is inverted and ANDed with the probed CPUID result + // If the '|' prefix is present: + // the value is ORed with the probed CPUID result + // Otherwise: + // the value is taken as the result of the CPUID + // + // The first value determines OPENSSL_ia32cap_P[0] and [1]. The second [2] + // and [3]. + + handle_cpu_env(&OPENSSL_ia32cap_P[0], env1); + env2 = strchr(env1, ':'); + if (env2 != NULL) { + handle_cpu_env(&OPENSSL_ia32cap_P[2], env2 + 1); + } +} + +#endif // !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c new file mode 100644 index 00000000..11a1fce4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +#include "internal.h" + + +#if !defined(PPC_FEATURE2_HAS_VCRYPTO) +// PPC_FEATURE2_HAS_VCRYPTO was taken from section 4.1.2.3 of the “OpenPOWER +// ABI for Linux Supplement”. +#define PPC_FEATURE2_HAS_VCRYPTO 0x02000000 +#endif + +void OPENSSL_cpuid_setup(void) { + OPENSSL_ppc64le_hwcap2 = getauxval(AT_HWCAP2); +} + +int CRYPTO_is_PPC64LE_vcrypto_capable(void) { + return (OPENSSL_ppc64le_hwcap2 & PPC_FEATURE2_HAS_VCRYPTO) != 0; +} + +#endif // OPENSSL_PPC64LE diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/crypto.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/crypto.c new file mode 100644 index 00000000..1b417f7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/crypto.c @@ -0,0 +1,233 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include "fipsmodule/rand/fork_detect.h" +#include "fipsmodule/rand/internal.h" +#include "internal.h" + + +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ + defined(OPENSSL_PPC64LE)) +// x86, x86_64, the ARMs and ppc64le need to record the result of a +// cpuid/getauxval call for the asm to work correctly, unless compiled without +// asm code. +#define NEED_CPUID + +#else + +// Otherwise, don't emit a static initialiser. + +#if !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#endif // !NO_ASM && !STATIC_ARMCAP && + // (X86 || X86_64 || ARM || AARCH64 || PPC64LE) + + +// Our assembly does not use the GOT to reference symbols, which means +// references to visible symbols will often require a TEXTREL. This is +// undesirable, so all assembly-referenced symbols should be hidden. CPU +// capabilities are the only such symbols defined in C. Explicitly hide them, +// rather than rely on being built with -fvisibility=hidden. +#if defined(OPENSSL_WINDOWS) +#define HIDDEN +#else +#define HIDDEN __attribute__((visibility("hidden"))) +#endif + + +// The capability variables are defined in this file in order to work around a +// linker bug. When linking with a .a, if no symbols in a .o are referenced +// then the .o is discarded, even if it has constructor functions. +// +// This still means that any binaries that don't include some functionality +// that tests the capability values will still skip the constructor but, so +// far, the init constructor function only sets the capability variables. + +#if defined(BORINGSSL_DISPATCH_TEST) +// This value must be explicitly initialised to zero in order to work around a +// bug in libtool or the linker on OS X. +// +// If not initialised then it becomes a "common symbol". When put into an +// archive, linking on OS X will fail to resolve common symbols. By +// initialising it to zero, it becomes a "data symbol", which isn't so +// affected. +HIDDEN uint8_t BORINGSSL_function_hit[7] = {0}; +#endif + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + +// This value must be explicitly initialized to zero. See similar comment above. +HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0}; + +#elif defined(OPENSSL_PPC64LE) + +HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0; + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#include + +#if defined(OPENSSL_STATIC_ARMCAP) + +// See ARM ACLE for the definitions of these macros. Note |__ARM_FEATURE_AES| +// covers both AES and PMULL and |__ARM_FEATURE_SHA2| covers SHA-1 and SHA-256. +// https://developer.arm.com/architectures/system-architectures/software-standards/acle +// https://github.com/ARM-software/acle/issues/152 +// +// TODO(davidben): Do we still need |OPENSSL_STATIC_ARMCAP_*| or are the +// standard flags and -march sufficient? +HIDDEN uint32_t OPENSSL_armcap_P = +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON) + ARMV7_NEON | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_AES) + ARMV8_AES | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_AES) + ARMV8_PMULL | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_SHA2) + ARMV8_SHA1 | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_SHA2) + ARMV8_SHA256 | +#endif +#if defined(__ARM_FEATURE_SHA512) + ARMV8_SHA512 | +#endif + 0; + +#else +HIDDEN uint32_t OPENSSL_armcap_P = 0; + +uint32_t *OPENSSL_get_armcap_pointer_for_test(void) { + return &OPENSSL_armcap_P; +} +#endif + +#endif + +#if defined(BORINGSSL_FIPS) +// In FIPS mode, the power-on self-test function calls |CRYPTO_library_init| +// because we have to ensure that CPUID detection occurs first. +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define OPENSSL_CDECL __cdecl +#else +#define OPENSSL_CDECL +#endif + +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) +static CRYPTO_once_t once = CRYPTO_ONCE_INIT; +#elif defined(_MSC_VER) +#pragma section(".CRT$XCU", read) +static void __cdecl do_library_init(void); +__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) = + do_library_init; +#else +static void do_library_init(void) __attribute__ ((constructor)); +#endif + +// do_library_init is the actual initialization function. If +// BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static +// initializer. Otherwise, it is called by CRYPTO_library_init. +static void OPENSSL_CDECL do_library_init(void) { + // WARNING: this function may only configure the capability variables. See the + // note above about the linker bug. +#if defined(NEED_CPUID) + OPENSSL_cpuid_setup(); +#endif +} + +void CRYPTO_library_init(void) { + // TODO(davidben): It would be tidier if this build knob could be replaced + // with an internal lazy-init mechanism that would handle things correctly + // in-library. https://crbug.com/542879 +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) + CRYPTO_once(&once, do_library_init); +#endif +} + +int CRYPTO_is_confidential_build(void) { +#if defined(BORINGSSL_CONFIDENTIAL) + return 1; +#else + return 0; +#endif +} + +int CRYPTO_has_asm(void) { +#if defined(OPENSSL_NO_ASM) + return 0; +#else + return 1; +#endif +} + +void CRYPTO_pre_sandbox_init(void) { + // Read from /proc/cpuinfo if needed. + CRYPTO_library_init(); + // Open /dev/urandom if needed. + CRYPTO_init_sysrand(); + // Set up MADV_WIPEONFORK state if needed. + CRYPTO_get_fork_generation(); +} + +const char *SSLeay_version(int which) { return OpenSSL_version(which); } + +const char *OpenSSL_version(int which) { + switch (which) { + case OPENSSL_VERSION: + return "BoringSSL"; + case OPENSSL_CFLAGS: + return "compiler: n/a"; + case OPENSSL_BUILT_ON: + return "built on: n/a"; + case OPENSSL_PLATFORM: + return "platform: n/a"; + case OPENSSL_DIR: + return "OPENSSLDIR: n/a"; + default: + return "not available"; + } +} + +unsigned long SSLeay(void) { return OPENSSL_VERSION_NUMBER; } + +unsigned long OpenSSL_version_num(void) { return OPENSSL_VERSION_NUMBER; } + +int CRYPTO_malloc_init(void) { return 1; } + +int OPENSSL_malloc_init(void) { return 1; } + +void ENGINE_load_builtin_engines(void) {} + +int ENGINE_register_all_complete(void) { return 1; } + +void OPENSSL_load_builtin_modules(void) {} + +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} + +void OPENSSL_cleanup(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S new file mode 100644 index 00000000..9e2c1ccd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S @@ -0,0 +1,2143 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This file is taken from crypto_scalarmult/curve25519/neon2/scalarmult.s in + * SUPERCOP 20141124 (http://bench.cr.yp.to/supercop.html). That code is public + * domain licensed but the standard ISC license is included above to keep + * licensing simple. */ + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__arm__) && !defined(__APPLE__) + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +.fpu neon +.text +.align 4 + +.global x25519_NEON +.hidden x25519_NEON +.type x25519_NEON, %function +x25519_NEON: +vpush {q4,q5,q6,q7} +mov r12,sp +sub sp,sp,#736 +and sp,sp,#0xffffffe0 +strd r4,[sp,#0] +strd r6,[sp,#8] +strd r8,[sp,#16] +strd r10,[sp,#24] +str r12,[sp,#480] +str r14,[sp,#484] +mov r0,r0 +mov r1,r1 +mov r2,r2 +add r3,sp,#32 +ldr r4,=0 +ldr r5,=254 +vmov.i32 q0,#1 +vshr.u64 q1,q0,#7 +vshr.u64 q0,q0,#8 +vmov.i32 d4,#19 +vmov.i32 d5,#38 +add r6,sp,#512 +vst1.8 {d2-d3},[r6,: 128] +add r6,sp,#528 +vst1.8 {d0-d1},[r6,: 128] +add r6,sp,#544 +vst1.8 {d4-d5},[r6,: 128] +add r6,r3,#0 +vmov.i32 q2,#0 +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 d4,[r6,: 64] +add r6,r3,#0 +ldr r7,=960 +sub r7,r7,#2 +neg r7,r7 +sub r7,r7,r7,LSL #7 +str r7,[r6] +add r6,sp,#704 +vld1.8 {d4-d5},[r1]! +vld1.8 {d6-d7},[r1] +vst1.8 {d4-d5},[r6,: 128]! +vst1.8 {d6-d7},[r6,: 128] +sub r1,r6,#16 +ldrb r6,[r1] +and r6,r6,#248 +strb r6,[r1] +ldrb r6,[r1,#31] +and r6,r6,#127 +orr r6,r6,#64 +strb r6,[r1,#31] +vmov.i64 q2,#0xffffffff +vshr.u64 q3,q2,#7 +vshr.u64 q2,q2,#6 +vld1.8 {d8},[r2] +vld1.8 {d10},[r2] +add r2,r2,#6 +vld1.8 {d12},[r2] +vld1.8 {d14},[r2] +add r2,r2,#6 +vld1.8 {d16},[r2] +add r2,r2,#4 +vld1.8 {d18},[r2] +vld1.8 {d20},[r2] +add r2,r2,#6 +vld1.8 {d22},[r2] +add r2,r2,#2 +vld1.8 {d24},[r2] +vld1.8 {d26},[r2] +vshr.u64 q5,q5,#26 +vshr.u64 q6,q6,#3 +vshr.u64 q7,q7,#29 +vshr.u64 q8,q8,#6 +vshr.u64 q10,q10,#25 +vshr.u64 q11,q11,#3 +vshr.u64 q12,q12,#12 +vshr.u64 q13,q13,#38 +vand q4,q4,q2 +vand q6,q6,q2 +vand q8,q8,q2 +vand q10,q10,q2 +vand q2,q12,q2 +vand q5,q5,q3 +vand q7,q7,q3 +vand q9,q9,q3 +vand q11,q11,q3 +vand q3,q13,q3 +add r2,r3,#48 +vadd.i64 q12,q4,q1 +vadd.i64 q13,q10,q1 +vshr.s64 q12,q12,#26 +vshr.s64 q13,q13,#26 +vadd.i64 q5,q5,q12 +vshl.i64 q12,q12,#26 +vadd.i64 q14,q5,q0 +vadd.i64 q11,q11,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q11,q0 +vsub.i64 q4,q4,q12 +vshr.s64 q12,q14,#25 +vsub.i64 q10,q10,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q12 +vshl.i64 q12,q12,#25 +vadd.i64 q14,q6,q1 +vadd.i64 q2,q2,q13 +vsub.i64 q5,q5,q12 +vshr.s64 q12,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q1 +vadd.i64 q7,q7,q12 +vshl.i64 q12,q12,#26 +vadd.i64 q15,q7,q0 +vsub.i64 q11,q11,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q12 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q3,q0 +vadd.i64 q8,q8,q12 +vshl.i64 q12,q12,#25 +vadd.i64 q15,q8,q1 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q7,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q9,q9,q12 +vtrn.32 d12,d14 +vshl.i64 q12,q12,#26 +vtrn.32 d13,d15 +vadd.i64 q0,q9,q0 +vadd.i64 q4,q4,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q6,q13,#4 +vsub.i64 q7,q8,q12 +vshr.s64 q0,q0,#25 +vadd.i64 q4,q4,q6 +vadd.i64 q6,q10,q0 +vshl.i64 q0,q0,#25 +vadd.i64 q8,q6,q1 +vadd.i64 q4,q4,q13 +vshl.i64 q10,q13,#25 +vadd.i64 q1,q4,q1 +vsub.i64 q0,q9,q0 +vshr.s64 q8,q8,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d14,d0 +vshr.s64 q1,q1,#26 +vtrn.32 d15,d1 +vadd.i64 q0,q11,q8 +vst1.8 d14,[r2,: 64] +vshl.i64 q7,q8,#26 +vadd.i64 q5,q5,q1 +vtrn.32 d4,d6 +vshl.i64 q1,q1,#26 +vtrn.32 d5,d7 +vsub.i64 q3,q6,q7 +add r2,r2,#16 +vsub.i64 q1,q4,q1 +vst1.8 d4,[r2,: 64] +vtrn.32 d6,d0 +vtrn.32 d7,d1 +sub r2,r2,#8 +vtrn.32 d2,d10 +vtrn.32 d3,d11 +vst1.8 d6,[r2,: 64] +sub r2,r2,#24 +vst1.8 d2,[r2,: 64] +add r2,r3,#96 +vmov.i32 q0,#0 +vmov.i64 d2,#0xff +vmov.i64 d3,#0 +vshr.u32 q1,q1,#7 +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#144 +vmov.i32 q0,#0 +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#240 +vmov.i32 q0,#0 +vmov.i64 d2,#0xff +vmov.i64 d3,#0 +vshr.u32 q1,q1,#7 +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 d0,[r2,: 64] +add r2,r3,#48 +add r6,r3,#192 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r6,: 128]! +vst1.8 {d2-d3},[r6,: 128]! +vst1.8 d4,[r6,: 64] +._mainloop: +mov r2,r5,LSR #3 +and r6,r5,#7 +ldrb r2,[r1,r2] +mov r2,r2,LSR r6 +and r2,r2,#1 +str r5,[sp,#488] +eor r4,r4,r2 +str r2,[sp,#492] +neg r2,r4 +add r4,r3,#96 +add r5,r3,#192 +add r6,r3,#144 +vld1.8 {d8-d9},[r4,: 128]! +add r7,r3,#240 +vld1.8 {d10-d11},[r5,: 128]! +veor q6,q4,q5 +vld1.8 {d14-d15},[r6,: 128]! +vdup.i32 q8,r2 +vld1.8 {d18-d19},[r7,: 128]! +veor q10,q7,q9 +vld1.8 {d22-d23},[r4,: 128]! +vand q6,q6,q8 +vld1.8 {d24-d25},[r5,: 128]! +vand q10,q10,q8 +vld1.8 {d26-d27},[r6,: 128]! +veor q4,q4,q6 +vld1.8 {d28-d29},[r7,: 128]! +veor q5,q5,q6 +vld1.8 {d0},[r4,: 64] +veor q6,q7,q10 +vld1.8 {d2},[r5,: 64] +veor q7,q9,q10 +vld1.8 {d4},[r6,: 64] +veor q9,q11,q12 +vld1.8 {d6},[r7,: 64] +veor q10,q0,q1 +sub r2,r4,#32 +vand q9,q9,q8 +sub r4,r5,#32 +vand q10,q10,q8 +sub r5,r6,#32 +veor q11,q11,q9 +sub r6,r7,#32 +veor q0,q0,q10 +veor q9,q12,q9 +veor q1,q1,q10 +veor q10,q13,q14 +veor q12,q2,q3 +vand q10,q10,q8 +vand q8,q12,q8 +veor q12,q13,q10 +veor q2,q2,q8 +veor q10,q14,q10 +veor q3,q3,q8 +vadd.i32 q8,q4,q6 +vsub.i32 q4,q4,q6 +vst1.8 {d16-d17},[r2,: 128]! +vadd.i32 q6,q11,q12 +vst1.8 {d8-d9},[r5,: 128]! +vsub.i32 q4,q11,q12 +vst1.8 {d12-d13},[r2,: 128]! +vadd.i32 q6,q0,q2 +vst1.8 {d8-d9},[r5,: 128]! +vsub.i32 q0,q0,q2 +vst1.8 d12,[r2,: 64] +vadd.i32 q2,q5,q7 +vst1.8 d0,[r5,: 64] +vsub.i32 q0,q5,q7 +vst1.8 {d4-d5},[r4,: 128]! +vadd.i32 q2,q9,q10 +vst1.8 {d0-d1},[r6,: 128]! +vsub.i32 q0,q9,q10 +vst1.8 {d4-d5},[r4,: 128]! +vadd.i32 q2,q1,q3 +vst1.8 {d0-d1},[r6,: 128]! +vsub.i32 q0,q1,q3 +vst1.8 d4,[r4,: 64] +vst1.8 d0,[r6,: 64] +add r2,sp,#544 +add r4,r3,#96 +add r5,r3,#144 +vld1.8 {d0-d1},[r2,: 128] +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4-d5},[r5,: 128]! +vzip.i32 q1,q2 +vld1.8 {d6-d7},[r4,: 128]! +vld1.8 {d8-d9},[r5,: 128]! +vshl.i32 q5,q1,#1 +vzip.i32 q3,q4 +vshl.i32 q6,q2,#1 +vld1.8 {d14},[r4,: 64] +vshl.i32 q8,q3,#1 +vld1.8 {d15},[r5,: 64] +vshl.i32 q9,q4,#1 +vmul.i32 d21,d7,d1 +vtrn.32 d14,d15 +vmul.i32 q11,q4,q0 +vmul.i32 q0,q7,q0 +vmull.s32 q12,d2,d2 +vmlal.s32 q12,d11,d1 +vmlal.s32 q12,d12,d0 +vmlal.s32 q12,d13,d23 +vmlal.s32 q12,d16,d22 +vmlal.s32 q12,d7,d21 +vmull.s32 q10,d2,d11 +vmlal.s32 q10,d4,d1 +vmlal.s32 q10,d13,d0 +vmlal.s32 q10,d6,d23 +vmlal.s32 q10,d17,d22 +vmull.s32 q13,d10,d4 +vmlal.s32 q13,d11,d3 +vmlal.s32 q13,d13,d1 +vmlal.s32 q13,d16,d0 +vmlal.s32 q13,d17,d23 +vmlal.s32 q13,d8,d22 +vmull.s32 q1,d10,d5 +vmlal.s32 q1,d11,d4 +vmlal.s32 q1,d6,d1 +vmlal.s32 q1,d17,d0 +vmlal.s32 q1,d8,d23 +vmull.s32 q14,d10,d6 +vmlal.s32 q14,d11,d13 +vmlal.s32 q14,d4,d4 +vmlal.s32 q14,d17,d1 +vmlal.s32 q14,d18,d0 +vmlal.s32 q14,d9,d23 +vmull.s32 q11,d10,d7 +vmlal.s32 q11,d11,d6 +vmlal.s32 q11,d12,d5 +vmlal.s32 q11,d8,d1 +vmlal.s32 q11,d19,d0 +vmull.s32 q15,d10,d8 +vmlal.s32 q15,d11,d17 +vmlal.s32 q15,d12,d6 +vmlal.s32 q15,d13,d5 +vmlal.s32 q15,d19,d1 +vmlal.s32 q15,d14,d0 +vmull.s32 q2,d10,d9 +vmlal.s32 q2,d11,d8 +vmlal.s32 q2,d12,d7 +vmlal.s32 q2,d13,d6 +vmlal.s32 q2,d14,d1 +vmull.s32 q0,d15,d1 +vmlal.s32 q0,d10,d14 +vmlal.s32 q0,d11,d19 +vmlal.s32 q0,d12,d8 +vmlal.s32 q0,d13,d17 +vmlal.s32 q0,d6,d6 +add r2,sp,#512 +vld1.8 {d18-d19},[r2,: 128] +vmull.s32 q3,d16,d7 +vmlal.s32 q3,d10,d15 +vmlal.s32 q3,d11,d14 +vmlal.s32 q3,d12,d9 +vmlal.s32 q3,d13,d8 +add r2,sp,#528 +vld1.8 {d8-d9},[r2,: 128] +vadd.i64 q5,q12,q9 +vadd.i64 q6,q15,q9 +vshr.s64 q5,q5,#26 +vshr.s64 q6,q6,#26 +vadd.i64 q7,q10,q5 +vshl.i64 q5,q5,#26 +vadd.i64 q8,q7,q4 +vadd.i64 q2,q2,q6 +vshl.i64 q6,q6,#26 +vadd.i64 q10,q2,q4 +vsub.i64 q5,q12,q5 +vshr.s64 q8,q8,#25 +vsub.i64 q6,q15,q6 +vshr.s64 q10,q10,#25 +vadd.i64 q12,q13,q8 +vshl.i64 q8,q8,#25 +vadd.i64 q13,q12,q9 +vadd.i64 q0,q0,q10 +vsub.i64 q7,q7,q8 +vshr.s64 q8,q13,#26 +vshl.i64 q10,q10,#25 +vadd.i64 q13,q0,q9 +vadd.i64 q1,q1,q8 +vshl.i64 q8,q8,#26 +vadd.i64 q15,q1,q4 +vsub.i64 q2,q2,q10 +vshr.s64 q10,q13,#26 +vsub.i64 q8,q12,q8 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q10 +vshl.i64 q10,q10,#26 +vadd.i64 q13,q3,q4 +vadd.i64 q14,q14,q12 +add r2,r3,#288 +vshl.i64 q12,q12,#25 +add r4,r3,#336 +vadd.i64 q15,q14,q9 +add r2,r2,#8 +vsub.i64 q0,q0,q10 +add r4,r4,#8 +vshr.s64 q10,q13,#25 +vsub.i64 q1,q1,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q13,q10,q10 +vadd.i64 q11,q11,q12 +vtrn.32 d16,d2 +vshl.i64 q12,q12,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q11,q4 +vadd.i64 q4,q5,q13 +vst1.8 d16,[r2,: 64]! +vshl.i64 q5,q10,#4 +vst1.8 d17,[r4,: 64]! +vsub.i64 q8,q14,q12 +vshr.s64 q1,q1,#25 +vadd.i64 q4,q4,q5 +vadd.i64 q5,q6,q1 +vshl.i64 q1,q1,#25 +vadd.i64 q6,q5,q9 +vadd.i64 q4,q4,q10 +vshl.i64 q10,q10,#25 +vadd.i64 q9,q4,q9 +vsub.i64 q1,q11,q1 +vshr.s64 q6,q6,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d16,d2 +vshr.s64 q9,q9,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q2,q6 +vst1.8 d16,[r2,: 64] +vshl.i64 q2,q6,#26 +vst1.8 d17,[r4,: 64] +vadd.i64 q6,q7,q9 +vtrn.32 d0,d6 +vshl.i64 q7,q9,#26 +vtrn.32 d1,d7 +vsub.i64 q2,q5,q2 +add r2,r2,#16 +vsub.i64 q3,q4,q7 +vst1.8 d0,[r2,: 64] +add r4,r4,#16 +vst1.8 d1,[r4,: 64] +vtrn.32 d4,d2 +vtrn.32 d5,d3 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d6,d12 +vtrn.32 d7,d13 +vst1.8 d4,[r2,: 64] +vst1.8 d5,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d6,[r2,: 64] +vst1.8 d7,[r4,: 64] +add r2,r3,#240 +add r4,r3,#96 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#144 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#192 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#144 +vshl.i64 q7,q7,#25 +add r4,r3,#96 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +add r2,r3,#288 +add r4,r3,#336 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vsub.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4-d5},[r4,: 128]! +vsub.i32 q1,q1,q2 +add r5,r3,#240 +vld1.8 {d4},[r2,: 64] +vld1.8 {d6},[r4,: 64] +vsub.i32 q2,q2,q3 +vst1.8 {d0-d1},[r5,: 128]! +vst1.8 {d2-d3},[r5,: 128]! +vst1.8 d4,[r5,: 64] +add r2,r3,#144 +add r4,r3,#96 +add r5,r3,#144 +add r6,r3,#192 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vsub.i32 q2,q0,q1 +vadd.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d6-d7},[r4,: 128]! +vsub.i32 q4,q1,q3 +vadd.i32 q1,q1,q3 +vld1.8 {d6},[r2,: 64] +vld1.8 {d10},[r4,: 64] +vsub.i32 q6,q3,q5 +vadd.i32 q3,q3,q5 +vst1.8 {d4-d5},[r5,: 128]! +vst1.8 {d0-d1},[r6,: 128]! +vst1.8 {d8-d9},[r5,: 128]! +vst1.8 {d2-d3},[r6,: 128]! +vst1.8 d12,[r5,: 64] +vst1.8 d6,[r6,: 64] +add r2,r3,#0 +add r4,r3,#240 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#336 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#288 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#288 +vshl.i64 q7,q7,#25 +add r4,r3,#96 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +add r2,sp,#544 +add r4,r3,#144 +add r5,r3,#192 +vld1.8 {d0-d1},[r2,: 128] +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4-d5},[r5,: 128]! +vzip.i32 q1,q2 +vld1.8 {d6-d7},[r4,: 128]! +vld1.8 {d8-d9},[r5,: 128]! +vshl.i32 q5,q1,#1 +vzip.i32 q3,q4 +vshl.i32 q6,q2,#1 +vld1.8 {d14},[r4,: 64] +vshl.i32 q8,q3,#1 +vld1.8 {d15},[r5,: 64] +vshl.i32 q9,q4,#1 +vmul.i32 d21,d7,d1 +vtrn.32 d14,d15 +vmul.i32 q11,q4,q0 +vmul.i32 q0,q7,q0 +vmull.s32 q12,d2,d2 +vmlal.s32 q12,d11,d1 +vmlal.s32 q12,d12,d0 +vmlal.s32 q12,d13,d23 +vmlal.s32 q12,d16,d22 +vmlal.s32 q12,d7,d21 +vmull.s32 q10,d2,d11 +vmlal.s32 q10,d4,d1 +vmlal.s32 q10,d13,d0 +vmlal.s32 q10,d6,d23 +vmlal.s32 q10,d17,d22 +vmull.s32 q13,d10,d4 +vmlal.s32 q13,d11,d3 +vmlal.s32 q13,d13,d1 +vmlal.s32 q13,d16,d0 +vmlal.s32 q13,d17,d23 +vmlal.s32 q13,d8,d22 +vmull.s32 q1,d10,d5 +vmlal.s32 q1,d11,d4 +vmlal.s32 q1,d6,d1 +vmlal.s32 q1,d17,d0 +vmlal.s32 q1,d8,d23 +vmull.s32 q14,d10,d6 +vmlal.s32 q14,d11,d13 +vmlal.s32 q14,d4,d4 +vmlal.s32 q14,d17,d1 +vmlal.s32 q14,d18,d0 +vmlal.s32 q14,d9,d23 +vmull.s32 q11,d10,d7 +vmlal.s32 q11,d11,d6 +vmlal.s32 q11,d12,d5 +vmlal.s32 q11,d8,d1 +vmlal.s32 q11,d19,d0 +vmull.s32 q15,d10,d8 +vmlal.s32 q15,d11,d17 +vmlal.s32 q15,d12,d6 +vmlal.s32 q15,d13,d5 +vmlal.s32 q15,d19,d1 +vmlal.s32 q15,d14,d0 +vmull.s32 q2,d10,d9 +vmlal.s32 q2,d11,d8 +vmlal.s32 q2,d12,d7 +vmlal.s32 q2,d13,d6 +vmlal.s32 q2,d14,d1 +vmull.s32 q0,d15,d1 +vmlal.s32 q0,d10,d14 +vmlal.s32 q0,d11,d19 +vmlal.s32 q0,d12,d8 +vmlal.s32 q0,d13,d17 +vmlal.s32 q0,d6,d6 +add r2,sp,#512 +vld1.8 {d18-d19},[r2,: 128] +vmull.s32 q3,d16,d7 +vmlal.s32 q3,d10,d15 +vmlal.s32 q3,d11,d14 +vmlal.s32 q3,d12,d9 +vmlal.s32 q3,d13,d8 +add r2,sp,#528 +vld1.8 {d8-d9},[r2,: 128] +vadd.i64 q5,q12,q9 +vadd.i64 q6,q15,q9 +vshr.s64 q5,q5,#26 +vshr.s64 q6,q6,#26 +vadd.i64 q7,q10,q5 +vshl.i64 q5,q5,#26 +vadd.i64 q8,q7,q4 +vadd.i64 q2,q2,q6 +vshl.i64 q6,q6,#26 +vadd.i64 q10,q2,q4 +vsub.i64 q5,q12,q5 +vshr.s64 q8,q8,#25 +vsub.i64 q6,q15,q6 +vshr.s64 q10,q10,#25 +vadd.i64 q12,q13,q8 +vshl.i64 q8,q8,#25 +vadd.i64 q13,q12,q9 +vadd.i64 q0,q0,q10 +vsub.i64 q7,q7,q8 +vshr.s64 q8,q13,#26 +vshl.i64 q10,q10,#25 +vadd.i64 q13,q0,q9 +vadd.i64 q1,q1,q8 +vshl.i64 q8,q8,#26 +vadd.i64 q15,q1,q4 +vsub.i64 q2,q2,q10 +vshr.s64 q10,q13,#26 +vsub.i64 q8,q12,q8 +vshr.s64 q12,q15,#25 +vadd.i64 q3,q3,q10 +vshl.i64 q10,q10,#26 +vadd.i64 q13,q3,q4 +vadd.i64 q14,q14,q12 +add r2,r3,#144 +vshl.i64 q12,q12,#25 +add r4,r3,#192 +vadd.i64 q15,q14,q9 +add r2,r2,#8 +vsub.i64 q0,q0,q10 +add r4,r4,#8 +vshr.s64 q10,q13,#25 +vsub.i64 q1,q1,q12 +vshr.s64 q12,q15,#26 +vadd.i64 q13,q10,q10 +vadd.i64 q11,q11,q12 +vtrn.32 d16,d2 +vshl.i64 q12,q12,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q11,q4 +vadd.i64 q4,q5,q13 +vst1.8 d16,[r2,: 64]! +vshl.i64 q5,q10,#4 +vst1.8 d17,[r4,: 64]! +vsub.i64 q8,q14,q12 +vshr.s64 q1,q1,#25 +vadd.i64 q4,q4,q5 +vadd.i64 q5,q6,q1 +vshl.i64 q1,q1,#25 +vadd.i64 q6,q5,q9 +vadd.i64 q4,q4,q10 +vshl.i64 q10,q10,#25 +vadd.i64 q9,q4,q9 +vsub.i64 q1,q11,q1 +vshr.s64 q6,q6,#26 +vsub.i64 q3,q3,q10 +vtrn.32 d16,d2 +vshr.s64 q9,q9,#26 +vtrn.32 d17,d3 +vadd.i64 q1,q2,q6 +vst1.8 d16,[r2,: 64] +vshl.i64 q2,q6,#26 +vst1.8 d17,[r4,: 64] +vadd.i64 q6,q7,q9 +vtrn.32 d0,d6 +vshl.i64 q7,q9,#26 +vtrn.32 d1,d7 +vsub.i64 q2,q5,q2 +add r2,r2,#16 +vsub.i64 q3,q4,q7 +vst1.8 d0,[r2,: 64] +add r4,r4,#16 +vst1.8 d1,[r4,: 64] +vtrn.32 d4,d2 +vtrn.32 d5,d3 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d6,d12 +vtrn.32 d7,d13 +vst1.8 d4,[r2,: 64] +vst1.8 d5,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d6,[r2,: 64] +vst1.8 d7,[r4,: 64] +add r2,r3,#336 +add r4,r3,#288 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vadd.i32 q0,q0,q1 +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4-d5},[r4,: 128]! +vadd.i32 q1,q1,q2 +add r5,r3,#288 +vld1.8 {d4},[r2,: 64] +vld1.8 {d6},[r4,: 64] +vadd.i32 q2,q2,q3 +vst1.8 {d0-d1},[r5,: 128]! +vst1.8 {d2-d3},[r5,: 128]! +vst1.8 d4,[r5,: 64] +add r2,r3,#48 +add r4,r3,#144 +vld1.8 {d0-d1},[r4,: 128]! +vld1.8 {d2-d3},[r4,: 128]! +vld1.8 {d4},[r4,: 64] +add r4,r3,#288 +vld1.8 {d6-d7},[r4,: 128]! +vtrn.32 q0,q3 +vld1.8 {d8-d9},[r4,: 128]! +vshl.i32 q5,q0,#4 +vtrn.32 q1,q4 +vshl.i32 q6,q3,#4 +vadd.i32 q5,q5,q0 +vadd.i32 q6,q6,q3 +vshl.i32 q7,q1,#4 +vld1.8 {d5},[r4,: 64] +vshl.i32 q8,q4,#4 +vtrn.32 d4,d5 +vadd.i32 q7,q7,q1 +vadd.i32 q8,q8,q4 +vld1.8 {d18-d19},[r2,: 128]! +vshl.i32 q10,q2,#4 +vld1.8 {d22-d23},[r2,: 128]! +vadd.i32 q10,q10,q2 +vld1.8 {d24},[r2,: 64] +vadd.i32 q5,q5,q0 +add r2,r3,#240 +vld1.8 {d26-d27},[r2,: 128]! +vadd.i32 q6,q6,q3 +vld1.8 {d28-d29},[r2,: 128]! +vadd.i32 q8,q8,q4 +vld1.8 {d25},[r2,: 64] +vadd.i32 q10,q10,q2 +vtrn.32 q9,q13 +vadd.i32 q7,q7,q1 +vadd.i32 q5,q5,q0 +vtrn.32 q11,q14 +vadd.i32 q6,q6,q3 +add r2,sp,#560 +vadd.i32 q10,q10,q2 +vtrn.32 d24,d25 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q6,q13,#1 +add r2,sp,#576 +vst1.8 {d20-d21},[r2,: 128] +vshl.i32 q10,q14,#1 +add r2,sp,#592 +vst1.8 {d12-d13},[r2,: 128] +vshl.i32 q15,q12,#1 +vadd.i32 q8,q8,q4 +vext.32 d10,d31,d30,#0 +vadd.i32 q7,q7,q1 +add r2,sp,#608 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q8,d18,d5 +vmlal.s32 q8,d26,d4 +vmlal.s32 q8,d19,d9 +vmlal.s32 q8,d27,d3 +vmlal.s32 q8,d22,d8 +vmlal.s32 q8,d28,d2 +vmlal.s32 q8,d23,d7 +vmlal.s32 q8,d29,d1 +vmlal.s32 q8,d24,d6 +vmlal.s32 q8,d25,d0 +add r2,sp,#624 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q2,d18,d4 +vmlal.s32 q2,d12,d9 +vmlal.s32 q2,d13,d8 +vmlal.s32 q2,d19,d3 +vmlal.s32 q2,d22,d2 +vmlal.s32 q2,d23,d1 +vmlal.s32 q2,d24,d0 +add r2,sp,#640 +vst1.8 {d20-d21},[r2,: 128] +vmull.s32 q7,d18,d9 +vmlal.s32 q7,d26,d3 +vmlal.s32 q7,d19,d8 +vmlal.s32 q7,d27,d2 +vmlal.s32 q7,d22,d7 +vmlal.s32 q7,d28,d1 +vmlal.s32 q7,d23,d6 +vmlal.s32 q7,d29,d0 +add r2,sp,#656 +vst1.8 {d10-d11},[r2,: 128] +vmull.s32 q5,d18,d3 +vmlal.s32 q5,d19,d2 +vmlal.s32 q5,d22,d1 +vmlal.s32 q5,d23,d0 +vmlal.s32 q5,d12,d8 +add r2,sp,#672 +vst1.8 {d16-d17},[r2,: 128] +vmull.s32 q4,d18,d8 +vmlal.s32 q4,d26,d2 +vmlal.s32 q4,d19,d7 +vmlal.s32 q4,d27,d1 +vmlal.s32 q4,d22,d6 +vmlal.s32 q4,d28,d0 +vmull.s32 q8,d18,d7 +vmlal.s32 q8,d26,d1 +vmlal.s32 q8,d19,d6 +vmlal.s32 q8,d27,d0 +add r2,sp,#576 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q7,d24,d21 +vmlal.s32 q7,d25,d20 +vmlal.s32 q4,d23,d21 +vmlal.s32 q4,d29,d20 +vmlal.s32 q8,d22,d21 +vmlal.s32 q8,d28,d20 +vmlal.s32 q5,d24,d20 +add r2,sp,#576 +vst1.8 {d14-d15},[r2,: 128] +vmull.s32 q7,d18,d6 +vmlal.s32 q7,d26,d0 +add r2,sp,#656 +vld1.8 {d30-d31},[r2,: 128] +vmlal.s32 q2,d30,d21 +vmlal.s32 q7,d19,d21 +vmlal.s32 q7,d27,d20 +add r2,sp,#624 +vld1.8 {d26-d27},[r2,: 128] +vmlal.s32 q4,d25,d27 +vmlal.s32 q8,d29,d27 +vmlal.s32 q8,d25,d26 +vmlal.s32 q7,d28,d27 +vmlal.s32 q7,d29,d26 +add r2,sp,#608 +vld1.8 {d28-d29},[r2,: 128] +vmlal.s32 q4,d24,d29 +vmlal.s32 q8,d23,d29 +vmlal.s32 q8,d24,d28 +vmlal.s32 q7,d22,d29 +vmlal.s32 q7,d23,d28 +add r2,sp,#608 +vst1.8 {d8-d9},[r2,: 128] +add r2,sp,#560 +vld1.8 {d8-d9},[r2,: 128] +vmlal.s32 q7,d24,d9 +vmlal.s32 q7,d25,d31 +vmull.s32 q1,d18,d2 +vmlal.s32 q1,d19,d1 +vmlal.s32 q1,d22,d0 +vmlal.s32 q1,d24,d27 +vmlal.s32 q1,d23,d20 +vmlal.s32 q1,d12,d7 +vmlal.s32 q1,d13,d6 +vmull.s32 q6,d18,d1 +vmlal.s32 q6,d19,d0 +vmlal.s32 q6,d23,d27 +vmlal.s32 q6,d22,d20 +vmlal.s32 q6,d24,d26 +vmull.s32 q0,d18,d0 +vmlal.s32 q0,d22,d27 +vmlal.s32 q0,d23,d26 +vmlal.s32 q0,d24,d31 +vmlal.s32 q0,d19,d20 +add r2,sp,#640 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q2,d18,d7 +vmlal.s32 q2,d19,d6 +vmlal.s32 q5,d18,d6 +vmlal.s32 q5,d19,d21 +vmlal.s32 q1,d18,d21 +vmlal.s32 q1,d19,d29 +vmlal.s32 q0,d18,d28 +vmlal.s32 q0,d19,d9 +vmlal.s32 q6,d18,d29 +vmlal.s32 q6,d19,d28 +add r2,sp,#592 +vld1.8 {d18-d19},[r2,: 128] +add r2,sp,#512 +vld1.8 {d22-d23},[r2,: 128] +vmlal.s32 q5,d19,d7 +vmlal.s32 q0,d18,d21 +vmlal.s32 q0,d19,d29 +vmlal.s32 q6,d18,d6 +add r2,sp,#528 +vld1.8 {d6-d7},[r2,: 128] +vmlal.s32 q6,d19,d21 +add r2,sp,#576 +vld1.8 {d18-d19},[r2,: 128] +vmlal.s32 q0,d30,d8 +add r2,sp,#672 +vld1.8 {d20-d21},[r2,: 128] +vmlal.s32 q5,d30,d29 +add r2,sp,#608 +vld1.8 {d24-d25},[r2,: 128] +vmlal.s32 q1,d30,d28 +vadd.i64 q13,q0,q11 +vadd.i64 q14,q5,q11 +vmlal.s32 q6,d30,d9 +vshr.s64 q4,q13,#26 +vshr.s64 q13,q14,#26 +vadd.i64 q7,q7,q4 +vshl.i64 q4,q4,#26 +vadd.i64 q14,q7,q3 +vadd.i64 q9,q9,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q15,q9,q3 +vsub.i64 q0,q0,q4 +vshr.s64 q4,q14,#25 +vsub.i64 q5,q5,q13 +vshr.s64 q13,q15,#25 +vadd.i64 q6,q6,q4 +vshl.i64 q4,q4,#25 +vadd.i64 q14,q6,q11 +vadd.i64 q2,q2,q13 +vsub.i64 q4,q7,q4 +vshr.s64 q7,q14,#26 +vshl.i64 q13,q13,#25 +vadd.i64 q14,q2,q11 +vadd.i64 q8,q8,q7 +vshl.i64 q7,q7,#26 +vadd.i64 q15,q8,q3 +vsub.i64 q9,q9,q13 +vshr.s64 q13,q14,#26 +vsub.i64 q6,q6,q7 +vshr.s64 q7,q15,#25 +vadd.i64 q10,q10,q13 +vshl.i64 q13,q13,#26 +vadd.i64 q14,q10,q3 +vadd.i64 q1,q1,q7 +add r2,r3,#240 +vshl.i64 q7,q7,#25 +add r4,r3,#144 +vadd.i64 q15,q1,q11 +add r2,r2,#8 +vsub.i64 q2,q2,q13 +add r4,r4,#8 +vshr.s64 q13,q14,#25 +vsub.i64 q7,q8,q7 +vshr.s64 q8,q15,#26 +vadd.i64 q14,q13,q13 +vadd.i64 q12,q12,q8 +vtrn.32 d12,d14 +vshl.i64 q8,q8,#26 +vtrn.32 d13,d15 +vadd.i64 q3,q12,q3 +vadd.i64 q0,q0,q14 +vst1.8 d12,[r2,: 64]! +vshl.i64 q7,q13,#4 +vst1.8 d13,[r4,: 64]! +vsub.i64 q1,q1,q8 +vshr.s64 q3,q3,#25 +vadd.i64 q0,q0,q7 +vadd.i64 q5,q5,q3 +vshl.i64 q3,q3,#25 +vadd.i64 q6,q5,q11 +vadd.i64 q0,q0,q13 +vshl.i64 q7,q13,#25 +vadd.i64 q8,q0,q11 +vsub.i64 q3,q12,q3 +vshr.s64 q6,q6,#26 +vsub.i64 q7,q10,q7 +vtrn.32 d2,d6 +vshr.s64 q8,q8,#26 +vtrn.32 d3,d7 +vadd.i64 q3,q9,q6 +vst1.8 d2,[r2,: 64] +vshl.i64 q6,q6,#26 +vst1.8 d3,[r4,: 64] +vadd.i64 q1,q4,q8 +vtrn.32 d4,d14 +vshl.i64 q4,q8,#26 +vtrn.32 d5,d15 +vsub.i64 q5,q5,q6 +add r2,r2,#16 +vsub.i64 q0,q0,q4 +vst1.8 d4,[r2,: 64] +add r4,r4,#16 +vst1.8 d5,[r4,: 64] +vtrn.32 d10,d6 +vtrn.32 d11,d7 +sub r2,r2,#8 +sub r4,r4,#8 +vtrn.32 d0,d2 +vtrn.32 d1,d3 +vst1.8 d10,[r2,: 64] +vst1.8 d11,[r4,: 64] +sub r2,r2,#24 +sub r4,r4,#24 +vst1.8 d0,[r2,: 64] +vst1.8 d1,[r4,: 64] +ldr r2,[sp,#488] +ldr r4,[sp,#492] +subs r5,r2,#1 +bge ._mainloop +add r1,r3,#144 +add r2,r3,#336 +vld1.8 {d0-d1},[r1,: 128]! +vld1.8 {d2-d3},[r1,: 128]! +vld1.8 {d4},[r1,: 64] +vst1.8 {d0-d1},[r2,: 128]! +vst1.8 {d2-d3},[r2,: 128]! +vst1.8 d4,[r2,: 64] +ldr r1,=0 +._invertloop: +add r2,r3,#144 +ldr r4,=0 +ldr r5,=2 +cmp r1,#1 +ldreq r5,=1 +addeq r2,r3,#336 +addeq r4,r3,#48 +cmp r1,#2 +ldreq r5,=1 +addeq r2,r3,#48 +cmp r1,#3 +ldreq r5,=5 +addeq r4,r3,#336 +cmp r1,#4 +ldreq r5,=10 +cmp r1,#5 +ldreq r5,=20 +cmp r1,#6 +ldreq r5,=10 +addeq r2,r3,#336 +addeq r4,r3,#336 +cmp r1,#7 +ldreq r5,=50 +cmp r1,#8 +ldreq r5,=100 +cmp r1,#9 +ldreq r5,=50 +addeq r2,r3,#336 +cmp r1,#10 +ldreq r5,=5 +addeq r2,r3,#48 +cmp r1,#11 +ldreq r5,=0 +addeq r2,r3,#96 +add r6,r3,#144 +add r7,r3,#288 +vld1.8 {d0-d1},[r6,: 128]! +vld1.8 {d2-d3},[r6,: 128]! +vld1.8 {d4},[r6,: 64] +vst1.8 {d0-d1},[r7,: 128]! +vst1.8 {d2-d3},[r7,: 128]! +vst1.8 d4,[r7,: 64] +cmp r5,#0 +beq ._skipsquaringloop +._squaringloop: +add r6,r3,#288 +add r7,r3,#288 +add r8,r3,#288 +vmov.i32 q0,#19 +vmov.i32 q1,#0 +vmov.i32 q2,#1 +vzip.i32 q1,q2 +vld1.8 {d4-d5},[r7,: 128]! +vld1.8 {d6-d7},[r7,: 128]! +vld1.8 {d9},[r7,: 64] +vld1.8 {d10-d11},[r6,: 128]! +add r7,sp,#416 +vld1.8 {d12-d13},[r6,: 128]! +vmul.i32 q7,q2,q0 +vld1.8 {d8},[r6,: 64] +vext.32 d17,d11,d10,#1 +vmul.i32 q9,q3,q0 +vext.32 d16,d10,d8,#1 +vshl.u32 q10,q5,q1 +vext.32 d22,d14,d4,#1 +vext.32 d24,d18,d6,#1 +vshl.u32 q13,q6,q1 +vshl.u32 d28,d8,d2 +vrev64.i32 d22,d22 +vmul.i32 d1,d9,d1 +vrev64.i32 d24,d24 +vext.32 d29,d8,d13,#1 +vext.32 d0,d1,d9,#1 +vrev64.i32 d0,d0 +vext.32 d2,d9,d1,#1 +vext.32 d23,d15,d5,#1 +vmull.s32 q4,d20,d4 +vrev64.i32 d23,d23 +vmlal.s32 q4,d21,d1 +vrev64.i32 d2,d2 +vmlal.s32 q4,d26,d19 +vext.32 d3,d5,d15,#1 +vmlal.s32 q4,d27,d18 +vrev64.i32 d3,d3 +vmlal.s32 q4,d28,d15 +vext.32 d14,d12,d11,#1 +vmull.s32 q5,d16,d23 +vext.32 d15,d13,d12,#1 +vmlal.s32 q5,d17,d4 +vst1.8 d8,[r7,: 64]! +vmlal.s32 q5,d14,d1 +vext.32 d12,d9,d8,#0 +vmlal.s32 q5,d15,d19 +vmov.i64 d13,#0 +vmlal.s32 q5,d29,d18 +vext.32 d25,d19,d7,#1 +vmlal.s32 q6,d20,d5 +vrev64.i32 d25,d25 +vmlal.s32 q6,d21,d4 +vst1.8 d11,[r7,: 64]! +vmlal.s32 q6,d26,d1 +vext.32 d9,d10,d10,#0 +vmlal.s32 q6,d27,d19 +vmov.i64 d8,#0 +vmlal.s32 q6,d28,d18 +vmlal.s32 q4,d16,d24 +vmlal.s32 q4,d17,d5 +vmlal.s32 q4,d14,d4 +vst1.8 d12,[r7,: 64]! +vmlal.s32 q4,d15,d1 +vext.32 d10,d13,d12,#0 +vmlal.s32 q4,d29,d19 +vmov.i64 d11,#0 +vmlal.s32 q5,d20,d6 +vmlal.s32 q5,d21,d5 +vmlal.s32 q5,d26,d4 +vext.32 d13,d8,d8,#0 +vmlal.s32 q5,d27,d1 +vmov.i64 d12,#0 +vmlal.s32 q5,d28,d19 +vst1.8 d9,[r7,: 64]! +vmlal.s32 q6,d16,d25 +vmlal.s32 q6,d17,d6 +vst1.8 d10,[r7,: 64] +vmlal.s32 q6,d14,d5 +vext.32 d8,d11,d10,#0 +vmlal.s32 q6,d15,d4 +vmov.i64 d9,#0 +vmlal.s32 q6,d29,d1 +vmlal.s32 q4,d20,d7 +vmlal.s32 q4,d21,d6 +vmlal.s32 q4,d26,d5 +vext.32 d11,d12,d12,#0 +vmlal.s32 q4,d27,d4 +vmov.i64 d10,#0 +vmlal.s32 q4,d28,d1 +vmlal.s32 q5,d16,d0 +sub r6,r7,#32 +vmlal.s32 q5,d17,d7 +vmlal.s32 q5,d14,d6 +vext.32 d30,d9,d8,#0 +vmlal.s32 q5,d15,d5 +vld1.8 {d31},[r6,: 64]! +vmlal.s32 q5,d29,d4 +vmlal.s32 q15,d20,d0 +vext.32 d0,d6,d18,#1 +vmlal.s32 q15,d21,d25 +vrev64.i32 d0,d0 +vmlal.s32 q15,d26,d24 +vext.32 d1,d7,d19,#1 +vext.32 d7,d10,d10,#0 +vmlal.s32 q15,d27,d23 +vrev64.i32 d1,d1 +vld1.8 {d6},[r6,: 64] +vmlal.s32 q15,d28,d22 +vmlal.s32 q3,d16,d4 +add r6,r6,#24 +vmlal.s32 q3,d17,d2 +vext.32 d4,d31,d30,#0 +vmov d17,d11 +vmlal.s32 q3,d14,d1 +vext.32 d11,d13,d13,#0 +vext.32 d13,d30,d30,#0 +vmlal.s32 q3,d15,d0 +vext.32 d1,d8,d8,#0 +vmlal.s32 q3,d29,d3 +vld1.8 {d5},[r6,: 64] +sub r6,r6,#16 +vext.32 d10,d6,d6,#0 +vmov.i32 q1,#0xffffffff +vshl.i64 q4,q1,#25 +add r7,sp,#512 +vld1.8 {d14-d15},[r7,: 128] +vadd.i64 q9,q2,q7 +vshl.i64 q1,q1,#26 +vshr.s64 q10,q9,#26 +vld1.8 {d0},[r6,: 64]! +vadd.i64 q5,q5,q10 +vand q9,q9,q1 +vld1.8 {d16},[r6,: 64]! +add r6,sp,#528 +vld1.8 {d20-d21},[r6,: 128] +vadd.i64 q11,q5,q10 +vsub.i64 q2,q2,q9 +vshr.s64 q9,q11,#25 +vext.32 d12,d5,d4,#0 +vand q11,q11,q4 +vadd.i64 q0,q0,q9 +vmov d19,d7 +vadd.i64 q3,q0,q7 +vsub.i64 q5,q5,q11 +vshr.s64 q11,q3,#26 +vext.32 d18,d11,d10,#0 +vand q3,q3,q1 +vadd.i64 q8,q8,q11 +vadd.i64 q11,q8,q10 +vsub.i64 q0,q0,q3 +vshr.s64 q3,q11,#25 +vand q11,q11,q4 +vadd.i64 q3,q6,q3 +vadd.i64 q6,q3,q7 +vsub.i64 q8,q8,q11 +vshr.s64 q11,q6,#26 +vand q6,q6,q1 +vadd.i64 q9,q9,q11 +vadd.i64 d25,d19,d21 +vsub.i64 q3,q3,q6 +vshr.s64 d23,d25,#25 +vand q4,q12,q4 +vadd.i64 d21,d23,d23 +vshl.i64 d25,d23,#4 +vadd.i64 d21,d21,d23 +vadd.i64 d25,d25,d21 +vadd.i64 d4,d4,d25 +vzip.i32 q0,q8 +vadd.i64 d12,d4,d14 +add r6,r8,#8 +vst1.8 d0,[r6,: 64] +vsub.i64 d19,d19,d9 +add r6,r6,#16 +vst1.8 d16,[r6,: 64] +vshr.s64 d22,d12,#26 +vand q0,q6,q1 +vadd.i64 d10,d10,d22 +vzip.i32 q3,q9 +vsub.i64 d4,d4,d0 +sub r6,r6,#8 +vst1.8 d6,[r6,: 64] +add r6,r6,#16 +vst1.8 d18,[r6,: 64] +vzip.i32 q2,q5 +sub r6,r6,#32 +vst1.8 d4,[r6,: 64] +subs r5,r5,#1 +bhi ._squaringloop +._skipsquaringloop: +mov r2,r2 +add r5,r3,#288 +add r6,r3,#144 +vmov.i32 q0,#19 +vmov.i32 q1,#0 +vmov.i32 q2,#1 +vzip.i32 q1,q2 +vld1.8 {d4-d5},[r5,: 128]! +vld1.8 {d6-d7},[r5,: 128]! +vld1.8 {d9},[r5,: 64] +vld1.8 {d10-d11},[r2,: 128]! +add r5,sp,#416 +vld1.8 {d12-d13},[r2,: 128]! +vmul.i32 q7,q2,q0 +vld1.8 {d8},[r2,: 64] +vext.32 d17,d11,d10,#1 +vmul.i32 q9,q3,q0 +vext.32 d16,d10,d8,#1 +vshl.u32 q10,q5,q1 +vext.32 d22,d14,d4,#1 +vext.32 d24,d18,d6,#1 +vshl.u32 q13,q6,q1 +vshl.u32 d28,d8,d2 +vrev64.i32 d22,d22 +vmul.i32 d1,d9,d1 +vrev64.i32 d24,d24 +vext.32 d29,d8,d13,#1 +vext.32 d0,d1,d9,#1 +vrev64.i32 d0,d0 +vext.32 d2,d9,d1,#1 +vext.32 d23,d15,d5,#1 +vmull.s32 q4,d20,d4 +vrev64.i32 d23,d23 +vmlal.s32 q4,d21,d1 +vrev64.i32 d2,d2 +vmlal.s32 q4,d26,d19 +vext.32 d3,d5,d15,#1 +vmlal.s32 q4,d27,d18 +vrev64.i32 d3,d3 +vmlal.s32 q4,d28,d15 +vext.32 d14,d12,d11,#1 +vmull.s32 q5,d16,d23 +vext.32 d15,d13,d12,#1 +vmlal.s32 q5,d17,d4 +vst1.8 d8,[r5,: 64]! +vmlal.s32 q5,d14,d1 +vext.32 d12,d9,d8,#0 +vmlal.s32 q5,d15,d19 +vmov.i64 d13,#0 +vmlal.s32 q5,d29,d18 +vext.32 d25,d19,d7,#1 +vmlal.s32 q6,d20,d5 +vrev64.i32 d25,d25 +vmlal.s32 q6,d21,d4 +vst1.8 d11,[r5,: 64]! +vmlal.s32 q6,d26,d1 +vext.32 d9,d10,d10,#0 +vmlal.s32 q6,d27,d19 +vmov.i64 d8,#0 +vmlal.s32 q6,d28,d18 +vmlal.s32 q4,d16,d24 +vmlal.s32 q4,d17,d5 +vmlal.s32 q4,d14,d4 +vst1.8 d12,[r5,: 64]! +vmlal.s32 q4,d15,d1 +vext.32 d10,d13,d12,#0 +vmlal.s32 q4,d29,d19 +vmov.i64 d11,#0 +vmlal.s32 q5,d20,d6 +vmlal.s32 q5,d21,d5 +vmlal.s32 q5,d26,d4 +vext.32 d13,d8,d8,#0 +vmlal.s32 q5,d27,d1 +vmov.i64 d12,#0 +vmlal.s32 q5,d28,d19 +vst1.8 d9,[r5,: 64]! +vmlal.s32 q6,d16,d25 +vmlal.s32 q6,d17,d6 +vst1.8 d10,[r5,: 64] +vmlal.s32 q6,d14,d5 +vext.32 d8,d11,d10,#0 +vmlal.s32 q6,d15,d4 +vmov.i64 d9,#0 +vmlal.s32 q6,d29,d1 +vmlal.s32 q4,d20,d7 +vmlal.s32 q4,d21,d6 +vmlal.s32 q4,d26,d5 +vext.32 d11,d12,d12,#0 +vmlal.s32 q4,d27,d4 +vmov.i64 d10,#0 +vmlal.s32 q4,d28,d1 +vmlal.s32 q5,d16,d0 +sub r2,r5,#32 +vmlal.s32 q5,d17,d7 +vmlal.s32 q5,d14,d6 +vext.32 d30,d9,d8,#0 +vmlal.s32 q5,d15,d5 +vld1.8 {d31},[r2,: 64]! +vmlal.s32 q5,d29,d4 +vmlal.s32 q15,d20,d0 +vext.32 d0,d6,d18,#1 +vmlal.s32 q15,d21,d25 +vrev64.i32 d0,d0 +vmlal.s32 q15,d26,d24 +vext.32 d1,d7,d19,#1 +vext.32 d7,d10,d10,#0 +vmlal.s32 q15,d27,d23 +vrev64.i32 d1,d1 +vld1.8 {d6},[r2,: 64] +vmlal.s32 q15,d28,d22 +vmlal.s32 q3,d16,d4 +add r2,r2,#24 +vmlal.s32 q3,d17,d2 +vext.32 d4,d31,d30,#0 +vmov d17,d11 +vmlal.s32 q3,d14,d1 +vext.32 d11,d13,d13,#0 +vext.32 d13,d30,d30,#0 +vmlal.s32 q3,d15,d0 +vext.32 d1,d8,d8,#0 +vmlal.s32 q3,d29,d3 +vld1.8 {d5},[r2,: 64] +sub r2,r2,#16 +vext.32 d10,d6,d6,#0 +vmov.i32 q1,#0xffffffff +vshl.i64 q4,q1,#25 +add r5,sp,#512 +vld1.8 {d14-d15},[r5,: 128] +vadd.i64 q9,q2,q7 +vshl.i64 q1,q1,#26 +vshr.s64 q10,q9,#26 +vld1.8 {d0},[r2,: 64]! +vadd.i64 q5,q5,q10 +vand q9,q9,q1 +vld1.8 {d16},[r2,: 64]! +add r2,sp,#528 +vld1.8 {d20-d21},[r2,: 128] +vadd.i64 q11,q5,q10 +vsub.i64 q2,q2,q9 +vshr.s64 q9,q11,#25 +vext.32 d12,d5,d4,#0 +vand q11,q11,q4 +vadd.i64 q0,q0,q9 +vmov d19,d7 +vadd.i64 q3,q0,q7 +vsub.i64 q5,q5,q11 +vshr.s64 q11,q3,#26 +vext.32 d18,d11,d10,#0 +vand q3,q3,q1 +vadd.i64 q8,q8,q11 +vadd.i64 q11,q8,q10 +vsub.i64 q0,q0,q3 +vshr.s64 q3,q11,#25 +vand q11,q11,q4 +vadd.i64 q3,q6,q3 +vadd.i64 q6,q3,q7 +vsub.i64 q8,q8,q11 +vshr.s64 q11,q6,#26 +vand q6,q6,q1 +vadd.i64 q9,q9,q11 +vadd.i64 d25,d19,d21 +vsub.i64 q3,q3,q6 +vshr.s64 d23,d25,#25 +vand q4,q12,q4 +vadd.i64 d21,d23,d23 +vshl.i64 d25,d23,#4 +vadd.i64 d21,d21,d23 +vadd.i64 d25,d25,d21 +vadd.i64 d4,d4,d25 +vzip.i32 q0,q8 +vadd.i64 d12,d4,d14 +add r2,r6,#8 +vst1.8 d0,[r2,: 64] +vsub.i64 d19,d19,d9 +add r2,r2,#16 +vst1.8 d16,[r2,: 64] +vshr.s64 d22,d12,#26 +vand q0,q6,q1 +vadd.i64 d10,d10,d22 +vzip.i32 q3,q9 +vsub.i64 d4,d4,d0 +sub r2,r2,#8 +vst1.8 d6,[r2,: 64] +add r2,r2,#16 +vst1.8 d18,[r2,: 64] +vzip.i32 q2,q5 +sub r2,r2,#32 +vst1.8 d4,[r2,: 64] +cmp r4,#0 +beq ._skippostcopy +add r2,r3,#144 +mov r4,r4 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r4,: 128]! +vst1.8 {d2-d3},[r4,: 128]! +vst1.8 d4,[r4,: 64] +._skippostcopy: +cmp r1,#1 +bne ._skipfinalcopy +add r2,r3,#288 +add r4,r3,#144 +vld1.8 {d0-d1},[r2,: 128]! +vld1.8 {d2-d3},[r2,: 128]! +vld1.8 {d4},[r2,: 64] +vst1.8 {d0-d1},[r4,: 128]! +vst1.8 {d2-d3},[r4,: 128]! +vst1.8 d4,[r4,: 64] +._skipfinalcopy: +add r1,r1,#1 +cmp r1,#12 +blo ._invertloop +add r1,r3,#144 +ldr r2,[r1],#4 +ldr r3,[r1],#4 +ldr r4,[r1],#4 +ldr r5,[r1],#4 +ldr r6,[r1],#4 +ldr r7,[r1],#4 +ldr r8,[r1],#4 +ldr r9,[r1],#4 +ldr r10,[r1],#4 +ldr r1,[r1] +add r11,r1,r1,LSL #4 +add r11,r11,r1,LSL #1 +add r11,r11,#16777216 +mov r11,r11,ASR #25 +add r11,r11,r2 +mov r11,r11,ASR #26 +add r11,r11,r3 +mov r11,r11,ASR #25 +add r11,r11,r4 +mov r11,r11,ASR #26 +add r11,r11,r5 +mov r11,r11,ASR #25 +add r11,r11,r6 +mov r11,r11,ASR #26 +add r11,r11,r7 +mov r11,r11,ASR #25 +add r11,r11,r8 +mov r11,r11,ASR #26 +add r11,r11,r9 +mov r11,r11,ASR #25 +add r11,r11,r10 +mov r11,r11,ASR #26 +add r11,r11,r1 +mov r11,r11,ASR #25 +add r2,r2,r11 +add r2,r2,r11,LSL #1 +add r2,r2,r11,LSL #4 +mov r11,r2,ASR #26 +add r3,r3,r11 +sub r2,r2,r11,LSL #26 +mov r11,r3,ASR #25 +add r4,r4,r11 +sub r3,r3,r11,LSL #25 +mov r11,r4,ASR #26 +add r5,r5,r11 +sub r4,r4,r11,LSL #26 +mov r11,r5,ASR #25 +add r6,r6,r11 +sub r5,r5,r11,LSL #25 +mov r11,r6,ASR #26 +add r7,r7,r11 +sub r6,r6,r11,LSL #26 +mov r11,r7,ASR #25 +add r8,r8,r11 +sub r7,r7,r11,LSL #25 +mov r11,r8,ASR #26 +add r9,r9,r11 +sub r8,r8,r11,LSL #26 +mov r11,r9,ASR #25 +add r10,r10,r11 +sub r9,r9,r11,LSL #25 +mov r11,r10,ASR #26 +add r1,r1,r11 +sub r10,r10,r11,LSL #26 +mov r11,r1,ASR #25 +sub r1,r1,r11,LSL #25 +add r2,r2,r3,LSL #26 +mov r3,r3,LSR #6 +add r3,r3,r4,LSL #19 +mov r4,r4,LSR #13 +add r4,r4,r5,LSL #13 +mov r5,r5,LSR #19 +add r5,r5,r6,LSL #6 +add r6,r7,r8,LSL #25 +mov r7,r8,LSR #7 +add r7,r7,r9,LSL #19 +mov r8,r9,LSR #13 +add r8,r8,r10,LSL #12 +mov r9,r10,LSR #20 +add r1,r9,r1,LSL #6 +str r2,[r0],#4 +str r3,[r0],#4 +str r4,[r0],#4 +str r5,[r0],#4 +str r6,[r0],#4 +str r7,[r0],#4 +str r8,[r0],#4 +str r1,[r0] +ldrd r4,[sp,#0] +ldrd r6,[sp,#8] +ldrd r8,[sp,#16] +ldrd r10,[sp,#24] +ldr r12,[sp,#480] +ldr r14,[sp,#484] +ldr r0,=0 +mov sp,r12 +vpop {q4,q5,q6,q7} +bx lr + +#endif /* !OPENSSL_NO_ASM && __arm__ && !__APPLE__ */ + +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c new file mode 100644 index 00000000..7b35f9ef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c @@ -0,0 +1,2156 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Some of this code is taken from the ref10 version of Ed25519 in SUPERCOP +// 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as +// public domain. Other parts have been replaced to call into code generated by +// Fiat (https://github.com/mit-plv/fiat-crypto) in //third_party/fiat. +// +// The field functions are shared by Ed25519 and X25519 where possible. + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// Various pre-computed constants. +#include "./curve25519_tables.h" + +#if defined(OPENSSL_NO_ASM) +#define FIAT_25519_NO_ASM +#endif + +#if defined(BORINGSSL_CURVE25519_64BIT) +#include "../../third_party/fiat/curve25519_64.h" +#else +#include "../../third_party/fiat/curve25519_32.h" +#endif // BORINGSSL_CURVE25519_64BIT + + +// Low-level intrinsic operations + +static uint64_t load_3(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + return result; +} + +static uint64_t load_4(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + return result; +} + + +// Field operations. + +#if defined(BORINGSSL_CURVE25519_64BIT) + +typedef uint64_t fe_limb_t; +#define FE_NUM_LIMBS 5 + +// assert_fe asserts that |f| satisfies bounds: +// +// [[0x0 ~> 0x8cccccccccccc], +// [0x0 ~> 0x8cccccccccccc], +// [0x0 ~> 0x8cccccccccccc], +// [0x0 ~> 0x8cccccccccccc], +// [0x0 ~> 0x8cccccccccccc]] +// +// See comments in curve25519_64.h for which functions use these bounds for +// inputs or outputs. +#define assert_fe(f) \ + do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] <= UINT64_C(0x8cccccccccccc)); \ + } \ + } while (0) + +// assert_fe_loose asserts that |f| satisfies bounds: +// +// [[0x0 ~> 0x1a666666666664], +// [0x0 ~> 0x1a666666666664], +// [0x0 ~> 0x1a666666666664], +// [0x0 ~> 0x1a666666666664], +// [0x0 ~> 0x1a666666666664]] +// +// See comments in curve25519_64.h for which functions use these bounds for +// inputs or outputs. +#define assert_fe_loose(f) \ + do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] <= UINT64_C(0x1a666666666664)); \ + } \ + } while (0) + +#else + +typedef uint32_t fe_limb_t; +#define FE_NUM_LIMBS 10 + +// assert_fe asserts that |f| satisfies bounds: +// +// [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], +// [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], +// [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], +// [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], +// [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] +// +// See comments in curve25519_32.h for which functions use these bounds for +// inputs or outputs. +#define assert_fe(f) \ + do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] <= \ + ((_assert_fe_i & 1) ? 0x2333333u : 0x4666666u)); \ + } \ + } while (0) + +// assert_fe_loose asserts that |f| satisfies bounds: +// +// [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], +// [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], +// [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], +// [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], +// [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] +// +// See comments in curve25519_32.h for which functions use these bounds for +// inputs or outputs. +#define assert_fe_loose(f) \ + do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] <= \ + ((_assert_fe_i & 1) ? 0x6999999u : 0xd333332u)); \ + } \ + } while (0) + +#endif // BORINGSSL_CURVE25519_64BIT + +OPENSSL_STATIC_ASSERT(sizeof(fe) == sizeof(fe_limb_t) * FE_NUM_LIMBS, + "fe_limb_t[FE_NUM_LIMBS] is inconsistent with fe"); + +static void fe_frombytes_strict(fe *h, const uint8_t s[32]) { + // |fiat_25519_from_bytes| requires the top-most bit be clear. + assert((s[31] & 0x80) == 0); + fiat_25519_from_bytes(h->v, s); + assert_fe(h->v); +} + +static void fe_frombytes(fe *h, const uint8_t s[32]) { + uint8_t s_copy[32]; + OPENSSL_memcpy(s_copy, s, 32); + s_copy[31] &= 0x7f; + fe_frombytes_strict(h, s_copy); +} + +static void fe_tobytes(uint8_t s[32], const fe *f) { + assert_fe(f->v); + fiat_25519_to_bytes(s, f->v); +} + +// h = 0 +static void fe_0(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); +} + +static void fe_loose_0(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); +} + +// h = 1 +static void fe_1(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); + h->v[0] = 1; +} + +static void fe_loose_1(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); + h->v[0] = 1; +} + +// h = f + g +// Can overlap h with f or g. +static void fe_add(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fiat_25519_add(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +// h = f - g +// Can overlap h with f or g. +static void fe_sub(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fiat_25519_sub(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_carry(fe *h, const fe_loose* f) { + assert_fe_loose(f->v); + fiat_25519_carry(h->v, f->v); + assert_fe(h->v); +} + +static void fe_mul_impl(fe_limb_t out[FE_NUM_LIMBS], + const fe_limb_t in1[FE_NUM_LIMBS], + const fe_limb_t in2[FE_NUM_LIMBS]) { + assert_fe_loose(in1); + assert_fe_loose(in2); + fiat_25519_carry_mul(out, in1, in2); + assert_fe(out); +} + +static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttt(fe *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_sq_tl(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fiat_25519_carry_square(h->v, f->v); + assert_fe(h->v); +} + +static void fe_sq_tt(fe *h, const fe *f) { + assert_fe_loose(f->v); + fiat_25519_carry_square(h->v, f->v); + assert_fe(h->v); +} + +// Replace (f,g) with (g,f) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cswap(fe *f, fe *g, fe_limb_t b) { + b = 0-b; + for (unsigned i = 0; i < FE_NUM_LIMBS; i++) { + fe_limb_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + g->v[i] ^= x; + } +} + +static void fe_mul121666(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fiat_25519_carry_scmul_121666(h->v, f->v); + assert_fe(h->v); +} + +// h = -f +static void fe_neg(fe_loose *h, const fe *f) { + assert_fe(f->v); + fiat_25519_opp(h->v, f->v); + assert_fe_loose(h->v); +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cmov(fe_loose *f, const fe_loose *g, fe_limb_t b) { + // Silence an unused function warning. |fiat_25519_selectznz| isn't quite the + // calling convention the rest of this code wants, so implement it by hand. + // + // TODO(davidben): Switch to fiat's calling convention, or ask fiat to emit a + // different one. + (void)fiat_25519_selectznz; + + b = 0-b; + for (unsigned i = 0; i < FE_NUM_LIMBS; i++) { + fe_limb_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + } +} + +// h = f +static void fe_copy(fe *h, const fe *f) { + OPENSSL_memmove(h, f, sizeof(fe)); +} + +static void fe_copy_lt(fe_loose *h, const fe *f) { + OPENSSL_STATIC_ASSERT(sizeof(fe_loose) == sizeof(fe), + "fe and fe_loose mismatch"); + OPENSSL_memmove(h, f, sizeof(fe)); +} +#if !defined(OPENSSL_SMALL) +static void fe_copy_ll(fe_loose *h, const fe_loose *f) { + OPENSSL_memmove(h, f, sizeof(fe_loose)); +} +#endif // !defined(OPENSSL_SMALL) + +static void fe_loose_invert(fe *out, const fe_loose *z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq_tl(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_tlt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t2, &t0); + fe_mul_ttt(&t1, &t1, &t2); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(out, &t1, &t0); +} + +static void fe_invert(fe *out, const fe *z) { + fe_loose l; + fe_copy_lt(&l, z); + fe_loose_invert(out, &l); +} + +// return 0 if f == 0 +// return 1 if f != 0 +static int fe_isnonzero(const fe_loose *f) { + fe tight; + fe_carry(&tight, f); + uint8_t s[32]; + fe_tobytes(s, &tight); + + static const uint8_t zero[32] = {0}; + return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0; +} + +// return 1 if f is in {1,3,5,...,q-2} +// return 0 if f is in {0,2,4,...,q-1} +static int fe_isnegative(const fe *f) { + uint8_t s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +static void fe_sq2_tt(fe *h, const fe *f) { + // h = f^2 + fe_sq_tt(h, f); + + // h = h + h + fe_loose tmp; + fe_add(&tmp, h, h); + fe_carry(h, &tmp); +} + +static void fe_pow22523(fe *out, const fe *z) { + fe t0; + fe t1; + fe t2; + int i; + + fe_sq_tt(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t0, &t0); + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t0, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t0, &t0); + } + fe_mul_ttt(out, &t0, z); +} + + +// Group operations. + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +static void ge_p3_tobytes(uint8_t s[32], const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t s[32]) { + fe u; + fe_loose v; + fe w; + fe vxx; + fe_loose check; + + fe_frombytes(&h->Y, s); + fe_1(&h->Z); + fe_sq_tt(&w, &h->Y); + fe_mul_ttt(&vxx, &w, &d); + fe_sub(&v, &w, &h->Z); // u = y^2-1 + fe_carry(&u, &v); + fe_add(&v, &vxx, &h->Z); // v = dy^2+1 + + fe_mul_ttl(&w, &u, &v); // w = u*v + fe_pow22523(&h->X, &w); // x = w^((q-5)/8) + fe_mul_ttt(&h->X, &h->X, &u); // x = u*w^((q-5)/8) + + fe_sq_tt(&vxx, &h->X); + fe_mul_ttl(&vxx, &vxx, &v); + fe_sub(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + fe_add(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + return 0; + } + fe_mul_ttt(&h->X, &h->X, &sqrtm1); + } + + if (fe_isnegative(&h->X) != (s[31] >> 7)) { + fe_loose t; + fe_neg(&t, &h->X); + fe_carry(&h->X, &t); + } + + fe_mul_ttt(&h->T, &h->X, &h->Y); + return 1; +} + +static void ge_p2_0(ge_p2 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); +} + +static void ge_p3_0(ge_p3 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); + fe_0(&h->T); +} + +static void ge_cached_0(ge_cached *h) { + fe_loose_1(&h->YplusX); + fe_loose_1(&h->YminusX); + fe_loose_1(&h->Z); + fe_loose_0(&h->T2d); +} + +static void ge_precomp_0(ge_precomp *h) { + fe_loose_1(&h->yplusx); + fe_loose_1(&h->yminusx); + fe_loose_0(&h->xy2d); +} + +// r = p +static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(&r->X, &p->X); + fe_copy(&r->Y, &p->Y); + fe_copy(&r->Z, &p->Z); +} + +// r = p +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(&r->YplusX, &p->Y, &p->X); + fe_sub(&r->YminusX, &p->Y, &p->X); + fe_copy_lt(&r->Z, &p->Z); + fe_mul_ltt(&r->T2d, &p->T, &d2); +} + +// r = p +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); +} + +// r = p +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); + fe_mul_tll(&r->T, &p->X, &p->Y); +} + +// r = p +static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) { + ge_p3 t; + x25519_ge_p1p1_to_p3(&t, p); + x25519_ge_p3_to_cached(r, &t); +} + +// r = 2 * p +static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe trX, trZ, trT; + fe t0; + + fe_sq_tt(&trX, &p->X); + fe_sq_tt(&trZ, &p->Y); + fe_sq2_tt(&trT, &p->Z); + fe_add(&r->Y, &p->X, &p->Y); + fe_sq_tl(&t0, &r->Y); + + fe_add(&r->Y, &trZ, &trX); + fe_sub(&r->Z, &trZ, &trX); + fe_carry(&trZ, &r->Y); + fe_sub(&r->X, &t0, &trZ); + fe_carry(&trZ, &r->Z); + fe_sub(&r->T, &trT, &trZ); +} + +// r = 2 * p +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +// r = p + q +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yplusx); + fe_mul_tll(&trY, &r->Y, &q->yminusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yminusx); + fe_mul_tll(&trY, &r->Y, &q->yplusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +// r = p + q +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YplusX); + fe_mul_tll(&trY, &r->Y, &q->YminusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YminusX); + fe_mul_tll(&trY, &r->Y, &q->YplusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +static uint8_t equal(signed char b, signed char c) { + uint8_t ub = b; + uint8_t uc = c; + uint8_t x = ub ^ uc; // 0: yes; 1..255: no + uint32_t y = x; // 0: yes; 1..255: no + y -= 1; // 4294967295: yes; 0..254: no + y >>= 31; // 1: yes; 0: no + return y; +} + +static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) { + fe_cmov(&t->yplusx, &u->yplusx, b); + fe_cmov(&t->yminusx, &u->yminusx, b); + fe_cmov(&t->xy2d, &u->xy2d, b); +} + +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) { + // precomp_table is first expanded into matching |ge_precomp| + // elements. + ge_precomp multiples[15]; + + unsigned i; + for (i = 0; i < 15; i++) { + // The precomputed table is assumed to already clear the top bit, so + // |fe_frombytes_strict| may be used directly. + const uint8_t *bytes = &precomp_table[i*(2 * 32)]; + fe x, y; + fe_frombytes_strict(&x, bytes); + fe_frombytes_strict(&y, bytes + 32); + + ge_precomp *out = &multiples[i]; + fe_add(&out->yplusx, &y, &x); + fe_sub(&out->yminusx, &y, &x); + fe_mul_ltt(&out->xy2d, &x, &y); + fe_mul_llt(&out->xy2d, &out->xy2d, &d2); + } + + // See the comment above |k25519SmallPrecomp| about the structure of the + // precomputed elements. This loop does 64 additions and 64 doublings to + // calculate the result. + ge_p3_0(h); + + for (i = 63; i < 64; i--) { + unsigned j; + signed char index = 0; + + for (j = 0; j < 4; j++) { + const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7)); + index |= (bit << j); + } + + ge_precomp e; + ge_precomp_0(&e); + + for (j = 1; j < 16; j++) { + cmov(&e, &multiples[j-1], equal(index, j)); + } + + ge_cached cached; + ge_p1p1 r; + x25519_ge_p3_to_cached(&cached, h); + x25519_ge_add(&r, h, &cached); + x25519_ge_p1p1_to_p3(h, &r); + + ge_madd(&r, h, &e); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#if defined(OPENSSL_SMALL) + +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp); +} + +#else + +static uint8_t negative(signed char b) { + uint32_t x = b; + x >>= 31; // 1: yes; 0: no + return x; +} + +static void table_select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + uint8_t bnegative = negative(b); + uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t, &k25519Precomp[pos][0], equal(babs, 1)); + cmov(t, &k25519Precomp[pos][1], equal(babs, 2)); + cmov(t, &k25519Precomp[pos][2], equal(babs, 3)); + cmov(t, &k25519Precomp[pos][3], equal(babs, 4)); + cmov(t, &k25519Precomp[pos][4], equal(babs, 5)); + cmov(t, &k25519Precomp[pos][5], equal(babs, 6)); + cmov(t, &k25519Precomp[pos][6], equal(babs, 7)); + cmov(t, &k25519Precomp[pos][7], equal(babs, 8)); + fe_copy_ll(&minust.yplusx, &t->yminusx); + fe_copy_ll(&minust.yminusx, &t->yplusx); + + // NOTE: the input table is canonical, but types don't encode it + fe tmp; + fe_carry(&tmp, &t->xy2d); + fe_neg(&minust.xy2d, &tmp); + + cmov(t, &minust, bnegative); +} + +// h = a * B +// where a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + // each e[i] is between 0 and 15 + // e[63] is between 0 and 7 + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + // each e[i] is between -8 and 8 + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#endif + +static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) { + fe_cmov(&t->YplusX, &u->YplusX, b); + fe_cmov(&t->YminusX, &u->YminusX, b); + fe_cmov(&t->Z, &u->Z, b); + fe_cmov(&t->T2d, &u->T2d, b); +} + +// r = scalar * A. +// where a = a[0]+256*a[1]+...+256^31 a[31]. +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) { + ge_p2 Ai_p2[8]; + ge_cached Ai[16]; + ge_p1p1 t; + + ge_cached_0(&Ai[0]); + x25519_ge_p3_to_cached(&Ai[1], A); + ge_p3_to_p2(&Ai_p2[1], A); + + unsigned i; + for (i = 2; i < 16; i += 2) { + ge_p2_dbl(&t, &Ai_p2[i / 2]); + ge_p1p1_to_cached(&Ai[i], &t); + if (i < 8) { + x25519_ge_p1p1_to_p2(&Ai_p2[i], &t); + } + x25519_ge_add(&t, A, &Ai[i]); + ge_p1p1_to_cached(&Ai[i + 1], &t); + if (i < 7) { + x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t); + } + } + + ge_p2_0(r); + ge_p3 u; + + for (i = 0; i < 256; i += 4) { + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p3(&u, &t); + + uint8_t index = scalar[31 - i/8]; + index >>= 4 - (i & 4); + index &= 0xf; + + unsigned j; + ge_cached selected; + ge_cached_0(&selected); + for (j = 0; j < 16; j++) { + cmov_cached(&selected, &Ai[j], equal(j, index)); + } + + x25519_ge_add(&t, &u, &selected); + x25519_ge_p1p1_to_p2(r, &t); + } +} + +static void slide(signed char *r, const uint8_t *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +// r = a * A + b * B +// where a = a[0]+256*a[1]+...+256^31 a[31]. +// and b = b[0]+256*b[1]+...+256^31 b[31]. +// B is the Ed25519 base point (x,4/5) with x positive. +static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, + const ge_p3 *A, const uint8_t *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; // A,3A,5A,7A,9A,11A,13A,15A + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + x25519_ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + x25519_ge_p1p1_to_p3(&A2, &t); + x25519_ge_add(&t, &A2, &Ai[0]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[1], &u); + x25519_ge_add(&t, &A2, &Ai[1]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[2], &u); + x25519_ge_add(&t, &A2, &Ai[2]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[3], &u); + x25519_ge_add(&t, &A2, &Ai[3]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[4], &u); + x25519_ge_add(&t, &A2, &Ai[4]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[5], &u); + x25519_ge_add(&t, &A2, &Ai[5]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[6], &u); + x25519_ge_add(&t, &A2, &Ai[6]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[7], &u); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + x25519_ge_p1p1_to_p2(r, &t); + } +} + +// int64_lshift21 returns |a << 21| but is defined when shifting bits into the +// sign bit. This works around a language flaw in C. +static inline int64_t int64_lshift21(int64_t a) { + return (int64_t)((uint64_t)a << 21); +} + +// The set of scalars is \Z/l +// where l = 2^252 + 27742317777372353535851937790883648493. + +// Input: +// s[0]+256*s[1]+...+256^63*s[63] = s +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = s mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// Overwrites s in place. +void x25519_sc_reduce(uint8_t s[64]) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= int64_lshift21(carry12); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= int64_lshift21(carry14); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= int64_lshift21(carry16); + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= int64_lshift21(carry13); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= int64_lshift21(carry15); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, + const uint8_t *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= int64_lshift21(carry12); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= int64_lshift21(carry14); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= int64_lshift21(carry16); + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= int64_lshift21(carry18); + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= int64_lshift21(carry20); + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= int64_lshift21(carry22); + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= int64_lshift21(carry13); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= int64_lshift21(carry15); + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= int64_lshift21(carry17); + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= int64_lshift21(carry19); + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= int64_lshift21(carry21); + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= int64_lshift21(carry12); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= int64_lshift21(carry14); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= int64_lshift21(carry16); + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= int64_lshift21(carry13); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= int64_lshift21(carry15); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= int64_lshift21(carry11); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= int64_lshift21(carry0); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= int64_lshift21(carry1); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= int64_lshift21(carry2); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= int64_lshift21(carry3); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= int64_lshift21(carry4); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= int64_lshift21(carry5); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= int64_lshift21(carry6); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= int64_lshift21(carry7); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= int64_lshift21(carry8); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= int64_lshift21(carry9); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= int64_lshift21(carry10); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { + uint8_t seed[32]; + RAND_bytes(seed, 32); + ED25519_keypair_from_seed(out_public_key, out_private_key, seed); +} + +int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, const uint8_t private_key[64]) { + // NOTE: The documentation on this function says that it returns zero on + // allocation failure. While that can't happen with the current + // implementation, we want to reserve the ability to allocate in this + // implementation in the future. + + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, az + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t nonce[SHA512_DIGEST_LENGTH]; + SHA512_Final(nonce, &hash_ctx); + + x25519_sc_reduce(nonce); + ge_p3 R; + x25519_ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(out_sig, &R); + + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, out_sig, 32); + SHA512_Update(&hash_ctx, private_key + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t hram[SHA512_DIGEST_LENGTH]; + SHA512_Final(hram, &hash_ctx); + + x25519_sc_reduce(hram); + sc_muladd(out_sig + 32, hram, az, nonce); + + return 1; +} + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], const uint8_t public_key[32]) { + ge_p3 A; + if ((signature[63] & 224) != 0 || + !x25519_ge_frombytes_vartime(&A, public_key)) { + return 0; + } + + fe_loose t; + fe_neg(&t, &A.X); + fe_carry(&A.X, &t); + fe_neg(&t, &A.T); + fe_carry(&A.T, &t); + + uint8_t pkcopy[32]; + OPENSSL_memcpy(pkcopy, public_key, 32); + uint8_t rcopy[32]; + OPENSSL_memcpy(rcopy, signature, 32); + union { + uint64_t u64[4]; + uint8_t u8[32]; + } scopy; + OPENSSL_memcpy(&scopy.u8[0], signature + 32, 32); + + // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in + // the range [0, order) in order to prevent signature malleability. + + // kOrder is the order of Curve25519 in little-endian form. + static const uint64_t kOrder[4] = { + UINT64_C(0x5812631a5cf5d3ed), + UINT64_C(0x14def9dea2f79cd6), + 0, + UINT64_C(0x1000000000000000), + }; + for (size_t i = 3;; i--) { + if (scopy.u64[i] > kOrder[i]) { + return 0; + } else if (scopy.u64[i] < kOrder[i]) { + break; + } else if (i == 0) { + return 0; + } + } + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, signature, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t h[SHA512_DIGEST_LENGTH]; + SHA512_Final(h, &hash_ctx); + + x25519_sc_reduce(h); + + ge_p2 R; + ge_double_scalarmult_vartime(&R, h, &A, scopy.u8); + + uint8_t rcheck[32]; + x25519_ge_tobytes(rcheck, &R); + + return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; +} + +void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(seed, 32, az); + + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, az); + ge_p3_tobytes(out_public_key, &A); + + OPENSSL_memcpy(out_private_key, seed, 32); + OPENSSL_memcpy(out_private_key + 32, out_public_key, 32); +} + + +static void x25519_scalar_mult_generic(uint8_t out[32], + const uint8_t scalar[32], + const uint8_t point[32]) { + fe x1, x2, z2, x3, z3, tmp0, tmp1; + fe_loose x2l, z2l, x3l, tmp0l, tmp1l; + + uint8_t e[32]; + OPENSSL_memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + // The following implementation was transcribed to Coq and proven to + // correspond to unary scalar multiplication in affine coordinates given that + // x1 != 0 is the x coordinate of some point on the curve. It was also checked + // in Coq that doing a ladderstep with x1 = x3 = 0 gives z2' = z3' = 0, and z2 + // = z3 = 0 gives z2' = z3' = 0. The statement was quantified over the + // underlying field, so it applies to Curve25519 itself and the quadratic + // twist of Curve25519. It was not proven in Coq that prime-field arithmetic + // correctly simulates extension-field arithmetic on prime-field values. + // The decoding of the byte array representation of e was not considered. + // Specification of Montgomery curves in affine coordinates: + // + // Proof that these form a group that is isomorphic to a Weierstrass curve: + // + // Coq transcription and correctness proof of the loop (where scalarbits=255): + // + // + // preconditions: 0 <= e < 2^255 (not necessarily e < order), fe_invert(0) = 0 + fe_frombytes(&x1, point); + fe_1(&x2); + fe_0(&z2); + fe_copy(&x3, &x1); + fe_1(&z3); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + // loop invariant as of right before the test, for the case where x1 != 0: + // pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 is nonzero + // let r := e >> (pos+1) in the following equalities of projective points: + // to_xz (r*P) === if swap then (x3, z3) else (x2, z2) + // to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3) + // x1 is the nonzero x coordinate of the nonzero point (r*P-(r+1)*P) + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + swap = b; + // Coq transcription of ladderstep formula (called from transcribed loop): + // + // + // x1 != 0 + // x1 = 0 + fe_sub(&tmp0l, &x3, &z3); + fe_sub(&tmp1l, &x2, &z2); + fe_add(&x2l, &x2, &z2); + fe_add(&z2l, &x3, &z3); + fe_mul_tll(&z3, &tmp0l, &x2l); + fe_mul_tll(&z2, &z2l, &tmp1l); + fe_sq_tl(&tmp0, &tmp1l); + fe_sq_tl(&tmp1, &x2l); + fe_add(&x3l, &z3, &z2); + fe_sub(&z2l, &z3, &z2); + fe_mul_ttt(&x2, &tmp1, &tmp0); + fe_sub(&tmp1l, &tmp1, &tmp0); + fe_sq_tl(&z2, &z2l); + fe_mul121666(&z3, &tmp1l); + fe_sq_tl(&x3, &x3l); + fe_add(&tmp0l, &tmp0, &z3); + fe_mul_ttt(&z3, &x1, &z2); + fe_mul_tll(&z2, &tmp1l, &tmp0l); + } + // here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) else (x2, z2) + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + + fe_invert(&z2, &z2); + fe_mul_ttt(&x2, &x2, &z2); + fe_tobytes(out, &x2); +} + +static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + x25519_NEON(out, scalar, point); + return; + } +#endif + + x25519_scalar_mult_generic(out, scalar, point); +} + +void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) { + RAND_bytes(out_private_key, 32); + + // All X25519 implementations should decode scalars correctly (see + // https://tools.ietf.org/html/rfc7748#section-5). However, if an + // implementation doesn't then it might interoperate with random keys a + // fraction of the time because they'll, randomly, happen to be correctly + // formed. + // + // Thus we do the opposite of the masking here to make sure that our private + // keys are never correctly masked and so, hopefully, any incorrect + // implementations are deterministically broken. + // + // This does not affect security because, although we're throwing away + // entropy, a valid implementation of scalarmult should throw away the exact + // same bits anyway. + out_private_key[0] |= ~248; + out_private_key[31] &= ~64; + out_private_key[31] |= ~127; + + X25519_public_from_private(out_public_value, out_private_key); +} + +int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { + static const uint8_t kZeros[32] = {0}; + x25519_scalar_mult(out_shared_key, private_key, peer_public_value); + // The all-zero output results when the input is a point of small order. + return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; +} + +void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + static const uint8_t kMongomeryBasePoint[32] = {9}; + x25519_NEON(out_public_value, private_key, kMongomeryBasePoint); + return; + } +#endif + + uint8_t e[32]; + OPENSSL_memcpy(e, private_key, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, e); + + // We only need the u-coordinate of the curve25519 point. The map is + // u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). + fe_loose zplusy, zminusy; + fe zminusy_inv; + fe_add(&zplusy, &A.Z, &A.Y); + fe_sub(&zminusy, &A.Z, &A.Y); + fe_loose_invert(&zminusy_inv, &zminusy); + fe_mul_tlt(&zminusy_inv, &zplusy, &zminusy_inv); + fe_tobytes(out_public_value, &zminusy_inv); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519_tables.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519_tables.h new file mode 100644 index 00000000..310581cf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/curve25519_tables.h @@ -0,0 +1,7872 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This file is generated from +// ./make_curve25519_tables.py > curve25519_tables.h + + +static const fe d = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, + 1442794654840575 +#else + 56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, + 48412415, 21499315 +#endif +}}; + +static const fe sqrtm1 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, + 765476049583133 +#else + 34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, + 31548777, 326685, 11406482 +#endif +}}; + +static const fe d2 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, + 633789495995903 +#else + 45281625, 27714825, 36363642, 13898781, 229458, 15978800, 54557047, + 27058993, 29715967, 9444199 +#endif +}}; + +#if defined(OPENSSL_SMALL) + +// This block of code replaces the standard base-point table with a much smaller +// one. The standard table is 30,720 bytes while this one is just 960. +// +// This table contains 15 pairs of group elements, (x, y), where each field +// element is serialised with |fe_tobytes|. If |i| is the index of the group +// element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀ +// is the most significant bit). The value of the group element is then: +// (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. +static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, + 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, + 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62, + 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, + 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, + 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61, + 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c, + 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c, + 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5, + 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3, + 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18, + 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, + 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, + 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b, + 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, + 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, + 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb, + 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c, + 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e, + 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e, + 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a, + 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43, + 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53, + 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8, + 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89, + 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef, + 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60, + 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a, + 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8, + 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54, + 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b, + 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd, + 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, + 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, + 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b, + 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, + 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, + 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07, + 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa, + 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a, + 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84, + 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc, + 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42, + 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0, + 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0, + 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a, + 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5, + 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c, + 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27, + 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31, + 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c, + 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87, + 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0, + 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23, + 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2, + 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87, + 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d, + 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b, + 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d, + 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6, + 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84, + 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04, + 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19, + 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b, + 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a, + 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea, + 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30, + 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7, + 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa, + 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5, + 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71, + 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab, + 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb, + 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c, + 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25, +}; + +#else + +// k25519Precomp[i][j] = (j+1)*256^i*B +static const ge_precomp k25519Precomp[32][8] = { + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, + 27544626, 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, + 338455783676468, 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, + 12720692, 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, + 29287918, 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1380971894829527, 790832306631236, 2067202295274102, + 1995808275510000, 1566530869037010 +#else + 54292951, 20578084, 45527620, 11784319, 41753206, 30803714, + 55390960, 29739860, 66750418, 23343128 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 463307831301544, 432984605774163, 1610641361907204, + 750899048855000, 1894842303421586 +#else + 45405608, 6903824, 27185491, 6451973, 37531140, 24000426, + 51492312, 11189267, 40279186, 28235350 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 748439484463711, 1033211726465151, 1396005112841647, + 1611506220286469, 1972177495910992 +#else + 26966623, 11152617, 32442495, 15396054, 14353839, 20802097, + 63980037, 24013313, 51636816, 29387734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, + 27787599, 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, + 16354576, 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, + 7512774, 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 934282339813791, 1846903124198670, 1172395437954843, + 1007037127761661, 1830588347719256 +#else + 50071967, 13921891, 10945806, 27521001, 27105051, 17470053, + 38182653, 15006022, 3284568, 27277892 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694390458783935, 1735906047636159, 705069562067493, + 648033061693059, 696214010414170 +#else + 23599295, 25248385, 55915199, 25867015, 13236773, 10506355, + 7464579, 9656445, 13059162, 10374397 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121406372216585, 192876649532226, 190294192191717, + 1994165897297032, 2245000007398739 +#else + 7798537, 16710257, 3033922, 2874086, 28997861, 2835604, + 32406664, 29715387, 66467155, 33453106 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, + 974092374476333, 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, + 32867885, 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, + 837766094556764, 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, + 41455196, 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, + 28542349, 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1388594989461809, 316767091099457, 394298842192982, + 1230079486801005, 1440737038838979 +#else + 51736881, 20691677, 32573249, 4720197, 40672342, 5875510, + 47920237, 18329612, 57289923, 21468654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7380825640100, 146210432690483, 304903576448906, + 1198869323871120, 997689833219095 +#else + 58559652, 109982, 15149363, 2178705, 22900618, 4543417, 3044240, + 17864545, 1762327, 14866737 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1181317918772081, 114573476638901, 262805072233344, + 265712217171332, 294181933805782 +#else + 48909169, 17603008, 56635573, 1707277, 49922944, 3916100, + 38872452, 3959420, 27914454, 4383652 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, + 350988370788628, 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, + 19480852, 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, + 20654025, 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, + 91986625355052, 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, + 35708204, 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2068619540119183, 1966274918058806, 957728544705549, + 729906502578991, 159834893065166 +#else + 14499471, 30824833, 33917750, 29299779, 28494861, 14271267, + 30290735, 10876454, 33954766, 2381725 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2073601412052185, 31021124762708, 264500969797082, + 248034690651703, 1030252227928288 +#else + 59913433, 30899068, 52378708, 462250, 39384538, 3941371, + 60872247, 3696004, 34808032, 15351954 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 551790716293402, 1989538725166328, 801169423371717, + 2052451893578887, 678432056995012 +#else + 27431194, 8222322, 16448760, 29646437, 48401861, 11938354, + 34147463, 30583916, 29551812, 10109425 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1368953770187805, 790347636712921, 437508475667162, + 2142576377050580, 1932081720066286 +#else + 53451805, 20399000, 35825113, 11777097, 21447386, 6519384, + 64730580, 31926875, 10092782, 28790261 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 953638594433374, 1092333936795051, 1419774766716690, + 805677984380077, 859228993502513 +#else + 27939166, 14210322, 4677035, 16277044, 44144402, 21156292, + 34600109, 12005537, 49298737, 12803509 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1200766035879111, 20142053207432, 1465634435977050, + 1645256912097844, 295121984874596 +#else + 17228999, 17892808, 65875336, 300139, 65883994, 21839654, + 30364212, 24516238, 18016356, 4397660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1735718747031557, 1248237894295956, 1204753118328107, + 976066523550493, 65943769534592 +#else + 56150021, 25864224, 4776340, 18600194, 27850027, 17952220, + 40489757, 14544524, 49631360, 982638 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1060098822528990, 1586825862073490, 212301317240126, + 1975302711403555, 666724059764335 +#else + 29253598, 15796703, 64244882, 23645547, 10057022, 3163536, + 7332899, 29434304, 46061167, 9934962 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1091990273418756, 1572899409348578, 80968014455247, + 306009358661350, 1520450739132526 +#else + 5793284, 16271923, 42977250, 23438027, 29188559, 1206517, + 52360934, 4559894, 36984942, 22656481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1480517209436112, 1511153322193952, 1244343858991172, + 304788150493241, 369136856496443 +#else + 39464912, 22061425, 16282656, 22517939, 28414020, 18542168, + 24191033, 4541697, 53770555, 5500567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151330273626164, 762045184746182, 1688074332551515, + 823046109005759, 907602769079491 +#else + 12650548, 32057319, 9052870, 11355358, 49428827, 25154267, + 49678271, 12264342, 10874051, 13524335 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2047386910586836, 168470092900250, 1552838872594810, + 340951180073789, 360819374702533 +#else + 25556948, 30508442, 714650, 2510400, 23394682, 23139102, + 33119037, 5080568, 44580805, 5376627 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1982622644432056, 2014393600336956, 128909208804214, + 1617792623929191, 105294281913815 +#else + 41020600, 29543379, 50095164, 30016803, 60382070, 1920896, + 44787559, 24106988, 4535767, 1569007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980234343912898, 1712256739246056, 588935272190264, + 204298813091998, 841798321043288 +#else + 64853442, 14606629, 45416424, 25514613, 28430648, 8775819, + 36614302, 3044289, 31848280, 12543772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 197561292938973, 454817274782871, 1963754960082318, + 2113372252160468, 971377527342673 +#else + 45080285, 2943892, 35251351, 6777305, 13784462, 29262229, + 39731668, 31491700, 7718481, 14474653 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 164699448829328, 3127451757672, 1199504971548753, + 1766155447043652, 1899238924683527 +#else + 2385296, 2454213, 44477544, 46602, 62670929, 17874016, 656964, + 26317767, 24316167, 28300865 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 732262946680281, 1674412764227063, 2182456405662809, + 1350894754474250, 558458873295247 +#else + 13741529, 10911568, 33875447, 24950694, 46931033, 32521134, + 33040650, 20129900, 46379407, 8321685 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2103305098582922, 1960809151316468, 715134605001343, + 1454892949167181, 40827143824949 +#else + 21060490, 31341688, 15712756, 29218333, 1639039, 10656336, + 23845965, 21679594, 57124405, 608371 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1239289043050212, 1744654158124578, 758702410031698, + 1796762995074688, 1603056663766 +#else + 53436132, 18466845, 56219170, 25997372, 61071954, 11305546, + 1123968, 26773855, 27229398, 23887 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2232056027107988, 987343914584615, 2115594492994461, + 1819598072792159, 1119305654014850 +#else + 43864724, 33260226, 55364135, 14712570, 37643165, 31524814, + 12797023, 27114124, 65475458, 16678953 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 320153677847348, 939613871605645, 641883205761567, + 1930009789398224, 329165806634126 +#else + 37608244, 4770661, 51054477, 14001337, 7830047, 9564805, + 65600720, 28759386, 49939598, 4904952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980930490474130, 1242488692177893, 1251446316964684, + 1086618677993530, 1961430968465772 +#else + 24059538, 14617003, 19037157, 18514524, 19766092, 18648003, + 5169210, 16191880, 2128236, 29227599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 276821765317453, 1536835591188030, 1305212741412361, + 61473904210175, 2051377036983058 +#else + 50127693, 4124965, 58568254, 22900634, 30336521, 19449185, + 37302527, 916032, 60226322, 30567899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 833449923882501, 1750270368490475, 1123347002068295, + 185477424765687, 278090826653186 +#else + 44477957, 12419371, 59974635, 26081060, 50629959, 16739174, + 285431, 2763829, 15736322, 4143876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 794524995833413, 1849907304548286, 53348672473145, + 1272368559505217, 1147304168324779 +#else + 2379333, 11839345, 62998462, 27565766, 11274297, 794957, 212801, + 18959769, 23527083, 17096164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1504846112759364, 1203096289004681, 562139421471418, + 274333017451844, 1284344053775441 +#else + 33431108, 22423954, 49269897, 17927531, 8909498, 8376530, + 34483524, 4087880, 51919953, 19138217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 483048732424432, 2116063063343382, 30120189902313, + 292451576741007, 1156379271702225 +#else + 1767664, 7197987, 53903638, 31531796, 54017513, 448825, 5799055, + 4357868, 62334673, 17231393 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 928372153029038, 2147692869914564, 1455665844462196, + 1986737809425946, 185207050258089 +#else + 6721966, 13833823, 43585476, 32003117, 26354292, 21691111, + 23365146, 29604700, 7390889, 2759800 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 137732961814206, 706670923917341, 1387038086865771, + 1965643813686352, 1384777115696347 +#else + 4409022, 2052381, 23373853, 10530217, 7676779, 20668478, + 21302352, 29290375, 1244379, 20634787 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 481144981981577, 2053319313589856, 2065402289827512, + 617954271490316, 1106602634668125 +#else + 62687625, 7169618, 4982368, 30596842, 30256824, 30776892, + 14086412, 9208236, 15886429, 16489664 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696298019648792, 893299659040895, 1148636718636009, + 26734077349617, 2203955659340681 +#else + 1996056, 10375649, 14346367, 13311202, 60234729, 17116020, + 53415665, 398368, 36502409, 32841498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 657390353372855, 998499966885562, 991893336905797, + 810470207106761, 343139804608786 +#else + 41801399, 9795879, 64331450, 14878808, 33577029, 14780362, + 13348553, 12076947, 36272402, 5113181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 791736669492960, 934767652997115, 824656780392914, + 1759463253018643, 361530362383518 +#else + 49338080, 11797795, 31950843, 13929123, 41220562, 12288343, + 36767763, 26218045, 13847710, 5387222 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022541353055597, 2094700262587466, 1551008075025686, + 242785517418164, 695985404963562 +#else + 48526701, 30138214, 17824842, 31213466, 22744342, 23111821, + 8763060, 3617786, 47508202, 10370990 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287487199965223, 2215311941380308, 1552928390931986, + 1664859529680196, 1125004975265243 +#else + 20246567, 19185054, 22358228, 33010720, 18507282, 23140436, + 14554436, 24808340, 32232923, 16763880 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 677434665154918, 989582503122485, 1817429540898386, + 1052904935475344, 1143826298169798 +#else + 9648486, 10094563, 26416693, 14745928, 36734546, 27081810, + 11094160, 15689506, 3140038, 17044340 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 367266328308408, 318431188922404, 695629353755355, + 634085657580832, 24581612564426 +#else + 50948792, 5472694, 31895588, 4744994, 8823515, 10365685, + 39884064, 9448612, 38334410, 366294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 773360688841258, 1815381330538070, 363773437667376, + 539629987070205, 783280434248437 +#else + 19153450, 11523972, 56012374, 27051289, 42461232, 5420646, + 28344573, 8041113, 719605, 11671788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 180820816194166, 168937968377394, 748416242794470, + 1227281252254508, 1567587861004268 +#else + 8678006, 2694440, 60300850, 2517371, 4964326, 11152271, + 51675948, 18287915, 27000812, 23358879 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 478775558583645, 2062896624554807, 699391259285399, + 358099408427873, 1277310261461761 +#else + 51950941, 7134311, 8639287, 30739555, 59873175, 10421741, + 564065, 5336097, 6750977, 19033406 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1984740906540026, 1079164179400229, 1056021349262661, + 1659958556483663, 1088529069025527 +#else + 11836410, 29574944, 26297893, 16080799, 23455045, 15735944, + 1695823, 24735310, 8169719, 16220347 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 580736401511151, 1842931091388998, 1177201471228238, + 2075460256527244, 1301133425678027 +#else + 48993007, 8653646, 17578566, 27461813, 59083086, 17541668, + 55964556, 30926767, 61118155, 19388398 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1515728832059182, 1575261009617579, 1510246567196186, + 191078022609704, 116661716289141 +#else + 43800366, 22586119, 15213227, 23473218, 36255258, 22504427, + 27884328, 2847284, 2655861, 1738395 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295295738269652, 1714742313707026, 545583042462581, + 2034411676262552, 1513248090013606 +#else + 39571412, 19301410, 41772562, 25551651, 57738101, 8129820, + 21651608, 30315096, 48021414, 22549153 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 230710545179830, 30821514358353, 760704303452229, + 390668103790604, 573437871383156 +#else + 1533110, 3437855, 23735889, 459276, 29970501, 11335377, + 26030092, 5821408, 10478196, 8544890 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1169380107545646, 263167233745614, 2022901299054448, + 819900753251120, 2023898464874585 +#else + 32173102, 17425121, 24896206, 3921497, 22579056, 30143578, + 19270448, 12217473, 17789017, 30158437 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102254323485823, 1570832666216754, 34696906544624, + 1993213739807337, 70638552271463 +#else + 36555903, 31326030, 51530034, 23407230, 13243888, 517024, + 15479401, 29701199, 30460519, 1052596 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894132856735058, 548675863558441, 845349339503395, + 1942269668326667, 1615682209874691 +#else + 55493970, 13323617, 32618793, 8175907, 51878691, 12596686, + 27491595, 28942073, 3179267, 24075541 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287670217537834, 1222355136884920, 1846481788678694, + 1150426571265110, 1613523400722047 +#else + 31947050, 19187781, 62468280, 18214510, 51982886, 27514722, + 52352086, 17142691, 19072639, 24043372 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 793388516527298, 1315457083650035, 1972286999342417, + 1901825953052455, 338269477222410 +#else + 11685058, 11822410, 3158003, 19601838, 33402193, 29389366, + 5977895, 28339415, 473098, 5040608 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 550201530671806, 778605267108140, 2063911101902983, + 115500557286349, 2041641272971022 +#else + 46817982, 8198641, 39698732, 11602122, 1290375, 30754672, + 28326861, 1721092, 47550222, 30422825 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 717255318455100, 519313764361315, 2080406977303708, + 541981206705521, 774328150311600 +#else + 7881532, 10687937, 7578723, 7738378, 48157852, 31000479, + 21820785, 8076149, 39240368, 11538388 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 261715221532238, 1795354330069993, 1496878026850283, + 499739720521052, 389031152673770 +#else + 47173198, 3899860, 18283497, 26752864, 51380203, 22305220, + 8754524, 7446702, 61432810, 5797015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997217696294013, 1717306351628065, 1684313917746180, + 1644426076011410, 1857378133465451 +#else + 55813245, 29760862, 51326753, 25589858, 12708868, 25098233, + 2014098, 24503858, 64739691, 27677090 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1475434724792648, 76931896285979, 1116729029771667, + 2002544139318042, 725547833803938 +#else + 44636488, 21985690, 39426843, 1146374, 18956691, 16640559, + 1192730, 29840233, 15123618, 10811505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022306639183567, 726296063571875, 315345054448644, + 1058733329149221, 1448201136060677 +#else + 14352079, 30134717, 48166819, 10822654, 32750596, 4699007, + 67038501, 15776355, 38222085, 21579878 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1710065158525665, 1895094923036397, 123988286168546, + 1145519900776355, 1607510767693874 +#else + 38867681, 25481956, 62129901, 28239114, 29416930, 1847569, + 46454691, 17069576, 4714546, 23953777 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 561605375422540, 1071733543815037, 131496498800990, + 1946868434569999, 828138133964203 +#else + 15200332, 8368572, 19679101, 15970074, 35236190, 1959450, + 24611599, 29010600, 55362987, 12340219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1548495173745801, 442310529226540, 998072547000384, + 553054358385281, 644824326376171 +#else + 12876937, 23074376, 33134380, 6590940, 60801088, 14872439, + 9613953, 8241152, 15370987, 9608631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445526537029440, 2225519789662536, 914628859347385, + 1064754194555068, 1660295614401091 +#else + 62965568, 21540023, 8446280, 33162829, 4407737, 13629032, + 59383996, 15866073, 38898243, 24740332 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1199690223111956, 24028135822341, 66638289244341, + 57626156285975, 565093967979607 +#else + 26660628, 17876777, 8393733, 358047, 59707573, 992987, 43204631, + 858696, 20571223, 8420556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 876926774220824, 554618976488214, 1012056309841565, + 839961821554611, 1414499340307677 +#else + 14620696, 13067227, 51661590, 8264466, 14106269, 15080814, + 33531827, 12516406, 45534429, 21077682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 703047626104145, 1266841406201770, 165556500219173, + 486991595001879, 1011325891650656 +#else + 236881, 10476226, 57258, 18877408, 6472997, 2466984, 17258519, + 7256740, 8791136, 15069930 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1622861044480487, 1156394801573634, 1869132565415504, + 327103985777730, 2095342781472284 +#else + 1276391, 24182514, 22949634, 17231625, 43615824, 27852245, + 14711874, 4874229, 36445724, 31223040 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 334886927423922, 489511099221528, 129160865966726, + 1720809113143481, 619700195649254 +#else + 5855666, 4990204, 53397016, 7294283, 59304582, 1924646, + 65685689, 25642053, 34039526, 9234252 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1646545795166119, 1758370782583567, 714746174550637, + 1472693650165135, 898994790308209 +#else + 20590503, 24535444, 31529743, 26201766, 64402029, 10650547, + 31559055, 21944845, 18979185, 13396066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333403773039279, 295772542452938, 1693106465353610, + 912330357530760, 471235657950362 +#else + 24474287, 4968103, 22267082, 4407354, 24063882, 25229252, + 48291976, 13594781, 33514650, 7021958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811196219982022, 1068969825533602, 289602974833439, + 1988956043611592, 863562343398367 +#else + 55541958, 26988926, 45743778, 15928891, 40950559, 4315420, + 41160136, 29637754, 45628383, 12868081 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 906282429780072, 2108672665779781, 432396390473936, + 150625823801893, 1708930497638539 +#else + 38473832, 13504660, 19988037, 31421671, 21078224, 6443208, + 45662757, 2244499, 54653067, 25465048 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 925664675702328, 21416848568684, 1831436641861340, + 601157008940113, 371818055044496 +#else + 36513336, 13793478, 61256044, 319135, 41385692, 27290532, + 33086545, 8957937, 51875216, 5540520 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1479786007267725, 1738881859066675, 68646196476567, + 2146507056100328, 1247662817535471 +#else + 55478669, 22050529, 58989363, 25911358, 2620055, 1022908, + 43398120, 31985447, 50980335, 18591624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 52035296774456, 939969390708103, 312023458773250, + 59873523517659, 1231345905848899 +#else + 23152952, 775386, 27395463, 14006635, 57407746, 4649511, + 1689819, 892185, 55595587, 18348483 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 643355106415761, 290186807495774, 2013561737429023, + 319648069511546, 393736678496162 +#else + 9770129, 9586738, 26496094, 4324120, 1556511, 30004408, + 27453818, 4763127, 47929250, 5867133 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 129358342392716, 1932811617704777, 1176749390799681, + 398040349861790, 1170779668090425 +#else + 34343820, 1927589, 31726409, 28801137, 23962433, 17534932, + 27846558, 5931263, 37359161, 17445976 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051980782668029, 121859921510665, 2048329875753063, + 1235229850149665, 519062146124755 +#else + 27461885, 30576896, 22380809, 1815854, 44075111, 30522493, + 7283489, 18406359, 47582163, 7734628 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1608170971973096, 415809060360428, 1350468408164766, + 2038620059057678, 1026904485989112 +#else + 59098600, 23963614, 55988460, 6196037, 29344158, 20123547, + 7585294, 30377806, 18549496, 15302069 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1837656083115103, 1510134048812070, 906263674192061, + 1821064197805734, 565375124676301 +#else + 34450527, 27383209, 59436070, 22502750, 6258877, 13504381, + 10458790, 27135971, 58236621, 8424745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 578027192365650, 2034800251375322, 2128954087207123, + 478816193810521, 2196171989962750 +#else + 24687186, 8613276, 36441818, 30320886, 1863891, 31723888, + 19206233, 7134917, 55824382, 32725512 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1633188840273139, 852787172373708, 1548762607215796, + 1266275218902681, 1107218203325133 +#else + 11334899, 24336410, 8025292, 12707519, 17523892, 23078361, + 10243737, 18868971, 62042829, 16498836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 462189358480054, 1784816734159228, 1611334301651368, + 1303938263943540, 707589560319424 +#else + 8911542, 6887158, 57524604, 26595841, 11145640, 24010752, + 17303924, 19430194, 6536640, 10543906 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1038829280972848, 38176604650029, 753193246598573, + 1136076426528122, 595709990562434 +#else + 38162480, 15479762, 49642029, 568875, 65611181, 11223453, + 64439674, 16928857, 39873154, 8876770 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1408451820859834, 2194984964010833, 2198361797561729, + 1061962440055713, 1645147963442934 +#else + 41365946, 20987567, 51458897, 32707824, 34082177, 32758143, + 33627041, 15824473, 66504438, 24514614 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 4701053362120, 1647641066302348, 1047553002242085, + 1923635013395977, 206970314902065 +#else + 10330056, 70051, 7957388, 24551765, 9764901, 15609756, 27698697, + 28664395, 1657393, 3084098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1750479161778571, 1362553355169293, 1891721260220598, + 966109370862782, 1024913988299801 +#else + 10477963, 26084172, 12119565, 20303627, 29016246, 28188843, + 31280318, 14396151, 36875289, 15272408 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 212699049131723, 1117950018299775, 1873945661751056, + 1403802921984058, 130896082652698 +#else + 54820555, 3169462, 28813183, 16658753, 25116432, 27923966, + 41934906, 20918293, 42094106, 1950503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 636808533673210, 1262201711667560, 390951380330599, + 1663420692697294, 561951321757406 +#else + 40928506, 9489186, 11053416, 18808271, 36055143, 5825629, + 58724558, 24786899, 15341278, 8373727 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 520731594438141, 1446301499955692, 273753264629267, + 1565101517999256, 1019411827004672 +#else + 28685821, 7759505, 52730348, 21551571, 35137043, 4079241, + 298136, 23321830, 64230656, 15190419 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 926527492029409, 1191853477411379, 734233225181171, + 184038887541270, 1790426146325343 +#else + 34175969, 13806335, 52771379, 17760000, 43104243, 10940927, + 8669718, 2742393, 41075551, 26679428 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1464651961852572, 1483737295721717, 1519450561335517, + 1161429831763785, 405914998179977 +#else + 65528476, 21825014, 41129205, 22109408, 49696989, 22641577, + 9291593, 17306653, 54954121, 6048604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996126634382301, 796204125879525, 127517800546509, + 344155944689303, 615279846169038 +#else + 36803549, 14843443, 1539301, 11864366, 20201677, 1900163, + 13934231, 5128323, 11213262, 9168384 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 738724080975276, 2188666632415296, 1961313708559162, + 1506545807547587, 1151301638969740 +#else + 40828332, 11007846, 19408960, 32613674, 48515898, 29225851, + 62020803, 22449281, 20470156, 17155731 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622917337413835, 1218989177089035, 1284857712846592, + 970502061709359, 351025208117090 +#else + 43972811, 9282191, 14855179, 18164354, 59746048, 19145871, + 44324911, 14461607, 14042978, 5230683 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2067814584765580, 1677855129927492, 2086109782475197, + 235286517313238, 1416314046739645 +#else + 29969548, 30812838, 50396996, 25001989, 9175485, 31085458, + 21556950, 3506042, 61174973, 21104723 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 586844262630358, 307444381952195, 458399356043426, + 602068024507062, 1028548203415243 +#else + 63964118, 8744660, 19704003, 4581278, 46678178, 6830682, + 45824694, 8971512, 38569675, 15326562 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678489922928203, 2016657584724032, 90977383049628, + 1026831907234582, 615271492942522 +#else + 47644235, 10110287, 49846336, 30050539, 43608476, 1355668, + 51585814, 15300987, 46594746, 9168259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301225714012278, 1094837270268560, 1202288391010439, + 644352775178361, 1647055902137983 +#else + 61755510, 4488612, 43305616, 16314346, 7780487, 17915493, + 38160505, 9601604, 33087103, 24543045 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1210746697896478, 1416608304244708, 686487477217856, + 1245131191434135, 1051238336855737 +#else + 47665694, 18041531, 46311396, 21109108, 37284416, 10229460, + 39664535, 18553900, 61111993, 15664671 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1135604073198207, 1683322080485474, 769147804376683, + 2086688130589414, 900445683120379 +#else + 23294591, 16921819, 44458082, 25083453, 27844203, 11461195, + 13099750, 31094076, 18151675, 13417686 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971518477615628, 401909519527336, 448627091057375, + 1409486868273821, 1214789035034363 +#else + 42385932, 29377914, 35958184, 5988918, 40250079, 6685064, + 1661597, 21002991, 15271675, 18101767 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364039144731711, 1897497433586190, 2203097701135459, + 145461396811251, 1349844460790699 +#else + 11433023, 20325767, 8239630, 28274915, 65123427, 32828713, + 48410099, 2167543, 60187563, 20114249 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1045230323257973, 818206601145807, 630513189076103, + 1672046528998132, 807204017562437 +#else + 35672693, 15575145, 30436815, 12192228, 44645511, 9395378, + 57191156, 24915434, 12215109, 12028277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 439961968385997, 386362664488986, 1382706320807688, + 309894000125359, 2207801346498567 +#else + 14098381, 6555944, 23007258, 5757252, 51681032, 20603929, + 30123439, 4617780, 50208775, 32898803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1229004686397588, 920643968530863, 123975893911178, + 681423993215777, 1400559197080973 +#else + 63082644, 18313596, 11893167, 13718664, 52299402, 1847384, + 51288865, 10154008, 23973261, 20869958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2003766096898049, 170074059235165, 1141124258967971, + 1485419893480973, 1573762821028725 +#else + 40577025, 29858441, 65199965, 2534300, 35238307, 17004076, + 18341389, 22134481, 32013173, 23450893 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 729905708611432, 1270323270673202, 123353058984288, + 426460209632942, 2195574535456672 +#else + 41629544, 10876442, 55337778, 18929291, 54739296, 1838103, + 21911214, 6354752, 4425632, 32716610 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1271140255321235, 2044363183174497, 52125387634689, + 1445120246694705, 942541986339084 +#else + 56675475, 18941465, 22229857, 30463385, 53917697, 776728, + 49693489, 21533969, 4725004, 14044970 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1761608437466135, 583360847526804, 1586706389685493, + 2157056599579261, 1170692369685772 +#else + 19268631, 26250011, 1555348, 8692754, 45634805, 23643767, + 6347389, 32142648, 47586572, 17444675 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 871476219910823, 1878769545097794, 2241832391238412, + 548957640601001, 690047440233174 +#else + 42244775, 12986007, 56209986, 27995847, 55796492, 33405905, + 19541417, 8180106, 9282262, 10282508 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 297194732135507, 1366347803776820, 1301185512245601, + 561849853336294, 1533554921345731 +#else + 40903763, 4428546, 58447668, 20360168, 4098401, 19389175, + 15522534, 8372215, 5542595, 22851749 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 999628998628371, 1132836708493400, 2084741674517453, + 469343353015612, 678782988708035 +#else + 56546323, 14895632, 26814552, 16880582, 49628109, 31065071, + 64326972, 6993760, 49014979, 10114654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2189427607417022, 699801937082607, 412764402319267, + 1478091893643349, 2244675696854460 +#else + 47001790, 32625013, 31422703, 10427861, 59998115, 6150668, + 38017109, 22025285, 25953724, 33448274 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1712292055966563, 204413590624874, 1405738637332841, + 408981300829763, 861082219276721 +#else + 62874467, 25515139, 57989738, 3045999, 2101609, 20947138, + 19390019, 6094296, 63793585, 12831124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 508561155940631, 966928475686665, 2236717801150132, + 424543858577297, 2089272956986143 +#else + 51110167, 7578151, 5310217, 14408357, 33560244, 33329692, + 31575953, 6326196, 7381791, 31132593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 221245220129925, 1156020201681217, 491145634799213, + 542422431960839, 828100817819207 +#else + 46206085, 3296810, 24736065, 17226043, 18374253, 7318640, + 6295303, 8082724, 51746375, 12339663 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 153756971240384, 1299874139923977, 393099165260502, + 1058234455773022, 996989038681183 +#else + 27724736, 2291157, 6088201, 19369634, 1792726, 5857634, + 13848414, 15768922, 25091167, 14856294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559086812798481, 573177704212711, 1629737083816402, + 1399819713462595, 1646954378266038 +#else + 48242193, 8331042, 24373479, 8541013, 66406866, 24284974, + 12927299, 20858939, 44926390, 24541532 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1887963056288059, 228507035730124, 1468368348640282, + 930557653420194, 613513962454686 +#else + 55685435, 28132841, 11632844, 3405020, 30536730, 21880393, + 39848098, 13866389, 30146206, 9142070 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1224529808187553, 1577022856702685, 2206946542980843, + 625883007765001, 279930793512158 +#else + 3924129, 18246916, 53291741, 23499471, 12291819, 32886066, + 39406089, 9326383, 58871006, 4171293 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1076287717051609, 1114455570543035, 187297059715481, + 250446884292121, 1885187512550540 +#else + 51186905, 16037936, 6713787, 16606682, 45496729, 2790943, + 26396185, 3731949, 345228, 28091483 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 902497362940219, 76749815795675, 1657927525633846, + 1420238379745202, 1340321636548352 +#else + 45781307, 13448258, 25284571, 1143661, 20614966, 24705045, + 2031538, 21163201, 50855680, 19972348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129576631190784, 1281994010027327, 996844254743018, + 257876363489249, 1150850742055018 +#else + 31016192, 16832003, 26371391, 19103199, 62081514, 14854136, + 17477601, 3842657, 28012650, 17149012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 628740660038789, 1943038498527841, 467786347793886, + 1093341428303375, 235413859513003 +#else + 62033029, 9368965, 58546785, 28953529, 51858910, 6970559, + 57918991, 16292056, 58241707, 3507939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237425418909360, 469614029179605, 1512389769174935, + 1241726368345357, 441602891065214 +#else + 29439664, 3537914, 23333589, 6997794, 49553303, 22536363, + 51899661, 18503164, 57943934, 6580395 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1736417953058555, 726531315520508, 1833335034432527, + 1629442561574747, 624418919286085 +#else + 54923003, 25874643, 16438268, 10826160, 58412047, 27318820, + 17860443, 24280586, 65013061, 9304566 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1960754663920689, 497040957888962, 1909832851283095, + 1271432136996826, 2219780368020940 +#else + 20714545, 29217521, 29088194, 7406487, 11426967, 28458727, + 14792666, 18945815, 5289420, 33077305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1537037379417136, 1358865369268262, 2130838645654099, + 828733687040705, 1999987652890901 +#else + 50443312, 22903641, 60948518, 20248671, 9192019, 31751970, + 17271489, 12349094, 26939669, 29802138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 629042105241814, 1098854999137608, 887281544569320, + 1423102019874777, 7911258951561 +#else + 54218966, 9373457, 31595848, 16374215, 21471720, 13221525, + 39825369, 21205872, 63410057, 117886 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811562332665373, 1501882019007673, 2213763501088999, + 359573079719636, 36370565049116 +#else + 22263325, 26994382, 3984569, 22379786, 51994855, 32987646, + 28311252, 5358056, 43789084, 541963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218907117361280, 1209298913016966, 1944312619096112, + 1130690631451061, 1342327389191701 +#else + 16259200, 3261970, 2309254, 18019958, 50223152, 28972515, + 24134069, 16848603, 53771797, 20002236 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1369976867854704, 1396479602419169, 1765656654398856, + 2203659200586299, 998327836117241 +#else + 9378160, 20414246, 44262881, 20809167, 28198280, 26310334, + 64709179, 32837080, 690425, 14876244 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230701885562825, 1348173180338974, 2172856128624598, + 1426538746123771, 444193481326151 +#else + 24977353, 33240048, 58884894, 20089345, 28432342, 32378079, + 54040059, 21257083, 44727879, 6618998 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 784210426627951, 918204562375674, 1284546780452985, + 1324534636134684, 1872449409642708 +#else + 65570671, 11685645, 12944378, 13682314, 42719353, 19141238, + 8044828, 19737104, 32239828, 27901670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319638829540294, 596282656808406, 2037902696412608, + 1557219121643918, 341938082688094 +#else + 48505798, 4762989, 66182614, 8885303, 38696384, 30367116, + 9781646, 23204373, 32779358, 5095274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1901860206695915, 2004489122065736, 1625847061568236, + 973529743399879, 2075287685312905 +#else + 34100715, 28339925, 34843976, 29869215, 9460460, 24227009, + 42507207, 14506723, 21639561, 30924196 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1371853944110545, 1042332820512553, 1949855697918254, + 1791195775521505, 37487364849293 +#else + 50707921, 20442216, 25239337, 15531969, 3987758, 29055114, + 65819361, 26690896, 17874573, 558605 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 687200189577855, 1082536651125675, 644224940871546, + 340923196057951, 343581346747396 +#else + 53508735, 10240080, 9171883, 16131053, 46239610, 9599699, + 33499487, 5080151, 2085892, 5119761 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2082717129583892, 27829425539422, 145655066671970, + 1690527209845512, 1865260509673478 +#else + 44903700, 31034903, 50727262, 414690, 42089314, 2170429, + 30634760, 25190818, 35108870, 27794547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1059729620568824, 2163709103470266, 1440302280256872, + 1769143160546397, 869830310425069 +#else + 60263160, 15791201, 8550074, 32241778, 29928808, 21462176, + 27534429, 26362287, 44757485, 12961481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609516219779025, 777277757338817, 2101121130363987, + 550762194946473, 1905542338659364 +#else + 42616785, 23983660, 10368193, 11582341, 43711571, 31309144, + 16533929, 8206996, 36914212, 28394793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024821921041576, 426948675450149, 595133284085473, + 471860860885970, 600321679413000 +#else + 55987368, 30172197, 2307365, 6362031, 66973409, 8868176, + 50273234, 7031274, 7589640, 8945490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 598474602406721, 1468128276358244, 1191923149557635, + 1501376424093216, 1281662691293476 +#else + 34956097, 8917966, 6661220, 21876816, 65916803, 17761038, + 7251488, 22372252, 24099108, 19098262 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1721138489890707, 1264336102277790, 433064545421287, + 1359988423149466, 1561871293409447 +#else + 5019539, 25646962, 4244126, 18840076, 40175591, 6453164, + 47990682, 20265406, 60876967, 23273695 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 719520245587143, 393380711632345, 132350400863381, + 1543271270810729, 1819543295798660 +#else + 10853575, 10721687, 26480089, 5861829, 44113045, 1972174, + 65242217, 22996533, 63745412, 27113307 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 396397949784152, 1811354474471839, 1362679985304303, + 2117033964846756, 498041172552279 +#else + 50106456, 5906789, 221599, 26991285, 7828207, 20305514, + 24362660, 31546264, 53242455, 7421391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812471844975748, 1856491995543149, 126579494584102, + 1036244859282620, 1975108050082550 +#else + 8139908, 27007935, 32257645, 27663886, 30375718, 1886181, + 45933756, 15441251, 28826358, 29431403 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 650623932407995, 1137551288410575, 2125223403615539, + 1725658013221271, 2134892965117796 +#else + 6267067, 9695052, 7709135, 16950835, 34239795, 31668296, + 14795159, 25714308, 13746020, 31812384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522584000310195, 1241762481390450, 1743702789495384, + 2227404127826575, 1686746002148897 +#else + 28584883, 7787108, 60375922, 18503702, 22846040, 25983196, + 63926927, 33190907, 4771361, 25134474 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 427904865186312, 1703211129693455, 1585368107547509, + 1436984488744336, 761188534613978 +#else + 24949256, 6376279, 39642383, 25379823, 48462709, 23623825, + 33543568, 21412737, 3569626, 11342593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 318101947455002, 248138407995851, 1481904195303927, + 309278454311197, 1258516760217879 +#else + 26514970, 4740088, 27912651, 3697550, 19331575, 22082093, + 6809885, 4608608, 7325975, 18753361 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1275068538599310, 513726919533379, 349926553492294, + 688428871968420, 1702400196000666 +#else + 55490446, 19000001, 42787651, 7655127, 65739590, 5214311, + 39708324, 10258389, 49462170, 25367739 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1061864036265233, 961611260325381, 321859632700838, + 1045600629959517, 1985130202504038 +#else + 11431185, 15823007, 26570245, 14329124, 18029990, 4796082, + 35662685, 15580663, 9280358, 29580745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1558816436882417, 1962896332636523, 1337709822062152, + 1501413830776938, 294436165831932 +#else + 66948081, 23228174, 44253547, 29249434, 46247496, 19933429, + 34297962, 22372809, 51563772, 4387440 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 818359826554971, 1862173000996177, 626821592884859, + 573655738872376, 1749691246745455 +#else + 46309467, 12194511, 3937617, 27748540, 39954043, 9340369, + 42594872, 8548136, 20617071, 26072431 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1988022651432119, 1082111498586040, 1834020786104821, + 1454826876423687, 692929915223122 +#else + 66170039, 29623845, 58394552, 16124717, 24603125, 27329039, + 53333511, 21678609, 24345682, 10325460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146513703733331, 584788900394667, 464965657279958, + 2183973639356127, 238371159456790 +#else + 47253587, 31985546, 44906155, 8714033, 14007766, 6928528, + 16318175, 32543743, 4766742, 3552007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129007025494441, 2197883144413266, 265142755578169, + 971864464758890, 1983715884903702 +#else + 45357481, 16823515, 1351762, 32751011, 63099193, 3950934, + 3217514, 14481909, 10988822, 29559670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291366624493075, 381456718189114, 1711482489312444, + 1815233647702022, 892279782992467 +#else + 15564307, 19242862, 3101242, 5684148, 30446780, 25503076, + 12677126, 27049089, 58813011, 13296004 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 444548969917454, 1452286453853356, 2113731441506810, + 645188273895859, 810317625309512 +#else + 57666574, 6624295, 36809900, 21640754, 62437882, 31497052, + 31521203, 9614054, 37108040, 12074673 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2242724082797924, 1373354730327868, 1006520110883049, + 2147330369940688, 1151816104883620 +#else + 4771172, 33419193, 14290748, 20464580, 27992297, 14998318, + 65694928, 31997715, 29832612, 17163397 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1745720200383796, 1911723143175317, 2056329390702074, + 355227174309849, 879232794371100 +#else + 7064884, 26013258, 47946901, 28486894, 48217594, 30641695, + 25825241, 5293297, 39986204, 13101589 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 163723479936298, 115424889803150, 1156016391581227, + 1894942220753364, 1970549419986329 +#else + 64810282, 2439669, 59642254, 1719964, 39841323, 17225986, + 32512468, 28236839, 36752793, 29363474 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 681981452362484, 267208874112496, 1374683991933094, + 638600984916117, 646178654558546 +#else + 37102324, 10162315, 33928688, 3981722, 50626726, 20484387, + 14413973, 9515896, 19568978, 9628812 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 13378654854251, 106237307029567, 1944412051589651, + 1841976767925457, 230702819835573 +#else + 33053803, 199357, 15894591, 1583059, 27380243, 28973997, + 49269969, 27447592, 60817077, 3437739 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 260683893467075, 854060306077237, 913639551980112, + 4704576840123, 280254810808712 +#else + 48129987, 3884492, 19469877, 12726490, 15913552, 13614290, + 44147131, 70103, 7463304, 4176122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 715374893080287, 1173334812210491, 1806524662079626, + 1894596008000979, 398905715033393 +#else + 39984863, 10659916, 11482427, 17484051, 12771466, 26919315, + 34389459, 28231680, 24216881, 5944158 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 500026409727661, 1596431288195371, 1420380351989370, + 985211561521489, 392444930785633 +#else + 8894125, 7450974, 64444715, 23788679, 39028346, 21165316, + 19345745, 14680796, 11632993, 5847885 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2096421546958141, 1922523000950363, 789831022876840, + 427295144688779, 320923973161730 +#else + 26942781, 31239115, 9129563, 28647825, 26024104, 11769399, + 55590027, 6367193, 57381634, 4782139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1927770723575450, 1485792977512719, 1850996108474547, + 551696031508956, 2126047405475647 +#else + 19916442, 28726022, 44198159, 22140040, 25606323, 27581991, + 33253852, 8220911, 6358847, 31680575 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2112099158080148, 742570803909715, 6484558077432, + 1951119898618916, 93090382703416 +#else + 801428, 31472730, 16569427, 11065167, 29875704, 96627, 7908388, + 29073952, 53570360, 1387154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 383905201636970, 859946997631870, 855623867637644, + 1017125780577795, 794250831877809 +#else + 19646058, 5720633, 55692158, 12814208, 11607948, 12749789, + 14147075, 15156355, 45242033, 11835259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 77571826285752, 999304298101753, 487841111777762, + 1038031143212339, 339066367948762 +#else + 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, + 26121523, 15467869, 40548314, 5052482 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 674994775520533, 266035846330789, 826951213393478, + 1405007746162285, 1781791018620876 +#else + 64091413, 10058205, 1980837, 3964243, 22160966, 12322533, + 60677741, 20936246, 12228556, 26550755 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1001412661522686, 348196197067298, 1666614366723946, + 888424995032760, 580747687801357 +#else + 32944382, 14922211, 44263970, 5188527, 21913450, 24834489, + 4001464, 13238564, 60994061, 8653814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1939560076207777, 1409892634407635, 552574736069277, + 383854338280405, 190706709864139 +#else + 22865569, 28901697, 27603667, 21009037, 14348957, 8234005, + 24808405, 5719875, 28483275, 2841751 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2177087163428741, 1439255351721944, 1208070840382793, + 2230616362004769, 1396886392021913 +#else + 50687877, 32441126, 66781144, 21446575, 21886281, 18001658, + 65220897, 33238773, 19932057, 20815229 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 676962063230039, 1880275537148808, 2046721011602706, + 888463247083003, 1318301552024067 +#else + 55452759, 10087520, 58243976, 28018288, 47830290, 30498519, + 3999227, 13239134, 62331395, 19644223 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1466980508178206, 617045217998949, 652303580573628, + 757303753529064, 207583137376902 +#else + 1382174, 21859713, 17266789, 9194690, 53784508, 9720080, + 20403944, 11284705, 53095046, 3093229 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1511056752906902, 105403126891277, 493434892772846, + 1091943425335976, 1802717338077427 +#else + 16650902, 22516500, 66044685, 1570628, 58779118, 7352752, + 66806440, 16271224, 43059443, 26862581 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853982405405128, 1878664056251147, 1528011020803992, + 1019626468153565, 1128438412189035 +#else + 45197768, 27626490, 62497547, 27994275, 35364760, 22769138, + 24123613, 15193618, 45456747, 16815042 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1963939888391106, 293456433791664, 697897559513649, + 985882796904380, 796244541237972 +#else + 57172930, 29264984, 41829040, 4372841, 2087473, 10399484, + 31870908, 14690798, 17361620, 11864968 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 416770998629779, 389655552427054, 1314476859406756, + 1749382513022778, 1161905598739491 +#else + 55801235, 6210371, 13206574, 5806320, 38091172, 19587231, + 54777658, 26067830, 41530403, 17313742 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1428358296490651, 1027115282420478, 304840698058337, + 441410174026628, 1819358356278573 +#else + 14668443, 21284197, 26039038, 15305210, 25515617, 4542480, + 10453892, 6577524, 9145645, 27110552 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204943430200135, 1554861433819175, 216426658514651, + 264149070665950, 2047097371738319 +#else + 5974855, 3053895, 57675815, 23169240, 35243739, 3225008, + 59136222, 3936127, 61456591, 30504127 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1934415182909034, 1393285083565062, 516409331772960, + 1157690734993892, 121039666594268 +#else + 30625386, 28825032, 41552902, 20761565, 46624288, 7695098, + 17097188, 17250936, 39109084, 1803631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 662035583584445, 286736105093098, 1131773000510616, + 818494214211439, 472943792054479 +#else + 63555773, 9865098, 61880298, 4272700, 61435032, 16864731, + 14911343, 12196514, 45703375, 7047411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665784778135882, 1893179629898606, 808313193813106, + 276797254706413, 1563426179676396 +#else + 20093258, 9920966, 55970670, 28210574, 13161586, 12044805, + 34252013, 4124600, 34765036, 23296865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 945205108984232, 526277562959295, 1324180513733566, + 1666970227868664, 153547609289173 +#else + 46320040, 14084653, 53577151, 7842146, 19119038, 19731827, + 4752376, 24839792, 45429205, 2288037 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2031433403516252, 203996615228162, 170487168837083, + 981513604791390, 843573964916831 +#else + 40289628, 30270716, 29965058, 3039786, 52635099, 2540456, + 29457502, 14625692, 42289247, 12570231 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1476570093962618, 838514669399805, 1857930577281364, + 2017007352225784, 317085545220047 +#else + 66045306, 22002608, 16920317, 12494842, 1278292, 27685323, + 45948920, 30055751, 55134159, 4724942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461557121912842, 1600674043318359, 2157134900399597, + 1670641601940616, 127765583803283 +#else + 17960970, 21778898, 62967895, 23851901, 58232301, 32143814, + 54201480, 24894499, 37532563, 1903855 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1293543509393474, 2143624609202546, 1058361566797508, + 214097127393994, 946888515472729 +#else + 23134274, 19275300, 56426866, 31942495, 20684484, 15770816, + 54119114, 3190295, 26955097, 14109738 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 357067959932916, 1290876214345711, 521245575443703, + 1494975468601005, 800942377643885 +#else + 15308788, 5320727, 36995055, 19235554, 22902007, 7767164, + 29425325, 22276870, 31960941, 11934971 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 566116659100033, 820247422481740, 994464017954148, + 327157611686365, 92591318111744 +#else + 39713153, 8435795, 4109644, 12222639, 42480996, 14818668, + 20638173, 4875028, 10491392, 1379718 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 617256647603209, 1652107761099439, 1857213046645471, + 1085597175214970, 817432759830522 +#else + 53949449, 9197840, 3875503, 24618324, 65725151, 27674630, + 33518458, 16176658, 21432314, 12180697 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 771808161440705, 1323510426395069, 680497615846440, + 851580615547985, 1320806384849017 +#else + 55321537, 11500837, 13787581, 19721842, 44678184, 10140204, + 1465425, 12689540, 56807545, 19681548 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1219260086131915, 647169006596815, 79601124759706, + 2161724213426748, 404861897060198 +#else + 5414091, 18168391, 46101199, 9643569, 12834970, 1186149, + 64485948, 32212200, 26128230, 6032912 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1327968293887866, 1335500852943256, 1401587164534264, + 558137311952440, 1551360549268902 +#else + 40771450, 19788269, 32496024, 19900513, 17847800, 20885276, + 3604024, 8316894, 41233830, 23117073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 417621685193956, 1429953819744454, 396157358457099, + 1940470778873255, 214000046234152 +#else + 3296484, 6223048, 24680646, 21307972, 44056843, 5903204, + 58246567, 28915267, 12376616, 3188849 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268047918491973, 2172375426948536, 1533916099229249, + 1761293575457130, 1590622667026765 +#else + 29190469, 18895386, 27549112, 32370916, 3520065, 22857131, + 32049514, 26245319, 50999629, 23702124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1627072914981959, 2211603081280073, 1912369601616504, + 1191770436221309, 2187309757525860 +#else + 52364359, 24245275, 735817, 32955454, 46701176, 28496527, + 25246077, 17758763, 18640740, 32593455 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1149147819689533, 378692712667677, 828475842424202, + 2218619146419342, 70688125792186 +#else + 60180029, 17123636, 10361373, 5642961, 4910474, 12345252, + 35470478, 33060001, 10530746, 1053335 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299739417079761, 1438616663452759, 1536729078504412, + 2053896748919838, 1008421032591246 +#else + 37842897, 19367626, 53570647, 21437058, 47651804, 22899047, + 35646494, 30605446, 24018830, 15026644 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040723824657366, 399555637875075, 632543375452995, + 872649937008051, 1235394727030233 +#else + 44516310, 30409154, 64819587, 5953842, 53668675, 9425630, + 25310643, 13003497, 64794073, 18408815 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2211311599327900, 2139787259888175, 938706616835350, + 12609661139114, 2081897930719789 +#else + 39688860, 32951110, 59064879, 31885314, 41016598, 13987818, + 39811242, 187898, 43942445, 31022696 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1324994503390450, 336982330582631, 1183998925654177, + 1091654665913274, 48727673971319 +#else + 45364466, 19743956, 1844839, 5021428, 56674465, 17642958, + 9716666, 16266922, 62038647, 726098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1845522914617879, 1222198248335542, 150841072760134, + 1927029069940982, 1189913404498011 +#else + 29370903, 27500434, 7334070, 18212173, 9385286, 2247707, + 53446902, 28714970, 30007387, 17731091 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079559557592645, 2215338383666441, 1903569501302605, + 49033973033940, 305703433934152 +#else + 66172485, 16086690, 23751945, 33011114, 65941325, 28365395, + 9137108, 730663, 9835848, 4555336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94653405416909, 1386121349852999, 1062130477891762, + 36553947479274, 833669648948846 +#else + 43732429, 1410445, 44855111, 20654817, 30867634, 15826977, + 17693930, 544696, 55123566, 12422645 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1432015813136298, 440364795295369, 1395647062821501, + 1976874522764578, 934452372723352 +#else + 31117226, 21338698, 53606025, 6561946, 57231997, 20796761, + 61990178, 29457725, 29120152, 13924425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1296625309219774, 2068273464883862, 1858621048097805, + 1492281814208508, 2235868981918946 +#else + 49707966, 19321222, 19675798, 30819676, 56101901, 27695611, + 57724924, 22236731, 7240930, 33317044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1490330266465570, 1858795661361448, 1436241134969763, + 294573218899647, 1208140011028933 +#else + 35747106, 22207651, 52101416, 27698213, 44655523, 21401660, + 1222335, 4389483, 3293637, 18002689 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1282462923712748, 741885683986255, 2027754642827561, + 518989529541027, 1826610009555945 +#else + 50424044, 19110186, 11038543, 11054958, 53307689, 30215898, + 42789283, 7733546, 12796905, 27218610 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525827120027511, 723686461809551, 1597702369236987, + 244802101764964, 1502833890372311 +#else + 58349431, 22736595, 41689999, 10783768, 36493307, 23807620, + 38855524, 3647835, 3222231, 22393970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 113622036244513, 1233740067745854, 674109952278496, + 2114345180342965, 166764512856263 +#else + 18606113, 1693100, 41660478, 18384159, 4112352, 10045021, + 23603893, 31506198, 59558087, 2484984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2041668749310338, 2184405322203901, 1633400637611036, + 2110682505536899, 2048144390084644 +#else + 9255298, 30423235, 54952701, 32550175, 13098012, 24339566, + 16377219, 31451620, 47306788, 30519729 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 503058759232932, 760293024620937, 2027152777219493, + 666858468148475, 1539184379870952 +#else + 44379556, 7496159, 61366665, 11329248, 19991973, 30206930, + 35390715, 9936965, 37011176, 22935634 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1916168475367211, 915626432541343, 883217071712575, + 363427871374304, 1976029821251593 +#else + 21878571, 28553135, 4338335, 13643897, 64071999, 13160959, + 19708896, 5415497, 59748361, 29445138 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678039535434506, 570587290189340, 1605302676614120, + 2147762562875701, 1706063797091704 +#else + 27736842, 10103576, 12500508, 8502413, 63695848, 23920873, + 10436917, 32004156, 43449720, 25422331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1439489648586438, 2194580753290951, 832380563557396, + 561521973970522, 584497280718389 +#else + 19492550, 21450067, 37426887, 32701801, 63900692, 12403436, + 30066266, 8367329, 13243957, 8709688 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 187989455492609, 681223515948275, 1933493571072456, + 1872921007304880, 488162364135671 +#else + 12015105, 2801261, 28198131, 10151021, 24818120, 28811299, + 55914672, 27908697, 5150967, 7274186 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1413466089534451, 410844090765630, 1397263346404072, + 408227143123410, 1594561803147811 +#else + 2831347, 21062286, 1478974, 6122054, 23825128, 20820846, + 31097298, 6083058, 31021603, 23760822 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102170800973153, 719462588665004, 1479649438510153, + 1097529543970028, 1302363283777685 +#else + 64578913, 31324785, 445612, 10720828, 53259337, 22048494, + 43601132, 16354464, 15067285, 19406725 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 942065717847195, 1069313679352961, 2007341951411051, + 70973416446291, 1419433790163706 +#else + 7840923, 14037873, 33744001, 15934015, 66380651, 29911725, + 21403987, 1057586, 47729402, 21151211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1146565545556377, 1661971299445212, 406681704748893, + 564452436406089, 1109109865829139 +#else + 915865, 17085158, 15608284, 24765302, 42751837, 6060029, + 49737545, 8410996, 59888403, 16527024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2214421081775077, 1165671861210569, 1890453018796184, + 3556249878661, 442116172656317 +#else + 32922597, 32997445, 20336073, 17369864, 10903704, 28169945, + 16957573, 52992, 23834301, 6588044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 753830546620811, 1666955059895019, 1530775289309243, + 1119987029104146, 2164156153857580 +#else + 32752011, 11232950, 3381995, 24839566, 22652987, 22810329, + 17159698, 16689107, 46794284, 32248439 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615171919212796, 1523849404854568, 854560460547503, + 2067097370290715, 1765325848586042 +#else + 62419196, 9166775, 41398568, 22707125, 11576751, 12733943, + 7924251, 30802151, 1976122, 26305405 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1094538949313667, 1796592198908825, 870221004284388, + 2025558921863561, 1699010892802384 +#else + 21251203, 16309901, 64125849, 26771309, 30810596, 12967303, + 156041, 30183180, 12331344, 25317235 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1951351290725195, 1916457206844795, 198025184438026, + 1909076887557595, 1938542290318919 +#else + 8651595, 29077400, 51023227, 28557437, 13002506, 2950805, + 29054427, 28447462, 10008135, 28886531 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1014323197538413, 869150639940606, 1756009942696599, + 1334952557375672, 1544945379082874 +#else + 31486061, 15114593, 52847614, 12951353, 14369431, 26166587, + 16347320, 19892343, 8684154, 23021480 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 764055910920305, 1603590757375439, 146805246592357, + 1843313433854297, 954279890114939 +#else + 19443825, 11385320, 24468943, 23895364, 43189605, 2187568, + 40845657, 27467510, 31316347, 14219878 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 80113526615750, 764536758732259, 1055139345100233, + 469252651759390, 617897512431515 +#else + 38514374, 1193784, 32245219, 11392485, 31092169, 15722801, + 27146014, 6992409, 29126555, 9207390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 74497112547268, 740094153192149, 1745254631717581, + 727713886503130, 1283034364416928 +#else + 32382916, 1110093, 18477781, 11028262, 39697101, 26006320, + 62128346, 10843781, 59151264, 19118701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 525892105991110, 1723776830270342, 1476444848991936, + 573789489857760, 133864092632978 +#else + 2814918, 7836403, 27519878, 25686276, 46214848, 22000742, + 45614304, 8550129, 28346258, 1994730 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 542611720192581, 1986812262899321, 1162535242465837, + 481498966143464, 544600533583622 +#else + 47530565, 8085544, 53108345, 29605809, 2785837, 17323125, + 47591912, 7174893, 22628102, 8115180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 64123227344372, 1239927720647794, 1360722983445904, + 222610813654661, 62429487187991 +#else + 36703732, 955510, 55975026, 18476362, 34661776, 20276352, + 41457285, 3317159, 57165847, 930271 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1793193323953132, 91096687857833, 70945970938921, + 2158587638946380, 1537042406482111 +#else + 51805164, 26720662, 28856489, 1357446, 23421993, 1057177, + 24091212, 32165462, 44343487, 22903716 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1895854577604609, 1394895708949416, 1728548428495944, + 1140864900240149, 563645333603061 +#else + 44357633, 28250434, 54201256, 20785565, 51297352, 25757378, + 52269845, 17000211, 65241845, 8398969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141358280486863, 91435889572504, 1087208572552643, + 1829599652522921, 1193307020643647 +#else + 35139535, 2106402, 62372504, 1362500, 12813763, 16200670, + 22981545, 27263159, 18009407, 17781660 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1611230858525381, 950720175540785, 499589887488610, + 2001656988495019, 88977313255908 +#else + 49887941, 24009210, 39324209, 14166834, 29815394, 7444469, + 29551787, 29827013, 19288548, 1325865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1189080501479658, 2184348804772597, 1040818725742319, + 2018318290311834, 1712060030915354 +#else + 15100138, 17718680, 43184885, 32549333, 40658671, 15509407, + 12376730, 30075286, 33166106, 25511682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 873966876953756, 1090638350350440, 1708559325189137, + 672344594801910, 1320437969700239 +#else + 20909212, 13023121, 57899112, 16251777, 61330449, 25459517, + 12412150, 10018715, 2213263, 19676059 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1508590048271766, 1131769479776094, 101550868699323, + 428297785557897, 561791648661744 +#else + 32529814, 22479743, 30361438, 16864679, 57972923, 1513225, + 22922121, 6382134, 61341936, 8371347 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756417570499462, 237882279232602, 2136263418594016, + 1701968045454886, 703713185137472 +#else + 9923462, 11271500, 12616794, 3544722, 37110496, 31832805, + 12891686, 25361300, 40665920, 10486143 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1781187809325462, 1697624151492346, 1381393690939988, + 175194132284669, 1483054666415238 +#else + 44511638, 26541766, 8587002, 25296571, 4084308, 20584370, + 361725, 2610596, 43187334, 22099236 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2175517777364616, 708781536456029, 955668231122942, + 1967557500069555, 2021208005604118 +#else + 5408392, 32417741, 62139741, 10561667, 24145918, 14240566, + 31319731, 29318891, 19985174, 30118346 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115135966606887, 224217372950782, 915967306279222, + 593866251291540, 561747094208006 +#else + 53114407, 16616820, 14549246, 3341099, 32155958, 13648976, + 49531796, 8849296, 65030, 8370684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1443163092879439, 391875531646162, 2180847134654632, + 464538543018753, 1594098196837178 +#else + 58787919, 21504805, 31204562, 5839400, 46481576, 32497154, + 47665921, 6922163, 12743482, 23753914 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 850858855888869, 319436476624586, 327807784938441, + 740785849558761, 17128415486016 +#else + 64747493, 12678784, 28815050, 4759974, 43215817, 4884716, + 23783145, 11038569, 18800704, 255233 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132756334090067, 536247820155645, 48907151276867, + 608473197600695, 1261689545022784 +#else + 61839187, 31780545, 13957885, 7990715, 23132995, 728773, + 13393847, 9066957, 19258688, 18800639 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525176236978354, 974205476721062, 293436255662638, + 148269621098039, 137961998433963 +#else + 64172210, 22726896, 56676774, 14516792, 63468078, 4372540, + 35173943, 2209389, 65584811, 2055793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121075518299410, 2071745529082111, 1265567917414828, + 1648196578317805, 496232102750820 +#else + 580882, 16705327, 5468415, 30871414, 36182444, 18858431, + 59905517, 24560042, 37087844, 7394434 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 122321229299801, 1022922077493685, 2001275453369484, + 2017441881607947, 993205880778002 +#else + 23838809, 1822728, 51370421, 15242726, 8318092, 29821328, + 45436683, 30062226, 62287122, 14799920 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 654925550560074, 1168810995576858, 575655959430926, + 905758704861388, 496774564663534 +#else + 13345610, 9759151, 3371034, 17416641, 16353038, 8577942, + 31129804, 13496856, 58052846, 7402517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1954109525779738, 2117022646152485, 338102630417180, + 1194140505732026, 107881734943492 +#else + 2286874, 29118501, 47066405, 31546095, 53412636, 5038121, + 11006906, 17794080, 8205060, 1607563 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714785840001267, 2036500018681589, 1876380234251966, + 2056717182974196, 1645855254384642 +#else + 14414067, 25552300, 3331829, 30346215, 22249150, 27960244, + 18364660, 30647474, 30019586, 24525154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 106431476499341, 62482972120563, 1513446655109411, + 807258751769522, 538491469114 +#else + 39420813, 1585952, 56333811, 931068, 37988643, 22552112, + 52698034, 12029092, 9944378, 8024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2002850762893643, 1243624520538135, 1486040410574605, + 2184752338181213, 378495998083531 +#else + 4368715, 29844802, 29874199, 18531449, 46878477, 22143727, + 50994269, 32555346, 58966475, 5640029 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 922510868424903, 1089502620807680, 402544072617374, + 1131446598479839, 1290278588136533 +#else + 10299591, 13746483, 11661824, 16234854, 7630238, 5998374, + 9809887, 16859868, 15219797, 19226649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1867998812076769, 715425053580701, 39968586461416, + 2173068014586163, 653822651801304 +#else + 27425505, 27835351, 3055005, 10660664, 23458024, 595578, + 51710259, 32381236, 48766680, 9742716 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 162892278589453, 182585796682149, 75093073137630, + 497037941226502, 133871727117371 +#else + 6744077, 2427284, 26042789, 2720740, 66260958, 1118973, + 32324614, 7406442, 12420155, 1994844 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1914596576579670, 1608999621851578, 1987629837704609, + 1519655314857977, 1819193753409464 +#else + 14012502, 28529712, 48724410, 23975962, 40623521, 29617992, + 54075385, 22644628, 24319928, 27108099 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949315551096831, 1069003344994464, 1939165033499916, + 1548227205730856, 1933767655861407 +#else + 16412671, 29047065, 10772640, 15929391, 50040076, 28895810, + 10555944, 23070383, 37006495, 28815383 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730519386931635, 1393284965610134, 1597143735726030, + 416032382447158, 1429665248828629 +#else + 22397363, 25786748, 57815702, 20761563, 17166286, 23799296, + 39775798, 6199365, 21880021, 21303672 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 360275475604565, 547835731063078, 215360904187529, + 596646739879007, 332709650425085 +#else + 62825557, 5368522, 35991846, 8163388, 36785801, 3209127, + 16557151, 8890729, 8840445, 4957760 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47602113726801, 1522314509708010, 437706261372925, + 814035330438027, 335930650933545 +#else + 51661137, 709326, 60189418, 22684253, 37330941, 6522331, + 45388683, 12130071, 52312361, 5005756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291597595523886, 1058020588994081, 402837842324045, + 1363323695882781, 2105763393033193 +#else + 64994094, 19246303, 23019041, 15765735, 41839181, 6002751, + 10183197, 20315106, 50713577, 31378319 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 109521982566564, 1715257748585139, 1112231216891516, + 2046641005101484, 134249157157013 +#else + 48083108, 1632004, 13466291, 25559332, 43468412, 16573536, + 35094956, 30497327, 22208661, 2000468 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2156991030936798, 2227544497153325, 1869050094431622, + 754875860479115, 1754242344267058 +#else + 3065054, 32141671, 41510189, 33192999, 49425798, 27851016, + 58944651, 11248526, 63417650, 26140247 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846089562873800, 98894784984326, 1412430299204844, + 171351226625762, 1100604760929008 +#else + 10379208, 27508878, 8877318, 1473647, 37817580, 21046851, + 16690914, 2553332, 63976176, 16400288 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 84172382130492, 499710970700046, 425749630620778, + 1762872794206857, 612842602127960 +#else + 15716668, 1254266, 48636174, 7446273, 58659946, 6344163, + 45011593, 26268851, 26894936, 9132066 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 868309334532756, 1703010512741873, 1952690008738057, + 4325269926064, 2071083554962116 +#else + 24158868, 12938817, 11085297, 25376834, 39045385, 29097348, + 36532400, 64451, 60291780, 30861549 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 523094549451158, 401938899487815, 1407690589076010, + 2022387426254453, 158660516411257 +#else + 13488534, 7794716, 22236231, 5989356, 25426474, 20976224, + 2350709, 30135921, 62420857, 2364225 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 612867287630009, 448212612103814, 571629077419196, + 1466796750919376, 1728478129663858 +#else + 16335033, 9132434, 25640582, 6678888, 1725628, 8517937, + 55301840, 21856974, 15445874, 25756331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723848973783452, 2208822520534681, 1718748322776940, + 1974268454121942, 1194212502258141 +#else + 29004188, 25687351, 28661401, 32914020, 54314860, 25611345, + 31863254, 29418892, 66830813, 17795152 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254114807944608, 977770684047110, 2010756238954993, + 1783628927194099, 1525962994408256 +#else + 60986784, 18687766, 38493958, 14569918, 56250865, 29962602, + 10343411, 26578142, 37280576, 22738620 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 232464058235826, 1948628555342434, 1835348780427694, + 1031609499437291, 64472106918373 +#else + 27081650, 3463984, 14099042, 29036828, 1616302, 27348828, + 29542635, 15372179, 17293797, 960709 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 767338676040683, 754089548318405, 1523192045639075, + 435746025122062, 512692508440385 +#else + 20263915, 11434237, 61343429, 11236809, 13505955, 22697330, + 50997518, 6493121, 47724353, 7639713 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1255955808701983, 1700487367990941, 1166401238800299, + 1175121994891534, 1190934801395380 +#else + 64278047, 18715199, 25403037, 25339236, 58791851, 17380732, + 18006286, 17510682, 29994676, 17746311 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 349144008168292, 1337012557669162, 1475912332999108, + 1321618454900458, 47611291904320 +#else + 9769828, 5202651, 42951466, 19923039, 39057860, 21992807, + 42495722, 19693649, 35924288, 709463 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877519947135419, 2172838026132651, 272304391224129, + 1655143327559984, 886229406429814 +#else + 12286395, 13076066, 45333675, 32377809, 42105665, 4057651, + 35090736, 24663557, 16102006, 13205847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 375806028254706, 214463229793940, 572906353144089, + 572168269875638, 697556386112979 +#else + 13733362, 5599946, 10557076, 3195751, 61550873, 8536969, + 41568694, 8525971, 10151379, 10394400 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168827102357844, 823864273033637, 2071538752104697, + 788062026895924, 599578340743362 +#else + 4024660, 17416881, 22436261, 12276534, 58009849, 30868332, + 19698228, 11743039, 33806530, 8934413 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1948116082078088, 2054898304487796, 2204939184983900, + 210526805152138, 786593586607626 +#else + 51229064, 29029191, 58528116, 30620370, 14634844, 32856154, + 57659786, 3137093, 55571978, 11721157 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1915320147894736, 156481169009469, 655050471180417, + 592917090415421, 2165897438660879 +#else + 17555920, 28540494, 8268605, 2331751, 44370049, 9761012, + 9319229, 8835153, 57903375, 32274386 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1726336468579724, 1119932070398949, 1929199510967666, + 33918788322959, 1836837863503150 +#else + 66647436, 25724417, 20614117, 16688288, 59594098, 28747312, + 22300303, 505429, 6108462, 27371017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 829996854845988, 217061778005138, 1686565909803640, + 1346948817219846, 1723823550730181 +#else + 62038564, 12367916, 36445330, 3234472, 32617080, 25131790, + 29880582, 20071101, 40210373, 25686972 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 384301494966394, 687038900403062, 2211195391021739, + 254684538421383, 1245698430589680 +#else + 35133562, 5726538, 26934134, 10237677, 63935147, 32949378, + 24199303, 3795095, 7592688, 18562353 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1247567493562688, 1978182094455847, 183871474792955, + 806570235643435, 288461518067916 +#else + 21594432, 18590204, 17466407, 29477210, 32537083, 2739898, + 6407723, 12018833, 38852812, 4298411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1449077384734201, 38285445457996, 2136537659177832, + 2146493000841573, 725161151123125 +#else + 46458361, 21592935, 39872588, 570497, 3767144, 31836892, + 13891941, 31985238, 13717173, 10805743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1201928866368855, 800415690605445, 1703146756828343, + 997278587541744, 1858284414104014 +#else + 52432215, 17910135, 15287173, 11927123, 24177847, 25378864, + 66312432, 14860608, 40169934, 27690595 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 356468809648877, 782373916933152, 1718002439402870, + 1392222252219254, 663171266061951 +#else + 12962541, 5311799, 57048096, 11658279, 18855286, 25600231, + 13286262, 20745728, 62727807, 9882021 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 759628738230460, 1012693474275852, 353780233086498, + 246080061387552, 2030378857679162 +#else + 18512060, 11319350, 46985740, 15090308, 18818594, 5271736, + 44380960, 3666878, 43141434, 30255002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040672435071076, 888593182036908, 1298443657189359, + 1804780278521327, 354070726137060 +#else + 60319844, 30408388, 16192428, 13241070, 15898607, 19348318, + 57023983, 26893321, 64705764, 5276064 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1894938527423184, 1463213041477277, 474410505497651, + 247294963033299, 877975941029128 +#else + 30169808, 28236784, 26306205, 21803573, 27814963, 7069267, + 7152851, 3684982, 1449224, 13082861 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207937160991127, 12966911039119, 820997788283092, + 1010440472205286, 1701372890140810 +#else + 10342807, 3098505, 2119311, 193222, 25702612, 12233820, + 23697382, 15056736, 46092426, 25352431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218882774543183, 533427444716285, 1233243976733245, + 435054256891319, 1509568989549904 +#else + 33958735, 3261607, 22745853, 7948688, 19370557, 18376767, + 40936887, 6482813, 56808784, 22494330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888838535711826, 1052177758340622, 1213553803324135, + 169182009127332, 463374268115872 +#else + 32869458, 28145887, 25609742, 15678670, 56421095, 18083360, + 26112420, 2521008, 44444576, 6904814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 299137589460312, 1594371588983567, 868058494039073, + 257771590636681, 1805012993142921 +#else + 29506904, 4457497, 3377935, 23757988, 36598817, 12935079, + 1561737, 3841096, 38105225, 26896789 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1806842755664364, 2098896946025095, 1356630998422878, + 1458279806348064, 347755825962072 +#else + 10340844, 26924055, 48452231, 31276001, 12621150, 20215377, + 30878496, 21730062, 41524312, 5181965 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1402334161391744, 1560083671046299, 1008585416617747, + 1147797150908892, 1420416683642459 +#else + 25940096, 20896407, 17324187, 23247058, 58437395, 15029093, + 24396252, 17103510, 64786011, 21165857 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665506704253369, 273770475169863, 799236974202630, + 848328990077558, 1811448782807931 +#else + 45343161, 9916822, 65808455, 4079497, 66080518, 11909558, + 1782390, 12641087, 20603771, 26992690 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1468412523962641, 771866649897997, 1931766110147832, + 799561180078482, 524837559150077 +#else + 48226577, 21881051, 24849421, 11501709, 13161720, 28785558, + 1925522, 11914390, 4662781, 7820689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2223212657821850, 630416247363666, 2144451165500328, + 816911130947791, 1024351058410032 +#else + 12241050, 33128450, 8132690, 9393934, 32846760, 31954812, + 29749455, 12172924, 16136752, 15264020 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1266603897524861, 156378408858100, 1275649024228779, + 447738405888420, 253186462063095 +#else + 56758909, 18873868, 58896884, 2330219, 49446315, 19008651, + 10658212, 6671822, 19012087, 3772772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022215964509735, 136144366993649, 1800716593296582, + 1193970603800203, 871675847064218 +#else + 3753511, 30133366, 10617073, 2028709, 14841030, 26832768, + 28718731, 17791548, 20527770, 12988982 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1862751661970328, 851596246739884, 1519315554814041, + 1542798466547449, 1417975335901520 +#else + 52286360, 27757162, 63400876, 12689772, 66209881, 22639565, + 42925817, 22989488, 3299664, 21129479 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1228168094547481, 334133883362894, 587567568420081, + 433612590281181, 603390400373205 +#else + 50331161, 18301130, 57466446, 4978982, 3308785, 8755439, + 6943197, 6461331, 41525717, 8991217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 121893973206505, 1843345804916664, 1703118377384911, + 497810164760654, 101150811654673 +#else + 49882601, 1816361, 65435576, 27467992, 31783887, 25378441, + 34160718, 7417949, 36866577, 1507264 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 458346255946468, 290909935619344, 1452768413850679, + 550922875254215, 1537286854336538 +#else + 29692644, 6829891, 56610064, 4334895, 20945975, 21647936, + 38221255, 8209390, 14606362, 22907359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 584322311184395, 380661238802118, 114839394528060, + 655082270500073, 2111856026034852 +#else + 63627275, 8707080, 32188102, 5672294, 22096700, 1711240, + 34088169, 9761486, 4170404, 31469107 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996965581008991, 2148998626477022, 1012273164934654, + 1073876063914522, 1688031788934939 +#else + 55521375, 14855944, 62981086, 32022574, 40459774, 15084045, + 22186522, 16002000, 52832027, 25153633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 923487018849600, 2085106799623355, 528082801620136, + 1606206360876188, 735907091712524 +#else + 62297408, 13761028, 35404987, 31070512, 63796392, 7869046, + 59995292, 23934339, 13240844, 10965870 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697697887804317, 1335343703828273, 831288615207040, + 949416685250051, 288760277392022 +#else + 59366301, 25297669, 52340529, 19898171, 43876480, 12387165, + 4498947, 14147411, 29514390, 4302863 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1419122478109648, 1325574567803701, 602393874111094, + 2107893372601700, 1314159682671307 +#else + 53695440, 21146572, 20757301, 19752600, 14785142, 8976368, + 62047588, 31410058, 17846987, 19582505 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2201150872731804, 2180241023425241, 97663456423163, + 1633405770247824, 848945042443986 +#else + 64864412, 32799703, 62511833, 32488122, 60861691, 1455298, + 45461136, 24339642, 61886162, 12650266 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1173339555550611, 818605084277583, 47521504364289, + 924108720564965, 735423405754506 +#else + 57202067, 17484121, 21134159, 12198166, 40044289, 708125, + 387813, 13770293, 47974538, 10958662 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830104860549448, 1886653193241086, 1600929509383773, + 1475051275443631, 286679780900937 +#else + 22470984, 12369526, 23446014, 28113323, 45588061, 23855708, + 55336367, 21979976, 42025033, 4271861 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1577111294832995, 1030899169768747, 144900916293530, + 1964672592979567, 568390100955250 +#else + 41939299, 23500789, 47199531, 15361594, 61124506, 2159191, + 75375, 29275903, 34582642, 8469672 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278388655910247, 487143369099838, 927762205508727, + 181017540174210, 1616886700741287 +#else + 15854951, 4148314, 58214974, 7259001, 11666551, 13824734, + 36577666, 2697371, 24154791, 24093489 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191033906638969, 940823957346562, 1606870843663445, + 861684761499847, 658674867251089 +#else + 15446137, 17747788, 29759746, 14019369, 30811221, 23944241, + 35526855, 12840103, 24913809, 9815020 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1875032594195546, 1427106132796197, 724736390962158, + 901860512044740, 635268497268760 +#else + 62399578, 27940162, 35267365, 21265538, 52665326, 10799413, + 58005188, 13438768, 18735128, 9466238 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622869792298357, 1903919278950367, 1922588621661629, + 1520574711600434, 1087100760174640 +#else + 11933045, 9281483, 5081055, 28370608, 64480701, 28648802, + 59381042, 22658328, 44380208, 16199063 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 25465949416618, 1693639527318811, 1526153382657203, + 125943137857169, 145276964043999 +#else + 14576810, 379472, 40322331, 25237195, 37682355, 22741457, + 67006097, 1876698, 30801119, 2164795 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 214739857969358, 920212862967915, 1939901550972269, + 1211862791775221, 85097515720120 +#else + 15995086, 3199873, 13672555, 13712240, 47730029, 28906785, + 54027253, 18058162, 53616056, 1268051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2006245852772938, 734762734836159, 254642929763427, + 1406213292755966, 239303749517686 +#else + 56818250, 29895392, 63822271, 10948817, 23037027, 3794475, + 63638526, 20954210, 50053494, 3565903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1619678837192149, 1919424032779215, 1357391272956794, + 1525634040073113, 1310226789796241 +#else + 29210069, 24135095, 61189071, 28601646, 10834810, 20226706, + 50596761, 22733718, 39946641, 19523900 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1040763709762123, 1704449869235352, 605263070456329, + 1998838089036355, 1312142911487502 +#else + 53946955, 15508587, 16663704, 25398282, 38758921, 9019122, + 37925443, 29785008, 2244110, 19552453 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1996723311435669, 1844342766567060, 985455700466044, + 1165924681400960, 311508689870129 +#else + 61955989, 29753495, 57802388, 27482848, 16243068, 14684434, + 41435776, 17373631, 13491505, 4641841 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 43173156290518, 2202883069785309, 1137787467085917, + 1733636061944606, 1394992037553852 +#else + 10813398, 643330, 47920349, 32825515, 30292061, 16954354, + 27548446, 25833190, 14476988, 20787001 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 670078326344559, 555655025059356, 471959386282438, + 2141455487356409, 849015953823125 +#else + 10292079, 9984945, 6481436, 8279905, 59857350, 7032742, + 27282937, 31910173, 39196053, 12651323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2197214573372804, 794254097241315, 1030190060513737, + 267632515541902, 2040478049202624 +#else + 35923332, 32741048, 22271203, 11835308, 10201545, 15351028, + 17099662, 3988035, 21721536, 30405492 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812516004670529, 1609256702920783, 1706897079364493, + 258549904773295, 996051247540686 +#else + 10202177, 27008593, 35735631, 23979793, 34958221, 25434748, + 54202543, 3852693, 13216206, 14842320 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540374301420584, 1764656898914615, 1810104162020396, + 923808779163088, 664390074196579 +#else + 51293224, 22953365, 60569911, 26295436, 60124204, 26972653, + 35608016, 13765823, 39674467, 9900183 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1323460699404750, 1262690757880991, 871777133477900, + 1060078894988977, 1712236889662886 +#else + 14465486, 19721101, 34974879, 18815558, 39665676, 12990491, + 33046193, 15796406, 60056998, 25514317 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1696163952057966, 1391710137550823, 608793846867416, + 1034391509472039, 1780770894075012 +#else + 30924398, 25274812, 6359015, 20738097, 16508376, 9071735, + 41620263, 15413634, 9524356, 26535554 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1367603834210841, 2131988646583224, 890353773628144, + 1908908219165595, 270836895252891 +#else + 12274201, 20378885, 32627640, 31769106, 6736624, 13267305, + 5237659, 28444949, 15663515, 4035784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 597536315471731, 40375058742586, 1942256403956049, + 1185484645495932, 312666282024145 +#else + 64157555, 8903984, 17349946, 601635, 50676049, 28941875, + 53376124, 17665097, 44850385, 4659090 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1919411405316294, 1234508526402192, 1066863051997083, + 1008444703737597, 1348810787701552 +#else + 50192582, 28601458, 36715152, 18395610, 20774811, 15897498, + 5736189, 15026997, 64930608, 20098846 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102881477513865, 1570274565945361, 1573617900503708, + 18662635732583, 2232324307922098 +#else + 58249865, 31335375, 28571665, 23398914, 66634396, 23448733, + 63307367, 278094, 23440562, 33264224 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853931367696942, 8107973870707, 350214504129299, + 775206934582587, 1752317649166792 +#else + 10226222, 27625730, 15139955, 120818, 52241171, 5218602, + 32937275, 11551483, 50536904, 26111567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1417148368003523, 721357181628282, 505725498207811, + 373232277872983, 261634707184480 +#else + 17932739, 21117156, 43069306, 10749059, 11316803, 7535897, + 22503767, 5561594, 63462240, 3898660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2186733281493267, 2250694917008620, 1014829812957440, + 479998161452389, 83566193876474 +#else + 7749907, 32584865, 50769132, 33537967, 42090752, 15122142, + 65535333, 7152529, 21831162, 1245233 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268116367301224, 560157088142809, 802626839600444, + 2210189936605713, 1129993785579988 +#else + 26958440, 18896406, 4314585, 8346991, 61431100, 11960071, + 34519569, 32934396, 36706772, 16838219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615183387352312, 917611676109240, 878893615973325, + 978940963313282, 938686890583575 +#else + 54942968, 9166946, 33491384, 13673479, 29787085, 13096535, + 6280834, 14587357, 44770839, 13987524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522024729211672, 1045059315315808, 1892245413707790, + 1907891107684253, 2059998109500714 +#else + 42758936, 7778774, 21116000, 15572597, 62275598, 28196653, + 62807965, 28429792, 59639082, 30696363 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1799679152208884, 912132775900387, 25967768040979, + 432130448590461, 274568990261996 +#else + 9681908, 26817309, 35157219, 13591837, 60225043, 386949, + 31622781, 6439245, 52527852, 4091396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 98698809797682, 2144627600856209, 1907959298569602, + 811491302610148, 1262481774981493 +#else + 58682418, 1470726, 38999185, 31957441, 3978626, 28430809, + 47486180, 12092162, 29077877, 18812444 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1791451399743152, 1713538728337276, 118349997257490, + 1882306388849954, 158235232210248 +#else + 5269168, 26694706, 53878652, 25533716, 25932562, 1763552, + 61502754, 28048550, 47091016, 2357888 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217809823321928, 2173947284933160, 1986927836272325, + 1388114931125539, 12686131160169 +#else + 32264008, 18146780, 61721128, 32394338, 65017541, 29607531, + 23104803, 20684524, 5727337, 189038 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1650875518872272, 1136263858253897, 1732115601395988, + 734312880662190, 1252904681142109 +#else + 14609104, 24599962, 61108297, 16931650, 52531476, 25810533, + 40363694, 10942114, 41219933, 18669734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 372986456113865, 525430915458171, 2116279931702135, + 501422713587815, 1907002872974925 +#else + 20513481, 5557931, 51504251, 7829530, 26413943, 31535028, + 45729895, 7471780, 13913677, 28416557 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803147181835288, 868941437997146, 316299302989663, + 943495589630550, 571224287904572 +#else + 41534488, 11967825, 29233242, 12948236, 60354399, 4713226, + 58167894, 14059179, 12878652, 8511905 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 227742695588364, 1776969298667369, 628602552821802, + 457210915378118, 2041906378111140 +#else + 41452044, 3393630, 64153449, 26478905, 64858154, 9366907, + 36885446, 6812973, 5568676, 30426776 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 815000523470260, 913085688728307, 1052060118271173, + 1345536665214223, 541623413135555 +#else + 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, + 49700111, 20050058, 52713667, 8070817 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1580216071604333, 1877997504342444, 857147161260913, + 703522726778478, 2182763974211603 +#else + 27117677, 23547054, 35826092, 27984343, 1127281, 12772488, + 37262958, 10483305, 55556115, 32525717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870080310923419, 71988220958492, 1783225432016732, + 615915287105016, 1035570475990230 +#else + 10637467, 27866368, 5674780, 1072708, 40765276, 26572129, + 65424888, 9177852, 39615702, 15431202 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 730987750830150, 857613889540280, 1083813157271766, + 1002817255970169, 1719228484436074 +#else + 20525126, 10892566, 54366392, 12779442, 37615830, 16150074, + 38868345, 14943141, 52052074, 25618500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 377616581647602, 1581980403078513, 804044118130621, + 2034382823044191, 643844048472185 +#else + 37084402, 5626925, 66557297, 23573344, 753597, 11981191, + 25244767, 30314666, 63752313, 9594023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 176957326463017, 1573744060478586, 528642225008045, + 1816109618372371, 1515140189765006 +#else + 43356201, 2636869, 61944954, 23450613, 585133, 7877383, + 11345683, 27062142, 13352334, 22577348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888911448245718, 1387110895611080, 1924503794066429, + 1731539523700949, 2230378382645454 +#else + 65177046, 28146973, 3304648, 20669563, 17015805, 28677341, + 37325013, 25801949, 53893326, 33235227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 443392177002051, 233793396845137, 2199506622312416, + 1011858706515937, 974676837063129 +#else + 20239939, 6607058, 6203985, 3483793, 48721888, 32775202, + 46385121, 15077869, 44358105, 14523816 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846351103143623, 1949984838808427, 671247021915253, + 1946756846184401, 1929296930380217 +#else + 27406023, 27512775, 27423595, 29057038, 4996213, 10002360, + 38266833, 29008937, 36936121, 28748764 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 849646212452002, 1410198775302919, 73767886183695, + 1641663456615812, 762256272452411 +#else + 11374242, 12660715, 17861383, 21013599, 10935567, 1099227, + 53222788, 24462691, 39381819, 11358503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692017667358279, 723305578826727, 1638042139863265, + 748219305990306, 334589200523901 +#else + 54378055, 10311866, 1510375, 10778093, 64989409, 24408729, + 32676002, 11149336, 40985213, 4985767 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22893968530686, 2235758574399251, 1661465835630252, + 925707319443452, 1203475116966621 +#else + 48012542, 341146, 60911379, 33315398, 15756972, 24757770, + 66125820, 13794113, 47694557, 17933176 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801299035785166, 1733292596726131, 1664508947088596, + 467749120991922, 1647498584535623 +#else + 6490062, 11940286, 25495923, 25828072, 8668372, 24803116, + 3367602, 6970005, 65417799, 24549641 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 903105258014366, 427141894933047, 561187017169777, + 1884330244401954, 1914145708422219 +#else + 1656478, 13457317, 15370807, 6364910, 13605745, 8362338, + 47934242, 28078708, 50312267, 28522993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344191060517578, 1960935031767890, 1518838929955259, + 1781502350597190, 1564784025565682 +#else + 44835530, 20030007, 67044178, 29220208, 48503227, 22632463, + 46537798, 26546453, 67009010, 23317098 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 673723351748086, 1979969272514923, 1175287312495508, + 1187589090978666, 1881897672213940 +#else + 17747446, 10039260, 19368299, 29503841, 46478228, 17513145, + 31992682, 17696456, 37848500, 28042460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1917185587363432, 1098342571752737, 5935801044414, + 2000527662351839, 1538640296181569 +#else + 31932008, 28568291, 47496481, 16366579, 22023614, 88450, + 11371999, 29810185, 4882241, 22927527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2495540013192, 678856913479236, 224998292422872, + 219635787698590, 1972465269000940 +#else + 29796488, 37186, 19818052, 10115756, 55279832, 3352735, + 18551198, 3272828, 61917932, 29392022 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 271413961212179, 1353052061471651, 344711291283483, + 2014925838520662, 2006221033113941 +#else + 12501267, 4044383, 58495907, 20162046, 34678811, 5136598, + 47878486, 30024734, 330069, 29895023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 194583029968109, 514316781467765, 829677956235672, + 1676415686873082, 810104584395840 +#else + 6384877, 2899513, 17807477, 7663917, 64749976, 12363164, + 25366522, 24980540, 66837568, 12071498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1980510813313589, 1948645276483975, 152063780665900, + 129968026417582, 256984195613935 +#else + 58743349, 29511910, 25133447, 29037077, 60897836, 2265926, + 34339246, 1936674, 61949167, 3829362 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1860190562533102, 1936576191345085, 461100292705964, + 1811043097042830, 957486749306835 +#else + 28425966, 27718999, 66531773, 28857233, 52891308, 6870929, + 7921550, 26986645, 26333139, 14267664 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796664815624365, 1543160838872951, 1500897791837765, + 1667315977988401, 599303877030711 +#else + 56041645, 11871230, 27385719, 22994888, 62522949, 22365119, + 10004785, 24844944, 45347639, 8930323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1151480509533204, 2136010406720455, 738796060240027, + 319298003765044, 1150614464349587 +#else + 45911060, 17158396, 25654215, 31829035, 12282011, 11008919, + 1541940, 4757911, 40617363, 17145491 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1731069268103150, 735642447616087, 1364750481334268, + 417232839982871, 927108269127661 +#else + 13537262, 25794942, 46504023, 10961926, 61186044, 20336366, + 53952279, 6217253, 51165165, 13814989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1017222050227968, 1987716148359, 2234319589635701, + 621282683093392, 2132553131763026 +#else + 49686272, 15157789, 18705543, 29619, 24409717, 33293956, + 27361680, 9257833, 65152338, 31777517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1567828528453324, 1017807205202360, 565295260895298, + 829541698429100, 307243822276582 +#else + 42063564, 23362465, 15366584, 15166509, 54003778, 8423555, + 37937324, 12361134, 48422886, 4578289 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 249079270936248, 1501514259790706, 947909724204848, + 944551802437487, 552658763982480 +#else + 24579768, 3711570, 1342322, 22374306, 40103728, 14124955, + 44564335, 14074918, 21964432, 8235257 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2089966982947227, 1854140343916181, 2151980759220007, + 2139781292261749, 158070445864917 +#else + 60580251, 31142934, 9442965, 27628844, 12025639, 32067012, + 64127349, 31885225, 13006805, 2355433 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1338766321464554, 1906702607371284, 1519569445519894, + 115384726262267, 1393058953390992 +#else + 50803946, 19949172, 60476436, 28412082, 16974358, 22643349, + 27202043, 1719366, 1141648, 20758196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364621558265400, 1512388234908357, 1926731583198686, + 2041482526432505, 920401122333774 +#else + 54244920, 20334445, 58790597, 22536340, 60298718, 28710537, + 13475065, 30420460, 32674894, 13715045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1884844597333588, 601480070269079, 620203503079537, + 1079527400117915, 1202076693132015 +#else + 11423316, 28086373, 32344215, 8962751, 24989809, 9241752, + 53843611, 16086211, 38367983, 17912338 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 840922919763324, 727955812569642, 1303406629750194, + 522898432152867, 294161410441865 +#else + 65699196, 12530727, 60740138, 10847386, 19531186, 19422272, + 55399715, 7791793, 39862921, 4383346 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353760790835310, 1598361541848743, 1122905698202299, + 1922533590158905, 419107700666580 +#else + 38137966, 5271446, 65842855, 23817442, 54653627, 16732598, + 62246457, 28647982, 27193556, 6245191 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359856369838236, 180914355488683, 861726472646627, + 218807937262986, 575626773232501 +#else + 51914908, 5362277, 65324971, 2695833, 4960227, 12840725, + 23061898, 3260492, 22510453, 8577507 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755467689082474, 909202735047934, 730078068932500, + 936309075711518, 2007798262842972 +#else + 54476394, 11257345, 34415870, 13548176, 66387860, 10879010, + 31168030, 13952092, 37537372, 29918525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609384177904073, 362745185608627, 1335318541768201, + 800965770436248, 547877979267412 +#else + 3877321, 23981693, 32416691, 5405324, 56104457, 19897796, + 3759768, 11935320, 5611860, 8164018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984339177776787, 815727786505884, 1645154585713747, + 1659074964378553, 1686601651984156 +#else + 50833043, 14667796, 15906460, 12155291, 44997715, 24514713, + 32003001, 24722143, 5773084, 25132323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697863093781930, 599794399429786, 1104556219769607, + 830560774794755, 12812858601017 +#else + 43320746, 25300131, 1950874, 8937633, 18686727, 16459170, + 66203139, 12376319, 31632953, 190926 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168737550514982, 897832437380552, 463140296333799, + 302564600022547, 2008360505135501 +#else + 42515238, 17415546, 58684872, 13378745, 14162407, 6901328, + 58820115, 4508563, 41767309, 29926903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1856930662813910, 678090852002597, 1920179140755167, + 1259527833759868, 55540971895511 +#else + 8884438, 27670423, 6023973, 10104341, 60227295, 28612898, + 18722940, 18768427, 65436375, 827624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1158643631044921, 476554103621892, 178447851439725, + 1305025542653569, 103433927680625 +#else + 34388281, 17265135, 34605316, 7101209, 13354605, 2659080, + 65308289, 19446395, 42230385, 1541285 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2176793111709008, 1576725716350391, 2009350167273523, + 2012390194631546, 2125297410909580 +#else + 2901328, 32436745, 3880375, 23495044, 49487923, 29941650, + 45306746, 29986950, 20456844, 31669399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 825403285195098, 2144208587560784, 1925552004644643, + 1915177840006985, 1015952128947864 +#else + 27019610, 12299467, 53450576, 31951197, 54247203, 28692960, + 47568713, 28538373, 29439640, 15138866 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1807108316634472, 1534392066433717, 347342975407218, + 1153820745616376, 7375003497471 +#else + 21536104, 26928012, 34661045, 22864223, 44700786, 5175813, + 61688824, 17193268, 7779327, 109896 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 983061001799725, 431211889901241, 2201903782961093, + 817393911064341, 2214616493042167 +#else + 30279725, 14648750, 59063993, 6425557, 13639621, 32810923, + 28698389, 12180118, 23177719, 33000357 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 228567918409756, 865093958780220, 358083886450556, + 159617889659320, 1360637926292598 +#else + 26572828, 3405927, 35407164, 12890904, 47843196, 5335865, + 60615096, 2378491, 4439158, 20275085 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 234147501399755, 2229469128637390, 2175289352258889, + 1397401514549353, 1885288963089922 +#else + 44392139, 3489069, 57883598, 33221678, 18875721, 32414337, + 14819433, 20822905, 49391106, 28092994 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1111762412951562, 252849572507389, 1048714233823341, + 146111095601446, 1237505378776770 +#else + 62052362, 16566550, 15953661, 3767752, 56672365, 15627059, + 66287910, 2177224, 8550082, 18440267 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1113790697840279, 1051167139966244, 1045930658550944, + 2011366241542643, 1686166824620755 +#else + 48635543, 16596774, 66727204, 15663610, 22860960, 15585581, + 39264755, 29971692, 43848403, 25125843 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1054097349305049, 1872495070333352, 182121071220717, + 1064378906787311, 100273572924182 +#else + 34628313, 15707274, 58902952, 27902350, 29464557, 2713815, + 44383727, 15860481, 45206294, 1494192 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1306410853171605, 1627717417672447, 50983221088417, + 1109249951172250, 870201789081392 +#else + 47546773, 19467038, 41524991, 24254879, 13127841, 759709, + 21923482, 16529112, 8742704, 12967017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 104233794644221, 1548919791188248, 2224541913267306, + 2054909377116478, 1043803389015153 +#else + 38643965, 1553204, 32536856, 23080703, 42417258, 33148257, + 58194238, 30620535, 37205105, 15553882 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 216762189468802, 707284285441622, 190678557969733, + 973969342604308, 1403009538434867 +#else + 21877890, 3230008, 9881174, 10539357, 62311749, 2841331, + 11543572, 14513274, 19375923, 20906471 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1279024291038477, 344776835218310, 273722096017199, + 1834200436811442, 634517197663804 +#else + 8832269, 19058947, 13253510, 5137575, 5037871, 4078777, + 24880818, 27331716, 2862652, 9455043 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343805853118335, 1302216857414201, 566872543223541, + 2051138939539004, 321428858384280 +#else + 29306751, 5123106, 20245049, 19404543, 9592565, 8447059, + 65031740, 30564351, 15511448, 4789663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 470067171324852, 1618629234173951, 2000092177515639, + 7307679772789, 1117521120249968 +#else + 46429108, 7004546, 8824831, 24119455, 63063159, 29803695, + 61354101, 108892, 23513200, 16652362 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278151578291475, 1810282338562947, 1771599529530998, + 1383659409671631, 685373414471841 +#else + 33852691, 4144781, 62632835, 26975308, 10770038, 26398890, + 60458447, 20618131, 48789665, 10212859 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 577009397403102, 1791440261786291, 2177643735971638, + 174546149911960, 1412505077782326 +#else + 2756062, 8598110, 7383731, 26694540, 22312758, 32449420, + 21179800, 2600940, 57120566, 21047965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893719721537457, 1201282458018197, 1522349501711173, + 58011597740583, 1130406465887139 +#else + 42463153, 13317461, 36659605, 17900503, 21365573, 22684775, + 11344423, 864440, 64609187, 16844368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 412607348255453, 1280455764199780, 2233277987330768, + 14180080401665, 331584698417165 +#else + 40676061, 6148328, 49924452, 19080277, 18782928, 33278435, + 44547329, 211299, 2719757, 4940997 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 262483770854550, 990511055108216, 526885552771698, + 571664396646158, 354086190278723 +#else + 65784982, 3911312, 60160120, 14759764, 37081714, 7851206, + 21690126, 8518463, 26699843, 5276295 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1820352417585487, 24495617171480, 1547899057533253, + 10041836186225, 480457105094042 +#else + 53958991, 27125364, 9396248, 365013, 24703301, 23065493, + 1321585, 149635, 51656090, 7159368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2023310314989233, 637905337525881, 2106474638900687, + 557820711084072, 1687858215057826 +#else + 9987761, 30149673, 17507961, 9505530, 9731535, 31388918, + 22356008, 8312176, 22477218, 25151047 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1144168702609745, 604444390410187, 1544541121756138, + 1925315550126027, 626401428894002 +#else + 18155857, 17049442, 19744715, 9006923, 15154154, 23015456, + 24256459, 28689437, 44560690, 9334108 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1922168257351784, 2018674099908659, 1776454117494445, + 956539191509034, 36031129147635 +#else + 2986088, 28642539, 10776627, 30080588, 10620589, 26471229, + 45695018, 14253544, 44521715, 536905 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 544644538748041, 1039872944430374, 876750409130610, + 710657711326551, 1216952687484972 +#else + 4377737, 8115836, 24567078, 15495314, 11625074, 13064599, + 7390551, 10589625, 10838060, 18134008 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 58242421545916, 2035812695641843, 2118491866122923, + 1191684463816273, 46921517454099 +#else + 47766460, 867879, 9277171, 30335973, 52677291, 31567988, + 19295825, 17757482, 6378259, 699185 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 272268252444639, 1374166457774292, 2230115177009552, + 1053149803909880, 1354288411641016 +#else + 7895007, 4057113, 60027092, 20476675, 49222032, 33231305, + 66392824, 15693154, 62063800, 20180469 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1857910905368338, 1754729879288912, 885945464109877, + 1516096106802166, 1602902393369811 +#else + 59371282, 27685029, 52542544, 26147512, 11385653, 13201616, + 31730678, 22591592, 63190227, 23885106 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1193437069800958, 901107149704790, 999672920611411, + 477584824802207, 364239578697845 +#else + 10188286, 17783598, 59772502, 13427542, 22223443, 14896287, + 30743455, 7116568, 45322357, 5427592 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 886299989548838, 1538292895758047, 1590564179491896, + 1944527126709657, 837344427345298 +#else + 696102, 13206899, 27047647, 22922350, 15285304, 23701253, + 10798489, 28975712, 19236242, 12477404 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 754558365378305, 1712186480903618, 1703656826337531, + 750310918489786, 518996040250900 +#else + 55879425, 11243795, 50054594, 25513566, 66320635, 25386464, + 63211194, 11180503, 43939348, 7733643 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1309847803895382, 1462151862813074, 211370866671570, + 1544595152703681, 1027691798954090 +#else + 17800790, 19518253, 40108434, 21787760, 23887826, 3149671, + 23466177, 23016261, 10322026, 15313801 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803217563745370, 1884799722343599, 1357706345069218, + 2244955901722095, 730869460037413 +#else + 26246234, 11968874, 32263343, 28085704, 6830754, 20231401, + 51314159, 33452449, 42659621, 10890803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 689299471295966, 1831210565161071, 1375187341585438, + 1106284977546171, 1893781834054269 +#else + 35743198, 10271362, 54448239, 27287163, 16690206, 20491888, + 52126651, 16484930, 25180797, 28219548 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696351368613042, 1494385251239250, 738037133616932, + 636385507851544, 927483222611406 +#else + 66522290, 10376443, 34522450, 22268075, 19801892, 10997610, + 2276632, 9482883, 316878, 13820577 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949114198209333, 1104419699537997, 783495707664463, + 1747473107602770, 2002634765788641 +#else + 57226037, 29044064, 64993357, 16457135, 56008783, 11674995, + 30756178, 26039378, 30696929, 29841583 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1607325776830197, 530883941415333, 1451089452727895, + 1581691157083423, 496100432831154 +#else + 32988917, 23951020, 12499365, 7910787, 56491607, 21622917, + 59766047, 23569034, 34759346, 7392472 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1068900648804224, 2006891997072550, 1134049269345549, + 1638760646180091, 2055396084625778 +#else + 58253184, 15927860, 9866406, 29905021, 64711949, 16898650, + 36699387, 24419436, 25112946, 30627788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2222475519314561, 1870703901472013, 1884051508440561, + 1344072275216753, 1318025677799069 +#else + 64604801, 33117465, 25621773, 27875660, 15085041, 28074555, + 42223985, 20028237, 5537437, 19640113 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 155711679280656, 681100400509288, 389811735211209, + 2135723811340709, 408733211204125 +#else + 55883280, 2320284, 57524584, 10149186, 33664201, 5808647, + 52232613, 31824764, 31234589, 6090599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7813206966729, 194444201427550, 2071405409526507, + 1065605076176312, 1645486789731291 +#else + 57475529, 116425, 26083934, 2897444, 60744427, 30866345, 609720, + 15878753, 60138459, 24519663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 16625790644959, 1647648827778410, 1579910185572704, + 436452271048548, 121070048451050 +#else + 39351007, 247743, 51914090, 24551880, 23288160, 23542496, + 43239268, 6503645, 20650474, 1804084 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1037263028552531, 568385780377829, 297953104144430, + 1558584511931211, 2238221839292471 +#else + 39519059, 15456423, 8972517, 8469608, 15640622, 4439847, + 3121995, 23224719, 27842615, 33352104 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 190565267697443, 672855706028058, 338796554369226, + 337687268493904, 853246848691734 +#else + 51801891, 2839643, 22530074, 10026331, 4602058, 5048462, + 28248656, 5031932, 55733782, 12714368 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1763863028400139, 766498079432444, 1321118624818005, + 69494294452268, 858786744165651 +#else + 20807691, 26283607, 29286140, 11421711, 39232341, 19686201, + 45881388, 1035545, 47375635, 12796919 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1292056768563024, 1456632109855638, 1100631247050184, + 1386133165675321, 1232898350193752 +#else + 12076880, 19253146, 58323862, 21705509, 42096072, 16400683, + 49517369, 20654993, 3480664, 18371617 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366253102478259, 525676242508811, 1449610995265438, + 1183300845322183, 185960306491545 +#else + 34747315, 5457596, 28548107, 7833186, 7303070, 21600887, + 42745799, 17632556, 33734809, 2771024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 28315355815982, 460422265558930, 1799675876678724, + 1969256312504498, 1051823843138725 +#else + 45719598, 421931, 26597266, 6860826, 22486084, 26817260, + 49971378, 29344205, 42556581, 15673396 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 156914999361983, 1606148405719949, 1665208410108430, + 317643278692271, 1383783705665320 +#else + 46924223, 2338215, 19788685, 23933476, 63107598, 24813538, + 46837679, 4733253, 3727144, 20619984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 54684536365732, 2210010038536222, 1194984798155308, + 535239027773705, 1516355079301361 +#else + 6120100, 814863, 55314462, 32931715, 6812204, 17806661, 2019593, + 7975683, 31123697, 22595451 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1484387703771650, 198537510937949, 2186282186359116, + 617687444857508, 647477376402122 +#else + 30069250, 22119100, 30434653, 2958439, 18399564, 32578143, + 12296868, 9204260, 50676426, 9648164 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2147715541830533, 500032538445817, 646380016884826, + 352227855331122, 1488268620408052 +#else + 32705413, 32003455, 30705657, 7451065, 55303258, 9631812, + 3305266, 5248604, 41100532, 22176930 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 159386186465542, 1877626593362941, 618737197060512, + 1026674284330807, 1158121760792685 +#else + 17219846, 2375039, 35537917, 27978816, 47649184, 9219902, + 294711, 15298639, 2662509, 17257359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1744544377739822, 1964054180355661, 1685781755873170, + 2169740670377448, 1286112621104591 +#else + 65935918, 25995736, 62742093, 29266687, 45762450, 25120105, + 32087528, 32331655, 32247247, 19164571 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 81977249784993, 1667943117713086, 1668983819634866, + 1605016835177615, 1353960708075544 +#else + 14312609, 1221556, 17395390, 24854289, 62163122, 24869796, + 38911119, 23916614, 51081240, 20175586 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1602253788689063, 439542044889886, 2220348297664483, + 657877410752869, 157451572512238 +#else + 65680039, 23875441, 57873182, 6549686, 59725795, 33085767, + 23046501, 9803137, 17597934, 2346211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1029287186166717, 65860128430192, 525298368814832, + 1491902500801986, 1461064796385400 +#else + 18510781, 15337574, 26171504, 981392, 44867312, 7827555, + 43617730, 22231079, 3059832, 21771562 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 408216988729246, 2121095722306989, 913562102267595, + 1879708920318308, 241061448436731 +#else + 10141598, 6082907, 17829293, 31606789, 9830091, 13613136, + 41552228, 28009845, 33606651, 3592095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1185483484383269, 1356339572588553, 584932367316448, + 102132779946470, 1792922621116791 +#else + 33114149, 17665080, 40583177, 20211034, 33076704, 8716171, + 1151462, 1521897, 66126199, 26716628 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1966196870701923, 2230044620318636, 1425982460745905, + 261167817826569, 46517743394330 +#else + 34169699, 29298616, 23947180, 33230254, 34035889, 21248794, + 50471177, 3891703, 26353178, 693168 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 107077591595359, 884959942172345, 27306869797400, + 2224911448949390, 964352058245223 +#else + 30374239, 1595580, 50224825, 13186930, 4600344, 406904, 9585294, + 33153764, 31375463, 14369965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730194207717538, 431790042319772, 1831515233279467, + 1372080552768581, 1074513929381760 +#else + 52738210, 25781902, 1510300, 6434173, 48324075, 27291703, + 32732229, 20445593, 17901440, 16011505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450880638731607, 1019861580989005, 1229729455116861, + 1174945729836143, 826083146840706 +#else + 18171223, 21619806, 54608461, 15197121, 56070717, 18324396, + 47936623, 17508055, 8764034, 12309598 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1899935429242705, 1602068751520477, 940583196550370, + 82431069053859, 1540863155745696 +#else + 5975889, 28311244, 47649501, 23872684, 55567586, 14015781, + 43443107, 1228318, 17544096, 22960650 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2136688454840028, 2099509000964294, 1690800495246475, + 1217643678575476, 828720645084218 +#else + 5811932, 31839139, 3442886, 31285122, 48741515, 25194890, + 49064820, 18144304, 61543482, 12348899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 765548025667841, 462473984016099, 998061409979798, + 546353034089527, 2212508972466858 +#else + 35709185, 11407554, 25755363, 6891399, 63851926, 14872273, + 42259511, 8141294, 56476330, 32968952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 46575283771160, 892570971573071, 1281983193144090, + 1491520128287375, 75847005908304 +#else + 54433560, 694025, 62032719, 13300343, 14015258, 19103038, + 57410191, 22225381, 30944592, 1130208 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1801436127943107, 1734436817907890, 1268728090345068, + 167003097070711, 2233597765834956 +#else + 8247747, 26843490, 40546482, 25845122, 52706924, 18905521, + 4652151, 2488540, 23550156, 33283200 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997562060465113, 1048700225534011, 7615603985628, + 1855310849546841, 2242557647635213 +#else + 17294297, 29765994, 7026747, 15626851, 22990044, 113481, + 2267737, 27646286, 66700045, 33416712 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1161017320376250, 492624580169043, 2169815802355237, + 976496781732542, 1770879511019629 +#else + 16091066, 17300506, 18599251, 7340678, 2137637, 32332775, + 63744702, 14550935, 3260525, 26388161 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1357044908364776, 729130645262438, 1762469072918979, + 1365633616878458, 181282906404941 +#else + 62198760, 20221544, 18550886, 10864893, 50649539, 26262835, + 44079994, 20349526, 54360141, 2701325 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1080413443139865, 1155205815510486, 1848782073549786, + 622566975152580, 124965574467971 +#else + 58534169, 16099414, 4629974, 17213908, 46322650, 27548999, + 57090500, 9276970, 11329923, 1862132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1184526762066993, 247622751762817, 692129017206356, + 820018689412496, 2188697339828085 +#else + 14763057, 17650824, 36190593, 3689866, 3511892, 10313526, + 45157776, 12219230, 58070901, 32614131 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2020536369003019, 202261491735136, 1053169669150884, + 2056531979272544, 778165514694311 +#else + 8894987, 30108338, 6150752, 3013931, 301220, 15693451, 35127648, + 30644714, 51670695, 11595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237404399610207, 1308324858405118, 1229680749538400, + 720131409105291, 1958958863624906 +#else + 15214943, 3537601, 40870142, 19495559, 4418656, 18323671, + 13947275, 10730794, 53619402, 29190761 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 515583508038846, 17656978857189, 1717918437373989, + 1568052070792483, 46975803123923 +#else + 64570558, 7682792, 32759013, 263109, 37124133, 25598979, + 44776739, 23365796, 977107, 699994 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 281527309158085, 36970532401524, 866906920877543, + 2222282602952734, 1289598729589882 +#else + 54642373, 4195083, 57897332, 550903, 51543527, 12917919, + 19118110, 33114591, 36574330, 19216518 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1278207464902042, 494742455008756, 1262082121427081, + 1577236621659884, 1888786707293291 +#else + 31788442, 19046775, 4799988, 7372237, 8808585, 18806489, + 9408236, 23502657, 12493931, 28145115 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353042527954210, 1830056151907359, 1111731275799225, + 174960955838824, 404312815582675 +#else + 41428258, 5260743, 47873055, 27269961, 63412921, 16566086, + 27218280, 2607121, 29375955, 6024730 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2064251142068628, 1666421603389706, 1419271365315441, + 468767774902855, 191535130366583 +#else + 842132, 30759739, 62345482, 24831616, 26332017, 21148791, + 11831879, 6985184, 57168503, 2854095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1716987058588002, 1859366439773457, 1767194234188234, + 64476199777924, 1117233614485261 +#else + 62261602, 25585100, 2516241, 27706719, 9695690, 26333246, + 16512644, 960770, 12121869, 16648078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984292135520292, 135138246951259, 2220652137473167, + 1722843421165029, 190482558012909 +#else + 51890212, 14667095, 53772635, 2013716, 30598287, 33090295, + 35603941, 25672367, 20237805, 2838411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 298845952651262, 1166086588952562, 1179896526238434, + 1347812759398693, 1412945390096208 +#else + 47820798, 4453151, 15298546, 17376044, 22115042, 17581828, + 12544293, 20083975, 1068880, 21054527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143239552672925, 906436640714209, 2177000572812152, + 2075299936108548, 325186347798433 +#else + 57549981, 17035596, 33238497, 13506958, 30505848, 32439836, + 58621956, 30924378, 12521377, 4845654 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 721024854374772, 684487861263316, 1373438744094159, + 2193186935276995, 1387043709851261 +#else + 38910324, 10744107, 64150484, 10199663, 7759311, 20465832, + 3409347, 32681032, 60626557, 20668561 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 418098668140962, 715065997721283, 1471916138376055, + 2168570337288357, 937812682637044 +#else + 43547042, 6230155, 46726851, 10655313, 43068279, 21933259, + 10477733, 32314216, 63995636, 13974497 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1043584187226485, 2143395746619356, 2209558562919611, + 482427979307092, 847556718384018 +#else + 12966261, 15550616, 35069916, 31939085, 21025979, 32924988, + 5642324, 7188737, 18895762, 12629579 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1248731221520759, 1465200936117687, 540803492710140, + 52978634680892, 261434490176109 +#else + 14741879, 18607545, 22177207, 21833195, 1279740, 8058600, + 11758140, 789443, 32195181, 3895677 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1057329623869501, 620334067429122, 461700859268034, + 2012481616501857, 297268569108938 +#else + 10758205, 15755439, 62598914, 9243697, 62229442, 6879878, + 64904289, 29988312, 58126794, 4429646 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1055352180870759, 1553151421852298, 1510903185371259, + 1470458349428097, 1226259419062731 +#else + 64654951, 15725972, 46672522, 23143759, 61304955, 22514211, + 59972993, 21911536, 18047435, 18272689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1492988790301668, 790326625573331, 1190107028409745, + 1389394752159193, 1620408196604194 +#else + 41935844, 22247266, 29759955, 11776784, 44846481, 17733976, + 10993113, 20703595, 49488162, 24145963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47000654413729, 1004754424173864, 1868044813557703, + 173236934059409, 588771199737015 +#else + 21987233, 700364, 42603816, 14972007, 59334599, 27836036, + 32155025, 2581431, 37149879, 8773374 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 30498470091663, 1082245510489825, 576771653181956, + 806509986132686, 1317634017056939 +#else + 41540495, 454462, 53896929, 16126714, 25240068, 8594567, + 20656846, 12017935, 59234475, 19634276 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420308055751555, 1493354863316002, 165206721528088, + 1884845694919786, 2065456951573059 +#else + 6028163, 6263078, 36097058, 22252721, 66289944, 2461771, + 35267690, 28086389, 65387075, 30777706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115636332012334, 1854340990964155, 83792697369514, + 1972177451994021, 457455116057587 +#else + 54829870, 16624276, 987579, 27631834, 32908202, 1248608, + 7719845, 29387734, 28408819, 6816612 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1698968457310898, 1435137169051090, 1083661677032510, + 938363267483709, 340103887207182 +#else + 56750770, 25316602, 19549650, 21385210, 22082622, 16147817, + 20613181, 13982702, 56769294, 5067942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1995325341336574, 911500251774648, 164010755403692, + 855378419194762, 1573601397528842 +#else + 36602878, 29732664, 12074680, 13582412, 47230892, 2443950, + 47389578, 12746131, 5331210, 23448488 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 241719380661528, 310028521317150, 1215881323380194, + 1408214976493624, 2141142156467363 +#else + 30528792, 3601899, 65151774, 4619784, 39747042, 18118043, + 24180792, 20984038, 27679907, 31905504 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315157046163473, 727368447885818, 1363466668108618, + 1668921439990361, 1398483384337907 +#else + 9402385, 19597367, 32834042, 10838634, 40528714, 20317236, + 26653273, 24868867, 22611443, 20839026 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 75029678299646, 1015388206460473, 1849729037055212, + 1939814616452984, 444404230394954 +#else + 22190590, 1118029, 22736441, 15130463, 36648172, 27563110, + 19189624, 28905490, 4854858, 6622139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2053597130993710, 2024431685856332, 2233550957004860, + 2012407275509545, 872546993104440 +#else + 58798126, 30600981, 58846284, 30166382, 56707132, 33282502, + 13424425, 29987205, 26404408, 13001963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217269667678610, 599909351968693, 1390077048548598, + 1471879360694802, 739586172317596 +#else + 35867026, 18138731, 64114613, 8939345, 11562230, 20713762, + 41044498, 21932711, 51703708, 11020692 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718318639380794, 1560510726633958, 904462881159922, + 1418028351780052, 94404349451937 +#else + 1866042, 25604943, 59210214, 23253421, 12483314, 13477547, + 3175636, 21130269, 28761761, 1406734 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132502667405250, 214379346175414, 1502748313768060, + 1960071701057800, 1353971822643138 +#else + 66660290, 31776765, 13018550, 3194501, 57528444, 22392694, + 24760584, 29207344, 25577410, 20175752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319394212043702, 2127459436033571, 717646691535162, + 663366796076914, 318459064945314 +#else + 42818486, 4759344, 66418211, 31701615, 2066746, 10693769, + 37513074, 9884935, 57739938, 4745409 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 405989424923593, 1960452633787083, 667349034401665, + 1492674260767112, 1451061489880787 +#else + 57967561, 6049713, 47577803, 29213020, 35848065, 9944275, + 51646856, 22242579, 10931923, 21622501 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 947085906234007, 323284730494107, 1485778563977200, + 728576821512394, 901584347702286 +#else + 50547351, 14112679, 59096219, 4817317, 59068400, 22139825, + 44255434, 10856640, 46638094, 13434653 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1575783124125742, 2126210792434375, 1569430791264065, + 1402582372904727, 1891780248341114 +#else + 22759470, 23480998, 50342599, 31683009, 13637441, 23386341, + 1765143, 20900106, 28445306, 28189722 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 838432205560695, 1997703511451664, 1018791879907867, + 1662001808174331, 78328132957753 +#else + 29875063, 12493613, 2795536, 29768102, 1710619, 15181182, + 56913147, 24765756, 9074233, 1167180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 739152638255629, 2074935399403557, 505483666745895, + 1611883356514088, 628654635394878 +#else + 40903181, 11014232, 57266213, 30918946, 40200743, 7532293, + 48391976, 24018933, 3843902, 9367684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1822054032121349, 643057948186973, 7306757352712, + 577249257962099, 284735863382083 +#else + 56139269, 27150720, 9591133, 9582310, 11349256, 108879, + 16235123, 8601684, 66969667, 4242894 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1366558556363930, 1448606567552086, 1478881020944768, + 165803179355898, 1115718458123498 +#else + 22092954, 20363309, 65066070, 21585919, 32186752, 22037044, + 60534522, 2470659, 39691498, 16625500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204146226972102, 1630511199034723, 2215235214174763, + 174665910283542, 956127674017216 +#else + 56051142, 3042015, 13770083, 24296510, 584235, 33009577, + 59338006, 2602724, 39757248, 14247412 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1562934578796716, 1070893489712745, 11324610642270, + 958989751581897, 2172552325473805 +#else + 6314156, 23289540, 34336361, 15957556, 56951134, 168749, + 58490057, 14290060, 27108877, 32373552 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1770564423056027, 735523631664565, 1326060113795289, + 1509650369341127, 65892421582684 +#else + 58522267, 26383465, 13241781, 10960156, 34117849, 19759835, + 33547975, 22495543, 39960412, 981873 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 623682558650637, 1337866509471512, 990313350206649, + 1314236615762469, 1164772974270275 +#else + 22833421, 9293594, 34459416, 19935764, 57971897, 14756818, + 44180005, 19583651, 56629059, 17356469 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 223256821462517, 723690150104139, 1000261663630601, + 933280913953265, 254872671543046 +#else + 59340277, 3326785, 38997067, 10783823, 19178761, 14905060, + 22680049, 13906969, 51175174, 3797898 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969087237026041, 624795725447124, 1335555107635969, + 2069986355593023, 1712100149341902 +#else + 21721337, 29341686, 54902740, 9310181, 63226625, 19901321, + 23740223, 30845200, 20491982, 25512280 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1236103475266979, 1837885883267218, 1026072585230455, + 1025865513954973, 1801964901432134 +#else + 9209251, 18419377, 53852306, 27386633, 66377847, 15289672, + 25947805, 15286587, 30997318, 26851369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115241013365517, 1712251818829143, 2148864332502771, + 2096001471438138, 2235017246626125 +#else + 7392013, 16618386, 23946583, 25514540, 53843699, 32020573, + 52911418, 31232855, 17649997, 33304352 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299268198601632, 2047148477845621, 2165648650132450, + 1612539282026145, 514197911628890 +#else + 57807776, 19360604, 30609525, 30504889, 41933794, 32270679, + 51867297, 24028707, 64875610, 7662145 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 118352772338543, 1067608711804704, 1434796676193498, + 1683240170548391, 230866769907437 +#else + 49550191, 1763593, 33994528, 15908609, 37067994, 21380136, + 7335079, 25082233, 63934189, 3440182 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850689576796636, 1601590730430274, 1139674615958142, + 1954384401440257, 76039205311 +#else + 47219164, 27577423, 42997570, 23865561, 10799742, 16982475, + 40449, 29122597, 4862399, 1133 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723387471374172, 997301467038410, 533927635123657, + 20928644693965, 1756575222802513 +#else + 34252636, 25680474, 61686474, 14860949, 50789833, 7956141, + 7258061, 311861, 36513873, 26175010 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146711623855116, 503278928021499, 625853062251406, + 1109121378393107, 1033853809911861 +#else + 63335436, 31988495, 28985339, 7499440, 24445838, 9325937, + 29727763, 16527196, 18278453, 15405622 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 571005965509422, 2005213373292546, 1016697270349626, + 56607856974274, 914438579435146 +#else + 62726958, 8508651, 47210498, 29880007, 61124410, 15149969, + 53795266, 843522, 45233802, 13626196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346698876211176, 2076651707527589, 1084761571110205, + 265334478828406, 1068954492309671 +#else + 2281448, 20067377, 56193445, 30944521, 1879357, 16164207, + 56324982, 3953791, 13340839, 15928663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1769967932677654, 1695893319756416, 1151863389675920, + 1781042784397689, 400287774418285 +#else + 31727126, 26374577, 48671360, 25270779, 2875792, 17164102, + 41838969, 26539605, 43656557, 5964752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1851867764003121, 403841933237558, 820549523771987, + 761292590207581, 1743735048551143 +#else + 4100401, 27594980, 49929526, 6017713, 48403027, 12227140, + 40424029, 11344143, 2538215, 25983677 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 410915148140008, 2107072311871739, 1004367461876503, + 99684895396761, 1180818713503224 +#else + 57675240, 6123112, 11159803, 31397824, 30016279, 14966241, + 46633881, 1485420, 66479608, 17595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 285945406881439, 648174397347453, 1098403762631981, + 1366547441102991, 1505876883139217 +#else + 40304287, 4260918, 11851389, 9658551, 35091757, 16367491, + 46903439, 20363143, 11659921, 22439314 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 672095903120153, 1675918957959872, 636236529315028, + 1569297300327696, 2164144194785875 +#else + 26180377, 10015009, 36264640, 24973138, 5418196, 9480663, + 2231568, 23384352, 33100371, 32248261 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1902708175321798, 1035343530915438, 1178560808893263, + 301095684058146, 1280977479761118 +#else + 15121094, 28352561, 56718958, 15427820, 39598927, 17561924, + 21670946, 4486675, 61177054, 19088051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1615357281742403, 404257611616381, 2160201349780978, + 1160947379188955, 1578038619549541 +#else + 16166467, 24070699, 56004733, 6023907, 35182066, 32189508, + 2340059, 17299464, 56373093, 23514607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013087639791217, 822734930507457, 1785668418619014, + 1668650702946164, 389450875221715 +#else + 28042865, 29997343, 54982337, 12259705, 63391366, 26608532, + 6766452, 24864833, 18036435, 5803270 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 453918449698368, 106406819929001, 2072540975937135, + 308588860670238, 1304394580755385 +#else + 66291264, 6763911, 11803561, 1585585, 10958447, 30883267, + 23855390, 4598332, 60949433, 19436993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295082798350326, 2091844511495996, 1851348972587817, + 3375039684596, 789440738712837 +#else + 36077558, 19298237, 17332028, 31170912, 31312681, 27587249, + 696308, 50292, 47013125, 11763583 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2083069137186154, 848523102004566, 993982213589257, + 1405313299916317, 1532824818698468 +#else + 66514282, 31040148, 34874710, 12643979, 12650761, 14811489, + 665117, 20940800, 47335652, 22840869 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495961298852430, 1397203457344779, 1774950217066942, + 139302743555696, 66603584342787 +#else + 30464590, 22291560, 62981387, 20819953, 19835326, 26448819, + 42712688, 2075772, 50088707, 992470 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1782411379088302, 1096724939964781, 27593390721418, + 542241850291353, 1540337798439873 +#else + 18357166, 26559999, 7766381, 16342475, 37783946, 411173, + 14578841, 8080033, 55534529, 22952821 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 693543956581437, 171507720360750, 1557908942697227, + 1074697073443438, 1104093109037196 +#else + 19598397, 10334610, 12555054, 2555664, 18821899, 23214652, + 21873262, 16014234, 26224780, 16452269 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 345288228393419, 1099643569747172, 134881908403743, + 1740551994106740, 248212179299770 +#else + 36884939, 5145195, 5944548, 16385966, 3976735, 2009897, + 55731060, 25936245, 46575034, 3698649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 231429562203065, 1526290236421172, 2021375064026423, + 1520954495658041, 806337791525116 +#else + 14187449, 3448569, 56472628, 22743496, 44444983, 30120835, + 7268409, 22663988, 27394300, 12015369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079623667189886, 872403650198613, 766894200588288, + 2163700860774109, 2023464507911816 +#else + 19695742, 16087646, 28032085, 12999827, 6817792, 11427614, + 20244189, 32241655, 53849736, 30151970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 854645372543796, 1936406001954827, 151460662541253, + 825325739271555, 1554306377287556 +#else + 30860084, 12735208, 65220619, 28854697, 50133957, 2256939, + 58942851, 12298311, 58558340, 23160969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497138821904622, 1044820250515590, 1742593886423484, + 1237204112746837, 849047450816987 +#else + 61389038, 22309106, 65198214, 15569034, 26642876, 25966672, + 61319509, 18435777, 62132699, 12651792 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 667962773375330, 1897271816877105, 1399712621683474, + 1143302161683099, 2081798441209593 +#else + 64260450, 9953420, 11531313, 28271553, 26895122, 20857343, + 53990043, 17036529, 9768697, 31021214 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 127147851567005, 1936114012888110, 1704424366552046, + 856674880716312, 716603621335359 +#else + 42389405, 1894650, 66821166, 28850346, 15348718, 25397902, + 32767512, 12765450, 4940095, 10678226 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1072409664800960, 2146937497077528, 1508780108920651, + 935767602384853, 1112800433544068 +#else + 18860224, 15980149, 48121624, 31991861, 40875851, 22482575, + 59264981, 13944023, 42736516, 16582018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333549023751292, 280219272863308, 2104176666454852, + 1036466864875785, 536135186520207 +#else + 51604604, 4970267, 37215820, 4175592, 46115652, 31354675, + 55404809, 15444559, 56105103, 7989036 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 373666279883137, 146457241530109, 304116267127857, + 416088749147715, 1258577131183391 +#else + 31490433, 5568061, 64696061, 2182382, 34772017, 4531685, + 35030595, 6200205, 47422751, 18754260 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1186115062588401, 2251609796968486, 1098944457878953, + 1153112761201374, 1791625503417267 +#else + 49800177, 17674491, 35586086, 33551600, 34221481, 16375548, + 8680158, 17182719, 28550067, 26697300 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870078460219737, 2129630962183380, 852283639691142, + 292865602592851, 401904317342226 +#else + 38981977, 27866340, 16837844, 31733974, 60258182, 12700015, + 37068883, 4364037, 1155602, 5988841 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1361070124828035, 815664541425524, 1026798897364671, + 1951790935390647, 555874891834790 +#else + 21890435, 20281525, 54484852, 12154348, 59276991, 15300495, + 23148983, 29083951, 24618406, 8283181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1546301003424277, 459094500062839, 1097668518375311, + 1780297770129643, 720763293687608 +#else + 33972757, 23041680, 9975415, 6841041, 35549071, 16356535, + 3070187, 26528504, 1466168, 10740210 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1212405311403990, 1536693382542438, 61028431067459, + 1863929423417129, 1223219538638038 +#else + 65599446, 18066246, 53605478, 22898515, 32799043, 909394, + 53169961, 27774712, 34944214, 18227391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1294303766540260, 1183557465955093, 882271357233093, + 63854569425375, 2213283684565087 +#else + 3960804, 19286629, 39082773, 17636380, 47704005, 13146867, + 15567327, 951507, 63848543, 32980496 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 339050984211414, 601386726509773, 413735232134068, + 966191255137228, 1839475899458159 +#else + 24740822, 5052253, 37014733, 8961360, 25877428, 6165135, + 42740684, 14397371, 59728495, 27410326 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 235605972169408, 2174055643032978, 1538335001838863, + 1281866796917192, 1815940222628465 +#else + 38220480, 3510802, 39005586, 32395953, 55870735, 22922977, + 51667400, 19101303, 65483377, 27059617 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1632352921721536, 1833328609514701, 2092779091951987, + 1923956201873226, 2210068022482919 +#else + 793280, 24323954, 8836301, 27318725, 39747955, 31184838, + 33152842, 28669181, 57202663, 32932579 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 35271216625062, 1712350667021807, 983664255668860, + 98571260373038, 1232645608559836 +#else + 5666214, 525582, 20782575, 25516013, 42570364, 14657739, + 16099374, 1468826, 60937436, 18367850 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1998172393429622, 1798947921427073, 784387737563581, + 1589352214827263, 1589861734168180 +#else + 62249590, 29775088, 64191105, 26806412, 7778749, 11688288, + 36704511, 23683193, 65549940, 23690785 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1733739258725305, 31715717059538, 201969945218860, + 992093044556990, 1194308773174556 +#else + 10896313, 25834728, 824274, 472601, 47648556, 3009586, 25248958, + 14783338, 36527388, 17796587 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 846415389605137, 746163495539180, 829658752826080, + 592067705956946, 957242537821393 +#else + 10566929, 12612572, 35164652, 11118702, 54475488, 12362878, + 21752402, 8822496, 24003793, 14264025 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1758148849754419, 619249044817679, 168089007997045, + 1371497636330523, 1867101418880350 +#else + 27713843, 26198459, 56100623, 9227529, 27050101, 2504721, + 23886875, 20436907, 13958494, 27821979 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 326633984209635, 261759506071016, 1700682323676193, + 1577907266349064, 1217647663383016 +#else + 43627235, 4867225, 39861736, 3900520, 29838369, 25342141, + 35219464, 23512650, 7340520, 18144364 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714182387328607, 1477856482074168, 574895689942184, + 2159118410227270, 1555532449716575 +#else + 4646495, 25543308, 44342840, 22021777, 23184552, 8566613, + 31366726, 32173371, 52042079, 23179239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 853828206885131, 998498946036955, 1835887550391235, + 207627336608048, 258363815956050 +#else + 49838347, 12723031, 50115803, 14878793, 21619651, 27356856, + 27584816, 3093888, 58265170, 3849920 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141141474651677, 1236728744905256, 643101419899887, + 1646615130509173, 1208239602291765 +#else + 58043933, 2103171, 25561640, 18428694, 61869039, 9582957, + 32477045, 24536477, 5002293, 18004173 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1501663228068911, 1354879465566912, 1444432675498247, + 897812463852601, 855062598754348 +#else + 55051311, 22376525, 21115584, 20189277, 8808711, 21523724, + 16489529, 13378448, 41263148, 12741425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 714380763546606, 1032824444965790, 1774073483745338, + 1063840874947367, 1738680636537158 +#else + 61162478, 10645102, 36197278, 15390283, 63821882, 26435754, + 24306471, 15852464, 28834118, 25908360 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1640635546696252, 633168953192112, 2212651044092396, + 30590958583852, 368515260889378 +#else + 49773116, 24447374, 42577584, 9434952, 58636780, 32971069, + 54018092, 455840, 20461858, 5491305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1171650314802029, 1567085444565577, 1453660792008405, + 757914533009261, 1619511342778196 +#else + 13669229, 17458950, 54626889, 23351392, 52539093, 21661233, + 42112877, 11293806, 38520660, 24132599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420958967093237, 971103481109486, 2169549185607107, + 1301191633558497, 1661514101014240 +#else + 28497909, 6272777, 34085870, 14470569, 8906179, 32328802, + 18504673, 19389266, 29867744, 24758489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 907123651818302, 1332556122804146, 1824055253424487, + 1367614217442959, 1982558335973172 +#else + 50901822, 13517195, 39309234, 19856633, 24009063, 27180541, + 60741263, 20379039, 22853428, 29542421 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121533090144639, 1021251337022187, 110469995947421, + 1511059774758394, 2110035908131662 +#else + 24191359, 16712145, 53177067, 15217830, 14542237, 1646131, + 18603514, 22516545, 12876622, 31441985 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 303213233384524, 2061932261128138, 352862124777736, + 40828818670255, 249879468482660 +#else + 17902668, 4518229, 66697162, 30725184, 26878216, 5258055, + 54248111, 608396, 16031844, 3723494 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 856559257852200, 508517664949010, 1378193767894916, + 1723459126947129, 1962275756614521 +#else + 38476072, 12763727, 46662418, 7577503, 33001348, 20536687, + 17558841, 25681542, 23896953, 29240187 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445691340537320, 40614383122127, 402104303144865, + 485134269878232, 1659439323587426 +#else + 47103464, 21542479, 31520463, 605201, 2543521, 5991821, + 64163800, 7229063, 57189218, 24727572 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 20057458979482, 1183363722525800, 2140003847237215, + 2053873950687614, 2112017736174909 +#else + 28816026, 298879, 38943848, 17633493, 19000927, 31888542, + 54428030, 30605106, 49057085, 31471516 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2228654250927986, 1483591363415267, 1368661293910956, + 1076511285177291, 526650682059608 +#else + 16000882, 33209536, 3493091, 22107234, 37604268, 20394642, + 12577739, 16041268, 47393624, 7847706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 709481497028540, 531682216165724, 316963769431931, + 1814315888453765, 258560242424104 +#else + 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, + 34252933, 27035413, 57088296, 3852847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1053447823660455, 1955135194248683, 1010900954918985, + 1182614026976701, 1240051576966610 +#else + 55678375, 15697595, 45987307, 29133784, 5386313, 15063598, + 16514493, 17622322, 29330898, 18478208 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1957943897155497, 1788667368028035, 137692910029106, + 1039519607062, 826404763313028 +#else + 41609129, 29175637, 51885955, 26653220, 16615730, 2051784, + 3303702, 15490, 39560068, 12314390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1848942433095597, 1582009882530495, 1849292741020143, + 1068498323302788, 2001402229799484 +#else + 15683501, 27551389, 18109119, 23573784, 15337967, 27556609, + 50391428, 15921865, 16103996, 29823217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528282417624269, 2142492439828191, 2179662545816034, + 362568973150328, 1591374675250271 +#else + 43939021, 22773182, 13588191, 31925625, 63310306, 32479502, + 47835256, 5402698, 37293151, 23713330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160026679434388, 232341189218716, 2149181472355545, + 598041771119831, 183859001910173 +#else + 23190676, 2384583, 34394524, 3462153, 37205209, 32025299, + 55842007, 8911516, 41903005, 2739712 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013278155187349, 662660471354454, 793981225706267, + 411706605985744, 804490933124791 +#else + 21374101, 30000182, 33584214, 9874410, 15377179, 11831242, + 33578960, 6134906, 4931255, 11987849 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051892037280204, 488391251096321, 2230187337030708, + 930221970662692, 679002758255210 +#else + 67101132, 30575573, 50885377, 7277596, 105524, 33232381, + 35628324, 13861387, 37032554, 10117929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1530723630438670, 875873929577927, 341560134269988, + 449903119530753, 1055551308214179 +#else + 37607694, 22809559, 40945095, 13051538, 41483300, 5089642, + 60783361, 6704078, 12890019, 15728940 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461835919309432, 1955256480136428, 180866187813063, + 1551979252664528, 557743861963950 +#else + 45136504, 21783052, 66157804, 29135591, 14704839, 2695116, + 903376, 23126293, 12885166, 8311031 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359179641731115, 1324915145732949, 902828372691474, + 294254275669987, 1887036027752957 +#else + 49592363, 5352193, 10384213, 19742774, 7506450, 13453191, + 26423267, 4384730, 1888765, 28119028 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2043271609454323, 2038225437857464, 1317528426475850, + 1398989128982787, 2027639881006861 +#else + 41291507, 30447119, 53614264, 30371925, 30896458, 19632703, + 34857219, 20846562, 47644429, 30214188 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2072902725256516, 312132452743412, 309930885642209, + 996244312618453, 1590501300352303 +#else + 43500868, 30888657, 66582772, 4651135, 5765089, 4618330, + 6092245, 14845197, 17151279, 23700316 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1397254305160710, 695734355138021, 2233992044438756, + 1776180593969996, 1085588199351115 +#else + 42278406, 20820711, 51942885, 10367249, 37577956, 33289075, + 22825804, 26467153, 50242379, 16176524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 440567051331029, 254894786356681, 493869224930222, + 1556322069683366, 1567456540319218 +#else + 43525589, 6564960, 20063689, 3798228, 62368686, 7359224, + 2006182, 23191006, 38362610, 23356922 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1950722461391320, 1907845598854797, 1822757481635527, + 2121567704750244, 73811931471221 +#else + 56482264, 29068029, 53788301, 28429114, 3432135, 27161203, + 23632036, 31613822, 32808309, 1099883 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 387139307395758, 2058036430315676, 1220915649965325, + 1794832055328951, 1230009312169328 +#else + 15030958, 5768825, 39657628, 30667132, 60681485, 18193060, + 51830967, 26745081, 2051440, 18328567 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1765973779329517, 659344059446977, 19821901606666, + 1301928341311214, 1116266004075885 +#else + 63746541, 26315059, 7517889, 9824992, 23555850, 295369, 5148398, + 19400244, 44422509, 16633659 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1127572801181483, 1224743760571696, 1276219889847274, + 1529738721702581, 1589819666871853 +#else + 4577067, 16802144, 13249840, 18250104, 19958762, 19017158, + 18559669, 22794883, 8402477, 23690159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2181229378964934, 2190885205260020, 1511536077659137, + 1246504208580490, 668883326494241 +#else + 38702534, 32502850, 40318708, 32646733, 49896449, 22523642, + 9453450, 18574360, 17983009, 9967138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 437866655573314, 669026411194768, 81896997980338, + 523874406393178, 245052060935236 +#else + 41346370, 6524721, 26585488, 9969270, 24709298, 1220360, + 65430874, 7806336, 17507396, 3651560 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1975438052228868, 1071801519999806, 594652299224319, + 1877697652668809, 1489635366987285 +#else + 56688388, 29436320, 14584638, 15971087, 51340543, 8861009, + 26556809, 27979875, 48555541, 22197296 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 958592545673770, 233048016518599, 851568750216589, + 567703851596087, 1740300006094761 +#else + 2839082, 14284142, 4029895, 3472686, 14402957, 12689363, + 40466743, 8459446, 61503401, 25932490 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2014540178270324, 192672779514432, 213877182641530, + 2194819933853411, 1716422829364835 +#else + 62269556, 30018987, 9744960, 2871048, 25113978, 3187018, + 41998051, 32705365, 17258083, 25576693 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540769606609725, 2148289943846077, 1597804156127445, + 1230603716683868, 815423458809453 +#else + 18164541, 22959256, 49953981, 32012014, 19237077, 23809137, + 23357532, 18337424, 26908269, 12150756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1738560251245018, 1779576754536888, 1783765347671392, + 1880170990446751, 1088225159617541 +#else + 36843994, 25906566, 5112248, 26517760, 65609056, 26580174, + 43167, 28016731, 34806789, 16215818 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 659303913929492, 1956447718227573, 1830568515922666, + 841069049744408, 1669607124206368 +#else + 60209940, 9824393, 54804085, 29153342, 35711722, 27277596, + 32574488, 12532905, 59605792, 24879084 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143465490433355, 1532194726196059, 1093276745494697, + 481041706116088, 2121405433561163 +#else + 39765323, 17038963, 39957339, 22831480, 946345, 16291093, + 254968, 7168080, 21676107, 31611404 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1686424298744462, 1451806974487153, 266296068846582, + 1834686947542675, 1720762336132256 +#else + 21260942, 25129680, 50276977, 21633609, 43430902, 3968120, + 63456915, 27338965, 63552672, 25641356 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 889217026388959, 1043290623284660, 856125087551909, + 1669272323124636, 1603340330827879 +#else + 16544735, 13250366, 50304436, 15546241, 62525861, 12757257, + 64646556, 24874095, 48201831, 23891632 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1206396181488998, 333158148435054, 1402633492821422, + 1120091191722026, 1945474114550509 +#else + 64693606, 17976703, 18312302, 4964443, 51836334, 20900867, + 26820650, 16690659, 25459437, 28989823 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 766720088232571, 1512222781191002, 1189719893490790, + 2091302129467914, 2141418006894941 +#else + 41964155, 11425019, 28423002, 22533875, 60963942, 17728207, + 9142794, 31162830, 60676445, 31909614 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 419663647306612, 1998875112167987, 1426599870253707, + 1154928355379510, 486538532138187 +#else + 44004212, 6253475, 16964147, 29785560, 41994891, 21257994, + 39651638, 17209773, 6335691, 7249989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938160078005954, 1421776319053174, 1941643234741774, + 180002183320818, 1414380336750546 +#else + 36775618, 13979674, 7503222, 21186118, 55152142, 28932738, + 36836594, 2682241, 25993170, 21075909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 398001940109652, 1577721237663248, 1012748649830402, + 1540516006905144, 1011684812884559 +#else + 4364628, 5930691, 32304656, 23509878, 59054082, 15091130, + 22857016, 22955477, 31820367, 15075278 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1653276489969630, 6081825167624, 1921777941170836, + 1604139841794531, 861211053640641 +#else + 31879134, 24635739, 17258760, 90626, 59067028, 28636722, + 24162787, 23903546, 49138625, 12833044 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996661541407379, 1455877387952927, 744312806857277, + 139213896196746, 1000282908547789 +#else + 19073683, 14851414, 42705695, 21694263, 7625277, 11091125, + 47489674, 2074448, 57694925, 14905376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450817495603008, 1476865707053229, 1030490562252053, + 620966950353376, 1744760161539058 +#else + 24483648, 21618865, 64589997, 22007013, 65555733, 15355505, + 41826784, 9253128, 27628530, 25998952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559728410002599, 37056661641185, 2038622963352006, + 1637244893271723, 1026565352238948 +#else + 17597607, 8340603, 19355617, 552187, 26198470, 30377849, + 4593323, 24396850, 52997988, 15297015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 962165956135846, 1116599660248791, 182090178006815, + 1455605467021751, 196053588803284 +#else + 510886, 14337390, 35323607, 16638631, 6328095, 2713355, + 46891447, 21690211, 8683220, 2921426 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796863823080135, 1897365583584155, 420466939481601, + 2165972651724672, 932177357788289 +#else + 18606791, 11874196, 27155355, 28272950, 43077121, 6265445, + 41930624, 32275507, 4674689, 13890525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877047233620632, 1375632631944375, 643773611882121, + 660022738847877, 19353932331831 +#else + 13609624, 13069022, 39736503, 20498523, 24360585, 9592974, + 14977157, 9835105, 4389687, 288396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2216943882299338, 394841323190322, 2222656898319671, + 558186553950529, 1077236877025190 +#else + 9922506, 33035038, 13613106, 5883594, 48350519, 33120168, + 54804801, 8317627, 23388070, 16052080 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801118384953213, 1914330175515892, 574541023311511, + 1471123787903705, 1526158900256288 +#else + 12719997, 11937594, 35138804, 28525742, 26900119, 8561328, + 46953177, 21921452, 52354592, 22741539 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 949617889087234, 2207116611267331, 912920039141287, + 501158539198789, 62362560771472 +#else + 15961858, 14150409, 26716931, 32888600, 44314535, 13603568, + 11829573, 7467844, 38286736, 929274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1474518386765335, 1760793622169197, 1157399790472736, + 1622864308058898, 165428294422792 +#else + 11038231, 21972036, 39798381, 26237869, 56610336, 17246600, + 43629330, 24182562, 45715720, 2465073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1961673048027128, 102619413083113, 1051982726768458, + 1603657989805485, 1941613251499678 +#else + 20017144, 29231206, 27915241, 1529148, 12396362, 15675764, + 13817261, 23896366, 2463390, 28932292 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1401939116319266, 335306339903072, 72046196085786, + 862423201496006, 850518754531384 +#else + 50749986, 20890520, 55043680, 4996453, 65852442, 1073571, + 9583558, 12851107, 4003896, 12673717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1234706593321979, 1083343891215917, 898273974314935, + 1640859118399498, 157578398571149 +#else + 65377275, 18398561, 63845933, 16143081, 19294135, 13385325, + 14741514, 24450706, 7903885, 2348101 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143483057726416, 1992614991758919, 674268662140796, + 1773370048077526, 674318359920189 +#else + 24536016, 17039225, 12715591, 29692277, 1511292, 10047386, + 63266518, 26425272, 38731325, 10048126 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1835401379538542, 173900035308392, 818247630716732, + 1762100412152786, 1021506399448291 +#else + 54486638, 27349611, 30718824, 2591312, 56491836, 12192839, + 18873298, 26257342, 34811107, 15221631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1506632088156630, 2127481795522179, 513812919490255, + 140643715928370, 442476620300318 +#else + 40630742, 22450567, 11546243, 31701949, 9180879, 7656409, + 45764914, 2095754, 29769758, 6593415 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2056683376856736, 219094741662735, 2193541883188309, + 1841182310235800, 556477468664293 +#else + 35114656, 30646970, 4176911, 3264766, 12538965, 32686321, + 26312344, 27435754, 30958053, 8292160 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315019427910827, 1049075855992603, 2066573052986543, + 266904467185534, 2040482348591520 +#else + 31429803, 19595316, 29173531, 15632448, 12174511, 30794338, + 32808830, 3977186, 26143136, 30405556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94096246544434, 922482381166992, 24517828745563, + 2139430508542503, 2097139044231004 +#else + 22648882, 1402143, 44308880, 13746058, 7936347, 365344, + 58440231, 31879998, 63350620, 31249806 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 537697207950515, 1399352016347350, 1563663552106345, + 2148749520888918, 549922092988516 +#else + 51616947, 8012312, 64594134, 20851969, 43143017, 23300402, + 65496150, 32018862, 50444388, 8194477 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1747985413252434, 680511052635695, 1809559829982725, + 594274250930054, 201673170745982 +#else + 27338066, 26047012, 59694639, 10140404, 48082437, 26964542, + 27277190, 8855376, 28572286, 3005164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 323583936109569, 1973572998577657, 1192219029966558, + 79354804385273, 1374043025560347 +#else + 26287105, 4821776, 25476601, 29408529, 63344350, 17765447, + 49100281, 1182478, 41014043, 20474836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213277331329947, 416202017849623, 1950535221091783, + 1313441578103244, 2171386783823658 +#else + 59937691, 3178079, 23970071, 6201893, 49913287, 29065239, + 45232588, 19571804, 32208682, 32356184 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 189088804229831, 993969372859110, 895870121536987, + 1547301535298256, 1477373024911350 +#else + 50451143, 2817642, 56822502, 14811297, 6024667, 13349505, + 39793360, 23056589, 39436278, 22014573 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1620578418245010, 541035331188469, 2235785724453865, + 2154865809088198, 1974627268751826 +#else + 15941010, 24148500, 45741813, 8062054, 31876073, 33315803, + 51830470, 32110002, 15397330, 29424239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346805451740245, 1350981335690626, 942744349501813, + 2155094562545502, 1012483751693409 +#else + 8934485, 20068965, 43822466, 20131190, 34662773, 14047985, + 31170398, 32113411, 39603297, 15087183 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2107080134091762, 1132567062788208, 1824935377687210, + 769194804343737, 1857941799971888 +#else + 48751602, 31397940, 24524912, 16876564, 15520426, 27193656, + 51606457, 11461895, 16788528, 27685490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1074666112436467, 249279386739593, 1174337926625354, + 1559013532006480, 1472287775519121 +#else + 65161459, 16013772, 21750665, 3714552, 49707082, 17498998, + 63338576, 23231111, 31322513, 21938797 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1872620123779532, 1892932666768992, 1921559078394978, + 1270573311796160, 1438913646755037 +#else + 21426636, 27904214, 53460576, 28206894, 38296674, 28633461, + 48833472, 18933017, 13040861, 21441484 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 837390187648199, 1012253300223599, 989780015893987, + 1351393287739814, 328627746545550 +#else + 11293895, 12478086, 39972463, 15083749, 37801443, 14748871, + 14555558, 20137329, 1613710, 4896935 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1028328827183114, 1711043289969857, 1350832470374933, + 1923164689604327, 1495656368846911 +#else + 41213962, 15323293, 58619073, 25496531, 25967125, 20128972, + 2825959, 28657387, 43137087, 22287016 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1900828492104143, 430212361082163, 687437570852799, + 832514536673512, 1685641495940794 +#else + 51184079, 28324551, 49665331, 6410663, 3622847, 10243618, + 20615400, 12405433, 43355834, 25118015 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 842632847936398, 605670026766216, 290836444839585, + 163210774892356, 2213815011799645 +#else + 60017550, 12556207, 46917512, 9025186, 50036385, 4333800, + 4378436, 2432030, 23097949, 32988414 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1176336383453996, 1725477294339771, 12700622672454, + 678015708818208, 162724078519879 +#else + 4565804, 17528778, 20084411, 25711615, 1724998, 189254, + 24767264, 10103221, 48596551, 2424777 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1448049969043497, 1789411762943521, 385587766217753, + 90201620913498, 832999441066823 +#else + 366633, 21577626, 8173089, 26664313, 30788633, 5745705, + 59940186, 1344108, 63466311, 12412658 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 516086333293313, 2240508292484616, 1351669528166508, + 1223255565316488, 750235824427138 +#else + 43107073, 7690285, 14929416, 33386175, 34898028, 20141445, + 24162696, 18227928, 63967362, 11179384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1263624896582495, 1102602401673328, 526302183714372, + 2152015839128799, 1483839308490010 +#else + 18289503, 18829478, 8056944, 16430056, 45379140, 7842513, + 61107423, 32067534, 48424218, 22110928 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 442991718646863, 1599275157036458, 1925389027579192, + 899514691371390, 350263251085160 +#else + 476239, 6601091, 60956074, 23831056, 17503544, 28690532, + 27672958, 13403813, 11052904, 5219329 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1689713572022143, 593854559254373, 978095044791970, + 1985127338729499, 1676069120347625 +#else + 20678527, 25178694, 34436965, 8849122, 62099106, 14574751, + 31186971, 29580702, 9014761, 24975376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1557207018622683, 340631692799603, 1477725909476187, + 614735951619419, 2033237123746766 +#else + 53464795, 23204192, 51146355, 5075807, 65594203, 22019831, + 34006363, 9160279, 8473550, 30297594 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 968764929340557, 1225534776710944, 662967304013036, + 1155521416178595, 791142883466590 +#else + 24900749, 14435722, 17209120, 18261891, 44516588, 9878982, + 59419555, 17218610, 42540382, 11788947 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1487081286167458, 993039441814934, 1792378982844640, + 698652444999874, 2153908693179754 +#else + 63990690, 22159237, 53306774, 14797440, 9652448, 26708528, + 47071426, 10410732, 42540394, 32095740 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1123181311102823, 685575944875442, 507605465509927, + 1412590462117473, 568017325228626 +#else + 51449703, 16736705, 44641714, 10215877, 58011687, 7563910, + 11871841, 21049238, 48595538, 8464117 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 560258797465417, 2193971151466401, 1824086900849026, + 579056363542056, 1690063960036441 +#else + 43708233, 8348506, 52522913, 32692717, 63158658, 27181012, + 14325288, 8628612, 33313881, 25183915 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1918407319222416, 353767553059963, 1930426334528099, + 1564816146005724, 1861342381708096 +#else + 46921872, 28586496, 22367355, 5271547, 66011747, 28765593, + 42303196, 23317577, 58168128, 27736162 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2131325168777276, 1176636658428908, 1756922641512981, + 1390243617176012, 1966325177038383 +#else + 60160060, 31759219, 34483180, 17533252, 32635413, 26180187, + 15989196, 20716244, 28358191, 29300528 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2063958120364491, 2140267332393533, 699896251574968, + 273268351312140, 375580724713232 +#else + 43547083, 30755372, 34757181, 31892468, 57961144, 10429266, + 50471180, 4072015, 61757200, 5596588 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024297515263178, 416959329722687, 1079014235017302, + 171612225573183, 1031677520051053 +#else + 38872266, 30164383, 12312895, 6213178, 3117142, 16078565, + 29266239, 2557221, 1768301, 15373193 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2033900009388450, 1744902869870788, 2190580087917640, + 1949474984254121, 231049754293748 +#else + 59865506, 30307471, 62515396, 26001078, 66980936, 32642186, + 66017961, 29049440, 42448372, 3442909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343868674606581, 550155864008088, 1450580864229630, + 481603765195050, 896972360018042 +#else + 36898293, 5124042, 14181784, 8197961, 18964734, 21615339, + 22597930, 7176455, 48523386, 13365929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151139328380127, 314745882084928, 59756825775204, + 1676664391494651, 2048348075599360 +#else + 59231455, 32054473, 8324672, 4690079, 6261860, 890446, 24538107, + 24984246, 57419264, 30522764 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528930066340597, 1605003907059576, 1055061081337675, + 1458319101947665, 1234195845213142 +#else + 25008885, 22782833, 62803832, 23916421, 16265035, 15721635, + 683793, 21730648, 15723478, 18390951 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830430507734812, 1780282976102377, 1425386760709037, + 362399353095425, 2168861579799910 +#else + 57448220, 12374378, 40101865, 26528283, 59384749, 21239917, + 11879681, 5400171, 519526, 32318556 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1155762232730333, 980662895504006, 2053766700883521, + 490966214077606, 510405877041357 +#else + 22258397, 17222199, 59239046, 14613015, 44588609, 30603508, + 46754982, 7315966, 16648397, 7605640 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1683750316716132, 652278688286128, 1221798761193539, + 1897360681476669, 319658166027343 +#else + 59027556, 25089834, 58885552, 9719709, 19259459, 18206220, + 23994941, 28272877, 57640015, 4763277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 618808732869972, 72755186759744, 2060379135624181, + 1730731526741822, 48862757828238 +#else + 45409620, 9220968, 51378240, 1084136, 41632757, 30702041, + 31088446, 25789909, 55752334, 728111 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1463171970593505, 1143040711767452, 614590986558883, + 1409210575145591, 1882816996436803 +#else + 26047201, 21802961, 60208540, 17032633, 24092067, 9158119, + 62835319, 20998873, 37743427, 28056159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230133264691131, 563950955091024, 2042915975426398, + 827314356293472, 672028980152815 +#else + 17510331, 33231575, 5854288, 8403524, 17133918, 30441820, + 38997856, 12327944, 10750447, 10014012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 264204366029760, 1654686424479449, 2185050199932931, + 2207056159091748, 506015669043634 +#else + 56796096, 3936951, 9156313, 24656749, 16498691, 32559785, + 39627812, 32887699, 3424690, 7540221 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784446333136569, 1973746527984364, 334856327359575, + 1156769775884610, 1023950124675478 +#else + 30322361, 26590322, 11361004, 29411115, 7433303, 4989748, + 60037442, 17237212, 57864598, 15258045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2065270940578383, 31477096270353, 306421879113491, + 181958643936686, 1907105536686083 +#else + 13054543, 30774935, 19155473, 469045, 54626067, 4566041, + 5631406, 2711395, 1062915, 28418087 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1496516440779464, 1748485652986458, 872778352227340, + 818358834654919, 97932669284220 +#else + 47868616, 22299832, 37599834, 26054466, 61273100, 13005410, + 61042375, 12194496, 32960380, 1459310 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 471636015770351, 672455402793577, 1804995246884103, + 1842309243470804, 1501862504981682 +#else + 19852015, 7027924, 23669353, 10020366, 8586503, 26896525, + 394196, 27452547, 18638002, 22379495 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1013216974933691, 538921919682598, 1915776722521558, + 1742822441583877, 1886550687916656 +#else + 31395515, 15098109, 26581030, 8030562, 50580950, 28547297, + 9012485, 25970078, 60465776, 28111795 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2094270000643336, 303971879192276, 40801275554748, + 649448917027930, 1818544418535447 +#else + 57916680, 31207054, 65111764, 4529533, 25766844, 607986, + 67095642, 9677542, 34813975, 27098423 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2241737709499165, 549397817447461, 838180519319392, + 1725686958520781, 1705639080897747 +#else + 64664349, 33404494, 29348901, 8186665, 1873760, 12489863, + 36174285, 25714739, 59256019, 25416002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1216074541925116, 50120933933509, 1565829004133810, + 721728156134580, 349206064666188 +#else + 51872508, 18120922, 7766469, 746860, 26346930, 23332670, + 39775412, 10754587, 57677388, 5203575 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 948617110470858, 346222547451945, 1126511960599975, + 1759386906004538, 493053284802266 +#else + 31834314, 14135496, 66338857, 5159117, 20917671, 16786336, + 59640890, 26216907, 31809242, 7347066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1454933046815146, 874696014266362, 1467170975468588, + 1432316382418897, 2111710746366763 +#else + 57502122, 21680191, 20414458, 13033986, 13716524, 21862551, + 19797969, 21343177, 15192875, 31466942 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2105387117364450, 1996463405126433, 1303008614294500, + 851908115948209, 1353742049788635 +#else + 54445282, 31372712, 1168161, 29749623, 26747876, 19416341, + 10609329, 12694420, 33473243, 20172328 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 750300956351719, 1487736556065813, 15158817002104, + 1511998221598392, 971739901354129 +#else + 33184999, 11180355, 15832085, 22169002, 65475192, 225883, + 15089336, 22530529, 60973201, 14480052 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1874648163531693, 2124487685930551, 1810030029384882, + 918400043048335, 586348627300650 +#else + 31308717, 27934434, 31030839, 31657333, 15674546, 26971549, + 5496207, 13685227, 27595050, 8737275 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1235084464747900, 1166111146432082, 1745394857881591, + 1405516473883040, 4463504151617 +#else + 46790012, 18404192, 10933842, 17376410, 8335351, 26008410, + 36100512, 20943827, 26498113, 66511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1663810156463827, 327797390285791, 1341846161759410, + 1964121122800605, 1747470312055380 +#else + 22644435, 24792703, 50437087, 4884561, 64003250, 19995065, + 30540765, 29267685, 53781076, 26039336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 660005247548233, 2071860029952887, 1358748199950107, + 911703252219107, 1014379923023831 +#else + 39091017, 9834844, 18617207, 30873120, 63706907, 20246925, + 8205539, 13585437, 49981399, 15115438 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2206641276178231, 1690587809721504, 1600173622825126, + 2156096097634421, 1106822408548216 +#else + 23711543, 32881517, 31206560, 25191721, 6164646, 23844445, + 33572981, 32128335, 8236920, 16492939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344788193552206, 1949552134239140, 1735915881729557, + 675891104100469, 1834220014427292 +#else + 43198286, 20038905, 40809380, 29050590, 25005589, 25867162, + 19574901, 10071562, 6708380, 27332008 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1920949492387964, 158885288387530, 70308263664033, + 626038464897817, 1468081726101009 +#else + 2101372, 28624378, 19702730, 2367575, 51681697, 1047674, + 5301017, 9328700, 29955601, 21876122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622221042073383, 1210146474039168, 1742246422343683, + 1403839361379025, 417189490895736 +#else + 3096359, 9271816, 45488000, 18032587, 52260867, 25961494, + 41216721, 20918836, 57191288, 6216607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22727256592983, 168471543384997, 1324340989803650, + 1839310709638189, 504999476432775 +#else + 34493015, 338662, 41913253, 2510421, 37895298, 19734218, + 24822829, 27407865, 40341383, 7525078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1313240518756327, 1721896294296942, 52263574587266, + 2065069734239232, 804910473424630 +#else + 44042215, 19568808, 16133486, 25658254, 63719298, 778787, + 66198528, 30771936, 47722230, 11994100 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1337466662091884, 1287645354669772, 2018019646776184, + 652181229374245, 898011753211715 +#else + 21691500, 19929806, 66467532, 19187410, 3285880, 30070836, + 42044197, 9718257, 59631427, 13381417 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969792547910734, 779969968247557, 2011350094423418, + 1823964252907487, 1058949448296945 +#else + 18445390, 29352196, 14979845, 11622458, 65381754, 29971451, + 23111647, 27179185, 28535281, 15779576 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207343737062002, 1118176942430253, 758894594548164, + 806764629546266, 1157700123092949 +#else + 30098034, 3089662, 57874477, 16662134, 45801924, 11308410, + 53040410, 12021729, 9955285, 17251076 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1273565321399022, 1638509681964574, 759235866488935, + 666015124346707, 897983460943405 +#else + 9734894, 18977602, 59635230, 24415696, 2060391, 11313496, + 48682835, 9924398, 20194861, 13380996 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717263794012298, 1059601762860786, 1837819172257618, + 1054130665797229, 680893204263559 +#else + 40730762, 25589224, 44941042, 15789296, 49053522, 27385639, + 65123949, 15707770, 26342023, 10146099 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2237039662793603, 2249022333361206, 2058613546633703, + 149454094845279, 2215176649164582 +#else + 41091971, 33334488, 21339190, 33513044, 19745255, 30675732, + 37471583, 2227039, 21612326, 33008704 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 79472182719605, 1851130257050174, 1825744808933107, + 821667333481068, 781795293511946 +#else + 54031477, 1184227, 23562814, 27583990, 46757619, 27205717, + 25764460, 12243797, 46252298, 11649657 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755822026485370, 152464789723500, 1178207602290608, + 410307889503239, 156581253571278 +#else + 57077370, 11262625, 27384172, 2271902, 26947504, 17556661, + 39943, 6114064, 33514190, 2333242 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1418185496130297, 484520167728613, 1646737281442950, + 1401487684670265, 1349185550126961 +#else + 45675257, 21132610, 8119781, 7219913, 45278342, 24538297, + 60429113, 20883793, 24350577, 20104431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495380034400429, 325049476417173, 46346894893933, + 1553408840354856, 828980101835683 +#else + 62992557, 22282898, 43222677, 4843614, 37020525, 690622, + 35572776, 23147595, 8317859, 12352766 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1280337889310282, 2070832742866672, 1640940617225222, + 2098284908289951, 450929509534434 +#else + 18200138, 19078521, 34021104, 30857812, 43406342, 24451920, + 43556767, 31266881, 20712162, 6719373 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 407703353998781, 126572141483652, 286039827513621, + 1999255076709338, 2030511179441770 +#else + 26656189, 6075253, 59250308, 1886071, 38764821, 4262325, + 11117530, 29791222, 26224234, 30256974 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254958221100483, 1153235960999843, 942907704968834, + 637105404087392, 1149293270147267 +#else + 49939907, 18700334, 63713187, 17184554, 47154818, 14050419, + 21728352, 9493610, 18620611, 17125804 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894249020470196, 400291701616810, 406878712230981, + 1599128793487393, 1145868722604026 +#else + 53785524, 13325348, 11432106, 5964811, 18609221, 6062965, + 61839393, 23828875, 36407290, 17074774 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497955250203334, 110116344653260, 1128535642171976, + 1900106496009660, 129792717460909 +#else + 43248326, 22321272, 26961356, 1640861, 34695752, 16816491, + 12248508, 28313793, 13735341, 1934062 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 452487513298665, 1352120549024569, 1173495883910956, + 1999111705922009, 367328130454226 +#else + 25089769, 6742589, 17081145, 20148166, 21909292, 17486451, + 51972569, 29789085, 45830866, 5473615 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717539401269642, 1475188995688487, 891921989653942, + 836824441505699, 1885988485608364 +#else + 31883658, 25593331, 1083431, 21982029, 22828470, 13290673, + 59983779, 12469655, 29111212, 28103418 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1241784121422547, 187337051947583, 1118481812236193, + 428747751936362, 30358898927325 +#else + 24244947, 18504025, 40845887, 2791539, 52111265, 16666677, + 24367466, 6388839, 56813277, 452382 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022432361201842, 1088816090685051, 1977843398539868, + 1854834215890724, 564238862029357 +#else + 41468082, 30136590, 5217915, 16224624, 19987036, 29472163, + 42872612, 27639183, 15766061, 8407814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938868489100585, 1100285072929025, 1017806255688848, + 1957262154788833, 152787950560442 +#else + 46701865, 13990230, 15495425, 16395525, 5377168, 15166495, + 58191841, 29165478, 59040954, 2276717 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 867319417678923, 620471962942542, 226032203305716, + 342001443957629, 1761675818237336 +#else + 30157899, 12924066, 49396814, 9245752, 19895028, 3368142, + 43281277, 5096218, 22740376, 26251015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295072362439987, 931227904689414, 1355731432641687, + 922235735834035, 892227229410209 +#else + 2041139, 19298082, 7783686, 13876377, 41161879, 20201972, + 24051123, 13742383, 51471265, 13295221 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1680989767906154, 535362787031440, 2136691276706570, + 1942228485381244, 1267350086882274 +#else + 33338218, 25048699, 12532112, 7977527, 9106186, 31839181, + 49388668, 28941459, 62657506, 18884987 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366018233770527, 432660629755596, 126409707644535, + 1973842949591662, 645627343442376 +#else + 47063583, 5454096, 52762316, 6447145, 28862071, 1883651, + 64639598, 29412551, 7770568, 9620597 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 535509430575217, 546885533737322, 1524675609547799, + 2138095752851703, 1260738089896827 +#else + 23208049, 7979712, 33071466, 8149229, 1758231, 22719437, + 30945527, 31860109, 33606523, 18786461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1159906385590467, 2198530004321610, 714559485023225, + 81880727882151, 1484020820037082 +#else + 1439939, 17283952, 66028874, 32760649, 4625401, 10647766, + 62065063, 1220117, 30494170, 22113633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1377485731340769, 2046328105512000, 1802058637158797, + 62146136768173, 1356993908853901 +#else + 62071265, 20526136, 64138304, 30492664, 15640973, 26852766, + 40369837, 926049, 65424525, 20220784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013612215646735, 1830770575920375, 536135310219832, + 609272325580394, 270684344495013 +#else + 13908495, 30005160, 30919927, 27280607, 45587000, 7989038, + 9021034, 9078865, 3353509, 4033511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1237542585982777, 2228682050256790, 1385281931622824, + 593183794882890, 493654978552689 +#else + 37445433, 18440821, 32259990, 33209950, 24295848, 20642309, + 23161162, 8839127, 27485041, 7356032 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47341488007760, 1891414891220257, 983894663308928, + 176161768286818, 1126261115179708 +#else + 9661008, 705443, 11980065, 28184278, 65480320, 14661172, + 60762722, 2625014, 28431036, 16782598 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694030170963455, 502038567066200, 1691160065225467, + 949628319562187, 275110186693066 +#else + 43269631, 25243016, 41163352, 7480957, 49427195, 25200248, + 44562891, 14150564, 15970762, 4099461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1124515748676336, 1661673816593408, 1499640319059718, + 1584929449166988, 558148594103306 +#else + 29262576, 16756590, 26350592, 24760869, 8529670, 22346382, + 13617292, 23617289, 11465738, 8317062 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784525599998356, 1619698033617383, 2097300287550715, + 258265458103756, 1905684794832758 +#else + 41615764, 26591503, 32500199, 24135381, 44070139, 31252209, + 14898636, 3848455, 20969334, 28396916 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288941072872766, 931787902039402, 190731008859042, + 2006859954667190, 1005931482221702 +#else + 46724414, 19206718, 48772458, 13884721, 34069410, 2842113, + 45498038, 29904543, 11177094, 14989547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1465551264822703, 152905080555927, 680334307368453, + 173227184634745, 666407097159852 +#else + 42612143, 21838415, 16959895, 2278463, 12066309, 10137771, + 13515641, 2581286, 38621356, 9930239 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2111017076203943, 1378760485794347, 1248583954016456, + 1352289194864422, 1895180776543896 +#else + 49357223, 31456605, 16544299, 20545132, 51194056, 18605350, + 18345766, 20150679, 16291480, 28240394 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 171348223915638, 662766099800389, 462338943760497, + 466917763340314, 656911292869115 +#else + 33879670, 2553287, 32678213, 9875984, 8534129, 6889387, + 57432090, 6957616, 4368891, 9788741 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 488623681976577, 866497561541722, 1708105560937768, + 1673781214218839, 1506146329818807 +#else + 16660737, 7281060, 56278106, 12911819, 20108584, 25452756, + 45386327, 24941283, 16250551, 22443329 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160425464456957, 950394373239689, 430497123340934, + 711676555398832, 320964687779005 +#else + 47343357, 2390525, 50557833, 14161979, 1905286, 6414907, + 4689584, 10604807, 36918461, 4782746 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 988979367990485, 1359729327576302, 1301834257246029, + 294141160829308, 29348272277475 +#else + 65754325, 14736940, 59741422, 20261545, 7710541, 19398842, + 57127292, 4383044, 22546403, 437323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1434382743317910, 100082049942065, 221102347892623, + 186982837860588, 1305765053501834 +#else + 31665558, 21373968, 50922033, 1491338, 48740239, 3294681, + 27343084, 2786261, 36475274, 19457415 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2205916462268190, 499863829790820, 961960554686616, + 158062762756985, 1841471168298305 +#else + 52641566, 32870716, 33734756, 7448551, 19294360, 14334329, + 47418233, 2355318, 47824193, 27440058 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191737341426592, 1847042034978363, 1382213545049056, + 1039952395710448, 788812858896859 +#else + 15121312, 17758270, 6377019, 27523071, 56310752, 20596586, + 18952176, 15496498, 37728731, 11754227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346965964571152, 1291881610839830, 2142916164336056, + 786821641205979, 1571709146321039 +#else + 64471568, 20071356, 8488726, 19250536, 12728760, 31931939, + 7141595, 11724556, 22761615, 23420291 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 787164375951248, 202869205373189, 1356590421032140, + 1431233331032510, 786341368775957 +#else + 16918416, 11729663, 49025285, 3022986, 36093132, 20214772, + 38367678, 21327038, 32851221, 11717399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 492448143532951, 304105152670757, 1761767168301056, + 233782684697790, 1981295323106089 +#else + 11166615, 7338049, 60386341, 4531519, 37640192, 26252376, + 31474878, 3483633, 65915689, 29523600 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665807507761866, 1343384868355425, 895831046139653, + 439338948736892, 1986828765695105 +#else + 66923210, 9921304, 31456609, 20017994, 55095045, 13348922, + 33142652, 6546660, 47123585, 29606055 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756096210874553, 1721699973539149, 258765301727885, + 1390588532210645, 1212530909934781 +#else + 34648249, 11266711, 55911757, 25655328, 31703693, 3855903, + 58571733, 20721383, 36336829, 18068118 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 852891097972275, 1816988871354562, 1543772755726524, + 1174710635522444, 202129090724628 +#else + 49102387, 12709067, 3991746, 27075244, 45617340, 23004006, + 35973516, 17504552, 10928916, 3011958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1205281565824323, 22430498399418, 992947814485516, + 1392458699738672, 688441466734558 +#else + 60151107, 17960094, 31696058, 334240, 29576716, 14796075, + 36277808, 20749251, 18008030, 10258577 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1050627428414972, 1955849529137135, 2171162376368357, + 91745868298214, 447733118757826 +#else + 44660220, 15655568, 7018479, 29144429, 36794597, 32352840, + 65255398, 1367119, 25127874, 6671743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287181461435438, 622722465530711, 880952150571872, + 741035693459198, 311565274989772 +#else + 29701166, 19180498, 56230743, 9279287, 67091296, 13127209, + 21382910, 11042292, 25838796, 4642684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1003649078149734, 545233927396469, 1849786171789880, + 1318943684880434, 280345687170552 +#else + 46678630, 14955536, 42982517, 8124618, 61739576, 27563961, + 30468146, 19653792, 18423288, 4177476 +#endif + }}, + }, + }, +}; + +#endif // OPENSSL_SMALL + +// Bi[i] = (2*i+1)*B +static const ge_precomp Bi[8] = { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, 27544626, + 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, 338455783676468, + 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, 12720692, + 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, 29287918, + 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, 27787599, + 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, 16354576, + 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, 7512774, + 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, 974092374476333, + 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, 32867885, + 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, 837766094556764, + 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, 41455196, + 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, 28542349, + 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, 350988370788628, + 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, 19480852, + 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, 91986625355052, + 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, 35708204, + 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1802695059465007, 1664899123557221, 593559490740857, + 2160434469266659, 927570450755031 +#else + 44589871, 26862249, 14201701, 24808930, 43598457, 8844725, 18474211, + 32192982, 54046167, 13821876 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1725674970513508, 1933645953859181, 1542344539275782, + 1767788773573747, 1297447965928905 +#else + 60653668, 25714560, 3374701, 28813570, 40010246, 22982724, 31655027, + 26342105, 18853321, 19333481 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1381809363726107, 1430341051343062, 2061843536018959, + 1551778050872521, 2036394857967624 +#else + 4566811, 20590564, 38133974, 21313742, 59506191, 30723862, 58594505, + 23123294, 2207752, 30344648 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1970894096313054, 528066325833207, 1619374932191227, + 2207306624415883, 1169170329061080 +#else + 41954014, 29368610, 29681143, 7868801, 60254203, 24130566, 54671499, + 32891431, 35997400, 17421995 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2070390218572616, 1458919061857835, 624171843017421, + 1055332792707765, 433987520732508 +#else + 25576264, 30851218, 7349803, 21739588, 16472781, 9300885, 3844789, + 15725684, 171356, 6466918 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893653801273833, 1168026499324677, 1242553501121234, + 1306366254304474, 1086752658510815 +#else + 23103977, 13316479, 9739013, 17404951, 817874, 18515490, 8965338, + 19466374, 36393951, 16193876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213454002618221, 939771523987438, 1159882208056014, 317388369627517, + 621213314200687 +#else + 33587053, 3180712, 64714734, 14003686, 50205390, 17283591, 17238397, + 4729455, 49034351, 9256799 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971678598905747, 338026507889165, 762398079972271, 655096486107477, + 42299032696322 +#else + 41926547, 29380300, 32336397, 5036987, 45872047, 11360616, 22616405, + 9761698, 47281666, 630304 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 177130678690680, 1754759263300204, 1864311296286618, + 1180675631479880, 1292726903152791 +#else + 53388152, 2639452, 42871404, 26147950, 9494426, 27780403, 60554312, + 17593437, 64659607, 19263131 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1913163449625248, 460779200291993, 2193883288642314, + 1008900146920800, 1721983679009502 +#else + 63957664, 28508356, 9282713, 6866145, 35201802, 32691408, 48168288, + 15033783, 25105118, 25659556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1070401523076875, 1272492007800961, 1910153608563310, + 2075579521696771, 1191169788841221 +#else + 42782475, 15950225, 35307649, 18961608, 55446126, 28463506, 1573891, + 30928545, 2198789, 17749813 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692896803108118, 500174642072499, 2068223309439677, + 1162190621851337, 1426986007309901 +#else + 64009494, 10324966, 64867251, 7453182, 61661885, 30818928, 53296841, + 17317989, 34647629, 21263748 +#endif + }}, + }, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/internal.h new file mode 100644 index 00000000..95183689 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/internal.h @@ -0,0 +1,146 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H +#define OPENSSL_HEADER_CURVE25519_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +#include "../internal.h" + + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define BORINGSSL_X25519_NEON + +// x25519_NEON is defined in asm/x25519-arm.S. +void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +#endif + +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_CURVE25519_64BIT +#endif + +#if defined(BORINGSSL_CURVE25519_64BIT) +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[4], represents the integer t[0]+2^51 t[1]+2^102 t[2]+2^153 +// t[3]+2^204 t[4]. +// fe limbs are bounded by 1.125*2^51. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint64_t v[5]; } fe; + +// fe_loose limbs are bounded by 3.375*2^51. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint64_t v[5]; } fe_loose; +#else +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. +// fe limbs are bounded by 1.125*2^26,1.125*2^25,1.125*2^26,1.125*2^25,etc. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint32_t v[10]; } fe; + +// fe_loose limbs are bounded by 3.375*2^26,3.375*2^25,3.375*2^26,3.375*2^25,etc. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint32_t v[10]; } fe_loose; +#endif + +// ge means group element. +// +// Here the group is the set of pairs (x,y) of field elements (see fe.h) +// satisfying -x^2 + y^2 = 1 + d x^2y^2 +// where d = -121665/121666. +// +// Representations: +// ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z +// ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +// ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +// ge_precomp (Duif): (y+x,y-x,2dxy) + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe_loose X; + fe_loose Y; + fe_loose Z; + fe_loose T; +} ge_p1p1; + +typedef struct { + fe_loose yplusx; + fe_loose yminusx; + fe_loose xy2d; +} ge_precomp; + +typedef struct { + fe_loose YplusX; + fe_loose YminusX; + fe_loose Z; + fe_loose T2d; +} ge_cached; + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h); +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t s[32]); +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p); +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]); +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]); +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A); +void x25519_sc_reduce(uint8_t s[64]); + +enum spake2_state_t { + spake2_state_init = 0, + spake2_state_msg_generated, + spake2_state_key_generated, +}; + +struct spake2_ctx_st { + uint8_t private_key[32]; + uint8_t my_msg[32]; + uint8_t password_scalar[32]; + uint8_t password_hash[64]; + uint8_t *my_name; + size_t my_name_len; + uint8_t *their_name; + size_t their_name_len; + enum spake2_role_t my_role; + enum spake2_state_t state; + char disable_password_scalar_hack; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CURVE25519_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/spake25519.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/spake25519.c new file mode 100644 index 00000000..d7de55b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/curve25519/spake25519.c @@ -0,0 +1,539 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +// The following precomputation tables are for the following +// points used in the SPAKE2 protocol. +// +// N: +// x: 49918732221787544735331783592030787422991506689877079631459872391322455579424 +// y: 54629554431565467720832445949441049581317094546788069926228343916274969994000 +// encoded: 10e3df0ae37d8e7a99b5fe74b44672103dbddcbd06af680d71329a11693bc778 +// +// M: +// x: 31406539342727633121250288103050113562375374900226415211311216773867585644232 +// y: 21177308356423958466833845032658859666296341766942662650232962324899758529114 +// encoded: 5ada7e4bf6ddd9adb6626d32131c6b5c51a1e347a3478f53cfcf441b88eed12e +// +// These points and their precomputation tables are generated with the +// following Python code. For a description of the precomputation table, +// see curve25519.c in this directory. +// +// Exact copies of the source code are kept in bug 27296743. + +/* +import hashlib +import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py + +SEED_N = 'edwards25519 point generation seed (N)' +SEED_M = 'edwards25519 point generation seed (M)' + +def genpoint(seed): + v = hashlib.sha256(seed).digest() + it = 1 + while True: + try: + x,y = E.decodepoint(v) + except Exception, e: + print e + it += 1 + v = hashlib.sha256(v).digest() + continue + print "Found in %d iterations:" % it + print " x = %d" % x + print " y = %d" % y + print " Encoded (hex)" + print E.encodepoint((x,y)).encode('hex') + return (x,y) + +def gentable(P): + t = [] + for i in range(1,16): + k = ((i >> 3 & 1) * (1 << 192) + + (i >> 2 & 1) * (1 << 128) + + (i >> 1 & 1) * (1 << 64) + + (i & 1)) + t.append(E.scalarmult(P, k)) + return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t) + +def printtable(table, name): + print "static const uint8_t %s[15 * 2 * 32] = {" % name, + for i in range(15 * 2 * 32): + if i % 12 == 0: + print "\n ", + print " 0x%02x," % ord(table[i]), + print "\n};" + +if __name__ == "__main__": + print "Searching for N" + N = genpoint(SEED_N) + print "Generating precomputation table for N" + Ntable = gentable(N) + printtable(Ntable, "kSpakeNSmallPrecomp") + + print "Searching for M" + M = genpoint(SEED_M) + print "Generating precomputation table for M" + Mtable = gentable(M) + printtable(Mtable, "kSpakeMSmallPrecomp") +*/ + +static const uint8_t kSpakeNSmallPrecomp[15 * 2 * 32] = { + 0x20, 0x1b, 0xc5, 0xb3, 0x43, 0x17, 0x71, 0x10, 0x44, 0x1e, 0x73, 0xb3, + 0xae, 0x3f, 0xbf, 0x9f, 0xf5, 0x44, 0xc8, 0x13, 0x8f, 0xd1, 0x01, 0xc2, + 0x8a, 0x1a, 0x6d, 0xea, 0x4d, 0x00, 0x5d, 0x6e, 0x10, 0xe3, 0xdf, 0x0a, + 0xe3, 0x7d, 0x8e, 0x7a, 0x99, 0xb5, 0xfe, 0x74, 0xb4, 0x46, 0x72, 0x10, + 0x3d, 0xbd, 0xdc, 0xbd, 0x06, 0xaf, 0x68, 0x0d, 0x71, 0x32, 0x9a, 0x11, + 0x69, 0x3b, 0xc7, 0x78, 0x93, 0xf1, 0x57, 0x97, 0x6e, 0xf0, 0x6e, 0x45, + 0x37, 0x4a, 0xf4, 0x0b, 0x18, 0x51, 0xf5, 0x4f, 0x67, 0x3c, 0xdc, 0xec, + 0x84, 0xed, 0xd0, 0xeb, 0xca, 0xfb, 0xdb, 0xff, 0x7f, 0xeb, 0xa8, 0x23, + 0x68, 0x87, 0x13, 0x64, 0x6a, 0x10, 0xf7, 0x45, 0xe0, 0x0f, 0x32, 0x21, + 0x59, 0x7c, 0x0e, 0x50, 0xad, 0x56, 0xd7, 0x12, 0x69, 0x7b, 0x58, 0xf8, + 0xb9, 0x3b, 0xa5, 0xbb, 0x4d, 0x1b, 0x87, 0x1c, 0x46, 0xa7, 0x17, 0x9d, + 0x6d, 0x84, 0x45, 0xbe, 0x7f, 0x95, 0xd2, 0x34, 0xcd, 0x89, 0x95, 0xc0, + 0xf0, 0xd3, 0xdf, 0x6e, 0x10, 0x4a, 0xe3, 0x7b, 0xce, 0x7f, 0x40, 0x27, + 0xc7, 0x2b, 0xab, 0x66, 0x03, 0x59, 0xb4, 0x7b, 0xc7, 0xc7, 0xf0, 0x39, + 0x9a, 0x33, 0x35, 0xbf, 0xcc, 0x2f, 0xf3, 0x2e, 0x68, 0x9d, 0x53, 0x5c, + 0x88, 0x52, 0xe3, 0x77, 0x90, 0xa1, 0x27, 0x85, 0xc5, 0x74, 0x7f, 0x23, + 0x0e, 0x93, 0x01, 0x3e, 0xe7, 0x2e, 0x2e, 0x95, 0xf3, 0x0d, 0xc2, 0x25, + 0x25, 0x39, 0x39, 0x3d, 0x6e, 0x8e, 0x89, 0xbd, 0xe8, 0xbb, 0x67, 0x5e, + 0x8c, 0x66, 0x8b, 0x63, 0x28, 0x1e, 0x4e, 0x74, 0x85, 0xa8, 0xaf, 0x0f, + 0x12, 0x5d, 0xb6, 0x8a, 0x83, 0x1a, 0x77, 0x76, 0x5e, 0x62, 0x8a, 0xa7, + 0x3c, 0xb8, 0x05, 0x57, 0x2b, 0xaf, 0x36, 0x2e, 0x10, 0x90, 0xb2, 0x39, + 0xb4, 0x3e, 0x75, 0x6d, 0x3a, 0xa8, 0x31, 0x35, 0xc2, 0x1e, 0x8f, 0xc2, + 0x79, 0x89, 0x35, 0x16, 0x26, 0xd1, 0xc7, 0x0b, 0x04, 0x1f, 0x1d, 0xf9, + 0x9c, 0x05, 0xa6, 0x6b, 0xb5, 0x19, 0x5a, 0x24, 0x6d, 0x91, 0xc5, 0x31, + 0xfd, 0xc5, 0xfa, 0xe7, 0xa6, 0xcb, 0x0e, 0x4b, 0x18, 0x0d, 0x94, 0xc7, + 0xee, 0x1d, 0x46, 0x1f, 0x92, 0xb1, 0xb2, 0x4a, 0x2b, 0x43, 0x37, 0xfe, + 0xc2, 0x15, 0x11, 0x89, 0xef, 0x59, 0x73, 0x3c, 0x06, 0x76, 0x78, 0xcb, + 0xa6, 0x0d, 0x79, 0x5f, 0x28, 0x0b, 0x5b, 0x8c, 0x9e, 0xe4, 0xaa, 0x51, + 0x9a, 0x42, 0x6f, 0x11, 0x50, 0x3d, 0x01, 0xd6, 0x21, 0xc0, 0x99, 0x5e, + 0x1a, 0xe8, 0x81, 0x25, 0x80, 0xeb, 0xed, 0x5d, 0x37, 0x47, 0x30, 0x70, + 0xa0, 0x4e, 0x0b, 0x43, 0x17, 0xbe, 0xb6, 0x47, 0xe7, 0x2a, 0x62, 0x9d, + 0x5d, 0xa6, 0xc5, 0x33, 0x62, 0x9d, 0x56, 0x24, 0x9d, 0x1d, 0xb2, 0x13, + 0xbc, 0x17, 0x66, 0x43, 0xd1, 0x68, 0xd5, 0x3b, 0x17, 0x69, 0x17, 0xa6, + 0x06, 0x9e, 0x12, 0xb8, 0x7c, 0xd5, 0xaf, 0x3e, 0x21, 0x1b, 0x31, 0xeb, + 0x0b, 0xa4, 0x98, 0x1c, 0xf2, 0x6a, 0x5e, 0x7c, 0x9b, 0x45, 0x8f, 0xb2, + 0x12, 0x06, 0xd5, 0x8c, 0x1d, 0xb2, 0xa7, 0x57, 0x5f, 0x2f, 0x4f, 0xdb, + 0x52, 0x99, 0x7c, 0x58, 0x01, 0x5f, 0xf2, 0xa5, 0xf6, 0x51, 0x86, 0x21, + 0x2f, 0x5b, 0x8d, 0x6a, 0xae, 0x83, 0x34, 0x6d, 0x58, 0x4b, 0xef, 0xfe, + 0xbf, 0x73, 0x5d, 0xdb, 0xc4, 0x97, 0x2a, 0x85, 0xf3, 0x6c, 0x46, 0x42, + 0xb3, 0x90, 0xc1, 0x57, 0x97, 0x50, 0x35, 0xb1, 0x9d, 0xb7, 0xc7, 0x3c, + 0x85, 0x6d, 0x6c, 0xfd, 0xce, 0xb0, 0xc9, 0xa2, 0x77, 0xee, 0xc3, 0x6b, + 0x0c, 0x37, 0xfa, 0x30, 0x91, 0xd1, 0x2c, 0xb8, 0x5e, 0x7f, 0x81, 0x5f, + 0x87, 0xfd, 0x18, 0x02, 0x5a, 0x30, 0x4e, 0x62, 0xbc, 0x65, 0xc6, 0xce, + 0x1a, 0xcf, 0x2b, 0xaa, 0x56, 0x3e, 0x4d, 0xcf, 0xba, 0x62, 0x5f, 0x9a, + 0xd0, 0x72, 0xff, 0xef, 0x28, 0xbd, 0xbe, 0xd8, 0x57, 0x3d, 0xf5, 0x57, + 0x7d, 0xe9, 0x71, 0x31, 0xec, 0x98, 0x90, 0x94, 0xd9, 0x54, 0xbf, 0x84, + 0x0b, 0xe3, 0x06, 0x47, 0x19, 0x9a, 0x13, 0x1d, 0xef, 0x9d, 0x13, 0xf3, + 0xdb, 0xc3, 0x5c, 0x72, 0x9e, 0xed, 0x24, 0xaa, 0x64, 0xed, 0xe7, 0x0d, + 0xa0, 0x7c, 0x73, 0xba, 0x9b, 0x86, 0xa7, 0x3b, 0x55, 0xab, 0x58, 0x30, + 0xf1, 0x15, 0x81, 0x83, 0x2f, 0xf9, 0x62, 0x84, 0x98, 0x66, 0xf6, 0x55, + 0x21, 0xd8, 0xf2, 0x25, 0x64, 0x71, 0x4b, 0x12, 0x76, 0x59, 0xc5, 0xaa, + 0x93, 0x67, 0xc3, 0x86, 0x25, 0xab, 0x4e, 0x4b, 0xf6, 0xd8, 0x3f, 0x44, + 0x2e, 0x11, 0xe0, 0xbd, 0x6a, 0xf2, 0x5d, 0xf5, 0xf9, 0x53, 0xea, 0xa4, + 0xc8, 0xd9, 0x50, 0x33, 0x81, 0xd9, 0xa8, 0x2d, 0x91, 0x7d, 0x13, 0x2a, + 0x11, 0xcf, 0xde, 0x3f, 0x0a, 0xd2, 0xbc, 0x33, 0xb2, 0x62, 0x53, 0xea, + 0x77, 0x88, 0x43, 0x66, 0x27, 0x43, 0x85, 0xe9, 0x5f, 0x55, 0xf5, 0x2a, + 0x8a, 0xac, 0xdf, 0xff, 0x9b, 0x4c, 0x96, 0x9c, 0xa5, 0x7a, 0xce, 0xd5, + 0x79, 0x18, 0xf1, 0x0b, 0x58, 0x95, 0x7a, 0xe7, 0xd3, 0x74, 0x65, 0x0b, + 0xa4, 0x64, 0x30, 0xe8, 0x5c, 0xfc, 0x55, 0x56, 0xee, 0x14, 0x14, 0xd3, + 0x45, 0x3b, 0xf8, 0xde, 0x05, 0x3e, 0xb9, 0x3c, 0xd7, 0x6a, 0x52, 0x72, + 0x5b, 0x39, 0x09, 0xbe, 0x82, 0x23, 0x10, 0x4a, 0xb7, 0xc3, 0xdc, 0x4c, + 0x5d, 0xc9, 0xf1, 0x14, 0x83, 0xf9, 0x0b, 0x9b, 0xe9, 0x23, 0x84, 0x6a, + 0xc4, 0x08, 0x3d, 0xda, 0x3d, 0x12, 0x95, 0x87, 0x18, 0xa4, 0x7d, 0x3f, + 0x23, 0xde, 0xd4, 0x1e, 0xa8, 0x47, 0xc3, 0x71, 0xdb, 0xf5, 0x03, 0x6c, + 0x57, 0xe7, 0xa4, 0x43, 0x82, 0x33, 0x7b, 0x62, 0x46, 0x7d, 0xf7, 0x10, + 0x69, 0x18, 0x38, 0x27, 0x9a, 0x6f, 0x38, 0xac, 0xfa, 0x92, 0xc5, 0xae, + 0x66, 0xa6, 0x73, 0x95, 0x15, 0x0e, 0x4c, 0x04, 0xb6, 0xfc, 0xf5, 0xc7, + 0x21, 0x3a, 0x99, 0xdb, 0x0e, 0x36, 0xf0, 0x56, 0xbc, 0x75, 0xf9, 0x87, + 0x9b, 0x11, 0x18, 0x92, 0x64, 0x1a, 0xe7, 0xc7, 0xab, 0x5a, 0xc7, 0x26, + 0x7f, 0x13, 0x98, 0x42, 0x52, 0x43, 0xdb, 0xc8, 0x6d, 0x0b, 0xb7, 0x31, + 0x93, 0x24, 0xd6, 0xe8, 0x24, 0x1f, 0x6f, 0x21, 0xa7, 0x8c, 0xeb, 0xdb, + 0x83, 0xb8, 0x89, 0xe3, 0xc1, 0xd7, 0x69, 0x3b, 0x02, 0x6b, 0x54, 0x0f, + 0x84, 0x2f, 0xb5, 0x5c, 0x17, 0x77, 0xbe, 0xe5, 0x61, 0x0d, 0xc5, 0xdf, + 0x3b, 0xcf, 0x3e, 0x93, 0x4f, 0xf5, 0x89, 0xb9, 0x5a, 0xc5, 0x29, 0x31, + 0xc0, 0xc2, 0xff, 0xe5, 0x3f, 0xa6, 0xac, 0x03, 0xca, 0xf5, 0xff, 0xe0, + 0x36, 0xce, 0xf3, 0xe2, 0xb7, 0x9c, 0x02, 0xe9, 0x9e, 0xd2, 0xbc, 0x87, + 0x2f, 0x3d, 0x9a, 0x1d, 0x8f, 0xc5, 0x72, 0xb8, 0xa2, 0x01, 0xd4, 0x68, + 0xb1, 0x84, 0x16, 0x10, 0xf6, 0xf3, 0x52, 0x25, 0xd9, 0xdc, 0x4c, 0xdd, + 0x0f, 0xd6, 0x4a, 0xcf, 0x60, 0x96, 0x7e, 0xcc, 0x42, 0x0f, 0x64, 0x9d, + 0x72, 0x46, 0x04, 0x07, 0xf2, 0x5b, 0xf4, 0x07, 0xd1, 0xf4, 0x59, 0x71, +}; + +static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = { + 0xc8, 0xa6, 0x63, 0xc5, 0x97, 0xf1, 0xee, 0x40, 0xab, 0x62, 0x42, 0xee, + 0x25, 0x6f, 0x32, 0x6c, 0x75, 0x2c, 0xa7, 0xd3, 0xbd, 0x32, 0x3b, 0x1e, + 0x11, 0x9c, 0xbd, 0x04, 0xa9, 0x78, 0x6f, 0x45, 0x5a, 0xda, 0x7e, 0x4b, + 0xf6, 0xdd, 0xd9, 0xad, 0xb6, 0x62, 0x6d, 0x32, 0x13, 0x1c, 0x6b, 0x5c, + 0x51, 0xa1, 0xe3, 0x47, 0xa3, 0x47, 0x8f, 0x53, 0xcf, 0xcf, 0x44, 0x1b, + 0x88, 0xee, 0xd1, 0x2e, 0x03, 0x89, 0xaf, 0xc0, 0x61, 0x2d, 0x9e, 0x35, + 0xeb, 0x0e, 0x03, 0xe0, 0xb7, 0xfb, 0xa5, 0xbc, 0x44, 0xbe, 0x0c, 0x89, + 0x0a, 0x0f, 0xd6, 0x59, 0x47, 0x9e, 0xe6, 0x3d, 0x36, 0x9d, 0xff, 0x44, + 0x5e, 0xac, 0xab, 0xe5, 0x3a, 0xd5, 0xb0, 0x35, 0x9f, 0x6d, 0x7f, 0xba, + 0xc0, 0x85, 0x0e, 0xf4, 0x70, 0x3f, 0x13, 0x90, 0x4c, 0x50, 0x1a, 0xee, + 0xc5, 0xeb, 0x69, 0xfe, 0x98, 0x42, 0x87, 0x1d, 0xce, 0x6c, 0x29, 0xaa, + 0x2b, 0x31, 0xc2, 0x38, 0x7b, 0x6b, 0xee, 0x88, 0x0b, 0xba, 0xce, 0xa8, + 0xca, 0x19, 0x60, 0x1b, 0x16, 0xf1, 0x25, 0x1e, 0xcf, 0x63, 0x66, 0x1e, + 0xbb, 0x63, 0xeb, 0x7d, 0xca, 0xd2, 0xb4, 0x23, 0x5a, 0x01, 0x6f, 0x05, + 0xd1, 0xdc, 0x41, 0x73, 0x75, 0xc0, 0xfd, 0x30, 0x91, 0x52, 0x68, 0x96, + 0x45, 0xb3, 0x66, 0x01, 0x3b, 0x53, 0x89, 0x3c, 0x69, 0xbc, 0x6c, 0x69, + 0xe3, 0x51, 0x8f, 0xe3, 0xd2, 0x84, 0xd5, 0x28, 0x66, 0xb5, 0xe6, 0x06, + 0x09, 0xfe, 0x6d, 0xb0, 0x72, 0x16, 0xe0, 0x8a, 0xce, 0x61, 0x65, 0xa9, + 0x21, 0x32, 0x48, 0xdc, 0x7a, 0x1d, 0xe1, 0x38, 0x7f, 0x8c, 0x75, 0x88, + 0x3d, 0x08, 0xa9, 0x4a, 0x6f, 0x3d, 0x9f, 0x7f, 0x3f, 0xbd, 0x57, 0x6b, + 0x19, 0xce, 0x3f, 0x4a, 0xc9, 0xd3, 0xf9, 0x6e, 0x72, 0x7b, 0x5b, 0x74, + 0xea, 0xbe, 0x9c, 0x7a, 0x6d, 0x9c, 0x40, 0x49, 0xe6, 0xfb, 0x2a, 0x1a, + 0x75, 0x70, 0xe5, 0x4e, 0xed, 0x74, 0xe0, 0x75, 0xac, 0xc0, 0xb1, 0x11, + 0x3e, 0xf2, 0xaf, 0x88, 0x4d, 0x66, 0xb6, 0xf6, 0x15, 0x4f, 0x3c, 0x6c, + 0x77, 0xae, 0x47, 0x51, 0x63, 0x9a, 0xfe, 0xe1, 0xb4, 0x1a, 0x12, 0xdf, + 0xe9, 0x54, 0x8d, 0x3b, 0x30, 0x2a, 0x75, 0xe3, 0xe5, 0x29, 0xb1, 0x4c, + 0xb0, 0x7c, 0x6d, 0xb5, 0xae, 0x85, 0xdb, 0x1e, 0x38, 0x55, 0x96, 0xa5, + 0x5b, 0x9f, 0x15, 0x23, 0x28, 0x36, 0xb8, 0xa2, 0x41, 0xb4, 0xd7, 0x19, + 0x91, 0x8d, 0x26, 0x3e, 0xca, 0x9c, 0x05, 0x7a, 0x2b, 0x60, 0x45, 0x86, + 0x8b, 0xee, 0x64, 0x6f, 0x5c, 0x09, 0x4d, 0x4b, 0x5a, 0x7f, 0xb0, 0xc3, + 0x26, 0x9d, 0x8b, 0xb8, 0x83, 0x69, 0xcf, 0x16, 0x72, 0x62, 0x3e, 0x5e, + 0x53, 0x4f, 0x9c, 0x73, 0x76, 0xfc, 0x19, 0xef, 0xa0, 0x74, 0x3a, 0x11, + 0x1e, 0xd0, 0x4d, 0xb7, 0x87, 0xa1, 0xd6, 0x87, 0x6c, 0x0e, 0x6c, 0x8c, + 0xe9, 0xa0, 0x44, 0xc4, 0x72, 0x3e, 0x73, 0x17, 0x13, 0xd1, 0x4e, 0x3d, + 0x8e, 0x1d, 0x5a, 0x8b, 0x75, 0xcb, 0x59, 0x2c, 0x47, 0x87, 0x15, 0x41, + 0xfe, 0x08, 0xe9, 0xa6, 0x97, 0x17, 0x08, 0x26, 0x6a, 0xb5, 0xbb, 0x73, + 0xaa, 0xb8, 0x5b, 0x65, 0x65, 0x5b, 0x30, 0x9e, 0x62, 0x59, 0x02, 0xf8, + 0xb8, 0x0f, 0x32, 0x10, 0xc1, 0x36, 0x08, 0x52, 0x98, 0x4a, 0x1e, 0xf0, + 0xab, 0x21, 0x5e, 0xde, 0x16, 0x0c, 0xda, 0x09, 0x99, 0x6b, 0x9e, 0xc0, + 0x90, 0xa5, 0x5a, 0xcc, 0xb0, 0xb7, 0xbb, 0xd2, 0x8b, 0x5f, 0xd3, 0x3b, + 0x3e, 0x8c, 0xa5, 0x71, 0x66, 0x06, 0xe3, 0x28, 0xd4, 0xf8, 0x3f, 0xe5, + 0x27, 0xdf, 0xfe, 0x0f, 0x09, 0xb2, 0x8a, 0x09, 0x5a, 0x23, 0x61, 0x0d, + 0x2d, 0xf5, 0x44, 0xf1, 0x5c, 0xf8, 0x82, 0x4e, 0xdc, 0x78, 0x7a, 0xab, + 0xc3, 0x57, 0x91, 0xaf, 0x65, 0x6e, 0x71, 0xf1, 0x44, 0xbf, 0xed, 0x43, + 0x50, 0xb4, 0x67, 0x48, 0xef, 0x5a, 0x10, 0x46, 0x81, 0xb4, 0x0c, 0xc8, + 0x48, 0xed, 0x99, 0x7a, 0x45, 0xa5, 0x92, 0xc3, 0x69, 0xd6, 0xd7, 0x8a, + 0x20, 0x1b, 0xeb, 0x8f, 0xb2, 0xff, 0xec, 0x6d, 0x76, 0x04, 0xf8, 0xc2, + 0x58, 0x9b, 0xf2, 0x20, 0x53, 0xc4, 0x74, 0x91, 0x19, 0xdd, 0x2d, 0x12, + 0x53, 0xc7, 0x6e, 0xd0, 0x02, 0x51, 0x3c, 0xa6, 0x7d, 0x80, 0x75, 0x6b, + 0x1d, 0xdf, 0xf8, 0x6a, 0x52, 0xbb, 0x81, 0xf8, 0x30, 0x45, 0xef, 0x51, + 0x85, 0x36, 0xbe, 0x8e, 0xcf, 0x0b, 0x9a, 0x46, 0xe8, 0x3f, 0x99, 0xfd, + 0xf7, 0xd9, 0x3e, 0x84, 0xe5, 0xe3, 0x37, 0xcf, 0x98, 0x7f, 0xeb, 0x5e, + 0x5a, 0x53, 0x77, 0x1c, 0x20, 0xdc, 0xf1, 0x20, 0x99, 0xec, 0x60, 0x40, + 0x93, 0xef, 0x5c, 0x1c, 0x81, 0xe2, 0xa5, 0xad, 0x2a, 0xc2, 0xdb, 0x6b, + 0xc1, 0x7e, 0x8f, 0xa9, 0x23, 0x5b, 0xd9, 0x0d, 0xfe, 0xa0, 0xac, 0x11, + 0x28, 0xba, 0x8e, 0x92, 0x07, 0x2d, 0x07, 0x40, 0x83, 0x14, 0x4c, 0x35, + 0x8d, 0xd0, 0x11, 0xff, 0x98, 0xdb, 0x00, 0x30, 0x6f, 0x65, 0xb6, 0xa0, + 0x7f, 0x9c, 0x08, 0xb8, 0xce, 0xb3, 0xa8, 0x42, 0xd3, 0x84, 0x45, 0xe1, + 0xe3, 0x8f, 0xa6, 0x89, 0x21, 0xd7, 0x74, 0x02, 0x4d, 0x64, 0xdf, 0x54, + 0x15, 0x9e, 0xba, 0x12, 0x49, 0x09, 0x41, 0xf6, 0x10, 0x24, 0xa1, 0x84, + 0x15, 0xfd, 0x68, 0x6a, 0x57, 0x66, 0xb3, 0x6d, 0x4c, 0xea, 0xbf, 0xbc, + 0x60, 0x3f, 0x52, 0x1c, 0x44, 0x1b, 0xc0, 0x4a, 0x25, 0xe3, 0xd9, 0x4c, + 0x9a, 0x74, 0xad, 0xfc, 0x9e, 0x8d, 0x0b, 0x18, 0x66, 0x24, 0xd1, 0x06, + 0xac, 0x68, 0xc1, 0xae, 0x14, 0xce, 0xb1, 0xf3, 0x86, 0x9f, 0x87, 0x11, + 0xd7, 0x9f, 0x30, 0x92, 0xdb, 0xec, 0x0b, 0x4a, 0xe8, 0xf6, 0x53, 0x36, + 0x68, 0x12, 0x11, 0x5e, 0xe0, 0x34, 0xa4, 0xff, 0x00, 0x0a, 0x26, 0xb8, + 0x62, 0x79, 0x9c, 0x0c, 0xd5, 0xe5, 0xf5, 0x1c, 0x1a, 0x16, 0x84, 0x4d, + 0x8e, 0x5d, 0x31, 0x7e, 0xf7, 0xe2, 0xd3, 0xa1, 0x41, 0x90, 0x61, 0x5d, + 0x04, 0xb2, 0x9a, 0x18, 0x9e, 0x54, 0xfb, 0xd1, 0x61, 0x95, 0x1b, 0x08, + 0xca, 0x7c, 0x49, 0x44, 0x74, 0x1d, 0x2f, 0xca, 0xc4, 0x7a, 0xe1, 0x8b, + 0x2f, 0xbb, 0x96, 0xee, 0x19, 0x8a, 0x5d, 0xfb, 0x3e, 0x82, 0xe7, 0x15, + 0xdb, 0x29, 0x14, 0xee, 0xc9, 0x4d, 0x9a, 0xfb, 0x9f, 0x8a, 0xbb, 0x17, + 0x37, 0x1b, 0x6e, 0x28, 0x6c, 0xf9, 0xff, 0xb5, 0xb5, 0x8b, 0x9d, 0x88, + 0x20, 0x08, 0x10, 0xd7, 0xca, 0x58, 0xf6, 0xe1, 0x32, 0x91, 0x6f, 0x36, + 0xc0, 0xad, 0xc1, 0x57, 0x5d, 0x76, 0x31, 0x43, 0xf3, 0xdd, 0xec, 0xf1, + 0xa9, 0x79, 0xe9, 0xe9, 0x85, 0xd7, 0x91, 0xc7, 0x31, 0x62, 0x3c, 0xd2, + 0x90, 0x2c, 0x9c, 0xa4, 0x56, 0x37, 0x7b, 0xbe, 0x40, 0x58, 0xc0, 0x81, + 0x83, 0x22, 0xe8, 0x13, 0x79, 0x18, 0xdb, 0x3a, 0x1b, 0x31, 0x0d, 0x00, + 0x6c, 0x22, 0x62, 0x75, 0x70, 0xd8, 0x96, 0x59, 0x99, 0x44, 0x79, 0x71, + 0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06, +}; + +SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len) { + SPAKE2_CTX *ctx = OPENSSL_malloc(sizeof(SPAKE2_CTX)); + if (ctx == NULL) { + return NULL; + } + + OPENSSL_memset(ctx, 0, sizeof(SPAKE2_CTX)); + ctx->my_role = my_role; + + CBS my_name_cbs, their_name_cbs; + CBS_init(&my_name_cbs, my_name, my_name_len); + CBS_init(&their_name_cbs, their_name, their_name_len); + if (!CBS_stow(&my_name_cbs, &ctx->my_name, &ctx->my_name_len) || + !CBS_stow(&their_name_cbs, &ctx->their_name, &ctx->their_name_len)) { + SPAKE2_CTX_free(ctx); + return NULL; + } + + return ctx; +} + +void SPAKE2_CTX_free(SPAKE2_CTX *ctx) { + if (ctx == NULL) { + return; + } + + OPENSSL_free(ctx->my_name); + OPENSSL_free(ctx->their_name); + OPENSSL_free(ctx); +} + +// left_shift_3 sets |n| to |n|*8, where |n| is represented in little-endian +// order. +static void left_shift_3(uint8_t n[32]) { + uint8_t carry = 0; + unsigned i; + + for (i = 0; i < 32; i++) { + const uint8_t next_carry = n[i] >> 5; + n[i] = (n[i] << 3) | carry; + carry = next_carry; + } +} + +typedef union { + uint8_t bytes[32]; + uint32_t words[8]; +} scalar; + +// kOrder is the order of the prime-order subgroup of curve25519 in +// little-endian order. +static const scalar kOrder = {{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}}; + +// scalar_cmov copies |src| to |dest| if |mask| is all ones. +static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { + for (size_t i = 0; i < 8; i++) { + dest->words[i] = + constant_time_select_w(mask, src->words[i], dest->words[i]); + } +} + +// scalar_double sets |s| to |2×s|. +static void scalar_double(scalar *s) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + const uint32_t carry_out = s->words[i] >> 31; + s->words[i] = (s->words[i] << 1) | carry; + carry = carry_out; + } +} + +// scalar_add sets |dest| to |dest| plus |src|. +static void scalar_add(scalar *dest, const scalar *src) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + uint64_t tmp = ((uint64_t)dest->words[i] + src->words[i]) + carry; + dest->words[i] = (uint32_t)tmp; + carry = (uint32_t)(tmp >> 32); + } +} + +int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *password, + size_t password_len) { + if (ctx->state != spake2_state_init) { + return 0; + } + + if (max_out_len < sizeof(ctx->my_msg)) { + return 0; + } + + uint8_t private_tmp[64]; + RAND_bytes(private_tmp, sizeof(private_tmp)); + x25519_sc_reduce(private_tmp); + // Multiply by the cofactor (eight) so that we'll clear it when operating on + // the peer's point later in the protocol. + left_shift_3(private_tmp); + OPENSSL_memcpy(ctx->private_key, private_tmp, sizeof(ctx->private_key)); + + ge_p3 P; + x25519_ge_scalarmult_base(&P, ctx->private_key); + + // mask = h(password) * . + uint8_t password_tmp[SHA512_DIGEST_LENGTH]; + SHA512(password, password_len, password_tmp); + OPENSSL_memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash)); + x25519_sc_reduce(password_tmp); + + // Due to a copy-paste error, the call to |left_shift_3| was omitted after + // the |x25519_sc_reduce|, just above. This meant that |ctx->password_scalar| + // was not a multiple of eight to clear the cofactor and thus three bits of + // the password hash would leak. In order to fix this in a unilateral way, + // points of small order are added to the mask point such that it is in the + // prime-order subgroup. Since the ephemeral scalar is a multiple of eight, + // these points will cancel out when calculating the shared secret. + // + // Adding points of small order is the same as adding multiples of the prime + // order to the password scalar. Since that's faster, that is what is done + // below. The prime order (kOrder) is a large prime, thus odd, thus the LSB + // is one. So adding it will flip the LSB. Adding twice it will flip the next + // bit and so one for all the bottom three bits. + + scalar password_scalar; + OPENSSL_memcpy(&password_scalar, password_tmp, sizeof(password_scalar)); + + // |password_scalar| is the result of |x25519_sc_reduce| and thus is, at + // most, $l-1$ (where $l$ is |kOrder|, the order of the prime-order subgroup + // of Ed25519). In the following, we may add $l + 2×l + 4×l$ for a max value + // of $8×l-1$. That is < 2**256, as required. + + if (!ctx->disable_password_scalar_hack) { + scalar order = kOrder; + scalar tmp; + + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 1, 1)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 2, 2)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 4, 4)); + scalar_add(&password_scalar, &tmp); + + assert((password_scalar.bytes[0] & 7) == 0); + } + + OPENSSL_memcpy(ctx->password_scalar, password_scalar.bytes, + sizeof(ctx->password_scalar)); + + ge_p3 mask; + x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeMSmallPrecomp + : kSpakeNSmallPrecomp); + + // P* = P + mask. + ge_cached mask_cached; + x25519_ge_p3_to_cached(&mask_cached, &mask); + ge_p1p1 Pstar; + x25519_ge_add(&Pstar, &P, &mask_cached); + + // Encode P* + ge_p2 Pstar_proj; + x25519_ge_p1p1_to_p2(&Pstar_proj, &Pstar); + x25519_ge_tobytes(ctx->my_msg, &Pstar_proj); + + OPENSSL_memcpy(out, ctx->my_msg, sizeof(ctx->my_msg)); + *out_len = sizeof(ctx->my_msg); + ctx->state = spake2_state_msg_generated; + + return 1; +} + +static void update_with_length_prefix(SHA512_CTX *sha, const uint8_t *data, + const size_t len) { + uint8_t len_le[8]; + size_t l = len; + unsigned i; + + for (i = 0; i < 8; i++) { + len_le[i] = l & 0xff; + l >>= 8; + } + + SHA512_Update(sha, len_le, sizeof(len_le)); + SHA512_Update(sha, data, len); +} + +int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, size_t *out_key_len, + size_t max_out_key_len, const uint8_t *their_msg, + size_t their_msg_len) { + if (ctx->state != spake2_state_msg_generated || + their_msg_len != 32) { + return 0; + } + + ge_p3 Qstar; + if (!x25519_ge_frombytes_vartime(&Qstar, their_msg)) { + // Point received from peer was not on the curve. + return 0; + } + + // Unmask peer's value. + ge_p3 peers_mask; + x25519_ge_scalarmult_small_precomp(&peers_mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeNSmallPrecomp + : kSpakeMSmallPrecomp); + + ge_cached peers_mask_cached; + x25519_ge_p3_to_cached(&peers_mask_cached, &peers_mask); + + ge_p1p1 Q_compl; + ge_p3 Q_ext; + x25519_ge_sub(&Q_compl, &Qstar, &peers_mask_cached); + x25519_ge_p1p1_to_p3(&Q_ext, &Q_compl); + + ge_p2 dh_shared; + x25519_ge_scalarmult(&dh_shared, ctx->private_key, &Q_ext); + + uint8_t dh_shared_encoded[32]; + x25519_ge_tobytes(dh_shared_encoded, &dh_shared); + + SHA512_CTX sha; + SHA512_Init(&sha); + if (ctx->my_role == spake2_role_alice) { + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + update_with_length_prefix(&sha, their_msg, 32); + } else { + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, their_msg, 32); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + } + update_with_length_prefix(&sha, dh_shared_encoded, sizeof(dh_shared_encoded)); + update_with_length_prefix(&sha, ctx->password_hash, + sizeof(ctx->password_hash)); + + uint8_t key[SHA512_DIGEST_LENGTH]; + SHA512_Final(key, &sha); + + size_t to_copy = max_out_key_len; + if (to_copy > sizeof(key)) { + to_copy = sizeof(key); + } + OPENSSL_memcpy(out_key, key, to_copy); + *out_key_len = to_copy; + ctx->state = spake2_state_key_generated; + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/des.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/des.c new file mode 100644 index 00000000..f193a150 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/des.c @@ -0,0 +1,784 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include "internal.h" + + +static const uint32_t des_skb[8][64] = { + { // for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 + 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, 0x00010000L, + 0x00010010L, 0x20010000L, 0x20010010L, 0x00000800L, 0x00000810L, + 0x20000800L, 0x20000810L, 0x00010800L, 0x00010810L, 0x20010800L, + 0x20010810L, 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, + 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, 0x00000820L, + 0x00000830L, 0x20000820L, 0x20000830L, 0x00010820L, 0x00010830L, + 0x20010820L, 0x20010830L, 0x00080000L, 0x00080010L, 0x20080000L, + 0x20080010L, 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, + 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, 0x00090800L, + 0x00090810L, 0x20090800L, 0x20090810L, 0x00080020L, 0x00080030L, + 0x20080020L, 0x20080030L, 0x00090020L, 0x00090030L, 0x20090020L, + 0x20090030L, 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, + 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, }, + { // for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 + 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, 0x00200000L, + 0x02200000L, 0x00202000L, 0x02202000L, 0x00000004L, 0x02000004L, + 0x00002004L, 0x02002004L, 0x00200004L, 0x02200004L, 0x00202004L, + 0x02202004L, 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, + 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, 0x00000404L, + 0x02000404L, 0x00002404L, 0x02002404L, 0x00200404L, 0x02200404L, + 0x00202404L, 0x02202404L, 0x10000000L, 0x12000000L, 0x10002000L, + 0x12002000L, 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, + 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, 0x10200004L, + 0x12200004L, 0x10202004L, 0x12202004L, 0x10000400L, 0x12000400L, + 0x10002400L, 0x12002400L, 0x10200400L, 0x12200400L, 0x10202400L, + 0x12202400L, 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, + 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, }, + { // for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 + 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, 0x01000000L, + 0x01000001L, 0x01040000L, 0x01040001L, 0x00000002L, 0x00000003L, + 0x00040002L, 0x00040003L, 0x01000002L, 0x01000003L, 0x01040002L, + 0x01040003L, 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, + 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, 0x00000202L, + 0x00000203L, 0x00040202L, 0x00040203L, 0x01000202L, 0x01000203L, + 0x01040202L, 0x01040203L, 0x08000000L, 0x08000001L, 0x08040000L, + 0x08040001L, 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, + 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, 0x09000002L, + 0x09000003L, 0x09040002L, 0x09040003L, 0x08000200L, 0x08000201L, + 0x08040200L, 0x08040201L, 0x09000200L, 0x09000201L, 0x09040200L, + 0x09040201L, 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, + 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, }, + { // for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 + 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, 0x00000008L, + 0x00100008L, 0x00000108L, 0x00100108L, 0x00001000L, 0x00101000L, + 0x00001100L, 0x00101100L, 0x00001008L, 0x00101008L, 0x00001108L, + 0x00101108L, 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, + 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, 0x04001000L, + 0x04101000L, 0x04001100L, 0x04101100L, 0x04001008L, 0x04101008L, + 0x04001108L, 0x04101108L, 0x00020000L, 0x00120000L, 0x00020100L, + 0x00120100L, 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, + 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, 0x00021008L, + 0x00121008L, 0x00021108L, 0x00121108L, 0x04020000L, 0x04120000L, + 0x04020100L, 0x04120100L, 0x04020008L, 0x04120008L, 0x04020108L, + 0x04120108L, 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, + 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, }, + { // for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 + 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, 0x00000004L, + 0x10000004L, 0x00010004L, 0x10010004L, 0x20000000L, 0x30000000L, + 0x20010000L, 0x30010000L, 0x20000004L, 0x30000004L, 0x20010004L, + 0x30010004L, 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, + 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, 0x20100000L, + 0x30100000L, 0x20110000L, 0x30110000L, 0x20100004L, 0x30100004L, + 0x20110004L, 0x30110004L, 0x00001000L, 0x10001000L, 0x00011000L, + 0x10011000L, 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, + 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, 0x20001004L, + 0x30001004L, 0x20011004L, 0x30011004L, 0x00101000L, 0x10101000L, + 0x00111000L, 0x10111000L, 0x00101004L, 0x10101004L, 0x00111004L, + 0x10111004L, 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, + 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, }, + { // for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 + 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, 0x00000400L, + 0x08000400L, 0x00000408L, 0x08000408L, 0x00020000L, 0x08020000L, + 0x00020008L, 0x08020008L, 0x00020400L, 0x08020400L, 0x00020408L, + 0x08020408L, 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, + 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, 0x00020001L, + 0x08020001L, 0x00020009L, 0x08020009L, 0x00020401L, 0x08020401L, + 0x00020409L, 0x08020409L, 0x02000000L, 0x0A000000L, 0x02000008L, + 0x0A000008L, 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, + 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, 0x02020400L, + 0x0A020400L, 0x02020408L, 0x0A020408L, 0x02000001L, 0x0A000001L, + 0x02000009L, 0x0A000009L, 0x02000401L, 0x0A000401L, 0x02000409L, + 0x0A000409L, 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, + 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, }, + { // for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 + 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, 0x01000000L, + 0x01000100L, 0x01080000L, 0x01080100L, 0x00000010L, 0x00000110L, + 0x00080010L, 0x00080110L, 0x01000010L, 0x01000110L, 0x01080010L, + 0x01080110L, 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, + 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, 0x00200010L, + 0x00200110L, 0x00280010L, 0x00280110L, 0x01200010L, 0x01200110L, + 0x01280010L, 0x01280110L, 0x00000200L, 0x00000300L, 0x00080200L, + 0x00080300L, 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, + 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, 0x01000210L, + 0x01000310L, 0x01080210L, 0x01080310L, 0x00200200L, 0x00200300L, + 0x00280200L, 0x00280300L, 0x01200200L, 0x01200300L, 0x01280200L, + 0x01280300L, 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, + 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, }, + { // for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 + 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, 0x00000002L, + 0x04000002L, 0x00040002L, 0x04040002L, 0x00002000L, 0x04002000L, + 0x00042000L, 0x04042000L, 0x00002002L, 0x04002002L, 0x00042002L, + 0x04042002L, 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, + 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, 0x00002020L, + 0x04002020L, 0x00042020L, 0x04042020L, 0x00002022L, 0x04002022L, + 0x00042022L, 0x04042022L, 0x00000800L, 0x04000800L, 0x00040800L, + 0x04040800L, 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, + 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, 0x00002802L, + 0x04002802L, 0x00042802L, 0x04042802L, 0x00000820L, 0x04000820L, + 0x00040820L, 0x04040820L, 0x00000822L, 0x04000822L, 0x00040822L, + 0x04040822L, 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, + 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, }}; + +static const uint32_t DES_SPtrans[8][64] = { + { // nibble 0 + 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, 0x02000000L, + 0x00080802L, 0x00080002L, 0x02000002L, 0x00080802L, 0x02080800L, + 0x02080000L, 0x00000802L, 0x02000802L, 0x02000000L, 0x00000000L, + 0x00080002L, 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, + 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, 0x00000002L, + 0x00000800L, 0x00080800L, 0x02080002L, 0x00000800L, 0x02000802L, + 0x02080002L, 0x00000000L, 0x00000000L, 0x02080802L, 0x02000800L, + 0x00080002L, 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, + 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, 0x00080802L, + 0x00000002L, 0x02000002L, 0x02080000L, 0x02080802L, 0x00080800L, + 0x02080000L, 0x02000802L, 0x02000000L, 0x00000802L, 0x00080002L, + 0x00000000L, 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, + 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, }, + { // nibble 1 + 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, 0x40000010L, + 0x00008010L, 0x40008000L, 0x00108000L, 0x00008000L, 0x40100010L, + 0x00000010L, 0x40008000L, 0x00100010L, 0x40108000L, 0x40100000L, + 0x00000010L, 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, + 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, 0x40008010L, + 0x00108010L, 0x40108000L, 0x40000010L, 0x40000000L, 0x00100000L, + 0x00008010L, 0x40108010L, 0x00100010L, 0x40108000L, 0x40008000L, + 0x00108010L, 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, + 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, 0x00008000L, + 0x40000000L, 0x00108010L, 0x40008010L, 0x40108000L, 0x00008000L, + 0x00000000L, 0x40000010L, 0x00000010L, 0x40108010L, 0x00108000L, + 0x40100000L, 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, + 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, }, + { // nibble 2 + 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, 0x00040001L, + 0x04000000L, 0x04000101L, 0x00040100L, 0x04000100L, 0x00040000L, + 0x04040000L, 0x00000001L, 0x04040101L, 0x00000101L, 0x00000001L, + 0x04040001L, 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, + 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, 0x04040001L, + 0x04000100L, 0x00040101L, 0x04040000L, 0x00040100L, 0x00000000L, + 0x04000000L, 0x00040101L, 0x04040100L, 0x00000100L, 0x00000001L, + 0x00040000L, 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, + 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, 0x00040001L, + 0x04000000L, 0x04040101L, 0x00000001L, 0x00040101L, 0x04000001L, + 0x04000000L, 0x04040101L, 0x00040000L, 0x04000100L, 0x04000101L, + 0x00040100L, 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, + 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, }, + { // nibble 3 + 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, 0x00000000L, + 0x10400000L, 0x10001008L, 0x00400008L, 0x10401000L, 0x10000008L, + 0x10000000L, 0x00001008L, 0x10000008L, 0x00401008L, 0x00400000L, + 0x10000000L, 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, + 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, 0x00001008L, + 0x00000000L, 0x00400008L, 0x10401000L, 0x10001000L, 0x10400008L, + 0x10401008L, 0x00400000L, 0x10400008L, 0x00001008L, 0x00400000L, + 0x10000008L, 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, + 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, 0x00000000L, + 0x10400008L, 0x10401000L, 0x00001000L, 0x10000000L, 0x10401008L, + 0x00401008L, 0x00400000L, 0x10401008L, 0x00000008L, 0x10001000L, + 0x00401008L, 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, + 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, }, + { // nibble 4 + 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, 0x08010020L, + 0x08000400L, 0x00010420L, 0x08010000L, 0x00010000L, 0x00000020L, + 0x08000020L, 0x00010400L, 0x08000420L, 0x08010020L, 0x08010400L, + 0x00000000L, 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, + 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, 0x00000020L, + 0x08000420L, 0x08010420L, 0x00010020L, 0x08010000L, 0x00000400L, + 0x00000420L, 0x08010400L, 0x08010400L, 0x08000420L, 0x00010020L, + 0x08010000L, 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, + 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, 0x00010420L, + 0x08000000L, 0x00000400L, 0x00010020L, 0x08000420L, 0x00000400L, + 0x00000000L, 0x08010420L, 0x08010020L, 0x08010400L, 0x00000420L, + 0x00010000L, 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, + 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, }, + { // nibble 5 + 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, 0x00200040L, + 0x00002000L, 0x80002040L, 0x00200000L, 0x00002040L, 0x80202040L, + 0x00202000L, 0x80000000L, 0x80002000L, 0x80000040L, 0x80200000L, + 0x00202040L, 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, + 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, 0x80202040L, + 0x80200000L, 0x80000000L, 0x00002040L, 0x00000040L, 0x00202000L, + 0x00202040L, 0x80002000L, 0x00002040L, 0x80000000L, 0x80002000L, + 0x00202040L, 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, + 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, 0x00200040L, + 0x80202040L, 0x00202000L, 0x00000040L, 0x80202040L, 0x00202000L, + 0x00200000L, 0x80002040L, 0x80000040L, 0x80200000L, 0x00202040L, + 0x00000000L, 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, + 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, }, + { // nibble 6 + 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, 0x01004204L, + 0x00004004L, 0x00004200L, 0x00000000L, 0x01000000L, 0x01000204L, + 0x00000204L, 0x01004000L, 0x00000004L, 0x01004200L, 0x01004000L, + 0x00000204L, 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, + 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, 0x01004004L, + 0x00004204L, 0x01004200L, 0x00000004L, 0x00004204L, 0x01004004L, + 0x00000200L, 0x01000000L, 0x00004204L, 0x01004000L, 0x01004004L, + 0x00000204L, 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, + 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, 0x00000200L, + 0x01000004L, 0x00000004L, 0x01000200L, 0x00000000L, 0x01000204L, + 0x01000200L, 0x00004200L, 0x00000204L, 0x00004000L, 0x01004204L, + 0x01000000L, 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, + 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, }, + { // nibble 7 + 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, 0x20020000L, + 0x00800080L, 0x20800000L, 0x20820080L, 0x00000080L, 0x20000000L, + 0x00820000L, 0x00020080L, 0x00820080L, 0x20020080L, 0x20000080L, + 0x20800000L, 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, 0x20000000L, + 0x00800000L, 0x20020080L, 0x20800080L, 0x00800000L, 0x00020000L, + 0x20820000L, 0x00000080L, 0x00800000L, 0x00020000L, 0x20000080L, + 0x20820080L, 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, + 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, 0x20820000L, + 0x00000080L, 0x00800080L, 0x20020000L, 0x20820080L, 0x00800000L, + 0x20800000L, 0x20000080L, 0x00820000L, 0x00020080L, 0x20020080L, + 0x20800000L, 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, + 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, }}; + +#define HPERM_OP(a, t, n, m) \ + ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \ + (a) = (a) ^ (t) ^ ((t) >> (16 - (n)))) + +void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { + static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 0}; + uint32_t c, d, t, s, t2; + const uint8_t *in; + int i; + + in = key->bytes; + + c2l(in, c); + c2l(in, d); + + // do PC1 in 47 simple operations :-) + // Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + // for the inspiration. :-) + PERM_OP(d, c, t, 4, 0x0f0f0f0fL); + HPERM_OP(c, t, -2, 0xcccc0000L); + HPERM_OP(d, t, -2, 0xcccc0000L); + PERM_OP(d, c, t, 1, 0x55555555L); + PERM_OP(c, d, t, 8, 0x00ff00ffL); + PERM_OP(d, c, t, 1, 0x55555555L); + d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | + ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); + c &= 0x0fffffffL; + + for (i = 0; i < ITERATIONS; i++) { + if (shifts2[i]) { + c = ((c >> 2L) | (c << 26L)); + d = ((d >> 2L) | (d << 26L)); + } else { + c = ((c >> 1L) | (c << 27L)); + d = ((d >> 1L) | (d << 27L)); + } + c &= 0x0fffffffL; + d &= 0x0fffffffL; + // could be a few less shifts but I am to lazy at this + // point in time to investigate + s = des_skb[0][(c) & 0x3f] | + des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | + des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | + des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | + ((c >> 22L) & 0x38)]; + t = des_skb[4][(d) & 0x3f] | + des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | + des_skb[6][(d >> 15L) & 0x3f] | + des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; + + // table contained 0213 4657 + t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; + schedule->subkeys[i][0] = CRYPTO_rotr_u32(t2, 30); + + t2 = ((s >> 16L) | (t & 0xffff0000L)); + schedule->subkeys[i][1] = CRYPTO_rotr_u32(t2, 26); + } +} + +static const uint8_t kOddParity[256] = { + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, + 14, 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, + 31, 31, 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, + 44, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, + 61, 61, 62, 62, 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, + 74, 76, 76, 79, 79, 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, + 91, 91, 93, 93, 94, 94, 97, 97, 98, 98, 100, 100, 103, 103, 104, + 104, 107, 107, 109, 109, 110, 110, 112, 112, 115, 115, 117, 117, 118, 118, + 121, 121, 122, 122, 124, 124, 127, 127, 128, 128, 131, 131, 133, 133, 134, + 134, 137, 137, 138, 138, 140, 140, 143, 143, 145, 145, 146, 146, 148, 148, + 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 161, 161, 162, 162, 164, + 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174, 176, 176, 179, 179, + 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191, 193, 193, 194, + 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206, 208, 208, + 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223, 224, + 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239, + 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, + 254 +}; + +void DES_set_odd_parity(DES_cblock *key) { + unsigned i; + + for (i = 0; i < DES_KEY_SZ; i++) { + key->bytes[i] = kOddParity[key->bytes[i]]; + } +} + +static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + r = data[0]; + l = data[1]; + + IP(r, l); + // Things have been modified so that the initial rotate is done outside + // the loop. This required the DES_SPtrans values in sp.h to be + // rotated 1 bit to the right. One perl script later and things have a + // 5% speed up on a sparc2. Thanks to Richard Outerbridge + // <71755.204@CompuServe.COM> for pointing this out. + // clear the top bits on machines with 8byte longs + // shift left by 2 + r = CRYPTO_rotr_u32(r, 29); + l = CRYPTO_rotr_u32(l, 29); + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + + // rotate and clear the top bits on machines with 8byte longs + l = CRYPTO_rotr_u32(l, 3); + r = CRYPTO_rotr_u32(r, 3); + + FP(r, l); + data[0] = l; + data[1] = r; +} + +static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + r = data[0]; + l = data[1]; + + // Things have been modified so that the initial rotate is done outside the + // loop. This required the DES_SPtrans values in sp.h to be rotated 1 bit to + // the right. One perl script later and things have a 5% speed up on a + // sparc2. Thanks to Richard Outerbridge <71755.204@CompuServe.COM> for + // pointing this out. + // clear the top bits on machines with 8byte longs + r = CRYPTO_rotr_u32(r, 29); + l = CRYPTO_rotr_u32(l, 29); + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + // rotate and clear the top bits on machines with 8byte longs + data[0] = CRYPTO_rotr_u32(l, 3); + data[1] = CRYPTO_rotr_u32(r, 3); +} + +void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks1, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks3, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_ecb_encrypt(const DES_cblock *in_block, DES_cblock *out_block, + const DES_key_schedule *schedule, int is_encrypt) { + uint32_t l; + uint32_t ll[2]; + const uint8_t *in = in_block->bytes; + uint8_t *out = out_block->bytes; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, schedule, is_encrypt); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + ll[0] = ll[1] = 0; +} + +void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *schedule, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + unsigned char *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (len != 0) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, len); + xor0 = tin0; + xor1 = tin1; + } + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin[0] = tin[1] = 0; +} + +void DES_ecb3_encrypt(const DES_cblock *input, DES_cblock *output, + const DES_key_schedule *ks1, const DES_key_schedule *ks2, + const DES_key_schedule *ks3, int enc) { + uint32_t l0, l1; + uint32_t ll[2]; + const uint8_t *in = input->bytes; + uint8_t *out = output->bytes; + + c2l(in, l0); + c2l(in, l1); + ll[0] = l0; + ll[1] = l1; + if (enc) { + DES_encrypt3(ll, ks1, ks2, ks3); + } else { + DES_decrypt3(ll, ks1, ks2, ks3); + } + l0 = ll[0]; + l1 = ll[1]; + l2c(l0, out); + l2c(l1, out); +} + +void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + uint8_t *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + uint32_t t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = t0; + xor1 = t1; + } + if (len != 0) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, len); + xor0 = t0; + xor1 = t1; + } + + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + + tin[0] = tin[1] = 0; +} + +void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, + int enc) { + DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc); +} + + +// Deprecated functions. + +void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) { + DES_set_key(key, schedule); +} + +#undef HPERM_OP +#undef c2l +#undef l2c +#undef c2ln +#undef l2cn +#undef PERM_OP +#undef IP +#undef FP +#undef LOAD_DATA +#undef D_ENCRYPT +#undef ITERATIONS +#undef HALF_ITERATIONS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/internal.h new file mode 100644 index 00000000..918943f9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/des/internal.h @@ -0,0 +1,238 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DES_INTERNAL_H +#define OPENSSL_HEADER_DES_INTERNAL_H + +#include + +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (unsigned char)(((l)) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 8L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 16L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 24L) & 0xff); \ + } while (0) + +// NOTE - c is not incremented as per c2l +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +// NOTE - c is not incremented as per l2c +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (unsigned char)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (unsigned char)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (unsigned char)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (unsigned char)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (unsigned char)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (unsigned char)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (unsigned char)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (unsigned char)(((l1)) & 0xff); \ + } \ + } while (0) + +/* IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 +16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 +24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + +32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 +40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 +48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 +56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + +The output has been subject to swaps of the form +0 1 -> 3 1 but the odd and even bits have been put into +2 3 2 0 +different words. The main trick is to remember that +t=((l>>size)^r)&(mask); +r^=t; +l^=(t<> (n)) ^ (b)) & (m)); \ + (b) ^= (t); \ + (a) ^= ((t) << (n)); \ + } while (0) + +#define IP(l, r) \ + do { \ + uint32_t tt; \ + PERM_OP(r, l, tt, 4, 0x0f0f0f0fL); \ + PERM_OP(l, r, tt, 16, 0x0000ffffL); \ + PERM_OP(r, l, tt, 2, 0x33333333L); \ + PERM_OP(l, r, tt, 8, 0x00ff00ffL); \ + PERM_OP(r, l, tt, 1, 0x55555555L); \ + } while (0) + +#define FP(l, r) \ + do { \ + uint32_t tt; \ + PERM_OP(l, r, tt, 1, 0x55555555L); \ + PERM_OP(r, l, tt, 8, 0x00ff00ffL); \ + PERM_OP(l, r, tt, 2, 0x33333333L); \ + PERM_OP(r, l, tt, 16, 0x0000ffffL); \ + PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \ + } while (0) + +#define LOAD_DATA(ks, R, S, u, t, E0, E1) \ + do { \ + (u) = (R) ^ (ks)->subkeys[S][0]; \ + (t) = (R) ^ (ks)->subkeys[S][1]; \ + } while (0) + +#define D_ENCRYPT(ks, LL, R, S) \ + do { \ + LOAD_DATA(ks, R, S, u, t, E0, E1); \ + t = CRYPTO_rotr_u32(t, 4); \ + (LL) ^= \ + DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \ + DES_SPtrans[4][(u >> 18L) & 0x3f] ^ \ + DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \ + DES_SPtrans[3][(t >> 10L) & 0x3f] ^ \ + DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \ + } while (0) + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/dh_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/dh_asn1.c new file mode 100644 index 00000000..987fb1da --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/dh_asn1.c @@ -0,0 +1,160 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include + +#include "../bytestring/internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DH object may be missing some components. + OPENSSL_PUT_ERROR(DH, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DH *DH_parse_parameters(CBS *cbs) { + DH *ret = DH_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->g)) { + goto err; + } + + uint64_t priv_length; + if (CBS_len(&child) != 0) { + if (!CBS_get_asn1_uint64(&child, &priv_length) || + priv_length > UINT_MAX) { + goto err; + } + ret->priv_length = (unsigned)priv_length; + } + + if (CBS_len(&child) != 0) { + goto err; + } + + return ret; + +err: + OPENSSL_PUT_ERROR(DH, DH_R_DECODE_ERROR); + DH_free(ret); + return NULL; +} + +int DH_marshal_parameters(CBB *cbb, const DH *dh) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dh->p) || + !marshal_integer(&child, dh->g) || + (dh->priv_length != 0 && + !CBB_add_asn1_uint64(&child, dh->priv_length)) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DH, DH_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DH *ret = DH_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DH_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DHparams(const DH *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DH_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/params.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/params.c new file mode 100644 index 00000000..3df5f4a0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dh_extra/params.c @@ -0,0 +1,272 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" + + +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { + static const BN_ULONG kPrime1536Data[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0xf1746c08, 0xca237327), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + + static const BIGNUM kPrime1536BN = STATIC_BIGNUM(kPrime1536Data); + + BIGNUM *alloc = NULL; + if (ret == NULL) { + alloc = BN_new(); + if (alloc == NULL) { + return NULL; + } + ret = alloc; + } + + if (!BN_copy(ret, &kPrime1536BN)) { + BN_free(alloc); + return NULL; + } + + return ret; +} + +int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, + BN_GENCB *cb) { + // We generate DH parameters as follows + // find a prime q which is prime_bits/2 bits long. + // p=(2*q)+1 or (p-1)/2 = q + // For this case, g is a generator if + // g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + // Since the factors of p-1 are q and 2, we just need to check + // g^2 mod p != 1 and g^q mod p != 1. + // + // Having said all that, + // there is another special case method for the generators 2, 3 and 5. + // for 2, p mod 24 == 11 + // for 3, p mod 12 == 5 <<<<< does not work for safe primes. + // for 5, p mod 10 == 3 or 7 + // + // Thanks to Phil Karn for the pointers about the + // special generators and for answering some of my questions. + // + // I've implemented the second simple method :-). + // Since DH should be using a safe prime (both p and q are prime), + // this generator function can take a very very long time to run. + + // Actually there is no reason to insist that 'generator' be a generator. + // It's just as OK (and in some sense better) to use a generator of the + // order-q subgroup. + + BIGNUM *t1, *t2; + int g, ok = 0; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) { + goto err; + } + + // Make sure |dh| has the necessary elements + if (dh->p == NULL) { + dh->p = BN_new(); + if (dh->p == NULL) { + goto err; + } + } + if (dh->g == NULL) { + dh->g = BN_new(); + if (dh->g == NULL) { + goto err; + } + } + + if (generator <= 1) { + OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) { + if (!BN_set_word(t1, 24)) { + goto err; + } + if (!BN_set_word(t2, 11)) { + goto err; + } + g = 2; + } else if (generator == DH_GENERATOR_5) { + if (!BN_set_word(t1, 10)) { + goto err; + } + if (!BN_set_word(t2, 3)) { + goto err; + } + // BN_set_word(t3,7); just have to miss + // out on these ones :-( + g = 5; + } else { + // in the general case, don't worry if 'generator' is a + // generator or not: since we are using safe primes, + // it will generate either an order-q or an order-2q group, + // which both is OK + if (!BN_set_word(t1, 2)) { + goto err; + } + if (!BN_set_word(t2, 1)) { + goto err; + } + g = generator; + } + + if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) { + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) { + goto err; + } + if (!BN_set_word(dh->g, g)) { + goto err; + } + ok = 1; + +err: + if (!ok) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) { + BIGNUM *a = NULL; + + if (src) { + a = BN_dup(src); + if (!a) { + return 0; + } + } + + BN_free(*dst); + *dst = a; + return 1; +} + +static int int_dh_param_copy(DH *to, const DH *from, int is_x942) { + if (is_x942 == -1) { + is_x942 = !!from->q; + } + if (!int_dh_bn_cpy(&to->p, from->p) || + !int_dh_bn_cpy(&to->g, from->g)) { + return 0; + } + + if (!is_x942) { + return 1; + } + + if (!int_dh_bn_cpy(&to->q, from->q) || + !int_dh_bn_cpy(&to->j, from->j)) { + return 0; + } + + OPENSSL_free(to->seed); + to->seed = NULL; + to->seedlen = 0; + + if (from->seed) { + to->seed = OPENSSL_memdup(from->seed, from->seedlen); + if (!to->seed) { + return 0; + } + to->seedlen = from->seedlen; + } + + return 1; +} + +DH *DHparams_dup(const DH *dh) { + DH *ret = DH_new(); + if (!ret) { + return NULL; + } + + if (!int_dh_param_copy(ret, dh, -1)) { + DH_free(ret); + return NULL; + } + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c new file mode 100644 index 00000000..42fddfa0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c @@ -0,0 +1,268 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include + +#include "../asn1/internal.h" +#include "../internal.h" +#include "../fipsmodule/digest/internal.h" + + +struct nid_to_digest { + int nid; + const EVP_MD* (*md_func)(void); + const char *short_name; + const char *long_name; +}; + +static const struct nid_to_digest nid_to_digest_mapping[] = { + {NID_md4, EVP_md4, SN_md4, LN_md4}, + {NID_md5, EVP_md5, SN_md5, LN_md5}, + {NID_sha1, EVP_sha1, SN_sha1, LN_sha1}, + {NID_sha224, EVP_sha224, SN_sha224, LN_sha224}, + {NID_sha256, EVP_sha256, SN_sha256, LN_sha256}, + {NID_sha384, EVP_sha384, SN_sha384, LN_sha384}, + {NID_sha512, EVP_sha512, SN_sha512, LN_sha512}, + {NID_sha512_256, EVP_sha512_256, SN_sha512_256, LN_sha512_256}, + {NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1}, + // As a remnant of signing |EVP_MD|s, OpenSSL returned the corresponding + // hash function when given a signature OID. To avoid unintended lax parsing + // of hash OIDs, this is no longer supported for lookup by OID or NID. + // Node.js, however, exposes |EVP_get_digestbyname|'s full behavior to + // consumers so we retain it there. + {NID_undef, EVP_sha1, SN_dsaWithSHA, LN_dsaWithSHA}, + {NID_undef, EVP_sha1, SN_dsaWithSHA1, LN_dsaWithSHA1}, + {NID_undef, EVP_sha1, SN_ecdsa_with_SHA1, NULL}, + {NID_undef, EVP_md5, SN_md5WithRSAEncryption, LN_md5WithRSAEncryption}, + {NID_undef, EVP_sha1, SN_sha1WithRSAEncryption, LN_sha1WithRSAEncryption}, + {NID_undef, EVP_sha224, SN_sha224WithRSAEncryption, + LN_sha224WithRSAEncryption}, + {NID_undef, EVP_sha256, SN_sha256WithRSAEncryption, + LN_sha256WithRSAEncryption}, + {NID_undef, EVP_sha384, SN_sha384WithRSAEncryption, + LN_sha384WithRSAEncryption}, + {NID_undef, EVP_sha512, SN_sha512WithRSAEncryption, + LN_sha512WithRSAEncryption}, +}; + +const EVP_MD* EVP_get_digestbynid(int nid) { + if (nid == NID_undef) { + // Skip the |NID_undef| entries in |nid_to_digest_mapping|. + return NULL; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + if (nid_to_digest_mapping[i].nid == nid) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; +} kMDOIDs[] = { + // 1.2.840.113549.2.4 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 }, + // 1.2.840.113549.2.5 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 }, + // 1.3.14.3.2.26 + { {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 }, + // 2.16.840.1.101.3.4.2.1 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 }, + // 2.16.840.1.101.3.4.2.2 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 }, + // 2.16.840.1.101.3.4.2.3 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 }, + // 2.16.840.1.101.3.4.2.4 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 }, +}; + +static const EVP_MD *cbs_to_md(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (CBS_len(cbs) == kMDOIDs[i].oid_len && + OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == + 0) { + return EVP_get_digestbynid(kMDOIDs[i].nid); + } + } + + return NULL; +} + +const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) { + // Handle objects with no corresponding OID. Note we don't use |OBJ_obj2nid| + // here to avoid pulling in the OID table. + if (obj->nid != NID_undef) { + return EVP_get_digestbynid(obj->nid); + } + + CBS cbs; + CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj)); + return cbs_to_md(&cbs); +} + +const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { + CBS algorithm, oid; + if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + + const EVP_MD *ret = cbs_to_md(&oid); + if (ret == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return NULL; + } + + // The parameters, if present, must be NULL. Historically, whether the NULL + // was included or omitted was not well-specified. When parsing an + // AlgorithmIdentifier, we allow both. (Note this code is not used when + // verifying RSASSA-PKCS1-v1_5 signatures.) + if (CBS_len(&algorithm) > 0) { + CBS param; + if (!CBS_get_asn1(&algorithm, ¶m, CBS_ASN1_NULL) || + CBS_len(¶m) != 0 || + CBS_len(&algorithm) != 0) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + } + + return ret; +} + +int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { + CBB algorithm, oid, null; + if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + int found = 0; + int nid = EVP_MD_type(md); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (nid == kMDOIDs[i].nid) { + if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + found = 1; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return 0; + } + + if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +const EVP_MD *EVP_get_digestbyname(const char *name) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + const char *short_name = nid_to_digest_mapping[i].short_name; + const char *long_name = nid_to_digest_mapping[i].long_name; + if ((short_name && strcmp(short_name, name) == 0) || + (long_name && strcmp(long_name, name) == 0)) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} + +static void blake2b256_init(EVP_MD_CTX *ctx) { BLAKE2B256_Init(ctx->md_data); } + +static void blake2b256_update(EVP_MD_CTX *ctx, const void *data, size_t len) { + BLAKE2B256_Update(ctx->md_data, data, len); +} + +static void blake2b256_final(EVP_MD_CTX *ctx, uint8_t *md) { + BLAKE2B256_Final(md, ctx->md_data); +} + +static const EVP_MD evp_md_blake2b256 = { + NID_undef, + BLAKE2B256_DIGEST_LENGTH, + 0, + blake2b256_init, + blake2b256_update, + blake2b256_final, + BLAKE2B_CBLOCK, + sizeof(BLAKE2B_CTX), +}; + +const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa.c new file mode 100644 index 00000000..303692b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa.c @@ -0,0 +1,967 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + * + * The DSS routines are based on patches supplied by + * Steven Schoch . */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../fipsmodule/bn/internal.h" +#include "../internal.h" + + +// Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of +// Miller-Rabin. +#define DSS_prime_checks 50 + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv, + BIGNUM **out_r); + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +DSA *DSA_new(void) { + DSA *dsa = OPENSSL_malloc(sizeof(DSA)); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dsa, 0, sizeof(DSA)); + + dsa->references = 1; + + CRYPTO_MUTEX_init(&dsa->method_mont_lock); + CRYPTO_new_ex_data(&dsa->ex_data); + + return dsa; +} + +void DSA_free(DSA *dsa) { + if (dsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data); + + BN_clear_free(dsa->p); + BN_clear_free(dsa->q); + BN_clear_free(dsa->g); + BN_clear_free(dsa->pub_key); + BN_clear_free(dsa->priv_key); + BN_MONT_CTX_free(dsa->method_mont_p); + BN_MONT_CTX_free(dsa->method_mont_q); + CRYPTO_MUTEX_cleanup(&dsa->method_mont_lock); + OPENSSL_free(dsa); +} + +int DSA_up_ref(DSA *dsa) { + CRYPTO_refcount_inc(&dsa->references); + return 1; +} + +const BIGNUM *DSA_get0_pub_key(const DSA *dsa) { return dsa->pub_key; } + +const BIGNUM *DSA_get0_priv_key(const DSA *dsa) { return dsa->priv_key; } + +const BIGNUM *DSA_get0_p(const DSA *dsa) { return dsa->p; } + +const BIGNUM *DSA_get0_q(const DSA *dsa) { return dsa->q; } + +const BIGNUM *DSA_get0_g(const DSA *dsa) { return dsa->g; } + +void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dsa->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dsa->priv_key; + } +} + +void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dsa->p; + } + if (out_q != NULL) { + *out_q = dsa->q; + } + if (out_g != NULL) { + *out_g = dsa->g; + } +} + +int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) { + if (dsa->pub_key == NULL && pub_key == NULL) { + return 0; + } + + if (pub_key != NULL) { + BN_free(dsa->pub_key); + dsa->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dsa->priv_key); + dsa->priv_key = priv_key; + } + + return 1; +} + +int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if ((dsa->p == NULL && p == NULL) || + (dsa->q == NULL && q == NULL) || + (dsa->g == NULL && g == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(dsa->p); + dsa->p = p; + } + if (q != NULL) { + BN_free(dsa->q); + dsa->q = q; + } + if (g != NULL) { + BN_free(dsa->g); + dsa->g = g; + } + + return 1; +} + +int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, + size_t seed_len, int *out_counter, + unsigned long *out_h, BN_GENCB *cb) { + int ok = 0; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; + BIGNUM *r0, *W, *X, *c, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int k, n = 0, m = 0; + unsigned i; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + unsigned qsize; + const EVP_MD *evpmd; + + evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); + qsize = EVP_MD_size(evpmd); + + if (bits < 512) { + bits = 512; + } + + bits = (bits + 63) / 64 * 64; + + if (seed_in != NULL) { + if (seed_len < (size_t)qsize) { + return 0; + } + if (seed_len > (size_t)qsize) { + // Only consume as much seed as is expected. + seed_len = qsize; + } + OPENSSL_memcpy(seed, seed_in, seed_len); + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) { + goto err; + } + + for (;;) { + // Find q. + for (;;) { + // step 1 + if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, m++)) { + goto err; + } + + int use_random_seed = (seed_in == NULL); + if (use_random_seed) { + if (!RAND_bytes(seed, qsize)) { + goto err; + } + } else { + // If we come back through, use random seed next time. + seed_in = NULL; + } + OPENSSL_memcpy(buf, seed, qsize); + OPENSSL_memcpy(buf2, seed, qsize); + // precompute "SEED + 1" for step 7: + for (i = qsize - 1; i < qsize; i--) { + buf[i]++; + if (buf[i] != 0) { + break; + } + } + + // step 2 + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) || + !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) { + goto err; + } + for (i = 0; i < qsize; i++) { + md[i] ^= buf2[i]; + } + + // step 3 + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, qsize, q)) { + goto err; + } + + // step 4 + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb); + if (r > 0) { + break; + } + if (r != 0) { + goto err; + } + + // do a callback call + // step 5 + } + + if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) { + goto err; + } + + // step 6 + counter = 0; + // "offset = 2" + + n = (bits - 1) / 160; + + for (;;) { + if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) { + goto err; + } + + // step 7 + BN_zero(W); + // now 'buf' contains "SEED + offset - 1" + for (k = 0; k <= n; k++) { + // obtain "SEED + offset + k" by incrementing: + for (i = qsize - 1; i < qsize; i--) { + buf[i]++; + if (buf[i] != 0) { + break; + } + } + + if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) { + goto err; + } + + // step 8 + if (!BN_bin2bn(md, qsize, r0) || + !BN_lshift(r0, r0, (qsize << 3) * k) || + !BN_add(W, W, r0)) { + goto err; + } + } + + // more of step 8 + if (!BN_mask_bits(W, bits - 1) || + !BN_copy(X, W) || + !BN_add(X, X, test)) { + goto err; + } + + // step 9 + if (!BN_lshift1(r0, q) || + !BN_mod(c, X, r0, ctx) || + !BN_sub(r0, c, BN_value_one()) || + !BN_sub(p, X, r0)) { + goto err; + } + + // step 10 + if (BN_cmp(p, test) >= 0) { + // step 11 + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); + if (r > 0) { + goto end; // found it + } + if (r != 0) { + goto err; + } + } + + // step 13 + counter++; + // "offset = offset + n + 1" + + // step 14 + if (counter >= 4096) { + break; + } + } + } +end: + if (!BN_GENCB_call(cb, 2, 1)) { + goto err; + } + + // We now need to generate g + // Set r0=(p-1)/q + if (!BN_sub(test, p, BN_value_one()) || + !BN_div(r0, NULL, test, q, ctx)) { + goto err; + } + + mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (mont == NULL || + !BN_set_word(test, h)) { + goto err; + } + + for (;;) { + // g=test^r0%p + if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) { + goto err; + } + if (!BN_is_one(g)) { + break; + } + if (!BN_add(test, test, BN_value_one())) { + goto err; + } + h++; + } + + if (!BN_GENCB_call(cb, 3, 1)) { + goto err; + } + + ok = 1; + +err: + if (ok) { + BN_free(dsa->p); + BN_free(dsa->q); + BN_free(dsa->g); + dsa->p = BN_dup(p); + dsa->q = BN_dup(q); + dsa->g = BN_dup(g); + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + ok = 0; + goto err; + } + if (out_counter != NULL) { + *out_counter = counter; + } + if (out_h != NULL) { + *out_h = h; + } + } + + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + BN_MONT_CTX_free(mont); + + return ok; +} + +DSA *DSAparams_dup(const DSA *dsa) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + ret->p = BN_dup(dsa->p); + ret->q = BN_dup(dsa->q); + ret->g = BN_dup(dsa->g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_generate_key(DSA *dsa) { + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + priv_key = dsa->priv_key; + if (priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) { + goto err; + } + } + + if (!BN_rand_range_ex(priv_key, 1, dsa->q)) { + goto err; + } + + pub_key = dsa->pub_key; + if (pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) { + goto err; + } + } + + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, &dsa->method_mont_lock, + dsa->p, ctx) || + !BN_mod_exp_mont_consttime(pub_key, dsa->g, priv_key, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; + ok = 1; + +err: + if (dsa->pub_key == NULL) { + BN_free(pub_key); + } + if (dsa->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + + return ok; +} + +DSA_SIG *DSA_SIG_new(void) { + DSA_SIG *sig; + sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) { + return NULL; + } + sig->r = NULL; + sig->s = NULL; + return sig; +} + +void DSA_SIG_free(DSA_SIG *sig) { + if (!sig) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s) { + if (out_r != NULL) { + *out_r = sig->r; + } + if (out_s != NULL) { + *out_s = sig->s; + } +} + +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + if (r == NULL || s == NULL) { + return 0; + } + BN_free(sig->r); + BN_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +// mod_mul_consttime sets |r| to |a| * |b| modulo |mont->N|, treating |a| and +// |b| as secret. This function internally uses Montgomery reduction, but +// neither inputs nor outputs are in Montgomery form. +static int mod_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + // |BN_mod_mul_montgomery| removes a factor of R, so we cancel it with a + // single |BN_to_montgomery| which adds one factor of R. + int ok = tmp != NULL && + BN_to_montgomery(tmp, a, mont, ctx) && + BN_mod_mul_montgomery(r, tmp, b, mont, ctx); + BN_CTX_end(ctx); + return ok; +} + +DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { + if (!dsa_check_parameters(dsa)) { + return NULL; + } + + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx = NULL; + DSA_SIG *ret = NULL; + + BN_init(&m); + BN_init(&xr); + s = BN_new(); + if (s == NULL) { + goto err; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + +redo: + if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) { + goto err; + } + + if (digest_len > BN_num_bytes(dsa->q)) { + // If the digest length is greater than the size of |dsa->q| use the + // BN_num_bits(dsa->q) leftmost bits of the digest, see FIPS 186-3, 4.2. + // Note the above check that |dsa->q| is a multiple of 8 bits. + digest_len = BN_num_bytes(dsa->q); + } + + if (BN_bin2bn(digest, digest_len, &m) == NULL) { + goto err; + } + + // |m| is bounded by 2^(num_bits(q)), which is slightly looser than q. This + // violates |bn_mod_add_consttime| and |mod_mul_consttime|'s preconditions. + // (The underlying algorithms could accept looser bounds, but we reduce for + // simplicity.) + size_t q_width = bn_minimal_width(dsa->q); + if (!bn_resize_words(&m, q_width) || + !bn_resize_words(&xr, q_width)) { + goto err; + } + bn_reduce_once_in_place(m.d, 0 /* no carry word */, dsa->q->d, + xr.d /* scratch space */, q_width); + + // Compute s = inv(k) (m + xr) mod q. Note |dsa->method_mont_q| is + // initialized by |dsa_sign_setup|. + if (!mod_mul_consttime(&xr, dsa->priv_key, r, dsa->method_mont_q, ctx) || + !bn_mod_add_consttime(s, &xr, &m, dsa->q, ctx) || + !mod_mul_consttime(s, s, kinv, dsa->method_mont_q, ctx)) { + goto err; + } + + // Redo if r or s is zero as required by FIPS 186-3: this is + // very unlikely. + if (BN_is_zero(r) || BN_is_zero(s)) { + goto redo; + } + ret = DSA_SIG_new(); + if (ret == NULL) { + goto err; + } + ret->r = r; + ret->s = s; + +err: + if (ret == NULL) { + OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB); + BN_free(r); + BN_free(s); + } + BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + BN_clear_free(kinv); + + return ret; +} + +int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig, + const DSA *dsa) { + int valid; + if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) { + return -1; + } + return valid; +} + +int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, const DSA *dsa) { + *out_valid = 0; + if (!dsa_check_parameters(dsa)) { + return 0; + } + + int ret = 0; + BIGNUM u1, u2, t1; + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 1; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 1; + goto err; + } + + // Calculate W = inv(S) mod Q + // save W in u2 + if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) { + goto err; + } + + // save M in u1 + unsigned q_bits = BN_num_bits(dsa->q); + if (digest_len > (q_bits >> 3)) { + // if the digest length is greater than the size of q use the + // BN_num_bits(dsa->q) leftmost bits of the digest, see + // fips 186-3, 4.2 + digest_len = (q_bits >> 3); + } + + if (BN_bin2bn(digest, digest_len, &u1) == NULL) { + goto err; + } + + // u1 = M * w mod q + if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) { + goto err; + } + + // u2 = r * w mod q + if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) { + goto err; + } + + if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx)) { + goto err; + } + + if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + // BN_copy(&u1,&t1); + // let u1 = u1 mod q + if (!BN_mod(&u1, &t1, dsa->q, ctx)) { + goto err; + } + + // V is now in u1. If the signature is correct, it will be + // equal to R. + *out_valid = BN_ucmp(&u1, sig->r) == 0; + ret = 1; + +err: + if (ret != 1) { + OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB); + } + BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + + return ret; +} + +int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, const DSA *dsa) { + DSA_SIG *s; + + s = DSA_do_sign(digest, digest_len, dsa); + if (s == NULL) { + *out_siglen = 0; + return 0; + } + + *out_siglen = i2d_DSA_SIG(s, &out_sig); + DSA_SIG_free(s); + return 1; +} + +int DSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const DSA *dsa) { + int valid; + if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) { + return -1; + } + return valid; +} + +int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, size_t sig_len, + const DSA *dsa) { + DSA_SIG *s = NULL; + int ret = 0; + uint8_t *der = NULL; + + s = DSA_SIG_new(); + if (s == NULL) { + goto err; + } + + const uint8_t *sigp = sig; + if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) { + goto err; + } + + // Ensure that the signature uses DER and doesn't have trailing garbage. + int der_len = i2d_DSA_SIG(s, &der); + if (der_len < 0 || (size_t)der_len != sig_len || + OPENSSL_memcmp(sig, der, sig_len)) { + goto err; + } + + ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa); + +err: + OPENSSL_free(der); + DSA_SIG_free(s); + return ret; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +int DSA_size(const DSA *dsa) { + size_t order_len = BN_num_bytes(dsa->q); + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // A DSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv, + BIGNUM **out_r) { + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + int ret = 0; + BIGNUM k; + BN_init(&k); + BIGNUM *r = BN_new(); + BIGNUM *kinv = BN_new(); + if (r == NULL || kinv == NULL || + // Get random k + !BN_rand_range_ex(&k, 1, dsa->q) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q, + ctx) || + // Compute r = (g^k mod p) mod q + !BN_mod_exp_mont_consttime(r, dsa->g, &k, dsa->p, ctx, + dsa->method_mont_p) || + // Note |BN_mod| below is not constant-time and may leak information about + // |r|. |dsa->p| may be significantly larger than |dsa->q|, so this is not + // easily performed in constant-time with Montgomery reduction. + // + // However, |r| at this point is g^k (mod p). It is almost the value of + // |r| revealed in the signature anyway (g^k (mod p) (mod q)), going from + // it to |k| would require computing a discrete log. + !BN_mod(r, r, dsa->q, ctx) || + // Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little + // Theorem. + !bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) { + OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB); + goto err; + } + + BN_clear_free(*out_kinv); + *out_kinv = kinv; + kinv = NULL; + + BN_clear_free(*out_r); + *out_r = r; + r = NULL; + + ret = 1; + +err: + BN_clear_free(&k); + BN_clear_free(r); + BN_clear_free(kinv); + return ret; +} + +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int DSA_set_ex_data(DSA *dsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg); +} + +void *DSA_get_ex_data(const DSA *dsa, int idx) { + return CRYPTO_get_ex_data(&dsa->ex_data, idx); +} + +DH *DSA_dup_DH(const DSA *dsa) { + if (dsa == NULL) { + return NULL; + } + + DH *ret = DH_new(); + if (ret == NULL) { + goto err; + } + if (dsa->q != NULL) { + ret->priv_length = BN_num_bits(dsa->q); + if ((ret->q = BN_dup(dsa->q)) == NULL) { + goto err; + } + } + if ((dsa->p != NULL && (ret->p = BN_dup(dsa->p)) == NULL) || + (dsa->g != NULL && (ret->g = BN_dup(dsa->g)) == NULL) || + (dsa->pub_key != NULL && (ret->pub_key = BN_dup(dsa->pub_key)) == NULL) || + (dsa->priv_key != NULL && + (ret->priv_key = BN_dup(dsa->priv_key)) == NULL)) { + goto err; + } + + return ret; + +err: + DH_free(ret); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c new file mode 100644 index 00000000..cfc11932 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c @@ -0,0 +1,390 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" + + +#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 + +// This function is in dsa_asn1.c rather than dsa.c because it is reachable from +// |EVP_PKEY| parsers. This makes it easier for the static linker to drop most +// of the DSA implementation. +int dsa_check_parameters(const DSA *dsa) { + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + // Reject invalid parameters. In particular, signing will infinite loop if |g| + // is zero. + if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); + return 0; + } + + // FIPS 186-4 allows only three different sizes for q. + unsigned q_bits = BN_num_bits(dsa->q); + if (q_bits != 160 && q_bits != 224 && q_bits != 256) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE); + return 0; + } + + // Bound |dsa->p| to avoid a DoS vector. Note this limit is much larger than + // the one in FIPS 186-4, which only allows L = 1024, 2048, and 3072. + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE); + return 0; + } + + return 1; +} + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DSA object may be missing some components. + OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DSA_SIG *DSA_SIG_parse(CBS *cbs) { + DSA_SIG *ret = DSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->r) || + !parse_integer(&child, &ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, sig->r) || + !marshal_integer(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_public_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + if (!dsa_check_parameters(ret)) { + goto err; + } + return ret; + +err: + DSA_free(ret); + return NULL; +} + +int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_parameters(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + if (!dsa_check_parameters(ret)) { + goto err; + } + return ret; + +err: + DSA_free(ret); + return NULL; +} + +int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_private_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + + if (version != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->priv_key) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + if (!dsa_check_parameters(ret)) { + goto err; + } + return ret; + +err: + DSA_free(ret); + return NULL; +} + +int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, 0 /* version */) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->priv_key) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA_SIG *ret = DSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out_sig != NULL) { + DSA_SIG_free(*out_sig); + *out_sig = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_SIG_marshal(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAparams(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/internal.h new file mode 100644 index 00000000..4de032ab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/dsa/internal.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_DSA_INTERNAL_H +#define OPENSSL_HEADER_DSA_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// dsa_check_parameters checks that |dsa|'s group is within DoS bounds. It +// returns one on success and zero on error. +int dsa_check_parameters(const DSA *dsa); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DSA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c new file mode 100644 index 00000000..aaeffb9d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c @@ -0,0 +1,559 @@ +/* Written by Nils Larsch for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static const unsigned kParametersTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const unsigned kPublicKeyTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; + +EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + CBS ec_private_key, private_key; + uint64_t version; + if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&ec_private_key, &version) || + version != 1 || + !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Parse the optional parameters field. + EC_GROUP *inner_group = NULL; + EC_KEY *ret = NULL; + BIGNUM *priv_key = NULL; + if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) { + // Per SEC 1, as an alternative to omitting it, one is allowed to specify + // this field and put in a NULL to mean inheriting this value. This was + // omitted in a previous version of this logic without problems, so leave it + // unimplemented. + CBS child; + if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + inner_group = EC_KEY_parse_parameters(&child); + if (inner_group == NULL) { + goto err; + } + if (group == NULL) { + group = inner_group; + } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) { + // If a group was supplied externally, it must match. + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + goto err; + } + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + } + + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + goto err; + } + + ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + goto err; + } + + // Although RFC 5915 specifies the length of the key, OpenSSL historically + // got this wrong, so accept any length. See upstream's + // 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. + priv_key = BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL); + ret->pub_key = EC_POINT_new(group); + if (priv_key == NULL || ret->pub_key == NULL || + !EC_KEY_set_private_key(ret, priv_key)) { + goto err; + } + + if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) { + CBS child, public_key; + uint8_t padding; + if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBS_get_u8(&public_key, &padding) || + padding != 0 || + // Explicitly check |public_key| is non-empty to save the conversion + // form later. + CBS_len(&public_key) == 0 || + !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key), + CBS_len(&public_key), NULL) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Save the point conversion form. + // TODO(davidben): Consider removing this. + ret->conv_form = + (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01); + } else { + // Compute the public key instead. + if (!ec_point_mul_scalar_base(group, &ret->pub_key->raw, + &ret->priv_key->scalar)) { + goto err; + } + // Remember the original private-key-only encoding. + // TODO(davidben): Consider removing this. + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + if (CBS_len(&ec_private_key) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Ensure the resulting key is valid. + if (!EC_KEY_check_key(ret)) { + goto err; + } + + BN_free(priv_key); + EC_GROUP_free(inner_group); + return ret; + +err: + EC_KEY_free(ret); + BN_free(priv_key); + EC_GROUP_free(inner_group); + return NULL; +} + +int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags) { + if (key == NULL || key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + CBB ec_private_key, private_key; + if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) || + !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_bn2cbb_padded(&private_key, + BN_num_bytes(EC_GROUP_get0_order(key->group)), + EC_KEY_get0_private_key(key))) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) { + CBB child; + if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) || + !EC_KEY_marshal_curve_name(&child, key->group) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + // TODO(fork): replace this flexibility with sensible default? + if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) { + CBB child, public_key; + if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBB_add_u8(&public_key, 0 /* padding */) || + !EC_POINT_point2cbb(&public_key, key->group, key->pub_key, + key->conv_form, NULL) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + if (!CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +// kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. +static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01}; + +static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a, + CBS *out_b, CBS *out_base_x, + CBS *out_base_y, CBS *out_order) { + // See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an + // ECParameters while RFC 5480 calls it a SpecifiedECDomain. + CBS params, field_id, field_type, curve, base, cofactor; + int has_cofactor; + uint64_t version; + if (!CBS_get_asn1(in, ¶ms, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(¶ms, &version) || + version != 1 || + !CBS_get_asn1(¶ms, &field_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) || + CBS_len(&field_type) != sizeof(kPrimeField) || + OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != + 0 || + !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) || + !CBS_is_unsigned_asn1_integer(out_prime) || + CBS_len(&field_id) != 0 || + !CBS_get_asn1(¶ms, &curve, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) || + // |curve| has an optional BIT STRING seed which we ignore. + !CBS_get_optional_asn1(&curve, NULL, NULL, CBS_ASN1_BITSTRING) || + CBS_len(&curve) != 0 || + !CBS_get_asn1(¶ms, &base, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(¶ms, out_order, CBS_ASN1_INTEGER) || + !CBS_is_unsigned_asn1_integer(out_order) || + !CBS_get_optional_asn1(¶ms, &cofactor, &has_cofactor, + CBS_ASN1_INTEGER) || + CBS_len(¶ms) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + if (has_cofactor) { + // We only support prime-order curves so the cofactor must be one. + if (CBS_len(&cofactor) != 1 || + CBS_data(&cofactor)[0] != 1) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; + } + } + + // Require that the base point use uncompressed form. + uint8_t form; + if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + return 0; + } + + if (CBS_len(&base) % 2 != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + size_t field_len = CBS_len(&base) / 2; + CBS_init(out_base_x, CBS_data(&base), field_len); + CBS_init(out_base_y, CBS_data(&base) + field_len, field_len); + + return 1; +} + +// integers_equal returns one if |a| and |b| are equal, up to leading zeros, and +// zero otherwise. +static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) { + // Remove leading zeros from |a| and |b|. + CBS a_copy = *a; + while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) { + CBS_skip(&a_copy, 1); + } + while (b_len > 0 && b[0] == 0) { + b++; + b_len--; + } + return CBS_mem_equal(&a_copy, b, b_len); +} + +EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { + CBS named_curve; + if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Look for a matching curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (CBS_len(&named_curve) == curve->oid_len && + OPENSSL_memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == + 0) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { + int nid = EC_GROUP_get_curve_name(group); + if (nid == NID_undef) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; + } + + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (curve->nid == nid) { + CBB child; + return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, curve->oid, curve->oid_len) && + CBB_flush(cbb); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; +} + +EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { + if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return EC_KEY_parse_curve_name(cbs); + } + + // OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions + // of named curves. + // + // TODO(davidben): Remove support for this. + CBS prime, a, b, base_x, base_y, order; + if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y, + &order)) { + return NULL; + } + + // Look for a matching prime curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + const unsigned param_len = curve->param_len; + // |curve->params| is ordered p, a, b, x, y, order, each component + // zero-padded up to the field length. Although SEC 1 states that the + // Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes + // |a| and |b|, so this comparison must allow omitting leading zeros. (This + // is relevant for P-521 whose |b| has a leading 0.) + if (integers_equal(&prime, curve->params, param_len) && + integers_equal(&a, curve->params + param_len, param_len) && + integers_equal(&b, curve->params + param_len * 2, param_len) && + integers_equal(&base_x, curve->params + param_len * 3, param_len) && + integers_equal(&base_y, curve->params + param_len * 4, param_len) && + integers_equal(&order, curve->params + param_len * 5, param_len)) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) { + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *p; + return CBB_add_space(out, &p, len) && + EC_POINT_point2oct(group, point, form, p, len, ctx) == len; +} + +EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) { + // This function treats its |out| parameter differently from other |d2i| + // functions. If supplied, take the group from |*out|. + const EC_GROUP *group = NULL; + if (out != NULL && *out != NULL) { + group = EC_KEY_get0_group(*out); + } + + if (len < 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + EC_KEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_GROUP *group = EC_KEY_parse_parameters(&cbs); + if (group == NULL) { + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + EC_GROUP_free(group); + EC_KEY_free(ret); + return NULL; + } + EC_GROUP_free(group); + + if (out_key != NULL) { + EC_KEY_free(*out_key); + *out_key = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_curve_name(&cbb, key->group)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { + EC_KEY *ret = NULL; + + if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + ret = *keyp; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + return NULL; + } + // save the point conversion form + ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01); + *inp += len; + return ret; +} + +int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { + size_t buf_len = 0; + int new_buffer = 0; + + if (key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, + 0, NULL); + + if (outp == NULL || buf_len == 0) { + // out == NULL => just return the length of the octet string + return buf_len; + } + + if (*outp == NULL) { + *outp = OPENSSL_malloc(buf_len); + if (*outp == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, + buf_len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + if (new_buffer) { + OPENSSL_free(*outp); + *outp = NULL; + } + return 0; + } + + if (!new_buffer) { + *outp += buf_len; + } + return buf_len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_derive.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_derive.c new file mode 100644 index 00000000..ef692e5e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/ec_derive.c @@ -0,0 +1,95 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" + + +EC_KEY *EC_KEY_derive_from_secret(const EC_GROUP *group, const uint8_t *secret, + size_t secret_len) { +#define EC_KEY_DERIVE_MAX_NAME_LEN 16 + const char *name = EC_curve_nid2nist(EC_GROUP_get_curve_name(group)); + if (name == NULL || strlen(name) > EC_KEY_DERIVE_MAX_NAME_LEN) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; + } + + // Assemble a label string to provide some key separation in case |secret| is + // misused, but ultimately it's on the caller to ensure |secret| is suitably + // separated. + static const char kLabel[] = "derive EC key "; + char info[sizeof(kLabel) + EC_KEY_DERIVE_MAX_NAME_LEN]; + OPENSSL_strlcpy(info, kLabel, sizeof(info)); + OPENSSL_strlcat(info, name, sizeof(info)); + + // Generate 128 bits beyond the group order so the bias is at most 2^-128. +#define EC_KEY_DERIVE_EXTRA_BITS 128 +#define EC_KEY_DERIVE_EXTRA_BYTES (EC_KEY_DERIVE_EXTRA_BITS / 8) + + if (EC_GROUP_order_bits(group) <= EC_KEY_DERIVE_EXTRA_BITS + 8) { + // The reduction strategy below requires the group order be large enough. + // (The actual bound is a bit tighter, but our curves are much larger than + // 128-bit.) + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return NULL; + } + + uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES]; + size_t derived_len = BN_num_bytes(&group->order) + EC_KEY_DERIVE_EXTRA_BYTES; + assert(derived_len <= sizeof(derived)); + if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len, + /*salt=*/NULL, /*salt_len=*/0, (const uint8_t *)info, + strlen(info))) { + return NULL; + } + + EC_KEY *key = EC_KEY_new(); + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *priv = BN_bin2bn(derived, derived_len, NULL); + EC_POINT *pub = EC_POINT_new(group); + if (key == NULL || ctx == NULL || priv == NULL || pub == NULL || + // Reduce |priv| with Montgomery reduction. First, convert "from" + // Montgomery form to compute |priv| * R^-1 mod |order|. This requires + // |priv| be under order * R, which is true if the group order is large + // enough. 2^(num_bytes(order)) < 2^8 * order, so: + // + // priv < 2^8 * order * 2^128 < order * order < order * R + !BN_from_montgomery(priv, priv, group->order_mont, ctx) || + // Multiply by R^2 and do another Montgomery reduction to compute + // priv * R^-1 * R^2 * R^-1 = priv mod order. + !BN_to_montgomery(priv, priv, group->order_mont, ctx) || + !EC_POINT_mul(group, pub, priv, NULL, NULL, ctx) || + !EC_KEY_set_group(key, group) || !EC_KEY_set_public_key(key, pub) || + !EC_KEY_set_private_key(key, priv)) { + EC_KEY_free(key); + key = NULL; + goto err; + } + +err: + OPENSSL_cleanse(derived, sizeof(derived)); + BN_CTX_free(ctx); + BN_free(priv); + EC_POINT_free(pub); + return key; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c new file mode 100644 index 00000000..6f1e388c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c @@ -0,0 +1,385 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include + +#include "internal.h" +#include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +// This file implements hash-to-curve, as described in +// draft-irtf-cfrg-hash-to-curve-07. +// +// This hash-to-curve implementation is written generically with the +// expectation that we will eventually wish to support other curves. If it +// becomes a performance bottleneck, some possible optimizations by +// specializing it to the curve: +// +// - Rather than using a generic |felem_exp|, specialize the exponentation to +// c2 with a faster addition chain. +// +// - |felem_mul| and |felem_sqr| are indirect calls to generic Montgomery +// code. Given the few curves, we could specialize +// |map_to_curve_simple_swu|. But doing this reasonably without duplicating +// code in C is difficult. (C++ templates would be useful here.) +// +// - P-521's Z and c2 have small power-of-two absolute values. We could save +// two multiplications in SSWU. (Other curves have reasonable values of Z +// and inconvenient c2.) This is unlikely to be worthwhile without C++ +// templates to make specializing more convenient. + +// expand_message_xmd implements the operation described in section 5.3.1 of +// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on +// allocation failure or if |out_len| was too large. +static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, + const uint8_t *msg, size_t msg_len, + const uint8_t *dst, size_t dst_len) { + int ret = 0; + const size_t block_size = EVP_MD_block_size(md); + const size_t md_size = EVP_MD_size(md); + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + + // Long DSTs are hashed down to size. See section 5.3.3. + OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, "hashed DST still too large"); + uint8_t dst_buf[EVP_MAX_MD_SIZE]; + if (dst_len >= 256) { + static const char kPrefix[] = "H2C-OVERSIZE-DST-"; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, kPrefix, sizeof(kPrefix) - 1) || + !EVP_DigestUpdate(&ctx, dst, dst_len) || + !EVP_DigestFinal_ex(&ctx, dst_buf, NULL)) { + goto err; + } + dst = dst_buf; + dst_len = md_size; + } + uint8_t dst_len_u8 = (uint8_t)dst_len; + + // Compute b_0. + static const uint8_t kZeros[EVP_MAX_MD_BLOCK_SIZE] = {0}; + // If |out_len| exceeds 16 bits then |i| will wrap below causing an error to + // be returned. This depends on the static assert above. + uint8_t l_i_b_str_zero[3] = {out_len >> 8, out_len, 0}; + uint8_t b_0[EVP_MAX_MD_SIZE]; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, kZeros, block_size) || + !EVP_DigestUpdate(&ctx, msg, msg_len) || + !EVP_DigestUpdate(&ctx, l_i_b_str_zero, sizeof(l_i_b_str_zero)) || + !EVP_DigestUpdate(&ctx, dst, dst_len) || + !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) || + !EVP_DigestFinal_ex(&ctx, b_0, NULL)) { + goto err; + } + + uint8_t b_i[EVP_MAX_MD_SIZE]; + uint8_t i = 1; + while (out_len > 0) { + if (i == 0) { + // Input was too large. + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + if (i > 1) { + for (size_t j = 0; j < md_size; j++) { + b_i[j] ^= b_0[j]; + } + } else { + OPENSSL_memcpy(b_i, b_0, md_size); + } + + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, b_i, md_size) || + !EVP_DigestUpdate(&ctx, &i, 1) || + !EVP_DigestUpdate(&ctx, dst, dst_len) || + !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) || + !EVP_DigestFinal_ex(&ctx, b_i, NULL)) { + goto err; + } + + size_t todo = out_len >= md_size ? md_size : out_len; + OPENSSL_memcpy(out, b_i, todo); + out += todo; + out_len -= todo; + i++; + } + + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +// num_bytes_to_derive determines the number of bytes to derive when hashing to +// a number modulo |modulus|. See the hash_to_field operation defined in +// section 5.2 of draft-irtf-cfrg-hash-to-curve-07. +static int num_bytes_to_derive(size_t *out, const BIGNUM *modulus, unsigned k) { + size_t bits = BN_num_bits(modulus); + size_t L = (bits + k + 7) / 8; + // We require 2^(8*L) < 2^(2*bits - 2) <= n^2 so to fit in bounds for + // |felem_reduce| and |ec_scalar_reduce|. All defined hash-to-curve suites + // define |k| to be well under this bound. (|k| is usually around half of + // |p_bits|.) + if (L * 8 >= 2 * bits - 2 || + L > 2 * EC_MAX_BYTES) { + assert(0); + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out = L; + return 1; +} + +// big_endian_to_words decodes |in| as a big-endian integer and writes the +// result to |out|. |num_words| must be large enough to contain the output. +static void big_endian_to_words(BN_ULONG *out, size_t num_words, + const uint8_t *in, size_t len) { + assert(len <= num_words * sizeof(BN_ULONG)); + // Ensure any excess bytes are zeroed. + OPENSSL_memset(out, 0, num_words * sizeof(BN_ULONG)); + uint8_t *out_u8 = (uint8_t *)out; + for (size_t i = 0; i < len; i++) { + out_u8[len - 1 - i] = in[i]; + } +} + +// hash_to_field implements the operation described in section 5.2 +// of draft-irtf-cfrg-hash-to-curve-07, with count = 2. |k| is the security +// factor. +static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md, + EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst, + size_t dst_len, unsigned k, const uint8_t *msg, + size_t msg_len) { + size_t L; + uint8_t buf[4 * EC_MAX_BYTES]; + if (!num_bytes_to_derive(&L, &group->field, k) || + !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) { + return 0; + } + BN_ULONG words[2 * EC_MAX_WORDS]; + size_t num_words = 2 * group->field.width; + big_endian_to_words(words, num_words, buf, L); + group->meth->felem_reduce(group, out1, words, num_words); + big_endian_to_words(words, num_words, buf + L, L); + group->meth->felem_reduce(group, out2, words, num_words); + return 1; +} + +// hash_to_scalar behaves like |hash_to_field2| but returns a value modulo the +// group order rather than a field element. |k| is the security factor. +static int hash_to_scalar(const EC_GROUP *group, const EVP_MD *md, + EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + unsigned k, const uint8_t *msg, size_t msg_len) { + size_t L; + uint8_t buf[EC_MAX_BYTES * 2]; + if (!num_bytes_to_derive(&L, &group->order, k) || + !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) { + return 0; + } + + BN_ULONG words[2 * EC_MAX_WORDS]; + size_t num_words = 2 * group->order.width; + big_endian_to_words(words, num_words, buf, L); + ec_scalar_reduce(group, out, words, num_words); + return 1; +} + +static inline void mul_A(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *in) { + assert(group->a_is_minus3); + EC_FELEM tmp; + ec_felem_add(group, &tmp, in, in); // tmp = 2*in + ec_felem_add(group, &tmp, &tmp, &tmp); // tmp = 4*in + ec_felem_sub(group, out, in, &tmp); // out = -3*in +} + +static inline void mul_minus_A(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *in) { + assert(group->a_is_minus3); + EC_FELEM tmp; + ec_felem_add(group, &tmp, in, in); // tmp = 2*in + ec_felem_add(group, out, &tmp, in); // out = 3*in +} + +// sgn0_le implements the operation described in section 4.1.2 of +// draft-irtf-cfrg-hash-to-curve-07. +static BN_ULONG sgn0_le(const EC_GROUP *group, const EC_FELEM *a) { + uint8_t buf[EC_MAX_BYTES]; + size_t len; + ec_felem_to_bytes(group, buf, &len, a); + return buf[len - 1] & 1; +} + +// map_to_curve_simple_swu implements the operation described in section 6.6.2 +// of draft-irtf-cfrg-hash-to-curve-07, using the optimization in appendix +// D.2.1. It returns one on success and zero on error. +static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, + const BN_ULONG *c1, size_t num_c1, + const EC_FELEM *c2, EC_RAW_POINT *out, + const EC_FELEM *u) { + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + // This function requires the prime be 3 mod 4, and that A = -3. + if (group->field.width == 0 || (group->field.d[0] & 3) != 3 || + !group->a_is_minus3) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + EC_FELEM tv1, tv2, tv3, tv4, xd, x1n, x2n, tmp, gxd, gx1, y1, y2; + felem_sqr(group, &tv1, u); // tv1 = u^2 + felem_mul(group, &tv3, Z, &tv1); // tv3 = Z * tv1 + felem_sqr(group, &tv2, &tv3); // tv2 = tv3^2 + ec_felem_add(group, &xd, &tv2, &tv3); // xd = tv2 + tv3 + ec_felem_add(group, &x1n, &xd, &group->one); // x1n = xd + 1 + felem_mul(group, &x1n, &x1n, &group->b); // x1n = x1n * B + mul_minus_A(group, &xd, &xd); // xd = -A * xd + BN_ULONG e1 = ec_felem_non_zero_mask(group, &xd); // e1 = xd == 0 [flipped] + mul_A(group, &tmp, Z); + ec_felem_select(group, &xd, e1, &xd, &tmp); // xd = CMOV(xd, Z * A, e1) + felem_sqr(group, &tv2, &xd); // tv2 = xd^2 + felem_mul(group, &gxd, &tv2, &xd); // gxd = tv2 * xd = xd^3 + mul_A(group, &tv2, &tv2); // tv2 = A * tv2 + felem_sqr(group, &gx1, &x1n); // gx1 = x1n^2 + ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 + felem_mul(group, &gx1, &gx1, &x1n); // gx1 = gx1 * x1n + felem_mul(group, &tv2, &group->b, &gxd); // tv2 = B * gxd + ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 + felem_sqr(group, &tv4, &gxd); // tv4 = gxd^2 + felem_mul(group, &tv2, &gx1, &gxd); // tv2 = gx1 * gxd + felem_mul(group, &tv4, &tv4, &tv2); // tv4 = tv4 * tv2 + group->meth->felem_exp(group, &y1, &tv4, c1, num_c1); // y1 = tv4^c1 + felem_mul(group, &y1, &y1, &tv2); // y1 = y1 * tv2 + felem_mul(group, &x2n, &tv3, &x1n); // x2n = tv3 * x1n + felem_mul(group, &y2, &y1, c2); // y2 = y1 * c2 + felem_mul(group, &y2, &y2, &tv1); // y2 = y2 * tv1 + felem_mul(group, &y2, &y2, u); // y2 = y2 * u + felem_sqr(group, &tv2, &y1); // tv2 = y1^2 + felem_mul(group, &tv2, &tv2, &gxd); // tv2 = tv2 * gxd + ec_felem_sub(group, &tv3, &tv2, &gx1); + BN_ULONG e2 = + ec_felem_non_zero_mask(group, &tv3); // e2 = tv2 == gx1 [flipped] + ec_felem_select(group, &x1n, e2, &x2n, &x1n); // xn = CMOV(x2n, x1n, e2) + ec_felem_select(group, &y1, e2, &y2, &y1); // y = CMOV(y2, y1, e2) + BN_ULONG sgn0_u = sgn0_le(group, u); + BN_ULONG sgn0_y = sgn0_le(group, &y1); + BN_ULONG e3 = sgn0_u ^ sgn0_y; + e3 = ((BN_ULONG)0) - e3; // e3 = sgn0(u) == sgn0(y) [flipped] + ec_felem_neg(group, &y2, &y1); + ec_felem_select(group, &y1, e3, &y2, &y1); // y = CMOV(-y, y, e3) + + // Appendix D.1 describes how to convert (x1n, xd, y1, 1) to Jacobian + // coordinates. Note yd = 1. Also note that gxd computed above is xd^3. + felem_mul(group, &out->X, &x1n, &xd); // X = xn * xd + felem_mul(group, &out->Y, &y1, &gxd); // Y = yn * gxd = yn * xd^3 + out->Z = xd; // Z = xd + return 1; +} + +static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, + const EC_FELEM *Z, const EC_FELEM *c2, unsigned k, + EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + EC_FELEM u0, u1; + if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) { + return 0; + } + + // Compute |c1| = (p - 3) / 4. + BN_ULONG c1[EC_MAX_WORDS]; + size_t num_c1 = group->field.width; + if (!bn_copy_words(c1, num_c1, &group->field)) { + return 0; + } + bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1); + + EC_RAW_POINT Q0, Q1; + if (!map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0) || + !map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1)) { + return 0; + } + + group->meth->add(group, out, &Q0, &Q1); // R = Q0 + Q1 + // All our curves have cofactor one, so |clear_cofactor| is a no-op. + return 1; +} + +static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) { + uint8_t bytes[EC_MAX_BYTES] = {0}; + size_t len = BN_num_bytes(&group->field); + bytes[len - 1] = a; + return ec_felem_from_bytes(group, out, bytes, len); +} + +int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, size_t msg_len) { + // See section 8.3 of draft-irtf-cfrg-hash-to-curve-07. + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + // kSqrt1728 was computed as follows in python3: + // + // p = 2**384 - 2**128 - 2**96 + 2**32 - 1 + // z3 = 12**3 + // c2 = pow(z3, (p+1)//4, p) + // assert z3 == pow(c2, 2, p) + // ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big') + + static const uint8_t kSqrt1728[] = { + 0x01, 0x98, 0x77, 0xcc, 0x10, 0x41, 0xb7, 0x55, 0x57, 0x43, 0xc0, 0xae, + 0x2e, 0x3a, 0x3e, 0x61, 0xfb, 0x2a, 0xaa, 0x2e, 0x0e, 0x87, 0xea, 0x55, + 0x7a, 0x56, 0x3d, 0x8b, 0x59, 0x8a, 0x09, 0x40, 0xd0, 0xa6, 0x97, 0xa9, + 0xe0, 0xb9, 0xe9, 0x2c, 0xfa, 0xa3, 0x14, 0xf5, 0x83, 0xc9, 0xd0, 0x66 + }; + + // Z = -12, c2 = sqrt(1728) + EC_FELEM Z, c2; + if (!felem_from_u8(group, &Z, 12) || + !ec_felem_from_bytes(group, &c2, kSqrt1728, sizeof(kSqrt1728))) { + return 0; + } + ec_felem_neg(group, &Z, &Z); + + return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst, + dst_len, msg, msg_len); +} + +int ec_hash_to_scalar_p384_xmd_sha512_draft07( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/192, msg, + msg_len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h new file mode 100644 index 00000000..52bd74d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ec_extra/internal.h @@ -0,0 +1,56 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_EC_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_EC_EXTRA_INTERNAL_H + +#include + +#include "../fipsmodule/ec/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Hash-to-curve. +// +// The following functions implement primitives from +// draft-irtf-cfrg-hash-to-curve. The |dst| parameter in each function is the +// domain separation tag and must be unique for each protocol and between the +// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec +// for additional guidance on this parameter. + +// ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 hashes |msg| to a point on +// |group| and writes the result to |out|, implementing the +// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, size_t msg_len); + +// ec_hash_to_scalar_p384_xmd_sha512_draft07 hashes |msg| to a scalar on |group| +// and writes the result to |out|, using the hash_to_field operation from the +// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07, but +// generating a value modulo the group order rather than a field element. +OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EC_EXTRA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdh_extra/ecdh_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdh_extra/ecdh_extra.c new file mode 100644 index 00000000..a117fdad --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdh_extra/ecdh_extra.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDH_compute_key(void *out, size_t out_len, const EC_POINT *pub_key, + const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, + size_t *out_len)) { + if (priv_key->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); + return -1; + } + const EC_SCALAR *const priv = &priv_key->priv_key->scalar; + const EC_GROUP *const group = EC_KEY_get0_group(priv_key); + if (EC_GROUP_cmp(group, pub_key->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + + EC_RAW_POINT shared_point; + uint8_t buf[EC_MAX_BYTES]; + size_t buf_len; + if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) || + !ec_get_x_coordinate_as_bytes(group, buf, &buf_len, sizeof(buf), + &shared_point)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + return -1; + } + + if (kdf != NULL) { + if (kdf(buf, buf_len, out, &out_len) == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED); + return -1; + } + } else { + // no KDF, just copy as much as we can + if (buf_len < out_len) { + out_len = buf_len; + } + OPENSSL_memcpy(out, buf, out_len); + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_OVERFLOW); + return -1; + } + + return (int)out_len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c new file mode 100644 index 00000000..bd71fa1b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c @@ -0,0 +1,267 @@ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../bytestring/internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *eckey) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, + (EC_KEY*) eckey /* cast away const */); + } + + int ret = 0; + ECDSA_SIG *s = ECDSA_do_sign(digest, digest_len, eckey); + if (s == NULL) { + *sig_len = 0; + goto err; + } + + CBB cbb; + CBB_zero(&cbb); + size_t len; + if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || + !ECDSA_SIG_marshal(&cbb, s) || + !CBB_finish(&cbb, NULL, &len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + *sig_len = 0; + goto err; + } + *sig_len = (unsigned)len; + ret = 1; + +err: + ECDSA_SIG_free(s); + return ret; +} + +int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { + ECDSA_SIG *s; + int ret = 0; + uint8_t *der = NULL; + + // Decode the ECDSA signature. + s = ECDSA_SIG_from_bytes(sig, sig_len); + if (s == NULL) { + goto err; + } + + // Defend against potential laxness in the DER parser. + size_t der_len; + if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || + der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { + // This should never happen. crypto/bytestring is strictly DER. + OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = ECDSA_do_verify(digest, digest_len, s, eckey); + +err: + OPENSSL_free(der); + ECDSA_SIG_free(s); + return ret; +} + + +size_t ECDSA_size(const EC_KEY *key) { + if (key == NULL) { + return 0; + } + + size_t group_order_size; + if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { + group_order_size = key->ecdsa_meth->group_order_size(key); + } else { + const EC_GROUP *group = EC_KEY_get0_group(key); + if (group == NULL) { + return 0; + } + + group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); + } + + return ECDSA_SIG_max_len(group_order_size); +} + +ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !BN_parse_asn1_unsigned(&child, ret->r) || + !BN_parse_asn1_unsigned(&child, ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !BN_marshal_asn1(&child, sig->r) || + !BN_marshal_asn1(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +size_t ECDSA_SIG_max_len(size_t order_len) { + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // An ECDSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + ECDSA_SIG_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/engine/engine.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/engine/engine.c new file mode 100644 index 00000000..1fc0e79f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/engine/engine.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" + + +struct engine_st { + RSA_METHOD *rsa_method; + ECDSA_METHOD *ecdsa_method; +}; + +ENGINE *ENGINE_new(void) { + ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE)); + if (engine == NULL) { + return NULL; + } + + OPENSSL_memset(engine, 0, sizeof(ENGINE)); + return engine; +} + +int ENGINE_free(ENGINE *engine) { + // Methods are currently required to be static so are not unref'ed. + OPENSSL_free(engine); + return 1; +} + +// set_method takes a pointer to a method and its given size and sets +// |*out_member| to point to it. This function might want to be extended in the +// future to support making a copy of the method so that a stable ABI for +// ENGINEs can be supported. But, for the moment, all *_METHODS must be +// static. +static int set_method(void **out_member, const void *method, size_t method_size, + size_t compiled_size) { + const struct openssl_method_common_st *common = method; + if (method_size != compiled_size || !common->is_static) { + return 0; + } + + *out_member = (void*) method; + return 1; +} + +int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->rsa_method, method, method_size, + sizeof(RSA_METHOD)); +} + +RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { + return engine->rsa_method; +} + +int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->ecdsa_method, method, method_size, + sizeof(ECDSA_METHOD)); +} + +ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { + return engine->ecdsa_method; +} + +void METHOD_ref(void *method_in) { + assert(((struct openssl_method_common_st*) method_in)->is_static); +} + +void METHOD_unref(void *method_in) { + struct openssl_method_common_st *method = method_in; + + if (method == NULL) { + return; + } + assert(method->is_static); +} + +OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err.c new file mode 100644 index 00000000..bf493b06 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err.c @@ -0,0 +1,873 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +struct err_error_st { + // file contains the filename where the error occurred. + const char *file; + // data contains a NUL-terminated string with optional data. It must be freed + // with |OPENSSL_free|. + char *data; + // packed contains the error library and reason, as packed by ERR_PACK. + uint32_t packed; + // line contains the line number where the error occurred. + uint16_t line; + // mark indicates a reversion point in the queue. See |ERR_pop_to_mark|. + unsigned mark : 1; +}; + +// ERR_STATE contains the per-thread, error queue. +typedef struct err_state_st { + // errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring + // buffer. + struct err_error_st errors[ERR_NUM_ERRORS]; + // top contains the index one past the most recent error. If |top| equals + // |bottom| then the queue is empty. + unsigned top; + // bottom contains the index of the last error in the queue. + unsigned bottom; + + // to_free, if not NULL, contains a pointer owned by this structure that was + // previously a |data| pointer of one of the elements of |errors|. + void *to_free; +} ERR_STATE; + +extern const uint32_t kOpenSSLReasonValues[]; +extern const size_t kOpenSSLReasonValuesLen; +extern const char kOpenSSLReasonStringData[]; + +// err_clear clears the given queued error. +static void err_clear(struct err_error_st *error) { + OPENSSL_free(error->data); + OPENSSL_memset(error, 0, sizeof(struct err_error_st)); +} + +static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { + err_clear(dst); + dst->file = src->file; + if (src->data != NULL) { + dst->data = OPENSSL_strdup(src->data); + } + dst->packed = src->packed; + dst->line = src->line; +} + +// global_next_library contains the next custom library value to return. +static int global_next_library = ERR_NUM_LIBS; + +// global_next_library_mutex protects |global_next_library| from concurrent +// updates. +static struct CRYPTO_STATIC_MUTEX global_next_library_mutex = + CRYPTO_STATIC_MUTEX_INIT; + +static void err_state_free(void *statep) { + ERR_STATE *state = statep; + + if (state == NULL) { + return; + } + + for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + OPENSSL_free(state); +} + +// err_get_state gets the ERR_STATE object for the current thread. +static ERR_STATE *err_get_state(void) { + ERR_STATE *state = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR); + if (state == NULL) { + state = OPENSSL_malloc(sizeof(ERR_STATE)); + if (state == NULL) { + return NULL; + } + OPENSSL_memset(state, 0, sizeof(ERR_STATE)); + if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_ERR, state, + err_state_free)) { + return NULL; + } + } + + return state; +} + +static uint32_t get_error_values(int inc, int top, const char **file, int *line, + const char **data, int *flags) { + unsigned i = 0; + ERR_STATE *state; + struct err_error_st *error; + uint32_t ret; + + state = err_get_state(); + if (state == NULL || state->bottom == state->top) { + return 0; + } + + if (top) { + assert(!inc); + // last error + i = state->top; + } else { + i = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[i]; + ret = error->packed; + + if (file != NULL && line != NULL) { + if (error->file == NULL) { + *file = "NA"; + *line = 0; + } else { + *file = error->file; + *line = error->line; + } + } + + if (data != NULL) { + if (error->data == NULL) { + *data = ""; + if (flags != NULL) { + *flags = 0; + } + } else { + *data = error->data; + if (flags != NULL) { + *flags = ERR_FLAG_STRING; + } + // If this error is being removed, take ownership of data from + // the error. The semantics are such that the caller doesn't + // take ownership either. Instead the error system takes + // ownership and retains it until the next call that affects the + // error queue. + if (inc) { + if (error->data != NULL) { + OPENSSL_free(state->to_free); + state->to_free = error->data; + } + error->data = NULL; + } + } + } + + if (inc) { + assert(!top); + err_clear(error); + state->bottom = i; + } + + return ret; +} + +uint32_t ERR_get_error(void) { + return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_get_error_line(const char **file, int *line) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags); +} + +uint32_t ERR_peek_error(void) { + return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data, + flags); +} + +uint32_t ERR_peek_last_error(void) { + return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags); +} + +void ERR_clear_error(void) { + ERR_STATE *const state = err_get_state(); + unsigned i; + + if (state == NULL) { + return; + } + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + state->to_free = NULL; + + state->top = state->bottom = 0; +} + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid) { + if (tid != NULL) { + assert(0); + return; + } + + ERR_clear_error(); +} + +int ERR_get_next_error_library(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex); + ret = global_next_library++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex); + + return ret; +} + +void ERR_remove_state(unsigned long pid) { + ERR_clear_error(); +} + +void ERR_clear_system_error(void) { + errno = 0; +} + +// err_string_cmp is a compare function for searching error values with +// |bsearch| in |err_string_lookup|. +static int err_string_cmp(const void *a, const void *b) { + const uint32_t a_key = *((const uint32_t*) a) >> 15; + const uint32_t b_key = *((const uint32_t*) b) >> 15; + + if (a_key < b_key) { + return -1; + } else if (a_key > b_key) { + return 1; + } else { + return 0; + } +} + +// err_string_lookup looks up the string associated with |lib| and |key| in +// |values| and |string_data|. It returns the string or NULL if not found. +static const char *err_string_lookup(uint32_t lib, uint32_t key, + const uint32_t *values, + size_t num_values, + const char *string_data) { + // |values| points to data in err_data.h, which is generated by + // err_data_generate.go. It's an array of uint32_t values. Each value has the + // following structure: + // | lib | key | offset | + // |6 bits| 11 bits | 15 bits | + // + // The |lib| value is a library identifier: one of the |ERR_LIB_*| values. + // The |key| is a reason code, depending on the context. + // The |offset| is the number of bytes from the start of |string_data| where + // the (NUL terminated) string for this value can be found. + // + // Values are sorted based on treating the |lib| and |key| part as an + // unsigned integer. + if (lib >= (1 << 6) || key >= (1 << 11)) { + return NULL; + } + uint32_t search_key = lib << 26 | key << 15; + const uint32_t *result = bsearch(&search_key, values, num_values, + sizeof(uint32_t), err_string_cmp); + if (result == NULL) { + return NULL; + } + + return &string_data[(*result) & 0x7fff]; +} + +static const char *const kLibraryNames[ERR_NUM_LIBS] = { + "invalid library (0)", + "unknown library", // ERR_LIB_NONE + "system library", // ERR_LIB_SYS + "bignum routines", // ERR_LIB_BN + "RSA routines", // ERR_LIB_RSA + "Diffie-Hellman routines", // ERR_LIB_DH + "public key routines", // ERR_LIB_EVP + "memory buffer routines", // ERR_LIB_BUF + "object identifier routines", // ERR_LIB_OBJ + "PEM routines", // ERR_LIB_PEM + "DSA routines", // ERR_LIB_DSA + "X.509 certificate routines", // ERR_LIB_X509 + "ASN.1 encoding routines", // ERR_LIB_ASN1 + "configuration file routines", // ERR_LIB_CONF + "common libcrypto routines", // ERR_LIB_CRYPTO + "elliptic curve routines", // ERR_LIB_EC + "SSL routines", // ERR_LIB_SSL + "BIO routines", // ERR_LIB_BIO + "PKCS7 routines", // ERR_LIB_PKCS7 + "PKCS8 routines", // ERR_LIB_PKCS8 + "X509 V3 routines", // ERR_LIB_X509V3 + "random number generator", // ERR_LIB_RAND + "ENGINE routines", // ERR_LIB_ENGINE + "OCSP routines", // ERR_LIB_OCSP + "UI routines", // ERR_LIB_UI + "COMP routines", // ERR_LIB_COMP + "ECDSA routines", // ERR_LIB_ECDSA + "ECDH routines", // ERR_LIB_ECDH + "HMAC routines", // ERR_LIB_HMAC + "Digest functions", // ERR_LIB_DIGEST + "Cipher functions", // ERR_LIB_CIPHER + "HKDF functions", // ERR_LIB_HKDF + "Trust Token functions", // ERR_LIB_TRUST_TOKEN + "User defined functions", // ERR_LIB_USER +}; + +static const char *err_lib_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + + if (lib >= ERR_NUM_LIBS) { + return NULL; + } + return kLibraryNames[lib]; +} + +const char *ERR_lib_error_string(uint32_t packed_error) { + const char *ret = err_lib_error_string(packed_error); + return ret == NULL ? "unknown library" : ret; +} + +const char *ERR_func_error_string(uint32_t packed_error) { + return "OPENSSL_internal"; +} + +static const char *err_reason_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + const uint32_t reason = ERR_GET_REASON(packed_error); + + if (lib == ERR_LIB_SYS) { + if (reason < 127) { + return strerror(reason); + } + return NULL; + } + + if (reason < ERR_NUM_LIBS) { + return kLibraryNames[reason]; + } + + if (reason < 100) { + switch (reason) { + case ERR_R_MALLOC_FAILURE: + return "malloc failure"; + case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED: + return "function should not have been called"; + case ERR_R_PASSED_NULL_PARAMETER: + return "passed a null parameter"; + case ERR_R_INTERNAL_ERROR: + return "internal error"; + case ERR_R_OVERFLOW: + return "overflow"; + default: + return NULL; + } + } + + return err_string_lookup(lib, reason, kOpenSSLReasonValues, + kOpenSSLReasonValuesLen, kOpenSSLReasonStringData); +} + +const char *ERR_reason_error_string(uint32_t packed_error) { + const char *ret = err_reason_error_string(packed_error); + return ret == NULL ? "unknown error" : ret; +} + +char *ERR_error_string(uint32_t packed_error, char *ret) { + static char buf[ERR_ERROR_STRING_BUF_LEN]; + + if (ret == NULL) { + // TODO(fork): remove this. + ret = buf; + } + +#if !defined(NDEBUG) + // This is aimed to help catch callers who don't provide + // |ERR_ERROR_STRING_BUF_LEN| bytes of space. + OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN); +#endif + + return ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN); +} + +char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { + if (len == 0) { + return NULL; + } + + unsigned lib = ERR_GET_LIB(packed_error); + unsigned reason = ERR_GET_REASON(packed_error); + + const char *lib_str = err_lib_error_string(packed_error); + const char *reason_str = err_reason_error_string(packed_error); + + char lib_buf[64], reason_buf[64]; + if (lib_str == NULL) { + BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib); + lib_str = lib_buf; + } + + if (reason_str == NULL) { + BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason); + reason_str = reason_buf; + } + + BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:OPENSSL_internal:%s", + packed_error, lib_str, reason_str); + + if (strlen(buf) == len - 1) { + // output may be truncated; make sure we always have 5 colon-separated + // fields, i.e. 4 colons. + static const unsigned num_colons = 4; + unsigned i; + char *s = buf; + + if (len <= num_colons) { + // In this situation it's not possible to ensure that the correct number + // of colons are included in the output. + return buf; + } + + for (i = 0; i < num_colons; i++) { + char *colon = strchr(s, ':'); + char *last_pos = &buf[len - 1] - num_colons + i; + + if (colon == NULL || colon > last_pos) { + // set colon |i| at last possible position (buf[len-1] is the + // terminating 0). If we're setting this colon, then all whole of the + // rest of the string must be colons in order to have the correct + // number. + OPENSSL_memset(last_pos, ':', num_colons - i); + break; + } + + s = colon + 1; + } + } + + return buf; +} + +void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) { + char buf[ERR_ERROR_STRING_BUF_LEN]; + char buf2[1024]; + const char *file, *data; + int line, flags; + uint32_t packed_error; + + // thread_hash is the least-significant bits of the |ERR_STATE| pointer value + // for this thread. + const unsigned long thread_hash = (uintptr_t) err_get_state(); + + for (;;) { + packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); + if (packed_error == 0) { + break; + } + + ERR_error_string_n(packed_error, buf, sizeof(buf)); + BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf, + file, line, (flags & ERR_FLAG_STRING) ? data : ""); + if (callback(buf2, strlen(buf2), ctx) <= 0) { + break; + } + } +} + +static int print_errors_to_file(const char* msg, size_t msg_len, void* ctx) { + assert(msg[msg_len] == '\0'); + FILE* fp = ctx; + int res = fputs(msg, fp); + return res < 0 ? 0 : 1; +} + +void ERR_print_errors_fp(FILE *file) { + ERR_print_errors_cb(print_errors_to_file, file); +} + +// err_set_error_data sets the data on the most recent error. +static void err_set_error_data(char *data) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL || state->top == state->bottom) { + OPENSSL_free(data); + return; + } + + error = &state->errors[state->top]; + + OPENSSL_free(error->data); + error->data = data; +} + +void ERR_put_error(int library, int unused, int reason, const char *file, + unsigned line) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL) { + return; + } + + if (library == ERR_LIB_SYS && reason == 0) { +#if defined(OPENSSL_WINDOWS) + reason = GetLastError(); +#else + reason = errno; +#endif + } + + state->top = (state->top + 1) % ERR_NUM_ERRORS; + if (state->top == state->bottom) { + state->bottom = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[state->top]; + err_clear(error); + error->file = file; + error->line = line; + error->packed = ERR_PACK(library, reason); +} + +// ERR_add_error_data_vdata takes a variable number of const char* pointers, +// concatenates them and sets the result as the data on the most recent +// error. +static void err_add_error_vdata(unsigned num, va_list args) { + size_t alloced, new_len, len = 0, substr_len; + char *buf; + const char *substr; + unsigned i; + + alloced = 80; + buf = OPENSSL_malloc(alloced + 1); + if (buf == NULL) { + return; + } + + for (i = 0; i < num; i++) { + substr = va_arg(args, const char *); + if (substr == NULL) { + continue; + } + + substr_len = strlen(substr); + new_len = len + substr_len; + if (new_len > alloced) { + char *new_buf; + + if (alloced + 20 + 1 < alloced) { + // overflow. + OPENSSL_free(buf); + return; + } + + alloced = new_len + 20; + new_buf = OPENSSL_realloc(buf, alloced + 1); + if (new_buf == NULL) { + OPENSSL_free(buf); + return; + } + buf = new_buf; + } + + OPENSSL_memcpy(buf + len, substr, substr_len); + len = new_len; + } + + buf[len] = 0; + err_set_error_data(buf); +} + +void ERR_add_error_data(unsigned count, ...) { + va_list args; + va_start(args, count); + err_add_error_vdata(count, args); + va_end(args); +} + +void ERR_add_error_dataf(const char *format, ...) { + va_list ap; + char *buf; + static const unsigned buf_len = 256; + + // A fixed-size buffer is used because va_copy (which would be needed in + // order to call vsnprintf twice and measure the buffer) wasn't defined until + // C99. + buf = OPENSSL_malloc(buf_len + 1); + if (buf == NULL) { + return; + } + + va_start(ap, format); + BIO_vsnprintf(buf, buf_len, format, ap); + buf[buf_len] = 0; + va_end(ap); + + err_set_error_data(buf); +} + +void ERR_set_error_data(char *data, int flags) { + if (!(flags & ERR_FLAG_STRING)) { + // We do not support non-string error data. + assert(0); + return; + } + if (flags & ERR_FLAG_MALLOCED) { + err_set_error_data(data); + } else { + char *copy = OPENSSL_strdup(data); + if (copy != NULL) { + err_set_error_data(copy); + } + } +} + +int ERR_set_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL || state->bottom == state->top) { + return 0; + } + state->errors[state->top].mark = 1; + return 1; +} + +int ERR_pop_to_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL) { + return 0; + } + + while (state->bottom != state->top) { + struct err_error_st *error = &state->errors[state->top]; + + if (error->mark) { + error->mark = 0; + return 1; + } + + err_clear(error); + if (state->top == 0) { + state->top = ERR_NUM_ERRORS - 1; + } else { + state->top--; + } + } + + return 0; +} + +void ERR_load_crypto_strings(void) {} + +void ERR_free_strings(void) {} + +void ERR_load_BIO_strings(void) {} + +void ERR_load_ERR_strings(void) {} + +void ERR_load_RAND_strings(void) {} + +struct err_save_state_st { + struct err_error_st *errors; + size_t num_errors; +}; + +void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) { + if (state == NULL) { + return; + } + for (size_t i = 0; i < state->num_errors; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->errors); + OPENSSL_free(state); +} + +ERR_SAVE_STATE *ERR_save_state(void) { + ERR_STATE *const state = err_get_state(); + if (state == NULL || state->top == state->bottom) { + return NULL; + } + + ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE)); + if (ret == NULL) { + return NULL; + } + + // Errors are stored in the range (bottom, top]. + size_t num_errors = state->top >= state->bottom + ? state->top - state->bottom + : ERR_NUM_ERRORS + state->top - state->bottom; + assert(num_errors < ERR_NUM_ERRORS); + ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st)); + if (ret->errors == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st)); + ret->num_errors = num_errors; + + for (size_t i = 0; i < num_errors; i++) { + size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS; + err_copy(&ret->errors[i], &state->errors[j]); + } + return ret; +} + +void ERR_restore_state(const ERR_SAVE_STATE *state) { + if (state == NULL || state->num_errors == 0) { + ERR_clear_error(); + return; + } + + ERR_STATE *const dst = err_get_state(); + if (dst == NULL) { + return; + } + + for (size_t i = 0; i < state->num_errors; i++) { + err_copy(&dst->errors[i], &state->errors[i]); + } + dst->top = state->num_errors - 1; + dst->bottom = ERR_NUM_ERRORS - 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err_data.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err_data.c new file mode 100644 index 00000000..4feb6789 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/err_data.c @@ -0,0 +1,1505 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + /* This file was generated by err_data_generate.go. */ + +#include +#include +#include + + +OPENSSL_STATIC_ASSERT(ERR_LIB_NONE == 1, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_SYS == 2, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_BN == 3, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_RSA == 4, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_DH == 5, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_EVP == 6, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_BUF == 7, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_OBJ == 8, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_PEM == 9, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_DSA == 10, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_X509 == 11, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_ASN1 == 12, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_CONF == 13, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_CRYPTO == 14, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_EC == 15, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_SSL == 16, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_BIO == 17, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS7 == 18, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS8 == 19, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_X509V3 == 20, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_RAND == 21, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_ENGINE == 22, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_OCSP == 23, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_UI == 24, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_COMP == 25, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_ECDSA == 26, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_ECDH == 27, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_HMAC == 28, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_DIGEST == 29, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_CIPHER == 30, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_HKDF == 31, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_TRUST_TOKEN == 32, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_LIB_USER == 33, "library value changed"); +OPENSSL_STATIC_ASSERT(ERR_NUM_LIBS == 34, "number of libraries changed"); + +const uint32_t kOpenSSLReasonValues[] = { + 0xc320885, + 0xc32889f, + 0xc3308ae, + 0xc3388be, + 0xc3408cd, + 0xc3488e6, + 0xc3508f2, + 0xc35890f, + 0xc36092f, + 0xc36893d, + 0xc37094d, + 0xc37895a, + 0xc38096a, + 0xc388975, + 0xc39098b, + 0xc39899a, + 0xc3a09ae, + 0xc3a8892, + 0xc3b00f7, + 0xc3b8921, + 0x10320892, + 0x10329620, + 0x1033162c, + 0x10339645, + 0x10341658, + 0x10348f72, + 0x10350cab, + 0x1035966b, + 0x10361695, + 0x103696a8, + 0x103716c7, + 0x103796e0, + 0x103816f5, + 0x10389713, + 0x10391722, + 0x1039973e, + 0x103a1759, + 0x103a9768, + 0x103b1784, + 0x103b979f, + 0x103c17c5, + 0x103c80f7, + 0x103d17d6, + 0x103d97ea, + 0x103e1809, + 0x103e9818, + 0x103f182f, + 0x103f9842, + 0x10400c6f, + 0x10409855, + 0x10411873, + 0x10419886, + 0x104218a0, + 0x104298b0, + 0x104318c4, + 0x104398da, + 0x104418f2, + 0x10449907, + 0x1045191b, + 0x1045992d, + 0x10460635, + 0x1046899a, + 0x10471942, + 0x10479959, + 0x1048196e, + 0x1048997c, + 0x10490ebe, + 0x104997b6, + 0x104a1680, + 0x14320c52, + 0x14328c60, + 0x14330c6f, + 0x14338c81, + 0x143400b9, + 0x143480f7, + 0x18320090, + 0x18328fc8, + 0x183300b9, + 0x18338fde, + 0x18340ff2, + 0x183480f7, + 0x18351011, + 0x18359029, + 0x1836103e, + 0x18369052, + 0x1837108a, + 0x183790a0, + 0x183810b4, + 0x183890c4, + 0x18390ac0, + 0x183990d4, + 0x183a10fa, + 0x183a9120, + 0x183b0cca, + 0x183b916f, + 0x183c1181, + 0x183c918c, + 0x183d119c, + 0x183d91ad, + 0x183e11be, + 0x183e91d0, + 0x183f11f9, + 0x183f9212, + 0x1840122a, + 0x1840870d, + 0x18411143, + 0x1841910e, + 0x1842112d, + 0x18428cb7, + 0x184310e9, + 0x18439155, + 0x18441007, + 0x18449076, + 0x20321264, + 0x20329251, + 0x24321270, + 0x243289e0, + 0x24331282, + 0x2433928f, + 0x2434129c, + 0x243492ae, + 0x243512bd, + 0x243592da, + 0x243612e7, + 0x243692f5, + 0x24371303, + 0x24379311, + 0x2438131a, + 0x24389327, + 0x2439133a, + 0x28320c9f, + 0x28328cca, + 0x28330c6f, + 0x28338cdd, + 0x28340cab, + 0x283480b9, + 0x283500f7, + 0x28358cb7, + 0x2c3232bf, + 0x2c329351, + 0x2c3332cd, + 0x2c33b2df, + 0x2c3432f3, + 0x2c34b305, + 0x2c353320, + 0x2c35b332, + 0x2c363362, + 0x2c36833a, + 0x2c37336f, + 0x2c37b39b, + 0x2c3833c0, + 0x2c38b3d7, + 0x2c3933f5, + 0x2c39b405, + 0x2c3a3417, + 0x2c3ab42b, + 0x2c3b343c, + 0x2c3bb45b, + 0x2c3c1363, + 0x2c3c9379, + 0x2c3d34a0, + 0x2c3d9392, + 0x2c3e34ca, + 0x2c3eb4d8, + 0x2c3f34f0, + 0x2c3fb508, + 0x2c403532, + 0x2c409264, + 0x2c413543, + 0x2c41b556, + 0x2c42122a, + 0x2c42b567, + 0x2c43076d, + 0x2c43b44d, + 0x2c4433ae, + 0x2c44b515, + 0x2c453345, + 0x2c45b381, + 0x2c4633e5, + 0x2c46b46f, + 0x2c473484, + 0x2c47b4bd, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x30340057, + 0x30348071, + 0x30350078, + 0x30358090, + 0x303600a1, + 0x303680b9, + 0x303700c6, + 0x303780d5, + 0x303800f7, + 0x30388104, + 0x30390117, + 0x30398132, + 0x303a0147, + 0x303a815b, + 0x303b016f, + 0x303b8180, + 0x303c0199, + 0x303c81b6, + 0x303d01c4, + 0x303d81d8, + 0x303e01e8, + 0x303e8201, + 0x303f0211, + 0x303f8224, + 0x30400233, + 0x3040823f, + 0x30410254, + 0x30418264, + 0x3042027b, + 0x30428288, + 0x3043029b, + 0x304382aa, + 0x304402bf, + 0x304482e0, + 0x304502f3, + 0x30458306, + 0x3046031f, + 0x3046833a, + 0x30470372, + 0x30478384, + 0x304803a2, + 0x304883b3, + 0x304903c2, + 0x304983da, + 0x304a03ec, + 0x304a8400, + 0x304b0418, + 0x304b842b, + 0x304c0436, + 0x304c8447, + 0x304d0453, + 0x304d8469, + 0x304e0477, + 0x304e848d, + 0x304f049f, + 0x304f84b1, + 0x305004d4, + 0x305084e7, + 0x305104f8, + 0x30518508, + 0x30520520, + 0x30528535, + 0x3053054d, + 0x30538561, + 0x30540579, + 0x30548592, + 0x305505ab, + 0x305585c8, + 0x305605d3, + 0x305685eb, + 0x305705fb, + 0x3057860c, + 0x3058061f, + 0x30588635, + 0x3059063e, + 0x30598653, + 0x305a0666, + 0x305a8675, + 0x305b0695, + 0x305b86a4, + 0x305c06c5, + 0x305c86e1, + 0x305d06ed, + 0x305d870d, + 0x305e0729, + 0x305e874d, + 0x305f0763, + 0x305f876d, + 0x306004c4, + 0x3060804a, + 0x30610357, + 0x3061873a, + 0x30620392, + 0x34320bb0, + 0x34328bc4, + 0x34330be1, + 0x34338bf4, + 0x34340c03, + 0x34348c3c, + 0x34350c20, + 0x3c320090, + 0x3c328d07, + 0x3c330d20, + 0x3c338d3b, + 0x3c340d58, + 0x3c348d82, + 0x3c350d9d, + 0x3c358dc3, + 0x3c360ddc, + 0x3c368df4, + 0x3c370e05, + 0x3c378e13, + 0x3c380e20, + 0x3c388e34, + 0x3c390cca, + 0x3c398e57, + 0x3c3a0e6b, + 0x3c3a895a, + 0x3c3b0e7b, + 0x3c3b8e96, + 0x3c3c0ea8, + 0x3c3c8edb, + 0x3c3d0ee5, + 0x3c3d8ef9, + 0x3c3e0f07, + 0x3c3e8f2c, + 0x3c3f0cf3, + 0x3c3f8f15, + 0x3c4000b9, + 0x3c4080f7, + 0x3c410d73, + 0x3c418db2, + 0x3c420ebe, + 0x3c428e48, + 0x40321a0e, + 0x40329a24, + 0x40331a52, + 0x40339a5c, + 0x40341a73, + 0x40349a91, + 0x40351aa1, + 0x40359ab3, + 0x40361ac0, + 0x40369acc, + 0x40371ae1, + 0x40379af3, + 0x40381afe, + 0x40389b10, + 0x40390f72, + 0x40399b20, + 0x403a1b33, + 0x403a9b54, + 0x403b1b65, + 0x403b9b75, + 0x403c0071, + 0x403c8090, + 0x403d1bd6, + 0x403d9bec, + 0x403e1bfb, + 0x403e9c33, + 0x403f1c4d, + 0x403f9c75, + 0x40401c8a, + 0x40409c9e, + 0x40411cd9, + 0x40419cf4, + 0x40421d0d, + 0x40429d20, + 0x40431d34, + 0x40439d62, + 0x40441d79, + 0x404480b9, + 0x40451d8e, + 0x40459da0, + 0x40461dc4, + 0x40469de4, + 0x40471df2, + 0x40479e19, + 0x40481e8a, + 0x40489f44, + 0x40491f5b, + 0x40499f75, + 0x404a1f8c, + 0x404a9faa, + 0x404b1fc2, + 0x404b9fef, + 0x404c2005, + 0x404ca017, + 0x404d2038, + 0x404da071, + 0x404e2085, + 0x404ea092, + 0x404f212c, + 0x404fa1a2, + 0x40502211, + 0x4050a225, + 0x40512258, + 0x40522268, + 0x4052a28c, + 0x405322a4, + 0x4053a2b7, + 0x405422cc, + 0x4054a2ef, + 0x4055231a, + 0x4055a357, + 0x4056237c, + 0x4056a395, + 0x405723ad, + 0x4057a3c0, + 0x405823d5, + 0x4058a3fc, + 0x4059242b, + 0x4059a458, + 0x405a246c, + 0x405aa47c, + 0x405b2494, + 0x405ba4a5, + 0x405c24b8, + 0x405ca4f7, + 0x405d2504, + 0x405da529, + 0x405e2567, + 0x405e8afe, + 0x405f2588, + 0x405fa595, + 0x406025a3, + 0x4060a5c5, + 0x40612626, + 0x4061a65e, + 0x40622675, + 0x4062a686, + 0x406326d3, + 0x4063a6e8, + 0x406426ff, + 0x4064a72b, + 0x40652746, + 0x4065a75d, + 0x40662775, + 0x4066a79f, + 0x406727ca, + 0x4067a80f, + 0x40682857, + 0x4068a878, + 0x406928aa, + 0x4069a8d8, + 0x406a28f9, + 0x406aa919, + 0x406b2aa1, + 0x406baac4, + 0x406c2ada, + 0x406cade4, + 0x406d2e13, + 0x406dae3b, + 0x406e2e69, + 0x406eaeb6, + 0x406f2f0f, + 0x406faf47, + 0x40702f5a, + 0x4070af77, + 0x4071084d, + 0x4071af89, + 0x40722f9c, + 0x4072afd2, + 0x40732fea, + 0x4073957b, + 0x40742ffe, + 0x4074b018, + 0x40753029, + 0x4075b03d, + 0x4076304b, + 0x40769327, + 0x40773070, + 0x4077b0b0, + 0x407830cb, + 0x4078b104, + 0x4079311b, + 0x4079b131, + 0x407a315d, + 0x407ab170, + 0x407b3185, + 0x407bb197, + 0x407c31c8, + 0x407cb1d1, + 0x407d2893, + 0x407da1ca, + 0x407e30e0, + 0x407ea40c, + 0x407f1e06, + 0x407f9fd9, + 0x4080213c, + 0x40809e2e, + 0x4081227a, + 0x4081a0e0, + 0x40822e54, + 0x40829b81, + 0x408323e7, + 0x4083a710, + 0x40841e42, + 0x4084a444, + 0x408524c9, + 0x4085a5ed, + 0x40862549, + 0x4086a1e4, + 0x40872e9a, + 0x4087a63b, + 0x40881bbf, + 0x4088a822, + 0x40891c0e, + 0x40899b9b, + 0x408a2b12, + 0x408a9993, + 0x408b31ac, + 0x408baf24, + 0x408c24d9, + 0x408c99cb, + 0x408d1f2a, + 0x408d9e74, + 0x408e205a, + 0x408ea337, + 0x408f2836, + 0x408fa609, + 0x409027eb, + 0x4090a51b, + 0x40912afa, + 0x409199f1, + 0x40921c5b, + 0x4092aed5, + 0x40932fb5, + 0x4093a1f5, + 0x40941e56, + 0x4094ab2b, + 0x40952697, + 0x4095b13d, + 0x40962e81, + 0x4096a155, + 0x40972240, + 0x4097a0a9, + 0x40981cbb, + 0x4098a6ab, + 0x40992ef1, + 0x4099a364, + 0x409a22fd, + 0x409a99af, + 0x409b1eb0, + 0x409b9edb, + 0x409c3092, + 0x409c9f03, + 0x409d2111, + 0x409da0f6, + 0x409e1d4c, + 0x409ea18a, + 0x409f2172, + 0x409f9ea3, + 0x40a021b2, + 0x40a0a0c3, + 0x41f429cc, + 0x41f92a5e, + 0x41fe2951, + 0x41feac07, + 0x41ff2d35, + 0x420329e5, + 0x42082a07, + 0x4208aa43, + 0x42092935, + 0x4209aa7d, + 0x420a298c, + 0x420aa96c, + 0x420b29ac, + 0x420baa25, + 0x420c2d51, + 0x420cab3b, + 0x420d2bee, + 0x420dac25, + 0x42122c58, + 0x42172d18, + 0x4217ac9a, + 0x421c2cbc, + 0x421f2c77, + 0x42212dc9, + 0x42262cfb, + 0x422b2da7, + 0x422babc9, + 0x422c2d89, + 0x422cab7c, + 0x422d2b55, + 0x422dad68, + 0x422e2ba8, + 0x42302cd7, + 0x4230ac3f, + 0x44320778, + 0x44328787, + 0x44330793, + 0x443387a1, + 0x443407b4, + 0x443487c5, + 0x443507cc, + 0x443587d6, + 0x443607e9, + 0x443687ff, + 0x44370811, + 0x4437881e, + 0x4438082d, + 0x44388835, + 0x4439084d, + 0x4439885b, + 0x443a086e, + 0x48321351, + 0x48329363, + 0x48331379, + 0x48339392, + 0x4c3213cf, + 0x4c3293df, + 0x4c3313f2, + 0x4c339412, + 0x4c3400b9, + 0x4c3480f7, + 0x4c35141e, + 0x4c35942c, + 0x4c361448, + 0x4c36946e, + 0x4c37147d, + 0x4c37948b, + 0x4c3814a0, + 0x4c3894ac, + 0x4c3914cc, + 0x4c3994f6, + 0x4c3a150f, + 0x4c3a9528, + 0x4c3b0635, + 0x4c3b9541, + 0x4c3c1553, + 0x4c3c9562, + 0x4c3d157b, + 0x4c3d8c92, + 0x4c3e15e8, + 0x4c3e958a, + 0x4c3f160a, + 0x4c3f9327, + 0x4c4015a0, + 0x4c4093bb, + 0x4c4115d8, + 0x4c41945b, + 0x4c4215c4, + 0x4c4293a3, + 0x50323579, + 0x5032b588, + 0x50333593, + 0x5033b5a3, + 0x503435bc, + 0x5034b5d6, + 0x503535e4, + 0x5035b5fa, + 0x5036360c, + 0x5036b622, + 0x5037363b, + 0x5037b64e, + 0x50383666, + 0x5038b677, + 0x5039368c, + 0x5039b6a0, + 0x503a36c0, + 0x503ab6d6, + 0x503b36ee, + 0x503bb700, + 0x503c371c, + 0x503cb733, + 0x503d374c, + 0x503db762, + 0x503e376f, + 0x503eb785, + 0x503f3797, + 0x503f83b3, + 0x504037aa, + 0x5040b7ba, + 0x504137d4, + 0x5041b7e3, + 0x504237fd, + 0x5042b81a, + 0x5043382a, + 0x5043b83a, + 0x50443857, + 0x50448469, + 0x5045386b, + 0x5045b889, + 0x5046389c, + 0x5046b8b2, + 0x504738c4, + 0x5047b8d9, + 0x504838ff, + 0x5048b90d, + 0x50493920, + 0x5049b935, + 0x504a394b, + 0x504ab95b, + 0x504b397b, + 0x504bb98e, + 0x504c39b1, + 0x504cb9df, + 0x504d3a0c, + 0x504dba29, + 0x504e3a44, + 0x504eba60, + 0x504f3a72, + 0x504fba89, + 0x50503a98, + 0x50508729, + 0x50513aab, + 0x5051b849, + 0x505239f1, + 0x58320fb0, + 0x68320f72, + 0x68328cca, + 0x68330cdd, + 0x68338f80, + 0x68340f90, + 0x683480f7, + 0x6c320f38, + 0x6c328c81, + 0x6c330f43, + 0x6c338f5c, + 0x74320a66, + 0x743280b9, + 0x74330c92, + 0x783209cb, + 0x783289e0, + 0x783309ec, + 0x78338090, + 0x783409fb, + 0x78348a10, + 0x78350a2f, + 0x78358a51, + 0x78360a66, + 0x78368a7c, + 0x78370a8c, + 0x78378aad, + 0x78380ac0, + 0x78388ad2, + 0x78390adf, + 0x78398afe, + 0x783a0b13, + 0x783a8b21, + 0x783b0b2b, + 0x783b8b3f, + 0x783c0b56, + 0x783c8b6b, + 0x783d0b82, + 0x783d8b97, + 0x783e0aed, + 0x783e8a9f, + 0x7c321240, + 0x8032146e, + 0x80328090, + 0x8033328e, + 0x803380b9, + 0x8034329d, + 0x8034b205, + 0x80353223, + 0x8035b2b1, + 0x80363265, + 0x8036b214, + 0x80373257, + 0x8037b1f2, + 0x80383278, + 0x8038b234, + 0x80393249, +}; + +const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + +const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\0" + "AUX_ERROR\0" + "BAD_GET_ASN1_OBJECT_CALL\0" + "BAD_OBJECT_HEADER\0" + "BAD_TEMPLATE\0" + "BMPSTRING_IS_WRONG_LENGTH\0" + "BN_LIB\0" + "BOOLEAN_IS_WRONG_LENGTH\0" + "BUFFER_TOO_SMALL\0" + "CONTEXT_NOT_INITIALISED\0" + "DECODE_ERROR\0" + "DEPTH_EXCEEDED\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0" + "ENCODE_ERROR\0" + "ERROR_GETTING_TIME\0" + "EXPECTING_AN_ASN1_SEQUENCE\0" + "EXPECTING_AN_INTEGER\0" + "EXPECTING_AN_OBJECT\0" + "EXPECTING_A_BOOLEAN\0" + "EXPECTING_A_TIME\0" + "EXPLICIT_LENGTH_MISMATCH\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\0" + "FIELD_MISSING\0" + "FIRST_NUM_TOO_LARGE\0" + "HEADER_TOO_LONG\0" + "ILLEGAL_BITSTRING_FORMAT\0" + "ILLEGAL_BOOLEAN\0" + "ILLEGAL_CHARACTERS\0" + "ILLEGAL_FORMAT\0" + "ILLEGAL_HEX\0" + "ILLEGAL_IMPLICIT_TAG\0" + "ILLEGAL_INTEGER\0" + "ILLEGAL_NESTED_TAGGING\0" + "ILLEGAL_NULL\0" + "ILLEGAL_NULL_VALUE\0" + "ILLEGAL_OBJECT\0" + "ILLEGAL_OPTIONAL_ANY\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\0" + "ILLEGAL_TAGGED_ANY\0" + "ILLEGAL_TIME_VALUE\0" + "INTEGER_NOT_ASCII_FORMAT\0" + "INTEGER_TOO_LARGE_FOR_LONG\0" + "INVALID_BIT_STRING_BITS_LEFT\0" + "INVALID_BIT_STRING_PADDING\0" + "INVALID_BMPSTRING\0" + "INVALID_DIGIT\0" + "INVALID_INTEGER\0" + "INVALID_MODIFIER\0" + "INVALID_NUMBER\0" + "INVALID_OBJECT_ENCODING\0" + "INVALID_SEPARATOR\0" + "INVALID_TIME_FORMAT\0" + "INVALID_UNIVERSALSTRING\0" + "INVALID_UTF8STRING\0" + "LIST_ERROR\0" + "MISSING_ASN1_EOS\0" + "MISSING_EOC\0" + "MISSING_SECOND_NUMBER\0" + "MISSING_VALUE\0" + "MSTRING_NOT_UNIVERSAL\0" + "MSTRING_WRONG_TAG\0" + "NESTED_ASN1_ERROR\0" + "NESTED_ASN1_STRING\0" + "NESTED_TOO_DEEP\0" + "NON_HEX_CHARACTERS\0" + "NOT_ASCII_FORMAT\0" + "NOT_ENOUGH_DATA\0" + "NO_MATCHING_CHOICE_TYPE\0" + "NULL_IS_WRONG_LENGTH\0" + "OBJECT_NOT_ASCII_FORMAT\0" + "ODD_NUMBER_OF_CHARS\0" + "SECOND_NUMBER_TOO_LARGE\0" + "SEQUENCE_LENGTH_MISMATCH\0" + "SEQUENCE_NOT_CONSTRUCTED\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\0" + "SHORT_LINE\0" + "STREAMING_NOT_SUPPORTED\0" + "STRING_TOO_LONG\0" + "STRING_TOO_SHORT\0" + "TAG_VALUE_TOO_HIGH\0" + "TIME_NOT_ASCII_FORMAT\0" + "TOO_LONG\0" + "TYPE_NOT_CONSTRUCTED\0" + "TYPE_NOT_PRIMITIVE\0" + "UNEXPECTED_EOC\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\0" + "UNKNOWN_FORMAT\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0" + "UNKNOWN_SIGNATURE_ALGORITHM\0" + "UNKNOWN_TAG\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_TYPE\0" + "WRONG_INTEGER_TYPE\0" + "WRONG_PUBLIC_KEY_TYPE\0" + "WRONG_TAG\0" + "WRONG_TYPE\0" + "BAD_FOPEN_MODE\0" + "BROKEN_PIPE\0" + "CONNECT_ERROR\0" + "ERROR_SETTING_NBIO\0" + "INVALID_ARGUMENT\0" + "IN_USE\0" + "KEEPALIVE\0" + "NBIO_CONNECT_ERROR\0" + "NO_HOSTNAME_SPECIFIED\0" + "NO_PORT_SPECIFIED\0" + "NO_SUCH_FILE\0" + "NULL_PARAMETER\0" + "SYS_LIB\0" + "UNABLE_TO_CREATE_SOCKET\0" + "UNINITIALIZED\0" + "UNSUPPORTED_METHOD\0" + "WRITE_TO_READ_ONLY_BIO\0" + "ARG2_LT_ARG3\0" + "BAD_ENCODING\0" + "BAD_RECIPROCAL\0" + "BIGNUM_TOO_LONG\0" + "BITS_TOO_SMALL\0" + "CALLED_WITH_EVEN_MODULUS\0" + "DIV_BY_ZERO\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\0" + "INPUT_NOT_REDUCED\0" + "INVALID_INPUT\0" + "INVALID_RANGE\0" + "NEGATIVE_NUMBER\0" + "NOT_A_SQUARE\0" + "NOT_INITIALIZED\0" + "NO_INVERSE\0" + "PRIVATE_KEY_TOO_LARGE\0" + "P_IS_NOT_PRIME\0" + "TOO_MANY_ITERATIONS\0" + "TOO_MANY_TEMPORARY_VARIABLES\0" + "AES_KEY_SETUP_FAILED\0" + "BAD_DECRYPT\0" + "BAD_KEY_LENGTH\0" + "CTRL_NOT_IMPLEMENTED\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\0" + "INITIALIZATION_ERROR\0" + "INPUT_NOT_INITIALIZED\0" + "INVALID_AD_SIZE\0" + "INVALID_KEY_LENGTH\0" + "INVALID_NONCE\0" + "INVALID_NONCE_SIZE\0" + "INVALID_OPERATION\0" + "IV_TOO_LARGE\0" + "NO_CIPHER_SET\0" + "NO_DIRECTION_SET\0" + "OUTPUT_ALIASES_INPUT\0" + "TAG_TOO_LARGE\0" + "TOO_LARGE\0" + "UNSUPPORTED_AD_SIZE\0" + "UNSUPPORTED_INPUT_SIZE\0" + "UNSUPPORTED_KEY_SIZE\0" + "UNSUPPORTED_NONCE_SIZE\0" + "UNSUPPORTED_TAG_SIZE\0" + "WRONG_FINAL_BLOCK_LENGTH\0" + "LIST_CANNOT_BE_NULL\0" + "MISSING_CLOSE_SQUARE_BRACKET\0" + "MISSING_EQUAL_SIGN\0" + "NO_CLOSE_BRACE\0" + "UNABLE_TO_CREATE_NEW_SECTION\0" + "VARIABLE_EXPANSION_TOO_LONG\0" + "VARIABLE_HAS_NO_VALUE\0" + "BAD_GENERATOR\0" + "INVALID_PUBKEY\0" + "MODULUS_TOO_LARGE\0" + "NO_PRIVATE_VALUE\0" + "UNKNOWN_HASH\0" + "BAD_Q_VALUE\0" + "BAD_VERSION\0" + "INVALID_PARAMETERS\0" + "MISSING_PARAMETERS\0" + "NEED_NEW_SETUP_VALUES\0" + "BIGNUM_OUT_OF_RANGE\0" + "COORDINATES_OUT_OF_RANGE\0" + "D2I_ECPKPARAMETERS_FAILURE\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\0" + "GROUP2PKPARAMETERS_FAILURE\0" + "GROUP_MISMATCH\0" + "I2D_ECPKPARAMETERS_FAILURE\0" + "INCOMPATIBLE_OBJECTS\0" + "INVALID_COFACTOR\0" + "INVALID_COMPRESSED_POINT\0" + "INVALID_COMPRESSION_BIT\0" + "INVALID_ENCODING\0" + "INVALID_FIELD\0" + "INVALID_FORM\0" + "INVALID_GROUP_ORDER\0" + "INVALID_PRIVATE_KEY\0" + "INVALID_SCALAR\0" + "MISSING_PRIVATE_KEY\0" + "NON_NAMED_CURVE\0" + "PKPARAMETERS2GROUP_FAILURE\0" + "POINT_AT_INFINITY\0" + "POINT_IS_NOT_ON_CURVE\0" + "PUBLIC_KEY_VALIDATION_FAILED\0" + "SLOT_FULL\0" + "UNDEFINED_GENERATOR\0" + "UNKNOWN_GROUP\0" + "UNKNOWN_ORDER\0" + "WRONG_CURVE_PARAMETERS\0" + "WRONG_ORDER\0" + "KDF_FAILED\0" + "POINT_ARITHMETIC_FAILURE\0" + "UNKNOWN_DIGEST_LENGTH\0" + "BAD_SIGNATURE\0" + "NOT_IMPLEMENTED\0" + "RANDOM_NUMBER_GENERATION_FAILED\0" + "OPERATION_NOT_SUPPORTED\0" + "COMMAND_NOT_SUPPORTED\0" + "DIFFERENT_KEY_TYPES\0" + "DIFFERENT_PARAMETERS\0" + "EMPTY_PSK\0" + "EXPECTING_AN_EC_KEY_KEY\0" + "EXPECTING_AN_RSA_KEY\0" + "EXPECTING_A_DSA_KEY\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" + "INVALID_BUFFER_SIZE\0" + "INVALID_DIGEST_LENGTH\0" + "INVALID_DIGEST_TYPE\0" + "INVALID_KEYBITS\0" + "INVALID_MGF1_MD\0" + "INVALID_PADDING_MODE\0" + "INVALID_PEER_KEY\0" + "INVALID_PSS_SALTLEN\0" + "INVALID_SIGNATURE\0" + "KEYS_NOT_SET\0" + "MEMORY_LIMIT_EXCEEDED\0" + "NOT_A_PRIVATE_KEY\0" + "NOT_XOF_OR_INVALID_LENGTH\0" + "NO_DEFAULT_DIGEST\0" + "NO_KEY_SET\0" + "NO_MDC2_SUPPORT\0" + "NO_NID_FOR_CURVE\0" + "NO_OPERATION_SET\0" + "NO_PARAMETERS_SET\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0" + "OPERATON_NOT_INITIALIZED\0" + "UNKNOWN_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_ALGORITHM\0" + "OUTPUT_TOO_LARGE\0" + "INVALID_OID_STRING\0" + "UNKNOWN_NID\0" + "BAD_BASE64_DECODE\0" + "BAD_END_LINE\0" + "BAD_IV_CHARS\0" + "BAD_PASSWORD_READ\0" + "CIPHER_IS_NULL\0" + "ERROR_CONVERTING_PRIVATE_KEY\0" + "NOT_DEK_INFO\0" + "NOT_ENCRYPTED\0" + "NOT_PROC_TYPE\0" + "NO_START_LINE\0" + "READ_KEY\0" + "SHORT_HEADER\0" + "UNSUPPORTED_CIPHER\0" + "UNSUPPORTED_ENCRYPTION\0" + "BAD_PKCS7_VERSION\0" + "NOT_PKCS7_SIGNED_DATA\0" + "NO_CERTIFICATES_INCLUDED\0" + "NO_CRLS_INCLUDED\0" + "AMBIGUOUS_FRIENDLY_NAME\0" + "BAD_ITERATION_COUNT\0" + "BAD_PKCS12_DATA\0" + "BAD_PKCS12_VERSION\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\0" + "CRYPT_ERROR\0" + "ENCRYPT_ERROR\0" + "ERROR_SETTING_CIPHER_PARAMS\0" + "INCORRECT_PASSWORD\0" + "INVALID_CHARACTERS\0" + "KEYGEN_FAILURE\0" + "KEY_GEN_ERROR\0" + "METHOD_NOT_SUPPORTED\0" + "MISSING_MAC\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\0" + "PKCS12_TOO_DEEPLY_NESTED\0" + "PRIVATE_KEY_DECODE_ERROR\0" + "PRIVATE_KEY_ENCODE_ERROR\0" + "UNKNOWN_ALGORITHM\0" + "UNKNOWN_CIPHER\0" + "UNKNOWN_CIPHER_ALGORITHM\0" + "UNKNOWN_DIGEST\0" + "UNSUPPORTED_KEYLENGTH\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\0" + "UNSUPPORTED_OPTIONS\0" + "UNSUPPORTED_PRF\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0" + "UNSUPPORTED_SALT_TYPE\0" + "BAD_E_VALUE\0" + "BAD_FIXED_HEADER_DECRYPT\0" + "BAD_PAD_BYTE_COUNT\0" + "BAD_RSA_PARAMETERS\0" + "BLOCK_TYPE_IS_NOT_01\0" + "BLOCK_TYPE_IS_NOT_02\0" + "BN_NOT_INITIALIZED\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\0" + "CRT_PARAMS_ALREADY_GIVEN\0" + "CRT_VALUES_INCORRECT\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\0" + "DATA_TOO_LARGE\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\0" + "DATA_TOO_LARGE_FOR_MODULUS\0" + "DATA_TOO_SMALL\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\0" + "D_E_NOT_CONGRUENT_TO_1\0" + "D_OUT_OF_RANGE\0" + "EMPTY_PUBLIC_KEY\0" + "FIRST_OCTET_INVALID\0" + "INCONSISTENT_SET_OF_CRT_VALUES\0" + "INTERNAL_ERROR\0" + "INVALID_MESSAGE_LENGTH\0" + "KEY_SIZE_TOO_SMALL\0" + "LAST_OCTET_INVALID\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\0" + "NO_PUBLIC_EXPONENT\0" + "NULL_BEFORE_BLOCK_MISSING\0" + "N_NOT_EQUAL_P_Q\0" + "OAEP_DECODING_ERROR\0" + "ONLY_ONE_OF_P_Q_GIVEN\0" + "OUTPUT_BUFFER_TOO_SMALL\0" + "PADDING_CHECK_FAILED\0" + "PKCS_DECODING_ERROR\0" + "SLEN_CHECK_FAILED\0" + "SLEN_RECOVERY_FAILED\0" + "UNKNOWN_ALGORITHM_TYPE\0" + "UNKNOWN_PADDING_TYPE\0" + "VALUE_MISSING\0" + "WRONG_SIGNATURE_LENGTH\0" + "ALPN_MISMATCH_ON_EARLY_DATA\0" + "ALPS_MISMATCH_ON_EARLY_DATA\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\0" + "APPLICATION_DATA_ON_SHUTDOWN\0" + "APP_DATA_IN_HANDSHAKE\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\0" + "BAD_ALERT\0" + "BAD_CHANGE_CIPHER_SPEC\0" + "BAD_DATA_RETURNED_BY_CALLBACK\0" + "BAD_DH_P_LENGTH\0" + "BAD_DIGEST_LENGTH\0" + "BAD_ECC_CERT\0" + "BAD_ECPOINT\0" + "BAD_HANDSHAKE_RECORD\0" + "BAD_HELLO_REQUEST\0" + "BAD_LENGTH\0" + "BAD_PACKET_LENGTH\0" + "BAD_RSA_ENCRYPT\0" + "BAD_SRTP_MKI_VALUE\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\0" + "BAD_SSL_FILETYPE\0" + "BAD_WRITE_RETRY\0" + "BIO_NOT_SET\0" + "BLOCK_CIPHER_PAD_IS_WRONG\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\0" + "CANNOT_PARSE_LEAF_CERT\0" + "CA_DN_LENGTH_MISMATCH\0" + "CA_DN_TOO_LONG\0" + "CCS_RECEIVED_EARLY\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\0" + "CERTIFICATE_VERIFY_FAILED\0" + "CERT_CB_ERROR\0" + "CERT_DECOMPRESSION_FAILED\0" + "CERT_LENGTH_MISMATCH\0" + "CHANNEL_ID_NOT_P256\0" + "CHANNEL_ID_SIGNATURE_INVALID\0" + "CIPHER_MISMATCH_ON_EARLY_DATA\0" + "CIPHER_OR_HASH_UNAVAILABLE\0" + "CLIENTHELLO_PARSE_FAILED\0" + "CLIENTHELLO_TLSEXT\0" + "CONNECTION_REJECTED\0" + "CONNECTION_TYPE_NOT_SET\0" + "COULD_NOT_PARSE_HINTS\0" + "CUSTOM_EXTENSION_ERROR\0" + "DATA_LENGTH_TOO_LONG\0" + "DECRYPTION_FAILED\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0" + "DH_P_TOO_LONG\0" + "DIGEST_CHECK_FAILED\0" + "DOWNGRADE_DETECTED\0" + "DTLS_MESSAGE_TOO_BIG\0" + "DUPLICATE_EXTENSION\0" + "DUPLICATE_KEY_SHARE\0" + "DUPLICATE_SIGNATURE_ALGORITHM\0" + "EARLY_DATA_NOT_IN_USE\0" + "ECC_CERT_NOT_FOR_SIGNING\0" + "ECH_REJECTED\0" + "ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH\0" + "ECH_SERVER_CONFIG_UNSUPPORTED_EXTENSION\0" + "ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS\0" + "EMPTY_HELLO_RETRY_REQUEST\0" + "EMS_STATE_INCONSISTENT\0" + "ENCRYPTED_LENGTH_TOO_LONG\0" + "ERROR_ADDING_EXTENSION\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\0" + "ERROR_PARSING_EXTENSION\0" + "EXCESSIVE_MESSAGE_SIZE\0" + "EXCESS_HANDSHAKE_DATA\0" + "EXTRA_DATA_IN_MESSAGE\0" + "FRAGMENT_MISMATCH\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0" + "HANDSHAKE_NOT_COMPLETE\0" + "HTTPS_PROXY_REQUEST\0" + "HTTP_REQUEST\0" + "INAPPROPRIATE_FALLBACK\0" + "INCONSISTENT_CLIENT_HELLO\0" + "INCONSISTENT_ECH_NEGOTIATION\0" + "INVALID_ALPN_PROTOCOL\0" + "INVALID_ALPN_PROTOCOL_LIST\0" + "INVALID_CLIENT_HELLO_INNER\0" + "INVALID_COMMAND\0" + "INVALID_COMPRESSION_LIST\0" + "INVALID_DELEGATED_CREDENTIAL\0" + "INVALID_ECH_CONFIG_LIST\0" + "INVALID_ECH_PUBLIC_NAME\0" + "INVALID_MESSAGE\0" + "INVALID_OUTER_EXTENSION\0" + "INVALID_OUTER_RECORD_TYPE\0" + "INVALID_SCT_LIST\0" + "INVALID_SIGNATURE_ALGORITHM\0" + "INVALID_SSL_SESSION\0" + "INVALID_TICKET_KEYS_LENGTH\0" + "KEY_USAGE_BIT_INCORRECT\0" + "LENGTH_MISMATCH\0" + "MISSING_EXTENSION\0" + "MISSING_KEY_SHARE\0" + "MISSING_RSA_CERTIFICATE\0" + "MISSING_TMP_DH_KEY\0" + "MISSING_TMP_ECDH_KEY\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0" + "MTU_TOO_SMALL\0" + "NEGOTIATED_ALPS_WITHOUT_ALPN\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\0" + "NEGOTIATED_TB_WITHOUT_EMS_OR_RI\0" + "NESTED_GROUP\0" + "NO_APPLICATION_PROTOCOL\0" + "NO_CERTIFICATES_RETURNED\0" + "NO_CERTIFICATE_ASSIGNED\0" + "NO_CERTIFICATE_SET\0" + "NO_CIPHERS_AVAILABLE\0" + "NO_CIPHERS_PASSED\0" + "NO_CIPHERS_SPECIFIED\0" + "NO_CIPHER_MATCH\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\0" + "NO_COMPRESSION_SPECIFIED\0" + "NO_GROUPS_SPECIFIED\0" + "NO_METHOD_SPECIFIED\0" + "NO_P256_SUPPORT\0" + "NO_PRIVATE_KEY_ASSIGNED\0" + "NO_RENEGOTIATION\0" + "NO_REQUIRED_DIGEST\0" + "NO_SHARED_CIPHER\0" + "NO_SHARED_GROUP\0" + "NO_SUPPORTED_VERSIONS_ENABLED\0" + "NULL_SSL_CTX\0" + "NULL_SSL_METHOD_PASSED\0" + "OCSP_CB_ERROR\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\0" + "OLD_SESSION_PRF_HASH_MISMATCH\0" + "OLD_SESSION_VERSION_NOT_RETURNED\0" + "PARSE_TLSEXT\0" + "PATH_TOO_LONG\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\0" + "PRE_SHARED_KEY_MUST_BE_LAST\0" + "PRIVATE_KEY_OPERATION_FAILED\0" + "PROTOCOL_IS_SHUTDOWN\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\0" + "PSK_IDENTITY_NOT_FOUND\0" + "PSK_NO_CLIENT_CB\0" + "PSK_NO_SERVER_CB\0" + "QUIC_INTERNAL_ERROR\0" + "QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED\0" + "READ_TIMEOUT_EXPIRED\0" + "RECORD_LENGTH_MISMATCH\0" + "RECORD_TOO_LARGE\0" + "RENEGOTIATION_EMS_MISMATCH\0" + "RENEGOTIATION_ENCODING_ERR\0" + "RENEGOTIATION_MISMATCH\0" + "REQUIRED_CIPHER_MISSING\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\0" + "SECOND_SERVERHELLO_VERSION_MISMATCH\0" + "SERVERHELLO_TLSEXT\0" + "SERVER_CERT_CHANGED\0" + "SERVER_ECHOED_INVALID_SESSION_ID\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\0" + "SESSION_MAY_NOT_BE_CREATED\0" + "SHUTDOWN_WHILE_IN_INIT\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\0" + "SSL3_EXT_INVALID_SERVERNAME\0" + "SSLV3_ALERT_BAD_CERTIFICATE\0" + "SSLV3_ALERT_BAD_RECORD_MAC\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\0" + "SSLV3_ALERT_CLOSE_NOTIFY\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\0" + "SSLV3_ALERT_NO_CERTIFICATE\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0" + "SSL_HANDSHAKE_FAILURE\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\0" + "SSL_SESSION_ID_TOO_LONG\0" + "TICKET_ENCRYPTION_FAILED\0" + "TLS13_DOWNGRADE\0" + "TLSV1_ALERT_ACCESS_DENIED\0" + "TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE\0" + "TLSV1_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE\0" + "TLSV1_ALERT_CERTIFICATE_REQUIRED\0" + "TLSV1_ALERT_CERTIFICATE_UNOBTAINABLE\0" + "TLSV1_ALERT_DECODE_ERROR\0" + "TLSV1_ALERT_DECRYPTION_FAILED\0" + "TLSV1_ALERT_DECRYPT_ERROR\0" + "TLSV1_ALERT_ECH_REQUIRED\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\0" + "TLSV1_ALERT_INTERNAL_ERROR\0" + "TLSV1_ALERT_NO_APPLICATION_PROTOCOL\0" + "TLSV1_ALERT_NO_RENEGOTIATION\0" + "TLSV1_ALERT_PROTOCOL_VERSION\0" + "TLSV1_ALERT_RECORD_OVERFLOW\0" + "TLSV1_ALERT_UNKNOWN_CA\0" + "TLSV1_ALERT_UNKNOWN_PSK_IDENTITY\0" + "TLSV1_ALERT_UNRECOGNIZED_NAME\0" + "TLSV1_ALERT_UNSUPPORTED_EXTENSION\0" + "TLSV1_ALERT_USER_CANCELLED\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0" + "TOO_MANY_EMPTY_FRAGMENTS\0" + "TOO_MANY_KEY_UPDATES\0" + "TOO_MANY_WARNING_ALERTS\0" + "TOO_MUCH_READ_EARLY_DATA\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\0" + "UNCOMPRESSED_CERT_TOO_LARGE\0" + "UNEXPECTED_COMPATIBILITY_MODE\0" + "UNEXPECTED_EXTENSION\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\0" + "UNEXPECTED_MESSAGE\0" + "UNEXPECTED_OPERATOR_IN_GROUP\0" + "UNEXPECTED_RECORD\0" + "UNKNOWN_ALERT_TYPE\0" + "UNKNOWN_CERTIFICATE_TYPE\0" + "UNKNOWN_CERT_COMPRESSION_ALG\0" + "UNKNOWN_CIPHER_RETURNED\0" + "UNKNOWN_CIPHER_TYPE\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\0" + "UNKNOWN_PROTOCOL\0" + "UNKNOWN_SSL_VERSION\0" + "UNKNOWN_STATE\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\0" + "UNSUPPORTED_ECH_SERVER_CONFIG\0" + "UNSUPPORTED_ELLIPTIC_CURVE\0" + "UNSUPPORTED_PROTOCOL\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\0" + "WRONG_CERTIFICATE_TYPE\0" + "WRONG_CIPHER_RETURNED\0" + "WRONG_CURVE\0" + "WRONG_ENCRYPTION_LEVEL_RECEIVED\0" + "WRONG_MESSAGE_TYPE\0" + "WRONG_SIGNATURE_TYPE\0" + "WRONG_SSL_VERSION\0" + "WRONG_VERSION_NUMBER\0" + "WRONG_VERSION_ON_EARLY_DATA\0" + "X509_LIB\0" + "X509_VERIFICATION_SETUP_PROBLEMS\0" + "BAD_VALIDITY_CHECK\0" + "DECODE_FAILURE\0" + "INVALID_KEY_ID\0" + "INVALID_METADATA\0" + "INVALID_METADATA_KEY\0" + "INVALID_PROOF\0" + "INVALID_TOKEN\0" + "NO_KEYS_CONFIGURED\0" + "NO_SRR_KEY_CONFIGURED\0" + "OVER_BATCHSIZE\0" + "SRR_SIGNATURE_ERROR\0" + "TOO_MANY_KEYS\0" + "AKID_MISMATCH\0" + "BAD_X509_FILETYPE\0" + "BASE64_DECODE_ERROR\0" + "CANT_CHECK_DH_KEY\0" + "CERT_ALREADY_IN_HASH_TABLE\0" + "CRL_ALREADY_DELTA\0" + "CRL_VERIFY_FAILURE\0" + "DELTA_CRL_WITHOUT_CRL_NUMBER\0" + "IDP_MISMATCH\0" + "INVALID_DIRECTORY\0" + "INVALID_FIELD_FOR_VERSION\0" + "INVALID_FIELD_NAME\0" + "INVALID_PARAMETER\0" + "INVALID_PSS_PARAMETERS\0" + "INVALID_TRUST\0" + "INVALID_VERSION\0" + "ISSUER_MISMATCH\0" + "KEY_TYPE_MISMATCH\0" + "KEY_VALUES_MISMATCH\0" + "LOADING_CERT_DIR\0" + "LOADING_DEFAULTS\0" + "NAME_TOO_LONG\0" + "NEWER_CRL_NOT_NEWER\0" + "NO_CERTIFICATE_FOUND\0" + "NO_CERTIFICATE_OR_CRL_FOUND\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\0" + "NO_CRL_FOUND\0" + "NO_CRL_NUMBER\0" + "PUBLIC_KEY_DECODE_ERROR\0" + "PUBLIC_KEY_ENCODE_ERROR\0" + "SHOULD_RETRY\0" + "SIGNATURE_ALGORITHM_MISMATCH\0" + "UNKNOWN_KEY_TYPE\0" + "UNKNOWN_PURPOSE_ID\0" + "UNKNOWN_TRUST_ID\0" + "WRONG_LOOKUP_TYPE\0" + "BAD_IP_ADDRESS\0" + "BAD_OBJECT\0" + "BN_DEC2BN_ERROR\0" + "BN_TO_ASN1_INTEGER_ERROR\0" + "CANNOT_FIND_FREE_FUNCTION\0" + "DIRNAME_ERROR\0" + "DISTPOINT_ALREADY_SET\0" + "DUPLICATE_ZONE_ID\0" + "ERROR_CONVERTING_ZONE\0" + "ERROR_CREATING_EXTENSION\0" + "ERROR_IN_EXTENSION\0" + "EXPECTED_A_SECTION_NAME\0" + "EXTENSION_EXISTS\0" + "EXTENSION_NAME_ERROR\0" + "EXTENSION_NOT_FOUND\0" + "EXTENSION_SETTING_NOT_SUPPORTED\0" + "EXTENSION_VALUE_ERROR\0" + "ILLEGAL_EMPTY_EXTENSION\0" + "ILLEGAL_HEX_DIGIT\0" + "INCORRECT_POLICY_SYNTAX_TAG\0" + "INVALID_BOOLEAN_STRING\0" + "INVALID_EXTENSION_STRING\0" + "INVALID_MULTIPLE_RDNS\0" + "INVALID_NAME\0" + "INVALID_NULL_ARGUMENT\0" + "INVALID_NULL_NAME\0" + "INVALID_NULL_VALUE\0" + "INVALID_NUMBERS\0" + "INVALID_OBJECT_IDENTIFIER\0" + "INVALID_OPTION\0" + "INVALID_POLICY_IDENTIFIER\0" + "INVALID_PROXY_POLICY_SETTING\0" + "INVALID_PURPOSE\0" + "INVALID_SECTION\0" + "INVALID_SYNTAX\0" + "INVALID_VALUE\0" + "ISSUER_DECODE_ERROR\0" + "NEED_ORGANIZATION_AND_NUMBERS\0" + "NO_CONFIG_DATABASE\0" + "NO_ISSUER_CERTIFICATE\0" + "NO_ISSUER_DETAILS\0" + "NO_POLICY_IDENTIFIER\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\0" + "NO_PUBLIC_KEY\0" + "NO_SUBJECT_DETAILS\0" + "ODD_NUMBER_OF_DIGITS\0" + "OPERATION_NOT_DEFINED\0" + "OTHERNAME_ERROR\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\0" + "POLICY_PATH_LENGTH\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\0" + "SECTION_NOT_FOUND\0" + "TRAILING_DATA_IN_EXTENSION\0" + "UNABLE_TO_GET_ISSUER_DETAILS\0" + "UNABLE_TO_GET_ISSUER_KEYID\0" + "UNKNOWN_BIT_STRING_ARGUMENT\0" + "UNKNOWN_EXTENSION\0" + "UNKNOWN_EXTENSION_NAME\0" + "UNKNOWN_OPTION\0" + "UNSUPPORTED_OPTION\0" + "USER_TOO_LONG\0" + ""; + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/internal.h new file mode 100644 index 00000000..94ba4cb1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/err/internal.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Private error queue functions. + +// ERR_SAVE_STATE contains a saved representation of the error queue. It is +// slightly more compact than |ERR_STATE| as the error queue will typically not +// contain |ERR_NUM_ERRORS| entries. +typedef struct err_save_state_st ERR_SAVE_STATE; + +// ERR_SAVE_STATE_free releases all memory associated with |state|. +OPENSSL_EXPORT void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state); + +// ERR_save_state returns a newly-allocated |ERR_SAVE_STATE| structure +// containing the current state of the error queue or NULL on allocation +// error. It should be released with |ERR_SAVE_STATE_free|. +OPENSSL_EXPORT ERR_SAVE_STATE *ERR_save_state(void); + +// ERR_restore_state clears the error queue and replaces it with |state|. +OPENSSL_EXPORT void ERR_restore_state(const ERR_SAVE_STATE *state); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(ERR_SAVE_STATE, ERR_SAVE_STATE_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/digestsign.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/digestsign.c new file mode 100644 index 00000000..fb30f97f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/digestsign.c @@ -0,0 +1,231 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include "internal.h" +#include "../fipsmodule/digest/internal.h" + + +enum evp_sign_verify_t { + evp_sign, + evp_verify, +}; + +static const struct evp_md_pctx_ops md_pctx_ops = { + EVP_PKEY_CTX_free, + EVP_PKEY_CTX_dup, +}; + +static int uses_prehash(EVP_MD_CTX *ctx, enum evp_sign_verify_t op) { + return (op == evp_sign) ? (ctx->pctx->pmeth->sign != NULL) + : (ctx->pctx->pmeth->verify != NULL); +} + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + enum evp_sign_verify_t op) { + if (ctx->pctx == NULL) { + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } + if (ctx->pctx == NULL) { + return 0; + } + ctx->pctx_ops = &md_pctx_ops; + + if (op == evp_verify) { + if (!EVP_PKEY_verify_init(ctx->pctx)) { + return 0; + } + } else { + if (!EVP_PKEY_sign_init(ctx->pctx)) { + return 0; + } + } + + if (type != NULL && + !EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) { + return 0; + } + + if (uses_prehash(ctx, op)) { + if (type == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + if (!EVP_DigestInit_ex(ctx, type, e)) { + return 0; + } + } + + if (pctx) { + *pctx = ctx->pctx; + } + return 1; +} + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, + ENGINE *e, EVP_PKEY *pkey) { + return do_sigver_init(ctx, pctx, type, e, pkey, evp_sign); +} + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { + return do_sigver_init(ctx, pctx, type, e, pkey, evp_verify); +} + +int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (out_sig) { + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; + } else { + size_t s = EVP_MD_size(ctx->digest); + return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s); + } +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; +} + +int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len, + const uint8_t *data, size_t data_len) { + if (uses_prehash(ctx, evp_sign)) { + // If |out_sig| is NULL, the caller is only querying the maximum output + // length. |data| should only be incorporated in the final call. + if (out_sig != NULL && + !EVP_DigestSignUpdate(ctx, data, data_len)) { + return 0; + } + + return EVP_DigestSignFinal(ctx, out_sig, out_sig_len); + } + + if (ctx->pctx->pmeth->sign_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->sign_message(ctx->pctx, out_sig, out_sig_len, data, + data_len); +} + +int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *data, size_t len) { + if (uses_prehash(ctx, evp_verify)) { + return EVP_DigestVerifyUpdate(ctx, data, len) && + EVP_DigestVerifyFinal(ctx, sig, sig_len); + } + + if (ctx->pctx->pmeth->verify_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->verify_message(ctx->pctx, sig, sig_len, data, len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp.c new file mode 100644 index 00000000..a0bb7405 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp.c @@ -0,0 +1,456 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// Node depends on |EVP_R_NOT_XOF_OR_INVALID_LENGTH|. +// +// TODO(davidben): Fix Node to not touch the error queue itself and remove this. +OPENSSL_DECLARE_ERROR_REASON(EVP, NOT_XOF_OR_INVALID_LENGTH) + +// The HPKE module uses the EVP error namespace, but it lives in another +// directory. +OPENSSL_DECLARE_ERROR_REASON(EVP, EMPTY_PSK) + +EVP_PKEY *EVP_PKEY_new(void) { + EVP_PKEY *ret; + + ret = OPENSSL_malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY)); + ret->type = EVP_PKEY_NONE; + ret->references = 1; + + return ret; +} + +static void free_it(EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_free) { + pkey->ameth->pkey_free(pkey); + pkey->pkey.ptr = NULL; + pkey->type = EVP_PKEY_NONE; + } +} + +void EVP_PKEY_free(EVP_PKEY *pkey) { + if (pkey == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) { + return; + } + + free_it(pkey); + OPENSSL_free(pkey); +} + +int EVP_PKEY_up_ref(EVP_PKEY *pkey) { + CRYPTO_refcount_inc(&pkey->references); + return 1; +} + +int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_opaque) { + return pkey->ameth->pkey_opaque(pkey); + } + return 0; +} + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + if (a->type != b->type) { + return -1; + } + + if (a->ameth) { + int ret; + // Compare parameters if the algorithm has them + if (a->ameth->param_cmp) { + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) { + return ret; + } + } + + if (a->ameth->pub_cmp) { + return a->ameth->pub_cmp(a, b); + } + } + + return -2; +} + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (to->type != from->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + goto err; + } + + if (from->ameth && from->ameth->param_copy) { + return from->ameth->param_copy(to, from); + } + +err: + return 0; +} + +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->param_missing) { + return pkey->ameth->param_missing(pkey); + } + return 0; +} + +int EVP_PKEY_size(const EVP_PKEY *pkey) { + if (pkey && pkey->ameth && pkey->ameth->pkey_size) { + return pkey->ameth->pkey_size(pkey); + } + return 0; +} + +int EVP_PKEY_bits(const EVP_PKEY *pkey) { + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) { + return pkey->ameth->pkey_bits(pkey); + } + return 0; +} + +int EVP_PKEY_id(const EVP_PKEY *pkey) { + return pkey->type; +} + +// evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which +// should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is +// unknown. +static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { + switch (nid) { + case EVP_PKEY_RSA: + return &rsa_asn1_meth; + case EVP_PKEY_EC: + return &ec_asn1_meth; + case EVP_PKEY_DSA: + return &dsa_asn1_meth; + case EVP_PKEY_ED25519: + return &ed25519_asn1_meth; + case EVP_PKEY_X25519: + return &x25519_asn1_meth; + default: + return NULL; + } +} + +int EVP_PKEY_type(int nid) { + const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid); + if (meth == NULL) { + return NID_undef; + } + return meth->pkey_id; +} + +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { + if (EVP_PKEY_assign_RSA(pkey, key)) { + RSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key); +} + +RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_RSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + return pkey->pkey.rsa; +} + +RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa != NULL) { + RSA_up_ref(rsa); + } + return rsa; +} + +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { + if (EVP_PKEY_assign_DSA(pkey, key)) { + DSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key); +} + +DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_DSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + return pkey->pkey.dsa; +} + +DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { + DSA *dsa = EVP_PKEY_get0_DSA(pkey); + if (dsa != NULL) { + DSA_up_ref(dsa); + } + return dsa; +} + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + if (EVP_PKEY_assign_EC_KEY(pkey, key)) { + EC_KEY_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); +} + +EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + return NULL; + } + return pkey->pkey.ec; +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key != NULL) { + EC_KEY_up_ref(ec_key); + } + return ec_key; +} + +DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { return NULL; } +DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey) { return NULL; } + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { + if (!EVP_PKEY_set_type(pkey, type)) { + return 0; + } + pkey->pkey.ptr = key; + return key != NULL; +} + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { + const EVP_PKEY_ASN1_METHOD *ameth; + + if (pkey && pkey->pkey.ptr) { + free_it(pkey); + } + + ameth = evp_pkey_asn1_find(type); + if (ameth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", type); + return 0; + } + + if (pkey) { + pkey->ameth = ameth; + pkey->type = pkey->ameth->pkey_id; + } + + return 1; +} + +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, + const uint8_t *in, size_t len) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + if (ret->ameth->set_priv_raw == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + + if (!ret->ameth->set_priv_raw(ret, in, len)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, + const uint8_t *in, size_t len) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + if (ret->ameth->set_pub_raw == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + + if (!ret->ameth->set_pub_raw(ret, in, len)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + if (pkey->ameth->get_priv_raw == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->get_priv_raw(pkey, out, out_len); +} + +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + if (pkey->ameth->get_pub_raw == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->get_pub_raw(pkey, out, out_len); +} + +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + if (a->type != b->type) { + return -1; + } + if (a->ameth && a->ameth->param_cmp) { + return a->ameth->param_cmp(a, b); + } + return -2; +} + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, + (void *)md); +} + +int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD, + 0, (void *)out_md); +} + +void *EVP_PKEY_get0(const EVP_PKEY *pkey) { + // Node references, but never calls this function, so for now we return NULL. + // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc., + // rather than reading |pkey->pkey.ptr| directly. This avoids problems if our + // internal representation does not match the type the caller expects from + // OpenSSL. + return NULL; +} + +void OpenSSL_add_all_algorithms(void) {} + +void OPENSSL_add_all_algorithms_conf(void) {} + +void OpenSSL_add_all_ciphers(void) {} + +void OpenSSL_add_all_digests(void) {} + +void EVP_cleanup(void) {} + +int EVP_PKEY_base_id(const EVP_PKEY *pkey) { + // OpenSSL has two notions of key type because it supports multiple OIDs for + // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling + // of DSA. We do not support these, so the base ID is simply the ID. + return EVP_PKEY_id(pkey); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c new file mode 100644 index 00000000..78e276a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c @@ -0,0 +1,547 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { + &rsa_asn1_meth, + &ec_asn1_meth, + &dsa_asn1_meth, + &ed25519_asn1_meth, + &x25519_asn1_meth, +}; + +static int parse_key_type(CBS *cbs, int *out_type) { + CBS oid; + if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { + return 0; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { + const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; + if (CBS_len(&oid) == method->oid_len && + OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { + *out_type = method->pkey_id; + return 1; + } + } + + return 0; +} + +EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + // Parse the SubjectPublicKeyInfo. + CBS spki, algorithm, key; + int type; + uint8_t padding; + if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || + CBS_len(&spki) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + if (!parse_key_type(&algorithm, &type)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + if (// Every key type defined encodes the key as a byte string with the same + // conversion to BIT STRING. + !CBS_get_u8(&key, &padding) || + padding != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific SPKI decoding function. + if (ret->ameth->pub_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->pub_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->pub_encode(cbb, key); +} + +EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + // Parse the PrivateKeyInfo. + CBS pkcs8, algorithm, key; + uint64_t version; + int type; + if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&pkcs8, &version) || + version != 0 || + !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + if (!parse_key_type(&algorithm, &type)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + // A PrivateKeyInfo ends with a SET of Attributes which we ignore. + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific PrivateKeyInfo decoding function. + if (ret->ameth->priv_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->priv_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->priv_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->priv_encode(cbb, key); +} + +static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL) { + return NULL; + } + + switch (type) { + case EVP_PKEY_EC: { + EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); + if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { + EC_KEY_free(ec_key); + goto err; + } + return ret; + } + case EVP_PKEY_DSA: { + DSA *dsa = DSA_parse_private_key(cbs); + if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { + DSA_free(dsa); + goto err; + } + return ret; + } + case EVP_PKEY_RSA: { + RSA *rsa = RSA_parse_private_key(cbs); + if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { + RSA_free(rsa); + goto err; + } + return ret; + } + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + +err: + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse with the legacy format. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = old_priv_decode(&cbs, type); + if (ret == NULL) { + // Try again with PKCS#8. + ERR_clear_error(); + CBS_init(&cbs, *inp, (size_t)len); + ret = EVP_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (ret->type != type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + EVP_PKEY_free(ret); + return NULL; + } + } + + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +// num_elements parses one SEQUENCE from |in| and returns the number of elements +// in it. On parse error, it returns zero. +static size_t num_elements(const uint8_t *in, size_t in_len) { + CBS cbs, sequence; + CBS_init(&cbs, in, (size_t)in_len); + + if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) { + return 0; + } + + size_t count = 0; + while (CBS_len(&sequence) > 0) { + if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) { + return 0; + } + + count++; + } + + return count; +} + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse the input as a PKCS#8 PrivateKeyInfo. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret != NULL) { + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; + } + ERR_clear_error(); + + // Count the elements to determine the legacy key format. + switch (num_elements(*inp, (size_t)len)) { + case 4: + return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len); + + case 6: + return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len); + + default: + return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len); + } +} + +int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { + switch (key->type) { + case EVP_PKEY_RSA: + return i2d_RSAPublicKey(key->pkey.rsa, outp); + case EVP_PKEY_DSA: + return i2d_DSAPublicKey(key->pkey.dsa, outp); + case EVP_PKEY_EC: + return i2o_ECPublicKey(key->pkey.ec, outp); + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp, + long len) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, len < 0 ? 0 : (size_t)len); + switch (type) { + case EVP_PKEY_RSA: { + RSA *rsa = RSA_parse_public_key(&cbs); + if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { + RSA_free(rsa); + goto err; + } + break; + } + + // Unlike OpenSSL, we do not support EC keys with this API. The raw EC + // public key serialization requires knowing the group. In OpenSSL, calling + // this function with |EVP_PKEY_EC| and setting |out| to NULL does not work. + // It requires |*out| to include a partially-initialized |EVP_PKEY| to + // extract the group. + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + goto err; + } + + *inp = CBS_data(&cbs); + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = EVP_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) { + if (pkey == NULL) { + return 0; + } + + CBB cbb; + if (!CBB_init(&cbb, 128) || + !EVP_marshal_public_key(&cbb, pkey)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *pkey = EVP_parse_public_key(&cbs); + if (pkey == NULL) { + return NULL; + } + RSA *rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (rsa == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = rsa; + } + *inp = CBS_data(&cbs); + return rsa; +} + +int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) { + if (rsa == NULL) { + return 0; + } + + int ret = -1; + EVP_PKEY *pkey = EVP_PKEY_new(); + if (pkey == NULL || + !EVP_PKEY_set1_RSA(pkey, (RSA *)rsa)) { + goto err; + } + + ret = i2d_PUBKEY(pkey, outp); + +err: + EVP_PKEY_free(pkey); + return ret; +} + +DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *pkey = EVP_parse_public_key(&cbs); + if (pkey == NULL) { + return NULL; + } + DSA *dsa = EVP_PKEY_get1_DSA(pkey); + EVP_PKEY_free(pkey); + if (dsa == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = dsa; + } + *inp = CBS_data(&cbs); + return dsa; +} + +int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) { + if (dsa == NULL) { + return 0; + } + + int ret = -1; + EVP_PKEY *pkey = EVP_PKEY_new(); + if (pkey == NULL || + !EVP_PKEY_set1_DSA(pkey, (DSA *)dsa)) { + goto err; + } + + ret = i2d_PUBKEY(pkey, outp); + +err: + EVP_PKEY_free(pkey); + return ret; +} + +EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *pkey = EVP_parse_public_key(&cbs); + if (pkey == NULL) { + return NULL; + } + EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey); + EVP_PKEY_free(pkey); + if (ec_key == NULL) { + return NULL; + } + if (out != NULL) { + EC_KEY_free(*out); + *out = ec_key; + } + *inp = CBS_data(&cbs); + return ec_key; +} + +int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) { + if (ec_key == NULL) { + return 0; + } + + int ret = -1; + EVP_PKEY *pkey = EVP_PKEY_new(); + if (pkey == NULL || + !EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY *)ec_key)) { + goto err; + } + + ret = i2d_PUBKEY(pkey, outp); + +err: + EVP_PKEY_free(pkey); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c new file mode 100644 index 00000000..102e7bf9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c @@ -0,0 +1,484 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static const EVP_PKEY_METHOD *const evp_methods[] = { + &rsa_pkey_meth, + &ec_pkey_meth, + &ed25519_pkey_meth, + &x25519_pkey_meth, +}; + +static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { + for (size_t i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) { + if (evp_methods[i]->pkey_id == type) { + return evp_methods[i]; + } + } + + return NULL; +} + +static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { + EVP_PKEY_CTX *ret; + const EVP_PKEY_METHOD *pmeth; + + if (id == -1) { + if (!pkey || !pkey->ameth) { + return NULL; + } + id = pkey->ameth->pkey_id; + } + + pmeth = evp_pkey_meth_find(id); + + if (pmeth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", id); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + + if (pkey) { + EVP_PKEY_up_ref(pkey); + ret->pkey = pkey; + } + + if (pmeth->init) { + if (pmeth->init(ret) <= 0) { + EVP_PKEY_free(ret->pkey); + OPENSSL_free(ret); + return NULL; + } + } + + return ret; +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { + return evp_pkey_ctx_new(pkey, e, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { + return evp_pkey_ctx_new(NULL, e, id); +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { + if (ctx == NULL) { + return; + } + if (ctx->pmeth && ctx->pmeth->cleanup) { + ctx->pmeth->cleanup(ctx); + } + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); + OPENSSL_free(ctx); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { + if (!ctx->pmeth || !ctx->pmeth->copy) { + return NULL; + } + + EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->pmeth = ctx->pmeth; + ret->engine = ctx->engine; + ret->operation = ctx->operation; + + if (ctx->pkey != NULL) { + EVP_PKEY_up_ref(ctx->pkey); + ret->pkey = ctx->pkey; + } + + if (ctx->peerkey != NULL) { + EVP_PKEY_up_ref(ctx->peerkey); + ret->peerkey = ctx->peerkey; + } + + if (ctx->pmeth->copy(ret, ctx) <= 0) { + ret->pmeth = NULL; + EVP_PKEY_CTX_free(ret); + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return NULL; + } + + return ret; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); + return 0; + } + + if (optype != -1 && !(ctx->operation & optype)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); + return 0; + } + + return ctx->pmeth->ctrl(ctx, cmd, p1, p2); +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->sign == NULL && ctx->pmeth->sign_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + ctx->operation = EVP_PKEY_OP_SIGN; + return 1; +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->sign(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->verify == NULL && ctx->pmeth->verify_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + return 1; +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + return 1; +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + return 1; +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + return 1; +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + return 1; +} + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { + int ret; + if (!ctx || !ctx->pmeth || + !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) || + !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE && + ctx->operation != EVP_PKEY_OP_ENCRYPT && + ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) { + return 0; + } + + if (ret == 2) { + return 1; + } + + if (!ctx->pkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pkey->type != peer->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } + + // ran@cryptocom.ru: For clarity. The error is if parameters in peer are + // present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + // 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + // (different key types) is impossible here because it is checked earlier. + // -2 is OK for us here, as well as 1, so we can check for 0 only. + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + return 0; + } + + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return 0; + } + + EVP_PKEY_up_ref(peer); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->derive(ctx, key, out_key_len); +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + return 1; +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + if (!out_pkey) { + return 0; + } + + if (!*out_pkey) { + *out_pkey = EVP_PKEY_new(); + if (!*out_pkey) { + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return 0; + } + } + + if (!ctx->pmeth->keygen(ctx, *out_pkey)) { + EVP_PKEY_free(*out_pkey); + *out_pkey = NULL; + return 0; + } + return 1; +} + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_PARAMGEN; + return 1; +} + +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + if (!out_pkey) { + return 0; + } + + if (!*out_pkey) { + *out_pkey = EVP_PKEY_new(); + if (!*out_pkey) { + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return 0; + } + } + + if (!ctx->pmeth->paramgen(ctx, *out_pkey)) { + EVP_PKEY_free(*out_pkey); + *out_pkey = NULL; + return 0; + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/internal.h new file mode 100644 index 00000000..f702f908 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/internal.h @@ -0,0 +1,269 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_EVP_INTERNAL_H +#define OPENSSL_HEADER_EVP_INTERNAL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct evp_pkey_asn1_method_st { + int pkey_id; + uint8_t oid[9]; + uint8_t oid_len; + + // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo + // and writes the result into |out|. It returns one on success and zero on + // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER + // type field, and |key| is the contents of the subjectPublicKey with the + // leading padding byte checked and removed. Although X.509 uses BIT STRINGs + // to represent SubjectPublicKeyInfo, every key type defined encodes the key + // as a byte string with the same conversion to BIT STRING. + int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result + // to |out|. It returns one on success and zero on error. + int (*pub_encode)(CBB *out, const EVP_PKEY *key); + + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + + // priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the + // result into |out|. It returns one on success and zero on error. |params| is + // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key| + // is the contents of the OCTET STRING privateKey field. + int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // priv_encode encodes |key| as a PrivateKeyInfo and appends the result to + // |out|. It returns one on success and zero on error. + int (*priv_encode)(CBB *out, const EVP_PKEY *key); + + int (*set_priv_raw)(EVP_PKEY *pkey, const uint8_t *in, size_t len); + int (*set_pub_raw)(EVP_PKEY *pkey, const uint8_t *in, size_t len); + int (*get_priv_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); + int (*get_pub_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); + + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by + // custom implementations which do not expose key material and parameters. + int (*pkey_opaque)(const EVP_PKEY *pk); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + + int (*param_missing)(const EVP_PKEY *pk); + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + + void (*pkey_free)(EVP_PKEY *pkey); +} /* EVP_PKEY_ASN1_METHOD */; + + +#define EVP_PKEY_OP_UNDEFINED 0 +#define EVP_PKEY_OP_KEYGEN (1 << 2) +#define EVP_PKEY_OP_SIGN (1 << 3) +#define EVP_PKEY_OP_VERIFY (1 << 4) +#define EVP_PKEY_OP_VERIFYRECOVER (1 << 5) +#define EVP_PKEY_OP_ENCRYPT (1 << 6) +#define EVP_PKEY_OP_DECRYPT (1 << 7) +#define EVP_PKEY_OP_DERIVE (1 << 8) +#define EVP_PKEY_OP_PARAMGEN (1 << 9) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER) + +#define EVP_PKEY_OP_TYPE_CRYPT (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +#define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +#define EVP_PKEY_OP_TYPE_GEN (EVP_PKEY_OP_KEYGEN | EVP_PKEY_OP_PARAMGEN) + +// EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype| +// arguments can be -1 to specify that any type and operation are acceptable, +// otherwise |keytype| must match the type of |ctx| and the bits of |optype| +// must intersect the operation flags set on |ctx|. +// +// The |p1| and |p2| arguments depend on the value of |cmd|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_GET_MD 2 + +// EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|: +// 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key. +// If the return value is <= 0, the key is rejected. +// 1: Is called at the end of |EVP_PKEY_derive_set_peer| and |p2| contains a +// peer key. If the return value is <= 0, the key is rejected. +// 2: Is called with |p2| == NULL to test whether the peer's key was used. +// (EC)DH always return one in this case. +// 3: Is called with |p2| == NULL to set whether the peer's key was used. +// (EC)DH always return one in this case. This was only used for GOST. +#define EVP_PKEY_CTRL_PEER_KEY 3 + +// EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl +// commands are numbered. +#define EVP_PKEY_ALG_CTRL 0x1000 + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 5) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 8) +#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 9) +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 10) +#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 13) + +struct evp_pkey_ctx_st { + // Method associated with this operation + const EVP_PKEY_METHOD *pmeth; + // Engine that implements this method or NULL if builtin + ENGINE *engine; + // Key: may be NULL + EVP_PKEY *pkey; + // Peer key for key agreement, may be NULL + EVP_PKEY *peerkey; + // operation contains one of the |EVP_PKEY_OP_*| values. + int operation; + // Algorithm specific data + void *data; +} /* EVP_PKEY_CTX */; + +struct evp_pkey_method_st { + int pkey_id; + + int (*init)(EVP_PKEY_CTX *ctx); + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup)(EVP_PKEY_CTX *ctx); + + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*sign_message)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_message)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_recover)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len); + + int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen); + + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); +} /* EVP_PKEY_METHOD */; + +typedef struct { + union { + uint8_t priv[64]; + struct { + // Shift the location of the public key to align with where it is in the + // private key representation. + uint8_t pad[32]; + uint8_t value[32]; + } pub; + } key; + char has_private; +} ED25519_KEY; + +typedef struct { + uint8_t pub[32]; + uint8_t priv[32]; + char has_private; +} X25519_KEY; + +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; + +extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth; +extern const EVP_PKEY_METHOD ed25519_pkey_meth; +extern const EVP_PKEY_METHOD x25519_pkey_meth; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EVP_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c new file mode 100644 index 00000000..b8963ce5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c @@ -0,0 +1,277 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.2. + + // Parameters may or may not be present. + DSA *dsa; + if (CBS_len(params) == 0) { + dsa = DSA_new(); + if (dsa == NULL) { + return 0; + } + } else { + dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + } + + dsa->pub_key = BN_new(); + if (dsa->pub_key == NULL) { + goto err; + } + + if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + DSA_free(dsa); + return 0; +} + +static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + (has_params && + !DSA_marshal_parameters(&algorithm, dsa)) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !BN_marshal_asn1(&key_bitstring, dsa->pub_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See PKCS#11, v2.40, section 2.5. + + // Decode parameters. + BN_CTX *ctx = NULL; + DSA *dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + dsa->priv_key = BN_new(); + dsa->pub_key = BN_new(); + if (dsa->priv_key == NULL || dsa->pub_key == NULL) { + goto err; + } + + // Decode the key. To avoid DoS attacks when importing private keys, we bound + // |dsa->priv_key| against |dsa->q|, which itself bound by + // |DSA_parse_parameters|. (We cannot call |BN_num_bits| on |dsa->priv_key|. + // That would leak a secret bit width.) + if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || + CBS_len(key) != 0 || + BN_cmp(dsa->priv_key, dsa->q) >= 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + // Calculate the public key. + ctx = BN_CTX_new(); + if (ctx == NULL || + !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, + ctx, NULL)) { + goto err; + } + + BN_CTX_free(ctx); + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + BN_CTX_free(ctx); + DSA_free(dsa); + return 0; +} + +static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + if (dsa == NULL || dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + + // See PKCS#11, v2.40, section 2.5. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + !DSA_marshal_parameters(&algorithm, dsa) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_marshal_asn1(&private_key, dsa->priv_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int int_dsa_size(const EVP_PKEY *pkey) { + return DSA_size(pkey->pkey.dsa); +} + +static int dsa_bits(const EVP_PKEY *pkey) { + return BN_num_bits(pkey->pkey.dsa->p); +} + +static int dsa_missing_parameters(const EVP_PKEY *pkey) { + DSA *dsa; + dsa = pkey->pkey.dsa; + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + return 1; + } + return 0; +} + +static int dup_bn_into(BIGNUM **out, BIGNUM *src) { + BIGNUM *a; + + a = BN_dup(src); + if (a == NULL) { + return 0; + } + BN_free(*out); + *out = a; + + return 1; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || + !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || + !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + return 0; + } + + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; +} + +static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + + dsa_priv_decode, + dsa_priv_encode, + + NULL /* set_priv_raw */, + NULL /* set_pub_raw */, + NULL /* get_priv_raw */, + NULL /* get_pub_raw */, + + NULL /* pkey_opaque */, + + int_dsa_size, + dsa_bits, + + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + + int_dsa_free, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec.c new file mode 100644 index 00000000..c50643c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec.c @@ -0,0 +1,286 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +typedef struct { + // message digest + const EVP_MD *md; + EC_GROUP *gen_group; +} EC_PKEY_CTX; + + +static int pkey_ec_init(EVP_PKEY_CTX *ctx) { + EC_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); + if (!dctx) { + return 0; + } + OPENSSL_memset(dctx, 0, sizeof(EC_PKEY_CTX)); + + ctx->data = dctx; + + return 1; +} + +static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { + EC_PKEY_CTX *dctx, *sctx; + if (!pkey_ec_init(dst)) { + return 0; + } + sctx = src->data; + dctx = dst->data; + + dctx->md = sctx->md; + + return 1; +} + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { + EC_PKEY_CTX *dctx = ctx->data; + if (!dctx) { + return; + } + + EC_GROUP_free(dctx->gen_group); + OPENSSL_free(dctx); +} + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + unsigned int sltmp; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t)ECDSA_size(ec)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { + return 0; + } + *siglen = (size_t)sltmp; + return 1; +} + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen) { + return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); +} + +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *keylen) { + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + EC_KEY *eckey; + + if (!ctx->pkey || !ctx->peerkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + return 0; + } + + eckey = ctx->pkey->pkey.ec; + + if (!key) { + const EC_GROUP *group; + group = EC_KEY_get0_group(eckey); + *keylen = (EC_GROUP_get_degree(group) + 7) / 8; + return 1; + } + pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + // NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is + // not an error, the result is truncated. + + outlen = *keylen; + + ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); + if (ret < 0) { + return 0; + } + *keylen = ret; + return 1; +} + +static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + EC_PKEY_CTX *dctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = dctx->md; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + // Default behaviour is OK + return 1; + + case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: { + EC_GROUP *group = EC_GROUP_new_by_curve_name(p1); + if (group == NULL) { + return 0; + } + EC_GROUP_free(dctx->gen_group); + dctx->gen_group = group; + return 1; + } + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + EC_PKEY_CTX *dctx = ctx->data; + const EC_GROUP *group = dctx->gen_group; + if (group == NULL) { + if (ctx->pkey == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + return 0; + } + group = EC_KEY_get0_group(ctx->pkey->pkey.ec); + } + EC_KEY *ec = EC_KEY_new(); + if (ec == NULL || + !EC_KEY_set_group(ec, group) || + !EC_KEY_generate_key(ec)) { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + EC_PKEY_CTX *dctx = ctx->data; + if (dctx->gen_group == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + return 0; + } + EC_KEY *ec = EC_KEY_new(); + if (ec == NULL || + !EC_KEY_set_group(ec, dctx->gen_group)) { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + pkey_ec_keygen, + pkey_ec_sign, + NULL /* sign_message */, + pkey_ec_verify, + NULL /* verify_message */, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + pkey_ec_derive, + pkey_ec_paramgen, + pkey_ec_ctrl, +}; + +int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL); +} + +int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int encoding) { + // BoringSSL only supports named curve syntax. + if (encoding != OPENSSL_EC_NAMED_CURVE) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PARAMETERS); + return 0; + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c new file mode 100644 index 00000000..04a78942 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c @@ -0,0 +1,255 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + const EC_GROUP *group = EC_KEY_get0_group(ec_key); + const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, group) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !EC_POINT_point2cbb(&key_bitstring, group, public_key, + POINT_CONVERSION_UNCOMPRESSED, NULL) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5480, section 2. + + // The parameters are a named curve. + EC_POINT *point = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = EC_KEY_parse_curve_name(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + eckey = EC_KEY_new(); + if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { + goto err; + } + + point = EC_POINT_new(group); + if (point == NULL || + !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || + !EC_KEY_set_public_key(eckey, point)) { + goto err; + } + + EC_GROUP_free(group); + EC_POINT_free(point); + EVP_PKEY_assign_EC_KEY(out, eckey); + return 1; + +err: + EC_GROUP_free(group); + EC_POINT_free(point); + EC_KEY_free(eckey); + return 0; +} + +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + int r; + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), + *pb = EC_KEY_get0_public_key(b->pkey.ec); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) { + return 1; + } else if (r == 1) { + return 0; + } else { + return -2; + } +} + +static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5915. + EC_GROUP *group = EC_KEY_parse_parameters(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_GROUP_free(group); + return 0; + } + + EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); + EC_GROUP_free(group); + if (ec_key == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_KEY_free(ec_key); + return 0; + } + + EVP_PKEY_assign_EC_KEY(out, ec_key); + return 1; +} + +static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + + // Omit the redundant copy of the curve name. This contradicts RFC 5915 but + // aligns with PKCS #11. SEC 1 only says they may be omitted if known by other + // means. Both OpenSSL and NSS omit the redundant parameters, so we omit them + // as well. + unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS; + + // See RFC 5915. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int int_ec_size(const EVP_PKEY *pkey) { + return ECDSA_size(pkey->pkey.ec); +} + +static int ec_bits(const EVP_PKEY *pkey) { + const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + if (group == NULL) { + ERR_clear_error(); + return 0; + } + return BN_num_bits(EC_GROUP_get0_order(group)); +} + +static int ec_missing_parameters(const EVP_PKEY *pkey) { + return EC_KEY_get0_group(pkey->pkey.ec) == NULL; +} + +static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); +} + +static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), + *group_b = EC_KEY_get0_group(b->pkey.ec); + if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + // mismatch + return 0; + } + return 1; +} + +static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } + +static int eckey_opaque(const EVP_PKEY *pkey) { + return EC_KEY_is_opaque(pkey->pkey.ec); +} + +const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + + eckey_priv_decode, + eckey_priv_encode, + + NULL /* set_priv_raw */, + NULL /* set_pub_raw */, + NULL /* get_priv_raw */, + NULL /* get_pub_raw */, + + eckey_opaque, + + int_ec_size, + ec_bits, + + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + + int_ec_free, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c new file mode 100644 index 00000000..d6e5c277 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c @@ -0,0 +1,104 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include "internal.h" + + +// Ed25519 has no parameters to copy. +static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } + +static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!EVP_PKEY_set_type(pkey, EVP_PKEY_ED25519)) { + OPENSSL_free(key); + return 0; + } + + uint8_t pubkey_unused[32]; + ED25519_keypair(pubkey_unused, key->key.priv); + key->has_private = 1; + + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = key; + return 1; +} + +static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (sig == NULL) { + *siglen = 64; + return 1; + } + + if (*siglen < 64) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!ED25519_sign(sig, tbs, tbslen, key->key.priv)) { + return 0; + } + + *siglen = 64; + return 1; +} + +static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (siglen != 64 || + !ED25519_verify(tbs, tbslen, sig, key->key.pub.value)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); + return 0; + } + + return 1; +} + +const EVP_PKEY_METHOD ed25519_pkey_meth = { + EVP_PKEY_ED25519, + NULL /* init */, + pkey_ed25519_copy, + NULL /* cleanup */, + pkey_ed25519_keygen, + NULL /* sign */, + pkey_ed25519_sign_message, + NULL /* verify */, + pkey_ed25519_verify_message, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + NULL /* derive */, + NULL /* paramgen */, + NULL /* ctrl */, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c new file mode 100644 index 00000000..fad315b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c @@ -0,0 +1,221 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static void ed25519_free(EVP_PKEY *pkey) { + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = NULL; +} + +static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { + if (len != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The RFC 8032 encoding stores only the 32-byte seed, so we must recover the + // full representation which we use from it. + uint8_t pubkey_unused[32]; + ED25519_keypair_from_seed(pubkey_unused, key->key.priv, in); + key->has_private = 1; + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { + if (len != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(key->key.pub.value, in, 32); + key->has_private = 0; + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + const ED25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (out == NULL) { + *out_len = 32; + return 1; + } + + if (*out_len < 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + // The raw private key format is the first 32 bytes of the private key. + OPENSSL_memcpy(out, key->key.priv, 32); + *out_len = 32; + return 1; +} + +static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + const ED25519_KEY *key = pkey->pkey.ptr; + if (out == NULL) { + *out_len = 32; + return 1; + } + + if (*out_len < 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(out, key->key.pub.value, 32); + *out_len = 32; + return 1; +} + +static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 8410, section 4. + + // The parameters must be omitted. Public keys have length 32. + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); +} + +static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { + const ED25519_KEY *key = pkey->pkey.ptr; + + // See RFC 8410, section 4. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + const ED25519_KEY *a_key = a->pkey.ptr; + const ED25519_KEY *b_key = b->pkey.ptr; + return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0; +} + +static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 8410, section 7. + + // Parameters must be empty. The key is a 32-byte value wrapped in an extra + // OCTET STRING layer. + CBS inner; + if (CBS_len(params) != 0 || + !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); +} + +static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { + ED25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + // See RFC 8410, section 7. + CBB pkcs8, algorithm, oid, private_key, inner; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || + // The PKCS#8 encoding stores only the 32-byte seed which is the first 32 + // bytes of the private key. + !CBB_add_bytes(&inner, key->key.priv, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_size(const EVP_PKEY *pkey) { return 64; } + +static int ed25519_bits(const EVP_PKEY *pkey) { return 253; } + +const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { + EVP_PKEY_ED25519, + {0x2b, 0x65, 0x70}, + 3, + ed25519_pub_decode, + ed25519_pub_encode, + ed25519_pub_cmp, + ed25519_priv_decode, + ed25519_priv_encode, + ed25519_set_priv_raw, + ed25519_set_pub_raw, + ed25519_get_priv_raw, + ed25519_get_pub_raw, + NULL /* pkey_opaque */, + ed25519_size, + ed25519_bits, + NULL /* param_missing */, + NULL /* param_copy */, + NULL /* param_cmp */, + ed25519_free, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c new file mode 100644 index 00000000..1c179a4e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa.c @@ -0,0 +1,648 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +typedef struct { + // Key gen parameters + int nbits; + BIGNUM *pub_exp; + // RSA padding mode + int pad_mode; + // message digest + const EVP_MD *md; + // message digest for MGF1 + const EVP_MD *mgf1md; + // PSS salt length + int saltlen; + // tbuf is a buffer which is either NULL, or is the size of the RSA modulus. + // It's used to store the output of RSA operations. + uint8_t *tbuf; + // OAEP label + uint8_t *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +typedef struct { + uint8_t *data; + size_t len; +} RSA_OAEP_LABEL_PARAMS; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) { + return 0; + } + OPENSSL_memset(rctx, 0, sizeof(RSA_PKEY_CTX)); + + rctx->nbits = 2048; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->saltlen = -2; + + ctx->data = rctx; + + return 1; +} + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { + RSA_PKEY_CTX *dctx, *sctx; + if (!pkey_rsa_init(dst)) { + return 0; + } + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) { + return 0; + } + } + + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + dctx->mgf1md = sctx->mgf1md; + dctx->saltlen = sctx->saltlen; + if (sctx->oaep_label) { + OPENSSL_free(dctx->oaep_label); + dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); + if (!dctx->oaep_label) { + return 0; + } + dctx->oaep_labellen = sctx->oaep_labellen; + } + + return 1; +} + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx == NULL) { + return; + } + + BN_free(rctx->pub_exp); + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx->oaep_label); + OPENSSL_free(rctx); +} + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { + if (ctx->tbuf) { + return 1; + } + ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); + if (!ctx->tbuf) { + return 0; + } + return 1; +} + +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!sig) { + *siglen = key_len; + return 1; + } + + if (*siglen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md) { + unsigned out_len; + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) { + return 0; + } + *siglen = out_len; + return 1; + + case RSA_PKCS1_PSS_PADDING: + return RSA_sign_pss_mgf1(rsa, siglen, sig, *siglen, tbs, tbslen, + rctx->md, rctx->mgf1md, rctx->saltlen); + + default: + return 0; + } + } + + return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode); +} + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) { + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); + + case RSA_PKCS1_PSS_PADDING: + return RSA_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md, + rctx->saltlen, sig, siglen); + + default: + return 0; + } + } + + size_t rslen; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + if (!setup_tbuf(rctx, ctx) || + !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, + rctx->pad_mode) || + rslen != tbslen || + CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { + return 0; + } + + return 1; +} + +static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t sig_len) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (out == NULL) { + *out_len = key_len; + return 1; + } + + if (*out_len < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md == NULL) { + return RSA_verify_raw(rsa, out_len, out, *out_len, sig, sig_len, + rctx->pad_mode); + } + + if (rctx->pad_mode != RSA_PKCS1_PADDING) { + return 0; + } + + // Assemble the encoded hash, using a placeholder hash value. + static const uint8_t kDummyHash[EVP_MAX_MD_SIZE] = {0}; + const size_t hash_len = EVP_MD_size(rctx->md); + uint8_t *asn1_prefix; + size_t asn1_prefix_len; + int asn1_prefix_allocated; + if (!setup_tbuf(rctx, ctx) || + !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, + &asn1_prefix_allocated, EVP_MD_type(rctx->md), + kDummyHash, hash_len)) { + return 0; + } + + size_t rslen; + int ok = 1; + if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len, + RSA_PKCS1_PADDING) || + rslen != asn1_prefix_len || + // Compare all but the hash suffix. + CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) { + ok = 0; + } + + if (asn1_prefix_allocated) { + OPENSSL_free(asn1_prefix); + } + + if (!ok) { + return 0; + } + + if (out != NULL) { + OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len); + } + *out_len = hash_len; + + return 1; +} + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (!setup_tbuf(rctx, ctx) || + !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, + rctx->oaep_label, rctx->oaep_labellen, + rctx->md, rctx->mgf1md) || + !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, + RSA_NO_PADDING)) { + return 0; + } + return 1; + } + + return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode); +} + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *outlen, const uint8_t *in, + size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + size_t padded_len; + if (!setup_tbuf(rctx, ctx) || + !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + RSA_NO_PADDING) || + !RSA_padding_check_PKCS1_OAEP_mgf1( + out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, + rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { + return 0; + } + return 1; + } + + return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode); +} + +static int check_padding_md(const EVP_MD *md, int padding) { + if (!md) { + return 1; + } + + if (padding == RSA_NO_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + + return 1; +} + +static int is_known_padding(int padding_mode) { + switch (padding_mode) { + case RSA_PKCS1_PADDING: + case RSA_NO_PADDING: + case RSA_PKCS1_OAEP_PADDING: + case RSA_PKCS1_PSS_PADDING: + return 1; + default: + return 0; + } +} + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + RSA_PKEY_CTX *rctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_RSA_PADDING: + if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || + (p1 == RSA_PKCS1_PSS_PADDING && + 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || + (p1 == RSA_PKCS1_OAEP_PADDING && + 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && + rctx->md == NULL) { + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + + case EVP_PKEY_CTRL_GET_RSA_PADDING: + *(int *)p2 = rctx->pad_mode; + return 1; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + return 0; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { + *(int *)p2 = rctx->saltlen; + } else { + if (p1 < -2) { + return 0; + } + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS); + return 0; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) { + return 0; + } + BN_free(rctx->pub_exp); + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_MD: + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) { + *(const EVP_MD **)p2 = rctx->md; + } else { + rctx->md = p2; + } + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) { + return 0; + } + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = rctx->md; + return 1; + + case EVP_PKEY_CTRL_RSA_MGF1_MD: + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && + rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + return 0; + } + if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { + if (rctx->mgf1md) { + *(const EVP_MD **)p2 = rctx->mgf1md; + } else { + *(const EVP_MD **)p2 = rctx->md; + } + } else { + rctx->mgf1md = p2; + } + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: { + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + OPENSSL_free(rctx->oaep_label); + RSA_OAEP_LABEL_PARAMS *params = p2; + rctx->oaep_label = params->data; + rctx->oaep_labellen = params->len; + return 1; + } + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + + if (!rctx->pub_exp) { + rctx->pub_exp = BN_new(); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) { + return 0; + } + } + rsa = RSA_new(); + if (!rsa) { + return 0; + } + + if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + pkey_rsa_keygen, + pkey_rsa_sign, + NULL /* sign_message */, + pkey_rsa_verify, + NULL /* verify_message */, + pkey_rsa_verify_recover, + pkey_rsa_encrypt, + pkey_rsa_decrypt, + NULL /* derive */, + NULL /* paramgen */, + pkey_rsa_ctrl, +}; + +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, + padding, NULL); +} + +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, + 0, out_padding); +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return 0; +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + return 0; +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md) { + return 0; +} + +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); +} + +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); +} + +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); +} + +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); +} + +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); +} + +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md); +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void*) md); +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md); +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label, + size_t label_len) { + RSA_OAEP_LABEL_PARAMS params = {label, label_len}; + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms); +} + +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label) { + CBS label; + if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) { + return -1; + } + if (CBS_len(&label) > INT_MAX) { + OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + return -1; + } + *out_label = CBS_data(&label); + return (int)CBS_len(&label); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c new file mode 100644 index 00000000..5e1157f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c @@ -0,0 +1,194 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { + // See RFC 3279, section 2.3.1. + CBB spki, algorithm, oid, null, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.1. + + // The parameters must be NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_public_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && + BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; +} + +static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { + CBB pkcs8, algorithm, oid, null, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !RSA_marshal_private_key(&private_key, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // Per RFC 3447, A.1, the parameters have type NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_private_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_opaque(const EVP_PKEY *pkey) { + return RSA_is_opaque(pkey->pkey.rsa); +} + +static int int_rsa_size(const EVP_PKEY *pkey) { + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) { + return RSA_bits(pkey->pkey.rsa); +} + +static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + + rsa_priv_decode, + rsa_priv_encode, + + NULL /* set_priv_raw */, + NULL /* set_pub_raw */, + NULL /* get_priv_raw */, + NULL /* get_pub_raw */, + + rsa_opaque, + + int_rsa_size, + rsa_bits, + + 0,0,0, + + int_rsa_free, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c new file mode 100644 index 00000000..ba3e9cb3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519.c @@ -0,0 +1,110 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include "internal.h" + + +// X25519 has no parameters to copy. +static int pkey_x25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } + +static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!EVP_PKEY_set_type(pkey, EVP_PKEY_X25519)) { + OPENSSL_free(key); + return 0; + } + + X25519_keypair(key->pub, key->priv); + key->has_private = 1; + + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = key; + return 1; +} + +static int pkey_x25519_derive(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len) { + if (ctx->pkey == NULL || ctx->peerkey == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + return 0; + } + + const X25519_KEY *our_key = ctx->pkey->pkey.ptr; + const X25519_KEY *peer_key = ctx->peerkey->pkey.ptr; + if (our_key == NULL || peer_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + return 0; + } + + if (!our_key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (out != NULL) { + if (*out_len < 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + if (!X25519(out, our_key->priv, peer_key->pub)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY); + return 0; + } + } + + *out_len = 32; + return 1; +} + +static int pkey_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + switch (type) { + case EVP_PKEY_CTRL_PEER_KEY: + // |EVP_PKEY_derive_set_peer| requires the key implement this command, + // even if it is a no-op. + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +const EVP_PKEY_METHOD x25519_pkey_meth = { + EVP_PKEY_X25519, + NULL /* init */, + pkey_x25519_copy, + NULL /* cleanup */, + pkey_x25519_keygen, + NULL /* sign */, + NULL /* sign_message */, + NULL /* verify */, + NULL /* verify_message */, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + pkey_x25519_derive, + NULL /* paramgen */, + pkey_x25519_ctrl, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c new file mode 100644 index 00000000..fea97795 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c @@ -0,0 +1,248 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static void x25519_free(EVP_PKEY *pkey) { + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = NULL; +} + +static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { + if (len != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(key->priv, in, 32); + X25519_public_from_private(key->pub, key->priv); + key->has_private = 1; + + x25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { + if (len != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(key->pub, in, 32); + key->has_private = 0; + + x25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + const X25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (out == NULL) { + *out_len = 32; + return 1; + } + + if (*out_len < 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(out, key->priv, 32); + *out_len = 32; + return 1; +} + +static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, + size_t *out_len) { + const X25519_KEY *key = pkey->pkey.ptr; + if (out == NULL) { + *out_len = 32; + return 1; + } + + if (*out_len < 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(out, key->pub, 32); + *out_len = 32; + return 1; +} + +static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 8410, section 4. + + // The parameters must be omitted. Public keys have length 32. + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); +} + +static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { + const X25519_KEY *key = pkey->pkey.ptr; + + // See RFC 8410, section 4. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !CBB_add_bytes(&key_bitstring, key->pub, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + const X25519_KEY *a_key = a->pkey.ptr; + const X25519_KEY *b_key = b->pkey.ptr; + return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0; +} + +static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 8410, section 7. + + // Parameters must be empty. The key is a 32-byte value wrapped in an extra + // OCTET STRING layer. + CBS inner; + if (CBS_len(params) != 0 || + !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); +} + +static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { + X25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + // See RFC 8410, section 7. + CBB pkcs8, algorithm, oid, private_key, inner; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || + // The PKCS#8 encoding stores only the 32-byte seed which is the first 32 + // bytes of the private key. + !CBB_add_bytes(&inner, key->priv, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int x25519_size(const EVP_PKEY *pkey) { return 32; } + +static int x25519_bits(const EVP_PKEY *pkey) { return 253; } + +const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { + EVP_PKEY_X25519, + {0x2b, 0x65, 0x6e}, + 3, + x25519_pub_decode, + x25519_pub_encode, + x25519_pub_cmp, + x25519_priv_decode, + x25519_priv_encode, + x25519_set_priv_raw, + x25519_set_pub_raw, + x25519_get_priv_raw, + x25519_get_pub_raw, + NULL /* pkey_opaque */, + x25519_size, + x25519_bits, + NULL /* param_missing */, + NULL /* param_copy */, + NULL /* param_cmp */, + x25519_free, +}; + +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| + // keys. Add support if it ever comes up. + if (pkey->type != EVP_PKEY_X25519) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return 0; + } + + return x25519_set_pub_raw(pkey, in, len); +} + +size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { + // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| + // keys. Add support if it ever comes up. + if (pkey->type != EVP_PKEY_X25519) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return 0; + } + + const X25519_KEY *key = pkey->pkey.ptr; + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + *out_ptr = OPENSSL_memdup(key->pub, 32); + return *out_ptr == NULL ? 0 : 32; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/pbkdf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/pbkdf.c new file mode 100644 index 00000000..fb09a2db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/pbkdf.c @@ -0,0 +1,146 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include + +#include "../internal.h" + + +int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, unsigned iterations, + const EVP_MD *digest, size_t key_len, uint8_t *out_key) { + // See RFC 8018, section 5.2. + int ret = 0; + size_t md_len = EVP_MD_size(digest); + uint32_t i = 1; + HMAC_CTX hctx; + HMAC_CTX_init(&hctx); + + if (!HMAC_Init_ex(&hctx, password, password_len, digest, NULL)) { + goto err; + } + + while (key_len > 0) { + size_t todo = md_len; + if (todo > key_len) { + todo = key_len; + } + + uint8_t i_buf[4]; + i_buf[0] = (uint8_t)((i >> 24) & 0xff); + i_buf[1] = (uint8_t)((i >> 16) & 0xff); + i_buf[2] = (uint8_t)((i >> 8) & 0xff); + i_buf[3] = (uint8_t)(i & 0xff); + + // Compute U_1. + uint8_t digest_tmp[EVP_MAX_MD_SIZE]; + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, salt, salt_len) || + !HMAC_Update(&hctx, i_buf, 4) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + + OPENSSL_memcpy(out_key, digest_tmp, todo); + for (unsigned j = 1; j < iterations; j++) { + // Compute the remaining U_* values and XOR. + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, digest_tmp, md_len) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + for (size_t k = 0; k < todo; k++) { + out_key[k] ^= digest_tmp[k]; + } + } + + key_len -= todo; + out_key += todo; + i++; + } + + // RFC 8018 describes iterations (c) as being a "positive integer", so a + // value of 0 is an error. + // + // Unfortunately not all consumers of PKCS5_PBKDF2_HMAC() check their return + // value, expecting it to succeed and unconditionally using |out_key|. As a + // precaution for such callsites in external code, the old behavior of + // iterations < 1 being treated as iterations == 1 is preserved, but + // additionally an error result is returned. + // + // TODO(eroman): Figure out how to remove this compatibility hack, or change + // the default to something more sensible like 2048. + if (iterations == 0) { + goto err; + } + + ret = 1; + +err: + HMAC_CTX_cleanup(&hctx); + return ret; +} + +int PKCS5_PBKDF2_HMAC_SHA1(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key) { + return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations, + EVP_sha1(), key_len, out_key); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/print.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/print.c new file mode 100644 index 00000000..b0cd8bb0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/print.c @@ -0,0 +1,489 @@ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" + + +static int bn_print(BIO *bp, const char *number, const BIGNUM *num, + uint8_t *buf, int off) { + if (num == NULL) { + return 1; + } + + if (!BIO_indent(bp, off, 128)) { + return 0; + } + if (BN_is_zero(num)) { + if (BIO_printf(bp, "%s 0\n", number) <= 0) { + return 0; + } + return 1; + } + + if (BN_num_bytes(num) <= sizeof(long)) { + const char *neg = BN_is_negative(num) ? "-" : ""; + if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, + (unsigned long)num->d[0], neg, + (unsigned long)num->d[0]) <= 0) { + return 0; + } + } else { + buf[0] = 0; + if (BIO_printf(bp, "%s%s", number, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; + } + int n = BN_bn2bin(num, &buf[1]); + + if (buf[1] & 0x80) { + n++; + } else { + buf++; + } + + int i; + for (i = 0; i < n; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 || + !BIO_indent(bp, off + 4, 128)) { + return 0; + } + } + if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) { + return 0; + } + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + } + return 1; +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) { + if (!b) { + return; + } + + size_t len = BN_num_bytes(b); + if (*pbuflen < len) { + *pbuflen = len; + } +} + +// RSA keys. + +static int do_rsa_print(BIO *out, const RSA *rsa, int off, + int include_private) { + const char *s, *str; + uint8_t *m = NULL; + int ret = 0, mod_len = 0; + size_t buf_len = 0; + + update_buflen(rsa->n, &buf_len); + update_buflen(rsa->e, &buf_len); + + if (include_private) { + update_buflen(rsa->d, &buf_len); + update_buflen(rsa->p, &buf_len); + update_buflen(rsa->q, &buf_len); + update_buflen(rsa->dmp1, &buf_len); + update_buflen(rsa->dmq1, &buf_len); + update_buflen(rsa->iqmp, &buf_len); + } + + m = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->n != NULL) { + mod_len = BN_num_bits(rsa->n); + } + + if (!BIO_indent(out, off, 128)) { + goto err; + } + + if (include_private && rsa->d) { + if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "Modulus:"; + s = "Exponent:"; + } + if (!bn_print(out, str, rsa->n, m, off) || + !bn_print(out, s, rsa->e, m, off)) { + goto err; + } + + if (include_private) { + if (!bn_print(out, "privateExponent:", rsa->d, m, off) || + !bn_print(out, "prime1:", rsa->p, m, off) || + !bn_print(out, "prime2:", rsa->q, m, off) || + !bn_print(out, "exponent1:", rsa->dmp1, m, off) || + !bn_print(out, "exponent2:", rsa->dmq1, m, off) || + !bn_print(out, "coefficient:", rsa->iqmp, m, off)) { + goto err; + } + } + ret = 1; + +err: + OPENSSL_free(m); + return ret; +} + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); +} + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); +} + + +// DSA keys. + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { + uint8_t *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + priv_key = NULL; + if (ptype == 2) { + priv_key = x->priv_key; + } + + pub_key = NULL; + if (ptype > 0) { + pub_key = x->pub_key; + } + + ktype = "DSA-Parameters"; + if (ptype == 2) { + ktype = "Private-Key"; + } else if (ptype == 1) { + ktype = "Public-Key"; + } + + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->g, &buf_len); + update_buflen(priv_key, &buf_len); + update_buflen(pub_key, &buf_len); + + m = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(x->p)) <= 0) { + goto err; + } + } + + if (!bn_print(bp, "priv:", priv_key, m, off) || + !bn_print(bp, "pub: ", pub_key, m, off) || + !bn_print(bp, "P: ", x->p, m, off) || + !bn_print(bp, "Q: ", x->q, m, off) || + !bn_print(bp, "G: ", x->g, m, off)) { + goto err; + } + ret = 1; + +err: + OPENSSL_free(m); + return ret; +} + +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +} + +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +} + +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +} + + +// EC keys. + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { + uint8_t *buffer = NULL; + const char *ecstr; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *order = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + uint8_t *pub_key_bytes = NULL; + size_t pub_key_bytes_len = 0; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (ktype > 0) { + public_key = EC_KEY_get0_public_key(x); + if (public_key != NULL) { + pub_key_bytes_len = EC_POINT_point2oct( + group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); + if (pub_key_bytes == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes_len = + EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), + pub_key_bytes, pub_key_bytes_len, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + buf_len = pub_key_bytes_len; + } + } + + if (ktype == 2) { + priv_key = EC_KEY_get0_private_key(x); + if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) { + buf_len = i; + } + } else { + priv_key = NULL; + } + + if (ktype > 0) { + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + } + if (ktype == 2) { + ecstr = "Private-Key"; + } else if (ktype == 1) { + ecstr = "Public-Key"; + } else { + ecstr = "ECDSA-Parameters"; + } + + if (!BIO_indent(bp, off, 128)) { + goto err; + } + order = BN_new(); + if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || + BIO_printf(bp, "%s: (%u bit)\n", ecstr, BN_num_bits(order)) <= 0) { + goto err; + } + + if ((priv_key != NULL) && + !bn_print(bp, "priv:", priv_key, buffer, off)) { + goto err; + } + if (pub_key_bytes != NULL) { + BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); + } + // TODO(fork): implement + /* + if (!ECPKParameters_print(bp, group, off)) + goto err; */ + ret = 1; + +err: + if (!ret) { + OPENSSL_PUT_ERROR(EVP, reason); + } + OPENSSL_free(pub_key_bytes); + BN_free(order); + BN_CTX_free(ctx); + OPENSSL_free(buffer); + return ret; +} + +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); +} + +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); +} + + +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); +} + + +typedef struct { + int type; + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +} EVP_PKEY_PRINT_METHOD; + +static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { + { + EVP_PKEY_RSA, + rsa_pub_print, + rsa_priv_print, + NULL /* param_print */, + }, + { + EVP_PKEY_DSA, + dsa_pub_print, + dsa_priv_print, + dsa_param_print, + }, + { + EVP_PKEY_EC, + eckey_pub_print, + eckey_priv_print, + eckey_param_print, + }, +}; + +static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods); + +static EVP_PKEY_PRINT_METHOD *find_method(int type) { + for (size_t i = 0; i < kPrintMethodsLen; i++) { + if (kPrintMethods[i].type == type) { + return &kPrintMethods[i]; + } + } + return NULL; +} + +static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) { + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm unsupported\n", kstr); + return 1; +} + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->pub_print != NULL) { + return method->pub_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Public Key"); +} + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->priv_print != NULL) { + return method->priv_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Private Key"); +} + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->param_print != NULL) { + return method->param_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Parameters"); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/scrypt.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/scrypt.c new file mode 100644 index 00000000..54bee65e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/scrypt.c @@ -0,0 +1,211 @@ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include + +#include +#include +#include + +#include "../internal.h" + + +// This file implements scrypt, described in RFC 7914. +// +// Note scrypt refers to both "blocks" and a "block size" parameter, r. These +// are two different notions of blocks. A Salsa20 block is 64 bytes long, +// represented in this implementation by 16 |uint32_t|s. |r| determines the +// number of 64-byte Salsa20 blocks in a scryptBlockMix block, which is 2 * |r| +// Salsa20 blocks. This implementation refers to them as Salsa20 blocks and +// scrypt blocks, respectively. + +// A block_t is a Salsa20 block. +typedef struct { uint32_t words[16]; } block_t; + +OPENSSL_STATIC_ASSERT(sizeof(block_t) == 64, "block_t has padding"); + +// salsa208_word_specification implements the Salsa20/8 core function, also +// described in RFC 7914, section 3. It modifies the block at |inout| +// in-place. +static void salsa208_word_specification(block_t *inout) { + block_t x; + OPENSSL_memcpy(&x, inout, sizeof(x)); + + for (int i = 8; i > 0; i -= 2) { + x.words[4] ^= CRYPTO_rotl_u32(x.words[0] + x.words[12], 7); + x.words[8] ^= CRYPTO_rotl_u32(x.words[4] + x.words[0], 9); + x.words[12] ^= CRYPTO_rotl_u32(x.words[8] + x.words[4], 13); + x.words[0] ^= CRYPTO_rotl_u32(x.words[12] + x.words[8], 18); + x.words[9] ^= CRYPTO_rotl_u32(x.words[5] + x.words[1], 7); + x.words[13] ^= CRYPTO_rotl_u32(x.words[9] + x.words[5], 9); + x.words[1] ^= CRYPTO_rotl_u32(x.words[13] + x.words[9], 13); + x.words[5] ^= CRYPTO_rotl_u32(x.words[1] + x.words[13], 18); + x.words[14] ^= CRYPTO_rotl_u32(x.words[10] + x.words[6], 7); + x.words[2] ^= CRYPTO_rotl_u32(x.words[14] + x.words[10], 9); + x.words[6] ^= CRYPTO_rotl_u32(x.words[2] + x.words[14], 13); + x.words[10] ^= CRYPTO_rotl_u32(x.words[6] + x.words[2], 18); + x.words[3] ^= CRYPTO_rotl_u32(x.words[15] + x.words[11], 7); + x.words[7] ^= CRYPTO_rotl_u32(x.words[3] + x.words[15], 9); + x.words[11] ^= CRYPTO_rotl_u32(x.words[7] + x.words[3], 13); + x.words[15] ^= CRYPTO_rotl_u32(x.words[11] + x.words[7], 18); + x.words[1] ^= CRYPTO_rotl_u32(x.words[0] + x.words[3], 7); + x.words[2] ^= CRYPTO_rotl_u32(x.words[1] + x.words[0], 9); + x.words[3] ^= CRYPTO_rotl_u32(x.words[2] + x.words[1], 13); + x.words[0] ^= CRYPTO_rotl_u32(x.words[3] + x.words[2], 18); + x.words[6] ^= CRYPTO_rotl_u32(x.words[5] + x.words[4], 7); + x.words[7] ^= CRYPTO_rotl_u32(x.words[6] + x.words[5], 9); + x.words[4] ^= CRYPTO_rotl_u32(x.words[7] + x.words[6], 13); + x.words[5] ^= CRYPTO_rotl_u32(x.words[4] + x.words[7], 18); + x.words[11] ^= CRYPTO_rotl_u32(x.words[10] + x.words[9], 7); + x.words[8] ^= CRYPTO_rotl_u32(x.words[11] + x.words[10], 9); + x.words[9] ^= CRYPTO_rotl_u32(x.words[8] + x.words[11], 13); + x.words[10] ^= CRYPTO_rotl_u32(x.words[9] + x.words[8], 18); + x.words[12] ^= CRYPTO_rotl_u32(x.words[15] + x.words[14], 7); + x.words[13] ^= CRYPTO_rotl_u32(x.words[12] + x.words[15], 9); + x.words[14] ^= CRYPTO_rotl_u32(x.words[13] + x.words[12], 13); + x.words[15] ^= CRYPTO_rotl_u32(x.words[14] + x.words[13], 18); + } + + for (int i = 0; i < 16; ++i) { + inout->words[i] += x.words[i]; + } +} + +// xor_block sets |*out| to be |*a| XOR |*b|. +static void xor_block(block_t *out, const block_t *a, const block_t *b) { + for (size_t i = 0; i < 16; i++) { + out->words[i] = a->words[i] ^ b->words[i]; + } +} + +// scryptBlockMix implements the function described in RFC 7914, section 4. B' +// is written to |out|. |out| and |B| may not alias and must be each one scrypt +// block (2 * |r| Salsa20 blocks) long. +static void scryptBlockMix(block_t *out, const block_t *B, uint64_t r) { + assert(out != B); + + block_t X; + OPENSSL_memcpy(&X, &B[r * 2 - 1], sizeof(X)); + for (uint64_t i = 0; i < r * 2; i++) { + xor_block(&X, &X, &B[i]); + salsa208_word_specification(&X); + + // This implements the permutation in step 3. + OPENSSL_memcpy(&out[i / 2 + (i & 1) * r], &X, sizeof(X)); + } +} + +// scryptROMix implements the function described in RFC 7914, section 5. |B| is +// an scrypt block (2 * |r| Salsa20 blocks) and is modified in-place. |T| and +// |V| are scratch space allocated by the caller. |T| must have space for one +// scrypt block (2 * |r| Salsa20 blocks). |V| must have space for |N| scrypt +// blocks (2 * |r| * |N| Salsa20 blocks). +static void scryptROMix(block_t *B, uint64_t r, uint64_t N, block_t *T, + block_t *V) { + // Steps 1 and 2. + OPENSSL_memcpy(V, B, 2 * r * sizeof(block_t)); + for (uint64_t i = 1; i < N; i++) { + scryptBlockMix(&V[2 * r * i /* scrypt block i */], + &V[2 * r * (i - 1) /* scrypt block i-1 */], r); + } + scryptBlockMix(B, &V[2 * r * (N - 1) /* scrypt block N-1 */], r); + + // Step 3. + for (uint64_t i = 0; i < N; i++) { + // Note this assumes |N| <= 2^32 and is a power of 2. + uint32_t j = B[2 * r - 1].words[0] & (N - 1); + for (size_t k = 0; k < 2 * r; k++) { + xor_block(&T[k], &B[k], &V[2 * r * j + k]); + } + scryptBlockMix(B, T, r); + } +} + +// SCRYPT_PR_MAX is the maximum value of p * r. This is equivalent to the +// bounds on p in section 6: +// +// p <= ((2^32-1) * hLen) / MFLen iff +// p <= ((2^32-1) * 32) / (128 * r) iff +// p * r <= (2^30-1) +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +// SCRYPT_MAX_MEM is the default maximum memory that may be allocated by +// |EVP_PBE_scrypt|. +#define SCRYPT_MAX_MEM (1024 * 1024 * 32) + +int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, uint64_t N, uint64_t r, + uint64_t p, size_t max_mem, uint8_t *out_key, + size_t key_len) { + if (r == 0 || p == 0 || p > SCRYPT_PR_MAX / r || + // |N| must be a power of two. + N < 2 || (N & (N - 1)) || + // We only support |N| <= 2^32 in |scryptROMix|. + N > UINT64_C(1) << 32 || + // Check that |N| < 2^(128×r / 8). + (16 * r <= 63 && N >= UINT64_C(1) << (16 * r))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PARAMETERS); + return 0; + } + + // Determine the amount of memory needed. B, T, and V are |p|, 1, and |N| + // scrypt blocks, respectively. Each scrypt block is 2*|r| |block_t|s. + if (max_mem == 0) { + max_mem = SCRYPT_MAX_MEM; + } + + size_t max_scrypt_blocks = max_mem / (2 * r * sizeof(block_t)); + if (max_scrypt_blocks < p + 1 || + max_scrypt_blocks - p - 1 < N) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + // Allocate and divide up the scratch space. |max_mem| fits in a size_t, which + // is no bigger than uint64_t, so none of these operations may overflow. + OPENSSL_STATIC_ASSERT(UINT64_MAX >= ((size_t)-1), "size_t exceeds uint64_t"); + size_t B_blocks = p * 2 * r; + size_t B_bytes = B_blocks * sizeof(block_t); + size_t T_blocks = 2 * r; + size_t V_blocks = N * 2 * r; + block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t)); + if (B == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + block_t *T = B + B_blocks; + block_t *V = T + T_blocks; + + // NOTE: PKCS5_PBKDF2_HMAC can only fail due to allocation failure + // or |iterations| of 0 (we pass 1 here). This is consistent with + // the documented failure conditions of EVP_PBE_scrypt. + if (!PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, 1, + EVP_sha256(), B_bytes, (uint8_t *)B)) { + goto err; + } + + for (uint64_t i = 0; i < p; i++) { + scryptROMix(B + 2 * r * i, r, N, T, V); + } + + if (!PKCS5_PBKDF2_HMAC(password, password_len, (const uint8_t *)B, B_bytes, 1, + EVP_sha256(), key_len, out_key)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(B); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/sign.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/sign.c new file mode 100644 index 00000000..38b76f15 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/evp/sign.c @@ -0,0 +1,151 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "internal.h" + + +int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + size_t sig_len = EVP_PKEY_size(pkey); + + *out_sig_len = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || + !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { + goto out; + } + *out_sig_len = sig_len; + ret = 1; + +out: + if (pkctx) { + EVP_PKEY_CTX_free(pkctx); + } + + return ret; +} + +int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + EVP_MD_CTX_cleanup(&tmp_ctx); + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || + !EVP_PKEY_verify_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) { + goto out; + } + ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len); + +out: + EVP_PKEY_CTX_free(pkctx); + return ret; +} + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ex_data.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ex_data.c new file mode 100644 index 00000000..dd311f88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/ex_data.c @@ -0,0 +1,261 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + + +DEFINE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +struct crypto_ex_data_func_st { + long argl; // Arbitary long + void *argp; // Arbitary void pointer + CRYPTO_EX_free *free_func; +}; + +int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, + long argl, void *argp, CRYPTO_EX_free *free_func) { + CRYPTO_EX_DATA_FUNCS *funcs; + int ret = 0; + + funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + if (funcs == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + funcs->argl = argl; + funcs->argp = argp; + funcs->free_func = free_func; + + CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock); + + if (ex_data_class->meth == NULL) { + ex_data_class->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + } + + if (ex_data_class->meth == NULL || + !sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_free(funcs); + goto err; + } + + *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + + ex_data_class->num_reserved; + ret = 1; + +err: + CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock); + return ret; +} + +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) { + int n, i; + + if (ad->sk == NULL) { + ad->sk = sk_void_new_null(); + if (ad->sk == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + n = sk_void_num(ad->sk); + + // Add NULL values until the stack is long enough. + for (i = n; i <= index; i++) { + if (!sk_void_push(ad->sk, NULL)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + sk_void_set(ad->sk, index, val); + return 1; +} + +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { + if (ad->sk == NULL || idx < 0 || (size_t)idx >= sk_void_num(ad->sk)) { + return NULL; + } + return sk_void_value(ad->sk, idx); +} + +// get_func_pointers takes a copy of the CRYPTO_EX_DATA_FUNCS pointers, if any, +// for the given class. If there are some pointers, it sets |*out| to point to +// a fresh stack of them. Otherwise it sets |*out| to NULL. It returns one on +// success or zero on error. +static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, + CRYPTO_EX_DATA_CLASS *ex_data_class) { + size_t n; + + *out = NULL; + + // CRYPTO_EX_DATA_FUNCS structures are static once set, so we can take a + // shallow copy of the list under lock and then use the structures without + // the lock held. + CRYPTO_STATIC_MUTEX_lock_read(&ex_data_class->lock); + n = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth); + if (n > 0) { + *out = sk_CRYPTO_EX_DATA_FUNCS_dup(ex_data_class->meth); + } + CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock); + + if (n > 0 && *out == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { + ad->sk = NULL; +} + +void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, + CRYPTO_EX_DATA *ad) { + if (ad->sk == NULL) { + // Nothing to do. + return; + } + + STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; + if (!get_func_pointers(&func_pointers, ex_data_class)) { + // TODO(davidben): This leaks memory on malloc error. + return; + } + + for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { + CRYPTO_EX_DATA_FUNCS *func_pointer = + sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); + if (func_pointer->free_func) { + void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved); + func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved, + func_pointer->argl, func_pointer->argp); + } + } + + sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers); + + sk_void_free(ad->sk); + ad->sk = NULL; +} + +void CRYPTO_cleanup_all_ex_data(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes.c new file mode 100644 index 00000000..39053138 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes.c @@ -0,0 +1,106 @@ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include + +#include "internal.h" +#include "../modes/internal.h" + + +// Be aware that different sets of AES functions use incompatible key +// representations, varying in format of the key schedule, the |AES_KEY.rounds| +// value, or both. Therefore they cannot mix. Also, on AArch64, the plain-C +// code, above, is incompatible with the |aes_hw_*| functions. + +void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_encrypt(in, out, key); + } else if (vpaes_capable()) { + vpaes_encrypt(in, out, key); + } else { + aes_nohw_encrypt(in, out, key); + } +} + +void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_decrypt(in, out, key); + } else if (vpaes_capable()) { + vpaes_decrypt(in, out, key); + } else { + aes_nohw_decrypt(in, out, key); + } +} + +int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (bits != 128 && bits != 192 && bits != 256) { + return -2; + } + if (hwaes_capable()) { + return aes_hw_set_encrypt_key(key, bits, aeskey); + } else if (vpaes_capable()) { + return vpaes_set_encrypt_key(key, bits, aeskey); + } else { + return aes_nohw_set_encrypt_key(key, bits, aeskey); + } +} + +int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (bits != 128 && bits != 192 && bits != 256) { + return -2; + } + if (hwaes_capable()) { + return aes_hw_set_decrypt_key(key, bits, aeskey); + } else if (vpaes_capable()) { + return vpaes_set_decrypt_key(key, bits, aeskey); + } else { + return aes_nohw_set_decrypt_key(key, bits, aeskey); + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes_nohw.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes_nohw.c new file mode 100644 index 00000000..27769af4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes_nohw.c @@ -0,0 +1,1282 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "../../internal.h" + +#if defined(OPENSSL_SSE2) +#include +#endif + + +// This file contains a constant-time implementation of AES, bitsliced with +// 32-bit, 64-bit, or 128-bit words, operating on two-, four-, and eight-block +// batches, respectively. The 128-bit implementation requires SSE2 intrinsics. +// +// This implementation is based on the algorithms described in the following +// references: +// - https://bearssl.org/constanttime.html#aes +// - https://eprint.iacr.org/2009/129.pdf +// - https://eprint.iacr.org/2009/191.pdf + + +// Word operations. +// +// An aes_word_t is the word used for this AES implementation. Throughout this +// file, bits and bytes are ordered little-endian, though "left" and "right" +// shifts match the operations themselves, which makes them reversed in a +// little-endian, left-to-right reading. +// +// Eight |aes_word_t|s contain |AES_NOHW_BATCH_SIZE| blocks. The bits in an +// |aes_word_t| are divided into 16 consecutive groups of |AES_NOHW_BATCH_SIZE| +// bits each, each corresponding to a byte in an AES block in column-major +// order (AES's byte order). We refer to these as "logical bytes". Note, in the +// 32-bit and 64-bit implementations, they are smaller than a byte. (The +// contents of a logical byte will be described later.) +// +// MSVC does not support C bit operators on |__m128i|, so the wrapper functions +// |aes_nohw_and|, etc., should be used instead. Note |aes_nohw_shift_left| and +// |aes_nohw_shift_right| measure the shift in logical bytes. That is, the shift +// value ranges from 0 to 15 independent of |aes_word_t| and +// |AES_NOHW_BATCH_SIZE|. +// +// This ordering is different from https://eprint.iacr.org/2009/129.pdf, which +// uses row-major order. Matching the AES order was easier to reason about, and +// we do not have PSHUFB available to arbitrarily permute bytes. + +#if defined(OPENSSL_SSE2) +typedef __m128i aes_word_t; +// AES_NOHW_WORD_SIZE is sizeof(aes_word_t). alignas(sizeof(T)) does not work in +// MSVC, so we define a constant. +#define AES_NOHW_WORD_SIZE 16 +#define AES_NOHW_BATCH_SIZE 8 +#define AES_NOHW_ROW0_MASK \ + _mm_set_epi32(0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff) +#define AES_NOHW_ROW1_MASK \ + _mm_set_epi32(0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00) +#define AES_NOHW_ROW2_MASK \ + _mm_set_epi32(0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000) +#define AES_NOHW_ROW3_MASK \ + _mm_set_epi32(0xff000000, 0xff000000, 0xff000000, 0xff000000) +#define AES_NOHW_COL01_MASK \ + _mm_set_epi32(0x00000000, 0x00000000, 0xffffffff, 0xffffffff) +#define AES_NOHW_COL2_MASK \ + _mm_set_epi32(0x00000000, 0xffffffff, 0x00000000, 0x00000000) +#define AES_NOHW_COL3_MASK \ + _mm_set_epi32(0xffffffff, 0x00000000, 0x00000000, 0x00000000) + +static inline aes_word_t aes_nohw_and(aes_word_t a, aes_word_t b) { + return _mm_and_si128(a, b); +} + +static inline aes_word_t aes_nohw_or(aes_word_t a, aes_word_t b) { + return _mm_or_si128(a, b); +} + +static inline aes_word_t aes_nohw_xor(aes_word_t a, aes_word_t b) { + return _mm_xor_si128(a, b); +} + +static inline aes_word_t aes_nohw_not(aes_word_t a) { + return _mm_xor_si128( + a, _mm_set_epi32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff)); +} + +// These are macros because parameters to |_mm_slli_si128| and |_mm_srli_si128| +// must be constants. +#define aes_nohw_shift_left(/* aes_word_t */ a, /* const */ i) \ + _mm_slli_si128((a), (i)) +#define aes_nohw_shift_right(/* aes_word_t */ a, /* const */ i) \ + _mm_srli_si128((a), (i)) +#else // !OPENSSL_SSE2 +#if defined(OPENSSL_64_BIT) +typedef uint64_t aes_word_t; +#define AES_NOHW_WORD_SIZE 8 +#define AES_NOHW_BATCH_SIZE 4 +#define AES_NOHW_ROW0_MASK UINT64_C(0x000f000f000f000f) +#define AES_NOHW_ROW1_MASK UINT64_C(0x00f000f000f000f0) +#define AES_NOHW_ROW2_MASK UINT64_C(0x0f000f000f000f00) +#define AES_NOHW_ROW3_MASK UINT64_C(0xf000f000f000f000) +#define AES_NOHW_COL01_MASK UINT64_C(0x00000000ffffffff) +#define AES_NOHW_COL2_MASK UINT64_C(0x0000ffff00000000) +#define AES_NOHW_COL3_MASK UINT64_C(0xffff000000000000) +#else // !OPENSSL_64_BIT +typedef uint32_t aes_word_t; +#define AES_NOHW_WORD_SIZE 4 +#define AES_NOHW_BATCH_SIZE 2 +#define AES_NOHW_ROW0_MASK 0x03030303 +#define AES_NOHW_ROW1_MASK 0x0c0c0c0c +#define AES_NOHW_ROW2_MASK 0x30303030 +#define AES_NOHW_ROW3_MASK 0xc0c0c0c0 +#define AES_NOHW_COL01_MASK 0x0000ffff +#define AES_NOHW_COL2_MASK 0x00ff0000 +#define AES_NOHW_COL3_MASK 0xff000000 +#endif // OPENSSL_64_BIT + +static inline aes_word_t aes_nohw_and(aes_word_t a, aes_word_t b) { + return a & b; +} + +static inline aes_word_t aes_nohw_or(aes_word_t a, aes_word_t b) { + return a | b; +} + +static inline aes_word_t aes_nohw_xor(aes_word_t a, aes_word_t b) { + return a ^ b; +} + +static inline aes_word_t aes_nohw_not(aes_word_t a) { return ~a; } + +static inline aes_word_t aes_nohw_shift_left(aes_word_t a, aes_word_t i) { + return a << (i * AES_NOHW_BATCH_SIZE); +} + +static inline aes_word_t aes_nohw_shift_right(aes_word_t a, aes_word_t i) { + return a >> (i * AES_NOHW_BATCH_SIZE); +} +#endif // OPENSSL_SSE2 + +OPENSSL_STATIC_ASSERT(AES_NOHW_BATCH_SIZE * 128 == 8 * 8 * sizeof(aes_word_t), + "batch size does not match word size"); +OPENSSL_STATIC_ASSERT(AES_NOHW_WORD_SIZE == sizeof(aes_word_t), + "AES_NOHW_WORD_SIZE is incorrect"); + + +// Block representations. +// +// This implementation uses three representations for AES blocks. First, the +// public API represents blocks as uint8_t[16] in the usual way. Second, most +// AES steps are evaluated in bitsliced form, stored in an |AES_NOHW_BATCH|. +// This stores |AES_NOHW_BATCH_SIZE| blocks in bitsliced order. For 64-bit words +// containing bitsliced blocks a, b, c, d, this would be as follows (vertical +// bars divide logical bytes): +// +// batch.w[0] = a0 b0 c0 d0 | a8 b8 c8 d8 | a16 b16 c16 d16 ... +// batch.w[1] = a1 b1 c1 d1 | a9 b9 c9 d9 | a17 b17 c17 d17 ... +// batch.w[2] = a2 b2 c2 d2 | a10 b10 c10 d10 | a18 b18 c18 d18 ... +// batch.w[3] = a3 b3 c3 d3 | a11 b11 c11 d11 | a19 b19 c19 d19 ... +// ... +// +// Finally, an individual block may be stored as an intermediate form in an +// aes_word_t[AES_NOHW_BLOCK_WORDS]. In this form, we permute the bits in each +// block, so that block[0]'s ith logical byte contains least-significant +// |AES_NOHW_BATCH_SIZE| bits of byte i, block[1] contains the next group of +// |AES_NOHW_BATCH_SIZE| bits, and so on. We refer to this transformation as +// "compacting" the block. Note this is no-op with 128-bit words because then +// |AES_NOHW_BLOCK_WORDS| is one and |AES_NOHW_BATCH_SIZE| is eight. For 64-bit +// words, one block would be stored in two words: +// +// block[0] = a0 a1 a2 a3 | a8 a9 a10 a11 | a16 a17 a18 a19 ... +// block[1] = a4 a5 a6 a7 | a12 a13 a14 a15 | a20 a21 a22 a23 ... +// +// Observe that the distances between corresponding bits in bitsliced and +// compact bit orders match. If we line up corresponding words of each block, +// the bitsliced and compact representations may be converted by tranposing bits +// in corresponding logical bytes. Continuing the 64-bit example: +// +// block_a[0] = a0 a1 a2 a3 | a8 a9 a10 a11 | a16 a17 a18 a19 ... +// block_b[0] = b0 b1 b2 b3 | b8 b9 b10 b11 | b16 b17 b18 b19 ... +// block_c[0] = c0 c1 c2 c3 | c8 c9 c10 c11 | c16 c17 c18 c19 ... +// block_d[0] = d0 d1 d2 d3 | d8 d9 d10 d11 | d16 d17 d18 d19 ... +// +// batch.w[0] = a0 b0 c0 d0 | a8 b8 c8 d8 | a16 b16 c16 d16 ... +// batch.w[1] = a1 b1 c1 d1 | a9 b9 c9 d9 | a17 b17 c17 d17 ... +// batch.w[2] = a2 b2 c2 d2 | a10 b10 c10 d10 | a18 b18 c18 d18 ... +// batch.w[3] = a3 b3 c3 d3 | a11 b11 c11 d11 | a19 b19 c19 d19 ... +// +// Note also that bitwise operations and (logical) byte permutations on an +// |aes_word_t| work equally for the bitsliced and compact words. +// +// We use the compact form in the |AES_KEY| representation to save work +// inflating round keys into |AES_NOHW_BATCH|. The compact form also exists +// temporarily while moving blocks in or out of an |AES_NOHW_BATCH|, immediately +// before or after |aes_nohw_transpose|. + +#define AES_NOHW_BLOCK_WORDS (16 / sizeof(aes_word_t)) + +// An AES_NOHW_BATCH stores |AES_NOHW_BATCH_SIZE| blocks. Unless otherwise +// specified, it is in bitsliced form. +typedef struct { + aes_word_t w[8]; +} AES_NOHW_BATCH; + +// An AES_NOHW_SCHEDULE is an expanded bitsliced AES key schedule. It is +// suitable for encryption or decryption. It is as large as |AES_NOHW_BATCH| +// |AES_KEY|s so it should not be used as a long-term key representation. +typedef struct { + // keys is an array of batches, one for each round key. Each batch stores + // |AES_NOHW_BATCH_SIZE| copies of the round key in bitsliced form. + AES_NOHW_BATCH keys[AES_MAXNR + 1]; +} AES_NOHW_SCHEDULE; + +// aes_nohw_batch_set sets the |i|th block of |batch| to |in|. |batch| is in +// compact form. +static inline void aes_nohw_batch_set(AES_NOHW_BATCH *batch, + const aes_word_t in[AES_NOHW_BLOCK_WORDS], + size_t i) { + // Note the words are interleaved. The order comes from |aes_nohw_transpose|. + // If |i| is zero and this is the 64-bit implementation, in[0] contains bits + // 0-3 and in[1] contains bits 4-7. We place in[0] at w[0] and in[1] at + // w[4] so that bits 0 and 4 are in the correct position. (In general, bits + // along diagonals of |AES_NOHW_BATCH_SIZE| by |AES_NOHW_BATCH_SIZE| squares + // will be correctly placed.) + assert(i < AES_NOHW_BATCH_SIZE); +#if defined(OPENSSL_SSE2) + batch->w[i] = in[0]; +#elif defined(OPENSSL_64_BIT) + batch->w[i] = in[0]; + batch->w[i + 4] = in[1]; +#else + batch->w[i] = in[0]; + batch->w[i + 2] = in[1]; + batch->w[i + 4] = in[2]; + batch->w[i + 6] = in[3]; +#endif +} + +// aes_nohw_batch_get writes the |i|th block of |batch| to |out|. |batch| is in +// compact form. +static inline void aes_nohw_batch_get(const AES_NOHW_BATCH *batch, + aes_word_t out[AES_NOHW_BLOCK_WORDS], + size_t i) { + assert(i < AES_NOHW_BATCH_SIZE); +#if defined(OPENSSL_SSE2) + out[0] = batch->w[i]; +#elif defined(OPENSSL_64_BIT) + out[0] = batch->w[i]; + out[1] = batch->w[i + 4]; +#else + out[0] = batch->w[i]; + out[1] = batch->w[i + 2]; + out[2] = batch->w[i + 4]; + out[3] = batch->w[i + 6]; +#endif +} + +#if !defined(OPENSSL_SSE2) +// aes_nohw_delta_swap returns |a| with bits |a & mask| and +// |a & (mask << shift)| swapped. |mask| and |mask << shift| may not overlap. +static inline aes_word_t aes_nohw_delta_swap(aes_word_t a, aes_word_t mask, + aes_word_t shift) { + // See + // https://reflectionsonsecurity.wordpress.com/2014/05/11/efficient-bit-permutation-using-delta-swaps/ + aes_word_t b = (a ^ (a >> shift)) & mask; + return a ^ b ^ (b << shift); +} + +// In the 32-bit and 64-bit implementations, a block spans multiple words. +// |aes_nohw_compact_block| must permute bits across different words. First we +// implement |aes_nohw_compact_word| which performs a smaller version of the +// transformation which stays within a single word. +// +// These transformations are generalizations of the output of +// http://programming.sirrida.de/calcperm.php on smaller inputs. +#if defined(OPENSSL_64_BIT) +static inline uint64_t aes_nohw_compact_word(uint64_t a) { + // Numbering the 64/2 = 16 4-bit chunks, least to most significant, we swap + // quartets of those chunks: + // 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 13 14 15 => + // 0 2 1 3 | 4 6 5 7 | 8 10 9 11 | 12 14 13 15 + a = aes_nohw_delta_swap(a, UINT64_C(0x00f000f000f000f0), 4); + // Swap quartets of 8-bit chunks (still numbering by 4-bit chunks): + // 0 2 1 3 | 4 6 5 7 | 8 10 9 11 | 12 14 13 15 => + // 0 2 4 6 | 1 3 5 7 | 8 10 12 14 | 9 11 13 15 + a = aes_nohw_delta_swap(a, UINT64_C(0x0000ff000000ff00), 8); + // Swap quartets of 16-bit chunks (still numbering by 4-bit chunks): + // 0 2 4 6 | 1 3 5 7 | 8 10 12 14 | 9 11 13 15 => + // 0 2 4 6 | 8 10 12 14 | 1 3 5 7 | 9 11 13 15 + a = aes_nohw_delta_swap(a, UINT64_C(0x00000000ffff0000), 16); + return a; +} + +static inline uint64_t aes_nohw_uncompact_word(uint64_t a) { + // Reverse the steps of |aes_nohw_uncompact_word|. + a = aes_nohw_delta_swap(a, UINT64_C(0x00000000ffff0000), 16); + a = aes_nohw_delta_swap(a, UINT64_C(0x0000ff000000ff00), 8); + a = aes_nohw_delta_swap(a, UINT64_C(0x00f000f000f000f0), 4); + return a; +} +#else // !OPENSSL_64_BIT +static inline uint32_t aes_nohw_compact_word(uint32_t a) { + // Numbering the 32/2 = 16 pairs of bits, least to most significant, we swap: + // 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 13 14 15 => + // 0 4 2 6 | 1 5 3 7 | 8 12 10 14 | 9 13 11 15 + // Note: 0x00cc = 0b0000_0000_1100_1100 + // 0x00cc << 6 = 0b0011_0011_0000_0000 + a = aes_nohw_delta_swap(a, 0x00cc00cc, 6); + // Now we swap groups of four bits (still numbering by pairs): + // 0 4 2 6 | 1 5 3 7 | 8 12 10 14 | 9 13 11 15 => + // 0 4 8 12 | 1 5 9 13 | 2 6 10 14 | 3 7 11 15 + // Note: 0x0000_f0f0 << 12 = 0x0f0f_0000 + a = aes_nohw_delta_swap(a, 0x0000f0f0, 12); + return a; +} + +static inline uint32_t aes_nohw_uncompact_word(uint32_t a) { + // Reverse the steps of |aes_nohw_uncompact_word|. + a = aes_nohw_delta_swap(a, 0x0000f0f0, 12); + a = aes_nohw_delta_swap(a, 0x00cc00cc, 6); + return a; +} + +static inline uint32_t aes_nohw_word_from_bytes(uint8_t a0, uint8_t a1, + uint8_t a2, uint8_t a3) { + return (uint32_t)a0 | ((uint32_t)a1 << 8) | ((uint32_t)a2 << 16) | + ((uint32_t)a3 << 24); +} +#endif // OPENSSL_64_BIT +#endif // !OPENSSL_SSE2 + +static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], + const uint8_t in[16]) { + memcpy(out, in, 16); +#if defined(OPENSSL_SSE2) + // No conversions needed. +#elif defined(OPENSSL_64_BIT) + uint64_t a0 = aes_nohw_compact_word(out[0]); + uint64_t a1 = aes_nohw_compact_word(out[1]); + out[0] = (a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32); + out[1] = (a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32); +#else + uint32_t a0 = aes_nohw_compact_word(out[0]); + uint32_t a1 = aes_nohw_compact_word(out[1]); + uint32_t a2 = aes_nohw_compact_word(out[2]); + uint32_t a3 = aes_nohw_compact_word(out[3]); + // Note clang, when building for ARM Thumb2, will sometimes miscompile + // expressions such as (a0 & 0x0000ff00) << 8, particularly when building + // without optimizations. This bug was introduced in + // https://reviews.llvm.org/rL340261 and fixed in + // https://reviews.llvm.org/rL351310. The following is written to avoid this. + out[0] = aes_nohw_word_from_bytes(a0, a1, a2, a3); + out[1] = aes_nohw_word_from_bytes(a0 >> 8, a1 >> 8, a2 >> 8, a3 >> 8); + out[2] = aes_nohw_word_from_bytes(a0 >> 16, a1 >> 16, a2 >> 16, a3 >> 16); + out[3] = aes_nohw_word_from_bytes(a0 >> 24, a1 >> 24, a2 >> 24, a3 >> 24); +#endif +} + +static inline void aes_nohw_uncompact_block( + uint8_t out[16], const aes_word_t in[AES_NOHW_BLOCK_WORDS]) { +#if defined(OPENSSL_SSE2) + memcpy(out, in, 16); // No conversions needed. +#elif defined(OPENSSL_64_BIT) + uint64_t a0 = in[0]; + uint64_t a1 = in[1]; + uint64_t b0 = + aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32)); + uint64_t b1 = + aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32)); + memcpy(out, &b0, 8); + memcpy(out + 8, &b1, 8); +#else + uint32_t a0 = in[0]; + uint32_t a1 = in[1]; + uint32_t a2 = in[2]; + uint32_t a3 = in[3]; + // Note clang, when building for ARM Thumb2, will sometimes miscompile + // expressions such as (a0 & 0x0000ff00) << 8, particularly when building + // without optimizations. This bug was introduced in + // https://reviews.llvm.org/rL340261 and fixed in + // https://reviews.llvm.org/rL351310. The following is written to avoid this. + uint32_t b0 = aes_nohw_word_from_bytes(a0, a1, a2, a3); + uint32_t b1 = aes_nohw_word_from_bytes(a0 >> 8, a1 >> 8, a2 >> 8, a3 >> 8); + uint32_t b2 = + aes_nohw_word_from_bytes(a0 >> 16, a1 >> 16, a2 >> 16, a3 >> 16); + uint32_t b3 = + aes_nohw_word_from_bytes(a0 >> 24, a1 >> 24, a2 >> 24, a3 >> 24); + b0 = aes_nohw_uncompact_word(b0); + b1 = aes_nohw_uncompact_word(b1); + b2 = aes_nohw_uncompact_word(b2); + b3 = aes_nohw_uncompact_word(b3); + memcpy(out, &b0, 4); + memcpy(out + 4, &b1, 4); + memcpy(out + 8, &b2, 4); + memcpy(out + 12, &b3, 4); +#endif +} + +// aes_nohw_swap_bits is a variation on a delta swap. It swaps the bits in +// |*a & (mask << shift)| with the bits in |*b & mask|. |mask| and +// |mask << shift| must not overlap. |mask| is specified as a |uint32_t|, but it +// is repeated to the full width of |aes_word_t|. +#if defined(OPENSSL_SSE2) +// This must be a macro because |_mm_srli_epi32| and |_mm_slli_epi32| require +// constant shift values. +#define aes_nohw_swap_bits(/*__m128i* */ a, /*__m128i* */ b, \ + /* uint32_t */ mask, /* const */ shift) \ + do { \ + __m128i swap = \ + _mm_and_si128(_mm_xor_si128(_mm_srli_epi32(*(a), (shift)), *(b)), \ + _mm_set_epi32((mask), (mask), (mask), (mask))); \ + *(a) = _mm_xor_si128(*(a), _mm_slli_epi32(swap, (shift))); \ + *(b) = _mm_xor_si128(*(b), swap); \ + \ + } while (0) +#else +static inline void aes_nohw_swap_bits(aes_word_t *a, aes_word_t *b, + uint32_t mask, aes_word_t shift) { +#if defined(OPENSSL_64_BIT) + aes_word_t mask_w = (((uint64_t)mask) << 32) | mask; +#else + aes_word_t mask_w = mask; +#endif + // This is a variation on a delta swap. + aes_word_t swap = ((*a >> shift) ^ *b) & mask_w; + *a ^= swap << shift; + *b ^= swap; +} +#endif // OPENSSL_SSE2 + +// aes_nohw_transpose converts |batch| to and from bitsliced form. It divides +// the 8 × word_size bits into AES_NOHW_BATCH_SIZE × AES_NOHW_BATCH_SIZE squares +// and transposes each square. +static void aes_nohw_transpose(AES_NOHW_BATCH *batch) { + // Swap bits with index 0 and 1 mod 2 (0x55 = 0b01010101). + aes_nohw_swap_bits(&batch->w[0], &batch->w[1], 0x55555555, 1); + aes_nohw_swap_bits(&batch->w[2], &batch->w[3], 0x55555555, 1); + aes_nohw_swap_bits(&batch->w[4], &batch->w[5], 0x55555555, 1); + aes_nohw_swap_bits(&batch->w[6], &batch->w[7], 0x55555555, 1); + +#if AES_NOHW_BATCH_SIZE >= 4 + // Swap bits with index 0-1 and 2-3 mod 4 (0x33 = 0b00110011). + aes_nohw_swap_bits(&batch->w[0], &batch->w[2], 0x33333333, 2); + aes_nohw_swap_bits(&batch->w[1], &batch->w[3], 0x33333333, 2); + aes_nohw_swap_bits(&batch->w[4], &batch->w[6], 0x33333333, 2); + aes_nohw_swap_bits(&batch->w[5], &batch->w[7], 0x33333333, 2); +#endif + +#if AES_NOHW_BATCH_SIZE >= 8 + // Swap bits with index 0-3 and 4-7 mod 8 (0x0f = 0b00001111). + aes_nohw_swap_bits(&batch->w[0], &batch->w[4], 0x0f0f0f0f, 4); + aes_nohw_swap_bits(&batch->w[1], &batch->w[5], 0x0f0f0f0f, 4); + aes_nohw_swap_bits(&batch->w[2], &batch->w[6], 0x0f0f0f0f, 4); + aes_nohw_swap_bits(&batch->w[3], &batch->w[7], 0x0f0f0f0f, 4); +#endif +} + +// aes_nohw_to_batch initializes |out| with the |num_blocks| blocks from |in|. +// |num_blocks| must be at most |AES_NOHW_BATCH|. +static void aes_nohw_to_batch(AES_NOHW_BATCH *out, const uint8_t *in, + size_t num_blocks) { + // Don't leave unused blocks uninitialized. + memset(out, 0, sizeof(AES_NOHW_BATCH)); + assert(num_blocks <= AES_NOHW_BATCH_SIZE); + for (size_t i = 0; i < num_blocks; i++) { + aes_word_t block[AES_NOHW_BLOCK_WORDS]; + aes_nohw_compact_block(block, in + 16 * i); + aes_nohw_batch_set(out, block, i); + } + + aes_nohw_transpose(out); +} + +// aes_nohw_to_batch writes the first |num_blocks| blocks in |batch| to |out|. +// |num_blocks| must be at most |AES_NOHW_BATCH|. +static void aes_nohw_from_batch(uint8_t *out, size_t num_blocks, + const AES_NOHW_BATCH *batch) { + AES_NOHW_BATCH copy = *batch; + aes_nohw_transpose(©); + + assert(num_blocks <= AES_NOHW_BATCH_SIZE); + for (size_t i = 0; i < num_blocks; i++) { + aes_word_t block[AES_NOHW_BLOCK_WORDS]; + aes_nohw_batch_get(©, block, i); + aes_nohw_uncompact_block(out + 16 * i, block); + } +} + + +// AES round steps. + +static void aes_nohw_add_round_key(AES_NOHW_BATCH *batch, + const AES_NOHW_BATCH *key) { + for (size_t i = 0; i < 8; i++) { + batch->w[i] = aes_nohw_xor(batch->w[i], key->w[i]); + } +} + +static void aes_nohw_sub_bytes(AES_NOHW_BATCH *batch) { + // See https://eprint.iacr.org/2009/191.pdf, Appendix C. + aes_word_t x0 = batch->w[7]; + aes_word_t x1 = batch->w[6]; + aes_word_t x2 = batch->w[5]; + aes_word_t x3 = batch->w[4]; + aes_word_t x4 = batch->w[3]; + aes_word_t x5 = batch->w[2]; + aes_word_t x6 = batch->w[1]; + aes_word_t x7 = batch->w[0]; + + // Figure 2, the top linear transformation. + aes_word_t y14 = aes_nohw_xor(x3, x5); + aes_word_t y13 = aes_nohw_xor(x0, x6); + aes_word_t y9 = aes_nohw_xor(x0, x3); + aes_word_t y8 = aes_nohw_xor(x0, x5); + aes_word_t t0 = aes_nohw_xor(x1, x2); + aes_word_t y1 = aes_nohw_xor(t0, x7); + aes_word_t y4 = aes_nohw_xor(y1, x3); + aes_word_t y12 = aes_nohw_xor(y13, y14); + aes_word_t y2 = aes_nohw_xor(y1, x0); + aes_word_t y5 = aes_nohw_xor(y1, x6); + aes_word_t y3 = aes_nohw_xor(y5, y8); + aes_word_t t1 = aes_nohw_xor(x4, y12); + aes_word_t y15 = aes_nohw_xor(t1, x5); + aes_word_t y20 = aes_nohw_xor(t1, x1); + aes_word_t y6 = aes_nohw_xor(y15, x7); + aes_word_t y10 = aes_nohw_xor(y15, t0); + aes_word_t y11 = aes_nohw_xor(y20, y9); + aes_word_t y7 = aes_nohw_xor(x7, y11); + aes_word_t y17 = aes_nohw_xor(y10, y11); + aes_word_t y19 = aes_nohw_xor(y10, y8); + aes_word_t y16 = aes_nohw_xor(t0, y11); + aes_word_t y21 = aes_nohw_xor(y13, y16); + aes_word_t y18 = aes_nohw_xor(x0, y16); + + // Figure 3, the middle non-linear section. + aes_word_t t2 = aes_nohw_and(y12, y15); + aes_word_t t3 = aes_nohw_and(y3, y6); + aes_word_t t4 = aes_nohw_xor(t3, t2); + aes_word_t t5 = aes_nohw_and(y4, x7); + aes_word_t t6 = aes_nohw_xor(t5, t2); + aes_word_t t7 = aes_nohw_and(y13, y16); + aes_word_t t8 = aes_nohw_and(y5, y1); + aes_word_t t9 = aes_nohw_xor(t8, t7); + aes_word_t t10 = aes_nohw_and(y2, y7); + aes_word_t t11 = aes_nohw_xor(t10, t7); + aes_word_t t12 = aes_nohw_and(y9, y11); + aes_word_t t13 = aes_nohw_and(y14, y17); + aes_word_t t14 = aes_nohw_xor(t13, t12); + aes_word_t t15 = aes_nohw_and(y8, y10); + aes_word_t t16 = aes_nohw_xor(t15, t12); + aes_word_t t17 = aes_nohw_xor(t4, t14); + aes_word_t t18 = aes_nohw_xor(t6, t16); + aes_word_t t19 = aes_nohw_xor(t9, t14); + aes_word_t t20 = aes_nohw_xor(t11, t16); + aes_word_t t21 = aes_nohw_xor(t17, y20); + aes_word_t t22 = aes_nohw_xor(t18, y19); + aes_word_t t23 = aes_nohw_xor(t19, y21); + aes_word_t t24 = aes_nohw_xor(t20, y18); + aes_word_t t25 = aes_nohw_xor(t21, t22); + aes_word_t t26 = aes_nohw_and(t21, t23); + aes_word_t t27 = aes_nohw_xor(t24, t26); + aes_word_t t28 = aes_nohw_and(t25, t27); + aes_word_t t29 = aes_nohw_xor(t28, t22); + aes_word_t t30 = aes_nohw_xor(t23, t24); + aes_word_t t31 = aes_nohw_xor(t22, t26); + aes_word_t t32 = aes_nohw_and(t31, t30); + aes_word_t t33 = aes_nohw_xor(t32, t24); + aes_word_t t34 = aes_nohw_xor(t23, t33); + aes_word_t t35 = aes_nohw_xor(t27, t33); + aes_word_t t36 = aes_nohw_and(t24, t35); + aes_word_t t37 = aes_nohw_xor(t36, t34); + aes_word_t t38 = aes_nohw_xor(t27, t36); + aes_word_t t39 = aes_nohw_and(t29, t38); + aes_word_t t40 = aes_nohw_xor(t25, t39); + aes_word_t t41 = aes_nohw_xor(t40, t37); + aes_word_t t42 = aes_nohw_xor(t29, t33); + aes_word_t t43 = aes_nohw_xor(t29, t40); + aes_word_t t44 = aes_nohw_xor(t33, t37); + aes_word_t t45 = aes_nohw_xor(t42, t41); + aes_word_t z0 = aes_nohw_and(t44, y15); + aes_word_t z1 = aes_nohw_and(t37, y6); + aes_word_t z2 = aes_nohw_and(t33, x7); + aes_word_t z3 = aes_nohw_and(t43, y16); + aes_word_t z4 = aes_nohw_and(t40, y1); + aes_word_t z5 = aes_nohw_and(t29, y7); + aes_word_t z6 = aes_nohw_and(t42, y11); + aes_word_t z7 = aes_nohw_and(t45, y17); + aes_word_t z8 = aes_nohw_and(t41, y10); + aes_word_t z9 = aes_nohw_and(t44, y12); + aes_word_t z10 = aes_nohw_and(t37, y3); + aes_word_t z11 = aes_nohw_and(t33, y4); + aes_word_t z12 = aes_nohw_and(t43, y13); + aes_word_t z13 = aes_nohw_and(t40, y5); + aes_word_t z14 = aes_nohw_and(t29, y2); + aes_word_t z15 = aes_nohw_and(t42, y9); + aes_word_t z16 = aes_nohw_and(t45, y14); + aes_word_t z17 = aes_nohw_and(t41, y8); + + // Figure 4, bottom linear transformation. + aes_word_t t46 = aes_nohw_xor(z15, z16); + aes_word_t t47 = aes_nohw_xor(z10, z11); + aes_word_t t48 = aes_nohw_xor(z5, z13); + aes_word_t t49 = aes_nohw_xor(z9, z10); + aes_word_t t50 = aes_nohw_xor(z2, z12); + aes_word_t t51 = aes_nohw_xor(z2, z5); + aes_word_t t52 = aes_nohw_xor(z7, z8); + aes_word_t t53 = aes_nohw_xor(z0, z3); + aes_word_t t54 = aes_nohw_xor(z6, z7); + aes_word_t t55 = aes_nohw_xor(z16, z17); + aes_word_t t56 = aes_nohw_xor(z12, t48); + aes_word_t t57 = aes_nohw_xor(t50, t53); + aes_word_t t58 = aes_nohw_xor(z4, t46); + aes_word_t t59 = aes_nohw_xor(z3, t54); + aes_word_t t60 = aes_nohw_xor(t46, t57); + aes_word_t t61 = aes_nohw_xor(z14, t57); + aes_word_t t62 = aes_nohw_xor(t52, t58); + aes_word_t t63 = aes_nohw_xor(t49, t58); + aes_word_t t64 = aes_nohw_xor(z4, t59); + aes_word_t t65 = aes_nohw_xor(t61, t62); + aes_word_t t66 = aes_nohw_xor(z1, t63); + aes_word_t s0 = aes_nohw_xor(t59, t63); + aes_word_t s6 = aes_nohw_xor(t56, aes_nohw_not(t62)); + aes_word_t s7 = aes_nohw_xor(t48, aes_nohw_not(t60)); + aes_word_t t67 = aes_nohw_xor(t64, t65); + aes_word_t s3 = aes_nohw_xor(t53, t66); + aes_word_t s4 = aes_nohw_xor(t51, t66); + aes_word_t s5 = aes_nohw_xor(t47, t65); + aes_word_t s1 = aes_nohw_xor(t64, aes_nohw_not(s3)); + aes_word_t s2 = aes_nohw_xor(t55, aes_nohw_not(t67)); + + batch->w[0] = s7; + batch->w[1] = s6; + batch->w[2] = s5; + batch->w[3] = s4; + batch->w[4] = s3; + batch->w[5] = s2; + batch->w[6] = s1; + batch->w[7] = s0; +} + +// aes_nohw_sub_bytes_inv_affine inverts the affine transform portion of the AES +// S-box, defined in FIPS PUB 197, section 5.1.1, step 2. +static void aes_nohw_sub_bytes_inv_affine(AES_NOHW_BATCH *batch) { + aes_word_t a0 = batch->w[0]; + aes_word_t a1 = batch->w[1]; + aes_word_t a2 = batch->w[2]; + aes_word_t a3 = batch->w[3]; + aes_word_t a4 = batch->w[4]; + aes_word_t a5 = batch->w[5]; + aes_word_t a6 = batch->w[6]; + aes_word_t a7 = batch->w[7]; + + // Apply the circulant [0 0 1 0 0 1 0 1]. This is the inverse of the circulant + // [1 0 0 0 1 1 1 1]. + aes_word_t b0 = aes_nohw_xor(a2, aes_nohw_xor(a5, a7)); + aes_word_t b1 = aes_nohw_xor(a3, aes_nohw_xor(a6, a0)); + aes_word_t b2 = aes_nohw_xor(a4, aes_nohw_xor(a7, a1)); + aes_word_t b3 = aes_nohw_xor(a5, aes_nohw_xor(a0, a2)); + aes_word_t b4 = aes_nohw_xor(a6, aes_nohw_xor(a1, a3)); + aes_word_t b5 = aes_nohw_xor(a7, aes_nohw_xor(a2, a4)); + aes_word_t b6 = aes_nohw_xor(a0, aes_nohw_xor(a3, a5)); + aes_word_t b7 = aes_nohw_xor(a1, aes_nohw_xor(a4, a6)); + + // XOR 0x05. Equivalently, we could XOR 0x63 before applying the circulant, + // but 0x05 has lower Hamming weight. (0x05 is the circulant applied to 0x63.) + batch->w[0] = aes_nohw_not(b0); + batch->w[1] = b1; + batch->w[2] = aes_nohw_not(b2); + batch->w[3] = b3; + batch->w[4] = b4; + batch->w[5] = b5; + batch->w[6] = b6; + batch->w[7] = b7; +} + +static void aes_nohw_inv_sub_bytes(AES_NOHW_BATCH *batch) { + // We implement the inverse S-box using the forwards implementation with the + // technique described in https://www.bearssl.org/constanttime.html#aes. + // + // The forwards S-box inverts its input and applies an affine transformation: + // S(x) = A(Inv(x)). Thus Inv(x) = InvA(S(x)). The inverse S-box is then: + // + // InvS(x) = Inv(InvA(x)). + // = InvA(S(InvA(x))) + aes_nohw_sub_bytes_inv_affine(batch); + aes_nohw_sub_bytes(batch); + aes_nohw_sub_bytes_inv_affine(batch); +} + +// aes_nohw_rotate_cols_right returns |v| with the columns in each row rotated +// to the right by |n|. This is a macro because |aes_nohw_shift_*| require +// constant shift counts in the SSE2 implementation. +#define aes_nohw_rotate_cols_right(/* aes_word_t */ v, /* const */ n) \ + (aes_nohw_or(aes_nohw_shift_right((v), (n)*4), \ + aes_nohw_shift_left((v), 16 - (n)*4))) + +static void aes_nohw_shift_rows(AES_NOHW_BATCH *batch) { + for (size_t i = 0; i < 8; i++) { + aes_word_t row0 = aes_nohw_and(batch->w[i], AES_NOHW_ROW0_MASK); + aes_word_t row1 = aes_nohw_and(batch->w[i], AES_NOHW_ROW1_MASK); + aes_word_t row2 = aes_nohw_and(batch->w[i], AES_NOHW_ROW2_MASK); + aes_word_t row3 = aes_nohw_and(batch->w[i], AES_NOHW_ROW3_MASK); + row1 = aes_nohw_rotate_cols_right(row1, 1); + row2 = aes_nohw_rotate_cols_right(row2, 2); + row3 = aes_nohw_rotate_cols_right(row3, 3); + batch->w[i] = aes_nohw_or(aes_nohw_or(row0, row1), aes_nohw_or(row2, row3)); + } +} + +static void aes_nohw_inv_shift_rows(AES_NOHW_BATCH *batch) { + for (size_t i = 0; i < 8; i++) { + aes_word_t row0 = aes_nohw_and(batch->w[i], AES_NOHW_ROW0_MASK); + aes_word_t row1 = aes_nohw_and(batch->w[i], AES_NOHW_ROW1_MASK); + aes_word_t row2 = aes_nohw_and(batch->w[i], AES_NOHW_ROW2_MASK); + aes_word_t row3 = aes_nohw_and(batch->w[i], AES_NOHW_ROW3_MASK); + row1 = aes_nohw_rotate_cols_right(row1, 3); + row2 = aes_nohw_rotate_cols_right(row2, 2); + row3 = aes_nohw_rotate_cols_right(row3, 1); + batch->w[i] = aes_nohw_or(aes_nohw_or(row0, row1), aes_nohw_or(row2, row3)); + } +} + +// aes_nohw_rotate_rows_down returns |v| with the rows in each column rotated +// down by one. +static inline aes_word_t aes_nohw_rotate_rows_down(aes_word_t v) { +#if defined(OPENSSL_SSE2) + return _mm_or_si128(_mm_srli_epi32(v, 8), _mm_slli_epi32(v, 24)); +#elif defined(OPENSSL_64_BIT) + return ((v >> 4) & UINT64_C(0x0fff0fff0fff0fff)) | + ((v << 12) & UINT64_C(0xf000f000f000f000)); +#else + return ((v >> 2) & 0x3f3f3f3f) | ((v << 6) & 0xc0c0c0c0); +#endif +} + +// aes_nohw_rotate_rows_twice returns |v| with the rows in each column rotated +// by two. +static inline aes_word_t aes_nohw_rotate_rows_twice(aes_word_t v) { +#if defined(OPENSSL_SSE2) + return _mm_or_si128(_mm_srli_epi32(v, 16), _mm_slli_epi32(v, 16)); +#elif defined(OPENSSL_64_BIT) + return ((v >> 8) & UINT64_C(0x00ff00ff00ff00ff)) | + ((v << 8) & UINT64_C(0xff00ff00ff00ff00)); +#else + return ((v >> 4) & 0x0f0f0f0f) | ((v << 4) & 0xf0f0f0f0); +#endif +} + +static void aes_nohw_mix_columns(AES_NOHW_BATCH *batch) { + // See https://eprint.iacr.org/2009/129.pdf, section 4.4 and appendix A. + aes_word_t a0 = batch->w[0]; + aes_word_t a1 = batch->w[1]; + aes_word_t a2 = batch->w[2]; + aes_word_t a3 = batch->w[3]; + aes_word_t a4 = batch->w[4]; + aes_word_t a5 = batch->w[5]; + aes_word_t a6 = batch->w[6]; + aes_word_t a7 = batch->w[7]; + + aes_word_t r0 = aes_nohw_rotate_rows_down(a0); + aes_word_t a0_r0 = aes_nohw_xor(a0, r0); + aes_word_t r1 = aes_nohw_rotate_rows_down(a1); + aes_word_t a1_r1 = aes_nohw_xor(a1, r1); + aes_word_t r2 = aes_nohw_rotate_rows_down(a2); + aes_word_t a2_r2 = aes_nohw_xor(a2, r2); + aes_word_t r3 = aes_nohw_rotate_rows_down(a3); + aes_word_t a3_r3 = aes_nohw_xor(a3, r3); + aes_word_t r4 = aes_nohw_rotate_rows_down(a4); + aes_word_t a4_r4 = aes_nohw_xor(a4, r4); + aes_word_t r5 = aes_nohw_rotate_rows_down(a5); + aes_word_t a5_r5 = aes_nohw_xor(a5, r5); + aes_word_t r6 = aes_nohw_rotate_rows_down(a6); + aes_word_t a6_r6 = aes_nohw_xor(a6, r6); + aes_word_t r7 = aes_nohw_rotate_rows_down(a7); + aes_word_t a7_r7 = aes_nohw_xor(a7, r7); + + batch->w[0] = + aes_nohw_xor(aes_nohw_xor(a7_r7, r0), aes_nohw_rotate_rows_twice(a0_r0)); + batch->w[1] = + aes_nohw_xor(aes_nohw_xor(a0_r0, a7_r7), + aes_nohw_xor(r1, aes_nohw_rotate_rows_twice(a1_r1))); + batch->w[2] = + aes_nohw_xor(aes_nohw_xor(a1_r1, r2), aes_nohw_rotate_rows_twice(a2_r2)); + batch->w[3] = + aes_nohw_xor(aes_nohw_xor(a2_r2, a7_r7), + aes_nohw_xor(r3, aes_nohw_rotate_rows_twice(a3_r3))); + batch->w[4] = + aes_nohw_xor(aes_nohw_xor(a3_r3, a7_r7), + aes_nohw_xor(r4, aes_nohw_rotate_rows_twice(a4_r4))); + batch->w[5] = + aes_nohw_xor(aes_nohw_xor(a4_r4, r5), aes_nohw_rotate_rows_twice(a5_r5)); + batch->w[6] = + aes_nohw_xor(aes_nohw_xor(a5_r5, r6), aes_nohw_rotate_rows_twice(a6_r6)); + batch->w[7] = + aes_nohw_xor(aes_nohw_xor(a6_r6, r7), aes_nohw_rotate_rows_twice(a7_r7)); +} + +static void aes_nohw_inv_mix_columns(AES_NOHW_BATCH *batch) { + aes_word_t a0 = batch->w[0]; + aes_word_t a1 = batch->w[1]; + aes_word_t a2 = batch->w[2]; + aes_word_t a3 = batch->w[3]; + aes_word_t a4 = batch->w[4]; + aes_word_t a5 = batch->w[5]; + aes_word_t a6 = batch->w[6]; + aes_word_t a7 = batch->w[7]; + + // bsaes-x86_64.pl describes the following decomposition of the inverse + // MixColumns matrix, credited to Jussi Kivilinna. This gives a much simpler + // multiplication. + // + // | 0e 0b 0d 09 | | 02 03 01 01 | | 05 00 04 00 | + // | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 | + // | 0d 09 0e 0b | | 01 01 02 03 | | 04 00 05 00 | + // | 0b 0d 09 0e | | 03 01 01 02 | | 00 04 00 05 | + // + // First, apply the [5 0 4 0] matrix. Multiplying by 4 in F_(2^8) is described + // by the following bit equations: + // + // b0 = a6 + // b1 = a6 ^ a7 + // b2 = a0 ^ a7 + // b3 = a1 ^ a6 + // b4 = a2 ^ a6 ^ a7 + // b5 = a3 ^ a7 + // b6 = a4 + // b7 = a5 + // + // Each coefficient is given by: + // + // b_ij = 05·a_ij ⊕ 04·a_i(j+2) = 04·(a_ij ⊕ a_i(j+2)) ⊕ a_ij + // + // We combine the two equations below. Note a_i(j+2) is a row rotation. + aes_word_t a0_r0 = aes_nohw_xor(a0, aes_nohw_rotate_rows_twice(a0)); + aes_word_t a1_r1 = aes_nohw_xor(a1, aes_nohw_rotate_rows_twice(a1)); + aes_word_t a2_r2 = aes_nohw_xor(a2, aes_nohw_rotate_rows_twice(a2)); + aes_word_t a3_r3 = aes_nohw_xor(a3, aes_nohw_rotate_rows_twice(a3)); + aes_word_t a4_r4 = aes_nohw_xor(a4, aes_nohw_rotate_rows_twice(a4)); + aes_word_t a5_r5 = aes_nohw_xor(a5, aes_nohw_rotate_rows_twice(a5)); + aes_word_t a6_r6 = aes_nohw_xor(a6, aes_nohw_rotate_rows_twice(a6)); + aes_word_t a7_r7 = aes_nohw_xor(a7, aes_nohw_rotate_rows_twice(a7)); + + batch->w[0] = aes_nohw_xor(a0, a6_r6); + batch->w[1] = aes_nohw_xor(a1, aes_nohw_xor(a6_r6, a7_r7)); + batch->w[2] = aes_nohw_xor(a2, aes_nohw_xor(a0_r0, a7_r7)); + batch->w[3] = aes_nohw_xor(a3, aes_nohw_xor(a1_r1, a6_r6)); + batch->w[4] = + aes_nohw_xor(aes_nohw_xor(a4, a2_r2), aes_nohw_xor(a6_r6, a7_r7)); + batch->w[5] = aes_nohw_xor(a5, aes_nohw_xor(a3_r3, a7_r7)); + batch->w[6] = aes_nohw_xor(a6, a4_r4); + batch->w[7] = aes_nohw_xor(a7, a5_r5); + + // Apply the [02 03 01 01] matrix, which is just MixColumns. + aes_nohw_mix_columns(batch); +} + +static void aes_nohw_encrypt_batch(const AES_NOHW_SCHEDULE *key, + size_t num_rounds, AES_NOHW_BATCH *batch) { + aes_nohw_add_round_key(batch, &key->keys[0]); + for (size_t i = 1; i < num_rounds; i++) { + aes_nohw_sub_bytes(batch); + aes_nohw_shift_rows(batch); + aes_nohw_mix_columns(batch); + aes_nohw_add_round_key(batch, &key->keys[i]); + } + aes_nohw_sub_bytes(batch); + aes_nohw_shift_rows(batch); + aes_nohw_add_round_key(batch, &key->keys[num_rounds]); +} + +static void aes_nohw_decrypt_batch(const AES_NOHW_SCHEDULE *key, + size_t num_rounds, AES_NOHW_BATCH *batch) { + aes_nohw_add_round_key(batch, &key->keys[num_rounds]); + aes_nohw_inv_shift_rows(batch); + aes_nohw_inv_sub_bytes(batch); + for (size_t i = num_rounds - 1; i > 0; i--) { + aes_nohw_add_round_key(batch, &key->keys[i]); + aes_nohw_inv_mix_columns(batch); + aes_nohw_inv_shift_rows(batch); + aes_nohw_inv_sub_bytes(batch); + } + aes_nohw_add_round_key(batch, &key->keys[0]); +} + + +// Key schedule. + +static void aes_nohw_expand_round_keys(AES_NOHW_SCHEDULE *out, + const AES_KEY *key) { + for (size_t i = 0; i <= key->rounds; i++) { + // Copy the round key into each block in the batch. + for (size_t j = 0; j < AES_NOHW_BATCH_SIZE; j++) { + aes_word_t tmp[AES_NOHW_BLOCK_WORDS]; + memcpy(tmp, key->rd_key + 4 * i, 16); + aes_nohw_batch_set(&out->keys[i], tmp, j); + } + aes_nohw_transpose(&out->keys[i]); + } +} + +static const uint8_t aes_nohw_rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, + 0x20, 0x40, 0x80, 0x1b, 0x36}; + +// aes_nohw_rcon_slice returns the |i|th group of |AES_NOHW_BATCH_SIZE| bits in +// |rcon|, stored in a |aes_word_t|. +static inline aes_word_t aes_nohw_rcon_slice(uint8_t rcon, size_t i) { + rcon = (rcon >> (i * AES_NOHW_BATCH_SIZE)) & ((1 << AES_NOHW_BATCH_SIZE) - 1); +#if defined(OPENSSL_SSE2) + return _mm_set_epi32(0, 0, 0, rcon); +#else + return ((aes_word_t)rcon); +#endif +} + +static void aes_nohw_sub_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], + const aes_word_t in[AES_NOHW_BLOCK_WORDS]) { + AES_NOHW_BATCH batch; + memset(&batch, 0, sizeof(batch)); + aes_nohw_batch_set(&batch, in, 0); + aes_nohw_transpose(&batch); + aes_nohw_sub_bytes(&batch); + aes_nohw_transpose(&batch); + aes_nohw_batch_get(&batch, out, 0); +} + +static void aes_nohw_setup_key_128(AES_KEY *key, const uint8_t in[16]) { + key->rounds = 10; + + aes_word_t block[AES_NOHW_BLOCK_WORDS]; + aes_nohw_compact_block(block, in); + memcpy(key->rd_key, block, 16); + + for (size_t i = 1; i <= 10; i++) { + aes_word_t sub[AES_NOHW_BLOCK_WORDS]; + aes_nohw_sub_block(sub, block); + uint8_t rcon = aes_nohw_rcon[i - 1]; + for (size_t j = 0; j < AES_NOHW_BLOCK_WORDS; j++) { + // Incorporate |rcon| and the transformed word into the first word. + block[j] = aes_nohw_xor(block[j], aes_nohw_rcon_slice(rcon, j)); + block[j] = aes_nohw_xor( + block[j], + aes_nohw_shift_right(aes_nohw_rotate_rows_down(sub[j]), 12)); + // Propagate to the remaining words. Note this is reordered from the usual + // formulation to avoid needing masks. + aes_word_t v = block[j]; + block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 4)); + block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 8)); + block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 12)); + } + memcpy(key->rd_key + 4 * i, block, 16); + } +} + +static void aes_nohw_setup_key_192(AES_KEY *key, const uint8_t in[24]) { + key->rounds = 12; + + aes_word_t storage1[AES_NOHW_BLOCK_WORDS], storage2[AES_NOHW_BLOCK_WORDS]; + aes_word_t *block1 = storage1, *block2 = storage2; + + // AES-192's key schedule is complex because each key schedule iteration + // produces six words, but we compute on blocks and each block is four words. + // We maintain a sliding window of two blocks, filled to 1.5 blocks at a time. + // We loop below every three blocks or two key schedule iterations. + // + // On entry to the loop, |block1| and the first half of |block2| contain the + // previous key schedule iteration. |block1| has been written to |key|, but + // |block2| has not as it is incomplete. + aes_nohw_compact_block(block1, in); + memcpy(key->rd_key, block1, 16); + + uint8_t half_block[16] = {0}; + memcpy(half_block, in + 16, 8); + aes_nohw_compact_block(block2, half_block); + + for (size_t i = 0; i < 4; i++) { + aes_word_t sub[AES_NOHW_BLOCK_WORDS]; + aes_nohw_sub_block(sub, block2); + uint8_t rcon = aes_nohw_rcon[2 * i]; + for (size_t j = 0; j < AES_NOHW_BLOCK_WORDS; j++) { + // Compute the first two words of the next key schedule iteration, which + // go in the second half of |block2|. The first two words of the previous + // iteration are in the first half of |block1|. Apply |rcon| here too + // because the shifts match. + block2[j] = aes_nohw_or( + block2[j], + aes_nohw_shift_left( + aes_nohw_xor(block1[j], aes_nohw_rcon_slice(rcon, j)), 8)); + // Incorporate the transformed word and propagate. Note the last word of + // the previous iteration corresponds to the second word of |copy|. This + // is incorporated into the first word of the next iteration, or the third + // word of |block2|. + block2[j] = aes_nohw_xor( + block2[j], aes_nohw_and(aes_nohw_shift_left( + aes_nohw_rotate_rows_down(sub[j]), 4), + AES_NOHW_COL2_MASK)); + block2[j] = aes_nohw_xor( + block2[j], + aes_nohw_and(aes_nohw_shift_left(block2[j], 4), AES_NOHW_COL3_MASK)); + + // Compute the remaining four words, which fill |block1|. Begin by moving + // the corresponding words of the previous iteration: the second half of + // |block1| and the first half of |block2|. + block1[j] = aes_nohw_shift_right(block1[j], 8); + block1[j] = aes_nohw_or(block1[j], aes_nohw_shift_left(block2[j], 8)); + // Incorporate the second word, computed previously in |block2|, and + // propagate. + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_right(block2[j], 12)); + aes_word_t v = block1[j]; + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 4)); + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 8)); + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 12)); + } + + // This completes two round keys. Note half of |block2| was computed in the + // previous loop iteration but was not yet output. + memcpy(key->rd_key + 4 * (3 * i + 1), block2, 16); + memcpy(key->rd_key + 4 * (3 * i + 2), block1, 16); + + aes_nohw_sub_block(sub, block1); + rcon = aes_nohw_rcon[2 * i + 1]; + for (size_t j = 0; j < AES_NOHW_BLOCK_WORDS; j++) { + // Compute the first four words of the next key schedule iteration in + // |block2|. Begin by moving the corresponding words of the previous + // iteration: the second half of |block2| and the first half of |block1|. + block2[j] = aes_nohw_shift_right(block2[j], 8); + block2[j] = aes_nohw_or(block2[j], aes_nohw_shift_left(block1[j], 8)); + // Incorporate rcon and the transformed word. Note the last word of the + // previous iteration corresponds to the last word of |copy|. + block2[j] = aes_nohw_xor(block2[j], aes_nohw_rcon_slice(rcon, j)); + block2[j] = aes_nohw_xor( + block2[j], + aes_nohw_shift_right(aes_nohw_rotate_rows_down(sub[j]), 12)); + // Propagate to the remaining words. + aes_word_t v = block2[j]; + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 4)); + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 8)); + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 12)); + + // Compute the last two words, which go in the first half of |block1|. The + // last two words of the previous iteration are in the second half of + // |block1|. + block1[j] = aes_nohw_shift_right(block1[j], 8); + // Propagate blocks and mask off the excess. + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_right(block2[j], 12)); + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(block1[j], 4)); + block1[j] = aes_nohw_and(block1[j], AES_NOHW_COL01_MASK); + } + + // |block2| has a complete round key. |block1| will be completed in the next + // iteration. + memcpy(key->rd_key + 4 * (3 * i + 3), block2, 16); + + // Swap blocks to restore the invariant. + aes_word_t *tmp = block1; + block1 = block2; + block2 = tmp; + } +} + +static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) { + key->rounds = 14; + + // Each key schedule iteration produces two round keys. + aes_word_t block1[AES_NOHW_BLOCK_WORDS], block2[AES_NOHW_BLOCK_WORDS]; + aes_nohw_compact_block(block1, in); + memcpy(key->rd_key, block1, 16); + + aes_nohw_compact_block(block2, in + 16); + memcpy(key->rd_key + 4, block2, 16); + + for (size_t i = 2; i <= 14; i += 2) { + aes_word_t sub[AES_NOHW_BLOCK_WORDS]; + aes_nohw_sub_block(sub, block2); + uint8_t rcon = aes_nohw_rcon[i / 2 - 1]; + for (size_t j = 0; j < AES_NOHW_BLOCK_WORDS; j++) { + // Incorporate |rcon| and the transformed word into the first word. + block1[j] = aes_nohw_xor(block1[j], aes_nohw_rcon_slice(rcon, j)); + block1[j] = aes_nohw_xor( + block1[j], + aes_nohw_shift_right(aes_nohw_rotate_rows_down(sub[j]), 12)); + // Propagate to the remaining words. + aes_word_t v = block1[j]; + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 4)); + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 8)); + block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 12)); + } + memcpy(key->rd_key + 4 * i, block1, 16); + + if (i == 14) { + break; + } + + aes_nohw_sub_block(sub, block1); + for (size_t j = 0; j < AES_NOHW_BLOCK_WORDS; j++) { + // Incorporate the transformed word into the first word. + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_right(sub[j], 12)); + // Propagate to the remaining words. + aes_word_t v = block2[j]; + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 4)); + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 8)); + block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 12)); + } + memcpy(key->rd_key + 4 * (i + 1), block2, 16); + } +} + + +// External API. + +int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey) { + switch (bits) { + case 128: + aes_nohw_setup_key_128(aeskey, key); + return 0; + case 192: + aes_nohw_setup_key_192(aeskey, key); + return 0; + case 256: + aes_nohw_setup_key_256(aeskey, key); + return 0; + } + return 1; +} + +int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey) { + return aes_nohw_set_encrypt_key(key, bits, aeskey); +} + +void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + AES_NOHW_SCHEDULE sched; + aes_nohw_expand_round_keys(&sched, key); + AES_NOHW_BATCH batch; + aes_nohw_to_batch(&batch, in, /*num_blocks=*/1); + aes_nohw_encrypt_batch(&sched, key->rounds, &batch); + aes_nohw_from_batch(out, /*num_blocks=*/1, &batch); +} + +void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + AES_NOHW_SCHEDULE sched; + aes_nohw_expand_round_keys(&sched, key); + AES_NOHW_BATCH batch; + aes_nohw_to_batch(&batch, in, /*num_blocks=*/1); + aes_nohw_decrypt_batch(&sched, key->rounds, &batch); + aes_nohw_from_batch(out, /*num_blocks=*/1, &batch); +} + +static inline void aes_nohw_xor_block(uint8_t out[16], const uint8_t a[16], + const uint8_t b[16]) { + for (size_t i = 0; i < 16; i += sizeof(aes_word_t)) { + aes_word_t x, y; + memcpy(&x, a + i, sizeof(aes_word_t)); + memcpy(&y, b + i, sizeof(aes_word_t)); + x = aes_nohw_xor(x, y); + memcpy(out + i, &x, sizeof(aes_word_t)); + } +} + +void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t blocks, const AES_KEY *key, + const uint8_t ivec[16]) { + if (blocks == 0) { + return; + } + + AES_NOHW_SCHEDULE sched; + aes_nohw_expand_round_keys(&sched, key); + + // Make |AES_NOHW_BATCH_SIZE| copies of |ivec|. + alignas(AES_NOHW_WORD_SIZE) union { + uint32_t u32[AES_NOHW_BATCH_SIZE * 4]; + uint8_t u8[AES_NOHW_BATCH_SIZE * 16]; + } ivs, enc_ivs; + for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { + memcpy(ivs.u8 + 16 * i, ivec, 16); + } + + uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]); + for (;;) { + // Update counters. + for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { + ivs.u32[4 * i + 3] = CRYPTO_bswap4(ctr + i); + } + + size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks; + AES_NOHW_BATCH batch; + aes_nohw_to_batch(&batch, ivs.u8, todo); + aes_nohw_encrypt_batch(&sched, key->rounds, &batch); + aes_nohw_from_batch(enc_ivs.u8, todo, &batch); + + for (size_t i = 0; i < todo; i++) { + aes_nohw_xor_block(out + 16 * i, in + 16 * i, enc_ivs.u8 + 16 * i); + } + + blocks -= todo; + if (blocks == 0) { + break; + } + + in += 16 * AES_NOHW_BATCH_SIZE; + out += 16 * AES_NOHW_BATCH_SIZE; + ctr += AES_NOHW_BATCH_SIZE; + } +} + +void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc) { + assert(len % 16 == 0); + size_t blocks = len / 16; + if (blocks == 0) { + return; + } + + AES_NOHW_SCHEDULE sched; + aes_nohw_expand_round_keys(&sched, key); + alignas(AES_NOHW_WORD_SIZE) uint8_t iv[16]; + memcpy(iv, ivec, 16); + + if (enc) { + // CBC encryption is not parallelizable. + while (blocks > 0) { + aes_nohw_xor_block(iv, iv, in); + + AES_NOHW_BATCH batch; + aes_nohw_to_batch(&batch, iv, /*num_blocks=*/1); + aes_nohw_encrypt_batch(&sched, key->rounds, &batch); + aes_nohw_from_batch(out, /*num_blocks=*/1, &batch); + + memcpy(iv, out, 16); + + in += 16; + out += 16; + blocks--; + } + memcpy(ivec, iv, 16); + return; + } + + for (;;) { + size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks; + // Make a copy of the input so we can decrypt in-place. + alignas(AES_NOHW_WORD_SIZE) uint8_t copy[AES_NOHW_BATCH_SIZE * 16]; + memcpy(copy, in, todo * 16); + + AES_NOHW_BATCH batch; + aes_nohw_to_batch(&batch, in, todo); + aes_nohw_decrypt_batch(&sched, key->rounds, &batch); + aes_nohw_from_batch(out, todo, &batch); + + aes_nohw_xor_block(out, out, iv); + for (size_t i = 1; i < todo; i++) { + aes_nohw_xor_block(out + 16 * i, out + 16 * i, copy + 16 * (i - 1)); + } + + // Save the last block as the IV. + memcpy(iv, copy + 16 * (todo - 1), 16); + + blocks -= todo; + if (blocks == 0) { + break; + } + + in += 16 * AES_NOHW_BATCH_SIZE; + out += 16 * AES_NOHW_BATCH_SIZE; + } + + memcpy(ivec, iv, 16); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h new file mode 100644 index 00000000..0685bc41 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h @@ -0,0 +1,234 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AES_INTERNAL_H +#define OPENSSL_HEADER_AES_INTERNAL_H + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +#define HWAES +#define HWAES_ECB + +OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_AESNI_capable(); } + +#define VPAES +#if defined(OPENSSL_X86_64) +#define VPAES_CTR32 +#endif +#define VPAES_CBC +OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_SSSE3_capable(); } + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#define HWAES + +OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); } + +#if defined(OPENSSL_ARM) +#define BSAES +#define VPAES +#define VPAES_CTR32 +OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); } +OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } +#endif + +#if defined(OPENSSL_AARCH64) +#define VPAES +#define VPAES_CBC +#define VPAES_CTR32 +OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } +#endif + +#elif defined(OPENSSL_PPC64LE) +#define HWAES + +OPENSSL_INLINE int hwaes_capable(void) { + return CRYPTO_is_PPC64LE_vcrypto_capable(); +} +#endif + +#endif // !NO_ASM + + +#if defined(HWAES) + +int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, const int enc); +void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); + +#else + +// If HWAES isn't defined then we provide dummy functions for each of the hwaes +// functions. +OPENSSL_INLINE int hwaes_capable(void) { return 0; } + +OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const AES_KEY *key, + uint8_t *ivec, int enc) { + abort(); +} + +OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} + +#endif // !HWAES + + +#if defined(HWAES_ECB) +void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, const int enc); +#endif // HWAES_ECB + + +#if defined(BSAES) +// Note |bsaes_cbc_encrypt| requires |enc| to be zero. +void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); +// VPAES to BSAES conversions are available on all BSAES platforms. +void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); +void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); +#else +OPENSSL_INLINE char bsaes_capable(void) { return 0; } + +// On other platforms, bsaes_capable() will always return false and so the +// following will never be called. +OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const AES_KEY *key, + uint8_t ivec[16], int enc) { + abort(); +} + +OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} + +OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, + const AES_KEY *vpaes) { + abort(); +} + +OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, + const AES_KEY *vpaes) { + abort(); +} +#endif // !BSAES + + +#if defined(VPAES) +// On platforms where VPAES gets defined (just above), then these functions are +// provided by asm. +int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); +int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); + +void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +#if defined(VPAES_CBC) +void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc); +#endif +#if defined(VPAES_CTR32) +void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); +#endif +#else +OPENSSL_INLINE char vpaes_capable(void) { return 0; } + +// On other platforms, vpaes_capable() will always return false and so the +// following will never be called. +OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} +OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} +OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const AES_KEY *key, + uint8_t *ivec, int enc) { + abort(); +} +#endif // !VPAES + + +int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); +int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); +void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t blocks, const AES_KEY *key, + const uint8_t ivec[16]); +void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/key_wrap.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/key_wrap.c new file mode 100644 index 00000000..64148c4e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/key_wrap.c @@ -0,0 +1,236 @@ +/* ==================================================================== + * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include +#include + +#include + +#include "../../internal.h" + + +// kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. +static const uint8_t kDefaultIV[] = { + 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, +}; + +static const unsigned kBound = 6; + +int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + // See RFC 3394, section 2.2.1. Additionally, note that section 2 requires the + // plaintext be at least two 8-byte blocks. + + if (in_len > INT_MAX - 8 || in_len < 16 || in_len % 8 != 0) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + + OPENSSL_memmove(out + 8, in, in_len); + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, iv, 8); + + size_t n = in_len / 8; + + for (unsigned j = 0; j < kBound; j++) { + for (size_t i = 1; i <= n; i++) { + OPENSSL_memcpy(A + 8, out + 8 * i, 8); + AES_encrypt(A, A, key); + + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(out + 8 * i, A + 8, 8); + } + } + + OPENSSL_memcpy(out, A, 8); + return (int)in_len + 8; +} + +// aes_unwrap_key_inner performs steps one and two from +// https://tools.ietf.org/html/rfc3394#section-2.2.2 +static int aes_unwrap_key_inner(const AES_KEY *key, uint8_t *out, + uint8_t out_iv[8], const uint8_t *in, + size_t in_len) { + // See RFC 3394, section 2.2.2. Additionally, note that section 2 requires the + // plaintext be at least two 8-byte blocks, so the ciphertext must be at least + // three blocks. + + if (in_len > INT_MAX || in_len < 24 || in_len % 8 != 0) { + return 0; + } + + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, in, 8); + OPENSSL_memmove(out, in + 8, in_len - 8); + + size_t n = (in_len / 8) - 1; + + for (unsigned j = kBound - 1; j < kBound; j--) { + for (size_t i = n; i > 0; i--) { + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(A + 8, out + 8 * (i - 1), 8); + AES_decrypt(A, A, key); + OPENSSL_memcpy(out + 8 * (i - 1), A + 8, 8); + } + } + + memcpy(out_iv, A, 8); + return 1; +} + +int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + uint8_t calculated_iv[8]; + if (!aes_unwrap_key_inner(key, out, calculated_iv, in, in_len)) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + if (CRYPTO_memcmp(calculated_iv, iv, 8) != 0) { + return -1; + } + + return (int)in_len - 8; +} + +// kPaddingConstant is used in Key Wrap with Padding. See +// https://tools.ietf.org/html/rfc5649#section-3 +static const uint8_t kPaddingConstant[4] = {0xa6, 0x59, 0x59, 0xa6}; + +int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *in, size_t in_len) { + // See https://tools.ietf.org/html/rfc5649#section-4.1 + const uint32_t in_len32_be = CRYPTO_bswap4(in_len); + const uint64_t in_len64 = in_len; + const size_t padded_len = (in_len + 7) & ~7; + + *out_len = 0; + if (in_len == 0 || in_len64 > 0xffffffffu || in_len + 7 < in_len || + padded_len + 8 < padded_len || max_out < padded_len + 8) { + return 0; + } + + uint8_t block[AES_BLOCK_SIZE]; + memcpy(block, kPaddingConstant, sizeof(kPaddingConstant)); + memcpy(block + 4, &in_len32_be, sizeof(in_len32_be)); + + if (in_len <= 8) { + memset(block + 8, 0, 8); + memcpy(block + 8, in, in_len); + AES_encrypt(block, out, key); + *out_len = AES_BLOCK_SIZE; + return 1; + } + + uint8_t *padded_in = OPENSSL_malloc(padded_len); + if (padded_in == NULL) { + return 0; + } + assert(padded_len >= 8); + memset(padded_in + padded_len - 8, 0, 8); + memcpy(padded_in, in, in_len); + const int ret = AES_wrap_key(key, block, out, padded_in, padded_len); + OPENSSL_free(padded_in); + if (ret < 0) { + return 0; + } + *out_len = ret; + return 1; +} + +int AES_unwrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *in, size_t in_len) { + *out_len = 0; + if (in_len < AES_BLOCK_SIZE || max_out < in_len - 8) { + return 0; + } + + uint8_t iv[8]; + if (in_len == AES_BLOCK_SIZE) { + uint8_t block[AES_BLOCK_SIZE]; + AES_decrypt(in, block, key); + memcpy(iv, block, sizeof(iv)); + memcpy(out, block + 8, 8); + } else if (!aes_unwrap_key_inner(key, out, iv, in, in_len)) { + return 0; + } + assert(in_len % 8 == 0); + + crypto_word_t ok = constant_time_eq_int( + CRYPTO_memcmp(iv, kPaddingConstant, sizeof(kPaddingConstant)), 0); + + uint32_t claimed_len32; + memcpy(&claimed_len32, iv + 4, sizeof(claimed_len32)); + const size_t claimed_len = CRYPTO_bswap4(claimed_len32); + ok &= ~constant_time_is_zero_w(claimed_len); + ok &= constant_time_eq_w((claimed_len - 1) >> 3, (in_len - 9) >> 3); + + // Check that padding bytes are all zero. + for (size_t i = in_len - 15; i < in_len - 8; i++) { + ok &= constant_time_is_zero_w(constant_time_ge_8(i, claimed_len) & out[i]); + } + + *out_len = constant_time_select_w(ok, claimed_len, 0); + return ok & 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/mode_wrappers.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/mode_wrappers.c new file mode 100644 index 00000000..82263745 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aes/mode_wrappers.c @@ -0,0 +1,122 @@ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include + +#include "../aes/internal.h" +#include "../modes/internal.h" + + +void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) { + if (hwaes_capable()) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num, + aes_hw_ctr32_encrypt_blocks); + } else if (vpaes_capable()) { +#if defined(VPAES_CTR32) + // TODO(davidben): On ARM, where |BSAES| is additionally defined, this could + // use |vpaes_ctr32_encrypt_blocks_with_bsaes|. + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num, + vpaes_ctr32_encrypt_blocks); +#else + CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num, + vpaes_encrypt); +#endif + } else { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num, + aes_nohw_ctr32_encrypt_blocks); + } +} + +void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key, + const int enc) { + assert(in && out && key); + assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + + if (AES_ENCRYPT == enc) { + AES_encrypt(in, out, key); + } else { + AES_decrypt(in, out, key); + } +} + +void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc) { + if (hwaes_capable()) { + aes_hw_cbc_encrypt(in, out, len, key, ivec, enc); + return; + } + + if (!vpaes_capable()) { + aes_nohw_cbc_encrypt(in, out, len, key, ivec, enc); + return; + } + if (enc) { + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, AES_encrypt); + } else { + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, AES_decrypt); + } +} + +void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num) { + unsigned num_u = (unsigned)(*num); + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u, AES_encrypt); + *num = (int)num_u; +} + +void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num, + int enc) { + unsigned num_u = (unsigned)(*num); + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc, AES_encrypt); + *num = (int)num_u; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S new file mode 100644 index 00000000..9cedbfb3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S @@ -0,0 +1,859 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.type _aesni_ctr32_ghash_6x,@function +.align 32 +_aesni_ctr32_ghash_6x: +.cfi_startproc + vmovdqu 32(%r11),%xmm2 + subq $6,%rdx + vpxor %xmm4,%xmm4,%xmm4 + vmovdqu 0-128(%rcx),%xmm15 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpaddb %xmm2,%xmm11,%xmm12 + vpaddb %xmm2,%xmm12,%xmm13 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm15,%xmm1,%xmm9 + vmovdqu %xmm4,16+8(%rsp) + jmp .Loop6x + +.align 32 +.Loop6x: + addl $100663296,%ebx + jc .Lhandle_ctr32 + vmovdqu 0-32(%r9),%xmm3 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm15,%xmm10,%xmm10 + vpxor %xmm15,%xmm11,%xmm11 + +.Lresume_ctr32: + vmovdqu %xmm1,(%r8) + vpclmulqdq $0x10,%xmm3,%xmm7,%xmm5 + vpxor %xmm15,%xmm12,%xmm12 + vmovups 16-128(%rcx),%xmm2 + vpclmulqdq $0x01,%xmm3,%xmm7,%xmm6 + + + + + + + + + + + + + + + + + + xorq %r12,%r12 + cmpq %r14,%r15 + + vaesenc %xmm2,%xmm9,%xmm9 + vmovdqu 48+8(%rsp),%xmm0 + vpxor %xmm15,%xmm13,%xmm13 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm1 + vaesenc %xmm2,%xmm10,%xmm10 + vpxor %xmm15,%xmm14,%xmm14 + setnc %r12b + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vmovdqu 16-32(%r9),%xmm3 + negq %r12 + vaesenc %xmm2,%xmm12,%xmm12 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm3,%xmm0,%xmm5 + vpxor %xmm4,%xmm8,%xmm8 + vaesenc %xmm2,%xmm13,%xmm13 + vpxor %xmm5,%xmm1,%xmm4 + andq $0x60,%r12 + vmovups 32-128(%rcx),%xmm15 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm1 + vaesenc %xmm2,%xmm14,%xmm14 + + vpclmulqdq $0x01,%xmm3,%xmm0,%xmm2 + leaq (%r14,%r12,1),%r14 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x11,%xmm3,%xmm0,%xmm3 + vmovdqu 64+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 88(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 80(%r14),%r12 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,32+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,40+8(%rsp) + vmovdqu 48-32(%r9),%xmm5 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 48-128(%rcx),%xmm15 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm5,%xmm0,%xmm1 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm5,%xmm0,%xmm2 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm3,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm5,%xmm0,%xmm3 + vaesenc %xmm15,%xmm11,%xmm11 + vpclmulqdq $0x11,%xmm5,%xmm0,%xmm5 + vmovdqu 80+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqu 64-32(%r9),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 64-128(%rcx),%xmm15 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 72(%r14),%r13 + vpxor %xmm5,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm1,%xmm0,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 64(%r14),%r12 + vpclmulqdq $0x11,%xmm1,%xmm0,%xmm1 + vmovdqu 96+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,48+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,56+8(%rsp) + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 96-32(%r9),%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 80-128(%rcx),%xmm15 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm2,%xmm0,%xmm5 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 56(%r14),%r13 + vpxor %xmm1,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm2,%xmm0,%xmm1 + vpxor 112+8(%rsp),%xmm8,%xmm8 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 48(%r14),%r12 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm2 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,64+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,72+8(%rsp) + vpxor %xmm3,%xmm4,%xmm4 + vmovdqu 112-32(%r9),%xmm3 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 96-128(%rcx),%xmm15 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm5 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x01,%xmm3,%xmm8,%xmm1 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 40(%r14),%r13 + vpxor %xmm2,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm3,%xmm8,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 32(%r14),%r12 + vpclmulqdq $0x11,%xmm3,%xmm8,%xmm8 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,80+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,88+8(%rsp) + vpxor %xmm5,%xmm6,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor %xmm1,%xmm6,%xmm6 + + vmovups 112-128(%rcx),%xmm15 + vpslldq $8,%xmm6,%xmm5 + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 16(%r11),%xmm3 + + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm8,%xmm7,%xmm7 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm5,%xmm4,%xmm4 + movbeq 24(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 16(%r14),%r12 + vpalignr $8,%xmm4,%xmm4,%xmm0 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + movq %r13,96+8(%rsp) + vaesenc %xmm15,%xmm12,%xmm12 + movq %r12,104+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + vmovups 128-128(%rcx),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 144-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm10,%xmm10 + vpsrldq $8,%xmm6,%xmm6 + vaesenc %xmm1,%xmm11,%xmm11 + vpxor %xmm6,%xmm7,%xmm7 + vaesenc %xmm1,%xmm12,%xmm12 + vpxor %xmm0,%xmm4,%xmm4 + movbeq 8(%r14),%r13 + vaesenc %xmm1,%xmm13,%xmm13 + movbeq 0(%r14),%r12 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 160-128(%rcx),%xmm1 + cmpl $11,%ebp + jb .Lenc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 176-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 192-128(%rcx),%xmm1 + je .Lenc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 208-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 224-128(%rcx),%xmm1 + jmp .Lenc_tail + +.align 32 +.Lhandle_ctr32: + vmovdqu (%r11),%xmm0 + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vmovdqu 0-32(%r9),%xmm3 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm15,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm15,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpshufb %xmm0,%xmm14,%xmm14 + vpshufb %xmm0,%xmm1,%xmm1 + jmp .Lresume_ctr32 + +.align 32 +.Lenc_tail: + vaesenc %xmm15,%xmm9,%xmm9 + vmovdqu %xmm7,16+8(%rsp) + vpalignr $8,%xmm4,%xmm4,%xmm8 + vaesenc %xmm15,%xmm10,%xmm10 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + vpxor 0(%rdi),%xmm1,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 16(%rdi),%xmm1,%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 32(%rdi),%xmm1,%xmm5 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 48(%rdi),%xmm1,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 64(%rdi),%xmm1,%xmm7 + vpxor 80(%rdi),%xmm1,%xmm3 + vmovdqu (%r8),%xmm1 + + vaesenclast %xmm2,%xmm9,%xmm9 + vmovdqu 32(%r11),%xmm2 + vaesenclast %xmm0,%xmm10,%xmm10 + vpaddb %xmm2,%xmm1,%xmm0 + movq %r13,112+8(%rsp) + leaq 96(%rdi),%rdi + vaesenclast %xmm5,%xmm11,%xmm11 + vpaddb %xmm2,%xmm0,%xmm5 + movq %r12,120+8(%rsp) + leaq 96(%rsi),%rsi + vmovdqu 0-128(%rcx),%xmm15 + vaesenclast %xmm6,%xmm12,%xmm12 + vpaddb %xmm2,%xmm5,%xmm6 + vaesenclast %xmm7,%xmm13,%xmm13 + vpaddb %xmm2,%xmm6,%xmm7 + vaesenclast %xmm3,%xmm14,%xmm14 + vpaddb %xmm2,%xmm7,%xmm3 + + addq $0x60,%r10 + subq $0x6,%rdx + jc .L6x_done + + vmovups %xmm9,-96(%rsi) + vpxor %xmm15,%xmm1,%xmm9 + vmovups %xmm10,-80(%rsi) + vmovdqa %xmm0,%xmm10 + vmovups %xmm11,-64(%rsi) + vmovdqa %xmm5,%xmm11 + vmovups %xmm12,-48(%rsi) + vmovdqa %xmm6,%xmm12 + vmovups %xmm13,-32(%rsi) + vmovdqa %xmm7,%xmm13 + vmovups %xmm14,-16(%rsi) + vmovdqa %xmm3,%xmm14 + vmovdqu 32+8(%rsp),%xmm7 + jmp .Loop6x + +.L6x_done: + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpxor %xmm4,%xmm8,%xmm8 + + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x +.globl aesni_gcm_decrypt +.hidden aesni_gcm_decrypt +.type aesni_gcm_decrypt,@function +.align 32 +aesni_gcm_decrypt: +.cfi_startproc + xorq %r10,%r10 + + + + cmpq $0x60,%rdx + jb .Lgcm_dec_abort + + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq .Lbswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + vmovdqu (%r9),%xmm8 + andq $-128,%rsp + vmovdqu (%r11),%xmm0 + leaq 128(%rcx),%rcx + leaq 32+32(%r9),%r9 + movl 240-128(%rcx),%ebp + vpshufb %xmm0,%xmm8,%xmm8 + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc .Ldec_no_key_aliasing + cmpq $768,%r15 + jnc .Ldec_no_key_aliasing + subq %r15,%rsp +.Ldec_no_key_aliasing: + + vmovdqu 80(%rdi),%xmm7 + leaq (%rdi),%r14 + vmovdqu 64(%rdi),%xmm4 + + + + + + + + leaq -192(%rdi,%rdx,1),%r15 + + vmovdqu 48(%rdi),%xmm5 + shrq $4,%rdx + xorq %r10,%r10 + vmovdqu 32(%rdi),%xmm6 + vpshufb %xmm0,%xmm7,%xmm7 + vmovdqu 16(%rdi),%xmm2 + vpshufb %xmm0,%xmm4,%xmm4 + vmovdqu (%rdi),%xmm3 + vpshufb %xmm0,%xmm5,%xmm5 + vmovdqu %xmm4,48(%rsp) + vpshufb %xmm0,%xmm6,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm2,%xmm2 + vmovdqu %xmm6,80(%rsp) + vpshufb %xmm0,%xmm3,%xmm3 + vmovdqu %xmm2,96(%rsp) + vmovdqu %xmm3,112(%rsp) + + call _aesni_ctr32_ghash_6x + + vmovups %xmm9,-96(%rsi) + vmovups %xmm10,-80(%rsi) + vmovups %xmm11,-64(%rsi) + vmovups %xmm12,-48(%rsi) + vmovups %xmm13,-32(%rsi) + vmovups %xmm14,-16(%rsi) + + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lgcm_dec_abort: + movq %r10,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_gcm_decrypt,.-aesni_gcm_decrypt +.type _aesni_ctr32_6x,@function +.align 32 +_aesni_ctr32_6x: +.cfi_startproc + vmovdqu 0-128(%rcx),%xmm4 + vmovdqu 32(%r11),%xmm2 + leaq -1(%rbp),%r13 + vmovups 16-128(%rcx),%xmm15 + leaq 32-128(%rcx),%r12 + vpxor %xmm4,%xmm1,%xmm9 + addl $100663296,%ebx + jc .Lhandle_ctr32_2 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddb %xmm2,%xmm11,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddb %xmm2,%xmm12,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp .Loop_ctr32 + +.align 16 +.Loop_ctr32: + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + vmovups (%r12),%xmm15 + leaq 16(%r12),%r12 + decl %r13d + jnz .Loop_ctr32 + + vmovdqu (%r12),%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 0(%rdi),%xmm3,%xmm4 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor 16(%rdi),%xmm3,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 32(%rdi),%xmm3,%xmm6 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 48(%rdi),%xmm3,%xmm8 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 64(%rdi),%xmm3,%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 80(%rdi),%xmm3,%xmm3 + leaq 96(%rdi),%rdi + + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm5,%xmm10,%xmm10 + vaesenclast %xmm6,%xmm11,%xmm11 + vaesenclast %xmm8,%xmm12,%xmm12 + vaesenclast %xmm2,%xmm13,%xmm13 + vaesenclast %xmm3,%xmm14,%xmm14 + vmovups %xmm9,0(%rsi) + vmovups %xmm10,16(%rsi) + vmovups %xmm11,32(%rsi) + vmovups %xmm12,48(%rsi) + vmovups %xmm13,64(%rsi) + vmovups %xmm14,80(%rsi) + leaq 96(%rsi),%rsi + + .byte 0xf3,0xc3 +.align 32 +.Lhandle_ctr32_2: + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpshufb %xmm0,%xmm14,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpshufb %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp .Loop_ctr32 +.cfi_endproc +.size _aesni_ctr32_6x,.-_aesni_ctr32_6x + +.globl aesni_gcm_encrypt +.hidden aesni_gcm_encrypt +.type aesni_gcm_encrypt,@function +.align 32 +aesni_gcm_encrypt: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST +.extern BORINGSSL_function_hit +.hidden BORINGSSL_function_hit + movb $1,BORINGSSL_function_hit+2(%rip) +#endif + xorq %r10,%r10 + + + + + cmpq $288,%rdx + jb .Lgcm_enc_abort + + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq .Lbswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + leaq 128(%rcx),%rcx + vmovdqu (%r11),%xmm0 + andq $-128,%rsp + movl 240-128(%rcx),%ebp + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc .Lenc_no_key_aliasing + cmpq $768,%r15 + jnc .Lenc_no_key_aliasing + subq %r15,%rsp +.Lenc_no_key_aliasing: + + leaq (%rsi),%r14 + + + + + + + + + leaq -192(%rsi,%rdx,1),%r15 + + shrq $4,%rdx + + call _aesni_ctr32_6x + vpshufb %xmm0,%xmm9,%xmm8 + vpshufb %xmm0,%xmm10,%xmm2 + vmovdqu %xmm8,112(%rsp) + vpshufb %xmm0,%xmm11,%xmm4 + vmovdqu %xmm2,96(%rsp) + vpshufb %xmm0,%xmm12,%xmm5 + vmovdqu %xmm4,80(%rsp) + vpshufb %xmm0,%xmm13,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm14,%xmm7 + vmovdqu %xmm6,48(%rsp) + + call _aesni_ctr32_6x + + vmovdqu (%r9),%xmm8 + leaq 32+32(%r9),%r9 + subq $12,%rdx + movq $192,%r10 + vpshufb %xmm0,%xmm8,%xmm8 + + call _aesni_ctr32_ghash_6x + vmovdqu 32(%rsp),%xmm7 + vmovdqu (%r11),%xmm0 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm7,%xmm7,%xmm1 + vmovdqu 32-32(%r9),%xmm15 + vmovups %xmm9,-96(%rsi) + vpshufb %xmm0,%xmm9,%xmm9 + vpxor %xmm7,%xmm1,%xmm1 + vmovups %xmm10,-80(%rsi) + vpshufb %xmm0,%xmm10,%xmm10 + vmovups %xmm11,-64(%rsi) + vpshufb %xmm0,%xmm11,%xmm11 + vmovups %xmm12,-48(%rsi) + vpshufb %xmm0,%xmm12,%xmm12 + vmovups %xmm13,-32(%rsi) + vpshufb %xmm0,%xmm13,%xmm13 + vmovups %xmm14,-16(%rsi) + vpshufb %xmm0,%xmm14,%xmm14 + vmovdqu %xmm9,16(%rsp) + vmovdqu 48(%rsp),%xmm6 + vmovdqu 16-32(%r9),%xmm0 + vpunpckhqdq %xmm6,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm5 + vpxor %xmm6,%xmm2,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + + vmovdqu 64(%rsp),%xmm9 + vpclmulqdq $0x00,%xmm0,%xmm6,%xmm4 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm9,%xmm9,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm6,%xmm6 + vpxor %xmm9,%xmm5,%xmm5 + vpxor %xmm7,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vmovdqu 80(%rsp),%xmm1 + vpclmulqdq $0x00,%xmm3,%xmm9,%xmm7 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm4,%xmm7,%xmm7 + vpunpckhqdq %xmm1,%xmm1,%xmm4 + vpclmulqdq $0x11,%xmm3,%xmm9,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpxor %xmm6,%xmm9,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm5,%xmm5 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 96(%rsp),%xmm2 + vpclmulqdq $0x00,%xmm0,%xmm1,%xmm6 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm7,%xmm6,%xmm6 + vpunpckhqdq %xmm2,%xmm2,%xmm7 + vpclmulqdq $0x11,%xmm0,%xmm1,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpxor %xmm9,%xmm1,%xmm1 + vpclmulqdq $0x10,%xmm15,%xmm4,%xmm4 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm5,%xmm4,%xmm4 + + vpxor 112(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm3,%xmm2,%xmm5 + vmovdqu 112-32(%r9),%xmm0 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x11,%xmm3,%xmm2,%xmm2 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm1,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm15,%xmm7,%xmm7 + vpxor %xmm4,%xmm7,%xmm4 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm6 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm1 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm8 + vpxor %xmm14,%xmm1,%xmm1 + vpxor %xmm5,%xmm6,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm9 + vmovdqu 32-32(%r9),%xmm15 + vpxor %xmm2,%xmm8,%xmm7 + vpxor %xmm4,%xmm9,%xmm6 + + vmovdqu 16-32(%r9),%xmm0 + vpxor %xmm5,%xmm7,%xmm9 + vpclmulqdq $0x00,%xmm3,%xmm14,%xmm4 + vpxor %xmm9,%xmm6,%xmm6 + vpunpckhqdq %xmm13,%xmm13,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm14,%xmm14 + vpxor %xmm13,%xmm2,%xmm2 + vpslldq $8,%xmm6,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + vpxor %xmm9,%xmm5,%xmm8 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm6,%xmm7,%xmm7 + + vpclmulqdq $0x00,%xmm0,%xmm13,%xmm5 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm12,%xmm12,%xmm9 + vpclmulqdq $0x11,%xmm0,%xmm13,%xmm13 + vpxor %xmm12,%xmm9,%xmm9 + vpxor %xmm14,%xmm13,%xmm13 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm3,%xmm12,%xmm4 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm11,%xmm11,%xmm1 + vpclmulqdq $0x11,%xmm3,%xmm12,%xmm12 + vpxor %xmm11,%xmm1,%xmm1 + vpxor %xmm13,%xmm12,%xmm12 + vxorps 16(%rsp),%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm9,%xmm9 + + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm0,%xmm11,%xmm5 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm10,%xmm10,%xmm2 + vpclmulqdq $0x11,%xmm0,%xmm11,%xmm11 + vpxor %xmm10,%xmm2,%xmm2 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpxor %xmm12,%xmm11,%xmm11 + vpclmulqdq $0x10,%xmm15,%xmm1,%xmm1 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm9,%xmm1,%xmm1 + + vxorps %xmm7,%xmm14,%xmm14 + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm3,%xmm10,%xmm4 + vmovdqu 112-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpclmulqdq $0x11,%xmm3,%xmm10,%xmm10 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm11,%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm15,%xmm2,%xmm2 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm7 + vpxor %xmm4,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm6 + vpxor %xmm10,%xmm7,%xmm7 + vpxor %xmm2,%xmm6,%xmm6 + + vpxor %xmm5,%xmm7,%xmm4 + vpxor %xmm4,%xmm6,%xmm6 + vpslldq $8,%xmm6,%xmm1 + vmovdqu 16(%r11),%xmm3 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm1,%xmm5,%xmm8 + vpxor %xmm6,%xmm7,%xmm7 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm2,%xmm8,%xmm8 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm7,%xmm2,%xmm2 + vpxor %xmm2,%xmm8,%xmm8 + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lgcm_enc_abort: + movq %r10,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_gcm_encrypt,.-aesni_gcm_encrypt +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.Lpoly: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.Lone_msb: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +.Ltwo_lsb: +.byte 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lone_lsb: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S new file mode 100644 index 00000000..54035071 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S @@ -0,0 +1,857 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +.p2align 5 +_aesni_ctr32_ghash_6x: + + vmovdqu 32(%r11),%xmm2 + subq $6,%rdx + vpxor %xmm4,%xmm4,%xmm4 + vmovdqu 0-128(%rcx),%xmm15 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpaddb %xmm2,%xmm11,%xmm12 + vpaddb %xmm2,%xmm12,%xmm13 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm15,%xmm1,%xmm9 + vmovdqu %xmm4,16+8(%rsp) + jmp L$oop6x + +.p2align 5 +L$oop6x: + addl $100663296,%ebx + jc L$handle_ctr32 + vmovdqu 0-32(%r9),%xmm3 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm15,%xmm10,%xmm10 + vpxor %xmm15,%xmm11,%xmm11 + +L$resume_ctr32: + vmovdqu %xmm1,(%r8) + vpclmulqdq $0x10,%xmm3,%xmm7,%xmm5 + vpxor %xmm15,%xmm12,%xmm12 + vmovups 16-128(%rcx),%xmm2 + vpclmulqdq $0x01,%xmm3,%xmm7,%xmm6 + + + + + + + + + + + + + + + + + + xorq %r12,%r12 + cmpq %r14,%r15 + + vaesenc %xmm2,%xmm9,%xmm9 + vmovdqu 48+8(%rsp),%xmm0 + vpxor %xmm15,%xmm13,%xmm13 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm1 + vaesenc %xmm2,%xmm10,%xmm10 + vpxor %xmm15,%xmm14,%xmm14 + setnc %r12b + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vmovdqu 16-32(%r9),%xmm3 + negq %r12 + vaesenc %xmm2,%xmm12,%xmm12 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm3,%xmm0,%xmm5 + vpxor %xmm4,%xmm8,%xmm8 + vaesenc %xmm2,%xmm13,%xmm13 + vpxor %xmm5,%xmm1,%xmm4 + andq $0x60,%r12 + vmovups 32-128(%rcx),%xmm15 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm1 + vaesenc %xmm2,%xmm14,%xmm14 + + vpclmulqdq $0x01,%xmm3,%xmm0,%xmm2 + leaq (%r14,%r12,1),%r14 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x11,%xmm3,%xmm0,%xmm3 + vmovdqu 64+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 88(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 80(%r14),%r12 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,32+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,40+8(%rsp) + vmovdqu 48-32(%r9),%xmm5 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 48-128(%rcx),%xmm15 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm5,%xmm0,%xmm1 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm5,%xmm0,%xmm2 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm3,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm5,%xmm0,%xmm3 + vaesenc %xmm15,%xmm11,%xmm11 + vpclmulqdq $0x11,%xmm5,%xmm0,%xmm5 + vmovdqu 80+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqu 64-32(%r9),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 64-128(%rcx),%xmm15 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 72(%r14),%r13 + vpxor %xmm5,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm1,%xmm0,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 64(%r14),%r12 + vpclmulqdq $0x11,%xmm1,%xmm0,%xmm1 + vmovdqu 96+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,48+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,56+8(%rsp) + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 96-32(%r9),%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 80-128(%rcx),%xmm15 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm2,%xmm0,%xmm5 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 56(%r14),%r13 + vpxor %xmm1,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm2,%xmm0,%xmm1 + vpxor 112+8(%rsp),%xmm8,%xmm8 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 48(%r14),%r12 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm2 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,64+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,72+8(%rsp) + vpxor %xmm3,%xmm4,%xmm4 + vmovdqu 112-32(%r9),%xmm3 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 96-128(%rcx),%xmm15 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm5 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x01,%xmm3,%xmm8,%xmm1 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 40(%r14),%r13 + vpxor %xmm2,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm3,%xmm8,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 32(%r14),%r12 + vpclmulqdq $0x11,%xmm3,%xmm8,%xmm8 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,80+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,88+8(%rsp) + vpxor %xmm5,%xmm6,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor %xmm1,%xmm6,%xmm6 + + vmovups 112-128(%rcx),%xmm15 + vpslldq $8,%xmm6,%xmm5 + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 16(%r11),%xmm3 + + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm8,%xmm7,%xmm7 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm5,%xmm4,%xmm4 + movbeq 24(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 16(%r14),%r12 + vpalignr $8,%xmm4,%xmm4,%xmm0 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + movq %r13,96+8(%rsp) + vaesenc %xmm15,%xmm12,%xmm12 + movq %r12,104+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + vmovups 128-128(%rcx),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 144-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm10,%xmm10 + vpsrldq $8,%xmm6,%xmm6 + vaesenc %xmm1,%xmm11,%xmm11 + vpxor %xmm6,%xmm7,%xmm7 + vaesenc %xmm1,%xmm12,%xmm12 + vpxor %xmm0,%xmm4,%xmm4 + movbeq 8(%r14),%r13 + vaesenc %xmm1,%xmm13,%xmm13 + movbeq 0(%r14),%r12 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 160-128(%rcx),%xmm1 + cmpl $11,%ebp + jb L$enc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 176-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 192-128(%rcx),%xmm1 + je L$enc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 208-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 224-128(%rcx),%xmm1 + jmp L$enc_tail + +.p2align 5 +L$handle_ctr32: + vmovdqu (%r11),%xmm0 + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vmovdqu 0-32(%r9),%xmm3 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm15,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm15,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpshufb %xmm0,%xmm14,%xmm14 + vpshufb %xmm0,%xmm1,%xmm1 + jmp L$resume_ctr32 + +.p2align 5 +L$enc_tail: + vaesenc %xmm15,%xmm9,%xmm9 + vmovdqu %xmm7,16+8(%rsp) + vpalignr $8,%xmm4,%xmm4,%xmm8 + vaesenc %xmm15,%xmm10,%xmm10 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + vpxor 0(%rdi),%xmm1,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 16(%rdi),%xmm1,%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 32(%rdi),%xmm1,%xmm5 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 48(%rdi),%xmm1,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 64(%rdi),%xmm1,%xmm7 + vpxor 80(%rdi),%xmm1,%xmm3 + vmovdqu (%r8),%xmm1 + + vaesenclast %xmm2,%xmm9,%xmm9 + vmovdqu 32(%r11),%xmm2 + vaesenclast %xmm0,%xmm10,%xmm10 + vpaddb %xmm2,%xmm1,%xmm0 + movq %r13,112+8(%rsp) + leaq 96(%rdi),%rdi + vaesenclast %xmm5,%xmm11,%xmm11 + vpaddb %xmm2,%xmm0,%xmm5 + movq %r12,120+8(%rsp) + leaq 96(%rsi),%rsi + vmovdqu 0-128(%rcx),%xmm15 + vaesenclast %xmm6,%xmm12,%xmm12 + vpaddb %xmm2,%xmm5,%xmm6 + vaesenclast %xmm7,%xmm13,%xmm13 + vpaddb %xmm2,%xmm6,%xmm7 + vaesenclast %xmm3,%xmm14,%xmm14 + vpaddb %xmm2,%xmm7,%xmm3 + + addq $0x60,%r10 + subq $0x6,%rdx + jc L$6x_done + + vmovups %xmm9,-96(%rsi) + vpxor %xmm15,%xmm1,%xmm9 + vmovups %xmm10,-80(%rsi) + vmovdqa %xmm0,%xmm10 + vmovups %xmm11,-64(%rsi) + vmovdqa %xmm5,%xmm11 + vmovups %xmm12,-48(%rsi) + vmovdqa %xmm6,%xmm12 + vmovups %xmm13,-32(%rsi) + vmovdqa %xmm7,%xmm13 + vmovups %xmm14,-16(%rsi) + vmovdqa %xmm3,%xmm14 + vmovdqu 32+8(%rsp),%xmm7 + jmp L$oop6x + +L$6x_done: + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpxor %xmm4,%xmm8,%xmm8 + + .byte 0xf3,0xc3 + + +.globl _aesni_gcm_decrypt +.private_extern _aesni_gcm_decrypt + +.p2align 5 +_aesni_gcm_decrypt: + + xorq %r10,%r10 + + + + cmpq $0x60,%rdx + jb L$gcm_dec_abort + + leaq (%rsp),%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq L$bswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + vmovdqu (%r9),%xmm8 + andq $-128,%rsp + vmovdqu (%r11),%xmm0 + leaq 128(%rcx),%rcx + leaq 32+32(%r9),%r9 + movl 240-128(%rcx),%ebp + vpshufb %xmm0,%xmm8,%xmm8 + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc L$dec_no_key_aliasing + cmpq $768,%r15 + jnc L$dec_no_key_aliasing + subq %r15,%rsp +L$dec_no_key_aliasing: + + vmovdqu 80(%rdi),%xmm7 + leaq (%rdi),%r14 + vmovdqu 64(%rdi),%xmm4 + + + + + + + + leaq -192(%rdi,%rdx,1),%r15 + + vmovdqu 48(%rdi),%xmm5 + shrq $4,%rdx + xorq %r10,%r10 + vmovdqu 32(%rdi),%xmm6 + vpshufb %xmm0,%xmm7,%xmm7 + vmovdqu 16(%rdi),%xmm2 + vpshufb %xmm0,%xmm4,%xmm4 + vmovdqu (%rdi),%xmm3 + vpshufb %xmm0,%xmm5,%xmm5 + vmovdqu %xmm4,48(%rsp) + vpshufb %xmm0,%xmm6,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm2,%xmm2 + vmovdqu %xmm6,80(%rsp) + vpshufb %xmm0,%xmm3,%xmm3 + vmovdqu %xmm2,96(%rsp) + vmovdqu %xmm3,112(%rsp) + + call _aesni_ctr32_ghash_6x + + vmovups %xmm9,-96(%rsi) + vmovups %xmm10,-80(%rsi) + vmovups %xmm11,-64(%rsi) + vmovups %xmm12,-48(%rsi) + vmovups %xmm13,-32(%rsi) + vmovups %xmm14,-16(%rsi) + + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 + + movq -40(%rax),%r14 + + movq -32(%rax),%r13 + + movq -24(%rax),%r12 + + movq -16(%rax),%rbp + + movq -8(%rax),%rbx + + leaq (%rax),%rsp + +L$gcm_dec_abort: + movq %r10,%rax + .byte 0xf3,0xc3 + + + +.p2align 5 +_aesni_ctr32_6x: + + vmovdqu 0-128(%rcx),%xmm4 + vmovdqu 32(%r11),%xmm2 + leaq -1(%rbp),%r13 + vmovups 16-128(%rcx),%xmm15 + leaq 32-128(%rcx),%r12 + vpxor %xmm4,%xmm1,%xmm9 + addl $100663296,%ebx + jc L$handle_ctr32_2 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddb %xmm2,%xmm11,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddb %xmm2,%xmm12,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp L$oop_ctr32 + +.p2align 4 +L$oop_ctr32: + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + vmovups (%r12),%xmm15 + leaq 16(%r12),%r12 + decl %r13d + jnz L$oop_ctr32 + + vmovdqu (%r12),%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 0(%rdi),%xmm3,%xmm4 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor 16(%rdi),%xmm3,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 32(%rdi),%xmm3,%xmm6 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 48(%rdi),%xmm3,%xmm8 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 64(%rdi),%xmm3,%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 80(%rdi),%xmm3,%xmm3 + leaq 96(%rdi),%rdi + + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm5,%xmm10,%xmm10 + vaesenclast %xmm6,%xmm11,%xmm11 + vaesenclast %xmm8,%xmm12,%xmm12 + vaesenclast %xmm2,%xmm13,%xmm13 + vaesenclast %xmm3,%xmm14,%xmm14 + vmovups %xmm9,0(%rsi) + vmovups %xmm10,16(%rsi) + vmovups %xmm11,32(%rsi) + vmovups %xmm12,48(%rsi) + vmovups %xmm13,64(%rsi) + vmovups %xmm14,80(%rsi) + leaq 96(%rsi),%rsi + + .byte 0xf3,0xc3 +.p2align 5 +L$handle_ctr32_2: + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpshufb %xmm0,%xmm14,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpshufb %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp L$oop_ctr32 + + + +.globl _aesni_gcm_encrypt +.private_extern _aesni_gcm_encrypt + +.p2align 5 +_aesni_gcm_encrypt: + +#ifdef BORINGSSL_DISPATCH_TEST + + movb $1,_BORINGSSL_function_hit+2(%rip) +#endif + xorq %r10,%r10 + + + + + cmpq $288,%rdx + jb L$gcm_enc_abort + + leaq (%rsp),%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq L$bswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + leaq 128(%rcx),%rcx + vmovdqu (%r11),%xmm0 + andq $-128,%rsp + movl 240-128(%rcx),%ebp + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc L$enc_no_key_aliasing + cmpq $768,%r15 + jnc L$enc_no_key_aliasing + subq %r15,%rsp +L$enc_no_key_aliasing: + + leaq (%rsi),%r14 + + + + + + + + + leaq -192(%rsi,%rdx,1),%r15 + + shrq $4,%rdx + + call _aesni_ctr32_6x + vpshufb %xmm0,%xmm9,%xmm8 + vpshufb %xmm0,%xmm10,%xmm2 + vmovdqu %xmm8,112(%rsp) + vpshufb %xmm0,%xmm11,%xmm4 + vmovdqu %xmm2,96(%rsp) + vpshufb %xmm0,%xmm12,%xmm5 + vmovdqu %xmm4,80(%rsp) + vpshufb %xmm0,%xmm13,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm14,%xmm7 + vmovdqu %xmm6,48(%rsp) + + call _aesni_ctr32_6x + + vmovdqu (%r9),%xmm8 + leaq 32+32(%r9),%r9 + subq $12,%rdx + movq $192,%r10 + vpshufb %xmm0,%xmm8,%xmm8 + + call _aesni_ctr32_ghash_6x + vmovdqu 32(%rsp),%xmm7 + vmovdqu (%r11),%xmm0 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm7,%xmm7,%xmm1 + vmovdqu 32-32(%r9),%xmm15 + vmovups %xmm9,-96(%rsi) + vpshufb %xmm0,%xmm9,%xmm9 + vpxor %xmm7,%xmm1,%xmm1 + vmovups %xmm10,-80(%rsi) + vpshufb %xmm0,%xmm10,%xmm10 + vmovups %xmm11,-64(%rsi) + vpshufb %xmm0,%xmm11,%xmm11 + vmovups %xmm12,-48(%rsi) + vpshufb %xmm0,%xmm12,%xmm12 + vmovups %xmm13,-32(%rsi) + vpshufb %xmm0,%xmm13,%xmm13 + vmovups %xmm14,-16(%rsi) + vpshufb %xmm0,%xmm14,%xmm14 + vmovdqu %xmm9,16(%rsp) + vmovdqu 48(%rsp),%xmm6 + vmovdqu 16-32(%r9),%xmm0 + vpunpckhqdq %xmm6,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm5 + vpxor %xmm6,%xmm2,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + + vmovdqu 64(%rsp),%xmm9 + vpclmulqdq $0x00,%xmm0,%xmm6,%xmm4 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm9,%xmm9,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm6,%xmm6 + vpxor %xmm9,%xmm5,%xmm5 + vpxor %xmm7,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vmovdqu 80(%rsp),%xmm1 + vpclmulqdq $0x00,%xmm3,%xmm9,%xmm7 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm4,%xmm7,%xmm7 + vpunpckhqdq %xmm1,%xmm1,%xmm4 + vpclmulqdq $0x11,%xmm3,%xmm9,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpxor %xmm6,%xmm9,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm5,%xmm5 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 96(%rsp),%xmm2 + vpclmulqdq $0x00,%xmm0,%xmm1,%xmm6 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm7,%xmm6,%xmm6 + vpunpckhqdq %xmm2,%xmm2,%xmm7 + vpclmulqdq $0x11,%xmm0,%xmm1,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpxor %xmm9,%xmm1,%xmm1 + vpclmulqdq $0x10,%xmm15,%xmm4,%xmm4 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm5,%xmm4,%xmm4 + + vpxor 112(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm3,%xmm2,%xmm5 + vmovdqu 112-32(%r9),%xmm0 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x11,%xmm3,%xmm2,%xmm2 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm1,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm15,%xmm7,%xmm7 + vpxor %xmm4,%xmm7,%xmm4 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm6 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm1 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm8 + vpxor %xmm14,%xmm1,%xmm1 + vpxor %xmm5,%xmm6,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm9 + vmovdqu 32-32(%r9),%xmm15 + vpxor %xmm2,%xmm8,%xmm7 + vpxor %xmm4,%xmm9,%xmm6 + + vmovdqu 16-32(%r9),%xmm0 + vpxor %xmm5,%xmm7,%xmm9 + vpclmulqdq $0x00,%xmm3,%xmm14,%xmm4 + vpxor %xmm9,%xmm6,%xmm6 + vpunpckhqdq %xmm13,%xmm13,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm14,%xmm14 + vpxor %xmm13,%xmm2,%xmm2 + vpslldq $8,%xmm6,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + vpxor %xmm9,%xmm5,%xmm8 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm6,%xmm7,%xmm7 + + vpclmulqdq $0x00,%xmm0,%xmm13,%xmm5 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm12,%xmm12,%xmm9 + vpclmulqdq $0x11,%xmm0,%xmm13,%xmm13 + vpxor %xmm12,%xmm9,%xmm9 + vpxor %xmm14,%xmm13,%xmm13 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm3,%xmm12,%xmm4 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm11,%xmm11,%xmm1 + vpclmulqdq $0x11,%xmm3,%xmm12,%xmm12 + vpxor %xmm11,%xmm1,%xmm1 + vpxor %xmm13,%xmm12,%xmm12 + vxorps 16(%rsp),%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm9,%xmm9 + + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm0,%xmm11,%xmm5 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm10,%xmm10,%xmm2 + vpclmulqdq $0x11,%xmm0,%xmm11,%xmm11 + vpxor %xmm10,%xmm2,%xmm2 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpxor %xmm12,%xmm11,%xmm11 + vpclmulqdq $0x10,%xmm15,%xmm1,%xmm1 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm9,%xmm1,%xmm1 + + vxorps %xmm7,%xmm14,%xmm14 + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm3,%xmm10,%xmm4 + vmovdqu 112-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpclmulqdq $0x11,%xmm3,%xmm10,%xmm10 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm11,%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm15,%xmm2,%xmm2 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm7 + vpxor %xmm4,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm6 + vpxor %xmm10,%xmm7,%xmm7 + vpxor %xmm2,%xmm6,%xmm6 + + vpxor %xmm5,%xmm7,%xmm4 + vpxor %xmm4,%xmm6,%xmm6 + vpslldq $8,%xmm6,%xmm1 + vmovdqu 16(%r11),%xmm3 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm1,%xmm5,%xmm8 + vpxor %xmm6,%xmm7,%xmm7 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm2,%xmm8,%xmm8 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm7,%xmm2,%xmm2 + vpxor %xmm2,%xmm8,%xmm8 + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 + + movq -40(%rax),%r14 + + movq -32(%rax),%r13 + + movq -24(%rax),%r12 + + movq -16(%rax),%rbp + + movq -8(%rax),%rbx + + leaq (%rax),%rsp + +L$gcm_enc_abort: + movq %r10,%rax + .byte 0xf3,0xc3 + + +.p2align 6 +L$bswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +L$poly: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +L$one_msb: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +L$two_lsb: +.byte 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +L$one_lsb: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S new file mode 100644 index 00000000..25fabd1b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S @@ -0,0 +1,2520 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +#ifdef BORINGSSL_DISPATCH_TEST +#endif +.globl aes_hw_encrypt +.hidden aes_hw_encrypt +.type aes_hw_encrypt,@function +.align 16 +aes_hw_encrypt: +.L_aes_hw_encrypt_begin: +#ifdef BORINGSSL_DISPATCH_TEST + pushl %ebx + pushl %edx + call .L000pic +.L000pic: + popl %ebx + leal BORINGSSL_function_hit+1-.L000pic(%ebx),%ebx + movl $1,%edx + movb %dl,(%ebx) + popl %edx + popl %ebx +#endif + movl 4(%esp),%eax + movl 12(%esp),%edx + movups (%eax),%xmm2 + movl 240(%edx),%ecx + movl 8(%esp),%eax + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L001enc1_loop_1: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L001enc1_loop_1 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%eax) + pxor %xmm2,%xmm2 + ret +.size aes_hw_encrypt,.-.L_aes_hw_encrypt_begin +.globl aes_hw_decrypt +.hidden aes_hw_decrypt +.type aes_hw_decrypt,@function +.align 16 +aes_hw_decrypt: +.L_aes_hw_decrypt_begin: + movl 4(%esp),%eax + movl 12(%esp),%edx + movups (%eax),%xmm2 + movl 240(%edx),%ecx + movl 8(%esp),%eax + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L002dec1_loop_2: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L002dec1_loop_2 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%eax) + pxor %xmm2,%xmm2 + ret +.size aes_hw_decrypt,.-.L_aes_hw_decrypt_begin +.hidden _aesni_encrypt2 +.type _aesni_encrypt2,@function +.align 16 +_aesni_encrypt2: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L003enc2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L003enc2_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + ret +.size _aesni_encrypt2,.-_aesni_encrypt2 +.hidden _aesni_decrypt2 +.type _aesni_decrypt2,@function +.align 16 +_aesni_decrypt2: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L004dec2_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L004dec2_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 + ret +.size _aesni_decrypt2,.-_aesni_decrypt2 +.hidden _aesni_encrypt3 +.type _aesni_encrypt3,@function +.align 16 +_aesni_encrypt3: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L005enc3_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L005enc3_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 + ret +.size _aesni_encrypt3,.-_aesni_encrypt3 +.hidden _aesni_decrypt3 +.type _aesni_decrypt3,@function +.align 16 +_aesni_decrypt3: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L006dec3_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L006dec3_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 + ret +.size _aesni_decrypt3,.-_aesni_decrypt3 +.hidden _aesni_encrypt4 +.type _aesni_encrypt4,@function +.align 16 +_aesni_encrypt4: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + shll $4,%ecx + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 15,31,64,0 + addl $16,%ecx +.L007enc4_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L007enc4_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 + ret +.size _aesni_encrypt4,.-_aesni_encrypt4 +.hidden _aesni_decrypt4 +.type _aesni_decrypt4,@function +.align 16 +_aesni_decrypt4: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + shll $4,%ecx + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 15,31,64,0 + addl $16,%ecx +.L008dec4_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L008dec4_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 + ret +.size _aesni_decrypt4,.-_aesni_decrypt4 +.hidden _aesni_encrypt6 +.type _aesni_encrypt6,@function +.align 16 +_aesni_encrypt6: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,220,209 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,220,217 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 102,15,56,220,225 + pxor %xmm0,%xmm7 + movups (%edx,%ecx,1),%xmm0 + addl $16,%ecx + jmp .L009_aesni_encrypt6_inner +.align 16 +.L010enc6_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.L009_aesni_encrypt6_inner: +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.L_aesni_encrypt6_enter: + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L010enc6_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 + ret +.size _aesni_encrypt6,.-_aesni_encrypt6 +.hidden _aesni_decrypt6 +.type _aesni_decrypt6,@function +.align 16 +_aesni_decrypt6: + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,222,209 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,222,217 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 102,15,56,222,225 + pxor %xmm0,%xmm7 + movups (%edx,%ecx,1),%xmm0 + addl $16,%ecx + jmp .L011_aesni_decrypt6_inner +.align 16 +.L012dec6_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.L011_aesni_decrypt6_inner: +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.L_aesni_decrypt6_enter: + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L012dec6_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 + ret +.size _aesni_decrypt6,.-_aesni_decrypt6 +.globl aes_hw_ecb_encrypt +.hidden aes_hw_ecb_encrypt +.type aes_hw_ecb_encrypt,@function +.align 16 +aes_hw_ecb_encrypt: +.L_aes_hw_ecb_encrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + andl $-16,%eax + jz .L013ecb_ret + movl 240(%edx),%ecx + testl %ebx,%ebx + jz .L014ecb_decrypt + movl %edx,%ebp + movl %ecx,%ebx + cmpl $96,%eax + jb .L015ecb_enc_tail + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + subl $96,%eax + jmp .L016ecb_enc_loop6_enter +.align 16 +.L017ecb_enc_loop6: + movups %xmm2,(%edi) + movdqu (%esi),%xmm2 + movups %xmm3,16(%edi) + movdqu 16(%esi),%xmm3 + movups %xmm4,32(%edi) + movdqu 32(%esi),%xmm4 + movups %xmm5,48(%edi) + movdqu 48(%esi),%xmm5 + movups %xmm6,64(%edi) + movdqu 64(%esi),%xmm6 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi +.L016ecb_enc_loop6_enter: + call _aesni_encrypt6 + movl %ebp,%edx + movl %ebx,%ecx + subl $96,%eax + jnc .L017ecb_enc_loop6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + movups %xmm7,80(%edi) + leal 96(%edi),%edi + addl $96,%eax + jz .L013ecb_ret +.L015ecb_enc_tail: + movups (%esi),%xmm2 + cmpl $32,%eax + jb .L018ecb_enc_one + movups 16(%esi),%xmm3 + je .L019ecb_enc_two + movups 32(%esi),%xmm4 + cmpl $64,%eax + jb .L020ecb_enc_three + movups 48(%esi),%xmm5 + je .L021ecb_enc_four + movups 64(%esi),%xmm6 + xorps %xmm7,%xmm7 + call _aesni_encrypt6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L013ecb_ret +.align 16 +.L018ecb_enc_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L022enc1_loop_3: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L022enc1_loop_3 +.byte 102,15,56,221,209 + movups %xmm2,(%edi) + jmp .L013ecb_ret +.align 16 +.L019ecb_enc_two: + call _aesni_encrypt2 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L013ecb_ret +.align 16 +.L020ecb_enc_three: + call _aesni_encrypt3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L013ecb_ret +.align 16 +.L021ecb_enc_four: + call _aesni_encrypt4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + jmp .L013ecb_ret +.align 16 +.L014ecb_decrypt: + movl %edx,%ebp + movl %ecx,%ebx + cmpl $96,%eax + jb .L023ecb_dec_tail + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + subl $96,%eax + jmp .L024ecb_dec_loop6_enter +.align 16 +.L025ecb_dec_loop6: + movups %xmm2,(%edi) + movdqu (%esi),%xmm2 + movups %xmm3,16(%edi) + movdqu 16(%esi),%xmm3 + movups %xmm4,32(%edi) + movdqu 32(%esi),%xmm4 + movups %xmm5,48(%edi) + movdqu 48(%esi),%xmm5 + movups %xmm6,64(%edi) + movdqu 64(%esi),%xmm6 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi +.L024ecb_dec_loop6_enter: + call _aesni_decrypt6 + movl %ebp,%edx + movl %ebx,%ecx + subl $96,%eax + jnc .L025ecb_dec_loop6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + movups %xmm7,80(%edi) + leal 96(%edi),%edi + addl $96,%eax + jz .L013ecb_ret +.L023ecb_dec_tail: + movups (%esi),%xmm2 + cmpl $32,%eax + jb .L026ecb_dec_one + movups 16(%esi),%xmm3 + je .L027ecb_dec_two + movups 32(%esi),%xmm4 + cmpl $64,%eax + jb .L028ecb_dec_three + movups 48(%esi),%xmm5 + je .L029ecb_dec_four + movups 64(%esi),%xmm6 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L013ecb_ret +.align 16 +.L026ecb_dec_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L030dec1_loop_4: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L030dec1_loop_4 +.byte 102,15,56,223,209 + movups %xmm2,(%edi) + jmp .L013ecb_ret +.align 16 +.L027ecb_dec_two: + call _aesni_decrypt2 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L013ecb_ret +.align 16 +.L028ecb_dec_three: + call _aesni_decrypt3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L013ecb_ret +.align 16 +.L029ecb_dec_four: + call _aesni_decrypt4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) +.L013ecb_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_ecb_encrypt,.-.L_aes_hw_ecb_encrypt_begin +.globl aes_hw_ccm64_encrypt_blocks +.hidden aes_hw_ccm64_encrypt_blocks +.type aes_hw_ccm64_encrypt_blocks,@function +.align 16 +aes_hw_ccm64_encrypt_blocks: +.L_aes_hw_ccm64_encrypt_blocks_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl 40(%esp),%ecx + movl %esp,%ebp + subl $60,%esp + andl $-16,%esp + movl %ebp,48(%esp) + movdqu (%ebx),%xmm7 + movdqu (%ecx),%xmm3 + movl 240(%edx),%ecx + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $1,%ebx + xorl %ebp,%ebp + movl %ebx,16(%esp) + movl %ebp,20(%esp) + movl %ebp,24(%esp) + movl %ebp,28(%esp) + shll $4,%ecx + movl $16,%ebx + leal (%edx),%ebp + movdqa (%esp),%xmm5 + movdqa %xmm7,%xmm2 + leal 32(%edx,%ecx,1),%edx + subl %ecx,%ebx +.byte 102,15,56,0,253 +.L031ccm64_enc_outer: + movups (%ebp),%xmm0 + movl %ebx,%ecx + movups (%esi),%xmm6 + xorps %xmm0,%xmm2 + movups 16(%ebp),%xmm1 + xorps %xmm6,%xmm0 + xorps %xmm0,%xmm3 + movups 32(%ebp),%xmm0 +.L032ccm64_enc2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L032ccm64_enc2_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + paddq 16(%esp),%xmm7 + decl %eax +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + leal 16(%esi),%esi + xorps %xmm2,%xmm6 + movdqa %xmm7,%xmm2 + movups %xmm6,(%edi) +.byte 102,15,56,0,213 + leal 16(%edi),%edi + jnz .L031ccm64_enc_outer + movl 48(%esp),%esp + movl 40(%esp),%edi + movups %xmm3,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_ccm64_encrypt_blocks,.-.L_aes_hw_ccm64_encrypt_blocks_begin +.globl aes_hw_ccm64_decrypt_blocks +.hidden aes_hw_ccm64_decrypt_blocks +.type aes_hw_ccm64_decrypt_blocks,@function +.align 16 +aes_hw_ccm64_decrypt_blocks: +.L_aes_hw_ccm64_decrypt_blocks_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl 40(%esp),%ecx + movl %esp,%ebp + subl $60,%esp + andl $-16,%esp + movl %ebp,48(%esp) + movdqu (%ebx),%xmm7 + movdqu (%ecx),%xmm3 + movl 240(%edx),%ecx + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $1,%ebx + xorl %ebp,%ebp + movl %ebx,16(%esp) + movl %ebp,20(%esp) + movl %ebp,24(%esp) + movl %ebp,28(%esp) + movdqa (%esp),%xmm5 + movdqa %xmm7,%xmm2 + movl %edx,%ebp + movl %ecx,%ebx +.byte 102,15,56,0,253 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L033enc1_loop_5: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L033enc1_loop_5 +.byte 102,15,56,221,209 + shll $4,%ebx + movl $16,%ecx + movups (%esi),%xmm6 + paddq 16(%esp),%xmm7 + leal 16(%esi),%esi + subl %ebx,%ecx + leal 32(%ebp,%ebx,1),%edx + movl %ecx,%ebx + jmp .L034ccm64_dec_outer +.align 16 +.L034ccm64_dec_outer: + xorps %xmm2,%xmm6 + movdqa %xmm7,%xmm2 + movups %xmm6,(%edi) + leal 16(%edi),%edi +.byte 102,15,56,0,213 + subl $1,%eax + jz .L035ccm64_dec_break + movups (%ebp),%xmm0 + movl %ebx,%ecx + movups 16(%ebp),%xmm1 + xorps %xmm0,%xmm6 + xorps %xmm0,%xmm2 + xorps %xmm6,%xmm3 + movups 32(%ebp),%xmm0 +.L036ccm64_dec2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L036ccm64_dec2_loop + movups (%esi),%xmm6 + paddq 16(%esp),%xmm7 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + leal 16(%esi),%esi + jmp .L034ccm64_dec_outer +.align 16 +.L035ccm64_dec_break: + movl 240(%ebp),%ecx + movl %ebp,%edx + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm6 + leal 32(%edx),%edx + xorps %xmm6,%xmm3 +.L037enc1_loop_6: +.byte 102,15,56,220,217 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L037enc1_loop_6 +.byte 102,15,56,221,217 + movl 48(%esp),%esp + movl 40(%esp),%edi + movups %xmm3,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_ccm64_decrypt_blocks,.-.L_aes_hw_ccm64_decrypt_blocks_begin +.globl aes_hw_ctr32_encrypt_blocks +.hidden aes_hw_ctr32_encrypt_blocks +.type aes_hw_ctr32_encrypt_blocks,@function +.align 16 +aes_hw_ctr32_encrypt_blocks: +.L_aes_hw_ctr32_encrypt_blocks_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +#ifdef BORINGSSL_DISPATCH_TEST + pushl %ebx + pushl %edx + call .L038pic +.L038pic: + popl %ebx + leal BORINGSSL_function_hit+0-.L038pic(%ebx),%ebx + movl $1,%edx + movb %dl,(%ebx) + popl %edx + popl %ebx +#endif + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl %esp,%ebp + subl $88,%esp + andl $-16,%esp + movl %ebp,80(%esp) + cmpl $1,%eax + je .L039ctr32_one_shortcut + movdqu (%ebx),%xmm7 + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $6,%ecx + xorl %ebp,%ebp + movl %ecx,16(%esp) + movl %ecx,20(%esp) + movl %ecx,24(%esp) + movl %ebp,28(%esp) +.byte 102,15,58,22,251,3 +.byte 102,15,58,34,253,3 + movl 240(%edx),%ecx + bswap %ebx + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movdqa (%esp),%xmm2 +.byte 102,15,58,34,195,0 + leal 3(%ebx),%ebp +.byte 102,15,58,34,205,0 + incl %ebx +.byte 102,15,58,34,195,1 + incl %ebp +.byte 102,15,58,34,205,1 + incl %ebx +.byte 102,15,58,34,195,2 + incl %ebp +.byte 102,15,58,34,205,2 + movdqa %xmm0,48(%esp) +.byte 102,15,56,0,194 + movdqu (%edx),%xmm6 + movdqa %xmm1,64(%esp) +.byte 102,15,56,0,202 + pshufd $192,%xmm0,%xmm2 + pshufd $128,%xmm0,%xmm3 + cmpl $6,%eax + jb .L040ctr32_tail + pxor %xmm6,%xmm7 + shll $4,%ecx + movl $16,%ebx + movdqa %xmm7,32(%esp) + movl %edx,%ebp + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + subl $6,%eax + jmp .L041ctr32_loop6 +.align 16 +.L041ctr32_loop6: + pshufd $64,%xmm0,%xmm4 + movdqa 32(%esp),%xmm0 + pshufd $192,%xmm1,%xmm5 + pxor %xmm0,%xmm2 + pshufd $128,%xmm1,%xmm6 + pxor %xmm0,%xmm3 + pshufd $64,%xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 +.byte 102,15,56,220,209 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 +.byte 102,15,56,220,217 + movups 32(%ebp),%xmm0 + movl %ebx,%ecx +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + call .L_aesni_encrypt6_enter + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps %xmm1,%xmm2 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm3 + movups %xmm2,(%edi) + movdqa 16(%esp),%xmm0 + xorps %xmm1,%xmm4 + movdqa 64(%esp),%xmm1 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + paddd %xmm0,%xmm1 + paddd 48(%esp),%xmm0 + movdqa (%esp),%xmm2 + movups 48(%esi),%xmm3 + movups 64(%esi),%xmm4 + xorps %xmm3,%xmm5 + movups 80(%esi),%xmm3 + leal 96(%esi),%esi + movdqa %xmm0,48(%esp) +.byte 102,15,56,0,194 + xorps %xmm4,%xmm6 + movups %xmm5,48(%edi) + xorps %xmm3,%xmm7 + movdqa %xmm1,64(%esp) +.byte 102,15,56,0,202 + movups %xmm6,64(%edi) + pshufd $192,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + pshufd $128,%xmm0,%xmm3 + subl $6,%eax + jnc .L041ctr32_loop6 + addl $6,%eax + jz .L042ctr32_ret + movdqu (%ebp),%xmm7 + movl %ebp,%edx + pxor 32(%esp),%xmm7 + movl 240(%ebp),%ecx +.L040ctr32_tail: + por %xmm7,%xmm2 + cmpl $2,%eax + jb .L043ctr32_one + pshufd $64,%xmm0,%xmm4 + por %xmm7,%xmm3 + je .L044ctr32_two + pshufd $192,%xmm1,%xmm5 + por %xmm7,%xmm4 + cmpl $4,%eax + jb .L045ctr32_three + pshufd $128,%xmm1,%xmm6 + por %xmm7,%xmm5 + je .L046ctr32_four + por %xmm7,%xmm6 + call _aesni_encrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps %xmm1,%xmm2 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm3 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm4 + movups 64(%esi),%xmm1 + xorps %xmm0,%xmm5 + movups %xmm2,(%edi) + xorps %xmm1,%xmm6 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L042ctr32_ret +.align 16 +.L039ctr32_one_shortcut: + movups (%ebx),%xmm2 + movl 240(%edx),%ecx +.L043ctr32_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L047enc1_loop_7: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L047enc1_loop_7 +.byte 102,15,56,221,209 + movups (%esi),%xmm6 + xorps %xmm2,%xmm6 + movups %xmm6,(%edi) + jmp .L042ctr32_ret +.align 16 +.L044ctr32_two: + call _aesni_encrypt2 + movups (%esi),%xmm5 + movups 16(%esi),%xmm6 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L042ctr32_ret +.align 16 +.L045ctr32_three: + call _aesni_encrypt3 + movups (%esi),%xmm5 + movups 16(%esi),%xmm6 + xorps %xmm5,%xmm2 + movups 32(%esi),%xmm7 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + xorps %xmm7,%xmm4 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L042ctr32_ret +.align 16 +.L046ctr32_four: + call _aesni_encrypt4 + movups (%esi),%xmm6 + movups 16(%esi),%xmm7 + movups 32(%esi),%xmm1 + xorps %xmm6,%xmm2 + movups 48(%esi),%xmm0 + xorps %xmm7,%xmm3 + movups %xmm2,(%edi) + xorps %xmm1,%xmm4 + movups %xmm3,16(%edi) + xorps %xmm0,%xmm5 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) +.L042ctr32_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movl 80(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_ctr32_encrypt_blocks,.-.L_aes_hw_ctr32_encrypt_blocks_begin +.globl aes_hw_xts_encrypt +.hidden aes_hw_xts_encrypt +.type aes_hw_xts_encrypt,@function +.align 16 +aes_hw_xts_encrypt: +.L_aes_hw_xts_encrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 36(%esp),%edx + movl 40(%esp),%esi + movl 240(%edx),%ecx + movups (%esi),%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L048enc1_loop_8: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L048enc1_loop_8 +.byte 102,15,56,221,209 + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl %esp,%ebp + subl $120,%esp + movl 240(%edx),%ecx + andl $-16,%esp + movl $135,96(%esp) + movl $0,100(%esp) + movl $1,104(%esp) + movl $0,108(%esp) + movl %eax,112(%esp) + movl %ebp,116(%esp) + movdqa %xmm2,%xmm1 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + pcmpgtd %xmm1,%xmm0 + andl $-16,%eax + movl %edx,%ebp + movl %ecx,%ebx + subl $96,%eax + jc .L049xts_enc_short + shll $4,%ecx + movl $16,%ebx + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + jmp .L050xts_enc_loop6 +.align 16 +.L050xts_enc_loop6: + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,16(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,32(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,64(%esp) + paddq %xmm1,%xmm1 + movups (%ebp),%xmm0 + pand %xmm3,%xmm7 + movups (%esi),%xmm2 + pxor %xmm1,%xmm7 + movl %ebx,%ecx + movdqu 16(%esi),%xmm3 + xorps %xmm0,%xmm2 + movdqu 32(%esi),%xmm4 + pxor %xmm0,%xmm3 + movdqu 48(%esi),%xmm5 + pxor %xmm0,%xmm4 + movdqu 64(%esi),%xmm6 + pxor %xmm0,%xmm5 + movdqu 80(%esi),%xmm1 + pxor %xmm0,%xmm6 + leal 96(%esi),%esi + pxor (%esp),%xmm2 + movdqa %xmm7,80(%esp) + pxor %xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 +.byte 102,15,56,220,209 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 +.byte 102,15,56,220,217 + pxor %xmm0,%xmm7 + movups 32(%ebp),%xmm0 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + call .L_aesni_encrypt6_enter + movdqa 80(%esp),%xmm1 + pxor %xmm0,%xmm0 + xorps (%esp),%xmm2 + pcmpgtd %xmm1,%xmm0 + xorps 16(%esp),%xmm3 + movups %xmm2,(%edi) + xorps 32(%esp),%xmm4 + movups %xmm3,16(%edi) + xorps 48(%esp),%xmm5 + movups %xmm4,32(%edi) + xorps 64(%esp),%xmm6 + movups %xmm5,48(%edi) + xorps %xmm1,%xmm7 + movups %xmm6,64(%edi) + pshufd $19,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqa 96(%esp),%xmm3 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + subl $96,%eax + jnc .L050xts_enc_loop6 + movl 240(%ebp),%ecx + movl %ebp,%edx + movl %ecx,%ebx +.L049xts_enc_short: + addl $96,%eax + jz .L051xts_enc_done6x + movdqa %xmm1,%xmm5 + cmpl $32,%eax + jb .L052xts_enc_one + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + je .L053xts_enc_two + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + cmpl $64,%eax + jb .L054xts_enc_three + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm7 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + movdqa %xmm5,(%esp) + movdqa %xmm6,16(%esp) + je .L055xts_enc_four + movdqa %xmm7,32(%esp) + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm7 + pxor %xmm1,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + pxor (%esp),%xmm2 + movdqu 48(%esi),%xmm5 + pxor 16(%esp),%xmm3 + movdqu 64(%esi),%xmm6 + pxor 32(%esp),%xmm4 + leal 80(%esi),%esi + pxor 48(%esp),%xmm5 + movdqa %xmm7,64(%esp) + pxor %xmm7,%xmm6 + call _aesni_encrypt6 + movaps 64(%esp),%xmm1 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps 32(%esp),%xmm4 + movups %xmm2,(%edi) + xorps 48(%esp),%xmm5 + movups %xmm3,16(%edi) + xorps %xmm1,%xmm6 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + leal 80(%edi),%edi + jmp .L056xts_enc_done +.align 16 +.L052xts_enc_one: + movups (%esi),%xmm2 + leal 16(%esi),%esi + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L057enc1_loop_9: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L057enc1_loop_9 +.byte 102,15,56,221,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) + leal 16(%edi),%edi + movdqa %xmm5,%xmm1 + jmp .L056xts_enc_done +.align 16 +.L053xts_enc_two: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + leal 32(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + call _aesni_encrypt2 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 32(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L056xts_enc_done +.align 16 +.L054xts_enc_three: + movaps %xmm1,%xmm7 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + leal 48(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + call _aesni_encrypt3 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + leal 48(%edi),%edi + movdqa %xmm7,%xmm1 + jmp .L056xts_enc_done +.align 16 +.L055xts_enc_four: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + xorps (%esp),%xmm2 + movups 48(%esi),%xmm5 + leal 64(%esi),%esi + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + xorps %xmm6,%xmm5 + call _aesni_encrypt4 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + xorps %xmm6,%xmm5 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + leal 64(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L056xts_enc_done +.align 16 +.L051xts_enc_done6x: + movl 112(%esp),%eax + andl $15,%eax + jz .L058xts_enc_ret + movdqa %xmm1,%xmm5 + movl %eax,112(%esp) + jmp .L059xts_enc_steal +.align 16 +.L056xts_enc_done: + movl 112(%esp),%eax + pxor %xmm0,%xmm0 + andl $15,%eax + jz .L058xts_enc_ret + pcmpgtd %xmm1,%xmm0 + movl %eax,112(%esp) + pshufd $19,%xmm0,%xmm5 + paddq %xmm1,%xmm1 + pand 96(%esp),%xmm5 + pxor %xmm1,%xmm5 +.L059xts_enc_steal: + movzbl (%esi),%ecx + movzbl -16(%edi),%edx + leal 1(%esi),%esi + movb %cl,-16(%edi) + movb %dl,(%edi) + leal 1(%edi),%edi + subl $1,%eax + jnz .L059xts_enc_steal + subl 112(%esp),%edi + movl %ebp,%edx + movl %ebx,%ecx + movups -16(%edi),%xmm2 + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L060enc1_loop_10: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L060enc1_loop_10 +.byte 102,15,56,221,209 + xorps %xmm5,%xmm2 + movups %xmm2,-16(%edi) +.L058xts_enc_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movdqa %xmm0,(%esp) + pxor %xmm3,%xmm3 + movdqa %xmm0,16(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm0,80(%esp) + movl 116(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_xts_encrypt,.-.L_aes_hw_xts_encrypt_begin +.globl aes_hw_xts_decrypt +.hidden aes_hw_xts_decrypt +.type aes_hw_xts_decrypt,@function +.align 16 +aes_hw_xts_decrypt: +.L_aes_hw_xts_decrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 36(%esp),%edx + movl 40(%esp),%esi + movl 240(%edx),%ecx + movups (%esi),%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L061enc1_loop_11: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L061enc1_loop_11 +.byte 102,15,56,221,209 + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl %esp,%ebp + subl $120,%esp + andl $-16,%esp + xorl %ebx,%ebx + testl $15,%eax + setnz %bl + shll $4,%ebx + subl %ebx,%eax + movl $135,96(%esp) + movl $0,100(%esp) + movl $1,104(%esp) + movl $0,108(%esp) + movl %eax,112(%esp) + movl %ebp,116(%esp) + movl 240(%edx),%ecx + movl %edx,%ebp + movl %ecx,%ebx + movdqa %xmm2,%xmm1 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + pcmpgtd %xmm1,%xmm0 + andl $-16,%eax + subl $96,%eax + jc .L062xts_dec_short + shll $4,%ecx + movl $16,%ebx + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + jmp .L063xts_dec_loop6 +.align 16 +.L063xts_dec_loop6: + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,16(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,32(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,64(%esp) + paddq %xmm1,%xmm1 + movups (%ebp),%xmm0 + pand %xmm3,%xmm7 + movups (%esi),%xmm2 + pxor %xmm1,%xmm7 + movl %ebx,%ecx + movdqu 16(%esi),%xmm3 + xorps %xmm0,%xmm2 + movdqu 32(%esi),%xmm4 + pxor %xmm0,%xmm3 + movdqu 48(%esi),%xmm5 + pxor %xmm0,%xmm4 + movdqu 64(%esi),%xmm6 + pxor %xmm0,%xmm5 + movdqu 80(%esi),%xmm1 + pxor %xmm0,%xmm6 + leal 96(%esi),%esi + pxor (%esp),%xmm2 + movdqa %xmm7,80(%esp) + pxor %xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 +.byte 102,15,56,222,209 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm7 + movups 32(%ebp),%xmm0 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + call .L_aesni_decrypt6_enter + movdqa 80(%esp),%xmm1 + pxor %xmm0,%xmm0 + xorps (%esp),%xmm2 + pcmpgtd %xmm1,%xmm0 + xorps 16(%esp),%xmm3 + movups %xmm2,(%edi) + xorps 32(%esp),%xmm4 + movups %xmm3,16(%edi) + xorps 48(%esp),%xmm5 + movups %xmm4,32(%edi) + xorps 64(%esp),%xmm6 + movups %xmm5,48(%edi) + xorps %xmm1,%xmm7 + movups %xmm6,64(%edi) + pshufd $19,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqa 96(%esp),%xmm3 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + subl $96,%eax + jnc .L063xts_dec_loop6 + movl 240(%ebp),%ecx + movl %ebp,%edx + movl %ecx,%ebx +.L062xts_dec_short: + addl $96,%eax + jz .L064xts_dec_done6x + movdqa %xmm1,%xmm5 + cmpl $32,%eax + jb .L065xts_dec_one + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + je .L066xts_dec_two + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + cmpl $64,%eax + jb .L067xts_dec_three + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm7 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + movdqa %xmm5,(%esp) + movdqa %xmm6,16(%esp) + je .L068xts_dec_four + movdqa %xmm7,32(%esp) + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm7 + pxor %xmm1,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + pxor (%esp),%xmm2 + movdqu 48(%esi),%xmm5 + pxor 16(%esp),%xmm3 + movdqu 64(%esi),%xmm6 + pxor 32(%esp),%xmm4 + leal 80(%esi),%esi + pxor 48(%esp),%xmm5 + movdqa %xmm7,64(%esp) + pxor %xmm7,%xmm6 + call _aesni_decrypt6 + movaps 64(%esp),%xmm1 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps 32(%esp),%xmm4 + movups %xmm2,(%edi) + xorps 48(%esp),%xmm5 + movups %xmm3,16(%edi) + xorps %xmm1,%xmm6 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + leal 80(%edi),%edi + jmp .L069xts_dec_done +.align 16 +.L065xts_dec_one: + movups (%esi),%xmm2 + leal 16(%esi),%esi + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L070dec1_loop_12: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L070dec1_loop_12 +.byte 102,15,56,223,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) + leal 16(%edi),%edi + movdqa %xmm5,%xmm1 + jmp .L069xts_dec_done +.align 16 +.L066xts_dec_two: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + leal 32(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + call _aesni_decrypt2 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 32(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L069xts_dec_done +.align 16 +.L067xts_dec_three: + movaps %xmm1,%xmm7 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + leal 48(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + call _aesni_decrypt3 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + leal 48(%edi),%edi + movdqa %xmm7,%xmm1 + jmp .L069xts_dec_done +.align 16 +.L068xts_dec_four: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + xorps (%esp),%xmm2 + movups 48(%esi),%xmm5 + leal 64(%esi),%esi + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + xorps %xmm6,%xmm5 + call _aesni_decrypt4 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + xorps %xmm6,%xmm5 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + leal 64(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L069xts_dec_done +.align 16 +.L064xts_dec_done6x: + movl 112(%esp),%eax + andl $15,%eax + jz .L071xts_dec_ret + movl %eax,112(%esp) + jmp .L072xts_dec_only_one_more +.align 16 +.L069xts_dec_done: + movl 112(%esp),%eax + pxor %xmm0,%xmm0 + andl $15,%eax + jz .L071xts_dec_ret + pcmpgtd %xmm1,%xmm0 + movl %eax,112(%esp) + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 +.L072xts_dec_only_one_more: + pshufd $19,%xmm0,%xmm5 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm5 + pxor %xmm1,%xmm5 + movl %ebp,%edx + movl %ebx,%ecx + movups (%esi),%xmm2 + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L073dec1_loop_13: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L073dec1_loop_13 +.byte 102,15,56,223,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) +.L074xts_dec_steal: + movzbl 16(%esi),%ecx + movzbl (%edi),%edx + leal 1(%esi),%esi + movb %cl,(%edi) + movb %dl,16(%edi) + leal 1(%edi),%edi + subl $1,%eax + jnz .L074xts_dec_steal + subl 112(%esp),%edi + movl %ebp,%edx + movl %ebx,%ecx + movups (%edi),%xmm2 + xorps %xmm6,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L075dec1_loop_14: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L075dec1_loop_14 +.byte 102,15,56,223,209 + xorps %xmm6,%xmm2 + movups %xmm2,(%edi) +.L071xts_dec_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movdqa %xmm0,(%esp) + pxor %xmm3,%xmm3 + movdqa %xmm0,16(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm0,80(%esp) + movl 116(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_xts_decrypt,.-.L_aes_hw_xts_decrypt_begin +.globl aes_hw_cbc_encrypt +.hidden aes_hw_cbc_encrypt +.type aes_hw_cbc_encrypt,@function +.align 16 +aes_hw_cbc_encrypt: +.L_aes_hw_cbc_encrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl %esp,%ebx + movl 24(%esp),%edi + subl $24,%ebx + movl 28(%esp),%eax + andl $-16,%ebx + movl 32(%esp),%edx + movl 36(%esp),%ebp + testl %eax,%eax + jz .L076cbc_abort + cmpl $0,40(%esp) + xchgl %esp,%ebx + movups (%ebp),%xmm7 + movl 240(%edx),%ecx + movl %edx,%ebp + movl %ebx,16(%esp) + movl %ecx,%ebx + je .L077cbc_decrypt + movaps %xmm7,%xmm2 + cmpl $16,%eax + jb .L078cbc_enc_tail + subl $16,%eax + jmp .L079cbc_enc_loop +.align 16 +.L079cbc_enc_loop: + movups (%esi),%xmm7 + leal 16(%esi),%esi + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm7 + leal 32(%edx),%edx + xorps %xmm7,%xmm2 +.L080enc1_loop_15: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L080enc1_loop_15 +.byte 102,15,56,221,209 + movl %ebx,%ecx + movl %ebp,%edx + movups %xmm2,(%edi) + leal 16(%edi),%edi + subl $16,%eax + jnc .L079cbc_enc_loop + addl $16,%eax + jnz .L078cbc_enc_tail + movaps %xmm2,%xmm7 + pxor %xmm2,%xmm2 + jmp .L081cbc_ret +.L078cbc_enc_tail: + movl %eax,%ecx +.long 2767451785 + movl $16,%ecx + subl %eax,%ecx + xorl %eax,%eax +.long 2868115081 + leal -16(%edi),%edi + movl %ebx,%ecx + movl %edi,%esi + movl %ebp,%edx + jmp .L079cbc_enc_loop +.align 16 +.L077cbc_decrypt: + cmpl $80,%eax + jbe .L082cbc_dec_tail + movaps %xmm7,(%esp) + subl $80,%eax + jmp .L083cbc_dec_loop6_enter +.align 16 +.L084cbc_dec_loop6: + movaps %xmm0,(%esp) + movups %xmm7,(%edi) + leal 16(%edi),%edi +.L083cbc_dec_loop6_enter: + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + call _aesni_decrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps (%esp),%xmm2 + xorps %xmm1,%xmm3 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm4 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm5 + movups 64(%esi),%xmm1 + xorps %xmm0,%xmm6 + movups 80(%esi),%xmm0 + xorps %xmm1,%xmm7 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 96(%esi),%esi + movups %xmm4,32(%edi) + movl %ebx,%ecx + movups %xmm5,48(%edi) + movl %ebp,%edx + movups %xmm6,64(%edi) + leal 80(%edi),%edi + subl $96,%eax + ja .L084cbc_dec_loop6 + movaps %xmm7,%xmm2 + movaps %xmm0,%xmm7 + addl $80,%eax + jle .L085cbc_dec_clear_tail_collected + movups %xmm2,(%edi) + leal 16(%edi),%edi +.L082cbc_dec_tail: + movups (%esi),%xmm2 + movaps %xmm2,%xmm6 + cmpl $16,%eax + jbe .L086cbc_dec_one + movups 16(%esi),%xmm3 + movaps %xmm3,%xmm5 + cmpl $32,%eax + jbe .L087cbc_dec_two + movups 32(%esi),%xmm4 + cmpl $48,%eax + jbe .L088cbc_dec_three + movups 48(%esi),%xmm5 + cmpl $64,%eax + jbe .L089cbc_dec_four + movups 64(%esi),%xmm6 + movaps %xmm7,(%esp) + movups (%esi),%xmm2 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps (%esp),%xmm2 + xorps %xmm1,%xmm3 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm4 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm5 + movups 64(%esi),%xmm7 + xorps %xmm0,%xmm6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%edi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%edi) + pxor %xmm5,%xmm5 + leal 64(%edi),%edi + movaps %xmm6,%xmm2 + pxor %xmm6,%xmm6 + subl $80,%eax + jmp .L090cbc_dec_tail_collected +.align 16 +.L086cbc_dec_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L091dec1_loop_16: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L091dec1_loop_16 +.byte 102,15,56,223,209 + xorps %xmm7,%xmm2 + movaps %xmm6,%xmm7 + subl $16,%eax + jmp .L090cbc_dec_tail_collected +.align 16 +.L087cbc_dec_two: + call _aesni_decrypt2 + xorps %xmm7,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movaps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + leal 16(%edi),%edi + movaps %xmm5,%xmm7 + subl $32,%eax + jmp .L090cbc_dec_tail_collected +.align 16 +.L088cbc_dec_three: + call _aesni_decrypt3 + xorps %xmm7,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm5,%xmm4 + movups %xmm2,(%edi) + movaps %xmm4,%xmm2 + pxor %xmm4,%xmm4 + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + leal 32(%edi),%edi + movups 32(%esi),%xmm7 + subl $48,%eax + jmp .L090cbc_dec_tail_collected +.align 16 +.L089cbc_dec_four: + call _aesni_decrypt4 + movups 16(%esi),%xmm1 + movups 32(%esi),%xmm0 + xorps %xmm7,%xmm2 + movups 48(%esi),%xmm7 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + xorps %xmm1,%xmm4 + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + xorps %xmm0,%xmm5 + movups %xmm4,32(%edi) + pxor %xmm4,%xmm4 + leal 48(%edi),%edi + movaps %xmm5,%xmm2 + pxor %xmm5,%xmm5 + subl $64,%eax + jmp .L090cbc_dec_tail_collected +.align 16 +.L085cbc_dec_clear_tail_collected: + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 +.L090cbc_dec_tail_collected: + andl $15,%eax + jnz .L092cbc_dec_tail_partial + movups %xmm2,(%edi) + pxor %xmm0,%xmm0 + jmp .L081cbc_ret +.align 16 +.L092cbc_dec_tail_partial: + movaps %xmm2,(%esp) + pxor %xmm0,%xmm0 + movl $16,%ecx + movl %esp,%esi + subl %eax,%ecx +.long 2767451785 + movdqa %xmm2,(%esp) +.L081cbc_ret: + movl 16(%esp),%esp + movl 36(%esp),%ebp + pxor %xmm2,%xmm2 + pxor %xmm1,%xmm1 + movups %xmm7,(%ebp) + pxor %xmm7,%xmm7 +.L076cbc_abort: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aes_hw_cbc_encrypt,.-.L_aes_hw_cbc_encrypt_begin +.hidden _aesni_set_encrypt_key +.type _aesni_set_encrypt_key,@function +.align 16 +_aesni_set_encrypt_key: + pushl %ebp + pushl %ebx + testl %eax,%eax + jz .L093bad_pointer + testl %edx,%edx + jz .L093bad_pointer + call .L094pic +.L094pic: + popl %ebx + leal .Lkey_const-.L094pic(%ebx),%ebx + leal OPENSSL_ia32cap_P-.Lkey_const(%ebx),%ebp + movups (%eax),%xmm0 + xorps %xmm4,%xmm4 + movl 4(%ebp),%ebp + leal 16(%edx),%edx + andl $268437504,%ebp + cmpl $256,%ecx + je .L09514rounds + cmpl $192,%ecx + je .L09612rounds + cmpl $128,%ecx + jne .L097bad_keybits +.align 16 +.L09810rounds: + cmpl $268435456,%ebp + je .L09910rounds_alt + movl $9,%ecx + movups %xmm0,-16(%edx) +.byte 102,15,58,223,200,1 + call .L100key_128_cold +.byte 102,15,58,223,200,2 + call .L101key_128 +.byte 102,15,58,223,200,4 + call .L101key_128 +.byte 102,15,58,223,200,8 + call .L101key_128 +.byte 102,15,58,223,200,16 + call .L101key_128 +.byte 102,15,58,223,200,32 + call .L101key_128 +.byte 102,15,58,223,200,64 + call .L101key_128 +.byte 102,15,58,223,200,128 + call .L101key_128 +.byte 102,15,58,223,200,27 + call .L101key_128 +.byte 102,15,58,223,200,54 + call .L101key_128 + movups %xmm0,(%edx) + movl %ecx,80(%edx) + jmp .L102good_key +.align 16 +.L101key_128: + movups %xmm0,(%edx) + leal 16(%edx),%edx +.L100key_128_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + ret +.align 16 +.L09910rounds_alt: + movdqa (%ebx),%xmm5 + movl $8,%ecx + movdqa 32(%ebx),%xmm4 + movdqa %xmm0,%xmm2 + movdqu %xmm0,-16(%edx) +.L103loop_key128: +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + leal 16(%edx),%edx + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,-16(%edx) + movdqa %xmm0,%xmm2 + decl %ecx + jnz .L103loop_key128 + movdqa 48(%ebx),%xmm4 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,(%edx) + movdqa %xmm0,%xmm2 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,16(%edx) + movl $9,%ecx + movl %ecx,96(%edx) + jmp .L102good_key +.align 16 +.L09612rounds: + movq 16(%eax),%xmm2 + cmpl $268435456,%ebp + je .L10412rounds_alt + movl $11,%ecx + movups %xmm0,-16(%edx) +.byte 102,15,58,223,202,1 + call .L105key_192a_cold +.byte 102,15,58,223,202,2 + call .L106key_192b +.byte 102,15,58,223,202,4 + call .L107key_192a +.byte 102,15,58,223,202,8 + call .L106key_192b +.byte 102,15,58,223,202,16 + call .L107key_192a +.byte 102,15,58,223,202,32 + call .L106key_192b +.byte 102,15,58,223,202,64 + call .L107key_192a +.byte 102,15,58,223,202,128 + call .L106key_192b + movups %xmm0,(%edx) + movl %ecx,48(%edx) + jmp .L102good_key +.align 16 +.L107key_192a: + movups %xmm0,(%edx) + leal 16(%edx),%edx +.align 16 +.L105key_192a_cold: + movaps %xmm2,%xmm5 +.L108key_192b_warm: + shufps $16,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + pslldq $4,%xmm3 + xorps %xmm4,%xmm0 + pshufd $85,%xmm1,%xmm1 + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + ret +.align 16 +.L106key_192b: + movaps %xmm0,%xmm3 + shufps $68,%xmm0,%xmm5 + movups %xmm5,(%edx) + shufps $78,%xmm2,%xmm3 + movups %xmm3,16(%edx) + leal 32(%edx),%edx + jmp .L108key_192b_warm +.align 16 +.L10412rounds_alt: + movdqa 16(%ebx),%xmm5 + movdqa 32(%ebx),%xmm4 + movl $8,%ecx + movdqu %xmm0,-16(%edx) +.L109loop_key192: + movq %xmm2,(%edx) + movdqa %xmm2,%xmm1 +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + pslld $1,%xmm4 + leal 24(%edx),%edx + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pxor %xmm2,%xmm0 + pxor %xmm3,%xmm2 + movdqu %xmm0,-16(%edx) + decl %ecx + jnz .L109loop_key192 + movl $11,%ecx + movl %ecx,32(%edx) + jmp .L102good_key +.align 16 +.L09514rounds: + movups 16(%eax),%xmm2 + leal 16(%edx),%edx + cmpl $268435456,%ebp + je .L11014rounds_alt + movl $13,%ecx + movups %xmm0,-32(%edx) + movups %xmm2,-16(%edx) +.byte 102,15,58,223,202,1 + call .L111key_256a_cold +.byte 102,15,58,223,200,1 + call .L112key_256b +.byte 102,15,58,223,202,2 + call .L113key_256a +.byte 102,15,58,223,200,2 + call .L112key_256b +.byte 102,15,58,223,202,4 + call .L113key_256a +.byte 102,15,58,223,200,4 + call .L112key_256b +.byte 102,15,58,223,202,8 + call .L113key_256a +.byte 102,15,58,223,200,8 + call .L112key_256b +.byte 102,15,58,223,202,16 + call .L113key_256a +.byte 102,15,58,223,200,16 + call .L112key_256b +.byte 102,15,58,223,202,32 + call .L113key_256a +.byte 102,15,58,223,200,32 + call .L112key_256b +.byte 102,15,58,223,202,64 + call .L113key_256a + movups %xmm0,(%edx) + movl %ecx,16(%edx) + xorl %eax,%eax + jmp .L102good_key +.align 16 +.L113key_256a: + movups %xmm2,(%edx) + leal 16(%edx),%edx +.L111key_256a_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + ret +.align 16 +.L112key_256b: + movups %xmm0,(%edx) + leal 16(%edx),%edx + shufps $16,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $140,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $170,%xmm1,%xmm1 + xorps %xmm1,%xmm2 + ret +.align 16 +.L11014rounds_alt: + movdqa (%ebx),%xmm5 + movdqa 32(%ebx),%xmm4 + movl $7,%ecx + movdqu %xmm0,-32(%edx) + movdqa %xmm2,%xmm1 + movdqu %xmm2,-16(%edx) +.L114loop_key256: +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pslld $1,%xmm4 + pxor %xmm2,%xmm0 + movdqu %xmm0,(%edx) + decl %ecx + jz .L115done_key256 + pshufd $255,%xmm0,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,221,211 + movdqa %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm3,%xmm1 + pxor %xmm1,%xmm2 + movdqu %xmm2,16(%edx) + leal 32(%edx),%edx + movdqa %xmm2,%xmm1 + jmp .L114loop_key256 +.L115done_key256: + movl $13,%ecx + movl %ecx,16(%edx) +.L102good_key: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + xorl %eax,%eax + popl %ebx + popl %ebp + ret +.align 4 +.L093bad_pointer: + movl $-1,%eax + popl %ebx + popl %ebp + ret +.align 4 +.L097bad_keybits: + pxor %xmm0,%xmm0 + movl $-2,%eax + popl %ebx + popl %ebp + ret +.size _aesni_set_encrypt_key,.-_aesni_set_encrypt_key +.globl aes_hw_set_encrypt_key +.hidden aes_hw_set_encrypt_key +.type aes_hw_set_encrypt_key,@function +.align 16 +aes_hw_set_encrypt_key: +.L_aes_hw_set_encrypt_key_begin: +#ifdef BORINGSSL_DISPATCH_TEST + pushl %ebx + pushl %edx + call .L116pic +.L116pic: + popl %ebx + leal BORINGSSL_function_hit+3-.L116pic(%ebx),%ebx + movl $1,%edx + movb %dl,(%ebx) + popl %edx + popl %ebx +#endif + movl 4(%esp),%eax + movl 8(%esp),%ecx + movl 12(%esp),%edx + call _aesni_set_encrypt_key + ret +.size aes_hw_set_encrypt_key,.-.L_aes_hw_set_encrypt_key_begin +.globl aes_hw_set_decrypt_key +.hidden aes_hw_set_decrypt_key +.type aes_hw_set_decrypt_key,@function +.align 16 +aes_hw_set_decrypt_key: +.L_aes_hw_set_decrypt_key_begin: + movl 4(%esp),%eax + movl 8(%esp),%ecx + movl 12(%esp),%edx + call _aesni_set_encrypt_key + movl 12(%esp),%edx + shll $4,%ecx + testl %eax,%eax + jnz .L117dec_key_ret + leal 16(%edx,%ecx,1),%eax + movups (%edx),%xmm0 + movups (%eax),%xmm1 + movups %xmm0,(%eax) + movups %xmm1,(%edx) + leal 16(%edx),%edx + leal -16(%eax),%eax +.L118dec_key_inverse: + movups (%edx),%xmm0 + movups (%eax),%xmm1 +.byte 102,15,56,219,192 +.byte 102,15,56,219,201 + leal 16(%edx),%edx + leal -16(%eax),%eax + movups %xmm0,16(%eax) + movups %xmm1,-16(%edx) + cmpl %edx,%eax + ja .L118dec_key_inverse + movups (%edx),%xmm0 +.byte 102,15,56,219,192 + movups %xmm0,(%edx) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + xorl %eax,%eax +.L117dec_key_ret: + ret +.size aes_hw_set_decrypt_key,.-.L_aes_hw_set_decrypt_key_begin +.align 64 +.Lkey_const: +.long 202313229,202313229,202313229,202313229 +.long 67569157,67569157,67569157,67569157 +.long 1,1,1,1 +.long 27,27,27,27 +.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69 +.byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 +.byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 +.byte 115,108,46,111,114,103,62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S new file mode 100644 index 00000000..850b8a76 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S @@ -0,0 +1,2513 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P +.globl aes_hw_encrypt +.hidden aes_hw_encrypt +.type aes_hw_encrypt,@function +.align 16 +aes_hw_encrypt: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST +.extern BORINGSSL_function_hit +.hidden BORINGSSL_function_hit + movb $1,BORINGSSL_function_hit+1(%rip) +#endif + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +.Loop_enc1_1: +.byte 102,15,56,220,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz .Loop_enc1_1 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 +.cfi_endproc +.size aes_hw_encrypt,.-aes_hw_encrypt + +.globl aes_hw_decrypt +.hidden aes_hw_decrypt +.type aes_hw_decrypt,@function +.align 16 +aes_hw_decrypt: +.cfi_startproc + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +.Loop_dec1_2: +.byte 102,15,56,222,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz .Loop_dec1_2 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 +.cfi_endproc +.size aes_hw_decrypt, .-aes_hw_decrypt +.type _aesni_encrypt2,@function +.align 16 +_aesni_encrypt2: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Lenc_loop2: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop2 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt2,.-_aesni_encrypt2 +.type _aesni_decrypt2,@function +.align 16 +_aesni_decrypt2: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Ldec_loop2: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop2 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt2,.-_aesni_decrypt2 +.type _aesni_encrypt3,@function +.align 16 +_aesni_encrypt3: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Lenc_loop3: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop3 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt3,.-_aesni_encrypt3 +.type _aesni_decrypt3,@function +.align 16 +_aesni_decrypt3: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Ldec_loop3: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop3 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt3,.-_aesni_decrypt3 +.type _aesni_encrypt4,@function +.align 16 +_aesni_encrypt4: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +.Lenc_loop4: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop4 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt4,.-_aesni_encrypt4 +.type _aesni_decrypt4,@function +.align 16 +_aesni_decrypt4: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +.Ldec_loop4: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop4 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt4,.-_aesni_decrypt4 +.type _aesni_encrypt6,@function +.align 16 +_aesni_encrypt6: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,220,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,220,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Lenc_loop6_enter +.align 16 +.Lenc_loop6: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.Lenc_loop6_enter: +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop6 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt6,.-_aesni_encrypt6 +.type _aesni_decrypt6,@function +.align 16 +_aesni_decrypt6: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,222,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,222,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Ldec_loop6_enter +.align 16 +.Ldec_loop6: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.Ldec_loop6_enter: +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop6 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt6,.-_aesni_decrypt6 +.type _aesni_encrypt8,@function +.align 16 +_aesni_encrypt8: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,220,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Lenc_loop8_inner +.align 16 +.Lenc_loop8: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.Lenc_loop8_inner: +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +.Lenc_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop8 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 +.byte 102,68,15,56,221,192 +.byte 102,68,15,56,221,200 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt8,.-_aesni_encrypt8 +.type _aesni_decrypt8,@function +.align 16 +_aesni_decrypt8: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Ldec_loop8_inner +.align 16 +.Ldec_loop8: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.Ldec_loop8_inner: +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +.Ldec_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop8 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 +.byte 102,68,15,56,223,192 +.byte 102,68,15,56,223,200 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt8,.-_aesni_decrypt8 +.globl aes_hw_ecb_encrypt +.hidden aes_hw_ecb_encrypt +.type aes_hw_ecb_encrypt,@function +.align 16 +aes_hw_ecb_encrypt: +.cfi_startproc + andq $-16,%rdx + jz .Lecb_ret + + movl 240(%rcx),%eax + movups (%rcx),%xmm0 + movq %rcx,%r11 + movl %eax,%r10d + testl %r8d,%r8d + jz .Lecb_decrypt + + cmpq $0x80,%rdx + jb .Lecb_enc_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp .Lecb_enc_loop8_enter +.align 16 +.Lecb_enc_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +.Lecb_enc_loop8_enter: + + call _aesni_encrypt8 + + subq $0x80,%rdx + jnc .Lecb_enc_loop8 + + movups %xmm2,(%rsi) + movq %r11,%rcx + movups %xmm3,16(%rsi) + movl %r10d,%eax + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz .Lecb_ret + +.Lecb_enc_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb .Lecb_enc_one + movups 16(%rdi),%xmm3 + je .Lecb_enc_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb .Lecb_enc_three + movups 48(%rdi),%xmm5 + je .Lecb_enc_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb .Lecb_enc_five + movups 80(%rdi),%xmm7 + je .Lecb_enc_six + movdqu 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_encrypt8 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_3: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_3 +.byte 102,15,56,221,209 + movups %xmm2,(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_two: + call _aesni_encrypt2 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_three: + call _aesni_encrypt3 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_four: + call _aesni_encrypt4 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_five: + xorps %xmm7,%xmm7 + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_six: + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + jmp .Lecb_ret + +.align 16 +.Lecb_decrypt: + cmpq $0x80,%rdx + jb .Lecb_dec_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp .Lecb_dec_loop8_enter +.align 16 +.Lecb_dec_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +.Lecb_dec_loop8_enter: + + call _aesni_decrypt8 + + movups (%r11),%xmm0 + subq $0x80,%rdx + jnc .Lecb_dec_loop8 + + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movq %r11,%rcx + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movl %r10d,%eax + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + movups %xmm9,112(%rsi) + pxor %xmm9,%xmm9 + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz .Lecb_ret + +.Lecb_dec_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb .Lecb_dec_one + movups 16(%rdi),%xmm3 + je .Lecb_dec_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb .Lecb_dec_three + movups 48(%rdi),%xmm5 + je .Lecb_dec_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb .Lecb_dec_five + movups 80(%rdi),%xmm7 + je .Lecb_dec_six + movups 96(%rdi),%xmm8 + movups (%rcx),%xmm0 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp .Lecb_ret +.align 16 +.Lecb_dec_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_4: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_4 +.byte 102,15,56,223,209 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lecb_ret +.align 16 +.Lecb_dec_two: + call _aesni_decrypt2 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + jmp .Lecb_ret +.align 16 +.Lecb_dec_three: + call _aesni_decrypt3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + jmp .Lecb_ret +.align 16 +.Lecb_dec_four: + call _aesni_decrypt4 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + jmp .Lecb_ret +.align 16 +.Lecb_dec_five: + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + jmp .Lecb_ret +.align 16 +.Lecb_dec_six: + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + +.Lecb_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + .byte 0xf3,0xc3 +.cfi_endproc +.size aes_hw_ecb_encrypt,.-aes_hw_ecb_encrypt +.globl aes_hw_ctr32_encrypt_blocks +.hidden aes_hw_ctr32_encrypt_blocks +.type aes_hw_ctr32_encrypt_blocks,@function +.align 16 +aes_hw_ctr32_encrypt_blocks: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST + movb $1,BORINGSSL_function_hit(%rip) +#endif + cmpq $1,%rdx + jne .Lctr32_bulk + + + + movups (%r8),%xmm2 + movups (%rdi),%xmm3 + movl 240(%rcx),%edx + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_5: +.byte 102,15,56,220,209 + decl %edx + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_5 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + xorps %xmm2,%xmm2 + jmp .Lctr32_epilogue + +.align 16 +.Lctr32_bulk: + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $128,%rsp + andq $-16,%rsp + + + + + movdqu (%r8),%xmm2 + movdqu (%rcx),%xmm0 + movl 12(%r8),%r8d + pxor %xmm0,%xmm2 + movl 12(%rcx),%ebp + movdqa %xmm2,0(%rsp) + bswapl %r8d + movdqa %xmm2,%xmm3 + movdqa %xmm2,%xmm4 + movdqa %xmm2,%xmm5 + movdqa %xmm2,64(%rsp) + movdqa %xmm2,80(%rsp) + movdqa %xmm2,96(%rsp) + movq %rdx,%r10 + movdqa %xmm2,112(%rsp) + + leaq 1(%r8),%rax + leaq 2(%r8),%rdx + bswapl %eax + bswapl %edx + xorl %ebp,%eax + xorl %ebp,%edx +.byte 102,15,58,34,216,3 + leaq 3(%r8),%rax + movdqa %xmm3,16(%rsp) +.byte 102,15,58,34,226,3 + bswapl %eax + movq %r10,%rdx + leaq 4(%r8),%r10 + movdqa %xmm4,32(%rsp) + xorl %ebp,%eax + bswapl %r10d +.byte 102,15,58,34,232,3 + xorl %ebp,%r10d + movdqa %xmm5,48(%rsp) + leaq 5(%r8),%r9 + movl %r10d,64+12(%rsp) + bswapl %r9d + leaq 6(%r8),%r10 + movl 240(%rcx),%eax + xorl %ebp,%r9d + bswapl %r10d + movl %r9d,80+12(%rsp) + xorl %ebp,%r10d + leaq 7(%r8),%r9 + movl %r10d,96+12(%rsp) + bswapl %r9d + leaq OPENSSL_ia32cap_P(%rip),%r10 + movl 4(%r10),%r10d + xorl %ebp,%r9d + andl $71303168,%r10d + movl %r9d,112+12(%rsp) + + movups 16(%rcx),%xmm1 + + movdqa 64(%rsp),%xmm6 + movdqa 80(%rsp),%xmm7 + + cmpq $8,%rdx + jb .Lctr32_tail + + subq $6,%rdx + cmpl $4194304,%r10d + je .Lctr32_6x + + leaq 128(%rcx),%rcx + subq $2,%rdx + jmp .Lctr32_loop8 + +.align 16 +.Lctr32_6x: + shll $4,%eax + movl $48,%r10d + bswapl %ebp + leaq 32(%rcx,%rax,1),%rcx + subq %rax,%r10 + jmp .Lctr32_loop6 + +.align 16 +.Lctr32_loop6: + addl $6,%r8d + movups -48(%rcx,%r10,1),%xmm0 +.byte 102,15,56,220,209 + movl %r8d,%eax + xorl %ebp,%eax +.byte 102,15,56,220,217 +.byte 0x0f,0x38,0xf1,0x44,0x24,12 + leal 1(%r8),%eax +.byte 102,15,56,220,225 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,28 +.byte 102,15,56,220,233 + leal 2(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,241 +.byte 0x0f,0x38,0xf1,0x44,0x24,44 + leal 3(%r8),%eax +.byte 102,15,56,220,249 + movups -32(%rcx,%r10,1),%xmm1 + xorl %ebp,%eax + +.byte 102,15,56,220,208 +.byte 0x0f,0x38,0xf1,0x44,0x24,60 + leal 4(%r8),%eax +.byte 102,15,56,220,216 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,76 +.byte 102,15,56,220,224 + leal 5(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,232 +.byte 0x0f,0x38,0xf1,0x44,0x24,92 + movq %r10,%rax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%r10,1),%xmm0 + + call .Lenc_loop6 + + movdqu (%rdi),%xmm8 + movdqu 16(%rdi),%xmm9 + movdqu 32(%rdi),%xmm10 + movdqu 48(%rdi),%xmm11 + movdqu 64(%rdi),%xmm12 + movdqu 80(%rdi),%xmm13 + leaq 96(%rdi),%rdi + movups -64(%rcx,%r10,1),%xmm1 + pxor %xmm2,%xmm8 + movaps 0(%rsp),%xmm2 + pxor %xmm3,%xmm9 + movaps 16(%rsp),%xmm3 + pxor %xmm4,%xmm10 + movaps 32(%rsp),%xmm4 + pxor %xmm5,%xmm11 + movaps 48(%rsp),%xmm5 + pxor %xmm6,%xmm12 + movaps 64(%rsp),%xmm6 + pxor %xmm7,%xmm13 + movaps 80(%rsp),%xmm7 + movdqu %xmm8,(%rsi) + movdqu %xmm9,16(%rsi) + movdqu %xmm10,32(%rsi) + movdqu %xmm11,48(%rsi) + movdqu %xmm12,64(%rsi) + movdqu %xmm13,80(%rsi) + leaq 96(%rsi),%rsi + + subq $6,%rdx + jnc .Lctr32_loop6 + + addq $6,%rdx + jz .Lctr32_done + + leal -48(%r10),%eax + leaq -80(%rcx,%r10,1),%rcx + negl %eax + shrl $4,%eax + jmp .Lctr32_tail + +.align 32 +.Lctr32_loop8: + addl $8,%r8d + movdqa 96(%rsp),%xmm8 +.byte 102,15,56,220,209 + movl %r8d,%r9d + movdqa 112(%rsp),%xmm9 +.byte 102,15,56,220,217 + bswapl %r9d + movups 32-128(%rcx),%xmm0 +.byte 102,15,56,220,225 + xorl %ebp,%r9d + nop +.byte 102,15,56,220,233 + movl %r9d,0+12(%rsp) + leaq 1(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 48-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,16+12(%rsp) + leaq 2(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 64-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,32+12(%rsp) + leaq 3(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 80-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,48+12(%rsp) + leaq 4(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 96-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,64+12(%rsp) + leaq 5(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 112-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,80+12(%rsp) + leaq 6(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 128-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,96+12(%rsp) + leaq 7(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 144-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + xorl %ebp,%r9d + movdqu 0(%rdi),%xmm10 +.byte 102,15,56,220,232 + movl %r9d,112+12(%rsp) + cmpl $11,%eax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 160-128(%rcx),%xmm0 + + jb .Lctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 176-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 192-128(%rcx),%xmm0 + je .Lctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 208-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 224-128(%rcx),%xmm0 + jmp .Lctr32_enc_done + +.align 16 +.Lctr32_enc_done: + movdqu 16(%rdi),%xmm11 + pxor %xmm0,%xmm10 + movdqu 32(%rdi),%xmm12 + pxor %xmm0,%xmm11 + movdqu 48(%rdi),%xmm13 + pxor %xmm0,%xmm12 + movdqu 64(%rdi),%xmm14 + pxor %xmm0,%xmm13 + movdqu 80(%rdi),%xmm15 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movdqu 96(%rdi),%xmm1 + leaq 128(%rdi),%rdi + +.byte 102,65,15,56,221,210 + pxor %xmm0,%xmm1 + movdqu 112-128(%rdi),%xmm10 +.byte 102,65,15,56,221,219 + pxor %xmm0,%xmm10 + movdqa 0(%rsp),%xmm11 +.byte 102,65,15,56,221,228 +.byte 102,65,15,56,221,237 + movdqa 16(%rsp),%xmm12 + movdqa 32(%rsp),%xmm13 +.byte 102,65,15,56,221,246 +.byte 102,65,15,56,221,255 + movdqa 48(%rsp),%xmm14 + movdqa 64(%rsp),%xmm15 +.byte 102,68,15,56,221,193 + movdqa 80(%rsp),%xmm0 + movups 16-128(%rcx),%xmm1 +.byte 102,69,15,56,221,202 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm0,%xmm7 + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + + subq $8,%rdx + jnc .Lctr32_loop8 + + addq $8,%rdx + jz .Lctr32_done + leaq -128(%rcx),%rcx + +.Lctr32_tail: + + + leaq 16(%rcx),%rcx + cmpq $4,%rdx + jb .Lctr32_loop3 + je .Lctr32_loop4 + + + shll $4,%eax + movdqa 96(%rsp),%xmm8 + pxor %xmm9,%xmm9 + + movups 16(%rcx),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + leaq 32-16(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,225 + addq $16,%rax + movups (%rdi),%xmm10 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 + movups 16(%rdi),%xmm11 + movups 32(%rdi),%xmm12 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 + + call .Lenc_loop8_enter + + movdqu 48(%rdi),%xmm13 + pxor %xmm10,%xmm2 + movdqu 64(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm10,%xmm6 + movdqu %xmm5,48(%rsi) + movdqu %xmm6,64(%rsi) + cmpq $6,%rdx + jb .Lctr32_done + + movups 80(%rdi),%xmm11 + xorps %xmm11,%xmm7 + movups %xmm7,80(%rsi) + je .Lctr32_done + + movups 96(%rdi),%xmm12 + xorps %xmm12,%xmm8 + movups %xmm8,96(%rsi) + jmp .Lctr32_done + +.align 32 +.Lctr32_loop4: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx),%xmm1 + jnz .Lctr32_loop4 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 + movups (%rdi),%xmm10 + movups 16(%rdi),%xmm11 +.byte 102,15,56,221,225 +.byte 102,15,56,221,233 + movups 32(%rdi),%xmm12 + movups 48(%rdi),%xmm13 + + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm4,32(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm5,48(%rsi) + jmp .Lctr32_done + +.align 32 +.Lctr32_loop3: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx),%xmm1 + jnz .Lctr32_loop3 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 +.byte 102,15,56,221,225 + + movups (%rdi),%xmm10 + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + cmpq $2,%rdx + jb .Lctr32_done + + movups 16(%rdi),%xmm11 + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + je .Lctr32_done + + movups 32(%rdi),%xmm12 + xorps %xmm12,%xmm4 + movups %xmm4,32(%rsi) + +.Lctr32_done: + xorps %xmm0,%xmm0 + xorl %ebp,%ebp + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + movaps %xmm0,0(%rsp) + pxor %xmm8,%xmm8 + movaps %xmm0,16(%rsp) + pxor %xmm9,%xmm9 + movaps %xmm0,32(%rsp) + pxor %xmm10,%xmm10 + movaps %xmm0,48(%rsp) + pxor %xmm11,%xmm11 + movaps %xmm0,64(%rsp) + pxor %xmm12,%xmm12 + movaps %xmm0,80(%rsp) + pxor %xmm13,%xmm13 + movaps %xmm0,96(%rsp) + pxor %xmm14,%xmm14 + movaps %xmm0,112(%rsp) + pxor %xmm15,%xmm15 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lctr32_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks +.globl aes_hw_cbc_encrypt +.hidden aes_hw_cbc_encrypt +.type aes_hw_cbc_encrypt,@function +.align 16 +aes_hw_cbc_encrypt: +.cfi_startproc + testq %rdx,%rdx + jz .Lcbc_ret + + movl 240(%rcx),%r10d + movq %rcx,%r11 + testl %r9d,%r9d + jz .Lcbc_decrypt + + movups (%r8),%xmm2 + movl %r10d,%eax + cmpq $16,%rdx + jb .Lcbc_enc_tail + subq $16,%rdx + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movups (%rdi),%xmm3 + leaq 16(%rdi),%rdi + + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm3 + leaq 32(%rcx),%rcx + xorps %xmm3,%xmm2 +.Loop_enc1_6: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_6 +.byte 102,15,56,221,209 + movl %r10d,%eax + movq %r11,%rcx + movups %xmm2,0(%rsi) + leaq 16(%rsi),%rsi + subq $16,%rdx + jnc .Lcbc_enc_loop + addq $16,%rdx + jnz .Lcbc_enc_tail + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%r8) + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + jmp .Lcbc_ret + +.Lcbc_enc_tail: + movq %rdx,%rcx + xchgq %rdi,%rsi +.long 0x9066A4F3 + movl $16,%ecx + subq %rdx,%rcx + xorl %eax,%eax +.long 0x9066AAF3 + leaq -16(%rdi),%rdi + movl %r10d,%eax + movq %rdi,%rsi + movq %r11,%rcx + xorq %rdx,%rdx + jmp .Lcbc_enc_loop + +.align 16 +.Lcbc_decrypt: + cmpq $16,%rdx + jne .Lcbc_decrypt_bulk + + + + movdqu (%rdi),%xmm2 + movdqu (%r8),%xmm3 + movdqa %xmm2,%xmm4 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_7: +.byte 102,15,56,222,209 + decl %r10d + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_7 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movdqu %xmm4,(%r8) + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lcbc_ret +.align 16 +.Lcbc_decrypt_bulk: + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $16,%rsp + andq $-16,%rsp + movq %rcx,%rbp + movups (%r8),%xmm10 + movl %r10d,%eax + cmpq $0x50,%rdx + jbe .Lcbc_dec_tail + + movups (%rcx),%xmm0 + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 + leaq OPENSSL_ia32cap_P(%rip),%r9 + movl 4(%r9),%r9d + cmpq $0x70,%rdx + jbe .Lcbc_dec_six_or_seven + + andl $71303168,%r9d + subq $0x50,%rdx + cmpl $4194304,%r9d + je .Lcbc_dec_loop6_enter + subq $0x20,%rdx + leaq 112(%rcx),%rcx + jmp .Lcbc_dec_loop8_enter +.align 16 +.Lcbc_dec_loop8: + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi +.Lcbc_dec_loop8_enter: + movdqu 96(%rdi),%xmm8 + pxor %xmm0,%xmm2 + movdqu 112(%rdi),%xmm9 + pxor %xmm0,%xmm3 + movups 16-112(%rcx),%xmm1 + pxor %xmm0,%xmm4 + movq $-1,%rbp + cmpq $0x70,%rdx + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 + +.byte 102,15,56,222,209 + pxor %xmm0,%xmm9 + movups 32-112(%rcx),%xmm0 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 + adcq $0,%rbp + andq $128,%rbp +.byte 102,68,15,56,222,201 + addq %rdi,%rbp + movups 48-112(%rcx),%xmm1 +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 64-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 80-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 96-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 112-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 128-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 144-112(%rcx),%xmm1 + cmpl $11,%eax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 160-112(%rcx),%xmm0 + jb .Lcbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 176-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 192-112(%rcx),%xmm0 + je .Lcbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 208-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 224-112(%rcx),%xmm0 + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_done: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm10 + pxor %xmm0,%xmm11 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + pxor %xmm0,%xmm12 + pxor %xmm0,%xmm13 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movdqu 80(%rdi),%xmm1 + +.byte 102,65,15,56,223,210 + movdqu 96(%rdi),%xmm10 + pxor %xmm0,%xmm1 +.byte 102,65,15,56,223,219 + pxor %xmm0,%xmm10 + movdqu 112(%rdi),%xmm0 +.byte 102,65,15,56,223,228 + leaq 128(%rdi),%rdi + movdqu 0(%rbp),%xmm11 +.byte 102,65,15,56,223,237 +.byte 102,65,15,56,223,246 + movdqu 16(%rbp),%xmm12 + movdqu 32(%rbp),%xmm13 +.byte 102,65,15,56,223,255 +.byte 102,68,15,56,223,193 + movdqu 48(%rbp),%xmm14 + movdqu 64(%rbp),%xmm15 +.byte 102,69,15,56,223,202 + movdqa %xmm0,%xmm10 + movdqu 80(%rbp),%xmm1 + movups -112(%rcx),%xmm0 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm1,%xmm7 + movups %xmm8,96(%rsi) + leaq 112(%rsi),%rsi + + subq $0x80,%rdx + ja .Lcbc_dec_loop8 + + movaps %xmm9,%xmm2 + leaq -112(%rcx),%rcx + addq $0x70,%rdx + jle .Lcbc_dec_clear_tail_collected + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi + cmpq $0x50,%rdx + jbe .Lcbc_dec_tail + + movaps %xmm11,%xmm2 +.Lcbc_dec_six_or_seven: + cmpq $0x60,%rdx + ja .Lcbc_dec_seven + + movaps %xmm7,%xmm8 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + leaq 80(%rsi),%rsi + movdqa %xmm7,%xmm2 + pxor %xmm7,%xmm7 + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_seven: + movups 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups 80(%rdi),%xmm9 + pxor %xmm10,%xmm2 + movups 96(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm9,%xmm8 + movdqu %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + leaq 96(%rsi),%rsi + movdqa %xmm8,%xmm2 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_loop6: + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 +.Lcbc_dec_loop6_enter: + leaq 96(%rdi),%rdi + movdqa %xmm7,%xmm8 + + call _aesni_decrypt6 + + pxor %xmm10,%xmm2 + movdqa %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm14,%xmm6 + movq %rbp,%rcx + movdqu %xmm5,48(%rsi) + pxor %xmm15,%xmm7 + movl %r10d,%eax + movdqu %xmm6,64(%rsi) + leaq 80(%rsi),%rsi + subq $0x60,%rdx + ja .Lcbc_dec_loop6 + + movdqa %xmm7,%xmm2 + addq $0x50,%rdx + jle .Lcbc_dec_clear_tail_collected + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + +.Lcbc_dec_tail: + movups (%rdi),%xmm2 + subq $0x10,%rdx + jbe .Lcbc_dec_one + + movups 16(%rdi),%xmm3 + movaps %xmm2,%xmm11 + subq $0x10,%rdx + jbe .Lcbc_dec_two + + movups 32(%rdi),%xmm4 + movaps %xmm3,%xmm12 + subq $0x10,%rdx + jbe .Lcbc_dec_three + + movups 48(%rdi),%xmm5 + movaps %xmm4,%xmm13 + subq $0x10,%rdx + jbe .Lcbc_dec_four + + movups 64(%rdi),%xmm6 + movaps %xmm5,%xmm14 + movaps %xmm6,%xmm15 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm15,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + leaq 64(%rsi),%rsi + movdqa %xmm6,%xmm2 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + subq $0x10,%rdx + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_one: + movaps %xmm2,%xmm11 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_8: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_8 +.byte 102,15,56,223,209 + xorps %xmm10,%xmm2 + movaps %xmm11,%xmm10 + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_two: + movaps %xmm3,%xmm12 + call _aesni_decrypt2 + pxor %xmm10,%xmm2 + movaps %xmm12,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + movdqa %xmm3,%xmm2 + pxor %xmm3,%xmm3 + leaq 16(%rsi),%rsi + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_three: + movaps %xmm4,%xmm13 + call _aesni_decrypt3 + pxor %xmm10,%xmm2 + movaps %xmm13,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movdqa %xmm4,%xmm2 + pxor %xmm4,%xmm4 + leaq 32(%rsi),%rsi + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_four: + movaps %xmm5,%xmm14 + call _aesni_decrypt4 + pxor %xmm10,%xmm2 + movaps %xmm14,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movdqa %xmm5,%xmm2 + pxor %xmm5,%xmm5 + leaq 48(%rsi),%rsi + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_clear_tail_collected: + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 +.Lcbc_dec_tail_collected: + movups %xmm10,(%r8) + andq $15,%rdx + jnz .Lcbc_dec_tail_partial + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lcbc_dec_ret +.align 16 +.Lcbc_dec_tail_partial: + movaps %xmm2,(%rsp) + pxor %xmm2,%xmm2 + movq $16,%rcx + movq %rsi,%rdi + subq %rdx,%rcx + leaq (%rsp),%rsi +.long 0x9066A4F3 + movdqa %xmm2,(%rsp) + +.Lcbc_dec_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lcbc_ret: + .byte 0xf3,0xc3 +.cfi_endproc +.size aes_hw_cbc_encrypt,.-aes_hw_cbc_encrypt +.globl aes_hw_set_decrypt_key +.hidden aes_hw_set_decrypt_key +.type aes_hw_set_decrypt_key,@function +.align 16 +aes_hw_set_decrypt_key: +.cfi_startproc +.byte 0x48,0x83,0xEC,0x08 +.cfi_adjust_cfa_offset 8 + call __aesni_set_encrypt_key + shll $4,%esi + testl %eax,%eax + jnz .Ldec_key_ret + leaq 16(%rdx,%rsi,1),%rdi + + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 + movups %xmm0,(%rdi) + movups %xmm1,(%rdx) + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + +.Ldec_key_inverse: + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 +.byte 102,15,56,219,192 +.byte 102,15,56,219,201 + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + movups %xmm0,16(%rdi) + movups %xmm1,-16(%rdx) + cmpq %rdx,%rdi + ja .Ldec_key_inverse + + movups (%rdx),%xmm0 +.byte 102,15,56,219,192 + pxor %xmm1,%xmm1 + movups %xmm0,(%rdi) + pxor %xmm0,%xmm0 +.Ldec_key_ret: + addq $8,%rsp +.cfi_adjust_cfa_offset -8 + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_set_decrypt_key: +.size aes_hw_set_decrypt_key,.-aes_hw_set_decrypt_key +.globl aes_hw_set_encrypt_key +.hidden aes_hw_set_encrypt_key +.type aes_hw_set_encrypt_key,@function +.align 16 +aes_hw_set_encrypt_key: +__aesni_set_encrypt_key: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST + movb $1,BORINGSSL_function_hit+3(%rip) +#endif +.byte 0x48,0x83,0xEC,0x08 +.cfi_adjust_cfa_offset 8 + movq $-1,%rax + testq %rdi,%rdi + jz .Lenc_key_ret + testq %rdx,%rdx + jz .Lenc_key_ret + + movups (%rdi),%xmm0 + xorps %xmm4,%xmm4 + leaq OPENSSL_ia32cap_P(%rip),%r10 + movl 4(%r10),%r10d + andl $268437504,%r10d + leaq 16(%rdx),%rax + cmpl $256,%esi + je .L14rounds + cmpl $192,%esi + je .L12rounds + cmpl $128,%esi + jne .Lbad_keybits + +.L10rounds: + movl $9,%esi + cmpl $268435456,%r10d + je .L10rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,200,1 + call .Lkey_expansion_128_cold +.byte 102,15,58,223,200,2 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,4 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,8 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,16 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,32 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,64 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,128 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,27 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,54 + call .Lkey_expansion_128 + movups %xmm0,(%rax) + movl %esi,80(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L10rounds_alt: + movdqa .Lkey_rotate(%rip),%xmm5 + movl $8,%r10d + movdqa .Lkey_rcon1(%rip),%xmm4 + movdqa %xmm0,%xmm2 + movdqu %xmm0,(%rdx) + jmp .Loop_key128 + +.align 16 +.Loop_key128: +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + leaq 16(%rax),%rax + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,-16(%rax) + movdqa %xmm0,%xmm2 + + decl %r10d + jnz .Loop_key128 + + movdqa .Lkey_rcon1b(%rip),%xmm4 + +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + movdqa %xmm0,%xmm2 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,16(%rax) + + movl %esi,96(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L12rounds: + movq 16(%rdi),%xmm2 + movl $11,%esi + cmpl $268435456,%r10d + je .L12rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,202,1 + call .Lkey_expansion_192a_cold +.byte 102,15,58,223,202,2 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,4 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,8 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,16 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,32 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,64 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,128 + call .Lkey_expansion_192b + movups %xmm0,(%rax) + movl %esi,48(%rax) + xorq %rax,%rax + jmp .Lenc_key_ret + +.align 16 +.L12rounds_alt: + movdqa .Lkey_rotate192(%rip),%xmm5 + movdqa .Lkey_rcon1(%rip),%xmm4 + movl $8,%r10d + movdqu %xmm0,(%rdx) + jmp .Loop_key192 + +.align 16 +.Loop_key192: + movq %xmm2,0(%rax) + movdqa %xmm2,%xmm1 +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + pslld $1,%xmm4 + leaq 24(%rax),%rax + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + + pshufd $0xff,%xmm0,%xmm3 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + + pxor %xmm2,%xmm0 + pxor %xmm3,%xmm2 + movdqu %xmm0,-16(%rax) + + decl %r10d + jnz .Loop_key192 + + movl %esi,32(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L14rounds: + movups 16(%rdi),%xmm2 + movl $13,%esi + leaq 16(%rax),%rax + cmpl $268435456,%r10d + je .L14rounds_alt + + movups %xmm0,(%rdx) + movups %xmm2,16(%rdx) +.byte 102,15,58,223,202,1 + call .Lkey_expansion_256a_cold +.byte 102,15,58,223,200,1 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,2 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,2 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,4 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,4 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,8 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,8 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,16 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,16 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,32 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,32 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,64 + call .Lkey_expansion_256a + movups %xmm0,(%rax) + movl %esi,16(%rax) + xorq %rax,%rax + jmp .Lenc_key_ret + +.align 16 +.L14rounds_alt: + movdqa .Lkey_rotate(%rip),%xmm5 + movdqa .Lkey_rcon1(%rip),%xmm4 + movl $7,%r10d + movdqu %xmm0,0(%rdx) + movdqa %xmm2,%xmm1 + movdqu %xmm2,16(%rdx) + jmp .Loop_key256 + +.align 16 +.Loop_key256: +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pslld $1,%xmm4 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + decl %r10d + jz .Ldone_key256 + + pshufd $0xff,%xmm0,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,221,211 + + movdqa %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm3,%xmm1 + + pxor %xmm1,%xmm2 + movdqu %xmm2,16(%rax) + leaq 32(%rax),%rax + movdqa %xmm2,%xmm1 + + jmp .Loop_key256 + +.Ldone_key256: + movl %esi,16(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.Lbad_keybits: + movq $-2,%rax +.Lenc_key_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + addq $8,%rsp +.cfi_adjust_cfa_offset -8 + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_set_encrypt_key: + +.align 16 +.Lkey_expansion_128: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_128_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_192a: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_192a_cold: + movaps %xmm2,%xmm5 +.Lkey_expansion_192b_warm: + shufps $16,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + pslldq $4,%xmm3 + xorps %xmm4,%xmm0 + pshufd $85,%xmm1,%xmm1 + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_192b: + movaps %xmm0,%xmm3 + shufps $68,%xmm0,%xmm5 + movups %xmm5,(%rax) + shufps $78,%xmm2,%xmm3 + movups %xmm3,16(%rax) + leaq 32(%rax),%rax + jmp .Lkey_expansion_192b_warm + +.align 16 +.Lkey_expansion_256a: + movups %xmm2,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_256a_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_256b: + movups %xmm0,(%rax) + leaq 16(%rax),%rax + + shufps $16,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $140,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $170,%xmm1,%xmm1 + xorps %xmm1,%xmm2 + .byte 0xf3,0xc3 +.size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key +.size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.Lincrement32: +.long 6,6,6,0 +.Lincrement64: +.long 1,0,0,0 +.Lxts_magic: +.long 0x87,0,1,0 +.Lincrement1: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +.Lkey_rotate: +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d +.Lkey_rotate192: +.long 0x04070605,0x04070605,0x04070605,0x04070605 +.Lkey_rcon1: +.long 1,1,1,1 +.Lkey_rcon1b: +.long 0x1b,0x1b,0x1b,0x1b + +.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S new file mode 100644 index 00000000..47416344 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S @@ -0,0 +1,2510 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.globl _aes_hw_encrypt +.private_extern _aes_hw_encrypt + +.p2align 4 +_aes_hw_encrypt: + +#ifdef BORINGSSL_DISPATCH_TEST + + movb $1,_BORINGSSL_function_hit+1(%rip) +#endif + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +L$oop_enc1_1: +.byte 102,15,56,220,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz L$oop_enc1_1 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 + + + +.globl _aes_hw_decrypt +.private_extern _aes_hw_decrypt + +.p2align 4 +_aes_hw_decrypt: + + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +L$oop_dec1_2: +.byte 102,15,56,222,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz L$oop_dec1_2 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_encrypt2: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +L$enc_loop2: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$enc_loop2 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_decrypt2: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +L$dec_loop2: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$dec_loop2 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_encrypt3: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +L$enc_loop3: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$enc_loop3 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_decrypt3: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +L$dec_loop3: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$dec_loop3 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_encrypt4: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +L$enc_loop4: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$enc_loop4 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_decrypt4: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +L$dec_loop4: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$dec_loop4 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_encrypt6: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,220,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,220,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp L$enc_loop6_enter +.p2align 4 +L$enc_loop6: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +L$enc_loop6_enter: +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$enc_loop6 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_decrypt6: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,222,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,222,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp L$dec_loop6_enter +.p2align 4 +L$dec_loop6: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +L$dec_loop6_enter: +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$dec_loop6 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_encrypt8: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,220,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp L$enc_loop8_inner +.p2align 4 +L$enc_loop8: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +L$enc_loop8_inner: +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +L$enc_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$enc_loop8 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 +.byte 102,68,15,56,221,192 +.byte 102,68,15,56,221,200 + .byte 0xf3,0xc3 + + + +.p2align 4 +_aesni_decrypt8: + + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp L$dec_loop8_inner +.p2align 4 +L$dec_loop8: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +L$dec_loop8_inner: +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +L$dec_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz L$dec_loop8 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 +.byte 102,68,15,56,223,192 +.byte 102,68,15,56,223,200 + .byte 0xf3,0xc3 + + +.globl _aes_hw_ecb_encrypt +.private_extern _aes_hw_ecb_encrypt + +.p2align 4 +_aes_hw_ecb_encrypt: + + andq $-16,%rdx + jz L$ecb_ret + + movl 240(%rcx),%eax + movups (%rcx),%xmm0 + movq %rcx,%r11 + movl %eax,%r10d + testl %r8d,%r8d + jz L$ecb_decrypt + + cmpq $0x80,%rdx + jb L$ecb_enc_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp L$ecb_enc_loop8_enter +.p2align 4 +L$ecb_enc_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +L$ecb_enc_loop8_enter: + + call _aesni_encrypt8 + + subq $0x80,%rdx + jnc L$ecb_enc_loop8 + + movups %xmm2,(%rsi) + movq %r11,%rcx + movups %xmm3,16(%rsi) + movl %r10d,%eax + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz L$ecb_ret + +L$ecb_enc_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb L$ecb_enc_one + movups 16(%rdi),%xmm3 + je L$ecb_enc_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb L$ecb_enc_three + movups 48(%rdi),%xmm5 + je L$ecb_enc_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb L$ecb_enc_five + movups 80(%rdi),%xmm7 + je L$ecb_enc_six + movdqu 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_encrypt8 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +L$oop_enc1_3: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_enc1_3 +.byte 102,15,56,221,209 + movups %xmm2,(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_two: + call _aesni_encrypt2 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_three: + call _aesni_encrypt3 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_four: + call _aesni_encrypt4 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_five: + xorps %xmm7,%xmm7 + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + jmp L$ecb_ret +.p2align 4 +L$ecb_enc_six: + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + jmp L$ecb_ret + +.p2align 4 +L$ecb_decrypt: + cmpq $0x80,%rdx + jb L$ecb_dec_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp L$ecb_dec_loop8_enter +.p2align 4 +L$ecb_dec_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +L$ecb_dec_loop8_enter: + + call _aesni_decrypt8 + + movups (%r11),%xmm0 + subq $0x80,%rdx + jnc L$ecb_dec_loop8 + + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movq %r11,%rcx + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movl %r10d,%eax + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + movups %xmm9,112(%rsi) + pxor %xmm9,%xmm9 + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz L$ecb_ret + +L$ecb_dec_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb L$ecb_dec_one + movups 16(%rdi),%xmm3 + je L$ecb_dec_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb L$ecb_dec_three + movups 48(%rdi),%xmm5 + je L$ecb_dec_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb L$ecb_dec_five + movups 80(%rdi),%xmm7 + je L$ecb_dec_six + movups 96(%rdi),%xmm8 + movups (%rcx),%xmm0 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +L$oop_dec1_4: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_dec1_4 +.byte 102,15,56,223,209 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_two: + call _aesni_decrypt2 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_three: + call _aesni_decrypt3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_four: + call _aesni_decrypt4 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_five: + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + jmp L$ecb_ret +.p2align 4 +L$ecb_dec_six: + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + +L$ecb_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + .byte 0xf3,0xc3 + + +.globl _aes_hw_ctr32_encrypt_blocks +.private_extern _aes_hw_ctr32_encrypt_blocks + +.p2align 4 +_aes_hw_ctr32_encrypt_blocks: + +#ifdef BORINGSSL_DISPATCH_TEST + movb $1,_BORINGSSL_function_hit(%rip) +#endif + cmpq $1,%rdx + jne L$ctr32_bulk + + + + movups (%r8),%xmm2 + movups (%rdi),%xmm3 + movl 240(%rcx),%edx + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +L$oop_enc1_5: +.byte 102,15,56,220,209 + decl %edx + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_enc1_5 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + xorps %xmm2,%xmm2 + jmp L$ctr32_epilogue + +.p2align 4 +L$ctr32_bulk: + leaq (%rsp),%r11 + + pushq %rbp + + subq $128,%rsp + andq $-16,%rsp + + + + + movdqu (%r8),%xmm2 + movdqu (%rcx),%xmm0 + movl 12(%r8),%r8d + pxor %xmm0,%xmm2 + movl 12(%rcx),%ebp + movdqa %xmm2,0(%rsp) + bswapl %r8d + movdqa %xmm2,%xmm3 + movdqa %xmm2,%xmm4 + movdqa %xmm2,%xmm5 + movdqa %xmm2,64(%rsp) + movdqa %xmm2,80(%rsp) + movdqa %xmm2,96(%rsp) + movq %rdx,%r10 + movdqa %xmm2,112(%rsp) + + leaq 1(%r8),%rax + leaq 2(%r8),%rdx + bswapl %eax + bswapl %edx + xorl %ebp,%eax + xorl %ebp,%edx +.byte 102,15,58,34,216,3 + leaq 3(%r8),%rax + movdqa %xmm3,16(%rsp) +.byte 102,15,58,34,226,3 + bswapl %eax + movq %r10,%rdx + leaq 4(%r8),%r10 + movdqa %xmm4,32(%rsp) + xorl %ebp,%eax + bswapl %r10d +.byte 102,15,58,34,232,3 + xorl %ebp,%r10d + movdqa %xmm5,48(%rsp) + leaq 5(%r8),%r9 + movl %r10d,64+12(%rsp) + bswapl %r9d + leaq 6(%r8),%r10 + movl 240(%rcx),%eax + xorl %ebp,%r9d + bswapl %r10d + movl %r9d,80+12(%rsp) + xorl %ebp,%r10d + leaq 7(%r8),%r9 + movl %r10d,96+12(%rsp) + bswapl %r9d + leaq _OPENSSL_ia32cap_P(%rip),%r10 + movl 4(%r10),%r10d + xorl %ebp,%r9d + andl $71303168,%r10d + movl %r9d,112+12(%rsp) + + movups 16(%rcx),%xmm1 + + movdqa 64(%rsp),%xmm6 + movdqa 80(%rsp),%xmm7 + + cmpq $8,%rdx + jb L$ctr32_tail + + subq $6,%rdx + cmpl $4194304,%r10d + je L$ctr32_6x + + leaq 128(%rcx),%rcx + subq $2,%rdx + jmp L$ctr32_loop8 + +.p2align 4 +L$ctr32_6x: + shll $4,%eax + movl $48,%r10d + bswapl %ebp + leaq 32(%rcx,%rax,1),%rcx + subq %rax,%r10 + jmp L$ctr32_loop6 + +.p2align 4 +L$ctr32_loop6: + addl $6,%r8d + movups -48(%rcx,%r10,1),%xmm0 +.byte 102,15,56,220,209 + movl %r8d,%eax + xorl %ebp,%eax +.byte 102,15,56,220,217 +.byte 0x0f,0x38,0xf1,0x44,0x24,12 + leal 1(%r8),%eax +.byte 102,15,56,220,225 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,28 +.byte 102,15,56,220,233 + leal 2(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,241 +.byte 0x0f,0x38,0xf1,0x44,0x24,44 + leal 3(%r8),%eax +.byte 102,15,56,220,249 + movups -32(%rcx,%r10,1),%xmm1 + xorl %ebp,%eax + +.byte 102,15,56,220,208 +.byte 0x0f,0x38,0xf1,0x44,0x24,60 + leal 4(%r8),%eax +.byte 102,15,56,220,216 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,76 +.byte 102,15,56,220,224 + leal 5(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,232 +.byte 0x0f,0x38,0xf1,0x44,0x24,92 + movq %r10,%rax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%r10,1),%xmm0 + + call L$enc_loop6 + + movdqu (%rdi),%xmm8 + movdqu 16(%rdi),%xmm9 + movdqu 32(%rdi),%xmm10 + movdqu 48(%rdi),%xmm11 + movdqu 64(%rdi),%xmm12 + movdqu 80(%rdi),%xmm13 + leaq 96(%rdi),%rdi + movups -64(%rcx,%r10,1),%xmm1 + pxor %xmm2,%xmm8 + movaps 0(%rsp),%xmm2 + pxor %xmm3,%xmm9 + movaps 16(%rsp),%xmm3 + pxor %xmm4,%xmm10 + movaps 32(%rsp),%xmm4 + pxor %xmm5,%xmm11 + movaps 48(%rsp),%xmm5 + pxor %xmm6,%xmm12 + movaps 64(%rsp),%xmm6 + pxor %xmm7,%xmm13 + movaps 80(%rsp),%xmm7 + movdqu %xmm8,(%rsi) + movdqu %xmm9,16(%rsi) + movdqu %xmm10,32(%rsi) + movdqu %xmm11,48(%rsi) + movdqu %xmm12,64(%rsi) + movdqu %xmm13,80(%rsi) + leaq 96(%rsi),%rsi + + subq $6,%rdx + jnc L$ctr32_loop6 + + addq $6,%rdx + jz L$ctr32_done + + leal -48(%r10),%eax + leaq -80(%rcx,%r10,1),%rcx + negl %eax + shrl $4,%eax + jmp L$ctr32_tail + +.p2align 5 +L$ctr32_loop8: + addl $8,%r8d + movdqa 96(%rsp),%xmm8 +.byte 102,15,56,220,209 + movl %r8d,%r9d + movdqa 112(%rsp),%xmm9 +.byte 102,15,56,220,217 + bswapl %r9d + movups 32-128(%rcx),%xmm0 +.byte 102,15,56,220,225 + xorl %ebp,%r9d + nop +.byte 102,15,56,220,233 + movl %r9d,0+12(%rsp) + leaq 1(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 48-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,16+12(%rsp) + leaq 2(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 64-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,32+12(%rsp) + leaq 3(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 80-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,48+12(%rsp) + leaq 4(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 96-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,64+12(%rsp) + leaq 5(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 112-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,80+12(%rsp) + leaq 6(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 128-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,96+12(%rsp) + leaq 7(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 144-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + xorl %ebp,%r9d + movdqu 0(%rdi),%xmm10 +.byte 102,15,56,220,232 + movl %r9d,112+12(%rsp) + cmpl $11,%eax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 160-128(%rcx),%xmm0 + + jb L$ctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 176-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 192-128(%rcx),%xmm0 + je L$ctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 208-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 224-128(%rcx),%xmm0 + jmp L$ctr32_enc_done + +.p2align 4 +L$ctr32_enc_done: + movdqu 16(%rdi),%xmm11 + pxor %xmm0,%xmm10 + movdqu 32(%rdi),%xmm12 + pxor %xmm0,%xmm11 + movdqu 48(%rdi),%xmm13 + pxor %xmm0,%xmm12 + movdqu 64(%rdi),%xmm14 + pxor %xmm0,%xmm13 + movdqu 80(%rdi),%xmm15 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movdqu 96(%rdi),%xmm1 + leaq 128(%rdi),%rdi + +.byte 102,65,15,56,221,210 + pxor %xmm0,%xmm1 + movdqu 112-128(%rdi),%xmm10 +.byte 102,65,15,56,221,219 + pxor %xmm0,%xmm10 + movdqa 0(%rsp),%xmm11 +.byte 102,65,15,56,221,228 +.byte 102,65,15,56,221,237 + movdqa 16(%rsp),%xmm12 + movdqa 32(%rsp),%xmm13 +.byte 102,65,15,56,221,246 +.byte 102,65,15,56,221,255 + movdqa 48(%rsp),%xmm14 + movdqa 64(%rsp),%xmm15 +.byte 102,68,15,56,221,193 + movdqa 80(%rsp),%xmm0 + movups 16-128(%rcx),%xmm1 +.byte 102,69,15,56,221,202 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm0,%xmm7 + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + + subq $8,%rdx + jnc L$ctr32_loop8 + + addq $8,%rdx + jz L$ctr32_done + leaq -128(%rcx),%rcx + +L$ctr32_tail: + + + leaq 16(%rcx),%rcx + cmpq $4,%rdx + jb L$ctr32_loop3 + je L$ctr32_loop4 + + + shll $4,%eax + movdqa 96(%rsp),%xmm8 + pxor %xmm9,%xmm9 + + movups 16(%rcx),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + leaq 32-16(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,225 + addq $16,%rax + movups (%rdi),%xmm10 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 + movups 16(%rdi),%xmm11 + movups 32(%rdi),%xmm12 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 + + call L$enc_loop8_enter + + movdqu 48(%rdi),%xmm13 + pxor %xmm10,%xmm2 + movdqu 64(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm10,%xmm6 + movdqu %xmm5,48(%rsi) + movdqu %xmm6,64(%rsi) + cmpq $6,%rdx + jb L$ctr32_done + + movups 80(%rdi),%xmm11 + xorps %xmm11,%xmm7 + movups %xmm7,80(%rsi) + je L$ctr32_done + + movups 96(%rdi),%xmm12 + xorps %xmm12,%xmm8 + movups %xmm8,96(%rsi) + jmp L$ctr32_done + +.p2align 5 +L$ctr32_loop4: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx),%xmm1 + jnz L$ctr32_loop4 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 + movups (%rdi),%xmm10 + movups 16(%rdi),%xmm11 +.byte 102,15,56,221,225 +.byte 102,15,56,221,233 + movups 32(%rdi),%xmm12 + movups 48(%rdi),%xmm13 + + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm4,32(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm5,48(%rsi) + jmp L$ctr32_done + +.p2align 5 +L$ctr32_loop3: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx),%xmm1 + jnz L$ctr32_loop3 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 +.byte 102,15,56,221,225 + + movups (%rdi),%xmm10 + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + cmpq $2,%rdx + jb L$ctr32_done + + movups 16(%rdi),%xmm11 + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + je L$ctr32_done + + movups 32(%rdi),%xmm12 + xorps %xmm12,%xmm4 + movups %xmm4,32(%rsi) + +L$ctr32_done: + xorps %xmm0,%xmm0 + xorl %ebp,%ebp + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + movaps %xmm0,0(%rsp) + pxor %xmm8,%xmm8 + movaps %xmm0,16(%rsp) + pxor %xmm9,%xmm9 + movaps %xmm0,32(%rsp) + pxor %xmm10,%xmm10 + movaps %xmm0,48(%rsp) + pxor %xmm11,%xmm11 + movaps %xmm0,64(%rsp) + pxor %xmm12,%xmm12 + movaps %xmm0,80(%rsp) + pxor %xmm13,%xmm13 + movaps %xmm0,96(%rsp) + pxor %xmm14,%xmm14 + movaps %xmm0,112(%rsp) + pxor %xmm15,%xmm15 + movq -8(%r11),%rbp + + leaq (%r11),%rsp + +L$ctr32_epilogue: + .byte 0xf3,0xc3 + + +.globl _aes_hw_cbc_encrypt +.private_extern _aes_hw_cbc_encrypt + +.p2align 4 +_aes_hw_cbc_encrypt: + + testq %rdx,%rdx + jz L$cbc_ret + + movl 240(%rcx),%r10d + movq %rcx,%r11 + testl %r9d,%r9d + jz L$cbc_decrypt + + movups (%r8),%xmm2 + movl %r10d,%eax + cmpq $16,%rdx + jb L$cbc_enc_tail + subq $16,%rdx + jmp L$cbc_enc_loop +.p2align 4 +L$cbc_enc_loop: + movups (%rdi),%xmm3 + leaq 16(%rdi),%rdi + + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm3 + leaq 32(%rcx),%rcx + xorps %xmm3,%xmm2 +L$oop_enc1_6: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_enc1_6 +.byte 102,15,56,221,209 + movl %r10d,%eax + movq %r11,%rcx + movups %xmm2,0(%rsi) + leaq 16(%rsi),%rsi + subq $16,%rdx + jnc L$cbc_enc_loop + addq $16,%rdx + jnz L$cbc_enc_tail + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%r8) + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + jmp L$cbc_ret + +L$cbc_enc_tail: + movq %rdx,%rcx + xchgq %rdi,%rsi +.long 0x9066A4F3 + movl $16,%ecx + subq %rdx,%rcx + xorl %eax,%eax +.long 0x9066AAF3 + leaq -16(%rdi),%rdi + movl %r10d,%eax + movq %rdi,%rsi + movq %r11,%rcx + xorq %rdx,%rdx + jmp L$cbc_enc_loop + +.p2align 4 +L$cbc_decrypt: + cmpq $16,%rdx + jne L$cbc_decrypt_bulk + + + + movdqu (%rdi),%xmm2 + movdqu (%r8),%xmm3 + movdqa %xmm2,%xmm4 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +L$oop_dec1_7: +.byte 102,15,56,222,209 + decl %r10d + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_dec1_7 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movdqu %xmm4,(%r8) + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp L$cbc_ret +.p2align 4 +L$cbc_decrypt_bulk: + leaq (%rsp),%r11 + + pushq %rbp + + subq $16,%rsp + andq $-16,%rsp + movq %rcx,%rbp + movups (%r8),%xmm10 + movl %r10d,%eax + cmpq $0x50,%rdx + jbe L$cbc_dec_tail + + movups (%rcx),%xmm0 + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 + leaq _OPENSSL_ia32cap_P(%rip),%r9 + movl 4(%r9),%r9d + cmpq $0x70,%rdx + jbe L$cbc_dec_six_or_seven + + andl $71303168,%r9d + subq $0x50,%rdx + cmpl $4194304,%r9d + je L$cbc_dec_loop6_enter + subq $0x20,%rdx + leaq 112(%rcx),%rcx + jmp L$cbc_dec_loop8_enter +.p2align 4 +L$cbc_dec_loop8: + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi +L$cbc_dec_loop8_enter: + movdqu 96(%rdi),%xmm8 + pxor %xmm0,%xmm2 + movdqu 112(%rdi),%xmm9 + pxor %xmm0,%xmm3 + movups 16-112(%rcx),%xmm1 + pxor %xmm0,%xmm4 + movq $-1,%rbp + cmpq $0x70,%rdx + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 + +.byte 102,15,56,222,209 + pxor %xmm0,%xmm9 + movups 32-112(%rcx),%xmm0 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 + adcq $0,%rbp + andq $128,%rbp +.byte 102,68,15,56,222,201 + addq %rdi,%rbp + movups 48-112(%rcx),%xmm1 +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 64-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 80-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 96-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 112-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 128-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 144-112(%rcx),%xmm1 + cmpl $11,%eax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 160-112(%rcx),%xmm0 + jb L$cbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 176-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 192-112(%rcx),%xmm0 + je L$cbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 208-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 224-112(%rcx),%xmm0 + jmp L$cbc_dec_done +.p2align 4 +L$cbc_dec_done: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm10 + pxor %xmm0,%xmm11 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + pxor %xmm0,%xmm12 + pxor %xmm0,%xmm13 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movdqu 80(%rdi),%xmm1 + +.byte 102,65,15,56,223,210 + movdqu 96(%rdi),%xmm10 + pxor %xmm0,%xmm1 +.byte 102,65,15,56,223,219 + pxor %xmm0,%xmm10 + movdqu 112(%rdi),%xmm0 +.byte 102,65,15,56,223,228 + leaq 128(%rdi),%rdi + movdqu 0(%rbp),%xmm11 +.byte 102,65,15,56,223,237 +.byte 102,65,15,56,223,246 + movdqu 16(%rbp),%xmm12 + movdqu 32(%rbp),%xmm13 +.byte 102,65,15,56,223,255 +.byte 102,68,15,56,223,193 + movdqu 48(%rbp),%xmm14 + movdqu 64(%rbp),%xmm15 +.byte 102,69,15,56,223,202 + movdqa %xmm0,%xmm10 + movdqu 80(%rbp),%xmm1 + movups -112(%rcx),%xmm0 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm1,%xmm7 + movups %xmm8,96(%rsi) + leaq 112(%rsi),%rsi + + subq $0x80,%rdx + ja L$cbc_dec_loop8 + + movaps %xmm9,%xmm2 + leaq -112(%rcx),%rcx + addq $0x70,%rdx + jle L$cbc_dec_clear_tail_collected + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi + cmpq $0x50,%rdx + jbe L$cbc_dec_tail + + movaps %xmm11,%xmm2 +L$cbc_dec_six_or_seven: + cmpq $0x60,%rdx + ja L$cbc_dec_seven + + movaps %xmm7,%xmm8 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + leaq 80(%rsi),%rsi + movdqa %xmm7,%xmm2 + pxor %xmm7,%xmm7 + jmp L$cbc_dec_tail_collected + +.p2align 4 +L$cbc_dec_seven: + movups 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups 80(%rdi),%xmm9 + pxor %xmm10,%xmm2 + movups 96(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm9,%xmm8 + movdqu %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + leaq 96(%rsi),%rsi + movdqa %xmm8,%xmm2 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp L$cbc_dec_tail_collected + +.p2align 4 +L$cbc_dec_loop6: + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 +L$cbc_dec_loop6_enter: + leaq 96(%rdi),%rdi + movdqa %xmm7,%xmm8 + + call _aesni_decrypt6 + + pxor %xmm10,%xmm2 + movdqa %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm14,%xmm6 + movq %rbp,%rcx + movdqu %xmm5,48(%rsi) + pxor %xmm15,%xmm7 + movl %r10d,%eax + movdqu %xmm6,64(%rsi) + leaq 80(%rsi),%rsi + subq $0x60,%rdx + ja L$cbc_dec_loop6 + + movdqa %xmm7,%xmm2 + addq $0x50,%rdx + jle L$cbc_dec_clear_tail_collected + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + +L$cbc_dec_tail: + movups (%rdi),%xmm2 + subq $0x10,%rdx + jbe L$cbc_dec_one + + movups 16(%rdi),%xmm3 + movaps %xmm2,%xmm11 + subq $0x10,%rdx + jbe L$cbc_dec_two + + movups 32(%rdi),%xmm4 + movaps %xmm3,%xmm12 + subq $0x10,%rdx + jbe L$cbc_dec_three + + movups 48(%rdi),%xmm5 + movaps %xmm4,%xmm13 + subq $0x10,%rdx + jbe L$cbc_dec_four + + movups 64(%rdi),%xmm6 + movaps %xmm5,%xmm14 + movaps %xmm6,%xmm15 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm15,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + leaq 64(%rsi),%rsi + movdqa %xmm6,%xmm2 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + subq $0x10,%rdx + jmp L$cbc_dec_tail_collected + +.p2align 4 +L$cbc_dec_one: + movaps %xmm2,%xmm11 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +L$oop_dec1_8: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz L$oop_dec1_8 +.byte 102,15,56,223,209 + xorps %xmm10,%xmm2 + movaps %xmm11,%xmm10 + jmp L$cbc_dec_tail_collected +.p2align 4 +L$cbc_dec_two: + movaps %xmm3,%xmm12 + call _aesni_decrypt2 + pxor %xmm10,%xmm2 + movaps %xmm12,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + movdqa %xmm3,%xmm2 + pxor %xmm3,%xmm3 + leaq 16(%rsi),%rsi + jmp L$cbc_dec_tail_collected +.p2align 4 +L$cbc_dec_three: + movaps %xmm4,%xmm13 + call _aesni_decrypt3 + pxor %xmm10,%xmm2 + movaps %xmm13,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movdqa %xmm4,%xmm2 + pxor %xmm4,%xmm4 + leaq 32(%rsi),%rsi + jmp L$cbc_dec_tail_collected +.p2align 4 +L$cbc_dec_four: + movaps %xmm5,%xmm14 + call _aesni_decrypt4 + pxor %xmm10,%xmm2 + movaps %xmm14,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movdqa %xmm5,%xmm2 + pxor %xmm5,%xmm5 + leaq 48(%rsi),%rsi + jmp L$cbc_dec_tail_collected + +.p2align 4 +L$cbc_dec_clear_tail_collected: + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 +L$cbc_dec_tail_collected: + movups %xmm10,(%r8) + andq $15,%rdx + jnz L$cbc_dec_tail_partial + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp L$cbc_dec_ret +.p2align 4 +L$cbc_dec_tail_partial: + movaps %xmm2,(%rsp) + pxor %xmm2,%xmm2 + movq $16,%rcx + movq %rsi,%rdi + subq %rdx,%rcx + leaq (%rsp),%rsi +.long 0x9066A4F3 + movdqa %xmm2,(%rsp) + +L$cbc_dec_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movq -8(%r11),%rbp + + leaq (%r11),%rsp + +L$cbc_ret: + .byte 0xf3,0xc3 + + +.globl _aes_hw_set_decrypt_key +.private_extern _aes_hw_set_decrypt_key + +.p2align 4 +_aes_hw_set_decrypt_key: + +.byte 0x48,0x83,0xEC,0x08 + + call __aesni_set_encrypt_key + shll $4,%esi + testl %eax,%eax + jnz L$dec_key_ret + leaq 16(%rdx,%rsi,1),%rdi + + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 + movups %xmm0,(%rdi) + movups %xmm1,(%rdx) + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + +L$dec_key_inverse: + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 +.byte 102,15,56,219,192 +.byte 102,15,56,219,201 + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + movups %xmm0,16(%rdi) + movups %xmm1,-16(%rdx) + cmpq %rdx,%rdi + ja L$dec_key_inverse + + movups (%rdx),%xmm0 +.byte 102,15,56,219,192 + pxor %xmm1,%xmm1 + movups %xmm0,(%rdi) + pxor %xmm0,%xmm0 +L$dec_key_ret: + addq $8,%rsp + + .byte 0xf3,0xc3 + +L$SEH_end_set_decrypt_key: + +.globl _aes_hw_set_encrypt_key +.private_extern _aes_hw_set_encrypt_key + +.p2align 4 +_aes_hw_set_encrypt_key: +__aesni_set_encrypt_key: + +#ifdef BORINGSSL_DISPATCH_TEST + movb $1,_BORINGSSL_function_hit+3(%rip) +#endif +.byte 0x48,0x83,0xEC,0x08 + + movq $-1,%rax + testq %rdi,%rdi + jz L$enc_key_ret + testq %rdx,%rdx + jz L$enc_key_ret + + movups (%rdi),%xmm0 + xorps %xmm4,%xmm4 + leaq _OPENSSL_ia32cap_P(%rip),%r10 + movl 4(%r10),%r10d + andl $268437504,%r10d + leaq 16(%rdx),%rax + cmpl $256,%esi + je L$14rounds + cmpl $192,%esi + je L$12rounds + cmpl $128,%esi + jne L$bad_keybits + +L$10rounds: + movl $9,%esi + cmpl $268435456,%r10d + je L$10rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,200,1 + call L$key_expansion_128_cold +.byte 102,15,58,223,200,2 + call L$key_expansion_128 +.byte 102,15,58,223,200,4 + call L$key_expansion_128 +.byte 102,15,58,223,200,8 + call L$key_expansion_128 +.byte 102,15,58,223,200,16 + call L$key_expansion_128 +.byte 102,15,58,223,200,32 + call L$key_expansion_128 +.byte 102,15,58,223,200,64 + call L$key_expansion_128 +.byte 102,15,58,223,200,128 + call L$key_expansion_128 +.byte 102,15,58,223,200,27 + call L$key_expansion_128 +.byte 102,15,58,223,200,54 + call L$key_expansion_128 + movups %xmm0,(%rax) + movl %esi,80(%rax) + xorl %eax,%eax + jmp L$enc_key_ret + +.p2align 4 +L$10rounds_alt: + movdqa L$key_rotate(%rip),%xmm5 + movl $8,%r10d + movdqa L$key_rcon1(%rip),%xmm4 + movdqa %xmm0,%xmm2 + movdqu %xmm0,(%rdx) + jmp L$oop_key128 + +.p2align 4 +L$oop_key128: +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + leaq 16(%rax),%rax + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,-16(%rax) + movdqa %xmm0,%xmm2 + + decl %r10d + jnz L$oop_key128 + + movdqa L$key_rcon1b(%rip),%xmm4 + +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + movdqa %xmm0,%xmm2 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,16(%rax) + + movl %esi,96(%rax) + xorl %eax,%eax + jmp L$enc_key_ret + +.p2align 4 +L$12rounds: + movq 16(%rdi),%xmm2 + movl $11,%esi + cmpl $268435456,%r10d + je L$12rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,202,1 + call L$key_expansion_192a_cold +.byte 102,15,58,223,202,2 + call L$key_expansion_192b +.byte 102,15,58,223,202,4 + call L$key_expansion_192a +.byte 102,15,58,223,202,8 + call L$key_expansion_192b +.byte 102,15,58,223,202,16 + call L$key_expansion_192a +.byte 102,15,58,223,202,32 + call L$key_expansion_192b +.byte 102,15,58,223,202,64 + call L$key_expansion_192a +.byte 102,15,58,223,202,128 + call L$key_expansion_192b + movups %xmm0,(%rax) + movl %esi,48(%rax) + xorq %rax,%rax + jmp L$enc_key_ret + +.p2align 4 +L$12rounds_alt: + movdqa L$key_rotate192(%rip),%xmm5 + movdqa L$key_rcon1(%rip),%xmm4 + movl $8,%r10d + movdqu %xmm0,(%rdx) + jmp L$oop_key192 + +.p2align 4 +L$oop_key192: + movq %xmm2,0(%rax) + movdqa %xmm2,%xmm1 +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + pslld $1,%xmm4 + leaq 24(%rax),%rax + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + + pshufd $0xff,%xmm0,%xmm3 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + + pxor %xmm2,%xmm0 + pxor %xmm3,%xmm2 + movdqu %xmm0,-16(%rax) + + decl %r10d + jnz L$oop_key192 + + movl %esi,32(%rax) + xorl %eax,%eax + jmp L$enc_key_ret + +.p2align 4 +L$14rounds: + movups 16(%rdi),%xmm2 + movl $13,%esi + leaq 16(%rax),%rax + cmpl $268435456,%r10d + je L$14rounds_alt + + movups %xmm0,(%rdx) + movups %xmm2,16(%rdx) +.byte 102,15,58,223,202,1 + call L$key_expansion_256a_cold +.byte 102,15,58,223,200,1 + call L$key_expansion_256b +.byte 102,15,58,223,202,2 + call L$key_expansion_256a +.byte 102,15,58,223,200,2 + call L$key_expansion_256b +.byte 102,15,58,223,202,4 + call L$key_expansion_256a +.byte 102,15,58,223,200,4 + call L$key_expansion_256b +.byte 102,15,58,223,202,8 + call L$key_expansion_256a +.byte 102,15,58,223,200,8 + call L$key_expansion_256b +.byte 102,15,58,223,202,16 + call L$key_expansion_256a +.byte 102,15,58,223,200,16 + call L$key_expansion_256b +.byte 102,15,58,223,202,32 + call L$key_expansion_256a +.byte 102,15,58,223,200,32 + call L$key_expansion_256b +.byte 102,15,58,223,202,64 + call L$key_expansion_256a + movups %xmm0,(%rax) + movl %esi,16(%rax) + xorq %rax,%rax + jmp L$enc_key_ret + +.p2align 4 +L$14rounds_alt: + movdqa L$key_rotate(%rip),%xmm5 + movdqa L$key_rcon1(%rip),%xmm4 + movl $7,%r10d + movdqu %xmm0,0(%rdx) + movdqa %xmm2,%xmm1 + movdqu %xmm2,16(%rdx) + jmp L$oop_key256 + +.p2align 4 +L$oop_key256: +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pslld $1,%xmm4 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + decl %r10d + jz L$done_key256 + + pshufd $0xff,%xmm0,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,221,211 + + movdqa %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm3,%xmm1 + + pxor %xmm1,%xmm2 + movdqu %xmm2,16(%rax) + leaq 32(%rax),%rax + movdqa %xmm2,%xmm1 + + jmp L$oop_key256 + +L$done_key256: + movl %esi,16(%rax) + xorl %eax,%eax + jmp L$enc_key_ret + +.p2align 4 +L$bad_keybits: + movq $-2,%rax +L$enc_key_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + addq $8,%rsp + + .byte 0xf3,0xc3 + +L$SEH_end_set_encrypt_key: + +.p2align 4 +L$key_expansion_128: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +L$key_expansion_128_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.p2align 4 +L$key_expansion_192a: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +L$key_expansion_192a_cold: + movaps %xmm2,%xmm5 +L$key_expansion_192b_warm: + shufps $16,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + pslldq $4,%xmm3 + xorps %xmm4,%xmm0 + pshufd $85,%xmm1,%xmm1 + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + .byte 0xf3,0xc3 + +.p2align 4 +L$key_expansion_192b: + movaps %xmm0,%xmm3 + shufps $68,%xmm0,%xmm5 + movups %xmm5,(%rax) + shufps $78,%xmm2,%xmm3 + movups %xmm3,16(%rax) + leaq 32(%rax),%rax + jmp L$key_expansion_192b_warm + +.p2align 4 +L$key_expansion_256a: + movups %xmm2,(%rax) + leaq 16(%rax),%rax +L$key_expansion_256a_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.p2align 4 +L$key_expansion_256b: + movups %xmm0,(%rax) + leaq 16(%rax),%rax + + shufps $16,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $140,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $170,%xmm1,%xmm1 + xorps %xmm1,%xmm2 + .byte 0xf3,0xc3 + + +.p2align 6 +L$bswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +L$increment32: +.long 6,6,6,0 +L$increment64: +.long 1,0,0,0 +L$xts_magic: +.long 0x87,0,1,0 +L$increment1: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +L$key_rotate: +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d +L$key_rotate192: +.long 0x04070605,0x04070605,0x04070605,0x04070605 +L$key_rcon1: +.long 1,1,1,1 +L$key_rcon1b: +.long 0x1b,0x1b,0x1b,0x1b + +.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S new file mode 100644 index 00000000..d56adf0e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S @@ -0,0 +1,816 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text + + +.code 32 +#undef __thumb2__ +.align 5 +Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d @ rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.text + +.globl _aes_hw_set_encrypt_key +.private_extern _aes_hw_set_encrypt_key +#ifdef __thumb2__ +.thumb_func _aes_hw_set_encrypt_key +#endif +.align 5 +_aes_hw_set_encrypt_key: +Lenc_key: + mov r3,#-1 + cmp r0,#0 + beq Lenc_key_abort + cmp r2,#0 + beq Lenc_key_abort + mov r3,#-2 + cmp r1,#128 + blt Lenc_key_abort + cmp r1,#256 + bgt Lenc_key_abort + tst r1,#0x3f + bne Lenc_key_abort + + adr r3,Lrcon + cmp r1,#192 + + veor q0,q0,q0 + vld1.8 {q3},[r0]! + mov r1,#8 @ reuse r1 + vld1.32 {q1,q2},[r3]! + + blt Loop128 + beq L192 + b L256 + +.align 4 +Loop128: + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + bne Loop128 + + vld1.32 {q1},[r3] + + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + veor q3,q3,q10 + vst1.32 {q3},[r2] + add r2,r2,#0x50 + + mov r12,#10 + b Ldone + +.align 4 +L192: + vld1.8 {d16},[r0]! + vmov.i8 q10,#8 @ borrow q10 + vst1.32 {q3},[r2]! + vsub.i8 q2,q2,q10 @ adjust the mask + +Loop192: + vtbl.8 d20,{q8},d4 + vtbl.8 d21,{q8},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {d16},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + + vdup.32 q9,d7[1] + veor q9,q9,q8 + veor q10,q10,q1 + vext.8 q8,q0,q8,#12 + vshl.u8 q1,q1,#1 + veor q8,q8,q9 + veor q3,q3,q10 + veor q8,q8,q10 + vst1.32 {q3},[r2]! + bne Loop192 + + mov r12,#12 + add r2,r2,#0x20 + b Ldone + +.align 4 +L256: + vld1.8 {q8},[r0] + mov r1,#7 + mov r12,#14 + vst1.32 {q3},[r2]! + +Loop256: + vtbl.8 d20,{q8},d4 + vtbl.8 d21,{q8},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q8},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + vst1.32 {q3},[r2]! + beq Ldone + + vdup.32 q10,d7[1] + vext.8 q9,q0,q8,#12 +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q8,q8,q9 + vext.8 q9,q0,q9,#12 + veor q8,q8,q9 + vext.8 q9,q0,q9,#12 + veor q8,q8,q9 + + veor q8,q8,q10 + b Loop256 + +Ldone: + str r12,[r2] + mov r3,#0 + +Lenc_key_abort: + mov r0,r3 @ return value + + bx lr + + +.globl _aes_hw_set_decrypt_key +.private_extern _aes_hw_set_decrypt_key +#ifdef __thumb2__ +.thumb_func _aes_hw_set_decrypt_key +#endif +.align 5 +_aes_hw_set_decrypt_key: + stmdb sp!,{r4,lr} + bl Lenc_key + + cmp r0,#0 + bne Ldec_key_abort + + sub r2,r2,#240 @ restore original r2 + mov r4,#-16 + add r0,r2,r12,lsl#4 @ end of key schedule + + vld1.32 {q0},[r2] + vld1.32 {q1},[r0] + vst1.32 {q0},[r0],r4 + vst1.32 {q1},[r2]! + +Loop_imc: + vld1.32 {q0},[r2] + vld1.32 {q1},[r0] +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 + vst1.32 {q0},[r0],r4 + vst1.32 {q1},[r2]! + cmp r0,r2 + bhi Loop_imc + + vld1.32 {q0},[r2] +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 + vst1.32 {q0},[r0] + + eor r0,r0,r0 @ return value +Ldec_key_abort: + ldmia sp!,{r4,pc} + +.globl _aes_hw_encrypt +.private_extern _aes_hw_encrypt +#ifdef __thumb2__ +.thumb_func _aes_hw_encrypt +#endif +.align 5 +_aes_hw_encrypt: + AARCH64_VALID_CALL_TARGET + ldr r3,[r2,#240] + vld1.32 {q0},[r2]! + vld1.8 {q2},[r0] + sub r3,r3,#2 + vld1.32 {q1},[r2]! + +Loop_enc: +.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q0},[r2]! + subs r3,r3,#2 +.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q1},[r2]! + bgt Loop_enc + +.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q0},[r2] +.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1 + veor q2,q2,q0 + + vst1.8 {q2},[r1] + bx lr + +.globl _aes_hw_decrypt +.private_extern _aes_hw_decrypt +#ifdef __thumb2__ +.thumb_func _aes_hw_decrypt +#endif +.align 5 +_aes_hw_decrypt: + AARCH64_VALID_CALL_TARGET + ldr r3,[r2,#240] + vld1.32 {q0},[r2]! + vld1.8 {q2},[r0] + sub r3,r3,#2 + vld1.32 {q1},[r2]! + +Loop_dec: +.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q0},[r2]! + subs r3,r3,#2 +.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q1},[r2]! + bgt Loop_dec + +.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q0},[r2] +.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1 + veor q2,q2,q0 + + vst1.8 {q2},[r1] + bx lr + +.globl _aes_hw_cbc_encrypt +.private_extern _aes_hw_cbc_encrypt +#ifdef __thumb2__ +.thumb_func _aes_hw_cbc_encrypt +#endif +.align 5 +_aes_hw_cbc_encrypt: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,lr} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldmia ip,{r4,r5} @ load remaining args + subs r2,r2,#16 + mov r8,#16 + blo Lcbc_abort + moveq r8,#0 + + cmp r5,#0 @ en- or decrypting? + ldr r5,[r3,#240] + and r2,r2,#-16 + vld1.8 {q6},[r4] + vld1.8 {q0},[r0],r8 + + vld1.32 {q8,q9},[r3] @ load key schedule... + sub r5,r5,#6 + add r7,r3,r5,lsl#4 @ pointer to last 7 round keys + sub r5,r5,#2 + vld1.32 {q10,q11},[r7]! + vld1.32 {q12,q13},[r7]! + vld1.32 {q14,q15},[r7]! + vld1.32 {q7},[r7] + + add r7,r3,#32 + mov r6,r5 + beq Lcbc_dec + + cmp r5,#2 + veor q0,q0,q6 + veor q5,q8,q7 + beq Lcbc_enc128 + + vld1.32 {q2,q3},[r7] + add r7,r3,#16 + add r6,r3,#16*4 + add r12,r3,#16*5 +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + add r14,r3,#16*6 + add r3,r3,#16*7 + b Lenter_cbc_enc + +.align 4 +Loop_cbc_enc: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vst1.8 {q6},[r1]! +Lenter_cbc_enc: +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q8},[r6] + cmp r5,#4 +.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r12] + beq Lcbc_enc192 + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q8},[r14] +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r3] + nop + +Lcbc_enc192: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + subs r2,r2,#16 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + moveq r8,#0 +.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.8 {q8},[r0],r8 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + veor q8,q8,q5 +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r7] @ re-pre-load rndkey[1] +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 + veor q6,q0,q7 + bhs Loop_cbc_enc + + vst1.8 {q6},[r1]! + b Lcbc_done + +.align 5 +Lcbc_enc128: + vld1.32 {q2,q3},[r7] +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + b Lenter_cbc_enc128 +Loop_cbc_enc128: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vst1.8 {q6},[r1]! +Lenter_cbc_enc128: +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + subs r2,r2,#16 +.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + moveq r8,#0 +.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.8 {q8},[r0],r8 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + veor q8,q8,q5 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 + veor q6,q0,q7 + bhs Loop_cbc_enc128 + + vst1.8 {q6},[r1]! + b Lcbc_done +.align 5 +Lcbc_dec: + vld1.8 {q10},[r0]! + subs r2,r2,#32 @ bias + add r6,r5,#2 + vorr q3,q0,q0 + vorr q1,q0,q0 + vorr q11,q10,q10 + blo Lcbc_dec_tail + + vorr q1,q10,q10 + vld1.8 {q10},[r0]! + vorr q2,q0,q0 + vorr q3,q1,q1 + vorr q11,q10,q10 + +Loop3x_cbc_dec: +.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q9},[r7]! + bgt Loop3x_cbc_dec + +.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q4,q6,q7 + subs r2,r2,#0x30 + veor q5,q2,q7 + movlo r6,r2 @ r6, r6, is zero at this point +.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q9,q3,q7 + add r0,r0,r6 @ r0 is adjusted in such way that + @ at exit from the loop q1-q10 + @ are loaded with last "words" + vorr q6,q11,q11 + mov r7,r3 +.byte 0x68,0x03,0xb0,0xf3 @ aesd q0,q12 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q2},[r0]! +.byte 0x6a,0x03,0xb0,0xf3 @ aesd q0,q13 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q3},[r0]! +.byte 0x6c,0x03,0xb0,0xf3 @ aesd q0,q14 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q11},[r0]! +.byte 0x6e,0x03,0xb0,0xf3 @ aesd q0,q15 +.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15 +.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15 + vld1.32 {q8},[r7]! @ re-pre-load rndkey[0] + add r6,r5,#2 + veor q4,q4,q0 + veor q5,q5,q1 + veor q10,q10,q9 + vld1.32 {q9},[r7]! @ re-pre-load rndkey[1] + vst1.8 {q4},[r1]! + vorr q0,q2,q2 + vst1.8 {q5},[r1]! + vorr q1,q3,q3 + vst1.8 {q10},[r1]! + vorr q10,q11,q11 + bhs Loop3x_cbc_dec + + cmn r2,#0x30 + beq Lcbc_done + nop + +Lcbc_dec_tail: +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q9},[r7]! + bgt Lcbc_dec_tail + +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 +.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + cmn r2,#0x20 +.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q5,q6,q7 +.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q9,q3,q7 +.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15 +.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15 + beq Lcbc_dec_one + veor q5,q5,q1 + veor q9,q9,q10 + vorr q6,q11,q11 + vst1.8 {q5},[r1]! + vst1.8 {q9},[r1]! + b Lcbc_done + +Lcbc_dec_one: + veor q5,q5,q10 + vorr q6,q11,q11 + vst1.8 {q5},[r1]! + +Lcbc_done: + vst1.8 {q6},[r4] +Lcbc_abort: + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,pc} + +.globl _aes_hw_ctr32_encrypt_blocks +.private_extern _aes_hw_ctr32_encrypt_blocks +#ifdef __thumb2__ +.thumb_func _aes_hw_ctr32_encrypt_blocks +#endif +.align 5 +_aes_hw_ctr32_encrypt_blocks: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,lr} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldr r4, [ip] @ load remaining arg + ldr r5,[r3,#240] + + ldr r8, [r4, #12] + vld1.32 {q0},[r4] + + vld1.32 {q8,q9},[r3] @ load key schedule... + sub r5,r5,#4 + mov r12,#16 + cmp r2,#2 + add r7,r3,r5,lsl#4 @ pointer to last 5 round keys + sub r5,r5,#2 + vld1.32 {q12,q13},[r7]! + vld1.32 {q14,q15},[r7]! + vld1.32 {q7},[r7] + add r7,r3,#32 + mov r6,r5 + movlo r12,#0 + + @ ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are + @ affected by silicon errata #1742098 [0] and #1655431 [1], + @ respectively, where the second instruction of an aese/aesmc + @ instruction pair may execute twice if an interrupt is taken right + @ after the first instruction consumes an input register of which a + @ single 32-bit lane has been updated the last time it was modified. + @ + @ This function uses a counter in one 32-bit lane. The + @ could write to q1 and q10 directly, but that trips this bugs. + @ We write to q6 and copy to the final register as a workaround. + @ + @ [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice + @ [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice +#ifndef __ARMEB__ + rev r8, r8 +#endif + add r10, r8, #1 + vorr q6,q0,q0 + rev r10, r10 + vmov.32 d13[1],r10 + add r8, r8, #2 + vorr q1,q6,q6 + bls Lctr32_tail + rev r12, r8 + vmov.32 d13[1],r12 + sub r2,r2,#3 @ bias + vorr q10,q6,q6 + b Loop3x_ctr32 + +.align 4 +Loop3x_ctr32: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.32 {q9},[r7]! + bgt Loop3x_ctr32 + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x83,0xb0,0xf3 @ aesmc q4,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0xa3,0xb0,0xf3 @ aesmc q5,q1 + vld1.8 {q2},[r0]! + add r9,r8,#1 +.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.8 {q3},[r0]! + rev r9,r9 +.byte 0x22,0x83,0xb0,0xf3 @ aese q4,q9 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x22,0xa3,0xb0,0xf3 @ aese q5,q9 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + vld1.8 {q11},[r0]! + mov r7,r3 +.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9 +.byte 0xa4,0x23,0xf0,0xf3 @ aesmc q9,q10 +.byte 0x28,0x83,0xb0,0xf3 @ aese q4,q12 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x28,0xa3,0xb0,0xf3 @ aese q5,q12 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + veor q2,q2,q7 + add r10,r8,#2 +.byte 0x28,0x23,0xf0,0xf3 @ aese q9,q12 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + veor q3,q3,q7 + add r8,r8,#3 +.byte 0x2a,0x83,0xb0,0xf3 @ aese q4,q13 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x2a,0xa3,0xb0,0xf3 @ aese q5,q13 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + @ Note the logic to update q0, q1, and q1 is written to work + @ around a bug in ARM Cortex-A57 and Cortex-A72 cores running in + @ 32-bit mode. See the comment above. + veor q11,q11,q7 + vmov.32 d13[1], r9 +.byte 0x2a,0x23,0xf0,0xf3 @ aese q9,q13 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + vorr q0,q6,q6 + rev r10,r10 +.byte 0x2c,0x83,0xb0,0xf3 @ aese q4,q14 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 + vmov.32 d13[1], r10 + rev r12,r8 +.byte 0x2c,0xa3,0xb0,0xf3 @ aese q5,q14 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + vorr q1,q6,q6 + vmov.32 d13[1], r12 +.byte 0x2c,0x23,0xf0,0xf3 @ aese q9,q14 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + vorr q10,q6,q6 + subs r2,r2,#3 +.byte 0x2e,0x83,0xb0,0xf3 @ aese q4,q15 +.byte 0x2e,0xa3,0xb0,0xf3 @ aese q5,q15 +.byte 0x2e,0x23,0xf0,0xf3 @ aese q9,q15 + + veor q2,q2,q4 + vld1.32 {q8},[r7]! @ re-pre-load rndkey[0] + vst1.8 {q2},[r1]! + veor q3,q3,q5 + mov r6,r5 + vst1.8 {q3},[r1]! + veor q11,q11,q9 + vld1.32 {q9},[r7]! @ re-pre-load rndkey[1] + vst1.8 {q11},[r1]! + bhs Loop3x_ctr32 + + adds r2,r2,#3 + beq Lctr32_done + cmp r2,#1 + mov r12,#16 + moveq r12,#0 + +Lctr32_tail: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.32 {q9},[r7]! + bgt Lctr32_tail + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.8 {q2},[r0],r12 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x28,0x23,0xb0,0xf3 @ aese q1,q12 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.8 {q3},[r0] +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2a,0x23,0xb0,0xf3 @ aese q1,q13 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + veor q2,q2,q7 +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2c,0x23,0xb0,0xf3 @ aese q1,q14 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + veor q3,q3,q7 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 +.byte 0x2e,0x23,0xb0,0xf3 @ aese q1,q15 + + cmp r2,#1 + veor q2,q2,q0 + veor q3,q3,q1 + vst1.8 {q2},[r1]! + beq Lctr32_done + vst1.8 {q3},[r1] + +Lctr32_done: + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} + +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S new file mode 100644 index 00000000..993a9b8e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S @@ -0,0 +1,807 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text +.arch armv7-a @ don't confuse not-so-latest binutils with argv8 :-) +.fpu neon +.code 32 +#undef __thumb2__ +.align 5 +.Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d @ rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.text + +.globl aes_hw_set_encrypt_key +.hidden aes_hw_set_encrypt_key +.type aes_hw_set_encrypt_key,%function +.align 5 +aes_hw_set_encrypt_key: +.Lenc_key: + mov r3,#-1 + cmp r0,#0 + beq .Lenc_key_abort + cmp r2,#0 + beq .Lenc_key_abort + mov r3,#-2 + cmp r1,#128 + blt .Lenc_key_abort + cmp r1,#256 + bgt .Lenc_key_abort + tst r1,#0x3f + bne .Lenc_key_abort + + adr r3,.Lrcon + cmp r1,#192 + + veor q0,q0,q0 + vld1.8 {q3},[r0]! + mov r1,#8 @ reuse r1 + vld1.32 {q1,q2},[r3]! + + blt .Loop128 + beq .L192 + b .L256 + +.align 4 +.Loop128: + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + bne .Loop128 + + vld1.32 {q1},[r3] + + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + + vtbl.8 d20,{q3},d4 + vtbl.8 d21,{q3},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q3},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + veor q3,q3,q10 + vst1.32 {q3},[r2] + add r2,r2,#0x50 + + mov r12,#10 + b .Ldone + +.align 4 +.L192: + vld1.8 {d16},[r0]! + vmov.i8 q10,#8 @ borrow q10 + vst1.32 {q3},[r2]! + vsub.i8 q2,q2,q10 @ adjust the mask + +.Loop192: + vtbl.8 d20,{q8},d4 + vtbl.8 d21,{q8},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {d16},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + + vdup.32 q9,d7[1] + veor q9,q9,q8 + veor q10,q10,q1 + vext.8 q8,q0,q8,#12 + vshl.u8 q1,q1,#1 + veor q8,q8,q9 + veor q3,q3,q10 + veor q8,q8,q10 + vst1.32 {q3},[r2]! + bne .Loop192 + + mov r12,#12 + add r2,r2,#0x20 + b .Ldone + +.align 4 +.L256: + vld1.8 {q8},[r0] + mov r1,#7 + mov r12,#14 + vst1.32 {q3},[r2]! + +.Loop256: + vtbl.8 d20,{q8},d4 + vtbl.8 d21,{q8},d5 + vext.8 q9,q0,q3,#12 + vst1.32 {q8},[r2]! +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + subs r1,r1,#1 + + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q3,q3,q9 + vext.8 q9,q0,q9,#12 + veor q10,q10,q1 + veor q3,q3,q9 + vshl.u8 q1,q1,#1 + veor q3,q3,q10 + vst1.32 {q3},[r2]! + beq .Ldone + + vdup.32 q10,d7[1] + vext.8 q9,q0,q8,#12 +.byte 0x00,0x43,0xf0,0xf3 @ aese q10,q0 + + veor q8,q8,q9 + vext.8 q9,q0,q9,#12 + veor q8,q8,q9 + vext.8 q9,q0,q9,#12 + veor q8,q8,q9 + + veor q8,q8,q10 + b .Loop256 + +.Ldone: + str r12,[r2] + mov r3,#0 + +.Lenc_key_abort: + mov r0,r3 @ return value + + bx lr +.size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key + +.globl aes_hw_set_decrypt_key +.hidden aes_hw_set_decrypt_key +.type aes_hw_set_decrypt_key,%function +.align 5 +aes_hw_set_decrypt_key: + stmdb sp!,{r4,lr} + bl .Lenc_key + + cmp r0,#0 + bne .Ldec_key_abort + + sub r2,r2,#240 @ restore original r2 + mov r4,#-16 + add r0,r2,r12,lsl#4 @ end of key schedule + + vld1.32 {q0},[r2] + vld1.32 {q1},[r0] + vst1.32 {q0},[r0],r4 + vst1.32 {q1},[r2]! + +.Loop_imc: + vld1.32 {q0},[r2] + vld1.32 {q1},[r0] +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 + vst1.32 {q0},[r0],r4 + vst1.32 {q1},[r2]! + cmp r0,r2 + bhi .Loop_imc + + vld1.32 {q0},[r2] +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 + vst1.32 {q0},[r0] + + eor r0,r0,r0 @ return value +.Ldec_key_abort: + ldmia sp!,{r4,pc} +.size aes_hw_set_decrypt_key,.-aes_hw_set_decrypt_key +.globl aes_hw_encrypt +.hidden aes_hw_encrypt +.type aes_hw_encrypt,%function +.align 5 +aes_hw_encrypt: + AARCH64_VALID_CALL_TARGET + ldr r3,[r2,#240] + vld1.32 {q0},[r2]! + vld1.8 {q2},[r0] + sub r3,r3,#2 + vld1.32 {q1},[r2]! + +.Loop_enc: +.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q0},[r2]! + subs r3,r3,#2 +.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q1},[r2]! + bgt .Loop_enc + +.byte 0x00,0x43,0xb0,0xf3 @ aese q2,q0 +.byte 0x84,0x43,0xb0,0xf3 @ aesmc q2,q2 + vld1.32 {q0},[r2] +.byte 0x02,0x43,0xb0,0xf3 @ aese q2,q1 + veor q2,q2,q0 + + vst1.8 {q2},[r1] + bx lr +.size aes_hw_encrypt,.-aes_hw_encrypt +.globl aes_hw_decrypt +.hidden aes_hw_decrypt +.type aes_hw_decrypt,%function +.align 5 +aes_hw_decrypt: + AARCH64_VALID_CALL_TARGET + ldr r3,[r2,#240] + vld1.32 {q0},[r2]! + vld1.8 {q2},[r0] + sub r3,r3,#2 + vld1.32 {q1},[r2]! + +.Loop_dec: +.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q0},[r2]! + subs r3,r3,#2 +.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q1},[r2]! + bgt .Loop_dec + +.byte 0x40,0x43,0xb0,0xf3 @ aesd q2,q0 +.byte 0xc4,0x43,0xb0,0xf3 @ aesimc q2,q2 + vld1.32 {q0},[r2] +.byte 0x42,0x43,0xb0,0xf3 @ aesd q2,q1 + veor q2,q2,q0 + + vst1.8 {q2},[r1] + bx lr +.size aes_hw_decrypt,.-aes_hw_decrypt +.globl aes_hw_cbc_encrypt +.hidden aes_hw_cbc_encrypt +.type aes_hw_cbc_encrypt,%function +.align 5 +aes_hw_cbc_encrypt: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,lr} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldmia ip,{r4,r5} @ load remaining args + subs r2,r2,#16 + mov r8,#16 + blo .Lcbc_abort + moveq r8,#0 + + cmp r5,#0 @ en- or decrypting? + ldr r5,[r3,#240] + and r2,r2,#-16 + vld1.8 {q6},[r4] + vld1.8 {q0},[r0],r8 + + vld1.32 {q8,q9},[r3] @ load key schedule... + sub r5,r5,#6 + add r7,r3,r5,lsl#4 @ pointer to last 7 round keys + sub r5,r5,#2 + vld1.32 {q10,q11},[r7]! + vld1.32 {q12,q13},[r7]! + vld1.32 {q14,q15},[r7]! + vld1.32 {q7},[r7] + + add r7,r3,#32 + mov r6,r5 + beq .Lcbc_dec + + cmp r5,#2 + veor q0,q0,q6 + veor q5,q8,q7 + beq .Lcbc_enc128 + + vld1.32 {q2,q3},[r7] + add r7,r3,#16 + add r6,r3,#16*4 + add r12,r3,#16*5 +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + add r14,r3,#16*6 + add r3,r3,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vst1.8 {q6},[r1]! +.Lenter_cbc_enc: +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q8},[r6] + cmp r5,#4 +.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r12] + beq .Lcbc_enc192 + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q8},[r14] +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r3] + nop + +.Lcbc_enc192: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + subs r2,r2,#16 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + moveq r8,#0 +.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.8 {q8},[r0],r8 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + veor q8,q8,q5 +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.32 {q9},[r7] @ re-pre-load rndkey[1] +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 + veor q6,q0,q7 + bhs .Loop_cbc_enc + + vst1.8 {q6},[r1]! + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + vld1.32 {q2,q3},[r7] +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vst1.8 {q6},[r1]! +.Lenter_cbc_enc128: +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + subs r2,r2,#16 +.byte 0x04,0x03,0xb0,0xf3 @ aese q0,q2 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + moveq r8,#0 +.byte 0x06,0x03,0xb0,0xf3 @ aese q0,q3 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x24,0x03,0xb0,0xf3 @ aese q0,q10 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x26,0x03,0xb0,0xf3 @ aese q0,q11 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + vld1.8 {q8},[r0],r8 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 + veor q8,q8,q5 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 + veor q6,q0,q7 + bhs .Loop_cbc_enc128 + + vst1.8 {q6},[r1]! + b .Lcbc_done +.align 5 +.Lcbc_dec: + vld1.8 {q10},[r0]! + subs r2,r2,#32 @ bias + add r6,r5,#2 + vorr q3,q0,q0 + vorr q1,q0,q0 + vorr q11,q10,q10 + blo .Lcbc_dec_tail + + vorr q1,q10,q10 + vld1.8 {q10},[r0]! + vorr q2,q0,q0 + vorr q3,q1,q1 + vorr q11,q10,q10 + +.Loop3x_cbc_dec: +.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q9},[r7]! + bgt .Loop3x_cbc_dec + +.byte 0x60,0x03,0xb0,0xf3 @ aesd q0,q8 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q4,q6,q7 + subs r2,r2,#0x30 + veor q5,q2,q7 + movlo r6,r2 @ r6, r6, is zero at this point +.byte 0x62,0x03,0xb0,0xf3 @ aesd q0,q9 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q9,q3,q7 + add r0,r0,r6 @ r0 is adjusted in such way that + @ at exit from the loop q1-q10 + @ are loaded with last "words" + vorr q6,q11,q11 + mov r7,r3 +.byte 0x68,0x03,0xb0,0xf3 @ aesd q0,q12 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q2},[r0]! +.byte 0x6a,0x03,0xb0,0xf3 @ aesd q0,q13 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q3},[r0]! +.byte 0x6c,0x03,0xb0,0xf3 @ aesd q0,q14 +.byte 0xc0,0x03,0xb0,0xf3 @ aesimc q0,q0 +.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.8 {q11},[r0]! +.byte 0x6e,0x03,0xb0,0xf3 @ aesd q0,q15 +.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15 +.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15 + vld1.32 {q8},[r7]! @ re-pre-load rndkey[0] + add r6,r5,#2 + veor q4,q4,q0 + veor q5,q5,q1 + veor q10,q10,q9 + vld1.32 {q9},[r7]! @ re-pre-load rndkey[1] + vst1.8 {q4},[r1]! + vorr q0,q2,q2 + vst1.8 {q5},[r1]! + vorr q1,q3,q3 + vst1.8 {q10},[r1]! + vorr q10,q11,q11 + bhs .Loop3x_cbc_dec + + cmn r2,#0x30 + beq .Lcbc_done + nop + +.Lcbc_dec_tail: +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + vld1.32 {q9},[r7]! + bgt .Lcbc_dec_tail + +.byte 0x60,0x23,0xb0,0xf3 @ aesd q1,q8 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x60,0x43,0xf0,0xf3 @ aesd q10,q8 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 +.byte 0x62,0x23,0xb0,0xf3 @ aesd q1,q9 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x62,0x43,0xf0,0xf3 @ aesd q10,q9 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 +.byte 0x68,0x23,0xb0,0xf3 @ aesd q1,q12 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x68,0x43,0xf0,0xf3 @ aesd q10,q12 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + cmn r2,#0x20 +.byte 0x6a,0x23,0xb0,0xf3 @ aesd q1,q13 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6a,0x43,0xf0,0xf3 @ aesd q10,q13 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q5,q6,q7 +.byte 0x6c,0x23,0xb0,0xf3 @ aesd q1,q14 +.byte 0xc2,0x23,0xb0,0xf3 @ aesimc q1,q1 +.byte 0x6c,0x43,0xf0,0xf3 @ aesd q10,q14 +.byte 0xe4,0x43,0xf0,0xf3 @ aesimc q10,q10 + veor q9,q3,q7 +.byte 0x6e,0x23,0xb0,0xf3 @ aesd q1,q15 +.byte 0x6e,0x43,0xf0,0xf3 @ aesd q10,q15 + beq .Lcbc_dec_one + veor q5,q5,q1 + veor q9,q9,q10 + vorr q6,q11,q11 + vst1.8 {q5},[r1]! + vst1.8 {q9},[r1]! + b .Lcbc_done + +.Lcbc_dec_one: + veor q5,q5,q10 + vorr q6,q11,q11 + vst1.8 {q5},[r1]! + +.Lcbc_done: + vst1.8 {q6},[r4] +.Lcbc_abort: + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,pc} +.size aes_hw_cbc_encrypt,.-aes_hw_cbc_encrypt +.globl aes_hw_ctr32_encrypt_blocks +.hidden aes_hw_ctr32_encrypt_blocks +.type aes_hw_ctr32_encrypt_blocks,%function +.align 5 +aes_hw_ctr32_encrypt_blocks: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,lr} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldr r4, [ip] @ load remaining arg + ldr r5,[r3,#240] + + ldr r8, [r4, #12] + vld1.32 {q0},[r4] + + vld1.32 {q8,q9},[r3] @ load key schedule... + sub r5,r5,#4 + mov r12,#16 + cmp r2,#2 + add r7,r3,r5,lsl#4 @ pointer to last 5 round keys + sub r5,r5,#2 + vld1.32 {q12,q13},[r7]! + vld1.32 {q14,q15},[r7]! + vld1.32 {q7},[r7] + add r7,r3,#32 + mov r6,r5 + movlo r12,#0 + + @ ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are + @ affected by silicon errata #1742098 [0] and #1655431 [1], + @ respectively, where the second instruction of an aese/aesmc + @ instruction pair may execute twice if an interrupt is taken right + @ after the first instruction consumes an input register of which a + @ single 32-bit lane has been updated the last time it was modified. + @ + @ This function uses a counter in one 32-bit lane. The + @ could write to q1 and q10 directly, but that trips this bugs. + @ We write to q6 and copy to the final register as a workaround. + @ + @ [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice + @ [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice +#ifndef __ARMEB__ + rev r8, r8 +#endif + add r10, r8, #1 + vorr q6,q0,q0 + rev r10, r10 + vmov.32 d13[1],r10 + add r8, r8, #2 + vorr q1,q6,q6 + bls .Lctr32_tail + rev r12, r8 + vmov.32 d13[1],r12 + sub r2,r2,#3 @ bias + vorr q10,q6,q6 + b .Loop3x_ctr32 + +.align 4 +.Loop3x_ctr32: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.32 {q9},[r7]! + bgt .Loop3x_ctr32 + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x83,0xb0,0xf3 @ aesmc q4,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0xa3,0xb0,0xf3 @ aesmc q5,q1 + vld1.8 {q2},[r0]! + add r9,r8,#1 +.byte 0x20,0x43,0xf0,0xf3 @ aese q10,q8 +.byte 0xa4,0x43,0xf0,0xf3 @ aesmc q10,q10 + vld1.8 {q3},[r0]! + rev r9,r9 +.byte 0x22,0x83,0xb0,0xf3 @ aese q4,q9 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x22,0xa3,0xb0,0xf3 @ aese q5,q9 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + vld1.8 {q11},[r0]! + mov r7,r3 +.byte 0x22,0x43,0xf0,0xf3 @ aese q10,q9 +.byte 0xa4,0x23,0xf0,0xf3 @ aesmc q9,q10 +.byte 0x28,0x83,0xb0,0xf3 @ aese q4,q12 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x28,0xa3,0xb0,0xf3 @ aese q5,q12 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + veor q2,q2,q7 + add r10,r8,#2 +.byte 0x28,0x23,0xf0,0xf3 @ aese q9,q12 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + veor q3,q3,q7 + add r8,r8,#3 +.byte 0x2a,0x83,0xb0,0xf3 @ aese q4,q13 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 +.byte 0x2a,0xa3,0xb0,0xf3 @ aese q5,q13 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + @ Note the logic to update q0, q1, and q1 is written to work + @ around a bug in ARM Cortex-A57 and Cortex-A72 cores running in + @ 32-bit mode. See the comment above. + veor q11,q11,q7 + vmov.32 d13[1], r9 +.byte 0x2a,0x23,0xf0,0xf3 @ aese q9,q13 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + vorr q0,q6,q6 + rev r10,r10 +.byte 0x2c,0x83,0xb0,0xf3 @ aese q4,q14 +.byte 0x88,0x83,0xb0,0xf3 @ aesmc q4,q4 + vmov.32 d13[1], r10 + rev r12,r8 +.byte 0x2c,0xa3,0xb0,0xf3 @ aese q5,q14 +.byte 0x8a,0xa3,0xb0,0xf3 @ aesmc q5,q5 + vorr q1,q6,q6 + vmov.32 d13[1], r12 +.byte 0x2c,0x23,0xf0,0xf3 @ aese q9,q14 +.byte 0xa2,0x23,0xf0,0xf3 @ aesmc q9,q9 + vorr q10,q6,q6 + subs r2,r2,#3 +.byte 0x2e,0x83,0xb0,0xf3 @ aese q4,q15 +.byte 0x2e,0xa3,0xb0,0xf3 @ aese q5,q15 +.byte 0x2e,0x23,0xf0,0xf3 @ aese q9,q15 + + veor q2,q2,q4 + vld1.32 {q8},[r7]! @ re-pre-load rndkey[0] + vst1.8 {q2},[r1]! + veor q3,q3,q5 + mov r6,r5 + vst1.8 {q3},[r1]! + veor q11,q11,q9 + vld1.32 {q9},[r7]! @ re-pre-load rndkey[1] + vst1.8 {q11},[r1]! + bhs .Loop3x_ctr32 + + adds r2,r2,#3 + beq .Lctr32_done + cmp r2,#1 + mov r12,#16 + moveq r12,#0 + +.Lctr32_tail: +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.32 {q8},[r7]! + subs r6,r6,#2 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.32 {q9},[r7]! + bgt .Lctr32_tail + +.byte 0x20,0x03,0xb0,0xf3 @ aese q0,q8 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x20,0x23,0xb0,0xf3 @ aese q1,q8 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 +.byte 0x22,0x03,0xb0,0xf3 @ aese q0,q9 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x22,0x23,0xb0,0xf3 @ aese q1,q9 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.8 {q2},[r0],r12 +.byte 0x28,0x03,0xb0,0xf3 @ aese q0,q12 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x28,0x23,0xb0,0xf3 @ aese q1,q12 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + vld1.8 {q3},[r0] +.byte 0x2a,0x03,0xb0,0xf3 @ aese q0,q13 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2a,0x23,0xb0,0xf3 @ aese q1,q13 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + veor q2,q2,q7 +.byte 0x2c,0x03,0xb0,0xf3 @ aese q0,q14 +.byte 0x80,0x03,0xb0,0xf3 @ aesmc q0,q0 +.byte 0x2c,0x23,0xb0,0xf3 @ aese q1,q14 +.byte 0x82,0x23,0xb0,0xf3 @ aesmc q1,q1 + veor q3,q3,q7 +.byte 0x2e,0x03,0xb0,0xf3 @ aese q0,q15 +.byte 0x2e,0x23,0xb0,0xf3 @ aese q1,q15 + + cmp r2,#1 + veor q2,q2,q0 + veor q3,q3,q1 + vst1.8 {q2},[r1]! + beq .Lctr32_done + vst1.8 {q3},[r1] + +.Lctr32_done: + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} +.size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S new file mode 100644 index 00000000..a3a27014 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S @@ -0,0 +1,806 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text + +.section __TEXT,__const +.align 5 +Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.text + +.globl _aes_hw_set_encrypt_key +.private_extern _aes_hw_set_encrypt_key + +.align 5 +_aes_hw_set_encrypt_key: +Lenc_key: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq Lenc_key_abort + cmp x2,#0 + b.eq Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt Lenc_key_abort + cmp w1,#256 + b.gt Lenc_key_abort + tst w1,#0x3f + b.ne Lenc_key_abort + + adrp x3,Lrcon@PAGE + add x3,x3,Lrcon@PAGEOFF + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt Loop128 + b.eq L192 + b L256 + +.align 4 +Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 + b Ldone + +.align 4 +L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.8b},[x2],#8 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne Loop192 + + mov w12,#12 + add x2,x2,#0x20 + b Ldone + +.align 4 +L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.eq Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b Loop256 + +Ldone: + str w12,[x2] + mov x3,#0 + +Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret + + +.globl _aes_hw_set_decrypt_key +.private_extern _aes_hw_set_decrypt_key + +.align 5 +_aes_hw_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl Lenc_key + + cmp x0,#0 + b.ne Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +Ldec_key_abort: + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _aes_hw_encrypt +.private_extern _aes_hw_encrypt + +.align 5 +_aes_hw_encrypt: + AARCH64_VALID_CALL_TARGET + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret + +.globl _aes_hw_decrypt +.private_extern _aes_hw_decrypt + +.align 5 +_aes_hw_decrypt: + AARCH64_VALID_CALL_TARGET + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret + +.globl _aes_hw_cbc_encrypt +.private_extern _aes_hw_cbc_encrypt + +.align 5 +_aes_hw_cbc_encrypt: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq Lcbc_enc128 + + ld1 {v2.4s,v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b Lenter_cbc_enc + +.align 4 +Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b Lcbc_done + +.align 5 +Lcbc_enc128: + ld1 {v2.4s,v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b Lenter_cbc_enc128 +Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b Lcbc_done +.align 5 +Lcbc_dec: + ld1 {v18.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v19.16b,v18.16b,v18.16b + b.lo Lcbc_dec_tail + + orr v1.16b,v18.16b,v18.16b + ld1 {v18.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v19.16b,v18.16b,v18.16b + +Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v18.16b + // are loaded with last "words" + orr v6.16b,v19.16b,v19.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v18.16b,v18.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v18.16b},[x1],#16 + orr v18.16b,v19.16b,v19.16b + b.hs Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq Lcbc_done + nop + +Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + b.eq Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b Lcbc_done + +Lcbc_dec_one: + eor v5.16b,v5.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + +Lcbc_done: + st1 {v6.16b},[x4] +Lcbc_abort: + ldr x29,[sp],#16 + ret + +.globl _aes_hw_ctr32_encrypt_blocks +.private_extern _aes_hw_ctr32_encrypt_blocks + +.align 5 +_aes_hw_ctr32_encrypt_blocks: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] + ld1 {v0.4s},[x4] + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo + + // ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are + // affected by silicon errata #1742098 [0] and #1655431 [1], + // respectively, where the second instruction of an aese/aesmc + // instruction pair may execute twice if an interrupt is taken right + // after the first instruction consumes an input register of which a + // single 32-bit lane has been updated the last time it was modified. + // + // This function uses a counter in one 32-bit lane. The vmov lines + // could write to v1.16b and v18.16b directly, but that trips this bugs. + // We write to v6.16b and copy to the final register as a workaround. + // + // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice + // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice +#ifndef __AARCH64EB__ + rev w8, w8 +#endif + add w10, w8, #1 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v6.s[3],w10 + add w8, w8, #2 + orr v1.16b,v6.16b,v6.16b + b.ls Lctr32_tail + rev w12, w8 + mov v6.s[3],w12 + sub x2,x2,#3 // bias + orr v18.16b,v6.16b,v6.16b + b Loop3x_ctr32 + +.align 4 +Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + add w9,w8,#1 + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + rev w9,w9 + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + // Note the logic to update v0.16b, v1.16b, and v1.16b is written to work + // around a bug in ARM Cortex-A57 and Cortex-A72 cores running in + // 32-bit mode. See the comment above. + eor v19.16b,v19.16b,v7.16b + mov v6.s[3], w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + orr v0.16b,v6.16b,v6.16b + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + mov v6.s[3], w10 + rev w12,w8 + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + orr v1.16b,v6.16b,v6.16b + mov v6.s[3], w12 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + orr v18.16b,v6.16b,v6.16b + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs Loop3x_ctr32 + + adds x2,x2,#3 + b.eq Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq Lctr32_done + st1 {v3.16b},[x1] + +Lctr32_done: + ldr x29,[sp],#16 + ret + +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S new file mode 100644 index 00000000..41df2587 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S @@ -0,0 +1,809 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text +.arch armv8-a+crypto +.section .rodata +.align 5 +.Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.text + +.globl aes_hw_set_encrypt_key +.hidden aes_hw_set_encrypt_key +.type aes_hw_set_encrypt_key,%function +.align 5 +aes_hw_set_encrypt_key: +.Lenc_key: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq .Lenc_key_abort + cmp x2,#0 + b.eq .Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt .Lenc_key_abort + cmp w1,#256 + b.gt .Lenc_key_abort + tst w1,#0x3f + b.ne .Lenc_key_abort + + adrp x3,.Lrcon + add x3,x3,:lo12:.Lrcon + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt .Loop128 + b.eq .L192 + b .L256 + +.align 4 +.Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne .Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 + b .Ldone + +.align 4 +.L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +.Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.8b},[x2],#8 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne .Loop192 + + mov w12,#12 + add x2,x2,#0x20 + b .Ldone + +.align 4 +.L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +.Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.eq .Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b .Loop256 + +.Ldone: + str w12,[x2] + mov x3,#0 + +.Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret +.size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key + +.globl aes_hw_set_decrypt_key +.hidden aes_hw_set_decrypt_key +.type aes_hw_set_decrypt_key,%function +.align 5 +aes_hw_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl .Lenc_key + + cmp x0,#0 + b.ne .Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +.Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi .Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +.Ldec_key_abort: + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_hw_set_decrypt_key,.-aes_hw_set_decrypt_key +.globl aes_hw_encrypt +.hidden aes_hw_encrypt +.type aes_hw_encrypt,%function +.align 5 +aes_hw_encrypt: + AARCH64_VALID_CALL_TARGET + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_hw_encrypt,.-aes_hw_encrypt +.globl aes_hw_decrypt +.hidden aes_hw_decrypt +.type aes_hw_decrypt,%function +.align 5 +aes_hw_decrypt: + AARCH64_VALID_CALL_TARGET + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_hw_decrypt,.-aes_hw_decrypt +.globl aes_hw_cbc_encrypt +.hidden aes_hw_cbc_encrypt +.type aes_hw_cbc_encrypt,%function +.align 5 +aes_hw_cbc_encrypt: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq .Lcbc_enc128 + + ld1 {v2.4s,v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq .Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +.Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + ld1 {v2.4s,v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b .Lcbc_done +.align 5 +.Lcbc_dec: + ld1 {v18.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v19.16b,v18.16b,v18.16b + b.lo .Lcbc_dec_tail + + orr v1.16b,v18.16b,v18.16b + ld1 {v18.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v19.16b,v18.16b,v18.16b + +.Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v18.16b + // are loaded with last "words" + orr v6.16b,v19.16b,v19.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v18.16b,v18.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v18.16b},[x1],#16 + orr v18.16b,v19.16b,v19.16b + b.hs .Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq .Lcbc_done + nop + +.Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + b.eq .Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lcbc_done + +.Lcbc_dec_one: + eor v5.16b,v5.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + +.Lcbc_done: + st1 {v6.16b},[x4] +.Lcbc_abort: + ldr x29,[sp],#16 + ret +.size aes_hw_cbc_encrypt,.-aes_hw_cbc_encrypt +.globl aes_hw_ctr32_encrypt_blocks +.hidden aes_hw_ctr32_encrypt_blocks +.type aes_hw_ctr32_encrypt_blocks,%function +.align 5 +aes_hw_ctr32_encrypt_blocks: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] + ld1 {v0.4s},[x4] + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo + + // ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are + // affected by silicon errata #1742098 [0] and #1655431 [1], + // respectively, where the second instruction of an aese/aesmc + // instruction pair may execute twice if an interrupt is taken right + // after the first instruction consumes an input register of which a + // single 32-bit lane has been updated the last time it was modified. + // + // This function uses a counter in one 32-bit lane. The vmov lines + // could write to v1.16b and v18.16b directly, but that trips this bugs. + // We write to v6.16b and copy to the final register as a workaround. + // + // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice + // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice +#ifndef __AARCH64EB__ + rev w8, w8 +#endif + add w10, w8, #1 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v6.s[3],w10 + add w8, w8, #2 + orr v1.16b,v6.16b,v6.16b + b.ls .Lctr32_tail + rev w12, w8 + mov v6.s[3],w12 + sub x2,x2,#3 // bias + orr v18.16b,v6.16b,v6.16b + b .Loop3x_ctr32 + +.align 4 +.Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + add w9,w8,#1 + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + rev w9,w9 + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + // Note the logic to update v0.16b, v1.16b, and v1.16b is written to work + // around a bug in ARM Cortex-A57 and Cortex-A72 cores running in + // 32-bit mode. See the comment above. + eor v19.16b,v19.16b,v7.16b + mov v6.s[3], w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + orr v0.16b,v6.16b,v6.16b + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + mov v6.s[3], w10 + rev w12,w8 + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + orr v1.16b,v6.16b,v6.16b + mov v6.s[3], w12 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + orr v18.16b,v6.16b,v6.16b + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs .Loop3x_ctr32 + + adds x2,x2,#3 + b.eq .Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +.Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq .Lctr32_done + st1 {v3.16b},[x1] + +.Lctr32_done: + ldr x29,[sp],#16 + ret +.size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S new file mode 100644 index 00000000..ea71ff9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S @@ -0,0 +1,989 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. + + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + +#if __ARM_MAX_ARCH__>=7 +.align 5 +LOPENSSL_armcap: +.word OPENSSL_armcap_P-Lbn_mul_mont +#endif + +.globl _bn_mul_mont +.private_extern _bn_mul_mont +#ifdef __thumb2__ +.thumb_func _bn_mul_mont +#endif + +.align 5 +_bn_mul_mont: +Lbn_mul_mont: + ldr ip,[sp,#4] @ load num + stmdb sp!,{r0,r2} @ sp points at argument block +#if __ARM_MAX_ARCH__>=7 + tst ip,#7 + bne Lialu + adr r0,Lbn_mul_mont + ldr r2,LOPENSSL_armcap + ldr r0,[r0,r2] +#ifdef __APPLE__ + ldr r0,[r0] +#endif + tst r0,#ARMV7_NEON @ NEON available? + ldmia sp, {r0,r2} + beq Lialu + add sp,sp,#8 + b bn_mul8x_mont_neon +.align 4 +Lialu: +#endif + cmp ip,#2 + mov r0,ip @ load num +#ifdef __thumb2__ + ittt lt +#endif + movlt r0,#0 + addlt sp,sp,#2*4 + blt Labrt + + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ save 10 registers + + mov r0,r0,lsl#2 @ rescale r0 for byte count + sub sp,sp,r0 @ alloca(4*num) + sub sp,sp,#4 @ +extra dword + sub r0,r0,#4 @ "num=num-1" + add r4,r2,r0 @ &bp[num-1] + + add r0,sp,r0 @ r0 to point at &tp[num-1] + ldr r8,[r0,#14*4] @ &n0 + ldr r2,[r2] @ bp[0] + ldr r5,[r1],#4 @ ap[0],ap++ + ldr r6,[r3],#4 @ np[0],np++ + ldr r8,[r8] @ *n0 + str r4,[r0,#15*4] @ save &bp[num] + + umull r10,r11,r5,r2 @ ap[0]*bp[0] + str r8,[r0,#14*4] @ save n0 value + mul r8,r10,r8 @ "tp[0]"*n0 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]" + mov r4,sp + +L1st: + ldr r5,[r1],#4 @ ap[j],ap++ + mov r10,r11 + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[0] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne L1st + + adds r12,r12,r11 + ldr r4,[r0,#13*4] @ restore bp + mov r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + mov r7,sp + str r14,[r0,#4] @ tp[num]= + +Louter: + sub r7,r0,r7 @ "original" r0-1 value + sub r1,r1,r7 @ "rewind" ap to &ap[1] + ldr r2,[r4,#4]! @ *(++bp) + sub r3,r3,r7 @ "rewind" np to &np[1] + ldr r5,[r1,#-4] @ ap[0] + ldr r10,[sp] @ tp[0] + ldr r6,[r3,#-4] @ np[0] + ldr r7,[sp,#4] @ tp[1] + + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0] + str r4,[r0,#13*4] @ save bp + mul r8,r10,r8 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]" + mov r4,sp + +Linner: + ldr r5,[r1],#4 @ ap[j],ap++ + adds r10,r11,r7 @ +=tp[j] + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[i] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adc r11,r11,#0 + ldr r7,[r4,#8] @ tp[j+1] + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne Linner + + adds r12,r12,r11 + mov r14,#0 + ldr r4,[r0,#13*4] @ restore bp + adc r14,r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adds r12,r12,r7 + ldr r7,[r0,#15*4] @ restore &bp[num] + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + str r14,[r0,#4] @ tp[num]= + + cmp r4,r7 +#ifdef __thumb2__ + itt ne +#endif + movne r7,sp + bne Louter + + ldr r2,[r0,#12*4] @ pull rp + mov r5,sp + add r0,r0,#4 @ r0 to point at &tp[num] + sub r5,r0,r5 @ "original" num value + mov r4,sp @ "rewind" r4 + mov r1,r4 @ "borrow" r1 + sub r3,r3,r5 @ "rewind" r3 to &np[0] + + subs r7,r7,r7 @ "clear" carry flag +Lsub: ldr r7,[r4],#4 + ldr r6,[r3],#4 + sbcs r7,r7,r6 @ tp[j]-np[j] + str r7,[r2],#4 @ rp[j]= + teq r4,r0 @ preserve carry + bne Lsub + sbcs r14,r14,#0 @ upmost carry + mov r4,sp @ "rewind" r4 + sub r2,r2,r5 @ "rewind" r2 + +Lcopy: ldr r7,[r4] @ conditional copy + ldr r5,[r2] + str sp,[r4],#4 @ zap tp +#ifdef __thumb2__ + it cc +#endif + movcc r5,r7 + str r5,[r2],#4 + teq r4,r0 @ preserve carry + bne Lcopy + + mov sp,r0 + add sp,sp,#4 @ skip over tp[num+1] + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ restore registers + add sp,sp,#2*4 @ skip over {r0,r2} + mov r0,#1 +Labrt: +#if __ARM_ARCH__>=5 + bx lr @ bx lr +#else + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif + +#if __ARM_MAX_ARCH__>=7 + + + +#ifdef __thumb2__ +.thumb_func bn_mul8x_mont_neon +#endif +.align 5 +bn_mul8x_mont_neon: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldmia ip,{r4,r5} @ load rest of parameter block + mov ip,sp + + cmp r5,#8 + bhi LNEON_8n + + @ special case for r5==8, everything is in register bank... + + vld1.32 {d28[0]}, [r2,:32]! + veor d8,d8,d8 + sub r7,sp,r5,lsl#4 + vld1.32 {d0,d1,d2,d3}, [r1]! @ can't specify :32 :-( + and r7,r7,#-64 + vld1.32 {d30[0]}, [r4,:32] + mov sp,r7 @ alloca + vzip.16 d28,d8 + + vmull.u32 q6,d28,d0[0] + vmull.u32 q7,d28,d0[1] + vmull.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmull.u32 q9,d28,d1[1] + + vadd.u64 d29,d29,d12 + veor d8,d8,d8 + vmul.u32 d29,d29,d30 + + vmull.u32 q10,d28,d2[0] + vld1.32 {d4,d5,d6,d7}, [r3]! + vmull.u32 q11,d28,d2[1] + vmull.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmull.u32 q13,d28,d3[1] + + vmlal.u32 q6,d29,d4[0] + sub r9,r5,#1 + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + + vmlal.u32 q10,d29,d6[0] + vmov q5,q6 + vmlal.u32 q11,d29,d6[1] + vmov q6,q7 + vmlal.u32 q12,d29,d7[0] + vmov q7,q8 + vmlal.u32 q13,d29,d7[1] + vmov q8,q9 + vmov q9,q10 + vshr.u64 d10,d10,#16 + vmov q10,q11 + vmov q11,q12 + vadd.u64 d10,d10,d11 + vmov q12,q13 + veor q13,q13 + vshr.u64 d10,d10,#16 + + b LNEON_outer8 + +.align 4 +LNEON_outer8: + vld1.32 {d28[0]}, [r2,:32]! + veor d8,d8,d8 + vzip.16 d28,d8 + vadd.u64 d12,d12,d10 + + vmlal.u32 q6,d28,d0[0] + vmlal.u32 q7,d28,d0[1] + vmlal.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmlal.u32 q9,d28,d1[1] + + vadd.u64 d29,d29,d12 + veor d8,d8,d8 + subs r9,r9,#1 + vmul.u32 d29,d29,d30 + + vmlal.u32 q10,d28,d2[0] + vmlal.u32 q11,d28,d2[1] + vmlal.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q13,d28,d3[1] + + vmlal.u32 q6,d29,d4[0] + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + + vmlal.u32 q10,d29,d6[0] + vmov q5,q6 + vmlal.u32 q11,d29,d6[1] + vmov q6,q7 + vmlal.u32 q12,d29,d7[0] + vmov q7,q8 + vmlal.u32 q13,d29,d7[1] + vmov q8,q9 + vmov q9,q10 + vshr.u64 d10,d10,#16 + vmov q10,q11 + vmov q11,q12 + vadd.u64 d10,d10,d11 + vmov q12,q13 + veor q13,q13 + vshr.u64 d10,d10,#16 + + bne LNEON_outer8 + + vadd.u64 d12,d12,d10 + mov r7,sp + vshr.u64 d10,d12,#16 + mov r8,r5 + vadd.u64 d13,d13,d10 + add r6,sp,#96 + vshr.u64 d10,d13,#16 + vzip.16 d12,d13 + + b LNEON_tail_entry + +.align 4 +LNEON_8n: + veor q6,q6,q6 + sub r7,sp,#128 + veor q7,q7,q7 + sub r7,r7,r5,lsl#4 + veor q8,q8,q8 + and r7,r7,#-64 + veor q9,q9,q9 + mov sp,r7 @ alloca + veor q10,q10,q10 + add r7,r7,#256 + veor q11,q11,q11 + sub r8,r5,#8 + veor q12,q12,q12 + veor q13,q13,q13 + +LNEON_8n_init: + vst1.64 {q6,q7},[r7,:256]! + subs r8,r8,#8 + vst1.64 {q8,q9},[r7,:256]! + vst1.64 {q10,q11},[r7,:256]! + vst1.64 {q12,q13},[r7,:256]! + bne LNEON_8n_init + + add r6,sp,#256 + vld1.32 {d0,d1,d2,d3},[r1]! + add r10,sp,#8 + vld1.32 {d30[0]},[r4,:32] + mov r9,r5 + b LNEON_8n_outer + +.align 4 +LNEON_8n_outer: + vld1.32 {d28[0]},[r2,:32]! @ *b++ + veor d8,d8,d8 + vzip.16 d28,d8 + add r7,sp,#128 + vld1.32 {d4,d5,d6,d7},[r3]! + + vmlal.u32 q6,d28,d0[0] + vmlal.u32 q7,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmlal.u32 q9,d28,d1[1] + vadd.u64 d29,d29,d12 + vmlal.u32 q10,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q11,d28,d2[1] + vst1.32 {d28},[sp,:64] @ put aside smashed b[8*i+0] + vmlal.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q13,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q6,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q7,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q8,d29,d5[0] + vshr.u64 d12,d12,#16 + vmlal.u32 q9,d29,d5[1] + vmlal.u32 q10,d29,d6[0] + vadd.u64 d12,d12,d13 + vmlal.u32 q11,d29,d6[1] + vshr.u64 d12,d12,#16 + vmlal.u32 q12,d29,d7[0] + vmlal.u32 q13,d29,d7[1] + vadd.u64 d14,d14,d12 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+0] + vmlal.u32 q7,d28,d0[0] + vld1.64 {q6},[r6,:128]! + vmlal.u32 q8,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q9,d28,d1[0] + vshl.i64 d29,d15,#16 + vmlal.u32 q10,d28,d1[1] + vadd.u64 d29,d29,d14 + vmlal.u32 q11,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q12,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+1] + vmlal.u32 q13,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q6,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q7,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q8,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q9,d29,d5[0] + vshr.u64 d14,d14,#16 + vmlal.u32 q10,d29,d5[1] + vmlal.u32 q11,d29,d6[0] + vadd.u64 d14,d14,d15 + vmlal.u32 q12,d29,d6[1] + vshr.u64 d14,d14,#16 + vmlal.u32 q13,d29,d7[0] + vmlal.u32 q6,d29,d7[1] + vadd.u64 d16,d16,d14 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+1] + vmlal.u32 q8,d28,d0[0] + vld1.64 {q7},[r6,:128]! + vmlal.u32 q9,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q10,d28,d1[0] + vshl.i64 d29,d17,#16 + vmlal.u32 q11,d28,d1[1] + vadd.u64 d29,d29,d16 + vmlal.u32 q12,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q13,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+2] + vmlal.u32 q6,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q7,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q8,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q9,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q10,d29,d5[0] + vshr.u64 d16,d16,#16 + vmlal.u32 q11,d29,d5[1] + vmlal.u32 q12,d29,d6[0] + vadd.u64 d16,d16,d17 + vmlal.u32 q13,d29,d6[1] + vshr.u64 d16,d16,#16 + vmlal.u32 q6,d29,d7[0] + vmlal.u32 q7,d29,d7[1] + vadd.u64 d18,d18,d16 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+2] + vmlal.u32 q9,d28,d0[0] + vld1.64 {q8},[r6,:128]! + vmlal.u32 q10,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q11,d28,d1[0] + vshl.i64 d29,d19,#16 + vmlal.u32 q12,d28,d1[1] + vadd.u64 d29,d29,d18 + vmlal.u32 q13,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q6,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+3] + vmlal.u32 q7,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q8,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q9,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q10,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q11,d29,d5[0] + vshr.u64 d18,d18,#16 + vmlal.u32 q12,d29,d5[1] + vmlal.u32 q13,d29,d6[0] + vadd.u64 d18,d18,d19 + vmlal.u32 q6,d29,d6[1] + vshr.u64 d18,d18,#16 + vmlal.u32 q7,d29,d7[0] + vmlal.u32 q8,d29,d7[1] + vadd.u64 d20,d20,d18 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+3] + vmlal.u32 q10,d28,d0[0] + vld1.64 {q9},[r6,:128]! + vmlal.u32 q11,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q12,d28,d1[0] + vshl.i64 d29,d21,#16 + vmlal.u32 q13,d28,d1[1] + vadd.u64 d29,d29,d20 + vmlal.u32 q6,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q7,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+4] + vmlal.u32 q8,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q9,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q10,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q11,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q12,d29,d5[0] + vshr.u64 d20,d20,#16 + vmlal.u32 q13,d29,d5[1] + vmlal.u32 q6,d29,d6[0] + vadd.u64 d20,d20,d21 + vmlal.u32 q7,d29,d6[1] + vshr.u64 d20,d20,#16 + vmlal.u32 q8,d29,d7[0] + vmlal.u32 q9,d29,d7[1] + vadd.u64 d22,d22,d20 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+4] + vmlal.u32 q11,d28,d0[0] + vld1.64 {q10},[r6,:128]! + vmlal.u32 q12,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q13,d28,d1[0] + vshl.i64 d29,d23,#16 + vmlal.u32 q6,d28,d1[1] + vadd.u64 d29,d29,d22 + vmlal.u32 q7,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q8,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+5] + vmlal.u32 q9,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q10,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q11,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q12,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q13,d29,d5[0] + vshr.u64 d22,d22,#16 + vmlal.u32 q6,d29,d5[1] + vmlal.u32 q7,d29,d6[0] + vadd.u64 d22,d22,d23 + vmlal.u32 q8,d29,d6[1] + vshr.u64 d22,d22,#16 + vmlal.u32 q9,d29,d7[0] + vmlal.u32 q10,d29,d7[1] + vadd.u64 d24,d24,d22 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+5] + vmlal.u32 q12,d28,d0[0] + vld1.64 {q11},[r6,:128]! + vmlal.u32 q13,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q6,d28,d1[0] + vshl.i64 d29,d25,#16 + vmlal.u32 q7,d28,d1[1] + vadd.u64 d29,d29,d24 + vmlal.u32 q8,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q9,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+6] + vmlal.u32 q10,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q11,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q12,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q13,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q6,d29,d5[0] + vshr.u64 d24,d24,#16 + vmlal.u32 q7,d29,d5[1] + vmlal.u32 q8,d29,d6[0] + vadd.u64 d24,d24,d25 + vmlal.u32 q9,d29,d6[1] + vshr.u64 d24,d24,#16 + vmlal.u32 q10,d29,d7[0] + vmlal.u32 q11,d29,d7[1] + vadd.u64 d26,d26,d24 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+6] + vmlal.u32 q13,d28,d0[0] + vld1.64 {q12},[r6,:128]! + vmlal.u32 q6,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q7,d28,d1[0] + vshl.i64 d29,d27,#16 + vmlal.u32 q8,d28,d1[1] + vadd.u64 d29,d29,d26 + vmlal.u32 q9,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q10,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+7] + vmlal.u32 q11,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q12,d28,d3[1] + vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0] + vmlal.u32 q13,d29,d4[0] + vld1.32 {d0,d1,d2,d3},[r1]! + vmlal.u32 q6,d29,d4[1] + vmlal.u32 q7,d29,d5[0] + vshr.u64 d26,d26,#16 + vmlal.u32 q8,d29,d5[1] + vmlal.u32 q9,d29,d6[0] + vadd.u64 d26,d26,d27 + vmlal.u32 q10,d29,d6[1] + vshr.u64 d26,d26,#16 + vmlal.u32 q11,d29,d7[0] + vmlal.u32 q12,d29,d7[1] + vadd.u64 d12,d12,d26 + vst1.32 {d29},[r10,:64] @ put aside smashed m[8*i+7] + add r10,sp,#8 @ rewind + sub r8,r5,#8 + b LNEON_8n_inner + +.align 4 +LNEON_8n_inner: + subs r8,r8,#8 + vmlal.u32 q6,d28,d0[0] + vld1.64 {q13},[r6,:128] + vmlal.u32 q7,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+0] + vmlal.u32 q8,d28,d1[0] + vld1.32 {d4,d5,d6,d7},[r3]! + vmlal.u32 q9,d28,d1[1] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q10,d28,d2[0] + vmlal.u32 q11,d28,d2[1] + vmlal.u32 q12,d28,d3[0] + vmlal.u32 q13,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+1] + vmlal.u32 q6,d29,d4[0] + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + vmlal.u32 q10,d29,d6[0] + vmlal.u32 q11,d29,d6[1] + vmlal.u32 q12,d29,d7[0] + vmlal.u32 q13,d29,d7[1] + vst1.64 {q6},[r7,:128]! + vmlal.u32 q7,d28,d0[0] + vld1.64 {q6},[r6,:128] + vmlal.u32 q8,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+1] + vmlal.u32 q9,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q10,d28,d1[1] + vmlal.u32 q11,d28,d2[0] + vmlal.u32 q12,d28,d2[1] + vmlal.u32 q13,d28,d3[0] + vmlal.u32 q6,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+2] + vmlal.u32 q7,d29,d4[0] + vmlal.u32 q8,d29,d4[1] + vmlal.u32 q9,d29,d5[0] + vmlal.u32 q10,d29,d5[1] + vmlal.u32 q11,d29,d6[0] + vmlal.u32 q12,d29,d6[1] + vmlal.u32 q13,d29,d7[0] + vmlal.u32 q6,d29,d7[1] + vst1.64 {q7},[r7,:128]! + vmlal.u32 q8,d28,d0[0] + vld1.64 {q7},[r6,:128] + vmlal.u32 q9,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+2] + vmlal.u32 q10,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q11,d28,d1[1] + vmlal.u32 q12,d28,d2[0] + vmlal.u32 q13,d28,d2[1] + vmlal.u32 q6,d28,d3[0] + vmlal.u32 q7,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+3] + vmlal.u32 q8,d29,d4[0] + vmlal.u32 q9,d29,d4[1] + vmlal.u32 q10,d29,d5[0] + vmlal.u32 q11,d29,d5[1] + vmlal.u32 q12,d29,d6[0] + vmlal.u32 q13,d29,d6[1] + vmlal.u32 q6,d29,d7[0] + vmlal.u32 q7,d29,d7[1] + vst1.64 {q8},[r7,:128]! + vmlal.u32 q9,d28,d0[0] + vld1.64 {q8},[r6,:128] + vmlal.u32 q10,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+3] + vmlal.u32 q11,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q12,d28,d1[1] + vmlal.u32 q13,d28,d2[0] + vmlal.u32 q6,d28,d2[1] + vmlal.u32 q7,d28,d3[0] + vmlal.u32 q8,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+4] + vmlal.u32 q9,d29,d4[0] + vmlal.u32 q10,d29,d4[1] + vmlal.u32 q11,d29,d5[0] + vmlal.u32 q12,d29,d5[1] + vmlal.u32 q13,d29,d6[0] + vmlal.u32 q6,d29,d6[1] + vmlal.u32 q7,d29,d7[0] + vmlal.u32 q8,d29,d7[1] + vst1.64 {q9},[r7,:128]! + vmlal.u32 q10,d28,d0[0] + vld1.64 {q9},[r6,:128] + vmlal.u32 q11,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+4] + vmlal.u32 q12,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q13,d28,d1[1] + vmlal.u32 q6,d28,d2[0] + vmlal.u32 q7,d28,d2[1] + vmlal.u32 q8,d28,d3[0] + vmlal.u32 q9,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+5] + vmlal.u32 q10,d29,d4[0] + vmlal.u32 q11,d29,d4[1] + vmlal.u32 q12,d29,d5[0] + vmlal.u32 q13,d29,d5[1] + vmlal.u32 q6,d29,d6[0] + vmlal.u32 q7,d29,d6[1] + vmlal.u32 q8,d29,d7[0] + vmlal.u32 q9,d29,d7[1] + vst1.64 {q10},[r7,:128]! + vmlal.u32 q11,d28,d0[0] + vld1.64 {q10},[r6,:128] + vmlal.u32 q12,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+5] + vmlal.u32 q13,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q6,d28,d1[1] + vmlal.u32 q7,d28,d2[0] + vmlal.u32 q8,d28,d2[1] + vmlal.u32 q9,d28,d3[0] + vmlal.u32 q10,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+6] + vmlal.u32 q11,d29,d4[0] + vmlal.u32 q12,d29,d4[1] + vmlal.u32 q13,d29,d5[0] + vmlal.u32 q6,d29,d5[1] + vmlal.u32 q7,d29,d6[0] + vmlal.u32 q8,d29,d6[1] + vmlal.u32 q9,d29,d7[0] + vmlal.u32 q10,d29,d7[1] + vst1.64 {q11},[r7,:128]! + vmlal.u32 q12,d28,d0[0] + vld1.64 {q11},[r6,:128] + vmlal.u32 q13,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+6] + vmlal.u32 q6,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q7,d28,d1[1] + vmlal.u32 q8,d28,d2[0] + vmlal.u32 q9,d28,d2[1] + vmlal.u32 q10,d28,d3[0] + vmlal.u32 q11,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+7] + vmlal.u32 q12,d29,d4[0] + vmlal.u32 q13,d29,d4[1] + vmlal.u32 q6,d29,d5[0] + vmlal.u32 q7,d29,d5[1] + vmlal.u32 q8,d29,d6[0] + vmlal.u32 q9,d29,d6[1] + vmlal.u32 q10,d29,d7[0] + vmlal.u32 q11,d29,d7[1] + vst1.64 {q12},[r7,:128]! + vmlal.u32 q13,d28,d0[0] + vld1.64 {q12},[r6,:128] + vmlal.u32 q6,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+7] + vmlal.u32 q7,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q8,d28,d1[1] + vmlal.u32 q9,d28,d2[0] + vmlal.u32 q10,d28,d2[1] + vmlal.u32 q11,d28,d3[0] + vmlal.u32 q12,d28,d3[1] + it eq + subeq r1,r1,r5,lsl#2 @ rewind + vmlal.u32 q13,d29,d4[0] + vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0] + vmlal.u32 q6,d29,d4[1] + vld1.32 {d0,d1,d2,d3},[r1]! + vmlal.u32 q7,d29,d5[0] + add r10,sp,#8 @ rewind + vmlal.u32 q8,d29,d5[1] + vmlal.u32 q9,d29,d6[0] + vmlal.u32 q10,d29,d6[1] + vmlal.u32 q11,d29,d7[0] + vst1.64 {q13},[r7,:128]! + vmlal.u32 q12,d29,d7[1] + + bne LNEON_8n_inner + add r6,sp,#128 + vst1.64 {q6,q7},[r7,:256]! + veor q2,q2,q2 @ d4-d5 + vst1.64 {q8,q9},[r7,:256]! + veor q3,q3,q3 @ d6-d7 + vst1.64 {q10,q11},[r7,:256]! + vst1.64 {q12},[r7,:128] + + subs r9,r9,#8 + vld1.64 {q6,q7},[r6,:256]! + vld1.64 {q8,q9},[r6,:256]! + vld1.64 {q10,q11},[r6,:256]! + vld1.64 {q12,q13},[r6,:256]! + + itt ne + subne r3,r3,r5,lsl#2 @ rewind + bne LNEON_8n_outer + + add r7,sp,#128 + vst1.64 {q2,q3}, [sp,:256]! @ start wiping stack frame + vshr.u64 d10,d12,#16 + vst1.64 {q2,q3},[sp,:256]! + vadd.u64 d13,d13,d10 + vst1.64 {q2,q3}, [sp,:256]! + vshr.u64 d10,d13,#16 + vst1.64 {q2,q3}, [sp,:256]! + vzip.16 d12,d13 + + mov r8,r5 + b LNEON_tail_entry + +.align 4 +LNEON_tail: + vadd.u64 d12,d12,d10 + vshr.u64 d10,d12,#16 + vld1.64 {q8,q9}, [r6, :256]! + vadd.u64 d13,d13,d10 + vld1.64 {q10,q11}, [r6, :256]! + vshr.u64 d10,d13,#16 + vld1.64 {q12,q13}, [r6, :256]! + vzip.16 d12,d13 + +LNEON_tail_entry: + vadd.u64 d14,d14,d10 + vst1.32 {d12[0]}, [r7, :32]! + vshr.u64 d10,d14,#16 + vadd.u64 d15,d15,d10 + vshr.u64 d10,d15,#16 + vzip.16 d14,d15 + vadd.u64 d16,d16,d10 + vst1.32 {d14[0]}, [r7, :32]! + vshr.u64 d10,d16,#16 + vadd.u64 d17,d17,d10 + vshr.u64 d10,d17,#16 + vzip.16 d16,d17 + vadd.u64 d18,d18,d10 + vst1.32 {d16[0]}, [r7, :32]! + vshr.u64 d10,d18,#16 + vadd.u64 d19,d19,d10 + vshr.u64 d10,d19,#16 + vzip.16 d18,d19 + vadd.u64 d20,d20,d10 + vst1.32 {d18[0]}, [r7, :32]! + vshr.u64 d10,d20,#16 + vadd.u64 d21,d21,d10 + vshr.u64 d10,d21,#16 + vzip.16 d20,d21 + vadd.u64 d22,d22,d10 + vst1.32 {d20[0]}, [r7, :32]! + vshr.u64 d10,d22,#16 + vadd.u64 d23,d23,d10 + vshr.u64 d10,d23,#16 + vzip.16 d22,d23 + vadd.u64 d24,d24,d10 + vst1.32 {d22[0]}, [r7, :32]! + vshr.u64 d10,d24,#16 + vadd.u64 d25,d25,d10 + vshr.u64 d10,d25,#16 + vzip.16 d24,d25 + vadd.u64 d26,d26,d10 + vst1.32 {d24[0]}, [r7, :32]! + vshr.u64 d10,d26,#16 + vadd.u64 d27,d27,d10 + vshr.u64 d10,d27,#16 + vzip.16 d26,d27 + vld1.64 {q6,q7}, [r6, :256]! + subs r8,r8,#8 + vst1.32 {d26[0]}, [r7, :32]! + bne LNEON_tail + + vst1.32 {d10[0]}, [r7, :32] @ top-most bit + sub r3,r3,r5,lsl#2 @ rewind r3 + subs r1,sp,#0 @ clear carry flag + add r2,sp,r5,lsl#2 + +LNEON_sub: + ldmia r1!, {r4,r5,r6,r7} + ldmia r3!, {r8,r9,r10,r11} + sbcs r8, r4,r8 + sbcs r9, r5,r9 + sbcs r10,r6,r10 + sbcs r11,r7,r11 + teq r1,r2 @ preserves carry + stmia r0!, {r8,r9,r10,r11} + bne LNEON_sub + + ldr r10, [r1] @ load top-most bit + mov r11,sp + veor q0,q0,q0 + sub r11,r2,r11 @ this is num*4 + veor q1,q1,q1 + mov r1,sp + sub r0,r0,r11 @ rewind r0 + mov r3,r2 @ second 3/4th of frame + sbcs r10,r10,#0 @ result is carry flag + +LNEON_copy_n_zap: + ldmia r1!, {r4,r5,r6,r7} + ldmia r0, {r8,r9,r10,r11} + it cc + movcc r8, r4 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + itt cc + movcc r9, r5 + movcc r10,r6 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + it cc + movcc r11,r7 + ldmia r1, {r4,r5,r6,r7} + stmia r0!, {r8,r9,r10,r11} + sub r1,r1,#16 + ldmia r0, {r8,r9,r10,r11} + it cc + movcc r8, r4 + vst1.64 {q0,q1}, [r1,:256]! @ wipe + itt cc + movcc r9, r5 + movcc r10,r6 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + it cc + movcc r11,r7 + teq r1,r2 @ preserves carry + stmia r0!, {r8,r9,r10,r11} + bne LNEON_copy_n_zap + + mov sp,ip + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11} + bx lr @ bx lr + +#endif +.byte 77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 +.comm _OPENSSL_armcap_P,4 +.non_lazy_symbol_pointer +OPENSSL_armcap_P: +.indirect_symbol _OPENSSL_armcap_P +.long 0 +.private_extern _OPENSSL_armcap_P +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S new file mode 100644 index 00000000..de82af55 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S @@ -0,0 +1,984 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. +.arch armv7-a + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + +#if __ARM_MAX_ARCH__>=7 +.align 5 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.Lbn_mul_mont +#endif + +.globl bn_mul_mont +.hidden bn_mul_mont +.type bn_mul_mont,%function + +.align 5 +bn_mul_mont: +.Lbn_mul_mont: + ldr ip,[sp,#4] @ load num + stmdb sp!,{r0,r2} @ sp points at argument block +#if __ARM_MAX_ARCH__>=7 + tst ip,#7 + bne .Lialu + adr r0,.Lbn_mul_mont + ldr r2,.LOPENSSL_armcap + ldr r0,[r0,r2] +#ifdef __APPLE__ + ldr r0,[r0] +#endif + tst r0,#ARMV7_NEON @ NEON available? + ldmia sp, {r0,r2} + beq .Lialu + add sp,sp,#8 + b bn_mul8x_mont_neon +.align 4 +.Lialu: +#endif + cmp ip,#2 + mov r0,ip @ load num +#ifdef __thumb2__ + ittt lt +#endif + movlt r0,#0 + addlt sp,sp,#2*4 + blt .Labrt + + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ save 10 registers + + mov r0,r0,lsl#2 @ rescale r0 for byte count + sub sp,sp,r0 @ alloca(4*num) + sub sp,sp,#4 @ +extra dword + sub r0,r0,#4 @ "num=num-1" + add r4,r2,r0 @ &bp[num-1] + + add r0,sp,r0 @ r0 to point at &tp[num-1] + ldr r8,[r0,#14*4] @ &n0 + ldr r2,[r2] @ bp[0] + ldr r5,[r1],#4 @ ap[0],ap++ + ldr r6,[r3],#4 @ np[0],np++ + ldr r8,[r8] @ *n0 + str r4,[r0,#15*4] @ save &bp[num] + + umull r10,r11,r5,r2 @ ap[0]*bp[0] + str r8,[r0,#14*4] @ save n0 value + mul r8,r10,r8 @ "tp[0]"*n0 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]" + mov r4,sp + +.L1st: + ldr r5,[r1],#4 @ ap[j],ap++ + mov r10,r11 + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[0] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne .L1st + + adds r12,r12,r11 + ldr r4,[r0,#13*4] @ restore bp + mov r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + mov r7,sp + str r14,[r0,#4] @ tp[num]= + +.Louter: + sub r7,r0,r7 @ "original" r0-1 value + sub r1,r1,r7 @ "rewind" ap to &ap[1] + ldr r2,[r4,#4]! @ *(++bp) + sub r3,r3,r7 @ "rewind" np to &np[1] + ldr r5,[r1,#-4] @ ap[0] + ldr r10,[sp] @ tp[0] + ldr r6,[r3,#-4] @ np[0] + ldr r7,[sp,#4] @ tp[1] + + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0] + str r4,[r0,#13*4] @ save bp + mul r8,r10,r8 + mov r12,#0 + umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]" + mov r4,sp + +.Linner: + ldr r5,[r1],#4 @ ap[j],ap++ + adds r10,r11,r7 @ +=tp[j] + ldr r6,[r3],#4 @ np[j],np++ + mov r11,#0 + umlal r10,r11,r5,r2 @ ap[j]*bp[i] + mov r14,#0 + umlal r12,r14,r6,r8 @ np[j]*n0 + adc r11,r11,#0 + ldr r7,[r4,#8] @ tp[j+1] + adds r12,r12,r10 + str r12,[r4],#4 @ tp[j-1]=,tp++ + adc r12,r14,#0 + cmp r4,r0 + bne .Linner + + adds r12,r12,r11 + mov r14,#0 + ldr r4,[r0,#13*4] @ restore bp + adc r14,r14,#0 + ldr r8,[r0,#14*4] @ restore n0 + adds r12,r12,r7 + ldr r7,[r0,#15*4] @ restore &bp[num] + adc r14,r14,#0 + str r12,[r0] @ tp[num-1]= + str r14,[r0,#4] @ tp[num]= + + cmp r4,r7 +#ifdef __thumb2__ + itt ne +#endif + movne r7,sp + bne .Louter + + ldr r2,[r0,#12*4] @ pull rp + mov r5,sp + add r0,r0,#4 @ r0 to point at &tp[num] + sub r5,r0,r5 @ "original" num value + mov r4,sp @ "rewind" r4 + mov r1,r4 @ "borrow" r1 + sub r3,r3,r5 @ "rewind" r3 to &np[0] + + subs r7,r7,r7 @ "clear" carry flag +.Lsub: ldr r7,[r4],#4 + ldr r6,[r3],#4 + sbcs r7,r7,r6 @ tp[j]-np[j] + str r7,[r2],#4 @ rp[j]= + teq r4,r0 @ preserve carry + bne .Lsub + sbcs r14,r14,#0 @ upmost carry + mov r4,sp @ "rewind" r4 + sub r2,r2,r5 @ "rewind" r2 + +.Lcopy: ldr r7,[r4] @ conditional copy + ldr r5,[r2] + str sp,[r4],#4 @ zap tp +#ifdef __thumb2__ + it cc +#endif + movcc r5,r7 + str r5,[r2],#4 + teq r4,r0 @ preserve carry + bne .Lcopy + + mov sp,r0 + add sp,sp,#4 @ skip over tp[num+1] + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ restore registers + add sp,sp,#2*4 @ skip over {r0,r2} + mov r0,#1 +.Labrt: +#if __ARM_ARCH__>=5 + bx lr @ bx lr +#else + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size bn_mul_mont,.-bn_mul_mont +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.type bn_mul8x_mont_neon,%function +.align 5 +bn_mul8x_mont_neon: + mov ip,sp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + ldmia ip,{r4,r5} @ load rest of parameter block + mov ip,sp + + cmp r5,#8 + bhi .LNEON_8n + + @ special case for r5==8, everything is in register bank... + + vld1.32 {d28[0]}, [r2,:32]! + veor d8,d8,d8 + sub r7,sp,r5,lsl#4 + vld1.32 {d0,d1,d2,d3}, [r1]! @ can't specify :32 :-( + and r7,r7,#-64 + vld1.32 {d30[0]}, [r4,:32] + mov sp,r7 @ alloca + vzip.16 d28,d8 + + vmull.u32 q6,d28,d0[0] + vmull.u32 q7,d28,d0[1] + vmull.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmull.u32 q9,d28,d1[1] + + vadd.u64 d29,d29,d12 + veor d8,d8,d8 + vmul.u32 d29,d29,d30 + + vmull.u32 q10,d28,d2[0] + vld1.32 {d4,d5,d6,d7}, [r3]! + vmull.u32 q11,d28,d2[1] + vmull.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmull.u32 q13,d28,d3[1] + + vmlal.u32 q6,d29,d4[0] + sub r9,r5,#1 + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + + vmlal.u32 q10,d29,d6[0] + vmov q5,q6 + vmlal.u32 q11,d29,d6[1] + vmov q6,q7 + vmlal.u32 q12,d29,d7[0] + vmov q7,q8 + vmlal.u32 q13,d29,d7[1] + vmov q8,q9 + vmov q9,q10 + vshr.u64 d10,d10,#16 + vmov q10,q11 + vmov q11,q12 + vadd.u64 d10,d10,d11 + vmov q12,q13 + veor q13,q13 + vshr.u64 d10,d10,#16 + + b .LNEON_outer8 + +.align 4 +.LNEON_outer8: + vld1.32 {d28[0]}, [r2,:32]! + veor d8,d8,d8 + vzip.16 d28,d8 + vadd.u64 d12,d12,d10 + + vmlal.u32 q6,d28,d0[0] + vmlal.u32 q7,d28,d0[1] + vmlal.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmlal.u32 q9,d28,d1[1] + + vadd.u64 d29,d29,d12 + veor d8,d8,d8 + subs r9,r9,#1 + vmul.u32 d29,d29,d30 + + vmlal.u32 q10,d28,d2[0] + vmlal.u32 q11,d28,d2[1] + vmlal.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q13,d28,d3[1] + + vmlal.u32 q6,d29,d4[0] + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + + vmlal.u32 q10,d29,d6[0] + vmov q5,q6 + vmlal.u32 q11,d29,d6[1] + vmov q6,q7 + vmlal.u32 q12,d29,d7[0] + vmov q7,q8 + vmlal.u32 q13,d29,d7[1] + vmov q8,q9 + vmov q9,q10 + vshr.u64 d10,d10,#16 + vmov q10,q11 + vmov q11,q12 + vadd.u64 d10,d10,d11 + vmov q12,q13 + veor q13,q13 + vshr.u64 d10,d10,#16 + + bne .LNEON_outer8 + + vadd.u64 d12,d12,d10 + mov r7,sp + vshr.u64 d10,d12,#16 + mov r8,r5 + vadd.u64 d13,d13,d10 + add r6,sp,#96 + vshr.u64 d10,d13,#16 + vzip.16 d12,d13 + + b .LNEON_tail_entry + +.align 4 +.LNEON_8n: + veor q6,q6,q6 + sub r7,sp,#128 + veor q7,q7,q7 + sub r7,r7,r5,lsl#4 + veor q8,q8,q8 + and r7,r7,#-64 + veor q9,q9,q9 + mov sp,r7 @ alloca + veor q10,q10,q10 + add r7,r7,#256 + veor q11,q11,q11 + sub r8,r5,#8 + veor q12,q12,q12 + veor q13,q13,q13 + +.LNEON_8n_init: + vst1.64 {q6,q7},[r7,:256]! + subs r8,r8,#8 + vst1.64 {q8,q9},[r7,:256]! + vst1.64 {q10,q11},[r7,:256]! + vst1.64 {q12,q13},[r7,:256]! + bne .LNEON_8n_init + + add r6,sp,#256 + vld1.32 {d0,d1,d2,d3},[r1]! + add r10,sp,#8 + vld1.32 {d30[0]},[r4,:32] + mov r9,r5 + b .LNEON_8n_outer + +.align 4 +.LNEON_8n_outer: + vld1.32 {d28[0]},[r2,:32]! @ *b++ + veor d8,d8,d8 + vzip.16 d28,d8 + add r7,sp,#128 + vld1.32 {d4,d5,d6,d7},[r3]! + + vmlal.u32 q6,d28,d0[0] + vmlal.u32 q7,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q8,d28,d1[0] + vshl.i64 d29,d13,#16 + vmlal.u32 q9,d28,d1[1] + vadd.u64 d29,d29,d12 + vmlal.u32 q10,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q11,d28,d2[1] + vst1.32 {d28},[sp,:64] @ put aside smashed b[8*i+0] + vmlal.u32 q12,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q13,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q6,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q7,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q8,d29,d5[0] + vshr.u64 d12,d12,#16 + vmlal.u32 q9,d29,d5[1] + vmlal.u32 q10,d29,d6[0] + vadd.u64 d12,d12,d13 + vmlal.u32 q11,d29,d6[1] + vshr.u64 d12,d12,#16 + vmlal.u32 q12,d29,d7[0] + vmlal.u32 q13,d29,d7[1] + vadd.u64 d14,d14,d12 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+0] + vmlal.u32 q7,d28,d0[0] + vld1.64 {q6},[r6,:128]! + vmlal.u32 q8,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q9,d28,d1[0] + vshl.i64 d29,d15,#16 + vmlal.u32 q10,d28,d1[1] + vadd.u64 d29,d29,d14 + vmlal.u32 q11,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q12,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+1] + vmlal.u32 q13,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q6,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q7,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q8,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q9,d29,d5[0] + vshr.u64 d14,d14,#16 + vmlal.u32 q10,d29,d5[1] + vmlal.u32 q11,d29,d6[0] + vadd.u64 d14,d14,d15 + vmlal.u32 q12,d29,d6[1] + vshr.u64 d14,d14,#16 + vmlal.u32 q13,d29,d7[0] + vmlal.u32 q6,d29,d7[1] + vadd.u64 d16,d16,d14 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+1] + vmlal.u32 q8,d28,d0[0] + vld1.64 {q7},[r6,:128]! + vmlal.u32 q9,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q10,d28,d1[0] + vshl.i64 d29,d17,#16 + vmlal.u32 q11,d28,d1[1] + vadd.u64 d29,d29,d16 + vmlal.u32 q12,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q13,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+2] + vmlal.u32 q6,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q7,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q8,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q9,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q10,d29,d5[0] + vshr.u64 d16,d16,#16 + vmlal.u32 q11,d29,d5[1] + vmlal.u32 q12,d29,d6[0] + vadd.u64 d16,d16,d17 + vmlal.u32 q13,d29,d6[1] + vshr.u64 d16,d16,#16 + vmlal.u32 q6,d29,d7[0] + vmlal.u32 q7,d29,d7[1] + vadd.u64 d18,d18,d16 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+2] + vmlal.u32 q9,d28,d0[0] + vld1.64 {q8},[r6,:128]! + vmlal.u32 q10,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q11,d28,d1[0] + vshl.i64 d29,d19,#16 + vmlal.u32 q12,d28,d1[1] + vadd.u64 d29,d29,d18 + vmlal.u32 q13,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q6,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+3] + vmlal.u32 q7,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q8,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q9,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q10,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q11,d29,d5[0] + vshr.u64 d18,d18,#16 + vmlal.u32 q12,d29,d5[1] + vmlal.u32 q13,d29,d6[0] + vadd.u64 d18,d18,d19 + vmlal.u32 q6,d29,d6[1] + vshr.u64 d18,d18,#16 + vmlal.u32 q7,d29,d7[0] + vmlal.u32 q8,d29,d7[1] + vadd.u64 d20,d20,d18 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+3] + vmlal.u32 q10,d28,d0[0] + vld1.64 {q9},[r6,:128]! + vmlal.u32 q11,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q12,d28,d1[0] + vshl.i64 d29,d21,#16 + vmlal.u32 q13,d28,d1[1] + vadd.u64 d29,d29,d20 + vmlal.u32 q6,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q7,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+4] + vmlal.u32 q8,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q9,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q10,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q11,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q12,d29,d5[0] + vshr.u64 d20,d20,#16 + vmlal.u32 q13,d29,d5[1] + vmlal.u32 q6,d29,d6[0] + vadd.u64 d20,d20,d21 + vmlal.u32 q7,d29,d6[1] + vshr.u64 d20,d20,#16 + vmlal.u32 q8,d29,d7[0] + vmlal.u32 q9,d29,d7[1] + vadd.u64 d22,d22,d20 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+4] + vmlal.u32 q11,d28,d0[0] + vld1.64 {q10},[r6,:128]! + vmlal.u32 q12,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q13,d28,d1[0] + vshl.i64 d29,d23,#16 + vmlal.u32 q6,d28,d1[1] + vadd.u64 d29,d29,d22 + vmlal.u32 q7,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q8,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+5] + vmlal.u32 q9,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q10,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q11,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q12,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q13,d29,d5[0] + vshr.u64 d22,d22,#16 + vmlal.u32 q6,d29,d5[1] + vmlal.u32 q7,d29,d6[0] + vadd.u64 d22,d22,d23 + vmlal.u32 q8,d29,d6[1] + vshr.u64 d22,d22,#16 + vmlal.u32 q9,d29,d7[0] + vmlal.u32 q10,d29,d7[1] + vadd.u64 d24,d24,d22 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+5] + vmlal.u32 q12,d28,d0[0] + vld1.64 {q11},[r6,:128]! + vmlal.u32 q13,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q6,d28,d1[0] + vshl.i64 d29,d25,#16 + vmlal.u32 q7,d28,d1[1] + vadd.u64 d29,d29,d24 + vmlal.u32 q8,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q9,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+6] + vmlal.u32 q10,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q11,d28,d3[1] + vld1.32 {d28[0]},[r2,:32]! @ *b++ + vmlal.u32 q12,d29,d4[0] + veor d10,d10,d10 + vmlal.u32 q13,d29,d4[1] + vzip.16 d28,d10 + vmlal.u32 q6,d29,d5[0] + vshr.u64 d24,d24,#16 + vmlal.u32 q7,d29,d5[1] + vmlal.u32 q8,d29,d6[0] + vadd.u64 d24,d24,d25 + vmlal.u32 q9,d29,d6[1] + vshr.u64 d24,d24,#16 + vmlal.u32 q10,d29,d7[0] + vmlal.u32 q11,d29,d7[1] + vadd.u64 d26,d26,d24 + vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+6] + vmlal.u32 q13,d28,d0[0] + vld1.64 {q12},[r6,:128]! + vmlal.u32 q6,d28,d0[1] + veor d8,d8,d8 + vmlal.u32 q7,d28,d1[0] + vshl.i64 d29,d27,#16 + vmlal.u32 q8,d28,d1[1] + vadd.u64 d29,d29,d26 + vmlal.u32 q9,d28,d2[0] + vmul.u32 d29,d29,d30 + vmlal.u32 q10,d28,d2[1] + vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+7] + vmlal.u32 q11,d28,d3[0] + vzip.16 d29,d8 + vmlal.u32 q12,d28,d3[1] + vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0] + vmlal.u32 q13,d29,d4[0] + vld1.32 {d0,d1,d2,d3},[r1]! + vmlal.u32 q6,d29,d4[1] + vmlal.u32 q7,d29,d5[0] + vshr.u64 d26,d26,#16 + vmlal.u32 q8,d29,d5[1] + vmlal.u32 q9,d29,d6[0] + vadd.u64 d26,d26,d27 + vmlal.u32 q10,d29,d6[1] + vshr.u64 d26,d26,#16 + vmlal.u32 q11,d29,d7[0] + vmlal.u32 q12,d29,d7[1] + vadd.u64 d12,d12,d26 + vst1.32 {d29},[r10,:64] @ put aside smashed m[8*i+7] + add r10,sp,#8 @ rewind + sub r8,r5,#8 + b .LNEON_8n_inner + +.align 4 +.LNEON_8n_inner: + subs r8,r8,#8 + vmlal.u32 q6,d28,d0[0] + vld1.64 {q13},[r6,:128] + vmlal.u32 q7,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+0] + vmlal.u32 q8,d28,d1[0] + vld1.32 {d4,d5,d6,d7},[r3]! + vmlal.u32 q9,d28,d1[1] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q10,d28,d2[0] + vmlal.u32 q11,d28,d2[1] + vmlal.u32 q12,d28,d3[0] + vmlal.u32 q13,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+1] + vmlal.u32 q6,d29,d4[0] + vmlal.u32 q7,d29,d4[1] + vmlal.u32 q8,d29,d5[0] + vmlal.u32 q9,d29,d5[1] + vmlal.u32 q10,d29,d6[0] + vmlal.u32 q11,d29,d6[1] + vmlal.u32 q12,d29,d7[0] + vmlal.u32 q13,d29,d7[1] + vst1.64 {q6},[r7,:128]! + vmlal.u32 q7,d28,d0[0] + vld1.64 {q6},[r6,:128] + vmlal.u32 q8,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+1] + vmlal.u32 q9,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q10,d28,d1[1] + vmlal.u32 q11,d28,d2[0] + vmlal.u32 q12,d28,d2[1] + vmlal.u32 q13,d28,d3[0] + vmlal.u32 q6,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+2] + vmlal.u32 q7,d29,d4[0] + vmlal.u32 q8,d29,d4[1] + vmlal.u32 q9,d29,d5[0] + vmlal.u32 q10,d29,d5[1] + vmlal.u32 q11,d29,d6[0] + vmlal.u32 q12,d29,d6[1] + vmlal.u32 q13,d29,d7[0] + vmlal.u32 q6,d29,d7[1] + vst1.64 {q7},[r7,:128]! + vmlal.u32 q8,d28,d0[0] + vld1.64 {q7},[r6,:128] + vmlal.u32 q9,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+2] + vmlal.u32 q10,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q11,d28,d1[1] + vmlal.u32 q12,d28,d2[0] + vmlal.u32 q13,d28,d2[1] + vmlal.u32 q6,d28,d3[0] + vmlal.u32 q7,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+3] + vmlal.u32 q8,d29,d4[0] + vmlal.u32 q9,d29,d4[1] + vmlal.u32 q10,d29,d5[0] + vmlal.u32 q11,d29,d5[1] + vmlal.u32 q12,d29,d6[0] + vmlal.u32 q13,d29,d6[1] + vmlal.u32 q6,d29,d7[0] + vmlal.u32 q7,d29,d7[1] + vst1.64 {q8},[r7,:128]! + vmlal.u32 q9,d28,d0[0] + vld1.64 {q8},[r6,:128] + vmlal.u32 q10,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+3] + vmlal.u32 q11,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q12,d28,d1[1] + vmlal.u32 q13,d28,d2[0] + vmlal.u32 q6,d28,d2[1] + vmlal.u32 q7,d28,d3[0] + vmlal.u32 q8,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+4] + vmlal.u32 q9,d29,d4[0] + vmlal.u32 q10,d29,d4[1] + vmlal.u32 q11,d29,d5[0] + vmlal.u32 q12,d29,d5[1] + vmlal.u32 q13,d29,d6[0] + vmlal.u32 q6,d29,d6[1] + vmlal.u32 q7,d29,d7[0] + vmlal.u32 q8,d29,d7[1] + vst1.64 {q9},[r7,:128]! + vmlal.u32 q10,d28,d0[0] + vld1.64 {q9},[r6,:128] + vmlal.u32 q11,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+4] + vmlal.u32 q12,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q13,d28,d1[1] + vmlal.u32 q6,d28,d2[0] + vmlal.u32 q7,d28,d2[1] + vmlal.u32 q8,d28,d3[0] + vmlal.u32 q9,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+5] + vmlal.u32 q10,d29,d4[0] + vmlal.u32 q11,d29,d4[1] + vmlal.u32 q12,d29,d5[0] + vmlal.u32 q13,d29,d5[1] + vmlal.u32 q6,d29,d6[0] + vmlal.u32 q7,d29,d6[1] + vmlal.u32 q8,d29,d7[0] + vmlal.u32 q9,d29,d7[1] + vst1.64 {q10},[r7,:128]! + vmlal.u32 q11,d28,d0[0] + vld1.64 {q10},[r6,:128] + vmlal.u32 q12,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+5] + vmlal.u32 q13,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q6,d28,d1[1] + vmlal.u32 q7,d28,d2[0] + vmlal.u32 q8,d28,d2[1] + vmlal.u32 q9,d28,d3[0] + vmlal.u32 q10,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+6] + vmlal.u32 q11,d29,d4[0] + vmlal.u32 q12,d29,d4[1] + vmlal.u32 q13,d29,d5[0] + vmlal.u32 q6,d29,d5[1] + vmlal.u32 q7,d29,d6[0] + vmlal.u32 q8,d29,d6[1] + vmlal.u32 q9,d29,d7[0] + vmlal.u32 q10,d29,d7[1] + vst1.64 {q11},[r7,:128]! + vmlal.u32 q12,d28,d0[0] + vld1.64 {q11},[r6,:128] + vmlal.u32 q13,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+6] + vmlal.u32 q6,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q7,d28,d1[1] + vmlal.u32 q8,d28,d2[0] + vmlal.u32 q9,d28,d2[1] + vmlal.u32 q10,d28,d3[0] + vmlal.u32 q11,d28,d3[1] + vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+7] + vmlal.u32 q12,d29,d4[0] + vmlal.u32 q13,d29,d4[1] + vmlal.u32 q6,d29,d5[0] + vmlal.u32 q7,d29,d5[1] + vmlal.u32 q8,d29,d6[0] + vmlal.u32 q9,d29,d6[1] + vmlal.u32 q10,d29,d7[0] + vmlal.u32 q11,d29,d7[1] + vst1.64 {q12},[r7,:128]! + vmlal.u32 q13,d28,d0[0] + vld1.64 {q12},[r6,:128] + vmlal.u32 q6,d28,d0[1] + vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+7] + vmlal.u32 q7,d28,d1[0] + it ne + addne r6,r6,#16 @ don't advance in last iteration + vmlal.u32 q8,d28,d1[1] + vmlal.u32 q9,d28,d2[0] + vmlal.u32 q10,d28,d2[1] + vmlal.u32 q11,d28,d3[0] + vmlal.u32 q12,d28,d3[1] + it eq + subeq r1,r1,r5,lsl#2 @ rewind + vmlal.u32 q13,d29,d4[0] + vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0] + vmlal.u32 q6,d29,d4[1] + vld1.32 {d0,d1,d2,d3},[r1]! + vmlal.u32 q7,d29,d5[0] + add r10,sp,#8 @ rewind + vmlal.u32 q8,d29,d5[1] + vmlal.u32 q9,d29,d6[0] + vmlal.u32 q10,d29,d6[1] + vmlal.u32 q11,d29,d7[0] + vst1.64 {q13},[r7,:128]! + vmlal.u32 q12,d29,d7[1] + + bne .LNEON_8n_inner + add r6,sp,#128 + vst1.64 {q6,q7},[r7,:256]! + veor q2,q2,q2 @ d4-d5 + vst1.64 {q8,q9},[r7,:256]! + veor q3,q3,q3 @ d6-d7 + vst1.64 {q10,q11},[r7,:256]! + vst1.64 {q12},[r7,:128] + + subs r9,r9,#8 + vld1.64 {q6,q7},[r6,:256]! + vld1.64 {q8,q9},[r6,:256]! + vld1.64 {q10,q11},[r6,:256]! + vld1.64 {q12,q13},[r6,:256]! + + itt ne + subne r3,r3,r5,lsl#2 @ rewind + bne .LNEON_8n_outer + + add r7,sp,#128 + vst1.64 {q2,q3}, [sp,:256]! @ start wiping stack frame + vshr.u64 d10,d12,#16 + vst1.64 {q2,q3},[sp,:256]! + vadd.u64 d13,d13,d10 + vst1.64 {q2,q3}, [sp,:256]! + vshr.u64 d10,d13,#16 + vst1.64 {q2,q3}, [sp,:256]! + vzip.16 d12,d13 + + mov r8,r5 + b .LNEON_tail_entry + +.align 4 +.LNEON_tail: + vadd.u64 d12,d12,d10 + vshr.u64 d10,d12,#16 + vld1.64 {q8,q9}, [r6, :256]! + vadd.u64 d13,d13,d10 + vld1.64 {q10,q11}, [r6, :256]! + vshr.u64 d10,d13,#16 + vld1.64 {q12,q13}, [r6, :256]! + vzip.16 d12,d13 + +.LNEON_tail_entry: + vadd.u64 d14,d14,d10 + vst1.32 {d12[0]}, [r7, :32]! + vshr.u64 d10,d14,#16 + vadd.u64 d15,d15,d10 + vshr.u64 d10,d15,#16 + vzip.16 d14,d15 + vadd.u64 d16,d16,d10 + vst1.32 {d14[0]}, [r7, :32]! + vshr.u64 d10,d16,#16 + vadd.u64 d17,d17,d10 + vshr.u64 d10,d17,#16 + vzip.16 d16,d17 + vadd.u64 d18,d18,d10 + vst1.32 {d16[0]}, [r7, :32]! + vshr.u64 d10,d18,#16 + vadd.u64 d19,d19,d10 + vshr.u64 d10,d19,#16 + vzip.16 d18,d19 + vadd.u64 d20,d20,d10 + vst1.32 {d18[0]}, [r7, :32]! + vshr.u64 d10,d20,#16 + vadd.u64 d21,d21,d10 + vshr.u64 d10,d21,#16 + vzip.16 d20,d21 + vadd.u64 d22,d22,d10 + vst1.32 {d20[0]}, [r7, :32]! + vshr.u64 d10,d22,#16 + vadd.u64 d23,d23,d10 + vshr.u64 d10,d23,#16 + vzip.16 d22,d23 + vadd.u64 d24,d24,d10 + vst1.32 {d22[0]}, [r7, :32]! + vshr.u64 d10,d24,#16 + vadd.u64 d25,d25,d10 + vshr.u64 d10,d25,#16 + vzip.16 d24,d25 + vadd.u64 d26,d26,d10 + vst1.32 {d24[0]}, [r7, :32]! + vshr.u64 d10,d26,#16 + vadd.u64 d27,d27,d10 + vshr.u64 d10,d27,#16 + vzip.16 d26,d27 + vld1.64 {q6,q7}, [r6, :256]! + subs r8,r8,#8 + vst1.32 {d26[0]}, [r7, :32]! + bne .LNEON_tail + + vst1.32 {d10[0]}, [r7, :32] @ top-most bit + sub r3,r3,r5,lsl#2 @ rewind r3 + subs r1,sp,#0 @ clear carry flag + add r2,sp,r5,lsl#2 + +.LNEON_sub: + ldmia r1!, {r4,r5,r6,r7} + ldmia r3!, {r8,r9,r10,r11} + sbcs r8, r4,r8 + sbcs r9, r5,r9 + sbcs r10,r6,r10 + sbcs r11,r7,r11 + teq r1,r2 @ preserves carry + stmia r0!, {r8,r9,r10,r11} + bne .LNEON_sub + + ldr r10, [r1] @ load top-most bit + mov r11,sp + veor q0,q0,q0 + sub r11,r2,r11 @ this is num*4 + veor q1,q1,q1 + mov r1,sp + sub r0,r0,r11 @ rewind r0 + mov r3,r2 @ second 3/4th of frame + sbcs r10,r10,#0 @ result is carry flag + +.LNEON_copy_n_zap: + ldmia r1!, {r4,r5,r6,r7} + ldmia r0, {r8,r9,r10,r11} + it cc + movcc r8, r4 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + itt cc + movcc r9, r5 + movcc r10,r6 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + it cc + movcc r11,r7 + ldmia r1, {r4,r5,r6,r7} + stmia r0!, {r8,r9,r10,r11} + sub r1,r1,#16 + ldmia r0, {r8,r9,r10,r11} + it cc + movcc r8, r4 + vst1.64 {q0,q1}, [r1,:256]! @ wipe + itt cc + movcc r9, r5 + movcc r10,r6 + vst1.64 {q0,q1}, [r3,:256]! @ wipe + it cc + movcc r11,r7 + teq r1,r2 @ preserves carry + stmia r0!, {r8,r9,r10,r11} + bne .LNEON_copy_n_zap + + mov sp,ip + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11} + bx lr @ bx lr +.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon +#endif +.byte 77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 +.comm OPENSSL_armcap_P,4,4 +.hidden OPENSSL_armcap_P +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S new file mode 100644 index 00000000..5e3c0501 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S @@ -0,0 +1,1440 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +.globl _bn_mul_mont +.private_extern _bn_mul_mont + +.align 5 +_bn_mul_mont: + AARCH64_SIGN_LINK_REGISTER + tst x5,#7 + b.eq __bn_sqr8x_mont + tst x5,#3 + b.eq __bn_mul4x_mont +Lmul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + ldr x9,[x2],#8 // bp[0] + sub x22,sp,x5,lsl#3 + ldp x7,x8,[x1],#16 // ap[0..1] + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + and x22,x22,#-16 // ABI says so + ldp x13,x14,[x3],#16 // np[0..1] + + mul x6,x7,x9 // ap[0]*bp[0] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + mul x10,x8,x9 // ap[1]*bp[0] + umulh x11,x8,x9 + + mul x15,x6,x4 // "tp[0]"*n0 + mov sp,x22 // alloca + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 // discarded + // (*) As for removal of first multiplication and addition + // instructions. The outcome of first addition is + // guaranteed to be zero, which leaves two computationally + // significant outcomes: it either carries or not. Then + // question is when does it carry? Is there alternative + // way to deduce it? If you follow operations, you can + // observe that condition for carry is quite simple: + // x6 being non-zero. So that carry can be calculated + // by adding -1 to x6. That's what next instruction does. + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + adc x13,x13,xzr + cbz x21,L1st_skip + +L1st: + ldr x8,[x1],#8 + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + ldr x14,[x3],#8 + adds x12,x16,x13 + mul x10,x8,x9 // ap[j]*bp[0] + adc x13,x17,xzr + umulh x11,x8,x9 + + adds x12,x12,x6 + mul x16,x14,x15 // np[j]*m1 + adc x13,x13,xzr + umulh x17,x14,x15 + str x12,[x22],#8 // tp[j-1] + cbnz x21,L1st + +L1st_skip: + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adc x13,x17,xzr + + adds x12,x12,x6 + sub x20,x5,#8 // i=num-1 + adcs x13,x13,x7 + + adc x19,xzr,xzr // upmost overflow bit + stp x12,x13,[x22] + +Louter: + ldr x9,[x2],#8 // bp[i] + ldp x7,x8,[x1],#16 + ldr x23,[sp] // tp[0] + add x22,sp,#8 + + mul x6,x7,x9 // ap[0]*bp[i] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + ldp x13,x14,[x3],#16 + mul x10,x8,x9 // ap[1]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x15,x6,x4 + sub x20,x20,#8 // i-- + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + cbz x21,Linner_skip + +Linner: + ldr x8,[x1],#8 + adc x13,x13,xzr + ldr x23,[x22],#8 // tp[j] + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + adds x12,x16,x13 + ldr x14,[x3],#8 + adc x13,x17,xzr + + mul x10,x8,x9 // ap[j]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x16,x14,x15 // np[j]*m1 + adds x12,x12,x6 + umulh x17,x14,x15 + str x12,[x22,#-16] // tp[j-1] + cbnz x21,Linner + +Linner_skip: + ldr x23,[x22],#8 // tp[j] + adc x13,x13,xzr + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adcs x13,x17,x19 + adc x19,xzr,xzr + + adds x6,x6,x23 + adc x7,x7,xzr + + adds x12,x12,x6 + adcs x13,x13,x7 + adc x19,x19,xzr // upmost overflow bit + stp x12,x13,[x22,#-16] + + cbnz x20,Louter + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x14,[x3],#8 // np[0] + subs x21,x5,#8 // j=num-1 and clear borrow + mov x1,x0 +Lsub: + sbcs x8,x23,x14 // tp[j]-np[j] + ldr x23,[x22],#8 + sub x21,x21,#8 // j-- + ldr x14,[x3],#8 + str x8,[x1],#8 // rp[j]=tp[j]-np[j] + cbnz x21,Lsub + + sbcs x8,x23,x14 + sbcs x19,x19,xzr // did it borrow? + str x8,[x1],#8 // rp[num-1] + + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x8,[x0],#8 // rp[0] + sub x5,x5,#8 // num-- + nop +Lcond_copy: + sub x5,x5,#8 // num-- + csel x14,x23,x8,lo // did it borrow? + ldr x23,[x22],#8 + ldr x8,[x0],#8 + str xzr,[x22,#-16] // wipe tp + str x14,[x0,#-16] + cbnz x5,Lcond_copy + + csel x14,x23,x8,lo + str xzr,[x22,#-8] // wipe tp + str x14,[x0,#-8] + + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldr x29,[sp],#64 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.align 5 +__bn_sqr8x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to + // only from bn_mul_mont which has already signed the return address. + cmp x1,x2 + b.ne __bn_mul4x_mont +Lsqr8x_mont: + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x3,[sp,#96] // offload rp and np + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + ldp x12,x13,[x1,#8*6] + + sub x2,sp,x5,lsl#4 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + mov sp,x2 // alloca + sub x27,x5,#8*8 + b Lsqr8x_zero_start + +Lsqr8x_zero: + sub x27,x27,#8*8 + stp xzr,xzr,[x2,#8*0] + stp xzr,xzr,[x2,#8*2] + stp xzr,xzr,[x2,#8*4] + stp xzr,xzr,[x2,#8*6] +Lsqr8x_zero_start: + stp xzr,xzr,[x2,#8*8] + stp xzr,xzr,[x2,#8*10] + stp xzr,xzr,[x2,#8*12] + stp xzr,xzr,[x2,#8*14] + add x2,x2,#8*16 + cbnz x27,Lsqr8x_zero + + add x3,x1,x5 + add x1,x1,#8*8 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + mov x23,xzr + mov x24,xzr + mov x25,xzr + mov x26,xzr + mov x2,sp + str x4,[x29,#112] // offload n0 + + // Multiply everything but a[i]*a[i] +.align 4 +Lsqr8x_outer_loop: + // a[1]a[0] (i) + // a[2]a[0] + // a[3]a[0] + // a[4]a[0] + // a[5]a[0] + // a[6]a[0] + // a[7]a[0] + // a[2]a[1] (ii) + // a[3]a[1] + // a[4]a[1] + // a[5]a[1] + // a[6]a[1] + // a[7]a[1] + // a[3]a[2] (iii) + // a[4]a[2] + // a[5]a[2] + // a[6]a[2] + // a[7]a[2] + // a[4]a[3] (iv) + // a[5]a[3] + // a[6]a[3] + // a[7]a[3] + // a[5]a[4] (v) + // a[6]a[4] + // a[7]a[4] + // a[6]a[5] (vi) + // a[7]a[5] + // a[7]a[6] (vii) + + mul x14,x7,x6 // lo(a[1..7]*a[0]) (i) + mul x15,x8,x6 + mul x16,x9,x6 + mul x17,x10,x6 + adds x20,x20,x14 // t[1]+lo(a[1]*a[0]) + mul x14,x11,x6 + adcs x21,x21,x15 + mul x15,x12,x6 + adcs x22,x22,x16 + mul x16,x13,x6 + adcs x23,x23,x17 + umulh x17,x7,x6 // hi(a[1..7]*a[0]) + adcs x24,x24,x14 + umulh x14,x8,x6 + adcs x25,x25,x15 + umulh x15,x9,x6 + adcs x26,x26,x16 + umulh x16,x10,x6 + stp x19,x20,[x2],#8*2 // t[0..1] + adc x19,xzr,xzr // t[8] + adds x21,x21,x17 // t[2]+lo(a[1]*a[0]) + umulh x17,x11,x6 + adcs x22,x22,x14 + umulh x14,x12,x6 + adcs x23,x23,x15 + umulh x15,x13,x6 + adcs x24,x24,x16 + mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii) + adcs x25,x25,x17 + mul x17,x9,x7 + adcs x26,x26,x14 + mul x14,x10,x7 + adc x19,x19,x15 + + mul x15,x11,x7 + adds x22,x22,x16 + mul x16,x12,x7 + adcs x23,x23,x17 + mul x17,x13,x7 + adcs x24,x24,x14 + umulh x14,x8,x7 // hi(a[2..7]*a[1]) + adcs x25,x25,x15 + umulh x15,x9,x7 + adcs x26,x26,x16 + umulh x16,x10,x7 + adcs x19,x19,x17 + umulh x17,x11,x7 + stp x21,x22,[x2],#8*2 // t[2..3] + adc x20,xzr,xzr // t[9] + adds x23,x23,x14 + umulh x14,x12,x7 + adcs x24,x24,x15 + umulh x15,x13,x7 + adcs x25,x25,x16 + mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii) + adcs x26,x26,x17 + mul x17,x10,x8 + adcs x19,x19,x14 + mul x14,x11,x8 + adc x20,x20,x15 + + mul x15,x12,x8 + adds x24,x24,x16 + mul x16,x13,x8 + adcs x25,x25,x17 + umulh x17,x9,x8 // hi(a[3..7]*a[2]) + adcs x26,x26,x14 + umulh x14,x10,x8 + adcs x19,x19,x15 + umulh x15,x11,x8 + adcs x20,x20,x16 + umulh x16,x12,x8 + stp x23,x24,[x2],#8*2 // t[4..5] + adc x21,xzr,xzr // t[10] + adds x25,x25,x17 + umulh x17,x13,x8 + adcs x26,x26,x14 + mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv) + adcs x19,x19,x15 + mul x15,x11,x9 + adcs x20,x20,x16 + mul x16,x12,x9 + adc x21,x21,x17 + + mul x17,x13,x9 + adds x26,x26,x14 + umulh x14,x10,x9 // hi(a[4..7]*a[3]) + adcs x19,x19,x15 + umulh x15,x11,x9 + adcs x20,x20,x16 + umulh x16,x12,x9 + adcs x21,x21,x17 + umulh x17,x13,x9 + stp x25,x26,[x2],#8*2 // t[6..7] + adc x22,xzr,xzr // t[11] + adds x19,x19,x14 + mul x14,x11,x10 // lo(a[5..7]*a[4]) (v) + adcs x20,x20,x15 + mul x15,x12,x10 + adcs x21,x21,x16 + mul x16,x13,x10 + adc x22,x22,x17 + + umulh x17,x11,x10 // hi(a[5..7]*a[4]) + adds x20,x20,x14 + umulh x14,x12,x10 + adcs x21,x21,x15 + umulh x15,x13,x10 + adcs x22,x22,x16 + mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi) + adc x23,xzr,xzr // t[12] + adds x21,x21,x17 + mul x17,x13,x11 + adcs x22,x22,x14 + umulh x14,x12,x11 // hi(a[6..7]*a[5]) + adc x23,x23,x15 + + umulh x15,x13,x11 + adds x22,x22,x16 + mul x16,x13,x12 // lo(a[7]*a[6]) (vii) + adcs x23,x23,x17 + umulh x17,x13,x12 // hi(a[7]*a[6]) + adc x24,xzr,xzr // t[13] + adds x23,x23,x14 + sub x27,x3,x1 // done yet? + adc x24,x24,x15 + + adds x24,x24,x16 + sub x14,x3,x5 // rewinded ap + adc x25,xzr,xzr // t[14] + add x25,x25,x17 + + cbz x27,Lsqr8x_outer_break + + mov x4,x6 + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x0,x1 + adcs x26,xzr,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved below + mov x27,#-8*8 + + // a[8]a[0] + // a[9]a[0] + // a[a]a[0] + // a[b]a[0] + // a[c]a[0] + // a[d]a[0] + // a[e]a[0] + // a[f]a[0] + // a[8]a[1] + // a[f]a[1]........................ + // a[8]a[2] + // a[f]a[2]........................ + // a[8]a[3] + // a[f]a[3]........................ + // a[8]a[4] + // a[f]a[4]........................ + // a[8]a[5] + // a[f]a[5]........................ + // a[8]a[6] + // a[f]a[6]........................ + // a[8]a[7] + // a[f]a[7]........................ +Lsqr8x_mul: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,Lsqr8x_mul + // note that carry flag is guaranteed + // to be zero at this point + cmp x1,x3 // done yet? + b.eq Lsqr8x_break + + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + ldr x4,[x0,#-8*8] + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b Lsqr8x_mul + +.align 4 +Lsqr8x_break: + ldp x6,x7,[x0,#8*0] + add x1,x0,#8*8 + ldp x8,x9,[x0,#8*2] + sub x14,x3,x1 // is it last iteration? + ldp x10,x11,[x0,#8*4] + sub x15,x2,x14 + ldp x12,x13,[x0,#8*6] + cbz x14,Lsqr8x_outer_loop + + stp x19,x20,[x2,#8*0] + ldp x19,x20,[x15,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x15,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x15,#8*4] + stp x25,x26,[x2,#8*6] + mov x2,x15 + ldp x25,x26,[x15,#8*6] + b Lsqr8x_outer_loop + +.align 4 +Lsqr8x_outer_break: + // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0] + ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0] + ldp x15,x16,[sp,#8*1] + ldp x11,x13,[x14,#8*2] + add x1,x14,#8*4 + ldp x17,x14,[sp,#8*3] + + stp x19,x20,[x2,#8*0] + mul x19,x7,x7 + stp x21,x22,[x2,#8*2] + umulh x7,x7,x7 + stp x23,x24,[x2,#8*4] + mul x8,x9,x9 + stp x25,x26,[x2,#8*6] + mov x2,sp + umulh x9,x9,x9 + adds x20,x7,x15,lsl#1 + extr x15,x16,x15,#63 + sub x27,x5,#8*4 + +Lsqr4x_shift_n_add: + adcs x21,x8,x15 + extr x16,x17,x16,#63 + sub x27,x27,#8*4 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + ldp x7,x9,[x1],#8*2 + umulh x11,x11,x11 + mul x12,x13,x13 + umulh x13,x13,x13 + extr x17,x14,x17,#63 + stp x19,x20,[x2,#8*0] + adcs x23,x10,x17 + extr x14,x15,x14,#63 + stp x21,x22,[x2,#8*2] + adcs x24,x11,x14 + ldp x17,x14,[x2,#8*7] + extr x15,x16,x15,#63 + adcs x25,x12,x15 + extr x16,x17,x16,#63 + adcs x26,x13,x16 + ldp x15,x16,[x2,#8*9] + mul x6,x7,x7 + ldp x11,x13,[x1],#8*2 + umulh x7,x7,x7 + mul x8,x9,x9 + umulh x9,x9,x9 + stp x23,x24,[x2,#8*4] + extr x17,x14,x17,#63 + stp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + adcs x19,x6,x17 + extr x14,x15,x14,#63 + adcs x20,x7,x14 + ldp x17,x14,[x2,#8*3] + extr x15,x16,x15,#63 + cbnz x27,Lsqr4x_shift_n_add + ldp x1,x4,[x29,#104] // pull np and n0 + + adcs x21,x8,x15 + extr x16,x17,x16,#63 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + umulh x11,x11,x11 + stp x19,x20,[x2,#8*0] + mul x12,x13,x13 + umulh x13,x13,x13 + stp x21,x22,[x2,#8*2] + extr x17,x14,x17,#63 + adcs x23,x10,x17 + extr x14,x15,x14,#63 + ldp x19,x20,[sp,#8*0] + adcs x24,x11,x14 + extr x15,x16,x15,#63 + ldp x6,x7,[x1,#8*0] + adcs x25,x12,x15 + extr x16,xzr,x16,#63 + ldp x8,x9,[x1,#8*2] + adc x26,x13,x16 + ldp x10,x11,[x1,#8*4] + + // Reduce by 512 bits per iteration + mul x28,x4,x19 // t[0]*n0 + ldp x12,x13,[x1,#8*6] + add x3,x1,x5 + ldp x21,x22,[sp,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[sp,#8*4] + stp x25,x26,[x2,#8*6] + ldp x25,x26,[sp,#8*6] + add x1,x1,#8*8 + mov x30,xzr // initial top-most carry + mov x2,sp + mov x27,#8 + +Lsqr8x_reduction: + // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0) + mul x15,x7,x28 + sub x27,x27,#1 + mul x16,x8,x28 + str x28,[x2],#8 // put aside t[0]*n0 for tail processing + mul x17,x9,x28 + // (*) adds xzr,x19,x14 + subs xzr,x19,#1 // (*) + mul x14,x10,x28 + adcs x19,x20,x15 + mul x15,x11,x28 + adcs x20,x21,x16 + mul x16,x12,x28 + adcs x21,x22,x17 + mul x17,x13,x28 + adcs x22,x23,x14 + umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0) + adcs x23,x24,x15 + umulh x15,x7,x28 + adcs x24,x25,x16 + umulh x16,x8,x28 + adcs x25,x26,x17 + umulh x17,x9,x28 + adc x26,xzr,xzr + adds x19,x19,x14 + umulh x14,x10,x28 + adcs x20,x20,x15 + umulh x15,x11,x28 + adcs x21,x21,x16 + umulh x16,x12,x28 + adcs x22,x22,x17 + umulh x17,x13,x28 + mul x28,x4,x19 // next t[0]*n0 + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adc x26,x26,x17 + cbnz x27,Lsqr8x_reduction + + ldp x14,x15,[x2,#8*0] + ldp x16,x17,[x2,#8*2] + mov x0,x2 + sub x27,x3,x1 // done yet? + adds x19,x19,x14 + adcs x20,x20,x15 + ldp x14,x15,[x2,#8*4] + adcs x21,x21,x16 + adcs x22,x22,x17 + ldp x16,x17,[x2,#8*6] + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adcs x26,x26,x17 + //adc x28,xzr,xzr // moved below + cbz x27,Lsqr8x8_post_condition + + ldr x4,[x2,#-8*8] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + mov x27,#-8*8 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + +Lsqr8x_tail: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,Lsqr8x_tail + // note that carry flag is guaranteed + // to be zero at this point + ldp x6,x7,[x2,#8*0] + sub x27,x3,x1 // done yet? + sub x16,x3,x5 // rewinded np + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + cbz x27,Lsqr8x_tail_break + + ldr x4,[x0,#-8*8] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b Lsqr8x_tail + +.align 4 +Lsqr8x_tail_break: + ldr x4,[x29,#112] // pull n0 + add x27,x2,#8*8 // end of current t[num] window + + subs xzr,x30,#1 // "move" top-most carry to carry bit + adcs x14,x19,x6 + adcs x15,x20,x7 + ldp x19,x20,[x0,#8*0] + adcs x21,x21,x8 + ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0] + adcs x22,x22,x9 + ldp x8,x9,[x16,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x16,#8*4] + adcs x25,x25,x12 + adcs x26,x26,x13 + ldp x12,x13,[x16,#8*6] + add x1,x16,#8*8 + adc x30,xzr,xzr // top-most carry + mul x28,x4,x19 + stp x14,x15,[x2,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x0,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x0,#8*4] + cmp x27,x29 // did we hit the bottom? + stp x25,x26,[x2,#8*6] + mov x2,x0 // slide the window + ldp x25,x26,[x0,#8*6] + mov x27,#8 + b.ne Lsqr8x_reduction + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x0,[x29,#96] // pull rp + add x2,x2,#8*8 + subs x14,x19,x6 + sbcs x15,x20,x7 + sub x27,x5,#8*8 + mov x3,x0 // x0 copy + +Lsqr8x_sub: + sbcs x16,x21,x8 + ldp x6,x7,[x1,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x1,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x10,x11,[x1,#8*4] + sbcs x17,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + ldp x19,x20,[x2,#8*0] + sub x27,x27,#8*8 + ldp x21,x22,[x2,#8*2] + ldp x23,x24,[x2,#8*4] + ldp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + stp x14,x15,[x0,#8*4] + sbcs x14,x19,x6 + stp x16,x17,[x0,#8*6] + add x0,x0,#8*8 + sbcs x15,x20,x7 + cbnz x27,Lsqr8x_sub + + sbcs x16,x21,x8 + mov x2,sp + add x1,sp,x5 + ldp x6,x7,[x3,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x3,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x19,x20,[x1,#8*0] + sbcs x17,x26,x13 + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + stp x14,x15,[x0,#8*4] + stp x16,x17,[x0,#8*6] + + sub x27,x5,#8*4 +Lsqr4x_cond_copy: + sub x27,x27,#8*4 + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + ldp x6,x7,[x3,#8*4] + ldp x19,x20,[x1,#8*4] + csel x16,x21,x8,lo + stp xzr,xzr,[x2,#8*2] + add x2,x2,#8*4 + csel x17,x22,x9,lo + ldp x8,x9,[x3,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + stp xzr,xzr,[x1,#8*0] + stp xzr,xzr,[x1,#8*2] + cbnz x27,Lsqr4x_cond_copy + + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + stp xzr,xzr,[x2,#8*2] + csel x16,x21,x8,lo + csel x17,x22,x9,lo + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + + b Lsqr8x_done + +.align 4 +Lsqr8x8_post_condition: + adc x28,xzr,xzr + ldr x30,[x29,#8] // pull return address + // x19-7,x28 hold result, x6-7 hold modulus + subs x6,x19,x6 + ldr x1,[x29,#96] // pull rp + sbcs x7,x20,x7 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x8 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x9 + stp xzr,xzr,[sp,#8*4] + sbcs x10,x23,x10 + stp xzr,xzr,[sp,#8*6] + sbcs x11,x24,x11 + stp xzr,xzr,[sp,#8*8] + sbcs x12,x25,x12 + stp xzr,xzr,[sp,#8*10] + sbcs x13,x26,x13 + stp xzr,xzr,[sp,#8*12] + sbcs x28,x28,xzr // did it borrow? + stp xzr,xzr,[sp,#8*14] + + // x6-7 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + csel x10,x23,x10,lo + csel x11,x24,x11,lo + stp x8,x9,[x1,#8*2] + csel x12,x25,x12,lo + csel x13,x26,x13,lo + stp x10,x11,[x1,#8*4] + stp x12,x13,[x1,#8*6] + +Lsqr8x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.align 5 +__bn_mul4x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to + // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // return address. + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + sub x26,sp,x5,lsl#3 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + sub sp,x26,#8*4 // alloca + + add x10,x2,x5 + add x27,x1,x5 + stp x0,x10,[x29,#96] // offload rp and &b[num] + + ldr x24,[x2,#8*0] // b[0] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + ldp x14,x15,[x3,#8*0] // n[0..3] + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + mov x28,#0 + mov x26,sp + +Loop_mul4x_1st_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[0]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[0]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0) + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0) + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + sub x10,x27,x1 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,Loop_mul4x_1st_reduction + + cbz x10,Lmul4x4_post_condition + + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldr x25,[sp] // a[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +Loop_mul4x_1st_tail: + mul x10,x6,x24 // lo(a[4..7]*b[i]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[i]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*a[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + adcs x23,x23,x0 + umulh x13,x17,x25 + adc x0,xzr,xzr + ldr x25,[sp,x28] // next t[0]*n0 + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,Loop_mul4x_1st_tail + + sub x11,x27,x5 // rewinded x1 + cbz x10,Lmul4x_proceed + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b Loop_mul4x_1st_tail + +.align 5 +Lmul4x_proceed: + ldr x24,[x2,#8*4]! // *++b + adc x30,x0,xzr + ldp x6,x7,[x11,#8*0] // a[0..3] + sub x3,x3,x5 // rewind np + ldp x8,x9,[x11,#8*2] + add x1,x11,#8*4 + + stp x19,x20,[x26,#8*0] // result!!! + ldp x19,x20,[sp,#8*4] // t[0..3] + stp x21,x22,[x26,#8*2] // result!!! + ldp x21,x22,[sp,#8*6] + + ldp x14,x15,[x3,#8*0] // n[0..3] + mov x26,sp + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + +.align 4 +Loop_mul4x_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[4]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + // (*) mul x10,x14,x25 + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 // lo(n[0..3]*t[0]*n0 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0 + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,Loop_mul4x_reduction + + adc x0,x0,xzr + ldp x10,x11,[x26,#8*4] // t[4..7] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + + ldr x25,[sp] // t[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.align 4 +Loop_mul4x_tail: + mul x10,x6,x24 // lo(a[4..7]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[4]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*t[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + umulh x13,x17,x25 + adcs x23,x23,x0 + ldr x25,[sp,x28] // next a[0]*n0 + adc x0,xzr,xzr + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,Loop_mul4x_tail + + sub x11,x3,x5 // rewinded np? + adc x0,x0,xzr + cbz x10,Loop_mul4x_break + + ldp x10,x11,[x26,#8*4] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b Loop_mul4x_tail + +.align 4 +Loop_mul4x_break: + ldp x12,x13,[x29,#96] // pull rp and &b[num] + adds x19,x19,x30 + add x2,x2,#8*4 // bp++ + adcs x20,x20,xzr + sub x1,x1,x5 // rewind ap + adcs x21,x21,xzr + stp x19,x20,[x26,#8*0] // result!!! + adcs x22,x22,xzr + ldp x19,x20,[sp,#8*4] // t[0..3] + adc x30,x0,xzr + stp x21,x22,[x26,#8*2] // result!!! + cmp x2,x13 // done yet? + ldp x21,x22,[sp,#8*6] + ldp x14,x15,[x11,#8*0] // n[0..3] + ldp x16,x17,[x11,#8*2] + add x3,x11,#8*4 + b.eq Lmul4x_post + + ldr x24,[x2] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + adds x1,x1,#8*4 // clear carry bit + mov x0,xzr + mov x26,sp + b Loop_mul4x_reduction + +.align 4 +Lmul4x_post: + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + mov x0,x12 + mov x27,x12 // x0 copy + subs x10,x19,x14 + add x26,sp,#8*8 + sbcs x11,x20,x15 + sub x28,x5,#8*4 + +Lmul4x_sub: + sbcs x12,x21,x16 + ldp x14,x15,[x3,#8*0] + sub x28,x28,#8*4 + ldp x19,x20,[x26,#8*0] + sbcs x13,x22,x17 + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + ldp x21,x22,[x26,#8*2] + add x26,x26,#8*4 + stp x10,x11,[x0,#8*0] + sbcs x10,x19,x14 + stp x12,x13,[x0,#8*2] + add x0,x0,#8*4 + sbcs x11,x20,x15 + cbnz x28,Lmul4x_sub + + sbcs x12,x21,x16 + mov x26,sp + add x1,sp,#8*4 + ldp x6,x7,[x27,#8*0] + sbcs x13,x22,x17 + stp x10,x11,[x0,#8*0] + ldp x8,x9,[x27,#8*2] + stp x12,x13,[x0,#8*2] + ldp x19,x20,[x1,#8*0] + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + + sub x28,x5,#8*4 +Lmul4x_cond_copy: + sub x28,x28,#8*4 + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + ldp x6,x7,[x27,#8*4] + ldp x19,x20,[x1,#8*4] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*2] + add x26,x26,#8*4 + csel x13,x22,x9,lo + ldp x8,x9,[x27,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + add x27,x27,#8*4 + cbnz x28,Lmul4x_cond_copy + + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + stp xzr,xzr,[x26,#8*2] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*3] + csel x13,x22,x9,lo + stp xzr,xzr,[x26,#8*4] + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + + b Lmul4x_done + +.align 4 +Lmul4x4_post_condition: + adc x0,x0,xzr + ldr x1,[x29,#96] // pull rp + // x19-3,x0 hold result, x14-7 hold modulus + subs x6,x19,x14 + ldr x30,[x29,#8] // pull return address + sbcs x7,x20,x15 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x16 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x17 + stp xzr,xzr,[sp,#8*4] + sbcs xzr,x0,xzr // did it borrow? + stp xzr,xzr,[sp,#8*6] + + // x6-3 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + stp x8,x9,[x1,#8*2] + +Lmul4x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER + ret + +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 4 +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S new file mode 100644 index 00000000..9c8c8593 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S @@ -0,0 +1,1443 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +.globl bn_mul_mont +.hidden bn_mul_mont +.type bn_mul_mont,%function +.align 5 +bn_mul_mont: + AARCH64_SIGN_LINK_REGISTER + tst x5,#7 + b.eq __bn_sqr8x_mont + tst x5,#3 + b.eq __bn_mul4x_mont +.Lmul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + ldr x9,[x2],#8 // bp[0] + sub x22,sp,x5,lsl#3 + ldp x7,x8,[x1],#16 // ap[0..1] + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + and x22,x22,#-16 // ABI says so + ldp x13,x14,[x3],#16 // np[0..1] + + mul x6,x7,x9 // ap[0]*bp[0] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + mul x10,x8,x9 // ap[1]*bp[0] + umulh x11,x8,x9 + + mul x15,x6,x4 // "tp[0]"*n0 + mov sp,x22 // alloca + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 // discarded + // (*) As for removal of first multiplication and addition + // instructions. The outcome of first addition is + // guaranteed to be zero, which leaves two computationally + // significant outcomes: it either carries or not. Then + // question is when does it carry? Is there alternative + // way to deduce it? If you follow operations, you can + // observe that condition for carry is quite simple: + // x6 being non-zero. So that carry can be calculated + // by adding -1 to x6. That's what next instruction does. + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + adc x13,x13,xzr + cbz x21,.L1st_skip + +.L1st: + ldr x8,[x1],#8 + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + ldr x14,[x3],#8 + adds x12,x16,x13 + mul x10,x8,x9 // ap[j]*bp[0] + adc x13,x17,xzr + umulh x11,x8,x9 + + adds x12,x12,x6 + mul x16,x14,x15 // np[j]*m1 + adc x13,x13,xzr + umulh x17,x14,x15 + str x12,[x22],#8 // tp[j-1] + cbnz x21,.L1st + +.L1st_skip: + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adc x13,x17,xzr + + adds x12,x12,x6 + sub x20,x5,#8 // i=num-1 + adcs x13,x13,x7 + + adc x19,xzr,xzr // upmost overflow bit + stp x12,x13,[x22] + +.Louter: + ldr x9,[x2],#8 // bp[i] + ldp x7,x8,[x1],#16 + ldr x23,[sp] // tp[0] + add x22,sp,#8 + + mul x6,x7,x9 // ap[0]*bp[i] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + ldp x13,x14,[x3],#16 + mul x10,x8,x9 // ap[1]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x15,x6,x4 + sub x20,x20,#8 // i-- + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + cbz x21,.Linner_skip + +.Linner: + ldr x8,[x1],#8 + adc x13,x13,xzr + ldr x23,[x22],#8 // tp[j] + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + adds x12,x16,x13 + ldr x14,[x3],#8 + adc x13,x17,xzr + + mul x10,x8,x9 // ap[j]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x16,x14,x15 // np[j]*m1 + adds x12,x12,x6 + umulh x17,x14,x15 + str x12,[x22,#-16] // tp[j-1] + cbnz x21,.Linner + +.Linner_skip: + ldr x23,[x22],#8 // tp[j] + adc x13,x13,xzr + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adcs x13,x17,x19 + adc x19,xzr,xzr + + adds x6,x6,x23 + adc x7,x7,xzr + + adds x12,x12,x6 + adcs x13,x13,x7 + adc x19,x19,xzr // upmost overflow bit + stp x12,x13,[x22,#-16] + + cbnz x20,.Louter + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x14,[x3],#8 // np[0] + subs x21,x5,#8 // j=num-1 and clear borrow + mov x1,x0 +.Lsub: + sbcs x8,x23,x14 // tp[j]-np[j] + ldr x23,[x22],#8 + sub x21,x21,#8 // j-- + ldr x14,[x3],#8 + str x8,[x1],#8 // rp[j]=tp[j]-np[j] + cbnz x21,.Lsub + + sbcs x8,x23,x14 + sbcs x19,x19,xzr // did it borrow? + str x8,[x1],#8 // rp[num-1] + + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x8,[x0],#8 // rp[0] + sub x5,x5,#8 // num-- + nop +.Lcond_copy: + sub x5,x5,#8 // num-- + csel x14,x23,x8,lo // did it borrow? + ldr x23,[x22],#8 + ldr x8,[x0],#8 + str xzr,[x22,#-16] // wipe tp + str x14,[x0,#-16] + cbnz x5,.Lcond_copy + + csel x14,x23,x8,lo + str xzr,[x22,#-8] // wipe tp + str x14,[x0,#-8] + + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldr x29,[sp],#64 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size bn_mul_mont,.-bn_mul_mont +.type __bn_sqr8x_mont,%function +.align 5 +__bn_sqr8x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to + // only from bn_mul_mont which has already signed the return address. + cmp x1,x2 + b.ne __bn_mul4x_mont +.Lsqr8x_mont: + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x3,[sp,#96] // offload rp and np + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + ldp x12,x13,[x1,#8*6] + + sub x2,sp,x5,lsl#4 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + mov sp,x2 // alloca + sub x27,x5,#8*8 + b .Lsqr8x_zero_start + +.Lsqr8x_zero: + sub x27,x27,#8*8 + stp xzr,xzr,[x2,#8*0] + stp xzr,xzr,[x2,#8*2] + stp xzr,xzr,[x2,#8*4] + stp xzr,xzr,[x2,#8*6] +.Lsqr8x_zero_start: + stp xzr,xzr,[x2,#8*8] + stp xzr,xzr,[x2,#8*10] + stp xzr,xzr,[x2,#8*12] + stp xzr,xzr,[x2,#8*14] + add x2,x2,#8*16 + cbnz x27,.Lsqr8x_zero + + add x3,x1,x5 + add x1,x1,#8*8 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + mov x23,xzr + mov x24,xzr + mov x25,xzr + mov x26,xzr + mov x2,sp + str x4,[x29,#112] // offload n0 + + // Multiply everything but a[i]*a[i] +.align 4 +.Lsqr8x_outer_loop: + // a[1]a[0] (i) + // a[2]a[0] + // a[3]a[0] + // a[4]a[0] + // a[5]a[0] + // a[6]a[0] + // a[7]a[0] + // a[2]a[1] (ii) + // a[3]a[1] + // a[4]a[1] + // a[5]a[1] + // a[6]a[1] + // a[7]a[1] + // a[3]a[2] (iii) + // a[4]a[2] + // a[5]a[2] + // a[6]a[2] + // a[7]a[2] + // a[4]a[3] (iv) + // a[5]a[3] + // a[6]a[3] + // a[7]a[3] + // a[5]a[4] (v) + // a[6]a[4] + // a[7]a[4] + // a[6]a[5] (vi) + // a[7]a[5] + // a[7]a[6] (vii) + + mul x14,x7,x6 // lo(a[1..7]*a[0]) (i) + mul x15,x8,x6 + mul x16,x9,x6 + mul x17,x10,x6 + adds x20,x20,x14 // t[1]+lo(a[1]*a[0]) + mul x14,x11,x6 + adcs x21,x21,x15 + mul x15,x12,x6 + adcs x22,x22,x16 + mul x16,x13,x6 + adcs x23,x23,x17 + umulh x17,x7,x6 // hi(a[1..7]*a[0]) + adcs x24,x24,x14 + umulh x14,x8,x6 + adcs x25,x25,x15 + umulh x15,x9,x6 + adcs x26,x26,x16 + umulh x16,x10,x6 + stp x19,x20,[x2],#8*2 // t[0..1] + adc x19,xzr,xzr // t[8] + adds x21,x21,x17 // t[2]+lo(a[1]*a[0]) + umulh x17,x11,x6 + adcs x22,x22,x14 + umulh x14,x12,x6 + adcs x23,x23,x15 + umulh x15,x13,x6 + adcs x24,x24,x16 + mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii) + adcs x25,x25,x17 + mul x17,x9,x7 + adcs x26,x26,x14 + mul x14,x10,x7 + adc x19,x19,x15 + + mul x15,x11,x7 + adds x22,x22,x16 + mul x16,x12,x7 + adcs x23,x23,x17 + mul x17,x13,x7 + adcs x24,x24,x14 + umulh x14,x8,x7 // hi(a[2..7]*a[1]) + adcs x25,x25,x15 + umulh x15,x9,x7 + adcs x26,x26,x16 + umulh x16,x10,x7 + adcs x19,x19,x17 + umulh x17,x11,x7 + stp x21,x22,[x2],#8*2 // t[2..3] + adc x20,xzr,xzr // t[9] + adds x23,x23,x14 + umulh x14,x12,x7 + adcs x24,x24,x15 + umulh x15,x13,x7 + adcs x25,x25,x16 + mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii) + adcs x26,x26,x17 + mul x17,x10,x8 + adcs x19,x19,x14 + mul x14,x11,x8 + adc x20,x20,x15 + + mul x15,x12,x8 + adds x24,x24,x16 + mul x16,x13,x8 + adcs x25,x25,x17 + umulh x17,x9,x8 // hi(a[3..7]*a[2]) + adcs x26,x26,x14 + umulh x14,x10,x8 + adcs x19,x19,x15 + umulh x15,x11,x8 + adcs x20,x20,x16 + umulh x16,x12,x8 + stp x23,x24,[x2],#8*2 // t[4..5] + adc x21,xzr,xzr // t[10] + adds x25,x25,x17 + umulh x17,x13,x8 + adcs x26,x26,x14 + mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv) + adcs x19,x19,x15 + mul x15,x11,x9 + adcs x20,x20,x16 + mul x16,x12,x9 + adc x21,x21,x17 + + mul x17,x13,x9 + adds x26,x26,x14 + umulh x14,x10,x9 // hi(a[4..7]*a[3]) + adcs x19,x19,x15 + umulh x15,x11,x9 + adcs x20,x20,x16 + umulh x16,x12,x9 + adcs x21,x21,x17 + umulh x17,x13,x9 + stp x25,x26,[x2],#8*2 // t[6..7] + adc x22,xzr,xzr // t[11] + adds x19,x19,x14 + mul x14,x11,x10 // lo(a[5..7]*a[4]) (v) + adcs x20,x20,x15 + mul x15,x12,x10 + adcs x21,x21,x16 + mul x16,x13,x10 + adc x22,x22,x17 + + umulh x17,x11,x10 // hi(a[5..7]*a[4]) + adds x20,x20,x14 + umulh x14,x12,x10 + adcs x21,x21,x15 + umulh x15,x13,x10 + adcs x22,x22,x16 + mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi) + adc x23,xzr,xzr // t[12] + adds x21,x21,x17 + mul x17,x13,x11 + adcs x22,x22,x14 + umulh x14,x12,x11 // hi(a[6..7]*a[5]) + adc x23,x23,x15 + + umulh x15,x13,x11 + adds x22,x22,x16 + mul x16,x13,x12 // lo(a[7]*a[6]) (vii) + adcs x23,x23,x17 + umulh x17,x13,x12 // hi(a[7]*a[6]) + adc x24,xzr,xzr // t[13] + adds x23,x23,x14 + sub x27,x3,x1 // done yet? + adc x24,x24,x15 + + adds x24,x24,x16 + sub x14,x3,x5 // rewinded ap + adc x25,xzr,xzr // t[14] + add x25,x25,x17 + + cbz x27,.Lsqr8x_outer_break + + mov x4,x6 + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x0,x1 + adcs x26,xzr,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved below + mov x27,#-8*8 + + // a[8]a[0] + // a[9]a[0] + // a[a]a[0] + // a[b]a[0] + // a[c]a[0] + // a[d]a[0] + // a[e]a[0] + // a[f]a[0] + // a[8]a[1] + // a[f]a[1]........................ + // a[8]a[2] + // a[f]a[2]........................ + // a[8]a[3] + // a[f]a[3]........................ + // a[8]a[4] + // a[f]a[4]........................ + // a[8]a[5] + // a[f]a[5]........................ + // a[8]a[6] + // a[f]a[6]........................ + // a[8]a[7] + // a[f]a[7]........................ +.Lsqr8x_mul: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_mul + // note that carry flag is guaranteed + // to be zero at this point + cmp x1,x3 // done yet? + b.eq .Lsqr8x_break + + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + ldr x4,[x0,#-8*8] + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_mul + +.align 4 +.Lsqr8x_break: + ldp x6,x7,[x0,#8*0] + add x1,x0,#8*8 + ldp x8,x9,[x0,#8*2] + sub x14,x3,x1 // is it last iteration? + ldp x10,x11,[x0,#8*4] + sub x15,x2,x14 + ldp x12,x13,[x0,#8*6] + cbz x14,.Lsqr8x_outer_loop + + stp x19,x20,[x2,#8*0] + ldp x19,x20,[x15,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x15,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x15,#8*4] + stp x25,x26,[x2,#8*6] + mov x2,x15 + ldp x25,x26,[x15,#8*6] + b .Lsqr8x_outer_loop + +.align 4 +.Lsqr8x_outer_break: + // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0] + ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0] + ldp x15,x16,[sp,#8*1] + ldp x11,x13,[x14,#8*2] + add x1,x14,#8*4 + ldp x17,x14,[sp,#8*3] + + stp x19,x20,[x2,#8*0] + mul x19,x7,x7 + stp x21,x22,[x2,#8*2] + umulh x7,x7,x7 + stp x23,x24,[x2,#8*4] + mul x8,x9,x9 + stp x25,x26,[x2,#8*6] + mov x2,sp + umulh x9,x9,x9 + adds x20,x7,x15,lsl#1 + extr x15,x16,x15,#63 + sub x27,x5,#8*4 + +.Lsqr4x_shift_n_add: + adcs x21,x8,x15 + extr x16,x17,x16,#63 + sub x27,x27,#8*4 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + ldp x7,x9,[x1],#8*2 + umulh x11,x11,x11 + mul x12,x13,x13 + umulh x13,x13,x13 + extr x17,x14,x17,#63 + stp x19,x20,[x2,#8*0] + adcs x23,x10,x17 + extr x14,x15,x14,#63 + stp x21,x22,[x2,#8*2] + adcs x24,x11,x14 + ldp x17,x14,[x2,#8*7] + extr x15,x16,x15,#63 + adcs x25,x12,x15 + extr x16,x17,x16,#63 + adcs x26,x13,x16 + ldp x15,x16,[x2,#8*9] + mul x6,x7,x7 + ldp x11,x13,[x1],#8*2 + umulh x7,x7,x7 + mul x8,x9,x9 + umulh x9,x9,x9 + stp x23,x24,[x2,#8*4] + extr x17,x14,x17,#63 + stp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + adcs x19,x6,x17 + extr x14,x15,x14,#63 + adcs x20,x7,x14 + ldp x17,x14,[x2,#8*3] + extr x15,x16,x15,#63 + cbnz x27,.Lsqr4x_shift_n_add + ldp x1,x4,[x29,#104] // pull np and n0 + + adcs x21,x8,x15 + extr x16,x17,x16,#63 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + umulh x11,x11,x11 + stp x19,x20,[x2,#8*0] + mul x12,x13,x13 + umulh x13,x13,x13 + stp x21,x22,[x2,#8*2] + extr x17,x14,x17,#63 + adcs x23,x10,x17 + extr x14,x15,x14,#63 + ldp x19,x20,[sp,#8*0] + adcs x24,x11,x14 + extr x15,x16,x15,#63 + ldp x6,x7,[x1,#8*0] + adcs x25,x12,x15 + extr x16,xzr,x16,#63 + ldp x8,x9,[x1,#8*2] + adc x26,x13,x16 + ldp x10,x11,[x1,#8*4] + + // Reduce by 512 bits per iteration + mul x28,x4,x19 // t[0]*n0 + ldp x12,x13,[x1,#8*6] + add x3,x1,x5 + ldp x21,x22,[sp,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[sp,#8*4] + stp x25,x26,[x2,#8*6] + ldp x25,x26,[sp,#8*6] + add x1,x1,#8*8 + mov x30,xzr // initial top-most carry + mov x2,sp + mov x27,#8 + +.Lsqr8x_reduction: + // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0) + mul x15,x7,x28 + sub x27,x27,#1 + mul x16,x8,x28 + str x28,[x2],#8 // put aside t[0]*n0 for tail processing + mul x17,x9,x28 + // (*) adds xzr,x19,x14 + subs xzr,x19,#1 // (*) + mul x14,x10,x28 + adcs x19,x20,x15 + mul x15,x11,x28 + adcs x20,x21,x16 + mul x16,x12,x28 + adcs x21,x22,x17 + mul x17,x13,x28 + adcs x22,x23,x14 + umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0) + adcs x23,x24,x15 + umulh x15,x7,x28 + adcs x24,x25,x16 + umulh x16,x8,x28 + adcs x25,x26,x17 + umulh x17,x9,x28 + adc x26,xzr,xzr + adds x19,x19,x14 + umulh x14,x10,x28 + adcs x20,x20,x15 + umulh x15,x11,x28 + adcs x21,x21,x16 + umulh x16,x12,x28 + adcs x22,x22,x17 + umulh x17,x13,x28 + mul x28,x4,x19 // next t[0]*n0 + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adc x26,x26,x17 + cbnz x27,.Lsqr8x_reduction + + ldp x14,x15,[x2,#8*0] + ldp x16,x17,[x2,#8*2] + mov x0,x2 + sub x27,x3,x1 // done yet? + adds x19,x19,x14 + adcs x20,x20,x15 + ldp x14,x15,[x2,#8*4] + adcs x21,x21,x16 + adcs x22,x22,x17 + ldp x16,x17,[x2,#8*6] + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adcs x26,x26,x17 + //adc x28,xzr,xzr // moved below + cbz x27,.Lsqr8x8_post_condition + + ldr x4,[x2,#-8*8] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + mov x27,#-8*8 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + +.Lsqr8x_tail: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_tail + // note that carry flag is guaranteed + // to be zero at this point + ldp x6,x7,[x2,#8*0] + sub x27,x3,x1 // done yet? + sub x16,x3,x5 // rewinded np + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + cbz x27,.Lsqr8x_tail_break + + ldr x4,[x0,#-8*8] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_tail + +.align 4 +.Lsqr8x_tail_break: + ldr x4,[x29,#112] // pull n0 + add x27,x2,#8*8 // end of current t[num] window + + subs xzr,x30,#1 // "move" top-most carry to carry bit + adcs x14,x19,x6 + adcs x15,x20,x7 + ldp x19,x20,[x0,#8*0] + adcs x21,x21,x8 + ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0] + adcs x22,x22,x9 + ldp x8,x9,[x16,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x16,#8*4] + adcs x25,x25,x12 + adcs x26,x26,x13 + ldp x12,x13,[x16,#8*6] + add x1,x16,#8*8 + adc x30,xzr,xzr // top-most carry + mul x28,x4,x19 + stp x14,x15,[x2,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x0,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x0,#8*4] + cmp x27,x29 // did we hit the bottom? + stp x25,x26,[x2,#8*6] + mov x2,x0 // slide the window + ldp x25,x26,[x0,#8*6] + mov x27,#8 + b.ne .Lsqr8x_reduction + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x0,[x29,#96] // pull rp + add x2,x2,#8*8 + subs x14,x19,x6 + sbcs x15,x20,x7 + sub x27,x5,#8*8 + mov x3,x0 // x0 copy + +.Lsqr8x_sub: + sbcs x16,x21,x8 + ldp x6,x7,[x1,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x1,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x10,x11,[x1,#8*4] + sbcs x17,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + ldp x19,x20,[x2,#8*0] + sub x27,x27,#8*8 + ldp x21,x22,[x2,#8*2] + ldp x23,x24,[x2,#8*4] + ldp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + stp x14,x15,[x0,#8*4] + sbcs x14,x19,x6 + stp x16,x17,[x0,#8*6] + add x0,x0,#8*8 + sbcs x15,x20,x7 + cbnz x27,.Lsqr8x_sub + + sbcs x16,x21,x8 + mov x2,sp + add x1,sp,x5 + ldp x6,x7,[x3,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x3,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x19,x20,[x1,#8*0] + sbcs x17,x26,x13 + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + stp x14,x15,[x0,#8*4] + stp x16,x17,[x0,#8*6] + + sub x27,x5,#8*4 +.Lsqr4x_cond_copy: + sub x27,x27,#8*4 + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + ldp x6,x7,[x3,#8*4] + ldp x19,x20,[x1,#8*4] + csel x16,x21,x8,lo + stp xzr,xzr,[x2,#8*2] + add x2,x2,#8*4 + csel x17,x22,x9,lo + ldp x8,x9,[x3,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + stp xzr,xzr,[x1,#8*0] + stp xzr,xzr,[x1,#8*2] + cbnz x27,.Lsqr4x_cond_copy + + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + stp xzr,xzr,[x2,#8*2] + csel x16,x21,x8,lo + csel x17,x22,x9,lo + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + + b .Lsqr8x_done + +.align 4 +.Lsqr8x8_post_condition: + adc x28,xzr,xzr + ldr x30,[x29,#8] // pull return address + // x19-7,x28 hold result, x6-7 hold modulus + subs x6,x19,x6 + ldr x1,[x29,#96] // pull rp + sbcs x7,x20,x7 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x8 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x9 + stp xzr,xzr,[sp,#8*4] + sbcs x10,x23,x10 + stp xzr,xzr,[sp,#8*6] + sbcs x11,x24,x11 + stp xzr,xzr,[sp,#8*8] + sbcs x12,x25,x12 + stp xzr,xzr,[sp,#8*10] + sbcs x13,x26,x13 + stp xzr,xzr,[sp,#8*12] + sbcs x28,x28,xzr // did it borrow? + stp xzr,xzr,[sp,#8*14] + + // x6-7 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + csel x10,x23,x10,lo + csel x11,x24,x11,lo + stp x8,x9,[x1,#8*2] + csel x12,x25,x12,lo + csel x13,x26,x13,lo + stp x10,x11,[x1,#8*4] + stp x12,x13,[x1,#8*6] + +.Lsqr8x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER + ret +.size __bn_sqr8x_mont,.-__bn_sqr8x_mont +.type __bn_mul4x_mont,%function +.align 5 +__bn_mul4x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to + // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // return address. + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + sub x26,sp,x5,lsl#3 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + sub sp,x26,#8*4 // alloca + + add x10,x2,x5 + add x27,x1,x5 + stp x0,x10,[x29,#96] // offload rp and &b[num] + + ldr x24,[x2,#8*0] // b[0] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + ldp x14,x15,[x3,#8*0] // n[0..3] + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + mov x28,#0 + mov x26,sp + +.Loop_mul4x_1st_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[0]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[0]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0) + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0) + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + sub x10,x27,x1 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_reduction + + cbz x10,.Lmul4x4_post_condition + + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldr x25,[sp] // a[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.Loop_mul4x_1st_tail: + mul x10,x6,x24 // lo(a[4..7]*b[i]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[i]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*a[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + adcs x23,x23,x0 + umulh x13,x17,x25 + adc x0,xzr,xzr + ldr x25,[sp,x28] // next t[0]*n0 + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_tail + + sub x11,x27,x5 // rewinded x1 + cbz x10,.Lmul4x_proceed + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_1st_tail + +.align 5 +.Lmul4x_proceed: + ldr x24,[x2,#8*4]! // *++b + adc x30,x0,xzr + ldp x6,x7,[x11,#8*0] // a[0..3] + sub x3,x3,x5 // rewind np + ldp x8,x9,[x11,#8*2] + add x1,x11,#8*4 + + stp x19,x20,[x26,#8*0] // result!!! + ldp x19,x20,[sp,#8*4] // t[0..3] + stp x21,x22,[x26,#8*2] // result!!! + ldp x21,x22,[sp,#8*6] + + ldp x14,x15,[x3,#8*0] // n[0..3] + mov x26,sp + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + +.align 4 +.Loop_mul4x_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[4]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + // (*) mul x10,x14,x25 + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 // lo(n[0..3]*t[0]*n0 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0 + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_reduction + + adc x0,x0,xzr + ldp x10,x11,[x26,#8*4] // t[4..7] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + + ldr x25,[sp] // t[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.align 4 +.Loop_mul4x_tail: + mul x10,x6,x24 // lo(a[4..7]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[4]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*t[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + umulh x13,x17,x25 + adcs x23,x23,x0 + ldr x25,[sp,x28] // next a[0]*n0 + adc x0,xzr,xzr + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_tail + + sub x11,x3,x5 // rewinded np? + adc x0,x0,xzr + cbz x10,.Loop_mul4x_break + + ldp x10,x11,[x26,#8*4] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_tail + +.align 4 +.Loop_mul4x_break: + ldp x12,x13,[x29,#96] // pull rp and &b[num] + adds x19,x19,x30 + add x2,x2,#8*4 // bp++ + adcs x20,x20,xzr + sub x1,x1,x5 // rewind ap + adcs x21,x21,xzr + stp x19,x20,[x26,#8*0] // result!!! + adcs x22,x22,xzr + ldp x19,x20,[sp,#8*4] // t[0..3] + adc x30,x0,xzr + stp x21,x22,[x26,#8*2] // result!!! + cmp x2,x13 // done yet? + ldp x21,x22,[sp,#8*6] + ldp x14,x15,[x11,#8*0] // n[0..3] + ldp x16,x17,[x11,#8*2] + add x3,x11,#8*4 + b.eq .Lmul4x_post + + ldr x24,[x2] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + adds x1,x1,#8*4 // clear carry bit + mov x0,xzr + mov x26,sp + b .Loop_mul4x_reduction + +.align 4 +.Lmul4x_post: + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + mov x0,x12 + mov x27,x12 // x0 copy + subs x10,x19,x14 + add x26,sp,#8*8 + sbcs x11,x20,x15 + sub x28,x5,#8*4 + +.Lmul4x_sub: + sbcs x12,x21,x16 + ldp x14,x15,[x3,#8*0] + sub x28,x28,#8*4 + ldp x19,x20,[x26,#8*0] + sbcs x13,x22,x17 + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + ldp x21,x22,[x26,#8*2] + add x26,x26,#8*4 + stp x10,x11,[x0,#8*0] + sbcs x10,x19,x14 + stp x12,x13,[x0,#8*2] + add x0,x0,#8*4 + sbcs x11,x20,x15 + cbnz x28,.Lmul4x_sub + + sbcs x12,x21,x16 + mov x26,sp + add x1,sp,#8*4 + ldp x6,x7,[x27,#8*0] + sbcs x13,x22,x17 + stp x10,x11,[x0,#8*0] + ldp x8,x9,[x27,#8*2] + stp x12,x13,[x0,#8*2] + ldp x19,x20,[x1,#8*0] + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + + sub x28,x5,#8*4 +.Lmul4x_cond_copy: + sub x28,x28,#8*4 + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + ldp x6,x7,[x27,#8*4] + ldp x19,x20,[x1,#8*4] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*2] + add x26,x26,#8*4 + csel x13,x22,x9,lo + ldp x8,x9,[x27,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + add x27,x27,#8*4 + cbnz x28,.Lmul4x_cond_copy + + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + stp xzr,xzr,[x26,#8*2] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*3] + csel x13,x22,x9,lo + stp xzr,xzr,[x26,#8*4] + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + + b .Lmul4x_done + +.align 4 +.Lmul4x4_post_condition: + adc x0,x0,xzr + ldr x1,[x29,#96] // pull rp + // x19-3,x0 hold result, x14-7 hold modulus + subs x6,x19,x14 + ldr x30,[x29,#8] // pull return address + sbcs x7,x20,x15 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x16 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x17 + stp xzr,xzr,[sp,#8*4] + sbcs xzr,x0,xzr // did it borrow? + stp xzr,xzr,[sp,#8*6] + + // x6-3 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + stp x8,x9,[x1,#8*2] + +.Lmul4x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER + ret +.size __bn_mul4x_mont,.-__bn_mul4x_mont +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 4 +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S new file mode 100644 index 00000000..bd7857f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S @@ -0,0 +1,1004 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl bn_mul_add_words +.hidden bn_mul_add_words +.type bn_mul_add_words,@function +.align 16 +bn_mul_add_words: +.L_bn_mul_add_words_begin: + call .L000PIC_me_up +.L000PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L000PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L001maw_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx + movd 16(%esp),%mm0 + pxor %mm1,%mm1 + jmp .L002maw_sse2_entry +.align 16 +.L003maw_sse2_unrolled: + movd (%eax),%mm3 + paddq %mm3,%mm1 + movd (%edx),%mm2 + pmuludq %mm0,%mm2 + movd 4(%edx),%mm4 + pmuludq %mm0,%mm4 + movd 8(%edx),%mm6 + pmuludq %mm0,%mm6 + movd 12(%edx),%mm7 + pmuludq %mm0,%mm7 + paddq %mm2,%mm1 + movd 4(%eax),%mm3 + paddq %mm4,%mm3 + movd 8(%eax),%mm5 + paddq %mm6,%mm5 + movd 12(%eax),%mm4 + paddq %mm4,%mm7 + movd %mm1,(%eax) + movd 16(%edx),%mm2 + pmuludq %mm0,%mm2 + psrlq $32,%mm1 + movd 20(%edx),%mm4 + pmuludq %mm0,%mm4 + paddq %mm3,%mm1 + movd 24(%edx),%mm6 + pmuludq %mm0,%mm6 + movd %mm1,4(%eax) + psrlq $32,%mm1 + movd 28(%edx),%mm3 + addl $32,%edx + pmuludq %mm0,%mm3 + paddq %mm5,%mm1 + movd 16(%eax),%mm5 + paddq %mm5,%mm2 + movd %mm1,8(%eax) + psrlq $32,%mm1 + paddq %mm7,%mm1 + movd 20(%eax),%mm5 + paddq %mm5,%mm4 + movd %mm1,12(%eax) + psrlq $32,%mm1 + paddq %mm2,%mm1 + movd 24(%eax),%mm5 + paddq %mm5,%mm6 + movd %mm1,16(%eax) + psrlq $32,%mm1 + paddq %mm4,%mm1 + movd 28(%eax),%mm5 + paddq %mm5,%mm3 + movd %mm1,20(%eax) + psrlq $32,%mm1 + paddq %mm6,%mm1 + movd %mm1,24(%eax) + psrlq $32,%mm1 + paddq %mm3,%mm1 + movd %mm1,28(%eax) + leal 32(%eax),%eax + psrlq $32,%mm1 + subl $8,%ecx + jz .L004maw_sse2_exit +.L002maw_sse2_entry: + testl $4294967288,%ecx + jnz .L003maw_sse2_unrolled +.align 4 +.L005maw_sse2_loop: + movd (%edx),%mm2 + movd (%eax),%mm3 + pmuludq %mm0,%mm2 + leal 4(%edx),%edx + paddq %mm3,%mm1 + paddq %mm2,%mm1 + movd %mm1,(%eax) + subl $1,%ecx + psrlq $32,%mm1 + leal 4(%eax),%eax + jnz .L005maw_sse2_loop +.L004maw_sse2_exit: + movd %mm1,%eax + emms + ret +.align 16 +.L001maw_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + xorl %esi,%esi + movl 20(%esp),%edi + movl 28(%esp),%ecx + movl 24(%esp),%ebx + andl $4294967288,%ecx + movl 32(%esp),%ebp + pushl %ecx + jz .L006maw_finish +.align 16 +.L007maw_loop: + + movl (%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl (%edi),%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + + movl 4(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 4(%edi),%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + + movl 8(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 8(%edi),%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + + movl 12(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 12(%edi),%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + + movl 16(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 16(%edi),%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + + movl 20(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 20(%edi),%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + + movl 24(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 24(%edi),%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi + + movl 28(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 28(%edi),%eax + adcl $0,%edx + movl %eax,28(%edi) + movl %edx,%esi + + subl $8,%ecx + leal 32(%ebx),%ebx + leal 32(%edi),%edi + jnz .L007maw_loop +.L006maw_finish: + movl 32(%esp),%ecx + andl $7,%ecx + jnz .L008maw_finish2 + jmp .L009maw_end +.L008maw_finish2: + + movl (%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl (%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 4(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 4(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,4(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 8(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 8(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,8(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 12(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 12(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,12(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 16(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 16(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,16(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 20(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 20(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,20(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 24(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 24(%edi),%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi +.L009maw_end: + movl %esi,%eax + popl %ecx + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_add_words,.-.L_bn_mul_add_words_begin +.globl bn_mul_words +.hidden bn_mul_words +.type bn_mul_words,@function +.align 16 +bn_mul_words: +.L_bn_mul_words_begin: + call .L010PIC_me_up +.L010PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L010PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L011mw_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx + movd 16(%esp),%mm0 + pxor %mm1,%mm1 +.align 16 +.L012mw_sse2_loop: + movd (%edx),%mm2 + pmuludq %mm0,%mm2 + leal 4(%edx),%edx + paddq %mm2,%mm1 + movd %mm1,(%eax) + subl $1,%ecx + psrlq $32,%mm1 + leal 4(%eax),%eax + jnz .L012mw_sse2_loop + movd %mm1,%eax + emms + ret +.align 16 +.L011mw_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + xorl %esi,%esi + movl 20(%esp),%edi + movl 24(%esp),%ebx + movl 28(%esp),%ebp + movl 32(%esp),%ecx + andl $4294967288,%ebp + jz .L013mw_finish +.L014mw_loop: + + movl (%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + + movl 4(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + + movl 8(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + + movl 12(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + + movl 16(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + + movl 20(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + + movl 24(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi + + movl 28(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,28(%edi) + movl %edx,%esi + + addl $32,%ebx + addl $32,%edi + subl $8,%ebp + jz .L013mw_finish + jmp .L014mw_loop +.L013mw_finish: + movl 28(%esp),%ebp + andl $7,%ebp + jnz .L015mw_finish2 + jmp .L016mw_end +.L015mw_finish2: + + movl (%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 4(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 8(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 12(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 16(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 20(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 24(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi +.L016mw_end: + movl %esi,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_words,.-.L_bn_mul_words_begin +.globl bn_sqr_words +.hidden bn_sqr_words +.type bn_sqr_words,@function +.align 16 +bn_sqr_words: +.L_bn_sqr_words_begin: + call .L017PIC_me_up +.L017PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L017PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L018sqr_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx +.align 16 +.L019sqr_sse2_loop: + movd (%edx),%mm0 + pmuludq %mm0,%mm0 + leal 4(%edx),%edx + movq %mm0,(%eax) + subl $1,%ecx + leal 8(%eax),%eax + jnz .L019sqr_sse2_loop + emms + ret +.align 16 +.L018sqr_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%ebx + andl $4294967288,%ebx + jz .L020sw_finish +.L021sw_loop: + + movl (%edi),%eax + mull %eax + movl %eax,(%esi) + movl %edx,4(%esi) + + movl 4(%edi),%eax + mull %eax + movl %eax,8(%esi) + movl %edx,12(%esi) + + movl 8(%edi),%eax + mull %eax + movl %eax,16(%esi) + movl %edx,20(%esi) + + movl 12(%edi),%eax + mull %eax + movl %eax,24(%esi) + movl %edx,28(%esi) + + movl 16(%edi),%eax + mull %eax + movl %eax,32(%esi) + movl %edx,36(%esi) + + movl 20(%edi),%eax + mull %eax + movl %eax,40(%esi) + movl %edx,44(%esi) + + movl 24(%edi),%eax + mull %eax + movl %eax,48(%esi) + movl %edx,52(%esi) + + movl 28(%edi),%eax + mull %eax + movl %eax,56(%esi) + movl %edx,60(%esi) + + addl $32,%edi + addl $64,%esi + subl $8,%ebx + jnz .L021sw_loop +.L020sw_finish: + movl 28(%esp),%ebx + andl $7,%ebx + jz .L022sw_end + + movl (%edi),%eax + mull %eax + movl %eax,(%esi) + decl %ebx + movl %edx,4(%esi) + jz .L022sw_end + + movl 4(%edi),%eax + mull %eax + movl %eax,8(%esi) + decl %ebx + movl %edx,12(%esi) + jz .L022sw_end + + movl 8(%edi),%eax + mull %eax + movl %eax,16(%esi) + decl %ebx + movl %edx,20(%esi) + jz .L022sw_end + + movl 12(%edi),%eax + mull %eax + movl %eax,24(%esi) + decl %ebx + movl %edx,28(%esi) + jz .L022sw_end + + movl 16(%edi),%eax + mull %eax + movl %eax,32(%esi) + decl %ebx + movl %edx,36(%esi) + jz .L022sw_end + + movl 20(%edi),%eax + mull %eax + movl %eax,40(%esi) + decl %ebx + movl %edx,44(%esi) + jz .L022sw_end + + movl 24(%edi),%eax + mull %eax + movl %eax,48(%esi) + movl %edx,52(%esi) +.L022sw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_sqr_words,.-.L_bn_sqr_words_begin +.globl bn_div_words +.hidden bn_div_words +.type bn_div_words,@function +.align 16 +bn_div_words: +.L_bn_div_words_begin: + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 12(%esp),%ecx + divl %ecx + ret +.size bn_div_words,.-.L_bn_div_words_begin +.globl bn_add_words +.hidden bn_add_words +.type bn_add_words,@function +.align 16 +bn_add_words: +.L_bn_add_words_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%ebx + movl 24(%esp),%esi + movl 28(%esp),%edi + movl 32(%esp),%ebp + xorl %eax,%eax + andl $4294967288,%ebp + jz .L023aw_finish +.L024aw_loop: + + movl (%esi),%ecx + movl (%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl 4(%esi),%ecx + movl 4(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl 8(%esi),%ecx + movl 8(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl 12(%esi),%ecx + movl 12(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl 16(%esi),%ecx + movl 16(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl 20(%esi),%ecx + movl 20(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl 24(%esi),%ecx + movl 24(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl 28(%esi),%ecx + movl 28(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%esi + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L024aw_loop +.L023aw_finish: + movl 32(%esp),%ebp + andl $7,%ebp + jz .L025aw_end + + movl (%esi),%ecx + movl (%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,(%ebx) + jz .L025aw_end + + movl 4(%esi),%ecx + movl 4(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,4(%ebx) + jz .L025aw_end + + movl 8(%esi),%ecx + movl 8(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,8(%ebx) + jz .L025aw_end + + movl 12(%esi),%ecx + movl 12(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,12(%ebx) + jz .L025aw_end + + movl 16(%esi),%ecx + movl 16(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,16(%ebx) + jz .L025aw_end + + movl 20(%esi),%ecx + movl 20(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,20(%ebx) + jz .L025aw_end + + movl 24(%esi),%ecx + movl 24(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) +.L025aw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_add_words,.-.L_bn_add_words_begin +.globl bn_sub_words +.hidden bn_sub_words +.type bn_sub_words,@function +.align 16 +bn_sub_words: +.L_bn_sub_words_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%ebx + movl 24(%esp),%esi + movl 28(%esp),%edi + movl 32(%esp),%ebp + xorl %eax,%eax + andl $4294967288,%ebp + jz .L026aw_finish +.L027aw_loop: + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl 4(%esi),%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl 8(%esi),%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl 12(%esi),%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl 16(%esi),%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl 20(%esi),%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl 24(%esi),%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl 28(%esi),%ecx + movl 28(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%esi + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L027aw_loop +.L026aw_finish: + movl 32(%esp),%ebp + andl $7,%ebp + jz .L028aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,(%ebx) + jz .L028aw_end + + movl 4(%esi),%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,4(%ebx) + jz .L028aw_end + + movl 8(%esi),%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,8(%ebx) + jz .L028aw_end + + movl 12(%esi),%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,12(%ebx) + jz .L028aw_end + + movl 16(%esi),%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,16(%ebx) + jz .L028aw_end + + movl 20(%esi),%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,20(%ebx) + jz .L028aw_end + + movl 24(%esi),%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) +.L028aw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_sub_words,.-.L_bn_sub_words_begin +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/add.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/add.c new file mode 100644 index 00000000..35a55255 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/add.c @@ -0,0 +1,316 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include + +#include "internal.h" + + +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + const BIGNUM *tmp; + int a_neg = a->neg, ret; + + // a + b a+b + // a + -b a-b + // -a + b b-a + // -a + -b -(a+b) + if (a_neg ^ b->neg) { + // only one is negative + if (a_neg) { + tmp = a; + a = b; + b = tmp; + } + + // we are now a - b + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) { + return 0; + } + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) { + return 0; + } + r->neg = 0; + } + return 1; + } + + ret = BN_uadd(r, a, b); + r->neg = a_neg; + return ret; +} + +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // Widths are public, so we normalize to make |a| the larger one. + if (a->width < b->width) { + const BIGNUM *tmp = a; + a = b; + b = tmp; + } + + int max = a->width; + int min = b->width; + if (!bn_wexpand(r, max + 1)) { + return 0; + } + r->width = max + 1; + + BN_ULONG carry = bn_add_words(r->d, a->d, b->d, min); + for (int i = min; i < max; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = carry + a->d[i]; + carry = tmp < a->d[i]; + r->d[i] = tmp; + } + + r->d[max] = carry; + return 1; +} + +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_uadd_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_add_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG l; + int i; + + // degenerate case: w is zero + if (!w) { + return 1; + } + + // degenerate case: a is zero + if (BN_is_zero(a)) { + return BN_set_word(a, w); + } + + // handle 'a' when negative + if (a->neg) { + a->neg = 0; + i = BN_sub_word(a, w); + if (!BN_is_zero(a)) { + a->neg = !(a->neg); + } + return i; + } + + for (i = 0; w != 0 && i < a->width; i++) { + a->d[i] = l = a->d[i] + w; + w = (w > l) ? 1 : 0; + } + + if (w && i == a->width) { + if (!bn_wexpand(a, a->width + 1)) { + return 0; + } + a->width++; + a->d[i] = w; + } + + return 1; +} + +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + int add = 0, neg = 0; + const BIGNUM *tmp; + + // a - b a-b + // a - -b a+b + // -a - b -(a+b) + // -a - -b b-a + if (a->neg) { + if (b->neg) { + tmp = a; + a = b; + b = tmp; + } else { + add = 1; + neg = 1; + } + } else { + if (b->neg) { + add = 1; + neg = 0; + } + } + + if (add) { + if (!BN_uadd(r, a, b)) { + return 0; + } + + r->neg = neg; + return 1; + } + + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) { + return 0; + } + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) { + return 0; + } + r->neg = 0; + } + + return 1; +} + +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // |b| may have more words than |a| given non-minimal inputs, but all words + // beyond |a->width| must then be zero. + int b_width = b->width; + if (b_width > a->width) { + if (!bn_fits_in_words(b, a->width)) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + b_width = a->width; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + + BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width); + for (int i = b_width; i < a->width; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = a->d[i]; + r->d[i] = a->d[i] - borrow; + borrow = tmp < r->d[i]; + } + + if (borrow) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + + r->width = a->width; + r->neg = 0; + return 1; +} + +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_usub_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_sub_word(BIGNUM *a, BN_ULONG w) { + int i; + + // degenerate case: w is zero + if (!w) { + return 1; + } + + // degenerate case: a is zero + if (BN_is_zero(a)) { + i = BN_set_word(a, w); + if (i != 0) { + BN_set_negative(a, 1); + } + return i; + } + + // handle 'a' when negative + if (a->neg) { + a->neg = 0; + i = BN_add_word(a, w); + a->neg = 1; + return i; + } + + if ((bn_minimal_width(a) == 1) && (a->d[0] < w)) { + a->d[0] = w - a->d[0]; + a->neg = 1; + return 1; + } + + i = 0; + for (;;) { + if (a->d[i] >= w) { + a->d[i] -= w; + break; + } else { + a->d[i] -= w; + i++; + w = 1; + } + } + + if ((a->d[i] == 0) && (i == (a->width - 1))) { + a->width--; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/asm/x86_64-gcc.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/asm/x86_64-gcc.c new file mode 100644 index 00000000..6e6d71dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/asm/x86_64-gcc.c @@ -0,0 +1,541 @@ +/* x86_64 BIGNUM accelerator version 0.1, December 2002. + * + * Implemented by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real + * versions, like 1.0... + * A. Well, that's because this code is basically a quick-n-dirty + * proof-of-concept hack. As you can see it's implemented with + * inline assembler, which means that you're bound to GCC and that + * there might be enough room for further improvement. + * + * Q. Why inline assembler? + * A. x86_64 features own ABI which I'm not familiar with. This is + * why I decided to let the compiler take care of subroutine + * prologue/epilogue as well as register allocation. For reference. + * Win64 implements different ABI for AMD64, different from Linux. + * + * Q. How much faster does it get? + * A. 'apps/openssl speed rsa dsa' output with no-asm: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2 + * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0 + * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8 + * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6 + * sign verify sign/s verify/s + * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3 + * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2 + * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0 + * + * 'apps/openssl speed rsa dsa' output with this module: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9 + * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7 + * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0 + * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8 + * sign verify sign/s verify/s + * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3 + * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4 + * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6 + * + * For the reference. IA-32 assembler implementation performs + * very much like 64-bit code compiled with no-asm on the same + * machine. + */ + +#include + +// TODO(davidben): Get this file working on MSVC x64. +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) + +#include "../internal.h" + + +#undef mul +#undef mul_add + +// "m"(a), "+m"(r) is the way to favor DirectPath µ-code; +// "g"(0) let the compiler to decide where does it +// want to keep the value of zero; +#define mul_add(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "m"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+m"(r), "+d"(high) \ + : "r"(carry), "g"(0) \ + : "cc"); \ + (carry) = high; \ + } while (0) + +#define mul(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "g"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + (r) = (carry); \ + (carry) = high; \ + } while (0) +#undef sqr +#define sqr(r0, r1, a) __asm__("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc"); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return (c1); + } + + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + if (num) { + mul_add(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[2], ap[2], w, c1); + return c1; + } + + return c1; +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + if (num) { + mul(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[2], ap[2], w, c1); + } + return c1; +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { + if (n == 0) { + return; + } + + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } + if (n) { + sqr(r[0], r[1], a[0]); + if (--n == 0) { + return; + } + sqr(r[2], r[3], a[1]); + if (--n == 0) { + return; + } + sqr(r[4], r[5], a[2]); + } +} + +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear carry + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " adcq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear borrow + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " sbbq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +// mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) +// mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) +// sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) +// sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) + +// Keep in mind that carrying into high part of multiplication result can not +// overflow, because it cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %2" : "=a"(t1), "=d"(t2) : "a"((a)[i]) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef sqr_add_c +#undef mul_add_c2 +#undef sqr_add_c2 + +#endif // !NO_ASM && X86_64 && (__GNUC__ || __clang__) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c new file mode 100644 index 00000000..ae07fd35 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c @@ -0,0 +1,438 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "internal.h" +#include "../delocate.h" + + +BIGNUM *BN_new(void) { + BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM)); + + if (bn == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); + bn->flags = BN_FLG_MALLOCED; + + return bn; +} + +void BN_init(BIGNUM *bn) { + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); +} + +void BN_free(BIGNUM *bn) { + if (bn == NULL) { + return; + } + + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } + + if (bn->flags & BN_FLG_MALLOCED) { + OPENSSL_free(bn); + } else { + bn->d = NULL; + } +} + +void BN_clear_free(BIGNUM *bn) { + BN_free(bn); +} + +BIGNUM *BN_dup(const BIGNUM *src) { + BIGNUM *copy; + + if (src == NULL) { + return NULL; + } + + copy = BN_new(); + if (copy == NULL) { + return NULL; + } + + if (!BN_copy(copy, src)) { + BN_free(copy); + return NULL; + } + + return copy; +} + +BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src) { + if (src == dest) { + return dest; + } + + if (!bn_wexpand(dest, src->width)) { + return NULL; + } + + OPENSSL_memcpy(dest->d, src->d, sizeof(src->d[0]) * src->width); + + dest->width = src->width; + dest->neg = src->neg; + return dest; +} + +void BN_clear(BIGNUM *bn) { + if (bn->d != NULL) { + OPENSSL_memset(bn->d, 0, bn->dmax * sizeof(bn->d[0])); + } + + bn->width = 0; + bn->neg = 0; +} + +DEFINE_METHOD_FUNCTION(BIGNUM, BN_value_one) { + static const BN_ULONG kOneLimbs[1] = { 1 }; + out->d = (BN_ULONG*) kOneLimbs; + out->width = 1; + out->dmax = 1; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +// BN_num_bits_word returns the minimum number of bits needed to represent the +// value in |l|. +unsigned BN_num_bits_word(BN_ULONG l) { + // |BN_num_bits| is often called on RSA prime factors. These have public bit + // lengths, but all bits beyond the high bit are secret, so count bits in + // constant time. + BN_ULONG x, mask; + int bits = (l != 0); + +#if BN_BITS2 > 32 + // Look at the upper half of |x|. |x| is at most 64 bits long. + x = l >> 32; + // Set |mask| to all ones if |x| (the top 32 bits of |l|) is non-zero and all + // all zeros otherwise. + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + // If |x| is non-zero, the lower half is included in the bit count in full, + // and we count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l ^= (x ^ l) & mask; // |l| is |x| if |mask| and remains |l| otherwise. +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + x = l >> 16; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 16 & mask; + l ^= (x ^ l) & mask; + + x = l >> 8; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 8 & mask; + l ^= (x ^ l) & mask; + + x = l >> 4; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 4 & mask; + l ^= (x ^ l) & mask; + + x = l >> 2; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 2 & mask; + l ^= (x ^ l) & mask; + + x = l >> 1; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 1 & mask; + + return bits; +} + +unsigned BN_num_bits(const BIGNUM *bn) { + const int width = bn_minimal_width(bn); + if (width == 0) { + return 0; + } + + return (width - 1) * BN_BITS2 + BN_num_bits_word(bn->d[width - 1]); +} + +unsigned BN_num_bytes(const BIGNUM *bn) { + return (BN_num_bits(bn) + 7) / 8; +} + +void BN_zero(BIGNUM *bn) { + bn->width = bn->neg = 0; +} + +int BN_one(BIGNUM *bn) { + return BN_set_word(bn, 1); +} + +int BN_set_word(BIGNUM *bn, BN_ULONG value) { + if (value == 0) { + BN_zero(bn); + return 1; + } + + if (!bn_wexpand(bn, 1)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = value; + bn->width = 1; + return 1; +} + +int BN_set_u64(BIGNUM *bn, uint64_t value) { +#if BN_BITS2 == 64 + return BN_set_word(bn, value); +#elif BN_BITS2 == 32 + if (value <= BN_MASK2) { + return BN_set_word(bn, (BN_ULONG)value); + } + + if (!bn_wexpand(bn, 2)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = (BN_ULONG)value; + bn->d[1] = (BN_ULONG)(value >> 32); + bn->width = 2; + return 1; +#else +#error "BN_BITS2 must be 32 or 64." +#endif +} + +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) { + if (!bn_wexpand(bn, num)) { + return 0; + } + OPENSSL_memmove(bn->d, words, num * sizeof(BN_ULONG)); + // |bn_wexpand| verified that |num| isn't too large. + bn->width = (int)num; + bn->neg = 0; + return 1; +} + +void bn_set_static_words(BIGNUM *bn, const BN_ULONG *words, size_t num) { + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } + bn->d = (BN_ULONG *)words; + + bn->width = num; + bn->dmax = num; + bn->neg = 0; + bn->flags |= BN_FLG_STATIC_DATA; +} + +int bn_fits_in_words(const BIGNUM *bn, size_t num) { + // All words beyond |num| must be zero. + BN_ULONG mask = 0; + for (size_t i = num; i < (size_t)bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn) { + if (bn->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + size_t width = (size_t)bn->width; + if (width > num) { + if (!bn_fits_in_words(bn, num)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + width = num; + } + + OPENSSL_memset(out, 0, sizeof(BN_ULONG) * num); + OPENSSL_memcpy(out, bn->d, sizeof(BN_ULONG) * width); + return 1; +} + +int BN_is_negative(const BIGNUM *bn) { + return bn->neg != 0; +} + +void BN_set_negative(BIGNUM *bn, int sign) { + if (sign && !BN_is_zero(bn)) { + bn->neg = 1; + } else { + bn->neg = 0; + } +} + +int bn_wexpand(BIGNUM *bn, size_t words) { + BN_ULONG *a; + + if (words <= (size_t)bn->dmax) { + return 1; + } + + if (words > (INT_MAX / (4 * BN_BITS2))) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + + if (bn->flags & BN_FLG_STATIC_DATA) { + OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return 0; + } + + a = OPENSSL_malloc(sizeof(BN_ULONG) * words); + if (a == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(a, bn->d, sizeof(BN_ULONG) * bn->width); + + OPENSSL_free(bn->d); + bn->d = a; + bn->dmax = (int)words; + + return 1; +} + +int bn_expand(BIGNUM *bn, size_t bits) { + if (bits + BN_BITS2 - 1 < bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2); +} + +int bn_resize_words(BIGNUM *bn, size_t words) { +#if defined(OPENSSL_PPC64LE) + // This is a workaround for a miscompilation bug in Clang 7.0.1 on POWER. + // The unittests catch the miscompilation, if it occurs, and it manifests + // as a crash in |bn_fits_in_words|. + // + // The bug only triggers if building in FIPS mode and with -O3. Clang 8.0.1 + // has the same bug but this workaround is not effective there---I've not + // been able to find a workaround for 8.0.1. + // + // At the time of writing (2019-08-08), Clang git does *not* have this bug + // and does not need this workaroud. The current git version should go on to + // be Clang 10 thus, once we can depend on that, this can be removed. + if (value_barrier_w((size_t)bn->width == words)) { + return 1; + } +#endif + + if ((size_t)bn->width <= words) { + if (!bn_wexpand(bn, words)) { + return 0; + } + OPENSSL_memset(bn->d + bn->width, 0, + (words - bn->width) * sizeof(BN_ULONG)); + bn->width = words; + return 1; + } + + // All words beyond the new width must be zero. + if (!bn_fits_in_words(bn, words)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + bn->width = words; + return 1; +} + +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num) { + for (size_t i = 0; i < num; i++) { + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + r[i] = constant_time_select_w(mask, a[i], b[i]); + } +} + +int bn_minimal_width(const BIGNUM *bn) { + int ret = bn->width; + while (ret > 0 && bn->d[ret - 1] == 0) { + ret--; + } + return ret; +} + +void bn_set_minimal_width(BIGNUM *bn) { + bn->width = bn_minimal_width(bn); + if (bn->width == 0) { + bn->neg = 0; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c new file mode 100644 index 00000000..78041183 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c @@ -0,0 +1,230 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "internal.h" + + +BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + size_t num_words; + unsigned m; + BN_ULONG word = 0; + BIGNUM *bn = NULL; + + if (ret == NULL) { + ret = bn = BN_new(); + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + return ret; + } + + num_words = ((len - 1) / BN_BYTES) + 1; + m = (len - 1) % BN_BYTES; + if (!bn_wexpand(ret, num_words)) { + if (bn) { + BN_free(bn); + } + return NULL; + } + + // |bn_wexpand| must check bounds on |num_words| to write it into + // |ret->dmax|. + assert(num_words <= INT_MAX); + ret->width = (int)num_words; + ret->neg = 0; + + while (len--) { + word = (word << 8) | *(in++); + if (m-- == 0) { + ret->d[--num_words] = word; + word = 0; + m = BN_BYTES - 1; + } + } + + return ret; +} + +BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + BIGNUM *bn = NULL; + if (ret == NULL) { + bn = BN_new(); + ret = bn; + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + ret->neg = 0; + return ret; + } + + // Reserve enough space in |ret|. + size_t num_words = ((len - 1) / BN_BYTES) + 1; + if (!bn_wexpand(ret, num_words)) { + BN_free(bn); + return NULL; + } + ret->width = num_words; + + // Make sure the top bytes will be zeroed. + ret->d[num_words - 1] = 0; + + // We only support little-endian platforms, so we can simply memcpy the + // internal representation. + OPENSSL_memcpy(ret->d, in, len); + return ret; +} + +size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) { + size_t n, i; + BN_ULONG l; + + n = i = BN_num_bytes(in); + while (i--) { + l = in->d[i / BN_BYTES]; + *(out++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + } + return n; +} + +static int fits_in_bytes(const uint8_t *bytes, size_t num_bytes, size_t len) { + uint8_t mask = 0; + for (size_t i = len; i < num_bytes; i++) { + mask |= bytes[i]; + } + return mask == 0; +} + +int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply memcpy into the + // internal representation. + OPENSSL_memcpy(out, bytes, num_bytes); + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out + num_bytes, 0, len - num_bytes); + return 1; +} + +int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply write the buffer + // in reverse. + for (size_t i = 0; i < num_bytes; i++) { + out[len - i - 1] = bytes[i]; + } + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out, 0, len - num_bytes); + return 1; +} + +BN_ULONG BN_get_word(const BIGNUM *bn) { + switch (bn_minimal_width(bn)) { + case 0: + return 0; + case 1: + return bn->d[0]; + default: + return BN_MASK2; + } +} + +int BN_get_u64(const BIGNUM *bn, uint64_t *out) { + switch (bn_minimal_width(bn)) { + case 0: + *out = 0; + return 1; + case 1: + *out = bn->d[0]; + return 1; +#if defined(OPENSSL_32_BIT) + case 2: + *out = (uint64_t) bn->d[0] | (((uint64_t) bn->d[1]) << 32); + return 1; +#endif + default: + return 0; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/cmp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/cmp.c new file mode 100644 index 00000000..18b2b658 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/cmp.c @@ -0,0 +1,200 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +static int bn_cmp_words_consttime(const BN_ULONG *a, size_t a_len, + const BN_ULONG *b, size_t b_len) { + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + int ret = 0; + // Process the common words in little-endian order. + size_t min = a_len < b_len ? a_len : b_len; + for (size_t i = 0; i < min; i++) { + crypto_word_t eq = constant_time_eq_w(a[i], b[i]); + crypto_word_t lt = constant_time_lt_w(a[i], b[i]); + ret = + constant_time_select_int(eq, ret, constant_time_select_int(lt, -1, 1)); + } + + // If |a| or |b| has non-zero words beyond |min|, they take precedence. + if (a_len < b_len) { + crypto_word_t mask = 0; + for (size_t i = a_len; i < b_len; i++) { + mask |= b[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, -1); + } else if (b_len < a_len) { + crypto_word_t mask = 0; + for (size_t i = b_len; i < a_len; i++) { + mask |= a[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, 1); + } + + return ret; +} + +int BN_ucmp(const BIGNUM *a, const BIGNUM *b) { + return bn_cmp_words_consttime(a->d, a->width, b->d, b->width); +} + +int BN_cmp(const BIGNUM *a, const BIGNUM *b) { + if ((a == NULL) || (b == NULL)) { + if (a != NULL) { + return -1; + } else if (b != NULL) { + return 1; + } else { + return 0; + } + } + + // We do not attempt to process the sign bit in constant time. Negative + // |BIGNUM|s should never occur in crypto, only calculators. + if (a->neg != b->neg) { + if (a->neg) { + return -1; + } + return 1; + } + + int ret = BN_ucmp(a, b); + return a->neg ? -ret : ret; +} + +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len) { + return bn_cmp_words_consttime(a, len, b, len) < 0; +} + +int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) { + if (bn->width == 0) { + return w == 0; + } + BN_ULONG mask = bn->d[0] ^ w; + for (int i = 1; i < bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { + BIGNUM b_bn; + BN_init(&b_bn); + + b_bn.d = &b; + b_bn.width = b > 0; + b_bn.dmax = 1; + b_bn.flags = BN_FLG_STATIC_DATA; + return BN_cmp(a, &b_bn); +} + +int BN_is_zero(const BIGNUM *bn) { + return bn_fits_in_words(bn, 0); +} + +int BN_is_one(const BIGNUM *bn) { + return bn->neg == 0 && BN_abs_is_word(bn, 1); +} + +int BN_is_word(const BIGNUM *bn, BN_ULONG w) { + return BN_abs_is_word(bn, w) && (w == 0 || bn->neg == 0); +} + +int BN_is_odd(const BIGNUM *bn) { + return bn->width > 0 && (bn->d[0] & 1) == 1; +} + +int BN_is_pow2(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + if (width == 0 || bn->neg) { + return 0; + } + + for (int i = 0; i < width - 1; i++) { + if (bn->d[i] != 0) { + return 0; + } + } + + return 0 == (bn->d[width-1] & (bn->d[width-1] - 1)); +} + +int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b) { + BN_ULONG mask = 0; + // If |a| or |b| has more words than the other, all those words must be zero. + for (int i = a->width; i < b->width; i++) { + mask |= b->d[i]; + } + for (int i = b->width; i < a->width; i++) { + mask |= a->d[i]; + } + // Common words must match. + int min = a->width < b->width ? a->width : b->width; + for (int i = 0; i < min; i++) { + mask |= (a->d[i] ^ b->d[i]); + } + // The sign bit must match. + mask |= (a->neg ^ b->neg); + return mask == 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c new file mode 100644 index 00000000..0c471c4e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c @@ -0,0 +1,236 @@ +/* Written by Ulf Moeller for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + + +#include + +#include +#include + +#include +#include + +#include "../../internal.h" + + +// The stack frame info is resizing, set a first-time expansion size; +#define BN_CTX_START_FRAMES 32 + + +// BN_STACK + +// A |BN_STACK| is a stack of |size_t| values. +typedef struct { + // Array of indexes into |ctx->bignums|. + size_t *indexes; + // Number of stack frames, and the size of the allocated array + size_t depth, size; +} BN_STACK; + +static void BN_STACK_init(BN_STACK *); +static void BN_STACK_cleanup(BN_STACK *); +static int BN_STACK_push(BN_STACK *, size_t idx); +static size_t BN_STACK_pop(BN_STACK *); + + +// BN_CTX + +DEFINE_STACK_OF(BIGNUM) + +// The opaque BN_CTX type +struct bignum_ctx { + // bignums is the stack of |BIGNUM|s managed by this |BN_CTX|. + STACK_OF(BIGNUM) *bignums; + // stack is the stack of |BN_CTX_start| frames. It is the value of |used| at + // the time |BN_CTX_start| was called. + BN_STACK stack; + // used is the number of |BIGNUM|s from |bignums| that have been used. + size_t used; + // error is one if any operation on this |BN_CTX| failed. All subsequent + // operations will fail. + char error; + // defer_error is one if an operation on this |BN_CTX| has failed, but no + // error has been pushed to the queue yet. This is used to defer errors from + // |BN_CTX_start| to |BN_CTX_get|. + char defer_error; +}; + +BN_CTX *BN_CTX_new(void) { + BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + // Initialise the structure + ret->bignums = NULL; + BN_STACK_init(&ret->stack); + ret->used = 0; + ret->error = 0; + ret->defer_error = 0; + return ret; +} + +void BN_CTX_free(BN_CTX *ctx) { + if (ctx == NULL) { + return; + } + + // All |BN_CTX_start| calls must be matched with |BN_CTX_end|, otherwise the + // function may use more memory than expected, potentially without bound if + // done in a loop. Assert that all |BIGNUM|s have been released. + assert(ctx->used == 0 || ctx->error); + sk_BIGNUM_pop_free(ctx->bignums, BN_free); + BN_STACK_cleanup(&ctx->stack); + OPENSSL_free(ctx); +} + +void BN_CTX_start(BN_CTX *ctx) { + if (ctx->error) { + // Once an operation has failed, |ctx->stack| no longer matches the number + // of |BN_CTX_end| calls to come. Do nothing. + return; + } + + if (!BN_STACK_push(&ctx->stack, ctx->used)) { + ctx->error = 1; + // |BN_CTX_start| cannot fail, so defer the error to |BN_CTX_get|. + ctx->defer_error = 1; + } +} + +BIGNUM *BN_CTX_get(BN_CTX *ctx) { + // Once any operation has failed, they all do. + if (ctx->error) { + if (ctx->defer_error) { + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ctx->defer_error = 0; + } + return NULL; + } + + if (ctx->bignums == NULL) { + ctx->bignums = sk_BIGNUM_new_null(); + if (ctx->bignums == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + ctx->error = 1; + return NULL; + } + } + + if (ctx->used == sk_BIGNUM_num(ctx->bignums)) { + BIGNUM *bn = BN_new(); + if (bn == NULL || !sk_BIGNUM_push(ctx->bignums, bn)) { + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + BN_free(bn); + ctx->error = 1; + return NULL; + } + } + + BIGNUM *ret = sk_BIGNUM_value(ctx->bignums, ctx->used); + BN_zero(ret); + // This is bounded by |sk_BIGNUM_num|, so it cannot overflow. + ctx->used++; + return ret; +} + +void BN_CTX_end(BN_CTX *ctx) { + if (ctx->error) { + // Once an operation has failed, |ctx->stack| no longer matches the number + // of |BN_CTX_end| calls to come. Do nothing. + return; + } + + ctx->used = BN_STACK_pop(&ctx->stack); +} + + +// BN_STACK + +static void BN_STACK_init(BN_STACK *st) { + st->indexes = NULL; + st->depth = st->size = 0; +} + +static void BN_STACK_cleanup(BN_STACK *st) { + OPENSSL_free(st->indexes); +} + +static int BN_STACK_push(BN_STACK *st, size_t idx) { + if (st->depth == st->size) { + // This function intentionally does not push to the error queue on error. + // Error-reporting is deferred to |BN_CTX_get|. + size_t new_size = st->size != 0 ? st->size * 3 / 2 : BN_CTX_START_FRAMES; + if (new_size <= st->size || new_size > ((size_t)-1) / sizeof(size_t)) { + return 0; + } + size_t *new_indexes = + OPENSSL_realloc(st->indexes, new_size * sizeof(size_t)); + if (new_indexes == NULL) { + return 0; + } + st->indexes = new_indexes; + st->size = new_size; + } + + st->indexes[st->depth] = idx; + st->depth++; + return 1; +} + +static size_t BN_STACK_pop(BN_STACK *st) { + assert(st->depth > 0); + st->depth--; + return st->indexes[st->depth]; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div.c new file mode 100644 index 00000000..31c33104 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div.c @@ -0,0 +1,902 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include + +#include "internal.h" + + +// bn_div_words divides a double-width |h|,|l| by |d| and returns the result, +// which must fit in a |BN_ULONG|. +OPENSSL_UNUSED static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, + BN_ULONG d) { + BN_ULONG dh, dl, q, ret = 0, th, tl, t; + int i, count = 2; + + if (d == 0) { + return BN_MASK2; + } + + i = BN_num_bits_word(d); + assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); + + i = BN_BITS2 - i; + if (h >= d) { + h -= d; + } + + if (i) { + d <<= i; + h = (h << i) | (l >> (BN_BITS2 - i)); + l <<= i; + } + dh = (d & BN_MASK2h) >> BN_BITS4; + dl = (d & BN_MASK2l); + for (;;) { + if ((h >> BN_BITS4) == dh) { + q = BN_MASK2l; + } else { + q = h / dh; + } + + th = q * dh; + tl = dl * q; + for (;;) { + t = h - th; + if ((t & BN_MASK2h) || + ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) { + break; + } + q--; + th -= dh; + tl -= dl; + } + t = (tl >> BN_BITS4); + tl = (tl << BN_BITS4) & BN_MASK2h; + th += t; + + if (l < tl) { + th++; + } + l -= tl; + if (h < th) { + h += d; + q--; + } + h -= th; + + if (--count == 0) { + break; + } + + ret = q << BN_BITS4; + h = (h << BN_BITS4) | (l >> BN_BITS4); + l = (l & BN_MASK2l) << BN_BITS4; + } + + ret |= q; + return ret; +} + +static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out, + BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) { + // GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when + // the |BN_ULLONG|-based C code is used. + // + // GCC bugs: + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668 + // + // Clang bugs: + // * https://llvm.org/bugs/show_bug.cgi?id=6397 + // * https://llvm.org/bugs/show_bug.cgi?id=12418 + // + // These issues aren't specific to x86 and x86_64, so it might be worthwhile + // to add more assembly language implementations. +#if defined(BN_CAN_USE_INLINE_ASM) && defined(OPENSSL_X86) + __asm__ volatile("divl %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#elif defined(BN_CAN_USE_INLINE_ASM) && defined(OPENSSL_X86_64) + __asm__ volatile("divq %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#else +#if defined(BN_CAN_DIVIDE_ULLONG) + BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1; + *quotient_out = (BN_ULONG)(n / d0); +#else + *quotient_out = bn_div_words(n0, n1, d0); +#endif + *rem_out = n1 - (*quotient_out * d0); +#endif +} + +// BN_div computes "quotient := numerator / divisor", rounding towards zero, +// and sets up |rem| such that "quotient * divisor + rem = numerator" holds. +// +// Thus: +// +// quotient->neg == numerator->neg ^ divisor->neg +// (unless the result is zero) +// rem->neg == numerator->neg +// (unless the remainder is zero) +// +// If |quotient| or |rem| is NULL, the respective value is not returned. +// +// This was specifically designed to contain fewer branches that may leak +// sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL +// and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and +// Jean-Pierre Seifert. +int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) { + int norm_shift, loop; + BIGNUM wnum; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + + // This function relies on the historical minimal-width |BIGNUM| invariant. + // It is already not constant-time (constant-time reductions should use + // Montgomery logic), so we shrink all inputs and intermediate values to + // retain the previous behavior. + + // Invalid zero-padding would have particularly bad consequences. + int numerator_width = bn_minimal_width(numerator); + int divisor_width = bn_minimal_width(divisor); + if ((numerator_width > 0 && numerator->d[numerator_width - 1] == 0) || + (divisor_width > 0 && divisor->d[divisor_width - 1] == 0)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED); + return 0; + } + + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *snum = BN_CTX_get(ctx); + BIGNUM *sdiv = BN_CTX_get(ctx); + BIGNUM *res = NULL; + if (quotient == NULL) { + res = BN_CTX_get(ctx); + } else { + res = quotient; + } + if (sdiv == NULL || res == NULL) { + goto err; + } + + // First we normalise the numbers + norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2); + if (!BN_lshift(sdiv, divisor, norm_shift)) { + goto err; + } + bn_set_minimal_width(sdiv); + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!BN_lshift(snum, numerator, norm_shift)) { + goto err; + } + bn_set_minimal_width(snum); + snum->neg = 0; + + // Since we don't want to have special-case logic for the case where snum is + // larger than sdiv, we pad snum with enough zeroes without changing its + // value. + if (snum->width <= sdiv->width + 1) { + if (!bn_wexpand(snum, sdiv->width + 2)) { + goto err; + } + for (int i = snum->width; i < sdiv->width + 2; i++) { + snum->d[i] = 0; + } + snum->width = sdiv->width + 2; + } else { + if (!bn_wexpand(snum, snum->width + 1)) { + goto err; + } + snum->d[snum->width] = 0; + snum->width++; + } + + div_n = sdiv->width; + num_n = snum->width; + loop = num_n - div_n; + // Lets setup a 'window' into snum + // This is the part that corresponds to the current + // 'area' being divided + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.width = div_n; + // only needed when BN_ucmp messes up the values between width and max + wnum.dmax = snum->dmax - loop; // so we don't step out of bounds + + // Get the top 2 words of sdiv + // div_n=sdiv->width; + d0 = sdiv->d[div_n - 1]; + d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2]; + + // pointer to the 'top' of snum + wnump = &(snum->d[num_n - 1]); + + // Setup |res|. |numerator| and |res| may alias, so we save |numerator->neg| + // for later. + const int numerator_neg = numerator->neg; + res->neg = (numerator_neg ^ divisor->neg); + if (!bn_wexpand(res, loop + 1)) { + goto err; + } + res->width = loop - 1; + resp = &(res->d[loop - 1]); + + // space for temp + if (!bn_wexpand(tmp, div_n + 1)) { + goto err; + } + + // if res->width == 0 then clear the neg value otherwise decrease + // the resp pointer + if (res->width == 0) { + res->neg = 0; + } else { + resp--; + } + + for (int i = 0; i < loop - 1; i++, wnump--, resp--) { + BN_ULONG q, l0; + // the first part of the loop uses the top two words of snum and sdiv to + // calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv + BN_ULONG n0, n1, rm = 0; + + n0 = wnump[0]; + n1 = wnump[-1]; + if (n0 == d0) { + q = BN_MASK2; + } else { + // n0 < d0 + bn_div_rem_words(&q, &rm, n0, n1, d0); + +#ifdef BN_ULLONG + BN_ULLONG t2 = (BN_ULLONG)d1 * q; + for (;;) { + if (t2 <= ((((BN_ULLONG)rm) << BN_BITS2) | wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + t2 -= d1; + } +#else // !BN_ULLONG + BN_ULONG t2l, t2h; + BN_UMULT_LOHI(t2l, t2h, d1, q); + for (;;) { + if (t2h < rm || + (t2h == rm && t2l <= wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + if (t2l < d1) { + t2h--; + } + t2l -= d1; + } +#endif // !BN_ULLONG + } + + l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); + tmp->d[div_n] = l0; + wnum.d--; + // ingore top values of the bignums just sub the two + // BN_ULONG arrays with bn_sub_words + if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) { + // Note: As we have considered only the leading + // two BN_ULONGs in the calculation of q, sdiv * q + // might be greater than wnum (but then (q-1) * sdiv + // is less or equal than wnum) + q--; + if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) { + // we can't have an overflow here (assuming + // that q != 0, but if q == 0 then tmp is + // zero anyway) + (*wnump)++; + } + } + // store part of the result + *resp = q; + } + + bn_set_minimal_width(snum); + + if (rem != NULL) { + if (!BN_rshift(rem, snum, norm_shift)) { + goto err; + } + if (!BN_is_zero(rem)) { + rem->neg = numerator_neg; + } + } + + bn_set_minimal_width(res); + BN_CTX_end(ctx); + return 1; + +err: + BN_CTX_end(ctx); + return 0; +} + +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { + if (!(BN_mod(r, m, d, ctx))) { + return 0; + } + if (!r->neg) { + return 1; + } + + // now -|d| < r < 0, so we have to set r := r + |d|. + return (d->neg ? BN_sub : BN_add)(r, r, d); +} + +BN_ULONG bn_reduce_once(BN_ULONG *r, const BN_ULONG *a, BN_ULONG carry, + const BN_ULONG *m, size_t num) { + assert(r != a); + // |r| = |a| - |m|. |bn_sub_words| performs the bulk of the subtraction, and + // then we apply the borrow to |carry|. + carry -= bn_sub_words(r, a, m, num); + // We know 0 <= |a| < 2*|m|, so -|m| <= |r| < |m|. + // + // If 0 <= |r| < |m|, |r| fits in |num| words and |carry| is zero. We then + // wish to select |r| as the answer. Otherwise -m <= r < 0 and we wish to + // return |r| + |m|, or |a|. |carry| must then be -1 or all ones. In both + // cases, |carry| is a suitable input to |bn_select_words|. + // + // Although |carry| may be one if it was one on input and |bn_sub_words| + // returns zero, this would give |r| > |m|, violating our input assumptions. + assert(carry == 0 || carry == (BN_ULONG)-1); + bn_select_words(r, carry, a /* r < 0 */, r /* r >= 0 */, num); + return carry; +} + +BN_ULONG bn_reduce_once_in_place(BN_ULONG *r, BN_ULONG carry, const BN_ULONG *m, + BN_ULONG *tmp, size_t num) { + // See |bn_reduce_once| for why this logic works. + carry -= bn_sub_words(tmp, r, m, num); + assert(carry == 0 || carry == (BN_ULONG)-1); + bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); + return carry; +} + +void bn_mod_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + // r = a - b + BN_ULONG borrow = bn_sub_words(r, a, b, num); + // tmp = a - b + m + bn_add_words(tmp, r, m, num); + bn_select_words(r, 0 - borrow, tmp /* r < 0 */, r /* r >= 0 */, num); +} + +void bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + BN_ULONG carry = bn_add_words(r, a, b, num); + bn_reduce_once_in_place(r, carry, m, tmp, num); +} + +int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, const BIGNUM *divisor, + unsigned divisor_min_bits, BN_CTX *ctx) { + if (BN_is_negative(numerator) || BN_is_negative(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + // This function implements long division in binary. It is not very efficient, + // but it is simple, easy to make constant-time, and performant enough for RSA + // key generation. + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *q = quotient, *r = remainder; + if (quotient == NULL || quotient == numerator || quotient == divisor) { + q = BN_CTX_get(ctx); + } + if (remainder == NULL || remainder == numerator || remainder == divisor) { + r = BN_CTX_get(ctx); + } + BIGNUM *tmp = BN_CTX_get(ctx); + if (q == NULL || r == NULL || tmp == NULL || + !bn_wexpand(q, numerator->width) || + !bn_wexpand(r, divisor->width) || + !bn_wexpand(tmp, divisor->width)) { + goto err; + } + + OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG)); + q->width = numerator->width; + q->neg = 0; + + OPENSSL_memset(r->d, 0, divisor->width * sizeof(BN_ULONG)); + r->width = divisor->width; + r->neg = 0; + + // Incorporate |numerator| into |r|, one bit at a time, reducing after each + // step. We maintain the invariant that |0 <= r < divisor| and + // |q * divisor + r = n| where |n| is the portion of |numerator| incorporated + // so far. + // + // First, we short-circuit the loop: if we know |divisor| has at least + // |divisor_min_bits| bits, the top |divisor_min_bits - 1| can be incorporated + // without reductions. This significantly speeds up |RSA_check_key|. For + // simplicity, we round down to a whole number of words. + assert(divisor_min_bits <= BN_num_bits(divisor)); + int initial_words = 0; + if (divisor_min_bits > 0) { + initial_words = (divisor_min_bits - 1) / BN_BITS2; + if (initial_words > numerator->width) { + initial_words = numerator->width; + } + OPENSSL_memcpy(r->d, numerator->d + numerator->width - initial_words, + initial_words * sizeof(BN_ULONG)); + } + + for (int i = numerator->width - initial_words - 1; i >= 0; i--) { + for (int bit = BN_BITS2 - 1; bit >= 0; bit--) { + // Incorporate the next bit of the numerator, by computing + // r = 2*r or 2*r + 1. Note the result fits in one more word. We store the + // extra word in |carry|. + BN_ULONG carry = bn_add_words(r->d, r->d, r->d, divisor->width); + r->d[0] |= (numerator->d[i] >> bit) & 1; + // |r| was previously fully-reduced, so we know: + // 2*0 <= r <= 2*(divisor-1) + 1 + // 0 <= r <= 2*divisor - 1 < 2*divisor. + // Thus |r| satisfies the preconditions for |bn_reduce_once_in_place|. + BN_ULONG subtracted = bn_reduce_once_in_place(r->d, carry, divisor->d, + tmp->d, divisor->width); + // The corresponding bit of the quotient is set iff we needed to subtract. + q->d[i] |= (~subtracted & 1) << bit; + } + } + + if ((quotient != NULL && !BN_copy(quotient, q)) || + (remainder != NULL && !BN_copy(remainder, r))) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) { + BIGNUM *ret = BN_CTX_get(ctx); + if (ret == NULL || + !bn_wexpand(ret, width)) { + return NULL; + } + ret->neg = 0; + ret->width = width; + return ret; +} + +// bn_resized_from_ctx returns |bn| with width at least |width| or NULL on +// error. This is so it may be used with low-level "words" functions. If +// necessary, it allocates a new |BIGNUM| with a lifetime of the current scope +// in |ctx|, so the caller does not need to explicitly free it. |bn| must fit in +// |width| words. +static const BIGNUM *bn_resized_from_ctx(const BIGNUM *bn, size_t width, + BN_CTX *ctx) { + if ((size_t)bn->width >= width) { + // Any excess words must be zero. + assert(bn_fits_in_words(bn, width)); + return bn; + } + BIGNUM *ret = bn_scratch_space_from_ctx(width, ctx); + if (ret == NULL || + !BN_copy(ret, bn) || + !bn_resize_words(ret, width)) { + return NULL; + } + return ret; +} + +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) { + if (!BN_add(r, a, b)) { + return 0; + } + return BN_nnmod(r, r, m, ctx); +} + +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_add_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + r->neg = 0; + } + BN_CTX_end(ctx); + return ok; +} + +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) { + if (!BN_sub(r, a, b)) { + return 0; + } + return BN_nnmod(r, r, m, ctx); +} + +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + r->neg = 0; + } + BN_CTX_end(ctx); + return ok; +} + +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_sub_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) { + BIGNUM *t; + int ret = 0; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL) { + goto err; + } + + if (a == b) { + if (!BN_sqr(t, a, ctx)) { + goto err; + } + } else { + if (!BN_mul(t, a, b, ctx)) { + goto err; + } + } + + if (!BN_nnmod(r, t, m, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { + if (!BN_sqr(r, a, ctx)) { + return 0; + } + + // r->neg == 0, thus we don't need BN_nnmod + return BN_mod(r, r, m, ctx); +} + +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) { + BIGNUM *abs_m = NULL; + int ret; + + if (!BN_nnmod(r, a, m, ctx)) { + return 0; + } + + if (m->neg) { + abs_m = BN_dup(m); + if (abs_m == NULL) { + return 0; + } + abs_m->neg = 0; + } + + ret = bn_mod_lshift_consttime(r, r, n, (abs_m ? abs_m : m), ctx); + + BN_free(abs_m); + return ret; +} + +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) { + if (!BN_copy(r, a)) { + return 0; + } + for (int i = 0; i < n; i++) { + if (!bn_mod_lshift1_consttime(r, r, m, ctx)) { + return 0; + } + } + return 1; +} + +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift_consttime(r, a, n, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { + if (!BN_lshift1(r, a)) { + return 0; + } + + return BN_nnmod(r, r, m, ctx); +} + +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx) { + return bn_mod_add_consttime(r, a, a, m, ctx); +} + +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift1_consttime(r, a, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG ret = 0; + int i, j; + + if (!w) { + // actually this an error (division by zero) + return (BN_ULONG) - 1; + } + + if (a->width == 0) { + return 0; + } + + // normalize input for |bn_div_rem_words|. + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) { + return (BN_ULONG) - 1; + } + + for (i = a->width - 1; i >= 0; i--) { + BN_ULONG l = a->d[i]; + BN_ULONG d; + BN_ULONG unused_rem; + bn_div_rem_words(&d, &unused_rem, ret, l, w); + ret = l - (d * w); + a->d[i] = d; + } + + bn_set_minimal_width(a); + ret >>= j; + return ret; +} + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) { +#ifndef BN_CAN_DIVIDE_ULLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) { + return (BN_ULONG) -1; + } + +#ifndef BN_CAN_DIVIDE_ULLONG + // If |w| is too long and we don't have |BN_ULLONG| division then we need to + // fall back to using |BN_div_word|. + if (w > ((BN_ULONG)1 << BN_BITS4)) { + BIGNUM *tmp = BN_dup(a); + if (tmp == NULL) { + return (BN_ULONG)-1; + } + ret = BN_div_word(tmp, w); + BN_free(tmp); + return ret; + } +#endif + + for (i = a->width - 1; i >= 0; i--) { +#ifndef BN_CAN_DIVIDE_ULLONG + ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; + ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; +#else + ret = (BN_ULLONG)(((ret << (BN_ULLONG)BN_BITS2) | a->d[i]) % (BN_ULLONG)w); +#endif + } + return (BN_ULONG)ret; +} + +int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (e == 0 || a->width == 0) { + BN_zero(r); + return 1; + } + + size_t num_words = 1 + ((e - 1) / BN_BITS2); + + // If |a| definitely has less than |e| bits, just BN_copy. + if ((size_t) a->width < num_words) { + return BN_copy(r, a) != NULL; + } + + // Otherwise, first make sure we have enough space in |r|. + // Note that this will fail if num_words > INT_MAX. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Copy the content of |a| into |r|. + OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG)); + + // If |e| isn't word-aligned, we have to mask off some of our bits. + size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8); + if (top_word_exponent != 0) { + r->d[num_words - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Fill in the remaining fields of |r|. + r->neg = a->neg; + r->width = (int) num_words; + bn_set_minimal_width(r); + return 1; +} + +int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (!BN_mod_pow2(r, a, e)) { + return 0; + } + + // If the returned value was non-negative, we're done. + if (BN_is_zero(r) || !r->neg) { + return 1; + } + + size_t num_words = 1 + (e - 1) / BN_BITS2; + + // Expand |r| to the size of our modulus. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Clear the upper words of |r|. + OPENSSL_memset(&r->d[r->width], 0, (num_words - r->width) * BN_BYTES); + + // Set parameters of |r|. + r->neg = 0; + r->width = (int) num_words; + + // Now, invert every word. The idea here is that we want to compute 2^e-|x|, + // which is actually equivalent to the twos-complement representation of |x| + // in |e| bits, which is -x = ~x + 1. + for (int i = 0; i < r->width; i++) { + r->d[i] = ~r->d[i]; + } + + // If our exponent doesn't span the top word, we have to mask the rest. + size_t top_word_exponent = e % BN_BITS2; + if (top_word_exponent != 0) { + r->d[r->width - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Keep the minimal-width invariant for |BIGNUM|. + bn_set_minimal_width(r); + + // Finally, add one, for the reason described above. + return BN_add(r, r, BN_value_one()); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div_extra.c new file mode 100644 index 00000000..f81a4d3c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div_extra.c @@ -0,0 +1,87 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +// The following functions use a Barrett reduction variant to avoid leaking the +// numerator. See http://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html +// +// We use 32-bit numerator and 16-bit divisor for simplicity. This allows +// computing |m| and |q| without architecture-specific code. + +// mod_u16 returns |n| mod |d|. |p| and |m| are the "magic numbers" for |d| (see +// reference). For proof of correctness in Coq, see +// https://github.com/davidben/fiat-crypto/blob/barrett/src/Arithmetic/BarrettReduction/RidiculousFish.v +// Note the Coq version of |mod_u16| additionally includes the computation of +// |p| and |m| from |bn_mod_u16_consttime| below. +static uint16_t mod_u16(uint32_t n, uint16_t d, uint32_t p, uint32_t m) { + // Compute floor(n/d) per steps 3 through 5. + uint32_t q = ((uint64_t)m * n) >> 32; + // Note there is a typo in the reference. We right-shift by one, not two. + uint32_t t = ((n - q) >> 1) + q; + t = t >> (p - 1); + + // Multiply and subtract to get the remainder. + n -= d * t; + assert(n < d); + return n; +} + +// shift_and_add_mod_u16 returns |r| * 2^32 + |a| mod |d|. |p| and |m| are the +// "magic numbers" for |d| (see reference). +static uint16_t shift_and_add_mod_u16(uint16_t r, uint32_t a, uint16_t d, + uint32_t p, uint32_t m) { + // Incorporate |a| in two 16-bit chunks. + uint32_t t = r; + t <<= 16; + t |= a >> 16; + t = mod_u16(t, d, p, m); + + t <<= 16; + t |= a & 0xffff; + t = mod_u16(t, d, p, m); + return t; +} + +uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d) { + if (d <= 1) { + return 0; + } + + // Compute the "magic numbers" for |d|. See steps 1 and 2. + // This computes p = ceil(log_2(d)). + uint32_t p = BN_num_bits_word(d - 1); + // This operation is not constant-time, but |p| and |d| are public values. + // Note that |p| is at most 16, so the computation fits in |uint64_t|. + assert(p <= 16); + uint32_t m = ((UINT64_C(1) << (32 + p)) + d - 1) / d; + + uint16_t ret = 0; + for (int i = bn->width - 1; i >= 0; i--) { +#if BN_BITS2 == 32 + ret = shift_and_add_mod_u16(ret, bn->d[i], d, p, m); +#elif BN_BITS2 == 64 + ret = shift_and_add_mod_u16(ret, bn->d[i] >> 32, d, p, m); + ret = shift_and_add_mod_u16(ret, bn->d[i] & 0xffffffff, d, p, m); +#else +#error "Unknown BN_ULONG size" +#endif + } + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c new file mode 100644 index 00000000..032c1423 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c @@ -0,0 +1,1287 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include +#include + +#include "internal.h" +#include "rsaz_exp.h" + + +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + int i, bits, ret = 0; + BIGNUM *v, *rr; + + BN_CTX_start(ctx); + if (r == a || r == p) { + rr = BN_CTX_get(ctx); + } else { + rr = r; + } + + v = BN_CTX_get(ctx); + if (rr == NULL || v == NULL) { + goto err; + } + + if (BN_copy(v, a) == NULL) { + goto err; + } + bits = BN_num_bits(p); + + if (BN_is_odd(p)) { + if (BN_copy(rr, a) == NULL) { + goto err; + } + } else { + if (!BN_one(rr)) { + goto err; + } + } + + for (i = 1; i < bits; i++) { + if (!BN_sqr(v, v, ctx)) { + goto err; + } + if (BN_is_bit_set(p, i)) { + if (!BN_mul(rr, rr, v, ctx)) { + goto err; + } + } + } + + if (r != rr && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +typedef struct bn_recp_ctx_st { + BIGNUM N; // the divisor + BIGNUM Nr; // the reciprocal + int num_bits; + int shift; + int flags; +} BN_RECP_CTX; + +static void BN_RECP_CTX_init(BN_RECP_CTX *recp) { + BN_init(&recp->N); + BN_init(&recp->Nr); + recp->num_bits = 0; + recp->shift = 0; + recp->flags = 0; +} + +static void BN_RECP_CTX_free(BN_RECP_CTX *recp) { + if (recp == NULL) { + return; + } + + BN_free(&recp->N); + BN_free(&recp->Nr); +} + +static int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) { + if (!BN_copy(&(recp->N), d)) { + return 0; + } + BN_zero(&recp->Nr); + recp->num_bits = BN_num_bits(d); + recp->shift = 0; + + return 1; +} + +// len is the expected size of the result We actually calculate with an extra +// word of precision, so we can do faster division if the remainder is not +// required. +// r := 2^len / m +static int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) { + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL) { + goto err; + } + + if (!BN_set_bit(t, len)) { + goto err; + } + + if (!BN_div(r, NULL, t, m, ctx)) { + goto err; + } + + ret = len; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx) { + int i, j, ret = 0; + BIGNUM *a, *b, *d, *r; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (dv != NULL) { + d = dv; + } else { + d = BN_CTX_get(ctx); + } + + if (rem != NULL) { + r = rem; + } else { + r = BN_CTX_get(ctx); + } + + if (a == NULL || b == NULL || d == NULL || r == NULL) { + goto err; + } + + if (BN_ucmp(m, &recp->N) < 0) { + BN_zero(d); + if (!BN_copy(r, m)) { + goto err; + } + BN_CTX_end(ctx); + return 1; + } + + // We want the remainder + // Given input of ABCDEF / ab + // we need multiply ABCDEF by 3 digests of the reciprocal of ab + + // i := max(BN_num_bits(m), 2*BN_num_bits(N)) + i = BN_num_bits(m); + j = recp->num_bits << 1; + if (j > i) { + i = j; + } + + // Nr := round(2^i / N) + if (i != recp->shift) { + recp->shift = + BN_reciprocal(&(recp->Nr), &(recp->N), i, + ctx); // BN_reciprocal returns i, or -1 for an error + } + + if (recp->shift == -1) { + goto err; + } + + // d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - + // BN_num_bits(N)))| + // = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - + // BN_num_bits(N)))| + // <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| + // = |m/N| + if (!BN_rshift(a, m, recp->num_bits)) { + goto err; + } + if (!BN_mul(b, a, &(recp->Nr), ctx)) { + goto err; + } + if (!BN_rshift(d, b, i - recp->num_bits)) { + goto err; + } + d->neg = 0; + + if (!BN_mul(b, &(recp->N), d, ctx)) { + goto err; + } + if (!BN_usub(r, m, b)) { + goto err; + } + r->neg = 0; + + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) { + goto err; + } + if (!BN_add_word(d, 1)) { + goto err; + } + } + + r->neg = BN_is_zero(r) ? 0 : m->neg; + d->neg = m->neg ^ recp->N.neg; + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx) { + int ret = 0; + BIGNUM *a; + const BIGNUM *ca; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + if (a == NULL) { + goto err; + } + + if (y != NULL) { + if (x == y) { + if (!BN_sqr(a, x, ctx)) { + goto err; + } + } else { + if (!BN_mul(a, x, y, ctx)) { + goto err; + } + } + ca = a; + } else { + ca = x; // Just do the mod + } + + ret = BN_div_recp(NULL, r, ca, recp, ctx); + +err: + BN_CTX_end(ctx); + return ret; +} + +// BN_window_bits_for_exponent_size returns sliding window size for mod_exp with +// a |b| bit exponent. +// +// For window size 'w' (w >= 2) and a random 'b' bits exponent, the number of +// multiplications is a constant plus on average +// +// 2^(w-1) + (b-w)/(w+1); +// +// here 2^(w-1) is for precomputing the table (we actually need entries only +// for windows that have the lowest bit set), and (b-w)/(w+1) is an +// approximation for the expected number of w-bit windows, not counting the +// first one. +// +// Thus we should use +// +// w >= 6 if b > 671 +// w = 5 if 671 > b > 239 +// w = 4 if 239 > b > 79 +// w = 3 if 79 > b > 23 +// w <= 2 if 23 > b +// +// (with draws in between). Very small exponents are often selected +// with low Hamming weight, so we use w = 1 for b <= 23. +static int BN_window_bits_for_exponent_size(int b) { + if (b > 671) { + return 6; + } + if (b > 239) { + return 5; + } + if (b > 79) { + return 4; + } + if (b > 23) { + return 3; + } + return 1; +} + +// TABLE_SIZE is the maximum precomputation table size for *variable* sliding +// windows. This must be 2^(max_window - 1), where max_window is the largest +// value returned from |BN_window_bits_for_exponent_size|. +#define TABLE_SIZE 32 + +// TABLE_BITS_SMALL is the smallest value returned from +// |BN_window_bits_for_exponent_size| when |b| is at most |BN_BITS2| * +// |BN_SMALL_MAX_WORDS| words. +#define TABLE_BITS_SMALL 5 + +// TABLE_SIZE_SMALL is the same as |TABLE_SIZE|, but when |b| is at most +// |BN_BITS2| * |BN_SMALL_MAX_WORDS|. +#define TABLE_SIZE_SMALL (1 << (TABLE_BITS_SMALL - 1)) + +static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) { + int i, j, ret = 0, wstart, window; + int start = 1; + BIGNUM *aa; + // Table of variables obtained from 'ctx' + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + // This function is only called on even moduli. + assert(!BN_is_odd(m)); + + int bits = BN_num_bits(p); + if (bits == 0) { + return BN_one(r); + } + + BN_CTX_start(ctx); + aa = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!aa || !val[0]) { + goto err; + } + + BN_RECP_CTX_init(&recp); + if (m->neg) { + // ignore sign of 'm' + if (!BN_copy(aa, m)) { + goto err; + } + aa->neg = 0; + if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) { + goto err; + } + } else { + if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) { + goto err; + } + } + + if (!BN_nnmod(val[0], a, m, ctx)) { + goto err; // 1 + } + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) { + goto err; // 2 + } + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx)) { + goto err; + } + } + } + + start = 1; // This is used to avoid multiplication etc + // when there is only the value '1' in the + // buffer. + wstart = bits - 1; // The top bit of the window + + if (!BN_one(r)) { + goto err; + } + + for (;;) { + int wvalue; // The 'value' of the window + int wend; // The bottom bit of the window + + if (!BN_is_bit_set(p, wstart)) { + if (!start) { + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) { + goto err; + } + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a 'set' bit, we now need to work out + // how bit a window to do. To do this we need to scan + // forward until the last set bit before the end of the + // window + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) { + break; + } + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + // wend is the size of the current window + j = wend + 1; + // add the 'bytes above' + if (!start) { + for (i = 0; i < j; i++) { + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) { + goto err; + } + } + } + + // wvalue will be an odd number < 2^window + if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) { + goto err; + } + + // move the 'window' down further + wstart -= wend + 1; + start = 0; + if (wstart < 0) { + break; + } + } + ret = 1; + +err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + return ret; +} + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) { + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_nnmod(r, a, m, ctx)) { + return 0; + } + a = r; + } + + if (BN_is_odd(m)) { + return BN_mod_exp_mont(r, a, p, m, ctx, NULL); + } + + return mod_exp_recp(r, a, p, m, ctx); +} + +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (a->neg || BN_ucmp(a, m) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + int bits = BN_num_bits(p); + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_abs_is_word(m, 1)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + int ret = 0; + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *new_mont = NULL; + + BN_CTX_start(ctx); + BIGNUM *r = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (r == NULL || val[0] == NULL) { + goto err; + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_consttime(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |a|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = a^(2*i + 1) + // for i = 0 to 2^(window-1), all in Montgomery form. + int window = BN_window_bits_for_exponent_size(bits); + if (!BN_to_montgomery(val[0], a, mont, ctx)) { + goto err; + } + if (window > 1) { + BIGNUM *d = BN_CTX_get(ctx); + if (d == NULL || + !BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) { + goto err; + } + for (int i = 1; i < 1 << (window - 1); i++) { + val[i] = BN_CTX_get(ctx); + if (val[i] == NULL || + !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) { + goto err; + } + } + } + + // |p| is non-zero, so at least one window is non-zero. To save some + // multiplications, defer initializing |r| until then. + int r_is_one = 1; + int wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!BN_is_bit_set(p, wstart)) { + if (!r_is_one && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + int wvalue = 1; + int wsize = 0; + for (int i = 1; i < window && i <= wstart; i++) { + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (int i = 0; i < wsize + 1; i++) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + } + } + + assert(wvalue & 1); + assert(wvalue < (1 << window)); + if (r_is_one) { + if (!BN_copy(r, val[wvalue >> 1])) { + goto err; + } + } else if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) { + goto err; + } + + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + // |p| is non-zero, so |r_is_one| must be cleared at some point. + assert(!r_is_one); + + if (!BN_from_montgomery(rr, r, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_CTX_end(ctx); + return ret; +} + +void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, + const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont) { + if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS) { + abort(); + } + assert(BN_is_odd(&mont->N)); + + // Count the number of bits in |p|. Note this function treats |p| as public. + while (num_p != 0 && p[num_p - 1] == 0) { + num_p--; + } + if (num_p == 0) { + bn_from_montgomery_small(r, num, mont->RR.d, num, mont); + return; + } + unsigned bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; + assert(bits != 0); + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |a|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = a^(2*i + 1) for + // i = 0 to 2^(window-1), all in Montgomery form. + unsigned window = BN_window_bits_for_exponent_size(bits); + if (window > TABLE_BITS_SMALL) { + window = TABLE_BITS_SMALL; // Tolerate excessively large |p|. + } + BN_ULONG val[TABLE_SIZE_SMALL][BN_SMALL_MAX_WORDS]; + OPENSSL_memcpy(val[0], a, num * sizeof(BN_ULONG)); + if (window > 1) { + BN_ULONG d[BN_SMALL_MAX_WORDS]; + bn_mod_mul_montgomery_small(d, val[0], val[0], num, mont); + for (unsigned i = 1; i < 1u << (window - 1); i++) { + bn_mod_mul_montgomery_small(val[i], val[i - 1], d, num, mont); + } + } + + // |p| is non-zero, so at least one window is non-zero. To save some + // multiplications, defer initializing |r| until then. + int r_is_one = 1; + unsigned wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!bn_is_bit_set_words(p, num_p, wstart)) { + if (!r_is_one) { + bn_mod_mul_montgomery_small(r, r, r, num, mont); + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + unsigned wvalue = 1; + unsigned wsize = 0; + for (unsigned i = 1; i < window && i <= wstart; i++) { + if (bn_is_bit_set_words(p, num_p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (unsigned i = 0; i < wsize + 1; i++) { + bn_mod_mul_montgomery_small(r, r, r, num, mont); + } + } + + assert(wvalue & 1); + assert(wvalue < (1u << window)); + if (r_is_one) { + OPENSSL_memcpy(r, val[wvalue >> 1], num * sizeof(BN_ULONG)); + } else { + bn_mod_mul_montgomery_small(r, r, val[wvalue >> 1], num, mont); + } + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + // |p| is non-zero, so |r_is_one| must be cleared at some point. + assert(!r_is_one); + OPENSSL_cleanse(val, sizeof(val)); +} + +void bn_mod_inverse0_prime_mont_small(BN_ULONG *r, const BN_ULONG *a, + size_t num, const BN_MONT_CTX *mont) { + if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS) { + abort(); + } + + // Per Fermat's Little Theorem, a^-1 = a^(p-2) (mod p) for p prime. + BN_ULONG p_minus_two[BN_SMALL_MAX_WORDS]; + const BN_ULONG *p = mont->N.d; + OPENSSL_memcpy(p_minus_two, p, num * sizeof(BN_ULONG)); + if (p_minus_two[0] >= 2) { + p_minus_two[0] -= 2; + } else { + p_minus_two[0] -= 2; + for (size_t i = 1; i < num; i++) { + if (p_minus_two[i]-- != 0) { + break; + } + } + } + + bn_mod_exp_mont_small(r, a, num, p_minus_two, num, mont); +} + +static void copy_to_prebuf(const BIGNUM *b, int top, BN_ULONG *table, int idx, + int window) { + int ret = bn_copy_words(table + idx * top, top, b); + assert(ret); // |b| is guaranteed to fit. + (void)ret; +} + +static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, + int window) { + if (!bn_wexpand(b, top)) { + return 0; + } + + OPENSSL_memset(b->d, 0, sizeof(BN_ULONG) * top); + const int width = 1 << window; + for (int i = 0; i < width; i++, table += top) { + BN_ULONG mask = constant_time_eq_int(i, idx); + for (int j = 0; j < top; j++) { + b->d[j] |= table[j] & mask; + } + } + + b->width = top; + return 1; +} + +#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK \ + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) + +// Window sizes optimized for fixed window size modular exponentiation +// algorithm (BN_mod_exp_mont_consttime). +// +// To achieve the security goals of BN_mode_exp_mont_consttime, the maximum +// size of the window must not exceed +// log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). +// +// Window size thresholds are defined for cache line sizes of 32 and 64, cache +// line sizes where log_2(32)=5 and log_2(64)=6 respectively. A window size of +// 7 should only be used on processors that have a 128 byte or greater cache +// line size. +#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 + +#define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 937 ? 6 : (b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) +#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) + +#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 + +#define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) +#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) + +#endif + +// Given a pointer value, compute the next address that is a cache line +// multiple. +#define MOD_EXP_CTIME_ALIGN(x_) \ + ((unsigned char *)(x_) + \ + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - \ + (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) + +// This variant of |BN_mod_exp_mont| uses fixed windows and fixed memory access +// patterns to protect secret exponents (cf. the hyper-threading timing attacks +// pointed out by Colin Percival, +// http://www.daemonology.net/hyperthreading-considered-harmful/) +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont) { + int i, ret = 0, window, wvalue; + BN_MONT_CTX *new_mont = NULL; + + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + BN_ULONG *powerbuf = NULL; + BIGNUM tmp, am; + + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (a->neg || BN_ucmp(a, m) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + // Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak + // whether the top bits are zero. + int max_bits = p->width * BN_BITS2; + int bits = max_bits; + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_abs_is_word(m, 1)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_consttime(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // Use the width in |mont->N|, rather than the copy in |m|. The assembly + // implementation assumes it can use |top| to size R. + int top = mont->N.width; + +#if defined(OPENSSL_BN_ASM_MONT5) || defined(RSAZ_ENABLED) + // Share one large stack-allocated buffer between the RSAZ and non-RSAZ code + // paths. If we were to use separate static buffers for each then there is + // some chance that both large buffers would be allocated on the stack, + // causing the stack space requirement to be truly huge (~10KB). + alignas(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH) BN_ULONG + storage[MOD_EXP_CTIME_STORAGE_LEN]; +#endif +#if defined(RSAZ_ENABLED) + // If the size of the operands allow it, perform the optimized RSAZ + // exponentiation. For further information see crypto/fipsmodule/bn/rsaz_exp.c + // and accompanying assembly modules. + if (a->width == 16 && p->width == 16 && BN_num_bits(m) == 1024 && + rsaz_avx2_preferred()) { + if (!bn_wexpand(rr, 16)) { + goto err; + } + RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d, mont->n0[0], + storage); + rr->width = 16; + rr->neg = 0; + ret = 1; + goto err; + } +#endif + + // Get the window size to use with size of p. + window = BN_window_bits_for_ctime_exponent_size(bits); +#if defined(OPENSSL_BN_ASM_MONT5) + if (window >= 5) { + window = 5; // ~5% improvement for RSA2048 sign, and even for RSA4096 + // reserve space for mont->N.d[] copy + powerbufLen += top * sizeof(mont->N.d[0]); + } +#endif + + // Allocate a buffer large enough to hold all of the pre-computed + // powers of am, am itself and tmp. + numPowers = 1 << window; + powerbufLen += + sizeof(m->d[0]) * + (top * numPowers + ((2 * top) > numPowers ? (2 * top) : numPowers)); + +#if defined(OPENSSL_BN_ASM_MONT5) + if ((size_t)powerbufLen <= sizeof(storage)) { + powerbuf = storage; + } + // |storage| is more than large enough to handle 1024-bit inputs. + assert(powerbuf != NULL || top * BN_BITS2 > 1024); +#endif + if (powerbuf == NULL) { + powerbufFree = + OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); + if (powerbufFree == NULL) { + goto err; + } + powerbuf = (BN_ULONG *)MOD_EXP_CTIME_ALIGN(powerbufFree); + } + OPENSSL_memset(powerbuf, 0, powerbufLen); + + // lay down tmp and am right after powers table + tmp.d = powerbuf + top * numPowers; + am.d = tmp.d + top; + tmp.width = am.width = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + if (!bn_one_to_montgomery(&tmp, mont, ctx)) { + goto err; + } + + // prepare a^1 in Montgomery domain + assert(!a->neg); + assert(BN_ucmp(a, m) < 0); + if (!BN_to_montgomery(&am, a, mont, ctx)) { + goto err; + } + +#if defined(OPENSSL_BN_ASM_MONT5) + // This optimization uses ideas from http://eprint.iacr.org/2011/239, + // specifically optimization of cache-timing attack countermeasures + // and pre-computation optimization. + + // Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as + // 512-bit RSA is hardly relevant, we omit it to spare size... + if (window == 5 && top > 1) { + const BN_ULONG *n0 = mont->n0; + BN_ULONG *np; + + // BN_to_montgomery can contaminate words above .top + // [in BN_DEBUG[_DEBUG] build]... + for (i = am.width; i < top; i++) { + am.d[i] = 0; + } + for (i = tmp.width; i < top; i++) { + tmp.d[i] = 0; + } + + // copy mont->N.d[] to improve cache locality + for (np = am.d + top, i = 0; i < top; i++) { + np[i] = mont->N.d[i]; + } + + bn_scatter5(tmp.d, top, powerbuf, 0); + bn_scatter5(am.d, am.width, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + + // same as above, but uses squaring for 1/2 of operations + for (i = 4; i < 32; i *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, i); + } + for (i = 3; i < 8; i += 2) { + int j; + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + for (j = 2 * i; j < 32; j *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, j); + } + } + for (; i < 16; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2 * i); + } + for (; i < 32; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } + + bits--; + for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) { + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + bn_gather5(tmp.d, top, powerbuf, wvalue); + + // At this point |bits| is 4 mod 5 and at least -1. (|bits| is the first bit + // that has not been read yet.) + assert(bits >= -1 && (bits == -1 || bits % 5 == 4)); + + // Scan the exponent one window at a time starting from the most + // significant bits. + if (top & 7) { + while (bits >= 0) { + for (wvalue = 0, i = 0; i < 5; i++, bits--) { + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + } else { + const uint8_t *p_bytes = (const uint8_t *)p->d; + assert(bits < max_bits); + // |p = 0| has been handled as a special case, so |max_bits| is at least + // one word. + assert(max_bits >= 64); + + // If the first bit to be read lands in the last byte, unroll the first + // iteration to avoid reading past the bounds of |p->d|. (After the first + // iteration, we are guaranteed to be past the last byte.) Note |bits| + // here is the top bit, inclusive. + if (bits - 4 >= max_bits - 8) { + // Read five bits from |bits-4| through |bits|, inclusive. + wvalue = p_bytes[p->width * BN_BYTES - 1]; + wvalue >>= (bits - 4) & 7; + wvalue &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + while (bits >= 0) { + // Read five bits from |bits-4| through |bits|, inclusive. + int first_bit = bits - 4; + uint16_t val; + OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val)); + val >>= first_bit & 7; + val &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val); + } + } + + ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); + tmp.width = top; + if (ret) { + if (!BN_copy(rr, &tmp)) { + ret = 0; + } + goto err; // non-zero ret means it's not error + } + } else +#endif + { + copy_to_prebuf(&tmp, top, powerbuf, 0, window); + copy_to_prebuf(&am, top, powerbuf, 1, window); + + // If the window size is greater than 1, then calculate + // val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) + // (even powers could instead be computed as (a^(i/2))^2 + // to use the slight performance advantage of sqr over mul). + if (window > 1) { + if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, 2, window); + + for (i = 3; i < numPowers; i++) { + // Calculate a^i = a^(i-1) * a + if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, i, window); + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) { + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, window)) { + goto err; + } + + // Scan the exponent one window at a time starting from the most + // significant bits. + while (bits >= 0) { + wvalue = 0; // The 'value' of the window + + // Scan the window, squaring the result as we go + for (i = 0; i < window; i++, bits--) { + if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) { + goto err; + } + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + + // Fetch the appropriate pre-computed value from the pre-buf + if (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) { + goto err; + } + + // Multiply the result into the intermediate result + if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) { + goto err; + } + } + } + + // Convert the final result from montgomery to standard format + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + if (powerbuf != NULL && powerbufFree == NULL) { + OPENSSL_cleanse(powerbuf, powerbufLen); + } + OPENSSL_free(powerbufFree); + return (ret); +} + +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont) { + BIGNUM a_bignum; + BN_init(&a_bignum); + + int ret = 0; + + // BN_mod_exp_mont requires reduced inputs. + if (bn_minimal_width(m) == 1) { + a %= m->d[0]; + } + + if (!BN_set_word(&a_bignum, a)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont); + +err: + BN_free(&a_bignum); + + return ret; +} + +#define TABLE_SIZE 32 + +int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, const BN_MONT_CTX *mont) { + BIGNUM tmp; + BN_init(&tmp); + + int ret = 0; + BN_MONT_CTX *new_mont = NULL; + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // BN_mod_mul_montgomery removes one Montgomery factor, so passing one + // Montgomery-encoded and one non-Montgomery-encoded value gives a + // non-Montgomery-encoded result. + if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || + !BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) || + !BN_to_montgomery(rr, rr, mont, ctx) || + !BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_free(&tmp); + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c new file mode 100644 index 00000000..8bc397c4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c @@ -0,0 +1,378 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include "internal.h" + + +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (!BN_is_odd(n)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + + if (BN_is_negative(a) || BN_cmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + BIGNUM *A, *B, *X, *Y; + int ret = 0; + int sign; + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + if (Y == NULL) { + goto err; + } + + BIGNUM *R = out; + + BN_zero(Y); + if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) { + goto err; + } + A->neg = 0; + sign = -1; + // From B = a mod |n|, A = |n| it follows that + // + // 0 <= B < A, + // -sign*X*a == B (mod |n|), + // sign*Y*a == A (mod |n|). + + // Binary inversion algorithm; requires odd modulus. This is faster than the + // general algorithm if the modulus is sufficiently small (about 400 .. 500 + // bits on 32-bit systems, but much more on 64-bit systems) + int shift; + + while (!BN_is_zero(B)) { + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) -sign*X*a == B (mod |n|), + // (2) sign*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the integers, + // and divide X by the same value mod |n|. + // When we're done, (1) still holds. + shift = 0; + while (!BN_is_bit_set(B, shift)) { + // note that 0 < B + shift++; + + if (BN_is_odd(X)) { + if (!BN_uadd(X, X, n)) { + goto err; + } + } + // now X is even, so we can easily divide it by two + if (!BN_rshift1(X, X)) { + goto err; + } + } + if (shift > 0) { + if (!BN_rshift(B, B, shift)) { + goto err; + } + } + + // Same for A and Y. Afterwards, (2) still holds. + shift = 0; + while (!BN_is_bit_set(A, shift)) { + // note that 0 < A + shift++; + + if (BN_is_odd(Y)) { + if (!BN_uadd(Y, Y, n)) { + goto err; + } + } + // now Y is even + if (!BN_rshift1(Y, Y)) { + goto err; + } + } + if (shift > 0) { + if (!BN_rshift(A, A, shift)) { + goto err; + } + } + + // We still have (1) and (2). + // Both A and B are odd. + // The following computations ensure that + // + // 0 <= B < |n|, + // 0 < A < |n|, + // (1) -sign*X*a == B (mod |n|), + // (2) sign*Y*a == A (mod |n|), + // + // and that either A or B is even in the next iteration. + if (BN_ucmp(B, A) >= 0) { + // -sign*(X + Y)*a == B - A (mod |n|) + if (!BN_uadd(X, X, Y)) { + goto err; + } + // NB: we could use BN_mod_add_quick(X, X, Y, n), but that + // actually makes the algorithm slower + if (!BN_usub(B, B, A)) { + goto err; + } + } else { + // sign*(X + Y)*a == A - B (mod |n|) + if (!BN_uadd(Y, Y, X)) { + goto err; + } + // as above, BN_mod_add_quick(Y, Y, X, n) would slow things down + if (!BN_usub(A, A, B)) { + goto err; + } + } + } + + if (!BN_is_one(A)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + // The while loop (Euclid's algorithm) ends when + // A == gcd(a,n); + // we have + // sign*Y*a == A (mod |n|), + // where Y is non-negative. + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) { + goto err; + } + } + // Now Y*a == A (mod |n|). + + // Y*a == 1 (mod |n|) + if (!Y->neg && BN_ucmp(Y, n) < 0) { + if (!BN_copy(R, Y)) { + goto err; + } + } else { + if (!BN_nnmod(R, Y, n, ctx)) { + goto err; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) { + BIGNUM *new_out = NULL; + if (out == NULL) { + new_out = BN_new(); + if (new_out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out = new_out; + } + + int ok = 0; + BIGNUM *a_reduced = NULL; + if (a->neg || BN_ucmp(a, n) >= 0) { + a_reduced = BN_dup(a); + if (a_reduced == NULL) { + goto err; + } + if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) { + goto err; + } + a = a_reduced; + } + + int no_inverse; + if (!BN_is_odd(n)) { + if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) { + goto err; + } + } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) { + goto err; + } + + ok = 1; + +err: + if (!ok) { + BN_free(new_out); + out = NULL; + } + BN_free(a_reduced); + return out; +} + +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (BN_is_negative(a) || BN_cmp(a, &mont->N) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + int ret = 0; + BIGNUM blinding_factor; + BN_init(&blinding_factor); + + if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N) || + !BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx) || + !BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) || + !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + ret = 1; + +err: + BN_free(&blinding_factor); + return ret; +} + +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} + +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd_extra.c new file mode 100644 index 00000000..11d56dd3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd_extra.c @@ -0,0 +1,326 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include + +#include "internal.h" + + +static BN_ULONG word_is_odd_mask(BN_ULONG a) { return (BN_ULONG)0 - (a & 1); } + +static void maybe_rshift1_words(BN_ULONG *a, BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + bn_rshift1_words(tmp, a, num); + bn_select_words(a, mask, tmp, a, num); +} + +static void maybe_rshift1_words_carry(BN_ULONG *a, BN_ULONG carry, + BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + maybe_rshift1_words(a, mask, tmp, num); + if (num != 0) { + carry &= mask; + a[num - 1] |= carry << (BN_BITS2-1); + } +} + +static BN_ULONG maybe_add_words(BN_ULONG *a, BN_ULONG mask, const BN_ULONG *b, + BN_ULONG *tmp, size_t num) { + BN_ULONG carry = bn_add_words(tmp, a, b, num); + bn_select_words(a, mask, tmp, a, num); + return carry & mask; +} + +static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + size_t width = x->width > y->width ? x->width : y->width; + if (width == 0) { + *out_shift = 0; + BN_zero(r); + return 1; + } + + // This is a constant-time implementation of Stein's algorithm (binary GCD). + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (u == NULL || v == NULL || tmp == NULL || + !BN_copy(u, x) || + !BN_copy(v, y) || + !bn_resize_words(u, width) || + !bn_resize_words(v, width) || + !bn_resize_words(tmp, width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned x_bits = x->width * BN_BITS2, y_bits = y->width * BN_BITS2; + unsigned num_iters = x_bits + y_bits; + if (num_iters < x_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + unsigned shift = 0; + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG u_less_than_v = + (BN_ULONG)0 - bn_sub_words(tmp->d, u->d, v->d, width); + bn_select_words(u->d, both_odd & ~u_less_than_v, tmp->d, u->d, width); + bn_sub_words(tmp->d, v->d, u->d, width); + bn_select_words(v->d, both_odd & u_less_than_v, tmp->d, v->d, width); + + // At least one of |u| and |v| is now even. + BN_ULONG u_is_odd = word_is_odd_mask(u->d[0]); + BN_ULONG v_is_odd = word_is_odd_mask(v->d[0]); + assert(!(u_is_odd & v_is_odd)); + + // If both are even, the final GCD gains a factor of two. + shift += 1 & (~u_is_odd & ~v_is_odd); + + // Halve any which are even. + maybe_rshift1_words(u->d, ~u_is_odd, tmp->d, width); + maybe_rshift1_words(v->d, ~v_is_odd, tmp->d, width); + } + + // One of |u| or |v| is zero at this point. The algorithm usually makes |u| + // zero, unless |y| was already zero on input. Fix this by combining the + // values. + assert(BN_is_zero(u) || BN_is_zero(v)); + for (size_t i = 0; i < width; i++) { + v->d[i] |= u->d[i]; + } + + *out_shift = shift; + ret = bn_set_words(r, v->d, width); + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { + unsigned shift; + return bn_gcd_consttime(r, &shift, x, y, ctx) && + BN_lshift(r, r, shift); +} + +int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + if (gcd == NULL || + !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { + goto err; + } + + // Check that 2^|shift| * |gcd| is one. + if (gcd->width == 0) { + *out_relatively_prime = 0; + } else { + BN_ULONG mask = shift | (gcd->d[0] ^ 1); + for (int i = 1; i < gcd->width; i++) { + mask |= gcd->d[i]; + } + *out_relatively_prime = mask == 0; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + int ret = gcd != NULL && // + bn_mul_consttime(r, a, b, ctx) && + bn_gcd_consttime(gcd, &shift, a, b, ctx) && + // |gcd| has a secret bit width. + bn_div_consttime(r, NULL, r, gcd, /*divisor_min_bits=*/0, ctx) && + bn_rshift_secret_shift(r, r, shift, ctx); + BN_CTX_end(ctx); + return ret; +} + +int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + if (BN_is_negative(a) || BN_ucmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + if (BN_is_zero(a)) { + if (BN_is_one(n)) { + BN_zero(r); + return 1; + } + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This is a constant-time implementation of the extended binary GCD + // algorithm. It is adapted from the Handbook of Applied Cryptography, section + // 14.4.3, algorithm 14.51, and modified to bound coefficients and avoid + // negative numbers. + // + // For more details and proof of correctness, see + // https://github.com/mit-plv/fiat-crypto/pull/333. In particular, see |step| + // and |mod_inverse_consttime| for the algorithm in Gallina and see + // |mod_inverse_consttime_spec| for the correctness result. + + if (!BN_is_odd(a) && !BN_is_odd(n)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This function exists to compute the RSA private exponent, where |a| is one + // word. We'll thus use |a_width| when available. + size_t n_width = n->width, a_width = a->width; + if (a_width > n_width) { + a_width = n_width; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + BIGNUM *C = BN_CTX_get(ctx); + BIGNUM *D = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + if (u == NULL || v == NULL || A == NULL || B == NULL || C == NULL || + D == NULL || tmp == NULL || tmp2 == NULL || + !BN_copy(u, a) || + !BN_copy(v, n) || + !BN_one(A) || + !BN_one(D) || + // For convenience, size |u| and |v| equivalently. + !bn_resize_words(u, n_width) || + !bn_resize_words(v, n_width) || + // |A| and |C| are bounded by |m|. + !bn_resize_words(A, n_width) || + !bn_resize_words(C, n_width) || + // |B| and |D| are bounded by |a|. + !bn_resize_words(B, a_width) || + !bn_resize_words(D, a_width) || + // |tmp| and |tmp2| may be used at either size. + !bn_resize_words(tmp, n_width) || + !bn_resize_words(tmp2, n_width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2; + unsigned num_iters = a_bits + n_bits; + if (num_iters < a_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + // Before and after each loop iteration, the following hold: + // + // u = A*a - B*n + // v = D*n - C*a + // 0 < u <= a + // 0 <= v <= n + // 0 <= A < n + // 0 <= B <= a + // 0 <= C < n + // 0 <= D <= a + // + // After each loop iteration, u and v only get smaller, and at least one of + // them shrinks by at least a factor of two. + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG v_less_than_u = + (BN_ULONG)0 - bn_sub_words(tmp->d, v->d, u->d, n_width); + bn_select_words(v->d, both_odd & ~v_less_than_u, tmp->d, v->d, n_width); + bn_sub_words(tmp->d, u->d, v->d, n_width); + bn_select_words(u->d, both_odd & v_less_than_u, tmp->d, u->d, n_width); + + // If we updated one of the values, update the corresponding coefficient. + BN_ULONG carry = bn_add_words(tmp->d, A->d, C->d, n_width); + carry -= bn_sub_words(tmp2->d, tmp->d, n->d, n_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, n_width); + bn_select_words(A->d, both_odd & v_less_than_u, tmp->d, A->d, n_width); + bn_select_words(C->d, both_odd & ~v_less_than_u, tmp->d, C->d, n_width); + + bn_add_words(tmp->d, B->d, D->d, a_width); + bn_sub_words(tmp2->d, tmp->d, a->d, a_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, a_width); + bn_select_words(B->d, both_odd & v_less_than_u, tmp->d, B->d, a_width); + bn_select_words(D->d, both_odd & ~v_less_than_u, tmp->d, D->d, a_width); + + // Our loop invariants hold at this point. Additionally, exactly one of |u| + // and |v| is now even. + BN_ULONG u_is_even = ~word_is_odd_mask(u->d[0]); + BN_ULONG v_is_even = ~word_is_odd_mask(v->d[0]); + assert(u_is_even != v_is_even); + + // Halve the even one and adjust the corresponding coefficient. + maybe_rshift1_words(u->d, u_is_even, tmp->d, n_width); + BN_ULONG A_or_B_is_odd = + word_is_odd_mask(A->d[0]) | word_is_odd_mask(B->d[0]); + BN_ULONG A_carry = + maybe_add_words(A->d, A_or_B_is_odd & u_is_even, n->d, tmp->d, n_width); + BN_ULONG B_carry = + maybe_add_words(B->d, A_or_B_is_odd & u_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(A->d, A_carry, u_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(B->d, B_carry, u_is_even, tmp->d, a_width); + + maybe_rshift1_words(v->d, v_is_even, tmp->d, n_width); + BN_ULONG C_or_D_is_odd = + word_is_odd_mask(C->d[0]) | word_is_odd_mask(D->d[0]); + BN_ULONG C_carry = + maybe_add_words(C->d, C_or_D_is_odd & v_is_even, n->d, tmp->d, n_width); + BN_ULONG D_carry = + maybe_add_words(D->d, C_or_D_is_odd & v_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(C->d, C_carry, v_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(D->d, D_carry, v_is_even, tmp->d, a_width); + } + + assert(BN_is_zero(v)); + if (!BN_is_one(u)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + ret = BN_copy(r, A) != NULL; + +err: + BN_CTX_end(ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c new file mode 100644 index 00000000..5b186f53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c @@ -0,0 +1,711 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include "internal.h" + + +// This file has two other implementations: x86 assembly language in +// asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. +#if defined(OPENSSL_NO_ASM) || \ + !(defined(OPENSSL_X86) || \ + (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__)))) + +#ifdef BN_ULLONG +#define mul_add(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (r) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(a) * (a); \ + (r0) = Lw(t); \ + (r1) = Hw(t); \ + } while (0) + +#else + +#define mul_add(r, a, w, c) \ + do { \ + BN_ULONG high, low, ret, tmp = (a); \ + ret = (r); \ + BN_UMULT_LOHI(low, high, w, tmp); \ + ret += (c); \ + (c) = (ret < (c)) ? 1 : 0; \ + (c) += high; \ + ret += low; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULONG high, low, ret, ta = (a); \ + BN_UMULT_LOHI(low, high, w, ta); \ + ret = low + (c); \ + (c) = high; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULONG tmp = (a); \ + BN_UMULT_LOHI(r0, r1, tmp, tmp); \ + } while (0) + +#endif // !BN_ULLONG + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + + while (num) { + mul_add(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + + return c1; +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + while (num) { + mul(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + return c1; +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { + if (n == 0) { + return; + } + + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#ifdef BN_ULLONG +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULLONG ll = 0; + + if (n == 0) { + return 0; + } + + while (n & ~3) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[1] + b[1]; + r[1] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[2] + b[2]; + r[2] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[3] + b[3]; + r[3] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)ll; +} + +#else // !BN_ULLONG + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG c, l, t; + + if (n == 0) { + return (BN_ULONG)0; + } + + c = 0; + while (n & ~3) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + t = a[1]; + t += c; + c = (t < c); + l = t + b[1]; + c += (l < t); + r[1] = l; + t = a[2]; + t += c; + c = (t < c); + l = t + b[2]; + c += (l < t); + r[2] = l; + t = a[3]; + t += c; + c = (t < c); + l = t + b[3]; + c += (l < t); + r[3] = l; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)c; +} + +#endif // !BN_ULLONG + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG t1, t2; + int c = 0; + + if (n == 0) { + return (BN_ULONG)0; + } + + while (n & ~3) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[1]; + t2 = b[1]; + r[1] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[2]; + t2 = b[2]; + r[2] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[3]; + t2 = b[3]; + r[3] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a++; + b++; + r++; + n--; + } + return c; +} + +// mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) +// mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) +// sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) +// sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) + +#ifdef BN_ULLONG + +// Keep in mind that additions to multiplication result can not overflow, +// because its high half cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a) * (b); \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += (hi); \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a) * (b); \ + BN_ULLONG tt = t + (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(tt); \ + hi = (BN_ULONG)Hw(tt); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#else + +// Keep in mind that additions to hi can not overflow, because the high word of +// a multiplication result cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + hi += ((c0) < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi, tt; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + tt = hi + (((c0) < lo) ? 1 : 0); \ + (c1) += tt; \ + (c2) += ((c1) < tt) ? 1 : 0; \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a)[i]; \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, ta); \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#endif // !BN_ULLONG + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef mul_add_c2 +#undef sqr_add_c +#undef sqr_add_c2 + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h new file mode 100644 index 00000000..bc04022f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h @@ -0,0 +1,715 @@ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#ifndef OPENSSL_HEADER_BN_INTERNAL_H +#define OPENSSL_HEADER_BN_INTERNAL_H + +#include + +#if defined(OPENSSL_X86_64) && defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(__umulh, _umul128) +#endif + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_64_BIT) + +#if defined(BORINGSSL_HAS_UINT128) +// MSVC doesn't support two-word integers on 64-bit. +#define BN_ULLONG uint128_t +#if defined(BORINGSSL_CAN_DIVIDE_UINT128) +#define BN_CAN_DIVIDE_ULLONG +#endif +#endif + +#define BN_BITS2 64 +#define BN_BYTES 8 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffUL) +#define BN_MASK2l (0xffffffffUL) +#define BN_MASK2h (0xffffffff00000000UL) +#define BN_MASK2h1 (0xffffffff80000000UL) +#define BN_MONT_CTX_N0_LIMBS 1 +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_NUM 19 +#define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo)) + +#elif defined(OPENSSL_32_BIT) + +#define BN_ULLONG uint64_t +#define BN_CAN_DIVIDE_ULLONG +#define BN_BITS2 32 +#define BN_BYTES 4 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffUL) +#define BN_MASK2l (0xffffUL) +#define BN_MASK2h1 (0xffff8000UL) +#define BN_MASK2h (0xffff0000UL) +// On some 32-bit platforms, Montgomery multiplication is done using 64-bit +// arithmetic with SIMD instructions. On such platforms, |BN_MONT_CTX::n0| +// needs to be two words long. Only certain 32-bit platforms actually make use +// of n0[1] and shorter R value would suffice for the others. However, +// currently only the assembly files know which is which. +#define BN_MONT_CTX_N0_LIMBS 2 +#define BN_DEC_CONV (1000000000UL) +#define BN_DEC_NUM 9 +#define TOBN(hi, lo) (lo), (hi) + +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#define BN_CAN_USE_INLINE_ASM +#endif + +// |BN_mod_exp_mont_consttime| is based on the assumption that the L1 data +// cache line width of the target processor is at least the following value. +#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH 64 + +// The number of |BN_ULONG|s needed for the |BN_mod_exp_mont_consttime| stack- +// allocated storage buffer. The buffer is just the right size for the RSAZ +// and is about ~1KB larger than what's necessary (4480 bytes) for 1024-bit +// inputs. +#define MOD_EXP_CTIME_STORAGE_LEN \ + (((320u * 3u) + (32u * 9u * 16u)) / sizeof(BN_ULONG)) + +#define STATIC_BIGNUM(x) \ + { \ + (BN_ULONG *)(x), sizeof(x) / sizeof(BN_ULONG), \ + sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ + } + +#if defined(BN_ULLONG) +#define Lw(t) ((BN_ULONG)(t)) +#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) +#endif + +// bn_minimal_width returns the minimal value of |bn->top| which fits the +// value of |bn|. +int bn_minimal_width(const BIGNUM *bn); + +// bn_set_minimal_width sets |bn->width| to |bn_minimal_width(bn)|. If |bn| is +// zero, |bn->neg| is set to zero. +void bn_set_minimal_width(BIGNUM *bn); + +// bn_wexpand ensures that |bn| has at least |words| works of space without +// altering its value. It returns one on success or zero on allocation +// failure. +int bn_wexpand(BIGNUM *bn, size_t words); + +// bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather +// than a number of words. +int bn_expand(BIGNUM *bn, size_t bits); + +// bn_resize_words adjusts |bn->top| to be |words|. It returns one on success +// and zero on allocation error or if |bn|'s value is too large. +OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words); + +// bn_select_words sets |r| to |a| if |mask| is all ones or |b| if |mask| is +// all zeros. +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num); + +// bn_set_words sets |bn| to the value encoded in the |num| words in |words|, +// least significant word first. +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num); + +// bn_set_static_words acts like |bn_set_words|, but doesn't copy the data. A +// flag is set on |bn| so that |BN_free| won't attempt to free the data. +// +// The |STATIC_BIGNUM| macro is probably a better solution for this outside of +// the FIPS module. Inside of the FIPS module that macro generates rel.ro data, +// which doesn't work with FIPS requirements. +void bn_set_static_words(BIGNUM *bn, const BN_ULONG *words, size_t num); + +// bn_fits_in_words returns one if |bn| may be represented in |num| words, plus +// a sign bit, and zero otherwise. +int bn_fits_in_words(const BIGNUM *bn, size_t num); + +// bn_copy_words copies the value of |bn| to |out| and returns one if the value +// is representable in |num| words. Otherwise, it returns zero. +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn); + +// bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places +// the result in |rp|. |ap| and |rp| must both be |num| words long. It returns +// the carry word of the operation. |ap| and |rp| may be equal but otherwise may +// not alias. +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w); + +// bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and +// |rp| must both be |num| words long. It returns the carry word of the +// operation. |ap| and |rp| may be equal but otherwise may not alias. +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, BN_ULONG w); + +// bn_sqr_words sets |rp[2*i]| and |rp[2*i+1]| to |ap[i]|'s square, for all |i| +// up to |num|. |ap| is an array of |num| words and |rp| an array of |2*num| +// words. |ap| and |rp| may not alias. +// +// This gives the contribution of the |ap[i]*ap[i]| terms when squaring |ap|. +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num); + +// bn_add_words adds |ap| to |bp| and places the result in |rp|, each of which +// are |num| words long. It returns the carry bit, which is one if the operation +// overflowed and zero otherwise. Any pair of |ap|, |bp|, and |rp| may be equal +// to each other but otherwise may not alias. +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_sub_words subtracts |bp| from |ap| and places the result in |rp|. It +// returns the borrow bit, which is one if the computation underflowed and zero +// otherwise. Any pair of |ap|, |bp|, and |rp| may be equal to each other but +// otherwise may not alias. +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_mul_comba4 sets |r| to the product of |a| and |b|. +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]); + +// bn_mul_comba8 sets |r| to the product of |a| and |b|. +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]); + +// bn_sqr_comba8 sets |r| to |a|^2. +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]); + +// bn_sqr_comba4 sets |r| to |a|^2. +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]); + +// bn_less_than_words returns one if |a| < |b| and zero otherwise, where |a| +// and |b| both are |len| words long. It runs in constant time. +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len); + +// bn_in_range_words returns one if |min_inclusive| <= |a| < |max_exclusive|, +// where |a| and |max_exclusive| both are |len| words long. |a| and +// |max_exclusive| are treated as secret. +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len); + +// bn_rand_range_words sets |out| to a uniformly distributed random number from +// |min_inclusive| to |max_exclusive|. Both |out| and |max_exclusive| are |len| +// words long. +// +// This function runs in time independent of the result, but |min_inclusive| and +// |max_exclusive| are public data. (Information about the range is unavoidably +// leaked by how many iterations it took to select a number.) +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]); + +// bn_range_secret_range behaves like |BN_rand_range_ex|, but treats +// |max_exclusive| as secret. Because of this constraint, the distribution of +// values returned is more complex. +// +// Rather than repeatedly generating values until one is in range, which would +// leak information, it generates one value. If the value is in range, it sets +// |*out_is_uniform| to one. Otherwise, it sets |*out_is_uniform| to zero, +// fixing up the value to force it in range. +// +// The subset of calls to |bn_rand_secret_range| which set |*out_is_uniform| to +// one are uniformly distributed in the target range. Calls overall are not. +// This function is intended for use in situations where the extra values are +// still usable and where the number of iterations needed to reach the target +// number of uniform outputs may be blinded for negligible probabilities of +// timing leaks. +// +// Although this function treats |max_exclusive| as secret, it treats the number +// of bits in |max_exclusive| as public. +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define OPENSSL_BN_ASM_MONT +// bn_mul_mont writes |ap| * |bp| mod |np| to |rp|, each |num| words +// long. Inputs and outputs are in Montgomery form. |n0| is a pointer to the +// corresponding field in |BN_MONT_CTX|. It returns one if |bn_mul_mont| handles +// inputs of this size and zero otherwise. +// +// TODO(davidben): The x86_64 implementation expects a 32-bit input and masks +// off upper bits. The aarch64 implementation expects a 64-bit input and does +// not. |size_t| is the safer option but not strictly correct for x86_64. But +// this function implicitly already has a bound on the size of |num| because it +// internally creates |num|-sized stack allocation. +// +// See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word +// inputs. +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num); +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) +#define OPENSSL_BN_ASM_MONT5 + +// bn_mul_mont_gather5 multiples loads index |power| of |table|, multiplies it +// by |ap| modulo |np|, and stores the result in |rp|. The values are |num| +// words long and represented in Montgomery form. |n0| is a pointer to the +// corresponding field in |BN_MONT_CTX|. +void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + +// bn_scatter5 stores |inp| to index |power| of |table|. |inp| and each entry of +// |table| are |num| words long. |power| must be less than 32. |table| must be +// 32*|num| words long. +void bn_scatter5(const BN_ULONG *inp, size_t num, BN_ULONG *table, + size_t power); + +// bn_gather5 loads index |power| of |table| and stores it in |out|. |out| and +// each entry of |table| are |num| words long. |power| must be less than 32. +void bn_gather5(BN_ULONG *out, size_t num, BN_ULONG *table, size_t power); + +// bn_power5 squares |ap| five times and multiplies it by the value stored at +// index |power| of |table|, modulo |np|. It stores the result in |rp|. The +// values are |num| words long and represented in Montgomery form. |n0| is a +// pointer to the corresponding field in |BN_MONT_CTX|. |num| must be divisible +// by 8. +void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, + const BN_ULONG *np, const BN_ULONG *n0, int num, int power); + +// bn_from_montgomery converts |ap| from Montgomery form modulo |np| and writes +// the result in |rp|, each of which is |num| words long. It returns one on +// success and zero if it cannot handle inputs of length |num|. |n0| is a +// pointer to the corresponding field in |BN_MONT_CTX|. +int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *not_used, const BN_ULONG *np, + const BN_ULONG *n0, int num); +#endif // !OPENSSL_NO_ASM && OPENSSL_X86_64 + +uint64_t bn_mont_n0(const BIGNUM *n); + +// bn_mod_exp_base_2_consttime calculates r = 2**p (mod n). |p| must be larger +// than log_2(n); i.e. 2**p must be larger than |n|. |n| must be positive and +// odd. |p| and the bit width of |n| are assumed public, but |n| is otherwise +// treated as secret. +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx); + +#if defined(_MSC_VER) +#if defined(OPENSSL_X86_64) +#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high))) +#elif defined(OPENSSL_AARCH64) +#define BN_UMULT_LOHI(low, high, a, b) \ + do { \ + const BN_ULONG _a = (a); \ + const BN_ULONG _b = (b); \ + (low) = _a * _b; \ + (high) = __umulh(_a, _b); \ + } while (0) +#endif +#endif // _MSC_VER + +#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI) +#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform." +#endif + +// bn_jacobi returns the Jacobi symbol of |a| and |b| (which is -1, 0 or 1), or +// -2 on error. +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_is_bit_set_words returns one if bit |bit| is set in |a| and zero +// otherwise. +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit); + +// bn_one_to_montgomery sets |r| to one in Montgomery form. It returns one on +// success and zero on error. This function treats the bit width of the modulus +// as public. +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx); + +// bn_less_than_montgomery_R returns one if |bn| is less than the Montgomery R +// value for |mont| and zero otherwise. +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont); + +// bn_mod_u16_consttime returns |bn| mod |d|, ignoring |bn|'s sign bit. It runs +// in time independent of the value of |bn|, but it treats |d| as public. +OPENSSL_EXPORT uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d); + +// bn_odd_number_is_obviously_composite returns one if |bn| is divisible by one +// of the first several odd primes and zero otherwise. +int bn_odd_number_is_obviously_composite(const BIGNUM *bn); + +// A BN_MILLER_RABIN stores state common to each Miller-Rabin iteration. It is +// initialized within an existing |BN_CTX| scope and may not be used after +// that scope is released with |BN_CTX_end|. Field names match those in FIPS +// 186-4, section C.3.1. +typedef struct { + // w1 is w-1. + BIGNUM *w1; + // m is (w-1)/2^a. + BIGNUM *m; + // one_mont is 1 (mod w) in Montgomery form. + BIGNUM *one_mont; + // w1_mont is w-1 (mod w) in Montgomery form. + BIGNUM *w1_mont; + // w_bits is BN_num_bits(w). + int w_bits; + // a is the largest integer such that 2^a divides w-1. + int a; +} BN_MILLER_RABIN; + +// bn_miller_rabin_init initializes |miller_rabin| for testing if |mont->N| is +// prime. It returns one on success and zero on error. +OPENSSL_EXPORT int bn_miller_rabin_init(BN_MILLER_RABIN *miller_rabin, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// bn_miller_rabin_iteration performs one Miller-Rabin iteration, checking if +// |b| is a composite witness for |mont->N|. |miller_rabin| must have been +// initialized with |bn_miller_rabin_setup|. On success, it returns one and sets +// |*out_is_possibly_prime| to one if |mont->N| may still be prime or zero if +// |b| shows it is composite. On allocation or internal failure, it returns +// zero. +OPENSSL_EXPORT int bn_miller_rabin_iteration( + const BN_MILLER_RABIN *miller_rabin, int *out_is_possibly_prime, + const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx); + +// bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide. +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num); + +// bn_rshift_words sets |r| to |a| >> |shift|, where both arrays are |num| bits +// wide. +void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift, + size_t num); + +// bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent +// of both |a| and |n|. +OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, + unsigned n, BN_CTX *ctx); + +// bn_reduce_once sets |r| to |a| mod |m| where 0 <= |a| < 2*|m|. It returns +// zero if |a| < |m| and a mask of all ones if |a| >= |m|. Each array is |num| +// words long, but |a| has an additional word specified by |carry|. |carry| must +// be zero or one, as implied by the bounds on |a|. +// +// |r|, |a|, and |m| may not alias. Use |bn_reduce_once_in_place| if |r| and |a| +// must alias. +BN_ULONG bn_reduce_once(BN_ULONG *r, const BN_ULONG *a, BN_ULONG carry, + const BN_ULONG *m, size_t num); + +// bn_reduce_once_in_place behaves like |bn_reduce_once| but acts in-place on +// |r|, using |tmp| as scratch space. |r|, |tmp|, and |m| may not alias. +BN_ULONG bn_reduce_once_in_place(BN_ULONG *r, BN_ULONG carry, const BN_ULONG *m, + BN_ULONG *tmp, size_t num); + + +// Constant-time non-modular arithmetic. +// +// The following functions implement non-modular arithmetic in constant-time +// and pessimally set |r->width| to the largest possible word size. +// +// Note this means that, e.g., repeatedly multiplying by one will cause widths +// to increase without bound. The corresponding public API functions minimize +// their outputs to avoid regressing calculator consumers. + +// bn_uadd_consttime behaves like |BN_uadd|, but it pessimally sets +// |r->width| = |a->width| + |b->width| + 1. +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_usub_consttime behaves like |BN_usub|, but it pessimally sets +// |r->width| = |a->width|. +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_abs_sub_consttime sets |r| to the absolute value of |a| - |b|, treating +// both inputs as secret. It returns one on success and zero on error. +OPENSSL_EXPORT int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// bn_mul_consttime behaves like |BN_mul|, but it rejects negative inputs and +// pessimally sets |r->width| to |a->width| + |b->width|, to avoid leaking +// information about |a| and |b|. +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_sqrt_consttime behaves like |BN_sqrt|, but it pessimally sets |r->width| +// to 2*|a->width|, to avoid leaking information about |a| and |b|. +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// bn_div_consttime behaves like |BN_div|, but it rejects negative inputs and +// treats both inputs, including their magnitudes, as secret. It is, as a +// result, much slower than |BN_div| and should only be used for rare operations +// where Montgomery reduction is not available. |divisor_min_bits| is a +// public lower bound for |BN_num_bits(divisor)|. When |divisor|'s bit width is +// public, this can speed up the operation. +// +// Note that |quotient->width| will be set pessimally to |numerator->width|. +OPENSSL_EXPORT int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, + const BIGNUM *divisor, + unsigned divisor_min_bits, BN_CTX *ctx); + +// bn_is_relatively_prime checks whether GCD(|x|, |y|) is one. On success, it +// returns one and sets |*out_relatively_prime| to one if the GCD was one and +// zero otherwise. On error, it returns zero. +OPENSSL_EXPORT int bn_is_relatively_prime(int *out_relatively_prime, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +// bn_lcm_consttime sets |r| to LCM(|a|, |b|). It returns one and success and +// zero on error. |a| and |b| are both treated as secret. +OPENSSL_EXPORT int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + + +// Constant-time modular arithmetic. +// +// The following functions implement basic constant-time modular arithmetic. + +// bn_mod_add_words sets |r| to |a| + |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +void bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num); + +// bn_mod_add_consttime acts like |BN_mod_add_quick| but takes a |BN_CTX|. +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_sub_words sets |r| to |a| - |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +void bn_mod_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num); + +// bn_mod_sub_consttime acts like |BN_mod_sub_quick| but takes a |BN_CTX|. +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_lshift1_consttime acts like |BN_mod_lshift1_quick| but takes a +// |BN_CTX|. +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_lshift_consttime acts like |BN_mod_lshift_quick| but takes a |BN_CTX|. +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_inverse_consttime sets |r| to |a|^-1, mod |n|. |a| must be non- +// negative and less than |n|. It returns one on success and zero on error. On +// failure, if the failure was caused by |a| having no inverse mod |n| then +// |*out_no_inverse| will be set to one; otherwise it will be set to zero. +// +// This function treats both |a| and |n| as secret, provided they are both non- +// zero and the inverse exists. It should only be used for even moduli where +// none of the less general implementations are applicable. +OPENSSL_EXPORT int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); + +// bn_mod_inverse_prime sets |out| to the modular inverse of |a| modulo |p|, +// computed with Fermat's Little Theorem. It returns one on success and zero on +// error. If |mont_p| is NULL, one will be computed temporarily. +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + +// bn_mod_inverse_secret_prime behaves like |bn_mod_inverse_prime| but uses +// |BN_mod_exp_mont_consttime| instead of |BN_mod_exp_mont| in hopes of +// protecting the exponent. +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + + +// Low-level operations for small numbers. +// +// The following functions implement algorithms suitable for use with scalars +// and field elements in elliptic curves. They rely on the number being small +// both to stack-allocate various temporaries and because they do not implement +// optimizations useful for the larger values used in RSA. + +// BN_SMALL_MAX_WORDS is the largest size input these functions handle. This +// limit allows temporaries to be more easily stack-allocated. This limit is set +// to accommodate P-521. +#if defined(OPENSSL_32_BIT) +#define BN_SMALL_MAX_WORDS 17 +#else +#define BN_SMALL_MAX_WORDS 9 +#endif + +// bn_mul_small sets |r| to |a|*|b|. |num_r| must be |num_a| + |num_b|. |r| may +// not alias with |a| or |b|. +void bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b); + +// bn_sqr_small sets |r| to |a|^2. |num_a| must be at most |BN_SMALL_MAX_WORDS|. +// |num_r| must be |num_a|*2. |r| and |a| may not alias. +void bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a); + +// In the following functions, the modulus must be at most |BN_SMALL_MAX_WORDS| +// words long. + +// bn_to_montgomery_small sets |r| to |a| translated to the Montgomery domain. +// |r| and |a| are |num| words long, which must be |mont->N.width|. |a| must be +// fully reduced and may alias |r|. +void bn_to_montgomery_small(BN_ULONG *r, const BN_ULONG *a, size_t num, + const BN_MONT_CTX *mont); + +// bn_from_montgomery_small sets |r| to |a| translated out of the Montgomery +// domain. |r| and |a| are |num_r| and |num_a| words long, respectively. |num_r| +// must be |mont->N.width|. |a| must be at most |mont->N|^2 and may alias |r|. +// +// Unlike most of these functions, only |num_r| is bounded by +// |BN_SMALL_MAX_WORDS|. |num_a| may exceed it, but must be at most 2 * |num_r|. +void bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont); + +// bn_mod_mul_montgomery_small sets |r| to |a| * |b| mod |mont->N|. Both inputs +// and outputs are in the Montgomery domain. Each array is |num| words long, +// which must be |mont->N.width|. Any two of |r|, |a|, and |b| may alias. |a| +// and |b| must be reduced on input. +void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, size_t num, + const BN_MONT_CTX *mont); + +// bn_mod_exp_mont_small sets |r| to |a|^|p| mod |mont->N|. It returns one on +// success and zero on programmer or internal error. Both inputs and outputs are +// in the Montgomery domain. |r| and |a| are |num| words long, which must be +// |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. +// This function runs in time independent of |a|, but |p| and |mont->N| are +// public values. |a| must be fully-reduced and may alias with |r|. +// +// Note this function differs from |BN_mod_exp_mont| which uses Montgomery +// reduction but takes input and output outside the Montgomery domain. Combine +// this function with |bn_from_montgomery_small| and |bn_to_montgomery_small| +// if necessary. +void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, + const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont); + +// bn_mod_inverse0_prime_mont_small sets |r| to |a|^-1 mod |mont->N|. If |a| is +// zero, |r| is set to zero. |mont->N| must be a prime. |r| and |a| are |num| +// words long, which must be |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. +// |a| must be fully-reduced and may alias |r|. This function runs in time +// independent of |a|, but |mont->N| is a public value. +void bn_mod_inverse0_prime_mont_small(BN_ULONG *r, const BN_ULONG *a, + size_t num, const BN_MONT_CTX *mont); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BN_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/jacobi.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/jacobi.c new file mode 100644 index 00000000..397b1de9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/jacobi.c @@ -0,0 +1,146 @@ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include "internal.h" + + +// least significant word +#define BN_lsw(n) (((n)->width == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // In 'tab', only odd-indexed entries are relevant: + // For any odd BIGNUM n, + // tab[BN_lsw(n) & 7] + // is $(-1)^{(n^2-1)/8}$ (using TeX notation). + // Note that the sign of n does not matter. + static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1}; + + // The Jacobi symbol is only defined for odd modulus. + if (!BN_is_odd(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return -2; + } + + // Require b be positive. + if (BN_is_negative(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return -2; + } + + int ret = -2; + BN_CTX_start(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + if (B == NULL) { + goto end; + } + + if (!BN_copy(A, a) || + !BN_copy(B, b)) { + goto end; + } + + // Adapted from logic to compute the Kronecker symbol, originally implemented + // according to Henri Cohen, "A Course in Computational Algebraic Number + // Theory" (algorithm 1.4.10). + + ret = 1; + + while (1) { + // Cohen's step 3: + + // B is positive and odd + if (BN_is_zero(A)) { + ret = BN_is_one(B) ? ret : 0; + goto end; + } + + // now A is non-zero + int i = 0; + while (!BN_is_bit_set(A, i)) { + i++; + } + if (!BN_rshift(A, A, i)) { + ret = -2; + goto end; + } + if (i & 1) { + // i is odd + // multiply 'ret' by $(-1)^{(B^2-1)/8}$ + ret = ret * tab[BN_lsw(B) & 7]; + } + + // Cohen's step 4: + // multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ + if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2) { + ret = -ret; + } + + // (A, B) := (B mod |A|, |A|) + if (!BN_nnmod(B, B, A, ctx)) { + ret = -2; + goto end; + } + BIGNUM *tmp = A; + A = B; + B = tmp; + tmp->neg = 0; + } + +end: + BN_CTX_end(ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c new file mode 100644 index 00000000..f3d00517 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c @@ -0,0 +1,502 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +BN_MONT_CTX *BN_MONT_CTX_new(void) { + BN_MONT_CTX *ret = OPENSSL_malloc(sizeof(BN_MONT_CTX)); + + if (ret == NULL) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BN_MONT_CTX)); + BN_init(&ret->RR); + BN_init(&ret->N); + + return ret; +} + +void BN_MONT_CTX_free(BN_MONT_CTX *mont) { + if (mont == NULL) { + return; + } + + BN_free(&mont->RR); + BN_free(&mont->N); + OPENSSL_free(mont); +} + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { + if (to == from) { + return to; + } + + if (!BN_copy(&to->RR, &from->RR) || + !BN_copy(&to->N, &from->N)) { + return NULL; + } + to->n0[0] = from->n0[0]; + to->n0[1] = from->n0[1]; + return to; +} + +static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { + if (BN_is_zero(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + if (!BN_is_odd(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + if (BN_is_negative(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + // Save the modulus. + if (!BN_copy(&mont->N, mod)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + // |mont->N| is always stored minimally. Computing RR efficiently leaks the + // size of the modulus. While the modulus may be private in RSA (one of the + // primes), their sizes are public, so this is fine. + bn_set_minimal_width(&mont->N); + + // Find n0 such that n0 * N == -1 (mod r). + // + // Only certain BN_BITS2<=32 platforms actually make use of n0[1]. For the + // others, we could use a shorter R value and use faster |BN_ULONG|-based + // math instead of |uint64_t|-based math, which would be double-precision. + // However, currently only the assembler files know which is which. + OPENSSL_STATIC_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + "BN_MONT_CTX_N0_LIMBS value is invalid"); + OPENSSL_STATIC_ASSERT( + sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == sizeof(uint64_t), + "uint64_t is insufficient precision for n0"); + uint64_t n0 = bn_mont_n0(&mont->N); + mont->n0[0] = (BN_ULONG)n0; +#if BN_MONT_CTX_N0_LIMBS == 2 + mont->n0[1] = (BN_ULONG)(n0 >> BN_BITS2); +#else + mont->n0[1] = 0; +#endif + return 1; +} + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { + if (!bn_mont_ctx_set_N_and_n0(mont, mod)) { + return 0; + } + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + return 0; + } + ctx = new_ctx; + } + + // Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS2 such that R + // > mod. Even though the assembly on some 32-bit platforms works with 64-bit + // values, using |BN_BITS2| here, rather than |BN_MONT_CTX_N0_LIMBS * + // BN_BITS2|, is correct because R**2 will still be a multiple of the latter + // as |BN_MONT_CTX_N0_LIMBS| is either one or two. + unsigned lgBigR = mont->N.width * BN_BITS2; + BN_zero(&mont->RR); + int ok = BN_set_bit(&mont->RR, lgBigR * 2) && + BN_mod(&mont->RR, &mont->RR, &mont->N, ctx) && + bn_resize_words(&mont->RR, mont->N.width); + BN_CTX_free(new_ctx); + return ok; +} + +BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, BN_CTX *ctx) { + BN_MONT_CTX *mont = BN_MONT_CTX_new(); + if (mont == NULL || + !BN_MONT_CTX_set(mont, mod, ctx)) { + BN_MONT_CTX_free(mont); + return NULL; + } + return mont; +} + +BN_MONT_CTX *BN_MONT_CTX_new_consttime(const BIGNUM *mod, BN_CTX *ctx) { + BN_MONT_CTX *mont = BN_MONT_CTX_new(); + if (mont == NULL || + !bn_mont_ctx_set_N_and_n0(mont, mod)) { + goto err; + } + unsigned lgBigR = mont->N.width * BN_BITS2; + if (!bn_mod_exp_base_2_consttime(&mont->RR, lgBigR * 2, &mont->N, ctx) || + !bn_resize_words(&mont->RR, mont->N.width)) { + goto err; + } + return mont; + +err: + BN_MONT_CTX_free(mont); + return NULL; +} + +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx) { + CRYPTO_MUTEX_lock_read(lock); + BN_MONT_CTX *ctx = *pmont; + CRYPTO_MUTEX_unlock_read(lock); + + if (ctx) { + return 1; + } + + CRYPTO_MUTEX_lock_write(lock); + if (*pmont == NULL) { + *pmont = BN_MONT_CTX_new_for_modulus(mod, bn_ctx); + } + const int ok = *pmont != NULL; + CRYPTO_MUTEX_unlock_write(lock); + return ok; +} + +int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx); +} + +static int bn_from_montgomery_in_place(BN_ULONG *r, size_t num_r, BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + const BN_ULONG *n = mont->N.d; + size_t num_n = mont->N.width; + if (num_r != num_n || num_a != 2 * num_n) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On + // input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r| + // includes |carry| which is stored separately. + BN_ULONG n0 = mont->n0[0]; + BN_ULONG carry = 0; + for (size_t i = 0; i < num_n; i++) { + BN_ULONG v = bn_mul_add_words(a + i, n, num_n, a[i] * n0); + v += carry + a[i + num_n]; + carry |= (v != a[i + num_n]); + carry &= (v <= a[i + num_n]); + a[i + num_n] = v; + } + + // Shift |num_n| words to divide by R. We have |a| < 2 * |n|. Note that |a| + // includes |carry| which is stored separately. + a += num_n; + + // |a| thus requires at most one additional subtraction |n| to be reduced. + bn_reduce_once(r, a, carry, n, num_n); + return 1; +} + +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, + const BN_MONT_CTX *mont) { + if (r->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + const BIGNUM *n = &mont->N; + if (n->width == 0) { + ret->width = 0; + return 1; + } + + int max = 2 * n->width; // carry is stored separately + if (!bn_resize_words(r, max) || + !bn_wexpand(ret, n->width)) { + return 0; + } + + ret->width = n->width; + ret->neg = 0; + return bn_from_montgomery_in_place(ret->d, ret->width, r->d, r->width, mont); +} + +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL || + !BN_copy(t, a)) { + goto err; + } + + ret = BN_from_montgomery_word(r, t, mont); + +err: + BN_CTX_end(ctx); + + return ret; +} + +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx) { + // If the high bit of |n| is set, R = 2^(width*BN_BITS2) < 2 * |n|, so we + // compute R - |n| rather than perform Montgomery reduction. + const BIGNUM *n = &mont->N; + if (n->width > 0 && (n->d[n->width - 1] >> (BN_BITS2 - 1)) != 0) { + if (!bn_wexpand(r, n->width)) { + return 0; + } + r->d[0] = 0 - n->d[0]; + for (int i = 1; i < n->width; i++) { + r->d[i] = ~n->d[i]; + } + r->width = n->width; + r->neg = 0; + return 1; + } + + return BN_from_montgomery(r, &mont->RR, mont, ctx); +} + +static int bn_mod_mul_montgomery_fallback(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + if (a == b) { + if (!bn_sqr_consttime(tmp, a, ctx)) { + goto err; + } + } else { + if (!bn_mul_consttime(tmp, a, b, ctx)) { + goto err; + } + } + + // reduce from aRR to aR + if (!BN_from_montgomery_word(r, tmp, mont)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + int num = mont->N.width; + if (num >= (128 / BN_BITS2) && + a->width == num && + b->width == num) { + if (!bn_wexpand(r, num)) { + return 0; + } + if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + // The check above ensures this won't happen. + assert(0); + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + r->neg = 0; + r->width = num; + return 1; + } +#endif + + return bn_mod_mul_montgomery_fallback(r, a, b, mont, ctx); +} + +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont) { + return !BN_is_negative(bn) && + bn_fits_in_words(bn, mont->N.width); +} + +void bn_to_montgomery_small(BN_ULONG *r, const BN_ULONG *a, size_t num, + const BN_MONT_CTX *mont) { + bn_mod_mul_montgomery_small(r, a, mont->RR.d, num, mont); +} + +void bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + if (num_r != (size_t)mont->N.width || num_r > BN_SMALL_MAX_WORDS || + num_a > 2 * num_r) { + abort(); + } + BN_ULONG tmp[BN_SMALL_MAX_WORDS * 2] = {0}; + OPENSSL_memcpy(tmp, a, num_a * sizeof(BN_ULONG)); + if (!bn_from_montgomery_in_place(r, num_r, tmp, 2 * num_r, mont)) { + abort(); + } + OPENSSL_cleanse(tmp, 2 * num_r * sizeof(BN_ULONG)); +} + +void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, size_t num, + const BN_MONT_CTX *mont) { + if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS) { + abort(); + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + if (num >= (128 / BN_BITS2)) { + if (!bn_mul_mont(r, a, b, mont->N.d, mont->n0, num)) { + abort(); // The check above ensures this won't happen. + } + return; + } +#endif + + // Compute the product. + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + if (a == b) { + bn_sqr_small(tmp, 2 * num, a, num); + } else { + bn_mul_small(tmp, 2 * num, a, num, b, num); + } + + // Reduce. + if (!bn_from_montgomery_in_place(r, num, tmp, 2 * num, mont)) { + abort(); + } + OPENSSL_cleanse(tmp, 2 * num * sizeof(BN_ULONG)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery_inv.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery_inv.c new file mode 100644 index 00000000..c9e8106d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery_inv.c @@ -0,0 +1,186 @@ +/* Copyright 2016 Brian Smith. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n); + +OPENSSL_STATIC_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + "BN_MONT_CTX_N0_LIMBS value is invalid"); +OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == + sizeof(uint64_t), + "uint64_t is insufficient precision for n0"); + +// LG_LITTLE_R is log_2(r). +#define LG_LITTLE_R (BN_MONT_CTX_N0_LIMBS * BN_BITS2) + +uint64_t bn_mont_n0(const BIGNUM *n) { + // These conditions are checked by the caller, |BN_MONT_CTX_set| or + // |BN_MONT_CTX_new_consttime|. + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + // r == 2**(BN_MONT_CTX_N0_LIMBS * BN_BITS2) and LG_LITTLE_R == lg(r). This + // ensures that we can do integer division by |r| by simply ignoring + // |BN_MONT_CTX_N0_LIMBS| limbs. Similarly, we can calculate values modulo + // |r| by just looking at the lowest |BN_MONT_CTX_N0_LIMBS| limbs. This is + // what makes Montgomery multiplication efficient. + // + // As shown in Algorithm 1 of "Fast Prime Field Elliptic Curve Cryptography + // with 256 Bit Primes" by Shay Gueron and Vlad Krasnov, in the loop of a + // multi-limb Montgomery multiplication of |a * b (mod n)|, given the + // unreduced product |t == a * b|, we repeatedly calculate: + // + // t1 := t % r |t1| is |t|'s lowest limb (see previous paragraph). + // t2 := t1*n0*n + // t3 := t + t2 + // t := t3 / r copy all limbs of |t3| except the lowest to |t|. + // + // In the last step, it would only make sense to ignore the lowest limb of + // |t3| if it were zero. The middle steps ensure that this is the case: + // + // t3 == 0 (mod r) + // t + t2 == 0 (mod r) + // t + t1*n0*n == 0 (mod r) + // t1*n0*n == -t (mod r) + // t*n0*n == -t (mod r) + // n0*n == -1 (mod r) + // n0 == -1/n (mod r) + // + // Thus, in each iteration of the loop, we multiply by the constant factor + // |n0|, the negative inverse of n (mod r). + + // n_mod_r = n % r. As explained above, this is done by taking the lowest + // |BN_MONT_CTX_N0_LIMBS| limbs of |n|. + uint64_t n_mod_r = n->d[0]; +#if BN_MONT_CTX_N0_LIMBS == 2 + if (n->width > 1) { + n_mod_r |= (uint64_t)n->d[1] << BN_BITS2; + } +#endif + + return bn_neg_inv_mod_r_u64(n_mod_r); +} + +// bn_neg_inv_r_mod_n_u64 calculates the -1/n mod r; i.e. it calculates |v| +// such that u*r - v*n == 1. |r| is the constant defined in |bn_mont_n0|. |n| +// must be odd. +// +// This is derived from |xbinGCD| in Henry S. Warren, Jr.'s "Montgomery +// Multiplication" (http://www.hackersdelight.org/MontgomeryMultiplication.pdf). +// It is very similar to the MODULAR-INVERSE function in Stephen R. Dussé's and +// Burton S. Kaliski Jr.'s "A Cryptographic Library for the Motorola DSP56000" +// (http://link.springer.com/chapter/10.1007%2F3-540-46877-3_21). +// +// This is inspired by Joppe W. Bos's "Constant Time Modular Inversion" +// (http://www.joppebos.com/files/CTInversion.pdf) so that the inversion is +// constant-time with respect to |n|. We assume uint64_t additions, +// subtractions, shifts, and bitwise operations are all constant time, which +// may be a large leap of faith on 32-bit targets. We avoid division and +// multiplication, which tend to be the most problematic in terms of timing +// leaks. +// +// Most GCD implementations return values such that |u*r + v*n == 1|, so the +// caller would have to negate the resultant |v| for the purpose of Montgomery +// multiplication. This implementation does the negation implicitly by doing +// the computations as a difference instead of a sum. +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) { + assert(n % 2 == 1); + + // alpha == 2**(lg r - 1) == r / 2. + static const uint64_t alpha = UINT64_C(1) << (LG_LITTLE_R - 1); + + const uint64_t beta = n; + + uint64_t u = 1; + uint64_t v = 0; + + // The invariant maintained from here on is: + // 2**(lg r - i) == u*2*alpha - v*beta. + for (size_t i = 0; i < LG_LITTLE_R; ++i) { +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert((BN_ULLONG)(1) << (LG_LITTLE_R - i) == + ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + // Delete a common factor of 2 in u and v if |u| is even. Otherwise, set + // |u = (u + beta) / 2| and |v = (v / 2) + alpha|. + + uint64_t u_is_odd = UINT64_C(0) - (u & 1); // Either 0xff..ff or 0. + + // The addition can overflow, so use Dietz's method for it. + // + // Dietz calculates (x+y)/2 by (x⊕y)>>1 + x&y. This is valid for all + // (unsigned) x and y, even when x+y overflows. Evidence for 32-bit values + // (embedded in 64 bits to so that overflow can be ignored): + // + // (declare-fun x () (_ BitVec 64)) + // (declare-fun y () (_ BitVec 64)) + // (assert (let ( + // (one (_ bv1 64)) + // (thirtyTwo (_ bv32 64))) + // (and + // (bvult x (bvshl one thirtyTwo)) + // (bvult y (bvshl one thirtyTwo)) + // (not (= + // (bvadd (bvlshr (bvxor x y) one) (bvand x y)) + // (bvlshr (bvadd x y) one))) + // ))) + // (check-sat) + uint64_t beta_if_u_is_odd = beta & u_is_odd; // Either |beta| or 0. + u = ((u ^ beta_if_u_is_odd) >> 1) + (u & beta_if_u_is_odd); + + uint64_t alpha_if_u_is_odd = alpha & u_is_odd; // Either |alpha| or 0. + v = (v >> 1) + alpha_if_u_is_odd; + } + + // The invariant now shows that u*r - v*n == 1 since r == 2 * alpha. +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert(1 == ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + return v; +} + +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx) { + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + BN_zero(r); + + unsigned n_bits = BN_num_bits(n); + assert(n_bits != 0); + assert(p > n_bits); + if (n_bits == 1) { + return 1; + } + + // Set |r| to the larger power of two smaller than |n|, then shift with + // reductions the rest of the way. + if (!BN_set_bit(r, n_bits - 1) || + !bn_mod_lshift_consttime(r, r, p - (n_bits - 1), n, ctx)) { + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/mul.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/mul.c new file mode 100644 index 00000000..7895035c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/mul.c @@ -0,0 +1,749 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_MUL_RECURSIVE_SIZE_NORMAL 16 +#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL + + +static void bn_abs_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t num, BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_words(tmp, a, b, num); + bn_sub_words(r, b, a, num); + bn_select_words(r, 0 - borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); +} + +static void bn_mul_normal(BN_ULONG *r, const BN_ULONG *a, size_t na, + const BN_ULONG *b, size_t nb) { + if (na < nb) { + size_t itmp = na; + na = nb; + nb = itmp; + const BN_ULONG *ltmp = a; + a = b; + b = ltmp; + } + BN_ULONG *rr = &(r[na]); + if (nb == 0) { + OPENSSL_memset(r, 0, na * sizeof(BN_ULONG)); + return; + } + rr[0] = bn_mul_words(r, a, na, b[0]); + + for (;;) { + if (--nb == 0) { + return; + } + rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]); + if (--nb == 0) { + return; + } + rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]); + if (--nb == 0) { + return; + } + rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]); + if (--nb == 0) { + return; + } + rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]); + rr += 4; + r += 4; + b += 4; + } +} + +// bn_sub_part_words sets |r| to |a| - |b|. It returns the borrow bit, which is +// one if the operation underflowed and zero otherwise. |cl| is the common +// length, that is, the shorter of len(a) or len(b). |dl| is the delta length, +// that is, len(a) - len(b). |r|'s length matches the larger of |a| and |b|, or +// cl + abs(dl). +// +// TODO(davidben): Make this take |size_t|. The |cl| + |dl| calling convention +// is confusing. +static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int cl, int dl) { + assert(cl >= 0); + BN_ULONG borrow = bn_sub_words(r, a, b, cl); + if (dl == 0) { + return borrow; + } + + r += cl; + a += cl; + b += cl; + + if (dl < 0) { + // |a| is shorter than |b|. Complete the subtraction as if the excess words + // in |a| were zeros. + dl = -dl; + for (int i = 0; i < dl; i++) { + r[i] = 0u - b[i] - borrow; + borrow |= r[i] != 0; + } + } else { + // |b| is shorter than |a|. Complete the subtraction as if the excess words + // in |b| were zeros. + for (int i = 0; i < dl; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = a[i]; + r[i] = a[i] - borrow; + borrow = tmp < r[i]; + } + } + + return borrow; +} + +// bn_abs_sub_part_words computes |r| = |a| - |b|, storing the absolute value +// and returning a mask of all ones if the result was negative and all zeros if +// the result was positive. |cl| and |dl| follow the |bn_sub_part_words| calling +// convention. +// +// TODO(davidben): Make this take |size_t|. The |cl| + |dl| calling convention +// is confusing. +static BN_ULONG bn_abs_sub_part_words(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int cl, int dl, + BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_part_words(tmp, a, b, cl, dl); + bn_sub_part_words(r, b, a, cl, -dl); + int r_len = cl + (dl < 0 ? -dl : dl); + borrow = 0 - borrow; + bn_select_words(r, borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, r_len); + return borrow; +} + +int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int cl = a->width < b->width ? a->width : b->width; + int dl = a->width - b->width; + int r_len = a->width < b->width ? b->width : a->width; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + bn_wexpand(r, r_len) && + bn_wexpand(tmp, r_len); + if (ok) { + bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); + r->width = r_len; + } + BN_CTX_end(ctx); + return ok; +} + +// Karatsuba recursive multiplication algorithm +// (cf. Knuth, The Art of Computer Programming, Vol. 2) + +// bn_mul_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2| + |dna|, |b| has length |n2| + |dnb|, and +// |t| has length 4*|n2|. |n2| must be a power of two. Finally, we must have +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dna| <= 0 and +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dnb| <= 0. +// +// TODO(davidben): Simplify and |size_t| the calling convention around lengths +// here. +static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n2, int dna, int dnb, BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + // Check |dna| and |dnb| are in range. + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dna && dna <= 0); + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dnb && dnb <= 0); + + // Only call bn_mul_comba 8 if n2 == 8 and the + // two arrays are complete [steve] + if (n2 == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(r, a, b); + return; + } + + // Else do normal multiply + if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(r, a, n2 + dna, b, n2 + dnb); + if (dna + dnb < 0) { + OPENSSL_memset(&r[2 * n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); + } + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + // + // Note that we know |n| >= |BN_MUL_RECURSIVE_SIZE_NORMAL|/2 above, so + // |tna| and |tnb| are non-negative. + int n = n2 / 2, tna = n + dna, tnb = n + dnb; + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + if (n == 4 && dna == 0 && dnb == 0) { + bn_mul_comba4(&t[n2], t, &t[n]); + + bn_mul_comba4(r, a, b); + bn_mul_comba4(&r[n2], &a[n], &b[n]); + } else if (n == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(&t[n2], t, &t[n]); + + bn_mul_comba8(r, a, b); + bn_mul_comba8(&r[n2], &a[n], &b[n]); + } else { + BN_ULONG *p = &t[n2 * 2]; + bn_mul_recursive(&t[n2], t, &t[n], n, 0, 0, p); + bn_mul_recursive(r, a, b, n, 0, 0, p); + bn_mul_recursive(&r[n2], &a[n], &b[n], n, dna, dnb, p); + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_part_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| +// has length 4*|n|, |a| has length |n| + |tna|, |b| has length |n| + |tnb|, and +// |t| has length 8*|n|. |n| must be a power of two. Additionally, we must have +// 0 <= tna < n and 0 <= tnb < n, and |tna| and |tnb| must differ by at most +// one. +// +// TODO(davidben): Make this take |size_t| and perhaps the actual lengths of |a| +// and |b|. +static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int n, int tna, int tnb, + BN_ULONG *t) { + // |n| is a power of two. + assert(n != 0 && (n & (n - 1)) == 0); + // Check |tna| and |tnb| are in range. + assert(0 <= tna && tna < n); + assert(0 <= tnb && tnb < n); + assert(-1 <= tna - tnb && tna - tnb <= 1); + + int n2 = n * 2; + if (n < 8) { + bn_mul_normal(r, a, n + tna, b, n + tnb); + OPENSSL_memset(r + n2 + tna + tnb, 0, n2 - tna - tnb); + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. |a1| + // and |b1| have size |tna| and |tnb|, respectively. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + if (n == 8) { + bn_mul_comba8(&t[n2], t, &t[n]); + bn_mul_comba8(r, a, b); + + bn_mul_normal(&r[n2], &a[n], tna, &b[n], tnb); + // |bn_mul_normal| only writes |tna| + |tna| words. Zero the rest. + OPENSSL_memset(&r[n2 + tna + tnb], 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { + BN_ULONG *p = &t[n2 * 2]; + bn_mul_recursive(&t[n2], t, &t[n], n, 0, 0, p); + bn_mul_recursive(r, a, b, n, 0, 0, p); + + OPENSSL_memset(&r[n2], 0, sizeof(BN_ULONG) * n2); + if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL && + tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(&r[n2], &a[n], tna, &b[n], tnb); + } else { + int i = n; + for (;;) { + i /= 2; + if (i < tna || i < tnb) { + // E.g., n == 16, i == 8 and tna == 11. |tna| and |tnb| are within one + // of each other, so if |tna| is larger and tna > i, then we know + // tnb >= i, and this call is valid. + bn_mul_part_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + if (i == tna || i == tnb) { + // If there is only a bottom half to the number, just do it. We know + // the larger of |tna - i| and |tnb - i| is zero. The other is zero or + // -1 by because of |tna| and |tnb| differ by at most one. + bn_mul_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + + // This loop will eventually terminate when |i| falls below + // |BN_MUL_RECURSIVE_SIZE_NORMAL| because we know one of |tna| and |tnb| + // exceeds that. + } + } + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_impl implements |BN_mul| and |bn_mul_consttime|. Note this function +// breaks |BIGNUM| invariants and may return a negative zero. This is handled by +// the callers. +static int bn_mul_impl(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int al = a->width; + int bl = b->width; + if (al == 0 || bl == 0) { + BN_zero(r); + return 1; + } + + int ret = 0; + BIGNUM *rr; + BN_CTX_start(ctx); + if (r == a || r == b) { + rr = BN_CTX_get(ctx); + if (rr == NULL) { + goto err; + } + } else { + rr = r; + } + rr->neg = a->neg ^ b->neg; + + int i = al - bl; + if (i == 0) { + if (al == 8) { + if (!bn_wexpand(rr, 16)) { + goto err; + } + rr->width = 16; + bn_mul_comba8(rr->d, a->d, b->d); + goto end; + } + } + + int top = al + bl; + static const int kMulNormalSize = 16; + if (al >= kMulNormalSize && bl >= kMulNormalSize) { + if (-1 <= i && i <= 1) { + // Find the largest power of two less than or equal to the larger length. + int j; + if (i >= 0) { + j = BN_num_bits_word((BN_ULONG)al); + } else { + j = BN_num_bits_word((BN_ULONG)bl); + } + j = 1 << (j - 1); + assert(j <= al || j <= bl); + BIGNUM *t = BN_CTX_get(ctx); + if (t == NULL) { + goto err; + } + if (al > j || bl > j) { + // We know |al| and |bl| are at most one from each other, so if al > j, + // bl >= j, and vice versa. Thus we can use |bn_mul_part_recursive|. + // + // TODO(davidben): This codepath is almost unused in standard + // algorithms. Is this optimization necessary? See notes in + // https://boringssl-review.googlesource.com/q/I0bd604e2cd6a75c266f64476c23a730ca1721ea6 + assert(al >= j && bl >= j); + if (!bn_wexpand(t, j * 8) || + !bn_wexpand(rr, j * 4)) { + goto err; + } + bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } else { + // al <= j && bl <= j. Additionally, we know j <= al or j <= bl, so one + // of al - j or bl - j is zero. The other, by the bound on |i| above, is + // zero or -1. Thus, we can use |bn_mul_recursive|. + if (!bn_wexpand(t, j * 4) || + !bn_wexpand(rr, j * 2)) { + goto err; + } + bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } + rr->width = top; + goto end; + } + } + + if (!bn_wexpand(rr, top)) { + goto err; + } + rr->width = top; + bn_mul_normal(rr->d, a->d, al, b->d, bl); + +end: + if (r != rr && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + if (!bn_mul_impl(r, a, b, ctx)) { + return 0; + } + + // This additionally fixes any negative zeros created by |bn_mul_impl|. + bn_set_minimal_width(r); + return 1; +} + +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // Prevent negative zeros. + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + return bn_mul_impl(r, a, b, ctx); +} + +void bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b) { + if (num_r != num_a + num_b) { + abort(); + } + // TODO(davidben): Should this call |bn_mul_comba4| too? |BN_mul| does not + // hit that code. + if (num_a == 8 && num_b == 8) { + bn_mul_comba8(r, a, b); + } else { + bn_mul_normal(r, a, num_a, b, num_b); + } +} + +// tmp must have 2*n words +static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, size_t n, + BN_ULONG *tmp) { + if (n == 0) { + return; + } + + size_t max = n * 2; + const BN_ULONG *ap = a; + BN_ULONG *rp = r; + rp[0] = rp[max - 1] = 0; + rp++; + + // Compute the contribution of a[i] * a[j] for all i < j. + if (n > 1) { + ap++; + rp[n - 1] = bn_mul_words(rp, ap, n - 1, ap[-1]); + rp += 2; + } + if (n > 2) { + for (size_t i = n - 2; i > 0; i--) { + ap++; + rp[i] = bn_mul_add_words(rp, ap, i, ap[-1]); + rp += 2; + } + } + + // The final result fits in |max| words, so none of the following operations + // will overflow. + + // Double |r|, giving the contribution of a[i] * a[j] for all i != j. + bn_add_words(r, r, r, max); + + // Add in the contribution of a[i] * a[i] for all i. + bn_sqr_words(tmp, a, n); + bn_add_words(r, r, tmp, max); +} + +// bn_sqr_recursive sets |r| to |a|^2, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2|, and |t| has length 4*|n2|. |n2| must be +// a power of two. +static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, size_t n2, + BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + + if (n2 == 4) { + bn_sqr_comba4(r, a); + return; + } + if (n2 == 8) { + bn_sqr_comba8(r, a); + return; + } + if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { + bn_sqr_normal(r, a, n2, t); + return; + } + + // Split |a| into a0,a1, each of size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0^2 to r0,r1, 2*a0*a1 to + // r1,r2, and a1^2 to r2,r3. + size_t n = n2 / 2; + BN_ULONG *t_recursive = &t[n2 * 2]; + + // t0 = |a0 - a1|. + bn_abs_sub_words(t, a, &a[n], n, &t[n]); + // t2,t3 = t0^2 = |a0 - a1|^2 = a0^2 - 2*a0*a1 + a1^2 + bn_sqr_recursive(&t[n2], t, n, t_recursive); + + // r0,r1 = a0^2 + bn_sqr_recursive(r, a, n, t_recursive); + + // r2,r3 = a1^2 + bn_sqr_recursive(&r[n2], &a[n], n, t_recursive); + + // t0,t1,c = r0,r1 + r2,r3 = a0^2 + a1^2 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + // t2,t3,c = t0,t1,c - t2,t3 = 2*a0*a1 + c -= bn_sub_words(&t[n2], t, &t[n2], n2); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (size_t i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The square should fit without carries. + assert(c == 0); +} + +int BN_mul_word(BIGNUM *bn, BN_ULONG w) { + if (!bn->width) { + return 1; + } + + if (w == 0) { + BN_zero(bn); + return 1; + } + + BN_ULONG ll = bn_mul_words(bn->d, bn->d, bn->width, w); + if (ll) { + if (!bn_wexpand(bn, bn->width + 1)) { + return 0; + } + bn->d[bn->width++] = ll; + } + + return 1; +} + +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + int al = a->width; + if (al <= 0) { + r->width = 0; + r->neg = 0; + return 1; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *rr = (a != r) ? r : BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (!rr || !tmp) { + goto err; + } + + int max = 2 * al; // Non-zero (from above) + if (!bn_wexpand(rr, max)) { + goto err; + } + + if (al == 4) { + bn_sqr_comba4(rr->d, a->d); + } else if (al == 8) { + bn_sqr_comba8(rr->d, a->d); + } else { + if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) { + BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2]; + bn_sqr_normal(rr->d, a->d, al, t); + } else { + // If |al| is a power of two, we can use |bn_sqr_recursive|. + if (al != 0 && (al & (al - 1)) == 0) { + if (!bn_wexpand(tmp, al * 4)) { + goto err; + } + bn_sqr_recursive(rr->d, a->d, al, tmp->d); + } else { + if (!bn_wexpand(tmp, max)) { + goto err; + } + bn_sqr_normal(rr->d, a->d, al, tmp->d); + } + } + } + + rr->neg = 0; + rr->width = max; + + if (rr != r && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + if (!bn_sqr_consttime(r, a, ctx)) { + return 0; + } + + bn_set_minimal_width(r); + return 1; +} + +void bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a) { + if (num_r != 2 * num_a || num_a > BN_SMALL_MAX_WORDS) { + abort(); + } + if (num_a == 4) { + bn_sqr_comba4(r, a); + } else if (num_a == 8) { + bn_sqr_comba8(r, a); + } else { + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + bn_sqr_normal(r, a, num_a, tmp); + OPENSSL_cleanse(tmp, 2 * num_a * sizeof(BN_ULONG)); + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c new file mode 100644 index 00000000..33765dc5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c @@ -0,0 +1,1076 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// kPrimes contains the first 1024 primes. +static const uint16_t kPrimes[] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, + 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, + 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, + 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, + 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, + 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, + 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, + 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, + 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, + 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, + 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, + 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, + 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, + 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, + 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, + 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, + 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, + 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, + 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, + 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, + 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, + 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, + 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, + 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, + 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, + 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, + 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, + 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, + 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, + 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, + 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, + 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, + 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, + 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, + 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, + 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, + 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, + 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, + 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, + 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, + 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, + 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, + 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, + 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, + 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, + 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, + 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, + 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, + 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, + 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, + 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, + 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, + 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, + 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, + 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, + 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, + 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, + 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, + 8117, 8123, 8147, 8161, +}; + +// BN_prime_checks_for_size returns the number of Miller-Rabin iterations +// necessary for generating a 'bits'-bit candidate prime. +// +// +// This table is generated using the algorithm of FIPS PUB 186-4 +// Digital Signature Standard (DSS), section F.1, page 117. +// (https://doi.org/10.6028/NIST.FIPS.186-4) +// The following magma script was used to generate the output: +// securitybits:=125; +// k:=1024; +// for t:=1 to 65 do +// for M:=3 to Floor(2*Sqrt(k-1)-1) do +// S:=0; +// // Sum over m +// for m:=3 to M do +// s:=0; +// // Sum over j +// for j:=2 to m do +// s+:=(RealField(32)!2)^-(j+(k-1)/j); +// end for; +// S+:=2^(m-(m-1)*t)*s; +// end for; +// A:=2^(k-2-M*t); +// B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; +// pkt:=2.00743*Log(2)*k*2^-k*(A+B); +// seclevel:=Floor(-Log(2,pkt)); +// if seclevel ge securitybits then +// printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; +// break; +// end if; +// end for; +// if seclevel ge securitybits then break; end if; +// end for; +// +// It can be run online at: http://magma.maths.usyd.edu.au/calc +// And will output: +// k: 1024, security: 129 bits (t: 6, M: 23) +// k is the number of bits of the prime, securitybits is the level we want to +// reach. +// prime length | RSA key size | # MR tests | security level +// -------------+--------------|------------+--------------- +// (b) >= 6394 | >= 12788 | 3 | 256 bit +// (b) >= 3747 | >= 7494 | 3 | 192 bit +// (b) >= 1345 | >= 2690 | 4 | 128 bit +// (b) >= 1080 | >= 2160 | 5 | 128 bit +// (b) >= 852 | >= 1704 | 5 | 112 bit +// (b) >= 476 | >= 952 | 5 | 80 bit +// (b) >= 400 | >= 800 | 6 | 80 bit +// (b) >= 347 | >= 694 | 7 | 80 bit +// (b) >= 308 | >= 616 | 8 | 80 bit +// (b) >= 55 | >= 110 | 27 | 64 bit +// (b) >= 6 | >= 12 | 34 | 64 bit +static int BN_prime_checks_for_size(int bits) { + if (bits >= 3747) { + return 3; + } + if (bits >= 1345) { + return 4; + } + if (bits >= 476) { + return 5; + } + if (bits >= 400) { + return 6; + } + if (bits >= 347) { + return 7; + } + if (bits >= 308) { + return 8; + } + if (bits >= 55) { + return 27; + } + return 34; +} + +// num_trial_division_primes returns the number of primes to try with trial +// division before using more expensive checks. For larger numbers, the value +// of excluding a candidate with trial division is larger. +static size_t num_trial_division_primes(const BIGNUM *n) { + if (n->width * BN_BITS2 > 1024) { + return OPENSSL_ARRAY_SIZE(kPrimes); + } + return OPENSSL_ARRAY_SIZE(kPrimes) / 2; +} + +// BN_PRIME_CHECKS_BLINDED is the iteration count for blinding the constant-time +// primality test. See |BN_primality_test| for details. This number is selected +// so that, for a candidate N-bit RSA prime, picking |BN_PRIME_CHECKS_BLINDED| +// random N-bit numbers will have at least |BN_prime_checks_for_size(N)| values +// in range with high probability. +// +// The following Python script computes the blinding factor needed for the +// corresponding iteration count. +/* +import math + +# We choose candidate RSA primes between sqrt(2)/2 * 2^N and 2^N and select +# witnesses by generating random N-bit numbers. Thus the probability of +# selecting one in range is at least sqrt(2)/2. +p = math.sqrt(2) / 2 + +# Target around 2^-8 probability of the blinding being insufficient given that +# key generation is a one-time, noisy operation. +epsilon = 2**-8 + +def choose(a, b): + r = 1 + for i in xrange(b): + r *= a - i + r /= (i + 1) + return r + +def failure_rate(min_uniform, iterations): + """ Returns the probability that, for |iterations| candidate witnesses, fewer + than |min_uniform| of them will be uniform. """ + prob = 0.0 + for i in xrange(min_uniform): + prob += (choose(iterations, i) * + p**i * (1-p)**(iterations - i)) + return prob + +for min_uniform in (3, 4, 5, 6, 8, 13, 19, 28): + # Find the smallest number of iterations under the target failure rate. + iterations = min_uniform + while True: + prob = failure_rate(min_uniform, iterations) + if prob < epsilon: + print min_uniform, iterations, prob + break + iterations += 1 + +Output: + 3 9 0.00368894873911 + 4 11 0.00363319494662 + 5 13 0.00336215573898 + 6 15 0.00300145783158 + 8 19 0.00225214119331 + 13 27 0.00385610026955 + 19 38 0.0021410539126 + 28 52 0.00325405801769 + +16 iterations suffices for 400-bit primes and larger (6 uniform samples needed), +which is already well below the minimum acceptable key size for RSA. +*/ +#define BN_PRIME_CHECKS_BLINDED 16 + +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, + const BIGNUM *rem, BN_CTX *ctx); +static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, + const BIGNUM *rem, BN_CTX *ctx); + +BN_GENCB *BN_GENCB_new(void) { + BN_GENCB *callback = OPENSSL_malloc(sizeof(BN_GENCB)); + if (callback == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(callback, 0, sizeof(BN_GENCB)); + return callback; +} + +void BN_GENCB_free(BN_GENCB *callback) { OPENSSL_free(callback); } + +void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, struct bn_gencb_st *), + void *arg) { + callback->callback = f; + callback->arg = arg; +} + +int BN_GENCB_call(BN_GENCB *callback, int event, int n) { + if (!callback) { + return 1; + } + + return callback->callback(event, n, callback); +} + +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb) { + BIGNUM *t; + int found = 0; + int i, j, c1 = 0; + BN_CTX *ctx; + int checks = BN_prime_checks_for_size(bits); + + if (bits < 2) { + // There are no prime numbers this small. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } else if (bits == 2 && safe) { + // The smallest safe prime (7) is three bits. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (!t) { + goto err; + } + +loop: + // make a random number and set the top and bottom bits + if (add == NULL) { + if (!probable_prime(ret, bits)) { + goto err; + } + } else { + if (safe) { + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) { + goto err; + } + } else { + if (!probable_prime_dh(ret, bits, add, rem, ctx)) { + goto err; + } + } + } + + if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { + // aborted + goto err; + } + + if (!safe) { + i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + if (i == -1) { + goto err; + } else if (i == 0) { + goto loop; + } + } else { + // for "safe prime" generation, check that (p-1)/2 is prime. Since a prime + // is odd, We just need to divide by 2 + if (!BN_rshift1(t, ret)) { + goto err; + } + + // Interleave |ret| and |t|'s primality tests to avoid paying the full + // iteration count on |ret| only to quickly discover |t| is composite. + // + // TODO(davidben): This doesn't quite work because an iteration count of 1 + // still runs the blinding mechanism. + for (i = 0; i < checks; i++) { + j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i)) { + goto err; + } + // We have a safe prime test pass + } + } + + // we have a prime :-) + found = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return found; +} + +static int bn_trial_division(uint16_t *out, const BIGNUM *bn) { + const size_t num_primes = num_trial_division_primes(bn); + for (size_t i = 1; i < num_primes; i++) { + if (bn_mod_u16_consttime(bn, kPrimes[i]) == 0) { + *out = kPrimes[i]; + return 1; + } + } + return 0; +} + +int bn_odd_number_is_obviously_composite(const BIGNUM *bn) { + uint16_t prime; + return bn_trial_division(&prime, bn) && !BN_is_word(bn, prime); +} + +int bn_miller_rabin_init(BN_MILLER_RABIN *miller_rabin, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + // This function corresponds to steps 1 through 3 of FIPS 186-4, C.3.1. + const BIGNUM *w = &mont->N; + // Note we do not call |BN_CTX_start| in this function. We intentionally + // allocate values in the containing scope so they outlive this function. + miller_rabin->w1 = BN_CTX_get(ctx); + miller_rabin->m = BN_CTX_get(ctx); + miller_rabin->one_mont = BN_CTX_get(ctx); + miller_rabin->w1_mont = BN_CTX_get(ctx); + if (miller_rabin->w1 == NULL || + miller_rabin->m == NULL || + miller_rabin->one_mont == NULL || + miller_rabin->w1_mont == NULL) { + return 0; + } + + // See FIPS 186-4, C.3.1, steps 1 through 3. + if (!bn_usub_consttime(miller_rabin->w1, w, BN_value_one())) { + return 0; + } + miller_rabin->a = BN_count_low_zero_bits(miller_rabin->w1); + if (!bn_rshift_secret_shift(miller_rabin->m, miller_rabin->w1, + miller_rabin->a, ctx)) { + return 0; + } + miller_rabin->w_bits = BN_num_bits(w); + + // Precompute some values in Montgomery form. + if (!bn_one_to_montgomery(miller_rabin->one_mont, mont, ctx) || + // w - 1 is -1 mod w, so we can compute it in the Montgomery domain, -R, + // with a subtraction. (|one_mont| cannot be zero.) + !bn_usub_consttime(miller_rabin->w1_mont, w, miller_rabin->one_mont)) { + return 0; + } + + return 1; +} + +int bn_miller_rabin_iteration(const BN_MILLER_RABIN *miller_rabin, + int *out_is_possibly_prime, const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + // This function corresponds to steps 4.3 through 4.5 of FIPS 186-4, C.3.1. + int ret = 0; + BN_CTX_start(ctx); + + // Step 4.3. We use Montgomery-encoding for better performance and to avoid + // timing leaks. + const BIGNUM *w = &mont->N; + BIGNUM *z = BN_CTX_get(ctx); + if (z == NULL || + !BN_mod_exp_mont_consttime(z, b, miller_rabin->m, w, ctx, mont) || + !BN_to_montgomery(z, z, mont, ctx)) { + goto err; + } + + // is_possibly_prime is all ones if we have determined |b| is not a composite + // witness for |w|. This is equivalent to going to step 4.7 in the original + // algorithm. To avoid timing leaks, we run the algorithm to the end for prime + // inputs. + crypto_word_t is_possibly_prime = 0; + + // Step 4.4. If z = 1 or z = w-1, b is not a composite witness and w is still + // possibly prime. + is_possibly_prime = BN_equal_consttime(z, miller_rabin->one_mont) | + BN_equal_consttime(z, miller_rabin->w1_mont); + is_possibly_prime = 0 - is_possibly_prime; // Make it all zeros or all ones. + + // Step 4.5. + // + // To avoid leaking |a|, we run the loop to |w_bits| and mask off all + // iterations once |j| = |a|. + for (int j = 1; j < miller_rabin->w_bits; j++) { + if (constant_time_eq_int(j, miller_rabin->a) & ~is_possibly_prime) { + // If the loop is done and we haven't seen z = 1 or z = w-1 yet, the + // value is composite and we can break in variable time. + break; + } + + // Step 4.5.1. + if (!BN_mod_mul_montgomery(z, z, z, mont, ctx)) { + goto err; + } + + // Step 4.5.2. If z = w-1 and the loop is not done, this is not a composite + // witness. + crypto_word_t z_is_w1_mont = BN_equal_consttime(z, miller_rabin->w1_mont); + z_is_w1_mont = 0 - z_is_w1_mont; // Make it all zeros or all ones. + is_possibly_prime |= z_is_w1_mont; // Go to step 4.7 if |z_is_w1_mont|. + + // Step 4.5.3. If z = 1 and the loop is not done, the previous value of z + // was not -1. There are no non-trivial square roots of 1 modulo a prime, so + // w is composite and we may exit in variable time. + if (BN_equal_consttime(z, miller_rabin->one_mont) & ~is_possibly_prime) { + break; + } + } + + *out_is_possibly_prime = is_possibly_prime & 1; + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_primality_test(int *out_is_probably_prime, const BIGNUM *w, int checks, + BN_CTX *ctx, int do_trial_division, BN_GENCB *cb) { + // This function's secrecy and performance requirements come from RSA key + // generation. We generate RSA keys by selecting two large, secret primes with + // rejection sampling. + // + // We thus treat |w| as secret if turns out to be a large prime. However, if + // |w| is composite, we treat this and |w| itself as public. (Conversely, if + // |w| is prime, that it is prime is public. Only the value is secret.) This + // is fine for RSA key generation, but note it is important that we use + // rejection sampling, with each candidate prime chosen independently. This + // would not work for, e.g., an algorithm which looked for primes in + // consecutive integers. These assumptions allow us to discard composites + // quickly. We additionally treat |w| as public when it is a small prime to + // simplify trial decryption and some edge cases. + // + // One RSA key generation will call this function on exactly two primes and + // many more composites. The overall cost is a combination of several factors: + // + // 1. Checking if |w| is divisible by a small prime is much faster than + // learning it is composite by Miller-Rabin (see below for details on that + // cost). Trial division by p saves 1/p of Miller-Rabin calls, so this is + // worthwhile until p exceeds the ratio of the two costs. + // + // 2. For a random (i.e. non-adversarial) candidate large prime and candidate + // witness, the probability of false witness is very low. (This is why FIPS + // 186-4 only requires a few iterations.) Thus composites not discarded by + // trial decryption, in practice, cost one Miller-Rabin iteration. Only the + // two actual primes cost the full iteration count. + // + // 3. A Miller-Rabin iteration is a modular exponentiation plus |a| additional + // modular squares, where |a| is the number of factors of two in |w-1|. |a| + // is likely small (the distribution falls exponentially), but it is also + // potentially secret, so we loop up to its log(w) upper bound when |w| is + // prime. When |w| is composite, we break early, so only two calls pay this + // cost. (Note that all calls pay the modular exponentiation which is, + // itself, log(w) modular multiplications and squares.) + // + // 4. While there are only two prime calls, they multiplicatively pay the full + // costs of (2) and (3). + // + // 5. After the primes are chosen, RSA keys derive some values from the + // primes, but this cost is negligible in comparison. + + *out_is_probably_prime = 0; + + if (BN_cmp(w, BN_value_one()) <= 0) { + return 1; + } + + if (!BN_is_odd(w)) { + // The only even prime is two. + *out_is_probably_prime = BN_is_word(w, 2); + return 1; + } + + // Miller-Rabin does not work for three. + if (BN_is_word(w, 3)) { + *out_is_probably_prime = 1; + return 1; + } + + if (do_trial_division) { + // Perform additional trial division checks to discard small primes. + uint16_t prime; + if (bn_trial_division(&prime, w)) { + *out_is_probably_prime = BN_is_word(w, prime); + return 1; + } + if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, -1)) { + return 0; + } + } + + if (checks == BN_prime_checks_for_generation) { + checks = BN_prime_checks_for_size(BN_num_bits(w)); + } + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + return 0; + } + ctx = new_ctx; + } + + // See C.3.1 from FIPS 186-4. + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *b = BN_CTX_get(ctx); + BN_MONT_CTX *mont = BN_MONT_CTX_new_consttime(w, ctx); + BN_MILLER_RABIN miller_rabin; + if (b == NULL || mont == NULL || + // Steps 1-3. + !bn_miller_rabin_init(&miller_rabin, mont, ctx)) { + goto err; + } + + // The following loop performs in inner iteration of the Miller-Rabin + // Primality test (Step 4). + // + // The algorithm as specified in FIPS 186-4 leaks information on |w|, the RSA + // private key. Instead, we run through each iteration unconditionally, + // performing modular multiplications, masking off any effects to behave + // equivalently to the specified algorithm. + // + // We also blind the number of values of |b| we try. Steps 4.1–4.2 say to + // discard out-of-range values. To avoid leaking information on |w|, we use + // |bn_rand_secret_range| which, rather than discarding bad values, adjusts + // them to be in range. Though not uniformly selected, these adjusted values + // are still usable as Miller-Rabin checks. + // + // Miller-Rabin is already probabilistic, so we could reach the desired + // confidence levels by just suitably increasing the iteration count. However, + // to align with FIPS 186-4, we use a more pessimal analysis: we do not count + // the non-uniform values towards the iteration count. As a result, this + // function is more complex and has more timing risk than necessary. + // + // We count both total iterations and uniform ones and iterate until we've + // reached at least |BN_PRIME_CHECKS_BLINDED| and |iterations|, respectively. + // If the latter is large enough, it will be the limiting factor with high + // probability and we won't leak information. + // + // Note this blinding does not impact most calls when picking primes because + // composites are rejected early. Only the two secret primes see extra work. + + crypto_word_t uniform_iterations = 0; + // Using |constant_time_lt_w| seems to prevent the compiler from optimizing + // this into two jumps. + for (int i = 1; (i <= BN_PRIME_CHECKS_BLINDED) | + constant_time_lt_w(uniform_iterations, checks); + i++) { + // Step 4.1-4.2 + int is_uniform; + if (!bn_rand_secret_range(b, &is_uniform, 2, miller_rabin.w1)) { + goto err; + } + uniform_iterations += is_uniform; + + // Steps 4.3-4.5 + int is_possibly_prime = 0; + if (!bn_miller_rabin_iteration(&miller_rabin, &is_possibly_prime, b, mont, + ctx)) { + goto err; + } + + if (!is_possibly_prime) { + // Step 4.6. We did not see z = w-1 before z = 1, so w must be composite. + *out_is_probably_prime = 0; + ret = 1; + goto err; + } + + // Step 4.7 + if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { + goto err; + } + } + + assert(uniform_iterations >= (crypto_word_t)checks); + *out_is_probably_prime = 1; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + +int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx, + BN_GENCB *cb) { + return BN_is_prime_fasttest_ex(candidate, checks, ctx, 0, cb); +} + +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb) { + int is_probably_prime; + if (!BN_primality_test(&is_probably_prime, a, checks, ctx, do_trial_division, + cb)) { + return -1; + } + return is_probably_prime; +} + +int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int checks, + BN_CTX *ctx, BN_GENCB *cb) { + // Enhanced Miller-Rabin is only valid on odd integers greater than 3. + if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT); + return 0; + } + + if (checks == BN_prime_checks_for_generation) { + checks = BN_prime_checks_for_size(BN_num_bits(w)); + } + + int ret = 0; + BN_MONT_CTX *mont = NULL; + + BN_CTX_start(ctx); + + BIGNUM *w1 = BN_CTX_get(ctx); + if (w1 == NULL || + !BN_copy(w1, w) || + !BN_sub_word(w1, 1)) { + goto err; + } + + // Write w1 as m*2^a (Steps 1 and 2). + int a = 0; + while (!BN_is_bit_set(w1, a)) { + a++; + } + BIGNUM *m = BN_CTX_get(ctx); + if (m == NULL || + !BN_rshift(m, w1, a)) { + goto err; + } + + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *g = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *x1 = BN_CTX_get(ctx); + if (b == NULL || + g == NULL || + z == NULL || + x == NULL || + x1 == NULL) { + goto err; + } + + // Montgomery setup for computations mod w + mont = BN_MONT_CTX_new_for_modulus(w, ctx); + if (mont == NULL) { + goto err; + } + + // The following loop performs in inner iteration of the Enhanced Miller-Rabin + // Primality test (Step 4). + for (int i = 1; i <= checks; i++) { + // Step 4.1-4.2 + if (!BN_rand_range_ex(b, 2, w1)) { + goto err; + } + + // Step 4.3-4.4 + if (!BN_gcd(g, b, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + ret = 1; + goto err; + } + + // Step 4.5 + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { + goto err; + } + + // Step 4.6 + if (BN_is_one(z) || BN_cmp(z, w1) == 0) { + goto loop; + } + + // Step 4.7 + for (int j = 1; j < a; j++) { + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + if (BN_cmp(z, w1) == 0) { + goto loop; + } + if (BN_is_one(z)) { + goto composite; + } + } + + // Step 4.8-4.9 + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + + // Step 4.10-4.11 + if (!BN_is_one(z) && !BN_copy(x, z)) { + goto err; + } + + composite: + // Step 4.12-4.14 + if (!BN_copy(x1, x) || + !BN_sub_word(x1, 1) || + !BN_gcd(g, x1, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + } else { + *out_result = bn_non_prime_power_composite; + } + + ret = 1; + goto err; + + loop: + // Step 4.15 + if (!BN_GENCB_call(cb, BN_GENCB_PRIME_TEST, i - 1)) { + goto err; + } + } + + *out_result = bn_probably_prime; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + + return ret; +} + +static int probable_prime(BIGNUM *rnd, int bits) { + do { + if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) { + return 0; + } + } while (bn_odd_number_is_obviously_composite(rnd)); + return 1; +} + +static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, + const BIGNUM *rem, BN_CTX *ctx) { + int ret = 0; + BIGNUM *t1; + + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) { + goto err; + } + + if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + goto err; + } + + // we need ((rnd-rem) % add) == 0 + + if (!BN_mod(t1, rnd, add, ctx)) { + goto err; + } + if (!BN_sub(rnd, rnd, t1)) { + goto err; + } + if (rem == NULL) { + if (!BN_add_word(rnd, 1)) { + goto err; + } + } else { + if (!BN_add(rnd, rnd, rem)) { + goto err; + } + } + // we now have a random number 'rand' to test. + + const size_t num_primes = num_trial_division_primes(rnd); +loop: + for (size_t i = 1; i < num_primes; i++) { + // check that rnd is a prime + if (bn_mod_u16_consttime(rnd, kPrimes[i]) <= 1) { + if (!BN_add(rnd, rnd, add)) { + goto err; + } + goto loop; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, + const BIGNUM *rem, BN_CTX *ctx) { + int ret = 0; + BIGNUM *t1, *qadd, *q; + + bits--; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + qadd = BN_CTX_get(ctx); + if (qadd == NULL) { + goto err; + } + + if (!BN_rshift1(qadd, padd)) { + goto err; + } + + if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + goto err; + } + + // we need ((rnd-rem) % add) == 0 + if (!BN_mod(t1, q, qadd, ctx)) { + goto err; + } + + if (!BN_sub(q, q, t1)) { + goto err; + } + + if (rem == NULL) { + if (!BN_add_word(q, 1)) { + goto err; + } + } else { + if (!BN_rshift1(t1, rem)) { + goto err; + } + if (!BN_add(q, q, t1)) { + goto err; + } + } + + // we now have a random number 'rand' to test. + if (!BN_lshift1(p, q)) { + goto err; + } + if (!BN_add_word(p, 1)) { + goto err; + } + + const size_t num_primes = num_trial_division_primes(p); +loop: + for (size_t i = 1; i < num_primes; i++) { + // check that p and q are prime + // check that for p and q + // gcd(p-1,primes) == 1 (except for 2) + if (bn_mod_u16_consttime(p, kPrimes[i]) == 0 || + bn_mod_u16_consttime(q, kPrimes[i]) == 0) { + if (!BN_add(p, p, padd)) { + goto err; + } + if (!BN_add(q, q, qadd)) { + goto err; + } + goto loop; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/random.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/random.c new file mode 100644 index 00000000..f66372b9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/random.c @@ -0,0 +1,341 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../rand/internal.h" + + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { + if (rnd == NULL) { + return 0; + } + + if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE && + top != BN_RAND_TOP_TWO) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bits == 0) { + BN_zero(rnd); + return 1; + } + + if (bits > INT_MAX - (BN_BITS2 - 1)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + + int words = (bits + BN_BITS2 - 1) / BN_BITS2; + int bit = (bits - 1) % BN_BITS2; + const BN_ULONG kOne = 1; + const BN_ULONG kThree = 3; + BN_ULONG mask = bit < BN_BITS2 - 1 ? (kOne << (bit + 1)) - 1 : BN_MASK2; + if (!bn_wexpand(rnd, words)) { + return 0; + } + + RAND_bytes((uint8_t *)rnd->d, words * sizeof(BN_ULONG)); + rnd->d[words - 1] &= mask; + if (top != BN_RAND_TOP_ANY) { + if (top == BN_RAND_TOP_TWO && bits > 1) { + if (bit == 0) { + rnd->d[words - 1] |= 1; + rnd->d[words - 2] |= kOne << (BN_BITS2 - 1); + } else { + rnd->d[words - 1] |= kThree << (bit - 1); + } + } else { + rnd->d[words - 1] |= kOne << bit; + } + } + if (bottom == BN_RAND_BOTTOM_ODD) { + rnd->d[0] |= 1; + } + + rnd->neg = 0; + rnd->width = words; + return 1; +} + +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { + return BN_rand(rnd, bits, top, bottom); +} + +// bn_less_than_word_mask returns a mask of all ones if the number represented +// by |len| words at |a| is less than |b| and zero otherwise. It performs this +// computation in time independent of the value of |a|. |b| is assumed public. +static crypto_word_t bn_less_than_word_mask(const BN_ULONG *a, size_t len, + BN_ULONG b) { + if (b == 0) { + return CONSTTIME_FALSE_W; + } + if (len == 0) { + return CONSTTIME_TRUE_W; + } + + // |a| < |b| iff a[1..len-1] are all zero and a[0] < b. + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + crypto_word_t mask = 0; + for (size_t i = 1; i < len; i++) { + mask |= a[i]; + } + // |mask| is now zero iff a[1..len-1] are all zero. + mask = constant_time_is_zero_w(mask); + mask &= constant_time_lt_w(a[0], b); + return mask; +} + +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len) { + crypto_word_t mask = ~bn_less_than_word_mask(a, len, min_inclusive); + return mask & bn_less_than_words(a, max_exclusive, len); +} + +static int bn_range_to_mask(size_t *out_words, BN_ULONG *out_mask, + size_t min_inclusive, const BN_ULONG *max_exclusive, + size_t len) { + // The magnitude of |max_exclusive| is assumed public. + size_t words = len; + while (words > 0 && max_exclusive[words - 1] == 0) { + words--; + } + if (words == 0 || + (words == 1 && max_exclusive[0] <= min_inclusive)) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + BN_ULONG mask = max_exclusive[words - 1]; + // This sets all bits in |mask| below the most significant bit. + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; +#if defined(OPENSSL_64_BIT) + mask |= mask >> 32; +#endif + + *out_words = words; + *out_mask = mask; + return 1; +} + +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]) { + // This function implements the equivalent of steps 4 through 7 of FIPS 186-4 + // appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| + // is n and |min_inclusive| is one. + + // Compute the bit length of |max_exclusive| (step 1), in terms of a number of + // |words| worth of entropy to fill and a mask of bits to clear in the top + // word. + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive, len)) { + return 0; + } + + // Fill any unused words with zero. + OPENSSL_memset(out + words, 0, (len - words) * sizeof(BN_ULONG)); + + unsigned count = 100; + do { + if (!--count) { + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + // Steps 4 and 5. Use |words| and |mask| together to obtain a string of N + // bits, where N is the bit length of |max_exclusive|. + RAND_bytes_with_additional_data((uint8_t *)out, words * sizeof(BN_ULONG), + additional_data); + out[words - 1] &= mask; + + // If out >= max_exclusive or out < min_inclusive, retry. This implements + // the equivalent of steps 6 and 7 without leaking the value of |out|. + } while (!bn_in_range_words(out, min_inclusive, max_exclusive, words)); + return 1; +} + +int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + static const uint8_t kDefaultAdditionalData[32] = {0}; + if (!bn_wexpand(r, max_exclusive->width) || + !bn_rand_range_words(r->d, min_inclusive, max_exclusive->d, + max_exclusive->width, kDefaultAdditionalData)) { + return 0; + } + + r->neg = 0; + r->width = max_exclusive->width; + return 1; +} + +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive->d, + max_exclusive->width) || + !bn_wexpand(r, words)) { + return 0; + } + + assert(words > 0); + assert(mask != 0); + // The range must be large enough for bit tricks to fix invalid values. + if (words == 1 && min_inclusive > mask >> 1) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + + // Select a uniform random number with num_bits(max_exclusive) bits. + RAND_bytes((uint8_t *)r->d, words * sizeof(BN_ULONG)); + r->d[words - 1] &= mask; + + // Check, in constant-time, if the value is in range. + *out_is_uniform = + bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words); + crypto_word_t in_range = *out_is_uniform; + in_range = 0 - in_range; + + // If the value is not in range, force it to be in range. + r->d[0] |= constant_time_select_w(in_range, 0, min_inclusive); + r->d[words - 1] &= constant_time_select_w(in_range, BN_MASK2, mask >> 1); + assert(bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words)); + + r->neg = 0; + r->width = words; + return 1; +} + +int BN_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range_ex(r, 0, range); +} + +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range(r, range); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c new file mode 100644 index 00000000..d0de9d66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c @@ -0,0 +1,226 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#include "rsaz_exp.h" + +#if defined(RSAZ_ENABLED) + +#include + +#include "internal.h" +#include "../../internal.h" + + +// one is 1 in RSAZ's representation. +alignas(64) static const BN_ULONG one[40] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// two80 is 2^80 in RSAZ's representation. Note RSAZ uses base 2^29, so this is +// 2^(29*2 + 22) = 2^80, not 2^(64*2 + 22). +alignas(64) static const BN_ULONG two80[40] = { + 0, 0, 1 << 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], + const BN_ULONG base_norm[16], + const BN_ULONG exponent[16], + const BN_ULONG m_norm[16], const BN_ULONG RR[16], + BN_ULONG k0, + BN_ULONG storage[MOD_EXP_CTIME_STORAGE_LEN]) { + OPENSSL_STATIC_ASSERT(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH % 64 == 0, + "MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH is too small"); + assert((uintptr_t)storage % 64 == 0); + + BN_ULONG *a_inv, *m, *result, *table_s = storage + 40 * 3, *R2 = table_s; + // Note |R2| aliases |table_s|. + if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) { + result = storage; + a_inv = storage + 40; + m = storage + 40 * 2; // should not cross page + } else { + m = storage; // should not cross page + result = storage + 40; + a_inv = storage + 40 * 2; + } + + rsaz_1024_norm2red_avx2(m, m_norm); + rsaz_1024_norm2red_avx2(a_inv, base_norm); + rsaz_1024_norm2red_avx2(R2, RR); + + // Convert |R2| from the usual radix, giving R = 2^1024, to RSAZ's radix, + // giving R = 2^(36*29) = 2^1044. + rsaz_1024_mul_avx2(R2, R2, R2, m, k0); + // R2 = 2^2048 * 2^2048 / 2^1044 = 2^3052 + rsaz_1024_mul_avx2(R2, R2, two80, m, k0); + // R2 = 2^3052 * 2^80 / 2^1044 = 2^2088 = (2^1044)^2 + + // table[0] = 1 + rsaz_1024_mul_avx2(result, R2, one, m, k0); + // table[1] = a_inv^1 + rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0); + + rsaz_1024_scatter5_avx2(table_s, result, 0); + rsaz_1024_scatter5_avx2(table_s, a_inv, 1); + + // table[2] = a_inv^2 + rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 2); +#if 0 + // This is almost 2x smaller and less than 1% slower. + for (int index = 3; index < 32; index++) { + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, index); + } +#else + // table[4] = a_inv^4 + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 4); + // table[8] = a_inv^8 + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 8); + // table[16] = a_inv^16 + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 16); + // table[17] = a_inv^17 + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 17); + + // table[3] + rsaz_1024_gather5_avx2(result, table_s, 2); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 3); + // table[6] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 6); + // table[12] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 12); + // table[24] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 24); + // table[25] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 25); + + // table[5] + rsaz_1024_gather5_avx2(result, table_s, 4); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 5); + // table[10] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 10); + // table[20] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 20); + // table[21] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 21); + + // table[7] + rsaz_1024_gather5_avx2(result, table_s, 6); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 7); + // table[14] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 14); + // table[28] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 28); + // table[29] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 29); + + // table[9] + rsaz_1024_gather5_avx2(result, table_s, 8); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 9); + // table[18] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 18); + // table[19] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 19); + + // table[11] + rsaz_1024_gather5_avx2(result, table_s, 10); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 11); + // table[22] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 22); + // table[23] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 23); + + // table[13] + rsaz_1024_gather5_avx2(result, table_s, 12); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 13); + // table[26] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 26); + // table[27] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 27); + + // table[15] + rsaz_1024_gather5_avx2(result, table_s, 14); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 15); + // table[30] + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 30); + // table[31] + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 31); +#endif + + const uint8_t *p_str = (const uint8_t *)exponent; + + // load first window + int wvalue = p_str[127] >> 3; + rsaz_1024_gather5_avx2(result, table_s, wvalue); + + int index = 1014; + while (index > -1) { // Loop for the remaining 127 windows. + + rsaz_1024_sqr_avx2(result, result, m, k0, 5); + + uint16_t wvalue_16; + memcpy(&wvalue_16, &p_str[index / 8], sizeof(wvalue_16)); + wvalue = wvalue_16; + wvalue = (wvalue >> (index % 8)) & 31; + index -= 5; + + rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); // Borrow |a_inv|. + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + } + + // Square four times. + rsaz_1024_sqr_avx2(result, result, m, k0, 4); + + wvalue = p_str[0] & 15; + + rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); // Borrow |a_inv|. + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + + // Convert from Montgomery. + rsaz_1024_mul_avx2(result, result, one, m, k0); + + rsaz_1024_red2norm_avx2(result_norm, result); + + OPENSSL_cleanse(storage, MOD_EXP_CTIME_STORAGE_LEN * sizeof(BN_ULONG)); +} + +#endif // RSAZ_ENABLED diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h new file mode 100644 index 00000000..bcb49d8c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h @@ -0,0 +1,103 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#ifndef OPENSSL_HEADER_BN_RSAZ_EXP_H +#define OPENSSL_HEADER_BN_RSAZ_EXP_H + +#include + +#include "internal.h" +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) +#define RSAZ_ENABLED + + +// RSAZ_1024_mod_exp_avx2 sets |result| to |base_norm| raised to |exponent| +// modulo |m_norm|. |base_norm| must be fully-reduced and |exponent| must have +// the high bit set (it is 1024 bits wide). |RR| and |k0| must be |RR| and |n0|, +// respectively, extracted from |m_norm|'s |BN_MONT_CTX|. |storage_words| is a +// temporary buffer that must be aligned to |MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH| +// bytes. +void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], const BN_ULONG base_norm[16], + const BN_ULONG exponent[16], + const BN_ULONG m_norm[16], const BN_ULONG RR[16], + BN_ULONG k0, + BN_ULONG storage_words[MOD_EXP_CTIME_STORAGE_LEN]); + +OPENSSL_INLINE int rsaz_avx2_capable(void) { + return CRYPTO_is_AVX2_capable(); +} + +OPENSSL_INLINE int rsaz_avx2_preferred(void) { + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + // If BMI1, BMI2, and ADX are available, x86_64-mont5.pl is faster. See the + // .Lmulx4x_enter and .Lpowerx5_enter branches. + return 0; + } + return CRYPTO_is_AVX2_capable(); +} + + +// Assembly functions. + +// RSAZ represents 1024-bit integers using unsaturated 29-bit limbs stored in +// 64-bit integers. This requires 36 limbs but padded up to 40. +// +// See crypto/bn/asm/rsaz-avx2.pl for further details. + +// rsaz_1024_norm2red_avx2 converts |norm| from |BIGNUM| to RSAZ representation +// and writes the result to |red|. +void rsaz_1024_norm2red_avx2(BN_ULONG red[40], const BN_ULONG norm[16]); + +// rsaz_1024_mul_avx2 computes |a| * |b| mod |n| and writes the result to |ret|. +// Inputs and outputs are in Montgomery form, using RSAZ's representation. |k| +// is -|n|^-1 mod 2^64 or |n0| from |BN_MONT_CTX|. +void rsaz_1024_mul_avx2(BN_ULONG ret[40], const BN_ULONG a[40], + const BN_ULONG b[40], const BN_ULONG n[40], BN_ULONG k); + +// rsaz_1024_mul_avx2 computes |a|^(2*|count|) mod |n| and writes the result to +// |ret|. Inputs and outputs are in Montgomery form, using RSAZ's +// representation. |k| is -|n|^-1 mod 2^64 or |n0| from |BN_MONT_CTX|. +void rsaz_1024_sqr_avx2(BN_ULONG ret[40], const BN_ULONG a[40], + const BN_ULONG n[40], BN_ULONG k, int count); + +// rsaz_1024_scatter5_avx2 stores |val| at index |i| of |tbl|. |i| must be +// positive and at most 31. Note the table only uses 18 |BN_ULONG|s per entry +// instead of 40. It packs two 29-bit limbs into each |BN_ULONG| and only stores +// 36 limbs rather than the padded 40. +void rsaz_1024_scatter5_avx2(BN_ULONG tbl[32 * 18], const BN_ULONG val[40], + int i); + +// rsaz_1024_gather5_avx2 loads index |i| of |tbl| and writes it to |val|. +void rsaz_1024_gather5_avx2(BN_ULONG val[40], const BN_ULONG tbl[32 * 18], + int i); + +// rsaz_1024_red2norm_avx2 converts |red| from RSAZ to |BIGNUM| representation +// and writes the result to |norm|. +void rsaz_1024_red2norm_avx2(BN_ULONG norm[16], const BN_ULONG red[40]); + + +#endif // !OPENSSL_NO_ASM && OPENSSL_X86_64 + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // OPENSSL_HEADER_BN_RSAZ_EXP_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/shift.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/shift.c new file mode 100644 index 00000000..364b5261 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/shift.c @@ -0,0 +1,364 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include + +#include "internal.h" + + +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) { + int i, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l; + + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + r->neg = a->neg; + nw = n / BN_BITS2; + if (!bn_wexpand(r, a->width + nw + 1)) { + return 0; + } + lb = n % BN_BITS2; + rb = BN_BITS2 - lb; + f = a->d; + t = r->d; + t[a->width + nw] = 0; + if (lb == 0) { + for (i = a->width - 1; i >= 0; i--) { + t[nw + i] = f[i]; + } + } else { + for (i = a->width - 1; i >= 0; i--) { + l = f[i]; + t[nw + i + 1] |= l >> rb; + t[nw + i] = l << lb; + } + } + OPENSSL_memset(t, 0, nw * sizeof(t[0])); + r->width = a->width + nw + 1; + bn_set_minimal_width(r); + + return 1; +} + +int BN_lshift1(BIGNUM *r, const BIGNUM *a) { + BN_ULONG *ap, *rp, t, c; + int i; + + if (r != a) { + r->neg = a->neg; + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + r->width = a->width; + } else { + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + } + ap = a->d; + rp = r->d; + c = 0; + for (i = 0; i < a->width; i++) { + t = *(ap++); + *(rp++) = (t << 1) | c; + c = t >> (BN_BITS2 - 1); + } + if (c) { + *rp = 1; + r->width++; + } + + return 1; +} + +void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift, + size_t num) { + unsigned shift_bits = shift % BN_BITS2; + size_t shift_words = shift / BN_BITS2; + if (shift_words >= num) { + OPENSSL_memset(r, 0, num * sizeof(BN_ULONG)); + return; + } + if (shift_bits == 0) { + OPENSSL_memmove(r, a + shift_words, (num - shift_words) * sizeof(BN_ULONG)); + } else { + for (size_t i = shift_words; i < num - 1; i++) { + r[i - shift_words] = + (a[i] >> shift_bits) | (a[i + 1] << (BN_BITS2 - shift_bits)); + } + r[num - 1 - shift_words] = a[num - 1] >> shift_bits; + } + OPENSSL_memset(r + num - shift_words, 0, shift_words * sizeof(BN_ULONG)); +} + +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) { + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift_words(r->d, a->d, n, a->width); + r->neg = a->neg; + r->width = a->width; + bn_set_minimal_width(r); + return 1; +} + +int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, unsigned n, + BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_copy(r, a) || + !bn_wexpand(tmp, r->width)) { + goto err; + } + + // Shift conditionally by powers of two. + unsigned max_bits = BN_BITS2 * r->width; + for (unsigned i = 0; (max_bits >> i) != 0; i++) { + BN_ULONG mask = (n >> i) & 1; + mask = 0 - mask; + bn_rshift_words(tmp->d, r->d, 1u << i, r->width); + bn_select_words(r->d, mask, tmp->d /* apply shift */, + r->d /* ignore shift */, r->width); + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num) { + if (num == 0) { + return; + } + for (size_t i = 0; i < num - 1; i++) { + r[i] = (a[i] >> 1) | (a[i + 1] << (BN_BITS2 - 1)); + } + r[num - 1] = a[num - 1] >> 1; +} + +int BN_rshift1(BIGNUM *r, const BIGNUM *a) { + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift1_words(r->d, a->d, a->width); + r->width = a->width; + r->neg = a->neg; + bn_set_minimal_width(r); + return 1; +} + +int BN_set_bit(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int i = n / BN_BITS2; + int j = n % BN_BITS2; + if (a->width <= i) { + if (!bn_wexpand(a, i + 1)) { + return 0; + } + for (int k = a->width; k < i + 1; k++) { + a->d[k] = 0; + } + a->width = i + 1; + } + + a->d[i] |= (((BN_ULONG)1) << j); + + return 1; +} + +int BN_clear_bit(BIGNUM *a, int n) { + int i, j; + + if (n < 0) { + return 0; + } + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->width <= i) { + return 0; + } + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_set_minimal_width(a); + return 1; +} + +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit) { + unsigned i = bit / BN_BITS2; + unsigned j = bit % BN_BITS2; + if (i >= num) { + return 0; + } + return (a[i] >> j) & 1; +} + +int BN_is_bit_set(const BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + return bn_is_bit_set_words(a->d, a->width, n); +} + +int BN_mask_bits(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int w = n / BN_BITS2; + int b = n % BN_BITS2; + if (w >= a->width) { + return 1; + } + if (b == 0) { + a->width = w; + } else { + a->width = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + + bn_set_minimal_width(a); + return 1; +} + +static int bn_count_low_zero_bits_word(BN_ULONG l) { + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + OPENSSL_STATIC_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + OPENSSL_STATIC_ASSERT(BN_BITS2 == sizeof(BN_ULONG) * 8, + "BN_ULONG has padding bits"); + // C has very bizarre rules for types smaller than an int. + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) >= sizeof(int), + "BN_ULONG gets promoted to int"); + + crypto_word_t mask; + int bits = 0; + +#if BN_BITS2 > 32 + // Check if the lower half of |x| are all zero. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 32)); + // If the lower half is all zeros, it is included in the bit count and we + // count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l = constant_time_select_w(mask, l >> 32, l); +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 16)); + bits += 16 & mask; + l = constant_time_select_w(mask, l >> 16, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 8)); + bits += 8 & mask; + l = constant_time_select_w(mask, l >> 8, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 4)); + bits += 4 & mask; + l = constant_time_select_w(mask, l >> 4, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 2)); + bits += 2 & mask; + l = constant_time_select_w(mask, l >> 2, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 1)); + bits += 1 & mask; + + return bits; +} + +int BN_count_low_zero_bits(const BIGNUM *bn) { + OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + OPENSSL_STATIC_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + + int ret = 0; + crypto_word_t saw_nonzero = 0; + for (int i = 0; i < bn->width; i++) { + crypto_word_t nonzero = ~constant_time_is_zero_w(bn->d[i]); + crypto_word_t first_nonzero = ~saw_nonzero & nonzero; + saw_nonzero |= nonzero; + + int bits = bn_count_low_zero_bits_word(bn->d[i]); + ret |= first_nonzero & (i * BN_BITS2 + bits); + } + + // If got to the end of |bn| and saw no non-zero words, |bn| is zero. |ret| + // will then remain zero. + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c new file mode 100644 index 00000000..b8322d0a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c @@ -0,0 +1,500 @@ +/* Written by Lenka Fibikova + * and Bodo Moeller for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include "internal.h" + + +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm + // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory", + // algorithm 1.5.1). |p| is assumed to be a prime. + + BIGNUM *ret = in; + int err = 1; + int r; + BIGNUM *A, *b, *q, *t, *x, *y; + int e, i, j; + + if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { + if (BN_abs_is_word(p, 2)) { + if (ret == NULL) { + ret = BN_new(); + } + if (ret == NULL || + !BN_set_word(ret, BN_is_bit_set(a, 0))) { + if (ret != in) { + BN_free(ret); + } + return NULL; + } + return ret; + } + + OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); + return NULL; + } + + if (BN_is_zero(a) || BN_is_one(a)) { + if (ret == NULL) { + ret = BN_new(); + } + if (ret == NULL || + !BN_set_word(ret, BN_is_one(a))) { + if (ret != in) { + BN_free(ret); + } + return NULL; + } + return ret; + } + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) { + goto end; + } + + if (ret == NULL) { + ret = BN_new(); + } + if (ret == NULL) { + goto end; + } + + // A = a mod p + if (!BN_nnmod(A, a, p, ctx)) { + goto end; + } + + // now write |p| - 1 as 2^e*q where q is odd + e = 1; + while (!BN_is_bit_set(p, e)) { + e++; + } + // we'll set q later (if needed) + + if (e == 1) { + // The easy case: (|p|-1)/2 is odd, so 2 has an inverse + // modulo (|p|-1)/2, and square roots can be computed + // directly by modular exponentiation. + // We have + // 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), + // so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. + if (!BN_rshift(q, p, 2)) { + goto end; + } + q->neg = 0; + if (!BN_add_word(q, 1) || + !BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) { + goto end; + } + err = 0; + goto vrfy; + } + + if (e == 2) { + // |p| == 5 (mod 8) + // + // In this case 2 is always a non-square since + // Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. + // So if a really is a square, then 2*a is a non-square. + // Thus for + // b := (2*a)^((|p|-5)/8), + // i := (2*a)*b^2 + // we have + // i^2 = (2*a)^((1 + (|p|-5)/4)*2) + // = (2*a)^((p-1)/2) + // = -1; + // so if we set + // x := a*b*(i-1), + // then + // x^2 = a^2 * b^2 * (i^2 - 2*i + 1) + // = a^2 * b^2 * (-2*i) + // = a*(-i)*(2*a*b^2) + // = a*(-i)*i + // = a. + // + // (This is due to A.O.L. Atkin, + // , + // November 1992.) + + // t := 2*a + if (!bn_mod_lshift1_consttime(t, A, p, ctx)) { + goto end; + } + + // b := (2*a)^((|p|-5)/8) + if (!BN_rshift(q, p, 3)) { + goto end; + } + q->neg = 0; + if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) { + goto end; + } + + // y := b^2 + if (!BN_mod_sqr(y, b, p, ctx)) { + goto end; + } + + // t := (2*a)*b^2 - 1 + if (!BN_mod_mul(t, t, y, p, ctx) || + !BN_sub_word(t, 1)) { + goto end; + } + + // x = a*b*t + if (!BN_mod_mul(x, A, b, p, ctx) || + !BN_mod_mul(x, x, t, p, ctx)) { + goto end; + } + + if (!BN_copy(ret, x)) { + goto end; + } + err = 0; + goto vrfy; + } + + // e > 2, so we really have to use the Tonelli/Shanks algorithm. + // First, find some y that is not a square. + if (!BN_copy(q, p)) { + goto end; // use 'q' as temp + } + q->neg = 0; + i = 2; + do { + // For efficiency, try small numbers first; + // if this fails, try random numbers. + if (i < 22) { + if (!BN_set_word(y, i)) { + goto end; + } + } else { + if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) { + goto end; + } + if (BN_ucmp(y, p) >= 0) { + if (!(p->neg ? BN_add : BN_sub)(y, y, p)) { + goto end; + } + } + // now 0 <= y < |p| + if (BN_is_zero(y)) { + if (!BN_set_word(y, i)) { + goto end; + } + } + } + + r = bn_jacobi(y, q, ctx); // here 'q' is |p| + if (r < -1) { + goto end; + } + if (r == 0) { + // m divides p + OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); + goto end; + } + } while (r == 1 && ++i < 82); + + if (r != -1) { + // Many rounds and still no non-square -- this is more likely + // a bug than just bad luck. + // Even if p is not prime, we should have found some y + // such that r == -1. + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); + goto end; + } + + // Here's our actual 'q': + if (!BN_rshift(q, q, e)) { + goto end; + } + + // Now that we have some non-square, we can find an element + // of order 2^e by computing its q'th power. + if (!BN_mod_exp_mont(y, y, q, p, ctx, NULL)) { + goto end; + } + if (BN_is_one(y)) { + OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME); + goto end; + } + + // Now we know that (if p is indeed prime) there is an integer + // k, 0 <= k < 2^e, such that + // + // a^q * y^k == 1 (mod p). + // + // As a^q is a square and y is not, k must be even. + // q+1 is even, too, so there is an element + // + // X := a^((q+1)/2) * y^(k/2), + // + // and it satisfies + // + // X^2 = a^q * a * y^k + // = a, + // + // so it is the square root that we are looking for. + + // t := (q-1)/2 (note that q is odd) + if (!BN_rshift1(t, q)) { + goto end; + } + + // x := a^((q-1)/2) + if (BN_is_zero(t)) { // special case: p = 2^e + 1 + if (!BN_nnmod(t, A, p, ctx)) { + goto end; + } + if (BN_is_zero(t)) { + // special case: a == 0 (mod p) + BN_zero(ret); + err = 0; + goto end; + } else if (!BN_one(x)) { + goto end; + } + } else { + if (!BN_mod_exp_mont(x, A, t, p, ctx, NULL)) { + goto end; + } + if (BN_is_zero(x)) { + // special case: a == 0 (mod p) + BN_zero(ret); + err = 0; + goto end; + } + } + + // b := a*x^2 (= a^q) + if (!BN_mod_sqr(b, x, p, ctx) || + !BN_mod_mul(b, b, A, p, ctx)) { + goto end; + } + + // x := a*x (= a^((q+1)/2)) + if (!BN_mod_mul(x, x, A, p, ctx)) { + goto end; + } + + while (1) { + // Now b is a^q * y^k for some even k (0 <= k < 2^E + // where E refers to the original value of e, which we + // don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). + // + // We have a*b = x^2, + // y^2^(e-1) = -1, + // b^2^(e-1) = 1. + if (BN_is_one(b)) { + if (!BN_copy(ret, x)) { + goto end; + } + err = 0; + goto vrfy; + } + + // Find the smallest i, 0 < i < e, such that b^(2^i) = 1 + for (i = 1; i < e; i++) { + if (i == 1) { + if (!BN_mod_sqr(t, b, p, ctx)) { + goto end; + } + } else { + if (!BN_mod_mul(t, t, t, p, ctx)) { + goto end; + } + } + if (BN_is_one(t)) { + break; + } + } + // If not found, a is not a square or p is not a prime. + if (i >= e) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + goto end; + } + + // t := y^2^(e - i - 1) + if (!BN_copy(t, y)) { + goto end; + } + for (j = e - i - 1; j > 0; j--) { + if (!BN_mod_sqr(t, t, p, ctx)) { + goto end; + } + } + if (!BN_mod_mul(y, t, t, p, ctx) || + !BN_mod_mul(x, x, t, p, ctx) || + !BN_mod_mul(b, b, y, p, ctx)) { + goto end; + } + + // e decreases each iteration, so this loop will terminate. + assert(i < e); + e = i; + } + +vrfy: + if (!err) { + // Verify the result. The input might have been not a square. + if (!BN_mod_sqr(x, ret, p, ctx)) { + err = 1; + } + + if (!err && 0 != BN_cmp(x, A)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + err = 1; + } + } + +end: + if (err) { + if (ret != in) { + BN_clear_free(ret); + } + ret = NULL; + } + BN_CTX_end(ctx); + return ret; +} + +int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { + BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2; + int ok = 0, last_delta_valid = 0; + + if (in->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(in)) { + BN_zero(out_sqrt); + return 1; + } + + BN_CTX_start(ctx); + if (out_sqrt == in) { + estimate = BN_CTX_get(ctx); + } else { + estimate = out_sqrt; + } + tmp = BN_CTX_get(ctx); + last_delta = BN_CTX_get(ctx); + delta = BN_CTX_get(ctx); + if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // We estimate that the square root of an n-bit number is 2^{n/2}. + if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) { + goto err; + } + + // This is Newton's method for finding a root of the equation |estimate|^2 - + // |in| = 0. + for (;;) { + // |estimate| = 1/2 * (|estimate| + |in|/|estimate|) + if (!BN_div(tmp, NULL, in, estimate, ctx) || + !BN_add(tmp, tmp, estimate) || + !BN_rshift1(estimate, tmp) || + // |tmp| = |estimate|^2 + !BN_sqr(tmp, estimate, ctx) || + // |delta| = |in| - |tmp| + !BN_sub(delta, in, tmp)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + delta->neg = 0; + // The difference between |in| and |estimate| squared is required to always + // decrease. This ensures that the loop always terminates, but I don't have + // a proof that it always finds the square root for a given square. + if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) { + break; + } + + last_delta_valid = 1; + + tmp2 = last_delta; + last_delta = delta; + delta = tmp2; + } + + if (BN_cmp(tmp, in) != 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + goto err; + } + + ok = 1; + +err: + if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { + ok = 0; + } + BN_CTX_end(ctx); + return ok; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S new file mode 100644 index 00000000..3d9be856 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S @@ -0,0 +1,1543 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel +@ of Linaro. Permission to use under GPL terms is granted. +@ ==================================================================== + +@ Bit-sliced AES for ARM NEON +@ +@ February 2012. +@ +@ This implementation is direct adaptation of bsaes-x86_64 module for +@ ARM NEON. Except that this module is endian-neutral [in sense that +@ it can be compiled for either endianness] by courtesy of vld1.8's +@ neutrality. Initial version doesn't implement interface to OpenSSL, +@ only low-level primitives and unsupported entry points, just enough +@ to collect performance results, which for Cortex-A8 core are: +@ +@ encrypt 19.5 cycles per byte processed with 128-bit key +@ decrypt 22.1 cycles per byte processed with 128-bit key +@ key conv. 440 cycles per 128-bit key/0.18 of 8x block +@ +@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7, +@ which is [much] worse than anticipated (for further details see +@ http://www.openssl.org/~appro/Snapdragon-S4.html). +@ +@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code +@ manages in 20.0 cycles]. +@ +@ When comparing to x86_64 results keep in mind that NEON unit is +@ [mostly] single-issue and thus can't [fully] benefit from +@ instruction-level parallelism. And when comparing to aes-armv4 +@ results keep in mind key schedule conversion overhead (see +@ bsaes-x86_64.pl for further details)... +@ +@ + +@ April-August 2013 +@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard. + +#ifndef __KERNEL__ +# include + +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +# define VFP_ABI_FRAME 0x40 +#else +# define VFP_ABI_PUSH +# define VFP_ABI_POP +# define VFP_ABI_FRAME 0 +# define BSAES_ASM_EXTENDED_KEY +# define XTS_CHAIN_TWEAK +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +#endif + +#ifdef __thumb__ +# define adrl adr +#endif + +#if __ARM_MAX_ARCH__>=7 + + + +.text +.syntax unified @ ARMv7-capable assembler is expected to handle this +#if defined(__thumb2__) && !defined(__APPLE__) +.thumb +#else +.code 32 +# undef __thumb2__ +#endif + +#ifdef __thumb2__ +.thumb_func _bsaes_decrypt8 +#endif +.align 4 +_bsaes_decrypt8: + adr r6,. + vldmia r4!, {q9} @ round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,LM0ISR +#else + add r6,r6,#LM0ISR-_bsaes_decrypt8 +#endif + + vldmia r6!, {q8} @ LM0ISR + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 + vmov.i8 q8,#0x55 @ compose LBS0 + vmov.i8 q9,#0x33 @ compose LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b Ldec_sbox +.align 4 +Ldec_loop: + vldmia r4!, {q8,q9,q10,q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +Ldec_sbox: + veor q1, q1, q4 + veor q3, q3, q4 + + veor q4, q4, q7 + veor q1, q1, q6 + veor q2, q2, q7 + veor q6, q6, q4 + + veor q0, q0, q1 + veor q2, q2, q5 + veor q7, q7, q6 + veor q3, q3, q0 + veor q5, q5, q0 + veor q1, q1, q3 + veor q11, q3, q0 + veor q10, q7, q4 + veor q9, q1, q6 + veor q13, q4, q0 + vmov q8, q10 + veor q12, q5, q2 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q6, q2 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q3, q7 + veor q12, q1, q5 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q4, q6 + veor q9, q9, q14 + vand q13, q0, q2 + vand q14, q7, q1 + vorr q15, q3, q5 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q5, q2 + veor q8, q1, q6 + veor q10, q15, q14 + vand q10, q10, q5 + veor q5, q5, q1 + vand q11, q1, q15 + vand q5, q5, q14 + veor q1, q11, q10 + veor q5, q5, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q2 + veor q12, q12, q8 + veor q2, q2, q6 + vand q8, q8, q15 + vand q6, q6, q13 + vand q12, q12, q14 + vand q2, q2, q9 + veor q8, q8, q12 + veor q2, q2, q6 + veor q12, q12, q11 + veor q6, q6, q10 + veor q5, q5, q12 + veor q2, q2, q12 + veor q1, q1, q8 + veor q6, q6, q8 + + veor q12, q3, q0 + veor q8, q7, q4 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q4 + vand q8, q8, q15 + vand q4, q4, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q4 + veor q12, q12, q11 + veor q4, q4, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q3 + veor q3, q3, q7 + vand q11, q7, q15 + vand q3, q3, q14 + veor q7, q11, q10 + veor q3, q3, q11 + veor q3, q3, q12 + veor q0, q0, q12 + veor q7, q7, q8 + veor q4, q4, q8 + veor q1, q1, q7 + veor q6, q6, q5 + + veor q4, q4, q1 + veor q2, q2, q7 + veor q5, q5, q7 + veor q4, q4, q2 + veor q7, q7, q0 + veor q4, q4, q5 + veor q3, q3, q6 + veor q6, q6, q1 + veor q3, q3, q4 + + veor q4, q4, q0 + veor q7, q7, q3 + subs r5,r5,#1 + bcc Ldec_done + @ multiplication by 0x05-0x00-0x04-0x00 + vext.8 q8, q0, q0, #8 + vext.8 q14, q3, q3, #8 + vext.8 q15, q5, q5, #8 + veor q8, q8, q0 + vext.8 q9, q1, q1, #8 + veor q14, q14, q3 + vext.8 q10, q6, q6, #8 + veor q15, q15, q5 + vext.8 q11, q4, q4, #8 + veor q9, q9, q1 + vext.8 q12, q2, q2, #8 + veor q10, q10, q6 + vext.8 q13, q7, q7, #8 + veor q11, q11, q4 + veor q12, q12, q2 + veor q13, q13, q7 + + veor q0, q0, q14 + veor q1, q1, q14 + veor q6, q6, q8 + veor q2, q2, q10 + veor q4, q4, q9 + veor q1, q1, q15 + veor q6, q6, q15 + veor q2, q2, q14 + veor q7, q7, q11 + veor q4, q4, q14 + veor q3, q3, q12 + veor q2, q2, q15 + veor q7, q7, q15 + veor q5, q5, q13 + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q6, q6, #12 + veor q1, q1, q9 + vext.8 q11, q4, q4, #12 + veor q6, q6, q10 + vext.8 q12, q2, q2, #12 + veor q4, q4, q11 + vext.8 q13, q7, q7, #12 + veor q2, q2, q12 + vext.8 q14, q3, q3, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q3, q3, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q2 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q2, q2, #8 + veor q12, q12, q4 + vext.8 q9, q7, q7, #8 + veor q15, q15, q3 + vext.8 q2, q4, q4, #8 + veor q11, q11, q6 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q4, q3, q3, #8 + veor q11, q11, q5 + vext.8 q3, q6, q6, #8 + veor q5, q9, q13 + veor q11, q11, q2 + veor q7, q7, q15 + veor q6, q4, q14 + veor q4, q8, q12 + veor q2, q3, q10 + vmov q3, q11 + @ vmov q5, q9 + vldmia r6, {q12} @ LISR + ite eq @ Thumb2 thing, sanity check in ARM + addeq r6,r6,#0x10 + bne Ldec_loop + vldmia r6, {q12} @ LISRM0 + b Ldec_loop +.align 4 +Ldec_done: + vmov.i8 q8,#0x55 @ compose LBS0 + vmov.i8 q9,#0x33 @ compose LBS1 + vshr.u64 q10, q3, #1 + vshr.u64 q11, q2, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q4 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q4, q4, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q2, #2 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q3, q3, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q4 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q4, q4, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q4, #4 + vshr.u64 q11, q6, #4 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q4, q4, q10 + veor q6, q6, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q6, q6, q8 + veor q4, q4, q8 + veor q2, q2, q8 + veor q7, q7, q8 + veor q3, q3, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr + + + +.align 6 +_bsaes_const: +LM0ISR:@ InvShiftRows constants +.quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +LISR: +.quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +LISRM0: +.quad 0x01040b0e0205080f, 0x0306090c00070a0d +LM0SR:@ ShiftRows constants +.quad 0x0a0e02060f03070b, 0x0004080c05090d01 +LSR: +.quad 0x0504070600030201, 0x0f0e0d0c0a09080b +LSRM0: +.quad 0x0304090e00050a0f, 0x01060b0c0207080d +LM0: +.quad 0x02060a0e03070b0f, 0x0004080c0105090d +LREVM0SR: +.quad 0x090d01050c000408, 0x03070b0f060a0e02 +.byte 66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 6 + + +#ifdef __thumb2__ +.thumb_func _bsaes_encrypt8 +#endif +.align 4 +_bsaes_encrypt8: + adr r6,. + vldmia r4!, {q9} @ round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,LM0SR +#else + sub r6,r6,#_bsaes_encrypt8-LM0SR +#endif + + vldmia r6!, {q8} @ LM0SR +_bsaes_encrypt8_alt: + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 +_bsaes_encrypt8_bitslice: + vmov.i8 q8,#0x55 @ compose LBS0 + vmov.i8 q9,#0x33 @ compose LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b Lenc_sbox +.align 4 +Lenc_loop: + vldmia r4!, {q8,q9,q10,q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +Lenc_sbox: + veor q2, q2, q1 + veor q5, q5, q6 + veor q3, q3, q0 + veor q6, q6, q2 + veor q5, q5, q0 + + veor q6, q6, q3 + veor q3, q3, q7 + veor q7, q7, q5 + veor q3, q3, q4 + veor q4, q4, q5 + + veor q2, q2, q7 + veor q3, q3, q1 + veor q1, q1, q5 + veor q11, q7, q4 + veor q10, q1, q2 + veor q9, q5, q3 + veor q13, q2, q4 + vmov q8, q10 + veor q12, q6, q0 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q3, q0 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q7, q1 + veor q12, q5, q6 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q2, q3 + veor q9, q9, q14 + vand q13, q4, q0 + vand q14, q1, q5 + vorr q15, q7, q6 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q6, q0 + veor q8, q5, q3 + veor q10, q15, q14 + vand q10, q10, q6 + veor q6, q6, q5 + vand q11, q5, q15 + vand q6, q6, q14 + veor q5, q11, q10 + veor q6, q6, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q3 + vand q8, q8, q15 + vand q3, q3, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q3 + veor q12, q12, q11 + veor q3, q3, q10 + veor q6, q6, q12 + veor q0, q0, q12 + veor q5, q5, q8 + veor q3, q3, q8 + + veor q12, q7, q4 + veor q8, q1, q2 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q4 + veor q12, q12, q8 + veor q4, q4, q2 + vand q8, q8, q15 + vand q2, q2, q13 + vand q12, q12, q14 + vand q4, q4, q9 + veor q8, q8, q12 + veor q4, q4, q2 + veor q12, q12, q11 + veor q2, q2, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q7 + veor q7, q7, q1 + vand q11, q1, q15 + vand q7, q7, q14 + veor q1, q11, q10 + veor q7, q7, q11 + veor q7, q7, q12 + veor q4, q4, q12 + veor q1, q1, q8 + veor q2, q2, q8 + veor q7, q7, q0 + veor q1, q1, q6 + veor q6, q6, q0 + veor q4, q4, q7 + veor q0, q0, q1 + + veor q1, q1, q5 + veor q5, q5, q2 + veor q2, q2, q3 + veor q3, q3, q5 + veor q4, q4, q5 + + veor q6, q6, q3 + subs r5,r5,#1 + bcc Lenc_done + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q4, q4, #12 + veor q1, q1, q9 + vext.8 q11, q6, q6, #12 + veor q4, q4, q10 + vext.8 q12, q3, q3, #12 + veor q6, q6, q11 + vext.8 q13, q7, q7, #12 + veor q3, q3, q12 + vext.8 q14, q2, q2, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q2, q2, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q3 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q3, q3, #8 + veor q12, q12, q6 + vext.8 q9, q7, q7, #8 + veor q15, q15, q2 + vext.8 q3, q6, q6, #8 + veor q11, q11, q4 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q6, q2, q2, #8 + veor q11, q11, q5 + vext.8 q2, q4, q4, #8 + veor q5, q9, q13 + veor q4, q8, q12 + veor q3, q3, q11 + veor q7, q7, q15 + veor q6, q6, q14 + @ vmov q4, q8 + veor q2, q2, q10 + @ vmov q5, q9 + vldmia r6, {q12} @ LSR + ite eq @ Thumb2 thing, samity check in ARM + addeq r6,r6,#0x10 + bne Lenc_loop + vldmia r6, {q12} @ LSRM0 + b Lenc_loop +.align 4 +Lenc_done: + vmov.i8 q8,#0x55 @ compose LBS0 + vmov.i8 q9,#0x33 @ compose LBS1 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q3, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q3, q3, q11 + vshr.u64 q10, q4, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q6 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q6, q6, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q4, q4, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q3, #2 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q3, q3, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q6 + veor q11, q11, q4 + vand q10, q10, q9 + vand q11, q11, q9 + veor q6, q6, q10 + vshl.u64 q10, q10, #2 + veor q4, q4, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q6, #4 + vshr.u64 q11, q4, #4 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q4, q4, q8 + veor q6, q6, q8 + veor q3, q3, q8 + veor q7, q7, q8 + veor q2, q2, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr + +#ifdef __thumb2__ +.thumb_func _bsaes_key_convert +#endif +.align 4 +_bsaes_key_convert: + adr r6,. + vld1.8 {q7}, [r4]! @ load round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,LM0 +#else + sub r6,r6,#_bsaes_key_convert-LM0 +#endif + vld1.8 {q15}, [r4]! @ load round 1 key + + vmov.i8 q8, #0x01 @ bit masks + vmov.i8 q9, #0x02 + vmov.i8 q10, #0x04 + vmov.i8 q11, #0x08 + vmov.i8 q12, #0x10 + vmov.i8 q13, #0x20 + vldmia r6, {q14} @ LM0 + +#ifdef __ARMEL__ + vrev32.8 q7, q7 + vrev32.8 q15, q15 +#endif + sub r5,r5,#1 + vstmia r12!, {q7} @ save round 0 key + b Lkey_loop + +.align 4 +Lkey_loop: + vtbl.8 d14,{q15},d28 + vtbl.8 d15,{q15},d29 + vmov.i8 q6, #0x40 + vmov.i8 q15, #0x80 + + vtst.8 q0, q7, q8 + vtst.8 q1, q7, q9 + vtst.8 q2, q7, q10 + vtst.8 q3, q7, q11 + vtst.8 q4, q7, q12 + vtst.8 q5, q7, q13 + vtst.8 q6, q7, q6 + vtst.8 q7, q7, q15 + vld1.8 {q15}, [r4]! @ load next round key + vmvn q0, q0 @ "pnot" + vmvn q1, q1 + vmvn q5, q5 + vmvn q6, q6 +#ifdef __ARMEL__ + vrev32.8 q15, q15 +#endif + subs r5,r5,#1 + vstmia r12!,{q0,q1,q2,q3,q4,q5,q6,q7} @ write bit-sliced round key + bne Lkey_loop + + vmov.i8 q7,#0x63 @ compose L63 + @ don't save last round key + bx lr + +.globl _bsaes_cbc_encrypt +.private_extern _bsaes_cbc_encrypt +#ifdef __thumb2__ +.thumb_func _bsaes_cbc_encrypt +#endif +.align 5 +_bsaes_cbc_encrypt: + @ In OpenSSL, this function had a fallback to aes_nohw_cbc_encrypt for + @ short inputs. We patch this out, using bsaes for all input sizes. + + @ it is up to the caller to make sure we are called with enc == 0 + + mov ip, sp + stmdb sp!, {r4,r5,r6,r7,r8,r9,r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ IV is 1st arg on the stack + mov r2, r2, lsr#4 @ len in 16 byte blocks + sub sp, #0x10 @ scratch space to carry over the IV + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ sifze of bit-slices key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + vldmia sp, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia sp, {q7} +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, r3, #248 + vldmia r4, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia r4, {q7} + +.align 2 + +#endif + + vld1.8 {q15}, [r8] @ load IV + b Lcbc_dec_loop + +.align 4 +Lcbc_dec_loop: + subs r2, r2, #0x8 + bmi Lcbc_dec_loop_finish + + vld1.8 {q0,q1}, [r0]! @ load input + vld1.8 {q2,q3}, [r0]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + vld1.8 {q4,q5}, [r0]! + mov r5, r10 + vld1.8 {q6,q7}, [r0] + sub r0, r0, #0x60 + vstmia r9, {q15} @ put aside IV + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q14,q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + veor q5, q5, q14 + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + vst1.8 {q5}, [r1]! + + b Lcbc_dec_loop + +Lcbc_dec_loop_finish: + adds r2, r2, #8 + beq Lcbc_dec_done + + @ Set up most parameters for the _bsaes_decrypt8 call. +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + mov r5, r10 + vstmia r9, {q15} @ put aside IV + + vld1.8 {q0}, [r0]! @ load input + cmp r2, #2 + blo Lcbc_dec_one + vld1.8 {q1}, [r0]! + beq Lcbc_dec_two + vld1.8 {q2}, [r0]! + cmp r2, #4 + blo Lcbc_dec_three + vld1.8 {q3}, [r0]! + beq Lcbc_dec_four + vld1.8 {q4}, [r0]! + cmp r2, #6 + blo Lcbc_dec_five + vld1.8 {q5}, [r0]! + beq Lcbc_dec_six + vld1.8 {q6}, [r0]! + sub r0, r0, #0x70 + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + b Lcbc_dec_done +.align 4 +Lcbc_dec_six: + sub r0, r0, #0x60 + bl _bsaes_decrypt8 + vldmia r9,{q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + b Lcbc_dec_done +.align 4 +Lcbc_dec_five: + sub r0, r0, #0x50 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0,q1}, [r1]! @ write output + veor q2, q2, q11 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + b Lcbc_dec_done +.align 4 +Lcbc_dec_four: + sub r0, r0, #0x40 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + b Lcbc_dec_done +.align 4 +Lcbc_dec_three: + sub r0, r0, #0x30 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + b Lcbc_dec_done +.align 4 +Lcbc_dec_two: + sub r0, r0, #0x20 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! @ reload input + veor q1, q1, q8 + vst1.8 {q0,q1}, [r1]! @ write output + b Lcbc_dec_done +.align 4 +Lcbc_dec_one: + sub r0, r0, #0x10 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q15}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vst1.8 {q0}, [r1]! @ write output + +Lcbc_dec_done: +#ifndef BSAES_ASM_EXTENDED_KEY + vmov.i32 q0, #0 + vmov.i32 q1, #0 +Lcbc_dec_bzero:@ wipe key schedule [if any] + vstmia sp!, {q0,q1} + cmp sp, r9 + bne Lcbc_dec_bzero +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + vst1.8 {q15}, [r8] @ return IV + VFP_ABI_POP + ldmia sp!, {r4,r5,r6,r7,r8,r9,r10, pc} + +.globl _bsaes_ctr32_encrypt_blocks +.private_extern _bsaes_ctr32_encrypt_blocks +#ifdef __thumb2__ +.thumb_func _bsaes_ctr32_encrypt_blocks +#endif +.align 5 +_bsaes_ctr32_encrypt_blocks: + @ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this + @ out to retain a constant-time implementation. + mov ip, sp + stmdb sp!, {r4,r5,r6,r7,r8,r9,r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ ctr is 1st arg on the stack + sub sp, sp, #0x10 @ scratch space to carry over the ctr + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ size of bit-sliced key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + + vld1.8 {q0}, [r8] @ load counter +#ifdef __APPLE__ + mov r8, #:lower16:(LREVM0SR-LM0) + add r8, r6, r8 +#else + add r8, r6, #LREVM0SR-LM0 @ borrow r8 +#endif + vldmia sp, {q4} @ load round0 key +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + +.align 2 + add r12, r3, #248 + vld1.8 {q0}, [r8] @ load counter + adrl r8, LREVM0SR @ borrow r8 + vldmia r12, {q4} @ load round0 key + sub sp, #0x10 @ place for adjusted round0 key +#endif + + vmov.i32 q8,#1 @ compose 1<<96 + veor q9,q9,q9 + vrev32.8 q0,q0 + vext.8 q8,q9,q8,#4 + vrev32.8 q4,q4 + vadd.u32 q9,q8,q8 @ compose 2<<96 + vstmia sp, {q4} @ save adjusted round0 key + b Lctr_enc_loop + +.align 4 +Lctr_enc_loop: + vadd.u32 q10, q8, q9 @ compose 3<<96 + vadd.u32 q1, q0, q8 @ +1 + vadd.u32 q2, q0, q9 @ +2 + vadd.u32 q3, q0, q10 @ +3 + vadd.u32 q4, q1, q10 + vadd.u32 q5, q2, q10 + vadd.u32 q6, q3, q10 + vadd.u32 q7, q4, q10 + vadd.u32 q10, q5, q10 @ next counter + + @ Borrow prologue from _bsaes_encrypt8 to use the opportunity + @ to flip byte order in 32-bit counter + + vldmia sp, {q9} @ load round0 key +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x10 @ pass next round key +#else + add r4, r3, #264 +#endif + vldmia r8, {q8} @ LREVM0SR + mov r5, r10 @ pass rounds + vstmia r9, {q10} @ save next counter +#ifdef __APPLE__ + mov r6, #:lower16:(LREVM0SR-LSR) + sub r6, r8, r6 +#else + sub r6, r8, #LREVM0SR-LSR @ pass constants +#endif + + bl _bsaes_encrypt8_alt + + subs r2, r2, #8 + blo Lctr_enc_loop_done + + vld1.8 {q8,q9}, [r0]! @ load input + vld1.8 {q10,q11}, [r0]! + veor q0, q8 + veor q1, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q10 + veor q6, q11 + vld1.8 {q14,q15}, [r0]! + veor q3, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q7, q13 + veor q2, q14 + vst1.8 {q4}, [r1]! + veor q5, q15 + vst1.8 {q6}, [r1]! + vmov.i32 q8, #1 @ compose 1<<96 + vst1.8 {q3}, [r1]! + veor q9, q9, q9 + vst1.8 {q7}, [r1]! + vext.8 q8, q9, q8, #4 + vst1.8 {q2}, [r1]! + vadd.u32 q9,q8,q8 @ compose 2<<96 + vst1.8 {q5}, [r1]! + vldmia r9, {q0} @ load counter + + bne Lctr_enc_loop + b Lctr_enc_done + +.align 4 +Lctr_enc_loop_done: + add r2, r2, #8 + vld1.8 {q8}, [r0]! @ load input + veor q0, q8 + vst1.8 {q0}, [r1]! @ write output + cmp r2, #2 + blo Lctr_enc_done + vld1.8 {q9}, [r0]! + veor q1, q9 + vst1.8 {q1}, [r1]! + beq Lctr_enc_done + vld1.8 {q10}, [r0]! + veor q4, q10 + vst1.8 {q4}, [r1]! + cmp r2, #4 + blo Lctr_enc_done + vld1.8 {q11}, [r0]! + veor q6, q11 + vst1.8 {q6}, [r1]! + beq Lctr_enc_done + vld1.8 {q12}, [r0]! + veor q3, q12 + vst1.8 {q3}, [r1]! + cmp r2, #6 + blo Lctr_enc_done + vld1.8 {q13}, [r0]! + veor q7, q13 + vst1.8 {q7}, [r1]! + beq Lctr_enc_done + vld1.8 {q14}, [r0] + veor q2, q14 + vst1.8 {q2}, [r1]! + +Lctr_enc_done: + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifndef BSAES_ASM_EXTENDED_KEY +Lctr_enc_bzero:@ wipe key schedule [if any] + vstmia sp!, {q0,q1} + cmp sp, r9 + bne Lctr_enc_bzero +#else + vstmia sp, {q0,q1} +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + VFP_ABI_POP + ldmia sp!, {r4,r5,r6,r7,r8,r9,r10, pc} @ return + + @ OpenSSL contains aes_nohw_* fallback code here. We patch this + @ out to retain a constant-time implementation. + +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S new file mode 100644 index 00000000..52bef0c2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S @@ -0,0 +1,1536 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel +@ of Linaro. Permission to use under GPL terms is granted. +@ ==================================================================== + +@ Bit-sliced AES for ARM NEON +@ +@ February 2012. +@ +@ This implementation is direct adaptation of bsaes-x86_64 module for +@ ARM NEON. Except that this module is endian-neutral [in sense that +@ it can be compiled for either endianness] by courtesy of vld1.8's +@ neutrality. Initial version doesn't implement interface to OpenSSL, +@ only low-level primitives and unsupported entry points, just enough +@ to collect performance results, which for Cortex-A8 core are: +@ +@ encrypt 19.5 cycles per byte processed with 128-bit key +@ decrypt 22.1 cycles per byte processed with 128-bit key +@ key conv. 440 cycles per 128-bit key/0.18 of 8x block +@ +@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7, +@ which is [much] worse than anticipated (for further details see +@ http://www.openssl.org/~appro/Snapdragon-S4.html). +@ +@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code +@ manages in 20.0 cycles]. +@ +@ When comparing to x86_64 results keep in mind that NEON unit is +@ [mostly] single-issue and thus can't [fully] benefit from +@ instruction-level parallelism. And when comparing to aes-armv4 +@ results keep in mind key schedule conversion overhead (see +@ bsaes-x86_64.pl for further details)... +@ +@ + +@ April-August 2013 +@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard. + +#ifndef __KERNEL__ +# include + +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +# define VFP_ABI_FRAME 0x40 +#else +# define VFP_ABI_PUSH +# define VFP_ABI_POP +# define VFP_ABI_FRAME 0 +# define BSAES_ASM_EXTENDED_KEY +# define XTS_CHAIN_TWEAK +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +#endif + +#ifdef __thumb__ +# define adrl adr +#endif + +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.text +.syntax unified @ ARMv7-capable assembler is expected to handle this +#if defined(__thumb2__) && !defined(__APPLE__) +.thumb +#else +.code 32 +# undef __thumb2__ +#endif + +.type _bsaes_decrypt8,%function +.align 4 +_bsaes_decrypt8: + adr r6,. + vldmia r4!, {q9} @ round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,.LM0ISR +#else + add r6,r6,#.LM0ISR-_bsaes_decrypt8 +#endif + + vldmia r6!, {q8} @ .LM0ISR + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b .Ldec_sbox +.align 4 +.Ldec_loop: + vldmia r4!, {q8,q9,q10,q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +.Ldec_sbox: + veor q1, q1, q4 + veor q3, q3, q4 + + veor q4, q4, q7 + veor q1, q1, q6 + veor q2, q2, q7 + veor q6, q6, q4 + + veor q0, q0, q1 + veor q2, q2, q5 + veor q7, q7, q6 + veor q3, q3, q0 + veor q5, q5, q0 + veor q1, q1, q3 + veor q11, q3, q0 + veor q10, q7, q4 + veor q9, q1, q6 + veor q13, q4, q0 + vmov q8, q10 + veor q12, q5, q2 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q6, q2 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q3, q7 + veor q12, q1, q5 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q4, q6 + veor q9, q9, q14 + vand q13, q0, q2 + vand q14, q7, q1 + vorr q15, q3, q5 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q5, q2 + veor q8, q1, q6 + veor q10, q15, q14 + vand q10, q10, q5 + veor q5, q5, q1 + vand q11, q1, q15 + vand q5, q5, q14 + veor q1, q11, q10 + veor q5, q5, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q2 + veor q12, q12, q8 + veor q2, q2, q6 + vand q8, q8, q15 + vand q6, q6, q13 + vand q12, q12, q14 + vand q2, q2, q9 + veor q8, q8, q12 + veor q2, q2, q6 + veor q12, q12, q11 + veor q6, q6, q10 + veor q5, q5, q12 + veor q2, q2, q12 + veor q1, q1, q8 + veor q6, q6, q8 + + veor q12, q3, q0 + veor q8, q7, q4 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q4 + vand q8, q8, q15 + vand q4, q4, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q4 + veor q12, q12, q11 + veor q4, q4, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q3 + veor q3, q3, q7 + vand q11, q7, q15 + vand q3, q3, q14 + veor q7, q11, q10 + veor q3, q3, q11 + veor q3, q3, q12 + veor q0, q0, q12 + veor q7, q7, q8 + veor q4, q4, q8 + veor q1, q1, q7 + veor q6, q6, q5 + + veor q4, q4, q1 + veor q2, q2, q7 + veor q5, q5, q7 + veor q4, q4, q2 + veor q7, q7, q0 + veor q4, q4, q5 + veor q3, q3, q6 + veor q6, q6, q1 + veor q3, q3, q4 + + veor q4, q4, q0 + veor q7, q7, q3 + subs r5,r5,#1 + bcc .Ldec_done + @ multiplication by 0x05-0x00-0x04-0x00 + vext.8 q8, q0, q0, #8 + vext.8 q14, q3, q3, #8 + vext.8 q15, q5, q5, #8 + veor q8, q8, q0 + vext.8 q9, q1, q1, #8 + veor q14, q14, q3 + vext.8 q10, q6, q6, #8 + veor q15, q15, q5 + vext.8 q11, q4, q4, #8 + veor q9, q9, q1 + vext.8 q12, q2, q2, #8 + veor q10, q10, q6 + vext.8 q13, q7, q7, #8 + veor q11, q11, q4 + veor q12, q12, q2 + veor q13, q13, q7 + + veor q0, q0, q14 + veor q1, q1, q14 + veor q6, q6, q8 + veor q2, q2, q10 + veor q4, q4, q9 + veor q1, q1, q15 + veor q6, q6, q15 + veor q2, q2, q14 + veor q7, q7, q11 + veor q4, q4, q14 + veor q3, q3, q12 + veor q2, q2, q15 + veor q7, q7, q15 + veor q5, q5, q13 + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q6, q6, #12 + veor q1, q1, q9 + vext.8 q11, q4, q4, #12 + veor q6, q6, q10 + vext.8 q12, q2, q2, #12 + veor q4, q4, q11 + vext.8 q13, q7, q7, #12 + veor q2, q2, q12 + vext.8 q14, q3, q3, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q3, q3, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q2 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q2, q2, #8 + veor q12, q12, q4 + vext.8 q9, q7, q7, #8 + veor q15, q15, q3 + vext.8 q2, q4, q4, #8 + veor q11, q11, q6 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q4, q3, q3, #8 + veor q11, q11, q5 + vext.8 q3, q6, q6, #8 + veor q5, q9, q13 + veor q11, q11, q2 + veor q7, q7, q15 + veor q6, q4, q14 + veor q4, q8, q12 + veor q2, q3, q10 + vmov q3, q11 + @ vmov q5, q9 + vldmia r6, {q12} @ .LISR + ite eq @ Thumb2 thing, sanity check in ARM + addeq r6,r6,#0x10 + bne .Ldec_loop + vldmia r6, {q12} @ .LISRM0 + b .Ldec_loop +.align 4 +.Ldec_done: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q3, #1 + vshr.u64 q11, q2, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q4 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q4, q4, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q2, #2 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q3, q3, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q4 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q4, q4, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q4, #4 + vshr.u64 q11, q6, #4 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q4, q4, q10 + veor q6, q6, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q6, q6, q8 + veor q4, q4, q8 + veor q2, q2, q8 + veor q7, q7, q8 + veor q3, q3, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr +.size _bsaes_decrypt8,.-_bsaes_decrypt8 + +.type _bsaes_const,%object +.align 6 +_bsaes_const: +.LM0ISR:@ InvShiftRows constants +.quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +.LISR: +.quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +.LISRM0: +.quad 0x01040b0e0205080f, 0x0306090c00070a0d +.LM0SR:@ ShiftRows constants +.quad 0x0a0e02060f03070b, 0x0004080c05090d01 +.LSR: +.quad 0x0504070600030201, 0x0f0e0d0c0a09080b +.LSRM0: +.quad 0x0304090e00050a0f, 0x01060b0c0207080d +.LM0: +.quad 0x02060a0e03070b0f, 0x0004080c0105090d +.LREVM0SR: +.quad 0x090d01050c000408, 0x03070b0f060a0e02 +.byte 66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 6 +.size _bsaes_const,.-_bsaes_const + +.type _bsaes_encrypt8,%function +.align 4 +_bsaes_encrypt8: + adr r6,. + vldmia r4!, {q9} @ round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,.LM0SR +#else + sub r6,r6,#_bsaes_encrypt8-.LM0SR +#endif + + vldmia r6!, {q8} @ .LM0SR +_bsaes_encrypt8_alt: + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 +_bsaes_encrypt8_bitslice: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b .Lenc_sbox +.align 4 +.Lenc_loop: + vldmia r4!, {q8,q9,q10,q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +.Lenc_sbox: + veor q2, q2, q1 + veor q5, q5, q6 + veor q3, q3, q0 + veor q6, q6, q2 + veor q5, q5, q0 + + veor q6, q6, q3 + veor q3, q3, q7 + veor q7, q7, q5 + veor q3, q3, q4 + veor q4, q4, q5 + + veor q2, q2, q7 + veor q3, q3, q1 + veor q1, q1, q5 + veor q11, q7, q4 + veor q10, q1, q2 + veor q9, q5, q3 + veor q13, q2, q4 + vmov q8, q10 + veor q12, q6, q0 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q3, q0 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q7, q1 + veor q12, q5, q6 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q2, q3 + veor q9, q9, q14 + vand q13, q4, q0 + vand q14, q1, q5 + vorr q15, q7, q6 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q6, q0 + veor q8, q5, q3 + veor q10, q15, q14 + vand q10, q10, q6 + veor q6, q6, q5 + vand q11, q5, q15 + vand q6, q6, q14 + veor q5, q11, q10 + veor q6, q6, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q3 + vand q8, q8, q15 + vand q3, q3, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q3 + veor q12, q12, q11 + veor q3, q3, q10 + veor q6, q6, q12 + veor q0, q0, q12 + veor q5, q5, q8 + veor q3, q3, q8 + + veor q12, q7, q4 + veor q8, q1, q2 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q4 + veor q12, q12, q8 + veor q4, q4, q2 + vand q8, q8, q15 + vand q2, q2, q13 + vand q12, q12, q14 + vand q4, q4, q9 + veor q8, q8, q12 + veor q4, q4, q2 + veor q12, q12, q11 + veor q2, q2, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q7 + veor q7, q7, q1 + vand q11, q1, q15 + vand q7, q7, q14 + veor q1, q11, q10 + veor q7, q7, q11 + veor q7, q7, q12 + veor q4, q4, q12 + veor q1, q1, q8 + veor q2, q2, q8 + veor q7, q7, q0 + veor q1, q1, q6 + veor q6, q6, q0 + veor q4, q4, q7 + veor q0, q0, q1 + + veor q1, q1, q5 + veor q5, q5, q2 + veor q2, q2, q3 + veor q3, q3, q5 + veor q4, q4, q5 + + veor q6, q6, q3 + subs r5,r5,#1 + bcc .Lenc_done + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q4, q4, #12 + veor q1, q1, q9 + vext.8 q11, q6, q6, #12 + veor q4, q4, q10 + vext.8 q12, q3, q3, #12 + veor q6, q6, q11 + vext.8 q13, q7, q7, #12 + veor q3, q3, q12 + vext.8 q14, q2, q2, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q2, q2, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q3 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q3, q3, #8 + veor q12, q12, q6 + vext.8 q9, q7, q7, #8 + veor q15, q15, q2 + vext.8 q3, q6, q6, #8 + veor q11, q11, q4 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q6, q2, q2, #8 + veor q11, q11, q5 + vext.8 q2, q4, q4, #8 + veor q5, q9, q13 + veor q4, q8, q12 + veor q3, q3, q11 + veor q7, q7, q15 + veor q6, q6, q14 + @ vmov q4, q8 + veor q2, q2, q10 + @ vmov q5, q9 + vldmia r6, {q12} @ .LSR + ite eq @ Thumb2 thing, samity check in ARM + addeq r6,r6,#0x10 + bne .Lenc_loop + vldmia r6, {q12} @ .LSRM0 + b .Lenc_loop +.align 4 +.Lenc_done: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q3, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q3, q3, q11 + vshr.u64 q10, q4, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q6 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q6, q6, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q4, q4, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q3, #2 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q3, q3, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q6 + veor q11, q11, q4 + vand q10, q10, q9 + vand q11, q11, q9 + veor q6, q6, q10 + vshl.u64 q10, q10, #2 + veor q4, q4, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q6, #4 + vshr.u64 q11, q4, #4 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q4, q4, q8 + veor q6, q6, q8 + veor q3, q3, q8 + veor q7, q7, q8 + veor q2, q2, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr +.size _bsaes_encrypt8,.-_bsaes_encrypt8 +.type _bsaes_key_convert,%function +.align 4 +_bsaes_key_convert: + adr r6,. + vld1.8 {q7}, [r4]! @ load round 0 key +#if defined(__thumb2__) || defined(__APPLE__) + adr r6,.LM0 +#else + sub r6,r6,#_bsaes_key_convert-.LM0 +#endif + vld1.8 {q15}, [r4]! @ load round 1 key + + vmov.i8 q8, #0x01 @ bit masks + vmov.i8 q9, #0x02 + vmov.i8 q10, #0x04 + vmov.i8 q11, #0x08 + vmov.i8 q12, #0x10 + vmov.i8 q13, #0x20 + vldmia r6, {q14} @ .LM0 + +#ifdef __ARMEL__ + vrev32.8 q7, q7 + vrev32.8 q15, q15 +#endif + sub r5,r5,#1 + vstmia r12!, {q7} @ save round 0 key + b .Lkey_loop + +.align 4 +.Lkey_loop: + vtbl.8 d14,{q15},d28 + vtbl.8 d15,{q15},d29 + vmov.i8 q6, #0x40 + vmov.i8 q15, #0x80 + + vtst.8 q0, q7, q8 + vtst.8 q1, q7, q9 + vtst.8 q2, q7, q10 + vtst.8 q3, q7, q11 + vtst.8 q4, q7, q12 + vtst.8 q5, q7, q13 + vtst.8 q6, q7, q6 + vtst.8 q7, q7, q15 + vld1.8 {q15}, [r4]! @ load next round key + vmvn q0, q0 @ "pnot" + vmvn q1, q1 + vmvn q5, q5 + vmvn q6, q6 +#ifdef __ARMEL__ + vrev32.8 q15, q15 +#endif + subs r5,r5,#1 + vstmia r12!,{q0,q1,q2,q3,q4,q5,q6,q7} @ write bit-sliced round key + bne .Lkey_loop + + vmov.i8 q7,#0x63 @ compose .L63 + @ don't save last round key + bx lr +.size _bsaes_key_convert,.-_bsaes_key_convert +.globl bsaes_cbc_encrypt +.hidden bsaes_cbc_encrypt +.type bsaes_cbc_encrypt,%function +.align 5 +bsaes_cbc_encrypt: + @ In OpenSSL, this function had a fallback to aes_nohw_cbc_encrypt for + @ short inputs. We patch this out, using bsaes for all input sizes. + + @ it is up to the caller to make sure we are called with enc == 0 + + mov ip, sp + stmdb sp!, {r4,r5,r6,r7,r8,r9,r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ IV is 1st arg on the stack + mov r2, r2, lsr#4 @ len in 16 byte blocks + sub sp, #0x10 @ scratch space to carry over the IV + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ sifze of bit-slices key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + vldmia sp, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia sp, {q7} +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, r3, #248 + vldmia r4, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia r4, {q7} + +.align 2 + +#endif + + vld1.8 {q15}, [r8] @ load IV + b .Lcbc_dec_loop + +.align 4 +.Lcbc_dec_loop: + subs r2, r2, #0x8 + bmi .Lcbc_dec_loop_finish + + vld1.8 {q0,q1}, [r0]! @ load input + vld1.8 {q2,q3}, [r0]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + vld1.8 {q4,q5}, [r0]! + mov r5, r10 + vld1.8 {q6,q7}, [r0] + sub r0, r0, #0x60 + vstmia r9, {q15} @ put aside IV + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q14,q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + veor q5, q5, q14 + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + vst1.8 {q5}, [r1]! + + b .Lcbc_dec_loop + +.Lcbc_dec_loop_finish: + adds r2, r2, #8 + beq .Lcbc_dec_done + + @ Set up most parameters for the _bsaes_decrypt8 call. +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + mov r5, r10 + vstmia r9, {q15} @ put aside IV + + vld1.8 {q0}, [r0]! @ load input + cmp r2, #2 + blo .Lcbc_dec_one + vld1.8 {q1}, [r0]! + beq .Lcbc_dec_two + vld1.8 {q2}, [r0]! + cmp r2, #4 + blo .Lcbc_dec_three + vld1.8 {q3}, [r0]! + beq .Lcbc_dec_four + vld1.8 {q4}, [r0]! + cmp r2, #6 + blo .Lcbc_dec_five + vld1.8 {q5}, [r0]! + beq .Lcbc_dec_six + vld1.8 {q6}, [r0]! + sub r0, r0, #0x70 + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_six: + sub r0, r0, #0x60 + bl _bsaes_decrypt8 + vldmia r9,{q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_five: + sub r0, r0, #0x50 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10,q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0,q1}, [r1]! @ write output + veor q2, q2, q11 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_four: + sub r0, r0, #0x40 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_three: + sub r0, r0, #0x30 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8,q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vst1.8 {q0,q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_two: + sub r0, r0, #0x20 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! @ reload input + veor q1, q1, q8 + vst1.8 {q0,q1}, [r1]! @ write output + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_one: + sub r0, r0, #0x10 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q15}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vst1.8 {q0}, [r1]! @ write output + +.Lcbc_dec_done: +#ifndef BSAES_ASM_EXTENDED_KEY + vmov.i32 q0, #0 + vmov.i32 q1, #0 +.Lcbc_dec_bzero:@ wipe key schedule [if any] + vstmia sp!, {q0,q1} + cmp sp, r9 + bne .Lcbc_dec_bzero +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + vst1.8 {q15}, [r8] @ return IV + VFP_ABI_POP + ldmia sp!, {r4,r5,r6,r7,r8,r9,r10, pc} +.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt +.globl bsaes_ctr32_encrypt_blocks +.hidden bsaes_ctr32_encrypt_blocks +.type bsaes_ctr32_encrypt_blocks,%function +.align 5 +bsaes_ctr32_encrypt_blocks: + @ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this + @ out to retain a constant-time implementation. + mov ip, sp + stmdb sp!, {r4,r5,r6,r7,r8,r9,r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ ctr is 1st arg on the stack + sub sp, sp, #0x10 @ scratch space to carry over the ctr + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ size of bit-sliced key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + + vld1.8 {q0}, [r8] @ load counter +#ifdef __APPLE__ + mov r8, #:lower16:(.LREVM0SR-.LM0) + add r8, r6, r8 +#else + add r8, r6, #.LREVM0SR-.LM0 @ borrow r8 +#endif + vldmia sp, {q4} @ load round0 key +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + +.align 2 + add r12, r3, #248 + vld1.8 {q0}, [r8] @ load counter + adrl r8, .LREVM0SR @ borrow r8 + vldmia r12, {q4} @ load round0 key + sub sp, #0x10 @ place for adjusted round0 key +#endif + + vmov.i32 q8,#1 @ compose 1<<96 + veor q9,q9,q9 + vrev32.8 q0,q0 + vext.8 q8,q9,q8,#4 + vrev32.8 q4,q4 + vadd.u32 q9,q8,q8 @ compose 2<<96 + vstmia sp, {q4} @ save adjusted round0 key + b .Lctr_enc_loop + +.align 4 +.Lctr_enc_loop: + vadd.u32 q10, q8, q9 @ compose 3<<96 + vadd.u32 q1, q0, q8 @ +1 + vadd.u32 q2, q0, q9 @ +2 + vadd.u32 q3, q0, q10 @ +3 + vadd.u32 q4, q1, q10 + vadd.u32 q5, q2, q10 + vadd.u32 q6, q3, q10 + vadd.u32 q7, q4, q10 + vadd.u32 q10, q5, q10 @ next counter + + @ Borrow prologue from _bsaes_encrypt8 to use the opportunity + @ to flip byte order in 32-bit counter + + vldmia sp, {q9} @ load round0 key +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x10 @ pass next round key +#else + add r4, r3, #264 +#endif + vldmia r8, {q8} @ .LREVM0SR + mov r5, r10 @ pass rounds + vstmia r9, {q10} @ save next counter +#ifdef __APPLE__ + mov r6, #:lower16:(.LREVM0SR-.LSR) + sub r6, r8, r6 +#else + sub r6, r8, #.LREVM0SR-.LSR @ pass constants +#endif + + bl _bsaes_encrypt8_alt + + subs r2, r2, #8 + blo .Lctr_enc_loop_done + + vld1.8 {q8,q9}, [r0]! @ load input + vld1.8 {q10,q11}, [r0]! + veor q0, q8 + veor q1, q9 + vld1.8 {q12,q13}, [r0]! + veor q4, q10 + veor q6, q11 + vld1.8 {q14,q15}, [r0]! + veor q3, q12 + vst1.8 {q0,q1}, [r1]! @ write output + veor q7, q13 + veor q2, q14 + vst1.8 {q4}, [r1]! + veor q5, q15 + vst1.8 {q6}, [r1]! + vmov.i32 q8, #1 @ compose 1<<96 + vst1.8 {q3}, [r1]! + veor q9, q9, q9 + vst1.8 {q7}, [r1]! + vext.8 q8, q9, q8, #4 + vst1.8 {q2}, [r1]! + vadd.u32 q9,q8,q8 @ compose 2<<96 + vst1.8 {q5}, [r1]! + vldmia r9, {q0} @ load counter + + bne .Lctr_enc_loop + b .Lctr_enc_done + +.align 4 +.Lctr_enc_loop_done: + add r2, r2, #8 + vld1.8 {q8}, [r0]! @ load input + veor q0, q8 + vst1.8 {q0}, [r1]! @ write output + cmp r2, #2 + blo .Lctr_enc_done + vld1.8 {q9}, [r0]! + veor q1, q9 + vst1.8 {q1}, [r1]! + beq .Lctr_enc_done + vld1.8 {q10}, [r0]! + veor q4, q10 + vst1.8 {q4}, [r1]! + cmp r2, #4 + blo .Lctr_enc_done + vld1.8 {q11}, [r0]! + veor q6, q11 + vst1.8 {q6}, [r1]! + beq .Lctr_enc_done + vld1.8 {q12}, [r0]! + veor q3, q12 + vst1.8 {q3}, [r1]! + cmp r2, #6 + blo .Lctr_enc_done + vld1.8 {q13}, [r0]! + veor q7, q13 + vst1.8 {q7}, [r1]! + beq .Lctr_enc_done + vld1.8 {q14}, [r0] + veor q2, q14 + vst1.8 {q2}, [r1]! + +.Lctr_enc_done: + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifndef BSAES_ASM_EXTENDED_KEY +.Lctr_enc_bzero:@ wipe key schedule [if any] + vstmia sp!, {q0,q1} + cmp sp, r9 + bne .Lctr_enc_bzero +#else + vstmia sp, {q0,q1} +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + VFP_ABI_POP + ldmia sp!, {r4,r5,r6,r7,r8,r9,r10, pc} @ return + + @ OpenSSL contains aes_nohw_* fallback code here. We patch this + @ out to retain a constant-time implementation. +.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/aead.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/aead.c new file mode 100644 index 00000000..fbaccca8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/aead.c @@ -0,0 +1,287 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; } + +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) { return aead->nonce_len; } + +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; } + +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; } + +void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_AEAD_CTX)); +} + +EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key, + size_t key_len, size_t tag_len) { + EVP_AEAD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_AEAD_CTX)); + EVP_AEAD_CTX_zero(ctx); + + if (EVP_AEAD_CTX_init(ctx, aead, key, key_len, tag_len, NULL)) { + return ctx; + } + + EVP_AEAD_CTX_free(ctx); + return NULL; +} + +void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) { + if (ctx == NULL) { + return; + } + EVP_AEAD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, size_t tag_len, + ENGINE *impl) { + if (!aead->init) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET); + ctx->aead = NULL; + return 0; + } + return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len, + evp_aead_open); +} + +int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + if (key_len != aead->key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE); + ctx->aead = NULL; + return 0; + } + + ctx->aead = aead; + + int ok; + if (aead->init) { + ok = aead->init(ctx, key, key_len, tag_len); + } else { + ok = aead->init_with_direction(ctx, key, key_len, tag_len, dir); + } + + if (!ok) { + ctx->aead = NULL; + } + + return ok; +} + +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) { + if (ctx->aead == NULL) { + return; + } + ctx->aead->cleanup(ctx); + ctx->aead = NULL; +} + +// check_alias returns 1 if |out| is compatible with |in| and 0 otherwise. If +// |in| and |out| alias, we require that |in| == |out|. +static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out, + size_t out_len) { + if (!buffers_alias(in, in_len, out, out_len)) { + return 1; + } + + return in == out; +} + +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (in_len + ctx->aead->overhead < in_len /* overflow */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + goto error; + } + + if (max_out_len < in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + size_t out_tag_len; + if (ctx->aead->seal_scatter(ctx, out, out + in_len, &out_tag_len, + max_out_len - in_len, nonce, nonce_len, in, + in_len, NULL, 0, ad, ad_len)) { + *out_len = in_len + out_tag_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, size_t + *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, size_t + nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + // |in| and |out| may alias exactly, |out_tag| may not alias. + if (!check_alias(in, in_len, out, in_len) || + buffers_alias(out, in_len, out_tag, max_out_tag_len) || + buffers_alias(in, in_len, out_tag, max_out_tag_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->seal_scatter_supports_extra_in && extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + goto error; + } + + if (ctx->aead->seal_scatter(ctx, out, out_tag, out_tag_len, max_out_tag_len, + nonce, nonce_len, in, in_len, extra_in, + extra_in_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, in_len); + OPENSSL_memset(out_tag, 0, max_out_tag_len); + *out_tag_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (ctx->aead->open) { + if (!ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len, in, + in_len, ad, ad_len)) { + goto error; + } + return 1; + } + + // AEADs that use the default implementation of open() must set |tag_len| at + // initialization time. + assert(ctx->tag_len); + + if (in_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + goto error; + } + + size_t plaintext_len = in_len - ctx->tag_len; + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + if (EVP_AEAD_CTX_open_gather(ctx, out, nonce, nonce_len, in, plaintext_len, + in + plaintext_len, ctx->tag_len, ad, ad_len)) { + *out_len = plaintext_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->open_gather) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + goto error; + } + + if (ctx->aead->open_gather(ctx, out, nonce, nonce_len, in, in_len, in_tag, + in_tag_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, in_len); + return 0; +} + +const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx) { return ctx->aead; } + +int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len) { + if (ctx->aead->get_iv == NULL) { + return 0; + } + + return ctx->aead->get_iv(ctx, out_iv, out_len); +} + +int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, size_t *out_tag_len, + const size_t in_len, const size_t extra_in_len) { + assert(ctx->aead->seal_scatter_supports_extra_in || !extra_in_len); + + if (ctx->aead->tag_len) { + *out_tag_len = ctx->aead->tag_len(ctx, in_len, extra_in_len); + return 1; + } + + if (extra_in_len + ctx->tag_len < extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW); + *out_tag_len = 0; + return 0; + } + *out_tag_len = extra_in_len + ctx->tag_len; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c new file mode 100644 index 00000000..3320d611 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c @@ -0,0 +1,648 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); + if (ctx) { + EVP_CIPHER_CTX_init(ctx); + } + return ctx; +} + +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { + if (c->cipher != NULL && c->cipher->cleanup) { + c->cipher->cleanup(c); + } + OPENSSL_free(c->cipher_data); + + OPENSSL_memset(c, 0, sizeof(EVP_CIPHER_CTX)); + return 1; +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { + if (ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { + if (in == NULL || in->cipher == NULL) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_CIPHER_CTX_cleanup(out); + OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX)); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { + out->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } + + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) { + if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { + out->cipher = NULL; + return 0; + } + } + + return 1; +} + +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_init(ctx); + return 1; +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *engine, const uint8_t *key, const uint8_t *iv, + int enc) { + if (enc == -1) { + enc = ctx->encrypt; + } else { + if (enc) { + enc = 1; + } + ctx->encrypt = enc; + } + + if (cipher) { + // Ensure a context left from last time is cleared (the previous check + // attempted to avoid this if the same ENGINE and EVP_CIPHER could be + // used). + if (ctx->cipher) { + EVP_CIPHER_CTX_cleanup(ctx); + // Restore encrypt and flags + ctx->encrypt = enc; + } + + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + + ctx->key_len = cipher->key_len; + ctx->flags = 0; + + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + // we assume block size is a power of 2 in *cryptUpdate + assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || + ctx->cipher->block_size == 16); + + if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch (EVP_CIPHER_CTX_mode(ctx)) { + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + ctx->num = 0; + OPENSSL_FALLTHROUGH; + + case EVP_CIPH_CBC_MODE: + assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv)); + if (iv) { + OPENSSL_memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + OPENSSL_memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + case EVP_CIPH_OFB_MODE: + ctx->num = 0; + // Don't reuse IV for CTR mode + if (iv) { + OPENSSL_memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + break; + + default: + return 0; + } + } + + if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (!ctx->cipher->init(ctx, key, iv, enc)) { + return 0; + } + } + + ctx->buf_len = 0; + ctx->final_used = 0; + return 1; +} + +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +// block_remainder returns the number of bytes to remove from |len| to get a +// multiple of |ctx|'s block size. +static int block_remainder(const EVP_CIPHER_CTX *ctx, int len) { + // |block_size| must be a power of two. + assert(ctx->cipher->block_size != 0); + assert((ctx->cipher->block_size & (ctx->cipher->block_size - 1)) == 0); + return len & (ctx->cipher->block_size - 1); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + // Ciphers that use blocks may write up to |bl| extra bytes. Ensure the output + // does not overflow |*out_len|. + int bl = ctx->cipher->block_size; + if (bl > 1 && in_len > INT_MAX - bl) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW); + return 0; + } + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + int ret = ctx->cipher->cipher(ctx, out, in, in_len); + if (ret < 0) { + return 0; + } else { + *out_len = ret; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->buf_len == 0 && block_remainder(ctx, in_len) == 0) { + if (ctx->cipher->cipher(ctx, out, in, in_len)) { + *out_len = in_len; + return 1; + } else { + *out_len = 0; + return 0; + } + } + + int i = ctx->buf_len; + assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) { + if (bl - i > in_len) { + OPENSSL_memcpy(&ctx->buf[i], in, in_len); + ctx->buf_len += in_len; + *out_len = 0; + return 1; + } else { + int j = bl - i; + OPENSSL_memcpy(&ctx->buf[i], in, j); + if (!ctx->cipher->cipher(ctx, out, ctx->buf, bl)) { + return 0; + } + in_len -= j; + in += j; + out += bl; + *out_len = bl; + } + } else { + *out_len = 0; + } + + i = block_remainder(ctx, in_len); + in_len -= i; + if (in_len > 0) { + if (!ctx->cipher->cipher(ctx, out, in, in_len)) { + return 0; + } + *out_len += in_len; + } + + if (i != 0) { + OPENSSL_memcpy(ctx->buf, &in[in_len], i); + } + ctx->buf_len = i; + return 1; +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = ctx->cipher->cipher(ctx, out, NULL, 0); + if (ret < 0) { + return 0; + } else { + *out_len = ret; + } + return 1; + } + + b = ctx->cipher->block_size; + assert(b <= sizeof(ctx->buf)); + if (b == 1) { + *out_len = 0; + return 1; + } + + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) { + ctx->buf[i] = n; + } + ret = ctx->cipher->cipher(ctx, out, ctx->buf, b); + + if (ret) { + *out_len = b; + } + + return ret; +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + // Ciphers that use blocks may write up to |bl| extra bytes. Ensure the output + // does not overflow |*out_len|. + unsigned int b = ctx->cipher->block_size; + if (b > 1 && in_len > INT_MAX - (int)b) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW); + return 0; + } + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + int r = ctx->cipher->cipher(ctx, out, in, in_len); + if (r < 0) { + *out_len = 0; + return 0; + } else { + *out_len = r; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } + + assert(b <= sizeof(ctx->final)); + int fix_len = 0; + if (ctx->final_used) { + OPENSSL_memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } + + if (!EVP_EncryptUpdate(ctx, out, out_len, in, in_len)) { + return 0; + } + + // if we have 'decrypted' a multiple of block size, make sure + // we have a copy of this last block + if (b > 1 && !ctx->buf_len) { + *out_len -= b; + ctx->final_used = 1; + OPENSSL_memcpy(ctx->final, &out[*out_len], b); + } else { + ctx->final_used = 0; + } + + if (fix_len) { + *out_len += b; + } + + return 1; +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { + int i, n; + unsigned int b; + *out_len = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->cipher(ctx, out, NULL, 0); + if (i < 0) { + return 0; + } else { + *out_len = i; + } + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH); + return 0; + } + assert(b <= sizeof(ctx->final)); + + // The following assumes that the ciphertext has been authenticated. + // Otherwise it provides a padding oracle. + n = ctx->final[b - 1]; + if (n == 0 || n > (int)b) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } + + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) { + out[i] = ctx->final[i]; + } + *out_len = n; + } else { + *out_len = 0; + } + + return 1; +} + +int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + return ctx->cipher->cipher(ctx, out, in, in_len); +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + if (ctx->encrypt) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } else { + return EVP_DecryptUpdate(ctx, out, out_len, in, in_len); + } +} + +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->encrypt) { + return EVP_EncryptFinal_ex(ctx, out, out_len); + } else { + return EVP_DecryptFinal_ex(ctx, out, out_len); + } +} + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher; +} + +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->nid; +} + +int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) { + return ctx->encrypt; +} + +unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->block_size; +} + +unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { + return ctx->key_len; +} + +unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->iv_len; +} + +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) { + return ctx->app_data; +} + +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) { + ctx->app_data = data; +} + +uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) { + int ret; + if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, command, arg, ptr); + if (ret == -1) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + + return ret; +} + +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) { + if (pad) { + ctx->flags &= ~EVP_CIPH_NO_PADDING; + } else { + ctx->flags |= EVP_CIPH_NO_PADDING; + } + return 1; +} + +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) { + if (c->key_len == key_len) { + return 1; + } + + if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH); + return 0; + } + + c->key_len = key_len; + return 1; +} + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) { return cipher->nid; } + +unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { + return cipher->block_size; +} + +unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { + return cipher->key_len; +} + +unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { + return cipher->iv_len; +} + +uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher) { + return cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher) { + return cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, int enc) { + if (cipher) { + EVP_CIPHER_CTX_init(ctx); + } + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + return EVP_CipherFinal_ex(ctx, out, out_len); +} + +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + return EVP_EncryptFinal_ex(ctx, out, out_len); +} + +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + return EVP_DecryptFinal_ex(ctx, out, out_len); +} + +int EVP_add_cipher_alias(const char *a, const char *b) { + return 1; +} + +void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, uint32_t flags) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c new file mode 100644 index 00000000..e40e9046 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c @@ -0,0 +1,1472 @@ +/* ==================================================================== + * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../aes/internal.h" +#include "../modes/internal.h" +#include "../delocate.h" + + +OPENSSL_MSVC_PRAGMA(warning(push)) +OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) // Unreachable code. + +#define AES_GCM_NONCE_LENGTH 12 + +#if defined(BSAES) +static void vpaes_ctr32_encrypt_blocks_with_bsaes(const uint8_t *in, + uint8_t *out, size_t blocks, + const AES_KEY *key, + const uint8_t ivec[16]) { + // |bsaes_ctr32_encrypt_blocks| is faster than |vpaes_ctr32_encrypt_blocks|, + // but it takes at least one full 8-block batch to amortize the conversion. + if (blocks < 8) { + vpaes_ctr32_encrypt_blocks(in, out, blocks, key, ivec); + return; + } + + size_t bsaes_blocks = blocks; + if (bsaes_blocks % 8 < 6) { + // |bsaes_ctr32_encrypt_blocks| internally works in 8-block batches. If the + // final batch is too small (under six blocks), it is faster to loop over + // |vpaes_encrypt|. Round |bsaes_blocks| down to a multiple of 8. + bsaes_blocks -= bsaes_blocks % 8; + } + + AES_KEY bsaes; + vpaes_encrypt_key_to_bsaes(&bsaes, key); + bsaes_ctr32_encrypt_blocks(in, out, bsaes_blocks, &bsaes, ivec); + OPENSSL_cleanse(&bsaes, sizeof(bsaes)); + + in += 16 * bsaes_blocks; + out += 16 * bsaes_blocks; + blocks -= bsaes_blocks; + + union { + uint32_t u32[4]; + uint8_t u8[16]; + } new_ivec; + memcpy(new_ivec.u8, ivec, 16); + uint32_t ctr = CRYPTO_bswap4(new_ivec.u32[3]) + bsaes_blocks; + new_ivec.u32[3] = CRYPTO_bswap4(ctr); + + // Finish any remaining blocks with |vpaes_ctr32_encrypt_blocks|. + vpaes_ctr32_encrypt_blocks(in, out, blocks, key, new_ivec.u8); +} +#endif // BSAES + +typedef struct { + union { + double align; + AES_KEY ks; + } ks; + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; +} EVP_AES_KEY; + +typedef struct { + GCM128_CONTEXT gcm; + union { + double align; + AES_KEY ks; + } ks; // AES key schedule to use + int key_set; // Set if key initialised + int iv_set; // Set if an iv is set + uint8_t *iv; // Temporary IV store + int ivlen; // IV length + int taglen; + int iv_gen; // It is OK to generate IVs + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + int ret; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + const int mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK; + + if (mode == EVP_CIPH_CTR_MODE) { + switch (ctx->key_len) { + case 16: + boringssl_fips_inc_counter(fips_counter_evp_aes_128_ctr); + break; + + case 32: + boringssl_fips_inc_counter(fips_counter_evp_aes_256_ctr); + break; + } + } + + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { + if (hwaes_capable()) { + ret = aes_hw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = aes_hw_decrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = aes_hw_cbc_encrypt; + } + } else if (bsaes_capable() && mode == EVP_CIPH_CBC_MODE) { + assert(vpaes_capable()); + ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + if (ret == 0) { + vpaes_decrypt_key_to_bsaes(&dat->ks.ks, &dat->ks.ks); + } + // If |dat->stream.cbc| is provided, |dat->block| is never used. + dat->block = NULL; + dat->stream.cbc = bsaes_cbc_encrypt; + } else if (vpaes_capable()) { + ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = vpaes_decrypt; + dat->stream.cbc = NULL; +#if defined(VPAES_CBC) + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = vpaes_cbc_encrypt; + } +#endif + } else { + ret = aes_nohw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = aes_nohw_decrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = aes_nohw_cbc_encrypt; + } + } + } else if (hwaes_capable()) { + ret = aes_hw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = aes_hw_encrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = aes_hw_cbc_encrypt; + } else if (mode == EVP_CIPH_CTR_MODE) { + dat->stream.ctr = aes_hw_ctr32_encrypt_blocks; + } + } else if (vpaes_capable()) { + ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = vpaes_encrypt; + dat->stream.cbc = NULL; +#if defined(VPAES_CBC) + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = vpaes_cbc_encrypt; + } +#endif + if (mode == EVP_CIPH_CTR_MODE) { +#if defined(BSAES) + assert(bsaes_capable()); + dat->stream.ctr = vpaes_ctr32_encrypt_blocks_with_bsaes; +#elif defined(VPAES_CTR32) + dat->stream.ctr = vpaes_ctr32_encrypt_blocks; +#endif + } + } else { + ret = aes_nohw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = aes_nohw_encrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = aes_nohw_cbc_encrypt; + } + } + + if (ret < 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (dat->stream.cbc) { + (*dat->stream.cbc)(in, out, len, &dat->ks.ks, ctx->iv, ctx->encrypt); + } else if (ctx->encrypt) { + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks.ks, ctx->iv, dat->block); + } else { + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks.ks, ctx->iv, dat->block); + } + + return 1; +} + +static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + size_t bl = ctx->cipher->block_size; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (len < bl) { + return 1; + } + + len -= bl; + for (size_t i = 0; i <= len; i += bl) { + (*dat->block)(in + i, out + i, &dat->ks.ks); + } + + return 1; +} + +static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (dat->stream.ctr) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks.ks, ctx->iv, ctx->buf, + &ctx->num, dat->stream.ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks.ks, ctx->iv, ctx->buf, + &ctx->num, dat->block); + } + return 1; +} + +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks.ks, ctx->iv, &ctx->num, + dat->block); + return 1; +} + +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, + block128_f *out_block, const uint8_t *key, + size_t key_bytes) { + if (hwaes_capable()) { + aes_hw_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_key != NULL) { + CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_hw_encrypt, 1); + } + if (out_block) { + *out_block = aes_hw_encrypt; + } + return aes_hw_ctr32_encrypt_blocks; + } + + if (vpaes_capable()) { + vpaes_set_encrypt_key(key, key_bytes * 8, aes_key); + if (out_block) { + *out_block = vpaes_encrypt; + } + if (gcm_key != NULL) { + CRYPTO_gcm128_init_key(gcm_key, aes_key, vpaes_encrypt, 0); + } +#if defined(BSAES) + assert(bsaes_capable()); + return vpaes_ctr32_encrypt_blocks_with_bsaes; +#elif defined(VPAES_CTR32) + return vpaes_ctr32_encrypt_blocks; +#else + return NULL; +#endif + } + + aes_nohw_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_key != NULL) { + CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_nohw_encrypt, 0); + } + if (out_block) { + *out_block = aes_nohw_encrypt; + } + return aes_nohw_ctr32_encrypt_blocks; +} + +#if defined(OPENSSL_32_BIT) +#define EVP_AES_GCM_CTX_PADDING (4+8) +#else +#define EVP_AES_GCM_CTX_PADDING 8 +#endif + +static EVP_AES_GCM_CTX *aes_gcm_from_cipher_ctx(EVP_CIPHER_CTX *ctx) { +#if defined(__GNUC__) || defined(__clang__) + OPENSSL_STATIC_ASSERT( + alignof(EVP_AES_GCM_CTX) <= 16, + "EVP_AES_GCM_CTX needs more alignment than this function provides"); +#endif + + // |malloc| guarantees up to 4-byte alignment on 32-bit and 8-byte alignment + // on 64-bit systems, so we need to adjust to reach 16-byte alignment. + assert(ctx->cipher->ctx_size == + sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING); + + char *ptr = ctx->cipher_data; +#if defined(OPENSSL_32_BIT) + assert((uintptr_t)ptr % 4 == 0); + ptr += (uintptr_t)ptr & 4; +#endif + assert((uintptr_t)ptr % 8 == 0); + ptr += (uintptr_t)ptr & 8; + return (EVP_AES_GCM_CTX *)ptr; +} + +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_AES_GCM_CTX *gctx = aes_gcm_from_cipher_ctx(ctx); + if (!iv && !key) { + return 1; + } + + switch (ctx->key_len) { + case 16: + boringssl_fips_inc_counter(fips_counter_evp_aes_128_gcm); + break; + + case 32: + boringssl_fips_inc_counter(fips_counter_evp_aes_256_gcm); + break; + } + + if (key) { + OPENSSL_memset(&gctx->gcm, 0, sizeof(gctx->gcm)); + gctx->ctr = aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm.gcm_key, NULL, key, + ctx->key_len); + // If we have an iv can set it directly, otherwise use saved IV. + if (iv == NULL && gctx->iv_set) { + iv = gctx->iv; + } + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + // If key set use IV, otherwise copy + if (gctx->key_set) { + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen); + } else { + OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); + } + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) { + EVP_AES_GCM_CTX *gctx = aes_gcm_from_cipher_ctx(c); + OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); + if (gctx->iv != c->iv) { + OPENSSL_free(gctx->iv); + } +} + +// increment counter (64-bit int) by 1 +static void ctr64_inc(uint8_t *counter) { + int n = 8; + uint8_t c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) { + return; + } + } while (n); +} + +static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { + EVP_AES_GCM_CTX *gctx = aes_gcm_from_cipher_ctx(c); + switch (type) { + case EVP_CTRL_INIT: + gctx->key_set = 0; + gctx->iv_set = 0; + gctx->ivlen = c->cipher->iv_len; + gctx->iv = c->iv; + gctx->taglen = -1; + gctx->iv_gen = 0; + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg <= 0) { + return 0; + } + + // Allocate memory for IV if needed + if (arg > EVP_MAX_IV_LENGTH && arg > gctx->ivlen) { + if (gctx->iv != c->iv) { + OPENSSL_free(gctx->iv); + } + gctx->iv = OPENSSL_malloc(arg); + if (!gctx->iv) { + return 0; + } + } + gctx->ivlen = arg; + return 1; + + case EVP_CTRL_AEAD_SET_TAG: + if (arg <= 0 || arg > 16 || c->encrypt) { + return 0; + } + OPENSSL_memcpy(c->buf, ptr, arg); + gctx->taglen = arg; + return 1; + + case EVP_CTRL_AEAD_GET_TAG: + if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) { + return 0; + } + OPENSSL_memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_AEAD_SET_IV_FIXED: + // Special case: -1 length restores whole IV + if (arg == -1) { + OPENSSL_memcpy(gctx->iv, ptr, gctx->ivlen); + gctx->iv_gen = 1; + return 1; + } + // Fixed field must be at least 4 bytes and invocation field + // at least 8. + if (arg < 4 || (gctx->ivlen - arg) < 8) { + return 0; + } + if (arg) { + OPENSSL_memcpy(gctx->iv, ptr, arg); + } + if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) { + return 0; + } + gctx->iv_gen = 1; + return 1; + + case EVP_CTRL_GCM_IV_GEN: + if (gctx->iv_gen == 0 || gctx->key_set == 0) { + return 0; + } + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) { + arg = gctx->ivlen; + } + OPENSSL_memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); + // Invocation field will be at least 8 bytes in size and + // so no need to check wrap around or increment more than + // last 8 bytes. + ctr64_inc(gctx->iv + gctx->ivlen - 8); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_GCM_SET_IV_INV: + if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) { + return 0; + } + OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_COPY: { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = aes_gcm_from_cipher_ctx(out); + // |EVP_CIPHER_CTX_copy| copies this generically, but we must redo it in + // case |out->cipher_data| and |in->cipher_data| are differently aligned. + OPENSSL_memcpy(gctx_out, gctx, sizeof(EVP_AES_GCM_CTX)); + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; + } else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (!gctx_out->iv) { + return 0; + } + OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + } +} + +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + EVP_AES_GCM_CTX *gctx = aes_gcm_from_cipher_ctx(ctx); + + // If not set up, return error + if (!gctx->key_set) { + return -1; + } + if (!gctx->iv_set) { + return -1; + } + + if (in) { + if (out == NULL) { + if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) { + return -1; + } + } else if (ctx->encrypt) { + if (gctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } else { + if (gctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0 || + !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) { + return -1; + } + gctx->iv_set = 0; + return 0; + } + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + gctx->taglen = 16; + // Don't reuse the IV + gctx->iv_set = 0; + return 0; + } +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_cbc; + out->block_size = 16; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ctr; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ofb128; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_gcm; + out->block_size = 1; + out->key_len = 16; + out->iv_len = AES_GCM_NONCE_LENGTH; + out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING; + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_cbc; + out->block_size = 16; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ctr; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ofb128; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_gcm; + out->block_size = 1; + out->key_len = 24; + out->iv_len = AES_GCM_NONCE_LENGTH; + out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING; + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_cbc; + out->block_size = 16; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ctr; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ofb128; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_gcm; + out->block_size = 1; + out->key_len = 32; + out->iv_len = AES_GCM_NONCE_LENGTH; + out->ctx_size = sizeof(EVP_AES_GCM_CTX) + EVP_AES_GCM_CTX_PADDING; + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_CUSTOM_COPY | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +#if defined(HWAES_ECB) + +static int aes_hw_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t len) { + size_t bl = ctx->cipher->block_size; + + if (len < bl) { + return 1; + } + + aes_hw_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); + + return 1; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_hw_128_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_hw_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_hw_192_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_hw_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_hw_256_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_hw_ecb_cipher; +} + +#define EVP_ECB_CIPHER_FUNCTION(keybits) \ + const EVP_CIPHER *EVP_aes_##keybits##_ecb(void) { \ + if (hwaes_capable()) { \ + return aes_hw_##keybits##_ecb(); \ + } \ + return aes_##keybits##_ecb_generic(); \ + } + +#else + +#define EVP_ECB_CIPHER_FUNCTION(keybits) \ + const EVP_CIPHER *EVP_aes_##keybits##_ecb(void) { \ + return aes_##keybits##_ecb_generic(); \ + } + +#endif // HWAES_ECB + +#define EVP_CIPHER_FUNCTION(keybits, mode) \ + const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ + return aes_##keybits##_##mode##_generic(); \ + } + +EVP_CIPHER_FUNCTION(128, cbc) +EVP_CIPHER_FUNCTION(128, ctr) +EVP_CIPHER_FUNCTION(128, ofb) +EVP_CIPHER_FUNCTION(128, gcm) + +EVP_CIPHER_FUNCTION(192, cbc) +EVP_CIPHER_FUNCTION(192, ctr) +EVP_CIPHER_FUNCTION(192, ofb) +EVP_CIPHER_FUNCTION(192, gcm) + +EVP_CIPHER_FUNCTION(256, cbc) +EVP_CIPHER_FUNCTION(256, ctr) +EVP_CIPHER_FUNCTION(256, ofb) +EVP_CIPHER_FUNCTION(256, gcm) + +EVP_ECB_CIPHER_FUNCTION(128) +EVP_ECB_CIPHER_FUNCTION(192) +EVP_ECB_CIPHER_FUNCTION(256) + + +#define EVP_AEAD_AES_GCM_TAG_LEN 16 + +struct aead_aes_gcm_ctx { + union { + double align; + AES_KEY ks; + } ks; + GCM128_KEY gcm_key; + ctr128_f ctr; +}; + +static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, + size_t *out_tag_len, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + switch (key_bits) { + case 128: + boringssl_fips_inc_counter(fips_counter_evp_aes_128_gcm); + break; + + case 256: + boringssl_fips_inc_counter(fips_counter_evp_aes_256_gcm); + break; + } + + if (key_bits != 128 && key_bits != 192 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + gcm_ctx->ctr = + aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm_key, NULL, key, key_len); + *out_tag_len = tag_len; + return 1; +} + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_ctx *gcm_ctx = (struct aead_aes_gcm_ctx *) &ctx->state; + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + return 0; + } + + ctx->tag_len = actual_tag_len; + return 1; +} + +static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) {} + +static int aead_aes_gcm_seal_scatter_impl( + const struct aead_aes_gcm_ctx *gcm_ctx, + uint8_t *out, uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len, + const uint8_t *ad, size_t ad_len, + size_t tag_len) { + if (extra_in_len + tag_len < tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < extra_in_len + tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + GCM128_CONTEXT gcm; + OPENSSL_memset(&gcm, 0, sizeof(gcm)); + OPENSSL_memcpy(&gcm.gcm_key, &gcm_ctx->gcm_key, sizeof(gcm.gcm_key)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + if (extra_in_len) { + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, extra_in, out_tag, + extra_in_len, gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, extra_in, out_tag, extra_in_len)) { + return 0; + } + } + } + + CRYPTO_gcm128_tag(&gcm, out_tag + extra_in_len, tag_len); + *out_tag_len = tag_len + extra_in_len; + + return 1; +} + +static int aead_aes_gcm_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, + size_t extra_in_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_ctx *gcm_ctx = + (const struct aead_aes_gcm_ctx *)&ctx->state; + return aead_aes_gcm_seal_scatter_impl( + gcm_ctx, out, out_tag, out_tag_len, max_out_tag_len, nonce, nonce_len, in, + in_len, extra_in, extra_in_len, ad, ad_len, ctx->tag_len); +} + +static int aead_aes_gcm_open_gather_impl(const struct aead_aes_gcm_ctx *gcm_ctx, + uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, + size_t in_tag_len, + const uint8_t *ad, size_t ad_len, + size_t tag_len) { + uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; + + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + GCM128_CONTEXT gcm; + OPENSSL_memset(&gcm, 0, sizeof(gcm)); + OPENSSL_memcpy(&gcm.gcm_key, &gcm_ctx->gcm_key, sizeof(gcm.gcm_key)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + CRYPTO_gcm128_tag(&gcm, tag, tag_len); + if (CRYPTO_memcmp(tag, in_tag, tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + struct aead_aes_gcm_ctx *gcm_ctx = (struct aead_aes_gcm_ctx *)&ctx->state; + return aead_aes_gcm_open_gather_impl(gcm_ctx, out, nonce, nonce_len, in, + in_len, in_tag, in_tag_len, ad, ad_len, + ctx->tag_len); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_192_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 24; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +static int aead_aes_gcm_init_randnonce(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, + size_t requested_tag_len) { + if (requested_tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH) { + if (requested_tag_len < AES_GCM_NONCE_LENGTH) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + requested_tag_len -= AES_GCM_NONCE_LENGTH; + } + + if (!aead_aes_gcm_init(ctx, key, key_len, requested_tag_len)) { + return 0; + } + + ctx->tag_len += AES_GCM_NONCE_LENGTH; + return 1; +} + +static int aead_aes_gcm_seal_scatter_randnonce( + const EVP_AEAD_CTX *ctx, + uint8_t *out, uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *external_nonce, size_t external_nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len, + const uint8_t *ad, size_t ad_len) { + if (external_nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + uint8_t nonce[AES_GCM_NONCE_LENGTH]; + if (max_out_tag_len < sizeof(nonce)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + RAND_bytes(nonce, sizeof(nonce)); + const struct aead_aes_gcm_ctx *gcm_ctx = + (const struct aead_aes_gcm_ctx *)&ctx->state; + if (!aead_aes_gcm_seal_scatter_impl(gcm_ctx, out, out_tag, out_tag_len, + max_out_tag_len - AES_GCM_NONCE_LENGTH, + nonce, sizeof(nonce), in, in_len, + extra_in, extra_in_len, ad, ad_len, + ctx->tag_len - AES_GCM_NONCE_LENGTH)) { + return 0; + } + + assert(*out_tag_len + sizeof(nonce) <= max_out_tag_len); + memcpy(out_tag + *out_tag_len, nonce, sizeof(nonce)); + *out_tag_len += sizeof(nonce); + + return 1; +} + +static int aead_aes_gcm_open_gather_randnonce( + const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *external_nonce, size_t external_nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + if (external_nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len < AES_GCM_NONCE_LENGTH) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + const uint8_t *nonce = in_tag + in_tag_len - AES_GCM_NONCE_LENGTH; + + const struct aead_aes_gcm_ctx *gcm_ctx = + (const struct aead_aes_gcm_ctx *)&ctx->state; + return aead_aes_gcm_open_gather_impl( + gcm_ctx, out, nonce, AES_GCM_NONCE_LENGTH, in, in_len, in_tag, + in_tag_len - AES_GCM_NONCE_LENGTH, ad, ad_len, + ctx->tag_len - AES_GCM_NONCE_LENGTH); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_randnonce) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 0; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN + AES_GCM_NONCE_LENGTH; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN + AES_GCM_NONCE_LENGTH; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init_randnonce; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter_randnonce; + out->open_gather = aead_aes_gcm_open_gather_randnonce; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_randnonce) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = 0; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN + AES_GCM_NONCE_LENGTH; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN + AES_GCM_NONCE_LENGTH; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init_randnonce; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter_randnonce; + out->open_gather = aead_aes_gcm_open_gather_randnonce; +} + +struct aead_aes_gcm_tls12_ctx { + struct aead_aes_gcm_ctx gcm_ctx; + uint64_t min_next_nonce; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_tls12_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_tls12_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx = + (struct aead_aes_gcm_tls12_ctx *) &ctx->state; + + gcm_ctx->min_next_nonce = 0; + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + return 0; + } + + ctx->tag_len = actual_tag_len; + return 1; +} + +static int aead_aes_gcm_tls12_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx = + (struct aead_aes_gcm_tls12_ctx *) &ctx->state; + + if (nonce_len != AES_GCM_NONCE_LENGTH) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // The given nonces must be strictly monotonically increasing. + uint64_t given_counter; + OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), + sizeof(given_counter)); + given_counter = CRYPTO_bswap8(given_counter); + if (given_counter == UINT64_MAX || + given_counter < gcm_ctx->min_next_nonce) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); + return 0; + } + + gcm_ctx->min_next_nonce = given_counter + 1; + + return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, + in_len, extra_in, extra_in_len, ad, ad_len); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +struct aead_aes_gcm_tls13_ctx { + struct aead_aes_gcm_ctx gcm_ctx; + uint64_t min_next_nonce; + uint64_t mask; + uint8_t first; +}; + +OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_tls13_ctx), + "AEAD state is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_tls13_ctx), + "AEAD state has insufficient alignment"); +#endif + +static int aead_aes_gcm_tls13_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_tls13_ctx *gcm_ctx = + (struct aead_aes_gcm_tls13_ctx *) &ctx->state; + + gcm_ctx->min_next_nonce = 0; + gcm_ctx->first = 1; + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + return 0; + } + + ctx->tag_len = actual_tag_len; + return 1; +} + +static int aead_aes_gcm_tls13_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + struct aead_aes_gcm_tls13_ctx *gcm_ctx = + (struct aead_aes_gcm_tls13_ctx *) &ctx->state; + + if (nonce_len != AES_GCM_NONCE_LENGTH) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // The given nonces must be strictly monotonically increasing. See + // https://tools.ietf.org/html/rfc8446#section-5.3 for details of the TLS 1.3 + // nonce construction. + uint64_t given_counter; + OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), + sizeof(given_counter)); + given_counter = CRYPTO_bswap8(given_counter); + + if (gcm_ctx->first) { + // In the first call the sequence number will be zero and therefore the + // given nonce will be 0 ^ mask = mask. + gcm_ctx->mask = given_counter; + gcm_ctx->first = 0; + } + given_counter ^= gcm_ctx->mask; + + if (given_counter == UINT64_MAX || + given_counter < gcm_ctx->min_next_nonce) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); + return 0; + } + + gcm_ctx->min_next_nonce = given_counter + 1; + + return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, + in_len, extra_in, extra_in_len, ad, ad_len); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls13) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls13_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_tls13_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls13) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = AES_GCM_NONCE_LENGTH; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls13_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_tls13_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +int EVP_has_aes_hardware(void) { +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + return hwaes_capable() && crypto_gcm_clmul_enabled(); +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable(); +#elif defined(OPENSSL_PPC64LE) + return CRYPTO_is_PPC64LE_vcrypto_capable(); +#else + return 0; +#endif +} + +OPENSSL_MSVC_PRAGMA(warning(pop)) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/internal.h new file mode 100644 index 00000000..f52fca98 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/internal.h @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CIPHER_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_INTERNAL_H + +#include + +#include +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_CIPH_MODE_MASK contains the bits of |flags| that represent the mode. +#define EVP_CIPH_MODE_MASK 0x3f + +// EVP_AEAD represents a specific AEAD algorithm. +struct evp_aead_st { + uint8_t key_len; + uint8_t nonce_len; + uint8_t overhead; + uint8_t max_tag_len; + int seal_scatter_supports_extra_in; + + // init initialises an |EVP_AEAD_CTX|. If this call returns zero then + // |cleanup| will not be called for that context. + int (*init)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len); + int (*init_with_direction)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + void (*cleanup)(EVP_AEAD_CTX *); + + int (*open)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len); + + int (*seal_scatter)(const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len); + + int (*open_gather)(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len); + + int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len); + + size_t (*tag_len)(const EVP_AEAD_CTX *ctx, size_t in_Len, + size_t extra_in_len); +}; + +// aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, +// where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is +// set to a function that encrypts single blocks. If not NULL, |*gcm_key| is +// initialised to do GHASH with the given key. It returns a function for +// optimised CTR-mode, or NULL if CTR-mode should be built using |*out_block|. +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, + block128_f *out_block, const uint8_t *key, + size_t key_bytes); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S new file mode 100644 index 00000000..5bfa33ab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S @@ -0,0 +1,1273 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl bn_mul_comba8 +.hidden bn_mul_comba8 +.type bn_mul_comba8,@function +.align 16 +bn_mul_comba8: +.L_bn_mul_comba8_begin: + pushl %esi + movl 12(%esp),%esi + pushl %edi + movl 20(%esp),%edi + pushl %ebp + pushl %ebx + xorl %ebx,%ebx + movl (%esi),%eax + xorl %ecx,%ecx + movl (%edi),%edx + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,(%eax) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,4(%eax) + movl 8(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,8(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,12(%eax) + movl 16(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,16(%eax) + movl 20(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 12(%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 16(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,20(%eax) + movl 24(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 16(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 12(%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 16(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 20(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,24(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 16(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 20(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 24(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + movl %ecx,28(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 24(%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 16(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 12(%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 24(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 28(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + movl %ebp,32(%eax) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 24(%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 16(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 16(%esi),%eax + adcl %edx,%ecx + movl 20(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 12(%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 28(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + movl %ebx,36(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esi),%eax + adcl %edx,%ebp + movl 20(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 16(%esi),%eax + adcl %edx,%ebp + movl 24(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + movl %ecx,40(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 24(%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esi),%eax + adcl %edx,%ebx + movl 24(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 28(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + movl %ebp,44(%eax) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 24(%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 28(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + movl %ebx,48(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + movl %ecx,52(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + adcl $0,%ecx + movl %ebp,56(%eax) + + + movl %ebx,60(%eax) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_mul_comba8,.-.L_bn_mul_comba8_begin +.globl bn_mul_comba4 +.hidden bn_mul_comba4 +.type bn_mul_comba4,@function +.align 16 +bn_mul_comba4: +.L_bn_mul_comba4_begin: + pushl %esi + movl 12(%esp),%esi + pushl %edi + movl 20(%esp),%edi + pushl %ebp + pushl %ebx + xorl %ebx,%ebx + movl (%esi),%eax + xorl %ecx,%ecx + movl (%edi),%edx + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,(%eax) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,4(%eax) + movl 8(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,8(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + movl %ebx,12(%eax) + movl 12(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + movl %ecx,16(%eax) + movl 12(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + movl %ebp,20(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + adcl $0,%ebp + movl %ebx,24(%eax) + + + movl %ecx,28(%eax) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_mul_comba4,.-.L_bn_mul_comba4_begin +.globl bn_sqr_comba8 +.hidden bn_sqr_comba8 +.type bn_sqr_comba8,@function +.align 16 +bn_sqr_comba8: +.L_bn_sqr_comba8_begin: + pushl %esi + pushl %edi + pushl %ebp + pushl %ebx + movl 20(%esp),%edi + movl 24(%esp),%esi + xorl %ebx,%ebx + xorl %ecx,%ecx + movl (%esi),%eax + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,(%edi) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + movl %ecx,4(%edi) + movl (%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 4(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl (%esi),%edx + adcl $0,%ecx + movl %ebp,8(%edi) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 8(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 16(%esi),%eax + adcl $0,%ebp + movl %ebx,12(%edi) + movl (%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 12(%esi),%eax + adcl $0,%ebx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl (%esi),%edx + adcl $0,%ebx + movl %ecx,16(%edi) + movl 20(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 16(%esi),%eax + adcl $0,%ecx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 12(%esi),%eax + adcl $0,%ecx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl %ebp,20(%edi) + movl (%esi),%edx + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 20(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 16(%esi),%eax + adcl $0,%ebp + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 12(%esi),%eax + adcl $0,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,24(%edi) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 24(%esi),%eax + adcl $0,%ebx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 20(%esi),%eax + adcl $0,%ebx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 16(%esi),%eax + adcl $0,%ebx + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 28(%esi),%eax + adcl $0,%ebx + movl %ecx,28(%edi) + movl 4(%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 20(%esi),%eax + adcl $0,%ecx + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 16(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl 8(%esi),%edx + adcl $0,%ecx + movl %ebp,32(%edi) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%eax + adcl $0,%ebp + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 20(%esi),%eax + adcl $0,%ebp + movl 16(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 28(%esi),%eax + adcl $0,%ebp + movl %ebx,36(%edi) + movl 12(%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 24(%esi),%eax + adcl $0,%ebx + movl 16(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 20(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl 16(%esi),%edx + adcl $0,%ebx + movl %ecx,40(%edi) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl 20(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 28(%esi),%eax + adcl $0,%ecx + movl %ebp,44(%edi) + movl 20(%esi),%edx + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%eax + adcl $0,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%edx + adcl $0,%ebp + movl %ebx,48(%edi) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 28(%esi),%eax + adcl $0,%ebx + movl %ecx,52(%edi) + + + xorl %ecx,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + adcl $0,%ecx + movl %ebp,56(%edi) + + movl %ebx,60(%edi) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_sqr_comba8,.-.L_bn_sqr_comba8_begin +.globl bn_sqr_comba4 +.hidden bn_sqr_comba4 +.type bn_sqr_comba4,@function +.align 16 +bn_sqr_comba4: +.L_bn_sqr_comba4_begin: + pushl %esi + pushl %edi + pushl %ebp + pushl %ebx + movl 20(%esp),%edi + movl 24(%esp),%esi + xorl %ebx,%ebx + xorl %ecx,%ecx + movl (%esi),%eax + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,(%edi) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + movl %ecx,4(%edi) + movl (%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 4(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl (%esi),%edx + adcl $0,%ecx + movl %ebp,8(%edi) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 8(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 12(%esi),%eax + adcl $0,%ebp + movl %ebx,12(%edi) + movl 4(%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%edx + adcl $0,%ebx + movl %ecx,16(%edi) + movl 12(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 12(%esi),%eax + adcl $0,%ecx + movl %ebp,20(%edi) + + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + adcl $0,%ebp + movl %ebx,24(%edi) + + movl %ecx,28(%edi) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_sqr_comba4,.-.L_bn_sqr_comba4_begin +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/delocate.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/delocate.h new file mode 100644 index 00000000..1bb0e4d0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/delocate.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_FIPSMODULE_DELOCATE_H +#define OPENSSL_HEADER_FIPSMODULE_DELOCATE_H + +#include + +#include "../internal.h" + + +#if !defined(BORINGSSL_SHARED_LIBRARY) && defined(BORINGSSL_FIPS) && \ + !defined(OPENSSL_ASAN) && !defined(OPENSSL_MSAN) +#define DEFINE_BSS_GET(type, name) \ + static type name __attribute__((used)); \ + type *name##_bss_get(void) __attribute__((const)); +// For FIPS builds we require that CRYPTO_ONCE_INIT be zero. +#define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name) +// For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero. +#define DEFINE_STATIC_MUTEX(name) \ + DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name) +// For FIPS builds we require that CRYPTO_EX_DATA_CLASS_INIT be zero. +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + DEFINE_BSS_GET(CRYPTO_EX_DATA_CLASS, name) +#else +#define DEFINE_BSS_GET(type, name) \ + static type name; \ + static type *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_ONCE(name) \ + static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \ + static CRYPTO_once_t *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_MUTEX(name) \ + static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \ + static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + static CRYPTO_EX_DATA_CLASS name = CRYPTO_EX_DATA_CLASS_INIT; \ + static CRYPTO_EX_DATA_CLASS *name##_bss_get(void) { return &name; } +#endif + +#define DEFINE_DATA(type, name, accessor_decorations) \ + DEFINE_BSS_GET(type, name##_storage) \ + DEFINE_STATIC_ONCE(name##_once) \ + static void name##_do_init(type *out); \ + static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \ + accessor_decorations type *name(void) { \ + CRYPTO_once(name##_once_bss_get(), name##_init); \ + /* See http://c-faq.com/ansi/constmismatch.html for why the following \ + * cast is needed. */ \ + return (const type *)name##_storage_bss_get(); \ + } \ + static void name##_do_init(type *out) + +// DEFINE_METHOD_FUNCTION defines a function named |name| which returns a +// method table of type const |type|*. In FIPS mode, to avoid rel.ro data, it +// is split into a CRYPTO_once_t-guarded initializer in the module and +// unhashed, non-module accessor functions to space reserved in the BSS. The +// method table is initialized by a caller-supplied function which takes a +// parameter named |out| of type |type|*. The caller should follow the macro +// invocation with the body of this function: +// +// DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { +// out->type = NID_md4; +// out->md_size = MD4_DIGEST_LENGTH; +// out->flags = 0; +// out->init = md4_init; +// out->update = md4_update; +// out->final = md4_final; +// out->block_size = 64; +// out->ctx_size = sizeof(MD4_CTX); +// } +// +// This mechanism does not use a static initializer because their execution +// order is undefined. See FIPS.md for more details. +#define DEFINE_METHOD_FUNCTION(type, name) DEFINE_DATA(type, name, const) + +#define DEFINE_LOCAL_DATA(type, name) DEFINE_DATA(type, name, static const) + +#endif // OPENSSL_HEADER_FIPSMODULE_DELOCATE_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/check.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/check.c new file mode 100644 index 00000000..9adaa79f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/check.c @@ -0,0 +1,217 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) { + *out_flags = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + BN_CTX_start(ctx); + + int ok = 0; + + // Check |pub_key| is greater than 1. + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_set_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) <= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_SMALL; + } + + // Check |pub_key| is less than |dh->p| - 1. + if (!BN_copy(tmp, dh->p) || + !BN_sub_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) >= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE; + } + + if (dh->q != NULL) { + // Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114 + // groups which are not safe primes but pick a generator on a prime-order + // subgroup of size |dh->q|. + if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(tmp)) { + *out_flags |= DH_CHECK_PUBKEY_INVALID; + } + } + + ok = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} + + +int DH_check(const DH *dh, int *out_flags) { + // Check that p is a safe prime and if g is 2, 3 or 5, check that it is a + // suitable generator where: + // for 2, p mod 24 == 11 + // for 3, p mod 12 == 5 + // for 5, p mod 10 == 3 or 7 + // should hold. + int ok = 0, r; + BN_CTX *ctx = NULL; + BN_ULONG l; + BIGNUM *t1 = NULL, *t2 = NULL; + + *out_flags = 0; + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + if (t1 == NULL) { + goto err; + } + t2 = BN_CTX_get(ctx); + if (t2 == NULL) { + goto err; + } + + if (dh->q) { + if (BN_cmp(dh->g, BN_value_one()) <= 0) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else if (BN_cmp(dh->g, dh->p) >= 0) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else { + // Check g^q == 1 mod p + if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(t1)) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } + r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_Q_NOT_PRIME; + } + // Check p == 1 mod q i.e. q divides p - 1 + if (!BN_div(t1, t2, dh->p, dh->q, ctx)) { + goto err; + } + if (!BN_is_one(t2)) { + *out_flags |= DH_CHECK_INVALID_Q_VALUE; + } + if (dh->j && BN_cmp(dh->j, t1)) { + *out_flags |= DH_CHECK_INVALID_J_VALUE; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { + l = BN_mod_word(dh->p, 24); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 11) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { + l = BN_mod_word(dh->p, 10); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 3 && l != 7) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else { + *out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR; + } + + r = BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_PRIME; + } else if (!dh->q) { + if (!BN_rshift1(t1, dh->p)) { + goto err; + } + r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME; + } + } + ok = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c new file mode 100644 index 00000000..64a5528b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c @@ -0,0 +1,468 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../bn/internal.h" + + +#define OPENSSL_DH_MAX_MODULUS_BITS 10000 + +DH *DH_new(void) { + DH *dh = OPENSSL_malloc(sizeof(DH)); + if (dh == NULL) { + OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dh, 0, sizeof(DH)); + + CRYPTO_MUTEX_init(&dh->method_mont_p_lock); + + dh->references = 1; + + return dh; +} + +void DH_free(DH *dh) { + if (dh == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) { + return; + } + + BN_MONT_CTX_free(dh->method_mont_p); + BN_clear_free(dh->p); + BN_clear_free(dh->g); + BN_clear_free(dh->q); + BN_clear_free(dh->j); + OPENSSL_free(dh->seed); + BN_clear_free(dh->counter); + BN_clear_free(dh->pub_key); + BN_clear_free(dh->priv_key); + CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); + + OPENSSL_free(dh); +} + +const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; } + +const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; } + +const BIGNUM *DH_get0_p(const DH *dh) { return dh->p; } + +const BIGNUM *DH_get0_q(const DH *dh) { return dh->q; } + +const BIGNUM *DH_get0_g(const DH *dh) { return dh->g; } + +void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dh->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dh->priv_key; + } +} + +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; +} + +void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dh->p; + } + if (out_q != NULL) { + *out_q = dh->q; + } + if (out_g != NULL) { + *out_g = dh->g; + } +} + +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if ((dh->p == NULL && p == NULL) || + (dh->g == NULL && g == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + return 1; +} + +int DH_set_length(DH *dh, unsigned priv_length) { + dh->priv_length = priv_length; + return 1; +} + +int DH_generate_key(DH *dh) { + boringssl_ensure_ffdh_self_test(); + + int ok = 0; + int generate_new_key = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + if (dh->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) { + goto err; + } + generate_new_key = 1; + } else { + priv_key = dh->priv_key; + } + + if (dh->pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) { + goto err; + } + } else { + pub_key = dh->pub_key; + } + + if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (generate_new_key) { + if (dh->q) { + if (!BN_rand_range_ex(priv_key, 2, dh->q)) { + goto err; + } + } else { + // secret exponent length + unsigned priv_bits = dh->priv_length; + if (priv_bits == 0) { + const unsigned p_bits = BN_num_bits(dh->p); + if (p_bits == 0) { + goto err; + } + + priv_bits = p_bits - 1; + } + + if (!BN_rand(priv_key, priv_bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) { + goto err; + } + } + } + + if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx, + dh->method_mont_p)) { + goto err; + } + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + +err: + if (ok != 1) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (dh->pub_key == NULL) { + BN_free(pub_key); + } + if (dh->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + return ok; +} + +static int dh_compute_key(DH *dh, BIGNUM *out_shared_key, + const BIGNUM *peers_key, BN_CTX *ctx) { + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + return 0; + } + + if (dh->priv_key == NULL) { + OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE); + return 0; + } + + int check_result; + if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) { + OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); + return 0; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *p_minus_1 = BN_CTX_get(ctx); + + if (!p_minus_1 || + !BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (!BN_mod_exp_mont_consttime(out_shared_key, peers_key, dh->priv_key, dh->p, + ctx, dh->method_mont_p) || + !BN_copy(p_minus_1, dh->p) || + !BN_sub_word(p_minus_1, 1)) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + goto err; + } + + // This performs the check required by SP 800-56Ar3 section 5.7.1.1 step two. + if (BN_cmp_word(out_shared_key, 1) <= 0 || + BN_cmp(out_shared_key, p_minus_1) == 0) { + OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +int dh_compute_key_padded_no_self_test(unsigned char *out, + const BIGNUM *peers_key, DH *dh) { + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return -1; + } + BN_CTX_start(ctx); + + int dh_size = DH_size(dh); + int ret = -1; + BIGNUM *shared_key = BN_CTX_get(ctx); + if (shared_key && + dh_compute_key(dh, shared_key, peers_key, ctx) && + BN_bn2bin_padded(out, dh_size, shared_key)) { + ret = dh_size; + } + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + +int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + boringssl_ensure_ffdh_self_test(); + + return dh_compute_key_padded_no_self_test(out, peers_key, dh); +} + +int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + boringssl_ensure_ffdh_self_test(); + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return -1; + } + BN_CTX_start(ctx); + + int ret = -1; + BIGNUM *shared_key = BN_CTX_get(ctx); + if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) { + ret = BN_bn2bin(shared_key, out); + } + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + +int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, + size_t max_out_len, const BIGNUM *peers_key, + const EVP_MD *digest) { + *out_len = (size_t)-1; + + const size_t digest_len = EVP_MD_size(digest); + if (digest_len > max_out_len) { + return 0; + } + + int ret = 0; + const size_t dh_len = DH_size(dh); + uint8_t *shared_bytes = OPENSSL_malloc(dh_len); + unsigned out_len_unsigned; + if (!shared_bytes || + // SP 800-56A is ambiguous about whether the output should be padded prior + // to revision three. But revision three, section C.1, awkwardly specifies + // padding to the length of p. + // + // Also, padded output avoids side-channels, so is always strongly + // advisable. + DH_compute_key_padded(shared_bytes, peers_key, dh) != (int)dh_len || + !EVP_Digest(shared_bytes, dh_len, out, &out_len_unsigned, digest, NULL) || + out_len_unsigned != digest_len) { + goto err; + } + + *out_len = digest_len; + ret = 1; + + err: + OPENSSL_free(shared_bytes); + return ret; +} + +int DH_size(const DH *dh) { return BN_num_bytes(dh->p); } + +unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } + +int DH_up_ref(DH *dh) { + CRYPTO_refcount_inc(&dh->references); + return 1; +} + +DH *DH_get_rfc7919_2048(void) { + // This is the prime from https://tools.ietf.org/html/rfc7919#appendix-A.1, + // which is specifically approved for FIPS in appendix D of SP 800-56Ar3. + static const BN_ULONG kFFDHE2048Data[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0x886b4238, 0x61285c97), + TOBN(0xc6f34a26, 0xc1b2effa), TOBN(0xc58ef183, 0x7d1683b2), + TOBN(0x3bb5fcbc, 0x2ec22005), TOBN(0xc3fe3b1b, 0x4c6fad73), + TOBN(0x8e4f1232, 0xeef28183), TOBN(0x9172fe9c, 0xe98583ff), + TOBN(0xc03404cd, 0x28342f61), TOBN(0x9e02fce1, 0xcdf7e2ec), + TOBN(0x0b07a7c8, 0xee0a6d70), TOBN(0xae56ede7, 0x6372bb19), + TOBN(0x1d4f42a3, 0xde394df4), TOBN(0xb96adab7, 0x60d7f468), + TOBN(0xd108a94b, 0xb2c8e3fb), TOBN(0xbc0ab182, 0xb324fb61), + TOBN(0x30acca4f, 0x483a797a), TOBN(0x1df158a1, 0x36ade735), + TOBN(0xe2a689da, 0xf3efe872), TOBN(0x984f0c70, 0xe0e68b77), + TOBN(0xb557135e, 0x7f57c935), TOBN(0x85636555, 0x3ded1af3), + TOBN(0x2433f51f, 0x5f066ed0), TOBN(0xd3df1ed5, 0xd5fd6561), + TOBN(0xf681b202, 0xaec4617a), TOBN(0x7d2fe363, 0x630c75d8), + TOBN(0xcc939dce, 0x249b3ef9), TOBN(0xa9e13641, 0x146433fb), + TOBN(0xd8b9c583, 0xce2d3695), TOBN(0xafdc5620, 0x273d3cf1), + TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff), + }; + + BIGNUM *const ffdhe2048_p = BN_new(); + BIGNUM *const ffdhe2048_q = BN_new(); + BIGNUM *const ffdhe2048_g = BN_new(); + DH *const dh = DH_new(); + + if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) { + goto err; + } + + bn_set_static_words(ffdhe2048_p, kFFDHE2048Data, + OPENSSL_ARRAY_SIZE(kFFDHE2048Data)); + + if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) || + !BN_set_word(ffdhe2048_g, 2) || + !DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) { + goto err; + } + + return dh; + + err: + BN_free(ffdhe2048_p); + BN_free(ffdhe2048_q); + BN_free(ffdhe2048_g); + DH_free(dh); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/internal.h new file mode 100644 index 00000000..68867956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/dh/internal.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// dh_compute_key_padded_no_self_test does the same as |DH_compute_key_padded|, +// but doesn't try to run the self-test first. This is for use in the self tests +// themselves, to prevent an infinite loop. +int dh_compute_key_padded_no_self_test(unsigned char *out, + const BIGNUM *peers_key, DH *dh); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c new file mode 100644 index 00000000..70104172 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c @@ -0,0 +1,287 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +int EVP_MD_type(const EVP_MD *md) { return md->type; } + +int EVP_MD_nid(const EVP_MD *md) { return EVP_MD_type(md); } + +uint32_t EVP_MD_flags(const EVP_MD *md) { return md->flags; } + +size_t EVP_MD_size(const EVP_MD *md) { return md->md_size; } + +size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } + + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) { + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + + if (ctx) { + EVP_MD_CTX_init(ctx); + } + + return ctx; +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } + +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { + OPENSSL_free(ctx->md_data); + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + if (ctx->pctx_ops) { + ctx->pctx_ops->free(ctx->pctx); + } + + EVP_MD_CTX_init(ctx); + + return 1; +} + +void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx) { + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + EVP_MD_CTX_cleanup(ctx); +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { + if (!ctx) { + return; + } + + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); } + +int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, size_t len) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} + +uint32_t EVP_MD_meth_get_flags(const EVP_MD *md) { return EVP_MD_flags(md); } + +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) {} + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + // |in->digest| may be NULL if this is a signing |EVP_MD_CTX| for, e.g., + // Ed25519 which does not hash with |EVP_MD_CTX|. + if (in == NULL || (in->pctx == NULL && in->digest == NULL)) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_PKEY_CTX *pctx = NULL; + assert(in->pctx == NULL || in->pctx_ops != NULL); + if (in->pctx) { + pctx = in->pctx_ops->dup(in->pctx); + if (!pctx) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + uint8_t *tmp_buf = NULL; + if (in->digest != NULL) { + if (out->digest != in->digest) { + assert(in->digest->ctx_size != 0); + tmp_buf = OPENSSL_malloc(in->digest->ctx_size); + if (tmp_buf == NULL) { + if (pctx) { + in->pctx_ops->free(pctx); + } + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + // |md_data| will be the correct size in this case. It's removed from + // |out| so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's + // reused. + tmp_buf = out->md_data; + out->md_data = NULL; + } + } + + EVP_MD_CTX_cleanup(out); + + out->digest = in->digest; + out->md_data = tmp_buf; + if (in->digest != NULL) { + OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); + } + out->pctx = pctx; + out->pctx_ops = in->pctx_ops; + assert(out->pctx == NULL || out->pctx_ops != NULL); + + return 1; +} + +void EVP_MD_CTX_move(EVP_MD_CTX *out, EVP_MD_CTX *in) { + EVP_MD_CTX_cleanup(out); + // While not guaranteed, |EVP_MD_CTX| is currently safe to move with |memcpy|. + OPENSSL_memcpy(out, in, sizeof(EVP_MD_CTX)); + EVP_MD_CTX_init(in); +} + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + EVP_MD_CTX_init(out); + return EVP_MD_CTX_copy_ex(out, in); +} + +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { + EVP_MD_CTX_cleanup(ctx); + EVP_MD_CTX_init(ctx); + return 1; +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { + if (ctx->digest != type) { + assert(type->ctx_size != 0); + uint8_t *md_data = OPENSSL_malloc(type->ctx_size); + if (md_data == NULL) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(ctx->md_data); + ctx->md_data = md_data; + ctx->digest = type; + } + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + + ctx->digest->init(ctx); + return 1; +} + +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + EVP_MD_CTX_init(ctx); + return EVP_DigestInit_ex(ctx, type, NULL); +} + +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + ctx->digest->update(ctx, data, len); + return 1; +} + +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) { + assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ctx->digest->final(ctx, md_out); + if (size != NULL) { + *size = ctx->digest->md_size; + } + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + return 1; +} + +int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) { + (void)EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return 1; +} + +int EVP_Digest(const void *data, size_t count, uint8_t *out_md, + unsigned int *out_size, const EVP_MD *type, ENGINE *impl) { + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + ret = EVP_DigestInit_ex(&ctx, type, impl) && + EVP_DigestUpdate(&ctx, data, count) && + EVP_DigestFinal_ex(&ctx, out_md, out_size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { + if (ctx == NULL) { + return NULL; + } + return ctx->digest; +} + +size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) { + return EVP_MD_size(EVP_MD_CTX_md(ctx)); +} + +size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) { + return EVP_MD_block_size(EVP_MD_CTX_md(ctx)); +} + +int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) { + return EVP_MD_type(EVP_MD_CTX_md(ctx)); +} + +int EVP_add_digest(const EVP_MD *digest) { + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digests.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digests.c new file mode 100644 index 00000000..fcc5d9e9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digests.c @@ -0,0 +1,304 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + +#if defined(NDEBUG) +#define CHECK(x) (void) (x) +#else +#define CHECK(x) assert(x) +#endif + + +static void md4_init(EVP_MD_CTX *ctx) { + CHECK(MD4_Init(ctx->md_data)); +} + +static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD4_Update(ctx->md_data, data, count)); +} + +static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD4_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { + out->type = NID_md4; + out->md_size = MD4_DIGEST_LENGTH; + out->flags = 0; + out->init = md4_init; + out->update = md4_update; + out->final = md4_final; + out->block_size = 64; + out->ctx_size = sizeof(MD4_CTX); +} + + +static void md5_init(EVP_MD_CTX *ctx) { + CHECK(MD5_Init(ctx->md_data)); +} + +static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD5_Update(ctx->md_data, data, count)); +} + +static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD5_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) { + out->type = NID_md5; + out->md_size = MD5_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_init; + out->update = md5_update; + out->final = md5_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_CTX); +} + + +static void sha1_init(EVP_MD_CTX *ctx) { + CHECK(SHA1_Init(ctx->md_data)); +} + +static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA1_Update(ctx->md_data, data, count)); +} + +static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA1_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { + out->type = NID_sha1; + out->md_size = SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = sha1_init; + out->update = sha1_update; + out->final = sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA_CTX); +} + + +static void sha224_init(EVP_MD_CTX *ctx) { + CHECK(SHA224_Init(ctx->md_data)); +} + +static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA224_Update(ctx->md_data, data, count)); +} + +static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA224_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { + out->type = NID_sha224; + out->md_size = SHA224_DIGEST_LENGTH; + out->flags = 0; + out->init = sha224_init; + out->update = sha224_update; + out->final = sha224_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha256_init(EVP_MD_CTX *ctx) { + CHECK(SHA256_Init(ctx->md_data)); +} + +static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA256_Update(ctx->md_data, data, count)); +} + +static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA256_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { + out->type = NID_sha256; + out->md_size = SHA256_DIGEST_LENGTH; + out->flags = 0; + out->init = sha256_init; + out->update = sha256_update; + out->final = sha256_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha384_init(EVP_MD_CTX *ctx) { + CHECK(SHA384_Init(ctx->md_data)); +} + +static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA384_Update(ctx->md_data, data, count)); +} + +static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA384_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { + out->type = NID_sha384; + out->md_size = SHA384_DIGEST_LENGTH; + out->flags = 0; + out->init = sha384_init; + out->update = sha384_update; + out->final = sha384_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +static void sha512_init(EVP_MD_CTX *ctx) { + CHECK(SHA512_Init(ctx->md_data)); +} + +static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA512_Update(ctx->md_data, data, count)); +} + +static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA512_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { + out->type = NID_sha512; + out->md_size = SHA512_DIGEST_LENGTH; + out->flags = 0; + out->init = sha512_init; + out->update = sha512_update; + out->final = sha512_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +static void sha512_256_init(EVP_MD_CTX *ctx) { + CHECK(SHA512_256_Init(ctx->md_data)); +} + +static void sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA512_256_Update(ctx->md_data, data, count)); +} + +static void sha512_256_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA512_256_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512_256) { + out->type = NID_sha512_256; + out->md_size = SHA512_256_DIGEST_LENGTH; + out->flags = 0; + out->init = sha512_256_init; + out->update = sha512_256_update; + out->final = sha512_256_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +typedef struct { + MD5_CTX md5; + SHA_CTX sha1; +} MD5_SHA1_CTX; + +static void md5_sha1_init(EVP_MD_CTX *md_ctx) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1)); +} + +static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, + size_t count) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Update(&ctx->md5, data, count) && + SHA1_Update(&ctx->sha1, data, count)); +} + +static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Final(out, &ctx->md5) && + SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) { + out->type = NID_md5_sha1; + out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_sha1_init; + out->update = md5_sha1_update; + out->final = md5_sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_SHA1_CTX); +} + +#undef CHECK diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/internal.h new file mode 100644 index 00000000..7dec82dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/internal.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DIGEST_INTERNAL_H +#define OPENSSL_HEADER_DIGEST_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct env_md_st { + // type contains a NID identifing the digest function. (For example, + // NID_md5.) + int type; + + // md_size contains the size, in bytes, of the resulting digest. + unsigned md_size; + + // flags contains the OR of |EVP_MD_FLAG_*| values. + uint32_t flags; + + // init initialises the state in |ctx->md_data|. + void (*init)(EVP_MD_CTX *ctx); + + // update hashes |len| bytes of |data| into the state in |ctx->md_data|. + void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + + // final completes the hash and writes |md_size| bytes of digest to |out|. + void (*final)(EVP_MD_CTX *ctx, uint8_t *out); + + // block_size contains the hash's native block size. + unsigned block_size; + + // ctx_size contains the size, in bytes, of the state of the hash function. + unsigned ctx_size; +}; + +// evp_md_pctx_ops contains function pointers to allow the |pctx| member of +// |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP +// functions. +struct evp_md_pctx_ops { + // free is called when an |EVP_MD_CTX| is being freed and the |pctx| also + // needs to be freed. + void (*free) (EVP_PKEY_CTX *pctx); + + // dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs + // to be copied. + EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx); +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DIGEST_INTERNAL diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/md32_common.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/md32_common.h new file mode 100644 index 00000000..df6dce41 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/digest/md32_common.h @@ -0,0 +1,195 @@ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_DIGEST_MD32_COMMON_H +#define OPENSSL_HEADER_DIGEST_MD32_COMMON_H + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// This is a generic 32-bit "collector" for message digest algorithms. It +// collects input character stream into chunks of 32-bit values and invokes the +// block function that performs the actual hash calculations. +// +// To make use of this mechanism, the hash context should be defined with the +// following parameters. +// +// typedef struct _state_st { +// uint32_t h[ / sizeof(uint32_t)]; +// uint32_t Nl, Nh; +// uint8_t data[]; +// unsigned num; +// ... +// } _CTX; +// +// is the output length of the hash in bytes, before +// any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and +// SHA-512). +// +// |h| is the hash state and is updated by a function of type +// |crypto_md32_block_func|. |data| is the partial unprocessed block and has +// |num| bytes. |Nl| and |Nh| maintain the number of bits processed so far. + +// A crypto_md32_block_func should incorporate |num_blocks| of input from |data| +// into |state|. It is assumed the caller has sized |state| and |data| for the +// hash function. +typedef void (*crypto_md32_block_func)(uint32_t *state, const uint8_t *data, + size_t num_blocks); + +// crypto_md32_update adds |len| bytes from |in| to the digest. |data| must be a +// buffer of length |block_size| with the first |*num| bytes containing a +// partial block. This function combines the partial block with |in| and +// incorporates any complete blocks into the digest state |h|. It then updates +// |data| and |*num| with the new partial block and updates |*Nh| and |*Nl| with +// the data consumed. +static inline void crypto_md32_update(crypto_md32_block_func block_func, + uint32_t *h, uint8_t *data, + size_t block_size, unsigned *num, + uint32_t *Nh, uint32_t *Nl, + const uint8_t *in, size_t len) { + if (len == 0) { + return; + } + + uint32_t l = *Nl + (((uint32_t)len) << 3); + if (l < *Nl) { + // Handle carries. + (*Nh)++; + } + *Nh += (uint32_t)(len >> 29); + *Nl = l; + + size_t n = *num; + if (n != 0) { + if (len >= block_size || len + n >= block_size) { + OPENSSL_memcpy(data + n, in, block_size - n); + block_func(h, data, 1); + n = block_size - n; + in += n; + len -= n; + *num = 0; + // Keep |data| zeroed when unused. + OPENSSL_memset(data, 0, block_size); + } else { + OPENSSL_memcpy(data + n, in, len); + *num += (unsigned)len; + return; + } + } + + n = len / block_size; + if (n > 0) { + block_func(h, in, n); + n *= block_size; + in += n; + len -= n; + } + + if (len != 0) { + *num = (unsigned)len; + OPENSSL_memcpy(data, in, len); + } +} + +// crypto_md32_final incorporates the partial block and trailing length into the +// digest state |h|. The trailing length is encoded in little-endian if +// |is_big_endian| is zero and big-endian otherwise. |data| must be a buffer of +// length |block_size| with the first |*num| bytes containing a partial block. +// |Nh| and |Nl| contain the total number of bits processed. On return, this +// function clears the partial block in |data| and +// |*num|. +// +// This function does not serialize |h| into a final digest. This is the +// responsibility of the caller. +static inline void crypto_md32_final(crypto_md32_block_func block_func, + uint32_t *h, uint8_t *data, + size_t block_size, unsigned *num, + uint32_t Nh, uint32_t Nl, + int is_big_endian) { + // |data| always has room for at least one byte. A full block would have + // been consumed. + size_t n = *num; + assert(n < block_size); + data[n] = 0x80; + n++; + + // Fill the block with zeros if there isn't room for a 64-bit length. + if (n > block_size - 8) { + OPENSSL_memset(data + n, 0, block_size - n); + n = 0; + block_func(h, data, 1); + } + OPENSSL_memset(data + n, 0, block_size - 8 - n); + + // Append a 64-bit length to the block and process it. + if (is_big_endian) { + CRYPTO_store_u32_be(data + block_size - 8, Nh); + CRYPTO_store_u32_be(data + block_size - 4, Nl); + } else { + CRYPTO_store_u32_le(data + block_size - 8, Nl); + CRYPTO_store_u32_le(data + block_size - 4, Nh); + } + block_func(h, data, 1); + *num = 0; + OPENSSL_memset(data, 0, block_size); +} + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DIGEST_MD32_COMMON_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c new file mode 100644 index 00000000..bc4bdc7c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c @@ -0,0 +1,1277 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../bn/internal.h" +#include "../delocate.h" + + +static void ec_point_free(EC_POINT *point, int free_group); + +static const uint8_t kP224Params[6 * 28] = { + // p = 2^224 - 2^96 + 1 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + // a + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, + // b + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4, + // x + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21, + // y + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34, + // order + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D, +}; + +static const uint8_t kP256Params[6 * 32] = { + // p = 2^256 - 2^224 + 2^192 + 2^96 - 1 + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // a + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + // b + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, + // x + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + // y + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, + 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, + // order + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51, +}; + +static const uint8_t kP384Params[6 * 48] = { + // p = 2^384 - 2^128 - 2^96 + 2^32 - 1 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + // a + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + // b + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, + // x + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + // y + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, + 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, + 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, + // order + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73, +}; + +static const uint8_t kP521Params[6 * 66] = { + // p = 2^521 - 1 + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // a + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + // b + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, + // x + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + // y + 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, + 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, + 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, + 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, + // order + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09, +}; + +DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) { + // 1.3.132.0.35 + static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; + out->curves[0].nid = NID_secp521r1; + out->curves[0].oid = kOIDP521; + out->curves[0].oid_len = sizeof(kOIDP521); + out->curves[0].comment = "NIST P-521"; + out->curves[0].param_len = 66; + out->curves[0].params = kP521Params; + out->curves[0].method = EC_GFp_mont_method(); + + // 1.3.132.0.34 + static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; + out->curves[1].nid = NID_secp384r1; + out->curves[1].oid = kOIDP384; + out->curves[1].oid_len = sizeof(kOIDP384); + out->curves[1].comment = "NIST P-384"; + out->curves[1].param_len = 48; + out->curves[1].params = kP384Params; + out->curves[1].method = EC_GFp_mont_method(); + + // 1.2.840.10045.3.1.7 + static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07}; + out->curves[2].nid = NID_X9_62_prime256v1; + out->curves[2].oid = kOIDP256; + out->curves[2].oid_len = sizeof(kOIDP256); + out->curves[2].comment = "NIST P-256"; + out->curves[2].param_len = 32; + out->curves[2].params = kP256Params; + out->curves[2].method = +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) + EC_GFp_nistz256_method(); +#else + EC_GFp_nistp256_method(); +#endif + + // 1.3.132.0.33 + static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21}; + out->curves[3].nid = NID_secp224r1; + out->curves[3].oid = kOIDP224; + out->curves[3].oid_len = sizeof(kOIDP224); + out->curves[3].comment = "NIST P-224"; + out->curves[3].param_len = 28; + out->curves[3].params = kP224Params; + out->curves[3].method = +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + EC_GFp_nistp224_method(); +#else + EC_GFp_mont_method(); +#endif +} + +EC_GROUP *ec_group_new(const EC_METHOD *meth) { + EC_GROUP *ret; + + if (meth == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL); + return NULL; + } + + if (meth->group_init == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EC_GROUP)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); + + ret->references = 1; + ret->meth = meth; + BN_init(&ret->order); + + if (!meth->group_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +static int ec_group_set_generator(EC_GROUP *group, const EC_AFFINE *generator, + const BIGNUM *order) { + assert(group->generator == NULL); + + if (!BN_copy(&group->order, order)) { + return 0; + } + // Store the order in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->order); + + BN_MONT_CTX_free(group->order_mont); + group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL); + if (group->order_mont == NULL) { + return 0; + } + + group->field_greater_than_order = BN_cmp(&group->field, order) > 0; + if (group->field_greater_than_order) { + BIGNUM tmp; + BN_init(&tmp); + int ok = + BN_sub(&tmp, &group->field, order) && + bn_copy_words(group->field_minus_order.words, group->field.width, &tmp); + BN_free(&tmp); + if (!ok) { + return 0; + } + } + + group->generator = EC_POINT_new(group); + if (group->generator == NULL) { + return 0; + } + ec_affine_to_jacobian(group, &group->generator->raw, generator); + assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z)); + + // Avoid a reference cycle. |group->generator| does not maintain an owning + // pointer to |group|. + int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references); + + assert(!is_zero); + (void)is_zero; + return 1; +} + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { + if (BN_num_bytes(p) > EC_MAX_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return NULL; + } + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return NULL; + } + } + + // Historically, |a| and |b| were not required to be fully reduced. + // TODO(davidben): Can this be removed? + EC_GROUP *ret = NULL; + BN_CTX_start(ctx); + BIGNUM *a_reduced = BN_CTX_get(ctx); + BIGNUM *b_reduced = BN_CTX_get(ctx); + if (a_reduced == NULL || b_reduced == NULL || + !BN_nnmod(a_reduced, a, p, ctx) || + !BN_nnmod(b_reduced, b, p, ctx)) { + goto err; + } + + ret = ec_group_new(EC_GFp_mont_method()); + if (ret == NULL || + !ret->meth->group_set_curve(ret, p, a_reduced, b_reduced, ctx)) { + EC_GROUP_free(ret); + ret = NULL; + goto err; + } + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) { + if (group->curve_name != NID_undef || group->generator != NULL || + generator->group != group) { + // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by + // |EC_GROUP_new_curve_GFp| and may only used once on each group. + // |generator| must have been created from |EC_GROUP_new_curve_GFp|, not a + // copy, so that |generator->group->generator| is set correctly. + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (BN_num_bytes(order) > EC_MAX_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + // Require a cofactor of one for custom curves, which implies prime order. + if (!BN_is_one(cofactor)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR); + return 0; + } + + // Require that p < 2×order. This simplifies some ECDSA operations. + // + // Note any curve which did not satisfy this must have been invalid or use a + // tiny prime (less than 17). See the proof in |field_element_to_scalar| in + // the ECDSA implementation. + int ret = 0; + BIGNUM *tmp = BN_new(); + if (tmp == NULL || + !BN_lshift1(tmp, order)) { + goto err; + } + if (BN_cmp(tmp, &group->field) <= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + EC_AFFINE affine; + if (!ec_jacobian_to_affine(group, &affine, &generator->raw) || + !ec_group_set_generator(group, &affine, order)) { + goto err; + } + + ret = 1; + +err: + BN_free(tmp); + return ret; +} + +static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { + EC_GROUP *group = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL; + int ok = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + const unsigned param_len = curve->param_len; + const uint8_t *params = curve->params; + + if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || + !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || + !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) || + !(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + group = ec_group_new(curve->method); + if (group == NULL || + !group->meth->group_set_curve(group, p, a, b, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + + EC_AFFINE G; + EC_FELEM x, y; + if (!ec_felem_from_bytes(group, &x, params + 3 * param_len, param_len) || + !ec_felem_from_bytes(group, &y, params + 4 * param_len, param_len) || + !ec_point_set_affine_coordinates(group, &G, &x, &y)) { + goto err; + } + + if (!ec_group_set_generator(group, &G, order)) { + goto err; + } + + ok = 1; + +err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(order); + return group; +} + +// Built-in groups are allocated lazily and static once allocated. +// TODO(davidben): Make these actually static. https://crbug.com/boringssl/20. +struct built_in_groups_st { + EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES]; +}; +DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups) +DEFINE_STATIC_MUTEX(built_in_groups_lock) + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { + struct built_in_groups_st *groups = built_in_groups_bss_get(); + EC_GROUP **group_ptr = NULL; + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + const struct built_in_curve *curve = NULL; + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + if (curves->curves[i].nid == nid) { + curve = &curves->curves[i]; + group_ptr = &groups->groups[i]; + break; + } + } + + if (curve == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; + } + + CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get()); + EC_GROUP *ret = *group_ptr; + CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get()); + if (ret != NULL) { + return ret; + } + + ret = ec_group_new_from_data(curve); + if (ret == NULL) { + return NULL; + } + + EC_GROUP *to_free = NULL; + CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get()); + if (*group_ptr == NULL) { + *group_ptr = ret; + // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup| + // into no-ops. At this point, |ret| is considered static. + ret->curve_name = nid; + } else { + to_free = ret; + ret = *group_ptr; + } + CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get()); + + EC_GROUP_free(to_free); + return ret; +} + +void EC_GROUP_free(EC_GROUP *group) { + if (group == NULL || + // Built-in curves are static. + group->curve_name != NID_undef || + !CRYPTO_refcount_dec_and_test_zero(&group->references)) { + return; + } + + if (group->meth->group_finish != NULL) { + group->meth->group_finish(group); + } + + ec_point_free(group->generator, 0 /* don't free group */); + BN_free(&group->order); + BN_MONT_CTX_free(group->order_mont); + + OPENSSL_free(group); +} + +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { + if (a == NULL || + // Built-in curves are static. + a->curve_name != NID_undef) { + return (EC_GROUP *)a; + } + + // Groups are logically immutable (but for |EC_GROUP_set_generator| which must + // be called early on), so we simply take a reference. + EC_GROUP *group = (EC_GROUP *)a; + CRYPTO_refcount_inc(&group->references); + return group; +} + +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { + // Note this function returns 0 if equal and non-zero otherwise. + if (a == b) { + return 0; + } + if (a->curve_name != b->curve_name) { + return 1; + } + if (a->curve_name != NID_undef) { + // Built-in curves may be compared by curve name alone. + return 0; + } + + // |a| and |b| are both custom curves. We compare the entire curve + // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes, + // custom curve construction is sadly done in two parts) but otherwise not the + // same object, we consider them always unequal. + return a->meth != b->meth || + a->generator == NULL || + b->generator == NULL || + BN_cmp(&a->order, &b->order) != 0 || + BN_cmp(&a->field, &b->field) != 0 || + !ec_felem_equal(a, &a->a, &b->a) || + !ec_felem_equal(a, &a->b, &b->b) || + !ec_GFp_simple_points_equal(a, &a->generator->raw, &b->generator->raw); +} + +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { + return group->generator; +} + +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) { + assert(!BN_is_zero(&group->order)); + return &group->order; +} + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { + if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) { + return 0; + } + return 1; +} + +int EC_GROUP_order_bits(const EC_GROUP *group) { + return BN_num_bits(&group->order); +} + +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx) { + // All |EC_GROUP|s have cofactor 1. + return BN_set_word(cofactor, 1); +} + +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, + BIGNUM *out_b, BN_CTX *ctx) { + return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b); +} + +int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } + +unsigned EC_GROUP_get_degree(const EC_GROUP *group) { + return BN_num_bits(&group->field); +} + +const char *EC_curve_nid2nist(int nid) { + switch (nid) { + case NID_secp224r1: + return "P-224"; + case NID_X9_62_prime256v1: + return "P-256"; + case NID_secp384r1: + return "P-384"; + case NID_secp521r1: + return "P-521"; + } + return NULL; +} + +int EC_curve_nist2nid(const char *name) { + if (strcmp(name, "P-224") == 0) { + return NID_secp224r1; + } + if (strcmp(name, "P-256") == 0) { + return NID_X9_62_prime256v1; + } + if (strcmp(name, "P-384") == 0) { + return NID_secp384r1; + } + if (strcmp(name, "P-521") == 0) { + return NID_secp521r1; + } + return NID_undef; +} + +EC_POINT *EC_POINT_new(const EC_GROUP *group) { + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + EC_POINT *ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->group = EC_GROUP_dup(group); + ec_GFp_simple_point_init(&ret->raw); + return ret; +} + +static void ec_point_free(EC_POINT *point, int free_group) { + if (!point) { + return; + } + if (free_group) { + EC_GROUP_free(point->group); + } + OPENSSL_free(point); +} + +void EC_POINT_free(EC_POINT *point) { + ec_point_free(point, 1 /* free group */); +} + +void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); } + +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { + if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) { + return 1; + } + ec_GFp_simple_point_copy(&dest->raw, &src->raw); + return 1; +} + +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { + if (a == NULL) { + return NULL; + } + + EC_POINT *ret = EC_POINT_new(group); + if (ret == NULL || + !EC_POINT_copy(ret, a)) { + EC_POINT_free(ret); + return NULL; + } + + return ret; +} + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + ec_GFp_simple_point_set_to_infinity(group, &point->raw); + return 1; +} + +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_is_at_infinity(group, &point->raw); +} + +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_is_on_curve(group, &point->raw); +} + +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + + // Note |EC_POINT_cmp| returns zero for equality and non-zero for inequality. + return ec_GFp_simple_points_equal(group, &a->raw, &b->raw) ? 0 : 1; +} + +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) { + if (group->meth->point_get_affine_coordinates == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + EC_FELEM x_felem, y_felem; + if (!group->meth->point_get_affine_coordinates(group, &point->raw, + x == NULL ? NULL : &x_felem, + y == NULL ? NULL : &y_felem) || + (x != NULL && !ec_felem_to_bignum(group, x, &x_felem)) || + (y != NULL && !ec_felem_to_bignum(group, y, &y_felem))) { + return 0; + } + return 1; +} + +int EC_POINT_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { + return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx); +} + +void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *p) { + out->X = p->X; + out->Y = p->Y; + out->Z = group->one; +} + +int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, + const EC_RAW_POINT *p) { + return group->meth->point_get_affine_coordinates(group, p, &out->X, &out->Y); +} + +int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, + const EC_RAW_POINT *in, size_t num) { + if (group->meth->jacobian_to_affine_batch == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->jacobian_to_affine_batch(group, out, in, num); +} + +int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out, + const EC_FELEM *x, const EC_FELEM *y) { + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + // Check if the point is on the curve. + EC_FELEM lhs, rhs; + felem_sqr(group, &lhs, y); // lhs = y^2 + felem_sqr(group, &rhs, x); // rhs = x^2 + ec_felem_add(group, &rhs, &rhs, &group->a); // rhs = x^2 + a + felem_mul(group, &rhs, &rhs, x); // rhs = x^3 + ax + ec_felem_add(group, &rhs, &rhs, &group->b); // rhs = x^3 + ax + b + if (!ec_felem_equal(group, &lhs, &rhs)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + // In the event of an error, defend against the caller not checking the + // return value by setting a known safe value. Note this may not be possible + // if the caller is in the process of constructing an arbitrary group and + // the generator is missing. + if (group->generator != NULL) { + assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z)); + out->X = group->generator->raw.X; + out->Y = group->generator->raw.Y; + } + return 0; + } + + out->X = *x; + out->Y = *y; + return 1; +} + +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if (x == NULL || y == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + EC_FELEM x_felem, y_felem; + EC_AFFINE affine; + if (!ec_bignum_to_felem(group, &x_felem, x) || + !ec_bignum_to_felem(group, &y_felem, y) || + !ec_point_set_affine_coordinates(group, &affine, &x_felem, &y_felem)) { + // In the event of an error, defend against the caller not checking the + // return value by setting a known safe value. + ec_set_to_safe_point(group, &point->raw); + return 0; + } + + ec_affine_to_jacobian(group, &point->raw, &affine); + return 1; +} + +int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx) { + return EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx); +} + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + group->meth->add(group, &r->raw, &a->raw, &b->raw); + return 1; +} + +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + group->meth->dbl(group, &r->raw, &a->raw); + return 1; +} + + +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + ec_GFp_simple_invert(group, &a->raw); + return 1; +} + +static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in, BN_CTX *ctx) { + if (ec_bignum_to_scalar(group, out, in)) { + return 1; + } + + ERR_clear_error(); + + // This is an unusual input, so we do not guarantee constant-time processing. + const BIGNUM *order = &group->order; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + BN_nnmod(tmp, in, order, ctx) && + ec_bignum_to_scalar(group, out, tmp); + BN_CTX_end(ctx); + return ok; +} + +int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const EC_POINT *p, + const BIGNUM *p_scalar, BN_CTX *ctx) { + // Previously, this function set |r| to the point at infinity if there was + // nothing to multiply. But, nobody should be calling this function with + // nothing to multiply in the first place. + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + int ret = 0; + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + goto err; + } + ctx = new_ctx; + } + + // If both |g_scalar| and |p_scalar| are non-NULL, + // |ec_point_mul_scalar_public| would share the doublings between the two + // products, which would be more efficient. However, we conservatively assume + // the caller needs a constant-time operation. (ECDSA verification does not + // use this function.) + // + // Previously, the low-level constant-time multiplication function aligned + // with this function's calling convention, but this was misleading. Curves + // which combined the two multiplications did not avoid the doubling case + // in the incomplete addition formula and were not constant-time. + + if (g_scalar != NULL) { + EC_SCALAR scalar; + if (!arbitrary_bignum_to_scalar(group, &scalar, g_scalar, ctx) || + !ec_point_mul_scalar_base(group, &r->raw, &scalar)) { + goto err; + } + } + + if (p_scalar != NULL) { + EC_SCALAR scalar; + EC_RAW_POINT tmp; + if (!arbitrary_bignum_to_scalar(group, &scalar, p_scalar, ctx) || + !ec_point_mul_scalar(group, &tmp, &p->raw, &scalar)) { + goto err; + } + if (g_scalar == NULL) { + OPENSSL_memcpy(&r->raw, &tmp, sizeof(EC_RAW_POINT)); + } else { + group->meth->add(group, &r->raw, &r->raw, &tmp); + } + } + + ret = 1; + +err: + BN_CTX_free(new_ctx); + return ret; +} + +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { + boringssl_ensure_ecc_self_test(); + + return ec_point_mul_no_self_test(group, r, g_scalar, p, p_scalar, ctx); +} + +int ec_point_mul_scalar_public(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar) { + if (g_scalar == NULL || p_scalar == NULL || p == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (group->meth->mul_public == NULL) { + return group->meth->mul_public_batch(group, r, g_scalar, p, p_scalar, 1); + } + + group->meth->mul_public(group, r, g_scalar, p, p_scalar); + return 1; +} + +int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *points, + const EC_SCALAR *scalars, size_t num) { + if (group->meth->mul_public_batch == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return group->meth->mul_public_batch(group, r, g_scalar, points, scalars, + num); +} + +int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, const EC_SCALAR *scalar) { + if (p == NULL || scalar == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + group->meth->mul(group, r, p, scalar); + + // Check the result is on the curve to defend against fault attacks or bugs. + // This has negligible cost compared to the multiplication. + if (!ec_GFp_simple_is_on_curve(group, r)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar) { + if (scalar == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + group->meth->mul_base(group, r, scalar); + + // Check the result is on the curve to defend against fault attacks or bugs. + // This has negligible cost compared to the multiplication. + if (!ec_GFp_simple_is_on_curve(group, r)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, + const EC_SCALAR *scalar2) { + if (group->meth->mul_batch == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + group->meth->mul_batch(group, r, p0, scalar0, p1, scalar1, p2, scalar2); + + // Check the result is on the curve to defend against fault attacks or bugs. + // This has negligible cost compared to the multiplication. + if (!ec_GFp_simple_is_on_curve(group, r)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, + const EC_RAW_POINT *p) { + if (group->meth->init_precomp == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return group->meth->init_precomp(group, out, p); +} + +int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_PRECOMP *p0, const EC_SCALAR *scalar0, + const EC_PRECOMP *p1, const EC_SCALAR *scalar1, + const EC_PRECOMP *p2, + const EC_SCALAR *scalar2) { + if (group->meth->mul_precomp == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + group->meth->mul_precomp(group, r, p0, scalar0, p1, scalar1, p2, scalar2); + + // Check the result is on the curve to defend against fault attacks or bugs. + // This has negligible cost compared to the multiplication. + if (!ec_GFp_simple_is_on_curve(group, r)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +void ec_point_select(const EC_GROUP *group, EC_RAW_POINT *out, BN_ULONG mask, + const EC_RAW_POINT *a, const EC_RAW_POINT *b) { + ec_felem_select(group, &out->X, mask, &a->X, &b->X); + ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y); + ec_felem_select(group, &out->Z, mask, &a->Z, &b->Z); +} + +void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask, + const EC_AFFINE *a, const EC_AFFINE *b) { + ec_felem_select(group, &out->X, mask, &a->X, &b->X); + ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y); +} + +void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, + const EC_PRECOMP *a, const EC_PRECOMP *b) { + OPENSSL_STATIC_ASSERT(sizeof(out->comb) == sizeof(*out), + "out->comb does not span the entire structure"); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(out->comb); i++) { + ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]); + } +} + +int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, + const EC_SCALAR *r) { + return group->meth->cmp_x_coordinate(group, p, r); +} + +int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, + const EC_RAW_POINT *p) { + uint8_t bytes[EC_MAX_BYTES]; + size_t len; + if (!ec_get_x_coordinate_as_bytes(group, bytes, &len, sizeof(bytes), p)) { + return 0; + } + + // For simplicity, in case of width mismatches between |group->field| and + // |group->order|, zero any untouched words in |out|. + OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); + for (size_t i = 0; i < len; i++) { + out->bytes[len - i - 1] = bytes[i]; + } + + // We must have p < 2×order, assuming p is not tiny (p >= 17). Thus rather we + // can reduce by performing at most one subtraction. + // + // Proof: We only work with prime order curves, so the number of points on + // the curve is the order. Thus Hasse's theorem gives: + // + // |order - (p + 1)| <= 2×sqrt(p) + // p + 1 - order <= 2×sqrt(p) + // p + 1 - 2×sqrt(p) <= order + // p + 1 - 2×(p/4) < order (p/4 > sqrt(p) for p >= 17) + // p/2 < p/2 + 1 < order + // p < 2×order + // + // Additionally, one can manually check this property for built-in curves. It + // is enforced for legacy custom curves in |EC_GROUP_set_generator|. + + // The above does not guarantee |group->field| is not one word larger than + // |group->order|, so read one extra carry word. + BN_ULONG tmp[EC_MAX_WORDS]; + BN_ULONG carry = + group->order.width < EC_MAX_WORDS ? out->words[group->order.width] : 0; + bn_reduce_once_in_place(out->words, carry, group->order.d, tmp, + group->order.width); + return 1; +} + +int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, size_t max_out, + const EC_RAW_POINT *p) { + size_t len = BN_num_bytes(&group->field); + assert(len <= EC_MAX_BYTES); + if (max_out < len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + EC_FELEM x; + if (!group->meth->point_get_affine_coordinates(group, p, &x, NULL)) { + return 0; + } + + ec_felem_to_bytes(group, out, out_len, &x); + *out_len = len; + return 1; +} + +void ec_set_to_safe_point(const EC_GROUP *group, EC_RAW_POINT *out) { + if (group->generator != NULL) { + ec_GFp_simple_point_copy(out, &group->generator->raw); + } else { + // The generator can be missing if the caller is in the process of + // constructing an arbitrary group. In this case, we give up and use the + // point at infinity. + ec_GFp_simple_point_set_to_infinity(group, out); + } +} + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} + +int EC_GROUP_get_asn1_flag(const EC_GROUP *group) { + return OPENSSL_EC_NAMED_CURVE; +} + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { + // This function exists purely to give callers a way to call + // |EC_METHOD_get_field_type|. cryptography.io crashes if |EC_GROUP_method_of| + // returns NULL, so return some other garbage pointer. + return (const EC_METHOD *)0x12340000; +} + +int EC_METHOD_get_field_type(const EC_METHOD *meth) { + return NID_X9_62_prime_field; +} + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) { + if (form != POINT_CONVERSION_UNCOMPRESSED) { + abort(); + } +} + +size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves) { + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + + for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES; + i++) { + out_curves[i].comment = curves->curves[i].comment; + out_curves[i].nid = curves->curves[i].nid; + } + + return OPENSSL_NUM_BUILT_IN_CURVES; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c new file mode 100644 index 00000000..e5bf7571 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c @@ -0,0 +1,477 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class) + +static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { + EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); + if (wrapped == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR)); + wrapped->bignum.d = wrapped->scalar.words; + wrapped->bignum.width = group->order.width; + wrapped->bignum.dmax = group->order.width; + wrapped->bignum.flags = BN_FLG_STATIC_DATA; + return wrapped; +} + +static void ec_wrapped_scalar_free(EC_WRAPPED_SCALAR *scalar) { + OPENSSL_free(scalar); +} + +EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } + +EC_KEY *EC_KEY_new_method(const ENGINE *engine) { + EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EC_KEY)); + + if (engine) { + ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); + } + if (ret->ecdsa_meth) { + METHOD_ref(ret->ecdsa_meth); + } + + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + + CRYPTO_new_ex_data(&ret->ex_data); + + if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); + if (ret->ecdsa_meth) { + METHOD_unref(ret->ecdsa_meth); + } + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +EC_KEY *EC_KEY_new_by_curve_name(int nid) { + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->group = EC_GROUP_new_by_curve_name(nid); + if (ret->group == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} + +void EC_KEY_free(EC_KEY *r) { + if (r == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) { + return; + } + + if (r->ecdsa_meth) { + if (r->ecdsa_meth->finish) { + r->ecdsa_meth->finish(r); + } + METHOD_unref(r->ecdsa_meth); + } + + EC_GROUP_free(r->group); + EC_POINT_free(r->pub_key); + ec_wrapped_scalar_free(r->priv_key); + + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); + + OPENSSL_free(r); +} + +EC_KEY *EC_KEY_dup(const EC_KEY *src) { + if (src == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + return NULL; + } + + if ((src->group != NULL && + !EC_KEY_set_group(ret, src->group)) || + (src->pub_key != NULL && + !EC_KEY_set_public_key(ret, src->pub_key)) || + (src->priv_key != NULL && + !EC_KEY_set_private_key(ret, EC_KEY_get0_private_key(src)))) { + EC_KEY_free(ret); + return NULL; + } + + ret->enc_flag = src->enc_flag; + ret->conv_form = src->conv_form; + return ret; +} + +int EC_KEY_up_ref(EC_KEY *r) { + CRYPTO_refcount_inc(&r->references); + return 1; +} + +int EC_KEY_is_opaque(const EC_KEY *key) { + return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); +} + +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; } + +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) { + // If |key| already has a group, it is an error to switch to another one. + if (key->group != NULL) { + if (EC_GROUP_cmp(key->group, group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + return 1; + } + + assert(key->priv_key == NULL); + assert(key->pub_key == NULL); + + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return key->group != NULL; +} + +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { + return key->priv_key != NULL ? &key->priv_key->bignum : NULL; +} + +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + EC_WRAPPED_SCALAR *scalar = ec_wrapped_scalar_new(key->group); + if (scalar == NULL) { + return 0; + } + if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + ec_wrapped_scalar_free(scalar); + return 0; + } + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = scalar; + return 1; +} + +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) { + return key->pub_key; +} + +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (pub_key != NULL && EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + EC_POINT_free(key->pub_key); + key->pub_key = EC_POINT_dup(pub_key, key->group); + return (key->pub_key == NULL) ? 0 : 1; +} + +unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) { return key->enc_flag; } + +void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) { + key->enc_flag = flags; +} + +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) { + return key->conv_form; +} + +void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) { + key->conv_form = cform; +} + +int EC_KEY_check_key(const EC_KEY *eckey) { + if (!eckey || !eckey->group || !eckey->pub_key) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + // Test whether the public key is on the elliptic curve. + if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, NULL)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + return 0; + } + + // Check the public and private keys match. + // + // NOTE: this is a FIPS pair-wise consistency check for the ECDH case. See SP + // 800-56Ar3, page 36. + if (eckey->priv_key != NULL) { + EC_RAW_POINT point; + if (!ec_point_mul_scalar_base(eckey->group, &point, + &eckey->priv_key->scalar)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + return 0; + } + if (!ec_GFp_simple_points_equal(eckey->group, &point, + &eckey->pub_key->raw)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); + return 0; + } + } + + return 1; +} + +int EC_KEY_check_fips(const EC_KEY *key) { + if (EC_KEY_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!EC_KEY_check_key(key)) { + return 0; + } + + if (key->priv_key) { + uint8_t data[16] = {0}; + ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key); + if (boringssl_fips_break_test("ECDSA_PWCT")) { + data[0] = ~data[0]; + } + int ok = sig != NULL && + ECDSA_do_verify(data, sizeof(data), sig, key); + ECDSA_SIG_free(sig); + if (!ok) { + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + } + + return 1; +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, + const BIGNUM *y) { + EC_POINT *point = NULL; + int ok = 0; + + if (!key || !key->group || !x || !y) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + point = EC_POINT_new(key->group); + if (point == NULL || + !EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, NULL) || + !EC_KEY_set_public_key(key, point) || + !EC_KEY_check_key(key)) { + goto err; + } + + ok = 1; + +err: + EC_POINT_free(point); + return ok; +} + +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **out_buf, BN_CTX *ctx) { + if (key == NULL || key->pub_key == NULL || key->group == NULL) { + return 0; + } + + const size_t len = + EC_POINT_point2oct(key->group, key->pub_key, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + + uint8_t *buf = OPENSSL_malloc(len); + if (buf == NULL) { + return 0; + } + + if (EC_POINT_point2oct(key->group, key->pub_key, form, buf, len, ctx) != + len) { + OPENSSL_free(buf); + return 0; + } + + *out_buf = buf; + return len; +} + +int EC_KEY_generate_key(EC_KEY *key) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2). + if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + static const uint8_t kDefaultAdditionalData[32] = {0}; + EC_WRAPPED_SCALAR *priv_key = ec_wrapped_scalar_new(key->group); + EC_POINT *pub_key = EC_POINT_new(key->group); + if (priv_key == NULL || pub_key == NULL || + // Generate the private key by testing candidates (FIPS 186-4 B.4.2). + !ec_random_nonzero_scalar(key->group, &priv_key->scalar, + kDefaultAdditionalData) || + !ec_point_mul_scalar_base(key->group, &pub_key->raw, &priv_key->scalar)) { + EC_POINT_free(pub_key); + ec_wrapped_scalar_free(priv_key); + return 0; + } + + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = priv_key; + EC_POINT_free(key->pub_key); + key->pub_key = pub_key; + return 1; +} + +int EC_KEY_generate_key_fips(EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + + if (EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey)) { + return 1; + } + + EC_POINT_free(eckey->pub_key); + ec_wrapped_scalar_free(eckey->priv_key); + eckey->pub_key = NULL; + eckey->priv_key = NULL; + return 0; +} + +int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) { + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} + +void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { + return CRYPTO_get_ex_data(&d->ex_data, idx); +} + +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c new file mode 100644 index 00000000..a0b2e944 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c @@ -0,0 +1,524 @@ +/* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "internal.h" + + +int ec_GFp_mont_group_init(EC_GROUP *group) { + int ok; + + ok = ec_GFp_simple_group_init(group); + group->mont = NULL; + return ok; +} + +void ec_GFp_mont_group_finish(EC_GROUP *group) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + ec_GFp_simple_group_finish(group); +} + +int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + BN_MONT_CTX_free(group->mont); + group->mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + + if (!ec_GFp_simple_group_set_curve(group, p, a, b, ctx)) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + return 0; + } + + return 1; +} + +static void ec_GFp_mont_felem_to_montgomery(const EC_GROUP *group, + EC_FELEM *out, const EC_FELEM *in) { + bn_to_montgomery_small(out->words, in->words, group->field.width, + group->mont); +} + +static void ec_GFp_mont_felem_from_montgomery(const EC_GROUP *group, + EC_FELEM *out, + const EC_FELEM *in) { + bn_from_montgomery_small(out->words, group->field.width, in->words, + group->field.width, group->mont); +} + +static void ec_GFp_mont_felem_inv0(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a) { + bn_mod_inverse0_prime_mont_small(out->words, a->words, group->field.width, + group->mont); +} + +void ec_GFp_mont_felem_mul(const EC_GROUP *group, EC_FELEM *r, + const EC_FELEM *a, const EC_FELEM *b) { + bn_mod_mul_montgomery_small(r->words, a->words, b->words, group->field.width, + group->mont); +} + +void ec_GFp_mont_felem_sqr(const EC_GROUP *group, EC_FELEM *r, + const EC_FELEM *a) { + bn_mod_mul_montgomery_small(r->words, a->words, a->words, group->field.width, + group->mont); +} + +void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, const EC_FELEM *in) { + EC_FELEM tmp; + ec_GFp_mont_felem_from_montgomery(group, &tmp, in); + ec_GFp_simple_felem_to_bytes(group, out, out_len, &tmp); +} + +int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, + const uint8_t *in, size_t len) { + if (!ec_GFp_simple_felem_from_bytes(group, out, in, len)) { + return 0; + } + + ec_GFp_mont_felem_to_montgomery(group, out, out); + return 1; +} + +static void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num) { + // Convert "from" Montgomery form so the value is reduced mod p. + bn_from_montgomery_small(out->words, group->field.width, words, num, + group->mont); + // Convert "to" Montgomery form to remove the R^-1 factor added. + ec_GFp_mont_felem_to_montgomery(group, out, out); + // Convert to Montgomery form to match this implementation's representation. + ec_GFp_mont_felem_to_montgomery(group, out, out); +} + +static void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a, const BN_ULONG *exp, + size_t num_exp) { + bn_mod_exp_mont_small(out->words, a->words, group->field.width, exp, num_exp, + group->mont); +} + +static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, + const EC_RAW_POINT *point, + EC_FELEM *x, EC_FELEM *y) { + if (ec_GFp_simple_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + // Transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3). Note the check above + // ensures |point->Z| is non-zero, so the inverse always exists. + EC_FELEM z1, z2; + ec_GFp_mont_felem_inv0(group, &z2, &point->Z); + ec_GFp_mont_felem_sqr(group, &z1, &z2); + + if (x != NULL) { + ec_GFp_mont_felem_mul(group, x, &point->X, &z1); + } + + if (y != NULL) { + ec_GFp_mont_felem_mul(group, &z1, &z1, &z2); + ec_GFp_mont_felem_mul(group, y, &point->Y, &z1); + } + + return 1; +} + +static int ec_GFp_mont_jacobian_to_affine_batch(const EC_GROUP *group, + EC_AFFINE *out, + const EC_RAW_POINT *in, + size_t num) { + if (num == 0) { + return 1; + } + + // Compute prefix products of all Zs. Use |out[i].X| as scratch space + // to store these values. + out[0].X = in[0].Z; + for (size_t i = 1; i < num; i++) { + ec_GFp_mont_felem_mul(group, &out[i].X, &out[i - 1].X, &in[i].Z); + } + + // Some input was infinity iff the product of all Zs is zero. + if (ec_felem_non_zero_mask(group, &out[num - 1].X) == 0) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + // Invert the product of all Zs. + EC_FELEM zinvprod; + ec_GFp_mont_felem_inv0(group, &zinvprod, &out[num - 1].X); + for (size_t i = num - 1; i < num; i--) { + // Our loop invariant is that |zinvprod| is Z0^-1 * Z1^-1 * ... * Zi^-1. + // Recover Zi^-1 by multiplying by the previous product. + EC_FELEM zinv, zinv2; + if (i == 0) { + zinv = zinvprod; + } else { + ec_GFp_mont_felem_mul(group, &zinv, &zinvprod, &out[i - 1].X); + // Maintain the loop invariant for the next iteration. + ec_GFp_mont_felem_mul(group, &zinvprod, &zinvprod, &in[i].Z); + } + + // Compute affine coordinates: x = X * Z^-2 and y = Y * Z^-3. + ec_GFp_mont_felem_sqr(group, &zinv2, &zinv); + ec_GFp_mont_felem_mul(group, &out[i].X, &in[i].X, &zinv2); + ec_GFp_mont_felem_mul(group, &out[i].Y, &in[i].Y, &zinv2); + ec_GFp_mont_felem_mul(group, &out[i].Y, &out[i].Y, &zinv); + } + + return 1; +} + +void ec_GFp_mont_add(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_RAW_POINT *a, const EC_RAW_POINT *b) { + if (a == b) { + ec_GFp_mont_dbl(group, out, a); + return; + } + + // The method is taken from: + // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl + // + // Coq transcription and correctness proof: + // + // + EC_FELEM x_out, y_out, z_out; + BN_ULONG z1nz = ec_felem_non_zero_mask(group, &a->Z); + BN_ULONG z2nz = ec_felem_non_zero_mask(group, &b->Z); + + // z1z1 = z1z1 = z1**2 + EC_FELEM z1z1; + ec_GFp_mont_felem_sqr(group, &z1z1, &a->Z); + + // z2z2 = z2**2 + EC_FELEM z2z2; + ec_GFp_mont_felem_sqr(group, &z2z2, &b->Z); + + // u1 = x1*z2z2 + EC_FELEM u1; + ec_GFp_mont_felem_mul(group, &u1, &a->X, &z2z2); + + // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 + EC_FELEM two_z1z2; + ec_felem_add(group, &two_z1z2, &a->Z, &b->Z); + ec_GFp_mont_felem_sqr(group, &two_z1z2, &two_z1z2); + ec_felem_sub(group, &two_z1z2, &two_z1z2, &z1z1); + ec_felem_sub(group, &two_z1z2, &two_z1z2, &z2z2); + + // s1 = y1 * z2**3 + EC_FELEM s1; + ec_GFp_mont_felem_mul(group, &s1, &b->Z, &z2z2); + ec_GFp_mont_felem_mul(group, &s1, &s1, &a->Y); + + // u2 = x2*z1z1 + EC_FELEM u2; + ec_GFp_mont_felem_mul(group, &u2, &b->X, &z1z1); + + // h = u2 - u1 + EC_FELEM h; + ec_felem_sub(group, &h, &u2, &u1); + + BN_ULONG xneq = ec_felem_non_zero_mask(group, &h); + + // z_out = two_z1z2 * h + ec_GFp_mont_felem_mul(group, &z_out, &h, &two_z1z2); + + // z1z1z1 = z1 * z1z1 + EC_FELEM z1z1z1; + ec_GFp_mont_felem_mul(group, &z1z1z1, &a->Z, &z1z1); + + // s2 = y2 * z1**3 + EC_FELEM s2; + ec_GFp_mont_felem_mul(group, &s2, &b->Y, &z1z1z1); + + // r = (s2 - s1)*2 + EC_FELEM r; + ec_felem_sub(group, &r, &s2, &s1); + ec_felem_add(group, &r, &r, &r); + + BN_ULONG yneq = ec_felem_non_zero_mask(group, &r); + + // This case will never occur in the constant-time |ec_GFp_mont_mul|. + BN_ULONG is_nontrivial_double = ~xneq & ~yneq & z1nz & z2nz; + if (is_nontrivial_double) { + ec_GFp_mont_dbl(group, out, a); + return; + } + + // I = (2h)**2 + EC_FELEM i; + ec_felem_add(group, &i, &h, &h); + ec_GFp_mont_felem_sqr(group, &i, &i); + + // J = h * I + EC_FELEM j; + ec_GFp_mont_felem_mul(group, &j, &h, &i); + + // V = U1 * I + EC_FELEM v; + ec_GFp_mont_felem_mul(group, &v, &u1, &i); + + // x_out = r**2 - J - 2V + ec_GFp_mont_felem_sqr(group, &x_out, &r); + ec_felem_sub(group, &x_out, &x_out, &j); + ec_felem_sub(group, &x_out, &x_out, &v); + ec_felem_sub(group, &x_out, &x_out, &v); + + // y_out = r(V-x_out) - 2 * s1 * J + ec_felem_sub(group, &y_out, &v, &x_out); + ec_GFp_mont_felem_mul(group, &y_out, &y_out, &r); + EC_FELEM s1j; + ec_GFp_mont_felem_mul(group, &s1j, &s1, &j); + ec_felem_sub(group, &y_out, &y_out, &s1j); + ec_felem_sub(group, &y_out, &y_out, &s1j); + + ec_felem_select(group, &x_out, z1nz, &x_out, &b->X); + ec_felem_select(group, &out->X, z2nz, &x_out, &a->X); + ec_felem_select(group, &y_out, z1nz, &y_out, &b->Y); + ec_felem_select(group, &out->Y, z2nz, &y_out, &a->Y); + ec_felem_select(group, &z_out, z1nz, &z_out, &b->Z); + ec_felem_select(group, &out->Z, z2nz, &z_out, &a->Z); +} + +void ec_GFp_mont_dbl(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a) { + if (group->a_is_minus3) { + // The method is taken from: + // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + // + // Coq transcription and correctness proof: + // + // + EC_FELEM delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; + // delta = z^2 + ec_GFp_mont_felem_sqr(group, &delta, &a->Z); + // gamma = y^2 + ec_GFp_mont_felem_sqr(group, &gamma, &a->Y); + // beta = x*gamma + ec_GFp_mont_felem_mul(group, &beta, &a->X, &gamma); + + // alpha = 3*(x-delta)*(x+delta) + ec_felem_sub(group, &ftmp, &a->X, &delta); + ec_felem_add(group, &ftmp2, &a->X, &delta); + + ec_felem_add(group, &tmptmp, &ftmp2, &ftmp2); + ec_felem_add(group, &ftmp2, &ftmp2, &tmptmp); + ec_GFp_mont_felem_mul(group, &alpha, &ftmp, &ftmp2); + + // x' = alpha^2 - 8*beta + ec_GFp_mont_felem_sqr(group, &r->X, &alpha); + ec_felem_add(group, &fourbeta, &beta, &beta); + ec_felem_add(group, &fourbeta, &fourbeta, &fourbeta); + ec_felem_add(group, &tmptmp, &fourbeta, &fourbeta); + ec_felem_sub(group, &r->X, &r->X, &tmptmp); + + // z' = (y + z)^2 - gamma - delta + ec_felem_add(group, &delta, &gamma, &delta); + ec_felem_add(group, &ftmp, &a->Y, &a->Z); + ec_GFp_mont_felem_sqr(group, &r->Z, &ftmp); + ec_felem_sub(group, &r->Z, &r->Z, &delta); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + ec_felem_sub(group, &r->Y, &fourbeta, &r->X); + ec_felem_add(group, &gamma, &gamma, &gamma); + ec_GFp_mont_felem_sqr(group, &gamma, &gamma); + ec_GFp_mont_felem_mul(group, &r->Y, &alpha, &r->Y); + ec_felem_add(group, &gamma, &gamma, &gamma); + ec_felem_sub(group, &r->Y, &r->Y, &gamma); + } else { + // The method is taken from: + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl + // + // Coq transcription and correctness proof: + // + // + EC_FELEM xx, yy, yyyy, zz; + ec_GFp_mont_felem_sqr(group, &xx, &a->X); + ec_GFp_mont_felem_sqr(group, &yy, &a->Y); + ec_GFp_mont_felem_sqr(group, &yyyy, &yy); + ec_GFp_mont_felem_sqr(group, &zz, &a->Z); + + // s = 2*((x_in + yy)^2 - xx - yyyy) + EC_FELEM s; + ec_felem_add(group, &s, &a->X, &yy); + ec_GFp_mont_felem_sqr(group, &s, &s); + ec_felem_sub(group, &s, &s, &xx); + ec_felem_sub(group, &s, &s, &yyyy); + ec_felem_add(group, &s, &s, &s); + + // m = 3*xx + a*zz^2 + EC_FELEM m; + ec_GFp_mont_felem_sqr(group, &m, &zz); + ec_GFp_mont_felem_mul(group, &m, &group->a, &m); + ec_felem_add(group, &m, &m, &xx); + ec_felem_add(group, &m, &m, &xx); + ec_felem_add(group, &m, &m, &xx); + + // x_out = m^2 - 2*s + ec_GFp_mont_felem_sqr(group, &r->X, &m); + ec_felem_sub(group, &r->X, &r->X, &s); + ec_felem_sub(group, &r->X, &r->X, &s); + + // z_out = (y_in + z_in)^2 - yy - zz + ec_felem_add(group, &r->Z, &a->Y, &a->Z); + ec_GFp_mont_felem_sqr(group, &r->Z, &r->Z); + ec_felem_sub(group, &r->Z, &r->Z, &yy); + ec_felem_sub(group, &r->Z, &r->Z, &zz); + + // y_out = m*(s-x_out) - 8*yyyy + ec_felem_add(group, &yyyy, &yyyy, &yyyy); + ec_felem_add(group, &yyyy, &yyyy, &yyyy); + ec_felem_add(group, &yyyy, &yyyy, &yyyy); + ec_felem_sub(group, &r->Y, &s, &r->X); + ec_GFp_mont_felem_mul(group, &r->Y, &r->Y, &m); + ec_felem_sub(group, &r->Y, &r->Y, &yyyy); + } +} + +static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group, + const EC_RAW_POINT *p, + const EC_SCALAR *r) { + if (!group->field_greater_than_order || + group->field.width != group->order.width) { + // Do not bother optimizing this case. p > order in all commonly-used + // curves. + return ec_GFp_simple_cmp_x_coordinate(group, p, r); + } + + if (ec_GFp_simple_is_at_infinity(group, p)) { + return 0; + } + + // We wish to compare X/Z^2 with r. This is equivalent to comparing X with + // r*Z^2. Note that X and Z are represented in Montgomery form, while r is + // not. + EC_FELEM r_Z2, Z2_mont, X; + ec_GFp_mont_felem_mul(group, &Z2_mont, &p->Z, &p->Z); + // r < order < p, so this is valid. + OPENSSL_memcpy(r_Z2.words, r->words, group->field.width * sizeof(BN_ULONG)); + ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont); + ec_GFp_mont_felem_from_montgomery(group, &X, &p->X); + + if (ec_felem_equal(group, &r_Z2, &X)) { + return 1; + } + + // During signing the x coefficient is reduced modulo the group order. + // Therefore there is a small possibility, less than 1/2^128, that group_order + // < p.x < P. in that case we need not only to compare against |r| but also to + // compare against r+group_order. + if (bn_less_than_words(r->words, group->field_minus_order.words, + group->field.width)) { + // We can ignore the carry because: r + group_order < p < 2^256. + bn_add_words(r_Z2.words, r->words, group->order.d, group->field.width); + ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont); + if (ec_felem_equal(group, &r_Z2, &X)) { + return 1; + } + } + + return 0; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates; + out->jacobian_to_affine_batch = ec_GFp_mont_jacobian_to_affine_batch; + out->add = ec_GFp_mont_add; + out->dbl = ec_GFp_mont_dbl; + out->mul = ec_GFp_mont_mul; + out->mul_base = ec_GFp_mont_mul_base; + out->mul_batch = ec_GFp_mont_mul_batch; + out->mul_public_batch = ec_GFp_mont_mul_public_batch; + out->init_precomp = ec_GFp_mont_init_precomp; + out->mul_precomp = ec_GFp_mont_mul_precomp; + out->felem_mul = ec_GFp_mont_felem_mul; + out->felem_sqr = ec_GFp_mont_felem_sqr; + out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; + out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->felem_reduce = ec_GFp_mont_felem_reduce; + out->felem_exp = ec_GFp_mont_felem_exp; + out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery; + out->scalar_to_montgomery_inv_vartime = + ec_simple_scalar_to_montgomery_inv_vartime; + out->cmp_x_coordinate = ec_GFp_mont_cmp_x_coordinate; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/felem.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/felem.c new file mode 100644 index 00000000..e27a68a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/felem.c @@ -0,0 +1,100 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in) { + uint8_t bytes[EC_MAX_BYTES]; + size_t len = BN_num_bytes(&group->field); + assert(sizeof(bytes) >= len); + if (BN_is_negative(in) || + BN_cmp(in, &group->field) >= 0 || + !BN_bn2bin_padded(bytes, len, in)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + return ec_felem_from_bytes(group, out, bytes, len); +} + +int ec_felem_to_bignum(const EC_GROUP *group, BIGNUM *out, const EC_FELEM *in) { + uint8_t bytes[EC_MAX_BYTES]; + size_t len; + ec_felem_to_bytes(group, bytes, &len, in); + return BN_bin2bn(bytes, len, out) != NULL; +} + +void ec_felem_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, + const EC_FELEM *in) { + group->meth->felem_to_bytes(group, out, out_len, in); +} + +int ec_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, const uint8_t *in, + size_t len) { + return group->meth->felem_from_bytes(group, out, in, len); +} + +void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a) { + // -a is zero if a is zero and p-a otherwise. + BN_ULONG mask = ec_felem_non_zero_mask(group, a); + BN_ULONG borrow = + bn_sub_words(out->words, group->field.d, a->words, group->field.width); + assert(borrow == 0); + (void)borrow; + for (int i = 0; i < group->field.width; i++) { + out->words[i] &= mask; + } +} + +void ec_felem_add(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, + const EC_FELEM *b) { + EC_FELEM tmp; + bn_mod_add_words(out->words, a->words, b->words, group->field.d, tmp.words, + group->field.width); +} + +void ec_felem_sub(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, + const EC_FELEM *b) { + EC_FELEM tmp; + bn_mod_sub_words(out->words, a->words, b->words, group->field.d, tmp.words, + group->field.width); +} + +BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a) { + BN_ULONG mask = 0; + for (int i = 0; i < group->field.width; i++) { + mask |= a->words[i]; + } + return ~constant_time_is_zero_w(mask); +} + +void ec_felem_select(const EC_GROUP *group, EC_FELEM *out, BN_ULONG mask, + const EC_FELEM *a, const EC_FELEM *b) { + bn_select_words(out->words, mask, a->words, b->words, group->field.width); +} + +int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a, + const EC_FELEM *b) { + return CRYPTO_memcmp(a->words, b->words, + group->field.width * sizeof(BN_ULONG)) == 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h new file mode 100644 index 00000000..e05f92d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h @@ -0,0 +1,779 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#ifndef OPENSSL_HEADER_EC_INTERNAL_H +#define OPENSSL_HEADER_EC_INTERNAL_H + +#include + +#include +#include +#include +#include + +#include "../bn/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EC internals. + + +// Cap the size of all field elements and scalars, including custom curves, to +// 66 bytes, large enough to fit secp521r1 and brainpoolP512r1, which appear to +// be the largest fields anyone plausibly uses. +#define EC_MAX_BYTES 66 +#define EC_MAX_WORDS ((EC_MAX_BYTES + BN_BYTES - 1) / BN_BYTES) + +OPENSSL_STATIC_ASSERT(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS, + "bn_*_small functions not usable"); + + +// Scalars. + +// An EC_SCALAR is an integer fully reduced modulo the order. Only the first +// |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP| +// and must not be mixed between groups. +typedef union { + // bytes is the representation of the scalar in little-endian order. + uint8_t bytes[EC_MAX_BYTES]; + BN_ULONG words[EC_MAX_WORDS]; +} EC_SCALAR; + +// ec_bignum_to_scalar converts |in| to an |EC_SCALAR| and writes it to +// |*out|. It returns one on success and zero if |in| is out of range. +OPENSSL_EXPORT int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in); + +// ec_scalar_to_bytes serializes |in| as a big-endian bytestring to |out| and +// sets |*out_len| to the number of bytes written. The number of bytes written +// is |BN_num_bytes(&group->order)|, which is at most |EC_MAX_BYTES|. +OPENSSL_EXPORT void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, const EC_SCALAR *in); + +// ec_scalar_from_bytes deserializes |in| and stores the resulting scalar over +// group |group| to |out|. It returns one on success and zero if |in| is +// invalid. +int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t *in, size_t len); + +// ec_scalar_reduce sets |out| to |words|, reduced modulo the group order. +// |words| must be less than order^2. |num| must be at most twice the width of +// group order. This function treats |words| as secret. +void ec_scalar_reduce(const EC_GROUP *group, EC_SCALAR *out, + const BN_ULONG *words, size_t num); + +// ec_random_nonzero_scalar sets |out| to a uniformly selected random value from +// 1 to |group->order| - 1. It returns one on success and zero on error. +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]); + +// ec_scalar_equal_vartime returns one if |a| and |b| are equal and zero +// otherwise. Both values are treated as public. +int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a, + const EC_SCALAR *b); + +// ec_scalar_is_zero returns one if |a| is zero and zero otherwise. +int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a); + +// ec_scalar_add sets |r| to |a| + |b|. +void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a, + const EC_SCALAR *b); + +// ec_scalar_sub sets |r| to |a| - |b|. +void ec_scalar_sub(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a, + const EC_SCALAR *b); + +// ec_scalar_neg sets |r| to -|a|. +void ec_scalar_neg(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a); + +// ec_scalar_to_montgomery sets |r| to |a| in Montgomery form. +void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a); + +// ec_scalar_to_montgomery sets |r| to |a| converted from Montgomery form. +void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a); + +// ec_scalar_mul_montgomery sets |r| to |a| * |b| where inputs and outputs are +// in Montgomery form. +void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a, const EC_SCALAR *b); + +// ec_scalar_inv0_montgomery sets |r| to |a|^-1 where inputs and outputs are in +// Montgomery form. If |a| is zero, |r| is set to zero. +void ec_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a); + +// ec_scalar_to_montgomery_inv_vartime sets |r| to |a|^-1 R. That is, it takes +// in |a| not in Montgomery form and computes the inverse in Montgomery form. It +// returns one on success and zero if |a| has no inverse. This function assumes +// |a| is public and may leak information about it via timing. +// +// Note this is not the same operation as |ec_scalar_inv0_montgomery|. +int ec_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a); + +// ec_scalar_select, in constant time, sets |out| to |a| if |mask| is all ones +// and |b| if |mask| is all zeros. +void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask, + const EC_SCALAR *a, const EC_SCALAR *b); + + +// Field elements. + +// An EC_FELEM represents a field element. Only the first |field->width| words +// are used. An |EC_FELEM| is specific to an |EC_GROUP| and must not be mixed +// between groups. Additionally, the representation (whether or not elements are +// represented in Montgomery-form) may vary between |EC_METHOD|s. +typedef union { + // bytes is the representation of the field element in little-endian order. + uint8_t bytes[EC_MAX_BYTES]; + BN_ULONG words[EC_MAX_WORDS]; +} EC_FELEM; + +// ec_bignum_to_felem converts |in| to an |EC_FELEM|. It returns one on success +// and zero if |in| is out of range. +int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in); + +// ec_felem_to_bignum converts |in| to a |BIGNUM|. It returns one on success and +// zero on allocation failure. +int ec_felem_to_bignum(const EC_GROUP *group, BIGNUM *out, const EC_FELEM *in); + +// ec_felem_to_bytes serializes |in| as a big-endian bytestring to |out| and +// sets |*out_len| to the number of bytes written. The number of bytes written +// is |BN_num_bytes(&group->order)|, which is at most |EC_MAX_BYTES|. +void ec_felem_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, + const EC_FELEM *in); + +// ec_felem_from_bytes deserializes |in| and stores the resulting field element +// to |out|. It returns one on success and zero if |in| is invalid. +int ec_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, const uint8_t *in, + size_t len); + +// ec_felem_neg sets |out| to -|a|. +void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a); + +// ec_felem_add sets |out| to |a| + |b|. +void ec_felem_add(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, + const EC_FELEM *b); + +// ec_felem_add sets |out| to |a| - |b|. +void ec_felem_sub(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, + const EC_FELEM *b); + +// ec_felem_non_zero_mask returns all ones if |a| is non-zero and all zeros +// otherwise. +BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a); + +// ec_felem_select, in constant time, sets |out| to |a| if |mask| is all ones +// and |b| if |mask| is all zeros. +void ec_felem_select(const EC_GROUP *group, EC_FELEM *out, BN_ULONG mask, + const EC_FELEM *a, const EC_FELEM *b); + +// ec_felem_equal returns one if |a| and |b| are equal and zero otherwise. +int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a, const EC_FELEM *b); + + +// Points. +// +// Points may represented in affine coordinates as |EC_AFFINE| or Jacobian +// coordinates as |EC_RAW_POINT|. Affine coordinates directly represent a +// point on the curve, but point addition over affine coordinates requires +// costly field inversions, so arithmetic is done in Jacobian coordinates. +// Converting from affine to Jacobian is cheap, while converting from Jacobian +// to affine costs a field inversion. (Jacobian coordinates amortize the field +// inversions needed in a sequence of point operations.) +// +// TODO(davidben): Rename |EC_RAW_POINT| to |EC_JACOBIAN|. + +// An EC_RAW_POINT represents an elliptic curve point in Jacobian coordinates. +// Unlike |EC_POINT|, it is a plain struct which can be stack-allocated and +// needs no cleanup. It is specific to an |EC_GROUP| and must not be mixed +// between groups. +typedef struct { + // X, Y, and Z are Jacobian projective coordinates. They represent + // (X/Z^2, Y/Z^3) if Z != 0 and the point at infinity otherwise. + EC_FELEM X, Y, Z; +} EC_RAW_POINT; + +// An EC_AFFINE represents an elliptic curve point in affine coordinates. +// coordinates. Note the point at infinity cannot be represented in affine +// coordinates. +typedef struct { + EC_FELEM X, Y; +} EC_AFFINE; + +// ec_affine_to_jacobian converts |p| to Jacobian form and writes the result to +// |*out|. This operation is very cheap and only costs a few copies. +void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *p); + +// ec_jacobian_to_affine converts |p| to affine form and writes the result to +// |*out|. It returns one on success and zero if |p| was the point at infinity. +// This operation performs a field inversion and should only be done once per +// point. +// +// If only extracting the x-coordinate, use |ec_get_x_coordinate_*| which is +// slightly faster. +int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, + const EC_RAW_POINT *p); + +// ec_jacobian_to_affine_batch converts |num| points in |in| from Jacobian +// coordinates to affine coordinates and writes the results to |out|. It returns +// one on success and zero if any of the input points were infinity. +// +// This function is not implemented for all curves. Add implementations as +// needed. +int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, + const EC_RAW_POINT *in, size_t num); + +// ec_point_set_affine_coordinates sets |out|'s to a point with affine +// coordinates |x| and |y|. It returns one if the point is on the curve and +// zero otherwise. If the point is not on the curve, the value of |out| is +// undefined. +int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out, + const EC_FELEM *x, const EC_FELEM *y); + +// ec_point_mul_no_self_test does the same as |EC_POINT_mul|, but doesn't try to +// run the self-test first. This is for use in the self tests themselves, to +// prevent an infinite loop. +int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const EC_POINT *p, + const BIGNUM *p_scalar, BN_CTX *ctx); + +// ec_point_mul_scalar sets |r| to |p| * |scalar|. Both inputs are considered +// secret. +int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, const EC_SCALAR *scalar); + +// ec_point_mul_scalar_base sets |r| to generator * |scalar|. |scalar| is +// treated as secret. +int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar); + +// ec_point_mul_scalar_batch sets |r| to |p0| * |scalar0| + |p1| * |scalar1| + +// |p2| * |scalar2|. |p2| may be NULL to skip that term. +// +// The inputs are treated as secret, however, this function leaks information +// about whether intermediate computations add a point to itself. Callers must +// ensure that discrete logs between |p0|, |p1|, and |p2| are uniformly +// distributed and independent of the scalars, which should be uniformly +// selected and not under the attackers control. This ensures the doubling case +// will occur with negligible probability. +// +// This function is not implemented for all curves. Add implementations as +// needed. +// +// TODO(davidben): This function does not use base point tables. For now, it is +// only used with the generic |EC_GFp_mont_method| implementation which has +// none. If generalizing to tuned curves, this may be useful. However, we still +// must double up to the least efficient input, so precomputed tables can only +// save table setup and allow a wider window size. +int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); + +#define EC_MONT_PRECOMP_COMB_SIZE 5 + +// An |EC_PRECOMP| stores precomputed information about a point, to optimize +// repeated multiplications involving it. It is a union so different +// |EC_METHOD|s can store different information in it. +typedef union { + EC_AFFINE comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1]; +} EC_PRECOMP; + +// ec_init_precomp precomputes multiples of |p| and writes the result to |out|. +// It returns one on success and zero on error. The resulting table may be used +// with |ec_point_mul_scalar_precomp|. This function will fail if |p| is the +// point at infinity. +// +// This function is not implemented for all curves. Add implementations as +// needed. +int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, + const EC_RAW_POINT *p); + +// ec_point_mul_scalar_precomp sets |r| to |p0| * |scalar0| + |p1| * |scalar1| + +// |p2| * |scalar2|. |p1| or |p2| may be NULL to skip the corresponding term. +// The points are represented as |EC_PRECOMP| and must be initialized with +// |ec_init_precomp|. This function runs faster than |ec_point_mul_scalar_batch| +// but requires setup work per input point, so it is only appropriate for points +// which are used frequently. +// +// The inputs are treated as secret, however, this function leaks information +// about whether intermediate computations add a point to itself. Callers must +// ensure that discrete logs between |p0|, |p1|, and |p2| are uniformly +// distributed and independent of the scalars, which should be uniformly +// selected and not under the attackers control. This ensures the doubling case +// will occur with negligible probability. +// +// This function is not implemented for all curves. Add implementations as +// needed. +// +// TODO(davidben): This function does not use base point tables. For now, it is +// only used with the generic |EC_GFp_mont_method| implementation which has +// none. If generalizing to tuned curves, we should add a parameter for the base +// point and arrange for the generic implementation to have base point tables +// available. +int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_PRECOMP *p0, const EC_SCALAR *scalar0, + const EC_PRECOMP *p1, const EC_SCALAR *scalar1, + const EC_PRECOMP *p2, const EC_SCALAR *scalar2); + +// ec_point_mul_scalar_public sets |r| to +// generator * |g_scalar| + |p| * |p_scalar|. It assumes that the inputs are +// public so there is no concern about leaking their values through timing. +OPENSSL_EXPORT int ec_point_mul_scalar_public(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar); + +// ec_point_mul_scalar_public_batch sets |r| to the sum of generator * +// |g_scalar| and |points[i]| * |scalars[i]| where |points| and |scalars| have +// |num| elements. It assumes that the inputs are public so there is no concern +// about leaking their values through timing. |g_scalar| may be NULL to skip +// that term. +// +// This function is not implemented for all curves. Add implementations as +// needed. +int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *points, + const EC_SCALAR *scalars, size_t num); + +// ec_point_select, in constant time, sets |out| to |a| if |mask| is all ones +// and |b| if |mask| is all zeros. +void ec_point_select(const EC_GROUP *group, EC_RAW_POINT *out, BN_ULONG mask, + const EC_RAW_POINT *a, const EC_RAW_POINT *b); + +// ec_affine_select behaves like |ec_point_select| but acts on affine points. +void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask, + const EC_AFFINE *a, const EC_AFFINE *b); + +// ec_precomp_select behaves like |ec_point_select| but acts on |EC_PRECOMP|. +void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, + const EC_PRECOMP *a, const EC_PRECOMP *b); + +// ec_cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group +// order, with |r|. It returns one if the values match and zero if |p| is the +// point at infinity of the values do not match. +int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, + const EC_SCALAR *r); + +// ec_get_x_coordinate_as_scalar sets |*out| to |p|'s x-coordinate, modulo +// |group->order|. It returns one on success and zero if |p| is the point at +// infinity. +int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, + const EC_RAW_POINT *p); + +// ec_get_x_coordinate_as_bytes writes |p|'s affine x-coordinate to |out|, which +// must have at must |max_out| bytes. It sets |*out_len| to the number of bytes +// written. The value is written big-endian and zero-padded to the size of the +// field. This function returns one on success and zero on failure. +int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, size_t max_out, + const EC_RAW_POINT *p); + +// ec_point_to_bytes behaves like |EC_POINT_point2oct| but takes an +// |EC_AFFINE|. +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, + point_conversion_form_t form, uint8_t *buf, + size_t len); + +// ec_point_from_uncompressed parses |in| as a point in uncompressed form and +// sets the result to |out|. It returns one on success and zero if the input was +// invalid. +int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out, + const uint8_t *in, size_t len); + +// ec_set_to_safe_point sets |out| to an arbitrary point on |group|, either the +// generator or the point at infinity. This is used to guard against callers of +// external APIs not checking the return value. +void ec_set_to_safe_point(const EC_GROUP *group, EC_RAW_POINT *out); + +// ec_affine_jacobian_equal returns one if |a| and |b| represent the same point +// and zero otherwise. It treats both inputs as secret. +int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a, + const EC_RAW_POINT *b); + + +// Implementation details. + +struct ec_method_st { + int (*group_init)(EC_GROUP *); + void (*group_finish)(EC_GROUP *); + int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + + // point_get_affine_coordinates sets |*x| and |*y| to the affine coordinates + // of |p|. Either |x| or |y| may be NULL to omit it. It returns one on success + // and zero if |p| is the point at infinity. + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_RAW_POINT *p, + EC_FELEM *x, EC_FELEM *y); + + // jacobian_to_affine_batch implements |ec_jacobian_to_affine_batch|. + int (*jacobian_to_affine_batch)(const EC_GROUP *group, EC_AFFINE *out, + const EC_RAW_POINT *in, size_t num); + + // add sets |r| to |a| + |b|. + void (*add)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *a, + const EC_RAW_POINT *b); + // dbl sets |r| to |a| + |a|. + void (*dbl)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *a); + + // mul sets |r| to |scalar|*|p|. + void (*mul)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *p, + const EC_SCALAR *scalar); + // mul_base sets |r| to |scalar|*generator. + void (*mul_base)(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar); + // mul_batch implements |ec_mul_scalar_batch|. + void (*mul_batch)(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); + // mul_public sets |r| to |g_scalar|*generator + |p_scalar|*|p|. It assumes + // that the inputs are public so there is no concern about leaking their + // values through timing. + // + // This function may be omitted if |mul_public_batch| is provided. + void (*mul_public)(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar); + // mul_public_batch implements |ec_point_mul_scalar_public_batch|. + int (*mul_public_batch)(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, const EC_RAW_POINT *points, + const EC_SCALAR *scalars, size_t num); + + // init_precomp implements |ec_init_precomp|. + int (*init_precomp)(const EC_GROUP *group, EC_PRECOMP *out, + const EC_RAW_POINT *p); + // mul_precomp implements |ec_point_mul_scalar_precomp|. + void (*mul_precomp)(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_PRECOMP *p0, const EC_SCALAR *scalar0, + const EC_PRECOMP *p1, const EC_SCALAR *scalar1, + const EC_PRECOMP *p2, const EC_SCALAR *scalar2); + + // felem_mul and felem_sqr implement multiplication and squaring, + // respectively, so that the generic |EC_POINT_add| and |EC_POINT_dbl| + // implementations can work both with |EC_GFp_mont_method| and the tuned + // operations. + // + // TODO(davidben): This constrains |EC_FELEM|'s internal representation, adds + // many indirect calls in the middle of the generic code, and a bunch of + // conversions. If p224-64.c were easily convertable to Montgomery form, we + // could say |EC_FELEM| is always in Montgomery form. If we routed the rest of + // simple.c to |EC_METHOD|, we could give |EC_POINT| an |EC_METHOD|-specific + // representation and say |EC_FELEM| is purely a |EC_GFp_mont_method| type. + void (*felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b); + void (*felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a); + + void (*felem_to_bytes)(const EC_GROUP *group, uint8_t *out, size_t *out_len, + const EC_FELEM *in); + int (*felem_from_bytes)(const EC_GROUP *group, EC_FELEM *out, + const uint8_t *in, size_t len); + + // felem_reduce sets |out| to |words|, reduced modulo the field size, p. + // |words| must be less than p^2. |num| must be at most twice the width of p. + // This function treats |words| as secret. + // + // This function is only used in hash-to-curve and may be omitted in curves + // that do not support it. + void (*felem_reduce)(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num); + + // felem_exp sets |out| to |a|^|exp|. It treats |a| is secret but |exp| as + // public. + // + // This function is used in hash-to-curve and may be NULL in curves not used + // with hash-to-curve. + void (*felem_exp)(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, + const BN_ULONG *exp, size_t num_exp); + + // scalar_inv0_montgomery implements |ec_scalar_inv0_montgomery|. + void (*scalar_inv0_montgomery)(const EC_GROUP *group, EC_SCALAR *out, + const EC_SCALAR *in); + + // scalar_to_montgomery_inv_vartime implements + // |ec_scalar_to_montgomery_inv_vartime|. + int (*scalar_to_montgomery_inv_vartime)(const EC_GROUP *group, EC_SCALAR *out, + const EC_SCALAR *in); + + // cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group + // order, with |r|. It returns one if the values match and zero if |p| is the + // point at infinity of the values do not match. + int (*cmp_x_coordinate)(const EC_GROUP *group, const EC_RAW_POINT *p, + const EC_SCALAR *r); +} /* EC_METHOD */; + +const EC_METHOD *EC_GFp_mont_method(void); + +struct ec_group_st { + const EC_METHOD *meth; + + // Unlike all other |EC_POINT|s, |generator| does not own |generator->group| + // to avoid a reference cycle. Additionally, Z is guaranteed to be one, so X + // and Y are suitable for use as an |EC_AFFINE|. + EC_POINT *generator; + BIGNUM order; + + int curve_name; // optional NID for named curve + + BN_MONT_CTX *order_mont; // data for ECDSA inverse + + // The following members are handled by the method functions, + // even if they appear generic + + BIGNUM field; // For curves over GF(p), this is the modulus. + + EC_FELEM a, b; // Curve coefficients. + + // a_is_minus3 is one if |a| is -3 mod |field| and zero otherwise. Point + // arithmetic is optimized for -3. + int a_is_minus3; + + // field_greater_than_order is one if |field| is greate than |order| and zero + // otherwise. + int field_greater_than_order; + + // field_minus_order, if |field_greater_than_order| is true, is |field| minus + // |order| represented as an |EC_FELEM|. Otherwise, it is zero. + // + // Note: unlike |EC_FELEM|s used as intermediate values internal to the + // |EC_METHOD|, this value is not encoded in Montgomery form. + EC_FELEM field_minus_order; + + CRYPTO_refcount_t references; + + BN_MONT_CTX *mont; // Montgomery structure. + + EC_FELEM one; // The value one. +} /* EC_GROUP */; + +struct ec_point_st { + // group is an owning reference to |group|, unless this is + // |group->generator|. + EC_GROUP *group; + // raw is the group-specific point data. Functions that take |EC_POINT| + // typically check consistency with |EC_GROUP| while functions that take + // |EC_RAW_POINT| do not. Thus accesses to this field should be externally + // checked for consistency. + EC_RAW_POINT raw; +} /* EC_POINT */; + +EC_GROUP *ec_group_new(const EC_METHOD *meth); + +void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, const EC_SCALAR *scalar); +void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar); +void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); +int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, + const EC_RAW_POINT *p); +void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_PRECOMP *p0, const EC_SCALAR *scalar0, + const EC_PRECOMP *p1, const EC_SCALAR *scalar1, + const EC_PRECOMP *p2, const EC_SCALAR *scalar2); + +// ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of +// |scalar| to |out|. |out| must have room for |bits| + 1 elements, each of +// which will be either zero or odd with an absolute value less than 2^w +// satisfying +// scalar = \sum_j out[j]*2^j +// where at most one of any w+1 consecutive digits is non-zero +// with the exception that the most significant digit may be only +// w-1 zeros away from that next non-zero digit. +void ec_compute_wNAF(const EC_GROUP *group, int8_t *out, + const EC_SCALAR *scalar, size_t bits, int w); + +int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *points, + const EC_SCALAR *scalars, size_t num); + +// method functions in simple.c +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(EC_GROUP *); +int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b); +void ec_GFp_simple_point_init(EC_RAW_POINT *); +void ec_GFp_simple_point_copy(EC_RAW_POINT *, const EC_RAW_POINT *); +void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_RAW_POINT *); +void ec_GFp_mont_add(const EC_GROUP *, EC_RAW_POINT *r, const EC_RAW_POINT *a, + const EC_RAW_POINT *b); +void ec_GFp_mont_dbl(const EC_GROUP *, EC_RAW_POINT *r, const EC_RAW_POINT *a); +void ec_GFp_simple_invert(const EC_GROUP *, EC_RAW_POINT *); +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_RAW_POINT *); +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_RAW_POINT *); +int ec_GFp_simple_points_equal(const EC_GROUP *, const EC_RAW_POINT *a, + const EC_RAW_POINT *b); +void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a); + +int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, + EC_SCALAR *r, + const EC_SCALAR *a); + +int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, + const EC_SCALAR *r); + +void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, const EC_FELEM *in); +int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, + const uint8_t *in, size_t len); + +// method functions in montgomery.c +int ec_GFp_mont_group_init(EC_GROUP *); +int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +void ec_GFp_mont_group_finish(EC_GROUP *); +void ec_GFp_mont_felem_mul(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b); +void ec_GFp_mont_felem_sqr(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a); + +void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, const EC_FELEM *in); +int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, + const uint8_t *in, size_t len); + +void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit, + crypto_word_t in); + +const EC_METHOD *EC_GFp_nistp224_method(void); +const EC_METHOD *EC_GFp_nistp256_method(void); + +// EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with +// x86-64 optimized P256. See http://eprint.iacr.org/2013/816. +const EC_METHOD *EC_GFp_nistz256_method(void); + +// An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| +// representation. It exists to support the |EC_KEY_get0_private_key| API. +typedef struct { + BIGNUM bignum; + EC_SCALAR scalar; +} EC_WRAPPED_SCALAR; + +struct ec_key_st { + EC_GROUP *group; + + // Ideally |pub_key| would be an |EC_AFFINE| so serializing it does not pay an + // inversion each time, but the |EC_KEY_get0_public_key| API implies public + // keys are stored in an |EC_POINT|-compatible form. + EC_POINT *pub_key; + EC_WRAPPED_SCALAR *priv_key; + + unsigned int enc_flag; + point_conversion_form_t conv_form; + + CRYPTO_refcount_t references; + + ECDSA_METHOD *ecdsa_meth; + + CRYPTO_EX_DATA ex_data; +} /* EC_KEY */; + +struct built_in_curve { + int nid; + const uint8_t *oid; + uint8_t oid_len; + // comment is a human-readable string describing the curve. + const char *comment; + // param_len is the number of bytes needed to store a field element. + uint8_t param_len; + // params points to an array of 6*|param_len| bytes which hold the field + // elements of the following (in big-endian order): prime, a, b, generator x, + // generator y, order. + const uint8_t *params; + const EC_METHOD *method; +}; + +#define OPENSSL_NUM_BUILT_IN_CURVES 4 + +struct built_in_curves { + struct built_in_curve curves[OPENSSL_NUM_BUILT_IN_CURVES]; +}; + +// OPENSSL_built_in_curves returns a pointer to static information about +// standard curves. The array is terminated with an entry where |nid| is +// |NID_undef|. +const struct built_in_curves *OPENSSL_built_in_curves(void); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EC_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c new file mode 100644 index 00000000..1f8dd202 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c @@ -0,0 +1,328 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include +#include + +#include "internal.h" + + +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, + point_conversion_form_t form, uint8_t *buf, + size_t len) { + if (form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + return 0; + } + + const size_t field_len = BN_num_bytes(&group->field); + size_t output_len = 1 /* type byte */ + field_len; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + // Uncompressed points have a second coordinate. + output_len += field_len; + } + + // if 'buf' is NULL, just return required length + if (buf != NULL) { + if (len < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + size_t field_len_out; + ec_felem_to_bytes(group, buf + 1, &field_len_out, &point->X); + assert(field_len_out == field_len); + + if (form == POINT_CONVERSION_UNCOMPRESSED) { + ec_felem_to_bytes(group, buf + 1 + field_len, &field_len_out, &point->Y); + assert(field_len_out == field_len); + buf[0] = form; + } else { + uint8_t y_buf[EC_MAX_BYTES]; + ec_felem_to_bytes(group, y_buf, &field_len_out, &point->Y); + buf[0] = form + (y_buf[field_len_out - 1] & 1); + } + } + + return output_len; +} + +int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out, + const uint8_t *in, size_t len) { + const size_t field_len = BN_num_bytes(&group->field); + if (len != 1 + 2 * field_len || in[0] != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + return 0; + } + + EC_FELEM x, y; + if (!ec_felem_from_bytes(group, &x, in + 1, field_len) || + !ec_felem_from_bytes(group, &y, in + 1 + field_len, field_len) || + !ec_point_set_affine_coordinates(group, out, &x, &y)) { + return 0; + } + + return 1; +} + +static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx) { + if (len == 0) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + point_conversion_form_t form = buf[0]; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + EC_AFFINE affine; + if (!ec_point_from_uncompressed(group, &affine, buf, len)) { + // In the event of an error, defend against the caller not checking the + // return value by setting a known safe value. + ec_set_to_safe_point(group, &point->raw); + return 0; + } + ec_affine_to_jacobian(group, &point->raw, &affine); + return 1; + } + + const int y_bit = form & 1; + const size_t field_len = BN_num_bytes(&group->field); + form = form & ~1u; + if (form != POINT_CONVERSION_COMPRESSED || + len != 1 /* type byte */ + field_len) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + return 0; + } + + // TODO(davidben): Integrate compressed coordinates with the lower-level EC + // abstractions. This requires a way to compute square roots, which is tricky + // for primes which are not 3 (mod 4), namely P-224 and custom curves. P-224's + // prime is particularly inconvenient for compressed coordinates. See + // https://cr.yp.to/papers/sqroot.pdf + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *x = BN_CTX_get(ctx); + if (x == NULL || !BN_bin2bn(buf + 1, field_len, x)) { + goto err; + } + if (BN_ucmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_oct2point(group, point, buf, len, ctx); +} + +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t *buf, + size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + EC_AFFINE affine; + if (!ec_jacobian_to_affine(group, &affine, &point->raw)) { + return 0; + } + return ec_point_to_bytes(group, &affine, form, buf, len); +} + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + return 0; + } + + BN_CTX *new_ctx = NULL; + int ret = 0; + + ERR_clear_error(); + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + y_bit = (y_bit != 0); + + BN_CTX_start(ctx); + BIGNUM *tmp1 = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + BIGNUM *a = BN_CTX_get(ctx); + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *y = BN_CTX_get(ctx); + if (y == NULL || + !EC_GROUP_get_curve_GFp(group, NULL, a, b, ctx)) { + goto err; + } + + // Recover y. We have a Weierstrass equation + // y^2 = x^3 + a*x + b, + // so y is one of the square roots of x^3 + a*x + b. + + // tmp1 := x^3 + if (!BN_mod_sqr(tmp2, x, &group->field, ctx) || + !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) { + goto err; + } + + // tmp1 := tmp1 + a*x + if (group->a_is_minus3) { + if (!bn_mod_lshift1_consttime(tmp2, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp2, tmp2, x, &group->field, ctx) || + !bn_mod_sub_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } else { + if (!BN_mod_mul(tmp2, a, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } + + // tmp1 := tmp1 + b + if (!bn_mod_add_consttime(tmp1, tmp1, b, &group->field, ctx)) { + goto err; + } + + if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN && + ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + ERR_clear_error(); + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + } else { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + } + goto err; + } + + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT); + goto err; + } + if (!BN_usub(y, &group->field, y)) { + goto err; + } + } + if (y_bit != BN_is_odd(y)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p224-64.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p224-64.c new file mode 100644 index 00000000..a398e01a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p224-64.c @@ -0,0 +1,1180 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// A 64-bit implementation of the NIST P-224 elliptic curve point multiplication +// +// Inspired by Daniel J. Bernstein's public domain nistp224 implementation +// and Adam Langley's public domain 64-bit C implementation of curve25519. + +#include + +#include +#include +#include +#include + +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + +// Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3 +// using 64-bit coefficients called 'limbs', and sometimes (for multiplication +// results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + +// 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-p224_limb +// representation is an 'p224_felem'; a 7-p224_widelimb representation is a +// 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we +// don't always reduce the representations: we ensure that inputs to each +// p224_felem multiplication satisfy a_i < 2^60, so outputs satisfy b_i < +// 4*2^60*2^60, and fit into a 128-bit word without overflow. The coefficients +// are then again partially reduced to obtain an p224_felem satisfying a_i < +// 2^57. We only reduce to the unique minimal representation at the end of the +// computation. + +typedef uint64_t p224_limb; +typedef uint128_t p224_widelimb; + +typedef p224_limb p224_felem[4]; +typedef p224_widelimb p224_widefelem[7]; + +// Field element represented as a byte arrary. 28*8 = 224 bits is also the +// group order size for the elliptic curve, and we also use this type for +// scalars for point multiplication. +typedef uint8_t p224_felem_bytearray[28]; + +// Precomputed multiples of the standard generator +// Points are given in coordinates (X, Y, Z) where Z normally is 1 +// (0 for the point at infinity). +// For each field element, slice a_0 is word 0, etc. +// +// The table has 2 * 16 elements, starting with the following: +// index | bits | point +// ------+---------+------------------------------ +// 0 | 0 0 0 0 | 0G +// 1 | 0 0 0 1 | 1G +// 2 | 0 0 1 0 | 2^56G +// 3 | 0 0 1 1 | (2^56 + 1)G +// 4 | 0 1 0 0 | 2^112G +// 5 | 0 1 0 1 | (2^112 + 1)G +// 6 | 0 1 1 0 | (2^112 + 2^56)G +// 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G +// 8 | 1 0 0 0 | 2^168G +// 9 | 1 0 0 1 | (2^168 + 1)G +// 10 | 1 0 1 0 | (2^168 + 2^56)G +// 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G +// 12 | 1 1 0 0 | (2^168 + 2^112)G +// 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G +// 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G +// 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G +// followed by a copy of this with each element multiplied by 2^28. +// +// The reason for this is so that we can clock bits into four different +// locations when doing simple scalar multiplies against the base point, +// and then another four locations using the second 16 elements. +static const p224_felem g_p224_pre_comp[2][16][3] = { + {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf}, + {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723}, + {1, 0, 0, 0}}, + {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5}, + {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321}, + {1, 0, 0, 0}}, + {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748}, + {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17}, + {1, 0, 0, 0}}, + {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe}, + {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b}, + {1, 0, 0, 0}}, + {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3}, + {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a}, + {1, 0, 0, 0}}, + {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c}, + {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244}, + {1, 0, 0, 0}}, + {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849}, + {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112}, + {1, 0, 0, 0}}, + {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47}, + {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394}, + {1, 0, 0, 0}}, + {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d}, + {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7}, + {1, 0, 0, 0}}, + {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24}, + {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881}, + {1, 0, 0, 0}}, + {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984}, + {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369}, + {1, 0, 0, 0}}, + {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3}, + {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60}, + {1, 0, 0, 0}}, + {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057}, + {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9}, + {1, 0, 0, 0}}, + {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9}, + {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc}, + {1, 0, 0, 0}}, + {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58}, + {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558}, + {1, 0, 0, 0}}}, + {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31}, + {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d}, + {1, 0, 0, 0}}, + {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3}, + {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a}, + {1, 0, 0, 0}}, + {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33}, + {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100}, + {1, 0, 0, 0}}, + {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5}, + {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea}, + {1, 0, 0, 0}}, + {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be}, + {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51}, + {1, 0, 0, 0}}, + {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1}, + {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb}, + {1, 0, 0, 0}}, + {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233}, + {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def}, + {1, 0, 0, 0}}, + {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae}, + {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45}, + {1, 0, 0, 0}}, + {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e}, + {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb}, + {1, 0, 0, 0}}, + {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de}, + {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3}, + {1, 0, 0, 0}}, + {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05}, + {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58}, + {1, 0, 0, 0}}, + {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb}, + {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0}, + {1, 0, 0, 0}}, + {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9}, + {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea}, + {1, 0, 0, 0}}, + {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba}, + {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405}, + {1, 0, 0, 0}}, + {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e}, + {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, + {1, 0, 0, 0}}}}; + +static uint64_t p224_load_u64(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, sizeof(ret)); + return ret; +} + +// Helper functions to convert field elements to/from internal representation +static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) { + out[0] = p224_load_u64(in) & 0x00ffffffffffffff; + out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff; + out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff; + out[3] = p224_load_u64(in + 20) >> 8; +} + +static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) { + for (size_t i = 0; i < 7; ++i) { + out[i] = in[0] >> (8 * i); + out[i + 7] = in[1] >> (8 * i); + out[i + 14] = in[2] >> (8 * i); + out[i + 21] = in[3] >> (8 * i); + } +} + +static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) { + p224_bin28_to_felem(out, in->bytes); +} + +// Requires 0 <= in < 2*p (always call p224_felem_reduce first) +static void p224_felem_to_generic(EC_FELEM *out, const p224_felem in) { + // Reduce to unique minimal representation. + static const int64_t two56 = ((p224_limb)1) << 56; + // 0 <= in < 2*p, p = 2^224 - 2^96 + 1 + // if in > p , reduce in = in - 2^224 + 2^96 - 1 + int64_t tmp[4], a; + tmp[0] = in[0]; + tmp[1] = in[1]; + tmp[2] = in[2]; + tmp[3] = in[3]; + // Case 1: a = 1 iff in >= 2^224 + a = (in[3] >> 56); + tmp[0] -= a; + tmp[1] += a << 40; + tmp[3] &= 0x00ffffffffffffff; + // Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and + // the lower part is non-zero + a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) | + (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63); + a &= 0x00ffffffffffffff; + // turn a into an all-one mask (if a = 0) or an all-zero mask + a = (a - 1) >> 63; + // subtract 2^224 - 2^96 + 1 if a is all-one + tmp[3] &= a ^ 0xffffffffffffffff; + tmp[2] &= a ^ 0xffffffffffffffff; + tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff; + tmp[0] -= 1 & a; + + // eliminate negative coefficients: if tmp[0] is negative, tmp[1] must + // be non-zero, so we only need one step + a = tmp[0] >> 63; + tmp[0] += two56 & a; + tmp[1] -= 1 & a; + + // carry 1 -> 2 -> 3 + tmp[2] += tmp[1] >> 56; + tmp[1] &= 0x00ffffffffffffff; + + tmp[3] += tmp[2] >> 56; + tmp[2] &= 0x00ffffffffffffff; + + // Now 0 <= tmp < p + p224_felem tmp2; + tmp2[0] = tmp[0]; + tmp2[1] = tmp[1]; + tmp2[2] = tmp[2]; + tmp2[3] = tmp[3]; + + p224_felem_to_bin28(out->bytes, tmp2); + // 224 is not a multiple of 64, so zero the remaining bytes. + OPENSSL_memset(out->bytes + 28, 0, 32 - 28); +} + + +// Field operations, using the internal representation of field elements. +// NB! These operations are specific to our point multiplication and cannot be +// expected to be correct in general - e.g., multiplication with a large scalar +// will cause an overflow. + +static void p224_felem_assign(p224_felem out, const p224_felem in) { + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +// Sum two field elements: out += in +static void p224_felem_sum(p224_felem out, const p224_felem in) { + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +// Subtract field elements: out -= in +// Assumes in[i] < 2^57 +static void p224_felem_diff(p224_felem out, const p224_felem in) { + static const p224_limb two58p2 = + (((p224_limb)1) << 58) + (((p224_limb)1) << 2); + static const p224_limb two58m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 2); + static const p224_limb two58m42m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_limb)1) << 2); + + // Add 0 mod 2^224-2^96+1 to ensure out > in + out[0] += two58p2; + out[1] += two58m42m2; + out[2] += two58m2; + out[3] += two58m2; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +// Subtract in unreduced 128-bit mode: out -= in +// Assumes in[i] < 2^119 +static void p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) { + static const p224_widelimb two120 = ((p224_widelimb)1) << 120; + static const p224_widelimb two120m64 = + (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64); + static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) - + (((p224_widelimb)1) << 104) - + (((p224_widelimb)1) << 64); + + // Add 0 mod 2^224-2^96+1 to ensure out > in + out[0] += two120; + out[1] += two120m64; + out[2] += two120m64; + out[3] += two120; + out[4] += two120m104m64; + out[5] += two120m64; + out[6] += two120m64; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; + out[4] -= in[4]; + out[5] -= in[5]; + out[6] -= in[6]; +} + +// Subtract in mixed mode: out128 -= in64 +// in[i] < 2^63 +static void p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) { + static const p224_widelimb two64p8 = + (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8); + static const p224_widelimb two64m8 = + (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8); + static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) - + (((p224_widelimb)1) << 48) - + (((p224_widelimb)1) << 8); + + // Add 0 mod 2^224-2^96+1 to ensure out > in + out[0] += two64p8; + out[1] += two64m48m8; + out[2] += two64m8; + out[3] += two64m8; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +// Multiply a field element by a scalar: out = out * scalar +// The scalars we actually use are small, so results fit without overflow +static void p224_felem_scalar(p224_felem out, const p224_limb scalar) { + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; +} + +// Multiply an unreduced field element by a scalar: out = out * scalar +// The scalars we actually use are small, so results fit without overflow +static void p224_widefelem_scalar(p224_widefelem out, + const p224_widelimb scalar) { + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; +} + +// Square a field element: out = in^2 +static void p224_felem_square(p224_widefelem out, const p224_felem in) { + p224_limb tmp0, tmp1, tmp2; + tmp0 = 2 * in[0]; + tmp1 = 2 * in[1]; + tmp2 = 2 * in[2]; + out[0] = ((p224_widelimb)in[0]) * in[0]; + out[1] = ((p224_widelimb)in[0]) * tmp1; + out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1]; + out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2; + out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2]; + out[5] = ((p224_widelimb)in[3]) * tmp2; + out[6] = ((p224_widelimb)in[3]) * in[3]; +} + +// Multiply two field elements: out = in1 * in2 +static void p224_felem_mul(p224_widefelem out, const p224_felem in1, + const p224_felem in2) { + out[0] = ((p224_widelimb)in1[0]) * in2[0]; + out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0]; + out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] + + ((p224_widelimb)in1[2]) * in2[0]; + out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] + + ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0]; + out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] + + ((p224_widelimb)in1[3]) * in2[1]; + out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2]; + out[6] = ((p224_widelimb)in1[3]) * in2[3]; +} + +// Reduce seven 128-bit coefficients to four 64-bit coefficients. +// Requires in[i] < 2^126, +// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 +static void p224_felem_reduce(p224_felem out, const p224_widefelem in) { + static const p224_widelimb two127p15 = + (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15); + static const p224_widelimb two127m71 = + (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71); + static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) - + (((p224_widelimb)1) << 71) - + (((p224_widelimb)1) << 55); + p224_widelimb output[5]; + + // Add 0 mod 2^224-2^96+1 to ensure all differences are positive + output[0] = in[0] + two127p15; + output[1] = in[1] + two127m71m55; + output[2] = in[2] + two127m71; + output[3] = in[3]; + output[4] = in[4]; + + // Eliminate in[4], in[5], in[6] + output[4] += in[6] >> 16; + output[3] += (in[6] & 0xffff) << 40; + output[2] -= in[6]; + + output[3] += in[5] >> 16; + output[2] += (in[5] & 0xffff) << 40; + output[1] -= in[5]; + + output[2] += output[4] >> 16; + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + // Carry 2 -> 3 -> 4 + output[3] += output[2] >> 56; + output[2] &= 0x00ffffffffffffff; + + output[4] = output[3] >> 56; + output[3] &= 0x00ffffffffffffff; + + // Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 + + // Eliminate output[4] + output[2] += output[4] >> 16; + // output[2] < 2^56 + 2^56 = 2^57 + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + // Carry 0 -> 1 -> 2 -> 3 + output[1] += output[0] >> 56; + out[0] = output[0] & 0x00ffffffffffffff; + + output[2] += output[1] >> 56; + // output[2] < 2^57 + 2^72 + out[1] = output[1] & 0x00ffffffffffffff; + output[3] += output[2] >> 56; + // output[3] <= 2^56 + 2^16 + out[2] = output[2] & 0x00ffffffffffffff; + + // out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, + // out[3] <= 2^56 + 2^16 (due to final carry), + // so out < 2*p + out[3] = output[3]; +} + +// Get negative value: out = -in +// Requires in[i] < 2^63, +// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 +static void p224_felem_neg(p224_felem out, const p224_felem in) { + p224_widefelem tmp = {0}; + p224_felem_diff_128_64(tmp, in); + p224_felem_reduce(out, tmp); +} + +// Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field +// elements are reduced to in < 2^225, so we only need to check three cases: 0, +// 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 +static p224_limb p224_felem_is_zero(const p224_felem in) { + p224_limb zero = in[0] | in[1] | in[2] | in[3]; + zero = (((int64_t)(zero)-1) >> 63) & 1; + + p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x00ffffffffffffff); + two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1; + p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x01ffffffffffffff); + two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1; + return (zero | two224m96p1 | two225m97p2); +} + +// Invert a field element +// Computation chain copied from djb's code +static void p224_felem_inv(p224_felem out, const p224_felem in) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4; + p224_widefelem tmp; + + p224_felem_square(tmp, in); + p224_felem_reduce(ftmp, tmp); // 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^2 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^4 - 2 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^5 - 4 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^6 - 8 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^6 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^7 - 2 + for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^12 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^13 - 2 + for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^24 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^25 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^48 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^49 - 2 + for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp4); + p224_felem_reduce(ftmp3, tmp); // 2^96 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^97 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp4); + p224_felem_reduce(ftmp2, tmp); // 2^120 - 1 + for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^126 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^127 - 2 + p224_felem_mul(tmp, ftmp, in); + p224_felem_reduce(ftmp, tmp); // 2^127 - 1 + for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + } + p224_felem_mul(tmp, ftmp, ftmp3); + p224_felem_reduce(out, tmp); // 2^224 - 2^96 - 1 +} + +// Copy in constant time: +// if icopy == 1, copy in to out, +// if icopy == 0, copy out to itself. +static void p224_copy_conditional(p224_felem out, const p224_felem in, + p224_limb icopy) { + // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one + const p224_limb copy = -icopy; + for (size_t i = 0; i < 4; ++i) { + const p224_limb tmp = copy & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +// ELLIPTIC CURVE POINT OPERATIONS +// +// Points are represented in Jacobian projective coordinates: +// (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3), +// or to the point at infinity if Z == 0. + +// Double an elliptic curve point: +// (X', Y', Z') = 2 * (X, Y, Z), where +// X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2 +// Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2 +// Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z +// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed, +// while x_out == y_in is not (maybe this works, but it's not tested). +static void p224_point_double(p224_felem x_out, p224_felem y_out, + p224_felem z_out, const p224_felem x_in, + const p224_felem y_in, const p224_felem z_in) { + p224_widefelem tmp, tmp2; + p224_felem delta, gamma, beta, alpha, ftmp, ftmp2; + + p224_felem_assign(ftmp, x_in); + p224_felem_assign(ftmp2, x_in); + + // delta = z^2 + p224_felem_square(tmp, z_in); + p224_felem_reduce(delta, tmp); + + // gamma = y^2 + p224_felem_square(tmp, y_in); + p224_felem_reduce(gamma, tmp); + + // beta = x*gamma + p224_felem_mul(tmp, x_in, gamma); + p224_felem_reduce(beta, tmp); + + // alpha = 3*(x-delta)*(x+delta) + p224_felem_diff(ftmp, delta); + // ftmp[i] < 2^57 + 2^58 + 2 < 2^59 + p224_felem_sum(ftmp2, delta); + // ftmp2[i] < 2^57 + 2^57 = 2^58 + p224_felem_scalar(ftmp2, 3); + // ftmp2[i] < 3 * 2^58 < 2^60 + p224_felem_mul(tmp, ftmp, ftmp2); + // tmp[i] < 2^60 * 2^59 * 4 = 2^121 + p224_felem_reduce(alpha, tmp); + + // x' = alpha^2 - 8*beta + p224_felem_square(tmp, alpha); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + p224_felem_assign(ftmp, beta); + p224_felem_scalar(ftmp, 8); + // ftmp[i] < 8 * 2^57 = 2^60 + p224_felem_diff_128_64(tmp, ftmp); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(x_out, tmp); + + // z' = (y + z)^2 - gamma - delta + p224_felem_sum(delta, gamma); + // delta[i] < 2^57 + 2^57 = 2^58 + p224_felem_assign(ftmp, y_in); + p224_felem_sum(ftmp, z_in); + // ftmp[i] < 2^57 + 2^57 = 2^58 + p224_felem_square(tmp, ftmp); + // tmp[i] < 4 * 2^58 * 2^58 = 2^118 + p224_felem_diff_128_64(tmp, delta); + // tmp[i] < 2^118 + 2^64 + 8 < 2^119 + p224_felem_reduce(z_out, tmp); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + p224_felem_scalar(beta, 4); + // beta[i] < 4 * 2^57 = 2^59 + p224_felem_diff(beta, x_out); + // beta[i] < 2^59 + 2^58 + 2 < 2^60 + p224_felem_mul(tmp, alpha, beta); + // tmp[i] < 4 * 2^57 * 2^60 = 2^119 + p224_felem_square(tmp2, gamma); + // tmp2[i] < 4 * 2^57 * 2^57 = 2^116 + p224_widefelem_scalar(tmp2, 8); + // tmp2[i] < 8 * 2^116 = 2^119 + p224_widefelem_diff(tmp, tmp2); + // tmp[i] < 2^119 + 2^120 < 2^121 + p224_felem_reduce(y_out, tmp); +} + +// Add two elliptic curve points: +// (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where +// X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 - +// 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 +// Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * +// X_1)^2 - X_3) - +// Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3 +// Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2) +// +// This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. + +// This function is not entirely constant-time: it includes a branch for +// checking whether the two input points are equal, (while not equal to the +// point at infinity). This case never happens during single point +// multiplication, so there is no timing leak for ECDH or ECDSA signing. +static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3, + const p224_felem x1, const p224_felem y1, + const p224_felem z1, const int mixed, + const p224_felem x2, const p224_felem y2, + const p224_felem z2) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; + p224_widefelem tmp, tmp2; + p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal; + + if (!mixed) { + // ftmp2 = z2^2 + p224_felem_square(tmp, z2); + p224_felem_reduce(ftmp2, tmp); + + // ftmp4 = z2^3 + p224_felem_mul(tmp, ftmp2, z2); + p224_felem_reduce(ftmp4, tmp); + + // ftmp4 = z2^3*y1 + p224_felem_mul(tmp2, ftmp4, y1); + p224_felem_reduce(ftmp4, tmp2); + + // ftmp2 = z2^2*x1 + p224_felem_mul(tmp2, ftmp2, x1); + p224_felem_reduce(ftmp2, tmp2); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later) + + // ftmp4 = z2^3*y1 + p224_felem_assign(ftmp4, y1); + + // ftmp2 = z2^2*x1 + p224_felem_assign(ftmp2, x1); + } + + // ftmp = z1^2 + p224_felem_square(tmp, z1); + p224_felem_reduce(ftmp, tmp); + + // ftmp3 = z1^3 + p224_felem_mul(tmp, ftmp, z1); + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^3*y2 + p224_felem_mul(tmp, ftmp3, y2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp3 = z1^3*y2 - z2^3*y1 + p224_felem_diff_128_64(tmp, ftmp4); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^2*x2 + p224_felem_mul(tmp, ftmp, x2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp = z1^2*x2 - z2^2*x1 + p224_felem_diff_128_64(tmp, ftmp2); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(ftmp, tmp); + + // the formulae are incorrect if the points are equal + // so we check for this and do doubling if this happens + x_equal = p224_felem_is_zero(ftmp); + y_equal = p224_felem_is_zero(ftmp3); + z1_is_zero = p224_felem_is_zero(z1); + z2_is_zero = p224_felem_is_zero(z2); + // In affine coordinates, (X_1, Y_1) == (X_2, Y_2) + p224_limb is_nontrivial_double = + x_equal & y_equal & (1 - z1_is_zero) & (1 - z2_is_zero); + if (is_nontrivial_double) { + p224_point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // ftmp5 = z1*z2 + if (!mixed) { + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(ftmp5, tmp); + } else { + // special case z2 = 0 is handled later + p224_felem_assign(ftmp5, z1); + } + + // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(z_out, tmp); + + // ftmp = (z1^2*x2 - z2^2*x1)^2 + p224_felem_assign(ftmp5, ftmp); + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + + // ftmp5 = (z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(ftmp5, tmp); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); + + // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp4, ftmp5); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // tmp2 = (z1^3*y2 - z2^3*y1)^2 + p224_felem_square(tmp2, ftmp3); + // tmp2[i] < 4 * 2^57 * 2^57 < 2^116 + + // tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 + p224_felem_diff_128_64(tmp2, ftmp5); + // tmp2[i] < 2^116 + 2^64 + 8 < 2^117 + + // ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + p224_felem_assign(ftmp5, ftmp2); + p224_felem_scalar(ftmp5, 2); + // ftmp5[i] < 2 * 2^57 = 2^58 + + /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 - + 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ + p224_felem_diff_128_64(tmp2, ftmp5); + // tmp2[i] < 2^117 + 2^64 + 8 < 2^118 + p224_felem_reduce(x_out, tmp2); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out + p224_felem_diff(ftmp2, x_out); + // ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 + + // tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) + p224_felem_mul(tmp2, ftmp3, ftmp2); + // tmp2[i] < 4 * 2^57 * 2^59 = 2^118 + + /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) - + z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */ + p224_widefelem_diff(tmp2, tmp); + // tmp2[i] < 2^118 + 2^120 < 2^121 + p224_felem_reduce(y_out, tmp2); + + // the result (x_out, y_out, z_out) is incorrect if one of the inputs is + // the point at infinity, so we need to check for this separately + + // if point 1 is at infinity, copy point 2 to output, and vice versa + p224_copy_conditional(x_out, x2, z1_is_zero); + p224_copy_conditional(x_out, x1, z2_is_zero); + p224_copy_conditional(y_out, y2, z1_is_zero); + p224_copy_conditional(y_out, y1, z2_is_zero); + p224_copy_conditional(z_out, z2, z1_is_zero); + p224_copy_conditional(z_out, z1, z2_is_zero); + p224_felem_assign(x3, x_out); + p224_felem_assign(y3, y_out); + p224_felem_assign(z3, z_out); +} + +// p224_select_point selects the |idx|th point from a precomputation table and +// copies it to out. +static void p224_select_point(const uint64_t idx, size_t size, + const p224_felem pre_comp[/*size*/][3], + p224_felem out[3]) { + p224_limb *outlimbs = &out[0][0]; + OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem)); + + for (size_t i = 0; i < size; i++) { + const p224_limb *inlimbs = &pre_comp[i][0][0]; + uint64_t mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (size_t j = 0; j < 4 * 3; j++) { + outlimbs[j] |= inlimbs[j] & mask; + } + } +} + +// p224_get_bit returns the |i|th bit in |in| +static crypto_word_t p224_get_bit(const p224_felem_bytearray in, size_t i) { + if (i >= 224) { + return 0; + } + return (in[i >> 3] >> (i & 7)) & 1; +} + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns +// (X', Y') = (X/Z^2, Y/Z^3) +static int ec_GFp_nistp224_point_get_affine_coordinates( + const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x, + EC_FELEM *y) { + if (ec_GFp_simple_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + p224_felem z1, z2; + p224_widefelem tmp; + p224_generic_to_felem(z1, &point->Z); + p224_felem_inv(z2, z1); + p224_felem_square(tmp, z2); + p224_felem_reduce(z1, tmp); + + if (x != NULL) { + p224_felem x_in, x_out; + p224_generic_to_felem(x_in, &point->X); + p224_felem_mul(tmp, x_in, z1); + p224_felem_reduce(x_out, tmp); + p224_felem_to_generic(x, x_out); + } + + if (y != NULL) { + p224_felem y_in, y_out; + p224_generic_to_felem(y_in, &point->Y); + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(z1, tmp); + p224_felem_mul(tmp, y_in, z1); + p224_felem_reduce(y_out, tmp); + p224_felem_to_generic(y, y_out); + } + + return 1; +} + +static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a, const EC_RAW_POINT *b) { + p224_felem x1, y1, z1, x2, y2, z2; + p224_generic_to_felem(x1, &a->X); + p224_generic_to_felem(y1, &a->Y); + p224_generic_to_felem(z1, &a->Z); + p224_generic_to_felem(x2, &b->X); + p224_generic_to_felem(y2, &b->Y); + p224_generic_to_felem(z2, &b->Z); + p224_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, z2); + // The outputs are already reduced, but still need to be contracted. + p224_felem_to_generic(&r->X, x1); + p224_felem_to_generic(&r->Y, y1); + p224_felem_to_generic(&r->Z, z1); +} + +static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a) { + p224_felem x, y, z; + p224_generic_to_felem(x, &a->X); + p224_generic_to_felem(y, &a->Y); + p224_generic_to_felem(z, &a->Z); + p224_point_double(x, y, z, x, y, z); + // The outputs are already reduced, but still need to be contracted. + p224_felem_to_generic(&r->X, x); + p224_felem_to_generic(&r->Y, y); + p224_felem_to_generic(&r->Z, z); +} + +static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3], + const EC_RAW_POINT *p) { + OPENSSL_memset(out[0], 0, sizeof(p224_felem) * 3); + + p224_generic_to_felem(out[1][0], &p->X); + p224_generic_to_felem(out[1][1], &p->Y); + p224_generic_to_felem(out[1][2], &p->Z); + + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + p224_point_add(out[j][0], out[j][1], out[j][2], out[1][0], out[1][1], + out[1][2], 0, out[j - 1][0], out[j - 1][1], out[j - 1][2]); + } else { + p224_point_double(out[j][0], out[j][1], out[j][2], out[j / 2][0], + out[j / 2][1], out[j / 2][2]); + } + } +} + +static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, + const EC_SCALAR *scalar) { + p224_felem p_pre_comp[17][3]; + ec_GFp_nistp224_make_precomp(p_pre_comp, p); + + // Set nq to the point at infinity. + p224_felem nq[3], tmp[4]; + OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem)); + + int skip = 1; // Save two point operations in the first round. + for (size_t i = 220; i < 221; i--) { + if (!skip) { + p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // Add every 5 doublings. + if (i % 5 == 0) { + crypto_word_t bits = p224_get_bit(scalar->bytes, i + 4) << 5; + bits |= p224_get_bit(scalar->bytes, i + 3) << 4; + bits |= p224_get_bit(scalar->bytes, i + 2) << 3; + bits |= p224_get_bit(scalar->bytes, i + 1) << 2; + bits |= p224_get_bit(scalar->bytes, i) << 1; + bits |= p224_get_bit(scalar->bytes, i - 1); + crypto_word_t sign, digit; + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + // Select the point to add or subtract. + p224_select_point(digit, 17, (const p224_felem(*)[3])p_pre_comp, tmp); + p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point + p224_copy_conditional(tmp[1], tmp[3], sign); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + } + } + + // Reduce the output to its unique minimal representation. + p224_felem_to_generic(&r->X, nq[0]); + p224_felem_to_generic(&r->Y, nq[1]); + p224_felem_to_generic(&r->Z, nq[2]); +} + +static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *scalar) { + // Set nq to the point at infinity. + p224_felem nq[3], tmp[3]; + OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem)); + + int skip = 1; // Save two point operations in the first round. + for (size_t i = 27; i < 28; i--) { + // double + if (!skip) { + p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // First, look 28 bits upwards. + crypto_word_t bits = p224_get_bit(scalar->bytes, i + 196) << 3; + bits |= p224_get_bit(scalar->bytes, i + 140) << 2; + bits |= p224_get_bit(scalar->bytes, i + 84) << 1; + bits |= p224_get_bit(scalar->bytes, i + 28); + // Select the point to add, in constant time. + p224_select_point(bits, 16, g_p224_pre_comp[1], tmp); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + + // Second, look at the current position/ + bits = p224_get_bit(scalar->bytes, i + 168) << 3; + bits |= p224_get_bit(scalar->bytes, i + 112) << 2; + bits |= p224_get_bit(scalar->bytes, i + 56) << 1; + bits |= p224_get_bit(scalar->bytes, i); + // Select the point to add, in constant time. + p224_select_point(bits, 16, g_p224_pre_comp[0], tmp); + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } + + // Reduce the output to its unique minimal representation. + p224_felem_to_generic(&r->X, nq[0]); + p224_felem_to_generic(&r->Y, nq[1]); + p224_felem_to_generic(&r->Z, nq[2]); +} + +static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar) { + // TODO(davidben): If P-224 ECDSA verify performance ever matters, using + // |ec_compute_wNAF| for |p_scalar| would likely be an easy improvement. + p224_felem p_pre_comp[17][3]; + ec_GFp_nistp224_make_precomp(p_pre_comp, p); + + // Set nq to the point at infinity. + p224_felem nq[3], tmp[3]; + OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem)); + + // Loop over both scalars msb-to-lsb, interleaving additions of multiples of + // the generator (two in each of the last 28 rounds) and additions of p (every + // 5th round). + int skip = 1; // Save two point operations in the first round. + for (size_t i = 220; i < 221; i--) { + if (!skip) { + p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // Add multiples of the generator. + if (i <= 27) { + // First, look 28 bits upwards. + crypto_word_t bits = p224_get_bit(g_scalar->bytes, i + 196) << 3; + bits |= p224_get_bit(g_scalar->bytes, i + 140) << 2; + bits |= p224_get_bit(g_scalar->bytes, i + 84) << 1; + bits |= p224_get_bit(g_scalar->bytes, i + 28); + + size_t index = (size_t)bits; + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + g_p224_pre_comp[1][index][0], g_p224_pre_comp[1][index][1], + g_p224_pre_comp[1][index][2]); + assert(!skip); + + // Second, look at the current position. + bits = p224_get_bit(g_scalar->bytes, i + 168) << 3; + bits |= p224_get_bit(g_scalar->bytes, i + 112) << 2; + bits |= p224_get_bit(g_scalar->bytes, i + 56) << 1; + bits |= p224_get_bit(g_scalar->bytes, i); + index = (size_t)bits; + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1], + g_p224_pre_comp[0][index][2]); + } + + // Incorporate |p_scalar| every 5 doublings. + if (i % 5 == 0) { + crypto_word_t bits = p224_get_bit(p_scalar->bytes, i + 4) << 5; + bits |= p224_get_bit(p_scalar->bytes, i + 3) << 4; + bits |= p224_get_bit(p_scalar->bytes, i + 2) << 3; + bits |= p224_get_bit(p_scalar->bytes, i + 1) << 2; + bits |= p224_get_bit(p_scalar->bytes, i) << 1; + bits |= p224_get_bit(p_scalar->bytes, i - 1); + crypto_word_t sign, digit; + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + // Select the point to add or subtract. + OPENSSL_memcpy(tmp, p_pre_comp[digit], 3 * sizeof(p224_felem)); + if (sign) { + p224_felem_neg(tmp[1], tmp[1]); // (X, -Y, Z) is the negative point + } + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + } + } + + // Reduce the output to its unique minimal representation. + p224_felem_to_generic(&r->X, nq[0]); + p224_felem_to_generic(&r->Y, nq[1]); + p224_felem_to_generic(&r->Z, nq[2]); +} + +static void ec_GFp_nistp224_felem_mul(const EC_GROUP *group, EC_FELEM *r, + const EC_FELEM *a, const EC_FELEM *b) { + p224_felem felem1, felem2; + p224_widefelem wide; + p224_generic_to_felem(felem1, a); + p224_generic_to_felem(felem2, b); + p224_felem_mul(wide, felem1, felem2); + p224_felem_reduce(felem1, wide); + p224_felem_to_generic(r, felem1); +} + +static void ec_GFp_nistp224_felem_sqr(const EC_GROUP *group, EC_FELEM *r, + const EC_FELEM *a) { + p224_felem felem; + p224_generic_to_felem(felem, a); + p224_widefelem wide; + p224_felem_square(wide, felem); + p224_felem_reduce(felem, wide); + p224_felem_to_generic(r, felem); +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) { + out->group_init = ec_GFp_simple_group_init; + out->group_finish = ec_GFp_simple_group_finish; + out->group_set_curve = ec_GFp_simple_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp224_point_get_affine_coordinates; + out->add = ec_GFp_nistp224_add; + out->dbl = ec_GFp_nistp224_dbl; + out->mul = ec_GFp_nistp224_point_mul; + out->mul_base = ec_GFp_nistp224_point_mul_base; + out->mul_public = ec_GFp_nistp224_point_mul_public; + out->felem_mul = ec_GFp_nistp224_felem_mul; + out->felem_sqr = ec_GFp_nistp224_felem_sqr; + out->felem_to_bytes = ec_GFp_simple_felem_to_bytes; + out->felem_from_bytes = ec_GFp_simple_felem_from_bytes; + out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery; + out->scalar_to_montgomery_inv_vartime = + ec_simple_scalar_to_montgomery_inv_vartime; + out->cmp_x_coordinate = ec_GFp_simple_cmp_x_coordinate; +} + +#endif // BORINGSSL_HAS_UINT128 && !SMALL diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz-table.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz-table.h new file mode 100644 index 00000000..b81480bd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz-table.h @@ -0,0 +1,9497 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2015, Intel Inc. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +// This is the precomputed constant time access table for the code in +// p256-nistz.c, for the default generator. The table consists of 37 +// subtables, each subtable contains 64 affine points. The affine points are +// encoded as eight uint64's, four for the x coordinate and four for the y. +// Both values are in little-endian order. There are 37 tables because a +// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37. +// Within each table there are 64 values because the 6-bit wNAF value can take +// 64 values, ignoring the sign bit, which is implemented by performing a +// negation of the affine point when required. We would like to align it to 2MB +// in order to increase the chances of using a large page but that appears to +// lead to invalid ELF files being produced. + +// This file is generated by make_tables.go. + +static const alignas(4096) PRECOMP256_ROW ecp_nistz256_precomputed[37] = { + {{{TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601), + TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6)}, + {TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c), + TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)}}, + {{TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d), + TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b)}, + {TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8), + TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b)}}, + {{TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb), + TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e)}, + {TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a), + TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07)}}, + {{TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173), + TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b)}, + {TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447), + TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863)}}, + {{TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d), + TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8)}, + {TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b), + TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916)}}, + {{TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e), + TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673)}, + {TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5), + TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f)}}, + {{TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7), + TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03)}, + {TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd), + TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867)}}, + {{TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455), + TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d)}, + {TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15), + TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76)}}, + {{TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841), + TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b)}, + {TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3), + TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b)}}, + {{TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139), + TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f)}, + {TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08), + TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5)}}, + {{TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0), + TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073)}, + {TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8), + TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e)}}, + {{TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33), + TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156)}, + {TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637), + TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca)}}, + {{TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d), + TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759)}, + {TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3), + TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797)}}, + {{TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3), + TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e)}, + {TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2), + TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb)}}, + {{TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b), + TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09)}, + {TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25), + TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4)}}, + {{TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b), + TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723)}, + {TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587), + TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220)}}, + {{TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b), + TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e)}, + {TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e), + TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0)}}, + {{TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e), + TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda)}, + {TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c), + TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d)}}, + {{TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e), + TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc)}, + {TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5), + TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b)}}, + {{TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc), + TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e)}, + {TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae), + TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0)}}, + {{TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d), + TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc)}, + {TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61), + TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3)}}, + {{TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a), + TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4)}, + {TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4), + TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074)}}, + {{TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e), + TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42)}, + {TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a), + TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f)}}, + {{TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35), + TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115)}, + {TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356), + TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a)}}, + {{TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0), + TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e)}, + {TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950), + TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968)}}, + {{TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538), + TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10)}, + {TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508), + TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7)}}, + {{TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313), + TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a)}, + {TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58), + TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31)}}, + {{TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892), + TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97)}, + {TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68), + TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278)}}, + {{TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880), + TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48)}, + {TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3), + TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b)}}, + {{TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1), + TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c)}, + {TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a), + TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72)}}, + {{TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6), + TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4)}, + {TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028), + TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745)}}, + {{TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf), + TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4)}, + {TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908), + TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4)}}, + {{TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103), + TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c)}, + {TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef), + TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4)}}, + {{TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d), + TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64)}, + {TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92), + TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8)}}, + {{TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7), + TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521)}, + {TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5), + TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8)}}, + {{TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f), + TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3)}, + {TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13), + TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526)}}, + {{TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55), + TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb)}, + {TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850), + TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8)}}, + {{TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce), + TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c)}, + {TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409), + TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d)}}, + {{TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346), + TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac)}, + {TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876), + TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408)}}, + {{TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c), + TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227)}, + {TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34), + TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f)}}, + {{TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822), + TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f)}, + {TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47), + TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b)}}, + {{TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7), + TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43)}, + {TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae), + TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d)}}, + {{TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa), + TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994)}, + {TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8), + TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0)}}, + {{TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb), + TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291)}, + {TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f), + TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a)}}, + {{TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18), + TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278)}, + {TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5), + TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5)}}, + {{TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba), + TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc)}, + {TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b), + TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865)}}, + {{TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906), + TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd)}, + {TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13), + TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27)}}, + {{TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0), + TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad)}, + {TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7), + TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2)}}, + {{TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909), + TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b)}, + {TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a), + TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36)}}, + {{TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278), + TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7)}, + {TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96), + TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13)}}, + {{TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f), + TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443)}, + {TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65), + TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d)}}, + {{TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0), + TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542)}, + {TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562), + TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d)}}, + {{TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679), + TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0)}, + {TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2), + TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283)}}, + {{TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f), + TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851)}, + {TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa), + TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb)}}, + {{TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6), + TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd)}, + {TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4), + TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4)}}, + {{TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a), + TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63)}, + {TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b), + TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08)}}, + {{TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29), + TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc)}, + {TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a), + TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626)}}, + {{TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf), + TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd)}, + {TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad), + TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741)}}, + {{TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1), + TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7)}, + {TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea), + TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b)}}, + {{TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7), + TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915)}, + {TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c), + TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832)}}, + {{TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84), + TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa)}, + {TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d), + TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3)}}, + {{TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7), + TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413)}, + {TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e), + TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009)}}, + {{TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed), + TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d)}, + {TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197), + TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70)}}, + {{TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9), + TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7)}, + {TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82), + TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)}}}, + {{{TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54), + TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617)}, + {TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff), + TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188)}}, + {{TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d), + TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c)}, + {TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5), + TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53)}}, + {{TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5), + TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6)}, + {TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3), + TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656)}}, + {{TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5), + TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290)}, + {TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d), + TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108)}}, + {{TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be), + TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502)}, + {TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220), + TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a)}}, + {{TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3), + TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4)}, + {TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd), + TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2)}}, + {{TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95), + TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0)}, + {TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda), + TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232)}}, + {{TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf), + TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863)}, + {TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd), + TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f)}}, + {{TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298), + TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c)}, + {TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78), + TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2)}}, + {{TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8), + TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014)}, + {TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30), + TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb)}}, + {{TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638), + TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec)}, + {TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314), + TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868)}}, + {{TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146), + TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e)}, + {TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f), + TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435)}}, + {{TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2), + TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808)}, + {TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3), + TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd)}}, + {{TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90), + TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60)}, + {TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347), + TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2)}}, + {{TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957), + TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec)}, + {TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3), + TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e)}}, + {{TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509), + TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45)}, + {TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d), + TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f)}}, + {{TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f), + TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85)}, + {TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54), + TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f)}}, + {{TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0), + TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6)}, + {TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787), + TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8)}}, + {{TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d), + TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176)}, + {TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc), + TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1)}}, + {{TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701), + TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442)}, + {TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30), + TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959)}}, + {{TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f), + TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f)}, + {TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be), + TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac)}}, + {{TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295), + TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c)}, + {TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241), + TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97)}}, + {{TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a), + TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f)}, + {TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0), + TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f)}}, + {{TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678), + TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48)}, + {TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948), + TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184)}}, + {{TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6), + TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f)}, + {TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52), + TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369)}}, + {{TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd), + TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887)}, + {TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682), + TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6)}}, + {{TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901), + TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef)}, + {TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549), + TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9)}}, + {{TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f), + TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c)}, + {TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278), + TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f)}}, + {{TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd), + TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04)}, + {TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad), + TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084)}}, + {{TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5), + TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723)}, + {TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd), + TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9)}}, + {{TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2), + TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c)}, + {TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24), + TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2)}}, + {{TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf), + TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da)}, + {TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad), + TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9)}}, + {{TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254), + TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39)}, + {TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6), + TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09)}}, + {{TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3), + TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc)}, + {TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1), + TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6)}}, + {{TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b), + TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec)}, + {TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14), + TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1)}}, + {{TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1), + TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09)}, + {TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e), + TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331)}}, + {{TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830), + TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da)}, + {TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0), + TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7)}}, + {{TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be), + TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb)}, + {TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1), + TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a)}}, + {{TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d), + TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b)}, + {TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d), + TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8)}}, + {{TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a), + TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272)}, + {TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82), + TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525)}}, + {{TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3), + TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a)}, + {TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159), + TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32)}}, + {{TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb), + TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4)}, + {TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01), + TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f)}}, + {{TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a), + TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120)}, + {TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b), + TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1)}}, + {{TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17), + TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c)}, + {TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3), + TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7)}}, + {{TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043), + TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2)}, + {TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4), + TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084)}}, + {{TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546), + TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd)}, + {TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7), + TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715)}}, + {{TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93), + TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e)}, + {TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26), + TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa)}}, + {{TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681), + TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663)}, + {TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce), + TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607)}}, + {{TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c), + TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72)}, + {TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992), + TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8)}}, + {{TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485), + TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7)}, + {TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50), + TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253)}}, + {{TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04), + TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1)}, + {TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13), + TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce)}}, + {{TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13), + TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe)}, + {TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747), + TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a)}}, + {{TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da), + TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b)}, + {TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0), + TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26)}}, + {{TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4), + TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621)}, + {TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3), + TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0)}}, + {{TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de), + TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228)}, + {TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa), + TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d)}}, + {{TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381), + TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb)}, + {TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9), + TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407)}}, + {{TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748), + TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb)}, + {TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661), + TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f)}}, + {{TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c), + TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45)}, + {TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19), + TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45)}}, + {{TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc), + TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131)}, + {TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980), + TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663)}}, + {{TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42), + TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589)}, + {TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212), + TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76)}}, + {{TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e), + TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5)}, + {TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee), + TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd)}}, + {{TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d), + TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e)}, + {TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773), + TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3)}}, + {{TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c), + TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0)}, + {TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545), + TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4)}}, + {{TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182), + TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085)}, + {TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b), + TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)}}}, + {{{TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8), + TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551)}, + {TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164), + TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38)}}, + {{TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0), + TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825)}, + {TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b), + TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a)}}, + {{TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35), + TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699)}, + {TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562), + TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6)}}, + {{TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e), + TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219)}, + {TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf), + TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415)}}, + {{TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012), + TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d)}, + {TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334), + TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f)}}, + {{TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18), + TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7)}, + {TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0), + TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151)}}, + {{TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af), + TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3)}, + {TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5), + TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514)}}, + {{TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142), + TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922)}, + {TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1), + TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b)}}, + {{TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d), + TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8)}, + {TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69), + TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1)}}, + {{TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5), + TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41)}, + {TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9), + TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63)}}, + {{TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b), + TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f)}, + {TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b), + TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440)}}, + {{TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72), + TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5)}, + {TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900), + TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a)}}, + {{TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c), + TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf)}, + {TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981), + TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe)}}, + {{TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031), + TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d)}, + {TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4), + TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88)}}, + {{TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8), + TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6)}, + {TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03), + TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51)}}, + {{TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f), + TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f)}, + {TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e), + TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53)}}, + {{TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c), + TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e)}, + {TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef), + TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d)}}, + {{TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de), + TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36)}, + {TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8), + TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82)}}, + {{TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e), + TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee)}, + {TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26), + TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e)}}, + {{TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337), + TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590)}, + {TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249), + TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b)}}, + {{TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6), + TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823)}, + {TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71), + TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91)}}, + {{TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273), + TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067)}, + {TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e), + TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530)}}, + {{TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606), + TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303)}, + {TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd), + TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a)}}, + {{TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7), + TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb)}, + {TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976), + TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609)}}, + {{TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90), + TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3)}, + {TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2), + TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec)}}, + {{TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43), + TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af)}, + {TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538), + TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6)}}, + {{TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79), + TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4)}, + {TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225), + TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153)}}, + {{TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99), + TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8)}, + {TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f), + TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10)}}, + {{TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864), + TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822)}, + {TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92), + TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87)}}, + {{TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1), + TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f)}, + {TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3), + TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba)}}, + {{TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917), + TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8)}, + {TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf), + TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234)}}, + {{TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1), + TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e)}, + {TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb), + TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f)}}, + {{TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43), + TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94)}, + {TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3), + TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a)}}, + {{TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d), + TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf)}, + {TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129), + TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7)}}, + {{TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4), + TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13)}, + {TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137), + TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85)}}, + {{TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390), + TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9)}, + {TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06), + TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331)}}, + {{TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50), + TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f)}, + {TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5), + TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77)}}, + {{TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2), + TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17)}, + {TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2), + TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76)}}, + {{TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc), + TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722)}, + {TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b), + TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba)}}, + {{TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b), + TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c)}, + {TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8), + TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855)}}, + {{TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73), + TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793)}, + {TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd), + TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07)}}, + {{TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749), + TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b)}, + {TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55), + TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b)}}, + {{TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e), + TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f)}, + {TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2), + TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80)}}, + {{TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114), + TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760)}, + {TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f), + TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d)}}, + {{TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c), + TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a)}, + {TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5), + TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14)}}, + {{TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649), + TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd)}, + {TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5), + TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523)}}, + {{TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92), + TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa)}, + {TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934), + TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50)}}, + {{TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05), + TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f)}, + {TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32), + TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef)}}, + {{TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e), + TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6)}, + {TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1), + TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207)}}, + {{TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c), + TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043)}, + {TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0), + TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391)}}, + {{TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da), + TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545)}, + {TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92), + TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5)}}, + {{TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7), + TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1)}, + {TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b), + TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71)}}, + {{TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18), + TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a)}, + {TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c), + TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a)}}, + {{TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0), + TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95)}, + {TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee), + TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55)}}, + {{TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc), + TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21)}, + {TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f), + TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44)}}, + {{TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea), + TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06)}, + {TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48), + TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d)}}, + {{TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4), + TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52)}, + {TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840), + TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf)}}, + {{TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32), + TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd)}, + {TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b), + TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6)}}, + {{TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958), + TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658)}, + {TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1), + TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab)}}, + {{TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7), + TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656)}, + {TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945), + TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de)}}, + {{TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd), + TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984)}, + {TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09), + TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c)}}, + {{TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e), + TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156)}, + {TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f), + TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd)}}, + {{TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca), + TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36)}, + {TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af), + TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0)}}, + {{TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035), + TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3)}, + {TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc), + TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)}}}, + {{{TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6), + TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829)}, + {TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8), + TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca)}}, + {{TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e), + TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db)}, + {TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3), + TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c)}}, + {{TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b), + TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a)}, + {TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042), + TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f)}}, + {{TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f), + TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e)}, + {TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509), + TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837)}}, + {{TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758), + TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68)}, + {TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5), + TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453)}}, + {{TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6), + TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4)}, + {TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881), + TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6)}}, + {{TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f), + TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89)}, + {TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34), + TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50)}}, + {{TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea), + TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed)}, + {TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6), + TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082)}}, + {{TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e), + TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10)}, + {TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9), + TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a)}}, + {{TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783), + TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8)}, + {TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60), + TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a)}}, + {{TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e), + TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346)}, + {TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9), + TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b)}}, + {{TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3), + TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7)}, + {TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef), + TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3)}}, + {{TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc), + TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9)}, + {TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e), + TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52)}}, + {{TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544), + TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f)}, + {TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d), + TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e)}}, + {{TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755), + TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d)}, + {TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5), + TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f)}}, + {{TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3), + TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142)}, + {TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942), + TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4)}}, + {{TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7), + TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0)}, + {TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e), + TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864)}}, + {{TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024), + TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d)}, + {TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279), + TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab)}}, + {{TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19), + TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc)}, + {TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d), + TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940)}}, + {{TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea), + TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d)}, + {TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b), + TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821)}}, + {{TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b), + TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d)}, + {TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2), + TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d)}}, + {{TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18), + TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8)}, + {TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246), + TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7)}}, + {{TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1), + TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006)}, + {TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d), + TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20)}}, + {{TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318), + TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a)}, + {TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb), + TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b)}}, + {{TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f), + TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9)}, + {TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88), + TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3)}}, + {{TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221), + TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb)}, + {TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84), + TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f)}}, + {{TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267), + TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397)}, + {TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f), + TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec)}}, + {{TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373), + TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7)}, + {TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead), + TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b)}}, + {{TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032), + TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db)}, + {TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460), + TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3)}}, + {{TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e), + TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124)}, + {TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069), + TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431)}}, + {{TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431), + TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b)}, + {TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57), + TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460)}}, + {{TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869), + TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc)}, + {TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49), + TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251)}}, + {{TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205), + TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149)}, + {TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33), + TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e)}}, + {{TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40), + TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292)}, + {TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4), + TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6)}}, + {{TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79), + TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d)}, + {TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd), + TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968)}}, + {{TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c), + TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280)}, + {TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe), + TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac)}}, + {{TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305), + TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8)}, + {TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010), + TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae)}}, + {{TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13), + TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed)}, + {TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65), + TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee)}}, + {{TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd), + TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257)}, + {TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65), + TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d)}}, + {{TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750), + TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7)}, + {TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251), + TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28)}}, + {{TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea), + TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e)}, + {TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af), + TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b)}}, + {{TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa), + TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582)}, + {TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468), + TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0)}}, + {{TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2), + TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed)}, + {TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0), + TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7)}}, + {{TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426), + TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241)}, + {TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace), + TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885)}}, + {{TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2), + TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8)}, + {TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd), + TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab)}}, + {{TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533), + TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd)}, + {TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1), + TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95)}}, + {{TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff), + TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71)}, + {TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e), + TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba)}}, + {{TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734), + TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9)}, + {TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703), + TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953)}}, + {{TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d), + TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5)}, + {TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1), + TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c)}}, + {{TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da), + TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311)}, + {TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f), + TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0)}}, + {{TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877), + TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352)}, + {TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba), + TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8)}}, + {{TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27), + TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd)}, + {TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f), + TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16)}}, + {{TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0), + TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e)}, + {TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136), + TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f)}}, + {{TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7), + TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4)}, + {TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca), + TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42)}}, + {{TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6), + TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1)}, + {TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed), + TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301)}}, + {{TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b), + TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02)}, + {TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720), + TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef)}}, + {{TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e), + TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7)}, + {TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795), + TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900)}}, + {{TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd), + TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54)}, + {TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa), + TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32)}}, + {{TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db), + TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c)}, + {TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff), + TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544)}}, + {{TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892), + TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc)}, + {TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c), + TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e)}}, + {{TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948), + TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37)}, + {TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65), + TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141)}}, + {{TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a), + TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f)}, + {TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8), + TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9)}}, + {{TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d), + TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe)}, + {TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1), + TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805)}}, + {{TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952), + TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37)}, + {TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b), + TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)}}}, + {{{TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206), + TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec)}, + {TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3), + TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c)}}, + {{TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5), + TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529)}, + {TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80), + TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be)}}, + {{TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c), + TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436)}, + {TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4), + TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a)}}, + {{TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc), + TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc)}, + {TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56), + TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba)}}, + {{TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74), + TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439)}, + {TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a), + TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158)}}, + {{TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e), + TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4)}, + {TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a), + TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321)}}, + {{TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493), + TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c)}, + {TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9), + TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b)}}, + {{TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb), + TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f)}, + {TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca), + TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3)}}, + {{TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27), + TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6)}, + {TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5), + TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d)}}, + {{TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7), + TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4)}, + {TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0), + TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080)}}, + {{TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b), + TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc)}, + {TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186), + TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610)}}, + {{TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3), + TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297)}, + {TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7), + TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76)}}, + {{TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef), + TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521)}, + {TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da), + TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370)}}, + {{TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146), + TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5)}, + {TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980), + TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de)}}, + {{TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8), + TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519)}, + {TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f), + TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f)}}, + {{TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0), + TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9)}, + {TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917), + TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3)}}, + {{TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358), + TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a)}, + {TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61), + TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207)}}, + {{TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c), + TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60)}, + {TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca), + TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493)}}, + {{TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0), + TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d)}, + {TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24), + TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01)}}, + {{TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665), + TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839)}, + {TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b), + TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0)}}, + {{TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09), + TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c)}, + {TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6), + TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4)}}, + {{TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484), + TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31)}, + {TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9), + TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9)}}, + {{TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7), + TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4)}, + {TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324), + TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d)}}, + {{TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e), + TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43)}, + {TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5), + TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60)}}, + {{TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba), + TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376)}, + {TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a), + TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d)}}, + {{TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551), + TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba)}, + {TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628), + TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108)}}, + {{TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9), + TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510)}, + {TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742), + TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207)}}, + {{TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4), + TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9)}, + {TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32), + TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4)}}, + {{TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753), + TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f)}, + {TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f), + TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d)}}, + {{TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20), + TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975)}, + {TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b), + TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b)}}, + {{TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7), + TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a)}, + {TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade), + TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b)}}, + {{TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620), + TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6)}, + {TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44), + TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c)}}, + {{TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585), + TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d)}, + {TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930), + TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a)}}, + {{TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493), + TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502)}, + {TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed), + TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58)}}, + {{TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b), + TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788)}, + {TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669), + TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865)}}, + {{TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3), + TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d)}, + {TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63), + TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e)}}, + {{TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42), + TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5)}, + {TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07), + TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129)}}, + {{TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93), + TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f)}, + {TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f), + TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1)}}, + {{TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b), + TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91)}, + {TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca), + TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824)}}, + {{TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522), + TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61)}, + {TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b), + TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2)}}, + {{TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c), + TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e)}, + {TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02), + TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631)}}, + {{TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d), + TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432)}, + {TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea), + TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb)}}, + {{TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522), + TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec)}, + {TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e), + TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7)}}, + {{TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076), + TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5)}, + {TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef), + TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad)}}, + {{TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf), + TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3)}, + {TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527), + TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0)}}, + {{TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde), + TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4)}, + {TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d), + TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650)}}, + {{TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a), + TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265)}, + {TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176), + TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e)}}, + {{TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1), + TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7)}, + {TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132), + TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025)}}, + {{TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76), + TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e)}, + {TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2), + TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b)}}, + {{TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea), + TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b)}, + {TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81), + TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375)}}, + {{TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65), + TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a)}, + {TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d), + TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5)}}, + {{TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20), + TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f)}, + {TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03), + TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82)}}, + {{TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f), + TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122)}, + {TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a), + TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88)}}, + {{TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e), + TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431)}, + {TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7), + TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c)}}, + {{TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb), + TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71)}, + {TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d), + TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68)}}, + {{TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85), + TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f)}, + {TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928), + TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514)}}, + {{TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd), + TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1)}, + {TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07), + TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c)}}, + {{TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573), + TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f)}, + {TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403), + TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728)}}, + {{TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43), + TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b)}, + {TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c), + TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2)}}, + {{TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8), + TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904)}, + {TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065), + TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6)}}, + {{TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0), + TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588)}, + {TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73), + TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493)}}, + {{TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3), + TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9)}, + {TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58), + TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314)}}, + {{TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a), + TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288)}, + {TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26), + TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3)}}, + {{TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5), + TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967)}, + {TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6), + TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)}}}, + {{{TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366), + TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5)}, + {TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576), + TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7)}}, + {{TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957), + TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4)}, + {TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682), + TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae)}}, + {{TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf), + TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9)}, + {TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4), + TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402)}}, + {{TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06), + TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381)}, + {TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b), + TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa)}}, + {{TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784), + TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228)}, + {TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118), + TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e)}}, + {{TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550), + TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048)}, + {TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7), + TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d)}}, + {{TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5), + TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f)}, + {TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68), + TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3)}}, + {{TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67), + TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0)}, + {TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19), + TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077)}}, + {{TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494), + TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4)}, + {TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7), + TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67)}}, + {{TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6), + TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8)}, + {TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27), + TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0)}}, + {{TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096), + TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d)}, + {TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21), + TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb)}}, + {{TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2), + TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc)}, + {TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c), + TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84)}}, + {{TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a), + TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b)}, + {TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0), + TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69)}}, + {{TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937), + TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3)}, + {TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422), + TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6)}}, + {{TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06), + TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce)}, + {TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598), + TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05)}}, + {{TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d), + TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08)}, + {TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158), + TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4)}}, + {{TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221), + TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85)}, + {TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5), + TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284)}}, + {{TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2), + TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73)}, + {TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90), + TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3)}}, + {{TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e), + TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a)}, + {TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80), + TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e)}}, + {{TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4), + TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064)}, + {TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab), + TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02)}}, + {{TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7), + TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc)}, + {TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1), + TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c)}}, + {{TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb), + TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8)}, + {TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe), + TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b)}}, + {{TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736), + TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0)}, + {TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83), + TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393)}}, + {{TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b), + TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae)}, + {TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5), + TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30)}}, + {{TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3), + TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a)}, + {TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066), + TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e)}}, + {{TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3), + TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf)}, + {TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6), + TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289)}}, + {{TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684), + TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5)}, + {TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e), + TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c)}}, + {{TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0), + TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f)}, + {TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2), + TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7)}}, + {{TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a), + TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45)}, + {TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9), + TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5)}}, + {{TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531), + TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af)}, + {TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f), + TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e)}}, + {{TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db), + TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7)}, + {TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073), + TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa)}}, + {{TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87), + TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f)}, + {TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace), + TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58)}}, + {{TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9), + TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41)}, + {TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f), + TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59)}}, + {{TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0), + TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961)}, + {TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c), + TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225)}}, + {{TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef), + TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734)}, + {TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6), + TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6)}}, + {{TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06), + TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08)}, + {TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de), + TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff)}}, + {{TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe), + TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e)}, + {TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee), + TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056)}}, + {{TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0), + TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709)}, + {TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0), + TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a)}}, + {{TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a), + TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d)}, + {TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6), + TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a)}}, + {{TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32), + TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d)}, + {TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a), + TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870)}}, + {{TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653), + TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea)}, + {TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc), + TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf)}}, + {{TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4), + TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390)}, + {TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc), + TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88)}}, + {{TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041), + TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe)}, + {TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0), + TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020)}}, + {{TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079), + TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662)}, + {TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53), + TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d)}}, + {{TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b), + TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c)}, + {TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c), + TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251)}}, + {{TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7), + TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238)}, + {TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce), + TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e)}}, + {{TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c), + TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592)}, + {TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8), + TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08)}}, + {{TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7), + TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7)}, + {TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc), + TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13)}}, + {{TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c), + TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63)}, + {TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea), + TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26)}}, + {{TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1), + TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa)}, + {TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483), + TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c)}}, + {{TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea), + TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103)}, + {TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4), + TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d)}}, + {{TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61), + TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80)}, + {TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e), + TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88)}}, + {{TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3), + TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10)}, + {TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69), + TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413)}}, + {{TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475), + TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4)}, + {TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d), + TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e)}}, + {{TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac), + TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553)}, + {TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290), + TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732)}}, + {{TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f), + TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46)}, + {TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486), + TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a)}}, + {{TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392), + TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b)}, + {TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa), + TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6)}}, + {{TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475), + TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644)}, + {TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3), + TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17)}}, + {{TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44), + TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688)}, + {TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b), + TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c)}}, + {{TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958), + TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea)}, + {TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb), + TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb)}}, + {{TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a), + TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50)}, + {TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588), + TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4)}}, + {{TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420), + TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6)}, + {TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2), + TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd)}}, + {{TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4), + TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82)}, + {TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8), + TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a)}}, + {{TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20), + TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8)}, + {TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27), + TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)}}}, + {{{TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350), + TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e)}, + {TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b), + TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78)}}, + {{TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c), + TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893)}, + {TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3), + TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07)}}, + {{TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325), + TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3)}, + {TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64), + TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614)}}, + {{TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63), + TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b)}, + {TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71), + TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f)}}, + {{TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2), + TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad)}, + {TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498), + TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3)}}, + {{TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6), + TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24)}, + {TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb), + TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4)}}, + {{TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b), + TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17)}, + {TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621), + TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c)}}, + {{TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef), + TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39)}, + {TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665), + TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69)}}, + {{TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9), + TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0)}, + {TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0), + TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8)}}, + {{TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1), + TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe)}, + {TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c), + TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615)}}, + {{TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef), + TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba)}, + {TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030), + TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725)}}, + {{TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362), + TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990)}, + {TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd), + TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca)}}, + {{TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581), + TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5)}, + {TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51), + TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76)}}, + {{TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97), + TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd)}, + {TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b), + TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715)}}, + {{TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51), + TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b)}, + {TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3), + TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924)}}, + {{TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49), + TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4)}, + {TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb), + TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d)}}, + {{TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369), + TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae)}, + {TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1), + TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed)}}, + {{TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3), + TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac)}, + {TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933), + TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369)}}, + {{TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13), + TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6)}, + {TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956), + TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a)}}, + {{TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c), + TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55)}, + {TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e), + TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5)}}, + {{TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a), + TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72)}, + {TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0), + TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704)}}, + {{TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0), + TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e)}, + {TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092), + TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2)}}, + {{TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164), + TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0)}, + {TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f), + TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b)}}, + {{TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b), + TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512)}, + {TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b), + TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd)}}, + {{TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e), + TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32)}, + {TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963), + TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a)}}, + {{TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48), + TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a)}, + {TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a), + TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2)}}, + {{TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925), + TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd)}, + {TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c), + TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae)}}, + {{TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b), + TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a)}, + {TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb), + TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504)}}, + {{TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34), + TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f)}, + {TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1), + TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51)}}, + {{TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9), + TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867)}, + {TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac), + TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85)}}, + {{TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee), + TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6)}, + {TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c), + TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b)}}, + {{TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241), + TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df)}, + {TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0), + TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b)}}, + {{TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034), + TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6)}, + {TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e), + TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0)}}, + {{TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb), + TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111)}, + {TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7), + TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f)}}, + {{TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e), + TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02)}, + {TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b), + TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d)}}, + {{TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d), + TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5)}, + {TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2), + TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc)}}, + {{TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c), + TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384)}, + {TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752), + TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0)}}, + {{TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc), + TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc)}, + {TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062), + TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7)}}, + {{TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8), + TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d)}, + {TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8), + TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19)}}, + {{TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf), + TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536)}, + {TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837), + TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740)}}, + {{TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7), + TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7)}, + {TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a), + TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab)}}, + {{TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8), + TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b)}, + {TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef), + TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75)}}, + {{TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72), + TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0)}, + {TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79), + TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151)}}, + {{TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21), + TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a)}, + {TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc), + TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b)}}, + {{TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f), + TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552)}, + {TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb), + TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8)}}, + {{TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95), + TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be)}, + {TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387), + TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a)}}, + {{TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de), + TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3)}, + {TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e), + TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7)}}, + {{TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57), + TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706)}, + {TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d), + TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5)}}, + {{TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7), + TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6)}, + {TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d), + TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7)}}, + {{TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f), + TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db)}, + {TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291), + TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8)}}, + {{TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080), + TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02)}, + {TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12), + TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc)}}, + {{TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397), + TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4)}, + {TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba), + TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a)}}, + {{TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd), + TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180)}, + {TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678), + TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf)}}, + {{TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f), + TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b)}, + {TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a), + TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9)}}, + {{TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c), + TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd)}, + {TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011), + TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c)}}, + {{TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde), + TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0)}, + {TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357), + TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6)}}, + {{TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719), + TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe)}, + {TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996), + TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e)}}, + {{TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3), + TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec)}, + {TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44), + TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335)}}, + {{TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba), + TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686)}, + {TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e), + TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51)}}, + {{TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c), + TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f)}, + {TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b), + TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b)}}, + {{TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792), + TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89)}, + {TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2), + TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705)}}, + {{TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3), + TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734)}, + {TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3), + TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41)}}, + {{TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075), + TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb)}, + {TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d), + TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643)}}, + {{TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83), + TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588)}, + {TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127), + TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)}}}, + {{{TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c), + TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698)}, + {TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81), + TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d)}}, + {{TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7), + TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724)}, + {TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac), + TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e)}}, + {{TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0), + TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd)}, + {TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031), + TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73)}}, + {{TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e), + TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9)}, + {TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a), + TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695)}}, + {{TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466), + TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b)}, + {TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15), + TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357)}}, + {{TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97), + TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d)}, + {TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6), + TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8)}}, + {{TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da), + TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c)}, + {TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8), + TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07)}}, + {{TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0), + TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2)}, + {TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5), + TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0)}}, + {{TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c), + TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e)}, + {TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07), + TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1)}}, + {{TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8), + TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05)}, + {TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b), + TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b)}}, + {{TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8), + TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b)}, + {TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821), + TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a)}}, + {{TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc), + TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd)}, + {TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f), + TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6)}}, + {{TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461), + TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47)}, + {TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04), + TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc)}}, + {{TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4), + TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f)}, + {TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040), + TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1)}}, + {{TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564), + TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619)}, + {TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a), + TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f)}}, + {{TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b), + TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a)}, + {TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560), + TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd)}}, + {{TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a), + TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62)}, + {TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880), + TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b)}}, + {{TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943), + TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894)}, + {TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f), + TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c)}}, + {{TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290), + TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6)}, + {TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f), + TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d)}}, + {{TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c), + TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e)}, + {TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342), + TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d)}}, + {{TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078), + TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645)}, + {TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e), + TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c)}}, + {{TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9), + TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8)}, + {TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7), + TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c)}}, + {{TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596), + TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499)}, + {TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b), + TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c)}}, + {{TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a), + TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43)}, + {TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a), + TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b)}}, + {{TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0), + TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578)}, + {TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f), + TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442)}}, + {{TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17), + TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0)}, + {TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271), + TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70)}}, + {{TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f), + TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1)}, + {TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93), + TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3)}}, + {{TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232), + TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf)}, + {TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4), + TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a)}}, + {{TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17), + TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168)}, + {TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d), + TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1)}}, + {{TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811), + TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a)}, + {TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0), + TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089)}}, + {{TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682), + TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456)}, + {TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b), + TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12)}}, + {{TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69), + TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8)}, + {TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e), + TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5)}}, + {{TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d), + TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb)}, + {TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1), + TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146)}}, + {{TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c), + TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e)}, + {TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6), + TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004)}}, + {{TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9), + TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052)}, + {TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219), + TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c)}}, + {{TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd), + TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e)}, + {TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a), + TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156)}}, + {{TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b), + TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa)}, + {TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9), + TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125)}}, + {{TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3), + TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21)}, + {TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643), + TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6)}}, + {{TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb), + TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec)}, + {TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac), + TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f)}}, + {{TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d), + TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62)}, + {TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2), + TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49)}}, + {{TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044), + TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714)}, + {TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1), + TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d)}}, + {{TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d), + TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5)}, + {TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73), + TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b)}}, + {{TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb), + TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490)}, + {TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d), + TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1)}}, + {{TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6), + TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db)}, + {TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44), + TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd)}}, + {{TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee), + TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c)}, + {TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a), + TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc)}}, + {{TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726), + TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02)}, + {TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692), + TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8)}}, + {{TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b), + TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7)}, + {TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22), + TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6)}}, + {{TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5), + TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff)}, + {TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0), + TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66)}}, + {{TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c), + TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729)}, + {TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da), + TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1)}}, + {{TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049), + TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822)}, + {TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40), + TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2)}}, + {{TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469), + TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8)}, + {TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14), + TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3)}}, + {{TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18), + TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040)}, + {TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d), + TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7)}}, + {{TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7), + TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87)}, + {TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988), + TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98)}}, + {{TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3), + TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558)}, + {TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1), + TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693)}}, + {{TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363), + TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da)}, + {TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e), + TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e)}}, + {{TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9), + TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e)}, + {TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10), + TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db)}}, + {{TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e), + TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd)}, + {TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9), + TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd)}}, + {{TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083), + TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab)}, + {TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4), + TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face)}}, + {{TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd), + TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb)}, + {TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d), + TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df)}}, + {{TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3), + TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2)}, + {TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8), + TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f)}}, + {{TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d), + TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340)}, + {TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0), + TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68)}}, + {{TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df), + TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce)}, + {TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d), + TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e)}}, + {{TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288), + TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc)}, + {TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274), + TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea)}}, + {{TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410), + TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58)}, + {TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b), + TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)}}}, + {{{TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686), + TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54)}, + {TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964), + TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a)}}, + {{TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef), + TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0)}, + {TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717), + TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6)}}, + {{TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729), + TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4)}, + {TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05), + TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a)}}, + {{TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf), + TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87)}, + {TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264), + TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb)}}, + {{TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94), + TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00)}, + {TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0), + TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd)}}, + {{TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84), + TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72)}, + {TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1), + TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d)}}, + {{TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b), + TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e)}, + {TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca), + TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7)}}, + {{TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624), + TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346)}, + {TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3), + TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b)}}, + {{TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620), + TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510)}, + {TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac), + TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4)}}, + {{TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4), + TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a)}, + {TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627), + TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326)}}, + {{TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e), + TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727)}, + {TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2), + TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc)}}, + {{TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223), + TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d)}, + {TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168), + TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299)}}, + {{TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934), + TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6)}, + {TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028), + TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29)}}, + {{TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108), + TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5)}, + {TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140), + TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2)}}, + {{TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63), + TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972)}, + {TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42), + TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474)}}, + {{TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9), + TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20)}, + {TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2), + TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16)}}, + {{TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6), + TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b)}, + {TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a), + TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284)}}, + {{TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80), + TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be)}, + {TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd), + TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9)}}, + {{TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0), + TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517)}, + {TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7), + TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a)}}, + {{TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27), + TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01)}, + {TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6), + TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86)}}, + {{TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27), + TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb)}, + {TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6), + TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0)}}, + {{TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f), + TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804)}, + {TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592), + TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e)}}, + {{TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab), + TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11)}, + {TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95), + TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49)}}, + {{TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0), + TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616)}, + {TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c), + TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96)}}, + {{TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652), + TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d)}, + {TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10), + TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f)}}, + {{TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144), + TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf)}, + {TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417), + TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c)}}, + {{TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66), + TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291)}, + {TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e), + TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a)}}, + {{TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229), + TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3)}, + {TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef), + TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549)}}, + {{TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032), + TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b)}, + {TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575), + TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771)}}, + {{TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e), + TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344)}, + {TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae), + TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188)}}, + {{TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91), + TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958)}, + {TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598), + TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6)}}, + {{TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496), + TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813)}, + {TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d), + TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782)}}, + {{TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02), + TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a)}, + {TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410), + TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2)}}, + {{TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c), + TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c)}, + {TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8), + TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18)}}, + {{TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b), + TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da)}, + {TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8), + TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88)}}, + {{TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4), + TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d)}, + {TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac), + TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1)}}, + {{TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e), + TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826)}, + {TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215), + TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86)}}, + {{TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333), + TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546)}, + {TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7), + TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb)}}, + {{TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749), + TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5)}, + {TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b), + TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26)}}, + {{TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b), + TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f)}, + {TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981), + TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c)}}, + {{TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760), + TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551)}, + {TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1), + TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5)}}, + {{TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f), + TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef)}, + {TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df), + TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150)}}, + {{TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214), + TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c)}, + {TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e), + TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31)}}, + {{TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393), + TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6)}, + {TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be), + TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022)}}, + {{TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65), + TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236)}, + {TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188), + TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a)}}, + {{TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d), + TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db)}, + {TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349), + TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f)}}, + {{TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697), + TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7)}, + {TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3), + TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45)}}, + {{TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401), + TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21)}, + {TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1), + TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b)}}, + {{TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb), + TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de)}, + {TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388), + TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde)}}, + {{TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9), + TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db)}, + {TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c), + TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0)}}, + {{TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342), + TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987)}, + {TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb), + TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86)}}, + {{TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74), + TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0)}, + {TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce), + TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e)}}, + {{TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6), + TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8)}, + {TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620), + TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13)}}, + {{TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821), + TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060)}, + {TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901), + TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286)}}, + {{TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7), + TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324)}, + {TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012), + TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4)}}, + {{TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2), + TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286)}, + {TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160), + TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a)}}, + {{TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d), + TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d)}, + {TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057), + TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b)}}, + {{TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf), + TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64)}, + {TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b), + TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635)}}, + {{TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091), + TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985)}, + {TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6), + TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27)}}, + {{TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b), + TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e)}, + {TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32), + TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393)}}, + {{TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5), + TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94)}, + {TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357), + TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b)}}, + {{TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1), + TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9)}, + {TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af), + TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913)}}, + {{TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e), + TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21)}, + {TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659), + TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8)}}, + {{TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2), + TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d)}, + {TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef), + TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)}}}, + {{{TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8), + TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8)}, + {TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98), + TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02)}}, + {{TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499), + TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f)}, + {TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192), + TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b)}}, + {{TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869), + TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e)}, + {TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411), + TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d)}}, + {{TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a), + TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7)}, + {TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426), + TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173)}}, + {{TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74), + TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102)}, + {TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2), + TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d)}}, + {{TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7), + TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012)}, + {TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21), + TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae)}}, + {{TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e), + TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9)}, + {TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652), + TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4)}}, + {{TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770), + TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c)}, + {TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b), + TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68)}}, + {{TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69), + TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868)}, + {TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54), + TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d)}}, + {{TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b), + TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc)}, + {TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208), + TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6)}}, + {{TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc), + TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b)}, + {TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8), + TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf)}}, + {{TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce), + TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3)}, + {TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0), + TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158)}}, + {{TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d), + TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1)}, + {TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e), + TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67)}}, + {{TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61), + TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e)}, + {TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875), + TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0)}}, + {{TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94), + TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e)}, + {TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822), + TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0)}}, + {{TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b), + TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd)}, + {TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f), + TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca)}}, + {{TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247), + TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433)}, + {TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8), + TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11)}}, + {{TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741), + TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a)}, + {TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6), + TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834)}}, + {{TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938), + TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd)}, + {TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35), + TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31)}}, + {{TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f), + TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403)}, + {TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4), + TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e)}}, + {{TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e), + TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541)}, + {TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02), + TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3)}}, + {{TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf), + TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9)}, + {TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52), + TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc)}}, + {{TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b), + TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72)}, + {TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70), + TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12)}}, + {{TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1), + TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e)}, + {TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2), + TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28)}}, + {{TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd), + TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163)}, + {TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce), + TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e)}}, + {{TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3), + TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe)}, + {TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a), + TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e)}}, + {{TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98), + TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1)}, + {TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700), + TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a)}}, + {{TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971), + TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939)}, + {TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2), + TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263)}}, + {{TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7), + TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3)}, + {TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2), + TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5)}}, + {{TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09), + TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f)}, + {TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392), + TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da)}}, + {{TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665), + TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0)}, + {TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c), + TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2)}}, + {{TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe), + TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9)}, + {TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097), + TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636)}}, + {{TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f), + TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76)}, + {TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7), + TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294)}}, + {{TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62), + TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f)}, + {TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d), + TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063)}}, + {{TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b), + TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b)}, + {TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42), + TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c)}}, + {{TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e), + TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab)}, + {TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52), + TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39)}}, + {{TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91), + TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae)}, + {TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b), + TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d)}}, + {{TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588), + TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da)}, + {TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1), + TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9)}}, + {{TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35), + TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22)}, + {TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081), + TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80)}}, + {{TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2), + TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec)}, + {TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7), + TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f)}}, + {{TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66), + TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83)}, + {TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce), + TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf)}}, + {{TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902), + TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32)}, + {TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660), + TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d)}}, + {{TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d), + TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0)}, + {TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46), + TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef)}}, + {{TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9), + TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec)}, + {TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be), + TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f)}}, + {{TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293), + TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1)}, + {TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0), + TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115)}}, + {{TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c), + TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd)}, + {TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d), + TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8)}}, + {{TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419), + TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2)}, + {TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234), + TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb)}}, + {{TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350), + TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128)}, + {TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf), + TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362)}}, + {{TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b), + TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e)}, + {TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573), + TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958)}}, + {{TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595), + TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842)}, + {TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a), + TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d)}}, + {{TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171), + TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29)}, + {TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6), + TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc)}}, + {{TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779), + TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31)}, + {TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a), + TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a)}}, + {{TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd), + TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5)}, + {TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d), + TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f)}}, + {{TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274), + TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3)}, + {TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9), + TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87)}}, + {{TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1), + TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033)}, + {TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3), + TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af)}}, + {{TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da), + TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd)}, + {TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391), + TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d)}}, + {{TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a), + TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13)}, + {TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05), + TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e)}}, + {{TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7), + TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d)}, + {TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4), + TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac)}}, + {{TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38), + TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f)}, + {TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f), + TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092)}}, + {{TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70), + TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac)}, + {TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31), + TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f)}}, + {{TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461), + TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073)}, + {TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811), + TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851)}}, + {{TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418), + TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027)}, + {TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330), + TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df)}}, + {{TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f), + TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7)}, + {TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0), + TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e)}}, + {{TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868), + TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea)}, + {TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff), + TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)}}}, + {{{TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb), + TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81)}, + {TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a), + TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522)}}, + {{TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd), + TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c)}, + {TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea), + TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9)}}, + {{TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf), + TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e)}, + {TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4), + TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537)}}, + {{TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f), + TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc)}, + {TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205), + TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de)}}, + {{TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab), + TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff)}, + {TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8), + TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b)}}, + {{TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3), + TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f)}, + {TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524), + TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1)}}, + {{TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8), + TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa)}, + {TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8), + TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474)}}, + {{TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549), + TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa)}, + {TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd), + TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985)}}, + {{TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa), + TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8)}, + {TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5), + TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf)}}, + {{TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c), + TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd)}, + {TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb), + TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5)}}, + {{TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c), + TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e)}, + {TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca), + TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7)}}, + {{TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958), + TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d)}, + {TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a), + TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b)}}, + {{TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e), + TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5)}, + {TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7), + TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a)}}, + {{TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8), + TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392)}, + {TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4), + TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd)}}, + {{TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c), + TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744)}, + {TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459), + TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b)}}, + {{TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379), + TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e)}, + {TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483), + TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa)}}, + {{TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9), + TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f)}, + {TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a), + TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398)}}, + {{TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16), + TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1)}, + {TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5), + TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349)}}, + {{TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d), + TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0)}, + {TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d), + TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9)}}, + {{TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe), + TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c)}, + {TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4), + TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f)}}, + {{TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754), + TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3)}, + {TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a), + TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852)}}, + {{TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac), + TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9)}, + {TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa), + TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323)}}, + {{TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455), + TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411)}, + {TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435), + TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e)}}, + {{TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18), + TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495)}, + {TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400), + TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0)}}, + {{TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210), + TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70)}, + {TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42), + TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a)}}, + {{TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773), + TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b)}, + {TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832), + TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3)}}, + {{TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97), + TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01)}, + {TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5), + TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281)}}, + {{TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc), + TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0)}, + {TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c), + TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6)}}, + {{TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be), + TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1)}, + {TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e), + TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96)}}, + {{TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45), + TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e)}, + {TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1), + TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46)}}, + {{TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863), + TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8)}, + {TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2), + TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024)}}, + {{TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb), + TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d)}, + {TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4), + TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7)}}, + {{TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148), + TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40)}, + {TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d), + TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201)}}, + {{TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41), + TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016)}, + {TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e), + TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1)}}, + {{TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88), + TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b)}, + {TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443), + TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2)}}, + {{TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4), + TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e)}, + {TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57), + TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac)}}, + {{TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b), + TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29)}, + {TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79), + TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031)}}, + {{TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a), + TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b)}, + {TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752), + TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2)}}, + {{TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d), + TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13)}, + {TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6), + TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e)}}, + {{TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165), + TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9)}, + {TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e), + TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561)}}, + {{TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40), + TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da)}, + {TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02), + TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3)}}, + {{TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b), + TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639)}, + {TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8), + TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab)}}, + {{TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10), + TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd)}, + {TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b), + TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8)}}, + {{TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66), + TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40)}, + {TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd), + TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b)}}, + {{TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb), + TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442)}, + {TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0), + TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628)}}, + {{TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be), + TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2)}, + {TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d), + TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca)}}, + {{TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed), + TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06)}, + {TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57), + TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2)}}, + {{TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7), + TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435)}, + {TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3), + TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78)}}, + {{TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c), + TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57)}, + {TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f), + TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c)}}, + {{TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5), + TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f)}, + {TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7), + TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf)}}, + {{TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c), + TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8)}, + {TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12), + TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a)}}, + {{TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919), + TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5)}, + {TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154), + TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1)}}, + {{TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285), + TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7)}, + {TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c), + TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517)}}, + {{TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523), + TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00)}, + {TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63), + TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946)}}, + {{TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1), + TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60)}, + {TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d), + TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d)}}, + {{TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438), + TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507)}, + {TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2), + TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd)}}, + {{TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3), + TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126)}, + {TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba), + TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569)}}, + {{TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b), + TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321)}, + {TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff), + TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731)}}, + {{TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd), + TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b)}, + {TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1), + TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041)}}, + {{TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7), + TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6)}, + {TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6), + TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b)}}, + {{TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5), + TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823)}, + {TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5), + TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1)}}, + {{TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306), + TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2)}, + {TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df), + TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8)}}, + {{TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18), + TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a)}, + {TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5), + TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa)}}, + {{TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640), + TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670)}, + {TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed), + TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)}}}, + {{{TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7), + TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e)}, + {TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d), + TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef)}}, + {{TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090), + TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124)}, + {TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3), + TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad)}}, + {{TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46), + TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505)}, + {TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33), + TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1)}}, + {{TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0), + TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec)}, + {TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00), + TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695)}}, + {{TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a), + TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1)}, + {TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1), + TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604)}}, + {{TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094), + TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33)}, + {TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773), + TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20)}}, + {{TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0), + TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc)}, + {TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5), + TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846)}}, + {{TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d), + TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9)}, + {TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2), + TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342)}}, + {{TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e), + TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f)}, + {TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb), + TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8)}}, + {{TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c), + TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef)}, + {TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485), + TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799)}}, + {{TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c), + TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a)}, + {TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374), + TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2)}}, + {{TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1), + TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f)}, + {TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0), + TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98)}}, + {{TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa), + TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe)}, + {TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568), + TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6)}}, + {{TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db), + TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39)}, + {TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed), + TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a)}}, + {{TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97), + TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe)}, + {TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116), + TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192)}}, + {{TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e), + TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201)}, + {TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66), + TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11)}}, + {{TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819), + TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709)}, + {TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671), + TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1)}}, + {{TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2), + TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a)}, + {TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9), + TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84)}}, + {{TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f), + TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a)}, + {TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e), + TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a)}}, + {{TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e), + TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0)}, + {TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f), + TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf)}}, + {{TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05), + TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596)}, + {TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674), + TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25)}}, + {{TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825), + TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e)}, + {TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6), + TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5)}}, + {{TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e), + TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de)}, + {TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7), + TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf)}}, + {{TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd), + TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad)}, + {TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced), + TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178)}}, + {{TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547), + TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96)}, + {TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0), + TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98)}}, + {{TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994), + TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa)}, + {TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa), + TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81)}}, + {{TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a), + TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148)}, + {TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab), + TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80)}}, + {{TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3), + TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb)}, + {TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41), + TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa)}}, + {{TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a), + TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a)}, + {TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd), + TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831)}}, + {{TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe), + TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6)}, + {TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810), + TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a)}}, + {{TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a), + TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054)}, + {TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9), + TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4)}}, + {{TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604), + TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb)}, + {TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff), + TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb)}}, + {{TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa), + TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d)}, + {TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c), + TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef)}}, + {{TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857), + TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a)}, + {TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6), + TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35)}}, + {{TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302), + TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe)}, + {TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f), + TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa)}}, + {{TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9), + TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a)}, + {TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515), + TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4)}}, + {{TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642), + TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf)}, + {TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3), + TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac)}}, + {{TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1), + TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196)}, + {TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77), + TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f)}}, + {{TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374), + TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6)}, + {TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131), + TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001)}}, + {{TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd), + TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115)}, + {TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617), + TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b)}}, + {{TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1), + TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a)}, + {TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c), + TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7)}}, + {{TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178), + TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770)}, + {TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a), + TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e)}}, + {{TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b), + TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f)}, + {TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef), + TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686)}}, + {{TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff), + TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee)}, + {TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2), + TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1)}}, + {{TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1), + TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7)}, + {TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9), + TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046)}}, + {{TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6), + TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5)}, + {TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644), + TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197)}}, + {{TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17), + TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253)}, + {TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be), + TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188)}}, + {{TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e), + TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf)}, + {TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397), + TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2)}}, + {{TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571), + TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1)}, + {TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9), + TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa)}}, + {{TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4), + TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb)}, + {TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575), + TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b)}}, + {{TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c), + TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af)}, + {TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a), + TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f)}}, + {{TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900), + TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958)}, + {TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7), + TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5)}}, + {{TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23), + TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051)}, + {TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0), + TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8)}}, + {{TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656), + TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4)}, + {TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16), + TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9)}}, + {{TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57), + TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0)}, + {TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817), + TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490)}}, + {{TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f), + TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6)}, + {TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637), + TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0)}}, + {{TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047), + TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44)}, + {TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b), + TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445)}}, + {{TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8), + TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503)}, + {TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71), + TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d)}}, + {{TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993), + TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47)}, + {TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203), + TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd)}}, + {{TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480), + TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733)}, + {TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9), + TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3)}}, + {{TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1), + TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce)}, + {TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa), + TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd)}}, + {{TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5), + TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358)}, + {TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b), + TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8)}}, + {{TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b), + TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562)}, + {TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b), + TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef)}}, + {{TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9), + TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3)}, + {TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952), + TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636)}}}, + {{{TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00), + TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28)}, + {TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949), + TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742)}}, + {{TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34), + TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5)}, + {TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc), + TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f)}}, + {{TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7), + TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3)}, + {TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c), + TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f)}}, + {{TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a), + TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620)}, + {TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa), + TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6)}}, + {{TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7), + TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999)}, + {TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c), + TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327)}}, + {{TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f), + TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb)}, + {TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d), + TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390)}}, + {{TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590), + TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d)}, + {TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8), + TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015)}}, + {{TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4), + TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6)}, + {TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3), + TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b)}}, + {{TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319), + TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e)}, + {TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3), + TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414)}}, + {{TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5), + TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e)}, + {TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a), + TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f)}}, + {{TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107), + TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159)}, + {TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567), + TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc)}}, + {{TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1), + TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b)}, + {TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f), + TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b)}}, + {{TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176), + TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e)}, + {TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547), + TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707)}}, + {{TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e), + TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d)}, + {TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909), + TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442)}}, + {{TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65), + TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b)}, + {TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90), + TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24)}}, + {{TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc), + TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f)}, + {TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35), + TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98)}}, + {{TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6), + TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1)}, + {TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182), + TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6)}}, + {{TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351), + TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491)}, + {TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e), + TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4)}}, + {{TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688), + TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4)}, + {TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc), + TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c)}}, + {{TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c), + TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4)}, + {TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e), + TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f)}}, + {{TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381), + TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7)}, + {TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150), + TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422)}}, + {{TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391), + TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035)}, + {TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe), + TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9)}}, + {{TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8), + TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7)}, + {TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c), + TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80)}}, + {{TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d), + TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e)}, + {TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9), + TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199)}}, + {{TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7), + TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1)}, + {TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829), + TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97)}}, + {{TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133), + TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba)}, + {TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139), + TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b)}}, + {{TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53), + TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60)}, + {TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff), + TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d)}}, + {{TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6), + TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305)}, + {TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249), + TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8)}}, + {{TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93), + TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4)}, + {TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f), + TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b)}}, + {{TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142), + TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5)}, + {TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e), + TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31)}}, + {{TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452), + TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca)}, + {TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289), + TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37)}}, + {{TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182), + TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f)}, + {TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d), + TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe)}}, + {{TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa), + TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409)}, + {TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a), + TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1)}}, + {{TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b), + TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf)}, + {TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215), + TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b)}}, + {{TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca), + TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79)}, + {TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1), + TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd)}}, + {{TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0), + TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06)}, + {TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6), + TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf)}}, + {{TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd), + TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb)}, + {TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683), + TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208)}}, + {{TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3), + TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7)}, + {TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db), + TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a)}}, + {{TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109), + TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32)}, + {TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25), + TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856)}}, + {{TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b), + TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c)}, + {TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac), + TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d)}}, + {{TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f), + TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4)}, + {TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1), + TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff)}}, + {{TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09), + TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc)}, + {TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781), + TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5)}}, + {{TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502), + TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8)}, + {TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123), + TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112)}}, + {{TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd), + TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3)}, + {TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770), + TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d)}}, + {{TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729), + TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b)}, + {TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f), + TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4)}}, + {{TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f), + TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26)}, + {TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9), + TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf)}}, + {{TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6), + TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59)}, + {TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce), + TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc)}}, + {{TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249), + TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d)}, + {TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f), + TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475)}}, + {{TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b), + TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb)}, + {TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103), + TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9)}}, + {{TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97), + TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674)}, + {TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46), + TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6)}}, + {{TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8), + TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337)}, + {TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8), + TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f)}}, + {{TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96), + TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56)}, + {TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639), + TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a)}}, + {{TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf), + TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051)}, + {TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab), + TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530)}}, + {{TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f), + TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96)}, + {TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff), + TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034)}}, + {{TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076), + TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b)}, + {TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071), + TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b)}}, + {{TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7), + TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44)}, + {TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9), + TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c)}}, + {{TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2), + TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1)}, + {TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b), + TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d)}}, + {{TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576), + TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95)}, + {TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c), + TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f)}}, + {{TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758), + TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016)}, + {TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3), + TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85)}}, + {{TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da), + TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3)}, + {TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e), + TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0)}}, + {{TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d), + TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b)}, + {TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f), + TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8)}}, + {{TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2), + TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b)}, + {TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe), + TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd)}}, + {{TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb), + TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b)}, + {TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a), + TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd)}}, + {{TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d), + TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3)}, + {TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a), + TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)}}}, + {{{TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d), + TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04)}, + {TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d), + TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152)}}, + {{TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7), + TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc)}, + {TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42), + TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036)}}, + {{TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e), + TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83)}, + {TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d), + TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3)}}, + {{TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed), + TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32)}, + {TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b), + TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc)}}, + {{TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747), + TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f)}, + {TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99), + TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a)}}, + {{TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc), + TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5)}, + {TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed), + TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533)}}, + {{TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1), + TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493)}, + {TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549), + TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5)}}, + {{TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04), + TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d)}, + {TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e), + TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44)}}, + {{TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5), + TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b)}, + {TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92), + TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e)}}, + {{TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61), + TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a)}, + {TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b), + TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253)}}, + {{TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f), + TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1)}, + {TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347), + TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b)}}, + {{TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7), + TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819)}, + {TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e), + TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6)}}, + {{TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4), + TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070)}, + {TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b), + TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b)}}, + {{TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016), + TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a)}, + {TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790), + TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0)}}, + {{TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371), + TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba)}, + {TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256), + TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6)}}, + {{TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4), + TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc)}, + {TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0), + TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711)}}, + {{TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8), + TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c)}, + {TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b), + TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4)}}, + {{TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a), + TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a)}, + {TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b), + TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5)}}, + {{TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1), + TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3)}, + {TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe), + TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45)}}, + {{TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc), + TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6)}, + {TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97), + TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e)}}, + {{TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5), + TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1)}, + {TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe), + TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc)}}, + {{TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb), + TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd)}, + {TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b), + TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db)}}, + {{TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb), + TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048)}, + {TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2), + TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46)}}, + {{TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b), + TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0)}, + {TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550), + TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418)}}, + {{TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282), + TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c)}, + {TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc), + TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a)}}, + {{TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f), + TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4)}, + {TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf), + TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90)}}, + {{TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe), + TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab)}, + {TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea), + TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b)}}, + {{TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64), + TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b)}, + {TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae), + TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc)}}, + {{TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2), + TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6)}, + {TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8), + TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe)}}, + {{TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0), + TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f)}, + {TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0), + TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6)}}, + {{TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953), + TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1)}, + {TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4), + TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094)}}, + {{TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab), + TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831)}, + {TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5), + TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f)}}, + {{TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5), + TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce)}, + {TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381), + TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897)}}, + {{TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301), + TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699)}, + {TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20), + TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9)}}, + {{TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2), + TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910)}, + {TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a), + TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242)}}, + {{TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f), + TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98)}, + {TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0), + TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6)}}, + {{TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0), + TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc)}, + {TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7), + TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3)}}, + {{TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d), + TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e)}, + {TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5), + TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f)}}, + {{TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d), + TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c)}, + {TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123), + TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c)}}, + {{TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b), + TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa)}, + {TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524), + TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820)}}, + {{TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654), + TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c)}, + {TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6), + TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1)}}, + {{TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32), + TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234)}, + {TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f), + TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8)}}, + {{TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48), + TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2)}, + {TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e), + TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6)}}, + {{TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca), + TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55)}, + {TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c), + TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385)}}, + {{TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a), + TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc)}, + {TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc), + TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce)}}, + {{TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842), + TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0)}, + {TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce), + TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365)}}, + {{TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159), + TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181)}, + {TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4), + TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb)}}, + {{TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a), + TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b)}, + {TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495), + TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95)}}, + {{TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085), + TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e)}, + {TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049), + TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538)}}, + {{TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268), + TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff)}, + {TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea), + TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711)}}, + {{TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975), + TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875)}, + {TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766), + TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c)}}, + {{TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1), + TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e)}, + {TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a), + TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a)}}, + {{TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b), + TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025)}, + {TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35), + TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d)}}, + {{TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603), + TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9)}, + {TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31), + TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934)}}, + {{TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11), + TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c)}, + {TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3), + TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125)}}, + {{TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe), + TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920)}, + {TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603), + TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2)}}, + {{TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28), + TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083)}, + {TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3), + TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0)}}, + {{TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7), + TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6)}, + {TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608), + TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33)}}, + {{TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5), + TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066)}, + {TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9), + TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb)}}, + {{TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937), + TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9)}, + {TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f), + TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c)}}, + {{TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981), + TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163)}, + {TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95), + TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9)}}, + {{TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a), + TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831)}, + {TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c), + TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d)}}, + {{TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb), + TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe)}, + {TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc), + TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a)}}, + {{TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284), + TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7)}, + {TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84), + TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a)}}}, + {{{TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34), + TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda)}, + {TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7), + TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997)}}, + {{TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e), + TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448)}, + {TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9), + TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368)}}, + {{TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc), + TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb)}, + {TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302), + TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106)}}, + {{TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce), + TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f)}, + {TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7), + TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d)}}, + {{TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff), + TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc)}, + {TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac), + TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e)}}, + {{TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3), + TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f)}, + {TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323), + TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591)}}, + {{TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9), + TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186)}, + {TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0), + TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71)}}, + {{TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac), + TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff)}, + {TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5), + TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444)}}, + {{TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8), + TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a)}, + {TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a), + TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e)}}, + {{TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062), + TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027)}, + {TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3), + TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01)}}, + {{TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b), + TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef)}, + {TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f), + TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51)}}, + {{TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745), + TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6)}, + {TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2), + TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310)}}, + {{TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22), + TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7)}, + {TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8), + TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b)}}, + {{TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934), + TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7)}, + {TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2), + TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74)}}, + {{TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df), + TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a)}, + {TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62), + TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9)}}, + {{TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e), + TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047)}, + {TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9), + TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f)}}, + {{TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b), + TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d)}, + {TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db), + TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7)}}, + {{TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1), + TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c)}, + {TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449), + TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9)}}, + {{TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080), + TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a)}, + {TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785), + TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c)}}, + {{TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728), + TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6)}, + {TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777), + TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98)}}, + {{TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d), + TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a)}, + {TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92), + TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6)}}, + {{TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f), + TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32)}, + {TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6), + TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8)}}, + {{TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5), + TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267)}, + {TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5), + TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98)}}, + {{TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b), + TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d)}, + {TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724), + TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232)}}, + {{TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61), + TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f)}, + {TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43), + TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026)}}, + {{TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e), + TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383)}, + {TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d), + TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b)}}, + {{TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91), + TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d)}, + {TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d), + TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e)}}, + {{TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1), + TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46)}, + {TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67), + TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c)}}, + {{TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1), + TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741)}, + {TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194), + TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988)}}, + {{TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85), + TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046)}, + {TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301), + TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb)}}, + {{TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27), + TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c)}, + {TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29), + TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa)}}, + {{TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78), + TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75)}, + {TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6), + TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670)}}, + {{TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988), + TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b)}, + {TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e), + TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2)}}, + {{TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc), + TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29)}, + {TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee), + TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e)}}, + {{TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4), + TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89)}, + {TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9), + TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2)}}, + {{TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1), + TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2)}, + {TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e), + TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6)}}, + {{TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1), + TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965)}, + {TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97), + TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02)}}, + {{TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be), + TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b)}, + {TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e), + TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92)}}, + {{TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f), + TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53)}, + {TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320), + TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433)}}, + {{TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3), + TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d)}, + {TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f), + TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055)}}, + {{TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd), + TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9)}, + {TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284), + TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492)}}, + {{TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f), + TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490)}, + {TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119), + TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba)}}, + {{TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9), + TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783)}, + {TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c), + TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb)}}, + {{TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630), + TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce)}, + {TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a), + TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e)}}, + {{TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331), + TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab)}, + {TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f), + TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b)}}, + {{TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f), + TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607)}, + {TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5), + TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108)}}, + {{TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1), + TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb)}, + {TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0), + TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf)}}, + {{TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d), + TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546)}, + {TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b), + TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d)}}, + {{TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3), + TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061)}, + {TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f), + TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd)}}, + {{TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6), + TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1)}, + {TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d), + TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47)}}, + {{TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29), + TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354)}, + {TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996), + TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528)}}, + {{TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4), + TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd)}, + {TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb), + TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae)}}, + {{TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660), + TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9)}, + {TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76), + TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732)}}, + {{TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082), + TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98)}, + {TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61), + TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3)}}, + {{TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73), + TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7)}, + {TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297), + TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927)}}, + {{TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93), + TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396)}, + {TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2), + TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d)}}, + {{TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74), + TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76)}, + {TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65), + TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4)}}, + {{TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea), + TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003)}, + {TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783), + TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018)}}, + {{TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297), + TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc)}, + {TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8), + TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143)}}, + {{TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167), + TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f)}, + {TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda), + TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664)}}, + {{TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2), + TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b)}, + {TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab), + TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4)}}, + {{TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3), + TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2)}, + {TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942), + TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f)}}, + {{TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097), + TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c)}, + {TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa), + TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360)}}, + {{TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150), + TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007)}, + {TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5), + TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)}}}, + {{{TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b), + TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab)}, + {TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f), + TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55)}}, + {{TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2), + TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df)}, + {TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c), + TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf)}}, + {{TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410), + TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7)}, + {TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c), + TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca)}}, + {{TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b), + TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d)}, + {TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450), + TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515)}}, + {{TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e), + TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284)}, + {TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6), + TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8)}}, + {{TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4), + TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd)}, + {TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3), + TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8)}}, + {{TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08), + TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de)}, + {TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b), + TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2)}}, + {{TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8), + TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb)}, + {TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e), + TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef)}}, + {{TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd), + TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2)}, + {TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334), + TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a)}}, + {{TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea), + TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875)}, + {TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b), + TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216)}}, + {{TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0), + TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243)}, + {TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26), + TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202)}}, + {{TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7), + TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8)}, + {TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99), + TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4)}}, + {{TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16), + TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619)}, + {TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a), + TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0)}}, + {{TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943), + TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463)}, + {TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa), + TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544)}}, + {{TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986), + TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97)}, + {TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5), + TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd)}}, + {{TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6), + TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe)}, + {TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19), + TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4)}}, + {{TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db), + TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e)}, + {TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53), + TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51)}}, + {{TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd), + TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191)}, + {TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5), + TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01)}}, + {{TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475), + TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d)}, + {TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e), + TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f)}}, + {{TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce), + TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38)}, + {TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd), + TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d)}}, + {{TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9), + TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50)}, + {TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994), + TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d)}}, + {{TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd), + TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5)}, + {TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8), + TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209)}}, + {{TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8), + TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a)}, + {TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633), + TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62)}}, + {{TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c), + TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6)}, + {TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2), + TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42)}}, + {{TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151), + TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51)}, + {TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d), + TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9)}}, + {{TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7), + TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4)}, + {TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c), + TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b)}}, + {{TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5), + TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc)}, + {TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c), + TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18)}}, + {{TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29), + TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d)}, + {TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c), + TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4)}}, + {{TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f), + TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec)}, + {TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14), + TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65)}}, + {{TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d), + TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5)}, + {TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090), + TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef)}}, + {{TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee), + TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2)}, + {TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4), + TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b)}}, + {{TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166), + TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007)}, + {TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2), + TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe)}}, + {{TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f), + TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce)}, + {TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a), + TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71)}}, + {{TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6), + TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421)}, + {TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a), + TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f)}}, + {{TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd), + TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03)}, + {TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca), + TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b)}}, + {{TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e), + TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702)}, + {TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007), + TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447)}}, + {{TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f), + TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1)}, + {TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172), + TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48)}}, + {{TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00), + TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361)}, + {TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446), + TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41)}}, + {{TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224), + TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d)}, + {TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937), + TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273)}}, + {{TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221), + TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1)}, + {TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc), + TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c)}}, + {{TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca), + TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5)}, + {TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02), + TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c)}}, + {{TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169), + TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f)}, + {TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d), + TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252)}}, + {{TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879), + TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3)}, + {TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4), + TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d)}}, + {{TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927), + TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af)}, + {TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97), + TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79)}}, + {{TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03), + TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f)}, + {TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca), + TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc)}}, + {{TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062), + TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13)}, + {TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e), + TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693)}}, + {{TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf), + TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8)}, + {TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6), + TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a)}}, + {{TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad), + TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281)}, + {TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4), + TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa)}}, + {{TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9), + TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2)}, + {TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63), + TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781)}}, + {{TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c), + TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7)}, + {TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da), + TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99)}}, + {{TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8), + TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9)}, + {TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c), + TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21)}}, + {{TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608), + TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2)}, + {TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89), + TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5)}}, + {{TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88), + TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262)}, + {TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3), + TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e)}}, + {{TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d), + TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649)}, + {TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c), + TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac)}}, + {{TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c), + TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca)}, + {TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1), + TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd)}}, + {{TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1), + TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c)}, + {TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a), + TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757)}}, + {{TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029), + TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015)}, + {TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5), + TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51)}}, + {{TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9), + TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07)}, + {TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a), + TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650)}}, + {{TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba), + TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839)}, + {TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc), + TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc)}}, + {{TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292), + TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6)}, + {TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e), + TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9)}}, + {{TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5), + TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01)}, + {TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3), + TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96)}}, + {{TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd), + TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec)}, + {TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd), + TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf)}}, + {{TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8), + TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c)}, + {TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f), + TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf)}}, + {{TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a), + TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d)}, + {TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2), + TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)}}}, + {{{TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78), + TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a)}, + {TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051), + TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39)}}, + {{TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c), + TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452)}, + {TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4), + TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b)}}, + {{TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c), + TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14)}, + {TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0), + TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270)}}, + {{TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205), + TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb)}, + {TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e), + TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3)}}, + {{TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8), + TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb)}, + {TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8), + TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd)}}, + {{TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb), + TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3)}, + {TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9), + TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b)}}, + {{TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5), + TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2)}, + {TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61), + TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5)}}, + {{TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd), + TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9)}, + {TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846), + TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7)}}, + {{TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c), + TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf)}, + {TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996), + TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47)}}, + {{TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66), + TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0)}, + {TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4), + TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36)}}, + {{TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be), + TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad)}, + {TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760), + TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74)}}, + {{TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154), + TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb)}, + {TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56), + TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a)}}, + {{TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568), + TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c)}, + {TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d), + TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385)}}, + {{TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1), + TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081)}, + {TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91), + TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa)}}, + {{TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316), + TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47)}, + {TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4), + TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345)}}, + {{TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954), + TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126)}, + {TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24), + TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394)}}, + {{TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb), + TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9)}, + {TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76), + TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e)}}, + {{TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5), + TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb)}, + {TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb), + TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be)}}, + {{TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597), + TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1)}, + {TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09), + TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f)}}, + {{TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7), + TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e)}, + {TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08), + TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c)}}, + {{TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03), + TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6)}, + {TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48), + TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745)}}, + {{TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082), + TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5)}, + {TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f), + TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5)}}, + {{TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947), + TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539)}, + {TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a), + TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002)}}, + {{TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb), + TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948)}, + {TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73), + TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e)}}, + {{TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647), + TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5)}, + {TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490), + TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f)}}, + {{TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea), + TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3)}, + {TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e), + TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516)}}, + {{TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e), + TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc)}, + {TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d), + TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604)}}, + {{TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b), + TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2)}, + {TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2), + TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e)}}, + {{TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290), + TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4)}, + {TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638), + TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa)}}, + {{TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307), + TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac)}, + {TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8), + TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8)}}, + {{TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2), + TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9)}, + {TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095), + TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9)}}, + {{TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2), + TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849)}, + {TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e), + TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638)}}, + {{TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506), + TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb)}, + {TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d), + TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4)}}, + {{TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14), + TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34)}, + {TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10), + TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9)}}, + {{TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79), + TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b)}, + {TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57), + TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca)}}, + {{TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb), + TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4)}, + {TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591), + TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f)}}, + {{TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6), + TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d)}, + {TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d), + TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a)}}, + {{TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1), + TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706)}, + {TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055), + TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3)}}, + {{TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810), + TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4)}, + {TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762), + TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96)}}, + {{TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655), + TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6)}, + {TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f), + TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878)}}, + {{TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9), + TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b)}, + {TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21), + TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982)}}, + {{TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13), + TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd)}, + {TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7), + TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0)}}, + {{TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea), + TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355)}, + {TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901), + TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac)}}, + {{TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965), + TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436)}, + {TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315), + TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef)}}, + {{TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a), + TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6)}, + {TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0), + TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4)}}, + {{TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0), + TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af)}, + {TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271), + TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a)}}, + {{TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5), + TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364)}, + {TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b), + TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5)}}, + {{TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66), + TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea)}, + {TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726), + TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4)}}, + {{TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d), + TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984)}, + {TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc), + TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d)}}, + {{TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7), + TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2)}, + {TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10), + TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28)}}, + {{TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b), + TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5)}, + {TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33), + TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c)}}, + {{TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810), + TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68)}, + {TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e), + TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125)}}, + {{TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f), + TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3)}, + {TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979), + TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba)}}, + {{TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c), + TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e)}, + {TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737), + TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e)}}, + {{TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525), + TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c)}, + {TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64), + TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5)}}, + {{TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d), + TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77)}, + {TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85), + TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5)}}, + {{TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e), + TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946)}, + {TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498), + TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1)}}, + {{TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477), + TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c)}, + {TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642), + TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224)}}, + {{TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3), + TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017)}, + {TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421), + TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6)}}, + {{TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319), + TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e)}, + {TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc), + TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205)}}, + {{TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402), + TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808)}, + {TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff), + TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2)}}, + {{TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1), + TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199)}, + {TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51), + TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418)}}, + {{TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145), + TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496)}, + {TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a), + TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d)}}, + {{TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c), + TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b)}, + {TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2), + TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)}}}, + {{{TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6), + TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1)}, + {TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866), + TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5)}}, + {{TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760), + TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d)}, + {TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251), + TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8)}}, + {{TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8), + TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a)}, + {TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a), + TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954)}}, + {{TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915), + TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911)}, + {TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc), + TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a)}}, + {{TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49), + TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a)}, + {TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11), + TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3)}}, + {{TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593), + TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5)}, + {TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83), + TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698)}}, + {{TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729), + TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0)}, + {TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e), + TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c)}}, + {{TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982), + TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509)}, + {TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268), + TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b)}}, + {{TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf), + TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f)}, + {TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295), + TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585)}}, + {{TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d), + TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d)}, + {TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db), + TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8)}}, + {{TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823), + TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690)}, + {TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec), + TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3)}}, + {{TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217), + TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f)}, + {TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074), + TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c)}}, + {{TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511), + TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649)}, + {TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0), + TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70)}}, + {{TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea), + TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35)}, + {TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686), + TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840)}}, + {{TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7), + TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9)}, + {TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a), + TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86)}}, + {{TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53), + TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd)}, + {TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190), + TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a)}}, + {{TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683), + TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc)}, + {TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524), + TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66)}}, + {{TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5), + TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac)}, + {TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766), + TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1)}}, + {{TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1), + TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea)}, + {TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2), + TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d)}}, + {{TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e), + TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b)}, + {TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261), + TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83)}}, + {{TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02), + TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920)}, + {TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540), + TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38)}}, + {{TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17), + TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad)}, + {TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e), + TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2)}}, + {{TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08), + TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2)}, + {TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b), + TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424)}}, + {{TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99), + TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6)}, + {TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453), + TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e)}}, + {{TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6), + TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6)}, + {TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea), + TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930)}}, + {{TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272), + TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf)}, + {TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1), + TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0)}}, + {{TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af), + TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c)}, + {TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e), + TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e)}}, + {{TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82), + TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e)}, + {TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c), + TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54)}}, + {{TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f), + TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b)}, + {TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369), + TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c)}}, + {{TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b), + TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df)}, + {TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af), + TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a)}}, + {{TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469), + TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f)}, + {TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f), + TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462)}}, + {{TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca), + TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555)}, + {TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204), + TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a)}}, + {{TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8), + TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758)}, + {TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5), + TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455)}}, + {{TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972), + TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e)}, + {TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd), + TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e)}}, + {{TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9), + TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25)}, + {TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d), + TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11)}}, + {{TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31), + TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53)}, + {TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44), + TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802)}}, + {{TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71), + TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362)}, + {TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c), + TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef)}}, + {{TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320), + TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3)}, + {TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6), + TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830)}}, + {{TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432), + TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73)}, + {TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49), + TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008)}}, + {{TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57), + TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8)}, + {TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065), + TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c)}}, + {{TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89), + TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e)}, + {TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6), + TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3)}}, + {{TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b), + TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212)}, + {TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78), + TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057)}}, + {{TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316), + TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391)}, + {TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd), + TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7)}}, + {{TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392), + TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb)}, + {TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69), + TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe)}}, + {{TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154), + TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23)}, + {TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149), + TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732)}}, + {{TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0), + TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2)}, + {TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95), + TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04)}}, + {{TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599), + TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0)}, + {TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696), + TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab)}}, + {{TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d), + TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d)}, + {TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1), + TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1)}}, + {{TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4), + TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974)}, + {TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0), + TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a)}}, + {{TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf), + TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b)}, + {TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9), + TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851)}}, + {{TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a), + TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051)}, + {TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78), + TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e)}}, + {{TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5), + TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc)}, + {TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a), + TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd)}}, + {{TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453), + TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2)}, + {TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6), + TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f)}}, + {{TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7), + TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1)}, + {TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f), + TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1)}}, + {{TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c), + TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a)}, + {TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9), + TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8)}}, + {{TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169), + TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2)}, + {TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452), + TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0)}}, + {{TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8), + TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4)}, + {TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93), + TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d)}}, + {{TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7), + TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b)}, + {TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c), + TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f)}}, + {{TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7), + TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9)}, + {TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96), + TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b)}}, + {{TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c), + TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5)}, + {TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c), + TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9)}}, + {{TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0), + TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183)}, + {TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e), + TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e)}}, + {{TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76), + TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b)}, + {TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167), + TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12)}}, + {{TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6), + TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a)}, + {TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963), + TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92)}}, + {{TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235), + TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a)}, + {TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d), + TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494)}}}, + {{{TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65), + TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860)}, + {TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f), + TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50)}}, + {{TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d), + TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6)}, + {TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d), + TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee)}}, + {{TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5), + TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca)}, + {TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2), + TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf)}}, + {{TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867), + TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6)}, + {TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65), + TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe)}}, + {{TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976), + TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3)}, + {TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837), + TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1)}}, + {{TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4), + TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6)}, + {TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae), + TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4)}}, + {{TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624), + TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c)}, + {TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6), + TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f)}}, + {{TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f), + TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d)}, + {TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a), + TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011)}}, + {{TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0), + TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854)}, + {TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459), + TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3)}}, + {{TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f), + TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c)}, + {TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941), + TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe)}}, + {{TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6), + TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c)}, + {TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919), + TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce)}}, + {{TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860), + TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa)}, + {TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073), + TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd)}}, + {{TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2), + TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a)}, + {TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91), + TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615)}}, + {{TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270), + TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f)}, + {TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664), + TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d)}}, + {{TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e), + TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a)}, + {TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77), + TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32)}}, + {{TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e), + TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c)}, + {TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e), + TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517)}}, + {{TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be), + TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664)}, + {TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a), + TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700)}}, + {{TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9), + TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152)}, + {TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a), + TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb)}}, + {{TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b), + TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db)}, + {TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85), + TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad)}}, + {{TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab), + TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662)}, + {TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f), + TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02)}}, + {{TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22), + TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e)}, + {TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5), + TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70)}}, + {{TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8), + TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993)}, + {TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0), + TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c)}}, + {{TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c), + TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682)}, + {TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85), + TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb)}}, + {{TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b), + TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef)}, + {TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1), + TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59)}}, + {{TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26), + TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e)}, + {TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296), + TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb)}}, + {{TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5), + TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d)}, + {TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47), + TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87)}}, + {{TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75), + TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130)}, + {TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769), + TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5)}}, + {{TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb), + TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5)}, + {TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c), + TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed)}}, + {{TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496), + TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7)}, + {TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936), + TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e)}}, + {{TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2), + TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d)}, + {TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670), + TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade)}}, + {{TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f), + TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252)}, + {TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336), + TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597)}}, + {{TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf), + TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11)}, + {TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3), + TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7)}}, + {{TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c), + TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4)}, + {TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e), + TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075)}}, + {{TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05), + TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493)}, + {TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a), + TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6)}}, + {{TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a), + TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1)}, + {TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d), + TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc)}}, + {{TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15), + TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77)}, + {TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11), + TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9)}}, + {{TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef), + TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f)}, + {TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759), + TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0)}}, + {{TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf), + TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee)}, + {TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455), + TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408)}}, + {{TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e), + TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954)}, + {TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec), + TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626)}}, + {{TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35), + TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c)}, + {TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c), + TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e)}}, + {{TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d), + TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80)}, + {TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849), + TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11)}}, + {{TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d), + TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47)}, + {TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1), + TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4)}}, + {{TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448), + TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9)}, + {TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286), + TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f)}}, + {{TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4), + TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521)}, + {TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c), + TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4)}}, + {{TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433), + TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8)}, + {TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d), + TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092)}}, + {{TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2), + TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7)}, + {TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524), + TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71)}}, + {{TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8), + TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816)}, + {TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8), + TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c)}}, + {{TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b), + TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b)}, + {TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a), + TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063)}}, + {{TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89), + TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb)}, + {TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084), + TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef)}}, + {{TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4), + TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab)}, + {TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca), + TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0)}}, + {{TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c), + TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675)}, + {TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c), + TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014)}}, + {{TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2), + TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52)}, + {TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f), + TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964)}}, + {{TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a), + TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed)}, + {TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e), + TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1)}}, + {{TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6), + TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c)}, + {TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681), + TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f)}}, + {{TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789), + TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885)}, + {TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895), + TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e)}}, + {{TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52), + TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8)}, + {TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939), + TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6)}}, + {{TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba), + TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04)}, + {TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741), + TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb)}}, + {{TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7), + TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4)}, + {TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe), + TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b)}}, + {{TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a), + TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480)}, + {TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4), + TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c)}}, + {{TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5), + TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08)}, + {TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74), + TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4)}}, + {{TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb), + TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a)}, + {TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5), + TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816)}}, + {{TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5), + TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5)}, + {TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89), + TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b)}}, + {{TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de), + TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d)}, + {TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e), + TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b)}}, + {{TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06), + TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d)}, + {TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc), + TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b)}}}, + {{{TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5), + TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d)}, + {TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e), + TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798)}}, + {{TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1), + TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee)}, + {TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153), + TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8)}}, + {{TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83), + TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7)}, + {TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae), + TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658)}}, + {{TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704), + TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8)}, + {TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6), + TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac)}}, + {{TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84), + TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4)}, + {TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b), + TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a)}}, + {{TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f), + TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c)}, + {TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59), + TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31)}}, + {{TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6), + TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69)}, + {TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723), + TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879)}}, + {{TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0), + TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c)}, + {TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca), + TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6)}}, + {{TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f), + TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755)}, + {TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9), + TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926)}}, + {{TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2), + TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2)}, + {TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7), + TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08)}}, + {{TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c), + TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99)}, + {TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4), + TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f)}}, + {{TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144), + TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b)}, + {TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5), + TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128)}}, + {{TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08), + TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4)}, + {TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9), + TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f)}}, + {{TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de), + TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889)}, + {TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca), + TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131)}}, + {{TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6), + TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8)}, + {TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120), + TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77)}}, + {{TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82), + TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee)}, + {TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6), + TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad)}}, + {{TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5), + TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948)}, + {TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc), + TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff)}}, + {{TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a), + TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e)}, + {TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62), + TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1)}}, + {{TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45), + TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916)}, + {TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd), + TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d)}}, + {{TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015), + TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7)}, + {TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5), + TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8)}}, + {{TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8), + TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4)}, + {TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666), + TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7)}}, + {{TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21), + TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78)}, + {TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066), + TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0)}}, + {{TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7), + TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25)}, + {TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686), + TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776)}}, + {{TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5), + TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada)}, + {TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99), + TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66)}}, + {{TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2), + TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3)}, + {TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2), + TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148)}}, + {{TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd), + TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8)}, + {TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a), + TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00)}}, + {{TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02), + TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac)}, + {TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb), + TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52)}}, + {{TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027), + TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689)}, + {TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac), + TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8)}}, + {{TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18), + TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66)}, + {TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff), + TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a)}}, + {{TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513), + TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67)}, + {TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822), + TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2)}}, + {{TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24), + TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d)}, + {TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4), + TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147)}}, + {{TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18), + TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351)}, + {TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694), + TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e)}}, + {{TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301), + TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21)}, + {TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c), + TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a)}}, + {{TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1), + TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e)}, + {TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d), + TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887)}}, + {{TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a), + TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291)}, + {TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9), + TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286)}}, + {{TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff), + TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb)}, + {TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce), + TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af)}}, + {{TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463), + TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5)}, + {TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3), + TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6)}}, + {{TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2), + TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab)}, + {TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d), + TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d)}}, + {{TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4), + TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033)}, + {TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226), + TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46)}}, + {{TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997), + TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb)}, + {TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f), + TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78)}}, + {{TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8), + TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e)}, + {TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506), + TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466)}}, + {{TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b), + TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7)}, + {TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40), + TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768)}}, + {{TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b), + TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f)}, + {TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071), + TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7)}}, + {{TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae), + TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03)}, + {TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b), + TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168)}}, + {{TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49), + TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922)}, + {TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e), + TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c)}}, + {{TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547), + TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451)}, + {TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c), + TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f)}}, + {{TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754), + TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171)}, + {TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e), + TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c)}}, + {{TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8), + TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03)}, + {TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6), + TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7)}}, + {{TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375), + TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0)}, + {TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911), + TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09)}}, + {{TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7), + TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c)}, + {TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64), + TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0)}}, + {{TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416), + TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9)}, + {TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791), + TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7)}}, + {{TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877), + TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035)}, + {TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79), + TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090)}}, + {{TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622), + TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb)}, + {TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe), + TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98)}}, + {{TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10), + TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140)}, + {TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166), + TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2)}}, + {{TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b), + TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7)}, + {TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380), + TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c)}}, + {{TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c), + TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe)}, + {TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2), + TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707)}}, + {{TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0), + TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7)}, + {TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6), + TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9)}}, + {{TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db), + TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3)}, + {TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d), + TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1)}}, + {{TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149), + TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51)}, + {TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28), + TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558)}}, + {{TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e), + TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43)}, + {TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b), + TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48)}}, + {{TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6), + TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8)}, + {TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c), + TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657)}}, + {{TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55), + TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a)}, + {TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d), + TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f)}}, + {{TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d), + TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24)}, + {TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c), + TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048)}}, + {{TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43), + TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7)}, + {TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b), + TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699)}}}, + {{{TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98), + TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021)}, + {TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d), + TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3)}}, + {{TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34), + TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da)}, + {TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc), + TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4)}}, + {{TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd), + TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc)}, + {TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1), + TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952)}}, + {{TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805), + TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19)}, + {TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c), + TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655)}}, + {{TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c), + TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69)}, + {TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461), + TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4)}}, + {{TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087), + TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268)}, + {TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9), + TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e)}}, + {{TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458), + TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb)}, + {TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e), + TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446)}}, + {{TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d), + TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637)}, + {TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87), + TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5)}}, + {{TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3), + TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2)}, + {TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432), + TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24)}}, + {{TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d), + TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c)}, + {TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973), + TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b)}}, + {{TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679), + TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873)}, + {TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70), + TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a)}}, + {{TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a), + TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1)}, + {TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0), + TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d)}}, + {{TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545), + TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13)}, + {TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8), + TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684)}}, + {{TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff), + TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161)}, + {TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d), + TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1)}}, + {{TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575), + TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b)}, + {TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5), + TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e)}}, + {{TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25), + TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca)}, + {TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0), + TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8)}}, + {{TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98), + TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da)}, + {TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc), + TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a)}}, + {{TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd), + TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc)}, + {TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4), + TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253)}}, + {{TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4), + TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7)}, + {TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6), + TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8)}}, + {{TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d), + TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c)}, + {TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255), + TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce)}}, + {{TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a), + TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc)}, + {TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f), + TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6)}}, + {{TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70), + TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1)}, + {TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f), + TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f)}}, + {{TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79), + TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472)}, + {TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a), + TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2)}}, + {{TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa), + TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656)}, + {TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec), + TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa)}}, + {{TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44), + TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8)}, + {TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4), + TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a)}}, + {{TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a), + TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d)}, + {TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0), + TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f)}}, + {{TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110), + TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1)}, + {TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547), + TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351)}}, + {{TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f), + TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef)}, + {TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb), + TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced)}}, + {{TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb), + TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4)}, + {TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b), + TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c)}}, + {{TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9), + TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32)}, + {TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768), + TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6)}}, + {{TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930), + TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38)}, + {TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80), + TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634)}}, + {{TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681), + TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3)}, + {TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b), + TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a)}}, + {{TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7), + TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb)}, + {TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79), + TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c)}}, + {{TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2), + TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b)}, + {TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0), + TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718)}}, + {{TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381), + TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d)}, + {TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71), + TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b)}}, + {{TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41), + TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a)}, + {TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99), + TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636)}}, + {{TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49), + TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce)}, + {TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1), + TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049)}}, + {{TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541), + TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb)}, + {TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0), + TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40)}}, + {{TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e), + TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086)}, + {TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed), + TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34)}}, + {{TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342), + TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51)}, + {TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f), + TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3)}}, + {{TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f), + TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60)}, + {TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f), + TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4)}}, + {{TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a), + TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2)}, + {TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c), + TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8)}}, + {{TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b), + TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247)}, + {TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d), + TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c)}}, + {{TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10), + TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0)}, + {TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d), + TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a)}}, + {{TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2), + TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097)}, + {TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae), + TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc)}}, + {{TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc), + TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58)}, + {TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c), + TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141)}}, + {{TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9), + TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8)}, + {TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62), + TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9)}}, + {{TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df), + TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5)}, + {TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b), + TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535)}}, + {{TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd), + TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112)}, + {TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec), + TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe)}}, + {{TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361), + TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77)}, + {TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e), + TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e)}}, + {{TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429), + TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc)}, + {TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f), + TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e)}}, + {{TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372), + TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332)}, + {TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4), + TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29)}}, + {{TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5), + TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04)}, + {TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f), + TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc)}}, + {{TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39), + TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29)}, + {TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb), + TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04)}}, + {{TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7), + TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61)}, + {TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e), + TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961)}}, + {{TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6), + TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc)}, + {TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e), + TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af)}}, + {{TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f), + TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab)}, + {TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9), + TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204)}}, + {{TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e), + TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2)}, + {TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c), + TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03)}}, + {{TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98), + TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42)}, + {TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8), + TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43)}}, + {{TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8), + TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86)}, + {TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d), + TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79)}}, + {{TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404), + TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9)}, + {TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314), + TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5)}}, + {{TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae), + TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357)}, + {TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d), + TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477)}}, + {{TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7), + TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80)}, + {TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d), + TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527)}}, + {{TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da), + TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad)}, + {TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17), + TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25)}}}, + {{{TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58), + TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85)}, + {TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e), + TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a)}}, + {{TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc), + TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3)}, + {TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2), + TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8)}}, + {{TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2), + TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe)}, + {TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d), + TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53)}}, + {{TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be), + TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336)}, + {TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933), + TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f)}}, + {{TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe), + TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc)}, + {TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326), + TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272)}}, + {{TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e), + TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f)}, + {TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c), + TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7)}}, + {{TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9), + TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918)}, + {TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457), + TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60)}}, + {{TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44), + TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a)}, + {TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017), + TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7)}}, + {{TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03), + TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef)}, + {TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1), + TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a)}}, + {{TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b), + TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947)}, + {TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b), + TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa)}}, + {{TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599), + TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1)}, + {TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492), + TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df)}}, + {{TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556), + TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2)}, + {TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f), + TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31)}}, + {{TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0), + TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e)}, + {TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6), + TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195)}}, + {{TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f), + TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15)}, + {TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4), + TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff)}}, + {{TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1), + TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c)}, + {TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9), + TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc)}}, + {{TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0), + TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1)}, + {TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8), + TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4)}}, + {{TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5), + TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a)}, + {TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0), + TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca)}}, + {{TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f), + TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b)}, + {TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37), + TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc)}}, + {{TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1), + TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613)}, + {TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6), + TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8)}}, + {{TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc), + TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984)}, + {TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18), + TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a)}}, + {{TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895), + TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5)}, + {TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d), + TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33)}}, + {{TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44), + TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b)}, + {TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7), + TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120)}}, + {{TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b), + TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9)}, + {TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a), + TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504)}}, + {{TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801), + TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2)}, + {TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e), + TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216)}}, + {{TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924), + TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169)}, + {TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8), + TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a)}}, + {{TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0), + TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd)}, + {TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8), + TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7)}}, + {{TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c), + TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7)}, + {TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556), + TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb)}}, + {{TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091), + TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749)}, + {TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6), + TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722)}}, + {{TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1), + TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce)}, + {TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863), + TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1)}}, + {{TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5), + TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836)}, + {TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf), + TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825)}}, + {{TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99), + TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e)}, + {TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3), + TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6)}}, + {{TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7), + TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5)}, + {TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99), + TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03)}}, + {{TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f), + TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5)}, + {TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516), + TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9)}}, + {{TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f), + TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235)}, + {TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674), + TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e)}}, + {{TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf), + TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05)}, + {TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748), + TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e)}}, + {{TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d), + TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c)}, + {TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601), + TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca)}}, + {{TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f), + TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f)}, + {TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf), + TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a)}}, + {{TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564), + TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6)}, + {TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695), + TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46)}}, + {{TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e), + TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15)}, + {TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955), + TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c)}}, + {{TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154), + TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29)}, + {TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840), + TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb)}}, + {{TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451), + TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e)}, + {TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece), + TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a)}}, + {{TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c), + TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364)}, + {TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8), + TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63)}}, + {{TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35), + TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6)}, + {TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d), + TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a)}}, + {{TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f), + TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391)}, + {TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230), + TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0)}}, + {{TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8), + TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d)}, + {TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801), + TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b)}}, + {{TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b), + TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5)}, + {TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009), + TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0)}}, + {{TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427), + TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d)}, + {TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840), + TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134)}}, + {{TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0), + TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390)}, + {TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9), + TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3)}}, + {{TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d), + TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7)}, + {TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d), + TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb)}}, + {{TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1), + TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326)}, + {TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d), + TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89)}}, + {{TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90), + TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec)}, + {TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df), + TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf)}}, + {{TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2), + TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75)}, + {TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e), + TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016)}}, + {{TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd), + TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719)}, + {TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700), + TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638)}}, + {{TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50), + TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58)}, + {TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0), + TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb)}}, + {{TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef), + TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257)}, + {TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a), + TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0)}}, + {{TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609), + TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2)}, + {TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6), + TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce)}}, + {{TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f), + TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319)}, + {TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb), + TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5)}}, + {{TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed), + TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b)}, + {TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2), + TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b)}}, + {{TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25), + TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624)}, + {TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79), + TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd)}}, + {{TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b), + TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d)}, + {TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442), + TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e)}}, + {{TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5), + TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19)}, + {TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57), + TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc)}}, + {{TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f), + TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3)}, + {TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0), + TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce)}}, + {{TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1), + TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672)}, + {TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d), + TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba)}}, + {{TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97), + TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69)}, + {TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81), + TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328)}}}, + {{{TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd), + TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5)}, + {TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af), + TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82)}}, + {{TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a), + TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3)}, + {TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d), + TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755)}}, + {{TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638), + TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f)}, + {TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1), + TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23)}}, + {{TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2), + TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4)}, + {TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105), + TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329)}}, + {{TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a), + TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897)}, + {TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57), + TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2)}}, + {{TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49), + TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69)}, + {TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2), + TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3)}}, + {{TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817), + TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164)}, + {TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263), + TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32)}}, + {{TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a), + TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f)}, + {TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1), + TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94)}}, + {{TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558), + TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9)}, + {TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22), + TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f)}}, + {{TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f), + TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b)}, + {TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7), + TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0)}}, + {{TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752), + TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf)}, + {TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d), + TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6)}}, + {{TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5), + TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58)}, + {TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177), + TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477)}}, + {{TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4), + TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6)}, + {TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54), + TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c)}}, + {{TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b), + TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b)}, + {TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c), + TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4)}}, + {{TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f), + TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e)}, + {TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487), + TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a)}}, + {{TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658), + TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6)}, + {TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803), + TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f)}}, + {{TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8), + TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893)}, + {TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f), + TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7)}}, + {{TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0), + TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794)}, + {TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e), + TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee)}}, + {{TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c), + TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989)}, + {TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b), + TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84)}}, + {{TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946), + TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc)}, + {TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae), + TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb)}}, + {{TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038), + TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0)}, + {TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6), + TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba)}}, + {{TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6), + TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25)}, + {TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4), + TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8)}}, + {{TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4), + TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d)}, + {TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5), + TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b)}}, + {{TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d), + TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8)}, + {TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6), + TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae)}}, + {{TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc), + TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40)}, + {TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95), + TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913)}}, + {{TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88), + TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e)}, + {TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034), + TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334)}}, + {{TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397), + TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2)}, + {TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0), + TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd)}}, + {{TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10), + TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8)}, + {TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62), + TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8)}}, + {{TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b), + TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075)}, + {TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e), + TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312)}}, + {{TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e), + TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d)}, + {TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb), + TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a)}}, + {{TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261), + TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d)}, + {TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb), + TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c)}}, + {{TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5), + TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0)}, + {TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee), + TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28)}}, + {{TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173), + TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f)}, + {TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01), + TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40)}}, + {{TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d), + TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5)}, + {TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1), + TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574)}}, + {{TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979), + TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d)}, + {TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7), + TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d)}}, + {{TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b), + TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638)}, + {TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36), + TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a)}}, + {{TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253), + TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467)}, + {TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94), + TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311)}}, + {{TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1), + TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea)}, + {TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6), + TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a)}}, + {{TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac), + TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d)}, + {TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354), + TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9)}}, + {{TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4), + TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b)}, + {TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94), + TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074)}}, + {{TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f), + TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60)}, + {TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690), + TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431)}}, + {{TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd), + TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e)}, + {TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e), + TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828)}}, + {{TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d), + TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe)}, + {TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345), + TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d)}}, + {{TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6), + TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8)}, + {TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c), + TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d)}}, + {{TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2), + TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126)}, + {TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395), + TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64)}}, + {{TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57), + TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9)}, + {TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789), + TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7)}}, + {{TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5), + TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced)}, + {TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96), + TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554)}}, + {{TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84), + TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0)}, + {TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88), + TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0)}}, + {{TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d), + TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9)}, + {TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32), + TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351)}}, + {{TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260), + TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8)}, + {TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490), + TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d)}}, + {{TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6), + TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec)}, + {TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627), + TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed)}}, + {{TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45), + TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1)}, + {TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048), + TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597)}}, + {{TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556), + TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577)}, + {TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5), + TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094)}}, + {{TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1), + TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f)}, + {TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96), + TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56)}}, + {{TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236), + TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2)}, + {TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0), + TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a)}}, + {{TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228), + TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa)}, + {TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e), + TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48)}}, + {{TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5), + TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77)}, + {TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f), + TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e)}}, + {{TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74), + TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a)}, + {TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069), + TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436)}}, + {{TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6), + TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd)}, + {TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999), + TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9)}}, + {{TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829), + TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8)}, + {TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df), + TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae)}}, + {{TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7), + TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70)}, + {TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b), + TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f)}}, + {{TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9), + TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7)}, + {TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb), + TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6)}}, + {{TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63), + TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da)}, + {TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b), + TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79)}}, + {{TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e), + TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860)}, + {TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b), + TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745)}}}, + {{{TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d), + TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea)}, + {TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151), + TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98)}}, + {{TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e), + TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f)}, + {TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260), + TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b)}}, + {{TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371), + TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee)}, + {TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3), + TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25)}}, + {{TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df), + TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5)}, + {TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27), + TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644)}}, + {{TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d), + TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8)}, + {TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5), + TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248)}}, + {{TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f), + TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46)}, + {TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6), + TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609)}}, + {{TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd), + TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848)}, + {TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb), + TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6)}}, + {{TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863), + TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e)}, + {TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456), + TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276)}}, + {{TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077), + TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875)}, + {TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481), + TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9)}}, + {{TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19), + TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60)}, + {TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995), + TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508)}}, + {{TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e), + TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a)}, + {TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803), + TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1)}}, + {{TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d), + TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842)}, + {TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e), + TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837)}}, + {{TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5), + TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442)}, + {TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca), + TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf)}}, + {{TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5), + TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3)}, + {TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6), + TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186)}}, + {{TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa), + TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415)}, + {TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115), + TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9)}}, + {{TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9), + TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907)}, + {TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f), + TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df)}}, + {{TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826), + TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69)}, + {TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48), + TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8)}}, + {{TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02), + TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846)}, + {TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4), + TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3)}}, + {{TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9), + TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c)}, + {TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac), + TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188)}}, + {{TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262), + TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2)}, + {TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971), + TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f)}}, + {{TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b), + TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21)}, + {TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41), + TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1)}}, + {{TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57), + TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931)}, + {TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc), + TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033)}}, + {{TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180), + TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894)}, + {TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c), + TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15)}}, + {{TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a), + TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31)}, + {TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186), + TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795)}}, + {{TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9), + TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024)}, + {TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d), + TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259)}}, + {{TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc), + TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e)}, + {TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8), + TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7)}}, + {{TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4), + TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39)}, + {TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190), + TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b)}}, + {{TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b), + TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab)}, + {TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790), + TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2)}}, + {{TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7), + TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a)}, + {TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854), + TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848)}}, + {{TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1), + TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9)}, + {TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd), + TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476)}}, + {{TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3), + TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2)}, + {TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d), + TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb)}}, + {{TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77), + TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b)}, + {TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3), + TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0)}}, + {{TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b), + TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d)}, + {TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8), + TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31)}}, + {{TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b), + TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b)}, + {TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb), + TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4)}}, + {{TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641), + TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055)}, + {TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5), + TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727)}}, + {{TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e), + TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3)}, + {TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55), + TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74)}}, + {{TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7), + TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36)}, + {TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369), + TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d)}}, + {{TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8), + TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2)}, + {TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26), + TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e)}}, + {{TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366), + TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865)}, + {TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf), + TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2)}}, + {{TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923), + TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2)}, + {TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1), + TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3)}}, + {{TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863), + TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017)}, + {TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e), + TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529)}}, + {{TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac), + TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08)}, + {TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475), + TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea)}}, + {{TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd), + TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de)}, + {TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a), + TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef)}}, + {{TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58), + TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815)}, + {TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4), + TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff)}}, + {{TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc), + TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583)}, + {TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe), + TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e)}}, + {{TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9), + TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507)}, + {TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0), + TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d)}}, + {{TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997), + TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536)}, + {TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680), + TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda)}}, + {{TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b), + TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12)}, + {TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d), + TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e)}}, + {{TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a), + TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154)}, + {TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b), + TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef)}}, + {{TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e), + TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f)}, + {TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2), + TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094)}}, + {{TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5), + TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b)}, + {TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a), + TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594)}}, + {{TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d), + TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223)}, + {TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06), + TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40)}}, + {{TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd), + TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8)}, + {TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249), + TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd)}}, + {{TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1), + TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e)}, + {TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e), + TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93)}}, + {{TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42), + TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5)}, + {TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60), + TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf)}}, + {{TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f), + TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557)}, + {TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8), + TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8)}}, + {{TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99), + TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c)}, + {TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd), + TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56)}}, + {{TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd), + TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e)}, + {TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d), + TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929)}}, + {{TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660), + TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329)}, + {TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299), + TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8)}}, + {{TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf), + TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7)}, + {TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27), + TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120)}}, + {{TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939), + TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4)}, + {TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880), + TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120)}}, + {{TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546), + TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b)}, + {TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27), + TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3)}}, + {{TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36), + TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1)}, + {TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142), + TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66)}}, + {{TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd), + TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6)}, + {TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366), + TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83)}}}, + {{{TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b), + TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325)}, + {TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707), + TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174)}}, + {{TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4), + TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea)}, + {TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3), + TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad)}}, + {{TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e), + TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9)}, + {TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98), + TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9)}}, + {{TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b), + TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394)}, + {TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9), + TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0)}}, + {{TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173), + TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb)}, + {TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394), + TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7)}}, + {{TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442), + TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b)}, + {TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127), + TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35)}}, + {{TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb), + TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b)}, + {TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c), + TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c)}}, + {{TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f), + TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7)}, + {TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac), + TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818)}}, + {{TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc), + TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a)}, + {TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc), + TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0)}}, + {{TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93), + TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de)}, + {TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee), + TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7)}}, + {{TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea), + TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9)}, + {TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b), + TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5)}}, + {{TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2), + TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe)}, + {TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635), + TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2)}}, + {{TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341), + TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b)}, + {TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43), + TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27)}}, + {{TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356), + TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b)}, + {TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6), + TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714)}}, + {{TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9), + TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc)}, + {TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b), + TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f)}}, + {{TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5), + TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f)}, + {TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341), + TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7)}}, + {{TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd), + TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf)}, + {TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c), + TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa)}}, + {{TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0), + TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd)}, + {TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586), + TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817)}}, + {{TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37), + TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51)}, + {TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0), + TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c)}}, + {{TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a), + TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b)}, + {TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f), + TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f)}}, + {{TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2), + TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1)}, + {TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3), + TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50)}}, + {{TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92), + TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca)}, + {TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63), + TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8)}}, + {{TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f), + TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f)}, + {TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4), + TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0)}}, + {{TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645), + TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed)}, + {TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba), + TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2)}}, + {{TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f), + TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933)}, + {TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d), + TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063)}}, + {{TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8), + TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8)}, + {TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df), + TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff)}}, + {{TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef), + TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d)}, + {TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a), + TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938)}}, + {{TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6), + TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92)}, + {TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda), + TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65)}}, + {{TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f), + TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4)}, + {TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf), + TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87)}}, + {{TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458), + TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d)}, + {TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5), + TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469)}}, + {{TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41), + TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee)}, + {TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f), + TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3)}}, + {{TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f), + TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2)}, + {TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069), + TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5)}}, + {{TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b), + TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047)}, + {TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f), + TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f)}}, + {{TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7), + TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0)}, + {TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d), + TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4)}}, + {{TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f), + TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472)}, + {TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c), + TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2)}}, + {{TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32), + TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a)}, + {TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080), + TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8)}}, + {{TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce), + TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796)}, + {TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79), + TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b)}}, + {{TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106), + TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433)}, + {TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102), + TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b)}}, + {{TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02), + TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f)}, + {TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34), + TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724)}}, + {{TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f), + TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd)}, + {TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a), + TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc)}}, + {{TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2), + TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a)}, + {TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a), + TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f)}}, + {{TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237), + TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9)}, + {TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd), + TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62)}}, + {{TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87), + TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd)}, + {TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6), + TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f)}}, + {{TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7), + TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886)}, + {TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea), + TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a)}}, + {{TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35), + TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db)}, + {TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b), + TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7)}}, + {{TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72), + TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25)}, + {TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61), + TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d)}}, + {{TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068), + TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53)}, + {TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632), + TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f)}}, + {{TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387), + TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e)}, + {TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067), + TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f)}}, + {{TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9), + TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c)}, + {TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d), + TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748)}}, + {{TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135), + TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631)}, + {TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a), + TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d)}}, + {{TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8), + TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad)}, + {TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b), + TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0)}}, + {{TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51), + TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05)}, + {TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb), + TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c)}}, + {{TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce), + TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9)}, + {TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf), + TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1)}}, + {{TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8), + TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624)}, + {TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6), + TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4)}}, + {{TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde), + TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13)}, + {TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee), + TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710)}}, + {{TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3), + TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100)}, + {TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a), + TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d)}}, + {{TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c), + TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df)}, + {TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093), + TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6)}}, + {{TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4), + TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2)}, + {TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11), + TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c)}}, + {{TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab), + TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c)}, + {TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400), + TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79)}}, + {{TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4), + TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d)}, + {TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8), + TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930)}}, + {{TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7), + TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303)}, + {TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e), + TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade)}}, + {{TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b), + TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b)}, + {TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927), + TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20)}}, + {{TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd), + TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6)}, + {TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288), + TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e)}}, + {{TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8), + TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d)}, + {TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362), + TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b)}}}, + {{{TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2), + TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400)}, + {TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e), + TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9)}}, + {{TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7), + TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e)}, + {TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a), + TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab)}}, + {{TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e), + TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d)}, + {TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1), + TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e)}}, + {{TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07), + TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325)}, + {TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386), + TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8)}}, + {{TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90), + TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df)}, + {TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64), + TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286)}}, + {{TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04), + TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069)}, + {TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf), + TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708)}}, + {{TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299), + TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6)}, + {TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32), + TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671)}}, + {{TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370), + TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3)}, + {TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103), + TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d)}}, + {{TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea), + TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe)}, + {TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b), + TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913)}}, + {{TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a), + TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb)}, + {TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e), + TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6)}}, + {{TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a), + TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613)}, + {TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129), + TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3)}}, + {{TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026), + TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac)}, + {TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7), + TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317)}}, + {{TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5), + TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3)}, + {TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a), + TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac)}}, + {{TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed), + TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613)}, + {TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16), + TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61)}}, + {{TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992), + TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2)}, + {TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e), + TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10)}}, + {{TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd), + TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064)}, + {TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2), + TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d)}}, + {{TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57), + TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a)}, + {TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21), + TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a)}}, + {{TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580), + TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3)}, + {TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f), + TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4)}}, + {{TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311), + TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47)}, + {TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f), + TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48)}}, + {{TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06), + TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1)}, + {TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2), + TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1)}}, + {{TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2), + TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836)}, + {TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686), + TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9)}}, + {{TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4), + TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555)}, + {TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f), + TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79)}}, + {{TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905), + TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f)}, + {TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8), + TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a)}}, + {{TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269), + TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b)}, + {TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22), + TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809)}}, + {{TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a), + TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87)}, + {TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36), + TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a)}}, + {{TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf), + TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea)}, + {TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10), + TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365)}}, + {{TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127), + TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d)}, + {TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299), + TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c)}}, + {{TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1), + TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c)}, + {TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8), + TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd)}}, + {{TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd), + TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd)}, + {TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27), + TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97)}}, + {{TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb), + TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a)}, + {TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43), + TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be)}}, + {{TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09), + TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468)}, + {TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1), + TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448)}}, + {{TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5), + TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069)}, + {TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9), + TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6)}}, + {{TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3), + TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a)}, + {TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4), + TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66)}}, + {{TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d), + TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00)}, + {TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4), + TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8)}}, + {{TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586), + TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f)}, + {TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8), + TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce)}}, + {{TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141), + TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083)}, + {TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1), + TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c)}}, + {{TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc), + TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be)}, + {TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3), + TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19)}}, + {{TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d), + TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079)}, + {TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d), + TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5)}}, + {{TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868), + TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d)}, + {TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80), + TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944)}}, + {{TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137), + TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801)}, + {TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c), + TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02)}}, + {{TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e), + TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e)}, + {TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681), + TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa)}}, + {{TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98), + TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2)}, + {TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92), + TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7)}}, + {{TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5), + TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2)}, + {TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef), + TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8)}}, + {{TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a), + TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d)}, + {TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f), + TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f)}}, + {{TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220), + TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056)}, + {TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28), + TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b)}}, + {{TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a), + TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0)}, + {TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54), + TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86)}}, + {{TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f), + TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6)}, + {TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751), + TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec)}}, + {{TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654), + TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149)}, + {TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3), + TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1)}}, + {{TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae), + TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5)}, + {TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062), + TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef)}}, + {{TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f), + TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1)}, + {TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c), + TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d)}}, + {{TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373), + TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76)}, + {TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a), + TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d)}}, + {{TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0), + TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057)}, + {TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24), + TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3)}}, + {{TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922), + TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a)}, + {TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4), + TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382)}}, + {{TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318), + TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685)}, + {TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a), + TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c)}}, + {{TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d), + TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac)}, + {TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc), + TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92)}}, + {{TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b), + TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794)}, + {TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38), + TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48)}}, + {{TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791), + TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616)}, + {TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f), + TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802)}}, + {{TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb), + TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3)}, + {TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5), + TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c)}}, + {{TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb), + TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68)}, + {TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157), + TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856)}}, + {{TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783), + TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05)}, + {TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd), + TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f)}}, + {{TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e), + TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614)}, + {TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d), + TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff)}}, + {{TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004), + TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5)}, + {TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1), + TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7)}}, + {{TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993), + TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233)}, + {TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552), + TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19)}}, + {{TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8), + TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054)}, + {TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3), + TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74)}}}, + {{{TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c), + TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f)}, + {TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a), + TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1)}}, + {{TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa), + TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068)}, + {TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399), + TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2)}}, + {{TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240), + TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd)}, + {TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242), + TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de)}}, + {{TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3), + TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6)}, + {TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1), + TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234)}}, + {{TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a), + TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52)}, + {TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62), + TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9)}}, + {{TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21), + TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00)}, + {TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab), + TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c)}}, + {{TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5), + TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863)}, + {TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7), + TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87)}}, + {{TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6), + TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3)}, + {TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501), + TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b)}}, + {{TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6), + TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52)}, + {TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d), + TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd)}}, + {{TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf), + TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e)}, + {TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac), + TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0)}}, + {{TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c), + TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d)}, + {TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6), + TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6)}}, + {{TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9), + TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e)}, + {TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc), + TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d)}}, + {{TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10), + TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9)}, + {TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9), + TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499)}}, + {{TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947), + TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f)}, + {TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571), + TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369)}}, + {{TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566), + TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5)}, + {TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324), + TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3)}}, + {{TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd), + TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969)}, + {TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1), + TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c)}}, + {{TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332), + TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8)}, + {TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33), + TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7)}}, + {{TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48), + TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f)}, + {TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2), + TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b)}}, + {{TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636), + TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5)}, + {TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b), + TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc)}}, + {{TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f), + TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c)}, + {TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f), + TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116)}}, + {{TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14), + TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289)}, + {TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09), + TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388)}}, + {{TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed), + TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e)}, + {TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04), + TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b)}}, + {{TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909), + TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c)}, + {TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f), + TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480)}}, + {{TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680), + TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9)}, + {TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d), + TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21)}}, + {{TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850), + TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc)}, + {TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842), + TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc)}}, + {{TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427), + TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b)}, + {TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45), + TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130)}}, + {{TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa), + TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692)}, + {TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf), + TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b)}}, + {{TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5), + TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a)}, + {TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c), + TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156)}}, + {{TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f), + TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b)}, + {TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0), + TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5)}}, + {{TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669), + TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc)}, + {TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee), + TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b)}}, + {{TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8), + TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8)}, + {TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48), + TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841)}}, + {{TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4), + TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad)}, + {TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd), + TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443)}}, + {{TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96), + TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb)}, + {TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b), + TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d)}}, + {{TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727), + TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff)}, + {TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f), + TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf)}}, + {{TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556), + TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361)}, + {TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa), + TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140)}}, + {{TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978), + TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e)}, + {TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50), + TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e)}}, + {{TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6), + TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0)}, + {TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648), + TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174)}}, + {{TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5), + TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc)}, + {TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d), + TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914)}}, + {{TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d), + TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb)}, + {TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e), + TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17)}}, + {{TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0), + TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f)}, + {TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34), + TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366)}}, + {{TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f), + TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178)}, + {TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976), + TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932)}}, + {{TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914), + TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a)}, + {TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09), + TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6)}}, + {{TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430), + TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450)}, + {TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23), + TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481)}}, + {{TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517), + TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932)}, + {TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a), + TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853)}}, + {{TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e), + TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b)}, + {TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40), + TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494)}}, + {{TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b), + TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c)}, + {TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d), + TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135)}}, + {{TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69), + TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd)}, + {TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d), + TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0)}}, + {{TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c), + TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e)}, + {TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1), + TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f)}}, + {{TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c), + TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab)}, + {TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a), + TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f)}}, + {{TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c), + TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80)}, + {TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba), + TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599)}}, + {{TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297), + TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c)}, + {TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f), + TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54)}}, + {{TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38), + TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d)}, + {TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c), + TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a)}}, + {{TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165), + TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8)}, + {TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86), + TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038)}}, + {{TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177), + TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b)}, + {TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb), + TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0)}}, + {{TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475), + TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3)}, + {TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37), + TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a)}}, + {{TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649), + TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d)}, + {TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf), + TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9)}}, + {{TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac), + TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a)}, + {TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224), + TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3)}}, + {{TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b), + TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe)}, + {TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff), + TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353)}}, + {{TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906), + TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743)}, + {TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27), + TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd)}}, + {{TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda), + TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2)}, + {TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288), + TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a)}}, + {{TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74), + TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710)}, + {TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf), + TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5)}}, + {{TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611), + TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10)}, + {TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6), + TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29)}}, + {{TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86), + TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279)}, + {TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4), + TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318)}}, + {{TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc), + TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc)}, + {TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3), + TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762)}}}, + {{{TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f), + TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61)}, + {TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20), + TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc)}}, + {{TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235), + TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7)}, + {TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60), + TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152)}}, + {{TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e), + TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093)}, + {TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8), + TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28)}}, + {{TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573), + TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e)}, + {TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16), + TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5)}}, + {{TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3), + TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d)}, + {TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6), + TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0)}}, + {{TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6), + TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965)}, + {TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123), + TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d)}}, + {{TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7), + TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3)}, + {TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d), + TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07)}}, + {{TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a), + TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b)}, + {TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f), + TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1)}}, + {{TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce), + TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217)}, + {TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d), + TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6)}}, + {{TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6), + TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884)}, + {TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682), + TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b)}}, + {{TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2), + TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6)}, + {TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4), + TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc)}}, + {{TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680), + TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2)}, + {TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142), + TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea)}}, + {{TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6), + TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529)}, + {TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925), + TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3)}}, + {{TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10), + TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3)}, + {TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6), + TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a)}}, + {{TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b), + TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d)}, + {TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05), + TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba)}}, + {{TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65), + TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3)}, + {TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3), + TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0)}}, + {{TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118), + TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214)}, + {TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b), + TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5)}}, + {{TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f), + TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21)}, + {TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb), + TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3)}}, + {{TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab), + TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f)}, + {TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1), + TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8)}}, + {{TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3), + TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e)}, + {TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0), + TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225)}}, + {{TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41), + TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9)}, + {TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad), + TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507)}}, + {{TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb), + TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628)}, + {TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b), + TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c)}}, + {{TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039), + TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211)}, + {TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005), + TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c)}}, + {{TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36), + TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3)}, + {TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371), + TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6)}}, + {{TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795), + TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2)}, + {TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a), + TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16)}}, + {{TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584), + TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8)}, + {TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b), + TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5)}}, + {{TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c), + TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7)}, + {TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee), + TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93)}}, + {{TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699), + TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60)}, + {TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e), + TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43)}}, + {{TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a), + TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e)}, + {TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1), + TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52)}}, + {{TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd), + TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924)}, + {TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4), + TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7)}}, + {{TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0), + TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab)}, + {TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08), + TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c)}}, + {{TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3), + TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288)}, + {TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f), + TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b)}}, + {{TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646), + TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c)}, + {TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda), + TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2)}}, + {{TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df), + TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c)}, + {TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df), + TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa)}}, + {{TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348), + TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e)}, + {TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59), + TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e)}}, + {{TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c), + TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917)}, + {TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357), + TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e)}}, + {{TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5), + TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4)}, + {TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f), + TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa)}}, + {{TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357), + TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1)}, + {TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805), + TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804)}}, + {{TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d), + TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7)}, + {TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a), + TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784)}}, + {{TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310), + TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74)}, + {TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51), + TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63)}}, + {{TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559), + TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4)}, + {TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a), + TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80)}}, + {{TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca), + TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182)}, + {TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860), + TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f)}}, + {{TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70), + TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5)}, + {TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd), + TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790)}}, + {{TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4), + TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa)}, + {TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685), + TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810)}}, + {{TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5), + TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92)}, + {TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21), + TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41)}}, + {{TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe), + TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08)}, + {TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1), + TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c)}}, + {{TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47), + TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7)}, + {TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a), + TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6)}}, + {{TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e), + TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2)}, + {TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b), + TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67)}}, + {{TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca), + TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04)}, + {TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a), + TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea)}}, + {{TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b), + TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f)}, + {TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815), + TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39)}}, + {{TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749), + TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77)}, + {TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61), + TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0)}}, + {{TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54), + TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614)}, + {TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28), + TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16)}}, + {{TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb), + TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954)}, + {TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998), + TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc)}}, + {{TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934), + TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44)}, + {TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a), + TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f)}}, + {{TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e), + TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d)}, + {TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f), + TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585)}}, + {{TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239), + TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413)}, + {TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e), + TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28)}}, + {{TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4), + TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10)}, + {TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33), + TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c)}}, + {{TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8), + TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2)}, + {TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815), + TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e)}}, + {{TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c), + TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240)}, + {TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3), + TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb)}}, + {{TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5), + TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d)}, + {TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f), + TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79)}}, + {{TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1), + TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0)}, + {TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3), + TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039)}}, + {{TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab), + TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944)}, + {TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb), + TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf)}}, + {{TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6), + TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316)}, + {TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789), + TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6)}}, + {{TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51), + TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017)}, + {TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722), + TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e)}}}, + {{{TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3), + TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb)}, + {TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c), + TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b)}}, + {{TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0), + TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b)}, + {TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080), + TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600)}}, + {{TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc), + TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026)}, + {TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89), + TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731)}}, + {{TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79), + TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0)}, + {TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6), + TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668)}}, + {{TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383), + TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee)}, + {TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f), + TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a)}}, + {{TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0), + TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa)}, + {TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf), + TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9)}}, + {{TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc), + TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745)}, + {TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea), + TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a)}}, + {{TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650), + TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b)}, + {TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989), + TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5)}}, + {{TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18), + TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c)}, + {TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638), + TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293)}}, + {{TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857), + TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5)}, + {TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74), + TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582)}}, + {{TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1), + TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c)}, + {TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef), + TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8)}}, + {{TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb), + TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f)}, + {TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583), + TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739)}}, + {{TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344), + TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c)}, + {TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82), + TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba)}}, + {{TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325), + TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0)}, + {TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791), + TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655)}}, + {{TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305), + TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6)}, + {TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7), + TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd)}}, + {{TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab), + TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350)}, + {TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974), + TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1)}}, + {{TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27), + TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78)}, + {TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996), + TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da)}}, + {{TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb), + TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77)}, + {TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230), + TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449)}}, + {{TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f), + TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e)}, + {TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40), + TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2)}}, + {{TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683), + TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83)}, + {TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2), + TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c)}}, + {{TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd), + TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804)}, + {TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118), + TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4)}}, + {{TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051), + TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec)}, + {TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b), + TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493)}}, + {{TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0), + TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b)}, + {TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4), + TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00)}}, + {{TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b), + TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953)}, + {TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6), + TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf)}}, + {{TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80), + TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328)}, + {TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215), + TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61)}}, + {{TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a), + TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497)}, + {TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0), + TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4)}}, + {{TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce), + TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56)}, + {TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e), + TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb)}}, + {{TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf), + TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961)}, + {TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063), + TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c)}}, + {{TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9), + TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb)}, + {TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1), + TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264)}}, + {{TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe), + TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0)}, + {TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182), + TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33)}}, + {{TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46), + TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78)}, + {TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055), + TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90)}}, + {{TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2), + TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5)}, + {TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b), + TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14)}}, + {{TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f), + TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0)}, + {TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565), + TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d)}}, + {{TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea), + TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2)}, + {TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670), + TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d)}}, + {{TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c), + TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c)}, + {TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33), + TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad)}}, + {{TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589), + TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd)}, + {TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414), + TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675)}}, + {{TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048), + TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f)}, + {TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef), + TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97)}}, + {{TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8), + TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b)}, + {TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a), + TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9)}}, + {{TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165), + TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da)}, + {TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c), + TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d)}}, + {{TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd), + TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11)}, + {TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d), + TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb)}}, + {{TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a), + TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000)}, + {TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9), + TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27)}}, + {{TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4), + TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193)}, + {TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17), + TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067)}}, + {{TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da), + TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449)}, + {TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b), + TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943)}}, + {{TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54), + TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f)}, + {TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53), + TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104)}}, + {{TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2), + TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903)}, + {TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e), + TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc)}}, + {{TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037), + TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22)}, + {TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8), + TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e)}}, + {{TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e), + TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39)}, + {TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498), + TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf)}}, + {{TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7), + TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a)}, + {TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b), + TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e)}}, + {{TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff), + TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8)}, + {TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be), + TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c)}}, + {{TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680), + TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef)}, + {TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8), + TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e)}}, + {{TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b), + TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201)}, + {TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900), + TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c)}}, + {{TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0), + TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191)}, + {TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5), + TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89)}}, + {{TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3), + TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12)}, + {TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf), + TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe)}}, + {{TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40), + TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936)}, + {TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379), + TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531)}}, + {{TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44), + TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15)}, + {TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7), + TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7)}}, + {{TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40), + TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c)}, + {TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e), + TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b)}}, + {{TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772), + TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47)}, + {TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2), + TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07)}}, + {{TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63), + TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5)}, + {TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db), + TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e)}}, + {{TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423), + TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b)}, + {TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459), + TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699)}}, + {{TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6), + TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777)}, + {TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d), + TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08)}}, + {{TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a), + TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e)}, + {TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46), + TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22)}}, + {{TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148), + TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f)}, + {TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab), + TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef)}}, + {{TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3), + TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91)}, + {TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243), + TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e)}}, + {{TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b), + TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b)}, + {TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0), + TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d)}}}, + {{{TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828), + TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa)}, + {TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17), + TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b)}}, + {{TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2), + TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff)}, + {TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6), + TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733)}}, + {{TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35), + TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538)}, + {TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b), + TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80)}}, + {{TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665), + TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6)}, + {TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c), + TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2)}}, + {{TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3), + TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996)}, + {TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7), + TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4)}}, + {{TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde), + TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f)}, + {TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f), + TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd)}}, + {{TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd), + TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c)}, + {TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6), + TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7)}}, + {{TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71), + TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11)}, + {TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1), + TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7)}}, + {{TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29), + TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514)}, + {TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5), + TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19)}}, + {{TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613), + TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16)}, + {TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5), + TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e)}}, + {{TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1), + TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a)}, + {TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b), + TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba)}}, + {{TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee), + TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa)}, + {TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1), + TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836)}}, + {{TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878), + TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a)}, + {TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f), + TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af)}}, + {{TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22), + TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b)}, + {TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c), + TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0)}}, + {{TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634), + TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405)}, + {TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65), + TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e)}}, + {{TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b), + TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831)}, + {TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029), + TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab)}}, + {{TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77), + TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e)}, + {TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5), + TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b)}}, + {{TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a), + TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620)}, + {TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4), + TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428)}}, + {{TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48), + TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf)}, + {TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584), + TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f)}}, + {{TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298), + TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d)}, + {TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85), + TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b)}}, + {{TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26), + TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87)}, + {TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811), + TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592)}}, + {{TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043), + TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa)}, + {TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82), + TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72)}}, + {{TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2), + TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba)}, + {TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1), + TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642)}}, + {{TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce), + TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294)}, + {TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c), + TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949)}}, + {{TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03), + TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd)}, + {TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd), + TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa)}}, + {{TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8), + TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db)}, + {TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff), + TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b)}}, + {{TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75), + TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb)}, + {TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999), + TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108)}}, + {{TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8), + TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec)}, + {TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229), + TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f)}}, + {{TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a), + TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29)}, + {TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053), + TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e)}}, + {{TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df), + TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558)}, + {TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b), + TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff)}}, + {{TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a), + TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e)}, + {TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43), + TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d)}}, + {{TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0), + TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43)}, + {TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904), + TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf)}}, + {{TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4), + TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12)}, + {TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460), + TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c)}}, + {{TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c), + TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8)}, + {TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4), + TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48)}}, + {{TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11), + TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9)}, + {TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c), + TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316)}}, + {{TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c), + TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01)}, + {TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101), + TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572)}}, + {{TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5), + TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250)}, + {TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c), + TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe)}}, + {{TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95), + TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8)}, + {TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb), + TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28)}}, + {{TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96), + TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51)}, + {TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233), + TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005)}}, + {{TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217), + TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a)}, + {TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f), + TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b)}}, + {{TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb), + TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761)}, + {TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db), + TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a)}}, + {{TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06), + TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12)}, + {TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4), + TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20)}}, + {{TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e), + TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9)}, + {TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad), + TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b)}}, + {{TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f), + TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed)}, + {TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c), + TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038)}}, + {{TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536), + TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2)}, + {TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea), + TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843)}}, + {{TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210), + TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6)}, + {TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff), + TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2)}}, + {{TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5), + TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e)}, + {TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6), + TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035)}}, + {{TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04), + TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3)}, + {TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd), + TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea)}}, + {{TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843), + TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed)}, + {TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e), + TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7)}}, + {{TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b), + TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754)}, + {TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385), + TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e)}}, + {{TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed), + TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772)}, + {TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e), + TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850)}}, + {{TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3), + TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7)}, + {TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354), + TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0)}}, + {{TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad), + TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b)}, + {TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5), + TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843)}}, + {{TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4), + TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c)}, + {TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18), + TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040)}}, + {{TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4), + TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c)}, + {TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963), + TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c)}}, + {{TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0), + TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4)}, + {TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84), + TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf)}}, + {{TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17), + TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065)}, + {TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178), + TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5)}}, + {{TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485), + TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea)}, + {TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea), + TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75)}}, + {{TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed), + TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22)}, + {TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff), + TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113)}}, + {{TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b), + TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331)}, + {TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08), + TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c)}}, + {{TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8), + TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22)}, + {TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295), + TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536)}}, + {{TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae), + TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb)}, + {TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc), + TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161)}}, + {{TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98), + TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd)}, + {TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a), + TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1)}}, + {{TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246), + TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53)}, + {TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707), + TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d)}}}, + {{{TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320), + TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae)}, + {TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de), + TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5)}}, + {{TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e), + TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2)}, + {TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7), + TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f)}}, + {{TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2), + TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0)}, + {TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e), + TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f)}}, + {{TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e), + TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef)}, + {TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2), + TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81)}}, + {{TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75), + TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663)}, + {TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e), + TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e)}}, + {{TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c), + TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951)}, + {TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d), + TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651)}}, + {{TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625), + TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a)}, + {TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b), + TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506)}}, + {{TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a), + TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be)}, + {TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4), + TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13)}}, + {{TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e), + TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c)}, + {TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931), + TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b)}}, + {{TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b), + TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d)}, + {TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3), + TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456)}}, + {{TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e), + TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce)}, + {TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12), + TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16)}}, + {{TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb), + TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7)}, + {TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f), + TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991)}}, + {{TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12), + TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2)}, + {TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f), + TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f)}}, + {{TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523), + TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b)}, + {TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b), + TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5)}}, + {{TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673), + TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2)}, + {TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c), + TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b)}}, + {{TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a), + TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540)}, + {TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995), + TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268)}}, + {{TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e), + TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3)}, + {TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75), + TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6)}}, + {{TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3), + TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382)}, + {TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d), + TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b)}}, + {{TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7), + TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061)}, + {TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1), + TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069)}}, + {{TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247), + TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0)}, + {TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24), + TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da)}}, + {{TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894), + TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b)}, + {TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9), + TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a)}}, + {{TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb), + TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05)}, + {TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf), + TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c)}}, + {{TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc), + TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd)}, + {TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e), + TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1)}}, + {{TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4), + TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e)}, + {TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64), + TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574)}}, + {{TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a), + TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae)}, + {TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35), + TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f)}}, + {{TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c), + TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed)}, + {TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345), + TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c)}}, + {{TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb), + TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87)}, + {TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a), + TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3)}}, + {{TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc), + TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c)}, + {TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2), + TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf)}}, + {{TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946), + TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5)}, + {TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9), + TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52)}}, + {{TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3), + TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad)}, + {TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96), + TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459)}}, + {{TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a), + TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7)}, + {TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d), + TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa)}}, + {{TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142), + TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec)}, + {TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10), + TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1)}}, + {{TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815), + TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5)}, + {TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464), + TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6)}}, + {{TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0), + TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963)}, + {TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232), + TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a)}}, + {{TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af), + TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7)}, + {TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae), + TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981)}}, + {{TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e), + TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a)}, + {TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9), + TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2)}}, + {{TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681), + TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9)}, + {TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8), + TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04)}}, + {{TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472), + TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7)}, + {TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71), + TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954)}}, + {{TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972), + TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8)}, + {TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4), + TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812)}}, + {{TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04), + TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e)}, + {TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d), + TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46)}}, + {{TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52), + TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7)}, + {TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b), + TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2)}}, + {{TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09), + TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef)}, + {TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6), + TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5)}}, + {{TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5), + TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac)}, + {TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de), + TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421)}}, + {{TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b), + TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d)}, + {TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708), + TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df)}}, + {{TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e), + TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c)}, + {TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e), + TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0)}}, + {{TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd), + TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27)}, + {TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d), + TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457)}}, + {{TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d), + TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9)}, + {TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51), + TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f)}}, + {{TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff), + TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc)}, + {TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1), + TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8)}}, + {{TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27), + TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566)}, + {TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7), + TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36)}}, + {{TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8), + TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4)}, + {TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd), + TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256)}}, + {{TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1), + TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175)}, + {TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c), + TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987)}}, + {{TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94), + TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240)}, + {TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22), + TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf)}}, + {{TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5), + TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894)}, + {TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743), + TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb)}}, + {{TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33), + TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b)}, + {TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59), + TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d)}}, + {{TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459), + TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278)}, + {TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782), + TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006)}}, + {{TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2), + TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f)}, + {TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83), + TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c)}}, + {{TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d), + TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161)}, + {TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513), + TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5)}}, + {{TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959), + TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f)}, + {TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75), + TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9)}}, + {{TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c), + TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231)}, + {TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36), + TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e)}}, + {{TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c), + TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49)}, + {TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef), + TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca)}}, + {{TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa), + TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c)}, + {TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081), + TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47)}}, + {{TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9), + TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96)}, + {TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4), + TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847)}}, + {{TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8), + TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72)}, + {TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf), + TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011)}}, + {{TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05), + TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58)}, + {TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8), + TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691)}}}, + {{{TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da), + TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c)}, + {TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa), + TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7)}}, + {{TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e), + TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21)}, + {TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025), + TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8)}}, + {{TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607), + TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82)}, + {TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0), + TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28)}}, + {{TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562), + TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d)}, + {TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0), + TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1)}}, + {{TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c), + TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9)}, + {TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085), + TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f)}}, + {{TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6), + TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f)}, + {TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9), + TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6)}}, + {{TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1), + TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef)}, + {TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13), + TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577)}}, + {{TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae), + TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240)}, + {TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39), + TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9)}}, + {{TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291), + TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8)}, + {TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d), + TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5)}}, + {{TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e), + TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8)}, + {TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f), + TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae)}}, + {{TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05), + TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae)}, + {TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced), + TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433)}}, + {{TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8), + TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d)}, + {TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1), + TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7)}}, + {{TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6), + TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e)}, + {TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994), + TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d)}}, + {{TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5), + TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d)}, + {TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b), + TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16)}}, + {{TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc), + TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a)}, + {TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5), + TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0)}}, + {{TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7), + TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda)}, + {TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2), + TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413)}}, + {{TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12), + TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0)}, + {TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65), + TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8)}}, + {{TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e), + TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d)}, + {TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da), + TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4)}}, + {{TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f), + TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277)}, + {TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec), + TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9)}}, + {{TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385), + TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36)}, + {TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a), + TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e)}}, + {{TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef), + TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b)}, + {TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f), + TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462)}}, + {{TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd), + TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed)}, + {TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f), + TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e)}}, + {{TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b), + TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf)}, + {TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2), + TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2)}}, + {{TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456), + TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e)}, + {TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a), + TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a)}}, + {{TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57), + TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a)}, + {TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42), + TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3)}}, + {{TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32), + TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d)}, + {TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909), + TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83)}}, + {{TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead), + TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8)}, + {TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd), + TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0)}}, + {{TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d), + TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436)}, + {TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179), + TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845)}}, + {{TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97), + TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4)}, + {TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d), + TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43)}}, + {{TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b), + TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff)}, + {TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb), + TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368)}}, + {{TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26), + TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937)}, + {TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8), + TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40)}}, + {{TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf), + TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2)}, + {TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a), + TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a)}}, + {{TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3), + TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3)}, + {TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002), + TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56)}}, + {{TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7), + TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411)}, + {TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b), + TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3)}}, + {{TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848), + TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e)}, + {TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72), + TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31)}}, + {{TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e), + TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68)}, + {TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf), + TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8)}}, + {{TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b), + TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758)}, + {TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533), + TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b)}}, + {{TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515), + TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8)}, + {TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885), + TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46)}}, + {{TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98), + TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3)}, + {TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72), + TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b)}}, + {{TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477), + TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819)}, + {TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b), + TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838)}}, + {{TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4), + TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3)}, + {TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718), + TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f)}}, + {{TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e), + TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1)}, + {TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c), + TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5)}}, + {{TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1), + TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133)}, + {TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3), + TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff)}}, + {{TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e), + TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea)}, + {TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec), + TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6)}}, + {{TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c), + TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39)}, + {TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39), + TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1)}}, + {{TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921), + TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149)}, + {TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e), + TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781)}}, + {{TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0), + TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe)}, + {TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30), + TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0)}}, + {{TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98), + TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651)}, + {TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521), + TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91)}}, + {{TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2), + TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87)}, + {TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41), + TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5)}}, + {{TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469), + TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6)}, + {TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8), + TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a)}}, + {{TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee), + TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31)}, + {TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e), + TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63)}}, + {{TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8), + TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a)}, + {TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7), + TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f)}}, + {{TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29), + TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61)}, + {TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e), + TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247)}}, + {{TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210), + TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947)}, + {TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c), + TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a)}}, + {{TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793), + TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7)}, + {TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c), + TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7)}}, + {{TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5), + TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1)}, + {TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da), + TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026)}}, + {{TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9), + TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146)}, + {TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22), + TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d)}}, + {{TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771), + TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de)}, + {TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049), + TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678)}}, + {{TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f), + TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a)}, + {TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c), + TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d)}}, + {{TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28), + TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7)}, + {TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7), + TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11)}}, + {{TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd), + TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93)}, + {TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb), + TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d)}}, + {{TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3), + TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606)}, + {TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89), + TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8)}}, + {{TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9), + TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7)}, + {TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276), + TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4)}}, + {{TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454), + TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372)}, + {TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e), + TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f)}}}, + {{{TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7), + TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943)}, + {TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362), + TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297)}}, + {{TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7), + TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0)}, + {TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c), + TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc)}}, + {{TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf), + TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858)}, + {TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304), + TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900)}}, + {{TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96), + TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304)}, + {TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b), + TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651)}}, + {{TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267), + TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65)}, + {TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1), + TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6)}}, + {{TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab), + TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d)}, + {TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece), + TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac)}}, + {{TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192), + TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046)}, + {TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352), + TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667)}}, + {{TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e), + TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57)}, + {TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b), + TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3)}}, + {{TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704), + TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7)}, + {TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be), + TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291)}}, + {{TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c), + TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d)}, + {TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c), + TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e)}}, + {{TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682), + TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799)}, + {TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9), + TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756)}}, + {{TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e), + TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8)}, + {TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86), + TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836)}}, + {{TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be), + TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1)}, + {TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d), + TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b)}}, + {{TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052), + TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48)}, + {TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d), + TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43)}}, + {{TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961), + TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17)}, + {TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1), + TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed)}}, + {{TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840), + TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644)}, + {TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e), + TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c)}}, + {{TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf), + TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867)}, + {TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41), + TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67)}}, + {{TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77), + TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a)}, + {TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276), + TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b)}}, + {{TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00), + TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d)}, + {TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842), + TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6)}}, + {{TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5), + TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544)}, + {TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63), + TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854)}}, + {{TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601), + TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487)}, + {TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7), + TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f)}}, + {{TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a), + TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f)}, + {TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74), + TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091)}}, + {{TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9), + TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63)}, + {TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e), + TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44)}}, + {{TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de), + TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7)}, + {TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c), + TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28)}}, + {{TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1), + TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92)}, + {TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46), + TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93)}}, + {{TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2), + TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056)}, + {TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1), + TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660)}}, + {{TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45), + TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b)}, + {TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a), + TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac)}}, + {{TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8), + TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab)}, + {TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51), + TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca)}}, + {{TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed), + TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3)}, + {TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5), + TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9)}}, + {{TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94), + TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a)}, + {TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec), + TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491)}}, + {{TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5), + TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd)}, + {TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9), + TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e)}}, + {{TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0), + TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f)}, + {TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91), + TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb)}}, + {{TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28), + TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0)}, + {TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56), + TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49)}}, + {{TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729), + TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3)}, + {TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc), + TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8)}}, + {{TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef), + TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2)}, + {TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc), + TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc)}}, + {{TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d), + TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee)}, + {TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032), + TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812)}}, + {{TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491), + TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1)}, + {TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc), + TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c)}}, + {{TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007), + TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d)}, + {TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10), + TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940)}}, + {{TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b), + TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1)}, + {TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5), + TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d)}}, + {{TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe), + TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318)}, + {TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca), + TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a)}}, + {{TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569), + TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e)}, + {TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b), + TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d)}}, + {{TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78), + TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a)}, + {TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b), + TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4)}}, + {{TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926), + TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5)}, + {TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772), + TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab)}}, + {{TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7), + TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b)}, + {TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599), + TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6)}}, + {{TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9), + TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67)}, + {TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907), + TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad)}}, + {{TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51), + TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0)}, + {TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff), + TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b)}}, + {{TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1), + TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a)}, + {TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901), + TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e)}}, + {{TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c), + TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3)}, + {TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511), + TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d)}}, + {{TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2), + TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511)}, + {TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c), + TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e)}}, + {{TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb), + TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249)}, + {TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4), + TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53)}}, + {{TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583), + TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5)}, + {TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760), + TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1)}}, + {{TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d), + TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b)}, + {TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5), + TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188)}}, + {{TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79), + TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef)}, + {TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b), + TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7)}}, + {{TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e), + TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf)}, + {TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4), + TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341)}}, + {{TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff), + TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00)}, + {TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8), + TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571)}}, + {{TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697), + TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd)}, + {TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096), + TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7)}}, + {{TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13), + TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522)}, + {TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021), + TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff)}}, + {{TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc), + TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f)}, + {TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee), + TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605)}}, + {{TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28), + TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0)}, + {TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be), + TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246)}}, + {{TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93), + TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c)}, + {TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214), + TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04)}}, + {{TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326), + TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499)}, + {TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f), + TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434)}}, + {{TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c), + TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532)}, + {TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269), + TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f)}}, + {{TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554), + TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f)}, + {TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799), + TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12)}}, + {{TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152), + TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458)}, + {TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc), + TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89)}}}, + {{{TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e), + TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de)}, + {TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56), + TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154)}}, + {{TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078), + TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc)}, + {TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0), + TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9)}}, + {{TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259), + TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407)}, + {TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f), + TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9)}}, + {{TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240), + TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca)}, + {TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228), + TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59)}}, + {{TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88), + TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f)}, + {TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26), + TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf)}}, + {{TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382), + TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43)}, + {TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4), + TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0)}}, + {{TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633), + TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea)}, + {TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a), + TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab)}}, + {{TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27), + TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50)}, + {TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e), + TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf)}}, + {{TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c), + TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25)}, + {TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5), + TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b)}}, + {{TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe), + TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee)}, + {TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7), + TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276)}}, + {{TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a), + TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851)}, + {TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba), + TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66)}}, + {{TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c), + TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b)}, + {TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61), + TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e)}}, + {{TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4), + TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb)}, + {TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75), + TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe)}}, + {{TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80), + TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a)}, + {TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4), + TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a)}}, + {{TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee), + TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf)}, + {TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1), + TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1)}}, + {{TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a), + TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331)}, + {TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625), + TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61)}}, + {{TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4), + TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a)}, + {TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360), + TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b)}}, + {{TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f), + TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219)}, + {TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5), + TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181)}}, + {{TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8), + TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c)}, + {TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c), + TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b)}}, + {{TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7), + TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2)}, + {TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e), + TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8)}}, + {{TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782), + TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d)}, + {TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4), + TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4)}}, + {{TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402), + TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372)}, + {TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa), + TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73)}}, + {{TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167), + TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79)}, + {TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04), + TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a)}}, + {{TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd), + TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81)}, + {TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1), + TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87)}}, + {{TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb), + TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6)}, + {TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33), + TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9)}}, + {{TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55), + TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8)}, + {TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a), + TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39)}}, + {{TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e), + TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6)}, + {TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d), + TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb)}}, + {{TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8), + TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1)}, + {TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888), + TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c)}}, + {{TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41), + TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8)}, + {TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d), + TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab)}}, + {{TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3), + TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e)}, + {TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4), + TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764)}}, + {{TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce), + TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f)}, + {TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38), + TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936)}}, + {{TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93), + TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0)}, + {TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58), + TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a)}}, + {{TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe), + TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae)}, + {TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28), + TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11)}}, + {{TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7), + TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73)}, + {TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823), + TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346)}}, + {{TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256), + TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40)}, + {TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7), + TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec)}}, + {{TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5), + TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530)}, + {TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac), + TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f)}}, + {{TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63), + TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15)}, + {TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20), + TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30)}}, + {{TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba), + TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa)}, + {TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8), + TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6)}}, + {{TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa), + TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3)}, + {TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa), + TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c)}}, + {{TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e), + TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872)}, + {TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618), + TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514)}}, + {{TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79), + TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3)}, + {TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8), + TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0)}}, + {{TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc), + TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036)}, + {TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7), + TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec)}}, + {{TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911), + TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1)}, + {TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27), + TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe)}}, + {{TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d), + TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42)}, + {TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05), + TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33)}}, + {{TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0), + TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111)}, + {TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007), + TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de)}}, + {{TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6), + TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5)}, + {TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7), + TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160)}}, + {{TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32), + TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f)}, + {TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112), + TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6)}}, + {{TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54), + TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5)}, + {TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe), + TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400)}}, + {{TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed), + TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69)}, + {TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1), + TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29)}}, + {{TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771), + TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678)}, + {TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5), + TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c)}}, + {{TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b), + TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea)}, + {TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99), + TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55)}}, + {{TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15), + TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95)}, + {TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa), + TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da)}}, + {{TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce), + TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254)}, + {TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855), + TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc)}}, + {{TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762), + TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236)}, + {TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979), + TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64)}}, + {{TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309), + TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8)}, + {TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672), + TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff)}}, + {{TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4), + TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e)}, + {TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4), + TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa)}}, + {{TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328), + TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c)}, + {TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014), + TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf)}}, + {{TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f), + TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad)}, + {TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08), + TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199)}}, + {{TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b), + TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd)}, + {TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14), + TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158)}}, + {{TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1), + TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd)}, + {TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a), + TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2)}}, + {{TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150), + TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719)}, + {TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb), + TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3)}}, + {{TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b), + TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe)}, + {TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7), + TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec)}}, + {{TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646), + TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a)}, + {TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66), + TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de)}}, + {{TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24), + TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04)}, + {TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81), + TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca)}}}, + {{{TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728), + TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d)}, + {TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf), + TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2)}}, + {{TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413), + TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7)}, + {TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5), + TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089)}}, + {{TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b), + TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07)}, + {TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682), + TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6)}}, + {{TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33), + TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd)}, + {TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac), + TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c)}}, + {{TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0), + TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241)}, + {TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363), + TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3)}}, + {{TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168), + TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02)}, + {TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac), + TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d)}}, + {{TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc), + TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649)}, + {TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7), + TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef)}}, + {{TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae), + TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c)}, + {TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52), + TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558)}}, + {{TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c), + TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c)}, + {TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec), + TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4)}}, + {{TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259), + TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1)}, + {TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c), + TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c)}}, + {{TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4), + TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3)}, + {TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2), + TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a)}}, + {{TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184), + TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00)}, + {TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4), + TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828)}}, + {{TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d), + TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478)}, + {TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0), + TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8)}}, + {{TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541), + TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be)}, + {TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a), + TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216)}}, + {{TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86), + TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128)}, + {TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf), + TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2)}}, + {{TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a), + TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84)}, + {TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e), + TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0)}}, + {{TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6), + TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16)}, + {TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2), + TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849)}}, + {{TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14), + TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644)}, + {TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2), + TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5)}}, + {{TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550), + TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1)}, + {TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d), + TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8)}}, + {{TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13), + TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d)}, + {TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d), + TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af)}}, + {{TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88), + TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d)}, + {TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2), + TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984)}}, + {{TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca), + TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40)}, + {TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b), + TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239)}}, + {{TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8), + TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe)}, + {TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279), + TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae)}}, + {{TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8), + TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab)}, + {TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f), + TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e)}}, + {{TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc), + TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e)}, + {TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622), + TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2)}}, + {{TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161), + TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6)}, + {TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0), + TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34)}}, + {{TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb), + TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b)}, + {TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d), + TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567)}}, + {{TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6), + TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff)}, + {TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122), + TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942)}}, + {{TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69), + TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa)}, + {TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e), + TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326)}}, + {{TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70), + TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1)}, + {TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed), + TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331)}}, + {{TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a), + TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7)}, + {TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2), + TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993)}}, + {{TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5), + TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d)}, + {TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f), + TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887)}}, + {{TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5), + TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56)}, + {TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73), + TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a)}}, + {{TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036), + TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162)}, + {TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5), + TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5)}}, + {{TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b), + TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1)}, + {TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389), + TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde)}}, + {{TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac), + TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768)}, + {TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc), + TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279)}}, + {{TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca), + TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba)}, + {TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a), + TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb)}}, + {{TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500), + TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476)}, + {TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa), + TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c)}}, + {{TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28), + TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34)}, + {TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a), + TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e)}}, + {{TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae), + TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f)}, + {TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e), + TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf)}}, + {{TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0), + TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854)}, + {TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab), + TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f)}}, + {{TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03), + TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720)}, + {TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495), + TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef)}}, + {{TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef), + TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349)}, + {TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825), + TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a)}}, + {{TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3), + TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5)}, + {TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7), + TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c)}}, + {{TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792), + TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2)}, + {TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d), + TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9)}}, + {{TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad), + TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854)}, + {TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4), + TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70)}}, + {{TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997), + TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52)}, + {TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2), + TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2)}}, + {{TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232), + TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca)}, + {TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8), + TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72)}}, + {{TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905), + TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42)}, + {TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642), + TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b)}}, + {{TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c), + TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed)}, + {TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e), + TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd)}}, + {{TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693), + TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f)}, + {TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3), + TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130)}}, + {{TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895), + TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b)}, + {TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9), + TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5)}}, + {{TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45), + TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df)}, + {TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25), + TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1)}}, + {{TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5), + TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf)}, + {TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54), + TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384)}}, + {{TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75), + TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb)}, + {TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9), + TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844)}}, + {{TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66), + TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6)}, + {TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f), + TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a)}}, + {{TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511), + TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee)}, + {TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9), + TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff)}}, + {{TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3), + TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12)}, + {TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16), + TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36)}}, + {{TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f), + TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429)}, + {TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c), + TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2)}}, + {{TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f), + TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843)}, + {TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622), + TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37)}}, + {{TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f), + TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f)}, + {TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a), + TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7)}}, + {{TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335), + TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9)}, + {TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0), + TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49)}}, + {{TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244), + TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd)}, + {TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6), + TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978)}}, + {{TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7), + TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4)}, + {TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac), + TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63)}}}, + {{{TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046), + TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d)}, + {TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa), + TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746)}}, + {{TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e), + TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19)}, + {TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2), + TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d)}}, + {{TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427), + TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77)}, + {TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9), + TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0)}}, + {{TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8), + TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0)}, + {TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05), + TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1)}}, + {{TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62), + TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99)}, + {TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61), + TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1)}}, + {{TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5), + TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685)}, + {TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771), + TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81)}}, + {{TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898), + TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11)}, + {TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4), + TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b)}}, + {{TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e), + TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26)}, + {TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f), + TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab)}}, + {{TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603), + TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77)}, + {TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2), + TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980)}}, + {{TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee), + TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326)}, + {TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6), + TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5)}}, + {{TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e), + TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9)}, + {TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591), + TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d)}}, + {{TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb), + TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac)}, + {TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e), + TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b)}}, + {{TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc), + TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3)}, + {TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c), + TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8)}}, + {{TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174), + TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081)}, + {TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2), + TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53)}}, + {{TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be), + TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf)}, + {TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6), + TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464)}}, + {{TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63), + TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d)}, + {TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c), + TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f)}}, + {{TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a), + TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222)}, + {TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea), + TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac)}}, + {{TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886), + TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8)}, + {TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e), + TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a)}}, + {{TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5), + TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800)}, + {TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494), + TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203)}}, + {{TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375), + TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d)}, + {TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b), + TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3)}}, + {{TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb), + TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b)}, + {TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac), + TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739)}}, + {{TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f), + TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee)}, + {TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7), + TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a)}}, + {{TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814), + TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5)}, + {TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe), + TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885)}}, + {{TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6), + TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8)}, + {TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70), + TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef)}}, + {{TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96), + TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d)}, + {TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e), + TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61)}}, + {{TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976), + TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe)}, + {TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d), + TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5)}}, + {{TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a), + TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447)}, + {TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2), + TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c)}}, + {{TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746), + TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4)}, + {TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985), + TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e)}}, + {{TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9), + TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef)}, + {TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6), + TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4)}}, + {{TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda), + TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960)}, + {TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7), + TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327)}}, + {{TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1), + TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc)}, + {TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e), + TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07)}}, + {{TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e), + TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0)}, + {TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8), + TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b)}}, + {{TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e), + TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33)}, + {TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa), + TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b)}}, + {{TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690), + TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7)}, + {TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc), + TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9)}}, + {{TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059), + TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b)}, + {TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1), + TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b)}}, + {{TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56), + TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed)}, + {TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af), + TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a)}}, + {{TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a), + TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd)}, + {TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e), + TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4)}}, + {{TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248), + TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382)}, + {TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9), + TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f)}}, + {{TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d), + TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9)}, + {TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506), + TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce)}}, + {{TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91), + TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8)}, + {TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4), + TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b)}}, + {{TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be), + TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41)}, + {TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a), + TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35)}}, + {{TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478), + TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8)}, + {TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0), + TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832)}}, + {{TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b), + TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047)}, + {TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423), + TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac)}}, + {{TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb), + TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734)}, + {TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493), + TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf)}}, + {{TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7), + TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f)}, + {TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc), + TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47)}}, + {{TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea), + TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62)}, + {TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993), + TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8)}}, + {{TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab), + TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2)}, + {TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d), + TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f)}}, + {{TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c), + TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067)}, + {TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097), + TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e)}}, + {{TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0), + TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162)}, + {TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042), + TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5)}}, + {{TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c), + TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0)}, + {TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2), + TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711)}}, + {{TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d), + TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a)}, + {TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d), + TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548)}}, + {{TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba), + TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827)}, + {TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a), + TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1)}}, + {{TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4), + TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195)}, + {TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65), + TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07)}}, + {{TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b), + TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1)}, + {TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4), + TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea)}}, + {{TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7), + TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22)}, + {TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60), + TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c)}}, + {{TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21), + TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676)}, + {TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b), + TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee)}}, + {{TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1), + TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98)}, + {TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb), + TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06)}}, + {{TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9), + TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f)}, + {TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1), + TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6)}}, + {{TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3), + TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635)}, + {TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120), + TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3)}}, + {{TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520), + TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf)}, + {TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a), + TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848)}}, + {{TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6), + TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc)}, + {TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc), + TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6)}}, + {{TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae), + TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d)}, + {TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317), + TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a)}}, + {{TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee), + TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7)}, + {TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b), + TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8)}}, + {{TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e), + TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792)}, + {TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5), + TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4)}}}, + {{{TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603), + TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129)}, + {TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c), + TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca)}}, + {{TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e), + TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8)}, + {TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8), + TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038)}}, + {{TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a), + TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109)}, + {TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43), + TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3)}}, + {{TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc), + TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4)}, + {TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3), + TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97)}}, + {{TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9), + TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb)}, + {TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b), + TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e)}}, + {{TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07), + TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270)}, + {TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b), + TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f)}}, + {{TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb), + TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997)}, + {TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a), + TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5)}}, + {{TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb), + TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a)}, + {TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586), + TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018)}}, + {{TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b), + TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739)}, + {TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962), + TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b)}}, + {{TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257), + TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8)}, + {TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f), + TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa)}}, + {{TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467), + TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665)}, + {TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a), + TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f)}}, + {{TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a), + TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8)}, + {TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3), + TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00)}}, + {{TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b), + TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52)}, + {TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f), + TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975)}}, + {{TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc), + TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323)}, + {TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9), + TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35)}}, + {{TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1), + TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d)}, + {TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb), + TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c)}}, + {{TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266), + TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf)}, + {TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf), + TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd)}}, + {{TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1), + TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110)}, + {TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3), + TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28)}}, + {{TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531), + TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8)}, + {TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a), + TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83)}}, + {{TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a), + TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d)}, + {TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783), + TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4)}}, + {{TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203), + TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc)}, + {TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a), + TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7)}}, + {{TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287), + TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c)}, + {TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70), + TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c)}}, + {{TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8), + TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4)}, + {TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f), + TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9)}}, + {{TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366), + TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b)}, + {TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01), + TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd)}}, + {{TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da), + TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e)}, + {TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465), + TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5)}}, + {{TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1), + TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c)}, + {TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217), + TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955)}}, + {{TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124), + TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775)}, + {TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a), + TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29)}}, + {{TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800), + TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194)}, + {TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6), + TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c)}}, + {{TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26), + TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724)}, + {TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026), + TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114)}}, + {{TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0), + TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262)}, + {TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b), + TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd)}}, + {{TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26), + TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f)}, + {TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909), + TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc)}}, + {{TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078), + TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b)}, + {TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406), + TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f)}}, + {{TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8), + TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b)}, + {TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22), + TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af)}}, + {{TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859), + TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a)}, + {TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819), + TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d)}}, + {{TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313), + TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408)}, + {TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed), + TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69)}}, + {{TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f), + TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00)}, + {TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7), + TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f)}}, + {{TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534), + TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78)}, + {TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125), + TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7)}}, + {{TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08), + TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd)}, + {TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b), + TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f)}}, + {{TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235), + TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28)}, + {TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2), + TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed)}}, + {{TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45), + TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744)}, + {TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a), + TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c)}}, + {{TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd), + TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312)}, + {TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830), + TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5)}}, + {{TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345), + TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462)}, + {TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe), + TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79)}}, + {{TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f), + TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a)}, + {TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c), + TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d)}}, + {{TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889), + TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f)}, + {TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182), + TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736)}}, + {{TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65), + TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747)}, + {TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68), + TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb)}}, + {{TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497), + TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d)}, + {TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416), + TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272)}}, + {{TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db), + TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57)}, + {TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104), + TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc)}}, + {{TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6), + TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0)}, + {TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e), + TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2)}}, + {{TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e), + TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e)}, + {TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04), + TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614)}}, + {{TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09), + TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b)}, + {TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f), + TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd)}}, + {{TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e), + TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd)}, + {TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6), + TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0)}}, + {{TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623), + TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01)}, + {TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92), + TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804)}}, + {{TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a), + TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d)}, + {TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe), + TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a)}}, + {{TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4), + TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e)}, + {TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4), + TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489)}}, + {{TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5), + TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62)}, + {TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643), + TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e)}}, + {{TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a), + TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3)}, + {TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398), + TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7)}}, + {{TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74), + TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799)}, + {TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d), + TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280)}}, + {{TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28), + TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c)}, + {TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b), + TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c)}}, + {{TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0), + TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae)}, + {TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10), + TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e)}}, + {{TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae), + TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e)}, + {TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15), + TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8)}}, + {{TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c), + TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2)}, + {TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b), + TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1)}}, + {{TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb), + TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670)}, + {TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef), + TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb)}}, + {{TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49), + TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a)}, + {TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e), + TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa)}}, + {{TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335), + TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632)}, + {TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660), + TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c)}}, + {{TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99), + TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4)}, + {TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e), + TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}}}}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c new file mode 100644 index 00000000..b17ef3b1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c @@ -0,0 +1,635 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" +#include "p256-nistz.h" + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) + +typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; + +// One converted into the Montgomery domain +static const BN_ULONG ONE[P256_LIMBS] = { + TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000), + TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe), +}; + +// Precomputed tables for the default generator +#include "p256-nistz-table.h" + +// Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in +// util.c for details +static crypto_word_t booth_recode_w5(crypto_word_t in) { + crypto_word_t s, d; + + s = ~((in >> 5) - 1); + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +static crypto_word_t booth_recode_w7(crypto_word_t in) { + crypto_word_t s, d; + + s = ~((in >> 7) - 1); + d = (1 << 8) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +// copy_conditional copies |src| to |dst| if |move| is one and leaves it as-is +// if |move| is zero. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +static void copy_conditional(BN_ULONG dst[P256_LIMBS], + const BN_ULONG src[P256_LIMBS], BN_ULONG move) { + BN_ULONG mask1 = ((BN_ULONG)0) - move; + BN_ULONG mask2 = ~mask1; + + dst[0] = (src[0] & mask1) ^ (dst[0] & mask2); + dst[1] = (src[1] & mask1) ^ (dst[1] & mask2); + dst[2] = (src[2] & mask1) ^ (dst[2] & mask2); + dst[3] = (src[3] & mask1) ^ (dst[3] & mask2); + if (P256_LIMBS == 8) { + dst[4] = (src[4] & mask1) ^ (dst[4] & mask2); + dst[5] = (src[5] & mask1) ^ (dst[5] & mask2); + dst[6] = (src[6] & mask1) ^ (dst[6] & mask2); + dst[7] = (src[7] & mask1) ^ (dst[7] & mask2); + } +} + +// is_not_zero returns one iff in != 0 and zero otherwise. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +// +// (define-fun is_not_zero ((in (_ BitVec 64))) (_ BitVec 64) +// (bvlshr (bvor in (bvsub #x0000000000000000 in)) #x000000000000003f) +// ) +// +// (declare-fun x () (_ BitVec 64)) +// +// (assert (and (= x #x0000000000000000) (= (is_not_zero x) #x0000000000000001))) +// (check-sat) +// +// (assert (and (not (= x #x0000000000000000)) (= (is_not_zero x) #x0000000000000000))) +// (check-sat) +// +static BN_ULONG is_not_zero(BN_ULONG in) { + in |= (0 - in); + in >>= BN_BITS2 - 1; + return in; +} + +// ecp_nistz256_mod_inverse_sqr_mont sets |r| to (|in| * 2^-256)^-2 * 2^256 mod +// p. That is, |r| is the modular inverse square of |in| for input and output in +// the Montgomery domain. +static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + // This implements the addition chain described in + // https://briansmith.org/ecc-inversion-addition-chains-01#p256_field_inversion + BN_ULONG x2[P256_LIMBS], x3[P256_LIMBS], x6[P256_LIMBS], x12[P256_LIMBS], + x15[P256_LIMBS], x30[P256_LIMBS], x32[P256_LIMBS]; + ecp_nistz256_sqr_mont(x2, in); // 2^2 - 2^1 + ecp_nistz256_mul_mont(x2, x2, in); // 2^2 - 2^0 + + ecp_nistz256_sqr_mont(x3, x2); // 2^3 - 2^1 + ecp_nistz256_mul_mont(x3, x3, in); // 2^3 - 2^0 + + ecp_nistz256_sqr_mont(x6, x3); + for (int i = 1; i < 3; i++) { + ecp_nistz256_sqr_mont(x6, x6); + } // 2^6 - 2^3 + ecp_nistz256_mul_mont(x6, x6, x3); // 2^6 - 2^0 + + ecp_nistz256_sqr_mont(x12, x6); + for (int i = 1; i < 6; i++) { + ecp_nistz256_sqr_mont(x12, x12); + } // 2^12 - 2^6 + ecp_nistz256_mul_mont(x12, x12, x6); // 2^12 - 2^0 + + ecp_nistz256_sqr_mont(x15, x12); + for (int i = 1; i < 3; i++) { + ecp_nistz256_sqr_mont(x15, x15); + } // 2^15 - 2^3 + ecp_nistz256_mul_mont(x15, x15, x3); // 2^15 - 2^0 + + ecp_nistz256_sqr_mont(x30, x15); + for (int i = 1; i < 15; i++) { + ecp_nistz256_sqr_mont(x30, x30); + } // 2^30 - 2^15 + ecp_nistz256_mul_mont(x30, x30, x15); // 2^30 - 2^0 + + ecp_nistz256_sqr_mont(x32, x30); + ecp_nistz256_sqr_mont(x32, x32); // 2^32 - 2^2 + ecp_nistz256_mul_mont(x32, x32, x2); // 2^32 - 2^0 + + BN_ULONG ret[P256_LIMBS]; + ecp_nistz256_sqr_mont(ret, x32); + for (int i = 1; i < 31 + 1; i++) { + ecp_nistz256_sqr_mont(ret, ret); + } // 2^64 - 2^32 + ecp_nistz256_mul_mont(ret, ret, in); // 2^64 - 2^32 + 2^0 + + for (int i = 0; i < 96 + 32; i++) { + ecp_nistz256_sqr_mont(ret, ret); + } // 2^192 - 2^160 + 2^128 + ecp_nistz256_mul_mont(ret, ret, x32); // 2^192 - 2^160 + 2^128 + 2^32 - 2^0 + + for (int i = 0; i < 32; i++) { + ecp_nistz256_sqr_mont(ret, ret); + } // 2^224 - 2^192 + 2^160 + 2^64 - 2^32 + ecp_nistz256_mul_mont(ret, ret, x32); // 2^224 - 2^192 + 2^160 + 2^64 - 2^0 + + for (int i = 0; i < 30; i++) { + ecp_nistz256_sqr_mont(ret, ret); + } // 2^254 - 2^222 + 2^190 + 2^94 - 2^30 + ecp_nistz256_mul_mont(ret, ret, x30); // 2^254 - 2^222 + 2^190 + 2^94 - 2^0 + + ecp_nistz256_sqr_mont(ret, ret); + ecp_nistz256_sqr_mont(r, ret); // 2^256 - 2^224 + 2^192 + 2^96 - 2^2 +} + +// r = p * p_scalar +static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, + const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar) { + assert(p != NULL); + assert(p_scalar != NULL); + assert(group->field.width == P256_LIMBS); + + static const size_t kWindowSize = 5; + static const crypto_word_t kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; + + // A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should + // add no more than 63 bytes of overhead. Thus, |table| should require + // ~1599 ((96 * 16) + 63) bytes of stack space. + alignas(64) P256_POINT table[16]; + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, p_scalar->bytes, 32); + p_str[32] = 0; + + // table[0] is implicitly (0,0,0) (the point at infinity), therefore it is + // not stored. All other values are actually stored with an offset of -1 in + // table. + P256_POINT *row = table; + assert(group->field.width == P256_LIMBS); + OPENSSL_memcpy(row[1 - 1].X, p->X.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(row[1 - 1].Y, p->Y.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(row[1 - 1].Z, p->Z.words, P256_LIMBS * sizeof(BN_ULONG)); + + ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]); + ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]); + ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]); + ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]); + ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]); + ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]); + ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[16 - 1], &row[8 - 1]); + + BN_ULONG tmp[P256_LIMBS]; + alignas(32) P256_POINT h; + size_t index = 255; + crypto_word_t wvalue = p_str[(index - 1) / 8]; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1); + + while (index >= 5) { + if (index != 255) { + size_t off = (index - 1) / 8; + + wvalue = (crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, (wvalue & 1)); + + ecp_nistz256_point_add(r, r, &h); + } + + index -= kWindowSize; + + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + } + + // Final window + wvalue = p_str[0]; + wvalue = (wvalue << 1) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, wvalue & 1); + + ecp_nistz256_point_add(r, r, &h); +} + +typedef union { + P256_POINT p; + P256_POINT_AFFINE a; +} p256_point_union_t; + +static crypto_word_t calc_first_wvalue(size_t *index, const uint8_t p_str[33]) { + static const size_t kWindowSize = 7; + static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; + *index = kWindowSize; + + crypto_word_t wvalue = (p_str[0] << 1) & kMask; + return booth_recode_w7(wvalue); +} + +static crypto_word_t calc_wvalue(size_t *index, const uint8_t p_str[33]) { + static const size_t kWindowSize = 7; + static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; + + const size_t off = (*index - 1) / 8; + crypto_word_t wvalue = + (crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8; + wvalue = (wvalue >> ((*index - 1) % 8)) & kMask; + *index += kWindowSize; + + return booth_recode_w7(wvalue); +} + +static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, + const EC_SCALAR *scalar) { + alignas(32) P256_POINT out; + ecp_nistz256_windowed_mul(group, &out, p, scalar); + + assert(group->field.width == P256_LIMBS); + OPENSSL_memcpy(r->X.words, out.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, out.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, out.Z, P256_LIMBS * sizeof(BN_ULONG)); +} + +static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar) { + alignas(32) p256_point_union_t t, p; + + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, scalar->bytes, 32); + p_str[32] = 0; + + // First window + size_t index = 0; + crypto_word_t wvalue = calc_first_wvalue(&index, p_str); + + ecp_nistz256_select_w7(&p.a, ecp_nistz256_precomputed[0], wvalue >> 1); + ecp_nistz256_neg(p.p.Z, p.p.Y); + copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + + // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p| + // is infinity and |ONE| otherwise. |p| was computed from the table, so it + // is infinity iff |wvalue >> 1| is zero. + OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); + copy_conditional(p.p.Z, ONE, is_not_zero(wvalue >> 1)); + + for (int i = 1; i < 37; i++) { + wvalue = calc_wvalue(&index, p_str); + + ecp_nistz256_select_w7(&t.a, ecp_nistz256_precomputed[i], wvalue >> 1); + + ecp_nistz256_neg(t.p.Z, t.a.Y); + copy_conditional(t.a.Y, t.p.Z, wvalue & 1); + + // Note |ecp_nistz256_point_add_affine| does not work if |p.p| and |t.a| + // are the same non-infinity point. + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + } + + assert(group->field.width == P256_LIMBS); + OPENSSL_memcpy(r->X.words, p.p.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, p.p.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, p.p.Z, P256_LIMBS * sizeof(BN_ULONG)); +} + +static void ecp_nistz256_points_mul_public(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *p_, + const EC_SCALAR *p_scalar) { + assert(p_ != NULL && p_scalar != NULL && g_scalar != NULL); + + alignas(32) p256_point_union_t t, p; + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, g_scalar->bytes, 32); + p_str[32] = 0; + + // First window + size_t index = 0; + size_t wvalue = calc_first_wvalue(&index, p_str); + + // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p| + // is infinity and |ONE| otherwise. |p| was computed from the table, so it + // is infinity iff |wvalue >> 1| is zero. + if ((wvalue >> 1) != 0) { + OPENSSL_memcpy(&p.a, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1], + sizeof(p.a)); + OPENSSL_memcpy(&p.p.Z, ONE, sizeof(p.p.Z)); + } else { + OPENSSL_memset(&p.a, 0, sizeof(p.a)); + OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); + } + + if ((wvalue & 1) == 1) { + ecp_nistz256_neg(p.p.Y, p.p.Y); + } + + for (int i = 1; i < 37; i++) { + wvalue = calc_wvalue(&index, p_str); + + if ((wvalue >> 1) == 0) { + continue; + } + + OPENSSL_memcpy(&t.a, &ecp_nistz256_precomputed[i][(wvalue >> 1) - 1], + sizeof(p.a)); + + if ((wvalue & 1) == 1) { + ecp_nistz256_neg(t.a.Y, t.a.Y); + } + + // Note |ecp_nistz256_point_add_affine| does not work if |p.p| and |t.a| + // are the same non-infinity point, so it is important that we compute the + // |g_scalar| term before the |p_scalar| term. + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + } + + ecp_nistz256_windowed_mul(group, &t.p, p_, p_scalar); + ecp_nistz256_point_add(&p.p, &p.p, &t.p); + + assert(group->field.width == P256_LIMBS); + OPENSSL_memcpy(r->X.words, p.p.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, p.p.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, p.p.Z, P256_LIMBS * sizeof(BN_ULONG)); +} + +static int ecp_nistz256_get_affine(const EC_GROUP *group, + const EC_RAW_POINT *point, EC_FELEM *x, + EC_FELEM *y) { + if (ec_GFp_simple_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + BN_ULONG z_inv2[P256_LIMBS]; + assert(group->field.width == P256_LIMBS); + ecp_nistz256_mod_inverse_sqr_mont(z_inv2, point->Z.words); + + if (x != NULL) { + ecp_nistz256_mul_mont(x->words, z_inv2, point->X.words); + } + + if (y != NULL) { + ecp_nistz256_sqr_mont(z_inv2, z_inv2); // z^-4 + ecp_nistz256_mul_mont(y->words, point->Y.words, point->Z.words); // y * z + ecp_nistz256_mul_mont(y->words, y->words, z_inv2); // y * z^-3 + } + + return 1; +} + +static void ecp_nistz256_add(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a_, const EC_RAW_POINT *b_) { + P256_POINT a, b; + OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(a.Z, a_->Z.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(b.X, b_->X.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(b.Y, b_->Y.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(b.Z, b_->Z.words, P256_LIMBS * sizeof(BN_ULONG)); + ecp_nistz256_point_add(&a, &a, &b); + OPENSSL_memcpy(r->X.words, a.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, a.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, a.Z, P256_LIMBS * sizeof(BN_ULONG)); +} + +static void ecp_nistz256_dbl(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a_) { + P256_POINT a; + OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(a.Z, a_->Z.words, P256_LIMBS * sizeof(BN_ULONG)); + ecp_nistz256_point_double(&a, &a); + OPENSSL_memcpy(r->X.words, a.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, a.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, a.Z, P256_LIMBS * sizeof(BN_ULONG)); +} + +static void ecp_nistz256_inv0_mod_ord(const EC_GROUP *group, EC_SCALAR *out, + const EC_SCALAR *in) { + // table[i] stores a power of |in| corresponding to the matching enum value. + enum { + // The following indices specify the power in binary. + i_1 = 0, + i_10, + i_11, + i_101, + i_111, + i_1010, + i_1111, + i_10101, + i_101010, + i_101111, + // The following indices specify 2^N-1, or N ones in a row. + i_x6, + i_x8, + i_x16, + i_x32 + }; + BN_ULONG table[15][P256_LIMBS]; + + // https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion + // + // Even though this code path spares 12 squarings, 4.5%, and 13 + // multiplications, 25%, the overall sign operation is not that much faster, + // not more that 2%. Most of the performance of this function comes from the + // scalar operations. + + // Pre-calculate powers. + OPENSSL_memcpy(table[i_1], in->words, P256_LIMBS * sizeof(BN_ULONG)); + + ecp_nistz256_ord_sqr_mont(table[i_10], table[i_1], 1); + + ecp_nistz256_ord_mul_mont(table[i_11], table[i_1], table[i_10]); + + ecp_nistz256_ord_mul_mont(table[i_101], table[i_11], table[i_10]); + + ecp_nistz256_ord_mul_mont(table[i_111], table[i_101], table[i_10]); + + ecp_nistz256_ord_sqr_mont(table[i_1010], table[i_101], 1); + + ecp_nistz256_ord_mul_mont(table[i_1111], table[i_1010], table[i_101]); + + ecp_nistz256_ord_sqr_mont(table[i_10101], table[i_1010], 1); + ecp_nistz256_ord_mul_mont(table[i_10101], table[i_10101], table[i_1]); + + ecp_nistz256_ord_sqr_mont(table[i_101010], table[i_10101], 1); + + ecp_nistz256_ord_mul_mont(table[i_101111], table[i_101010], table[i_101]); + + ecp_nistz256_ord_mul_mont(table[i_x6], table[i_101010], table[i_10101]); + + ecp_nistz256_ord_sqr_mont(table[i_x8], table[i_x6], 2); + ecp_nistz256_ord_mul_mont(table[i_x8], table[i_x8], table[i_11]); + + ecp_nistz256_ord_sqr_mont(table[i_x16], table[i_x8], 8); + ecp_nistz256_ord_mul_mont(table[i_x16], table[i_x16], table[i_x8]); + + ecp_nistz256_ord_sqr_mont(table[i_x32], table[i_x16], 16); + ecp_nistz256_ord_mul_mont(table[i_x32], table[i_x32], table[i_x16]); + + // Compute |in| raised to the order-2. + ecp_nistz256_ord_sqr_mont(out->words, table[i_x32], 64); + ecp_nistz256_ord_mul_mont(out->words, out->words, table[i_x32]); + static const struct { + uint8_t p, i; + } kChain[27] = {{32, i_x32}, {6, i_101111}, {5, i_111}, {4, i_11}, + {5, i_1111}, {5, i_10101}, {4, i_101}, {3, i_101}, + {3, i_101}, {5, i_111}, {9, i_101111}, {6, i_1111}, + {2, i_1}, {5, i_1}, {6, i_1111}, {5, i_111}, + {4, i_111}, {5, i_111}, {5, i_101}, {3, i_11}, + {10, i_101111}, {2, i_11}, {5, i_11}, {5, i_11}, + {3, i_1}, {7, i_10101}, {6, i_1111}}; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kChain); i++) { + ecp_nistz256_ord_sqr_mont(out->words, out->words, kChain[i].p); + ecp_nistz256_ord_mul_mont(out->words, out->words, table[kChain[i].i]); + } +} + +static int ecp_nistz256_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, + EC_SCALAR *out, + const EC_SCALAR *in) { +#if defined(OPENSSL_X86_64) + if (!CRYPTO_is_AVX_capable()) { + // No AVX support; fallback to generic code. + return ec_simple_scalar_to_montgomery_inv_vartime(group, out, in); + } +#endif + + assert(group->order.width == P256_LIMBS); + if (!beeu_mod_inverse_vartime(out->words, in->words, group->order.d)) { + return 0; + } + + // The result should be returned in the Montgomery domain. + ec_scalar_to_montgomery(group, out, out); + return 1; +} + +static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group, + const EC_RAW_POINT *p, + const EC_SCALAR *r) { + if (ec_GFp_simple_is_at_infinity(group, p)) { + return 0; + } + + assert(group->order.width == P256_LIMBS); + assert(group->field.width == P256_LIMBS); + + // We wish to compare X/Z^2 with r. This is equivalent to comparing X with + // r*Z^2. Note that X and Z are represented in Montgomery form, while r is + // not. + BN_ULONG r_Z2[P256_LIMBS], Z2_mont[P256_LIMBS], X[P256_LIMBS]; + ecp_nistz256_mul_mont(Z2_mont, p->Z.words, p->Z.words); + ecp_nistz256_mul_mont(r_Z2, r->words, Z2_mont); + ecp_nistz256_from_mont(X, p->X.words); + + if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) { + return 1; + } + + // During signing the x coefficient is reduced modulo the group order. + // Therefore there is a small possibility, less than 1/2^128, that group_order + // < p.x < P. in that case we need not only to compare against |r| but also to + // compare against r+group_order. + if (bn_less_than_words(r->words, group->field_minus_order.words, + P256_LIMBS)) { + // We can ignore the carry because: r + group_order < p < 2^256. + bn_add_words(r_Z2, r->words, group->order.d, P256_LIMBS); + ecp_nistz256_mul_mont(r_Z2, r_Z2, Z2_mont); + if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) { + return 1; + } + } + + return 0; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ecp_nistz256_get_affine; + out->add = ecp_nistz256_add; + out->dbl = ecp_nistz256_dbl; + out->mul = ecp_nistz256_point_mul; + out->mul_base = ecp_nistz256_point_mul_base; + out->mul_public = ecp_nistz256_points_mul_public; + out->felem_mul = ec_GFp_mont_felem_mul; + out->felem_sqr = ec_GFp_mont_felem_sqr; + out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; + out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->scalar_inv0_montgomery = ecp_nistz256_inv0_mod_ord; + out->scalar_to_montgomery_inv_vartime = + ecp_nistz256_scalar_to_montgomery_inv_vartime; + out->cmp_x_coordinate = ecp_nistz256_cmp_x_coordinate; +} + +#endif /* !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.h new file mode 100644 index 00000000..3ca41151 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.h @@ -0,0 +1,155 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#ifndef OPENSSL_HEADER_EC_P256_X86_64_H +#define OPENSSL_HEADER_EC_P256_X86_64_H + +#include + +#include + +#include "../bn/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) + +// P-256 field operations. +// +// An element mod P in P-256 is represented as a little-endian array of +// |P256_LIMBS| |BN_ULONG|s, spanning the full range of values. +// +// The following functions take fully-reduced inputs mod P and give +// fully-reduced outputs. They may be used in-place. + +#define P256_LIMBS (256 / BN_BITS2) + +// ecp_nistz256_neg sets |res| to -|a| mod P. +void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P. +void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); + +// ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P. +void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_from_mont sets |res| to |in|, converted from Montgomery domain +// by multiplying with 1. +static inline void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + static const BN_ULONG ONE[P256_LIMBS] = { 1 }; + ecp_nistz256_mul_mont(res, in, ONE); +} + +// ecp_nistz256_to_mont sets |res| to |in|, converted to Montgomery domain +// by multiplying with RR = 2^512 mod P precomputed for NIST P256 curve. +static inline void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + static const BN_ULONG RR[P256_LIMBS] = { + TOBN(0x00000000, 0x00000003), TOBN(0xfffffffb, 0xffffffff), + TOBN(0xffffffff, 0xfffffffe), TOBN(0x00000004, 0xfffffffd)}; + ecp_nistz256_mul_mont(res, in, RR); +} + + +// P-256 scalar operations. +// +// The following functions compute modulo N, where N is the order of P-256. They +// take fully-reduced inputs and give fully-reduced outputs. + +// ecp_nistz256_ord_mul_mont sets |res| to |a| * |b| where inputs and outputs +// are in Montgomery form. That is, |res| is |a| * |b| * 2^-256 mod N. +void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); + +// ecp_nistz256_ord_sqr_mont sets |res| to |a|^(2*|rep|) where inputs and +// outputs are in Montgomery form. That is, |res| is +// (|a| * 2^-256)^(2*|rep|) * 2^256 mod N. +void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], BN_ULONG rep); + +// beeu_mod_inverse_vartime sets out = a^-1 mod p using a Euclidean algorithm. +// Assumption: 0 < a < p < 2^(256) and p is odd. +int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG p[P256_LIMBS]); + + +// P-256 point operations. +// +// The following functions may be used in-place. All coordinates are in the +// Montgomery domain. + +// A P256_POINT represents a P-256 point in Jacobian coordinates. +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; + BN_ULONG Z[P256_LIMBS]; +} P256_POINT; + +// A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity +// is encoded as (0, 0). +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; +} P256_POINT_AFFINE; + +// ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16], + int index); + +// ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w7(P256_POINT_AFFINE *val, + const P256_POINT_AFFINE in_t[64], int index); + +// ecp_nistz256_point_double sets |r| to |a| doubled. +void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a); + +// ecp_nistz256_point_add adds |a| to |b| and places the result in |r|. +void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, + const P256_POINT *b); + +// ecp_nistz256_point_add_affine adds |a| to |b| and places the result in +// |r|. |a| and |b| must not represent the same point unless they are both +// infinity. +void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a, + const P256_POINT_AFFINE *b); + +#endif /* !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) */ + + +#if defined(__cplusplus) +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_EC_P256_X86_64_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c new file mode 100644 index 00000000..cbff3097 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c @@ -0,0 +1,742 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// An implementation of the NIST P-256 elliptic curve point multiplication. +// 256-bit Montgomery form for 64 and 32-bit. Field operations are generated by +// Fiat, which lives in //third_party/fiat. + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "../../internal.h" +#include "../delocate.h" +#include "./internal.h" + +#if defined(OPENSSL_NO_ASM) +#define FIAT_P256_NO_ASM +#endif + +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_NISTP256_64BIT 1 +#include "../../../third_party/fiat/p256_64.h" +#else +#include "../../../third_party/fiat/p256_32.h" +#endif + + +// utility functions, handwritten + +#if defined(BORINGSSL_NISTP256_64BIT) +#define FIAT_P256_NLIMBS 4 +typedef uint64_t fiat_p256_limb_t; +typedef uint64_t fiat_p256_felem[FIAT_P256_NLIMBS]; +static const fiat_p256_felem fiat_p256_one = {0x1, 0xffffffff00000000, + 0xffffffffffffffff, 0xfffffffe}; +#else // 64BIT; else 32BIT +#define FIAT_P256_NLIMBS 8 +typedef uint32_t fiat_p256_limb_t; +typedef uint32_t fiat_p256_felem[FIAT_P256_NLIMBS]; +static const fiat_p256_felem fiat_p256_one = { + 0x1, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0x0}; +#endif // 64BIT + + +static fiat_p256_limb_t fiat_p256_nz( + const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { + fiat_p256_limb_t ret; + fiat_p256_nonzero(&ret, in1); + return ret; +} + +static void fiat_p256_copy(fiat_p256_limb_t out[FIAT_P256_NLIMBS], + const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { + for (size_t i = 0; i < FIAT_P256_NLIMBS; i++) { + out[i] = in1[i]; + } +} + +static void fiat_p256_cmovznz(fiat_p256_limb_t out[FIAT_P256_NLIMBS], + fiat_p256_limb_t t, + const fiat_p256_limb_t z[FIAT_P256_NLIMBS], + const fiat_p256_limb_t nz[FIAT_P256_NLIMBS]) { + fiat_p256_selectznz(out, !!t, z, nz); +} + +static void fiat_p256_from_generic(fiat_p256_felem out, const EC_FELEM *in) { + fiat_p256_from_bytes(out, in->bytes); +} + +static void fiat_p256_to_generic(EC_FELEM *out, const fiat_p256_felem in) { + // This works because 256 is a multiple of 64, so there are no excess bytes to + // zero when rounding up to |BN_ULONG|s. + OPENSSL_STATIC_ASSERT( + 256 / 8 == sizeof(BN_ULONG) * ((256 + BN_BITS2 - 1) / BN_BITS2), + "fiat_p256_to_bytes leaves bytes uninitialized"); + fiat_p256_to_bytes(out->bytes, in); +} + +// fiat_p256_inv_square calculates |out| = |in|^{-2} +// +// Based on Fermat's Little Theorem: +// a^p = a (mod p) +// a^{p-1} = 1 (mod p) +// a^{p-3} = a^{-2} (mod p) +static void fiat_p256_inv_square(fiat_p256_felem out, + const fiat_p256_felem in) { + // This implements the addition chain described in + // https://briansmith.org/ecc-inversion-addition-chains-01#p256_field_inversion + fiat_p256_felem x2, x3, x6, x12, x15, x30, x32; + fiat_p256_square(x2, in); // 2^2 - 2^1 + fiat_p256_mul(x2, x2, in); // 2^2 - 2^0 + + fiat_p256_square(x3, x2); // 2^3 - 2^1 + fiat_p256_mul(x3, x3, in); // 2^3 - 2^0 + + fiat_p256_square(x6, x3); + for (int i = 1; i < 3; i++) { + fiat_p256_square(x6, x6); + } // 2^6 - 2^3 + fiat_p256_mul(x6, x6, x3); // 2^6 - 2^0 + + fiat_p256_square(x12, x6); + for (int i = 1; i < 6; i++) { + fiat_p256_square(x12, x12); + } // 2^12 - 2^6 + fiat_p256_mul(x12, x12, x6); // 2^12 - 2^0 + + fiat_p256_square(x15, x12); + for (int i = 1; i < 3; i++) { + fiat_p256_square(x15, x15); + } // 2^15 - 2^3 + fiat_p256_mul(x15, x15, x3); // 2^15 - 2^0 + + fiat_p256_square(x30, x15); + for (int i = 1; i < 15; i++) { + fiat_p256_square(x30, x30); + } // 2^30 - 2^15 + fiat_p256_mul(x30, x30, x15); // 2^30 - 2^0 + + fiat_p256_square(x32, x30); + fiat_p256_square(x32, x32); // 2^32 - 2^2 + fiat_p256_mul(x32, x32, x2); // 2^32 - 2^0 + + fiat_p256_felem ret; + fiat_p256_square(ret, x32); + for (int i = 1; i < 31 + 1; i++) { + fiat_p256_square(ret, ret); + } // 2^64 - 2^32 + fiat_p256_mul(ret, ret, in); // 2^64 - 2^32 + 2^0 + + for (int i = 0; i < 96 + 32; i++) { + fiat_p256_square(ret, ret); + } // 2^192 - 2^160 + 2^128 + fiat_p256_mul(ret, ret, x32); // 2^192 - 2^160 + 2^128 + 2^32 - 2^0 + + for (int i = 0; i < 32; i++) { + fiat_p256_square(ret, ret); + } // 2^224 - 2^192 + 2^160 + 2^64 - 2^32 + fiat_p256_mul(ret, ret, x32); // 2^224 - 2^192 + 2^160 + 2^64 - 2^0 + + for (int i = 0; i < 30; i++) { + fiat_p256_square(ret, ret); + } // 2^254 - 2^222 + 2^190 + 2^94 - 2^30 + fiat_p256_mul(ret, ret, x30); // 2^254 - 2^222 + 2^190 + 2^94 - 2^0 + + fiat_p256_square(ret, ret); + fiat_p256_square(out, ret); // 2^256 - 2^224 + 2^192 + 2^96 - 2^2 +} + +// Group operations +// ---------------- +// +// Building on top of the field operations we have the operations on the +// elliptic curve group itself. Points on the curve are represented in Jacobian +// coordinates. +// +// Both operations were transcribed to Coq and proven to correspond to naive +// implementations using Affine coordinates, for all suitable fields. In the +// Coq proofs, issues of constant-time execution and memory layout (aliasing) +// conventions were not considered. Specification of affine coordinates: +// +// As a sanity check, a proof that these points form a commutative group: +// + +// fiat_p256_point_double calculates 2*(x_in, y_in, z_in) +// +// The method is taken from: +// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b +// +// Coq transcription and correctness proof: +// +// +// +// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. +// while x_out == y_in is not (maybe this works, but it's not tested). +static void fiat_p256_point_double(fiat_p256_felem x_out, fiat_p256_felem y_out, + fiat_p256_felem z_out, + const fiat_p256_felem x_in, + const fiat_p256_felem y_in, + const fiat_p256_felem z_in) { + fiat_p256_felem delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; + // delta = z^2 + fiat_p256_square(delta, z_in); + // gamma = y^2 + fiat_p256_square(gamma, y_in); + // beta = x*gamma + fiat_p256_mul(beta, x_in, gamma); + + // alpha = 3*(x-delta)*(x+delta) + fiat_p256_sub(ftmp, x_in, delta); + fiat_p256_add(ftmp2, x_in, delta); + + fiat_p256_add(tmptmp, ftmp2, ftmp2); + fiat_p256_add(ftmp2, ftmp2, tmptmp); + fiat_p256_mul(alpha, ftmp, ftmp2); + + // x' = alpha^2 - 8*beta + fiat_p256_square(x_out, alpha); + fiat_p256_add(fourbeta, beta, beta); + fiat_p256_add(fourbeta, fourbeta, fourbeta); + fiat_p256_add(tmptmp, fourbeta, fourbeta); + fiat_p256_sub(x_out, x_out, tmptmp); + + // z' = (y + z)^2 - gamma - delta + fiat_p256_add(delta, gamma, delta); + fiat_p256_add(ftmp, y_in, z_in); + fiat_p256_square(z_out, ftmp); + fiat_p256_sub(z_out, z_out, delta); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + fiat_p256_sub(y_out, fourbeta, x_out); + fiat_p256_add(gamma, gamma, gamma); + fiat_p256_square(gamma, gamma); + fiat_p256_mul(y_out, alpha, y_out); + fiat_p256_add(gamma, gamma, gamma); + fiat_p256_sub(y_out, y_out, gamma); +} + +// fiat_p256_point_add calculates (x1, y1, z1) + (x2, y2, z2) +// +// The method is taken from: +// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, +// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). +// +// Coq transcription and correctness proof: +// +// +// +// This function includes a branch for checking whether the two input points +// are equal, (while not equal to the point at infinity). This case never +// happens during single point multiplication, so there is no timing leak for +// ECDH or ECDSA signing. +static void fiat_p256_point_add(fiat_p256_felem x3, fiat_p256_felem y3, + fiat_p256_felem z3, const fiat_p256_felem x1, + const fiat_p256_felem y1, + const fiat_p256_felem z1, const int mixed, + const fiat_p256_felem x2, + const fiat_p256_felem y2, + const fiat_p256_felem z2) { + fiat_p256_felem x_out, y_out, z_out; + fiat_p256_limb_t z1nz = fiat_p256_nz(z1); + fiat_p256_limb_t z2nz = fiat_p256_nz(z2); + + // z1z1 = z1z1 = z1**2 + fiat_p256_felem z1z1; + fiat_p256_square(z1z1, z1); + + fiat_p256_felem u1, s1, two_z1z2; + if (!mixed) { + // z2z2 = z2**2 + fiat_p256_felem z2z2; + fiat_p256_square(z2z2, z2); + + // u1 = x1*z2z2 + fiat_p256_mul(u1, x1, z2z2); + + // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 + fiat_p256_add(two_z1z2, z1, z2); + fiat_p256_square(two_z1z2, two_z1z2); + fiat_p256_sub(two_z1z2, two_z1z2, z1z1); + fiat_p256_sub(two_z1z2, two_z1z2, z2z2); + + // s1 = y1 * z2**3 + fiat_p256_mul(s1, z2, z2z2); + fiat_p256_mul(s1, s1, y1); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later). + + // u1 = x1*z2z2 + fiat_p256_copy(u1, x1); + // two_z1z2 = 2z1z2 + fiat_p256_add(two_z1z2, z1, z1); + // s1 = y1 * z2**3 + fiat_p256_copy(s1, y1); + } + + // u2 = x2*z1z1 + fiat_p256_felem u2; + fiat_p256_mul(u2, x2, z1z1); + + // h = u2 - u1 + fiat_p256_felem h; + fiat_p256_sub(h, u2, u1); + + fiat_p256_limb_t xneq = fiat_p256_nz(h); + + // z_out = two_z1z2 * h + fiat_p256_mul(z_out, h, two_z1z2); + + // z1z1z1 = z1 * z1z1 + fiat_p256_felem z1z1z1; + fiat_p256_mul(z1z1z1, z1, z1z1); + + // s2 = y2 * z1**3 + fiat_p256_felem s2; + fiat_p256_mul(s2, y2, z1z1z1); + + // r = (s2 - s1)*2 + fiat_p256_felem r; + fiat_p256_sub(r, s2, s1); + fiat_p256_add(r, r, r); + + fiat_p256_limb_t yneq = fiat_p256_nz(r); + + fiat_p256_limb_t is_nontrivial_double = constant_time_is_zero_w(xneq | yneq) & + ~constant_time_is_zero_w(z1nz) & + ~constant_time_is_zero_w(z2nz); + if (is_nontrivial_double) { + fiat_p256_point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // I = (2h)**2 + fiat_p256_felem i; + fiat_p256_add(i, h, h); + fiat_p256_square(i, i); + + // J = h * I + fiat_p256_felem j; + fiat_p256_mul(j, h, i); + + // V = U1 * I + fiat_p256_felem v; + fiat_p256_mul(v, u1, i); + + // x_out = r**2 - J - 2V + fiat_p256_square(x_out, r); + fiat_p256_sub(x_out, x_out, j); + fiat_p256_sub(x_out, x_out, v); + fiat_p256_sub(x_out, x_out, v); + + // y_out = r(V-x_out) - 2 * s1 * J + fiat_p256_sub(y_out, v, x_out); + fiat_p256_mul(y_out, y_out, r); + fiat_p256_felem s1j; + fiat_p256_mul(s1j, s1, j); + fiat_p256_sub(y_out, y_out, s1j); + fiat_p256_sub(y_out, y_out, s1j); + + fiat_p256_cmovznz(x_out, z1nz, x2, x_out); + fiat_p256_cmovznz(x3, z2nz, x1, x_out); + fiat_p256_cmovznz(y_out, z1nz, y2, y_out); + fiat_p256_cmovznz(y3, z2nz, y1, y_out); + fiat_p256_cmovznz(z_out, z1nz, z2, z_out); + fiat_p256_cmovznz(z3, z2nz, z1, z_out); +} + +#include "./p256_table.h" + +// fiat_p256_select_point_affine selects the |idx-1|th point from a +// precomputation table and copies it to out. If |idx| is zero, the output is +// the point at infinity. +static void fiat_p256_select_point_affine( + const fiat_p256_limb_t idx, size_t size, + const fiat_p256_felem pre_comp[/*size*/][2], fiat_p256_felem out[3]) { + OPENSSL_memset(out, 0, sizeof(fiat_p256_felem) * 3); + for (size_t i = 0; i < size; i++) { + fiat_p256_limb_t mismatch = i ^ (idx - 1); + fiat_p256_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]); + fiat_p256_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]); + } + fiat_p256_cmovznz(out[2], idx, out[2], fiat_p256_one); +} + +// fiat_p256_select_point selects the |idx|th point from a precomputation table +// and copies it to out. +static void fiat_p256_select_point(const fiat_p256_limb_t idx, size_t size, + const fiat_p256_felem pre_comp[/*size*/][3], + fiat_p256_felem out[3]) { + OPENSSL_memset(out, 0, sizeof(fiat_p256_felem) * 3); + for (size_t i = 0; i < size; i++) { + fiat_p256_limb_t mismatch = i ^ idx; + fiat_p256_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]); + fiat_p256_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]); + fiat_p256_cmovznz(out[2], mismatch, pre_comp[i][2], out[2]); + } +} + +// fiat_p256_get_bit returns the |i|th bit in |in| +static crypto_word_t fiat_p256_get_bit(const uint8_t *in, int i) { + if (i < 0 || i >= 256) { + return 0; + } + return (in[i >> 3] >> (i & 7)) & 1; +} + +// OPENSSL EC_METHOD FUNCTIONS + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = +// (X/Z^2, Y/Z^3). +static int ec_GFp_nistp256_point_get_affine_coordinates( + const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x_out, + EC_FELEM *y_out) { + if (ec_GFp_simple_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + fiat_p256_felem z1, z2; + fiat_p256_from_generic(z1, &point->Z); + fiat_p256_inv_square(z2, z1); + + if (x_out != NULL) { + fiat_p256_felem x; + fiat_p256_from_generic(x, &point->X); + fiat_p256_mul(x, x, z2); + fiat_p256_to_generic(x_out, x); + } + + if (y_out != NULL) { + fiat_p256_felem y; + fiat_p256_from_generic(y, &point->Y); + fiat_p256_square(z2, z2); // z^-4 + fiat_p256_mul(y, y, z1); // y * z + fiat_p256_mul(y, y, z2); // y * z^-3 + fiat_p256_to_generic(y_out, y); + } + + return 1; +} + +static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a, const EC_RAW_POINT *b) { + fiat_p256_felem x1, y1, z1, x2, y2, z2; + fiat_p256_from_generic(x1, &a->X); + fiat_p256_from_generic(y1, &a->Y); + fiat_p256_from_generic(z1, &a->Z); + fiat_p256_from_generic(x2, &b->X); + fiat_p256_from_generic(y2, &b->Y); + fiat_p256_from_generic(z2, &b->Z); + fiat_p256_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, + z2); + fiat_p256_to_generic(&r->X, x1); + fiat_p256_to_generic(&r->Y, y1); + fiat_p256_to_generic(&r->Z, z1); +} + +static void ec_GFp_nistp256_dbl(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *a) { + fiat_p256_felem x, y, z; + fiat_p256_from_generic(x, &a->X); + fiat_p256_from_generic(y, &a->Y); + fiat_p256_from_generic(z, &a->Z); + fiat_p256_point_double(x, y, z, x, y, z); + fiat_p256_to_generic(&r->X, x); + fiat_p256_to_generic(&r->Y, y); + fiat_p256_to_generic(&r->Z, z); +} + +static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, + const EC_SCALAR *scalar) { + fiat_p256_felem p_pre_comp[17][3]; + OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); + // Precompute multiples. + fiat_p256_from_generic(p_pre_comp[1][0], &p->X); + fiat_p256_from_generic(p_pre_comp[1][1], &p->Y); + fiat_p256_from_generic(p_pre_comp[1][2], &p->Z); + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + fiat_p256_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2], + p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2], + 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][2]); + } else { + fiat_p256_point_double(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[j / 2][0], + p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]); + } + } + + // Set nq to the point at infinity. + fiat_p256_felem nq[3] = {{0}, {0}, {0}}, ftmp, tmp[3]; + + // Loop over |scalar| msb-to-lsb, incorporating |p_pre_comp| every 5th round. + int skip = 1; // Save two point operations in the first round. + for (size_t i = 255; i < 256; i--) { + // double + if (!skip) { + fiat_p256_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // do other additions every 5 doublings + if (i % 5 == 0) { + crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 4) << 5; + bits |= fiat_p256_get_bit(scalar->bytes, i + 3) << 4; + bits |= fiat_p256_get_bit(scalar->bytes, i + 2) << 3; + bits |= fiat_p256_get_bit(scalar->bytes, i + 1) << 2; + bits |= fiat_p256_get_bit(scalar->bytes, i) << 1; + bits |= fiat_p256_get_bit(scalar->bytes, i - 1); + crypto_word_t sign, digit; + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + // select the point to add or subtract, in constant time. + fiat_p256_select_point((fiat_p256_limb_t)digit, 17, + (const fiat_p256_felem(*)[3])p_pre_comp, tmp); + fiat_p256_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point. + fiat_p256_cmovznz(tmp[1], (fiat_p256_limb_t)sign, tmp[1], ftmp); + + if (!skip) { + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], + 0 /* mixed */, tmp[0], tmp[1], tmp[2]); + } else { + fiat_p256_copy(nq[0], tmp[0]); + fiat_p256_copy(nq[1], tmp[1]); + fiat_p256_copy(nq[2], tmp[2]); + skip = 0; + } + } + } + + fiat_p256_to_generic(&r->X, nq[0]); + fiat_p256_to_generic(&r->Y, nq[1]); + fiat_p256_to_generic(&r->Z, nq[2]); +} + +static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *scalar) { + // Set nq to the point at infinity. + fiat_p256_felem nq[3] = {{0}, {0}, {0}}, tmp[3]; + + int skip = 1; // Save two point operations in the first round. + for (size_t i = 31; i < 32; i--) { + if (!skip) { + fiat_p256_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // First, look 32 bits upwards. + crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 224) << 3; + bits |= fiat_p256_get_bit(scalar->bytes, i + 160) << 2; + bits |= fiat_p256_get_bit(scalar->bytes, i + 96) << 1; + bits |= fiat_p256_get_bit(scalar->bytes, i + 32); + // Select the point to add, in constant time. + fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, + fiat_p256_g_pre_comp[1], tmp); + + if (!skip) { + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], + 1 /* mixed */, tmp[0], tmp[1], tmp[2]); + } else { + fiat_p256_copy(nq[0], tmp[0]); + fiat_p256_copy(nq[1], tmp[1]); + fiat_p256_copy(nq[2], tmp[2]); + skip = 0; + } + + // Second, look at the current position. + bits = fiat_p256_get_bit(scalar->bytes, i + 192) << 3; + bits |= fiat_p256_get_bit(scalar->bytes, i + 128) << 2; + bits |= fiat_p256_get_bit(scalar->bytes, i + 64) << 1; + bits |= fiat_p256_get_bit(scalar->bytes, i); + // Select the point to add, in constant time. + fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, + fiat_p256_g_pre_comp[0], tmp); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } + + fiat_p256_to_generic(&r->X, nq[0]); + fiat_p256_to_generic(&r->Y, nq[1]); + fiat_p256_to_generic(&r->Z, nq[2]); +} + +static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, + EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *p, + const EC_SCALAR *p_scalar) { +#define P256_WSIZE_PUBLIC 4 + // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|. + fiat_p256_felem p_pre_comp[1 << (P256_WSIZE_PUBLIC - 1)][3]; + fiat_p256_from_generic(p_pre_comp[0][0], &p->X); + fiat_p256_from_generic(p_pre_comp[0][1], &p->Y); + fiat_p256_from_generic(p_pre_comp[0][2], &p->Z); + fiat_p256_felem p2[3]; + fiat_p256_point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], + p_pre_comp[0][1], p_pre_comp[0][2]); + for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) { + fiat_p256_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], + p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], + p_pre_comp[i - 1][2], 0 /* not mixed */, p2[0], p2[1], + p2[2]); + } + + // Set up the coefficients for |p_scalar|. + int8_t p_wNAF[257]; + ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC); + + // Set |ret| to the point at infinity. + int skip = 1; // Save some point operations. + fiat_p256_felem ret[3] = {{0}, {0}, {0}}; + for (int i = 256; i >= 0; i--) { + if (!skip) { + fiat_p256_point_double(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2]); + } + + // For the |g_scalar|, we use the precomputed table without the + // constant-time lookup. + if (i <= 31) { + // First, look 32 bits upwards. + crypto_word_t bits = fiat_p256_get_bit(g_scalar->bytes, i + 224) << 3; + bits |= fiat_p256_get_bit(g_scalar->bytes, i + 160) << 2; + bits |= fiat_p256_get_bit(g_scalar->bytes, i + 96) << 1; + bits |= fiat_p256_get_bit(g_scalar->bytes, i + 32); + if (bits != 0) { + size_t index = (size_t)(bits - 1); + fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], + 1 /* mixed */, fiat_p256_g_pre_comp[1][index][0], + fiat_p256_g_pre_comp[1][index][1], + fiat_p256_one); + skip = 0; + } + + // Second, look at the current position. + bits = fiat_p256_get_bit(g_scalar->bytes, i + 192) << 3; + bits |= fiat_p256_get_bit(g_scalar->bytes, i + 128) << 2; + bits |= fiat_p256_get_bit(g_scalar->bytes, i + 64) << 1; + bits |= fiat_p256_get_bit(g_scalar->bytes, i); + if (bits != 0) { + size_t index = (size_t)(bits - 1); + fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], + 1 /* mixed */, fiat_p256_g_pre_comp[0][index][0], + fiat_p256_g_pre_comp[0][index][1], + fiat_p256_one); + skip = 0; + } + } + + int digit = p_wNAF[i]; + if (digit != 0) { + assert(digit & 1); + size_t idx = (size_t)(digit < 0 ? (-digit) >> 1 : digit >> 1); + fiat_p256_felem *y = &p_pre_comp[idx][1], tmp; + if (digit < 0) { + fiat_p256_opp(tmp, p_pre_comp[idx][1]); + y = &tmp; + } + if (!skip) { + fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], + 0 /* not mixed */, p_pre_comp[idx][0], *y, + p_pre_comp[idx][2]); + } else { + fiat_p256_copy(ret[0], p_pre_comp[idx][0]); + fiat_p256_copy(ret[1], *y); + fiat_p256_copy(ret[2], p_pre_comp[idx][2]); + skip = 0; + } + } + } + + fiat_p256_to_generic(&r->X, ret[0]); + fiat_p256_to_generic(&r->Y, ret[1]); + fiat_p256_to_generic(&r->Z, ret[2]); +} + +static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group, + const EC_RAW_POINT *p, + const EC_SCALAR *r) { + if (ec_GFp_simple_is_at_infinity(group, p)) { + return 0; + } + + // We wish to compare X/Z^2 with r. This is equivalent to comparing X with + // r*Z^2. Note that X and Z are represented in Montgomery form, while r is + // not. + fiat_p256_felem Z2_mont; + fiat_p256_from_generic(Z2_mont, &p->Z); + fiat_p256_mul(Z2_mont, Z2_mont, Z2_mont); + + fiat_p256_felem r_Z2; + fiat_p256_from_bytes(r_Z2, r->bytes); // r < order < p, so this is valid. + fiat_p256_mul(r_Z2, r_Z2, Z2_mont); + + fiat_p256_felem X; + fiat_p256_from_generic(X, &p->X); + fiat_p256_from_montgomery(X, X); + + if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) { + return 1; + } + + // During signing the x coefficient is reduced modulo the group order. + // Therefore there is a small possibility, less than 1/2^128, that group_order + // < p.x < P. in that case we need not only to compare against |r| but also to + // compare against r+group_order. + assert(group->field.width == group->order.width); + if (bn_less_than_words(r->words, group->field_minus_order.words, + group->field.width)) { + // We can ignore the carry because: r + group_order < p < 2^256. + EC_FELEM tmp; + bn_add_words(tmp.words, r->words, group->order.d, group->order.width); + fiat_p256_from_generic(r_Z2, &tmp); + fiat_p256_mul(r_Z2, r_Z2, Z2_mont); + if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) { + return 1; + } + } + + return 0; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp256_point_get_affine_coordinates; + out->add = ec_GFp_nistp256_add; + out->dbl = ec_GFp_nistp256_dbl; + out->mul = ec_GFp_nistp256_point_mul; + out->mul_base = ec_GFp_nistp256_point_mul_base; + out->mul_public = ec_GFp_nistp256_point_mul_public; + out->felem_mul = ec_GFp_mont_felem_mul; + out->felem_sqr = ec_GFp_mont_felem_sqr; + out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; + out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery; + out->scalar_to_montgomery_inv_vartime = + ec_simple_scalar_to_montgomery_inv_vartime; + out->cmp_x_coordinate = ec_GFp_nistp256_cmp_x_coordinate; +} + +#undef BORINGSSL_NISTP256_64BIT diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256_table.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256_table.h new file mode 100644 index 00000000..14129a36 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256_table.h @@ -0,0 +1,297 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This file is generated by make_tables.go. + +// Base point pre computation +// -------------------------- +// +// Two different sorts of precomputed tables are used in the following code. +// Each contain various points on the curve, where each point is three field +// elements (x, y, z). +// +// For the base point table, z is usually 1 (0 for the point at infinity). +// This table has 2 * 16 elements, starting with the following: +// index | bits | point +// ------+---------+------------------------------ +// 0 | 0 0 0 0 | 0G +// 1 | 0 0 0 1 | 1G +// 2 | 0 0 1 0 | 2^64G +// 3 | 0 0 1 1 | (2^64 + 1)G +// 4 | 0 1 0 0 | 2^128G +// 5 | 0 1 0 1 | (2^128 + 1)G +// 6 | 0 1 1 0 | (2^128 + 2^64)G +// 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G +// 8 | 1 0 0 0 | 2^192G +// 9 | 1 0 0 1 | (2^192 + 1)G +// 10 | 1 0 1 0 | (2^192 + 2^64)G +// 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G +// 12 | 1 1 0 0 | (2^192 + 2^128)G +// 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G +// 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G +// 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G +// followed by a copy of this with each element multiplied by 2^32. +// +// The reason for this is so that we can clock bits into four different +// locations when doing simple scalar multiplies against the base point, +// and then another four locations using the second 16 elements. +// +// Tables for other points have table[i] = iG for i in 0 .. 16. + +// fiat_p256_g_pre_comp is the table of precomputed base points +#if defined(BORINGSSL_NISTP256_64BIT) +static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = { + {{{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, + 0x18905f76a53755c6}, + {0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, + 0x8571ff1825885d85}}, + {{0x4f922fc516a0d2bb, 0x0d5cc16c1a623499, 0x9241cf3a57c62c8b, + 0x2f5e6961fd1b667f}, + {0x5c15c70bf5a01797, 0x3d20b44d60956192, 0x04911b37071fdb52, + 0xf648f9168d6f0f7b}}, + {{0x9e566847e137bbbc, 0xe434469e8a6a0bec, 0xb1c4276179d73463, + 0x5abe0285133d0015}, + {0x92aa837cc04c7dab, 0x573d9f4c43260c07, 0x0c93156278e6cc37, + 0x94bb725b6b6f7383}}, + {{0x62a8c244bfe20925, 0x91c19ac38fdce867, 0x5a96a5d5dd387063, + 0x61d587d421d324f6}, + {0xe87673a2a37173ea, 0x2384800853778b65, 0x10f8441e05bab43e, + 0xfa11fe124621efbe}}, + {{0x1c891f2b2cb19ffd, 0x01ba8d5bb1923c23, 0xb6d03d678ac5ca8e, + 0x586eb04c1f13bedc}, + {0x0c35c6e527e8ed09, 0x1e81a33c1819ede2, 0x278fd6c056c652fa, + 0x19d5ac0870864f11}}, + {{0x62577734d2b533d5, 0x673b8af6a1bdddc0, 0x577e7c9aa79ec293, + 0xbb6de651c3b266b1}, + {0xe7e9303ab65259b3, 0xd6a0afd3d03a7480, 0xc5ac83d19b3cfc27, + 0x60b4619a5d18b99b}}, + {{0xbd6a38e11ae5aa1c, 0xb8b7652b49e73658, 0x0b130014ee5f87ed, + 0x9d0f27b2aeebffcd}, + {0xca9246317a730a55, 0x9c955b2fddbbc83a, 0x07c1dfe0ac019a71, + 0x244a566d356ec48d}}, + {{0x56f8410ef4f8b16a, 0x97241afec47b266a, 0x0a406b8e6d9c87c1, + 0x803f3e02cd42ab1b}, + {0x7f0309a804dbec69, 0xa83b85f73bbad05f, 0xc6097273ad8e197f, + 0xc097440e5067adc1}}, + {{0x846a56f2c379ab34, 0xa8ee068b841df8d1, 0x20314459176c68ef, + 0xf1af32d5915f1f30}, + {0x99c375315d75bd50, 0x837cffbaf72f67bc, 0x0613a41848d7723f, + 0x23d0f130e2d41c8b}}, + {{0xed93e225d5be5a2b, 0x6fe799835934f3c6, 0x4314092622626ffc, + 0x50bbb4d97990216a}, + {0x378191c6e57ec63e, 0x65422c40181dcdb2, 0x41a8099b0236e0f6, + 0x2b10011801fe49c3}}, + {{0xfc68b5c59b391593, 0xc385f5a2598270fc, 0x7144f3aad19adcbb, + 0xdd55899983fbae0c}, + {0x93b88b8e74b82ff4, 0xd2e03c4071e734c9, 0x9a7a9eaf43c0322a, + 0xe6e4c551149d6041}}, + {{0x5fe14bfe80ec21fe, 0xf6ce116ac255be82, 0x98bc5a072f4a5d67, + 0xfad27148db7e63af}, + {0x90c0b6ac29ab05b3, 0x37a9a83c4e251ae6, 0x0a7dc875c2aade7d, + 0x77387de39f0e1a84}}, + {{0x1e9ecc49a56c0dd7, 0xa5cffcd846086c74, 0x8f7a1408f505aece, + 0xb37b85c0bef0c47e}, + {0x3596b6e4cc0e6a8f, 0xfd6d4bbf6b388f23, 0xaba453fac39cef4e, + 0x9c135ac8f9f628d5}}, + {{0x0a1c729495c8f8be, 0x2961c4803bf362bf, 0x9e418403df63d4ac, + 0xc109f9cb91ece900}, + {0xc2d095d058945705, 0xb9083d96ddeb85c0, 0x84692b8d7a40449b, + 0x9bc3344f2eee1ee1}}, + {{0x0d5ae35642913074, 0x55491b2748a542b1, 0x469ca665b310732a, + 0x29591d525f1a4cc1}, + {0xe76f5b6bb84f983f, 0xbe7eef419f5f84e1, 0x1200d49680baa189, + 0x6376551f18ef332c}}}, + {{{0x202886024147519a, 0xd0981eac26b372f0, 0xa9d4a7caa785ebc8, + 0xd953c50ddbdf58e9}, + {0x9d6361ccfd590f8f, 0x72e9626b44e6c917, 0x7fd9611022eb64cf, + 0x863ebb7e9eb288f3}}, + {{0x4fe7ee31b0e63d34, 0xf4600572a9e54fab, 0xc0493334d5e7b5a4, + 0x8589fb9206d54831}, + {0xaa70f5cc6583553a, 0x0879094ae25649e5, 0xcc90450710044652, + 0xebb0696d02541c4f}}, + {{0xabbaa0c03b89da99, 0xa6f2d79eb8284022, 0x27847862b81c05e8, + 0x337a4b5905e54d63}, + {0x3c67500d21f7794a, 0x207005b77d6d7f61, 0x0a5a378104cfd6e8, + 0x0d65e0d5f4c2fbd6}}, + {{0xd433e50f6d3549cf, 0x6f33696ffacd665e, 0x695bfdacce11fcb4, + 0x810ee252af7c9860}, + {0x65450fe17159bb2c, 0xf7dfbebe758b357b, 0x2b057e74d69fea72, + 0xd485717a92731745}}, + {{0xce1f69bbe83f7669, 0x09f8ae8272877d6b, 0x9548ae543244278d, + 0x207755dee3c2c19c}, + {0x87bd61d96fef1945, 0x18813cefb12d28c3, 0x9fbcd1d672df64aa, + 0x48dc5ee57154b00d}}, + {{0xef0f469ef49a3154, 0x3e85a5956e2b2e9a, 0x45aaec1eaa924a9c, + 0xaa12dfc8a09e4719}, + {0x26f272274df69f1d, 0xe0e4c82ca2ff5e73, 0xb9d8ce73b7a9dd44, + 0x6c036e73e48ca901}}, + {{0xe1e421e1a47153f0, 0xb86c3b79920418c9, 0x93bdce87705d7672, + 0xf25ae793cab79a77}, + {0x1f3194a36d869d0c, 0x9d55c8824986c264, 0x49fb5ea3096e945e, + 0x39b8e65313db0a3e}}, + {{0xe3417bc035d0b34a, 0x440b386b8327c0a7, 0x8fb7262dac0362d1, + 0x2c41114ce0cdf943}, + {0x2ba5cef1ad95a0b1, 0xc09b37a867d54362, 0x26d6cdd201e486c9, + 0x20477abf42ff9297}}, + {{0x0f121b41bc0a67d2, 0x62d4760a444d248a, 0x0e044f1d659b4737, + 0x08fde365250bb4a8}, + {0xaceec3da848bf287, 0xc2a62182d3369d6e, 0x3582dfdc92449482, + 0x2f7e2fd2565d6cd7}}, + {{0x0a0122b5178a876b, 0x51ff96ff085104b4, 0x050b31ab14f29f76, + 0x84abb28b5f87d4e6}, + {0xd5ed439f8270790a, 0x2d6cb59d85e3f46b, 0x75f55c1b6c1e2212, + 0xe5436f6717655640}}, + {{0xc2965ecc9aeb596d, 0x01ea03e7023c92b4, 0x4704b4b62e013961, + 0x0ca8fd3f905ea367}, + {0x92523a42551b2b61, 0x1eb7a89c390fcd06, 0xe7f1d2be0392a63e, + 0x96dca2644ddb0c33}}, + {{0x231c210e15339848, 0xe87a28e870778c8d, 0x9d1de6616956e170, + 0x4ac3c9382bb09c0b}, + {0x19be05516998987d, 0x8b2376c4ae09f4d6, 0x1de0b7651a3f933d, + 0x380d94c7e39705f4}}, + {{0x3685954b8c31c31d, 0x68533d005bf21a0c, 0x0bd7626e75c79ec9, + 0xca17754742c69d54}, + {0xcc6edafff6d2dbb2, 0xfd0d8cbd174a9d18, 0x875e8793aa4578e8, + 0xa976a7139cab2ce6}}, + {{0xce37ab11b43ea1db, 0x0a7ff1a95259d292, 0x851b02218f84f186, + 0xa7222beadefaad13}, + {0xa2ac78ec2b0a9144, 0x5a024051f2fa59c5, 0x91d1eca56147ce38, + 0xbe94d523bc2ac690}}, + {{0x2d8daefd79ec1a0f, 0x3bbcd6fdceb39c97, 0xf5575ffc58f61a95, + 0xdbd986c4adf7b420}, + {0x81aa881415f39eb7, 0x6ee2fcf5b98d976c, 0x5465475dcf2f717d, + 0x8e24d3c46860bbd0}}}}; +#else +static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = { + {{{0x18a9143c, 0x79e730d4, 0x5fedb601, 0x75ba95fc, 0x77622510, 0x79fb732b, + 0xa53755c6, 0x18905f76}, + {0xce95560a, 0xddf25357, 0xba19e45c, 0x8b4ab8e4, 0xdd21f325, 0xd2e88688, + 0x25885d85, 0x8571ff18}}, + {{0x16a0d2bb, 0x4f922fc5, 0x1a623499, 0x0d5cc16c, 0x57c62c8b, 0x9241cf3a, + 0xfd1b667f, 0x2f5e6961}, + {0xf5a01797, 0x5c15c70b, 0x60956192, 0x3d20b44d, 0x071fdb52, 0x04911b37, + 0x8d6f0f7b, 0xf648f916}}, + {{0xe137bbbc, 0x9e566847, 0x8a6a0bec, 0xe434469e, 0x79d73463, 0xb1c42761, + 0x133d0015, 0x5abe0285}, + {0xc04c7dab, 0x92aa837c, 0x43260c07, 0x573d9f4c, 0x78e6cc37, 0x0c931562, + 0x6b6f7383, 0x94bb725b}}, + {{0xbfe20925, 0x62a8c244, 0x8fdce867, 0x91c19ac3, 0xdd387063, 0x5a96a5d5, + 0x21d324f6, 0x61d587d4}, + {0xa37173ea, 0xe87673a2, 0x53778b65, 0x23848008, 0x05bab43e, 0x10f8441e, + 0x4621efbe, 0xfa11fe12}}, + {{0x2cb19ffd, 0x1c891f2b, 0xb1923c23, 0x01ba8d5b, 0x8ac5ca8e, 0xb6d03d67, + 0x1f13bedc, 0x586eb04c}, + {0x27e8ed09, 0x0c35c6e5, 0x1819ede2, 0x1e81a33c, 0x56c652fa, 0x278fd6c0, + 0x70864f11, 0x19d5ac08}}, + {{0xd2b533d5, 0x62577734, 0xa1bdddc0, 0x673b8af6, 0xa79ec293, 0x577e7c9a, + 0xc3b266b1, 0xbb6de651}, + {0xb65259b3, 0xe7e9303a, 0xd03a7480, 0xd6a0afd3, 0x9b3cfc27, 0xc5ac83d1, + 0x5d18b99b, 0x60b4619a}}, + {{0x1ae5aa1c, 0xbd6a38e1, 0x49e73658, 0xb8b7652b, 0xee5f87ed, 0x0b130014, + 0xaeebffcd, 0x9d0f27b2}, + {0x7a730a55, 0xca924631, 0xddbbc83a, 0x9c955b2f, 0xac019a71, 0x07c1dfe0, + 0x356ec48d, 0x244a566d}}, + {{0xf4f8b16a, 0x56f8410e, 0xc47b266a, 0x97241afe, 0x6d9c87c1, 0x0a406b8e, + 0xcd42ab1b, 0x803f3e02}, + {0x04dbec69, 0x7f0309a8, 0x3bbad05f, 0xa83b85f7, 0xad8e197f, 0xc6097273, + 0x5067adc1, 0xc097440e}}, + {{0xc379ab34, 0x846a56f2, 0x841df8d1, 0xa8ee068b, 0x176c68ef, 0x20314459, + 0x915f1f30, 0xf1af32d5}, + {0x5d75bd50, 0x99c37531, 0xf72f67bc, 0x837cffba, 0x48d7723f, 0x0613a418, + 0xe2d41c8b, 0x23d0f130}}, + {{0xd5be5a2b, 0xed93e225, 0x5934f3c6, 0x6fe79983, 0x22626ffc, 0x43140926, + 0x7990216a, 0x50bbb4d9}, + {0xe57ec63e, 0x378191c6, 0x181dcdb2, 0x65422c40, 0x0236e0f6, 0x41a8099b, + 0x01fe49c3, 0x2b100118}}, + {{0x9b391593, 0xfc68b5c5, 0x598270fc, 0xc385f5a2, 0xd19adcbb, 0x7144f3aa, + 0x83fbae0c, 0xdd558999}, + {0x74b82ff4, 0x93b88b8e, 0x71e734c9, 0xd2e03c40, 0x43c0322a, 0x9a7a9eaf, + 0x149d6041, 0xe6e4c551}}, + {{0x80ec21fe, 0x5fe14bfe, 0xc255be82, 0xf6ce116a, 0x2f4a5d67, 0x98bc5a07, + 0xdb7e63af, 0xfad27148}, + {0x29ab05b3, 0x90c0b6ac, 0x4e251ae6, 0x37a9a83c, 0xc2aade7d, 0x0a7dc875, + 0x9f0e1a84, 0x77387de3}}, + {{0xa56c0dd7, 0x1e9ecc49, 0x46086c74, 0xa5cffcd8, 0xf505aece, 0x8f7a1408, + 0xbef0c47e, 0xb37b85c0}, + {0xcc0e6a8f, 0x3596b6e4, 0x6b388f23, 0xfd6d4bbf, 0xc39cef4e, 0xaba453fa, + 0xf9f628d5, 0x9c135ac8}}, + {{0x95c8f8be, 0x0a1c7294, 0x3bf362bf, 0x2961c480, 0xdf63d4ac, 0x9e418403, + 0x91ece900, 0xc109f9cb}, + {0x58945705, 0xc2d095d0, 0xddeb85c0, 0xb9083d96, 0x7a40449b, 0x84692b8d, + 0x2eee1ee1, 0x9bc3344f}}, + {{0x42913074, 0x0d5ae356, 0x48a542b1, 0x55491b27, 0xb310732a, 0x469ca665, + 0x5f1a4cc1, 0x29591d52}, + {0xb84f983f, 0xe76f5b6b, 0x9f5f84e1, 0xbe7eef41, 0x80baa189, 0x1200d496, + 0x18ef332c, 0x6376551f}}}, + {{{0x4147519a, 0x20288602, 0x26b372f0, 0xd0981eac, 0xa785ebc8, 0xa9d4a7ca, + 0xdbdf58e9, 0xd953c50d}, + {0xfd590f8f, 0x9d6361cc, 0x44e6c917, 0x72e9626b, 0x22eb64cf, 0x7fd96110, + 0x9eb288f3, 0x863ebb7e}}, + {{0xb0e63d34, 0x4fe7ee31, 0xa9e54fab, 0xf4600572, 0xd5e7b5a4, 0xc0493334, + 0x06d54831, 0x8589fb92}, + {0x6583553a, 0xaa70f5cc, 0xe25649e5, 0x0879094a, 0x10044652, 0xcc904507, + 0x02541c4f, 0xebb0696d}}, + {{0x3b89da99, 0xabbaa0c0, 0xb8284022, 0xa6f2d79e, 0xb81c05e8, 0x27847862, + 0x05e54d63, 0x337a4b59}, + {0x21f7794a, 0x3c67500d, 0x7d6d7f61, 0x207005b7, 0x04cfd6e8, 0x0a5a3781, + 0xf4c2fbd6, 0x0d65e0d5}}, + {{0x6d3549cf, 0xd433e50f, 0xfacd665e, 0x6f33696f, 0xce11fcb4, 0x695bfdac, + 0xaf7c9860, 0x810ee252}, + {0x7159bb2c, 0x65450fe1, 0x758b357b, 0xf7dfbebe, 0xd69fea72, 0x2b057e74, + 0x92731745, 0xd485717a}}, + {{0xe83f7669, 0xce1f69bb, 0x72877d6b, 0x09f8ae82, 0x3244278d, 0x9548ae54, + 0xe3c2c19c, 0x207755de}, + {0x6fef1945, 0x87bd61d9, 0xb12d28c3, 0x18813cef, 0x72df64aa, 0x9fbcd1d6, + 0x7154b00d, 0x48dc5ee5}}, + {{0xf49a3154, 0xef0f469e, 0x6e2b2e9a, 0x3e85a595, 0xaa924a9c, 0x45aaec1e, + 0xa09e4719, 0xaa12dfc8}, + {0x4df69f1d, 0x26f27227, 0xa2ff5e73, 0xe0e4c82c, 0xb7a9dd44, 0xb9d8ce73, + 0xe48ca901, 0x6c036e73}}, + {{0xa47153f0, 0xe1e421e1, 0x920418c9, 0xb86c3b79, 0x705d7672, 0x93bdce87, + 0xcab79a77, 0xf25ae793}, + {0x6d869d0c, 0x1f3194a3, 0x4986c264, 0x9d55c882, 0x096e945e, 0x49fb5ea3, + 0x13db0a3e, 0x39b8e653}}, + {{0x35d0b34a, 0xe3417bc0, 0x8327c0a7, 0x440b386b, 0xac0362d1, 0x8fb7262d, + 0xe0cdf943, 0x2c41114c}, + {0xad95a0b1, 0x2ba5cef1, 0x67d54362, 0xc09b37a8, 0x01e486c9, 0x26d6cdd2, + 0x42ff9297, 0x20477abf}}, + {{0xbc0a67d2, 0x0f121b41, 0x444d248a, 0x62d4760a, 0x659b4737, 0x0e044f1d, + 0x250bb4a8, 0x08fde365}, + {0x848bf287, 0xaceec3da, 0xd3369d6e, 0xc2a62182, 0x92449482, 0x3582dfdc, + 0x565d6cd7, 0x2f7e2fd2}}, + {{0x178a876b, 0x0a0122b5, 0x085104b4, 0x51ff96ff, 0x14f29f76, 0x050b31ab, + 0x5f87d4e6, 0x84abb28b}, + {0x8270790a, 0xd5ed439f, 0x85e3f46b, 0x2d6cb59d, 0x6c1e2212, 0x75f55c1b, + 0x17655640, 0xe5436f67}}, + {{0x9aeb596d, 0xc2965ecc, 0x023c92b4, 0x01ea03e7, 0x2e013961, 0x4704b4b6, + 0x905ea367, 0x0ca8fd3f}, + {0x551b2b61, 0x92523a42, 0x390fcd06, 0x1eb7a89c, 0x0392a63e, 0xe7f1d2be, + 0x4ddb0c33, 0x96dca264}}, + {{0x15339848, 0x231c210e, 0x70778c8d, 0xe87a28e8, 0x6956e170, 0x9d1de661, + 0x2bb09c0b, 0x4ac3c938}, + {0x6998987d, 0x19be0551, 0xae09f4d6, 0x8b2376c4, 0x1a3f933d, 0x1de0b765, + 0xe39705f4, 0x380d94c7}}, + {{0x8c31c31d, 0x3685954b, 0x5bf21a0c, 0x68533d00, 0x75c79ec9, 0x0bd7626e, + 0x42c69d54, 0xca177547}, + {0xf6d2dbb2, 0xcc6edaff, 0x174a9d18, 0xfd0d8cbd, 0xaa4578e8, 0x875e8793, + 0x9cab2ce6, 0xa976a713}}, + {{0xb43ea1db, 0xce37ab11, 0x5259d292, 0x0a7ff1a9, 0x8f84f186, 0x851b0221, + 0xdefaad13, 0xa7222bea}, + {0x2b0a9144, 0xa2ac78ec, 0xf2fa59c5, 0x5a024051, 0x6147ce38, 0x91d1eca5, + 0xbc2ac690, 0xbe94d523}}, + {{0x79ec1a0f, 0x2d8daefd, 0xceb39c97, 0x3bbcd6fd, 0x58f61a95, 0xf5575ffc, + 0xadf7b420, 0xdbd986c4}, + {0x15f39eb7, 0x81aa8814, 0xb98d976c, 0x6ee2fcf5, 0xcf2f717d, 0x5465475d, + 0x6860bbd0, 0x8e24d3c4}}}}; +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/scalar.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/scalar.c new file mode 100644 index 00000000..e3e8f698 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/scalar.c @@ -0,0 +1,175 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in) { + if (!bn_copy_words(out->words, group->order.width, in) || + !bn_less_than_words(out->words, group->order.d, group->order.width)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + return 1; +} + +int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a, + const EC_SCALAR *b) { + return OPENSSL_memcmp(a->words, b->words, + group->order.width * sizeof(BN_ULONG)) == 0; +} + +int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a) { + BN_ULONG mask = 0; + for (int i = 0; i < group->order.width; i++) { + mask |= a->words[i]; + } + return mask == 0; +} + +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]) { + return bn_rand_range_words(out->words, 1, group->order.d, group->order.width, + additional_data); +} + +void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, + const EC_SCALAR *in) { + size_t len = BN_num_bytes(&group->order); + for (size_t i = 0; i < len; i++) { + out[len - i - 1] = in->bytes[i]; + } + *out_len = len; +} + +int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t *in, size_t len) { + if (len != BN_num_bytes(&group->order)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + + OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); + + for (size_t i = 0; i < len; i++) { + out->bytes[i] = in[len - i - 1]; + } + + if (!bn_less_than_words(out->words, group->order.d, group->order.width)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + + return 1; +} + +void ec_scalar_reduce(const EC_GROUP *group, EC_SCALAR *out, + const BN_ULONG *words, size_t num) { + // Convert "from" Montgomery form so the value is reduced modulo the order. + bn_from_montgomery_small(out->words, group->order.width, words, num, + group->order_mont); + // Convert "to" Montgomery form to remove the R^-1 factor added. + ec_scalar_to_montgomery(group, out, out); +} + +void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a, + const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + BN_ULONG tmp[EC_MAX_WORDS]; + bn_mod_add_words(r->words, a->words, b->words, order->d, tmp, order->width); + OPENSSL_cleanse(tmp, sizeof(tmp)); +} + +void ec_scalar_sub(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a, + const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + BN_ULONG tmp[EC_MAX_WORDS]; + bn_mod_sub_words(r->words, a->words, b->words, order->d, tmp, order->width); + OPENSSL_cleanse(tmp, sizeof(tmp)); +} + +void ec_scalar_neg(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a) { + EC_SCALAR zero; + OPENSSL_memset(&zero, 0, sizeof(EC_SCALAR)); + ec_scalar_sub(group, r, &zero, a); +} + +void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask, + const EC_SCALAR *a, const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + bn_select_words(out->words, mask, a->words, b->words, order->width); +} + +void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a) { + const BIGNUM *order = &group->order; + bn_to_montgomery_small(r->words, a->words, order->width, group->order_mont); +} + +void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a) { + const BIGNUM *order = &group->order; + bn_from_montgomery_small(r->words, order->width, a->words, order->width, + group->order_mont); +} + +void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a, const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + bn_mod_mul_montgomery_small(r->words, a->words, b->words, order->width, + group->order_mont); +} + +void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a) { + const BIGNUM *order = &group->order; + bn_mod_inverse0_prime_mont_small(r->words, a->words, order->width, + group->order_mont); +} + +int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, + EC_SCALAR *r, + const EC_SCALAR *a) { + if (ec_scalar_is_zero(group, a)) { + return 0; + } + + // This implementation (in fact) runs in constant time, + // even though for this interface it is not mandatory. + + // r = a^-1 in the Montgomery domain. This is + // |ec_scalar_to_montgomery| followed by |ec_scalar_inv0_montgomery|, but + // |ec_scalar_inv0_montgomery| followed by |ec_scalar_from_montgomery| is + // equivalent and slightly more efficient. + ec_scalar_inv0_montgomery(group, r, a); + ec_scalar_from_montgomery(group, r, r); + return 1; +} + +void ec_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a) { + group->meth->scalar_inv0_montgomery(group, r, a); +} + +int ec_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a) { + return group->meth->scalar_to_montgomery_inv_vartime(group, r, a); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple.c new file mode 100644 index 00000000..91392cda --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple.c @@ -0,0 +1,357 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// Most method functions in this file are designed to work with non-trivial +// representations of field elements if necessary (see ecp_mont.c): while +// standard modular addition and subtraction are used, the field_mul and +// field_sqr methods will be used for multiplication, and field_encode and +// field_decode (if defined) will be used for converting between +// representations. +// +// Functions here specifically assume that if a non-trivial representation is +// used, it is a Montgomery representation (i.e. 'encoding' means multiplying +// by some factor R). + +int ec_GFp_simple_group_init(EC_GROUP *group) { + BN_init(&group->field); + group->a_is_minus3 = 0; + return 1; +} + +void ec_GFp_simple_group_finish(EC_GROUP *group) { + BN_free(&group->field); +} + +int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + // p must be a prime > 3 + if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return 0; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + // group->field + if (!BN_copy(&group->field, p)) { + goto err; + } + BN_set_negative(&group->field, 0); + // Store the field in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->field); + + if (!ec_bignum_to_felem(group, &group->a, a) || + !ec_bignum_to_felem(group, &group->b, b) || + !ec_bignum_to_felem(group, &group->one, BN_value_one())) { + goto err; + } + + // group->a_is_minus3 + if (!BN_copy(tmp, a) || + !BN_add_word(tmp, 3)) { + goto err; + } + group->a_is_minus3 = (0 == BN_cmp(tmp, &group->field)); + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b) { + if ((p != NULL && !BN_copy(p, &group->field)) || + (a != NULL && !ec_felem_to_bignum(group, a, &group->a)) || + (b != NULL && !ec_felem_to_bignum(group, b, &group->b))) { + return 0; + } + return 1; +} + +void ec_GFp_simple_point_init(EC_RAW_POINT *point) { + OPENSSL_memset(&point->X, 0, sizeof(EC_FELEM)); + OPENSSL_memset(&point->Y, 0, sizeof(EC_FELEM)); + OPENSSL_memset(&point->Z, 0, sizeof(EC_FELEM)); +} + +void ec_GFp_simple_point_copy(EC_RAW_POINT *dest, const EC_RAW_POINT *src) { + OPENSSL_memcpy(&dest->X, &src->X, sizeof(EC_FELEM)); + OPENSSL_memcpy(&dest->Y, &src->Y, sizeof(EC_FELEM)); + OPENSSL_memcpy(&dest->Z, &src->Z, sizeof(EC_FELEM)); +} + +void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_RAW_POINT *point) { + // Although it is strictly only necessary to zero Z, we zero the entire point + // in case |point| was stack-allocated and yet to be initialized. + ec_GFp_simple_point_init(point); +} + +void ec_GFp_simple_invert(const EC_GROUP *group, EC_RAW_POINT *point) { + ec_felem_neg(group, &point->Y, &point->Y); +} + +int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, + const EC_RAW_POINT *point) { + return ec_felem_non_zero_mask(group, &point->Z) == 0; +} + +int ec_GFp_simple_is_on_curve(const EC_GROUP *group, + const EC_RAW_POINT *point) { + // We have a curve defined by a Weierstrass equation + // y^2 = x^3 + a*x + b. + // The point to consider is given in Jacobian projective coordinates + // where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). + // Substituting this and multiplying by Z^6 transforms the above equation + // into + // Y^2 = X^3 + a*X*Z^4 + b*Z^6. + // To test this, we add up the right-hand side in 'rh'. + // + // This function may be used when double-checking the secret result of a point + // multiplication, so we proceed in constant-time. + + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + // rh := X^2 + EC_FELEM rh; + felem_sqr(group, &rh, &point->X); + + EC_FELEM tmp, Z4, Z6; + felem_sqr(group, &tmp, &point->Z); + felem_sqr(group, &Z4, &tmp); + felem_mul(group, &Z6, &Z4, &tmp); + + // rh := rh + a*Z^4 + if (group->a_is_minus3) { + ec_felem_add(group, &tmp, &Z4, &Z4); + ec_felem_add(group, &tmp, &tmp, &Z4); + ec_felem_sub(group, &rh, &rh, &tmp); + } else { + felem_mul(group, &tmp, &Z4, &group->a); + ec_felem_add(group, &rh, &rh, &tmp); + } + + // rh := (rh + a*Z^4)*X + felem_mul(group, &rh, &rh, &point->X); + + // rh := rh + b*Z^6 + felem_mul(group, &tmp, &group->b, &Z6); + ec_felem_add(group, &rh, &rh, &tmp); + + // 'lh' := Y^2 + felem_sqr(group, &tmp, &point->Y); + + ec_felem_sub(group, &tmp, &tmp, &rh); + BN_ULONG not_equal = ec_felem_non_zero_mask(group, &tmp); + + // If Z = 0, the point is infinity, which is always on the curve. + BN_ULONG not_infinity = ec_felem_non_zero_mask(group, &point->Z); + + return 1 & ~(not_infinity & not_equal); +} + +int ec_GFp_simple_points_equal(const EC_GROUP *group, const EC_RAW_POINT *a, + const EC_RAW_POINT *b) { + // This function is implemented in constant-time for two reasons. First, + // although EC points are usually public, their Jacobian Z coordinates may be + // secret, or at least are not obviously public. Second, more complex + // protocols will sometimes manipulate secret points. + // + // This does mean that we pay a 6M+2S Jacobian comparison when comparing two + // publicly affine points costs no field operations at all. If needed, we can + // restore this optimization by keeping better track of affine vs. Jacobian + // forms. See https://crbug.com/boringssl/326. + + // If neither |a| or |b| is infinity, we have to decide whether + // (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), + // or equivalently, whether + // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). + + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + EC_FELEM tmp1, tmp2, Za23, Zb23; + felem_sqr(group, &Zb23, &b->Z); // Zb23 = Z_b^2 + felem_mul(group, &tmp1, &a->X, &Zb23); // tmp1 = X_a * Z_b^2 + felem_sqr(group, &Za23, &a->Z); // Za23 = Z_a^2 + felem_mul(group, &tmp2, &b->X, &Za23); // tmp2 = X_b * Z_a^2 + ec_felem_sub(group, &tmp1, &tmp1, &tmp2); + const BN_ULONG x_not_equal = ec_felem_non_zero_mask(group, &tmp1); + + felem_mul(group, &Zb23, &Zb23, &b->Z); // Zb23 = Z_b^3 + felem_mul(group, &tmp1, &a->Y, &Zb23); // tmp1 = Y_a * Z_b^3 + felem_mul(group, &Za23, &Za23, &a->Z); // Za23 = Z_a^3 + felem_mul(group, &tmp2, &b->Y, &Za23); // tmp2 = Y_b * Z_a^3 + ec_felem_sub(group, &tmp1, &tmp1, &tmp2); + const BN_ULONG y_not_equal = ec_felem_non_zero_mask(group, &tmp1); + const BN_ULONG x_and_y_equal = ~(x_not_equal | y_not_equal); + + const BN_ULONG a_not_infinity = ec_felem_non_zero_mask(group, &a->Z); + const BN_ULONG b_not_infinity = ec_felem_non_zero_mask(group, &b->Z); + const BN_ULONG a_and_b_infinity = ~(a_not_infinity | b_not_infinity); + + const BN_ULONG equal = + a_and_b_infinity | (a_not_infinity & b_not_infinity & x_and_y_equal); + return equal & 1; +} + +int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a, + const EC_RAW_POINT *b) { + // If |b| is not infinity, we have to decide whether + // (X_a, Y_a) = (X_b/Z_b^2, Y_b/Z_b^3), + // or equivalently, whether + // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b, Y_b). + + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; + + EC_FELEM tmp, Zb2; + felem_sqr(group, &Zb2, &b->Z); // Zb2 = Z_b^2 + felem_mul(group, &tmp, &a->X, &Zb2); // tmp = X_a * Z_b^2 + ec_felem_sub(group, &tmp, &tmp, &b->X); + const BN_ULONG x_not_equal = ec_felem_non_zero_mask(group, &tmp); + + felem_mul(group, &tmp, &a->Y, &Zb2); // tmp = Y_a * Z_b^2 + felem_mul(group, &tmp, &tmp, &b->Z); // tmp = Y_a * Z_b^3 + ec_felem_sub(group, &tmp, &tmp, &b->Y); + const BN_ULONG y_not_equal = ec_felem_non_zero_mask(group, &tmp); + const BN_ULONG x_and_y_equal = ~(x_not_equal | y_not_equal); + + const BN_ULONG b_not_infinity = ec_felem_non_zero_mask(group, &b->Z); + + const BN_ULONG equal = b_not_infinity & x_and_y_equal; + return equal & 1; +} + +int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, + const EC_SCALAR *r) { + if (ec_GFp_simple_is_at_infinity(group, p)) { + // |ec_get_x_coordinate_as_scalar| will check this internally, but this way + // we do not push to the error queue. + return 0; + } + + EC_SCALAR x; + return ec_get_x_coordinate_as_scalar(group, &x, p) && + ec_scalar_equal_vartime(group, &x, r); +} + +void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out, + size_t *out_len, const EC_FELEM *in) { + size_t len = BN_num_bytes(&group->field); + for (size_t i = 0; i < len; i++) { + out[i] = in->bytes[len - 1 - i]; + } + *out_len = len; +} + +int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, + const uint8_t *in, size_t len) { + if (len != BN_num_bytes(&group->field)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + OPENSSL_memset(out, 0, sizeof(EC_FELEM)); + for (size_t i = 0; i < len; i++) { + out->bytes[i] = in[len - 1 - i]; + } + + if (!bn_less_than_words(out->words, group->field.d, group->field.width)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple_mul.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple_mul.c new file mode 100644 index 00000000..9675625c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple_mul.c @@ -0,0 +1,270 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p, const EC_SCALAR *scalar) { + // This is a generic implementation for uncommon curves that not do not + // warrant a tuned one. It uses unsigned digits so that the doubling case in + // |ec_GFp_mont_add| is always unreachable, erring on safety and simplicity. + + // Compute a table of the first 32 multiples of |p| (including infinity). + EC_RAW_POINT precomp[32]; + ec_GFp_simple_point_set_to_infinity(group, &precomp[0]); + ec_GFp_simple_point_copy(&precomp[1], p); + for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + if (j & 1) { + ec_GFp_mont_add(group, &precomp[j], &precomp[1], &precomp[j - 1]); + } else { + ec_GFp_mont_dbl(group, &precomp[j], &precomp[j / 2]); + } + } + + // Divide bits in |scalar| into windows. + unsigned bits = BN_num_bits(&group->order); + int r_is_at_infinity = 1; + for (unsigned i = bits - 1; i < bits; i--) { + if (!r_is_at_infinity) { + ec_GFp_mont_dbl(group, r, r); + } + if (i % 5 == 0) { + // Compute the next window value. + const size_t width = group->order.width; + uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 4; + window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 3; + window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 2; + window |= bn_is_bit_set_words(scalar->words, width, i + 1) << 1; + window |= bn_is_bit_set_words(scalar->words, width, i); + + // Select the entry in constant-time. + EC_RAW_POINT tmp; + OPENSSL_memset(&tmp, 0, sizeof(EC_RAW_POINT)); + for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + BN_ULONG mask = constant_time_eq_w(j, window); + ec_point_select(group, &tmp, mask, &precomp[j], &tmp); + } + + if (r_is_at_infinity) { + ec_GFp_simple_point_copy(r, &tmp); + r_is_at_infinity = 0; + } else { + ec_GFp_mont_add(group, r, r, &tmp); + } + } + } + if (r_is_at_infinity) { + ec_GFp_simple_point_set_to_infinity(group, r); + } +} + +void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *scalar) { + ec_GFp_mont_mul(group, r, &group->generator->raw, scalar); +} + +static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_RAW_POINT *out, + size_t num, const EC_RAW_POINT *p) { + assert(num > 1); + ec_GFp_simple_point_set_to_infinity(group, &out[0]); + ec_GFp_simple_point_copy(&out[1], p); + for (size_t j = 2; j < num; j++) { + if (j & 1) { + ec_GFp_mont_add(group, &out[j], &out[1], &out[j - 1]); + } else { + ec_GFp_mont_dbl(group, &out[j], &out[j / 2]); + } + } +} + +static void ec_GFp_mont_batch_get_window(const EC_GROUP *group, + EC_RAW_POINT *out, + const EC_RAW_POINT precomp[17], + const EC_SCALAR *scalar, unsigned i) { + const size_t width = group->order.width; + uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 5; + window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 4; + window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 3; + window |= bn_is_bit_set_words(scalar->words, width, i + 1) << 2; + window |= bn_is_bit_set_words(scalar->words, width, i) << 1; + if (i > 0) { + window |= bn_is_bit_set_words(scalar->words, width, i - 1); + } + crypto_word_t sign, digit; + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, window); + + // Select the entry in constant-time. + OPENSSL_memset(out, 0, sizeof(EC_RAW_POINT)); + for (size_t j = 0; j < 17; j++) { + BN_ULONG mask = constant_time_eq_w(j, digit); + ec_point_select(group, out, mask, &precomp[j], out); + } + + // Negate if necessary. + EC_FELEM neg_Y; + ec_felem_neg(group, &neg_Y, &out->Y); + crypto_word_t sign_mask = sign; + sign_mask = 0u - sign_mask; + ec_felem_select(group, &out->Y, sign_mask, &neg_Y, &out->Y); +} + +void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, const EC_SCALAR *scalar2) { + EC_RAW_POINT precomp[3][17]; + ec_GFp_mont_batch_precomp(group, precomp[0], 17, p0); + ec_GFp_mont_batch_precomp(group, precomp[1], 17, p1); + if (p2 != NULL) { + ec_GFp_mont_batch_precomp(group, precomp[2], 17, p2); + } + + // Divide bits in |scalar| into windows. + unsigned bits = BN_num_bits(&group->order); + int r_is_at_infinity = 1; + for (unsigned i = bits; i <= bits; i--) { + if (!r_is_at_infinity) { + ec_GFp_mont_dbl(group, r, r); + } + if (i % 5 == 0) { + EC_RAW_POINT tmp; + ec_GFp_mont_batch_get_window(group, &tmp, precomp[0], scalar0, i); + if (r_is_at_infinity) { + ec_GFp_simple_point_copy(r, &tmp); + r_is_at_infinity = 0; + } else { + ec_GFp_mont_add(group, r, r, &tmp); + } + + ec_GFp_mont_batch_get_window(group, &tmp, precomp[1], scalar1, i); + ec_GFp_mont_add(group, r, r, &tmp); + + if (p2 != NULL) { + ec_GFp_mont_batch_get_window(group, &tmp, precomp[2], scalar2, i); + ec_GFp_mont_add(group, r, r, &tmp); + } + } + } + if (r_is_at_infinity) { + ec_GFp_simple_point_set_to_infinity(group, r); + } +} + +static unsigned ec_GFp_mont_comb_stride(const EC_GROUP *group) { + return (BN_num_bits(&group->field) + EC_MONT_PRECOMP_COMB_SIZE - 1) / + EC_MONT_PRECOMP_COMB_SIZE; +} + +int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, + const EC_RAW_POINT *p) { + // comb[i - 1] stores the ith element of the comb. That is, if i is + // b4 * 2^4 + b3 * 2^3 + ... + b0 * 2^0, it stores k * |p|, where k is + // b4 * 2^(4*stride) + b3 * 2^(3*stride) + ... + b0 * 2^(0*stride). stride + // here is |ec_GFp_mont_comb_stride|. We store at index i - 1 because the 0th + // comb entry is always infinity. + EC_RAW_POINT comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1]; + unsigned stride = ec_GFp_mont_comb_stride(group); + + // We compute the comb sequentially by the highest set bit. Initially, all + // entries up to 2^0 are filled. + comb[(1 << 0) - 1] = *p; + for (unsigned i = 1; i < EC_MONT_PRECOMP_COMB_SIZE; i++) { + // Compute entry 2^i by doubling the entry for 2^(i-1) |stride| times. + unsigned bit = 1 << i; + ec_GFp_mont_dbl(group, &comb[bit - 1], &comb[bit / 2 - 1]); + for (unsigned j = 1; j < stride; j++) { + ec_GFp_mont_dbl(group, &comb[bit - 1], &comb[bit - 1]); + } + // Compute entries from 2^i + 1 to 2^i + (2^i - 1) by adding entry 2^i to + // a previous entry. + for (unsigned j = 1; j < bit; j++) { + ec_GFp_mont_add(group, &comb[bit + j - 1], &comb[bit - 1], &comb[j - 1]); + } + } + + // Store the comb in affine coordinates to shrink the table. (This reduces + // cache pressure and makes the constant-time selects faster.) + OPENSSL_STATIC_ASSERT( + OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb), + "comb sizes did not match"); + return ec_jacobian_to_affine_batch(group, out->comb, comb, + OPENSSL_ARRAY_SIZE(comb)); +} + +static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, + EC_RAW_POINT *out, + const EC_PRECOMP *precomp, + const EC_SCALAR *scalar, unsigned i) { + const size_t width = group->order.width; + unsigned stride = ec_GFp_mont_comb_stride(group); + // Select the bits corresponding to the comb shifted up by |i|. + unsigned window = 0; + for (unsigned j = 0; j < EC_MONT_PRECOMP_COMB_SIZE; j++) { + window |= bn_is_bit_set_words(scalar->words, width, j * stride + i) + << j; + } + + // Select precomp->comb[window - 1]. If |window| is zero, |match| will always + // be zero, which will leave |out| at infinity. + OPENSSL_memset(out, 0, sizeof(EC_RAW_POINT)); + for (unsigned j = 0; j < OPENSSL_ARRAY_SIZE(precomp->comb); j++) { + BN_ULONG match = constant_time_eq_w(window, j + 1); + ec_felem_select(group, &out->X, match, &precomp->comb[j].X, &out->X); + ec_felem_select(group, &out->Y, match, &precomp->comb[j].Y, &out->Y); + } + BN_ULONG is_infinity = constant_time_is_zero_w(window); + ec_felem_select(group, &out->Z, is_infinity, &out->Z, &group->one); +} + +void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_PRECOMP *p0, const EC_SCALAR *scalar0, + const EC_PRECOMP *p1, const EC_SCALAR *scalar1, + const EC_PRECOMP *p2, const EC_SCALAR *scalar2) { + unsigned stride = ec_GFp_mont_comb_stride(group); + int r_is_at_infinity = 1; + for (unsigned i = stride - 1; i < stride; i--) { + if (!r_is_at_infinity) { + ec_GFp_mont_dbl(group, r, r); + } + + EC_RAW_POINT tmp; + ec_GFp_mont_get_comb_window(group, &tmp, p0, scalar0, i); + if (r_is_at_infinity) { + ec_GFp_simple_point_copy(r, &tmp); + r_is_at_infinity = 0; + } else { + ec_GFp_mont_add(group, r, r, &tmp); + } + + if (p1 != NULL) { + ec_GFp_mont_get_comb_window(group, &tmp, p1, scalar1, i); + ec_GFp_mont_add(group, r, r, &tmp); + } + + if (p2 != NULL) { + ec_GFp_mont_get_comb_window(group, &tmp, p2, scalar2, i); + ec_GFp_mont_add(group, r, r, &tmp); + } + } + if (r_is_at_infinity) { + ec_GFp_simple_point_set_to_infinity(group, r); + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/util.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/util.c new file mode 100644 index 00000000..cd44afa4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/util.c @@ -0,0 +1,255 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +// This function looks at 5+1 scalar bits (5 current, 1 adjacent less +// significant bit), and recodes them into a signed digit for use in fast point +// multiplication: the use of signed rather than unsigned digits means that +// fewer points need to be precomputed, given that point inversion is easy (a +// precomputed point dP makes -dP available as well). +// +// BACKGROUND: +// +// Signed digits for multiplication were introduced by Booth ("A signed binary +// multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, +// pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. +// Booth's original encoding did not generally improve the density of nonzero +// digits over the binary representation, and was merely meant to simplify the +// handling of signed factors given in two's complement; but it has since been +// shown to be the basis of various signed-digit representations that do have +// further advantages, including the wNAF, using the following general +// approach: +// +// (1) Given a binary representation +// +// b_k ... b_2 b_1 b_0, +// +// of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 +// by using bit-wise subtraction as follows: +// +// b_k b_(k-1) ... b_2 b_1 b_0 +// - b_k ... b_3 b_2 b_1 b_0 +// ----------------------------------------- +// s_(k+1) s_k ... s_3 s_2 s_1 s_0 +// +// A left-shift followed by subtraction of the original value yields a new +// representation of the same value, using signed bits s_i = b_(i-1) - b_i. +// This representation from Booth's paper has since appeared in the +// literature under a variety of different names including "reversed binary +// form", "alternating greedy expansion", "mutual opposite form", and +// "sign-alternating {+-1}-representation". +// +// An interesting property is that among the nonzero bits, values 1 and -1 +// strictly alternate. +// +// (2) Various window schemes can be applied to the Booth representation of +// integers: for example, right-to-left sliding windows yield the wNAF +// (a signed-digit encoding independently discovered by various researchers +// in the 1990s), and left-to-right sliding windows yield a left-to-right +// equivalent of the wNAF (independently discovered by various researchers +// around 2004). +// +// To prevent leaking information through side channels in point multiplication, +// we need to recode the given integer into a regular pattern: sliding windows +// as in wNAFs won't do, we need their fixed-window equivalent -- which is a few +// decades older: we'll be using the so-called "modified Booth encoding" due to +// MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 +// (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five +// signed bits into a signed digit: +// +// s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j) +// +// The sign-alternating property implies that the resulting digit values are +// integers from -16 to 16. +// +// Of course, we don't actually need to compute the signed digits s_i as an +// intermediate step (that's just a nice way to see how this scheme relates +// to the wNAF): a direct computation obtains the recoded digit from the +// six bits b_(5j + 4) ... b_(5j - 1). +// +// This function takes those six bits as an integer (0 .. 63), writing the +// recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute +// value, in the range 0 .. 16). Note that this integer essentially provides +// the input bits "shifted to the left" by one position: for example, the input +// to compute the least significant recoded digit, given that there's no bit +// b_-1, has to be b_4 b_3 b_2 b_1 b_0 0. +// +// DOUBLING CASE: +// +// Point addition formulas for short Weierstrass curves are often incomplete. +// Edge cases such as P + P or P + ∞ must be handled separately. This +// complicates constant-time requirements. P + ∞ cannot be avoided (any window +// may be zero) and is handled with constant-time selects. P + P (where P is not +// ∞) usually is not. Instead, windowing strategies are chosen to avoid this +// case. Whether this happens depends on the group order. +// +// Let w be the window width (in this function, w = 5). The non-trivial doubling +// case in single-point scalar multiplication may occur if and only if the +// 2^(w-1) bit of the group order is zero. +// +// Note the above only holds if the scalar is fully reduced and the group order +// is a prime that is much larger than 2^w. It also only holds when windows +// are applied from most significant to least significant, doubling between each +// window. It does not apply to more complex table strategies such as +// |EC_GFp_nistz256_method|. +// +// PROOF: +// +// Let n be the group order. Let l be the number of bits needed to represent n. +// Assume there exists some 0 <= k < n such that signed w-bit windowed +// multiplication hits the doubling case. +// +// Windowed multiplication consists of iterating over groups of s_i (defined +// above based on k's binary representation) from most to least significant. At +// iteration i (for i = ..., 3w, 2w, w, 0, starting from the most significant +// window), we: +// +// 1. Double the accumulator A, w times. Let A_i be the value of A at this +// point. +// +// 2. Set A to T_i + A_i, where T_i is a precomputed multiple of P +// corresponding to the window s_(i+w-1) ... s_i. +// +// Let j be the index such that A_j = T_j ≠ ∞. Looking at A_i and T_i as +// multiples of P, define a_i and t_i to be scalar coefficients of A_i and T_i. +// Thus a_j = t_j ≠ 0 (mod n). Note a_i and t_i may not be reduced mod n. t_i is +// the value of the w signed bits s_(i+w-1) ... s_i. a_i is computed as a_i = +// 2^w * (a_(i+w) + t_(i+w)). +// +// t_i is bounded by -2^(w-1) <= t_i <= 2^(w-1). Additionally, we may write it +// in terms of unsigned bits b_i. t_i consists of signed bits s_(i+w-1) ... s_i. +// This is computed as: +// +// b_(i+w-2) b_(i+w-3) ... b_i b_(i-1) +// - b_(i+w-1) b_(i+w-2) ... b_(i+1) b_i +// -------------------------------------------- +// t_i = s_(i+w-1) s_(i+w-2) ... s_(i+1) s_i +// +// Observe that b_(i+w-2) through b_i occur in both terms. Let x be the integer +// represented by that bit string, i.e. 2^(w-2)*b_(i+w-2) + ... + b_i. +// +// t_i = (2*x + b_(i-1)) - (2^(w-1)*b_(i+w-1) + x) +// = x - 2^(w-1)*b_(i+w-1) + b_(i-1) +// +// Or, using C notation for bit operations: +// +// t_i = (k>>i) & ((1<<(w-1)) - 1) - (k>>i) & (1<<(w-1)) + (k>>(i-1)) & 1 +// +// Note b_(i-1) is added in left-shifted by one (or doubled) from its place. +// This is compensated by t_(i-w)'s subtraction term. Thus, a_i may be computed +// by adding b_l b_(l-1) ... b_(i+1) b_i and an extra copy of b_(i-1). In C +// notation, this is: +// +// a_i = (k>>(i+w)) << w + ((k>>(i+w-1)) & 1) << w +// +// Observe that, while t_i may be positive or negative, a_i is bounded by +// 0 <= a_i < n + 2^w. Additionally, a_i can only be zero if b_(i+w-1) and up +// are all zero. (Note this implies a non-trivial P + (-P) is unreachable for +// all groups. That would imply the subsequent a_i is zero, which means all +// terms thus far were zero.) +// +// Returning to our doubling position, we have a_j = t_j (mod n). We now +// determine the value of a_j - t_j, which must be divisible by n. Our bounds on +// a_j and t_j imply a_j - t_j is 0 or n. If it is 0, a_j = t_j. However, 2^w +// divides a_j and -2^(w-1) <= t_j <= 2^(w-1), so this can only happen if +// a_j = t_j = 0, which is a trivial doubling. Therefore, a_j - t_j = n. +// +// Now we determine j. Suppose j > 0. w divides j, so j >= w. Then, +// +// n = a_j - t_j = (k>>(j+w)) << w + ((k>>(j+w-1)) & 1) << w - t_j +// <= k/2^j + 2^w - t_j +// < n/2^w + 2^w + 2^(w-1) +// +// n is much larger than 2^w, so this is impossible. Thus, j = 0: only the final +// addition may hit the doubling case. +// +// Finally, we consider bit patterns for n and k. Divide k into k_H + k_M + k_L +// such that k_H is the contribution from b_(l-1) .. b_w, k_M is the +// contribution from b_(w-1), and k_L is the contribution from b_(w-2) ... b_0. +// That is: +// +// - 2^w divides k_H +// - k_M is 0 or 2^(w-1) +// - 0 <= k_L < 2^(w-1) +// +// Divide n into n_H + n_M + n_L similarly. We thus have: +// +// t_0 = (k>>0) & ((1<<(w-1)) - 1) - (k>>0) & (1<<(w-1)) + (k>>(0-1)) & 1 +// = k & ((1<<(w-1)) - 1) - k & (1<<(w-1)) +// = k_L - k_M +// +// a_0 = (k>>(0+w)) << w + ((k>>(0+w-1)) & 1) << w +// = (k>>w) << w + ((k>>(w-1)) & 1) << w +// = k_H + 2*k_M +// +// n = a_0 - t_0 +// n_H + n_M + n_L = (k_H + 2*k_M) - (k_L - k_M) +// = k_H + 3*k_M - k_L +// +// k_H - k_L < k and k < n, so k_H - k_L ≠ n. Therefore k_M is not 0 and must be +// 2^(w-1). Now we consider k_H and n_H. We know k_H <= n_H. Suppose k_H = n_H. +// Then, +// +// n_M + n_L = 3*(2^(w-1)) - k_L +// > 3*(2^(w-1)) - 2^(w-1) +// = 2^w +// +// Contradiction (n_M + n_L is the bottom w bits of n). Thus k_H < n_H. Suppose +// k_H < n_H - 2*2^w. Then, +// +// n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L +// < n_H - 2*2^w + 3*(2^(w-1)) - k_L +// n_M + n_L < -2^(w-1) - k_L +// +// Contradiction. Thus, k_H = n_H - 2^w. (Note 2^w divides n_H and k_H.) Thus, +// +// n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L +// = n_H - 2^w + 3*(2^(w-1)) - k_L +// n_M + n_L = 2^(w-1) - k_L +// <= 2^(w-1) +// +// Equality would mean 2^(w-1) divides n, which is impossible if n is prime. +// Thus n_M + n_L < 2^(w-1), so n_M is zero, proving our condition. +// +// This proof constructs k, so, to show the converse, let k_H = n_H - 2^w, +// k_M = 2^(w-1), k_L = 2^(w-1) - n_L. This will result in a non-trivial point +// doubling in the final addition and is the only such scalar. +// +// COMMON CURVES: +// +// The group orders for common curves end in the following bit patterns: +// +// P-521: ...00001001; w = 4 is okay +// P-384: ...01110011; w = 2, 5, 6, 7 are okay +// P-256: ...01010001; w = 5, 7 are okay +// P-224: ...00111101; w = 3, 4, 5, 6 are okay +void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit, + crypto_word_t in) { + crypto_word_t s, d; + + s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as + * 6-bit value */ + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + *sign = s & 1; + *digit = d; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c new file mode 100644 index 00000000..ebabc3d1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c @@ -0,0 +1,270 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +// This file implements the wNAF-based interleaving multi-exponentiation method +// at: +// http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 +// http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + +void ec_compute_wNAF(const EC_GROUP *group, int8_t *out, + const EC_SCALAR *scalar, size_t bits, int w) { + // 'int8_t' can represent integers with absolute values less than 2^7. + assert(0 < w && w <= 7); + assert(bits != 0); + int bit = 1 << w; // 2^w, at most 128 + int next_bit = bit << 1; // 2^(w+1), at most 256 + int mask = next_bit - 1; // at most 255 + + int window_val = scalar->words[0] & mask; + for (size_t j = 0; j < bits + 1; j++) { + assert(0 <= window_val && window_val <= next_bit); + int digit = 0; + if (window_val & 1) { + assert(0 < window_val && window_val < next_bit); + if (window_val & bit) { + digit = window_val - next_bit; + // We know -next_bit < digit < 0 and window_val - digit = next_bit. + + // modified wNAF + if (j + w + 1 >= bits) { + // special case for generating modified wNAFs: + // no new bits will be added into window_val, + // so using a positive digit here will decrease + // the total length of the representation + + digit = window_val & (mask >> 1); + // We know 0 < digit < bit and window_val - digit = bit. + } + } else { + digit = window_val; + // We know 0 < digit < bit and window_val - digit = 0. + } + + window_val -= digit; + + // Now window_val is 0 or 2^(w+1) in standard wNAF generation. + // For modified window NAFs, it may also be 2^w. + // + // See the comments above for the derivation of each of these bounds. + assert(window_val == 0 || window_val == next_bit || window_val == bit); + assert(-bit < digit && digit < bit); + + // window_val was odd, so digit is also odd. + assert(digit & 1); + } + + out[j] = digit; + + // Incorporate the next bit. Previously, |window_val| <= |next_bit|, so if + // we shift and add at most one copy of |bit|, this will continue to hold + // afterwards. + window_val >>= 1; + window_val += + bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w + 1); + assert(window_val <= next_bit); + } + + // bits + 1 entries should be sufficient to consume all bits. + assert(window_val == 0); +} + +// compute_precomp sets |out[i]| to (2*i+1)*p, for i from 0 to |len|. +static void compute_precomp(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_RAW_POINT *p, size_t len) { + ec_GFp_simple_point_copy(&out[0], p); + EC_RAW_POINT two_p; + ec_GFp_mont_dbl(group, &two_p, p); + for (size_t i = 1; i < len; i++) { + ec_GFp_mont_add(group, &out[i], &out[i - 1], &two_p); + } +} + +static void lookup_precomp(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_RAW_POINT *precomp, int digit) { + if (digit < 0) { + digit = -digit; + ec_GFp_simple_point_copy(out, &precomp[digit >> 1]); + ec_GFp_simple_invert(group, out); + } else { + ec_GFp_simple_point_copy(out, &precomp[digit >> 1]); + } +} + +// EC_WNAF_WINDOW_BITS is the window size to use for |ec_GFp_mont_mul_public|. +#define EC_WNAF_WINDOW_BITS 4 + +// EC_WNAF_TABLE_SIZE is the table size to use for |ec_GFp_mont_mul_public|. +#define EC_WNAF_TABLE_SIZE (1 << (EC_WNAF_WINDOW_BITS - 1)) + +// EC_WNAF_STACK is the number of points worth of data to stack-allocate and +// avoid a malloc. +#define EC_WNAF_STACK 3 + +int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_SCALAR *g_scalar, + const EC_RAW_POINT *points, + const EC_SCALAR *scalars, size_t num) { + size_t bits = BN_num_bits(&group->order); + size_t wNAF_len = bits + 1; + + int ret = 0; + int8_t wNAF_stack[EC_WNAF_STACK][EC_MAX_BYTES * 8 + 1]; + int8_t (*wNAF_alloc)[EC_MAX_BYTES * 8 + 1] = NULL; + int8_t (*wNAF)[EC_MAX_BYTES * 8 + 1]; + EC_RAW_POINT precomp_stack[EC_WNAF_STACK][EC_WNAF_TABLE_SIZE]; + EC_RAW_POINT (*precomp_alloc)[EC_WNAF_TABLE_SIZE] = NULL; + EC_RAW_POINT (*precomp)[EC_WNAF_TABLE_SIZE]; + if (num <= EC_WNAF_STACK) { + wNAF = wNAF_stack; + precomp = precomp_stack; + } else { + if (num >= ((size_t)-1) / sizeof(wNAF_alloc[0]) || + num >= ((size_t)-1) / sizeof(precomp_alloc[0])) { + OPENSSL_PUT_ERROR(EC, ERR_R_OVERFLOW); + goto err; + } + wNAF_alloc = OPENSSL_malloc(num * sizeof(wNAF_alloc[0])); + precomp_alloc = OPENSSL_malloc(num * sizeof(precomp_alloc[0])); + if (wNAF_alloc == NULL || precomp_alloc == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } + wNAF = wNAF_alloc; + precomp = precomp_alloc; + } + + int8_t g_wNAF[EC_MAX_BYTES * 8 + 1]; + EC_RAW_POINT g_precomp[EC_WNAF_TABLE_SIZE]; + assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF)); + const EC_RAW_POINT *g = &group->generator->raw; + if (g_scalar != NULL) { + ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS); + compute_precomp(group, g_precomp, g, EC_WNAF_TABLE_SIZE); + } + + for (size_t i = 0; i < num; i++) { + assert(wNAF_len <= OPENSSL_ARRAY_SIZE(wNAF[i])); + ec_compute_wNAF(group, wNAF[i], &scalars[i], bits, EC_WNAF_WINDOW_BITS); + compute_precomp(group, precomp[i], &points[i], EC_WNAF_TABLE_SIZE); + } + + EC_RAW_POINT tmp; + int r_is_at_infinity = 1; + for (size_t k = wNAF_len - 1; k < wNAF_len; k--) { + if (!r_is_at_infinity) { + ec_GFp_mont_dbl(group, r, r); + } + + if (g_scalar != NULL && g_wNAF[k] != 0) { + lookup_precomp(group, &tmp, g_precomp, g_wNAF[k]); + if (r_is_at_infinity) { + ec_GFp_simple_point_copy(r, &tmp); + r_is_at_infinity = 0; + } else { + ec_GFp_mont_add(group, r, r, &tmp); + } + } + + for (size_t i = 0; i < num; i++) { + if (wNAF[i][k] != 0) { + lookup_precomp(group, &tmp, precomp[i], wNAF[i][k]); + if (r_is_at_infinity) { + ec_GFp_simple_point_copy(r, &tmp); + r_is_at_infinity = 0; + } else { + ec_GFp_mont_add(group, r, r, &tmp); + } + } + } + } + + if (r_is_at_infinity) { + ec_GFp_simple_point_set_to_infinity(group, r); + } + + ret = 1; + +err: + OPENSSL_free(wNAF_alloc); + OPENSSL_free(precomp_alloc); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdh/ecdh.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdh/ecdh.c new file mode 100644 index 00000000..c3ff88e4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdh/ecdh.c @@ -0,0 +1,125 @@ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "../ec/internal.h" +#include "../../internal.h" + + +int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, + const EC_KEY *priv_key) { + boringssl_ensure_ecc_self_test(); + + if (priv_key->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); + return 0; + } + const EC_SCALAR *const priv = &priv_key->priv_key->scalar; + const EC_GROUP *const group = EC_KEY_get0_group(priv_key); + if (EC_GROUP_cmp(group, pub_key->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + EC_RAW_POINT shared_point; + uint8_t buf[EC_MAX_BYTES]; + size_t buflen; + if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) || + !ec_get_x_coordinate_as_bytes(group, buf, &buflen, sizeof(buf), + &shared_point)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + return 0; + } + + switch (out_len) { + case SHA224_DIGEST_LENGTH: + SHA224(buf, buflen, out); + break; + case SHA256_DIGEST_LENGTH: + SHA256(buf, buflen, out); + break; + case SHA384_DIGEST_LENGTH: + SHA384(buf, buflen, out); + break; + case SHA512_DIGEST_LENGTH: + SHA512(buf, buflen, out); + break; + default: + OPENSSL_PUT_ERROR(ECDH, ECDH_R_UNKNOWN_DIGEST_LENGTH); + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c new file mode 100644 index 00000000..42f8ce23 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c @@ -0,0 +1,349 @@ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../../internal.h" +#include "../bn/internal.h" +#include "../ec/internal.h" +#include "internal.h" + + +// digest_to_scalar interprets |digest_len| bytes from |digest| as a scalar for +// ECDSA. +static void digest_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t *digest, size_t digest_len) { + const BIGNUM *order = &group->order; + size_t num_bits = BN_num_bits(order); + // Need to truncate digest if it is too long: first truncate whole bytes. + size_t num_bytes = (num_bits + 7) / 8; + if (digest_len > num_bytes) { + digest_len = num_bytes; + } + OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); + for (size_t i = 0; i < digest_len; i++) { + out->bytes[i] = digest[digest_len - 1 - i]; + } + + // If it is still too long, truncate remaining bits with a shift. + if (8 * digest_len > num_bits) { + bn_rshift_words(out->words, out->words, 8 - (num_bits & 0x7), order->width); + } + + // |out| now has the same bit width as |order|, but this only bounds by + // 2*|order|. Subtract the order if out of range. + // + // Montgomery multiplication accepts the looser bounds, so this isn't strictly + // necessary, but it is a cleaner abstraction and has no performance impact. + BN_ULONG tmp[EC_MAX_WORDS]; + bn_reduce_once_in_place(out->words, 0 /* no carry */, order->d, tmp, + order->width); +} + +ECDSA_SIG *ECDSA_SIG_new(void) { + ECDSA_SIG *sig = OPENSSL_malloc(sizeof(ECDSA_SIG)); + if (sig == NULL) { + return NULL; + } + sig->r = BN_new(); + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL) { + ECDSA_SIG_free(sig); + return NULL; + } + return sig; +} + +void ECDSA_SIG_free(ECDSA_SIG *sig) { + if (sig == NULL) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig) { + return sig->r; +} + +const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig) { + return sig->s; +} + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s) { + if (out_r != NULL) { + *out_r = sig->r; + } + if (out_s != NULL) { + *out_s = sig->s; + } +} + +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + if (r == NULL || s == NULL) { + return 0; + } + BN_free(sig->r); + BN_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +int ecdsa_do_verify_no_self_test(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { + const EC_GROUP *group = EC_KEY_get0_group(eckey); + const EC_POINT *pub_key = EC_KEY_get0_public_key(eckey); + if (group == NULL || pub_key == NULL || sig == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS); + return 0; + } + + EC_SCALAR r, s, u1, u2, s_inv_mont, m; + if (BN_is_zero(sig->r) || + !ec_bignum_to_scalar(group, &r, sig->r) || + BN_is_zero(sig->s) || + !ec_bignum_to_scalar(group, &s, sig->s)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + return 0; + } + + // s_inv_mont = s^-1 in the Montgomery domain. + if (!ec_scalar_to_montgomery_inv_vartime(group, &s_inv_mont, &s)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); + return 0; + } + + // u1 = m * s^-1 mod order + // u2 = r * s^-1 mod order + // + // |s_inv_mont| is in Montgomery form while |m| and |r| are not, so |u1| and + // |u2| will be taken out of Montgomery form, as desired. + digest_to_scalar(group, &m, digest, digest_len); + ec_scalar_mul_montgomery(group, &u1, &m, &s_inv_mont); + ec_scalar_mul_montgomery(group, &u2, &r, &s_inv_mont); + + EC_RAW_POINT point; + if (!ec_point_mul_scalar_public(group, &point, &u1, &pub_key->raw, &u2)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + return 0; + } + + if (!ec_cmp_x_coordinate(group, &point, &r)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + return 0; + } + + return 1; +} + +int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + + return ecdsa_do_verify_no_self_test(digest, digest_len, sig, eckey); +} + +static ECDSA_SIG *ecdsa_sign_impl(const EC_GROUP *group, int *out_retry, + const EC_SCALAR *priv_key, const EC_SCALAR *k, + const uint8_t *digest, size_t digest_len) { + *out_retry = 0; + + // Check that the size of the group order is FIPS compliant (FIPS 186-4 + // B.5.2). + const BIGNUM *order = EC_GROUP_get0_order(group); + if (BN_num_bits(order) < 160) { + OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER); + return NULL; + } + + // Compute r, the x-coordinate of k * generator. + EC_RAW_POINT tmp_point; + EC_SCALAR r; + if (!ec_point_mul_scalar_base(group, &tmp_point, k) || + !ec_get_x_coordinate_as_scalar(group, &r, &tmp_point)) { + return NULL; + } + + if (ec_scalar_is_zero(group, &r)) { + *out_retry = 1; + return NULL; + } + + // s = priv_key * r. Note if only one parameter is in the Montgomery domain, + // |ec_scalar_mod_mul_montgomery| will compute the answer in the normal + // domain. + EC_SCALAR s; + ec_scalar_to_montgomery(group, &s, &r); + ec_scalar_mul_montgomery(group, &s, priv_key, &s); + + // s = m + priv_key * r. + EC_SCALAR tmp; + digest_to_scalar(group, &tmp, digest, digest_len); + ec_scalar_add(group, &s, &s, &tmp); + + // s = k^-1 * (m + priv_key * r). First, we compute k^-1 in the Montgomery + // domain. This is |ec_scalar_to_montgomery| followed by + // |ec_scalar_inv0_montgomery|, but |ec_scalar_inv0_montgomery| followed by + // |ec_scalar_from_montgomery| is equivalent and slightly more efficient. + // Then, as above, only one parameter is in the Montgomery domain, so the + // result is in the normal domain. Finally, note k is non-zero (or computing r + // would fail), so the inverse must exist. + ec_scalar_inv0_montgomery(group, &tmp, k); // tmp = k^-1 R^2 + ec_scalar_from_montgomery(group, &tmp, &tmp); // tmp = k^-1 R + ec_scalar_mul_montgomery(group, &s, &s, &tmp); + if (ec_scalar_is_zero(group, &s)) { + *out_retry = 1; + return NULL; + } + + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (ret == NULL || // + !bn_set_words(ret->r, r.words, order->width) || + !bn_set_words(ret->s, s.words, order->width)) { + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +ECDSA_SIG *ecdsa_sign_with_nonce_for_known_answer_test(const uint8_t *digest, + size_t digest_len, + const EC_KEY *eckey, + const uint8_t *nonce, + size_t nonce_len) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + return NULL; + } + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if (group == NULL || eckey->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + const EC_SCALAR *priv_key = &eckey->priv_key->scalar; + + EC_SCALAR k; + if (!ec_scalar_from_bytes(group, &k, nonce, nonce_len)) { + return NULL; + } + int retry_ignored; + return ecdsa_sign_impl(group, &retry_ignored, priv_key, &k, digest, + digest_len); +} + +// This function is only exported for testing and is not called in production +// code. +ECDSA_SIG *ECDSA_sign_with_nonce_and_leak_private_key_for_testing( + const uint8_t *digest, size_t digest_len, const EC_KEY *eckey, + const uint8_t *nonce, size_t nonce_len) { + boringssl_ensure_ecc_self_test(); + + return ecdsa_sign_with_nonce_for_known_answer_test(digest, digest_len, eckey, + nonce, nonce_len); +} + +ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, + const EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + return NULL; + } + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if (group == NULL || eckey->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + const BIGNUM *order = EC_GROUP_get0_order(group); + const EC_SCALAR *priv_key = &eckey->priv_key->scalar; + + // Pass a SHA512 hash of the private key and digest as additional data + // into the RBG. This is a hardening measure against entropy failure. + OPENSSL_STATIC_ASSERT(SHA512_DIGEST_LENGTH >= 32, + "additional_data is too large for SHA-512"); + SHA512_CTX sha; + uint8_t additional_data[SHA512_DIGEST_LENGTH]; + SHA512_Init(&sha); + SHA512_Update(&sha, priv_key->words, order->width * sizeof(BN_ULONG)); + SHA512_Update(&sha, digest, digest_len); + SHA512_Final(additional_data, &sha); + + for (;;) { + EC_SCALAR k; + if (!ec_random_nonzero_scalar(group, &k, additional_data)) { + return NULL; + } + + int retry; + ECDSA_SIG *sig = + ecdsa_sign_impl(group, &retry, priv_key, &k, digest, digest_len); + if (sig != NULL || !retry) { + return sig; + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/internal.h new file mode 100644 index 00000000..58d10010 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_ECDSA_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_ECDSA_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ecdsa_sign_with_nonce_for_known_answer_test behaves like |ECDSA_do_sign| but +// takes a fixed nonce. This function is used as part of known-answer tests in +// the FIPS module. +ECDSA_SIG *ecdsa_sign_with_nonce_for_known_answer_test(const uint8_t *digest, + size_t digest_len, + const EC_KEY *eckey, + const uint8_t *nonce, + size_t nonce_len); + +// ecdsa_do_verify_no_self_test does the same as |ECDSA_do_verify|, but doesn't +// try to run the self-test first. This is for use in the self tests themselves, +// to prevent an infinite loop. +int ecdsa_do_verify_no_self_test(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_ECDSA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/fips_shared_support.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/fips_shared_support.c new file mode 100644 index 00000000..2a66a1f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/fips_shared_support.c @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + + +#if defined(BORINGSSL_FIPS) && defined(BORINGSSL_SHARED_LIBRARY) +// BORINGSSL_bcm_text_hash is is default hash value for the FIPS integrity check +// that must be replaced with the real value during the build process. This +// value need only be distinct, i.e. so that we can safely search-and-replace it +// in an object file. +const uint8_t BORINGSSL_bcm_text_hash[64]; +const uint8_t BORINGSSL_bcm_text_hash[64] = { + 0xae, 0x2c, 0xea, 0x2a, 0xbd, 0xa6, 0xf3, 0xec, 0x97, 0x7f, 0x9b, + 0xf6, 0x94, 0x9a, 0xfc, 0x83, 0x68, 0x27, 0xcb, 0xa0, 0xa0, 0x9f, + 0x6b, 0x6f, 0xde, 0x52, 0xcd, 0xe2, 0xcd, 0xff, 0x31, 0x80, 0xa2, + 0xd4, 0xc3, 0x66, 0x0f, 0xc2, 0x6a, 0x7b, 0xf4, 0xbe, 0x39, 0xa2, + 0xd7, 0x25, 0xdb, 0x21, 0x98, 0xe9, 0xd5, 0x53, 0xbf, 0x5c, 0x32, + 0x06, 0x83, 0x34, 0x0c, 0x65, 0x89, 0x52, 0xbd, 0x1f, +}; +#endif // FIPS && SHARED_LIBRARY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S new file mode 100644 index 00000000..6d9f1b64 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S @@ -0,0 +1,265 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 PMULL +@ instructions are in aesv8-armx.pl.) + + +.text +#if defined(__thumb2__) || defined(__clang__) +.syntax unified +#define ldrplb ldrbpl +#define ldrneb ldrbne +#endif +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif +#if __ARM_MAX_ARCH__>=7 + + + +.globl _gcm_init_neon +.private_extern _gcm_init_neon +#ifdef __thumb2__ +.thumb_func _gcm_init_neon +#endif +.align 4 +_gcm_init_neon: + vld1.64 d7,[r1]! @ load H + vmov.i8 q8,#0xe1 + vld1.64 d6,[r1] + vshl.i64 d17,#57 + vshr.u64 d16,#63 @ t0=0xc2....01 + vdup.8 q9,d7[7] + vshr.u64 d26,d6,#63 + vshr.s8 q9,#7 @ broadcast carry bit + vshl.i64 q3,q3,#1 + vand q8,q8,q9 + vorr d7,d26 @ H<<<=1 + veor q3,q3,q8 @ twisted H + vstmia r0,{q3} + + bx lr @ bx lr + + +.globl _gcm_gmult_neon +.private_extern _gcm_gmult_neon +#ifdef __thumb2__ +.thumb_func _gcm_gmult_neon +#endif +.align 4 +_gcm_gmult_neon: + vld1.64 d7,[r0]! @ load Xi + vld1.64 d6,[r0]! + vmov.i64 d29,#0x0000ffffffffffff + vldmia r1,{d26,d27} @ load twisted H + vmov.i64 d30,#0x00000000ffffffff +#ifdef __ARMEL__ + vrev64.8 q3,q3 +#endif + vmov.i64 d31,#0x000000000000ffff + veor d28,d26,d27 @ Karatsuba pre-processing + mov r3,#16 + b Lgmult_neon + + +.globl _gcm_ghash_neon +.private_extern _gcm_ghash_neon +#ifdef __thumb2__ +.thumb_func _gcm_ghash_neon +#endif +.align 4 +_gcm_ghash_neon: + vld1.64 d1,[r0]! @ load Xi + vld1.64 d0,[r0]! + vmov.i64 d29,#0x0000ffffffffffff + vldmia r1,{d26,d27} @ load twisted H + vmov.i64 d30,#0x00000000ffffffff +#ifdef __ARMEL__ + vrev64.8 q0,q0 +#endif + vmov.i64 d31,#0x000000000000ffff + veor d28,d26,d27 @ Karatsuba pre-processing + +Loop_neon: + vld1.64 d7,[r2]! @ load inp + vld1.64 d6,[r2]! +#ifdef __ARMEL__ + vrev64.8 q3,q3 +#endif + veor q3,q0 @ inp^=Xi +Lgmult_neon: + vext.8 d16, d26, d26, #1 @ A1 + vmull.p8 q8, d16, d6 @ F = A1*B + vext.8 d0, d6, d6, #1 @ B1 + vmull.p8 q0, d26, d0 @ E = A*B1 + vext.8 d18, d26, d26, #2 @ A2 + vmull.p8 q9, d18, d6 @ H = A2*B + vext.8 d22, d6, d6, #2 @ B2 + vmull.p8 q11, d26, d22 @ G = A*B2 + vext.8 d20, d26, d26, #3 @ A3 + veor q8, q8, q0 @ L = E + F + vmull.p8 q10, d20, d6 @ J = A3*B + vext.8 d0, d6, d6, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q0, d26, d0 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d6, d6, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d26, d22 @ K = A*B4 + veor q10, q10, q0 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q0, d26, d6 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q0, q0, q8 + veor q0, q0, q10 + veor d6,d6,d7 @ Karatsuba pre-processing + vext.8 d16, d28, d28, #1 @ A1 + vmull.p8 q8, d16, d6 @ F = A1*B + vext.8 d2, d6, d6, #1 @ B1 + vmull.p8 q1, d28, d2 @ E = A*B1 + vext.8 d18, d28, d28, #2 @ A2 + vmull.p8 q9, d18, d6 @ H = A2*B + vext.8 d22, d6, d6, #2 @ B2 + vmull.p8 q11, d28, d22 @ G = A*B2 + vext.8 d20, d28, d28, #3 @ A3 + veor q8, q8, q1 @ L = E + F + vmull.p8 q10, d20, d6 @ J = A3*B + vext.8 d2, d6, d6, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q1, d28, d2 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d6, d6, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d28, d22 @ K = A*B4 + veor q10, q10, q1 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q1, d28, d6 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q1, q1, q8 + veor q1, q1, q10 + vext.8 d16, d27, d27, #1 @ A1 + vmull.p8 q8, d16, d7 @ F = A1*B + vext.8 d4, d7, d7, #1 @ B1 + vmull.p8 q2, d27, d4 @ E = A*B1 + vext.8 d18, d27, d27, #2 @ A2 + vmull.p8 q9, d18, d7 @ H = A2*B + vext.8 d22, d7, d7, #2 @ B2 + vmull.p8 q11, d27, d22 @ G = A*B2 + vext.8 d20, d27, d27, #3 @ A3 + veor q8, q8, q2 @ L = E + F + vmull.p8 q10, d20, d7 @ J = A3*B + vext.8 d4, d7, d7, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q2, d27, d4 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d7, d7, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d27, d22 @ K = A*B4 + veor q10, q10, q2 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q2, d27, d7 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q2, q2, q8 + veor q2, q2, q10 + veor q1,q1,q0 @ Karatsuba post-processing + veor q1,q1,q2 + veor d1,d1,d2 + veor d4,d4,d3 @ Xh|Xl - 256-bit result + + @ equivalent of reduction_avx from ghash-x86_64.pl + vshl.i64 q9,q0,#57 @ 1st phase + vshl.i64 q10,q0,#62 + veor q10,q10,q9 @ + vshl.i64 q9,q0,#63 + veor q10, q10, q9 @ + veor d1,d1,d20 @ + veor d4,d4,d21 + + vshr.u64 q10,q0,#1 @ 2nd phase + veor q2,q2,q0 + veor q0,q0,q10 @ + vshr.u64 q10,q10,#6 + vshr.u64 q0,q0,#1 @ + veor q0,q0,q2 @ + veor q0,q0,q10 @ + + subs r3,#16 + bne Loop_neon + +#ifdef __ARMEL__ + vrev64.8 q0,q0 +#endif + sub r0,#16 + vst1.64 d1,[r0]! @ write out Xi + vst1.64 d0,[r0] + + bx lr @ bx lr + +#endif +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S new file mode 100644 index 00000000..3b495ce2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S @@ -0,0 +1,262 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 PMULL +@ instructions are in aesv8-armx.pl.) +.arch armv7-a + +.text +#if defined(__thumb2__) || defined(__clang__) +.syntax unified +#define ldrplb ldrbpl +#define ldrneb ldrbne +#endif +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.globl gcm_init_neon +.hidden gcm_init_neon +.type gcm_init_neon,%function +.align 4 +gcm_init_neon: + vld1.64 d7,[r1]! @ load H + vmov.i8 q8,#0xe1 + vld1.64 d6,[r1] + vshl.i64 d17,#57 + vshr.u64 d16,#63 @ t0=0xc2....01 + vdup.8 q9,d7[7] + vshr.u64 d26,d6,#63 + vshr.s8 q9,#7 @ broadcast carry bit + vshl.i64 q3,q3,#1 + vand q8,q8,q9 + vorr d7,d26 @ H<<<=1 + veor q3,q3,q8 @ twisted H + vstmia r0,{q3} + + bx lr @ bx lr +.size gcm_init_neon,.-gcm_init_neon + +.globl gcm_gmult_neon +.hidden gcm_gmult_neon +.type gcm_gmult_neon,%function +.align 4 +gcm_gmult_neon: + vld1.64 d7,[r0]! @ load Xi + vld1.64 d6,[r0]! + vmov.i64 d29,#0x0000ffffffffffff + vldmia r1,{d26,d27} @ load twisted H + vmov.i64 d30,#0x00000000ffffffff +#ifdef __ARMEL__ + vrev64.8 q3,q3 +#endif + vmov.i64 d31,#0x000000000000ffff + veor d28,d26,d27 @ Karatsuba pre-processing + mov r3,#16 + b .Lgmult_neon +.size gcm_gmult_neon,.-gcm_gmult_neon + +.globl gcm_ghash_neon +.hidden gcm_ghash_neon +.type gcm_ghash_neon,%function +.align 4 +gcm_ghash_neon: + vld1.64 d1,[r0]! @ load Xi + vld1.64 d0,[r0]! + vmov.i64 d29,#0x0000ffffffffffff + vldmia r1,{d26,d27} @ load twisted H + vmov.i64 d30,#0x00000000ffffffff +#ifdef __ARMEL__ + vrev64.8 q0,q0 +#endif + vmov.i64 d31,#0x000000000000ffff + veor d28,d26,d27 @ Karatsuba pre-processing + +.Loop_neon: + vld1.64 d7,[r2]! @ load inp + vld1.64 d6,[r2]! +#ifdef __ARMEL__ + vrev64.8 q3,q3 +#endif + veor q3,q0 @ inp^=Xi +.Lgmult_neon: + vext.8 d16, d26, d26, #1 @ A1 + vmull.p8 q8, d16, d6 @ F = A1*B + vext.8 d0, d6, d6, #1 @ B1 + vmull.p8 q0, d26, d0 @ E = A*B1 + vext.8 d18, d26, d26, #2 @ A2 + vmull.p8 q9, d18, d6 @ H = A2*B + vext.8 d22, d6, d6, #2 @ B2 + vmull.p8 q11, d26, d22 @ G = A*B2 + vext.8 d20, d26, d26, #3 @ A3 + veor q8, q8, q0 @ L = E + F + vmull.p8 q10, d20, d6 @ J = A3*B + vext.8 d0, d6, d6, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q0, d26, d0 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d6, d6, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d26, d22 @ K = A*B4 + veor q10, q10, q0 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q0, d26, d6 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q0, q0, q8 + veor q0, q0, q10 + veor d6,d6,d7 @ Karatsuba pre-processing + vext.8 d16, d28, d28, #1 @ A1 + vmull.p8 q8, d16, d6 @ F = A1*B + vext.8 d2, d6, d6, #1 @ B1 + vmull.p8 q1, d28, d2 @ E = A*B1 + vext.8 d18, d28, d28, #2 @ A2 + vmull.p8 q9, d18, d6 @ H = A2*B + vext.8 d22, d6, d6, #2 @ B2 + vmull.p8 q11, d28, d22 @ G = A*B2 + vext.8 d20, d28, d28, #3 @ A3 + veor q8, q8, q1 @ L = E + F + vmull.p8 q10, d20, d6 @ J = A3*B + vext.8 d2, d6, d6, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q1, d28, d2 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d6, d6, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d28, d22 @ K = A*B4 + veor q10, q10, q1 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q1, d28, d6 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q1, q1, q8 + veor q1, q1, q10 + vext.8 d16, d27, d27, #1 @ A1 + vmull.p8 q8, d16, d7 @ F = A1*B + vext.8 d4, d7, d7, #1 @ B1 + vmull.p8 q2, d27, d4 @ E = A*B1 + vext.8 d18, d27, d27, #2 @ A2 + vmull.p8 q9, d18, d7 @ H = A2*B + vext.8 d22, d7, d7, #2 @ B2 + vmull.p8 q11, d27, d22 @ G = A*B2 + vext.8 d20, d27, d27, #3 @ A3 + veor q8, q8, q2 @ L = E + F + vmull.p8 q10, d20, d7 @ J = A3*B + vext.8 d4, d7, d7, #3 @ B3 + veor q9, q9, q11 @ M = G + H + vmull.p8 q2, d27, d4 @ I = A*B3 + veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8 + vand d17, d17, d29 + vext.8 d22, d7, d7, #4 @ B4 + veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16 + vand d19, d19, d30 + vmull.p8 q11, d27, d22 @ K = A*B4 + veor q10, q10, q2 @ N = I + J + veor d16, d16, d17 + veor d18, d18, d19 + veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24 + vand d21, d21, d31 + vext.8 q8, q8, q8, #15 + veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32 + vmov.i64 d23, #0 + vext.8 q9, q9, q9, #14 + veor d20, d20, d21 + vmull.p8 q2, d27, d7 @ D = A*B + vext.8 q11, q11, q11, #12 + vext.8 q10, q10, q10, #13 + veor q8, q8, q9 + veor q10, q10, q11 + veor q2, q2, q8 + veor q2, q2, q10 + veor q1,q1,q0 @ Karatsuba post-processing + veor q1,q1,q2 + veor d1,d1,d2 + veor d4,d4,d3 @ Xh|Xl - 256-bit result + + @ equivalent of reduction_avx from ghash-x86_64.pl + vshl.i64 q9,q0,#57 @ 1st phase + vshl.i64 q10,q0,#62 + veor q10,q10,q9 @ + vshl.i64 q9,q0,#63 + veor q10, q10, q9 @ + veor d1,d1,d20 @ + veor d4,d4,d21 + + vshr.u64 q10,q0,#1 @ 2nd phase + veor q2,q2,q0 + veor q0,q0,q10 @ + vshr.u64 q10,q10,#6 + vshr.u64 q0,q0,#1 @ + veor q0,q0,q2 @ + veor q0,q0,q10 @ + + subs r3,#16 + bne .Loop_neon + +#ifdef __ARMEL__ + vrev64.8 q0,q0 +#endif + sub r0,#16 + vst1.64 d1,[r0]! @ write out Xi + vst1.64 d0,[r0] + + bx lr @ bx lr +.size gcm_ghash_neon,.-gcm_ghash_neon +#endif +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S new file mode 100644 index 00000000..cd3c17e1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S @@ -0,0 +1,350 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +.globl _gcm_init_neon +.private_extern _gcm_init_neon + +.align 4 +_gcm_init_neon: + AARCH64_VALID_CALL_TARGET + // This function is adapted from gcm_init_v8. xC2 is t3. + ld1 {v17.2d}, [x1] // load H + movi v19.16b, #0xe1 + shl v19.2d, v19.2d, #57 // 0xc2.0 + ext v3.16b, v17.16b, v17.16b, #8 + ushr v18.2d, v19.2d, #63 + dup v17.4s, v17.s[1] + ext v16.16b, v18.16b, v19.16b, #8 // t0=0xc2....01 + ushr v18.2d, v3.2d, #63 + sshr v17.4s, v17.4s, #31 // broadcast carry bit + and v18.16b, v18.16b, v16.16b + shl v3.2d, v3.2d, #1 + ext v18.16b, v18.16b, v18.16b, #8 + and v16.16b, v16.16b, v17.16b + orr v3.16b, v3.16b, v18.16b // H<<<=1 + eor v5.16b, v3.16b, v16.16b // twisted H + st1 {v5.2d}, [x0] // store Htable[0] + ret + + +.globl _gcm_gmult_neon +.private_extern _gcm_gmult_neon + +.align 4 +_gcm_gmult_neon: + AARCH64_VALID_CALL_TARGET + ld1 {v3.16b}, [x0] // load Xi + ld1 {v5.1d}, [x1], #8 // load twisted H + ld1 {v6.1d}, [x1] + adrp x9, Lmasks@PAGE // load constants + add x9, x9, Lmasks@PAGEOFF + ld1 {v24.2d, v25.2d}, [x9] + rev64 v3.16b, v3.16b // byteswap Xi + ext v3.16b, v3.16b, v3.16b, #8 + eor v7.8b, v5.8b, v6.8b // Karatsuba pre-processing + + mov x3, #16 + b Lgmult_neon + + +.globl _gcm_ghash_neon +.private_extern _gcm_ghash_neon + +.align 4 +_gcm_ghash_neon: + AARCH64_VALID_CALL_TARGET + ld1 {v0.16b}, [x0] // load Xi + ld1 {v5.1d}, [x1], #8 // load twisted H + ld1 {v6.1d}, [x1] + adrp x9, Lmasks@PAGE // load constants + add x9, x9, Lmasks@PAGEOFF + ld1 {v24.2d, v25.2d}, [x9] + rev64 v0.16b, v0.16b // byteswap Xi + ext v0.16b, v0.16b, v0.16b, #8 + eor v7.8b, v5.8b, v6.8b // Karatsuba pre-processing + +Loop_neon: + ld1 {v3.16b}, [x2], #16 // load inp + rev64 v3.16b, v3.16b // byteswap inp + ext v3.16b, v3.16b, v3.16b, #8 + eor v3.16b, v3.16b, v0.16b // inp ^= Xi + +Lgmult_neon: + // Split the input into v3 and v4. (The upper halves are unused, + // so it is okay to leave them alone.) + ins v4.d[0], v3.d[1] + ext v16.8b, v5.8b, v5.8b, #1 // A1 + pmull v16.8h, v16.8b, v3.8b // F = A1*B + ext v0.8b, v3.8b, v3.8b, #1 // B1 + pmull v0.8h, v5.8b, v0.8b // E = A*B1 + ext v17.8b, v5.8b, v5.8b, #2 // A2 + pmull v17.8h, v17.8b, v3.8b // H = A2*B + ext v19.8b, v3.8b, v3.8b, #2 // B2 + pmull v19.8h, v5.8b, v19.8b // G = A*B2 + ext v18.8b, v5.8b, v5.8b, #3 // A3 + eor v16.16b, v16.16b, v0.16b // L = E + F + pmull v18.8h, v18.8b, v3.8b // J = A3*B + ext v0.8b, v3.8b, v3.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v0.8h, v5.8b, v0.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v3.8b, v3.8b, #4 // B4 + eor v18.16b, v18.16b, v0.16b // N = I + J + pmull v19.8h, v5.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v0.8h, v5.8b, v3.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v0.16b, v0.16b, v16.16b + eor v0.16b, v0.16b, v18.16b + eor v3.8b, v3.8b, v4.8b // Karatsuba pre-processing + ext v16.8b, v7.8b, v7.8b, #1 // A1 + pmull v16.8h, v16.8b, v3.8b // F = A1*B + ext v1.8b, v3.8b, v3.8b, #1 // B1 + pmull v1.8h, v7.8b, v1.8b // E = A*B1 + ext v17.8b, v7.8b, v7.8b, #2 // A2 + pmull v17.8h, v17.8b, v3.8b // H = A2*B + ext v19.8b, v3.8b, v3.8b, #2 // B2 + pmull v19.8h, v7.8b, v19.8b // G = A*B2 + ext v18.8b, v7.8b, v7.8b, #3 // A3 + eor v16.16b, v16.16b, v1.16b // L = E + F + pmull v18.8h, v18.8b, v3.8b // J = A3*B + ext v1.8b, v3.8b, v3.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v1.8h, v7.8b, v1.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v3.8b, v3.8b, #4 // B4 + eor v18.16b, v18.16b, v1.16b // N = I + J + pmull v19.8h, v7.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v1.8h, v7.8b, v3.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v1.16b, v1.16b, v16.16b + eor v1.16b, v1.16b, v18.16b + ext v16.8b, v6.8b, v6.8b, #1 // A1 + pmull v16.8h, v16.8b, v4.8b // F = A1*B + ext v2.8b, v4.8b, v4.8b, #1 // B1 + pmull v2.8h, v6.8b, v2.8b // E = A*B1 + ext v17.8b, v6.8b, v6.8b, #2 // A2 + pmull v17.8h, v17.8b, v4.8b // H = A2*B + ext v19.8b, v4.8b, v4.8b, #2 // B2 + pmull v19.8h, v6.8b, v19.8b // G = A*B2 + ext v18.8b, v6.8b, v6.8b, #3 // A3 + eor v16.16b, v16.16b, v2.16b // L = E + F + pmull v18.8h, v18.8b, v4.8b // J = A3*B + ext v2.8b, v4.8b, v4.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v2.8h, v6.8b, v2.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v4.8b, v4.8b, #4 // B4 + eor v18.16b, v18.16b, v2.16b // N = I + J + pmull v19.8h, v6.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v2.8h, v6.8b, v4.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v2.16b, v2.16b, v16.16b + eor v2.16b, v2.16b, v18.16b + ext v16.16b, v0.16b, v2.16b, #8 + eor v1.16b, v1.16b, v0.16b // Karatsuba post-processing + eor v1.16b, v1.16b, v2.16b + eor v1.16b, v1.16b, v16.16b // Xm overlaps Xh.lo and Xl.hi + ins v0.d[1], v1.d[0] // Xh|Xl - 256-bit result + // This is a no-op due to the ins instruction below. + // ins v2.d[0], v1.d[1] + + // equivalent of reduction_avx from ghash-x86_64.pl + shl v17.2d, v0.2d, #57 // 1st phase + shl v18.2d, v0.2d, #62 + eor v18.16b, v18.16b, v17.16b // + shl v17.2d, v0.2d, #63 + eor v18.16b, v18.16b, v17.16b // + // Note Xm contains {Xl.d[1], Xh.d[0]}. + eor v18.16b, v18.16b, v1.16b + ins v0.d[1], v18.d[0] // Xl.d[1] ^= t2.d[0] + ins v2.d[0], v18.d[1] // Xh.d[0] ^= t2.d[1] + + ushr v18.2d, v0.2d, #1 // 2nd phase + eor v2.16b, v2.16b,v0.16b + eor v0.16b, v0.16b,v18.16b // + ushr v18.2d, v18.2d, #6 + ushr v0.2d, v0.2d, #1 // + eor v0.16b, v0.16b, v2.16b // + eor v0.16b, v0.16b, v18.16b // + + subs x3, x3, #16 + bne Loop_neon + + rev64 v0.16b, v0.16b // byteswap Xi and write + ext v0.16b, v0.16b, v0.16b, #8 + st1 {v0.16b}, [x0] + + ret + + +.section __TEXT,__const +.align 4 +Lmasks: +.quad 0x0000ffffffffffff // k48 +.quad 0x00000000ffffffff // k32 +.quad 0x000000000000ffff // k16 +.quad 0x0000000000000000 // k0 +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S new file mode 100644 index 00000000..dcba2809 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S @@ -0,0 +1,353 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +.globl gcm_init_neon +.hidden gcm_init_neon +.type gcm_init_neon,%function +.align 4 +gcm_init_neon: + AARCH64_VALID_CALL_TARGET + // This function is adapted from gcm_init_v8. xC2 is t3. + ld1 {v17.2d}, [x1] // load H + movi v19.16b, #0xe1 + shl v19.2d, v19.2d, #57 // 0xc2.0 + ext v3.16b, v17.16b, v17.16b, #8 + ushr v18.2d, v19.2d, #63 + dup v17.4s, v17.s[1] + ext v16.16b, v18.16b, v19.16b, #8 // t0=0xc2....01 + ushr v18.2d, v3.2d, #63 + sshr v17.4s, v17.4s, #31 // broadcast carry bit + and v18.16b, v18.16b, v16.16b + shl v3.2d, v3.2d, #1 + ext v18.16b, v18.16b, v18.16b, #8 + and v16.16b, v16.16b, v17.16b + orr v3.16b, v3.16b, v18.16b // H<<<=1 + eor v5.16b, v3.16b, v16.16b // twisted H + st1 {v5.2d}, [x0] // store Htable[0] + ret +.size gcm_init_neon,.-gcm_init_neon + +.globl gcm_gmult_neon +.hidden gcm_gmult_neon +.type gcm_gmult_neon,%function +.align 4 +gcm_gmult_neon: + AARCH64_VALID_CALL_TARGET + ld1 {v3.16b}, [x0] // load Xi + ld1 {v5.1d}, [x1], #8 // load twisted H + ld1 {v6.1d}, [x1] + adrp x9, .Lmasks // load constants + add x9, x9, :lo12:.Lmasks + ld1 {v24.2d, v25.2d}, [x9] + rev64 v3.16b, v3.16b // byteswap Xi + ext v3.16b, v3.16b, v3.16b, #8 + eor v7.8b, v5.8b, v6.8b // Karatsuba pre-processing + + mov x3, #16 + b .Lgmult_neon +.size gcm_gmult_neon,.-gcm_gmult_neon + +.globl gcm_ghash_neon +.hidden gcm_ghash_neon +.type gcm_ghash_neon,%function +.align 4 +gcm_ghash_neon: + AARCH64_VALID_CALL_TARGET + ld1 {v0.16b}, [x0] // load Xi + ld1 {v5.1d}, [x1], #8 // load twisted H + ld1 {v6.1d}, [x1] + adrp x9, .Lmasks // load constants + add x9, x9, :lo12:.Lmasks + ld1 {v24.2d, v25.2d}, [x9] + rev64 v0.16b, v0.16b // byteswap Xi + ext v0.16b, v0.16b, v0.16b, #8 + eor v7.8b, v5.8b, v6.8b // Karatsuba pre-processing + +.Loop_neon: + ld1 {v3.16b}, [x2], #16 // load inp + rev64 v3.16b, v3.16b // byteswap inp + ext v3.16b, v3.16b, v3.16b, #8 + eor v3.16b, v3.16b, v0.16b // inp ^= Xi + +.Lgmult_neon: + // Split the input into v3 and v4. (The upper halves are unused, + // so it is okay to leave them alone.) + ins v4.d[0], v3.d[1] + ext v16.8b, v5.8b, v5.8b, #1 // A1 + pmull v16.8h, v16.8b, v3.8b // F = A1*B + ext v0.8b, v3.8b, v3.8b, #1 // B1 + pmull v0.8h, v5.8b, v0.8b // E = A*B1 + ext v17.8b, v5.8b, v5.8b, #2 // A2 + pmull v17.8h, v17.8b, v3.8b // H = A2*B + ext v19.8b, v3.8b, v3.8b, #2 // B2 + pmull v19.8h, v5.8b, v19.8b // G = A*B2 + ext v18.8b, v5.8b, v5.8b, #3 // A3 + eor v16.16b, v16.16b, v0.16b // L = E + F + pmull v18.8h, v18.8b, v3.8b // J = A3*B + ext v0.8b, v3.8b, v3.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v0.8h, v5.8b, v0.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v3.8b, v3.8b, #4 // B4 + eor v18.16b, v18.16b, v0.16b // N = I + J + pmull v19.8h, v5.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v0.8h, v5.8b, v3.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v0.16b, v0.16b, v16.16b + eor v0.16b, v0.16b, v18.16b + eor v3.8b, v3.8b, v4.8b // Karatsuba pre-processing + ext v16.8b, v7.8b, v7.8b, #1 // A1 + pmull v16.8h, v16.8b, v3.8b // F = A1*B + ext v1.8b, v3.8b, v3.8b, #1 // B1 + pmull v1.8h, v7.8b, v1.8b // E = A*B1 + ext v17.8b, v7.8b, v7.8b, #2 // A2 + pmull v17.8h, v17.8b, v3.8b // H = A2*B + ext v19.8b, v3.8b, v3.8b, #2 // B2 + pmull v19.8h, v7.8b, v19.8b // G = A*B2 + ext v18.8b, v7.8b, v7.8b, #3 // A3 + eor v16.16b, v16.16b, v1.16b // L = E + F + pmull v18.8h, v18.8b, v3.8b // J = A3*B + ext v1.8b, v3.8b, v3.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v1.8h, v7.8b, v1.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v3.8b, v3.8b, #4 // B4 + eor v18.16b, v18.16b, v1.16b // N = I + J + pmull v19.8h, v7.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v1.8h, v7.8b, v3.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v1.16b, v1.16b, v16.16b + eor v1.16b, v1.16b, v18.16b + ext v16.8b, v6.8b, v6.8b, #1 // A1 + pmull v16.8h, v16.8b, v4.8b // F = A1*B + ext v2.8b, v4.8b, v4.8b, #1 // B1 + pmull v2.8h, v6.8b, v2.8b // E = A*B1 + ext v17.8b, v6.8b, v6.8b, #2 // A2 + pmull v17.8h, v17.8b, v4.8b // H = A2*B + ext v19.8b, v4.8b, v4.8b, #2 // B2 + pmull v19.8h, v6.8b, v19.8b // G = A*B2 + ext v18.8b, v6.8b, v6.8b, #3 // A3 + eor v16.16b, v16.16b, v2.16b // L = E + F + pmull v18.8h, v18.8b, v4.8b // J = A3*B + ext v2.8b, v4.8b, v4.8b, #3 // B3 + eor v17.16b, v17.16b, v19.16b // M = G + H + pmull v2.8h, v6.8b, v2.8b // I = A*B3 + + // Here we diverge from the 32-bit version. It computes the following + // (instructions reordered for clarity): + // + // veor $t0#lo, $t0#lo, $t0#hi @ t0 = P0 + P1 (L) + // vand $t0#hi, $t0#hi, $k48 + // veor $t0#lo, $t0#lo, $t0#hi + // + // veor $t1#lo, $t1#lo, $t1#hi @ t1 = P2 + P3 (M) + // vand $t1#hi, $t1#hi, $k32 + // veor $t1#lo, $t1#lo, $t1#hi + // + // veor $t2#lo, $t2#lo, $t2#hi @ t2 = P4 + P5 (N) + // vand $t2#hi, $t2#hi, $k16 + // veor $t2#lo, $t2#lo, $t2#hi + // + // veor $t3#lo, $t3#lo, $t3#hi @ t3 = P6 + P7 (K) + // vmov.i64 $t3#hi, #0 + // + // $kN is a mask with the bottom N bits set. AArch64 cannot compute on + // upper halves of SIMD registers, so we must split each half into + // separate registers. To compensate, we pair computations up and + // parallelize. + + ext v19.8b, v4.8b, v4.8b, #4 // B4 + eor v18.16b, v18.16b, v2.16b // N = I + J + pmull v19.8h, v6.8b, v19.8b // K = A*B4 + + // This can probably be scheduled more efficiently. For now, we just + // pair up independent instructions. + zip1 v20.2d, v16.2d, v17.2d + zip1 v22.2d, v18.2d, v19.2d + zip2 v21.2d, v16.2d, v17.2d + zip2 v23.2d, v18.2d, v19.2d + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + and v21.16b, v21.16b, v24.16b + and v23.16b, v23.16b, v25.16b + eor v20.16b, v20.16b, v21.16b + eor v22.16b, v22.16b, v23.16b + zip1 v16.2d, v20.2d, v21.2d + zip1 v18.2d, v22.2d, v23.2d + zip2 v17.2d, v20.2d, v21.2d + zip2 v19.2d, v22.2d, v23.2d + + ext v16.16b, v16.16b, v16.16b, #15 // t0 = t0 << 8 + ext v17.16b, v17.16b, v17.16b, #14 // t1 = t1 << 16 + pmull v2.8h, v6.8b, v4.8b // D = A*B + ext v19.16b, v19.16b, v19.16b, #12 // t3 = t3 << 32 + ext v18.16b, v18.16b, v18.16b, #13 // t2 = t2 << 24 + eor v16.16b, v16.16b, v17.16b + eor v18.16b, v18.16b, v19.16b + eor v2.16b, v2.16b, v16.16b + eor v2.16b, v2.16b, v18.16b + ext v16.16b, v0.16b, v2.16b, #8 + eor v1.16b, v1.16b, v0.16b // Karatsuba post-processing + eor v1.16b, v1.16b, v2.16b + eor v1.16b, v1.16b, v16.16b // Xm overlaps Xh.lo and Xl.hi + ins v0.d[1], v1.d[0] // Xh|Xl - 256-bit result + // This is a no-op due to the ins instruction below. + // ins v2.d[0], v1.d[1] + + // equivalent of reduction_avx from ghash-x86_64.pl + shl v17.2d, v0.2d, #57 // 1st phase + shl v18.2d, v0.2d, #62 + eor v18.16b, v18.16b, v17.16b // + shl v17.2d, v0.2d, #63 + eor v18.16b, v18.16b, v17.16b // + // Note Xm contains {Xl.d[1], Xh.d[0]}. + eor v18.16b, v18.16b, v1.16b + ins v0.d[1], v18.d[0] // Xl.d[1] ^= t2.d[0] + ins v2.d[0], v18.d[1] // Xh.d[0] ^= t2.d[1] + + ushr v18.2d, v0.2d, #1 // 2nd phase + eor v2.16b, v2.16b,v0.16b + eor v0.16b, v0.16b,v18.16b // + ushr v18.2d, v18.2d, #6 + ushr v0.2d, v0.2d, #1 // + eor v0.16b, v0.16b, v2.16b // + eor v0.16b, v0.16b, v18.16b // + + subs x3, x3, #16 + bne .Loop_neon + + rev64 v0.16b, v0.16b // byteswap Xi and write + ext v0.16b, v0.16b, v0.16b, #8 + st1 {v0.16b}, [x0] + + ret +.size gcm_ghash_neon,.-gcm_ghash_neon + +.section .rodata +.align 4 +.Lmasks: +.quad 0x0000ffffffffffff // k48 +.quad 0x00000000ffffffff // k32 +.quad 0x000000000000ffff // k16 +.quad 0x0000000000000000 // k0 +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S new file mode 100644 index 00000000..08324bff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S @@ -0,0 +1,301 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl gcm_gmult_ssse3 +.hidden gcm_gmult_ssse3 +.type gcm_gmult_ssse3,@function +.align 16 +gcm_gmult_ssse3: +.L_gcm_gmult_ssse3_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movdqu (%edi),%xmm0 + call .L000pic_point +.L000pic_point: + popl %eax + movdqa .Lreverse_bytes-.L000pic_point(%eax),%xmm7 + movdqa .Llow4_mask-.L000pic_point(%eax),%xmm2 +.byte 102,15,56,0,199 + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + movl $5,%eax +.L001loop_row_1: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L001loop_row_1 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movl $5,%eax +.L002loop_row_2: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L002loop_row_2 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movl $6,%eax +.L003loop_row_3: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L003loop_row_3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,0,215 + movdqu %xmm2,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_gmult_ssse3,.-.L_gcm_gmult_ssse3_begin +.globl gcm_ghash_ssse3 +.hidden gcm_ghash_ssse3 +.type gcm_ghash_ssse3,@function +.align 16 +gcm_ghash_ssse3: +.L_gcm_ghash_ssse3_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%edx + movl 32(%esp),%ecx + movdqu (%edi),%xmm0 + call .L004pic_point +.L004pic_point: + popl %ebx + movdqa .Lreverse_bytes-.L004pic_point(%ebx),%xmm7 + andl $-16,%ecx +.byte 102,15,56,0,199 + pxor %xmm3,%xmm3 +.L005loop_ghash: + movdqa .Llow4_mask-.L004pic_point(%ebx),%xmm2 + movdqu (%edx),%xmm1 +.byte 102,15,56,0,207 + pxor %xmm1,%xmm0 + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + pxor %xmm2,%xmm2 + movl $5,%eax +.L006loop_row_4: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L006loop_row_4 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movl $5,%eax +.L007loop_row_5: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L007loop_row_5 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movl $6,%eax +.L008loop_row_6: + movdqa (%esi),%xmm4 + leal 16(%esi),%esi + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + pxor %xmm5,%xmm2 + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + subl $1,%eax + jnz .L008loop_row_6 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movdqa %xmm2,%xmm0 + leal -256(%esi),%esi + leal 16(%edx),%edx + subl $16,%ecx + jnz .L005loop_ghash +.byte 102,15,56,0,199 + movdqu %xmm0,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_ghash_ssse3,.-.L_gcm_ghash_ssse3_begin +.align 16 +.Lreverse_bytes: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.align 16 +.Llow4_mask: +.long 252645135,252645135,252645135,252645135 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S new file mode 100644 index 00000000..814d88bf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S @@ -0,0 +1,434 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + + +.type gcm_gmult_ssse3, @function +.globl gcm_gmult_ssse3 +.hidden gcm_gmult_ssse3 +.align 16 +gcm_gmult_ssse3: +.cfi_startproc +.Lgmult_seh_begin: + movdqu (%rdi),%xmm0 + movdqa .Lreverse_bytes(%rip),%xmm10 + movdqa .Llow4_mask(%rip),%xmm2 + + +.byte 102,65,15,56,0,194 + + + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + + + + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +.Loop_row_1: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_1 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +.Loop_row_2: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_2 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $6,%rax +.Loop_row_3: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_3 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + +.byte 102,65,15,56,0,210 + movdqu %xmm2,(%rdi) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +.Lgmult_seh_end: +.cfi_endproc +.size gcm_gmult_ssse3,.-gcm_gmult_ssse3 + + + + + +.type gcm_ghash_ssse3, @function +.globl gcm_ghash_ssse3 +.hidden gcm_ghash_ssse3 +.align 16 +gcm_ghash_ssse3: +.Lghash_seh_begin: +.cfi_startproc + movdqu (%rdi),%xmm0 + movdqa .Lreverse_bytes(%rip),%xmm10 + movdqa .Llow4_mask(%rip),%xmm11 + + + andq $-16,%rcx + + + +.byte 102,65,15,56,0,194 + + + pxor %xmm3,%xmm3 +.Loop_ghash: + + movdqu (%rdx),%xmm1 +.byte 102,65,15,56,0,202 + pxor %xmm1,%xmm0 + + + movdqa %xmm11,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm11,%xmm0 + + + + + pxor %xmm2,%xmm2 + + movq $5,%rax +.Loop_row_4: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_4 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +.Loop_row_5: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_5 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $6,%rax +.Loop_row_6: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz .Loop_row_6 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movdqa %xmm2,%xmm0 + + + leaq -256(%rsi),%rsi + + + leaq 16(%rdx),%rdx + subq $16,%rcx + jnz .Loop_ghash + + +.byte 102,65,15,56,0,194 + movdqu %xmm0,(%rdi) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +.Lghash_seh_end: +.cfi_endproc +.size gcm_ghash_ssse3,.-gcm_ghash_ssse3 + +.align 16 + + +.Lreverse_bytes: +.byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + +.Llow4_mask: +.quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S new file mode 100644 index 00000000..da8a4ef4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S @@ -0,0 +1,433 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + + + +.globl _gcm_gmult_ssse3 +.private_extern _gcm_gmult_ssse3 +.p2align 4 +_gcm_gmult_ssse3: + +L$gmult_seh_begin: + movdqu (%rdi),%xmm0 + movdqa L$reverse_bytes(%rip),%xmm10 + movdqa L$low4_mask(%rip),%xmm2 + + +.byte 102,65,15,56,0,194 + + + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + + + + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +L$oop_row_1: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_1 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +L$oop_row_2: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_2 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $6,%rax +L$oop_row_3: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_3 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + +.byte 102,65,15,56,0,210 + movdqu %xmm2,(%rdi) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +L$gmult_seh_end: + + + + + + + + +.globl _gcm_ghash_ssse3 +.private_extern _gcm_ghash_ssse3 +.p2align 4 +_gcm_ghash_ssse3: +L$ghash_seh_begin: + + movdqu (%rdi),%xmm0 + movdqa L$reverse_bytes(%rip),%xmm10 + movdqa L$low4_mask(%rip),%xmm11 + + + andq $-16,%rcx + + + +.byte 102,65,15,56,0,194 + + + pxor %xmm3,%xmm3 +L$oop_ghash: + + movdqu (%rdx),%xmm1 +.byte 102,65,15,56,0,202 + pxor %xmm1,%xmm0 + + + movdqa %xmm11,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm11,%xmm0 + + + + + pxor %xmm2,%xmm2 + + movq $5,%rax +L$oop_row_4: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_4 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $5,%rax +L$oop_row_5: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_5 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movq $6,%rax +L$oop_row_6: + movdqa (%rsi),%xmm4 + leaq 16(%rsi),%rsi + + + movdqa %xmm2,%xmm6 +.byte 102,15,58,15,243,1 + movdqa %xmm6,%xmm3 + psrldq $1,%xmm2 + + + + + movdqa %xmm4,%xmm5 +.byte 102,15,56,0,224 +.byte 102,15,56,0,233 + + + pxor %xmm5,%xmm2 + + + + movdqa %xmm4,%xmm5 + psllq $60,%xmm5 + movdqa %xmm5,%xmm6 + pslldq $8,%xmm6 + pxor %xmm6,%xmm3 + + + psrldq $8,%xmm5 + pxor %xmm5,%xmm2 + psrlq $4,%xmm4 + pxor %xmm4,%xmm2 + + subq $1,%rax + jnz L$oop_row_6 + + + + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $1,%xmm3 + pxor %xmm3,%xmm2 + psrlq $5,%xmm3 + pxor %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movdqa %xmm2,%xmm0 + + + leaq -256(%rsi),%rsi + + + leaq 16(%rdx),%rdx + subq $16,%rcx + jnz L$oop_ghash + + +.byte 102,65,15,56,0,194 + movdqu %xmm0,(%rdi) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +L$ghash_seh_end: + + + +.p2align 4 + + +L$reverse_bytes: +.byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + +L$low4_mask: +.quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S new file mode 100644 index 00000000..859e740b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S @@ -0,0 +1,337 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl gcm_init_clmul +.hidden gcm_init_clmul +.type gcm_init_clmul,@function +.align 16 +gcm_init_clmul: +.L_gcm_init_clmul_begin: + movl 4(%esp),%edx + movl 8(%esp),%eax + call .L000pic +.L000pic: + popl %ecx + leal .Lbswap-.L000pic(%ecx),%ecx + movdqu (%eax),%xmm2 + pshufd $78,%xmm2,%xmm2 + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + pand 16(%ecx),%xmm5 + pxor %xmm5,%xmm2 + movdqa %xmm2,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm2,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm2,%xmm3 + movdqu %xmm2,(%edx) + pxor %xmm0,%xmm4 + movdqu %xmm0,16(%edx) +.byte 102,15,58,15,227,8 + movdqu %xmm4,32(%edx) + ret +.size gcm_init_clmul,.-.L_gcm_init_clmul_begin +.globl gcm_gmult_clmul +.hidden gcm_gmult_clmul +.type gcm_gmult_clmul,@function +.align 16 +gcm_gmult_clmul: +.L_gcm_gmult_clmul_begin: + movl 4(%esp),%eax + movl 8(%esp),%edx + call .L001pic +.L001pic: + popl %ecx + leal .Lbswap-.L001pic(%ecx),%ecx + movdqu (%eax),%xmm0 + movdqa (%ecx),%xmm5 + movups (%edx),%xmm2 +.byte 102,15,56,0,197 + movups 32(%edx),%xmm4 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%eax) + ret +.size gcm_gmult_clmul,.-.L_gcm_gmult_clmul_begin +.globl gcm_ghash_clmul +.hidden gcm_ghash_clmul +.type gcm_ghash_clmul,@function +.align 16 +gcm_ghash_clmul: +.L_gcm_ghash_clmul_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%eax + movl 24(%esp),%edx + movl 28(%esp),%esi + movl 32(%esp),%ebx + call .L002pic +.L002pic: + popl %ecx + leal .Lbswap-.L002pic(%ecx),%ecx + movdqu (%eax),%xmm0 + movdqa (%ecx),%xmm5 + movdqu (%edx),%xmm2 +.byte 102,15,56,0,197 + subl $16,%ebx + jz .L003odd_tail + movdqu (%esi),%xmm3 + movdqu 16(%esi),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + movdqu 32(%edx),%xmm5 + pxor %xmm3,%xmm0 + pshufd $78,%xmm6,%xmm3 + movdqa %xmm6,%xmm7 + pxor %xmm6,%xmm3 + leal 32(%esi),%esi +.byte 102,15,58,68,242,0 +.byte 102,15,58,68,250,17 +.byte 102,15,58,68,221,0 + movups 16(%edx),%xmm2 + nop + subl $32,%ebx + jbe .L004even_tail + jmp .L005mod_loop +.align 32 +.L005mod_loop: + pshufd $78,%xmm0,%xmm4 + movdqa %xmm0,%xmm1 + pxor %xmm0,%xmm4 + nop +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,229,16 + movups (%edx),%xmm2 + xorps %xmm6,%xmm0 + movdqa (%ecx),%xmm5 + xorps %xmm7,%xmm1 + movdqu (%esi),%xmm7 + pxor %xmm0,%xmm3 + movdqu 16(%esi),%xmm6 + pxor %xmm1,%xmm3 +.byte 102,15,56,0,253 + pxor %xmm3,%xmm4 + movdqa %xmm4,%xmm3 + psrldq $8,%xmm4 + pslldq $8,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm3,%xmm0 +.byte 102,15,56,0,245 + pxor %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 +.byte 102,15,58,68,242,0 + movups 32(%edx),%xmm5 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + pshufd $78,%xmm7,%xmm3 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm7,%xmm3 + pxor %xmm4,%xmm1 +.byte 102,15,58,68,250,17 + movups 16(%edx),%xmm2 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,58,68,221,0 + leal 32(%esi),%esi + subl $32,%ebx + ja .L005mod_loop +.L004even_tail: + pshufd $78,%xmm0,%xmm4 + movdqa %xmm0,%xmm1 + pxor %xmm0,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,229,16 + movdqa (%ecx),%xmm5 + xorps %xmm6,%xmm0 + xorps %xmm7,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm3,%xmm4 + movdqa %xmm4,%xmm3 + psrldq $8,%xmm4 + pslldq $8,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + testl %ebx,%ebx + jnz .L006done + movups (%edx),%xmm2 +.L003odd_tail: + movdqu (%esi),%xmm3 +.byte 102,15,56,0,221 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.L006done: +.byte 102,15,56,0,197 + movdqu %xmm0,(%eax) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_ghash_clmul,.-.L_gcm_ghash_clmul_begin +.align 64 +.Lbswap: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,194 +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,44,32,67 +.byte 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 +.byte 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 +.byte 0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S new file mode 100644 index 00000000..eca324c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S @@ -0,0 +1,1134 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P +.globl gcm_init_clmul +.hidden gcm_init_clmul +.type gcm_init_clmul,@function +.align 16 +gcm_init_clmul: +.cfi_startproc +.L_init_clmul: + movdqu (%rsi),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand .L0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + pshufd $78,%xmm2,%xmm6 + movdqa %xmm2,%xmm0 + pxor %xmm2,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm2,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm2,%xmm3 + movdqu %xmm2,0(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,16(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,32(%rdi) + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm5 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm5,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm5,%xmm3 + movdqu %xmm5,48(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,64(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,80(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_init_clmul,.-gcm_init_clmul +.globl gcm_gmult_clmul +.hidden gcm_gmult_clmul +.type gcm_gmult_clmul,@function +.align 16 +gcm_gmult_clmul: +.cfi_startproc +.L_gmult_clmul: + movdqu (%rdi),%xmm0 + movdqa .Lbswap_mask(%rip),%xmm5 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm4 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_gmult_clmul,.-gcm_gmult_clmul +.globl gcm_ghash_clmul +.hidden gcm_ghash_clmul +.type gcm_ghash_clmul,@function +.align 32 +gcm_ghash_clmul: +.cfi_startproc +.L_ghash_clmul: + movdqa .Lbswap_mask(%rip),%xmm10 + + movdqu (%rdi),%xmm0 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm7 +.byte 102,65,15,56,0,194 + + subq $0x10,%rcx + jz .Lodd_tail + + movdqu 16(%rsi),%xmm6 + leaq OPENSSL_ia32cap_P(%rip),%rax + movl 4(%rax),%eax + cmpq $0x30,%rcx + jb .Lskip4x + + andl $71303168,%eax + cmpl $4194304,%eax + je .Lskip4x + + subq $0x30,%rcx + movq $0xA040608020C0E000,%rax + movdqu 48(%rsi),%xmm14 + movdqu 64(%rsi),%xmm15 + + + + + movdqu 48(%rdx),%xmm3 + movdqu 32(%rdx),%xmm11 +.byte 102,65,15,56,0,218 +.byte 102,69,15,56,0,218 + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm11,%xmm12 +.byte 102,68,15,58,68,222,0 +.byte 102,68,15,58,68,238,17 +.byte 102,68,15,58,68,231,16 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 + xorps %xmm12,%xmm4 + + movdqu 16(%rdx),%xmm11 + movdqu 0(%rdx),%xmm8 +.byte 102,69,15,56,0,218 +.byte 102,69,15,56,0,194 + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm8,%xmm0 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 +.byte 102,69,15,58,68,238,17 +.byte 102,68,15,58,68,231,0 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jc .Ltail4x + + jmp .Lmod4_loop +.align 32 +.Lmod4_loop: +.byte 102,65,15,58,68,199,0 + xorps %xmm12,%xmm4 + movdqu 48(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,65,15,58,68,207,17 + xorps %xmm3,%xmm0 + movdqu 32(%rdx),%xmm3 + movdqa %xmm11,%xmm13 +.byte 102,68,15,58,68,199,16 + pshufd $78,%xmm11,%xmm12 + xorps %xmm5,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,65,15,56,0,218 + movups 32(%rsi),%xmm7 + xorps %xmm4,%xmm8 +.byte 102,68,15,58,68,218,0 + pshufd $78,%xmm3,%xmm4 + + pxor %xmm0,%xmm8 + movdqa %xmm3,%xmm5 + pxor %xmm1,%xmm8 + pxor %xmm3,%xmm4 + movdqa %xmm8,%xmm9 +.byte 102,68,15,58,68,234,17 + pslldq $8,%xmm8 + psrldq $8,%xmm9 + pxor %xmm8,%xmm0 + movdqa .L7_mask(%rip),%xmm8 + pxor %xmm9,%xmm1 +.byte 102,76,15,110,200 + + pand %xmm0,%xmm8 +.byte 102,69,15,56,0,200 + pxor %xmm0,%xmm9 +.byte 102,68,15,58,68,231,0 + psllq $57,%xmm9 + movdqa %xmm9,%xmm8 + pslldq $8,%xmm9 +.byte 102,15,58,68,222,0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + movdqu 0(%rdx),%xmm8 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,238,17 + xorps %xmm11,%xmm3 + movdqu 16(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,15,58,68,231,16 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 +.byte 102,69,15,56,0,194 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + + movdqa %xmm11,%xmm13 + pxor %xmm12,%xmm4 + pshufd $78,%xmm11,%xmm12 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm1 +.byte 102,69,15,58,68,238,17 + xorps %xmm11,%xmm3 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 + +.byte 102,68,15,58,68,231,0 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jnc .Lmod4_loop + +.Ltail4x: +.byte 102,65,15,58,68,199,0 +.byte 102,65,15,58,68,207,17 +.byte 102,68,15,58,68,199,16 + xorps %xmm12,%xmm4 + xorps %xmm3,%xmm0 + xorps %xmm5,%xmm1 + pxor %xmm0,%xmm1 + pxor %xmm4,%xmm8 + + pxor %xmm1,%xmm8 + pxor %xmm0,%xmm1 + + movdqa %xmm8,%xmm9 + psrldq $8,%xmm8 + pslldq $8,%xmm9 + pxor %xmm8,%xmm1 + pxor %xmm9,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + addq $0x40,%rcx + jz .Ldone + movdqu 32(%rsi),%xmm7 + subq $0x10,%rcx + jz .Lodd_tail +.Lskip4x: + + + + + + movdqu (%rdx),%xmm8 + movdqu 16(%rdx),%xmm3 +.byte 102,69,15,56,0,194 +.byte 102,65,15,56,0,218 + pxor %xmm8,%xmm0 + + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + leaq 32(%rdx),%rdx + nop + subq $0x20,%rcx + jbe .Leven_tail + nop + jmp .Lmod_loop + +.align 32 +.Lmod_loop: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + movdqu (%rdx),%xmm9 + pxor %xmm0,%xmm8 +.byte 102,69,15,56,0,202 + movdqu 16(%rdx),%xmm3 + + pxor %xmm1,%xmm8 + pxor %xmm9,%xmm1 + pxor %xmm8,%xmm4 +.byte 102,65,15,56,0,218 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm3,%xmm5 + + movdqa %xmm0,%xmm9 + movdqa %xmm0,%xmm8 + psllq $5,%xmm0 + pxor %xmm0,%xmm8 +.byte 102,15,58,68,218,0 + psllq $1,%xmm0 + pxor %xmm8,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm8 + pslldq $8,%xmm0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pshufd $78,%xmm5,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm5,%xmm4 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,234,17 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + pxor %xmm9,%xmm0 + leaq 32(%rdx),%rdx + psrlq $1,%xmm0 +.byte 102,15,58,68,231,0 + pxor %xmm1,%xmm0 + + subq $0x20,%rcx + ja .Lmod_loop + +.Leven_tail: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + pxor %xmm0,%xmm8 + pxor %xmm1,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + testq %rcx,%rcx + jnz .Ldone + +.Lodd_tail: + movdqu (%rdx),%xmm8 +.byte 102,69,15,56,0,194 + pxor %xmm8,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,223,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.Ldone: +.byte 102,65,15,56,0,194 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_ghash_clmul,.-gcm_ghash_clmul +.globl gcm_init_avx +.hidden gcm_init_avx +.type gcm_init_avx,@function +.align 32 +gcm_init_avx: +.cfi_startproc + vzeroupper + + vmovdqu (%rsi),%xmm2 + vpshufd $78,%xmm2,%xmm2 + + + vpshufd $255,%xmm2,%xmm4 + vpsrlq $63,%xmm2,%xmm3 + vpsllq $1,%xmm2,%xmm2 + vpxor %xmm5,%xmm5,%xmm5 + vpcmpgtd %xmm4,%xmm5,%xmm5 + vpslldq $8,%xmm3,%xmm3 + vpor %xmm3,%xmm2,%xmm2 + + + vpand .L0x1c2_polynomial(%rip),%xmm5,%xmm5 + vpxor %xmm5,%xmm2,%xmm2 + + vpunpckhqdq %xmm2,%xmm2,%xmm6 + vmovdqa %xmm2,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + movq $4,%r10 + jmp .Linit_start_avx +.align 32 +.Linit_loop_avx: + vpalignr $8,%xmm3,%xmm4,%xmm5 + vmovdqu %xmm5,-16(%rdi) + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 +.Linit_start_avx: + vmovdqa %xmm0,%xmm5 + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + vpshufd $78,%xmm5,%xmm3 + vpshufd $78,%xmm0,%xmm4 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqu %xmm5,0(%rdi) + vpxor %xmm0,%xmm4,%xmm4 + vmovdqu %xmm0,16(%rdi) + leaq 48(%rdi),%rdi + subq $1,%r10 + jnz .Linit_loop_avx + + vpalignr $8,%xmm4,%xmm3,%xmm5 + vmovdqu %xmm5,-16(%rdi) + + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_init_avx,.-gcm_init_avx +.globl gcm_gmult_avx +.hidden gcm_gmult_avx +.type gcm_gmult_avx,@function +.align 32 +gcm_gmult_avx: +.cfi_startproc + jmp .L_gmult_clmul +.cfi_endproc +.size gcm_gmult_avx,.-gcm_gmult_avx +.globl gcm_ghash_avx +.hidden gcm_ghash_avx +.type gcm_ghash_avx,@function +.align 32 +gcm_ghash_avx: +.cfi_startproc + vzeroupper + + vmovdqu (%rdi),%xmm10 + leaq .L0x1c2_polynomial(%rip),%r10 + leaq 64(%rsi),%rsi + vmovdqu .Lbswap_mask(%rip),%xmm13 + vpshufb %xmm13,%xmm10,%xmm10 + cmpq $0x80,%rcx + jb .Lshort_avx + subq $0x80,%rcx + + vmovdqu 112(%rdx),%xmm14 + vmovdqu 0-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vmovdqu 32-64(%rsi),%xmm7 + + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm14,%xmm9,%xmm9 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 80(%rdx),%xmm14 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 48-64(%rsi),%xmm6 + vpxor %xmm14,%xmm9,%xmm9 + vmovdqu 64(%rdx),%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 48(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 32(%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 16(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu (%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + + leaq 128(%rdx),%rdx + cmpq $0x80,%rcx + jb .Ltail_avx + + vpxor %xmm10,%xmm15,%xmm15 + subq $0x80,%rcx + jmp .Loop8x_avx + +.align 32 +.Loop8x_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 112(%rdx),%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpxor %xmm15,%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm10 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm11 + vmovdqu 0-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm12 + vmovdqu 32-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm3,%xmm10,%xmm10 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vxorps %xmm4,%xmm11,%xmm11 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm5,%xmm12,%xmm12 + vxorps %xmm15,%xmm8,%xmm8 + + vmovdqu 80(%rdx),%xmm14 + vpxor %xmm10,%xmm12,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm11,%xmm12,%xmm12 + vpslldq $8,%xmm12,%xmm9 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vpsrldq $8,%xmm12,%xmm12 + vpxor %xmm9,%xmm10,%xmm10 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vxorps %xmm12,%xmm11,%xmm11 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 64(%rdx),%xmm15 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vxorps %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + + vmovdqu 48(%rdx),%xmm14 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 32(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + vxorps %xmm12,%xmm10,%xmm10 + + vmovdqu 16(%rdx),%xmm14 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vxorps %xmm11,%xmm12,%xmm12 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu (%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm12,%xmm15,%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + vpxor %xmm10,%xmm15,%xmm15 + + leaq 128(%rdx),%rdx + subq $0x80,%rcx + jnc .Loop8x_avx + + addq $0x80,%rcx + jmp .Ltail_no_xor_avx + +.align 32 +.Lshort_avx: + vmovdqu -16(%rdx,%rcx,1),%xmm14 + leaq (%rdx,%rcx,1),%rdx + vmovdqu 0-64(%rsi),%xmm6 + vmovdqu 32-64(%rsi),%xmm7 + vpshufb %xmm13,%xmm14,%xmm15 + + vmovdqa %xmm0,%xmm3 + vmovdqa %xmm1,%xmm4 + vmovdqa %xmm2,%xmm5 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -32(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -48(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 80-64(%rsi),%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -64(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -80(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 96-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 128-64(%rsi),%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -96(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -112(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 144-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovq 184-64(%rsi),%xmm7 + subq $0x10,%rcx + jmp .Ltail_avx + +.align 32 +.Ltail_avx: + vpxor %xmm10,%xmm15,%xmm15 +.Ltail_no_xor_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + + vmovdqu (%r10),%xmm12 + + vpxor %xmm0,%xmm3,%xmm10 + vpxor %xmm1,%xmm4,%xmm11 + vpxor %xmm2,%xmm5,%xmm5 + + vpxor %xmm10,%xmm5,%xmm5 + vpxor %xmm11,%xmm5,%xmm5 + vpslldq $8,%xmm5,%xmm9 + vpsrldq $8,%xmm5,%xmm5 + vpxor %xmm9,%xmm10,%xmm10 + vpxor %xmm5,%xmm11,%xmm11 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm11,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + cmpq $0,%rcx + jne .Lshort_avx + + vpshufb %xmm13,%xmm10,%xmm10 + vmovdqu %xmm10,(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_ghash_avx,.-gcm_ghash_avx +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.L0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.L7_mask: +.long 7,0,7,0 +.align 64 + +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S new file mode 100644 index 00000000..ccbc7f3c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S @@ -0,0 +1,1132 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.globl _gcm_init_clmul +.private_extern _gcm_init_clmul + +.p2align 4 +_gcm_init_clmul: + +L$_init_clmul: + movdqu (%rsi),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand L$0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + pshufd $78,%xmm2,%xmm6 + movdqa %xmm2,%xmm0 + pxor %xmm2,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm2,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm2,%xmm3 + movdqu %xmm2,0(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,16(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,32(%rdi) + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm5 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm5,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm5,%xmm3 + movdqu %xmm5,48(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,64(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,80(%rdi) + .byte 0xf3,0xc3 + + +.globl _gcm_gmult_clmul +.private_extern _gcm_gmult_clmul + +.p2align 4 +_gcm_gmult_clmul: + +L$_gmult_clmul: + movdqu (%rdi),%xmm0 + movdqa L$bswap_mask(%rip),%xmm5 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm4 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 + + +.globl _gcm_ghash_clmul +.private_extern _gcm_ghash_clmul + +.p2align 5 +_gcm_ghash_clmul: + +L$_ghash_clmul: + movdqa L$bswap_mask(%rip),%xmm10 + + movdqu (%rdi),%xmm0 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm7 +.byte 102,65,15,56,0,194 + + subq $0x10,%rcx + jz L$odd_tail + + movdqu 16(%rsi),%xmm6 + leaq _OPENSSL_ia32cap_P(%rip),%rax + movl 4(%rax),%eax + cmpq $0x30,%rcx + jb L$skip4x + + andl $71303168,%eax + cmpl $4194304,%eax + je L$skip4x + + subq $0x30,%rcx + movq $0xA040608020C0E000,%rax + movdqu 48(%rsi),%xmm14 + movdqu 64(%rsi),%xmm15 + + + + + movdqu 48(%rdx),%xmm3 + movdqu 32(%rdx),%xmm11 +.byte 102,65,15,56,0,218 +.byte 102,69,15,56,0,218 + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm11,%xmm12 +.byte 102,68,15,58,68,222,0 +.byte 102,68,15,58,68,238,17 +.byte 102,68,15,58,68,231,16 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 + xorps %xmm12,%xmm4 + + movdqu 16(%rdx),%xmm11 + movdqu 0(%rdx),%xmm8 +.byte 102,69,15,56,0,218 +.byte 102,69,15,56,0,194 + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm8,%xmm0 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 +.byte 102,69,15,58,68,238,17 +.byte 102,68,15,58,68,231,0 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jc L$tail4x + + jmp L$mod4_loop +.p2align 5 +L$mod4_loop: +.byte 102,65,15,58,68,199,0 + xorps %xmm12,%xmm4 + movdqu 48(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,65,15,58,68,207,17 + xorps %xmm3,%xmm0 + movdqu 32(%rdx),%xmm3 + movdqa %xmm11,%xmm13 +.byte 102,68,15,58,68,199,16 + pshufd $78,%xmm11,%xmm12 + xorps %xmm5,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,65,15,56,0,218 + movups 32(%rsi),%xmm7 + xorps %xmm4,%xmm8 +.byte 102,68,15,58,68,218,0 + pshufd $78,%xmm3,%xmm4 + + pxor %xmm0,%xmm8 + movdqa %xmm3,%xmm5 + pxor %xmm1,%xmm8 + pxor %xmm3,%xmm4 + movdqa %xmm8,%xmm9 +.byte 102,68,15,58,68,234,17 + pslldq $8,%xmm8 + psrldq $8,%xmm9 + pxor %xmm8,%xmm0 + movdqa L$7_mask(%rip),%xmm8 + pxor %xmm9,%xmm1 +.byte 102,76,15,110,200 + + pand %xmm0,%xmm8 +.byte 102,69,15,56,0,200 + pxor %xmm0,%xmm9 +.byte 102,68,15,58,68,231,0 + psllq $57,%xmm9 + movdqa %xmm9,%xmm8 + pslldq $8,%xmm9 +.byte 102,15,58,68,222,0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + movdqu 0(%rdx),%xmm8 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,238,17 + xorps %xmm11,%xmm3 + movdqu 16(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,15,58,68,231,16 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 +.byte 102,69,15,56,0,194 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + + movdqa %xmm11,%xmm13 + pxor %xmm12,%xmm4 + pshufd $78,%xmm11,%xmm12 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm1 +.byte 102,69,15,58,68,238,17 + xorps %xmm11,%xmm3 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 + +.byte 102,68,15,58,68,231,0 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jnc L$mod4_loop + +L$tail4x: +.byte 102,65,15,58,68,199,0 +.byte 102,65,15,58,68,207,17 +.byte 102,68,15,58,68,199,16 + xorps %xmm12,%xmm4 + xorps %xmm3,%xmm0 + xorps %xmm5,%xmm1 + pxor %xmm0,%xmm1 + pxor %xmm4,%xmm8 + + pxor %xmm1,%xmm8 + pxor %xmm0,%xmm1 + + movdqa %xmm8,%xmm9 + psrldq $8,%xmm8 + pslldq $8,%xmm9 + pxor %xmm8,%xmm1 + pxor %xmm9,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + addq $0x40,%rcx + jz L$done + movdqu 32(%rsi),%xmm7 + subq $0x10,%rcx + jz L$odd_tail +L$skip4x: + + + + + + movdqu (%rdx),%xmm8 + movdqu 16(%rdx),%xmm3 +.byte 102,69,15,56,0,194 +.byte 102,65,15,56,0,218 + pxor %xmm8,%xmm0 + + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + leaq 32(%rdx),%rdx + nop + subq $0x20,%rcx + jbe L$even_tail + nop + jmp L$mod_loop + +.p2align 5 +L$mod_loop: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + movdqu (%rdx),%xmm9 + pxor %xmm0,%xmm8 +.byte 102,69,15,56,0,202 + movdqu 16(%rdx),%xmm3 + + pxor %xmm1,%xmm8 + pxor %xmm9,%xmm1 + pxor %xmm8,%xmm4 +.byte 102,65,15,56,0,218 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm3,%xmm5 + + movdqa %xmm0,%xmm9 + movdqa %xmm0,%xmm8 + psllq $5,%xmm0 + pxor %xmm0,%xmm8 +.byte 102,15,58,68,218,0 + psllq $1,%xmm0 + pxor %xmm8,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm8 + pslldq $8,%xmm0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pshufd $78,%xmm5,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm5,%xmm4 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,234,17 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + pxor %xmm9,%xmm0 + leaq 32(%rdx),%rdx + psrlq $1,%xmm0 +.byte 102,15,58,68,231,0 + pxor %xmm1,%xmm0 + + subq $0x20,%rcx + ja L$mod_loop + +L$even_tail: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + pxor %xmm0,%xmm8 + pxor %xmm1,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + testq %rcx,%rcx + jnz L$done + +L$odd_tail: + movdqu (%rdx),%xmm8 +.byte 102,69,15,56,0,194 + pxor %xmm8,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,223,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +L$done: +.byte 102,65,15,56,0,194 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 + + +.globl _gcm_init_avx +.private_extern _gcm_init_avx + +.p2align 5 +_gcm_init_avx: + + vzeroupper + + vmovdqu (%rsi),%xmm2 + vpshufd $78,%xmm2,%xmm2 + + + vpshufd $255,%xmm2,%xmm4 + vpsrlq $63,%xmm2,%xmm3 + vpsllq $1,%xmm2,%xmm2 + vpxor %xmm5,%xmm5,%xmm5 + vpcmpgtd %xmm4,%xmm5,%xmm5 + vpslldq $8,%xmm3,%xmm3 + vpor %xmm3,%xmm2,%xmm2 + + + vpand L$0x1c2_polynomial(%rip),%xmm5,%xmm5 + vpxor %xmm5,%xmm2,%xmm2 + + vpunpckhqdq %xmm2,%xmm2,%xmm6 + vmovdqa %xmm2,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + movq $4,%r10 + jmp L$init_start_avx +.p2align 5 +L$init_loop_avx: + vpalignr $8,%xmm3,%xmm4,%xmm5 + vmovdqu %xmm5,-16(%rdi) + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 +L$init_start_avx: + vmovdqa %xmm0,%xmm5 + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + vpshufd $78,%xmm5,%xmm3 + vpshufd $78,%xmm0,%xmm4 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqu %xmm5,0(%rdi) + vpxor %xmm0,%xmm4,%xmm4 + vmovdqu %xmm0,16(%rdi) + leaq 48(%rdi),%rdi + subq $1,%r10 + jnz L$init_loop_avx + + vpalignr $8,%xmm4,%xmm3,%xmm5 + vmovdqu %xmm5,-16(%rdi) + + vzeroupper + .byte 0xf3,0xc3 + + +.globl _gcm_gmult_avx +.private_extern _gcm_gmult_avx + +.p2align 5 +_gcm_gmult_avx: + + jmp L$_gmult_clmul + + +.globl _gcm_ghash_avx +.private_extern _gcm_ghash_avx + +.p2align 5 +_gcm_ghash_avx: + + vzeroupper + + vmovdqu (%rdi),%xmm10 + leaq L$0x1c2_polynomial(%rip),%r10 + leaq 64(%rsi),%rsi + vmovdqu L$bswap_mask(%rip),%xmm13 + vpshufb %xmm13,%xmm10,%xmm10 + cmpq $0x80,%rcx + jb L$short_avx + subq $0x80,%rcx + + vmovdqu 112(%rdx),%xmm14 + vmovdqu 0-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vmovdqu 32-64(%rsi),%xmm7 + + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm14,%xmm9,%xmm9 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 80(%rdx),%xmm14 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 48-64(%rsi),%xmm6 + vpxor %xmm14,%xmm9,%xmm9 + vmovdqu 64(%rdx),%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 48(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 32(%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 16(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu (%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + + leaq 128(%rdx),%rdx + cmpq $0x80,%rcx + jb L$tail_avx + + vpxor %xmm10,%xmm15,%xmm15 + subq $0x80,%rcx + jmp L$oop8x_avx + +.p2align 5 +L$oop8x_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 112(%rdx),%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpxor %xmm15,%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm10 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm11 + vmovdqu 0-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm12 + vmovdqu 32-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm3,%xmm10,%xmm10 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vxorps %xmm4,%xmm11,%xmm11 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm5,%xmm12,%xmm12 + vxorps %xmm15,%xmm8,%xmm8 + + vmovdqu 80(%rdx),%xmm14 + vpxor %xmm10,%xmm12,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm11,%xmm12,%xmm12 + vpslldq $8,%xmm12,%xmm9 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vpsrldq $8,%xmm12,%xmm12 + vpxor %xmm9,%xmm10,%xmm10 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vxorps %xmm12,%xmm11,%xmm11 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 64(%rdx),%xmm15 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vxorps %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + + vmovdqu 48(%rdx),%xmm14 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 32(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + vxorps %xmm12,%xmm10,%xmm10 + + vmovdqu 16(%rdx),%xmm14 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vxorps %xmm11,%xmm12,%xmm12 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu (%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm12,%xmm15,%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + vpxor %xmm10,%xmm15,%xmm15 + + leaq 128(%rdx),%rdx + subq $0x80,%rcx + jnc L$oop8x_avx + + addq $0x80,%rcx + jmp L$tail_no_xor_avx + +.p2align 5 +L$short_avx: + vmovdqu -16(%rdx,%rcx,1),%xmm14 + leaq (%rdx,%rcx,1),%rdx + vmovdqu 0-64(%rsi),%xmm6 + vmovdqu 32-64(%rsi),%xmm7 + vpshufb %xmm13,%xmm14,%xmm15 + + vmovdqa %xmm0,%xmm3 + vmovdqa %xmm1,%xmm4 + vmovdqa %xmm2,%xmm5 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -32(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -48(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 80-64(%rsi),%xmm7 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -64(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -80(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 96-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 128-64(%rsi),%xmm7 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -96(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz L$tail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -112(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 144-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovq 184-64(%rsi),%xmm7 + subq $0x10,%rcx + jmp L$tail_avx + +.p2align 5 +L$tail_avx: + vpxor %xmm10,%xmm15,%xmm15 +L$tail_no_xor_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + + vmovdqu (%r10),%xmm12 + + vpxor %xmm0,%xmm3,%xmm10 + vpxor %xmm1,%xmm4,%xmm11 + vpxor %xmm2,%xmm5,%xmm5 + + vpxor %xmm10,%xmm5,%xmm5 + vpxor %xmm11,%xmm5,%xmm5 + vpslldq $8,%xmm5,%xmm9 + vpsrldq $8,%xmm5,%xmm5 + vpxor %xmm9,%xmm10,%xmm10 + vpxor %xmm5,%xmm11,%xmm11 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm11,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + cmpq $0,%rcx + jne L$short_avx + + vpshufb %xmm13,%xmm10,%xmm10 + vmovdqu %xmm10,(%rdi) + vzeroupper + .byte 0xf3,0xc3 + + +.p2align 6 +L$bswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +L$0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +L$7_mask: +.long 7,0,7,0 +.p2align 6 + +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S new file mode 100644 index 00000000..c12cdb20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S @@ -0,0 +1,267 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text + +.code 32 +#undef __thumb2__ +.globl _gcm_init_v8 +.private_extern _gcm_init_v8 +#ifdef __thumb2__ +.thumb_func _gcm_init_v8 +#endif +.align 4 +_gcm_init_v8: + AARCH64_VALID_CALL_TARGET + vld1.64 {q9},[r1] @ load input H + vmov.i8 q11,#0xe1 + vshl.i64 q11,q11,#57 @ 0xc2.0 + vext.8 q3,q9,q9,#8 + vshr.u64 q10,q11,#63 + vdup.32 q9,d18[1] + vext.8 q8,q10,q11,#8 @ t0=0xc2....01 + vshr.u64 q10,q3,#63 + vshr.s32 q9,q9,#31 @ broadcast carry bit + vand q10,q10,q8 + vshl.i64 q3,q3,#1 + vext.8 q10,q10,q10,#8 + vand q8,q8,q9 + vorr q3,q3,q10 @ H<<<=1 + veor q12,q3,q8 @ twisted H + vst1.64 {q12},[r0]! @ store Htable[0] + + @ calculate H^2 + vext.8 q8,q12,q12,#8 @ Karatsuba pre-processing +.byte 0xa8,0x0e,0xa8,0xf2 @ pmull q0,q12,q12 + veor q8,q8,q12 +.byte 0xa9,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q12 +.byte 0xa0,0x2e,0xa0,0xf2 @ pmull q1,q8,q8 + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q14,q0,q10 + + vext.8 q9,q14,q14,#8 @ Karatsuba pre-processing + veor q9,q9,q14 + vext.8 q13,q8,q9,#8 @ pack Karatsuba pre-processed + vst1.64 {q13,q14},[r0]! @ store Htable[1..2] + bx lr + +.globl _gcm_gmult_v8 +.private_extern _gcm_gmult_v8 +#ifdef __thumb2__ +.thumb_func _gcm_gmult_v8 +#endif +.align 4 +_gcm_gmult_v8: + AARCH64_VALID_CALL_TARGET + vld1.64 {q9},[r0] @ load Xi + vmov.i8 q11,#0xe1 + vld1.64 {q12,q13},[r1] @ load twisted H, ... + vshl.u64 q11,q11,#57 +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vext.8 q3,q9,q9,#8 + +.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo + veor q9,q9,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi +.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi) + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q0,q0,q10 + +#ifndef __ARMEB__ + vrev64.8 q0,q0 +#endif + vext.8 q0,q0,q0,#8 + vst1.64 {q0},[r0] @ write out Xi + + bx lr + +.globl _gcm_ghash_v8 +.private_extern _gcm_ghash_v8 +#ifdef __thumb2__ +.thumb_func _gcm_ghash_v8 +#endif +.align 4 +_gcm_ghash_v8: + AARCH64_VALID_CALL_TARGET + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so + vld1.64 {q0},[r0] @ load [rotated] Xi + @ "[rotated]" means that + @ loaded value would have + @ to be rotated in order to + @ make it appear as in + @ algorithm specification + subs r3,r3,#32 @ see if r3 is 32 or larger + mov r12,#16 @ r12 is used as post- + @ increment for input pointer; + @ as loop is modulo-scheduled + @ r12 is zeroed just in time + @ to preclude overstepping + @ inp[len], which means that + @ last block[s] are actually + @ loaded twice, but last + @ copy is not processed + vld1.64 {q12,q13},[r1]! @ load twisted H, ..., H^2 + vmov.i8 q11,#0xe1 + vld1.64 {q14},[r1] + moveq r12,#0 @ is it time to zero r12? + vext.8 q0,q0,q0,#8 @ rotate Xi + vld1.64 {q8},[r2]! @ load [rotated] I[0] + vshl.u64 q11,q11,#57 @ compose 0xc2.0 constant +#ifndef __ARMEB__ + vrev64.8 q8,q8 + vrev64.8 q0,q0 +#endif + vext.8 q3,q8,q8,#8 @ rotate I[0] + blo Lodd_tail_v8 @ r3 was less than 32 + vld1.64 {q9},[r2],r12 @ load [rotated] I[1] +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vext.8 q7,q9,q9,#8 + veor q3,q3,q0 @ I[i]^=Xi +.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1 + veor q9,q9,q7 @ Karatsuba pre-processing +.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7 + b Loop_mod2x_v8 + +.align 4 +Loop_mod2x_v8: + vext.8 q10,q3,q3,#8 + subs r3,r3,#32 @ is there more data? +.byte 0x86,0x0e,0xac,0xf2 @ pmull q0,q14,q3 @ H^2.lo·Xi.lo + movlo r12,#0 @ is it time to zero r12? + +.byte 0xa2,0xae,0xaa,0xf2 @ pmull q5,q13,q9 + veor q10,q10,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xad,0xf2 @ pmull2 q2,q14,q3 @ H^2.hi·Xi.hi + veor q0,q0,q4 @ accumulate +.byte 0xa5,0x2e,0xab,0xf2 @ pmull2 q1,q13,q10 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + vld1.64 {q8},[r2],r12 @ load [rotated] I[i+2] + + veor q2,q2,q6 + moveq r12,#0 @ is it time to zero r12? + veor q1,q1,q5 + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + vld1.64 {q9},[r2],r12 @ load [rotated] I[i+3] +#ifndef __ARMEB__ + vrev64.8 q8,q8 +#endif + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + vext.8 q7,q9,q9,#8 + vext.8 q3,q8,q8,#8 + veor q0,q1,q10 +.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1 + veor q3,q3,q2 @ accumulate q3 early + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q3,q3,q10 + veor q9,q9,q7 @ Karatsuba pre-processing + veor q3,q3,q0 +.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7 + bhs Loop_mod2x_v8 @ there was at least 32 more bytes + + veor q2,q2,q10 + vext.8 q3,q8,q8,#8 @ re-construct q3 + adds r3,r3,#32 @ re-construct r3 + veor q0,q0,q2 @ re-construct q0 + beq Ldone_v8 @ is r3 zero? +Lodd_tail_v8: + vext.8 q10,q0,q0,#8 + veor q3,q3,q0 @ inp^=Xi + veor q9,q8,q10 @ q9 is rotated inp^Xi + +.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo + veor q9,q9,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi +.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi) + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q0,q0,q10 + +Ldone_v8: +#ifndef __ARMEB__ + vrev64.8 q0,q0 +#endif + vext.8 q0,q0,q0,#8 + vst1.64 {q0},[r0] @ write out Xi + + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so + bx lr + +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S new file mode 100644 index 00000000..19f868ec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S @@ -0,0 +1,264 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text +.fpu neon +.code 32 +#undef __thumb2__ +.globl gcm_init_v8 +.hidden gcm_init_v8 +.type gcm_init_v8,%function +.align 4 +gcm_init_v8: + AARCH64_VALID_CALL_TARGET + vld1.64 {q9},[r1] @ load input H + vmov.i8 q11,#0xe1 + vshl.i64 q11,q11,#57 @ 0xc2.0 + vext.8 q3,q9,q9,#8 + vshr.u64 q10,q11,#63 + vdup.32 q9,d18[1] + vext.8 q8,q10,q11,#8 @ t0=0xc2....01 + vshr.u64 q10,q3,#63 + vshr.s32 q9,q9,#31 @ broadcast carry bit + vand q10,q10,q8 + vshl.i64 q3,q3,#1 + vext.8 q10,q10,q10,#8 + vand q8,q8,q9 + vorr q3,q3,q10 @ H<<<=1 + veor q12,q3,q8 @ twisted H + vst1.64 {q12},[r0]! @ store Htable[0] + + @ calculate H^2 + vext.8 q8,q12,q12,#8 @ Karatsuba pre-processing +.byte 0xa8,0x0e,0xa8,0xf2 @ pmull q0,q12,q12 + veor q8,q8,q12 +.byte 0xa9,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q12 +.byte 0xa0,0x2e,0xa0,0xf2 @ pmull q1,q8,q8 + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q14,q0,q10 + + vext.8 q9,q14,q14,#8 @ Karatsuba pre-processing + veor q9,q9,q14 + vext.8 q13,q8,q9,#8 @ pack Karatsuba pre-processed + vst1.64 {q13,q14},[r0]! @ store Htable[1..2] + bx lr +.size gcm_init_v8,.-gcm_init_v8 +.globl gcm_gmult_v8 +.hidden gcm_gmult_v8 +.type gcm_gmult_v8,%function +.align 4 +gcm_gmult_v8: + AARCH64_VALID_CALL_TARGET + vld1.64 {q9},[r0] @ load Xi + vmov.i8 q11,#0xe1 + vld1.64 {q12,q13},[r1] @ load twisted H, ... + vshl.u64 q11,q11,#57 +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vext.8 q3,q9,q9,#8 + +.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo + veor q9,q9,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi +.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi) + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q0,q0,q10 + +#ifndef __ARMEB__ + vrev64.8 q0,q0 +#endif + vext.8 q0,q0,q0,#8 + vst1.64 {q0},[r0] @ write out Xi + + bx lr +.size gcm_gmult_v8,.-gcm_gmult_v8 +.globl gcm_ghash_v8 +.hidden gcm_ghash_v8 +.type gcm_ghash_v8,%function +.align 4 +gcm_ghash_v8: + AARCH64_VALID_CALL_TARGET + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so + vld1.64 {q0},[r0] @ load [rotated] Xi + @ "[rotated]" means that + @ loaded value would have + @ to be rotated in order to + @ make it appear as in + @ algorithm specification + subs r3,r3,#32 @ see if r3 is 32 or larger + mov r12,#16 @ r12 is used as post- + @ increment for input pointer; + @ as loop is modulo-scheduled + @ r12 is zeroed just in time + @ to preclude overstepping + @ inp[len], which means that + @ last block[s] are actually + @ loaded twice, but last + @ copy is not processed + vld1.64 {q12,q13},[r1]! @ load twisted H, ..., H^2 + vmov.i8 q11,#0xe1 + vld1.64 {q14},[r1] + moveq r12,#0 @ is it time to zero r12? + vext.8 q0,q0,q0,#8 @ rotate Xi + vld1.64 {q8},[r2]! @ load [rotated] I[0] + vshl.u64 q11,q11,#57 @ compose 0xc2.0 constant +#ifndef __ARMEB__ + vrev64.8 q8,q8 + vrev64.8 q0,q0 +#endif + vext.8 q3,q8,q8,#8 @ rotate I[0] + blo .Lodd_tail_v8 @ r3 was less than 32 + vld1.64 {q9},[r2],r12 @ load [rotated] I[1] +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vext.8 q7,q9,q9,#8 + veor q3,q3,q0 @ I[i]^=Xi +.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1 + veor q9,q9,q7 @ Karatsuba pre-processing +.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7 + b .Loop_mod2x_v8 + +.align 4 +.Loop_mod2x_v8: + vext.8 q10,q3,q3,#8 + subs r3,r3,#32 @ is there more data? +.byte 0x86,0x0e,0xac,0xf2 @ pmull q0,q14,q3 @ H^2.lo·Xi.lo + movlo r12,#0 @ is it time to zero r12? + +.byte 0xa2,0xae,0xaa,0xf2 @ pmull q5,q13,q9 + veor q10,q10,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xad,0xf2 @ pmull2 q2,q14,q3 @ H^2.hi·Xi.hi + veor q0,q0,q4 @ accumulate +.byte 0xa5,0x2e,0xab,0xf2 @ pmull2 q1,q13,q10 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + vld1.64 {q8},[r2],r12 @ load [rotated] I[i+2] + + veor q2,q2,q6 + moveq r12,#0 @ is it time to zero r12? + veor q1,q1,q5 + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + vld1.64 {q9},[r2],r12 @ load [rotated] I[i+3] +#ifndef __ARMEB__ + vrev64.8 q8,q8 +#endif + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + +#ifndef __ARMEB__ + vrev64.8 q9,q9 +#endif + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + vext.8 q7,q9,q9,#8 + vext.8 q3,q8,q8,#8 + veor q0,q1,q10 +.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1 + veor q3,q3,q2 @ accumulate q3 early + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q3,q3,q10 + veor q9,q9,q7 @ Karatsuba pre-processing + veor q3,q3,q0 +.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7 + bhs .Loop_mod2x_v8 @ there was at least 32 more bytes + + veor q2,q2,q10 + vext.8 q3,q8,q8,#8 @ re-construct q3 + adds r3,r3,#32 @ re-construct r3 + veor q0,q0,q2 @ re-construct q0 + beq .Ldone_v8 @ is r3 zero? +.Lodd_tail_v8: + vext.8 q10,q0,q0,#8 + veor q3,q3,q0 @ inp^=Xi + veor q9,q8,q10 @ q9 is rotated inp^Xi + +.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo + veor q9,q9,q3 @ Karatsuba pre-processing +.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi +.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi) + + vext.8 q9,q0,q2,#8 @ Karatsuba post-processing + veor q10,q0,q2 + veor q1,q1,q9 + veor q1,q1,q10 +.byte 0x26,0x4e,0xe0,0xf2 @ pmull q10,q0,q11 @ 1st phase of reduction + + vmov d4,d3 @ Xh|Xm - 256-bit result + vmov d3,d0 @ Xm is rotated Xl + veor q0,q1,q10 + + vext.8 q10,q0,q0,#8 @ 2nd phase of reduction +.byte 0x26,0x0e,0xa0,0xf2 @ pmull q0,q0,q11 + veor q10,q10,q2 + veor q0,q0,q10 + +.Ldone_v8: +#ifndef __ARMEB__ + vrev64.8 q0,q0 +#endif + vext.8 q0,q0,q0,#8 + vst1.64 {q0},[r0] @ write out Xi + + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ 32-bit ABI says so + bx lr +.size gcm_ghash_v8,.-gcm_ghash_v8 +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S new file mode 100644 index 00000000..bc33a2c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S @@ -0,0 +1,580 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text + +.globl _gcm_init_v8 +.private_extern _gcm_init_v8 + +.align 4 +_gcm_init_v8: + AARCH64_VALID_CALL_TARGET + ld1 {v17.2d},[x1] //load input H + movi v19.16b,#0xe1 + shl v19.2d,v19.2d,#57 //0xc2.0 + ext v3.16b,v17.16b,v17.16b,#8 + ushr v18.2d,v19.2d,#63 + dup v17.4s,v17.s[1] + ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01 + ushr v18.2d,v3.2d,#63 + sshr v17.4s,v17.4s,#31 //broadcast carry bit + and v18.16b,v18.16b,v16.16b + shl v3.2d,v3.2d,#1 + ext v18.16b,v18.16b,v18.16b,#8 + and v16.16b,v16.16b,v17.16b + orr v3.16b,v3.16b,v18.16b //H<<<=1 + eor v20.16b,v3.16b,v16.16b //twisted H + st1 {v20.2d},[x0],#16 //store Htable[0] + + //calculate H^2 + ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing + pmull v0.1q,v20.1d,v20.1d + eor v16.16b,v16.16b,v20.16b + pmull2 v2.1q,v20.2d,v20.2d + pmull v1.1q,v16.1d,v16.1d + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v22.16b,v0.16b,v18.16b + + ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v21.2d,v22.2d},[x0],#32 //store Htable[1..2] + //calculate H^3 and H^4 + pmull v0.1q,v20.1d, v22.1d + pmull v5.1q,v22.1d,v22.1d + pmull2 v2.1q,v20.2d, v22.2d + pmull2 v7.1q,v22.2d,v22.2d + pmull v1.1q,v16.1d,v17.1d + pmull v6.1q,v17.1d,v17.1d + + ext v16.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + ext v17.16b,v5.16b,v7.16b,#8 + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v16.16b + eor v4.16b,v5.16b,v7.16b + eor v6.16b,v6.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + eor v6.16b,v6.16b,v4.16b + pmull v4.1q,v5.1d,v19.1d + + ins v2.d[0],v1.d[1] + ins v7.d[0],v6.d[1] + ins v1.d[1],v0.d[0] + ins v6.d[1],v5.d[0] + eor v0.16b,v1.16b,v18.16b + eor v5.16b,v6.16b,v4.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + ext v4.16b,v5.16b,v5.16b,#8 + pmull v0.1q,v0.1d,v19.1d + pmull v5.1q,v5.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v4.16b,v4.16b,v7.16b + eor v20.16b, v0.16b,v18.16b //H^3 + eor v22.16b,v5.16b,v4.16b //H^4 + + ext v16.16b,v20.16b, v20.16b,#8 //Karatsuba pre-processing + ext v17.16b,v22.16b,v22.16b,#8 + eor v16.16b,v16.16b,v20.16b + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v20.2d,v21.2d,v22.2d},[x0] //store Htable[3..5] + ret + +.globl _gcm_gmult_v8 +.private_extern _gcm_gmult_v8 + +.align 4 +_gcm_gmult_v8: + AARCH64_VALID_CALL_TARGET + ld1 {v17.2d},[x0] //load Xi + movi v19.16b,#0xe1 + ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... + shl v19.2d,v19.2d,#57 +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ext v3.16b,v17.16b,v17.16b,#8 + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret + +.globl _gcm_ghash_v8 +.private_extern _gcm_ghash_v8 + +.align 4 +_gcm_ghash_v8: + AARCH64_VALID_CALL_TARGET + cmp x3,#64 + b.hs Lgcm_ghash_v8_4x + ld1 {v0.2d},[x0] //load [rotated] Xi + //"[rotated]" means that + //loaded value would have + //to be rotated in order to + //make it appear as in + //algorithm specification + subs x3,x3,#32 //see if x3 is 32 or larger + mov x12,#16 //x12 is used as post- + //increment for input pointer; + //as loop is modulo-scheduled + //x12 is zeroed just in time + //to preclude overstepping + //inp[len], which means that + //last block[s] are actually + //loaded twice, but last + //copy is not processed + ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v22.2d},[x1] + csel x12,xzr,x12,eq //is it time to zero x12? + ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi + ld1 {v16.2d},[x2],#16 //load [rotated] I[0] + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant +#ifndef __AARCH64EB__ + rev64 v16.16b,v16.16b + rev64 v0.16b,v0.16b +#endif + ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] + b.lo Lodd_tail_v8 //x3 was less than 32 + ld1 {v17.2d},[x2],x12 //load [rotated] I[1] +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ext v7.16b,v17.16b,v17.16b,#8 + eor v3.16b,v3.16b,v0.16b //I[i]^=Xi + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + pmull2 v6.1q,v20.2d,v7.2d + b Loop_mod2x_v8 + +.align 4 +Loop_mod2x_v8: + ext v18.16b,v3.16b,v3.16b,#8 + subs x3,x3,#32 //is there more data? + pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo + csel x12,xzr,x12,lo //is it time to zero x12? + + pmull v5.1q,v21.1d,v17.1d + eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi + eor v0.16b,v0.16b,v4.16b //accumulate + pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2] + + eor v2.16b,v2.16b,v6.16b + csel x12,xzr,x12,eq //is it time to zero x12? + eor v1.16b,v1.16b,v5.16b + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] +#ifndef __AARCH64EB__ + rev64 v16.16b,v16.16b +#endif + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v7.16b,v17.16b,v17.16b,#8 + ext v3.16b,v16.16b,v16.16b,#8 + eor v0.16b,v1.16b,v18.16b + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v3.16b,v3.16b,v18.16b + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + eor v3.16b,v3.16b,v0.16b + pmull2 v6.1q,v20.2d,v7.2d + b.hs Loop_mod2x_v8 //there was at least 32 more bytes + + eor v2.16b,v2.16b,v18.16b + ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b + adds x3,x3,#32 //re-construct x3 + eor v0.16b,v0.16b,v2.16b //re-construct v0.16b + b.eq Ldone_v8 //is x3 zero? +Lodd_tail_v8: + ext v18.16b,v0.16b,v0.16b,#8 + eor v3.16b,v3.16b,v0.16b //inp^=Xi + eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +Ldone_v8: +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret + + +.align 4 +gcm_ghash_v8_4x: +Lgcm_ghash_v8_4x: + ld1 {v0.2d},[x0] //load [rotated] Xi + ld1 {v20.2d,v21.2d,v22.2d},[x1],#48 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v26.2d,v27.2d,v28.2d},[x1] //load twisted H^3, ..., H^4 + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant + + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + ext v25.16b,v7.16b,v7.16b,#8 + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + pmull2 v31.1q,v20.2d,v25.2d + pmull v30.1q,v21.1d,v7.1d + + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#128 + b.lo Ltail4x + + b Loop4x + +.align 4 +Loop4x: + eor v16.16b,v4.16b,v0.16b + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 + ext v3.16b,v16.16b,v16.16b,#8 +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + ext v25.16b,v7.16b,v7.16b,#8 + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + ext v24.16b,v6.16b,v6.16b,#8 + eor v1.16b,v1.16b,v30.16b + ext v23.16b,v5.16b,v5.16b,#8 + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + eor v1.16b,v1.16b,v17.16b + pmull2 v31.1q,v20.2d,v25.2d + eor v1.16b,v1.16b,v18.16b + pmull v30.1q,v21.1d,v7.1d + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + eor v0.16b,v1.16b,v18.16b + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + eor v18.16b,v18.16b,v2.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v0.16b,v0.16b,v18.16b + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#64 + b.hs Loop4x + +Ltail4x: + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + + adds x3,x3,#64 + b.eq Ldone4x + + cmp x3,#32 + b.lo Lone + b.eq Ltwo +Lthree: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d,v6.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + pmull v29.1q,v20.1d,v24.1d //H·Ii+2 + eor v6.16b,v6.16b,v24.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + pmull2 v31.1q,v20.2d,v24.2d + pmull v30.1q,v21.1d,v6.1d + eor v0.16b,v0.16b,v18.16b + pmull v7.1q,v22.1d,v23.1d //H^2·Ii+1 + eor v5.16b,v5.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull2 v23.1q,v22.2d,v23.2d + eor v16.16b,v4.16b,v0.16b + pmull2 v5.1q,v21.2d,v5.2d + ext v3.16b,v16.16b,v16.16b,#8 + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + pmull v0.1q,v26.1d,v3.1d //H^3·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v26.2d,v3.2d + pmull v1.1q,v27.1d,v16.1d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b Ldone4x + +.align 4 +Ltwo: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull v29.1q,v20.1d,v23.1d //H·Ii+1 + eor v5.16b,v5.16b,v23.16b + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull2 v31.1q,v20.2d,v23.2d + pmull v30.1q,v21.1d,v5.1d + + pmull v0.1q,v22.1d,v3.1d //H^2·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v22.2d,v3.2d + pmull2 v1.1q,v21.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b Ldone4x + +.align 4 +Lone: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v20.1d,v3.1d + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v20.2d,v3.2d + pmull v1.1q,v21.1d,v16.1d + +Ldone4x: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + st1 {v0.2d},[x0] //write out Xi + + ret + +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S new file mode 100644 index 00000000..8a2e1f20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S @@ -0,0 +1,583 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +#if __ARM_MAX_ARCH__>=7 +.text +.arch armv8-a+crypto +.globl gcm_init_v8 +.hidden gcm_init_v8 +.type gcm_init_v8,%function +.align 4 +gcm_init_v8: + AARCH64_VALID_CALL_TARGET + ld1 {v17.2d},[x1] //load input H + movi v19.16b,#0xe1 + shl v19.2d,v19.2d,#57 //0xc2.0 + ext v3.16b,v17.16b,v17.16b,#8 + ushr v18.2d,v19.2d,#63 + dup v17.4s,v17.s[1] + ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01 + ushr v18.2d,v3.2d,#63 + sshr v17.4s,v17.4s,#31 //broadcast carry bit + and v18.16b,v18.16b,v16.16b + shl v3.2d,v3.2d,#1 + ext v18.16b,v18.16b,v18.16b,#8 + and v16.16b,v16.16b,v17.16b + orr v3.16b,v3.16b,v18.16b //H<<<=1 + eor v20.16b,v3.16b,v16.16b //twisted H + st1 {v20.2d},[x0],#16 //store Htable[0] + + //calculate H^2 + ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing + pmull v0.1q,v20.1d,v20.1d + eor v16.16b,v16.16b,v20.16b + pmull2 v2.1q,v20.2d,v20.2d + pmull v1.1q,v16.1d,v16.1d + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v22.16b,v0.16b,v18.16b + + ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v21.2d,v22.2d},[x0],#32 //store Htable[1..2] + //calculate H^3 and H^4 + pmull v0.1q,v20.1d, v22.1d + pmull v5.1q,v22.1d,v22.1d + pmull2 v2.1q,v20.2d, v22.2d + pmull2 v7.1q,v22.2d,v22.2d + pmull v1.1q,v16.1d,v17.1d + pmull v6.1q,v17.1d,v17.1d + + ext v16.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + ext v17.16b,v5.16b,v7.16b,#8 + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v16.16b + eor v4.16b,v5.16b,v7.16b + eor v6.16b,v6.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + eor v6.16b,v6.16b,v4.16b + pmull v4.1q,v5.1d,v19.1d + + ins v2.d[0],v1.d[1] + ins v7.d[0],v6.d[1] + ins v1.d[1],v0.d[0] + ins v6.d[1],v5.d[0] + eor v0.16b,v1.16b,v18.16b + eor v5.16b,v6.16b,v4.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + ext v4.16b,v5.16b,v5.16b,#8 + pmull v0.1q,v0.1d,v19.1d + pmull v5.1q,v5.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v4.16b,v4.16b,v7.16b + eor v20.16b, v0.16b,v18.16b //H^3 + eor v22.16b,v5.16b,v4.16b //H^4 + + ext v16.16b,v20.16b, v20.16b,#8 //Karatsuba pre-processing + ext v17.16b,v22.16b,v22.16b,#8 + eor v16.16b,v16.16b,v20.16b + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v20.2d,v21.2d,v22.2d},[x0] //store Htable[3..5] + ret +.size gcm_init_v8,.-gcm_init_v8 +.globl gcm_gmult_v8 +.hidden gcm_gmult_v8 +.type gcm_gmult_v8,%function +.align 4 +gcm_gmult_v8: + AARCH64_VALID_CALL_TARGET + ld1 {v17.2d},[x0] //load Xi + movi v19.16b,#0xe1 + ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... + shl v19.2d,v19.2d,#57 +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ext v3.16b,v17.16b,v17.16b,#8 + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_gmult_v8,.-gcm_gmult_v8 +.globl gcm_ghash_v8 +.hidden gcm_ghash_v8 +.type gcm_ghash_v8,%function +.align 4 +gcm_ghash_v8: + AARCH64_VALID_CALL_TARGET + cmp x3,#64 + b.hs .Lgcm_ghash_v8_4x + ld1 {v0.2d},[x0] //load [rotated] Xi + //"[rotated]" means that + //loaded value would have + //to be rotated in order to + //make it appear as in + //algorithm specification + subs x3,x3,#32 //see if x3 is 32 or larger + mov x12,#16 //x12 is used as post- + //increment for input pointer; + //as loop is modulo-scheduled + //x12 is zeroed just in time + //to preclude overstepping + //inp[len], which means that + //last block[s] are actually + //loaded twice, but last + //copy is not processed + ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v22.2d},[x1] + csel x12,xzr,x12,eq //is it time to zero x12? + ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi + ld1 {v16.2d},[x2],#16 //load [rotated] I[0] + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant +#ifndef __AARCH64EB__ + rev64 v16.16b,v16.16b + rev64 v0.16b,v0.16b +#endif + ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] + b.lo .Lodd_tail_v8 //x3 was less than 32 + ld1 {v17.2d},[x2],x12 //load [rotated] I[1] +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ext v7.16b,v17.16b,v17.16b,#8 + eor v3.16b,v3.16b,v0.16b //I[i]^=Xi + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + pmull2 v6.1q,v20.2d,v7.2d + b .Loop_mod2x_v8 + +.align 4 +.Loop_mod2x_v8: + ext v18.16b,v3.16b,v3.16b,#8 + subs x3,x3,#32 //is there more data? + pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo + csel x12,xzr,x12,lo //is it time to zero x12? + + pmull v5.1q,v21.1d,v17.1d + eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi + eor v0.16b,v0.16b,v4.16b //accumulate + pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2] + + eor v2.16b,v2.16b,v6.16b + csel x12,xzr,x12,eq //is it time to zero x12? + eor v1.16b,v1.16b,v5.16b + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] +#ifndef __AARCH64EB__ + rev64 v16.16b,v16.16b +#endif + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + +#ifndef __AARCH64EB__ + rev64 v17.16b,v17.16b +#endif + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v7.16b,v17.16b,v17.16b,#8 + ext v3.16b,v16.16b,v16.16b,#8 + eor v0.16b,v1.16b,v18.16b + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v3.16b,v3.16b,v18.16b + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + eor v3.16b,v3.16b,v0.16b + pmull2 v6.1q,v20.2d,v7.2d + b.hs .Loop_mod2x_v8 //there was at least 32 more bytes + + eor v2.16b,v2.16b,v18.16b + ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b + adds x3,x3,#32 //re-construct x3 + eor v0.16b,v0.16b,v2.16b //re-construct v0.16b + b.eq .Ldone_v8 //is x3 zero? +.Lodd_tail_v8: + ext v18.16b,v0.16b,v0.16b,#8 + eor v3.16b,v3.16b,v0.16b //inp^=Xi + eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +.Ldone_v8: +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8,.-gcm_ghash_v8 +.type gcm_ghash_v8_4x,%function +.align 4 +gcm_ghash_v8_4x: +.Lgcm_ghash_v8_4x: + ld1 {v0.2d},[x0] //load [rotated] Xi + ld1 {v20.2d,v21.2d,v22.2d},[x1],#48 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v26.2d,v27.2d,v28.2d},[x1] //load twisted H^3, ..., H^4 + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant + + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + ext v25.16b,v7.16b,v7.16b,#8 + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + pmull2 v31.1q,v20.2d,v25.2d + pmull v30.1q,v21.1d,v7.1d + + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#128 + b.lo .Ltail4x + + b .Loop4x + +.align 4 +.Loop4x: + eor v16.16b,v4.16b,v0.16b + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 + ext v3.16b,v16.16b,v16.16b,#8 +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + ext v25.16b,v7.16b,v7.16b,#8 + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + ext v24.16b,v6.16b,v6.16b,#8 + eor v1.16b,v1.16b,v30.16b + ext v23.16b,v5.16b,v5.16b,#8 + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + eor v1.16b,v1.16b,v17.16b + pmull2 v31.1q,v20.2d,v25.2d + eor v1.16b,v1.16b,v18.16b + pmull v30.1q,v21.1d,v7.1d + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + eor v0.16b,v1.16b,v18.16b + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + eor v18.16b,v18.16b,v2.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v0.16b,v0.16b,v18.16b + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#64 + b.hs .Loop4x + +.Ltail4x: + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + + adds x3,x3,#64 + b.eq .Ldone4x + + cmp x3,#32 + b.lo .Lone + b.eq .Ltwo +.Lthree: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d,v6.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + pmull v29.1q,v20.1d,v24.1d //H·Ii+2 + eor v6.16b,v6.16b,v24.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + pmull2 v31.1q,v20.2d,v24.2d + pmull v30.1q,v21.1d,v6.1d + eor v0.16b,v0.16b,v18.16b + pmull v7.1q,v22.1d,v23.1d //H^2·Ii+1 + eor v5.16b,v5.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull2 v23.1q,v22.2d,v23.2d + eor v16.16b,v4.16b,v0.16b + pmull2 v5.1q,v21.2d,v5.2d + ext v3.16b,v16.16b,v16.16b,#8 + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + pmull v0.1q,v26.1d,v3.1d //H^3·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v26.2d,v3.2d + pmull v1.1q,v27.1d,v16.1d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Ltwo: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v5.16b,v5.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull v29.1q,v20.1d,v23.1d //H·Ii+1 + eor v5.16b,v5.16b,v23.16b + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull2 v31.1q,v20.2d,v23.2d + pmull v30.1q,v21.1d,v5.1d + + pmull v0.1q,v22.1d,v3.1d //H^2·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v22.2d,v3.2d + pmull2 v1.1q,v21.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Lone: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __AARCH64EB__ + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v20.1d,v3.1d + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v20.2d,v3.2d + pmull v1.1q,v21.1d,v16.1d + +.Ldone4x: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + +#ifndef __AARCH64EB__ + rev64 v0.16b,v0.16b +#endif + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8_4x,.-gcm_ghash_v8_4x +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c new file mode 100644 index 00000000..35edb2b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c @@ -0,0 +1,235 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "../../internal.h" + + +uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, + const uint8_t *data, size_t data_len, uint8_t *out, + unsigned int *out_len) { + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + if (!HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) || + !HMAC_Update(&ctx, data, data_len) || + !HMAC_Final(&ctx, out, out_len)) { + out = NULL; + } + + HMAC_CTX_cleanup(&ctx); + return out; +} + +void HMAC_CTX_init(HMAC_CTX *ctx) { + ctx->md = NULL; + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); +} + +HMAC_CTX *HMAC_CTX_new(void) { + HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx != NULL) { + HMAC_CTX_init(ctx); + } + return ctx; +} + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) { + EVP_MD_CTX_cleanup(&ctx->i_ctx); + EVP_MD_CTX_cleanup(&ctx->o_ctx); + EVP_MD_CTX_cleanup(&ctx->md_ctx); + OPENSSL_cleanse(ctx, sizeof(HMAC_CTX)); +} + +void HMAC_CTX_cleanse(HMAC_CTX *ctx) { + EVP_MD_CTX_cleanse(&ctx->i_ctx); + EVP_MD_CTX_cleanse(&ctx->o_ctx); + EVP_MD_CTX_cleanse(&ctx->md_ctx); + OPENSSL_cleanse(ctx, sizeof(HMAC_CTX)); +} + +void HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl) { + if (md == NULL) { + md = ctx->md; + } + + // If either |key| is non-NULL or |md| has changed, initialize with a new key + // rather than rewinding the previous one. + // + // TODO(davidben,eroman): Passing the previous |md| with a NULL |key| is + // ambiguous between using the empty key and reusing the previous key. There + // exist callers which intend the latter, but the former is an awkward edge + // case. Fix to API to avoid this. + if (md != ctx->md || key != NULL) { + uint8_t pad[EVP_MAX_MD_BLOCK_SIZE]; + uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE]; + unsigned key_block_len; + + size_t block_size = EVP_MD_block_size(md); + assert(block_size <= sizeof(key_block)); + if (block_size < key_len) { + // Long keys are hashed. + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) || + !EVP_DigestFinal_ex(&ctx->md_ctx, key_block, &key_block_len)) { + return 0; + } + } else { + assert(key_len <= sizeof(key_block)); + OPENSSL_memcpy(key_block, key, key_len); + key_block_len = (unsigned)key_len; + } + // Keys are then padded with zeros. + if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) { + OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x36 ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x5c ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + ctx->md = md; + } + + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) { + return 0; + } + + return 1; +} + +int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) { + return EVP_DigestUpdate(&ctx->md_ctx, data, data_len); +} + +int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) { + unsigned int i; + uint8_t buf[EVP_MAX_MD_SIZE]; + + // TODO(davidben): The only thing that can officially fail here is + // |EVP_MD_CTX_copy_ex|, but even that should be impossible in this case. + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) || + !EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx) || + !EVP_DigestUpdate(&ctx->md_ctx, buf, i) || + !EVP_DigestFinal_ex(&ctx->md_ctx, out, out_len)) { + *out_len = 0; + return 0; + } + + return 1; +} + +size_t HMAC_size(const HMAC_CTX *ctx) { + return EVP_MD_size(ctx->md); +} + +int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src) { + if (!EVP_MD_CTX_copy_ex(&dest->i_ctx, &src->i_ctx) || + !EVP_MD_CTX_copy_ex(&dest->o_ctx, &src->o_ctx) || + !EVP_MD_CTX_copy_ex(&dest->md_ctx, &src->md_ctx)) { + return 0; + } + + dest->md = src->md; + return 1; +} + +void HMAC_CTX_reset(HMAC_CTX *ctx) { + HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); +} + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md) { + if (key && md) { + HMAC_CTX_init(ctx); + } + return HMAC_Init_ex(ctx, key, key_len, md, NULL); +} + +int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src) { + HMAC_CTX_init(dest); + return HMAC_CTX_copy_ex(dest, src); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md4/md4.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md4/md4.c new file mode 100644 index 00000000..aa418307 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md4/md4.c @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "../../internal.h" +#include "../digest/md32_common.h" + + +uint8_t *MD4(const uint8_t *data, size_t len, uint8_t out[MD4_DIGEST_LENGTH]) { + MD4_CTX ctx; + MD4_Init(&ctx); + MD4_Update(&ctx, data, len); + MD4_Final(out, &ctx); + + return out; +} + +// Implemented from RFC 1186 The MD4 Message-Digest Algorithm. + +int MD4_Init(MD4_CTX *md4) { + OPENSSL_memset(md4, 0, sizeof(MD4_CTX)); + md4->h[0] = 0x67452301UL; + md4->h[1] = 0xefcdab89UL; + md4->h[2] = 0x98badcfeUL; + md4->h[3] = 0x10325476UL; + return 1; +} + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +void MD4_Transform(MD4_CTX *c, const uint8_t data[MD4_CBLOCK]) { + md4_block_data_order(c->h, data, 1); +} + +int MD4_Update(MD4_CTX *c, const void *data, size_t len) { + crypto_md32_update(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num, + &c->Nh, &c->Nl, data, len); + return 1; +} + +int MD4_Final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *c) { + crypto_md32_final(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num, + c->Nh, c->Nl, /*is_big_endian=*/0); + + CRYPTO_store_u32_le(out, c->h[0]); + CRYPTO_store_u32_le(out + 4, c->h[1]); + CRYPTO_store_u32_le(out + 8, c->h[2]); + CRYPTO_store_u32_le(out + 12, c->h[3]); + return 1; +} + +// As pointed out by Wei Dai , the above can be +// simplified to the code below. Wei attributes these optimizations +// to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. +#define F(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define H(b, c, d) ((b) ^ (c) ^ (d)) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + } while (0) + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D; + uint32_t X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + for (; num--;) { + X0 = CRYPTO_load_u32_le(data); + data += 4; + X1 = CRYPTO_load_u32_le(data); + data += 4; + // Round 0 + R0(A, B, C, D, X0, 3, 0); + X2 = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X1, 7, 0); + X3 = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X2, 11, 0); + X4 = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X3, 19, 0); + X5 = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X4, 3, 0); + X6 = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X5, 7, 0); + X7 = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X6, 11, 0); + X8 = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X7, 19, 0); + X9 = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X8, 3, 0); + X10 = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X9, 7, 0); + X11 = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X10, 11, 0); + X12 = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X11, 19, 0); + X13 = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X12, 3, 0); + X14 = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X13, 7, 0); + X15 = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X14, 11, 0); + R0(B, C, D, A, X15, 19, 0); + // Round 1 + R1(A, B, C, D, X0, 3, 0x5A827999L); + R1(D, A, B, C, X4, 5, 0x5A827999L); + R1(C, D, A, B, X8, 9, 0x5A827999L); + R1(B, C, D, A, X12, 13, 0x5A827999L); + R1(A, B, C, D, X1, 3, 0x5A827999L); + R1(D, A, B, C, X5, 5, 0x5A827999L); + R1(C, D, A, B, X9, 9, 0x5A827999L); + R1(B, C, D, A, X13, 13, 0x5A827999L); + R1(A, B, C, D, X2, 3, 0x5A827999L); + R1(D, A, B, C, X6, 5, 0x5A827999L); + R1(C, D, A, B, X10, 9, 0x5A827999L); + R1(B, C, D, A, X14, 13, 0x5A827999L); + R1(A, B, C, D, X3, 3, 0x5A827999L); + R1(D, A, B, C, X7, 5, 0x5A827999L); + R1(C, D, A, B, X11, 9, 0x5A827999L); + R1(B, C, D, A, X15, 13, 0x5A827999L); + // Round 2 + R2(A, B, C, D, X0, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X8, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X4, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X12, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X2, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X10, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X6, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X14, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X1, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X9, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X5, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X13, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X3, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X11, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X7, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X15, 15, 0x6ED9EBA1L); + + A = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} + +#undef F +#undef G +#undef H +#undef R0 +#undef R1 +#undef R2 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S new file mode 100644 index 00000000..891c31cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S @@ -0,0 +1,695 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl md5_block_asm_data_order +.hidden md5_block_asm_data_order +.type md5_block_asm_data_order,@function +.align 16 +md5_block_asm_data_order: +.L_md5_block_asm_data_order_begin: + pushl %esi + pushl %edi + movl 12(%esp),%edi + movl 16(%esp),%esi + movl 20(%esp),%ecx + pushl %ebp + shll $6,%ecx + pushl %ebx + addl %esi,%ecx + subl $64,%ecx + movl (%edi),%eax + pushl %ecx + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx +.L000start: + + + movl %ecx,%edi + movl (%esi),%ebp + + xorl %edx,%edi + andl %ebx,%edi + leal 3614090360(%eax,%ebp,1),%eax + xorl %edx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $7,%eax + movl 4(%esi),%ebp + addl %ebx,%eax + + xorl %ecx,%edi + andl %eax,%edi + leal 3905402710(%edx,%ebp,1),%edx + xorl %ecx,%edi + addl %edi,%edx + movl %eax,%edi + roll $12,%edx + movl 8(%esi),%ebp + addl %eax,%edx + + xorl %ebx,%edi + andl %edx,%edi + leal 606105819(%ecx,%ebp,1),%ecx + xorl %ebx,%edi + addl %edi,%ecx + movl %edx,%edi + roll $17,%ecx + movl 12(%esi),%ebp + addl %edx,%ecx + + xorl %eax,%edi + andl %ecx,%edi + leal 3250441966(%ebx,%ebp,1),%ebx + xorl %eax,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $22,%ebx + movl 16(%esi),%ebp + addl %ecx,%ebx + + xorl %edx,%edi + andl %ebx,%edi + leal 4118548399(%eax,%ebp,1),%eax + xorl %edx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $7,%eax + movl 20(%esi),%ebp + addl %ebx,%eax + + xorl %ecx,%edi + andl %eax,%edi + leal 1200080426(%edx,%ebp,1),%edx + xorl %ecx,%edi + addl %edi,%edx + movl %eax,%edi + roll $12,%edx + movl 24(%esi),%ebp + addl %eax,%edx + + xorl %ebx,%edi + andl %edx,%edi + leal 2821735955(%ecx,%ebp,1),%ecx + xorl %ebx,%edi + addl %edi,%ecx + movl %edx,%edi + roll $17,%ecx + movl 28(%esi),%ebp + addl %edx,%ecx + + xorl %eax,%edi + andl %ecx,%edi + leal 4249261313(%ebx,%ebp,1),%ebx + xorl %eax,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $22,%ebx + movl 32(%esi),%ebp + addl %ecx,%ebx + + xorl %edx,%edi + andl %ebx,%edi + leal 1770035416(%eax,%ebp,1),%eax + xorl %edx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $7,%eax + movl 36(%esi),%ebp + addl %ebx,%eax + + xorl %ecx,%edi + andl %eax,%edi + leal 2336552879(%edx,%ebp,1),%edx + xorl %ecx,%edi + addl %edi,%edx + movl %eax,%edi + roll $12,%edx + movl 40(%esi),%ebp + addl %eax,%edx + + xorl %ebx,%edi + andl %edx,%edi + leal 4294925233(%ecx,%ebp,1),%ecx + xorl %ebx,%edi + addl %edi,%ecx + movl %edx,%edi + roll $17,%ecx + movl 44(%esi),%ebp + addl %edx,%ecx + + xorl %eax,%edi + andl %ecx,%edi + leal 2304563134(%ebx,%ebp,1),%ebx + xorl %eax,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $22,%ebx + movl 48(%esi),%ebp + addl %ecx,%ebx + + xorl %edx,%edi + andl %ebx,%edi + leal 1804603682(%eax,%ebp,1),%eax + xorl %edx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $7,%eax + movl 52(%esi),%ebp + addl %ebx,%eax + + xorl %ecx,%edi + andl %eax,%edi + leal 4254626195(%edx,%ebp,1),%edx + xorl %ecx,%edi + addl %edi,%edx + movl %eax,%edi + roll $12,%edx + movl 56(%esi),%ebp + addl %eax,%edx + + xorl %ebx,%edi + andl %edx,%edi + leal 2792965006(%ecx,%ebp,1),%ecx + xorl %ebx,%edi + addl %edi,%ecx + movl %edx,%edi + roll $17,%ecx + movl 60(%esi),%ebp + addl %edx,%ecx + + xorl %eax,%edi + andl %ecx,%edi + leal 1236535329(%ebx,%ebp,1),%ebx + xorl %eax,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $22,%ebx + movl 4(%esi),%ebp + addl %ecx,%ebx + + + + leal 4129170786(%eax,%ebp,1),%eax + xorl %ebx,%edi + andl %edx,%edi + movl 24(%esi),%ebp + xorl %ecx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $5,%eax + addl %ebx,%eax + + leal 3225465664(%edx,%ebp,1),%edx + xorl %eax,%edi + andl %ecx,%edi + movl 44(%esi),%ebp + xorl %ebx,%edi + addl %edi,%edx + movl %eax,%edi + roll $9,%edx + addl %eax,%edx + + leal 643717713(%ecx,%ebp,1),%ecx + xorl %edx,%edi + andl %ebx,%edi + movl (%esi),%ebp + xorl %eax,%edi + addl %edi,%ecx + movl %edx,%edi + roll $14,%ecx + addl %edx,%ecx + + leal 3921069994(%ebx,%ebp,1),%ebx + xorl %ecx,%edi + andl %eax,%edi + movl 20(%esi),%ebp + xorl %edx,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $20,%ebx + addl %ecx,%ebx + + leal 3593408605(%eax,%ebp,1),%eax + xorl %ebx,%edi + andl %edx,%edi + movl 40(%esi),%ebp + xorl %ecx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $5,%eax + addl %ebx,%eax + + leal 38016083(%edx,%ebp,1),%edx + xorl %eax,%edi + andl %ecx,%edi + movl 60(%esi),%ebp + xorl %ebx,%edi + addl %edi,%edx + movl %eax,%edi + roll $9,%edx + addl %eax,%edx + + leal 3634488961(%ecx,%ebp,1),%ecx + xorl %edx,%edi + andl %ebx,%edi + movl 16(%esi),%ebp + xorl %eax,%edi + addl %edi,%ecx + movl %edx,%edi + roll $14,%ecx + addl %edx,%ecx + + leal 3889429448(%ebx,%ebp,1),%ebx + xorl %ecx,%edi + andl %eax,%edi + movl 36(%esi),%ebp + xorl %edx,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $20,%ebx + addl %ecx,%ebx + + leal 568446438(%eax,%ebp,1),%eax + xorl %ebx,%edi + andl %edx,%edi + movl 56(%esi),%ebp + xorl %ecx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $5,%eax + addl %ebx,%eax + + leal 3275163606(%edx,%ebp,1),%edx + xorl %eax,%edi + andl %ecx,%edi + movl 12(%esi),%ebp + xorl %ebx,%edi + addl %edi,%edx + movl %eax,%edi + roll $9,%edx + addl %eax,%edx + + leal 4107603335(%ecx,%ebp,1),%ecx + xorl %edx,%edi + andl %ebx,%edi + movl 32(%esi),%ebp + xorl %eax,%edi + addl %edi,%ecx + movl %edx,%edi + roll $14,%ecx + addl %edx,%ecx + + leal 1163531501(%ebx,%ebp,1),%ebx + xorl %ecx,%edi + andl %eax,%edi + movl 52(%esi),%ebp + xorl %edx,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $20,%ebx + addl %ecx,%ebx + + leal 2850285829(%eax,%ebp,1),%eax + xorl %ebx,%edi + andl %edx,%edi + movl 8(%esi),%ebp + xorl %ecx,%edi + addl %edi,%eax + movl %ebx,%edi + roll $5,%eax + addl %ebx,%eax + + leal 4243563512(%edx,%ebp,1),%edx + xorl %eax,%edi + andl %ecx,%edi + movl 28(%esi),%ebp + xorl %ebx,%edi + addl %edi,%edx + movl %eax,%edi + roll $9,%edx + addl %eax,%edx + + leal 1735328473(%ecx,%ebp,1),%ecx + xorl %edx,%edi + andl %ebx,%edi + movl 48(%esi),%ebp + xorl %eax,%edi + addl %edi,%ecx + movl %edx,%edi + roll $14,%ecx + addl %edx,%ecx + + leal 2368359562(%ebx,%ebp,1),%ebx + xorl %ecx,%edi + andl %eax,%edi + movl 20(%esi),%ebp + xorl %edx,%edi + addl %edi,%ebx + movl %ecx,%edi + roll $20,%ebx + addl %ecx,%ebx + + + + xorl %edx,%edi + xorl %ebx,%edi + leal 4294588738(%eax,%ebp,1),%eax + addl %edi,%eax + roll $4,%eax + movl 32(%esi),%ebp + movl %ebx,%edi + + leal 2272392833(%edx,%ebp,1),%edx + addl %ebx,%eax + xorl %ecx,%edi + xorl %eax,%edi + movl 44(%esi),%ebp + addl %edi,%edx + movl %eax,%edi + roll $11,%edx + addl %eax,%edx + + xorl %ebx,%edi + xorl %edx,%edi + leal 1839030562(%ecx,%ebp,1),%ecx + addl %edi,%ecx + roll $16,%ecx + movl 56(%esi),%ebp + movl %edx,%edi + + leal 4259657740(%ebx,%ebp,1),%ebx + addl %edx,%ecx + xorl %eax,%edi + xorl %ecx,%edi + movl 4(%esi),%ebp + addl %edi,%ebx + movl %ecx,%edi + roll $23,%ebx + addl %ecx,%ebx + + xorl %edx,%edi + xorl %ebx,%edi + leal 2763975236(%eax,%ebp,1),%eax + addl %edi,%eax + roll $4,%eax + movl 16(%esi),%ebp + movl %ebx,%edi + + leal 1272893353(%edx,%ebp,1),%edx + addl %ebx,%eax + xorl %ecx,%edi + xorl %eax,%edi + movl 28(%esi),%ebp + addl %edi,%edx + movl %eax,%edi + roll $11,%edx + addl %eax,%edx + + xorl %ebx,%edi + xorl %edx,%edi + leal 4139469664(%ecx,%ebp,1),%ecx + addl %edi,%ecx + roll $16,%ecx + movl 40(%esi),%ebp + movl %edx,%edi + + leal 3200236656(%ebx,%ebp,1),%ebx + addl %edx,%ecx + xorl %eax,%edi + xorl %ecx,%edi + movl 52(%esi),%ebp + addl %edi,%ebx + movl %ecx,%edi + roll $23,%ebx + addl %ecx,%ebx + + xorl %edx,%edi + xorl %ebx,%edi + leal 681279174(%eax,%ebp,1),%eax + addl %edi,%eax + roll $4,%eax + movl (%esi),%ebp + movl %ebx,%edi + + leal 3936430074(%edx,%ebp,1),%edx + addl %ebx,%eax + xorl %ecx,%edi + xorl %eax,%edi + movl 12(%esi),%ebp + addl %edi,%edx + movl %eax,%edi + roll $11,%edx + addl %eax,%edx + + xorl %ebx,%edi + xorl %edx,%edi + leal 3572445317(%ecx,%ebp,1),%ecx + addl %edi,%ecx + roll $16,%ecx + movl 24(%esi),%ebp + movl %edx,%edi + + leal 76029189(%ebx,%ebp,1),%ebx + addl %edx,%ecx + xorl %eax,%edi + xorl %ecx,%edi + movl 36(%esi),%ebp + addl %edi,%ebx + movl %ecx,%edi + roll $23,%ebx + addl %ecx,%ebx + + xorl %edx,%edi + xorl %ebx,%edi + leal 3654602809(%eax,%ebp,1),%eax + addl %edi,%eax + roll $4,%eax + movl 48(%esi),%ebp + movl %ebx,%edi + + leal 3873151461(%edx,%ebp,1),%edx + addl %ebx,%eax + xorl %ecx,%edi + xorl %eax,%edi + movl 60(%esi),%ebp + addl %edi,%edx + movl %eax,%edi + roll $11,%edx + addl %eax,%edx + + xorl %ebx,%edi + xorl %edx,%edi + leal 530742520(%ecx,%ebp,1),%ecx + addl %edi,%ecx + roll $16,%ecx + movl 8(%esi),%ebp + movl %edx,%edi + + leal 3299628645(%ebx,%ebp,1),%ebx + addl %edx,%ecx + xorl %eax,%edi + xorl %ecx,%edi + movl (%esi),%ebp + addl %edi,%ebx + movl $-1,%edi + roll $23,%ebx + addl %ecx,%ebx + + + + xorl %edx,%edi + orl %ebx,%edi + leal 4096336452(%eax,%ebp,1),%eax + xorl %ecx,%edi + movl 28(%esi),%ebp + addl %edi,%eax + movl $-1,%edi + roll $6,%eax + xorl %ecx,%edi + addl %ebx,%eax + + orl %eax,%edi + leal 1126891415(%edx,%ebp,1),%edx + xorl %ebx,%edi + movl 56(%esi),%ebp + addl %edi,%edx + movl $-1,%edi + roll $10,%edx + xorl %ebx,%edi + addl %eax,%edx + + orl %edx,%edi + leal 2878612391(%ecx,%ebp,1),%ecx + xorl %eax,%edi + movl 20(%esi),%ebp + addl %edi,%ecx + movl $-1,%edi + roll $15,%ecx + xorl %eax,%edi + addl %edx,%ecx + + orl %ecx,%edi + leal 4237533241(%ebx,%ebp,1),%ebx + xorl %edx,%edi + movl 48(%esi),%ebp + addl %edi,%ebx + movl $-1,%edi + roll $21,%ebx + xorl %edx,%edi + addl %ecx,%ebx + + orl %ebx,%edi + leal 1700485571(%eax,%ebp,1),%eax + xorl %ecx,%edi + movl 12(%esi),%ebp + addl %edi,%eax + movl $-1,%edi + roll $6,%eax + xorl %ecx,%edi + addl %ebx,%eax + + orl %eax,%edi + leal 2399980690(%edx,%ebp,1),%edx + xorl %ebx,%edi + movl 40(%esi),%ebp + addl %edi,%edx + movl $-1,%edi + roll $10,%edx + xorl %ebx,%edi + addl %eax,%edx + + orl %edx,%edi + leal 4293915773(%ecx,%ebp,1),%ecx + xorl %eax,%edi + movl 4(%esi),%ebp + addl %edi,%ecx + movl $-1,%edi + roll $15,%ecx + xorl %eax,%edi + addl %edx,%ecx + + orl %ecx,%edi + leal 2240044497(%ebx,%ebp,1),%ebx + xorl %edx,%edi + movl 32(%esi),%ebp + addl %edi,%ebx + movl $-1,%edi + roll $21,%ebx + xorl %edx,%edi + addl %ecx,%ebx + + orl %ebx,%edi + leal 1873313359(%eax,%ebp,1),%eax + xorl %ecx,%edi + movl 60(%esi),%ebp + addl %edi,%eax + movl $-1,%edi + roll $6,%eax + xorl %ecx,%edi + addl %ebx,%eax + + orl %eax,%edi + leal 4264355552(%edx,%ebp,1),%edx + xorl %ebx,%edi + movl 24(%esi),%ebp + addl %edi,%edx + movl $-1,%edi + roll $10,%edx + xorl %ebx,%edi + addl %eax,%edx + + orl %edx,%edi + leal 2734768916(%ecx,%ebp,1),%ecx + xorl %eax,%edi + movl 52(%esi),%ebp + addl %edi,%ecx + movl $-1,%edi + roll $15,%ecx + xorl %eax,%edi + addl %edx,%ecx + + orl %ecx,%edi + leal 1309151649(%ebx,%ebp,1),%ebx + xorl %edx,%edi + movl 16(%esi),%ebp + addl %edi,%ebx + movl $-1,%edi + roll $21,%ebx + xorl %edx,%edi + addl %ecx,%ebx + + orl %ebx,%edi + leal 4149444226(%eax,%ebp,1),%eax + xorl %ecx,%edi + movl 44(%esi),%ebp + addl %edi,%eax + movl $-1,%edi + roll $6,%eax + xorl %ecx,%edi + addl %ebx,%eax + + orl %eax,%edi + leal 3174756917(%edx,%ebp,1),%edx + xorl %ebx,%edi + movl 8(%esi),%ebp + addl %edi,%edx + movl $-1,%edi + roll $10,%edx + xorl %ebx,%edi + addl %eax,%edx + + orl %edx,%edi + leal 718787259(%ecx,%ebp,1),%ecx + xorl %eax,%edi + movl 36(%esi),%ebp + addl %edi,%ecx + movl $-1,%edi + roll $15,%ecx + xorl %eax,%edi + addl %edx,%ecx + + orl %ecx,%edi + leal 3951481745(%ebx,%ebp,1),%ebx + xorl %edx,%edi + movl 24(%esp),%ebp + addl %edi,%ebx + addl $64,%esi + roll $21,%ebx + movl (%ebp),%edi + addl %ecx,%ebx + addl %edi,%eax + movl 4(%ebp),%edi + addl %edi,%ebx + movl 8(%ebp),%edi + addl %edi,%ecx + movl 12(%ebp),%edi + addl %edi,%edx + movl %eax,(%ebp) + movl %ebx,4(%ebp) + movl (%esp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + cmpl %esi,%edi + jae .L000start + popl %eax + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size md5_block_asm_data_order,.-.L_md5_block_asm_data_order_begin +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S new file mode 100644 index 00000000..a01dbc81 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S @@ -0,0 +1,709 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.align 16 + +.globl md5_block_asm_data_order +.hidden md5_block_asm_data_order +.type md5_block_asm_data_order,@function +md5_block_asm_data_order: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset r12,-32 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset r14,-40 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset r15,-48 +.Lprologue: + + + + + movq %rdi,%rbp + shlq $6,%rdx + leaq (%rsi,%rdx,1),%rdi + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + + + + + + + + cmpq %rdi,%rsi + je .Lend + + +.Lloop: + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r14d + movl %edx,%r15d + movl 0(%rsi),%r10d + movl %edx,%r11d + xorl %ecx,%r11d + leal -680876936(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 4(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -389564586(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 8(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal 606105819(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 12(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1044525330(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 16(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal -176418897(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 20(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal 1200080426(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 24(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1473231341(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 28(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -45705983(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 32(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1770035416(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 36(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -1958414417(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 40(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -42063(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 44(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1990404162(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 48(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1804603682(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 52(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -40341101(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 56(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1502002290(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 60(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal 1236535329(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 0(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + movl 4(%rsi),%r10d + movl %edx,%r11d + movl %edx,%r12d + notl %r11d + leal -165796510(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 24(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1069501632(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 44(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 643717713(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -373897302(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 20(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -701558691(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 40(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal 38016083(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 60(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -660478335(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 16(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -405537848(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 36(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal 568446438(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 56(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1019803690(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 12(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -187363961(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 32(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal 1163531501(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 52(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -1444681467(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 8(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -51403784(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 28(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 1735328473(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 48(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -1926607734(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + movl 20(%rsi),%r10d + movl %ecx,%r11d + leal -378558(%rax,%r10,1),%eax + movl 32(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -2022574463(%rdx,%r10,1),%edx + movl 44(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 1839030562(%rcx,%r10,1),%ecx + movl 56(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -35309556(%rbx,%r10,1),%ebx + movl 4(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -1530992060(%rax,%r10,1),%eax + movl 16(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal 1272893353(%rdx,%r10,1),%edx + movl 28(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -155497632(%rcx,%r10,1),%ecx + movl 40(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -1094730640(%rbx,%r10,1),%ebx + movl 52(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal 681279174(%rax,%r10,1),%eax + movl 0(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -358537222(%rdx,%r10,1),%edx + movl 12(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -722521979(%rcx,%r10,1),%ecx + movl 24(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal 76029189(%rbx,%r10,1),%ebx + movl 36(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -640364487(%rax,%r10,1),%eax + movl 48(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -421815835(%rdx,%r10,1),%edx + movl 60(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 530742520(%rcx,%r10,1),%ecx + movl 8(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -995338651(%rbx,%r10,1),%ebx + movl 0(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + movl 0(%rsi),%r10d + movl $0xffffffff,%r11d + xorl %edx,%r11d + leal -198630844(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 28(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal 1126891415(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 56(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1416354905(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 20(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -57434055(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 48(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1700485571(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 12(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1894986606(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 40(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1051523(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 4(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -2054922799(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 32(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1873313359(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 60(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -30611744(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 24(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1560198380(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 52(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal 1309151649(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 16(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal -145523070(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 44(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1120210379(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 8(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal 718787259(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 36(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -343485551(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 0(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + + addl %r8d,%eax + addl %r9d,%ebx + addl %r14d,%ecx + addl %r15d,%edx + + + addq $64,%rsi + cmpq %rdi,%rsi + jb .Lloop + + +.Lend: + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + movq (%rsp),%r15 +.cfi_restore r15 + movq 8(%rsp),%r14 +.cfi_restore r14 + movq 16(%rsp),%r12 +.cfi_restore r12 + movq 24(%rsp),%rbx +.cfi_restore rbx + movq 32(%rsp),%rbp +.cfi_restore rbp + addq $40,%rsp +.cfi_adjust_cfa_offset -40 +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size md5_block_asm_data_order,.-md5_block_asm_data_order +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S new file mode 100644 index 00000000..03bad95a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S @@ -0,0 +1,703 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.p2align 4 + +.globl _md5_block_asm_data_order +.private_extern _md5_block_asm_data_order + +_md5_block_asm_data_order: + + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r14 + + pushq %r15 + +L$prologue: + + + + + movq %rdi,%rbp + shlq $6,%rdx + leaq (%rsi,%rdx,1),%rdi + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + + + + + + + + cmpq %rdi,%rsi + je L$end + + +L$loop: + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r14d + movl %edx,%r15d + movl 0(%rsi),%r10d + movl %edx,%r11d + xorl %ecx,%r11d + leal -680876936(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 4(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -389564586(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 8(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal 606105819(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 12(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1044525330(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 16(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal -176418897(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 20(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal 1200080426(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 24(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1473231341(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 28(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -45705983(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 32(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1770035416(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 36(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -1958414417(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 40(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -42063(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 44(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal -1990404162(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 48(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + xorl %ecx,%r11d + leal 1804603682(%rax,%r10,1),%eax + andl %ebx,%r11d + xorl %edx,%r11d + movl 52(%rsi),%r10d + addl %r11d,%eax + roll $7,%eax + movl %ecx,%r11d + addl %ebx,%eax + xorl %ebx,%r11d + leal -40341101(%rdx,%r10,1),%edx + andl %eax,%r11d + xorl %ecx,%r11d + movl 56(%rsi),%r10d + addl %r11d,%edx + roll $12,%edx + movl %ebx,%r11d + addl %eax,%edx + xorl %eax,%r11d + leal -1502002290(%rcx,%r10,1),%ecx + andl %edx,%r11d + xorl %ebx,%r11d + movl 60(%rsi),%r10d + addl %r11d,%ecx + roll $17,%ecx + movl %eax,%r11d + addl %edx,%ecx + xorl %edx,%r11d + leal 1236535329(%rbx,%r10,1),%ebx + andl %ecx,%r11d + xorl %eax,%r11d + movl 0(%rsi),%r10d + addl %r11d,%ebx + roll $22,%ebx + movl %edx,%r11d + addl %ecx,%ebx + movl 4(%rsi),%r10d + movl %edx,%r11d + movl %edx,%r12d + notl %r11d + leal -165796510(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 24(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1069501632(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 44(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 643717713(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -373897302(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 20(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -701558691(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 40(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal 38016083(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 60(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -660478335(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 16(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -405537848(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 36(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal 568446438(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 56(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -1019803690(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 12(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal -187363961(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 32(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal 1163531501(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 52(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + notl %r11d + leal -1444681467(%rax,%r10,1),%eax + andl %ebx,%r12d + andl %ecx,%r11d + movl 8(%rsi),%r10d + orl %r11d,%r12d + movl %ecx,%r11d + addl %r12d,%eax + movl %ecx,%r12d + roll $5,%eax + addl %ebx,%eax + notl %r11d + leal -51403784(%rdx,%r10,1),%edx + andl %eax,%r12d + andl %ebx,%r11d + movl 28(%rsi),%r10d + orl %r11d,%r12d + movl %ebx,%r11d + addl %r12d,%edx + movl %ebx,%r12d + roll $9,%edx + addl %eax,%edx + notl %r11d + leal 1735328473(%rcx,%r10,1),%ecx + andl %edx,%r12d + andl %eax,%r11d + movl 48(%rsi),%r10d + orl %r11d,%r12d + movl %eax,%r11d + addl %r12d,%ecx + movl %eax,%r12d + roll $14,%ecx + addl %edx,%ecx + notl %r11d + leal -1926607734(%rbx,%r10,1),%ebx + andl %ecx,%r12d + andl %edx,%r11d + movl 0(%rsi),%r10d + orl %r11d,%r12d + movl %edx,%r11d + addl %r12d,%ebx + movl %edx,%r12d + roll $20,%ebx + addl %ecx,%ebx + movl 20(%rsi),%r10d + movl %ecx,%r11d + leal -378558(%rax,%r10,1),%eax + movl 32(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -2022574463(%rdx,%r10,1),%edx + movl 44(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 1839030562(%rcx,%r10,1),%ecx + movl 56(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -35309556(%rbx,%r10,1),%ebx + movl 4(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -1530992060(%rax,%r10,1),%eax + movl 16(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal 1272893353(%rdx,%r10,1),%edx + movl 28(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -155497632(%rcx,%r10,1),%ecx + movl 40(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -1094730640(%rbx,%r10,1),%ebx + movl 52(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal 681279174(%rax,%r10,1),%eax + movl 0(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -358537222(%rdx,%r10,1),%edx + movl 12(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal -722521979(%rcx,%r10,1),%ecx + movl 24(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal 76029189(%rbx,%r10,1),%ebx + movl 36(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + leal -640364487(%rax,%r10,1),%eax + movl 48(%rsi),%r10d + xorl %edx,%r11d + xorl %ebx,%r11d + addl %r11d,%eax + roll $4,%eax + movl %ebx,%r11d + addl %ebx,%eax + leal -421815835(%rdx,%r10,1),%edx + movl 60(%rsi),%r10d + xorl %ecx,%r11d + xorl %eax,%r11d + addl %r11d,%edx + roll $11,%edx + movl %eax,%r11d + addl %eax,%edx + leal 530742520(%rcx,%r10,1),%ecx + movl 8(%rsi),%r10d + xorl %ebx,%r11d + xorl %edx,%r11d + addl %r11d,%ecx + roll $16,%ecx + movl %edx,%r11d + addl %edx,%ecx + leal -995338651(%rbx,%r10,1),%ebx + movl 0(%rsi),%r10d + xorl %eax,%r11d + xorl %ecx,%r11d + addl %r11d,%ebx + roll $23,%ebx + movl %ecx,%r11d + addl %ecx,%ebx + movl 0(%rsi),%r10d + movl $0xffffffff,%r11d + xorl %edx,%r11d + leal -198630844(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 28(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal 1126891415(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 56(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1416354905(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 20(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -57434055(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 48(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1700485571(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 12(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1894986606(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 40(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1051523(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 4(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -2054922799(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 32(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal 1873313359(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 60(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -30611744(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 24(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal -1560198380(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 52(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal 1309151649(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 16(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + leal -145523070(%rax,%r10,1),%eax + orl %ebx,%r11d + xorl %ecx,%r11d + addl %r11d,%eax + movl 44(%rsi),%r10d + movl $0xffffffff,%r11d + roll $6,%eax + xorl %ecx,%r11d + addl %ebx,%eax + leal -1120210379(%rdx,%r10,1),%edx + orl %eax,%r11d + xorl %ebx,%r11d + addl %r11d,%edx + movl 8(%rsi),%r10d + movl $0xffffffff,%r11d + roll $10,%edx + xorl %ebx,%r11d + addl %eax,%edx + leal 718787259(%rcx,%r10,1),%ecx + orl %edx,%r11d + xorl %eax,%r11d + addl %r11d,%ecx + movl 36(%rsi),%r10d + movl $0xffffffff,%r11d + roll $15,%ecx + xorl %eax,%r11d + addl %edx,%ecx + leal -343485551(%rbx,%r10,1),%ebx + orl %ecx,%r11d + xorl %edx,%r11d + addl %r11d,%ebx + movl 0(%rsi),%r10d + movl $0xffffffff,%r11d + roll $21,%ebx + xorl %edx,%r11d + addl %ecx,%ebx + + addl %r8d,%eax + addl %r9d,%ebx + addl %r14d,%ecx + addl %r15d,%edx + + + addq $64,%rsi + cmpq %rdi,%rsi + jb L$loop + + +L$end: + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + movq (%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r12 + + movq 24(%rsp),%rbx + + movq 32(%rsp),%rbp + + addq $40,%rsp + +L$epilogue: + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/internal.h new file mode 100644 index 00000000..4119ef71 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/internal.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_MD5_INTERNAL_H +#define OPENSSL_HEADER_MD5_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define MD5_ASM +extern void md5_block_asm_data_order(uint32_t *state, const uint8_t *data, + size_t num); +#endif + + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // OPENSSL_HEADER_MD5_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/md5.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/md5.c new file mode 100644 index 00000000..7c57cdc6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/md5/md5.c @@ -0,0 +1,284 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "../../internal.h" +#include "../digest/md32_common.h" +#include "internal.h" + + +uint8_t *MD5(const uint8_t *data, size_t len, uint8_t out[MD5_DIGEST_LENGTH]) { + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, data, len); + MD5_Final(out, &ctx); + + return out; +} + +int MD5_Init(MD5_CTX *md5) { + OPENSSL_memset(md5, 0, sizeof(MD5_CTX)); + md5->h[0] = 0x67452301UL; + md5->h[1] = 0xefcdab89UL; + md5->h[2] = 0x98badcfeUL; + md5->h[3] = 0x10325476UL; + return 1; +} + +#if defined(MD5_ASM) +#define md5_block_data_order md5_block_asm_data_order +#else +static void md5_block_data_order(uint32_t *state, const uint8_t *data, + size_t num); +#endif + +void MD5_Transform(MD5_CTX *c, const uint8_t data[MD5_CBLOCK]) { + md5_block_data_order(c->h, data, 1); +} + +int MD5_Update(MD5_CTX *c, const void *data, size_t len) { + crypto_md32_update(&md5_block_data_order, c->h, c->data, MD5_CBLOCK, &c->num, + &c->Nh, &c->Nl, data, len); + return 1; +} + +int MD5_Final(uint8_t out[MD5_DIGEST_LENGTH], MD5_CTX *c) { + crypto_md32_final(&md5_block_data_order, c->h, c->data, MD5_CBLOCK, &c->num, + c->Nh, c->Nl, /*is_big_endian=*/0); + + CRYPTO_store_u32_le(out, c->h[0]); + CRYPTO_store_u32_le(out + 4, c->h[1]); + CRYPTO_store_u32_le(out + 8, c->h[2]); + CRYPTO_store_u32_le(out + 12, c->h[3]); + return 1; +} + +// As pointed out by Wei Dai , the above can be +// simplified to the code below. Wei attributes these optimizations +// to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. +#define F(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b, c, d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b, c, d) ((b) ^ (c) ^ (d)) +#define I(b, c, d) (((~(d)) | (b)) ^ (c)) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + (a) += (b); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + (a) += (b); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + (a) += (b); \ + } while (0) + +#define R3(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + I((b), (c), (d))); \ + (a) = CRYPTO_rotl_u32(a, s); \ + (a) += (b); \ + } while (0) + +#ifndef MD5_ASM +#ifdef X +#undef X +#endif +static void md5_block_data_order(uint32_t *state, const uint8_t *data, + size_t num) { + uint32_t A, B, C, D; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12, + XX13, XX14, XX15; +#define X(i) XX##i + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + for (; num--;) { + X(0) = CRYPTO_load_u32_le(data); + data += 4; + X(1) = CRYPTO_load_u32_le(data); + data += 4; + // Round 0 + R0(A, B, C, D, X(0), 7, 0xd76aa478L); + X(2) = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X(1), 12, 0xe8c7b756L); + X(3) = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X(2), 17, 0x242070dbL); + X(4) = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X(3), 22, 0xc1bdceeeL); + X(5) = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X(4), 7, 0xf57c0fafL); + X(6) = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X(5), 12, 0x4787c62aL); + X(7) = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X(6), 17, 0xa8304613L); + X(8) = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X(7), 22, 0xfd469501L); + X(9) = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X(8), 7, 0x698098d8L); + X(10) = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X(9), 12, 0x8b44f7afL); + X(11) = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X(10), 17, 0xffff5bb1L); + X(12) = CRYPTO_load_u32_le(data); + data += 4; + R0(B, C, D, A, X(11), 22, 0x895cd7beL); + X(13) = CRYPTO_load_u32_le(data); + data += 4; + R0(A, B, C, D, X(12), 7, 0x6b901122L); + X(14) = CRYPTO_load_u32_le(data); + data += 4; + R0(D, A, B, C, X(13), 12, 0xfd987193L); + X(15) = CRYPTO_load_u32_le(data); + data += 4; + R0(C, D, A, B, X(14), 17, 0xa679438eL); + R0(B, C, D, A, X(15), 22, 0x49b40821L); + // Round 1 + R1(A, B, C, D, X(1), 5, 0xf61e2562L); + R1(D, A, B, C, X(6), 9, 0xc040b340L); + R1(C, D, A, B, X(11), 14, 0x265e5a51L); + R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL); + R1(A, B, C, D, X(5), 5, 0xd62f105dL); + R1(D, A, B, C, X(10), 9, 0x02441453L); + R1(C, D, A, B, X(15), 14, 0xd8a1e681L); + R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L); + R1(A, B, C, D, X(9), 5, 0x21e1cde6L); + R1(D, A, B, C, X(14), 9, 0xc33707d6L); + R1(C, D, A, B, X(3), 14, 0xf4d50d87L); + R1(B, C, D, A, X(8), 20, 0x455a14edL); + R1(A, B, C, D, X(13), 5, 0xa9e3e905L); + R1(D, A, B, C, X(2), 9, 0xfcefa3f8L); + R1(C, D, A, B, X(7), 14, 0x676f02d9L); + R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL); + // Round 2 + R2(A, B, C, D, X(5), 4, 0xfffa3942L); + R2(D, A, B, C, X(8), 11, 0x8771f681L); + R2(C, D, A, B, X(11), 16, 0x6d9d6122L); + R2(B, C, D, A, X(14), 23, 0xfde5380cL); + R2(A, B, C, D, X(1), 4, 0xa4beea44L); + R2(D, A, B, C, X(4), 11, 0x4bdecfa9L); + R2(C, D, A, B, X(7), 16, 0xf6bb4b60L); + R2(B, C, D, A, X(10), 23, 0xbebfbc70L); + R2(A, B, C, D, X(13), 4, 0x289b7ec6L); + R2(D, A, B, C, X(0), 11, 0xeaa127faL); + R2(C, D, A, B, X(3), 16, 0xd4ef3085L); + R2(B, C, D, A, X(6), 23, 0x04881d05L); + R2(A, B, C, D, X(9), 4, 0xd9d4d039L); + R2(D, A, B, C, X(12), 11, 0xe6db99e5L); + R2(C, D, A, B, X(15), 16, 0x1fa27cf8L); + R2(B, C, D, A, X(2), 23, 0xc4ac5665L); + // Round 3 + R3(A, B, C, D, X(0), 6, 0xf4292244L); + R3(D, A, B, C, X(7), 10, 0x432aff97L); + R3(C, D, A, B, X(14), 15, 0xab9423a7L); + R3(B, C, D, A, X(5), 21, 0xfc93a039L); + R3(A, B, C, D, X(12), 6, 0x655b59c3L); + R3(D, A, B, C, X(3), 10, 0x8f0ccc92L); + R3(C, D, A, B, X(10), 15, 0xffeff47dL); + R3(B, C, D, A, X(1), 21, 0x85845dd1L); + R3(A, B, C, D, X(8), 6, 0x6fa87e4fL); + R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L); + R3(C, D, A, B, X(6), 15, 0xa3014314L); + R3(B, C, D, A, X(13), 21, 0x4e0811a1L); + R3(A, B, C, D, X(4), 6, 0xf7537e82L); + R3(D, A, B, C, X(11), 10, 0xbd3af235L); + R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL); + R3(B, C, D, A, X(9), 21, 0xeb86d391L); + + A = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} +#undef X +#endif + +#undef F +#undef G +#undef H +#undef I +#undef R0 +#undef R1 +#undef R2 +#undef R3 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cbc.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cbc.c new file mode 100644 index 00000000..2afaa262 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cbc.c @@ -0,0 +1,178 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + block128_f block) { + assert(key != NULL && ivec != NULL); + if (len == 0) { + // Avoid |ivec| == |iv| in the |memcpy| below, which is not legal in C. + return; + } + + assert(in != NULL && out != NULL); + size_t n; + const uint8_t *iv = ivec; + while (len >= 16) { + for (n = 0; n < 16; n += sizeof(crypto_word_t)) { + CRYPTO_store_word_le( + out + n, CRYPTO_load_word_le(in + n) ^ CRYPTO_load_word_le(iv + n)); + } + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + + while (len) { + for (n = 0; n < 16 && n < len; ++n) { + out[n] = in[n] ^ iv[n]; + } + for (; n < 16; ++n) { + out[n] = iv[n]; + } + (*block)(out, out, key); + iv = out; + if (len <= 16) { + break; + } + len -= 16; + in += 16; + out += 16; + } + + OPENSSL_memcpy(ivec, iv, 16); +} + +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + block128_f block) { + assert(key != NULL && ivec != NULL); + if (len == 0) { + // Avoid |ivec| == |iv| in the |memcpy| below, which is not legal in C. + return; + } + + assert(in != NULL && out != NULL); + + const uintptr_t inptr = (uintptr_t) in; + const uintptr_t outptr = (uintptr_t) out; + // If |in| and |out| alias, |in| must be ahead. + assert(inptr >= outptr || inptr + len <= outptr); + + size_t n; + union { + crypto_word_t t[16 / sizeof(crypto_word_t)]; + uint8_t c[16]; + } tmp; + + if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { + // If |out| is at least two blocks behind |in| or completely disjoint, there + // is no need to decrypt to a temporary block. + OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, + "block cannot be evenly divided into words"); + const uint8_t *iv = ivec; + while (len >= 16) { + (*block)(in, out, key); + for (n = 0; n < 16; n += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(out + n) ^ + CRYPTO_load_word_le(iv + n)); + } + iv = in; + len -= 16; + in += 16; + out += 16; + } + OPENSSL_memcpy(ivec, iv, 16); + } else { + OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, + "block cannot be evenly divided into words"); + + while (len >= 16) { + (*block)(in, tmp.c, key); + for (n = 0; n < 16; n += sizeof(crypto_word_t)) { + crypto_word_t c = CRYPTO_load_word_le(in + n); + CRYPTO_store_word_le(out + n, tmp.t[n / sizeof(crypto_word_t)] ^ + CRYPTO_load_word_le(ivec + n)); + CRYPTO_store_word_le(ivec + n, c); + } + len -= 16; + in += 16; + out += 16; + } + } + + while (len) { + uint8_t c; + (*block)(in, tmp.c, key); + for (n = 0; n < 16 && n < len; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + if (len <= 16) { + for (; n < 16; ++n) { + ivec[n] = in[n]; + } + break; + } + len -= 16; + in += 16; + out += 16; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cfb.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cfb.c new file mode 100644 index 00000000..9cb9c6ad --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cfb.c @@ -0,0 +1,203 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include + +#include "internal.h" + + +OPENSSL_STATIC_ASSERT(16 % sizeof(size_t) == 0, + "block cannot be divided into size_t"); + +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block) { + assert(in && out && key && ivec && num); + + unsigned n = *num; + + if (enc) { + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(crypto_word_t)) { + crypto_word_t tmp = + CRYPTO_load_word_le(ivec + n) ^ CRYPTO_load_word_le(in + n); + CRYPTO_store_word_le(ivec + n, tmp); + CRYPTO_store_word_le(out + n, tmp); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } else { + while (n && len) { + uint8_t c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(crypto_word_t)) { + crypto_word_t t = CRYPTO_load_word_le(in + n); + CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(ivec + n) ^ t); + CRYPTO_store_word_le(ivec + n, t); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + uint8_t c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } +} + + +/* This expects a single block of size nbits for both in and out. Note that + it corrupts any extra bits in the last byte of out */ +static void cfbr_encrypt_block(const uint8_t *in, uint8_t *out, unsigned nbits, + const AES_KEY *key, uint8_t ivec[16], int enc, + block128_f block) { + int n, rem, num; + uint8_t ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't use) one + byte off the end */ + + if (nbits <= 0 || nbits > 128) { + return; + } + + // fill in the first half of the new IV with the current IV + OPENSSL_memcpy(ovec, ivec, 16); + // construct the new IV + (*block)(ivec, ivec, key); + num = (nbits + 7) / 8; + if (enc) { + // encrypt the input + for (n = 0; n < num; ++n) { + out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); + } + } else { + // decrypt the input + for (n = 0; n < num; ++n) { + out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; + } + } + // shift ovec left... + rem = nbits % 8; + num = nbits / 8; + if (rem == 0) { + OPENSSL_memcpy(ivec, ovec + num, 16); + } else { + for (n = 0; n < 16; ++n) { + ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); + } + } + + // it is not necessary to cleanse ovec, since the IV is not secret +} + +// N.B. This expects the input to be packed, MS bit first +void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits, + const AES_KEY *key, uint8_t ivec[16], + unsigned *num, int enc, block128_f block) { + size_t n; + uint8_t c[1], d[1]; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < bits; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); + out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } +} + +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[16], unsigned *num, int enc, + block128_f block) { + size_t n; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < length; ++n) { + cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ctr.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ctr.c new file mode 100644 index 00000000..893a58d0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ctr.c @@ -0,0 +1,201 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// NOTE: the IV/counter CTR mode is big-endian. The code itself +// is endian-neutral. + +// increment counter (128-bit int) by 1 +static void ctr128_inc(uint8_t *counter) { + uint32_t n = 16, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, + "block cannot be divided into crypto_word_t"); + +// The input encrypted as though 128bit counter mode is being used. The extra +// state information to record how much of the 128bit block we have used is +// contained in *num, and the encrypted counter is kept in ecount_buf. Both +// *num and ecount_buf must be initialised with zeros before the first call to +// CRYPTO_ctr128_encrypt(). +// +// This algorithm assumes that the counter is in the x lower bits of the IV +// (ivec), and that the application has full control over overflow and the rest +// of the IV. This implementation takes NO responsibility for checking that +// the counter doesn't overflow into the rest of the IV when incremented. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned int *num, + block128_f block) { + unsigned int n; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + while (len >= 16) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + for (n = 0; n < 16; n += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(in + n) ^ + CRYPTO_load_word_le(ecount_buf + n)); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; +} + +// increment upper 96 bits of 128-bit counter by 1 +static void ctr96_inc(uint8_t *counter) { + uint32_t n = 12, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned int *num, + ctr128_f func) { + unsigned int n, ctr32; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + + ctr32 = CRYPTO_load_u32_be(ivec + 12); + while (len >= 16) { + size_t blocks = len / 16; + // 1<<28 is just a not-so-small yet not-so-large number... + // Below condition is practically never met, but it has to + // be checked for code correctness. + if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) { + blocks = (1U << 28); + } + // As (*func) operates on 32-bit counter, caller + // has to handle overflow. 'if' below detects the + // overflow, which is then handled by limiting the + // amount of blocks to the exact overflow point... + ctr32 += (uint32_t)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func)(in, out, blocks, key, ivec); + // (*func) does not update ivec, caller does: + CRYPTO_store_u32_be(ivec + 12, ctr32); + // ... overflow was detected, propogate carry. + if (ctr32 == 0) { + ctr96_inc(ivec); + } + blocks *= 16; + len -= blocks; + out += blocks; + in += blocks; + } + if (len) { + OPENSSL_memset(ecount_buf, 0, 16); + (*func)(ecount_buf, ecount_buf, 1, key, ivec); + ++ctr32; + CRYPTO_store_u32_be(ivec + 12, ctr32); + if (ctr32 == 0) { + ctr96_inc(ivec); + } + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + + *num = n; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c new file mode 100644 index 00000000..d3c512ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c @@ -0,0 +1,730 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four +// bits of a |size_t|. +static const size_t kSizeTWithoutLower4Bits = (size_t) -16; + + +#define GCM_MUL(ctx, Xi) gcm_gmult_nohw((ctx)->Xi.u, (ctx)->gcm_key.Htable) +#define GHASH(ctx, in, len) \ + gcm_ghash_nohw((ctx)->Xi.u, (ctx)->gcm_key.Htable, in, len) +// GHASH_CHUNK is "stride parameter" missioned to mitigate cache +// trashing effect. In other words idea is to hash data while it's +// still in L1 cache after encryption pass... +#define GHASH_CHUNK (3 * 1024) + +#if defined(GHASH_ASM_X86_64) || defined(GHASH_ASM_X86) +static inline void gcm_reduce_1bit(u128 *V) { + if (sizeof(crypto_word_t) == 8) { + uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V->hi & 1)); + V->hi = (V->lo << 63) | (V->hi >> 1); + V->lo = (V->lo >> 1) ^ T; + } else { + uint32_t T = 0xe1000000U & (0 - (uint32_t)(V->hi & 1)); + V->hi = (V->lo << 63) | (V->hi >> 1); + V->lo = (V->lo >> 1) ^ ((uint64_t)T << 32); + } +} + +void gcm_init_ssse3(u128 Htable[16], const uint64_t H[2]) { + Htable[0].hi = 0; + Htable[0].lo = 0; + u128 V; + V.hi = H[1]; + V.lo = H[0]; + + Htable[8] = V; + gcm_reduce_1bit(&V); + Htable[4] = V; + gcm_reduce_1bit(&V); + Htable[2] = V; + gcm_reduce_1bit(&V); + Htable[1] = V; + Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; + V = Htable[4]; + Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; + Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; + Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; + V = Htable[8]; + Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; + Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo; + Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo; + Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo; + Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo; + Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo; + Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo; + + // Treat |Htable| as a 16x16 byte table and transpose it. Thus, Htable[i] + // contains the i'th byte of j*H for all j. + uint8_t *Hbytes = (uint8_t *)Htable; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < i; j++) { + uint8_t tmp = Hbytes[16*i + j]; + Hbytes[16*i + j] = Hbytes[16*j + i]; + Hbytes[16*j + i] = tmp; + } + } +} +#endif // GHASH_ASM_X86_64 || GHASH_ASM_X86 + +#ifdef GCM_FUNCREF +#undef GCM_MUL +#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi.u, (ctx)->gcm_key.Htable) +#undef GHASH +#define GHASH(ctx, in, len) \ + (*gcm_ghash_p)((ctx)->Xi.u, (ctx)->gcm_key.Htable, in, len) +#endif // GCM_FUNCREF + +void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], int *out_is_avx, + const uint8_t gcm_key[16]) { + *out_is_avx = 0; + + union { + uint64_t u[2]; + uint8_t c[16]; + } H; + + OPENSSL_memcpy(H.c, gcm_key, 16); + + // H is stored in host byte order + H.u[0] = CRYPTO_bswap8(H.u[0]); + H.u[1] = CRYPTO_bswap8(H.u[1]); + + OPENSSL_memcpy(out_key, H.c, 16); + +#if defined(GHASH_ASM_X86_64) + if (crypto_gcm_clmul_enabled()) { + if (CRYPTO_is_AVX_capable() && CRYPTO_is_MOVBE_capable()) { + gcm_init_avx(out_table, H.u); + *out_mult = gcm_gmult_avx; + *out_hash = gcm_ghash_avx; + *out_is_avx = 1; + return; + } + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } + if (CRYPTO_is_SSSE3_capable()) { + gcm_init_ssse3(out_table, H.u); + *out_mult = gcm_gmult_ssse3; + *out_hash = gcm_ghash_ssse3; + return; + } +#elif defined(GHASH_ASM_X86) + if (crypto_gcm_clmul_enabled()) { + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } + if (CRYPTO_is_SSSE3_capable()) { + gcm_init_ssse3(out_table, H.u); + *out_mult = gcm_gmult_ssse3; + *out_hash = gcm_ghash_ssse3; + return; + } +#elif defined(GHASH_ASM_ARM) + if (gcm_pmull_capable()) { + gcm_init_v8(out_table, H.u); + *out_mult = gcm_gmult_v8; + *out_hash = gcm_ghash_v8; + return; + } + + if (gcm_neon_capable()) { + gcm_init_neon(out_table, H.u); + *out_mult = gcm_gmult_neon; + *out_hash = gcm_ghash_neon; + return; + } +#elif defined(GHASH_ASM_PPC64LE) + if (CRYPTO_is_PPC64LE_vcrypto_capable()) { + gcm_init_p8(out_table, H.u); + *out_mult = gcm_gmult_p8; + *out_hash = gcm_ghash_p8; + return; + } +#endif + + gcm_init_nohw(out_table, H.u); + *out_mult = gcm_gmult_nohw; + *out_hash = gcm_ghash_nohw; +} + +void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, const AES_KEY *aes_key, + block128_f block, int block_is_hwaes) { + OPENSSL_memset(gcm_key, 0, sizeof(*gcm_key)); + gcm_key->block = block; + + uint8_t ghash_key[16]; + OPENSSL_memset(ghash_key, 0, sizeof(ghash_key)); + (*block)(ghash_key, ghash_key, aes_key); + + int is_avx; + CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, &gcm_key->H, + gcm_key->Htable, &is_avx, ghash_key); + + gcm_key->use_aesni_gcm_crypt = (is_avx && block_is_hwaes) ? 1 : 0; +} + +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, + const uint8_t *iv, size_t len) { +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; +#endif + + ctx->Yi.u[0] = 0; + ctx->Yi.u[1] = 0; + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + ctx->len.u[0] = 0; // AAD length + ctx->len.u[1] = 0; // message length + ctx->ares = 0; + ctx->mres = 0; + + uint32_t ctr; + if (len == 12) { + OPENSSL_memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + uint64_t len0 = len; + + while (len >= 16) { + for (size_t i = 0; i < 16; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (size_t i = 0; i < len; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + ctx->Yi.u[1] ^= CRYPTO_bswap8(len0); + + GCM_MUL(ctx, Yi); + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + } + + (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EK0.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); +} + +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->gcm_key.ghash; +#endif + + if (ctx->len.u[1]) { + return 0; + } + + uint64_t alen = ctx->len.u[0] + len; + if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { + return 0; + } + ctx->len.u[0] = alen; + + unsigned n = ctx->ares; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(aad++); + --len; + n = (n + 1) % 16; + } + if (n == 0) { + GCM_MUL(ctx, Xi); + } else { + ctx->ares = n; + return 1; + } + } + + // Process a whole number of blocks. + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, aad, len_blocks); + aad += len_blocks; + len -= len_blocks; + } + + // Process the remainder. + if (len != 0) { + n = (unsigned int)len; + for (size_t i = 0; i < len; ++i) { + ctx->Xi.c[i] ^= aad[i]; + } + } + + ctx->ares = n; + return 1; +} + +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, + const uint8_t *in, uint8_t *out, size_t len) { + block128_f block = ctx->gcm_key.block; +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->gcm_key.ghash; +#endif + + uint64_t mlen = ctx->len.u[1] + len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + unsigned n = ctx->mres; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) { + GCM_MUL(ctx, Xi); + } else { + ctx->mres = n; + return 1; + } + } + + uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + i, + CRYPTO_load_word_le(in + i) ^ + ctx->EKi.t[i / sizeof(crypto_word_t)]); + } + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + i, + CRYPTO_load_word_le(in + i) ^ + ctx->EKi.t[i / sizeof(crypto_word_t)]); + } + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - len_blocks, len_blocks); + } + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, + const unsigned char *in, unsigned char *out, + size_t len) { + block128_f block = ctx->gcm_key.block; +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->gcm_key.ghash; +#endif + + uint64_t mlen = ctx->len.u[1] + len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + unsigned n = ctx->mres; + if (n) { + while (n && len) { + uint8_t c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) { + GCM_MUL(ctx, Xi); + } else { + ctx->mres = n; + return 1; + } + } + + uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + i, + CRYPTO_load_word_le(in + i) ^ + ctx->EKi.t[i / sizeof(crypto_word_t)]); + } + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, in, len_blocks); + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { + CRYPTO_store_word_le(out + i, + CRYPTO_load_word_le(in + i) ^ + ctx->EKi.t[i / sizeof(crypto_word_t)]); + } + out += 16; + in += 16; + len -= 16; + } + } + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->gcm_key.ghash; +#endif + + uint64_t mlen = ctx->len.u[1] + len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + unsigned n = ctx->mres; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) { + GCM_MUL(ctx, Xi); + } else { + ctx->mres = n; + return 1; + } + } + +#if defined(AESNI_GCM) + // Check |len| to work around a C language bug. See https://crbug.com/1019588. + if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { + // |aesni_gcm_encrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + while (len >= GHASH_CHUNK) { + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + size_t j = len_blocks / 16; + + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + in += len_blocks; + len -= len_blocks; + GHASH(ctx, out, len_blocks); + out += len_blocks; + } + if (len) { + (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->gcm_key.ghash; +#endif + + uint64_t mlen = ctx->len.u[1] + len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + unsigned n = ctx->mres; + if (n) { + while (n && len) { + uint8_t c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) { + GCM_MUL(ctx, Xi); + } else { + ctx->mres = n; + return 1; + } + } + +#if defined(AESNI_GCM) + // Check |len| to work around a C language bug. See https://crbug.com/1019588. + if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { + // |aesni_gcm_decrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + size_t j = len_blocks / 16; + + GHASH(ctx, in, len_blocks); + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += len_blocks; + in += len_blocks; + len -= len_blocks; + } + if (len) { + (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { +#ifdef GCM_FUNCREF + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + ctx->gcm_key.gmult; +#endif + + if (ctx->mres || ctx->ares) { + GCM_MUL(ctx, Xi); + } + + ctx->Xi.u[0] ^= CRYPTO_bswap8(ctx->len.u[0] << 3); + ctx->Xi.u[1] ^= CRYPTO_bswap8(ctx->len.u[1] << 3); + GCM_MUL(ctx, Xi); + + ctx->Xi.u[0] ^= ctx->EK0.u[0]; + ctx->Xi.u[1] ^= ctx->EK0.u[1]; + + if (tag && len <= sizeof(ctx->Xi)) { + return CRYPTO_memcmp(ctx->Xi.c, tag, len) == 0; + } else { + return 0; + } +} + +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) { + CRYPTO_gcm128_finish(ctx, NULL, 0); + OPENSSL_memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +int crypto_gcm_clmul_enabled(void) { +#if defined(GHASH_ASM_X86) || defined(GHASH_ASM_X86_64) + return CRYPTO_is_FXSR_capable() && CRYPTO_is_PCLMUL_capable(); +#else + return 0; +#endif +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm_nohw.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm_nohw.c new file mode 100644 index 00000000..de019a9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm_nohw.c @@ -0,0 +1,304 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include "../../internal.h" +#include "internal.h" + +#if !defined(BORINGSSL_HAS_UINT128) && defined(OPENSSL_SSE2) +#include +#endif + + +// This file contains a constant-time implementation of GHASH based on the notes +// in https://bearssl.org/constanttime.html#ghash-for-gcm and the reduction +// algorithm described in +// https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf. +// +// Unlike the BearSSL notes, we use uint128_t in the 64-bit implementation. Our +// primary compilers (clang, clang-cl, and gcc) all support it. MSVC will run +// the 32-bit implementation, but we can use its intrinsics if necessary. + +#if defined(BORINGSSL_HAS_UINT128) + +static void gcm_mul64_nohw(uint64_t *out_lo, uint64_t *out_hi, uint64_t a, + uint64_t b) { + // One term every four bits means the largest term is 64/4 = 16, which barely + // overflows into the next term. Using one term every five bits would cost 25 + // multiplications instead of 16. It is faster to mask off the bottom four + // bits of |a|, giving a largest term of 60/4 = 15, and apply the bottom bits + // separately. + uint64_t a0 = a & UINT64_C(0x1111111111111110); + uint64_t a1 = a & UINT64_C(0x2222222222222220); + uint64_t a2 = a & UINT64_C(0x4444444444444440); + uint64_t a3 = a & UINT64_C(0x8888888888888880); + + uint64_t b0 = b & UINT64_C(0x1111111111111111); + uint64_t b1 = b & UINT64_C(0x2222222222222222); + uint64_t b2 = b & UINT64_C(0x4444444444444444); + uint64_t b3 = b & UINT64_C(0x8888888888888888); + + uint128_t c0 = (a0 * (uint128_t)b0) ^ (a1 * (uint128_t)b3) ^ + (a2 * (uint128_t)b2) ^ (a3 * (uint128_t)b1); + uint128_t c1 = (a0 * (uint128_t)b1) ^ (a1 * (uint128_t)b0) ^ + (a2 * (uint128_t)b3) ^ (a3 * (uint128_t)b2); + uint128_t c2 = (a0 * (uint128_t)b2) ^ (a1 * (uint128_t)b1) ^ + (a2 * (uint128_t)b0) ^ (a3 * (uint128_t)b3); + uint128_t c3 = (a0 * (uint128_t)b3) ^ (a1 * (uint128_t)b2) ^ + (a2 * (uint128_t)b1) ^ (a3 * (uint128_t)b0); + + // Multiply the bottom four bits of |a| with |b|. + uint64_t a0_mask = UINT64_C(0) - (a & 1); + uint64_t a1_mask = UINT64_C(0) - ((a >> 1) & 1); + uint64_t a2_mask = UINT64_C(0) - ((a >> 2) & 1); + uint64_t a3_mask = UINT64_C(0) - ((a >> 3) & 1); + uint128_t extra = (a0_mask & b) ^ ((uint128_t)(a1_mask & b) << 1) ^ + ((uint128_t)(a2_mask & b) << 2) ^ + ((uint128_t)(a3_mask & b) << 3); + + *out_lo = (((uint64_t)c0) & UINT64_C(0x1111111111111111)) ^ + (((uint64_t)c1) & UINT64_C(0x2222222222222222)) ^ + (((uint64_t)c2) & UINT64_C(0x4444444444444444)) ^ + (((uint64_t)c3) & UINT64_C(0x8888888888888888)) ^ ((uint64_t)extra); + *out_hi = (((uint64_t)(c0 >> 64)) & UINT64_C(0x1111111111111111)) ^ + (((uint64_t)(c1 >> 64)) & UINT64_C(0x2222222222222222)) ^ + (((uint64_t)(c2 >> 64)) & UINT64_C(0x4444444444444444)) ^ + (((uint64_t)(c3 >> 64)) & UINT64_C(0x8888888888888888)) ^ + ((uint64_t)(extra >> 64)); +} + +#elif defined(OPENSSL_SSE2) + +static __m128i gcm_mul32_nohw(uint32_t a, uint32_t b) { + // One term every four bits means the largest term is 32/4 = 8, which does not + // overflow into the next term. + __m128i aa = _mm_setr_epi32(a, 0, a, 0); + __m128i bb = _mm_setr_epi32(b, 0, b, 0); + + __m128i a0a0 = + _mm_and_si128(aa, _mm_setr_epi32(0x11111111, 0, 0x11111111, 0)); + __m128i a2a2 = + _mm_and_si128(aa, _mm_setr_epi32(0x44444444, 0, 0x44444444, 0)); + __m128i b0b1 = + _mm_and_si128(bb, _mm_setr_epi32(0x11111111, 0, 0x22222222, 0)); + __m128i b2b3 = + _mm_and_si128(bb, _mm_setr_epi32(0x44444444, 0, 0x88888888, 0)); + + __m128i c0c1 = + _mm_xor_si128(_mm_mul_epu32(a0a0, b0b1), _mm_mul_epu32(a2a2, b2b3)); + __m128i c2c3 = + _mm_xor_si128(_mm_mul_epu32(a2a2, b0b1), _mm_mul_epu32(a0a0, b2b3)); + + __m128i a1a1 = + _mm_and_si128(aa, _mm_setr_epi32(0x22222222, 0, 0x22222222, 0)); + __m128i a3a3 = + _mm_and_si128(aa, _mm_setr_epi32(0x88888888, 0, 0x88888888, 0)); + __m128i b3b0 = + _mm_and_si128(bb, _mm_setr_epi32(0x88888888, 0, 0x11111111, 0)); + __m128i b1b2 = + _mm_and_si128(bb, _mm_setr_epi32(0x22222222, 0, 0x44444444, 0)); + + c0c1 = _mm_xor_si128(c0c1, _mm_mul_epu32(a1a1, b3b0)); + c0c1 = _mm_xor_si128(c0c1, _mm_mul_epu32(a3a3, b1b2)); + c2c3 = _mm_xor_si128(c2c3, _mm_mul_epu32(a3a3, b3b0)); + c2c3 = _mm_xor_si128(c2c3, _mm_mul_epu32(a1a1, b1b2)); + + c0c1 = _mm_and_si128( + c0c1, _mm_setr_epi32(0x11111111, 0x11111111, 0x22222222, 0x22222222)); + c2c3 = _mm_and_si128( + c2c3, _mm_setr_epi32(0x44444444, 0x44444444, 0x88888888, 0x88888888)); + + c0c1 = _mm_xor_si128(c0c1, c2c3); + // c0 ^= c1 + c0c1 = _mm_xor_si128(c0c1, _mm_srli_si128(c0c1, 8)); + return c0c1; +} + +static void gcm_mul64_nohw(uint64_t *out_lo, uint64_t *out_hi, uint64_t a, + uint64_t b) { + uint32_t a0 = a & 0xffffffff; + uint32_t a1 = a >> 32; + uint32_t b0 = b & 0xffffffff; + uint32_t b1 = b >> 32; + // Karatsuba multiplication. + __m128i lo = gcm_mul32_nohw(a0, b0); + __m128i hi = gcm_mul32_nohw(a1, b1); + __m128i mid = gcm_mul32_nohw(a0 ^ a1, b0 ^ b1); + mid = _mm_xor_si128(mid, lo); + mid = _mm_xor_si128(mid, hi); + __m128i ret = _mm_unpacklo_epi64(lo, hi); + mid = _mm_slli_si128(mid, 4); + mid = _mm_and_si128(mid, _mm_setr_epi32(0, 0xffffffff, 0xffffffff, 0)); + ret = _mm_xor_si128(ret, mid); + memcpy(out_lo, &ret, 8); + memcpy(out_hi, ((char*)&ret) + 8, 8); +} + +#else // !BORINGSSL_HAS_UINT128 && !OPENSSL_SSE2 + +static uint64_t gcm_mul32_nohw(uint32_t a, uint32_t b) { + // One term every four bits means the largest term is 32/4 = 8, which does not + // overflow into the next term. + uint32_t a0 = a & 0x11111111; + uint32_t a1 = a & 0x22222222; + uint32_t a2 = a & 0x44444444; + uint32_t a3 = a & 0x88888888; + + uint32_t b0 = b & 0x11111111; + uint32_t b1 = b & 0x22222222; + uint32_t b2 = b & 0x44444444; + uint32_t b3 = b & 0x88888888; + + uint64_t c0 = (a0 * (uint64_t)b0) ^ (a1 * (uint64_t)b3) ^ + (a2 * (uint64_t)b2) ^ (a3 * (uint64_t)b1); + uint64_t c1 = (a0 * (uint64_t)b1) ^ (a1 * (uint64_t)b0) ^ + (a2 * (uint64_t)b3) ^ (a3 * (uint64_t)b2); + uint64_t c2 = (a0 * (uint64_t)b2) ^ (a1 * (uint64_t)b1) ^ + (a2 * (uint64_t)b0) ^ (a3 * (uint64_t)b3); + uint64_t c3 = (a0 * (uint64_t)b3) ^ (a1 * (uint64_t)b2) ^ + (a2 * (uint64_t)b1) ^ (a3 * (uint64_t)b0); + + return (c0 & UINT64_C(0x1111111111111111)) | + (c1 & UINT64_C(0x2222222222222222)) | + (c2 & UINT64_C(0x4444444444444444)) | + (c3 & UINT64_C(0x8888888888888888)); +} + +static void gcm_mul64_nohw(uint64_t *out_lo, uint64_t *out_hi, uint64_t a, + uint64_t b) { + uint32_t a0 = a & 0xffffffff; + uint32_t a1 = a >> 32; + uint32_t b0 = b & 0xffffffff; + uint32_t b1 = b >> 32; + // Karatsuba multiplication. + uint64_t lo = gcm_mul32_nohw(a0, b0); + uint64_t hi = gcm_mul32_nohw(a1, b1); + uint64_t mid = gcm_mul32_nohw(a0 ^ a1, b0 ^ b1) ^ lo ^ hi; + *out_lo = lo ^ (mid << 32); + *out_hi = hi ^ (mid >> 32); +} + +#endif // BORINGSSL_HAS_UINT128 + +void gcm_init_nohw(u128 Htable[16], const uint64_t Xi[2]) { + // We implement GHASH in terms of POLYVAL, as described in RFC 8452. This + // avoids a shift by 1 in the multiplication, needed to account for bit + // reversal losing a bit after multiplication, that is, + // rev128(X) * rev128(Y) = rev255(X*Y). + // + // Per Appendix A, we run mulX_POLYVAL. Note this is the same transformation + // applied by |gcm_init_clmul|, etc. Note |Xi| has already been byteswapped. + // + // See also slide 16 of + // https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf + Htable[0].lo = Xi[1]; + Htable[0].hi = Xi[0]; + + uint64_t carry = Htable[0].hi >> 63; + carry = 0u - carry; + + Htable[0].hi <<= 1; + Htable[0].hi |= Htable[0].lo >> 63; + Htable[0].lo <<= 1; + + // The irreducible polynomial is 1 + x^121 + x^126 + x^127 + x^128, so we + // conditionally add 0xc200...0001. + Htable[0].lo ^= carry & 1; + Htable[0].hi ^= carry & UINT64_C(0xc200000000000000); + + // This implementation does not use the rest of |Htable|. +} + +static void gcm_polyval_nohw(uint64_t Xi[2], const u128 *H) { + // Karatsuba multiplication. The product of |Xi| and |H| is stored in |r0| + // through |r3|. Note there is no byte or bit reversal because we are + // evaluating POLYVAL. + uint64_t r0, r1; + gcm_mul64_nohw(&r0, &r1, Xi[0], H->lo); + uint64_t r2, r3; + gcm_mul64_nohw(&r2, &r3, Xi[1], H->hi); + uint64_t mid0, mid1; + gcm_mul64_nohw(&mid0, &mid1, Xi[0] ^ Xi[1], H->hi ^ H->lo); + mid0 ^= r0 ^ r2; + mid1 ^= r1 ^ r3; + r2 ^= mid1; + r1 ^= mid0; + + // Now we multiply our 256-bit result by x^-128 and reduce. |r2| and + // |r3| shifts into position and we must multiply |r0| and |r1| by x^-128. We + // have: + // + // 1 = x^121 + x^126 + x^127 + x^128 + // x^-128 = x^-7 + x^-2 + x^-1 + 1 + // + // This is the GHASH reduction step, but with bits flowing in reverse. + + // The x^-7, x^-2, and x^-1 terms shift bits past x^0, which would require + // another reduction steps. Instead, we gather the excess bits, incorporate + // them into |r0| and |r1| and reduce once. See slides 17-19 + // of https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf. + r1 ^= (r0 << 63) ^ (r0 << 62) ^ (r0 << 57); + + // 1 + r2 ^= r0; + r3 ^= r1; + + // x^-1 + r2 ^= r0 >> 1; + r2 ^= r1 << 63; + r3 ^= r1 >> 1; + + // x^-2 + r2 ^= r0 >> 2; + r2 ^= r1 << 62; + r3 ^= r1 >> 2; + + // x^-7 + r2 ^= r0 >> 7; + r2 ^= r1 << 57; + r3 ^= r1 >> 7; + + Xi[0] = r2; + Xi[1] = r3; +} + +void gcm_gmult_nohw(uint64_t Xi[2], const u128 Htable[16]) { + uint64_t swapped[2]; + swapped[0] = CRYPTO_bswap8(Xi[1]); + swapped[1] = CRYPTO_bswap8(Xi[0]); + gcm_polyval_nohw(swapped, &Htable[0]); + Xi[0] = CRYPTO_bswap8(swapped[1]); + Xi[1] = CRYPTO_bswap8(swapped[0]); +} + +void gcm_ghash_nohw(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) { + uint64_t swapped[2]; + swapped[0] = CRYPTO_bswap8(Xi[1]); + swapped[1] = CRYPTO_bswap8(Xi[0]); + + while (len >= 16) { + uint64_t block[2]; + OPENSSL_memcpy(block, inp, 16); + swapped[0] ^= CRYPTO_bswap8(block[1]); + swapped[1] ^= CRYPTO_bswap8(block[0]); + gcm_polyval_nohw(swapped, &Htable[0]); + inp += 16; + len -= 16; + } + + Xi[0] = CRYPTO_bswap8(swapped[1]); + Xi[1] = CRYPTO_bswap8(swapped[0]); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h new file mode 100644 index 00000000..5a081485 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h @@ -0,0 +1,415 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_MODES_INTERNAL_H +#define OPENSSL_HEADER_MODES_INTERNAL_H + +#include + +#include + +#include +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// block128_f is the type of an AES block cipher implementation. +// +// Unlike upstream OpenSSL, it and the other functions in this file hard-code +// |AES_KEY|. It is undefined in C to call a function pointer with anything +// other than the original type. Thus we either must match |block128_f| to the +// type signature of |AES_encrypt| and friends or pass in |void*| wrapper +// functions. +// +// These functions are called exclusively with AES, so we use the former. +typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], + const AES_KEY *key); + + +// CTR. + +// ctr128_f is the type of a function that performs CTR-mode encryption. +typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, + const AES_KEY *key, const uint8_t ivec[16]); + +// CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) +// |len| bytes from |in| to |out| using |block| in counter mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ecount_buf| and |*num|, which must be zeroed before the initial +// call. The counter is a 128-bit, big-endian value in |ivec| and is +// incremented by this function. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + block128_f block); + +// CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes +// |ctr|, a function that performs CTR mode but only deals with the lower 32 +// bits of the counter. This is useful when |ctr| can be an optimised +// function. +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + ctr128_f ctr); + + +// GCM. +// +// This API differs from the upstream API slightly. The |GCM128_CONTEXT| does +// not have a |key| pointer that points to the key as upstream's version does. +// Instead, every function takes a |key| parameter. This way |GCM128_CONTEXT| +// can be safely copied. Additionally, |gcm_key| is split into a separate +// struct. + +typedef struct { uint64_t hi,lo; } u128; + +// gmult_func multiplies |Xi| by the GCM key and writes the result back to +// |Xi|. +typedef void (*gmult_func)(uint64_t Xi[2], const u128 Htable[16]); + +// ghash_func repeatedly multiplies |Xi| by the GCM key and adds in blocks from +// |inp|. The result is written back to |Xi| and the |len| argument must be a +// multiple of 16. +typedef void (*ghash_func)(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len); + +typedef struct gcm128_key_st { + // Note the MOVBE-based, x86-64, GHASH assembly requires |H| and |Htable| to + // be the first two elements of this struct. Additionally, some assembly + // routines require a 16-byte-aligned |Htable| when hashing data, but not + // initialization. |GCM128_KEY| is not itself aligned to simplify embedding in + // |EVP_AEAD_CTX|, but |Htable|'s offset must be a multiple of 16. + u128 H; + u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; + + block128_f block; + + // use_aesni_gcm_crypt is true if this context should use the assembly + // functions |aesni_gcm_encrypt| and |aesni_gcm_decrypt| to process data. + unsigned use_aesni_gcm_crypt:1; +} GCM128_KEY; + +// GCM128_CONTEXT contains state for a single GCM operation. The structure +// should be zero-initialized before use. +typedef struct { + // The following 5 names follow names in GCM specification + union { + uint64_t u[2]; + uint32_t d[4]; + uint8_t c[16]; + crypto_word_t t[16 / sizeof(crypto_word_t)]; + } Yi, EKi, EK0, len, Xi; + + // Note that the order of |Xi| and |gcm_key| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. Additionally, some assembly routines require + // |gcm_key| to be 16-byte aligned. |GCM128_KEY| is not itself aligned to + // simplify embedding in |EVP_AEAD_CTX|. + alignas(16) GCM128_KEY gcm_key; + + unsigned mres, ares; +} GCM128_CONTEXT; + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is +// used. +int crypto_gcm_clmul_enabled(void); +#endif + +// CRYPTO_ghash_init writes a precomputed table of powers of |gcm_key| to +// |out_table| and sets |*out_mult| and |*out_hash| to (potentially hardware +// accelerated) functions for performing operations in the GHASH field. If the +// AVX implementation was used |*out_is_avx| will be true. +void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], int *out_is_avx, + const uint8_t gcm_key[16]); + +// CRYPTO_gcm128_init_key initialises |gcm_key| to use |block| (typically AES) +// with the given key. |block_is_hwaes| is one if |block| is |aes_hw_encrypt|. +OPENSSL_EXPORT void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, + const AES_KEY *key, block128_f block, + int block_is_hwaes); + +// CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the +// same key that was passed to |CRYPTO_gcm128_init|. +OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, + const uint8_t *iv, size_t iv_len); + +// CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. +// This must be called before and data is encrypted. It returns one on success +// and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, + size_t len); + +// CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const AES_KEY *key, const uint8_t *in, + uint8_t *out, size_t len); + +// CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const AES_KEY *key, const uint8_t *in, + uint8_t *out, size_t len); + +// CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const AES_KEY *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const AES_KEY *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_finish calculates the authenticator and compares it against +// |len| bytes of |tag|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, + size_t len); + +// CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. +// The minimum of |len| and 16 bytes are copied into |tag|. +OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, + size_t len); + + +// GCM assembly. + +void gcm_init_nohw(u128 Htable[16], const uint64_t H[2]); +void gcm_gmult_nohw(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_nohw(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#if !defined(OPENSSL_NO_ASM) + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +#define GCM_FUNCREF +void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_clmul(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +// |gcm_gmult_ssse3| and |gcm_ghash_ssse3| require |Htable| to be +// 16-byte-aligned, but |gcm_init_ssse3| does not. +void gcm_init_ssse3(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_ssse3(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_ssse3(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, + size_t len); + +#if defined(OPENSSL_X86_64) +#define GHASH_ASM_X86_64 +void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, + size_t len); + +#define AESNI_GCM +size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], uint64_t *Xi); +size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], uint64_t *Xi); +#endif // OPENSSL_X86_64 + +#if defined(OPENSSL_X86) +#define GHASH_ASM_X86 +#endif // OPENSSL_X86 + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#define GHASH_ASM_ARM +#define GCM_FUNCREF + +OPENSSL_INLINE int gcm_pmull_capable(void) { + return CRYPTO_is_ARMv8_PMULL_capable(); +} + +void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_v8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +OPENSSL_INLINE int gcm_neon_capable(void) { return CRYPTO_is_NEON_capable(); } + +void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#elif defined(OPENSSL_PPC64LE) +#define GHASH_ASM_PPC64LE +#define GCM_FUNCREF +void gcm_init_p8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_p8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#endif +#endif // OPENSSL_NO_ASM + + +// CBC. + +// cbc128_f is the type of a function that performs CBC-mode encryption. +typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], int enc); + +// CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. The input need not be a multiple of +// 128 bits long, but the output will round up to the nearest 128 bit multiple, +// zero padding the input if needed. The IV will be updated on return. +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + block128_f block); + +// CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. If |len| is not a multiple of 128 +// bits then only that many bytes will be written, but a multiple of 128 bits +// is always read from |in|. The IV will be updated on return. +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + block128_f block); + + +// OFB. + +// CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode) +// |len| bytes from |in| to |out| using |block| in OFB mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ivec| and |*num|, the latter must be zero before the initial +// call. +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], unsigned *num, + block128_f block); + + +// CFB. + +// CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB mode. There's no requirement that +// |len| be a multiple of any value and any partial blocks are stored in |ivec| +// and |*num|, the latter must be zero before the initial call. +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +// CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-8 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + unsigned *num, int enc, block128_f block); + +// CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-1 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits, + const AES_KEY *key, uint8_t ivec[16], + unsigned *num, int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + block128_f block); + + +// POLYVAL. +// +// POLYVAL is a polynomial authenticator that operates over a field very +// similar to the one that GHASH uses. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#section-3. + +typedef union { + uint64_t u[2]; + uint8_t c[16]; +} polyval_block; + +struct polyval_ctx { + // Note that the order of |S|, |H| and |Htable| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. Additionally, some assembly routines require + // |Htable| to be 16-byte aligned. + polyval_block S; + u128 H; + alignas(16) u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; +}; + +// CRYPTO_POLYVAL_init initialises |ctx| using |key|. +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]); + +// CRYPTO_POLYVAL_update_blocks updates the accumulator in |ctx| given the +// blocks from |in|. Only a whole number of blocks can be processed so |in_len| +// must be a multiple of 16. +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len); + +// CRYPTO_POLYVAL_finish writes the accumulator from |ctx| to |out|. +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MODES_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ofb.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ofb.c new file mode 100644 index 00000000..fd4078ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ofb.c @@ -0,0 +1,97 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#include + +#include +#include + +#include "internal.h" + + +OPENSSL_STATIC_ASSERT(16 % sizeof(size_t) == 0, + "block cannot be divided into size_t"); + +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], unsigned *num, + block128_f block) { + assert(key != NULL && ivec != NULL && num != NULL); + assert(len == 0 || (in != NULL && out != NULL)); + + unsigned n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } + + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t a, b; + OPENSSL_memcpy(&a, in + n, sizeof(size_t)); + OPENSSL_memcpy(&b, ivec + n, sizeof(size_t)); + + const size_t c = a ^ b; + OPENSSL_memcpy(out + n, &c, sizeof(size_t)); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + out[n] = in[n] ^ ivec[n]; + ++n; + } + } + *num = n; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/polyval.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/polyval.c new file mode 100644 index 00000000..5fd5309d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/modes/polyval.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// byte_reverse reverses the order of the bytes in |b->c|. +static void byte_reverse(polyval_block *b) { + const uint64_t t = CRYPTO_bswap8(b->u[0]); + b->u[0] = CRYPTO_bswap8(b->u[1]); + b->u[1] = t; +} + +// reverse_and_mulX_ghash interprets the bytes |b->c| as a reversed element of +// the GHASH field, multiplies that by 'x' and serialises the result back into +// |b|, but with GHASH's backwards bit ordering. +static void reverse_and_mulX_ghash(polyval_block *b) { + uint64_t hi = b->u[0]; + uint64_t lo = b->u[1]; + const crypto_word_t carry = constant_time_eq_w(hi & 1, 1); + hi >>= 1; + hi |= lo << 63; + lo >>= 1; + lo ^= ((uint64_t) constant_time_select_w(carry, 0xe1, 0)) << 56; + + b->u[0] = CRYPTO_bswap8(lo); + b->u[1] = CRYPTO_bswap8(hi); +} + +// POLYVAL(H, X_1, ..., X_n) = +// ByteReverse(GHASH(mulX_GHASH(ByteReverse(H)), ByteReverse(X_1), ..., +// ByteReverse(X_n))). +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#appendix-A. + +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]) { + polyval_block H; + OPENSSL_memcpy(H.c, key, 16); + reverse_and_mulX_ghash(&H); + + int is_avx; + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, + H.c); + OPENSSL_memset(&ctx->S, 0, sizeof(ctx->S)); +} + +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len) { + assert((in_len & 15) == 0); + polyval_block reversed[32]; + + while (in_len > 0) { + size_t todo = in_len; + if (todo > sizeof(reversed)) { + todo = sizeof(reversed); + } + OPENSSL_memcpy(reversed, in, todo); + in += todo; + in_len -= todo; + + size_t blocks = todo / sizeof(polyval_block); + for (size_t i = 0; i < blocks; i++) { + byte_reverse(&reversed[i]); + } + + ctx->ghash(ctx->S.u, ctx->Htable, (const uint8_t *) reversed, todo); + } +} + +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]) { + polyval_block S = ctx->S; + byte_reverse(&S); + OPENSSL_memcpy(out, &S.c, sizeof(polyval_block)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S new file mode 100644 index 00000000..2dd3dcd2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S @@ -0,0 +1,1769 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "CNIOBoringSSL_arm_arch.h" + +.text +.align 5 +Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +Lone: +.quad 1,0,0,0 +Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +// void ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_to_mont +.private_extern _ecp_nistz256_to_mont + +.align 6 +_ecp_nistz256_to_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,LRR // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + adr x2,LRR // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_from_mont +.private_extern _ecp_nistz256_from_mont + +.align 4 +_ecp_nistz256_from_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + mov x3,#1 // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + adr x2,Lone // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl _ecp_nistz256_mul_mont +.private_extern _ecp_nistz256_mul_mont + +.align 4 +_ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_sqr_mont +.private_extern _ecp_nistz256_sqr_mont + +.align 4 +_ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_div_by_2 +.private_extern _ecp_nistz256_div_by_2 + +.align 4 +_ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_mul_by_2 +.private_extern _ecp_nistz256_mul_by_2 + +.align 4 +_ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_mul_by_3 +.private_extern _ecp_nistz256_mul_by_3 + +.align 4 +_ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl _ecp_nistz256_sub +.private_extern _ecp_nistz256_sub + +.align 4 +_ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_neg +.private_extern _ecp_nistz256_neg + +.align 4 +_ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 + +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 + +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... + +.align 4 +__ecp_nistz256_add_to: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret + +.globl _ecp_nistz256_point_double +.private_extern _ecp_nistz256_point_double + +.align 5 +_ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + ldr x12,Lpoly+8 + mov x8,x14 + ldr x13,Lpoly+24 + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _ecp_nistz256_point_add +.private_extern _ecp_nistz256_point_add + +.align 5 +_ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b Ldouble_shortcut + +.align 4 +Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _ecp_nistz256_point_add_affine +.private_extern _ecp_nistz256_point_add_affine + +.align 5 +_ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,Lpoly+8 + ldr x13,Lpoly+24 + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adr x23,Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl _ecp_nistz256_ord_mul_mont +.private_extern _ecp_nistz256_ord_mul_mont + +.align 4 +_ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// int rep); +.globl _ecp_nistz256_ord_sqr_mont +.private_extern _ecp_nistz256_ord_sqr_mont + +.align 4 +_ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b Loop_ord_sqr + +.align 4 +Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl _ecp_nistz256_select_w5 +.private_extern _ecp_nistz256_select_w5 + +.align 4 +_ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // x10 := x0 + // w9 := 0; loop counter and incremented internal index + mov x10, x0 + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + movi v20.16b, #0 + movi v21.16b, #0 + +Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v27] := Load a (3*256-bit = 6*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // continue loading ... + ld1 {v26.2d, v27.2d}, [x1],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + bit v20.16b, v26.16b, v3.16b + bit v21.16b, v27.16b, v3.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz w9, #4, Lselect_w5_loop + + // Write [v16-v21] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x10],#64 + st1 {v20.2d, v21.2d}, [x10] + + ret + + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl _ecp_nistz256_select_w7 +.private_extern _ecp_nistz256_select_w7 + +.align 4 +_ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // w9 := 0; loop counter and incremented internal index + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + +Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v25] := Load a (2*256-bit = 4*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz w9, #6, Lselect_w7_loop + + // Write [v16-v19] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x0] + + ret + +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S new file mode 100644 index 00000000..d1b5e20f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S @@ -0,0 +1,1772 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "CNIOBoringSSL_arm_arch.h" + +.text +.align 5 +.Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +.Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lone: +.quad 1,0,0,0 +.Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +// void ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_to_mont +.hidden ecp_nistz256_to_mont +.type ecp_nistz256_to_mont,%function +.align 6 +ecp_nistz256_to_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,.LRR // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.LRR // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont + +// void ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_from_mont +.hidden ecp_nistz256_from_mont +.type ecp_nistz256_from_mont,%function +.align 4 +ecp_nistz256_from_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + mov x3,#1 // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.Lone // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont +.hidden ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,%function +.align 4 +ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont +.hidden ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,%function +.align 4 +ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 +.hidden ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,%function +.align 4 +ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 +.hidden ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,%function +.align 4 +ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 +.hidden ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,%function +.align 4 +ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub +.hidden ecp_nistz256_sub +.type ecp_nistz256_sub,%function +.align 4 +ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sub,.-ecp_nistz256_sub + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg +.hidden ecp_nistz256_neg +.type ecp_nistz256_neg,%function +.align 4 +ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_neg,.-ecp_nistz256_neg + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 +.type __ecp_nistz256_mul_mont,%function +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 +.type __ecp_nistz256_sqr_mont,%function +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.type __ecp_nistz256_add_to,%function +.align 4 +__ecp_nistz256_add_to: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_add_to,.-__ecp_nistz256_add_to + +.type __ecp_nistz256_sub_from,%function +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from + +.type __ecp_nistz256_sub_morf,%function +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf + +.type __ecp_nistz256_div_by_2,%function +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 +.globl ecp_nistz256_point_double +.hidden ecp_nistz256_point_double +.type ecp_nistz256_point_double,%function +.align 5 +ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +.Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + ldr x12,.Lpoly+8 + mov x8,x14 + ldr x13,.Lpoly+24 + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.hidden ecp_nistz256_point_add +.type ecp_nistz256_point_add,%function +.align 5 +ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +.Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b .Ldouble_shortcut + +.align 4 +.Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +.Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.hidden ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,%function +.align 5 +ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adr x23,.Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont +.hidden ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,%function +.align 4 +ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// int rep); +.globl ecp_nistz256_ord_sqr_mont +.hidden ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,%function +.align 4 +ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b .Loop_ord_sqr + +.align 4 +.Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,.Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w5 +.hidden ecp_nistz256_select_w5 +.type ecp_nistz256_select_w5,%function +.align 4 +ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // x10 := x0 + // w9 := 0; loop counter and incremented internal index + mov x10, x0 + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + movi v20.16b, #0 + movi v21.16b, #0 + +.Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v27] := Load a (3*256-bit = 6*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // continue loading ... + ld1 {v26.2d, v27.2d}, [x1],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + bit v20.16b, v26.16b, v3.16b + bit v21.16b, v27.16b, v3.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz w9, #4, .Lselect_w5_loop + + // Write [v16-v21] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x10],#64 + st1 {v20.2d, v21.2d}, [x10] + + ret +.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5 + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w7 +.hidden ecp_nistz256_select_w7 +.type ecp_nistz256_select_w7,%function +.align 4 +ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // w9 := 0; loop counter and incremented internal index + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + +.Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v25] := Load a (2*256-bit = 4*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz w9, #6, .Lselect_w7_loop + + // Write [v16-v19] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x0] + + ret +.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S new file mode 100644 index 00000000..d83a8d37 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S @@ -0,0 +1,4550 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + + +.align 64 +.Lpoly: +.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 + +.LOne: +.long 1,1,1,1,1,1,1,1 +.LTwo: +.long 2,2,2,2,2,2,2,2 +.LThree: +.long 3,3,3,3,3,3,3,3 +.LONE_mont: +.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe + + +.Lord: +.quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f + + + +.globl ecp_nistz256_neg +.hidden ecp_nistz256_neg +.type ecp_nistz256_neg,@function +.align 32 +ecp_nistz256_neg: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lneg_body: + + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r13,%r13 + + subq 0(%rsi),%r8 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r8,%rax + sbbq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + movq %r9,%rdx + sbbq $0,%r13 + + addq 0(%rsi),%r8 + movq %r10,%rcx + adcq 8(%rsi),%r9 + adcq 16(%rsi),%r10 + movq %r11,%r12 + adcq 24(%rsi),%r11 + testq %r13,%r13 + + cmovzq %rax,%r8 + cmovzq %rdx,%r9 + movq %r8,0(%rdi) + cmovzq %rcx,%r10 + movq %r9,8(%rdi) + cmovzq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lneg_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_neg,.-ecp_nistz256_neg + + + + + + +.globl ecp_nistz256_ord_mul_mont +.hidden ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,@function +.align 32 +ecp_nistz256_ord_mul_mont: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je .Lecp_nistz256_ord_mul_montx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_mul_body: + + movq 0(%rdx),%rax + movq %rdx,%rbx + leaq .Lord(%rip),%r14 + movq .LordK(%rip),%r15 + + + movq %rax,%rcx + mulq 0(%rsi) + movq %rax,%r8 + movq %rcx,%rax + movq %rdx,%r9 + + mulq 8(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq 16(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + + movq %r8,%r13 + imulq %r15,%r8 + + movq %rdx,%r11 + mulq 24(%rsi) + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq 0(%r14) + movq %r8,%rbp + addq %rax,%r13 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%r8 + + mulq 8(%r14) + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %rbp,%rax + adcq %rdx,%r10 + movq %rbp,%rdx + adcq $0,%r8 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 8(%rbx),%rax + sbbq %rdx,%rbp + + addq %r8,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + + movq %r9,%rcx + imulq %r15,%r9 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + xorq %r8,%r8 + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + mulq 0(%r14) + movq %r9,%rbp + addq %rax,%rcx + movq %r9,%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%r9 + + mulq 8(%r14) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq %rdx,%r11 + movq %rbp,%rdx + adcq $0,%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r12 + movq 16(%rbx),%rax + sbbq %rdx,%rbp + + addq %r9,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + + movq %r10,%rcx + imulq %r15,%r10 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + xorq %r9,%r9 + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + mulq 0(%r14) + movq %r10,%rbp + addq %rax,%rcx + movq %r10,%rax + adcq %rdx,%rcx + + subq %r10,%r12 + sbbq $0,%r10 + + mulq 8(%r14) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq %rdx,%r12 + movq %rbp,%rdx + adcq $0,%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r13 + movq 24(%rbx),%rax + sbbq %rdx,%rbp + + addq %r10,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rcx,%rax + adcq $0,%rdx + + movq %r11,%rcx + imulq %r15,%r11 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r8 + adcq $0,%rdx + xorq %r10,%r10 + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + mulq 0(%r14) + movq %r11,%rbp + addq %rax,%rcx + movq %r11,%rax + adcq %rdx,%rcx + + subq %r11,%r13 + sbbq $0,%r11 + + mulq 8(%r14) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq %rdx,%r13 + movq %rbp,%rdx + adcq $0,%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + sbbq %rdx,%rbp + + addq %r11,%r8 + adcq %rbp,%r9 + adcq $0,%r10 + + + movq %r12,%rsi + subq 0(%r14),%r12 + movq %r13,%r11 + sbbq 8(%r14),%r13 + movq %r8,%rcx + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rsi,%r12 + cmovcq %r11,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_mul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + + + + + + + +.globl ecp_nistz256_ord_sqr_mont +.hidden ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,@function +.align 32 +ecp_nistz256_ord_sqr_mont: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je .Lecp_nistz256_ord_sqr_montx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_sqr_body: + + movq 0(%rsi),%r8 + movq 8(%rsi),%rax + movq 16(%rsi),%r14 + movq 24(%rsi),%r15 + leaq .Lord(%rip),%rsi + movq %rdx,%rbx + jmp .Loop_ord_sqr + +.align 32 +.Loop_ord_sqr: + + movq %rax,%rbp + mulq %r8 + movq %rax,%r9 +.byte 102,72,15,110,205 + movq %r14,%rax + movq %rdx,%r10 + + mulq %r8 + addq %rax,%r10 + movq %r15,%rax +.byte 102,73,15,110,214 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r8 + addq %rax,%r11 + movq %r15,%rax +.byte 102,73,15,110,223 + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + movq %rax,%r13 + movq %r14,%rax + movq %rdx,%r14 + + + mulq %rbp + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r15 + + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + + addq %r15,%r12 + adcq %rdx,%r13 + adcq $0,%r14 + + + xorq %r15,%r15 + movq %r8,%rax + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + + mulq %rax + movq %rax,%r8 +.byte 102,72,15,126,200 + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r9 + adcq %rax,%r10 +.byte 102,72,15,126,208 + adcq $0,%rdx + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r11 + adcq %rax,%r12 +.byte 102,72,15,126,216 + adcq $0,%rdx + movq %rdx,%rbp + + movq %r8,%rcx + imulq 32(%rsi),%r8 + + mulq %rax + addq %rbp,%r13 + adcq %rax,%r14 + movq 0(%rsi),%rax + adcq %rdx,%r15 + + + mulq %r8 + movq %r8,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%rbp + + mulq %r8 + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %r8,%rax + adcq %rdx,%r10 + movq %r8,%rdx + adcq $0,%rbp + + movq %r9,%rcx + imulq 32(%rsi),%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 0(%rsi),%rax + sbbq %rdx,%r8 + + addq %rbp,%r11 + adcq $0,%r8 + + + mulq %r9 + movq %r9,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%rbp + + mulq %r9 + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + movq %r9,%rdx + adcq $0,%rbp + + movq %r10,%rcx + imulq 32(%rsi),%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + movq 0(%rsi),%rax + sbbq %rdx,%r9 + + addq %rbp,%r8 + adcq $0,%r9 + + + mulq %r10 + movq %r10,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r10,%r8 + sbbq $0,%rbp + + mulq %r10 + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %r10,%rax + adcq %rdx,%r8 + movq %r10,%rdx + adcq $0,%rbp + + movq %r11,%rcx + imulq 32(%rsi),%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r9 + movq 0(%rsi),%rax + sbbq %rdx,%r10 + + addq %rbp,%r9 + adcq $0,%r10 + + + mulq %r11 + movq %r11,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r11,%r9 + sbbq $0,%rbp + + mulq %r11 + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + movq %r11,%rdx + adcq $0,%rbp + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r10 + sbbq %rdx,%r11 + + addq %rbp,%r10 + adcq $0,%r11 + + + xorq %rdx,%rdx + addq %r12,%r8 + adcq %r13,%r9 + movq %r8,%r12 + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%rax + adcq $0,%rdx + + + subq 0(%rsi),%r8 + movq %r10,%r14 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r15 + sbbq 24(%rsi),%r11 + sbbq $0,%rdx + + cmovcq %r12,%r8 + cmovncq %r9,%rax + cmovncq %r10,%r14 + cmovncq %r11,%r15 + + decq %rbx + jnz .Loop_ord_sqr + + movq %r8,0(%rdi) + movq %rax,8(%rdi) + pxor %xmm1,%xmm1 + movq %r14,16(%rdi) + pxor %xmm2,%xmm2 + movq %r15,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_sqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont + +.type ecp_nistz256_ord_mul_montx,@function +.align 32 +ecp_nistz256_ord_mul_montx: +.cfi_startproc +.Lecp_nistz256_ord_mul_montx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_mulx_body: + + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + leaq .Lord-128(%rip),%r14 + movq .LordK(%rip),%r15 + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + mulxq %r11,%rbp,%r11 + addq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + mulxq %r15,%rdx,%rax + adcq %rbp,%r10 + adcq %rcx,%r11 + adcq $0,%r12 + + + xorq %r13,%r13 + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 24+128(%r14),%rcx,%rbp + movq 8(%rbx),%rdx + adcxq %rcx,%r11 + adoxq %rbp,%r12 + adcxq %r8,%r12 + adoxq %r8,%r13 + adcq $0,%r13 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%r14),%rcx,%rbp + movq 16(%rbx),%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcxq %r9,%r13 + adoxq %r9,%r8 + adcq $0,%r8 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%r14),%rcx,%rbp + movq 24(%rbx),%rdx + adcxq %rcx,%r13 + adoxq %rbp,%r8 + adcxq %r10,%r8 + adoxq %r10,%r9 + adcq $0,%r9 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%r14),%rcx,%rbp + leaq 128(%r14),%r14 + movq %r12,%rbx + adcxq %rcx,%r8 + adoxq %rbp,%r9 + movq %r13,%rdx + adcxq %r11,%r9 + adoxq %r11,%r10 + adcq $0,%r10 + + + + movq %r8,%rcx + subq 0(%r14),%r12 + sbbq 8(%r14),%r13 + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_mulx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_mul_montx,.-ecp_nistz256_ord_mul_montx + +.type ecp_nistz256_ord_sqr_montx,@function +.align 32 +ecp_nistz256_ord_sqr_montx: +.cfi_startproc +.Lecp_nistz256_ord_sqr_montx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_sqrx_body: + + movq %rdx,%rbx + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq .Lord(%rip),%rsi + jmp .Loop_ord_sqrx + +.align 32 +.Loop_ord_sqrx: + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + movq %rdx,%rax +.byte 102,73,15,110,206 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + addq %rcx,%r10 +.byte 102,73,15,110,215 + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + mulxq %r8,%rcx,%r14 + movq %rax,%rdx +.byte 102,73,15,110,216 + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + + mulxq %rdx,%r8,%rbp +.byte 102,72,15,126,202 + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax +.byte 102,72,15,126,210 + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 + mulxq %rdx,%rcx,%rbp +.byte 0x67 +.byte 102,72,15,126,218 + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + adoxq %rbp,%r13 + mulxq %rdx,%rcx,%rax + adoxq %rcx,%r14 + adoxq %rax,%r15 + + + movq %r8,%rdx + mulxq 32(%rsi),%rdx,%rcx + + xorq %rax,%rax + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + adcxq %rax,%r8 + + + movq %r9,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + adoxq %rax,%r9 + + + movq %r10,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + adcxq %rax,%r10 + + + movq %r11,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + adoxq %rax,%r11 + + + addq %r8,%r12 + adcq %r13,%r9 + movq %r12,%rdx + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%r14 + adcq $0,%rax + + + subq 0(%rsi),%r12 + movq %r10,%r15 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r8 + sbbq 24(%rsi),%r11 + sbbq $0,%rax + + cmovncq %r12,%rdx + cmovncq %r9,%r14 + cmovncq %r10,%r15 + cmovncq %r11,%r8 + + decq %rbx + jnz .Loop_ord_sqrx + + movq %rdx,0(%rdi) + movq %r14,8(%rdi) + pxor %xmm1,%xmm1 + movq %r15,16(%rdi) + pxor %xmm2,%xmm2 + movq %r8,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_sqrx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_sqr_montx,.-ecp_nistz256_ord_sqr_montx + + + + + + +.globl ecp_nistz256_mul_mont +.hidden ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,@function +.align 32 +ecp_nistz256_mul_mont: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx +.Lmul_mont: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lmul_body: + cmpl $0x80100,%ecx + je .Lmul_montx + movq %rdx,%rbx + movq 0(%rdx),%rax + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + + call __ecp_nistz256_mul_montq + jmp .Lmul_mont_done + +.align 32 +.Lmul_montx: + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_mul_montx +.Lmul_mont_done: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +.type __ecp_nistz256_mul_montq,@function +.align 32 +__ecp_nistz256_mul_montq: +.cfi_startproc + + + movq %rax,%rbp + mulq %r9 + movq .Lpoly+8(%rip),%r14 + movq %rax,%r8 + movq %rbp,%rax + movq %rdx,%r9 + + mulq %r10 + movq .Lpoly+24(%rip),%r15 + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %r11 + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r12 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + xorq %r13,%r13 + movq %rdx,%r12 + + + + + + + + + + + movq %r8,%rbp + shlq $32,%r8 + mulq %r15 + shrq $32,%rbp + addq %r8,%r9 + adcq %rbp,%r10 + adcq %rax,%r11 + movq 8(%rbx),%rax + adcq %rdx,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + + movq %r9,%rbp + shlq $32,%r9 + mulq %r15 + shrq $32,%rbp + addq %r9,%r10 + adcq %rbp,%r11 + adcq %rax,%r12 + movq 16(%rbx),%rax + adcq %rdx,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + + movq %r10,%rbp + shlq $32,%r10 + mulq %r15 + shrq $32,%rbp + addq %r10,%r11 + adcq %rbp,%r12 + adcq %rax,%r13 + movq 24(%rbx),%rax + adcq %rdx,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + + movq %r11,%rbp + shlq $32,%r11 + mulq %r15 + shrq $32,%rbp + addq %r11,%r12 + adcq %rbp,%r13 + movq %r12,%rcx + adcq %rax,%r8 + adcq %rdx,%r9 + movq %r13,%rbp + adcq $0,%r10 + + + + subq $-1,%r12 + movq %r8,%rbx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rdx + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rcx,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rbx,%r8 + movq %r13,8(%rdi) + cmovcq %rdx,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq + + + + + + + + +.globl ecp_nistz256_sqr_mont +.hidden ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,@function +.align 32 +ecp_nistz256_sqr_mont: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lsqr_body: + cmpl $0x80100,%ecx + je .Lsqr_montx + movq 0(%rsi),%rax + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + + call __ecp_nistz256_sqr_montq + jmp .Lsqr_mont_done + +.align 32 +.Lsqr_montx: + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_sqr_montx +.Lsqr_mont_done: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lsqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +.type __ecp_nistz256_sqr_montq,@function +.align 32 +__ecp_nistz256_sqr_montq: +.cfi_startproc + movq %rax,%r13 + mulq %r14 + movq %rax,%r9 + movq %r15,%rax + movq %rdx,%r10 + + mulq %r13 + addq %rax,%r10 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r13 + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq %r14 + addq %rax,%r12 + movq %r8,%rax + adcq $0,%rdx + addq %rbp,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + + mulq %r15 + xorq %r15,%r15 + addq %rax,%r13 + movq 0(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + mulq %rax + movq %rax,%r8 + movq 8(%rsi),%rax + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r9 + adcq %rax,%r10 + movq 16(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r11 + adcq %rax,%r12 + movq 24(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r13 + adcq %rax,%r14 + movq %r8,%rax + adcq %rdx,%r15 + + movq .Lpoly+8(%rip),%rsi + movq .Lpoly+24(%rip),%rbp + + + + + movq %r8,%rcx + shlq $32,%r8 + mulq %rbp + shrq $32,%rcx + addq %r8,%r9 + adcq %rcx,%r10 + adcq %rax,%r11 + movq %r9,%rax + adcq $0,%rdx + + + + movq %r9,%rcx + shlq $32,%r9 + movq %rdx,%r8 + mulq %rbp + shrq $32,%rcx + addq %r9,%r10 + adcq %rcx,%r11 + adcq %rax,%r8 + movq %r10,%rax + adcq $0,%rdx + + + + movq %r10,%rcx + shlq $32,%r10 + movq %rdx,%r9 + mulq %rbp + shrq $32,%rcx + addq %r10,%r11 + adcq %rcx,%r8 + adcq %rax,%r9 + movq %r11,%rax + adcq $0,%rdx + + + + movq %r11,%rcx + shlq $32,%r11 + movq %rdx,%r10 + mulq %rbp + shrq $32,%rcx + addq %r11,%r8 + adcq %rcx,%r9 + adcq %rax,%r10 + adcq $0,%rdx + xorq %r11,%r11 + + + + addq %r8,%r12 + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %rdx,%r15 + movq %r13,%r9 + adcq $0,%r11 + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%rcx + sbbq %rbp,%r15 + sbbq $0,%r11 + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %rcx,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq +.type __ecp_nistz256_mul_montx,@function +.align 32 +__ecp_nistz256_mul_montx: +.cfi_startproc + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + movq $32,%r14 + xorq %r13,%r13 + mulxq %r11,%rbp,%r11 + movq .Lpoly+24(%rip),%r15 + adcq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + adcq %rbp,%r10 + shlxq %r14,%r8,%rbp + adcq %rcx,%r11 + shrxq %r14,%r8,%rcx + adcq $0,%r12 + + + + addq %rbp,%r9 + adcq %rcx,%r10 + + mulxq %r15,%rcx,%rbp + movq 8(%rbx),%rdx + adcq %rcx,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + adcxq %rcx,%r12 + shlxq %r14,%r9,%rcx + adoxq %rbp,%r13 + shrxq %r14,%r9,%rbp + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + + addq %rcx,%r10 + adcq %rbp,%r11 + + mulxq %r15,%rcx,%rbp + movq 16(%rbx),%rdx + adcq %rcx,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + adcxq %rcx,%r13 + shlxq %r14,%r10,%rcx + adoxq %rbp,%r8 + shrxq %r14,%r10,%rbp + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + + addq %rcx,%r11 + adcq %rbp,%r12 + + mulxq %r15,%rcx,%rbp + movq 24(%rbx),%rdx + adcq %rcx,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + adcxq %rcx,%r8 + shlxq %r14,%r11,%rcx + adoxq %rbp,%r9 + shrxq %r14,%r11,%rbp + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + + addq %rcx,%r12 + adcq %rbp,%r13 + + mulxq %r15,%rcx,%rbp + movq %r12,%rbx + movq .Lpoly+8(%rip),%r14 + adcq %rcx,%r8 + movq %r13,%rdx + adcq %rbp,%r9 + adcq $0,%r10 + + + + xorl %eax,%eax + movq %r8,%rcx + sbbq $-1,%r12 + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rbp + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %rbp,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx + +.type __ecp_nistz256_sqr_montx,@function +.align 32 +__ecp_nistz256_sqr_montx: +.cfi_startproc + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + xorl %eax,%eax + adcq %rcx,%r10 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + + mulxq %r8,%rcx,%r14 + movq 0+128(%rsi),%rdx + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + mulxq %rdx,%r8,%rbp + movq 8+128(%rsi),%rdx + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax + movq 16+128(%rsi),%rdx + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 +.byte 0x67 + mulxq %rdx,%rcx,%rbp + movq 24+128(%rsi),%rdx + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + movq $32,%rsi + adoxq %rbp,%r13 +.byte 0x67,0x67 + mulxq %rdx,%rcx,%rax + movq .Lpoly+24(%rip),%rdx + adoxq %rcx,%r14 + shlxq %rsi,%r8,%rcx + adoxq %rax,%r15 + shrxq %rsi,%r8,%rax + movq %rdx,%rbp + + + addq %rcx,%r9 + adcq %rax,%r10 + + mulxq %r8,%rcx,%r8 + adcq %rcx,%r11 + shlxq %rsi,%r9,%rcx + adcq $0,%r8 + shrxq %rsi,%r9,%rax + + + addq %rcx,%r10 + adcq %rax,%r11 + + mulxq %r9,%rcx,%r9 + adcq %rcx,%r8 + shlxq %rsi,%r10,%rcx + adcq $0,%r9 + shrxq %rsi,%r10,%rax + + + addq %rcx,%r11 + adcq %rax,%r8 + + mulxq %r10,%rcx,%r10 + adcq %rcx,%r9 + shlxq %rsi,%r11,%rcx + adcq $0,%r10 + shrxq %rsi,%r11,%rax + + + addq %rcx,%r8 + adcq %rax,%r9 + + mulxq %r11,%rcx,%r11 + adcq %rcx,%r10 + adcq $0,%r11 + + xorq %rdx,%rdx + addq %r8,%r12 + movq .Lpoly+8(%rip),%rsi + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %r11,%r15 + movq %r13,%r9 + adcq $0,%rdx + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%r11 + sbbq %rbp,%r15 + sbbq $0,%rdx + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %r11,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx + + +.globl ecp_nistz256_select_w5 +.hidden ecp_nistz256_select_w5 +.type ecp_nistz256_select_w5,@function +.align 32 +ecp_nistz256_select_w5: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rax + movq 8(%rax),%rax + testl $32,%eax + jnz .Lavx2_select_w5 + movdqa .LOne(%rip),%xmm0 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + + movdqa %xmm0,%xmm8 + pshufd $0,%xmm1,%xmm1 + + movq $16,%rax +.Lselect_loop_sse_w5: + + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + pcmpeqd %xmm1,%xmm15 + + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + movdqa 64(%rsi),%xmm13 + movdqa 80(%rsi),%xmm14 + leaq 96(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + pand %xmm15,%xmm13 + por %xmm12,%xmm5 + pand %xmm15,%xmm14 + por %xmm13,%xmm6 + por %xmm14,%xmm7 + + decq %rax + jnz .Lselect_loop_sse_w5 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + movdqu %xmm6,64(%rdi) + movdqu %xmm7,80(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_select_w5: +.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5 + + + +.globl ecp_nistz256_select_w7 +.hidden ecp_nistz256_select_w7 +.type ecp_nistz256_select_w7,@function +.align 32 +ecp_nistz256_select_w7: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rax + movq 8(%rax),%rax + testl $32,%eax + jnz .Lavx2_select_w7 + movdqa .LOne(%rip),%xmm8 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + + movdqa %xmm8,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq $64,%rax + +.Lselect_loop_sse_w7: + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + pcmpeqd %xmm1,%xmm15 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + leaq 64(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + prefetcht0 255(%rsi) + por %xmm12,%xmm5 + + decq %rax + jnz .Lselect_loop_sse_w7 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_select_w7: +.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 + + +.type ecp_nistz256_avx2_select_w5,@function +.align 32 +ecp_nistz256_avx2_select_w5: +.cfi_startproc +.Lavx2_select_w5: + vzeroupper + vmovdqa .LTwo(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + vpxor %ymm4,%ymm4,%ymm4 + + vmovdqa .LOne(%rip),%ymm5 + vmovdqa .LTwo(%rip),%ymm10 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + movq $8,%rax +.Lselect_loop_avx2_w5: + + vmovdqa 0(%rsi),%ymm6 + vmovdqa 32(%rsi),%ymm7 + vmovdqa 64(%rsi),%ymm8 + + vmovdqa 96(%rsi),%ymm11 + vmovdqa 128(%rsi),%ymm12 + vmovdqa 160(%rsi),%ymm13 + + vpcmpeqd %ymm1,%ymm5,%ymm9 + vpcmpeqd %ymm1,%ymm10,%ymm14 + + vpaddd %ymm0,%ymm5,%ymm5 + vpaddd %ymm0,%ymm10,%ymm10 + leaq 192(%rsi),%rsi + + vpand %ymm9,%ymm6,%ymm6 + vpand %ymm9,%ymm7,%ymm7 + vpand %ymm9,%ymm8,%ymm8 + vpand %ymm14,%ymm11,%ymm11 + vpand %ymm14,%ymm12,%ymm12 + vpand %ymm14,%ymm13,%ymm13 + + vpxor %ymm6,%ymm2,%ymm2 + vpxor %ymm7,%ymm3,%ymm3 + vpxor %ymm8,%ymm4,%ymm4 + vpxor %ymm11,%ymm2,%ymm2 + vpxor %ymm12,%ymm3,%ymm3 + vpxor %ymm13,%ymm4,%ymm4 + + decq %rax + jnz .Lselect_loop_avx2_w5 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vmovdqu %ymm4,64(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_avx2_select_w5: +.size ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5 + + + +.globl ecp_nistz256_avx2_select_w7 +.hidden ecp_nistz256_avx2_select_w7 +.type ecp_nistz256_avx2_select_w7,@function +.align 32 +ecp_nistz256_avx2_select_w7: +.cfi_startproc +.Lavx2_select_w7: + vzeroupper + vmovdqa .LThree(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + + vmovdqa .LOne(%rip),%ymm4 + vmovdqa .LTwo(%rip),%ymm8 + vmovdqa .LThree(%rip),%ymm12 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + + movq $21,%rax +.Lselect_loop_avx2_w7: + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vmovdqa 64(%rsi),%ymm9 + vmovdqa 96(%rsi),%ymm10 + + vmovdqa 128(%rsi),%ymm13 + vmovdqa 160(%rsi),%ymm14 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + vpcmpeqd %ymm1,%ymm8,%ymm11 + vpcmpeqd %ymm1,%ymm12,%ymm15 + + vpaddd %ymm0,%ymm4,%ymm4 + vpaddd %ymm0,%ymm8,%ymm8 + vpaddd %ymm0,%ymm12,%ymm12 + leaq 192(%rsi),%rsi + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + vpand %ymm11,%ymm9,%ymm9 + vpand %ymm11,%ymm10,%ymm10 + vpand %ymm15,%ymm13,%ymm13 + vpand %ymm15,%ymm14,%ymm14 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + vpxor %ymm9,%ymm2,%ymm2 + vpxor %ymm10,%ymm3,%ymm3 + vpxor %ymm13,%ymm2,%ymm2 + vpxor %ymm14,%ymm3,%ymm3 + + decq %rax + jnz .Lselect_loop_avx2_w7 + + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_avx2_select_w7: +.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7 +.type __ecp_nistz256_add_toq,@function +.align 32 +__ecp_nistz256_add_toq: +.cfi_startproc + xorq %r11,%r11 + addq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq + +.type __ecp_nistz256_sub_fromq,@function +.align 32 +__ecp_nistz256_sub_fromq: +.cfi_startproc + subq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq %r11,%r11 + + addq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + testq %r11,%r11 + + cmovzq %rax,%r12 + cmovzq %rbp,%r13 + movq %r12,0(%rdi) + cmovzq %rcx,%r8 + movq %r13,8(%rdi) + cmovzq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq + +.type __ecp_nistz256_subq,@function +.align 32 +__ecp_nistz256_subq: +.cfi_startproc + subq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq %r11,%r11 + + addq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + testq %r11,%r11 + + cmovnzq %rax,%r12 + cmovnzq %rbp,%r13 + cmovnzq %rcx,%r8 + cmovnzq %r10,%r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_subq,.-__ecp_nistz256_subq + +.type __ecp_nistz256_mul_by_2q,@function +.align 32 +__ecp_nistz256_mul_by_2q: +.cfi_startproc + xorq %r11,%r11 + addq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q +.globl ecp_nistz256_point_double +.hidden ecp_nistz256_point_double +.type ecp_nistz256_point_double,@function +.align 32 +ecp_nistz256_point_double: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je .Lpoint_doublex + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $160+8,%rsp +.cfi_adjust_cfa_offset 32*5+8 +.Lpoint_doubleq_body: + +.Lpoint_double_shortcutq: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq .Lpoly+8(%rip),%r14 + movq .Lpoly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-0(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 32(%rbx),%rax + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-0(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montq + call __ecp_nistz256_mul_by_2q + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montq + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rax + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 0+32(%rsp),%rax + movq 8+32(%rsp),%r14 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montq + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subq + + movq 32(%rsp),%rax + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-0(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromq + + leaq 160+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_doubleq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.hidden ecp_nistz256_point_add +.type ecp_nistz256_point_add,@function +.align 32 +ecp_nistz256_point_add: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je .Lpoint_addx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $576+8,%rsp +.cfi_adjust_cfa_offset 32*18+8 +.Lpoint_addq_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-0(%rsi),%rsi + movq %rax,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rax + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-0(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 416(%rsp),%rax + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 512(%rsp),%rax + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq 0+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 480(%rsp),%rax + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + orq %r8,%r12 +.byte 0x3e + jnz .Ladd_proceedq + + + + testq %r9,%r9 + jz .Ladd_doubleq + + + + + + +.byte 102,72,15,126,199 + pxor %xmm0,%xmm0 + movdqu %xmm0,0(%rdi) + movdqu %xmm0,16(%rdi) + movdqu %xmm0,32(%rdi) + movdqu %xmm0,48(%rdi) + movdqu %xmm0,64(%rdi) + movdqu %xmm0,80(%rdi) + jmp .Ladd_doneq + +.align 32 +.Ladd_doubleq: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp +.cfi_adjust_cfa_offset -416 + jmp .Lpoint_double_shortcutq +.cfi_adjust_cfa_offset 416 + +.align 32 +.Ladd_proceedq: + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq 0+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0(%rsp),%rax + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 160(%rsp),%rax + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +.Ladd_doneq: + leaq 576+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_addq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.hidden ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,@function +.align 32 +ecp_nistz256_point_add_affine: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je .Lpoint_add_affinex + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $480+8,%rsp +.cfi_adjust_cfa_offset 32*15+8 +.Ladd_affineq_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-0(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rax + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-0(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+96(%rsp),%rax + movq 8+96(%rsp),%r14 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq 0+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rax + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq 0+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand .LONE_mont(%rip),%xmm2 + pand .LONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Ladd_affineq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +.type __ecp_nistz256_add_tox,@function +.align 32 +__ecp_nistz256_add_tox: +.cfi_startproc + xorq %r11,%r11 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox + +.type __ecp_nistz256_sub_fromx,@function +.align 32 +__ecp_nistz256_sub_fromx: +.cfi_startproc + xorq %r11,%r11 + sbbq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq $0,%r11 + + xorq %r10,%r10 + adcq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + + btq $0,%r11 + cmovncq %rax,%r12 + cmovncq %rbp,%r13 + movq %r12,0(%rdi) + cmovncq %rcx,%r8 + movq %r13,8(%rdi) + cmovncq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx + +.type __ecp_nistz256_subx,@function +.align 32 +__ecp_nistz256_subx: +.cfi_startproc + xorq %r11,%r11 + sbbq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq $0,%r11 + + xorq %r9,%r9 + adcq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + + btq $0,%r11 + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + cmovcq %rcx,%r8 + cmovcq %r10,%r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_subx,.-__ecp_nistz256_subx + +.type __ecp_nistz256_mul_by_2x,@function +.align 32 +__ecp_nistz256_mul_by_2x: +.cfi_startproc + xorq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x +.type ecp_nistz256_point_doublex,@function +.align 32 +ecp_nistz256_point_doublex: +.cfi_startproc +.Lpoint_doublex: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $160+8,%rsp +.cfi_adjust_cfa_offset 32*5+8 +.Lpoint_doublex_body: + +.Lpoint_double_shortcutx: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq .Lpoly+8(%rip),%r14 + movq .Lpoly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-128(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 32(%rbx),%rdx + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-128(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montx + call __ecp_nistz256_mul_by_2x + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montx + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rdx + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 0+32(%rsp),%rdx + movq 8+32(%rsp),%r14 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montx + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subx + + movq 32(%rsp),%rdx + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-128(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromx + + leaq 160+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_doublex_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_doublex,.-ecp_nistz256_point_doublex +.type ecp_nistz256_point_addx,@function +.align 32 +ecp_nistz256_point_addx: +.cfi_startproc +.Lpoint_addx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $576+8,%rsp +.cfi_adjust_cfa_offset 32*18+8 +.Lpoint_addx_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-128(%rsi),%rsi + movq %rdx,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rdx + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-128(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 416(%rsp),%rdx + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 512(%rsp),%rdx + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq -128+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 480(%rsp),%rdx + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + orq %r8,%r12 +.byte 0x3e + jnz .Ladd_proceedx + + + + testq %r9,%r9 + jz .Ladd_doublex + + + + + + +.byte 102,72,15,126,199 + pxor %xmm0,%xmm0 + movdqu %xmm0,0(%rdi) + movdqu %xmm0,16(%rdi) + movdqu %xmm0,32(%rdi) + movdqu %xmm0,48(%rdi) + movdqu %xmm0,64(%rdi) + movdqu %xmm0,80(%rdi) + jmp .Ladd_donex + +.align 32 +.Ladd_doublex: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp +.cfi_adjust_cfa_offset -416 + jmp .Lpoint_double_shortcutx +.cfi_adjust_cfa_offset 416 + +.align 32 +.Ladd_proceedx: + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq -128+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0(%rsp),%rdx + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 160(%rsp),%rdx + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +.Ladd_donex: + leaq 576+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_addx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_addx,.-ecp_nistz256_point_addx +.type ecp_nistz256_point_add_affinex,@function +.align 32 +ecp_nistz256_point_add_affinex: +.cfi_startproc +.Lpoint_add_affinex: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $480+8,%rsp +.cfi_adjust_cfa_offset 32*15+8 +.Ladd_affinex_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-128(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rdx + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-128(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+96(%rsp),%rdx + movq 8+96(%rsp),%r14 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq -128+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rdx + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq -128+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand .LONE_mont(%rip),%xmm2 + pand .LONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Ladd_affinex_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add_affinex,.-ecp_nistz256_point_add_affinex +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S new file mode 100644 index 00000000..42c6a432 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S @@ -0,0 +1,4474 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + +.p2align 6 +L$poly: +.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 + +L$One: +.long 1,1,1,1,1,1,1,1 +L$Two: +.long 2,2,2,2,2,2,2,2 +L$Three: +.long 3,3,3,3,3,3,3,3 +L$ONE_mont: +.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe + + +L$ord: +.quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 +L$ordK: +.quad 0xccd1c8aaee00bc4f + + + +.globl _ecp_nistz256_neg +.private_extern _ecp_nistz256_neg + +.p2align 5 +_ecp_nistz256_neg: + + pushq %r12 + + pushq %r13 + +L$neg_body: + + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r13,%r13 + + subq 0(%rsi),%r8 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r8,%rax + sbbq 24(%rsi),%r11 + leaq L$poly(%rip),%rsi + movq %r9,%rdx + sbbq $0,%r13 + + addq 0(%rsi),%r8 + movq %r10,%rcx + adcq 8(%rsi),%r9 + adcq 16(%rsi),%r10 + movq %r11,%r12 + adcq 24(%rsi),%r11 + testq %r13,%r13 + + cmovzq %rax,%r8 + cmovzq %rdx,%r9 + movq %r8,0(%rdi) + cmovzq %rcx,%r10 + movq %r9,8(%rdi) + cmovzq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 + + movq 8(%rsp),%r12 + + leaq 16(%rsp),%rsp + +L$neg_epilogue: + .byte 0xf3,0xc3 + + + + + + + + +.globl _ecp_nistz256_ord_mul_mont +.private_extern _ecp_nistz256_ord_mul_mont + +.p2align 5 +_ecp_nistz256_ord_mul_mont: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je L$ecp_nistz256_ord_mul_montx + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$ord_mul_body: + + movq 0(%rdx),%rax + movq %rdx,%rbx + leaq L$ord(%rip),%r14 + movq L$ordK(%rip),%r15 + + + movq %rax,%rcx + mulq 0(%rsi) + movq %rax,%r8 + movq %rcx,%rax + movq %rdx,%r9 + + mulq 8(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq 16(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + + movq %r8,%r13 + imulq %r15,%r8 + + movq %rdx,%r11 + mulq 24(%rsi) + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq 0(%r14) + movq %r8,%rbp + addq %rax,%r13 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%r8 + + mulq 8(%r14) + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %rbp,%rax + adcq %rdx,%r10 + movq %rbp,%rdx + adcq $0,%r8 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 8(%rbx),%rax + sbbq %rdx,%rbp + + addq %r8,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + + movq %r9,%rcx + imulq %r15,%r9 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + xorq %r8,%r8 + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + mulq 0(%r14) + movq %r9,%rbp + addq %rax,%rcx + movq %r9,%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%r9 + + mulq 8(%r14) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq %rdx,%r11 + movq %rbp,%rdx + adcq $0,%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r12 + movq 16(%rbx),%rax + sbbq %rdx,%rbp + + addq %r9,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + + movq %r10,%rcx + imulq %r15,%r10 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + xorq %r9,%r9 + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + mulq 0(%r14) + movq %r10,%rbp + addq %rax,%rcx + movq %r10,%rax + adcq %rdx,%rcx + + subq %r10,%r12 + sbbq $0,%r10 + + mulq 8(%r14) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq %rdx,%r12 + movq %rbp,%rdx + adcq $0,%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r13 + movq 24(%rbx),%rax + sbbq %rdx,%rbp + + addq %r10,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rcx,%rax + adcq $0,%rdx + + movq %r11,%rcx + imulq %r15,%r11 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r8 + adcq $0,%rdx + xorq %r10,%r10 + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + mulq 0(%r14) + movq %r11,%rbp + addq %rax,%rcx + movq %r11,%rax + adcq %rdx,%rcx + + subq %r11,%r13 + sbbq $0,%r11 + + mulq 8(%r14) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq %rdx,%r13 + movq %rbp,%rdx + adcq $0,%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + sbbq %rdx,%rbp + + addq %r11,%r8 + adcq %rbp,%r9 + adcq $0,%r10 + + + movq %r12,%rsi + subq 0(%r14),%r12 + movq %r13,%r11 + sbbq 8(%r14),%r13 + movq %r8,%rcx + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rsi,%r12 + cmovcq %r11,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$ord_mul_epilogue: + .byte 0xf3,0xc3 + + + + + + + + + +.globl _ecp_nistz256_ord_sqr_mont +.private_extern _ecp_nistz256_ord_sqr_mont + +.p2align 5 +_ecp_nistz256_ord_sqr_mont: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je L$ecp_nistz256_ord_sqr_montx + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$ord_sqr_body: + + movq 0(%rsi),%r8 + movq 8(%rsi),%rax + movq 16(%rsi),%r14 + movq 24(%rsi),%r15 + leaq L$ord(%rip),%rsi + movq %rdx,%rbx + jmp L$oop_ord_sqr + +.p2align 5 +L$oop_ord_sqr: + + movq %rax,%rbp + mulq %r8 + movq %rax,%r9 +.byte 102,72,15,110,205 + movq %r14,%rax + movq %rdx,%r10 + + mulq %r8 + addq %rax,%r10 + movq %r15,%rax +.byte 102,73,15,110,214 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r8 + addq %rax,%r11 + movq %r15,%rax +.byte 102,73,15,110,223 + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + movq %rax,%r13 + movq %r14,%rax + movq %rdx,%r14 + + + mulq %rbp + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r15 + + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + + addq %r15,%r12 + adcq %rdx,%r13 + adcq $0,%r14 + + + xorq %r15,%r15 + movq %r8,%rax + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + + mulq %rax + movq %rax,%r8 +.byte 102,72,15,126,200 + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r9 + adcq %rax,%r10 +.byte 102,72,15,126,208 + adcq $0,%rdx + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r11 + adcq %rax,%r12 +.byte 102,72,15,126,216 + adcq $0,%rdx + movq %rdx,%rbp + + movq %r8,%rcx + imulq 32(%rsi),%r8 + + mulq %rax + addq %rbp,%r13 + adcq %rax,%r14 + movq 0(%rsi),%rax + adcq %rdx,%r15 + + + mulq %r8 + movq %r8,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%rbp + + mulq %r8 + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %r8,%rax + adcq %rdx,%r10 + movq %r8,%rdx + adcq $0,%rbp + + movq %r9,%rcx + imulq 32(%rsi),%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 0(%rsi),%rax + sbbq %rdx,%r8 + + addq %rbp,%r11 + adcq $0,%r8 + + + mulq %r9 + movq %r9,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%rbp + + mulq %r9 + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + movq %r9,%rdx + adcq $0,%rbp + + movq %r10,%rcx + imulq 32(%rsi),%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + movq 0(%rsi),%rax + sbbq %rdx,%r9 + + addq %rbp,%r8 + adcq $0,%r9 + + + mulq %r10 + movq %r10,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r10,%r8 + sbbq $0,%rbp + + mulq %r10 + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %r10,%rax + adcq %rdx,%r8 + movq %r10,%rdx + adcq $0,%rbp + + movq %r11,%rcx + imulq 32(%rsi),%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r9 + movq 0(%rsi),%rax + sbbq %rdx,%r10 + + addq %rbp,%r9 + adcq $0,%r10 + + + mulq %r11 + movq %r11,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r11,%r9 + sbbq $0,%rbp + + mulq %r11 + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + movq %r11,%rdx + adcq $0,%rbp + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r10 + sbbq %rdx,%r11 + + addq %rbp,%r10 + adcq $0,%r11 + + + xorq %rdx,%rdx + addq %r12,%r8 + adcq %r13,%r9 + movq %r8,%r12 + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%rax + adcq $0,%rdx + + + subq 0(%rsi),%r8 + movq %r10,%r14 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r15 + sbbq 24(%rsi),%r11 + sbbq $0,%rdx + + cmovcq %r12,%r8 + cmovncq %r9,%rax + cmovncq %r10,%r14 + cmovncq %r11,%r15 + + decq %rbx + jnz L$oop_ord_sqr + + movq %r8,0(%rdi) + movq %rax,8(%rdi) + pxor %xmm1,%xmm1 + movq %r14,16(%rdi) + pxor %xmm2,%xmm2 + movq %r15,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$ord_sqr_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +ecp_nistz256_ord_mul_montx: + +L$ecp_nistz256_ord_mul_montx: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$ord_mulx_body: + + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + leaq L$ord-128(%rip),%r14 + movq L$ordK(%rip),%r15 + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + mulxq %r11,%rbp,%r11 + addq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + mulxq %r15,%rdx,%rax + adcq %rbp,%r10 + adcq %rcx,%r11 + adcq $0,%r12 + + + xorq %r13,%r13 + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 24+128(%r14),%rcx,%rbp + movq 8(%rbx),%rdx + adcxq %rcx,%r11 + adoxq %rbp,%r12 + adcxq %r8,%r12 + adoxq %r8,%r13 + adcq $0,%r13 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%r14),%rcx,%rbp + movq 16(%rbx),%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcxq %r9,%r13 + adoxq %r9,%r8 + adcq $0,%r8 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%r14),%rcx,%rbp + movq 24(%rbx),%rdx + adcxq %rcx,%r13 + adoxq %rbp,%r8 + adcxq %r10,%r8 + adoxq %r10,%r9 + adcq $0,%r9 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%r14),%rcx,%rbp + leaq 128(%r14),%r14 + movq %r12,%rbx + adcxq %rcx,%r8 + adoxq %rbp,%r9 + movq %r13,%rdx + adcxq %r11,%r9 + adoxq %r11,%r10 + adcq $0,%r10 + + + + movq %r8,%rcx + subq 0(%r14),%r12 + sbbq 8(%r14),%r13 + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$ord_mulx_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +ecp_nistz256_ord_sqr_montx: + +L$ecp_nistz256_ord_sqr_montx: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$ord_sqrx_body: + + movq %rdx,%rbx + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq L$ord(%rip),%rsi + jmp L$oop_ord_sqrx + +.p2align 5 +L$oop_ord_sqrx: + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + movq %rdx,%rax +.byte 102,73,15,110,206 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + addq %rcx,%r10 +.byte 102,73,15,110,215 + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + mulxq %r8,%rcx,%r14 + movq %rax,%rdx +.byte 102,73,15,110,216 + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + + mulxq %rdx,%r8,%rbp +.byte 102,72,15,126,202 + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax +.byte 102,72,15,126,210 + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 + mulxq %rdx,%rcx,%rbp +.byte 0x67 +.byte 102,72,15,126,218 + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + adoxq %rbp,%r13 + mulxq %rdx,%rcx,%rax + adoxq %rcx,%r14 + adoxq %rax,%r15 + + + movq %r8,%rdx + mulxq 32(%rsi),%rdx,%rcx + + xorq %rax,%rax + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + adcxq %rax,%r8 + + + movq %r9,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + adoxq %rax,%r9 + + + movq %r10,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + adcxq %rax,%r10 + + + movq %r11,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + adoxq %rax,%r11 + + + addq %r8,%r12 + adcq %r13,%r9 + movq %r12,%rdx + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%r14 + adcq $0,%rax + + + subq 0(%rsi),%r12 + movq %r10,%r15 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r8 + sbbq 24(%rsi),%r11 + sbbq $0,%rax + + cmovncq %r12,%rdx + cmovncq %r9,%r14 + cmovncq %r10,%r15 + cmovncq %r11,%r8 + + decq %rbx + jnz L$oop_ord_sqrx + + movq %rdx,0(%rdi) + movq %r14,8(%rdi) + pxor %xmm1,%xmm1 + movq %r15,16(%rdi) + pxor %xmm2,%xmm2 + movq %r8,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$ord_sqrx_epilogue: + .byte 0xf3,0xc3 + + + + + + + + +.globl _ecp_nistz256_mul_mont +.private_extern _ecp_nistz256_mul_mont + +.p2align 5 +_ecp_nistz256_mul_mont: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx +L$mul_mont: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$mul_body: + cmpl $0x80100,%ecx + je L$mul_montx + movq %rdx,%rbx + movq 0(%rdx),%rax + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + + call __ecp_nistz256_mul_montq + jmp L$mul_mont_done + +.p2align 5 +L$mul_montx: + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_mul_montx +L$mul_mont_done: + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$mul_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_mul_montq: + + + + movq %rax,%rbp + mulq %r9 + movq L$poly+8(%rip),%r14 + movq %rax,%r8 + movq %rbp,%rax + movq %rdx,%r9 + + mulq %r10 + movq L$poly+24(%rip),%r15 + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %r11 + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r12 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + xorq %r13,%r13 + movq %rdx,%r12 + + + + + + + + + + + movq %r8,%rbp + shlq $32,%r8 + mulq %r15 + shrq $32,%rbp + addq %r8,%r9 + adcq %rbp,%r10 + adcq %rax,%r11 + movq 8(%rbx),%rax + adcq %rdx,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + + movq %r9,%rbp + shlq $32,%r9 + mulq %r15 + shrq $32,%rbp + addq %r9,%r10 + adcq %rbp,%r11 + adcq %rax,%r12 + movq 16(%rbx),%rax + adcq %rdx,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + + movq %r10,%rbp + shlq $32,%r10 + mulq %r15 + shrq $32,%rbp + addq %r10,%r11 + adcq %rbp,%r12 + adcq %rax,%r13 + movq 24(%rbx),%rax + adcq %rdx,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + + movq %r11,%rbp + shlq $32,%r11 + mulq %r15 + shrq $32,%rbp + addq %r11,%r12 + adcq %rbp,%r13 + movq %r12,%rcx + adcq %rax,%r8 + adcq %rdx,%r9 + movq %r13,%rbp + adcq $0,%r10 + + + + subq $-1,%r12 + movq %r8,%rbx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rdx + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rcx,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rbx,%r8 + movq %r13,8(%rdi) + cmovcq %rdx,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + + + + + + + +.globl _ecp_nistz256_sqr_mont +.private_extern _ecp_nistz256_sqr_mont + +.p2align 5 +_ecp_nistz256_sqr_mont: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$sqr_body: + cmpl $0x80100,%ecx + je L$sqr_montx + movq 0(%rsi),%rax + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + + call __ecp_nistz256_sqr_montq + jmp L$sqr_mont_done + +.p2align 5 +L$sqr_montx: + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_sqr_montx +L$sqr_mont_done: + movq 0(%rsp),%r15 + + movq 8(%rsp),%r14 + + movq 16(%rsp),%r13 + + movq 24(%rsp),%r12 + + movq 32(%rsp),%rbx + + movq 40(%rsp),%rbp + + leaq 48(%rsp),%rsp + +L$sqr_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_sqr_montq: + + movq %rax,%r13 + mulq %r14 + movq %rax,%r9 + movq %r15,%rax + movq %rdx,%r10 + + mulq %r13 + addq %rax,%r10 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r13 + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq %r14 + addq %rax,%r12 + movq %r8,%rax + adcq $0,%rdx + addq %rbp,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + + mulq %r15 + xorq %r15,%r15 + addq %rax,%r13 + movq 0(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + mulq %rax + movq %rax,%r8 + movq 8(%rsi),%rax + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r9 + adcq %rax,%r10 + movq 16(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r11 + adcq %rax,%r12 + movq 24(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r13 + adcq %rax,%r14 + movq %r8,%rax + adcq %rdx,%r15 + + movq L$poly+8(%rip),%rsi + movq L$poly+24(%rip),%rbp + + + + + movq %r8,%rcx + shlq $32,%r8 + mulq %rbp + shrq $32,%rcx + addq %r8,%r9 + adcq %rcx,%r10 + adcq %rax,%r11 + movq %r9,%rax + adcq $0,%rdx + + + + movq %r9,%rcx + shlq $32,%r9 + movq %rdx,%r8 + mulq %rbp + shrq $32,%rcx + addq %r9,%r10 + adcq %rcx,%r11 + adcq %rax,%r8 + movq %r10,%rax + adcq $0,%rdx + + + + movq %r10,%rcx + shlq $32,%r10 + movq %rdx,%r9 + mulq %rbp + shrq $32,%rcx + addq %r10,%r11 + adcq %rcx,%r8 + adcq %rax,%r9 + movq %r11,%rax + adcq $0,%rdx + + + + movq %r11,%rcx + shlq $32,%r11 + movq %rdx,%r10 + mulq %rbp + shrq $32,%rcx + addq %r11,%r8 + adcq %rcx,%r9 + adcq %rax,%r10 + adcq $0,%rdx + xorq %r11,%r11 + + + + addq %r8,%r12 + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %rdx,%r15 + movq %r13,%r9 + adcq $0,%r11 + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%rcx + sbbq %rbp,%r15 + sbbq $0,%r11 + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %rcx,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 + + + +.p2align 5 +__ecp_nistz256_mul_montx: + + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + movq $32,%r14 + xorq %r13,%r13 + mulxq %r11,%rbp,%r11 + movq L$poly+24(%rip),%r15 + adcq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + adcq %rbp,%r10 + shlxq %r14,%r8,%rbp + adcq %rcx,%r11 + shrxq %r14,%r8,%rcx + adcq $0,%r12 + + + + addq %rbp,%r9 + adcq %rcx,%r10 + + mulxq %r15,%rcx,%rbp + movq 8(%rbx),%rdx + adcq %rcx,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + adcxq %rcx,%r12 + shlxq %r14,%r9,%rcx + adoxq %rbp,%r13 + shrxq %r14,%r9,%rbp + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + + addq %rcx,%r10 + adcq %rbp,%r11 + + mulxq %r15,%rcx,%rbp + movq 16(%rbx),%rdx + adcq %rcx,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + adcxq %rcx,%r13 + shlxq %r14,%r10,%rcx + adoxq %rbp,%r8 + shrxq %r14,%r10,%rbp + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + + addq %rcx,%r11 + adcq %rbp,%r12 + + mulxq %r15,%rcx,%rbp + movq 24(%rbx),%rdx + adcq %rcx,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + adcxq %rcx,%r8 + shlxq %r14,%r11,%rcx + adoxq %rbp,%r9 + shrxq %r14,%r11,%rbp + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + + addq %rcx,%r12 + adcq %rbp,%r13 + + mulxq %r15,%rcx,%rbp + movq %r12,%rbx + movq L$poly+8(%rip),%r14 + adcq %rcx,%r8 + movq %r13,%rdx + adcq %rbp,%r9 + adcq $0,%r10 + + + + xorl %eax,%eax + movq %r8,%rcx + sbbq $-1,%r12 + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rbp + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %rbp,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_sqr_montx: + + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + xorl %eax,%eax + adcq %rcx,%r10 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + + mulxq %r8,%rcx,%r14 + movq 0+128(%rsi),%rdx + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + mulxq %rdx,%r8,%rbp + movq 8+128(%rsi),%rdx + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax + movq 16+128(%rsi),%rdx + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 +.byte 0x67 + mulxq %rdx,%rcx,%rbp + movq 24+128(%rsi),%rdx + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + movq $32,%rsi + adoxq %rbp,%r13 +.byte 0x67,0x67 + mulxq %rdx,%rcx,%rax + movq L$poly+24(%rip),%rdx + adoxq %rcx,%r14 + shlxq %rsi,%r8,%rcx + adoxq %rax,%r15 + shrxq %rsi,%r8,%rax + movq %rdx,%rbp + + + addq %rcx,%r9 + adcq %rax,%r10 + + mulxq %r8,%rcx,%r8 + adcq %rcx,%r11 + shlxq %rsi,%r9,%rcx + adcq $0,%r8 + shrxq %rsi,%r9,%rax + + + addq %rcx,%r10 + adcq %rax,%r11 + + mulxq %r9,%rcx,%r9 + adcq %rcx,%r8 + shlxq %rsi,%r10,%rcx + adcq $0,%r9 + shrxq %rsi,%r10,%rax + + + addq %rcx,%r11 + adcq %rax,%r8 + + mulxq %r10,%rcx,%r10 + adcq %rcx,%r9 + shlxq %rsi,%r11,%rcx + adcq $0,%r10 + shrxq %rsi,%r11,%rax + + + addq %rcx,%r8 + adcq %rax,%r9 + + mulxq %r11,%rcx,%r11 + adcq %rcx,%r10 + adcq $0,%r11 + + xorq %rdx,%rdx + addq %r8,%r12 + movq L$poly+8(%rip),%rsi + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %r11,%r15 + movq %r13,%r9 + adcq $0,%rdx + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%r11 + sbbq %rbp,%r15 + sbbq $0,%rdx + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %r11,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.globl _ecp_nistz256_select_w5 +.private_extern _ecp_nistz256_select_w5 + +.p2align 5 +_ecp_nistz256_select_w5: + + leaq _OPENSSL_ia32cap_P(%rip),%rax + movq 8(%rax),%rax + testl $32,%eax + jnz L$avx2_select_w5 + movdqa L$One(%rip),%xmm0 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + + movdqa %xmm0,%xmm8 + pshufd $0,%xmm1,%xmm1 + + movq $16,%rax +L$select_loop_sse_w5: + + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + pcmpeqd %xmm1,%xmm15 + + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + movdqa 64(%rsi),%xmm13 + movdqa 80(%rsi),%xmm14 + leaq 96(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + pand %xmm15,%xmm13 + por %xmm12,%xmm5 + pand %xmm15,%xmm14 + por %xmm13,%xmm6 + por %xmm14,%xmm7 + + decq %rax + jnz L$select_loop_sse_w5 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + movdqu %xmm6,64(%rdi) + movdqu %xmm7,80(%rdi) + .byte 0xf3,0xc3 + +L$SEH_end_ecp_nistz256_select_w5: + + + + +.globl _ecp_nistz256_select_w7 +.private_extern _ecp_nistz256_select_w7 + +.p2align 5 +_ecp_nistz256_select_w7: + + leaq _OPENSSL_ia32cap_P(%rip),%rax + movq 8(%rax),%rax + testl $32,%eax + jnz L$avx2_select_w7 + movdqa L$One(%rip),%xmm8 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + + movdqa %xmm8,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq $64,%rax + +L$select_loop_sse_w7: + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + pcmpeqd %xmm1,%xmm15 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + leaq 64(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + prefetcht0 255(%rsi) + por %xmm12,%xmm5 + + decq %rax + jnz L$select_loop_sse_w7 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + .byte 0xf3,0xc3 + +L$SEH_end_ecp_nistz256_select_w7: + + + + +.p2align 5 +ecp_nistz256_avx2_select_w5: + +L$avx2_select_w5: + vzeroupper + vmovdqa L$Two(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + vpxor %ymm4,%ymm4,%ymm4 + + vmovdqa L$One(%rip),%ymm5 + vmovdqa L$Two(%rip),%ymm10 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + movq $8,%rax +L$select_loop_avx2_w5: + + vmovdqa 0(%rsi),%ymm6 + vmovdqa 32(%rsi),%ymm7 + vmovdqa 64(%rsi),%ymm8 + + vmovdqa 96(%rsi),%ymm11 + vmovdqa 128(%rsi),%ymm12 + vmovdqa 160(%rsi),%ymm13 + + vpcmpeqd %ymm1,%ymm5,%ymm9 + vpcmpeqd %ymm1,%ymm10,%ymm14 + + vpaddd %ymm0,%ymm5,%ymm5 + vpaddd %ymm0,%ymm10,%ymm10 + leaq 192(%rsi),%rsi + + vpand %ymm9,%ymm6,%ymm6 + vpand %ymm9,%ymm7,%ymm7 + vpand %ymm9,%ymm8,%ymm8 + vpand %ymm14,%ymm11,%ymm11 + vpand %ymm14,%ymm12,%ymm12 + vpand %ymm14,%ymm13,%ymm13 + + vpxor %ymm6,%ymm2,%ymm2 + vpxor %ymm7,%ymm3,%ymm3 + vpxor %ymm8,%ymm4,%ymm4 + vpxor %ymm11,%ymm2,%ymm2 + vpxor %ymm12,%ymm3,%ymm3 + vpxor %ymm13,%ymm4,%ymm4 + + decq %rax + jnz L$select_loop_avx2_w5 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vmovdqu %ymm4,64(%rdi) + vzeroupper + .byte 0xf3,0xc3 + +L$SEH_end_ecp_nistz256_avx2_select_w5: + + + + +.globl _ecp_nistz256_avx2_select_w7 +.private_extern _ecp_nistz256_avx2_select_w7 + +.p2align 5 +_ecp_nistz256_avx2_select_w7: + +L$avx2_select_w7: + vzeroupper + vmovdqa L$Three(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + + vmovdqa L$One(%rip),%ymm4 + vmovdqa L$Two(%rip),%ymm8 + vmovdqa L$Three(%rip),%ymm12 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + + movq $21,%rax +L$select_loop_avx2_w7: + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vmovdqa 64(%rsi),%ymm9 + vmovdqa 96(%rsi),%ymm10 + + vmovdqa 128(%rsi),%ymm13 + vmovdqa 160(%rsi),%ymm14 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + vpcmpeqd %ymm1,%ymm8,%ymm11 + vpcmpeqd %ymm1,%ymm12,%ymm15 + + vpaddd %ymm0,%ymm4,%ymm4 + vpaddd %ymm0,%ymm8,%ymm8 + vpaddd %ymm0,%ymm12,%ymm12 + leaq 192(%rsi),%rsi + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + vpand %ymm11,%ymm9,%ymm9 + vpand %ymm11,%ymm10,%ymm10 + vpand %ymm15,%ymm13,%ymm13 + vpand %ymm15,%ymm14,%ymm14 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + vpxor %ymm9,%ymm2,%ymm2 + vpxor %ymm10,%ymm3,%ymm3 + vpxor %ymm13,%ymm2,%ymm2 + vpxor %ymm14,%ymm3,%ymm3 + + decq %rax + jnz L$select_loop_avx2_w7 + + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vzeroupper + .byte 0xf3,0xc3 + +L$SEH_end_ecp_nistz256_avx2_select_w7: + + +.p2align 5 +__ecp_nistz256_add_toq: + + xorq %r11,%r11 + addq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_sub_fromq: + + subq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq %r11,%r11 + + addq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + testq %r11,%r11 + + cmovzq %rax,%r12 + cmovzq %rbp,%r13 + movq %r12,0(%rdi) + cmovzq %rcx,%r8 + movq %r13,8(%rdi) + cmovzq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_subq: + + subq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq %r11,%r11 + + addq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + testq %r11,%r11 + + cmovnzq %rax,%r12 + cmovnzq %rbp,%r13 + cmovnzq %rcx,%r8 + cmovnzq %r10,%r9 + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_mul_by_2q: + + xorq %r11,%r11 + addq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + +.globl _ecp_nistz256_point_double +.private_extern _ecp_nistz256_point_double + +.p2align 5 +_ecp_nistz256_point_double: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je L$point_doublex + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $160+8,%rsp + +L$point_doubleq_body: + +L$point_double_shortcutq: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq L$poly+8(%rip),%r14 + movq L$poly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-0(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 32(%rbx),%rax + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-0(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montq + call __ecp_nistz256_mul_by_2q + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montq + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rax + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 0+32(%rsp),%rax + movq 8+32(%rsp),%r14 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montq + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subq + + movq 32(%rsp),%rax + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-0(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromq + + leaq 160+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$point_doubleq_epilogue: + .byte 0xf3,0xc3 + + +.globl _ecp_nistz256_point_add +.private_extern _ecp_nistz256_point_add + +.p2align 5 +_ecp_nistz256_point_add: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je L$point_addx + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $576+8,%rsp + +L$point_addq_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-0(%rsi),%rsi + movq %rax,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rax + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-0(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 416(%rsp),%rax + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 512(%rsp),%rax + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq 0+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 480(%rsp),%rax + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + orq %r8,%r12 +.byte 0x3e + jnz L$add_proceedq + + + + testq %r9,%r9 + jz L$add_doubleq + + + + + + +.byte 102,72,15,126,199 + pxor %xmm0,%xmm0 + movdqu %xmm0,0(%rdi) + movdqu %xmm0,16(%rdi) + movdqu %xmm0,32(%rdi) + movdqu %xmm0,48(%rdi) + movdqu %xmm0,64(%rdi) + movdqu %xmm0,80(%rdi) + jmp L$add_doneq + +.p2align 5 +L$add_doubleq: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp + + jmp L$point_double_shortcutq + + +.p2align 5 +L$add_proceedq: + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq 0+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0(%rsp),%rax + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 160(%rsp),%rax + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +L$add_doneq: + leaq 576+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$point_addq_epilogue: + .byte 0xf3,0xc3 + + +.globl _ecp_nistz256_point_add_affine +.private_extern _ecp_nistz256_point_add_affine + +.p2align 5 +_ecp_nistz256_point_add_affine: + + leaq _OPENSSL_ia32cap_P(%rip),%rcx + movq 8(%rcx),%rcx + andl $0x80100,%ecx + cmpl $0x80100,%ecx + je L$point_add_affinex + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $480+8,%rsp + +L$add_affineq_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-0(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rax + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-0(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+96(%rsp),%rax + movq 8+96(%rsp),%r14 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq 0+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rax + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq 0+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand L$ONE_mont(%rip),%xmm2 + pand L$ONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$add_affineq_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +__ecp_nistz256_add_tox: + + xorq %r11,%r11 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_sub_fromx: + + xorq %r11,%r11 + sbbq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq $0,%r11 + + xorq %r10,%r10 + adcq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + + btq $0,%r11 + cmovncq %rax,%r12 + cmovncq %rbp,%r13 + movq %r12,0(%rdi) + cmovncq %rcx,%r8 + movq %r13,8(%rdi) + cmovncq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_subx: + + xorq %r11,%r11 + sbbq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq $0,%r11 + + xorq %r9,%r9 + adcq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + + btq $0,%r11 + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + cmovcq %rcx,%r8 + cmovcq %r10,%r9 + + .byte 0xf3,0xc3 + + + + +.p2align 5 +__ecp_nistz256_mul_by_2x: + + xorq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 + + + +.p2align 5 +ecp_nistz256_point_doublex: + +L$point_doublex: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $160+8,%rsp + +L$point_doublex_body: + +L$point_double_shortcutx: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq L$poly+8(%rip),%r14 + movq L$poly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-128(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 32(%rbx),%rdx + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-128(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montx + call __ecp_nistz256_mul_by_2x + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montx + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rdx + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 0+32(%rsp),%rdx + movq 8+32(%rsp),%r14 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montx + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subx + + movq 32(%rsp),%rdx + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-128(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromx + + leaq 160+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$point_doublex_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +ecp_nistz256_point_addx: + +L$point_addx: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $576+8,%rsp + +L$point_addx_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-128(%rsi),%rsi + movq %rdx,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rdx + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-128(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 416(%rsp),%rdx + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 512(%rsp),%rdx + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq -128+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 480(%rsp),%rdx + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + orq %r8,%r12 +.byte 0x3e + jnz L$add_proceedx + + + + testq %r9,%r9 + jz L$add_doublex + + + + + + +.byte 102,72,15,126,199 + pxor %xmm0,%xmm0 + movdqu %xmm0,0(%rdi) + movdqu %xmm0,16(%rdi) + movdqu %xmm0,32(%rdi) + movdqu %xmm0,48(%rdi) + movdqu %xmm0,64(%rdi) + movdqu %xmm0,80(%rdi) + jmp L$add_donex + +.p2align 5 +L$add_doublex: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp + + jmp L$point_double_shortcutx + + +.p2align 5 +L$add_proceedx: + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq -128+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0(%rsp),%rdx + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 160(%rsp),%rdx + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +L$add_donex: + leaq 576+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$point_addx_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +ecp_nistz256_point_add_affinex: + +L$point_add_affinex: + pushq %rbp + + pushq %rbx + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + subq $480+8,%rsp + +L$add_affinex_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-128(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rdx + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-128(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+96(%rsp),%rdx + movq 8+96(%rsp),%r14 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq -128+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rdx + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq -128+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand L$ONE_mont(%rip),%xmm2 + pand L$ONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbx + + movq -8(%rsi),%rbp + + leaq (%rsi),%rsp + +L$add_affinex_epilogue: + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S new file mode 100644 index 00000000..f1215166 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S @@ -0,0 +1,324 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "CNIOBoringSSL_arm_arch.h" + +.text +.globl _beeu_mod_inverse_vartime +.private_extern _beeu_mod_inverse_vartime + +.align 4 +_beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp x25,x26,[x1] + ldp x27,x28,[x1,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp x0,x1,[x2] + ldp x2,x30,[x2,#16] + + // A = a3..a0 := n + mov x21, x0 + mov x22, x1 + mov x23, x2 + mov x24, x30 + + // X = x4..x0 := 1 + mov x3, #1 + eor x4, x4, x4 + eor x5, x5, x5 + eor x6, x6, x6 + eor x7, x7, x7 + + // Y = y4..y0 := 0 + eor x8, x8, x8 + eor x9, x9, x9 + eor x10, x10, x10 + eor x11, x11, x11 + eor x12, x12, x12 + +Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + orr x14, x25, x26 + orr x14, x14, x27 + + // reverse the bit order of x25. This is needed for clz after this macro + rbit x15, x25 + + orr x14, x14, x28 + cbz x14,Lbeeu_loop_end + + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in x25 + // ( = number of leading 0s in x15; see the "rbit" instruction in TEST_B_ZERO) + clz x13, x15 + + // If there is no shift, goto shift_A_Y + cbz x13, Lbeeu_shift_A_Y + + // Shift B right by "x13" bits + neg x14, x13 + lsr x25, x25, x13 + lsl x15, x26, x14 + + lsr x26, x26, x13 + lsl x19, x27, x14 + + orr x25, x25, x15 + + lsr x27, x27, x13 + lsl x20, x28, x14 + + orr x26, x26, x19 + + lsr x28, x28, x13 + + orr x27, x27, x20 + + + // Shift X right by "x13" bits, adding n whenever X becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_X: + tbz x3, #0, Lshift1_0 + adds x3, x3, x0 + adcs x4, x4, x1 + adcs x5, x5, x2 + adcs x6, x6, x30 + adc x7, x7, x14 +Lshift1_0: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x3, x4, x3, #1 + extr x4, x5, x4, #1 + extr x5, x6, x5, #1 + extr x6, x7, x6, #1 + lsr x7, x7, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "x13" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and x13 is decreased while executing the X loop. + // - SHIFT256(B, x13) is performed before right-shifting X; they are independent + +Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of x21 + // x13 := number of trailing 0s in x21 (= number of leading 0s in x15) + rbit x15, x21 + clz x13, x15 + + // If there is no shift, goto |B-A|, X+Y update + cbz x13, Lbeeu_update_B_X_or_A_Y + + // Shift A right by "x13" bits + neg x14, x13 + lsr x21, x21, x13 + lsl x15, x22, x14 + + lsr x22, x22, x13 + lsl x19, x23, x14 + + orr x21, x21, x15 + + lsr x23, x23, x13 + lsl x20, x24, x14 + + orr x22, x22, x19 + + lsr x24, x24, x13 + + orr x23, x23, x20 + + + // Shift Y right by "x13" bits, adding n whenever Y becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_Y: + tbz x8, #0, Lshift1_1 + adds x8, x8, x0 + adcs x9, x9, x1 + adcs x10, x10, x2 + adcs x11, x11, x30 + adc x12, x12, x14 +Lshift1_1: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x8, x9, x8, #1 + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_Y + +Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs x14, x25, x21 + sbcs x15, x26, x22 + sbcs x19, x27, x23 + sbcs x20, x28, x24 + bcs Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs x21, x21, x25 + sbcs x22, x22, x26 + sbcs x23, x23, x27 + sbcs x24, x24, x28 + + adds x8, x8, x3 + adcs x9, x9, x4 + adcs x10, x10, x5 + adcs x11, x11, x6 + adc x12, x12, x7 + b Lbeeu_loop + +Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov x25, x14 + mov x26, x15 + mov x27, x19 + mov x28, x20 + + adds x3, x3, x8 + adcs x4, x4, x9 + adcs x5, x5, x10 + adcs x6, x6, x11 + adc x7, x7, x12 + b Lbeeu_loop + +Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub x14, x21, #1 + orr x14, x14, x22 + orr x14, x14, x23 + orr x14, x14, x24 + cbnz x14, Lbeeu_err + + // If Y>n ==> Y:=Y-n +Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // (x14 = 0 from above) + subs x3, x8, x0 + sbcs x4, x9, x1 + sbcs x5, x10, x2 + sbcs x6, x11, x30 + sbcs x7, x12, x14 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel x8, x3, x8, cs + csel x9, x4, x9, cs + csel x10, x5, x10, cs + csel x11, x6, x11, cs + csel x12, x7, x12, cs + bcs Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs x8, x0, x8 + sbcs x9, x1, x9 + sbcs x10, x2, x10 + sbcs x11, x30, x11 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp x8, x9, [x3] + stp x10, x11, [x3,#16] + // return 1 (success) + mov x0, #1 + b Lbeeu_finish + +Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S new file mode 100644 index 00000000..d7eb3c32 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S @@ -0,0 +1,327 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "CNIOBoringSSL_arm_arch.h" + +.text +.globl beeu_mod_inverse_vartime +.hidden beeu_mod_inverse_vartime +.type beeu_mod_inverse_vartime, %function +.align 4 +beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp x25,x26,[x1] + ldp x27,x28,[x1,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp x0,x1,[x2] + ldp x2,x30,[x2,#16] + + // A = a3..a0 := n + mov x21, x0 + mov x22, x1 + mov x23, x2 + mov x24, x30 + + // X = x4..x0 := 1 + mov x3, #1 + eor x4, x4, x4 + eor x5, x5, x5 + eor x6, x6, x6 + eor x7, x7, x7 + + // Y = y4..y0 := 0 + eor x8, x8, x8 + eor x9, x9, x9 + eor x10, x10, x10 + eor x11, x11, x11 + eor x12, x12, x12 + +.Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + orr x14, x25, x26 + orr x14, x14, x27 + + // reverse the bit order of x25. This is needed for clz after this macro + rbit x15, x25 + + orr x14, x14, x28 + cbz x14,.Lbeeu_loop_end + + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in x25 + // ( = number of leading 0s in x15; see the "rbit" instruction in TEST_B_ZERO) + clz x13, x15 + + // If there is no shift, goto shift_A_Y + cbz x13, .Lbeeu_shift_A_Y + + // Shift B right by "x13" bits + neg x14, x13 + lsr x25, x25, x13 + lsl x15, x26, x14 + + lsr x26, x26, x13 + lsl x19, x27, x14 + + orr x25, x25, x15 + + lsr x27, x27, x13 + lsl x20, x28, x14 + + orr x26, x26, x19 + + lsr x28, x28, x13 + + orr x27, x27, x20 + + + // Shift X right by "x13" bits, adding n whenever X becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +.Lbeeu_shift_loop_X: + tbz x3, #0, .Lshift1_0 + adds x3, x3, x0 + adcs x4, x4, x1 + adcs x5, x5, x2 + adcs x6, x6, x30 + adc x7, x7, x14 +.Lshift1_0: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x3, x4, x3, #1 + extr x4, x5, x4, #1 + extr x5, x6, x5, #1 + extr x6, x7, x6, #1 + lsr x7, x7, #1 + + subs x13, x13, #1 + bne .Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "x13" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and x13 is decreased while executing the X loop. + // - SHIFT256(B, x13) is performed before right-shifting X; they are independent + +.Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of x21 + // x13 := number of trailing 0s in x21 (= number of leading 0s in x15) + rbit x15, x21 + clz x13, x15 + + // If there is no shift, goto |B-A|, X+Y update + cbz x13, .Lbeeu_update_B_X_or_A_Y + + // Shift A right by "x13" bits + neg x14, x13 + lsr x21, x21, x13 + lsl x15, x22, x14 + + lsr x22, x22, x13 + lsl x19, x23, x14 + + orr x21, x21, x15 + + lsr x23, x23, x13 + lsl x20, x24, x14 + + orr x22, x22, x19 + + lsr x24, x24, x13 + + orr x23, x23, x20 + + + // Shift Y right by "x13" bits, adding n whenever Y becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +.Lbeeu_shift_loop_Y: + tbz x8, #0, .Lshift1_1 + adds x8, x8, x0 + adcs x9, x9, x1 + adcs x10, x10, x2 + adcs x11, x11, x30 + adc x12, x12, x14 +.Lshift1_1: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x8, x9, x8, #1 + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + subs x13, x13, #1 + bne .Lbeeu_shift_loop_Y + +.Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs x14, x25, x21 + sbcs x15, x26, x22 + sbcs x19, x27, x23 + sbcs x20, x28, x24 + bcs .Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs x21, x21, x25 + sbcs x22, x22, x26 + sbcs x23, x23, x27 + sbcs x24, x24, x28 + + adds x8, x8, x3 + adcs x9, x9, x4 + adcs x10, x10, x5 + adcs x11, x11, x6 + adc x12, x12, x7 + b .Lbeeu_loop + +.Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov x25, x14 + mov x26, x15 + mov x27, x19 + mov x28, x20 + + adds x3, x3, x8 + adcs x4, x4, x9 + adcs x5, x5, x10 + adcs x6, x6, x11 + adc x7, x7, x12 + b .Lbeeu_loop + +.Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub x14, x21, #1 + orr x14, x14, x22 + orr x14, x14, x23 + orr x14, x14, x24 + cbnz x14, .Lbeeu_err + + // If Y>n ==> Y:=Y-n +.Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // (x14 = 0 from above) + subs x3, x8, x0 + sbcs x4, x9, x1 + sbcs x5, x10, x2 + sbcs x6, x11, x30 + sbcs x7, x12, x14 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel x8, x3, x8, cs + csel x9, x4, x9, cs + csel x10, x5, x10, cs + csel x11, x6, x11, cs + csel x12, x7, x12, cs + bcs .Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs x8, x0, x8 + sbcs x9, x1, x9 + sbcs x10, x2, x10 + sbcs x11, x30, x11 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp x8, x9, [x3] + stp x10, x11, [x3,#16] + // return 1 (success) + mov x0, #1 + b .Lbeeu_finish + +.Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +.Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size beeu_mod_inverse_vartime,.-beeu_mod_inverse_vartime +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S new file mode 100644 index 00000000..64579d01 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S @@ -0,0 +1,350 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.type beeu_mod_inverse_vartime,@function +.hidden beeu_mod_inverse_vartime +.globl beeu_mod_inverse_vartime +.hidden beeu_mod_inverse_vartime +.align 32 +beeu_mod_inverse_vartime: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset rbp,-16 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset r12,-24 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset r13,-32 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset r14,-40 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset r15,-48 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset rbx,-56 + pushq %rsi +.cfi_adjust_cfa_offset 8 +.cfi_offset rsi,-64 + + subq $80,%rsp +.cfi_adjust_cfa_offset 80 + movq %rdi,0(%rsp) + + + movq $1,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %rdi,%rdi + + xorq %r12,%r12 + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + xorq %rbp,%rbp + + + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu %xmm0,48(%rsp) + vmovdqu %xmm1,64(%rsp) + + vmovdqu 0(%rdx),%xmm0 + vmovdqu 16(%rdx),%xmm1 + vmovdqu %xmm0,16(%rsp) + vmovdqu %xmm1,32(%rsp) + +.Lbeeu_loop: + xorq %rbx,%rbx + orq 48(%rsp),%rbx + orq 56(%rsp),%rbx + orq 64(%rsp),%rbx + orq 72(%rsp),%rbx + jz .Lbeeu_loop_end + + + + + + + + + + + movq $1,%rcx + + +.Lbeeu_shift_loop_XB: + movq %rcx,%rbx + andq 48(%rsp),%rbx + jnz .Lbeeu_shift_loop_end_XB + + + movq $1,%rbx + andq %r8,%rbx + jz .Lshift1_0 + addq 0(%rdx),%r8 + adcq 8(%rdx),%r9 + adcq 16(%rdx),%r10 + adcq 24(%rdx),%r11 + adcq $0,%rdi + +.Lshift1_0: + shrdq $1,%r9,%r8 + shrdq $1,%r10,%r9 + shrdq $1,%r11,%r10 + shrdq $1,%rdi,%r11 + shrq $1,%rdi + + shlq $1,%rcx + + + + + + cmpq $0x8000000,%rcx + jne .Lbeeu_shift_loop_XB + +.Lbeeu_shift_loop_end_XB: + bsfq %rcx,%rcx + testq %rcx,%rcx + jz .Lbeeu_no_shift_XB + + + + movq 8+48(%rsp),%rax + movq 16+48(%rsp),%rbx + movq 24+48(%rsp),%rsi + + shrdq %cl,%rax,0+48(%rsp) + shrdq %cl,%rbx,8+48(%rsp) + shrdq %cl,%rsi,16+48(%rsp) + + shrq %cl,%rsi + movq %rsi,24+48(%rsp) + + +.Lbeeu_no_shift_XB: + + movq $1,%rcx + + +.Lbeeu_shift_loop_YA: + movq %rcx,%rbx + andq 16(%rsp),%rbx + jnz .Lbeeu_shift_loop_end_YA + + + movq $1,%rbx + andq %r12,%rbx + jz .Lshift1_1 + addq 0(%rdx),%r12 + adcq 8(%rdx),%r13 + adcq 16(%rdx),%r14 + adcq 24(%rdx),%r15 + adcq $0,%rbp + +.Lshift1_1: + shrdq $1,%r13,%r12 + shrdq $1,%r14,%r13 + shrdq $1,%r15,%r14 + shrdq $1,%rbp,%r15 + shrq $1,%rbp + + shlq $1,%rcx + + + + + + cmpq $0x8000000,%rcx + jne .Lbeeu_shift_loop_YA + +.Lbeeu_shift_loop_end_YA: + bsfq %rcx,%rcx + testq %rcx,%rcx + jz .Lbeeu_no_shift_YA + + + + movq 8+16(%rsp),%rax + movq 16+16(%rsp),%rbx + movq 24+16(%rsp),%rsi + + shrdq %cl,%rax,0+16(%rsp) + shrdq %cl,%rbx,8+16(%rsp) + shrdq %cl,%rsi,16+16(%rsp) + + shrq %cl,%rsi + movq %rsi,24+16(%rsp) + + +.Lbeeu_no_shift_YA: + + movq 48(%rsp),%rax + movq 56(%rsp),%rbx + movq 64(%rsp),%rsi + movq 72(%rsp),%rcx + subq 16(%rsp),%rax + sbbq 24(%rsp),%rbx + sbbq 32(%rsp),%rsi + sbbq 40(%rsp),%rcx + jnc .Lbeeu_B_bigger_than_A + + + movq 16(%rsp),%rax + movq 24(%rsp),%rbx + movq 32(%rsp),%rsi + movq 40(%rsp),%rcx + subq 48(%rsp),%rax + sbbq 56(%rsp),%rbx + sbbq 64(%rsp),%rsi + sbbq 72(%rsp),%rcx + movq %rax,16(%rsp) + movq %rbx,24(%rsp) + movq %rsi,32(%rsp) + movq %rcx,40(%rsp) + + + addq %r8,%r12 + adcq %r9,%r13 + adcq %r10,%r14 + adcq %r11,%r15 + adcq %rdi,%rbp + jmp .Lbeeu_loop + +.Lbeeu_B_bigger_than_A: + + movq %rax,48(%rsp) + movq %rbx,56(%rsp) + movq %rsi,64(%rsp) + movq %rcx,72(%rsp) + + + addq %r12,%r8 + adcq %r13,%r9 + adcq %r14,%r10 + adcq %r15,%r11 + adcq %rbp,%rdi + + jmp .Lbeeu_loop + +.Lbeeu_loop_end: + + + + + movq 16(%rsp),%rbx + subq $1,%rbx + orq 24(%rsp),%rbx + orq 32(%rsp),%rbx + orq 40(%rsp),%rbx + + jnz .Lbeeu_err + + + + + movq 0(%rdx),%r8 + movq 8(%rdx),%r9 + movq 16(%rdx),%r10 + movq 24(%rdx),%r11 + xorq %rdi,%rdi + +.Lbeeu_reduction_loop: + movq %r12,16(%rsp) + movq %r13,24(%rsp) + movq %r14,32(%rsp) + movq %r15,40(%rsp) + movq %rbp,48(%rsp) + + + subq %r8,%r12 + sbbq %r9,%r13 + sbbq %r10,%r14 + sbbq %r11,%r15 + sbbq $0,%rbp + + + cmovcq 16(%rsp),%r12 + cmovcq 24(%rsp),%r13 + cmovcq 32(%rsp),%r14 + cmovcq 40(%rsp),%r15 + jnc .Lbeeu_reduction_loop + + + subq %r12,%r8 + sbbq %r13,%r9 + sbbq %r14,%r10 + sbbq %r15,%r11 + +.Lbeeu_save: + + movq 0(%rsp),%rdi + + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + + movq $1,%rax + jmp .Lbeeu_finish + +.Lbeeu_err: + + xorq %rax,%rax + +.Lbeeu_finish: + addq $80,%rsp +.cfi_adjust_cfa_offset -80 + popq %rsi +.cfi_adjust_cfa_offset -8 +.cfi_restore rsi + popq %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore rbx + popq %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore r15 + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore r12 + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore rbp + .byte 0xf3,0xc3 +.cfi_endproc + +.size beeu_mod_inverse_vartime, .-beeu_mod_inverse_vartime +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S new file mode 100644 index 00000000..7b2f65ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S @@ -0,0 +1,335 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +.private_extern _beeu_mod_inverse_vartime +.globl _beeu_mod_inverse_vartime +.private_extern _beeu_mod_inverse_vartime +.p2align 5 +_beeu_mod_inverse_vartime: + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + pushq %rbx + + pushq %rsi + + + subq $80,%rsp + + movq %rdi,0(%rsp) + + + movq $1,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %rdi,%rdi + + xorq %r12,%r12 + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + xorq %rbp,%rbp + + + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu %xmm0,48(%rsp) + vmovdqu %xmm1,64(%rsp) + + vmovdqu 0(%rdx),%xmm0 + vmovdqu 16(%rdx),%xmm1 + vmovdqu %xmm0,16(%rsp) + vmovdqu %xmm1,32(%rsp) + +L$beeu_loop: + xorq %rbx,%rbx + orq 48(%rsp),%rbx + orq 56(%rsp),%rbx + orq 64(%rsp),%rbx + orq 72(%rsp),%rbx + jz L$beeu_loop_end + + + + + + + + + + + movq $1,%rcx + + +L$beeu_shift_loop_XB: + movq %rcx,%rbx + andq 48(%rsp),%rbx + jnz L$beeu_shift_loop_end_XB + + + movq $1,%rbx + andq %r8,%rbx + jz L$shift1_0 + addq 0(%rdx),%r8 + adcq 8(%rdx),%r9 + adcq 16(%rdx),%r10 + adcq 24(%rdx),%r11 + adcq $0,%rdi + +L$shift1_0: + shrdq $1,%r9,%r8 + shrdq $1,%r10,%r9 + shrdq $1,%r11,%r10 + shrdq $1,%rdi,%r11 + shrq $1,%rdi + + shlq $1,%rcx + + + + + + cmpq $0x8000000,%rcx + jne L$beeu_shift_loop_XB + +L$beeu_shift_loop_end_XB: + bsfq %rcx,%rcx + testq %rcx,%rcx + jz L$beeu_no_shift_XB + + + + movq 8+48(%rsp),%rax + movq 16+48(%rsp),%rbx + movq 24+48(%rsp),%rsi + + shrdq %cl,%rax,0+48(%rsp) + shrdq %cl,%rbx,8+48(%rsp) + shrdq %cl,%rsi,16+48(%rsp) + + shrq %cl,%rsi + movq %rsi,24+48(%rsp) + + +L$beeu_no_shift_XB: + + movq $1,%rcx + + +L$beeu_shift_loop_YA: + movq %rcx,%rbx + andq 16(%rsp),%rbx + jnz L$beeu_shift_loop_end_YA + + + movq $1,%rbx + andq %r12,%rbx + jz L$shift1_1 + addq 0(%rdx),%r12 + adcq 8(%rdx),%r13 + adcq 16(%rdx),%r14 + adcq 24(%rdx),%r15 + adcq $0,%rbp + +L$shift1_1: + shrdq $1,%r13,%r12 + shrdq $1,%r14,%r13 + shrdq $1,%r15,%r14 + shrdq $1,%rbp,%r15 + shrq $1,%rbp + + shlq $1,%rcx + + + + + + cmpq $0x8000000,%rcx + jne L$beeu_shift_loop_YA + +L$beeu_shift_loop_end_YA: + bsfq %rcx,%rcx + testq %rcx,%rcx + jz L$beeu_no_shift_YA + + + + movq 8+16(%rsp),%rax + movq 16+16(%rsp),%rbx + movq 24+16(%rsp),%rsi + + shrdq %cl,%rax,0+16(%rsp) + shrdq %cl,%rbx,8+16(%rsp) + shrdq %cl,%rsi,16+16(%rsp) + + shrq %cl,%rsi + movq %rsi,24+16(%rsp) + + +L$beeu_no_shift_YA: + + movq 48(%rsp),%rax + movq 56(%rsp),%rbx + movq 64(%rsp),%rsi + movq 72(%rsp),%rcx + subq 16(%rsp),%rax + sbbq 24(%rsp),%rbx + sbbq 32(%rsp),%rsi + sbbq 40(%rsp),%rcx + jnc L$beeu_B_bigger_than_A + + + movq 16(%rsp),%rax + movq 24(%rsp),%rbx + movq 32(%rsp),%rsi + movq 40(%rsp),%rcx + subq 48(%rsp),%rax + sbbq 56(%rsp),%rbx + sbbq 64(%rsp),%rsi + sbbq 72(%rsp),%rcx + movq %rax,16(%rsp) + movq %rbx,24(%rsp) + movq %rsi,32(%rsp) + movq %rcx,40(%rsp) + + + addq %r8,%r12 + adcq %r9,%r13 + adcq %r10,%r14 + adcq %r11,%r15 + adcq %rdi,%rbp + jmp L$beeu_loop + +L$beeu_B_bigger_than_A: + + movq %rax,48(%rsp) + movq %rbx,56(%rsp) + movq %rsi,64(%rsp) + movq %rcx,72(%rsp) + + + addq %r12,%r8 + adcq %r13,%r9 + adcq %r14,%r10 + adcq %r15,%r11 + adcq %rbp,%rdi + + jmp L$beeu_loop + +L$beeu_loop_end: + + + + + movq 16(%rsp),%rbx + subq $1,%rbx + orq 24(%rsp),%rbx + orq 32(%rsp),%rbx + orq 40(%rsp),%rbx + + jnz L$beeu_err + + + + + movq 0(%rdx),%r8 + movq 8(%rdx),%r9 + movq 16(%rdx),%r10 + movq 24(%rdx),%r11 + xorq %rdi,%rdi + +L$beeu_reduction_loop: + movq %r12,16(%rsp) + movq %r13,24(%rsp) + movq %r14,32(%rsp) + movq %r15,40(%rsp) + movq %rbp,48(%rsp) + + + subq %r8,%r12 + sbbq %r9,%r13 + sbbq %r10,%r14 + sbbq %r11,%r15 + sbbq $0,%rbp + + + cmovcq 16(%rsp),%r12 + cmovcq 24(%rsp),%r13 + cmovcq 32(%rsp),%r14 + cmovcq 40(%rsp),%r15 + jnc L$beeu_reduction_loop + + + subq %r12,%r8 + sbbq %r13,%r9 + sbbq %r14,%r10 + sbbq %r15,%r11 + +L$beeu_save: + + movq 0(%rsp),%rdi + + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + + movq $1,%rax + jmp L$beeu_finish + +L$beeu_err: + + xorq %rax,%rax + +L$beeu_finish: + addq $80,%rsp + + popq %rsi + + popq %rbx + + popq %r15 + + popq %r14 + + popq %r13 + + popq %r12 + + popq %rbp + + .byte 0xf3,0xc3 + + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/ctrdrbg.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/ctrdrbg.c new file mode 100644 index 00000000..28aa7abd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/ctrdrbg.c @@ -0,0 +1,202 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../cipher/internal.h" + + +// Section references in this file refer to SP 800-90Ar1: +// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + +// See table 3. +static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; + +int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, size_t personalization_len) { + // Section 10.2.1.3.1 + if (personalization_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t seed_material[CTR_DRBG_ENTROPY_LEN]; + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 0; i < personalization_len; i++) { + seed_material[i] ^= personalization[i]; + } + + // Section 10.2.1.2 + + // kInitMask is the result of encrypting blocks with big-endian value 1, 2 + // and 3 with the all-zero AES-256 key. + static const uint8_t kInitMask[CTR_DRBG_ENTROPY_LEN] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, + 0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca, + 0x37, 0xa6, 0x2a, 0x74, 0xd1, 0xa2, 0xf5, 0x8e, 0x75, 0x06, 0x35, 0x8e, + }; + + for (size_t i = 0; i < sizeof(kInitMask); i++) { + seed_material[i] ^= kInitMask[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); + OPENSSL_memcpy(drbg->counter.bytes, seed_material + 32, 16); + drbg->reseed_counter = 1; + + return 1; +} + +OPENSSL_STATIC_ASSERT(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, + "not a multiple of AES block size"); + +// ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a +// big-endian number. +static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { + drbg->counter.words[3] = + CRYPTO_bswap4(CRYPTO_bswap4(drbg->counter.words[3]) + n); +} + +static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, + size_t data_len) { + // Per section 10.2.1.2, |data_len| must be |CTR_DRBG_ENTROPY_LEN|. Here, we + // allow shorter inputs and right-pad them with zeros. This is equivalent to + // the specified algorithm but saves a copy in |CTR_DRBG_generate|. + if (data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t temp[CTR_DRBG_ENTROPY_LEN]; + for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, temp + i, &drbg->ks); + } + + for (size_t i = 0; i < data_len; i++) { + temp[i] ^= data[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32); + OPENSSL_memcpy(drbg->counter.bytes, temp + 32, 16); + + return 1; +} + +int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len) { + // Section 10.2.1.4 + uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; + + if (additional_data_len > 0) { + if (additional_data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + OPENSSL_memcpy(entropy_copy, entropy, CTR_DRBG_ENTROPY_LEN); + for (size_t i = 0; i < additional_data_len; i++) { + entropy_copy[i] ^= additional_data[i]; + } + + entropy = entropy_copy; + } + + if (!ctr_drbg_update(drbg, entropy, CTR_DRBG_ENTROPY_LEN)) { + return 0; + } + + drbg->reseed_counter = 1; + + return 1; +} + +int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len) { + // See 9.3.1 + if (out_len > CTR_DRBG_MAX_GENERATE_LENGTH) { + return 0; + } + + // See 10.2.1.5.1 + if (drbg->reseed_counter > kMaxReseedCount) { + return 0; + } + + if (additional_data_len != 0 && + !ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + // kChunkSize is used to interact better with the cache. Since the AES-CTR + // code assumes that it's encrypting rather than just writing keystream, the + // buffer has to be zeroed first. Without chunking, large reads would zero + // the whole buffer, flushing the L1 cache, and then do another pass (missing + // the cache every time) to “encrypt” it. The code can avoid this by + // chunking. + static const size_t kChunkSize = 8 * 1024; + + while (out_len >= AES_BLOCK_SIZE) { + size_t todo = kChunkSize; + if (todo > out_len) { + todo = out_len; + } + + todo &= ~(AES_BLOCK_SIZE-1); + const size_t num_blocks = todo / AES_BLOCK_SIZE; + + if (drbg->ctr) { + OPENSSL_memset(out, 0, todo); + ctr32_add(drbg, 1); + drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter.bytes); + ctr32_add(drbg, num_blocks - 1); + } else { + for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, out + i, &drbg->ks); + } + } + + out += todo; + out_len -= todo; + } + + if (out_len > 0) { + uint8_t block[AES_BLOCK_SIZE]; + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, block, &drbg->ks); + + OPENSSL_memcpy(out, block, out_len); + } + + // Right-padding |additional_data| in step 2.2 is handled implicitly by + // |ctr_drbg_update|, to save a copy. + if (!ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + drbg->reseed_counter++; + return 1; +} + +void CTR_DRBG_clear(CTR_DRBG_STATE *drbg) { + OPENSSL_cleanse(drbg, sizeof(CTR_DRBG_STATE)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c new file mode 100644 index 00000000..fd7c1069 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c @@ -0,0 +1,137 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE // needed for madvise() and MAP_ANONYMOUS on Linux. +#endif + +#include + +#include "fork_detect.h" + +#if defined(OPENSSL_LINUX) +#include +#include +#include + +#include + +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(MADV_WIPEONFORK) +OPENSSL_STATIC_ASSERT(MADV_WIPEONFORK == 18, "MADV_WIPEONFORK is not 18"); +#else +#define MADV_WIPEONFORK 18 +#endif + +DEFINE_STATIC_ONCE(g_fork_detect_once); +DEFINE_STATIC_MUTEX(g_fork_detect_lock); +DEFINE_BSS_GET(volatile char *, g_fork_detect_addr); +DEFINE_BSS_GET(uint64_t, g_fork_generation); +DEFINE_BSS_GET(int, g_ignore_madv_wipeonfork); + +static void init_fork_detect(void) { + if (*g_ignore_madv_wipeonfork_bss_get()) { + return; + } + + long page_size = sysconf(_SC_PAGESIZE); + if (page_size <= 0) { + return; + } + + void *addr = mmap(NULL, (size_t)page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (addr == MAP_FAILED) { + return; + } + + // Some versions of qemu (up to at least 5.0.0-rc4, see linux-user/syscall.c) + // ignore |madvise| calls and just return zero (i.e. success). But we need to + // know whether MADV_WIPEONFORK actually took effect. Therefore try an invalid + // call to check that the implementation of |madvise| is actually rejecting + // unknown |advice| values. + if (madvise(addr, (size_t)page_size, -1) == 0 || + madvise(addr, (size_t)page_size, MADV_WIPEONFORK) != 0) { + munmap(addr, (size_t)page_size); + return; + } + + *((volatile char *) addr) = 1; + *g_fork_detect_addr_bss_get() = addr; + *g_fork_generation_bss_get() = 1; +} + +uint64_t CRYPTO_get_fork_generation(void) { + // In a single-threaded process, there are obviously no races because there's + // only a single mutator in the address space. + // + // In a multi-threaded environment, |CRYPTO_once| ensures that the flag byte + // is initialised atomically, even if multiple threads enter this function + // concurrently. + // + // In the limit, the kernel may clear WIPEONFORK pages while a multi-threaded + // process is running. (For example, because a VM was cloned.) Therefore a + // lock is used below to synchronise the potentially multiple threads that may + // concurrently observe the cleared flag. + + CRYPTO_once(g_fork_detect_once_bss_get(), init_fork_detect); + // This pointer is |volatile| because the value pointed to may be changed by + // external forces (i.e. the kernel wiping the page) thus the compiler must + // not assume that it has exclusive access to it. + volatile char *const flag_ptr = *g_fork_detect_addr_bss_get(); + if (flag_ptr == NULL) { + // Our kernel is too old to support |MADV_WIPEONFORK|. + return 0; + } + + struct CRYPTO_STATIC_MUTEX *const lock = g_fork_detect_lock_bss_get(); + uint64_t *const generation_ptr = g_fork_generation_bss_get(); + + CRYPTO_STATIC_MUTEX_lock_read(lock); + uint64_t current_generation = *generation_ptr; + if (*flag_ptr) { + CRYPTO_STATIC_MUTEX_unlock_read(lock); + return current_generation; + } + + CRYPTO_STATIC_MUTEX_unlock_read(lock); + CRYPTO_STATIC_MUTEX_lock_write(lock); + current_generation = *generation_ptr; + if (*flag_ptr == 0) { + // A fork has occurred. + *flag_ptr = 1; + + current_generation++; + if (current_generation == 0) { + current_generation = 1; + } + *generation_ptr = current_generation; + } + CRYPTO_STATIC_MUTEX_unlock_write(lock); + + return current_generation; +} + +void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void) { + *g_ignore_madv_wipeonfork_bss_get() = 1; +} + +#else // !OPENSSL_LINUX + +uint64_t CRYPTO_get_fork_generation(void) { return 0; } + +#endif // OPENSSL_LINUX diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h new file mode 100644 index 00000000..85368679 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FORK_DETECT_H +#define OPENSSL_HEADER_CRYPTO_FORK_DETECT_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// crypto_get_fork_generation returns the fork generation number for the current +// process, or zero if not supported on the platform. The fork generation number +// is a non-zero, strictly-monotonic counter with the property that, if queried +// in an address space and then again in a subsequently forked copy, the forked +// address space will observe a greater value. +// +// This function may be used to clear cached values across a fork. When +// initializing a cache, record the fork generation. Before using the cache, +// check if the fork generation has changed. If so, drop the cache and update +// the save fork generation. Note this logic transparently handles platforms +// which always return zero. +// +// This is not reliably supported on all platforms which implement |fork|, so it +// should only be used as a hardening measure. +OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void); + +// CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing is an internal detail +// used for testing purposes. +OPENSSL_EXPORT void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FORK_DETECT_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h new file mode 100644 index 00000000..cac718df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_RAND_GETRANDOM_FILLIN_H +#define OPENSSL_HEADER_CRYPTO_RAND_GETRANDOM_FILLIN_H + +#include + + +#if defined(OPENSSL_LINUX) + +#include + +#if defined(OPENSSL_X86_64) +#define EXPECTED_NR_getrandom 318 +#elif defined(OPENSSL_X86) +#define EXPECTED_NR_getrandom 355 +#elif defined(OPENSSL_AARCH64) +#define EXPECTED_NR_getrandom 278 +#elif defined(OPENSSL_ARM) +#define EXPECTED_NR_getrandom 384 +#elif defined(OPENSSL_PPC64LE) +#define EXPECTED_NR_getrandom 359 +#endif + +#if defined(EXPECTED_NR_getrandom) +#define USE_NR_getrandom + +#if defined(__NR_getrandom) + +#if __NR_getrandom != EXPECTED_NR_getrandom +#error "system call number for getrandom is not the expected value" +#endif + +#else // __NR_getrandom + +#define __NR_getrandom EXPECTED_NR_getrandom + +#endif // __NR_getrandom + +#endif // EXPECTED_NR_getrandom + +#if !defined(GRND_NONBLOCK) +#define GRND_NONBLOCK 1 +#endif +#if !defined(GRND_RANDOM) +#define GRND_RANDOM 2 +#endif + +#endif // OPENSSL_LINUX + + +#endif // OPENSSL_HEADER_CRYPTO_RAND_GETRANDOM_FILLIN_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/internal.h new file mode 100644 index 00000000..7b4133d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/internal.h @@ -0,0 +1,182 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H + +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && !defined(OPENSSL_TRUSTY) +#define OPENSSL_URANDOM +#endif + +// RAND_bytes_with_additional_data samples from the RNG after mixing 32 bytes +// from |user_additional_data| in. +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]); + +#if defined(BORINGSSL_FIPS) + +// We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to whiten. +#define BORINGSSL_FIPS_OVERREAD 10 + +// CRYPTO_get_seed_entropy writes |out_entropy_len| bytes of entropy, suitable +// for seeding a DRBG, to |out_entropy|. It sets |*out_used_cpu| to one if the +// entropy came directly from the CPU and zero if it came from the OS. It +// actively obtains entropy from the CPU/OS and so should not be called from +// within the FIPS module. +void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, + int *out_used_cpu); + +// RAND_load_entropy supplies |entropy_len| bytes of entropy to the module. The +// |from_cpu| parameter is true iff the entropy was obtained directly from the +// CPU. +void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len, + int from_cpu); + +// RAND_need_entropy is implemented outside of the FIPS module and is called +// when the module has stopped because it has run out of entropy. +void RAND_need_entropy(size_t bytes_needed); + +#endif // BORINGSSL_FIPS + +// CRYPTO_sysrand fills |len| bytes at |buf| with entropy from the operating +// system. +void CRYPTO_sysrand(uint8_t *buf, size_t len); + +// CRYPTO_sysrand_for_seed fills |len| bytes at |buf| with entropy from the +// operating system. It may draw from the |GRND_RANDOM| pool on Android, +// depending on the vendor's configuration. +void CRYPTO_sysrand_for_seed(uint8_t *buf, size_t len); + +#if defined(OPENSSL_URANDOM) +// CRYPTO_init_sysrand initializes long-lived resources needed to draw entropy +// from the operating system. +void CRYPTO_init_sysrand(void); + +// CRYPTO_sysrand_if_available fills |len| bytes at |buf| with entropy from the +// operating system, or early /dev/urandom data, and returns 1, _if_ the entropy +// pool is initialized or if getrandom() is not available and not in FIPS mode. +// Otherwise it will not block and will instead fill |buf| with all zeros and +// return 0. +int CRYPTO_sysrand_if_available(uint8_t *buf, size_t len); +#else +OPENSSL_INLINE void CRYPTO_init_sysrand(void) {} + +OPENSSL_INLINE int CRYPTO_sysrand_if_available(uint8_t *buf, size_t len) { + CRYPTO_sysrand(buf, len); + return 1; +} +#endif + +// rand_fork_unsafe_buffering_enabled returns whether fork-unsafe buffering has +// been enabled via |RAND_enable_fork_unsafe_buffering|. +int rand_fork_unsafe_buffering_enabled(void); + +// CTR_DRBG_STATE contains the state of a CTR_DRBG based on AES-256. See SP +// 800-90Ar1. +typedef struct { + AES_KEY ks; + block128_f block; + ctr128_f ctr; + union { + uint8_t bytes[16]; + uint32_t words[4]; + } counter; + uint64_t reseed_counter; +} CTR_DRBG_STATE; + +// See SP 800-90Ar1, table 3. +#define CTR_DRBG_ENTROPY_LEN 48 +#define CTR_DRBG_MAX_GENERATE_LENGTH 65536 + +// CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of +// entropy in |entropy| and, optionally, a personalization string up to +// |CTR_DRBG_ENTROPY_LEN| bytes in length. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, + size_t personalization_len); + +// CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy +// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// additional data. It returns one on success or zero on error. +OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional +// data (if any) and then writes |out_len| random bytes to |out|, where +// |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, + size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_clear zeroises the state of |drbg|. +OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); + + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +OPENSSL_INLINE int have_rdrand(void) { + return CRYPTO_is_RDRAND_capable(); +} + +// have_fast_rdrand returns true if RDRAND is supported and it's reasonably +// fast. Concretely the latter is defined by whether the chip is Intel (fast) or +// not (assumed slow). +OPENSSL_INLINE int have_fast_rdrand(void) { + return CRYPTO_is_RDRAND_capable() && CRYPTO_is_intel_cpu(); +} + +// CRYPTO_rdrand writes eight bytes of random data from the hardware RNG to +// |out|. It returns one on success or zero on hardware failure. +int CRYPTO_rdrand(uint8_t out[8]); + +// CRYPTO_rdrand_multiple8_buf fills |len| bytes at |buf| with random data from +// the hardware RNG. The |len| argument must be a multiple of eight. It returns +// one on success and zero on hardware failure. +int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); + +#else // OPENSSL_X86_64 && !OPENSSL_NO_ASM + +OPENSSL_INLINE int have_rdrand(void) { + return 0; +} + +OPENSSL_INLINE int have_fast_rdrand(void) { + return 0; +} + +#endif // OPENSSL_X86_64 && !OPENSSL_NO_ASM + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c new file mode 100644 index 00000000..b204ea53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c @@ -0,0 +1,456 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#if defined(BORINGSSL_FIPS) +#include +#endif + +#include +#include +#include + +#include "internal.h" +#include "fork_detect.h" +#include "../../internal.h" +#include "../delocate.h" + + +// It's assumed that the operating system always has an unfailing source of +// entropy which is accessed via |CRYPTO_sysrand[_for_seed]|. (If the operating +// system entropy source fails, it's up to |CRYPTO_sysrand| to abort the +// process—we don't try to handle it.) +// +// In addition, the hardware may provide a low-latency RNG. Intel's rdrand +// instruction is the canonical example of this. When a hardware RNG is +// available we don't need to worry about an RNG failure arising from fork()ing +// the process or moving a VM, so we can keep thread-local RNG state and use it +// as an additional-data input to CTR-DRBG. +// +// (We assume that the OS entropy is safe from fork()ing and VM duplication. +// This might be a bit of a leap of faith, esp on Windows, but there's nothing +// that we can do about it.) + +// kReseedInterval is the number of generate calls made to CTR-DRBG before +// reseeding. +static const unsigned kReseedInterval = 4096; + +// CRNGT_BLOCK_SIZE is the number of bytes in a “block” for the purposes of the +// continuous random number generator test in FIPS 140-2, section 4.9.2. +#define CRNGT_BLOCK_SIZE 16 + +// rand_thread_state contains the per-thread state for the RNG. +struct rand_thread_state { + CTR_DRBG_STATE drbg; + uint64_t fork_generation; + // calls is the number of generate calls made on |drbg| since it was last + // (re)seeded. This is bound by |kReseedInterval|. + unsigned calls; + // last_block_valid is non-zero iff |last_block| contains data from + // |get_seed_entropy|. + int last_block_valid; + +#if defined(BORINGSSL_FIPS) + // last_block contains the previous block from |get_seed_entropy|. + uint8_t last_block[CRNGT_BLOCK_SIZE]; + // next and prev form a NULL-terminated, double-linked list of all states in + // a process. + struct rand_thread_state *next, *prev; +#endif +}; + +#if defined(BORINGSSL_FIPS) +// thread_states_list is the head of a linked-list of all |rand_thread_state| +// objects in the process, one per thread. This is needed because FIPS requires +// that they be zeroed on process exit, but thread-local destructors aren't +// called when the whole process is exiting. +DEFINE_BSS_GET(struct rand_thread_state *, thread_states_list); +DEFINE_STATIC_MUTEX(thread_states_list_lock); +DEFINE_STATIC_MUTEX(state_clear_all_lock); + +static void rand_thread_state_clear_all(void) __attribute__((destructor)); +static void rand_thread_state_clear_all(void) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + CRYPTO_STATIC_MUTEX_lock_write(state_clear_all_lock_bss_get()); + for (struct rand_thread_state *cur = *thread_states_list_bss_get(); + cur != NULL; cur = cur->next) { + CTR_DRBG_clear(&cur->drbg); + } + // The locks are deliberately left locked so that any threads that are still + // running will hang if they try to call |RAND_bytes|. +} +#endif + +// rand_thread_state_free frees a |rand_thread_state|. This is called when a +// thread exits. +static void rand_thread_state_free(void *state_in) { + struct rand_thread_state *state = state_in; + + if (state_in == NULL) { + return; + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + + if (state->prev != NULL) { + state->prev->next = state->next; + } else { + *thread_states_list_bss_get() = state->next; + } + + if (state->next != NULL) { + state->next->prev = state->prev; + } + + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + + CTR_DRBG_clear(&state->drbg); +#endif + + OPENSSL_free(state); +} + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +// rdrand should only be called if either |have_rdrand| or |have_fast_rdrand| +// returned true. +static int rdrand(uint8_t *buf, const size_t len) { + const size_t len_multiple8 = len & ~7; + if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { + return 0; + } + const size_t remainder = len - len_multiple8; + + if (remainder != 0) { + assert(remainder < 8); + + uint8_t rand_buf[8]; + if (!CRYPTO_rdrand(rand_buf)) { + return 0; + } + OPENSSL_memcpy(buf + len_multiple8, rand_buf, remainder); + } + + return 1; +} + +#else + +static int rdrand(uint8_t *buf, size_t len) { + return 0; +} + +#endif + +#if defined(BORINGSSL_FIPS) + +void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, + int *out_used_cpu) { + *out_used_cpu = 0; + if (have_rdrand() && rdrand(out_entropy, out_entropy_len)) { + *out_used_cpu = 1; + } else { + CRYPTO_sysrand_for_seed(out_entropy, out_entropy_len); + } + + if (boringssl_fips_break_test("CRNG")) { + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in |rand_get_seed|. + OPENSSL_memset(out_entropy, 0, out_entropy_len); + } +} + +// In passive entropy mode, entropy is supplied from outside of the module via +// |RAND_load_entropy| and is stored in global instance of the following +// structure. + +struct entropy_buffer { + // bytes contains entropy suitable for seeding a DRBG. + uint8_t bytes[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + // bytes_valid indicates the number of bytes of |bytes| that contain valid + // data. + size_t bytes_valid; + // from_cpu is true if any of the contents of |bytes| were obtained directly + // from the CPU. + int from_cpu; +}; + +DEFINE_BSS_GET(struct entropy_buffer, entropy_buffer); +DEFINE_STATIC_MUTEX(entropy_buffer_lock); + +void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len, + int from_cpu) { + struct entropy_buffer *const buffer = entropy_buffer_bss_get(); + + CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + const size_t space = sizeof(buffer->bytes) - buffer->bytes_valid; + if (entropy_len > space) { + entropy_len = space; + } + + OPENSSL_memcpy(&buffer->bytes[buffer->bytes_valid], entropy, entropy_len); + buffer->bytes_valid += entropy_len; + buffer->from_cpu |= from_cpu && (entropy_len != 0); + CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); +} + +// get_seed_entropy fills |out_entropy_len| bytes of |out_entropy| from the +// global |entropy_buffer|. +static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, + int *out_used_cpu) { + struct entropy_buffer *const buffer = entropy_buffer_bss_get(); + if (out_entropy_len > sizeof(buffer->bytes)) { + abort(); + } + + CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + while (buffer->bytes_valid < out_entropy_len) { + CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); + RAND_need_entropy(out_entropy_len - buffer->bytes_valid); + CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + } + + *out_used_cpu = buffer->from_cpu; + OPENSSL_memcpy(out_entropy, buffer->bytes, out_entropy_len); + OPENSSL_memmove(buffer->bytes, &buffer->bytes[out_entropy_len], + buffer->bytes_valid - out_entropy_len); + buffer->bytes_valid -= out_entropy_len; + if (buffer->bytes_valid == 0) { + buffer->from_cpu = 0; + } + + CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); +} + +// rand_get_seed fills |seed| with entropy and sets |*out_used_cpu| to one if +// that entropy came directly from the CPU and zero otherwise. +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN], + int *out_used_cpu) { + if (!state->last_block_valid) { + int unused; + get_seed_entropy(state->last_block, sizeof(state->last_block), &unused); + state->last_block_valid = 1; + } + + uint8_t entropy[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + get_seed_entropy(entropy, sizeof(entropy), out_used_cpu); + + // See FIPS 140-2, section 4.9.2. This is the “continuous random number + // generator test” which causes the program to randomly abort. Hopefully the + // rate of failure is small enough not to be a problem in practice. + if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) { + fprintf(stderr, "CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + + OPENSSL_STATIC_ASSERT(sizeof(entropy) % CRNGT_BLOCK_SIZE == 0, ""); + for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy); + i += CRNGT_BLOCK_SIZE) { + if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, + CRNGT_BLOCK_SIZE) == 0) { + fprintf(stderr, "CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + } + OPENSSL_memcpy(state->last_block, + entropy + sizeof(entropy) - CRNGT_BLOCK_SIZE, + CRNGT_BLOCK_SIZE); + + OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 1; i < BORINGSSL_FIPS_OVERREAD; i++) { + for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { + seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; + } + } +} + +#else + +// rand_get_seed fills |seed| with entropy and sets |*out_used_cpu| to one if +// that entropy came directly from the CPU and zero otherwise. +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN], + int *out_used_cpu) { + // If not in FIPS mode, we don't overread from the system entropy source and + // we don't depend only on the hardware RDRAND. + CRYPTO_sysrand_for_seed(seed, CTR_DRBG_ENTROPY_LEN); + *out_used_cpu = 0; +} + +#endif + +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]) { + if (out_len == 0) { + return; + } + + const uint64_t fork_generation = CRYPTO_get_fork_generation(); + + // Additional data is mixed into every CTR-DRBG call to protect, as best we + // can, against forks & VM clones. We do not over-read this information and + // don't reseed with it so, from the point of view of FIPS, this doesn't + // provide “prediction resistance”. But, in practice, it does. + uint8_t additional_data[32]; + // Intel chips have fast RDRAND instructions while, in other cases, RDRAND can + // be _slower_ than a system call. + if (!have_fast_rdrand() || + !rdrand(additional_data, sizeof(additional_data))) { + // Without a hardware RNG to save us from address-space duplication, the OS + // entropy is used. This can be expensive (one read per |RAND_bytes| call) + // and so is disabled when we have fork detection, or if the application has + // promised not to fork. + if (fork_generation != 0 || rand_fork_unsafe_buffering_enabled()) { + OPENSSL_memset(additional_data, 0, sizeof(additional_data)); + } else if (!have_rdrand()) { + // No alternative so block for OS entropy. + CRYPTO_sysrand(additional_data, sizeof(additional_data)); + } else if (!CRYPTO_sysrand_if_available(additional_data, + sizeof(additional_data)) && + !rdrand(additional_data, sizeof(additional_data))) { + // RDRAND failed: block for OS entropy. + CRYPTO_sysrand(additional_data, sizeof(additional_data)); + } + } + + for (size_t i = 0; i < sizeof(additional_data); i++) { + additional_data[i] ^= user_additional_data[i]; + } + + struct rand_thread_state stack_state; + struct rand_thread_state *state = + CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); + + if (state == NULL) { + state = OPENSSL_malloc(sizeof(struct rand_thread_state)); + if (state == NULL || + !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, + rand_thread_state_free)) { + // If the system is out of memory, use an ephemeral state on the + // stack. + state = &stack_state; + } + + state->last_block_valid = 0; + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + int used_cpu; + rand_get_seed(state, seed, &used_cpu); + + uint8_t personalization[CTR_DRBG_ENTROPY_LEN] = {0}; + size_t personalization_len = 0; +#if defined(OPENSSL_URANDOM) + // If we used RDRAND, also opportunistically read from the system. This + // avoids solely relying on the hardware once the entropy pool has been + // initialized. + if (used_cpu && + CRYPTO_sysrand_if_available(personalization, sizeof(personalization))) { + personalization_len = sizeof(personalization); + } +#endif + + if (!CTR_DRBG_init(&state->drbg, seed, personalization, + personalization_len)) { + abort(); + } + state->calls = 0; + state->fork_generation = fork_generation; + +#if defined(BORINGSSL_FIPS) + if (state != &stack_state) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + struct rand_thread_state **states_list = thread_states_list_bss_get(); + state->next = *states_list; + if (state->next != NULL) { + state->next->prev = state; + } + state->prev = NULL; + *states_list = state; + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + } +#endif + } + + if (state->calls >= kReseedInterval || + state->fork_generation != fork_generation) { + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + int used_cpu; + rand_get_seed(state, seed, &used_cpu); +#if defined(BORINGSSL_FIPS) + // Take a read lock around accesses to |state->drbg|. This is needed to + // avoid returning bad entropy if we race with + // |rand_thread_state_clear_all|. + // + // This lock must be taken after any calls to |CRYPTO_sysrand| to avoid a + // bug on ppc64le. glibc may implement pthread locks by wrapping user code + // in a hardware transaction, but, on some older versions of glibc and the + // kernel, syscalls made with |syscall| did not abort the transaction. + CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get()); +#endif + if (!CTR_DRBG_reseed(&state->drbg, seed, NULL, 0)) { + abort(); + } + state->calls = 0; + state->fork_generation = fork_generation; + } else { +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get()); +#endif + } + + int first_call = 1; + while (out_len > 0) { + size_t todo = out_len; + if (todo > CTR_DRBG_MAX_GENERATE_LENGTH) { + todo = CTR_DRBG_MAX_GENERATE_LENGTH; + } + + if (!CTR_DRBG_generate(&state->drbg, out, todo, additional_data, + first_call ? sizeof(additional_data) : 0)) { + abort(); + } + + out += todo; + out_len -= todo; + // Though we only check before entering the loop, this cannot add enough to + // overflow a |size_t|. + state->calls++; + first_call = 0; + } + + if (state == &stack_state) { + CTR_DRBG_clear(&state->drbg); + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_unlock_read(state_clear_all_lock_bss_get()); +#endif +} + +int RAND_bytes(uint8_t *out, size_t out_len) { + static const uint8_t kZeroAdditionalData[32] = {0}; + RAND_bytes_with_additional_data(out, out_len, kZeroAdditionalData); + return 1; +} + +int RAND_pseudo_bytes(uint8_t *buf, size_t len) { + return RAND_bytes(buf, len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/urandom.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/urandom.c new file mode 100644 index 00000000..c9d91040 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rand/urandom.c @@ -0,0 +1,401 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE // needed for syscall() on Linux. +#endif + +#include + +#include "internal.h" + +#if defined(OPENSSL_URANDOM) + +#include +#include +#include +#include +#include +#include + +#if defined(OPENSSL_LINUX) +#if defined(BORINGSSL_FIPS) +#include +#include +#endif +#include + +#if defined(OPENSSL_ANDROID) +#include +#endif + +#if !defined(OPENSSL_ANDROID) +#define OPENSSL_HAS_GETAUXVAL +#endif +// glibc prior to 2.16 does not have getauxval and sys/auxv.h. Android has some +// host builds (i.e. not building for Android itself, so |OPENSSL_ANDROID| is +// unset) which are still using a 2.15 sysroot. +// +// TODO(davidben): Remove this once Android updates their sysroot. +#if defined(__GLIBC_PREREQ) +#if !__GLIBC_PREREQ(2, 16) +#undef OPENSSL_HAS_GETAUXVAL +#endif +#endif +#if defined(OPENSSL_HAS_GETAUXVAL) +#include +#endif +#endif // OPENSSL_LINUX + +#if defined(OPENSSL_MACOS) +#include +#endif + +#if defined(OPENSSL_FREEBSD) +#define URANDOM_BLOCKS_FOR_ENTROPY +#if __FreeBSD__ >= 12 +// getrandom is supported in FreeBSD 12 and up. +#define FREEBSD_GETRANDOM +#include +#endif +#endif + +#include +#include + +#include "getrandom_fillin.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(USE_NR_getrandom) + +#if defined(OPENSSL_MSAN) +void __msan_unpoison(void *, size_t); +#endif + +static ssize_t boringssl_getrandom(void *buf, size_t buf_len, unsigned flags) { + ssize_t ret; + do { + ret = syscall(__NR_getrandom, buf, buf_len, flags); + } while (ret == -1 && errno == EINTR); + +#if defined(OPENSSL_MSAN) + if (ret > 0) { + // MSAN doesn't recognise |syscall| and thus doesn't notice that we have + // initialised the output buffer. + __msan_unpoison(buf, ret); + } +#endif // OPENSSL_MSAN + + return ret; +} + +#endif // USE_NR_getrandom + +// kHaveGetrandom in |urandom_fd| signals that |getrandom| or |getentropy| is +// available and should be used instead. +static const int kHaveGetrandom = -3; + +// urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. +DEFINE_BSS_GET(int, urandom_fd) + +#if defined(USE_NR_getrandom) + +// getrandom_ready is one if |getrandom| had been initialized by the time +// |init_once| was called and zero otherwise. +DEFINE_BSS_GET(int, getrandom_ready) + +// extra_getrandom_flags_for_seed contains a value that is ORed into the flags +// for getrandom() when reading entropy for a seed. +DEFINE_BSS_GET(int, extra_getrandom_flags_for_seed) + +// On Android, check a system property to decide whether to set +// |extra_getrandom_flags_for_seed| otherwise they will default to zero. If +// ro.oem_boringcrypto_hwrand is true then |extra_getrandom_flags_for_seed| will +// be set to GRND_RANDOM, causing all random data to be drawn from the same +// source as /dev/random. +static void maybe_set_extra_getrandom_flags(void) { +#if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID) + char value[PROP_VALUE_MAX + 1]; + int length = __system_property_get("ro.boringcrypto.hwrand", value); + if (length < 0 || length > PROP_VALUE_MAX) { + return; + } + + value[length] = 0; + if (strcasecmp(value, "true") == 0) { + *extra_getrandom_flags_for_seed_bss_get() = GRND_RANDOM; + } +#endif +} + +#endif // USE_NR_getrandom + +DEFINE_STATIC_ONCE(rand_once) + +// init_once initializes the state of this module to values previously +// requested. This is the only function that modifies |urandom_fd|, which may be +// read safely after calling the once. +static void init_once(void) { +#if defined(USE_NR_getrandom) + int have_getrandom; + uint8_t dummy; + ssize_t getrandom_ret = + boringssl_getrandom(&dummy, sizeof(dummy), GRND_NONBLOCK); + if (getrandom_ret == 1) { + *getrandom_ready_bss_get() = 1; + have_getrandom = 1; + } else if (getrandom_ret == -1 && errno == EAGAIN) { + // We have getrandom, but the entropy pool has not been initialized yet. + have_getrandom = 1; + } else if (getrandom_ret == -1 && errno == ENOSYS) { + // Fallthrough to using /dev/urandom, below. + have_getrandom = 0; + } else { + // Other errors are fatal. + perror("getrandom"); + abort(); + } + + if (have_getrandom) { + *urandom_fd_bss_get() = kHaveGetrandom; + maybe_set_extra_getrandom_flags(); + return; + } +#endif // USE_NR_getrandom + +#if defined(OPENSSL_MACOS) + // getentropy is available in macOS 10.12 and up. iOS 10 and up may also + // support it, but the header is missing. See https://crbug.com/boringssl/287. + if (__builtin_available(macos 10.12, *)) { + *urandom_fd_bss_get() = kHaveGetrandom; + return; + } +#endif + +#if defined(FREEBSD_GETRANDOM) + *urandom_fd_bss_get() = kHaveGetrandom; + return; +#endif + + // Android FIPS builds must support getrandom. +#if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID) + perror("getrandom not found"); + abort(); +#endif + + int fd; + do { + fd = open("/dev/urandom", O_RDONLY); + } while (fd == -1 && errno == EINTR); + + if (fd < 0) { + perror("failed to open /dev/urandom"); + abort(); + } + + int flags = fcntl(fd, F_GETFD); + if (flags == -1) { + // Native Client doesn't implement |fcntl|. + if (errno != ENOSYS) { + perror("failed to get flags from urandom fd"); + abort(); + } + } else { + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) { + perror("failed to set FD_CLOEXEC on urandom fd"); + abort(); + } + } + *urandom_fd_bss_get() = fd; +} + +DEFINE_STATIC_ONCE(wait_for_entropy_once) + +static void wait_for_entropy(void) { + int fd = *urandom_fd_bss_get(); + if (fd == kHaveGetrandom) { + // |getrandom| and |getentropy| support blocking in |fill_with_entropy| + // directly. For |getrandom|, we first probe with a non-blocking call to aid + // debugging. +#if defined(USE_NR_getrandom) + if (*getrandom_ready_bss_get()) { + // The entropy pool was already initialized in |init_once|. + return; + } + + uint8_t dummy; + ssize_t getrandom_ret = + boringssl_getrandom(&dummy, sizeof(dummy), GRND_NONBLOCK); + if (getrandom_ret == -1 && errno == EAGAIN) { + // Attempt to get the path of the current process to aid in debugging when + // something blocks. + const char *current_process = ""; +#if defined(OPENSSL_HAS_GETAUXVAL) + const unsigned long getauxval_ret = getauxval(AT_EXECFN); + if (getauxval_ret != 0) { + current_process = (const char *)getauxval_ret; + } +#endif + + fprintf( + stderr, + "%s: getrandom indicates that the entropy pool has not been " + "initialized. Rather than continue with poor entropy, this process " + "will block until entropy is available.\n", + current_process); + + getrandom_ret = + boringssl_getrandom(&dummy, sizeof(dummy), 0 /* no flags */); + } + + if (getrandom_ret != 1) { + perror("getrandom"); + abort(); + } +#endif // USE_NR_getrandom + return; + } + +#if defined(BORINGSSL_FIPS) && !defined(URANDOM_BLOCKS_FOR_ENTROPY) + // In FIPS mode on platforms where urandom doesn't block at startup, we ensure + // that the kernel has sufficient entropy before continuing. This is + // automatically handled by getrandom, which requires that the entropy pool + // has been initialised, but for urandom we have to poll. + for (;;) { + int entropy_bits; + if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { + fprintf(stderr, + "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " + "case when in FIPS mode.\n"); + abort(); + } + + static const int kBitsNeeded = 256; + if (entropy_bits >= kBitsNeeded) { + break; + } + + usleep(250000); + } +#endif // BORINGSSL_FIPS && !URANDOM_BLOCKS_FOR_ENTROPY +} + +// fill_with_entropy writes |len| bytes of entropy into |out|. It returns one +// on success and zero on error. If |block| is one, this function will block +// until the entropy pool is initialized. Otherwise, this function may fail, +// setting |errno| to |EAGAIN| if the entropy pool has not yet been initialized. +// If |seed| is one, this function will OR in the value of +// |*extra_getrandom_flags_for_seed()| when using |getrandom|. +static int fill_with_entropy(uint8_t *out, size_t len, int block, int seed) { + if (len == 0) { + return 1; + } + +#if defined(USE_NR_getrandom) || defined(FREEBSD_GETRANDOM) + int getrandom_flags = 0; + if (!block) { + getrandom_flags |= GRND_NONBLOCK; + } +#endif + +#if defined (USE_NR_getrandom) + if (seed) { + getrandom_flags |= *extra_getrandom_flags_for_seed_bss_get(); + } +#endif + + CRYPTO_init_sysrand(); + if (block) { + CRYPTO_once(wait_for_entropy_once_bss_get(), wait_for_entropy); + } + + // Clear |errno| so it has defined value if |read| or |getrandom| + // "successfully" returns zero. + errno = 0; + while (len > 0) { + ssize_t r; + + if (*urandom_fd_bss_get() == kHaveGetrandom) { +#if defined(USE_NR_getrandom) + r = boringssl_getrandom(out, len, getrandom_flags); +#elif defined(FREEBSD_GETRANDOM) + r = getrandom(out, len, getrandom_flags); +#elif defined(OPENSSL_MACOS) + if (__builtin_available(macos 10.12, *)) { + // |getentropy| can only request 256 bytes at a time. + size_t todo = len <= 256 ? len : 256; + if (getentropy(out, todo) != 0) { + r = -1; + } else { + r = (ssize_t)todo; + } + } else { + fprintf(stderr, "urandom fd corrupt.\n"); + abort(); + } +#else // USE_NR_getrandom + fprintf(stderr, "urandom fd corrupt.\n"); + abort(); +#endif + } else { + do { + r = read(*urandom_fd_bss_get(), out, len); + } while (r == -1 && errno == EINTR); + } + + if (r <= 0) { + return 0; + } + out += r; + len -= r; + } + + return 1; +} + +void CRYPTO_init_sysrand(void) { + CRYPTO_once(rand_once_bss_get(), init_once); +} + +// CRYPTO_sysrand puts |requested| random bytes into |out|. +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + if (!fill_with_entropy(out, requested, /*block=*/1, /*seed=*/0)) { + perror("entropy fill failed"); + abort(); + } +} + +void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) { + if (!fill_with_entropy(out, requested, /*block=*/1, /*seed=*/1)) { + perror("entropy fill failed"); + abort(); + } +} + +int CRYPTO_sysrand_if_available(uint8_t *out, size_t requested) { + if (fill_with_entropy(out, requested, /*block=*/0, /*seed=*/0)) { + return 1; + } else if (errno == EAGAIN) { + OPENSSL_memset(out, 0, requested); + return 0; + } else { + perror("opportunistic entropy fill failed"); + abort(); + } +} + +#endif // OPENSSL_URANDOM diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S new file mode 100644 index 00000000..e81105b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S @@ -0,0 +1,70 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + +.globl CRYPTO_rdrand +.hidden CRYPTO_rdrand +.type CRYPTO_rdrand,@function +.align 16 +CRYPTO_rdrand: +.cfi_startproc + xorq %rax,%rax +.byte 72,15,199,242 + + adcq %rax,%rax + movq %rdx,0(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size CRYPTO_rdrand,.-CRYPTO_rdrand + + + + + +.globl CRYPTO_rdrand_multiple8_buf +.hidden CRYPTO_rdrand_multiple8_buf +.type CRYPTO_rdrand_multiple8_buf,@function +.align 16 +CRYPTO_rdrand_multiple8_buf: +.cfi_startproc + testq %rsi,%rsi + jz .Lout + movq $8,%rdx +.Lloop: +.byte 72,15,199,241 + jnc .Lerr + movq %rcx,0(%rdi) + addq %rdx,%rdi + subq %rdx,%rsi + jnz .Lloop +.Lout: + movq $1,%rax + .byte 0xf3,0xc3 +.Lerr: + xorq %rax,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size CRYPTO_rdrand_multiple8_buf,.-CRYPTO_rdrand_multiple8_buf +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S new file mode 100644 index 00000000..62733dc9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S @@ -0,0 +1,69 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + +.globl _CRYPTO_rdrand +.private_extern _CRYPTO_rdrand + +.p2align 4 +_CRYPTO_rdrand: + + xorq %rax,%rax +.byte 72,15,199,242 + + adcq %rax,%rax + movq %rdx,0(%rdi) + .byte 0xf3,0xc3 + + + + + + + +.globl _CRYPTO_rdrand_multiple8_buf +.private_extern _CRYPTO_rdrand_multiple8_buf + +.p2align 4 +_CRYPTO_rdrand_multiple8_buf: + + testq %rsi,%rsi + jz L$out + movq $8,%rdx +L$loop: +.byte 72,15,199,241 + jnc L$err + movq %rcx,0(%rdi) + addq %rdx,%rdi + subq %rdx,%rsi + jnz L$loop +L$out: + movq $1,%rax + .byte 0xf3,0xc3 +L$err: + xorq %rax,%rax + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c new file mode 100644 index 00000000..a5fff39e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c @@ -0,0 +1,243 @@ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; // The base blinding factor, Montgomery-encoded. + BIGNUM *Ai; // The inverse of the blinding factor, Montgomery-encoded. + unsigned counter; +}; + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +BN_BLINDING *BN_BLINDING_new(void) { + BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BN_BLINDING)); + + ret->A = BN_new(); + if (ret->A == NULL) { + goto err; + } + + ret->Ai = BN_new(); + if (ret->Ai == NULL) { + goto err; + } + + // The blinding values need to be created before this blinding can be used. + ret->counter = BN_BLINDING_COUNTER - 1; + + return ret; + +err: + BN_BLINDING_free(ret); + return NULL; +} + +void BN_BLINDING_free(BN_BLINDING *r) { + if (r == NULL) { + return; + } + + BN_free(r->A); + BN_free(r->Ai); + OPENSSL_free(r); +} + +void BN_BLINDING_invalidate(BN_BLINDING *b) { + b->counter = BN_BLINDING_COUNTER - 1; +} + +static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (++b->counter == BN_BLINDING_COUNTER) { + // re-create blinding parameters + if (!bn_blinding_create_param(b, e, mont, ctx)) { + goto err; + } + b->counter = 0; + } else { + if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) || + !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) { + goto err; + } + } + + return 1; + +err: + // |A| and |Ai| may be in an inconsistent state so they both need to be + // replaced the next time this blinding is used. Note that this is only + // sufficient because support for |BN_BLINDING_NO_UPDATE| and + // |BN_BLINDING_NO_RECREATE| was previously dropped. + b->counter = BN_BLINDING_COUNTER - 1; + + return 0; +} + +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + if (!bn_blinding_update(b, e, mont, ctx) || + !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) { + return 0; + } + + return 1; +} + +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont, + BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx); +} + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + int no_inverse; + if (!BN_rand_range_ex(b->A, 1, &mont->N) || + // Compute |b->A|^-1 in Montgomery form. Note |BN_from_montgomery| + + // |BN_mod_inverse_blinded| is equivalent to, but more efficient than, + // |BN_mod_inverse_blinded| + |BN_to_montgomery|. + // + // We do not retry if |b->A| has no inverse. Finding a non-invertible + // value of |b->A| is equivalent to factoring |mont->N|. There is + // negligible probability of stumbling on one at random. + !BN_from_montgomery(b->Ai, b->A, mont, ctx) || + !BN_mod_inverse_blinded(b->Ai, &no_inverse, b->Ai, mont, ctx) || + // TODO(davidben): |BN_mod_exp_mont| internally computes the result in + // Montgomery form. Save a pair of Montgomery reductions and a + // multiplication by returning that value directly. + !BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont) || + !BN_to_montgomery(b->A, b->A, mont, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h new file mode 100644 index 00000000..e7d4ff77 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h @@ -0,0 +1,153 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_RSA_INTERNAL_H +#define OPENSSL_HEADER_RSA_INTERNAL_H + +#include + +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Default implementations of RSA operations. + +const RSA_METHOD *RSA_default_method(void); + +size_t rsa_default_size(const RSA *rsa); +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +BN_BLINDING *BN_BLINDING_new(void); +void BN_BLINDING_free(BN_BLINDING *b); +void BN_BLINDING_invalidate(BN_BLINDING *b); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont_ctx, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, + BN_CTX *ctx); + + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len); + +// rsa_check_public_key checks that |rsa|'s public modulus and exponent are +// within DoS bounds. +int rsa_check_public_key(const RSA *rsa); + +// RSA_private_transform calls either the method-specific |private_transform| +// function (if given) or the generic one. See the comment for +// |private_transform| in |rsa_meth_st|. +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +// This constant is exported for test purposes. +extern const BN_ULONG kBoringSSLRSASqrtTwo[]; +extern const size_t kBoringSSLRSASqrtTwoLen; + + +// Functions that avoid self-tests. +// +// Self-tests need to call functions that don't try and ensure that the +// self-tests have passed. These functions, in turn, need to limit themselves +// to such functions too. +// +// These functions are the same as their public versions, but skip the self-test +// check. + +int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, RSA *rsa); + +int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, + unsigned digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RSA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c new file mode 100644 index 00000000..902cd69b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c @@ -0,0 +1,695 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define RSA_PKCS1_PADDING_SIZE 11 + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 9.2. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return 0; + } + + to[0] = 0; + to[1] = 1; + OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len); + to[to_len - from_len - 1] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + // See RFC 8017, section 9.2. This is part of signature verification and thus + // does not need to run in constant-time. + if (from_len < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + // Check the header. + if (from[0] != 0 || from[1] != 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); + return 0; + } + + // Scan over padded data, looking for the 00. + size_t pad; + for (pad = 2 /* header */; pad < from_len; pad++) { + if (from[pad] == 0x00) { + break; + } + + if (from[pad] != 0xff) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); + return 0; + } + } + + if (pad == from_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); + return 0; + } + + if (pad < 2 /* header */ + 8) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT); + return 0; + } + + // Skip over the 00. + pad++; + + if (from_len - pad > max_out) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + OPENSSL_memcpy(out, from + pad, from_len - pad); + *out_len = from_len - pad; + return 1; +} + +static int rand_nonzero(uint8_t *out, size_t len) { + if (!RAND_bytes(out, len)) { + return 0; + } + + for (size_t i = 0; i < len; i++) { + while (out[i] == 0) { + if (!RAND_bytes(out + i, 1)) { + return 0; + } + } + } + + return 1; +} + +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 7.2.1. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + to[0] = 0; + to[1] = 2; + + size_t padding_len = to_len - 3 - from_len; + if (!rand_nonzero(to + 2, padding_len)) { + return 0; + } + + to[2 + padding_len] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return 0; + } + + // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography + // Standard", section 7.2.2. + if (from_len < RSA_PKCS1_PADDING_SIZE) { + // |from| is zero-padded to the size of the RSA modulus, a public value, so + // this can be rejected in non-constant time. + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); + crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); + + crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; + for (size_t i = 2; i < from_len; i++) { + crypto_word_t equals0 = constant_time_is_zero_w(from[i]); + zero_index = + constant_time_select_w(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); + } + + // The input must begin with 00 02. + crypto_word_t valid_index = first_byte_is_zero; + valid_index &= second_byte_is_two; + + // We must have found the end of PS. + valid_index &= ~looking_for_index; + + // PS must be at least 8 bytes long, and it starts two bytes into |from|. + valid_index &= constant_time_ge_w(zero_index, 2 + 8); + + // Skip the zero byte. + zero_index++; + + // NOTE: Although this logic attempts to be constant time, the API contracts + // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + // impossible to completely avoid Bleichenbacher's attack. Consumers should + // use |RSA_PADDING_NONE| and perform the padding check in constant-time + // combined with a swap to a random session key or other mitigation. + CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index)); + CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index)); + + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { + // This shouldn't happen because this function is always called with + // |max_out| as the key size and |from_len| is bounded by the key size. + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; +} + +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len) { + if (from_len > to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (from_len < to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(to, from, from_len); + return 1; +} + +static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, + size_t seed_len, const EVP_MD *md) { + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + + size_t md_len = EVP_MD_size(md); + + for (uint32_t i = 0; len > 0; i++) { + uint8_t counter[4]; + counter[0] = (uint8_t)(i >> 24); + counter[1] = (uint8_t)(i >> 16); + counter[2] = (uint8_t)(i >> 8); + counter[3] = (uint8_t)i; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, seed, seed_len) || + !EVP_DigestUpdate(&ctx, counter, sizeof(counter))) { + goto err; + } + + if (md_len <= len) { + if (!EVP_DigestFinal_ex(&ctx, out, NULL)) { + goto err; + } + out += md_len; + len -= md_len; + } else { + uint8_t digest[EVP_MAX_MD_SIZE]; + if (!EVP_DigestFinal_ex(&ctx, digest, NULL)) { + goto err; + } + OPENSSL_memcpy(out, digest, len); + len = 0; + } + } + + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, + const EVP_MD *md, const EVP_MD *mgf1md) { + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + if (to_len < 2 * mdlen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + size_t emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + uint8_t *seed = to + 1; + uint8_t *db = to + mdlen + 1; + + if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { + return 0; + } + OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); + if (!RAND_bytes(seed, mdlen)) { + return 0; + } + + uint8_t *dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < emlen - mdlen; i++) { + db[i] ^= dbmask[i]; + } + + uint8_t seedmask[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= seedmask[i]; + } + ret = 1; + +out: + OPENSSL_free(dbmask); + return ret; +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; + + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + // The encoded message is one byte smaller than the modulus to ensure that it + // doesn't end up greater than the modulus. Thus there's an extra "+1" here + // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. + if (from_len < 1 + 2*mdlen + 1) { + // 'from_len' is the length of the modulus, i.e. does not depend on the + // particular ciphertext. + goto decoding_err; + } + + size_t dblen = from_len - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + + uint8_t seed[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= maskedseed[i]; + } + + if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < dblen; i++) { + db[i] ^= maskeddb[i]; + } + + uint8_t phash[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { + goto err; + } + + crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_w(from[0]); + + crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; + size_t one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + crypto_word_t equals1 = constant_time_eq_w(db[i], 1); + crypto_word_t equals0 = constant_time_eq_w(db[i], 0); + one_index = + constant_time_select_w(looking_for_one_byte & equals1, i, one_index); + looking_for_one_byte = + constant_time_select_w(equals1, 0, looking_for_one_byte); + bad |= looking_for_one_byte & ~equals0; + } + + bad |= looking_for_one_byte; + + if (bad) { + goto decoding_err; + } + + one_index++; + size_t mlen = dblen - one_index; + if (max_out < mlen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; + OPENSSL_free(db); + return 1; + +decoding_err: + // to avoid chosen ciphertext attacks, the error message should not reveal + // which kind of decoding error happened + OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); + err: + OPENSSL_free(db); + return 0; +} + +static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen) { + int i; + int ret = 0; + int maskedDBLen, MSBits, emLen; + size_t hLen; + const uint8_t *H; + uint8_t *DB = NULL; + EVP_MD_CTX ctx; + uint8_t H_[EVP_MAX_MD_SIZE]; + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + // Negative sLen has special meanings: + // -1 sLen == hLen + // -2 salt length is autorecovered from signature + // -N reserved + if (sLen == -1) { + sLen = hLen; + } else if (sLen == -2) { + sLen = -2; + } else if (sLen < -2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < (int)hLen + 2 || emLen < ((int)hLen + sLen + 2)) { + // sLen can be small negative + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (!DB) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) { + goto err; + } + for (i = 0; i < maskedDBLen; i++) { + DB[i] ^= EM[i]; + } + if (MSBits) { + DB[0] &= 0xFF >> (8 - MSBits); + } + for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) { + ; + } + if (DB[i++] != 0x1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || + !EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) || + !EVP_DigestUpdate(&ctx, mHash, hLen) || + !EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i) || + !EVP_DigestFinal_ex(&ctx, H_, NULL)) { + goto err; + } + if (OPENSSL_memcmp(H_, H, hLen)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + ret = 0; + } else { + ret = 1; + } + +err: + OPENSSL_free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLenRequested) { + int ret = 0; + size_t maskedDBLen, MSBits, emLen; + size_t hLen; + unsigned char *H, *salt = NULL, *p; + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + if (BN_is_zero(rsa->n)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + assert(emLen >= 1); + *EM++ = 0; + emLen--; + } + + if (emLen < hLen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + + // Negative sLenRequested has special meanings: + // -1 sLen == hLen + // -2 salt length is maximized + // -N reserved + size_t sLen; + if (sLenRequested == -1) { + sLen = hLen; + } else if (sLenRequested == -2) { + sLen = emLen - hLen - 2; + } else if (sLenRequested < 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } else { + sLen = (size_t)sLenRequested; + } + + if (emLen - hLen - 2 < sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (!salt) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!RAND_bytes(salt, sLen)) { + goto err; + } + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + int digest_ok = EVP_DigestInit_ex(&ctx, Hash, NULL) && + EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) && + EVP_DigestUpdate(&ctx, mHash, hLen) && + EVP_DigestUpdate(&ctx, salt, sLen) && + EVP_DigestFinal_ex(&ctx, H, NULL); + EVP_MD_CTX_cleanup(&ctx); + if (!digest_ok) { + goto err; + } + + // Generate dbMask in place then perform XOR on it + if (!PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) { + goto err; + } + + p = EM; + + // Initial PS XORs with all zeroes which is a NOP so just update + // pointer. Note from a test above this value is guaranteed to + // be non-negative. + p += emLen - sLen - hLen - 2; + *p++ ^= 0x1; + if (sLen > 0) { + for (size_t i = 0; i < sLen; i++) { + *p++ ^= salt[i]; + } + } + if (MSBits) { + EM[0] &= 0xFF >> (8 - MSBits); + } + + // H is already in place so just set final 0xbc + + EM[emLen - 1] = 0xbc; + + ret = 1; + +err: + OPENSSL_free(salt); + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c new file mode 100644 index 00000000..25a6628c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c @@ -0,0 +1,959 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" + + +// RSA_R_BLOCK_TYPE_IS_NOT_02 is part of the legacy SSLv23 padding scheme. +// Cryptography.io depends on this error code. +OPENSSL_DECLARE_ERROR_REASON(RSA, BLOCK_TYPE_IS_NOT_02) + +DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class) + +RSA *RSA_new(void) { return RSA_new_method(NULL); } + +RSA *RSA_new_method(const ENGINE *engine) { + RSA *rsa = OPENSSL_malloc(sizeof(RSA)); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(rsa, 0, sizeof(RSA)); + + if (engine) { + rsa->meth = ENGINE_get_RSA_method(engine); + } + + if (rsa->meth == NULL) { + rsa->meth = (RSA_METHOD *) RSA_default_method(); + } + METHOD_ref(rsa->meth); + + rsa->references = 1; + rsa->flags = rsa->meth->flags; + CRYPTO_MUTEX_init(&rsa->lock); + CRYPTO_new_ex_data(&rsa->ex_data); + + if (rsa->meth->init && !rsa->meth->init(rsa)) { + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + CRYPTO_MUTEX_cleanup(&rsa->lock); + METHOD_unref(rsa->meth); + OPENSSL_free(rsa); + return NULL; + } + + return rsa; +} + +void RSA_free(RSA *rsa) { + unsigned u; + + if (rsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) { + return; + } + + if (rsa->meth->finish) { + rsa->meth->finish(rsa); + } + METHOD_unref(rsa->meth); + + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + + BN_free(rsa->n); + BN_free(rsa->e); + BN_free(rsa->d); + BN_free(rsa->p); + BN_free(rsa->q); + BN_free(rsa->dmp1); + BN_free(rsa->dmq1); + BN_free(rsa->iqmp); + BN_MONT_CTX_free(rsa->mont_n); + BN_MONT_CTX_free(rsa->mont_p); + BN_MONT_CTX_free(rsa->mont_q); + BN_free(rsa->d_fixed); + BN_free(rsa->dmp1_fixed); + BN_free(rsa->dmq1_fixed); + BN_free(rsa->inv_small_mod_large_mont); + for (u = 0; u < rsa->num_blindings; u++) { + BN_BLINDING_free(rsa->blindings[u]); + } + OPENSSL_free(rsa->blindings); + OPENSSL_free(rsa->blindings_inuse); + CRYPTO_MUTEX_cleanup(&rsa->lock); + OPENSSL_free(rsa); +} + +int RSA_up_ref(RSA *rsa) { + CRYPTO_refcount_inc(&rsa->references); + return 1; +} + +unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); } + +const BIGNUM *RSA_get0_n(const RSA *rsa) { return rsa->n; } + +const BIGNUM *RSA_get0_e(const RSA *rsa) { return rsa->e; } + +const BIGNUM *RSA_get0_d(const RSA *rsa) { return rsa->d; } + +const BIGNUM *RSA_get0_p(const RSA *rsa) { return rsa->p; } + +const BIGNUM *RSA_get0_q(const RSA *rsa) { return rsa->q; } + +const BIGNUM *RSA_get0_dmp1(const RSA *rsa) { return rsa->dmp1; } + +const BIGNUM *RSA_get0_dmq1(const RSA *rsa) { return rsa->dmq1; } + +const BIGNUM *RSA_get0_iqmp(const RSA *rsa) { return rsa->iqmp; } + +void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, + const BIGNUM **out_d) { + if (out_n != NULL) { + *out_n = rsa->n; + } + if (out_e != NULL) { + *out_e = rsa->e; + } + if (out_d != NULL) { + *out_d = rsa->d; + } +} + +void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q) { + if (out_p != NULL) { + *out_p = rsa->p; + } + if (out_q != NULL) { + *out_q = rsa->q; + } +} + +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { + // We do not support the id-RSASSA-PSS key encoding. If we add support later, + // the |maskHash| field should be filled in for OpenSSL compatibility. + return NULL; +} + +void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { + if (out_dmp1 != NULL) { + *out_dmp1 = rsa->dmp1; + } + if (out_dmq1 != NULL) { + *out_dmq1 = rsa->dmq1; + } + if (out_iqmp != NULL) { + *out_iqmp = rsa->iqmp; + } +} + +int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + if ((rsa->n == NULL && n == NULL) || + (rsa->e == NULL && e == NULL)) { + return 0; + } + + if (n != NULL) { + BN_free(rsa->n); + rsa->n = n; + } + if (e != NULL) { + BN_free(rsa->e); + rsa->e = e; + } + if (d != NULL) { + BN_free(rsa->d); + rsa->d = d; + } + + return 1; +} + +int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { + if ((rsa->p == NULL && p == NULL) || + (rsa->q == NULL && q == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(rsa->p); + rsa->p = p; + } + if (q != NULL) { + BN_free(rsa->q); + rsa->q = q; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { + if ((rsa->dmp1 == NULL && dmp1 == NULL) || + (rsa->dmq1 == NULL && dmq1 == NULL) || + (rsa->iqmp == NULL && iqmp == NULL)) { + return 0; + } + + if (dmp1 != NULL) { + BN_free(rsa->dmp1); + rsa->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(rsa->dmq1); + rsa->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(rsa->iqmp); + rsa->iqmp = iqmp; + } + + return 1; +} + +int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { + if (rsa->meth->sign_raw) { + return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + return rsa_sign_raw_no_self_test(rsa, out_len, out, max_out, in, in_len, + padding); +} + +int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->decrypt) { + return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +unsigned RSA_size(const RSA *rsa) { + if (rsa->meth->size) { + return rsa->meth->size(rsa); + } + + return rsa_default_size(rsa); +} + +int RSA_is_opaque(const RSA *rsa) { + return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); +} + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl, + argp, free_func)) { + return -1; + } + return index; +} + +int RSA_set_ex_data(RSA *rsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg); +} + +void *RSA_get_ex_data(const RSA *rsa, int idx) { + return CRYPTO_get_ex_data(&rsa->ex_data, idx); +} + +// SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's +// the length of an MD5 and SHA1 hash. +static const unsigned SSL_SIG_LENGTH = 36; + +// pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is +// to be signed with PKCS#1. +struct pkcs1_sig_prefix { + // nid identifies the hash function. + int nid; + // hash_len is the expected length of the hash function. + uint8_t hash_len; + // len is the number of bytes of |bytes| which are valid. + uint8_t len; + // bytes contains the DER bytes. + uint8_t bytes[19]; +}; + +// kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with +// different hash functions. +static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { + { + NID_md5, + MD5_DIGEST_LENGTH, + 18, + {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}, + }, + { + NID_sha1, + SHA_DIGEST_LENGTH, + 15, + {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14}, + }, + { + NID_sha224, + SHA224_DIGEST_LENGTH, + 19, + {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, + }, + { + NID_sha256, + SHA256_DIGEST_LENGTH, + 19, + {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, + }, + { + NID_sha384, + SHA384_DIGEST_LENGTH, + 19, + {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, + }, + { + NID_sha512, + SHA512_DIGEST_LENGTH, + 19, + {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, + }, + { + NID_undef, 0, 0, {0}, + }, +}; + +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *digest, + size_t digest_len) { + unsigned i; + + if (hash_nid == NID_md5_sha1) { + // Special case: SSL signature, just check the length. + if (digest_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + *out_msg = (uint8_t *)digest; + *out_msg_len = SSL_SIG_LENGTH; + *is_alloced = 0; + return 1; + } + + for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; + if (sig_prefix->nid != hash_nid) { + continue; + } + + if (digest_len != sig_prefix->hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + const uint8_t* prefix = sig_prefix->bytes; + unsigned prefix_len = sig_prefix->len; + unsigned signed_msg_len; + uint8_t *signed_msg; + + signed_msg_len = prefix_len + digest_len; + if (signed_msg_len < prefix_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG); + return 0; + } + + signed_msg = OPENSSL_malloc(signed_msg_len); + if (!signed_msg) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(signed_msg, prefix, prefix_len); + OPENSSL_memcpy(signed_msg + prefix_len, digest, digest_len); + + *out_msg = signed_msg; + *out_msg_len = signed_msg_len; + *is_alloced = 1; + + return 1; + } + + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; +} + +int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, + unsigned digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa) { + const unsigned rsa_size = RSA_size(rsa); + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0; + int signed_msg_is_alloced = 0; + size_t size_t_out_len; + + if (rsa->meth->sign) { + return rsa->meth->sign(hash_nid, digest, digest_len, out, out_len, rsa); + } + + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, digest, + digest_len) || + !rsa_sign_raw_no_self_test(rsa, &size_t_out_len, out, rsa_size, + signed_msg, signed_msg_len, + RSA_PKCS1_PADDING)) { + goto err; + } + + *out_len = size_t_out_len; + ret = 1; + +err: + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_sign(int hash_nid, const uint8_t *digest, unsigned digest_len, + uint8_t *out, unsigned *out_len, RSA *rsa) { + boringssl_ensure_rsa_self_test(); + + return rsa_sign_no_self_test(hash_nid, digest, digest_len, out, out_len, rsa); +} + +int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *digest, size_t digest_len, + const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len) { + if (digest_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t padded_len = RSA_size(rsa); + uint8_t *padded = OPENSSL_malloc(padded_len); + if (padded == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, digest, md, mgf1_md, + salt_len) && + RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len, + RSA_NO_PADDING); + OPENSSL_free(padded); + return ret; +} + +int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, RSA *rsa) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const size_t rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0, len; + int signed_msg_is_alloced = 0; + + if (hash_nid == NID_md5_sha1 && digest_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (!buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!rsa_verify_raw_no_self_test(rsa, &len, buf, rsa_size, sig, sig_len, + RSA_PKCS1_PADDING) || + !RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, digest, + digest_len)) { + goto out; + } + + // Check that no other information follows the hash value (FIPS 186-4 Section + // 5.5) and it matches the expected hash. + if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + goto out; + } + + ret = 1; + +out: + OPENSSL_free(buf); + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, RSA *rsa) { + boringssl_ensure_rsa_self_test(); + return rsa_verify_no_self_test(hash_nid, digest, digest_len, sig, sig_len, + rsa); +} + +int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len, + const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len) { + if (digest_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t em_len = RSA_size(rsa); + uint8_t *em = OPENSSL_malloc(em_len); + if (em == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) { + goto err; + } + + if (em_len != RSA_size(rsa)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, digest, md, mgf1_md, em, salt_len); + +err: + OPENSSL_free(em); + return ret; +} + +static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv, + const BIGNUM *m, unsigned m_min_bits, + BN_CTX *ctx) { + if (BN_is_negative(ainv) || BN_cmp(ainv, m) >= 0) { + *out_ok = 0; + return 1; + } + + // Note |bn_mul_consttime| and |bn_div_consttime| do not scale linearly, but + // checking |ainv| is in range bounds the running time, assuming |m|'s bounds + // were checked by the caller. + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ret = tmp != NULL && + bn_mul_consttime(tmp, a, ainv, ctx) && + bn_div_consttime(NULL, tmp, tmp, m, m_min_bits, ctx); + if (ret) { + *out_ok = BN_is_one(tmp); + } + BN_CTX_end(ctx); + return ret; +} + +int RSA_check_key(const RSA *key) { + // TODO(davidben): RSA key initialization is spread across + // |rsa_check_public_key|, |RSA_check_key|, |freeze_private_key|, and + // |BN_MONT_CTX_set_locked| as a result of API issues. See + // https://crbug.com/boringssl/316. As a result, we inconsistently check RSA + // invariants. We should fix this and integrate that logic. + + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + return 1; + } + + if (!rsa_check_public_key(key)) { + return 0; + } + + if ((key->p != NULL) != (key->q != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); + return 0; + } + + // |key->d| must be bounded by |key->n|. This ensures bounds on |RSA_bits| + // translate to bounds on the running time of private key operations. + if (key->d != NULL && + (BN_is_negative(key->d) || BN_cmp(key->d, key->n) >= 0)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_OUT_OF_RANGE); + return 0; + } + + if (key->d == NULL || key->p == NULL) { + // For a public key, or without p and q, there's nothing that can be + // checked. + return 1; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BIGNUM tmp, de, pm1, qm1, dmp1, dmq1; + int ok = 0; + BN_init(&tmp); + BN_init(&de); + BN_init(&pm1); + BN_init(&qm1); + BN_init(&dmp1); + BN_init(&dmq1); + + // Check that p * q == n. Before we multiply, we check that p and q are in + // bounds, to avoid a DoS vector in |bn_mul_consttime| below. Note that + // n was bound by |rsa_check_public_key|. + if (BN_is_negative(key->p) || BN_cmp(key->p, key->n) >= 0 || + BN_is_negative(key->q) || BN_cmp(key->q, key->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); + goto out; + } + if (!bn_mul_consttime(&tmp, key->p, key->q, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + if (BN_cmp(&tmp, key->n) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); + goto out; + } + + // d must be an inverse of e mod the Carmichael totient, lcm(p-1, q-1), but it + // may be unreduced because other implementations use the Euler totient. We + // simply check that d * e is one mod p-1 and mod q-1. Note d and e were bound + // by earlier checks in this function. + if (!bn_usub_consttime(&pm1, key->p, BN_value_one()) || + !bn_usub_consttime(&qm1, key->q, BN_value_one())) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + const unsigned pm1_bits = BN_num_bits(&pm1); + const unsigned qm1_bits = BN_num_bits(&qm1); + if (!bn_mul_consttime(&de, key->d, key->e, ctx) || + !bn_div_consttime(NULL, &tmp, &de, &pm1, pm1_bits, ctx) || + !bn_div_consttime(NULL, &de, &de, &qm1, qm1_bits, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (!BN_is_one(&tmp) || !BN_is_one(&de)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); + goto out; + } + + int has_crt_values = key->dmp1 != NULL; + if (has_crt_values != (key->dmq1 != NULL) || + has_crt_values != (key->iqmp != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); + goto out; + } + + if (has_crt_values) { + int dmp1_ok, dmq1_ok, iqmp_ok; + if (!check_mod_inverse(&dmp1_ok, key->e, key->dmp1, &pm1, pm1_bits, ctx) || + !check_mod_inverse(&dmq1_ok, key->e, key->dmq1, &qm1, qm1_bits, ctx) || + // |p| is odd, so |pm1| and |p| have the same bit width. If they didn't, + // we only need a lower bound anyway. + !check_mod_inverse(&iqmp_ok, key->q, key->iqmp, key->p, pm1_bits, + ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (!dmp1_ok || !dmq1_ok || !iqmp_ok) { + OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); + goto out; + } + } + + ok = 1; + +out: + BN_free(&tmp); + BN_free(&de); + BN_free(&pm1); + BN_free(&qm1); + BN_free(&dmp1); + BN_free(&dmq1); + BN_CTX_free(ctx); + + return ok; +} + + +// This is the product of the 132 smallest odd primes, from 3 to 751. +static const BN_ULONG kSmallFactorsLimbs[] = { + TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f), + TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b), + TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871), + TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3), + TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893), + TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e), + TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea), + TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727), + 0x000017b1 +}; + +DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { + out->d = (BN_ULONG *) kSmallFactorsLimbs; + out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs); + out->dmax = out->width; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +int RSA_check_fips(RSA *key) { + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!RSA_check_key(key)) { + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BIGNUM small_gcd; + BN_init(&small_gcd); + + int ret = 1; + + // Perform partial public key validation of RSA keys (SP 800-89 5.3.3). + // Although this is not for primality testing, SP 800-89 cites an RSA + // primality testing algorithm, so we use |BN_prime_checks_for_generation| to + // match. This is only a plausibility test and we expect the value to be + // composite, so too few iterations will cause us to reject the key, not use + // an implausible one. + enum bn_primality_result_t primality_result; + if (BN_num_bits(key->e) <= 16 || + BN_num_bits(key->e) > 256 || + !BN_is_odd(key->n) || + !BN_is_odd(key->e) || + !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) || + !BN_is_one(&small_gcd) || + !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n, + BN_prime_checks_for_generation, + ctx, NULL) || + primality_result != bn_non_prime_power_composite) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + ret = 0; + } + + BN_free(&small_gcd); + BN_CTX_free(ctx); + + if (!ret || key->d == NULL || key->p == NULL) { + // On a failure or on only a public key, there's nothing else can be + // checked. + return ret; + } + + // FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG, + // section 9.9, it is not known whether |rsa| will be used for signing or + // encryption, so either pair-wise consistency self-test is acceptable. We + // perform a signing test. + uint8_t data[32] = {0}; + unsigned sig_len = RSA_size(key); + uint8_t *sig = OPENSSL_malloc(sig_len); + if (sig == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + goto cleanup; + } + if (boringssl_fips_break_test("RSA_PWCT")) { + data[0] = ~data[0]; + } + if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + } + +cleanup: + OPENSSL_free(sig); + + return ret; +} + +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->meth->private_transform) { + return rsa->meth->private_transform(rsa, out, in, len); + } + + return rsa_default_private_transform(rsa, out, in, len); +} + +int RSA_flags(const RSA *rsa) { return rsa->flags; } + +int RSA_test_flags(const RSA *rsa, int flags) { return rsa->flags & flags; } + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c new file mode 100644 index 00000000..543c6c5e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c @@ -0,0 +1,1431 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" +#include "../delocate.h" +#include "../rand/fork_detect.h" + + +int rsa_check_public_key(const RSA *rsa) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + unsigned n_bits = BN_num_bits(rsa->n); + if (n_bits > 16 * 1024) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + + // Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as + // the limit based on the recommendations in [1] and [2]. Windows CryptoAPI + // doesn't support values larger than 32 bits [3], so it is unlikely that + // exponents larger than 32 bits are being used for anything Windows commonly + // does. + // + // [1] https://www.imperialviolet.org/2012/03/16/rsae.html + // [2] https://www.imperialviolet.org/2012/03/17/rsados.html + // [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + static const unsigned kMaxExponentBits = 33; + unsigned e_bits = BN_num_bits(rsa->e); + if (e_bits > kMaxExponentBits || + // Additionally reject e = 1 or even e. e must be odd to be relatively + // prime with phi(n). + e_bits < 2 || + !BN_is_odd(rsa->e)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + // Verify |n > e|. Comparing |n_bits| to |kMaxExponentBits| is a small + // shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits| + // is much smaller than the minimum RSA key size that any application should + // accept. + if (n_bits <= kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + assert(BN_ucmp(rsa->n, rsa->e) > 0); + + return 1; +} + +static int ensure_fixed_copy(BIGNUM **out, const BIGNUM *in, int width) { + if (*out != NULL) { + return 1; + } + BIGNUM *copy = BN_dup(in); + if (copy == NULL || + !bn_resize_words(copy, width)) { + BN_free(copy); + return 0; + } + *out = copy; + CONSTTIME_SECRET(copy->d, sizeof(BN_ULONG) * width); + + return 1; +} + +// freeze_private_key finishes initializing |rsa|'s private key components. +// After this function has returned, |rsa| may not be changed. This is needed +// because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified +// it wrong (see https://github.com/openssl/openssl/issues/5158). +static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { + CRYPTO_MUTEX_lock_read(&rsa->lock); + int frozen = rsa->private_key_frozen; + CRYPTO_MUTEX_unlock_read(&rsa->lock); + if (frozen) { + return 1; + } + + int ret = 0; + CRYPTO_MUTEX_lock_write(&rsa->lock); + if (rsa->private_key_frozen) { + ret = 1; + goto err; + } + + // Pre-compute various intermediate values, as well as copies of private + // exponents with correct widths. Note that other threads may concurrently + // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate + // copies. We use |mont_n->N|, |mont_p->N|, and |mont_q->N| as copies of |n|, + // |p|, and |q| with the correct minimal widths. + + if (rsa->mont_n == NULL) { + rsa->mont_n = BN_MONT_CTX_new_for_modulus(rsa->n, ctx); + if (rsa->mont_n == NULL) { + goto err; + } + } + const BIGNUM *n_fixed = &rsa->mont_n->N; + + // The only public upper-bound of |rsa->d| is the bit length of |rsa->n|. The + // ASN.1 serialization of RSA private keys unfortunately leaks the byte length + // of |rsa->d|, but normalize it so we only leak it once, rather than per + // operation. + if (rsa->d != NULL && + !ensure_fixed_copy(&rsa->d_fixed, rsa->d, n_fixed->width)) { + goto err; + } + + if (rsa->p != NULL && rsa->q != NULL) { + // TODO: p and q are also CONSTTIME_SECRET but not yet marked as such + // because the Montgomery code does things like test whether or not values + // are zero. So the secret marking probably needs to happen inside that + // code. + + if (rsa->mont_p == NULL) { + rsa->mont_p = BN_MONT_CTX_new_consttime(rsa->p, ctx); + if (rsa->mont_p == NULL) { + goto err; + } + } + const BIGNUM *p_fixed = &rsa->mont_p->N; + + if (rsa->mont_q == NULL) { + rsa->mont_q = BN_MONT_CTX_new_consttime(rsa->q, ctx); + if (rsa->mont_q == NULL) { + goto err; + } + } + const BIGNUM *q_fixed = &rsa->mont_q->N; + + if (rsa->dmp1 != NULL && rsa->dmq1 != NULL) { + // Key generation relies on this function to compute |iqmp|. + if (rsa->iqmp == NULL) { + BIGNUM *iqmp = BN_new(); + if (iqmp == NULL || + !bn_mod_inverse_secret_prime(iqmp, rsa->q, rsa->p, ctx, + rsa->mont_p)) { + BN_free(iqmp); + goto err; + } + rsa->iqmp = iqmp; + } + + // CRT components are only publicly bounded by their corresponding + // moduli's bit lengths. |rsa->iqmp| is unused outside of this one-time + // setup, so we do not compute a fixed-width version of it. + if (!ensure_fixed_copy(&rsa->dmp1_fixed, rsa->dmp1, p_fixed->width) || + !ensure_fixed_copy(&rsa->dmq1_fixed, rsa->dmq1, q_fixed->width)) { + goto err; + } + + // Compute |inv_small_mod_large_mont|. Note that it is always modulo the + // larger prime, independent of what is stored in |rsa->iqmp|. + if (rsa->inv_small_mod_large_mont == NULL) { + BIGNUM *inv_small_mod_large_mont = BN_new(); + int ok; + if (BN_cmp(rsa->p, rsa->q) < 0) { + ok = inv_small_mod_large_mont != NULL && + bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p, + rsa->q, ctx, rsa->mont_q) && + BN_to_montgomery(inv_small_mod_large_mont, + inv_small_mod_large_mont, rsa->mont_q, ctx); + } else { + ok = inv_small_mod_large_mont != NULL && + BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp, + rsa->mont_p, ctx); + } + if (!ok) { + BN_free(inv_small_mod_large_mont); + goto err; + } + rsa->inv_small_mod_large_mont = inv_small_mod_large_mont; + CONSTTIME_SECRET( + rsa->inv_small_mod_large_mont->d, + sizeof(BN_ULONG) * rsa->inv_small_mod_large_mont->width); + } + } + } + + rsa->private_key_frozen = 1; + ret = 1; + +err: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; +} + +size_t rsa_default_size(const RSA *rsa) { + return BN_num_bytes(rsa->n); +} + +int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + + if (!rsa_check_public_key(rsa)) { + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + uint8_t *buf = NULL; + BN_CTX *ctx = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + buf = OPENSSL_malloc(rsa_size); + if (!f || !result || !buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, + NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (BN_bin2bn(buf, rsa_size, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // usually the padding functions would catch this + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + // put in leading 0 bytes if the number is less than the length of the + // modulus + if (!BN_bn2bin_padded(out, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + OPENSSL_free(buf); + + return ret; +} + +// MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per +// RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and +// destroyed as needed. +#if defined(OPENSSL_TSAN) +// Smaller under TSAN so that the edge case can be hit with fewer threads. +#define MAX_BLINDINGS_PER_RSA 2 +#else +#define MAX_BLINDINGS_PER_RSA 1024 +#endif + +// rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by +// allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If +// none are free, the cache will be extended by a extra element and the new +// BN_BLINDING is returned. +// +// On success, the index of the assigned BN_BLINDING is written to +// |*index_used| and must be passed to |rsa_blinding_release| when finished. +static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, + BN_CTX *ctx) { + assert(ctx != NULL); + assert(rsa->mont_n != NULL); + + BN_BLINDING *ret = NULL; + const uint64_t fork_generation = CRYPTO_get_fork_generation(); + CRYPTO_MUTEX_lock_write(&rsa->lock); + + // Wipe the blinding cache on |fork|. + if (rsa->blinding_fork_generation != fork_generation) { + for (unsigned i = 0; i < rsa->num_blindings; i++) { + // The inuse flag must be zero unless we were forked from a + // multi-threaded process, in which case calling back into BoringSSL is + // forbidden. + assert(rsa->blindings_inuse[i] == 0); + BN_BLINDING_invalidate(rsa->blindings[i]); + } + rsa->blinding_fork_generation = fork_generation; + } + + uint8_t *const free_inuse_flag = + OPENSSL_memchr(rsa->blindings_inuse, 0, rsa->num_blindings); + if (free_inuse_flag != NULL) { + *free_inuse_flag = 1; + *index_used = free_inuse_flag - rsa->blindings_inuse; + ret = rsa->blindings[*index_used]; + goto out; + } + + if (rsa->num_blindings >= MAX_BLINDINGS_PER_RSA) { + // No |BN_BLINDING| is free and nor can the cache be extended. This index + // value is magic and indicates to |rsa_blinding_release| that a + // |BN_BLINDING| was not inserted into the array. + *index_used = MAX_BLINDINGS_PER_RSA; + ret = BN_BLINDING_new(); + goto out; + } + + // Double the length of the cache. + OPENSSL_STATIC_ASSERT(MAX_BLINDINGS_PER_RSA < UINT_MAX / 2, + "MAX_BLINDINGS_PER_RSA too large"); + unsigned new_num_blindings = rsa->num_blindings * 2; + if (new_num_blindings == 0) { + new_num_blindings = 1; + } + if (new_num_blindings > MAX_BLINDINGS_PER_RSA) { + new_num_blindings = MAX_BLINDINGS_PER_RSA; + } + assert(new_num_blindings > rsa->num_blindings); + + OPENSSL_STATIC_ASSERT( + MAX_BLINDINGS_PER_RSA < UINT_MAX / sizeof(BN_BLINDING *), + "MAX_BLINDINGS_PER_RSA too large"); + BN_BLINDING **new_blindings = + OPENSSL_malloc(sizeof(BN_BLINDING *) * new_num_blindings); + uint8_t *new_blindings_inuse = OPENSSL_malloc(new_num_blindings); + if (new_blindings == NULL || new_blindings_inuse == NULL) { + goto err; + } + + OPENSSL_memcpy(new_blindings, rsa->blindings, + sizeof(BN_BLINDING *) * rsa->num_blindings); + OPENSSL_memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); + + for (unsigned i = rsa->num_blindings; i < new_num_blindings; i++) { + new_blindings[i] = BN_BLINDING_new(); + if (new_blindings[i] == NULL) { + for (unsigned j = rsa->num_blindings; j < i; j++) { + BN_BLINDING_free(new_blindings[j]); + } + goto err; + } + } + memset(&new_blindings_inuse[rsa->num_blindings], 0, + new_num_blindings - rsa->num_blindings); + + new_blindings_inuse[rsa->num_blindings] = 1; + *index_used = rsa->num_blindings; + assert(*index_used != MAX_BLINDINGS_PER_RSA); + ret = new_blindings[rsa->num_blindings]; + + OPENSSL_free(rsa->blindings); + rsa->blindings = new_blindings; + OPENSSL_free(rsa->blindings_inuse); + rsa->blindings_inuse = new_blindings_inuse; + rsa->num_blindings = new_num_blindings; + + goto out; + +err: + OPENSSL_free(new_blindings_inuse); + OPENSSL_free(new_blindings); + +out: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; +} + +// rsa_blinding_release marks the cached BN_BLINDING at the given index as free +// for other threads to use. +static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding, + unsigned blinding_index) { + if (blinding_index == MAX_BLINDINGS_PER_RSA) { + // This blinding wasn't cached. + BN_BLINDING_free(blinding); + return; + } + + CRYPTO_MUTEX_lock_write(&rsa->lock); + rsa->blindings_inuse[blinding_index] = 0; + CRYPTO_MUTEX_unlock_write(&rsa->lock); +} + +// signing +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, rsa_size, in, in_len); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (!RSA_private_transform(rsa, out, buf, rsa_size)) { + goto err; + } + + CONSTTIME_DECLASSIFY(out, rsa_size); + *out_len = rsa_size; + ret = 1; + +err: + OPENSSL_free(buf); + + return ret; +} + +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + goto err; + } + + if (!RSA_private_transform(rsa, buf, in, rsa_size)) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + *out_len = rsa_size; + ret = 1; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + CONSTTIME_DECLASSIFY(&ret, sizeof(ret)); + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + } else { + CONSTTIME_DECLASSIFY(out, *out_len); + } + +err: + if (padding != RSA_NO_PADDING) { + OPENSSL_free(buf); + } + + return ret; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + +int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { + if (!rsa_check_public_key(rsa)) { + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + + int ret = 0; + uint8_t *buf = NULL; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (BN_bin2bn(in, in_len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + if (!BN_bn2bin_padded(buf, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_1(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_NO_PADDING: + ret = 1; + *out_len = rsa_size; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + goto err; + } + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (buf != out) { + OPENSSL_free(buf); + } + return ret; +} + +int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + return rsa_verify_raw_no_self_test(rsa, out_len, out, max_out, in, in_len, + padding); +} + +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->n == NULL || rsa->d == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + BIGNUM *f, *result; + BN_CTX *ctx = NULL; + unsigned blinding_index = 0; + BN_BLINDING *blinding = NULL; + int ret = 0; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_bin2bn(in, len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // Usually the padding functions would catch this. + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + const int do_blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0; + + if (rsa->e == NULL && do_blinding) { + // We cannot do blinding or verification without |e|, and continuing without + // those countermeasures is dangerous. However, the Java/Android RSA API + // requires support for keys where only |d| and |n| (and not |e|) are known. + // The callers that require that bad behavior set |RSA_FLAG_NO_BLINDING|. + OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + + if (do_blinding) { + blinding = rsa_blinding_get(rsa, &blinding_index, ctx); + if (blinding == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) { + goto err; + } + } + + if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL && + rsa->dmq1 != NULL && rsa->iqmp != NULL && + // Require that we can reduce |f| by |rsa->p| and |rsa->q| in constant + // time, which requires primes be the same size, rounded to the Montgomery + // coefficient. (See |mod_montgomery|.) This is not required by RFC 8017, + // but it is true for keys generated by us and all common implementations. + bn_less_than_montgomery_R(rsa->q, rsa->mont_p) && + bn_less_than_montgomery_R(rsa->p, rsa->mont_q)) { + if (!mod_exp(result, f, rsa, ctx)) { + goto err; + } + } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, ctx, + rsa->mont_n)) { + goto err; + } + + // Verify the result to protect against fault attacks as described in the + // 1997 paper "On the Importance of Checking Cryptographic Protocols for + // Faults" by Dan Boneh, Richard A. DeMillo, and Richard J. Lipton. Some + // implementations do this only when the CRT is used, but we do it in all + // cases. Section 6 of the aforementioned paper describes an attack that + // works when the CRT isn't used. That attack is much less likely to succeed + // than the CRT attack, but there have likely been improvements since 1997. + // + // This check is cheap assuming |e| is small; it almost always is. + if (rsa->e != NULL) { + BIGNUM *vrfy = BN_CTX_get(ctx); + if (vrfy == NULL || + !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || + !BN_equal_consttime(vrfy, f)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + } + + if (do_blinding && + !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) { + goto err; + } + + // The computation should have left |result| as a maximally-wide number, so + // that it and serializing does not leak information about the magnitude of + // the result. + // + // See Falko Strenzke, "Manger's Attack revisited", ICICS 2010. + assert(result->width == rsa->mont_n->N.width); + if (!BN_bn2bin_padded(out, len, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (blinding != NULL) { + rsa_blinding_release(rsa, blinding, blinding_index); + } + + return ret; +} + +// mod_montgomery sets |r| to |I| mod |p|. |I| must already be fully reduced +// modulo |p| times |q|. It returns one on success and zero on error. +static int mod_montgomery(BIGNUM *r, const BIGNUM *I, const BIGNUM *p, + const BN_MONT_CTX *mont_p, const BIGNUM *q, + BN_CTX *ctx) { + // Reducing in constant-time with Montgomery reduction requires I <= p * R. We + // have I < p * q, so this follows if q < R. The caller should have checked + // this already. + if (!bn_less_than_montgomery_R(q, mont_p)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (// Reduce mod p with Montgomery reduction. This computes I * R^-1 mod p. + !BN_from_montgomery(r, I, mont_p, ctx) || + // Multiply by R^2 and do another Montgomery reduction to compute + // I * R^-1 * R^2 * R^-1 = I mod p. + !BN_to_montgomery(r, r, mont_p, ctx)) { + return 0; + } + + // By precomputing R^3 mod p (normally |BN_MONT_CTX| only uses R^2 mod p) and + // adjusting the API for |BN_mod_exp_mont_consttime|, we could instead compute + // I * R mod p here and save a reduction per prime. But this would require + // changing the RSAZ code and may not be worth it. Note that the RSAZ code + // uses a different radix, so it uses R' = 2^1044. There we'd actually want + // R^2 * R', and would futher benefit from a precomputed R'^2. It currently + // converts |mont_p->RR| to R'^2. + return 1; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { + assert(ctx != NULL); + + assert(rsa->n != NULL); + assert(rsa->e != NULL); + assert(rsa->d != NULL); + assert(rsa->p != NULL); + assert(rsa->q != NULL); + assert(rsa->dmp1 != NULL); + assert(rsa->dmq1 != NULL); + assert(rsa->iqmp != NULL); + + BIGNUM *r1, *m1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + if (r1 == NULL || + m1 == NULL) { + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + goto err; + } + + // Implementing RSA with CRT in constant-time is sensitive to which prime is + // larger. Canonicalize fields so that |p| is the larger prime. + const BIGNUM *dmp1 = rsa->dmp1_fixed, *dmq1 = rsa->dmq1_fixed; + const BN_MONT_CTX *mont_p = rsa->mont_p, *mont_q = rsa->mont_q; + if (BN_cmp(rsa->p, rsa->q) < 0) { + mont_p = rsa->mont_q; + mont_q = rsa->mont_p; + dmp1 = rsa->dmq1_fixed; + dmq1 = rsa->dmp1_fixed; + } + + // Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if + // someone gives us non-minimal values, these will be slightly more efficient + // on the non-Montgomery operations. + const BIGNUM *n = &rsa->mont_n->N; + const BIGNUM *p = &mont_p->N; + const BIGNUM *q = &mont_q->N; + + // This is a pre-condition for |mod_montgomery|. It was already checked by the + // caller. + assert(BN_ucmp(I, n) < 0); + + if (// |m1| is the result modulo |q|. + !mod_montgomery(r1, I, q, mont_q, p, ctx) || + !BN_mod_exp_mont_consttime(m1, r1, dmq1, q, ctx, mont_q) || + // |r0| is the result modulo |p|. + !mod_montgomery(r1, I, p, mont_p, q, ctx) || + !BN_mod_exp_mont_consttime(r0, r1, dmp1, p, ctx, mont_p) || + // Compute r0 = r0 - m1 mod p. |p| is the larger prime, so |m1| is already + // fully reduced mod |p|. + !bn_mod_sub_consttime(r0, r0, m1, p, ctx) || + // r0 = r0 * iqmp mod p. We use Montgomery multiplication to compute this + // in constant time. |inv_small_mod_large_mont| is in Montgomery form and + // r0 is not, so the result is taken out of Montgomery form. + !BN_mod_mul_montgomery(r0, r0, rsa->inv_small_mod_large_mont, mont_p, + ctx) || + // r0 = r0 * q + m1 gives the final result. Reducing modulo q gives m1, so + // it is correct mod p. Reducing modulo p gives (r0-m1)*iqmp*q + m1 = r0, + // so it is correct mod q. Finally, the result is bounded by [m1, n + m1), + // and the result is at least |m1|, so this must be the unique answer in + // [0, n). + !bn_mul_consttime(r0, r0, q, ctx) || + !bn_uadd_consttime(r0, r0, m1) || + // The result should be bounded by |n|, but fixed-width operations may + // bound the width slightly higher, so fix it. + !bn_resize_words(r0, n->width)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int ensure_bignum(BIGNUM **out) { + if (*out == NULL) { + *out = BN_new(); + } + return *out != NULL; +} + +// kBoringSSLRSASqrtTwo is the BIGNUM representation of ⌊2²⁰⁴⁷×√2⌋. This is +// chosen to give enough precision for 4096-bit RSA, the largest key size FIPS +// specifies. Key sizes beyond this will round up. +// +// To calculate, use the following Haskell code: +// +// import Text.Printf (printf) +// import Data.List (intercalate) +// +// pow2 = 4095 +// target = 2^pow2 +// +// f x = x*x - (toRational target) +// +// fprime x = 2*x +// +// newtonIteration x = x - (f x) / (fprime x) +// +// converge x = +// let n = floor x in +// if n*n - target < 0 && (n+1)*(n+1) - target > 0 +// then n +// else converge (newtonIteration x) +// +// divrem bits x = (x `div` (2^bits), x `rem` (2^bits)) +// +// bnWords :: Integer -> [Integer] +// bnWords x = +// if x == 0 +// then [] +// else let (high, low) = divrem 64 x in low : bnWords high +// +// showWord x = let (high, low) = divrem 32 x in printf "TOBN(0x%08x, 0x%08x)" high low +// +// output :: String +// output = intercalate ", " $ map showWord $ bnWords $ converge (2 ^ (pow2 `div` 2)) +// +// To verify this number, check that n² < 2⁴⁰⁹⁵ < (n+1)², where n is value +// represented here. Note the components are listed in little-endian order. Here +// is some sample Python code to check: +// +// >>> TOBN = lambda a, b: a << 32 | b +// >>> l = [ ] +// >>> n = sum(a * 2**(64*i) for i, a in enumerate(l)) +// >>> n**2 < 2**4095 < (n+1)**2 +// True +const BN_ULONG kBoringSSLRSASqrtTwo[] = { + TOBN(0x4d7c60a5, 0xe633e3e1), TOBN(0x5fcf8f7b, 0xca3ea33b), + TOBN(0xc246785e, 0x92957023), TOBN(0xf9acce41, 0x797f2805), + TOBN(0xfdfe170f, 0xd3b1f780), TOBN(0xd24f4a76, 0x3facb882), + TOBN(0x18838a2e, 0xaff5f3b2), TOBN(0xc1fcbdde, 0xa2f7dc33), + TOBN(0xdea06241, 0xf7aa81c2), TOBN(0xf6a1be3f, 0xca221307), + TOBN(0x332a5e9f, 0x7bda1ebf), TOBN(0x0104dc01, 0xfe32352f), + TOBN(0xb8cf341b, 0x6f8236c7), TOBN(0x4264dabc, 0xd528b651), + TOBN(0xf4d3a02c, 0xebc93e0c), TOBN(0x81394ab6, 0xd8fd0efd), + TOBN(0xeaa4a089, 0x9040ca4a), TOBN(0xf52f120f, 0x836e582e), + TOBN(0xcb2a6343, 0x31f3c84d), TOBN(0xc6d5a8a3, 0x8bb7e9dc), + TOBN(0x460abc72, 0x2f7c4e33), TOBN(0xcab1bc91, 0x1688458a), + TOBN(0x53059c60, 0x11bc337b), TOBN(0xd2202e87, 0x42af1f4e), + TOBN(0x78048736, 0x3dfa2768), TOBN(0x0f74a85e, 0x439c7b4a), + TOBN(0xa8b1fe6f, 0xdc83db39), TOBN(0x4afc8304, 0x3ab8a2c3), + TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c), + TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484), +}; +const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo); + +// generate_prime sets |out| to a prime with length |bits| such that |out|-1 is +// relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to +// |p|. |sqrt2| must be ⌊2^(bits-1)×√2⌋ (or a slightly overestimate for large +// sizes), and |pow2_bits_100| must be 2^(bits-100). +// +// This function fails with probability around 2^-21. +static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e, + const BIGNUM *p, const BIGNUM *sqrt2, + const BIGNUM *pow2_bits_100, BN_CTX *ctx, + BN_GENCB *cb) { + if (bits < 128 || (bits % BN_BITS2) != 0) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(BN_is_pow2(pow2_bits_100)); + assert(BN_is_bit_set(pow2_bits_100, bits - 100)); + + // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is nlen/2. + + // Use the limit from steps 4.7 and 5.8 for most values of |e|. When |e| is 3, + // the 186-4 limit is too low, so we use a higher one. Note this case is not + // reachable from |RSA_generate_key_fips|. + // + // |limit| determines the failure probability. We must find a prime that is + // not 1 mod |e|. By the prime number theorem, we'll find one with probability + // p = (e-1)/e * 2/(ln(2)*bits). Note the second term is doubled because we + // discard even numbers. + // + // The failure probability is thus (1-p)^limit. To convert that to a power of + // two, we take logs. -log_2((1-p)^limit) = -limit * ln(1-p) / ln(2). + // + // >>> def f(bits, e, limit): + // ... p = (e-1.0)/e * 2.0/(math.log(2)*bits) + // ... return -limit * math.log(1 - p) / math.log(2) + // ... + // >>> f(1024, 65537, 5*1024) + // 20.842750558272634 + // >>> f(1536, 65537, 5*1536) + // 20.83294549602474 + // >>> f(2048, 65537, 5*2048) + // 20.828047576234948 + // >>> f(1024, 3, 8*1024) + // 22.222147925962307 + // >>> f(1536, 3, 8*1536) + // 22.21518251065506 + // >>> f(2048, 3, 8*2048) + // 22.211701985875937 + if (bits >= INT_MAX/32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + int limit = BN_is_word(e, 3) ? bits * 8 : bits * 5; + + int ret = 0, tries = 0, rand_tries = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + for (;;) { + // Generate a random number of length |bits| where the bottom bit is set + // (steps 4.2, 4.3, 5.2 and 5.3) and the top bit is set (implied by the + // bound checked below in steps 4.4 and 5.5). + if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) || + !BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) { + goto err; + } + + if (p != NULL) { + // If |p| and |out| are too close, try again (step 5.4). + if (!bn_abs_sub_consttime(tmp, out, p, ctx)) { + goto err; + } + if (BN_cmp(tmp, pow2_bits_100) <= 0) { + continue; + } + } + + // If out < 2^(bits-1)×√2, try again (steps 4.4 and 5.5). This is equivalent + // to out <= ⌊2^(bits-1)×√2⌋, or out <= sqrt2 for FIPS key sizes. + // + // For larger keys, the comparison is approximate, leaning towards + // retrying. That is, we reject a negligible fraction of primes that are + // within the FIPS bound, but we will never accept a prime outside the + // bound, ensuring the resulting RSA key is the right size. + if (BN_cmp(out, sqrt2) <= 0) { + continue; + } + + // RSA key generation's bottleneck is discarding composites. If it fails + // trial division, do not bother computing a GCD or performing Miller-Rabin. + if (!bn_odd_number_is_obviously_composite(out)) { + // Check gcd(out-1, e) is one (steps 4.5 and 5.6). + int relatively_prime; + if (!BN_sub(tmp, out, BN_value_one()) || + !bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) { + goto err; + } + if (relatively_prime) { + // Test |out| for primality (steps 4.5.1 and 5.6.1). + int is_probable_prime; + if (!BN_primality_test(&is_probable_prime, out, + BN_prime_checks_for_generation, ctx, 0, cb)) { + goto err; + } + if (is_probable_prime) { + ret = 1; + goto err; + } + } + } + + // If we've tried too many times to find a prime, abort (steps 4.7 and + // 5.8). + tries++; + if (tries >= limit) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); + goto err; + } + if (!BN_GENCB_call(cb, 2, tries)) { + goto err; + } + } + +err: + BN_CTX_end(ctx); + return ret; +} + +// rsa_generate_key_impl generates an RSA key using a generalized version of +// FIPS 186-4 appendix B.3. |RSA_generate_key_fips| performs additional checks +// for FIPS-compliant key generation. +// +// This function returns one on success and zero on failure. It has a failure +// probability of about 2^-20. +static int rsa_generate_key_impl(RSA *rsa, int bits, const BIGNUM *e_value, + BN_GENCB *cb) { + // See FIPS 186-4 appendix B.3. This function implements a generalized version + // of the FIPS algorithm. |RSA_generate_key_fips| performs additional checks + // for FIPS-compliant key generation. + + // Always generate RSA keys which are a multiple of 128 bits. Round |bits| + // down as needed. + bits &= ~127; + + // Reject excessively small keys. + if (bits < 256) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + // Reject excessively large public exponents. Windows CryptoAPI and Go don't + // support values larger than 32 bits, so match their limits for generating + // keys. (|rsa_check_public_key| uses a slightly more conservative value, but + // we don't need to support generating such keys.) + // https://github.com/golang/go/issues/3161 + // https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + if (BN_num_bits(e_value) > 32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + int ret = 0; + int prime_bits = bits / 2; + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + goto bn_err; + } + BN_CTX_start(ctx); + BIGNUM *totient = BN_CTX_get(ctx); + BIGNUM *pm1 = BN_CTX_get(ctx); + BIGNUM *qm1 = BN_CTX_get(ctx); + BIGNUM *sqrt2 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits = BN_CTX_get(ctx); + if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL || + pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL || + !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) || + !BN_set_bit(pow2_prime_bits, prime_bits)) { + goto bn_err; + } + + // We need the RSA components non-NULL. + if (!ensure_bignum(&rsa->n) || + !ensure_bignum(&rsa->d) || + !ensure_bignum(&rsa->e) || + !ensure_bignum(&rsa->p) || + !ensure_bignum(&rsa->q) || + !ensure_bignum(&rsa->dmp1) || + !ensure_bignum(&rsa->dmq1)) { + goto bn_err; + } + + if (!BN_copy(rsa->e, e_value)) { + goto bn_err; + } + + // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋. + if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) { + goto bn_err; + } + int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2; + assert(sqrt2_bits == (int)BN_num_bits(sqrt2)); + if (sqrt2_bits > prime_bits) { + // For key sizes up to 4096 (prime_bits = 2048), this is exactly + // ⌊2^(prime_bits-1)×√2⌋. + if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) { + goto bn_err; + } + } else if (prime_bits > sqrt2_bits) { + // For key sizes beyond 4096, this is approximate. We err towards retrying + // to ensure our key is the right size and round up. + if (!BN_add_word(sqrt2, 1) || + !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) { + goto bn_err; + } + } + assert(prime_bits == (int)BN_num_bits(sqrt2)); + + do { + // Generate p and q, each of size |prime_bits|, using the steps outlined in + // appendix FIPS 186-4 appendix B.3.3. + // + // Each call to |generate_prime| fails with probability p = 2^-21. The + // probability that either call fails is 1 - (1-p)^2, which is around 2^-20. + if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 0) || + !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 1)) { + goto bn_err; + } + + if (BN_cmp(rsa->p, rsa->q) < 0) { + BIGNUM *tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-4. This differs + // from typical RSA implementations which use (p-1)*(q-1). + // + // Note this means the size of d might reveal information about p-1 and + // q-1. However, we do operations with Chinese Remainder Theorem, so we only + // use d (mod p-1) and d (mod q-1) as exponents. Using a minimal totient + // does not affect those two values. + int no_inverse; + if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) || + !bn_usub_consttime(qm1, rsa->q, BN_value_one()) || + !bn_lcm_consttime(totient, pm1, qm1, ctx) || + !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) { + goto bn_err; + } + + // Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on + // values for d. + } while (BN_cmp(rsa->d, pow2_prime_bits) <= 0); + + assert(BN_num_bits(pm1) == (unsigned)prime_bits); + assert(BN_num_bits(qm1) == (unsigned)prime_bits); + if (// Calculate n. + !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) || + // Calculate d mod (p-1). + !bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, prime_bits, ctx) || + // Calculate d mod (q-1) + !bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, prime_bits, ctx)) { + goto bn_err; + } + bn_set_minimal_width(rsa->n); + + // Sanity-check that |rsa->n| has the specified size. This is implied by + // |generate_prime|'s bounds. + if (BN_num_bits(rsa->n) != (unsigned)bits) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + // Call |freeze_private_key| to compute the inverse of q mod p, by way of + // |rsa->mont_p|. + if (!freeze_private_key(rsa, ctx)) { + goto bn_err; + } + + // The key generation process is complex and thus error-prone. It could be + // disastrous to generate and then use a bad key so double-check that the key + // makes sense. + if (!RSA_check_key(rsa)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +bn_err: + if (!ret) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + } +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ret; +} + +static void replace_bignum(BIGNUM **out, BIGNUM **in) { + BN_free(*out); + *out = *in; + *in = NULL; +} + +static void replace_bn_mont_ctx(BN_MONT_CTX **out, BN_MONT_CTX **in) { + BN_MONT_CTX_free(*out); + *out = *in; + *in = NULL; +} + +static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, + const BIGNUM *e_value, BN_GENCB *cb, + int check_fips) { + boringssl_ensure_rsa_self_test(); + + RSA *tmp = NULL; + uint32_t err; + int ret = 0; + + // |rsa_generate_key_impl|'s 2^-20 failure probability is too high at scale, + // so we run the FIPS algorithm four times, bringing it down to 2^-80. We + // should just adjust the retry limit, but FIPS 186-4 prescribes that value + // and thus results in unnecessary complexity. + int failures = 0; + do { + ERR_clear_error(); + // Generate into scratch space, to avoid leaving partial work on failure. + tmp = RSA_new(); + if (tmp == NULL) { + goto out; + } + + if (rsa_generate_key_impl(tmp, bits, e_value, cb)) { + break; + } + + err = ERR_peek_error(); + RSA_free(tmp); + tmp = NULL; + failures++; + + // Only retry on |RSA_R_TOO_MANY_ITERATIONS|. This is so a caller-induced + // failure in |BN_GENCB_call| is still fatal. + } while (failures < 4 && ERR_GET_LIB(err) == ERR_LIB_RSA && + ERR_GET_REASON(err) == RSA_R_TOO_MANY_ITERATIONS); + + if (tmp == NULL || (check_fips && !RSA_check_fips(tmp))) { + goto out; + } + + replace_bignum(&rsa->n, &tmp->n); + replace_bignum(&rsa->e, &tmp->e); + replace_bignum(&rsa->d, &tmp->d); + replace_bignum(&rsa->p, &tmp->p); + replace_bignum(&rsa->q, &tmp->q); + replace_bignum(&rsa->dmp1, &tmp->dmp1); + replace_bignum(&rsa->dmq1, &tmp->dmq1); + replace_bignum(&rsa->iqmp, &tmp->iqmp); + replace_bn_mont_ctx(&rsa->mont_n, &tmp->mont_n); + replace_bn_mont_ctx(&rsa->mont_p, &tmp->mont_p); + replace_bn_mont_ctx(&rsa->mont_q, &tmp->mont_q); + replace_bignum(&rsa->d_fixed, &tmp->d_fixed); + replace_bignum(&rsa->dmp1_fixed, &tmp->dmp1_fixed); + replace_bignum(&rsa->dmq1_fixed, &tmp->dmq1_fixed); + replace_bignum(&rsa->inv_small_mod_large_mont, + &tmp->inv_small_mod_large_mont); + rsa->private_key_frozen = tmp->private_key_frozen; + ret = 1; + +out: + RSA_free(tmp); + return ret; +} + +int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e_value, + BN_GENCB *cb) { + return RSA_generate_key_ex_maybe_fips(rsa, bits, e_value, cb, + /*check_fips=*/0); +} + +int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb) { + // FIPS 186-4 allows 2048-bit and 3072-bit RSA keys (1024-bit and 1536-bit + // primes, respectively) with the prime generation method we use. + // Subsequently, IG A.14 stated that larger modulus sizes can be used and ACVP + // testing supports 4096 bits. + if (bits != 2048 && bits != 3072 && bits != 4096) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + return 0; + } + + BIGNUM *e = BN_new(); + int ret = e != NULL && + BN_set_word(e, RSA_F4) && + RSA_generate_key_ex_maybe_fips(rsa, bits, e, cb, /*check_fips=*/1); + BN_free(e); + return ret; +} + +DEFINE_METHOD_FUNCTION(RSA_METHOD, RSA_default_method) { + // All of the methods are NULL to make it easier for the compiler/linker to + // drop unused functions. The wrapper functions will select the appropriate + // |rsa_default_*| implementation. + OPENSSL_memset(out, 0, sizeof(RSA_METHOD)); + out->common.is_static = 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S new file mode 100644 index 00000000..edddc728 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S @@ -0,0 +1,1756 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.globl rsaz_1024_sqr_avx2 +.hidden rsaz_1024_sqr_avx2 +.type rsaz_1024_sqr_avx2,@function +.align 64 +rsaz_1024_sqr_avx2: +.cfi_startproc + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + movq %rax,%rbp +.cfi_def_cfa_register %rbp + movq %rdx,%r13 + subq $832,%rsp + movq %r13,%r15 + subq $-128,%rdi + subq $-128,%rsi + subq $-128,%r13 + + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + vpxor %ymm9,%ymm9,%ymm9 + jz .Lsqr_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%r13),%ymm0 + andq $-2048,%rsp + vmovdqu 32-128(%r13),%ymm1 + vmovdqu 64-128(%r13),%ymm2 + vmovdqu 96-128(%r13),%ymm3 + vmovdqu 128-128(%r13),%ymm4 + vmovdqu 160-128(%r13),%ymm5 + vmovdqu 192-128(%r13),%ymm6 + vmovdqu 224-128(%r13),%ymm7 + vmovdqu 256-128(%r13),%ymm8 + leaq 832+128(%rsp),%r13 + vmovdqu %ymm0,0-128(%r13) + vmovdqu %ymm1,32-128(%r13) + vmovdqu %ymm2,64-128(%r13) + vmovdqu %ymm3,96-128(%r13) + vmovdqu %ymm4,128-128(%r13) + vmovdqu %ymm5,160-128(%r13) + vmovdqu %ymm6,192-128(%r13) + vmovdqu %ymm7,224-128(%r13) + vmovdqu %ymm8,256-128(%r13) + vmovdqu %ymm9,288-128(%r13) + +.Lsqr_1024_no_n_copy: + andq $-1024,%rsp + + vmovdqu 32-128(%rsi),%ymm1 + vmovdqu 64-128(%rsi),%ymm2 + vmovdqu 96-128(%rsi),%ymm3 + vmovdqu 128-128(%rsi),%ymm4 + vmovdqu 160-128(%rsi),%ymm5 + vmovdqu 192-128(%rsi),%ymm6 + vmovdqu 224-128(%rsi),%ymm7 + vmovdqu 256-128(%rsi),%ymm8 + + leaq 192(%rsp),%rbx + vmovdqu .Land_mask(%rip),%ymm15 + jmp .LOOP_GRANDE_SQR_1024 + +.align 32 +.LOOP_GRANDE_SQR_1024: + leaq 576+128(%rsp),%r9 + leaq 448(%rsp),%r12 + + + + + vpaddq %ymm1,%ymm1,%ymm1 + vpbroadcastq 0-128(%rsi),%ymm10 + vpaddq %ymm2,%ymm2,%ymm2 + vmovdqa %ymm1,0-128(%r9) + vpaddq %ymm3,%ymm3,%ymm3 + vmovdqa %ymm2,32-128(%r9) + vpaddq %ymm4,%ymm4,%ymm4 + vmovdqa %ymm3,64-128(%r9) + vpaddq %ymm5,%ymm5,%ymm5 + vmovdqa %ymm4,96-128(%r9) + vpaddq %ymm6,%ymm6,%ymm6 + vmovdqa %ymm5,128-128(%r9) + vpaddq %ymm7,%ymm7,%ymm7 + vmovdqa %ymm6,160-128(%r9) + vpaddq %ymm8,%ymm8,%ymm8 + vmovdqa %ymm7,192-128(%r9) + vpxor %ymm9,%ymm9,%ymm9 + vmovdqa %ymm8,224-128(%r9) + + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpbroadcastq 32-128(%rsi),%ymm11 + vmovdqu %ymm9,288-192(%rbx) + vpmuludq %ymm10,%ymm1,%ymm1 + vmovdqu %ymm9,320-448(%r12) + vpmuludq %ymm10,%ymm2,%ymm2 + vmovdqu %ymm9,352-448(%r12) + vpmuludq %ymm10,%ymm3,%ymm3 + vmovdqu %ymm9,384-448(%r12) + vpmuludq %ymm10,%ymm4,%ymm4 + vmovdqu %ymm9,416-448(%r12) + vpmuludq %ymm10,%ymm5,%ymm5 + vmovdqu %ymm9,448-448(%r12) + vpmuludq %ymm10,%ymm6,%ymm6 + vmovdqu %ymm9,480-448(%r12) + vpmuludq %ymm10,%ymm7,%ymm7 + vmovdqu %ymm9,512-448(%r12) + vpmuludq %ymm10,%ymm8,%ymm8 + vpbroadcastq 64-128(%rsi),%ymm10 + vmovdqu %ymm9,544-448(%r12) + + movq %rsi,%r15 + movl $4,%r14d + jmp .Lsqr_entry_1024 +.align 32 +.LOOP_SQR_1024: + vpbroadcastq 32-128(%r15),%ymm11 + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpaddq 0-192(%rbx),%ymm0,%ymm0 + vpmuludq 0-128(%r9),%ymm10,%ymm1 + vpaddq 32-192(%rbx),%ymm1,%ymm1 + vpmuludq 32-128(%r9),%ymm10,%ymm2 + vpaddq 64-192(%rbx),%ymm2,%ymm2 + vpmuludq 64-128(%r9),%ymm10,%ymm3 + vpaddq 96-192(%rbx),%ymm3,%ymm3 + vpmuludq 96-128(%r9),%ymm10,%ymm4 + vpaddq 128-192(%rbx),%ymm4,%ymm4 + vpmuludq 128-128(%r9),%ymm10,%ymm5 + vpaddq 160-192(%rbx),%ymm5,%ymm5 + vpmuludq 160-128(%r9),%ymm10,%ymm6 + vpaddq 192-192(%rbx),%ymm6,%ymm6 + vpmuludq 192-128(%r9),%ymm10,%ymm7 + vpaddq 224-192(%rbx),%ymm7,%ymm7 + vpmuludq 224-128(%r9),%ymm10,%ymm8 + vpbroadcastq 64-128(%r15),%ymm10 + vpaddq 256-192(%rbx),%ymm8,%ymm8 +.Lsqr_entry_1024: + vmovdqu %ymm0,0-192(%rbx) + vmovdqu %ymm1,32-192(%rbx) + + vpmuludq 32-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 32-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 64-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 96-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 128-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 160-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 192-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 224-128(%r9),%ymm11,%ymm0 + vpbroadcastq 96-128(%r15),%ymm11 + vpaddq 288-192(%rbx),%ymm0,%ymm0 + + vmovdqu %ymm2,64-192(%rbx) + vmovdqu %ymm3,96-192(%rbx) + + vpmuludq 64-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 64-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 96-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 128-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 160-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 224-128(%r9),%ymm10,%ymm1 + vpbroadcastq 128-128(%r15),%ymm10 + vpaddq 320-448(%r12),%ymm1,%ymm1 + + vmovdqu %ymm4,128-192(%rbx) + vmovdqu %ymm5,160-192(%rbx) + + vpmuludq 96-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 96-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq 128-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm0,%ymm0 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq 224-128(%r9),%ymm11,%ymm2 + vpbroadcastq 160-128(%r15),%ymm11 + vpaddq 352-448(%r12),%ymm2,%ymm2 + + vmovdqu %ymm6,192-192(%rbx) + vmovdqu %ymm7,224-192(%rbx) + + vpmuludq 128-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 128-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 160-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 192-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 224-128(%r9),%ymm10,%ymm3 + vpbroadcastq 192-128(%r15),%ymm10 + vpaddq 384-448(%r12),%ymm3,%ymm3 + + vmovdqu %ymm8,256-192(%rbx) + vmovdqu %ymm0,288-192(%rbx) + leaq 8(%rbx),%rbx + + vpmuludq 160-128(%rsi),%ymm11,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 224-128(%r9),%ymm11,%ymm4 + vpbroadcastq 224-128(%r15),%ymm11 + vpaddq 416-448(%r12),%ymm4,%ymm4 + + vmovdqu %ymm1,320-448(%r12) + vmovdqu %ymm2,352-448(%r12) + + vpmuludq 192-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpbroadcastq 256-128(%r15),%ymm0 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq 224-128(%r9),%ymm10,%ymm5 + vpbroadcastq 0+8-128(%r15),%ymm10 + vpaddq 448-448(%r12),%ymm5,%ymm5 + + vmovdqu %ymm3,384-448(%r12) + vmovdqu %ymm4,416-448(%r12) + leaq 8(%r15),%r15 + + vpmuludq 224-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 224-128(%r9),%ymm11,%ymm6 + vpaddq 480-448(%r12),%ymm6,%ymm6 + + vpmuludq 256-128(%rsi),%ymm0,%ymm7 + vmovdqu %ymm5,448-448(%r12) + vpaddq 512-448(%r12),%ymm7,%ymm7 + vmovdqu %ymm6,480-448(%r12) + vmovdqu %ymm7,512-448(%r12) + leaq 8(%r12),%r12 + + decl %r14d + jnz .LOOP_SQR_1024 + + vmovdqu 256(%rsp),%ymm8 + vmovdqu 288(%rsp),%ymm1 + vmovdqu 320(%rsp),%ymm2 + leaq 192(%rsp),%rbx + + vpsrlq $29,%ymm8,%ymm14 + vpand %ymm15,%ymm8,%ymm8 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + + vpermq $0x93,%ymm14,%ymm14 + vpxor %ymm9,%ymm9,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm8,%ymm8 + vpblendd $3,%ymm11,%ymm9,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,288-192(%rbx) + vmovdqu %ymm2,320-192(%rbx) + + movq (%rsp),%rax + movq 8(%rsp),%r10 + movq 16(%rsp),%r11 + movq 24(%rsp),%r12 + vmovdqu 32(%rsp),%ymm1 + vmovdqu 64-192(%rbx),%ymm2 + vmovdqu 96-192(%rbx),%ymm3 + vmovdqu 128-192(%rbx),%ymm4 + vmovdqu 160-192(%rbx),%ymm5 + vmovdqu 192-192(%rbx),%ymm6 + vmovdqu 224-192(%rbx),%ymm7 + + movq %rax,%r9 + imull %ecx,%eax + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + + movq %rax,%rdx + imulq -128(%r13),%rax + vpbroadcastq %xmm12,%ymm12 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax + shrq $29,%r9 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + addq %r9,%r10 + addq %rax,%r11 + imulq 24-128(%r13),%rdx + addq %rdx,%r12 + + movq %r10,%rax + imull %ecx,%eax + andl $0x1fffffff,%eax + + movl $9,%r14d + jmp .LOOP_REDUCE_1024 + +.align 32 +.LOOP_REDUCE_1024: + vmovd %eax,%xmm13 + vpbroadcastq %xmm13,%ymm13 + + vpmuludq 32-128(%r13),%ymm12,%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm10,%ymm1,%ymm1 + addq %rax,%r10 + vpmuludq 64-128(%r13),%ymm12,%ymm14 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm14,%ymm2,%ymm2 + vpmuludq 96-128(%r13),%ymm12,%ymm11 +.byte 0x67 + addq %rax,%r11 +.byte 0x67 + movq %rdx,%rax + imulq 16-128(%r13),%rax + shrq $29,%r10 + vpaddq %ymm11,%ymm3,%ymm3 + vpmuludq 128-128(%r13),%ymm12,%ymm10 + addq %rax,%r12 + addq %r10,%r11 + vpaddq %ymm10,%ymm4,%ymm4 + vpmuludq 160-128(%r13),%ymm12,%ymm14 + movq %r11,%rax + imull %ecx,%eax + vpaddq %ymm14,%ymm5,%ymm5 + vpmuludq 192-128(%r13),%ymm12,%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm11,%ymm6,%ymm6 + vpmuludq 224-128(%r13),%ymm12,%ymm10 + vpaddq %ymm10,%ymm7,%ymm7 + vpmuludq 256-128(%r13),%ymm12,%ymm14 + vmovd %eax,%xmm12 + + vpaddq %ymm14,%ymm8,%ymm8 + + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 32-8-128(%r13),%ymm13,%ymm11 + vmovdqu 96-8-128(%r13),%ymm14 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm1,%ymm1 + vpmuludq 64-8-128(%r13),%ymm13,%ymm10 + vmovdqu 128-8-128(%r13),%ymm11 + addq %rax,%r11 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm10,%ymm2,%ymm2 + addq %r12,%rax + shrq $29,%r11 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 160-8-128(%r13),%ymm10 + addq %r11,%rax + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 192-8-128(%r13),%ymm14 +.byte 0x67 + movq %rax,%r12 + imull %ecx,%eax + vpaddq %ymm11,%ymm4,%ymm4 + vpmuludq %ymm13,%ymm10,%ymm10 +.byte 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm5,%ymm5 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 256-8-128(%r13),%ymm10 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 288-8-128(%r13),%ymm9 + vmovd %eax,%xmm0 + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm7,%ymm7 + vpmuludq %ymm13,%ymm10,%ymm10 + vmovdqu 32-16-128(%r13),%ymm14 + vpbroadcastq %xmm0,%ymm0 + vpaddq %ymm10,%ymm8,%ymm8 + vpmuludq %ymm13,%ymm9,%ymm9 + vmovdqu 64-16-128(%r13),%ymm11 + addq %rax,%r12 + + vmovdqu 32-24-128(%r13),%ymm13 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 96-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq %ymm0,%ymm13,%ymm13 + vpmuludq %ymm12,%ymm11,%ymm11 +.byte 0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff + vpaddq %ymm1,%ymm13,%ymm13 + vpaddq %ymm11,%ymm2,%ymm2 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 160-16-128(%r13),%ymm11 +.byte 0x67 + vmovq %xmm13,%rax + vmovdqu %ymm13,(%rsp) + vpaddq %ymm10,%ymm3,%ymm3 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 192-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq %ymm12,%ymm11,%ymm11 + vmovdqu 224-16-128(%r13),%ymm14 + vpaddq %ymm11,%ymm5,%ymm5 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 256-16-128(%r13),%ymm11 + vpaddq %ymm10,%ymm6,%ymm6 + vpmuludq %ymm12,%ymm14,%ymm14 + shrq $29,%r12 + vmovdqu 288-16-128(%r13),%ymm10 + addq %r12,%rax + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq %ymm12,%ymm11,%ymm11 + + movq %rax,%r9 + imull %ecx,%eax + vpaddq %ymm11,%ymm8,%ymm8 + vpmuludq %ymm12,%ymm10,%ymm10 + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + vmovdqu 96-24-128(%r13),%ymm11 +.byte 0x67 + vpaddq %ymm10,%ymm9,%ymm9 + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 64-24-128(%r13),%ymm0,%ymm14 + vmovdqu 128-24-128(%r13),%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + movq 8(%rsp),%r10 + vpaddq %ymm14,%ymm2,%ymm1 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 160-24-128(%r13),%ymm14 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax +.byte 0x67 + shrq $29,%r9 + movq 16(%rsp),%r11 + vpaddq %ymm11,%ymm3,%ymm2 + vpmuludq %ymm0,%ymm10,%ymm10 + vmovdqu 192-24-128(%r13),%ymm11 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + vpaddq %ymm10,%ymm4,%ymm3 + vpmuludq %ymm0,%ymm14,%ymm14 + vmovdqu 224-24-128(%r13),%ymm10 + imulq 24-128(%r13),%rdx + addq %rax,%r11 + leaq (%r9,%r10,1),%rax + vpaddq %ymm14,%ymm5,%ymm4 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 256-24-128(%r13),%ymm14 + movq %rax,%r10 + imull %ecx,%eax + vpmuludq %ymm0,%ymm10,%ymm10 + vpaddq %ymm11,%ymm6,%ymm5 + vmovdqu 288-24-128(%r13),%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm7,%ymm6 + vpmuludq %ymm0,%ymm14,%ymm14 + addq 24(%rsp),%rdx + vpaddq %ymm14,%ymm8,%ymm7 + vpmuludq %ymm0,%ymm11,%ymm11 + vpaddq %ymm11,%ymm9,%ymm8 + vmovq %r12,%xmm9 + movq %rdx,%r12 + + decl %r14d + jnz .LOOP_REDUCE_1024 + leaq 448(%rsp),%r12 + vpaddq %ymm9,%ymm13,%ymm0 + vpxor %ymm9,%ymm9,%ymm9 + + vpaddq 288-192(%rbx),%ymm0,%ymm0 + vpaddq 320-448(%r12),%ymm1,%ymm1 + vpaddq 352-448(%r12),%ymm2,%ymm2 + vpaddq 384-448(%r12),%ymm3,%ymm3 + vpaddq 416-448(%r12),%ymm4,%ymm4 + vpaddq 448-448(%r12),%ymm5,%ymm5 + vpaddq 480-448(%r12),%ymm6,%ymm6 + vpaddq 512-448(%r12),%ymm7,%ymm7 + vpaddq 544-448(%r12),%ymm8,%ymm8 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm13,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vmovdqu %ymm0,0-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,32-128(%rdi) + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vmovdqu %ymm2,64-128(%rdi) + vpaddq %ymm13,%ymm4,%ymm4 + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vpaddq %ymm13,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vmovdqu %ymm4,128-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vmovdqu %ymm5,160-128(%rdi) + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vmovdqu %ymm6,192-128(%rdi) + vpaddq %ymm13,%ymm8,%ymm8 + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + + movq %rdi,%rsi + decl %r8d + jne .LOOP_GRANDE_SQR_1024 + + vzeroall + movq %rbp,%rax +.cfi_def_cfa_register %rax + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lsqr_1024_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_sqr_avx2,.-rsaz_1024_sqr_avx2 +.globl rsaz_1024_mul_avx2 +.hidden rsaz_1024_mul_avx2 +.type rsaz_1024_mul_avx2,@function +.align 64 +rsaz_1024_mul_avx2: +.cfi_startproc + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + movq %rax,%rbp +.cfi_def_cfa_register %rbp + vzeroall + movq %rdx,%r13 + subq $64,%rsp + + + + + + +.byte 0x67,0x67 + movq %rsi,%r15 + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + movq %rsi,%r15 + cmovnzq %r13,%rsi + cmovnzq %r15,%r13 + + movq %rcx,%r15 + subq $-128,%rsi + subq $-128,%rcx + subq $-128,%rdi + + andq $4095,%r15 + addq $320,%r15 +.byte 0x67,0x67 + shrq $12,%r15 + jz .Lmul_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%rcx),%ymm0 + andq $-512,%rsp + vmovdqu 32-128(%rcx),%ymm1 + vmovdqu 64-128(%rcx),%ymm2 + vmovdqu 96-128(%rcx),%ymm3 + vmovdqu 128-128(%rcx),%ymm4 + vmovdqu 160-128(%rcx),%ymm5 + vmovdqu 192-128(%rcx),%ymm6 + vmovdqu 224-128(%rcx),%ymm7 + vmovdqu 256-128(%rcx),%ymm8 + leaq 64+128(%rsp),%rcx + vmovdqu %ymm0,0-128(%rcx) + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm1,32-128(%rcx) + vpxor %ymm1,%ymm1,%ymm1 + vmovdqu %ymm2,64-128(%rcx) + vpxor %ymm2,%ymm2,%ymm2 + vmovdqu %ymm3,96-128(%rcx) + vpxor %ymm3,%ymm3,%ymm3 + vmovdqu %ymm4,128-128(%rcx) + vpxor %ymm4,%ymm4,%ymm4 + vmovdqu %ymm5,160-128(%rcx) + vpxor %ymm5,%ymm5,%ymm5 + vmovdqu %ymm6,192-128(%rcx) + vpxor %ymm6,%ymm6,%ymm6 + vmovdqu %ymm7,224-128(%rcx) + vpxor %ymm7,%ymm7,%ymm7 + vmovdqu %ymm8,256-128(%rcx) + vmovdqa %ymm0,%ymm8 + vmovdqu %ymm9,288-128(%rcx) +.Lmul_1024_no_n_copy: + andq $-64,%rsp + + movq (%r13),%rbx + vpbroadcastq (%r13),%ymm10 + vmovdqu %ymm0,(%rsp) + xorq %r9,%r9 +.byte 0x67 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + + vmovdqu .Land_mask(%rip),%ymm15 + movl $9,%r14d + vmovdqu %ymm9,288-128(%rdi) + jmp .Loop_mul_1024 + +.align 32 +.Loop_mul_1024: + vpsrlq $29,%ymm3,%ymm9 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r9,%rax + movq %rbx,%r10 + imulq 8-128(%rsi),%r10 + addq 8(%rsp),%r10 + + movq %rax,%r9 + imull %r8d,%eax + andl $0x1fffffff,%eax + + movq %rbx,%r11 + imulq 16-128(%rsi),%r11 + addq 16(%rsp),%r11 + + movq %rbx,%r12 + imulq 24-128(%rsi),%r12 + addq 24(%rsp),%r12 + vpmuludq 32-128(%rsi),%ymm10,%ymm0 + vmovd %eax,%xmm11 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq 64-128(%rsi),%ymm10,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 96-128(%rsi),%ymm10,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq 128-128(%rsi),%ymm10,%ymm0 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq 160-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 192-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq 224-128(%rsi),%ymm10,%ymm0 + vpermq $0x93,%ymm9,%ymm9 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq 256-128(%rsi),%ymm10,%ymm12 + vpbroadcastq 8(%r13),%ymm10 + vpaddq %ymm12,%ymm8,%ymm8 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%rcx),%rax + addq %rax,%r11 + shrq $29,%r9 + imulq 24-128(%rcx),%rdx + addq %rdx,%r12 + addq %r9,%r10 + + vpmuludq 32-128(%rcx),%ymm11,%ymm13 + vmovq %xmm10,%rbx + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 64-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm2,%ymm2 + vpmuludq 96-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 128-128(%rcx),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 160-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm5,%ymm5 + vpmuludq 192-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 224-128(%rcx),%ymm11,%ymm13 + vpblendd $3,%ymm14,%ymm9,%ymm12 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 256-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm0,%ymm8,%ymm8 + + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rsi),%ymm12 + movq %rbx,%rax + imulq 8-128(%rsi),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rsi),%ymm13 + + movq %r10,%rax + vpblendd $0xfc,%ymm14,%ymm9,%ymm9 + imull %r8d,%eax + vpaddq %ymm9,%ymm4,%ymm4 + andl $0x1fffffff,%eax + + imulq 16-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovd %eax,%xmm11 + vmovdqu -8+96-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -8+128-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+160-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+192-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -8+224-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+256-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+288-128(%rsi),%ymm9 + vpaddq %ymm12,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm13,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm9,%ymm9 + vpbroadcastq 16(%r13),%ymm10 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rcx),%ymm0 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rcx),%ymm12 + shrq $29,%r10 + imulq 16-128(%rcx),%rdx + addq %rdx,%r12 + addq %r10,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -8+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rsi),%ymm0 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r11,%rax + + vmovdqu -16+64-128(%rsi),%ymm12 + movq %rax,%r11 + imull %r8d,%eax + andl $0x1fffffff,%eax + + imulq 8-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -16+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -16+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -16+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 24(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rcx),%ymm0 + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r11 + vmovdqu -16+64-128(%rcx),%ymm12 + imulq 8-128(%rcx),%rdx + addq %rdx,%r12 + shrq $29,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -16+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+32-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+64-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm9,%ymm9 + + addq %r11,%r12 + imulq -128(%rsi),%rbx + addq %rbx,%r12 + + movq %r12,%rax + imull %r8d,%eax + andl $0x1fffffff,%eax + + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -24+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -24+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -24+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 32(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + addq $32,%r13 + + vmovdqu -24+32-128(%rcx),%ymm0 + imulq -128(%rcx),%rax + addq %rax,%r12 + shrq $29,%r12 + + vmovdqu -24+64-128(%rcx),%ymm12 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -24+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm0 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu %ymm0,(%rsp) + vpaddq %ymm12,%ymm2,%ymm1 + vmovdqu -24+128-128(%rcx),%ymm0 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm2 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm3 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm4 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm5 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+288-128(%rcx),%ymm13 + movq %r12,%r9 + vpaddq %ymm0,%ymm7,%ymm6 + vpmuludq %ymm11,%ymm12,%ymm12 + addq (%rsp),%r9 + vpaddq %ymm12,%ymm8,%ymm7 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovq %r12,%xmm12 + vpaddq %ymm13,%ymm9,%ymm8 + + decl %r14d + jnz .Loop_mul_1024 + vpaddq (%rsp),%ymm12,%ymm0 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm10,%ymm10 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpermq $0x93,%ymm11,%ymm11 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm10,%ymm10 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vmovdqu %ymm0,0-128(%rdi) + vmovdqu %ymm1,32-128(%rdi) + vmovdqu %ymm2,64-128(%rdi) + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vmovdqu %ymm4,128-128(%rdi) + vmovdqu %ymm5,160-128(%rdi) + vmovdqu %ymm6,192-128(%rdi) + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + vzeroupper + + movq %rbp,%rax +.cfi_def_cfa_register %rax + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_1024_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_mul_avx2,.-rsaz_1024_mul_avx2 +.globl rsaz_1024_red2norm_avx2 +.hidden rsaz_1024_red2norm_avx2 +.type rsaz_1024_red2norm_avx2,@function +.align 32 +rsaz_1024_red2norm_avx2: +.cfi_startproc + subq $-128,%rsi + xorq %rax,%rax + movq -128(%rsi),%r8 + movq -120(%rsi),%r9 + movq -112(%rsi),%r10 + shlq $0,%r8 + shlq $29,%r9 + movq %r10,%r11 + shlq $58,%r10 + shrq $6,%r11 + addq %r8,%rax + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,0(%rdi) + movq %r11,%rax + movq -104(%rsi),%r8 + movq -96(%rsi),%r9 + shlq $23,%r8 + movq %r9,%r10 + shlq $52,%r9 + shrq $12,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,8(%rdi) + movq %r10,%rax + movq -88(%rsi),%r11 + movq -80(%rsi),%r8 + shlq $17,%r11 + movq %r8,%r9 + shlq $46,%r8 + shrq $18,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,16(%rdi) + movq %r9,%rax + movq -72(%rsi),%r10 + movq -64(%rsi),%r11 + shlq $11,%r10 + movq %r11,%r8 + shlq $40,%r11 + shrq $24,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,24(%rdi) + movq %r8,%rax + movq -56(%rsi),%r9 + movq -48(%rsi),%r10 + movq -40(%rsi),%r11 + shlq $5,%r9 + shlq $34,%r10 + movq %r11,%r8 + shlq $63,%r11 + shrq $1,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,32(%rdi) + movq %r8,%rax + movq -32(%rsi),%r9 + movq -24(%rsi),%r10 + shlq $28,%r9 + movq %r10,%r11 + shlq $57,%r10 + shrq $7,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,40(%rdi) + movq %r11,%rax + movq -16(%rsi),%r8 + movq -8(%rsi),%r9 + shlq $22,%r8 + movq %r9,%r10 + shlq $51,%r9 + shrq $13,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,48(%rdi) + movq %r10,%rax + movq 0(%rsi),%r11 + movq 8(%rsi),%r8 + shlq $16,%r11 + movq %r8,%r9 + shlq $45,%r8 + shrq $19,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,56(%rdi) + movq %r9,%rax + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + shlq $10,%r10 + movq %r11,%r8 + shlq $39,%r11 + shrq $25,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,64(%rdi) + movq %r8,%rax + movq 32(%rsi),%r9 + movq 40(%rsi),%r10 + movq 48(%rsi),%r11 + shlq $4,%r9 + shlq $33,%r10 + movq %r11,%r8 + shlq $62,%r11 + shrq $2,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,72(%rdi) + movq %r8,%rax + movq 56(%rsi),%r9 + movq 64(%rsi),%r10 + shlq $27,%r9 + movq %r10,%r11 + shlq $56,%r10 + shrq $8,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,80(%rdi) + movq %r11,%rax + movq 72(%rsi),%r8 + movq 80(%rsi),%r9 + shlq $21,%r8 + movq %r9,%r10 + shlq $50,%r9 + shrq $14,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,88(%rdi) + movq %r10,%rax + movq 88(%rsi),%r11 + movq 96(%rsi),%r8 + shlq $15,%r11 + movq %r8,%r9 + shlq $44,%r8 + shrq $20,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,96(%rdi) + movq %r9,%rax + movq 104(%rsi),%r10 + movq 112(%rsi),%r11 + shlq $9,%r10 + movq %r11,%r8 + shlq $38,%r11 + shrq $26,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,104(%rdi) + movq %r8,%rax + movq 120(%rsi),%r9 + movq 128(%rsi),%r10 + movq 136(%rsi),%r11 + shlq $3,%r9 + shlq $32,%r10 + movq %r11,%r8 + shlq $61,%r11 + shrq $3,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,112(%rdi) + movq %r8,%rax + movq 144(%rsi),%r9 + movq 152(%rsi),%r10 + shlq $26,%r9 + movq %r10,%r11 + shlq $55,%r10 + shrq $9,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,120(%rdi) + movq %r11,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2 + +.globl rsaz_1024_norm2red_avx2 +.hidden rsaz_1024_norm2red_avx2 +.type rsaz_1024_norm2red_avx2,@function +.align 32 +rsaz_1024_norm2red_avx2: +.cfi_startproc + subq $-128,%rdi + movq (%rsi),%r8 + movl $0x1fffffff,%eax + movq 8(%rsi),%r9 + movq %r8,%r11 + shrq $0,%r11 + andq %rax,%r11 + movq %r11,-128(%rdi) + movq %r8,%r10 + shrq $29,%r10 + andq %rax,%r10 + movq %r10,-120(%rdi) + shrdq $58,%r9,%r8 + andq %rax,%r8 + movq %r8,-112(%rdi) + movq 16(%rsi),%r10 + movq %r9,%r8 + shrq $23,%r8 + andq %rax,%r8 + movq %r8,-104(%rdi) + shrdq $52,%r10,%r9 + andq %rax,%r9 + movq %r9,-96(%rdi) + movq 24(%rsi),%r11 + movq %r10,%r9 + shrq $17,%r9 + andq %rax,%r9 + movq %r9,-88(%rdi) + shrdq $46,%r11,%r10 + andq %rax,%r10 + movq %r10,-80(%rdi) + movq 32(%rsi),%r8 + movq %r11,%r10 + shrq $11,%r10 + andq %rax,%r10 + movq %r10,-72(%rdi) + shrdq $40,%r8,%r11 + andq %rax,%r11 + movq %r11,-64(%rdi) + movq 40(%rsi),%r9 + movq %r8,%r11 + shrq $5,%r11 + andq %rax,%r11 + movq %r11,-56(%rdi) + movq %r8,%r10 + shrq $34,%r10 + andq %rax,%r10 + movq %r10,-48(%rdi) + shrdq $63,%r9,%r8 + andq %rax,%r8 + movq %r8,-40(%rdi) + movq 48(%rsi),%r10 + movq %r9,%r8 + shrq $28,%r8 + andq %rax,%r8 + movq %r8,-32(%rdi) + shrdq $57,%r10,%r9 + andq %rax,%r9 + movq %r9,-24(%rdi) + movq 56(%rsi),%r11 + movq %r10,%r9 + shrq $22,%r9 + andq %rax,%r9 + movq %r9,-16(%rdi) + shrdq $51,%r11,%r10 + andq %rax,%r10 + movq %r10,-8(%rdi) + movq 64(%rsi),%r8 + movq %r11,%r10 + shrq $16,%r10 + andq %rax,%r10 + movq %r10,0(%rdi) + shrdq $45,%r8,%r11 + andq %rax,%r11 + movq %r11,8(%rdi) + movq 72(%rsi),%r9 + movq %r8,%r11 + shrq $10,%r11 + andq %rax,%r11 + movq %r11,16(%rdi) + shrdq $39,%r9,%r8 + andq %rax,%r8 + movq %r8,24(%rdi) + movq 80(%rsi),%r10 + movq %r9,%r8 + shrq $4,%r8 + andq %rax,%r8 + movq %r8,32(%rdi) + movq %r9,%r11 + shrq $33,%r11 + andq %rax,%r11 + movq %r11,40(%rdi) + shrdq $62,%r10,%r9 + andq %rax,%r9 + movq %r9,48(%rdi) + movq 88(%rsi),%r11 + movq %r10,%r9 + shrq $27,%r9 + andq %rax,%r9 + movq %r9,56(%rdi) + shrdq $56,%r11,%r10 + andq %rax,%r10 + movq %r10,64(%rdi) + movq 96(%rsi),%r8 + movq %r11,%r10 + shrq $21,%r10 + andq %rax,%r10 + movq %r10,72(%rdi) + shrdq $50,%r8,%r11 + andq %rax,%r11 + movq %r11,80(%rdi) + movq 104(%rsi),%r9 + movq %r8,%r11 + shrq $15,%r11 + andq %rax,%r11 + movq %r11,88(%rdi) + shrdq $44,%r9,%r8 + andq %rax,%r8 + movq %r8,96(%rdi) + movq 112(%rsi),%r10 + movq %r9,%r8 + shrq $9,%r8 + andq %rax,%r8 + movq %r8,104(%rdi) + shrdq $38,%r10,%r9 + andq %rax,%r9 + movq %r9,112(%rdi) + movq 120(%rsi),%r11 + movq %r10,%r9 + shrq $3,%r9 + andq %rax,%r9 + movq %r9,120(%rdi) + movq %r10,%r8 + shrq $32,%r8 + andq %rax,%r8 + movq %r8,128(%rdi) + shrdq $61,%r11,%r10 + andq %rax,%r10 + movq %r10,136(%rdi) + xorq %r8,%r8 + movq %r11,%r10 + shrq $26,%r10 + andq %rax,%r10 + movq %r10,144(%rdi) + shrdq $55,%r8,%r11 + andq %rax,%r11 + movq %r11,152(%rdi) + movq %r8,160(%rdi) + movq %r8,168(%rdi) + movq %r8,176(%rdi) + movq %r8,184(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2 +.globl rsaz_1024_scatter5_avx2 +.hidden rsaz_1024_scatter5_avx2 +.type rsaz_1024_scatter5_avx2,@function +.align 32 +rsaz_1024_scatter5_avx2: +.cfi_startproc + vzeroupper + vmovdqu .Lscatter_permd(%rip),%ymm5 + shll $4,%edx + leaq (%rdi,%rdx,1),%rdi + movl $9,%eax + jmp .Loop_scatter_1024 + +.align 32 +.Loop_scatter_1024: + vmovdqu (%rsi),%ymm0 + leaq 32(%rsi),%rsi + vpermd %ymm0,%ymm5,%ymm0 + vmovdqu %xmm0,(%rdi) + leaq 512(%rdi),%rdi + decl %eax + jnz .Loop_scatter_1024 + + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2 + +.globl rsaz_1024_gather5_avx2 +.hidden rsaz_1024_gather5_avx2 +.type rsaz_1024_gather5_avx2,@function +.align 32 +rsaz_1024_gather5_avx2: +.cfi_startproc + vzeroupper + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + leaq -256(%rsp),%rsp + andq $-32,%rsp + leaq .Linc(%rip),%r10 + leaq -128(%rsp),%rax + + vmovd %edx,%xmm4 + vmovdqa (%r10),%ymm0 + vmovdqa 32(%r10),%ymm1 + vmovdqa 64(%r10),%ymm5 + vpbroadcastd %xmm4,%ymm4 + + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,0+128(%rax) + vpaddd %ymm5,%ymm2,%ymm0 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,32+128(%rax) + vpaddd %ymm5,%ymm3,%ymm1 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,64+128(%rax) + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vmovdqa %ymm3,96+128(%rax) + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,128+128(%rax) + vpaddd %ymm5,%ymm2,%ymm8 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,160+128(%rax) + vpaddd %ymm5,%ymm3,%ymm9 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,192+128(%rax) + vpaddd %ymm5,%ymm8,%ymm10 + vpcmpeqd %ymm4,%ymm8,%ymm8 + vmovdqa %ymm3,224+128(%rax) + vpaddd %ymm5,%ymm9,%ymm11 + vpcmpeqd %ymm4,%ymm9,%ymm9 + vpaddd %ymm5,%ymm10,%ymm12 + vpcmpeqd %ymm4,%ymm10,%ymm10 + vpaddd %ymm5,%ymm11,%ymm13 + vpcmpeqd %ymm4,%ymm11,%ymm11 + vpaddd %ymm5,%ymm12,%ymm14 + vpcmpeqd %ymm4,%ymm12,%ymm12 + vpaddd %ymm5,%ymm13,%ymm15 + vpcmpeqd %ymm4,%ymm13,%ymm13 + vpcmpeqd %ymm4,%ymm14,%ymm14 + vpcmpeqd %ymm4,%ymm15,%ymm15 + + vmovdqa -32(%r10),%ymm7 + leaq 128(%rsi),%rsi + movl $9,%edx + +.Loop_gather_1024: + vmovdqa 0-128(%rsi),%ymm0 + vmovdqa 32-128(%rsi),%ymm1 + vmovdqa 64-128(%rsi),%ymm2 + vmovdqa 96-128(%rsi),%ymm3 + vpand 0+128(%rax),%ymm0,%ymm0 + vpand 32+128(%rax),%ymm1,%ymm1 + vpand 64+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm1,%ymm4 + vpand 96+128(%rax),%ymm3,%ymm3 + vmovdqa 128-128(%rsi),%ymm0 + vmovdqa 160-128(%rsi),%ymm1 + vpor %ymm2,%ymm3,%ymm5 + vmovdqa 192-128(%rsi),%ymm2 + vmovdqa 224-128(%rsi),%ymm3 + vpand 128+128(%rax),%ymm0,%ymm0 + vpand 160+128(%rax),%ymm1,%ymm1 + vpand 192+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm4,%ymm4 + vpand 224+128(%rax),%ymm3,%ymm3 + vpand 256-128(%rsi),%ymm8,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 288-128(%rsi),%ymm9,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 320-128(%rsi),%ymm10,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 352-128(%rsi),%ymm11,%ymm3 + vpor %ymm0,%ymm4,%ymm4 + vpand 384-128(%rsi),%ymm12,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 416-128(%rsi),%ymm13,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 448-128(%rsi),%ymm14,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 480-128(%rsi),%ymm15,%ymm3 + leaq 512(%rsi),%rsi + vpor %ymm0,%ymm4,%ymm4 + vpor %ymm1,%ymm5,%ymm5 + vpor %ymm2,%ymm4,%ymm4 + vpor %ymm3,%ymm5,%ymm5 + + vpor %ymm5,%ymm4,%ymm4 + vextracti128 $1,%ymm4,%xmm5 + vpor %xmm4,%xmm5,%xmm5 + vpermd %ymm5,%ymm7,%ymm5 + vmovdqu %ymm5,(%rdi) + leaq 32(%rdi),%rdi + decl %edx + jnz .Loop_gather_1024 + + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + vzeroupper + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_rsaz_1024_gather5: +.size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2 +.align 64 +.Land_mask: +.quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff +.Lscatter_permd: +.long 0,2,4,6,7,7,7,7 +.Lgather_permd: +.long 0,7,1,7,2,7,3,7 +.Linc: +.long 0,0,0,0, 1,1,1,1 +.long 2,2,2,2, 3,3,3,3 +.long 4,4,4,4, 4,4,4,4 +.align 64 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S new file mode 100644 index 00000000..a1061778 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S @@ -0,0 +1,1755 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.globl _rsaz_1024_sqr_avx2 +.private_extern _rsaz_1024_sqr_avx2 + +.p2align 6 +_rsaz_1024_sqr_avx2: + + leaq (%rsp),%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + vzeroupper + movq %rax,%rbp + + movq %rdx,%r13 + subq $832,%rsp + movq %r13,%r15 + subq $-128,%rdi + subq $-128,%rsi + subq $-128,%r13 + + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + vpxor %ymm9,%ymm9,%ymm9 + jz L$sqr_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%r13),%ymm0 + andq $-2048,%rsp + vmovdqu 32-128(%r13),%ymm1 + vmovdqu 64-128(%r13),%ymm2 + vmovdqu 96-128(%r13),%ymm3 + vmovdqu 128-128(%r13),%ymm4 + vmovdqu 160-128(%r13),%ymm5 + vmovdqu 192-128(%r13),%ymm6 + vmovdqu 224-128(%r13),%ymm7 + vmovdqu 256-128(%r13),%ymm8 + leaq 832+128(%rsp),%r13 + vmovdqu %ymm0,0-128(%r13) + vmovdqu %ymm1,32-128(%r13) + vmovdqu %ymm2,64-128(%r13) + vmovdqu %ymm3,96-128(%r13) + vmovdqu %ymm4,128-128(%r13) + vmovdqu %ymm5,160-128(%r13) + vmovdqu %ymm6,192-128(%r13) + vmovdqu %ymm7,224-128(%r13) + vmovdqu %ymm8,256-128(%r13) + vmovdqu %ymm9,288-128(%r13) + +L$sqr_1024_no_n_copy: + andq $-1024,%rsp + + vmovdqu 32-128(%rsi),%ymm1 + vmovdqu 64-128(%rsi),%ymm2 + vmovdqu 96-128(%rsi),%ymm3 + vmovdqu 128-128(%rsi),%ymm4 + vmovdqu 160-128(%rsi),%ymm5 + vmovdqu 192-128(%rsi),%ymm6 + vmovdqu 224-128(%rsi),%ymm7 + vmovdqu 256-128(%rsi),%ymm8 + + leaq 192(%rsp),%rbx + vmovdqu L$and_mask(%rip),%ymm15 + jmp L$OOP_GRANDE_SQR_1024 + +.p2align 5 +L$OOP_GRANDE_SQR_1024: + leaq 576+128(%rsp),%r9 + leaq 448(%rsp),%r12 + + + + + vpaddq %ymm1,%ymm1,%ymm1 + vpbroadcastq 0-128(%rsi),%ymm10 + vpaddq %ymm2,%ymm2,%ymm2 + vmovdqa %ymm1,0-128(%r9) + vpaddq %ymm3,%ymm3,%ymm3 + vmovdqa %ymm2,32-128(%r9) + vpaddq %ymm4,%ymm4,%ymm4 + vmovdqa %ymm3,64-128(%r9) + vpaddq %ymm5,%ymm5,%ymm5 + vmovdqa %ymm4,96-128(%r9) + vpaddq %ymm6,%ymm6,%ymm6 + vmovdqa %ymm5,128-128(%r9) + vpaddq %ymm7,%ymm7,%ymm7 + vmovdqa %ymm6,160-128(%r9) + vpaddq %ymm8,%ymm8,%ymm8 + vmovdqa %ymm7,192-128(%r9) + vpxor %ymm9,%ymm9,%ymm9 + vmovdqa %ymm8,224-128(%r9) + + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpbroadcastq 32-128(%rsi),%ymm11 + vmovdqu %ymm9,288-192(%rbx) + vpmuludq %ymm10,%ymm1,%ymm1 + vmovdqu %ymm9,320-448(%r12) + vpmuludq %ymm10,%ymm2,%ymm2 + vmovdqu %ymm9,352-448(%r12) + vpmuludq %ymm10,%ymm3,%ymm3 + vmovdqu %ymm9,384-448(%r12) + vpmuludq %ymm10,%ymm4,%ymm4 + vmovdqu %ymm9,416-448(%r12) + vpmuludq %ymm10,%ymm5,%ymm5 + vmovdqu %ymm9,448-448(%r12) + vpmuludq %ymm10,%ymm6,%ymm6 + vmovdqu %ymm9,480-448(%r12) + vpmuludq %ymm10,%ymm7,%ymm7 + vmovdqu %ymm9,512-448(%r12) + vpmuludq %ymm10,%ymm8,%ymm8 + vpbroadcastq 64-128(%rsi),%ymm10 + vmovdqu %ymm9,544-448(%r12) + + movq %rsi,%r15 + movl $4,%r14d + jmp L$sqr_entry_1024 +.p2align 5 +L$OOP_SQR_1024: + vpbroadcastq 32-128(%r15),%ymm11 + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpaddq 0-192(%rbx),%ymm0,%ymm0 + vpmuludq 0-128(%r9),%ymm10,%ymm1 + vpaddq 32-192(%rbx),%ymm1,%ymm1 + vpmuludq 32-128(%r9),%ymm10,%ymm2 + vpaddq 64-192(%rbx),%ymm2,%ymm2 + vpmuludq 64-128(%r9),%ymm10,%ymm3 + vpaddq 96-192(%rbx),%ymm3,%ymm3 + vpmuludq 96-128(%r9),%ymm10,%ymm4 + vpaddq 128-192(%rbx),%ymm4,%ymm4 + vpmuludq 128-128(%r9),%ymm10,%ymm5 + vpaddq 160-192(%rbx),%ymm5,%ymm5 + vpmuludq 160-128(%r9),%ymm10,%ymm6 + vpaddq 192-192(%rbx),%ymm6,%ymm6 + vpmuludq 192-128(%r9),%ymm10,%ymm7 + vpaddq 224-192(%rbx),%ymm7,%ymm7 + vpmuludq 224-128(%r9),%ymm10,%ymm8 + vpbroadcastq 64-128(%r15),%ymm10 + vpaddq 256-192(%rbx),%ymm8,%ymm8 +L$sqr_entry_1024: + vmovdqu %ymm0,0-192(%rbx) + vmovdqu %ymm1,32-192(%rbx) + + vpmuludq 32-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 32-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 64-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 96-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 128-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 160-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 192-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 224-128(%r9),%ymm11,%ymm0 + vpbroadcastq 96-128(%r15),%ymm11 + vpaddq 288-192(%rbx),%ymm0,%ymm0 + + vmovdqu %ymm2,64-192(%rbx) + vmovdqu %ymm3,96-192(%rbx) + + vpmuludq 64-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 64-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 96-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 128-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 160-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 224-128(%r9),%ymm10,%ymm1 + vpbroadcastq 128-128(%r15),%ymm10 + vpaddq 320-448(%r12),%ymm1,%ymm1 + + vmovdqu %ymm4,128-192(%rbx) + vmovdqu %ymm5,160-192(%rbx) + + vpmuludq 96-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 96-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq 128-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm0,%ymm0 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq 224-128(%r9),%ymm11,%ymm2 + vpbroadcastq 160-128(%r15),%ymm11 + vpaddq 352-448(%r12),%ymm2,%ymm2 + + vmovdqu %ymm6,192-192(%rbx) + vmovdqu %ymm7,224-192(%rbx) + + vpmuludq 128-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 128-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 160-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 192-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 224-128(%r9),%ymm10,%ymm3 + vpbroadcastq 192-128(%r15),%ymm10 + vpaddq 384-448(%r12),%ymm3,%ymm3 + + vmovdqu %ymm8,256-192(%rbx) + vmovdqu %ymm0,288-192(%rbx) + leaq 8(%rbx),%rbx + + vpmuludq 160-128(%rsi),%ymm11,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 224-128(%r9),%ymm11,%ymm4 + vpbroadcastq 224-128(%r15),%ymm11 + vpaddq 416-448(%r12),%ymm4,%ymm4 + + vmovdqu %ymm1,320-448(%r12) + vmovdqu %ymm2,352-448(%r12) + + vpmuludq 192-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpbroadcastq 256-128(%r15),%ymm0 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq 224-128(%r9),%ymm10,%ymm5 + vpbroadcastq 0+8-128(%r15),%ymm10 + vpaddq 448-448(%r12),%ymm5,%ymm5 + + vmovdqu %ymm3,384-448(%r12) + vmovdqu %ymm4,416-448(%r12) + leaq 8(%r15),%r15 + + vpmuludq 224-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 224-128(%r9),%ymm11,%ymm6 + vpaddq 480-448(%r12),%ymm6,%ymm6 + + vpmuludq 256-128(%rsi),%ymm0,%ymm7 + vmovdqu %ymm5,448-448(%r12) + vpaddq 512-448(%r12),%ymm7,%ymm7 + vmovdqu %ymm6,480-448(%r12) + vmovdqu %ymm7,512-448(%r12) + leaq 8(%r12),%r12 + + decl %r14d + jnz L$OOP_SQR_1024 + + vmovdqu 256(%rsp),%ymm8 + vmovdqu 288(%rsp),%ymm1 + vmovdqu 320(%rsp),%ymm2 + leaq 192(%rsp),%rbx + + vpsrlq $29,%ymm8,%ymm14 + vpand %ymm15,%ymm8,%ymm8 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + + vpermq $0x93,%ymm14,%ymm14 + vpxor %ymm9,%ymm9,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm8,%ymm8 + vpblendd $3,%ymm11,%ymm9,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,288-192(%rbx) + vmovdqu %ymm2,320-192(%rbx) + + movq (%rsp),%rax + movq 8(%rsp),%r10 + movq 16(%rsp),%r11 + movq 24(%rsp),%r12 + vmovdqu 32(%rsp),%ymm1 + vmovdqu 64-192(%rbx),%ymm2 + vmovdqu 96-192(%rbx),%ymm3 + vmovdqu 128-192(%rbx),%ymm4 + vmovdqu 160-192(%rbx),%ymm5 + vmovdqu 192-192(%rbx),%ymm6 + vmovdqu 224-192(%rbx),%ymm7 + + movq %rax,%r9 + imull %ecx,%eax + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + + movq %rax,%rdx + imulq -128(%r13),%rax + vpbroadcastq %xmm12,%ymm12 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax + shrq $29,%r9 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + addq %r9,%r10 + addq %rax,%r11 + imulq 24-128(%r13),%rdx + addq %rdx,%r12 + + movq %r10,%rax + imull %ecx,%eax + andl $0x1fffffff,%eax + + movl $9,%r14d + jmp L$OOP_REDUCE_1024 + +.p2align 5 +L$OOP_REDUCE_1024: + vmovd %eax,%xmm13 + vpbroadcastq %xmm13,%ymm13 + + vpmuludq 32-128(%r13),%ymm12,%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm10,%ymm1,%ymm1 + addq %rax,%r10 + vpmuludq 64-128(%r13),%ymm12,%ymm14 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm14,%ymm2,%ymm2 + vpmuludq 96-128(%r13),%ymm12,%ymm11 +.byte 0x67 + addq %rax,%r11 +.byte 0x67 + movq %rdx,%rax + imulq 16-128(%r13),%rax + shrq $29,%r10 + vpaddq %ymm11,%ymm3,%ymm3 + vpmuludq 128-128(%r13),%ymm12,%ymm10 + addq %rax,%r12 + addq %r10,%r11 + vpaddq %ymm10,%ymm4,%ymm4 + vpmuludq 160-128(%r13),%ymm12,%ymm14 + movq %r11,%rax + imull %ecx,%eax + vpaddq %ymm14,%ymm5,%ymm5 + vpmuludq 192-128(%r13),%ymm12,%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm11,%ymm6,%ymm6 + vpmuludq 224-128(%r13),%ymm12,%ymm10 + vpaddq %ymm10,%ymm7,%ymm7 + vpmuludq 256-128(%r13),%ymm12,%ymm14 + vmovd %eax,%xmm12 + + vpaddq %ymm14,%ymm8,%ymm8 + + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 32-8-128(%r13),%ymm13,%ymm11 + vmovdqu 96-8-128(%r13),%ymm14 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm1,%ymm1 + vpmuludq 64-8-128(%r13),%ymm13,%ymm10 + vmovdqu 128-8-128(%r13),%ymm11 + addq %rax,%r11 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm10,%ymm2,%ymm2 + addq %r12,%rax + shrq $29,%r11 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 160-8-128(%r13),%ymm10 + addq %r11,%rax + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 192-8-128(%r13),%ymm14 +.byte 0x67 + movq %rax,%r12 + imull %ecx,%eax + vpaddq %ymm11,%ymm4,%ymm4 + vpmuludq %ymm13,%ymm10,%ymm10 +.byte 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm5,%ymm5 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 256-8-128(%r13),%ymm10 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 288-8-128(%r13),%ymm9 + vmovd %eax,%xmm0 + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm7,%ymm7 + vpmuludq %ymm13,%ymm10,%ymm10 + vmovdqu 32-16-128(%r13),%ymm14 + vpbroadcastq %xmm0,%ymm0 + vpaddq %ymm10,%ymm8,%ymm8 + vpmuludq %ymm13,%ymm9,%ymm9 + vmovdqu 64-16-128(%r13),%ymm11 + addq %rax,%r12 + + vmovdqu 32-24-128(%r13),%ymm13 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 96-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq %ymm0,%ymm13,%ymm13 + vpmuludq %ymm12,%ymm11,%ymm11 +.byte 0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff + vpaddq %ymm1,%ymm13,%ymm13 + vpaddq %ymm11,%ymm2,%ymm2 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 160-16-128(%r13),%ymm11 +.byte 0x67 + vmovq %xmm13,%rax + vmovdqu %ymm13,(%rsp) + vpaddq %ymm10,%ymm3,%ymm3 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 192-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq %ymm12,%ymm11,%ymm11 + vmovdqu 224-16-128(%r13),%ymm14 + vpaddq %ymm11,%ymm5,%ymm5 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 256-16-128(%r13),%ymm11 + vpaddq %ymm10,%ymm6,%ymm6 + vpmuludq %ymm12,%ymm14,%ymm14 + shrq $29,%r12 + vmovdqu 288-16-128(%r13),%ymm10 + addq %r12,%rax + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq %ymm12,%ymm11,%ymm11 + + movq %rax,%r9 + imull %ecx,%eax + vpaddq %ymm11,%ymm8,%ymm8 + vpmuludq %ymm12,%ymm10,%ymm10 + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + vmovdqu 96-24-128(%r13),%ymm11 +.byte 0x67 + vpaddq %ymm10,%ymm9,%ymm9 + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 64-24-128(%r13),%ymm0,%ymm14 + vmovdqu 128-24-128(%r13),%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + movq 8(%rsp),%r10 + vpaddq %ymm14,%ymm2,%ymm1 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 160-24-128(%r13),%ymm14 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax +.byte 0x67 + shrq $29,%r9 + movq 16(%rsp),%r11 + vpaddq %ymm11,%ymm3,%ymm2 + vpmuludq %ymm0,%ymm10,%ymm10 + vmovdqu 192-24-128(%r13),%ymm11 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + vpaddq %ymm10,%ymm4,%ymm3 + vpmuludq %ymm0,%ymm14,%ymm14 + vmovdqu 224-24-128(%r13),%ymm10 + imulq 24-128(%r13),%rdx + addq %rax,%r11 + leaq (%r9,%r10,1),%rax + vpaddq %ymm14,%ymm5,%ymm4 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 256-24-128(%r13),%ymm14 + movq %rax,%r10 + imull %ecx,%eax + vpmuludq %ymm0,%ymm10,%ymm10 + vpaddq %ymm11,%ymm6,%ymm5 + vmovdqu 288-24-128(%r13),%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm7,%ymm6 + vpmuludq %ymm0,%ymm14,%ymm14 + addq 24(%rsp),%rdx + vpaddq %ymm14,%ymm8,%ymm7 + vpmuludq %ymm0,%ymm11,%ymm11 + vpaddq %ymm11,%ymm9,%ymm8 + vmovq %r12,%xmm9 + movq %rdx,%r12 + + decl %r14d + jnz L$OOP_REDUCE_1024 + leaq 448(%rsp),%r12 + vpaddq %ymm9,%ymm13,%ymm0 + vpxor %ymm9,%ymm9,%ymm9 + + vpaddq 288-192(%rbx),%ymm0,%ymm0 + vpaddq 320-448(%r12),%ymm1,%ymm1 + vpaddq 352-448(%r12),%ymm2,%ymm2 + vpaddq 384-448(%r12),%ymm3,%ymm3 + vpaddq 416-448(%r12),%ymm4,%ymm4 + vpaddq 448-448(%r12),%ymm5,%ymm5 + vpaddq 480-448(%r12),%ymm6,%ymm6 + vpaddq 512-448(%r12),%ymm7,%ymm7 + vpaddq 544-448(%r12),%ymm8,%ymm8 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm13,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vmovdqu %ymm0,0-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,32-128(%rdi) + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vmovdqu %ymm2,64-128(%rdi) + vpaddq %ymm13,%ymm4,%ymm4 + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vpaddq %ymm13,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vmovdqu %ymm4,128-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vmovdqu %ymm5,160-128(%rdi) + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vmovdqu %ymm6,192-128(%rdi) + vpaddq %ymm13,%ymm8,%ymm8 + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + + movq %rdi,%rsi + decl %r8d + jne L$OOP_GRANDE_SQR_1024 + + vzeroall + movq %rbp,%rax + + movq -48(%rax),%r15 + + movq -40(%rax),%r14 + + movq -32(%rax),%r13 + + movq -24(%rax),%r12 + + movq -16(%rax),%rbp + + movq -8(%rax),%rbx + + leaq (%rax),%rsp + +L$sqr_1024_epilogue: + .byte 0xf3,0xc3 + + +.globl _rsaz_1024_mul_avx2 +.private_extern _rsaz_1024_mul_avx2 + +.p2align 6 +_rsaz_1024_mul_avx2: + + leaq (%rsp),%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + movq %rax,%rbp + + vzeroall + movq %rdx,%r13 + subq $64,%rsp + + + + + + +.byte 0x67,0x67 + movq %rsi,%r15 + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + movq %rsi,%r15 + cmovnzq %r13,%rsi + cmovnzq %r15,%r13 + + movq %rcx,%r15 + subq $-128,%rsi + subq $-128,%rcx + subq $-128,%rdi + + andq $4095,%r15 + addq $320,%r15 +.byte 0x67,0x67 + shrq $12,%r15 + jz L$mul_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%rcx),%ymm0 + andq $-512,%rsp + vmovdqu 32-128(%rcx),%ymm1 + vmovdqu 64-128(%rcx),%ymm2 + vmovdqu 96-128(%rcx),%ymm3 + vmovdqu 128-128(%rcx),%ymm4 + vmovdqu 160-128(%rcx),%ymm5 + vmovdqu 192-128(%rcx),%ymm6 + vmovdqu 224-128(%rcx),%ymm7 + vmovdqu 256-128(%rcx),%ymm8 + leaq 64+128(%rsp),%rcx + vmovdqu %ymm0,0-128(%rcx) + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm1,32-128(%rcx) + vpxor %ymm1,%ymm1,%ymm1 + vmovdqu %ymm2,64-128(%rcx) + vpxor %ymm2,%ymm2,%ymm2 + vmovdqu %ymm3,96-128(%rcx) + vpxor %ymm3,%ymm3,%ymm3 + vmovdqu %ymm4,128-128(%rcx) + vpxor %ymm4,%ymm4,%ymm4 + vmovdqu %ymm5,160-128(%rcx) + vpxor %ymm5,%ymm5,%ymm5 + vmovdqu %ymm6,192-128(%rcx) + vpxor %ymm6,%ymm6,%ymm6 + vmovdqu %ymm7,224-128(%rcx) + vpxor %ymm7,%ymm7,%ymm7 + vmovdqu %ymm8,256-128(%rcx) + vmovdqa %ymm0,%ymm8 + vmovdqu %ymm9,288-128(%rcx) +L$mul_1024_no_n_copy: + andq $-64,%rsp + + movq (%r13),%rbx + vpbroadcastq (%r13),%ymm10 + vmovdqu %ymm0,(%rsp) + xorq %r9,%r9 +.byte 0x67 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + + vmovdqu L$and_mask(%rip),%ymm15 + movl $9,%r14d + vmovdqu %ymm9,288-128(%rdi) + jmp L$oop_mul_1024 + +.p2align 5 +L$oop_mul_1024: + vpsrlq $29,%ymm3,%ymm9 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r9,%rax + movq %rbx,%r10 + imulq 8-128(%rsi),%r10 + addq 8(%rsp),%r10 + + movq %rax,%r9 + imull %r8d,%eax + andl $0x1fffffff,%eax + + movq %rbx,%r11 + imulq 16-128(%rsi),%r11 + addq 16(%rsp),%r11 + + movq %rbx,%r12 + imulq 24-128(%rsi),%r12 + addq 24(%rsp),%r12 + vpmuludq 32-128(%rsi),%ymm10,%ymm0 + vmovd %eax,%xmm11 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq 64-128(%rsi),%ymm10,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 96-128(%rsi),%ymm10,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq 128-128(%rsi),%ymm10,%ymm0 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq 160-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 192-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq 224-128(%rsi),%ymm10,%ymm0 + vpermq $0x93,%ymm9,%ymm9 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq 256-128(%rsi),%ymm10,%ymm12 + vpbroadcastq 8(%r13),%ymm10 + vpaddq %ymm12,%ymm8,%ymm8 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%rcx),%rax + addq %rax,%r11 + shrq $29,%r9 + imulq 24-128(%rcx),%rdx + addq %rdx,%r12 + addq %r9,%r10 + + vpmuludq 32-128(%rcx),%ymm11,%ymm13 + vmovq %xmm10,%rbx + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 64-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm2,%ymm2 + vpmuludq 96-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 128-128(%rcx),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 160-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm5,%ymm5 + vpmuludq 192-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 224-128(%rcx),%ymm11,%ymm13 + vpblendd $3,%ymm14,%ymm9,%ymm12 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 256-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm0,%ymm8,%ymm8 + + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rsi),%ymm12 + movq %rbx,%rax + imulq 8-128(%rsi),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rsi),%ymm13 + + movq %r10,%rax + vpblendd $0xfc,%ymm14,%ymm9,%ymm9 + imull %r8d,%eax + vpaddq %ymm9,%ymm4,%ymm4 + andl $0x1fffffff,%eax + + imulq 16-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovd %eax,%xmm11 + vmovdqu -8+96-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -8+128-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+160-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+192-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -8+224-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+256-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+288-128(%rsi),%ymm9 + vpaddq %ymm12,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm13,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm9,%ymm9 + vpbroadcastq 16(%r13),%ymm10 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rcx),%ymm0 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rcx),%ymm12 + shrq $29,%r10 + imulq 16-128(%rcx),%rdx + addq %rdx,%r12 + addq %r10,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -8+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rsi),%ymm0 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r11,%rax + + vmovdqu -16+64-128(%rsi),%ymm12 + movq %rax,%r11 + imull %r8d,%eax + andl $0x1fffffff,%eax + + imulq 8-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -16+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -16+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -16+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 24(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rcx),%ymm0 + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r11 + vmovdqu -16+64-128(%rcx),%ymm12 + imulq 8-128(%rcx),%rdx + addq %rdx,%r12 + shrq $29,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -16+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+32-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+64-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm9,%ymm9 + + addq %r11,%r12 + imulq -128(%rsi),%rbx + addq %rbx,%r12 + + movq %r12,%rax + imull %r8d,%eax + andl $0x1fffffff,%eax + + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -24+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -24+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -24+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 32(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + addq $32,%r13 + + vmovdqu -24+32-128(%rcx),%ymm0 + imulq -128(%rcx),%rax + addq %rax,%r12 + shrq $29,%r12 + + vmovdqu -24+64-128(%rcx),%ymm12 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -24+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm0 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu %ymm0,(%rsp) + vpaddq %ymm12,%ymm2,%ymm1 + vmovdqu -24+128-128(%rcx),%ymm0 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm2 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm3 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm4 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm5 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+288-128(%rcx),%ymm13 + movq %r12,%r9 + vpaddq %ymm0,%ymm7,%ymm6 + vpmuludq %ymm11,%ymm12,%ymm12 + addq (%rsp),%r9 + vpaddq %ymm12,%ymm8,%ymm7 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovq %r12,%xmm12 + vpaddq %ymm13,%ymm9,%ymm8 + + decl %r14d + jnz L$oop_mul_1024 + vpaddq (%rsp),%ymm12,%ymm0 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm10,%ymm10 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpermq $0x93,%ymm11,%ymm11 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm10,%ymm10 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vmovdqu %ymm0,0-128(%rdi) + vmovdqu %ymm1,32-128(%rdi) + vmovdqu %ymm2,64-128(%rdi) + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vmovdqu %ymm4,128-128(%rdi) + vmovdqu %ymm5,160-128(%rdi) + vmovdqu %ymm6,192-128(%rdi) + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + vzeroupper + + movq %rbp,%rax + + movq -48(%rax),%r15 + + movq -40(%rax),%r14 + + movq -32(%rax),%r13 + + movq -24(%rax),%r12 + + movq -16(%rax),%rbp + + movq -8(%rax),%rbx + + leaq (%rax),%rsp + +L$mul_1024_epilogue: + .byte 0xf3,0xc3 + + +.globl _rsaz_1024_red2norm_avx2 +.private_extern _rsaz_1024_red2norm_avx2 + +.p2align 5 +_rsaz_1024_red2norm_avx2: + + subq $-128,%rsi + xorq %rax,%rax + movq -128(%rsi),%r8 + movq -120(%rsi),%r9 + movq -112(%rsi),%r10 + shlq $0,%r8 + shlq $29,%r9 + movq %r10,%r11 + shlq $58,%r10 + shrq $6,%r11 + addq %r8,%rax + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,0(%rdi) + movq %r11,%rax + movq -104(%rsi),%r8 + movq -96(%rsi),%r9 + shlq $23,%r8 + movq %r9,%r10 + shlq $52,%r9 + shrq $12,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,8(%rdi) + movq %r10,%rax + movq -88(%rsi),%r11 + movq -80(%rsi),%r8 + shlq $17,%r11 + movq %r8,%r9 + shlq $46,%r8 + shrq $18,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,16(%rdi) + movq %r9,%rax + movq -72(%rsi),%r10 + movq -64(%rsi),%r11 + shlq $11,%r10 + movq %r11,%r8 + shlq $40,%r11 + shrq $24,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,24(%rdi) + movq %r8,%rax + movq -56(%rsi),%r9 + movq -48(%rsi),%r10 + movq -40(%rsi),%r11 + shlq $5,%r9 + shlq $34,%r10 + movq %r11,%r8 + shlq $63,%r11 + shrq $1,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,32(%rdi) + movq %r8,%rax + movq -32(%rsi),%r9 + movq -24(%rsi),%r10 + shlq $28,%r9 + movq %r10,%r11 + shlq $57,%r10 + shrq $7,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,40(%rdi) + movq %r11,%rax + movq -16(%rsi),%r8 + movq -8(%rsi),%r9 + shlq $22,%r8 + movq %r9,%r10 + shlq $51,%r9 + shrq $13,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,48(%rdi) + movq %r10,%rax + movq 0(%rsi),%r11 + movq 8(%rsi),%r8 + shlq $16,%r11 + movq %r8,%r9 + shlq $45,%r8 + shrq $19,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,56(%rdi) + movq %r9,%rax + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + shlq $10,%r10 + movq %r11,%r8 + shlq $39,%r11 + shrq $25,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,64(%rdi) + movq %r8,%rax + movq 32(%rsi),%r9 + movq 40(%rsi),%r10 + movq 48(%rsi),%r11 + shlq $4,%r9 + shlq $33,%r10 + movq %r11,%r8 + shlq $62,%r11 + shrq $2,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,72(%rdi) + movq %r8,%rax + movq 56(%rsi),%r9 + movq 64(%rsi),%r10 + shlq $27,%r9 + movq %r10,%r11 + shlq $56,%r10 + shrq $8,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,80(%rdi) + movq %r11,%rax + movq 72(%rsi),%r8 + movq 80(%rsi),%r9 + shlq $21,%r8 + movq %r9,%r10 + shlq $50,%r9 + shrq $14,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,88(%rdi) + movq %r10,%rax + movq 88(%rsi),%r11 + movq 96(%rsi),%r8 + shlq $15,%r11 + movq %r8,%r9 + shlq $44,%r8 + shrq $20,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,96(%rdi) + movq %r9,%rax + movq 104(%rsi),%r10 + movq 112(%rsi),%r11 + shlq $9,%r10 + movq %r11,%r8 + shlq $38,%r11 + shrq $26,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,104(%rdi) + movq %r8,%rax + movq 120(%rsi),%r9 + movq 128(%rsi),%r10 + movq 136(%rsi),%r11 + shlq $3,%r9 + shlq $32,%r10 + movq %r11,%r8 + shlq $61,%r11 + shrq $3,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,112(%rdi) + movq %r8,%rax + movq 144(%rsi),%r9 + movq 152(%rsi),%r10 + shlq $26,%r9 + movq %r10,%r11 + shlq $55,%r10 + shrq $9,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,120(%rdi) + movq %r11,%rax + .byte 0xf3,0xc3 + + + +.globl _rsaz_1024_norm2red_avx2 +.private_extern _rsaz_1024_norm2red_avx2 + +.p2align 5 +_rsaz_1024_norm2red_avx2: + + subq $-128,%rdi + movq (%rsi),%r8 + movl $0x1fffffff,%eax + movq 8(%rsi),%r9 + movq %r8,%r11 + shrq $0,%r11 + andq %rax,%r11 + movq %r11,-128(%rdi) + movq %r8,%r10 + shrq $29,%r10 + andq %rax,%r10 + movq %r10,-120(%rdi) + shrdq $58,%r9,%r8 + andq %rax,%r8 + movq %r8,-112(%rdi) + movq 16(%rsi),%r10 + movq %r9,%r8 + shrq $23,%r8 + andq %rax,%r8 + movq %r8,-104(%rdi) + shrdq $52,%r10,%r9 + andq %rax,%r9 + movq %r9,-96(%rdi) + movq 24(%rsi),%r11 + movq %r10,%r9 + shrq $17,%r9 + andq %rax,%r9 + movq %r9,-88(%rdi) + shrdq $46,%r11,%r10 + andq %rax,%r10 + movq %r10,-80(%rdi) + movq 32(%rsi),%r8 + movq %r11,%r10 + shrq $11,%r10 + andq %rax,%r10 + movq %r10,-72(%rdi) + shrdq $40,%r8,%r11 + andq %rax,%r11 + movq %r11,-64(%rdi) + movq 40(%rsi),%r9 + movq %r8,%r11 + shrq $5,%r11 + andq %rax,%r11 + movq %r11,-56(%rdi) + movq %r8,%r10 + shrq $34,%r10 + andq %rax,%r10 + movq %r10,-48(%rdi) + shrdq $63,%r9,%r8 + andq %rax,%r8 + movq %r8,-40(%rdi) + movq 48(%rsi),%r10 + movq %r9,%r8 + shrq $28,%r8 + andq %rax,%r8 + movq %r8,-32(%rdi) + shrdq $57,%r10,%r9 + andq %rax,%r9 + movq %r9,-24(%rdi) + movq 56(%rsi),%r11 + movq %r10,%r9 + shrq $22,%r9 + andq %rax,%r9 + movq %r9,-16(%rdi) + shrdq $51,%r11,%r10 + andq %rax,%r10 + movq %r10,-8(%rdi) + movq 64(%rsi),%r8 + movq %r11,%r10 + shrq $16,%r10 + andq %rax,%r10 + movq %r10,0(%rdi) + shrdq $45,%r8,%r11 + andq %rax,%r11 + movq %r11,8(%rdi) + movq 72(%rsi),%r9 + movq %r8,%r11 + shrq $10,%r11 + andq %rax,%r11 + movq %r11,16(%rdi) + shrdq $39,%r9,%r8 + andq %rax,%r8 + movq %r8,24(%rdi) + movq 80(%rsi),%r10 + movq %r9,%r8 + shrq $4,%r8 + andq %rax,%r8 + movq %r8,32(%rdi) + movq %r9,%r11 + shrq $33,%r11 + andq %rax,%r11 + movq %r11,40(%rdi) + shrdq $62,%r10,%r9 + andq %rax,%r9 + movq %r9,48(%rdi) + movq 88(%rsi),%r11 + movq %r10,%r9 + shrq $27,%r9 + andq %rax,%r9 + movq %r9,56(%rdi) + shrdq $56,%r11,%r10 + andq %rax,%r10 + movq %r10,64(%rdi) + movq 96(%rsi),%r8 + movq %r11,%r10 + shrq $21,%r10 + andq %rax,%r10 + movq %r10,72(%rdi) + shrdq $50,%r8,%r11 + andq %rax,%r11 + movq %r11,80(%rdi) + movq 104(%rsi),%r9 + movq %r8,%r11 + shrq $15,%r11 + andq %rax,%r11 + movq %r11,88(%rdi) + shrdq $44,%r9,%r8 + andq %rax,%r8 + movq %r8,96(%rdi) + movq 112(%rsi),%r10 + movq %r9,%r8 + shrq $9,%r8 + andq %rax,%r8 + movq %r8,104(%rdi) + shrdq $38,%r10,%r9 + andq %rax,%r9 + movq %r9,112(%rdi) + movq 120(%rsi),%r11 + movq %r10,%r9 + shrq $3,%r9 + andq %rax,%r9 + movq %r9,120(%rdi) + movq %r10,%r8 + shrq $32,%r8 + andq %rax,%r8 + movq %r8,128(%rdi) + shrdq $61,%r11,%r10 + andq %rax,%r10 + movq %r10,136(%rdi) + xorq %r8,%r8 + movq %r11,%r10 + shrq $26,%r10 + andq %rax,%r10 + movq %r10,144(%rdi) + shrdq $55,%r8,%r11 + andq %rax,%r11 + movq %r11,152(%rdi) + movq %r8,160(%rdi) + movq %r8,168(%rdi) + movq %r8,176(%rdi) + movq %r8,184(%rdi) + .byte 0xf3,0xc3 + + +.globl _rsaz_1024_scatter5_avx2 +.private_extern _rsaz_1024_scatter5_avx2 + +.p2align 5 +_rsaz_1024_scatter5_avx2: + + vzeroupper + vmovdqu L$scatter_permd(%rip),%ymm5 + shll $4,%edx + leaq (%rdi,%rdx,1),%rdi + movl $9,%eax + jmp L$oop_scatter_1024 + +.p2align 5 +L$oop_scatter_1024: + vmovdqu (%rsi),%ymm0 + leaq 32(%rsi),%rsi + vpermd %ymm0,%ymm5,%ymm0 + vmovdqu %xmm0,(%rdi) + leaq 512(%rdi),%rdi + decl %eax + jnz L$oop_scatter_1024 + + vzeroupper + .byte 0xf3,0xc3 + + + +.globl _rsaz_1024_gather5_avx2 +.private_extern _rsaz_1024_gather5_avx2 + +.p2align 5 +_rsaz_1024_gather5_avx2: + + vzeroupper + movq %rsp,%r11 + + leaq -256(%rsp),%rsp + andq $-32,%rsp + leaq L$inc(%rip),%r10 + leaq -128(%rsp),%rax + + vmovd %edx,%xmm4 + vmovdqa (%r10),%ymm0 + vmovdqa 32(%r10),%ymm1 + vmovdqa 64(%r10),%ymm5 + vpbroadcastd %xmm4,%ymm4 + + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,0+128(%rax) + vpaddd %ymm5,%ymm2,%ymm0 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,32+128(%rax) + vpaddd %ymm5,%ymm3,%ymm1 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,64+128(%rax) + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vmovdqa %ymm3,96+128(%rax) + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,128+128(%rax) + vpaddd %ymm5,%ymm2,%ymm8 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,160+128(%rax) + vpaddd %ymm5,%ymm3,%ymm9 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,192+128(%rax) + vpaddd %ymm5,%ymm8,%ymm10 + vpcmpeqd %ymm4,%ymm8,%ymm8 + vmovdqa %ymm3,224+128(%rax) + vpaddd %ymm5,%ymm9,%ymm11 + vpcmpeqd %ymm4,%ymm9,%ymm9 + vpaddd %ymm5,%ymm10,%ymm12 + vpcmpeqd %ymm4,%ymm10,%ymm10 + vpaddd %ymm5,%ymm11,%ymm13 + vpcmpeqd %ymm4,%ymm11,%ymm11 + vpaddd %ymm5,%ymm12,%ymm14 + vpcmpeqd %ymm4,%ymm12,%ymm12 + vpaddd %ymm5,%ymm13,%ymm15 + vpcmpeqd %ymm4,%ymm13,%ymm13 + vpcmpeqd %ymm4,%ymm14,%ymm14 + vpcmpeqd %ymm4,%ymm15,%ymm15 + + vmovdqa -32(%r10),%ymm7 + leaq 128(%rsi),%rsi + movl $9,%edx + +L$oop_gather_1024: + vmovdqa 0-128(%rsi),%ymm0 + vmovdqa 32-128(%rsi),%ymm1 + vmovdqa 64-128(%rsi),%ymm2 + vmovdqa 96-128(%rsi),%ymm3 + vpand 0+128(%rax),%ymm0,%ymm0 + vpand 32+128(%rax),%ymm1,%ymm1 + vpand 64+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm1,%ymm4 + vpand 96+128(%rax),%ymm3,%ymm3 + vmovdqa 128-128(%rsi),%ymm0 + vmovdqa 160-128(%rsi),%ymm1 + vpor %ymm2,%ymm3,%ymm5 + vmovdqa 192-128(%rsi),%ymm2 + vmovdqa 224-128(%rsi),%ymm3 + vpand 128+128(%rax),%ymm0,%ymm0 + vpand 160+128(%rax),%ymm1,%ymm1 + vpand 192+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm4,%ymm4 + vpand 224+128(%rax),%ymm3,%ymm3 + vpand 256-128(%rsi),%ymm8,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 288-128(%rsi),%ymm9,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 320-128(%rsi),%ymm10,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 352-128(%rsi),%ymm11,%ymm3 + vpor %ymm0,%ymm4,%ymm4 + vpand 384-128(%rsi),%ymm12,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 416-128(%rsi),%ymm13,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 448-128(%rsi),%ymm14,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 480-128(%rsi),%ymm15,%ymm3 + leaq 512(%rsi),%rsi + vpor %ymm0,%ymm4,%ymm4 + vpor %ymm1,%ymm5,%ymm5 + vpor %ymm2,%ymm4,%ymm4 + vpor %ymm3,%ymm5,%ymm5 + + vpor %ymm5,%ymm4,%ymm4 + vextracti128 $1,%ymm4,%xmm5 + vpor %xmm4,%xmm5,%xmm5 + vpermd %ymm5,%ymm7,%ymm5 + vmovdqu %ymm5,(%rdi) + leaq 32(%rdi),%rdi + decl %edx + jnz L$oop_gather_1024 + + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + vzeroupper + leaq (%r11),%rsp + + .byte 0xf3,0xc3 + +L$SEH_end_rsaz_1024_gather5: + +.p2align 6 +L$and_mask: +.quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff +L$scatter_permd: +.long 0,2,4,6,7,7,7,7 +L$gather_permd: +.long 0,7,1,7,2,7,3,7 +L$inc: +.long 0,0,0,0, 1,1,1,1 +.long 2,2,2,2, 3,3,3,3 +.long 4,4,4,4, 4,4,4,4 +.p2align 6 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/fips.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/fips.c new file mode 100644 index 00000000..c9d5b23f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/fips.c @@ -0,0 +1,118 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include "../../internal.h" +#include "../delocate.h" + + +int FIPS_mode(void) { +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) + return 1; +#else + return 0; +#endif +} + +int FIPS_mode_set(int on) { return on == FIPS_mode(); } + +uint32_t FIPS_version(void) { + return 0; +} + +int FIPS_query_algorithm_status(const char *algorithm) { +#if defined(BORINGSSL_FIPS) + static const char kApprovedAlgorithms[][13] = { + "AES-CBC", + "AES-CCM", + "AES-CTR", + "AES-ECB", + "AES-GCM", + "AES-KW", + "AES-KWP", + "ctrDRBG", + "ECC-SSC", + "ECDSA-sign", + "ECDSA-verify", + "FFC-SSC", + "HMAC", + "RSA-sign", + "RSA-verify", + "SHA-1", + "SHA2-224", + "SHA2-256", + "SHA2-384", + "SHA2-512", + "SHA2-512/256", + }; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kApprovedAlgorithms); i++) { + if (strcmp(algorithm, kApprovedAlgorithms[i]) == 0) { + return 1; + } + } +#endif // BORINGSSL_FIPS + + return 0; +} + +#if defined(BORINGSSL_FIPS_COUNTERS) + +size_t FIPS_read_counter(enum fips_counter_t counter) { + if (counter < 0 || counter > fips_counter_max) { + abort(); + } + + const size_t *array = + CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS); + if (!array) { + return 0; + } + + return array[counter]; +} + +void boringssl_fips_inc_counter(enum fips_counter_t counter) { + if (counter < 0 || counter > fips_counter_max) { + abort(); + } + + size_t *array = + CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS); + if (!array) { + const size_t num_bytes = sizeof(size_t) * (fips_counter_max + 1); + array = OPENSSL_malloc(num_bytes); + if (!array) { + return; + } + + OPENSSL_memset(array, 0, num_bytes); + if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_FIPS_COUNTERS, array, + OPENSSL_free)) { + // |OPENSSL_free| has already been called by |CRYPTO_set_thread_local|. + return; + } + } + + array[counter]++; +} + +#else + +size_t FIPS_read_counter(enum fips_counter_t counter) { return 0; } + +// boringssl_fips_inc_counter is a no-op, inline function in internal.h in this +// case. That should let the compiler optimise away the callsites. + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c new file mode 100644 index 00000000..1898f01f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c @@ -0,0 +1,966 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../internal.h" +#include "../dh/internal.h" +#include "../ec/internal.h" +#include "../ecdsa/internal.h" +#include "../rand/internal.h" +#include "../rsa/internal.h" +#include "../tls/internal.h" + + +// MSVC wants to put a NUL byte at the end of non-char arrays and so cannot +// compile the real logic. +#if defined(_MSC_VER) + +int BORINGSSL_self_test(void) { + return 0; +} + +#else + +static void hexdump(const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; i++) { + fprintf(stderr, "%02x", in[i]); + } +} + +static int check_test(const void *expected, const void *actual, + size_t expected_len, const char *name) { + if (OPENSSL_memcmp(actual, expected, expected_len) != 0) { + fprintf(stderr, "%s failed.\nExpected: ", name); + hexdump(expected, expected_len); + fprintf(stderr, "\nCalculated: "); + hexdump(actual, expected_len); + fprintf(stderr, "\n"); + fflush(stderr); + return 0; + } + return 1; +} + +static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) { + *out = BN_bin2bn(in, len, NULL); + return *out != NULL; +} + +static int serialize_ecdsa_sig(uint8_t *out, size_t out_len, + const ECDSA_SIG *sig) { + if ((out_len & 1) || // + !BN_bn2bin_padded(out, out_len / 2, sig->r) || + !BN_bn2bin_padded(out + out_len / 2, out_len / 2, sig->s)) { + return 0; + } + return 1; +} + +static ECDSA_SIG *parse_ecdsa_sig(const uint8_t *in, size_t in_len) { + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (!ret || // + (in_len & 1) || + BN_bin2bn(in, in_len/2, ret->r) == NULL || + BN_bin2bn(in + in_len/2, in_len/2, ret->s) == NULL) { + ECDSA_SIG_free(ret); + ret = NULL; + } + return ret; +} + +static RSA *self_test_rsa_key(void) { + static const uint8_t kN[] = { + 0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc, + 0xc9, 0xa2, 0xc2, 0x3a, 0xa6, 0x1d, 0xd8, 0xf0, 0x26, 0x5b, 0x38, 0x90, + 0x17, 0x48, 0x15, 0xce, 0x21, 0xcd, 0xd6, 0x62, 0x99, 0xe2, 0xd7, 0xda, + 0x40, 0x80, 0x3c, 0xad, 0x18, 0xb7, 0x26, 0xe9, 0x30, 0x8a, 0x23, 0x3f, + 0x68, 0x9a, 0x9c, 0x31, 0x34, 0x91, 0x99, 0x06, 0x11, 0x36, 0xb2, 0x9e, + 0x3a, 0xd0, 0xbc, 0xb9, 0x93, 0x4e, 0xb8, 0x72, 0xa1, 0x9f, 0xb6, 0x8c, + 0xd5, 0x17, 0x1f, 0x7e, 0xaa, 0x75, 0xbb, 0xdf, 0xa1, 0x70, 0x48, 0xc4, + 0xec, 0x9a, 0x51, 0xed, 0x41, 0xc9, 0x74, 0xc0, 0x3e, 0x1e, 0x85, 0x2f, + 0xbe, 0x34, 0xc7, 0x65, 0x34, 0x8b, 0x4d, 0x55, 0x4b, 0xe1, 0x45, 0x54, + 0x0d, 0x75, 0x7e, 0x89, 0x4d, 0x0c, 0xf6, 0x33, 0xe5, 0xfc, 0xfb, 0x56, + 0x1b, 0xf2, 0x39, 0x9d, 0xe0, 0xff, 0x55, 0xcf, 0x02, 0x05, 0xb9, 0x74, + 0xd2, 0x91, 0xfc, 0x87, 0xe1, 0xbb, 0x97, 0x2a, 0xe4, 0xdd, 0x20, 0xc0, + 0x38, 0x47, 0xc0, 0x76, 0x3f, 0xa1, 0x9b, 0x5c, 0x20, 0xff, 0xff, 0xc7, + 0x49, 0x3b, 0x4c, 0xaf, 0x99, 0xa6, 0x3e, 0x82, 0x5c, 0x58, 0x27, 0xce, + 0x01, 0x03, 0xc3, 0x16, 0x35, 0x20, 0xe9, 0xf0, 0x15, 0x7a, 0x41, 0xd5, + 0x1f, 0x52, 0xea, 0xdf, 0xad, 0x4c, 0xbb, 0x0d, 0xcb, 0x04, 0x91, 0xb0, + 0x95, 0xa8, 0xce, 0x25, 0xfd, 0xd2, 0x62, 0x47, 0x77, 0xee, 0x13, 0xf1, + 0x48, 0x72, 0x9e, 0xd9, 0x2d, 0xe6, 0x5f, 0xa4, 0xc6, 0x9e, 0x5a, 0xb2, + 0xc6, 0xa2, 0xf7, 0x0a, 0x16, 0x17, 0xae, 0x6b, 0x1c, 0x30, 0x7c, 0x63, + 0x08, 0x83, 0xe7, 0x43, 0xec, 0x54, 0x5e, 0x2c, 0x08, 0x0b, 0x5e, 0x46, + 0xa7, 0x10, 0x93, 0x43, 0x53, 0x4e, 0xe3, 0x16, 0x73, 0x55, 0xce, 0xf2, + 0x94, 0xc0, 0xbe, 0xb3, + }; + static const uint8_t kE[] = {0x01, 0x00, 0x01}; // 65537 + static const uint8_t kD[] = { + 0x2f, 0x2c, 0x1e, 0xd2, 0x3d, 0x2c, 0xb1, 0x9b, 0x21, 0x02, 0xce, 0xb8, + 0x95, 0x5f, 0x4f, 0xd9, 0x21, 0x38, 0x11, 0x36, 0xb0, 0x9a, 0x36, 0xab, + 0x97, 0x47, 0x75, 0xf7, 0x2e, 0xfd, 0x75, 0x1f, 0x58, 0x16, 0x9c, 0xf6, + 0x14, 0xe9, 0x8e, 0xa3, 0x69, 0x9d, 0x9d, 0x86, 0xfe, 0x5c, 0x1b, 0x3b, + 0x11, 0xf5, 0x55, 0x64, 0x77, 0xc4, 0xfc, 0x53, 0xaa, 0x8c, 0x78, 0x9f, + 0x75, 0xab, 0x20, 0x3a, 0xa1, 0x77, 0x37, 0x22, 0x02, 0x8e, 0x54, 0x8a, + 0x67, 0x1c, 0x5e, 0xe0, 0x3e, 0xd9, 0x44, 0x37, 0xd1, 0x29, 0xee, 0x56, + 0x6c, 0x30, 0x9a, 0x93, 0x4d, 0xd9, 0xdb, 0xc5, 0x03, 0x1a, 0x75, 0xcc, + 0x0f, 0xc2, 0x61, 0xb5, 0x6c, 0x62, 0x9f, 0xc6, 0xa8, 0xc7, 0x8a, 0x60, + 0x17, 0x11, 0x62, 0x4c, 0xef, 0x74, 0x31, 0x97, 0xad, 0x89, 0x2d, 0xe8, + 0x31, 0x1d, 0x8b, 0x58, 0x82, 0xe3, 0x03, 0x1a, 0x6b, 0xdf, 0x3f, 0x3e, + 0xa4, 0x27, 0x19, 0xef, 0x46, 0x7a, 0x90, 0xdf, 0xa7, 0xe7, 0xc9, 0x66, + 0xab, 0x41, 0x1d, 0x65, 0x78, 0x1c, 0x18, 0x40, 0x5c, 0xd6, 0x87, 0xb5, + 0xea, 0x29, 0x44, 0xb3, 0xf5, 0xb3, 0xd2, 0x4f, 0xce, 0x88, 0x78, 0x49, + 0x27, 0x4e, 0x0b, 0x30, 0x85, 0xfb, 0x73, 0xfd, 0x8b, 0x32, 0x15, 0xee, + 0x1f, 0xc9, 0x0e, 0x89, 0xb9, 0x43, 0x2f, 0xe9, 0x60, 0x8d, 0xda, 0xae, + 0x2b, 0x30, 0x99, 0xee, 0x88, 0x81, 0x20, 0x7b, 0x4a, 0xc3, 0x18, 0xf2, + 0x94, 0x02, 0x79, 0x94, 0xaa, 0x65, 0xd9, 0x1b, 0x45, 0x2a, 0xac, 0x6e, + 0x30, 0x48, 0x57, 0xea, 0xbe, 0x79, 0x7d, 0xfc, 0x67, 0xaa, 0x47, 0xc0, + 0xf7, 0x52, 0xfd, 0x0b, 0x63, 0x4e, 0x3d, 0x2e, 0xcc, 0x36, 0xa0, 0xdb, + 0x92, 0x0b, 0xa9, 0x1b, 0xeb, 0xc2, 0xd5, 0x08, 0xd3, 0x85, 0x87, 0xf8, + 0x5d, 0x1a, 0xf6, 0xc1, + }; + static const uint8_t kP[] = { + 0xf7, 0x06, 0xa3, 0x98, 0x8a, 0x52, 0xf8, 0x63, 0x68, 0x27, 0x4f, 0x68, + 0x7f, 0x34, 0xec, 0x8e, 0x5d, 0xf8, 0x30, 0x92, 0xb3, 0x62, 0x4c, 0xeb, + 0xdb, 0x19, 0x6b, 0x09, 0xc5, 0xa3, 0xf0, 0xbb, 0xff, 0x0f, 0xc2, 0xd4, + 0x9b, 0xc9, 0x54, 0x4f, 0xb9, 0xf9, 0xe1, 0x4c, 0xf0, 0xe3, 0x4c, 0x90, + 0xda, 0x7a, 0x01, 0xc2, 0x9f, 0xc4, 0xc8, 0x8e, 0xb1, 0x1e, 0x93, 0x75, + 0x75, 0xc6, 0x13, 0x25, 0xc3, 0xee, 0x3b, 0xcc, 0xb8, 0x72, 0x6c, 0x49, + 0xb0, 0x09, 0xfb, 0xab, 0x44, 0xeb, 0x4d, 0x40, 0xf0, 0x61, 0x6b, 0xe5, + 0xe6, 0xfe, 0x3e, 0x0a, 0x77, 0x26, 0x39, 0x76, 0x3d, 0x4c, 0x3e, 0x9b, + 0x5b, 0xc0, 0xaf, 0xa2, 0x58, 0x76, 0xb0, 0xe9, 0xda, 0x7f, 0x0e, 0x78, + 0xc9, 0x76, 0x49, 0x5c, 0xfa, 0xb3, 0xb0, 0x15, 0x4b, 0x41, 0xc7, 0x27, + 0xa4, 0x75, 0x28, 0x5c, 0x30, 0x69, 0x50, 0x29, + }; + static const uint8_t kQ[] = { + 0xda, 0xe6, 0xd2, 0xbb, 0x44, 0xff, 0x4f, 0xdf, 0x57, 0xc1, 0x11, 0xa3, + 0x51, 0xba, 0x17, 0x89, 0x4c, 0x01, 0xc0, 0x0c, 0x97, 0x34, 0x50, 0xcf, + 0x32, 0x1e, 0xc0, 0xbd, 0x7b, 0x35, 0xb5, 0x6a, 0x26, 0xcc, 0xea, 0x4c, + 0x8e, 0x87, 0x4a, 0x67, 0x8b, 0xd3, 0xe5, 0x4f, 0x3a, 0x60, 0x48, 0x59, + 0x04, 0x93, 0x39, 0xd7, 0x7c, 0xfb, 0x19, 0x1a, 0x34, 0xd5, 0xe8, 0xaf, + 0xe7, 0x22, 0x2c, 0x0d, 0xc2, 0x91, 0x69, 0xb6, 0xe9, 0x2a, 0xe9, 0x1c, + 0x4c, 0x6e, 0x8f, 0x40, 0xf5, 0xa8, 0x3e, 0x82, 0x69, 0x69, 0xbe, 0x9f, + 0x7d, 0x5c, 0x7f, 0x92, 0x78, 0x17, 0xa3, 0x6d, 0x41, 0x2d, 0x72, 0xed, + 0x3f, 0x71, 0xfa, 0x97, 0xb4, 0x63, 0xe4, 0x4f, 0xd9, 0x46, 0x03, 0xfb, + 0x00, 0xeb, 0x30, 0x70, 0xb9, 0x51, 0xd9, 0x0a, 0xd2, 0xf8, 0x50, 0xd4, + 0xfb, 0x43, 0x84, 0xf8, 0xac, 0x58, 0xc3, 0x7b, + }; + static const uint8_t kDModPMinusOne[] = { + 0xf5, 0x50, 0x8f, 0x88, 0x7d, 0xdd, 0xb5, 0xb4, 0x2a, 0x8b, 0xd7, 0x4d, + 0x23, 0xfe, 0xaf, 0xe9, 0x16, 0x22, 0xd2, 0x41, 0xed, 0x88, 0xf2, 0x70, + 0xcb, 0x4d, 0xeb, 0xc1, 0x71, 0x97, 0xc4, 0x0b, 0x3e, 0x5a, 0x2d, 0x96, + 0xab, 0xfa, 0xfd, 0x12, 0x8b, 0xd3, 0x3e, 0x4e, 0x05, 0x6f, 0x04, 0xeb, + 0x59, 0x3c, 0x0e, 0xa1, 0x73, 0xbe, 0x9d, 0x99, 0x2f, 0x05, 0xf9, 0x54, + 0x8d, 0x98, 0x1e, 0x0d, 0xc4, 0x0c, 0xc3, 0x30, 0x23, 0xff, 0xe5, 0xd0, + 0x2b, 0xd5, 0x4e, 0x2b, 0xa0, 0xae, 0xb8, 0x32, 0x84, 0x45, 0x8b, 0x3c, + 0x6d, 0xf0, 0x10, 0x36, 0x9e, 0x6a, 0xc4, 0x67, 0xca, 0xa9, 0xfc, 0x06, + 0x96, 0xd0, 0xbc, 0xda, 0xd1, 0x55, 0x55, 0x8d, 0x77, 0x21, 0xf4, 0x82, + 0x39, 0x37, 0x91, 0xd5, 0x97, 0x56, 0x78, 0xc8, 0x3c, 0xcb, 0x5e, 0xf6, + 0xdc, 0x58, 0x48, 0xb3, 0x7c, 0x94, 0x29, 0x39, + }; + static const uint8_t kDModQMinusOne[] = { + 0x64, 0x65, 0xbd, 0x7d, 0x1a, 0x96, 0x26, 0xa1, 0xfe, 0xf3, 0x94, 0x0d, + 0x5d, 0xec, 0x85, 0xe2, 0xf8, 0xb3, 0x4c, 0xcb, 0xf9, 0x85, 0x8b, 0x12, + 0x9c, 0xa0, 0x32, 0x32, 0x35, 0x92, 0x5a, 0x94, 0x47, 0x1b, 0x70, 0xd2, + 0x90, 0x04, 0x49, 0x01, 0xd8, 0xc5, 0xe4, 0xc4, 0x43, 0xb7, 0xe9, 0x36, + 0xba, 0xbc, 0x73, 0xa8, 0xfb, 0xaf, 0x86, 0xc1, 0xd8, 0x3d, 0xcb, 0xac, + 0xf1, 0xcb, 0x60, 0x7d, 0x27, 0x21, 0xde, 0x64, 0x7f, 0xe8, 0xa8, 0x65, + 0xcc, 0x40, 0x60, 0xff, 0xa0, 0x2b, 0xfc, 0x0f, 0x80, 0x1d, 0x79, 0xca, + 0x58, 0x8a, 0xd6, 0x0f, 0xed, 0x78, 0x9a, 0x02, 0x00, 0x04, 0xc2, 0x53, + 0x41, 0xe8, 0x1a, 0xd0, 0xfd, 0x71, 0x5b, 0x43, 0xac, 0x19, 0x4a, 0xb6, + 0x12, 0xa3, 0xcb, 0xe1, 0xc7, 0x7d, 0x5c, 0x98, 0x74, 0x4e, 0x63, 0x74, + 0x6b, 0x91, 0x7a, 0x29, 0x3b, 0x92, 0xb2, 0x85, + }; + static const uint8_t kQInverseModP[] = { + 0xd0, 0xde, 0x19, 0xda, 0x1e, 0xa2, 0xd8, 0x8f, 0x1c, 0x92, 0x73, 0xb0, + 0xc9, 0x90, 0xc7, 0xf5, 0xec, 0xc5, 0x89, 0x01, 0x05, 0x78, 0x11, 0x2d, + 0x74, 0x34, 0x44, 0xad, 0xd5, 0xf7, 0xa4, 0xfe, 0x9f, 0x25, 0x4d, 0x0b, + 0x92, 0xe3, 0xb8, 0x7d, 0xd3, 0xfd, 0xa5, 0xca, 0x95, 0x60, 0xa3, 0xf9, + 0x55, 0x42, 0x14, 0xb2, 0x45, 0x51, 0x9f, 0x73, 0x88, 0x43, 0x8a, 0xd1, + 0x65, 0x9e, 0xd1, 0xf7, 0x82, 0x2a, 0x2a, 0x8d, 0x70, 0x56, 0xe3, 0xef, + 0xc9, 0x0e, 0x2a, 0x2c, 0x15, 0xaf, 0x7f, 0x97, 0x81, 0x66, 0xf3, 0xb5, + 0x00, 0xa9, 0x26, 0xcc, 0x1e, 0xc2, 0x98, 0xdd, 0xd3, 0x37, 0x06, 0x79, + 0xb3, 0x60, 0x58, 0x79, 0x99, 0x3f, 0xa3, 0x15, 0x1f, 0x31, 0xe3, 0x11, + 0x88, 0x4c, 0x35, 0x57, 0xfa, 0x79, 0xd7, 0xd8, 0x72, 0xee, 0x73, 0x95, + 0x89, 0x29, 0xc7, 0x05, 0x27, 0x68, 0x90, 0x15, + }; + + RSA *rsa = RSA_new(); + if (rsa == NULL || + !set_bignum(&rsa->n, kN, sizeof(kN)) || + !set_bignum(&rsa->e, kE, sizeof(kE)) || + !set_bignum(&rsa->d, kD, sizeof(kD)) || + !set_bignum(&rsa->p, kP, sizeof(kP)) || + !set_bignum(&rsa->q, kQ, sizeof(kQ)) || + !set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) || + !set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) || + !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +static EC_KEY *self_test_ecdsa_key(void) { + static const uint8_t kQx[] = { + 0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17, + 0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2, + 0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81, + }; + static const uint8_t kQy[] = { + 0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef, + 0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac, + 0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88, + }; + static const uint8_t kD[] = { + 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, + 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, + 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, + }; + + EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL); + BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL); + BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL); + if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL || + !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) || + !EC_KEY_set_private_key(ec_key, d)) { + EC_KEY_free(ec_key); + ec_key = NULL; + } + + BN_free(qx); + BN_free(qy); + BN_free(d); + return ec_key; +} + +static DH *self_test_dh(void) { + DH *dh = DH_get_rfc7919_2048(); + if (!dh) { + return NULL; + } + + BIGNUM *priv = BN_new(); + if (!priv) { + goto err; + } + + // kFFDHE2048PrivateKeyData is a 225-bit value. (225 because that's the + // minimum private key size in + // https://tools.ietf.org/html/rfc7919#appendix-A.1.) + static const BN_ULONG kFFDHE2048PrivateKeyData[] = { + TOBN(0x187be36b, 0xd38a4fa1), + TOBN(0x0a152f39, 0x6458f3b8), + TOBN(0x0570187e, 0xc422eeb7), + TOBN(0x00000001, 0x91173f2a), + }; + + bn_set_static_words(priv, kFFDHE2048PrivateKeyData, + OPENSSL_ARRAY_SIZE(kFFDHE2048PrivateKeyData)); + + if (!DH_set0_key(dh, NULL, priv)) { + goto err; + } + return dh; + +err: + BN_free(priv); + DH_free(dh); + return NULL; +} + + +// Lazy self-tests +// +// Self tests that are slow are deferred until the corresponding algorithm is +// actually exercised, in FIPS mode. (In non-FIPS mode these tests are only run +// when requested by |BORINGSSL_self_test|.) + +static int boringssl_self_test_rsa(void) { + int ret = 0; + uint8_t output[256]; + + RSA *const rsa_key = self_test_rsa_key(); + if (rsa_key == NULL) { + fprintf(stderr, "RSA key construction failed\n"); + goto err; + } + + // RSA Sign KAT + + static const uint8_t kRSASignDigest[32] = { + 0xd2, 0xb5, 0x6e, 0x53, 0x30, 0x6f, 0x72, 0x0d, 0x79, 0x29, 0xd8, + 0x70, 0x8b, 0xf4, 0x6f, 0x1c, 0x22, 0x30, 0x03, 0x05, 0x58, 0x2b, + 0x11, 0x5b, 0xed, 0xca, 0xc7, 0x22, 0xd8, 0xaa, 0x5a, 0xb2, + }; + static const uint8_t kRSASignSignature[256] = { + 0x64, 0xce, 0xdd, 0x91, 0x27, 0xb0, 0x4f, 0xb9, 0x14, 0xea, 0xc0, 0xb4, + 0xa2, 0x06, 0xc5, 0xd8, 0x40, 0x0f, 0x6c, 0x54, 0xac, 0xf7, 0x02, 0xde, + 0x26, 0xbb, 0xfd, 0x33, 0xe5, 0x2f, 0x4d, 0xb1, 0x53, 0xc4, 0xff, 0xd0, + 0x5f, 0xea, 0x15, 0x89, 0x83, 0x4c, 0xe3, 0x80, 0x0b, 0xe9, 0x13, 0x82, + 0x1d, 0x71, 0x92, 0x1a, 0x03, 0x60, 0x2c, 0xaf, 0xe2, 0x16, 0xc7, 0x43, + 0x3f, 0xde, 0x6b, 0x94, 0xfd, 0x6e, 0x08, 0x7b, 0x11, 0xf1, 0x34, 0x52, + 0xe5, 0xc0, 0x97, 0x66, 0x4a, 0xe0, 0x91, 0x45, 0xc8, 0xb1, 0x3d, 0x6a, + 0x54, 0xc1, 0x32, 0x0f, 0x32, 0xad, 0x25, 0x11, 0x3e, 0x49, 0xad, 0x41, + 0xce, 0x7b, 0xca, 0x95, 0x6b, 0x54, 0x5e, 0x86, 0x1b, 0xce, 0xfa, 0x2a, + 0x60, 0xe8, 0xfa, 0xbb, 0x23, 0xb2, 0x41, 0xbc, 0x7c, 0x98, 0xec, 0x73, + 0x20, 0xed, 0xb3, 0xcf, 0xab, 0x07, 0x24, 0x85, 0x6a, 0x2a, 0x61, 0x76, + 0x28, 0xf8, 0x00, 0x80, 0xeb, 0xd9, 0x3a, 0x63, 0xe2, 0x01, 0xb1, 0xee, + 0x6d, 0xe9, 0x73, 0xe9, 0xb6, 0x75, 0x2e, 0xf9, 0x81, 0xd9, 0xa8, 0x79, + 0xf6, 0x8f, 0xe3, 0x02, 0x7d, 0xf6, 0xea, 0xdc, 0x35, 0xe4, 0x62, 0x0d, + 0x91, 0xba, 0x3e, 0x7d, 0x8b, 0x82, 0xbf, 0x15, 0x74, 0x6a, 0x4e, 0x29, + 0xf8, 0x9b, 0x2c, 0x94, 0x8d, 0xa7, 0x00, 0x4d, 0x7b, 0xbf, 0x35, 0x07, + 0xeb, 0xdd, 0x10, 0xef, 0xd5, 0x2f, 0xe6, 0x98, 0x4b, 0x7e, 0x24, 0x80, + 0xe2, 0x01, 0xf2, 0x66, 0xb7, 0xd3, 0x93, 0xfe, 0x2a, 0xb3, 0x74, 0xed, + 0xec, 0x4b, 0xb1, 0x5f, 0x5f, 0xee, 0x85, 0x44, 0xa7, 0x26, 0xdf, 0xc1, + 0x2e, 0x7a, 0xf3, 0xa5, 0x8f, 0xf8, 0x64, 0xda, 0x65, 0xad, 0x91, 0xe2, + 0x90, 0x94, 0x20, 0x16, 0xb8, 0x61, 0xa5, 0x0a, 0x7d, 0xb4, 0xbf, 0xc0, + 0x10, 0xaf, 0x72, 0x67, + }; + + unsigned sig_len; + if (!rsa_sign_no_self_test(NID_sha256, kRSASignDigest, sizeof(kRSASignDigest), + output, &sig_len, rsa_key) || + !check_test(kRSASignSignature, output, sizeof(kRSASignSignature), + "RSA-sign KAT")) { + fprintf(stderr, "RSA signing test failed.\n"); + goto err; + } + + // RSA Verify KAT + + static const uint8_t kRSAVerifyDigest[32] = { + 0x09, 0x65, 0x2f, 0xd8, 0xed, 0x9d, 0xc2, 0x6d, 0xbc, 0xbf, 0xf2, + 0xa7, 0xa5, 0xed, 0xe1, 0x37, 0x13, 0x78, 0x21, 0x36, 0xcf, 0x8d, + 0x22, 0x3d, 0xab, 0x93, 0xb4, 0x12, 0xa8, 0xb5, 0x15, 0x53, + }; + static const uint8_t kRSAVerifySignature[256] = { + 0xab, 0xe2, 0xcb, 0xc1, 0x3d, 0x6b, 0xd3, 0x9d, 0x48, 0xdb, 0x53, 0x34, + 0xdd, 0xbf, 0x8d, 0x07, 0x0a, 0x93, 0xbd, 0xcb, 0x10, 0x4e, 0x2c, 0xc5, + 0xd0, 0xee, 0x48, 0x6e, 0xe2, 0x95, 0xf6, 0xb3, 0x1b, 0xda, 0x12, 0x6c, + 0x41, 0x89, 0x0b, 0x98, 0xb7, 0x3e, 0x70, 0xe6, 0xb6, 0x5d, 0x82, 0xf9, + 0x5c, 0x66, 0x31, 0x21, 0x75, 0x5a, 0x90, 0x74, 0x4c, 0x8d, 0x1c, 0x21, + 0x14, 0x8a, 0x19, 0x60, 0xbe, 0x0e, 0xca, 0x44, 0x6e, 0x9f, 0xf4, 0x97, + 0xf1, 0x34, 0x5c, 0x53, 0x7e, 0xf8, 0x11, 0x9b, 0x9a, 0x43, 0x98, 0xe9, + 0x5c, 0x5c, 0x6d, 0xe2, 0xb1, 0xc9, 0x55, 0x90, 0x5c, 0x52, 0x99, 0xd8, + 0xce, 0x7a, 0x3b, 0x6a, 0xb7, 0x63, 0x80, 0xd9, 0xba, 0xbd, 0xd1, 0x5f, + 0x61, 0x02, 0x37, 0xe1, 0xf3, 0xf2, 0xaa, 0x1c, 0x1f, 0x1e, 0x77, 0x0b, + 0x62, 0xfb, 0xb5, 0x96, 0x38, 0x1b, 0x2e, 0xbd, 0xd7, 0x7e, 0xce, 0xf9, + 0xc9, 0x0d, 0x4c, 0x92, 0xf7, 0xb6, 0xb0, 0x5f, 0xed, 0x29, 0x36, 0x28, + 0x5f, 0xa9, 0x48, 0x26, 0xe6, 0x20, 0x55, 0x32, 0x2a, 0x33, 0xb6, 0xf0, + 0x4c, 0x74, 0xce, 0x69, 0xe5, 0xd8, 0xd7, 0x37, 0xfb, 0x83, 0x8b, 0x79, + 0xd2, 0xd4, 0x8e, 0x3d, 0xaf, 0x71, 0x38, 0x75, 0x31, 0x88, 0x25, 0x31, + 0xa9, 0x5a, 0xc9, 0x64, 0xd0, 0x2e, 0xa4, 0x13, 0xbf, 0x85, 0x95, 0x29, + 0x82, 0xbb, 0xc0, 0x89, 0x52, 0x7d, 0xaf, 0xf5, 0xb8, 0x45, 0xc9, 0xa0, + 0xf4, 0xd1, 0x4e, 0xf1, 0x95, 0x6d, 0x9c, 0x3a, 0xca, 0xe8, 0x82, 0xd1, + 0x2d, 0xa6, 0x6d, 0xa0, 0xf3, 0x57, 0x94, 0xf5, 0xee, 0x32, 0x23, 0x23, + 0x33, 0x51, 0x7d, 0xb9, 0x31, 0x52, 0x32, 0xa1, 0x83, 0xb9, 0x91, 0x65, + 0x4d, 0xbe, 0xa4, 0x16, 0x15, 0x34, 0x5c, 0x88, 0x53, 0x25, 0x92, 0x67, + 0x44, 0xa5, 0x39, 0x15, + }; + if (!rsa_verify_no_self_test(NID_sha256, kRSAVerifyDigest, + sizeof(kRSAVerifyDigest), kRSAVerifySignature, + sizeof(kRSAVerifySignature), rsa_key)) { + fprintf(stderr, "RSA-verify KAT failed.\n"); + goto err; + } + + ret = 1; + +err: + RSA_free(rsa_key); + + return ret; +} + +static int boringssl_self_test_ecc(void) { + int ret = 0; + EC_KEY *ec_key = NULL; + EC_GROUP *ec_group = NULL; + EC_POINT *ec_point_in = NULL; + EC_POINT *ec_point_out = NULL; + BIGNUM *ec_scalar = NULL; + ECDSA_SIG *sig = NULL; + + ec_key = self_test_ecdsa_key(); + if (ec_key == NULL) { + fprintf(stderr, "ECDSA KeyGen failed\n"); + goto err; + } + + // ECDSA Sign/Verify KAT + + static const uint8_t kECDSASignDigest[32] = { + 0x1e, 0x35, 0x93, 0x0b, 0xe8, 0x60, 0xd0, 0x94, 0x2c, 0xa7, 0xbb, + 0xd6, 0xf6, 0xde, 0xd8, 0x7f, 0x15, 0x7e, 0x4d, 0xe2, 0x4f, 0x81, + 0xed, 0x4b, 0x87, 0x5c, 0x0e, 0x01, 0x8e, 0x89, 0xa8, 0x1f, + }; + static const uint8_t kECDSASignSig[64] = { + 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, + 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x68, + 0x04, 0x73, 0x40, 0x94, 0xb2, 0xd1, 0x90, 0xac, 0x2d, 0x0c, 0xd7, + 0xa5, 0x7f, 0x2f, 0x2e, 0xb2, 0x62, 0xb0, 0x09, 0x16, 0xe1, 0xa6, + 0x70, 0xb5, 0xbb, 0x0d, 0xfd, 0x8e, 0x0c, 0x02, 0x3f, + }; + + // The 'k' value for ECDSA is fixed to avoid an entropy draw. + uint8_t ecdsa_k[32] = {0}; + ecdsa_k[31] = 42; + + sig = ecdsa_sign_with_nonce_for_known_answer_test( + kECDSASignDigest, sizeof(kECDSASignDigest), ec_key, ecdsa_k, + sizeof(ecdsa_k)); + + uint8_t ecdsa_sign_output[64]; + if (sig == NULL || + !serialize_ecdsa_sig(ecdsa_sign_output, sizeof(ecdsa_sign_output), sig) || + !check_test(kECDSASignSig, ecdsa_sign_output, sizeof(ecdsa_sign_output), + "ECDSA-sign signature")) { + fprintf(stderr, "ECDSA-sign KAT failed.\n"); + goto err; + } + + static const uint8_t kECDSAVerifyDigest[32] = { + 0x78, 0x7c, 0x50, 0x5c, 0x60, 0xc9, 0xe4, 0x13, 0x6c, 0xe4, 0x48, + 0xba, 0x93, 0xff, 0x71, 0xfa, 0x9c, 0x18, 0xf4, 0x17, 0x09, 0x4f, + 0xdf, 0x5a, 0xe2, 0x75, 0xc0, 0xcc, 0xd2, 0x67, 0x97, 0xad, + }; + static const uint8_t kECDSAVerifySig[64] = { + 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, + 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x2d, + 0x36, 0xe5, 0x79, 0x97, 0x90, 0xbf, 0xbe, 0x21, 0x83, 0xd3, 0x3e, + 0x96, 0xf3, 0xc5, 0x1f, 0x6a, 0x23, 0x2f, 0x2a, 0x24, 0x48, 0x8c, + 0x8e, 0x5f, 0x64, 0xc3, 0x7e, 0xa2, 0xcf, 0x05, 0x29, + }; + + ECDSA_SIG_free(sig); + sig = parse_ecdsa_sig(kECDSAVerifySig, sizeof(kECDSAVerifySig)); + if (!sig || + !ecdsa_do_verify_no_self_test(kECDSAVerifyDigest, + sizeof(kECDSAVerifyDigest), sig, ec_key)) { + fprintf(stderr, "ECDSA-verify KAT failed.\n"); + goto err; + } + + // Primitive Z Computation KAT (IG 9.6). + + // kP256Point is SHA256("Primitive Z Computation KAT")×G within P-256. + static const uint8_t kP256Point[65] = { + 0x04, 0x4e, 0xc1, 0x94, 0x8c, 0x5c, 0xf4, 0x37, 0x35, 0x0d, 0xa3, + 0xf9, 0x55, 0xf9, 0x8b, 0x26, 0x23, 0x5c, 0x43, 0xe0, 0x83, 0x51, + 0x2b, 0x0d, 0x4b, 0x56, 0x24, 0xc3, 0xe4, 0xa5, 0xa8, 0xe2, 0xe9, + 0x95, 0xf2, 0xc4, 0xb9, 0xb7, 0x48, 0x7d, 0x2a, 0xae, 0xc5, 0xc0, + 0x0a, 0xcc, 0x1b, 0xd0, 0xec, 0xb8, 0xdc, 0xbe, 0x0c, 0xbe, 0x52, + 0x79, 0x93, 0x7c, 0x0b, 0x92, 0x2b, 0x7f, 0x17, 0xa5, 0x80, + }; + // kP256Scalar is SHA256("Primitive Z Computation KAT scalar"). + static const uint8_t kP256Scalar[32] = { + 0xe7, 0x60, 0x44, 0x91, 0x26, 0x9a, 0xfb, 0x5b, 0x10, 0x2d, 0x6e, + 0xa5, 0x2c, 0xb5, 0x9f, 0xeb, 0x70, 0xae, 0xde, 0x6c, 0xe3, 0xbf, + 0xb3, 0xe0, 0x10, 0x54, 0x85, 0xab, 0xd8, 0x61, 0xd7, 0x7b, + }; + // kP256PointResult is |kP256Scalar|×|kP256Point|. + static const uint8_t kP256PointResult[65] = { + 0x04, 0xf1, 0x63, 0x00, 0x88, 0xc5, 0xd5, 0xe9, 0x05, 0x52, 0xac, + 0xb6, 0xec, 0x68, 0x76, 0xb8, 0x73, 0x7f, 0x0f, 0x72, 0x34, 0xe6, + 0xbb, 0x30, 0x32, 0x22, 0x37, 0xb6, 0x2a, 0x80, 0xe8, 0x9e, 0x6e, + 0x6f, 0x36, 0x02, 0xe7, 0x21, 0xd2, 0x31, 0xdb, 0x94, 0x63, 0xb7, + 0xd8, 0x19, 0x0e, 0xc2, 0xc0, 0xa7, 0x2f, 0x15, 0x49, 0x1a, 0xa2, + 0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a, 0x0c, + }; + + ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (ec_group == NULL) { + fprintf(stderr, "Failed to create P-256 group.\n"); + goto err; + } + ec_point_in = EC_POINT_new(ec_group); + ec_point_out = EC_POINT_new(ec_group); + ec_scalar = BN_new(); + uint8_t z_comp_result[65]; + if (ec_point_in == NULL || ec_point_out == NULL || ec_scalar == NULL || + !EC_POINT_oct2point(ec_group, ec_point_in, kP256Point, sizeof(kP256Point), + NULL) || + !BN_bin2bn(kP256Scalar, sizeof(kP256Scalar), ec_scalar) || + !ec_point_mul_no_self_test(ec_group, ec_point_out, NULL, ec_point_in, + ec_scalar, NULL) || + !EC_POINT_point2oct(ec_group, ec_point_out, POINT_CONVERSION_UNCOMPRESSED, + z_comp_result, sizeof(z_comp_result), NULL) || + !check_test(kP256PointResult, z_comp_result, sizeof(z_comp_result), + "Z Computation Result")) { + fprintf(stderr, "Z-computation KAT failed.\n"); + goto err; + } + + ret = 1; + +err: + EC_KEY_free(ec_key); + EC_POINT_free(ec_point_in); + EC_POINT_free(ec_point_out); + EC_GROUP_free(ec_group); + BN_free(ec_scalar); + ECDSA_SIG_free(sig); + + return ret; +} + +static int boringssl_self_test_ffdh(void) { + int ret = 0; + DH *dh = NULL; + BIGNUM *ffdhe2048_value = NULL; + + // FFC Diffie-Hellman KAT + + // kFFDHE2048PublicValueData is an arbitrary public value, mod + // kFFDHE2048Data. (The private key happens to be 4096.) + static const BN_ULONG kFFDHE2048PublicValueData[] = { + TOBN(0x187be36b, 0xd38a4fa1), TOBN(0x0a152f39, 0x6458f3b8), + TOBN(0x0570187e, 0xc422eeb7), TOBN(0x18af7482, 0x91173f2a), + TOBN(0xe9fdac6a, 0xcff4eaaa), TOBN(0xf6afebb7, 0x6e589d6c), + TOBN(0xf92f8e9a, 0xb7e33fb0), TOBN(0x70acf2aa, 0x4cf36ddd), + TOBN(0x561ab426, 0xd07137fd), TOBN(0x5f57d037, 0x430ee91e), + TOBN(0xe3e768c8, 0x60d10b8a), TOBN(0xb14884d8, 0xa18af8ce), + TOBN(0xf8a98014, 0xa12b74e4), TOBN(0x748d407c, 0x3437b7a8), + TOBN(0x627588c4, 0x9875d5a7), TOBN(0xdd24a127, 0x53c8f09d), + TOBN(0x85a997d5, 0x0cd51aec), TOBN(0x44f0c619, 0xce348458), + TOBN(0x9b894b24, 0x5f6b69a1), TOBN(0xae1302f2, 0xf6d4777e), + TOBN(0xe6678eeb, 0x375db18e), TOBN(0x2674e1d6, 0x4fbcbdc8), + TOBN(0xb297a823, 0x6fa93d28), TOBN(0x6a12fb70, 0x7c8c0510), + TOBN(0x5c6d1aeb, 0xdb06f65b), TOBN(0xe8c2954e, 0x4c1804ca), + TOBN(0x06bdeac1, 0xf5500fa7), TOBN(0x6a315604, 0x189cd76b), + TOBN(0xbae7b0b3, 0x6e362dc0), TOBN(0xa57c73bd, 0xdc70fb82), + TOBN(0xfaff50d2, 0x9d573457), TOBN(0x352bd399, 0xbe84058e), + }; + static const uint8_t kDHOutput[2048 / 8] = { + 0x2a, 0xe6, 0xd3, 0xa6, 0x13, 0x58, 0x8e, 0xce, 0x53, 0xaa, 0xf6, 0x5d, + 0x9a, 0xae, 0x02, 0x12, 0xf5, 0x80, 0x3d, 0x06, 0x09, 0x76, 0xac, 0x57, + 0x37, 0x9e, 0xab, 0x38, 0x62, 0x25, 0x05, 0x1d, 0xf3, 0xa9, 0x39, 0x60, + 0xf6, 0xae, 0x90, 0xed, 0x1e, 0xad, 0x6e, 0xe9, 0xe3, 0xba, 0x27, 0xf6, + 0xdb, 0x54, 0xdf, 0xe2, 0xbd, 0xbb, 0x7f, 0xf1, 0x81, 0xac, 0x1a, 0xfa, + 0xdb, 0x87, 0x07, 0x98, 0x76, 0x90, 0x21, 0xf2, 0xae, 0xda, 0x0d, 0x84, + 0x97, 0x64, 0x0b, 0xbf, 0xb8, 0x8d, 0x10, 0x46, 0xe2, 0xd5, 0xca, 0x1b, + 0xbb, 0xe5, 0x37, 0xb2, 0x3b, 0x35, 0xd3, 0x1b, 0x65, 0xea, 0xae, 0xf2, + 0x03, 0xe2, 0xb6, 0xde, 0x22, 0xb7, 0x86, 0x49, 0x79, 0xfe, 0xd7, 0x16, + 0xf7, 0xdc, 0x9c, 0x59, 0xf5, 0xb7, 0x70, 0xc0, 0x53, 0x42, 0x6f, 0xb1, + 0xd2, 0x4e, 0x00, 0x25, 0x4b, 0x2d, 0x5a, 0x9b, 0xd0, 0xe9, 0x27, 0x43, + 0xcc, 0x00, 0x66, 0xea, 0x94, 0x7a, 0x0b, 0xb9, 0x89, 0x0c, 0x5e, 0x94, + 0xb8, 0x3a, 0x78, 0x9c, 0x4d, 0x84, 0xe6, 0x32, 0x2c, 0x38, 0x7c, 0xf7, + 0x43, 0x9c, 0xd8, 0xb8, 0x1c, 0xce, 0x24, 0x91, 0x20, 0x67, 0x7a, 0x54, + 0x1f, 0x7e, 0x86, 0x7f, 0xa1, 0xc1, 0x03, 0x4e, 0x2c, 0x26, 0x71, 0xb2, + 0x06, 0x30, 0xb3, 0x6c, 0x15, 0xcc, 0xac, 0x25, 0xe5, 0x37, 0x3f, 0x24, + 0x8f, 0x2a, 0x89, 0x5e, 0x3d, 0x43, 0x94, 0xc9, 0x36, 0xae, 0x40, 0x00, + 0x6a, 0x0d, 0xb0, 0x6e, 0x8b, 0x2e, 0x70, 0x57, 0xe1, 0x88, 0x53, 0xd6, + 0x06, 0x80, 0x2a, 0x4e, 0x5a, 0xf0, 0x1e, 0xaa, 0xcb, 0xab, 0x06, 0x0e, + 0x27, 0x0f, 0xd9, 0x88, 0xd9, 0x01, 0xe3, 0x07, 0xeb, 0xdf, 0xc3, 0x12, + 0xe3, 0x40, 0x88, 0x7b, 0x5f, 0x59, 0x78, 0x6e, 0x26, 0x20, 0xc3, 0xdf, + 0xc8, 0xe4, 0x5e, 0xb8, + }; + + ffdhe2048_value = BN_new(); + if (ffdhe2048_value) { + bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData, + OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData)); + } + + dh = self_test_dh(); + uint8_t dh_out[sizeof(kDHOutput)]; + if (dh == NULL || ffdhe2048_value == NULL || sizeof(dh_out) != DH_size(dh) || + dh_compute_key_padded_no_self_test(dh_out, ffdhe2048_value, dh) != + sizeof(dh_out) || + !check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH")) { + fprintf(stderr, "FFDH failed.\n"); + goto err; + } + + ret = 1; + +err: + DH_free(dh); + BN_free(ffdhe2048_value); + + return ret; +} + +#if defined(BORINGSSL_FIPS) + +static void run_self_test_rsa(void) { + if (!boringssl_self_test_rsa()) { + BORINGSSL_FIPS_abort(); + } +} + +DEFINE_STATIC_ONCE(g_self_test_once_rsa); + +void boringssl_ensure_rsa_self_test(void) { + CRYPTO_once(g_self_test_once_rsa_bss_get(), run_self_test_rsa); +} + +static void run_self_test_ecc(void) { + if (!boringssl_self_test_ecc()) { + BORINGSSL_FIPS_abort(); + } +} + +DEFINE_STATIC_ONCE(g_self_test_once_ecc); + +void boringssl_ensure_ecc_self_test(void) { + CRYPTO_once(g_self_test_once_ecc_bss_get(), run_self_test_ecc); +} + +static void run_self_test_ffdh(void) { + if (!boringssl_self_test_ffdh()) { + BORINGSSL_FIPS_abort(); + } +} + +DEFINE_STATIC_ONCE(g_self_test_once_ffdh); + +void boringssl_ensure_ffdh_self_test(void) { + CRYPTO_once(g_self_test_once_ffdh_bss_get(), run_self_test_ffdh); +} + +#endif // BORINGSSL_FIPS + + +// Startup self tests. +// +// These tests are run at process start when in FIPS mode. + +int boringssl_self_test_sha256(void) { + static const uint8_t kInput[16] = { + 0xff, 0x3b, 0x85, 0x7d, 0xa7, 0x23, 0x6a, 0x2b, + 0xaa, 0x0f, 0x39, 0x6b, 0x51, 0x52, 0x22, 0x17, + }; + static const uint8_t kPlaintextSHA256[32] = { + 0x7f, 0xe4, 0xd5, 0xf1, 0xa1, 0xe3, 0x82, 0x87, 0xd9, 0x58, 0xf5, + 0x11, 0xc7, 0x1d, 0x5e, 0x27, 0x5e, 0xcc, 0xd2, 0x66, 0xcf, 0xb9, + 0xc8, 0xc6, 0x60, 0xd8, 0x92, 0x1e, 0x57, 0xfd, 0x46, 0x75, + }; + uint8_t output[SHA256_DIGEST_LENGTH]; + + // SHA-256 KAT + SHA256(kInput, sizeof(kInput), output); + return check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), + "SHA-256 KAT"); +} + +int boringssl_self_test_sha512(void) { + static const uint8_t kInput[16] = { + 0x21, 0x25, 0x12, 0xf8, 0xd2, 0xad, 0x83, 0x22, + 0x78, 0x1c, 0x6c, 0x4d, 0x69, 0xa9, 0xda, 0xa1, + }; + static const uint8_t kPlaintextSHA512[64] = { + 0x29, 0x3c, 0x94, 0x35, 0x4e, 0x98, 0x83, 0xe5, 0xc2, 0x78, 0x36, + 0x7a, 0xe5, 0x18, 0x90, 0xbf, 0x35, 0x41, 0x01, 0x64, 0x19, 0x8d, + 0x26, 0xeb, 0xe1, 0xf8, 0x2f, 0x04, 0x8e, 0xfa, 0x8b, 0x2b, 0xc6, + 0xb2, 0x9d, 0x5d, 0x46, 0x76, 0x5a, 0xc8, 0xb5, 0x25, 0xa3, 0xea, + 0x52, 0x84, 0x47, 0x6d, 0x6d, 0xf4, 0xc9, 0x71, 0xf3, 0x3d, 0x89, + 0x4c, 0x3b, 0x20, 0x8c, 0x5b, 0x75, 0xe8, 0xf8, 0x7c, + }; + uint8_t output[SHA512_DIGEST_LENGTH]; + + // SHA-512 KAT + SHA512(kInput, sizeof(kInput), output); + return check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), + "SHA-512 KAT"); +} + +int boringssl_self_test_hmac_sha256(void) { + static const uint8_t kInput[16] = { + 0xda, 0xd9, 0x12, 0x93, 0xdf, 0xcf, 0x2a, 0x7c, + 0x8e, 0xcd, 0x13, 0xfe, 0x35, 0x3f, 0xa7, 0x5b, + }; + static const uint8_t kPlaintextHMACSHA256[32] = { + 0x36, 0x5f, 0x5b, 0xd5, 0xf5, 0xeb, 0xfd, 0xc7, 0x6e, 0x53, 0xa5, + 0x73, 0x6d, 0x73, 0x20, 0x13, 0xaa, 0xd3, 0xbc, 0x86, 0x4b, 0xb8, + 0x84, 0x94, 0x16, 0x46, 0x88, 0x9c, 0x48, 0xee, 0xa9, 0x0e, + }; + uint8_t output[EVP_MAX_MD_SIZE]; + + unsigned output_len; + HMAC(EVP_sha256(), kInput, sizeof(kInput), kInput, sizeof(kInput), output, + &output_len); + return output_len == sizeof(kPlaintextHMACSHA256) && + check_test(kPlaintextHMACSHA256, output, sizeof(kPlaintextHMACSHA256), + "HMAC-SHA-256 KAT"); +} + +static int boringssl_self_test_fast(void) { + static const uint8_t kAESKey[16] = "BoringCrypto Key"; + static const uint8_t kAESIV[16] = {0}; + + EVP_AEAD_CTX aead_ctx; + EVP_AEAD_CTX_zero(&aead_ctx); + int ret = 0; + + AES_KEY aes_key; + uint8_t aes_iv[16]; + uint8_t output[256]; + + // AES-CBC Encryption KAT + static const uint8_t kAESCBCEncPlaintext[32] = { + 0x07, 0x86, 0x09, 0xa6, 0xc5, 0xac, 0x25, 0x44, 0x69, 0x9a, 0xdf, + 0x68, 0x2f, 0xa3, 0x77, 0xf9, 0xbe, 0x8a, 0xb6, 0xae, 0xf5, 0x63, + 0xe8, 0xc5, 0x6a, 0x36, 0xb8, 0x4f, 0x55, 0x7f, 0xad, 0xd3, + }; + static const uint8_t kAESCBCEncCiphertext[sizeof(kAESCBCEncPlaintext)] = { + 0x56, 0x46, 0xc1, 0x41, 0xf4, 0x13, 0xd6, 0xff, 0x62, 0x92, 0x41, + 0x7a, 0x26, 0xc6, 0x86, 0xbd, 0x30, 0x5f, 0xb6, 0x57, 0xa7, 0xd2, + 0x50, 0x3a, 0xc5, 0x5e, 0x8e, 0x93, 0x40, 0xf2, 0x10, 0xd8, + }; + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + fprintf(stderr, "AES_set_encrypt_key failed.\n"); + goto err; + } + AES_cbc_encrypt(kAESCBCEncPlaintext, output, sizeof(kAESCBCEncPlaintext), + &aes_key, aes_iv, AES_ENCRYPT); + if (!check_test(kAESCBCEncCiphertext, output, sizeof(kAESCBCEncCiphertext), + "AES-CBC-encrypt KAT")) { + goto err; + } + + // AES-CBC Decryption KAT + static const uint8_t kAESCBCDecCiphertext[32] = { + 0x34, 0x7a, 0xa5, 0xa0, 0x24, 0xb2, 0x82, 0x57, 0xb3, 0x65, 0x10, + 0xbe, 0x58, 0x3d, 0x4f, 0x47, 0xad, 0xb7, 0xbb, 0xee, 0xdc, 0x60, + 0x05, 0xbb, 0xbd, 0x0d, 0x0a, 0x9f, 0x06, 0xbb, 0x7b, 0x10, + }; + static const uint8_t kAESCBCDecPlaintext[sizeof(kAESCBCDecCiphertext)] = { + 0x51, 0xa7, 0xa0, 0x1f, 0x6b, 0x79, 0x6c, 0xcd, 0x48, 0x03, 0xa1, + 0x41, 0xdc, 0x56, 0xa6, 0xc2, 0x16, 0xb5, 0xd1, 0xd3, 0xb7, 0x06, + 0xb2, 0x25, 0x6f, 0xa6, 0xd0, 0xd2, 0x0e, 0x6f, 0x19, 0xb5, + }; + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + fprintf(stderr, "AES_set_decrypt_key failed.\n"); + goto err; + } + AES_cbc_encrypt(kAESCBCDecCiphertext, output, sizeof(kAESCBCDecCiphertext), + &aes_key, aes_iv, AES_DECRYPT); + if (!check_test(kAESCBCDecPlaintext, output, sizeof(kAESCBCDecPlaintext), + "AES-CBC-decrypt KAT")) { + goto err; + } + + size_t out_len; + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, + sizeof(kAESKey), 0, NULL)) { + fprintf(stderr, "EVP_AEAD_CTX_init for AES-128-GCM failed.\n"); + goto err; + } + + // AES-GCM Encryption KAT + static const uint8_t kAESGCMEncPlaintext[32] = { + 0x8f, 0xcc, 0x40, 0x99, 0x80, 0x8e, 0x75, 0xca, 0xaf, 0xf5, 0x82, + 0x89, 0x88, 0x48, 0xa8, 0x8d, 0x80, 0x8b, 0x55, 0xab, 0x4e, 0x93, + 0x70, 0x79, 0x7d, 0x94, 0x0b, 0xe8, 0xcc, 0x1d, 0x78, 0x84, + }; + static const uint8_t kAESGCMCiphertext[sizeof(kAESGCMEncPlaintext) + 16] = { + 0x87, 0x7b, 0xd5, 0x8d, 0x96, 0x3e, 0x4b, 0xe6, 0x64, 0x94, 0x40, 0x2f, + 0x61, 0x9b, 0x7e, 0x56, 0x52, 0x7d, 0xa4, 0x5a, 0xf9, 0xa6, 0xe2, 0xdb, + 0x1c, 0x63, 0x2e, 0x97, 0x93, 0x0f, 0xfb, 0xed, 0xb5, 0x9e, 0x1c, 0x20, + 0xb2, 0xb0, 0x58, 0xda, 0x48, 0x07, 0x2d, 0xbd, 0x96, 0x0d, 0x34, 0xc6, + }; + if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kAESGCMEncPlaintext, sizeof(kAESGCMEncPlaintext), NULL, + 0) || + !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), + "AES-GCM-encrypt KAT")) { + fprintf(stderr, "EVP_AEAD_CTX_seal for AES-128-GCM failed.\n"); + goto err; + } + + // AES-GCM Decryption KAT + static const uint8_t kAESGCMDecCiphertext[48] = { + 0x35, 0xf3, 0x05, 0x8f, 0x87, 0x57, 0x60, 0xff, 0x09, 0xd3, 0x12, 0x0f, + 0x70, 0xc4, 0xbc, 0x9e, 0xd7, 0xa8, 0x68, 0x72, 0xe1, 0x34, 0x52, 0x20, + 0x21, 0x76, 0xf7, 0x37, 0x1a, 0xe0, 0x4f, 0xaa, 0xe1, 0xdd, 0x39, 0x19, + 0x20, 0xf5, 0xd1, 0x39, 0x53, 0xd8, 0x96, 0x78, 0x59, 0x94, 0x82, 0x3c, + }; + static const uint8_t kAESGCMDecPlaintext[sizeof(kAESGCMDecCiphertext) - 16] = + { + 0x3d, 0x44, 0x90, 0x9b, 0x91, 0xe7, 0x5e, 0xd3, 0xc2, 0xb2, 0xd0, + 0xa9, 0x99, 0x17, 0x6a, 0x45, 0x05, 0x5e, 0x99, 0x83, 0x56, 0x01, + 0xc0, 0x82, 0x40, 0x81, 0xd2, 0x48, 0x45, 0xf2, 0xcc, 0xc3, + }; + if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kAESGCMDecCiphertext, sizeof(kAESGCMDecCiphertext), + NULL, 0) || + !check_test(kAESGCMDecPlaintext, output, sizeof(kAESGCMDecPlaintext), + "AES-GCM-decrypt KAT")) { + fprintf(stderr, + "AES-GCM-decrypt KAT failed because EVP_AEAD_CTX_open failed.\n"); + goto err; + } + + // SHA-1 KAT + static const uint8_t kSHA1Input[16] = { + 0x13, 0x2f, 0xd9, 0xba, 0xd5, 0xc1, 0x82, 0x62, + 0x63, 0xba, 0xfb, 0xb6, 0x99, 0xf7, 0x07, 0xa5, + }; + static const uint8_t kSHA1Digest[20] = { + 0x94, 0x19, 0x55, 0x93, 0x0a, 0x58, 0x29, 0x38, 0xeb, 0xf5, + 0x09, 0x11, 0x6d, 0x1a, 0xfd, 0x0f, 0x1e, 0x11, 0xe3, 0xcb, + }; + SHA1(kSHA1Input, sizeof(kSHA1Input), output); + if (!check_test(kSHA1Digest, output, sizeof(kSHA1Digest), + "SHA-1 KAT")) { + goto err; + } + + if (!boringssl_self_test_sha256() || + !boringssl_self_test_sha512() || + !boringssl_self_test_hmac_sha256()) { + goto err; + } + + // DBRG KAT + static const uint8_t kDRBGEntropy[48] = { + 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, 0xe5, + 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, 0xbb, 0x4a, + 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, 0x40, 0xc2, 0xb5, 0x0b, + 0xab, 0xe1, 0x4a, 0xae, 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, + }; + static const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; + static const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; + static const uint8_t kDRBGOutput[64] = { + 0x19, 0x1f, 0x2b, 0x49, 0x76, 0x85, 0xfd, 0x51, 0xb6, 0x56, 0xbc, + 0x1c, 0x7d, 0xd5, 0xdd, 0x44, 0x76, 0xa3, 0x5e, 0x17, 0x9b, 0x8e, + 0xb8, 0x98, 0x65, 0x12, 0xca, 0x35, 0x6c, 0xa0, 0x6f, 0xa0, 0x22, + 0xe4, 0xf6, 0xd8, 0x43, 0xed, 0x4e, 0x2d, 0x97, 0x39, 0x43, 0x3b, + 0x57, 0xfc, 0x23, 0x3f, 0x71, 0x0a, 0xe0, 0xed, 0xfe, 0xd5, 0xb8, + 0x67, 0x7a, 0x00, 0x39, 0xb2, 0x6e, 0xa9, 0x25, 0x97, + }; + static const uint8_t kDRBGEntropy2[48] = { + 0xc7, 0x16, 0x1c, 0xa3, 0x6c, 0x23, 0x09, 0xb7, 0x16, 0xe9, 0x85, 0x9b, + 0xb9, 0x6c, 0x6d, 0x49, 0xbd, 0xc8, 0x35, 0x21, 0x03, 0xa1, 0x8c, 0xd2, + 0x4e, 0xf4, 0x2e, 0xc9, 0x7e, 0xf4, 0x6b, 0xf4, 0x46, 0xeb, 0x1a, 0x45, + 0x76, 0xc1, 0x86, 0xe9, 0x35, 0x18, 0x03, 0x76, 0x3a, 0x79, 0x12, 0xfe, + }; + static const uint8_t kDRBGReseedOutput[64] = { + 0x00, 0xf2, 0x05, 0xaa, 0xfd, 0x11, 0x6c, 0x77, 0xbc, 0x81, 0x86, + 0x99, 0xca, 0x51, 0xcf, 0x80, 0x15, 0x9f, 0x02, 0x9e, 0x0b, 0xcd, + 0x26, 0xc8, 0x4b, 0x87, 0x8a, 0x15, 0x1a, 0xdd, 0xf2, 0xf3, 0xeb, + 0x94, 0x0b, 0x08, 0xc8, 0xc9, 0x57, 0xa4, 0x0b, 0x4b, 0x0f, 0x13, + 0xde, 0x7c, 0x0c, 0x6a, 0xac, 0x34, 0x4a, 0x9a, 0xf2, 0xd0, 0x83, + 0x02, 0x05, 0x17, 0xc9, 0x81, 0x8f, 0x2a, 0x81, 0x92, + }; + CTR_DRBG_STATE drbg; + if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + sizeof(kDRBGPersonalization)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGOutput, output, sizeof(kDRBGOutput), + "DRBG Generate KAT") || + !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), + "DRBG-reseed KAT")) { + fprintf(stderr, "CTR-DRBG failed.\n"); + goto err; + } + CTR_DRBG_clear(&drbg); + + CTR_DRBG_STATE kZeroDRBG; + memset(&kZeroDRBG, 0, sizeof(kZeroDRBG)); + if (!check_test(&kZeroDRBG, &drbg, sizeof(drbg), "DRBG Clear KAT")) { + goto err; + } + + // TLS KDF KAT + static const uint8_t kTLSSecret[32] = { + 0xab, 0xc3, 0x65, 0x7b, 0x09, 0x4c, 0x76, 0x28, 0xa0, 0xb2, 0x82, + 0x99, 0x6f, 0xe7, 0x5a, 0x75, 0xf4, 0x98, 0x4f, 0xd9, 0x4d, 0x4e, + 0xcc, 0x2f, 0xcf, 0x53, 0xa2, 0xc4, 0x69, 0xa3, 0xf7, 0x31, + }; + static const char kTLSLabel[] = "FIPS self test"; + static const uint8_t kTLSSeed1[16] = { + 0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2, + 0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65, + }; + static const uint8_t kTLSSeed2[16] = { + 0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c, + 0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81, + }; + static const uint8_t kTLSOutput[32] = { + 0xe2, 0x1d, 0xd6, 0xc2, 0x68, 0xc7, 0x57, 0x03, 0x2c, 0x2c, 0xeb, + 0xbb, 0xb8, 0xa9, 0x7d, 0xe9, 0xee, 0xe6, 0xc9, 0x47, 0x83, 0x0a, + 0xbd, 0x11, 0x60, 0x5d, 0xd5, 0x2c, 0x47, 0xb6, 0x05, 0x88, + }; + uint8_t tls_output[sizeof(kTLSOutput)]; + if (!CRYPTO_tls1_prf(EVP_sha256(), tls_output, sizeof(tls_output), kTLSSecret, + sizeof(kTLSSecret), kTLSLabel, sizeof(kTLSLabel), + kTLSSeed1, sizeof(kTLSSeed1), kTLSSeed2, + sizeof(kTLSSeed2)) || + !check_test(kTLSOutput, tls_output, sizeof(kTLSOutput), "TLS-KDF KAT")) { + fprintf(stderr, "TLS KDF failed.\n"); + goto err; + } + + ret = 1; + +err: + EVP_AEAD_CTX_cleanup(&aead_ctx); + + return ret; +} + +int BORINGSSL_self_test(void) { + if (!boringssl_self_test_fast() || + // When requested to run self tests, also run the lazy tests. + !boringssl_self_test_rsa() || + !boringssl_self_test_ecc() || + !boringssl_self_test_ffdh()) { + return 0; + } + + return 1; +} + +#if defined(BORINGSSL_FIPS) +int boringssl_self_test_startup(void) { + return boringssl_self_test_fast(); +} +#endif + +#endif // !_MSC_VER diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h new file mode 100644 index 00000000..ce139b2e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SHA_INTERNAL_H +#define OPENSSL_HEADER_SHA_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_PPC64LE) || \ + (!defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) +// POWER has an intrinsics-based implementation of SHA-1 and thus the functions +// normally defined in assembly are available even with |OPENSSL_NO_ASM| in +// this case. +#define SHA1_ASM +void sha1_block_data_order(uint32_t *state, const uint8_t *in, + size_t num_blocks); +#endif + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA256_ASM +#define SHA512_ASM +void sha256_block_data_order(uint32_t *state, const uint8_t *in, + size_t num_blocks); +void sha512_block_data_order(uint64_t *state, const uint8_t *in, + size_t num_blocks); +#endif + + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // OPENSSL_HEADER_SHA_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c new file mode 100644 index 00000000..57974346 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c @@ -0,0 +1,361 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +// Altivec-optimized SHA1 in C. This is tested on ppc64le only. +// +// References: +// https://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1 +// http://arctic.org/~dean/crypto/sha1.html +// +// This code used the generic SHA-1 from OpenSSL as a basis and AltiVec +// optimisations were added on top. + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +static uint32_t rotate(uint32_t a, int n) { return (a << n) | (a >> (32 - n)); } + +typedef vector unsigned int vec_uint32_t; +typedef vector unsigned char vec_uint8_t; + +// Vector constants +static const vec_uint8_t k_swap_endianness = {3, 2, 1, 0, 7, 6, 5, 4, + 11, 10, 9, 8, 15, 14, 13, 12}; + +// Shift amounts for byte and bit shifts and rotations +static const vec_uint8_t k_4_bytes = {32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32}; +static const vec_uint8_t k_12_bytes = {96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96}; + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +// Vector versions of the above. +static const vec_uint32_t K_00_19_x_4 = {K_00_19, K_00_19, K_00_19, K_00_19}; +static const vec_uint32_t K_20_39_x_4 = {K_20_39, K_20_39, K_20_39, K_20_39}; +static const vec_uint32_t K_40_59_x_4 = {K_40_59, K_40_59, K_40_59, K_40_59}; +static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; + +// vector message scheduling: compute message schedule for round i..i+3 where i +// is divisible by 4. We return the schedule w[i..i+3] as a vector. In +// addition, we also precompute sum w[i..+3] and an additive constant K. This +// is done to offload some computation of f() in the integer execution units. +// +// Byte shifting code below may not be correct for big-endian systems. +static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, + vec_uint32_t k) { + const vector unsigned char unaligned_data = + vec_vsx_ld(0, (const unsigned char*) data); + const vec_uint32_t v = (vec_uint32_t) unaligned_data; + const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using these steps for i in [16, 20, 24, 28] +// +// w'[i ] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) <<< 1 +// w'[i+1] = (w[i-2] ^ w[i-7] ^ w[i-13] ^ w[i-15]) <<< 1 +// w'[i+2] = (w[i-1] ^ w[i-6] ^ w[i-12] ^ w[i-14]) <<< 1 +// w'[i+3] = ( 0 ^ w[i-5] ^ w[i-11] ^ w[i-13]) <<< 1 +// +// w[ i] = w'[ i] +// w[i+1] = w'[i+1] +// w[i+2] = w'[i+2] +// w[i+3] = w'[i+3] ^ (w'[i] <<< 1) +static vec_uint32_t sched_16_31(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_12, + vec_uint32_t minus_16, vec_uint32_t k) { + const vec_uint32_t minus_3 = vec_sro(minus_4, k_4_bytes); + const vec_uint32_t minus_14 = vec_sld((minus_12), (minus_16), 8); + const vec_uint32_t k_1_bit = vec_splat_u32(1); + const vec_uint32_t w_prime = + vec_rl(minus_3 ^ minus_8 ^ minus_14 ^ minus_16, k_1_bit); + const vec_uint32_t w = + w_prime ^ vec_rl(vec_slo(w_prime, k_12_bytes), k_1_bit); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using this relation for i in [32, 36, 40 ... 76] +// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]), 2) <<< 2 +static vec_uint32_t sched_32_79(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_16, + vec_uint32_t minus_28, vec_uint32_t minus_32, + vec_uint32_t k) { + const vec_uint32_t minus_6 = vec_sld(minus_4, minus_8, 8); + const vec_uint32_t k_2_bits = vec_splat_u32(2); + const vec_uint32_t w = + vec_rl(minus_6 ^ minus_16 ^ minus_28 ^ minus_32, k_2_bits); + vec_st(w + k, 0, pre_added); + return w; +} + +// As pointed out by Wei Dai , F() below can be simplified +// to the code in F_00_19. Wei attributes these optimisations to Peter +// Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define +// F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another +// tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a +#define F_00_19(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b, c, d) ((b) ^ (c) ^ (d)) +#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d))) +#define F_60_79(b, c, d) F_20_39(b, c, d) + +// We pre-added the K constants during message scheduling. +#define BODY_00_19(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_00_19((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_20_39(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_20_39((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_40_59((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_60_79((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, E, T; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + vec_uint32_t vw[20]; + const uint32_t *w = (const uint32_t *)&vw; + + vec_uint32_t k = K_00_19_x_4; + const vec_uint32_t w0 = sched_00_15(vw + 0, data + 0, k); + BODY_00_19(0, A, B, C, D, E, T); + BODY_00_19(1, T, A, B, C, D, E); + BODY_00_19(2, E, T, A, B, C, D); + BODY_00_19(3, D, E, T, A, B, C); + + const vec_uint32_t w4 = sched_00_15(vw + 1, data + 16, k); + BODY_00_19(4, C, D, E, T, A, B); + BODY_00_19(5, B, C, D, E, T, A); + BODY_00_19(6, A, B, C, D, E, T); + BODY_00_19(7, T, A, B, C, D, E); + + const vec_uint32_t w8 = sched_00_15(vw + 2, data + 32, k); + BODY_00_19(8, E, T, A, B, C, D); + BODY_00_19(9, D, E, T, A, B, C); + BODY_00_19(10, C, D, E, T, A, B); + BODY_00_19(11, B, C, D, E, T, A); + + const vec_uint32_t w12 = sched_00_15(vw + 3, data + 48, k); + BODY_00_19(12, A, B, C, D, E, T); + BODY_00_19(13, T, A, B, C, D, E); + BODY_00_19(14, E, T, A, B, C, D); + BODY_00_19(15, D, E, T, A, B, C); + + const vec_uint32_t w16 = sched_16_31(vw + 4, w12, w8, w4, w0, k); + BODY_00_19(16, C, D, E, T, A, B); + BODY_00_19(17, B, C, D, E, T, A); + BODY_00_19(18, A, B, C, D, E, T); + BODY_00_19(19, T, A, B, C, D, E); + + k = K_20_39_x_4; + const vec_uint32_t w20 = sched_16_31(vw + 5, w16, w12, w8, w4, k); + BODY_20_39(20, E, T, A, B, C, D); + BODY_20_39(21, D, E, T, A, B, C); + BODY_20_39(22, C, D, E, T, A, B); + BODY_20_39(23, B, C, D, E, T, A); + + const vec_uint32_t w24 = sched_16_31(vw + 6, w20, w16, w12, w8, k); + BODY_20_39(24, A, B, C, D, E, T); + BODY_20_39(25, T, A, B, C, D, E); + BODY_20_39(26, E, T, A, B, C, D); + BODY_20_39(27, D, E, T, A, B, C); + + const vec_uint32_t w28 = sched_16_31(vw + 7, w24, w20, w16, w12, k); + BODY_20_39(28, C, D, E, T, A, B); + BODY_20_39(29, B, C, D, E, T, A); + BODY_20_39(30, A, B, C, D, E, T); + BODY_20_39(31, T, A, B, C, D, E); + + const vec_uint32_t w32 = sched_32_79(vw + 8, w28, w24, w16, w4, w0, k); + BODY_20_39(32, E, T, A, B, C, D); + BODY_20_39(33, D, E, T, A, B, C); + BODY_20_39(34, C, D, E, T, A, B); + BODY_20_39(35, B, C, D, E, T, A); + + const vec_uint32_t w36 = sched_32_79(vw + 9, w32, w28, w20, w8, w4, k); + BODY_20_39(36, A, B, C, D, E, T); + BODY_20_39(37, T, A, B, C, D, E); + BODY_20_39(38, E, T, A, B, C, D); + BODY_20_39(39, D, E, T, A, B, C); + + k = K_40_59_x_4; + const vec_uint32_t w40 = sched_32_79(vw + 10, w36, w32, w24, w12, w8, k); + BODY_40_59(40, C, D, E, T, A, B); + BODY_40_59(41, B, C, D, E, T, A); + BODY_40_59(42, A, B, C, D, E, T); + BODY_40_59(43, T, A, B, C, D, E); + + const vec_uint32_t w44 = sched_32_79(vw + 11, w40, w36, w28, w16, w12, k); + BODY_40_59(44, E, T, A, B, C, D); + BODY_40_59(45, D, E, T, A, B, C); + BODY_40_59(46, C, D, E, T, A, B); + BODY_40_59(47, B, C, D, E, T, A); + + const vec_uint32_t w48 = sched_32_79(vw + 12, w44, w40, w32, w20, w16, k); + BODY_40_59(48, A, B, C, D, E, T); + BODY_40_59(49, T, A, B, C, D, E); + BODY_40_59(50, E, T, A, B, C, D); + BODY_40_59(51, D, E, T, A, B, C); + + const vec_uint32_t w52 = sched_32_79(vw + 13, w48, w44, w36, w24, w20, k); + BODY_40_59(52, C, D, E, T, A, B); + BODY_40_59(53, B, C, D, E, T, A); + BODY_40_59(54, A, B, C, D, E, T); + BODY_40_59(55, T, A, B, C, D, E); + + const vec_uint32_t w56 = sched_32_79(vw + 14, w52, w48, w40, w28, w24, k); + BODY_40_59(56, E, T, A, B, C, D); + BODY_40_59(57, D, E, T, A, B, C); + BODY_40_59(58, C, D, E, T, A, B); + BODY_40_59(59, B, C, D, E, T, A); + + k = K_60_79_x_4; + const vec_uint32_t w60 = sched_32_79(vw + 15, w56, w52, w44, w32, w28, k); + BODY_60_79(60, A, B, C, D, E, T); + BODY_60_79(61, T, A, B, C, D, E); + BODY_60_79(62, E, T, A, B, C, D); + BODY_60_79(63, D, E, T, A, B, C); + + const vec_uint32_t w64 = sched_32_79(vw + 16, w60, w56, w48, w36, w32, k); + BODY_60_79(64, C, D, E, T, A, B); + BODY_60_79(65, B, C, D, E, T, A); + BODY_60_79(66, A, B, C, D, E, T); + BODY_60_79(67, T, A, B, C, D, E); + + const vec_uint32_t w68 = sched_32_79(vw + 17, w64, w60, w52, w40, w36, k); + BODY_60_79(68, E, T, A, B, C, D); + BODY_60_79(69, D, E, T, A, B, C); + BODY_60_79(70, C, D, E, T, A, B); + BODY_60_79(71, B, C, D, E, T, A); + + const vec_uint32_t w72 = sched_32_79(vw + 18, w68, w64, w56, w44, w40, k); + BODY_60_79(72, A, B, C, D, E, T); + BODY_60_79(73, T, A, B, C, D, E); + BODY_60_79(74, E, T, A, B, C, D); + BODY_60_79(75, D, E, T, A, B, C); + + // We don't use the last value + (void)sched_32_79(vw + 19, w72, w68, w60, w48, w44, k); + BODY_60_79(76, C, D, E, T, A, B); + BODY_60_79(77, B, C, D, E, T, A); + BODY_60_79(78, A, B, C, D, E, T); + BODY_60_79(79, T, A, B, C, D, E); + + const uint32_t mask = 0xffffffffUL; + state[0] = (state[0] + E) & mask; + state[1] = (state[1] + T) & mask; + state[2] = (state[2] + A) & mask; + state[3] = (state[3] + B) & mask; + state[4] = (state[4] + C) & mask; + + data += 64; + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} + +#endif // OPENSSL_PPC64LE + +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_19 +#undef BODY_20_39 +#undef BODY_40_59 +#undef BODY_60_79 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1.c new file mode 100644 index 00000000..974a1689 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1.c @@ -0,0 +1,357 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "../../internal.h" +#include "../digest/md32_common.h" +#include "internal.h" + + +int SHA1_Init(SHA_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA_CTX)); + sha->h[0] = 0x67452301UL; + sha->h[1] = 0xefcdab89UL; + sha->h[2] = 0x98badcfeUL; + sha->h[3] = 0x10325476UL; + sha->h[4] = 0xc3d2e1f0UL; + return 1; +} + +uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t out[SHA_DIGEST_LENGTH]) { + SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, data, len); + SHA1_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#if !defined(SHA1_ASM) +static void sha1_block_data_order(uint32_t *state, const uint8_t *data, + size_t num); +#endif + +void SHA1_Transform(SHA_CTX *c, const uint8_t data[SHA_CBLOCK]) { + sha1_block_data_order(c->h, data, 1); +} + +int SHA1_Update(SHA_CTX *c, const void *data, size_t len) { + crypto_md32_update(&sha1_block_data_order, c->h, c->data, SHA_CBLOCK, &c->num, + &c->Nh, &c->Nl, data, len); + return 1; +} + +int SHA1_Final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *c) { + crypto_md32_final(&sha1_block_data_order, c->h, c->data, SHA_CBLOCK, &c->num, + c->Nh, c->Nl, /*is_big_endian=*/1); + + CRYPTO_store_u32_be(out, c->h[0]); + CRYPTO_store_u32_be(out + 4, c->h[1]); + CRYPTO_store_u32_be(out + 8, c->h[2]); + CRYPTO_store_u32_be(out + 12, c->h[3]); + CRYPTO_store_u32_be(out + 16, c->h[4]); + return 1; +} + +#define Xupdate(a, ix, ia, ib, ic, id) \ + do { \ + (a) = ((ia) ^ (ib) ^ (ic) ^ (id)); \ + (ix) = (a) = CRYPTO_rotl_u32((a), 1); \ + } while (0) + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +// As pointed out by Wei Dai , F() below can be simplified +// to the code in F_00_19. Wei attributes these optimisations to Peter +// Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define +// F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another +// tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a +#define F_00_19(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b, c, d) ((b) ^ (c) ^ (d)) +#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d))) +#define F_60_79(b, c, d) F_20_39(b, c, d) + +#define BODY_00_15(i, a, b, c, d, e, f, xi) \ + do { \ + (f) = (xi) + (e) + K_00_19 + CRYPTO_rotl_u32((a), 5) + \ + F_00_19((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + Xupdate(f, xi, xa, xb, xc, xd); \ + (f) += (e) + K_00_19 + CRYPTO_rotl_u32((a), 5) + F_00_19((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + Xupdate(f, xi, xa, xb, xc, xd); \ + (f) += (e) + K_20_39 + CRYPTO_rotl_u32((a), 5) + F_20_39((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f) += (e) + K_20_39 + CRYPTO_rotl_u32((a), 5) + F_20_39((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f) += (e) + K_40_59 + CRYPTO_rotl_u32((a), 5) + F_40_59((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + Xupdate(f, xa, xa, xb, xc, xd); \ + (f) = (xa) + (e) + K_60_79 + CRYPTO_rotl_u32((a), 5) + \ + F_60_79((b), (c), (d)); \ + (b) = CRYPTO_rotl_u32((b), 30); \ + } while (0) + +#ifdef X +#undef X +#endif + +/* Originally X was an array. As it's automatic it's natural +* to expect RISC compiler to accomodate at least part of it in +* the register bank, isn't it? Unfortunately not all compilers +* "find" this expectation reasonable:-( On order to make such +* compilers generate better code I replace X[] with a bunch of +* X0, X1, etc. See the function body below... +* */ +#define X(i) XX##i + +#if !defined(SHA1_ASM) +static void sha1_block_data_order(uint32_t *state, const uint8_t *data, + size_t num) { + register uint32_t A, B, C, D, E, T; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, + XX11, XX12, XX13, XX14, XX15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + X(0) = CRYPTO_load_u32_be(data); + data += 4; + X(1) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + X(2) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + X(3) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + X(4) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + X(5) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + X(6) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + X(7) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + X(8) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + X(9) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + X(10) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + X(11) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + X(12) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + X(13) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + X(14) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + X(15) = CRYPTO_load_u32_be(data); + data += 4; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + + BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13)); + BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14)); + BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15)); + BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0)); + + BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1)); + BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2)); + BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3)); + BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4)); + BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5)); + BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6)); + BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7)); + BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8)); + BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9)); + BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10)); + BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11)); + BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12)); + + BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13)); + BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14)); + BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15)); + BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0)); + BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1)); + BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2)); + BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3)); + BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4)); + + BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5)); + BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6)); + BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7)); + BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8)); + BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9)); + BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10)); + BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11)); + BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12)); + BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13)); + BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14)); + BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15)); + BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0)); + BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1)); + BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2)); + BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3)); + BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4)); + BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5)); + BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6)); + BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7)); + BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8)); + + BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9)); + BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10)); + BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11)); + BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12)); + BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13)); + BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14)); + BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15)); + BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0)); + BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1)); + BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2)); + BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3)); + BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4)); + BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5)); + BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6)); + BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7)); + BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8)); + BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9)); + BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10)); + BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11)); + BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12)); + + state[0] = (state[0] + E) & 0xffffffffL; + state[1] = (state[1] + T) & 0xffffffffL; + state[2] = (state[2] + A) & 0xffffffffL; + state[3] = (state[3] + B) & 0xffffffffL; + state[4] = (state[4] + C) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} +#endif + +#undef Xupdate +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_15 +#undef BODY_16_19 +#undef BODY_20_31 +#undef BODY_32_39 +#undef BODY_40_59 +#undef BODY_60_79 +#undef X diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha256.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha256.c new file mode 100644 index 00000000..afaf7c4b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha256.c @@ -0,0 +1,321 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "../../internal.h" +#include "../digest/md32_common.h" +#include "internal.h" + + +int SHA224_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0xc1059ed8UL; + sha->h[1] = 0x367cd507UL; + sha->h[2] = 0x3070dd17UL; + sha->h[3] = 0xf70e5939UL; + sha->h[4] = 0xffc00b31UL; + sha->h[5] = 0x68581511UL; + sha->h[6] = 0x64f98fa7UL; + sha->h[7] = 0xbefa4fa4UL; + sha->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +int SHA256_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0x6a09e667UL; + sha->h[1] = 0xbb67ae85UL; + sha->h[2] = 0x3c6ef372UL; + sha->h[3] = 0xa54ff53aUL; + sha->h[4] = 0x510e527fUL; + sha->h[5] = 0x9b05688cUL; + sha->h[6] = 0x1f83d9abUL; + sha->h[7] = 0x5be0cd19UL; + sha->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA224(const uint8_t *data, size_t len, + uint8_t out[SHA224_DIGEST_LENGTH]) { + SHA256_CTX ctx; + SHA224_Init(&ctx); + SHA224_Update(&ctx, data, len); + SHA224_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA256(const uint8_t *data, size_t len, + uint8_t out[SHA256_DIGEST_LENGTH]) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, data, len); + SHA256_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#ifndef SHA256_ASM +static void sha256_block_data_order(uint32_t *state, const uint8_t *in, + size_t num); +#endif + +void SHA256_Transform(SHA256_CTX *c, const uint8_t data[SHA256_CBLOCK]) { + sha256_block_data_order(c->h, data, 1); +} + +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) { + crypto_md32_update(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK, + &c->num, &c->Nh, &c->Nl, data, len); + return 1; +} + +int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) { + return SHA256_Update(ctx, data, len); +} + +static int sha256_final_impl(uint8_t *out, SHA256_CTX *c) { + crypto_md32_final(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK, + &c->num, c->Nh, c->Nl, /*is_big_endian=*/1); + + // TODO(davidben): This overflow check one of the few places a low-level hash + // 'final' function can fail. SHA-512 does not have a corresponding check. + // These functions already misbehave if the caller arbitrarily mutates |c|, so + // can we assume one of |SHA256_Init| or |SHA224_Init| was used? + if (c->md_len > SHA256_DIGEST_LENGTH) { + return 0; + } + + assert(c->md_len % 4 == 0); + const size_t out_words = c->md_len / 4; + for (size_t i = 0; i < out_words; i++) { + CRYPTO_store_u32_be(out, c->h[i]); + out += 4; + } + return 1; +} + +int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *c) { + // Ideally we would assert |sha->md_len| is |SHA256_DIGEST_LENGTH| to match + // the size hint, but calling code often pairs |SHA224_Init| with + // |SHA256_Final| and expects |sha->md_len| to carry the size over. + // + // TODO(davidben): Add an assert and fix code to match them up. + return sha256_final_impl(out, c); +} +int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *ctx) { + // SHA224_Init sets |ctx->md_len| to |SHA224_DIGEST_LENGTH|, so this has a + // smaller output. + assert(ctx->md_len == SHA224_DIGEST_LENGTH); + return sha256_final_impl(out, ctx); +} + +#ifndef SHA256_ASM +static const uint32_t K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; + +// See FIPS 180-4, section 4.1.2. +#define Sigma0(x) \ + (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \ + CRYPTO_rotr_u32((x), 22)) +#define Sigma1(x) \ + (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \ + CRYPTO_rotr_u32((x), 25)) +#define sigma0(x) \ + (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3)) +#define sigma1(x) \ + (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10)) + +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define ROUND_00_15(i, a, b, c, d, e, f, g, h) \ + do { \ + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \ + h = Sigma0(a) + Maj(a, b, c); \ + d += T1; \ + h += T1; \ + } while (0) + +#define ROUND_16_63(i, a, b, c, d, e, f, g, h, X) \ + do { \ + s0 = X[(i + 1) & 0x0f]; \ + s0 = sigma0(s0); \ + s1 = X[(i + 14) & 0x0f]; \ + s1 = sigma1(s1); \ + T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \ + ROUND_00_15(i, a, b, c, d, e, f, g, h); \ + } while (0) + +static void sha256_block_data_order(uint32_t *state, const uint8_t *data, + size_t num) { + uint32_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint32_t X[16]; + int i; + + while (num--) { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + T1 = X[0] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = CRYPTO_load_u32_be(data); + data += 4; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + for (i = 16; i < 64; i += 8) { + ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); + ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); + ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); + ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); + ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); + ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); + ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); + ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } +} + +#endif // !SHA256_ASM + +void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data, + size_t num_blocks) { + sha256_block_data_order(state, data, num_blocks); +} + +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_63 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha512.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha512.c new file mode 100644 index 00000000..e1464635 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha512.c @@ -0,0 +1,508 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +// The 32-bit hash algorithms share a common byte-order neutral collector and +// padding function implementations that operate on unaligned data, +// ../digest/md32_common.h. SHA-512 is the only 64-bit hash algorithm, as of +// this writing, so there is no need for a common collector/padding +// implementation yet. + +static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha); + +int SHA384_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA384_DIGEST_LENGTH; + return 1; +} + + +int SHA512_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0x6a09e667f3bcc908); + sha->h[1] = UINT64_C(0xbb67ae8584caa73b); + sha->h[2] = UINT64_C(0x3c6ef372fe94f82b); + sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1); + sha->h[4] = UINT64_C(0x510e527fade682d1); + sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f); + sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); + sha->h[7] = UINT64_C(0x5be0cd19137e2179); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA512_DIGEST_LENGTH; + return 1; +} + +int SHA512_256_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0x22312194fc2bf72c); + sha->h[1] = UINT64_C(0x9f555fa3c84c64c2); + sha->h[2] = UINT64_C(0x2393b86b6f53b151); + sha->h[3] = UINT64_C(0x963877195940eabd); + sha->h[4] = UINT64_C(0x96283ee2a88effe3); + sha->h[5] = UINT64_C(0xbe5e1e2553863992); + sha->h[6] = UINT64_C(0x2b0199fc2c85b8aa); + sha->h[7] = UINT64_C(0x0eb72ddc81c52ca2); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA512_256_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA384(const uint8_t *data, size_t len, + uint8_t out[SHA384_DIGEST_LENGTH]) { + SHA512_CTX ctx; + SHA384_Init(&ctx); + SHA384_Update(&ctx, data, len); + SHA384_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA512(const uint8_t *data, size_t len, + uint8_t out[SHA512_DIGEST_LENGTH]) { + SHA512_CTX ctx; + SHA512_Init(&ctx); + SHA512_Update(&ctx, data, len); + SHA512_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA512_256(const uint8_t *data, size_t len, + uint8_t out[SHA512_256_DIGEST_LENGTH]) { + SHA512_CTX ctx; + SHA512_256_Init(&ctx); + SHA512_256_Update(&ctx, data, len); + SHA512_256_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#if !defined(SHA512_ASM) +static void sha512_block_data_order(uint64_t *state, const uint8_t *in, + size_t num_blocks); +#endif + + +int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], SHA512_CTX *sha) { + // |SHA384_Init| sets |sha->md_len| to |SHA384_DIGEST_LENGTH|, so this has a + // smaller output. + assert(sha->md_len == SHA384_DIGEST_LENGTH); + return sha512_final_impl(out, sha); +} + +int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + return SHA512_Update(sha, data, len); +} + +int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) { + return SHA512_Update(sha, data, len); +} + +int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], SHA512_CTX *sha) { + // |SHA512_256_Init| sets |sha->md_len| to |SHA512_256_DIGEST_LENGTH|, so this + // has a |smaller output. + assert(sha->md_len == SHA512_256_DIGEST_LENGTH); + return sha512_final_impl(out, sha); +} + +void SHA512_Transform(SHA512_CTX *c, const uint8_t block[SHA512_CBLOCK]) { + sha512_block_data_order(c->h, block, 1); +} + +int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { + uint64_t l; + uint8_t *p = c->p; + const uint8_t *data = in_data; + + if (len == 0) { + return 1; + } + + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); + if (l < c->Nl) { + c->Nh++; + } + if (sizeof(len) >= 8) { + c->Nh += (((uint64_t)len) >> 61); + } + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->p) - c->num; + + if (len < n) { + OPENSSL_memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return 1; + } else { + OPENSSL_memcpy(p + c->num, data, n), c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c->h, p, 1); + } + } + + if (len >= sizeof(c->p)) { + sha512_block_data_order(c->h, data, len / sizeof(c->p)); + data += len; + len %= sizeof(c->p); + data -= len; + } + + if (len != 0) { + OPENSSL_memcpy(p, data, len); + c->num = (int)len; + } + + return 1; +} + +int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) { + // Ideally we would assert |sha->md_len| is |SHA512_DIGEST_LENGTH| to match + // the size hint, but calling code often pairs |SHA384_Init| with + // |SHA512_Final| and expects |sha->md_len| to carry the size over. + // + // TODO(davidben): Add an assert and fix code to match them up. + return sha512_final_impl(out, sha); +} + +static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha) { + uint8_t *p = sha->p; + size_t n = sha->num; + + p[n] = 0x80; // There always is a room for one + n++; + if (n > (sizeof(sha->p) - 16)) { + OPENSSL_memset(p + n, 0, sizeof(sha->p) - n); + n = 0; + sha512_block_data_order(sha->h, p, 1); + } + + OPENSSL_memset(p + n, 0, sizeof(sha->p) - 16 - n); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, sha->Nh); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, sha->Nl); + + sha512_block_data_order(sha->h, p, 1); + + if (out == NULL) { + // TODO(davidben): This NULL check is absent in other low-level hash 'final' + // functions and is one of the few places one can fail. + return 0; + } + + assert(sha->md_len % 8 == 0); + const size_t out_words = sha->md_len / 8; + for (size_t i = 0; i < out_words; i++) { + CRYPTO_store_u64_be(out, sha->h[i]); + out += 8; + } + + return 1; +} + +#ifndef SHA512_ASM +static const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#define Sigma0(x) \ + (CRYPTO_rotr_u64((x), 28) ^ CRYPTO_rotr_u64((x), 34) ^ \ + CRYPTO_rotr_u64((x), 39)) +#define Sigma1(x) \ + (CRYPTO_rotr_u64((x), 14) ^ CRYPTO_rotr_u64((x), 18) ^ \ + CRYPTO_rotr_u64((x), 41)) +#define sigma0(x) \ + (CRYPTO_rotr_u64((x), 1) ^ CRYPTO_rotr_u64((x), 8) ^ ((x) >> 7)) +#define sigma1(x) \ + (CRYPTO_rotr_u64((x), 19) ^ CRYPTO_rotr_u64((x), 61) ^ ((x) >> 6)) + +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +// This code should give better results on 32-bit CPU with less than +// ~24 registers, both size and performance wise... +static void sha512_block_data_order(uint64_t *state, const uint8_t *in, + size_t num) { + uint64_t A, E, T; + uint64_t X[9 + 80], *F; + int i; + + while (num--) { + F = X + 80; + A = state[0]; + F[1] = state[1]; + F[2] = state[2]; + F[3] = state[3]; + E = state[4]; + F[5] = state[5]; + F[6] = state[6]; + F[7] = state[7]; + + for (i = 0; i < 16; i++, F--) { + T = CRYPTO_load_u64_be(in + i * 8); + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + for (; i < 80; i++, F--) { + T = sigma0(F[8 + 16 - 1]); + T += sigma1(F[8 + 16 - 14]); + T += F[8 + 16] + F[8 + 16 - 9]; + + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + state[0] += A; + state[1] += F[1]; + state[2] += F[2]; + state[3] += F[3]; + state[4] += E; + state[5] += F[5]; + state[6] += F[6]; + state[7] += F[7]; + + in += 16 * 8; + } +} + +#else + +#define ROUND_00_15(i, a, b, c, d, e, f, g, h) \ + do { \ + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; \ + h = Sigma0(a) + Maj(a, b, c); \ + d += T1; \ + h += T1; \ + } while (0) + +#define ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X) \ + do { \ + s0 = X[(j + 1) & 0x0f]; \ + s0 = sigma0(s0); \ + s1 = X[(j + 14) & 0x0f]; \ + s1 = sigma1(s1); \ + T1 = X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f]; \ + ROUND_00_15(i + j, a, b, c, d, e, f, g, h); \ + } while (0) + +static void sha512_block_data_order(uint64_t *state, const uint8_t *in, + size_t num) { + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint64_t X[16]; + int i; + + while (num--) { + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + T1 = X[0] = CRYPTO_load_u64_be(in); + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = CRYPTO_load_u64_be(in + 8); + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = CRYPTO_load_u64_be(in + 2 * 8); + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = CRYPTO_load_u64_be(in + 3 * 8); + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = CRYPTO_load_u64_be(in + 4 * 8); + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = CRYPTO_load_u64_be(in + 5 * 8); + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = CRYPTO_load_u64_be(in + 6 * 8); + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = CRYPTO_load_u64_be(in + 7 * 8); + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = CRYPTO_load_u64_be(in + 8 * 8); + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = CRYPTO_load_u64_be(in + 9 * 8); + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = CRYPTO_load_u64_be(in + 10 * 8); + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = CRYPTO_load_u64_be(in + 11 * 8); + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = CRYPTO_load_u64_be(in + 12 * 8); + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = CRYPTO_load_u64_be(in + 13 * 8); + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = CRYPTO_load_u64_be(in + 14 * 8); + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = CRYPTO_load_u64_be(in + 15 * 8); + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + for (i = 16; i < 80; i += 16) { + ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); + ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + in += 16 * 8; + } +} + +#endif + +#endif // !SHA512_ASM + +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_80 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S new file mode 100644 index 00000000..e278903e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S @@ -0,0 +1,3815 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl sha1_block_data_order +.hidden sha1_block_data_order +.type sha1_block_data_order,@function +.align 16 +sha1_block_data_order: +.L_sha1_block_data_order_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L000pic_point +.L000pic_point: + popl %ebp + leal OPENSSL_ia32cap_P-.L000pic_point(%ebp),%esi + leal .LK_XX_XX-.L000pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%edx + testl $512,%edx + jz .L001x86 + movl 8(%esi),%ecx + testl $16777216,%eax + jz .L001x86 + andl $268435456,%edx + andl $1073741824,%eax + orl %edx,%eax + cmpl $1342177280,%eax + je .Lavx_shortcut + jmp .Lssse3_shortcut +.align 16 +.L001x86: + movl 20(%esp),%ebp + movl 24(%esp),%esi + movl 28(%esp),%eax + subl $76,%esp + shll $6,%eax + addl %esi,%eax + movl %eax,104(%esp) + movl 16(%ebp),%edi + jmp .L002loop +.align 16 +.L002loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esp) + movl %ebx,4(%esp) + movl %ecx,8(%esp) + movl %edx,12(%esp) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,16(%esp) + movl %ebx,20(%esp) + movl %ecx,24(%esp) + movl %edx,28(%esp) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,40(%esp) + movl %edx,44(%esp) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,48(%esp) + movl %ebx,52(%esp) + movl %ecx,56(%esp) + movl %edx,60(%esp) + movl %esi,100(%esp) + movl (%ebp),%eax + movl 4(%ebp),%ebx + movl 8(%ebp),%ecx + movl 12(%ebp),%edx + + movl %ecx,%esi + movl %eax,%ebp + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl (%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 4(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 8(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 12(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + addl %ecx,%ebp + + movl %edi,%ebx + movl %ebp,%ecx + roll $5,%ebp + xorl %esi,%ebx + addl %eax,%ebp + movl 16(%esp),%eax + andl %edx,%ebx + rorl $2,%edx + xorl %esi,%ebx + leal 1518500249(%ebp,%eax,1),%ebp + addl %ebx,%ebp + + movl %edx,%eax + movl %ebp,%ebx + roll $5,%ebp + xorl %edi,%eax + addl %esi,%ebp + movl 20(%esp),%esi + andl %ecx,%eax + rorl $2,%ecx + xorl %edi,%eax + leal 1518500249(%ebp,%esi,1),%ebp + addl %eax,%ebp + + movl %ecx,%esi + movl %ebp,%eax + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl 24(%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 28(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 32(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 36(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + addl %ecx,%ebp + + movl %edi,%ebx + movl %ebp,%ecx + roll $5,%ebp + xorl %esi,%ebx + addl %eax,%ebp + movl 40(%esp),%eax + andl %edx,%ebx + rorl $2,%edx + xorl %esi,%ebx + leal 1518500249(%ebp,%eax,1),%ebp + addl %ebx,%ebp + + movl %edx,%eax + movl %ebp,%ebx + roll $5,%ebp + xorl %edi,%eax + addl %esi,%ebp + movl 44(%esp),%esi + andl %ecx,%eax + rorl $2,%ecx + xorl %edi,%eax + leal 1518500249(%ebp,%esi,1),%ebp + addl %eax,%ebp + + movl %ecx,%esi + movl %ebp,%eax + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl 48(%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 52(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 56(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 60(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + movl (%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 8(%esp),%ebx + xorl %esi,%ebp + xorl 32(%esp),%ebx + andl %edx,%ebp + xorl 52(%esp),%ebx + roll $1,%ebx + xorl %esi,%ebp + addl %ebp,%eax + movl %ecx,%ebp + rorl $2,%edx + movl %ebx,(%esp) + roll $5,%ebp + leal 1518500249(%ebx,%eax,1),%ebx + movl 4(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 12(%esp),%eax + xorl %edi,%ebp + xorl 36(%esp),%eax + andl %ecx,%ebp + xorl 56(%esp),%eax + roll $1,%eax + xorl %edi,%ebp + addl %ebp,%esi + movl %ebx,%ebp + rorl $2,%ecx + movl %eax,4(%esp) + roll $5,%ebp + leal 1518500249(%eax,%esi,1),%eax + movl 8(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 16(%esp),%esi + xorl %edx,%ebp + xorl 40(%esp),%esi + andl %ebx,%ebp + xorl 60(%esp),%esi + roll $1,%esi + xorl %edx,%ebp + addl %ebp,%edi + movl %eax,%ebp + rorl $2,%ebx + movl %esi,8(%esp) + roll $5,%ebp + leal 1518500249(%esi,%edi,1),%esi + movl 12(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 20(%esp),%edi + xorl %ecx,%ebp + xorl 44(%esp),%edi + andl %eax,%ebp + xorl (%esp),%edi + roll $1,%edi + xorl %ecx,%ebp + addl %ebp,%edx + movl %esi,%ebp + rorl $2,%eax + movl %edi,12(%esp) + roll $5,%ebp + leal 1518500249(%edi,%edx,1),%edi + movl 16(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 24(%esp),%edx + xorl %eax,%ebp + xorl 48(%esp),%edx + xorl %ebx,%ebp + xorl 4(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,16(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 20(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 28(%esp),%ecx + xorl %esi,%ebp + xorl 52(%esp),%ecx + xorl %eax,%ebp + xorl 8(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,20(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 24(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 32(%esp),%ebx + xorl %edi,%ebp + xorl 56(%esp),%ebx + xorl %esi,%ebp + xorl 12(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,24(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 28(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 36(%esp),%eax + xorl %edx,%ebp + xorl 60(%esp),%eax + xorl %edi,%ebp + xorl 16(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,28(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 32(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 40(%esp),%esi + xorl %ecx,%ebp + xorl (%esp),%esi + xorl %edx,%ebp + xorl 20(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,32(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 36(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 44(%esp),%edi + xorl %ebx,%ebp + xorl 4(%esp),%edi + xorl %ecx,%ebp + xorl 24(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,36(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl 40(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 48(%esp),%edx + xorl %eax,%ebp + xorl 8(%esp),%edx + xorl %ebx,%ebp + xorl 28(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,40(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 44(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 52(%esp),%ecx + xorl %esi,%ebp + xorl 12(%esp),%ecx + xorl %eax,%ebp + xorl 32(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,44(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 48(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 56(%esp),%ebx + xorl %edi,%ebp + xorl 16(%esp),%ebx + xorl %esi,%ebp + xorl 36(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,48(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 52(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 60(%esp),%eax + xorl %edx,%ebp + xorl 20(%esp),%eax + xorl %edi,%ebp + xorl 40(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,52(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 56(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl (%esp),%esi + xorl %ecx,%ebp + xorl 24(%esp),%esi + xorl %edx,%ebp + xorl 44(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,56(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 60(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 4(%esp),%edi + xorl %ebx,%ebp + xorl 28(%esp),%edi + xorl %ecx,%ebp + xorl 48(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,60(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl (%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 8(%esp),%edx + xorl %eax,%ebp + xorl 32(%esp),%edx + xorl %ebx,%ebp + xorl 52(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 4(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 12(%esp),%ecx + xorl %esi,%ebp + xorl 36(%esp),%ecx + xorl %eax,%ebp + xorl 56(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,4(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 8(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 16(%esp),%ebx + xorl %edi,%ebp + xorl 40(%esp),%ebx + xorl %esi,%ebp + xorl 60(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,8(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 12(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 20(%esp),%eax + xorl %edx,%ebp + xorl 44(%esp),%eax + xorl %edi,%ebp + xorl (%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,12(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 16(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 24(%esp),%esi + xorl %ecx,%ebp + xorl 48(%esp),%esi + xorl %edx,%ebp + xorl 4(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,16(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 20(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 28(%esp),%edi + xorl %ebx,%ebp + xorl 52(%esp),%edi + xorl %ecx,%ebp + xorl 8(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,20(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl 24(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 32(%esp),%edx + xorl %eax,%ebp + xorl 56(%esp),%edx + xorl %ebx,%ebp + xorl 12(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,24(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 28(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 36(%esp),%ecx + xorl %esi,%ebp + xorl 60(%esp),%ecx + xorl %eax,%ebp + xorl 16(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,28(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 32(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 40(%esp),%ebx + xorl %esi,%ebp + xorl (%esp),%ebx + andl %edx,%ebp + xorl 20(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,32(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 36(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 44(%esp),%eax + xorl %edi,%ebp + xorl 4(%esp),%eax + andl %ecx,%ebp + xorl 24(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,36(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 40(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 48(%esp),%esi + xorl %edx,%ebp + xorl 8(%esp),%esi + andl %ebx,%ebp + xorl 28(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,40(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 44(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 52(%esp),%edi + xorl %ecx,%ebp + xorl 12(%esp),%edi + andl %eax,%ebp + xorl 32(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,44(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 48(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 56(%esp),%edx + xorl %ebx,%ebp + xorl 16(%esp),%edx + andl %esi,%ebp + xorl 36(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,48(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 52(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 60(%esp),%ecx + xorl %eax,%ebp + xorl 20(%esp),%ecx + andl %edi,%ebp + xorl 40(%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,52(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 56(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl (%esp),%ebx + xorl %esi,%ebp + xorl 24(%esp),%ebx + andl %edx,%ebp + xorl 44(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,56(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 60(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 4(%esp),%eax + xorl %edi,%ebp + xorl 28(%esp),%eax + andl %ecx,%ebp + xorl 48(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,60(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl (%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 8(%esp),%esi + xorl %edx,%ebp + xorl 32(%esp),%esi + andl %ebx,%ebp + xorl 52(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 4(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 12(%esp),%edi + xorl %ecx,%ebp + xorl 36(%esp),%edi + andl %eax,%ebp + xorl 56(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,4(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 8(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 16(%esp),%edx + xorl %ebx,%ebp + xorl 40(%esp),%edx + andl %esi,%ebp + xorl 60(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,8(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 12(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 20(%esp),%ecx + xorl %eax,%ebp + xorl 44(%esp),%ecx + andl %edi,%ebp + xorl (%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,12(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 16(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 24(%esp),%ebx + xorl %esi,%ebp + xorl 48(%esp),%ebx + andl %edx,%ebp + xorl 4(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,16(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 20(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 28(%esp),%eax + xorl %edi,%ebp + xorl 52(%esp),%eax + andl %ecx,%ebp + xorl 8(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,20(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 24(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 32(%esp),%esi + xorl %edx,%ebp + xorl 56(%esp),%esi + andl %ebx,%ebp + xorl 12(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,24(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 28(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 36(%esp),%edi + xorl %ecx,%ebp + xorl 60(%esp),%edi + andl %eax,%ebp + xorl 16(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,28(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 32(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 40(%esp),%edx + xorl %ebx,%ebp + xorl (%esp),%edx + andl %esi,%ebp + xorl 20(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,32(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 36(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 44(%esp),%ecx + xorl %eax,%ebp + xorl 4(%esp),%ecx + andl %edi,%ebp + xorl 24(%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,36(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 40(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 48(%esp),%ebx + xorl %esi,%ebp + xorl 8(%esp),%ebx + andl %edx,%ebp + xorl 28(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,40(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 44(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 52(%esp),%eax + xorl %edi,%ebp + xorl 12(%esp),%eax + andl %ecx,%ebp + xorl 32(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,44(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 48(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 56(%esp),%esi + xorl %ecx,%ebp + xorl 16(%esp),%esi + xorl %edx,%ebp + xorl 36(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,48(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 52(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 60(%esp),%edi + xorl %ebx,%ebp + xorl 20(%esp),%edi + xorl %ecx,%ebp + xorl 40(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,52(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 56(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl (%esp),%edx + xorl %eax,%ebp + xorl 24(%esp),%edx + xorl %ebx,%ebp + xorl 44(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,56(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 60(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 4(%esp),%ecx + xorl %esi,%ebp + xorl 28(%esp),%ecx + xorl %eax,%ebp + xorl 48(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,60(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl (%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 8(%esp),%ebx + xorl %edi,%ebp + xorl 32(%esp),%ebx + xorl %esi,%ebp + xorl 52(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 4(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 12(%esp),%eax + xorl %edx,%ebp + xorl 36(%esp),%eax + xorl %edi,%ebp + xorl 56(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,4(%esp) + leal 3395469782(%eax,%esi,1),%eax + movl 8(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 16(%esp),%esi + xorl %ecx,%ebp + xorl 40(%esp),%esi + xorl %edx,%ebp + xorl 60(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,8(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 12(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 20(%esp),%edi + xorl %ebx,%ebp + xorl 44(%esp),%edi + xorl %ecx,%ebp + xorl (%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,12(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 16(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 24(%esp),%edx + xorl %eax,%ebp + xorl 48(%esp),%edx + xorl %ebx,%ebp + xorl 4(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,16(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 20(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 28(%esp),%ecx + xorl %esi,%ebp + xorl 52(%esp),%ecx + xorl %eax,%ebp + xorl 8(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,20(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl 24(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 32(%esp),%ebx + xorl %edi,%ebp + xorl 56(%esp),%ebx + xorl %esi,%ebp + xorl 12(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,24(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 28(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 36(%esp),%eax + xorl %edx,%ebp + xorl 60(%esp),%eax + xorl %edi,%ebp + xorl 16(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,28(%esp) + leal 3395469782(%eax,%esi,1),%eax + movl 32(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 40(%esp),%esi + xorl %ecx,%ebp + xorl (%esp),%esi + xorl %edx,%ebp + xorl 20(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,32(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 36(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 44(%esp),%edi + xorl %ebx,%ebp + xorl 4(%esp),%edi + xorl %ecx,%ebp + xorl 24(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,36(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 40(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 48(%esp),%edx + xorl %eax,%ebp + xorl 8(%esp),%edx + xorl %ebx,%ebp + xorl 28(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,40(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 44(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 52(%esp),%ecx + xorl %esi,%ebp + xorl 12(%esp),%ecx + xorl %eax,%ebp + xorl 32(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,44(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl 48(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 56(%esp),%ebx + xorl %edi,%ebp + xorl 16(%esp),%ebx + xorl %esi,%ebp + xorl 36(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,48(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 52(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 60(%esp),%eax + xorl %edx,%ebp + xorl 20(%esp),%eax + xorl %edi,%ebp + xorl 40(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + leal 3395469782(%eax,%esi,1),%eax + movl 56(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl (%esp),%esi + xorl %ecx,%ebp + xorl 24(%esp),%esi + xorl %edx,%ebp + xorl 44(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + leal 3395469782(%esi,%edi,1),%esi + movl 60(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 4(%esp),%edi + xorl %ebx,%ebp + xorl 28(%esp),%edi + xorl %ecx,%ebp + xorl 48(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + leal 3395469782(%edi,%edx,1),%edi + addl %ebp,%edi + movl 96(%esp),%ebp + movl 100(%esp),%edx + addl (%ebp),%edi + addl 4(%ebp),%esi + addl 8(%ebp),%eax + addl 12(%ebp),%ebx + addl 16(%ebp),%ecx + movl %edi,(%ebp) + addl $64,%edx + movl %esi,4(%ebp) + cmpl 104(%esp),%edx + movl %eax,8(%ebp) + movl %ecx,%edi + movl %ebx,12(%ebp) + movl %edx,%esi + movl %ecx,16(%ebp) + jb .L002loop + addl $76,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size sha1_block_data_order,.-.L_sha1_block_data_order_begin +.hidden _sha1_block_data_order_ssse3 +.type _sha1_block_data_order_ssse3,@function +.align 16 +_sha1_block_data_order_ssse3: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L003pic_point +.L003pic_point: + popl %ebp + leal .LK_XX_XX-.L003pic_point(%ebp),%ebp +.Lssse3_shortcut: + movdqa (%ebp),%xmm7 + movdqa 16(%ebp),%xmm0 + movdqa 32(%ebp),%xmm1 + movdqa 48(%ebp),%xmm2 + movdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + movdqa %xmm0,112(%esp) + movdqa %xmm1,128(%esp) + movdqa %xmm2,144(%esp) + shll $6,%edx + movdqa %xmm7,160(%esp) + addl %ebp,%edx + movdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + movdqu -64(%ebp),%xmm0 + movdqu -48(%ebp),%xmm1 + movdqu -32(%ebp),%xmm2 + movdqu -16(%ebp),%xmm3 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + movdqa %xmm7,96(%esp) +.byte 102,15,56,0,222 + paddd %xmm7,%xmm0 + paddd %xmm7,%xmm1 + paddd %xmm7,%xmm2 + movdqa %xmm0,(%esp) + psubd %xmm7,%xmm0 + movdqa %xmm1,16(%esp) + psubd %xmm7,%xmm1 + movdqa %xmm2,32(%esp) + movl %ecx,%ebp + psubd %xmm7,%xmm2 + xorl %edx,%ebp + pshufd $238,%xmm0,%xmm4 + andl %ebp,%esi + jmp .L004loop +.align 16 +.L004loop: + rorl $2,%ebx + xorl %edx,%esi + movl %eax,%ebp + punpcklqdq %xmm1,%xmm4 + movdqa %xmm3,%xmm6 + addl (%esp),%edi + xorl %ecx,%ebx + paddd %xmm3,%xmm7 + movdqa %xmm0,64(%esp) + roll $5,%eax + addl %esi,%edi + psrldq $4,%xmm6 + andl %ebx,%ebp + xorl %ecx,%ebx + pxor %xmm0,%xmm4 + addl %eax,%edi + rorl $7,%eax + pxor %xmm2,%xmm6 + xorl %ecx,%ebp + movl %edi,%esi + addl 4(%esp),%edx + pxor %xmm6,%xmm4 + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm7,48(%esp) + addl %ebp,%edx + andl %eax,%esi + movdqa %xmm4,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + movdqa %xmm4,%xmm6 + xorl %ebx,%esi + pslldq $12,%xmm0 + paddd %xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + psrld $31,%xmm6 + xorl %eax,%edi + roll $5,%edx + movdqa %xmm0,%xmm7 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + psrld $30,%xmm0 + addl %edx,%ecx + rorl $7,%edx + por %xmm6,%xmm4 + xorl %eax,%ebp + movl %ecx,%esi + addl 12(%esp),%ebx + pslld $2,%xmm7 + xorl %edi,%edx + roll $5,%ecx + pxor %xmm0,%xmm4 + movdqa 96(%esp),%xmm0 + addl %ebp,%ebx + andl %edx,%esi + pxor %xmm7,%xmm4 + pshufd $238,%xmm1,%xmm5 + xorl %edi,%edx + addl %ecx,%ebx + rorl $7,%ecx + xorl %edi,%esi + movl %ebx,%ebp + punpcklqdq %xmm2,%xmm5 + movdqa %xmm4,%xmm7 + addl 16(%esp),%eax + xorl %edx,%ecx + paddd %xmm4,%xmm0 + movdqa %xmm1,80(%esp) + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm7 + andl %ecx,%ebp + xorl %edx,%ecx + pxor %xmm1,%xmm5 + addl %ebx,%eax + rorl $7,%ebx + pxor %xmm3,%xmm7 + xorl %edx,%ebp + movl %eax,%esi + addl 20(%esp),%edi + pxor %xmm7,%xmm5 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm0,(%esp) + addl %ebp,%edi + andl %ebx,%esi + movdqa %xmm5,%xmm1 + xorl %ecx,%ebx + addl %eax,%edi + rorl $7,%eax + movdqa %xmm5,%xmm7 + xorl %ecx,%esi + pslldq $12,%xmm1 + paddd %xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + psrld $31,%xmm7 + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm1,%xmm0 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + psrld $30,%xmm1 + addl %edi,%edx + rorl $7,%edi + por %xmm7,%xmm5 + xorl %ebx,%ebp + movl %edx,%esi + addl 28(%esp),%ecx + pslld $2,%xmm0 + xorl %eax,%edi + roll $5,%edx + pxor %xmm1,%xmm5 + movdqa 112(%esp),%xmm1 + addl %ebp,%ecx + andl %edi,%esi + pxor %xmm0,%xmm5 + pshufd $238,%xmm2,%xmm6 + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%edx + xorl %eax,%esi + movl %ecx,%ebp + punpcklqdq %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + addl 32(%esp),%ebx + xorl %edi,%edx + paddd %xmm5,%xmm1 + movdqa %xmm2,96(%esp) + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm0 + andl %edx,%ebp + xorl %edi,%edx + pxor %xmm2,%xmm6 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm4,%xmm0 + xorl %edi,%ebp + movl %ebx,%esi + addl 36(%esp),%eax + pxor %xmm0,%xmm6 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm1,16(%esp) + addl %ebp,%eax + andl %ecx,%esi + movdqa %xmm6,%xmm2 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movdqa %xmm6,%xmm0 + xorl %edx,%esi + pslldq $12,%xmm2 + paddd %xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + psrld $31,%xmm0 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm2,%xmm1 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + psrld $30,%xmm2 + addl %eax,%edi + rorl $7,%eax + por %xmm0,%xmm6 + xorl %ecx,%ebp + movdqa 64(%esp),%xmm0 + movl %edi,%esi + addl 44(%esp),%edx + pslld $2,%xmm1 + xorl %ebx,%eax + roll $5,%edi + pxor %xmm2,%xmm6 + movdqa 112(%esp),%xmm2 + addl %ebp,%edx + andl %eax,%esi + pxor %xmm1,%xmm6 + pshufd $238,%xmm3,%xmm7 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + xorl %ebx,%esi + movl %edx,%ebp + punpcklqdq %xmm4,%xmm7 + movdqa %xmm6,%xmm1 + addl 48(%esp),%ecx + xorl %eax,%edi + paddd %xmm6,%xmm2 + movdqa %xmm3,64(%esp) + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm1 + andl %edi,%ebp + xorl %eax,%edi + pxor %xmm3,%xmm7 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm5,%xmm1 + xorl %eax,%ebp + movl %ecx,%esi + addl 52(%esp),%ebx + pxor %xmm1,%xmm7 + xorl %edi,%edx + roll $5,%ecx + movdqa %xmm2,32(%esp) + addl %ebp,%ebx + andl %edx,%esi + movdqa %xmm7,%xmm3 + xorl %edi,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm7,%xmm1 + xorl %edi,%esi + pslldq $12,%xmm3 + paddd %xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + psrld $31,%xmm1 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm3,%xmm2 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + psrld $30,%xmm3 + addl %ebx,%eax + rorl $7,%ebx + por %xmm1,%xmm7 + xorl %edx,%ebp + movdqa 80(%esp),%xmm1 + movl %eax,%esi + addl 60(%esp),%edi + pslld $2,%xmm2 + xorl %ecx,%ebx + roll $5,%eax + pxor %xmm3,%xmm7 + movdqa 112(%esp),%xmm3 + addl %ebp,%edi + andl %ebx,%esi + pxor %xmm2,%xmm7 + pshufd $238,%xmm6,%xmm2 + xorl %ecx,%ebx + addl %eax,%edi + rorl $7,%eax + pxor %xmm4,%xmm0 + punpcklqdq %xmm7,%xmm2 + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + pxor %xmm1,%xmm0 + movdqa %xmm4,80(%esp) + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm3,%xmm4 + addl %esi,%edx + paddd %xmm7,%xmm3 + andl %eax,%ebp + pxor %xmm2,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + xorl %ebx,%ebp + movdqa %xmm0,%xmm2 + movdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + roll $5,%edx + pslld $2,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + psrld $30,%xmm2 + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + xorl %edi,%edx + roll $5,%ecx + por %xmm2,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + movdqa 96(%esp),%xmm2 + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + pshufd $238,%xmm7,%xmm3 + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 16(%esp),%edi + pxor %xmm5,%xmm1 + punpcklqdq %xmm0,%xmm3 + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + pxor %xmm2,%xmm1 + movdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + movdqa %xmm4,%xmm5 + rorl $7,%ebx + paddd %xmm0,%xmm4 + addl %eax,%edi + pxor %xmm3,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + movdqa %xmm1,%xmm3 + movdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + psrld $30,%xmm3 + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + por %xmm3,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + movdqa 64(%esp),%xmm3 + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + pshufd $238,%xmm0,%xmm4 + addl %ecx,%ebx + addl 32(%esp),%eax + pxor %xmm6,%xmm2 + punpcklqdq %xmm1,%xmm4 + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + pxor %xmm3,%xmm2 + movdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + movdqa 128(%esp),%xmm6 + rorl $7,%ecx + paddd %xmm1,%xmm5 + addl %ebx,%eax + pxor %xmm4,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm4 + movdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + pslld $2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + psrld $30,%xmm4 + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + por %xmm4,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + movdqa 80(%esp),%xmm4 + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + pshufd $238,%xmm1,%xmm5 + addl %edx,%ecx + addl 48(%esp),%ebx + pxor %xmm7,%xmm3 + punpcklqdq %xmm2,%xmm5 + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + pxor %xmm4,%xmm3 + movdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + movdqa %xmm6,%xmm7 + rorl $7,%edx + paddd %xmm2,%xmm6 + addl %ecx,%ebx + pxor %xmm5,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm5 + movdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pslld $2,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + psrld $30,%xmm5 + movl %eax,%ebp + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + por %xmm5,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + movdqa 96(%esp),%xmm5 + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + pshufd $238,%xmm2,%xmm6 + addl %edi,%edx + addl (%esp),%ecx + pxor %xmm0,%xmm4 + punpcklqdq %xmm3,%xmm6 + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + pxor %xmm5,%xmm4 + movdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + movdqa %xmm7,%xmm0 + rorl $7,%edi + paddd %xmm3,%xmm7 + addl %edx,%ecx + pxor %xmm6,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm6 + movdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + pslld $2,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + psrld $30,%xmm6 + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + por %xmm6,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + movdqa 64(%esp),%xmm6 + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + pshufd $238,%xmm3,%xmm7 + addl %eax,%edi + addl 16(%esp),%edx + pxor %xmm1,%xmm5 + punpcklqdq %xmm4,%xmm7 + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + pxor %xmm6,%xmm5 + movdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + movdqa %xmm0,%xmm1 + rorl $7,%eax + paddd %xmm4,%xmm0 + addl %edi,%edx + pxor %xmm7,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm7 + movdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + pslld $2,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + psrld $30,%xmm7 + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + por %xmm7,%xmm5 + addl 28(%esp),%eax + movdqa 80(%esp),%xmm7 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + pshufd $238,%xmm4,%xmm0 + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 32(%esp),%edi + pxor %xmm2,%xmm6 + punpcklqdq %xmm5,%xmm0 + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + pxor %xmm7,%xmm6 + movdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + roll $5,%eax + movdqa %xmm1,%xmm2 + addl %esi,%edi + paddd %xmm5,%xmm1 + xorl %ebx,%ebp + pxor %xmm0,%xmm6 + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + andl %ebx,%ebp + movdqa %xmm6,%xmm0 + movdqa %xmm1,16(%esp) + xorl %ecx,%ebx + rorl $7,%eax + movl %edi,%esi + xorl %ebx,%ebp + roll $5,%edi + pslld $2,%xmm6 + addl %ebp,%edx + xorl %eax,%esi + psrld $30,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%edi + por %xmm0,%xmm6 + movl %edx,%ebp + xorl %eax,%esi + movdqa 96(%esp),%xmm0 + roll $5,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + pshufd $238,%xmm5,%xmm1 + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + rorl $7,%edx + movl %ecx,%esi + xorl %edi,%ebp + roll $5,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 48(%esp),%eax + pxor %xmm3,%xmm7 + punpcklqdq %xmm6,%xmm1 + andl %edx,%esi + xorl %edi,%edx + rorl $7,%ecx + pxor %xmm0,%xmm7 + movdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + roll $5,%ebx + movdqa 144(%esp),%xmm3 + addl %esi,%eax + paddd %xmm6,%xmm2 + xorl %ecx,%ebp + pxor %xmm1,%xmm7 + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + andl %ecx,%ebp + movdqa %xmm7,%xmm1 + movdqa %xmm2,32(%esp) + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%ebp + roll $5,%eax + pslld $2,%xmm7 + addl %ebp,%edi + xorl %ebx,%esi + psrld $30,%xmm1 + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + por %xmm1,%xmm7 + movl %edi,%ebp + xorl %ebx,%esi + movdqa 64(%esp),%xmm1 + roll $5,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + pshufd $238,%xmm6,%xmm2 + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + rorl $7,%edi + movl %edx,%esi + xorl %eax,%ebp + roll $5,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl (%esp),%ebx + pxor %xmm4,%xmm0 + punpcklqdq %xmm7,%xmm2 + andl %edi,%esi + xorl %eax,%edi + rorl $7,%edx + pxor %xmm1,%xmm0 + movdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + roll $5,%ecx + movdqa %xmm3,%xmm4 + addl %esi,%ebx + paddd %xmm7,%xmm3 + xorl %edx,%ebp + pxor %xmm2,%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + andl %edx,%ebp + movdqa %xmm0,%xmm2 + movdqa %xmm3,48(%esp) + xorl %edi,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + pslld $2,%xmm0 + addl %ebp,%eax + xorl %ecx,%esi + psrld $30,%xmm2 + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + por %xmm2,%xmm0 + movl %eax,%ebp + xorl %ecx,%esi + movdqa 80(%esp),%xmm2 + roll $5,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + pshufd $238,%xmm7,%xmm3 + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + rorl $7,%eax + movl %edi,%esi + xorl %ebx,%ebp + roll $5,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 16(%esp),%ecx + pxor %xmm5,%xmm1 + punpcklqdq %xmm0,%xmm3 + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%edi + pxor %xmm2,%xmm1 + movdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + roll $5,%edx + movdqa %xmm4,%xmm5 + addl %esi,%ecx + paddd %xmm0,%xmm4 + xorl %edi,%ebp + pxor %xmm3,%xmm1 + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + andl %edi,%ebp + movdqa %xmm1,%xmm3 + movdqa %xmm4,(%esp) + xorl %eax,%edi + rorl $7,%edx + movl %ecx,%esi + xorl %edi,%ebp + roll $5,%ecx + pslld $2,%xmm1 + addl %ebp,%ebx + xorl %edx,%esi + psrld $30,%xmm3 + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + rorl $7,%ecx + por %xmm3,%xmm1 + movl %ebx,%ebp + xorl %edx,%esi + movdqa 96(%esp),%xmm3 + roll $5,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + pshufd $238,%xmm0,%xmm4 + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%ebp + roll $5,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 32(%esp),%edx + pxor %xmm6,%xmm2 + punpcklqdq %xmm1,%xmm4 + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + pxor %xmm3,%xmm2 + movdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + roll $5,%edi + movdqa %xmm5,%xmm6 + addl %esi,%edx + paddd %xmm1,%xmm5 + xorl %eax,%ebp + pxor %xmm4,%xmm2 + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + andl %eax,%ebp + movdqa %xmm2,%xmm4 + movdqa %xmm5,16(%esp) + xorl %ebx,%eax + rorl $7,%edi + movl %edx,%esi + xorl %eax,%ebp + roll $5,%edx + pslld $2,%xmm2 + addl %ebp,%ecx + xorl %edi,%esi + psrld $30,%xmm4 + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + rorl $7,%edx + por %xmm4,%xmm2 + movl %ecx,%ebp + xorl %edi,%esi + movdqa 64(%esp),%xmm4 + roll $5,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + pshufd $238,%xmm1,%xmm5 + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + addl 48(%esp),%edi + pxor %xmm7,%xmm3 + punpcklqdq %xmm2,%xmm5 + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + pxor %xmm4,%xmm3 + movdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + movdqa %xmm6,%xmm7 + rorl $7,%ebx + paddd %xmm2,%xmm6 + addl %eax,%edi + pxor %xmm5,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + movdqa %xmm3,%xmm5 + movdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + psrld $30,%xmm5 + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + por %xmm5,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + addl (%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + paddd %xmm3,%xmm7 + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + movdqa %xmm7,48(%esp) + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je .L005done + movdqa 160(%esp),%xmm7 + movdqa 176(%esp),%xmm6 + movdqu (%ebp),%xmm0 + movdqu 16(%ebp),%xmm1 + movdqu 32(%ebp),%xmm2 + movdqu 48(%ebp),%xmm3 + addl $64,%ebp +.byte 102,15,56,0,198 + movl %ebp,196(%esp) + movdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx +.byte 102,15,56,0,206 + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + paddd %xmm7,%xmm0 + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + movdqa %xmm0,(%esp) + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + psubd %xmm7,%xmm0 + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi +.byte 102,15,56,0,214 + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + paddd %xmm7,%xmm1 + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + movdqa %xmm1,16(%esp) + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + psubd %xmm7,%xmm1 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax +.byte 102,15,56,0,222 + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + paddd %xmm7,%xmm2 + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + movdqa %xmm2,32(%esp) + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + psubd %xmm7,%xmm2 + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + rorl $7,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %ecx,%ebx + movl %edx,12(%ebp) + xorl %edx,%ebx + movl %edi,16(%ebp) + movl %esi,%ebp + pshufd $238,%xmm0,%xmm4 + andl %ebx,%esi + movl %ebp,%ebx + jmp .L004loop +.align 16 +.L005done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + rorl $7,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_ssse3,.-_sha1_block_data_order_ssse3 +.hidden _sha1_block_data_order_avx +.type _sha1_block_data_order_avx,@function +.align 16 +_sha1_block_data_order_avx: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L006pic_point +.L006pic_point: + popl %ebp + leal .LK_XX_XX-.L006pic_point(%ebp),%ebp +.Lavx_shortcut: + vzeroall + vmovdqa (%ebp),%xmm7 + vmovdqa 16(%ebp),%xmm0 + vmovdqa 32(%ebp),%xmm1 + vmovdqa 48(%ebp),%xmm2 + vmovdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + vmovdqa %xmm0,112(%esp) + vmovdqa %xmm1,128(%esp) + vmovdqa %xmm2,144(%esp) + shll $6,%edx + vmovdqa %xmm7,160(%esp) + addl %ebp,%edx + vmovdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + vmovdqu -64(%ebp),%xmm0 + vmovdqu -48(%ebp),%xmm1 + vmovdqu -32(%ebp),%xmm2 + vmovdqu -16(%ebp),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vmovdqa %xmm7,96(%esp) + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm7,%xmm0,%xmm4 + vpaddd %xmm7,%xmm1,%xmm5 + vpaddd %xmm7,%xmm2,%xmm6 + vmovdqa %xmm4,(%esp) + movl %ecx,%ebp + vmovdqa %xmm5,16(%esp) + xorl %edx,%ebp + vmovdqa %xmm6,32(%esp) + andl %ebp,%esi + jmp .L007loop +.align 16 +.L007loop: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%ebp + addl (%esp),%edi + vpaddd %xmm3,%xmm7,%xmm7 + vmovdqa %xmm0,64(%esp) + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%edi + vpxor %xmm2,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vmovdqa %xmm7,48(%esp) + movl %edi,%esi + addl 4(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%edi,%edi + addl %ebp,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm6 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm0 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrld $30,%xmm0,%xmm7 + vpor %xmm6,%xmm4,%xmm4 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + vpslld $2,%xmm0,%xmm0 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vpxor %xmm7,%xmm4,%xmm4 + movl %ecx,%esi + addl 12(%esp),%ebx + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpxor %xmm0,%xmm4,%xmm4 + addl %ebp,%ebx + andl %edx,%esi + vmovdqa 96(%esp),%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%ebp + addl 16(%esp),%eax + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqa %xmm1,80(%esp) + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vmovdqa %xmm0,(%esp) + movl %eax,%esi + addl 20(%esp),%edi + vpxor %xmm7,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %ebp,%edi + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm7 + xorl %ecx,%ebx + addl %eax,%edi + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm1 + vpaddd %xmm5,%xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm0 + vpor %xmm7,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpxor %xmm0,%xmm5,%xmm5 + movl %edx,%esi + addl 28(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpxor %xmm1,%xmm5,%xmm5 + addl %ebp,%ecx + andl %edi,%esi + vmovdqa 112(%esp),%xmm1 + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%ebp + addl 32(%esp),%ebx + vpaddd %xmm5,%xmm1,%xmm1 + vmovdqa %xmm2,96(%esp) + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + vpxor %xmm2,%xmm6,%xmm6 + xorl %edi,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%ecx,%ecx + xorl %edi,%ebp + vmovdqa %xmm1,16(%esp) + movl %ebx,%esi + addl 36(%esp),%eax + vpxor %xmm0,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + addl %ebp,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm2 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm1 + vpor %xmm0,%xmm6,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + vmovdqa 64(%esp),%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vpxor %xmm1,%xmm6,%xmm6 + movl %edi,%esi + addl 44(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpxor %xmm2,%xmm6,%xmm6 + addl %ebp,%edx + andl %eax,%esi + vmovdqa 112(%esp),%xmm2 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%ebp + addl 48(%esp),%ecx + vpaddd %xmm6,%xmm2,%xmm2 + vmovdqa %xmm3,64(%esp) + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm1 + addl %esi,%ecx + andl %edi,%ebp + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%edi + addl %edx,%ecx + vpxor %xmm5,%xmm1,%xmm1 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vmovdqa %xmm2,32(%esp) + movl %ecx,%esi + addl 52(%esp),%ebx + vpxor %xmm1,%xmm7,%xmm7 + xorl %edi,%edx + shldl $5,%ecx,%ecx + addl %ebp,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm1 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpslldq $12,%xmm7,%xmm3 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm2 + vpor %xmm1,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + vmovdqa 80(%esp),%xmm1 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vpxor %xmm2,%xmm7,%xmm7 + movl %eax,%esi + addl 60(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpxor %xmm3,%xmm7,%xmm7 + addl %ebp,%edi + andl %ebx,%esi + vmovdqa 112(%esp),%xmm3 + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,80(%esp) + xorl %ebx,%eax + shldl $5,%edi,%edi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + addl %esi,%edx + andl %eax,%ebp + vpxor %xmm2,%xmm0,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + vpor %xmm2,%xmm0,%xmm0 + xorl %edi,%edx + shldl $5,%ecx,%ecx + vmovdqa 96(%esp),%xmm2 + addl %esi,%ebx + andl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm3,%xmm1,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm3,%xmm1,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + vmovdqa 64(%esp),%xmm3 + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + vmovdqa 128(%esp),%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm4,%xmm2,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vpor %xmm4,%xmm2,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + vmovdqa 80(%esp),%xmm4 + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + vmovdqa 96(%esp),%xmm5 + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpalignr $8,%xmm2,%xmm3,%xmm6 + vpxor %xmm0,%xmm4,%xmm4 + addl (%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + vmovdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + vmovdqa %xmm7,%xmm0 + vpaddd %xmm3,%xmm7,%xmm7 + shrdl $7,%edi,%edi + addl %edx,%ecx + vpxor %xmm6,%xmm4,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm6 + vmovdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm6,%xmm4,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + vmovdqa 64(%esp),%xmm6 + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpalignr $8,%xmm3,%xmm4,%xmm7 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + vpxor %xmm6,%xmm5,%xmm5 + vmovdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + vmovdqa %xmm0,%xmm1 + vpaddd %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + addl %edi,%edx + vpxor %xmm7,%xmm5,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm7 + vmovdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm7,%xmm5,%xmm5 + addl 28(%esp),%eax + vmovdqa 80(%esp),%xmm7 + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + vmovdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + vmovdqa %xmm1,%xmm2 + vpaddd %xmm5,%xmm1,%xmm1 + shldl $5,%eax,%eax + addl %esi,%edi + vpxor %xmm0,%xmm6,%xmm6 + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + vpsrld $30,%xmm6,%xmm0 + vmovdqa %xmm1,16(%esp) + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + vpor %xmm0,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%edi,%edi + vmovdqa 96(%esp),%xmm0 + movl %edx,%ebp + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm1 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + vmovdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + vmovdqa 144(%esp),%xmm3 + vpaddd %xmm6,%xmm2,%xmm2 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + vpsrld $30,%xmm7,%xmm1 + vmovdqa %xmm2,32(%esp) + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + vpor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vmovdqa 64(%esp),%xmm1 + movl %edi,%ebp + xorl %ebx,%esi + shldl $5,%edi,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + addl (%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm2,%xmm0,%xmm0 + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + vpor %xmm2,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vmovdqa 80(%esp),%xmm2 + movl %eax,%ebp + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%edi,%edi + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm3,%xmm1,%xmm1 + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + vpor %xmm3,%xmm1,%xmm1 + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vmovdqa 96(%esp),%xmm3 + movl %ebx,%ebp + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + vmovdqa %xmm5,%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shldl $5,%edi,%edi + addl %esi,%edx + vpxor %xmm4,%xmm2,%xmm2 + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + vpor %xmm4,%xmm2,%xmm2 + xorl %eax,%edi + shrdl $7,%edx,%edx + vmovdqa 64(%esp),%xmm4 + movl %ecx,%ebp + xorl %edi,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl (%esp),%eax + vpaddd %xmm3,%xmm7,%xmm7 + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm7,48(%esp) + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je .L008done + vmovdqa 160(%esp),%xmm7 + vmovdqa 176(%esp),%xmm6 + vmovdqu (%ebp),%xmm0 + vmovdqu 16(%ebp),%xmm1 + vmovdqu 32(%ebp),%xmm2 + vmovdqu 48(%ebp),%xmm3 + addl $64,%ebp + vpshufb %xmm6,%xmm0,%xmm0 + movl %ebp,196(%esp) + vmovdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpaddd %xmm7,%xmm0,%xmm4 + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,(%esp) + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%ebp + shldl $5,%edx,%edx + vpaddd %xmm7,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vmovdqa %xmm5,16(%esp) + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %edi,%ebp + shldl $5,%edi,%edi + vpaddd %xmm7,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vmovdqa %xmm6,32(%esp) + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,%ebx + movl %ecx,8(%ebp) + xorl %edx,%ebx + movl %edx,12(%ebp) + movl %edi,16(%ebp) + movl %esi,%ebp + andl %ebx,%esi + movl %ebp,%ebx + jmp .L007loop +.align 16 +.L008done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroall + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_avx,.-_sha1_block_data_order_avx +.align 64 +.LK_XX_XX: +.long 1518500249,1518500249,1518500249,1518500249 +.long 1859775393,1859775393,1859775393,1859775393 +.long 2400959708,2400959708,2400959708,2400959708 +.long 3395469782,3395469782,3395469782,3395469782 +.long 66051,67438087,134810123,202182159 +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115 +.byte 102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82 +.byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 +.byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S new file mode 100644 index 00000000..c85ee85c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S @@ -0,0 +1,1525 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + +.globl _sha1_block_data_order +.private_extern _sha1_block_data_order +#ifdef __thumb2__ +.thumb_func _sha1_block_data_order +#endif + +.align 5 +_sha1_block_data_order: +#if __ARM_MAX_ARCH__>=7 +Lsha1_block: + adr r3,Lsha1_block + ldr r12,LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV8_SHA1 + bne LARMv8 + tst r12,#ARMV7_NEON + bne LNEON +#endif + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 + ldmia r0,{r3,r4,r5,r6,r7} +Lloop: + ldr r8,LK_00_19 + mov r14,sp + sub sp,sp,#15*4 + mov r5,r5,ror#30 + mov r6,r6,ror#30 + mov r7,r7,ror#30 @ [6] +L_00_15: +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r6,r8,r6,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r4,r5 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r6,r8,r6,ror#2 @ E+=K_00_19 + eor r10,r4,r5 @ F_xx_xx + add r6,r6,r7,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r3,r10,ror#2 + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r6,r6,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r5,r8,r5,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r3,r4 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r5,r8,r5,ror#2 @ E+=K_00_19 + eor r10,r3,r4 @ F_xx_xx + add r5,r5,r6,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r7,r10,ror#2 + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r5,r5,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r4,r8,r4,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r7,r3 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r4,r8,r4,ror#2 @ E+=K_00_19 + eor r10,r7,r3 @ F_xx_xx + add r4,r4,r5,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r6,r10,ror#2 + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r4,r4,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r3,r8,r3,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r6,r7 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r3,r8,r3,ror#2 @ E+=K_00_19 + eor r10,r6,r7 @ F_xx_xx + add r3,r3,r4,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r5,r10,ror#2 + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r3,r3,r10 @ E+=F_00_19(B,C,D) +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp +#endif + bne L_00_15 @ [((11+4)*5+2)*3] + sub sp,sp,#25*4 +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + add r6,r6,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + add r5,r5,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + add r4,r4,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + add r3,r3,r10 @ E+=F_00_19(B,C,D) + + ldr r8,LK_20_39 @ [+15+16*4] + cmn sp,#0 @ [+3], clear carry to denote 20_39 +L_20_39_or_60_79: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r4,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_20_39(B,C,D) +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp @ preserve carry +#endif + bne L_20_39_or_60_79 @ [+((12+3)*5+2)*4] + bcs L_done @ [+((12+3)*5+2)*4], spare 300 bytes + + ldr r8,LK_40_59 + sub sp,sp,#20*4 @ [+2] +L_40_59: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r4,r10,ror#2 @ F_xx_xx + and r11,r5,r6 @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_40_59(B,C,D) + add r7,r7,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + and r11,r4,r5 @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_40_59(B,C,D) + add r6,r6,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + and r11,r3,r4 @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_40_59(B,C,D) + add r5,r5,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + and r11,r7,r3 @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_40_59(B,C,D) + add r4,r4,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + and r11,r6,r7 @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_40_59(B,C,D) + add r3,r3,r11,ror#2 +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp +#endif + bne L_40_59 @ [+((12+5)*5+2)*4] + + ldr r8,LK_60_79 + sub sp,sp,#20*4 + cmp sp,#0 @ set carry to denote 60_79 + b L_20_39_or_60_79 @ [+4], spare 300 bytes +L_done: + add sp,sp,#80*4 @ "deallocate" stack frame + ldmia r0,{r8,r9,r10,r11,r12} + add r3,r8,r3 + add r4,r9,r4 + add r5,r10,r5,ror#2 + add r6,r11,r6,ror#2 + add r7,r12,r7,ror#2 + stmia r0,{r3,r4,r5,r6,r7} + teq r1,r2 + bne Lloop @ [+18], total 1307 + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif + + +.align 5 +LK_00_19:.word 0x5a827999 +LK_20_39:.word 0x6ed9eba1 +LK_40_59:.word 0x8f1bbcdc +LK_60_79:.word 0xca62c1d6 +#if __ARM_MAX_ARCH__>=7 +LOPENSSL_armcap: +.word OPENSSL_armcap_P-Lsha1_block +#endif +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 5 +#if __ARM_MAX_ARCH__>=7 + + + +#ifdef __thumb2__ +.thumb_func sha1_block_data_order_neon +#endif +.align 4 +sha1_block_data_order_neon: +LNEON: + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 + @ dmb @ errata #451034 on early Cortex A8 + @ vstmdb sp!,{d8-d15} @ ABI specification says so + mov r14,sp + sub r12,sp,#64 + adr r8,LK_00_19 + bic r12,r12,#15 @ align for 128-bit stores + + ldmia r0,{r3,r4,r5,r6,r7} @ load context + mov sp,r12 @ alloca + + vld1.8 {q0,q1},[r1]! @ handles unaligned + veor q15,q15,q15 + vld1.8 {q2,q3},[r1]! + vld1.32 {d28[],d29[]},[r8,:32]! @ load K_00_19 + vrev32.8 q0,q0 @ yes, even on + vrev32.8 q1,q1 @ big-endian... + vrev32.8 q2,q2 + vadd.i32 q8,q0,q14 + vrev32.8 q3,q3 + vadd.i32 q9,q1,q14 + vst1.32 {q8},[r12,:128]! + vadd.i32 q10,q2,q14 + vst1.32 {q9},[r12,:128]! + vst1.32 {q10},[r12,:128]! + ldr r9,[sp] @ big RAW stall + +Loop_neon: + vext.8 q8,q0,q1,#8 + bic r10,r6,r4 + add r7,r7,r9 + and r11,r5,r4 + vadd.i32 q13,q3,q14 + ldr r9,[sp,#4] + add r7,r7,r3,ror#27 + vext.8 q12,q3,q15,#4 + eor r11,r11,r10 + mov r4,r4,ror#2 + add r7,r7,r11 + veor q8,q8,q0 + bic r10,r5,r3 + add r6,r6,r9 + veor q12,q12,q2 + and r11,r4,r3 + ldr r9,[sp,#8] + veor q12,q12,q8 + add r6,r6,r7,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q13,q15,q12,#4 + bic r10,r4,r7 + add r5,r5,r9 + vadd.i32 q8,q12,q12 + and r11,r3,r7 + ldr r9,[sp,#12] + vsri.32 q8,q12,#31 + add r5,r5,r6,ror#27 + eor r11,r11,r10 + mov r7,r7,ror#2 + vshr.u32 q12,q13,#30 + add r5,r5,r11 + bic r10,r3,r6 + vshl.u32 q13,q13,#2 + add r4,r4,r9 + and r11,r7,r6 + veor q8,q8,q12 + ldr r9,[sp,#16] + add r4,r4,r5,ror#27 + veor q8,q8,q13 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q9,q1,q2,#8 + bic r10,r7,r5 + add r3,r3,r9 + and r11,r6,r5 + vadd.i32 q13,q8,q14 + ldr r9,[sp,#20] + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r4,ror#27 + vext.8 q12,q8,q15,#4 + eor r11,r11,r10 + mov r5,r5,ror#2 + add r3,r3,r11 + veor q9,q9,q1 + bic r10,r6,r4 + add r7,r7,r9 + veor q12,q12,q3 + and r11,r5,r4 + ldr r9,[sp,#24] + veor q12,q12,q9 + add r7,r7,r3,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q13,q15,q12,#4 + bic r10,r5,r3 + add r6,r6,r9 + vadd.i32 q9,q12,q12 + and r11,r4,r3 + ldr r9,[sp,#28] + vsri.32 q9,q12,#31 + add r6,r6,r7,ror#27 + eor r11,r11,r10 + mov r3,r3,ror#2 + vshr.u32 q12,q13,#30 + add r6,r6,r11 + bic r10,r4,r7 + vshl.u32 q13,q13,#2 + add r5,r5,r9 + and r11,r3,r7 + veor q9,q9,q12 + ldr r9,[sp,#32] + add r5,r5,r6,ror#27 + veor q9,q9,q13 + eor r11,r11,r10 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q10,q2,q3,#8 + bic r10,r3,r6 + add r4,r4,r9 + and r11,r7,r6 + vadd.i32 q13,q9,q14 + ldr r9,[sp,#36] + add r4,r4,r5,ror#27 + vext.8 q12,q9,q15,#4 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + veor q10,q10,q2 + bic r10,r7,r5 + add r3,r3,r9 + veor q12,q12,q8 + and r11,r6,r5 + ldr r9,[sp,#40] + veor q12,q12,q10 + add r3,r3,r4,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q13,q15,q12,#4 + bic r10,r6,r4 + add r7,r7,r9 + vadd.i32 q10,q12,q12 + and r11,r5,r4 + ldr r9,[sp,#44] + vsri.32 q10,q12,#31 + add r7,r7,r3,ror#27 + eor r11,r11,r10 + mov r4,r4,ror#2 + vshr.u32 q12,q13,#30 + add r7,r7,r11 + bic r10,r5,r3 + vshl.u32 q13,q13,#2 + add r6,r6,r9 + and r11,r4,r3 + veor q10,q10,q12 + ldr r9,[sp,#48] + add r6,r6,r7,ror#27 + veor q10,q10,q13 + eor r11,r11,r10 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q11,q3,q8,#8 + bic r10,r4,r7 + add r5,r5,r9 + and r11,r3,r7 + vadd.i32 q13,q10,q14 + ldr r9,[sp,#52] + add r5,r5,r6,ror#27 + vext.8 q12,q10,q15,#4 + eor r11,r11,r10 + mov r7,r7,ror#2 + add r5,r5,r11 + veor q11,q11,q3 + bic r10,r3,r6 + add r4,r4,r9 + veor q12,q12,q9 + and r11,r7,r6 + ldr r9,[sp,#56] + veor q12,q12,q11 + add r4,r4,r5,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q13,q15,q12,#4 + bic r10,r7,r5 + add r3,r3,r9 + vadd.i32 q11,q12,q12 + and r11,r6,r5 + ldr r9,[sp,#60] + vsri.32 q11,q12,#31 + add r3,r3,r4,ror#27 + eor r11,r11,r10 + mov r5,r5,ror#2 + vshr.u32 q12,q13,#30 + add r3,r3,r11 + bic r10,r6,r4 + vshl.u32 q13,q13,#2 + add r7,r7,r9 + and r11,r5,r4 + veor q11,q11,q12 + ldr r9,[sp,#0] + add r7,r7,r3,ror#27 + veor q11,q11,q13 + eor r11,r11,r10 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q10,q11,#8 + bic r10,r5,r3 + add r6,r6,r9 + and r11,r4,r3 + veor q0,q0,q8 + ldr r9,[sp,#4] + add r6,r6,r7,ror#27 + veor q0,q0,q1 + eor r11,r11,r10 + mov r3,r3,ror#2 + vadd.i32 q13,q11,q14 + add r6,r6,r11 + bic r10,r4,r7 + veor q12,q12,q0 + add r5,r5,r9 + and r11,r3,r7 + vshr.u32 q0,q12,#30 + ldr r9,[sp,#8] + add r5,r5,r6,ror#27 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + eor r11,r11,r10 + mov r7,r7,ror#2 + vsli.32 q0,q12,#2 + add r5,r5,r11 + bic r10,r3,r6 + add r4,r4,r9 + and r11,r7,r6 + ldr r9,[sp,#12] + add r4,r4,r5,ror#27 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + bic r10,r7,r5 + add r3,r3,r9 + and r11,r6,r5 + ldr r9,[sp,#16] + add r3,r3,r4,ror#27 + eor r11,r11,r10 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q11,q0,#8 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#20] + veor q1,q1,q9 + eor r11,r10,r5 + add r7,r7,r3,ror#27 + veor q1,q1,q2 + mov r4,r4,ror#2 + add r7,r7,r11 + vadd.i32 q13,q0,q14 + eor r10,r3,r5 + add r6,r6,r9 + veor q12,q12,q1 + ldr r9,[sp,#24] + eor r11,r10,r4 + vshr.u32 q1,q12,#30 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + vst1.32 {q13},[r12,:128]! + add r6,r6,r11 + eor r10,r7,r4 + vsli.32 q1,q12,#2 + add r5,r5,r9 + ldr r9,[sp,#28] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#32] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q12,q0,q1,#8 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#36] + veor q2,q2,q10 + eor r11,r10,r6 + add r3,r3,r4,ror#27 + veor q2,q2,q3 + mov r5,r5,ror#2 + add r3,r3,r11 + vadd.i32 q13,q1,q14 + eor r10,r4,r6 + vld1.32 {d28[],d29[]},[r8,:32]! + add r7,r7,r9 + veor q12,q12,q2 + ldr r9,[sp,#40] + eor r11,r10,r5 + vshr.u32 q2,q12,#30 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + vst1.32 {q13},[r12,:128]! + add r7,r7,r11 + eor r10,r3,r5 + vsli.32 q2,q12,#2 + add r6,r6,r9 + ldr r9,[sp,#44] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#48] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q12,q1,q2,#8 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#52] + veor q3,q3,q11 + eor r11,r10,r7 + add r4,r4,r5,ror#27 + veor q3,q3,q8 + mov r6,r6,ror#2 + add r4,r4,r11 + vadd.i32 q13,q2,q14 + eor r10,r5,r7 + add r3,r3,r9 + veor q12,q12,q3 + ldr r9,[sp,#56] + eor r11,r10,r6 + vshr.u32 q3,q12,#30 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + vst1.32 {q13},[r12,:128]! + add r3,r3,r11 + eor r10,r4,r6 + vsli.32 q3,q12,#2 + add r7,r7,r9 + ldr r9,[sp,#60] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#0] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q12,q2,q3,#8 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#4] + veor q8,q8,q0 + eor r11,r10,r3 + add r5,r5,r6,ror#27 + veor q8,q8,q9 + mov r7,r7,ror#2 + add r5,r5,r11 + vadd.i32 q13,q3,q14 + eor r10,r6,r3 + add r4,r4,r9 + veor q12,q12,q8 + ldr r9,[sp,#8] + eor r11,r10,r7 + vshr.u32 q8,q12,#30 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + add r4,r4,r11 + eor r10,r5,r7 + vsli.32 q8,q12,#2 + add r3,r3,r9 + ldr r9,[sp,#12] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#16] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q3,q8,#8 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#20] + veor q9,q9,q1 + eor r11,r10,r4 + add r6,r6,r7,ror#27 + veor q9,q9,q10 + mov r3,r3,ror#2 + add r6,r6,r11 + vadd.i32 q13,q8,q14 + eor r10,r7,r4 + add r5,r5,r9 + veor q12,q12,q9 + ldr r9,[sp,#24] + eor r11,r10,r3 + vshr.u32 q9,q12,#30 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + vst1.32 {q13},[r12,:128]! + add r5,r5,r11 + eor r10,r6,r3 + vsli.32 q9,q12,#2 + add r4,r4,r9 + ldr r9,[sp,#28] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#32] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q8,q9,#8 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#36] + veor q10,q10,q2 + add r7,r7,r3,ror#27 + eor r11,r5,r6 + veor q10,q10,q11 + add r7,r7,r10 + and r11,r11,r4 + vadd.i32 q13,q9,q14 + mov r4,r4,ror#2 + add r7,r7,r11 + veor q12,q12,q10 + add r6,r6,r9 + and r10,r4,r5 + vshr.u32 q10,q12,#30 + ldr r9,[sp,#40] + add r6,r6,r7,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r4,r5 + add r6,r6,r10 + vsli.32 q10,q12,#2 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#44] + add r5,r5,r6,ror#27 + eor r11,r3,r4 + add r5,r5,r10 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#48] + add r4,r4,r5,ror#27 + eor r11,r7,r3 + add r4,r4,r10 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q12,q9,q10,#8 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#52] + veor q11,q11,q3 + add r3,r3,r4,ror#27 + eor r11,r6,r7 + veor q11,q11,q0 + add r3,r3,r10 + and r11,r11,r5 + vadd.i32 q13,q10,q14 + mov r5,r5,ror#2 + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r11 + veor q12,q12,q11 + add r7,r7,r9 + and r10,r5,r6 + vshr.u32 q11,q12,#30 + ldr r9,[sp,#56] + add r7,r7,r3,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r5,r6 + add r7,r7,r10 + vsli.32 q11,q12,#2 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#60] + add r6,r6,r7,ror#27 + eor r11,r4,r5 + add r6,r6,r10 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#0] + add r5,r5,r6,ror#27 + eor r11,r3,r4 + add r5,r5,r10 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q12,q10,q11,#8 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#4] + veor q0,q0,q8 + add r4,r4,r5,ror#27 + eor r11,r7,r3 + veor q0,q0,q1 + add r4,r4,r10 + and r11,r11,r6 + vadd.i32 q13,q11,q14 + mov r6,r6,ror#2 + add r4,r4,r11 + veor q12,q12,q0 + add r3,r3,r9 + and r10,r6,r7 + vshr.u32 q0,q12,#30 + ldr r9,[sp,#8] + add r3,r3,r4,ror#27 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + eor r11,r6,r7 + add r3,r3,r10 + vsli.32 q0,q12,#2 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#12] + add r7,r7,r3,ror#27 + eor r11,r5,r6 + add r7,r7,r10 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#16] + add r6,r6,r7,ror#27 + eor r11,r4,r5 + add r6,r6,r10 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q12,q11,q0,#8 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#20] + veor q1,q1,q9 + add r5,r5,r6,ror#27 + eor r11,r3,r4 + veor q1,q1,q2 + add r5,r5,r10 + and r11,r11,r7 + vadd.i32 q13,q0,q14 + mov r7,r7,ror#2 + add r5,r5,r11 + veor q12,q12,q1 + add r4,r4,r9 + and r10,r7,r3 + vshr.u32 q1,q12,#30 + ldr r9,[sp,#24] + add r4,r4,r5,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r7,r3 + add r4,r4,r10 + vsli.32 q1,q12,#2 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#28] + add r3,r3,r4,ror#27 + eor r11,r6,r7 + add r3,r3,r10 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#32] + add r7,r7,r3,ror#27 + eor r11,r5,r6 + add r7,r7,r10 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q0,q1,#8 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#36] + veor q2,q2,q10 + add r6,r6,r7,ror#27 + eor r11,r4,r5 + veor q2,q2,q3 + add r6,r6,r10 + and r11,r11,r3 + vadd.i32 q13,q1,q14 + mov r3,r3,ror#2 + add r6,r6,r11 + veor q12,q12,q2 + add r5,r5,r9 + and r10,r3,r4 + vshr.u32 q2,q12,#30 + ldr r9,[sp,#40] + add r5,r5,r6,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r3,r4 + add r5,r5,r10 + vsli.32 q2,q12,#2 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#44] + add r4,r4,r5,ror#27 + eor r11,r7,r3 + add r4,r4,r10 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#48] + add r3,r3,r4,ror#27 + eor r11,r6,r7 + add r3,r3,r10 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q1,q2,#8 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#52] + veor q3,q3,q11 + eor r11,r10,r5 + add r7,r7,r3,ror#27 + veor q3,q3,q8 + mov r4,r4,ror#2 + add r7,r7,r11 + vadd.i32 q13,q2,q14 + eor r10,r3,r5 + add r6,r6,r9 + veor q12,q12,q3 + ldr r9,[sp,#56] + eor r11,r10,r4 + vshr.u32 q3,q12,#30 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + vst1.32 {q13},[r12,:128]! + add r6,r6,r11 + eor r10,r7,r4 + vsli.32 q3,q12,#2 + add r5,r5,r9 + ldr r9,[sp,#60] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#0] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + vadd.i32 q13,q3,q14 + eor r10,r5,r7 + add r3,r3,r9 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + teq r1,r2 + sub r8,r8,#16 + it eq + subeq r1,r1,#64 + vld1.8 {q0,q1},[r1]! + ldr r9,[sp,#4] + eor r11,r10,r6 + vld1.8 {q2,q3},[r1]! + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r11 + eor r10,r4,r6 + vrev32.8 q0,q0 + add r7,r7,r9 + ldr r9,[sp,#8] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#12] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#16] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + vrev32.8 q1,q1 + eor r10,r6,r3 + add r4,r4,r9 + vadd.i32 q8,q0,q14 + ldr r9,[sp,#20] + eor r11,r10,r7 + vst1.32 {q8},[r12,:128]! + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#24] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#28] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#32] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + vrev32.8 q2,q2 + eor r10,r7,r4 + add r5,r5,r9 + vadd.i32 q9,q1,q14 + ldr r9,[sp,#36] + eor r11,r10,r3 + vst1.32 {q9},[r12,:128]! + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#40] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#44] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#48] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + vrev32.8 q3,q3 + eor r10,r3,r5 + add r6,r6,r9 + vadd.i32 q10,q2,q14 + ldr r9,[sp,#52] + eor r11,r10,r4 + vst1.32 {q10},[r12,:128]! + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#56] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#60] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + ldmia r0,{r9,r10,r11,r12} @ accumulate context + add r3,r3,r9 + ldr r9,[r0,#16] + add r4,r4,r10 + add r5,r5,r11 + add r6,r6,r12 + it eq + moveq sp,r14 + add r7,r7,r9 + it ne + ldrne r9,[sp] + stmia r0,{r3,r4,r5,r6,r7} + itt ne + addne r12,sp,#3*16 + bne Loop_neon + + @ vldmia sp!,{d8-d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} + +#endif +#if __ARM_MAX_ARCH__>=7 + +# if defined(__thumb2__) +# define INST(a,b,c,d) .byte c,d|0xf,a,b +# else +# define INST(a,b,c,d) .byte a,b,c,d|0x10 +# endif + +#ifdef __thumb2__ +.thumb_func sha1_block_data_order_armv8 +#endif +.align 5 +sha1_block_data_order_armv8: +LARMv8: + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + + veor q1,q1,q1 + adr r3,LK_00_19 + vld1.32 {q0},[r0]! + vld1.32 {d2[0]},[r0] + sub r0,r0,#16 + vld1.32 {d16[],d17[]},[r3,:32]! + vld1.32 {d18[],d19[]},[r3,:32]! + vld1.32 {d20[],d21[]},[r3,:32]! + vld1.32 {d22[],d23[]},[r3,:32] + +Loop_v8: + vld1.8 {q4,q5},[r1]! + vld1.8 {q6,q7},[r1]! + vrev32.8 q4,q4 + vrev32.8 q5,q5 + + vadd.i32 q12,q8,q4 + vrev32.8 q6,q6 + vmov q14,q0 @ offload + subs r2,r2,#1 + + vadd.i32 q13,q8,q5 + vrev32.8 q7,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 0 + INST(0x68,0x0c,0x02,0xe2) @ sha1c q0,q1,q12 + vadd.i32 q12,q8,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 1 + INST(0x6a,0x0c,0x06,0xe2) @ sha1c q0,q3,q13 + vadd.i32 q13,q8,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 2 + INST(0x68,0x0c,0x04,0xe2) @ sha1c q0,q2,q12 + vadd.i32 q12,q8,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 3 + INST(0x6a,0x0c,0x06,0xe2) @ sha1c q0,q3,q13 + vadd.i32 q13,q9,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 4 + INST(0x68,0x0c,0x04,0xe2) @ sha1c q0,q2,q12 + vadd.i32 q12,q9,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 5 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q9,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 6 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q9,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 7 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q9,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 8 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q10,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 9 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q10,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 10 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q10,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 11 + INST(0x6a,0x0c,0x26,0xe2) @ sha1m q0,q3,q13 + vadd.i32 q13,q10,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 12 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q10,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 13 + INST(0x6a,0x0c,0x26,0xe2) @ sha1m q0,q3,q13 + vadd.i32 q13,q11,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 14 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q11,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 15 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q11,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 16 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q11,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 17 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q11,q7 + + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 18 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 19 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + + vadd.i32 q1,q1,q2 + vadd.i32 q0,q0,q14 + bne Loop_v8 + + vst1.32 {q0},[r0]! + vst1.32 {d2[0]},[r0] + + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + bx lr @ bx lr + +#endif +#if __ARM_MAX_ARCH__>=7 +.comm _OPENSSL_armcap_P,4 +.non_lazy_symbol_pointer +OPENSSL_armcap_P: +.indirect_symbol _OPENSSL_armcap_P +.long 0 +.private_extern _OPENSSL_armcap_P +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S new file mode 100644 index 00000000..6907a0b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S @@ -0,0 +1,1518 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + +.globl sha1_block_data_order +.hidden sha1_block_data_order +.type sha1_block_data_order,%function + +.align 5 +sha1_block_data_order: +#if __ARM_MAX_ARCH__>=7 +.Lsha1_block: + adr r3,.Lsha1_block + ldr r12,.LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV8_SHA1 + bne .LARMv8 + tst r12,#ARMV7_NEON + bne .LNEON +#endif + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 + ldmia r0,{r3,r4,r5,r6,r7} +.Lloop: + ldr r8,.LK_00_19 + mov r14,sp + sub sp,sp,#15*4 + mov r5,r5,ror#30 + mov r6,r6,ror#30 + mov r7,r7,ror#30 @ [6] +.L_00_15: +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r6,r8,r6,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r4,r5 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r6,r8,r6,ror#2 @ E+=K_00_19 + eor r10,r4,r5 @ F_xx_xx + add r6,r6,r7,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r3,r10,ror#2 + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r6,r6,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r5,r8,r5,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r3,r4 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r5,r8,r5,ror#2 @ E+=K_00_19 + eor r10,r3,r4 @ F_xx_xx + add r5,r5,r6,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r7,r10,ror#2 + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r5,r5,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r4,r8,r4,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r7,r3 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r4,r8,r4,ror#2 @ E+=K_00_19 + eor r10,r7,r3 @ F_xx_xx + add r4,r4,r5,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r6,r10,ror#2 + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r4,r4,r10 @ E+=F_00_19(B,C,D) +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r3,r8,r3,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r6,r7 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r3,r8,r3,ror#2 @ E+=K_00_19 + eor r10,r6,r7 @ F_xx_xx + add r3,r3,r4,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r5,r10,ror#2 + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r3,r3,r10 @ E+=F_00_19(B,C,D) +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp +#endif + bne .L_00_15 @ [((11+4)*5+2)*3] + sub sp,sp,#25*4 +#if __ARM_ARCH__<7 + ldrb r10,[r1,#2] + ldrb r9,[r1,#3] + ldrb r11,[r1,#1] + add r7,r8,r7,ror#2 @ E+=K_00_19 + ldrb r12,[r1],#4 + orr r9,r9,r10,lsl#8 + eor r10,r5,r6 @ F_xx_xx + orr r9,r9,r11,lsl#16 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + orr r9,r9,r12,lsl#24 +#else + ldr r9,[r1],#4 @ handles unaligned + add r7,r8,r7,ror#2 @ E+=K_00_19 + eor r10,r5,r6 @ F_xx_xx + add r7,r7,r3,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev r9,r9 @ byte swap +#endif +#endif + and r10,r4,r10,ror#2 + add r7,r7,r9 @ E+=X[i] + eor r10,r10,r6,ror#2 @ F_00_19(B,C,D) + str r9,[r14,#-4]! + add r7,r7,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + eor r10,r10,r5,ror#2 @ F_00_19(B,C,D) + add r6,r6,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + eor r10,r10,r4,ror#2 @ F_00_19(B,C,D) + add r5,r5,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + eor r10,r10,r3,ror#2 @ F_00_19(B,C,D) + add r4,r4,r10 @ E+=F_00_19(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + eor r10,r10,r7,ror#2 @ F_00_19(B,C,D) + add r3,r3,r10 @ E+=F_00_19(B,C,D) + + ldr r8,.LK_20_39 @ [+15+16*4] + cmn sp,#0 @ [+3], clear carry to denote 20_39 +.L_20_39_or_60_79: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r4,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r3,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r7,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r6,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_20_39(B,C,D) + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + eor r10,r5,r10,ror#2 @ F_xx_xx + @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_20_39(B,C,D) +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp @ preserve carry +#endif + bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4] + bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes + + ldr r8,.LK_40_59 + sub sp,sp,#20*4 @ [+2] +.L_40_59: + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r7,r8,r7,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r5,r6 @ F_xx_xx + mov r9,r9,ror#31 + add r7,r7,r3,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r4,r10,ror#2 @ F_xx_xx + and r11,r5,r6 @ F_xx_xx + add r7,r7,r9 @ E+=X[i] + add r7,r7,r10 @ E+=F_40_59(B,C,D) + add r7,r7,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r6,r8,r6,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r4,r5 @ F_xx_xx + mov r9,r9,ror#31 + add r6,r6,r7,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r3,r10,ror#2 @ F_xx_xx + and r11,r4,r5 @ F_xx_xx + add r6,r6,r9 @ E+=X[i] + add r6,r6,r10 @ E+=F_40_59(B,C,D) + add r6,r6,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r5,r8,r5,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r3,r4 @ F_xx_xx + mov r9,r9,ror#31 + add r5,r5,r6,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r7,r10,ror#2 @ F_xx_xx + and r11,r3,r4 @ F_xx_xx + add r5,r5,r9 @ E+=X[i] + add r5,r5,r10 @ E+=F_40_59(B,C,D) + add r5,r5,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r4,r8,r4,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r7,r3 @ F_xx_xx + mov r9,r9,ror#31 + add r4,r4,r5,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r6,r10,ror#2 @ F_xx_xx + and r11,r7,r3 @ F_xx_xx + add r4,r4,r9 @ E+=X[i] + add r4,r4,r10 @ E+=F_40_59(B,C,D) + add r4,r4,r11,ror#2 + ldr r9,[r14,#15*4] + ldr r10,[r14,#13*4] + ldr r11,[r14,#7*4] + add r3,r8,r3,ror#2 @ E+=K_xx_xx + ldr r12,[r14,#2*4] + eor r9,r9,r10 + eor r11,r11,r12 @ 1 cycle stall + eor r10,r6,r7 @ F_xx_xx + mov r9,r9,ror#31 + add r3,r3,r4,ror#27 @ E+=ROR(A,27) + eor r9,r9,r11,ror#31 + str r9,[r14,#-4]! + and r10,r5,r10,ror#2 @ F_xx_xx + and r11,r6,r7 @ F_xx_xx + add r3,r3,r9 @ E+=X[i] + add r3,r3,r10 @ E+=F_40_59(B,C,D) + add r3,r3,r11,ror#2 +#if defined(__thumb2__) + mov r12,sp + teq r14,r12 +#else + teq r14,sp +#endif + bne .L_40_59 @ [+((12+5)*5+2)*4] + + ldr r8,.LK_60_79 + sub sp,sp,#20*4 + cmp sp,#0 @ set carry to denote 60_79 + b .L_20_39_or_60_79 @ [+4], spare 300 bytes +.L_done: + add sp,sp,#80*4 @ "deallocate" stack frame + ldmia r0,{r8,r9,r10,r11,r12} + add r3,r8,r3 + add r4,r9,r4 + add r5,r10,r5,ror#2 + add r6,r11,r6,ror#2 + add r7,r12,r7,ror#2 + stmia r0,{r3,r4,r5,r6,r7} + teq r1,r2 + bne .Lloop @ [+18], total 1307 + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size sha1_block_data_order,.-sha1_block_data_order + +.align 5 +.LK_00_19:.word 0x5a827999 +.LK_20_39:.word 0x6ed9eba1 +.LK_40_59:.word 0x8f1bbcdc +.LK_60_79:.word 0xca62c1d6 +#if __ARM_MAX_ARCH__>=7 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.Lsha1_block +#endif +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 5 +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.type sha1_block_data_order_neon,%function +.align 4 +sha1_block_data_order_neon: +.LNEON: + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 + @ dmb @ errata #451034 on early Cortex A8 + @ vstmdb sp!,{d8-d15} @ ABI specification says so + mov r14,sp + sub r12,sp,#64 + adr r8,.LK_00_19 + bic r12,r12,#15 @ align for 128-bit stores + + ldmia r0,{r3,r4,r5,r6,r7} @ load context + mov sp,r12 @ alloca + + vld1.8 {q0,q1},[r1]! @ handles unaligned + veor q15,q15,q15 + vld1.8 {q2,q3},[r1]! + vld1.32 {d28[],d29[]},[r8,:32]! @ load K_00_19 + vrev32.8 q0,q0 @ yes, even on + vrev32.8 q1,q1 @ big-endian... + vrev32.8 q2,q2 + vadd.i32 q8,q0,q14 + vrev32.8 q3,q3 + vadd.i32 q9,q1,q14 + vst1.32 {q8},[r12,:128]! + vadd.i32 q10,q2,q14 + vst1.32 {q9},[r12,:128]! + vst1.32 {q10},[r12,:128]! + ldr r9,[sp] @ big RAW stall + +.Loop_neon: + vext.8 q8,q0,q1,#8 + bic r10,r6,r4 + add r7,r7,r9 + and r11,r5,r4 + vadd.i32 q13,q3,q14 + ldr r9,[sp,#4] + add r7,r7,r3,ror#27 + vext.8 q12,q3,q15,#4 + eor r11,r11,r10 + mov r4,r4,ror#2 + add r7,r7,r11 + veor q8,q8,q0 + bic r10,r5,r3 + add r6,r6,r9 + veor q12,q12,q2 + and r11,r4,r3 + ldr r9,[sp,#8] + veor q12,q12,q8 + add r6,r6,r7,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q13,q15,q12,#4 + bic r10,r4,r7 + add r5,r5,r9 + vadd.i32 q8,q12,q12 + and r11,r3,r7 + ldr r9,[sp,#12] + vsri.32 q8,q12,#31 + add r5,r5,r6,ror#27 + eor r11,r11,r10 + mov r7,r7,ror#2 + vshr.u32 q12,q13,#30 + add r5,r5,r11 + bic r10,r3,r6 + vshl.u32 q13,q13,#2 + add r4,r4,r9 + and r11,r7,r6 + veor q8,q8,q12 + ldr r9,[sp,#16] + add r4,r4,r5,ror#27 + veor q8,q8,q13 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q9,q1,q2,#8 + bic r10,r7,r5 + add r3,r3,r9 + and r11,r6,r5 + vadd.i32 q13,q8,q14 + ldr r9,[sp,#20] + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r4,ror#27 + vext.8 q12,q8,q15,#4 + eor r11,r11,r10 + mov r5,r5,ror#2 + add r3,r3,r11 + veor q9,q9,q1 + bic r10,r6,r4 + add r7,r7,r9 + veor q12,q12,q3 + and r11,r5,r4 + ldr r9,[sp,#24] + veor q12,q12,q9 + add r7,r7,r3,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q13,q15,q12,#4 + bic r10,r5,r3 + add r6,r6,r9 + vadd.i32 q9,q12,q12 + and r11,r4,r3 + ldr r9,[sp,#28] + vsri.32 q9,q12,#31 + add r6,r6,r7,ror#27 + eor r11,r11,r10 + mov r3,r3,ror#2 + vshr.u32 q12,q13,#30 + add r6,r6,r11 + bic r10,r4,r7 + vshl.u32 q13,q13,#2 + add r5,r5,r9 + and r11,r3,r7 + veor q9,q9,q12 + ldr r9,[sp,#32] + add r5,r5,r6,ror#27 + veor q9,q9,q13 + eor r11,r11,r10 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q10,q2,q3,#8 + bic r10,r3,r6 + add r4,r4,r9 + and r11,r7,r6 + vadd.i32 q13,q9,q14 + ldr r9,[sp,#36] + add r4,r4,r5,ror#27 + vext.8 q12,q9,q15,#4 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + veor q10,q10,q2 + bic r10,r7,r5 + add r3,r3,r9 + veor q12,q12,q8 + and r11,r6,r5 + ldr r9,[sp,#40] + veor q12,q12,q10 + add r3,r3,r4,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q13,q15,q12,#4 + bic r10,r6,r4 + add r7,r7,r9 + vadd.i32 q10,q12,q12 + and r11,r5,r4 + ldr r9,[sp,#44] + vsri.32 q10,q12,#31 + add r7,r7,r3,ror#27 + eor r11,r11,r10 + mov r4,r4,ror#2 + vshr.u32 q12,q13,#30 + add r7,r7,r11 + bic r10,r5,r3 + vshl.u32 q13,q13,#2 + add r6,r6,r9 + and r11,r4,r3 + veor q10,q10,q12 + ldr r9,[sp,#48] + add r6,r6,r7,ror#27 + veor q10,q10,q13 + eor r11,r11,r10 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q11,q3,q8,#8 + bic r10,r4,r7 + add r5,r5,r9 + and r11,r3,r7 + vadd.i32 q13,q10,q14 + ldr r9,[sp,#52] + add r5,r5,r6,ror#27 + vext.8 q12,q10,q15,#4 + eor r11,r11,r10 + mov r7,r7,ror#2 + add r5,r5,r11 + veor q11,q11,q3 + bic r10,r3,r6 + add r4,r4,r9 + veor q12,q12,q9 + and r11,r7,r6 + ldr r9,[sp,#56] + veor q12,q12,q11 + add r4,r4,r5,ror#27 + eor r11,r11,r10 + vst1.32 {q13},[r12,:128]! + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q13,q15,q12,#4 + bic r10,r7,r5 + add r3,r3,r9 + vadd.i32 q11,q12,q12 + and r11,r6,r5 + ldr r9,[sp,#60] + vsri.32 q11,q12,#31 + add r3,r3,r4,ror#27 + eor r11,r11,r10 + mov r5,r5,ror#2 + vshr.u32 q12,q13,#30 + add r3,r3,r11 + bic r10,r6,r4 + vshl.u32 q13,q13,#2 + add r7,r7,r9 + and r11,r5,r4 + veor q11,q11,q12 + ldr r9,[sp,#0] + add r7,r7,r3,ror#27 + veor q11,q11,q13 + eor r11,r11,r10 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q10,q11,#8 + bic r10,r5,r3 + add r6,r6,r9 + and r11,r4,r3 + veor q0,q0,q8 + ldr r9,[sp,#4] + add r6,r6,r7,ror#27 + veor q0,q0,q1 + eor r11,r11,r10 + mov r3,r3,ror#2 + vadd.i32 q13,q11,q14 + add r6,r6,r11 + bic r10,r4,r7 + veor q12,q12,q0 + add r5,r5,r9 + and r11,r3,r7 + vshr.u32 q0,q12,#30 + ldr r9,[sp,#8] + add r5,r5,r6,ror#27 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + eor r11,r11,r10 + mov r7,r7,ror#2 + vsli.32 q0,q12,#2 + add r5,r5,r11 + bic r10,r3,r6 + add r4,r4,r9 + and r11,r7,r6 + ldr r9,[sp,#12] + add r4,r4,r5,ror#27 + eor r11,r11,r10 + mov r6,r6,ror#2 + add r4,r4,r11 + bic r10,r7,r5 + add r3,r3,r9 + and r11,r6,r5 + ldr r9,[sp,#16] + add r3,r3,r4,ror#27 + eor r11,r11,r10 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q11,q0,#8 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#20] + veor q1,q1,q9 + eor r11,r10,r5 + add r7,r7,r3,ror#27 + veor q1,q1,q2 + mov r4,r4,ror#2 + add r7,r7,r11 + vadd.i32 q13,q0,q14 + eor r10,r3,r5 + add r6,r6,r9 + veor q12,q12,q1 + ldr r9,[sp,#24] + eor r11,r10,r4 + vshr.u32 q1,q12,#30 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + vst1.32 {q13},[r12,:128]! + add r6,r6,r11 + eor r10,r7,r4 + vsli.32 q1,q12,#2 + add r5,r5,r9 + ldr r9,[sp,#28] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#32] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q12,q0,q1,#8 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#36] + veor q2,q2,q10 + eor r11,r10,r6 + add r3,r3,r4,ror#27 + veor q2,q2,q3 + mov r5,r5,ror#2 + add r3,r3,r11 + vadd.i32 q13,q1,q14 + eor r10,r4,r6 + vld1.32 {d28[],d29[]},[r8,:32]! + add r7,r7,r9 + veor q12,q12,q2 + ldr r9,[sp,#40] + eor r11,r10,r5 + vshr.u32 q2,q12,#30 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + vst1.32 {q13},[r12,:128]! + add r7,r7,r11 + eor r10,r3,r5 + vsli.32 q2,q12,#2 + add r6,r6,r9 + ldr r9,[sp,#44] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#48] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q12,q1,q2,#8 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#52] + veor q3,q3,q11 + eor r11,r10,r7 + add r4,r4,r5,ror#27 + veor q3,q3,q8 + mov r6,r6,ror#2 + add r4,r4,r11 + vadd.i32 q13,q2,q14 + eor r10,r5,r7 + add r3,r3,r9 + veor q12,q12,q3 + ldr r9,[sp,#56] + eor r11,r10,r6 + vshr.u32 q3,q12,#30 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + vst1.32 {q13},[r12,:128]! + add r3,r3,r11 + eor r10,r4,r6 + vsli.32 q3,q12,#2 + add r7,r7,r9 + ldr r9,[sp,#60] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#0] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q12,q2,q3,#8 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#4] + veor q8,q8,q0 + eor r11,r10,r3 + add r5,r5,r6,ror#27 + veor q8,q8,q9 + mov r7,r7,ror#2 + add r5,r5,r11 + vadd.i32 q13,q3,q14 + eor r10,r6,r3 + add r4,r4,r9 + veor q12,q12,q8 + ldr r9,[sp,#8] + eor r11,r10,r7 + vshr.u32 q8,q12,#30 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + add r4,r4,r11 + eor r10,r5,r7 + vsli.32 q8,q12,#2 + add r3,r3,r9 + ldr r9,[sp,#12] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#16] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q3,q8,#8 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#20] + veor q9,q9,q1 + eor r11,r10,r4 + add r6,r6,r7,ror#27 + veor q9,q9,q10 + mov r3,r3,ror#2 + add r6,r6,r11 + vadd.i32 q13,q8,q14 + eor r10,r7,r4 + add r5,r5,r9 + veor q12,q12,q9 + ldr r9,[sp,#24] + eor r11,r10,r3 + vshr.u32 q9,q12,#30 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + vst1.32 {q13},[r12,:128]! + add r5,r5,r11 + eor r10,r6,r3 + vsli.32 q9,q12,#2 + add r4,r4,r9 + ldr r9,[sp,#28] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#32] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q8,q9,#8 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#36] + veor q10,q10,q2 + add r7,r7,r3,ror#27 + eor r11,r5,r6 + veor q10,q10,q11 + add r7,r7,r10 + and r11,r11,r4 + vadd.i32 q13,q9,q14 + mov r4,r4,ror#2 + add r7,r7,r11 + veor q12,q12,q10 + add r6,r6,r9 + and r10,r4,r5 + vshr.u32 q10,q12,#30 + ldr r9,[sp,#40] + add r6,r6,r7,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r4,r5 + add r6,r6,r10 + vsli.32 q10,q12,#2 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#44] + add r5,r5,r6,ror#27 + eor r11,r3,r4 + add r5,r5,r10 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#48] + add r4,r4,r5,ror#27 + eor r11,r7,r3 + add r4,r4,r10 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + vext.8 q12,q9,q10,#8 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#52] + veor q11,q11,q3 + add r3,r3,r4,ror#27 + eor r11,r6,r7 + veor q11,q11,q0 + add r3,r3,r10 + and r11,r11,r5 + vadd.i32 q13,q10,q14 + mov r5,r5,ror#2 + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r11 + veor q12,q12,q11 + add r7,r7,r9 + and r10,r5,r6 + vshr.u32 q11,q12,#30 + ldr r9,[sp,#56] + add r7,r7,r3,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r5,r6 + add r7,r7,r10 + vsli.32 q11,q12,#2 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#60] + add r6,r6,r7,ror#27 + eor r11,r4,r5 + add r6,r6,r10 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#0] + add r5,r5,r6,ror#27 + eor r11,r3,r4 + add r5,r5,r10 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + vext.8 q12,q10,q11,#8 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#4] + veor q0,q0,q8 + add r4,r4,r5,ror#27 + eor r11,r7,r3 + veor q0,q0,q1 + add r4,r4,r10 + and r11,r11,r6 + vadd.i32 q13,q11,q14 + mov r6,r6,ror#2 + add r4,r4,r11 + veor q12,q12,q0 + add r3,r3,r9 + and r10,r6,r7 + vshr.u32 q0,q12,#30 + ldr r9,[sp,#8] + add r3,r3,r4,ror#27 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + eor r11,r6,r7 + add r3,r3,r10 + vsli.32 q0,q12,#2 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#12] + add r7,r7,r3,ror#27 + eor r11,r5,r6 + add r7,r7,r10 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#16] + add r6,r6,r7,ror#27 + eor r11,r4,r5 + add r6,r6,r10 + and r11,r11,r3 + mov r3,r3,ror#2 + add r6,r6,r11 + vext.8 q12,q11,q0,#8 + add r5,r5,r9 + and r10,r3,r4 + ldr r9,[sp,#20] + veor q1,q1,q9 + add r5,r5,r6,ror#27 + eor r11,r3,r4 + veor q1,q1,q2 + add r5,r5,r10 + and r11,r11,r7 + vadd.i32 q13,q0,q14 + mov r7,r7,ror#2 + add r5,r5,r11 + veor q12,q12,q1 + add r4,r4,r9 + and r10,r7,r3 + vshr.u32 q1,q12,#30 + ldr r9,[sp,#24] + add r4,r4,r5,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r7,r3 + add r4,r4,r10 + vsli.32 q1,q12,#2 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#28] + add r3,r3,r4,ror#27 + eor r11,r6,r7 + add r3,r3,r10 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + add r7,r7,r9 + and r10,r5,r6 + ldr r9,[sp,#32] + add r7,r7,r3,ror#27 + eor r11,r5,r6 + add r7,r7,r10 + and r11,r11,r4 + mov r4,r4,ror#2 + add r7,r7,r11 + vext.8 q12,q0,q1,#8 + add r6,r6,r9 + and r10,r4,r5 + ldr r9,[sp,#36] + veor q2,q2,q10 + add r6,r6,r7,ror#27 + eor r11,r4,r5 + veor q2,q2,q3 + add r6,r6,r10 + and r11,r11,r3 + vadd.i32 q13,q1,q14 + mov r3,r3,ror#2 + add r6,r6,r11 + veor q12,q12,q2 + add r5,r5,r9 + and r10,r3,r4 + vshr.u32 q2,q12,#30 + ldr r9,[sp,#40] + add r5,r5,r6,ror#27 + vst1.32 {q13},[r12,:128]! + eor r11,r3,r4 + add r5,r5,r10 + vsli.32 q2,q12,#2 + and r11,r11,r7 + mov r7,r7,ror#2 + add r5,r5,r11 + add r4,r4,r9 + and r10,r7,r3 + ldr r9,[sp,#44] + add r4,r4,r5,ror#27 + eor r11,r7,r3 + add r4,r4,r10 + and r11,r11,r6 + mov r6,r6,ror#2 + add r4,r4,r11 + add r3,r3,r9 + and r10,r6,r7 + ldr r9,[sp,#48] + add r3,r3,r4,ror#27 + eor r11,r6,r7 + add r3,r3,r10 + and r11,r11,r5 + mov r5,r5,ror#2 + add r3,r3,r11 + vext.8 q12,q1,q2,#8 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#52] + veor q3,q3,q11 + eor r11,r10,r5 + add r7,r7,r3,ror#27 + veor q3,q3,q8 + mov r4,r4,ror#2 + add r7,r7,r11 + vadd.i32 q13,q2,q14 + eor r10,r3,r5 + add r6,r6,r9 + veor q12,q12,q3 + ldr r9,[sp,#56] + eor r11,r10,r4 + vshr.u32 q3,q12,#30 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + vst1.32 {q13},[r12,:128]! + add r6,r6,r11 + eor r10,r7,r4 + vsli.32 q3,q12,#2 + add r5,r5,r9 + ldr r9,[sp,#60] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#0] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + vadd.i32 q13,q3,q14 + eor r10,r5,r7 + add r3,r3,r9 + vst1.32 {q13},[r12,:128]! + sub r12,r12,#64 + teq r1,r2 + sub r8,r8,#16 + it eq + subeq r1,r1,#64 + vld1.8 {q0,q1},[r1]! + ldr r9,[sp,#4] + eor r11,r10,r6 + vld1.8 {q2,q3},[r1]! + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + vld1.32 {d28[],d29[]},[r8,:32]! + add r3,r3,r11 + eor r10,r4,r6 + vrev32.8 q0,q0 + add r7,r7,r9 + ldr r9,[sp,#8] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#12] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#16] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + vrev32.8 q1,q1 + eor r10,r6,r3 + add r4,r4,r9 + vadd.i32 q8,q0,q14 + ldr r9,[sp,#20] + eor r11,r10,r7 + vst1.32 {q8},[r12,:128]! + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#24] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#28] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + eor r10,r3,r5 + add r6,r6,r9 + ldr r9,[sp,#32] + eor r11,r10,r4 + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + vrev32.8 q2,q2 + eor r10,r7,r4 + add r5,r5,r9 + vadd.i32 q9,q1,q14 + ldr r9,[sp,#36] + eor r11,r10,r3 + vst1.32 {q9},[r12,:128]! + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#40] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + ldr r9,[sp,#44] + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + eor r10,r4,r6 + add r7,r7,r9 + ldr r9,[sp,#48] + eor r11,r10,r5 + add r7,r7,r3,ror#27 + mov r4,r4,ror#2 + add r7,r7,r11 + vrev32.8 q3,q3 + eor r10,r3,r5 + add r6,r6,r9 + vadd.i32 q10,q2,q14 + ldr r9,[sp,#52] + eor r11,r10,r4 + vst1.32 {q10},[r12,:128]! + add r6,r6,r7,ror#27 + mov r3,r3,ror#2 + add r6,r6,r11 + eor r10,r7,r4 + add r5,r5,r9 + ldr r9,[sp,#56] + eor r11,r10,r3 + add r5,r5,r6,ror#27 + mov r7,r7,ror#2 + add r5,r5,r11 + eor r10,r6,r3 + add r4,r4,r9 + ldr r9,[sp,#60] + eor r11,r10,r7 + add r4,r4,r5,ror#27 + mov r6,r6,ror#2 + add r4,r4,r11 + eor r10,r5,r7 + add r3,r3,r9 + eor r11,r10,r6 + add r3,r3,r4,ror#27 + mov r5,r5,ror#2 + add r3,r3,r11 + ldmia r0,{r9,r10,r11,r12} @ accumulate context + add r3,r3,r9 + ldr r9,[r0,#16] + add r4,r4,r10 + add r5,r5,r11 + add r6,r6,r12 + it eq + moveq sp,r14 + add r7,r7,r9 + it ne + ldrne r9,[sp] + stmia r0,{r3,r4,r5,r6,r7} + itt ne + addne r12,sp,#3*16 + bne .Loop_neon + + @ vldmia sp!,{d8-d15} + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +.size sha1_block_data_order_neon,.-sha1_block_data_order_neon +#endif +#if __ARM_MAX_ARCH__>=7 + +# if defined(__thumb2__) +# define INST(a,b,c,d) .byte c,d|0xf,a,b +# else +# define INST(a,b,c,d) .byte a,b,c,d|0x10 +# endif + +.type sha1_block_data_order_armv8,%function +.align 5 +sha1_block_data_order_armv8: +.LARMv8: + vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so + + veor q1,q1,q1 + adr r3,.LK_00_19 + vld1.32 {q0},[r0]! + vld1.32 {d2[0]},[r0] + sub r0,r0,#16 + vld1.32 {d16[],d17[]},[r3,:32]! + vld1.32 {d18[],d19[]},[r3,:32]! + vld1.32 {d20[],d21[]},[r3,:32]! + vld1.32 {d22[],d23[]},[r3,:32] + +.Loop_v8: + vld1.8 {q4,q5},[r1]! + vld1.8 {q6,q7},[r1]! + vrev32.8 q4,q4 + vrev32.8 q5,q5 + + vadd.i32 q12,q8,q4 + vrev32.8 q6,q6 + vmov q14,q0 @ offload + subs r2,r2,#1 + + vadd.i32 q13,q8,q5 + vrev32.8 q7,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 0 + INST(0x68,0x0c,0x02,0xe2) @ sha1c q0,q1,q12 + vadd.i32 q12,q8,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 1 + INST(0x6a,0x0c,0x06,0xe2) @ sha1c q0,q3,q13 + vadd.i32 q13,q8,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 2 + INST(0x68,0x0c,0x04,0xe2) @ sha1c q0,q2,q12 + vadd.i32 q12,q8,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 3 + INST(0x6a,0x0c,0x06,0xe2) @ sha1c q0,q3,q13 + vadd.i32 q13,q9,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 4 + INST(0x68,0x0c,0x04,0xe2) @ sha1c q0,q2,q12 + vadd.i32 q12,q9,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 5 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q9,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 6 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q9,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 7 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q9,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 8 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q10,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 9 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q10,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 10 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q10,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 11 + INST(0x6a,0x0c,0x26,0xe2) @ sha1m q0,q3,q13 + vadd.i32 q13,q10,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 12 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q10,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0x4c,0x8c,0x3a,0xe2) @ sha1su0 q4,q5,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 13 + INST(0x6a,0x0c,0x26,0xe2) @ sha1m q0,q3,q13 + vadd.i32 q13,q11,q7 + INST(0x8e,0x83,0xba,0xf3) @ sha1su1 q4,q7 + INST(0x4e,0xac,0x3c,0xe2) @ sha1su0 q5,q6,q7 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 14 + INST(0x68,0x0c,0x24,0xe2) @ sha1m q0,q2,q12 + vadd.i32 q12,q11,q4 + INST(0x88,0xa3,0xba,0xf3) @ sha1su1 q5,q4 + INST(0x48,0xcc,0x3e,0xe2) @ sha1su0 q6,q7,q4 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 15 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q11,q5 + INST(0x8a,0xc3,0xba,0xf3) @ sha1su1 q6,q5 + INST(0x4a,0xec,0x38,0xe2) @ sha1su0 q7,q4,q5 + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 16 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + vadd.i32 q12,q11,q6 + INST(0x8c,0xe3,0xba,0xf3) @ sha1su1 q7,q6 + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 17 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + vadd.i32 q13,q11,q7 + + INST(0xc0,0x62,0xb9,0xf3) @ sha1h q3,q0 @ 18 + INST(0x68,0x0c,0x14,0xe2) @ sha1p q0,q2,q12 + + INST(0xc0,0x42,0xb9,0xf3) @ sha1h q2,q0 @ 19 + INST(0x6a,0x0c,0x16,0xe2) @ sha1p q0,q3,q13 + + vadd.i32 q1,q1,q2 + vadd.i32 q0,q0,q14 + bne .Loop_v8 + + vst1.32 {q0},[r0]! + vst1.32 {d2[0]},[r0] + + vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} + bx lr @ bx lr +.size sha1_block_data_order_armv8,.-sha1_block_data_order_armv8 +#endif +#if __ARM_MAX_ARCH__>=7 +.comm OPENSSL_armcap_P,4,4 +.hidden OPENSSL_armcap_P +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S new file mode 100644 index 00000000..bdb3122e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S @@ -0,0 +1,1242 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + + +.private_extern _OPENSSL_armcap_P +.globl _sha1_block_data_order +.private_extern _sha1_block_data_order + +.align 6 +_sha1_block_data_order: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:_OPENSSL_armcap_P +#else + adrp x16,_OPENSSL_armcap_P@PAGE +#endif + ldr w16,[x16,_OPENSSL_armcap_P@PAGEOFF] + tst w16,#ARMV8_SHA1 + b.ne Lv8_entry + + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + ldp w20,w21,[x0] + ldp w22,w23,[x0,#8] + ldr w24,[x0,#16] + +Loop: + ldr x3,[x1],#64 + movz w28,#0x7999 + sub x2,x2,#1 + movk w28,#0x5a82,lsl#16 +#ifdef __AARCH64EB__ + ror x3,x3,#32 +#else + rev32 x3,x3 +#endif + add w24,w24,w28 // warm it up + add w24,w24,w3 + lsr x4,x3,#32 + ldr x5,[x1,#-56] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w4 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x5,x5,#32 +#else + rev32 x5,x5 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w5 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x6,x5,#32 + ldr x7,[x1,#-48] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w6 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x7,x7,#32 +#else + rev32 x7,x7 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w7 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x8,x7,#32 + ldr x9,[x1,#-40] + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w8 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x9,x9,#32 +#else + rev32 x9,x9 +#endif + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w9 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + lsr x10,x9,#32 + ldr x11,[x1,#-32] + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w10 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x11,x11,#32 +#else + rev32 x11,x11 +#endif + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w11 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + lsr x12,x11,#32 + ldr x13,[x1,#-24] + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w12 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x13,x13,#32 +#else + rev32 x13,x13 +#endif + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w13 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + lsr x14,x13,#32 + ldr x15,[x1,#-16] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w14 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x15,x15,#32 +#else + rev32 x15,x15 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w15 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x16,x15,#32 + ldr x17,[x1,#-8] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w16 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x17,x17,#32 +#else + rev32 x17,x17 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w17 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x19,x17,#32 + eor w3,w3,w5 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w3,w3,w11 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w3,w3,w16 + ror w22,w22,#2 + add w24,w24,w19 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + eor w4,w4,w12 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + eor w4,w4,w17 + ror w21,w21,#2 + add w23,w23,w3 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + eor w5,w5,w13 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + eor w5,w5,w19 + ror w20,w20,#2 + add w22,w22,w4 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + eor w6,w6,w14 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + eor w6,w6,w3 + ror w24,w24,#2 + add w21,w21,w5 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + eor w7,w7,w15 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + eor w7,w7,w4 + ror w23,w23,#2 + add w20,w20,w6 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w7,w7,#31 + movz w28,#0xeba1 + movk w28,#0x6ed9,lsl#16 + eor w8,w8,w10 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w8,w8,w16 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w8,w8,w5 + ror w22,w22,#2 + add w24,w24,w7 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w9,w9,w6 + add w23,w23,w8 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w10,w10,w7 + add w22,w22,w9 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w11,w11,w8 + add w21,w21,w10 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w12,w12,w9 + add w20,w20,w11 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w13,w13,w10 + add w24,w24,w12 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w14,w14,w11 + add w23,w23,w13 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w15,w15,w12 + add w22,w22,w14 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w16,w16,w13 + add w21,w21,w15 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w17,w17,w14 + add w20,w20,w16 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w19,w19,w15 + add w24,w24,w17 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w3,w3,w16 + add w23,w23,w19 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w4,w4,w17 + add w22,w22,w3 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w5,w5,w19 + add w21,w21,w4 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w6,w6,w3 + add w20,w20,w5 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w7,w7,w4 + add w24,w24,w6 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w8,w8,w5 + add w23,w23,w7 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w9,w9,w6 + add w22,w22,w8 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w10,w10,w7 + add w21,w21,w9 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w11,w11,w8 + add w20,w20,w10 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w11,w11,#31 + movz w28,#0xbcdc + movk w28,#0x8f1b,lsl#16 + eor w12,w12,w14 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w12,w12,w9 + add w24,w24,w11 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w13,w13,w15 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w13,w13,w5 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w13,w13,w10 + add w23,w23,w12 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w14,w14,w16 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w14,w14,w6 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w14,w14,w11 + add w22,w22,w13 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w15,w15,w17 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w15,w15,w7 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w15,w15,w12 + add w21,w21,w14 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w15,w15,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w16,w16,w19 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w16,w16,w8 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w16,w16,w13 + add w20,w20,w15 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w16,w16,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w17,w17,w3 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w17,w17,w9 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w17,w17,w14 + add w24,w24,w16 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w17,w17,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w19,w19,w4 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w19,w19,w10 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w19,w19,w15 + add w23,w23,w17 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w19,w19,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w3,w3,w5 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w3,w3,w11 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w3,w3,w16 + add w22,w22,w19 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w3,w3,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w4,w4,w6 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w4,w4,w12 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w4,w4,w17 + add w21,w21,w3 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w4,w4,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w5,w5,w7 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w5,w5,w13 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w5,w5,w19 + add w20,w20,w4 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w5,w5,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w6,w6,w8 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w6,w6,w14 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w6,w6,w3 + add w24,w24,w5 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w6,w6,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w7,w7,w9 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w7,w7,w15 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w7,w7,w4 + add w23,w23,w6 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w7,w7,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w8,w8,w10 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w8,w8,w16 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w8,w8,w5 + add w22,w22,w7 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w8,w8,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w9,w9,w11 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w9,w9,w17 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w9,w9,w6 + add w21,w21,w8 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w9,w9,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w10,w10,w12 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w10,w10,w19 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w10,w10,w7 + add w20,w20,w9 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w10,w10,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w11,w11,w13 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w11,w11,w3 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w11,w11,w8 + add w24,w24,w10 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w11,w11,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w12,w12,w14 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w12,w12,w4 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w12,w12,w9 + add w23,w23,w11 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w13,w13,w15 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w13,w13,w5 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w13,w13,w10 + add w22,w22,w12 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w14,w14,w16 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w14,w14,w6 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w14,w14,w11 + add w21,w21,w13 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w15,w15,w17 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w15,w15,w7 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w15,w15,w12 + add w20,w20,w14 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w15,w15,#31 + movz w28,#0xc1d6 + movk w28,#0xca62,lsl#16 + orr w25,w22,w23 + and w26,w22,w23 + eor w16,w16,w19 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w16,w16,w8 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w16,w16,w13 + add w24,w24,w15 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w17,w17,w14 + add w23,w23,w16 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w19,w19,w15 + add w22,w22,w17 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w3,w3,w16 + add w21,w21,w19 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w4,w4,w17 + add w20,w20,w3 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w5,w5,w19 + add w24,w24,w4 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w6,w6,w3 + add w23,w23,w5 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w7,w7,w4 + add w22,w22,w6 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w8,w8,w5 + add w21,w21,w7 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w9,w9,w6 + add w20,w20,w8 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w10,w10,w7 + add w24,w24,w9 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w11,w11,w8 + add w23,w23,w10 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w12,w12,w9 + add w22,w22,w11 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w13,w13,w10 + add w21,w21,w12 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w14,w14,w11 + add w20,w20,w13 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w15,w15,w12 + add w24,w24,w14 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w16,w16,w13 + add w23,w23,w15 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w17,w17,w14 + add w22,w22,w16 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w19,w19,w15 + add w21,w21,w17 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w19,w19,#31 + ldp w4,w5,[x0] + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w19 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ldp w6,w7,[x0,#8] + eor w25,w24,w22 + ror w27,w21,#27 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + ldr w8,[x0,#16] + add w20,w20,w25 // e+=F(b,c,d) + add w21,w21,w5 + add w22,w22,w6 + add w20,w20,w4 + add w23,w23,w7 + add w24,w24,w8 + stp w20,w21,[x0] + stp w22,w23,[x0,#8] + str w24,[x0,#16] + cbnz x2,Loop + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldr x29,[sp],#96 + ret + + +.align 6 +sha1_block_armv8: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET +Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + adrp x4,Lconst@PAGE + add x4,x4,Lconst@PAGEOFF + eor v1.16b,v1.16b,v1.16b + ld1 {v0.4s},[x0],#16 + ld1 {v1.s}[0],[x0] + sub x0,x0,#16 + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[x4] + +Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + + add v20.4s,v16.4s,v4.4s + rev32 v6.16b,v6.16b + orr v22.16b,v0.16b,v0.16b // offload + + add v21.4s,v16.4s,v5.4s + rev32 v7.16b,v7.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b +.long 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0 + add v20.4s,v16.4s,v6.4s +.long 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 1 +.long 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v16.4s,v7.4s +.long 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.long 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 2 +.long 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v16.4s,v4.4s +.long 0x5e281885 //sha1su1 v5.16b,v4.16b +.long 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 3 +.long 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.long 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.long 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 4 +.long 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v6.4s +.long 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.long 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 5 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v7.4s +.long 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.long 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 6 +.long 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v4.4s +.long 0x5e281885 //sha1su1 v5.16b,v4.16b +.long 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 7 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.long 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.long 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 8 +.long 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.long 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.long 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 9 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v7.4s +.long 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.long 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 10 +.long 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v4.4s +.long 0x5e281885 //sha1su1 v5.16b,v4.16b +.long 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 11 +.long 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v5.4s +.long 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.long 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 12 +.long 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.long 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.long 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 13 +.long 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s +.long 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.long 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 14 +.long 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v4.4s +.long 0x5e281885 //sha1su1 v5.16b,v4.16b +.long 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 15 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v5.4s +.long 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.long 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.long 0x5e280803 //sha1h v3.16b,v0.16b // 16 +.long 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v6.4s +.long 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.long 0x5e280802 //sha1h v2.16b,v0.16b // 17 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + +.long 0x5e280803 //sha1h v3.16b,v0.16b // 18 +.long 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + +.long 0x5e280802 //sha1h v2.16b,v0.16b // 19 +.long 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + + add v1.4s,v1.4s,v2.4s + add v0.4s,v0.4s,v22.4s + + cbnz x2,Loop_hw + + st1 {v0.4s},[x0],#16 + st1 {v1.s}[0],[x0] + + ldr x29,[sp],#16 + ret + +.section __TEXT,__const +.align 6 +Lconst: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S new file mode 100644 index 00000000..738f12bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S @@ -0,0 +1,1245 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + + +.hidden OPENSSL_armcap_P +.globl sha1_block_data_order +.hidden sha1_block_data_order +.type sha1_block_data_order,%function +.align 6 +sha1_block_data_order: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x16,OPENSSL_armcap_P +#endif + ldr w16,[x16,:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA1 + b.ne .Lv8_entry + + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + ldp w20,w21,[x0] + ldp w22,w23,[x0,#8] + ldr w24,[x0,#16] + +.Loop: + ldr x3,[x1],#64 + movz w28,#0x7999 + sub x2,x2,#1 + movk w28,#0x5a82,lsl#16 +#ifdef __AARCH64EB__ + ror x3,x3,#32 +#else + rev32 x3,x3 +#endif + add w24,w24,w28 // warm it up + add w24,w24,w3 + lsr x4,x3,#32 + ldr x5,[x1,#-56] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w4 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x5,x5,#32 +#else + rev32 x5,x5 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w5 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x6,x5,#32 + ldr x7,[x1,#-48] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w6 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x7,x7,#32 +#else + rev32 x7,x7 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w7 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x8,x7,#32 + ldr x9,[x1,#-40] + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w8 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x9,x9,#32 +#else + rev32 x9,x9 +#endif + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w9 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + lsr x10,x9,#32 + ldr x11,[x1,#-32] + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w10 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x11,x11,#32 +#else + rev32 x11,x11 +#endif + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w11 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + lsr x12,x11,#32 + ldr x13,[x1,#-24] + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w12 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x13,x13,#32 +#else + rev32 x13,x13 +#endif + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w13 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + lsr x14,x13,#32 + ldr x15,[x1,#-16] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w14 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x15,x15,#32 +#else + rev32 x15,x15 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w15 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x16,x15,#32 + ldr x17,[x1,#-8] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w16 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x17,x17,#32 +#else + rev32 x17,x17 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w17 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x19,x17,#32 + eor w3,w3,w5 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w3,w3,w11 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w3,w3,w16 + ror w22,w22,#2 + add w24,w24,w19 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + eor w4,w4,w12 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + eor w4,w4,w17 + ror w21,w21,#2 + add w23,w23,w3 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + eor w5,w5,w13 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + eor w5,w5,w19 + ror w20,w20,#2 + add w22,w22,w4 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + eor w6,w6,w14 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + eor w6,w6,w3 + ror w24,w24,#2 + add w21,w21,w5 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + eor w7,w7,w15 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + eor w7,w7,w4 + ror w23,w23,#2 + add w20,w20,w6 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w7,w7,#31 + movz w28,#0xeba1 + movk w28,#0x6ed9,lsl#16 + eor w8,w8,w10 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w8,w8,w16 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w8,w8,w5 + ror w22,w22,#2 + add w24,w24,w7 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w9,w9,w6 + add w23,w23,w8 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w10,w10,w7 + add w22,w22,w9 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w11,w11,w8 + add w21,w21,w10 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w12,w12,w9 + add w20,w20,w11 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w13,w13,w10 + add w24,w24,w12 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w14,w14,w11 + add w23,w23,w13 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w15,w15,w12 + add w22,w22,w14 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w16,w16,w13 + add w21,w21,w15 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w17,w17,w14 + add w20,w20,w16 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w19,w19,w15 + add w24,w24,w17 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w3,w3,w16 + add w23,w23,w19 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w4,w4,w17 + add w22,w22,w3 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w5,w5,w19 + add w21,w21,w4 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w6,w6,w3 + add w20,w20,w5 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w7,w7,w4 + add w24,w24,w6 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w8,w8,w5 + add w23,w23,w7 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w9,w9,w6 + add w22,w22,w8 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w10,w10,w7 + add w21,w21,w9 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w11,w11,w8 + add w20,w20,w10 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w11,w11,#31 + movz w28,#0xbcdc + movk w28,#0x8f1b,lsl#16 + eor w12,w12,w14 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w12,w12,w9 + add w24,w24,w11 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w13,w13,w15 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w13,w13,w5 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w13,w13,w10 + add w23,w23,w12 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w14,w14,w16 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w14,w14,w6 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w14,w14,w11 + add w22,w22,w13 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w15,w15,w17 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w15,w15,w7 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w15,w15,w12 + add w21,w21,w14 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w15,w15,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w16,w16,w19 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w16,w16,w8 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w16,w16,w13 + add w20,w20,w15 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w16,w16,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w17,w17,w3 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w17,w17,w9 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w17,w17,w14 + add w24,w24,w16 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w17,w17,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w19,w19,w4 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w19,w19,w10 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w19,w19,w15 + add w23,w23,w17 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w19,w19,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w3,w3,w5 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w3,w3,w11 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w3,w3,w16 + add w22,w22,w19 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w3,w3,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w4,w4,w6 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w4,w4,w12 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w4,w4,w17 + add w21,w21,w3 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w4,w4,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w5,w5,w7 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w5,w5,w13 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w5,w5,w19 + add w20,w20,w4 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w5,w5,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w6,w6,w8 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w6,w6,w14 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w6,w6,w3 + add w24,w24,w5 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w6,w6,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w7,w7,w9 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w7,w7,w15 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w7,w7,w4 + add w23,w23,w6 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w7,w7,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w8,w8,w10 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w8,w8,w16 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w8,w8,w5 + add w22,w22,w7 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w8,w8,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w9,w9,w11 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w9,w9,w17 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w9,w9,w6 + add w21,w21,w8 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w9,w9,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w10,w10,w12 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w10,w10,w19 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w10,w10,w7 + add w20,w20,w9 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w10,w10,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w11,w11,w13 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w11,w11,w3 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w11,w11,w8 + add w24,w24,w10 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w11,w11,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w12,w12,w14 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w12,w12,w4 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w12,w12,w9 + add w23,w23,w11 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w13,w13,w15 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w13,w13,w5 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w13,w13,w10 + add w22,w22,w12 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w14,w14,w16 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w14,w14,w6 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w14,w14,w11 + add w21,w21,w13 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w15,w15,w17 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w15,w15,w7 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w15,w15,w12 + add w20,w20,w14 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w15,w15,#31 + movz w28,#0xc1d6 + movk w28,#0xca62,lsl#16 + orr w25,w22,w23 + and w26,w22,w23 + eor w16,w16,w19 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w16,w16,w8 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w16,w16,w13 + add w24,w24,w15 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w17,w17,w14 + add w23,w23,w16 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w19,w19,w15 + add w22,w22,w17 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w3,w3,w16 + add w21,w21,w19 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w4,w4,w17 + add w20,w20,w3 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w5,w5,w19 + add w24,w24,w4 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w6,w6,w3 + add w23,w23,w5 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w7,w7,w4 + add w22,w22,w6 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w8,w8,w5 + add w21,w21,w7 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w9,w9,w6 + add w20,w20,w8 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w10,w10,w7 + add w24,w24,w9 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w11,w11,w8 + add w23,w23,w10 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w12,w12,w9 + add w22,w22,w11 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w13,w13,w10 + add w21,w21,w12 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w14,w14,w11 + add w20,w20,w13 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w15,w15,w12 + add w24,w24,w14 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w16,w16,w13 + add w23,w23,w15 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w17,w17,w14 + add w22,w22,w16 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w19,w19,w15 + add w21,w21,w17 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w19,w19,#31 + ldp w4,w5,[x0] + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w19 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ldp w6,w7,[x0,#8] + eor w25,w24,w22 + ror w27,w21,#27 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + ldr w8,[x0,#16] + add w20,w20,w25 // e+=F(b,c,d) + add w21,w21,w5 + add w22,w22,w6 + add w20,w20,w4 + add w23,w23,w7 + add w24,w24,w8 + stp w20,w21,[x0] + stp w22,w23,[x0,#8] + str w24,[x0,#16] + cbnz x2,.Loop + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldr x29,[sp],#96 + ret +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_armv8,%function +.align 6 +sha1_block_armv8: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + adrp x4,.Lconst + add x4,x4,:lo12:.Lconst + eor v1.16b,v1.16b,v1.16b + ld1 {v0.4s},[x0],#16 + ld1 {v1.s}[0],[x0] + sub x0,x0,#16 + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[x4] + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + + add v20.4s,v16.4s,v4.4s + rev32 v6.16b,v6.16b + orr v22.16b,v0.16b,v0.16b // offload + + add v21.4s,v16.4s,v5.4s + rev32 v7.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b +.inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0 + add v20.4s,v16.4s,v6.4s +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 1 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v16.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 2 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v16.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 3 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 4 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 5 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 6 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 7 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 8 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 9 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 10 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 11 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 12 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 13 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 14 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 15 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 16 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 17 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 18 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 19 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + + add v1.4s,v1.4s,v2.4s + add v0.4s,v0.4s,v22.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s},[x0],#16 + st1 {v1.s}[0],[x0] + + ldr x29,[sp],#16 + ret +.size sha1_block_armv8,.-sha1_block_armv8 +.section .rodata +.align 6 +.Lconst: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S new file mode 100644 index 00000000..039a6aa3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S @@ -0,0 +1,5475 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + +.globl sha1_block_data_order +.hidden sha1_block_data_order +.type sha1_block_data_order,@function +.align 16 +sha1_block_data_order: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r10 + movl 0(%r10),%r9d + movl 4(%r10),%r8d + movl 8(%r10),%r10d + testl $512,%r8d + jz .Lialu + testl $536870912,%r10d + jnz _shaext_shortcut + andl $296,%r10d + cmpl $296,%r10d + je _avx2_shortcut + andl $268435456,%r8d + andl $1073741824,%r9d + orl %r9d,%r8d + cmpl $1342177280,%r8d + je _avx_shortcut + jmp _ssse3_shortcut + +.align 16 +.Lialu: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %rax,64(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xc0,0x00,0x06,0x23,0x08 +.Lprologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp .Lloop + +.align 16 +.Lloop: + movl 0(%r9),%edx + bswapl %edx + movl 4(%r9),%ebp + movl %r12d,%eax + movl %edx,0(%rsp) + movl %esi,%ecx + bswapl %ebp + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 8(%r9),%r14d + movl %r11d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ecx + bswapl %r14d + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 12(%r9),%edx + movl %edi,%eax + movl %r14d,8(%rsp) + movl %r12d,%ecx + bswapl %edx + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 16(%r9),%ebp + movl %esi,%eax + movl %edx,12(%rsp) + movl %r11d,%ecx + bswapl %ebp + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 20(%r9),%r14d + movl %r13d,%eax + movl %ebp,16(%rsp) + movl %edi,%ecx + bswapl %r14d + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 24(%r9),%edx + movl %r12d,%eax + movl %r14d,20(%rsp) + movl %esi,%ecx + bswapl %edx + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%r14,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 28(%r9),%ebp + movl %r11d,%eax + movl %edx,24(%rsp) + movl %r13d,%ecx + bswapl %ebp + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 32(%r9),%r14d + movl %edi,%eax + movl %ebp,28(%rsp) + movl %r12d,%ecx + bswapl %r14d + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 36(%r9),%edx + movl %esi,%eax + movl %r14d,32(%rsp) + movl %r11d,%ecx + bswapl %edx + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%r14,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 40(%r9),%ebp + movl %r13d,%eax + movl %edx,36(%rsp) + movl %edi,%ecx + bswapl %ebp + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rdx,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 44(%r9),%r14d + movl %r12d,%eax + movl %ebp,40(%rsp) + movl %esi,%ecx + bswapl %r14d + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 48(%r9),%edx + movl %r11d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ecx + bswapl %edx + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%r14,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 52(%r9),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %r12d,%ecx + bswapl %ebp + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rdx,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 56(%r9),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r11d,%ecx + bswapl %r14d + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rbp,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 60(%r9),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %edi,%ecx + bswapl %edx + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%r14,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %esi,%ecx + xorl 8(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + roll $30,%edi + xorl %r12d,%eax + addl %ecx,%r13d + roll $1,%ebp + addl %eax,%r13d + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %r13d,%ecx + xorl 12(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + roll $30,%esi + xorl %r11d,%eax + addl %ecx,%r12d + roll $1,%r14d + addl %eax,%r12d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + roll $30,%r13d + xorl %edi,%eax + addl %ecx,%r11d + roll $1,%edx + addl %eax,%r11d + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + roll $30,%r12d + xorl %esi,%eax + addl %ecx,%edi + roll $1,%ebp + addl %eax,%edi + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %edi,%ecx + xorl 24(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + roll $30,%r11d + xorl %r13d,%eax + addl %ecx,%esi + roll $1,%r14d + addl %eax,%esi + xorl 20(%rsp),%edx + movl %edi,%eax + movl %r14d,16(%rsp) + movl %esi,%ecx + xorl 28(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 24(%rsp),%ebp + movl %esi,%eax + movl %edx,20(%rsp) + movl %r13d,%ecx + xorl 32(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %r13d,%eax + movl %ebp,24(%rsp) + movl %r12d,%ecx + xorl 36(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %r12d,%eax + movl %r14d,28(%rsp) + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r11d,%eax + movl %edx,32(%rsp) + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %edi,%eax + movl %ebp,36(%rsp) + movl %esi,%ecx + xorl 48(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal 1859775393(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 44(%rsp),%edx + movl %esi,%eax + movl %r14d,40(%rsp) + movl %r13d,%ecx + xorl 52(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal 1859775393(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 48(%rsp),%ebp + movl %r13d,%eax + movl %edx,44(%rsp) + movl %r12d,%ecx + xorl 56(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal 1859775393(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %r12d,%eax + movl %ebp,48(%rsp) + movl %r11d,%ecx + xorl 60(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal 1859775393(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r11d,%eax + movl %r14d,52(%rsp) + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal 1859775393(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 60(%rsp),%ebp + movl %edi,%eax + movl %edx,56(%rsp) + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal 1859775393(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 0(%rsp),%r14d + movl %esi,%eax + movl %ebp,60(%rsp) + movl %r13d,%ecx + xorl 8(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%r14d + leal 1859775393(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 4(%rsp),%edx + movl %r13d,%eax + movl %r14d,0(%rsp) + movl %r12d,%ecx + xorl 12(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%edx + leal 1859775393(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 8(%rsp),%ebp + movl %r12d,%eax + movl %edx,4(%rsp) + movl %r11d,%ecx + xorl 16(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%ebp + leal 1859775393(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 12(%rsp),%r14d + movl %r11d,%eax + movl %ebp,8(%rsp) + movl %edi,%ecx + xorl 20(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%r14d + leal 1859775393(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 16(%rsp),%edx + movl %edi,%eax + movl %r14d,12(%rsp) + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 20(%rsp),%ebp + movl %esi,%eax + movl %edx,16(%rsp) + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 52(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 24(%rsp),%r14d + movl %r13d,%eax + movl %ebp,20(%rsp) + movl %r12d,%ecx + xorl 32(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 56(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 28(%rsp),%edx + movl %r12d,%eax + movl %r14d,24(%rsp) + movl %r11d,%ecx + xorl 36(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 60(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 32(%rsp),%ebp + movl %r11d,%eax + movl %edx,28(%rsp) + movl %edi,%ecx + xorl 40(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 0(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 36(%rsp),%r14d + movl %r12d,%eax + movl %ebp,32(%rsp) + movl %r12d,%ebx + xorl 44(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 40(%rsp),%edx + movl %r11d,%eax + movl %r14d,36(%rsp) + movl %r11d,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 44(%rsp),%ebp + movl %edi,%eax + movl %edx,40(%rsp) + movl %edi,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 48(%rsp),%r14d + movl %esi,%eax + movl %ebp,44(%rsp) + movl %esi,%ebx + xorl 56(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 52(%rsp),%edx + movl %r13d,%eax + movl %r14d,48(%rsp) + movl %r13d,%ebx + xorl 60(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 56(%rsp),%ebp + movl %r12d,%eax + movl %edx,52(%rsp) + movl %r12d,%ebx + xorl 0(%rsp),%ebp + andl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%ebp + leal -1894007588(%rdx,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%ebp + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 60(%rsp),%r14d + movl %r11d,%eax + movl %ebp,56(%rsp) + movl %r11d,%ebx + xorl 4(%rsp),%r14d + andl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%r14d + leal -1894007588(%rbp,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%r14d + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 0(%rsp),%edx + movl %edi,%eax + movl %r14d,60(%rsp) + movl %edi,%ebx + xorl 8(%rsp),%edx + andl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + leal -1894007588(%r14,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%edx + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 4(%rsp),%ebp + movl %esi,%eax + movl %edx,0(%rsp) + movl %esi,%ebx + xorl 12(%rsp),%ebp + andl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + leal -1894007588(%rdx,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%ebp + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 8(%rsp),%r14d + movl %r13d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ebx + xorl 16(%rsp),%r14d + andl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%r14d + leal -1894007588(%rbp,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%r14d + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 12(%rsp),%edx + movl %r12d,%eax + movl %r14d,8(%rsp) + movl %r12d,%ebx + xorl 20(%rsp),%edx + andl %r11d,%eax + movl %esi,%ecx + xorl 44(%rsp),%edx + leal -1894007588(%r14,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%edx + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 16(%rsp),%ebp + movl %r11d,%eax + movl %edx,12(%rsp) + movl %r11d,%ebx + xorl 24(%rsp),%ebp + andl %edi,%eax + movl %r13d,%ecx + xorl 48(%rsp),%ebp + leal -1894007588(%rdx,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%ebp + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 20(%rsp),%r14d + movl %edi,%eax + movl %ebp,16(%rsp) + movl %edi,%ebx + xorl 28(%rsp),%r14d + andl %esi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%r14d + leal -1894007588(%rbp,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%r14d + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 24(%rsp),%edx + movl %esi,%eax + movl %r14d,20(%rsp) + movl %esi,%ebx + xorl 32(%rsp),%edx + andl %r13d,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + leal -1894007588(%r14,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%edx + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 28(%rsp),%ebp + movl %r13d,%eax + movl %edx,24(%rsp) + movl %r13d,%ebx + xorl 36(%rsp),%ebp + andl %r12d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + leal -1894007588(%rdx,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%ebp + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 32(%rsp),%r14d + movl %r12d,%eax + movl %ebp,28(%rsp) + movl %r12d,%ebx + xorl 40(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 0(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 36(%rsp),%edx + movl %r11d,%eax + movl %r14d,32(%rsp) + movl %r11d,%ebx + xorl 44(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 4(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 40(%rsp),%ebp + movl %edi,%eax + movl %edx,36(%rsp) + movl %edi,%ebx + xorl 48(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 44(%rsp),%r14d + movl %esi,%eax + movl %ebp,40(%rsp) + movl %esi,%ebx + xorl 52(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 12(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 48(%rsp),%edx + movl %r13d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 52(%rsp),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 20(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 56(%rsp),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r13d,%ecx + xorl 0(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 24(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 60(%rsp),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %r12d,%ecx + xorl 4(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 28(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %r11d,%ecx + xorl 8(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %edi,%ecx + xorl 12(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + leal -899497514(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + leal -899497514(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + leal -899497514(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %r12d,%ecx + xorl 24(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + leal -899497514(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 20(%rsp),%edx + movl %r12d,%eax + movl %r14d,16(%rsp) + movl %r11d,%ecx + xorl 28(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal -899497514(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 24(%rsp),%ebp + movl %r11d,%eax + movl %edx,20(%rsp) + movl %edi,%ecx + xorl 32(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal -899497514(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %edi,%eax + movl %ebp,24(%rsp) + movl %esi,%ecx + xorl 36(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal -899497514(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %esi,%eax + movl %r14d,28(%rsp) + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal -899497514(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r13d,%eax + + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal -899497514(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %r12d,%eax + + movl %r11d,%ecx + xorl 48(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal -899497514(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 44(%rsp),%edx + movl %r11d,%eax + + movl %edi,%ecx + xorl 52(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal -899497514(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 48(%rsp),%ebp + movl %edi,%eax + + movl %esi,%ecx + xorl 56(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %esi,%eax + + movl %r13d,%ecx + xorl 60(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r13d,%eax + + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 60(%rsp),%ebp + movl %r12d,%eax + + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r11d,%eax + movl %edi,%ecx + xorl %r13d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz .Lloop + + movq 64(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_data_order_shaext,@function +.align 32 +sha1_block_data_order_shaext: +_shaext_shortcut: +.cfi_startproc + movdqu (%rdi),%xmm0 + movd 16(%rdi),%xmm1 + movdqa K_XX_XX+160(%rip),%xmm3 + + movdqu (%rsi),%xmm4 + pshufd $27,%xmm0,%xmm0 + movdqu 16(%rsi),%xmm5 + pshufd $27,%xmm1,%xmm1 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,227 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,235 +.byte 102,15,56,0,243 + movdqa %xmm1,%xmm9 +.byte 102,15,56,0,251 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + decq %rdx + leaq 64(%rsi),%r8 + paddd %xmm4,%xmm1 + cmovneq %r8,%rsi + movdqa %xmm0,%xmm8 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 + movdqu (%rsi),%xmm4 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,213 + movdqu 16(%rsi),%xmm5 +.byte 102,15,56,0,227 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,206 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,235 + + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,215 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,243 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 65,15,56,200,201 +.byte 102,15,56,0,251 + + paddd %xmm8,%xmm0 + movdqa %xmm1,%xmm9 + + jnz .Loop_shaext + + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm1,%xmm1 + movdqu %xmm0,(%rdi) + movd %xmm1,16(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_shaext,.-sha1_block_data_order_shaext +.type sha1_block_data_order_ssse3,@function +.align 16 +sha1_block_data_order_ssse3: +_ssse3_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + leaq -64(%rsp),%rsp + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + addq $64,%r9 + paddd %xmm9,%xmm0 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp .Loop_ssse3 +.align 16 +.Loop_ssse3: + rorl $2,%ebx + pshufd $238,%xmm0,%xmm4 + xorl %edx,%esi + movdqa %xmm3,%xmm8 + paddd %xmm3,%xmm9 + movl %eax,%edi + addl 0(%rsp),%ebp + punpcklqdq %xmm1,%xmm4 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + psrldq $4,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + pxor %xmm0,%xmm4 + addl %eax,%ebp + rorl $7,%eax + pxor %xmm2,%xmm8 + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + pxor %xmm8,%xmm4 + xorl %ebx,%eax + roll $5,%ebp + movdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + movdqa %xmm4,%xmm10 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + movdqa %xmm4,%xmm8 + xorl %ebx,%esi + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + psrld $31,%xmm8 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm9 + andl %ebp,%edi + xorl %eax,%ebp + psrld $30,%xmm10 + addl %edx,%ecx + rorl $7,%edx + por %xmm8,%xmm4 + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + xorl %ebp,%edx + movdqa -64(%r14),%xmm10 + roll $5,%ecx + addl %edi,%ebx + andl %edx,%esi + pxor %xmm9,%xmm4 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + pshufd $238,%xmm1,%xmm5 + xorl %ebp,%esi + movdqa %xmm4,%xmm9 + paddd %xmm4,%xmm10 + movl %ebx,%edi + addl 16(%rsp),%eax + punpcklqdq %xmm2,%xmm5 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + pxor %xmm1,%xmm5 + addl %ebx,%eax + rorl $7,%ebx + pxor %xmm3,%xmm9 + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + pxor %xmm9,%xmm5 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm10,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + movdqa %xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + movdqa %xmm5,%xmm9 + xorl %ecx,%esi + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + psrld $31,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm10 + andl %eax,%edi + xorl %ebx,%eax + psrld $30,%xmm8 + addl %ebp,%edx + rorl $7,%ebp + por %xmm9,%xmm5 + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + xorl %eax,%ebp + movdqa -32(%r14),%xmm8 + roll $5,%edx + addl %edi,%ecx + andl %ebp,%esi + pxor %xmm10,%xmm5 + xorl %eax,%ebp + addl %edx,%ecx + rorl $7,%edx + pshufd $238,%xmm2,%xmm6 + xorl %eax,%esi + movdqa %xmm5,%xmm10 + paddd %xmm5,%xmm8 + movl %ecx,%edi + addl 32(%rsp),%ebx + punpcklqdq %xmm3,%xmm6 + xorl %ebp,%edx + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm10 + andl %edx,%edi + xorl %ebp,%edx + pxor %xmm2,%xmm6 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm4,%xmm10 + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + pxor %xmm10,%xmm6 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm8,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + movdqa %xmm6,%xmm9 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movdqa %xmm6,%xmm10 + xorl %edx,%esi + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + psrld $31,%xmm10 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + movdqa %xmm9,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + psrld $30,%xmm9 + addl %eax,%ebp + rorl $7,%eax + por %xmm10,%xmm6 + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + xorl %ebx,%eax + movdqa -32(%r14),%xmm9 + roll $5,%ebp + addl %edi,%edx + andl %eax,%esi + pxor %xmm8,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + pshufd $238,%xmm3,%xmm7 + xorl %ebx,%esi + movdqa %xmm6,%xmm8 + paddd %xmm6,%xmm9 + movl %edx,%edi + addl 48(%rsp),%ecx + punpcklqdq %xmm4,%xmm7 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm8 + andl %ebp,%edi + xorl %eax,%ebp + pxor %xmm3,%xmm7 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm5,%xmm8 + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + pxor %xmm8,%xmm7 + xorl %ebp,%edx + roll $5,%ecx + movdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + movdqa %xmm7,%xmm10 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm7,%xmm8 + xorl %ebp,%esi + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + psrld $31,%xmm8 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + movdqa %xmm10,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + psrld $30,%xmm10 + addl %ebx,%eax + rorl $7,%ebx + por %xmm8,%xmm7 + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + xorl %ecx,%ebx + movdqa -32(%r14),%xmm10 + roll $5,%eax + addl %edi,%ebp + andl %ebx,%esi + pxor %xmm9,%xmm7 + pshufd $238,%xmm6,%xmm9 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + pxor %xmm4,%xmm0 + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + punpcklqdq %xmm7,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + pxor %xmm1,%xmm0 + addl %esi,%edx + andl %eax,%edi + movdqa %xmm10,%xmm8 + xorl %ebx,%eax + paddd %xmm7,%xmm10 + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 4(%rsp),%ecx + movdqa %xmm0,%xmm9 + xorl %eax,%ebp + roll $5,%edx + movdqa %xmm10,48(%rsp) + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + pslld $2,%xmm0 + addl %edx,%ecx + rorl $7,%edx + psrld $30,%xmm9 + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + por %xmm9,%xmm0 + xorl %ebp,%edx + roll $5,%ecx + pshufd $238,%xmm7,%xmm10 + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pxor %xmm5,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm0,%xmm10 + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebx + paddd %xmm0,%xmm8 + addl %eax,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm8,0(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 24(%rsp),%ecx + pslld $2,%xmm1 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm10 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm10,%xmm1 + addl %edx,%ecx + addl 28(%rsp),%ebx + pshufd $238,%xmm0,%xmm8 + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + pxor %xmm6,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + punpcklqdq %xmm1,%xmm8 + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + addl %esi,%eax + xorl %edx,%edi + movdqa 0(%r14),%xmm10 + rorl $7,%ecx + paddd %xmm1,%xmm9 + addl %ebx,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + addl %edi,%ebp + xorl %ecx,%esi + movdqa %xmm9,16(%rsp) + rorl $7,%ebx + addl %eax,%ebp + addl 40(%rsp),%edx + pslld $2,%xmm2 + xorl %ebx,%esi + movl %ebp,%edi + psrld $30,%xmm8 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + por %xmm8,%xmm2 + addl %ebp,%edx + addl 44(%rsp),%ecx + pshufd $238,%xmm1,%xmm9 + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + punpcklqdq %xmm2,%xmm9 + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + movdqa %xmm10,%xmm8 + rorl $7,%edx + paddd %xmm2,%xmm10 + addl %ecx,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + addl %edi,%eax + xorl %edx,%esi + movdqa %xmm10,32(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 56(%rsp),%ebp + pslld $2,%xmm3 + xorl %ecx,%esi + movl %eax,%edi + psrld $30,%xmm9 + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + por %xmm9,%xmm3 + addl %eax,%ebp + addl 60(%rsp),%edx + pshufd $238,%xmm2,%xmm10 + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + pxor %xmm0,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + punpcklqdq %xmm3,%xmm10 + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebp + paddd %xmm3,%xmm8 + addl %edx,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + addl %edi,%ebx + xorl %ebp,%esi + movdqa %xmm8,48(%rsp) + rorl $7,%edx + addl %ecx,%ebx + addl 8(%rsp),%eax + pslld $2,%xmm4 + xorl %edx,%esi + movl %ebx,%edi + psrld $30,%xmm10 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + por %xmm10,%xmm4 + addl %ebx,%eax + addl 12(%rsp),%ebp + pshufd $238,%xmm3,%xmm8 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + pxor %xmm1,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + punpcklqdq %xmm4,%xmm8 + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%eax + paddd %xmm4,%xmm9 + addl %ebp,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + addl %edi,%ecx + xorl %eax,%esi + movdqa %xmm9,0(%rsp) + rorl $7,%ebp + addl %edx,%ecx + addl 24(%rsp),%ebx + pslld $2,%xmm5 + xorl %ebp,%esi + movl %ecx,%edi + psrld $30,%xmm8 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + por %xmm8,%xmm5 + addl %ecx,%ebx + addl 28(%rsp),%eax + pshufd $238,%xmm4,%xmm9 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + pxor %xmm2,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + punpcklqdq %xmm5,%xmm9 + movl %eax,%edi + xorl %ecx,%esi + pxor %xmm7,%xmm6 + roll $5,%eax + addl %esi,%ebp + movdqa %xmm10,%xmm8 + xorl %ebx,%edi + paddd %xmm5,%xmm10 + xorl %ecx,%ebx + pxor %xmm9,%xmm6 + addl %eax,%ebp + addl 36(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movdqa %xmm6,%xmm9 + movl %ebp,%esi + xorl %ebx,%edi + movdqa %xmm10,16(%rsp) + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + pslld $2,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + psrld $30,%xmm9 + addl 40(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + por %xmm9,%xmm6 + rorl $7,%ebp + movl %edx,%edi + xorl %eax,%esi + roll $5,%edx + pshufd $238,%xmm5,%xmm10 + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movl %ecx,%esi + xorl %ebp,%edi + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + pxor %xmm3,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + rorl $7,%ecx + punpcklqdq %xmm6,%xmm10 + movl %ebx,%edi + xorl %edx,%esi + pxor %xmm0,%xmm7 + roll $5,%ebx + addl %esi,%eax + movdqa 32(%r14),%xmm9 + xorl %ecx,%edi + paddd %xmm6,%xmm8 + xorl %edx,%ecx + pxor %xmm10,%xmm7 + addl %ebx,%eax + addl 52(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movdqa %xmm7,%xmm10 + movl %eax,%esi + xorl %ecx,%edi + movdqa %xmm8,32(%rsp) + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + pslld $2,%xmm7 + xorl %ecx,%ebx + addl %eax,%ebp + psrld $30,%xmm10 + addl 56(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + por %xmm10,%xmm7 + rorl $7,%eax + movl %ebp,%edi + xorl %ebx,%esi + roll $5,%ebp + pshufd $238,%xmm6,%xmm8 + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movl %edx,%esi + xorl %eax,%edi + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + pxor %xmm4,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + rorl $7,%edx + punpcklqdq %xmm7,%xmm8 + movl %ecx,%edi + xorl %ebp,%esi + pxor %xmm1,%xmm0 + roll $5,%ecx + addl %esi,%ebx + movdqa %xmm9,%xmm10 + xorl %edx,%edi + paddd %xmm7,%xmm9 + xorl %ebp,%edx + pxor %xmm8,%xmm0 + addl %ecx,%ebx + addl 4(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movdqa %xmm0,%xmm8 + movl %ebx,%esi + xorl %edx,%edi + movdqa %xmm9,48(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + pslld $2,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + psrld $30,%xmm8 + addl 8(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + por %xmm8,%xmm0 + rorl $7,%ebx + movl %eax,%edi + xorl %ecx,%esi + roll $5,%eax + pshufd $238,%xmm7,%xmm9 + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movl %ebp,%esi + xorl %ebx,%edi + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + pxor %xmm5,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%ebp + punpcklqdq %xmm0,%xmm9 + movl %edx,%edi + xorl %eax,%esi + pxor %xmm2,%xmm1 + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm8 + xorl %ebp,%edi + paddd %xmm0,%xmm10 + xorl %eax,%ebp + pxor %xmm9,%xmm1 + addl %edx,%ecx + addl 20(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movdqa %xmm1,%xmm9 + movl %ecx,%esi + xorl %ebp,%edi + movdqa %xmm10,0(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + pslld $2,%xmm1 + xorl %ebp,%edx + addl %ecx,%ebx + psrld $30,%xmm9 + addl 24(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + por %xmm9,%xmm1 + rorl $7,%ecx + movl %ebx,%edi + xorl %edx,%esi + roll $5,%ebx + pshufd $238,%xmm0,%xmm10 + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%edi + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + pxor %xmm6,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + punpcklqdq %xmm1,%xmm10 + movl %ebp,%edi + xorl %ebx,%esi + pxor %xmm3,%xmm2 + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm9 + xorl %eax,%edi + paddd %xmm1,%xmm8 + xorl %ebx,%eax + pxor %xmm10,%xmm2 + addl %ebp,%edx + addl 36(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movdqa %xmm2,%xmm10 + movl %edx,%esi + xorl %eax,%edi + movdqa %xmm8,16(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + pslld $2,%xmm2 + xorl %eax,%ebp + addl %edx,%ecx + psrld $30,%xmm10 + addl 40(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + por %xmm10,%xmm2 + rorl $7,%edx + movl %ecx,%edi + xorl %ebp,%esi + roll $5,%ecx + pshufd $238,%xmm1,%xmm8 + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm2,%xmm8 + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%ebx + paddd %xmm2,%xmm9 + addl %eax,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm9,32(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 56(%rsp),%ecx + pslld $2,%xmm3 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm8 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm8,%xmm3 + addl %edx,%ecx + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + paddd %xmm3,%xmm10 + addl %esi,%eax + xorl %edx,%edi + movdqa %xmm10,48(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je .Ldone_ssse3 + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi +.byte 102,15,56,0,206 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + paddd %xmm9,%xmm0 + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + movdqa %xmm0,0(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + psubd %xmm9,%xmm0 + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi +.byte 102,15,56,0,214 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + paddd %xmm9,%xmm1 + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + movdqa %xmm1,16(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + psubd %xmm9,%xmm1 + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi +.byte 102,15,56,0,222 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + paddd %xmm9,%xmm2 + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + movdqa %xmm2,32(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + psubd %xmm9,%xmm2 + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp .Loop_ssse3 + +.align 16 +.Ldone_ssse3: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_ssse3: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3 +.type sha1_block_data_order_avx,@function +.align 16 +sha1_block_data_order_avx: +_avx_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + leaq -64(%rsp),%rsp + vzeroupper + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm11,%xmm0,%xmm4 + vpaddd %xmm11,%xmm1,%xmm5 + vpaddd %xmm11,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + jmp .Loop_avx +.align 16 +.Loop_avx: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm11,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm10 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm4,%xmm4 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vpxor %xmm10,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm11,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm10 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm10,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa -32(%r14),%xmm11 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vpaddd %xmm5,%xmm11,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm10 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm6,%xmm6 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm10,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm11,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm10 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm10,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm11,%xmm9 + addl %esi,%edx + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm11,%xmm9 + vmovdqa 0(%r14),%xmm11 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + vpaddd %xmm3,%xmm11,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm11,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm11,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm11,%xmm9 + vmovdqa 32(%r14),%xmm11 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm11,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm11,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm11,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm11,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je .Ldone_avx + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm11,%xmm0,%xmm4 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm11,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm5,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm11,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm6,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp .Loop_avx + +.align 16 +.Ldone_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroupper + + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_avx,.-sha1_block_data_order_avx +.type sha1_block_data_order_avx2,@function +.align 16 +sha1_block_data_order_avx2: +_avx2_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + vzeroupper + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + leaq -640(%rsp),%rsp + shlq $6,%r10 + leaq 64(%r9),%r13 + andq $-128,%rsp + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + cmpq %r10,%r13 + cmovaeq %r9,%r13 + movl 4(%r8),%ebp + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl 16(%r8),%esi + vmovdqu 64(%r14),%ymm6 + + vmovdqu (%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + leaq 64(%r9),%r9 + vinserti128 $1,(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vpshufb %ymm6,%ymm0,%ymm0 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vpshufb %ymm6,%ymm1,%ymm1 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + vpshufb %ymm6,%ymm2,%ymm2 + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm3,%ymm3 + + vpaddd %ymm11,%ymm0,%ymm4 + vpaddd %ymm11,%ymm1,%ymm5 + vmovdqu %ymm4,0(%rsp) + vpaddd %ymm11,%ymm2,%ymm6 + vmovdqu %ymm5,32(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + vmovdqu %ymm6,64(%rsp) + vmovdqu %ymm7,96(%rsp) + vpalignr $8,%ymm0,%ymm1,%ymm4 + vpsrldq $4,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $31,%ymm4,%ymm8 + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + vpxor %ymm10,%ymm4,%ymm4 + vpaddd %ymm11,%ymm4,%ymm9 + vmovdqu %ymm9,128(%rsp) + vpalignr $8,%ymm1,%ymm2,%ymm5 + vpsrldq $4,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm10,%ymm5,%ymm5 + vpaddd %ymm11,%ymm5,%ymm9 + vmovdqu %ymm9,160(%rsp) + vpalignr $8,%ymm2,%ymm3,%ymm6 + vpsrldq $4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $31,%ymm6,%ymm8 + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + vpxor %ymm10,%ymm6,%ymm6 + vpaddd %ymm11,%ymm6,%ymm9 + vmovdqu %ymm9,192(%rsp) + vpalignr $8,%ymm3,%ymm4,%ymm7 + vpsrldq $4,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm7,%ymm8 + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + vpxor %ymm10,%ymm7,%ymm7 + vpaddd %ymm11,%ymm7,%ymm9 + vmovdqu %ymm9,224(%rsp) + leaq 128(%rsp),%r13 + jmp .Loop_avx2 +.align 32 +.Loop_avx2: + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + jmp .Lalign32_1 +.align 32 +.Lalign32_1: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + vpxor %ymm1,%ymm0,%ymm0 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpxor %ymm8,%ymm0,%ymm0 + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vpor %ymm8,%ymm0,%ymm0 + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + vpaddd %ymm11,%ymm0,%ymm9 + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + vmovdqu %ymm9,256(%rsp) + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + vpxor %ymm2,%ymm1,%ymm1 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpxor %ymm8,%ymm1,%ymm1 + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vpor %ymm8,%ymm1,%ymm1 + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + vpaddd %ymm11,%ymm1,%ymm9 + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vmovdqu %ymm9,288(%rsp) + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + vpxor %ymm3,%ymm2,%ymm2 + vmovdqu 0(%r14),%ymm11 + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpxor %ymm8,%ymm2,%ymm2 + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vpor %ymm8,%ymm2,%ymm2 + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + vpaddd %ymm11,%ymm2,%ymm9 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vmovdqu %ymm9,320(%rsp) + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + vpxor %ymm4,%ymm3,%ymm3 + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpxor %ymm8,%ymm3,%ymm3 + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + vpor %ymm8,%ymm3,%ymm3 + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + vpaddd %ymm11,%ymm3,%ymm9 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vmovdqu %ymm9,352(%rsp) + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpalignr $8,%ymm2,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpxor %ymm5,%ymm4,%ymm4 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpxor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + vpsrld $30,%ymm4,%ymm8 + vpslld $2,%ymm4,%ymm4 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpor %ymm8,%ymm4,%ymm4 + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpaddd %ymm11,%ymm4,%ymm9 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + vmovdqu %ymm9,384(%rsp) + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpalignr $8,%ymm3,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm6,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpxor %ymm8,%ymm5,%ymm5 + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + vpsrld $30,%ymm5,%ymm8 + vpslld $2,%ymm5,%ymm5 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vpor %ymm8,%ymm5,%ymm5 + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + vmovdqu %ymm9,416(%rsp) + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm7,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + vpxor %ymm8,%ymm6,%ymm6 + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + vpsrld $30,%ymm6,%ymm8 + vpslld $2,%ymm6,%ymm6 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpor %ymm8,%ymm6,%ymm6 + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + vmovdqu %ymm9,448(%rsp) + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm5,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm0,%ymm7,%ymm7 + vmovdqu 32(%r14),%ymm11 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpxor %ymm8,%ymm7,%ymm7 + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + vpsrld $30,%ymm7,%ymm8 + vpslld $2,%ymm7,%ymm7 + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpor %ymm8,%ymm7,%ymm7 + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + vmovdqu %ymm9,480(%rsp) + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + jmp .Lalign32_2 +.align 32 +.Lalign32_2: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -64(%r13),%ebp + xorl %esi,%ecx + vpxor %ymm1,%ymm0,%ymm0 + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + vpxor %ymm8,%ymm0,%ymm0 + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + vpor %ymm8,%ymm0,%ymm0 + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpaddd %ymm11,%ymm0,%ymm9 + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + vmovdqu %ymm9,512(%rsp) + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -28(%r13),%ebx + xorl %eax,%edx + vpxor %ymm2,%ymm1,%ymm1 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpxor %ymm8,%ymm1,%ymm1 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + vpor %ymm8,%ymm1,%ymm1 + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpaddd %ymm11,%ymm1,%ymm9 + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + vmovdqu %ymm9,544(%rsp) + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl 8(%r13),%ecx + xorl %ebp,%esi + vpxor %ymm3,%ymm2,%ymm2 + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + vpxor %ymm8,%ymm2,%ymm2 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + vpor %ymm8,%ymm2,%ymm2 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpaddd %ymm11,%ymm2,%ymm9 + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + vmovdqu %ymm9,576(%rsp) + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl 44(%r13),%edx + xorl %ebx,%eax + vpxor %ymm4,%ymm3,%ymm3 + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm3,%ymm3 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl %r12d,%edx + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + vpor %ymm8,%ymm3,%ymm3 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpaddd %ymm11,%ymm3,%ymm9 + addl %r12d,%ecx + andl %edi,%edx + addl 68(%r13),%ebx + xorl %eax,%edx + vmovdqu %ymm9,608(%rsp) + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -96(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -60(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%r9),%r13 + leaq 128(%r9),%rdi + cmpq %r10,%r13 + cmovaeq %r9,%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + je .Ldone_avx2 + vmovdqu 64(%r14),%ymm6 + cmpq %r10,%rdi + ja .Last_avx2 + + vmovdqu -64(%rdi),%xmm0 + vmovdqu -48(%rdi),%xmm1 + vmovdqu -32(%rdi),%xmm2 + vmovdqu -16(%rdi),%xmm3 + vinserti128 $1,0(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + jmp .Last_avx2 + +.align 32 +.Last_avx2: + leaq 128+16(%rsp),%r13 + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + subq $-128,%r9 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm0,%ymm0 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpshufb %ymm6,%ymm1,%ymm1 + vpaddd %ymm11,%ymm0,%ymm8 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vmovdqu %ymm8,0(%rsp) + vpshufb %ymm6,%ymm2,%ymm2 + vpaddd %ymm11,%ymm1,%ymm9 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + vmovdqu %ymm9,32(%rsp) + vpshufb %ymm6,%ymm3,%ymm3 + vpaddd %ymm11,%ymm2,%ymm6 + addl -64(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + jmp .Lalign32_3 +.align 32 +.Lalign32_3: + vmovdqu %ymm6,64(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + addl -28(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vmovdqu %ymm7,96(%rsp) + addl 8(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm0,%ymm1,%ymm4 + addl 44(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + vpsrldq $4,%ymm3,%ymm8 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + xorl %ebp,%esi + addl %r12d,%edx + vpxor %ymm8,%ymm4,%ymm4 + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + vpsrld $31,%ymm4,%ymm8 + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + andl %edi,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + addl 68(%r13),%ebx + xorl %eax,%edx + vpxor %ymm10,%ymm4,%ymm4 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpaddd %ymm11,%ymm4,%ymm9 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vmovdqu %ymm9,128(%rsp) + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm1,%ymm2,%ymm5 + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrldq $4,%ymm4,%ymm8 + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + xorl %eax,%edx + addl %r12d,%ecx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + vpxor %ymm10,%ymm5,%ymm5 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vmovdqu %ymm9,160(%rsp) + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm2,%ymm3,%ymm6 + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpsrldq $4,%ymm5,%ymm8 + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm8,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + vpsrld $31,%ymm6,%ymm8 + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + xorl %ebp,%esi + addl %r12d,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + xorl %ebx,%esi + addl -96(%r13),%ecx + vpxor %ymm10,%ymm6,%ymm6 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vmovdqu %ymm9,192(%rsp) + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpalignr $8,%ymm3,%ymm4,%ymm7 + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpsrldq $4,%ymm6,%ymm8 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm8,%ymm7,%ymm7 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + vpsrld $31,%ymm7,%ymm8 + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + xorl %ebx,%eax + addl %r12d,%esi + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + xorl %ecx,%eax + addl -60(%r13),%edx + vpxor %ymm10,%ymm7,%ymm7 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vmovdqu %ymm9,224(%rsp) + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%rsp),%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + jbe .Loop_avx2 + +.Ldone_avx2: + vzeroupper + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_avx2,.-sha1_block_data_order_avx2 +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S new file mode 100644 index 00000000..23797c42 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S @@ -0,0 +1,5473 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +.globl _sha1_block_data_order +.private_extern _sha1_block_data_order + +.p2align 4 +_sha1_block_data_order: + + leaq _OPENSSL_ia32cap_P(%rip),%r10 + movl 0(%r10),%r9d + movl 4(%r10),%r8d + movl 8(%r10),%r10d + testl $512,%r8d + jz L$ialu + testl $536870912,%r10d + jnz _shaext_shortcut + andl $296,%r10d + cmpl $296,%r10d + je _avx2_shortcut + andl $268435456,%r8d + andl $1073741824,%r9d + orl %r9d,%r8d + cmpl $1342177280,%r8d + je _avx_shortcut + jmp _ssse3_shortcut + +.p2align 4 +L$ialu: + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %rax,64(%rsp) + +L$prologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp L$loop + +.p2align 4 +L$loop: + movl 0(%r9),%edx + bswapl %edx + movl 4(%r9),%ebp + movl %r12d,%eax + movl %edx,0(%rsp) + movl %esi,%ecx + bswapl %ebp + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 8(%r9),%r14d + movl %r11d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ecx + bswapl %r14d + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 12(%r9),%edx + movl %edi,%eax + movl %r14d,8(%rsp) + movl %r12d,%ecx + bswapl %edx + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 16(%r9),%ebp + movl %esi,%eax + movl %edx,12(%rsp) + movl %r11d,%ecx + bswapl %ebp + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 20(%r9),%r14d + movl %r13d,%eax + movl %ebp,16(%rsp) + movl %edi,%ecx + bswapl %r14d + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 24(%r9),%edx + movl %r12d,%eax + movl %r14d,20(%rsp) + movl %esi,%ecx + bswapl %edx + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%r14,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 28(%r9),%ebp + movl %r11d,%eax + movl %edx,24(%rsp) + movl %r13d,%ecx + bswapl %ebp + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 32(%r9),%r14d + movl %edi,%eax + movl %ebp,28(%rsp) + movl %r12d,%ecx + bswapl %r14d + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 36(%r9),%edx + movl %esi,%eax + movl %r14d,32(%rsp) + movl %r11d,%ecx + bswapl %edx + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%r14,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 40(%r9),%ebp + movl %r13d,%eax + movl %edx,36(%rsp) + movl %edi,%ecx + bswapl %ebp + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rdx,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 44(%r9),%r14d + movl %r12d,%eax + movl %ebp,40(%rsp) + movl %esi,%ecx + bswapl %r14d + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 48(%r9),%edx + movl %r11d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ecx + bswapl %edx + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%r14,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 52(%r9),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %r12d,%ecx + bswapl %ebp + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rdx,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 56(%r9),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r11d,%ecx + bswapl %r14d + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rbp,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 60(%r9),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %edi,%ecx + bswapl %edx + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%r14,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %esi,%ecx + xorl 8(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + roll $30,%edi + xorl %r12d,%eax + addl %ecx,%r13d + roll $1,%ebp + addl %eax,%r13d + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %r13d,%ecx + xorl 12(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + roll $30,%esi + xorl %r11d,%eax + addl %ecx,%r12d + roll $1,%r14d + addl %eax,%r12d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + roll $30,%r13d + xorl %edi,%eax + addl %ecx,%r11d + roll $1,%edx + addl %eax,%r11d + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + roll $30,%r12d + xorl %esi,%eax + addl %ecx,%edi + roll $1,%ebp + addl %eax,%edi + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %edi,%ecx + xorl 24(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + roll $30,%r11d + xorl %r13d,%eax + addl %ecx,%esi + roll $1,%r14d + addl %eax,%esi + xorl 20(%rsp),%edx + movl %edi,%eax + movl %r14d,16(%rsp) + movl %esi,%ecx + xorl 28(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 24(%rsp),%ebp + movl %esi,%eax + movl %edx,20(%rsp) + movl %r13d,%ecx + xorl 32(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %r13d,%eax + movl %ebp,24(%rsp) + movl %r12d,%ecx + xorl 36(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %r12d,%eax + movl %r14d,28(%rsp) + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r11d,%eax + movl %edx,32(%rsp) + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %edi,%eax + movl %ebp,36(%rsp) + movl %esi,%ecx + xorl 48(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal 1859775393(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 44(%rsp),%edx + movl %esi,%eax + movl %r14d,40(%rsp) + movl %r13d,%ecx + xorl 52(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal 1859775393(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 48(%rsp),%ebp + movl %r13d,%eax + movl %edx,44(%rsp) + movl %r12d,%ecx + xorl 56(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal 1859775393(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %r12d,%eax + movl %ebp,48(%rsp) + movl %r11d,%ecx + xorl 60(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal 1859775393(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r11d,%eax + movl %r14d,52(%rsp) + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal 1859775393(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 60(%rsp),%ebp + movl %edi,%eax + movl %edx,56(%rsp) + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal 1859775393(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 0(%rsp),%r14d + movl %esi,%eax + movl %ebp,60(%rsp) + movl %r13d,%ecx + xorl 8(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%r14d + leal 1859775393(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 4(%rsp),%edx + movl %r13d,%eax + movl %r14d,0(%rsp) + movl %r12d,%ecx + xorl 12(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%edx + leal 1859775393(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 8(%rsp),%ebp + movl %r12d,%eax + movl %edx,4(%rsp) + movl %r11d,%ecx + xorl 16(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%ebp + leal 1859775393(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 12(%rsp),%r14d + movl %r11d,%eax + movl %ebp,8(%rsp) + movl %edi,%ecx + xorl 20(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%r14d + leal 1859775393(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 16(%rsp),%edx + movl %edi,%eax + movl %r14d,12(%rsp) + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 20(%rsp),%ebp + movl %esi,%eax + movl %edx,16(%rsp) + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 52(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 24(%rsp),%r14d + movl %r13d,%eax + movl %ebp,20(%rsp) + movl %r12d,%ecx + xorl 32(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 56(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 28(%rsp),%edx + movl %r12d,%eax + movl %r14d,24(%rsp) + movl %r11d,%ecx + xorl 36(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 60(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 32(%rsp),%ebp + movl %r11d,%eax + movl %edx,28(%rsp) + movl %edi,%ecx + xorl 40(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 0(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 36(%rsp),%r14d + movl %r12d,%eax + movl %ebp,32(%rsp) + movl %r12d,%ebx + xorl 44(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 40(%rsp),%edx + movl %r11d,%eax + movl %r14d,36(%rsp) + movl %r11d,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 44(%rsp),%ebp + movl %edi,%eax + movl %edx,40(%rsp) + movl %edi,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 48(%rsp),%r14d + movl %esi,%eax + movl %ebp,44(%rsp) + movl %esi,%ebx + xorl 56(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 52(%rsp),%edx + movl %r13d,%eax + movl %r14d,48(%rsp) + movl %r13d,%ebx + xorl 60(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 56(%rsp),%ebp + movl %r12d,%eax + movl %edx,52(%rsp) + movl %r12d,%ebx + xorl 0(%rsp),%ebp + andl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%ebp + leal -1894007588(%rdx,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%ebp + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 60(%rsp),%r14d + movl %r11d,%eax + movl %ebp,56(%rsp) + movl %r11d,%ebx + xorl 4(%rsp),%r14d + andl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%r14d + leal -1894007588(%rbp,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%r14d + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 0(%rsp),%edx + movl %edi,%eax + movl %r14d,60(%rsp) + movl %edi,%ebx + xorl 8(%rsp),%edx + andl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + leal -1894007588(%r14,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%edx + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 4(%rsp),%ebp + movl %esi,%eax + movl %edx,0(%rsp) + movl %esi,%ebx + xorl 12(%rsp),%ebp + andl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + leal -1894007588(%rdx,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%ebp + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 8(%rsp),%r14d + movl %r13d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ebx + xorl 16(%rsp),%r14d + andl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%r14d + leal -1894007588(%rbp,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%r14d + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 12(%rsp),%edx + movl %r12d,%eax + movl %r14d,8(%rsp) + movl %r12d,%ebx + xorl 20(%rsp),%edx + andl %r11d,%eax + movl %esi,%ecx + xorl 44(%rsp),%edx + leal -1894007588(%r14,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%edx + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 16(%rsp),%ebp + movl %r11d,%eax + movl %edx,12(%rsp) + movl %r11d,%ebx + xorl 24(%rsp),%ebp + andl %edi,%eax + movl %r13d,%ecx + xorl 48(%rsp),%ebp + leal -1894007588(%rdx,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%ebp + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 20(%rsp),%r14d + movl %edi,%eax + movl %ebp,16(%rsp) + movl %edi,%ebx + xorl 28(%rsp),%r14d + andl %esi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%r14d + leal -1894007588(%rbp,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%r14d + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 24(%rsp),%edx + movl %esi,%eax + movl %r14d,20(%rsp) + movl %esi,%ebx + xorl 32(%rsp),%edx + andl %r13d,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + leal -1894007588(%r14,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%edx + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 28(%rsp),%ebp + movl %r13d,%eax + movl %edx,24(%rsp) + movl %r13d,%ebx + xorl 36(%rsp),%ebp + andl %r12d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + leal -1894007588(%rdx,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%ebp + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 32(%rsp),%r14d + movl %r12d,%eax + movl %ebp,28(%rsp) + movl %r12d,%ebx + xorl 40(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 0(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 36(%rsp),%edx + movl %r11d,%eax + movl %r14d,32(%rsp) + movl %r11d,%ebx + xorl 44(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 4(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 40(%rsp),%ebp + movl %edi,%eax + movl %edx,36(%rsp) + movl %edi,%ebx + xorl 48(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 44(%rsp),%r14d + movl %esi,%eax + movl %ebp,40(%rsp) + movl %esi,%ebx + xorl 52(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 12(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 48(%rsp),%edx + movl %r13d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 52(%rsp),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 20(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 56(%rsp),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r13d,%ecx + xorl 0(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 24(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 60(%rsp),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %r12d,%ecx + xorl 4(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 28(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %r11d,%ecx + xorl 8(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %edi,%ecx + xorl 12(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + leal -899497514(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + leal -899497514(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + leal -899497514(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %r12d,%ecx + xorl 24(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + leal -899497514(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 20(%rsp),%edx + movl %r12d,%eax + movl %r14d,16(%rsp) + movl %r11d,%ecx + xorl 28(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal -899497514(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 24(%rsp),%ebp + movl %r11d,%eax + movl %edx,20(%rsp) + movl %edi,%ecx + xorl 32(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal -899497514(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %edi,%eax + movl %ebp,24(%rsp) + movl %esi,%ecx + xorl 36(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal -899497514(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %esi,%eax + movl %r14d,28(%rsp) + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal -899497514(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r13d,%eax + + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal -899497514(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %r12d,%eax + + movl %r11d,%ecx + xorl 48(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal -899497514(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 44(%rsp),%edx + movl %r11d,%eax + + movl %edi,%ecx + xorl 52(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal -899497514(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 48(%rsp),%ebp + movl %edi,%eax + + movl %esi,%ecx + xorl 56(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %esi,%eax + + movl %r13d,%ecx + xorl 60(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r13d,%eax + + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 60(%rsp),%ebp + movl %r12d,%eax + + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r11d,%eax + movl %edi,%ecx + xorl %r13d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz L$loop + + movq 64(%rsp),%rsi + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +sha1_block_data_order_shaext: +_shaext_shortcut: + + movdqu (%rdi),%xmm0 + movd 16(%rdi),%xmm1 + movdqa K_XX_XX+160(%rip),%xmm3 + + movdqu (%rsi),%xmm4 + pshufd $27,%xmm0,%xmm0 + movdqu 16(%rsi),%xmm5 + pshufd $27,%xmm1,%xmm1 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,227 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,235 +.byte 102,15,56,0,243 + movdqa %xmm1,%xmm9 +.byte 102,15,56,0,251 + jmp L$oop_shaext + +.p2align 4 +L$oop_shaext: + decq %rdx + leaq 64(%rsi),%r8 + paddd %xmm4,%xmm1 + cmovneq %r8,%rsi + movdqa %xmm0,%xmm8 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 + movdqu (%rsi),%xmm4 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,213 + movdqu 16(%rsi),%xmm5 +.byte 102,15,56,0,227 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,206 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,235 + + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,215 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,243 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 65,15,56,200,201 +.byte 102,15,56,0,251 + + paddd %xmm8,%xmm0 + movdqa %xmm1,%xmm9 + + jnz L$oop_shaext + + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm1,%xmm1 + movdqu %xmm0,(%rdi) + movd %xmm1,16(%rdi) + .byte 0xf3,0xc3 + + + +.p2align 4 +sha1_block_data_order_ssse3: +_ssse3_shortcut: + + movq %rsp,%r11 + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + leaq -64(%rsp),%rsp + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + addq $64,%r9 + paddd %xmm9,%xmm0 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp L$oop_ssse3 +.p2align 4 +L$oop_ssse3: + rorl $2,%ebx + pshufd $238,%xmm0,%xmm4 + xorl %edx,%esi + movdqa %xmm3,%xmm8 + paddd %xmm3,%xmm9 + movl %eax,%edi + addl 0(%rsp),%ebp + punpcklqdq %xmm1,%xmm4 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + psrldq $4,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + pxor %xmm0,%xmm4 + addl %eax,%ebp + rorl $7,%eax + pxor %xmm2,%xmm8 + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + pxor %xmm8,%xmm4 + xorl %ebx,%eax + roll $5,%ebp + movdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + movdqa %xmm4,%xmm10 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + movdqa %xmm4,%xmm8 + xorl %ebx,%esi + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + psrld $31,%xmm8 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm9 + andl %ebp,%edi + xorl %eax,%ebp + psrld $30,%xmm10 + addl %edx,%ecx + rorl $7,%edx + por %xmm8,%xmm4 + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + xorl %ebp,%edx + movdqa -64(%r14),%xmm10 + roll $5,%ecx + addl %edi,%ebx + andl %edx,%esi + pxor %xmm9,%xmm4 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + pshufd $238,%xmm1,%xmm5 + xorl %ebp,%esi + movdqa %xmm4,%xmm9 + paddd %xmm4,%xmm10 + movl %ebx,%edi + addl 16(%rsp),%eax + punpcklqdq %xmm2,%xmm5 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + pxor %xmm1,%xmm5 + addl %ebx,%eax + rorl $7,%ebx + pxor %xmm3,%xmm9 + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + pxor %xmm9,%xmm5 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm10,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + movdqa %xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + movdqa %xmm5,%xmm9 + xorl %ecx,%esi + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + psrld $31,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm10 + andl %eax,%edi + xorl %ebx,%eax + psrld $30,%xmm8 + addl %ebp,%edx + rorl $7,%ebp + por %xmm9,%xmm5 + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + xorl %eax,%ebp + movdqa -32(%r14),%xmm8 + roll $5,%edx + addl %edi,%ecx + andl %ebp,%esi + pxor %xmm10,%xmm5 + xorl %eax,%ebp + addl %edx,%ecx + rorl $7,%edx + pshufd $238,%xmm2,%xmm6 + xorl %eax,%esi + movdqa %xmm5,%xmm10 + paddd %xmm5,%xmm8 + movl %ecx,%edi + addl 32(%rsp),%ebx + punpcklqdq %xmm3,%xmm6 + xorl %ebp,%edx + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm10 + andl %edx,%edi + xorl %ebp,%edx + pxor %xmm2,%xmm6 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm4,%xmm10 + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + pxor %xmm10,%xmm6 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm8,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + movdqa %xmm6,%xmm9 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movdqa %xmm6,%xmm10 + xorl %edx,%esi + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + psrld $31,%xmm10 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + movdqa %xmm9,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + psrld $30,%xmm9 + addl %eax,%ebp + rorl $7,%eax + por %xmm10,%xmm6 + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + xorl %ebx,%eax + movdqa -32(%r14),%xmm9 + roll $5,%ebp + addl %edi,%edx + andl %eax,%esi + pxor %xmm8,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + pshufd $238,%xmm3,%xmm7 + xorl %ebx,%esi + movdqa %xmm6,%xmm8 + paddd %xmm6,%xmm9 + movl %edx,%edi + addl 48(%rsp),%ecx + punpcklqdq %xmm4,%xmm7 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm8 + andl %ebp,%edi + xorl %eax,%ebp + pxor %xmm3,%xmm7 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm5,%xmm8 + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + pxor %xmm8,%xmm7 + xorl %ebp,%edx + roll $5,%ecx + movdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + movdqa %xmm7,%xmm10 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm7,%xmm8 + xorl %ebp,%esi + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + psrld $31,%xmm8 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + movdqa %xmm10,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + psrld $30,%xmm10 + addl %ebx,%eax + rorl $7,%ebx + por %xmm8,%xmm7 + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + xorl %ecx,%ebx + movdqa -32(%r14),%xmm10 + roll $5,%eax + addl %edi,%ebp + andl %ebx,%esi + pxor %xmm9,%xmm7 + pshufd $238,%xmm6,%xmm9 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + pxor %xmm4,%xmm0 + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + punpcklqdq %xmm7,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + pxor %xmm1,%xmm0 + addl %esi,%edx + andl %eax,%edi + movdqa %xmm10,%xmm8 + xorl %ebx,%eax + paddd %xmm7,%xmm10 + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 4(%rsp),%ecx + movdqa %xmm0,%xmm9 + xorl %eax,%ebp + roll $5,%edx + movdqa %xmm10,48(%rsp) + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + pslld $2,%xmm0 + addl %edx,%ecx + rorl $7,%edx + psrld $30,%xmm9 + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + por %xmm9,%xmm0 + xorl %ebp,%edx + roll $5,%ecx + pshufd $238,%xmm7,%xmm10 + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pxor %xmm5,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm0,%xmm10 + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebx + paddd %xmm0,%xmm8 + addl %eax,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm8,0(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 24(%rsp),%ecx + pslld $2,%xmm1 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm10 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm10,%xmm1 + addl %edx,%ecx + addl 28(%rsp),%ebx + pshufd $238,%xmm0,%xmm8 + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + pxor %xmm6,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + punpcklqdq %xmm1,%xmm8 + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + addl %esi,%eax + xorl %edx,%edi + movdqa 0(%r14),%xmm10 + rorl $7,%ecx + paddd %xmm1,%xmm9 + addl %ebx,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + addl %edi,%ebp + xorl %ecx,%esi + movdqa %xmm9,16(%rsp) + rorl $7,%ebx + addl %eax,%ebp + addl 40(%rsp),%edx + pslld $2,%xmm2 + xorl %ebx,%esi + movl %ebp,%edi + psrld $30,%xmm8 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + por %xmm8,%xmm2 + addl %ebp,%edx + addl 44(%rsp),%ecx + pshufd $238,%xmm1,%xmm9 + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + punpcklqdq %xmm2,%xmm9 + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + movdqa %xmm10,%xmm8 + rorl $7,%edx + paddd %xmm2,%xmm10 + addl %ecx,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + addl %edi,%eax + xorl %edx,%esi + movdqa %xmm10,32(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 56(%rsp),%ebp + pslld $2,%xmm3 + xorl %ecx,%esi + movl %eax,%edi + psrld $30,%xmm9 + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + por %xmm9,%xmm3 + addl %eax,%ebp + addl 60(%rsp),%edx + pshufd $238,%xmm2,%xmm10 + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + pxor %xmm0,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + punpcklqdq %xmm3,%xmm10 + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebp + paddd %xmm3,%xmm8 + addl %edx,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + addl %edi,%ebx + xorl %ebp,%esi + movdqa %xmm8,48(%rsp) + rorl $7,%edx + addl %ecx,%ebx + addl 8(%rsp),%eax + pslld $2,%xmm4 + xorl %edx,%esi + movl %ebx,%edi + psrld $30,%xmm10 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + por %xmm10,%xmm4 + addl %ebx,%eax + addl 12(%rsp),%ebp + pshufd $238,%xmm3,%xmm8 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + pxor %xmm1,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + punpcklqdq %xmm4,%xmm8 + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%eax + paddd %xmm4,%xmm9 + addl %ebp,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + addl %edi,%ecx + xorl %eax,%esi + movdqa %xmm9,0(%rsp) + rorl $7,%ebp + addl %edx,%ecx + addl 24(%rsp),%ebx + pslld $2,%xmm5 + xorl %ebp,%esi + movl %ecx,%edi + psrld $30,%xmm8 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + por %xmm8,%xmm5 + addl %ecx,%ebx + addl 28(%rsp),%eax + pshufd $238,%xmm4,%xmm9 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + pxor %xmm2,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + punpcklqdq %xmm5,%xmm9 + movl %eax,%edi + xorl %ecx,%esi + pxor %xmm7,%xmm6 + roll $5,%eax + addl %esi,%ebp + movdqa %xmm10,%xmm8 + xorl %ebx,%edi + paddd %xmm5,%xmm10 + xorl %ecx,%ebx + pxor %xmm9,%xmm6 + addl %eax,%ebp + addl 36(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movdqa %xmm6,%xmm9 + movl %ebp,%esi + xorl %ebx,%edi + movdqa %xmm10,16(%rsp) + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + pslld $2,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + psrld $30,%xmm9 + addl 40(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + por %xmm9,%xmm6 + rorl $7,%ebp + movl %edx,%edi + xorl %eax,%esi + roll $5,%edx + pshufd $238,%xmm5,%xmm10 + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movl %ecx,%esi + xorl %ebp,%edi + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + pxor %xmm3,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + rorl $7,%ecx + punpcklqdq %xmm6,%xmm10 + movl %ebx,%edi + xorl %edx,%esi + pxor %xmm0,%xmm7 + roll $5,%ebx + addl %esi,%eax + movdqa 32(%r14),%xmm9 + xorl %ecx,%edi + paddd %xmm6,%xmm8 + xorl %edx,%ecx + pxor %xmm10,%xmm7 + addl %ebx,%eax + addl 52(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movdqa %xmm7,%xmm10 + movl %eax,%esi + xorl %ecx,%edi + movdqa %xmm8,32(%rsp) + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + pslld $2,%xmm7 + xorl %ecx,%ebx + addl %eax,%ebp + psrld $30,%xmm10 + addl 56(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + por %xmm10,%xmm7 + rorl $7,%eax + movl %ebp,%edi + xorl %ebx,%esi + roll $5,%ebp + pshufd $238,%xmm6,%xmm8 + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movl %edx,%esi + xorl %eax,%edi + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + pxor %xmm4,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + rorl $7,%edx + punpcklqdq %xmm7,%xmm8 + movl %ecx,%edi + xorl %ebp,%esi + pxor %xmm1,%xmm0 + roll $5,%ecx + addl %esi,%ebx + movdqa %xmm9,%xmm10 + xorl %edx,%edi + paddd %xmm7,%xmm9 + xorl %ebp,%edx + pxor %xmm8,%xmm0 + addl %ecx,%ebx + addl 4(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movdqa %xmm0,%xmm8 + movl %ebx,%esi + xorl %edx,%edi + movdqa %xmm9,48(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + pslld $2,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + psrld $30,%xmm8 + addl 8(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + por %xmm8,%xmm0 + rorl $7,%ebx + movl %eax,%edi + xorl %ecx,%esi + roll $5,%eax + pshufd $238,%xmm7,%xmm9 + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movl %ebp,%esi + xorl %ebx,%edi + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + pxor %xmm5,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%ebp + punpcklqdq %xmm0,%xmm9 + movl %edx,%edi + xorl %eax,%esi + pxor %xmm2,%xmm1 + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm8 + xorl %ebp,%edi + paddd %xmm0,%xmm10 + xorl %eax,%ebp + pxor %xmm9,%xmm1 + addl %edx,%ecx + addl 20(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movdqa %xmm1,%xmm9 + movl %ecx,%esi + xorl %ebp,%edi + movdqa %xmm10,0(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + pslld $2,%xmm1 + xorl %ebp,%edx + addl %ecx,%ebx + psrld $30,%xmm9 + addl 24(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + por %xmm9,%xmm1 + rorl $7,%ecx + movl %ebx,%edi + xorl %edx,%esi + roll $5,%ebx + pshufd $238,%xmm0,%xmm10 + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%edi + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + pxor %xmm6,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + punpcklqdq %xmm1,%xmm10 + movl %ebp,%edi + xorl %ebx,%esi + pxor %xmm3,%xmm2 + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm9 + xorl %eax,%edi + paddd %xmm1,%xmm8 + xorl %ebx,%eax + pxor %xmm10,%xmm2 + addl %ebp,%edx + addl 36(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movdqa %xmm2,%xmm10 + movl %edx,%esi + xorl %eax,%edi + movdqa %xmm8,16(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + pslld $2,%xmm2 + xorl %eax,%ebp + addl %edx,%ecx + psrld $30,%xmm10 + addl 40(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + por %xmm10,%xmm2 + rorl $7,%edx + movl %ecx,%edi + xorl %ebp,%esi + roll $5,%ecx + pshufd $238,%xmm1,%xmm8 + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm2,%xmm8 + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%ebx + paddd %xmm2,%xmm9 + addl %eax,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm9,32(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 56(%rsp),%ecx + pslld $2,%xmm3 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm8 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm8,%xmm3 + addl %edx,%ecx + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + paddd %xmm3,%xmm10 + addl %esi,%eax + xorl %edx,%edi + movdqa %xmm10,48(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je L$done_ssse3 + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi +.byte 102,15,56,0,206 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + paddd %xmm9,%xmm0 + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + movdqa %xmm0,0(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + psubd %xmm9,%xmm0 + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi +.byte 102,15,56,0,214 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + paddd %xmm9,%xmm1 + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + movdqa %xmm1,16(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + psubd %xmm9,%xmm1 + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi +.byte 102,15,56,0,222 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + paddd %xmm9,%xmm2 + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + movdqa %xmm2,32(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + psubd %xmm9,%xmm2 + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp L$oop_ssse3 + +.p2align 4 +L$done_ssse3: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 + + movq -32(%r11),%r13 + + movq -24(%r11),%r12 + + movq -16(%r11),%rbp + + movq -8(%r11),%rbx + + leaq (%r11),%rsp + +L$epilogue_ssse3: + .byte 0xf3,0xc3 + + + +.p2align 4 +sha1_block_data_order_avx: +_avx_shortcut: + + movq %rsp,%r11 + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + leaq -64(%rsp),%rsp + vzeroupper + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm11,%xmm0,%xmm4 + vpaddd %xmm11,%xmm1,%xmm5 + vpaddd %xmm11,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + jmp L$oop_avx +.p2align 4 +L$oop_avx: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm11,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm10 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm4,%xmm4 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vpxor %xmm10,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm11,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm10 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm10,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa -32(%r14),%xmm11 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vpaddd %xmm5,%xmm11,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm10 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm6,%xmm6 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm10,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm11,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm10 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm10,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm11,%xmm9 + addl %esi,%edx + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm11,%xmm9 + vmovdqa 0(%r14),%xmm11 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + vpaddd %xmm3,%xmm11,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm11,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm11,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm11,%xmm9 + vmovdqa 32(%r14),%xmm11 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm11,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm11,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm11,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm11,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je L$done_avx + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm11,%xmm0,%xmm4 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm11,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm5,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm11,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm6,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp L$oop_avx + +.p2align 4 +L$done_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroupper + + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 + + movq -32(%r11),%r13 + + movq -24(%r11),%r12 + + movq -16(%r11),%rbp + + movq -8(%r11),%rbx + + leaq (%r11),%rsp + +L$epilogue_avx: + .byte 0xf3,0xc3 + + + +.p2align 4 +sha1_block_data_order_avx2: +_avx2_shortcut: + + movq %rsp,%r11 + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + vzeroupper + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + leaq -640(%rsp),%rsp + shlq $6,%r10 + leaq 64(%r9),%r13 + andq $-128,%rsp + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + cmpq %r10,%r13 + cmovaeq %r9,%r13 + movl 4(%r8),%ebp + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl 16(%r8),%esi + vmovdqu 64(%r14),%ymm6 + + vmovdqu (%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + leaq 64(%r9),%r9 + vinserti128 $1,(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vpshufb %ymm6,%ymm0,%ymm0 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vpshufb %ymm6,%ymm1,%ymm1 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + vpshufb %ymm6,%ymm2,%ymm2 + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm3,%ymm3 + + vpaddd %ymm11,%ymm0,%ymm4 + vpaddd %ymm11,%ymm1,%ymm5 + vmovdqu %ymm4,0(%rsp) + vpaddd %ymm11,%ymm2,%ymm6 + vmovdqu %ymm5,32(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + vmovdqu %ymm6,64(%rsp) + vmovdqu %ymm7,96(%rsp) + vpalignr $8,%ymm0,%ymm1,%ymm4 + vpsrldq $4,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $31,%ymm4,%ymm8 + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + vpxor %ymm10,%ymm4,%ymm4 + vpaddd %ymm11,%ymm4,%ymm9 + vmovdqu %ymm9,128(%rsp) + vpalignr $8,%ymm1,%ymm2,%ymm5 + vpsrldq $4,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm10,%ymm5,%ymm5 + vpaddd %ymm11,%ymm5,%ymm9 + vmovdqu %ymm9,160(%rsp) + vpalignr $8,%ymm2,%ymm3,%ymm6 + vpsrldq $4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $31,%ymm6,%ymm8 + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + vpxor %ymm10,%ymm6,%ymm6 + vpaddd %ymm11,%ymm6,%ymm9 + vmovdqu %ymm9,192(%rsp) + vpalignr $8,%ymm3,%ymm4,%ymm7 + vpsrldq $4,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm7,%ymm8 + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + vpxor %ymm10,%ymm7,%ymm7 + vpaddd %ymm11,%ymm7,%ymm9 + vmovdqu %ymm9,224(%rsp) + leaq 128(%rsp),%r13 + jmp L$oop_avx2 +.p2align 5 +L$oop_avx2: + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + jmp L$align32_1 +.p2align 5 +L$align32_1: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + vpxor %ymm1,%ymm0,%ymm0 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpxor %ymm8,%ymm0,%ymm0 + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vpor %ymm8,%ymm0,%ymm0 + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + vpaddd %ymm11,%ymm0,%ymm9 + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + vmovdqu %ymm9,256(%rsp) + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + vpxor %ymm2,%ymm1,%ymm1 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpxor %ymm8,%ymm1,%ymm1 + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vpor %ymm8,%ymm1,%ymm1 + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + vpaddd %ymm11,%ymm1,%ymm9 + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vmovdqu %ymm9,288(%rsp) + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + vpxor %ymm3,%ymm2,%ymm2 + vmovdqu 0(%r14),%ymm11 + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpxor %ymm8,%ymm2,%ymm2 + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vpor %ymm8,%ymm2,%ymm2 + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + vpaddd %ymm11,%ymm2,%ymm9 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vmovdqu %ymm9,320(%rsp) + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + vpxor %ymm4,%ymm3,%ymm3 + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpxor %ymm8,%ymm3,%ymm3 + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + vpor %ymm8,%ymm3,%ymm3 + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + vpaddd %ymm11,%ymm3,%ymm9 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vmovdqu %ymm9,352(%rsp) + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpalignr $8,%ymm2,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpxor %ymm5,%ymm4,%ymm4 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpxor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + vpsrld $30,%ymm4,%ymm8 + vpslld $2,%ymm4,%ymm4 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpor %ymm8,%ymm4,%ymm4 + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpaddd %ymm11,%ymm4,%ymm9 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + vmovdqu %ymm9,384(%rsp) + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpalignr $8,%ymm3,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm6,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpxor %ymm8,%ymm5,%ymm5 + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + vpsrld $30,%ymm5,%ymm8 + vpslld $2,%ymm5,%ymm5 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vpor %ymm8,%ymm5,%ymm5 + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + vmovdqu %ymm9,416(%rsp) + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm7,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + vpxor %ymm8,%ymm6,%ymm6 + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + vpsrld $30,%ymm6,%ymm8 + vpslld $2,%ymm6,%ymm6 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpor %ymm8,%ymm6,%ymm6 + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + vmovdqu %ymm9,448(%rsp) + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm5,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm0,%ymm7,%ymm7 + vmovdqu 32(%r14),%ymm11 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpxor %ymm8,%ymm7,%ymm7 + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + vpsrld $30,%ymm7,%ymm8 + vpslld $2,%ymm7,%ymm7 + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpor %ymm8,%ymm7,%ymm7 + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + vmovdqu %ymm9,480(%rsp) + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + jmp L$align32_2 +.p2align 5 +L$align32_2: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -64(%r13),%ebp + xorl %esi,%ecx + vpxor %ymm1,%ymm0,%ymm0 + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + vpxor %ymm8,%ymm0,%ymm0 + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + vpor %ymm8,%ymm0,%ymm0 + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpaddd %ymm11,%ymm0,%ymm9 + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + vmovdqu %ymm9,512(%rsp) + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -28(%r13),%ebx + xorl %eax,%edx + vpxor %ymm2,%ymm1,%ymm1 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpxor %ymm8,%ymm1,%ymm1 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + vpor %ymm8,%ymm1,%ymm1 + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpaddd %ymm11,%ymm1,%ymm9 + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + vmovdqu %ymm9,544(%rsp) + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl 8(%r13),%ecx + xorl %ebp,%esi + vpxor %ymm3,%ymm2,%ymm2 + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + vpxor %ymm8,%ymm2,%ymm2 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + vpor %ymm8,%ymm2,%ymm2 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpaddd %ymm11,%ymm2,%ymm9 + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + vmovdqu %ymm9,576(%rsp) + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl 44(%r13),%edx + xorl %ebx,%eax + vpxor %ymm4,%ymm3,%ymm3 + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm3,%ymm3 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl %r12d,%edx + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + vpor %ymm8,%ymm3,%ymm3 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpaddd %ymm11,%ymm3,%ymm9 + addl %r12d,%ecx + andl %edi,%edx + addl 68(%r13),%ebx + xorl %eax,%edx + vmovdqu %ymm9,608(%rsp) + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -96(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -60(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%r9),%r13 + leaq 128(%r9),%rdi + cmpq %r10,%r13 + cmovaeq %r9,%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + je L$done_avx2 + vmovdqu 64(%r14),%ymm6 + cmpq %r10,%rdi + ja L$ast_avx2 + + vmovdqu -64(%rdi),%xmm0 + vmovdqu -48(%rdi),%xmm1 + vmovdqu -32(%rdi),%xmm2 + vmovdqu -16(%rdi),%xmm3 + vinserti128 $1,0(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + jmp L$ast_avx2 + +.p2align 5 +L$ast_avx2: + leaq 128+16(%rsp),%r13 + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + subq $-128,%r9 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm0,%ymm0 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpshufb %ymm6,%ymm1,%ymm1 + vpaddd %ymm11,%ymm0,%ymm8 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vmovdqu %ymm8,0(%rsp) + vpshufb %ymm6,%ymm2,%ymm2 + vpaddd %ymm11,%ymm1,%ymm9 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + vmovdqu %ymm9,32(%rsp) + vpshufb %ymm6,%ymm3,%ymm3 + vpaddd %ymm11,%ymm2,%ymm6 + addl -64(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + jmp L$align32_3 +.p2align 5 +L$align32_3: + vmovdqu %ymm6,64(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + addl -28(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vmovdqu %ymm7,96(%rsp) + addl 8(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm0,%ymm1,%ymm4 + addl 44(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + vpsrldq $4,%ymm3,%ymm8 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + xorl %ebp,%esi + addl %r12d,%edx + vpxor %ymm8,%ymm4,%ymm4 + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + vpsrld $31,%ymm4,%ymm8 + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + andl %edi,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + addl 68(%r13),%ebx + xorl %eax,%edx + vpxor %ymm10,%ymm4,%ymm4 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpaddd %ymm11,%ymm4,%ymm9 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vmovdqu %ymm9,128(%rsp) + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm1,%ymm2,%ymm5 + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrldq $4,%ymm4,%ymm8 + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + xorl %eax,%edx + addl %r12d,%ecx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + vpxor %ymm10,%ymm5,%ymm5 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vmovdqu %ymm9,160(%rsp) + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm2,%ymm3,%ymm6 + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpsrldq $4,%ymm5,%ymm8 + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm8,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + vpsrld $31,%ymm6,%ymm8 + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + xorl %ebp,%esi + addl %r12d,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + xorl %ebx,%esi + addl -96(%r13),%ecx + vpxor %ymm10,%ymm6,%ymm6 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vmovdqu %ymm9,192(%rsp) + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpalignr $8,%ymm3,%ymm4,%ymm7 + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpsrldq $4,%ymm6,%ymm8 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm8,%ymm7,%ymm7 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + vpsrld $31,%ymm7,%ymm8 + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + xorl %ebx,%eax + addl %r12d,%esi + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + xorl %ecx,%eax + addl -60(%r13),%edx + vpxor %ymm10,%ymm7,%ymm7 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vmovdqu %ymm9,224(%rsp) + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%rsp),%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + jbe L$oop_avx2 + +L$done_avx2: + vzeroupper + movq -40(%r11),%r14 + + movq -32(%r11),%r13 + + movq -24(%r11),%r12 + + movq -16(%r11),%rbp + + movq -8(%r11),%rbx + + leaq (%r11),%rsp + +L$epilogue_avx2: + .byte 0xf3,0xc3 + + +.p2align 6 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 6 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S new file mode 100644 index 00000000..18c31a20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S @@ -0,0 +1,5574 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl sha256_block_data_order +.hidden sha256_block_data_order +.type sha256_block_data_order,@function +.align 16 +sha256_block_data_order: +.L_sha256_block_data_order_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl %esp,%ebx + call .L000pic_point +.L000pic_point: + popl %ebp + leal .L001K256-.L000pic_point(%ebp),%ebp + subl $16,%esp + andl $-64,%esp + shll $6,%eax + addl %edi,%eax + movl %esi,(%esp) + movl %edi,4(%esp) + movl %eax,8(%esp) + movl %ebx,12(%esp) + leal OPENSSL_ia32cap_P-.L001K256(%ebp),%edx + movl (%edx),%ecx + movl 4(%edx),%ebx + testl $1048576,%ecx + jnz .L002loop + movl 8(%edx),%edx + testl $16777216,%ecx + jz .L003no_xmm + andl $1073741824,%ecx + andl $268435968,%ebx + orl %ebx,%ecx + andl $1342177280,%ecx + cmpl $1342177280,%ecx + je .L004AVX + testl $512,%ebx + jnz .L005SSSE3 +.L003no_xmm: + subl %edi,%eax + cmpl $256,%eax + jae .L006unrolled + jmp .L002loop +.align 16 +.L002loop: + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + bswap %eax + movl 12(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + bswap %eax + movl 28(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 32(%edi),%eax + movl 36(%edi),%ebx + movl 40(%edi),%ecx + bswap %eax + movl 44(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 48(%edi),%eax + movl 52(%edi),%ebx + movl 56(%edi),%ecx + bswap %eax + movl 60(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + addl $64,%edi + leal -36(%esp),%esp + movl %edi,104(%esp) + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,8(%esp) + xorl %ecx,%ebx + movl %ecx,12(%esp) + movl %edi,16(%esp) + movl %ebx,(%esp) + movl 16(%esi),%edx + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edi + movl %ebx,24(%esp) + movl %ecx,28(%esp) + movl %edi,32(%esp) +.align 16 +.L00700_15: + movl %edx,%ecx + movl 24(%esp),%esi + rorl $14,%ecx + movl 28(%esp),%edi + xorl %edx,%ecx + xorl %edi,%esi + movl 96(%esp),%ebx + rorl $5,%ecx + andl %edx,%esi + movl %edx,20(%esp) + xorl %ecx,%edx + addl 32(%esp),%ebx + xorl %edi,%esi + rorl $6,%edx + movl %eax,%ecx + addl %esi,%ebx + rorl $9,%ecx + addl %edx,%ebx + movl 8(%esp),%edi + xorl %eax,%ecx + movl %eax,4(%esp) + leal -4(%esp),%esp + rorl $11,%ecx + movl (%ebp),%esi + xorl %eax,%ecx + movl 20(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %esi,%ebx + movl %eax,(%esp) + addl %ebx,%edx + andl 4(%esp),%eax + addl %ecx,%ebx + xorl %edi,%eax + addl $4,%ebp + addl %ebx,%eax + cmpl $3248222580,%esi + jne .L00700_15 + movl 156(%esp),%ecx + jmp .L00816_63 +.align 16 +.L00816_63: + movl %ecx,%ebx + movl 104(%esp),%esi + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 160(%esp),%ebx + shrl $10,%edi + addl 124(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 24(%esp),%esi + rorl $14,%ecx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %edx,%ecx + xorl %edi,%esi + movl %ebx,96(%esp) + rorl $5,%ecx + andl %edx,%esi + movl %edx,20(%esp) + xorl %ecx,%edx + addl 32(%esp),%ebx + xorl %edi,%esi + rorl $6,%edx + movl %eax,%ecx + addl %esi,%ebx + rorl $9,%ecx + addl %edx,%ebx + movl 8(%esp),%edi + xorl %eax,%ecx + movl %eax,4(%esp) + leal -4(%esp),%esp + rorl $11,%ecx + movl (%ebp),%esi + xorl %eax,%ecx + movl 20(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %esi,%ebx + movl %eax,(%esp) + addl %ebx,%edx + andl 4(%esp),%eax + addl %ecx,%ebx + xorl %edi,%eax + movl 156(%esp),%ecx + addl $4,%ebp + addl %ebx,%eax + cmpl $3329325298,%esi + jne .L00816_63 + movl 356(%esp),%esi + movl 8(%esp),%ebx + movl 16(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl 24(%esp),%eax + movl 28(%esp),%ebx + movl 32(%esp),%ecx + movl 360(%esp),%edi + addl 16(%esi),%edx + addl 20(%esi),%eax + addl 24(%esi),%ebx + addl 28(%esi),%ecx + movl %edx,16(%esi) + movl %eax,20(%esi) + movl %ebx,24(%esi) + movl %ecx,28(%esi) + leal 356(%esp),%esp + subl $256,%ebp + cmpl 8(%esp),%edi + jb .L002loop + movl 12(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L001K256: +.long 1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298 +.long 66051,67438087,134810123,202182159 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97 +.byte 110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32 +.byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 +.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 +.byte 62,0 +.align 16 +.L006unrolled: + leal -96(%esp),%esp + movl (%esi),%eax + movl 4(%esi),%ebp + movl 8(%esi),%ecx + movl 12(%esi),%ebx + movl %ebp,4(%esp) + xorl %ecx,%ebp + movl %ecx,8(%esp) + movl %ebx,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %ebx,20(%esp) + movl %ecx,24(%esp) + movl %esi,28(%esp) + jmp .L009grand_loop +.align 16 +.L009grand_loop: + movl (%edi),%ebx + movl 4(%edi),%ecx + bswap %ebx + movl 8(%edi),%esi + bswap %ecx + movl %ebx,32(%esp) + bswap %esi + movl %ecx,36(%esp) + movl %esi,40(%esp) + movl 12(%edi),%ebx + movl 16(%edi),%ecx + bswap %ebx + movl 20(%edi),%esi + bswap %ecx + movl %ebx,44(%esp) + bswap %esi + movl %ecx,48(%esp) + movl %esi,52(%esp) + movl 24(%edi),%ebx + movl 28(%edi),%ecx + bswap %ebx + movl 32(%edi),%esi + bswap %ecx + movl %ebx,56(%esp) + bswap %esi + movl %ecx,60(%esp) + movl %esi,64(%esp) + movl 36(%edi),%ebx + movl 40(%edi),%ecx + bswap %ebx + movl 44(%edi),%esi + bswap %ecx + movl %ebx,68(%esp) + bswap %esi + movl %ecx,72(%esp) + movl %esi,76(%esp) + movl 48(%edi),%ebx + movl 52(%edi),%ecx + bswap %ebx + movl 56(%edi),%esi + bswap %ecx + movl %ebx,80(%esp) + bswap %esi + movl %ecx,84(%esp) + movl %esi,88(%esp) + movl 60(%edi),%ebx + addl $64,%edi + bswap %ebx + movl %edi,100(%esp) + movl %ebx,92(%esp) + movl %edx,%ecx + movl 20(%esp),%esi + rorl $14,%edx + movl 24(%esp),%edi + xorl %ecx,%edx + movl 32(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1116352408(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 16(%esp),%ecx + rorl $14,%edx + movl 20(%esp),%edi + xorl %esi,%edx + movl 36(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1899447441(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 12(%esp),%esi + rorl $14,%edx + movl 16(%esp),%edi + xorl %ecx,%edx + movl 40(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3049323471(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 8(%esp),%ecx + rorl $14,%edx + movl 12(%esp),%edi + xorl %esi,%edx + movl 44(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3921009573(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 4(%esp),%esi + rorl $14,%edx + movl 8(%esp),%edi + xorl %ecx,%edx + movl 48(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 961987163(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl (%esp),%ecx + rorl $14,%edx + movl 4(%esp),%edi + xorl %esi,%edx + movl 52(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1508970993(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 28(%esp),%esi + rorl $14,%edx + movl (%esp),%edi + xorl %ecx,%edx + movl 56(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2453635748(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 24(%esp),%ecx + rorl $14,%edx + movl 28(%esp),%edi + xorl %esi,%edx + movl 60(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2870763221(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 20(%esp),%esi + rorl $14,%edx + movl 24(%esp),%edi + xorl %ecx,%edx + movl 64(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3624381080(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 16(%esp),%ecx + rorl $14,%edx + movl 20(%esp),%edi + xorl %esi,%edx + movl 68(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 310598401(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 12(%esp),%esi + rorl $14,%edx + movl 16(%esp),%edi + xorl %ecx,%edx + movl 72(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 607225278(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 8(%esp),%ecx + rorl $14,%edx + movl 12(%esp),%edi + xorl %esi,%edx + movl 76(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1426881987(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 4(%esp),%esi + rorl $14,%edx + movl 8(%esp),%edi + xorl %ecx,%edx + movl 80(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1925078388(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl (%esp),%ecx + rorl $14,%edx + movl 4(%esp),%edi + xorl %esi,%edx + movl 84(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2162078206(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 28(%esp),%esi + rorl $14,%edx + movl (%esp),%edi + xorl %ecx,%edx + movl 88(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2614888103(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 24(%esp),%ecx + rorl $14,%edx + movl 28(%esp),%edi + xorl %esi,%edx + movl 92(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3248222580(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3835390401(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 4022224774(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 264347078(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 604807628(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 770255983(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1249150122(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1555081692(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1996064986(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2554220882(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2821834349(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2952996808(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3210313671(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3336571891(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3584528711(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,88(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 113926993(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,92(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 338241895(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 666307205(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 773529912(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1294757372(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1396182291(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1695183700(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1986661051(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2177026350(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2456956037(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2730485921(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2820302411(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3259730800(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3345764771(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3516065817(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3600352804(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,88(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 4094571909(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,92(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 275423344(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 430227734(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 506948616(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 659060556(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 883997877(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 958139571(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1322822218(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1537002063(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1747873779(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1955562222(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2024104815(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2227730452(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2361852424(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2428436474(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2756734187(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3204031479(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3329325298(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 96(%esp),%esi + xorl %edi,%ebp + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebp + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebp,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebp,4(%esp) + xorl %edi,%ebp + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ebx + movl 28(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ebx + addl 28(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %ebx,24(%esi) + movl %ecx,28(%esi) + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ebx,24(%esp) + movl %ecx,28(%esp) + cmpl 104(%esp),%edi + jb .L009grand_loop + movl 108(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L005SSSE3: + leal -96(%esp),%esp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + movdqa 256(%ebp),%xmm7 + jmp .L010grand_ssse3 +.align 16 +.L010grand_ssse3: + movdqu (%edi),%xmm0 + movdqu 16(%edi),%xmm1 + movdqu 32(%edi),%xmm2 + movdqu 48(%edi),%xmm3 + addl $64,%edi +.byte 102,15,56,0,199 + movl %edi,100(%esp) +.byte 102,15,56,0,207 + movdqa (%ebp),%xmm4 +.byte 102,15,56,0,215 + movdqa 16(%ebp),%xmm5 + paddd %xmm0,%xmm4 +.byte 102,15,56,0,223 + movdqa 32(%ebp),%xmm6 + paddd %xmm1,%xmm5 + movdqa 48(%ebp),%xmm7 + movdqa %xmm4,32(%esp) + paddd %xmm2,%xmm6 + movdqa %xmm5,48(%esp) + paddd %xmm3,%xmm7 + movdqa %xmm6,64(%esp) + movdqa %xmm7,80(%esp) + jmp .L011ssse3_00_47 +.align 16 +.L011ssse3_00_47: + addl $64,%ebp + movl %edx,%ecx + movdqa %xmm1,%xmm4 + rorl $14,%edx + movl 20(%esp),%esi + movdqa %xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi +.byte 102,15,58,15,224,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,250,4 + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 4(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm0 + movl %eax,(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm3,%xmm7 + xorl %esi,%ecx + addl 32(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl 16(%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,12(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm0 + movl %ebx,28(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm0 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + pshufd $80,%xmm0,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa (%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,4(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm0 + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + paddd %xmm0,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movdqa %xmm6,32(%esp) + movl %edx,%ecx + movdqa %xmm2,%xmm4 + rorl $14,%edx + movl 4(%esp),%esi + movdqa %xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi +.byte 102,15,58,15,225,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,251,4 + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 20(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm1 + movl %eax,16(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm0,%xmm7 + xorl %esi,%ecx + addl 48(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl (%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,28(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm1 + movl %ebx,12(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm1 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + pshufd $80,%xmm1,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 16(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,20(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm1 + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + paddd %xmm1,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movdqa %xmm6,48(%esp) + movl %edx,%ecx + movdqa %xmm3,%xmm4 + rorl $14,%edx + movl 20(%esp),%esi + movdqa %xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi +.byte 102,15,58,15,226,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,248,4 + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 4(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm2 + movl %eax,(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm1,%xmm7 + xorl %esi,%ecx + addl 64(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl 16(%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,12(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm2 + movl %ebx,28(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm2 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + pshufd $80,%xmm2,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 32(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,4(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm2 + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + paddd %xmm2,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movdqa %xmm6,64(%esp) + movl %edx,%ecx + movdqa %xmm0,%xmm4 + rorl $14,%edx + movl 4(%esp),%esi + movdqa %xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi +.byte 102,15,58,15,227,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,249,4 + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 20(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm3 + movl %eax,16(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm2,%xmm7 + xorl %esi,%ecx + addl 80(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl (%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,28(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm3 + movl %ebx,12(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm3 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + pshufd $80,%xmm3,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 48(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,20(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm3 + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + paddd %xmm3,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L011ssse3_00_47 + movl %edx,%ecx + rorl $14,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + movdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L010grand_ssse3 + movl 108(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L004AVX: + leal -96(%esp),%esp + vzeroall + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + vmovdqa 256(%ebp),%xmm7 + jmp .L012grand_avx +.align 32 +.L012grand_avx: + vmovdqu (%edi),%xmm0 + vmovdqu 16(%edi),%xmm1 + vmovdqu 32(%edi),%xmm2 + vmovdqu 48(%edi),%xmm3 + addl $64,%edi + vpshufb %xmm7,%xmm0,%xmm0 + movl %edi,100(%esp) + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd (%ebp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 16(%ebp),%xmm1,%xmm5 + vpaddd 32(%ebp),%xmm2,%xmm6 + vpaddd 48(%ebp),%xmm3,%xmm7 + vmovdqa %xmm4,32(%esp) + vmovdqa %xmm5,48(%esp) + vmovdqa %xmm6,64(%esp) + vmovdqa %xmm7,80(%esp) + jmp .L013avx_00_47 +.align 16 +.L013avx_00_47: + addl $64,%ebp + vpalignr $4,%xmm0,%xmm1,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm2,%xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm3,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm0,%xmm0 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm0,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm0,%xmm0 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd (%ebp),%xmm0,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,32(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm3,%xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm0,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm1,%xmm1 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm1,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm1,%xmm1 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 16(%ebp),%xmm1,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,48(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm0,%xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm1,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm2,%xmm2 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm2,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm2,%xmm2 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd 32(%ebp),%xmm2,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,64(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm1,%xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm2,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm3,%xmm3 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm3,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm3,%xmm3 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 48(%ebp),%xmm3,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L013avx_00_47 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + vmovdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L012grand_avx + movl 108(%esp),%esp + vzeroall + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size sha256_block_data_order,.-.L_sha256_block_data_order_begin +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S new file mode 100644 index 00000000..405080fd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S @@ -0,0 +1,2853 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Permission to use under GPL terms is granted. +@ ==================================================================== + +@ SHA256 block procedure for ARMv4. May 2007. + +@ Performance is ~2x better than gcc 3.4 generated code and in "abso- +@ lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per +@ byte [on single-issue Xscale PXA250 core]. + +@ July 2010. +@ +@ Rescheduling for dual-issue pipeline resulted in 22% improvement on +@ Cortex A8 core and ~20 cycles per processed byte. + +@ February 2011. +@ +@ Profiler-assisted and platform-specific optimization resulted in 16% +@ improvement on Cortex A8 core and ~15.4 cycles per processed byte. + +@ September 2013. +@ +@ Add NEON implementation. On Cortex A8 it was measured to process one +@ byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon +@ S4 does it in 12.5 cycles too, but it's 50% faster than integer-only +@ code (meaning that latter performs sub-optimally, nothing was done +@ about it). + +@ May 2014. +@ +@ Add ARMv8 code path performing at 2.0 cpb on Apple A7. + +#ifndef __KERNEL__ +# include +#else +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +#endif + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors. It does have ARMv8-only code, but those +@ instructions are manually-encoded. (See unsha256.) + + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + + +.align 5 +K256: +.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +.word 0 @ terminator +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +LOPENSSL_armcap: +.word OPENSSL_armcap_P-Lsha256_block_data_order +#endif +.align 5 + +.globl _sha256_block_data_order +.private_extern _sha256_block_data_order +#ifdef __thumb2__ +.thumb_func _sha256_block_data_order +#endif +_sha256_block_data_order: +Lsha256_block_data_order: +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r3,pc,#8 @ _sha256_block_data_order +#else + adr r3,Lsha256_block_data_order +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + ldr r12,LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV8_SHA256 + bne LARMv8 + tst r12,#ARMV7_NEON + bne LNEON +#endif + add r2,r1,r2,lsl#6 @ len to point at the end of inp + stmdb sp!,{r0,r1,r2,r4-r11,lr} + ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} + sub r14,r3,#256+32 @ K256 + sub sp,sp,#16*4 @ alloca(X[16]) +Loop: +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ magic + eor r12,r12,r12 +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 0 +# if 0==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r8,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 0 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 0==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r8,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#0*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 0==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 0<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#2*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#15*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 1 +# if 1==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r7,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 1 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 1==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r7,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#1*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 1==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 1<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#3*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#0*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 2 +# if 2==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r6,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 2 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 2==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r6,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#2*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 2==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 2<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#4*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#1*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 3 +# if 3==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r5,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 3 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 3==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r5,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#3*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 3==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 3<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#5*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#2*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 4 +# if 4==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r4,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 4 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 4==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r4,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#4*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 4==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 4<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#6*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#3*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 5 +# if 5==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r11,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 5==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r11,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#5*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 5==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 5<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#7*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#4*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 6 +# if 6==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r10,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 6 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 6==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r10,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#6*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 6==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 6<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#8*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#5*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 7 +# if 7==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r9,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 7==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r9,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#7*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 7==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 7<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#9*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#6*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 8 +# if 8==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r8,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 8 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 8==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r8,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#8*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 8==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 8<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#10*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#7*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 9 +# if 9==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r7,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 9 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 9==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r7,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#9*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 9==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 9<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#11*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#8*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 10 +# if 10==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r6,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 10 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 10==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r6,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#10*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 10==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 10<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#12*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#9*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 11 +# if 11==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r5,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 11 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 11==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r5,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#11*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 11==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 11<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#13*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#10*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 12 +# if 12==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r4,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 12 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 12==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r4,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#12*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 12==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 12<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#14*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#11*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 13 +# if 13==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r11,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 13 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 13==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r11,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#13*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 13==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 13<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#15*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#12*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 14 +# if 14==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r10,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 14 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 14==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r10,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#14*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 14==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 14<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#0*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#13*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 15 +# if 15==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r9,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 15 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 15==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r9,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#15*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 15==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 15<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#1*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#14*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +Lrounds_16_xx: + @ ldr r2,[sp,#1*4] @ 16 + @ ldr r1,[sp,#14*4] + mov r0,r2,ror#7 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#0*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#9*4] + + add r12,r12,r0 + eor r0,r8,r8,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r8,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#0*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 16==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 16<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#2*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#15*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#2*4] @ 17 + @ ldr r1,[sp,#15*4] + mov r0,r2,ror#7 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#1*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#10*4] + + add r3,r3,r0 + eor r0,r7,r7,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r7,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#1*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 17==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 17<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#3*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#0*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#3*4] @ 18 + @ ldr r1,[sp,#0*4] + mov r0,r2,ror#7 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#2*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#11*4] + + add r12,r12,r0 + eor r0,r6,r6,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r6,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#2*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 18==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 18<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#4*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#1*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#4*4] @ 19 + @ ldr r1,[sp,#1*4] + mov r0,r2,ror#7 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#3*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#12*4] + + add r3,r3,r0 + eor r0,r5,r5,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r5,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#3*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 19==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 19<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#5*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#2*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#5*4] @ 20 + @ ldr r1,[sp,#2*4] + mov r0,r2,ror#7 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#4*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#13*4] + + add r12,r12,r0 + eor r0,r4,r4,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r4,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#4*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 20==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 20<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#6*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#3*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#6*4] @ 21 + @ ldr r1,[sp,#3*4] + mov r0,r2,ror#7 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#5*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#14*4] + + add r3,r3,r0 + eor r0,r11,r11,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r11,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#5*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 21==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 21<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#7*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#4*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#7*4] @ 22 + @ ldr r1,[sp,#4*4] + mov r0,r2,ror#7 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#6*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#15*4] + + add r12,r12,r0 + eor r0,r10,r10,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r10,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#6*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 22==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 22<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#8*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#5*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#8*4] @ 23 + @ ldr r1,[sp,#5*4] + mov r0,r2,ror#7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#7*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#0*4] + + add r3,r3,r0 + eor r0,r9,r9,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r9,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#7*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 23==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 23<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#9*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#6*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#9*4] @ 24 + @ ldr r1,[sp,#6*4] + mov r0,r2,ror#7 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#8*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#1*4] + + add r12,r12,r0 + eor r0,r8,r8,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r8,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#8*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 24==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 24<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#10*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#7*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#10*4] @ 25 + @ ldr r1,[sp,#7*4] + mov r0,r2,ror#7 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#9*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#2*4] + + add r3,r3,r0 + eor r0,r7,r7,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r7,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#9*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 25==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 25<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#11*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#8*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#11*4] @ 26 + @ ldr r1,[sp,#8*4] + mov r0,r2,ror#7 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#10*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#3*4] + + add r12,r12,r0 + eor r0,r6,r6,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r6,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#10*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 26==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 26<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#12*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#9*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#12*4] @ 27 + @ ldr r1,[sp,#9*4] + mov r0,r2,ror#7 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#11*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#4*4] + + add r3,r3,r0 + eor r0,r5,r5,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r5,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#11*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 27==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 27<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#13*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#10*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#13*4] @ 28 + @ ldr r1,[sp,#10*4] + mov r0,r2,ror#7 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#12*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#5*4] + + add r12,r12,r0 + eor r0,r4,r4,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r4,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#12*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 28==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 28<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#14*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#11*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#14*4] @ 29 + @ ldr r1,[sp,#11*4] + mov r0,r2,ror#7 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#13*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#6*4] + + add r3,r3,r0 + eor r0,r11,r11,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r11,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#13*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 29==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 29<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#15*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#12*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#15*4] @ 30 + @ ldr r1,[sp,#12*4] + mov r0,r2,ror#7 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#14*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#7*4] + + add r12,r12,r0 + eor r0,r10,r10,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r10,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#14*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 30==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 30<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#0*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#13*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#0*4] @ 31 + @ ldr r1,[sp,#13*4] + mov r0,r2,ror#7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#15*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#8*4] + + add r3,r3,r0 + eor r0,r9,r9,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r9,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#15*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 31==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 31<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#1*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#14*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + ite eq @ Thumb2 thing, sanity check in ARM +#endif + ldreq r3,[sp,#16*4] @ pull ctx + bne Lrounds_16_xx + + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldr r0,[r3,#0] + ldr r2,[r3,#4] + ldr r12,[r3,#8] + add r4,r4,r0 + ldr r0,[r3,#12] + add r5,r5,r2 + ldr r2,[r3,#16] + add r6,r6,r12 + ldr r12,[r3,#20] + add r7,r7,r0 + ldr r0,[r3,#24] + add r8,r8,r2 + ldr r2,[r3,#28] + add r9,r9,r12 + ldr r1,[sp,#17*4] @ pull inp + ldr r12,[sp,#18*4] @ pull inp+len + add r10,r10,r0 + add r11,r11,r2 + stmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} + cmp r1,r12 + sub r14,r14,#256 @ rewind Ktbl + bne Loop + + add sp,sp,#19*4 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif + +#if __ARM_MAX_ARCH__>=7 + + + +.globl _sha256_block_data_order_neon +.private_extern _sha256_block_data_order_neon +#ifdef __thumb2__ +.thumb_func _sha256_block_data_order_neon +#endif +.align 5 +.skip 16 +_sha256_block_data_order_neon: +LNEON: + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + + sub r11,sp,#16*4+16 + adr r14,K256 + bic r11,r11,#15 @ align for 128-bit stores + mov r12,sp + mov sp,r11 @ alloca + add r2,r1,r2,lsl#6 @ len to point at the end of inp + + vld1.8 {q0},[r1]! + vld1.8 {q1},[r1]! + vld1.8 {q2},[r1]! + vld1.8 {q3},[r1]! + vld1.32 {q8},[r14,:128]! + vld1.32 {q9},[r14,:128]! + vld1.32 {q10},[r14,:128]! + vld1.32 {q11},[r14,:128]! + vrev32.8 q0,q0 @ yes, even on + str r0,[sp,#64] + vrev32.8 q1,q1 @ big-endian + str r1,[sp,#68] + mov r1,sp + vrev32.8 q2,q2 + str r2,[sp,#72] + vrev32.8 q3,q3 + str r12,[sp,#76] @ save original sp + vadd.i32 q8,q8,q0 + vadd.i32 q9,q9,q1 + vst1.32 {q8},[r1,:128]! + vadd.i32 q10,q10,q2 + vst1.32 {q9},[r1,:128]! + vadd.i32 q11,q11,q3 + vst1.32 {q10},[r1,:128]! + vst1.32 {q11},[r1,:128]! + + ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} + sub r1,r1,#64 + ldr r2,[sp,#0] + eor r12,r12,r12 + eor r3,r5,r6 + b L_00_48 + +.align 4 +L_00_48: + vext.8 q8,q0,q1,#4 + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + vext.8 q9,q2,q3,#4 + add r4,r4,r12 + and r2,r2,r8 + eor r12,r0,r8,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vadd.i32 q0,q0,q9 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + vshr.u32 q9,q8,#3 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#4] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + veor q9,q9,q10 + add r10,r10,r2 + vsli.32 q11,q8,#14 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + vshr.u32 d24,d7,#17 + add r11,r11,r3 + and r2,r2,r7 + veor q9,q9,q11 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + vsli.32 d24,d7,#15 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + vshr.u32 d25,d7,#10 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + vadd.i32 q0,q0,q9 + add r10,r10,r2 + ldr r2,[sp,#8] + veor d25,d25,d24 + and r12,r12,r3 + add r6,r6,r10 + vshr.u32 d24,d7,#19 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + vsli.32 d24,d7,#13 + add r9,r9,r2 + eor r2,r7,r8 + veor d25,d25,d24 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + vadd.i32 d0,d0,d25 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + vshr.u32 d24,d0,#17 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + vsli.32 d24,d0,#15 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + vshr.u32 d25,d0,#10 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + veor d25,d25,d24 + ldr r2,[sp,#12] + and r3,r3,r12 + vshr.u32 d24,d0,#19 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + vld1.32 {q8},[r14,:128]! + add r8,r8,r2 + vsli.32 d24,d0,#13 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + veor d25,d25,d24 + add r9,r9,r3 + and r2,r2,r5 + vadd.i32 d1,d1,d25 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + vadd.i32 q8,q8,q0 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#16] + and r12,r12,r3 + add r4,r4,r8 + vst1.32 {q8},[r1,:128]! + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vext.8 q8,q1,q2,#4 + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + vext.8 q9,q3,q0,#4 + add r8,r8,r12 + and r2,r2,r4 + eor r12,r0,r4,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vadd.i32 q1,q1,q9 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + vshr.u32 q9,q8,#3 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#20] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + veor q9,q9,q10 + add r6,r6,r2 + vsli.32 q11,q8,#14 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + vshr.u32 d24,d1,#17 + add r7,r7,r3 + and r2,r2,r11 + veor q9,q9,q11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + vsli.32 d24,d1,#15 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + vshr.u32 d25,d1,#10 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + vadd.i32 q1,q1,q9 + add r6,r6,r2 + ldr r2,[sp,#24] + veor d25,d25,d24 + and r12,r12,r3 + add r10,r10,r6 + vshr.u32 d24,d1,#19 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + vsli.32 d24,d1,#13 + add r5,r5,r2 + eor r2,r11,r4 + veor d25,d25,d24 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + vadd.i32 d2,d2,d25 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + vshr.u32 d24,d2,#17 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + vsli.32 d24,d2,#15 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + vshr.u32 d25,d2,#10 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + veor d25,d25,d24 + ldr r2,[sp,#28] + and r3,r3,r12 + vshr.u32 d24,d2,#19 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + vld1.32 {q8},[r14,:128]! + add r4,r4,r2 + vsli.32 d24,d2,#13 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + veor d25,d25,d24 + add r5,r5,r3 + and r2,r2,r9 + vadd.i32 d3,d3,d25 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + vadd.i32 q8,q8,q1 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#32] + and r12,r12,r3 + add r8,r8,r4 + vst1.32 {q8},[r1,:128]! + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vext.8 q8,q2,q3,#4 + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + vext.8 q9,q0,q1,#4 + add r4,r4,r12 + and r2,r2,r8 + eor r12,r0,r8,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vadd.i32 q2,q2,q9 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + vshr.u32 q9,q8,#3 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#36] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + veor q9,q9,q10 + add r10,r10,r2 + vsli.32 q11,q8,#14 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + vshr.u32 d24,d3,#17 + add r11,r11,r3 + and r2,r2,r7 + veor q9,q9,q11 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + vsli.32 d24,d3,#15 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + vshr.u32 d25,d3,#10 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + vadd.i32 q2,q2,q9 + add r10,r10,r2 + ldr r2,[sp,#40] + veor d25,d25,d24 + and r12,r12,r3 + add r6,r6,r10 + vshr.u32 d24,d3,#19 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + vsli.32 d24,d3,#13 + add r9,r9,r2 + eor r2,r7,r8 + veor d25,d25,d24 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + vadd.i32 d4,d4,d25 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + vshr.u32 d24,d4,#17 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + vsli.32 d24,d4,#15 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + vshr.u32 d25,d4,#10 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + veor d25,d25,d24 + ldr r2,[sp,#44] + and r3,r3,r12 + vshr.u32 d24,d4,#19 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + vld1.32 {q8},[r14,:128]! + add r8,r8,r2 + vsli.32 d24,d4,#13 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + veor d25,d25,d24 + add r9,r9,r3 + and r2,r2,r5 + vadd.i32 d5,d5,d25 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + vadd.i32 q8,q8,q2 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#48] + and r12,r12,r3 + add r4,r4,r8 + vst1.32 {q8},[r1,:128]! + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vext.8 q8,q3,q0,#4 + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + vext.8 q9,q1,q2,#4 + add r8,r8,r12 + and r2,r2,r4 + eor r12,r0,r4,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vadd.i32 q3,q3,q9 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + vshr.u32 q9,q8,#3 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#52] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + veor q9,q9,q10 + add r6,r6,r2 + vsli.32 q11,q8,#14 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + vshr.u32 d24,d5,#17 + add r7,r7,r3 + and r2,r2,r11 + veor q9,q9,q11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + vsli.32 d24,d5,#15 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + vshr.u32 d25,d5,#10 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + vadd.i32 q3,q3,q9 + add r6,r6,r2 + ldr r2,[sp,#56] + veor d25,d25,d24 + and r12,r12,r3 + add r10,r10,r6 + vshr.u32 d24,d5,#19 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + vsli.32 d24,d5,#13 + add r5,r5,r2 + eor r2,r11,r4 + veor d25,d25,d24 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + vadd.i32 d6,d6,d25 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + vshr.u32 d24,d6,#17 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + vsli.32 d24,d6,#15 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + vshr.u32 d25,d6,#10 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + veor d25,d25,d24 + ldr r2,[sp,#60] + and r3,r3,r12 + vshr.u32 d24,d6,#19 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + vld1.32 {q8},[r14,:128]! + add r4,r4,r2 + vsli.32 d24,d6,#13 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + veor d25,d25,d24 + add r5,r5,r3 + and r2,r2,r9 + vadd.i32 d7,d7,d25 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + vadd.i32 q8,q8,q3 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[r14] + and r12,r12,r3 + add r8,r8,r4 + vst1.32 {q8},[r1,:128]! + add r4,r4,r0,ror#2 + eor r12,r12,r6 + teq r2,#0 @ check for K256 terminator + ldr r2,[sp,#0] + sub r1,r1,#64 + bne L_00_48 + + ldr r1,[sp,#68] + ldr r0,[sp,#72] + sub r14,r14,#256 @ rewind r14 + teq r1,r0 + it eq + subeq r1,r1,#64 @ avoid SEGV + vld1.8 {q0},[r1]! @ load next input block + vld1.8 {q1},[r1]! + vld1.8 {q2},[r1]! + vld1.8 {q3},[r1]! + it ne + strne r1,[sp,#68] + mov r1,sp + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + add r4,r4,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r8 + eor r12,r0,r8,ror#19 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vrev32.8 q0,q0 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vadd.i32 q8,q8,q0 + ldr r2,[sp,#4] + and r3,r3,r12 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + add r10,r10,r2 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + add r11,r11,r3 + and r2,r2,r7 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + add r10,r10,r2 + ldr r2,[sp,#8] + and r12,r12,r3 + add r6,r6,r10 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + add r9,r9,r2 + eor r2,r7,r8 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + ldr r2,[sp,#12] + and r3,r3,r12 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + add r8,r8,r2 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + add r9,r9,r3 + and r2,r2,r5 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#16] + and r12,r12,r3 + add r4,r4,r8 + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vst1.32 {q8},[r1,:128]! + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + add r8,r8,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r4 + eor r12,r0,r4,ror#19 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vrev32.8 q1,q1 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vadd.i32 q8,q8,q1 + ldr r2,[sp,#20] + and r3,r3,r12 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + add r6,r6,r2 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + add r7,r7,r3 + and r2,r2,r11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + add r6,r6,r2 + ldr r2,[sp,#24] + and r12,r12,r3 + add r10,r10,r6 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + add r5,r5,r2 + eor r2,r11,r4 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + ldr r2,[sp,#28] + and r3,r3,r12 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + add r4,r4,r2 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + add r5,r5,r3 + and r2,r2,r9 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#32] + and r12,r12,r3 + add r8,r8,r4 + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vst1.32 {q8},[r1,:128]! + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + add r4,r4,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r8 + eor r12,r0,r8,ror#19 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vrev32.8 q2,q2 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vadd.i32 q8,q8,q2 + ldr r2,[sp,#36] + and r3,r3,r12 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + add r10,r10,r2 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + add r11,r11,r3 + and r2,r2,r7 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + add r10,r10,r2 + ldr r2,[sp,#40] + and r12,r12,r3 + add r6,r6,r10 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + add r9,r9,r2 + eor r2,r7,r8 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + ldr r2,[sp,#44] + and r3,r3,r12 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + add r8,r8,r2 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + add r9,r9,r3 + and r2,r2,r5 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#48] + and r12,r12,r3 + add r4,r4,r8 + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vst1.32 {q8},[r1,:128]! + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + add r8,r8,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r4 + eor r12,r0,r4,ror#19 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vrev32.8 q3,q3 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vadd.i32 q8,q8,q3 + ldr r2,[sp,#52] + and r3,r3,r12 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + add r6,r6,r2 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + add r7,r7,r3 + and r2,r2,r11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + add r6,r6,r2 + ldr r2,[sp,#56] + and r12,r12,r3 + add r10,r10,r6 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + add r5,r5,r2 + eor r2,r11,r4 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + ldr r2,[sp,#60] + and r3,r3,r12 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + add r4,r4,r2 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + add r5,r5,r3 + and r2,r2,r9 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#64] + and r12,r12,r3 + add r8,r8,r4 + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vst1.32 {q8},[r1,:128]! + ldr r0,[r2,#0] + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldr r12,[r2,#4] + ldr r3,[r2,#8] + ldr r1,[r2,#12] + add r4,r4,r0 @ accumulate + ldr r0,[r2,#16] + add r5,r5,r12 + ldr r12,[r2,#20] + add r6,r6,r3 + ldr r3,[r2,#24] + add r7,r7,r1 + ldr r1,[r2,#28] + add r8,r8,r0 + str r4,[r2],#4 + add r9,r9,r12 + str r5,[r2],#4 + add r10,r10,r3 + str r6,[r2],#4 + add r11,r11,r1 + str r7,[r2],#4 + stmia r2,{r8,r9,r10,r11} + + ittte ne + movne r1,sp + ldrne r2,[sp,#0] + eorne r12,r12,r12 + ldreq sp,[sp,#76] @ restore original sp + itt ne + eorne r3,r5,r6 + bne L_00_48 + + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} + +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + +# if defined(__thumb2__) +# define INST(a,b,c,d) .byte c,d|0xc,a,b +# else +# define INST(a,b,c,d) .byte a,b,c,d +# endif + +#ifdef __thumb2__ +.thumb_func sha256_block_data_order_armv8 +#endif +.align 5 +sha256_block_data_order_armv8: +LARMv8: + vld1.32 {q0,q1},[r0] + sub r3,r3,#256+32 + add r2,r1,r2,lsl#6 @ len to point at the end of inp + b Loop_v8 + +.align 4 +Loop_v8: + vld1.8 {q8,q9},[r1]! + vld1.8 {q10,q11},[r1]! + vld1.32 {q12},[r3]! + vrev32.8 q8,q8 + vrev32.8 q9,q9 + vrev32.8 q10,q10 + vrev32.8 q11,q11 + vmov q14,q0 @ offload + vmov q15,q1 + teq r1,r2 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + + vld1.32 {q13},[r3] + vadd.i32 q12,q12,q10 + sub r3,r3,#256-16 @ rewind + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + + vadd.i32 q13,q13,q11 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + + vadd.i32 q0,q0,q14 + vadd.i32 q1,q1,q15 + it ne + bne Loop_v8 + + vst1.32 {q0,q1},[r0] + + bx lr @ bx lr + +#endif +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.comm _OPENSSL_armcap_P,4 +.non_lazy_symbol_pointer +OPENSSL_armcap_P: +.indirect_symbol _OPENSSL_armcap_P +.long 0 +.private_extern _OPENSSL_armcap_P +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S new file mode 100644 index 00000000..f132da91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S @@ -0,0 +1,2846 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Permission to use under GPL terms is granted. +@ ==================================================================== + +@ SHA256 block procedure for ARMv4. May 2007. + +@ Performance is ~2x better than gcc 3.4 generated code and in "abso- +@ lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per +@ byte [on single-issue Xscale PXA250 core]. + +@ July 2010. +@ +@ Rescheduling for dual-issue pipeline resulted in 22% improvement on +@ Cortex A8 core and ~20 cycles per processed byte. + +@ February 2011. +@ +@ Profiler-assisted and platform-specific optimization resulted in 16% +@ improvement on Cortex A8 core and ~15.4 cycles per processed byte. + +@ September 2013. +@ +@ Add NEON implementation. On Cortex A8 it was measured to process one +@ byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon +@ S4 does it in 12.5 cycles too, but it's 50% faster than integer-only +@ code (meaning that latter performs sub-optimally, nothing was done +@ about it). + +@ May 2014. +@ +@ Add ARMv8 code path performing at 2.0 cpb on Apple A7. + +#ifndef __KERNEL__ +# include +#else +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +#endif + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors. It does have ARMv8-only code, but those +@ instructions are manually-encoded. (See unsha256.) +.arch armv7-a + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +#else +.code 32 +#endif + +.type K256,%object +.align 5 +K256: +.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size K256,.-K256 +.word 0 @ terminator +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.Lsha256_block_data_order +#endif +.align 5 + +.globl sha256_block_data_order +.hidden sha256_block_data_order +.type sha256_block_data_order,%function +sha256_block_data_order: +.Lsha256_block_data_order: +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r3,pc,#8 @ sha256_block_data_order +#else + adr r3,.Lsha256_block_data_order +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + ldr r12,.LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV8_SHA256 + bne .LARMv8 + tst r12,#ARMV7_NEON + bne .LNEON +#endif + add r2,r1,r2,lsl#6 @ len to point at the end of inp + stmdb sp!,{r0,r1,r2,r4-r11,lr} + ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} + sub r14,r3,#256+32 @ K256 + sub sp,sp,#16*4 @ alloca(X[16]) +.Loop: +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ magic + eor r12,r12,r12 +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 0 +# if 0==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r8,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 0 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 0==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r8,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#0*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 0==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 0<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#2*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#15*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 1 +# if 1==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r7,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 1 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 1==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r7,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#1*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 1==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 1<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#3*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#0*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 2 +# if 2==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r6,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 2 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 2==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r6,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#2*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 2==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 2<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#4*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#1*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 3 +# if 3==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r5,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 3 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 3==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r5,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#3*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 3==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 3<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#5*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#2*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 4 +# if 4==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r4,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 4 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 4==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r4,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#4*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 4==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 4<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#6*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#3*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 5 +# if 5==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r11,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 5==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r11,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#5*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 5==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 5<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#7*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#4*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 6 +# if 6==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r10,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 6 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 6==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r10,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#6*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 6==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 6<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#8*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#5*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 7 +# if 7==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r9,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 7==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r9,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#7*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 7==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 7<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#9*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#6*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 8 +# if 8==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r8,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 8 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 8==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r8,r8,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r8,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#8*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 8==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 8<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#10*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#7*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 9 +# if 9==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r7,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 9 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 9==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r7,r7,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r7,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#9*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 9==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 9<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#11*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#8*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 10 +# if 10==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r6,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 10 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 10==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r6,r6,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r6,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#10*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 10==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 10<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#12*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#9*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 11 +# if 11==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r5,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 11 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 11==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r5,r5,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r5,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#11*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 11==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 11<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#13*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#10*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 12 +# if 12==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r4,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 12 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 12==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r4,r4,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r4,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#12*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 12==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 12<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#14*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#11*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 13 +# if 13==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r11,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 13 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 13==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r11,r11,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r11,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#13*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 13==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 13<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#15*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#12*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 14 +# if 14==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + eor r0,r0,r10,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 14 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + ldrb r12,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r12,lsl#8 + ldrb r12,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 14==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r10,r10,ror#5 + orr r2,r2,r12,lsl#24 + eor r0,r0,r10,ror#19 @ Sigma1(e) +#endif + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#14*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 14==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 14<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#0*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#13*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + @ ldr r2,[r1],#4 @ 15 +# if 15==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + eor r0,r0,r9,ror#19 @ Sigma1(e) +# ifndef __ARMEB__ + rev r2,r2 +# endif +#else + @ ldrb r2,[r1,#3] @ 15 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + ldrb r3,[r1,#2] + ldrb r0,[r1,#1] + orr r2,r2,r3,lsl#8 + ldrb r3,[r1],#4 + orr r2,r2,r0,lsl#16 +# if 15==15 + str r1,[sp,#17*4] @ make room for r1 +# endif + eor r0,r9,r9,ror#5 + orr r2,r2,r3,lsl#24 + eor r0,r0,r9,ror#19 @ Sigma1(e) +#endif + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#15*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 15==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 15<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#1*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#14*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +.Lrounds_16_xx: + @ ldr r2,[sp,#1*4] @ 16 + @ ldr r1,[sp,#14*4] + mov r0,r2,ror#7 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#0*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#9*4] + + add r12,r12,r0 + eor r0,r8,r8,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r8,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#0*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 16==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 16<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#2*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#15*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#2*4] @ 17 + @ ldr r1,[sp,#15*4] + mov r0,r2,ror#7 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#1*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#10*4] + + add r3,r3,r0 + eor r0,r7,r7,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r7,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#1*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 17==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 17<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#3*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#0*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#3*4] @ 18 + @ ldr r1,[sp,#0*4] + mov r0,r2,ror#7 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#2*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#11*4] + + add r12,r12,r0 + eor r0,r6,r6,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r6,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#2*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 18==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 18<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#4*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#1*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#4*4] @ 19 + @ ldr r1,[sp,#1*4] + mov r0,r2,ror#7 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#3*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#12*4] + + add r3,r3,r0 + eor r0,r5,r5,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r5,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#3*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 19==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 19<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#5*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#2*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#5*4] @ 20 + @ ldr r1,[sp,#2*4] + mov r0,r2,ror#7 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#4*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#13*4] + + add r12,r12,r0 + eor r0,r4,r4,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r4,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#4*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 20==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 20<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#6*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#3*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#6*4] @ 21 + @ ldr r1,[sp,#3*4] + mov r0,r2,ror#7 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#5*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#14*4] + + add r3,r3,r0 + eor r0,r11,r11,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r11,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#5*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 21==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 21<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#7*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#4*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#7*4] @ 22 + @ ldr r1,[sp,#4*4] + mov r0,r2,ror#7 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#6*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#15*4] + + add r12,r12,r0 + eor r0,r10,r10,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r10,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#6*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 22==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 22<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#8*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#5*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#8*4] @ 23 + @ ldr r1,[sp,#5*4] + mov r0,r2,ror#7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#7*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#0*4] + + add r3,r3,r0 + eor r0,r9,r9,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r9,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#7*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 23==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 23<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#9*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#6*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#9*4] @ 24 + @ ldr r1,[sp,#6*4] + mov r0,r2,ror#7 + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#8*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#1*4] + + add r12,r12,r0 + eor r0,r8,r8,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r8,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r11,r11,r2 @ h+=X[i] + str r2,[sp,#8*4] + eor r2,r9,r10 + add r11,r11,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r8 + add r11,r11,r12 @ h+=K256[i] + eor r2,r2,r10 @ Ch(e,f,g) + eor r0,r4,r4,ror#11 + add r11,r11,r2 @ h+=Ch(e,f,g) +#if 24==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 24<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r4,r5 @ a^b, b^c in next round +#else + ldr r2,[sp,#10*4] @ from future BODY_16_xx + eor r12,r4,r5 @ a^b, b^c in next round + ldr r1,[sp,#7*4] @ from future BODY_16_xx +#endif + eor r0,r0,r4,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r7,r7,r11 @ d+=h + eor r3,r3,r5 @ Maj(a,b,c) + add r11,r11,r0,ror#2 @ h+=Sigma0(a) + @ add r11,r11,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#10*4] @ 25 + @ ldr r1,[sp,#7*4] + mov r0,r2,ror#7 + add r11,r11,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#9*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#2*4] + + add r3,r3,r0 + eor r0,r7,r7,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r7,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r10,r10,r2 @ h+=X[i] + str r2,[sp,#9*4] + eor r2,r8,r9 + add r10,r10,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r7 + add r10,r10,r3 @ h+=K256[i] + eor r2,r2,r9 @ Ch(e,f,g) + eor r0,r11,r11,ror#11 + add r10,r10,r2 @ h+=Ch(e,f,g) +#if 25==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 25<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r11,r4 @ a^b, b^c in next round +#else + ldr r2,[sp,#11*4] @ from future BODY_16_xx + eor r3,r11,r4 @ a^b, b^c in next round + ldr r1,[sp,#8*4] @ from future BODY_16_xx +#endif + eor r0,r0,r11,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r6,r6,r10 @ d+=h + eor r12,r12,r4 @ Maj(a,b,c) + add r10,r10,r0,ror#2 @ h+=Sigma0(a) + @ add r10,r10,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#11*4] @ 26 + @ ldr r1,[sp,#8*4] + mov r0,r2,ror#7 + add r10,r10,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#10*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#3*4] + + add r12,r12,r0 + eor r0,r6,r6,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r6,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r9,r9,r2 @ h+=X[i] + str r2,[sp,#10*4] + eor r2,r7,r8 + add r9,r9,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r6 + add r9,r9,r12 @ h+=K256[i] + eor r2,r2,r8 @ Ch(e,f,g) + eor r0,r10,r10,ror#11 + add r9,r9,r2 @ h+=Ch(e,f,g) +#if 26==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 26<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r10,r11 @ a^b, b^c in next round +#else + ldr r2,[sp,#12*4] @ from future BODY_16_xx + eor r12,r10,r11 @ a^b, b^c in next round + ldr r1,[sp,#9*4] @ from future BODY_16_xx +#endif + eor r0,r0,r10,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r5,r5,r9 @ d+=h + eor r3,r3,r11 @ Maj(a,b,c) + add r9,r9,r0,ror#2 @ h+=Sigma0(a) + @ add r9,r9,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#12*4] @ 27 + @ ldr r1,[sp,#9*4] + mov r0,r2,ror#7 + add r9,r9,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#11*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#4*4] + + add r3,r3,r0 + eor r0,r5,r5,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r5,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r8,r8,r2 @ h+=X[i] + str r2,[sp,#11*4] + eor r2,r6,r7 + add r8,r8,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r5 + add r8,r8,r3 @ h+=K256[i] + eor r2,r2,r7 @ Ch(e,f,g) + eor r0,r9,r9,ror#11 + add r8,r8,r2 @ h+=Ch(e,f,g) +#if 27==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 27<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r9,r10 @ a^b, b^c in next round +#else + ldr r2,[sp,#13*4] @ from future BODY_16_xx + eor r3,r9,r10 @ a^b, b^c in next round + ldr r1,[sp,#10*4] @ from future BODY_16_xx +#endif + eor r0,r0,r9,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r4,r4,r8 @ d+=h + eor r12,r12,r10 @ Maj(a,b,c) + add r8,r8,r0,ror#2 @ h+=Sigma0(a) + @ add r8,r8,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#13*4] @ 28 + @ ldr r1,[sp,#10*4] + mov r0,r2,ror#7 + add r8,r8,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#12*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#5*4] + + add r12,r12,r0 + eor r0,r4,r4,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r4,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r7,r7,r2 @ h+=X[i] + str r2,[sp,#12*4] + eor r2,r5,r6 + add r7,r7,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r4 + add r7,r7,r12 @ h+=K256[i] + eor r2,r2,r6 @ Ch(e,f,g) + eor r0,r8,r8,ror#11 + add r7,r7,r2 @ h+=Ch(e,f,g) +#if 28==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 28<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r8,r9 @ a^b, b^c in next round +#else + ldr r2,[sp,#14*4] @ from future BODY_16_xx + eor r12,r8,r9 @ a^b, b^c in next round + ldr r1,[sp,#11*4] @ from future BODY_16_xx +#endif + eor r0,r0,r8,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r11,r11,r7 @ d+=h + eor r3,r3,r9 @ Maj(a,b,c) + add r7,r7,r0,ror#2 @ h+=Sigma0(a) + @ add r7,r7,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#14*4] @ 29 + @ ldr r1,[sp,#11*4] + mov r0,r2,ror#7 + add r7,r7,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#13*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#6*4] + + add r3,r3,r0 + eor r0,r11,r11,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r11,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r6,r6,r2 @ h+=X[i] + str r2,[sp,#13*4] + eor r2,r4,r5 + add r6,r6,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r11 + add r6,r6,r3 @ h+=K256[i] + eor r2,r2,r5 @ Ch(e,f,g) + eor r0,r7,r7,ror#11 + add r6,r6,r2 @ h+=Ch(e,f,g) +#if 29==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 29<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r7,r8 @ a^b, b^c in next round +#else + ldr r2,[sp,#15*4] @ from future BODY_16_xx + eor r3,r7,r8 @ a^b, b^c in next round + ldr r1,[sp,#12*4] @ from future BODY_16_xx +#endif + eor r0,r0,r7,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r10,r10,r6 @ d+=h + eor r12,r12,r8 @ Maj(a,b,c) + add r6,r6,r0,ror#2 @ h+=Sigma0(a) + @ add r6,r6,r12 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#15*4] @ 30 + @ ldr r1,[sp,#12*4] + mov r0,r2,ror#7 + add r6,r6,r12 @ h+=Maj(a,b,c) from the past + mov r12,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r12,r12,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#14*4] + eor r12,r12,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#7*4] + + add r12,r12,r0 + eor r0,r10,r10,ror#5 @ from BODY_00_15 + add r2,r2,r12 + eor r0,r0,r10,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r12,[r14],#4 @ *K256++ + add r5,r5,r2 @ h+=X[i] + str r2,[sp,#14*4] + eor r2,r11,r4 + add r5,r5,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r10 + add r5,r5,r12 @ h+=K256[i] + eor r2,r2,r4 @ Ch(e,f,g) + eor r0,r6,r6,ror#11 + add r5,r5,r2 @ h+=Ch(e,f,g) +#if 30==31 + and r12,r12,#0xff + cmp r12,#0xf2 @ done? +#endif +#if 30<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r12,r6,r7 @ a^b, b^c in next round +#else + ldr r2,[sp,#0*4] @ from future BODY_16_xx + eor r12,r6,r7 @ a^b, b^c in next round + ldr r1,[sp,#13*4] @ from future BODY_16_xx +#endif + eor r0,r0,r6,ror#20 @ Sigma0(a) + and r3,r3,r12 @ (b^c)&=(a^b) + add r9,r9,r5 @ d+=h + eor r3,r3,r7 @ Maj(a,b,c) + add r5,r5,r0,ror#2 @ h+=Sigma0(a) + @ add r5,r5,r3 @ h+=Maj(a,b,c) + @ ldr r2,[sp,#0*4] @ 31 + @ ldr r1,[sp,#13*4] + mov r0,r2,ror#7 + add r5,r5,r3 @ h+=Maj(a,b,c) from the past + mov r3,r1,ror#17 + eor r0,r0,r2,ror#18 + eor r3,r3,r1,ror#19 + eor r0,r0,r2,lsr#3 @ sigma0(X[i+1]) + ldr r2,[sp,#15*4] + eor r3,r3,r1,lsr#10 @ sigma1(X[i+14]) + ldr r1,[sp,#8*4] + + add r3,r3,r0 + eor r0,r9,r9,ror#5 @ from BODY_00_15 + add r2,r2,r3 + eor r0,r0,r9,ror#19 @ Sigma1(e) + add r2,r2,r1 @ X[i] + ldr r3,[r14],#4 @ *K256++ + add r4,r4,r2 @ h+=X[i] + str r2,[sp,#15*4] + eor r2,r10,r11 + add r4,r4,r0,ror#6 @ h+=Sigma1(e) + and r2,r2,r9 + add r4,r4,r3 @ h+=K256[i] + eor r2,r2,r11 @ Ch(e,f,g) + eor r0,r5,r5,ror#11 + add r4,r4,r2 @ h+=Ch(e,f,g) +#if 31==31 + and r3,r3,#0xff + cmp r3,#0xf2 @ done? +#endif +#if 31<15 +# if __ARM_ARCH__>=7 + ldr r2,[r1],#4 @ prefetch +# else + ldrb r2,[r1,#3] +# endif + eor r3,r5,r6 @ a^b, b^c in next round +#else + ldr r2,[sp,#1*4] @ from future BODY_16_xx + eor r3,r5,r6 @ a^b, b^c in next round + ldr r1,[sp,#14*4] @ from future BODY_16_xx +#endif + eor r0,r0,r5,ror#20 @ Sigma0(a) + and r12,r12,r3 @ (b^c)&=(a^b) + add r8,r8,r4 @ d+=h + eor r12,r12,r6 @ Maj(a,b,c) + add r4,r4,r0,ror#2 @ h+=Sigma0(a) + @ add r4,r4,r12 @ h+=Maj(a,b,c) +#if __ARM_ARCH__>=7 + ite eq @ Thumb2 thing, sanity check in ARM +#endif + ldreq r3,[sp,#16*4] @ pull ctx + bne .Lrounds_16_xx + + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldr r0,[r3,#0] + ldr r2,[r3,#4] + ldr r12,[r3,#8] + add r4,r4,r0 + ldr r0,[r3,#12] + add r5,r5,r2 + ldr r2,[r3,#16] + add r6,r6,r12 + ldr r12,[r3,#20] + add r7,r7,r0 + ldr r0,[r3,#24] + add r8,r8,r2 + ldr r2,[r3,#28] + add r9,r9,r12 + ldr r1,[sp,#17*4] @ pull inp + ldr r12,[sp,#18*4] @ pull inp+len + add r10,r10,r0 + add r11,r11,r2 + stmia r3,{r4,r5,r6,r7,r8,r9,r10,r11} + cmp r1,r12 + sub r14,r14,#256 @ rewind Ktbl + bne .Loop + + add sp,sp,#19*4 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size sha256_block_data_order,.-sha256_block_data_order +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.globl sha256_block_data_order_neon +.hidden sha256_block_data_order_neon +.type sha256_block_data_order_neon,%function +.align 5 +.skip 16 +sha256_block_data_order_neon: +.LNEON: + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + + sub r11,sp,#16*4+16 + adr r14,K256 + bic r11,r11,#15 @ align for 128-bit stores + mov r12,sp + mov sp,r11 @ alloca + add r2,r1,r2,lsl#6 @ len to point at the end of inp + + vld1.8 {q0},[r1]! + vld1.8 {q1},[r1]! + vld1.8 {q2},[r1]! + vld1.8 {q3},[r1]! + vld1.32 {q8},[r14,:128]! + vld1.32 {q9},[r14,:128]! + vld1.32 {q10},[r14,:128]! + vld1.32 {q11},[r14,:128]! + vrev32.8 q0,q0 @ yes, even on + str r0,[sp,#64] + vrev32.8 q1,q1 @ big-endian + str r1,[sp,#68] + mov r1,sp + vrev32.8 q2,q2 + str r2,[sp,#72] + vrev32.8 q3,q3 + str r12,[sp,#76] @ save original sp + vadd.i32 q8,q8,q0 + vadd.i32 q9,q9,q1 + vst1.32 {q8},[r1,:128]! + vadd.i32 q10,q10,q2 + vst1.32 {q9},[r1,:128]! + vadd.i32 q11,q11,q3 + vst1.32 {q10},[r1,:128]! + vst1.32 {q11},[r1,:128]! + + ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} + sub r1,r1,#64 + ldr r2,[sp,#0] + eor r12,r12,r12 + eor r3,r5,r6 + b .L_00_48 + +.align 4 +.L_00_48: + vext.8 q8,q0,q1,#4 + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + vext.8 q9,q2,q3,#4 + add r4,r4,r12 + and r2,r2,r8 + eor r12,r0,r8,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vadd.i32 q0,q0,q9 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + vshr.u32 q9,q8,#3 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#4] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + veor q9,q9,q10 + add r10,r10,r2 + vsli.32 q11,q8,#14 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + vshr.u32 d24,d7,#17 + add r11,r11,r3 + and r2,r2,r7 + veor q9,q9,q11 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + vsli.32 d24,d7,#15 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + vshr.u32 d25,d7,#10 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + vadd.i32 q0,q0,q9 + add r10,r10,r2 + ldr r2,[sp,#8] + veor d25,d25,d24 + and r12,r12,r3 + add r6,r6,r10 + vshr.u32 d24,d7,#19 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + vsli.32 d24,d7,#13 + add r9,r9,r2 + eor r2,r7,r8 + veor d25,d25,d24 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + vadd.i32 d0,d0,d25 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + vshr.u32 d24,d0,#17 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + vsli.32 d24,d0,#15 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + vshr.u32 d25,d0,#10 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + veor d25,d25,d24 + ldr r2,[sp,#12] + and r3,r3,r12 + vshr.u32 d24,d0,#19 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + vld1.32 {q8},[r14,:128]! + add r8,r8,r2 + vsli.32 d24,d0,#13 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + veor d25,d25,d24 + add r9,r9,r3 + and r2,r2,r5 + vadd.i32 d1,d1,d25 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + vadd.i32 q8,q8,q0 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#16] + and r12,r12,r3 + add r4,r4,r8 + vst1.32 {q8},[r1,:128]! + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vext.8 q8,q1,q2,#4 + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + vext.8 q9,q3,q0,#4 + add r8,r8,r12 + and r2,r2,r4 + eor r12,r0,r4,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vadd.i32 q1,q1,q9 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + vshr.u32 q9,q8,#3 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#20] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + veor q9,q9,q10 + add r6,r6,r2 + vsli.32 q11,q8,#14 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + vshr.u32 d24,d1,#17 + add r7,r7,r3 + and r2,r2,r11 + veor q9,q9,q11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + vsli.32 d24,d1,#15 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + vshr.u32 d25,d1,#10 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + vadd.i32 q1,q1,q9 + add r6,r6,r2 + ldr r2,[sp,#24] + veor d25,d25,d24 + and r12,r12,r3 + add r10,r10,r6 + vshr.u32 d24,d1,#19 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + vsli.32 d24,d1,#13 + add r5,r5,r2 + eor r2,r11,r4 + veor d25,d25,d24 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + vadd.i32 d2,d2,d25 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + vshr.u32 d24,d2,#17 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + vsli.32 d24,d2,#15 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + vshr.u32 d25,d2,#10 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + veor d25,d25,d24 + ldr r2,[sp,#28] + and r3,r3,r12 + vshr.u32 d24,d2,#19 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + vld1.32 {q8},[r14,:128]! + add r4,r4,r2 + vsli.32 d24,d2,#13 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + veor d25,d25,d24 + add r5,r5,r3 + and r2,r2,r9 + vadd.i32 d3,d3,d25 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + vadd.i32 q8,q8,q1 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#32] + and r12,r12,r3 + add r8,r8,r4 + vst1.32 {q8},[r1,:128]! + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vext.8 q8,q2,q3,#4 + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + vext.8 q9,q0,q1,#4 + add r4,r4,r12 + and r2,r2,r8 + eor r12,r0,r8,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vadd.i32 q2,q2,q9 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + vshr.u32 q9,q8,#3 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#36] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + veor q9,q9,q10 + add r10,r10,r2 + vsli.32 q11,q8,#14 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + vshr.u32 d24,d3,#17 + add r11,r11,r3 + and r2,r2,r7 + veor q9,q9,q11 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + vsli.32 d24,d3,#15 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + vshr.u32 d25,d3,#10 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + vadd.i32 q2,q2,q9 + add r10,r10,r2 + ldr r2,[sp,#40] + veor d25,d25,d24 + and r12,r12,r3 + add r6,r6,r10 + vshr.u32 d24,d3,#19 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + vsli.32 d24,d3,#13 + add r9,r9,r2 + eor r2,r7,r8 + veor d25,d25,d24 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + vadd.i32 d4,d4,d25 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + vshr.u32 d24,d4,#17 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + vsli.32 d24,d4,#15 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + vshr.u32 d25,d4,#10 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + veor d25,d25,d24 + ldr r2,[sp,#44] + and r3,r3,r12 + vshr.u32 d24,d4,#19 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + vld1.32 {q8},[r14,:128]! + add r8,r8,r2 + vsli.32 d24,d4,#13 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + veor d25,d25,d24 + add r9,r9,r3 + and r2,r2,r5 + vadd.i32 d5,d5,d25 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + vadd.i32 q8,q8,q2 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#48] + and r12,r12,r3 + add r4,r4,r8 + vst1.32 {q8},[r1,:128]! + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vext.8 q8,q3,q0,#4 + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + vext.8 q9,q1,q2,#4 + add r8,r8,r12 + and r2,r2,r4 + eor r12,r0,r4,ror#19 + vshr.u32 q10,q8,#7 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vadd.i32 q3,q3,q9 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + vshr.u32 q9,q8,#3 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vsli.32 q10,q8,#25 + ldr r2,[sp,#52] + and r3,r3,r12 + vshr.u32 q11,q8,#18 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + veor q9,q9,q10 + add r6,r6,r2 + vsli.32 q11,q8,#14 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + vshr.u32 d24,d5,#17 + add r7,r7,r3 + and r2,r2,r11 + veor q9,q9,q11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + vsli.32 d24,d5,#15 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + vshr.u32 d25,d5,#10 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + vadd.i32 q3,q3,q9 + add r6,r6,r2 + ldr r2,[sp,#56] + veor d25,d25,d24 + and r12,r12,r3 + add r10,r10,r6 + vshr.u32 d24,d5,#19 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + vsli.32 d24,d5,#13 + add r5,r5,r2 + eor r2,r11,r4 + veor d25,d25,d24 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + vadd.i32 d6,d6,d25 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + vshr.u32 d24,d6,#17 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + vsli.32 d24,d6,#15 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + vshr.u32 d25,d6,#10 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + veor d25,d25,d24 + ldr r2,[sp,#60] + and r3,r3,r12 + vshr.u32 d24,d6,#19 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + vld1.32 {q8},[r14,:128]! + add r4,r4,r2 + vsli.32 d24,d6,#13 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + veor d25,d25,d24 + add r5,r5,r3 + and r2,r2,r9 + vadd.i32 d7,d7,d25 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + vadd.i32 q8,q8,q3 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[r14] + and r12,r12,r3 + add r8,r8,r4 + vst1.32 {q8},[r1,:128]! + add r4,r4,r0,ror#2 + eor r12,r12,r6 + teq r2,#0 @ check for K256 terminator + ldr r2,[sp,#0] + sub r1,r1,#64 + bne .L_00_48 + + ldr r1,[sp,#68] + ldr r0,[sp,#72] + sub r14,r14,#256 @ rewind r14 + teq r1,r0 + it eq + subeq r1,r1,#64 @ avoid SEGV + vld1.8 {q0},[r1]! @ load next input block + vld1.8 {q1},[r1]! + vld1.8 {q2},[r1]! + vld1.8 {q3},[r1]! + it ne + strne r1,[sp,#68] + mov r1,sp + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + add r4,r4,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r8 + eor r12,r0,r8,ror#19 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vrev32.8 q0,q0 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vadd.i32 q8,q8,q0 + ldr r2,[sp,#4] + and r3,r3,r12 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + add r10,r10,r2 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + add r11,r11,r3 + and r2,r2,r7 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + add r10,r10,r2 + ldr r2,[sp,#8] + and r12,r12,r3 + add r6,r6,r10 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + add r9,r9,r2 + eor r2,r7,r8 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + ldr r2,[sp,#12] + and r3,r3,r12 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + add r8,r8,r2 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + add r9,r9,r3 + and r2,r2,r5 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#16] + and r12,r12,r3 + add r4,r4,r8 + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vst1.32 {q8},[r1,:128]! + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + add r8,r8,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r4 + eor r12,r0,r4,ror#19 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vrev32.8 q1,q1 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vadd.i32 q8,q8,q1 + ldr r2,[sp,#20] + and r3,r3,r12 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + add r6,r6,r2 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + add r7,r7,r3 + and r2,r2,r11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + add r6,r6,r2 + ldr r2,[sp,#24] + and r12,r12,r3 + add r10,r10,r6 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + add r5,r5,r2 + eor r2,r11,r4 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + ldr r2,[sp,#28] + and r3,r3,r12 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + add r4,r4,r2 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + add r5,r5,r3 + and r2,r2,r9 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#32] + and r12,r12,r3 + add r8,r8,r4 + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vst1.32 {q8},[r1,:128]! + add r11,r11,r2 + eor r2,r9,r10 + eor r0,r8,r8,ror#5 + add r4,r4,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r8 + eor r12,r0,r8,ror#19 + eor r0,r4,r4,ror#11 + eor r2,r2,r10 + vrev32.8 q2,q2 + add r11,r11,r12,ror#6 + eor r12,r4,r5 + eor r0,r0,r4,ror#20 + add r11,r11,r2 + vadd.i32 q8,q8,q2 + ldr r2,[sp,#36] + and r3,r3,r12 + add r7,r7,r11 + add r11,r11,r0,ror#2 + eor r3,r3,r5 + add r10,r10,r2 + eor r2,r8,r9 + eor r0,r7,r7,ror#5 + add r11,r11,r3 + and r2,r2,r7 + eor r3,r0,r7,ror#19 + eor r0,r11,r11,ror#11 + eor r2,r2,r9 + add r10,r10,r3,ror#6 + eor r3,r11,r4 + eor r0,r0,r11,ror#20 + add r10,r10,r2 + ldr r2,[sp,#40] + and r12,r12,r3 + add r6,r6,r10 + add r10,r10,r0,ror#2 + eor r12,r12,r4 + add r9,r9,r2 + eor r2,r7,r8 + eor r0,r6,r6,ror#5 + add r10,r10,r12 + and r2,r2,r6 + eor r12,r0,r6,ror#19 + eor r0,r10,r10,ror#11 + eor r2,r2,r8 + add r9,r9,r12,ror#6 + eor r12,r10,r11 + eor r0,r0,r10,ror#20 + add r9,r9,r2 + ldr r2,[sp,#44] + and r3,r3,r12 + add r5,r5,r9 + add r9,r9,r0,ror#2 + eor r3,r3,r11 + add r8,r8,r2 + eor r2,r6,r7 + eor r0,r5,r5,ror#5 + add r9,r9,r3 + and r2,r2,r5 + eor r3,r0,r5,ror#19 + eor r0,r9,r9,ror#11 + eor r2,r2,r7 + add r8,r8,r3,ror#6 + eor r3,r9,r10 + eor r0,r0,r9,ror#20 + add r8,r8,r2 + ldr r2,[sp,#48] + and r12,r12,r3 + add r4,r4,r8 + add r8,r8,r0,ror#2 + eor r12,r12,r10 + vst1.32 {q8},[r1,:128]! + add r7,r7,r2 + eor r2,r5,r6 + eor r0,r4,r4,ror#5 + add r8,r8,r12 + vld1.32 {q8},[r14,:128]! + and r2,r2,r4 + eor r12,r0,r4,ror#19 + eor r0,r8,r8,ror#11 + eor r2,r2,r6 + vrev32.8 q3,q3 + add r7,r7,r12,ror#6 + eor r12,r8,r9 + eor r0,r0,r8,ror#20 + add r7,r7,r2 + vadd.i32 q8,q8,q3 + ldr r2,[sp,#52] + and r3,r3,r12 + add r11,r11,r7 + add r7,r7,r0,ror#2 + eor r3,r3,r9 + add r6,r6,r2 + eor r2,r4,r5 + eor r0,r11,r11,ror#5 + add r7,r7,r3 + and r2,r2,r11 + eor r3,r0,r11,ror#19 + eor r0,r7,r7,ror#11 + eor r2,r2,r5 + add r6,r6,r3,ror#6 + eor r3,r7,r8 + eor r0,r0,r7,ror#20 + add r6,r6,r2 + ldr r2,[sp,#56] + and r12,r12,r3 + add r10,r10,r6 + add r6,r6,r0,ror#2 + eor r12,r12,r8 + add r5,r5,r2 + eor r2,r11,r4 + eor r0,r10,r10,ror#5 + add r6,r6,r12 + and r2,r2,r10 + eor r12,r0,r10,ror#19 + eor r0,r6,r6,ror#11 + eor r2,r2,r4 + add r5,r5,r12,ror#6 + eor r12,r6,r7 + eor r0,r0,r6,ror#20 + add r5,r5,r2 + ldr r2,[sp,#60] + and r3,r3,r12 + add r9,r9,r5 + add r5,r5,r0,ror#2 + eor r3,r3,r7 + add r4,r4,r2 + eor r2,r10,r11 + eor r0,r9,r9,ror#5 + add r5,r5,r3 + and r2,r2,r9 + eor r3,r0,r9,ror#19 + eor r0,r5,r5,ror#11 + eor r2,r2,r11 + add r4,r4,r3,ror#6 + eor r3,r5,r6 + eor r0,r0,r5,ror#20 + add r4,r4,r2 + ldr r2,[sp,#64] + and r12,r12,r3 + add r8,r8,r4 + add r4,r4,r0,ror#2 + eor r12,r12,r6 + vst1.32 {q8},[r1,:128]! + ldr r0,[r2,#0] + add r4,r4,r12 @ h+=Maj(a,b,c) from the past + ldr r12,[r2,#4] + ldr r3,[r2,#8] + ldr r1,[r2,#12] + add r4,r4,r0 @ accumulate + ldr r0,[r2,#16] + add r5,r5,r12 + ldr r12,[r2,#20] + add r6,r6,r3 + ldr r3,[r2,#24] + add r7,r7,r1 + ldr r1,[r2,#28] + add r8,r8,r0 + str r4,[r2],#4 + add r9,r9,r12 + str r5,[r2],#4 + add r10,r10,r3 + str r6,[r2],#4 + add r11,r11,r1 + str r7,[r2],#4 + stmia r2,{r8,r9,r10,r11} + + ittte ne + movne r1,sp + ldrne r2,[sp,#0] + eorne r12,r12,r12 + ldreq sp,[sp,#76] @ restore original sp + itt ne + eorne r3,r5,r6 + bne .L_00_48 + + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +.size sha256_block_data_order_neon,.-sha256_block_data_order_neon +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + +# if defined(__thumb2__) +# define INST(a,b,c,d) .byte c,d|0xc,a,b +# else +# define INST(a,b,c,d) .byte a,b,c,d +# endif + +.type sha256_block_data_order_armv8,%function +.align 5 +sha256_block_data_order_armv8: +.LARMv8: + vld1.32 {q0,q1},[r0] + sub r3,r3,#256+32 + add r2,r1,r2,lsl#6 @ len to point at the end of inp + b .Loop_v8 + +.align 4 +.Loop_v8: + vld1.8 {q8,q9},[r1]! + vld1.8 {q10,q11},[r1]! + vld1.32 {q12},[r3]! + vrev32.8 q8,q8 + vrev32.8 q9,q9 + vrev32.8 q10,q10 + vrev32.8 q11,q11 + vmov q14,q0 @ offload + vmov q15,q1 + teq r1,r2 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + INST(0xe2,0x03,0xfa,0xf3) @ sha256su0 q8,q9 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe6,0x0c,0x64,0xf3) @ sha256su1 q8,q10,q11 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + INST(0xe4,0x23,0xfa,0xf3) @ sha256su0 q9,q10 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe0,0x2c,0x66,0xf3) @ sha256su1 q9,q11,q8 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q10 + INST(0xe6,0x43,0xfa,0xf3) @ sha256su0 q10,q11 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + INST(0xe2,0x4c,0x60,0xf3) @ sha256su1 q10,q8,q9 + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q11 + INST(0xe0,0x63,0xfa,0xf3) @ sha256su0 q11,q8 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + INST(0xe4,0x6c,0x62,0xf3) @ sha256su1 q11,q9,q10 + vld1.32 {q13},[r3]! + vadd.i32 q12,q12,q8 + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + + vld1.32 {q12},[r3]! + vadd.i32 q13,q13,q9 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + + vld1.32 {q13},[r3] + vadd.i32 q12,q12,q10 + sub r3,r3,#256-16 @ rewind + vmov q2,q0 + INST(0x68,0x0c,0x02,0xf3) @ sha256h q0,q1,q12 + INST(0x68,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q12 + + vadd.i32 q13,q13,q11 + vmov q2,q0 + INST(0x6a,0x0c,0x02,0xf3) @ sha256h q0,q1,q13 + INST(0x6a,0x2c,0x14,0xf3) @ sha256h2 q1,q2,q13 + + vadd.i32 q0,q0,q14 + vadd.i32 q1,q1,q15 + it ne + bne .Loop_v8 + + vst1.32 {q0,q1},[r0] + + bx lr @ bx lr +.size sha256_block_data_order_armv8,.-sha256_block_data_order_armv8 +#endif +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.comm OPENSSL_armcap_P,4,4 +.hidden OPENSSL_armcap_P +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S new file mode 100644 index 00000000..b5d2d996 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S @@ -0,0 +1,1219 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the OpenSSL license (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. + +#ifndef __KERNEL__ +# include +#endif + +.text + + +.private_extern _OPENSSL_armcap_P +.globl _sha256_block_data_order +.private_extern _sha256_block_data_order + +.align 6 +_sha256_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:_OPENSSL_armcap_P +#else + adrp x16,_OPENSSL_armcap_P@PAGE +#endif + ldr w16,[x16,_OPENSSL_armcap_P@PAGEOFF] + tst w16,#ARMV8_SHA256 + b.ne Lv8_entry +#endif + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*4 + + ldp w20,w21,[x0] // load context + ldp w22,w23,[x0,#2*4] + ldp w24,w25,[x0,#4*4] + add x2,x1,x2,lsl#6 // end of input + ldp w26,w27,[x0,#6*4] + adrp x30,LK256@PAGE + add x30,x30,LK256@PAGEOFF + stp x0,x2,[x29,#96] + +Loop: + ldp w3,w4,[x1],#2*4 + ldr w19,[x30],#4 // *K++ + eor w28,w21,w22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev w3,w3 // 0 +#endif + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w6,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w3 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w4,w4 // 1 +#endif + ldp w5,w6,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w7,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w4 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w5,w5 // 2 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w8,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w5 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w6,w6 // 3 +#endif + ldp w7,w8,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w9,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w6 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w7,w7 // 4 +#endif + add w24,w24,w17 // h+=Sigma0(a) + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w10,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w7 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w10,ror#11 // Sigma1(e) + ror w10,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w10,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w8,w8 // 5 +#endif + ldp w9,w10,[x1],#2*4 + add w23,w23,w17 // h+=Sigma0(a) + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w11,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w8 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w11,ror#11 // Sigma1(e) + ror w11,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w11,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w9,w9 // 6 +#endif + add w22,w22,w17 // h+=Sigma0(a) + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w12,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w9 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w12,ror#11 // Sigma1(e) + ror w12,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w12,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w10,w10 // 7 +#endif + ldp w11,w12,[x1],#2*4 + add w21,w21,w17 // h+=Sigma0(a) + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + eor w13,w25,w25,ror#14 + and w17,w26,w25 + bic w28,w27,w25 + add w20,w20,w10 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w13,ror#11 // Sigma1(e) + ror w13,w21,#2 + add w20,w20,w17 // h+=Ch(e,f,g) + eor w17,w21,w21,ror#9 + add w20,w20,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w24,w24,w20 // d+=h + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w13,w17,ror#13 // Sigma0(a) + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w11,w11 // 8 +#endif + add w20,w20,w17 // h+=Sigma0(a) + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w14,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w11 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w14,ror#11 // Sigma1(e) + ror w14,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w14,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w12,w12 // 9 +#endif + ldp w13,w14,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w15,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w12 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w15,ror#11 // Sigma1(e) + ror w15,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w15,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w13,w13 // 10 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w0,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w13 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w0,ror#11 // Sigma1(e) + ror w0,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w0,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w14,w14 // 11 +#endif + ldp w15,w0,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w6,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w14 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w15,w15 // 12 +#endif + add w24,w24,w17 // h+=Sigma0(a) + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w7,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w15 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w0,w0 // 13 +#endif + ldp w1,w2,[x1] + add w23,w23,w17 // h+=Sigma0(a) + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w8,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w0 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w1,w1 // 14 +#endif + ldr w6,[sp,#12] + add w22,w22,w17 // h+=Sigma0(a) + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w9,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w1 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w2,w2 // 15 +#endif + ldr w7,[sp,#0] + add w21,w21,w17 // h+=Sigma0(a) + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 +Loop_16_xx: + ldr w8,[sp,#4] + str w11,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w10,w5,#7 + and w17,w25,w24 + ror w9,w2,#17 + bic w19,w26,w24 + ror w11,w20,#2 + add w27,w27,w3 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w10,w10,w5,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w11,w11,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w9,w9,w2,ror#19 + eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w11,w20,ror#22 // Sigma0(a) + eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) + add w4,w4,w13 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w4,w4,w10 + add w27,w27,w17 // h+=Sigma0(a) + add w4,w4,w9 + ldr w9,[sp,#8] + str w12,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w11,w6,#7 + and w17,w24,w23 + ror w10,w3,#17 + bic w28,w25,w23 + ror w12,w27,#2 + add w26,w26,w4 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w11,w11,w6,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w12,w12,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w10,w10,w3,ror#19 + eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w12,w27,ror#22 // Sigma0(a) + eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) + add w5,w5,w14 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w5,w5,w11 + add w26,w26,w17 // h+=Sigma0(a) + add w5,w5,w10 + ldr w10,[sp,#12] + str w13,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w12,w7,#7 + and w17,w23,w22 + ror w11,w4,#17 + bic w19,w24,w22 + ror w13,w26,#2 + add w25,w25,w5 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w12,w12,w7,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w13,w13,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w11,w11,w4,ror#19 + eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w13,w26,ror#22 // Sigma0(a) + eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) + add w6,w6,w15 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w6,w6,w12 + add w25,w25,w17 // h+=Sigma0(a) + add w6,w6,w11 + ldr w11,[sp,#0] + str w14,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w13,w8,#7 + and w17,w22,w21 + ror w12,w5,#17 + bic w28,w23,w21 + ror w14,w25,#2 + add w24,w24,w6 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w13,w13,w8,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w14,w14,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w12,w12,w5,ror#19 + eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w14,w25,ror#22 // Sigma0(a) + eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) + add w7,w7,w0 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w7,w7,w13 + add w24,w24,w17 // h+=Sigma0(a) + add w7,w7,w12 + ldr w12,[sp,#4] + str w15,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w14,w9,#7 + and w17,w21,w20 + ror w13,w6,#17 + bic w19,w22,w20 + ror w15,w24,#2 + add w23,w23,w7 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w14,w14,w9,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w15,w15,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w13,w13,w6,ror#19 + eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w15,w24,ror#22 // Sigma0(a) + eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) + add w8,w8,w1 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w8,w8,w14 + add w23,w23,w17 // h+=Sigma0(a) + add w8,w8,w13 + ldr w13,[sp,#8] + str w0,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w15,w10,#7 + and w17,w20,w27 + ror w14,w7,#17 + bic w28,w21,w27 + ror w0,w23,#2 + add w22,w22,w8 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w15,w15,w10,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w0,w0,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w14,w14,w7,ror#19 + eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w0,w23,ror#22 // Sigma0(a) + eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) + add w9,w9,w2 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w9,w9,w15 + add w22,w22,w17 // h+=Sigma0(a) + add w9,w9,w14 + ldr w14,[sp,#12] + str w1,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w0,w11,#7 + and w17,w27,w26 + ror w15,w8,#17 + bic w19,w20,w26 + ror w1,w22,#2 + add w21,w21,w9 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w0,w0,w11,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w1,w1,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w15,w15,w8,ror#19 + eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w1,w22,ror#22 // Sigma0(a) + eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) + add w10,w10,w3 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w10,w10,w0 + add w21,w21,w17 // h+=Sigma0(a) + add w10,w10,w15 + ldr w15,[sp,#0] + str w2,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w1,w12,#7 + and w17,w26,w25 + ror w0,w9,#17 + bic w28,w27,w25 + ror w2,w21,#2 + add w20,w20,w10 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w1,w1,w12,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w2,w2,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w0,w0,w9,ror#19 + eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w2,w21,ror#22 // Sigma0(a) + eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) + add w11,w11,w4 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w11,w11,w1 + add w20,w20,w17 // h+=Sigma0(a) + add w11,w11,w0 + ldr w0,[sp,#4] + str w3,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w2,w13,#7 + and w17,w25,w24 + ror w1,w10,#17 + bic w19,w26,w24 + ror w3,w20,#2 + add w27,w27,w11 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w2,w2,w13,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w3,w3,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w1,w1,w10,ror#19 + eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w3,w20,ror#22 // Sigma0(a) + eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) + add w12,w12,w5 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w12,w12,w2 + add w27,w27,w17 // h+=Sigma0(a) + add w12,w12,w1 + ldr w1,[sp,#8] + str w4,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w3,w14,#7 + and w17,w24,w23 + ror w2,w11,#17 + bic w28,w25,w23 + ror w4,w27,#2 + add w26,w26,w12 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w3,w3,w14,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w4,w4,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w2,w2,w11,ror#19 + eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w4,w27,ror#22 // Sigma0(a) + eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) + add w13,w13,w6 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w13,w13,w3 + add w26,w26,w17 // h+=Sigma0(a) + add w13,w13,w2 + ldr w2,[sp,#12] + str w5,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w4,w15,#7 + and w17,w23,w22 + ror w3,w12,#17 + bic w19,w24,w22 + ror w5,w26,#2 + add w25,w25,w13 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w4,w4,w15,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w5,w5,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w3,w3,w12,ror#19 + eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w5,w26,ror#22 // Sigma0(a) + eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) + add w14,w14,w7 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w14,w14,w4 + add w25,w25,w17 // h+=Sigma0(a) + add w14,w14,w3 + ldr w3,[sp,#0] + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w5,w0,#7 + and w17,w22,w21 + ror w4,w13,#17 + bic w28,w23,w21 + ror w6,w25,#2 + add w24,w24,w14 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w5,w5,w0,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w6,w6,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w4,w4,w13,ror#19 + eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w25,ror#22 // Sigma0(a) + eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) + add w15,w15,w8 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w15,w15,w5 + add w24,w24,w17 // h+=Sigma0(a) + add w15,w15,w4 + ldr w4,[sp,#4] + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w6,w1,#7 + and w17,w21,w20 + ror w5,w14,#17 + bic w19,w22,w20 + ror w7,w24,#2 + add w23,w23,w15 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w6,w6,w1,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w7,w7,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w5,w5,w14,ror#19 + eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w24,ror#22 // Sigma0(a) + eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) + add w0,w0,w9 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w0,w0,w6 + add w23,w23,w17 // h+=Sigma0(a) + add w0,w0,w5 + ldr w5,[sp,#8] + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w7,w2,#7 + and w17,w20,w27 + ror w6,w15,#17 + bic w28,w21,w27 + ror w8,w23,#2 + add w22,w22,w0 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w7,w7,w2,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w8,w8,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w6,w6,w15,ror#19 + eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w23,ror#22 // Sigma0(a) + eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) + add w1,w1,w10 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w1,w1,w7 + add w22,w22,w17 // h+=Sigma0(a) + add w1,w1,w6 + ldr w6,[sp,#12] + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w8,w3,#7 + and w17,w27,w26 + ror w7,w0,#17 + bic w19,w20,w26 + ror w9,w22,#2 + add w21,w21,w1 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w8,w8,w3,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w9,w9,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w7,w7,w0,ror#19 + eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w22,ror#22 // Sigma0(a) + eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) + add w2,w2,w11 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w2,w2,w8 + add w21,w21,w17 // h+=Sigma0(a) + add w2,w2,w7 + ldr w7,[sp,#0] + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 + cbnz w19,Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#260 // rewind + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#2*4] + add x1,x1,#14*4 // advance input pointer + ldp w7,w8,[x0,#4*4] + add w20,w20,w3 + ldp w9,w10,[x0,#6*4] + add w21,w21,w4 + add w22,w22,w5 + add w23,w23,w6 + stp w20,w21,[x0] + add w24,w24,w7 + add w25,w25,w8 + stp w22,w23,[x0,#2*4] + add w26,w26,w9 + add w27,w27,w10 + cmp x1,x2 + stp w24,w25,[x0,#4*4] + stp w26,w27,[x0,#6*4] + b.ne Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*4 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.section __TEXT,__const +.align 6 + +LK256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0 //terminator + +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +.text +#ifndef __KERNEL__ + +.align 6 +sha256_block_armv8: +Lv8_entry: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v0.4s,v1.4s},[x0] + adrp x3,LK256@PAGE + add x3,x3,LK256@PAGEOFF + +Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + ld1 {v16.4s},[x3],#16 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + orr v18.16b,v0.16b,v0.16b // offload + orr v19.16b,v1.16b,v1.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.long 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.long 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.long 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.long 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.long 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.long 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.long 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.long 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.long 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.long 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.long 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.long 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.long 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.long 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + ld1 {v17.4s},[x3] + add v16.4s,v16.4s,v6.4s + sub x3,x3,#64*4-16 // rewind + orr v2.16b,v0.16b,v0.16b +.long 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.long 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + add v17.4s,v17.4s,v7.4s + orr v2.16b,v0.16b,v0.16b +.long 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.long 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + add v0.4s,v0.4s,v18.4s + add v1.4s,v1.4s,v19.4s + + cbnz x2,Loop_hw + + st1 {v0.4s,v1.4s},[x0] + + ldr x29,[sp],#16 + ret + +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S new file mode 100644 index 00000000..b7255a3d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S @@ -0,0 +1,1222 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the OpenSSL license (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. + +#ifndef __KERNEL__ +# include +#endif + +.text + + +.hidden OPENSSL_armcap_P +.globl sha256_block_data_order +.hidden sha256_block_data_order +.type sha256_block_data_order,%function +.align 6 +sha256_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x16,OPENSSL_armcap_P +#endif + ldr w16,[x16,:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA256 + b.ne .Lv8_entry +#endif + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*4 + + ldp w20,w21,[x0] // load context + ldp w22,w23,[x0,#2*4] + ldp w24,w25,[x0,#4*4] + add x2,x1,x2,lsl#6 // end of input + ldp w26,w27,[x0,#6*4] + adrp x30,.LK256 + add x30,x30,:lo12:.LK256 + stp x0,x2,[x29,#96] + +.Loop: + ldp w3,w4,[x1],#2*4 + ldr w19,[x30],#4 // *K++ + eor w28,w21,w22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev w3,w3 // 0 +#endif + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w6,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w3 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w4,w4 // 1 +#endif + ldp w5,w6,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w7,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w4 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w5,w5 // 2 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w8,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w5 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w6,w6 // 3 +#endif + ldp w7,w8,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w9,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w6 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w7,w7 // 4 +#endif + add w24,w24,w17 // h+=Sigma0(a) + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w10,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w7 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w10,ror#11 // Sigma1(e) + ror w10,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w10,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w8,w8 // 5 +#endif + ldp w9,w10,[x1],#2*4 + add w23,w23,w17 // h+=Sigma0(a) + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w11,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w8 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w11,ror#11 // Sigma1(e) + ror w11,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w11,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w9,w9 // 6 +#endif + add w22,w22,w17 // h+=Sigma0(a) + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w12,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w9 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w12,ror#11 // Sigma1(e) + ror w12,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w12,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w10,w10 // 7 +#endif + ldp w11,w12,[x1],#2*4 + add w21,w21,w17 // h+=Sigma0(a) + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + eor w13,w25,w25,ror#14 + and w17,w26,w25 + bic w28,w27,w25 + add w20,w20,w10 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w13,ror#11 // Sigma1(e) + ror w13,w21,#2 + add w20,w20,w17 // h+=Ch(e,f,g) + eor w17,w21,w21,ror#9 + add w20,w20,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w24,w24,w20 // d+=h + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w13,w17,ror#13 // Sigma0(a) + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w11,w11 // 8 +#endif + add w20,w20,w17 // h+=Sigma0(a) + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w14,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w11 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w14,ror#11 // Sigma1(e) + ror w14,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w14,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w12,w12 // 9 +#endif + ldp w13,w14,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w15,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w12 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w15,ror#11 // Sigma1(e) + ror w15,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w15,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w13,w13 // 10 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w0,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w13 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w0,ror#11 // Sigma1(e) + ror w0,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w0,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w14,w14 // 11 +#endif + ldp w15,w0,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w6,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w14 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w15,w15 // 12 +#endif + add w24,w24,w17 // h+=Sigma0(a) + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w7,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w15 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w0,w0 // 13 +#endif + ldp w1,w2,[x1] + add w23,w23,w17 // h+=Sigma0(a) + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w8,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w0 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w1,w1 // 14 +#endif + ldr w6,[sp,#12] + add w22,w22,w17 // h+=Sigma0(a) + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w9,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w1 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w2,w2 // 15 +#endif + ldr w7,[sp,#0] + add w21,w21,w17 // h+=Sigma0(a) + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 +.Loop_16_xx: + ldr w8,[sp,#4] + str w11,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w10,w5,#7 + and w17,w25,w24 + ror w9,w2,#17 + bic w19,w26,w24 + ror w11,w20,#2 + add w27,w27,w3 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w10,w10,w5,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w11,w11,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w9,w9,w2,ror#19 + eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w11,w20,ror#22 // Sigma0(a) + eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) + add w4,w4,w13 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w4,w4,w10 + add w27,w27,w17 // h+=Sigma0(a) + add w4,w4,w9 + ldr w9,[sp,#8] + str w12,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w11,w6,#7 + and w17,w24,w23 + ror w10,w3,#17 + bic w28,w25,w23 + ror w12,w27,#2 + add w26,w26,w4 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w11,w11,w6,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w12,w12,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w10,w10,w3,ror#19 + eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w12,w27,ror#22 // Sigma0(a) + eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) + add w5,w5,w14 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w5,w5,w11 + add w26,w26,w17 // h+=Sigma0(a) + add w5,w5,w10 + ldr w10,[sp,#12] + str w13,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w12,w7,#7 + and w17,w23,w22 + ror w11,w4,#17 + bic w19,w24,w22 + ror w13,w26,#2 + add w25,w25,w5 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w12,w12,w7,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w13,w13,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w11,w11,w4,ror#19 + eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w13,w26,ror#22 // Sigma0(a) + eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) + add w6,w6,w15 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w6,w6,w12 + add w25,w25,w17 // h+=Sigma0(a) + add w6,w6,w11 + ldr w11,[sp,#0] + str w14,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w13,w8,#7 + and w17,w22,w21 + ror w12,w5,#17 + bic w28,w23,w21 + ror w14,w25,#2 + add w24,w24,w6 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w13,w13,w8,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w14,w14,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w12,w12,w5,ror#19 + eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w14,w25,ror#22 // Sigma0(a) + eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) + add w7,w7,w0 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w7,w7,w13 + add w24,w24,w17 // h+=Sigma0(a) + add w7,w7,w12 + ldr w12,[sp,#4] + str w15,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w14,w9,#7 + and w17,w21,w20 + ror w13,w6,#17 + bic w19,w22,w20 + ror w15,w24,#2 + add w23,w23,w7 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w14,w14,w9,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w15,w15,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w13,w13,w6,ror#19 + eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w15,w24,ror#22 // Sigma0(a) + eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) + add w8,w8,w1 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w8,w8,w14 + add w23,w23,w17 // h+=Sigma0(a) + add w8,w8,w13 + ldr w13,[sp,#8] + str w0,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w15,w10,#7 + and w17,w20,w27 + ror w14,w7,#17 + bic w28,w21,w27 + ror w0,w23,#2 + add w22,w22,w8 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w15,w15,w10,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w0,w0,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w14,w14,w7,ror#19 + eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w0,w23,ror#22 // Sigma0(a) + eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) + add w9,w9,w2 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w9,w9,w15 + add w22,w22,w17 // h+=Sigma0(a) + add w9,w9,w14 + ldr w14,[sp,#12] + str w1,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w0,w11,#7 + and w17,w27,w26 + ror w15,w8,#17 + bic w19,w20,w26 + ror w1,w22,#2 + add w21,w21,w9 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w0,w0,w11,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w1,w1,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w15,w15,w8,ror#19 + eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w1,w22,ror#22 // Sigma0(a) + eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) + add w10,w10,w3 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w10,w10,w0 + add w21,w21,w17 // h+=Sigma0(a) + add w10,w10,w15 + ldr w15,[sp,#0] + str w2,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w1,w12,#7 + and w17,w26,w25 + ror w0,w9,#17 + bic w28,w27,w25 + ror w2,w21,#2 + add w20,w20,w10 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w1,w1,w12,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w2,w2,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w0,w0,w9,ror#19 + eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w2,w21,ror#22 // Sigma0(a) + eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) + add w11,w11,w4 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w11,w11,w1 + add w20,w20,w17 // h+=Sigma0(a) + add w11,w11,w0 + ldr w0,[sp,#4] + str w3,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w2,w13,#7 + and w17,w25,w24 + ror w1,w10,#17 + bic w19,w26,w24 + ror w3,w20,#2 + add w27,w27,w11 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w2,w2,w13,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w3,w3,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w1,w1,w10,ror#19 + eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w3,w20,ror#22 // Sigma0(a) + eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) + add w12,w12,w5 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w12,w12,w2 + add w27,w27,w17 // h+=Sigma0(a) + add w12,w12,w1 + ldr w1,[sp,#8] + str w4,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w3,w14,#7 + and w17,w24,w23 + ror w2,w11,#17 + bic w28,w25,w23 + ror w4,w27,#2 + add w26,w26,w12 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w3,w3,w14,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w4,w4,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w2,w2,w11,ror#19 + eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w4,w27,ror#22 // Sigma0(a) + eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) + add w13,w13,w6 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w13,w13,w3 + add w26,w26,w17 // h+=Sigma0(a) + add w13,w13,w2 + ldr w2,[sp,#12] + str w5,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w4,w15,#7 + and w17,w23,w22 + ror w3,w12,#17 + bic w19,w24,w22 + ror w5,w26,#2 + add w25,w25,w13 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w4,w4,w15,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w5,w5,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w3,w3,w12,ror#19 + eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w5,w26,ror#22 // Sigma0(a) + eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) + add w14,w14,w7 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w14,w14,w4 + add w25,w25,w17 // h+=Sigma0(a) + add w14,w14,w3 + ldr w3,[sp,#0] + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w5,w0,#7 + and w17,w22,w21 + ror w4,w13,#17 + bic w28,w23,w21 + ror w6,w25,#2 + add w24,w24,w14 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w5,w5,w0,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w6,w6,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w4,w4,w13,ror#19 + eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w25,ror#22 // Sigma0(a) + eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) + add w15,w15,w8 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w15,w15,w5 + add w24,w24,w17 // h+=Sigma0(a) + add w15,w15,w4 + ldr w4,[sp,#4] + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w6,w1,#7 + and w17,w21,w20 + ror w5,w14,#17 + bic w19,w22,w20 + ror w7,w24,#2 + add w23,w23,w15 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w6,w6,w1,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w7,w7,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w5,w5,w14,ror#19 + eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w24,ror#22 // Sigma0(a) + eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) + add w0,w0,w9 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w0,w0,w6 + add w23,w23,w17 // h+=Sigma0(a) + add w0,w0,w5 + ldr w5,[sp,#8] + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w7,w2,#7 + and w17,w20,w27 + ror w6,w15,#17 + bic w28,w21,w27 + ror w8,w23,#2 + add w22,w22,w0 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w7,w7,w2,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w8,w8,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w6,w6,w15,ror#19 + eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w23,ror#22 // Sigma0(a) + eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) + add w1,w1,w10 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w1,w1,w7 + add w22,w22,w17 // h+=Sigma0(a) + add w1,w1,w6 + ldr w6,[sp,#12] + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w8,w3,#7 + and w17,w27,w26 + ror w7,w0,#17 + bic w19,w20,w26 + ror w9,w22,#2 + add w21,w21,w1 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w8,w8,w3,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w9,w9,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w7,w7,w0,ror#19 + eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w22,ror#22 // Sigma0(a) + eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) + add w2,w2,w11 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w2,w2,w8 + add w21,w21,w17 // h+=Sigma0(a) + add w2,w2,w7 + ldr w7,[sp,#0] + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 + cbnz w19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#260 // rewind + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#2*4] + add x1,x1,#14*4 // advance input pointer + ldp w7,w8,[x0,#4*4] + add w20,w20,w3 + ldp w9,w10,[x0,#6*4] + add w21,w21,w4 + add w22,w22,w5 + add w23,w23,w6 + stp w20,w21,[x0] + add w24,w24,w7 + add w25,w25,w8 + stp w22,w23,[x0,#2*4] + add w26,w26,w9 + add w27,w27,w10 + cmp x1,x2 + stp w24,w25,[x0,#4*4] + stp w26,w27,[x0,#6*4] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*4 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size sha256_block_data_order,.-sha256_block_data_order + +.section .rodata +.align 6 +.type .LK256,%object +.LK256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0 //terminator +.size .LK256,.-.LK256 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +.text +#ifndef __KERNEL__ +.type sha256_block_armv8,%function +.align 6 +sha256_block_armv8: +.Lv8_entry: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v0.4s,v1.4s},[x0] + adrp x3,.LK256 + add x3,x3,:lo12:.LK256 + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + ld1 {v16.4s},[x3],#16 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + orr v18.16b,v0.16b,v0.16b // offload + orr v19.16b,v1.16b,v1.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + ld1 {v17.4s},[x3] + add v16.4s,v16.4s,v6.4s + sub x3,x3,#64*4-16 // rewind + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + add v17.4s,v17.4s,v7.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + add v0.4s,v0.4s,v18.4s + add v1.4s,v1.4s,v19.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s,v1.4s},[x0] + + ldr x29,[sp],#16 + ret +.size sha256_block_armv8,.-sha256_block_armv8 +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S new file mode 100644 index 00000000..f611dd7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S @@ -0,0 +1,4191 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P +.globl sha256_block_data_order +.hidden sha256_block_data_order +.type sha256_block_data_order,@function +.align 16 +sha256_block_data_order: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $536870912,%r11d + jnz .Lshaext_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut + testl $512,%r10d + jnz .Lssse3_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp .Lloop + +.align 16 +.Lloop: + movl %ebx,%edi + leaq K256(%rip),%rbp + xorl %ecx,%edi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + addl %r14d,%eax + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 36(%rsp),%r12d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 8(%rsp),%r13d + movl 60(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 40(%rsp),%r12d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 12(%rsp),%r13d + movl 0(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 44(%rsp),%r12d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 16(%rsp),%r13d + movl 4(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 48(%rsp),%r12d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 20(%rsp),%r13d + movl 8(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 52(%rsp),%r12d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 24(%rsp),%r13d + movl 12(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 56(%rsp),%r12d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 28(%rsp),%r13d + movl 16(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 60(%rsp),%r12d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 32(%rsp),%r13d + movl 20(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 0(%rsp),%r12d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + movl 36(%rsp),%r13d + movl 24(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 4(%rsp),%r12d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 40(%rsp),%r13d + movl 28(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 8(%rsp),%r12d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 44(%rsp),%r13d + movl 32(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 12(%rsp),%r12d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 48(%rsp),%r13d + movl 36(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 16(%rsp),%r12d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 52(%rsp),%r13d + movl 40(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 20(%rsp),%r12d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 56(%rsp),%r13d + movl 44(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 24(%rsp),%r12d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 60(%rsp),%r13d + movl 48(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 28(%rsp),%r12d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 0(%rsp),%r13d + movl 52(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 32(%rsp),%r12d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + cmpb $0,3(%rbp) + jnz .Lrounds_16_xx + + movq 64+0(%rsp),%rdi + addl %r14d,%eax + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order,.-sha256_block_data_order +.align 64 +.type K256,@object +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.type sha256_block_data_order_shaext,@function +.align 64 +sha256_block_data_order_shaext: +.cfi_startproc +.Lshaext_shortcut: + leaq K256+128(%rip),%rcx + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa 512-128(%rcx),%xmm7 + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm7,%xmm8 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + movdqu (%rsi),%xmm3 + movdqu 16(%rsi),%xmm4 + movdqu 32(%rsi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%rsi),%xmm6 + + movdqa 0-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 + movdqa %xmm2,%xmm10 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + nop + movdqa %xmm1,%xmm9 +.byte 15,56,203,202 + + movdqa 32-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + leaq 64(%rsi),%rsi +.byte 15,56,204,220 +.byte 15,56,203,202 + + movdqa 64-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + + movdqa 96-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 128-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 160-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 192-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 224-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 256-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 288-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 320-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 352-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 384-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 416-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + + movdqa 448-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa %xmm8,%xmm7 +.byte 15,56,203,202 + + movdqa 480-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + decq %rdx + nop +.byte 15,56,203,202 + + paddd %xmm10,%xmm2 + paddd %xmm9,%xmm1 + jnz .Loop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm7 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + + movdqu %xmm1,(%rdi) + movdqu %xmm2,16(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_shaext,.-sha256_block_data_order_shaext +.type sha256_block_data_order_ssse3,@function +.align 64 +sha256_block_data_order_ssse3: +.cfi_startproc +.Lssse3_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue_ssse3: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + + + jmp .Lloop_ssse3 +.align 16 +.Lloop_ssse3: + movdqa K256+512(%rip),%xmm7 + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 +.byte 102,15,56,0,199 + movdqu 48(%rsi),%xmm3 + leaq K256(%rip),%rbp +.byte 102,15,56,0,207 + movdqa 0(%rbp),%xmm4 + movdqa 32(%rbp),%xmm5 +.byte 102,15,56,0,215 + paddd %xmm0,%xmm4 + movdqa 64(%rbp),%xmm6 +.byte 102,15,56,0,223 + movdqa 96(%rbp),%xmm7 + paddd %xmm1,%xmm5 + paddd %xmm2,%xmm6 + paddd %xmm3,%xmm7 + movdqa %xmm4,0(%rsp) + movl %eax,%r14d + movdqa %xmm5,16(%rsp) + movl %ebx,%edi + movdqa %xmm6,32(%rsp) + xorl %ecx,%edi + movdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lssse3_00_47 + +.align 16 +.Lssse3_00_47: + subq $-128,%rbp + rorl $14,%r13d + movdqa %xmm1,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm3,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,224,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,250,4 + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm3,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 4(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm0 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm0 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm0,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 0(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm0,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,0(%rsp) + rorl $14,%r13d + movdqa %xmm2,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm0,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,225,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,251,4 + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm0,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 20(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm1 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm1 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm1,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 32(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm1,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,16(%rsp) + rorl $14,%r13d + movdqa %xmm3,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm1,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,226,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,248,4 + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm1,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 36(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm2 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm2 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm2,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 64(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm2,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,32(%rsp) + rorl $14,%r13d + movdqa %xmm0,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm2,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,227,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,249,4 + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm2,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 52(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm3 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm3 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm3,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 96(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm3,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne .Lssse3_00_47 + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop_ssse3 + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_ssse3: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_ssse3,.-sha256_block_data_order_ssse3 +.type sha256_block_data_order_avx,@function +.align 64 +sha256_block_data_order_avx: +.cfi_startproc +.Lavx_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue_avx: + + vzeroupper + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%xmm8 + vmovdqa K256+512+64(%rip),%xmm9 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%edi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%edi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + subq $-128,%rbp + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm3,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm0,%xmm0 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpshufd $80,%xmm0,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm0,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm1,%xmm1 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpshufd $80,%xmm1,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm1,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm2,%xmm2 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpshufd $80,%xmm2,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm2,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm3,%xmm3 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpshufd $80,%xmm3,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne .Lavx_00_47 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop_avx + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_avx,.-sha256_block_data_order_avx +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S new file mode 100644 index 00000000..a6f72595 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S @@ -0,0 +1,4189 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +.globl _sha256_block_data_order +.private_extern _sha256_block_data_order + +.p2align 4 +_sha256_block_data_order: + + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $536870912,%r11d + jnz L$shaext_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je L$avx_shortcut + testl $512,%r10d + jnz L$ssse3_shortcut + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) + +L$prologue: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp L$loop + +.p2align 4 +L$loop: + movl %ebx,%edi + leaq K256(%rip),%rbp + xorl %ecx,%edi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + addl %r14d,%eax + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + jmp L$rounds_16_xx +.p2align 4 +L$rounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 36(%rsp),%r12d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 8(%rsp),%r13d + movl 60(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 40(%rsp),%r12d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 12(%rsp),%r13d + movl 0(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 44(%rsp),%r12d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 16(%rsp),%r13d + movl 4(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 48(%rsp),%r12d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 20(%rsp),%r13d + movl 8(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 52(%rsp),%r12d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 24(%rsp),%r13d + movl 12(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 56(%rsp),%r12d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 28(%rsp),%r13d + movl 16(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 60(%rsp),%r12d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 32(%rsp),%r13d + movl 20(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 0(%rsp),%r12d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + movl 36(%rsp),%r13d + movl 24(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 4(%rsp),%r12d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 40(%rsp),%r13d + movl 28(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 8(%rsp),%r12d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 44(%rsp),%r13d + movl 32(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 12(%rsp),%r12d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 48(%rsp),%r13d + movl 36(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 16(%rsp),%r12d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 52(%rsp),%r13d + movl 40(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 20(%rsp),%r12d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 56(%rsp),%r13d + movl 44(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 24(%rsp),%r12d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 60(%rsp),%r13d + movl 48(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 28(%rsp),%r12d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 0(%rsp),%r13d + movl 52(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 32(%rsp),%r12d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + cmpb $0,3(%rbp) + jnz L$rounds_16_xx + + movq 64+0(%rsp),%rdi + addl %r14d,%eax + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb L$loop + + movq 88(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue: + .byte 0xf3,0xc3 + + +.p2align 6 + +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + +.p2align 6 +sha256_block_data_order_shaext: + +L$shaext_shortcut: + leaq K256+128(%rip),%rcx + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa 512-128(%rcx),%xmm7 + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm7,%xmm8 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp L$oop_shaext + +.p2align 4 +L$oop_shaext: + movdqu (%rsi),%xmm3 + movdqu 16(%rsi),%xmm4 + movdqu 32(%rsi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%rsi),%xmm6 + + movdqa 0-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 + movdqa %xmm2,%xmm10 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + nop + movdqa %xmm1,%xmm9 +.byte 15,56,203,202 + + movdqa 32-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + leaq 64(%rsi),%rsi +.byte 15,56,204,220 +.byte 15,56,203,202 + + movdqa 64-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + + movdqa 96-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 128-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 160-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 192-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 224-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 256-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 288-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 320-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 352-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 384-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 416-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + + movdqa 448-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa %xmm8,%xmm7 +.byte 15,56,203,202 + + movdqa 480-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + decq %rdx + nop +.byte 15,56,203,202 + + paddd %xmm10,%xmm2 + paddd %xmm9,%xmm1 + jnz L$oop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm7 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + + movdqu %xmm1,(%rdi) + movdqu %xmm2,16(%rdi) + .byte 0xf3,0xc3 + + + +.p2align 6 +sha256_block_data_order_ssse3: + +L$ssse3_shortcut: + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) + +L$prologue_ssse3: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + + + jmp L$loop_ssse3 +.p2align 4 +L$loop_ssse3: + movdqa K256+512(%rip),%xmm7 + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 +.byte 102,15,56,0,199 + movdqu 48(%rsi),%xmm3 + leaq K256(%rip),%rbp +.byte 102,15,56,0,207 + movdqa 0(%rbp),%xmm4 + movdqa 32(%rbp),%xmm5 +.byte 102,15,56,0,215 + paddd %xmm0,%xmm4 + movdqa 64(%rbp),%xmm6 +.byte 102,15,56,0,223 + movdqa 96(%rbp),%xmm7 + paddd %xmm1,%xmm5 + paddd %xmm2,%xmm6 + paddd %xmm3,%xmm7 + movdqa %xmm4,0(%rsp) + movl %eax,%r14d + movdqa %xmm5,16(%rsp) + movl %ebx,%edi + movdqa %xmm6,32(%rsp) + xorl %ecx,%edi + movdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp L$ssse3_00_47 + +.p2align 4 +L$ssse3_00_47: + subq $-128,%rbp + rorl $14,%r13d + movdqa %xmm1,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm3,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,224,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,250,4 + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm3,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 4(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm0 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm0 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm0,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 0(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm0,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,0(%rsp) + rorl $14,%r13d + movdqa %xmm2,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm0,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,225,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,251,4 + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm0,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 20(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm1 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm1 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm1,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 32(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm1,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,16(%rsp) + rorl $14,%r13d + movdqa %xmm3,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm1,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,226,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,248,4 + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm1,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 36(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm2 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm2 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm2,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 64(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm2,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,32(%rsp) + rorl $14,%r13d + movdqa %xmm0,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm2,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,227,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,249,4 + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm2,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 52(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm3 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm3 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm3,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 96(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm3,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne L$ssse3_00_47 + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb L$loop_ssse3 + + movq 88(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue_ssse3: + .byte 0xf3,0xc3 + + + +.p2align 6 +sha256_block_data_order_avx: + +L$avx_shortcut: + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) + +L$prologue_avx: + + vzeroupper + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%xmm8 + vmovdqa K256+512+64(%rip),%xmm9 + jmp L$loop_avx +.p2align 4 +L$loop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%edi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%edi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp L$avx_00_47 + +.p2align 4 +L$avx_00_47: + subq $-128,%rbp + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm3,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm0,%xmm0 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpshufd $80,%xmm0,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm0,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm1,%xmm1 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpshufd $80,%xmm1,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm1,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm2,%xmm2 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpshufd $80,%xmm2,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm2,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm3,%xmm3 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpshufd $80,%xmm3,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne L$avx_00_47 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb L$loop_avx + + movq 88(%rsp),%rsi + + vzeroupper + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue_avx: + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S new file mode 100644 index 00000000..b62e0862 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S @@ -0,0 +1,2844 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl sha512_block_data_order +.hidden sha512_block_data_order +.type sha512_block_data_order,@function +.align 16 +sha512_block_data_order: +.L_sha512_block_data_order_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl %esp,%ebx + call .L000pic_point +.L000pic_point: + popl %ebp + leal .L001K512-.L000pic_point(%ebp),%ebp + subl $16,%esp + andl $-64,%esp + shll $7,%eax + addl %edi,%eax + movl %esi,(%esp) + movl %edi,4(%esp) + movl %eax,8(%esp) + movl %ebx,12(%esp) + leal OPENSSL_ia32cap_P-.L001K512(%ebp),%edx + movl (%edx),%ecx + testl $67108864,%ecx + jz .L002loop_x86 + movl 4(%edx),%edx + movq (%esi),%mm0 + andl $16777216,%ecx + movq 8(%esi),%mm1 + andl $512,%edx + movq 16(%esi),%mm2 + orl %edx,%ecx + movq 24(%esi),%mm3 + movq 32(%esi),%mm4 + movq 40(%esi),%mm5 + movq 48(%esi),%mm6 + movq 56(%esi),%mm7 + cmpl $16777728,%ecx + je .L003SSSE3 + subl $80,%esp + jmp .L004loop_sse2 +.align 16 +.L004loop_sse2: + movq %mm1,8(%esp) + movq %mm2,16(%esp) + movq %mm3,24(%esp) + movq %mm5,40(%esp) + movq %mm6,48(%esp) + pxor %mm1,%mm2 + movq %mm7,56(%esp) + movq %mm0,%mm3 + movl (%edi),%eax + movl 4(%edi),%ebx + addl $8,%edi + movl $15,%edx + bswap %eax + bswap %ebx + jmp .L00500_14_sse2 +.align 16 +.L00500_14_sse2: + movd %eax,%mm1 + movl (%edi),%eax + movd %ebx,%mm7 + movl 4(%edi),%ebx + addl $8,%edi + bswap %eax + bswap %ebx + punpckldq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm3,%mm0 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm2,%mm3 + movq %mm0,%mm2 + addl $8,%ebp + paddq %mm6,%mm3 + movq 48(%esp),%mm6 + decl %edx + jnz .L00500_14_sse2 + movd %eax,%mm1 + movd %ebx,%mm7 + punpckldq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm3,%mm0 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm2,%mm3 + movq %mm0,%mm2 + addl $8,%ebp + paddq %mm6,%mm3 + pxor %mm0,%mm0 + movl $32,%edx + jmp .L00616_79_sse2 +.align 16 +.L00616_79_sse2: + movq 88(%esp),%mm5 + movq %mm7,%mm1 + psrlq $1,%mm7 + movq %mm5,%mm6 + psrlq $6,%mm5 + psllq $56,%mm1 + paddq %mm3,%mm0 + movq %mm7,%mm3 + psrlq $6,%mm7 + pxor %mm1,%mm3 + psllq $7,%mm1 + pxor %mm7,%mm3 + psrlq $1,%mm7 + pxor %mm1,%mm3 + movq %mm5,%mm1 + psrlq $13,%mm5 + pxor %mm3,%mm7 + psllq $3,%mm6 + pxor %mm5,%mm1 + paddq 200(%esp),%mm7 + pxor %mm6,%mm1 + psrlq $42,%mm5 + paddq 128(%esp),%mm7 + pxor %mm5,%mm1 + psllq $42,%mm6 + movq 40(%esp),%mm5 + pxor %mm6,%mm1 + movq 48(%esp),%mm6 + paddq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm6,%mm2 + addl $8,%ebp + movq 88(%esp),%mm5 + movq %mm7,%mm1 + psrlq $1,%mm7 + movq %mm5,%mm6 + psrlq $6,%mm5 + psllq $56,%mm1 + paddq %mm3,%mm2 + movq %mm7,%mm3 + psrlq $6,%mm7 + pxor %mm1,%mm3 + psllq $7,%mm1 + pxor %mm7,%mm3 + psrlq $1,%mm7 + pxor %mm1,%mm3 + movq %mm5,%mm1 + psrlq $13,%mm5 + pxor %mm3,%mm7 + psllq $3,%mm6 + pxor %mm5,%mm1 + paddq 200(%esp),%mm7 + pxor %mm6,%mm1 + psrlq $42,%mm5 + paddq 128(%esp),%mm7 + pxor %mm5,%mm1 + psllq $42,%mm6 + movq 40(%esp),%mm5 + pxor %mm6,%mm1 + movq 48(%esp),%mm6 + paddq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm6,%mm0 + addl $8,%ebp + decl %edx + jnz .L00616_79_sse2 + paddq %mm3,%mm0 + movq 8(%esp),%mm1 + movq 24(%esp),%mm3 + movq 40(%esp),%mm5 + movq 48(%esp),%mm6 + movq 56(%esp),%mm7 + pxor %mm1,%mm2 + paddq (%esi),%mm0 + paddq 8(%esi),%mm1 + paddq 16(%esi),%mm2 + paddq 24(%esi),%mm3 + paddq 32(%esi),%mm4 + paddq 40(%esi),%mm5 + paddq 48(%esi),%mm6 + paddq 56(%esi),%mm7 + movl $640,%eax + movq %mm0,(%esi) + movq %mm1,8(%esi) + movq %mm2,16(%esi) + movq %mm3,24(%esi) + movq %mm4,32(%esi) + movq %mm5,40(%esi) + movq %mm6,48(%esi) + movq %mm7,56(%esi) + leal (%esp,%eax,1),%esp + subl %eax,%ebp + cmpl 88(%esp),%edi + jb .L004loop_sse2 + movl 92(%esp),%esp + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L003SSSE3: + leal -64(%esp),%edx + subl $256,%esp + movdqa 640(%ebp),%xmm1 + movdqu (%edi),%xmm0 +.byte 102,15,56,0,193 + movdqa (%ebp),%xmm3 + movdqa %xmm1,%xmm2 + movdqu 16(%edi),%xmm1 + paddq %xmm0,%xmm3 +.byte 102,15,56,0,202 + movdqa %xmm3,-128(%edx) + movdqa 16(%ebp),%xmm4 + movdqa %xmm2,%xmm3 + movdqu 32(%edi),%xmm2 + paddq %xmm1,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm4,-112(%edx) + movdqa 32(%ebp),%xmm5 + movdqa %xmm3,%xmm4 + movdqu 48(%edi),%xmm3 + paddq %xmm2,%xmm5 +.byte 102,15,56,0,220 + movdqa %xmm5,-96(%edx) + movdqa 48(%ebp),%xmm6 + movdqa %xmm4,%xmm5 + movdqu 64(%edi),%xmm4 + paddq %xmm3,%xmm6 +.byte 102,15,56,0,229 + movdqa %xmm6,-80(%edx) + movdqa 64(%ebp),%xmm7 + movdqa %xmm5,%xmm6 + movdqu 80(%edi),%xmm5 + paddq %xmm4,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm7,-64(%edx) + movdqa %xmm0,(%edx) + movdqa 80(%ebp),%xmm0 + movdqa %xmm6,%xmm7 + movdqu 96(%edi),%xmm6 + paddq %xmm5,%xmm0 +.byte 102,15,56,0,247 + movdqa %xmm0,-48(%edx) + movdqa %xmm1,16(%edx) + movdqa 96(%ebp),%xmm1 + movdqa %xmm7,%xmm0 + movdqu 112(%edi),%xmm7 + paddq %xmm6,%xmm1 +.byte 102,15,56,0,248 + movdqa %xmm1,-32(%edx) + movdqa %xmm2,32(%edx) + movdqa 112(%ebp),%xmm2 + movdqa (%edx),%xmm0 + paddq %xmm7,%xmm2 + movdqa %xmm2,-16(%edx) + nop +.align 32 +.L007loop_ssse3: + movdqa 16(%edx),%xmm2 + movdqa %xmm3,48(%edx) + leal 128(%ebp),%ebp + movq %mm1,8(%esp) + movl %edi,%ebx + movq %mm2,16(%esp) + leal 128(%edi),%edi + movq %mm3,24(%esp) + cmpl %eax,%edi + movq %mm5,40(%esp) + cmovbl %edi,%ebx + movq %mm6,48(%esp) + movl $4,%ecx + pxor %mm1,%mm2 + movq %mm7,56(%esp) + pxor %mm3,%mm3 + jmp .L00800_47_ssse3 +.align 32 +.L00800_47_ssse3: + movdqa %xmm5,%xmm3 + movdqa %xmm2,%xmm1 +.byte 102,15,58,15,208,8 + movdqa %xmm4,(%edx) +.byte 102,15,58,15,220,8 + movdqa %xmm2,%xmm4 + psrlq $7,%xmm2 + paddq %xmm3,%xmm0 + movdqa %xmm4,%xmm3 + psrlq $1,%xmm4 + psllq $56,%xmm3 + pxor %xmm4,%xmm2 + psrlq $7,%xmm4 + pxor %xmm3,%xmm2 + psllq $7,%xmm3 + pxor %xmm4,%xmm2 + movdqa %xmm7,%xmm4 + pxor %xmm3,%xmm2 + movdqa %xmm7,%xmm3 + psrlq $6,%xmm4 + paddq %xmm2,%xmm0 + movdqa %xmm7,%xmm2 + psrlq $19,%xmm3 + psllq $3,%xmm2 + pxor %xmm3,%xmm4 + psrlq $42,%xmm3 + pxor %xmm2,%xmm4 + psllq $42,%xmm2 + pxor %xmm3,%xmm4 + movdqa 32(%edx),%xmm3 + pxor %xmm2,%xmm4 + movdqa (%ebp),%xmm2 + movq %mm4,%mm1 + paddq %xmm4,%xmm0 + movq -128(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + paddq %xmm0,%xmm2 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -120(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm2,-128(%edx) + movdqa %xmm6,%xmm4 + movdqa %xmm3,%xmm2 +.byte 102,15,58,15,217,8 + movdqa %xmm5,16(%edx) +.byte 102,15,58,15,229,8 + movdqa %xmm3,%xmm5 + psrlq $7,%xmm3 + paddq %xmm4,%xmm1 + movdqa %xmm5,%xmm4 + psrlq $1,%xmm5 + psllq $56,%xmm4 + pxor %xmm5,%xmm3 + psrlq $7,%xmm5 + pxor %xmm4,%xmm3 + psllq $7,%xmm4 + pxor %xmm5,%xmm3 + movdqa %xmm0,%xmm5 + pxor %xmm4,%xmm3 + movdqa %xmm0,%xmm4 + psrlq $6,%xmm5 + paddq %xmm3,%xmm1 + movdqa %xmm0,%xmm3 + psrlq $19,%xmm4 + psllq $3,%xmm3 + pxor %xmm4,%xmm5 + psrlq $42,%xmm4 + pxor %xmm3,%xmm5 + psllq $42,%xmm3 + pxor %xmm4,%xmm5 + movdqa 48(%edx),%xmm4 + pxor %xmm3,%xmm5 + movdqa 16(%ebp),%xmm3 + movq %mm4,%mm1 + paddq %xmm5,%xmm1 + movq -112(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + paddq %xmm1,%xmm3 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -104(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm3,-112(%edx) + movdqa %xmm7,%xmm5 + movdqa %xmm4,%xmm3 +.byte 102,15,58,15,226,8 + movdqa %xmm6,32(%edx) +.byte 102,15,58,15,238,8 + movdqa %xmm4,%xmm6 + psrlq $7,%xmm4 + paddq %xmm5,%xmm2 + movdqa %xmm6,%xmm5 + psrlq $1,%xmm6 + psllq $56,%xmm5 + pxor %xmm6,%xmm4 + psrlq $7,%xmm6 + pxor %xmm5,%xmm4 + psllq $7,%xmm5 + pxor %xmm6,%xmm4 + movdqa %xmm1,%xmm6 + pxor %xmm5,%xmm4 + movdqa %xmm1,%xmm5 + psrlq $6,%xmm6 + paddq %xmm4,%xmm2 + movdqa %xmm1,%xmm4 + psrlq $19,%xmm5 + psllq $3,%xmm4 + pxor %xmm5,%xmm6 + psrlq $42,%xmm5 + pxor %xmm4,%xmm6 + psllq $42,%xmm4 + pxor %xmm5,%xmm6 + movdqa (%edx),%xmm5 + pxor %xmm4,%xmm6 + movdqa 32(%ebp),%xmm4 + movq %mm4,%mm1 + paddq %xmm6,%xmm2 + movq -96(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + paddq %xmm2,%xmm4 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -88(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm4,-96(%edx) + movdqa %xmm0,%xmm6 + movdqa %xmm5,%xmm4 +.byte 102,15,58,15,235,8 + movdqa %xmm7,48(%edx) +.byte 102,15,58,15,247,8 + movdqa %xmm5,%xmm7 + psrlq $7,%xmm5 + paddq %xmm6,%xmm3 + movdqa %xmm7,%xmm6 + psrlq $1,%xmm7 + psllq $56,%xmm6 + pxor %xmm7,%xmm5 + psrlq $7,%xmm7 + pxor %xmm6,%xmm5 + psllq $7,%xmm6 + pxor %xmm7,%xmm5 + movdqa %xmm2,%xmm7 + pxor %xmm6,%xmm5 + movdqa %xmm2,%xmm6 + psrlq $6,%xmm7 + paddq %xmm5,%xmm3 + movdqa %xmm2,%xmm5 + psrlq $19,%xmm6 + psllq $3,%xmm5 + pxor %xmm6,%xmm7 + psrlq $42,%xmm6 + pxor %xmm5,%xmm7 + psllq $42,%xmm5 + pxor %xmm6,%xmm7 + movdqa 16(%edx),%xmm6 + pxor %xmm5,%xmm7 + movdqa 48(%ebp),%xmm5 + movq %mm4,%mm1 + paddq %xmm7,%xmm3 + movq -80(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + paddq %xmm3,%xmm5 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -72(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm5,-80(%edx) + movdqa %xmm1,%xmm7 + movdqa %xmm6,%xmm5 +.byte 102,15,58,15,244,8 + movdqa %xmm0,(%edx) +.byte 102,15,58,15,248,8 + movdqa %xmm6,%xmm0 + psrlq $7,%xmm6 + paddq %xmm7,%xmm4 + movdqa %xmm0,%xmm7 + psrlq $1,%xmm0 + psllq $56,%xmm7 + pxor %xmm0,%xmm6 + psrlq $7,%xmm0 + pxor %xmm7,%xmm6 + psllq $7,%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm3,%xmm0 + pxor %xmm7,%xmm6 + movdqa %xmm3,%xmm7 + psrlq $6,%xmm0 + paddq %xmm6,%xmm4 + movdqa %xmm3,%xmm6 + psrlq $19,%xmm7 + psllq $3,%xmm6 + pxor %xmm7,%xmm0 + psrlq $42,%xmm7 + pxor %xmm6,%xmm0 + psllq $42,%xmm6 + pxor %xmm7,%xmm0 + movdqa 32(%edx),%xmm7 + pxor %xmm6,%xmm0 + movdqa 64(%ebp),%xmm6 + movq %mm4,%mm1 + paddq %xmm0,%xmm4 + movq -64(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + paddq %xmm4,%xmm6 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -56(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm6,-64(%edx) + movdqa %xmm2,%xmm0 + movdqa %xmm7,%xmm6 +.byte 102,15,58,15,253,8 + movdqa %xmm1,16(%edx) +.byte 102,15,58,15,193,8 + movdqa %xmm7,%xmm1 + psrlq $7,%xmm7 + paddq %xmm0,%xmm5 + movdqa %xmm1,%xmm0 + psrlq $1,%xmm1 + psllq $56,%xmm0 + pxor %xmm1,%xmm7 + psrlq $7,%xmm1 + pxor %xmm0,%xmm7 + psllq $7,%xmm0 + pxor %xmm1,%xmm7 + movdqa %xmm4,%xmm1 + pxor %xmm0,%xmm7 + movdqa %xmm4,%xmm0 + psrlq $6,%xmm1 + paddq %xmm7,%xmm5 + movdqa %xmm4,%xmm7 + psrlq $19,%xmm0 + psllq $3,%xmm7 + pxor %xmm0,%xmm1 + psrlq $42,%xmm0 + pxor %xmm7,%xmm1 + psllq $42,%xmm7 + pxor %xmm0,%xmm1 + movdqa 48(%edx),%xmm0 + pxor %xmm7,%xmm1 + movdqa 80(%ebp),%xmm7 + movq %mm4,%mm1 + paddq %xmm1,%xmm5 + movq -48(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + paddq %xmm5,%xmm7 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -40(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm7,-48(%edx) + movdqa %xmm3,%xmm1 + movdqa %xmm0,%xmm7 +.byte 102,15,58,15,198,8 + movdqa %xmm2,32(%edx) +.byte 102,15,58,15,202,8 + movdqa %xmm0,%xmm2 + psrlq $7,%xmm0 + paddq %xmm1,%xmm6 + movdqa %xmm2,%xmm1 + psrlq $1,%xmm2 + psllq $56,%xmm1 + pxor %xmm2,%xmm0 + psrlq $7,%xmm2 + pxor %xmm1,%xmm0 + psllq $7,%xmm1 + pxor %xmm2,%xmm0 + movdqa %xmm5,%xmm2 + pxor %xmm1,%xmm0 + movdqa %xmm5,%xmm1 + psrlq $6,%xmm2 + paddq %xmm0,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $19,%xmm1 + psllq $3,%xmm0 + pxor %xmm1,%xmm2 + psrlq $42,%xmm1 + pxor %xmm0,%xmm2 + psllq $42,%xmm0 + pxor %xmm1,%xmm2 + movdqa (%edx),%xmm1 + pxor %xmm0,%xmm2 + movdqa 96(%ebp),%xmm0 + movq %mm4,%mm1 + paddq %xmm2,%xmm6 + movq -32(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + paddq %xmm6,%xmm0 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -24(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm0,-32(%edx) + movdqa %xmm4,%xmm2 + movdqa %xmm1,%xmm0 +.byte 102,15,58,15,207,8 + movdqa %xmm3,48(%edx) +.byte 102,15,58,15,211,8 + movdqa %xmm1,%xmm3 + psrlq $7,%xmm1 + paddq %xmm2,%xmm7 + movdqa %xmm3,%xmm2 + psrlq $1,%xmm3 + psllq $56,%xmm2 + pxor %xmm3,%xmm1 + psrlq $7,%xmm3 + pxor %xmm2,%xmm1 + psllq $7,%xmm2 + pxor %xmm3,%xmm1 + movdqa %xmm6,%xmm3 + pxor %xmm2,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $6,%xmm3 + paddq %xmm1,%xmm7 + movdqa %xmm6,%xmm1 + psrlq $19,%xmm2 + psllq $3,%xmm1 + pxor %xmm2,%xmm3 + psrlq $42,%xmm2 + pxor %xmm1,%xmm3 + psllq $42,%xmm1 + pxor %xmm2,%xmm3 + movdqa 16(%edx),%xmm2 + pxor %xmm1,%xmm3 + movdqa 112(%ebp),%xmm1 + movq %mm4,%mm1 + paddq %xmm3,%xmm7 + movq -16(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + paddq %xmm7,%xmm1 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -8(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm1,-16(%edx) + leal 128(%ebp),%ebp + decl %ecx + jnz .L00800_47_ssse3 + movdqa (%ebp),%xmm1 + leal -640(%ebp),%ebp + movdqu (%ebx),%xmm0 +.byte 102,15,56,0,193 + movdqa (%ebp),%xmm3 + movdqa %xmm1,%xmm2 + movdqu 16(%ebx),%xmm1 + paddq %xmm0,%xmm3 +.byte 102,15,56,0,202 + movq %mm4,%mm1 + movq -128(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -120(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm3,-128(%edx) + movdqa 16(%ebp),%xmm4 + movdqa %xmm2,%xmm3 + movdqu 32(%ebx),%xmm2 + paddq %xmm1,%xmm4 +.byte 102,15,56,0,211 + movq %mm4,%mm1 + movq -112(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -104(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm4,-112(%edx) + movdqa 32(%ebp),%xmm5 + movdqa %xmm3,%xmm4 + movdqu 48(%ebx),%xmm3 + paddq %xmm2,%xmm5 +.byte 102,15,56,0,220 + movq %mm4,%mm1 + movq -96(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -88(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm5,-96(%edx) + movdqa 48(%ebp),%xmm6 + movdqa %xmm4,%xmm5 + movdqu 64(%ebx),%xmm4 + paddq %xmm3,%xmm6 +.byte 102,15,56,0,229 + movq %mm4,%mm1 + movq -80(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -72(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm6,-80(%edx) + movdqa 64(%ebp),%xmm7 + movdqa %xmm5,%xmm6 + movdqu 80(%ebx),%xmm5 + paddq %xmm4,%xmm7 +.byte 102,15,56,0,238 + movq %mm4,%mm1 + movq -64(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -56(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm7,-64(%edx) + movdqa %xmm0,(%edx) + movdqa 80(%ebp),%xmm0 + movdqa %xmm6,%xmm7 + movdqu 96(%ebx),%xmm6 + paddq %xmm5,%xmm0 +.byte 102,15,56,0,247 + movq %mm4,%mm1 + movq -48(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -40(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm0,-48(%edx) + movdqa %xmm1,16(%edx) + movdqa 96(%ebp),%xmm1 + movdqa %xmm7,%xmm0 + movdqu 112(%ebx),%xmm7 + paddq %xmm6,%xmm1 +.byte 102,15,56,0,248 + movq %mm4,%mm1 + movq -32(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -24(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm1,-32(%edx) + movdqa %xmm2,32(%edx) + movdqa 112(%ebp),%xmm2 + movdqa (%edx),%xmm0 + paddq %xmm7,%xmm2 + movq %mm4,%mm1 + movq -16(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -8(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm2,-16(%edx) + movq 8(%esp),%mm1 + paddq %mm3,%mm0 + movq 24(%esp),%mm3 + movq 56(%esp),%mm7 + pxor %mm1,%mm2 + paddq (%esi),%mm0 + paddq 8(%esi),%mm1 + paddq 16(%esi),%mm2 + paddq 24(%esi),%mm3 + paddq 32(%esi),%mm4 + paddq 40(%esi),%mm5 + paddq 48(%esi),%mm6 + paddq 56(%esi),%mm7 + movq %mm0,(%esi) + movq %mm1,8(%esi) + movq %mm2,16(%esi) + movq %mm3,24(%esi) + movq %mm4,32(%esi) + movq %mm5,40(%esi) + movq %mm6,48(%esi) + movq %mm7,56(%esi) + cmpl %eax,%edi + jb .L007loop_ssse3 + movl 76(%edx),%esp + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 16 +.L002loop_x86: + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + movl 28(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 32(%edi),%eax + movl 36(%edi),%ebx + movl 40(%edi),%ecx + movl 44(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 48(%edi),%eax + movl 52(%edi),%ebx + movl 56(%edi),%ecx + movl 60(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 64(%edi),%eax + movl 68(%edi),%ebx + movl 72(%edi),%ecx + movl 76(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 80(%edi),%eax + movl 84(%edi),%ebx + movl 88(%edi),%ecx + movl 92(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 96(%edi),%eax + movl 100(%edi),%ebx + movl 104(%edi),%ecx + movl 108(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 112(%edi),%eax + movl 116(%edi),%ebx + movl 120(%edi),%ecx + movl 124(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + addl $128,%edi + subl $72,%esp + movl %edi,204(%esp) + leal 8(%esp),%edi + movl $16,%ecx +.long 2784229001 +.align 16 +.L00900_15_x86: + movl 40(%esp),%ecx + movl 44(%esp),%edx + movl %ecx,%esi + shrl $9,%ecx + movl %edx,%edi + shrl $9,%edx + movl %ecx,%ebx + shll $14,%esi + movl %edx,%eax + shll $14,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%eax + shll $4,%esi + xorl %edx,%ebx + shll $4,%edi + xorl %esi,%ebx + shrl $4,%ecx + xorl %edi,%eax + shrl $4,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 48(%esp),%ecx + movl 52(%esp),%edx + movl 56(%esp),%esi + movl 60(%esp),%edi + addl 64(%esp),%eax + adcl 68(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + andl 40(%esp),%ecx + andl 44(%esp),%edx + addl 192(%esp),%eax + adcl 196(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + movl (%ebp),%esi + movl 4(%ebp),%edi + addl %ecx,%eax + adcl %edx,%ebx + movl 32(%esp),%ecx + movl 36(%esp),%edx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + addl %ecx,%eax + adcl %edx,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,%esi + shrl $2,%ecx + movl %edx,%edi + shrl $2,%edx + movl %ecx,%ebx + shll $4,%esi + movl %edx,%eax + shll $4,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%ebx + shll $21,%esi + xorl %edx,%eax + shll $21,%edi + xorl %esi,%eax + shrl $21,%ecx + xorl %edi,%ebx + shrl $21,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 16(%esp),%esi + movl 20(%esp),%edi + addl (%esp),%eax + adcl 4(%esp),%ebx + orl %esi,%ecx + orl %edi,%edx + andl 24(%esp),%ecx + andl 28(%esp),%edx + andl 8(%esp),%esi + andl 12(%esp),%edi + orl %esi,%ecx + orl %edi,%edx + addl %ecx,%eax + adcl %edx,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + movb (%ebp),%dl + subl $8,%esp + leal 8(%ebp),%ebp + cmpb $148,%dl + jne .L00900_15_x86 +.align 16 +.L01016_79_x86: + movl 312(%esp),%ecx + movl 316(%esp),%edx + movl %ecx,%esi + shrl $1,%ecx + movl %edx,%edi + shrl $1,%edx + movl %ecx,%eax + shll $24,%esi + movl %edx,%ebx + shll $24,%edi + xorl %esi,%ebx + shrl $6,%ecx + xorl %edi,%eax + shrl $6,%edx + xorl %ecx,%eax + shll $7,%esi + xorl %edx,%ebx + shll $1,%edi + xorl %esi,%ebx + shrl $1,%ecx + xorl %edi,%eax + shrl $1,%edx + xorl %ecx,%eax + shll $6,%edi + xorl %edx,%ebx + xorl %edi,%eax + movl %eax,(%esp) + movl %ebx,4(%esp) + movl 208(%esp),%ecx + movl 212(%esp),%edx + movl %ecx,%esi + shrl $6,%ecx + movl %edx,%edi + shrl $6,%edx + movl %ecx,%eax + shll $3,%esi + movl %edx,%ebx + shll $3,%edi + xorl %esi,%eax + shrl $13,%ecx + xorl %edi,%ebx + shrl $13,%edx + xorl %ecx,%eax + shll $10,%esi + xorl %edx,%ebx + shll $10,%edi + xorl %esi,%ebx + shrl $10,%ecx + xorl %edi,%eax + shrl $10,%edx + xorl %ecx,%ebx + shll $13,%edi + xorl %edx,%eax + xorl %edi,%eax + movl 320(%esp),%ecx + movl 324(%esp),%edx + addl (%esp),%eax + adcl 4(%esp),%ebx + movl 248(%esp),%esi + movl 252(%esp),%edi + addl %ecx,%eax + adcl %edx,%ebx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,192(%esp) + movl %ebx,196(%esp) + movl 40(%esp),%ecx + movl 44(%esp),%edx + movl %ecx,%esi + shrl $9,%ecx + movl %edx,%edi + shrl $9,%edx + movl %ecx,%ebx + shll $14,%esi + movl %edx,%eax + shll $14,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%eax + shll $4,%esi + xorl %edx,%ebx + shll $4,%edi + xorl %esi,%ebx + shrl $4,%ecx + xorl %edi,%eax + shrl $4,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 48(%esp),%ecx + movl 52(%esp),%edx + movl 56(%esp),%esi + movl 60(%esp),%edi + addl 64(%esp),%eax + adcl 68(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + andl 40(%esp),%ecx + andl 44(%esp),%edx + addl 192(%esp),%eax + adcl 196(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + movl (%ebp),%esi + movl 4(%ebp),%edi + addl %ecx,%eax + adcl %edx,%ebx + movl 32(%esp),%ecx + movl 36(%esp),%edx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + addl %ecx,%eax + adcl %edx,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,%esi + shrl $2,%ecx + movl %edx,%edi + shrl $2,%edx + movl %ecx,%ebx + shll $4,%esi + movl %edx,%eax + shll $4,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%ebx + shll $21,%esi + xorl %edx,%eax + shll $21,%edi + xorl %esi,%eax + shrl $21,%ecx + xorl %edi,%ebx + shrl $21,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 16(%esp),%esi + movl 20(%esp),%edi + addl (%esp),%eax + adcl 4(%esp),%ebx + orl %esi,%ecx + orl %edi,%edx + andl 24(%esp),%ecx + andl 28(%esp),%edx + andl 8(%esp),%esi + andl 12(%esp),%edi + orl %esi,%ecx + orl %edi,%edx + addl %ecx,%eax + adcl %edx,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + movb (%ebp),%dl + subl $8,%esp + leal 8(%ebp),%ebp + cmpb $23,%dl + jne .L01016_79_x86 + movl 840(%esp),%esi + movl 844(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + addl 8(%esp),%eax + adcl 12(%esp),%ebx + movl %eax,(%esi) + movl %ebx,4(%esi) + addl 16(%esp),%ecx + adcl 20(%esp),%edx + movl %ecx,8(%esi) + movl %edx,12(%esi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + addl 24(%esp),%eax + adcl 28(%esp),%ebx + movl %eax,16(%esi) + movl %ebx,20(%esi) + addl 32(%esp),%ecx + adcl 36(%esp),%edx + movl %ecx,24(%esi) + movl %edx,28(%esi) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + addl 40(%esp),%eax + adcl 44(%esp),%ebx + movl %eax,32(%esi) + movl %ebx,36(%esi) + addl 48(%esp),%ecx + adcl 52(%esp),%edx + movl %ecx,40(%esi) + movl %edx,44(%esi) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + addl 56(%esp),%eax + adcl 60(%esp),%ebx + movl %eax,48(%esi) + movl %ebx,52(%esi) + addl 64(%esp),%ecx + adcl 68(%esp),%edx + movl %ecx,56(%esi) + movl %edx,60(%esi) + addl $840,%esp + subl $640,%ebp + cmpl 8(%esp),%edi + jb .L002loop_x86 + movl 12(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L001K512: +.long 3609767458,1116352408 +.long 602891725,1899447441 +.long 3964484399,3049323471 +.long 2173295548,3921009573 +.long 4081628472,961987163 +.long 3053834265,1508970993 +.long 2937671579,2453635748 +.long 3664609560,2870763221 +.long 2734883394,3624381080 +.long 1164996542,310598401 +.long 1323610764,607225278 +.long 3590304994,1426881987 +.long 4068182383,1925078388 +.long 991336113,2162078206 +.long 633803317,2614888103 +.long 3479774868,3248222580 +.long 2666613458,3835390401 +.long 944711139,4022224774 +.long 2341262773,264347078 +.long 2007800933,604807628 +.long 1495990901,770255983 +.long 1856431235,1249150122 +.long 3175218132,1555081692 +.long 2198950837,1996064986 +.long 3999719339,2554220882 +.long 766784016,2821834349 +.long 2566594879,2952996808 +.long 3203337956,3210313671 +.long 1034457026,3336571891 +.long 2466948901,3584528711 +.long 3758326383,113926993 +.long 168717936,338241895 +.long 1188179964,666307205 +.long 1546045734,773529912 +.long 1522805485,1294757372 +.long 2643833823,1396182291 +.long 2343527390,1695183700 +.long 1014477480,1986661051 +.long 1206759142,2177026350 +.long 344077627,2456956037 +.long 1290863460,2730485921 +.long 3158454273,2820302411 +.long 3505952657,3259730800 +.long 106217008,3345764771 +.long 3606008344,3516065817 +.long 1432725776,3600352804 +.long 1467031594,4094571909 +.long 851169720,275423344 +.long 3100823752,430227734 +.long 1363258195,506948616 +.long 3750685593,659060556 +.long 3785050280,883997877 +.long 3318307427,958139571 +.long 3812723403,1322822218 +.long 2003034995,1537002063 +.long 3602036899,1747873779 +.long 1575990012,1955562222 +.long 1125592928,2024104815 +.long 2716904306,2227730452 +.long 442776044,2361852424 +.long 593698344,2428436474 +.long 3733110249,2756734187 +.long 2999351573,3204031479 +.long 3815920427,3329325298 +.long 3928383900,3391569614 +.long 566280711,3515267271 +.long 3454069534,3940187606 +.long 4000239992,4118630271 +.long 1914138554,116418474 +.long 2731055270,174292421 +.long 3203993006,289380356 +.long 320620315,460393269 +.long 587496836,685471733 +.long 1086792851,852142971 +.long 365543100,1017036298 +.long 2618297676,1126000580 +.long 3409855158,1288033470 +.long 4234509866,1501505948 +.long 987167468,1607167915 +.long 1246189591,1816402316 +.long 67438087,66051 +.long 202182159,134810123 +.size sha512_block_data_order,.-.L_sha512_block_data_order_begin +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97 +.byte 110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32 +.byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 +.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 +.byte 62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S new file mode 100644 index 00000000..4dcdaf5a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S @@ -0,0 +1,1906 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Permission to use under GPL terms is granted. +@ ==================================================================== + +@ SHA512 block procedure for ARMv4. September 2007. + +@ This code is ~4.5 (four and a half) times faster than code generated +@ by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue +@ Xscale PXA250 core]. +@ +@ July 2010. +@ +@ Rescheduling for dual-issue pipeline resulted in 6% improvement on +@ Cortex A8 core and ~40 cycles per processed byte. + +@ February 2011. +@ +@ Profiler-assisted and platform-specific optimization resulted in 7% +@ improvement on Coxtex A8 core and ~38 cycles per byte. + +@ March 2011. +@ +@ Add NEON implementation. On Cortex A8 it was measured to process +@ one byte in 23.3 cycles or ~60% faster than integer-only code. + +@ August 2012. +@ +@ Improve NEON performance by 12% on Snapdragon S4. In absolute +@ terms it's 22.6 cycles per byte, which is disappointing result. +@ Technical writers asserted that 3-way S4 pipeline can sustain +@ multiple NEON instructions per cycle, but dual NEON issue could +@ not be observed, see http://www.openssl.org/~appro/Snapdragon-S4.html +@ for further details. On side note Cortex-A15 processes one byte in +@ 16 cycles. + +@ Byte order [in]dependence. ========================================= +@ +@ Originally caller was expected to maintain specific *dword* order in +@ h[0-7], namely with most significant dword at *lower* address, which +@ was reflected in below two parameters as 0 and 4. Now caller is +@ expected to maintain native byte order for whole 64-bit values. +#ifndef __KERNEL__ +# include +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +#else +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +# define VFP_ABI_PUSH +# define VFP_ABI_POP +#endif + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. + + +#ifdef __ARMEL__ +# define LO 0 +# define HI 4 +# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +#else +# define HI 0 +# define LO 4 +# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +#endif + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +# define adrl adr +#else +.code 32 +#endif + + +.align 5 +K512: + WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd) + WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc) + WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019) + WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118) + WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe) + WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2) + WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1) + WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694) + WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3) + WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65) + WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483) + WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5) + WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210) + WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4) + WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725) + WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70) + WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926) + WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df) + WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8) + WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b) + WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001) + WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30) + WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910) + WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8) + WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53) + WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8) + WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb) + WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3) + WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60) + WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec) + WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9) + WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b) + WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207) + WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178) + WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6) + WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b) + WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493) + WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c) + WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) + WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) + +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +LOPENSSL_armcap: +.word OPENSSL_armcap_P-Lsha512_block_data_order +.skip 32-4 +#else +.skip 32 +#endif + +.globl _sha512_block_data_order +.private_extern _sha512_block_data_order +#ifdef __thumb2__ +.thumb_func _sha512_block_data_order +#endif +_sha512_block_data_order: +Lsha512_block_data_order: +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r3,pc,#8 @ _sha512_block_data_order +#else + adr r3,Lsha512_block_data_order +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + ldr r12,LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV7_NEON + bne LNEON +#endif + add r2,r1,r2,lsl#7 @ len to point at the end of inp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + sub r14,r3,#672 @ K512 + sub sp,sp,#9*8 + + ldr r7,[r0,#32+LO] + ldr r8,[r0,#32+HI] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] +Loop: + str r9, [sp,#48+0] + str r10, [sp,#48+4] + str r11, [sp,#56+0] + str r12, [sp,#56+4] + ldr r5,[r0,#0+LO] + ldr r6,[r0,#0+HI] + ldr r3,[r0,#8+LO] + ldr r4,[r0,#8+HI] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + str r3,[sp,#8+0] + str r4,[sp,#8+4] + str r9, [sp,#16+0] + str r10, [sp,#16+4] + str r11, [sp,#24+0] + str r12, [sp,#24+4] + ldr r3,[r0,#40+LO] + ldr r4,[r0,#40+HI] + str r3,[sp,#40+0] + str r4,[sp,#40+4] + +L00_15: +#if __ARM_ARCH__<7 + ldrb r3,[r1,#7] + ldrb r9, [r1,#6] + ldrb r10, [r1,#5] + ldrb r11, [r1,#4] + ldrb r4,[r1,#3] + ldrb r12, [r1,#2] + orr r3,r3,r9,lsl#8 + ldrb r9, [r1,#1] + orr r3,r3,r10,lsl#16 + ldrb r10, [r1],#8 + orr r3,r3,r11,lsl#24 + orr r4,r4,r12,lsl#8 + orr r4,r4,r9,lsl#16 + orr r4,r4,r10,lsl#24 +#else + ldr r3,[r1,#4] + ldr r4,[r1],#8 +#ifdef __ARMEL__ + rev r3,r3 + rev r4,r4 +#endif +#endif + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#148 + + ldr r12,[sp,#16+0] @ c.lo +#if __ARM_ARCH__>=7 + it eq @ Thumb2 thing, sanity check in ARM +#endif + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 + tst r14,#1 + beq L00_15 + ldr r9,[sp,#184+0] + ldr r10,[sp,#184+4] + bic r14,r14,#1 +L16_79: + @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 + @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 + mov r3,r9,lsr#1 + ldr r11,[sp,#80+0] + mov r4,r10,lsr#1 + ldr r12,[sp,#80+4] + eor r3,r3,r10,lsl#31 + eor r4,r4,r9,lsl#31 + eor r3,r3,r9,lsr#8 + eor r4,r4,r10,lsr#8 + eor r3,r3,r10,lsl#24 + eor r4,r4,r9,lsl#24 + eor r3,r3,r9,lsr#7 + eor r4,r4,r10,lsr#7 + eor r3,r3,r10,lsl#25 + + @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 + @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 + mov r9,r11,lsr#19 + mov r10,r12,lsr#19 + eor r9,r9,r12,lsl#13 + eor r10,r10,r11,lsl#13 + eor r9,r9,r12,lsr#29 + eor r10,r10,r11,lsr#29 + eor r9,r9,r11,lsl#3 + eor r10,r10,r12,lsl#3 + eor r9,r9,r11,lsr#6 + eor r10,r10,r12,lsr#6 + ldr r11,[sp,#120+0] + eor r9,r9,r12,lsl#26 + + ldr r12,[sp,#120+4] + adds r3,r3,r9 + ldr r9,[sp,#192+0] + adc r4,r4,r10 + + ldr r10,[sp,#192+4] + adds r3,r3,r11 + adc r4,r4,r12 + adds r3,r3,r9 + adc r4,r4,r10 + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#23 + + ldr r12,[sp,#16+0] @ c.lo +#if __ARM_ARCH__>=7 + it eq @ Thumb2 thing, sanity check in ARM +#endif + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 +#if __ARM_ARCH__>=7 + ittt eq @ Thumb2 thing, sanity check in ARM +#endif + ldreq r9,[sp,#184+0] + ldreq r10,[sp,#184+4] + beq L16_79 + bic r14,r14,#1 + + ldr r3,[sp,#8+0] + ldr r4,[sp,#8+4] + ldr r9, [r0,#0+LO] + ldr r10, [r0,#0+HI] + ldr r11, [r0,#8+LO] + ldr r12, [r0,#8+HI] + adds r9,r5,r9 + str r9, [r0,#0+LO] + adc r10,r6,r10 + str r10, [r0,#0+HI] + adds r11,r3,r11 + str r11, [r0,#8+LO] + adc r12,r4,r12 + str r12, [r0,#8+HI] + + ldr r5,[sp,#16+0] + ldr r6,[sp,#16+4] + ldr r3,[sp,#24+0] + ldr r4,[sp,#24+4] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + adds r9,r5,r9 + str r9, [r0,#16+LO] + adc r10,r6,r10 + str r10, [r0,#16+HI] + adds r11,r3,r11 + str r11, [r0,#24+LO] + adc r12,r4,r12 + str r12, [r0,#24+HI] + + ldr r3,[sp,#40+0] + ldr r4,[sp,#40+4] + ldr r9, [r0,#32+LO] + ldr r10, [r0,#32+HI] + ldr r11, [r0,#40+LO] + ldr r12, [r0,#40+HI] + adds r7,r7,r9 + str r7,[r0,#32+LO] + adc r8,r8,r10 + str r8,[r0,#32+HI] + adds r11,r3,r11 + str r11, [r0,#40+LO] + adc r12,r4,r12 + str r12, [r0,#40+HI] + + ldr r5,[sp,#48+0] + ldr r6,[sp,#48+4] + ldr r3,[sp,#56+0] + ldr r4,[sp,#56+4] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] + adds r9,r5,r9 + str r9, [r0,#48+LO] + adc r10,r6,r10 + str r10, [r0,#48+HI] + adds r11,r3,r11 + str r11, [r0,#56+LO] + adc r12,r4,r12 + str r12, [r0,#56+HI] + + add sp,sp,#640 + sub r14,r14,#640 + + teq r1,r2 + bne Loop + + add sp,sp,#8*9 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif + +#if __ARM_MAX_ARCH__>=7 + + + +.globl _sha512_block_data_order_neon +.private_extern _sha512_block_data_order_neon +#ifdef __thumb2__ +.thumb_func _sha512_block_data_order_neon +#endif +.align 4 +_sha512_block_data_order_neon: +LNEON: + dmb @ errata #451034 on early Cortex A8 + add r2,r1,r2,lsl#7 @ len to point at the end of inp + adr r3,K512 + VFP_ABI_PUSH + vldmia r0,{d16,d17,d18,d19,d20,d21,d22,d23} @ load context +Loop_neon: + vshr.u64 d24,d20,#14 @ 0 +#if 0<16 + vld1.64 {d0},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 +#if 0>0 + vadd.i64 d16,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 0<16 && defined(__ARMEL__) + vrev64.8 d0,d0 +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d0 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 1 +#if 1<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 1>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 1<16 && defined(__ARMEL__) + vrev64.8 d1,d1 +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d1 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 2 +#if 2<16 + vld1.64 {d2},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 +#if 2>0 + vadd.i64 d22,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 2<16 && defined(__ARMEL__) + vrev64.8 d2,d2 +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d2 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 3 +#if 3<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 3>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 3<16 && defined(__ARMEL__) + vrev64.8 d3,d3 +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d3 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 4 +#if 4<16 + vld1.64 {d4},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 +#if 4>0 + vadd.i64 d20,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 4<16 && defined(__ARMEL__) + vrev64.8 d4,d4 +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d4 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 5 +#if 5<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 5>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 5<16 && defined(__ARMEL__) + vrev64.8 d5,d5 +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d5 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 6 +#if 6<16 + vld1.64 {d6},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 +#if 6>0 + vadd.i64 d18,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 6<16 && defined(__ARMEL__) + vrev64.8 d6,d6 +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d6 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 7 +#if 7<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 7>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 7<16 && defined(__ARMEL__) + vrev64.8 d7,d7 +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d7 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + vshr.u64 d24,d20,#14 @ 8 +#if 8<16 + vld1.64 {d8},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 +#if 8>0 + vadd.i64 d16,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 8<16 && defined(__ARMEL__) + vrev64.8 d8,d8 +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d8 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 9 +#if 9<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 9>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 9<16 && defined(__ARMEL__) + vrev64.8 d9,d9 +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d9 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 10 +#if 10<16 + vld1.64 {d10},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 +#if 10>0 + vadd.i64 d22,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 10<16 && defined(__ARMEL__) + vrev64.8 d10,d10 +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d10 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 11 +#if 11<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 11>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 11<16 && defined(__ARMEL__) + vrev64.8 d11,d11 +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d11 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 12 +#if 12<16 + vld1.64 {d12},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 +#if 12>0 + vadd.i64 d20,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 12<16 && defined(__ARMEL__) + vrev64.8 d12,d12 +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d12 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 13 +#if 13<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 13>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 13<16 && defined(__ARMEL__) + vrev64.8 d13,d13 +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d13 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 14 +#if 14<16 + vld1.64 {d14},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 +#if 14>0 + vadd.i64 d18,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 14<16 && defined(__ARMEL__) + vrev64.8 d14,d14 +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d14 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 15 +#if 15<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 15>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 15<16 && defined(__ARMEL__) + vrev64.8 d15,d15 +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d15 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + mov r12,#4 +L16_79_neon: + subs r12,#1 + vshr.u64 q12,q7,#19 + vshr.u64 q13,q7,#61 + vadd.i64 d16,d30 @ h+=Maj from the past + vshr.u64 q15,q7,#6 + vsli.64 q12,q7,#45 + vext.8 q14,q0,q1,#8 @ X[i+1] + vsli.64 q13,q7,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q0,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q4,q5,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q0,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q0,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 16<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d0 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 17 +#if 17<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 17>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 17<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d1 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 q12,q0,#19 + vshr.u64 q13,q0,#61 + vadd.i64 d22,d30 @ h+=Maj from the past + vshr.u64 q15,q0,#6 + vsli.64 q12,q0,#45 + vext.8 q14,q1,q2,#8 @ X[i+1] + vsli.64 q13,q0,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q1,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q5,q6,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q1,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q1,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 18<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d2 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 19 +#if 19<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 19>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 19<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d3 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 q12,q1,#19 + vshr.u64 q13,q1,#61 + vadd.i64 d20,d30 @ h+=Maj from the past + vshr.u64 q15,q1,#6 + vsli.64 q12,q1,#45 + vext.8 q14,q2,q3,#8 @ X[i+1] + vsli.64 q13,q1,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q2,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q6,q7,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q2,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q2,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 20<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d4 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 21 +#if 21<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 21>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 21<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d5 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 q12,q2,#19 + vshr.u64 q13,q2,#61 + vadd.i64 d18,d30 @ h+=Maj from the past + vshr.u64 q15,q2,#6 + vsli.64 q12,q2,#45 + vext.8 q14,q3,q4,#8 @ X[i+1] + vsli.64 q13,q2,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q3,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q7,q0,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q3,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q3,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 22<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d6 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 23 +#if 23<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 23>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 23<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d7 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + vshr.u64 q12,q3,#19 + vshr.u64 q13,q3,#61 + vadd.i64 d16,d30 @ h+=Maj from the past + vshr.u64 q15,q3,#6 + vsli.64 q12,q3,#45 + vext.8 q14,q4,q5,#8 @ X[i+1] + vsli.64 q13,q3,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q4,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q0,q1,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q4,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q4,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 24<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d8 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 25 +#if 25<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 25>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 25<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d9 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 q12,q4,#19 + vshr.u64 q13,q4,#61 + vadd.i64 d22,d30 @ h+=Maj from the past + vshr.u64 q15,q4,#6 + vsli.64 q12,q4,#45 + vext.8 q14,q5,q6,#8 @ X[i+1] + vsli.64 q13,q4,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q5,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q1,q2,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q5,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q5,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 26<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d10 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 27 +#if 27<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 27>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 27<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d11 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 q12,q5,#19 + vshr.u64 q13,q5,#61 + vadd.i64 d20,d30 @ h+=Maj from the past + vshr.u64 q15,q5,#6 + vsli.64 q12,q5,#45 + vext.8 q14,q6,q7,#8 @ X[i+1] + vsli.64 q13,q5,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q6,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q2,q3,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q6,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q6,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 28<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d12 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 29 +#if 29<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 29>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 29<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d13 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 q12,q6,#19 + vshr.u64 q13,q6,#61 + vadd.i64 d18,d30 @ h+=Maj from the past + vshr.u64 q15,q6,#6 + vsli.64 q12,q6,#45 + vext.8 q14,q7,q0,#8 @ X[i+1] + vsli.64 q13,q6,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q7,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q3,q4,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q7,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q7,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 30<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d14 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 31 +#if 31<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 31>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 31<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d15 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + bne L16_79_neon + + vadd.i64 d16,d30 @ h+=Maj from the past + vldmia r0,{d24,d25,d26,d27,d28,d29,d30,d31} @ load context to temp + vadd.i64 q8,q12 @ vectorized accumulate + vadd.i64 q9,q13 + vadd.i64 q10,q14 + vadd.i64 q11,q15 + vstmia r0,{d16,d17,d18,d19,d20,d21,d22,d23} @ save context + teq r1,r2 + sub r3,#640 @ rewind K512 + bne Loop_neon + + VFP_ABI_POP + bx lr @ .word 0xe12fff1e + +#endif +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.comm _OPENSSL_armcap_P,4 +.non_lazy_symbol_pointer +OPENSSL_armcap_P: +.indirect_symbol _OPENSSL_armcap_P +.long 0 +.private_extern _OPENSSL_armcap_P +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S new file mode 100644 index 00000000..689ca91e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S @@ -0,0 +1,1901 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +@ Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +@ +@ Licensed under the OpenSSL license (the "License"). You may not use +@ this file except in compliance with the License. You can obtain a copy +@ in the file LICENSE in the source distribution or at +@ https://www.openssl.org/source/license.html + + +@ ==================================================================== +@ Written by Andy Polyakov for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Permission to use under GPL terms is granted. +@ ==================================================================== + +@ SHA512 block procedure for ARMv4. September 2007. + +@ This code is ~4.5 (four and a half) times faster than code generated +@ by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue +@ Xscale PXA250 core]. +@ +@ July 2010. +@ +@ Rescheduling for dual-issue pipeline resulted in 6% improvement on +@ Cortex A8 core and ~40 cycles per processed byte. + +@ February 2011. +@ +@ Profiler-assisted and platform-specific optimization resulted in 7% +@ improvement on Coxtex A8 core and ~38 cycles per byte. + +@ March 2011. +@ +@ Add NEON implementation. On Cortex A8 it was measured to process +@ one byte in 23.3 cycles or ~60% faster than integer-only code. + +@ August 2012. +@ +@ Improve NEON performance by 12% on Snapdragon S4. In absolute +@ terms it's 22.6 cycles per byte, which is disappointing result. +@ Technical writers asserted that 3-way S4 pipeline can sustain +@ multiple NEON instructions per cycle, but dual NEON issue could +@ not be observed, see http://www.openssl.org/~appro/Snapdragon-S4.html +@ for further details. On side note Cortex-A15 processes one byte in +@ 16 cycles. + +@ Byte order [in]dependence. ========================================= +@ +@ Originally caller was expected to maintain specific *dword* order in +@ h[0-7], namely with most significant dword at *lower* address, which +@ was reflected in below two parameters as 0 and 4. Now caller is +@ expected to maintain native byte order for whole 64-bit values. +#ifndef __KERNEL__ +# include +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +#else +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_MAX_ARCH__ 7 +# define VFP_ABI_PUSH +# define VFP_ABI_POP +#endif + +@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both +@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. +.arch armv7-a + +#ifdef __ARMEL__ +# define LO 0 +# define HI 4 +# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +#else +# define HI 0 +# define LO 4 +# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +#endif + +.text +#if defined(__thumb2__) +.syntax unified +.thumb +# define adrl adr +#else +.code 32 +#endif + +.type K512,%object +.align 5 +K512: + WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd) + WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc) + WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019) + WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118) + WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe) + WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2) + WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1) + WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694) + WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3) + WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65) + WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483) + WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5) + WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210) + WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4) + WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725) + WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70) + WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926) + WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df) + WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8) + WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b) + WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001) + WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30) + WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910) + WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8) + WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53) + WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8) + WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb) + WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3) + WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60) + WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec) + WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9) + WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b) + WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207) + WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178) + WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6) + WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b) + WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493) + WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c) + WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) + WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) +.size K512,.-K512 +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.Lsha512_block_data_order +.skip 32-4 +#else +.skip 32 +#endif + +.globl sha512_block_data_order +.hidden sha512_block_data_order +.type sha512_block_data_order,%function +sha512_block_data_order: +.Lsha512_block_data_order: +#if __ARM_ARCH__<7 && !defined(__thumb2__) + sub r3,pc,#8 @ sha512_block_data_order +#else + adr r3,.Lsha512_block_data_order +#endif +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) + ldr r12,.LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P +#ifdef __APPLE__ + ldr r12,[r12] +#endif + tst r12,#ARMV7_NEON + bne .LNEON +#endif + add r2,r1,r2,lsl#7 @ len to point at the end of inp + stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + sub r14,r3,#672 @ K512 + sub sp,sp,#9*8 + + ldr r7,[r0,#32+LO] + ldr r8,[r0,#32+HI] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] +.Loop: + str r9, [sp,#48+0] + str r10, [sp,#48+4] + str r11, [sp,#56+0] + str r12, [sp,#56+4] + ldr r5,[r0,#0+LO] + ldr r6,[r0,#0+HI] + ldr r3,[r0,#8+LO] + ldr r4,[r0,#8+HI] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + str r3,[sp,#8+0] + str r4,[sp,#8+4] + str r9, [sp,#16+0] + str r10, [sp,#16+4] + str r11, [sp,#24+0] + str r12, [sp,#24+4] + ldr r3,[r0,#40+LO] + ldr r4,[r0,#40+HI] + str r3,[sp,#40+0] + str r4,[sp,#40+4] + +.L00_15: +#if __ARM_ARCH__<7 + ldrb r3,[r1,#7] + ldrb r9, [r1,#6] + ldrb r10, [r1,#5] + ldrb r11, [r1,#4] + ldrb r4,[r1,#3] + ldrb r12, [r1,#2] + orr r3,r3,r9,lsl#8 + ldrb r9, [r1,#1] + orr r3,r3,r10,lsl#16 + ldrb r10, [r1],#8 + orr r3,r3,r11,lsl#24 + orr r4,r4,r12,lsl#8 + orr r4,r4,r9,lsl#16 + orr r4,r4,r10,lsl#24 +#else + ldr r3,[r1,#4] + ldr r4,[r1],#8 +#ifdef __ARMEL__ + rev r3,r3 + rev r4,r4 +#endif +#endif + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#148 + + ldr r12,[sp,#16+0] @ c.lo +#if __ARM_ARCH__>=7 + it eq @ Thumb2 thing, sanity check in ARM +#endif + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 + tst r14,#1 + beq .L00_15 + ldr r9,[sp,#184+0] + ldr r10,[sp,#184+4] + bic r14,r14,#1 +.L16_79: + @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 + @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 + mov r3,r9,lsr#1 + ldr r11,[sp,#80+0] + mov r4,r10,lsr#1 + ldr r12,[sp,#80+4] + eor r3,r3,r10,lsl#31 + eor r4,r4,r9,lsl#31 + eor r3,r3,r9,lsr#8 + eor r4,r4,r10,lsr#8 + eor r3,r3,r10,lsl#24 + eor r4,r4,r9,lsl#24 + eor r3,r3,r9,lsr#7 + eor r4,r4,r10,lsr#7 + eor r3,r3,r10,lsl#25 + + @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 + @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 + mov r9,r11,lsr#19 + mov r10,r12,lsr#19 + eor r9,r9,r12,lsl#13 + eor r10,r10,r11,lsl#13 + eor r9,r9,r12,lsr#29 + eor r10,r10,r11,lsr#29 + eor r9,r9,r11,lsl#3 + eor r10,r10,r12,lsl#3 + eor r9,r9,r11,lsr#6 + eor r10,r10,r12,lsr#6 + ldr r11,[sp,#120+0] + eor r9,r9,r12,lsl#26 + + ldr r12,[sp,#120+4] + adds r3,r3,r9 + ldr r9,[sp,#192+0] + adc r4,r4,r10 + + ldr r10,[sp,#192+4] + adds r3,r3,r11 + adc r4,r4,r12 + adds r3,r3,r9 + adc r4,r4,r10 + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov r9,r7,lsr#14 + str r3,[sp,#64+0] + mov r10,r8,lsr#14 + str r4,[sp,#64+4] + eor r9,r9,r8,lsl#18 + ldr r11,[sp,#56+0] @ h.lo + eor r10,r10,r7,lsl#18 + ldr r12,[sp,#56+4] @ h.hi + eor r9,r9,r7,lsr#18 + eor r10,r10,r8,lsr#18 + eor r9,r9,r8,lsl#14 + eor r10,r10,r7,lsl#14 + eor r9,r9,r8,lsr#9 + eor r10,r10,r7,lsr#9 + eor r9,r9,r7,lsl#23 + eor r10,r10,r8,lsl#23 @ Sigma1(e) + adds r3,r3,r9 + ldr r9,[sp,#40+0] @ f.lo + adc r4,r4,r10 @ T += Sigma1(e) + ldr r10,[sp,#40+4] @ f.hi + adds r3,r3,r11 + ldr r11,[sp,#48+0] @ g.lo + adc r4,r4,r12 @ T += h + ldr r12,[sp,#48+4] @ g.hi + + eor r9,r9,r11 + str r7,[sp,#32+0] + eor r10,r10,r12 + str r8,[sp,#32+4] + and r9,r9,r7 + str r5,[sp,#0+0] + and r10,r10,r8 + str r6,[sp,#0+4] + eor r9,r9,r11 + ldr r11,[r14,#LO] @ K[i].lo + eor r10,r10,r12 @ Ch(e,f,g) + ldr r12,[r14,#HI] @ K[i].hi + + adds r3,r3,r9 + ldr r7,[sp,#24+0] @ d.lo + adc r4,r4,r10 @ T += Ch(e,f,g) + ldr r8,[sp,#24+4] @ d.hi + adds r3,r3,r11 + and r9,r11,#0xff + adc r4,r4,r12 @ T += K[i] + adds r7,r7,r3 + ldr r11,[sp,#8+0] @ b.lo + adc r8,r8,r4 @ d += T + teq r9,#23 + + ldr r12,[sp,#16+0] @ c.lo +#if __ARM_ARCH__>=7 + it eq @ Thumb2 thing, sanity check in ARM +#endif + orreq r14,r14,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov r9,r5,lsr#28 + mov r10,r6,lsr#28 + eor r9,r9,r6,lsl#4 + eor r10,r10,r5,lsl#4 + eor r9,r9,r6,lsr#2 + eor r10,r10,r5,lsr#2 + eor r9,r9,r5,lsl#30 + eor r10,r10,r6,lsl#30 + eor r9,r9,r6,lsr#7 + eor r10,r10,r5,lsr#7 + eor r9,r9,r5,lsl#25 + eor r10,r10,r6,lsl#25 @ Sigma0(a) + adds r3,r3,r9 + and r9,r5,r11 + adc r4,r4,r10 @ T += Sigma0(a) + + ldr r10,[sp,#8+4] @ b.hi + orr r5,r5,r11 + ldr r11,[sp,#16+4] @ c.hi + and r5,r5,r12 + and r12,r6,r10 + orr r6,r6,r10 + orr r5,r5,r9 @ Maj(a,b,c).lo + and r6,r6,r11 + adds r5,r5,r3 + orr r6,r6,r12 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc r6,r6,r4 @ h += T + tst r14,#1 + add r14,r14,#8 +#if __ARM_ARCH__>=7 + ittt eq @ Thumb2 thing, sanity check in ARM +#endif + ldreq r9,[sp,#184+0] + ldreq r10,[sp,#184+4] + beq .L16_79 + bic r14,r14,#1 + + ldr r3,[sp,#8+0] + ldr r4,[sp,#8+4] + ldr r9, [r0,#0+LO] + ldr r10, [r0,#0+HI] + ldr r11, [r0,#8+LO] + ldr r12, [r0,#8+HI] + adds r9,r5,r9 + str r9, [r0,#0+LO] + adc r10,r6,r10 + str r10, [r0,#0+HI] + adds r11,r3,r11 + str r11, [r0,#8+LO] + adc r12,r4,r12 + str r12, [r0,#8+HI] + + ldr r5,[sp,#16+0] + ldr r6,[sp,#16+4] + ldr r3,[sp,#24+0] + ldr r4,[sp,#24+4] + ldr r9, [r0,#16+LO] + ldr r10, [r0,#16+HI] + ldr r11, [r0,#24+LO] + ldr r12, [r0,#24+HI] + adds r9,r5,r9 + str r9, [r0,#16+LO] + adc r10,r6,r10 + str r10, [r0,#16+HI] + adds r11,r3,r11 + str r11, [r0,#24+LO] + adc r12,r4,r12 + str r12, [r0,#24+HI] + + ldr r3,[sp,#40+0] + ldr r4,[sp,#40+4] + ldr r9, [r0,#32+LO] + ldr r10, [r0,#32+HI] + ldr r11, [r0,#40+LO] + ldr r12, [r0,#40+HI] + adds r7,r7,r9 + str r7,[r0,#32+LO] + adc r8,r8,r10 + str r8,[r0,#32+HI] + adds r11,r3,r11 + str r11, [r0,#40+LO] + adc r12,r4,r12 + str r12, [r0,#40+HI] + + ldr r5,[sp,#48+0] + ldr r6,[sp,#48+4] + ldr r3,[sp,#56+0] + ldr r4,[sp,#56+4] + ldr r9, [r0,#48+LO] + ldr r10, [r0,#48+HI] + ldr r11, [r0,#56+LO] + ldr r12, [r0,#56+HI] + adds r9,r5,r9 + str r9, [r0,#48+LO] + adc r10,r6,r10 + str r10, [r0,#48+HI] + adds r11,r3,r11 + str r11, [r0,#56+LO] + adc r12,r4,r12 + str r12, [r0,#56+HI] + + add sp,sp,#640 + sub r14,r14,#640 + + teq r1,r2 + bne .Loop + + add sp,sp,#8*9 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} +#else + ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet +.word 0xe12fff1e @ interoperable with Thumb ISA:-) +#endif +.size sha512_block_data_order,.-sha512_block_data_order +#if __ARM_MAX_ARCH__>=7 +.arch armv7-a +.fpu neon + +.globl sha512_block_data_order_neon +.hidden sha512_block_data_order_neon +.type sha512_block_data_order_neon,%function +.align 4 +sha512_block_data_order_neon: +.LNEON: + dmb @ errata #451034 on early Cortex A8 + add r2,r1,r2,lsl#7 @ len to point at the end of inp + adr r3,K512 + VFP_ABI_PUSH + vldmia r0,{d16,d17,d18,d19,d20,d21,d22,d23} @ load context +.Loop_neon: + vshr.u64 d24,d20,#14 @ 0 +#if 0<16 + vld1.64 {d0},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 +#if 0>0 + vadd.i64 d16,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 0<16 && defined(__ARMEL__) + vrev64.8 d0,d0 +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d0 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 1 +#if 1<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 1>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 1<16 && defined(__ARMEL__) + vrev64.8 d1,d1 +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d1 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 2 +#if 2<16 + vld1.64 {d2},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 +#if 2>0 + vadd.i64 d22,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 2<16 && defined(__ARMEL__) + vrev64.8 d2,d2 +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d2 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 3 +#if 3<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 3>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 3<16 && defined(__ARMEL__) + vrev64.8 d3,d3 +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d3 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 4 +#if 4<16 + vld1.64 {d4},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 +#if 4>0 + vadd.i64 d20,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 4<16 && defined(__ARMEL__) + vrev64.8 d4,d4 +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d4 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 5 +#if 5<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 5>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 5<16 && defined(__ARMEL__) + vrev64.8 d5,d5 +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d5 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 6 +#if 6<16 + vld1.64 {d6},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 +#if 6>0 + vadd.i64 d18,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 6<16 && defined(__ARMEL__) + vrev64.8 d6,d6 +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d6 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 7 +#if 7<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 7>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 7<16 && defined(__ARMEL__) + vrev64.8 d7,d7 +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d7 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + vshr.u64 d24,d20,#14 @ 8 +#if 8<16 + vld1.64 {d8},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d20,#18 +#if 8>0 + vadd.i64 d16,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d20,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 8<16 && defined(__ARMEL__) + vrev64.8 d8,d8 +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d8 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 9 +#if 9<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 9>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 9<16 && defined(__ARMEL__) + vrev64.8 d9,d9 +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d9 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 d24,d18,#14 @ 10 +#if 10<16 + vld1.64 {d10},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d18,#18 +#if 10>0 + vadd.i64 d22,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d18,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 10<16 && defined(__ARMEL__) + vrev64.8 d10,d10 +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d10 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 11 +#if 11<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 11>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 11<16 && defined(__ARMEL__) + vrev64.8 d11,d11 +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d11 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 d24,d16,#14 @ 12 +#if 12<16 + vld1.64 {d12},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d16,#18 +#if 12>0 + vadd.i64 d20,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d16,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 12<16 && defined(__ARMEL__) + vrev64.8 d12,d12 +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d12 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 13 +#if 13<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 13>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 13<16 && defined(__ARMEL__) + vrev64.8 d13,d13 +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d13 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 d24,d22,#14 @ 14 +#if 14<16 + vld1.64 {d14},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d22,#18 +#if 14>0 + vadd.i64 d18,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d22,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 14<16 && defined(__ARMEL__) + vrev64.8 d14,d14 +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d14 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 15 +#if 15<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 15>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 15<16 && defined(__ARMEL__) + vrev64.8 d15,d15 +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d15 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + mov r12,#4 +.L16_79_neon: + subs r12,#1 + vshr.u64 q12,q7,#19 + vshr.u64 q13,q7,#61 + vadd.i64 d16,d30 @ h+=Maj from the past + vshr.u64 q15,q7,#6 + vsli.64 q12,q7,#45 + vext.8 q14,q0,q1,#8 @ X[i+1] + vsli.64 q13,q7,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q0,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q4,q5,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q0,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q0,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 16<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d0 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 17 +#if 17<16 + vld1.64 {d1},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 17>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 17<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d1 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 q12,q0,#19 + vshr.u64 q13,q0,#61 + vadd.i64 d22,d30 @ h+=Maj from the past + vshr.u64 q15,q0,#6 + vsli.64 q12,q0,#45 + vext.8 q14,q1,q2,#8 @ X[i+1] + vsli.64 q13,q0,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q1,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q5,q6,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q1,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q1,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 18<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d2 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 19 +#if 19<16 + vld1.64 {d3},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 19>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 19<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d3 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 q12,q1,#19 + vshr.u64 q13,q1,#61 + vadd.i64 d20,d30 @ h+=Maj from the past + vshr.u64 q15,q1,#6 + vsli.64 q12,q1,#45 + vext.8 q14,q2,q3,#8 @ X[i+1] + vsli.64 q13,q1,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q2,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q6,q7,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q2,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q2,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 20<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d4 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 21 +#if 21<16 + vld1.64 {d5},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 21>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 21<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d5 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 q12,q2,#19 + vshr.u64 q13,q2,#61 + vadd.i64 d18,d30 @ h+=Maj from the past + vshr.u64 q15,q2,#6 + vsli.64 q12,q2,#45 + vext.8 q14,q3,q4,#8 @ X[i+1] + vsli.64 q13,q2,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q3,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q7,q0,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q3,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q3,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 22<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d6 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 23 +#if 23<16 + vld1.64 {d7},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 23>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 23<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d7 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + vshr.u64 q12,q3,#19 + vshr.u64 q13,q3,#61 + vadd.i64 d16,d30 @ h+=Maj from the past + vshr.u64 q15,q3,#6 + vsli.64 q12,q3,#45 + vext.8 q14,q4,q5,#8 @ X[i+1] + vsli.64 q13,q3,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q4,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q0,q1,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d20,#14 @ from NEON_00_15 + vadd.i64 q4,q14 + vshr.u64 d25,d20,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d20,#41 @ from NEON_00_15 + vadd.i64 q4,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d20,#50 + vsli.64 d25,d20,#46 + vmov d29,d20 + vsli.64 d26,d20,#23 +#if 24<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d21,d22 @ Ch(e,f,g) + vshr.u64 d24,d16,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d23 + vshr.u64 d25,d16,#34 + vsli.64 d24,d16,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d16,#39 + vadd.i64 d28,d8 + vsli.64 d25,d16,#30 + veor d30,d16,d17 + vsli.64 d26,d16,#25 + veor d23,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d18,d17 @ Maj(a,b,c) + veor d23,d26 @ Sigma0(a) + vadd.i64 d19,d27 + vadd.i64 d30,d27 + @ vadd.i64 d23,d30 + vshr.u64 d24,d19,#14 @ 25 +#if 25<16 + vld1.64 {d9},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d19,#18 +#if 25>0 + vadd.i64 d23,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d19,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d19,#50 + vsli.64 d25,d19,#46 + vmov d29,d19 + vsli.64 d26,d19,#23 +#if 25<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d20,d21 @ Ch(e,f,g) + vshr.u64 d24,d23,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d22 + vshr.u64 d25,d23,#34 + vsli.64 d24,d23,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d23,#39 + vadd.i64 d28,d9 + vsli.64 d25,d23,#30 + veor d30,d23,d16 + vsli.64 d26,d23,#25 + veor d22,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d17,d16 @ Maj(a,b,c) + veor d22,d26 @ Sigma0(a) + vadd.i64 d18,d27 + vadd.i64 d30,d27 + @ vadd.i64 d22,d30 + vshr.u64 q12,q4,#19 + vshr.u64 q13,q4,#61 + vadd.i64 d22,d30 @ h+=Maj from the past + vshr.u64 q15,q4,#6 + vsli.64 q12,q4,#45 + vext.8 q14,q5,q6,#8 @ X[i+1] + vsli.64 q13,q4,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q5,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q1,q2,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d18,#14 @ from NEON_00_15 + vadd.i64 q5,q14 + vshr.u64 d25,d18,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d18,#41 @ from NEON_00_15 + vadd.i64 q5,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d18,#50 + vsli.64 d25,d18,#46 + vmov d29,d18 + vsli.64 d26,d18,#23 +#if 26<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d19,d20 @ Ch(e,f,g) + vshr.u64 d24,d22,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d21 + vshr.u64 d25,d22,#34 + vsli.64 d24,d22,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d22,#39 + vadd.i64 d28,d10 + vsli.64 d25,d22,#30 + veor d30,d22,d23 + vsli.64 d26,d22,#25 + veor d21,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d16,d23 @ Maj(a,b,c) + veor d21,d26 @ Sigma0(a) + vadd.i64 d17,d27 + vadd.i64 d30,d27 + @ vadd.i64 d21,d30 + vshr.u64 d24,d17,#14 @ 27 +#if 27<16 + vld1.64 {d11},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d17,#18 +#if 27>0 + vadd.i64 d21,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d17,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d17,#50 + vsli.64 d25,d17,#46 + vmov d29,d17 + vsli.64 d26,d17,#23 +#if 27<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d18,d19 @ Ch(e,f,g) + vshr.u64 d24,d21,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d20 + vshr.u64 d25,d21,#34 + vsli.64 d24,d21,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d21,#39 + vadd.i64 d28,d11 + vsli.64 d25,d21,#30 + veor d30,d21,d22 + vsli.64 d26,d21,#25 + veor d20,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d23,d22 @ Maj(a,b,c) + veor d20,d26 @ Sigma0(a) + vadd.i64 d16,d27 + vadd.i64 d30,d27 + @ vadd.i64 d20,d30 + vshr.u64 q12,q5,#19 + vshr.u64 q13,q5,#61 + vadd.i64 d20,d30 @ h+=Maj from the past + vshr.u64 q15,q5,#6 + vsli.64 q12,q5,#45 + vext.8 q14,q6,q7,#8 @ X[i+1] + vsli.64 q13,q5,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q6,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q2,q3,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d16,#14 @ from NEON_00_15 + vadd.i64 q6,q14 + vshr.u64 d25,d16,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d16,#41 @ from NEON_00_15 + vadd.i64 q6,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d16,#50 + vsli.64 d25,d16,#46 + vmov d29,d16 + vsli.64 d26,d16,#23 +#if 28<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d17,d18 @ Ch(e,f,g) + vshr.u64 d24,d20,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d19 + vshr.u64 d25,d20,#34 + vsli.64 d24,d20,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d20,#39 + vadd.i64 d28,d12 + vsli.64 d25,d20,#30 + veor d30,d20,d21 + vsli.64 d26,d20,#25 + veor d19,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d22,d21 @ Maj(a,b,c) + veor d19,d26 @ Sigma0(a) + vadd.i64 d23,d27 + vadd.i64 d30,d27 + @ vadd.i64 d19,d30 + vshr.u64 d24,d23,#14 @ 29 +#if 29<16 + vld1.64 {d13},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d23,#18 +#if 29>0 + vadd.i64 d19,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d23,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d23,#50 + vsli.64 d25,d23,#46 + vmov d29,d23 + vsli.64 d26,d23,#23 +#if 29<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d16,d17 @ Ch(e,f,g) + vshr.u64 d24,d19,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d18 + vshr.u64 d25,d19,#34 + vsli.64 d24,d19,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d19,#39 + vadd.i64 d28,d13 + vsli.64 d25,d19,#30 + veor d30,d19,d20 + vsli.64 d26,d19,#25 + veor d18,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d21,d20 @ Maj(a,b,c) + veor d18,d26 @ Sigma0(a) + vadd.i64 d22,d27 + vadd.i64 d30,d27 + @ vadd.i64 d18,d30 + vshr.u64 q12,q6,#19 + vshr.u64 q13,q6,#61 + vadd.i64 d18,d30 @ h+=Maj from the past + vshr.u64 q15,q6,#6 + vsli.64 q12,q6,#45 + vext.8 q14,q7,q0,#8 @ X[i+1] + vsli.64 q13,q6,#3 + veor q15,q12 + vshr.u64 q12,q14,#1 + veor q15,q13 @ sigma1(X[i+14]) + vshr.u64 q13,q14,#8 + vadd.i64 q7,q15 + vshr.u64 q15,q14,#7 + vsli.64 q12,q14,#63 + vsli.64 q13,q14,#56 + vext.8 q14,q3,q4,#8 @ X[i+9] + veor q15,q12 + vshr.u64 d24,d22,#14 @ from NEON_00_15 + vadd.i64 q7,q14 + vshr.u64 d25,d22,#18 @ from NEON_00_15 + veor q15,q13 @ sigma0(X[i+1]) + vshr.u64 d26,d22,#41 @ from NEON_00_15 + vadd.i64 q7,q15 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d22,#50 + vsli.64 d25,d22,#46 + vmov d29,d22 + vsli.64 d26,d22,#23 +#if 30<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d23,d16 @ Ch(e,f,g) + vshr.u64 d24,d18,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d17 + vshr.u64 d25,d18,#34 + vsli.64 d24,d18,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d18,#39 + vadd.i64 d28,d14 + vsli.64 d25,d18,#30 + veor d30,d18,d19 + vsli.64 d26,d18,#25 + veor d17,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d20,d19 @ Maj(a,b,c) + veor d17,d26 @ Sigma0(a) + vadd.i64 d21,d27 + vadd.i64 d30,d27 + @ vadd.i64 d17,d30 + vshr.u64 d24,d21,#14 @ 31 +#if 31<16 + vld1.64 {d15},[r1]! @ handles unaligned +#endif + vshr.u64 d25,d21,#18 +#if 31>0 + vadd.i64 d17,d30 @ h+=Maj from the past +#endif + vshr.u64 d26,d21,#41 + vld1.64 {d28},[r3,:64]! @ K[i++] + vsli.64 d24,d21,#50 + vsli.64 d25,d21,#46 + vmov d29,d21 + vsli.64 d26,d21,#23 +#if 31<16 && defined(__ARMEL__) + vrev64.8 , +#endif + veor d25,d24 + vbsl d29,d22,d23 @ Ch(e,f,g) + vshr.u64 d24,d17,#28 + veor d26,d25 @ Sigma1(e) + vadd.i64 d27,d29,d16 + vshr.u64 d25,d17,#34 + vsli.64 d24,d17,#36 + vadd.i64 d27,d26 + vshr.u64 d26,d17,#39 + vadd.i64 d28,d15 + vsli.64 d25,d17,#30 + veor d30,d17,d18 + vsli.64 d26,d17,#25 + veor d16,d24,d25 + vadd.i64 d27,d28 + vbsl d30,d19,d18 @ Maj(a,b,c) + veor d16,d26 @ Sigma0(a) + vadd.i64 d20,d27 + vadd.i64 d30,d27 + @ vadd.i64 d16,d30 + bne .L16_79_neon + + vadd.i64 d16,d30 @ h+=Maj from the past + vldmia r0,{d24,d25,d26,d27,d28,d29,d30,d31} @ load context to temp + vadd.i64 q8,q12 @ vectorized accumulate + vadd.i64 q9,q13 + vadd.i64 q10,q14 + vadd.i64 q11,q15 + vstmia r0,{d16,d17,d18,d19,d20,d21,d22,d23} @ save context + teq r1,r2 + sub r3,#640 @ rewind K512 + bne .Loop_neon + + VFP_ABI_POP + bx lr @ .word 0xe12fff1e +.size sha512_block_data_order_neon,.-sha512_block_data_order_neon +#endif +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.comm OPENSSL_armcap_P,4,4 +.hidden OPENSSL_armcap_P +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S new file mode 100644 index 00000000..40167b7e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S @@ -0,0 +1,1621 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the OpenSSL license (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. + +#ifndef __KERNEL__ +# include +#endif + +.text + + +.private_extern _OPENSSL_armcap_P +.globl _sha512_block_data_order +.private_extern _sha512_block_data_order + +.align 6 +_sha512_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:_OPENSSL_armcap_P +#else + adrp x16,_OPENSSL_armcap_P@PAGE +#endif + ldr w16,[x16,_OPENSSL_armcap_P@PAGEOFF] + tst w16,#ARMV8_SHA512 + b.ne Lv8_entry +#endif + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*8 + + ldp x20,x21,[x0] // load context + ldp x22,x23,[x0,#2*8] + ldp x24,x25,[x0,#4*8] + add x2,x1,x2,lsl#7 // end of input + ldp x26,x27,[x0,#6*8] + adrp x30,LK512@PAGE + add x30,x30,LK512@PAGEOFF + stp x0,x2,[x29,#96] + +Loop: + ldp x3,x4,[x1],#2*8 + ldr x19,[x30],#8 // *K++ + eor x28,x21,x22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev x3,x3 // 0 +#endif + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x6,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x3 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x4,x4 // 1 +#endif + ldp x5,x6,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x7,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x4 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x5,x5 // 2 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x8,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x5 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x6,x6 // 3 +#endif + ldp x7,x8,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x9,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x6 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x7,x7 // 4 +#endif + add x24,x24,x17 // h+=Sigma0(a) + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x10,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x7 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x10,ror#18 // Sigma1(e) + ror x10,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x10,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x8,x8 // 5 +#endif + ldp x9,x10,[x1],#2*8 + add x23,x23,x17 // h+=Sigma0(a) + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x11,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x8 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x11,ror#18 // Sigma1(e) + ror x11,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x11,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x9,x9 // 6 +#endif + add x22,x22,x17 // h+=Sigma0(a) + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x12,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x9 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x12,ror#18 // Sigma1(e) + ror x12,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x12,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x10,x10 // 7 +#endif + ldp x11,x12,[x1],#2*8 + add x21,x21,x17 // h+=Sigma0(a) + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + eor x13,x25,x25,ror#23 + and x17,x26,x25 + bic x28,x27,x25 + add x20,x20,x10 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x13,ror#18 // Sigma1(e) + ror x13,x21,#28 + add x20,x20,x17 // h+=Ch(e,f,g) + eor x17,x21,x21,ror#5 + add x20,x20,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x24,x24,x20 // d+=h + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x13,x17,ror#34 // Sigma0(a) + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x11,x11 // 8 +#endif + add x20,x20,x17 // h+=Sigma0(a) + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x14,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x11 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x14,ror#18 // Sigma1(e) + ror x14,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x14,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x12,x12 // 9 +#endif + ldp x13,x14,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x15,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x12 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x15,ror#18 // Sigma1(e) + ror x15,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x15,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x13,x13 // 10 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x0,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x13 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x0,ror#18 // Sigma1(e) + ror x0,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x0,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x14,x14 // 11 +#endif + ldp x15,x0,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x6,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x14 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x15,x15 // 12 +#endif + add x24,x24,x17 // h+=Sigma0(a) + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x7,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x15 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x0,x0 // 13 +#endif + ldp x1,x2,[x1] + add x23,x23,x17 // h+=Sigma0(a) + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x8,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x0 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x1,x1 // 14 +#endif + ldr x6,[sp,#24] + add x22,x22,x17 // h+=Sigma0(a) + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x9,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x1 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x2,x2 // 15 +#endif + ldr x7,[sp,#0] + add x21,x21,x17 // h+=Sigma0(a) + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 +Loop_16_xx: + ldr x8,[sp,#8] + str x11,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x10,x5,#1 + and x17,x25,x24 + ror x9,x2,#19 + bic x19,x26,x24 + ror x11,x20,#28 + add x27,x27,x3 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x10,x10,x5,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x11,x11,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x9,x9,x2,ror#61 + eor x10,x10,x5,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x11,x20,ror#39 // Sigma0(a) + eor x9,x9,x2,lsr#6 // sigma1(X[i+14]) + add x4,x4,x13 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x4,x4,x10 + add x27,x27,x17 // h+=Sigma0(a) + add x4,x4,x9 + ldr x9,[sp,#16] + str x12,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x11,x6,#1 + and x17,x24,x23 + ror x10,x3,#19 + bic x28,x25,x23 + ror x12,x27,#28 + add x26,x26,x4 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x11,x11,x6,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x12,x12,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x10,x10,x3,ror#61 + eor x11,x11,x6,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x12,x27,ror#39 // Sigma0(a) + eor x10,x10,x3,lsr#6 // sigma1(X[i+14]) + add x5,x5,x14 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x5,x5,x11 + add x26,x26,x17 // h+=Sigma0(a) + add x5,x5,x10 + ldr x10,[sp,#24] + str x13,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x12,x7,#1 + and x17,x23,x22 + ror x11,x4,#19 + bic x19,x24,x22 + ror x13,x26,#28 + add x25,x25,x5 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x12,x12,x7,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x13,x13,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x11,x11,x4,ror#61 + eor x12,x12,x7,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x13,x26,ror#39 // Sigma0(a) + eor x11,x11,x4,lsr#6 // sigma1(X[i+14]) + add x6,x6,x15 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x6,x6,x12 + add x25,x25,x17 // h+=Sigma0(a) + add x6,x6,x11 + ldr x11,[sp,#0] + str x14,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x13,x8,#1 + and x17,x22,x21 + ror x12,x5,#19 + bic x28,x23,x21 + ror x14,x25,#28 + add x24,x24,x6 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x13,x13,x8,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x14,x14,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x12,x12,x5,ror#61 + eor x13,x13,x8,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x14,x25,ror#39 // Sigma0(a) + eor x12,x12,x5,lsr#6 // sigma1(X[i+14]) + add x7,x7,x0 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x7,x7,x13 + add x24,x24,x17 // h+=Sigma0(a) + add x7,x7,x12 + ldr x12,[sp,#8] + str x15,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x14,x9,#1 + and x17,x21,x20 + ror x13,x6,#19 + bic x19,x22,x20 + ror x15,x24,#28 + add x23,x23,x7 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x14,x14,x9,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x15,x15,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x13,x13,x6,ror#61 + eor x14,x14,x9,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x15,x24,ror#39 // Sigma0(a) + eor x13,x13,x6,lsr#6 // sigma1(X[i+14]) + add x8,x8,x1 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x8,x8,x14 + add x23,x23,x17 // h+=Sigma0(a) + add x8,x8,x13 + ldr x13,[sp,#16] + str x0,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x15,x10,#1 + and x17,x20,x27 + ror x14,x7,#19 + bic x28,x21,x27 + ror x0,x23,#28 + add x22,x22,x8 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x15,x15,x10,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x0,x0,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x14,x14,x7,ror#61 + eor x15,x15,x10,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x0,x23,ror#39 // Sigma0(a) + eor x14,x14,x7,lsr#6 // sigma1(X[i+14]) + add x9,x9,x2 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x9,x9,x15 + add x22,x22,x17 // h+=Sigma0(a) + add x9,x9,x14 + ldr x14,[sp,#24] + str x1,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x0,x11,#1 + and x17,x27,x26 + ror x15,x8,#19 + bic x19,x20,x26 + ror x1,x22,#28 + add x21,x21,x9 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x0,x0,x11,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x1,x1,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x15,x15,x8,ror#61 + eor x0,x0,x11,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x1,x22,ror#39 // Sigma0(a) + eor x15,x15,x8,lsr#6 // sigma1(X[i+14]) + add x10,x10,x3 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x10,x10,x0 + add x21,x21,x17 // h+=Sigma0(a) + add x10,x10,x15 + ldr x15,[sp,#0] + str x2,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x1,x12,#1 + and x17,x26,x25 + ror x0,x9,#19 + bic x28,x27,x25 + ror x2,x21,#28 + add x20,x20,x10 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x1,x1,x12,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x2,x2,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x0,x0,x9,ror#61 + eor x1,x1,x12,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x2,x21,ror#39 // Sigma0(a) + eor x0,x0,x9,lsr#6 // sigma1(X[i+14]) + add x11,x11,x4 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x11,x11,x1 + add x20,x20,x17 // h+=Sigma0(a) + add x11,x11,x0 + ldr x0,[sp,#8] + str x3,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x2,x13,#1 + and x17,x25,x24 + ror x1,x10,#19 + bic x19,x26,x24 + ror x3,x20,#28 + add x27,x27,x11 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x2,x2,x13,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x3,x3,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x1,x1,x10,ror#61 + eor x2,x2,x13,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x3,x20,ror#39 // Sigma0(a) + eor x1,x1,x10,lsr#6 // sigma1(X[i+14]) + add x12,x12,x5 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x12,x12,x2 + add x27,x27,x17 // h+=Sigma0(a) + add x12,x12,x1 + ldr x1,[sp,#16] + str x4,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x3,x14,#1 + and x17,x24,x23 + ror x2,x11,#19 + bic x28,x25,x23 + ror x4,x27,#28 + add x26,x26,x12 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x3,x3,x14,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x4,x4,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x2,x2,x11,ror#61 + eor x3,x3,x14,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x4,x27,ror#39 // Sigma0(a) + eor x2,x2,x11,lsr#6 // sigma1(X[i+14]) + add x13,x13,x6 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x13,x13,x3 + add x26,x26,x17 // h+=Sigma0(a) + add x13,x13,x2 + ldr x2,[sp,#24] + str x5,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x4,x15,#1 + and x17,x23,x22 + ror x3,x12,#19 + bic x19,x24,x22 + ror x5,x26,#28 + add x25,x25,x13 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x4,x4,x15,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x5,x5,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x3,x3,x12,ror#61 + eor x4,x4,x15,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x5,x26,ror#39 // Sigma0(a) + eor x3,x3,x12,lsr#6 // sigma1(X[i+14]) + add x14,x14,x7 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x14,x14,x4 + add x25,x25,x17 // h+=Sigma0(a) + add x14,x14,x3 + ldr x3,[sp,#0] + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x5,x0,#1 + and x17,x22,x21 + ror x4,x13,#19 + bic x28,x23,x21 + ror x6,x25,#28 + add x24,x24,x14 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x5,x5,x0,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x6,x6,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x4,x4,x13,ror#61 + eor x5,x5,x0,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x25,ror#39 // Sigma0(a) + eor x4,x4,x13,lsr#6 // sigma1(X[i+14]) + add x15,x15,x8 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x15,x15,x5 + add x24,x24,x17 // h+=Sigma0(a) + add x15,x15,x4 + ldr x4,[sp,#8] + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x6,x1,#1 + and x17,x21,x20 + ror x5,x14,#19 + bic x19,x22,x20 + ror x7,x24,#28 + add x23,x23,x15 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x6,x6,x1,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x7,x7,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x5,x5,x14,ror#61 + eor x6,x6,x1,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x24,ror#39 // Sigma0(a) + eor x5,x5,x14,lsr#6 // sigma1(X[i+14]) + add x0,x0,x9 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x0,x0,x6 + add x23,x23,x17 // h+=Sigma0(a) + add x0,x0,x5 + ldr x5,[sp,#16] + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x7,x2,#1 + and x17,x20,x27 + ror x6,x15,#19 + bic x28,x21,x27 + ror x8,x23,#28 + add x22,x22,x0 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x7,x7,x2,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x8,x8,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x6,x6,x15,ror#61 + eor x7,x7,x2,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x23,ror#39 // Sigma0(a) + eor x6,x6,x15,lsr#6 // sigma1(X[i+14]) + add x1,x1,x10 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x1,x1,x7 + add x22,x22,x17 // h+=Sigma0(a) + add x1,x1,x6 + ldr x6,[sp,#24] + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x8,x3,#1 + and x17,x27,x26 + ror x7,x0,#19 + bic x19,x20,x26 + ror x9,x22,#28 + add x21,x21,x1 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x8,x8,x3,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x9,x9,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x7,x7,x0,ror#61 + eor x8,x8,x3,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x22,ror#39 // Sigma0(a) + eor x7,x7,x0,lsr#6 // sigma1(X[i+14]) + add x2,x2,x11 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x2,x2,x8 + add x21,x21,x17 // h+=Sigma0(a) + add x2,x2,x7 + ldr x7,[sp,#0] + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 + cbnz x19,Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#648 // rewind + + ldp x3,x4,[x0] + ldp x5,x6,[x0,#2*8] + add x1,x1,#14*8 // advance input pointer + ldp x7,x8,[x0,#4*8] + add x20,x20,x3 + ldp x9,x10,[x0,#6*8] + add x21,x21,x4 + add x22,x22,x5 + add x23,x23,x6 + stp x20,x21,[x0] + add x24,x24,x7 + add x25,x25,x8 + stp x22,x23,[x0,#2*8] + add x26,x26,x9 + add x27,x27,x10 + cmp x1,x2 + stp x24,x25,[x0,#4*8] + stp x26,x27,[x0,#6*8] + b.ne Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*8 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.section __TEXT,__const +.align 6 + +LK512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0 // terminator + +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +.text +#ifndef __KERNEL__ + +.align 6 +sha512_block_armv8: +Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adrp x3,LK512@PAGE + add x3,x3,LK512@PAGEOFF + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b Loop_hw + +.align 4 +Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret + +#endif +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S new file mode 100644 index 00000000..e715e58d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S @@ -0,0 +1,1624 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the OpenSSL license (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. + +#ifndef __KERNEL__ +# include +#endif + +.text + + +.hidden OPENSSL_armcap_P +.globl sha512_block_data_order +.hidden sha512_block_data_order +.type sha512_block_data_order,%function +.align 6 +sha512_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x16,OPENSSL_armcap_P +#endif + ldr w16,[x16,:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA512 + b.ne .Lv8_entry +#endif + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*8 + + ldp x20,x21,[x0] // load context + ldp x22,x23,[x0,#2*8] + ldp x24,x25,[x0,#4*8] + add x2,x1,x2,lsl#7 // end of input + ldp x26,x27,[x0,#6*8] + adrp x30,.LK512 + add x30,x30,:lo12:.LK512 + stp x0,x2,[x29,#96] + +.Loop: + ldp x3,x4,[x1],#2*8 + ldr x19,[x30],#8 // *K++ + eor x28,x21,x22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev x3,x3 // 0 +#endif + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x6,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x3 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x4,x4 // 1 +#endif + ldp x5,x6,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x7,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x4 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x5,x5 // 2 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x8,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x5 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x6,x6 // 3 +#endif + ldp x7,x8,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x9,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x6 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x7,x7 // 4 +#endif + add x24,x24,x17 // h+=Sigma0(a) + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x10,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x7 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x10,ror#18 // Sigma1(e) + ror x10,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x10,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x8,x8 // 5 +#endif + ldp x9,x10,[x1],#2*8 + add x23,x23,x17 // h+=Sigma0(a) + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x11,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x8 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x11,ror#18 // Sigma1(e) + ror x11,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x11,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x9,x9 // 6 +#endif + add x22,x22,x17 // h+=Sigma0(a) + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x12,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x9 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x12,ror#18 // Sigma1(e) + ror x12,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x12,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x10,x10 // 7 +#endif + ldp x11,x12,[x1],#2*8 + add x21,x21,x17 // h+=Sigma0(a) + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + eor x13,x25,x25,ror#23 + and x17,x26,x25 + bic x28,x27,x25 + add x20,x20,x10 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x13,ror#18 // Sigma1(e) + ror x13,x21,#28 + add x20,x20,x17 // h+=Ch(e,f,g) + eor x17,x21,x21,ror#5 + add x20,x20,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x24,x24,x20 // d+=h + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x13,x17,ror#34 // Sigma0(a) + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x11,x11 // 8 +#endif + add x20,x20,x17 // h+=Sigma0(a) + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x14,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x11 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x14,ror#18 // Sigma1(e) + ror x14,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x14,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x12,x12 // 9 +#endif + ldp x13,x14,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x15,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x12 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x15,ror#18 // Sigma1(e) + ror x15,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x15,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x13,x13 // 10 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x0,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x13 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x0,ror#18 // Sigma1(e) + ror x0,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x0,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x14,x14 // 11 +#endif + ldp x15,x0,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x6,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x14 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x15,x15 // 12 +#endif + add x24,x24,x17 // h+=Sigma0(a) + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x7,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x15 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x0,x0 // 13 +#endif + ldp x1,x2,[x1] + add x23,x23,x17 // h+=Sigma0(a) + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x8,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x0 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x1,x1 // 14 +#endif + ldr x6,[sp,#24] + add x22,x22,x17 // h+=Sigma0(a) + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x9,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x1 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x2,x2 // 15 +#endif + ldr x7,[sp,#0] + add x21,x21,x17 // h+=Sigma0(a) + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 +.Loop_16_xx: + ldr x8,[sp,#8] + str x11,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x10,x5,#1 + and x17,x25,x24 + ror x9,x2,#19 + bic x19,x26,x24 + ror x11,x20,#28 + add x27,x27,x3 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x10,x10,x5,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x11,x11,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x9,x9,x2,ror#61 + eor x10,x10,x5,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x11,x20,ror#39 // Sigma0(a) + eor x9,x9,x2,lsr#6 // sigma1(X[i+14]) + add x4,x4,x13 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x4,x4,x10 + add x27,x27,x17 // h+=Sigma0(a) + add x4,x4,x9 + ldr x9,[sp,#16] + str x12,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x11,x6,#1 + and x17,x24,x23 + ror x10,x3,#19 + bic x28,x25,x23 + ror x12,x27,#28 + add x26,x26,x4 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x11,x11,x6,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x12,x12,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x10,x10,x3,ror#61 + eor x11,x11,x6,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x12,x27,ror#39 // Sigma0(a) + eor x10,x10,x3,lsr#6 // sigma1(X[i+14]) + add x5,x5,x14 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x5,x5,x11 + add x26,x26,x17 // h+=Sigma0(a) + add x5,x5,x10 + ldr x10,[sp,#24] + str x13,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x12,x7,#1 + and x17,x23,x22 + ror x11,x4,#19 + bic x19,x24,x22 + ror x13,x26,#28 + add x25,x25,x5 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x12,x12,x7,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x13,x13,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x11,x11,x4,ror#61 + eor x12,x12,x7,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x13,x26,ror#39 // Sigma0(a) + eor x11,x11,x4,lsr#6 // sigma1(X[i+14]) + add x6,x6,x15 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x6,x6,x12 + add x25,x25,x17 // h+=Sigma0(a) + add x6,x6,x11 + ldr x11,[sp,#0] + str x14,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x13,x8,#1 + and x17,x22,x21 + ror x12,x5,#19 + bic x28,x23,x21 + ror x14,x25,#28 + add x24,x24,x6 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x13,x13,x8,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x14,x14,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x12,x12,x5,ror#61 + eor x13,x13,x8,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x14,x25,ror#39 // Sigma0(a) + eor x12,x12,x5,lsr#6 // sigma1(X[i+14]) + add x7,x7,x0 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x7,x7,x13 + add x24,x24,x17 // h+=Sigma0(a) + add x7,x7,x12 + ldr x12,[sp,#8] + str x15,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x14,x9,#1 + and x17,x21,x20 + ror x13,x6,#19 + bic x19,x22,x20 + ror x15,x24,#28 + add x23,x23,x7 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x14,x14,x9,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x15,x15,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x13,x13,x6,ror#61 + eor x14,x14,x9,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x15,x24,ror#39 // Sigma0(a) + eor x13,x13,x6,lsr#6 // sigma1(X[i+14]) + add x8,x8,x1 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x8,x8,x14 + add x23,x23,x17 // h+=Sigma0(a) + add x8,x8,x13 + ldr x13,[sp,#16] + str x0,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x15,x10,#1 + and x17,x20,x27 + ror x14,x7,#19 + bic x28,x21,x27 + ror x0,x23,#28 + add x22,x22,x8 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x15,x15,x10,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x0,x0,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x14,x14,x7,ror#61 + eor x15,x15,x10,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x0,x23,ror#39 // Sigma0(a) + eor x14,x14,x7,lsr#6 // sigma1(X[i+14]) + add x9,x9,x2 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x9,x9,x15 + add x22,x22,x17 // h+=Sigma0(a) + add x9,x9,x14 + ldr x14,[sp,#24] + str x1,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x0,x11,#1 + and x17,x27,x26 + ror x15,x8,#19 + bic x19,x20,x26 + ror x1,x22,#28 + add x21,x21,x9 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x0,x0,x11,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x1,x1,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x15,x15,x8,ror#61 + eor x0,x0,x11,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x1,x22,ror#39 // Sigma0(a) + eor x15,x15,x8,lsr#6 // sigma1(X[i+14]) + add x10,x10,x3 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x10,x10,x0 + add x21,x21,x17 // h+=Sigma0(a) + add x10,x10,x15 + ldr x15,[sp,#0] + str x2,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x1,x12,#1 + and x17,x26,x25 + ror x0,x9,#19 + bic x28,x27,x25 + ror x2,x21,#28 + add x20,x20,x10 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x1,x1,x12,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x2,x2,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x0,x0,x9,ror#61 + eor x1,x1,x12,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x2,x21,ror#39 // Sigma0(a) + eor x0,x0,x9,lsr#6 // sigma1(X[i+14]) + add x11,x11,x4 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x11,x11,x1 + add x20,x20,x17 // h+=Sigma0(a) + add x11,x11,x0 + ldr x0,[sp,#8] + str x3,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x2,x13,#1 + and x17,x25,x24 + ror x1,x10,#19 + bic x19,x26,x24 + ror x3,x20,#28 + add x27,x27,x11 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x2,x2,x13,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x3,x3,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x1,x1,x10,ror#61 + eor x2,x2,x13,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x3,x20,ror#39 // Sigma0(a) + eor x1,x1,x10,lsr#6 // sigma1(X[i+14]) + add x12,x12,x5 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x12,x12,x2 + add x27,x27,x17 // h+=Sigma0(a) + add x12,x12,x1 + ldr x1,[sp,#16] + str x4,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x3,x14,#1 + and x17,x24,x23 + ror x2,x11,#19 + bic x28,x25,x23 + ror x4,x27,#28 + add x26,x26,x12 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x3,x3,x14,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x4,x4,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x2,x2,x11,ror#61 + eor x3,x3,x14,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x4,x27,ror#39 // Sigma0(a) + eor x2,x2,x11,lsr#6 // sigma1(X[i+14]) + add x13,x13,x6 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x13,x13,x3 + add x26,x26,x17 // h+=Sigma0(a) + add x13,x13,x2 + ldr x2,[sp,#24] + str x5,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x4,x15,#1 + and x17,x23,x22 + ror x3,x12,#19 + bic x19,x24,x22 + ror x5,x26,#28 + add x25,x25,x13 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x4,x4,x15,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x5,x5,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x3,x3,x12,ror#61 + eor x4,x4,x15,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x5,x26,ror#39 // Sigma0(a) + eor x3,x3,x12,lsr#6 // sigma1(X[i+14]) + add x14,x14,x7 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x14,x14,x4 + add x25,x25,x17 // h+=Sigma0(a) + add x14,x14,x3 + ldr x3,[sp,#0] + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x5,x0,#1 + and x17,x22,x21 + ror x4,x13,#19 + bic x28,x23,x21 + ror x6,x25,#28 + add x24,x24,x14 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x5,x5,x0,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x6,x6,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x4,x4,x13,ror#61 + eor x5,x5,x0,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x25,ror#39 // Sigma0(a) + eor x4,x4,x13,lsr#6 // sigma1(X[i+14]) + add x15,x15,x8 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x15,x15,x5 + add x24,x24,x17 // h+=Sigma0(a) + add x15,x15,x4 + ldr x4,[sp,#8] + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x6,x1,#1 + and x17,x21,x20 + ror x5,x14,#19 + bic x19,x22,x20 + ror x7,x24,#28 + add x23,x23,x15 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x6,x6,x1,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x7,x7,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x5,x5,x14,ror#61 + eor x6,x6,x1,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x24,ror#39 // Sigma0(a) + eor x5,x5,x14,lsr#6 // sigma1(X[i+14]) + add x0,x0,x9 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x0,x0,x6 + add x23,x23,x17 // h+=Sigma0(a) + add x0,x0,x5 + ldr x5,[sp,#16] + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x7,x2,#1 + and x17,x20,x27 + ror x6,x15,#19 + bic x28,x21,x27 + ror x8,x23,#28 + add x22,x22,x0 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x7,x7,x2,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x8,x8,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x6,x6,x15,ror#61 + eor x7,x7,x2,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x23,ror#39 // Sigma0(a) + eor x6,x6,x15,lsr#6 // sigma1(X[i+14]) + add x1,x1,x10 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x1,x1,x7 + add x22,x22,x17 // h+=Sigma0(a) + add x1,x1,x6 + ldr x6,[sp,#24] + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x8,x3,#1 + and x17,x27,x26 + ror x7,x0,#19 + bic x19,x20,x26 + ror x9,x22,#28 + add x21,x21,x1 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x8,x8,x3,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x9,x9,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x7,x7,x0,ror#61 + eor x8,x8,x3,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x22,ror#39 // Sigma0(a) + eor x7,x7,x0,lsr#6 // sigma1(X[i+14]) + add x2,x2,x11 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x2,x2,x8 + add x21,x21,x17 // h+=Sigma0(a) + add x2,x2,x7 + ldr x7,[sp,#0] + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 + cbnz x19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#648 // rewind + + ldp x3,x4,[x0] + ldp x5,x6,[x0,#2*8] + add x1,x1,#14*8 // advance input pointer + ldp x7,x8,[x0,#4*8] + add x20,x20,x3 + ldp x9,x10,[x0,#6*8] + add x21,x21,x4 + add x22,x22,x5 + add x23,x23,x6 + stp x20,x21,[x0] + add x24,x24,x7 + add x25,x25,x8 + stp x22,x23,[x0,#2*8] + add x26,x26,x9 + add x27,x27,x10 + cmp x1,x2 + stp x24,x25,[x0,#4*8] + stp x26,x27,[x0,#6*8] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*8 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size sha512_block_data_order,.-sha512_block_data_order + +.section .rodata +.align 6 +.type .LK512,%object +.LK512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0 // terminator +.size .LK512,.-.LK512 +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +.text +#ifndef __KERNEL__ +.type sha512_block_armv8,%function +.align 6 +sha512_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adrp x3,.LK512 + add x3,x3,:lo12:.LK512 + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b .Loop_hw + +.align 4 +.Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,.Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret +.size sha512_block_armv8,.-sha512_block_armv8 +#endif +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S new file mode 100644 index 00000000..2d0f335c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S @@ -0,0 +1,2999 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P +.globl sha512_block_data_order +.hidden sha512_block_data_order +.type sha512_block_data_order,@function +.align 16 +sha512_block_data_order: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue: + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop + +.align 16 +.Lloop: + movq %rbx,%rdi + leaq K512(%rip),%rbp + xorq %rcx,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + addq %r14,%rax + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 72(%rsp),%r12 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 16(%rsp),%r13 + movq 120(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 80(%rsp),%r12 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 24(%rsp),%r13 + movq 0(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 88(%rsp),%r12 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 32(%rsp),%r13 + movq 8(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 96(%rsp),%r12 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 40(%rsp),%r13 + movq 16(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 104(%rsp),%r12 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 48(%rsp),%r13 + movq 24(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 112(%rsp),%r12 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 56(%rsp),%r13 + movq 32(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 120(%rsp),%r12 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 64(%rsp),%r13 + movq 40(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 0(%rsp),%r12 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + movq 72(%rsp),%r13 + movq 48(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 8(%rsp),%r12 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 80(%rsp),%r13 + movq 56(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 16(%rsp),%r12 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 88(%rsp),%r13 + movq 64(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 24(%rsp),%r12 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 96(%rsp),%r13 + movq 72(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 32(%rsp),%r12 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 104(%rsp),%r13 + movq 80(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 40(%rsp),%r12 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 112(%rsp),%r13 + movq 88(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 48(%rsp),%r12 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 120(%rsp),%r13 + movq 96(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 56(%rsp),%r12 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 0(%rsp),%r13 + movq 104(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 64(%rsp),%r12 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + cmpb $0,7(%rbp) + jnz .Lrounds_16_xx + + movq 128+0(%rsp),%rdi + addq %r14,%rax + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop + + movq 152(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order,.-sha512_block_data_order +.align 64 +.type K512,@object +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 + +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.type sha512_block_data_order_avx,@function +.align 64 +sha512_block_data_order_avx: +.cfi_startproc +.Lavx_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue_avx: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm0,%xmm0 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 0(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm7,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm7,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm7,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 8(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm0,%xmm0 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm1,%xmm1 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 16(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm0,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm0,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm0,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 24(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm1,%xmm1 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm2,%xmm2 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 32(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm1,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm1,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm1,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 40(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm2,%xmm2 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm3,%xmm3 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 48(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm2,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm2,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm2,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 56(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm3,%xmm3 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm4,%xmm4 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 64(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm3,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm3,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm3,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 72(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm4,%xmm4 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm5,%xmm5 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 80(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm4,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm4,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm4,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 88(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm5,%xmm5 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm6,%xmm6 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 96(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm5,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm5,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm5,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 104(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm6,%xmm6 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm7,%xmm7 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 112(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm6,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm6,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm6,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 120(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm7,%xmm7 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne .Lavx_00_47 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop_avx + + movq 152(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order_avx,.-sha512_block_data_order_avx +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S new file mode 100644 index 00000000..5c00a6f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S @@ -0,0 +1,2997 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + +.globl _sha512_block_data_order +.private_extern _sha512_block_data_order + +.p2align 4 +_sha512_block_data_order: + + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je L$avx_shortcut + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) + +L$prologue: + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp L$loop + +.p2align 4 +L$loop: + movq %rbx,%rdi + leaq K512(%rip),%rbp + xorq %rcx,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + addq %r14,%rax + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + jmp L$rounds_16_xx +.p2align 4 +L$rounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 72(%rsp),%r12 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 16(%rsp),%r13 + movq 120(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 80(%rsp),%r12 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 24(%rsp),%r13 + movq 0(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 88(%rsp),%r12 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 32(%rsp),%r13 + movq 8(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 96(%rsp),%r12 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 40(%rsp),%r13 + movq 16(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 104(%rsp),%r12 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 48(%rsp),%r13 + movq 24(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 112(%rsp),%r12 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 56(%rsp),%r13 + movq 32(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 120(%rsp),%r12 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 64(%rsp),%r13 + movq 40(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 0(%rsp),%r12 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + movq 72(%rsp),%r13 + movq 48(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 8(%rsp),%r12 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 80(%rsp),%r13 + movq 56(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 16(%rsp),%r12 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 88(%rsp),%r13 + movq 64(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 24(%rsp),%r12 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 96(%rsp),%r13 + movq 72(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 32(%rsp),%r12 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 104(%rsp),%r13 + movq 80(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 40(%rsp),%r12 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 112(%rsp),%r13 + movq 88(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 48(%rsp),%r12 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 120(%rsp),%r13 + movq 96(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 56(%rsp),%r12 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 0(%rsp),%r13 + movq 104(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 64(%rsp),%r12 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + cmpb $0,7(%rbp) + jnz L$rounds_16_xx + + movq 128+0(%rsp),%rdi + addq %r14,%rax + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb L$loop + + movq 152(%rsp),%rsi + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue: + .byte 0xf3,0xc3 + + +.p2align 6 + +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 + +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + +.p2align 6 +sha512_block_data_order_avx: + +L$avx_shortcut: + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) + +L$prologue_avx: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp L$loop_avx +.p2align 4 +L$loop_avx: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp L$avx_00_47 + +.p2align 4 +L$avx_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm0,%xmm0 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 0(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm7,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm7,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm7,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 8(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm0,%xmm0 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm1,%xmm1 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 16(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm0,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm0,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm0,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 24(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm1,%xmm1 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm2,%xmm2 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 32(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm1,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm1,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm1,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 40(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm2,%xmm2 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm3,%xmm3 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 48(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm2,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm2,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm2,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 56(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm3,%xmm3 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm4,%xmm4 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 64(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm3,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm3,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm3,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 72(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm4,%xmm4 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm5,%xmm5 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 80(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm4,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm4,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm4,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 88(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm5,%xmm5 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm6,%xmm6 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 96(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm5,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm5,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm5,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 104(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm6,%xmm6 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm7,%xmm7 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 112(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm6,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm6,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm6,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 120(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm7,%xmm7 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne L$avx_00_47 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb L$loop_avx + + movq 152(%rsp),%rsi + + vzeroupper + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$epilogue_avx: + .byte 0xf3,0xc3 + + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/internal.h new file mode 100644 index 00000000..feb4a2ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/internal.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// tls1_prf calculates |out_len| bytes of the TLS PDF, using |digest|, and +// writes them to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/kdf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/kdf.c new file mode 100644 index 00000000..cf5d4405 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/tls/kdf.c @@ -0,0 +1,165 @@ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// tls1_P_hash computes the TLS P_ function as described in RFC 5246, +// section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and +// |secret| as the secret. |label|, |seed1|, and |seed2| are concatenated to +// form the seed parameter. It returns true on success and false on failure. +static int tls1_P_hash(uint8_t *out, size_t out_len, + const EVP_MD *md, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + HMAC_CTX ctx, ctx_tmp, ctx_init; + uint8_t A1[EVP_MAX_MD_SIZE]; + unsigned A1_len; + int ret = 0; + + const size_t chunk = EVP_MD_size(md); + HMAC_CTX_init(&ctx); + HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_init(&ctx_init); + + if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) || + !HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, A1, &A1_len)) { + goto err; + } + + for (;;) { + unsigned len; + uint8_t hmac[EVP_MAX_MD_SIZE]; + if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, A1, A1_len) || + // Save a copy of |ctx| to compute the next A1 value below. + (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, hmac, &len)) { + goto err; + } + assert(len == chunk); + + // XOR the result into |out|. + if (len > out_len) { + len = out_len; + } + for (unsigned i = 0; i < len; i++) { + out[i] ^= hmac[i]; + } + out += len; + out_len -= len; + + if (out_len == 0) { + break; + } + + // Calculate the next A1 value. + if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_cleanse(A1, sizeof(A1)); + HMAC_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&ctx_tmp); + HMAC_CTX_cleanup(&ctx_init); + return ret; +} + +int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + if (out_len == 0) { + return 1; + } + + OPENSSL_memset(out, 0, out_len); + + if (digest == EVP_md5_sha1()) { + // If using the MD5/SHA1 PRF, |secret| is partitioned between MD5 and SHA-1. + size_t secret_half = secret_len - (secret_len / 2); + if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half, label, + label_len, seed1, seed1_len, seed2, seed2_len)) { + return 0; + } + + // Note that, if |secret_len| is odd, the two halves share a byte. + secret += secret_len - secret_half; + secret_len = secret_half; + digest = EVP_sha1(); + } + + return tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, + seed1, seed1_len, seed2, seed2_len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S new file mode 100644 index 00000000..37912592 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S @@ -0,0 +1,1272 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.syntax unified + + + + +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif + +.text + + +.align 7 @ totally strategic alignment +_vpaes_consts: +Lk_mc_forward:@ mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +Lk_mc_backward:@ mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +Lk_sr:@ sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +@ +@ "Hot" constants +@ +Lk_inv:@ inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +Lk_ipt:@ input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +Lk_sbo:@ sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +Lk_sb1:@ sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +Lk_sb2:@ sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,55,32,78,69,79,78,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 + +.align 6 +@@ +@@ _aes_preheat +@@ +@@ Fills q9-q15 as specified below. +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_preheat +#endif +.align 4 +_vpaes_preheat: + adr r10, Lk_inv + vmov.i8 q9, #0x0f @ Lk_s0F + vld1.64 {q10,q11}, [r10]! @ Lk_inv + add r10, r10, #64 @ Skip Lk_ipt, Lk_sbo + vld1.64 {q12,q13}, [r10]! @ Lk_sb1 + vld1.64 {q14,q15}, [r10] @ Lk_sb2 + bx lr + +@@ +@@ _aes_encrypt_core +@@ +@@ AES-encrypt q0. +@@ +@@ Inputs: +@@ q0 = input +@@ q9-q15 as in _vpaes_preheat +@@ [r2] = scheduled keys +@@ +@@ Output in q0 +@@ Clobbers q1-q5, r8-r11 +@@ Preserves q6-q8 so you get some local vectors +@@ +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_encrypt_core +#endif +.align 4 +_vpaes_encrypt_core: + mov r9, r2 + ldr r8, [r2,#240] @ pull rounds + adr r11, Lk_ipt + @ vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + @ vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + vld1.64 {q2, q3}, [r11] + adr r11, Lk_mc_forward+16 + vld1.64 {q5}, [r9]! @ vmovdqu (%r9), %xmm5 # round0 key + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d2, {q2}, d2 @ vpshufb %xmm1, %xmm2, %xmm1 + vtbl.8 d3, {q2}, d3 + vtbl.8 d4, {q3}, d0 @ vpshufb %xmm0, %xmm3, %xmm2 + vtbl.8 d5, {q3}, d1 + veor q0, q1, q5 @ vpxor %xmm5, %xmm1, %xmm0 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + + @ .Lenc_entry ends with a bnz instruction which is normally paired with + @ subs in .Lenc_loop. + tst r8, r8 + b Lenc_entry + +.align 4 +Lenc_loop: + @ middle of middle round + add r10, r11, #0x40 + vtbl.8 d8, {q13}, d4 @ vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + vtbl.8 d9, {q13}, d5 + vld1.64 {q1}, [r11]! @ vmovdqa -0x40(%r11,%r10), %xmm1 # Lk_mc_forward[] + vtbl.8 d0, {q12}, d6 @ vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + vtbl.8 d1, {q12}, d7 + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + vtbl.8 d10, {q15}, d4 @ vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + vtbl.8 d11, {q15}, d5 + veor q0, q0, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = A + vtbl.8 d4, {q14}, d6 @ vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + vtbl.8 d5, {q14}, d7 + vld1.64 {q4}, [r10] @ vmovdqa (%r11,%r10), %xmm4 # Lk_mc_backward[] + vtbl.8 d6, {q0}, d2 @ vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + vtbl.8 d7, {q0}, d3 + veor q2, q2, q5 @ vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + @ Write to q5 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d10, {q0}, d8 @ vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + vtbl.8 d11, {q0}, d9 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + vtbl.8 d8, {q3}, d2 @ vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + vtbl.8 d9, {q3}, d3 + @ Here we restore the original q0/q5 usage. + veor q0, q5, q3 @ vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and r11, r11, #~(1<<6) @ and $0x30, %r11 # ... mod 4 + veor q0, q0, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + subs r8, r8, #1 @ nr-- + +Lenc_entry: + @ top of round + vand q1, q0, q9 @ vpand %xmm0, %xmm9, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + vtbl.8 d10, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + vtbl.8 d11, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q3, q3, q5 @ vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + vtbl.8 d5, {q10}, d7 + vtbl.8 d6, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + vtbl.8 d7, {q10}, d9 + veor q2, q2, q1 @ vpxor %xmm1, %xmm2, %xmm2 # 2 = io + veor q3, q3, q0 @ vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + vld1.64 {q5}, [r9]! @ vmovdqu (%r9), %xmm5 + bne Lenc_loop + + @ middle of last round + add r10, r11, #0x80 + + adr r11, Lk_sbo + @ Read to q1 instead of q4, so the vtbl.8 instruction below does not + @ overlap table and destination registers. + vld1.64 {q1}, [r11]! @ vmovdqa -0x60(%r10), %xmm4 # 3 : sbou + vld1.64 {q0}, [r11] @ vmovdqa -0x50(%r10), %xmm0 # 0 : sbot Lk_sbo+16 + vtbl.8 d8, {q1}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + vtbl.8 d9, {q1}, d5 + vld1.64 {q1}, [r10] @ vmovdqa 0x40(%r11,%r10), %xmm1 # Lk_sr[] + @ Write to q2 instead of q0 below, to avoid overlapping table and + @ destination registers. + vtbl.8 d4, {q0}, d6 @ vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + vtbl.8 d5, {q0}, d7 + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + veor q2, q2, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = A + @ Here we restore the original q0/q2 usage. + vtbl.8 d0, {q2}, d2 @ vpshufb %xmm1, %xmm0, %xmm0 + vtbl.8 d1, {q2}, d3 + bx lr + + +.globl _vpaes_encrypt +.private_extern _vpaes_encrypt +#ifdef __thumb2__ +.thumb_func _vpaes_encrypt +#endif +.align 4 +_vpaes_encrypt: + @ _vpaes_encrypt_core uses r8-r11. Round up to r7-r11 to maintain stack + @ alignment. + stmdb sp!, {r7,r8,r9,r10,r11,lr} + @ _vpaes_encrypt_core uses q4-q5 (d8-d11), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11} + + vld1.64 {q0}, [r0] + bl _vpaes_preheat + bl _vpaes_encrypt_core + vst1.64 {q0}, [r1] + + vldmia sp!, {d8,d9,d10,d11} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return + + +@ +@ Decryption stuff +@ + +.align 4 +_vpaes_decrypt_consts: +Lk_dipt:@ decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +Lk_dsbo:@ decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +Lk_dsb9:@ decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +Lk_dsbd:@ decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +Lk_dsbb:@ decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +Lk_dsbe:@ decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 + + +@@ +@@ Decryption core +@@ +@@ Same API as encryption core, except it clobbers q12-q15 rather than using +@@ the values from _vpaes_preheat. q9-q11 must still be set from +@@ _vpaes_preheat. +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_decrypt_core +#endif +.align 4 +_vpaes_decrypt_core: + mov r9, r2 + ldr r8, [r2,#240] @ pull rounds + + @ This function performs shuffles with various constants. The x86_64 + @ version loads them on-demand into %xmm0-%xmm5. This does not work well + @ for ARMv7 because those registers are shuffle destinations. The ARMv8 + @ version preloads those constants into registers, but ARMv7 has half + @ the registers to work with. Instead, we load them on-demand into + @ q12-q15, registers normally use for preloaded constants. This is fine + @ because decryption doesn't use those constants. The values are + @ constant, so this does not interfere with potential 2x optimizations. + adr r7, Lk_dipt + + vld1.64 {q12,q13}, [r7] @ vmovdqa Lk_dipt(%rip), %xmm2 # iptlo + lsl r11, r8, #4 @ mov %rax, %r11; shl $4, %r11 + eor r11, r11, #0x30 @ xor $0x30, %r11 + adr r10, Lk_sr + and r11, r11, #0x30 @ and $0x30, %r11 + add r11, r11, r10 + adr r10, Lk_mc_forward+48 + + vld1.64 {q4}, [r9]! @ vmovdqu (%r9), %xmm4 # round0 key + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d4, {q12}, d2 @ vpshufb %xmm1, %xmm2, %xmm2 + vtbl.8 d5, {q12}, d3 + vld1.64 {q5}, [r10] @ vmovdqa Lk_mc_forward+48(%rip), %xmm5 + @ vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + vtbl.8 d0, {q13}, d0 @ vpshufb %xmm0, %xmm1, %xmm0 + vtbl.8 d1, {q13}, d1 + veor q2, q2, q4 @ vpxor %xmm4, %xmm2, %xmm2 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + + @ .Ldec_entry ends with a bnz instruction which is normally paired with + @ subs in .Ldec_loop. + tst r8, r8 + b Ldec_entry + +.align 4 +Ldec_loop: +@ +@ Inverse mix columns +@ + + @ We load .Lk_dsb* into q12-q15 on-demand. See the comment at the top of + @ the function. + adr r10, Lk_dsb9 + vld1.64 {q12,q13}, [r10]! @ vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + @ vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + @ Load sbd* ahead of time. + vld1.64 {q14,q15}, [r10]! @ vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + @ vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + vtbl.8 d8, {q12}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + vtbl.8 d9, {q12}, d5 + vtbl.8 d2, {q13}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + vtbl.8 d3, {q13}, d7 + veor q0, q4, q0 @ vpxor %xmm4, %xmm0, %xmm0 + + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + + @ Load sbb* ahead of time. + vld1.64 {q12,q13}, [r10]! @ vmovdqa 0x20(%r10),%xmm4 # 4 : sbbu + @ vmovdqa 0x30(%r10),%xmm1 # 0 : sbbt + + vtbl.8 d8, {q14}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + vtbl.8 d9, {q14}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q15}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + vtbl.8 d3, {q15}, d7 + @ vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + @ vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + @ Load sbd* ahead of time. + vld1.64 {q14,q15}, [r10]! @ vmovdqa 0x40(%r10),%xmm4 # 4 : sbeu + @ vmovdqa 0x50(%r10),%xmm1 # 0 : sbet + + vtbl.8 d8, {q12}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + vtbl.8 d9, {q12}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q13}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + vtbl.8 d3, {q13}, d7 + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + + vtbl.8 d8, {q14}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + vtbl.8 d9, {q14}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q15}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + vtbl.8 d3, {q15}, d7 + vext.8 q5, q5, q5, #12 @ vpalignr $12, %xmm5, %xmm5, %xmm5 + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + subs r8, r8, #1 @ sub $1,%rax # nr-- + +Ldec_entry: + @ top of round + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + vtbl.8 d4, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + vtbl.8 d5, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + veor q4, q4, q2 @ vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + vtbl.8 d5, {q10}, d7 + vtbl.8 d6, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + vtbl.8 d7, {q10}, d9 + veor q2, q2, q1 @ vpxor %xmm1, %xmm2, %xmm2 # 2 = io + veor q3, q3, q0 @ vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + vld1.64 {q0}, [r9]! @ vmovdqu (%r9), %xmm0 + bne Ldec_loop + + @ middle of last round + + adr r10, Lk_dsbo + + @ Write to q1 rather than q4 to avoid overlapping table and destination. + vld1.64 {q1}, [r10]! @ vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + vtbl.8 d8, {q1}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + vtbl.8 d9, {q1}, d5 + @ Write to q2 rather than q1 to avoid overlapping table and destination. + vld1.64 {q2}, [r10] @ vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + vtbl.8 d2, {q2}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + vtbl.8 d3, {q2}, d7 + vld1.64 {q2}, [r11] @ vmovdqa -0x160(%r11), %xmm2 # Lk_sr-Lk_dsbd=-0x160 + veor q4, q4, q0 @ vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + @ Write to q1 rather than q0 so the table and destination registers + @ below do not overlap. + veor q1, q1, q4 @ vpxor %xmm4, %xmm1, %xmm0 # 0 = A + vtbl.8 d0, {q1}, d4 @ vpshufb %xmm2, %xmm0, %xmm0 + vtbl.8 d1, {q1}, d5 + bx lr + + +.globl _vpaes_decrypt +.private_extern _vpaes_decrypt +#ifdef __thumb2__ +.thumb_func _vpaes_decrypt +#endif +.align 4 +_vpaes_decrypt: + @ _vpaes_decrypt_core uses r7-r11. + stmdb sp!, {r7,r8,r9,r10,r11,lr} + @ _vpaes_decrypt_core uses q4-q5 (d8-d11), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11} + + vld1.64 {q0}, [r0] + bl _vpaes_preheat + bl _vpaes_decrypt_core + vst1.64 {q0}, [r1] + + vldmia sp!, {d8,d9,d10,d11} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@ @@ +@@ AES key schedule @@ +@@ @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@ This function diverges from both x86_64 and armv7 in which constants are +@ pinned. x86_64 has a common preheat function for all operations. aarch64 +@ separates them because it has enough registers to pin nearly all constants. +@ armv7 does not have enough registers, but needing explicit loads and stores +@ also complicates using x86_64's register allocation directly. +@ +@ We pin some constants for convenience and leave q14 and q15 free to load +@ others on demand. + +@ +@ Key schedule constants +@ + +.align 4 +_vpaes_key_consts: +Lk_dksd:@ decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +Lk_dksb:@ decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +Lk_dkse:@ decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +Lk_dks9:@ decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +Lk_rcon:@ rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +Lk_opt:@ output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +Lk_deskew:@ deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + + +#ifdef __thumb2__ +.thumb_func _vpaes_key_preheat +#endif +.align 4 +_vpaes_key_preheat: + adr r11, Lk_rcon + vmov.i8 q12, #0x5b @ Lk_s63 + adr r10, Lk_inv @ Must be aligned to 8 mod 16. + vmov.i8 q9, #0x0f @ Lk_s0F + vld1.64 {q10,q11}, [r10] @ Lk_inv + vld1.64 {q8}, [r11] @ Lk_rcon + bx lr + + +#ifdef __thumb2__ +.thumb_func _vpaes_schedule_core +#endif +.align 4 +_vpaes_schedule_core: + @ We only need to save lr, but ARM requires an 8-byte stack alignment, + @ so save an extra register. + stmdb sp!, {r3,lr} + + bl _vpaes_key_preheat @ load the tables + + adr r11, Lk_ipt @ Must be aligned to 8 mod 16. + vld1.64 {q0}, [r0]! @ vmovdqu (%rdi), %xmm0 # load key (unaligned) + + @ input transform + @ Use q4 here rather than q3 so .Lschedule_am_decrypting does not + @ overlap table and destination. + vmov q4, q0 @ vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + adr r10, Lk_sr @ Must be aligned to 8 mod 16. + vmov q7, q0 @ vmovdqa %xmm0, %xmm7 + + add r8, r8, r10 + tst r3, r3 + bne Lschedule_am_decrypting + + @ encrypting, output zeroth round key after transform + vst1.64 {q0}, [r2] @ vmovdqu %xmm0, (%rdx) + b Lschedule_go + +Lschedule_am_decrypting: + @ decrypting, output zeroth round key after shiftrows + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + vtbl.8 d6, {q4}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q4}, d3 + vst1.64 {q3}, [r2] @ vmovdqu %xmm3, (%rdx) + eor r8, r8, #0x30 @ xor $0x30, %r8 + +Lschedule_go: + cmp r1, #192 @ cmp $192, %esi + bhi Lschedule_256 + beq Lschedule_192 + @ 128: fall though + +@@ +@@ .schedule_128 +@@ +@@ 128-bit specific part of key schedule. +@@ +@@ This schedule is really simple, because all its parts +@@ are accomplished by the subroutines. +@@ +Lschedule_128: + mov r0, #10 @ mov $10, %esi + +Loop_schedule_128: + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq Lschedule_mangle_last + bl _vpaes_schedule_mangle @ write output + b Loop_schedule_128 + +@@ +@@ .aes_schedule_192 +@@ +@@ 192-bit specific part of key schedule. +@@ +@@ The main body of this schedule is the same as the 128-bit +@@ schedule, but with more smearing. The long, high side is +@@ stored in q7 as before, and the short, low side is in +@@ the high bits of q6. +@@ +@@ This schedule is somewhat nastier, however, because each +@@ round produces 192 bits of key material, or 1.5 round keys. +@@ Therefore, on each cycle we do 2 rounds and produce 3 round +@@ keys. +@@ +.align 4 +Lschedule_192: + sub r0, r0, #8 + vld1.64 {q0}, [r0] @ vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform @ input transform + vmov q6, q0 @ vmovdqa %xmm0, %xmm6 # save short part + vmov.i8 d12, #0 @ vpxor %xmm4, %xmm4, %xmm4 # clear 4 + @ vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov r0, #4 @ mov $4, %esi + +Loop_schedule_192: + bl _vpaes_schedule_round + vext.8 q0, q6, q0, #8 @ vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle @ save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle @ save key n+1 + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq Lschedule_mangle_last + bl _vpaes_schedule_mangle @ save key n+2 + bl _vpaes_schedule_192_smear + b Loop_schedule_192 + +@@ +@@ .aes_schedule_256 +@@ +@@ 256-bit specific part of key schedule. +@@ +@@ The structure here is very similar to the 128-bit +@@ schedule, but with an additional "low side" in +@@ q6. The low side's rounds are the same as the +@@ high side's, except no rcon and no rotation. +@@ +.align 4 +Lschedule_256: + vld1.64 {q0}, [r0] @ vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform @ input transform + mov r0, #7 @ mov $7, %esi + +Loop_schedule_256: + bl _vpaes_schedule_mangle @ output low result + vmov q6, q0 @ vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + @ high round + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq Lschedule_mangle_last + bl _vpaes_schedule_mangle + + @ low round. swap xmm7 and xmm6 + vdup.32 q0, d1[1] @ vpshufd $0xFF, %xmm0, %xmm0 + vmov.i8 q4, #0 + vmov q5, q7 @ vmovdqa %xmm7, %xmm5 + vmov q7, q6 @ vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + vmov q7, q5 @ vmovdqa %xmm5, %xmm7 + + b Loop_schedule_256 + +@@ +@@ .aes_schedule_mangle_last +@@ +@@ Mangler for last round of key schedule +@@ Mangles q0 +@@ when encrypting, outputs out(q0) ^ 63 +@@ when decrypting, outputs unskew(q0) +@@ +@@ Always called right before return... jumps to cleanup and exits +@@ +.align 4 +Lschedule_mangle_last: + @ schedule last round key from xmm0 + adr r11, Lk_deskew @ lea Lk_deskew(%rip),%r11 # prepare to deskew + tst r3, r3 + bne Lschedule_mangle_last_dec + + @ encrypting + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10),%xmm1 + adr r11, Lk_opt @ lea Lk_opt(%rip), %r11 # prepare to output transform + add r2, r2, #32 @ add $32, %rdx + vmov q2, q0 + vtbl.8 d0, {q2}, d2 @ vpshufb %xmm1, %xmm0, %xmm0 # output permute + vtbl.8 d1, {q2}, d3 + +Lschedule_mangle_last_dec: + sub r2, r2, #16 @ add $-16, %rdx + veor q0, q0, q12 @ vpxor Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform @ output transform + vst1.64 {q0}, [r2] @ vmovdqu %xmm0, (%rdx) # save last key + + @ cleanup + veor q0, q0, q0 @ vpxor %xmm0, %xmm0, %xmm0 + veor q1, q1, q1 @ vpxor %xmm1, %xmm1, %xmm1 + veor q2, q2, q2 @ vpxor %xmm2, %xmm2, %xmm2 + veor q3, q3, q3 @ vpxor %xmm3, %xmm3, %xmm3 + veor q4, q4, q4 @ vpxor %xmm4, %xmm4, %xmm4 + veor q5, q5, q5 @ vpxor %xmm5, %xmm5, %xmm5 + veor q6, q6, q6 @ vpxor %xmm6, %xmm6, %xmm6 + veor q7, q7, q7 @ vpxor %xmm7, %xmm7, %xmm7 + ldmia sp!, {r3,pc} @ return + + +@@ +@@ .aes_schedule_192_smear +@@ +@@ Smear the short, low side in the 192-bit key schedule. +@@ +@@ Inputs: +@@ q7: high side, b a x y +@@ q6: low side, d c 0 0 +@@ +@@ Outputs: +@@ q6: b+c+d b+c 0 0 +@@ q0: b+c+d b+c b a +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_schedule_192_smear +#endif +.align 4 +_vpaes_schedule_192_smear: + vmov.i8 q1, #0 + vdup.32 q0, d15[1] + vshl.i64 q1, q6, #32 @ vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + vmov d0, d15 @ vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + veor q6, q6, q1 @ vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + veor q1, q1, q1 @ vpxor %xmm1, %xmm1, %xmm1 + veor q6, q6, q0 @ vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + vmov q0, q6 @ vmovdqa %xmm6, %xmm0 + vmov d12, d2 @ vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + bx lr + + +@@ +@@ .aes_schedule_round +@@ +@@ Runs one main round of the key schedule on q0, q7 +@@ +@@ Specifically, runs subbytes on the high dword of q0 +@@ then rotates it by one byte and xors into the low dword of +@@ q7. +@@ +@@ Adds rcon from low byte of q8, then rotates q8 for +@@ next rcon. +@@ +@@ Smears the dwords of q7 by xoring the low into the +@@ second low, result into third, result into highest. +@@ +@@ Returns results in q7 = q0. +@@ Clobbers q1-q4, r11. +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_schedule_round +#endif +.align 4 +_vpaes_schedule_round: + @ extract rcon from xmm8 + vmov.i8 q4, #0 @ vpxor %xmm4, %xmm4, %xmm4 + vext.8 q1, q8, q4, #15 @ vpalignr $15, %xmm8, %xmm4, %xmm1 + vext.8 q8, q8, q8, #15 @ vpalignr $15, %xmm8, %xmm8, %xmm8 + veor q7, q7, q1 @ vpxor %xmm1, %xmm7, %xmm7 + + @ rotate + vdup.32 q0, d1[1] @ vpshufd $0xFF, %xmm0, %xmm0 + vext.8 q0, q0, q0, #1 @ vpalignr $1, %xmm0, %xmm0, %xmm0 + + @ fall through... + + @ low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + @ The x86_64 version pins .Lk_sb1 in %xmm13 and .Lk_sb1+16 in %xmm12. + @ We pin other values in _vpaes_key_preheat, so load them now. + adr r11, Lk_sb1 + vld1.64 {q14,q15}, [r11] + + @ smear xmm7 + vext.8 q1, q4, q7, #12 @ vpslldq $4, %xmm7, %xmm1 + veor q7, q7, q1 @ vpxor %xmm1, %xmm7, %xmm7 + vext.8 q4, q4, q7, #8 @ vpslldq $8, %xmm7, %xmm4 + + @ subbytes + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + veor q7, q7, q4 @ vpxor %xmm4, %xmm7, %xmm7 + vtbl.8 d4, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + vtbl.8 d5, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q7, q7, q12 @ vpxor Lk_s63(%rip), %xmm7, %xmm7 + vtbl.8 d6, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + vtbl.8 d7, {q10}, d7 + veor q4, q4, q2 @ vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + vtbl.8 d5, {q10}, d9 + veor q3, q3, q1 @ vpxor %xmm1, %xmm3, %xmm3 # 2 = io + veor q2, q2, q0 @ vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + vtbl.8 d8, {q15}, d6 @ vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + vtbl.8 d9, {q15}, d7 + vtbl.8 d2, {q14}, d4 @ vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + vtbl.8 d3, {q14}, d5 + veor q1, q1, q4 @ vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + @ add in smeared stuff + veor q0, q1, q7 @ vpxor %xmm7, %xmm1, %xmm0 + veor q7, q1, q7 @ vmovdqa %xmm0, %xmm7 + bx lr + + +@@ +@@ .aes_schedule_transform +@@ +@@ Linear-transform q0 according to tables at [r11] +@@ +@@ Requires that q9 = 0x0F0F... as in preheat +@@ Output in q0 +@@ Clobbers q1, q2, q14, q15 +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_schedule_transform +#endif +.align 4 +_vpaes_schedule_transform: + vld1.64 {q14,q15}, [r11] @ vmovdqa (%r11), %xmm2 # lo + @ vmovdqa 16(%r11), %xmm1 # hi + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d4, {q14}, d2 @ vpshufb %xmm1, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d3 + vtbl.8 d0, {q15}, d0 @ vpshufb %xmm0, %xmm1, %xmm0 + vtbl.8 d1, {q15}, d1 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + bx lr + + +@@ +@@ .aes_schedule_mangle +@@ +@@ Mangles q0 from (basis-transformed) standard version +@@ to our version. +@@ +@@ On encrypt, +@@ xor with 0x63 +@@ multiply by circulant 0,1,1,1 +@@ apply shiftrows transform +@@ +@@ On decrypt, +@@ xor with 0x63 +@@ multiply by "inverse mixcolumns" circulant E,B,D,9 +@@ deskew +@@ apply shiftrows transform +@@ +@@ +@@ Writes out to [r2], and increments or decrements it +@@ Keeps track of round number mod 4 in r8 +@@ Preserves q0 +@@ Clobbers q1-q5 +@@ +#ifdef __thumb2__ +.thumb_func _vpaes_schedule_mangle +#endif +.align 4 +_vpaes_schedule_mangle: + tst r3, r3 + vmov q4, q0 @ vmovdqa %xmm0, %xmm4 # save xmm0 for later + adr r11, Lk_mc_forward @ Must be aligned to 8 mod 16. + vld1.64 {q5}, [r11] @ vmovdqa Lk_mc_forward(%rip),%xmm5 + bne Lschedule_mangle_dec + + @ encrypting + @ Write to q2 so we do not overlap table and destination below. + veor q2, q0, q12 @ vpxor Lk_s63(%rip), %xmm0, %xmm4 + add r2, r2, #16 @ add $16, %rdx + vtbl.8 d8, {q2}, d10 @ vpshufb %xmm5, %xmm4, %xmm4 + vtbl.8 d9, {q2}, d11 + vtbl.8 d2, {q4}, d10 @ vpshufb %xmm5, %xmm4, %xmm1 + vtbl.8 d3, {q4}, d11 + vtbl.8 d6, {q1}, d10 @ vpshufb %xmm5, %xmm1, %xmm3 + vtbl.8 d7, {q1}, d11 + veor q4, q4, q1 @ vpxor %xmm1, %xmm4, %xmm4 + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + veor q3, q3, q4 @ vpxor %xmm4, %xmm3, %xmm3 + + b Lschedule_mangle_both +.align 4 +Lschedule_mangle_dec: + @ inverse mix columns + adr r11, Lk_dksd @ lea Lk_dksd(%rip),%r11 + vshr.u8 q1, q4, #4 @ vpsrlb $4, %xmm4, %xmm1 # 1 = hi + vand q4, q4, q9 @ vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x00(%r11), %xmm2 + @ vmovdqa 0x10(%r11), %xmm3 + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dksb ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x20(%r11), %xmm2 + @ vmovdqa 0x30(%r11), %xmm3 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dkse ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x40(%r11), %xmm2 + @ vmovdqa 0x50(%r11), %xmm3 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dkse ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x60(%r11), %xmm2 + @ vmovdqa 0x70(%r11), %xmm4 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + vtbl.8 d8, {q15}, d2 @ vpshufb %xmm1, %xmm4, %xmm4 + vtbl.8 d9, {q15}, d3 + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + veor q3, q4, q2 @ vpxor %xmm2, %xmm4, %xmm3 + + sub r2, r2, #16 @ add $-16, %rdx + +Lschedule_mangle_both: + @ Write to q2 so table and destination do not overlap. + vtbl.8 d4, {q3}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d5, {q3}, d3 + add r8, r8, #64-16 @ add $-16, %r8 + and r8, r8, #~(1<<6) @ and $0x30, %r8 + vst1.64 {q2}, [r2] @ vmovdqu %xmm3, (%rdx) + bx lr + + +.globl _vpaes_set_encrypt_key +.private_extern _vpaes_set_encrypt_key +#ifdef __thumb2__ +.thumb_func _vpaes_set_encrypt_key +#endif +.align 4 +_vpaes_set_encrypt_key: + stmdb sp!, {r7,r8,r9,r10,r11, lr} + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + lsr r9, r1, #5 @ shr $5,%eax + add r9, r9, #5 @ $5,%eax + str r9, [r2,#240] @ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov r3, #0 @ mov $0,%ecx + mov r8, #0x30 @ mov $0x30,%r8d + bl _vpaes_schedule_core + eor r0, r0, r0 + + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return + + +.globl _vpaes_set_decrypt_key +.private_extern _vpaes_set_decrypt_key +#ifdef __thumb2__ +.thumb_func _vpaes_set_decrypt_key +#endif +.align 4 +_vpaes_set_decrypt_key: + stmdb sp!, {r7,r8,r9,r10,r11, lr} + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + lsr r9, r1, #5 @ shr $5,%eax + add r9, r9, #5 @ $5,%eax + str r9, [r2,#240] @ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl r9, r9, #4 @ shl $4,%eax + add r2, r2, #16 @ lea 16(%rdx,%rax),%rdx + add r2, r2, r9 + + mov r3, #1 @ mov $1,%ecx + lsr r8, r1, #1 @ shr $1,%r8d + and r8, r8, #32 @ and $32,%r8d + eor r8, r8, #32 @ xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return + + +@ Additional constants for converting to bsaes. + +.align 4 +_vpaes_convert_consts: +@ .Lk_opt_then_skew applies skew(opt(x)) XOR 0x63, where skew is the linear +@ transform in the AES S-box. 0x63 is incorporated into the low half of the +@ table. This was computed with the following script: +@ +@ def u64s_to_u128(x, y): +@ return x | (y << 64) +@ def u128_to_u64s(w): +@ return w & ((1<<64)-1), w >> 64 +@ def get_byte(w, i): +@ return (w >> (i*8)) & 0xff +@ def apply_table(table, b): +@ lo = b & 0xf +@ hi = b >> 4 +@ return get_byte(table[0], lo) ^ get_byte(table[1], hi) +@ def opt(b): +@ table = [ +@ u64s_to_u128(0xFF9F4929D6B66000, 0xF7974121DEBE6808), +@ u64s_to_u128(0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0), +@ ] +@ return apply_table(table, b) +@ def rot_byte(b, n): +@ return 0xff & ((b << n) | (b >> (8-n))) +@ def skew(x): +@ return (x ^ rot_byte(x, 1) ^ rot_byte(x, 2) ^ rot_byte(x, 3) ^ +@ rot_byte(x, 4)) +@ table = [0, 0] +@ for i in range(16): +@ table[0] |= (skew(opt(i)) ^ 0x63) << (i*8) +@ table[1] |= skew(opt(i<<4)) << (i*8) +@ print(" .quad 0x%016x, 0x%016x" % u128_to_u64s(table[0])) +@ print(" .quad 0x%016x, 0x%016x" % u128_to_u64s(table[1])) +Lk_opt_then_skew: +.quad 0x9cb8436798bc4763, 0x6440bb9f6044bf9b +.quad 0x1f30062936192f00, 0xb49bad829db284ab + +@ .Lk_decrypt_transform is a permutation which performs an 8-bit left-rotation +@ followed by a byte-swap on each 32-bit word of a vector. E.g., 0x11223344 +@ becomes 0x22334411 and then 0x11443322. +Lk_decrypt_transform: +.quad 0x0704050603000102, 0x0f0c0d0e0b08090a + + +@ void vpaes_encrypt_key_to_bsaes(AES_KEY *bsaes, const AES_KEY *vpaes); +.globl _vpaes_encrypt_key_to_bsaes +.private_extern _vpaes_encrypt_key_to_bsaes +#ifdef __thumb2__ +.thumb_func _vpaes_encrypt_key_to_bsaes +#endif +.align 4 +_vpaes_encrypt_key_to_bsaes: + stmdb sp!, {r11, lr} + + @ See _vpaes_schedule_core for the key schedule logic. In particular, + @ _vpaes_schedule_transform(.Lk_ipt) (section 2.2 of the paper), + @ _vpaes_schedule_mangle (section 4.3), and .Lschedule_mangle_last + @ contain the transformations not in the bsaes representation. This + @ function inverts those transforms. + @ + @ Note also that bsaes-armv7.pl expects aes-armv4.pl's key + @ representation, which does not match the other aes_nohw_* + @ implementations. The ARM aes_nohw_* stores each 32-bit word + @ byteswapped, as a convenience for (unsupported) big-endian ARM, at the + @ cost of extra REV and VREV32 operations in little-endian ARM. + + vmov.i8 q9, #0x0f @ Required by _vpaes_schedule_transform + adr r2, Lk_mc_forward @ Must be aligned to 8 mod 16. + add r3, r2, 0x90 @ Lk_sr+0x10-Lk_mc_forward = 0x90 (Apple's toolchain doesn't support the expression) + + vld1.64 {q12}, [r2] + vmov.i8 q10, #0x5b @ Lk_s63 from vpaes-x86_64 + adr r11, Lk_opt @ Must be aligned to 8 mod 16. + vmov.i8 q11, #0x63 @ LK_s63 without Lk_ipt applied + + @ vpaes stores one fewer round count than bsaes, but the number of keys + @ is the same. + ldr r2, [r1,#240] + add r2, r2, #1 + str r2, [r0,#240] + + @ The first key is transformed with _vpaes_schedule_transform(.Lk_ipt). + @ Invert this with .Lk_opt. + vld1.64 {q0}, [r1]! + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ The middle keys have _vpaes_schedule_transform(.Lk_ipt) applied, + @ followed by _vpaes_schedule_mangle. _vpaes_schedule_mangle XORs 0x63, + @ multiplies by the circulant 0,1,1,1, then applies ShiftRows. +Loop_enc_key_to_bsaes: + vld1.64 {q0}, [r1]! + + @ Invert the ShiftRows step (see .Lschedule_mangle_both). Note we cycle + @ r3 in the opposite direction and start at .Lk_sr+0x10 instead of 0x30. + @ We use r3 rather than r8 to avoid a callee-saved register. + vld1.64 {q1}, [r3] + vtbl.8 d4, {q0}, d2 + vtbl.8 d5, {q0}, d3 + add r3, r3, #16 + and r3, r3, #~(1<<6) + vmov q0, q2 + + @ Handle the last key differently. + subs r2, r2, #1 + beq Loop_enc_key_to_bsaes_last + + @ Multiply by the circulant. This is its own inverse. + vtbl.8 d2, {q0}, d24 + vtbl.8 d3, {q0}, d25 + vmov q0, q1 + vtbl.8 d4, {q1}, d24 + vtbl.8 d5, {q1}, d25 + veor q0, q0, q2 + vtbl.8 d2, {q2}, d24 + vtbl.8 d3, {q2}, d25 + veor q0, q0, q1 + + @ XOR and finish. + veor q0, q0, q10 + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + b Loop_enc_key_to_bsaes + +Loop_enc_key_to_bsaes_last: + @ The final key does not have a basis transform (note + @ .Lschedule_mangle_last inverts the original transform). It only XORs + @ 0x63 and applies ShiftRows. The latter was already inverted in the + @ loop. Note that, because we act on the original representation, we use + @ q11, not q10. + veor q0, q0, q11 + vrev32.8 q0, q0 + vst1.64 {q0}, [r0] + + @ Wipe registers which contained key material. + veor q0, q0, q0 + veor q1, q1, q1 + veor q2, q2, q2 + + ldmia sp!, {r11, pc} @ return + + +@ void vpaes_decrypt_key_to_bsaes(AES_KEY *vpaes, const AES_KEY *bsaes); +.globl _vpaes_decrypt_key_to_bsaes +.private_extern _vpaes_decrypt_key_to_bsaes +#ifdef __thumb2__ +.thumb_func _vpaes_decrypt_key_to_bsaes +#endif +.align 4 +_vpaes_decrypt_key_to_bsaes: + stmdb sp!, {r11, lr} + + @ See _vpaes_schedule_core for the key schedule logic. Note vpaes + @ computes the decryption key schedule in reverse. Additionally, + @ aes-x86_64.pl shares some transformations, so we must only partially + @ invert vpaes's transformations. In general, vpaes computes in a + @ different basis (.Lk_ipt and .Lk_opt) and applies the inverses of + @ MixColumns, ShiftRows, and the affine part of the AES S-box (which is + @ split into a linear skew and XOR of 0x63). We undo all but MixColumns. + @ + @ Note also that bsaes-armv7.pl expects aes-armv4.pl's key + @ representation, which does not match the other aes_nohw_* + @ implementations. The ARM aes_nohw_* stores each 32-bit word + @ byteswapped, as a convenience for (unsupported) big-endian ARM, at the + @ cost of extra REV and VREV32 operations in little-endian ARM. + + adr r2, Lk_decrypt_transform + adr r3, Lk_sr+0x30 + adr r11, Lk_opt_then_skew @ Input to _vpaes_schedule_transform. + vld1.64 {q12}, [r2] @ Reuse q12 from encryption. + vmov.i8 q9, #0x0f @ Required by _vpaes_schedule_transform + + @ vpaes stores one fewer round count than bsaes, but the number of keys + @ is the same. + ldr r2, [r1,#240] + add r2, r2, #1 + str r2, [r0,#240] + + @ Undo the basis change and reapply the S-box affine transform. See + @ .Lschedule_mangle_last. + vld1.64 {q0}, [r1]! + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ See _vpaes_schedule_mangle for the transform on the middle keys. Note + @ it simultaneously inverts MixColumns and the S-box affine transform. + @ See .Lk_dksd through .Lk_dks9. +Loop_dec_key_to_bsaes: + vld1.64 {q0}, [r1]! + + @ Invert the ShiftRows step (see .Lschedule_mangle_both). Note going + @ forwards cancels inverting for which direction we cycle r3. We use r3 + @ rather than r8 to avoid a callee-saved register. + vld1.64 {q1}, [r3] + vtbl.8 d4, {q0}, d2 + vtbl.8 d5, {q0}, d3 + add r3, r3, #64-16 + and r3, r3, #~(1<<6) + vmov q0, q2 + + @ Handle the last key differently. + subs r2, r2, #1 + beq Loop_dec_key_to_bsaes_last + + @ Undo the basis change and reapply the S-box affine transform. + bl _vpaes_schedule_transform + + @ Rotate each word by 8 bytes (cycle the rows) and then byte-swap. We + @ combine the two operations in .Lk_decrypt_transform. + @ + @ TODO(davidben): Where does the rotation come from? + vtbl.8 d2, {q0}, d24 + vtbl.8 d3, {q0}, d25 + + vst1.64 {q1}, [r0]! + b Loop_dec_key_to_bsaes + +Loop_dec_key_to_bsaes_last: + @ The final key only inverts ShiftRows (already done in the loop). See + @ .Lschedule_am_decrypting. Its basis is not transformed. + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ Wipe registers which contained key material. + veor q0, q0, q0 + veor q1, q1, q1 + veor q2, q2, q2 + + ldmia sp!, {r11, pc} @ return + +.globl _vpaes_ctr32_encrypt_blocks +.private_extern _vpaes_ctr32_encrypt_blocks +#ifdef __thumb2__ +.thumb_func _vpaes_ctr32_encrypt_blocks +#endif +.align 4 +_vpaes_ctr32_encrypt_blocks: + mov ip, sp + stmdb sp!, {r7,r8,r9,r10,r11, lr} + @ This function uses q4-q7 (d8-d15), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + cmp r2, #0 + @ r8 is passed on the stack. + ldr r8, [ip] + beq Lctr32_done + + @ _vpaes_encrypt_core expects the key in r2, so swap r2 and r3. + mov r9, r3 + mov r3, r2 + mov r2, r9 + + @ Load the IV and counter portion. + ldr r7, [r8, #12] + vld1.8 {q7}, [r8] + + bl _vpaes_preheat + rev r7, r7 @ The counter is big-endian. + +Lctr32_loop: + vmov q0, q7 + vld1.8 {q6}, [r0]! @ Load input ahead of time + bl _vpaes_encrypt_core + veor q0, q0, q6 @ XOR input and result + vst1.8 {q0}, [r1]! + subs r3, r3, #1 + @ Update the counter. + add r7, r7, #1 + rev r9, r7 + vmov.32 d15[1], r9 + bne Lctr32_loop + +Lctr32_done: + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return + +#endif // !OPENSSL_NO_ASM +#endif // defined(__arm__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S new file mode 100644 index 00000000..b6fc2c10 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S @@ -0,0 +1,1243 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__arm__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.syntax unified + +.arch armv7-a +.fpu neon + +#if defined(__thumb2__) +.thumb +#else +.code 32 +#endif + +.text + +.type _vpaes_consts,%object +.align 7 @ totally strategic alignment +_vpaes_consts: +.Lk_mc_forward:@ mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +.Lk_mc_backward:@ mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +.Lk_sr:@ sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +@ +@ "Hot" constants +@ +.Lk_inv:@ inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +.Lk_ipt:@ input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +.Lk_sbo:@ sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +.Lk_sb1:@ sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.Lk_sb2:@ sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,55,32,78,69,79,78,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 +.size _vpaes_consts,.-_vpaes_consts +.align 6 +@@ +@@ _aes_preheat +@@ +@@ Fills q9-q15 as specified below. +@@ +.type _vpaes_preheat,%function +.align 4 +_vpaes_preheat: + adr r10, .Lk_inv + vmov.i8 q9, #0x0f @ .Lk_s0F + vld1.64 {q10,q11}, [r10]! @ .Lk_inv + add r10, r10, #64 @ Skip .Lk_ipt, .Lk_sbo + vld1.64 {q12,q13}, [r10]! @ .Lk_sb1 + vld1.64 {q14,q15}, [r10] @ .Lk_sb2 + bx lr + +@@ +@@ _aes_encrypt_core +@@ +@@ AES-encrypt q0. +@@ +@@ Inputs: +@@ q0 = input +@@ q9-q15 as in _vpaes_preheat +@@ [r2] = scheduled keys +@@ +@@ Output in q0 +@@ Clobbers q1-q5, r8-r11 +@@ Preserves q6-q8 so you get some local vectors +@@ +@@ +.type _vpaes_encrypt_core,%function +.align 4 +_vpaes_encrypt_core: + mov r9, r2 + ldr r8, [r2,#240] @ pull rounds + adr r11, .Lk_ipt + @ vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + @ vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + vld1.64 {q2, q3}, [r11] + adr r11, .Lk_mc_forward+16 + vld1.64 {q5}, [r9]! @ vmovdqu (%r9), %xmm5 # round0 key + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d2, {q2}, d2 @ vpshufb %xmm1, %xmm2, %xmm1 + vtbl.8 d3, {q2}, d3 + vtbl.8 d4, {q3}, d0 @ vpshufb %xmm0, %xmm3, %xmm2 + vtbl.8 d5, {q3}, d1 + veor q0, q1, q5 @ vpxor %xmm5, %xmm1, %xmm0 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + + @ .Lenc_entry ends with a bnz instruction which is normally paired with + @ subs in .Lenc_loop. + tst r8, r8 + b .Lenc_entry + +.align 4 +.Lenc_loop: + @ middle of middle round + add r10, r11, #0x40 + vtbl.8 d8, {q13}, d4 @ vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + vtbl.8 d9, {q13}, d5 + vld1.64 {q1}, [r11]! @ vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + vtbl.8 d0, {q12}, d6 @ vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + vtbl.8 d1, {q12}, d7 + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + vtbl.8 d10, {q15}, d4 @ vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + vtbl.8 d11, {q15}, d5 + veor q0, q0, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = A + vtbl.8 d4, {q14}, d6 @ vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + vtbl.8 d5, {q14}, d7 + vld1.64 {q4}, [r10] @ vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + vtbl.8 d6, {q0}, d2 @ vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + vtbl.8 d7, {q0}, d3 + veor q2, q2, q5 @ vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + @ Write to q5 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d10, {q0}, d8 @ vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + vtbl.8 d11, {q0}, d9 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + vtbl.8 d8, {q3}, d2 @ vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + vtbl.8 d9, {q3}, d3 + @ Here we restore the original q0/q5 usage. + veor q0, q5, q3 @ vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and r11, r11, #~(1<<6) @ and $0x30, %r11 # ... mod 4 + veor q0, q0, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + subs r8, r8, #1 @ nr-- + +.Lenc_entry: + @ top of round + vand q1, q0, q9 @ vpand %xmm0, %xmm9, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + vtbl.8 d10, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + vtbl.8 d11, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q3, q3, q5 @ vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + vtbl.8 d5, {q10}, d7 + vtbl.8 d6, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + vtbl.8 d7, {q10}, d9 + veor q2, q2, q1 @ vpxor %xmm1, %xmm2, %xmm2 # 2 = io + veor q3, q3, q0 @ vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + vld1.64 {q5}, [r9]! @ vmovdqu (%r9), %xmm5 + bne .Lenc_loop + + @ middle of last round + add r10, r11, #0x80 + + adr r11, .Lk_sbo + @ Read to q1 instead of q4, so the vtbl.8 instruction below does not + @ overlap table and destination registers. + vld1.64 {q1}, [r11]! @ vmovdqa -0x60(%r10), %xmm4 # 3 : sbou + vld1.64 {q0}, [r11] @ vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + vtbl.8 d8, {q1}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + vtbl.8 d9, {q1}, d5 + vld1.64 {q1}, [r10] @ vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + @ Write to q2 instead of q0 below, to avoid overlapping table and + @ destination registers. + vtbl.8 d4, {q0}, d6 @ vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + vtbl.8 d5, {q0}, d7 + veor q4, q4, q5 @ vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + veor q2, q2, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 0 = A + @ Here we restore the original q0/q2 usage. + vtbl.8 d0, {q2}, d2 @ vpshufb %xmm1, %xmm0, %xmm0 + vtbl.8 d1, {q2}, d3 + bx lr +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + +.globl vpaes_encrypt +.hidden vpaes_encrypt +.type vpaes_encrypt,%function +.align 4 +vpaes_encrypt: + @ _vpaes_encrypt_core uses r8-r11. Round up to r7-r11 to maintain stack + @ alignment. + stmdb sp!, {r7,r8,r9,r10,r11,lr} + @ _vpaes_encrypt_core uses q4-q5 (d8-d11), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11} + + vld1.64 {q0}, [r0] + bl _vpaes_preheat + bl _vpaes_encrypt_core + vst1.64 {q0}, [r1] + + vldmia sp!, {d8,d9,d10,d11} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return +.size vpaes_encrypt,.-vpaes_encrypt + +@ +@ Decryption stuff +@ +.type _vpaes_decrypt_consts,%object +.align 4 +_vpaes_decrypt_consts: +.Lk_dipt:@ decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +.Lk_dsbo:@ decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.Lk_dsb9:@ decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd:@ decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb:@ decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe:@ decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 +.size _vpaes_decrypt_consts,.-_vpaes_decrypt_consts + +@@ +@@ Decryption core +@@ +@@ Same API as encryption core, except it clobbers q12-q15 rather than using +@@ the values from _vpaes_preheat. q9-q11 must still be set from +@@ _vpaes_preheat. +@@ +.type _vpaes_decrypt_core,%function +.align 4 +_vpaes_decrypt_core: + mov r9, r2 + ldr r8, [r2,#240] @ pull rounds + + @ This function performs shuffles with various constants. The x86_64 + @ version loads them on-demand into %xmm0-%xmm5. This does not work well + @ for ARMv7 because those registers are shuffle destinations. The ARMv8 + @ version preloads those constants into registers, but ARMv7 has half + @ the registers to work with. Instead, we load them on-demand into + @ q12-q15, registers normally use for preloaded constants. This is fine + @ because decryption doesn't use those constants. The values are + @ constant, so this does not interfere with potential 2x optimizations. + adr r7, .Lk_dipt + + vld1.64 {q12,q13}, [r7] @ vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl r11, r8, #4 @ mov %rax, %r11; shl $4, %r11 + eor r11, r11, #0x30 @ xor $0x30, %r11 + adr r10, .Lk_sr + and r11, r11, #0x30 @ and $0x30, %r11 + add r11, r11, r10 + adr r10, .Lk_mc_forward+48 + + vld1.64 {q4}, [r9]! @ vmovdqu (%r9), %xmm4 # round0 key + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d4, {q12}, d2 @ vpshufb %xmm1, %xmm2, %xmm2 + vtbl.8 d5, {q12}, d3 + vld1.64 {q5}, [r10] @ vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + @ vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + vtbl.8 d0, {q13}, d0 @ vpshufb %xmm0, %xmm1, %xmm0 + vtbl.8 d1, {q13}, d1 + veor q2, q2, q4 @ vpxor %xmm4, %xmm2, %xmm2 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + + @ .Ldec_entry ends with a bnz instruction which is normally paired with + @ subs in .Ldec_loop. + tst r8, r8 + b .Ldec_entry + +.align 4 +.Ldec_loop: +@ +@ Inverse mix columns +@ + + @ We load .Lk_dsb* into q12-q15 on-demand. See the comment at the top of + @ the function. + adr r10, .Lk_dsb9 + vld1.64 {q12,q13}, [r10]! @ vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + @ vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + @ Load sbd* ahead of time. + vld1.64 {q14,q15}, [r10]! @ vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + @ vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + vtbl.8 d8, {q12}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + vtbl.8 d9, {q12}, d5 + vtbl.8 d2, {q13}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + vtbl.8 d3, {q13}, d7 + veor q0, q4, q0 @ vpxor %xmm4, %xmm0, %xmm0 + + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + + @ Load sbb* ahead of time. + vld1.64 {q12,q13}, [r10]! @ vmovdqa 0x20(%r10),%xmm4 # 4 : sbbu + @ vmovdqa 0x30(%r10),%xmm1 # 0 : sbbt + + vtbl.8 d8, {q14}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + vtbl.8 d9, {q14}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q15}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + vtbl.8 d3, {q15}, d7 + @ vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + @ vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + @ Load sbd* ahead of time. + vld1.64 {q14,q15}, [r10]! @ vmovdqa 0x40(%r10),%xmm4 # 4 : sbeu + @ vmovdqa 0x50(%r10),%xmm1 # 0 : sbet + + vtbl.8 d8, {q12}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + vtbl.8 d9, {q12}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q13}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + vtbl.8 d3, {q13}, d7 + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + + vtbl.8 d8, {q14}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + vtbl.8 d9, {q14}, d5 + @ Write to q1 instead of q0, so the table and destination registers do + @ not overlap. + vtbl.8 d2, {q0}, d10 @ vpshufb %xmm5, %xmm0, %xmm0 # MC ch + vtbl.8 d3, {q0}, d11 + @ Here we restore the original q0/q1 usage. This instruction is + @ reordered from the ARMv8 version so we do not clobber the vtbl.8 + @ below. + veor q0, q1, q4 @ vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + vtbl.8 d2, {q15}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + vtbl.8 d3, {q15}, d7 + vext.8 q5, q5, q5, #12 @ vpalignr $12, %xmm5, %xmm5, %xmm5 + veor q0, q0, q1 @ vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + subs r8, r8, #1 @ sub $1,%rax # nr-- + +.Ldec_entry: + @ top of round + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + vtbl.8 d4, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + vtbl.8 d5, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + veor q4, q4, q2 @ vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + vtbl.8 d5, {q10}, d7 + vtbl.8 d6, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + vtbl.8 d7, {q10}, d9 + veor q2, q2, q1 @ vpxor %xmm1, %xmm2, %xmm2 # 2 = io + veor q3, q3, q0 @ vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + vld1.64 {q0}, [r9]! @ vmovdqu (%r9), %xmm0 + bne .Ldec_loop + + @ middle of last round + + adr r10, .Lk_dsbo + + @ Write to q1 rather than q4 to avoid overlapping table and destination. + vld1.64 {q1}, [r10]! @ vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + vtbl.8 d8, {q1}, d4 @ vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + vtbl.8 d9, {q1}, d5 + @ Write to q2 rather than q1 to avoid overlapping table and destination. + vld1.64 {q2}, [r10] @ vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + vtbl.8 d2, {q2}, d6 @ vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + vtbl.8 d3, {q2}, d7 + vld1.64 {q2}, [r11] @ vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + veor q4, q4, q0 @ vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + @ Write to q1 rather than q0 so the table and destination registers + @ below do not overlap. + veor q1, q1, q4 @ vpxor %xmm4, %xmm1, %xmm0 # 0 = A + vtbl.8 d0, {q1}, d4 @ vpshufb %xmm2, %xmm0, %xmm0 + vtbl.8 d1, {q1}, d5 + bx lr +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + +.globl vpaes_decrypt +.hidden vpaes_decrypt +.type vpaes_decrypt,%function +.align 4 +vpaes_decrypt: + @ _vpaes_decrypt_core uses r7-r11. + stmdb sp!, {r7,r8,r9,r10,r11,lr} + @ _vpaes_decrypt_core uses q4-q5 (d8-d11), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11} + + vld1.64 {q0}, [r0] + bl _vpaes_preheat + bl _vpaes_decrypt_core + vst1.64 {q0}, [r1] + + vldmia sp!, {d8,d9,d10,d11} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return +.size vpaes_decrypt,.-vpaes_decrypt +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@ @@ +@@ AES key schedule @@ +@@ @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@ This function diverges from both x86_64 and armv7 in which constants are +@ pinned. x86_64 has a common preheat function for all operations. aarch64 +@ separates them because it has enough registers to pin nearly all constants. +@ armv7 does not have enough registers, but needing explicit loads and stores +@ also complicates using x86_64's register allocation directly. +@ +@ We pin some constants for convenience and leave q14 and q15 free to load +@ others on demand. + +@ +@ Key schedule constants +@ +.type _vpaes_key_consts,%object +.align 4 +_vpaes_key_consts: +.Lk_dksd:@ decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb:@ decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse:@ decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9:@ decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +.Lk_rcon:@ rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_opt:@ output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +.Lk_deskew:@ deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 +.size _vpaes_key_consts,.-_vpaes_key_consts + +.type _vpaes_key_preheat,%function +.align 4 +_vpaes_key_preheat: + adr r11, .Lk_rcon + vmov.i8 q12, #0x5b @ .Lk_s63 + adr r10, .Lk_inv @ Must be aligned to 8 mod 16. + vmov.i8 q9, #0x0f @ .Lk_s0F + vld1.64 {q10,q11}, [r10] @ .Lk_inv + vld1.64 {q8}, [r11] @ .Lk_rcon + bx lr +.size _vpaes_key_preheat,.-_vpaes_key_preheat + +.type _vpaes_schedule_core,%function +.align 4 +_vpaes_schedule_core: + @ We only need to save lr, but ARM requires an 8-byte stack alignment, + @ so save an extra register. + stmdb sp!, {r3,lr} + + bl _vpaes_key_preheat @ load the tables + + adr r11, .Lk_ipt @ Must be aligned to 8 mod 16. + vld1.64 {q0}, [r0]! @ vmovdqu (%rdi), %xmm0 # load key (unaligned) + + @ input transform + @ Use q4 here rather than q3 so .Lschedule_am_decrypting does not + @ overlap table and destination. + vmov q4, q0 @ vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + adr r10, .Lk_sr @ Must be aligned to 8 mod 16. + vmov q7, q0 @ vmovdqa %xmm0, %xmm7 + + add r8, r8, r10 + tst r3, r3 + bne .Lschedule_am_decrypting + + @ encrypting, output zeroth round key after transform + vst1.64 {q0}, [r2] @ vmovdqu %xmm0, (%rdx) + b .Lschedule_go + +.Lschedule_am_decrypting: + @ decrypting, output zeroth round key after shiftrows + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + vtbl.8 d6, {q4}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q4}, d3 + vst1.64 {q3}, [r2] @ vmovdqu %xmm3, (%rdx) + eor r8, r8, #0x30 @ xor $0x30, %r8 + +.Lschedule_go: + cmp r1, #192 @ cmp $192, %esi + bhi .Lschedule_256 + beq .Lschedule_192 + @ 128: fall though + +@@ +@@ .schedule_128 +@@ +@@ 128-bit specific part of key schedule. +@@ +@@ This schedule is really simple, because all its parts +@@ are accomplished by the subroutines. +@@ +.Lschedule_128: + mov r0, #10 @ mov $10, %esi + +.Loop_schedule_128: + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq .Lschedule_mangle_last + bl _vpaes_schedule_mangle @ write output + b .Loop_schedule_128 + +@@ +@@ .aes_schedule_192 +@@ +@@ 192-bit specific part of key schedule. +@@ +@@ The main body of this schedule is the same as the 128-bit +@@ schedule, but with more smearing. The long, high side is +@@ stored in q7 as before, and the short, low side is in +@@ the high bits of q6. +@@ +@@ This schedule is somewhat nastier, however, because each +@@ round produces 192 bits of key material, or 1.5 round keys. +@@ Therefore, on each cycle we do 2 rounds and produce 3 round +@@ keys. +@@ +.align 4 +.Lschedule_192: + sub r0, r0, #8 + vld1.64 {q0}, [r0] @ vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform @ input transform + vmov q6, q0 @ vmovdqa %xmm0, %xmm6 # save short part + vmov.i8 d12, #0 @ vpxor %xmm4, %xmm4, %xmm4 # clear 4 + @ vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov r0, #4 @ mov $4, %esi + +.Loop_schedule_192: + bl _vpaes_schedule_round + vext.8 q0, q6, q0, #8 @ vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle @ save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle @ save key n+1 + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq .Lschedule_mangle_last + bl _vpaes_schedule_mangle @ save key n+2 + bl _vpaes_schedule_192_smear + b .Loop_schedule_192 + +@@ +@@ .aes_schedule_256 +@@ +@@ 256-bit specific part of key schedule. +@@ +@@ The structure here is very similar to the 128-bit +@@ schedule, but with an additional "low side" in +@@ q6. The low side's rounds are the same as the +@@ high side's, except no rcon and no rotation. +@@ +.align 4 +.Lschedule_256: + vld1.64 {q0}, [r0] @ vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform @ input transform + mov r0, #7 @ mov $7, %esi + +.Loop_schedule_256: + bl _vpaes_schedule_mangle @ output low result + vmov q6, q0 @ vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + @ high round + bl _vpaes_schedule_round + subs r0, r0, #1 @ dec %esi + beq .Lschedule_mangle_last + bl _vpaes_schedule_mangle + + @ low round. swap xmm7 and xmm6 + vdup.32 q0, d1[1] @ vpshufd $0xFF, %xmm0, %xmm0 + vmov.i8 q4, #0 + vmov q5, q7 @ vmovdqa %xmm7, %xmm5 + vmov q7, q6 @ vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + vmov q7, q5 @ vmovdqa %xmm5, %xmm7 + + b .Loop_schedule_256 + +@@ +@@ .aes_schedule_mangle_last +@@ +@@ Mangler for last round of key schedule +@@ Mangles q0 +@@ when encrypting, outputs out(q0) ^ 63 +@@ when decrypting, outputs unskew(q0) +@@ +@@ Always called right before return... jumps to cleanup and exits +@@ +.align 4 +.Lschedule_mangle_last: + @ schedule last round key from xmm0 + adr r11, .Lk_deskew @ lea .Lk_deskew(%rip),%r11 # prepare to deskew + tst r3, r3 + bne .Lschedule_mangle_last_dec + + @ encrypting + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10),%xmm1 + adr r11, .Lk_opt @ lea .Lk_opt(%rip), %r11 # prepare to output transform + add r2, r2, #32 @ add $32, %rdx + vmov q2, q0 + vtbl.8 d0, {q2}, d2 @ vpshufb %xmm1, %xmm0, %xmm0 # output permute + vtbl.8 d1, {q2}, d3 + +.Lschedule_mangle_last_dec: + sub r2, r2, #16 @ add $-16, %rdx + veor q0, q0, q12 @ vpxor .Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform @ output transform + vst1.64 {q0}, [r2] @ vmovdqu %xmm0, (%rdx) # save last key + + @ cleanup + veor q0, q0, q0 @ vpxor %xmm0, %xmm0, %xmm0 + veor q1, q1, q1 @ vpxor %xmm1, %xmm1, %xmm1 + veor q2, q2, q2 @ vpxor %xmm2, %xmm2, %xmm2 + veor q3, q3, q3 @ vpxor %xmm3, %xmm3, %xmm3 + veor q4, q4, q4 @ vpxor %xmm4, %xmm4, %xmm4 + veor q5, q5, q5 @ vpxor %xmm5, %xmm5, %xmm5 + veor q6, q6, q6 @ vpxor %xmm6, %xmm6, %xmm6 + veor q7, q7, q7 @ vpxor %xmm7, %xmm7, %xmm7 + ldmia sp!, {r3,pc} @ return +.size _vpaes_schedule_core,.-_vpaes_schedule_core + +@@ +@@ .aes_schedule_192_smear +@@ +@@ Smear the short, low side in the 192-bit key schedule. +@@ +@@ Inputs: +@@ q7: high side, b a x y +@@ q6: low side, d c 0 0 +@@ +@@ Outputs: +@@ q6: b+c+d b+c 0 0 +@@ q0: b+c+d b+c b a +@@ +.type _vpaes_schedule_192_smear,%function +.align 4 +_vpaes_schedule_192_smear: + vmov.i8 q1, #0 + vdup.32 q0, d15[1] + vshl.i64 q1, q6, #32 @ vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + vmov d0, d15 @ vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + veor q6, q6, q1 @ vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + veor q1, q1, q1 @ vpxor %xmm1, %xmm1, %xmm1 + veor q6, q6, q0 @ vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + vmov q0, q6 @ vmovdqa %xmm6, %xmm0 + vmov d12, d2 @ vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + bx lr +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + +@@ +@@ .aes_schedule_round +@@ +@@ Runs one main round of the key schedule on q0, q7 +@@ +@@ Specifically, runs subbytes on the high dword of q0 +@@ then rotates it by one byte and xors into the low dword of +@@ q7. +@@ +@@ Adds rcon from low byte of q8, then rotates q8 for +@@ next rcon. +@@ +@@ Smears the dwords of q7 by xoring the low into the +@@ second low, result into third, result into highest. +@@ +@@ Returns results in q7 = q0. +@@ Clobbers q1-q4, r11. +@@ +.type _vpaes_schedule_round,%function +.align 4 +_vpaes_schedule_round: + @ extract rcon from xmm8 + vmov.i8 q4, #0 @ vpxor %xmm4, %xmm4, %xmm4 + vext.8 q1, q8, q4, #15 @ vpalignr $15, %xmm8, %xmm4, %xmm1 + vext.8 q8, q8, q8, #15 @ vpalignr $15, %xmm8, %xmm8, %xmm8 + veor q7, q7, q1 @ vpxor %xmm1, %xmm7, %xmm7 + + @ rotate + vdup.32 q0, d1[1] @ vpshufd $0xFF, %xmm0, %xmm0 + vext.8 q0, q0, q0, #1 @ vpalignr $1, %xmm0, %xmm0, %xmm0 + + @ fall through... + + @ low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + @ The x86_64 version pins .Lk_sb1 in %xmm13 and .Lk_sb1+16 in %xmm12. + @ We pin other values in _vpaes_key_preheat, so load them now. + adr r11, .Lk_sb1 + vld1.64 {q14,q15}, [r11] + + @ smear xmm7 + vext.8 q1, q4, q7, #12 @ vpslldq $4, %xmm7, %xmm1 + veor q7, q7, q1 @ vpxor %xmm1, %xmm7, %xmm7 + vext.8 q4, q4, q7, #8 @ vpslldq $8, %xmm7, %xmm4 + + @ subbytes + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 # 0 = k + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 # 1 = i + veor q7, q7, q4 @ vpxor %xmm4, %xmm7, %xmm7 + vtbl.8 d4, {q11}, d2 @ vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + vtbl.8 d5, {q11}, d3 + veor q1, q1, q0 @ vpxor %xmm0, %xmm1, %xmm1 # 0 = j + vtbl.8 d6, {q10}, d0 @ vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + vtbl.8 d7, {q10}, d1 + veor q3, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + vtbl.8 d8, {q10}, d2 @ vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + vtbl.8 d9, {q10}, d3 + veor q7, q7, q12 @ vpxor .Lk_s63(%rip), %xmm7, %xmm7 + vtbl.8 d6, {q10}, d6 @ vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + vtbl.8 d7, {q10}, d7 + veor q4, q4, q2 @ vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + vtbl.8 d4, {q10}, d8 @ vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + vtbl.8 d5, {q10}, d9 + veor q3, q3, q1 @ vpxor %xmm1, %xmm3, %xmm3 # 2 = io + veor q2, q2, q0 @ vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + vtbl.8 d8, {q15}, d6 @ vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + vtbl.8 d9, {q15}, d7 + vtbl.8 d2, {q14}, d4 @ vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + vtbl.8 d3, {q14}, d5 + veor q1, q1, q4 @ vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + @ add in smeared stuff + veor q0, q1, q7 @ vpxor %xmm7, %xmm1, %xmm0 + veor q7, q1, q7 @ vmovdqa %xmm0, %xmm7 + bx lr +.size _vpaes_schedule_round,.-_vpaes_schedule_round + +@@ +@@ .aes_schedule_transform +@@ +@@ Linear-transform q0 according to tables at [r11] +@@ +@@ Requires that q9 = 0x0F0F... as in preheat +@@ Output in q0 +@@ Clobbers q1, q2, q14, q15 +@@ +.type _vpaes_schedule_transform,%function +.align 4 +_vpaes_schedule_transform: + vld1.64 {q14,q15}, [r11] @ vmovdqa (%r11), %xmm2 # lo + @ vmovdqa 16(%r11), %xmm1 # hi + vand q1, q0, q9 @ vpand %xmm9, %xmm0, %xmm1 + vshr.u8 q0, q0, #4 @ vpsrlb $4, %xmm0, %xmm0 + vtbl.8 d4, {q14}, d2 @ vpshufb %xmm1, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d3 + vtbl.8 d0, {q15}, d0 @ vpshufb %xmm0, %xmm1, %xmm0 + vtbl.8 d1, {q15}, d1 + veor q0, q0, q2 @ vpxor %xmm2, %xmm0, %xmm0 + bx lr +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + +@@ +@@ .aes_schedule_mangle +@@ +@@ Mangles q0 from (basis-transformed) standard version +@@ to our version. +@@ +@@ On encrypt, +@@ xor with 0x63 +@@ multiply by circulant 0,1,1,1 +@@ apply shiftrows transform +@@ +@@ On decrypt, +@@ xor with 0x63 +@@ multiply by "inverse mixcolumns" circulant E,B,D,9 +@@ deskew +@@ apply shiftrows transform +@@ +@@ +@@ Writes out to [r2], and increments or decrements it +@@ Keeps track of round number mod 4 in r8 +@@ Preserves q0 +@@ Clobbers q1-q5 +@@ +.type _vpaes_schedule_mangle,%function +.align 4 +_vpaes_schedule_mangle: + tst r3, r3 + vmov q4, q0 @ vmovdqa %xmm0, %xmm4 # save xmm0 for later + adr r11, .Lk_mc_forward @ Must be aligned to 8 mod 16. + vld1.64 {q5}, [r11] @ vmovdqa .Lk_mc_forward(%rip),%xmm5 + bne .Lschedule_mangle_dec + + @ encrypting + @ Write to q2 so we do not overlap table and destination below. + veor q2, q0, q12 @ vpxor .Lk_s63(%rip), %xmm0, %xmm4 + add r2, r2, #16 @ add $16, %rdx + vtbl.8 d8, {q2}, d10 @ vpshufb %xmm5, %xmm4, %xmm4 + vtbl.8 d9, {q2}, d11 + vtbl.8 d2, {q4}, d10 @ vpshufb %xmm5, %xmm4, %xmm1 + vtbl.8 d3, {q4}, d11 + vtbl.8 d6, {q1}, d10 @ vpshufb %xmm5, %xmm1, %xmm3 + vtbl.8 d7, {q1}, d11 + veor q4, q4, q1 @ vpxor %xmm1, %xmm4, %xmm4 + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + veor q3, q3, q4 @ vpxor %xmm4, %xmm3, %xmm3 + + b .Lschedule_mangle_both +.align 4 +.Lschedule_mangle_dec: + @ inverse mix columns + adr r11, .Lk_dksd @ lea .Lk_dksd(%rip),%r11 + vshr.u8 q1, q4, #4 @ vpsrlb $4, %xmm4, %xmm1 # 1 = hi + vand q4, q4, q9 @ vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x00(%r11), %xmm2 + @ vmovdqa 0x10(%r11), %xmm3 + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dksb ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x20(%r11), %xmm2 + @ vmovdqa 0x30(%r11), %xmm3 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dkse ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x40(%r11), %xmm2 + @ vmovdqa 0x50(%r11), %xmm3 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + vtbl.8 d6, {q15}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d7, {q15}, d3 + @ Load .Lk_dkse ahead of time. + vld1.64 {q14,q15}, [r11]! @ vmovdqa 0x60(%r11), %xmm2 + @ vmovdqa 0x70(%r11), %xmm4 + @ Write to q13 so we do not overlap table and destination. + veor q13, q3, q2 @ vpxor %xmm2, %xmm3, %xmm3 + + vtbl.8 d4, {q14}, d8 @ vpshufb %xmm4, %xmm2, %xmm2 + vtbl.8 d5, {q14}, d9 + vtbl.8 d6, {q13}, d10 @ vpshufb %xmm5, %xmm3, %xmm3 + vtbl.8 d7, {q13}, d11 + vtbl.8 d8, {q15}, d2 @ vpshufb %xmm1, %xmm4, %xmm4 + vtbl.8 d9, {q15}, d3 + vld1.64 {q1}, [r8] @ vmovdqa (%r8,%r10), %xmm1 + veor q2, q2, q3 @ vpxor %xmm3, %xmm2, %xmm2 + veor q3, q4, q2 @ vpxor %xmm2, %xmm4, %xmm3 + + sub r2, r2, #16 @ add $-16, %rdx + +.Lschedule_mangle_both: + @ Write to q2 so table and destination do not overlap. + vtbl.8 d4, {q3}, d2 @ vpshufb %xmm1, %xmm3, %xmm3 + vtbl.8 d5, {q3}, d3 + add r8, r8, #64-16 @ add $-16, %r8 + and r8, r8, #~(1<<6) @ and $0x30, %r8 + vst1.64 {q2}, [r2] @ vmovdqu %xmm3, (%rdx) + bx lr +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + +.globl vpaes_set_encrypt_key +.hidden vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,%function +.align 4 +vpaes_set_encrypt_key: + stmdb sp!, {r7,r8,r9,r10,r11, lr} + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + lsr r9, r1, #5 @ shr $5,%eax + add r9, r9, #5 @ $5,%eax + str r9, [r2,#240] @ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov r3, #0 @ mov $0,%ecx + mov r8, #0x30 @ mov $0x30,%r8d + bl _vpaes_schedule_core + eor r0, r0, r0 + + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.hidden vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,%function +.align 4 +vpaes_set_decrypt_key: + stmdb sp!, {r7,r8,r9,r10,r11, lr} + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + lsr r9, r1, #5 @ shr $5,%eax + add r9, r9, #5 @ $5,%eax + str r9, [r2,#240] @ mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl r9, r9, #4 @ shl $4,%eax + add r2, r2, #16 @ lea 16(%rdx,%rax),%rdx + add r2, r2, r9 + + mov r3, #1 @ mov $1,%ecx + lsr r8, r1, #1 @ shr $1,%r8d + and r8, r8, #32 @ and $32,%r8d + eor r8, r8, #32 @ xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key + +@ Additional constants for converting to bsaes. +.type _vpaes_convert_consts,%object +.align 4 +_vpaes_convert_consts: +@ .Lk_opt_then_skew applies skew(opt(x)) XOR 0x63, where skew is the linear +@ transform in the AES S-box. 0x63 is incorporated into the low half of the +@ table. This was computed with the following script: +@ +@ def u64s_to_u128(x, y): +@ return x | (y << 64) +@ def u128_to_u64s(w): +@ return w & ((1<<64)-1), w >> 64 +@ def get_byte(w, i): +@ return (w >> (i*8)) & 0xff +@ def apply_table(table, b): +@ lo = b & 0xf +@ hi = b >> 4 +@ return get_byte(table[0], lo) ^ get_byte(table[1], hi) +@ def opt(b): +@ table = [ +@ u64s_to_u128(0xFF9F4929D6B66000, 0xF7974121DEBE6808), +@ u64s_to_u128(0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0), +@ ] +@ return apply_table(table, b) +@ def rot_byte(b, n): +@ return 0xff & ((b << n) | (b >> (8-n))) +@ def skew(x): +@ return (x ^ rot_byte(x, 1) ^ rot_byte(x, 2) ^ rot_byte(x, 3) ^ +@ rot_byte(x, 4)) +@ table = [0, 0] +@ for i in range(16): +@ table[0] |= (skew(opt(i)) ^ 0x63) << (i*8) +@ table[1] |= skew(opt(i<<4)) << (i*8) +@ print(" .quad 0x%016x, 0x%016x" % u128_to_u64s(table[0])) +@ print(" .quad 0x%016x, 0x%016x" % u128_to_u64s(table[1])) +.Lk_opt_then_skew: +.quad 0x9cb8436798bc4763, 0x6440bb9f6044bf9b +.quad 0x1f30062936192f00, 0xb49bad829db284ab + +@ .Lk_decrypt_transform is a permutation which performs an 8-bit left-rotation +@ followed by a byte-swap on each 32-bit word of a vector. E.g., 0x11223344 +@ becomes 0x22334411 and then 0x11443322. +.Lk_decrypt_transform: +.quad 0x0704050603000102, 0x0f0c0d0e0b08090a +.size _vpaes_convert_consts,.-_vpaes_convert_consts + +@ void vpaes_encrypt_key_to_bsaes(AES_KEY *bsaes, const AES_KEY *vpaes); +.globl vpaes_encrypt_key_to_bsaes +.hidden vpaes_encrypt_key_to_bsaes +.type vpaes_encrypt_key_to_bsaes,%function +.align 4 +vpaes_encrypt_key_to_bsaes: + stmdb sp!, {r11, lr} + + @ See _vpaes_schedule_core for the key schedule logic. In particular, + @ _vpaes_schedule_transform(.Lk_ipt) (section 2.2 of the paper), + @ _vpaes_schedule_mangle (section 4.3), and .Lschedule_mangle_last + @ contain the transformations not in the bsaes representation. This + @ function inverts those transforms. + @ + @ Note also that bsaes-armv7.pl expects aes-armv4.pl's key + @ representation, which does not match the other aes_nohw_* + @ implementations. The ARM aes_nohw_* stores each 32-bit word + @ byteswapped, as a convenience for (unsupported) big-endian ARM, at the + @ cost of extra REV and VREV32 operations in little-endian ARM. + + vmov.i8 q9, #0x0f @ Required by _vpaes_schedule_transform + adr r2, .Lk_mc_forward @ Must be aligned to 8 mod 16. + add r3, r2, 0x90 @ .Lk_sr+0x10-.Lk_mc_forward = 0x90 (Apple's toolchain doesn't support the expression) + + vld1.64 {q12}, [r2] + vmov.i8 q10, #0x5b @ .Lk_s63 from vpaes-x86_64 + adr r11, .Lk_opt @ Must be aligned to 8 mod 16. + vmov.i8 q11, #0x63 @ .LK_s63 without .Lk_ipt applied + + @ vpaes stores one fewer round count than bsaes, but the number of keys + @ is the same. + ldr r2, [r1,#240] + add r2, r2, #1 + str r2, [r0,#240] + + @ The first key is transformed with _vpaes_schedule_transform(.Lk_ipt). + @ Invert this with .Lk_opt. + vld1.64 {q0}, [r1]! + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ The middle keys have _vpaes_schedule_transform(.Lk_ipt) applied, + @ followed by _vpaes_schedule_mangle. _vpaes_schedule_mangle XORs 0x63, + @ multiplies by the circulant 0,1,1,1, then applies ShiftRows. +.Loop_enc_key_to_bsaes: + vld1.64 {q0}, [r1]! + + @ Invert the ShiftRows step (see .Lschedule_mangle_both). Note we cycle + @ r3 in the opposite direction and start at .Lk_sr+0x10 instead of 0x30. + @ We use r3 rather than r8 to avoid a callee-saved register. + vld1.64 {q1}, [r3] + vtbl.8 d4, {q0}, d2 + vtbl.8 d5, {q0}, d3 + add r3, r3, #16 + and r3, r3, #~(1<<6) + vmov q0, q2 + + @ Handle the last key differently. + subs r2, r2, #1 + beq .Loop_enc_key_to_bsaes_last + + @ Multiply by the circulant. This is its own inverse. + vtbl.8 d2, {q0}, d24 + vtbl.8 d3, {q0}, d25 + vmov q0, q1 + vtbl.8 d4, {q1}, d24 + vtbl.8 d5, {q1}, d25 + veor q0, q0, q2 + vtbl.8 d2, {q2}, d24 + vtbl.8 d3, {q2}, d25 + veor q0, q0, q1 + + @ XOR and finish. + veor q0, q0, q10 + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + b .Loop_enc_key_to_bsaes + +.Loop_enc_key_to_bsaes_last: + @ The final key does not have a basis transform (note + @ .Lschedule_mangle_last inverts the original transform). It only XORs + @ 0x63 and applies ShiftRows. The latter was already inverted in the + @ loop. Note that, because we act on the original representation, we use + @ q11, not q10. + veor q0, q0, q11 + vrev32.8 q0, q0 + vst1.64 {q0}, [r0] + + @ Wipe registers which contained key material. + veor q0, q0, q0 + veor q1, q1, q1 + veor q2, q2, q2 + + ldmia sp!, {r11, pc} @ return +.size vpaes_encrypt_key_to_bsaes,.-vpaes_encrypt_key_to_bsaes + +@ void vpaes_decrypt_key_to_bsaes(AES_KEY *vpaes, const AES_KEY *bsaes); +.globl vpaes_decrypt_key_to_bsaes +.hidden vpaes_decrypt_key_to_bsaes +.type vpaes_decrypt_key_to_bsaes,%function +.align 4 +vpaes_decrypt_key_to_bsaes: + stmdb sp!, {r11, lr} + + @ See _vpaes_schedule_core for the key schedule logic. Note vpaes + @ computes the decryption key schedule in reverse. Additionally, + @ aes-x86_64.pl shares some transformations, so we must only partially + @ invert vpaes's transformations. In general, vpaes computes in a + @ different basis (.Lk_ipt and .Lk_opt) and applies the inverses of + @ MixColumns, ShiftRows, and the affine part of the AES S-box (which is + @ split into a linear skew and XOR of 0x63). We undo all but MixColumns. + @ + @ Note also that bsaes-armv7.pl expects aes-armv4.pl's key + @ representation, which does not match the other aes_nohw_* + @ implementations. The ARM aes_nohw_* stores each 32-bit word + @ byteswapped, as a convenience for (unsupported) big-endian ARM, at the + @ cost of extra REV and VREV32 operations in little-endian ARM. + + adr r2, .Lk_decrypt_transform + adr r3, .Lk_sr+0x30 + adr r11, .Lk_opt_then_skew @ Input to _vpaes_schedule_transform. + vld1.64 {q12}, [r2] @ Reuse q12 from encryption. + vmov.i8 q9, #0x0f @ Required by _vpaes_schedule_transform + + @ vpaes stores one fewer round count than bsaes, but the number of keys + @ is the same. + ldr r2, [r1,#240] + add r2, r2, #1 + str r2, [r0,#240] + + @ Undo the basis change and reapply the S-box affine transform. See + @ .Lschedule_mangle_last. + vld1.64 {q0}, [r1]! + bl _vpaes_schedule_transform + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ See _vpaes_schedule_mangle for the transform on the middle keys. Note + @ it simultaneously inverts MixColumns and the S-box affine transform. + @ See .Lk_dksd through .Lk_dks9. +.Loop_dec_key_to_bsaes: + vld1.64 {q0}, [r1]! + + @ Invert the ShiftRows step (see .Lschedule_mangle_both). Note going + @ forwards cancels inverting for which direction we cycle r3. We use r3 + @ rather than r8 to avoid a callee-saved register. + vld1.64 {q1}, [r3] + vtbl.8 d4, {q0}, d2 + vtbl.8 d5, {q0}, d3 + add r3, r3, #64-16 + and r3, r3, #~(1<<6) + vmov q0, q2 + + @ Handle the last key differently. + subs r2, r2, #1 + beq .Loop_dec_key_to_bsaes_last + + @ Undo the basis change and reapply the S-box affine transform. + bl _vpaes_schedule_transform + + @ Rotate each word by 8 bytes (cycle the rows) and then byte-swap. We + @ combine the two operations in .Lk_decrypt_transform. + @ + @ TODO(davidben): Where does the rotation come from? + vtbl.8 d2, {q0}, d24 + vtbl.8 d3, {q0}, d25 + + vst1.64 {q1}, [r0]! + b .Loop_dec_key_to_bsaes + +.Loop_dec_key_to_bsaes_last: + @ The final key only inverts ShiftRows (already done in the loop). See + @ .Lschedule_am_decrypting. Its basis is not transformed. + vrev32.8 q0, q0 + vst1.64 {q0}, [r0]! + + @ Wipe registers which contained key material. + veor q0, q0, q0 + veor q1, q1, q1 + veor q2, q2, q2 + + ldmia sp!, {r11, pc} @ return +.size vpaes_decrypt_key_to_bsaes,.-vpaes_decrypt_key_to_bsaes +.globl vpaes_ctr32_encrypt_blocks +.hidden vpaes_ctr32_encrypt_blocks +.type vpaes_ctr32_encrypt_blocks,%function +.align 4 +vpaes_ctr32_encrypt_blocks: + mov ip, sp + stmdb sp!, {r7,r8,r9,r10,r11, lr} + @ This function uses q4-q7 (d8-d15), which are callee-saved. + vstmdb sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + + cmp r2, #0 + @ r8 is passed on the stack. + ldr r8, [ip] + beq .Lctr32_done + + @ _vpaes_encrypt_core expects the key in r2, so swap r2 and r3. + mov r9, r3 + mov r3, r2 + mov r2, r9 + + @ Load the IV and counter portion. + ldr r7, [r8, #12] + vld1.8 {q7}, [r8] + + bl _vpaes_preheat + rev r7, r7 @ The counter is big-endian. + +.Lctr32_loop: + vmov q0, q7 + vld1.8 {q6}, [r0]! @ .Load input ahead of time + bl _vpaes_encrypt_core + veor q0, q0, q6 @ XOR input and result + vst1.8 {q0}, [r1]! + subs r3, r3, #1 + @ Update the counter. + add r7, r7, #1 + rev r9, r7 + vmov.32 d15[1], r9 + bne .Lctr32_loop + +.Lctr32_done: + vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} + ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return +.size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__arm__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S new file mode 100644 index 00000000..fea011af --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S @@ -0,0 +1,1239 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.section __TEXT,__const + + +.align 7 // totally strategic alignment +_vpaes_consts: +Lk_mc_forward: // mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +Lk_mc_backward: // mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +Lk_sr: // sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +// +// "Hot" constants +// +Lk_inv: // inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +Lk_ipt: // input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +Lk_sbo: // sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +Lk_sb1: // sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +Lk_sb2: // sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +// +// Decryption stuff +// +Lk_dipt: // decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +Lk_dsbo: // decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +Lk_dsb9: // decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +Lk_dsbd: // decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +Lk_dsbb: // decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +Lk_dsbe: // decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 + +// +// Key schedule constants +// +Lk_dksd: // decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +Lk_dksb: // decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +Lk_dkse: // decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +Lk_dks9: // decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +Lk_rcon: // rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +Lk_opt: // output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +Lk_deskew: // deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 + +.align 6 + +.text +## +## _aes_preheat +## +## Fills register %r10 -> .aes_consts (so you can -fPIC) +## and %xmm9-%xmm15 as specified below. +## + +.align 4 +_vpaes_encrypt_preheat: + adrp x10, Lk_inv@PAGE + add x10, x10, Lk_inv@PAGEOFF + movi v17.16b, #0x0f + ld1 {v18.2d,v19.2d}, [x10],#32 // Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64 // Lk_ipt, Lk_sbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10] // Lk_sb1, Lk_sb2 + ret + + +## +## _aes_encrypt_core +## +## AES-encrypt %xmm0. +## +## Inputs: +## %xmm0 = input +## %xmm9-%xmm15 as in _vpaes_preheat +## (%rdx) = scheduled keys +## +## Output in %xmm0 +## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +## Preserves %xmm6 - %xmm8 so you get some local vectors +## +## + +.align 4 +_vpaes_encrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adrp x11, Lk_mc_forward@PAGE+16 + add x11, x11, Lk_mc_forward@PAGEOFF+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b Lenc_entry + +.align 4 +Lenc_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + sub w8, w8, #1 // nr-- + +Lenc_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v5.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, Lenc_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + ret + + +.globl _vpaes_encrypt +.private_extern _vpaes_encrypt + +.align 4 +_vpaes_encrypt: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_encrypt_preheat + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + + +.align 4 +_vpaes_encrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adrp x11, Lk_mc_forward@PAGE+16 + add x11, x11, Lk_mc_forward@PAGEOFF+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + tbl v9.16b, {v20.16b}, v9.16b + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + tbl v10.16b, {v21.16b}, v8.16b + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v8.16b, v9.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b Lenc_2x_entry + +.align 4 +Lenc_2x_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + tbl v12.16b, {v25.16b}, v10.16b + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + tbl v8.16b, {v24.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + tbl v13.16b, {v27.16b}, v10.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + tbl v10.16b, {v26.16b}, v11.16b + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + tbl v11.16b, {v8.16b}, v1.16b + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + eor v10.16b, v10.16b, v13.16b + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + tbl v8.16b, {v8.16b}, v4.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + eor v11.16b, v11.16b, v10.16b + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + tbl v12.16b, {v11.16b},v1.16b + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + eor v8.16b, v8.16b, v11.16b + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + eor v8.16b, v8.16b, v12.16b + sub w8, w8, #1 // nr-- + +Lenc_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v5.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + tbl v13.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v13.16b + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v13.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, Lenc_2x_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + tbl v8.16b, {v23.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v0.16b, {v0.16b},v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v1.16b + ret + + + +.align 4 +_vpaes_decrypt_preheat: + adrp x10, Lk_inv@PAGE + add x10, x10, Lk_inv@PAGEOFF + movi v17.16b, #0x0f + adrp x11, Lk_dipt@PAGE + add x11, x11, Lk_dipt@PAGEOFF + ld1 {v18.2d,v19.2d}, [x10],#32 // Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64 // Lk_dipt, Lk_dsbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64 // Lk_dsb9, Lk_dsbd + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x11] // Lk_dsbb, Lk_dsbe + ret + + +## +## Decryption core +## +## Same API as encryption core. +## + +.align 4 +_vpaes_decrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adrp x10, Lk_sr@PAGE + add x10, x10, Lk_sr@PAGEOFF + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adrp x10, Lk_mc_forward@PAGE+48 + add x10, x10, Lk_mc_forward@PAGEOFF+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + ld1 {v5.2d}, [x10] // vmovdqa Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b Ldec_entry + +.align 4 +Ldec_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + sub w8, w8, #1 // sub $1,%rax # nr-- + +Ldec_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, Ldec_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # Lk_sr-Lk_dsbd=-0x160 + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + ret + + +.globl _vpaes_decrypt +.private_extern _vpaes_decrypt + +.align 4 +_vpaes_decrypt: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_decrypt_preheat + bl _vpaes_decrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// v14-v15 input, v0-v1 output + +.align 4 +_vpaes_decrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adrp x10, Lk_sr@PAGE + add x10, x10, Lk_sr@PAGEOFF + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adrp x10, Lk_mc_forward@PAGE+48 + add x10, x10, Lk_mc_forward@PAGEOFF+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v2.16b, {v20.16b},v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + tbl v10.16b, {v20.16b},v9.16b + ld1 {v5.2d}, [x10] // vmovdqa Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b},v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + tbl v8.16b, {v21.16b},v8.16b + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v10.16b, v10.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b Ldec_2x_entry + +.align 4 +Ldec_2x_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v12.16b, {v24.16b}, v10.16b + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + tbl v9.16b, {v25.16b}, v11.16b + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + eor v8.16b, v12.16b, v16.16b + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v12.16b, {v26.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + tbl v9.16b, {v27.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v12.16b, {v28.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + tbl v9.16b, {v29.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v12.16b, {v30.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + tbl v9.16b, {v31.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + sub w8, w8, #1 // sub $1,%rax # nr-- + +Ldec_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v2.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + tbl v10.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v10.16b + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v10.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, Ldec_2x_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + tbl v9.16b, {v23.16b}, v11.16b + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # Lk_sr-Lk_dsbd=-0x160 + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + eor v8.16b, v9.16b, v12.16b + tbl v0.16b, {v0.16b},v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v2.16b + ret + +######################################################## +## ## +## AES key schedule ## +## ## +######################################################## + +.align 4 +_vpaes_key_preheat: + adrp x10, Lk_inv@PAGE + add x10, x10, Lk_inv@PAGEOFF + movi v16.16b, #0x5b // Lk_s63 + adrp x11, Lk_sb1@PAGE + add x11, x11, Lk_sb1@PAGEOFF + movi v17.16b, #0x0f // Lk_s0F + ld1 {v18.2d,v19.2d,v20.2d,v21.2d}, [x10] // Lk_inv, Lk_ipt + adrp x10, Lk_dksd@PAGE + add x10, x10, Lk_dksd@PAGEOFF + ld1 {v22.2d,v23.2d}, [x11] // Lk_sb1 + adrp x11, Lk_mc_forward@PAGE + add x11, x11, Lk_mc_forward@PAGEOFF + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64 // Lk_dksd, Lk_dksb + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64 // Lk_dkse, Lk_dks9 + ld1 {v8.2d}, [x10] // Lk_rcon + ld1 {v9.2d}, [x11] // Lk_mc_forward[0] + ret + + + +.align 4 +_vpaes_schedule_core: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp,#-16]! + add x29,sp,#0 + + bl _vpaes_key_preheat // load the tables + + ld1 {v0.16b}, [x0],#16 // vmovdqu (%rdi), %xmm0 # load key (unaligned) + + // input transform + mov v3.16b, v0.16b // vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + mov v7.16b, v0.16b // vmovdqa %xmm0, %xmm7 + + adrp x10, Lk_sr@PAGE // lea Lk_sr(%rip),%r10 + add x10, x10, Lk_sr@PAGEOFF + + add x8, x8, x10 + cbnz w3, Lschedule_am_decrypting + + // encrypting, output zeroth round key after transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) + b Lschedule_go + +Lschedule_am_decrypting: + // decrypting, output zeroth round key after shiftrows + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + eor x8, x8, #0x30 // xor $0x30, %r8 + +Lschedule_go: + cmp w1, #192 // cmp $192, %esi + b.hi Lschedule_256 + b.eq Lschedule_192 + // 128: fall though + +## +## .schedule_128 +## +## 128-bit specific part of key schedule. +## +## This schedule is really simple, because all its parts +## are accomplished by the subroutines. +## +Lschedule_128: + mov x0, #10 // mov $10, %esi + +Loop_schedule_128: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + cbz x0, Lschedule_mangle_last + bl _vpaes_schedule_mangle // write output + b Loop_schedule_128 + +## +## .aes_schedule_192 +## +## 192-bit specific part of key schedule. +## +## The main body of this schedule is the same as the 128-bit +## schedule, but with more smearing. The long, high side is +## stored in %xmm7 as before, and the short, low side is in +## the high bits of %xmm6. +## +## This schedule is somewhat nastier, however, because each +## round produces 192 bits of key material, or 1.5 round keys. +## Therefore, on each cycle we do 2 rounds and produce 3 round +## keys. +## +.align 4 +Lschedule_192: + sub x0, x0, #8 + ld1 {v0.16b}, [x0] // vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform // input transform + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save short part + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 # clear 4 + ins v6.d[0], v4.d[0] // vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov x0, #4 // mov $4, %esi + +Loop_schedule_192: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + ext v0.16b, v6.16b, v0.16b, #8 // vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle // save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle // save key n+1 + bl _vpaes_schedule_round + cbz x0, Lschedule_mangle_last + bl _vpaes_schedule_mangle // save key n+2 + bl _vpaes_schedule_192_smear + b Loop_schedule_192 + +## +## .aes_schedule_256 +## +## 256-bit specific part of key schedule. +## +## The structure here is very similar to the 128-bit +## schedule, but with an additional "low side" in +## %xmm6. The low side's rounds are the same as the +## high side's, except no rcon and no rotation. +## +.align 4 +Lschedule_256: + ld1 {v0.16b}, [x0] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform // input transform + mov x0, #7 // mov $7, %esi + +Loop_schedule_256: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_mangle // output low result + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + // high round + bl _vpaes_schedule_round + cbz x0, Lschedule_mangle_last + bl _vpaes_schedule_mangle + + // low round. swap xmm7 and xmm6 + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + movi v4.16b, #0 + mov v5.16b, v7.16b // vmovdqa %xmm7, %xmm5 + mov v7.16b, v6.16b // vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + mov v7.16b, v5.16b // vmovdqa %xmm5, %xmm7 + + b Loop_schedule_256 + +## +## .aes_schedule_mangle_last +## +## Mangler for last round of key schedule +## Mangles %xmm0 +## when encrypting, outputs out(%xmm0) ^ 63 +## when decrypting, outputs unskew(%xmm0) +## +## Always called right before return... jumps to cleanup and exits +## +.align 4 +Lschedule_mangle_last: + // schedule last round key from xmm0 + adrp x11, Lk_deskew@PAGE // lea Lk_deskew(%rip),%r11 # prepare to deskew + add x11, x11, Lk_deskew@PAGEOFF + + cbnz w3, Lschedule_mangle_last_dec + + // encrypting + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10),%xmm1 + adrp x11, Lk_opt@PAGE // lea Lk_opt(%rip), %r11 # prepare to output transform + add x11, x11, Lk_opt@PAGEOFF + add x2, x2, #32 // add $32, %rdx + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 # output permute + +Lschedule_mangle_last_dec: + ld1 {v20.2d,v21.2d}, [x11] // reload constants + sub x2, x2, #16 // add $-16, %rdx + eor v0.16b, v0.16b, v16.16b // vpxor Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform // output transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) # save last key + + // cleanup + eor v0.16b, v0.16b, v0.16b // vpxor %xmm0, %xmm0, %xmm0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v2.16b, v2.16b, v2.16b // vpxor %xmm2, %xmm2, %xmm2 + eor v3.16b, v3.16b, v3.16b // vpxor %xmm3, %xmm3, %xmm3 + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 + eor v5.16b, v5.16b, v5.16b // vpxor %xmm5, %xmm5, %xmm5 + eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 + eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 + ldp x29, x30, [sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +## +## .aes_schedule_192_smear +## +## Smear the short, low side in the 192-bit key schedule. +## +## Inputs: +## %xmm7: high side, b a x y +## %xmm6: low side, d c 0 0 +## %xmm13: 0 +## +## Outputs: +## %xmm6: b+c+d b+c 0 0 +## %xmm0: b+c+d b+c b a +## + +.align 4 +_vpaes_schedule_192_smear: + movi v1.16b, #0 + dup v0.4s, v7.s[3] + ins v1.s[3], v6.s[2] // vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + ins v0.s[0], v7.s[2] // vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + eor v6.16b, v6.16b, v1.16b // vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v6.16b, v6.16b, v0.16b // vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + mov v0.16b, v6.16b // vmovdqa %xmm6, %xmm0 + ins v6.d[0], v1.d[0] // vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + ret + + +## +## .aes_schedule_round +## +## Runs one main round of the key schedule on %xmm0, %xmm7 +## +## Specifically, runs subbytes on the high dword of %xmm0 +## then rotates it by one byte and xors into the low dword of +## %xmm7. +## +## Adds rcon from low byte of %xmm8, then rotates %xmm8 for +## next rcon. +## +## Smears the dwords of %xmm7 by xoring the low into the +## second low, result into third, result into highest. +## +## Returns results in %xmm7 = %xmm0. +## Clobbers %xmm1-%xmm4, %r11. +## + +.align 4 +_vpaes_schedule_round: + // extract rcon from xmm8 + movi v4.16b, #0 // vpxor %xmm4, %xmm4, %xmm4 + ext v1.16b, v8.16b, v4.16b, #15 // vpalignr $15, %xmm8, %xmm4, %xmm1 + ext v8.16b, v8.16b, v8.16b, #15 // vpalignr $15, %xmm8, %xmm8, %xmm8 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + + // rotate + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + ext v0.16b, v0.16b, v0.16b, #1 // vpalignr $1, %xmm0, %xmm0, %xmm0 + + // fall through... + + // low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + // smear xmm7 + ext v1.16b, v4.16b, v7.16b, #12 // vpslldq $4, %xmm7, %xmm1 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + ext v4.16b, v4.16b, v7.16b, #8 // vpslldq $8, %xmm7, %xmm4 + + // subbytes + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + eor v7.16b, v7.16b, v4.16b // vpxor %xmm4, %xmm7, %xmm7 + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v7.16b, v7.16b, v16.16b // vpxor Lk_s63(%rip), %xmm7, %xmm7 + tbl v3.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + eor v3.16b, v3.16b, v1.16b // vpxor %xmm1, %xmm3, %xmm3 # 2 = io + eor v2.16b, v2.16b, v0.16b // vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + tbl v4.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + tbl v1.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + eor v1.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + // add in smeared stuff + eor v0.16b, v1.16b, v7.16b // vpxor %xmm7, %xmm1, %xmm0 + eor v7.16b, v1.16b, v7.16b // vmovdqa %xmm0, %xmm7 + ret + + +## +## .aes_schedule_transform +## +## Linear-transform %xmm0 according to tables at (%r11) +## +## Requires that %xmm9 = 0x0F0F... as in preheat +## Output in %xmm0 +## Clobbers %xmm1, %xmm2 +## + +.align 4 +_vpaes_schedule_transform: + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + // vmovdqa (%r11), %xmm2 # lo + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + // vmovdqa 16(%r11), %xmm1 # hi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + ret + + +## +## .aes_schedule_mangle +## +## Mangle xmm0 from (basis-transformed) standard version +## to our version. +## +## On encrypt, +## xor with 0x63 +## multiply by circulant 0,1,1,1 +## apply shiftrows transform +## +## On decrypt, +## xor with 0x63 +## multiply by "inverse mixcolumns" circulant E,B,D,9 +## deskew +## apply shiftrows transform +## +## +## Writes out to (%rdx), and increments or decrements it +## Keeps track of round number mod 4 in %r8 +## Preserves xmm0 +## Clobbers xmm1-xmm5 +## + +.align 4 +_vpaes_schedule_mangle: + mov v4.16b, v0.16b // vmovdqa %xmm0, %xmm4 # save xmm0 for later + // vmovdqa .Lk_mc_forward(%rip),%xmm5 + cbnz w3, Lschedule_mangle_dec + + // encrypting + eor v4.16b, v0.16b, v16.16b // vpxor Lk_s63(%rip), %xmm0, %xmm4 + add x2, x2, #16 // add $16, %rdx + tbl v4.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm4 + tbl v1.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm1 + tbl v3.16b, {v1.16b}, v9.16b // vpshufb %xmm5, %xmm1, %xmm3 + eor v4.16b, v4.16b, v1.16b // vpxor %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v3.16b, v3.16b, v4.16b // vpxor %xmm4, %xmm3, %xmm3 + + b Lschedule_mangle_both +.align 4 +Lschedule_mangle_dec: + // inverse mix columns + // lea .Lk_dksd(%rip),%r11 + ushr v1.16b, v4.16b, #4 // vpsrlb $4, %xmm4, %xmm1 # 1 = hi + and v4.16b, v4.16b, v17.16b // vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + // vmovdqa 0x00(%r11), %xmm2 + tbl v2.16b, {v24.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + // vmovdqa 0x10(%r11), %xmm3 + tbl v3.16b, {v25.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x20(%r11), %xmm2 + tbl v2.16b, {v26.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x30(%r11), %xmm3 + tbl v3.16b, {v27.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x40(%r11), %xmm2 + tbl v2.16b, {v28.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x50(%r11), %xmm3 + tbl v3.16b, {v29.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + + // vmovdqa 0x60(%r11), %xmm2 + tbl v2.16b, {v30.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + // vmovdqa 0x70(%r11), %xmm4 + tbl v4.16b, {v31.16b}, v1.16b // vpshufb %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + eor v3.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm3 + + sub x2, x2, #16 // add $-16, %rdx + +Lschedule_mangle_both: + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + add x8, x8, #48 // add $-16, %r8 + and x8, x8, #~(1<<6) // and $0x30, %r8 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + ret + + +.globl _vpaes_set_encrypt_key +.private_extern _vpaes_set_encrypt_key + +.align 4 +_vpaes_set_encrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov w3, #0 // mov $0,%ecx + mov x8, #0x30 // mov $0x30,%r8d + bl _vpaes_schedule_core + eor x0, x0, x0 + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +.globl _vpaes_set_decrypt_key +.private_extern _vpaes_set_decrypt_key + +.align 4 +_vpaes_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl w9, w9, #4 // shl $4,%eax + add x2, x2, #16 // lea 16(%rdx,%rax),%rdx + add x2, x2, x9 + + mov w3, #1 // mov $1,%ecx + lsr w8, w1, #1 // shr $1,%r8d + and x8, x8, #32 // and $32,%r8d + eor x8, x8, #32 // xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _vpaes_cbc_encrypt +.private_extern _vpaes_cbc_encrypt + +.align 4 +_vpaes_cbc_encrypt: + AARCH64_SIGN_LINK_REGISTER + cbz x2, Lcbc_abort + cmp w5, #0 // check direction + b.eq vpaes_cbc_decrypt + + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x17, x2 // reassign + mov x2, x3 // reassign + + ld1 {v0.16b}, [x4] // load ivec + bl _vpaes_encrypt_preheat + b Lcbc_enc_loop + +.align 4 +Lcbc_enc_loop: + ld1 {v7.16b}, [x0],#16 // load input + eor v7.16b, v7.16b, v0.16b // xor with ivec + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 // save output + subs x17, x17, #16 + b.hi Lcbc_enc_loop + + st1 {v0.16b}, [x4] // write ivec + + ldp x29,x30,[sp],#16 +Lcbc_abort: + AARCH64_VALIDATE_LINK_REGISTER + ret + + + +.align 4 +vpaes_cbc_decrypt: + // Not adding AARCH64_SIGN_LINK_REGISTER here because vpaes_cbc_decrypt is jumped to + // only from vpaes_cbc_encrypt which has already signed the return address. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 // reassign + mov x2, x3 // reassign + ld1 {v6.16b}, [x4] // load ivec + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq Lcbc_dec_loop2x + + ld1 {v7.16b}, [x0], #16 // load input + bl _vpaes_decrypt_core + eor v0.16b, v0.16b, v6.16b // xor with ivec + orr v6.16b, v7.16b, v7.16b // next ivec value + st1 {v0.16b}, [x1], #16 + subs x17, x17, #16 + b.ls Lcbc_dec_done + +.align 4 +Lcbc_dec_loop2x: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + eor v0.16b, v0.16b, v6.16b // xor with ivec + eor v1.16b, v1.16b, v14.16b + orr v6.16b, v15.16b, v15.16b + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi Lcbc_dec_loop2x + +Lcbc_dec_done: + st1 {v6.16b}, [x4] + + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _vpaes_ctr32_encrypt_blocks +.private_extern _vpaes_ctr32_encrypt_blocks + +.align 4 +_vpaes_ctr32_encrypt_blocks: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + cbz x2, Lctr32_done + + // Note, unlike the other functions, x2 here is measured in blocks, + // not bytes. + mov x17, x2 + mov x2, x3 + + // Load the IV and counter portion. + ldr w6, [x4, #12] + ld1 {v7.16b}, [x4] + + bl _vpaes_encrypt_preheat + tst x17, #1 + rev w6, w6 // The counter is big-endian. + b.eq Lctr32_prep_loop + + // Handle one block so the remaining block count is even for + // _vpaes_encrypt_2x. + ld1 {v6.16b}, [x0], #16 // Load input ahead of time + bl _vpaes_encrypt_core + eor v0.16b, v0.16b, v6.16b // XOR input and result + st1 {v0.16b}, [x1], #16 + subs x17, x17, #1 + // Update the counter. + add w6, w6, #1 + rev w7, w6 + mov v7.s[3], w7 + b.ls Lctr32_done + +Lctr32_prep_loop: + // _vpaes_encrypt_core takes its input from v7, while _vpaes_encrypt_2x + // uses v14 and v15. + mov v15.16b, v7.16b + mov v14.16b, v7.16b + add w6, w6, #1 + rev w7, w6 + mov v15.s[3], w7 + +Lctr32_loop: + ld1 {v6.16b,v7.16b}, [x0], #32 // Load input ahead of time + bl _vpaes_encrypt_2x + eor v0.16b, v0.16b, v6.16b // XOR input and result + eor v1.16b, v1.16b, v7.16b // XOR input and result (#2) + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #2 + // Update the counter. + add w7, w6, #1 + add w6, w6, #2 + rev w7, w7 + mov v14.s[3], w7 + rev w7, w6 + mov v15.s[3], w7 + b.hi Lctr32_loop + +Lctr32_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif // !OPENSSL_NO_ASM +#endif // defined(__aarch64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S new file mode 100644 index 00000000..6034268a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S @@ -0,0 +1,1242 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__aarch64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) +#if defined(__aarch64__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.section .rodata + +.type _vpaes_consts,%object +.align 7 // totally strategic alignment +_vpaes_consts: +.Lk_mc_forward: // mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +.Lk_mc_backward: // mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +.Lk_sr: // sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +// +// "Hot" constants +// +.Lk_inv: // inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +.Lk_ipt: // input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +.Lk_sbo: // sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +.Lk_sb1: // sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.Lk_sb2: // sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +// +// Decryption stuff +// +.Lk_dipt: // decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +.Lk_dsbo: // decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.Lk_dsb9: // decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: // decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: // decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: // decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 + +// +// Key schedule constants +// +.Lk_dksd: // decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: // decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: // decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: // decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +.Lk_rcon: // rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_opt: // output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +.Lk_deskew: // deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 +.size _vpaes_consts,.-_vpaes_consts +.align 6 + +.text +## +## _aes_preheat +## +## Fills register %r10 -> .aes_consts (so you can -fPIC) +## and %xmm9-%xmm15 as specified below. +## +.type _vpaes_encrypt_preheat,%function +.align 4 +_vpaes_encrypt_preheat: + adrp x10, .Lk_inv + add x10, x10, :lo12:.Lk_inv + movi v17.16b, #0x0f + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64 // .Lk_ipt, .Lk_sbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10] // .Lk_sb1, .Lk_sb2 + ret +.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat + +## +## _aes_encrypt_core +## +## AES-encrypt %xmm0. +## +## Inputs: +## %xmm0 = input +## %xmm9-%xmm15 as in _vpaes_preheat +## (%rdx) = scheduled keys +## +## Output in %xmm0 +## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +## Preserves %xmm6 - %xmm8 so you get some local vectors +## +## +.type _vpaes_encrypt_core,%function +.align 4 +_vpaes_encrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adrp x11, .Lk_mc_forward+16 + add x11, x11, :lo12:.Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Lenc_entry + +.align 4 +.Lenc_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + sub w8, w8, #1 // nr-- + +.Lenc_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v5.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + +.globl vpaes_encrypt +.hidden vpaes_encrypt +.type vpaes_encrypt,%function +.align 4 +vpaes_encrypt: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_encrypt_preheat + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_encrypt,.-vpaes_encrypt + +.type _vpaes_encrypt_2x,%function +.align 4 +_vpaes_encrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adrp x11, .Lk_mc_forward+16 + add x11, x11, :lo12:.Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + tbl v9.16b, {v20.16b}, v9.16b + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + tbl v10.16b, {v21.16b}, v8.16b + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v8.16b, v9.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Lenc_2x_entry + +.align 4 +.Lenc_2x_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + tbl v12.16b, {v25.16b}, v10.16b + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + tbl v8.16b, {v24.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + tbl v13.16b, {v27.16b}, v10.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + tbl v10.16b, {v26.16b}, v11.16b + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + tbl v11.16b, {v8.16b}, v1.16b + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + eor v10.16b, v10.16b, v13.16b + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + tbl v8.16b, {v8.16b}, v4.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + eor v11.16b, v11.16b, v10.16b + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + tbl v12.16b, {v11.16b},v1.16b + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + eor v8.16b, v8.16b, v11.16b + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + eor v8.16b, v8.16b, v12.16b + sub w8, w8, #1 // nr-- + +.Lenc_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v5.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + tbl v13.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v13.16b + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v13.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_2x_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + tbl v8.16b, {v23.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v0.16b, {v0.16b},v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v1.16b + ret +.size _vpaes_encrypt_2x,.-_vpaes_encrypt_2x + +.type _vpaes_decrypt_preheat,%function +.align 4 +_vpaes_decrypt_preheat: + adrp x10, .Lk_inv + add x10, x10, :lo12:.Lk_inv + movi v17.16b, #0x0f + adrp x11, .Lk_dipt + add x11, x11, :lo12:.Lk_dipt + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64 // .Lk_dipt, .Lk_dsbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64 // .Lk_dsb9, .Lk_dsbd + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x11] // .Lk_dsbb, .Lk_dsbe + ret +.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat + +## +## Decryption core +## +## Same API as encryption core. +## +.type _vpaes_decrypt_core,%function +.align 4 +_vpaes_decrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adrp x10, .Lk_sr + add x10, x10, :lo12:.Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adrp x10, .Lk_mc_forward+48 + add x10, x10, :lo12:.Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Ldec_entry + +.align 4 +.Ldec_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + +.globl vpaes_decrypt +.hidden vpaes_decrypt +.type vpaes_decrypt,%function +.align 4 +vpaes_decrypt: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_decrypt_preheat + bl _vpaes_decrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_decrypt,.-vpaes_decrypt + +// v14-v15 input, v0-v1 output +.type _vpaes_decrypt_2x,%function +.align 4 +_vpaes_decrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adrp x10, .Lk_sr + add x10, x10, :lo12:.Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adrp x10, .Lk_mc_forward+48 + add x10, x10, :lo12:.Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v2.16b, {v20.16b},v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + tbl v10.16b, {v20.16b},v9.16b + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b},v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + tbl v8.16b, {v21.16b},v8.16b + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v10.16b, v10.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Ldec_2x_entry + +.align 4 +.Ldec_2x_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v12.16b, {v24.16b}, v10.16b + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + tbl v9.16b, {v25.16b}, v11.16b + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + eor v8.16b, v12.16b, v16.16b + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v12.16b, {v26.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + tbl v9.16b, {v27.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v12.16b, {v28.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + tbl v9.16b, {v29.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v12.16b, {v30.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + tbl v9.16b, {v31.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v2.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + tbl v10.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v10.16b + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v10.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_2x_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + tbl v9.16b, {v23.16b}, v11.16b + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + eor v8.16b, v9.16b, v12.16b + tbl v0.16b, {v0.16b},v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v2.16b + ret +.size _vpaes_decrypt_2x,.-_vpaes_decrypt_2x +######################################################## +## ## +## AES key schedule ## +## ## +######################################################## +.type _vpaes_key_preheat,%function +.align 4 +_vpaes_key_preheat: + adrp x10, .Lk_inv + add x10, x10, :lo12:.Lk_inv + movi v16.16b, #0x5b // .Lk_s63 + adrp x11, .Lk_sb1 + add x11, x11, :lo12:.Lk_sb1 + movi v17.16b, #0x0f // .Lk_s0F + ld1 {v18.2d,v19.2d,v20.2d,v21.2d}, [x10] // .Lk_inv, .Lk_ipt + adrp x10, .Lk_dksd + add x10, x10, :lo12:.Lk_dksd + ld1 {v22.2d,v23.2d}, [x11] // .Lk_sb1 + adrp x11, .Lk_mc_forward + add x11, x11, :lo12:.Lk_mc_forward + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64 // .Lk_dksd, .Lk_dksb + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64 // .Lk_dkse, .Lk_dks9 + ld1 {v8.2d}, [x10] // .Lk_rcon + ld1 {v9.2d}, [x11] // .Lk_mc_forward[0] + ret +.size _vpaes_key_preheat,.-_vpaes_key_preheat + +.type _vpaes_schedule_core,%function +.align 4 +_vpaes_schedule_core: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp,#-16]! + add x29,sp,#0 + + bl _vpaes_key_preheat // load the tables + + ld1 {v0.16b}, [x0],#16 // vmovdqu (%rdi), %xmm0 # load key (unaligned) + + // input transform + mov v3.16b, v0.16b // vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + mov v7.16b, v0.16b // vmovdqa %xmm0, %xmm7 + + adrp x10, .Lk_sr // lea .Lk_sr(%rip),%r10 + add x10, x10, :lo12:.Lk_sr + + add x8, x8, x10 + cbnz w3, .Lschedule_am_decrypting + + // encrypting, output zeroth round key after transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) + b .Lschedule_go + +.Lschedule_am_decrypting: + // decrypting, output zeroth round key after shiftrows + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + eor x8, x8, #0x30 // xor $0x30, %r8 + +.Lschedule_go: + cmp w1, #192 // cmp $192, %esi + b.hi .Lschedule_256 + b.eq .Lschedule_192 + // 128: fall though + +## +## .schedule_128 +## +## 128-bit specific part of key schedule. +## +## This schedule is really simple, because all its parts +## are accomplished by the subroutines. +## +.Lschedule_128: + mov x0, #10 // mov $10, %esi + +.Loop_schedule_128: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // write output + b .Loop_schedule_128 + +## +## .aes_schedule_192 +## +## 192-bit specific part of key schedule. +## +## The main body of this schedule is the same as the 128-bit +## schedule, but with more smearing. The long, high side is +## stored in %xmm7 as before, and the short, low side is in +## the high bits of %xmm6. +## +## This schedule is somewhat nastier, however, because each +## round produces 192 bits of key material, or 1.5 round keys. +## Therefore, on each cycle we do 2 rounds and produce 3 round +## keys. +## +.align 4 +.Lschedule_192: + sub x0, x0, #8 + ld1 {v0.16b}, [x0] // vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform // input transform + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save short part + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 # clear 4 + ins v6.d[0], v4.d[0] // vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov x0, #4 // mov $4, %esi + +.Loop_schedule_192: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + ext v0.16b, v6.16b, v0.16b, #8 // vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle // save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle // save key n+1 + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // save key n+2 + bl _vpaes_schedule_192_smear + b .Loop_schedule_192 + +## +## .aes_schedule_256 +## +## 256-bit specific part of key schedule. +## +## The structure here is very similar to the 128-bit +## schedule, but with an additional "low side" in +## %xmm6. The low side's rounds are the same as the +## high side's, except no rcon and no rotation. +## +.align 4 +.Lschedule_256: + ld1 {v0.16b}, [x0] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform // input transform + mov x0, #7 // mov $7, %esi + +.Loop_schedule_256: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_mangle // output low result + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + // high round + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle + + // low round. swap xmm7 and xmm6 + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + movi v4.16b, #0 + mov v5.16b, v7.16b // vmovdqa %xmm7, %xmm5 + mov v7.16b, v6.16b // vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + mov v7.16b, v5.16b // vmovdqa %xmm5, %xmm7 + + b .Loop_schedule_256 + +## +## .aes_schedule_mangle_last +## +## Mangler for last round of key schedule +## Mangles %xmm0 +## when encrypting, outputs out(%xmm0) ^ 63 +## when decrypting, outputs unskew(%xmm0) +## +## Always called right before return... jumps to cleanup and exits +## +.align 4 +.Lschedule_mangle_last: + // schedule last round key from xmm0 + adrp x11, .Lk_deskew // lea .Lk_deskew(%rip),%r11 # prepare to deskew + add x11, x11, :lo12:.Lk_deskew + + cbnz w3, .Lschedule_mangle_last_dec + + // encrypting + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10),%xmm1 + adrp x11, .Lk_opt // lea .Lk_opt(%rip), %r11 # prepare to output transform + add x11, x11, :lo12:.Lk_opt + add x2, x2, #32 // add $32, %rdx + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 # output permute + +.Lschedule_mangle_last_dec: + ld1 {v20.2d,v21.2d}, [x11] // reload constants + sub x2, x2, #16 // add $-16, %rdx + eor v0.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform // output transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) # save last key + + // cleanup + eor v0.16b, v0.16b, v0.16b // vpxor %xmm0, %xmm0, %xmm0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v2.16b, v2.16b, v2.16b // vpxor %xmm2, %xmm2, %xmm2 + eor v3.16b, v3.16b, v3.16b // vpxor %xmm3, %xmm3, %xmm3 + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 + eor v5.16b, v5.16b, v5.16b // vpxor %xmm5, %xmm5, %xmm5 + eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 + eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 + ldp x29, x30, [sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core + +## +## .aes_schedule_192_smear +## +## Smear the short, low side in the 192-bit key schedule. +## +## Inputs: +## %xmm7: high side, b a x y +## %xmm6: low side, d c 0 0 +## %xmm13: 0 +## +## Outputs: +## %xmm6: b+c+d b+c 0 0 +## %xmm0: b+c+d b+c b a +## +.type _vpaes_schedule_192_smear,%function +.align 4 +_vpaes_schedule_192_smear: + movi v1.16b, #0 + dup v0.4s, v7.s[3] + ins v1.s[3], v6.s[2] // vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + ins v0.s[0], v7.s[2] // vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + eor v6.16b, v6.16b, v1.16b // vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v6.16b, v6.16b, v0.16b // vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + mov v0.16b, v6.16b // vmovdqa %xmm6, %xmm0 + ins v6.d[0], v1.d[0] // vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + +## +## .aes_schedule_round +## +## Runs one main round of the key schedule on %xmm0, %xmm7 +## +## Specifically, runs subbytes on the high dword of %xmm0 +## then rotates it by one byte and xors into the low dword of +## %xmm7. +## +## Adds rcon from low byte of %xmm8, then rotates %xmm8 for +## next rcon. +## +## Smears the dwords of %xmm7 by xoring the low into the +## second low, result into third, result into highest. +## +## Returns results in %xmm7 = %xmm0. +## Clobbers %xmm1-%xmm4, %r11. +## +.type _vpaes_schedule_round,%function +.align 4 +_vpaes_schedule_round: + // extract rcon from xmm8 + movi v4.16b, #0 // vpxor %xmm4, %xmm4, %xmm4 + ext v1.16b, v8.16b, v4.16b, #15 // vpalignr $15, %xmm8, %xmm4, %xmm1 + ext v8.16b, v8.16b, v8.16b, #15 // vpalignr $15, %xmm8, %xmm8, %xmm8 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + + // rotate + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + ext v0.16b, v0.16b, v0.16b, #1 // vpalignr $1, %xmm0, %xmm0, %xmm0 + + // fall through... + + // low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + // smear xmm7 + ext v1.16b, v4.16b, v7.16b, #12 // vpslldq $4, %xmm7, %xmm1 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + ext v4.16b, v4.16b, v7.16b, #8 // vpslldq $8, %xmm7, %xmm4 + + // subbytes + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + eor v7.16b, v7.16b, v4.16b // vpxor %xmm4, %xmm7, %xmm7 + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v7.16b, v7.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm7, %xmm7 + tbl v3.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + eor v3.16b, v3.16b, v1.16b // vpxor %xmm1, %xmm3, %xmm3 # 2 = io + eor v2.16b, v2.16b, v0.16b // vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + tbl v4.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + tbl v1.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + eor v1.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + // add in smeared stuff + eor v0.16b, v1.16b, v7.16b // vpxor %xmm7, %xmm1, %xmm0 + eor v7.16b, v1.16b, v7.16b // vmovdqa %xmm0, %xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round + +## +## .aes_schedule_transform +## +## Linear-transform %xmm0 according to tables at (%r11) +## +## Requires that %xmm9 = 0x0F0F... as in preheat +## Output in %xmm0 +## Clobbers %xmm1, %xmm2 +## +.type _vpaes_schedule_transform,%function +.align 4 +_vpaes_schedule_transform: + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + // vmovdqa (%r11), %xmm2 # lo + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + // vmovdqa 16(%r11), %xmm1 # hi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + +## +## .aes_schedule_mangle +## +## Mangle xmm0 from (basis-transformed) standard version +## to our version. +## +## On encrypt, +## xor with 0x63 +## multiply by circulant 0,1,1,1 +## apply shiftrows transform +## +## On decrypt, +## xor with 0x63 +## multiply by "inverse mixcolumns" circulant E,B,D,9 +## deskew +## apply shiftrows transform +## +## +## Writes out to (%rdx), and increments or decrements it +## Keeps track of round number mod 4 in %r8 +## Preserves xmm0 +## Clobbers xmm1-xmm5 +## +.type _vpaes_schedule_mangle,%function +.align 4 +_vpaes_schedule_mangle: + mov v4.16b, v0.16b // vmovdqa %xmm0, %xmm4 # save xmm0 for later + // vmovdqa .Lk_mc_forward(%rip),%xmm5 + cbnz w3, .Lschedule_mangle_dec + + // encrypting + eor v4.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm4 + add x2, x2, #16 // add $16, %rdx + tbl v4.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm4 + tbl v1.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm1 + tbl v3.16b, {v1.16b}, v9.16b // vpshufb %xmm5, %xmm1, %xmm3 + eor v4.16b, v4.16b, v1.16b // vpxor %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v3.16b, v3.16b, v4.16b // vpxor %xmm4, %xmm3, %xmm3 + + b .Lschedule_mangle_both +.align 4 +.Lschedule_mangle_dec: + // inverse mix columns + // lea .Lk_dksd(%rip),%r11 + ushr v1.16b, v4.16b, #4 // vpsrlb $4, %xmm4, %xmm1 # 1 = hi + and v4.16b, v4.16b, v17.16b // vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + // vmovdqa 0x00(%r11), %xmm2 + tbl v2.16b, {v24.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + // vmovdqa 0x10(%r11), %xmm3 + tbl v3.16b, {v25.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x20(%r11), %xmm2 + tbl v2.16b, {v26.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x30(%r11), %xmm3 + tbl v3.16b, {v27.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x40(%r11), %xmm2 + tbl v2.16b, {v28.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x50(%r11), %xmm3 + tbl v3.16b, {v29.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + + // vmovdqa 0x60(%r11), %xmm2 + tbl v2.16b, {v30.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + // vmovdqa 0x70(%r11), %xmm4 + tbl v4.16b, {v31.16b}, v1.16b // vpshufb %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + eor v3.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm3 + + sub x2, x2, #16 // add $-16, %rdx + +.Lschedule_mangle_both: + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + add x8, x8, #48 // add $-16, %r8 + and x8, x8, #~(1<<6) // and $0x30, %r8 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + +.globl vpaes_set_encrypt_key +.hidden vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,%function +.align 4 +vpaes_set_encrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov w3, #0 // mov $0,%ecx + mov x8, #0x30 // mov $0x30,%r8d + bl _vpaes_schedule_core + eor x0, x0, x0 + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.hidden vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,%function +.align 4 +vpaes_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl w9, w9, #4 // shl $4,%eax + add x2, x2, #16 // lea 16(%rdx,%rax),%rdx + add x2, x2, x9 + + mov w3, #1 // mov $1,%ecx + lsr w8, w1, #1 // shr $1,%r8d + and x8, x8, #32 // and $32,%r8d + eor x8, x8, #32 // xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key +.globl vpaes_cbc_encrypt +.hidden vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,%function +.align 4 +vpaes_cbc_encrypt: + AARCH64_SIGN_LINK_REGISTER + cbz x2, .Lcbc_abort + cmp w5, #0 // check direction + b.eq vpaes_cbc_decrypt + + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x17, x2 // reassign + mov x2, x3 // reassign + + ld1 {v0.16b}, [x4] // load ivec + bl _vpaes_encrypt_preheat + b .Lcbc_enc_loop + +.align 4 +.Lcbc_enc_loop: + ld1 {v7.16b}, [x0],#16 // load input + eor v7.16b, v7.16b, v0.16b // xor with ivec + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 // save output + subs x17, x17, #16 + b.hi .Lcbc_enc_loop + + st1 {v0.16b}, [x4] // write ivec + + ldp x29,x30,[sp],#16 +.Lcbc_abort: + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt + +.type vpaes_cbc_decrypt,%function +.align 4 +vpaes_cbc_decrypt: + // Not adding AARCH64_SIGN_LINK_REGISTER here because vpaes_cbc_decrypt is jumped to + // only from vpaes_cbc_encrypt which has already signed the return address. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 // reassign + mov x2, x3 // reassign + ld1 {v6.16b}, [x4] // load ivec + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq .Lcbc_dec_loop2x + + ld1 {v7.16b}, [x0], #16 // load input + bl _vpaes_decrypt_core + eor v0.16b, v0.16b, v6.16b // xor with ivec + orr v6.16b, v7.16b, v7.16b // next ivec value + st1 {v0.16b}, [x1], #16 + subs x17, x17, #16 + b.ls .Lcbc_dec_done + +.align 4 +.Lcbc_dec_loop2x: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + eor v0.16b, v0.16b, v6.16b // xor with ivec + eor v1.16b, v1.16b, v14.16b + orr v6.16b, v15.16b, v15.16b + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lcbc_dec_loop2x + +.Lcbc_dec_done: + st1 {v6.16b}, [x4] + + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt +.globl vpaes_ctr32_encrypt_blocks +.hidden vpaes_ctr32_encrypt_blocks +.type vpaes_ctr32_encrypt_blocks,%function +.align 4 +vpaes_ctr32_encrypt_blocks: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + cbz x2, .Lctr32_done + + // Note, unlike the other functions, x2 here is measured in blocks, + // not bytes. + mov x17, x2 + mov x2, x3 + + // Load the IV and counter portion. + ldr w6, [x4, #12] + ld1 {v7.16b}, [x4] + + bl _vpaes_encrypt_preheat + tst x17, #1 + rev w6, w6 // The counter is big-endian. + b.eq .Lctr32_prep_loop + + // Handle one block so the remaining block count is even for + // _vpaes_encrypt_2x. + ld1 {v6.16b}, [x0], #16 // .Load input ahead of time + bl _vpaes_encrypt_core + eor v0.16b, v0.16b, v6.16b // XOR input and result + st1 {v0.16b}, [x1], #16 + subs x17, x17, #1 + // Update the counter. + add w6, w6, #1 + rev w7, w6 + mov v7.s[3], w7 + b.ls .Lctr32_done + +.Lctr32_prep_loop: + // _vpaes_encrypt_core takes its input from v7, while _vpaes_encrypt_2x + // uses v14 and v15. + mov v15.16b, v7.16b + mov v14.16b, v7.16b + add w6, w6, #1 + rev w7, w6 + mov v15.s[3], w7 + +.Lctr32_loop: + ld1 {v6.16b,v7.16b}, [x0], #32 // .Load input ahead of time + bl _vpaes_encrypt_2x + eor v0.16b, v0.16b, v6.16b // XOR input and result + eor v1.16b, v1.16b, v7.16b // XOR input and result (#2) + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #2 + // Update the counter. + add w7, w6, #1 + add w6, w6, #2 + rev w7, w7 + mov v14.s[3], w7 + rev w7, w6 + mov v15.s[3], w7 + b.hi .Lctr32_loop + +.Lctr32_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif +#endif // !OPENSSL_NO_ASM +.section .note.GNU-stack,"",%progbits +#endif // defined(__aarch64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S new file mode 100644 index 00000000..a44f2e16 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S @@ -0,0 +1,715 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +#ifdef BORINGSSL_DISPATCH_TEST +#endif +.align 64 +.L_vpaes_consts: +.long 218628480,235210255,168496130,67568393 +.long 252381056,17041926,33884169,51187212 +.long 252645135,252645135,252645135,252645135 +.long 1512730624,3266504856,1377990664,3401244816 +.long 830229760,1275146365,2969422977,3447763452 +.long 3411033600,2979783055,338359620,2782886510 +.long 4209124096,907596821,221174255,1006095553 +.long 191964160,3799684038,3164090317,1589111125 +.long 182528256,1777043520,2877432650,3265356744 +.long 1874708224,3503451415,3305285752,363511674 +.long 1606117888,3487855781,1093350906,2384367825 +.long 197121,67569157,134941193,202313229 +.long 67569157,134941193,202313229,197121 +.long 134941193,202313229,197121,67569157 +.long 202313229,197121,67569157,134941193 +.long 33619971,100992007,168364043,235736079 +.long 235736079,33619971,100992007,168364043 +.long 168364043,235736079,33619971,100992007 +.long 100992007,168364043,235736079,33619971 +.long 50462976,117835012,185207048,252579084 +.long 252314880,51251460,117574920,184942860 +.long 184682752,252054788,50987272,118359308 +.long 118099200,185467140,251790600,50727180 +.long 2946363062,528716217,1300004225,1881839624 +.long 1532713819,1532713819,1532713819,1532713819 +.long 3602276352,4288629033,3737020424,4153884961 +.long 1354558464,32357713,2958822624,3775749553 +.long 1201988352,132424512,1572796698,503232858 +.long 2213177600,1597421020,4103937655,675398315 +.long 2749646592,4273543773,1511898873,121693092 +.long 3040248576,1103263732,2871565598,1608280554 +.long 2236667136,2588920351,482954393,64377734 +.long 3069987328,291237287,2117370568,3650299247 +.long 533321216,3573750986,2572112006,1401264716 +.long 1339849704,2721158661,548607111,3445553514 +.long 2128193280,3054596040,2183486460,1257083700 +.long 655635200,1165381986,3923443150,2344132524 +.long 190078720,256924420,290342170,357187870 +.long 1610966272,2263057382,4103205268,309794674 +.long 2592527872,2233205587,1335446729,3402964816 +.long 3973531904,3225098121,3002836325,1918774430 +.long 3870401024,2102906079,2284471353,4117666579 +.long 617007872,1021508343,366931923,691083277 +.long 2528395776,3491914898,2968704004,1613121270 +.long 3445188352,3247741094,844474987,4093578302 +.long 651481088,1190302358,1689581232,574775300 +.long 4289380608,206939853,2555985458,2489840491 +.long 2130264064,327674451,3566485037,3349835193 +.long 2470714624,316102159,3636825756,3393945945 +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105 +.byte 111,110,32,65,69,83,32,102,111,114,32,120,56,54,47,83 +.byte 83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117 +.byte 114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105 +.byte 118,101,114,115,105,116,121,41,0 +.align 64 +.hidden _vpaes_preheat +.type _vpaes_preheat,@function +.align 16 +_vpaes_preheat: + addl (%esp),%ebp + movdqa -48(%ebp),%xmm7 + movdqa -16(%ebp),%xmm6 + ret +.size _vpaes_preheat,.-_vpaes_preheat +.hidden _vpaes_encrypt_core +.type _vpaes_encrypt_core,@function +.align 16 +_vpaes_encrypt_core: + movl $16,%ecx + movl 240(%edx),%eax + movdqa %xmm6,%xmm1 + movdqa (%ebp),%xmm2 + pandn %xmm0,%xmm1 + pand %xmm6,%xmm0 + movdqu (%edx),%xmm5 +.byte 102,15,56,0,208 + movdqa 16(%ebp),%xmm0 + pxor %xmm5,%xmm2 + psrld $4,%xmm1 + addl $16,%edx +.byte 102,15,56,0,193 + leal 192(%ebp),%ebx + pxor %xmm2,%xmm0 + jmp .L000enc_entry +.align 16 +.L001enc_loop: + movdqa 32(%ebp),%xmm4 + movdqa 48(%ebp),%xmm0 +.byte 102,15,56,0,226 +.byte 102,15,56,0,195 + pxor %xmm5,%xmm4 + movdqa 64(%ebp),%xmm5 + pxor %xmm4,%xmm0 + movdqa -64(%ebx,%ecx,1),%xmm1 +.byte 102,15,56,0,234 + movdqa 80(%ebp),%xmm2 + movdqa (%ebx,%ecx,1),%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm0,%xmm3 + pxor %xmm5,%xmm2 +.byte 102,15,56,0,193 + addl $16,%edx + pxor %xmm2,%xmm0 +.byte 102,15,56,0,220 + addl $16,%ecx + pxor %xmm0,%xmm3 +.byte 102,15,56,0,193 + andl $48,%ecx + subl $1,%eax + pxor %xmm3,%xmm0 +.L000enc_entry: + movdqa %xmm6,%xmm1 + movdqa -32(%ebp),%xmm5 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm6,%xmm0 +.byte 102,15,56,0,232 + movdqa %xmm7,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm7,%xmm4 + pxor %xmm5,%xmm3 +.byte 102,15,56,0,224 + movdqa %xmm7,%xmm2 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm7,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%edx),%xmm5 + pxor %xmm1,%xmm3 + jnz .L001enc_loop + movdqa 96(%ebp),%xmm4 + movdqa 112(%ebp),%xmm0 +.byte 102,15,56,0,226 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,195 + movdqa 64(%ebx,%ecx,1),%xmm1 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,193 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core +.hidden _vpaes_decrypt_core +.type _vpaes_decrypt_core,@function +.align 16 +_vpaes_decrypt_core: + leal 608(%ebp),%ebx + movl 240(%edx),%eax + movdqa %xmm6,%xmm1 + movdqa -64(%ebx),%xmm2 + pandn %xmm0,%xmm1 + movl %eax,%ecx + psrld $4,%xmm1 + movdqu (%edx),%xmm5 + shll $4,%ecx + pand %xmm6,%xmm0 +.byte 102,15,56,0,208 + movdqa -48(%ebx),%xmm0 + xorl $48,%ecx +.byte 102,15,56,0,193 + andl $48,%ecx + pxor %xmm5,%xmm2 + movdqa 176(%ebp),%xmm5 + pxor %xmm2,%xmm0 + addl $16,%edx + leal -352(%ebx,%ecx,1),%ecx + jmp .L002dec_entry +.align 16 +.L003dec_loop: + movdqa -32(%ebx),%xmm4 + movdqa -16(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa (%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 16(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 32(%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 48(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 64(%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 80(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + addl $16,%edx +.byte 102,15,58,15,237,12 + pxor %xmm1,%xmm0 + subl $1,%eax +.L002dec_entry: + movdqa %xmm6,%xmm1 + movdqa -32(%ebp),%xmm2 + pandn %xmm0,%xmm1 + pand %xmm6,%xmm0 + psrld $4,%xmm1 +.byte 102,15,56,0,208 + movdqa %xmm7,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm7,%xmm4 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm7,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm7,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%edx),%xmm0 + pxor %xmm1,%xmm3 + jnz .L003dec_loop + movdqa 96(%ebx),%xmm4 +.byte 102,15,56,0,226 + pxor %xmm0,%xmm4 + movdqa 112(%ebx),%xmm0 + movdqa (%ecx),%xmm2 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,194 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core +.hidden _vpaes_schedule_core +.type _vpaes_schedule_core,@function +.align 16 +_vpaes_schedule_core: + addl (%esp),%ebp + movdqu (%esi),%xmm0 + movdqa 320(%ebp),%xmm2 + movdqa %xmm0,%xmm3 + leal (%ebp),%ebx + movdqa %xmm2,4(%esp) + call _vpaes_schedule_transform + movdqa %xmm0,%xmm7 + testl %edi,%edi + jnz .L004schedule_am_decrypting + movdqu %xmm0,(%edx) + jmp .L005schedule_go +.L004schedule_am_decrypting: + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,217 + movdqu %xmm3,(%edx) + xorl $48,%ecx +.L005schedule_go: + cmpl $192,%eax + ja .L006schedule_256 + je .L007schedule_192 +.L008schedule_128: + movl $10,%eax +.L009loop_schedule_128: + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + jmp .L009loop_schedule_128 +.align 16 +.L007schedule_192: + movdqu 8(%esi),%xmm0 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm6 + pxor %xmm4,%xmm4 + movhlps %xmm4,%xmm6 + movl $4,%eax +.L011loop_schedule_192: + call _vpaes_schedule_round +.byte 102,15,58,15,198,8 + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + jmp .L011loop_schedule_192 +.align 16 +.L006schedule_256: + movdqu 16(%esi),%xmm0 + call _vpaes_schedule_transform + movl $7,%eax +.L012loop_schedule_256: + call _vpaes_schedule_mangle + movdqa %xmm0,%xmm6 + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + pshufd $255,%xmm0,%xmm0 + movdqa %xmm7,20(%esp) + movdqa %xmm6,%xmm7 + call .L_vpaes_schedule_low_round + movdqa 20(%esp),%xmm7 + jmp .L012loop_schedule_256 +.align 16 +.L010schedule_mangle_last: + leal 384(%ebp),%ebx + testl %edi,%edi + jnz .L013schedule_mangle_last_dec + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,193 + leal 352(%ebp),%ebx + addl $32,%edx +.L013schedule_mangle_last_dec: + addl $-16,%edx + pxor 336(%ebp),%xmm0 + call _vpaes_schedule_transform + movdqu %xmm0,(%edx) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core +.hidden _vpaes_schedule_192_smear +.type _vpaes_schedule_192_smear,@function +.align 16 +_vpaes_schedule_192_smear: + pshufd $128,%xmm6,%xmm1 + pshufd $254,%xmm7,%xmm0 + pxor %xmm1,%xmm6 + pxor %xmm1,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm6,%xmm0 + movhlps %xmm1,%xmm6 + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear +.hidden _vpaes_schedule_round +.type _vpaes_schedule_round,@function +.align 16 +_vpaes_schedule_round: + movdqa 8(%esp),%xmm2 + pxor %xmm1,%xmm1 +.byte 102,15,58,15,202,15 +.byte 102,15,58,15,210,15 + pxor %xmm1,%xmm7 + pshufd $255,%xmm0,%xmm0 +.byte 102,15,58,15,192,1 + movdqa %xmm2,8(%esp) +.L_vpaes_schedule_low_round: + movdqa %xmm7,%xmm1 + pslldq $4,%xmm7 + pxor %xmm1,%xmm7 + movdqa %xmm7,%xmm1 + pslldq $8,%xmm7 + pxor %xmm1,%xmm7 + pxor 336(%ebp),%xmm7 + movdqa -16(%ebp),%xmm4 + movdqa -48(%ebp),%xmm5 + movdqa %xmm4,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm4,%xmm0 + movdqa -32(%ebp),%xmm2 +.byte 102,15,56,0,208 + pxor %xmm1,%xmm0 + movdqa %xmm5,%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + movdqa %xmm5,%xmm4 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm5,%xmm2 +.byte 102,15,56,0,211 + pxor %xmm0,%xmm2 + movdqa %xmm5,%xmm3 +.byte 102,15,56,0,220 + pxor %xmm1,%xmm3 + movdqa 32(%ebp),%xmm4 +.byte 102,15,56,0,226 + movdqa 48(%ebp),%xmm0 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 + pxor %xmm7,%xmm0 + movdqa %xmm0,%xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round +.hidden _vpaes_schedule_transform +.type _vpaes_schedule_transform,@function +.align 16 +_vpaes_schedule_transform: + movdqa -16(%ebp),%xmm2 + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + movdqa (%ebx),%xmm2 +.byte 102,15,56,0,208 + movdqa 16(%ebx),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm2,%xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform +.hidden _vpaes_schedule_mangle +.type _vpaes_schedule_mangle,@function +.align 16 +_vpaes_schedule_mangle: + movdqa %xmm0,%xmm4 + movdqa 128(%ebp),%xmm5 + testl %edi,%edi + jnz .L014schedule_mangle_dec + addl $16,%edx + pxor 336(%ebp),%xmm4 +.byte 102,15,56,0,229 + movdqa %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 + jmp .L015schedule_mangle_both +.align 16 +.L014schedule_mangle_dec: + movdqa -16(%ebp),%xmm2 + leal 416(%ebp),%esi + movdqa %xmm2,%xmm1 + pandn %xmm4,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm4 + movdqa (%esi),%xmm2 +.byte 102,15,56,0,212 + movdqa 16(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 32(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 48(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 64(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 80(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 96(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 112(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + addl $-16,%edx +.L015schedule_mangle_both: + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,217 + addl $-16,%ecx + andl $48,%ecx + movdqu %xmm3,(%edx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle +.globl vpaes_set_encrypt_key +.hidden vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,@function +.align 16 +vpaes_set_encrypt_key: +.L_vpaes_set_encrypt_key_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +#ifdef BORINGSSL_DISPATCH_TEST + pushl %ebx + pushl %edx + call .L016pic +.L016pic: + popl %ebx + leal BORINGSSL_function_hit+5-.L016pic(%ebx),%ebx + movl $1,%edx + movb %dl,(%ebx) + popl %edx + popl %ebx +#endif + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%eax + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movl %eax,%ebx + shrl $5,%ebx + addl $5,%ebx + movl %ebx,240(%edx) + movl $48,%ecx + movl $0,%edi + leal .L_vpaes_consts+0x30-.L017pic_point,%ebp + call _vpaes_schedule_core +.L017pic_point: + movl 48(%esp),%esp + xorl %eax,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_set_encrypt_key,.-.L_vpaes_set_encrypt_key_begin +.globl vpaes_set_decrypt_key +.hidden vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,@function +.align 16 +vpaes_set_decrypt_key: +.L_vpaes_set_decrypt_key_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%eax + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movl %eax,%ebx + shrl $5,%ebx + addl $5,%ebx + movl %ebx,240(%edx) + shll $4,%ebx + leal 16(%edx,%ebx,1),%edx + movl $1,%edi + movl %eax,%ecx + shrl $1,%ecx + andl $32,%ecx + xorl $32,%ecx + leal .L_vpaes_consts+0x30-.L018pic_point,%ebp + call _vpaes_schedule_core +.L018pic_point: + movl 48(%esp),%esp + xorl %eax,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_set_decrypt_key,.-.L_vpaes_set_decrypt_key_begin +.globl vpaes_encrypt +.hidden vpaes_encrypt +.type vpaes_encrypt,@function +.align 16 +vpaes_encrypt: +.L_vpaes_encrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +#ifdef BORINGSSL_DISPATCH_TEST + pushl %ebx + pushl %edx + call .L019pic +.L019pic: + popl %ebx + leal BORINGSSL_function_hit+4-.L019pic(%ebx),%ebx + movl $1,%edx + movb %dl,(%ebx) + popl %edx + popl %ebx +#endif + leal .L_vpaes_consts+0x30-.L020pic_point,%ebp + call _vpaes_preheat +.L020pic_point: + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%edi + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movdqu (%esi),%xmm0 + call _vpaes_encrypt_core + movdqu %xmm0,(%edi) + movl 48(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_encrypt,.-.L_vpaes_encrypt_begin +.globl vpaes_decrypt +.hidden vpaes_decrypt +.type vpaes_decrypt,@function +.align 16 +vpaes_decrypt: +.L_vpaes_decrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + leal .L_vpaes_consts+0x30-.L021pic_point,%ebp + call _vpaes_preheat +.L021pic_point: + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%edi + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movdqu (%esi),%xmm0 + call _vpaes_decrypt_core + movdqu %xmm0,(%edi) + movl 48(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_decrypt,.-.L_vpaes_decrypt_begin +.globl vpaes_cbc_encrypt +.hidden vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,@function +.align 16 +vpaes_cbc_encrypt: +.L_vpaes_cbc_encrypt_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + subl $16,%eax + jc .L022cbc_abort + leal -56(%esp),%ebx + movl 36(%esp),%ebp + andl $-16,%ebx + movl 40(%esp),%ecx + xchgl %esp,%ebx + movdqu (%ebp),%xmm1 + subl %esi,%edi + movl %ebx,48(%esp) + movl %edi,(%esp) + movl %edx,4(%esp) + movl %ebp,8(%esp) + movl %eax,%edi + leal .L_vpaes_consts+0x30-.L023pic_point,%ebp + call _vpaes_preheat +.L023pic_point: + cmpl $0,%ecx + je .L024cbc_dec_loop + jmp .L025cbc_enc_loop +.align 16 +.L025cbc_enc_loop: + movdqu (%esi),%xmm0 + pxor %xmm1,%xmm0 + call _vpaes_encrypt_core + movl (%esp),%ebx + movl 4(%esp),%edx + movdqa %xmm0,%xmm1 + movdqu %xmm0,(%ebx,%esi,1) + leal 16(%esi),%esi + subl $16,%edi + jnc .L025cbc_enc_loop + jmp .L026cbc_done +.align 16 +.L024cbc_dec_loop: + movdqu (%esi),%xmm0 + movdqa %xmm1,16(%esp) + movdqa %xmm0,32(%esp) + call _vpaes_decrypt_core + movl (%esp),%ebx + movl 4(%esp),%edx + pxor 16(%esp),%xmm0 + movdqa 32(%esp),%xmm1 + movdqu %xmm0,(%ebx,%esi,1) + leal 16(%esi),%esi + subl $16,%edi + jnc .L024cbc_dec_loop +.L026cbc_done: + movl 8(%esp),%ebx + movl 48(%esp),%esp + movdqu %xmm1,(%ebx) +.L022cbc_abort: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_cbc_encrypt,.-.L_vpaes_cbc_encrypt_begin +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S new file mode 100644 index 00000000..c821d36a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S @@ -0,0 +1,1140 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + + + + + + + + + + + + + +.type _vpaes_encrypt_core,@function +.align 16 +_vpaes_encrypt_core: +.cfi_startproc + movq %rdx,%r9 + movq $16,%r11 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa .Lk_ipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movdqu (%r9),%xmm5 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa .Lk_ipt+16(%rip),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm5,%xmm2 + addq $16,%r9 + pxor %xmm2,%xmm0 + leaq .Lk_mc_backward(%rip),%r10 + jmp .Lenc_entry + +.align 16 +.Lenc_loop: + + movdqa %xmm13,%xmm4 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,226 +.byte 102,15,56,0,195 + pxor %xmm5,%xmm4 + movdqa %xmm15,%xmm5 + pxor %xmm4,%xmm0 + movdqa -64(%r11,%r10,1),%xmm1 +.byte 102,15,56,0,234 + movdqa (%r11,%r10,1),%xmm4 + movdqa %xmm14,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm0,%xmm3 + pxor %xmm5,%xmm2 +.byte 102,15,56,0,193 + addq $16,%r9 + pxor %xmm2,%xmm0 +.byte 102,15,56,0,220 + addq $16,%r11 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,193 + andq $0x30,%r11 + subq $1,%rax + pxor %xmm3,%xmm0 + +.Lenc_entry: + + movdqa %xmm9,%xmm1 + movdqa %xmm11,%xmm5 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,232 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm5,%xmm3 +.byte 102,15,56,0,224 + movdqa %xmm10,%xmm2 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm5 + pxor %xmm1,%xmm3 + jnz .Lenc_loop + + + movdqa -96(%r10),%xmm4 + movdqa -80(%r10),%xmm0 +.byte 102,15,56,0,226 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,195 + movdqa 64(%r11,%r10,1),%xmm1 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,193 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.type _vpaes_encrypt_core_2x,@function +.align 16 +_vpaes_encrypt_core_2x: +.cfi_startproc + movq %rdx,%r9 + movq $16,%r11 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa %xmm9,%xmm7 + movdqa .Lk_ipt(%rip),%xmm2 + movdqa %xmm2,%xmm8 + pandn %xmm0,%xmm1 + pandn %xmm6,%xmm7 + movdqu (%r9),%xmm5 + + psrld $4,%xmm1 + psrld $4,%xmm7 + pand %xmm9,%xmm0 + pand %xmm9,%xmm6 +.byte 102,15,56,0,208 +.byte 102,68,15,56,0,198 + movdqa .Lk_ipt+16(%rip),%xmm0 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,247 + pxor %xmm5,%xmm2 + pxor %xmm5,%xmm8 + addq $16,%r9 + pxor %xmm2,%xmm0 + pxor %xmm8,%xmm6 + leaq .Lk_mc_backward(%rip),%r10 + jmp .Lenc2x_entry + +.align 16 +.Lenc2x_loop: + + movdqa .Lk_sb1(%rip),%xmm4 + movdqa .Lk_sb1+16(%rip),%xmm0 + movdqa %xmm4,%xmm12 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,226 +.byte 102,69,15,56,0,224 +.byte 102,15,56,0,195 +.byte 102,65,15,56,0,243 + pxor %xmm5,%xmm4 + pxor %xmm5,%xmm12 + movdqa .Lk_sb2(%rip),%xmm5 + movdqa %xmm5,%xmm13 + pxor %xmm4,%xmm0 + pxor %xmm12,%xmm6 + movdqa -64(%r11,%r10,1),%xmm1 + +.byte 102,15,56,0,234 +.byte 102,69,15,56,0,232 + movdqa (%r11,%r10,1),%xmm4 + + movdqa .Lk_sb2+16(%rip),%xmm2 + movdqa %xmm2,%xmm8 +.byte 102,15,56,0,211 +.byte 102,69,15,56,0,195 + movdqa %xmm0,%xmm3 + movdqa %xmm6,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm13,%xmm8 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + addq $16,%r9 + pxor %xmm2,%xmm0 + pxor %xmm8,%xmm6 +.byte 102,15,56,0,220 +.byte 102,68,15,56,0,220 + addq $16,%r11 + pxor %xmm0,%xmm3 + pxor %xmm6,%xmm11 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + andq $0x30,%r11 + subq $1,%rax + pxor %xmm3,%xmm0 + pxor %xmm11,%xmm6 + +.Lenc2x_entry: + + movdqa %xmm9,%xmm1 + movdqa %xmm9,%xmm7 + movdqa .Lk_inv+16(%rip),%xmm5 + movdqa %xmm5,%xmm13 + pandn %xmm0,%xmm1 + pandn %xmm6,%xmm7 + psrld $4,%xmm1 + psrld $4,%xmm7 + pand %xmm9,%xmm0 + pand %xmm9,%xmm6 +.byte 102,15,56,0,232 +.byte 102,68,15,56,0,238 + movdqa %xmm10,%xmm3 + movdqa %xmm10,%xmm11 + pxor %xmm1,%xmm0 + pxor %xmm7,%xmm6 +.byte 102,15,56,0,217 +.byte 102,68,15,56,0,223 + movdqa %xmm10,%xmm4 + movdqa %xmm10,%xmm12 + pxor %xmm5,%xmm3 + pxor %xmm13,%xmm11 +.byte 102,15,56,0,224 +.byte 102,68,15,56,0,230 + movdqa %xmm10,%xmm2 + movdqa %xmm10,%xmm8 + pxor %xmm5,%xmm4 + pxor %xmm13,%xmm12 +.byte 102,15,56,0,211 +.byte 102,69,15,56,0,195 + movdqa %xmm10,%xmm3 + movdqa %xmm10,%xmm11 + pxor %xmm0,%xmm2 + pxor %xmm6,%xmm8 +.byte 102,15,56,0,220 +.byte 102,69,15,56,0,220 + movdqu (%r9),%xmm5 + + pxor %xmm1,%xmm3 + pxor %xmm7,%xmm11 + jnz .Lenc2x_loop + + + movdqa -96(%r10),%xmm4 + movdqa -80(%r10),%xmm0 + movdqa %xmm4,%xmm12 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,226 +.byte 102,69,15,56,0,224 + pxor %xmm5,%xmm4 + pxor %xmm5,%xmm12 +.byte 102,15,56,0,195 +.byte 102,65,15,56,0,243 + movdqa 64(%r11,%r10,1),%xmm1 + + pxor %xmm4,%xmm0 + pxor %xmm12,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_encrypt_core_2x,.-_vpaes_encrypt_core_2x + + + + + + +.type _vpaes_decrypt_core,@function +.align 16 +_vpaes_decrypt_core: +.cfi_startproc + movq %rdx,%r9 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa .Lk_dipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movq %rax,%r11 + psrld $4,%xmm1 + movdqu (%r9),%xmm5 + shlq $4,%r11 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa .Lk_dipt+16(%rip),%xmm0 + xorq $0x30,%r11 + leaq .Lk_dsbd(%rip),%r10 +.byte 102,15,56,0,193 + andq $0x30,%r11 + pxor %xmm5,%xmm2 + movdqa .Lk_mc_forward+48(%rip),%xmm5 + pxor %xmm2,%xmm0 + addq $16,%r9 + addq %r10,%r11 + jmp .Ldec_entry + +.align 16 +.Ldec_loop: + + + + movdqa -32(%r10),%xmm4 + movdqa -16(%r10),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 0(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 16(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 32(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 48(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 64(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 80(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + addq $16,%r9 +.byte 102,15,58,15,237,12 + pxor %xmm1,%xmm0 + subq $1,%rax + +.Ldec_entry: + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + movdqa %xmm11,%xmm2 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm0 + pxor %xmm1,%xmm3 + jnz .Ldec_loop + + + movdqa 96(%r10),%xmm4 +.byte 102,15,56,0,226 + pxor %xmm0,%xmm4 + movdqa 112(%r10),%xmm0 + movdqa -352(%r11),%xmm2 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,194 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + + + + + + +.type _vpaes_schedule_core,@function +.align 16 +_vpaes_schedule_core: +.cfi_startproc + + + + + + call _vpaes_preheat + movdqa .Lk_rcon(%rip),%xmm8 + movdqu (%rdi),%xmm0 + + + movdqa %xmm0,%xmm3 + leaq .Lk_ipt(%rip),%r11 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm7 + + leaq .Lk_sr(%rip),%r10 + testq %rcx,%rcx + jnz .Lschedule_am_decrypting + + + movdqu %xmm0,(%rdx) + jmp .Lschedule_go + +.Lschedule_am_decrypting: + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + movdqu %xmm3,(%rdx) + xorq $0x30,%r8 + +.Lschedule_go: + cmpl $192,%esi + ja .Lschedule_256 + je .Lschedule_192 + + + + + + + + + + +.Lschedule_128: + movl $10,%esi + +.Loop_schedule_128: + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + jmp .Loop_schedule_128 + + + + + + + + + + + + + + + + +.align 16 +.Lschedule_192: + movdqu 8(%rdi),%xmm0 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm6 + pxor %xmm4,%xmm4 + movhlps %xmm4,%xmm6 + movl $4,%esi + +.Loop_schedule_192: + call _vpaes_schedule_round +.byte 102,15,58,15,198,8 + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + jmp .Loop_schedule_192 + + + + + + + + + + + +.align 16 +.Lschedule_256: + movdqu 16(%rdi),%xmm0 + call _vpaes_schedule_transform + movl $7,%esi + +.Loop_schedule_256: + call _vpaes_schedule_mangle + movdqa %xmm0,%xmm6 + + + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + + + pshufd $0xFF,%xmm0,%xmm0 + movdqa %xmm7,%xmm5 + movdqa %xmm6,%xmm7 + call _vpaes_schedule_low_round + movdqa %xmm5,%xmm7 + + jmp .Loop_schedule_256 + + + + + + + + + + + + +.align 16 +.Lschedule_mangle_last: + + leaq .Lk_deskew(%rip),%r11 + testq %rcx,%rcx + jnz .Lschedule_mangle_last_dec + + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,193 + leaq .Lk_opt(%rip),%r11 + addq $32,%rdx + +.Lschedule_mangle_last_dec: + addq $-16,%rdx + pxor .Lk_s63(%rip),%xmm0 + call _vpaes_schedule_transform + movdqu %xmm0,(%rdx) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_core,.-_vpaes_schedule_core + + + + + + + + + + + + + + + +.type _vpaes_schedule_192_smear,@function +.align 16 +_vpaes_schedule_192_smear: +.cfi_startproc + pshufd $0x80,%xmm6,%xmm1 + pshufd $0xFE,%xmm7,%xmm0 + pxor %xmm1,%xmm6 + pxor %xmm1,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm6,%xmm0 + movhlps %xmm1,%xmm6 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + + + + + + + + + + + + + + + + + + + +.type _vpaes_schedule_round,@function +.align 16 +_vpaes_schedule_round: +.cfi_startproc + + pxor %xmm1,%xmm1 +.byte 102,65,15,58,15,200,15 +.byte 102,69,15,58,15,192,15 + pxor %xmm1,%xmm7 + + + pshufd $0xFF,%xmm0,%xmm0 +.byte 102,15,58,15,192,1 + + + + +_vpaes_schedule_low_round: + + movdqa %xmm7,%xmm1 + pslldq $4,%xmm7 + pxor %xmm1,%xmm7 + movdqa %xmm7,%xmm1 + pslldq $8,%xmm7 + pxor %xmm1,%xmm7 + pxor .Lk_s63(%rip),%xmm7 + + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa %xmm11,%xmm2 +.byte 102,15,56,0,208 + pxor %xmm1,%xmm0 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + movdqa %xmm10,%xmm4 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + pxor %xmm0,%xmm2 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,220 + pxor %xmm1,%xmm3 + movdqa %xmm13,%xmm4 +.byte 102,15,56,0,226 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 + + + pxor %xmm7,%xmm0 + movdqa %xmm0,%xmm7 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_round,.-_vpaes_schedule_round + + + + + + + + + + +.type _vpaes_schedule_transform,@function +.align 16 +_vpaes_schedule_transform: +.cfi_startproc + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa (%r11),%xmm2 +.byte 102,15,56,0,208 + movdqa 16(%r11),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm2,%xmm0 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + + + + + + + + + + + + + + + + + + + + + + + + +.type _vpaes_schedule_mangle,@function +.align 16 +_vpaes_schedule_mangle: +.cfi_startproc + movdqa %xmm0,%xmm4 + movdqa .Lk_mc_forward(%rip),%xmm5 + testq %rcx,%rcx + jnz .Lschedule_mangle_dec + + + addq $16,%rdx + pxor .Lk_s63(%rip),%xmm4 +.byte 102,15,56,0,229 + movdqa %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 + + jmp .Lschedule_mangle_both +.align 16 +.Lschedule_mangle_dec: + + leaq .Lk_dksd(%rip),%r11 + movdqa %xmm9,%xmm1 + pandn %xmm4,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm4 + + movdqa 0(%r11),%xmm2 +.byte 102,15,56,0,212 + movdqa 16(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 32(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 48(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 64(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 80(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 96(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 112(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + + addq $-16,%rdx + +.Lschedule_mangle_both: + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + addq $-16,%r8 + andq $0x30,%r8 + movdqu %xmm3,(%rdx) + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + + + + +.globl vpaes_set_encrypt_key +.hidden vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,@function +.align 16 +vpaes_set_encrypt_key: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST +.extern BORINGSSL_function_hit +.hidden BORINGSSL_function_hit + movb $1,BORINGSSL_function_hit+5(%rip) +#endif + + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + + movl $0,%ecx + movl $0x30,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.hidden vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,@function +.align 16 +vpaes_set_decrypt_key: +.cfi_startproc + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + shll $4,%eax + leaq 16(%rdx,%rax,1),%rdx + + movl $1,%ecx + movl %esi,%r8d + shrl $1,%r8d + andl $32,%r8d + xorl $32,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key + +.globl vpaes_encrypt +.hidden vpaes_encrypt +.type vpaes_encrypt,@function +.align 16 +vpaes_encrypt: +.cfi_startproc +#ifdef BORINGSSL_DISPATCH_TEST +.extern BORINGSSL_function_hit +.hidden BORINGSSL_function_hit + movb $1,BORINGSSL_function_hit+4(%rip) +#endif + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_encrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_encrypt,.-vpaes_encrypt + +.globl vpaes_decrypt +.hidden vpaes_decrypt +.type vpaes_decrypt,@function +.align 16 +vpaes_decrypt: +.cfi_startproc + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_decrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_decrypt,.-vpaes_decrypt +.globl vpaes_cbc_encrypt +.hidden vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,@function +.align 16 +vpaes_cbc_encrypt: +.cfi_startproc + xchgq %rcx,%rdx + subq $16,%rcx + jc .Lcbc_abort + movdqu (%r8),%xmm6 + subq %rdi,%rsi + call _vpaes_preheat + cmpl $0,%r9d + je .Lcbc_dec_loop + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movdqu (%rdi),%xmm0 + pxor %xmm6,%xmm0 + call _vpaes_encrypt_core + movdqa %xmm0,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc .Lcbc_enc_loop + jmp .Lcbc_done +.align 16 +.Lcbc_dec_loop: + movdqu (%rdi),%xmm0 + movdqa %xmm0,%xmm7 + call _vpaes_decrypt_core + pxor %xmm6,%xmm0 + movdqa %xmm7,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc .Lcbc_dec_loop +.Lcbc_done: + movdqu %xmm6,(%r8) +.Lcbc_abort: + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt +.globl vpaes_ctr32_encrypt_blocks +.hidden vpaes_ctr32_encrypt_blocks +.type vpaes_ctr32_encrypt_blocks,@function +.align 16 +vpaes_ctr32_encrypt_blocks: +.cfi_startproc + + xchgq %rcx,%rdx + testq %rcx,%rcx + jz .Lctr32_abort + movdqu (%r8),%xmm0 + movdqa .Lctr_add_one(%rip),%xmm8 + subq %rdi,%rsi + call _vpaes_preheat + movdqa %xmm0,%xmm6 + pshufb .Lrev_ctr(%rip),%xmm6 + + testq $1,%rcx + jz .Lctr32_prep_loop + + + + movdqu (%rdi),%xmm7 + call _vpaes_encrypt_core + pxor %xmm7,%xmm0 + paddd %xmm8,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + subq $1,%rcx + leaq 16(%rdi),%rdi + jz .Lctr32_done + +.Lctr32_prep_loop: + + + movdqa %xmm6,%xmm14 + movdqa %xmm6,%xmm15 + paddd %xmm8,%xmm15 + +.Lctr32_loop: + movdqa .Lrev_ctr(%rip),%xmm1 + movdqa %xmm14,%xmm0 + movdqa %xmm15,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + call _vpaes_encrypt_core_2x + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa .Lctr_add_two(%rip),%xmm3 + pxor %xmm1,%xmm0 + pxor %xmm2,%xmm6 + paddd %xmm3,%xmm14 + paddd %xmm3,%xmm15 + movdqu %xmm0,(%rsi,%rdi,1) + movdqu %xmm6,16(%rsi,%rdi,1) + subq $2,%rcx + leaq 32(%rdi),%rdi + jnz .Lctr32_loop + +.Lctr32_done: +.Lctr32_abort: + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks + + + + + + +.type _vpaes_preheat,@function +.align 16 +_vpaes_preheat: +.cfi_startproc + leaq .Lk_s0F(%rip),%r10 + movdqa -32(%r10),%xmm10 + movdqa -16(%r10),%xmm11 + movdqa 0(%r10),%xmm9 + movdqa 48(%r10),%xmm13 + movdqa 64(%r10),%xmm12 + movdqa 80(%r10),%xmm15 + movdqa 96(%r10),%xmm14 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_preheat,.-_vpaes_preheat + + + + + +.type _vpaes_consts,@object +.align 64 +_vpaes_consts: +.Lk_inv: +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 + +.Lk_s0F: +.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F + +.Lk_ipt: +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 + +.Lk_sb1: +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.Lk_sb2: +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.Lk_sbo: +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA + +.Lk_mc_forward: +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 + +.Lk_mc_backward: +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F + +.Lk_sr: +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +.Lk_rcon: +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_s63: +.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B + +.Lk_opt: +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 + +.Lk_deskew: +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + + + + + +.Lk_dksd: +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + + + + + +.Lk_dipt: +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 + +.Lk_dsb9: +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 +.Lk_dsbo: +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C + + +.Lrev_ctr: +.quad 0x0706050403020100, 0x0c0d0e0f0b0a0908 + + +.Lctr_add_one: +.quad 0x0000000000000000, 0x0000000100000000 +.Lctr_add_two: +.quad 0x0000000000000000, 0x0000000200000000 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 64 +.size _vpaes_consts,.-_vpaes_consts +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S new file mode 100644 index 00000000..f87404b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S @@ -0,0 +1,1137 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + + + + + + + + + + + + + + + +.p2align 4 +_vpaes_encrypt_core: + + movq %rdx,%r9 + movq $16,%r11 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa L$k_ipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movdqu (%r9),%xmm5 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa L$k_ipt+16(%rip),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm5,%xmm2 + addq $16,%r9 + pxor %xmm2,%xmm0 + leaq L$k_mc_backward(%rip),%r10 + jmp L$enc_entry + +.p2align 4 +L$enc_loop: + + movdqa %xmm13,%xmm4 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,226 +.byte 102,15,56,0,195 + pxor %xmm5,%xmm4 + movdqa %xmm15,%xmm5 + pxor %xmm4,%xmm0 + movdqa -64(%r11,%r10,1),%xmm1 +.byte 102,15,56,0,234 + movdqa (%r11,%r10,1),%xmm4 + movdqa %xmm14,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm0,%xmm3 + pxor %xmm5,%xmm2 +.byte 102,15,56,0,193 + addq $16,%r9 + pxor %xmm2,%xmm0 +.byte 102,15,56,0,220 + addq $16,%r11 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,193 + andq $0x30,%r11 + subq $1,%rax + pxor %xmm3,%xmm0 + +L$enc_entry: + + movdqa %xmm9,%xmm1 + movdqa %xmm11,%xmm5 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,232 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm5,%xmm3 +.byte 102,15,56,0,224 + movdqa %xmm10,%xmm2 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm5 + pxor %xmm1,%xmm3 + jnz L$enc_loop + + + movdqa -96(%r10),%xmm4 + movdqa -80(%r10),%xmm0 +.byte 102,15,56,0,226 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,195 + movdqa 64(%r11,%r10,1),%xmm1 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,193 + .byte 0xf3,0xc3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.p2align 4 +_vpaes_encrypt_core_2x: + + movq %rdx,%r9 + movq $16,%r11 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa %xmm9,%xmm7 + movdqa L$k_ipt(%rip),%xmm2 + movdqa %xmm2,%xmm8 + pandn %xmm0,%xmm1 + pandn %xmm6,%xmm7 + movdqu (%r9),%xmm5 + + psrld $4,%xmm1 + psrld $4,%xmm7 + pand %xmm9,%xmm0 + pand %xmm9,%xmm6 +.byte 102,15,56,0,208 +.byte 102,68,15,56,0,198 + movdqa L$k_ipt+16(%rip),%xmm0 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,247 + pxor %xmm5,%xmm2 + pxor %xmm5,%xmm8 + addq $16,%r9 + pxor %xmm2,%xmm0 + pxor %xmm8,%xmm6 + leaq L$k_mc_backward(%rip),%r10 + jmp L$enc2x_entry + +.p2align 4 +L$enc2x_loop: + + movdqa L$k_sb1(%rip),%xmm4 + movdqa L$k_sb1+16(%rip),%xmm0 + movdqa %xmm4,%xmm12 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,226 +.byte 102,69,15,56,0,224 +.byte 102,15,56,0,195 +.byte 102,65,15,56,0,243 + pxor %xmm5,%xmm4 + pxor %xmm5,%xmm12 + movdqa L$k_sb2(%rip),%xmm5 + movdqa %xmm5,%xmm13 + pxor %xmm4,%xmm0 + pxor %xmm12,%xmm6 + movdqa -64(%r11,%r10,1),%xmm1 + +.byte 102,15,56,0,234 +.byte 102,69,15,56,0,232 + movdqa (%r11,%r10,1),%xmm4 + + movdqa L$k_sb2+16(%rip),%xmm2 + movdqa %xmm2,%xmm8 +.byte 102,15,56,0,211 +.byte 102,69,15,56,0,195 + movdqa %xmm0,%xmm3 + movdqa %xmm6,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm13,%xmm8 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + addq $16,%r9 + pxor %xmm2,%xmm0 + pxor %xmm8,%xmm6 +.byte 102,15,56,0,220 +.byte 102,68,15,56,0,220 + addq $16,%r11 + pxor %xmm0,%xmm3 + pxor %xmm6,%xmm11 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + andq $0x30,%r11 + subq $1,%rax + pxor %xmm3,%xmm0 + pxor %xmm11,%xmm6 + +L$enc2x_entry: + + movdqa %xmm9,%xmm1 + movdqa %xmm9,%xmm7 + movdqa L$k_inv+16(%rip),%xmm5 + movdqa %xmm5,%xmm13 + pandn %xmm0,%xmm1 + pandn %xmm6,%xmm7 + psrld $4,%xmm1 + psrld $4,%xmm7 + pand %xmm9,%xmm0 + pand %xmm9,%xmm6 +.byte 102,15,56,0,232 +.byte 102,68,15,56,0,238 + movdqa %xmm10,%xmm3 + movdqa %xmm10,%xmm11 + pxor %xmm1,%xmm0 + pxor %xmm7,%xmm6 +.byte 102,15,56,0,217 +.byte 102,68,15,56,0,223 + movdqa %xmm10,%xmm4 + movdqa %xmm10,%xmm12 + pxor %xmm5,%xmm3 + pxor %xmm13,%xmm11 +.byte 102,15,56,0,224 +.byte 102,68,15,56,0,230 + movdqa %xmm10,%xmm2 + movdqa %xmm10,%xmm8 + pxor %xmm5,%xmm4 + pxor %xmm13,%xmm12 +.byte 102,15,56,0,211 +.byte 102,69,15,56,0,195 + movdqa %xmm10,%xmm3 + movdqa %xmm10,%xmm11 + pxor %xmm0,%xmm2 + pxor %xmm6,%xmm8 +.byte 102,15,56,0,220 +.byte 102,69,15,56,0,220 + movdqu (%r9),%xmm5 + + pxor %xmm1,%xmm3 + pxor %xmm7,%xmm11 + jnz L$enc2x_loop + + + movdqa -96(%r10),%xmm4 + movdqa -80(%r10),%xmm0 + movdqa %xmm4,%xmm12 + movdqa %xmm0,%xmm6 +.byte 102,15,56,0,226 +.byte 102,69,15,56,0,224 + pxor %xmm5,%xmm4 + pxor %xmm5,%xmm12 +.byte 102,15,56,0,195 +.byte 102,65,15,56,0,243 + movdqa 64(%r11,%r10,1),%xmm1 + + pxor %xmm4,%xmm0 + pxor %xmm12,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + .byte 0xf3,0xc3 + + + + + + + + + +.p2align 4 +_vpaes_decrypt_core: + + movq %rdx,%r9 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa L$k_dipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movq %rax,%r11 + psrld $4,%xmm1 + movdqu (%r9),%xmm5 + shlq $4,%r11 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa L$k_dipt+16(%rip),%xmm0 + xorq $0x30,%r11 + leaq L$k_dsbd(%rip),%r10 +.byte 102,15,56,0,193 + andq $0x30,%r11 + pxor %xmm5,%xmm2 + movdqa L$k_mc_forward+48(%rip),%xmm5 + pxor %xmm2,%xmm0 + addq $16,%r9 + addq %r10,%r11 + jmp L$dec_entry + +.p2align 4 +L$dec_loop: + + + + movdqa -32(%r10),%xmm4 + movdqa -16(%r10),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 0(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 16(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 32(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 48(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 64(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 80(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + addq $16,%r9 +.byte 102,15,58,15,237,12 + pxor %xmm1,%xmm0 + subq $1,%rax + +L$dec_entry: + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + movdqa %xmm11,%xmm2 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm0 + pxor %xmm1,%xmm3 + jnz L$dec_loop + + + movdqa 96(%r10),%xmm4 +.byte 102,15,56,0,226 + pxor %xmm0,%xmm4 + movdqa 112(%r10),%xmm0 + movdqa -352(%r11),%xmm2 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,194 + .byte 0xf3,0xc3 + + + + + + + + + +.p2align 4 +_vpaes_schedule_core: + + + + + + + call _vpaes_preheat + movdqa L$k_rcon(%rip),%xmm8 + movdqu (%rdi),%xmm0 + + + movdqa %xmm0,%xmm3 + leaq L$k_ipt(%rip),%r11 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm7 + + leaq L$k_sr(%rip),%r10 + testq %rcx,%rcx + jnz L$schedule_am_decrypting + + + movdqu %xmm0,(%rdx) + jmp L$schedule_go + +L$schedule_am_decrypting: + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + movdqu %xmm3,(%rdx) + xorq $0x30,%r8 + +L$schedule_go: + cmpl $192,%esi + ja L$schedule_256 + je L$schedule_192 + + + + + + + + + + +L$schedule_128: + movl $10,%esi + +L$oop_schedule_128: + call _vpaes_schedule_round + decq %rsi + jz L$schedule_mangle_last + call _vpaes_schedule_mangle + jmp L$oop_schedule_128 + + + + + + + + + + + + + + + + +.p2align 4 +L$schedule_192: + movdqu 8(%rdi),%xmm0 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm6 + pxor %xmm4,%xmm4 + movhlps %xmm4,%xmm6 + movl $4,%esi + +L$oop_schedule_192: + call _vpaes_schedule_round +.byte 102,15,58,15,198,8 + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle + call _vpaes_schedule_round + decq %rsi + jz L$schedule_mangle_last + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + jmp L$oop_schedule_192 + + + + + + + + + + + +.p2align 4 +L$schedule_256: + movdqu 16(%rdi),%xmm0 + call _vpaes_schedule_transform + movl $7,%esi + +L$oop_schedule_256: + call _vpaes_schedule_mangle + movdqa %xmm0,%xmm6 + + + call _vpaes_schedule_round + decq %rsi + jz L$schedule_mangle_last + call _vpaes_schedule_mangle + + + pshufd $0xFF,%xmm0,%xmm0 + movdqa %xmm7,%xmm5 + movdqa %xmm6,%xmm7 + call _vpaes_schedule_low_round + movdqa %xmm5,%xmm7 + + jmp L$oop_schedule_256 + + + + + + + + + + + + +.p2align 4 +L$schedule_mangle_last: + + leaq L$k_deskew(%rip),%r11 + testq %rcx,%rcx + jnz L$schedule_mangle_last_dec + + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,193 + leaq L$k_opt(%rip),%r11 + addq $32,%rdx + +L$schedule_mangle_last_dec: + addq $-16,%rdx + pxor L$k_s63(%rip),%xmm0 + call _vpaes_schedule_transform + movdqu %xmm0,(%rdx) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + .byte 0xf3,0xc3 + + + + + + + + + + + + + + + + + + +.p2align 4 +_vpaes_schedule_192_smear: + + pshufd $0x80,%xmm6,%xmm1 + pshufd $0xFE,%xmm7,%xmm0 + pxor %xmm1,%xmm6 + pxor %xmm1,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm6,%xmm0 + movhlps %xmm1,%xmm6 + .byte 0xf3,0xc3 + + + + + + + + + + + + + + + + + + + + + + +.p2align 4 +_vpaes_schedule_round: + + + pxor %xmm1,%xmm1 +.byte 102,65,15,58,15,200,15 +.byte 102,69,15,58,15,192,15 + pxor %xmm1,%xmm7 + + + pshufd $0xFF,%xmm0,%xmm0 +.byte 102,15,58,15,192,1 + + + + +_vpaes_schedule_low_round: + + movdqa %xmm7,%xmm1 + pslldq $4,%xmm7 + pxor %xmm1,%xmm7 + movdqa %xmm7,%xmm1 + pslldq $8,%xmm7 + pxor %xmm1,%xmm7 + pxor L$k_s63(%rip),%xmm7 + + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa %xmm11,%xmm2 +.byte 102,15,56,0,208 + pxor %xmm1,%xmm0 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + movdqa %xmm10,%xmm4 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + pxor %xmm0,%xmm2 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,220 + pxor %xmm1,%xmm3 + movdqa %xmm13,%xmm4 +.byte 102,15,56,0,226 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 + + + pxor %xmm7,%xmm0 + movdqa %xmm0,%xmm7 + .byte 0xf3,0xc3 + + + + + + + + + + + + + +.p2align 4 +_vpaes_schedule_transform: + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa (%r11),%xmm2 +.byte 102,15,56,0,208 + movdqa 16(%r11),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm2,%xmm0 + .byte 0xf3,0xc3 + + + + + + + + + + + + + + + + + + + + + + + + + + + +.p2align 4 +_vpaes_schedule_mangle: + + movdqa %xmm0,%xmm4 + movdqa L$k_mc_forward(%rip),%xmm5 + testq %rcx,%rcx + jnz L$schedule_mangle_dec + + + addq $16,%rdx + pxor L$k_s63(%rip),%xmm4 +.byte 102,15,56,0,229 + movdqa %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 + + jmp L$schedule_mangle_both +.p2align 4 +L$schedule_mangle_dec: + + leaq L$k_dksd(%rip),%r11 + movdqa %xmm9,%xmm1 + pandn %xmm4,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm4 + + movdqa 0(%r11),%xmm2 +.byte 102,15,56,0,212 + movdqa 16(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 32(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 48(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 64(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 80(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 96(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 112(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + + addq $-16,%rdx + +L$schedule_mangle_both: + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + addq $-16,%r8 + andq $0x30,%r8 + movdqu %xmm3,(%rdx) + .byte 0xf3,0xc3 + + + + + + +.globl _vpaes_set_encrypt_key +.private_extern _vpaes_set_encrypt_key + +.p2align 4 +_vpaes_set_encrypt_key: + +#ifdef BORINGSSL_DISPATCH_TEST + + movb $1,_BORINGSSL_function_hit+5(%rip) +#endif + + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + + movl $0,%ecx + movl $0x30,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 + + + +.globl _vpaes_set_decrypt_key +.private_extern _vpaes_set_decrypt_key + +.p2align 4 +_vpaes_set_decrypt_key: + + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + shll $4,%eax + leaq 16(%rdx,%rax,1),%rdx + + movl $1,%ecx + movl %esi,%r8d + shrl $1,%r8d + andl $32,%r8d + xorl $32,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 + + + +.globl _vpaes_encrypt +.private_extern _vpaes_encrypt + +.p2align 4 +_vpaes_encrypt: + +#ifdef BORINGSSL_DISPATCH_TEST + + movb $1,_BORINGSSL_function_hit+4(%rip) +#endif + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_encrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 + + + +.globl _vpaes_decrypt +.private_extern _vpaes_decrypt + +.p2align 4 +_vpaes_decrypt: + + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_decrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 + + +.globl _vpaes_cbc_encrypt +.private_extern _vpaes_cbc_encrypt + +.p2align 4 +_vpaes_cbc_encrypt: + + xchgq %rcx,%rdx + subq $16,%rcx + jc L$cbc_abort + movdqu (%r8),%xmm6 + subq %rdi,%rsi + call _vpaes_preheat + cmpl $0,%r9d + je L$cbc_dec_loop + jmp L$cbc_enc_loop +.p2align 4 +L$cbc_enc_loop: + movdqu (%rdi),%xmm0 + pxor %xmm6,%xmm0 + call _vpaes_encrypt_core + movdqa %xmm0,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc L$cbc_enc_loop + jmp L$cbc_done +.p2align 4 +L$cbc_dec_loop: + movdqu (%rdi),%xmm0 + movdqa %xmm0,%xmm7 + call _vpaes_decrypt_core + pxor %xmm6,%xmm0 + movdqa %xmm7,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc L$cbc_dec_loop +L$cbc_done: + movdqu %xmm6,(%r8) +L$cbc_abort: + .byte 0xf3,0xc3 + + +.globl _vpaes_ctr32_encrypt_blocks +.private_extern _vpaes_ctr32_encrypt_blocks + +.p2align 4 +_vpaes_ctr32_encrypt_blocks: + + + xchgq %rcx,%rdx + testq %rcx,%rcx + jz L$ctr32_abort + movdqu (%r8),%xmm0 + movdqa L$ctr_add_one(%rip),%xmm8 + subq %rdi,%rsi + call _vpaes_preheat + movdqa %xmm0,%xmm6 + pshufb L$rev_ctr(%rip),%xmm6 + + testq $1,%rcx + jz L$ctr32_prep_loop + + + + movdqu (%rdi),%xmm7 + call _vpaes_encrypt_core + pxor %xmm7,%xmm0 + paddd %xmm8,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + subq $1,%rcx + leaq 16(%rdi),%rdi + jz L$ctr32_done + +L$ctr32_prep_loop: + + + movdqa %xmm6,%xmm14 + movdqa %xmm6,%xmm15 + paddd %xmm8,%xmm15 + +L$ctr32_loop: + movdqa L$rev_ctr(%rip),%xmm1 + movdqa %xmm14,%xmm0 + movdqa %xmm15,%xmm6 +.byte 102,15,56,0,193 +.byte 102,15,56,0,241 + call _vpaes_encrypt_core_2x + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa L$ctr_add_two(%rip),%xmm3 + pxor %xmm1,%xmm0 + pxor %xmm2,%xmm6 + paddd %xmm3,%xmm14 + paddd %xmm3,%xmm15 + movdqu %xmm0,(%rsi,%rdi,1) + movdqu %xmm6,16(%rsi,%rdi,1) + subq $2,%rcx + leaq 32(%rdi),%rdi + jnz L$ctr32_loop + +L$ctr32_done: +L$ctr32_abort: + .byte 0xf3,0xc3 + + + + + + + + + +.p2align 4 +_vpaes_preheat: + + leaq L$k_s0F(%rip),%r10 + movdqa -32(%r10),%xmm10 + movdqa -16(%r10),%xmm11 + movdqa 0(%r10),%xmm9 + movdqa 48(%r10),%xmm13 + movdqa 64(%r10),%xmm12 + movdqa 80(%r10),%xmm15 + movdqa 96(%r10),%xmm14 + .byte 0xf3,0xc3 + + + + + + + + +.p2align 6 +_vpaes_consts: +L$k_inv: +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 + +L$k_s0F: +.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F + +L$k_ipt: +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 + +L$k_sb1: +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +L$k_sb2: +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +L$k_sbo: +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA + +L$k_mc_forward: +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 + +L$k_mc_backward: +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F + +L$k_sr: +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +L$k_rcon: +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +L$k_s63: +.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B + +L$k_opt: +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 + +L$k_deskew: +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + + + + + +L$k_dksd: +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +L$k_dksb: +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +L$k_dkse: +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +L$k_dks9: +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + + + + + +L$k_dipt: +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 + +L$k_dsb9: +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +L$k_dsbd: +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +L$k_dsbb: +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +L$k_dsbe: +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 +L$k_dsbo: +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C + + +L$rev_ctr: +.quad 0x0706050403020100, 0x0c0d0e0f0b0a0908 + + +L$ctr_add_one: +.quad 0x0000000000000000, 0x0000000100000000 +L$ctr_add_two: +.quad 0x0000000000000000, 0x0000000200000000 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.p2align 6 + +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S new file mode 100644 index 00000000..c0b284ba --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S @@ -0,0 +1,491 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__i386__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__i386__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text +.globl bn_mul_mont +.hidden bn_mul_mont +.type bn_mul_mont,@function +.align 16 +bn_mul_mont: +.L_bn_mul_mont_begin: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl %eax,%eax + movl 40(%esp),%edi + cmpl $4,%edi + jl .L000just_leave + leal 20(%esp),%esi + leal 24(%esp),%edx + addl $2,%edi + negl %edi + leal -32(%esp,%edi,4),%ebp + negl %edi + movl %ebp,%eax + subl %edx,%eax + andl $2047,%eax + subl %eax,%ebp + xorl %ebp,%edx + andl $2048,%edx + xorl $2048,%edx + subl %edx,%ebp + andl $-64,%ebp + movl %esp,%eax + subl %ebp,%eax + andl $-4096,%eax + movl %esp,%edx + leal (%ebp,%eax,1),%esp + movl (%esp),%eax + cmpl %ebp,%esp + ja .L001page_walk + jmp .L002page_walk_done +.align 16 +.L001page_walk: + leal -4096(%esp),%esp + movl (%esp),%eax + cmpl %ebp,%esp + ja .L001page_walk +.L002page_walk_done: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%ebp + movl 16(%esi),%esi + movl (%esi),%esi + movl %eax,4(%esp) + movl %ebx,8(%esp) + movl %ecx,12(%esp) + movl %ebp,16(%esp) + movl %esi,20(%esp) + leal -3(%edi),%ebx + movl %edx,24(%esp) + call .L003PIC_me_up +.L003PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L003PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L004non_sse2 + movl $-1,%eax + movd %eax,%mm7 + movl 8(%esp),%esi + movl 12(%esp),%edi + movl 16(%esp),%ebp + xorl %edx,%edx + xorl %ecx,%ecx + movd (%edi),%mm4 + movd (%esi),%mm5 + movd (%ebp),%mm3 + pmuludq %mm4,%mm5 + movq %mm5,%mm2 + movq %mm5,%mm0 + pand %mm7,%mm0 + pmuludq 20(%esp),%mm5 + pmuludq %mm5,%mm3 + paddq %mm0,%mm3 + movd 4(%ebp),%mm1 + movd 4(%esi),%mm0 + psrlq $32,%mm2 + psrlq $32,%mm3 + incl %ecx +.align 16 +.L0051st: + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + movd 4(%ebp,%ecx,4),%mm1 + paddq %mm0,%mm3 + movd 4(%esi,%ecx,4),%mm0 + psrlq $32,%mm2 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm3 + leal 1(%ecx),%ecx + cmpl %ebx,%ecx + jl .L0051st + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + paddq %mm0,%mm3 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm2 + psrlq $32,%mm3 + paddq %mm2,%mm3 + movq %mm3,32(%esp,%ebx,4) + incl %edx +.L006outer: + xorl %ecx,%ecx + movd (%edi,%edx,4),%mm4 + movd (%esi),%mm5 + movd 32(%esp),%mm6 + movd (%ebp),%mm3 + pmuludq %mm4,%mm5 + paddq %mm6,%mm5 + movq %mm5,%mm0 + movq %mm5,%mm2 + pand %mm7,%mm0 + pmuludq 20(%esp),%mm5 + pmuludq %mm5,%mm3 + paddq %mm0,%mm3 + movd 36(%esp),%mm6 + movd 4(%ebp),%mm1 + movd 4(%esi),%mm0 + psrlq $32,%mm2 + psrlq $32,%mm3 + paddq %mm6,%mm2 + incl %ecx + decl %ebx +.L007inner: + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + movd 36(%esp,%ecx,4),%mm6 + pand %mm7,%mm0 + movd 4(%ebp,%ecx,4),%mm1 + paddq %mm0,%mm3 + movd 4(%esi,%ecx,4),%mm0 + psrlq $32,%mm2 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm3 + paddq %mm6,%mm2 + decl %ebx + leal 1(%ecx),%ecx + jnz .L007inner + movl %ecx,%ebx + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + paddq %mm0,%mm3 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm2 + psrlq $32,%mm3 + movd 36(%esp,%ebx,4),%mm6 + paddq %mm2,%mm3 + paddq %mm6,%mm3 + movq %mm3,32(%esp,%ebx,4) + leal 1(%edx),%edx + cmpl %ebx,%edx + jle .L006outer + emms + jmp .L008common_tail +.align 16 +.L004non_sse2: + movl 8(%esp),%esi + leal 1(%ebx),%ebp + movl 12(%esp),%edi + xorl %ecx,%ecx + movl %esi,%edx + andl $1,%ebp + subl %edi,%edx + leal 4(%edi,%ebx,4),%eax + orl %edx,%ebp + movl (%edi),%edi + jz .L009bn_sqr_mont + movl %eax,28(%esp) + movl (%esi),%eax + xorl %edx,%edx +.align 16 +.L010mull: + movl %edx,%ebp + mull %edi + addl %eax,%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + movl (%esi,%ecx,4),%eax + cmpl %ebx,%ecx + movl %ebp,28(%esp,%ecx,4) + jl .L010mull + movl %edx,%ebp + mull %edi + movl 20(%esp),%edi + addl %ebp,%eax + movl 16(%esp),%esi + adcl $0,%edx + imull 32(%esp),%edi + movl %eax,32(%esp,%ebx,4) + xorl %ecx,%ecx + movl %edx,36(%esp,%ebx,4) + movl %ecx,40(%esp,%ebx,4) + movl (%esi),%eax + mull %edi + addl 32(%esp),%eax + movl 4(%esi),%eax + adcl $0,%edx + incl %ecx + jmp .L0112ndmadd +.align 16 +.L0121stmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,28(%esp,%ecx,4) + jl .L0121stmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%eax + movl 20(%esp),%edi + adcl $0,%edx + movl 16(%esp),%esi + addl %eax,%ebp + adcl $0,%edx + imull 32(%esp),%edi + xorl %ecx,%ecx + addl 36(%esp,%ebx,4),%edx + movl %ebp,32(%esp,%ebx,4) + adcl $0,%ecx + movl (%esi),%eax + movl %edx,36(%esp,%ebx,4) + movl %ecx,40(%esp,%ebx,4) + mull %edi + addl 32(%esp),%eax + movl 4(%esi),%eax + adcl $0,%edx + movl $1,%ecx +.align 16 +.L0112ndmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,24(%esp,%ecx,4) + jl .L0112ndmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + adcl $0,%edx + movl %ebp,28(%esp,%ebx,4) + xorl %eax,%eax + movl 12(%esp),%ecx + addl 36(%esp,%ebx,4),%edx + adcl 40(%esp,%ebx,4),%eax + leal 4(%ecx),%ecx + movl %edx,32(%esp,%ebx,4) + cmpl 28(%esp),%ecx + movl %eax,36(%esp,%ebx,4) + je .L008common_tail + movl (%ecx),%edi + movl 8(%esp),%esi + movl %ecx,12(%esp) + xorl %ecx,%ecx + xorl %edx,%edx + movl (%esi),%eax + jmp .L0121stmadd +.align 16 +.L009bn_sqr_mont: + movl %ebx,(%esp) + movl %ecx,12(%esp) + movl %edi,%eax + mull %edi + movl %eax,32(%esp) + movl %edx,%ebx + shrl $1,%edx + andl $1,%ebx + incl %ecx +.align 16 +.L013sqr: + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + leal 1(%ecx),%ecx + adcl $0,%edx + leal (%ebx,%eax,2),%ebp + shrl $31,%eax + cmpl (%esp),%ecx + movl %eax,%ebx + movl %ebp,28(%esp,%ecx,4) + jl .L013sqr + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + movl 20(%esp),%edi + adcl $0,%edx + movl 16(%esp),%esi + leal (%ebx,%eax,2),%ebp + imull 32(%esp),%edi + shrl $31,%eax + movl %ebp,32(%esp,%ecx,4) + leal (%eax,%edx,2),%ebp + movl (%esi),%eax + shrl $31,%edx + movl %ebp,36(%esp,%ecx,4) + movl %edx,40(%esp,%ecx,4) + mull %edi + addl 32(%esp),%eax + movl %ecx,%ebx + adcl $0,%edx + movl 4(%esi),%eax + movl $1,%ecx +.align 16 +.L0143rdmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + movl 4(%esi,%ecx,4),%eax + adcl $0,%edx + movl %ebp,28(%esp,%ecx,4) + movl %edx,%ebp + mull %edi + addl 36(%esp,%ecx,4),%ebp + leal 2(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,24(%esp,%ecx,4) + jl .L0143rdmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + adcl $0,%edx + movl %ebp,28(%esp,%ebx,4) + movl 12(%esp),%ecx + xorl %eax,%eax + movl 8(%esp),%esi + addl 36(%esp,%ebx,4),%edx + adcl 40(%esp,%ebx,4),%eax + movl %edx,32(%esp,%ebx,4) + cmpl %ebx,%ecx + movl %eax,36(%esp,%ebx,4) + je .L008common_tail + movl 4(%esi,%ecx,4),%edi + leal 1(%ecx),%ecx + movl %edi,%eax + movl %ecx,12(%esp) + mull %edi + addl 32(%esp,%ecx,4),%eax + adcl $0,%edx + movl %eax,32(%esp,%ecx,4) + xorl %ebp,%ebp + cmpl %ebx,%ecx + leal 1(%ecx),%ecx + je .L015sqrlast + movl %edx,%ebx + shrl $1,%edx + andl $1,%ebx +.align 16 +.L016sqradd: + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + leal (%eax,%eax,1),%ebp + adcl $0,%edx + shrl $31,%eax + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%eax + addl %ebx,%ebp + adcl $0,%eax + cmpl (%esp),%ecx + movl %ebp,28(%esp,%ecx,4) + movl %eax,%ebx + jle .L016sqradd + movl %edx,%ebp + addl %edx,%edx + shrl $31,%ebp + addl %ebx,%edx + adcl $0,%ebp +.L015sqrlast: + movl 20(%esp),%edi + movl 16(%esp),%esi + imull 32(%esp),%edi + addl 32(%esp,%ecx,4),%edx + movl (%esi),%eax + adcl $0,%ebp + movl %edx,32(%esp,%ecx,4) + movl %ebp,36(%esp,%ecx,4) + mull %edi + addl 32(%esp),%eax + leal -1(%ecx),%ebx + adcl $0,%edx + movl $1,%ecx + movl 4(%esi),%eax + jmp .L0143rdmadd +.align 16 +.L008common_tail: + movl 16(%esp),%ebp + movl 4(%esp),%edi + leal 32(%esp),%esi + movl (%esi),%eax + movl %ebx,%ecx + xorl %edx,%edx +.align 16 +.L017sub: + sbbl (%ebp,%edx,4),%eax + movl %eax,(%edi,%edx,4) + decl %ecx + movl 4(%esi,%edx,4),%eax + leal 1(%edx),%edx + jge .L017sub + sbbl $0,%eax + movl $-1,%edx + xorl %eax,%edx + jmp .L018copy +.align 16 +.L018copy: + movl 32(%esp,%ebx,4),%esi + movl (%edi,%ebx,4),%ebp + movl %ecx,32(%esp,%ebx,4) + andl %eax,%esi + andl %edx,%ebp + orl %esi,%ebp + movl %ebp,(%edi,%ebx,4) + decl %ebx + jge .L018copy + movl 24(%esp),%esp + movl $1,%eax +.L000just_leave: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_mont,.-.L_bn_mul_mont_begin +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 +.byte 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 +.byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 +.byte 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 +.byte 111,114,103,62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__i386__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S new file mode 100644 index 00000000..f24bdc9c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S @@ -0,0 +1,1267 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + +.globl bn_mul_mont +.hidden bn_mul_mont +.type bn_mul_mont,@function +.align 16 +bn_mul_mont: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax + testl $3,%r9d + jnz .Lmul_enter + cmpl $8,%r9d + jb .Lmul_enter + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + cmpq %rsi,%rdx + jne .Lmul4x_enter + testl $7,%r9d + jz .Lsqr8x_enter + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -16(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + +.align 16 +.Lmul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul_body: + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne .L1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne .Linner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + movq %r9,%r15 + +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsp,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +.Lcopy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r9,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul_mont,.-bn_mul_mont +.type bn_mul4x_mont,@function +.align 16 +bn_mul4x_mont: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmul4x_enter: + andl $0x80100,%r11d + cmpl $0x80100,%r11d + je .Lmulx4x_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -32(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + +.Lmul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: + + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul4x_body: + movq %rdi,16(%rsp,%r9,8) + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .L1st4x +.align 16 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.align 4 +.Louter4x: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .Linner4x +.align 16 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jb .Louter4x + movq 16(%rsp,%r9,8),%rdi + leaq -4(%r9),%r15 + movq 0(%rsp),%rax + movq 8(%rsp),%rdx + shrq $2,%r15 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + +.Lsub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz .Lsub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + pxor %xmm0,%xmm0 +.byte 102,72,15,110,224 + pcmpeqd %xmm5,%xmm5 + pshufd $0,%xmm4,%xmm4 + movq %r9,%r15 + pxor %xmm4,%xmm5 + shrq $2,%r15 + xorl %eax,%eax + + jmp .Lcopy4x +.align 16 +.Lcopy4x: + movdqa (%rsp,%rax,1),%xmm1 + movdqu (%rdi,%rax,1),%xmm2 + pand %xmm4,%xmm1 + pand %xmm5,%xmm2 + movdqa 16(%rsp,%rax,1),%xmm3 + movdqa %xmm0,(%rsp,%rax,1) + por %xmm2,%xmm1 + movdqu 16(%rdi,%rax,1),%xmm2 + movdqu %xmm1,(%rdi,%rax,1) + pand %xmm4,%xmm3 + pand %xmm5,%xmm2 + movdqa %xmm0,16(%rsp,%rax,1) + por %xmm2,%xmm3 + movdqu %xmm3,16(%rdi,%rax,1) + leaq 32(%rax),%rax + decq %r15 + jnz .Lcopy4x + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi, 8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul4x_mont,.-bn_mul4x_mont +.extern bn_sqrx8x_internal +.hidden bn_sqrx8x_internal +.extern bn_sqr8x_internal +.hidden bn_sqr8x_internal + +.type bn_sqr8x_mont,@function +.align 32 +bn_sqr8x_mont: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lsqr8x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lsqr8x_prologue: + + movl %r9d,%r10d + shll $3,%r9d + shlq $3+2,%r10 + negq %r9 + + + + + + + leaq -64(%rsp,%r9,2),%r11 + movq %rsp,%rbp + movq (%r8),%r8 + subq %rsi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lsqr8x_sp_alt + subq %r11,%rbp + leaq -64(%rbp,%r9,2),%rbp + jmp .Lsqr8x_sp_done + +.align 32 +.Lsqr8x_sp_alt: + leaq 4096-64(,%r9,2),%r10 + leaq -64(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lsqr8x_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lsqr8x_page_walk + jmp .Lsqr8x_page_walk_done + +.align 16 +.Lsqr8x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lsqr8x_page_walk +.Lsqr8x_page_walk_done: + + movq %r9,%r10 + negq %r9 + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lsqr8x_body: + +.byte 102,72,15,110,209 + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,73,15,110,218 + leaq OPENSSL_ia32cap_P(%rip),%rax + movl 8(%rax),%eax + andl $0x80100,%eax + cmpl $0x80100,%eax + jne .Lsqr8x_nox + + call bn_sqrx8x_internal + + + + + leaq (%r8,%rcx,1),%rbx + movq %rcx,%r9 + movq %rcx,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp .Lsqr8x_sub + +.align 32 +.Lsqr8x_nox: + call bn_sqr8x_internal + + + + + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx + movq %r9,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp .Lsqr8x_sub + +.align 32 +.Lsqr8x_sub: + movq 0(%rbx),%r12 + movq 8(%rbx),%r13 + movq 16(%rbx),%r14 + movq 24(%rbx),%r15 + leaq 32(%rbx),%rbx + sbbq 0(%rbp),%r12 + sbbq 8(%rbp),%r13 + sbbq 16(%rbp),%r14 + sbbq 24(%rbp),%r15 + leaq 32(%rbp),%rbp + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + incq %rcx + jnz .Lsqr8x_sub + + sbbq $0,%rax + leaq (%rbx,%r9,1),%rbx + leaq (%rdi,%r9,1),%rdi + +.byte 102,72,15,110,200 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + jmp .Lsqr8x_cond_copy + +.align 32 +.Lsqr8x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + movdqa %xmm0,-32(%rbx,%rdx,1) + movdqa %xmm0,-16(%rbx,%rdx,1) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + addq $32,%r9 + jnz .Lsqr8x_cond_copy + + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lsqr8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqr8x_mont,.-bn_sqr8x_mont +.type bn_mulx4x_mont,@function +.align 32 +bn_mulx4x_mont: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmulx4x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmulx4x_prologue: + + shll $3,%r9d + xorq %r10,%r10 + subq %r9,%r10 + movq (%r8),%r8 + leaq -72(%rsp,%r10,1),%rbp + andq $-128,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + +.align 16 +.Lmulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: + + leaq (%rdx,%r9,1),%r10 + + + + + + + + + + + + + movq %r9,0(%rsp) + shrq $5,%r9 + movq %r10,16(%rsp) + subq $1,%r9 + movq %r8,24(%rsp) + movq %rdi,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 + movq %r9,48(%rsp) + jmp .Lmulx4x_body + +.align 32 +.Lmulx4x_body: + leaq 8(%rdx),%rdi + movq (%rdx),%rdx + leaq 64+32(%rsp),%rbx + movq %rdx,%r9 + + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r14 + addq %rax,%r11 + movq %rdi,8(%rsp) + mulxq 16(%rsi),%r12,%r13 + adcq %r14,%r12 + adcq $0,%r13 + + movq %r8,%rdi + imulq 24(%rsp),%r8 + xorq %rbp,%rbp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%rdi + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 +.byte 0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00 + movq 48(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + + jmp .Lmulx4x_1st + +.align 32 +.Lmulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_1st + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + addq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + jmp .Lmulx4x_outer + +.align 32 +.Lmulx4x_outer: + movq (%rdi),%rdx + leaq 8(%rdi),%rdi + subq %rax,%rsi + movq %r15,(%rbx) + leaq 64+32(%rsp),%rbx + subq %rax,%rcx + + mulxq 0(%rsi),%r8,%r11 + xorl %ebp,%ebp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + adoxq -16(%rbx),%r12 + adcxq %rbp,%r13 + adoxq %rbp,%r13 + + movq %rdi,8(%rsp) + movq %r8,%r15 + imulq 24(%rsp),%r8 + xorl %ebp,%ebp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + adcxq %rax,%r13 + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + adoxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + leaq 32(%rcx),%rcx + adcxq %rax,%r12 + adoxq %rbp,%r15 + movq 48(%rsp),%rdi + movq %r12,-16(%rbx) + + jmp .Lmulx4x_inner + +.align 32 +.Lmulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-32(%rbx) + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_inner + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + subq 0(%rbx),%rbp + adcq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + + cmpq 16(%rsp),%rdi + jne .Lmulx4x_outer + + leaq 64(%rsp),%rbx + subq %rax,%rcx + negq %r15 + movq %rax,%rdx + shrq $3+2,%rax + movq 32(%rsp),%rdi + jmp .Lmulx4x_sub + +.align 32 +.Lmulx4x_sub: + movq 0(%rbx),%r11 + movq 8(%rbx),%r12 + movq 16(%rbx),%r13 + movq 24(%rbx),%r14 + leaq 32(%rbx),%rbx + sbbq 0(%rcx),%r11 + sbbq 8(%rcx),%r12 + sbbq 16(%rcx),%r13 + sbbq 24(%rcx),%r14 + leaq 32(%rcx),%rcx + movq %r11,0(%rdi) + movq %r12,8(%rdi) + movq %r13,16(%rdi) + movq %r14,24(%rdi) + leaq 32(%rdi),%rdi + decq %rax + jnz .Lmulx4x_sub + + sbbq $0,%r15 + leaq 64(%rsp),%rbx + subq %rdx,%rdi + +.byte 102,73,15,110,207 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + jmp .Lmulx4x_cond_copy + +.align 32 +.Lmulx4x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + subq $32,%rdx + jnz .Lmulx4x_cond_copy + + movq %rdx,(%rbx) + + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmulx4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mulx4x_mont,.-bn_mulx4x_mont +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 16 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S new file mode 100644 index 00000000..aa62b060 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S @@ -0,0 +1,1263 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + +.globl _bn_mul_mont +.private_extern _bn_mul_mont + +.p2align 4 +_bn_mul_mont: + + movl %r9d,%r9d + movq %rsp,%rax + + testl $3,%r9d + jnz L$mul_enter + cmpl $8,%r9d + jb L$mul_enter + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + cmpq %rsi,%rdx + jne L$mul4x_enter + testl $7,%r9d + jz L$sqr8x_enter + jmp L$mul4x_enter + +.p2align 4 +L$mul_enter: + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + + negq %r9 + movq %rsp,%r11 + leaq -16(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul_page_walk + jmp L$mul_page_walk_done + +.p2align 4 +L$mul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul_page_walk +L$mul_page_walk_done: + + movq %rax,8(%rsp,%r9,8) + +L$mul_body: + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$1st_enter + +.p2align 4 +L$1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne L$1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp L$outer +.p2align 4 +L$outer: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$inner_enter + +.p2align 4 +L$inner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$inner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne L$inner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb L$outer + + xorq %r14,%r14 + movq (%rsp),%rax + movq %r9,%r15 + +.p2align 4 +L$sub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsp,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz L$sub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +L$copy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r9,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz L$copy + + movq 8(%rsp,%r9,8),%rsi + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mul_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 4 +bn_mul4x_mont: + + movl %r9d,%r9d + movq %rsp,%rax + +L$mul4x_enter: + andl $0x80100,%r11d + cmpl $0x80100,%r11d + je L$mulx4x_enter + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + + negq %r9 + movq %rsp,%r11 + leaq -32(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul4x_page_walk + jmp L$mul4x_page_walk_done + +L$mul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul4x_page_walk +L$mul4x_page_walk_done: + + movq %rax,8(%rsp,%r9,8) + +L$mul4x_body: + movq %rdi,16(%rsp,%r9,8) + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp L$1st4x +.p2align 4 +L$1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb L$1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.p2align 2 +L$outer4x: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp L$inner4x +.p2align 4 +L$inner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb L$inner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jb L$outer4x + movq 16(%rsp,%r9,8),%rdi + leaq -4(%r9),%r15 + movq 0(%rsp),%rax + movq 8(%rsp),%rdx + shrq $2,%r15 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + +L$sub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz L$sub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + pxor %xmm0,%xmm0 +.byte 102,72,15,110,224 + pcmpeqd %xmm5,%xmm5 + pshufd $0,%xmm4,%xmm4 + movq %r9,%r15 + pxor %xmm4,%xmm5 + shrq $2,%r15 + xorl %eax,%eax + + jmp L$copy4x +.p2align 4 +L$copy4x: + movdqa (%rsp,%rax,1),%xmm1 + movdqu (%rdi,%rax,1),%xmm2 + pand %xmm4,%xmm1 + pand %xmm5,%xmm2 + movdqa 16(%rsp,%rax,1),%xmm3 + movdqa %xmm0,(%rsp,%rax,1) + por %xmm2,%xmm1 + movdqu 16(%rdi,%rax,1),%xmm2 + movdqu %xmm1,(%rdi,%rax,1) + pand %xmm4,%xmm3 + pand %xmm5,%xmm2 + movdqa %xmm0,16(%rsp,%rax,1) + por %xmm2,%xmm3 + movdqu %xmm3,16(%rdi,%rax,1) + leaq 32(%rax),%rax + decq %r15 + jnz L$copy4x + movq 8(%rsp,%r9,8),%rsi + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mul4x_epilogue: + .byte 0xf3,0xc3 + + + + + + +.p2align 5 +bn_sqr8x_mont: + + movq %rsp,%rax + +L$sqr8x_enter: + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$sqr8x_prologue: + + movl %r9d,%r10d + shll $3,%r9d + shlq $3+2,%r10 + negq %r9 + + + + + + + leaq -64(%rsp,%r9,2),%r11 + movq %rsp,%rbp + movq (%r8),%r8 + subq %rsi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$sqr8x_sp_alt + subq %r11,%rbp + leaq -64(%rbp,%r9,2),%rbp + jmp L$sqr8x_sp_done + +.p2align 5 +L$sqr8x_sp_alt: + leaq 4096-64(,%r9,2),%r10 + leaq -64(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$sqr8x_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$sqr8x_page_walk + jmp L$sqr8x_page_walk_done + +.p2align 4 +L$sqr8x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$sqr8x_page_walk +L$sqr8x_page_walk_done: + + movq %r9,%r10 + negq %r9 + + movq %r8,32(%rsp) + movq %rax,40(%rsp) + +L$sqr8x_body: + +.byte 102,72,15,110,209 + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,73,15,110,218 + leaq _OPENSSL_ia32cap_P(%rip),%rax + movl 8(%rax),%eax + andl $0x80100,%eax + cmpl $0x80100,%eax + jne L$sqr8x_nox + + call _bn_sqrx8x_internal + + + + + leaq (%r8,%rcx,1),%rbx + movq %rcx,%r9 + movq %rcx,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp L$sqr8x_sub + +.p2align 5 +L$sqr8x_nox: + call _bn_sqr8x_internal + + + + + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx + movq %r9,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp L$sqr8x_sub + +.p2align 5 +L$sqr8x_sub: + movq 0(%rbx),%r12 + movq 8(%rbx),%r13 + movq 16(%rbx),%r14 + movq 24(%rbx),%r15 + leaq 32(%rbx),%rbx + sbbq 0(%rbp),%r12 + sbbq 8(%rbp),%r13 + sbbq 16(%rbp),%r14 + sbbq 24(%rbp),%r15 + leaq 32(%rbp),%rbp + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + incq %rcx + jnz L$sqr8x_sub + + sbbq $0,%rax + leaq (%rbx,%r9,1),%rbx + leaq (%rdi,%r9,1),%rdi + +.byte 102,72,15,110,200 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi + + jmp L$sqr8x_cond_copy + +.p2align 5 +L$sqr8x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + movdqa %xmm0,-32(%rbx,%rdx,1) + movdqa %xmm0,-16(%rbx,%rdx,1) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + addq $32,%r9 + jnz L$sqr8x_cond_copy + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$sqr8x_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +bn_mulx4x_mont: + + movq %rsp,%rax + +L$mulx4x_enter: + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$mulx4x_prologue: + + shll $3,%r9d + xorq %r10,%r10 + subq %r9,%r10 + movq (%r8),%r8 + leaq -72(%rsp,%r10,1),%rbp + andq $-128,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mulx4x_page_walk + jmp L$mulx4x_page_walk_done + +.p2align 4 +L$mulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mulx4x_page_walk +L$mulx4x_page_walk_done: + + leaq (%rdx,%r9,1),%r10 + + + + + + + + + + + + + movq %r9,0(%rsp) + shrq $5,%r9 + movq %r10,16(%rsp) + subq $1,%r9 + movq %r8,24(%rsp) + movq %rdi,32(%rsp) + movq %rax,40(%rsp) + + movq %r9,48(%rsp) + jmp L$mulx4x_body + +.p2align 5 +L$mulx4x_body: + leaq 8(%rdx),%rdi + movq (%rdx),%rdx + leaq 64+32(%rsp),%rbx + movq %rdx,%r9 + + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r14 + addq %rax,%r11 + movq %rdi,8(%rsp) + mulxq 16(%rsi),%r12,%r13 + adcq %r14,%r12 + adcq $0,%r13 + + movq %r8,%rdi + imulq 24(%rsp),%r8 + xorq %rbp,%rbp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%rdi + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 +.byte 0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00 + movq 48(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + + jmp L$mulx4x_1st + +.p2align 5 +L$mulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz L$mulx4x_1st + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + addq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + jmp L$mulx4x_outer + +.p2align 5 +L$mulx4x_outer: + movq (%rdi),%rdx + leaq 8(%rdi),%rdi + subq %rax,%rsi + movq %r15,(%rbx) + leaq 64+32(%rsp),%rbx + subq %rax,%rcx + + mulxq 0(%rsi),%r8,%r11 + xorl %ebp,%ebp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + adoxq -16(%rbx),%r12 + adcxq %rbp,%r13 + adoxq %rbp,%r13 + + movq %rdi,8(%rsp) + movq %r8,%r15 + imulq 24(%rsp),%r8 + xorl %ebp,%ebp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + adcxq %rax,%r13 + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + adoxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + leaq 32(%rcx),%rcx + adcxq %rax,%r12 + adoxq %rbp,%r15 + movq 48(%rsp),%rdi + movq %r12,-16(%rbx) + + jmp L$mulx4x_inner + +.p2align 5 +L$mulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-32(%rbx) + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz L$mulx4x_inner + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + subq 0(%rbx),%rbp + adcq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + + cmpq 16(%rsp),%rdi + jne L$mulx4x_outer + + leaq 64(%rsp),%rbx + subq %rax,%rcx + negq %r15 + movq %rax,%rdx + shrq $3+2,%rax + movq 32(%rsp),%rdi + jmp L$mulx4x_sub + +.p2align 5 +L$mulx4x_sub: + movq 0(%rbx),%r11 + movq 8(%rbx),%r12 + movq 16(%rbx),%r13 + movq 24(%rbx),%r14 + leaq 32(%rbx),%rbx + sbbq 0(%rcx),%r11 + sbbq 8(%rcx),%r12 + sbbq 16(%rcx),%r13 + sbbq 24(%rcx),%r14 + leaq 32(%rcx),%rcx + movq %r11,0(%rdi) + movq %r12,8(%rdi) + movq %r13,16(%rdi) + movq %r14,24(%rdi) + leaq 32(%rdi),%rdi + decq %rax + jnz L$mulx4x_sub + + sbbq $0,%r15 + leaq 64(%rsp),%rbx + subq %rdx,%rdi + +.byte 102,73,15,110,207 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi + + jmp L$mulx4x_cond_copy + +.p2align 5 +L$mulx4x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + subq $32,%rdx + jnz L$mulx4x_cond_copy + + movq %rdx,(%rbx) + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mulx4x_epilogue: + .byte 0xf3,0xc3 + + +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.p2align 4 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S new file mode 100644 index 00000000..ac98157b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S @@ -0,0 +1,3797 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + +.extern OPENSSL_ia32cap_P +.hidden OPENSSL_ia32cap_P + +.globl bn_mul_mont_gather5 +.hidden bn_mul_mont_gather5 +.type bn_mul_mont_gather5,@function +.align 64 +bn_mul_mont_gather5: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax + testl $7,%r9d + jnz .Lmul_enter + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + movd 8(%rsp),%xmm5 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -280(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + +.Lmul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + + leaq .Linc(%rip),%r10 + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul_body: + + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 24-112(%rsp,%r9,8),%r10 + andq $-16,%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne .L1st + + + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + leaq 24+128(%rsp,%r9,8),%rdx + andq $-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + + movq (%rsi),%rax +.byte 102,72,15,126,195 + + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne .Linner + + addq %rax,%r13 + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r9,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp .Lsub +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +.Lcopy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r14,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul_mont_gather5,.-bn_mul_mont_gather5 +.type bn_mul4x_mont_gather5,@function +.align 32 +bn_mul4x_mont_gather5: +.cfi_startproc +.byte 0x67 + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmul4x_enter: + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je .Lmulx4x_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmul4x_prologue: + +.byte 0x67 + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lmul4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lmul4xsp_done + +.align 32 +.Lmul4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lmul4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + +.Lmul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: + + negq %r9 + + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lmul4x_body: + + call mul4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5 + +.type mul4x_internal,@function +.align 32 +mul4x_internal: +.cfi_startproc + shlq $5,%r9 + movd 8(%rax),%xmm5 + leaq .Linc(%rip),%rax + leaq 128(%rdx,%r9,1),%r13 + shrq $5,%r9 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r9,1),%r10 + leaq 128(%rdx),%r12 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67,0x67 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq %r13,16+8(%rsp) + movq %rdi,56+8(%rsp) + + movq (%r8),%r8 + movq (%rsi),%rax + leaq (%rsi,%r9,1),%rsi + negq %r9 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + leaq 64+8(%rsp),%r14 + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + jmp .L1st4x + +.align 32 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + jmp .Louter4x + +.align 32 +.Louter4x: + leaq 16+128(%r14),%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r14,%r9,1),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + movq %rdi,(%r14) + + leaq (%r14,%r9,1),%r14 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdx,%r13 + jmp .Linner4x + +.align 32 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + addq (%r14),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq %rbp,%rax + movq -8(%rcx),%rbp + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + movq %rdi,-16(%r14) + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%r14),%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + cmpq 16+8(%rsp),%r12 + jb .Louter4x + xorq %rax,%rax + subq %r13,%rbp + adcq %r15,%r15 + orq %r15,%rdi + subq %rdi,%rax + leaq (%r14,%r9,1),%rbx + movq (%rcx),%r12 + leaq (%rcx),%rbp + movq %r9,%rcx + sarq $3+2,%rcx + movq 56+8(%rsp),%rdi + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqr4x_sub_entry +.cfi_endproc +.size mul4x_internal,.-mul4x_internal +.globl bn_power5 +.hidden bn_power5 +.type bn_power5,@function +.align 32 +bn_power5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je .Lpowerx5_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lpower5_prologue: + + shll $3,%r9d + leal (%r9,%r9,2),%r10d + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lpwr_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lpwr_sp_done + +.align 32 +.Lpwr_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lpwr_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwr_page_walk + jmp .Lpwr_page_walk_done + +.Lpwr_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwr_page_walk +.Lpwr_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lpower5_body: +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq %rsi,%rdi + movq 40(%rsp),%rax + leaq 32(%rsp),%r8 + + call mul4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpower5_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_power5,.-bn_power5 + +.globl bn_sqr8x_internal +.hidden bn_sqr8x_internal +.hidden bn_sqr8x_internal +.type bn_sqr8x_internal,@function +.align 32 +bn_sqr8x_internal: +__bn_sqr8x_internal: +.cfi_startproc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 32(%r10),%rbp + leaq (%rsi,%r9,1),%rsi + + movq %r9,%rcx + + + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + movq %r11,-16(%rdi,%rbp,1) + movq %rdx,%r10 + + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + movq %rax,%r12 + movq %rbx,%rax + movq %rdx,%r13 + + leaq (%rbp),%rcx + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + jmp .Lsqr4x_1st + +.align 32 +.Lsqr4x_1st: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq 16(%rsi,%rcx,1),%rbx + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %r10,8(%rdi,%rcx,1) + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 24(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,16(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + leaq 32(%rcx),%rcx + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_1st + + mulq %r15 + addq %rax,%r13 + leaq 16(%rbp),%rbp + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + jmp .Lsqr4x_outer + +.align 32 +.Lsqr4x_outer: + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq -24(%rdi,%rbp,1),%r10 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + movq %r10,-24(%rdi,%rbp,1) + movq %rdx,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + addq -16(%rdi,%rbp,1),%r11 + movq %rdx,%r10 + adcq $0,%r10 + movq %r11,-16(%rdi,%rbp,1) + + xorq %r12,%r12 + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq $0,%rdx + addq -8(%rdi,%rbp,1),%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rbp,1) + + leaq (%rbp),%rcx + jmp .Lsqr4x_inner + +.align 32 +.Lsqr4x_inner: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + addq (%rdi,%rcx,1),%r13 + adcq $0,%r12 + +.byte 0x67 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %r11,(%rdi,%rcx,1) + movq %rbx,%rax + movq %rdx,%r13 + adcq $0,%r13 + addq 8(%rdi,%rcx,1),%r12 + leaq 16(%rcx),%rcx + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_inner + +.byte 0x67 + mulq %r15 + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + addq $16,%rbp + jnz .Lsqr4x_outer + + + movq -32(%rsi),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi),%rbx + movq %rax,%r15 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq %r10,-24(%rdi) + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + movq -8(%rsi),%rbx + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,-16(%rdi) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi) + + mulq %r15 + addq %rax,%r13 + movq -16(%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + mulq %rbx + addq $16,%rbp + xorq %r14,%r14 + subq %r9,%rbp + xorq %r15,%r15 + + addq %r12,%rax + adcq $0,%rdx + movq %rax,8(%rdi) + movq %rdx,16(%rdi) + movq %r15,24(%rdi) + + movq -16(%rsi,%rbp,1),%rax + leaq 48+8(%rsp),%rdi + xorq %r10,%r10 + movq 8(%rdi),%r11 + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + leaq 16(%rbp),%rbp + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + jmp .Lsqr4x_shift_n_add + +.align 32 +.Lsqr4x_shift_n_add: + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi) + adcq %rdx,%r8 + + leaq (%r14,%r10,2),%r12 + movq %r8,-8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq 8(%rsi,%rbp,1),%rax + movq %r12,0(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 16(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + addq $32,%rbp + jnz .Lsqr4x_shift_n_add + + leaq (%r14,%r10,2),%r12 +.byte 0x67 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + mulq %rax + negq %r15 + adcq %rax,%rbx + adcq %rdx,%r8 + movq %rbx,-16(%rdi) + movq %r8,-8(%rdi) +.byte 102,72,15,126,213 +__bn_sqr8x_reduction: + xorq %rax,%rax + leaq (%r9,%rbp,1),%rcx + leaq 48+8(%rsp,%r9,2),%rdx + movq %rcx,0+8(%rsp) + leaq 48+8(%rsp,%r9,1),%rdi + movq %rdx,8+8(%rsp) + negq %r9 + jmp .L8x_reduction_loop + +.align 32 +.L8x_reduction_loop: + leaq (%rdi,%r9,1),%rdi +.byte 0x66 + movq 0(%rdi),%rbx + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,(%rdx) + leaq 64(%rdi),%rdi + +.byte 0x67 + movq %rbx,%r8 + imulq 32+8(%rsp),%rbx + movq 0(%rbp),%rax + movl $8,%ecx + jmp .L8x_reduce + +.align 32 +.L8x_reduce: + mulq %rbx + movq 8(%rbp),%rax + negq %r8 + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rbx,48-8+8(%rsp,%rcx,8) + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq 32+8(%rsp),%rsi + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + imulq %r8,%rsi + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq %rsi,%rbx + addq %rax,%r15 + movq 0(%rbp),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz .L8x_reduce + + leaq 64(%rbp),%rbp + xorq %rax,%rax + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae .L8x_no_tail + +.byte 0x66 + addq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movq 48+56+8(%rsp),%rbx + movl $8,%ecx + movq 0(%rbp),%rax + jmp .L8x_tail + +.align 32 +.L8x_tail: + mulq %rbx + addq %rax,%r8 + movq 8(%rbp),%rax + movq %r8,(%rdi) + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + leaq 8(%rdi),%rdi + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq 48-16+8(%rsp,%rcx,8),%rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r15,%r14 + movq 0(%rbp),%rax + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz .L8x_tail + + leaq 64(%rbp),%rbp + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae .L8x_tail_done + + movq 48+56+8(%rsp),%rbx + negq %rsi + movq 0(%rbp),%rax + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movl $8,%ecx + jmp .L8x_tail + +.align 32 +.L8x_tail_done: + xorq %rax,%rax + addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + negq %rsi +.L8x_no_tail: + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + movq -8(%rbp),%rcx + xorq %rsi,%rsi + +.byte 102,72,15,126,213 + + movq %r8,0(%rdi) + movq %r9,8(%rdi) +.byte 102,73,15,126,217 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rdi),%rdi + + cmpq %rdx,%rdi + jb .L8x_reduction_loop + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqr8x_internal,.-bn_sqr8x_internal +.type __bn_post4x_internal,@function +.align 32 +__bn_post4x_internal: +.cfi_startproc + movq 0(%rbp),%r12 + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx +.byte 102,72,15,126,207 + negq %rax +.byte 102,72,15,126,206 + sarq $3+2,%rcx + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqr4x_sub_entry + +.align 16 +.Lsqr4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +.Lsqr4x_sub_entry: + leaq 32(%rbp),%rbp + notq %r12 + notq %r13 + notq %r14 + notq %r15 + andq %rax,%r12 + andq %rax,%r13 + andq %rax,%r14 + andq %rax,%r15 + + negq %r10 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + adcq 16(%rbx),%r14 + adcq 24(%rbx),%r15 + movq %r12,0(%rdi) + leaq 32(%rbx),%rbx + movq %r13,8(%rdi) + sbbq %r10,%r10 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + + incq %rcx + jnz .Lsqr4x_sub + + movq %r9,%r10 + negq %r9 + .byte 0xf3,0xc3 +.cfi_endproc +.size __bn_post4x_internal,.-__bn_post4x_internal +.globl bn_from_montgomery +.hidden bn_from_montgomery +.type bn_from_montgomery,@function +.align 32 +bn_from_montgomery: +.cfi_startproc + testl $7,%r9d + jz bn_from_mont8x + xorl %eax,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_from_montgomery,.-bn_from_montgomery + +.type bn_from_mont8x,@function +.align 32 +bn_from_mont8x: +.cfi_startproc +.byte 0x67 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lfrom_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lfrom_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lfrom_sp_done + +.align 32 +.Lfrom_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lfrom_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lfrom_page_walk + jmp .Lfrom_page_walk_done + +.Lfrom_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lfrom_page_walk +.Lfrom_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lfrom_body: + movq %r9,%r11 + leaq 48(%rsp),%rax + pxor %xmm0,%xmm0 + jmp .Lmul_by_1 + +.align 32 +.Lmul_by_1: + movdqu (%rsi),%xmm1 + movdqu 16(%rsi),%xmm2 + movdqu 32(%rsi),%xmm3 + movdqa %xmm0,(%rax,%r9,1) + movdqu 48(%rsi),%xmm4 + movdqa %xmm0,16(%rax,%r9,1) +.byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 + movdqa %xmm1,(%rax) + movdqa %xmm0,32(%rax,%r9,1) + movdqa %xmm2,16(%rax) + movdqa %xmm0,48(%rax,%r9,1) + movdqa %xmm3,32(%rax) + movdqa %xmm4,48(%rax) + leaq 64(%rax),%rax + subq $64,%r11 + jnz .Lmul_by_1 + +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 0x67 + movq %rcx,%rbp +.byte 102,73,15,110,218 + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + andl $0x80108,%r11d + cmpl $0x80108,%r11d + jne .Lfrom_mont_nox + + leaq (%rax,%r9,1),%rdi + call __bn_sqrx8x_reduction + call __bn_postx4x_internal + + pxor %xmm0,%xmm0 + leaq 48(%rsp),%rax + jmp .Lfrom_mont_zero + +.align 32 +.Lfrom_mont_nox: + call __bn_sqr8x_reduction + call __bn_post4x_internal + + pxor %xmm0,%xmm0 + leaq 48(%rsp),%rax + jmp .Lfrom_mont_zero + +.align 32 +.Lfrom_mont_zero: + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + movdqa %xmm0,32(%rax) + movdqa %xmm0,48(%rax) + leaq 64(%rax),%rax + subq $32,%r9 + jnz .Lfrom_mont_zero + + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lfrom_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_from_mont8x,.-bn_from_mont8x +.type bn_mulx4x_mont_gather5,@function +.align 32 +bn_mulx4x_mont_gather5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmulx4x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmulx4x_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lmulx4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lmulx4xsp_done + +.Lmulx4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lmulx4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + +.Lmulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: + + + + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lmulx4x_body: + call mulx4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmulx4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mulx4x_mont_gather5,.-bn_mulx4x_mont_gather5 + +.type mulx4x_internal,@function +.align 32 +mulx4x_internal: +.cfi_startproc + movq %r9,8(%rsp) + movq %r9,%r10 + negq %r9 + shlq $5,%r9 + negq %r10 + leaq 128(%rdx,%r9,1),%r13 + shrq $5+5,%r9 + movd 8(%rax),%xmm5 + subq $1,%r9 + leaq .Linc(%rip),%rax + movq %r13,16+8(%rsp) + movq %r9,24+8(%rsp) + movq %rdi,56+8(%rsp) + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r10,1),%r10 + leaq 128(%rdx),%rdi + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67 + movdqa %xmm1,%xmm2 +.byte 0x67 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 +.byte 0x67 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + + pand 64(%rdi),%xmm0 + pand 80(%rdi),%xmm1 + pand 96(%rdi),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%rdi),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%rdi),%xmm4 + movdqa -112(%rdi),%xmm5 + movdqa -96(%rdi),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%rdi),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%rdi),%xmm4 + movdqa -48(%rdi),%xmm5 + movdqa -32(%rdi),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%rdi),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%rdi),%xmm4 + movdqa 16(%rdi),%xmm5 + movdqa 32(%rdi),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%rdi),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + leaq 64+32+8(%rsp),%rbx + + movq %rdx,%r9 + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r12 + addq %rax,%r11 + mulxq 16(%rsi),%rax,%r13 + adcq %rax,%r12 + adcq $0,%r13 + mulxq 24(%rsi),%rax,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + xorq %rbp,%rbp + movq %r8,%rdx + + movq %rdi,8+8(%rsp) + + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + jmp .Lmulx4x_1st + +.align 32 +.Lmulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_1st + + movq 8(%rsp),%rax + adcq %rbp,%r15 + leaq (%rsi,%rax,1),%rsi + addq %r15,%r14 + movq 8+8(%rsp),%rdi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + jmp .Lmulx4x_outer + +.align 32 +.Lmulx4x_outer: + leaq 16-256(%rbx),%r10 + pxor %xmm4,%xmm4 +.byte 0x67,0x67 + pxor %xmm5,%xmm5 + movdqa -128(%rdi),%xmm0 + movdqa -112(%rdi),%xmm1 + movdqa -96(%rdi),%xmm2 + pand 256(%r10),%xmm0 + movdqa -80(%rdi),%xmm3 + pand 272(%r10),%xmm1 + por %xmm0,%xmm4 + pand 288(%r10),%xmm2 + por %xmm1,%xmm5 + pand 304(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%rdi),%xmm0 + movdqa -48(%rdi),%xmm1 + movdqa -32(%rdi),%xmm2 + pand 320(%r10),%xmm0 + movdqa -16(%rdi),%xmm3 + pand 336(%r10),%xmm1 + por %xmm0,%xmm4 + pand 352(%r10),%xmm2 + por %xmm1,%xmm5 + pand 368(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%rdi),%xmm0 + movdqa 16(%rdi),%xmm1 + movdqa 32(%rdi),%xmm2 + pand 384(%r10),%xmm0 + movdqa 48(%rdi),%xmm3 + pand 400(%r10),%xmm1 + por %xmm0,%xmm4 + pand 416(%r10),%xmm2 + por %xmm1,%xmm5 + pand 432(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%rdi),%xmm0 + movdqa 80(%rdi),%xmm1 + movdqa 96(%rdi),%xmm2 + pand 448(%r10),%xmm0 + movdqa 112(%rdi),%xmm3 + pand 464(%r10),%xmm1 + por %xmm0,%xmm4 + pand 480(%r10),%xmm2 + por %xmm1,%xmm5 + pand 496(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + + movq %rbp,(%rbx) + leaq 32(%rbx,%rax,1),%rbx + mulxq 0(%rsi),%r8,%r11 + xorq %rbp,%rbp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + mulxq 24(%rsi),%rdx,%r14 + adoxq -16(%rbx),%r12 + adcxq %rdx,%r13 + leaq (%rcx,%rax,1),%rcx + leaq 32(%rsi),%rsi + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + adoxq %rbp,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + + movq %r8,%rdx + xorq %rbp,%rbp + movq %rdi,8+8(%rsp) + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r12 + movq %r11,-24(%rbx) + adoxq %rbp,%r15 + movq %r12,-16(%rbx) + leaq 32(%rcx),%rcx + jmp .Lmulx4x_inner + +.align 32 +.Lmulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + movq %r11,-32(%rbx) + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + leaq 32(%rcx),%rcx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_inner + + movq 0+8(%rsp),%rax + adcq %rbp,%r15 + subq 0(%rbx),%rdi + movq 8+8(%rsp),%rdi + movq 16+8(%rsp),%r10 + adcq %r15,%r14 + leaq (%rsi,%rax,1),%rsi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + + cmpq %r10,%rdi + jb .Lmulx4x_outer + + movq -8(%rcx),%r10 + movq %rbp,%r8 + movq (%rcx,%rax,1),%r12 + leaq (%rcx,%rax,1),%rbp + movq %rax,%rcx + leaq (%rbx,%rax,1),%rdi + xorl %eax,%eax + xorq %r15,%r15 + subq %r14,%r10 + adcq %r15,%r15 + orq %r15,%r8 + sarq $3+2,%rcx + subq %r8,%rax + movq 56+8(%rsp),%rdx + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqrx4x_sub_entry +.cfi_endproc +.size mulx4x_internal,.-mulx4x_internal +.type bn_powerx5,@function +.align 32 +bn_powerx5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lpowerx5_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lpowerx5_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lpwrx_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lpwrx_sp_done + +.align 32 +.Lpwrx_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lpwrx_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwrx_page_walk + jmp .Lpwrx_page_walk_done + +.Lpwrx_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwrx_page_walk +.Lpwrx_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + + + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lpowerx5_body: + + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + + movq %r10,%r9 + movq %rsi,%rdi +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq 40(%rsp),%rax + + call mulx4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpowerx5_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_powerx5,.-bn_powerx5 + +.globl bn_sqrx8x_internal +.hidden bn_sqrx8x_internal +.hidden bn_sqrx8x_internal +.type bn_sqrx8x_internal,@function +.align 32 +bn_sqrx8x_internal: +__bn_sqrx8x_internal: +.cfi_startproc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 48+8(%rsp),%rdi + leaq (%rsi,%r9,1),%rbp + movq %r9,0+8(%rsp) + movq %rbp,8+8(%rsp) + jmp .Lsqr8x_zero_start + +.align 32 +.byte 0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 +.Lsqrx8x_zero: +.byte 0x3e + movdqa %xmm0,0(%rdi) + movdqa %xmm0,16(%rdi) + movdqa %xmm0,32(%rdi) + movdqa %xmm0,48(%rdi) +.Lsqr8x_zero_start: + movdqa %xmm0,64(%rdi) + movdqa %xmm0,80(%rdi) + movdqa %xmm0,96(%rdi) + movdqa %xmm0,112(%rdi) + leaq 128(%rdi),%rdi + subq $64,%r9 + jnz .Lsqrx8x_zero + + movq 0(%rsi),%rdx + + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + leaq 48+8(%rsp),%rdi + xorq %rbp,%rbp + jmp .Lsqrx8x_outer_loop + +.align 32 +.Lsqrx8x_outer_loop: + mulxq 8(%rsi),%r8,%rax + adcxq %r9,%r8 + adoxq %rax,%r10 + mulxq 16(%rsi),%r9,%rax + adcxq %r10,%r9 + adoxq %rax,%r11 +.byte 0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00 + adcxq %r11,%r10 + adoxq %rax,%r12 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 + adcxq %r12,%r11 + adoxq %rax,%r13 + mulxq 40(%rsi),%r12,%rax + adcxq %r13,%r12 + adoxq %rax,%r14 + mulxq 48(%rsi),%r13,%rax + adcxq %r14,%r13 + adoxq %r15,%rax + mulxq 56(%rsi),%r14,%r15 + movq 8(%rsi),%rdx + adcxq %rax,%r14 + adoxq %rbp,%r15 + adcq 64(%rdi),%r15 + movq %r8,8(%rdi) + movq %r9,16(%rdi) + sbbq %rcx,%rcx + xorq %rbp,%rbp + + + mulxq 16(%rsi),%r8,%rbx + mulxq 24(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 32(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %rbx,%r11 +.byte 0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00 + adcxq %r13,%r11 + adoxq %r14,%r12 +.byte 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 + movq 16(%rsi),%rdx + adcxq %rax,%r12 + adoxq %rbx,%r13 + adcxq %r15,%r13 + adoxq %rbp,%r14 + adcxq %rbp,%r14 + + movq %r8,24(%rdi) + movq %r9,32(%rdi) + + mulxq 24(%rsi),%r8,%rbx + mulxq 32(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 40(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %r13,%r11 +.byte 0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00 +.byte 0x3e + movq 24(%rsi),%rdx + adcxq %rbx,%r11 + adoxq %rax,%r12 + adcxq %r14,%r12 + movq %r8,40(%rdi) + movq %r9,48(%rdi) + mulxq 32(%rsi),%r8,%rax + adoxq %rbp,%r13 + adcxq %rbp,%r13 + + mulxq 40(%rsi),%r9,%rbx + adcxq %r10,%r8 + adoxq %rax,%r9 + mulxq 48(%rsi),%r10,%rax + adcxq %r11,%r9 + adoxq %r12,%r10 + mulxq 56(%rsi),%r11,%r12 + movq 32(%rsi),%rdx + movq 40(%rsi),%r14 + adcxq %rbx,%r10 + adoxq %rax,%r11 + movq 48(%rsi),%r15 + adcxq %r13,%r11 + adoxq %rbp,%r12 + adcxq %rbp,%r12 + + movq %r8,56(%rdi) + movq %r9,64(%rdi) + + mulxq %r14,%r9,%rax + movq 56(%rsi),%r8 + adcxq %r10,%r9 + mulxq %r15,%r10,%rbx + adoxq %rax,%r10 + adcxq %r11,%r10 + mulxq %r8,%r11,%rax + movq %r14,%rdx + adoxq %rbx,%r11 + adcxq %r12,%r11 + + adcxq %rbp,%rax + + mulxq %r15,%r14,%rbx + mulxq %r8,%r12,%r13 + movq %r15,%rdx + leaq 64(%rsi),%rsi + adcxq %r14,%r11 + adoxq %rbx,%r12 + adcxq %rax,%r12 + adoxq %rbp,%r13 + +.byte 0x67,0x67 + mulxq %r8,%r8,%r14 + adcxq %r8,%r13 + adcxq %rbp,%r14 + + cmpq 8+8(%rsp),%rsi + je .Lsqrx8x_outer_break + + negq %rcx + movq $-8,%rcx + movq %rbp,%r15 + movq 64(%rdi),%r8 + adcxq 72(%rdi),%r9 + adcxq 80(%rdi),%r10 + adcxq 88(%rdi),%r11 + adcq 96(%rdi),%r12 + adcq 104(%rdi),%r13 + adcq 112(%rdi),%r14 + adcq 120(%rdi),%r15 + leaq (%rsi),%rbp + leaq 128(%rdi),%rdi + sbbq %rax,%rax + + movq -64(%rsi),%rdx + movq %rax,16+8(%rsp) + movq %rdi,24+8(%rsp) + + + xorl %eax,%eax + jmp .Lsqrx8x_loop + +.align 32 +.Lsqrx8x_loop: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + movq %rbx,(%rdi,%rcx,8) + movl $0,%ebx + adcxq %rax,%r13 + adoxq %r15,%r14 + +.byte 0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00 + movq 8(%rsi,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rbx,%r15 + adcxq %rbx,%r15 + +.byte 0x67 + incq %rcx + jnz .Lsqrx8x_loop + + leaq 64(%rbp),%rbp + movq $-8,%rcx + cmpq 8+8(%rsp),%rbp + je .Lsqrx8x_break + + subq 16+8(%rsp),%rbx +.byte 0x66 + movq -64(%rsi),%rdx + adcxq 0(%rdi),%r8 + adcxq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi +.byte 0x67 + sbbq %rax,%rax + xorl %ebx,%ebx + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_loop + +.align 32 +.Lsqrx8x_break: + xorq %rbp,%rbp + subq 16+8(%rsp),%rbx + adcxq %rbp,%r8 + movq 24+8(%rsp),%rcx + adcxq %rbp,%r9 + movq 0(%rsi),%rdx + adcq $0,%r10 + movq %r8,0(%rdi) + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + cmpq %rcx,%rdi + je .Lsqrx8x_outer_loop + + movq %r9,8(%rdi) + movq 8(%rcx),%r9 + movq %r10,16(%rdi) + movq 16(%rcx),%r10 + movq %r11,24(%rdi) + movq 24(%rcx),%r11 + movq %r12,32(%rdi) + movq 32(%rcx),%r12 + movq %r13,40(%rdi) + movq 40(%rcx),%r13 + movq %r14,48(%rdi) + movq 48(%rcx),%r14 + movq %r15,56(%rdi) + movq 56(%rcx),%r15 + movq %rcx,%rdi + jmp .Lsqrx8x_outer_loop + +.align 32 +.Lsqrx8x_outer_break: + movq %r9,72(%rdi) +.byte 102,72,15,126,217 + movq %r10,80(%rdi) + movq %r11,88(%rdi) + movq %r12,96(%rdi) + movq %r13,104(%rdi) + movq %r14,112(%rdi) + leaq 48+8(%rsp),%rdi + movq (%rsi,%rcx,1),%rdx + + movq 8(%rdi),%r11 + xorq %r10,%r10 + movq 0+8(%rsp),%r9 + adoxq %r11,%r11 + movq 16(%rdi),%r12 + movq 24(%rdi),%r13 + + +.align 32 +.Lsqrx4x_shift_n_add: + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax +.byte 0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00 +.byte 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 40(%rdi),%r11 + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + movq 16(%rsi,%rcx,1),%rdx + movq 48(%rdi),%r12 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 56(%rdi),%r13 + movq %rax,16(%rdi) + movq %rbx,24(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax + movq 24(%rsi,%rcx,1),%rdx + leaq 32(%rcx),%rcx + movq 64(%rdi),%r10 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 72(%rdi),%r11 + movq %rax,32(%rdi) + movq %rbx,40(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + jrcxz .Lsqrx4x_shift_n_add_break +.byte 0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 80(%rdi),%r12 + movq 88(%rdi),%r13 + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi + nop + jmp .Lsqrx4x_shift_n_add + +.align 32 +.Lsqrx4x_shift_n_add_break: + adcxq %r13,%rbx + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi +.byte 102,72,15,126,213 +__bn_sqrx8x_reduction: + xorl %eax,%eax + movq 32+8(%rsp),%rbx + movq 48+8(%rsp),%rdx + leaq -64(%rbp,%r9,1),%rcx + + movq %rcx,0+8(%rsp) + movq %rdi,8+8(%rsp) + + leaq 48+8(%rsp),%rdi + jmp .Lsqrx8x_reduction_loop + +.align 32 +.Lsqrx8x_reduction_loop: + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq %rdx,%r8 + imulq %rbx,%rdx + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,24+8(%rsp) + + leaq 64(%rdi),%rdi + xorq %rsi,%rsi + movq $-8,%rcx + jmp .Lsqrx8x_reduce + +.align 32 +.Lsqrx8x_reduce: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rbx,%rax + adoxq %r9,%r8 + + mulxq 8(%rbp),%rbx,%r9 + adcxq %rbx,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rbx,%r10 + adcxq %rbx,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rbx,%r11 + adcxq %rbx,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 + movq %rdx,%rax + movq %r8,%rdx + adcxq %rbx,%r11 + adoxq %r13,%r12 + + mulxq 32+8(%rsp),%rbx,%rdx + movq %rax,%rdx + movq %rax,64+48+8(%rsp,%rcx,8) + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq %rbx,%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + adcxq %rsi,%r15 + +.byte 0x67,0x67,0x67 + incq %rcx + jnz .Lsqrx8x_reduce + + movq %rsi,%rax + cmpq 0+8(%rsp),%rbp + jae .Lsqrx8x_no_tail + + movq 48+8(%rsp),%rdx + addq 0(%rdi),%r8 + leaq 64(%rbp),%rbp + movq $-8,%rcx + adcxq 8(%rdi),%r9 + adcxq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_tail + +.align 32 +.Lsqrx8x_tail: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq 72+48+8(%rsp,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + movq %rbx,(%rdi,%rcx,8) + movq %r8,%rbx + adcxq %rsi,%r15 + + incq %rcx + jnz .Lsqrx8x_tail + + cmpq 0+8(%rsp),%rbp + jae .Lsqrx8x_tail_done + + subq 16+8(%rsp),%rsi + movq 48+8(%rsp),%rdx + leaq 64(%rbp),%rbp + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + subq $8,%rcx + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_tail + +.align 32 +.Lsqrx8x_tail_done: + xorq %rax,%rax + addq 24+8(%rsp),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + subq 16+8(%rsp),%rsi +.Lsqrx8x_no_tail: + adcq 0(%rdi),%r8 +.byte 102,72,15,126,217 + adcq 8(%rdi),%r9 + movq 56(%rbp),%rsi +.byte 102,72,15,126,213 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + + movq 32+8(%rsp),%rbx + movq 64(%rdi,%rcx,1),%rdx + + movq %r8,0(%rdi) + leaq 64(%rdi),%r8 + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + leaq 64(%rdi,%rcx,1),%rdi + cmpq 8+8(%rsp),%r8 + jb .Lsqrx8x_reduction_loop + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqrx8x_internal,.-bn_sqrx8x_internal +.align 32 +.type __bn_postx4x_internal,@function +__bn_postx4x_internal: +.cfi_startproc + movq 0(%rbp),%r12 + movq %rcx,%r10 + movq %rcx,%r9 + negq %rax + sarq $3+2,%rcx + +.byte 102,72,15,126,202 +.byte 102,72,15,126,206 + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqrx4x_sub_entry + +.align 16 +.Lsqrx4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +.Lsqrx4x_sub_entry: + andnq %rax,%r12,%r12 + leaq 32(%rbp),%rbp + andnq %rax,%r13,%r13 + andnq %rax,%r14,%r14 + andnq %rax,%r15,%r15 + + negq %r8 + adcq 0(%rdi),%r12 + adcq 8(%rdi),%r13 + adcq 16(%rdi),%r14 + adcq 24(%rdi),%r15 + movq %r12,0(%rdx) + leaq 32(%rdi),%rdi + movq %r13,8(%rdx) + sbbq %r8,%r8 + movq %r14,16(%rdx) + movq %r15,24(%rdx) + leaq 32(%rdx),%rdx + + incq %rcx + jnz .Lsqrx4x_sub + + negq %r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __bn_postx4x_internal,.-__bn_postx4x_internal +.globl bn_scatter5 +.hidden bn_scatter5 +.type bn_scatter5,@function +.align 16 +bn_scatter5: +.cfi_startproc + cmpl $0,%esi + jz .Lscatter_epilogue + leaq (%rdx,%rcx,8),%rdx +.Lscatter: + movq (%rdi),%rax + leaq 8(%rdi),%rdi + movq %rax,(%rdx) + leaq 256(%rdx),%rdx + subl $1,%esi + jnz .Lscatter +.Lscatter_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_scatter5,.-bn_scatter5 + +.globl bn_gather5 +.hidden bn_gather5 +.type bn_gather5,@function +.align 32 +bn_gather5: +.cfi_startproc +.LSEH_begin_bn_gather5: + +.byte 0x4c,0x8d,0x14,0x24 +.cfi_def_cfa_register %r10 +.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + leaq .Linc(%rip),%rax + andq $-16,%rsp + + movd %ecx,%xmm5 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 128(%rdx),%r11 + leaq 128(%rsp),%rax + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-128(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-112(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-96(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-80(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-48(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-16(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,0(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,16(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,48(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,80(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,96(%rax) + movdqa %xmm4,%xmm2 + movdqa %xmm3,112(%rax) + jmp .Lgather + +.align 32 +.Lgather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r11),%xmm0 + movdqa -112(%r11),%xmm1 + movdqa -96(%r11),%xmm2 + pand -128(%rax),%xmm0 + movdqa -80(%r11),%xmm3 + pand -112(%rax),%xmm1 + por %xmm0,%xmm4 + pand -96(%rax),%xmm2 + por %xmm1,%xmm5 + pand -80(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r11),%xmm0 + movdqa -48(%r11),%xmm1 + movdqa -32(%r11),%xmm2 + pand -64(%rax),%xmm0 + movdqa -16(%r11),%xmm3 + pand -48(%rax),%xmm1 + por %xmm0,%xmm4 + pand -32(%rax),%xmm2 + por %xmm1,%xmm5 + pand -16(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + pand 0(%rax),%xmm0 + movdqa 48(%r11),%xmm3 + pand 16(%rax),%xmm1 + por %xmm0,%xmm4 + pand 32(%rax),%xmm2 + por %xmm1,%xmm5 + pand 48(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r11),%xmm0 + movdqa 80(%r11),%xmm1 + movdqa 96(%r11),%xmm2 + pand 64(%rax),%xmm0 + movdqa 112(%r11),%xmm3 + pand 80(%rax),%xmm1 + por %xmm0,%xmm4 + pand 96(%rax),%xmm2 + por %xmm1,%xmm5 + pand 112(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,(%rdi) + leaq 8(%rdi),%rdi + subl $1,%esi + jnz .Lgather + + leaq (%r10),%rsp +.cfi_def_cfa_register %rsp + .byte 0xf3,0xc3 +.LSEH_end_bn_gather5: +.cfi_endproc +.size bn_gather5,.-bn_gather5 +.align 64 +.Linc: +.long 0,0, 1,1 +.long 2,2, 2,2 +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +#endif +.section .note.GNU-stack,"",@progbits +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S new file mode 100644 index 00000000..56c6ecfe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S @@ -0,0 +1,3795 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__APPLE__) +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(BORINGSSL_PREFIX) +#include +#endif +.text + + + +.globl _bn_mul_mont_gather5 +.private_extern _bn_mul_mont_gather5 + +.p2align 6 +_bn_mul_mont_gather5: + + movl %r9d,%r9d + movq %rsp,%rax + + testl $7,%r9d + jnz L$mul_enter + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + jmp L$mul4x_enter + +.p2align 4 +L$mul_enter: + movd 8(%rsp),%xmm5 + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + + + negq %r9 + movq %rsp,%r11 + leaq -280(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul_page_walk + jmp L$mul_page_walk_done + +L$mul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja L$mul_page_walk +L$mul_page_walk_done: + + leaq L$inc(%rip),%r10 + movq %rax,8(%rsp,%r9,8) + +L$mul_body: + + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 24-112(%rsp,%r9,8),%r10 + andq $-16,%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$1st_enter + +.p2align 4 +L$1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne L$1st + + + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp L$outer +.p2align 4 +L$outer: + leaq 24+128(%rsp,%r9,8),%rdx + andq $-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + + movq (%rsi),%rax +.byte 102,72,15,126,195 + + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp L$inner_enter + +.p2align 4 +L$inner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +L$inner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne L$inner + + addq %rax,%r13 + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r9,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb L$outer + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp L$sub +.p2align 4 +L$sub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz L$sub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +L$copy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r14,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz L$copy + + movq 8(%rsp,%r9,8),%rsi + + movq $1,%rax + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mul_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +bn_mul4x_mont_gather5: + +.byte 0x67 + movq %rsp,%rax + +L$mul4x_enter: + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je L$mulx4x_enter + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$mul4x_prologue: + +.byte 0x67 + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$mul4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp L$mul4xsp_done + +.p2align 5 +L$mul4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$mul4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mul4x_page_walk + jmp L$mul4x_page_walk_done + +L$mul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mul4x_page_walk +L$mul4x_page_walk_done: + + negq %r9 + + movq %rax,40(%rsp) + +L$mul4x_body: + + call mul4x_internal + + movq 40(%rsp),%rsi + + movq $1,%rax + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mul4x_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +mul4x_internal: + + shlq $5,%r9 + movd 8(%rax),%xmm5 + leaq L$inc(%rip),%rax + leaq 128(%rdx,%r9,1),%r13 + shrq $5,%r9 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r9,1),%r10 + leaq 128(%rdx),%r12 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67,0x67 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq %r13,16+8(%rsp) + movq %rdi,56+8(%rsp) + + movq (%r8),%r8 + movq (%rsi),%rax + leaq (%rsi,%r9,1),%rsi + negq %r9 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + leaq 64+8(%rsp),%r14 + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + jmp L$1st4x + +.p2align 5 +L$1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz L$1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + jmp L$outer4x + +.p2align 5 +L$outer4x: + leaq 16+128(%r14),%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r14,%r9,1),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + movq %rdi,(%r14) + + leaq (%r14,%r9,1),%r14 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdx,%r13 + jmp L$inner4x + +.p2align 5 +L$inner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + addq (%r14),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz L$inner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq %rbp,%rax + movq -8(%rcx),%rbp + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + movq %rdi,-16(%r14) + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%r14),%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + cmpq 16+8(%rsp),%r12 + jb L$outer4x + xorq %rax,%rax + subq %r13,%rbp + adcq %r15,%r15 + orq %r15,%rdi + subq %rdi,%rax + leaq (%r14,%r9,1),%rbx + movq (%rcx),%r12 + leaq (%rcx),%rbp + movq %r9,%rcx + sarq $3+2,%rcx + movq 56+8(%rsp),%rdi + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp L$sqr4x_sub_entry + + +.globl _bn_power5 +.private_extern _bn_power5 + +.p2align 5 +_bn_power5: + + movq %rsp,%rax + + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je L$powerx5_enter + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$power5_prologue: + + shll $3,%r9d + leal (%r9,%r9,2),%r10d + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$pwr_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp L$pwr_sp_done + +.p2align 5 +L$pwr_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$pwr_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$pwr_page_walk + jmp L$pwr_page_walk_done + +L$pwr_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$pwr_page_walk +L$pwr_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) + +L$power5_body: +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq %rsi,%rdi + movq 40(%rsp),%rax + leaq 32(%rsp),%r8 + + call mul4x_internal + + movq 40(%rsp),%rsi + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$power5_epilogue: + .byte 0xf3,0xc3 + + + +.globl _bn_sqr8x_internal +.private_extern _bn_sqr8x_internal +.private_extern _bn_sqr8x_internal + +.p2align 5 +_bn_sqr8x_internal: +__bn_sqr8x_internal: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 32(%r10),%rbp + leaq (%rsi,%r9,1),%rsi + + movq %r9,%rcx + + + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + movq %r11,-16(%rdi,%rbp,1) + movq %rdx,%r10 + + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + movq %rax,%r12 + movq %rbx,%rax + movq %rdx,%r13 + + leaq (%rbp),%rcx + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + jmp L$sqr4x_1st + +.p2align 5 +L$sqr4x_1st: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq 16(%rsi,%rcx,1),%rbx + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %r10,8(%rdi,%rcx,1) + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 24(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,16(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + leaq 32(%rcx),%rcx + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne L$sqr4x_1st + + mulq %r15 + addq %rax,%r13 + leaq 16(%rbp),%rbp + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + jmp L$sqr4x_outer + +.p2align 5 +L$sqr4x_outer: + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq -24(%rdi,%rbp,1),%r10 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + movq %r10,-24(%rdi,%rbp,1) + movq %rdx,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + addq -16(%rdi,%rbp,1),%r11 + movq %rdx,%r10 + adcq $0,%r10 + movq %r11,-16(%rdi,%rbp,1) + + xorq %r12,%r12 + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq $0,%rdx + addq -8(%rdi,%rbp,1),%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rbp,1) + + leaq (%rbp),%rcx + jmp L$sqr4x_inner + +.p2align 5 +L$sqr4x_inner: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + addq (%rdi,%rcx,1),%r13 + adcq $0,%r12 + +.byte 0x67 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %r11,(%rdi,%rcx,1) + movq %rbx,%rax + movq %rdx,%r13 + adcq $0,%r13 + addq 8(%rdi,%rcx,1),%r12 + leaq 16(%rcx),%rcx + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne L$sqr4x_inner + +.byte 0x67 + mulq %r15 + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + addq $16,%rbp + jnz L$sqr4x_outer + + + movq -32(%rsi),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi),%rbx + movq %rax,%r15 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq %r10,-24(%rdi) + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + movq -8(%rsi),%rbx + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,-16(%rdi) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi) + + mulq %r15 + addq %rax,%r13 + movq -16(%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + mulq %rbx + addq $16,%rbp + xorq %r14,%r14 + subq %r9,%rbp + xorq %r15,%r15 + + addq %r12,%rax + adcq $0,%rdx + movq %rax,8(%rdi) + movq %rdx,16(%rdi) + movq %r15,24(%rdi) + + movq -16(%rsi,%rbp,1),%rax + leaq 48+8(%rsp),%rdi + xorq %r10,%r10 + movq 8(%rdi),%r11 + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + leaq 16(%rbp),%rbp + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + jmp L$sqr4x_shift_n_add + +.p2align 5 +L$sqr4x_shift_n_add: + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi) + adcq %rdx,%r8 + + leaq (%r14,%r10,2),%r12 + movq %r8,-8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq 8(%rsi,%rbp,1),%rax + movq %r12,0(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 16(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + addq $32,%rbp + jnz L$sqr4x_shift_n_add + + leaq (%r14,%r10,2),%r12 +.byte 0x67 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + mulq %rax + negq %r15 + adcq %rax,%rbx + adcq %rdx,%r8 + movq %rbx,-16(%rdi) + movq %r8,-8(%rdi) +.byte 102,72,15,126,213 +__bn_sqr8x_reduction: + xorq %rax,%rax + leaq (%r9,%rbp,1),%rcx + leaq 48+8(%rsp,%r9,2),%rdx + movq %rcx,0+8(%rsp) + leaq 48+8(%rsp,%r9,1),%rdi + movq %rdx,8+8(%rsp) + negq %r9 + jmp L$8x_reduction_loop + +.p2align 5 +L$8x_reduction_loop: + leaq (%rdi,%r9,1),%rdi +.byte 0x66 + movq 0(%rdi),%rbx + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,(%rdx) + leaq 64(%rdi),%rdi + +.byte 0x67 + movq %rbx,%r8 + imulq 32+8(%rsp),%rbx + movq 0(%rbp),%rax + movl $8,%ecx + jmp L$8x_reduce + +.p2align 5 +L$8x_reduce: + mulq %rbx + movq 8(%rbp),%rax + negq %r8 + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rbx,48-8+8(%rsp,%rcx,8) + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq 32+8(%rsp),%rsi + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + imulq %r8,%rsi + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq %rsi,%rbx + addq %rax,%r15 + movq 0(%rbp),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz L$8x_reduce + + leaq 64(%rbp),%rbp + xorq %rax,%rax + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae L$8x_no_tail + +.byte 0x66 + addq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movq 48+56+8(%rsp),%rbx + movl $8,%ecx + movq 0(%rbp),%rax + jmp L$8x_tail + +.p2align 5 +L$8x_tail: + mulq %rbx + addq %rax,%r8 + movq 8(%rbp),%rax + movq %r8,(%rdi) + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + leaq 8(%rdi),%rdi + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq 48-16+8(%rsp,%rcx,8),%rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r15,%r14 + movq 0(%rbp),%rax + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz L$8x_tail + + leaq 64(%rbp),%rbp + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae L$8x_tail_done + + movq 48+56+8(%rsp),%rbx + negq %rsi + movq 0(%rbp),%rax + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movl $8,%ecx + jmp L$8x_tail + +.p2align 5 +L$8x_tail_done: + xorq %rax,%rax + addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + negq %rsi +L$8x_no_tail: + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + movq -8(%rbp),%rcx + xorq %rsi,%rsi + +.byte 102,72,15,126,213 + + movq %r8,0(%rdi) + movq %r9,8(%rdi) +.byte 102,73,15,126,217 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rdi),%rdi + + cmpq %rdx,%rdi + jb L$8x_reduction_loop + .byte 0xf3,0xc3 + + + +.p2align 5 +__bn_post4x_internal: + + movq 0(%rbp),%r12 + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx +.byte 102,72,15,126,207 + negq %rax +.byte 102,72,15,126,206 + sarq $3+2,%rcx + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp L$sqr4x_sub_entry + +.p2align 4 +L$sqr4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +L$sqr4x_sub_entry: + leaq 32(%rbp),%rbp + notq %r12 + notq %r13 + notq %r14 + notq %r15 + andq %rax,%r12 + andq %rax,%r13 + andq %rax,%r14 + andq %rax,%r15 + + negq %r10 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + adcq 16(%rbx),%r14 + adcq 24(%rbx),%r15 + movq %r12,0(%rdi) + leaq 32(%rbx),%rbx + movq %r13,8(%rdi) + sbbq %r10,%r10 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + + incq %rcx + jnz L$sqr4x_sub + + movq %r9,%r10 + negq %r9 + .byte 0xf3,0xc3 + + +.globl _bn_from_montgomery +.private_extern _bn_from_montgomery + +.p2align 5 +_bn_from_montgomery: + + testl $7,%r9d + jz bn_from_mont8x + xorl %eax,%eax + .byte 0xf3,0xc3 + + + + +.p2align 5 +bn_from_mont8x: + +.byte 0x67 + movq %rsp,%rax + + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$from_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$from_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp L$from_sp_done + +.p2align 5 +L$from_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$from_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$from_page_walk + jmp L$from_page_walk_done + +L$from_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$from_page_walk +L$from_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) + +L$from_body: + movq %r9,%r11 + leaq 48(%rsp),%rax + pxor %xmm0,%xmm0 + jmp L$mul_by_1 + +.p2align 5 +L$mul_by_1: + movdqu (%rsi),%xmm1 + movdqu 16(%rsi),%xmm2 + movdqu 32(%rsi),%xmm3 + movdqa %xmm0,(%rax,%r9,1) + movdqu 48(%rsi),%xmm4 + movdqa %xmm0,16(%rax,%r9,1) +.byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 + movdqa %xmm1,(%rax) + movdqa %xmm0,32(%rax,%r9,1) + movdqa %xmm2,16(%rax) + movdqa %xmm0,48(%rax,%r9,1) + movdqa %xmm3,32(%rax) + movdqa %xmm4,48(%rax) + leaq 64(%rax),%rax + subq $64,%r11 + jnz L$mul_by_1 + +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 0x67 + movq %rcx,%rbp +.byte 102,73,15,110,218 + leaq _OPENSSL_ia32cap_P(%rip),%r11 + movl 8(%r11),%r11d + andl $0x80108,%r11d + cmpl $0x80108,%r11d + jne L$from_mont_nox + + leaq (%rax,%r9,1),%rdi + call __bn_sqrx8x_reduction + call __bn_postx4x_internal + + pxor %xmm0,%xmm0 + leaq 48(%rsp),%rax + jmp L$from_mont_zero + +.p2align 5 +L$from_mont_nox: + call __bn_sqr8x_reduction + call __bn_post4x_internal + + pxor %xmm0,%xmm0 + leaq 48(%rsp),%rax + jmp L$from_mont_zero + +.p2align 5 +L$from_mont_zero: + movq 40(%rsp),%rsi + + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + movdqa %xmm0,32(%rax) + movdqa %xmm0,48(%rax) + leaq 64(%rax),%rax + subq $32,%r9 + jnz L$from_mont_zero + + movq $1,%rax + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$from_epilogue: + .byte 0xf3,0xc3 + + + +.p2align 5 +bn_mulx4x_mont_gather5: + + movq %rsp,%rax + +L$mulx4x_enter: + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$mulx4x_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$mulx4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp L$mulx4xsp_done + +L$mulx4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$mulx4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mulx4x_page_walk + jmp L$mulx4x_page_walk_done + +L$mulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$mulx4x_page_walk +L$mulx4x_page_walk_done: + + + + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) + +L$mulx4x_body: + call mulx4x_internal + + movq 40(%rsp),%rsi + + movq $1,%rax + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$mulx4x_epilogue: + .byte 0xf3,0xc3 + + + + +.p2align 5 +mulx4x_internal: + + movq %r9,8(%rsp) + movq %r9,%r10 + negq %r9 + shlq $5,%r9 + negq %r10 + leaq 128(%rdx,%r9,1),%r13 + shrq $5+5,%r9 + movd 8(%rax),%xmm5 + subq $1,%r9 + leaq L$inc(%rip),%rax + movq %r13,16+8(%rsp) + movq %r9,24+8(%rsp) + movq %rdi,56+8(%rsp) + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r10,1),%r10 + leaq 128(%rdx),%rdi + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67 + movdqa %xmm1,%xmm2 +.byte 0x67 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 +.byte 0x67 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + + pand 64(%rdi),%xmm0 + pand 80(%rdi),%xmm1 + pand 96(%rdi),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%rdi),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%rdi),%xmm4 + movdqa -112(%rdi),%xmm5 + movdqa -96(%rdi),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%rdi),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%rdi),%xmm4 + movdqa -48(%rdi),%xmm5 + movdqa -32(%rdi),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%rdi),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%rdi),%xmm4 + movdqa 16(%rdi),%xmm5 + movdqa 32(%rdi),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%rdi),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + leaq 64+32+8(%rsp),%rbx + + movq %rdx,%r9 + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r12 + addq %rax,%r11 + mulxq 16(%rsi),%rax,%r13 + adcq %rax,%r12 + adcq $0,%r13 + mulxq 24(%rsi),%rax,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + xorq %rbp,%rbp + movq %r8,%rdx + + movq %rdi,8+8(%rsp) + + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + jmp L$mulx4x_1st + +.p2align 5 +L$mulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz L$mulx4x_1st + + movq 8(%rsp),%rax + adcq %rbp,%r15 + leaq (%rsi,%rax,1),%rsi + addq %r15,%r14 + movq 8+8(%rsp),%rdi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + jmp L$mulx4x_outer + +.p2align 5 +L$mulx4x_outer: + leaq 16-256(%rbx),%r10 + pxor %xmm4,%xmm4 +.byte 0x67,0x67 + pxor %xmm5,%xmm5 + movdqa -128(%rdi),%xmm0 + movdqa -112(%rdi),%xmm1 + movdqa -96(%rdi),%xmm2 + pand 256(%r10),%xmm0 + movdqa -80(%rdi),%xmm3 + pand 272(%r10),%xmm1 + por %xmm0,%xmm4 + pand 288(%r10),%xmm2 + por %xmm1,%xmm5 + pand 304(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%rdi),%xmm0 + movdqa -48(%rdi),%xmm1 + movdqa -32(%rdi),%xmm2 + pand 320(%r10),%xmm0 + movdqa -16(%rdi),%xmm3 + pand 336(%r10),%xmm1 + por %xmm0,%xmm4 + pand 352(%r10),%xmm2 + por %xmm1,%xmm5 + pand 368(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%rdi),%xmm0 + movdqa 16(%rdi),%xmm1 + movdqa 32(%rdi),%xmm2 + pand 384(%r10),%xmm0 + movdqa 48(%rdi),%xmm3 + pand 400(%r10),%xmm1 + por %xmm0,%xmm4 + pand 416(%r10),%xmm2 + por %xmm1,%xmm5 + pand 432(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%rdi),%xmm0 + movdqa 80(%rdi),%xmm1 + movdqa 96(%rdi),%xmm2 + pand 448(%r10),%xmm0 + movdqa 112(%rdi),%xmm3 + pand 464(%r10),%xmm1 + por %xmm0,%xmm4 + pand 480(%r10),%xmm2 + por %xmm1,%xmm5 + pand 496(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + + movq %rbp,(%rbx) + leaq 32(%rbx,%rax,1),%rbx + mulxq 0(%rsi),%r8,%r11 + xorq %rbp,%rbp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + mulxq 24(%rsi),%rdx,%r14 + adoxq -16(%rbx),%r12 + adcxq %rdx,%r13 + leaq (%rcx,%rax,1),%rcx + leaq 32(%rsi),%rsi + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + adoxq %rbp,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + + movq %r8,%rdx + xorq %rbp,%rbp + movq %rdi,8+8(%rsp) + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r12 + movq %r11,-24(%rbx) + adoxq %rbp,%r15 + movq %r12,-16(%rbx) + leaq 32(%rcx),%rcx + jmp L$mulx4x_inner + +.p2align 5 +L$mulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + movq %r11,-32(%rbx) + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + leaq 32(%rcx),%rcx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + movq %r13,-16(%rbx) + + decq %rdi + jnz L$mulx4x_inner + + movq 0+8(%rsp),%rax + adcq %rbp,%r15 + subq 0(%rbx),%rdi + movq 8+8(%rsp),%rdi + movq 16+8(%rsp),%r10 + adcq %r15,%r14 + leaq (%rsi,%rax,1),%rsi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + + cmpq %r10,%rdi + jb L$mulx4x_outer + + movq -8(%rcx),%r10 + movq %rbp,%r8 + movq (%rcx,%rax,1),%r12 + leaq (%rcx,%rax,1),%rbp + movq %rax,%rcx + leaq (%rbx,%rax,1),%rdi + xorl %eax,%eax + xorq %r15,%r15 + subq %r14,%r10 + adcq %r15,%r15 + orq %r15,%r8 + sarq $3+2,%rcx + subq %r8,%rax + movq 56+8(%rsp),%rdx + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp L$sqrx4x_sub_entry + + + +.p2align 5 +bn_powerx5: + + movq %rsp,%rax + +L$powerx5_enter: + pushq %rbx + + pushq %rbp + + pushq %r12 + + pushq %r13 + + pushq %r14 + + pushq %r15 + +L$powerx5_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb L$pwrx_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp L$pwrx_sp_done + +.p2align 5 +L$pwrx_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +L$pwrx_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$pwrx_page_walk + jmp L$pwrx_page_walk_done + +L$pwrx_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja L$pwrx_page_walk +L$pwrx_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + + + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + movq %r8,32(%rsp) + movq %rax,40(%rsp) + +L$powerx5_body: + + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + + movq %r10,%r9 + movq %rsi,%rdi +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq 40(%rsp),%rax + + call mulx4x_internal + + movq 40(%rsp),%rsi + + movq $1,%rax + + movq -48(%rsi),%r15 + + movq -40(%rsi),%r14 + + movq -32(%rsi),%r13 + + movq -24(%rsi),%r12 + + movq -16(%rsi),%rbp + + movq -8(%rsi),%rbx + + leaq (%rsi),%rsp + +L$powerx5_epilogue: + .byte 0xf3,0xc3 + + + +.globl _bn_sqrx8x_internal +.private_extern _bn_sqrx8x_internal +.private_extern _bn_sqrx8x_internal + +.p2align 5 +_bn_sqrx8x_internal: +__bn_sqrx8x_internal: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 48+8(%rsp),%rdi + leaq (%rsi,%r9,1),%rbp + movq %r9,0+8(%rsp) + movq %rbp,8+8(%rsp) + jmp L$sqr8x_zero_start + +.p2align 5 +.byte 0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 +L$sqrx8x_zero: +.byte 0x3e + movdqa %xmm0,0(%rdi) + movdqa %xmm0,16(%rdi) + movdqa %xmm0,32(%rdi) + movdqa %xmm0,48(%rdi) +L$sqr8x_zero_start: + movdqa %xmm0,64(%rdi) + movdqa %xmm0,80(%rdi) + movdqa %xmm0,96(%rdi) + movdqa %xmm0,112(%rdi) + leaq 128(%rdi),%rdi + subq $64,%r9 + jnz L$sqrx8x_zero + + movq 0(%rsi),%rdx + + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + leaq 48+8(%rsp),%rdi + xorq %rbp,%rbp + jmp L$sqrx8x_outer_loop + +.p2align 5 +L$sqrx8x_outer_loop: + mulxq 8(%rsi),%r8,%rax + adcxq %r9,%r8 + adoxq %rax,%r10 + mulxq 16(%rsi),%r9,%rax + adcxq %r10,%r9 + adoxq %rax,%r11 +.byte 0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00 + adcxq %r11,%r10 + adoxq %rax,%r12 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 + adcxq %r12,%r11 + adoxq %rax,%r13 + mulxq 40(%rsi),%r12,%rax + adcxq %r13,%r12 + adoxq %rax,%r14 + mulxq 48(%rsi),%r13,%rax + adcxq %r14,%r13 + adoxq %r15,%rax + mulxq 56(%rsi),%r14,%r15 + movq 8(%rsi),%rdx + adcxq %rax,%r14 + adoxq %rbp,%r15 + adcq 64(%rdi),%r15 + movq %r8,8(%rdi) + movq %r9,16(%rdi) + sbbq %rcx,%rcx + xorq %rbp,%rbp + + + mulxq 16(%rsi),%r8,%rbx + mulxq 24(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 32(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %rbx,%r11 +.byte 0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00 + adcxq %r13,%r11 + adoxq %r14,%r12 +.byte 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 + movq 16(%rsi),%rdx + adcxq %rax,%r12 + adoxq %rbx,%r13 + adcxq %r15,%r13 + adoxq %rbp,%r14 + adcxq %rbp,%r14 + + movq %r8,24(%rdi) + movq %r9,32(%rdi) + + mulxq 24(%rsi),%r8,%rbx + mulxq 32(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 40(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %r13,%r11 +.byte 0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00 +.byte 0x3e + movq 24(%rsi),%rdx + adcxq %rbx,%r11 + adoxq %rax,%r12 + adcxq %r14,%r12 + movq %r8,40(%rdi) + movq %r9,48(%rdi) + mulxq 32(%rsi),%r8,%rax + adoxq %rbp,%r13 + adcxq %rbp,%r13 + + mulxq 40(%rsi),%r9,%rbx + adcxq %r10,%r8 + adoxq %rax,%r9 + mulxq 48(%rsi),%r10,%rax + adcxq %r11,%r9 + adoxq %r12,%r10 + mulxq 56(%rsi),%r11,%r12 + movq 32(%rsi),%rdx + movq 40(%rsi),%r14 + adcxq %rbx,%r10 + adoxq %rax,%r11 + movq 48(%rsi),%r15 + adcxq %r13,%r11 + adoxq %rbp,%r12 + adcxq %rbp,%r12 + + movq %r8,56(%rdi) + movq %r9,64(%rdi) + + mulxq %r14,%r9,%rax + movq 56(%rsi),%r8 + adcxq %r10,%r9 + mulxq %r15,%r10,%rbx + adoxq %rax,%r10 + adcxq %r11,%r10 + mulxq %r8,%r11,%rax + movq %r14,%rdx + adoxq %rbx,%r11 + adcxq %r12,%r11 + + adcxq %rbp,%rax + + mulxq %r15,%r14,%rbx + mulxq %r8,%r12,%r13 + movq %r15,%rdx + leaq 64(%rsi),%rsi + adcxq %r14,%r11 + adoxq %rbx,%r12 + adcxq %rax,%r12 + adoxq %rbp,%r13 + +.byte 0x67,0x67 + mulxq %r8,%r8,%r14 + adcxq %r8,%r13 + adcxq %rbp,%r14 + + cmpq 8+8(%rsp),%rsi + je L$sqrx8x_outer_break + + negq %rcx + movq $-8,%rcx + movq %rbp,%r15 + movq 64(%rdi),%r8 + adcxq 72(%rdi),%r9 + adcxq 80(%rdi),%r10 + adcxq 88(%rdi),%r11 + adcq 96(%rdi),%r12 + adcq 104(%rdi),%r13 + adcq 112(%rdi),%r14 + adcq 120(%rdi),%r15 + leaq (%rsi),%rbp + leaq 128(%rdi),%rdi + sbbq %rax,%rax + + movq -64(%rsi),%rdx + movq %rax,16+8(%rsp) + movq %rdi,24+8(%rsp) + + + xorl %eax,%eax + jmp L$sqrx8x_loop + +.p2align 5 +L$sqrx8x_loop: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + movq %rbx,(%rdi,%rcx,8) + movl $0,%ebx + adcxq %rax,%r13 + adoxq %r15,%r14 + +.byte 0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00 + movq 8(%rsi,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rbx,%r15 + adcxq %rbx,%r15 + +.byte 0x67 + incq %rcx + jnz L$sqrx8x_loop + + leaq 64(%rbp),%rbp + movq $-8,%rcx + cmpq 8+8(%rsp),%rbp + je L$sqrx8x_break + + subq 16+8(%rsp),%rbx +.byte 0x66 + movq -64(%rsi),%rdx + adcxq 0(%rdi),%r8 + adcxq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi +.byte 0x67 + sbbq %rax,%rax + xorl %ebx,%ebx + movq %rax,16+8(%rsp) + jmp L$sqrx8x_loop + +.p2align 5 +L$sqrx8x_break: + xorq %rbp,%rbp + subq 16+8(%rsp),%rbx + adcxq %rbp,%r8 + movq 24+8(%rsp),%rcx + adcxq %rbp,%r9 + movq 0(%rsi),%rdx + adcq $0,%r10 + movq %r8,0(%rdi) + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + cmpq %rcx,%rdi + je L$sqrx8x_outer_loop + + movq %r9,8(%rdi) + movq 8(%rcx),%r9 + movq %r10,16(%rdi) + movq 16(%rcx),%r10 + movq %r11,24(%rdi) + movq 24(%rcx),%r11 + movq %r12,32(%rdi) + movq 32(%rcx),%r12 + movq %r13,40(%rdi) + movq 40(%rcx),%r13 + movq %r14,48(%rdi) + movq 48(%rcx),%r14 + movq %r15,56(%rdi) + movq 56(%rcx),%r15 + movq %rcx,%rdi + jmp L$sqrx8x_outer_loop + +.p2align 5 +L$sqrx8x_outer_break: + movq %r9,72(%rdi) +.byte 102,72,15,126,217 + movq %r10,80(%rdi) + movq %r11,88(%rdi) + movq %r12,96(%rdi) + movq %r13,104(%rdi) + movq %r14,112(%rdi) + leaq 48+8(%rsp),%rdi + movq (%rsi,%rcx,1),%rdx + + movq 8(%rdi),%r11 + xorq %r10,%r10 + movq 0+8(%rsp),%r9 + adoxq %r11,%r11 + movq 16(%rdi),%r12 + movq 24(%rdi),%r13 + + +.p2align 5 +L$sqrx4x_shift_n_add: + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax +.byte 0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00 +.byte 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 40(%rdi),%r11 + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + movq 16(%rsi,%rcx,1),%rdx + movq 48(%rdi),%r12 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 56(%rdi),%r13 + movq %rax,16(%rdi) + movq %rbx,24(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax + movq 24(%rsi,%rcx,1),%rdx + leaq 32(%rcx),%rcx + movq 64(%rdi),%r10 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 72(%rdi),%r11 + movq %rax,32(%rdi) + movq %rbx,40(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + jrcxz L$sqrx4x_shift_n_add_break +.byte 0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 80(%rdi),%r12 + movq 88(%rdi),%r13 + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi + nop + jmp L$sqrx4x_shift_n_add + +.p2align 5 +L$sqrx4x_shift_n_add_break: + adcxq %r13,%rbx + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi +.byte 102,72,15,126,213 +__bn_sqrx8x_reduction: + xorl %eax,%eax + movq 32+8(%rsp),%rbx + movq 48+8(%rsp),%rdx + leaq -64(%rbp,%r9,1),%rcx + + movq %rcx,0+8(%rsp) + movq %rdi,8+8(%rsp) + + leaq 48+8(%rsp),%rdi + jmp L$sqrx8x_reduction_loop + +.p2align 5 +L$sqrx8x_reduction_loop: + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq %rdx,%r8 + imulq %rbx,%rdx + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,24+8(%rsp) + + leaq 64(%rdi),%rdi + xorq %rsi,%rsi + movq $-8,%rcx + jmp L$sqrx8x_reduce + +.p2align 5 +L$sqrx8x_reduce: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rbx,%rax + adoxq %r9,%r8 + + mulxq 8(%rbp),%rbx,%r9 + adcxq %rbx,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rbx,%r10 + adcxq %rbx,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rbx,%r11 + adcxq %rbx,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 + movq %rdx,%rax + movq %r8,%rdx + adcxq %rbx,%r11 + adoxq %r13,%r12 + + mulxq 32+8(%rsp),%rbx,%rdx + movq %rax,%rdx + movq %rax,64+48+8(%rsp,%rcx,8) + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq %rbx,%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + adcxq %rsi,%r15 + +.byte 0x67,0x67,0x67 + incq %rcx + jnz L$sqrx8x_reduce + + movq %rsi,%rax + cmpq 0+8(%rsp),%rbp + jae L$sqrx8x_no_tail + + movq 48+8(%rsp),%rdx + addq 0(%rdi),%r8 + leaq 64(%rbp),%rbp + movq $-8,%rcx + adcxq 8(%rdi),%r9 + adcxq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp L$sqrx8x_tail + +.p2align 5 +L$sqrx8x_tail: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq 72+48+8(%rsp,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + movq %rbx,(%rdi,%rcx,8) + movq %r8,%rbx + adcxq %rsi,%r15 + + incq %rcx + jnz L$sqrx8x_tail + + cmpq 0+8(%rsp),%rbp + jae L$sqrx8x_tail_done + + subq 16+8(%rsp),%rsi + movq 48+8(%rsp),%rdx + leaq 64(%rbp),%rbp + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + subq $8,%rcx + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp L$sqrx8x_tail + +.p2align 5 +L$sqrx8x_tail_done: + xorq %rax,%rax + addq 24+8(%rsp),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + subq 16+8(%rsp),%rsi +L$sqrx8x_no_tail: + adcq 0(%rdi),%r8 +.byte 102,72,15,126,217 + adcq 8(%rdi),%r9 + movq 56(%rbp),%rsi +.byte 102,72,15,126,213 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + + movq 32+8(%rsp),%rbx + movq 64(%rdi,%rcx,1),%rdx + + movq %r8,0(%rdi) + leaq 64(%rdi),%r8 + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + leaq 64(%rdi,%rcx,1),%rdi + cmpq 8+8(%rsp),%r8 + jb L$sqrx8x_reduction_loop + .byte 0xf3,0xc3 + + +.p2align 5 + +__bn_postx4x_internal: + + movq 0(%rbp),%r12 + movq %rcx,%r10 + movq %rcx,%r9 + negq %rax + sarq $3+2,%rcx + +.byte 102,72,15,126,202 +.byte 102,72,15,126,206 + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp L$sqrx4x_sub_entry + +.p2align 4 +L$sqrx4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +L$sqrx4x_sub_entry: + andnq %rax,%r12,%r12 + leaq 32(%rbp),%rbp + andnq %rax,%r13,%r13 + andnq %rax,%r14,%r14 + andnq %rax,%r15,%r15 + + negq %r8 + adcq 0(%rdi),%r12 + adcq 8(%rdi),%r13 + adcq 16(%rdi),%r14 + adcq 24(%rdi),%r15 + movq %r12,0(%rdx) + leaq 32(%rdi),%rdi + movq %r13,8(%rdx) + sbbq %r8,%r8 + movq %r14,16(%rdx) + movq %r15,24(%rdx) + leaq 32(%rdx),%rdx + + incq %rcx + jnz L$sqrx4x_sub + + negq %r9 + + .byte 0xf3,0xc3 + + +.globl _bn_scatter5 +.private_extern _bn_scatter5 + +.p2align 4 +_bn_scatter5: + + cmpl $0,%esi + jz L$scatter_epilogue + leaq (%rdx,%rcx,8),%rdx +L$scatter: + movq (%rdi),%rax + leaq 8(%rdi),%rdi + movq %rax,(%rdx) + leaq 256(%rdx),%rdx + subl $1,%esi + jnz L$scatter +L$scatter_epilogue: + .byte 0xf3,0xc3 + + + +.globl _bn_gather5 +.private_extern _bn_gather5 + +.p2align 5 +_bn_gather5: + +L$SEH_begin_bn_gather5: + +.byte 0x4c,0x8d,0x14,0x24 + +.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + leaq L$inc(%rip),%rax + andq $-16,%rsp + + movd %ecx,%xmm5 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 128(%rdx),%r11 + leaq 128(%rsp),%rax + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-128(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-112(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-96(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-80(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-48(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-16(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,0(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,16(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,48(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,80(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,96(%rax) + movdqa %xmm4,%xmm2 + movdqa %xmm3,112(%rax) + jmp L$gather + +.p2align 5 +L$gather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r11),%xmm0 + movdqa -112(%r11),%xmm1 + movdqa -96(%r11),%xmm2 + pand -128(%rax),%xmm0 + movdqa -80(%r11),%xmm3 + pand -112(%rax),%xmm1 + por %xmm0,%xmm4 + pand -96(%rax),%xmm2 + por %xmm1,%xmm5 + pand -80(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r11),%xmm0 + movdqa -48(%r11),%xmm1 + movdqa -32(%r11),%xmm2 + pand -64(%rax),%xmm0 + movdqa -16(%r11),%xmm3 + pand -48(%rax),%xmm1 + por %xmm0,%xmm4 + pand -32(%rax),%xmm2 + por %xmm1,%xmm5 + pand -16(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + pand 0(%rax),%xmm0 + movdqa 48(%r11),%xmm3 + pand 16(%rax),%xmm1 + por %xmm0,%xmm4 + pand 32(%rax),%xmm2 + por %xmm1,%xmm5 + pand 48(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r11),%xmm0 + movdqa 80(%r11),%xmm1 + movdqa 96(%r11),%xmm2 + pand 64(%rax),%xmm0 + movdqa 112(%r11),%xmm3 + pand 80(%rax),%xmm1 + por %xmm0,%xmm4 + pand 96(%rax),%xmm2 + por %xmm1,%xmm5 + pand 112(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,(%rdi) + leaq 8(%rdi),%rdi + subl $1,%esi + jnz L$gather + + leaq (%r10),%rsp + + .byte 0xf3,0xc3 +L$SEH_end_bn_gather5: + + +.p2align 6 +L$inc: +.long 0,0, 1,1 +.long 2,2, 2,2 +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +#endif +#endif // defined(__x86_64__) && defined(__APPLE__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hkdf/hkdf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hkdf/hkdf.c new file mode 100644 index 00000000..14f77ce7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hkdf/hkdf.c @@ -0,0 +1,112 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" + + +int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len, const uint8_t *info, size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2 + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prk_len; + + if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt, + salt_len) || + !HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)) { + return 0; + } + + return 1; +} + +int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len) { + // https://tools.ietf.org/html/rfc5869#section-2.2 + + // If salt is not given, HashLength zeros are used. However, HMAC does that + // internally already so we can ignore it. + unsigned len; + if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == NULL) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + return 0; + } + *out_len = len; + assert(*out_len == EVP_MD_size(digest)); + return 1; +} + +int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *prk, size_t prk_len, const uint8_t *info, + size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2.3 + const size_t digest_len = EVP_MD_size(digest); + uint8_t previous[EVP_MAX_MD_SIZE]; + size_t n, done = 0; + unsigned i; + int ret = 0; + HMAC_CTX hmac; + + // Expand key material to desired length. + n = (out_len + digest_len - 1) / digest_len; + if (out_len + digest_len < out_len || n > 255) { + OPENSSL_PUT_ERROR(HKDF, HKDF_R_OUTPUT_TOO_LARGE); + return 0; + } + + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) { + goto out; + } + + for (i = 0; i < n; i++) { + uint8_t ctr = i + 1; + size_t todo; + + if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) || + !HMAC_Update(&hmac, previous, digest_len))) { + goto out; + } + if (!HMAC_Update(&hmac, info, info_len) || + !HMAC_Update(&hmac, &ctr, 1) || + !HMAC_Final(&hmac, previous, NULL)) { + goto out; + } + + todo = digest_len; + if (done + todo > out_len) { + todo = out_len - done; + } + OPENSSL_memcpy(out_key + done, previous, todo); + done += todo; + } + + ret = 1; + +out: + HMAC_CTX_cleanup(&hmac); + if (ret != 1) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + } + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hpke/hpke.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hpke/hpke.c new file mode 100644 index 00000000..a0eec3ae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hpke/hpke.c @@ -0,0 +1,618 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + + +// This file implements RFC 9180. + +#define MAX_SEED_LEN X25519_PRIVATE_KEY_LEN +#define MAX_SHARED_SECRET_LEN SHA256_DIGEST_LENGTH + +struct evp_hpke_kem_st { + uint16_t id; + size_t public_key_len; + size_t private_key_len; + size_t seed_len; + int (*init_key)(EVP_HPKE_KEY *key, const uint8_t *priv_key, + size_t priv_key_len); + int (*generate_key)(EVP_HPKE_KEY *key); + int (*encap_with_seed)(const EVP_HPKE_KEM *kem, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, uint8_t *out_enc, + size_t *out_enc_len, size_t max_enc, + const uint8_t *peer_public_key, + size_t peer_public_key_len, const uint8_t *seed, + size_t seed_len); + int (*decap)(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len); +}; + +struct evp_hpke_kdf_st { + uint16_t id; + // We only support HKDF-based KDFs. + const EVP_MD *(*hkdf_md_func)(void); +}; + +struct evp_hpke_aead_st { + uint16_t id; + const EVP_AEAD *(*aead_func)(void); +}; + + +// Low-level labeled KDF functions. + +static const char kHpkeVersionId[] = "HPKE-v1"; + +static int add_label_string(CBB *cbb, const char *label) { + return CBB_add_bytes(cbb, (const uint8_t *)label, strlen(label)); +} + +static int hpke_labeled_extract(const EVP_MD *hkdf_md, uint8_t *out_key, + size_t *out_len, const uint8_t *salt, + size_t salt_len, const uint8_t *suite_id, + size_t suite_id_len, const char *label, + const uint8_t *ikm, size_t ikm_len) { + // labeledIKM = concat("HPKE-v1", suite_id, label, IKM) + CBB labeled_ikm; + int ok = CBB_init(&labeled_ikm, 0) && + add_label_string(&labeled_ikm, kHpkeVersionId) && + CBB_add_bytes(&labeled_ikm, suite_id, suite_id_len) && + add_label_string(&labeled_ikm, label) && + CBB_add_bytes(&labeled_ikm, ikm, ikm_len) && + HKDF_extract(out_key, out_len, hkdf_md, CBB_data(&labeled_ikm), + CBB_len(&labeled_ikm), salt, salt_len); + CBB_cleanup(&labeled_ikm); + return ok; +} + +static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key, + size_t out_len, const uint8_t *prk, + size_t prk_len, const uint8_t *suite_id, + size_t suite_id_len, const char *label, + const uint8_t *info, size_t info_len) { + // labeledInfo = concat(I2OSP(L, 2), "HPKE-v1", suite_id, label, info) + CBB labeled_info; + int ok = CBB_init(&labeled_info, 0) && + CBB_add_u16(&labeled_info, out_len) && + add_label_string(&labeled_info, kHpkeVersionId) && + CBB_add_bytes(&labeled_info, suite_id, suite_id_len) && + add_label_string(&labeled_info, label) && + CBB_add_bytes(&labeled_info, info, info_len) && + HKDF_expand(out_key, out_len, hkdf_md, prk, prk_len, + CBB_data(&labeled_info), CBB_len(&labeled_info)); + CBB_cleanup(&labeled_info); + return ok; +} + + +// KEM implementations. + +// dhkem_extract_and_expand implements the ExtractAndExpand operation in the +// DHKEM construction. See section 4.1 of RFC 9180. +static int dhkem_extract_and_expand(uint16_t kem_id, const EVP_MD *hkdf_md, + uint8_t *out_key, size_t out_len, + const uint8_t *dh, size_t dh_len, + const uint8_t *kem_context, + size_t kem_context_len) { + // concat("KEM", I2OSP(kem_id, 2)) + uint8_t suite_id[5] = {'K', 'E', 'M', kem_id >> 8, kem_id & 0xff}; + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prk_len; + return hpke_labeled_extract(hkdf_md, prk, &prk_len, NULL, 0, suite_id, + sizeof(suite_id), "eae_prk", dh, dh_len) && + hpke_labeled_expand(hkdf_md, out_key, out_len, prk, prk_len, suite_id, + sizeof(suite_id), "shared_secret", kem_context, + kem_context_len); +} + +static int x25519_init_key(EVP_HPKE_KEY *key, const uint8_t *priv_key, + size_t priv_key_len) { + if (priv_key_len != X25519_PRIVATE_KEY_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + OPENSSL_memcpy(key->private_key, priv_key, priv_key_len); + X25519_public_from_private(key->public_key, priv_key); + return 1; +} + +static int x25519_generate_key(EVP_HPKE_KEY *key) { + X25519_keypair(key->public_key, key->private_key); + return 1; +} + +static int x25519_encap_with_seed( + const EVP_HPKE_KEM *kem, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, uint8_t *out_enc, size_t *out_enc_len, + size_t max_enc, const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *seed, size_t seed_len) { + if (max_enc < X25519_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + if (seed_len != X25519_PRIVATE_KEY_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + X25519_public_from_private(out_enc, seed); + + uint8_t dh[X25519_SHARED_KEY_LEN]; + if (peer_public_key_len != X25519_PUBLIC_VALUE_LEN || + !X25519(dh, seed, peer_public_key)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY); + return 0; + } + + uint8_t kem_context[2 * X25519_PUBLIC_VALUE_LEN]; + OPENSSL_memcpy(kem_context, out_enc, X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, peer_public_key, + X25519_PUBLIC_VALUE_LEN); + if (!dhkem_extract_and_expand(kem->id, EVP_sha256(), out_shared_secret, + SHA256_DIGEST_LENGTH, dh, sizeof(dh), + kem_context, sizeof(kem_context))) { + return 0; + } + + *out_enc_len = X25519_PUBLIC_VALUE_LEN; + *out_shared_secret_len = SHA256_DIGEST_LENGTH; + return 1; +} + +static int x25519_decap(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len) { + uint8_t dh[X25519_SHARED_KEY_LEN]; + if (enc_len != X25519_PUBLIC_VALUE_LEN || + !X25519(dh, key->private_key, enc)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY); + return 0; + } + + uint8_t kem_context[2 * X25519_PUBLIC_VALUE_LEN]; + OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, key->public_key, + X25519_PUBLIC_VALUE_LEN); + if (!dhkem_extract_and_expand(key->kem->id, EVP_sha256(), out_shared_secret, + SHA256_DIGEST_LENGTH, dh, sizeof(dh), + kem_context, sizeof(kem_context))) { + return 0; + } + + *out_shared_secret_len = SHA256_DIGEST_LENGTH; + return 1; +} + +const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void) { + static const EVP_HPKE_KEM kKEM = { + /*id=*/EVP_HPKE_DHKEM_X25519_HKDF_SHA256, + /*public_key_len=*/X25519_PUBLIC_VALUE_LEN, + /*private_key_len=*/X25519_PRIVATE_KEY_LEN, + /*seed_len=*/X25519_PRIVATE_KEY_LEN, + x25519_init_key, + x25519_generate_key, + x25519_encap_with_seed, + x25519_decap, + }; + return &kKEM; +} + +uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem) { return kem->id; } + +void EVP_HPKE_KEY_zero(EVP_HPKE_KEY *key) { + OPENSSL_memset(key, 0, sizeof(EVP_HPKE_KEY)); +} + +void EVP_HPKE_KEY_cleanup(EVP_HPKE_KEY *key) { + // Nothing to clean up for now, but we may introduce a cleanup process in the + // future. +} + +EVP_HPKE_KEY *EVP_HPKE_KEY_new(void) { + EVP_HPKE_KEY *key = OPENSSL_malloc(sizeof(EVP_HPKE_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + EVP_HPKE_KEY_zero(key); + return key; +} + +void EVP_HPKE_KEY_free(EVP_HPKE_KEY *key) { + if (key != NULL) { + EVP_HPKE_KEY_cleanup(key); + OPENSSL_free(key); + } +} + +int EVP_HPKE_KEY_copy(EVP_HPKE_KEY *dst, const EVP_HPKE_KEY *src) { + // For now, |EVP_HPKE_KEY| is trivially copyable. + OPENSSL_memcpy(dst, src, sizeof(EVP_HPKE_KEY)); + return 1; +} + +int EVP_HPKE_KEY_init(EVP_HPKE_KEY *key, const EVP_HPKE_KEM *kem, + const uint8_t *priv_key, size_t priv_key_len) { + EVP_HPKE_KEY_zero(key); + key->kem = kem; + if (!kem->init_key(key, priv_key, priv_key_len)) { + key->kem = NULL; + return 0; + } + return 1; +} + +int EVP_HPKE_KEY_generate(EVP_HPKE_KEY *key, const EVP_HPKE_KEM *kem) { + EVP_HPKE_KEY_zero(key); + key->kem = kem; + if (!kem->generate_key(key)) { + key->kem = NULL; + return 0; + } + return 1; +} + +const EVP_HPKE_KEM *EVP_HPKE_KEY_kem(const EVP_HPKE_KEY *key) { + return key->kem; +} + +int EVP_HPKE_KEY_public_key(const EVP_HPKE_KEY *key, uint8_t *out, + size_t *out_len, size_t max_out) { + if (max_out < key->kem->public_key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + OPENSSL_memcpy(out, key->public_key, key->kem->public_key_len); + *out_len = key->kem->public_key_len; + return 1; +} + +int EVP_HPKE_KEY_private_key(const EVP_HPKE_KEY *key, uint8_t *out, + size_t *out_len, size_t max_out) { + if (max_out < key->kem->private_key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + OPENSSL_memcpy(out, key->private_key, key->kem->private_key_len); + *out_len = key->kem->private_key_len; + return 1; +} + + +// Supported KDFs and AEADs. + +const EVP_HPKE_KDF *EVP_hpke_hkdf_sha256(void) { + static const EVP_HPKE_KDF kKDF = {EVP_HPKE_HKDF_SHA256, &EVP_sha256}; + return &kKDF; +} + +uint16_t EVP_HPKE_KDF_id(const EVP_HPKE_KDF *kdf) { return kdf->id; } + +const EVP_HPKE_AEAD *EVP_hpke_aes_128_gcm(void) { + static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_AES_128_GCM, + &EVP_aead_aes_128_gcm}; + return &kAEAD; +} + +const EVP_HPKE_AEAD *EVP_hpke_aes_256_gcm(void) { + static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_AES_256_GCM, + &EVP_aead_aes_256_gcm}; + return &kAEAD; +} + +const EVP_HPKE_AEAD *EVP_hpke_chacha20_poly1305(void) { + static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_CHACHA20_POLY1305, + &EVP_aead_chacha20_poly1305}; + return &kAEAD; +} + +uint16_t EVP_HPKE_AEAD_id(const EVP_HPKE_AEAD *aead) { return aead->id; } + +const EVP_AEAD *EVP_HPKE_AEAD_aead(const EVP_HPKE_AEAD *aead) { + return aead->aead_func(); +} + + +// HPKE implementation. + +// This is strlen("HPKE") + 3 * sizeof(uint16_t). +#define HPKE_SUITE_ID_LEN 10 + +// The suite_id for non-KEM pieces of HPKE is defined as concat("HPKE", +// I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)). +static int hpke_build_suite_id(const EVP_HPKE_CTX *ctx, + uint8_t out[HPKE_SUITE_ID_LEN]) { + CBB cbb; + int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) && + add_label_string(&cbb, "HPKE") && + CBB_add_u16(&cbb, EVP_HPKE_DHKEM_X25519_HKDF_SHA256) && + CBB_add_u16(&cbb, ctx->kdf->id) && + CBB_add_u16(&cbb, ctx->aead->id); + CBB_cleanup(&cbb); + return ret; +} + +#define HPKE_MODE_BASE 0 + +static int hpke_key_schedule(EVP_HPKE_CTX *ctx, const uint8_t *shared_secret, + size_t shared_secret_len, const uint8_t *info, + size_t info_len) { + uint8_t suite_id[HPKE_SUITE_ID_LEN]; + if (!hpke_build_suite_id(ctx, suite_id)) { + return 0; + } + + // psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id) + // TODO(davidben): Precompute this value and store it with the EVP_HPKE_KDF. + const EVP_MD *hkdf_md = ctx->kdf->hkdf_md_func(); + uint8_t psk_id_hash[EVP_MAX_MD_SIZE]; + size_t psk_id_hash_len; + if (!hpke_labeled_extract(hkdf_md, psk_id_hash, &psk_id_hash_len, NULL, 0, + suite_id, sizeof(suite_id), "psk_id_hash", NULL, + 0)) { + return 0; + } + + // info_hash = LabeledExtract("", "info_hash", info) + uint8_t info_hash[EVP_MAX_MD_SIZE]; + size_t info_hash_len; + if (!hpke_labeled_extract(hkdf_md, info_hash, &info_hash_len, NULL, 0, + suite_id, sizeof(suite_id), "info_hash", info, + info_len)) { + return 0; + } + + // key_schedule_context = concat(mode, psk_id_hash, info_hash) + uint8_t context[sizeof(uint8_t) + 2 * EVP_MAX_MD_SIZE]; + size_t context_len; + CBB context_cbb; + if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) || + !CBB_add_u8(&context_cbb, HPKE_MODE_BASE) || + !CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) || + !CBB_add_bytes(&context_cbb, info_hash, info_hash_len) || + !CBB_finish(&context_cbb, NULL, &context_len)) { + return 0; + } + + // secret = LabeledExtract(shared_secret, "secret", psk) + uint8_t secret[EVP_MAX_MD_SIZE]; + size_t secret_len; + if (!hpke_labeled_extract(hkdf_md, secret, &secret_len, shared_secret, + shared_secret_len, suite_id, sizeof(suite_id), + "secret", NULL, 0)) { + return 0; + } + + // key = LabeledExpand(secret, "key", key_schedule_context, Nk) + const EVP_AEAD *aead = EVP_HPKE_AEAD_aead(ctx->aead); + uint8_t key[EVP_AEAD_MAX_KEY_LENGTH]; + const size_t kKeyLen = EVP_AEAD_key_length(aead); + if (!hpke_labeled_expand(hkdf_md, key, kKeyLen, secret, secret_len, suite_id, + sizeof(suite_id), "key", context, context_len) || + !EVP_AEAD_CTX_init(&ctx->aead_ctx, aead, key, kKeyLen, + EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) { + return 0; + } + + // base_nonce = LabeledExpand(secret, "base_nonce", key_schedule_context, Nn) + if (!hpke_labeled_expand(hkdf_md, ctx->base_nonce, + EVP_AEAD_nonce_length(aead), secret, secret_len, + suite_id, sizeof(suite_id), "base_nonce", context, + context_len)) { + return 0; + } + + // exporter_secret = LabeledExpand(secret, "exp", key_schedule_context, Nh) + if (!hpke_labeled_expand(hkdf_md, ctx->exporter_secret, EVP_MD_size(hkdf_md), + secret, secret_len, suite_id, sizeof(suite_id), + "exp", context, context_len)) { + return 0; + } + + return 1; +} + +void EVP_HPKE_CTX_zero(EVP_HPKE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_HPKE_CTX)); + EVP_AEAD_CTX_zero(&ctx->aead_ctx); +} + +void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) { + EVP_AEAD_CTX_cleanup(&ctx->aead_ctx); +} + +EVP_HPKE_CTX *EVP_HPKE_CTX_new(void) { + EVP_HPKE_CTX *ctx = OPENSSL_malloc(sizeof(EVP_HPKE_CTX)); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + EVP_HPKE_CTX_zero(ctx); + return ctx; +} + +void EVP_HPKE_CTX_free(EVP_HPKE_CTX *ctx) { + if (ctx != NULL) { + EVP_HPKE_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +int EVP_HPKE_CTX_setup_sender(EVP_HPKE_CTX *ctx, uint8_t *out_enc, + size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf, + const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, + size_t peer_public_key_len, const uint8_t *info, + size_t info_len) { + uint8_t seed[MAX_SEED_LEN]; + RAND_bytes(seed, kem->seed_len); + return EVP_HPKE_CTX_setup_sender_with_seed_for_testing( + ctx, out_enc, out_enc_len, max_enc, kem, kdf, aead, peer_public_key, + peer_public_key_len, info, info_len, seed, kem->seed_len); +} + +int EVP_HPKE_CTX_setup_sender_with_seed_for_testing( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len, const uint8_t *seed, + size_t seed_len) { + EVP_HPKE_CTX_zero(ctx); + ctx->is_sender = 1; + ctx->kdf = kdf; + ctx->aead = aead; + uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; + size_t shared_secret_len; + if (!kem->encap_with_seed(kem, shared_secret, &shared_secret_len, out_enc, + out_enc_len, max_enc, peer_public_key, + peer_public_key_len, seed, seed_len) || + !hpke_key_schedule(ctx, shared_secret, shared_secret_len, info, + info_len)) { + EVP_HPKE_CTX_cleanup(ctx); + return 0; + } + return 1; +} + +int EVP_HPKE_CTX_setup_recipient(EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key, + const EVP_HPKE_KDF *kdf, + const EVP_HPKE_AEAD *aead, const uint8_t *enc, + size_t enc_len, const uint8_t *info, + size_t info_len) { + EVP_HPKE_CTX_zero(ctx); + ctx->is_sender = 0; + ctx->kdf = kdf; + ctx->aead = aead; + uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; + size_t shared_secret_len; + if (!key->kem->decap(key, shared_secret, &shared_secret_len, enc, enc_len) || + !hpke_key_schedule(ctx, shared_secret, sizeof(shared_secret), info, + info_len)) { + EVP_HPKE_CTX_cleanup(ctx); + return 0; + } + return 1; +} + +static void hpke_nonce(const EVP_HPKE_CTX *ctx, uint8_t *out_nonce, + size_t nonce_len) { + assert(nonce_len >= 8); + + // Write padded big-endian bytes of |ctx->seq| to |out_nonce|. + OPENSSL_memset(out_nonce, 0, nonce_len); + uint64_t seq_copy = ctx->seq; + for (size_t i = 0; i < 8; i++) { + out_nonce[nonce_len - i - 1] = seq_copy & 0xff; + seq_copy >>= 8; + } + + // XOR the encoded sequence with the |ctx->base_nonce|. + for (size_t i = 0; i < nonce_len; i++) { + out_nonce[i] ^= ctx->base_nonce[i]; + } +} + +int EVP_HPKE_CTX_open(EVP_HPKE_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (ctx->is_sender) { + OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->seq == UINT64_MAX) { + OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + return 0; + } + + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + const size_t nonce_len = EVP_AEAD_nonce_length(ctx->aead_ctx.aead); + hpke_nonce(ctx, nonce, nonce_len); + + if (!EVP_AEAD_CTX_open(&ctx->aead_ctx, out, out_len, max_out_len, nonce, + nonce_len, in, in_len, ad, ad_len)) { + return 0; + } + ctx->seq++; + return 1; +} + +int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (!ctx->is_sender) { + OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->seq == UINT64_MAX) { + OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + return 0; + } + + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + const size_t nonce_len = EVP_AEAD_nonce_length(ctx->aead_ctx.aead); + hpke_nonce(ctx, nonce, nonce_len); + + if (!EVP_AEAD_CTX_seal(&ctx->aead_ctx, out, out_len, max_out_len, nonce, + nonce_len, in, in_len, ad, ad_len)) { + return 0; + } + ctx->seq++; + return 1; +} + +int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *ctx, uint8_t *out, + size_t secret_len, const uint8_t *context, + size_t context_len) { + uint8_t suite_id[HPKE_SUITE_ID_LEN]; + if (!hpke_build_suite_id(ctx, suite_id)) { + return 0; + } + const EVP_MD *hkdf_md = ctx->kdf->hkdf_md_func(); + if (!hpke_labeled_expand(hkdf_md, out, secret_len, ctx->exporter_secret, + EVP_MD_size(hkdf_md), suite_id, sizeof(suite_id), + "sec", context, context_len)) { + return 0; + } + return 1; +} + +size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *ctx) { + assert(ctx->is_sender); + return EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(&ctx->aead_ctx)); +} + +const EVP_HPKE_AEAD *EVP_HPKE_CTX_aead(const EVP_HPKE_CTX *ctx) { + return ctx->aead; +} + +const EVP_HPKE_KDF *EVP_HPKE_CTX_kdf(const EVP_HPKE_CTX *ctx) { + return ctx->kdf; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S new file mode 100644 index 00000000..f6538fe4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S @@ -0,0 +1,8500 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__x86_64__) && defined(__linux__) +// Copyright (c) 2017, the HRSS authors. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && defined(__linux__) + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +// This is the polynomial multiplication function from [HRSS], provided by kind +// permission of the authors. +// +// HRSS: https://eprint.iacr.org/2017/1005 + +# This file was generated by poly_rq_mul.py +.text +.align 32 +const3: +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +.word 3 +const9: +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +.word 9 +const0: +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +const729: +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +.word 729 +const3_inv: +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +.word 43691 +const5_inv: +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +.word 52429 +shuf48_16: +.byte 10 +.byte 11 +.byte 12 +.byte 13 +.byte 14 +.byte 15 +.byte 0 +.byte 1 +.byte 2 +.byte 3 +.byte 4 +.byte 5 +.byte 6 +.byte 7 +.byte 8 +.byte 9 +.byte 10 +.byte 11 +.byte 12 +.byte 13 +.byte 14 +.byte 15 +.byte 0 +.byte 1 +.byte 2 +.byte 3 +.byte 4 +.byte 5 +.byte 6 +.byte 7 +.byte 8 +.byte 9 +shufmin1_mask3: +.byte 2 +.byte 3 +.byte 4 +.byte 5 +.byte 6 +.byte 7 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +.byte 255 +mask32_to_16: +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +.word 0xffff +.word 0x0 +mask5_3_5_3: +.word 0 +.word 0 +.word 0 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 0 +.word 0 +.word 0 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +mask3_5_3_5: +.word 65535 +.word 65535 +.word 65535 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 65535 +.word 65535 +.word 65535 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +mask3_5_4_3_1: +.word 65535 +.word 65535 +.word 65535 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 65535 +.word 65535 +.word 65535 +.word 0 +mask_keephigh: +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 0 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +.word 65535 +mask_mod8192: +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.word 8191 +.text +.global poly_Rq_mul +.hidden poly_Rq_mul +.type poly_Rq_mul, @function +.att_syntax prefix +poly_Rq_mul: +.cfi_startproc +push %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset rbp, -16 +movq %rsp, %rbp +.cfi_def_cfa_register rbp +push %r12 +.cfi_offset r12, -24 +# This function originally used a significant amount of stack space. As an +# alternative, the needed scratch space is now passed in as the 4th argument. +# The amount of scratch space used must thus be kept in sync with +# POLY_MUL_RQ_SCRATCH_SPACE in internal.h. +# +# Setting RSP to point into the given scratch space upsets the ABI tests +# therefore all references to RSP are switched to R8. +mov %rcx, %r8 +addq $6144+12288+512+9408+32, %r8 +mov %r8, %rax +subq $6144, %r8 +mov %r8, %r11 +subq $12288, %r8 +mov %r8, %r12 +subq $512, %r8 +vmovdqa const3(%rip), %ymm3 +vmovdqu 0(%rsi), %ymm0 +vmovdqu 88(%rsi), %ymm1 +vmovdqu 176(%rsi), %ymm2 +vmovdqu 264(%rsi), %ymm12 +vmovdqu 1056(%rsi), %ymm4 +vmovdqu 1144(%rsi), %ymm5 +vmovdqu 1232(%rsi), %ymm6 +vmovdqu 1320(%rsi), %ymm7 +vmovdqu 352(%rsi), %ymm8 +vmovdqu 440(%rsi), %ymm9 +vmovdqu 528(%rsi), %ymm10 +vmovdqu 616(%rsi), %ymm11 +vmovdqa %ymm0, 0(%rax) +vmovdqa %ymm1, 96(%rax) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 192(%rax) +vmovdqa %ymm2, 288(%rax) +vmovdqa %ymm12, 384(%rax) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 480(%rax) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 576(%rax) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 672(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 768(%rax) +vmovdqa %ymm4, 5184(%rax) +vmovdqa %ymm5, 5280(%rax) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5376(%rax) +vmovdqa %ymm6, 5472(%rax) +vmovdqa %ymm7, 5568(%rax) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5664(%rax) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5760(%rax) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5856(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 5952(%rax) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 704(%rsi), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 792(%rsi), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 880(%rsi), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 968(%rsi), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 864(%rax) +vmovdqa %ymm9, 960(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1056(%rax) +vmovdqa %ymm10, 1152(%rax) +vmovdqa %ymm11, 1248(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1344(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1440(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1536(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1632(%rax) +vmovdqa %ymm12, 1728(%rax) +vmovdqa %ymm13, 1824(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1920(%rax) +vmovdqa %ymm14, 2016(%rax) +vmovdqa %ymm15, 2112(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2208(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2304(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2400(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2496(%rax) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2592(%rax) +vmovdqa %ymm9, 2688(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2784(%rax) +vmovdqa %ymm10, 2880(%rax) +vmovdqa %ymm11, 2976(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3072(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3168(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3264(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3360(%rax) +vmovdqa %ymm12, 3456(%rax) +vmovdqa %ymm13, 3552(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3648(%rax) +vmovdqa %ymm14, 3744(%rax) +vmovdqa %ymm15, 3840(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 3936(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4032(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4128(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4224(%rax) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4320(%rax) +vmovdqa %ymm13, 4416(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4512(%rax) +vmovdqa %ymm14, 4608(%rax) +vmovdqa %ymm15, 4704(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4800(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4896(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4992(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5088(%rax) +vmovdqu 32(%rsi), %ymm0 +vmovdqu 120(%rsi), %ymm1 +vmovdqu 208(%rsi), %ymm2 +vmovdqu 296(%rsi), %ymm12 +vmovdqu 1088(%rsi), %ymm4 +vmovdqu 1176(%rsi), %ymm5 +vmovdqu 1264(%rsi), %ymm6 +vmovdqu 1352(%rsi), %ymm7 +vmovdqu 384(%rsi), %ymm8 +vmovdqu 472(%rsi), %ymm9 +vmovdqu 560(%rsi), %ymm10 +vmovdqu 648(%rsi), %ymm11 +vmovdqa %ymm0, 32(%rax) +vmovdqa %ymm1, 128(%rax) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 224(%rax) +vmovdqa %ymm2, 320(%rax) +vmovdqa %ymm12, 416(%rax) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 512(%rax) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 608(%rax) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 704(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 800(%rax) +vmovdqa %ymm4, 5216(%rax) +vmovdqa %ymm5, 5312(%rax) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5408(%rax) +vmovdqa %ymm6, 5504(%rax) +vmovdqa %ymm7, 5600(%rax) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5696(%rax) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5792(%rax) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5888(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 5984(%rax) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 736(%rsi), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 824(%rsi), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 912(%rsi), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 1000(%rsi), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 896(%rax) +vmovdqa %ymm9, 992(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1088(%rax) +vmovdqa %ymm10, 1184(%rax) +vmovdqa %ymm11, 1280(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1376(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1472(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1568(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1664(%rax) +vmovdqa %ymm12, 1760(%rax) +vmovdqa %ymm13, 1856(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1952(%rax) +vmovdqa %ymm14, 2048(%rax) +vmovdqa %ymm15, 2144(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2240(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2336(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2432(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2528(%rax) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2624(%rax) +vmovdqa %ymm9, 2720(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2816(%rax) +vmovdqa %ymm10, 2912(%rax) +vmovdqa %ymm11, 3008(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3104(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3200(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3296(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3392(%rax) +vmovdqa %ymm12, 3488(%rax) +vmovdqa %ymm13, 3584(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3680(%rax) +vmovdqa %ymm14, 3776(%rax) +vmovdqa %ymm15, 3872(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 3968(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4064(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4160(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4256(%rax) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4352(%rax) +vmovdqa %ymm13, 4448(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4544(%rax) +vmovdqa %ymm14, 4640(%rax) +vmovdqa %ymm15, 4736(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4832(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4928(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 5024(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5120(%rax) +vmovdqu 64(%rsi), %ymm0 +vmovdqu 152(%rsi), %ymm1 +vmovdqu 240(%rsi), %ymm2 +vmovdqu 328(%rsi), %ymm12 +vmovdqu 1120(%rsi), %ymm4 +vmovdqu 1208(%rsi), %ymm5 +vmovdqu 1296(%rsi), %ymm6 + +# Only 18 bytes more can be read, but vmovdqu reads 32. +# Copy 18 bytes to the red zone and zero pad to 32 bytes. +xor %r9, %r9 +movq %r9, -16(%rsp) +movq %r9, -8(%rsp) +movq 1384(%rsi), %r9 +movq %r9, -32(%rsp) +movq 1384+8(%rsi), %r9 +movq %r9, -24(%rsp) +movw 1384+16(%rsi), %r9w +movw %r9w, -16(%rsp) +vmovdqu -32(%rsp), %ymm7 + +vmovdqu 416(%rsi), %ymm8 +vmovdqu 504(%rsi), %ymm9 +vmovdqu 592(%rsi), %ymm10 +vmovdqu 680(%rsi), %ymm11 +vmovdqa %ymm0, 64(%rax) +vmovdqa %ymm1, 160(%rax) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 256(%rax) +vmovdqa %ymm2, 352(%rax) +vmovdqa %ymm12, 448(%rax) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 544(%rax) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 640(%rax) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 736(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 832(%rax) +vmovdqa %ymm4, 5248(%rax) +vmovdqa %ymm5, 5344(%rax) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5440(%rax) +vmovdqa %ymm6, 5536(%rax) +vmovdqa %ymm7, 5632(%rax) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5728(%rax) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5824(%rax) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5920(%rax) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 6016(%rax) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 768(%rsi), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 856(%rsi), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 944(%rsi), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 1032(%rsi), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 928(%rax) +vmovdqa %ymm9, 1024(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1120(%rax) +vmovdqa %ymm10, 1216(%rax) +vmovdqa %ymm11, 1312(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1408(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1504(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1600(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1696(%rax) +vmovdqa %ymm12, 1792(%rax) +vmovdqa %ymm13, 1888(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1984(%rax) +vmovdqa %ymm14, 2080(%rax) +vmovdqa %ymm15, 2176(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2272(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2368(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2464(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2560(%rax) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2656(%rax) +vmovdqa %ymm9, 2752(%rax) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2848(%rax) +vmovdqa %ymm10, 2944(%rax) +vmovdqa %ymm11, 3040(%rax) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3136(%rax) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3232(%rax) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3328(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3424(%rax) +vmovdqa %ymm12, 3520(%rax) +vmovdqa %ymm13, 3616(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3712(%rax) +vmovdqa %ymm14, 3808(%rax) +vmovdqa %ymm15, 3904(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4000(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4096(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4192(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4288(%rax) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4384(%rax) +vmovdqa %ymm13, 4480(%rax) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4576(%rax) +vmovdqa %ymm14, 4672(%rax) +vmovdqa %ymm15, 4768(%rax) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4864(%rax) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4960(%rax) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 5056(%rax) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5152(%rax) +vmovdqu 0(%rdx), %ymm0 +vmovdqu 88(%rdx), %ymm1 +vmovdqu 176(%rdx), %ymm2 +vmovdqu 264(%rdx), %ymm12 +vmovdqu 1056(%rdx), %ymm4 +vmovdqu 1144(%rdx), %ymm5 +vmovdqu 1232(%rdx), %ymm6 +vmovdqu 1320(%rdx), %ymm7 +vmovdqu 352(%rdx), %ymm8 +vmovdqu 440(%rdx), %ymm9 +vmovdqu 528(%rdx), %ymm10 +vmovdqu 616(%rdx), %ymm11 +vmovdqa %ymm0, 0(%r11) +vmovdqa %ymm1, 96(%r11) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 192(%r11) +vmovdqa %ymm2, 288(%r11) +vmovdqa %ymm12, 384(%r11) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 480(%r11) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 576(%r11) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 672(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 768(%r11) +vmovdqa %ymm4, 5184(%r11) +vmovdqa %ymm5, 5280(%r11) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5376(%r11) +vmovdqa %ymm6, 5472(%r11) +vmovdqa %ymm7, 5568(%r11) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5664(%r11) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5760(%r11) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5856(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 5952(%r11) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 704(%rdx), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 792(%rdx), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 880(%rdx), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 968(%rdx), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 864(%r11) +vmovdqa %ymm9, 960(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1056(%r11) +vmovdqa %ymm10, 1152(%r11) +vmovdqa %ymm11, 1248(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1344(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1440(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1536(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1632(%r11) +vmovdqa %ymm12, 1728(%r11) +vmovdqa %ymm13, 1824(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1920(%r11) +vmovdqa %ymm14, 2016(%r11) +vmovdqa %ymm15, 2112(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2208(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2304(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2400(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2496(%r11) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2592(%r11) +vmovdqa %ymm9, 2688(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2784(%r11) +vmovdqa %ymm10, 2880(%r11) +vmovdqa %ymm11, 2976(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3072(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3168(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3264(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3360(%r11) +vmovdqa %ymm12, 3456(%r11) +vmovdqa %ymm13, 3552(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3648(%r11) +vmovdqa %ymm14, 3744(%r11) +vmovdqa %ymm15, 3840(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 3936(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4032(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4128(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4224(%r11) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4320(%r11) +vmovdqa %ymm13, 4416(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4512(%r11) +vmovdqa %ymm14, 4608(%r11) +vmovdqa %ymm15, 4704(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4800(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4896(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4992(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5088(%r11) +vmovdqu 32(%rdx), %ymm0 +vmovdqu 120(%rdx), %ymm1 +vmovdqu 208(%rdx), %ymm2 +vmovdqu 296(%rdx), %ymm12 +vmovdqu 1088(%rdx), %ymm4 +vmovdqu 1176(%rdx), %ymm5 +vmovdqu 1264(%rdx), %ymm6 +vmovdqu 1352(%rdx), %ymm7 +vmovdqu 384(%rdx), %ymm8 +vmovdqu 472(%rdx), %ymm9 +vmovdqu 560(%rdx), %ymm10 +vmovdqu 648(%rdx), %ymm11 +vmovdqa %ymm0, 32(%r11) +vmovdqa %ymm1, 128(%r11) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 224(%r11) +vmovdqa %ymm2, 320(%r11) +vmovdqa %ymm12, 416(%r11) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 512(%r11) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 608(%r11) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 704(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 800(%r11) +vmovdqa %ymm4, 5216(%r11) +vmovdqa %ymm5, 5312(%r11) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5408(%r11) +vmovdqa %ymm6, 5504(%r11) +vmovdqa %ymm7, 5600(%r11) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5696(%r11) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5792(%r11) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5888(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 5984(%r11) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 736(%rdx), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 824(%rdx), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 912(%rdx), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 1000(%rdx), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 896(%r11) +vmovdqa %ymm9, 992(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1088(%r11) +vmovdqa %ymm10, 1184(%r11) +vmovdqa %ymm11, 1280(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1376(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1472(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1568(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1664(%r11) +vmovdqa %ymm12, 1760(%r11) +vmovdqa %ymm13, 1856(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1952(%r11) +vmovdqa %ymm14, 2048(%r11) +vmovdqa %ymm15, 2144(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2240(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2336(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2432(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2528(%r11) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2624(%r11) +vmovdqa %ymm9, 2720(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2816(%r11) +vmovdqa %ymm10, 2912(%r11) +vmovdqa %ymm11, 3008(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3104(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3200(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3296(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3392(%r11) +vmovdqa %ymm12, 3488(%r11) +vmovdqa %ymm13, 3584(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3680(%r11) +vmovdqa %ymm14, 3776(%r11) +vmovdqa %ymm15, 3872(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 3968(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4064(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4160(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4256(%r11) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4352(%r11) +vmovdqa %ymm13, 4448(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4544(%r11) +vmovdqa %ymm14, 4640(%r11) +vmovdqa %ymm15, 4736(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4832(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4928(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 5024(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5120(%r11) +vmovdqu 64(%rdx), %ymm0 +vmovdqu 152(%rdx), %ymm1 +vmovdqu 240(%rdx), %ymm2 +vmovdqu 328(%rdx), %ymm12 +vmovdqu 1120(%rdx), %ymm4 +vmovdqu 1208(%rdx), %ymm5 +vmovdqu 1296(%rdx), %ymm6 + +# Only 18 bytes more can be read, but vmovdqu reads 32. +# Copy 18 bytes to the red zone and zero pad to 32 bytes. +xor %r9, %r9 +movq %r9, -16(%rsp) +movq %r9, -8(%rsp) +movq 1384(%rdx), %r9 +movq %r9, -32(%rsp) +movq 1384+8(%rdx), %r9 +movq %r9, -24(%rsp) +movw 1384+16(%rdx), %r9w +movw %r9w, -16(%rsp) +vmovdqu -32(%rsp), %ymm7 + +vmovdqu 416(%rdx), %ymm8 +vmovdqu 504(%rdx), %ymm9 +vmovdqu 592(%rdx), %ymm10 +vmovdqu 680(%rdx), %ymm11 +vmovdqa %ymm0, 64(%r11) +vmovdqa %ymm1, 160(%r11) +vpaddw %ymm0, %ymm1, %ymm14 +vmovdqa %ymm14, 256(%r11) +vmovdqa %ymm2, 352(%r11) +vmovdqa %ymm12, 448(%r11) +vpaddw %ymm2, %ymm12, %ymm14 +vmovdqa %ymm14, 544(%r11) +vpaddw %ymm0, %ymm2, %ymm14 +vmovdqa %ymm14, 640(%r11) +vpaddw %ymm1, %ymm12, %ymm15 +vmovdqa %ymm15, 736(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 832(%r11) +vmovdqa %ymm4, 5248(%r11) +vmovdqa %ymm5, 5344(%r11) +vpaddw %ymm4, %ymm5, %ymm14 +vmovdqa %ymm14, 5440(%r11) +vmovdqa %ymm6, 5536(%r11) +vmovdqa %ymm7, 5632(%r11) +vpaddw %ymm6, %ymm7, %ymm14 +vmovdqa %ymm14, 5728(%r11) +vpaddw %ymm4, %ymm6, %ymm14 +vmovdqa %ymm14, 5824(%r11) +vpaddw %ymm5, %ymm7, %ymm15 +vmovdqa %ymm15, 5920(%r11) +vpaddw %ymm14, %ymm15, %ymm14 +vmovdqa %ymm14, 6016(%r11) +vmovdqa %ymm0, 0(%r8) +vmovdqa %ymm1, 32(%r8) +vmovdqa %ymm2, 64(%r8) +vmovdqa %ymm12, 96(%r8) +vmovdqa %ymm8, 128(%r8) +vmovdqa %ymm9, 160(%r8) +vmovdqa %ymm10, 192(%r8) +vmovdqa %ymm11, 224(%r8) +vmovdqu 768(%rdx), %ymm0 +vpaddw 0(%r8), %ymm0, %ymm1 +vpaddw 128(%r8), %ymm4, %ymm2 +vpaddw %ymm2, %ymm1, %ymm8 +vpsubw %ymm2, %ymm1, %ymm12 +vmovdqa %ymm0, 256(%r8) +vmovdqu 856(%rdx), %ymm0 +vpaddw 32(%r8), %ymm0, %ymm1 +vpaddw 160(%r8), %ymm5, %ymm2 +vpaddw %ymm2, %ymm1, %ymm9 +vpsubw %ymm2, %ymm1, %ymm13 +vmovdqa %ymm0, 288(%r8) +vmovdqu 944(%rdx), %ymm0 +vpaddw 64(%r8), %ymm0, %ymm1 +vpaddw 192(%r8), %ymm6, %ymm2 +vpaddw %ymm2, %ymm1, %ymm10 +vpsubw %ymm2, %ymm1, %ymm14 +vmovdqa %ymm0, 320(%r8) +vmovdqu 1032(%rdx), %ymm0 +vpaddw 96(%r8), %ymm0, %ymm1 +vpaddw 224(%r8), %ymm7, %ymm2 +vpaddw %ymm2, %ymm1, %ymm11 +vpsubw %ymm2, %ymm1, %ymm15 +vmovdqa %ymm0, 352(%r8) +vmovdqa %ymm8, 928(%r11) +vmovdqa %ymm9, 1024(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 1120(%r11) +vmovdqa %ymm10, 1216(%r11) +vmovdqa %ymm11, 1312(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 1408(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 1504(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 1600(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 1696(%r11) +vmovdqa %ymm12, 1792(%r11) +vmovdqa %ymm13, 1888(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 1984(%r11) +vmovdqa %ymm14, 2080(%r11) +vmovdqa %ymm15, 2176(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 2272(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 2368(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 2464(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 2560(%r11) +vmovdqa 256(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm4, %ymm1 +vpaddw 128(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm8 +vpsubw %ymm1, %ymm0, %ymm12 +vmovdqa 288(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm5, %ymm1 +vpaddw 160(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm9 +vpsubw %ymm1, %ymm0, %ymm13 +vmovdqa 320(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm6, %ymm1 +vpaddw 192(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm10 +vpsubw %ymm1, %ymm0, %ymm14 +vmovdqa 352(%r8), %ymm0 +vpsllw $2, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm0 +vpsllw $2, %ymm7, %ymm1 +vpaddw 224(%r8), %ymm1, %ymm1 +vpsllw $1, %ymm1, %ymm1 +vpaddw %ymm1, %ymm0, %ymm11 +vpsubw %ymm1, %ymm0, %ymm15 +vmovdqa %ymm8, 2656(%r11) +vmovdqa %ymm9, 2752(%r11) +vpaddw %ymm8, %ymm9, %ymm0 +vmovdqa %ymm0, 2848(%r11) +vmovdqa %ymm10, 2944(%r11) +vmovdqa %ymm11, 3040(%r11) +vpaddw %ymm10, %ymm11, %ymm0 +vmovdqa %ymm0, 3136(%r11) +vpaddw %ymm8, %ymm10, %ymm0 +vmovdqa %ymm0, 3232(%r11) +vpaddw %ymm9, %ymm11, %ymm1 +vmovdqa %ymm1, 3328(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 3424(%r11) +vmovdqa %ymm12, 3520(%r11) +vmovdqa %ymm13, 3616(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 3712(%r11) +vmovdqa %ymm14, 3808(%r11) +vmovdqa %ymm15, 3904(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4000(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4096(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 4192(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 4288(%r11) +vpmullw %ymm3, %ymm4, %ymm0 +vpaddw 256(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 128(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 0(%r8), %ymm0, %ymm12 +vpmullw %ymm3, %ymm5, %ymm0 +vpaddw 288(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 160(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 32(%r8), %ymm0, %ymm13 +vpmullw %ymm3, %ymm6, %ymm0 +vpaddw 320(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 192(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 64(%r8), %ymm0, %ymm14 +vpmullw %ymm3, %ymm7, %ymm0 +vpaddw 352(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 224(%r8), %ymm0, %ymm0 +vpmullw %ymm3, %ymm0, %ymm0 +vpaddw 96(%r8), %ymm0, %ymm15 +vmovdqa %ymm12, 4384(%r11) +vmovdqa %ymm13, 4480(%r11) +vpaddw %ymm12, %ymm13, %ymm0 +vmovdqa %ymm0, 4576(%r11) +vmovdqa %ymm14, 4672(%r11) +vmovdqa %ymm15, 4768(%r11) +vpaddw %ymm14, %ymm15, %ymm0 +vmovdqa %ymm0, 4864(%r11) +vpaddw %ymm12, %ymm14, %ymm0 +vmovdqa %ymm0, 4960(%r11) +vpaddw %ymm13, %ymm15, %ymm1 +vmovdqa %ymm1, 5056(%r11) +vpaddw %ymm0, %ymm1, %ymm0 +vmovdqa %ymm0, 5152(%r11) +subq $9408, %r8 +mov $4, %ecx +karatsuba_loop_4eced63f144beffcb0247f9c6f67d165: +mov %r8, %r9 +mov %r8, %r10 +subq $32, %r8 +vmovdqa 0(%rax), %ymm0 +vmovdqa 192(%rax), %ymm1 +vmovdqa 384(%rax), %ymm2 +vmovdqa 576(%rax), %ymm3 +vpunpcklwd 96(%rax), %ymm0, %ymm4 +vpunpckhwd 96(%rax), %ymm0, %ymm5 +vpunpcklwd 288(%rax), %ymm1, %ymm6 +vpunpckhwd 288(%rax), %ymm1, %ymm7 +vpunpcklwd 480(%rax), %ymm2, %ymm8 +vpunpckhwd 480(%rax), %ymm2, %ymm9 +vpunpcklwd 672(%rax), %ymm3, %ymm10 +vpunpckhwd 672(%rax), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 768(%rax), %ymm0 +vmovdqa 960(%rax), %ymm1 +vmovdqa 1152(%rax), %ymm2 +vmovdqa 1344(%rax), %ymm3 +vpunpcklwd 864(%rax), %ymm0, %ymm12 +vpunpckhwd 864(%rax), %ymm0, %ymm13 +vpunpcklwd 1056(%rax), %ymm1, %ymm14 +vpunpckhwd 1056(%rax), %ymm1, %ymm15 +vpunpcklwd 1248(%rax), %ymm2, %ymm0 +vpunpckhwd 1248(%rax), %ymm2, %ymm1 +vpunpcklwd 1440(%rax), %ymm3, %ymm2 +vpunpckhwd 1440(%rax), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 0(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 32(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 64(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 96(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 128(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 160(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 192(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 256(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 288(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 320(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 352(%r9) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 384(%r9) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 416(%r9) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 448(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 224(%r9) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 480(%r9) +vmovdqa 32(%rax), %ymm0 +vmovdqa 224(%rax), %ymm1 +vmovdqa 416(%rax), %ymm2 +vmovdqa 608(%rax), %ymm3 +vpunpcklwd 128(%rax), %ymm0, %ymm4 +vpunpckhwd 128(%rax), %ymm0, %ymm5 +vpunpcklwd 320(%rax), %ymm1, %ymm6 +vpunpckhwd 320(%rax), %ymm1, %ymm7 +vpunpcklwd 512(%rax), %ymm2, %ymm8 +vpunpckhwd 512(%rax), %ymm2, %ymm9 +vpunpcklwd 704(%rax), %ymm3, %ymm10 +vpunpckhwd 704(%rax), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 800(%rax), %ymm0 +vmovdqa 992(%rax), %ymm1 +vmovdqa 1184(%rax), %ymm2 +vmovdqa 1376(%rax), %ymm3 +vpunpcklwd 896(%rax), %ymm0, %ymm12 +vpunpckhwd 896(%rax), %ymm0, %ymm13 +vpunpcklwd 1088(%rax), %ymm1, %ymm14 +vpunpckhwd 1088(%rax), %ymm1, %ymm15 +vpunpcklwd 1280(%rax), %ymm2, %ymm0 +vpunpckhwd 1280(%rax), %ymm2, %ymm1 +vpunpcklwd 1472(%rax), %ymm3, %ymm2 +vpunpckhwd 1472(%rax), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 512(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 544(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 576(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 608(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 640(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 672(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 704(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 768(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 800(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 832(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 864(%r9) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 896(%r9) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 928(%r9) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 960(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 736(%r9) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 992(%r9) +vmovdqa 64(%rax), %ymm0 +vmovdqa 256(%rax), %ymm1 +vmovdqa 448(%rax), %ymm2 +vmovdqa 640(%rax), %ymm3 +vpunpcklwd 160(%rax), %ymm0, %ymm4 +vpunpckhwd 160(%rax), %ymm0, %ymm5 +vpunpcklwd 352(%rax), %ymm1, %ymm6 +vpunpckhwd 352(%rax), %ymm1, %ymm7 +vpunpcklwd 544(%rax), %ymm2, %ymm8 +vpunpckhwd 544(%rax), %ymm2, %ymm9 +vpunpcklwd 736(%rax), %ymm3, %ymm10 +vpunpckhwd 736(%rax), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 832(%rax), %ymm0 +vmovdqa 1024(%rax), %ymm1 +vmovdqa 1216(%rax), %ymm2 +vmovdqa 1408(%rax), %ymm3 +vpunpcklwd 928(%rax), %ymm0, %ymm12 +vpunpckhwd 928(%rax), %ymm0, %ymm13 +vpunpcklwd 1120(%rax), %ymm1, %ymm14 +vpunpckhwd 1120(%rax), %ymm1, %ymm15 +vpunpcklwd 1312(%rax), %ymm2, %ymm0 +vpunpckhwd 1312(%rax), %ymm2, %ymm1 +vpunpcklwd 1504(%rax), %ymm3, %ymm2 +vpunpckhwd 1504(%rax), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 1024(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 1056(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 1088(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 1120(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 1152(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1184(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1216(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1280(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1312(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 1344(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 1376(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1248(%r9) +vmovdqa 0(%r11), %ymm0 +vmovdqa 192(%r11), %ymm1 +vmovdqa 384(%r11), %ymm2 +vmovdqa 576(%r11), %ymm3 +vpunpcklwd 96(%r11), %ymm0, %ymm4 +vpunpckhwd 96(%r11), %ymm0, %ymm5 +vpunpcklwd 288(%r11), %ymm1, %ymm6 +vpunpckhwd 288(%r11), %ymm1, %ymm7 +vpunpcklwd 480(%r11), %ymm2, %ymm8 +vpunpckhwd 480(%r11), %ymm2, %ymm9 +vpunpcklwd 672(%r11), %ymm3, %ymm10 +vpunpckhwd 672(%r11), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 768(%r11), %ymm0 +vmovdqa 960(%r11), %ymm1 +vmovdqa 1152(%r11), %ymm2 +vmovdqa 1344(%r11), %ymm3 +vpunpcklwd 864(%r11), %ymm0, %ymm12 +vpunpckhwd 864(%r11), %ymm0, %ymm13 +vpunpcklwd 1056(%r11), %ymm1, %ymm14 +vpunpckhwd 1056(%r11), %ymm1, %ymm15 +vpunpcklwd 1248(%r11), %ymm2, %ymm0 +vpunpckhwd 1248(%r11), %ymm2, %ymm1 +vpunpcklwd 1440(%r11), %ymm3, %ymm2 +vpunpckhwd 1440(%r11), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 1408(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 1440(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 1472(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 1504(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 1536(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1568(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1600(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1664(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1696(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 1728(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 1760(%r9) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 1792(%r9) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 1824(%r9) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 1856(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1632(%r9) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 1888(%r9) +vmovdqa 32(%r11), %ymm0 +vmovdqa 224(%r11), %ymm1 +vmovdqa 416(%r11), %ymm2 +vmovdqa 608(%r11), %ymm3 +vpunpcklwd 128(%r11), %ymm0, %ymm4 +vpunpckhwd 128(%r11), %ymm0, %ymm5 +vpunpcklwd 320(%r11), %ymm1, %ymm6 +vpunpckhwd 320(%r11), %ymm1, %ymm7 +vpunpcklwd 512(%r11), %ymm2, %ymm8 +vpunpckhwd 512(%r11), %ymm2, %ymm9 +vpunpcklwd 704(%r11), %ymm3, %ymm10 +vpunpckhwd 704(%r11), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 800(%r11), %ymm0 +vmovdqa 992(%r11), %ymm1 +vmovdqa 1184(%r11), %ymm2 +vmovdqa 1376(%r11), %ymm3 +vpunpcklwd 896(%r11), %ymm0, %ymm12 +vpunpckhwd 896(%r11), %ymm0, %ymm13 +vpunpcklwd 1088(%r11), %ymm1, %ymm14 +vpunpckhwd 1088(%r11), %ymm1, %ymm15 +vpunpcklwd 1280(%r11), %ymm2, %ymm0 +vpunpckhwd 1280(%r11), %ymm2, %ymm1 +vpunpcklwd 1472(%r11), %ymm3, %ymm2 +vpunpckhwd 1472(%r11), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 1920(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 1952(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 1984(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 2016(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 2048(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 2080(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 2112(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 2176(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 2208(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 2240(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2272(%r9) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2304(%r9) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2336(%r9) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2368(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 2144(%r9) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 2400(%r9) +vmovdqa 64(%r11), %ymm0 +vmovdqa 256(%r11), %ymm1 +vmovdqa 448(%r11), %ymm2 +vmovdqa 640(%r11), %ymm3 +vpunpcklwd 160(%r11), %ymm0, %ymm4 +vpunpckhwd 160(%r11), %ymm0, %ymm5 +vpunpcklwd 352(%r11), %ymm1, %ymm6 +vpunpckhwd 352(%r11), %ymm1, %ymm7 +vpunpcklwd 544(%r11), %ymm2, %ymm8 +vpunpckhwd 544(%r11), %ymm2, %ymm9 +vpunpcklwd 736(%r11), %ymm3, %ymm10 +vpunpckhwd 736(%r11), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 832(%r11), %ymm0 +vmovdqa 1024(%r11), %ymm1 +vmovdqa 1216(%r11), %ymm2 +vmovdqa 1408(%r11), %ymm3 +vpunpcklwd 928(%r11), %ymm0, %ymm12 +vpunpckhwd 928(%r11), %ymm0, %ymm13 +vpunpcklwd 1120(%r11), %ymm1, %ymm14 +vpunpckhwd 1120(%r11), %ymm1, %ymm15 +vpunpcklwd 1312(%r11), %ymm2, %ymm0 +vpunpckhwd 1312(%r11), %ymm2, %ymm1 +vpunpcklwd 1504(%r11), %ymm3, %ymm2 +vpunpckhwd 1504(%r11), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 2432(%r9) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 2464(%r9) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 2496(%r9) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 2528(%r9) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 2560(%r9) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 2592(%r9) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 2624(%r9) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 2688(%r9) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 2720(%r9) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 2752(%r9) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2784(%r9) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 2656(%r9) +addq $32, %r8 +innerloop_4eced63f144beffcb0247f9c6f67d165: +vmovdqa 0(%r9), %ymm0 +vmovdqa 1408(%r9), %ymm6 +vmovdqa 32(%r9), %ymm1 +vmovdqa 1440(%r9), %ymm7 +vmovdqa 64(%r9), %ymm2 +vmovdqa 1472(%r9), %ymm8 +vmovdqa 96(%r9), %ymm3 +vmovdqa 1504(%r9), %ymm9 +vmovdqa 128(%r9), %ymm4 +vmovdqa 1536(%r9), %ymm10 +vmovdqa 160(%r9), %ymm5 +vmovdqa 1568(%r9), %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 2816(%r10) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 2848(%r10) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 2880(%r10) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 2912(%r10) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 2944(%r10) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 2976(%r10) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3008(%r10) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3040(%r10) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3072(%r10) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3104(%r10) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 3136(%r10) +vmovdqa 192(%r9), %ymm0 +vmovdqa 1600(%r9), %ymm6 +vmovdqa 224(%r9), %ymm1 +vmovdqa 1632(%r9), %ymm7 +vmovdqa 256(%r9), %ymm2 +vmovdqa 1664(%r9), %ymm8 +vmovdqa 288(%r9), %ymm3 +vmovdqa 1696(%r9), %ymm9 +vmovdqa 320(%r9), %ymm4 +vmovdqa 1728(%r9), %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 3200(%r10) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3232(%r10) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3264(%r10) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3296(%r10) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3328(%r10) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3360(%r10) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3392(%r10) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3424(%r10) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 3456(%r10) +vpaddw 0(%r9), %ymm0, %ymm0 +vpaddw 1408(%r9), %ymm6, %ymm6 +vpaddw 32(%r9), %ymm1, %ymm1 +vpaddw 1440(%r9), %ymm7, %ymm7 +vpaddw 64(%r9), %ymm2, %ymm2 +vpaddw 1472(%r9), %ymm8, %ymm8 +vpaddw 96(%r9), %ymm3, %ymm3 +vpaddw 1504(%r9), %ymm9, %ymm9 +vpaddw 128(%r9), %ymm4, %ymm4 +vpaddw 1536(%r9), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 2976(%r10), %ymm12, %ymm12 +vpsubw 3360(%r10), %ymm12, %ymm12 +vmovdqa %ymm12, 3168(%r10) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 3008(%r10), %ymm0 +vpsubw 3200(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 3392(%r10), %ymm6, %ymm6 +vmovdqa %ymm6, 3200(%r10) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 2816(%r10), %ymm0, %ymm0 +vmovdqa %ymm0, 3008(%r10) +vmovdqa 3040(%r10), %ymm1 +vpsubw 3232(%r10), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 3424(%r10), %ymm7, %ymm7 +vmovdqa %ymm7, 3232(%r10) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 2848(%r10), %ymm1, %ymm1 +vmovdqa %ymm1, 3040(%r10) +vmovdqa 3072(%r10), %ymm2 +vpsubw 3264(%r10), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 3456(%r10), %ymm8, %ymm8 +vmovdqa %ymm8, 3264(%r10) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 2880(%r10), %ymm2, %ymm2 +vmovdqa %ymm2, 3072(%r10) +vmovdqa 3104(%r10), %ymm3 +vpsubw 3296(%r10), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 3296(%r10) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 2912(%r10), %ymm3, %ymm3 +vmovdqa %ymm3, 3104(%r10) +vmovdqa 3136(%r10), %ymm4 +vpsubw 3328(%r10), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 2944(%r10), %ymm4, %ymm4 +vmovdqa %ymm4, 3136(%r10) +vmovdqa 352(%r9), %ymm0 +vmovdqa 1760(%r9), %ymm6 +vmovdqa 384(%r9), %ymm1 +vmovdqa 1792(%r9), %ymm7 +vmovdqa 416(%r9), %ymm2 +vmovdqa 1824(%r9), %ymm8 +vmovdqa 448(%r9), %ymm3 +vmovdqa 1856(%r9), %ymm9 +vmovdqa 480(%r9), %ymm4 +vmovdqa 1888(%r9), %ymm10 +vmovdqa 512(%r9), %ymm5 +vmovdqa 1920(%r9), %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 3520(%r10) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3552(%r10) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3584(%r10) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3616(%r10) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3648(%r10) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3680(%r10) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3712(%r10) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3744(%r10) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3776(%r10) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3808(%r10) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 3840(%r10) +vmovdqa 544(%r9), %ymm0 +vmovdqa 1952(%r9), %ymm6 +vmovdqa 576(%r9), %ymm1 +vmovdqa 1984(%r9), %ymm7 +vmovdqa 608(%r9), %ymm2 +vmovdqa 2016(%r9), %ymm8 +vmovdqa 640(%r9), %ymm3 +vmovdqa 2048(%r9), %ymm9 +vmovdqa 672(%r9), %ymm4 +vmovdqa 2080(%r9), %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 3904(%r10) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 3936(%r10) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 3968(%r10) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 4000(%r10) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 4032(%r10) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 4064(%r10) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 4096(%r10) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 4128(%r10) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 4160(%r10) +vpaddw 352(%r9), %ymm0, %ymm0 +vpaddw 1760(%r9), %ymm6, %ymm6 +vpaddw 384(%r9), %ymm1, %ymm1 +vpaddw 1792(%r9), %ymm7, %ymm7 +vpaddw 416(%r9), %ymm2, %ymm2 +vpaddw 1824(%r9), %ymm8, %ymm8 +vpaddw 448(%r9), %ymm3, %ymm3 +vpaddw 1856(%r9), %ymm9, %ymm9 +vpaddw 480(%r9), %ymm4, %ymm4 +vpaddw 1888(%r9), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 3680(%r10), %ymm12, %ymm12 +vpsubw 4064(%r10), %ymm12, %ymm12 +vmovdqa %ymm12, 3872(%r10) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 3712(%r10), %ymm0 +vpsubw 3904(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 4096(%r10), %ymm6, %ymm6 +vmovdqa %ymm6, 3904(%r10) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 3520(%r10), %ymm0, %ymm0 +vmovdqa %ymm0, 3712(%r10) +vmovdqa 3744(%r10), %ymm1 +vpsubw 3936(%r10), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 4128(%r10), %ymm7, %ymm7 +vmovdqa %ymm7, 3936(%r10) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 3552(%r10), %ymm1, %ymm1 +vmovdqa %ymm1, 3744(%r10) +vmovdqa 3776(%r10), %ymm2 +vpsubw 3968(%r10), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 4160(%r10), %ymm8, %ymm8 +vmovdqa %ymm8, 3968(%r10) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 3584(%r10), %ymm2, %ymm2 +vmovdqa %ymm2, 3776(%r10) +vmovdqa 3808(%r10), %ymm3 +vpsubw 4000(%r10), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 4000(%r10) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 3616(%r10), %ymm3, %ymm3 +vmovdqa %ymm3, 3808(%r10) +vmovdqa 3840(%r10), %ymm4 +vpsubw 4032(%r10), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 3648(%r10), %ymm4, %ymm4 +vmovdqa %ymm4, 3840(%r10) +vmovdqa 0(%r9), %ymm0 +vmovdqa 1408(%r9), %ymm6 +vpaddw 352(%r9), %ymm0, %ymm0 +vpaddw 1760(%r9), %ymm6, %ymm6 +vmovdqa 32(%r9), %ymm1 +vmovdqa 1440(%r9), %ymm7 +vpaddw 384(%r9), %ymm1, %ymm1 +vpaddw 1792(%r9), %ymm7, %ymm7 +vmovdqa 64(%r9), %ymm2 +vmovdqa 1472(%r9), %ymm8 +vpaddw 416(%r9), %ymm2, %ymm2 +vpaddw 1824(%r9), %ymm8, %ymm8 +vmovdqa 96(%r9), %ymm3 +vmovdqa 1504(%r9), %ymm9 +vpaddw 448(%r9), %ymm3, %ymm3 +vpaddw 1856(%r9), %ymm9, %ymm9 +vmovdqa 128(%r9), %ymm4 +vmovdqa 1536(%r9), %ymm10 +vpaddw 480(%r9), %ymm4, %ymm4 +vpaddw 1888(%r9), %ymm10, %ymm10 +vmovdqa 160(%r9), %ymm5 +vmovdqa 1568(%r9), %ymm11 +vpaddw 512(%r9), %ymm5, %ymm5 +vpaddw 1920(%r9), %ymm11, %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 5888(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 5920(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 5952(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 5984(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6016(%r8) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6048(%r8) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6080(%r8) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6112(%r8) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6144(%r8) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6176(%r8) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 6208(%r8) +vmovdqa 192(%r9), %ymm0 +vmovdqa 1600(%r9), %ymm6 +vpaddw 544(%r9), %ymm0, %ymm0 +vpaddw 1952(%r9), %ymm6, %ymm6 +vmovdqa 224(%r9), %ymm1 +vmovdqa 1632(%r9), %ymm7 +vpaddw 576(%r9), %ymm1, %ymm1 +vpaddw 1984(%r9), %ymm7, %ymm7 +vmovdqa 256(%r9), %ymm2 +vmovdqa 1664(%r9), %ymm8 +vpaddw 608(%r9), %ymm2, %ymm2 +vpaddw 2016(%r9), %ymm8, %ymm8 +vmovdqa 288(%r9), %ymm3 +vmovdqa 1696(%r9), %ymm9 +vpaddw 640(%r9), %ymm3, %ymm3 +vpaddw 2048(%r9), %ymm9, %ymm9 +vmovdqa 320(%r9), %ymm4 +vmovdqa 1728(%r9), %ymm10 +vpaddw 672(%r9), %ymm4, %ymm4 +vpaddw 2080(%r9), %ymm10, %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 6272(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6304(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6336(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6368(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6400(%r8) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6432(%r8) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6464(%r8) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6496(%r8) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 6528(%r8) +vpaddw 0(%r9), %ymm0, %ymm0 +vpaddw 1408(%r9), %ymm6, %ymm6 +vpaddw 352(%r9), %ymm0, %ymm0 +vpaddw 1760(%r9), %ymm6, %ymm6 +vpaddw 32(%r9), %ymm1, %ymm1 +vpaddw 1440(%r9), %ymm7, %ymm7 +vpaddw 384(%r9), %ymm1, %ymm1 +vpaddw 1792(%r9), %ymm7, %ymm7 +vpaddw 64(%r9), %ymm2, %ymm2 +vpaddw 1472(%r9), %ymm8, %ymm8 +vpaddw 416(%r9), %ymm2, %ymm2 +vpaddw 1824(%r9), %ymm8, %ymm8 +vpaddw 96(%r9), %ymm3, %ymm3 +vpaddw 1504(%r9), %ymm9, %ymm9 +vpaddw 448(%r9), %ymm3, %ymm3 +vpaddw 1856(%r9), %ymm9, %ymm9 +vpaddw 128(%r9), %ymm4, %ymm4 +vpaddw 1536(%r9), %ymm10, %ymm10 +vpaddw 480(%r9), %ymm4, %ymm4 +vpaddw 1888(%r9), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 6048(%r8), %ymm12, %ymm12 +vpsubw 6432(%r8), %ymm12, %ymm12 +vmovdqa %ymm12, 6240(%r8) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 6080(%r8), %ymm0 +vpsubw 6272(%r8), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 6464(%r8), %ymm6, %ymm6 +vmovdqa %ymm6, 6272(%r8) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 5888(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 6080(%r8) +vmovdqa 6112(%r8), %ymm1 +vpsubw 6304(%r8), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 6496(%r8), %ymm7, %ymm7 +vmovdqa %ymm7, 6304(%r8) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 5920(%r8), %ymm1, %ymm1 +vmovdqa %ymm1, 6112(%r8) +vmovdqa 6144(%r8), %ymm2 +vpsubw 6336(%r8), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 6528(%r8), %ymm8, %ymm8 +vmovdqa %ymm8, 6336(%r8) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 5952(%r8), %ymm2, %ymm2 +vmovdqa %ymm2, 6144(%r8) +vmovdqa 6176(%r8), %ymm3 +vpsubw 6368(%r8), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 6368(%r8) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 5984(%r8), %ymm3, %ymm3 +vmovdqa %ymm3, 6176(%r8) +vmovdqa 6208(%r8), %ymm4 +vpsubw 6400(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 6016(%r8), %ymm4, %ymm4 +vmovdqa %ymm4, 6208(%r8) +vmovdqa 6208(%r8), %ymm0 +vpsubw 3136(%r10), %ymm0, %ymm0 +vpsubw 3840(%r10), %ymm0, %ymm0 +vmovdqa %ymm0, 3488(%r10) +vmovdqa 3168(%r10), %ymm0 +vpsubw 3520(%r10), %ymm0, %ymm0 +vmovdqa 6240(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3872(%r10), %ymm1, %ymm1 +vpsubw 2816(%r10), %ymm0, %ymm0 +vpaddw 5888(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3168(%r10) +vmovdqa %ymm1, 3520(%r10) +vmovdqa 3200(%r10), %ymm0 +vpsubw 3552(%r10), %ymm0, %ymm0 +vmovdqa 6272(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3904(%r10), %ymm1, %ymm1 +vpsubw 2848(%r10), %ymm0, %ymm0 +vpaddw 5920(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3200(%r10) +vmovdqa %ymm1, 3552(%r10) +vmovdqa 3232(%r10), %ymm0 +vpsubw 3584(%r10), %ymm0, %ymm0 +vmovdqa 6304(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3936(%r10), %ymm1, %ymm1 +vpsubw 2880(%r10), %ymm0, %ymm0 +vpaddw 5952(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3232(%r10) +vmovdqa %ymm1, 3584(%r10) +vmovdqa 3264(%r10), %ymm0 +vpsubw 3616(%r10), %ymm0, %ymm0 +vmovdqa 6336(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3968(%r10), %ymm1, %ymm1 +vpsubw 2912(%r10), %ymm0, %ymm0 +vpaddw 5984(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3264(%r10) +vmovdqa %ymm1, 3616(%r10) +vmovdqa 3296(%r10), %ymm0 +vpsubw 3648(%r10), %ymm0, %ymm0 +vmovdqa 6368(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4000(%r10), %ymm1, %ymm1 +vpsubw 2944(%r10), %ymm0, %ymm0 +vpaddw 6016(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3296(%r10) +vmovdqa %ymm1, 3648(%r10) +vmovdqa 3328(%r10), %ymm0 +vpsubw 3680(%r10), %ymm0, %ymm0 +vmovdqa 6400(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4032(%r10), %ymm1, %ymm1 +vpsubw 2976(%r10), %ymm0, %ymm0 +vpaddw 6048(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3328(%r10) +vmovdqa %ymm1, 3680(%r10) +vmovdqa 3360(%r10), %ymm0 +vpsubw 3712(%r10), %ymm0, %ymm0 +vmovdqa 6432(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4064(%r10), %ymm1, %ymm1 +vpsubw 3008(%r10), %ymm0, %ymm0 +vpaddw 6080(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3360(%r10) +vmovdqa %ymm1, 3712(%r10) +vmovdqa 3392(%r10), %ymm0 +vpsubw 3744(%r10), %ymm0, %ymm0 +vmovdqa 6464(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4096(%r10), %ymm1, %ymm1 +vpsubw 3040(%r10), %ymm0, %ymm0 +vpaddw 6112(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3392(%r10) +vmovdqa %ymm1, 3744(%r10) +vmovdqa 3424(%r10), %ymm0 +vpsubw 3776(%r10), %ymm0, %ymm0 +vmovdqa 6496(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4128(%r10), %ymm1, %ymm1 +vpsubw 3072(%r10), %ymm0, %ymm0 +vpaddw 6144(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3424(%r10) +vmovdqa %ymm1, 3776(%r10) +vmovdqa 3456(%r10), %ymm0 +vpsubw 3808(%r10), %ymm0, %ymm0 +vmovdqa 6528(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 4160(%r10), %ymm1, %ymm1 +vpsubw 3104(%r10), %ymm0, %ymm0 +vpaddw 6176(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3456(%r10) +vmovdqa %ymm1, 3808(%r10) +neg %ecx +jns done_4eced63f144beffcb0247f9c6f67d165 +add $704, %r9 +add $1408, %r10 +jmp innerloop_4eced63f144beffcb0247f9c6f67d165 +done_4eced63f144beffcb0247f9c6f67d165: +sub $704, %r9 +sub $1408, %r10 +vmovdqa 0(%r9), %ymm0 +vpaddw 704(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6592(%r8) +vmovdqa 1408(%r9), %ymm0 +vpaddw 2112(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7296(%r8) +vmovdqa 32(%r9), %ymm0 +vpaddw 736(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6624(%r8) +vmovdqa 1440(%r9), %ymm0 +vpaddw 2144(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7328(%r8) +vmovdqa 64(%r9), %ymm0 +vpaddw 768(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6656(%r8) +vmovdqa 1472(%r9), %ymm0 +vpaddw 2176(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7360(%r8) +vmovdqa 96(%r9), %ymm0 +vpaddw 800(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6688(%r8) +vmovdqa 1504(%r9), %ymm0 +vpaddw 2208(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7392(%r8) +vmovdqa 128(%r9), %ymm0 +vpaddw 832(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6720(%r8) +vmovdqa 1536(%r9), %ymm0 +vpaddw 2240(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7424(%r8) +vmovdqa 160(%r9), %ymm0 +vpaddw 864(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6752(%r8) +vmovdqa 1568(%r9), %ymm0 +vpaddw 2272(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7456(%r8) +vmovdqa 192(%r9), %ymm0 +vpaddw 896(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6784(%r8) +vmovdqa 1600(%r9), %ymm0 +vpaddw 2304(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7488(%r8) +vmovdqa 224(%r9), %ymm0 +vpaddw 928(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6816(%r8) +vmovdqa 1632(%r9), %ymm0 +vpaddw 2336(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7520(%r8) +vmovdqa 256(%r9), %ymm0 +vpaddw 960(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6848(%r8) +vmovdqa 1664(%r9), %ymm0 +vpaddw 2368(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7552(%r8) +vmovdqa 288(%r9), %ymm0 +vpaddw 992(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6880(%r8) +vmovdqa 1696(%r9), %ymm0 +vpaddw 2400(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7584(%r8) +vmovdqa 320(%r9), %ymm0 +vpaddw 1024(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6912(%r8) +vmovdqa 1728(%r9), %ymm0 +vpaddw 2432(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7616(%r8) +vmovdqa 352(%r9), %ymm0 +vpaddw 1056(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6944(%r8) +vmovdqa 1760(%r9), %ymm0 +vpaddw 2464(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7648(%r8) +vmovdqa 384(%r9), %ymm0 +vpaddw 1088(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 6976(%r8) +vmovdqa 1792(%r9), %ymm0 +vpaddw 2496(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7680(%r8) +vmovdqa 416(%r9), %ymm0 +vpaddw 1120(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7008(%r8) +vmovdqa 1824(%r9), %ymm0 +vpaddw 2528(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7712(%r8) +vmovdqa 448(%r9), %ymm0 +vpaddw 1152(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7040(%r8) +vmovdqa 1856(%r9), %ymm0 +vpaddw 2560(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7744(%r8) +vmovdqa 480(%r9), %ymm0 +vpaddw 1184(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7072(%r8) +vmovdqa 1888(%r9), %ymm0 +vpaddw 2592(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7776(%r8) +vmovdqa 512(%r9), %ymm0 +vpaddw 1216(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7104(%r8) +vmovdqa 1920(%r9), %ymm0 +vpaddw 2624(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7808(%r8) +vmovdqa 544(%r9), %ymm0 +vpaddw 1248(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7136(%r8) +vmovdqa 1952(%r9), %ymm0 +vpaddw 2656(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7840(%r8) +vmovdqa 576(%r9), %ymm0 +vpaddw 1280(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7168(%r8) +vmovdqa 1984(%r9), %ymm0 +vpaddw 2688(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7872(%r8) +vmovdqa 608(%r9), %ymm0 +vpaddw 1312(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7200(%r8) +vmovdqa 2016(%r9), %ymm0 +vpaddw 2720(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7904(%r8) +vmovdqa 640(%r9), %ymm0 +vpaddw 1344(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7232(%r8) +vmovdqa 2048(%r9), %ymm0 +vpaddw 2752(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7936(%r8) +vmovdqa 672(%r9), %ymm0 +vpaddw 1376(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7264(%r8) +vmovdqa 2080(%r9), %ymm0 +vpaddw 2784(%r9), %ymm0, %ymm0 +vmovdqa %ymm0, 7968(%r8) +vmovdqa 6592(%r8), %ymm0 +vmovdqa 7296(%r8), %ymm6 +vmovdqa 6624(%r8), %ymm1 +vmovdqa 7328(%r8), %ymm7 +vmovdqa 6656(%r8), %ymm2 +vmovdqa 7360(%r8), %ymm8 +vmovdqa 6688(%r8), %ymm3 +vmovdqa 7392(%r8), %ymm9 +vmovdqa 6720(%r8), %ymm4 +vmovdqa 7424(%r8), %ymm10 +vmovdqa 6752(%r8), %ymm5 +vmovdqa 7456(%r8), %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 8000(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8032(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8064(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8096(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8128(%r8) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8160(%r8) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8192(%r8) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8224(%r8) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8256(%r8) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8288(%r8) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 8320(%r8) +vmovdqa 6784(%r8), %ymm0 +vmovdqa 7488(%r8), %ymm6 +vmovdqa 6816(%r8), %ymm1 +vmovdqa 7520(%r8), %ymm7 +vmovdqa 6848(%r8), %ymm2 +vmovdqa 7552(%r8), %ymm8 +vmovdqa 6880(%r8), %ymm3 +vmovdqa 7584(%r8), %ymm9 +vmovdqa 6912(%r8), %ymm4 +vmovdqa 7616(%r8), %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 8384(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8416(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8448(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8480(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8512(%r8) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8544(%r8) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8576(%r8) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8608(%r8) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 8640(%r8) +vpaddw 6592(%r8), %ymm0, %ymm0 +vpaddw 7296(%r8), %ymm6, %ymm6 +vpaddw 6624(%r8), %ymm1, %ymm1 +vpaddw 7328(%r8), %ymm7, %ymm7 +vpaddw 6656(%r8), %ymm2, %ymm2 +vpaddw 7360(%r8), %ymm8, %ymm8 +vpaddw 6688(%r8), %ymm3, %ymm3 +vpaddw 7392(%r8), %ymm9, %ymm9 +vpaddw 6720(%r8), %ymm4, %ymm4 +vpaddw 7424(%r8), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 8160(%r8), %ymm12, %ymm12 +vpsubw 8544(%r8), %ymm12, %ymm12 +vmovdqa %ymm12, 8352(%r8) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 8192(%r8), %ymm0 +vpsubw 8384(%r8), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 8576(%r8), %ymm6, %ymm6 +vmovdqa %ymm6, 8384(%r8) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 8000(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8192(%r8) +vmovdqa 8224(%r8), %ymm1 +vpsubw 8416(%r8), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 8608(%r8), %ymm7, %ymm7 +vmovdqa %ymm7, 8416(%r8) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 8032(%r8), %ymm1, %ymm1 +vmovdqa %ymm1, 8224(%r8) +vmovdqa 8256(%r8), %ymm2 +vpsubw 8448(%r8), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 8640(%r8), %ymm8, %ymm8 +vmovdqa %ymm8, 8448(%r8) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 8064(%r8), %ymm2, %ymm2 +vmovdqa %ymm2, 8256(%r8) +vmovdqa 8288(%r8), %ymm3 +vpsubw 8480(%r8), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 8480(%r8) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 8096(%r8), %ymm3, %ymm3 +vmovdqa %ymm3, 8288(%r8) +vmovdqa 8320(%r8), %ymm4 +vpsubw 8512(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 8128(%r8), %ymm4, %ymm4 +vmovdqa %ymm4, 8320(%r8) +vmovdqa 6944(%r8), %ymm0 +vmovdqa 7648(%r8), %ymm6 +vmovdqa 6976(%r8), %ymm1 +vmovdqa 7680(%r8), %ymm7 +vmovdqa 7008(%r8), %ymm2 +vmovdqa 7712(%r8), %ymm8 +vmovdqa 7040(%r8), %ymm3 +vmovdqa 7744(%r8), %ymm9 +vmovdqa 7072(%r8), %ymm4 +vmovdqa 7776(%r8), %ymm10 +vmovdqa 7104(%r8), %ymm5 +vmovdqa 7808(%r8), %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 8704(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8736(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8768(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8800(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8832(%r8) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8864(%r8) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8896(%r8) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8928(%r8) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 8960(%r8) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 8992(%r8) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 9024(%r8) +vmovdqa 7136(%r8), %ymm0 +vmovdqa 7840(%r8), %ymm6 +vmovdqa 7168(%r8), %ymm1 +vmovdqa 7872(%r8), %ymm7 +vmovdqa 7200(%r8), %ymm2 +vmovdqa 7904(%r8), %ymm8 +vmovdqa 7232(%r8), %ymm3 +vmovdqa 7936(%r8), %ymm9 +vmovdqa 7264(%r8), %ymm4 +vmovdqa 7968(%r8), %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 9088(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 9120(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 9152(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 9184(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 9216(%r8) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 9248(%r8) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 9280(%r8) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 9312(%r8) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 9344(%r8) +vpaddw 6944(%r8), %ymm0, %ymm0 +vpaddw 7648(%r8), %ymm6, %ymm6 +vpaddw 6976(%r8), %ymm1, %ymm1 +vpaddw 7680(%r8), %ymm7, %ymm7 +vpaddw 7008(%r8), %ymm2, %ymm2 +vpaddw 7712(%r8), %ymm8, %ymm8 +vpaddw 7040(%r8), %ymm3, %ymm3 +vpaddw 7744(%r8), %ymm9, %ymm9 +vpaddw 7072(%r8), %ymm4, %ymm4 +vpaddw 7776(%r8), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 8864(%r8), %ymm12, %ymm12 +vpsubw 9248(%r8), %ymm12, %ymm12 +vmovdqa %ymm12, 9056(%r8) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 8896(%r8), %ymm0 +vpsubw 9088(%r8), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 9280(%r8), %ymm6, %ymm6 +vmovdqa %ymm6, 9088(%r8) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 8704(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8896(%r8) +vmovdqa 8928(%r8), %ymm1 +vpsubw 9120(%r8), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 9312(%r8), %ymm7, %ymm7 +vmovdqa %ymm7, 9120(%r8) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 8736(%r8), %ymm1, %ymm1 +vmovdqa %ymm1, 8928(%r8) +vmovdqa 8960(%r8), %ymm2 +vpsubw 9152(%r8), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 9344(%r8), %ymm8, %ymm8 +vmovdqa %ymm8, 9152(%r8) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 8768(%r8), %ymm2, %ymm2 +vmovdqa %ymm2, 8960(%r8) +vmovdqa 8992(%r8), %ymm3 +vpsubw 9184(%r8), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 9184(%r8) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 8800(%r8), %ymm3, %ymm3 +vmovdqa %ymm3, 8992(%r8) +vmovdqa 9024(%r8), %ymm4 +vpsubw 9216(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 8832(%r8), %ymm4, %ymm4 +vmovdqa %ymm4, 9024(%r8) +vmovdqa 6592(%r8), %ymm0 +vmovdqa 7296(%r8), %ymm6 +vpaddw 6944(%r8), %ymm0, %ymm0 +vpaddw 7648(%r8), %ymm6, %ymm6 +vmovdqa 6624(%r8), %ymm1 +vmovdqa 7328(%r8), %ymm7 +vpaddw 6976(%r8), %ymm1, %ymm1 +vpaddw 7680(%r8), %ymm7, %ymm7 +vmovdqa 6656(%r8), %ymm2 +vmovdqa 7360(%r8), %ymm8 +vpaddw 7008(%r8), %ymm2, %ymm2 +vpaddw 7712(%r8), %ymm8, %ymm8 +vmovdqa 6688(%r8), %ymm3 +vmovdqa 7392(%r8), %ymm9 +vpaddw 7040(%r8), %ymm3, %ymm3 +vpaddw 7744(%r8), %ymm9, %ymm9 +vmovdqa 6720(%r8), %ymm4 +vmovdqa 7424(%r8), %ymm10 +vpaddw 7072(%r8), %ymm4, %ymm4 +vpaddw 7776(%r8), %ymm10, %ymm10 +vmovdqa 6752(%r8), %ymm5 +vmovdqa 7456(%r8), %ymm11 +vpaddw 7104(%r8), %ymm5, %ymm5 +vpaddw 7808(%r8), %ymm11, %ymm11 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 5888(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 5920(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 5952(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 5984(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6016(%r8) +vpmullw %ymm0, %ymm11, %ymm13 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6048(%r8) +vpmullw %ymm1, %ymm11, %ymm12 +vpmullw %ymm2, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6080(%r8) +vpmullw %ymm2, %ymm11, %ymm13 +vpmullw %ymm3, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm5, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6112(%r8) +vpmullw %ymm3, %ymm11, %ymm12 +vpmullw %ymm4, %ymm10, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm5, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6144(%r8) +vpmullw %ymm4, %ymm11, %ymm13 +vpmullw %ymm5, %ymm10, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6176(%r8) +vpmullw %ymm5, %ymm11, %ymm12 +vmovdqa %ymm12, 6208(%r8) +vmovdqa 6784(%r8), %ymm0 +vmovdqa 7488(%r8), %ymm6 +vpaddw 7136(%r8), %ymm0, %ymm0 +vpaddw 7840(%r8), %ymm6, %ymm6 +vmovdqa 6816(%r8), %ymm1 +vmovdqa 7520(%r8), %ymm7 +vpaddw 7168(%r8), %ymm1, %ymm1 +vpaddw 7872(%r8), %ymm7, %ymm7 +vmovdqa 6848(%r8), %ymm2 +vmovdqa 7552(%r8), %ymm8 +vpaddw 7200(%r8), %ymm2, %ymm2 +vpaddw 7904(%r8), %ymm8, %ymm8 +vmovdqa 6880(%r8), %ymm3 +vmovdqa 7584(%r8), %ymm9 +vpaddw 7232(%r8), %ymm3, %ymm3 +vpaddw 7936(%r8), %ymm9, %ymm9 +vmovdqa 6912(%r8), %ymm4 +vmovdqa 7616(%r8), %ymm10 +vpaddw 7264(%r8), %ymm4, %ymm4 +vpaddw 7968(%r8), %ymm10, %ymm10 +vpmullw %ymm0, %ymm6, %ymm12 +vmovdqa %ymm12, 6272(%r8) +vpmullw %ymm0, %ymm7, %ymm13 +vpmullw %ymm1, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6304(%r8) +vpmullw %ymm0, %ymm8, %ymm12 +vpmullw %ymm1, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6336(%r8) +vpmullw %ymm0, %ymm9, %ymm13 +vpmullw %ymm1, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm2, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm6, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6368(%r8) +vpmullw %ymm0, %ymm10, %ymm12 +vpmullw %ymm1, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm2, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm3, %ymm7, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm6, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6400(%r8) +vpmullw %ymm1, %ymm10, %ymm13 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6432(%r8) +vpmullw %ymm2, %ymm10, %ymm12 +vpmullw %ymm3, %ymm9, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vpmullw %ymm4, %ymm8, %ymm15 +vpaddw %ymm12, %ymm15, %ymm12 +vmovdqa %ymm12, 6464(%r8) +vpmullw %ymm3, %ymm10, %ymm13 +vpmullw %ymm4, %ymm9, %ymm15 +vpaddw %ymm13, %ymm15, %ymm13 +vmovdqa %ymm13, 6496(%r8) +vpmullw %ymm4, %ymm10, %ymm12 +vmovdqa %ymm12, 6528(%r8) +vpaddw 6592(%r8), %ymm0, %ymm0 +vpaddw 7296(%r8), %ymm6, %ymm6 +vpaddw 6944(%r8), %ymm0, %ymm0 +vpaddw 7648(%r8), %ymm6, %ymm6 +vpaddw 6624(%r8), %ymm1, %ymm1 +vpaddw 7328(%r8), %ymm7, %ymm7 +vpaddw 6976(%r8), %ymm1, %ymm1 +vpaddw 7680(%r8), %ymm7, %ymm7 +vpaddw 6656(%r8), %ymm2, %ymm2 +vpaddw 7360(%r8), %ymm8, %ymm8 +vpaddw 7008(%r8), %ymm2, %ymm2 +vpaddw 7712(%r8), %ymm8, %ymm8 +vpaddw 6688(%r8), %ymm3, %ymm3 +vpaddw 7392(%r8), %ymm9, %ymm9 +vpaddw 7040(%r8), %ymm3, %ymm3 +vpaddw 7744(%r8), %ymm9, %ymm9 +vpaddw 6720(%r8), %ymm4, %ymm4 +vpaddw 7424(%r8), %ymm10, %ymm10 +vpaddw 7072(%r8), %ymm4, %ymm4 +vpaddw 7776(%r8), %ymm10, %ymm10 +vpmullw %ymm0, %ymm11, %ymm12 +vpmullw %ymm1, %ymm10, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm2, %ymm9, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm3, %ymm8, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm4, %ymm7, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpmullw %ymm5, %ymm6, %ymm15 +vpaddw %ymm15, %ymm12, %ymm12 +vpsubw 6048(%r8), %ymm12, %ymm12 +vpsubw 6432(%r8), %ymm12, %ymm12 +vmovdqa %ymm12, 6240(%r8) +vpmullw %ymm5, %ymm7, %ymm12 +vpmullw %ymm5, %ymm8, %ymm13 +vpmullw %ymm5, %ymm9, %ymm14 +vpmullw %ymm5, %ymm10, %ymm15 +vpmullw %ymm1, %ymm11, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm10, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm3, %ymm9, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm4, %ymm8, %ymm5 +vpaddw %ymm5, %ymm12, %ymm12 +vpmullw %ymm2, %ymm11, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm10, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm4, %ymm9, %ymm5 +vpaddw %ymm5, %ymm13, %ymm13 +vpmullw %ymm3, %ymm11, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm10, %ymm5 +vpaddw %ymm5, %ymm14, %ymm14 +vpmullw %ymm4, %ymm11, %ymm5 +vpaddw %ymm5, %ymm15, %ymm15 +vpmullw %ymm0, %ymm10, %ymm11 +vpmullw %ymm1, %ymm9, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm2, %ymm8, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm3, %ymm7, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm4, %ymm6, %ymm5 +vpaddw %ymm5, %ymm11, %ymm11 +vpmullw %ymm0, %ymm9, %ymm10 +vpmullw %ymm1, %ymm8, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm2, %ymm7, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm3, %ymm6, %ymm5 +vpaddw %ymm5, %ymm10, %ymm10 +vpmullw %ymm0, %ymm8, %ymm9 +vpmullw %ymm1, %ymm7, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm2, %ymm6, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vpmullw %ymm0, %ymm7, %ymm8 +vpmullw %ymm1, %ymm6, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vpmullw %ymm0, %ymm6, %ymm7 +vmovdqa 6080(%r8), %ymm0 +vpsubw 6272(%r8), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm6 +vpsubw 6464(%r8), %ymm6, %ymm6 +vmovdqa %ymm6, 6272(%r8) +vpaddw %ymm7, %ymm0, %ymm0 +vpsubw 5888(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 6080(%r8) +vmovdqa 6112(%r8), %ymm1 +vpsubw 6304(%r8), %ymm1, %ymm1 +vpsubw %ymm1, %ymm13, %ymm7 +vpsubw 6496(%r8), %ymm7, %ymm7 +vmovdqa %ymm7, 6304(%r8) +vpaddw %ymm8, %ymm1, %ymm1 +vpsubw 5920(%r8), %ymm1, %ymm1 +vmovdqa %ymm1, 6112(%r8) +vmovdqa 6144(%r8), %ymm2 +vpsubw 6336(%r8), %ymm2, %ymm2 +vpsubw %ymm2, %ymm14, %ymm8 +vpsubw 6528(%r8), %ymm8, %ymm8 +vmovdqa %ymm8, 6336(%r8) +vpaddw %ymm9, %ymm2, %ymm2 +vpsubw 5952(%r8), %ymm2, %ymm2 +vmovdqa %ymm2, 6144(%r8) +vmovdqa 6176(%r8), %ymm3 +vpsubw 6368(%r8), %ymm3, %ymm3 +vpsubw %ymm3, %ymm15, %ymm9 +vmovdqa %ymm9, 6368(%r8) +vpaddw %ymm10, %ymm3, %ymm3 +vpsubw 5984(%r8), %ymm3, %ymm3 +vmovdqa %ymm3, 6176(%r8) +vmovdqa 6208(%r8), %ymm4 +vpsubw 6400(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vpsubw 6016(%r8), %ymm4, %ymm4 +vmovdqa %ymm4, 6208(%r8) +vmovdqa 8352(%r8), %ymm0 +vpsubw 8704(%r8), %ymm0, %ymm0 +vmovdqa 6240(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9056(%r8), %ymm1, %ymm6 +vpsubw 8000(%r8), %ymm0, %ymm0 +vpaddw 5888(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8352(%r8) +vmovdqa 8384(%r8), %ymm0 +vpsubw 8736(%r8), %ymm0, %ymm0 +vmovdqa 6272(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9088(%r8), %ymm1, %ymm7 +vpsubw 8032(%r8), %ymm0, %ymm0 +vpaddw 5920(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8384(%r8) +vmovdqa 8416(%r8), %ymm0 +vpsubw 8768(%r8), %ymm0, %ymm0 +vmovdqa 6304(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9120(%r8), %ymm1, %ymm8 +vpsubw 8064(%r8), %ymm0, %ymm0 +vpaddw 5952(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8416(%r8) +vmovdqa 8448(%r8), %ymm0 +vpsubw 8800(%r8), %ymm0, %ymm0 +vmovdqa 6336(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9152(%r8), %ymm1, %ymm9 +vpsubw 8096(%r8), %ymm0, %ymm0 +vpaddw 5984(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8448(%r8) +vmovdqa 8480(%r8), %ymm0 +vpsubw 8832(%r8), %ymm0, %ymm0 +vmovdqa 6368(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9184(%r8), %ymm1, %ymm10 +vpsubw 8128(%r8), %ymm0, %ymm0 +vpaddw 6016(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8480(%r8) +vmovdqa 8512(%r8), %ymm0 +vpsubw 8864(%r8), %ymm0, %ymm0 +vmovdqa 6400(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9216(%r8), %ymm1, %ymm11 +vpsubw 8160(%r8), %ymm0, %ymm0 +vpaddw 6048(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8512(%r8) +vmovdqa 8544(%r8), %ymm0 +vpsubw 8896(%r8), %ymm0, %ymm0 +vmovdqa 6432(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9248(%r8), %ymm1, %ymm12 +vpsubw 8192(%r8), %ymm0, %ymm0 +vpaddw 6080(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8544(%r8) +vmovdqa 8576(%r8), %ymm0 +vpsubw 8928(%r8), %ymm0, %ymm0 +vmovdqa 6464(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9280(%r8), %ymm1, %ymm13 +vpsubw 8224(%r8), %ymm0, %ymm0 +vpaddw 6112(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8576(%r8) +vmovdqa 8608(%r8), %ymm0 +vpsubw 8960(%r8), %ymm0, %ymm0 +vmovdqa 6496(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9312(%r8), %ymm1, %ymm14 +vpsubw 8256(%r8), %ymm0, %ymm0 +vpaddw 6144(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8608(%r8) +vmovdqa 8640(%r8), %ymm0 +vpsubw 8992(%r8), %ymm0, %ymm0 +vmovdqa 6528(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 9344(%r8), %ymm1, %ymm15 +vpsubw 8288(%r8), %ymm0, %ymm0 +vpaddw 6176(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 8640(%r8) +vmovdqa 6208(%r8), %ymm0 +vpsubw 8320(%r8), %ymm0, %ymm0 +vpsubw 9024(%r8), %ymm0, %ymm0 +vpsubw 3488(%r10), %ymm0, %ymm0 +vpsubw 4896(%r10), %ymm0, %ymm0 +vmovdqa %ymm0, 4192(%r10) +vmovdqa 3520(%r10), %ymm0 +vpsubw 4224(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm6, %ymm6 +vpsubw 4928(%r10), %ymm6, %ymm6 +vpsubw 2816(%r10), %ymm0, %ymm0 +vpaddw 8000(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3520(%r10) +vmovdqa %ymm6, 4224(%r10) +vmovdqa 3552(%r10), %ymm0 +vpsubw 4256(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm7, %ymm7 +vpsubw 4960(%r10), %ymm7, %ymm7 +vpsubw 2848(%r10), %ymm0, %ymm0 +vpaddw 8032(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3552(%r10) +vmovdqa %ymm7, 4256(%r10) +vmovdqa 3584(%r10), %ymm0 +vpsubw 4288(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm8, %ymm8 +vpsubw 4992(%r10), %ymm8, %ymm8 +vpsubw 2880(%r10), %ymm0, %ymm0 +vpaddw 8064(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3584(%r10) +vmovdqa %ymm8, 4288(%r10) +vmovdqa 3616(%r10), %ymm0 +vpsubw 4320(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm9, %ymm9 +vpsubw 5024(%r10), %ymm9, %ymm9 +vpsubw 2912(%r10), %ymm0, %ymm0 +vpaddw 8096(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3616(%r10) +vmovdqa %ymm9, 4320(%r10) +vmovdqa 3648(%r10), %ymm0 +vpsubw 4352(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm10, %ymm10 +vpsubw 5056(%r10), %ymm10, %ymm10 +vpsubw 2944(%r10), %ymm0, %ymm0 +vpaddw 8128(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3648(%r10) +vmovdqa %ymm10, 4352(%r10) +vmovdqa 3680(%r10), %ymm0 +vpsubw 4384(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm11, %ymm11 +vpsubw 5088(%r10), %ymm11, %ymm11 +vpsubw 2976(%r10), %ymm0, %ymm0 +vpaddw 8160(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3680(%r10) +vmovdqa %ymm11, 4384(%r10) +vmovdqa 3712(%r10), %ymm0 +vpsubw 4416(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm12, %ymm12 +vpsubw 5120(%r10), %ymm12, %ymm12 +vpsubw 3008(%r10), %ymm0, %ymm0 +vpaddw 8192(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3712(%r10) +vmovdqa %ymm12, 4416(%r10) +vmovdqa 3744(%r10), %ymm0 +vpsubw 4448(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm13, %ymm13 +vpsubw 5152(%r10), %ymm13, %ymm13 +vpsubw 3040(%r10), %ymm0, %ymm0 +vpaddw 8224(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3744(%r10) +vmovdqa %ymm13, 4448(%r10) +vmovdqa 3776(%r10), %ymm0 +vpsubw 4480(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm14, %ymm14 +vpsubw 5184(%r10), %ymm14, %ymm14 +vpsubw 3072(%r10), %ymm0, %ymm0 +vpaddw 8256(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3776(%r10) +vmovdqa %ymm14, 4480(%r10) +vmovdqa 3808(%r10), %ymm0 +vpsubw 4512(%r10), %ymm0, %ymm0 +vpsubw %ymm0, %ymm15, %ymm15 +vpsubw 5216(%r10), %ymm15, %ymm15 +vpsubw 3104(%r10), %ymm0, %ymm0 +vpaddw 8288(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3808(%r10) +vmovdqa %ymm15, 4512(%r10) +vmovdqa 3840(%r10), %ymm0 +vpsubw 4544(%r10), %ymm0, %ymm0 +vmovdqa 9024(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5248(%r10), %ymm1, %ymm1 +vpsubw 3136(%r10), %ymm0, %ymm0 +vpaddw 8320(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3840(%r10) +vmovdqa %ymm1, 4544(%r10) +vmovdqa 3872(%r10), %ymm0 +vpsubw 4576(%r10), %ymm0, %ymm0 +vmovdqa 9056(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5280(%r10), %ymm1, %ymm1 +vpsubw 3168(%r10), %ymm0, %ymm0 +vpaddw 8352(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3872(%r10) +vmovdqa %ymm1, 4576(%r10) +vmovdqa 3904(%r10), %ymm0 +vpsubw 4608(%r10), %ymm0, %ymm0 +vmovdqa 9088(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5312(%r10), %ymm1, %ymm1 +vpsubw 3200(%r10), %ymm0, %ymm0 +vpaddw 8384(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3904(%r10) +vmovdqa %ymm1, 4608(%r10) +vmovdqa 3936(%r10), %ymm0 +vpsubw 4640(%r10), %ymm0, %ymm0 +vmovdqa 9120(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5344(%r10), %ymm1, %ymm1 +vpsubw 3232(%r10), %ymm0, %ymm0 +vpaddw 8416(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3936(%r10) +vmovdqa %ymm1, 4640(%r10) +vmovdqa 3968(%r10), %ymm0 +vpsubw 4672(%r10), %ymm0, %ymm0 +vmovdqa 9152(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5376(%r10), %ymm1, %ymm1 +vpsubw 3264(%r10), %ymm0, %ymm0 +vpaddw 8448(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 3968(%r10) +vmovdqa %ymm1, 4672(%r10) +vmovdqa 4000(%r10), %ymm0 +vpsubw 4704(%r10), %ymm0, %ymm0 +vmovdqa 9184(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5408(%r10), %ymm1, %ymm1 +vpsubw 3296(%r10), %ymm0, %ymm0 +vpaddw 8480(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4000(%r10) +vmovdqa %ymm1, 4704(%r10) +vmovdqa 4032(%r10), %ymm0 +vpsubw 4736(%r10), %ymm0, %ymm0 +vmovdqa 9216(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5440(%r10), %ymm1, %ymm1 +vpsubw 3328(%r10), %ymm0, %ymm0 +vpaddw 8512(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4032(%r10) +vmovdqa %ymm1, 4736(%r10) +vmovdqa 4064(%r10), %ymm0 +vpsubw 4768(%r10), %ymm0, %ymm0 +vmovdqa 9248(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5472(%r10), %ymm1, %ymm1 +vpsubw 3360(%r10), %ymm0, %ymm0 +vpaddw 8544(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4064(%r10) +vmovdqa %ymm1, 4768(%r10) +vmovdqa 4096(%r10), %ymm0 +vpsubw 4800(%r10), %ymm0, %ymm0 +vmovdqa 9280(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5504(%r10), %ymm1, %ymm1 +vpsubw 3392(%r10), %ymm0, %ymm0 +vpaddw 8576(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4096(%r10) +vmovdqa %ymm1, 4800(%r10) +vmovdqa 4128(%r10), %ymm0 +vpsubw 4832(%r10), %ymm0, %ymm0 +vmovdqa 9312(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5536(%r10), %ymm1, %ymm1 +vpsubw 3424(%r10), %ymm0, %ymm0 +vpaddw 8608(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4128(%r10) +vmovdqa %ymm1, 4832(%r10) +vmovdqa 4160(%r10), %ymm0 +vpsubw 4864(%r10), %ymm0, %ymm0 +vmovdqa 9344(%r8), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5568(%r10), %ymm1, %ymm1 +vpsubw 3456(%r10), %ymm0, %ymm0 +vpaddw 8640(%r8), %ymm0, %ymm0 +vmovdqa %ymm0, 4160(%r10) +vmovdqa %ymm1, 4864(%r10) +vpxor %ymm1, %ymm1, %ymm1 +vmovdqa %ymm1, 5600(%r10) +subq $32, %r8 +vmovdqa 2816(%r10), %ymm0 +vmovdqa 2880(%r10), %ymm1 +vmovdqa 2944(%r10), %ymm2 +vmovdqa 3008(%r10), %ymm3 +vpunpcklwd 2848(%r10), %ymm0, %ymm4 +vpunpckhwd 2848(%r10), %ymm0, %ymm5 +vpunpcklwd 2912(%r10), %ymm1, %ymm6 +vpunpckhwd 2912(%r10), %ymm1, %ymm7 +vpunpcklwd 2976(%r10), %ymm2, %ymm8 +vpunpckhwd 2976(%r10), %ymm2, %ymm9 +vpunpcklwd 3040(%r10), %ymm3, %ymm10 +vpunpckhwd 3040(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 3072(%r10), %ymm0 +vmovdqa 3136(%r10), %ymm1 +vmovdqa 3200(%r10), %ymm2 +vmovdqa 3264(%r10), %ymm3 +vpunpcklwd 3104(%r10), %ymm0, %ymm12 +vpunpckhwd 3104(%r10), %ymm0, %ymm13 +vpunpcklwd 3168(%r10), %ymm1, %ymm14 +vpunpckhwd 3168(%r10), %ymm1, %ymm15 +vpunpcklwd 3232(%r10), %ymm2, %ymm0 +vpunpckhwd 3232(%r10), %ymm2, %ymm1 +vpunpcklwd 3296(%r10), %ymm3, %ymm2 +vpunpckhwd 3296(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 0(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 192(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 384(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 576(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 768(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 960(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1152(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1536(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1728(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 1920(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2112(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2304(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2496(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2688(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1344(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 2880(%r12) +vmovdqa 3328(%r10), %ymm0 +vmovdqa 3392(%r10), %ymm1 +vmovdqa 3456(%r10), %ymm2 +vmovdqa 3520(%r10), %ymm3 +vpunpcklwd 3360(%r10), %ymm0, %ymm4 +vpunpckhwd 3360(%r10), %ymm0, %ymm5 +vpunpcklwd 3424(%r10), %ymm1, %ymm6 +vpunpckhwd 3424(%r10), %ymm1, %ymm7 +vpunpcklwd 3488(%r10), %ymm2, %ymm8 +vpunpckhwd 3488(%r10), %ymm2, %ymm9 +vpunpcklwd 3552(%r10), %ymm3, %ymm10 +vpunpckhwd 3552(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 3584(%r10), %ymm0 +vmovdqa 3648(%r10), %ymm1 +vmovdqa 3712(%r10), %ymm2 +vmovdqa 3776(%r10), %ymm3 +vpunpcklwd 3616(%r10), %ymm0, %ymm12 +vpunpckhwd 3616(%r10), %ymm0, %ymm13 +vpunpcklwd 3680(%r10), %ymm1, %ymm14 +vpunpckhwd 3680(%r10), %ymm1, %ymm15 +vpunpcklwd 3744(%r10), %ymm2, %ymm0 +vpunpckhwd 3744(%r10), %ymm2, %ymm1 +vpunpcklwd 3808(%r10), %ymm3, %ymm2 +vpunpckhwd 3808(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 32(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 224(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 416(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 608(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 800(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 992(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1184(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1568(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1760(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 1952(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2144(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2336(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2528(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2720(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1376(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 2912(%r12) +vmovdqa 3840(%r10), %ymm0 +vmovdqa 3904(%r10), %ymm1 +vmovdqa 3968(%r10), %ymm2 +vmovdqa 4032(%r10), %ymm3 +vpunpcklwd 3872(%r10), %ymm0, %ymm4 +vpunpckhwd 3872(%r10), %ymm0, %ymm5 +vpunpcklwd 3936(%r10), %ymm1, %ymm6 +vpunpckhwd 3936(%r10), %ymm1, %ymm7 +vpunpcklwd 4000(%r10), %ymm2, %ymm8 +vpunpckhwd 4000(%r10), %ymm2, %ymm9 +vpunpcklwd 4064(%r10), %ymm3, %ymm10 +vpunpckhwd 4064(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 4096(%r10), %ymm0 +vmovdqa 4160(%r10), %ymm1 +vmovdqa 4224(%r10), %ymm2 +vmovdqa 4288(%r10), %ymm3 +vpunpcklwd 4128(%r10), %ymm0, %ymm12 +vpunpckhwd 4128(%r10), %ymm0, %ymm13 +vpunpcklwd 4192(%r10), %ymm1, %ymm14 +vpunpckhwd 4192(%r10), %ymm1, %ymm15 +vpunpcklwd 4256(%r10), %ymm2, %ymm0 +vpunpckhwd 4256(%r10), %ymm2, %ymm1 +vpunpcklwd 4320(%r10), %ymm3, %ymm2 +vpunpckhwd 4320(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 64(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 256(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 448(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 640(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 832(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1024(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1216(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1600(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1792(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 1984(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2176(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2368(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2560(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2752(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1408(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 2944(%r12) +vmovdqa 4224(%r10), %ymm0 +vmovdqa 4288(%r10), %ymm1 +vmovdqa 4352(%r10), %ymm2 +vmovdqa 4416(%r10), %ymm3 +vpunpcklwd 4256(%r10), %ymm0, %ymm4 +vpunpckhwd 4256(%r10), %ymm0, %ymm5 +vpunpcklwd 4320(%r10), %ymm1, %ymm6 +vpunpckhwd 4320(%r10), %ymm1, %ymm7 +vpunpcklwd 4384(%r10), %ymm2, %ymm8 +vpunpckhwd 4384(%r10), %ymm2, %ymm9 +vpunpcklwd 4448(%r10), %ymm3, %ymm10 +vpunpckhwd 4448(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 4480(%r10), %ymm0 +vmovdqa 4544(%r10), %ymm1 +vmovdqa 4608(%r10), %ymm2 +vmovdqa 4672(%r10), %ymm3 +vpunpcklwd 4512(%r10), %ymm0, %ymm12 +vpunpckhwd 4512(%r10), %ymm0, %ymm13 +vpunpcklwd 4576(%r10), %ymm1, %ymm14 +vpunpckhwd 4576(%r10), %ymm1, %ymm15 +vpunpcklwd 4640(%r10), %ymm2, %ymm0 +vpunpckhwd 4640(%r10), %ymm2, %ymm1 +vpunpcklwd 4704(%r10), %ymm3, %ymm2 +vpunpckhwd 4704(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 96(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 288(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 480(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 672(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 864(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1056(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1248(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1632(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1824(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 2016(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2208(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2400(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2592(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2784(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1440(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 2976(%r12) +vmovdqa 4736(%r10), %ymm0 +vmovdqa 4800(%r10), %ymm1 +vmovdqa 4864(%r10), %ymm2 +vmovdqa 4928(%r10), %ymm3 +vpunpcklwd 4768(%r10), %ymm0, %ymm4 +vpunpckhwd 4768(%r10), %ymm0, %ymm5 +vpunpcklwd 4832(%r10), %ymm1, %ymm6 +vpunpckhwd 4832(%r10), %ymm1, %ymm7 +vpunpcklwd 4896(%r10), %ymm2, %ymm8 +vpunpckhwd 4896(%r10), %ymm2, %ymm9 +vpunpcklwd 4960(%r10), %ymm3, %ymm10 +vpunpckhwd 4960(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 4992(%r10), %ymm0 +vmovdqa 5056(%r10), %ymm1 +vmovdqa 5120(%r10), %ymm2 +vmovdqa 5184(%r10), %ymm3 +vpunpcklwd 5024(%r10), %ymm0, %ymm12 +vpunpckhwd 5024(%r10), %ymm0, %ymm13 +vpunpcklwd 5088(%r10), %ymm1, %ymm14 +vpunpckhwd 5088(%r10), %ymm1, %ymm15 +vpunpcklwd 5152(%r10), %ymm2, %ymm0 +vpunpckhwd 5152(%r10), %ymm2, %ymm1 +vpunpcklwd 5216(%r10), %ymm3, %ymm2 +vpunpckhwd 5216(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 128(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 320(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 512(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 704(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 896(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1088(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1280(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1664(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1856(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 2048(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2240(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2432(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2624(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2816(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1472(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 3008(%r12) +vmovdqa 5248(%r10), %ymm0 +vmovdqa 5312(%r10), %ymm1 +vmovdqa 5376(%r10), %ymm2 +vmovdqa 5440(%r10), %ymm3 +vpunpcklwd 5280(%r10), %ymm0, %ymm4 +vpunpckhwd 5280(%r10), %ymm0, %ymm5 +vpunpcklwd 5344(%r10), %ymm1, %ymm6 +vpunpckhwd 5344(%r10), %ymm1, %ymm7 +vpunpcklwd 5408(%r10), %ymm2, %ymm8 +vpunpckhwd 5408(%r10), %ymm2, %ymm9 +vpunpcklwd 5472(%r10), %ymm3, %ymm10 +vpunpckhwd 5472(%r10), %ymm3, %ymm11 +vpunpckldq %ymm6, %ymm4, %ymm0 +vpunpckhdq %ymm6, %ymm4, %ymm1 +vpunpckldq %ymm7, %ymm5, %ymm2 +vpunpckhdq %ymm7, %ymm5, %ymm3 +vpunpckldq %ymm10, %ymm8, %ymm12 +vpunpckhdq %ymm10, %ymm8, %ymm13 +vpunpckldq %ymm11, %ymm9, %ymm14 +vpunpckhdq %ymm11, %ymm9, %ymm15 +vpunpcklqdq %ymm12, %ymm0, %ymm4 +vpunpckhqdq %ymm12, %ymm0, %ymm5 +vpunpcklqdq %ymm13, %ymm1, %ymm6 +vpunpckhqdq %ymm13, %ymm1, %ymm7 +vpunpcklqdq %ymm14, %ymm2, %ymm8 +vpunpckhqdq %ymm14, %ymm2, %ymm9 +vpunpcklqdq %ymm15, %ymm3, %ymm10 +vpunpckhqdq %ymm15, %ymm3, %ymm11 +vmovdqa 5504(%r10), %ymm0 +vmovdqa 5568(%r10), %ymm1 +vmovdqa 5632(%r10), %ymm2 +vmovdqa 5696(%r10), %ymm3 +vpunpcklwd 5536(%r10), %ymm0, %ymm12 +vpunpckhwd 5536(%r10), %ymm0, %ymm13 +vpunpcklwd 5600(%r10), %ymm1, %ymm14 +vpunpckhwd 5600(%r10), %ymm1, %ymm15 +vpunpcklwd 5664(%r10), %ymm2, %ymm0 +vpunpckhwd 5664(%r10), %ymm2, %ymm1 +vpunpcklwd 5728(%r10), %ymm3, %ymm2 +vpunpckhwd 5728(%r10), %ymm3, %ymm3 +vmovdqa %ymm11, 0(%r8) +vpunpckldq %ymm14, %ymm12, %ymm11 +vpunpckhdq %ymm14, %ymm12, %ymm12 +vpunpckldq %ymm15, %ymm13, %ymm14 +vpunpckhdq %ymm15, %ymm13, %ymm15 +vpunpckldq %ymm2, %ymm0, %ymm13 +vpunpckhdq %ymm2, %ymm0, %ymm0 +vpunpckldq %ymm3, %ymm1, %ymm2 +vpunpckhdq %ymm3, %ymm1, %ymm1 +vpunpcklqdq %ymm13, %ymm11, %ymm3 +vpunpckhqdq %ymm13, %ymm11, %ymm13 +vpunpcklqdq %ymm0, %ymm12, %ymm11 +vpunpckhqdq %ymm0, %ymm12, %ymm0 +vpunpcklqdq %ymm2, %ymm14, %ymm12 +vpunpckhqdq %ymm2, %ymm14, %ymm2 +vpunpcklqdq %ymm1, %ymm15, %ymm14 +vpunpckhqdq %ymm1, %ymm15, %ymm1 +vinserti128 $1, %xmm3, %ymm4, %ymm15 +vmovdqa %ymm15, 160(%r12) +vinserti128 $1, %xmm13, %ymm5, %ymm15 +vmovdqa %ymm15, 352(%r12) +vinserti128 $1, %xmm11, %ymm6, %ymm15 +vmovdqa %ymm15, 544(%r12) +vinserti128 $1, %xmm0, %ymm7, %ymm15 +vmovdqa %ymm15, 736(%r12) +vinserti128 $1, %xmm12, %ymm8, %ymm15 +vmovdqa %ymm15, 928(%r12) +vinserti128 $1, %xmm2, %ymm9, %ymm15 +vmovdqa %ymm15, 1120(%r12) +vinserti128 $1, %xmm14, %ymm10, %ymm15 +vmovdqa %ymm15, 1312(%r12) +vpermq $78, %ymm4, %ymm4 +vpermq $78, %ymm5, %ymm5 +vpermq $78, %ymm6, %ymm6 +vpermq $78, %ymm7, %ymm7 +vpermq $78, %ymm8, %ymm8 +vpermq $78, %ymm9, %ymm9 +vpermq $78, %ymm10, %ymm10 +vinserti128 $0, %xmm4, %ymm3, %ymm15 +vmovdqa %ymm15, 1696(%r12) +vinserti128 $0, %xmm5, %ymm13, %ymm15 +vmovdqa %ymm15, 1888(%r12) +vinserti128 $0, %xmm6, %ymm11, %ymm15 +vmovdqa %ymm15, 2080(%r12) +vinserti128 $0, %xmm7, %ymm0, %ymm15 +vmovdqa %ymm15, 2272(%r12) +vinserti128 $0, %xmm8, %ymm12, %ymm15 +vmovdqa %ymm15, 2464(%r12) +vinserti128 $0, %xmm9, %ymm2, %ymm15 +vmovdqa %ymm15, 2656(%r12) +vinserti128 $0, %xmm10, %ymm14, %ymm15 +vmovdqa %ymm15, 2848(%r12) +vmovdqa 0(%r8), %ymm11 +vinserti128 $1, %xmm1, %ymm11, %ymm14 +vmovdqa %ymm14, 1504(%r12) +vpermq $78, %ymm11, %ymm11 +vinserti128 $0, %xmm11, %ymm1, %ymm1 +vmovdqa %ymm1, 3040(%r12) +addq $32, %r8 +add $1536, %rax +add $1536, %r11 +add $3072, %r12 +dec %ecx +jnz karatsuba_loop_4eced63f144beffcb0247f9c6f67d165 +sub $12288, %r12 +add $9408-2400, %r8 +vpxor %ymm0, %ymm0, %ymm0 +vmovdqa %ymm0, 1792(%r8) +vmovdqa %ymm0, 1824(%r8) +vmovdqa %ymm0, 1856(%r8) +vmovdqa %ymm0, 1888(%r8) +vmovdqa %ymm0, 1920(%r8) +vmovdqa %ymm0, 1952(%r8) +vmovdqa %ymm0, 1984(%r8) +vmovdqa %ymm0, 2016(%r8) +vmovdqa %ymm0, 2048(%r8) +vmovdqa %ymm0, 2080(%r8) +vmovdqa %ymm0, 2112(%r8) +vmovdqa %ymm0, 2144(%r8) +vmovdqa %ymm0, 2176(%r8) +vmovdqa %ymm0, 2208(%r8) +vmovdqa %ymm0, 2240(%r8) +vmovdqa %ymm0, 2272(%r8) +vmovdqa %ymm0, 2304(%r8) +vmovdqa %ymm0, 2336(%r8) +vmovdqa %ymm0, 2368(%r8) +vmovdqa %ymm0, 2400(%r8) +vmovdqa %ymm0, 2432(%r8) +vmovdqa %ymm0, 2464(%r8) +vmovdqa %ymm0, 2496(%r8) +vmovdqa %ymm0, 2528(%r8) +vmovdqa %ymm0, 2560(%r8) +vmovdqa %ymm0, 2592(%r8) +vmovdqa %ymm0, 2624(%r8) +vmovdqa %ymm0, 2656(%r8) +vmovdqa %ymm0, 2688(%r8) +vmovdqa %ymm0, 2720(%r8) +vmovdqa %ymm0, 2752(%r8) +vmovdqa %ymm0, 2784(%r8) +vmovdqa const729(%rip), %ymm15 +vmovdqa const3_inv(%rip), %ymm14 +vmovdqa const5_inv(%rip), %ymm13 +vmovdqa const9(%rip), %ymm12 +vmovdqa 96(%r12), %ymm0 +vpsubw 192(%r12), %ymm0, %ymm0 +vmovdqa 480(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 288(%r12), %ymm1, %ymm1 +vpsubw 0(%r12), %ymm0, %ymm0 +vpaddw 384(%r12), %ymm0, %ymm0 +vmovdqa 672(%r12), %ymm2 +vpsubw 768(%r12), %ymm2, %ymm2 +vmovdqa 1056(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 864(%r12), %ymm3, %ymm3 +vpsubw 576(%r12), %ymm2, %ymm2 +vpaddw 960(%r12), %ymm2, %ymm2 +vmovdqa 1248(%r12), %ymm4 +vpsubw 1344(%r12), %ymm4, %ymm4 +vmovdqa 1632(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 1440(%r12), %ymm5, %ymm5 +vpsubw 1152(%r12), %ymm4, %ymm4 +vpaddw 1536(%r12), %ymm4, %ymm4 +vpsubw 576(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 0(%r12), %ymm1, %ymm1 +vpaddw 1152(%r12), %ymm1, %ymm1 +vmovdqa 288(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 1440(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 864(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 0(%r12), %ymm8 +vmovdqa 864(%r12), %ymm9 +vmovdqa %ymm8, 0(%r8) +vmovdqa %ymm0, 32(%r8) +vmovdqa %ymm1, 64(%r8) +vmovdqa %ymm7, 96(%r8) +vmovdqa %ymm5, 128(%r8) +vmovdqa %ymm2, 160(%r8) +vmovdqa %ymm3, 192(%r8) +vmovdqa %ymm9, 224(%r8) +vmovdqa 1824(%r12), %ymm0 +vpsubw 1920(%r12), %ymm0, %ymm0 +vmovdqa 2208(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 2016(%r12), %ymm1, %ymm1 +vpsubw 1728(%r12), %ymm0, %ymm0 +vpaddw 2112(%r12), %ymm0, %ymm0 +vmovdqa 2400(%r12), %ymm2 +vpsubw 2496(%r12), %ymm2, %ymm2 +vmovdqa 2784(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 2592(%r12), %ymm3, %ymm3 +vpsubw 2304(%r12), %ymm2, %ymm2 +vpaddw 2688(%r12), %ymm2, %ymm2 +vmovdqa 2976(%r12), %ymm4 +vpsubw 3072(%r12), %ymm4, %ymm4 +vmovdqa 3360(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 3168(%r12), %ymm5, %ymm5 +vpsubw 2880(%r12), %ymm4, %ymm4 +vpaddw 3264(%r12), %ymm4, %ymm4 +vpsubw 2304(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 1728(%r12), %ymm1, %ymm1 +vpaddw 2880(%r12), %ymm1, %ymm1 +vmovdqa 2016(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 3168(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 2592(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 1728(%r12), %ymm8 +vmovdqa 2592(%r12), %ymm9 +vmovdqa %ymm8, 256(%r8) +vmovdqa %ymm0, 288(%r8) +vmovdqa %ymm1, 320(%r8) +vmovdqa %ymm7, 352(%r8) +vmovdqa %ymm5, 384(%r8) +vmovdqa %ymm2, 416(%r8) +vmovdqa %ymm3, 448(%r8) +vmovdqa %ymm9, 480(%r8) +vmovdqa 3552(%r12), %ymm0 +vpsubw 3648(%r12), %ymm0, %ymm0 +vmovdqa 3936(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3744(%r12), %ymm1, %ymm1 +vpsubw 3456(%r12), %ymm0, %ymm0 +vpaddw 3840(%r12), %ymm0, %ymm0 +vmovdqa 4128(%r12), %ymm2 +vpsubw 4224(%r12), %ymm2, %ymm2 +vmovdqa 4512(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 4320(%r12), %ymm3, %ymm3 +vpsubw 4032(%r12), %ymm2, %ymm2 +vpaddw 4416(%r12), %ymm2, %ymm2 +vmovdqa 4704(%r12), %ymm4 +vpsubw 4800(%r12), %ymm4, %ymm4 +vmovdqa 5088(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 4896(%r12), %ymm5, %ymm5 +vpsubw 4608(%r12), %ymm4, %ymm4 +vpaddw 4992(%r12), %ymm4, %ymm4 +vpsubw 4032(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 3456(%r12), %ymm1, %ymm1 +vpaddw 4608(%r12), %ymm1, %ymm1 +vmovdqa 3744(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 4896(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 4320(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 3456(%r12), %ymm8 +vmovdqa 4320(%r12), %ymm9 +vmovdqa %ymm8, 512(%r8) +vmovdqa %ymm0, 544(%r8) +vmovdqa %ymm1, 576(%r8) +vmovdqa %ymm7, 608(%r8) +vmovdqa %ymm5, 640(%r8) +vmovdqa %ymm2, 672(%r8) +vmovdqa %ymm3, 704(%r8) +vmovdqa %ymm9, 736(%r8) +vmovdqa 5280(%r12), %ymm0 +vpsubw 5376(%r12), %ymm0, %ymm0 +vmovdqa 5664(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5472(%r12), %ymm1, %ymm1 +vpsubw 5184(%r12), %ymm0, %ymm0 +vpaddw 5568(%r12), %ymm0, %ymm0 +vmovdqa 5856(%r12), %ymm2 +vpsubw 5952(%r12), %ymm2, %ymm2 +vmovdqa 6240(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 6048(%r12), %ymm3, %ymm3 +vpsubw 5760(%r12), %ymm2, %ymm2 +vpaddw 6144(%r12), %ymm2, %ymm2 +vmovdqa 6432(%r12), %ymm4 +vpsubw 6528(%r12), %ymm4, %ymm4 +vmovdqa 6816(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 6624(%r12), %ymm5, %ymm5 +vpsubw 6336(%r12), %ymm4, %ymm4 +vpaddw 6720(%r12), %ymm4, %ymm4 +vpsubw 5760(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 5184(%r12), %ymm1, %ymm1 +vpaddw 6336(%r12), %ymm1, %ymm1 +vmovdqa 5472(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 6624(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 6048(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 5184(%r12), %ymm8 +vmovdqa 6048(%r12), %ymm9 +vmovdqa %ymm8, 768(%r8) +vmovdqa %ymm0, 800(%r8) +vmovdqa %ymm1, 832(%r8) +vmovdqa %ymm7, 864(%r8) +vmovdqa %ymm5, 896(%r8) +vmovdqa %ymm2, 928(%r8) +vmovdqa %ymm3, 960(%r8) +vmovdqa %ymm9, 992(%r8) +vmovdqa 7008(%r12), %ymm0 +vpsubw 7104(%r12), %ymm0, %ymm0 +vmovdqa 7392(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 7200(%r12), %ymm1, %ymm1 +vpsubw 6912(%r12), %ymm0, %ymm0 +vpaddw 7296(%r12), %ymm0, %ymm0 +vmovdqa 7584(%r12), %ymm2 +vpsubw 7680(%r12), %ymm2, %ymm2 +vmovdqa 7968(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 7776(%r12), %ymm3, %ymm3 +vpsubw 7488(%r12), %ymm2, %ymm2 +vpaddw 7872(%r12), %ymm2, %ymm2 +vmovdqa 8160(%r12), %ymm4 +vpsubw 8256(%r12), %ymm4, %ymm4 +vmovdqa 8544(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 8352(%r12), %ymm5, %ymm5 +vpsubw 8064(%r12), %ymm4, %ymm4 +vpaddw 8448(%r12), %ymm4, %ymm4 +vpsubw 7488(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 6912(%r12), %ymm1, %ymm1 +vpaddw 8064(%r12), %ymm1, %ymm1 +vmovdqa 7200(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 8352(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 7776(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 6912(%r12), %ymm8 +vmovdqa 7776(%r12), %ymm9 +vmovdqa %ymm8, 1024(%r8) +vmovdqa %ymm0, 1056(%r8) +vmovdqa %ymm1, 1088(%r8) +vmovdqa %ymm7, 1120(%r8) +vmovdqa %ymm5, 1152(%r8) +vmovdqa %ymm2, 1184(%r8) +vmovdqa %ymm3, 1216(%r8) +vmovdqa %ymm9, 1248(%r8) +vmovdqa 8736(%r12), %ymm0 +vpsubw 8832(%r12), %ymm0, %ymm0 +vmovdqa 9120(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 8928(%r12), %ymm1, %ymm1 +vpsubw 8640(%r12), %ymm0, %ymm0 +vpaddw 9024(%r12), %ymm0, %ymm0 +vmovdqa 9312(%r12), %ymm2 +vpsubw 9408(%r12), %ymm2, %ymm2 +vmovdqa 9696(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 9504(%r12), %ymm3, %ymm3 +vpsubw 9216(%r12), %ymm2, %ymm2 +vpaddw 9600(%r12), %ymm2, %ymm2 +vmovdqa 9888(%r12), %ymm4 +vpsubw 9984(%r12), %ymm4, %ymm4 +vmovdqa 10272(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 10080(%r12), %ymm5, %ymm5 +vpsubw 9792(%r12), %ymm4, %ymm4 +vpaddw 10176(%r12), %ymm4, %ymm4 +vpsubw 9216(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 8640(%r12), %ymm1, %ymm1 +vpaddw 9792(%r12), %ymm1, %ymm1 +vmovdqa 8928(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 10080(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 9504(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 8640(%r12), %ymm8 +vmovdqa 9504(%r12), %ymm9 +vmovdqa %ymm8, 1280(%r8) +vmovdqa %ymm0, 1312(%r8) +vmovdqa %ymm1, 1344(%r8) +vmovdqa %ymm7, 1376(%r8) +vmovdqa %ymm5, 1408(%r8) +vmovdqa %ymm2, 1440(%r8) +vmovdqa %ymm3, 1472(%r8) +vmovdqa %ymm9, 1504(%r8) +vmovdqa 10464(%r12), %ymm0 +vpsubw 10560(%r12), %ymm0, %ymm0 +vmovdqa 10848(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 10656(%r12), %ymm1, %ymm1 +vpsubw 10368(%r12), %ymm0, %ymm0 +vpaddw 10752(%r12), %ymm0, %ymm0 +vmovdqa 11040(%r12), %ymm2 +vpsubw 11136(%r12), %ymm2, %ymm2 +vmovdqa 11424(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 11232(%r12), %ymm3, %ymm3 +vpsubw 10944(%r12), %ymm2, %ymm2 +vpaddw 11328(%r12), %ymm2, %ymm2 +vmovdqa 11616(%r12), %ymm4 +vpsubw 11712(%r12), %ymm4, %ymm4 +vmovdqa 12000(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 11808(%r12), %ymm5, %ymm5 +vpsubw 11520(%r12), %ymm4, %ymm4 +vpaddw 11904(%r12), %ymm4, %ymm4 +vpsubw 10944(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 10368(%r12), %ymm1, %ymm1 +vpaddw 11520(%r12), %ymm1, %ymm1 +vmovdqa 10656(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 11808(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 11232(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 10368(%r12), %ymm8 +vmovdqa 11232(%r12), %ymm9 +vmovdqa %ymm8, 1536(%r8) +vmovdqa %ymm0, 1568(%r8) +vmovdqa %ymm1, 1600(%r8) +vmovdqa %ymm7, 1632(%r8) +vmovdqa %ymm5, 1664(%r8) +vmovdqa %ymm2, 1696(%r8) +vmovdqa %ymm3, 1728(%r8) +vmovdqa %ymm9, 1760(%r8) +vmovdqa 0(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm10 +vpunpckhwd const0(%rip), %ymm11, %ymm9 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm9, %ymm9 +vmovdqa 256(%r8), %ymm8 +vpunpcklwd const0(%rip), %ymm8, %ymm7 +vpunpckhwd const0(%rip), %ymm8, %ymm8 +vmovdqa 512(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm7, %ymm4 +vpaddd %ymm6, %ymm8, %ymm3 +vpsubd %ymm10, %ymm4, %ymm4 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm5, %ymm7, %ymm5 +vpsubd %ymm6, %ymm8, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1536(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm8 +vpunpckhwd const0(%rip), %ymm5, %ymm7 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm7, %ymm7 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm7, %ymm3, %ymm3 +vpsrld $1, %ymm4, %ymm4 +vpsrld $1, %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpackusdw %ymm3, %ymm4, %ymm3 +vmovdqa 768(%r8), %ymm4 +vpaddw 1024(%r8), %ymm4, %ymm7 +vpsubw 1024(%r8), %ymm4, %ymm4 +vpsrlw $2, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsllw $1, %ymm11, %ymm8 +vpsubw %ymm8, %ymm7, %ymm8 +vpsllw $7, %ymm5, %ymm7 +vpsubw %ymm7, %ymm8, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm3, %ymm7, %ymm7 +vmovdqa 1280(%r8), %ymm8 +vpsubw %ymm11, %ymm8, %ymm8 +vpmullw %ymm15, %ymm5, %ymm9 +vpsubw %ymm9, %ymm8, %ymm9 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm7, %ymm3, %ymm3 +vpmullw %ymm12, %ymm7, %ymm8 +vpaddw %ymm8, %ymm3, %ymm8 +vpmullw %ymm12, %ymm8, %ymm8 +vpsubw %ymm8, %ymm9, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm4, %ymm8, %ymm8 +vpsubw %ymm8, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpmullw %ymm13, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_3_5(%rip), %ymm7, %ymm9 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm10 +vpor %ymm10, %ymm7, %ymm7 +vpaddw %ymm7, %ymm11, %ymm11 +vmovdqa %xmm9, 2048(%r8) +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm9 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm10 +vpor %ymm10, %ymm8, %ymm8 +vpaddw %ymm8, %ymm6, %ymm6 +vmovdqa %xmm9, 2304(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm9 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm10 +vpor %ymm10, %ymm5, %ymm5 +vpaddw %ymm5, %ymm3, %ymm3 +vmovdqa %xmm9, 2560(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 0(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 352(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 704(%rdi) +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %ymm4, 1056(%rdi) +vmovdqa 32(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm8 +vpunpckhwd const0(%rip), %ymm5, %ymm7 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm7, %ymm7 +vmovdqa 288(%r8), %ymm4 +vpunpcklwd const0(%rip), %ymm4, %ymm3 +vpunpckhwd const0(%rip), %ymm4, %ymm4 +vmovdqa 544(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm3, %ymm9 +vpaddd %ymm6, %ymm4, %ymm10 +vpsubd %ymm8, %ymm9, %ymm9 +vpsubd %ymm7, %ymm10, %ymm10 +vpsubd %ymm11, %ymm3, %ymm11 +vpsubd %ymm6, %ymm4, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1568(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm3, %ymm3 +vpsubd %ymm4, %ymm9, %ymm9 +vpsubd %ymm3, %ymm10, %ymm10 +vpsrld $1, %ymm9, %ymm9 +vpsrld $1, %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpackusdw %ymm10, %ymm9, %ymm10 +vmovdqa 800(%r8), %ymm9 +vpaddw 1056(%r8), %ymm9, %ymm3 +vpsubw 1056(%r8), %ymm9, %ymm9 +vpsrlw $2, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsllw $1, %ymm5, %ymm4 +vpsubw %ymm4, %ymm3, %ymm4 +vpsllw $7, %ymm11, %ymm3 +vpsubw %ymm3, %ymm4, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm10, %ymm3, %ymm3 +vmovdqa 1312(%r8), %ymm4 +vpsubw %ymm5, %ymm4, %ymm4 +vpmullw %ymm15, %ymm11, %ymm7 +vpsubw %ymm7, %ymm4, %ymm7 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm3, %ymm10, %ymm10 +vpmullw %ymm12, %ymm3, %ymm4 +vpaddw %ymm4, %ymm10, %ymm4 +vpmullw %ymm12, %ymm4, %ymm4 +vpsubw %ymm4, %ymm7, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpmullw %ymm13, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_3_5(%rip), %ymm3, %ymm7 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm8 +vpor %ymm8, %ymm3, %ymm3 +vpaddw %ymm3, %ymm5, %ymm5 +vmovdqa %xmm7, 2080(%r8) +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm7 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm8 +vpor %ymm8, %ymm4, %ymm4 +vpaddw %ymm4, %ymm6, %ymm6 +vmovdqa %xmm7, 2336(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm7 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm8 +vpor %ymm8, %ymm11, %ymm11 +vpaddw %ymm11, %ymm10, %ymm10 +vmovdqa %xmm7, 2592(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 88(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 440(%rdi) +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 792(%rdi) +vpand mask_mod8192(%rip), %ymm9, %ymm9 +vmovdqu %ymm9, 1144(%rdi) +vmovdqa 64(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm3, %ymm3 +vmovdqa 320(%r8), %ymm9 +vpunpcklwd const0(%rip), %ymm9, %ymm10 +vpunpckhwd const0(%rip), %ymm9, %ymm9 +vmovdqa 576(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm10, %ymm7 +vpaddd %ymm6, %ymm9, %ymm8 +vpsubd %ymm4, %ymm7, %ymm7 +vpsubd %ymm3, %ymm8, %ymm8 +vpsubd %ymm5, %ymm10, %ymm5 +vpsubd %ymm6, %ymm9, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1600(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm9 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm10, %ymm10 +vpsubd %ymm9, %ymm7, %ymm7 +vpsubd %ymm10, %ymm8, %ymm8 +vpsrld $1, %ymm7, %ymm7 +vpsrld $1, %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpackusdw %ymm8, %ymm7, %ymm8 +vmovdqa 832(%r8), %ymm7 +vpaddw 1088(%r8), %ymm7, %ymm10 +vpsubw 1088(%r8), %ymm7, %ymm7 +vpsrlw $2, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsllw $1, %ymm11, %ymm9 +vpsubw %ymm9, %ymm10, %ymm9 +vpsllw $7, %ymm5, %ymm10 +vpsubw %ymm10, %ymm9, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm8, %ymm10, %ymm10 +vmovdqa 1344(%r8), %ymm9 +vpsubw %ymm11, %ymm9, %ymm9 +vpmullw %ymm15, %ymm5, %ymm3 +vpsubw %ymm3, %ymm9, %ymm3 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm10, %ymm8, %ymm8 +vpmullw %ymm12, %ymm10, %ymm9 +vpaddw %ymm9, %ymm8, %ymm9 +vpmullw %ymm12, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm7, %ymm9, %ymm9 +vpsubw %ymm9, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vpmullw %ymm13, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm3 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm10, %ymm10 +vpaddw %ymm10, %ymm11, %ymm11 +vmovdqa %xmm3, 2112(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_3_5(%rip), %ymm9, %ymm3 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm9, %ymm9 +vpaddw %ymm9, %ymm6, %ymm6 +vmovdqa %xmm3, 2368(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm3 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm5, %ymm5 +vpaddw %ymm5, %ymm8, %ymm8 +vmovdqa %xmm3, 2624(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 176(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 528(%rdi) +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %ymm8, 880(%rdi) +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %ymm7, 1232(%rdi) +vmovdqa 96(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm9 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm10, %ymm10 +vmovdqa 352(%r8), %ymm7 +vpunpcklwd const0(%rip), %ymm7, %ymm8 +vpunpckhwd const0(%rip), %ymm7, %ymm7 +vmovdqa 608(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm8, %ymm3 +vpaddd %ymm6, %ymm7, %ymm4 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm10, %ymm4, %ymm4 +vpsubd %ymm11, %ymm8, %ymm11 +vpsubd %ymm6, %ymm7, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1632(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm7 +vpunpckhwd const0(%rip), %ymm11, %ymm8 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm8, %ymm8 +vpsubd %ymm7, %ymm3, %ymm3 +vpsubd %ymm8, %ymm4, %ymm4 +vpsrld $1, %ymm3, %ymm3 +vpsrld $1, %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpackusdw %ymm4, %ymm3, %ymm4 +vmovdqa 864(%r8), %ymm3 +vpaddw 1120(%r8), %ymm3, %ymm8 +vpsubw 1120(%r8), %ymm3, %ymm3 +vpsrlw $2, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsllw $1, %ymm5, %ymm7 +vpsubw %ymm7, %ymm8, %ymm7 +vpsllw $7, %ymm11, %ymm8 +vpsubw %ymm8, %ymm7, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm4, %ymm8, %ymm8 +vmovdqa 1376(%r8), %ymm7 +vpsubw %ymm5, %ymm7, %ymm7 +vpmullw %ymm15, %ymm11, %ymm10 +vpsubw %ymm10, %ymm7, %ymm10 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm8, %ymm4, %ymm4 +vpmullw %ymm12, %ymm8, %ymm7 +vpaddw %ymm7, %ymm4, %ymm7 +vpmullw %ymm12, %ymm7, %ymm7 +vpsubw %ymm7, %ymm10, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm3, %ymm7, %ymm7 +vpsubw %ymm7, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpmullw %ymm13, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm10 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm9 +vpor %ymm9, %ymm8, %ymm8 +vpaddw %ymm8, %ymm5, %ymm5 +vmovdqa %xmm10, 2144(%r8) +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_3_5(%rip), %ymm7, %ymm10 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm9 +vpor %ymm9, %ymm7, %ymm7 +vpaddw %ymm7, %ymm6, %ymm6 +vmovdqa %xmm10, 2400(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm10 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm9 +vpor %ymm9, %ymm11, %ymm11 +vpaddw %ymm11, %ymm4, %ymm4 +vmovdqa %xmm10, 2656(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 264(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 616(%rdi) +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %ymm4, 968(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 1320(%rdi) +vmovdqa 128(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm7 +vpunpckhwd const0(%rip), %ymm11, %ymm8 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm8, %ymm8 +vmovdqa 384(%r8), %ymm3 +vpunpcklwd const0(%rip), %ymm3, %ymm4 +vpunpckhwd const0(%rip), %ymm3, %ymm3 +vmovdqa 640(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm4, %ymm10 +vpaddd %ymm6, %ymm3, %ymm9 +vpsubd %ymm7, %ymm10, %ymm10 +vpsubd %ymm8, %ymm9, %ymm9 +vpsubd %ymm5, %ymm4, %ymm5 +vpsubd %ymm6, %ymm3, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1664(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm3 +vpunpckhwd const0(%rip), %ymm5, %ymm4 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm4, %ymm4 +vpsubd %ymm3, %ymm10, %ymm10 +vpsubd %ymm4, %ymm9, %ymm9 +vpsrld $1, %ymm10, %ymm10 +vpsrld $1, %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpackusdw %ymm9, %ymm10, %ymm9 +vmovdqa 896(%r8), %ymm10 +vpaddw 1152(%r8), %ymm10, %ymm4 +vpsubw 1152(%r8), %ymm10, %ymm10 +vpsrlw $2, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsllw $1, %ymm11, %ymm3 +vpsubw %ymm3, %ymm4, %ymm3 +vpsllw $7, %ymm5, %ymm4 +vpsubw %ymm4, %ymm3, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vmovdqa 1408(%r8), %ymm3 +vpsubw %ymm11, %ymm3, %ymm3 +vpmullw %ymm15, %ymm5, %ymm8 +vpsubw %ymm8, %ymm3, %ymm8 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpmullw %ymm12, %ymm4, %ymm3 +vpaddw %ymm3, %ymm9, %ymm3 +vpmullw %ymm12, %ymm3, %ymm3 +vpsubw %ymm3, %ymm8, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm10, %ymm3, %ymm3 +vpsubw %ymm3, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vpmullw %ymm13, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vmovdqu 352(%rdi), %ymm8 +vmovdqu 704(%rdi), %ymm7 +vmovdqu 1056(%rdi), %ymm2 +vpaddw %ymm11, %ymm8, %ymm11 +vpaddw %ymm6, %ymm7, %ymm6 +vpaddw %ymm9, %ymm2, %ymm9 +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm2 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm7 +vpor %ymm7, %ymm10, %ymm10 +vmovdqu 0(%rdi), %ymm7 +vpaddw %ymm10, %ymm7, %ymm7 +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %ymm7, 0(%rdi) +vmovdqa %xmm2, 1920(%r8) +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm2 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm7 +vpor %ymm7, %ymm4, %ymm4 +vpaddw %ymm4, %ymm11, %ymm11 +vmovdqa %xmm2, 2176(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_3_5(%rip), %ymm3, %ymm2 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm7 +vpor %ymm7, %ymm3, %ymm3 +vpaddw %ymm3, %ymm6, %ymm6 +vmovdqa %xmm2, 2432(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm2 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm7 +vpor %ymm7, %ymm5, %ymm5 +vpaddw %ymm5, %ymm9, %ymm9 +vmovdqa %xmm2, 2688(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 352(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 704(%rdi) +vpand mask_mod8192(%rip), %ymm9, %ymm9 +vmovdqu %ymm9, 1056(%rdi) +vmovdqa 160(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm3 +vpunpckhwd const0(%rip), %ymm5, %ymm4 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm4, %ymm4 +vmovdqa 416(%r8), %ymm10 +vpunpcklwd const0(%rip), %ymm10, %ymm9 +vpunpckhwd const0(%rip), %ymm10, %ymm10 +vmovdqa 672(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm9, %ymm2 +vpaddd %ymm6, %ymm10, %ymm7 +vpsubd %ymm3, %ymm2, %ymm2 +vpsubd %ymm4, %ymm7, %ymm7 +vpsubd %ymm11, %ymm9, %ymm11 +vpsubd %ymm6, %ymm10, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1696(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm10 +vpunpckhwd const0(%rip), %ymm11, %ymm9 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm9, %ymm9 +vpsubd %ymm10, %ymm2, %ymm2 +vpsubd %ymm9, %ymm7, %ymm7 +vpsrld $1, %ymm2, %ymm2 +vpsrld $1, %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpackusdw %ymm7, %ymm2, %ymm7 +vmovdqa 928(%r8), %ymm2 +vpaddw 1184(%r8), %ymm2, %ymm9 +vpsubw 1184(%r8), %ymm2, %ymm2 +vpsrlw $2, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsllw $1, %ymm5, %ymm10 +vpsubw %ymm10, %ymm9, %ymm10 +vpsllw $7, %ymm11, %ymm9 +vpsubw %ymm9, %ymm10, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm7, %ymm9, %ymm9 +vmovdqa 1440(%r8), %ymm10 +vpsubw %ymm5, %ymm10, %ymm10 +vpmullw %ymm15, %ymm11, %ymm4 +vpsubw %ymm4, %ymm10, %ymm4 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm9, %ymm7, %ymm7 +vpmullw %ymm12, %ymm9, %ymm10 +vpaddw %ymm10, %ymm7, %ymm10 +vpmullw %ymm12, %ymm10, %ymm10 +vpsubw %ymm10, %ymm4, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm2, %ymm10, %ymm10 +vpsubw %ymm10, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vpmullw %ymm13, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vmovdqu 440(%rdi), %ymm4 +vmovdqu 792(%rdi), %ymm3 +vmovdqu 1144(%rdi), %ymm8 +vpaddw %ymm5, %ymm4, %ymm5 +vpaddw %ymm6, %ymm3, %ymm6 +vpaddw %ymm7, %ymm8, %ymm7 +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_3_5(%rip), %ymm2, %ymm8 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm2, %ymm2 +vmovdqu 88(%rdi), %ymm3 +vpaddw %ymm2, %ymm3, %ymm3 +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 88(%rdi) +vmovdqa %xmm8, 1952(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_3_5(%rip), %ymm9, %ymm8 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm9, %ymm9 +vpaddw %ymm9, %ymm5, %ymm5 +vmovdqa %xmm8, 2208(%r8) +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm8 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm10, %ymm10 +vpaddw %ymm10, %ymm6, %ymm6 +vmovdqa %xmm8, 2464(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm8 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm11, %ymm11 +vpaddw %ymm11, %ymm7, %ymm7 +vmovdqa %xmm8, 2720(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 440(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 792(%rdi) +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %ymm7, 1144(%rdi) +vmovdqa 192(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm10 +vpunpckhwd const0(%rip), %ymm11, %ymm9 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm9, %ymm9 +vmovdqa 448(%r8), %ymm2 +vpunpcklwd const0(%rip), %ymm2, %ymm7 +vpunpckhwd const0(%rip), %ymm2, %ymm2 +vmovdqa 704(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm7, %ymm8 +vpaddd %ymm6, %ymm2, %ymm3 +vpsubd %ymm10, %ymm8, %ymm8 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm5, %ymm7, %ymm5 +vpsubd %ymm6, %ymm2, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1728(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm7 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm7, %ymm7 +vpsubd %ymm2, %ymm8, %ymm8 +vpsubd %ymm7, %ymm3, %ymm3 +vpsrld $1, %ymm8, %ymm8 +vpsrld $1, %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpackusdw %ymm3, %ymm8, %ymm3 +vmovdqa 960(%r8), %ymm8 +vpaddw 1216(%r8), %ymm8, %ymm7 +vpsubw 1216(%r8), %ymm8, %ymm8 +vpsrlw $2, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsllw $1, %ymm11, %ymm2 +vpsubw %ymm2, %ymm7, %ymm2 +vpsllw $7, %ymm5, %ymm7 +vpsubw %ymm7, %ymm2, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm3, %ymm7, %ymm7 +vmovdqa 1472(%r8), %ymm2 +vpsubw %ymm11, %ymm2, %ymm2 +vpmullw %ymm15, %ymm5, %ymm9 +vpsubw %ymm9, %ymm2, %ymm9 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm7, %ymm3, %ymm3 +vpmullw %ymm12, %ymm7, %ymm2 +vpaddw %ymm2, %ymm3, %ymm2 +vpmullw %ymm12, %ymm2, %ymm2 +vpsubw %ymm2, %ymm9, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vpmullw %ymm13, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vmovdqu 528(%rdi), %ymm9 +vmovdqu 880(%rdi), %ymm10 +vmovdqu 1232(%rdi), %ymm4 +vpaddw %ymm11, %ymm9, %ymm11 +vpaddw %ymm6, %ymm10, %ymm6 +vpaddw %ymm3, %ymm4, %ymm3 +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm4 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm10 +vpor %ymm10, %ymm8, %ymm8 +vmovdqu 176(%rdi), %ymm10 +vpaddw %ymm8, %ymm10, %ymm10 +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 176(%rdi) +vmovdqa %xmm4, 1984(%r8) +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_3_5(%rip), %ymm7, %ymm4 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm10 +vpor %ymm10, %ymm7, %ymm7 +vpaddw %ymm7, %ymm11, %ymm11 +vmovdqa %xmm4, 2240(%r8) +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_3_5(%rip), %ymm2, %ymm4 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm10 +vpor %ymm10, %ymm2, %ymm2 +vpaddw %ymm2, %ymm6, %ymm6 +vmovdqa %xmm4, 2496(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm4 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm10 +vpor %ymm10, %ymm5, %ymm5 +vpaddw %ymm5, %ymm3, %ymm3 +vmovdqa %xmm4, 2752(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 528(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 880(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 1232(%rdi) +vmovdqa 224(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm7 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm7, %ymm7 +vmovdqa 480(%r8), %ymm8 +vpunpcklwd const0(%rip), %ymm8, %ymm3 +vpunpckhwd const0(%rip), %ymm8, %ymm8 +vmovdqa 736(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm3, %ymm4 +vpaddd %ymm6, %ymm8, %ymm10 +vpsubd %ymm2, %ymm4, %ymm4 +vpsubd %ymm7, %ymm10, %ymm10 +vpsubd %ymm11, %ymm3, %ymm11 +vpsubd %ymm6, %ymm8, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1760(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm3, %ymm3 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm3, %ymm10, %ymm10 +vpsrld $1, %ymm4, %ymm4 +vpsrld $1, %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpackusdw %ymm10, %ymm4, %ymm10 +vmovdqa 992(%r8), %ymm4 +vpaddw 1248(%r8), %ymm4, %ymm3 +vpsubw 1248(%r8), %ymm4, %ymm4 +vpsrlw $2, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsllw $1, %ymm5, %ymm8 +vpsubw %ymm8, %ymm3, %ymm8 +vpsllw $7, %ymm11, %ymm3 +vpsubw %ymm3, %ymm8, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm10, %ymm3, %ymm3 +vmovdqa 1504(%r8), %ymm8 +vpsubw %ymm5, %ymm8, %ymm8 +vpmullw %ymm15, %ymm11, %ymm7 +vpsubw %ymm7, %ymm8, %ymm7 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm3, %ymm10, %ymm10 +vpmullw %ymm12, %ymm3, %ymm8 +vpaddw %ymm8, %ymm10, %ymm8 +vpmullw %ymm12, %ymm8, %ymm8 +vpsubw %ymm8, %ymm7, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm4, %ymm8, %ymm8 +vpsubw %ymm8, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpmullw %ymm13, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vmovdqu 616(%rdi), %ymm7 +vmovdqu 968(%rdi), %ymm2 +vmovdqu 1320(%rdi), %ymm9 +vpaddw %ymm5, %ymm7, %ymm5 +vpaddw %ymm6, %ymm2, %ymm6 +vpaddw %ymm10, %ymm9, %ymm10 +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm9 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm2 +vpor %ymm2, %ymm4, %ymm4 +vmovdqu 264(%rdi), %ymm2 +vpaddw %ymm4, %ymm2, %ymm2 +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %ymm2, 264(%rdi) +vmovdqa %xmm9, 2016(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_3_5(%rip), %ymm3, %ymm9 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm2 +vpor %ymm2, %ymm3, %ymm3 +vpaddw %ymm3, %ymm5, %ymm5 +vmovdqa %xmm9, 2272(%r8) +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm9 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm2 +vpor %ymm2, %ymm8, %ymm8 +vpaddw %ymm8, %ymm6, %ymm6 +vmovdqa %xmm9, 2528(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm9 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm2 +vpor %ymm2, %ymm11, %ymm11 +vpaddw %ymm11, %ymm10, %ymm10 +vmovdqa %xmm9, 2784(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 616(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 968(%rdi) +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 1320(%rdi) +vmovdqa 128(%r12), %ymm0 +vpsubw 224(%r12), %ymm0, %ymm0 +vmovdqa 512(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 320(%r12), %ymm1, %ymm1 +vpsubw 32(%r12), %ymm0, %ymm0 +vpaddw 416(%r12), %ymm0, %ymm0 +vmovdqa 704(%r12), %ymm2 +vpsubw 800(%r12), %ymm2, %ymm2 +vmovdqa 1088(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 896(%r12), %ymm3, %ymm3 +vpsubw 608(%r12), %ymm2, %ymm2 +vpaddw 992(%r12), %ymm2, %ymm2 +vmovdqa 1280(%r12), %ymm4 +vpsubw 1376(%r12), %ymm4, %ymm4 +vmovdqa 1664(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 1472(%r12), %ymm5, %ymm5 +vpsubw 1184(%r12), %ymm4, %ymm4 +vpaddw 1568(%r12), %ymm4, %ymm4 +vpsubw 608(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 32(%r12), %ymm1, %ymm1 +vpaddw 1184(%r12), %ymm1, %ymm1 +vmovdqa 320(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 1472(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 896(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 32(%r12), %ymm8 +vmovdqa 896(%r12), %ymm9 +vmovdqa %ymm8, 0(%r8) +vmovdqa %ymm0, 32(%r8) +vmovdqa %ymm1, 64(%r8) +vmovdqa %ymm7, 96(%r8) +vmovdqa %ymm5, 128(%r8) +vmovdqa %ymm2, 160(%r8) +vmovdqa %ymm3, 192(%r8) +vmovdqa %ymm9, 224(%r8) +vmovdqa 1856(%r12), %ymm0 +vpsubw 1952(%r12), %ymm0, %ymm0 +vmovdqa 2240(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 2048(%r12), %ymm1, %ymm1 +vpsubw 1760(%r12), %ymm0, %ymm0 +vpaddw 2144(%r12), %ymm0, %ymm0 +vmovdqa 2432(%r12), %ymm2 +vpsubw 2528(%r12), %ymm2, %ymm2 +vmovdqa 2816(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 2624(%r12), %ymm3, %ymm3 +vpsubw 2336(%r12), %ymm2, %ymm2 +vpaddw 2720(%r12), %ymm2, %ymm2 +vmovdqa 3008(%r12), %ymm4 +vpsubw 3104(%r12), %ymm4, %ymm4 +vmovdqa 3392(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 3200(%r12), %ymm5, %ymm5 +vpsubw 2912(%r12), %ymm4, %ymm4 +vpaddw 3296(%r12), %ymm4, %ymm4 +vpsubw 2336(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 1760(%r12), %ymm1, %ymm1 +vpaddw 2912(%r12), %ymm1, %ymm1 +vmovdqa 2048(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 3200(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 2624(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 1760(%r12), %ymm8 +vmovdqa 2624(%r12), %ymm9 +vmovdqa %ymm8, 256(%r8) +vmovdqa %ymm0, 288(%r8) +vmovdqa %ymm1, 320(%r8) +vmovdqa %ymm7, 352(%r8) +vmovdqa %ymm5, 384(%r8) +vmovdqa %ymm2, 416(%r8) +vmovdqa %ymm3, 448(%r8) +vmovdqa %ymm9, 480(%r8) +vmovdqa 3584(%r12), %ymm0 +vpsubw 3680(%r12), %ymm0, %ymm0 +vmovdqa 3968(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3776(%r12), %ymm1, %ymm1 +vpsubw 3488(%r12), %ymm0, %ymm0 +vpaddw 3872(%r12), %ymm0, %ymm0 +vmovdqa 4160(%r12), %ymm2 +vpsubw 4256(%r12), %ymm2, %ymm2 +vmovdqa 4544(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 4352(%r12), %ymm3, %ymm3 +vpsubw 4064(%r12), %ymm2, %ymm2 +vpaddw 4448(%r12), %ymm2, %ymm2 +vmovdqa 4736(%r12), %ymm4 +vpsubw 4832(%r12), %ymm4, %ymm4 +vmovdqa 5120(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 4928(%r12), %ymm5, %ymm5 +vpsubw 4640(%r12), %ymm4, %ymm4 +vpaddw 5024(%r12), %ymm4, %ymm4 +vpsubw 4064(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 3488(%r12), %ymm1, %ymm1 +vpaddw 4640(%r12), %ymm1, %ymm1 +vmovdqa 3776(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 4928(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 4352(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 3488(%r12), %ymm8 +vmovdqa 4352(%r12), %ymm9 +vmovdqa %ymm8, 512(%r8) +vmovdqa %ymm0, 544(%r8) +vmovdqa %ymm1, 576(%r8) +vmovdqa %ymm7, 608(%r8) +vmovdqa %ymm5, 640(%r8) +vmovdqa %ymm2, 672(%r8) +vmovdqa %ymm3, 704(%r8) +vmovdqa %ymm9, 736(%r8) +vmovdqa 5312(%r12), %ymm0 +vpsubw 5408(%r12), %ymm0, %ymm0 +vmovdqa 5696(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5504(%r12), %ymm1, %ymm1 +vpsubw 5216(%r12), %ymm0, %ymm0 +vpaddw 5600(%r12), %ymm0, %ymm0 +vmovdqa 5888(%r12), %ymm2 +vpsubw 5984(%r12), %ymm2, %ymm2 +vmovdqa 6272(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 6080(%r12), %ymm3, %ymm3 +vpsubw 5792(%r12), %ymm2, %ymm2 +vpaddw 6176(%r12), %ymm2, %ymm2 +vmovdqa 6464(%r12), %ymm4 +vpsubw 6560(%r12), %ymm4, %ymm4 +vmovdqa 6848(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 6656(%r12), %ymm5, %ymm5 +vpsubw 6368(%r12), %ymm4, %ymm4 +vpaddw 6752(%r12), %ymm4, %ymm4 +vpsubw 5792(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 5216(%r12), %ymm1, %ymm1 +vpaddw 6368(%r12), %ymm1, %ymm1 +vmovdqa 5504(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 6656(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 6080(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 5216(%r12), %ymm8 +vmovdqa 6080(%r12), %ymm9 +vmovdqa %ymm8, 768(%r8) +vmovdqa %ymm0, 800(%r8) +vmovdqa %ymm1, 832(%r8) +vmovdqa %ymm7, 864(%r8) +vmovdqa %ymm5, 896(%r8) +vmovdqa %ymm2, 928(%r8) +vmovdqa %ymm3, 960(%r8) +vmovdqa %ymm9, 992(%r8) +vmovdqa 7040(%r12), %ymm0 +vpsubw 7136(%r12), %ymm0, %ymm0 +vmovdqa 7424(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 7232(%r12), %ymm1, %ymm1 +vpsubw 6944(%r12), %ymm0, %ymm0 +vpaddw 7328(%r12), %ymm0, %ymm0 +vmovdqa 7616(%r12), %ymm2 +vpsubw 7712(%r12), %ymm2, %ymm2 +vmovdqa 8000(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 7808(%r12), %ymm3, %ymm3 +vpsubw 7520(%r12), %ymm2, %ymm2 +vpaddw 7904(%r12), %ymm2, %ymm2 +vmovdqa 8192(%r12), %ymm4 +vpsubw 8288(%r12), %ymm4, %ymm4 +vmovdqa 8576(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 8384(%r12), %ymm5, %ymm5 +vpsubw 8096(%r12), %ymm4, %ymm4 +vpaddw 8480(%r12), %ymm4, %ymm4 +vpsubw 7520(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 6944(%r12), %ymm1, %ymm1 +vpaddw 8096(%r12), %ymm1, %ymm1 +vmovdqa 7232(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 8384(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 7808(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 6944(%r12), %ymm8 +vmovdqa 7808(%r12), %ymm9 +vmovdqa %ymm8, 1024(%r8) +vmovdqa %ymm0, 1056(%r8) +vmovdqa %ymm1, 1088(%r8) +vmovdqa %ymm7, 1120(%r8) +vmovdqa %ymm5, 1152(%r8) +vmovdqa %ymm2, 1184(%r8) +vmovdqa %ymm3, 1216(%r8) +vmovdqa %ymm9, 1248(%r8) +vmovdqa 8768(%r12), %ymm0 +vpsubw 8864(%r12), %ymm0, %ymm0 +vmovdqa 9152(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 8960(%r12), %ymm1, %ymm1 +vpsubw 8672(%r12), %ymm0, %ymm0 +vpaddw 9056(%r12), %ymm0, %ymm0 +vmovdqa 9344(%r12), %ymm2 +vpsubw 9440(%r12), %ymm2, %ymm2 +vmovdqa 9728(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 9536(%r12), %ymm3, %ymm3 +vpsubw 9248(%r12), %ymm2, %ymm2 +vpaddw 9632(%r12), %ymm2, %ymm2 +vmovdqa 9920(%r12), %ymm4 +vpsubw 10016(%r12), %ymm4, %ymm4 +vmovdqa 10304(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 10112(%r12), %ymm5, %ymm5 +vpsubw 9824(%r12), %ymm4, %ymm4 +vpaddw 10208(%r12), %ymm4, %ymm4 +vpsubw 9248(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 8672(%r12), %ymm1, %ymm1 +vpaddw 9824(%r12), %ymm1, %ymm1 +vmovdqa 8960(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 10112(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 9536(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 8672(%r12), %ymm8 +vmovdqa 9536(%r12), %ymm9 +vmovdqa %ymm8, 1280(%r8) +vmovdqa %ymm0, 1312(%r8) +vmovdqa %ymm1, 1344(%r8) +vmovdqa %ymm7, 1376(%r8) +vmovdqa %ymm5, 1408(%r8) +vmovdqa %ymm2, 1440(%r8) +vmovdqa %ymm3, 1472(%r8) +vmovdqa %ymm9, 1504(%r8) +vmovdqa 10496(%r12), %ymm0 +vpsubw 10592(%r12), %ymm0, %ymm0 +vmovdqa 10880(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 10688(%r12), %ymm1, %ymm1 +vpsubw 10400(%r12), %ymm0, %ymm0 +vpaddw 10784(%r12), %ymm0, %ymm0 +vmovdqa 11072(%r12), %ymm2 +vpsubw 11168(%r12), %ymm2, %ymm2 +vmovdqa 11456(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 11264(%r12), %ymm3, %ymm3 +vpsubw 10976(%r12), %ymm2, %ymm2 +vpaddw 11360(%r12), %ymm2, %ymm2 +vmovdqa 11648(%r12), %ymm4 +vpsubw 11744(%r12), %ymm4, %ymm4 +vmovdqa 12032(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 11840(%r12), %ymm5, %ymm5 +vpsubw 11552(%r12), %ymm4, %ymm4 +vpaddw 11936(%r12), %ymm4, %ymm4 +vpsubw 10976(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 10400(%r12), %ymm1, %ymm1 +vpaddw 11552(%r12), %ymm1, %ymm1 +vmovdqa 10688(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 11840(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 11264(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 10400(%r12), %ymm8 +vmovdqa 11264(%r12), %ymm9 +vmovdqa %ymm8, 1536(%r8) +vmovdqa %ymm0, 1568(%r8) +vmovdqa %ymm1, 1600(%r8) +vmovdqa %ymm7, 1632(%r8) +vmovdqa %ymm5, 1664(%r8) +vmovdqa %ymm2, 1696(%r8) +vmovdqa %ymm3, 1728(%r8) +vmovdqa %ymm9, 1760(%r8) +vmovdqa 0(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm3, %ymm3 +vmovdqa 256(%r8), %ymm4 +vpunpcklwd const0(%rip), %ymm4, %ymm10 +vpunpckhwd const0(%rip), %ymm4, %ymm4 +vmovdqa 512(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm10, %ymm9 +vpaddd %ymm6, %ymm4, %ymm2 +vpsubd %ymm8, %ymm9, %ymm9 +vpsubd %ymm3, %ymm2, %ymm2 +vpsubd %ymm5, %ymm10, %ymm5 +vpsubd %ymm6, %ymm4, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1536(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm4 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm10, %ymm10 +vpsubd %ymm4, %ymm9, %ymm9 +vpsubd %ymm10, %ymm2, %ymm2 +vpsrld $1, %ymm9, %ymm9 +vpsrld $1, %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpackusdw %ymm2, %ymm9, %ymm2 +vmovdqa 768(%r8), %ymm9 +vpaddw 1024(%r8), %ymm9, %ymm10 +vpsubw 1024(%r8), %ymm9, %ymm9 +vpsrlw $2, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsllw $1, %ymm11, %ymm4 +vpsubw %ymm4, %ymm10, %ymm4 +vpsllw $7, %ymm5, %ymm10 +vpsubw %ymm10, %ymm4, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm2, %ymm10, %ymm10 +vmovdqa 1280(%r8), %ymm4 +vpsubw %ymm11, %ymm4, %ymm4 +vpmullw %ymm15, %ymm5, %ymm3 +vpsubw %ymm3, %ymm4, %ymm3 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm10, %ymm2, %ymm2 +vpmullw %ymm12, %ymm10, %ymm4 +vpaddw %ymm4, %ymm2, %ymm4 +vpmullw %ymm12, %ymm4, %ymm4 +vpsubw %ymm4, %ymm3, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpmullw %ymm13, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm3 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm8 +vpor %ymm8, %ymm10, %ymm10 +vpaddw 2048(%r8), %ymm11, %ymm11 +vpaddw %ymm10, %ymm11, %ymm11 +vmovdqa %xmm3, 2048(%r8) +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm3 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm8 +vpor %ymm8, %ymm4, %ymm4 +vpaddw 2304(%r8), %ymm6, %ymm6 +vpaddw %ymm4, %ymm6, %ymm6 +vmovdqa %xmm3, 2304(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm3 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm8 +vpor %ymm8, %ymm5, %ymm5 +vpaddw 2560(%r8), %ymm2, %ymm2 +vpaddw %ymm5, %ymm2, %ymm2 +vmovdqa %xmm3, 2560(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 32(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 384(%rdi) +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %ymm2, 736(%rdi) +vpand mask_mod8192(%rip), %ymm9, %ymm9 +vmovdqu %ymm9, 1088(%rdi) +vmovdqa 32(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm4 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm10, %ymm10 +vmovdqa 288(%r8), %ymm9 +vpunpcklwd const0(%rip), %ymm9, %ymm2 +vpunpckhwd const0(%rip), %ymm9, %ymm9 +vmovdqa 544(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm2, %ymm3 +vpaddd %ymm6, %ymm9, %ymm8 +vpsubd %ymm4, %ymm3, %ymm3 +vpsubd %ymm10, %ymm8, %ymm8 +vpsubd %ymm11, %ymm2, %ymm11 +vpsubd %ymm6, %ymm9, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1568(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm9 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm2, %ymm2 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm2, %ymm8, %ymm8 +vpsrld $1, %ymm3, %ymm3 +vpsrld $1, %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpackusdw %ymm8, %ymm3, %ymm8 +vmovdqa 800(%r8), %ymm3 +vpaddw 1056(%r8), %ymm3, %ymm2 +vpsubw 1056(%r8), %ymm3, %ymm3 +vpsrlw $2, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsllw $1, %ymm5, %ymm9 +vpsubw %ymm9, %ymm2, %ymm9 +vpsllw $7, %ymm11, %ymm2 +vpsubw %ymm2, %ymm9, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vmovdqa 1312(%r8), %ymm9 +vpsubw %ymm5, %ymm9, %ymm9 +vpmullw %ymm15, %ymm11, %ymm10 +vpsubw %ymm10, %ymm9, %ymm10 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpmullw %ymm12, %ymm2, %ymm9 +vpaddw %ymm9, %ymm8, %ymm9 +vpmullw %ymm12, %ymm9, %ymm9 +vpsubw %ymm9, %ymm10, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm3, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpmullw %ymm13, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_3_5(%rip), %ymm2, %ymm10 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm4 +vpor %ymm4, %ymm2, %ymm2 +vpaddw 2080(%r8), %ymm5, %ymm5 +vpaddw %ymm2, %ymm5, %ymm5 +vmovdqa %xmm10, 2080(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_3_5(%rip), %ymm9, %ymm10 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm4 +vpor %ymm4, %ymm9, %ymm9 +vpaddw 2336(%r8), %ymm6, %ymm6 +vpaddw %ymm9, %ymm6, %ymm6 +vmovdqa %xmm10, 2336(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm10 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm4 +vpor %ymm4, %ymm11, %ymm11 +vpaddw 2592(%r8), %ymm8, %ymm8 +vpaddw %ymm11, %ymm8, %ymm8 +vmovdqa %xmm10, 2592(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 120(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 472(%rdi) +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %ymm8, 824(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 1176(%rdi) +vmovdqa 64(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm9 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm2, %ymm2 +vmovdqa 320(%r8), %ymm3 +vpunpcklwd const0(%rip), %ymm3, %ymm8 +vpunpckhwd const0(%rip), %ymm3, %ymm3 +vmovdqa 576(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm8, %ymm10 +vpaddd %ymm6, %ymm3, %ymm4 +vpsubd %ymm9, %ymm10, %ymm10 +vpsubd %ymm2, %ymm4, %ymm4 +vpsubd %ymm5, %ymm8, %ymm5 +vpsubd %ymm6, %ymm3, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1600(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm3 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm8, %ymm8 +vpsubd %ymm3, %ymm10, %ymm10 +vpsubd %ymm8, %ymm4, %ymm4 +vpsrld $1, %ymm10, %ymm10 +vpsrld $1, %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpackusdw %ymm4, %ymm10, %ymm4 +vmovdqa 832(%r8), %ymm10 +vpaddw 1088(%r8), %ymm10, %ymm8 +vpsubw 1088(%r8), %ymm10, %ymm10 +vpsrlw $2, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsllw $1, %ymm11, %ymm3 +vpsubw %ymm3, %ymm8, %ymm3 +vpsllw $7, %ymm5, %ymm8 +vpsubw %ymm8, %ymm3, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm4, %ymm8, %ymm8 +vmovdqa 1344(%r8), %ymm3 +vpsubw %ymm11, %ymm3, %ymm3 +vpmullw %ymm15, %ymm5, %ymm2 +vpsubw %ymm2, %ymm3, %ymm2 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm8, %ymm4, %ymm4 +vpmullw %ymm12, %ymm8, %ymm3 +vpaddw %ymm3, %ymm4, %ymm3 +vpmullw %ymm12, %ymm3, %ymm3 +vpsubw %ymm3, %ymm2, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm10, %ymm3, %ymm3 +vpsubw %ymm3, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vpmullw %ymm13, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm2 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm9 +vpor %ymm9, %ymm8, %ymm8 +vpaddw 2112(%r8), %ymm11, %ymm11 +vpaddw %ymm8, %ymm11, %ymm11 +vmovdqa %xmm2, 2112(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_3_5(%rip), %ymm3, %ymm2 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm9 +vpor %ymm9, %ymm3, %ymm3 +vpaddw 2368(%r8), %ymm6, %ymm6 +vpaddw %ymm3, %ymm6, %ymm6 +vmovdqa %xmm2, 2368(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm2 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm9 +vpor %ymm9, %ymm5, %ymm5 +vpaddw 2624(%r8), %ymm4, %ymm4 +vpaddw %ymm5, %ymm4, %ymm4 +vmovdqa %xmm2, 2624(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 208(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 560(%rdi) +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %ymm4, 912(%rdi) +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 1264(%rdi) +vmovdqa 96(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm3 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm8, %ymm8 +vmovdqa 352(%r8), %ymm10 +vpunpcklwd const0(%rip), %ymm10, %ymm4 +vpunpckhwd const0(%rip), %ymm10, %ymm10 +vmovdqa 608(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm4, %ymm2 +vpaddd %ymm6, %ymm10, %ymm9 +vpsubd %ymm3, %ymm2, %ymm2 +vpsubd %ymm8, %ymm9, %ymm9 +vpsubd %ymm11, %ymm4, %ymm11 +vpsubd %ymm6, %ymm10, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1632(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm10 +vpunpckhwd const0(%rip), %ymm11, %ymm4 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm4, %ymm4 +vpsubd %ymm10, %ymm2, %ymm2 +vpsubd %ymm4, %ymm9, %ymm9 +vpsrld $1, %ymm2, %ymm2 +vpsrld $1, %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpackusdw %ymm9, %ymm2, %ymm9 +vmovdqa 864(%r8), %ymm2 +vpaddw 1120(%r8), %ymm2, %ymm4 +vpsubw 1120(%r8), %ymm2, %ymm2 +vpsrlw $2, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsllw $1, %ymm5, %ymm10 +vpsubw %ymm10, %ymm4, %ymm10 +vpsllw $7, %ymm11, %ymm4 +vpsubw %ymm4, %ymm10, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vmovdqa 1376(%r8), %ymm10 +vpsubw %ymm5, %ymm10, %ymm10 +vpmullw %ymm15, %ymm11, %ymm8 +vpsubw %ymm8, %ymm10, %ymm8 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpmullw %ymm12, %ymm4, %ymm10 +vpaddw %ymm10, %ymm9, %ymm10 +vpmullw %ymm12, %ymm10, %ymm10 +vpsubw %ymm10, %ymm8, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm2, %ymm10, %ymm10 +vpsubw %ymm10, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vpmullw %ymm13, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm8 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm4, %ymm4 +vpaddw 2144(%r8), %ymm5, %ymm5 +vpaddw %ymm4, %ymm5, %ymm5 +vmovdqa %xmm8, 2144(%r8) +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm8 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm10, %ymm10 +vpaddw 2400(%r8), %ymm6, %ymm6 +vpaddw %ymm10, %ymm6, %ymm6 +vmovdqa %xmm8, 2400(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm8 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm3 +vpor %ymm3, %ymm11, %ymm11 +vpaddw 2656(%r8), %ymm9, %ymm9 +vpaddw %ymm11, %ymm9, %ymm9 +vmovdqa %xmm8, 2656(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 296(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 648(%rdi) +vpand mask_mod8192(%rip), %ymm9, %ymm9 +vmovdqu %ymm9, 1000(%rdi) +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %ymm2, 1352(%rdi) +vmovdqa 128(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm10 +vpunpckhwd const0(%rip), %ymm11, %ymm4 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm4, %ymm4 +vmovdqa 384(%r8), %ymm2 +vpunpcklwd const0(%rip), %ymm2, %ymm9 +vpunpckhwd const0(%rip), %ymm2, %ymm2 +vmovdqa 640(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm9, %ymm8 +vpaddd %ymm6, %ymm2, %ymm3 +vpsubd %ymm10, %ymm8, %ymm8 +vpsubd %ymm4, %ymm3, %ymm3 +vpsubd %ymm5, %ymm9, %ymm5 +vpsubd %ymm6, %ymm2, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1664(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm9 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm9, %ymm9 +vpsubd %ymm2, %ymm8, %ymm8 +vpsubd %ymm9, %ymm3, %ymm3 +vpsrld $1, %ymm8, %ymm8 +vpsrld $1, %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpackusdw %ymm3, %ymm8, %ymm3 +vmovdqa 896(%r8), %ymm8 +vpaddw 1152(%r8), %ymm8, %ymm9 +vpsubw 1152(%r8), %ymm8, %ymm8 +vpsrlw $2, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsllw $1, %ymm11, %ymm2 +vpsubw %ymm2, %ymm9, %ymm2 +vpsllw $7, %ymm5, %ymm9 +vpsubw %ymm9, %ymm2, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm3, %ymm9, %ymm9 +vmovdqa 1408(%r8), %ymm2 +vpsubw %ymm11, %ymm2, %ymm2 +vpmullw %ymm15, %ymm5, %ymm4 +vpsubw %ymm4, %ymm2, %ymm4 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm3 +vpmullw %ymm12, %ymm9, %ymm2 +vpaddw %ymm2, %ymm3, %ymm2 +vpmullw %ymm12, %ymm2, %ymm2 +vpsubw %ymm2, %ymm4, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vpmullw %ymm13, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vmovdqu 384(%rdi), %ymm4 +vmovdqu 736(%rdi), %ymm10 +vmovdqu 1088(%rdi), %ymm7 +vpaddw %ymm11, %ymm4, %ymm11 +vpaddw %ymm6, %ymm10, %ymm6 +vpaddw %ymm3, %ymm7, %ymm3 +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm7 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm10 +vpor %ymm10, %ymm8, %ymm8 +vmovdqu 32(%rdi), %ymm10 +vpaddw 1920(%r8), %ymm10, %ymm10 +vpaddw %ymm8, %ymm10, %ymm10 +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 32(%rdi) +vmovdqa %xmm7, 1920(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_3_5(%rip), %ymm9, %ymm7 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm10 +vpor %ymm10, %ymm9, %ymm9 +vpaddw 2176(%r8), %ymm11, %ymm11 +vpaddw %ymm9, %ymm11, %ymm11 +vmovdqa %xmm7, 2176(%r8) +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_3_5(%rip), %ymm2, %ymm7 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm10 +vpor %ymm10, %ymm2, %ymm2 +vpaddw 2432(%r8), %ymm6, %ymm6 +vpaddw %ymm2, %ymm6, %ymm6 +vmovdqa %xmm7, 2432(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm7 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm10 +vpor %ymm10, %ymm5, %ymm5 +vpaddw 2688(%r8), %ymm3, %ymm3 +vpaddw %ymm5, %ymm3, %ymm3 +vmovdqa %xmm7, 2688(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 384(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 736(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %ymm3, 1088(%rdi) +vmovdqa 160(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm9 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm9, %ymm9 +vmovdqa 416(%r8), %ymm8 +vpunpcklwd const0(%rip), %ymm8, %ymm3 +vpunpckhwd const0(%rip), %ymm8, %ymm8 +vmovdqa 672(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm3, %ymm7 +vpaddd %ymm6, %ymm8, %ymm10 +vpsubd %ymm2, %ymm7, %ymm7 +vpsubd %ymm9, %ymm10, %ymm10 +vpsubd %ymm11, %ymm3, %ymm11 +vpsubd %ymm6, %ymm8, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1696(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm3, %ymm3 +vpsubd %ymm8, %ymm7, %ymm7 +vpsubd %ymm3, %ymm10, %ymm10 +vpsrld $1, %ymm7, %ymm7 +vpsrld $1, %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpackusdw %ymm10, %ymm7, %ymm10 +vmovdqa 928(%r8), %ymm7 +vpaddw 1184(%r8), %ymm7, %ymm3 +vpsubw 1184(%r8), %ymm7, %ymm7 +vpsrlw $2, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsllw $1, %ymm5, %ymm8 +vpsubw %ymm8, %ymm3, %ymm8 +vpsllw $7, %ymm11, %ymm3 +vpsubw %ymm3, %ymm8, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm10, %ymm3, %ymm3 +vmovdqa 1440(%r8), %ymm8 +vpsubw %ymm5, %ymm8, %ymm8 +vpmullw %ymm15, %ymm11, %ymm9 +vpsubw %ymm9, %ymm8, %ymm9 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm3, %ymm10, %ymm10 +vpmullw %ymm12, %ymm3, %ymm8 +vpaddw %ymm8, %ymm10, %ymm8 +vpmullw %ymm12, %ymm8, %ymm8 +vpsubw %ymm8, %ymm9, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm7, %ymm8, %ymm8 +vpsubw %ymm8, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vpmullw %ymm13, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vmovdqu 472(%rdi), %ymm9 +vmovdqu 824(%rdi), %ymm2 +vmovdqu 1176(%rdi), %ymm4 +vpaddw %ymm5, %ymm9, %ymm5 +vpaddw %ymm6, %ymm2, %ymm6 +vpaddw %ymm10, %ymm4, %ymm10 +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_3_5(%rip), %ymm7, %ymm4 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm7, %ymm7 +vmovdqu 120(%rdi), %ymm2 +vpaddw 1952(%r8), %ymm2, %ymm2 +vpaddw %ymm7, %ymm2, %ymm2 +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %ymm2, 120(%rdi) +vmovdqa %xmm4, 1952(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_3_5(%rip), %ymm3, %ymm4 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm3, %ymm3 +vpaddw 2208(%r8), %ymm5, %ymm5 +vpaddw %ymm3, %ymm5, %ymm5 +vmovdqa %xmm4, 2208(%r8) +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_3_5(%rip), %ymm8, %ymm4 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm8, %ymm8 +vpaddw 2464(%r8), %ymm6, %ymm6 +vpaddw %ymm8, %ymm6, %ymm6 +vmovdqa %xmm4, 2464(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm4 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm11, %ymm11 +vpaddw 2720(%r8), %ymm10, %ymm10 +vpaddw %ymm11, %ymm10, %ymm10 +vmovdqa %xmm4, 2720(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 472(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 824(%rdi) +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %ymm10, 1176(%rdi) +vmovdqa 192(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm3 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm3, %ymm3 +vmovdqa 448(%r8), %ymm7 +vpunpcklwd const0(%rip), %ymm7, %ymm10 +vpunpckhwd const0(%rip), %ymm7, %ymm7 +vmovdqa 704(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm10, %ymm4 +vpaddd %ymm6, %ymm7, %ymm2 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm3, %ymm2, %ymm2 +vpsubd %ymm5, %ymm10, %ymm5 +vpsubd %ymm6, %ymm7, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1728(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm7 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm10, %ymm10 +vpsubd %ymm7, %ymm4, %ymm4 +vpsubd %ymm10, %ymm2, %ymm2 +vpsrld $1, %ymm4, %ymm4 +vpsrld $1, %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpackusdw %ymm2, %ymm4, %ymm2 +vmovdqa 960(%r8), %ymm4 +vpaddw 1216(%r8), %ymm4, %ymm10 +vpsubw 1216(%r8), %ymm4, %ymm4 +vpsrlw $2, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsllw $1, %ymm11, %ymm7 +vpsubw %ymm7, %ymm10, %ymm7 +vpsllw $7, %ymm5, %ymm10 +vpsubw %ymm10, %ymm7, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm2, %ymm10, %ymm10 +vmovdqa 1472(%r8), %ymm7 +vpsubw %ymm11, %ymm7, %ymm7 +vpmullw %ymm15, %ymm5, %ymm3 +vpsubw %ymm3, %ymm7, %ymm3 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm10, %ymm2, %ymm2 +vpmullw %ymm12, %ymm10, %ymm7 +vpaddw %ymm7, %ymm2, %ymm7 +vpmullw %ymm12, %ymm7, %ymm7 +vpsubw %ymm7, %ymm3, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm4, %ymm7, %ymm7 +vpsubw %ymm7, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpmullw %ymm13, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vmovdqu 560(%rdi), %ymm3 +vmovdqu 912(%rdi), %ymm8 +vmovdqu 1264(%rdi), %ymm9 +vpaddw %ymm11, %ymm3, %ymm11 +vpaddw %ymm6, %ymm8, %ymm6 +vpaddw %ymm2, %ymm9, %ymm2 +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm9 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm8 +vpor %ymm8, %ymm4, %ymm4 +vmovdqu 208(%rdi), %ymm8 +vpaddw 1984(%r8), %ymm8, %ymm8 +vpaddw %ymm4, %ymm8, %ymm8 +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %ymm8, 208(%rdi) +vmovdqa %xmm9, 1984(%r8) +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_3_5(%rip), %ymm10, %ymm9 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm8 +vpor %ymm8, %ymm10, %ymm10 +vpaddw 2240(%r8), %ymm11, %ymm11 +vpaddw %ymm10, %ymm11, %ymm11 +vmovdqa %xmm9, 2240(%r8) +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_3_5(%rip), %ymm7, %ymm9 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm8 +vpor %ymm8, %ymm7, %ymm7 +vpaddw 2496(%r8), %ymm6, %ymm6 +vpaddw %ymm7, %ymm6, %ymm6 +vmovdqa %xmm9, 2496(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_3_5(%rip), %ymm5, %ymm9 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $206, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm8 +vpor %ymm8, %ymm5, %ymm5 +vpaddw 2752(%r8), %ymm2, %ymm2 +vpaddw %ymm5, %ymm2, %ymm2 +vmovdqa %xmm9, 2752(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 560(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 912(%rdi) +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %ymm2, 1264(%rdi) +vmovdqa 224(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm7 +vpunpckhwd const0(%rip), %ymm5, %ymm10 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm10, %ymm10 +vmovdqa 480(%r8), %ymm4 +vpunpcklwd const0(%rip), %ymm4, %ymm2 +vpunpckhwd const0(%rip), %ymm4, %ymm4 +vmovdqa 736(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm2, %ymm9 +vpaddd %ymm6, %ymm4, %ymm8 +vpsubd %ymm7, %ymm9, %ymm9 +vpsubd %ymm10, %ymm8, %ymm8 +vpsubd %ymm11, %ymm2, %ymm11 +vpsubd %ymm6, %ymm4, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1760(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm2, %ymm2 +vpsubd %ymm4, %ymm9, %ymm9 +vpsubd %ymm2, %ymm8, %ymm8 +vpsrld $1, %ymm9, %ymm9 +vpsrld $1, %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpackusdw %ymm8, %ymm9, %ymm8 +vmovdqa 992(%r8), %ymm9 +vpaddw 1248(%r8), %ymm9, %ymm2 +vpsubw 1248(%r8), %ymm9, %ymm9 +vpsrlw $2, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsllw $1, %ymm5, %ymm4 +vpsubw %ymm4, %ymm2, %ymm4 +vpsllw $7, %ymm11, %ymm2 +vpsubw %ymm2, %ymm4, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vmovdqa 1504(%r8), %ymm4 +vpsubw %ymm5, %ymm4, %ymm4 +vpmullw %ymm15, %ymm11, %ymm10 +vpsubw %ymm10, %ymm4, %ymm10 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpmullw %ymm12, %ymm2, %ymm4 +vpaddw %ymm4, %ymm8, %ymm4 +vpmullw %ymm12, %ymm4, %ymm4 +vpsubw %ymm4, %ymm10, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpmullw %ymm13, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vmovdqu 648(%rdi), %ymm10 +vmovdqu 1000(%rdi), %ymm7 +vmovdqu 1352(%rdi), %ymm3 +vpaddw %ymm5, %ymm10, %ymm5 +vpaddw %ymm6, %ymm7, %ymm6 +vpaddw %ymm8, %ymm3, %ymm8 +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_3_5(%rip), %ymm9, %ymm3 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm7 +vpor %ymm7, %ymm9, %ymm9 +vmovdqu 296(%rdi), %ymm7 +vpaddw 2016(%r8), %ymm7, %ymm7 +vpaddw %ymm9, %ymm7, %ymm7 +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %ymm7, 296(%rdi) +vmovdqa %xmm3, 2016(%r8) +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_3_5(%rip), %ymm2, %ymm3 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm7 +vpor %ymm7, %ymm2, %ymm2 +vpaddw 2272(%r8), %ymm5, %ymm5 +vpaddw %ymm2, %ymm5, %ymm5 +vmovdqa %xmm3, 2272(%r8) +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_3_5(%rip), %ymm4, %ymm3 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm7 +vpor %ymm7, %ymm4, %ymm4 +vpaddw 2528(%r8), %ymm6, %ymm6 +vpaddw %ymm4, %ymm6, %ymm6 +vmovdqa %xmm3, 2528(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_3_5(%rip), %ymm11, %ymm3 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $206, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm7 +vpor %ymm7, %ymm11, %ymm11 +vpaddw 2784(%r8), %ymm8, %ymm8 +vpaddw %ymm11, %ymm8, %ymm8 +vmovdqa %xmm3, 2784(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %ymm5, 648(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %ymm6, 1000(%rdi) +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %ymm8, 1352(%rdi) +vmovdqa 160(%r12), %ymm0 +vpsubw 256(%r12), %ymm0, %ymm0 +vmovdqa 544(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 352(%r12), %ymm1, %ymm1 +vpsubw 64(%r12), %ymm0, %ymm0 +vpaddw 448(%r12), %ymm0, %ymm0 +vmovdqa 736(%r12), %ymm2 +vpsubw 832(%r12), %ymm2, %ymm2 +vmovdqa 1120(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 928(%r12), %ymm3, %ymm3 +vpsubw 640(%r12), %ymm2, %ymm2 +vpaddw 1024(%r12), %ymm2, %ymm2 +vmovdqa 1312(%r12), %ymm4 +vpsubw 1408(%r12), %ymm4, %ymm4 +vmovdqa 1696(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 1504(%r12), %ymm5, %ymm5 +vpsubw 1216(%r12), %ymm4, %ymm4 +vpaddw 1600(%r12), %ymm4, %ymm4 +vpsubw 640(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 64(%r12), %ymm1, %ymm1 +vpaddw 1216(%r12), %ymm1, %ymm1 +vmovdqa 352(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 1504(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 928(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 64(%r12), %ymm8 +vmovdqa 928(%r12), %ymm9 +vmovdqa %ymm8, 0(%r8) +vmovdqa %ymm0, 32(%r8) +vmovdqa %ymm1, 64(%r8) +vmovdqa %ymm7, 96(%r8) +vmovdqa %ymm5, 128(%r8) +vmovdqa %ymm2, 160(%r8) +vmovdqa %ymm3, 192(%r8) +vmovdqa %ymm9, 224(%r8) +vmovdqa 1888(%r12), %ymm0 +vpsubw 1984(%r12), %ymm0, %ymm0 +vmovdqa 2272(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 2080(%r12), %ymm1, %ymm1 +vpsubw 1792(%r12), %ymm0, %ymm0 +vpaddw 2176(%r12), %ymm0, %ymm0 +vmovdqa 2464(%r12), %ymm2 +vpsubw 2560(%r12), %ymm2, %ymm2 +vmovdqa 2848(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 2656(%r12), %ymm3, %ymm3 +vpsubw 2368(%r12), %ymm2, %ymm2 +vpaddw 2752(%r12), %ymm2, %ymm2 +vmovdqa 3040(%r12), %ymm4 +vpsubw 3136(%r12), %ymm4, %ymm4 +vmovdqa 3424(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 3232(%r12), %ymm5, %ymm5 +vpsubw 2944(%r12), %ymm4, %ymm4 +vpaddw 3328(%r12), %ymm4, %ymm4 +vpsubw 2368(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 1792(%r12), %ymm1, %ymm1 +vpaddw 2944(%r12), %ymm1, %ymm1 +vmovdqa 2080(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 3232(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 2656(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 1792(%r12), %ymm8 +vmovdqa 2656(%r12), %ymm9 +vmovdqa %ymm8, 256(%r8) +vmovdqa %ymm0, 288(%r8) +vmovdqa %ymm1, 320(%r8) +vmovdqa %ymm7, 352(%r8) +vmovdqa %ymm5, 384(%r8) +vmovdqa %ymm2, 416(%r8) +vmovdqa %ymm3, 448(%r8) +vmovdqa %ymm9, 480(%r8) +vmovdqa 3616(%r12), %ymm0 +vpsubw 3712(%r12), %ymm0, %ymm0 +vmovdqa 4000(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 3808(%r12), %ymm1, %ymm1 +vpsubw 3520(%r12), %ymm0, %ymm0 +vpaddw 3904(%r12), %ymm0, %ymm0 +vmovdqa 4192(%r12), %ymm2 +vpsubw 4288(%r12), %ymm2, %ymm2 +vmovdqa 4576(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 4384(%r12), %ymm3, %ymm3 +vpsubw 4096(%r12), %ymm2, %ymm2 +vpaddw 4480(%r12), %ymm2, %ymm2 +vmovdqa 4768(%r12), %ymm4 +vpsubw 4864(%r12), %ymm4, %ymm4 +vmovdqa 5152(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 4960(%r12), %ymm5, %ymm5 +vpsubw 4672(%r12), %ymm4, %ymm4 +vpaddw 5056(%r12), %ymm4, %ymm4 +vpsubw 4096(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 3520(%r12), %ymm1, %ymm1 +vpaddw 4672(%r12), %ymm1, %ymm1 +vmovdqa 3808(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 4960(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 4384(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 3520(%r12), %ymm8 +vmovdqa 4384(%r12), %ymm9 +vmovdqa %ymm8, 512(%r8) +vmovdqa %ymm0, 544(%r8) +vmovdqa %ymm1, 576(%r8) +vmovdqa %ymm7, 608(%r8) +vmovdqa %ymm5, 640(%r8) +vmovdqa %ymm2, 672(%r8) +vmovdqa %ymm3, 704(%r8) +vmovdqa %ymm9, 736(%r8) +vmovdqa 5344(%r12), %ymm0 +vpsubw 5440(%r12), %ymm0, %ymm0 +vmovdqa 5728(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 5536(%r12), %ymm1, %ymm1 +vpsubw 5248(%r12), %ymm0, %ymm0 +vpaddw 5632(%r12), %ymm0, %ymm0 +vmovdqa 5920(%r12), %ymm2 +vpsubw 6016(%r12), %ymm2, %ymm2 +vmovdqa 6304(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 6112(%r12), %ymm3, %ymm3 +vpsubw 5824(%r12), %ymm2, %ymm2 +vpaddw 6208(%r12), %ymm2, %ymm2 +vmovdqa 6496(%r12), %ymm4 +vpsubw 6592(%r12), %ymm4, %ymm4 +vmovdqa 6880(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 6688(%r12), %ymm5, %ymm5 +vpsubw 6400(%r12), %ymm4, %ymm4 +vpaddw 6784(%r12), %ymm4, %ymm4 +vpsubw 5824(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 5248(%r12), %ymm1, %ymm1 +vpaddw 6400(%r12), %ymm1, %ymm1 +vmovdqa 5536(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 6688(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 6112(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 5248(%r12), %ymm8 +vmovdqa 6112(%r12), %ymm9 +vmovdqa %ymm8, 768(%r8) +vmovdqa %ymm0, 800(%r8) +vmovdqa %ymm1, 832(%r8) +vmovdqa %ymm7, 864(%r8) +vmovdqa %ymm5, 896(%r8) +vmovdqa %ymm2, 928(%r8) +vmovdqa %ymm3, 960(%r8) +vmovdqa %ymm9, 992(%r8) +vmovdqa 7072(%r12), %ymm0 +vpsubw 7168(%r12), %ymm0, %ymm0 +vmovdqa 7456(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 7264(%r12), %ymm1, %ymm1 +vpsubw 6976(%r12), %ymm0, %ymm0 +vpaddw 7360(%r12), %ymm0, %ymm0 +vmovdqa 7648(%r12), %ymm2 +vpsubw 7744(%r12), %ymm2, %ymm2 +vmovdqa 8032(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 7840(%r12), %ymm3, %ymm3 +vpsubw 7552(%r12), %ymm2, %ymm2 +vpaddw 7936(%r12), %ymm2, %ymm2 +vmovdqa 8224(%r12), %ymm4 +vpsubw 8320(%r12), %ymm4, %ymm4 +vmovdqa 8608(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 8416(%r12), %ymm5, %ymm5 +vpsubw 8128(%r12), %ymm4, %ymm4 +vpaddw 8512(%r12), %ymm4, %ymm4 +vpsubw 7552(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 6976(%r12), %ymm1, %ymm1 +vpaddw 8128(%r12), %ymm1, %ymm1 +vmovdqa 7264(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 8416(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 7840(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 6976(%r12), %ymm8 +vmovdqa 7840(%r12), %ymm9 +vmovdqa %ymm8, 1024(%r8) +vmovdqa %ymm0, 1056(%r8) +vmovdqa %ymm1, 1088(%r8) +vmovdqa %ymm7, 1120(%r8) +vmovdqa %ymm5, 1152(%r8) +vmovdqa %ymm2, 1184(%r8) +vmovdqa %ymm3, 1216(%r8) +vmovdqa %ymm9, 1248(%r8) +vmovdqa 8800(%r12), %ymm0 +vpsubw 8896(%r12), %ymm0, %ymm0 +vmovdqa 9184(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 8992(%r12), %ymm1, %ymm1 +vpsubw 8704(%r12), %ymm0, %ymm0 +vpaddw 9088(%r12), %ymm0, %ymm0 +vmovdqa 9376(%r12), %ymm2 +vpsubw 9472(%r12), %ymm2, %ymm2 +vmovdqa 9760(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 9568(%r12), %ymm3, %ymm3 +vpsubw 9280(%r12), %ymm2, %ymm2 +vpaddw 9664(%r12), %ymm2, %ymm2 +vmovdqa 9952(%r12), %ymm4 +vpsubw 10048(%r12), %ymm4, %ymm4 +vmovdqa 10336(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 10144(%r12), %ymm5, %ymm5 +vpsubw 9856(%r12), %ymm4, %ymm4 +vpaddw 10240(%r12), %ymm4, %ymm4 +vpsubw 9280(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 8704(%r12), %ymm1, %ymm1 +vpaddw 9856(%r12), %ymm1, %ymm1 +vmovdqa 8992(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 10144(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 9568(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 8704(%r12), %ymm8 +vmovdqa 9568(%r12), %ymm9 +vmovdqa %ymm8, 1280(%r8) +vmovdqa %ymm0, 1312(%r8) +vmovdqa %ymm1, 1344(%r8) +vmovdqa %ymm7, 1376(%r8) +vmovdqa %ymm5, 1408(%r8) +vmovdqa %ymm2, 1440(%r8) +vmovdqa %ymm3, 1472(%r8) +vmovdqa %ymm9, 1504(%r8) +vmovdqa 10528(%r12), %ymm0 +vpsubw 10624(%r12), %ymm0, %ymm0 +vmovdqa 10912(%r12), %ymm1 +vpsubw %ymm0, %ymm1, %ymm1 +vpsubw 10720(%r12), %ymm1, %ymm1 +vpsubw 10432(%r12), %ymm0, %ymm0 +vpaddw 10816(%r12), %ymm0, %ymm0 +vmovdqa 11104(%r12), %ymm2 +vpsubw 11200(%r12), %ymm2, %ymm2 +vmovdqa 11488(%r12), %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw 11296(%r12), %ymm3, %ymm3 +vpsubw 11008(%r12), %ymm2, %ymm2 +vpaddw 11392(%r12), %ymm2, %ymm2 +vmovdqa 11680(%r12), %ymm4 +vpsubw 11776(%r12), %ymm4, %ymm4 +vmovdqa 12064(%r12), %ymm5 +vpsubw %ymm4, %ymm5, %ymm5 +vpsubw 11872(%r12), %ymm5, %ymm5 +vpsubw 11584(%r12), %ymm4, %ymm4 +vpaddw 11968(%r12), %ymm4, %ymm4 +vpsubw 11008(%r12), %ymm1, %ymm1 +vpsubw %ymm1, %ymm5, %ymm5 +vpsubw %ymm3, %ymm5, %ymm5 +vpsubw 10432(%r12), %ymm1, %ymm1 +vpaddw 11584(%r12), %ymm1, %ymm1 +vmovdqa 10720(%r12), %ymm6 +vpsubw %ymm2, %ymm6, %ymm7 +vmovdqa 11872(%r12), %ymm2 +vpsubw %ymm7, %ymm2, %ymm2 +vpsubw 11296(%r12), %ymm2, %ymm2 +vpsubw %ymm0, %ymm7, %ymm7 +vpaddw %ymm4, %ymm7, %ymm7 +vmovdqa 10432(%r12), %ymm8 +vmovdqa 11296(%r12), %ymm9 +vmovdqa %ymm8, 1536(%r8) +vmovdqa %ymm0, 1568(%r8) +vmovdqa %ymm1, 1600(%r8) +vmovdqa %ymm7, 1632(%r8) +vmovdqa %ymm5, 1664(%r8) +vmovdqa %ymm2, 1696(%r8) +vmovdqa %ymm3, 1728(%r8) +vmovdqa %ymm9, 1760(%r8) +vmovdqa 0(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm2, %ymm2 +vmovdqa 256(%r8), %ymm9 +vpunpcklwd const0(%rip), %ymm9, %ymm8 +vpunpckhwd const0(%rip), %ymm9, %ymm9 +vmovdqa 512(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm8, %ymm3 +vpaddd %ymm6, %ymm9, %ymm7 +vpsubd %ymm4, %ymm3, %ymm3 +vpsubd %ymm2, %ymm7, %ymm7 +vpsubd %ymm5, %ymm8, %ymm5 +vpsubd %ymm6, %ymm9, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1536(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm9 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm8, %ymm8 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm8, %ymm7, %ymm7 +vpsrld $1, %ymm3, %ymm3 +vpsrld $1, %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpackusdw %ymm7, %ymm3, %ymm7 +vmovdqa 768(%r8), %ymm3 +vpaddw 1024(%r8), %ymm3, %ymm8 +vpsubw 1024(%r8), %ymm3, %ymm3 +vpsrlw $2, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsllw $1, %ymm11, %ymm9 +vpsubw %ymm9, %ymm8, %ymm9 +vpsllw $7, %ymm5, %ymm8 +vpsubw %ymm8, %ymm9, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm7, %ymm8, %ymm8 +vmovdqa 1280(%r8), %ymm9 +vpsubw %ymm11, %ymm9, %ymm9 +vpmullw %ymm15, %ymm5, %ymm2 +vpsubw %ymm2, %ymm9, %ymm2 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm8, %ymm7, %ymm7 +vpmullw %ymm12, %ymm8, %ymm9 +vpaddw %ymm9, %ymm7, %ymm9 +vpmullw %ymm12, %ymm9, %ymm9 +vpsubw %ymm9, %ymm2, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm3, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpmullw %ymm13, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_4_3_1(%rip), %ymm8, %ymm2 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm4 +vpor %ymm4, %ymm8, %ymm8 +vpaddw 2048(%r8), %ymm11, %ymm11 +vpaddw %ymm8, %ymm11, %ymm11 +vmovdqa %xmm2, 2048(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_4_3_1(%rip), %ymm9, %ymm2 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm4 +vpor %ymm4, %ymm9, %ymm9 +vpaddw 2304(%r8), %ymm6, %ymm6 +vpaddw %ymm9, %ymm6, %ymm6 +vmovdqa %xmm2, 2304(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_4_3_1(%rip), %ymm5, %ymm2 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm4 +vpor %ymm4, %ymm5, %ymm5 +vpaddw 2560(%r8), %ymm7, %ymm7 +vpaddw %ymm5, %ymm7, %ymm7 +vmovdqa %xmm2, 2560(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %xmm11, 64(%rdi) +vextracti128 $1, %ymm11, %xmm11 +vmovq %xmm11, 80(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 416(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 432(%rdi) +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %xmm7, 768(%rdi) +vextracti128 $1, %ymm7, %xmm7 +vmovq %xmm7, 784(%rdi) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %xmm3, 1120(%rdi) +vextracti128 $1, %ymm3, %xmm3 +vmovq %xmm3, 1136(%rdi) +vmovdqa 32(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm9 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm8, %ymm8 +vmovdqa 288(%r8), %ymm3 +vpunpcklwd const0(%rip), %ymm3, %ymm7 +vpunpckhwd const0(%rip), %ymm3, %ymm3 +vmovdqa 544(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm7, %ymm2 +vpaddd %ymm6, %ymm3, %ymm4 +vpsubd %ymm9, %ymm2, %ymm2 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm11, %ymm7, %ymm11 +vpsubd %ymm6, %ymm3, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1568(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm3 +vpunpckhwd const0(%rip), %ymm11, %ymm7 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm7, %ymm7 +vpsubd %ymm3, %ymm2, %ymm2 +vpsubd %ymm7, %ymm4, %ymm4 +vpsrld $1, %ymm2, %ymm2 +vpsrld $1, %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpackusdw %ymm4, %ymm2, %ymm4 +vmovdqa 800(%r8), %ymm2 +vpaddw 1056(%r8), %ymm2, %ymm7 +vpsubw 1056(%r8), %ymm2, %ymm2 +vpsrlw $2, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsllw $1, %ymm5, %ymm3 +vpsubw %ymm3, %ymm7, %ymm3 +vpsllw $7, %ymm11, %ymm7 +vpsubw %ymm7, %ymm3, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm4, %ymm7, %ymm7 +vmovdqa 1312(%r8), %ymm3 +vpsubw %ymm5, %ymm3, %ymm3 +vpmullw %ymm15, %ymm11, %ymm8 +vpsubw %ymm8, %ymm3, %ymm8 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm7, %ymm4, %ymm4 +vpmullw %ymm12, %ymm7, %ymm3 +vpaddw %ymm3, %ymm4, %ymm3 +vpmullw %ymm12, %ymm3, %ymm3 +vpsubw %ymm3, %ymm8, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vpsubw %ymm3, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vpmullw %ymm13, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_4_3_1(%rip), %ymm7, %ymm8 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $139, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm9 +vpor %ymm9, %ymm7, %ymm7 +vpaddw 2080(%r8), %ymm5, %ymm5 +vpaddw %ymm7, %ymm5, %ymm5 +vmovdqa %xmm8, 2080(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_4_3_1(%rip), %ymm3, %ymm8 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $139, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm9 +vpor %ymm9, %ymm3, %ymm3 +vpaddw 2336(%r8), %ymm6, %ymm6 +vpaddw %ymm3, %ymm6, %ymm6 +vmovdqa %xmm8, 2336(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_4_3_1(%rip), %ymm11, %ymm8 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $139, %ymm8, %ymm8 +vpand mask_keephigh(%rip), %ymm8, %ymm9 +vpor %ymm9, %ymm11, %ymm11 +vpaddw 2592(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vmovdqa %xmm8, 2592(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %xmm5, 152(%rdi) +vextracti128 $1, %ymm5, %xmm5 +vmovq %xmm5, 168(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 504(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 520(%rdi) +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %xmm4, 856(%rdi) +vextracti128 $1, %ymm4, %xmm4 +vmovq %xmm4, 872(%rdi) +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %xmm2, 1208(%rdi) +vextracti128 $1, %ymm2, %xmm2 +vmovq %xmm2, 1224(%rdi) +vmovdqa 64(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm3 +vpunpckhwd const0(%rip), %ymm11, %ymm7 +vpslld $1, %ymm3, %ymm3 +vpslld $1, %ymm7, %ymm7 +vmovdqa 320(%r8), %ymm2 +vpunpcklwd const0(%rip), %ymm2, %ymm4 +vpunpckhwd const0(%rip), %ymm2, %ymm2 +vmovdqa 576(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm4, %ymm8 +vpaddd %ymm6, %ymm2, %ymm9 +vpsubd %ymm3, %ymm8, %ymm8 +vpsubd %ymm7, %ymm9, %ymm9 +vpsubd %ymm5, %ymm4, %ymm5 +vpsubd %ymm6, %ymm2, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1600(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm4 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm4, %ymm4 +vpsubd %ymm2, %ymm8, %ymm8 +vpsubd %ymm4, %ymm9, %ymm9 +vpsrld $1, %ymm8, %ymm8 +vpsrld $1, %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpackusdw %ymm9, %ymm8, %ymm9 +vmovdqa 832(%r8), %ymm8 +vpaddw 1088(%r8), %ymm8, %ymm4 +vpsubw 1088(%r8), %ymm8, %ymm8 +vpsrlw $2, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsllw $1, %ymm11, %ymm2 +vpsubw %ymm2, %ymm4, %ymm2 +vpsllw $7, %ymm5, %ymm4 +vpsubw %ymm4, %ymm2, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm9, %ymm4, %ymm4 +vmovdqa 1344(%r8), %ymm2 +vpsubw %ymm11, %ymm2, %ymm2 +vpmullw %ymm15, %ymm5, %ymm7 +vpsubw %ymm7, %ymm2, %ymm7 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm4, %ymm9, %ymm9 +vpmullw %ymm12, %ymm4, %ymm2 +vpaddw %ymm2, %ymm9, %ymm2 +vpmullw %ymm12, %ymm2, %ymm2 +vpsubw %ymm2, %ymm7, %ymm2 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm6, %ymm2, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vpmullw %ymm13, %ymm2, %ymm2 +vpsubw %ymm2, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_4_3_1(%rip), %ymm4, %ymm7 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $139, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm3 +vpor %ymm3, %ymm4, %ymm4 +vpaddw 2112(%r8), %ymm11, %ymm11 +vpaddw %ymm4, %ymm11, %ymm11 +vmovdqa %xmm7, 2112(%r8) +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_4_3_1(%rip), %ymm2, %ymm7 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $139, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm3 +vpor %ymm3, %ymm2, %ymm2 +vpaddw 2368(%r8), %ymm6, %ymm6 +vpaddw %ymm2, %ymm6, %ymm6 +vmovdqa %xmm7, 2368(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_4_3_1(%rip), %ymm5, %ymm7 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $139, %ymm7, %ymm7 +vpand mask_keephigh(%rip), %ymm7, %ymm3 +vpor %ymm3, %ymm5, %ymm5 +vpaddw 2624(%r8), %ymm9, %ymm9 +vpaddw %ymm5, %ymm9, %ymm9 +vmovdqa %xmm7, 2624(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %xmm11, 240(%rdi) +vextracti128 $1, %ymm11, %xmm11 +vmovq %xmm11, 256(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 592(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 608(%rdi) +vpand mask_mod8192(%rip), %ymm9, %ymm9 +vmovdqu %xmm9, 944(%rdi) +vextracti128 $1, %ymm9, %xmm9 +vmovq %xmm9, 960(%rdi) +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %xmm8, 1296(%rdi) +vextracti128 $1, %ymm8, %xmm8 +vmovq %xmm8, 1312(%rdi) +vmovdqa 96(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm2 +vpunpckhwd const0(%rip), %ymm5, %ymm4 +vpslld $1, %ymm2, %ymm2 +vpslld $1, %ymm4, %ymm4 +vmovdqa 352(%r8), %ymm8 +vpunpcklwd const0(%rip), %ymm8, %ymm9 +vpunpckhwd const0(%rip), %ymm8, %ymm8 +vmovdqa 608(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm9, %ymm7 +vpaddd %ymm6, %ymm8, %ymm3 +vpsubd %ymm2, %ymm7, %ymm7 +vpsubd %ymm4, %ymm3, %ymm3 +vpsubd %ymm11, %ymm9, %ymm11 +vpsubd %ymm6, %ymm8, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1632(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm9 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm9, %ymm9 +vpsubd %ymm8, %ymm7, %ymm7 +vpsubd %ymm9, %ymm3, %ymm3 +vpsrld $1, %ymm7, %ymm7 +vpsrld $1, %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpackusdw %ymm3, %ymm7, %ymm3 +vmovdqa 864(%r8), %ymm7 +vpaddw 1120(%r8), %ymm7, %ymm9 +vpsubw 1120(%r8), %ymm7, %ymm7 +vpsrlw $2, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsllw $1, %ymm5, %ymm8 +vpsubw %ymm8, %ymm9, %ymm8 +vpsllw $7, %ymm11, %ymm9 +vpsubw %ymm9, %ymm8, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm3, %ymm9, %ymm9 +vmovdqa 1376(%r8), %ymm8 +vpsubw %ymm5, %ymm8, %ymm8 +vpmullw %ymm15, %ymm11, %ymm4 +vpsubw %ymm4, %ymm8, %ymm4 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm3 +vpmullw %ymm12, %ymm9, %ymm8 +vpaddw %ymm8, %ymm3, %ymm8 +vpmullw %ymm12, %ymm8, %ymm8 +vpsubw %ymm8, %ymm4, %ymm8 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm6, %ymm8, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm7, %ymm8, %ymm8 +vpsubw %ymm8, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vpmullw %ymm13, %ymm8, %ymm8 +vpsubw %ymm8, %ymm6, %ymm6 +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_4_3_1(%rip), %ymm9, %ymm4 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $139, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm9, %ymm9 +vpaddw 2144(%r8), %ymm5, %ymm5 +vpaddw %ymm9, %ymm5, %ymm5 +vmovdqa %xmm4, 2144(%r8) +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_4_3_1(%rip), %ymm8, %ymm4 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $139, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm8, %ymm8 +vpaddw 2400(%r8), %ymm6, %ymm6 +vpaddw %ymm8, %ymm6, %ymm6 +vmovdqa %xmm4, 2400(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_4_3_1(%rip), %ymm11, %ymm4 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $139, %ymm4, %ymm4 +vpand mask_keephigh(%rip), %ymm4, %ymm2 +vpor %ymm2, %ymm11, %ymm11 +vpaddw 2656(%r8), %ymm3, %ymm3 +vpaddw %ymm11, %ymm3, %ymm3 +vmovdqa %xmm4, 2656(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %xmm5, 328(%rdi) +vextracti128 $1, %ymm5, %xmm5 +vmovq %xmm5, 344(%rdi) +vpshufb shufmin1_mask3(%rip), %ymm5, %ymm5 +vmovdqa %xmm5, 1792(%r8) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 680(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 696(%rdi) +vpshufb shufmin1_mask3(%rip), %ymm6, %ymm6 +vmovdqa %xmm6, 1824(%r8) +vpand mask_mod8192(%rip), %ymm3, %ymm3 +vmovdqu %xmm3, 1032(%rdi) +vextracti128 $1, %ymm3, %xmm3 +vmovq %xmm3, 1048(%rdi) +vpshufb shufmin1_mask3(%rip), %ymm3, %ymm3 +vmovdqa %xmm3, 1856(%r8) +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %xmm7, 1384(%rdi) +vextracti128 $1, %ymm7, %xmm7 +vpextrw $0, %xmm7, 1400(%rdi) +vpshufb shufmin1_mask3(%rip), %ymm7, %ymm7 +vmovdqa %xmm7, 1888(%r8) +vmovdqa 128(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm8 +vpunpckhwd const0(%rip), %ymm11, %ymm9 +vpslld $1, %ymm8, %ymm8 +vpslld $1, %ymm9, %ymm9 +vmovdqa 384(%r8), %ymm7 +vpunpcklwd const0(%rip), %ymm7, %ymm3 +vpunpckhwd const0(%rip), %ymm7, %ymm7 +vmovdqa 640(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm3, %ymm4 +vpaddd %ymm6, %ymm7, %ymm2 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm9, %ymm2, %ymm2 +vpsubd %ymm5, %ymm3, %ymm5 +vpsubd %ymm6, %ymm7, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1664(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm7 +vpunpckhwd const0(%rip), %ymm5, %ymm3 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm3, %ymm3 +vpsubd %ymm7, %ymm4, %ymm4 +vpsubd %ymm3, %ymm2, %ymm2 +vpsrld $1, %ymm4, %ymm4 +vpsrld $1, %ymm2, %ymm2 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm2, %ymm2 +vpackusdw %ymm2, %ymm4, %ymm2 +vmovdqa 896(%r8), %ymm4 +vpaddw 1152(%r8), %ymm4, %ymm3 +vpsubw 1152(%r8), %ymm4, %ymm4 +vpsrlw $2, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsllw $1, %ymm11, %ymm7 +vpsubw %ymm7, %ymm3, %ymm7 +vpsllw $7, %ymm5, %ymm3 +vpsubw %ymm3, %ymm7, %ymm3 +vpsrlw $3, %ymm3, %ymm3 +vpsubw %ymm2, %ymm3, %ymm3 +vmovdqa 1408(%r8), %ymm7 +vpsubw %ymm11, %ymm7, %ymm7 +vpmullw %ymm15, %ymm5, %ymm9 +vpsubw %ymm9, %ymm7, %ymm9 +vpmullw %ymm14, %ymm3, %ymm3 +vpsubw %ymm3, %ymm2, %ymm2 +vpmullw %ymm12, %ymm3, %ymm7 +vpaddw %ymm7, %ymm2, %ymm7 +vpmullw %ymm12, %ymm7, %ymm7 +vpsubw %ymm7, %ymm9, %ymm7 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm6, %ymm7, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm4, %ymm7, %ymm7 +vpsubw %ymm7, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vpmullw %ymm13, %ymm7, %ymm7 +vpsubw %ymm7, %ymm6, %ymm6 +vmovdqu 416(%rdi), %ymm9 +vmovdqu 768(%rdi), %ymm8 +vmovdqu 1120(%rdi), %ymm10 +vpaddw %ymm11, %ymm9, %ymm11 +vpaddw %ymm6, %ymm8, %ymm6 +vpaddw %ymm2, %ymm10, %ymm2 +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_4_3_1(%rip), %ymm4, %ymm10 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $139, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm8 +vpor %ymm8, %ymm4, %ymm4 +vmovdqu 64(%rdi), %ymm8 +vpaddw 1920(%r8), %ymm8, %ymm8 +vpaddw %ymm4, %ymm8, %ymm8 +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %xmm8, 64(%rdi) +vextracti128 $1, %ymm8, %xmm8 +vmovq %xmm8, 80(%rdi) +vmovdqa %xmm10, 1920(%r8) +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_4_3_1(%rip), %ymm3, %ymm10 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $139, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm8 +vpor %ymm8, %ymm3, %ymm3 +vpaddw 2176(%r8), %ymm11, %ymm11 +vpaddw %ymm3, %ymm11, %ymm11 +vmovdqa %xmm10, 2176(%r8) +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_4_3_1(%rip), %ymm7, %ymm10 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $139, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm8 +vpor %ymm8, %ymm7, %ymm7 +vpaddw 2432(%r8), %ymm6, %ymm6 +vpaddw %ymm7, %ymm6, %ymm6 +vmovdqa %xmm10, 2432(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_4_3_1(%rip), %ymm5, %ymm10 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $139, %ymm10, %ymm10 +vpand mask_keephigh(%rip), %ymm10, %ymm8 +vpor %ymm8, %ymm5, %ymm5 +vpaddw 2688(%r8), %ymm2, %ymm2 +vpaddw %ymm5, %ymm2, %ymm2 +vmovdqa %xmm10, 2688(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %xmm11, 416(%rdi) +vextracti128 $1, %ymm11, %xmm11 +vmovq %xmm11, 432(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 768(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 784(%rdi) +vpand mask_mod8192(%rip), %ymm2, %ymm2 +vmovdqu %xmm2, 1120(%rdi) +vextracti128 $1, %ymm2, %xmm2 +vmovq %xmm2, 1136(%rdi) +vmovdqa 160(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm7 +vpunpckhwd const0(%rip), %ymm5, %ymm3 +vpslld $1, %ymm7, %ymm7 +vpslld $1, %ymm3, %ymm3 +vmovdqa 416(%r8), %ymm4 +vpunpcklwd const0(%rip), %ymm4, %ymm2 +vpunpckhwd const0(%rip), %ymm4, %ymm4 +vmovdqa 672(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm2, %ymm10 +vpaddd %ymm6, %ymm4, %ymm8 +vpsubd %ymm7, %ymm10, %ymm10 +vpsubd %ymm3, %ymm8, %ymm8 +vpsubd %ymm11, %ymm2, %ymm11 +vpsubd %ymm6, %ymm4, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1696(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm2, %ymm2 +vpsubd %ymm4, %ymm10, %ymm10 +vpsubd %ymm2, %ymm8, %ymm8 +vpsrld $1, %ymm10, %ymm10 +vpsrld $1, %ymm8, %ymm8 +vpand mask32_to_16(%rip), %ymm10, %ymm10 +vpand mask32_to_16(%rip), %ymm8, %ymm8 +vpackusdw %ymm8, %ymm10, %ymm8 +vmovdqa 928(%r8), %ymm10 +vpaddw 1184(%r8), %ymm10, %ymm2 +vpsubw 1184(%r8), %ymm10, %ymm10 +vpsrlw $2, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsllw $1, %ymm5, %ymm4 +vpsubw %ymm4, %ymm2, %ymm4 +vpsllw $7, %ymm11, %ymm2 +vpsubw %ymm2, %ymm4, %ymm2 +vpsrlw $3, %ymm2, %ymm2 +vpsubw %ymm8, %ymm2, %ymm2 +vmovdqa 1440(%r8), %ymm4 +vpsubw %ymm5, %ymm4, %ymm4 +vpmullw %ymm15, %ymm11, %ymm3 +vpsubw %ymm3, %ymm4, %ymm3 +vpmullw %ymm14, %ymm2, %ymm2 +vpsubw %ymm2, %ymm8, %ymm8 +vpmullw %ymm12, %ymm2, %ymm4 +vpaddw %ymm4, %ymm8, %ymm4 +vpmullw %ymm12, %ymm4, %ymm4 +vpsubw %ymm4, %ymm3, %ymm4 +vpmullw %ymm14, %ymm4, %ymm4 +vpsubw %ymm6, %ymm4, %ymm4 +vpsrlw $3, %ymm4, %ymm4 +vpsubw %ymm10, %ymm4, %ymm4 +vpsubw %ymm4, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vpmullw %ymm13, %ymm4, %ymm4 +vpsubw %ymm4, %ymm6, %ymm6 +vmovdqu 504(%rdi), %ymm3 +vmovdqu 856(%rdi), %ymm7 +vmovdqu 1208(%rdi), %ymm9 +vpaddw %ymm5, %ymm3, %ymm5 +vpaddw %ymm6, %ymm7, %ymm6 +vpaddw %ymm8, %ymm9, %ymm8 +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_4_3_1(%rip), %ymm10, %ymm9 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $139, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm7 +vpor %ymm7, %ymm10, %ymm10 +vmovdqu 152(%rdi), %ymm7 +vpaddw 1952(%r8), %ymm7, %ymm7 +vpaddw %ymm10, %ymm7, %ymm7 +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %xmm7, 152(%rdi) +vextracti128 $1, %ymm7, %xmm7 +vmovq %xmm7, 168(%rdi) +vmovdqa %xmm9, 1952(%r8) +vpshufb shuf48_16(%rip), %ymm2, %ymm2 +vpand mask3_5_4_3_1(%rip), %ymm2, %ymm9 +vpand mask5_3_5_3(%rip), %ymm2, %ymm2 +vpermq $139, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm7 +vpor %ymm7, %ymm2, %ymm2 +vpaddw 2208(%r8), %ymm5, %ymm5 +vpaddw %ymm2, %ymm5, %ymm5 +vmovdqa %xmm9, 2208(%r8) +vpshufb shuf48_16(%rip), %ymm4, %ymm4 +vpand mask3_5_4_3_1(%rip), %ymm4, %ymm9 +vpand mask5_3_5_3(%rip), %ymm4, %ymm4 +vpermq $139, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm7 +vpor %ymm7, %ymm4, %ymm4 +vpaddw 2464(%r8), %ymm6, %ymm6 +vpaddw %ymm4, %ymm6, %ymm6 +vmovdqa %xmm9, 2464(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_4_3_1(%rip), %ymm11, %ymm9 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $139, %ymm9, %ymm9 +vpand mask_keephigh(%rip), %ymm9, %ymm7 +vpor %ymm7, %ymm11, %ymm11 +vpaddw 2720(%r8), %ymm8, %ymm8 +vpaddw %ymm11, %ymm8, %ymm8 +vmovdqa %xmm9, 2720(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %xmm5, 504(%rdi) +vextracti128 $1, %ymm5, %xmm5 +vmovq %xmm5, 520(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 856(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 872(%rdi) +vpand mask_mod8192(%rip), %ymm8, %ymm8 +vmovdqu %xmm8, 1208(%rdi) +vextracti128 $1, %ymm8, %xmm8 +vmovq %xmm8, 1224(%rdi) +vmovdqa 192(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm4 +vpunpckhwd const0(%rip), %ymm11, %ymm2 +vpslld $1, %ymm4, %ymm4 +vpslld $1, %ymm2, %ymm2 +vmovdqa 448(%r8), %ymm10 +vpunpcklwd const0(%rip), %ymm10, %ymm8 +vpunpckhwd const0(%rip), %ymm10, %ymm10 +vmovdqa 704(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm5 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm5, %ymm8, %ymm9 +vpaddd %ymm6, %ymm10, %ymm7 +vpsubd %ymm4, %ymm9, %ymm9 +vpsubd %ymm2, %ymm7, %ymm7 +vpsubd %ymm5, %ymm8, %ymm5 +vpsubd %ymm6, %ymm10, %ymm6 +vpsrld $1, %ymm5, %ymm5 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm5, %ymm5 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm5, %ymm6 +vmovdqa 1728(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm10 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm8, %ymm8 +vpsubd %ymm10, %ymm9, %ymm9 +vpsubd %ymm8, %ymm7, %ymm7 +vpsrld $1, %ymm9, %ymm9 +vpsrld $1, %ymm7, %ymm7 +vpand mask32_to_16(%rip), %ymm9, %ymm9 +vpand mask32_to_16(%rip), %ymm7, %ymm7 +vpackusdw %ymm7, %ymm9, %ymm7 +vmovdqa 960(%r8), %ymm9 +vpaddw 1216(%r8), %ymm9, %ymm8 +vpsubw 1216(%r8), %ymm9, %ymm9 +vpsrlw $2, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsllw $1, %ymm11, %ymm10 +vpsubw %ymm10, %ymm8, %ymm10 +vpsllw $7, %ymm5, %ymm8 +vpsubw %ymm8, %ymm10, %ymm8 +vpsrlw $3, %ymm8, %ymm8 +vpsubw %ymm7, %ymm8, %ymm8 +vmovdqa 1472(%r8), %ymm10 +vpsubw %ymm11, %ymm10, %ymm10 +vpmullw %ymm15, %ymm5, %ymm2 +vpsubw %ymm2, %ymm10, %ymm2 +vpmullw %ymm14, %ymm8, %ymm8 +vpsubw %ymm8, %ymm7, %ymm7 +vpmullw %ymm12, %ymm8, %ymm10 +vpaddw %ymm10, %ymm7, %ymm10 +vpmullw %ymm12, %ymm10, %ymm10 +vpsubw %ymm10, %ymm2, %ymm10 +vpmullw %ymm14, %ymm10, %ymm10 +vpsubw %ymm6, %ymm10, %ymm10 +vpsrlw $3, %ymm10, %ymm10 +vpsubw %ymm9, %ymm10, %ymm10 +vpsubw %ymm10, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vpmullw %ymm13, %ymm10, %ymm10 +vpsubw %ymm10, %ymm6, %ymm6 +vmovdqu 592(%rdi), %ymm2 +vmovdqu 944(%rdi), %ymm4 +vmovdqu 1296(%rdi), %ymm3 +vpaddw %ymm11, %ymm2, %ymm11 +vpaddw %ymm6, %ymm4, %ymm6 +vpaddw %ymm7, %ymm3, %ymm7 +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_4_3_1(%rip), %ymm9, %ymm3 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $139, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm9, %ymm9 +vmovdqu 240(%rdi), %ymm4 +vpaddw 1984(%r8), %ymm4, %ymm4 +vpaddw %ymm9, %ymm4, %ymm4 +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %xmm4, 240(%rdi) +vextracti128 $1, %ymm4, %xmm4 +vmovq %xmm4, 256(%rdi) +vmovdqa %xmm3, 1984(%r8) +vpshufb shuf48_16(%rip), %ymm8, %ymm8 +vpand mask3_5_4_3_1(%rip), %ymm8, %ymm3 +vpand mask5_3_5_3(%rip), %ymm8, %ymm8 +vpermq $139, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm8, %ymm8 +vpaddw 2240(%r8), %ymm11, %ymm11 +vpaddw %ymm8, %ymm11, %ymm11 +vmovdqa %xmm3, 2240(%r8) +vpshufb shuf48_16(%rip), %ymm10, %ymm10 +vpand mask3_5_4_3_1(%rip), %ymm10, %ymm3 +vpand mask5_3_5_3(%rip), %ymm10, %ymm10 +vpermq $139, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm10, %ymm10 +vpaddw 2496(%r8), %ymm6, %ymm6 +vpaddw %ymm10, %ymm6, %ymm6 +vmovdqa %xmm3, 2496(%r8) +vpshufb shuf48_16(%rip), %ymm5, %ymm5 +vpand mask3_5_4_3_1(%rip), %ymm5, %ymm3 +vpand mask5_3_5_3(%rip), %ymm5, %ymm5 +vpermq $139, %ymm3, %ymm3 +vpand mask_keephigh(%rip), %ymm3, %ymm4 +vpor %ymm4, %ymm5, %ymm5 +vpaddw 2752(%r8), %ymm7, %ymm7 +vpaddw %ymm5, %ymm7, %ymm7 +vmovdqa %xmm3, 2752(%r8) +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %xmm11, 592(%rdi) +vextracti128 $1, %ymm11, %xmm11 +vmovq %xmm11, 608(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 944(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 960(%rdi) +vpand mask_mod8192(%rip), %ymm7, %ymm7 +vmovdqu %xmm7, 1296(%rdi) +vextracti128 $1, %ymm7, %xmm7 +vmovq %xmm7, 1312(%rdi) +vmovdqa 224(%r8), %ymm5 +vpunpcklwd const0(%rip), %ymm5, %ymm10 +vpunpckhwd const0(%rip), %ymm5, %ymm8 +vpslld $1, %ymm10, %ymm10 +vpslld $1, %ymm8, %ymm8 +vmovdqa 480(%r8), %ymm9 +vpunpcklwd const0(%rip), %ymm9, %ymm7 +vpunpckhwd const0(%rip), %ymm9, %ymm9 +vmovdqa 736(%r8), %ymm6 +vpunpcklwd const0(%rip), %ymm6, %ymm11 +vpunpckhwd const0(%rip), %ymm6, %ymm6 +vpaddd %ymm11, %ymm7, %ymm3 +vpaddd %ymm6, %ymm9, %ymm4 +vpsubd %ymm10, %ymm3, %ymm3 +vpsubd %ymm8, %ymm4, %ymm4 +vpsubd %ymm11, %ymm7, %ymm11 +vpsubd %ymm6, %ymm9, %ymm6 +vpsrld $1, %ymm11, %ymm11 +vpsrld $1, %ymm6, %ymm6 +vpand mask32_to_16(%rip), %ymm11, %ymm11 +vpand mask32_to_16(%rip), %ymm6, %ymm6 +vpackusdw %ymm6, %ymm11, %ymm6 +vmovdqa 1760(%r8), %ymm11 +vpunpcklwd const0(%rip), %ymm11, %ymm9 +vpunpckhwd const0(%rip), %ymm11, %ymm7 +vpslld $1, %ymm9, %ymm9 +vpslld $1, %ymm7, %ymm7 +vpsubd %ymm9, %ymm3, %ymm3 +vpsubd %ymm7, %ymm4, %ymm4 +vpsrld $1, %ymm3, %ymm3 +vpsrld $1, %ymm4, %ymm4 +vpand mask32_to_16(%rip), %ymm3, %ymm3 +vpand mask32_to_16(%rip), %ymm4, %ymm4 +vpackusdw %ymm4, %ymm3, %ymm4 +vmovdqa 992(%r8), %ymm3 +vpaddw 1248(%r8), %ymm3, %ymm7 +vpsubw 1248(%r8), %ymm3, %ymm3 +vpsrlw $2, %ymm3, %ymm3 +vpsubw %ymm6, %ymm3, %ymm3 +vpmullw %ymm14, %ymm3, %ymm3 +vpsllw $1, %ymm5, %ymm9 +vpsubw %ymm9, %ymm7, %ymm9 +vpsllw $7, %ymm11, %ymm7 +vpsubw %ymm7, %ymm9, %ymm7 +vpsrlw $3, %ymm7, %ymm7 +vpsubw %ymm4, %ymm7, %ymm7 +vmovdqa 1504(%r8), %ymm9 +vpsubw %ymm5, %ymm9, %ymm9 +vpmullw %ymm15, %ymm11, %ymm8 +vpsubw %ymm8, %ymm9, %ymm8 +vpmullw %ymm14, %ymm7, %ymm7 +vpsubw %ymm7, %ymm4, %ymm4 +vpmullw %ymm12, %ymm7, %ymm9 +vpaddw %ymm9, %ymm4, %ymm9 +vpmullw %ymm12, %ymm9, %ymm9 +vpsubw %ymm9, %ymm8, %ymm9 +vpmullw %ymm14, %ymm9, %ymm9 +vpsubw %ymm6, %ymm9, %ymm9 +vpsrlw $3, %ymm9, %ymm9 +vpsubw %ymm3, %ymm9, %ymm9 +vpsubw %ymm9, %ymm3, %ymm3 +vpsubw %ymm3, %ymm6, %ymm6 +vpmullw %ymm13, %ymm9, %ymm9 +vpsubw %ymm9, %ymm6, %ymm6 +vextracti128 $1, %ymm4, %xmm8 +vpshufb shufmin1_mask3(%rip), %ymm8, %ymm8 +vmovdqa %ymm8, 2816(%r8) +vextracti128 $1, %ymm3, %xmm8 +vpshufb shufmin1_mask3(%rip), %ymm8, %ymm8 +vmovdqa %ymm8, 2848(%r8) +vextracti128 $1, %ymm7, %xmm8 +vpshufb shufmin1_mask3(%rip), %ymm8, %ymm8 +vmovdqa %ymm8, 2880(%r8) +vmovdqu 680(%rdi), %ymm8 +vmovdqu 1032(%rdi), %ymm10 + +# Only 18 bytes can be read at 1384, but vmovdqu reads 32. +# Copy 18 bytes to the red zone and zero pad to 32 bytes. +xor %r9, %r9 +movq %r9, -16(%rsp) +movq %r9, -8(%rsp) +movq 1384(%rdi), %r9 +movq %r9, -32(%rsp) +movq 1384+8(%rdi), %r9 +movq %r9, -24(%rsp) +movw 1384+16(%rdi), %r9w +movw %r9w, -16(%rsp) +vmovdqu -32(%rsp), %ymm2 + +vpaddw %ymm5, %ymm8, %ymm5 +vpaddw %ymm6, %ymm10, %ymm6 +vpaddw %ymm4, %ymm2, %ymm4 +vpshufb shuf48_16(%rip), %ymm3, %ymm3 +vpand mask3_5_4_3_1(%rip), %ymm3, %ymm2 +vpand mask5_3_5_3(%rip), %ymm3, %ymm3 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm10 +vpor %ymm10, %ymm3, %ymm3 +vmovdqu 328(%rdi), %ymm10 +vpaddw 2016(%r8), %ymm10, %ymm10 +vpaddw %ymm3, %ymm10, %ymm10 +vpand mask_mod8192(%rip), %ymm10, %ymm10 +vmovdqu %xmm10, 328(%rdi) +vextracti128 $1, %ymm10, %xmm10 +vmovq %xmm10, 344(%rdi) +vpshufb shufmin1_mask3(%rip), %ymm10, %ymm10 +vmovdqa %xmm10, 1792(%r8) +vmovdqa %xmm2, 2016(%r8) +vpshufb shuf48_16(%rip), %ymm7, %ymm7 +vpand mask3_5_4_3_1(%rip), %ymm7, %ymm2 +vpand mask5_3_5_3(%rip), %ymm7, %ymm7 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm10 +vpor %ymm10, %ymm7, %ymm7 +vpaddw 2272(%r8), %ymm5, %ymm5 +vpaddw %ymm7, %ymm5, %ymm5 +vmovdqa %xmm2, 2272(%r8) +vpshufb shuf48_16(%rip), %ymm9, %ymm9 +vpand mask3_5_4_3_1(%rip), %ymm9, %ymm2 +vpand mask5_3_5_3(%rip), %ymm9, %ymm9 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm10 +vpor %ymm10, %ymm9, %ymm9 +vpaddw 2528(%r8), %ymm6, %ymm6 +vpaddw %ymm9, %ymm6, %ymm6 +vmovdqa %xmm2, 2528(%r8) +vpshufb shuf48_16(%rip), %ymm11, %ymm11 +vpand mask3_5_4_3_1(%rip), %ymm11, %ymm2 +vpand mask5_3_5_3(%rip), %ymm11, %ymm11 +vpermq $139, %ymm2, %ymm2 +vpand mask_keephigh(%rip), %ymm2, %ymm10 +vpor %ymm10, %ymm11, %ymm11 +vpaddw 2784(%r8), %ymm4, %ymm4 +vpaddw %ymm11, %ymm4, %ymm4 +vmovdqa %xmm2, 2784(%r8) +vpand mask_mod8192(%rip), %ymm5, %ymm5 +vmovdqu %xmm5, 680(%rdi) +vextracti128 $1, %ymm5, %xmm5 +vmovq %xmm5, 696(%rdi) +vpand mask_mod8192(%rip), %ymm6, %ymm6 +vmovdqu %xmm6, 1032(%rdi) +vextracti128 $1, %ymm6, %xmm6 +vmovq %xmm6, 1048(%rdi) +vpand mask_mod8192(%rip), %ymm4, %ymm4 +vmovdqu %xmm4, 1384(%rdi) +vextracti128 $1, %ymm4, %xmm4 +vpextrw $0, %xmm4, 1400(%rdi) +vmovdqu 0(%rdi), %ymm11 +vpaddw 1888(%r8), %ymm11, %ymm11 +vpaddw 2816(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 0(%rdi) +vmovdqu 352(%rdi), %ymm11 +vpaddw 2528(%r8), %ymm11, %ymm11 +vpaddw 2848(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 352(%rdi) +vmovdqu 704(%rdi), %ymm11 +vpaddw 2784(%r8), %ymm11, %ymm11 +vpaddw 2880(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 704(%rdi) +vmovdqu 88(%rdi), %ymm11 +vpaddw 2048(%r8), %ymm11, %ymm11 +vpaddw 1920(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 88(%rdi) +vmovdqu 440(%rdi), %ymm11 +vpaddw 2304(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 440(%rdi) +vmovdqu 792(%rdi), %ymm11 +vpaddw 2560(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 792(%rdi) +vmovdqu 176(%rdi), %ymm11 +vpaddw 2080(%r8), %ymm11, %ymm11 +vpaddw 1952(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 176(%rdi) +vmovdqu 528(%rdi), %ymm11 +vpaddw 2336(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 528(%rdi) +vmovdqu 880(%rdi), %ymm11 +vpaddw 2592(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 880(%rdi) +vmovdqu 264(%rdi), %ymm11 +vpaddw 2112(%r8), %ymm11, %ymm11 +vpaddw 1984(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 264(%rdi) +vmovdqu 616(%rdi), %ymm11 +vpaddw 2368(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 616(%rdi) +vmovdqu 968(%rdi), %ymm11 +vpaddw 2624(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 968(%rdi) +vmovdqu 352(%rdi), %ymm11 +vpaddw 2144(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 352(%rdi) +vmovdqu 704(%rdi), %ymm11 +vpaddw 2400(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 704(%rdi) +vmovdqu 1056(%rdi), %ymm11 +vpaddw 2656(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 1056(%rdi) +vmovdqu 440(%rdi), %ymm11 +vpaddw 2176(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 440(%rdi) +vmovdqu 792(%rdi), %ymm11 +vpaddw 2432(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 792(%rdi) +vmovdqu 1144(%rdi), %ymm11 +vpaddw 2688(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 1144(%rdi) +vmovdqu 528(%rdi), %ymm11 +vpaddw 2208(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 528(%rdi) +vmovdqu 880(%rdi), %ymm11 +vpaddw 2464(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 880(%rdi) +vmovdqu 1232(%rdi), %ymm11 +vpaddw 2720(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 1232(%rdi) +vmovdqu 616(%rdi), %ymm11 +vpaddw 2240(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 616(%rdi) +vmovdqu 968(%rdi), %ymm11 +vpaddw 2496(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 968(%rdi) +vmovdqu 1320(%rdi), %ymm11 +vpaddw 2752(%r8), %ymm11, %ymm11 +vpand mask_mod8192(%rip), %ymm11, %ymm11 +vmovdqu %ymm11, 1320(%rdi) +pop %r12 +.cfi_restore r12 +pop %rbp +.cfi_restore rbp +.cfi_def_cfa_register rsp +.cfi_adjust_cfa_offset -8 +ret +.cfi_endproc +.size poly_Rq_mul,.-poly_Rq_mul + +#endif + +#if defined(__ELF__) +.section .note.GNU-stack,"",@progbits +#endif +#endif // defined(__x86_64__) && defined(__linux__) +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/hrss.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/hrss.c new file mode 100644 index 00000000..2f8de3a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/hrss.c @@ -0,0 +1,2236 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#define RESTRICT +#else +#define RESTRICT restrict +#endif + +#include "../internal.h" +#include "internal.h" + +#if defined(OPENSSL_SSE2) +#include +#endif + +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && defined(__ARM_NEON) +#include +#endif + +// This is an implementation of [HRSS], but with a KEM transformation based on +// [SXY]. The primary references are: + +// HRSS: https://eprint.iacr.org/2017/667.pdf +// HRSSNIST: +// https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents/round-1/submissions/NTRU_HRSS_KEM.zip +// SXY: https://eprint.iacr.org/2017/1005.pdf +// NTRUTN14: +// https://assets.onboardsecurity.com/static/downloads/NTRU/resources/NTRUTech014.pdf +// NTRUCOMP: https://eprint.iacr.org/2018/1174 +// SAFEGCD: https://gcd.cr.yp.to/papers.html#safegcd + + +// Vector operations. +// +// A couple of functions in this file can use vector operations to meaningful +// effect. If we're building for a target that has a supported vector unit, +// |HRSS_HAVE_VECTOR_UNIT| will be defined and |vec_t| will be typedefed to a +// 128-bit vector. The following functions abstract over the differences between +// NEON and SSE2 for implementing some vector operations. + +// TODO: MSVC can likely also be made to work with vector operations, but ^ must +// be replaced with _mm_xor_si128, etc. +#if defined(OPENSSL_SSE2) && (defined(__clang__) || !defined(_MSC_VER)) + +#define HRSS_HAVE_VECTOR_UNIT +typedef __m128i vec_t; + +// vec_capable returns one iff the current platform supports SSE2. +static int vec_capable(void) { return 1; } + +// vec_add performs a pair-wise addition of four uint16s from |a| and |b|. +static inline vec_t vec_add(vec_t a, vec_t b) { return _mm_add_epi16(a, b); } + +// vec_sub performs a pair-wise subtraction of four uint16s from |a| and |b|. +static inline vec_t vec_sub(vec_t a, vec_t b) { return _mm_sub_epi16(a, b); } + +// vec_mul multiplies each uint16_t in |a| by |b| and returns the resulting +// vector. +static inline vec_t vec_mul(vec_t a, uint16_t b) { + return _mm_mullo_epi16(a, _mm_set1_epi16(b)); +} + +// vec_fma multiplies each uint16_t in |b| by |c|, adds the result to |a|, and +// returns the resulting vector. +static inline vec_t vec_fma(vec_t a, vec_t b, uint16_t c) { + return _mm_add_epi16(a, _mm_mullo_epi16(b, _mm_set1_epi16(c))); +} + +// vec3_rshift_word right-shifts the 24 uint16_t's in |v| by one uint16. +static inline void vec3_rshift_word(vec_t v[3]) { + // Intel's left and right shifting is backwards compared to the order in + // memory because they're based on little-endian order of words (and not just + // bytes). So the shifts in this function will be backwards from what one + // might expect. + const __m128i carry0 = _mm_srli_si128(v[0], 14); + v[0] = _mm_slli_si128(v[0], 2); + + const __m128i carry1 = _mm_srli_si128(v[1], 14); + v[1] = _mm_slli_si128(v[1], 2); + v[1] |= carry0; + + v[2] = _mm_slli_si128(v[2], 2); + v[2] |= carry1; +} + +// vec4_rshift_word right-shifts the 32 uint16_t's in |v| by one uint16. +static inline void vec4_rshift_word(vec_t v[4]) { + // Intel's left and right shifting is backwards compared to the order in + // memory because they're based on little-endian order of words (and not just + // bytes). So the shifts in this function will be backwards from what one + // might expect. + const __m128i carry0 = _mm_srli_si128(v[0], 14); + v[0] = _mm_slli_si128(v[0], 2); + + const __m128i carry1 = _mm_srli_si128(v[1], 14); + v[1] = _mm_slli_si128(v[1], 2); + v[1] |= carry0; + + const __m128i carry2 = _mm_srli_si128(v[2], 14); + v[2] = _mm_slli_si128(v[2], 2); + v[2] |= carry1; + + v[3] = _mm_slli_si128(v[3], 2); + v[3] |= carry2; +} + +// vec_merge_3_5 takes the final three uint16_t's from |left|, appends the first +// five from |right|, and returns the resulting vector. +static inline vec_t vec_merge_3_5(vec_t left, vec_t right) { + return _mm_srli_si128(left, 10) | _mm_slli_si128(right, 6); +} + +// poly3_vec_lshift1 left-shifts the 768 bits in |a_s|, and in |a_a|, by one +// bit. +static inline void poly3_vec_lshift1(vec_t a_s[6], vec_t a_a[6]) { + vec_t carry_s = {0}; + vec_t carry_a = {0}; + + for (int i = 0; i < 6; i++) { + vec_t next_carry_s = _mm_srli_epi64(a_s[i], 63); + a_s[i] = _mm_slli_epi64(a_s[i], 1); + a_s[i] |= _mm_slli_si128(next_carry_s, 8); + a_s[i] |= carry_s; + carry_s = _mm_srli_si128(next_carry_s, 8); + + vec_t next_carry_a = _mm_srli_epi64(a_a[i], 63); + a_a[i] = _mm_slli_epi64(a_a[i], 1); + a_a[i] |= _mm_slli_si128(next_carry_a, 8); + a_a[i] |= carry_a; + carry_a = _mm_srli_si128(next_carry_a, 8); + } +} + +// poly3_vec_rshift1 right-shifts the 768 bits in |a_s|, and in |a_a|, by one +// bit. +static inline void poly3_vec_rshift1(vec_t a_s[6], vec_t a_a[6]) { + vec_t carry_s = {0}; + vec_t carry_a = {0}; + + for (int i = 5; i >= 0; i--) { + const vec_t next_carry_s = _mm_slli_epi64(a_s[i], 63); + a_s[i] = _mm_srli_epi64(a_s[i], 1); + a_s[i] |= _mm_srli_si128(next_carry_s, 8); + a_s[i] |= carry_s; + carry_s = _mm_slli_si128(next_carry_s, 8); + + const vec_t next_carry_a = _mm_slli_epi64(a_a[i], 63); + a_a[i] = _mm_srli_epi64(a_a[i], 1); + a_a[i] |= _mm_srli_si128(next_carry_a, 8); + a_a[i] |= carry_a; + carry_a = _mm_slli_si128(next_carry_a, 8); + } +} + +// vec_broadcast_bit duplicates the least-significant bit in |a| to all bits in +// a vector and returns the result. +static inline vec_t vec_broadcast_bit(vec_t a) { + return _mm_shuffle_epi32(_mm_srai_epi32(_mm_slli_epi64(a, 63), 31), + 0b01010101); +} + +// vec_get_word returns the |i|th uint16_t in |v|. (This is a macro because the +// compiler requires that |i| be a compile-time constant.) +#define vec_get_word(v, i) _mm_extract_epi16(v, i) + +#elif (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && defined(__ARM_NEON) + +#define HRSS_HAVE_VECTOR_UNIT +typedef uint16x8_t vec_t; + +// These functions perform the same actions as the SSE2 function of the same +// name, above. + +static int vec_capable(void) { return CRYPTO_is_NEON_capable(); } + +static inline vec_t vec_add(vec_t a, vec_t b) { return a + b; } + +static inline vec_t vec_sub(vec_t a, vec_t b) { return a - b; } + +static inline vec_t vec_mul(vec_t a, uint16_t b) { return vmulq_n_u16(a, b); } + +static inline vec_t vec_fma(vec_t a, vec_t b, uint16_t c) { + return vmlaq_n_u16(a, b, c); +} + +static inline void vec3_rshift_word(vec_t v[3]) { + const uint16x8_t kZero = {0}; + v[2] = vextq_u16(v[1], v[2], 7); + v[1] = vextq_u16(v[0], v[1], 7); + v[0] = vextq_u16(kZero, v[0], 7); +} + +static inline void vec4_rshift_word(vec_t v[4]) { + const uint16x8_t kZero = {0}; + v[3] = vextq_u16(v[2], v[3], 7); + v[2] = vextq_u16(v[1], v[2], 7); + v[1] = vextq_u16(v[0], v[1], 7); + v[0] = vextq_u16(kZero, v[0], 7); +} + +static inline vec_t vec_merge_3_5(vec_t left, vec_t right) { + return vextq_u16(left, right, 5); +} + +static inline uint16_t vec_get_word(vec_t v, unsigned i) { + return v[i]; +} + +#if !defined(OPENSSL_AARCH64) + +static inline vec_t vec_broadcast_bit(vec_t a) { + a = (vec_t)vshrq_n_s16(((int16x8_t)a) << 15, 15); + return vdupq_lane_u16(vget_low_u16(a), 0); +} + +static inline void poly3_vec_lshift1(vec_t a_s[6], vec_t a_a[6]) { + vec_t carry_s = {0}; + vec_t carry_a = {0}; + const vec_t kZero = {0}; + + for (int i = 0; i < 6; i++) { + vec_t next_carry_s = a_s[i] >> 15; + a_s[i] <<= 1; + a_s[i] |= vextq_u16(kZero, next_carry_s, 7); + a_s[i] |= carry_s; + carry_s = vextq_u16(next_carry_s, kZero, 7); + + vec_t next_carry_a = a_a[i] >> 15; + a_a[i] <<= 1; + a_a[i] |= vextq_u16(kZero, next_carry_a, 7); + a_a[i] |= carry_a; + carry_a = vextq_u16(next_carry_a, kZero, 7); + } +} + +static inline void poly3_vec_rshift1(vec_t a_s[6], vec_t a_a[6]) { + vec_t carry_s = {0}; + vec_t carry_a = {0}; + const vec_t kZero = {0}; + + for (int i = 5; i >= 0; i--) { + vec_t next_carry_s = a_s[i] << 15; + a_s[i] >>= 1; + a_s[i] |= vextq_u16(next_carry_s, kZero, 1); + a_s[i] |= carry_s; + carry_s = vextq_u16(kZero, next_carry_s, 1); + + vec_t next_carry_a = a_a[i] << 15; + a_a[i] >>= 1; + a_a[i] |= vextq_u16(next_carry_a, kZero, 1); + a_a[i] |= carry_a; + carry_a = vextq_u16(kZero, next_carry_a, 1); + } +} + +#endif // !OPENSSL_AARCH64 + +#endif // (ARM || AARCH64) && NEON + +// Polynomials in this scheme have N terms. +// #define N 701 + +// Underlying data types and arithmetic operations. +// ------------------------------------------------ + +// Binary polynomials. + +// poly2 represents a degree-N polynomial over GF(2). The words are in little- +// endian order, i.e. the coefficient of x^0 is the LSB of the first word. The +// final word is only partially used since N is not a multiple of the word size. + +// Defined in internal.h: +// struct poly2 { +// crypto_word_t v[WORDS_PER_POLY]; +// }; + +OPENSSL_UNUSED static void hexdump(const void *void_in, size_t len) { + const uint8_t *in = (const uint8_t *)void_in; + for (size_t i = 0; i < len; i++) { + printf("%02x", in[i]); + } + printf("\n"); +} + +static void poly2_zero(struct poly2 *p) { + OPENSSL_memset(&p->v[0], 0, sizeof(crypto_word_t) * WORDS_PER_POLY); +} + +// word_reverse returns |in| with the bits in reverse order. +static crypto_word_t word_reverse(crypto_word_t in) { +#if defined(OPENSSL_64_BIT) + static const crypto_word_t kMasks[6] = { + UINT64_C(0x5555555555555555), + UINT64_C(0x3333333333333333), + UINT64_C(0x0f0f0f0f0f0f0f0f), + UINT64_C(0x00ff00ff00ff00ff), + UINT64_C(0x0000ffff0000ffff), + UINT64_C(0x00000000ffffffff), + }; +#else + static const crypto_word_t kMasks[5] = { + 0x55555555, + 0x33333333, + 0x0f0f0f0f, + 0x00ff00ff, + 0x0000ffff, + }; +#endif + + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMasks); i++) { + in = ((in >> (1 << i)) & kMasks[i]) | ((in & kMasks[i]) << (1 << i)); + } + + return in; +} + +// lsb_to_all replicates the least-significant bit of |v| to all bits of the +// word. This is used in bit-slicing operations to make a vector from a fixed +// value. +static crypto_word_t lsb_to_all(crypto_word_t v) { return 0u - (v & 1); } + +// poly2_mod_phiN reduces |p| by Φ(N). +static void poly2_mod_phiN(struct poly2 *p) { + // m is the term at x^700, replicated to every bit. + const crypto_word_t m = + lsb_to_all(p->v[WORDS_PER_POLY - 1] >> (BITS_IN_LAST_WORD - 1)); + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + p->v[i] ^= m; + } + p->v[WORDS_PER_POLY - 1] &= (UINT64_C(1) << (BITS_IN_LAST_WORD - 1)) - 1; +} + +// poly2_reverse_700 reverses the order of the first 700 bits of |in| and writes +// the result to |out|. +static void poly2_reverse_700(struct poly2 *out, const struct poly2 *in) { + struct poly2 t; + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + t.v[i] = word_reverse(in->v[i]); + } + + static const size_t shift = BITS_PER_WORD - ((N-1) % BITS_PER_WORD); + for (size_t i = 0; i < WORDS_PER_POLY-1; i++) { + out->v[i] = t.v[WORDS_PER_POLY-1-i] >> shift; + out->v[i] |= t.v[WORDS_PER_POLY-2-i] << (BITS_PER_WORD - shift); + } + out->v[WORDS_PER_POLY-1] = t.v[0] >> shift; +} + +// poly2_cswap exchanges the values of |a| and |b| if |swap| is all ones. +static void poly2_cswap(struct poly2 *a, struct poly2 *b, crypto_word_t swap) { + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + const crypto_word_t sum = swap & (a->v[i] ^ b->v[i]); + a->v[i] ^= sum; + b->v[i] ^= sum; + } +} + +// poly2_fmadd sets |out| to |out| + |in| * m, where m is either +// |CONSTTIME_TRUE_W| or |CONSTTIME_FALSE_W|. +static void poly2_fmadd(struct poly2 *out, const struct poly2 *in, + crypto_word_t m) { + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + out->v[i] ^= in->v[i] & m; + } +} + +// poly2_lshift1 left-shifts |p| by one bit. +static void poly2_lshift1(struct poly2 *p) { + crypto_word_t carry = 0; + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + const crypto_word_t next_carry = p->v[i] >> (BITS_PER_WORD - 1); + p->v[i] <<= 1; + p->v[i] |= carry; + carry = next_carry; + } +} + +// poly2_rshift1 right-shifts |p| by one bit. +static void poly2_rshift1(struct poly2 *p) { + crypto_word_t carry = 0; + for (size_t i = WORDS_PER_POLY - 1; i < WORDS_PER_POLY; i--) { + const crypto_word_t next_carry = p->v[i] & 1; + p->v[i] >>= 1; + p->v[i] |= carry << (BITS_PER_WORD - 1); + carry = next_carry; + } +} + +// poly2_clear_top_bits clears the bits in the final word that are only for +// alignment. +static void poly2_clear_top_bits(struct poly2 *p) { + p->v[WORDS_PER_POLY - 1] &= (UINT64_C(1) << BITS_IN_LAST_WORD) - 1; +} + +// poly2_top_bits_are_clear returns one iff the extra bits in the final words of +// |p| are zero. +static int poly2_top_bits_are_clear(const struct poly2 *p) { + return (p->v[WORDS_PER_POLY - 1] & + ~((UINT64_C(1) << BITS_IN_LAST_WORD) - 1)) == 0; +} + +// Ternary polynomials. + +// poly3 represents a degree-N polynomial over GF(3). Each coefficient is +// bitsliced across the |s| and |a| arrays, like this: +// +// s | a | value +// ----------------- +// 0 | 0 | 0 +// 0 | 1 | 1 +// 1 | 1 | -1 (aka 2) +// 1 | 0 | +// +// ('s' is for sign, and 'a' is the absolute value.) +// +// Once bitsliced as such, the following circuits can be used to implement +// addition and multiplication mod 3: +// +// (s3, a3) = (s1, a1) × (s2, a2) +// a3 = a1 ∧ a2 +// s3 = (s1 ⊕ s2) ∧ a3 +// +// (s3, a3) = (s1, a1) + (s2, a2) +// t = s1 ⊕ a2 +// s3 = t ∧ (s2 ⊕ a1) +// a3 = (a1 ⊕ a2) ∨ (t ⊕ s2) +// +// (s3, a3) = (s1, a1) - (s2, a2) +// t = a1 ⊕ a2 +// s3 = (s1 ⊕ a2) ∧ (t ⊕ s2) +// a3 = t ∨ (s1 ⊕ s2) +// +// Negating a value just involves XORing s by a. +// +// struct poly3 { +// struct poly2 s, a; +// }; + +OPENSSL_UNUSED static void poly3_print(const struct poly3 *in) { + struct poly3 p; + OPENSSL_memcpy(&p, in, sizeof(p)); + p.s.v[WORDS_PER_POLY - 1] &= ((crypto_word_t)1 << BITS_IN_LAST_WORD) - 1; + p.a.v[WORDS_PER_POLY - 1] &= ((crypto_word_t)1 << BITS_IN_LAST_WORD) - 1; + + printf("{["); + for (unsigned i = 0; i < WORDS_PER_POLY; i++) { + if (i) { + printf(" "); + } + printf(BN_HEX_FMT2, p.s.v[i]); + } + printf("] ["); + for (unsigned i = 0; i < WORDS_PER_POLY; i++) { + if (i) { + printf(" "); + } + printf(BN_HEX_FMT2, p.a.v[i]); + } + printf("]}\n"); +} + +static void poly3_zero(struct poly3 *p) { + poly2_zero(&p->s); + poly2_zero(&p->a); +} + +// poly3_reverse_700 reverses the order of the first 700 terms of |in| and +// writes them to |out|. +static void poly3_reverse_700(struct poly3 *out, const struct poly3 *in) { + poly2_reverse_700(&out->a, &in->a); + poly2_reverse_700(&out->s, &in->s); +} + +// poly3_word_mul sets (|out_s|, |out_a|) to (|s1|, |a1|) × (|s2|, |a2|). +static void poly3_word_mul(crypto_word_t *out_s, crypto_word_t *out_a, + const crypto_word_t s1, const crypto_word_t a1, + const crypto_word_t s2, const crypto_word_t a2) { + *out_a = a1 & a2; + *out_s = (s1 ^ s2) & *out_a; +} + +// poly3_word_add sets (|out_s|, |out_a|) to (|s1|, |a1|) + (|s2|, |a2|). +static void poly3_word_add(crypto_word_t *out_s, crypto_word_t *out_a, + const crypto_word_t s1, const crypto_word_t a1, + const crypto_word_t s2, const crypto_word_t a2) { + const crypto_word_t t = s1 ^ a2; + *out_s = t & (s2 ^ a1); + *out_a = (a1 ^ a2) | (t ^ s2); +} + +// poly3_word_sub sets (|out_s|, |out_a|) to (|s1|, |a1|) - (|s2|, |a2|). +static void poly3_word_sub(crypto_word_t *out_s, crypto_word_t *out_a, + const crypto_word_t s1, const crypto_word_t a1, + const crypto_word_t s2, const crypto_word_t a2) { + const crypto_word_t t = a1 ^ a2; + *out_s = (s1 ^ a2) & (t ^ s2); + *out_a = t | (s1 ^ s2); +} + +// poly3_mul_const sets |p| to |p|×m, where m = (ms, ma). +static void poly3_mul_const(struct poly3 *p, crypto_word_t ms, + crypto_word_t ma) { + ms = lsb_to_all(ms); + ma = lsb_to_all(ma); + + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + poly3_word_mul(&p->s.v[i], &p->a.v[i], p->s.v[i], p->a.v[i], ms, ma); + } +} + +// poly3_fmadd sets |out| to |out| - |in|×m, where m is (ms, ma). +static void poly3_fmsub(struct poly3 *RESTRICT out, + const struct poly3 *RESTRICT in, crypto_word_t ms, + crypto_word_t ma) { + crypto_word_t product_s, product_a; + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + poly3_word_mul(&product_s, &product_a, in->s.v[i], in->a.v[i], ms, ma); + poly3_word_sub(&out->s.v[i], &out->a.v[i], out->s.v[i], out->a.v[i], + product_s, product_a); + } +} + +// final_bit_to_all replicates the bit in the final position of the last word to +// all the bits in the word. +static crypto_word_t final_bit_to_all(crypto_word_t v) { + return lsb_to_all(v >> (BITS_IN_LAST_WORD - 1)); +} + +// poly3_top_bits_are_clear returns one iff the extra bits in the final words of +// |p| are zero. +OPENSSL_UNUSED static int poly3_top_bits_are_clear(const struct poly3 *p) { + return poly2_top_bits_are_clear(&p->s) && poly2_top_bits_are_clear(&p->a); +} + +// poly3_mod_phiN reduces |p| by Φ(N). +static void poly3_mod_phiN(struct poly3 *p) { + // In order to reduce by Φ(N) we subtract by the value of the greatest + // coefficient. + const crypto_word_t factor_s = final_bit_to_all(p->s.v[WORDS_PER_POLY - 1]); + const crypto_word_t factor_a = final_bit_to_all(p->a.v[WORDS_PER_POLY - 1]); + + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + poly3_word_sub(&p->s.v[i], &p->a.v[i], p->s.v[i], p->a.v[i], factor_s, + factor_a); + } + + poly2_clear_top_bits(&p->s); + poly2_clear_top_bits(&p->a); +} + +static void poly3_cswap(struct poly3 *a, struct poly3 *b, crypto_word_t swap) { + poly2_cswap(&a->s, &b->s, swap); + poly2_cswap(&a->a, &b->a, swap); +} + +static void poly3_lshift1(struct poly3 *p) { + poly2_lshift1(&p->s); + poly2_lshift1(&p->a); +} + +static void poly3_rshift1(struct poly3 *p) { + poly2_rshift1(&p->s); + poly2_rshift1(&p->a); +} + +// poly3_span represents a pointer into a poly3. +struct poly3_span { + crypto_word_t *s; + crypto_word_t *a; +}; + +// poly3_span_add adds |n| words of values from |a| and |b| and writes the +// result to |out|. +static void poly3_span_add(const struct poly3_span *out, + const struct poly3_span *a, + const struct poly3_span *b, size_t n) { + for (size_t i = 0; i < n; i++) { + poly3_word_add(&out->s[i], &out->a[i], a->s[i], a->a[i], b->s[i], b->a[i]); + } +} + +// poly3_span_sub subtracts |n| words of |b| from |n| words of |a|. +static void poly3_span_sub(const struct poly3_span *a, + const struct poly3_span *b, size_t n) { + for (size_t i = 0; i < n; i++) { + poly3_word_sub(&a->s[i], &a->a[i], a->s[i], a->a[i], b->s[i], b->a[i]); + } +} + +// poly3_mul_aux is a recursive function that multiplies |n| words from |a| and +// |b| and writes 2×|n| words to |out|. Each call uses 2*ceil(n/2) elements of +// |scratch| and the function recurses, except if |n| == 1, when |scratch| isn't +// used and the recursion stops. For |n| in {11, 22}, the transitive total +// amount of |scratch| needed happens to be 2n+2. +static void poly3_mul_aux(const struct poly3_span *out, + const struct poly3_span *scratch, + const struct poly3_span *a, + const struct poly3_span *b, size_t n) { + if (n == 1) { + crypto_word_t r_s_low = 0, r_s_high = 0, r_a_low = 0, r_a_high = 0; + crypto_word_t b_s = b->s[0], b_a = b->a[0]; + const crypto_word_t a_s = a->s[0], a_a = a->a[0]; + + for (size_t i = 0; i < BITS_PER_WORD; i++) { + // Multiply (s, a) by the next value from (b_s, b_a). + crypto_word_t m_s, m_a; + poly3_word_mul(&m_s, &m_a, a_s, a_a, lsb_to_all(b_s), lsb_to_all(b_a)); + b_s >>= 1; + b_a >>= 1; + + if (i == 0) { + // Special case otherwise the code tries to shift by BITS_PER_WORD + // below, which is undefined. + r_s_low = m_s; + r_a_low = m_a; + continue; + } + + // Shift the multiplication result to the correct position. + const crypto_word_t m_s_low = m_s << i; + const crypto_word_t m_s_high = m_s >> (BITS_PER_WORD - i); + const crypto_word_t m_a_low = m_a << i; + const crypto_word_t m_a_high = m_a >> (BITS_PER_WORD - i); + + // Add into the result. + poly3_word_add(&r_s_low, &r_a_low, r_s_low, r_a_low, m_s_low, m_a_low); + poly3_word_add(&r_s_high, &r_a_high, r_s_high, r_a_high, m_s_high, + m_a_high); + } + + out->s[0] = r_s_low; + out->s[1] = r_s_high; + out->a[0] = r_a_low; + out->a[1] = r_a_high; + return; + } + + // Karatsuba multiplication. + // https://en.wikipedia.org/wiki/Karatsuba_algorithm + + // When |n| is odd, the two "halves" will have different lengths. The first + // is always the smaller. + const size_t low_len = n / 2; + const size_t high_len = n - low_len; + const struct poly3_span a_high = {&a->s[low_len], &a->a[low_len]}; + const struct poly3_span b_high = {&b->s[low_len], &b->a[low_len]}; + + // Store a_1 + a_0 in the first half of |out| and b_1 + b_0 in the second + // half. + const struct poly3_span a_cross_sum = *out; + const struct poly3_span b_cross_sum = {&out->s[high_len], &out->a[high_len]}; + poly3_span_add(&a_cross_sum, a, &a_high, low_len); + poly3_span_add(&b_cross_sum, b, &b_high, low_len); + if (high_len != low_len) { + a_cross_sum.s[low_len] = a_high.s[low_len]; + a_cross_sum.a[low_len] = a_high.a[low_len]; + b_cross_sum.s[low_len] = b_high.s[low_len]; + b_cross_sum.a[low_len] = b_high.a[low_len]; + } + + const struct poly3_span child_scratch = {&scratch->s[2 * high_len], + &scratch->a[2 * high_len]}; + const struct poly3_span out_mid = {&out->s[low_len], &out->a[low_len]}; + const struct poly3_span out_high = {&out->s[2 * low_len], + &out->a[2 * low_len]}; + + // Calculate (a_1 + a_0) × (b_1 + b_0) and write to scratch buffer. + poly3_mul_aux(scratch, &child_scratch, &a_cross_sum, &b_cross_sum, high_len); + // Calculate a_1 × b_1. + poly3_mul_aux(&out_high, &child_scratch, &a_high, &b_high, high_len); + // Calculate a_0 × b_0. + poly3_mul_aux(out, &child_scratch, a, b, low_len); + + // Subtract those last two products from the first. + poly3_span_sub(scratch, out, low_len * 2); + poly3_span_sub(scratch, &out_high, high_len * 2); + + // Add the middle product into the output. + poly3_span_add(&out_mid, &out_mid, scratch, high_len * 2); +} + +// HRSS_poly3_mul sets |*out| to |x|×|y| mod Φ(N). +void HRSS_poly3_mul(struct poly3 *out, const struct poly3 *x, + const struct poly3 *y) { + crypto_word_t prod_s[WORDS_PER_POLY * 2]; + crypto_word_t prod_a[WORDS_PER_POLY * 2]; + crypto_word_t scratch_s[WORDS_PER_POLY * 2 + 2]; + crypto_word_t scratch_a[WORDS_PER_POLY * 2 + 2]; + const struct poly3_span prod_span = {prod_s, prod_a}; + const struct poly3_span scratch_span = {scratch_s, scratch_a}; + const struct poly3_span x_span = {(crypto_word_t *)x->s.v, + (crypto_word_t *)x->a.v}; + const struct poly3_span y_span = {(crypto_word_t *)y->s.v, + (crypto_word_t *)y->a.v}; + + poly3_mul_aux(&prod_span, &scratch_span, &x_span, &y_span, WORDS_PER_POLY); + + // |prod| needs to be reduced mod (𝑥^n - 1), which just involves adding the + // upper-half to the lower-half. However, N is 701, which isn't a multiple of + // BITS_PER_WORD, so the upper-half vectors all have to be shifted before + // being added to the lower-half. + for (size_t i = 0; i < WORDS_PER_POLY; i++) { + crypto_word_t v_s = prod_s[WORDS_PER_POLY + i - 1] >> BITS_IN_LAST_WORD; + v_s |= prod_s[WORDS_PER_POLY + i] << (BITS_PER_WORD - BITS_IN_LAST_WORD); + crypto_word_t v_a = prod_a[WORDS_PER_POLY + i - 1] >> BITS_IN_LAST_WORD; + v_a |= prod_a[WORDS_PER_POLY + i] << (BITS_PER_WORD - BITS_IN_LAST_WORD); + + poly3_word_add(&out->s.v[i], &out->a.v[i], prod_s[i], prod_a[i], v_s, v_a); + } + + poly3_mod_phiN(out); +} + +#if defined(HRSS_HAVE_VECTOR_UNIT) && !defined(OPENSSL_AARCH64) + +// poly3_vec_cswap swaps (|a_s|, |a_a|) and (|b_s|, |b_a|) if |swap| is +// |0xff..ff|. Otherwise, |swap| must be zero. +static inline void poly3_vec_cswap(vec_t a_s[6], vec_t a_a[6], vec_t b_s[6], + vec_t b_a[6], const vec_t swap) { + for (int i = 0; i < 6; i++) { + const vec_t sum_s = swap & (a_s[i] ^ b_s[i]); + a_s[i] ^= sum_s; + b_s[i] ^= sum_s; + + const vec_t sum_a = swap & (a_a[i] ^ b_a[i]); + a_a[i] ^= sum_a; + b_a[i] ^= sum_a; + } +} + +// poly3_vec_fmsub subtracts (|ms|, |ma|) × (|b_s|, |b_a|) from (|a_s|, |a_a|). +static inline void poly3_vec_fmsub(vec_t a_s[6], vec_t a_a[6], vec_t b_s[6], + vec_t b_a[6], const vec_t ms, + const vec_t ma) { + for (int i = 0; i < 6; i++) { + // See the bitslice formula, above. + const vec_t s = b_s[i]; + const vec_t a = b_a[i]; + const vec_t product_a = a & ma; + const vec_t product_s = (s ^ ms) & product_a; + + const vec_t out_s = a_s[i]; + const vec_t out_a = a_a[i]; + const vec_t t = out_a ^ product_a; + a_s[i] = (out_s ^ product_a) & (t ^ product_s); + a_a[i] = t | (out_s ^ product_s); + } +} + +// poly3_invert_vec sets |*out| to |in|^-1, i.e. such that |out|×|in| == 1 mod +// Φ(N). +static void poly3_invert_vec(struct poly3 *out, const struct poly3 *in) { + // This algorithm is taken from section 7.1 of [SAFEGCD]. + const vec_t kZero = {0}; + const vec_t kOne = {1}; + static const uint8_t kBottomSixtyOne[sizeof(vec_t)] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f}; + + vec_t v_s[6], v_a[6], r_s[6], r_a[6], f_s[6], f_a[6], g_s[6], g_a[6]; + // v = 0 + memset(&v_s, 0, sizeof(v_s)); + memset(&v_a, 0, sizeof(v_a)); + // r = 1 + memset(&r_s, 0, sizeof(r_s)); + memset(&r_a, 0, sizeof(r_a)); + r_a[0] = kOne; + // f = all ones. + memset(f_s, 0, sizeof(f_s)); + memset(f_a, 0xff, 5 * sizeof(vec_t)); + memcpy(&f_a[5], kBottomSixtyOne, sizeof(kBottomSixtyOne)); + // g is the reversal of |in|. + struct poly3 in_reversed; + poly3_reverse_700(&in_reversed, in); + g_s[5] = kZero; + memcpy(&g_s, &in_reversed.s.v, WORDS_PER_POLY * sizeof(crypto_word_t)); + g_a[5] = kZero; + memcpy(&g_a, &in_reversed.a.v, WORDS_PER_POLY * sizeof(crypto_word_t)); + + int delta = 1; + + for (size_t i = 0; i < (2*(N-1)) - 1; i++) { + poly3_vec_lshift1(v_s, v_a); + + const crypto_word_t delta_sign_bit = (delta >> (sizeof(delta) * 8 - 1)) & 1; + const crypto_word_t delta_is_non_negative = delta_sign_bit - 1; + const crypto_word_t delta_is_non_zero = ~constant_time_is_zero_w(delta); + const vec_t g_has_constant_term = vec_broadcast_bit(g_a[0]); + const vec_t mask_w = + {delta_is_non_negative & delta_is_non_zero}; + const vec_t mask = vec_broadcast_bit(mask_w) & g_has_constant_term; + + const vec_t c_a = vec_broadcast_bit(f_a[0] & g_a[0]); + const vec_t c_s = vec_broadcast_bit((f_s[0] ^ g_s[0]) & c_a); + + delta = constant_time_select_int(lsb_to_all(mask[0]), -delta, delta); + delta++; + + poly3_vec_cswap(f_s, f_a, g_s, g_a, mask); + poly3_vec_fmsub(g_s, g_a, f_s, f_a, c_s, c_a); + poly3_vec_rshift1(g_s, g_a); + + poly3_vec_cswap(v_s, v_a, r_s, r_a, mask); + poly3_vec_fmsub(r_s, r_a, v_s, v_a, c_s, c_a); + } + + assert(delta == 0); + memcpy(out->s.v, v_s, WORDS_PER_POLY * sizeof(crypto_word_t)); + memcpy(out->a.v, v_a, WORDS_PER_POLY * sizeof(crypto_word_t)); + poly3_mul_const(out, vec_get_word(f_s[0], 0), vec_get_word(f_a[0], 0)); + poly3_reverse_700(out, out); +} + +#endif // HRSS_HAVE_VECTOR_UNIT + +// HRSS_poly3_invert sets |*out| to |in|^-1, i.e. such that |out|×|in| == 1 mod +// Φ(N). +void HRSS_poly3_invert(struct poly3 *out, const struct poly3 *in) { + // The vector version of this function seems slightly slower on AArch64, but + // is useful on ARMv7 and x86-64. +#if defined(HRSS_HAVE_VECTOR_UNIT) && !defined(OPENSSL_AARCH64) + if (vec_capable()) { + poly3_invert_vec(out, in); + return; + } +#endif + + // This algorithm is taken from section 7.1 of [SAFEGCD]. + struct poly3 v, r, f, g; + // v = 0 + poly3_zero(&v); + // r = 1 + poly3_zero(&r); + r.a.v[0] = 1; + // f = all ones. + OPENSSL_memset(&f.s, 0, sizeof(struct poly2)); + OPENSSL_memset(&f.a, 0xff, sizeof(struct poly2)); + f.a.v[WORDS_PER_POLY - 1] >>= BITS_PER_WORD - BITS_IN_LAST_WORD; + // g is the reversal of |in|. + poly3_reverse_700(&g, in); + int delta = 1; + + for (size_t i = 0; i < (2*(N-1)) - 1; i++) { + poly3_lshift1(&v); + + const crypto_word_t delta_sign_bit = (delta >> (sizeof(delta) * 8 - 1)) & 1; + const crypto_word_t delta_is_non_negative = delta_sign_bit - 1; + const crypto_word_t delta_is_non_zero = ~constant_time_is_zero_w(delta); + const crypto_word_t g_has_constant_term = lsb_to_all(g.a.v[0]); + const crypto_word_t mask = + g_has_constant_term & delta_is_non_negative & delta_is_non_zero; + + crypto_word_t c_s, c_a; + poly3_word_mul(&c_s, &c_a, f.s.v[0], f.a.v[0], g.s.v[0], g.a.v[0]); + c_s = lsb_to_all(c_s); + c_a = lsb_to_all(c_a); + + delta = constant_time_select_int(mask, -delta, delta); + delta++; + + poly3_cswap(&f, &g, mask); + poly3_fmsub(&g, &f, c_s, c_a); + poly3_rshift1(&g); + + poly3_cswap(&v, &r, mask); + poly3_fmsub(&r, &v, c_s, c_a); + } + + assert(delta == 0); + poly3_mul_const(&v, f.s.v[0], f.a.v[0]); + poly3_reverse_700(out, &v); +} + +// Polynomials in Q. + +// Coefficients are reduced mod Q. (Q is clearly not prime, therefore the +// coefficients do not form a field.) +#define Q 8192 + +// VECS_PER_POLY is the number of 128-bit vectors needed to represent a +// polynomial. +#define COEFFICIENTS_PER_VEC (sizeof(vec_t) / sizeof(uint16_t)) +#define VECS_PER_POLY ((N + COEFFICIENTS_PER_VEC - 1) / COEFFICIENTS_PER_VEC) + +// poly represents a polynomial with coefficients mod Q. Note that, while Q is a +// power of two, this does not operate in GF(Q). That would be a binary field +// but this is simply mod Q. Thus the coefficients are not a field. +// +// Coefficients are ordered little-endian, thus the coefficient of x^0 is the +// first element of the array. +struct poly { +#if defined(HRSS_HAVE_VECTOR_UNIT) + union { + // N + 3 = 704, which is a multiple of 64 and thus aligns things, esp for + // the vector code. + uint16_t v[N + 3]; + vec_t vectors[VECS_PER_POLY]; + }; +#else + // Even if !HRSS_HAVE_VECTOR_UNIT, external assembly may be called that + // requires alignment. + alignas(16) uint16_t v[N + 3]; +#endif +}; + +// poly_normalize zeros out the excess elements of |x| which are included only +// for alignment. +static void poly_normalize(struct poly *x) { + OPENSSL_memset(&x->v[N], 0, 3 * sizeof(uint16_t)); +} + +// poly_assert_normalized asserts that the excess elements of |x| are zeroed out +// for the cases that case. (E.g. |poly_mul_vec|.) +static void poly_assert_normalized(const struct poly *x) { + assert(x->v[N] == 0); + assert(x->v[N + 1] == 0); + assert(x->v[N + 2] == 0); +} + +OPENSSL_UNUSED static void poly_print(const struct poly *p) { + printf("["); + for (unsigned i = 0; i < N; i++) { + if (i) { + printf(" "); + } + printf("%d", p->v[i]); + } + printf("]\n"); +} + +// POLY_MUL_SCRATCH contains space for the working variables needed by +// |poly_mul|. The contents afterwards may be discarded, but the object may also +// be reused with future |poly_mul| calls to save heap allocations. +// +// This object must have 32-byte alignment. +struct POLY_MUL_SCRATCH { + union { + // This is used by |poly_mul_novec|. + struct { + uint16_t prod[2 * N]; + uint16_t scratch[1318]; + } novec; + +#if defined(HRSS_HAVE_VECTOR_UNIT) + // This is used by |poly_mul_vec|. + struct { + vec_t prod[VECS_PER_POLY * 2]; + vec_t scratch[172]; + } vec; +#endif + +#if defined(POLY_RQ_MUL_ASM) + // This is the space used by |poly_Rq_mul|. + uint8_t rq[POLY_MUL_RQ_SCRATCH_SPACE]; +#endif + } u; +}; + +#if defined(HRSS_HAVE_VECTOR_UNIT) + +// poly_mul_vec_aux is a recursive function that multiplies |n| words from |a| +// and |b| and writes 2×|n| words to |out|. Each call uses 2*ceil(n/2) elements +// of |scratch| and the function recurses, except if |n| < 3, when |scratch| +// isn't used and the recursion stops. If |n| == |VECS_PER_POLY| then |scratch| +// needs 172 elements. +static void poly_mul_vec_aux(vec_t *restrict out, vec_t *restrict scratch, + const vec_t *restrict a, const vec_t *restrict b, + const size_t n) { + // In [HRSS], the technique they used for polynomial multiplication is + // described: they start with Toom-4 at the top level and then two layers of + // Karatsuba. Karatsuba is a specific instance of the general Toom–Cook + // decomposition, which splits an input n-ways and produces 2n-1 + // multiplications of those parts. So, starting with 704 coefficients (rounded + // up from 701 to have more factors of two), Toom-4 gives seven + // multiplications of degree-174 polynomials. Each round of Karatsuba (which + // is Toom-2) increases the number of multiplications by a factor of three + // while halving the size of the values being multiplied. So two rounds gives + // 63 multiplications of degree-44 polynomials. Then they (I think) form + // vectors by gathering all 63 coefficients of each power together, for each + // input, and doing more rounds of Karatsuba on the vectors until they bottom- + // out somewhere with schoolbook multiplication. + // + // I tried something like that for NEON. NEON vectors are 128 bits so hold + // eight coefficients. I wrote a function that did Karatsuba on eight + // multiplications at the same time, using such vectors, and a Go script that + // decomposed from degree-704, with Karatsuba in non-transposed form, until it + // reached multiplications of degree-44. It batched up those 81 + // multiplications into lots of eight with a single one left over (which was + // handled directly). + // + // It worked, but it was significantly slower than the dumb algorithm used + // below. Potentially that was because I misunderstood how [HRSS] did it, or + // because Clang is bad at generating good code from NEON intrinsics on ARMv7. + // (Which is true: the code generated by Clang for the below is pretty crap.) + // + // This algorithm is much simpler. It just does Karatsuba decomposition all + // the way down and never transposes. When it gets down to degree-16 or + // degree-24 values, they are multiplied using schoolbook multiplication and + // vector intrinsics. The vector operations form each of the eight phase- + // shifts of one of the inputs, point-wise multiply, and then add into the + // result at the correct place. This means that 33% (degree-16) or 25% + // (degree-24) of the multiplies and adds are wasted, but it does ok. + if (n == 2) { + vec_t result[4]; + vec_t vec_a[3]; + static const vec_t kZero = {0}; + vec_a[0] = a[0]; + vec_a[1] = a[1]; + vec_a[2] = kZero; + + result[0] = vec_mul(vec_a[0], vec_get_word(b[0], 0)); + result[1] = vec_mul(vec_a[1], vec_get_word(b[0], 0)); + + result[1] = vec_fma(result[1], vec_a[0], vec_get_word(b[1], 0)); + result[2] = vec_mul(vec_a[1], vec_get_word(b[1], 0)); + result[3] = kZero; + + vec3_rshift_word(vec_a); + +#define BLOCK(x, y) \ + do { \ + result[x + 0] = \ + vec_fma(result[x + 0], vec_a[0], vec_get_word(b[y / 8], y % 8)); \ + result[x + 1] = \ + vec_fma(result[x + 1], vec_a[1], vec_get_word(b[y / 8], y % 8)); \ + result[x + 2] = \ + vec_fma(result[x + 2], vec_a[2], vec_get_word(b[y / 8], y % 8)); \ + } while (0) + + BLOCK(0, 1); + BLOCK(1, 9); + + vec3_rshift_word(vec_a); + + BLOCK(0, 2); + BLOCK(1, 10); + + vec3_rshift_word(vec_a); + + BLOCK(0, 3); + BLOCK(1, 11); + + vec3_rshift_word(vec_a); + + BLOCK(0, 4); + BLOCK(1, 12); + + vec3_rshift_word(vec_a); + + BLOCK(0, 5); + BLOCK(1, 13); + + vec3_rshift_word(vec_a); + + BLOCK(0, 6); + BLOCK(1, 14); + + vec3_rshift_word(vec_a); + + BLOCK(0, 7); + BLOCK(1, 15); + +#undef BLOCK + + memcpy(out, result, sizeof(result)); + return; + } + + if (n == 3) { + vec_t result[6]; + vec_t vec_a[4]; + static const vec_t kZero = {0}; + vec_a[0] = a[0]; + vec_a[1] = a[1]; + vec_a[2] = a[2]; + vec_a[3] = kZero; + + result[0] = vec_mul(a[0], vec_get_word(b[0], 0)); + result[1] = vec_mul(a[1], vec_get_word(b[0], 0)); + result[2] = vec_mul(a[2], vec_get_word(b[0], 0)); + +#define BLOCK_PRE(x, y) \ + do { \ + result[x + 0] = \ + vec_fma(result[x + 0], vec_a[0], vec_get_word(b[y / 8], y % 8)); \ + result[x + 1] = \ + vec_fma(result[x + 1], vec_a[1], vec_get_word(b[y / 8], y % 8)); \ + result[x + 2] = vec_mul(vec_a[2], vec_get_word(b[y / 8], y % 8)); \ + } while (0) + + BLOCK_PRE(1, 8); + BLOCK_PRE(2, 16); + + result[5] = kZero; + + vec4_rshift_word(vec_a); + +#define BLOCK(x, y) \ + do { \ + result[x + 0] = \ + vec_fma(result[x + 0], vec_a[0], vec_get_word(b[y / 8], y % 8)); \ + result[x + 1] = \ + vec_fma(result[x + 1], vec_a[1], vec_get_word(b[y / 8], y % 8)); \ + result[x + 2] = \ + vec_fma(result[x + 2], vec_a[2], vec_get_word(b[y / 8], y % 8)); \ + result[x + 3] = \ + vec_fma(result[x + 3], vec_a[3], vec_get_word(b[y / 8], y % 8)); \ + } while (0) + + BLOCK(0, 1); + BLOCK(1, 9); + BLOCK(2, 17); + + vec4_rshift_word(vec_a); + + BLOCK(0, 2); + BLOCK(1, 10); + BLOCK(2, 18); + + vec4_rshift_word(vec_a); + + BLOCK(0, 3); + BLOCK(1, 11); + BLOCK(2, 19); + + vec4_rshift_word(vec_a); + + BLOCK(0, 4); + BLOCK(1, 12); + BLOCK(2, 20); + + vec4_rshift_word(vec_a); + + BLOCK(0, 5); + BLOCK(1, 13); + BLOCK(2, 21); + + vec4_rshift_word(vec_a); + + BLOCK(0, 6); + BLOCK(1, 14); + BLOCK(2, 22); + + vec4_rshift_word(vec_a); + + BLOCK(0, 7); + BLOCK(1, 15); + BLOCK(2, 23); + +#undef BLOCK +#undef BLOCK_PRE + + memcpy(out, result, sizeof(result)); + + return; + } + + // Karatsuba multiplication. + // https://en.wikipedia.org/wiki/Karatsuba_algorithm + + // When |n| is odd, the two "halves" will have different lengths. The first is + // always the smaller. + const size_t low_len = n / 2; + const size_t high_len = n - low_len; + const vec_t *a_high = &a[low_len]; + const vec_t *b_high = &b[low_len]; + + // Store a_1 + a_0 in the first half of |out| and b_1 + b_0 in the second + // half. + for (size_t i = 0; i < low_len; i++) { + out[i] = vec_add(a_high[i], a[i]); + out[high_len + i] = vec_add(b_high[i], b[i]); + } + if (high_len != low_len) { + out[low_len] = a_high[low_len]; + out[high_len + low_len] = b_high[low_len]; + } + + vec_t *const child_scratch = &scratch[2 * high_len]; + // Calculate (a_1 + a_0) × (b_1 + b_0) and write to scratch buffer. + poly_mul_vec_aux(scratch, child_scratch, out, &out[high_len], high_len); + // Calculate a_1 × b_1. + poly_mul_vec_aux(&out[low_len * 2], child_scratch, a_high, b_high, high_len); + // Calculate a_0 × b_0. + poly_mul_vec_aux(out, child_scratch, a, b, low_len); + + // Subtract those last two products from the first. + for (size_t i = 0; i < low_len * 2; i++) { + scratch[i] = vec_sub(scratch[i], vec_add(out[i], out[low_len * 2 + i])); + } + if (low_len != high_len) { + scratch[low_len * 2] = vec_sub(scratch[low_len * 2], out[low_len * 4]); + scratch[low_len * 2 + 1] = + vec_sub(scratch[low_len * 2 + 1], out[low_len * 4 + 1]); + } + + // Add the middle product into the output. + for (size_t i = 0; i < high_len * 2; i++) { + out[low_len + i] = vec_add(out[low_len + i], scratch[i]); + } +} + +// poly_mul_vec sets |*out| to |x|×|y| mod (𝑥^n - 1). +static void poly_mul_vec(struct POLY_MUL_SCRATCH *scratch, struct poly *out, + const struct poly *x, const struct poly *y) { + OPENSSL_STATIC_ASSERT(sizeof(out->v) == sizeof(vec_t) * VECS_PER_POLY, + "struct poly is the wrong size"); + OPENSSL_STATIC_ASSERT(alignof(struct poly) == alignof(vec_t), + "struct poly has incorrect alignment"); + poly_assert_normalized(x); + poly_assert_normalized(y); + + vec_t *const prod = scratch->u.vec.prod; + vec_t *const aux_scratch = scratch->u.vec.scratch; + poly_mul_vec_aux(prod, aux_scratch, x->vectors, y->vectors, VECS_PER_POLY); + + // |prod| needs to be reduced mod (𝑥^n - 1), which just involves adding the + // upper-half to the lower-half. However, N is 701, which isn't a multiple of + // the vector size, so the upper-half vectors all have to be shifted before + // being added to the lower-half. + vec_t *out_vecs = (vec_t *)out->v; + + for (size_t i = 0; i < VECS_PER_POLY; i++) { + const vec_t prev = prod[VECS_PER_POLY - 1 + i]; + const vec_t this = prod[VECS_PER_POLY + i]; + out_vecs[i] = vec_add(prod[i], vec_merge_3_5(prev, this)); + } + + OPENSSL_memset(&out->v[N], 0, 3 * sizeof(uint16_t)); +} + +#endif // HRSS_HAVE_VECTOR_UNIT + +// poly_mul_novec_aux writes the product of |a| and |b| to |out|, using +// |scratch| as scratch space. It'll use Karatsuba if the inputs are large +// enough to warrant it. Each call uses 2*ceil(n/2) elements of |scratch| and +// the function recurses, except if |n| < 64, when |scratch| isn't used and the +// recursion stops. If |n| == |N| then |scratch| needs 1318 elements. +static void poly_mul_novec_aux(uint16_t *out, uint16_t *scratch, + const uint16_t *a, const uint16_t *b, size_t n) { + static const size_t kSchoolbookLimit = 64; + if (n < kSchoolbookLimit) { + OPENSSL_memset(out, 0, sizeof(uint16_t) * n * 2); + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) { + out[i + j] += (unsigned) a[i] * b[j]; + } + } + + return; + } + + // Karatsuba multiplication. + // https://en.wikipedia.org/wiki/Karatsuba_algorithm + + // When |n| is odd, the two "halves" will have different lengths. The + // first is always the smaller. + const size_t low_len = n / 2; + const size_t high_len = n - low_len; + const uint16_t *const a_high = &a[low_len]; + const uint16_t *const b_high = &b[low_len]; + + for (size_t i = 0; i < low_len; i++) { + out[i] = a_high[i] + a[i]; + out[high_len + i] = b_high[i] + b[i]; + } + if (high_len != low_len) { + out[low_len] = a_high[low_len]; + out[high_len + low_len] = b_high[low_len]; + } + + uint16_t *const child_scratch = &scratch[2 * high_len]; + poly_mul_novec_aux(scratch, child_scratch, out, &out[high_len], high_len); + poly_mul_novec_aux(&out[low_len * 2], child_scratch, a_high, b_high, + high_len); + poly_mul_novec_aux(out, child_scratch, a, b, low_len); + + for (size_t i = 0; i < low_len * 2; i++) { + scratch[i] -= out[i] + out[low_len * 2 + i]; + } + if (low_len != high_len) { + scratch[low_len * 2] -= out[low_len * 4]; + assert(out[low_len * 4 + 1] == 0); + } + + for (size_t i = 0; i < high_len * 2; i++) { + out[low_len + i] += scratch[i]; + } +} + +// poly_mul_novec sets |*out| to |x|×|y| mod (𝑥^n - 1). +static void poly_mul_novec(struct POLY_MUL_SCRATCH *scratch, struct poly *out, + const struct poly *x, const struct poly *y) { + uint16_t *const prod = scratch->u.novec.prod; + uint16_t *const aux_scratch = scratch->u.novec.scratch; + poly_mul_novec_aux(prod, aux_scratch, x->v, y->v, N); + + for (size_t i = 0; i < N; i++) { + out->v[i] = prod[i] + prod[i + N]; + } + OPENSSL_memset(&out->v[N], 0, 3 * sizeof(uint16_t)); +} + +static void poly_mul(struct POLY_MUL_SCRATCH *scratch, struct poly *r, + const struct poly *a, const struct poly *b) { +#if defined(POLY_RQ_MUL_ASM) + if (CRYPTO_is_AVX2_capable()) { + poly_Rq_mul(r->v, a->v, b->v, scratch->u.rq); + poly_normalize(r); + } else +#endif + +#if defined(HRSS_HAVE_VECTOR_UNIT) + if (vec_capable()) { + poly_mul_vec(scratch, r, a, b); + } else +#endif + + // Fallback, non-vector case. + { + poly_mul_novec(scratch, r, a, b); + } + + poly_assert_normalized(r); +} + +// poly_mul_x_minus_1 sets |p| to |p|×(𝑥 - 1) mod (𝑥^n - 1). +static void poly_mul_x_minus_1(struct poly *p) { + // Multiplying by (𝑥 - 1) means negating each coefficient and adding in + // the value of the previous one. + const uint16_t orig_final_coefficient = p->v[N - 1]; + + for (size_t i = N - 1; i > 0; i--) { + p->v[i] = p->v[i - 1] - p->v[i]; + } + p->v[0] = orig_final_coefficient - p->v[0]; +} + +// poly_mod_phiN sets |p| to |p| mod Φ(N). +static void poly_mod_phiN(struct poly *p) { + const uint16_t coeff700 = p->v[N - 1]; + + for (unsigned i = 0; i < N; i++) { + p->v[i] -= coeff700; + } +} + +// poly_clamp reduces each coefficient mod Q. +static void poly_clamp(struct poly *p) { + for (unsigned i = 0; i < N; i++) { + p->v[i] &= Q - 1; + } +} + + +// Conversion functions +// -------------------- + +// poly2_from_poly sets |*out| to |in| mod 2. +static void poly2_from_poly(struct poly2 *out, const struct poly *in) { + crypto_word_t *words = out->v; + unsigned shift = 0; + crypto_word_t word = 0; + + for (unsigned i = 0; i < N; i++) { + word >>= 1; + word |= (crypto_word_t)(in->v[i] & 1) << (BITS_PER_WORD - 1); + shift++; + + if (shift == BITS_PER_WORD) { + *words = word; + words++; + word = 0; + shift = 0; + } + } + + word >>= BITS_PER_WORD - shift; + *words = word; +} + +// mod3 treats |a| as a signed number and returns |a| mod 3. +static uint16_t mod3(int16_t a) { + const int16_t q = ((int32_t)a * 21845) >> 16; + int16_t ret = a - 3 * q; + // At this point, |ret| is in {0, 1, 2, 3} and that needs to be mapped to {0, + // 1, 2, 0}. + return ret & ((ret & (ret >> 1)) - 1); +} + +// poly3_from_poly sets |*out| to |in|. +static void poly3_from_poly(struct poly3 *out, const struct poly *in) { + crypto_word_t *words_s = out->s.v; + crypto_word_t *words_a = out->a.v; + crypto_word_t s = 0; + crypto_word_t a = 0; + unsigned shift = 0; + + for (unsigned i = 0; i < N; i++) { + // This duplicates the 13th bit upwards to the top of the uint16, + // essentially treating it as a sign bit and converting into a signed int16. + // The signed value is reduced mod 3, yielding {0, 1, 2}. + const uint16_t v = mod3((int16_t)(in->v[i] << 3) >> 3); + s >>= 1; + const crypto_word_t s_bit = (crypto_word_t)(v & 2) << (BITS_PER_WORD - 2); + s |= s_bit; + a >>= 1; + a |= s_bit | (crypto_word_t)(v & 1) << (BITS_PER_WORD - 1); + shift++; + + if (shift == BITS_PER_WORD) { + *words_s = s; + words_s++; + *words_a = a; + words_a++; + s = a = 0; + shift = 0; + } + } + + s >>= BITS_PER_WORD - shift; + a >>= BITS_PER_WORD - shift; + *words_s = s; + *words_a = a; +} + +// poly3_from_poly_checked sets |*out| to |in|, which has coefficients in {0, 1, +// Q-1}. It returns a mask indicating whether all coefficients were found to be +// in that set. +static crypto_word_t poly3_from_poly_checked(struct poly3 *out, + const struct poly *in) { + crypto_word_t *words_s = out->s.v; + crypto_word_t *words_a = out->a.v; + crypto_word_t s = 0; + crypto_word_t a = 0; + unsigned shift = 0; + crypto_word_t ok = CONSTTIME_TRUE_W; + + for (unsigned i = 0; i < N; i++) { + const uint16_t v = in->v[i]; + // Maps {0, 1, Q-1} to {0, 1, 2}. + uint16_t mod3 = v & 3; + mod3 ^= mod3 >> 1; + const uint16_t expected = (uint16_t)((~((mod3 >> 1) - 1)) | mod3) % Q; + ok &= constant_time_eq_w(v, expected); + + s >>= 1; + const crypto_word_t s_bit = (crypto_word_t)(mod3 & 2) + << (BITS_PER_WORD - 2); + s |= s_bit; + a >>= 1; + a |= s_bit | (crypto_word_t)(mod3 & 1) << (BITS_PER_WORD - 1); + shift++; + + if (shift == BITS_PER_WORD) { + *words_s = s; + words_s++; + *words_a = a; + words_a++; + s = a = 0; + shift = 0; + } + } + + s >>= BITS_PER_WORD - shift; + a >>= BITS_PER_WORD - shift; + *words_s = s; + *words_a = a; + + return ok; +} + +static void poly_from_poly2(struct poly *out, const struct poly2 *in) { + const crypto_word_t *words = in->v; + unsigned shift = 0; + crypto_word_t word = *words; + + for (unsigned i = 0; i < N; i++) { + out->v[i] = word & 1; + word >>= 1; + shift++; + + if (shift == BITS_PER_WORD) { + words++; + word = *words; + shift = 0; + } + } + + poly_normalize(out); +} + +static void poly_from_poly3(struct poly *out, const struct poly3 *in) { + const crypto_word_t *words_s = in->s.v; + const crypto_word_t *words_a = in->a.v; + crypto_word_t word_s = ~(*words_s); + crypto_word_t word_a = *words_a; + unsigned shift = 0; + + for (unsigned i = 0; i < N; i++) { + out->v[i] = (uint16_t)(word_s & 1) - 1; + out->v[i] |= word_a & 1; + word_s >>= 1; + word_a >>= 1; + shift++; + + if (shift == BITS_PER_WORD) { + words_s++; + words_a++; + word_s = ~(*words_s); + word_a = *words_a; + shift = 0; + } + } + + poly_normalize(out); +} + +// Polynomial inversion +// -------------------- + +// poly_invert_mod2 sets |*out| to |in^-1| (i.e. such that |*out|×|in| = 1 mod +// Φ(N)), all mod 2. This isn't useful in itself, but is part of doing inversion +// mod Q. +static void poly_invert_mod2(struct poly *out, const struct poly *in) { + // This algorithm is taken from section 7.1 of [SAFEGCD]. + struct poly2 v, r, f, g; + + // v = 0 + poly2_zero(&v); + // r = 1 + poly2_zero(&r); + r.v[0] = 1; + // f = all ones. + OPENSSL_memset(&f, 0xff, sizeof(struct poly2)); + f.v[WORDS_PER_POLY - 1] >>= BITS_PER_WORD - BITS_IN_LAST_WORD; + // g is the reversal of |in|. + poly2_from_poly(&g, in); + poly2_mod_phiN(&g); + poly2_reverse_700(&g, &g); + int delta = 1; + + for (size_t i = 0; i < (2*(N-1)) - 1; i++) { + poly2_lshift1(&v); + + const crypto_word_t delta_sign_bit = (delta >> (sizeof(delta) * 8 - 1)) & 1; + const crypto_word_t delta_is_non_negative = delta_sign_bit - 1; + const crypto_word_t delta_is_non_zero = ~constant_time_is_zero_w(delta); + const crypto_word_t g_has_constant_term = lsb_to_all(g.v[0]); + const crypto_word_t mask = + g_has_constant_term & delta_is_non_negative & delta_is_non_zero; + + const crypto_word_t c = lsb_to_all(f.v[0] & g.v[0]); + + delta = constant_time_select_int(mask, -delta, delta); + delta++; + + poly2_cswap(&f, &g, mask); + poly2_fmadd(&g, &f, c); + poly2_rshift1(&g); + + poly2_cswap(&v, &r, mask); + poly2_fmadd(&r, &v, c); + } + + assert(delta == 0); + assert(f.v[0] & 1); + poly2_reverse_700(&v, &v); + poly_from_poly2(out, &v); + poly_assert_normalized(out); +} + +// poly_invert sets |*out| to |in^-1| (i.e. such that |*out|×|in| = 1 mod Φ(N)). +static void poly_invert(struct POLY_MUL_SCRATCH *scratch, struct poly *out, + const struct poly *in) { + // Inversion mod Q, which is done based on the result of inverting mod + // 2. See [NTRUTN14] paper, bottom of page two. + struct poly a, *b, tmp; + + // a = -in. + for (unsigned i = 0; i < N; i++) { + a.v[i] = -in->v[i]; + } + poly_normalize(&a); + + // b = in^-1 mod 2. + b = out; + poly_invert_mod2(b, in); + + // We are working mod Q=2**13 and we need to iterate ceil(log_2(13)) + // times, which is four. + for (unsigned i = 0; i < 4; i++) { + poly_mul(scratch, &tmp, &a, b); + tmp.v[0] += 2; + poly_mul(scratch, b, b, &tmp); + } + + poly_assert_normalized(out); +} + +// Marshal and unmarshal functions for various basic types. +// -------------------------------------------------------- + +#define POLY_BYTES 1138 + +// poly_marshal serialises all but the final coefficient of |in| to |out|. +static void poly_marshal(uint8_t out[POLY_BYTES], const struct poly *in) { + const uint16_t *p = in->v; + + for (size_t i = 0; i < N / 8; i++) { + out[0] = p[0]; + out[1] = (0x1f & (p[0] >> 8)) | ((p[1] & 0x07) << 5); + out[2] = p[1] >> 3; + out[3] = (3 & (p[1] >> 11)) | ((p[2] & 0x3f) << 2); + out[4] = (0x7f & (p[2] >> 6)) | ((p[3] & 0x01) << 7); + out[5] = p[3] >> 1; + out[6] = (0xf & (p[3] >> 9)) | ((p[4] & 0x0f) << 4); + out[7] = p[4] >> 4; + out[8] = (1 & (p[4] >> 12)) | ((p[5] & 0x7f) << 1); + out[9] = (0x3f & (p[5] >> 7)) | ((p[6] & 0x03) << 6); + out[10] = p[6] >> 2; + out[11] = (7 & (p[6] >> 10)) | ((p[7] & 0x1f) << 3); + out[12] = p[7] >> 5; + + p += 8; + out += 13; + } + + // There are four remaining values. + out[0] = p[0]; + out[1] = (0x1f & (p[0] >> 8)) | ((p[1] & 0x07) << 5); + out[2] = p[1] >> 3; + out[3] = (3 & (p[1] >> 11)) | ((p[2] & 0x3f) << 2); + out[4] = (0x7f & (p[2] >> 6)) | ((p[3] & 0x01) << 7); + out[5] = p[3] >> 1; + out[6] = 0xf & (p[3] >> 9); +} + +// poly_unmarshal parses the output of |poly_marshal| and sets |out| such that +// all but the final coefficients match, and the final coefficient is calculated +// such that evaluating |out| at one results in zero. It returns one on success +// or zero if |in| is an invalid encoding. +static int poly_unmarshal(struct poly *out, const uint8_t in[POLY_BYTES]) { + uint16_t *p = out->v; + + for (size_t i = 0; i < N / 8; i++) { + p[0] = (uint16_t)(in[0]) | (uint16_t)(in[1] & 0x1f) << 8; + p[1] = (uint16_t)(in[1] >> 5) | (uint16_t)(in[2]) << 3 | + (uint16_t)(in[3] & 3) << 11; + p[2] = (uint16_t)(in[3] >> 2) | (uint16_t)(in[4] & 0x7f) << 6; + p[3] = (uint16_t)(in[4] >> 7) | (uint16_t)(in[5]) << 1 | + (uint16_t)(in[6] & 0xf) << 9; + p[4] = (uint16_t)(in[6] >> 4) | (uint16_t)(in[7]) << 4 | + (uint16_t)(in[8] & 1) << 12; + p[5] = (uint16_t)(in[8] >> 1) | (uint16_t)(in[9] & 0x3f) << 7; + p[6] = (uint16_t)(in[9] >> 6) | (uint16_t)(in[10]) << 2 | + (uint16_t)(in[11] & 7) << 10; + p[7] = (uint16_t)(in[11] >> 3) | (uint16_t)(in[12]) << 5; + + p += 8; + in += 13; + } + + // There are four coefficients remaining. + p[0] = (uint16_t)(in[0]) | (uint16_t)(in[1] & 0x1f) << 8; + p[1] = (uint16_t)(in[1] >> 5) | (uint16_t)(in[2]) << 3 | + (uint16_t)(in[3] & 3) << 11; + p[2] = (uint16_t)(in[3] >> 2) | (uint16_t)(in[4] & 0x7f) << 6; + p[3] = (uint16_t)(in[4] >> 7) | (uint16_t)(in[5]) << 1 | + (uint16_t)(in[6] & 0xf) << 9; + + for (unsigned i = 0; i < N - 1; i++) { + out->v[i] = (int16_t)(out->v[i] << 3) >> 3; + } + + // There are four unused bits in the last byte. We require them to be zero. + if ((in[6] & 0xf0) != 0) { + return 0; + } + + // Set the final coefficient as specifed in [HRSSNIST] 1.9.2 step 6. + uint32_t sum = 0; + for (size_t i = 0; i < N - 1; i++) { + sum += out->v[i]; + } + + out->v[N - 1] = (uint16_t)(0u - sum); + poly_normalize(out); + + return 1; +} + +// mod3_from_modQ maps {0, 1, Q-1, 65535} -> {0, 1, 2, 2}. Note that |v| may +// have an invalid value when processing attacker-controlled inputs. +static uint16_t mod3_from_modQ(uint16_t v) { + v &= 3; + return v ^ (v >> 1); +} + +// poly_marshal_mod3 marshals |in| to |out| where the coefficients of |in| are +// all in {0, 1, Q-1, 65535} and |in| is mod Φ(N). (Note that coefficients may +// have invalid values when processing attacker-controlled inputs.) +static void poly_marshal_mod3(uint8_t out[HRSS_POLY3_BYTES], + const struct poly *in) { + const uint16_t *coeffs = in->v; + + // Only 700 coefficients are marshaled because in[700] must be zero. + assert(coeffs[N-1] == 0); + + for (size_t i = 0; i < HRSS_POLY3_BYTES; i++) { + const uint16_t coeffs0 = mod3_from_modQ(coeffs[0]); + const uint16_t coeffs1 = mod3_from_modQ(coeffs[1]); + const uint16_t coeffs2 = mod3_from_modQ(coeffs[2]); + const uint16_t coeffs3 = mod3_from_modQ(coeffs[3]); + const uint16_t coeffs4 = mod3_from_modQ(coeffs[4]); + out[i] = coeffs0 + coeffs1 * 3 + coeffs2 * 9 + coeffs3 * 27 + coeffs4 * 81; + coeffs += 5; + } +} + +// HRSS-specific functions +// ----------------------- + +// poly_short_sample samples a vector of values in {0xffff (i.e. -1), 0, 1}. +// This is the same action as the algorithm in [HRSSNIST] section 1.8.1, but +// with HRSS-SXY the sampling algorithm is now a private detail of the +// implementation (previously it had to match between two parties). This +// function uses that freedom to implement a flatter distribution of values. +static void poly_short_sample(struct poly *out, + const uint8_t in[HRSS_SAMPLE_BYTES]) { + OPENSSL_STATIC_ASSERT(HRSS_SAMPLE_BYTES == N - 1, + "HRSS_SAMPLE_BYTES incorrect"); + for (size_t i = 0; i < N - 1; i++) { + uint16_t v = mod3(in[i]); + // Map {0, 1, 2} -> {0, 1, 0xffff} + v |= ((v >> 1) ^ 1) - 1; + out->v[i] = v; + } + out->v[N - 1] = 0; + poly_normalize(out); +} + +// poly_short_sample_plus performs the T+ sample as defined in [HRSSNIST], +// section 1.8.2. +static void poly_short_sample_plus(struct poly *out, + const uint8_t in[HRSS_SAMPLE_BYTES]) { + poly_short_sample(out, in); + + // sum (and the product in the for loop) will overflow. But that's fine + // because |sum| is bound by +/- (N-2), and N < 2^15 so it works out. + uint16_t sum = 0; + for (unsigned i = 0; i < N - 2; i++) { + sum += (unsigned) out->v[i] * out->v[i + 1]; + } + + // If the sum is negative, flip the sign of even-positioned coefficients. (See + // page 8 of [HRSS].) + sum = ((int16_t) sum) >> 15; + const uint16_t scale = sum | (~sum & 1); + for (unsigned i = 0; i < N; i += 2) { + out->v[i] = (unsigned) out->v[i] * scale; + } + poly_assert_normalized(out); +} + +// poly_lift computes the function discussed in [HRSS], appendix B. +static void poly_lift(struct poly *out, const struct poly *a) { + // We wish to calculate a/(𝑥-1) mod Φ(N) over GF(3), where Φ(N) is the + // Nth cyclotomic polynomial, i.e. 1 + 𝑥 + … + 𝑥^700 (since N is prime). + + // 1/(𝑥-1) has a fairly basic structure that we can exploit to speed this up: + // + // R. = PolynomialRing(GF(3)…) + // inv = R.cyclotomic_polynomial(1).inverse_mod(R.cyclotomic_polynomial(n)) + // list(inv)[:15] + // [1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2] + // + // This three-element pattern of coefficients repeats for the whole + // polynomial. + // + // Next define the overbar operator such that z̅ = z[0] + + // reverse(z[1:]). (Index zero of a polynomial here is the coefficient + // of the constant term. So index one is the coefficient of 𝑥 and so + // on.) + // + // A less odd way to define this is to see that z̅ negates the indexes, + // so z̅[0] = z[-0], z̅[1] = z[-1] and so on. + // + // The use of z̅ is that, when working mod (𝑥^701 - 1), vz[0] = , vz[1] = , …. (Where is the inner product: the sum + // of the point-wise products.) Although we calculated the inverse mod + // Φ(N), we can work mod (𝑥^N - 1) and reduce mod Φ(N) at the end. + // (That's because (𝑥^N - 1) is a multiple of Φ(N).) + // + // When working mod (𝑥^N - 1), multiplication by 𝑥 is a right-rotation + // of the list of coefficients. + // + // Thus we can consider what the pattern of z̅, 𝑥z̅, 𝑥^2z̅, … looks like: + // + // def reverse(xs): + // suffix = list(xs[1:]) + // suffix.reverse() + // return [xs[0]] + suffix + // + // def rotate(xs): + // return [xs[-1]] + xs[:-1] + // + // zoverbar = reverse(list(inv) + [0]) + // xzoverbar = rotate(reverse(list(inv) + [0])) + // x2zoverbar = rotate(rotate(reverse(list(inv) + [0]))) + // + // zoverbar[:15] + // [1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1] + // xzoverbar[:15] + // [0, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0] + // x2zoverbar[:15] + // [2, 0, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] + // + // (For a formula for z̅, see lemma two of appendix B.) + // + // After the first three elements have been taken care of, all then have + // a repeating three-element cycle. The next value (𝑥^3z̅) involves + // three rotations of the first pattern, thus the three-element cycle + // lines up. However, the discontinuity in the first three elements + // obviously moves to a different position. Consider the difference + // between 𝑥^3z̅ and z̅: + // + // [x-y for (x,y) in zip(zoverbar, x3zoverbar)][:15] + // [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + // + // This pattern of differences is the same for all elements, although it + // obviously moves right with the rotations. + // + // From this, we reach algorithm eight of appendix B. + + // Handle the first three elements of the inner products. + out->v[0] = a->v[0] + a->v[2]; + out->v[1] = a->v[1]; + out->v[2] = -a->v[0] + a->v[2]; + + // s0, s1, s2 are added into out->v[0], out->v[1], and out->v[2], + // respectively. We do not compute s1 because it's just -(s0 + s1). + uint16_t s0 = 0, s2 = 0; + for (size_t i = 3; i < 699; i += 3) { + s0 += -a->v[i] + a->v[i + 2]; + // s1 += a->v[i] - a->v[i + 1]; + s2 += a->v[i + 1] - a->v[i + 2]; + } + + // Handle the fact that the three-element pattern doesn't fill the + // polynomial exactly (since 701 isn't a multiple of three). + s0 -= a->v[699]; + // s1 += a->v[699] - a->v[700]; + s2 += a->v[700]; + + // Note that s0 + s1 + s2 = 0. + out->v[0] += s0; + out->v[1] -= (s0 + s2); // = s1 + out->v[2] += s2; + + // Calculate the remaining inner products by taking advantage of the + // fact that the pattern repeats every three cycles and the pattern of + // differences moves with the rotation. + for (size_t i = 3; i < N; i++) { + out->v[i] = (out->v[i - 3] - (a->v[i - 2] + a->v[i - 1] + a->v[i])); + } + + // Reduce mod Φ(N) by subtracting a multiple of out[700] from every + // element and convert to mod Q. (See above about adding twice as + // subtraction.) + const crypto_word_t v = out->v[700]; + for (unsigned i = 0; i < N; i++) { + const uint16_t vi_mod3 = mod3(out->v[i] - v); + // Map {0, 1, 2} to {0, 1, 0xffff}. + out->v[i] = (~((vi_mod3 >> 1) - 1)) | vi_mod3; + } + + poly_mul_x_minus_1(out); + poly_normalize(out); +} + +struct public_key { + struct poly ph; +}; + +struct private_key { + struct poly3 f, f_inverse; + struct poly ph_inverse; + uint8_t hmac_key[32]; +}; + +// public_key_from_external converts an external public key pointer into an +// internal one. Externally the alignment is only specified to be eight bytes +// but we need 16-byte alignment. We could annotate the external struct with +// that alignment but we can only assume that malloced pointers are 8-byte +// aligned in any case. (Even if the underlying malloc returns values with +// 16-byte alignment, |OPENSSL_malloc| will store an 8-byte size prefix and mess +// that up.) +static struct public_key *public_key_from_external( + struct HRSS_public_key *ext) { + OPENSSL_STATIC_ASSERT( + sizeof(struct HRSS_public_key) >= sizeof(struct public_key) + 15, + "HRSS public key too small"); + + return align_pointer(ext->opaque, 16); +} + +// private_key_from_external does the same thing as |public_key_from_external|, +// but for private keys. See the comment on that function about alignment +// issues. +static struct private_key *private_key_from_external( + struct HRSS_private_key *ext) { + OPENSSL_STATIC_ASSERT( + sizeof(struct HRSS_private_key) >= sizeof(struct private_key) + 15, + "HRSS private key too small"); + + return align_pointer(ext->opaque, 16); +} + +// malloc_align32 returns a pointer to |size| bytes of 32-byte-aligned heap and +// sets |*out_ptr| to a value that can be passed to |OPENSSL_free| to release +// it. It returns NULL if out of memory. +static void *malloc_align32(void **out_ptr, size_t size) { + void *ptr = OPENSSL_malloc(size + 31); + if (!ptr) { + *out_ptr = NULL; + return NULL; + } + + *out_ptr = ptr; + return align_pointer(ptr, 32); +} + +int HRSS_generate_key( + struct HRSS_public_key *out_pub, struct HRSS_private_key *out_priv, + const uint8_t in[HRSS_SAMPLE_BYTES + HRSS_SAMPLE_BYTES + 32]) { + struct public_key *pub = public_key_from_external(out_pub); + struct private_key *priv = private_key_from_external(out_priv); + + struct vars { + struct POLY_MUL_SCRATCH scratch; + struct poly f; + struct poly pg_phi1; + struct poly pfg_phi1; + struct poly pfg_phi1_inverse; + }; + + void *malloc_ptr; + struct vars *const vars = malloc_align32(&malloc_ptr, sizeof(struct vars)); + if (!vars) { + // If the caller ignores the return value the output will still be safe. + // The private key output is randomised in case it's later passed to + // |HRSS_encap|. + memset(out_pub, 0, sizeof(struct HRSS_public_key)); + RAND_bytes((uint8_t*) out_priv, sizeof(struct HRSS_private_key)); + return 0; + } + +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + + OPENSSL_memcpy(priv->hmac_key, in + 2 * HRSS_SAMPLE_BYTES, + sizeof(priv->hmac_key)); + + poly_short_sample_plus(&vars->f, in); + poly3_from_poly(&priv->f, &vars->f); + HRSS_poly3_invert(&priv->f_inverse, &priv->f); + + // pg_phi1 is p (i.e. 3) × g × Φ(1) (i.e. 𝑥-1). + poly_short_sample_plus(&vars->pg_phi1, in + HRSS_SAMPLE_BYTES); + for (unsigned i = 0; i < N; i++) { + vars->pg_phi1.v[i] *= 3; + } + poly_mul_x_minus_1(&vars->pg_phi1); + + poly_mul(&vars->scratch, &vars->pfg_phi1, &vars->f, &vars->pg_phi1); + + poly_invert(&vars->scratch, &vars->pfg_phi1_inverse, &vars->pfg_phi1); + + poly_mul(&vars->scratch, &pub->ph, &vars->pfg_phi1_inverse, &vars->pg_phi1); + poly_mul(&vars->scratch, &pub->ph, &pub->ph, &vars->pg_phi1); + poly_clamp(&pub->ph); + + poly_mul(&vars->scratch, &priv->ph_inverse, &vars->pfg_phi1_inverse, + &vars->f); + poly_mul(&vars->scratch, &priv->ph_inverse, &priv->ph_inverse, &vars->f); + poly_clamp(&priv->ph_inverse); + + OPENSSL_free(malloc_ptr); + return 1; +} + +static const char kSharedKey[] = "shared key"; + +int HRSS_encap(uint8_t out_ciphertext[POLY_BYTES], uint8_t out_shared_key[32], + const struct HRSS_public_key *in_pub, + const uint8_t in[HRSS_SAMPLE_BYTES + HRSS_SAMPLE_BYTES]) { + const struct public_key *pub = + public_key_from_external((struct HRSS_public_key *)in_pub); + + struct vars { + struct POLY_MUL_SCRATCH scratch; + struct poly m, r, m_lifted; + struct poly prh_plus_m; + SHA256_CTX hash_ctx; + uint8_t m_bytes[HRSS_POLY3_BYTES]; + uint8_t r_bytes[HRSS_POLY3_BYTES]; + }; + + void *malloc_ptr; + struct vars *const vars = malloc_align32(&malloc_ptr, sizeof(struct vars)); + if (!vars) { + // If the caller ignores the return value the output will still be safe. + // The private key output is randomised in case it's used to encrypt and + // transmit something. + memset(out_ciphertext, 0, POLY_BYTES); + RAND_bytes(out_shared_key, 32); + return 0; + } + +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + + poly_short_sample(&vars->m, in); + poly_short_sample(&vars->r, in + HRSS_SAMPLE_BYTES); + poly_lift(&vars->m_lifted, &vars->m); + + poly_mul(&vars->scratch, &vars->prh_plus_m, &vars->r, &pub->ph); + for (unsigned i = 0; i < N; i++) { + vars->prh_plus_m.v[i] += vars->m_lifted.v[i]; + } + + poly_marshal(out_ciphertext, &vars->prh_plus_m); + + poly_marshal_mod3(vars->m_bytes, &vars->m); + poly_marshal_mod3(vars->r_bytes, &vars->r); + + SHA256_Init(&vars->hash_ctx); + SHA256_Update(&vars->hash_ctx, kSharedKey, sizeof(kSharedKey)); + SHA256_Update(&vars->hash_ctx, vars->m_bytes, sizeof(vars->m_bytes)); + SHA256_Update(&vars->hash_ctx, vars->r_bytes, sizeof(vars->r_bytes)); + SHA256_Update(&vars->hash_ctx, out_ciphertext, POLY_BYTES); + SHA256_Final(out_shared_key, &vars->hash_ctx); + + OPENSSL_free(malloc_ptr); + return 1; +} + +int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], + const struct HRSS_private_key *in_priv, + const uint8_t *ciphertext, size_t ciphertext_len) { + const struct private_key *priv = + private_key_from_external((struct HRSS_private_key *)in_priv); + + struct vars { + struct POLY_MUL_SCRATCH scratch; + uint8_t masked_key[SHA256_CBLOCK]; + SHA256_CTX hash_ctx; + struct poly c; + struct poly f, cf; + struct poly3 cf3, m3; + struct poly m, m_lifted; + struct poly r; + struct poly3 r3; + uint8_t expected_ciphertext[HRSS_CIPHERTEXT_BYTES]; + uint8_t m_bytes[HRSS_POLY3_BYTES]; + uint8_t r_bytes[HRSS_POLY3_BYTES]; + uint8_t shared_key[32]; + }; + + void *malloc_ptr; + struct vars *const vars = malloc_align32(&malloc_ptr, sizeof(struct vars)); + if (!vars) { + // If the caller ignores the return value the output will still be safe. + // The private key output is randomised in case it's used to encrypt and + // transmit something. + RAND_bytes(out_shared_key, HRSS_KEY_BYTES); + return 0; + } + +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + + // This is HMAC, expanded inline rather than using the |HMAC| function so that + // we can avoid dealing with possible allocation failures and so keep this + // function infallible. + OPENSSL_STATIC_ASSERT(sizeof(priv->hmac_key) <= sizeof(vars->masked_key), + "HRSS HMAC key larger than SHA-256 block size"); + for (size_t i = 0; i < sizeof(priv->hmac_key); i++) { + vars->masked_key[i] = priv->hmac_key[i] ^ 0x36; + } + OPENSSL_memset(vars->masked_key + sizeof(priv->hmac_key), 0x36, + sizeof(vars->masked_key) - sizeof(priv->hmac_key)); + + SHA256_Init(&vars->hash_ctx); + SHA256_Update(&vars->hash_ctx, vars->masked_key, sizeof(vars->masked_key)); + SHA256_Update(&vars->hash_ctx, ciphertext, ciphertext_len); + uint8_t inner_digest[SHA256_DIGEST_LENGTH]; + SHA256_Final(inner_digest, &vars->hash_ctx); + + for (size_t i = 0; i < sizeof(priv->hmac_key); i++) { + vars->masked_key[i] ^= (0x5c ^ 0x36); + } + OPENSSL_memset(vars->masked_key + sizeof(priv->hmac_key), 0x5c, + sizeof(vars->masked_key) - sizeof(priv->hmac_key)); + + SHA256_Init(&vars->hash_ctx); + SHA256_Update(&vars->hash_ctx, vars->masked_key, sizeof(vars->masked_key)); + SHA256_Update(&vars->hash_ctx, inner_digest, sizeof(inner_digest)); + OPENSSL_STATIC_ASSERT(HRSS_KEY_BYTES == SHA256_DIGEST_LENGTH, + "HRSS shared key length incorrect"); + SHA256_Final(out_shared_key, &vars->hash_ctx); + + // If the ciphertext is publicly invalid then a random shared key is still + // returned to simply the logic of the caller, but this path is not constant + // time. + if (ciphertext_len != HRSS_CIPHERTEXT_BYTES || + !poly_unmarshal(&vars->c, ciphertext)) { + goto out; + } + + poly_from_poly3(&vars->f, &priv->f); + poly_mul(&vars->scratch, &vars->cf, &vars->c, &vars->f); + poly3_from_poly(&vars->cf3, &vars->cf); + // Note that cf3 is not reduced mod Φ(N). That reduction is deferred. + HRSS_poly3_mul(&vars->m3, &vars->cf3, &priv->f_inverse); + + poly_from_poly3(&vars->m, &vars->m3); + poly_lift(&vars->m_lifted, &vars->m); + + for (unsigned i = 0; i < N; i++) { + vars->r.v[i] = vars->c.v[i] - vars->m_lifted.v[i]; + } + poly_normalize(&vars->r); + poly_mul(&vars->scratch, &vars->r, &vars->r, &priv->ph_inverse); + poly_mod_phiN(&vars->r); + poly_clamp(&vars->r); + + crypto_word_t ok = poly3_from_poly_checked(&vars->r3, &vars->r); + + // [NTRUCOMP] section 5.1 includes ReEnc2 and a proof that it's valid. Rather + // than do an expensive |poly_mul|, it rebuilds |c'| from |c - lift(m)| + // (called |b|) with: + // t = (−b(1)/N) mod Q + // c' = b + tΦ(N) + lift(m) mod Q + // + // When polynomials are transmitted, the final coefficient is omitted and + // |poly_unmarshal| sets it such that f(1) == 0. Thus c(1) == 0. Also, + // |poly_lift| multiplies the result by (x-1) and therefore evaluating a + // lifted polynomial at 1 is also zero. Thus lift(m)(1) == 0 and so + // (c - lift(m))(1) == 0. + // + // Although we defer the reduction above, |b| is conceptually reduced mod + // Φ(N). In order to do that reduction one subtracts |c[N-1]| from every + // coefficient. Therefore b(1) = -c[N-1]×N. The value of |t|, above, then is + // just recovering |c[N-1]|, and adding tΦ(N) is simply undoing the reduction. + // Therefore b + tΦ(N) + lift(m) = c by construction and we don't need to + // recover |c| at all so long as we do the checks in + // |poly3_from_poly_checked|. + // + // The |poly_marshal| here then is just confirming that |poly_unmarshal| is + // strict and could be omitted. + + OPENSSL_STATIC_ASSERT(HRSS_CIPHERTEXT_BYTES == POLY_BYTES, + "ciphertext is the wrong size"); + assert(ciphertext_len == sizeof(vars->expected_ciphertext)); + poly_marshal(vars->expected_ciphertext, &vars->c); + + poly_marshal_mod3(vars->m_bytes, &vars->m); + poly_marshal_mod3(vars->r_bytes, &vars->r); + + ok &= constant_time_is_zero_w( + CRYPTO_memcmp(ciphertext, vars->expected_ciphertext, + sizeof(vars->expected_ciphertext))); + + SHA256_Init(&vars->hash_ctx); + SHA256_Update(&vars->hash_ctx, kSharedKey, sizeof(kSharedKey)); + SHA256_Update(&vars->hash_ctx, vars->m_bytes, sizeof(vars->m_bytes)); + SHA256_Update(&vars->hash_ctx, vars->r_bytes, sizeof(vars->r_bytes)); + SHA256_Update(&vars->hash_ctx, vars->expected_ciphertext, + sizeof(vars->expected_ciphertext)); + SHA256_Final(vars->shared_key, &vars->hash_ctx); + + for (unsigned i = 0; i < sizeof(vars->shared_key); i++) { + out_shared_key[i] = + constant_time_select_8(ok, vars->shared_key[i], out_shared_key[i]); + } + +out: + OPENSSL_free(malloc_ptr); + return 1; +} + +void HRSS_marshal_public_key(uint8_t out[HRSS_PUBLIC_KEY_BYTES], + const struct HRSS_public_key *in_pub) { + const struct public_key *pub = + public_key_from_external((struct HRSS_public_key *)in_pub); + poly_marshal(out, &pub->ph); +} + +int HRSS_parse_public_key(struct HRSS_public_key *out, + const uint8_t in[HRSS_PUBLIC_KEY_BYTES]) { + struct public_key *pub = public_key_from_external(out); + if (!poly_unmarshal(&pub->ph, in)) { + return 0; + } + OPENSSL_memset(&pub->ph.v[N], 0, 3 * sizeof(uint16_t)); + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/internal.h new file mode 100644 index 00000000..3cb7a23d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/hrss/internal.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HRSS_INTERNAL_H +#define OPENSSL_HEADER_HRSS_INTERNAL_H + +#include +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define N 701 +#define BITS_PER_WORD (sizeof(crypto_word_t) * 8) +#define WORDS_PER_POLY ((N + BITS_PER_WORD - 1) / BITS_PER_WORD) +#define BITS_IN_LAST_WORD (N % BITS_PER_WORD) + +struct poly2 { + crypto_word_t v[WORDS_PER_POLY]; +}; + +struct poly3 { + struct poly2 s, a; +}; + +OPENSSL_EXPORT void HRSS_poly3_mul(struct poly3 *out, const struct poly3 *x, + const struct poly3 *y); +OPENSSL_EXPORT void HRSS_poly3_invert(struct poly3 *out, + const struct poly3 *in); + +// On x86-64, we can use the AVX2 code from [HRSS]. (The authors have given +// explicit permission for this and signed a CLA.) However it's 57KB of object +// code, so it's not used if |OPENSSL_SMALL| is defined. +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \ + defined(OPENSSL_X86_64) && defined(OPENSSL_LINUX) +#define POLY_RQ_MUL_ASM +// POLY_MUL_RQ_SCRATCH_SPACE is the number of bytes of scratch space needed +// by the assembly function poly_Rq_mul. +#define POLY_MUL_RQ_SCRATCH_SPACE (6144 + 6144 + 12288 + 512 + 9408 + 32) + +// poly_Rq_mul is defined in assembly. Inputs and outputs must be 16-byte- +// aligned. +extern void poly_Rq_mul( + uint16_t r[N + 3], const uint16_t a[N + 3], const uint16_t b[N + 3], + // The following should be `scratch[POLY_MUL_RQ_SCRATCH_SPACE]` but + // GCC 11.1 has a bug with unions that breaks that. + uint8_t scratch[]); +#endif + + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // !OPENSSL_HEADER_HRSS_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/internal.h new file mode 100644 index 00000000..4c4fed52 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/internal.h @@ -0,0 +1,1256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_INTERNAL_H + +#include +#include +#include +#include + +#include +#include + +#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION) +#include +#endif + +#if defined(BORINGSSL_FIPS_BREAK_TESTS) +#include +#endif + +#if !defined(__cplusplus) +#if defined(_MSC_VER) && !defined(__clang__) +#define alignas(x) __declspec(align(x)) +#define alignof __alignof +#else +// With the exception of MSVC, we require C11 to build the library. C11 is a +// prerequisite for improved refcounting performance. All our supported C +// compilers have long implemented C11 and made it default. The most likely +// cause of pre-C11 modes is stale -std=c99 or -std=gnu99 flags in build +// configuration. Such flags can be removed. +#if __STDC_VERSION__ < 201112L +#error "BoringSSL must be built in C11 mode or higher." +#endif +#include +#endif +#endif + +#if defined(OPENSSL_THREADS) && \ + (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__)) +#include +#define OPENSSL_PTHREADS +#endif + +#if defined(OPENSSL_THREADS) && !defined(OPENSSL_PTHREADS) && \ + defined(OPENSSL_WINDOWS) +#define OPENSSL_WINDOWS_THREADS +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ + defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) +// OPENSSL_cpuid_setup initializes the platform-specific feature cache. +void OPENSSL_cpuid_setup(void); +#endif + +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_STATIC_ARMCAP) +// OPENSSL_get_armcap_pointer_for_test returns a pointer to |OPENSSL_armcap_P| +// for unit tests. Any modifications to the value must be made after +// |CRYPTO_library_init| but before any other function call in BoringSSL. +OPENSSL_EXPORT uint32_t *OPENSSL_get_armcap_pointer_for_test(void); +#endif + + +#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT) +#define BORINGSSL_HAS_UINT128 +typedef __int128_t int128_t; +typedef __uint128_t uint128_t; + +// clang-cl supports __uint128_t but modulus and division don't work. +// https://crbug.com/787617. +#if !defined(_MSC_VER) || !defined(__clang__) +#define BORINGSSL_CAN_DIVIDE_UINT128 +#endif +#endif + +#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +// Have a generic fall-through for different versions of C/C++. +#if defined(__cplusplus) && __cplusplus >= 201703L +#define OPENSSL_FALLTHROUGH [[fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__clang__) +#define OPENSSL_FALLTHROUGH [[clang::fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__GNUC__) && \ + __GNUC__ >= 7 +#define OPENSSL_FALLTHROUGH [[gnu::fallthrough]] +#elif defined(__GNUC__) && __GNUC__ >= 7 // gcc 7 +#define OPENSSL_FALLTHROUGH __attribute__ ((fallthrough)) +#elif defined(__clang__) +#if __has_attribute(fallthrough) && __clang_major__ >= 5 +// Clang 3.5, at least, complains about "error: declaration does not declare +// anything", possibily because we put a semicolon after this macro in +// practice. Thus limit it to >= Clang 5, which does work. +#define OPENSSL_FALLTHROUGH __attribute__ ((fallthrough)) +#else // clang versions that do not support fallthrough. +#define OPENSSL_FALLTHROUGH +#endif +#else // C++11 on gcc 6, and all other cases +#define OPENSSL_FALLTHROUGH +#endif + +// For convenience in testing 64-bit generic code, we allow disabling SSE2 +// intrinsics via |OPENSSL_NO_SSE2_FOR_TESTING|. x86_64 always has SSE2 +// available, so we would otherwise need to test such code on a non-x86_64 +// platform. +#if defined(__SSE2__) && !defined(OPENSSL_NO_SSE2_FOR_TESTING) +#define OPENSSL_SSE2 +#endif + + +// Pointer utility functions. + +// buffers_alias returns one if |a| and |b| alias and zero otherwise. +static inline int buffers_alias(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len) { + // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated + // objects are undefined whereas pointer to integer conversions are merely + // implementation-defined. We assume the implementation defined it in a sane + // way. + uintptr_t a_u = (uintptr_t)a; + uintptr_t b_u = (uintptr_t)b; + return a_u + a_len > b_u && b_u + b_len > a_u; +} + +// align_pointer returns |ptr|, advanced to |alignment|. |alignment| must be a +// power of two, and |ptr| must have at least |alignment - 1| bytes of scratch +// space. +static inline void *align_pointer(void *ptr, size_t alignment) { + // |alignment| must be a power of two. + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); + // Instead of aligning |ptr| as a |uintptr_t| and casting back, compute the + // offset and advance in pointer space. C guarantees that casting from pointer + // to |uintptr_t| and back gives the same pointer, but general + // integer-to-pointer conversions are implementation-defined. GCC does define + // it in the useful way, but this makes fewer assumptions. + uintptr_t offset = (0u - (uintptr_t)ptr) & (alignment - 1); + ptr = (char *)ptr + offset; + assert(((uintptr_t)ptr & (alignment - 1)) == 0); + return ptr; +} + + +// Constant-time utility functions. +// +// The following methods return a bitmask of all ones (0xff...f) for true and 0 +// for false. This is useful for choosing a value based on the result of a +// conditional in constant time. For example, +// +// if (a < b) { +// c = a; +// } else { +// c = b; +// } +// +// can be written as +// +// crypto_word_t lt = constant_time_lt_w(a, b); +// c = constant_time_select_w(lt, a, b); + +// crypto_word_t is the type that most constant-time functions use. Ideally we +// would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit +// pointers, which means that |size_t| can be 32 bits when |BN_ULONG| is 64 +// bits. Since we want to be able to do constant-time operations on a +// |BN_ULONG|, |crypto_word_t| is defined as an unsigned value with the native +// word length. +#if defined(OPENSSL_64_BIT) +typedef uint64_t crypto_word_t; +#elif defined(OPENSSL_32_BIT) +typedef uint32_t crypto_word_t; +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +#define CONSTTIME_TRUE_W ~((crypto_word_t)0) +#define CONSTTIME_FALSE_W ((crypto_word_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) +#define CONSTTIME_FALSE_8 ((uint8_t)0) + +// value_barrier_w returns |a|, but prevents GCC and Clang from reasoning about +// the returned value. This is used to mitigate compilers undoing constant-time +// code, until we can express our requirements directly in the language. +// +// Note the compiler is aware that |value_barrier_w| has no side effects and +// always has the same output for a given input. This allows it to eliminate +// dead code, move computations across loops, and vectorize. +static inline crypto_word_t value_barrier_w(crypto_word_t a) { +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) + __asm__("" : "+r"(a) : /* no inputs */); +#endif + return a; +} + +// value_barrier_u32 behaves like |value_barrier_w| but takes a |uint32_t|. +static inline uint32_t value_barrier_u32(uint32_t a) { +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) + __asm__("" : "+r"(a) : /* no inputs */); +#endif + return a; +} + +// value_barrier_u64 behaves like |value_barrier_w| but takes a |uint64_t|. +static inline uint64_t value_barrier_u64(uint64_t a) { +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) + __asm__("" : "+r"(a) : /* no inputs */); +#endif + return a; +} + +// constant_time_msb_w returns the given value with the MSB copied to all the +// other bits. +static inline crypto_word_t constant_time_msb_w(crypto_word_t a) { + return 0u - (a >> (sizeof(a) * 8 - 1)); +} + +// constant_time_lt_w returns 0xff..f if a < b and 0 otherwise. +static inline crypto_word_t constant_time_lt_w(crypto_word_t a, + crypto_word_t b) { + // Consider the two cases of the problem: + // msb(a) == msb(b): a < b iff the MSB of a - b is set. + // msb(a) != msb(b): a < b iff the MSB of b is set. + // + // If msb(a) == msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^((a-b) ^ a)) == (because msb(a^b) == 0) + // msb(a^a^(a-b)) == (rearranging) + // msb(a-b) (because ∀x. x^x == 0) + // + // Else, if msb(a) != msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^(𝟙 | ((a-b)^a))) == (because msb(a^b) == 1 and 𝟙 + // represents a value s.t. msb(𝟙) = 1) + // msb(a^𝟙) == (because ORing with 1 results in 1) + // msb(b) + // + // + // Here is an SMT-LIB verification of this formula: + // + // (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32) + // (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a))) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // (declare-fun b () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(a^((a^b)|((a-b)^a))); +} + +// constant_time_lt_8 acts like |constant_time_lt_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_lt_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_lt_w(a, b)); +} + +// constant_time_ge_w returns 0xff..f if a >= b and 0 otherwise. +static inline crypto_word_t constant_time_ge_w(crypto_word_t a, + crypto_word_t b) { + return ~constant_time_lt_w(a, b); +} + +// constant_time_ge_8 acts like |constant_time_ge_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_ge_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_ge_w(a, b)); +} + +// constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. +static inline crypto_word_t constant_time_is_zero_w(crypto_word_t a) { + // Here is an SMT-LIB verification of this formula: + // + // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32) + // (bvand (bvnot a) (bvsub a #x00000001)) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(~a & (a - 1)); +} + +// constant_time_is_zero_8 acts like |constant_time_is_zero_w| but returns an +// 8-bit mask. +static inline uint8_t constant_time_is_zero_8(crypto_word_t a) { + return (uint8_t)(constant_time_is_zero_w(a)); +} + +// constant_time_eq_w returns 0xff..f if a == b and 0 otherwise. +static inline crypto_word_t constant_time_eq_w(crypto_word_t a, + crypto_word_t b) { + return constant_time_is_zero_w(a ^ b); +} + +// constant_time_eq_8 acts like |constant_time_eq_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_eq_w(a, b)); +} + +// constant_time_eq_int acts like |constant_time_eq_w| but works on int +// values. +static inline crypto_word_t constant_time_eq_int(int a, int b) { + return constant_time_eq_w((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_int_8(int a, int b) { + return constant_time_eq_8((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is all +// 1s or all 0s (as returned by the methods above), the select methods return +// either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). +static inline crypto_word_t constant_time_select_w(crypto_word_t mask, + crypto_word_t a, + crypto_word_t b) { + // Clang recognizes this pattern as a select. While it usually transforms it + // to a cmov, it sometimes further transforms it into a branch, which we do + // not want. + // + // Adding barriers to both |mask| and |~mask| breaks the relationship between + // the two, which makes the compiler stick with bitmasks. + return (value_barrier_w(mask) & a) | (value_barrier_w(~mask) & b); +} + +// constant_time_select_8 acts like |constant_time_select| but operates on +// 8-bit values. +static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a, + uint8_t b) { + return (uint8_t)(constant_time_select_w(mask, a, b)); +} + +// constant_time_select_int acts like |constant_time_select| but operates on +// ints. +static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { + return (int)(constant_time_select_w(mask, (crypto_word_t)(a), + (crypto_word_t)(b))); +} + +#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION) + +// CONSTTIME_SECRET takes a pointer and a number of bytes and marks that region +// of memory as secret. Secret data is tracked as it flows to registers and +// other parts of a memory. If secret data is used as a condition for a branch, +// or as a memory index, it will trigger warnings in valgrind. +#define CONSTTIME_SECRET(x, y) VALGRIND_MAKE_MEM_UNDEFINED(x, y) + +// CONSTTIME_DECLASSIFY takes a pointer and a number of bytes and marks that +// region of memory as public. Public data is not subject to constant-time +// rules. +#define CONSTTIME_DECLASSIFY(x, y) VALGRIND_MAKE_MEM_DEFINED(x, y) + +#else + +#define CONSTTIME_SECRET(x, y) +#define CONSTTIME_DECLASSIFY(x, y) + +#endif // BORINGSSL_CONSTANT_TIME_VALIDATION + + +// Thread-safe initialisation. + +#if !defined(OPENSSL_THREADS) +typedef uint32_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT 0 +#elif defined(OPENSSL_WINDOWS_THREADS) +typedef INIT_ONCE CRYPTO_once_t; +#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT +#elif defined(OPENSSL_PTHREADS) +typedef pthread_once_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT +#else +#error "Unknown threading library" +#endif + +// CRYPTO_once calls |init| exactly once per process. This is thread-safe: if +// concurrent threads call |CRYPTO_once| with the same |CRYPTO_once_t| argument +// then they will block until |init| completes, but |init| will have only been +// called once. +// +// The |once| argument must be a |CRYPTO_once_t| that has been initialised with +// the value |CRYPTO_ONCE_INIT|. +OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); + + +// Reference counting. + +// Automatically enable C11 atomics if implemented. +#if !defined(OPENSSL_C11_ATOMIC) && defined(OPENSSL_THREADS) && \ + !defined(__STDC_NO_ATOMICS__) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 201112L +#define OPENSSL_C11_ATOMIC +#endif + +// CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. +#define CRYPTO_REFCOUNT_MAX 0xffffffff + +// CRYPTO_refcount_inc atomically increments the value at |*count| unless the +// value would overflow. It's safe for multiple threads to concurrently call +// this or |CRYPTO_refcount_dec_and_test_zero| on the same +// |CRYPTO_refcount_t|. +OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count); + +// CRYPTO_refcount_dec_and_test_zero tests the value at |*count|: +// if it's zero, it crashes the address space. +// if it's the maximum value, it returns zero. +// otherwise, it atomically decrements it and returns one iff the resulting +// value is zero. +// +// It's safe for multiple threads to concurrently call this or +// |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|. +OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count); + + +// Locks. +// +// Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in +// structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as +// a global lock. A global lock must be initialised to the value +// |CRYPTO_STATIC_MUTEX_INIT|. +// +// |CRYPTO_MUTEX| can appear in public structures and so is defined in +// thread.h as a structure large enough to fit the real type. The global lock is +// a different type so it may be initialized with platform initializer macros. + +#if !defined(OPENSSL_THREADS) +struct CRYPTO_STATIC_MUTEX { + char padding; // Empty structs have different sizes in C and C++. +}; +#define CRYPTO_STATIC_MUTEX_INIT { 0 } +#elif defined(OPENSSL_WINDOWS_THREADS) +struct CRYPTO_STATIC_MUTEX { + SRWLOCK lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT } +#elif defined(OPENSSL_PTHREADS) +struct CRYPTO_STATIC_MUTEX { + pthread_rwlock_t lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER } +#else +#error "Unknown threading library" +#endif + +// CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a +// |CRYPTO_STATIC_MUTEX|. +OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a +// read lock, but none may have a write lock. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type +// of lock on it. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_cleanup releases all resources held by |lock|. +OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also +// have a read lock, but none may have a write lock. The |lock| variable does +// not need to be initialised by any function, but must have been statically +// initialised with |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has +// any type of lock on it. The |lock| variable does not need to be initialised +// by any function, but must have been statically initialised with +// |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +#if defined(__cplusplus) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +namespace internal { + +// MutexLockBase is a RAII helper for CRYPTO_MUTEX locking. +template +class MutexLockBase { + public: + explicit MutexLockBase(CRYPTO_MUTEX *mu) : mu_(mu) { + assert(mu_ != nullptr); + LockFunc(mu_); + } + ~MutexLockBase() { ReleaseFunc(mu_); } + MutexLockBase(const MutexLockBase &) = delete; + MutexLockBase &operator=(const MutexLockBase &) = + delete; + + private: + CRYPTO_MUTEX *const mu_; +}; + +} // namespace internal + +using MutexWriteLock = + internal::MutexLockBase; +using MutexReadLock = + internal::MutexLockBase; + +BSSL_NAMESPACE_END + +} // extern "C++" +#endif // defined(__cplusplus) + + +// Thread local storage. + +// thread_local_data_t enumerates the types of thread-local data that can be +// stored. +typedef enum { + OPENSSL_THREAD_LOCAL_ERR = 0, + OPENSSL_THREAD_LOCAL_RAND, + OPENSSL_THREAD_LOCAL_FIPS_COUNTERS, + OPENSSL_THREAD_LOCAL_TEST, + NUM_OPENSSL_THREAD_LOCALS, +} thread_local_data_t; + +// thread_local_destructor_t is the type of a destructor function that will be +// called when a thread exits and its thread-local storage needs to be freed. +typedef void (*thread_local_destructor_t)(void *); + +// CRYPTO_get_thread_local gets the pointer value that is stored for the +// current thread for the given index, or NULL if none has been set. +OPENSSL_EXPORT void *CRYPTO_get_thread_local(thread_local_data_t value); + +// CRYPTO_set_thread_local sets a pointer value for the current thread at the +// given index. This function should only be called once per thread for a given +// |index|: rather than update the pointer value itself, update the data that +// is pointed to. +// +// The destructor function will be called when a thread exits to free this +// thread-local data. All calls to |CRYPTO_set_thread_local| with the same +// |index| should have the same |destructor| argument. The destructor may be +// called with a NULL argument if a thread that never set a thread-local +// pointer for |index|, exits. The destructor may be called concurrently with +// different arguments. +// +// This function returns one on success or zero on error. If it returns zero +// then |destructor| has been called with |value| already. +OPENSSL_EXPORT int CRYPTO_set_thread_local( + thread_local_data_t index, void *value, + thread_local_destructor_t destructor); + + +// ex_data + +typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +// CRYPTO_EX_DATA_CLASS tracks the ex_indices registered for a type which +// supports ex_data. It should defined as a static global within the module +// which defines that type. +typedef struct { + struct CRYPTO_STATIC_MUTEX lock; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + // num_reserved is one if the ex_data index zero is reserved for legacy + // |TYPE_get_app_data| functions. + uint8_t num_reserved; +} CRYPTO_EX_DATA_CLASS; + +#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0} +#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \ + {CRYPTO_STATIC_MUTEX_INIT, NULL, 1} + +// CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes +// it to |*out_index|. Each class of object should provide a wrapper function +// that uses the correct |CRYPTO_EX_DATA_CLASS|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, + int *out_index, long argl, + void *argp, + CRYPTO_EX_free *free_func); + +// CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class +// of object should provide a wrapper function. +OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val); + +// CRYPTO_get_ex_data returns an extra data pointer for a given object, or NULL +// if no such index exists. Each class of object should provide a wrapper +// function. +OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index); + +// CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. +OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad); + +// CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an +// object of the given class. +OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, + void *obj, CRYPTO_EX_DATA *ad); + + +// Endianness conversions. + +#if defined(__GNUC__) && __GNUC__ >= 2 +static inline uint16_t CRYPTO_bswap2(uint16_t x) { + return __builtin_bswap16(x); +} + +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return __builtin_bswap32(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return __builtin_bswap64(x); +} +#elif defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(_byteswap_uint64, _byteswap_ulong, _byteswap_ushort) +static inline uint16_t CRYPTO_bswap2(uint16_t x) { + return _byteswap_ushort(x); +} + +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return _byteswap_ulong(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return _byteswap_uint64(x); +} +#else +static inline uint16_t CRYPTO_bswap2(uint16_t x) { + return (x >> 8) | (x << 8); +} + +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + x = (x >> 16) | (x << 16); + x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8); + return x; +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32); +} +#endif + + +// Language bug workarounds. +// +// Most C standard library functions are undefined if passed NULL, even when the +// corresponding length is zero. This gives them (and, in turn, all functions +// which call them) surprising behavior on empty arrays. Some compilers will +// miscompile code due to this rule. See also +// https://www.imperialviolet.org/2016/06/26/nonnull.html +// +// These wrapper functions behave the same as the corresponding C standard +// functions, but behave as expected when passed NULL if the length is zero. +// +// Note |OPENSSL_memcmp| is a different function from |CRYPTO_memcmp|. + +// C++ defines |memchr| as a const-correct overload. +#if defined(__cplusplus) +extern "C++" { + +static inline const void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +static inline void *OPENSSL_memchr(void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +} // extern "C++" +#else // __cplusplus + +static inline void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +#endif // __cplusplus + +static inline int OPENSSL_memcmp(const void *s1, const void *s2, size_t n) { + if (n == 0) { + return 0; + } + + return memcmp(s1, s2, n); +} + +static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memcpy(dst, src, n); +} + +static inline void *OPENSSL_memmove(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memmove(dst, src, n); +} + +static inline void *OPENSSL_memset(void *dst, int c, size_t n) { + if (n == 0) { + return dst; + } + + return memset(dst, c, n); +} + + +// Loads and stores. +// +// The following functions load and store sized integers with the specified +// endianness. They use |memcpy|, and so avoid alignment or strict aliasing +// requirements on the input and output pointers. + +static inline uint32_t CRYPTO_load_u32_le(const void *in) { + uint32_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void CRYPTO_store_u32_le(void *out, uint32_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +static inline uint32_t CRYPTO_load_u32_be(const void *in) { + uint32_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return CRYPTO_bswap4(v); +} + +static inline void CRYPTO_store_u32_be(void *out, uint32_t v) { + v = CRYPTO_bswap4(v); + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +static inline uint64_t CRYPTO_load_u64_be(const void *ptr) { + uint64_t ret; + OPENSSL_memcpy(&ret, ptr, sizeof(ret)); + return CRYPTO_bswap8(ret); +} + +static inline void CRYPTO_store_u64_be(void *out, uint64_t v) { + v = CRYPTO_bswap8(v); + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +static inline crypto_word_t CRYPTO_load_word_le(const void *in) { + crypto_word_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void CRYPTO_store_word_le(void *out, crypto_word_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + + +// Bit rotation functions. +// +// Note these functions use |(-shift) & 31|, etc., because shifting by the bit +// width is undefined. Both Clang and GCC recognize this pattern as a rotation, +// but MSVC does not. Instead, we call MSVC's built-in functions. + +static inline uint32_t CRYPTO_rotl_u32(uint32_t value, int shift) { +#if defined(_MSC_VER) + return _rotl(value, shift); +#else + return (value << shift) | (value >> ((-shift) & 31)); +#endif +} + +static inline uint32_t CRYPTO_rotr_u32(uint32_t value, int shift) { +#if defined(_MSC_VER) + return _rotr(value, shift); +#else + return (value >> shift) | (value << ((-shift) & 31)); +#endif +} + +static inline uint64_t CRYPTO_rotl_u64(uint64_t value, int shift) { +#if defined(_MSC_VER) + return _rotl64(value, shift); +#else + return (value << shift) | (value >> ((-shift) & 63)); +#endif +} + +static inline uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) { +#if defined(_MSC_VER) + return _rotr64(value, shift); +#else + return (value >> shift) | (value << ((-shift) & 63)); +#endif +} + + +// FIPS functions. + +#if defined(BORINGSSL_FIPS) + +// BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test +// fails. It prevents any further cryptographic operations by the current +// process. +void BORINGSSL_FIPS_abort(void) __attribute__((noreturn)); + +// boringssl_self_test_startup runs all startup self tests and returns one on +// success or zero on error. Startup self tests do not include lazy tests. +// Call |BORINGSSL_self_test| to run every self test. +int boringssl_self_test_startup(void); + +// boringssl_ensure_rsa_self_test checks whether the RSA self-test has been run +// in this address space. If not, it runs it and crashes the address space if +// unsuccessful. +void boringssl_ensure_rsa_self_test(void); + +// boringssl_ensure_ecc_self_test checks whether the ECDSA and ECDH self-test +// has been run in this address space. If not, it runs it and crashes the +// address space if unsuccessful. +void boringssl_ensure_ecc_self_test(void); + +// boringssl_ensure_ffdh_self_test checks whether the FFDH self-test has been +// run in this address space. If not, it runs it and crashes the address space +// if unsuccessful. +void boringssl_ensure_ffdh_self_test(void); + +#else + +// Outside of FIPS mode, the lazy tests are no-ops. + +OPENSSL_INLINE void boringssl_ensure_rsa_self_test(void) {} +OPENSSL_INLINE void boringssl_ensure_ecc_self_test(void) {} +OPENSSL_INLINE void boringssl_ensure_ffdh_self_test(void) {} + +#endif // FIPS + +// boringssl_self_test_sha256 performs a SHA-256 KAT. +int boringssl_self_test_sha256(void); + +// boringssl_self_test_sha512 performs a SHA-512 KAT. +int boringssl_self_test_sha512(void); + +// boringssl_self_test_hmac_sha256 performs an HMAC-SHA-256 KAT. +int boringssl_self_test_hmac_sha256(void); + +#if defined(BORINGSSL_FIPS_COUNTERS) +void boringssl_fips_inc_counter(enum fips_counter_t counter); +#else +OPENSSL_INLINE void boringssl_fips_inc_counter(enum fips_counter_t counter) {} +#endif + +#if defined(BORINGSSL_FIPS_BREAK_TESTS) +OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { + const char *const value = getenv("BORINGSSL_FIPS_BREAK_TEST"); + return value != NULL && strcmp(value, test) == 0; +} +#else +OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { + return 0; +} +#endif // BORINGSSL_FIPS_BREAK_TESTS + + +// Runtime CPU feature support + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or +// x86-64 system. +// +// Index 0: +// EDX for CPUID where EAX = 1 +// Bit 20 is always zero +// Bit 28 is adjusted to reflect whether the data cache is shared between +// multiple logical cores +// Bit 30 is used to indicate an Intel CPU +// Index 1: +// ECX for CPUID where EAX = 1 +// Bit 11 is used to indicate AMD XOP support, not SDBG +// Index 2: +// EBX for CPUID where EAX = 7 +// Index 3: +// ECX for CPUID where EAX = 7 +// +// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM +// bits in XCR0, so it is not necessary to check those. +extern uint32_t OPENSSL_ia32cap_P[4]; + +#if defined(BORINGSSL_FIPS) && !defined(BORINGSSL_SHARED_LIBRARY) +// The FIPS module, as a static library, requires an out-of-line version of +// |OPENSSL_ia32cap_get| so accesses can be rewritten by delocate. Mark the +// function const so multiple accesses can be optimized together. +const uint32_t *OPENSSL_ia32cap_get(void) __attribute__((const)); +#else +OPENSSL_INLINE const uint32_t *OPENSSL_ia32cap_get(void) { + return OPENSSL_ia32cap_P; +} +#endif + +// See Intel manual, volume 2A, table 3-11. + +OPENSSL_INLINE int CRYPTO_is_FXSR_capable(void) { +#if defined(__FXSR__) + return 1; +#else + return (OPENSSL_ia32cap_get()[0] & (1 << 24)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_intel_cpu(void) { + // The reserved bit 30 is used to indicate an Intel CPU. + return (OPENSSL_ia32cap_get()[0] & (1 << 30)) != 0; +} + +// See Intel manual, volume 2A, table 3-10. + +OPENSSL_INLINE int CRYPTO_is_PCLMUL_capable(void) { +#if defined(__PCLMUL__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 1)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_SSSE3_capable(void) { +#if defined(__SSSE3__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 9)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_SSE4_1_capable(void) { +#if defined(__SSE4_1__) + return 1; +#else + return (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_MOVBE_capable(void) { +#if defined(__MOVBE__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 22)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AESNI_capable(void) { +#if defined(__AES__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 25)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AVX_capable(void) { +#if defined(__AVX__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 28)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_RDRAND_capable(void) { + // The GCC/Clang feature name and preprocessor symbol for RDRAND are "rdrnd" + // and |__RDRND__|, respectively. +#if defined(__RDRND__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0; +#endif +} + +// See Intel manual, volume 2A, table 3-8. + +OPENSSL_INLINE int CRYPTO_is_BMI1_capable(void) { +#if defined(__BMI1__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 3)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AVX2_capable(void) { +#if defined(__AVX2__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 5)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_BMI2_capable(void) { +#if defined(__BMI2__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 8)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ADX_capable(void) { +#if defined(__ADX__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 19)) != 0; +#endif +} + +#endif // OPENSSL_X86 || OPENSSL_X86_64 + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#if defined(OPENSSL_APPLE) && defined(OPENSSL_ARM) +// We do not detect any features at runtime for Apple's 32-bit ARM platforms. On +// 64-bit ARM, we detect some post-ARMv8.0 features. +#define OPENSSL_STATIC_ARMCAP +#endif + +// Normalize some older feature flags to their modern ACLE values. +// https://developer.arm.com/architectures/system-architectures/software-standards/acle +#if defined(__ARM_NEON__) && !defined(__ARM_NEON) +#define __ARM_NEON 1 +#endif +#if defined(__ARM_FEATURE_CRYPTO) +#if !defined(__ARM_FEATURE_AES) +#define __ARM_FEATURE_AES 1 +#endif +#if !defined(__ARM_FEATURE_SHA2) +#define __ARM_FEATURE_SHA2 1 +#endif +#endif + +#if !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON +// unit. Note that |OPENSSL_armcap_P| also exists and contains the same +// information in a form that's easier for assembly to use. +OPENSSL_EXPORT int CRYPTO_is_NEON_capable_at_runtime(void); + +// CRYPTO_is_ARMv8_AES_capable_at_runtime returns true if the current CPU +// supports the ARMv8 AES instruction. +int CRYPTO_is_ARMv8_AES_capable_at_runtime(void); + +// CRYPTO_is_ARMv8_PMULL_capable_at_runtime returns true if the current CPU +// supports the ARMv8 PMULL instruction. +int CRYPTO_is_ARMv8_PMULL_capable_at_runtime(void); +#endif // !OPENSSL_STATIC_ARMCAP + +// CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If +// this is known statically, it is a constant inline function. +OPENSSL_INLINE int CRYPTO_is_NEON_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_NEON_capable_at_runtime(); +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ARMv8_AES_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_AES) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_ARMv8_AES_capable_at_runtime(); +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ARMv8_PMULL_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_AES) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_ARMv8_PMULL_capable_at_runtime(); +#endif +} + +#endif // OPENSSL_ARM || OPENSSL_AARCH64 + +#if defined(OPENSSL_PPC64LE) + +// CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports +// the Vector.AES category of instructions. +int CRYPTO_is_PPC64LE_vcrypto_capable(void); + +extern unsigned long OPENSSL_ppc64le_hwcap2; + +#endif // OPENSSL_PPC64LE + +#if defined(BORINGSSL_DISPATCH_TEST) +// Runtime CPU dispatch testing support + +// BORINGSSL_function_hit is an array of flags. The following functions will +// set these flags if BORINGSSL_DISPATCH_TEST is defined. +// 0: aes_hw_ctr32_encrypt_blocks +// 1: aes_hw_encrypt +// 2: aesni_gcm_encrypt +// 3: aes_hw_set_encrypt_key +// 4: vpaes_encrypt +// 5: vpaes_set_encrypt_key +extern uint8_t BORINGSSL_function_hit[7]; +#endif // BORINGSSL_DISPATCH_TEST + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/internal.h new file mode 100644 index 00000000..88334c6c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/internal.h @@ -0,0 +1,253 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_LHASH_INTERNAL_H +#define OPENSSL_HEADER_LHASH_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// lhash is a traditional, chaining hash table that automatically expands and +// contracts as needed. One should not use the lh_* functions directly, rather +// use the type-safe macro wrappers: +// +// A hash table of a specific type of object has type |LHASH_OF(type)|. This +// can be defined (once) with |DEFINE_LHASH_OF(type)| and declared where needed +// with |DECLARE_LHASH_OF(type)|. For example: +// +// struct foo { +// int bar; +// }; +// +// DEFINE_LHASH_OF(struct foo) +// +// Although note that the hash table will contain /pointers/ to |foo|. +// +// A macro will be defined for each of the |OPENSSL_lh_*| functions below. For +// |LHASH_OF(foo)|, the macros would be |lh_foo_new|, |lh_foo_num_items| etc. + + +// lhash_cmp_func is a comparison function that returns a value equal, or not +// equal, to zero depending on whether |*a| is equal, or not equal to |*b|, +// respectively. Note the difference between this and |stack_cmp_func| in that +// this takes pointers to the objects directly. +// +// This function's actual type signature is int (*)(const T*, const T*). The +// low-level |lh_*| functions will be passed a type-specific wrapper to call it +// correctly. +typedef int (*lhash_cmp_func)(const void *a, const void *b); +typedef int (*lhash_cmp_func_helper)(lhash_cmp_func func, const void *a, + const void *b); + +// lhash_hash_func is a function that maps an object to a uniformly distributed +// uint32_t. +// +// This function's actual type signature is uint32_t (*)(const T*). The +// low-level |lh_*| functions will be passed a type-specific wrapper to call it +// correctly. +typedef uint32_t (*lhash_hash_func)(const void *a); +typedef uint32_t (*lhash_hash_func_helper)(lhash_hash_func func, const void *a); + +typedef struct lhash_st _LHASH; + +// OPENSSL_lh_new returns a new, empty hash table or NULL on error. +OPENSSL_EXPORT _LHASH *OPENSSL_lh_new(lhash_hash_func hash, + lhash_cmp_func comp); + +// OPENSSL_lh_free frees the hash table itself but none of the elements. See +// |OPENSSL_lh_doall|. +OPENSSL_EXPORT void OPENSSL_lh_free(_LHASH *lh); + +// OPENSSL_lh_num_items returns the number of items in |lh|. +OPENSSL_EXPORT size_t OPENSSL_lh_num_items(const _LHASH *lh); + +// OPENSSL_lh_retrieve finds an element equal to |data| in the hash table and +// returns it. If no such element exists, it returns NULL. +OPENSSL_EXPORT void *OPENSSL_lh_retrieve(const _LHASH *lh, const void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func); + +// OPENSSL_lh_retrieve_key finds an element matching |key|, given the specified +// hash and comparison function. This differs from |OPENSSL_lh_retrieve| in that +// the key may be a different type than the values stored in |lh|. |key_hash| +// and |cmp_key| must be compatible with the functions passed into +// |OPENSSL_lh_new|. +OPENSSL_EXPORT void *OPENSSL_lh_retrieve_key(const _LHASH *lh, const void *key, + uint32_t key_hash, + int (*cmp_key)(const void *key, + const void *value)); + +// OPENSSL_lh_insert inserts |data| into the hash table. If an existing element +// is equal to |data| (with respect to the comparison function) then |*old_data| +// will be set to that value and it will be replaced. Otherwise, or in the +// event of an error, |*old_data| will be set to NULL. It returns one on +// success or zero in the case of an allocation error. +OPENSSL_EXPORT int OPENSSL_lh_insert(_LHASH *lh, void **old_data, void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func); + +// OPENSSL_lh_delete removes an element equal to |data| from the hash table and +// returns it. If no such element is found, it returns NULL. +OPENSSL_EXPORT void *OPENSSL_lh_delete(_LHASH *lh, const void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func); + +// OPENSSL_lh_doall_arg calls |func| on each element of the hash table and also +// passes |arg| as the second argument. +// TODO(fork): rename this +OPENSSL_EXPORT void OPENSSL_lh_doall_arg(_LHASH *lh, + void (*func)(void *, void *), + void *arg); + +#define DEFINE_LHASH_OF(type) \ + DECLARE_LHASH_OF(type) \ + \ + typedef int (*lhash_##type##_cmp_func)(const type *, const type *); \ + typedef uint32_t (*lhash_##type##_hash_func)(const type *); \ + \ + OPENSSL_INLINE int lh_##type##_call_cmp_func(lhash_cmp_func func, \ + const void *a, const void *b) { \ + return ((lhash_##type##_cmp_func)func)((const type *)a, (const type *)b); \ + } \ + \ + OPENSSL_INLINE uint32_t lh_##type##_call_hash_func(lhash_hash_func func, \ + const void *a) { \ + return ((lhash_##type##_hash_func)func)((const type *)a); \ + } \ + \ + OPENSSL_INLINE LHASH_OF(type) *lh_##type##_new( \ + lhash_##type##_hash_func hash, lhash_##type##_cmp_func comp) { \ + return (LHASH_OF(type) *)OPENSSL_lh_new((lhash_hash_func)hash, \ + (lhash_cmp_func)comp); \ + } \ + \ + OPENSSL_INLINE void lh_##type##_free(LHASH_OF(type) *lh) { \ + OPENSSL_lh_free((_LHASH *)lh); \ + } \ + \ + OPENSSL_INLINE size_t lh_##type##_num_items(const LHASH_OF(type) *lh) { \ + return OPENSSL_lh_num_items((const _LHASH *)lh); \ + } \ + \ + OPENSSL_INLINE type *lh_##type##_retrieve(const LHASH_OF(type) *lh, \ + const type *data) { \ + return (type *)OPENSSL_lh_retrieve((const _LHASH *)lh, data, \ + lh_##type##_call_hash_func, \ + lh_##type##_call_cmp_func); \ + } \ + \ + typedef struct { \ + int (*cmp_key)(const void *key, const type *value); \ + const void *key; \ + } LHASH_CMP_KEY_##type; \ + \ + OPENSSL_INLINE int lh_##type##_call_cmp_key(const void *key, \ + const void *value) { \ + const LHASH_CMP_KEY_##type *cb = (const LHASH_CMP_KEY_##type *)key; \ + return cb->cmp_key(cb->key, (const type *)value); \ + } \ + \ + OPENSSL_INLINE type *lh_##type##_retrieve_key( \ + const LHASH_OF(type) *lh, const void *key, uint32_t key_hash, \ + int (*cmp_key)(const void *key, const type *value)) { \ + LHASH_CMP_KEY_##type cb = {cmp_key, key}; \ + return (type *)OPENSSL_lh_retrieve_key((const _LHASH *)lh, &cb, key_hash, \ + lh_##type##_call_cmp_key); \ + } \ + \ + OPENSSL_INLINE int lh_##type##_insert(LHASH_OF(type) *lh, type **old_data, \ + type *data) { \ + void *old_data_void = NULL; \ + int ret = OPENSSL_lh_insert((_LHASH *)lh, &old_data_void, data, \ + lh_##type##_call_hash_func, \ + lh_##type##_call_cmp_func); \ + *old_data = (type *)old_data_void; \ + return ret; \ + } \ + \ + OPENSSL_INLINE type *lh_##type##_delete(LHASH_OF(type) *lh, \ + const type *data) { \ + return (type *)OPENSSL_lh_delete((_LHASH *)lh, data, \ + lh_##type##_call_hash_func, \ + lh_##type##_call_cmp_func); \ + } \ + \ + typedef struct { \ + void (*doall_arg)(type *, void *); \ + void *arg; \ + } LHASH_DOALL_##type; \ + \ + OPENSSL_INLINE void lh_##type##_call_doall_arg(void *value, void *arg) { \ + const LHASH_DOALL_##type *cb = (const LHASH_DOALL_##type *)arg; \ + cb->doall_arg((type *)value, cb->arg); \ + } \ + \ + OPENSSL_INLINE void lh_##type##_doall_arg( \ + LHASH_OF(type) *lh, void (*func)(type *, void *), void *arg) { \ + LHASH_DOALL_##type cb = {func, arg}; \ + OPENSSL_lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall_arg, &cb); \ + } + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_LHASH_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/lhash.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/lhash.c new file mode 100644 index 00000000..8b696579 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/lhash/lhash.c @@ -0,0 +1,353 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +// kMinNumBuckets is the minimum size of the buckets array in an |_LHASH|. +static const size_t kMinNumBuckets = 16; + +// kMaxAverageChainLength contains the maximum, average chain length. When the +// average chain length exceeds this value, the hash table will be resized. +static const size_t kMaxAverageChainLength = 2; +static const size_t kMinAverageChainLength = 1; + +// lhash_item_st is an element of a hash chain. It points to the opaque data +// for this element and to the next item in the chain. The linked-list is NULL +// terminated. +typedef struct lhash_item_st { + void *data; + struct lhash_item_st *next; + // hash contains the cached, hash value of |data|. + uint32_t hash; +} LHASH_ITEM; + +struct lhash_st { + // num_items contains the total number of items in the hash table. + size_t num_items; + // buckets is an array of |num_buckets| pointers. Each points to the head of + // a chain of LHASH_ITEM objects that have the same hash value, mod + // |num_buckets|. + LHASH_ITEM **buckets; + // num_buckets contains the length of |buckets|. This value is always >= + // kMinNumBuckets. + size_t num_buckets; + // callback_depth contains the current depth of |lh_doall| or |lh_doall_arg| + // calls. If non-zero then this suppresses resizing of the |buckets| array, + // which would otherwise disrupt the iteration. + unsigned callback_depth; + + lhash_cmp_func comp; + lhash_hash_func hash; +}; + +_LHASH *OPENSSL_lh_new(lhash_hash_func hash, lhash_cmp_func comp) { + _LHASH *ret = OPENSSL_malloc(sizeof(_LHASH)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(_LHASH)); + + ret->num_buckets = kMinNumBuckets; + ret->buckets = OPENSSL_malloc(sizeof(LHASH_ITEM *) * ret->num_buckets); + if (ret->buckets == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->buckets, 0, sizeof(LHASH_ITEM *) * ret->num_buckets); + + ret->comp = comp; + ret->hash = hash; + return ret; +} + +void OPENSSL_lh_free(_LHASH *lh) { + if (lh == NULL) { + return; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *n = lh->buckets[i]; n != NULL; n = next) { + next = n->next; + OPENSSL_free(n); + } + } + + OPENSSL_free(lh->buckets); + OPENSSL_free(lh); +} + +size_t OPENSSL_lh_num_items(const _LHASH *lh) { return lh->num_items; } + +// get_next_ptr_and_hash returns a pointer to the pointer that points to the +// item equal to |data|. In other words, it searches for an item equal to |data| +// and, if it's at the start of a chain, then it returns a pointer to an +// element of |lh->buckets|, otherwise it returns a pointer to the |next| +// element of the previous item in the chain. If an element equal to |data| is +// not found, it returns a pointer that points to a NULL pointer. If |out_hash| +// is not NULL, then it also puts the hash value of |data| in |*out_hash|. +static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash, + const void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func) { + const uint32_t hash = call_hash_func(lh->hash, data); + if (out_hash != NULL) { + *out_hash = hash; + } + + LHASH_ITEM **ret = &lh->buckets[hash % lh->num_buckets]; + for (LHASH_ITEM *cur = *ret; cur != NULL; cur = *ret) { + if (call_cmp_func(lh->comp, cur->data, data) == 0) { + break; + } + ret = &cur->next; + } + + return ret; +} + +// get_next_ptr_by_key behaves like |get_next_ptr_and_hash| but takes a key +// which may be a different type from the values stored in |lh|. +static LHASH_ITEM **get_next_ptr_by_key(const _LHASH *lh, const void *key, + uint32_t key_hash, + int (*cmp_key)(const void *key, + const void *value)) { + LHASH_ITEM **ret = &lh->buckets[key_hash % lh->num_buckets]; + for (LHASH_ITEM *cur = *ret; cur != NULL; cur = *ret) { + if (cmp_key(key, cur->data) == 0) { + break; + } + ret = &cur->next; + } + + return ret; +} + +void *OPENSSL_lh_retrieve(const _LHASH *lh, const void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func) { + LHASH_ITEM **next_ptr = + get_next_ptr_and_hash(lh, NULL, data, call_hash_func, call_cmp_func); + return *next_ptr == NULL ? NULL : (*next_ptr)->data; +} + +void *OPENSSL_lh_retrieve_key(const _LHASH *lh, const void *key, + uint32_t key_hash, + int (*cmp_key)(const void *key, + const void *value)) { + LHASH_ITEM **next_ptr = get_next_ptr_by_key(lh, key, key_hash, cmp_key); + return *next_ptr == NULL ? NULL : (*next_ptr)->data; +} + +// lh_rebucket allocates a new array of |new_num_buckets| pointers and +// redistributes the existing items into it before making it |lh->buckets| and +// freeing the old array. +static void lh_rebucket(_LHASH *lh, const size_t new_num_buckets) { + LHASH_ITEM **new_buckets, *cur, *next; + size_t i, alloc_size; + + alloc_size = sizeof(LHASH_ITEM *) * new_num_buckets; + if (alloc_size / sizeof(LHASH_ITEM*) != new_num_buckets) { + return; + } + + new_buckets = OPENSSL_malloc(alloc_size); + if (new_buckets == NULL) { + return; + } + OPENSSL_memset(new_buckets, 0, alloc_size); + + for (i = 0; i < lh->num_buckets; i++) { + for (cur = lh->buckets[i]; cur != NULL; cur = next) { + const size_t new_bucket = cur->hash % new_num_buckets; + next = cur->next; + cur->next = new_buckets[new_bucket]; + new_buckets[new_bucket] = cur; + } + } + + OPENSSL_free(lh->buckets); + + lh->num_buckets = new_num_buckets; + lh->buckets = new_buckets; +} + +// lh_maybe_resize resizes the |buckets| array if needed. +static void lh_maybe_resize(_LHASH *lh) { + size_t avg_chain_length; + + if (lh->callback_depth > 0) { + // Don't resize the hash if we are currently iterating over it. + return; + } + + assert(lh->num_buckets >= kMinNumBuckets); + avg_chain_length = lh->num_items / lh->num_buckets; + + if (avg_chain_length > kMaxAverageChainLength) { + const size_t new_num_buckets = lh->num_buckets * 2; + + if (new_num_buckets > lh->num_buckets) { + lh_rebucket(lh, new_num_buckets); + } + } else if (avg_chain_length < kMinAverageChainLength && + lh->num_buckets > kMinNumBuckets) { + size_t new_num_buckets = lh->num_buckets / 2; + + if (new_num_buckets < kMinNumBuckets) { + new_num_buckets = kMinNumBuckets; + } + + lh_rebucket(lh, new_num_buckets); + } +} + +int OPENSSL_lh_insert(_LHASH *lh, void **old_data, void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func) { + uint32_t hash; + LHASH_ITEM **next_ptr, *item; + + *old_data = NULL; + next_ptr = + get_next_ptr_and_hash(lh, &hash, data, call_hash_func, call_cmp_func); + + + if (*next_ptr != NULL) { + // An element equal to |data| already exists in the hash table. It will be + // replaced. + *old_data = (*next_ptr)->data; + (*next_ptr)->data = data; + return 1; + } + + // An element equal to |data| doesn't exist in the hash table yet. + item = OPENSSL_malloc(sizeof(LHASH_ITEM)); + if (item == NULL) { + return 0; + } + + item->data = data; + item->hash = hash; + item->next = NULL; + *next_ptr = item; + lh->num_items++; + lh_maybe_resize(lh); + + return 1; +} + +void *OPENSSL_lh_delete(_LHASH *lh, const void *data, + lhash_hash_func_helper call_hash_func, + lhash_cmp_func_helper call_cmp_func) { + LHASH_ITEM **next_ptr, *item, *ret; + + next_ptr = + get_next_ptr_and_hash(lh, NULL, data, call_hash_func, call_cmp_func); + + if (*next_ptr == NULL) { + // No such element. + return NULL; + } + + item = *next_ptr; + *next_ptr = item->next; + ret = item->data; + OPENSSL_free(item); + + lh->num_items--; + lh_maybe_resize(lh); + + return ret; +} + +void OPENSSL_lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) { + if (lh == NULL) { + return; + } + + if (lh->callback_depth < UINT_MAX) { + // |callback_depth| is a saturating counter. + lh->callback_depth++; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *cur = lh->buckets[i]; cur != NULL; cur = next) { + next = cur->next; + func(cur->data, arg); + } + } + + if (lh->callback_depth < UINT_MAX) { + lh->callback_depth--; + } + + // The callback may have added or removed elements and the non-zero value of + // |callback_depth| will have suppressed any resizing. Thus any needed + // resizing is done here. + lh_maybe_resize(lh); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/mem.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/mem.c new file mode 100644 index 00000000..b7e51a88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/mem.c @@ -0,0 +1,416 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +#define OPENSSL_MALLOC_PREFIX 8 +OPENSSL_STATIC_ASSERT(OPENSSL_MALLOC_PREFIX >= sizeof(size_t), + "size_t too large"); + +#if defined(OPENSSL_ASAN) +void __asan_poison_memory_region(const volatile void *addr, size_t size); +void __asan_unpoison_memory_region(const volatile void *addr, size_t size); +#else +static void __asan_poison_memory_region(const void *addr, size_t size) {} +static void __asan_unpoison_memory_region(const void *addr, size_t size) {} +#endif + +// Windows doesn't really support weak symbols as of May 2019, and Clang on +// Windows will emit strong symbols instead. See +// https://bugs.llvm.org/show_bug.cgi?id=37598 +#if defined(__ELF__) && defined(__GNUC__) +#define WEAK_SYMBOL_FUNC(rettype, name, args) \ + rettype name args __attribute__((weak)); +#else +#define WEAK_SYMBOL_FUNC(rettype, name, args) static rettype(*name) args = NULL; +#endif + +// sdallocx is a sized |free| function. By passing the size (which we happen to +// always know in BoringSSL), the malloc implementation can save work. We cannot +// depend on |sdallocx| being available, however, so it's a weak symbol. +// +// This will always be safe, but will only be overridden if the malloc +// implementation is statically linked with BoringSSL. So, if |sdallocx| is +// provided in, say, libc.so, we still won't use it because that's dynamically +// linked. This isn't an ideal result, but its helps in some cases. +WEAK_SYMBOL_FUNC(void, sdallocx, (void *ptr, size_t size, int flags)); + +// The following three functions can be defined to override default heap +// allocation and freeing. If defined, it is the responsibility of +// |OPENSSL_memory_free| to zero out the memory before returning it to the +// system. |OPENSSL_memory_free| will not be passed NULL pointers. +// +// WARNING: These functions are called on every allocation and free in +// BoringSSL across the entire process. They may be called by any code in the +// process which calls BoringSSL, including in process initializers and thread +// destructors. When called, BoringSSL may hold pthreads locks. Any other code +// in the process which, directly or indirectly, calls BoringSSL may be on the +// call stack and may itself be using arbitrary synchronization primitives. +// +// As a result, these functions may not have the usual programming environment +// available to most C or C++ code. In particular, they may not call into +// BoringSSL, or any library which depends on BoringSSL. Any synchronization +// primitives used must tolerate every other synchronization primitive linked +// into the process, including pthreads locks. Failing to meet these constraints +// may result in deadlocks, crashes, or memory corruption. +WEAK_SYMBOL_FUNC(void*, OPENSSL_memory_alloc, (size_t size)); +WEAK_SYMBOL_FUNC(void, OPENSSL_memory_free, (void *ptr)); +WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr)); + +// kBoringSSLBinaryTag is a distinctive byte sequence to identify binaries that +// are linking in BoringSSL and, roughly, what version they are using. +static const uint8_t kBoringSSLBinaryTag[18] = { + // 16 bytes of magic tag. + 0x8c, 0x62, 0x20, 0x0b, 0xd2, 0xa0, 0x72, 0x58, + 0x44, 0xa8, 0x96, 0x69, 0xad, 0x55, 0x7e, 0xec, + // Current source iteration. Incremented ~monthly. + 3, 0, +}; + +void *OPENSSL_malloc(size_t size) { + if (OPENSSL_memory_alloc != NULL) { + assert(OPENSSL_memory_free != NULL); + assert(OPENSSL_memory_get_size != NULL); + return OPENSSL_memory_alloc(size); + } + + if (size + OPENSSL_MALLOC_PREFIX < size) { + // |OPENSSL_malloc| is a central function in BoringSSL thus a reference to + // |kBoringSSLBinaryTag| is created here so that the tag isn't discarded by + // the linker. The following is sufficient to stop GCC, Clang, and MSVC + // optimising away the reference at the time of writing. Since this + // probably results in an actual memory reference, it is put in this very + // rare code path. + uint8_t unused = *(volatile uint8_t *)kBoringSSLBinaryTag; + (void) unused; + return NULL; + } + + void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); + if (ptr == NULL) { + return NULL; + } + + *(size_t *)ptr = size; + + __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); + return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; +} + +void OPENSSL_free(void *orig_ptr) { + if (orig_ptr == NULL) { + return; + } + + if (OPENSSL_memory_free != NULL) { + OPENSSL_memory_free(orig_ptr); + return; + } + + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); + + size_t size = *(size_t *)ptr; + OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); + +// ASan knows to intercept malloc and free, but not sdallocx. +#if defined(OPENSSL_ASAN) + free(ptr); +#else + if (sdallocx) { + sdallocx(ptr, size + OPENSSL_MALLOC_PREFIX, 0 /* flags */); + } else { + free(ptr); + } +#endif +} + +void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { + if (orig_ptr == NULL) { + return OPENSSL_malloc(new_size); + } + + size_t old_size; + if (OPENSSL_memory_get_size != NULL) { + old_size = OPENSSL_memory_get_size(orig_ptr); + } else { + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); + old_size = *(size_t *)ptr; + __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); + } + + void *ret = OPENSSL_malloc(new_size); + if (ret == NULL) { + return NULL; + } + + size_t to_copy = new_size; + if (old_size < to_copy) { + to_copy = old_size; + } + + memcpy(ret, orig_ptr, to_copy); + OPENSSL_free(orig_ptr); + + return ret; +} + +void OPENSSL_cleanse(void *ptr, size_t len) { +#if defined(OPENSSL_WINDOWS) + SecureZeroMemory(ptr, len); +#else + OPENSSL_memset(ptr, 0, len); + +#if !defined(OPENSSL_NO_ASM) + /* As best as we can tell, this is sufficient to break any optimisations that + might try to eliminate "superfluous" memsets. If there's an easy way to + detect memset_s, it would be better to use that. */ + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#endif +#endif // !OPENSSL_NO_ASM +} + +void OPENSSL_clear_free(void *ptr, size_t unused) { + OPENSSL_free(ptr); +} + +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { + const uint8_t *a = in_a; + const uint8_t *b = in_b; + uint8_t x = 0; + + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + + return x; +} + +uint32_t OPENSSL_hash32(const void *ptr, size_t len) { + // These are the FNV-1a parameters for 32 bits. + static const uint32_t kPrime = 16777619u; + static const uint32_t kOffsetBasis = 2166136261u; + + const uint8_t *in = ptr; + uint32_t h = kOffsetBasis; + + for (size_t i = 0; i < len; i++) { + h ^= in[i]; + h *= kPrime; + } + + return h; +} + +uint32_t OPENSSL_strhash(const char *s) { return OPENSSL_hash32(s, strlen(s)); } + +size_t OPENSSL_strnlen(const char *s, size_t len) { + for (size_t i = 0; i < len; i++) { + if (s[i] == 0) { + return i; + } + } + + return len; +} + +char *OPENSSL_strdup(const char *s) { + if (s == NULL) { + return NULL; + } + const size_t len = strlen(s) + 1; + char *ret = OPENSSL_malloc(len); + if (ret == NULL) { + return NULL; + } + OPENSSL_memcpy(ret, s, len); + return ret; +} + +int OPENSSL_tolower(int c) { + if (c >= 'A' && c <= 'Z') { + return c + ('a' - 'A'); + } + return c; +} + +int OPENSSL_strcasecmp(const char *a, const char *b) { + for (size_t i = 0;; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } +} + +int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) { + for (size_t i = 0; i < n; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } + + return 0; +} + +int BIO_snprintf(char *buf, size_t n, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = BIO_vsnprintf(buf, n, format, args); + va_end(args); + return ret; +} + +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) { + return vsnprintf(buf, n, format, args); +} + +char *OPENSSL_strndup(const char *str, size_t size) { + size = OPENSSL_strnlen(str, size); + + size_t alloc_size = size + 1; + if (alloc_size < size) { + // overflow + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + char *ret = OPENSSL_malloc(alloc_size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, str, size); + ret[size] = '\0'; + return ret; +} + +size_t OPENSSL_strlcpy(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + + for (; dst_size > 1 && *src; dst_size--) { + *dst++ = *src++; + l++; + } + + if (dst_size) { + *dst = 0; + } + + return l + strlen(src); +} + +size_t OPENSSL_strlcat(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + for (; dst_size > 0 && *dst; dst_size--, dst++) { + l++; + } + return l + OPENSSL_strlcpy(dst, src, dst_size); +} + +void *OPENSSL_memdup(const void *data, size_t size) { + if (size == 0) { + return NULL; + } + + void *ret = OPENSSL_malloc(size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, data, size); + return ret; +} + +void *CRYPTO_malloc(size_t size, const char *file, int line) { + return OPENSSL_malloc(size); +} + +void *CRYPTO_realloc(void *ptr, size_t new_size, const char *file, int line) { + return OPENSSL_realloc(ptr, new_size); +} + +void CRYPTO_free(void *ptr, const char *file, int line) { OPENSSL_free(ptr); } diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj.c new file mode 100644 index 00000000..384b00f6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj.c @@ -0,0 +1,553 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../asn1/internal.h" +#include "../internal.h" +#include "../lhash/internal.h" + +// obj_data.h must be included after the definition of |ASN1_OBJECT|. +#include "obj_dat.h" + + +DEFINE_LHASH_OF(ASN1_OBJECT) + +static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT; +// These globals are protected by |global_added_lock|. +static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL; + +static struct CRYPTO_STATIC_MUTEX global_next_nid_lock = + CRYPTO_STATIC_MUTEX_INIT; +static unsigned global_next_nid = NUM_NID; + +static int obj_next_nid(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock); + ret = global_next_nid++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock); + + return ret; +} + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { + ASN1_OBJECT *r; + unsigned char *data = NULL; + char *sn = NULL, *ln = NULL; + + if (o == NULL) { + return NULL; + } + + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + // TODO(fork): this is a little dangerous. + return (ASN1_OBJECT *)o; + } + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB); + return NULL; + } + r->ln = r->sn = NULL; + + data = OPENSSL_malloc(o->length); + if (data == NULL) { + goto err; + } + if (o->data != NULL) { + OPENSSL_memcpy(data, o->data, o->length); + } + + // once data is attached to an object, it remains const + r->data = data; + r->length = o->length; + r->nid = o->nid; + + if (o->ln != NULL) { + ln = OPENSSL_strdup(o->ln); + if (ln == NULL) { + goto err; + } + } + + if (o->sn != NULL) { + sn = OPENSSL_strdup(o->sn); + if (sn == NULL) { + goto err; + } + } + + r->sn = sn; + r->ln = ln; + + r->flags = + o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return r; + +err: + OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ln); + OPENSSL_free(sn); + OPENSSL_free(data); + OPENSSL_free(r); + return NULL; +} + +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + int ret; + + ret = a->length - b->length; + if (ret) { + return ret; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj) { + if (obj == NULL) { + return NULL; + } + + return obj->data; +} + +size_t OBJ_length(const ASN1_OBJECT *obj) { + if (obj == NULL || obj->length < 0) { + return 0; + } + + return (size_t)obj->length; +} + +// obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is +// an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an +// unsigned int in the array. +static int obj_cmp(const void *key, const void *element) { + uint16_t nid = *((const uint16_t *)element); + const ASN1_OBJECT *a = key; + const ASN1_OBJECT *b = &kObjects[nid]; + + if (a->length < b->length) { + return -1; + } else if (a->length > b->length) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +int OBJ_obj2nid(const ASN1_OBJECT *obj) { + if (obj == NULL) { + return NID_undef; + } + + if (obj->nid != 0) { + return obj->nid; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_data != NULL) { + ASN1_OBJECT *match; + + match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + const uint16_t *nid_ptr = + bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), + sizeof(kNIDsInOIDOrder[0]), obj_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_cbs2nid(const CBS *cbs) { + if (CBS_len(cbs) > INT_MAX) { + return NID_undef; + } + + ASN1_OBJECT obj; + OPENSSL_memset(&obj, 0, sizeof(obj)); + obj.data = CBS_data(cbs); + obj.length = (int)CBS_len(cbs); + + return OBJ_obj2nid(&obj); +} + +// short_name_cmp is called to search the kNIDsInShortNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int short_name_cmp(const void *key, const void *element) { + const char *name = (const char *)key; + uint16_t nid = *((const uint16_t *)element); + + return strcmp(name, kObjects[nid].sn); +} + +int OBJ_sn2nid(const char *short_name) { + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_short_name != NULL) { + ASN1_OBJECT *match, template; + + template.sn = short_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + const uint16_t *nid_ptr = + bsearch(short_name, kNIDsInShortNameOrder, + OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder), + sizeof(kNIDsInShortNameOrder[0]), short_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +// long_name_cmp is called to search the kNIDsInLongNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int long_name_cmp(const void *key, const void *element) { + const char *name = (const char *)key; + uint16_t nid = *((const uint16_t *)element); + + return strcmp(name, kObjects[nid].ln); +} + +int OBJ_ln2nid(const char *long_name) { + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_long_name != NULL) { + ASN1_OBJECT *match, template; + + template.ln = long_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + const uint16_t *nid_ptr = bsearch( + long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), + sizeof(kNIDsInLongNameOrder[0]), long_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_txt2nid(const char *s) { + ASN1_OBJECT *obj; + int nid; + + obj = OBJ_txt2obj(s, 0 /* search names */); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} + +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + CBB oid; + + if (obj == NULL || + !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, obj->data, obj->length) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +ASN1_OBJECT *OBJ_nid2obj(int nid) { + if (nid >= 0 && nid < NUM_NID) { + if (nid != NID_undef && kObjects[nid].nid == NID_undef) { + goto err; + } + return (ASN1_OBJECT *)&kObjects[nid]; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_nid != NULL) { + ASN1_OBJECT *match, template; + + template.nid = nid; + match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + +err: + OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID); + return NULL; +} + +const char *OBJ_nid2sn(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->sn; +} + +const char *OBJ_nid2ln(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->ln; +} + +static ASN1_OBJECT *create_object_with_text_oid(int (*get_nid)(void), + const char *oid, + const char *short_name, + const char *long_name) { + uint8_t *buf; + size_t len; + CBB cbb; + if (!CBB_init(&cbb, 32) || + !CBB_add_asn1_oid_from_text(&cbb, oid, strlen(oid)) || + !CBB_finish(&cbb, &buf, &len)) { + OPENSSL_PUT_ERROR(OBJ, OBJ_R_INVALID_OID_STRING); + CBB_cleanup(&cbb); + return NULL; + } + + ASN1_OBJECT *ret = ASN1_OBJECT_create(get_nid ? get_nid() : NID_undef, buf, + len, short_name, long_name); + OPENSSL_free(buf); + return ret; +} + +ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) { + if (!dont_search_names) { + int nid = OBJ_sn2nid(s); + if (nid == NID_undef) { + nid = OBJ_ln2nid(s); + } + + if (nid != NID_undef) { + return OBJ_nid2obj(nid); + } + } + + return create_object_with_text_oid(NULL, s, NULL, NULL); +} + +static int strlcpy_int(char *dst, const char *src, int dst_size) { + size_t ret = OPENSSL_strlcpy(dst, src, dst_size < 0 ? 0 : (size_t)dst_size); + if (ret > INT_MAX) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_OVERFLOW); + return -1; + } + return (int)ret; +} + +int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid) { + // Python depends on the empty OID successfully encoding as the empty + // string. + if (obj == NULL || obj->length == 0) { + return strlcpy_int(out, "", out_len); + } + + if (!always_return_oid) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) { + const char *name = OBJ_nid2ln(nid); + if (name == NULL) { + name = OBJ_nid2sn(nid); + } + if (name != NULL) { + return strlcpy_int(out, name, out_len); + } + } + } + + CBS cbs; + CBS_init(&cbs, obj->data, obj->length); + char *txt = CBS_asn1_oid_to_text(&cbs); + if (txt == NULL) { + if (out_len > 0) { + out[0] = '\0'; + } + return -1; + } + + int ret = strlcpy_int(out, txt, out_len); + OPENSSL_free(txt); + return ret; +} + +static uint32_t hash_nid(const ASN1_OBJECT *obj) { + return obj->nid; +} + +static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return a->nid - b->nid; +} + +static uint32_t hash_data(const ASN1_OBJECT *obj) { + return OPENSSL_hash32(obj->data, obj->length); +} + +static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + int i = a->length - b->length; + if (i) { + return i; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +static uint32_t hash_short_name(const ASN1_OBJECT *obj) { + return OPENSSL_strhash(obj->sn); +} + +static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->sn, b->sn); +} + +static uint32_t hash_long_name(const ASN1_OBJECT *obj) { + return OPENSSL_strhash(obj->ln); +} + +static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->ln, b->ln); +} + +// obj_add_object inserts |obj| into the various global hashes for run-time +// added objects. It returns one on success or zero otherwise. +static int obj_add_object(ASN1_OBJECT *obj) { + int ok; + ASN1_OBJECT *old_object; + + obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock); + if (global_added_by_nid == NULL) { + global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); + global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); + global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); + } + + // We don't pay attention to |old_object| (which contains any previous object + // that was evicted from the hashes) because we don't have a reference count + // on ASN1_OBJECT values. Also, we should never have duplicates nids and so + // should always have objects in |global_added_by_nid|. + + ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); + if (obj->length != 0 && obj->data != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); + } + if (obj->sn != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj); + } + if (obj->ln != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); + } + CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); + + return ok; +} + +int OBJ_create(const char *oid, const char *short_name, const char *long_name) { + ASN1_OBJECT *op = + create_object_with_text_oid(obj_next_nid, oid, short_name, long_name); + if (op == NULL || + !obj_add_object(op)) { + return NID_undef; + } + return op->nid; +} + +void OBJ_cleanup(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h new file mode 100644 index 00000000..778d8e3c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_dat.h @@ -0,0 +1,11585 @@ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +/* This file is generated by crypto/obj/objects.go. */ + + +#define NUM_NID 963 + +static const uint8_t kObjectData[] = { + /* NID_rsadsi */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + /* NID_pkcs */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + /* NID_md2 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x02, + /* NID_md5 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x05, + /* NID_rc4 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x03, + 0x04, + /* NID_rsaEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x01, + /* NID_md2WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x02, + /* NID_md5WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x04, + /* NID_pbeWithMD2AndDES_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x01, + /* NID_pbeWithMD5AndDES_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x03, + /* NID_X500 */ + 0x55, + /* NID_X509 */ + 0x55, + 0x04, + /* NID_commonName */ + 0x55, + 0x04, + 0x03, + /* NID_countryName */ + 0x55, + 0x04, + 0x06, + /* NID_localityName */ + 0x55, + 0x04, + 0x07, + /* NID_stateOrProvinceName */ + 0x55, + 0x04, + 0x08, + /* NID_organizationName */ + 0x55, + 0x04, + 0x0a, + /* NID_organizationalUnitName */ + 0x55, + 0x04, + 0x0b, + /* NID_rsa */ + 0x55, + 0x08, + 0x01, + 0x01, + /* NID_pkcs7 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + /* NID_pkcs7_data */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x01, + /* NID_pkcs7_signed */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x02, + /* NID_pkcs7_enveloped */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x03, + /* NID_pkcs7_signedAndEnveloped */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x04, + /* NID_pkcs7_digest */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x05, + /* NID_pkcs7_encrypted */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x07, + 0x06, + /* NID_pkcs3 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x03, + /* NID_dhKeyAgreement */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x03, + 0x01, + /* NID_des_ecb */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x06, + /* NID_des_cfb64 */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x09, + /* NID_des_cbc */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x07, + /* NID_des_ede_ecb */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x11, + /* NID_idea_cbc */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x81, + 0x3c, + 0x07, + 0x01, + 0x01, + 0x02, + /* NID_rc2_cbc */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x03, + 0x02, + /* NID_sha */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x12, + /* NID_shaWithRSAEncryption */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x0f, + /* NID_des_ede3_cbc */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x03, + 0x07, + /* NID_des_ofb64 */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x08, + /* NID_pkcs9 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + /* NID_pkcs9_emailAddress */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x01, + /* NID_pkcs9_unstructuredName */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x02, + /* NID_pkcs9_contentType */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x03, + /* NID_pkcs9_messageDigest */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x04, + /* NID_pkcs9_signingTime */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x05, + /* NID_pkcs9_countersignature */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x06, + /* NID_pkcs9_challengePassword */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x07, + /* NID_pkcs9_unstructuredAddress */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x08, + /* NID_pkcs9_extCertAttributes */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x09, + /* NID_netscape */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + /* NID_netscape_cert_extension */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + /* NID_netscape_data_type */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + /* NID_sha1 */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x1a, + /* NID_sha1WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x05, + /* NID_dsaWithSHA */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x0d, + /* NID_dsa_2 */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x0c, + /* NID_pbeWithSHA1AndRC2_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x0b, + /* NID_id_pbkdf2 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x0c, + /* NID_dsaWithSHA1_2 */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x1b, + /* NID_netscape_cert_type */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x01, + /* NID_netscape_base_url */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x02, + /* NID_netscape_revocation_url */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x03, + /* NID_netscape_ca_revocation_url */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x04, + /* NID_netscape_renewal_url */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x07, + /* NID_netscape_ca_policy_url */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x08, + /* NID_netscape_ssl_server_name */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x0c, + /* NID_netscape_comment */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x01, + 0x0d, + /* NID_netscape_cert_sequence */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + 0x05, + /* NID_id_ce */ + 0x55, + 0x1d, + /* NID_subject_key_identifier */ + 0x55, + 0x1d, + 0x0e, + /* NID_key_usage */ + 0x55, + 0x1d, + 0x0f, + /* NID_private_key_usage_period */ + 0x55, + 0x1d, + 0x10, + /* NID_subject_alt_name */ + 0x55, + 0x1d, + 0x11, + /* NID_issuer_alt_name */ + 0x55, + 0x1d, + 0x12, + /* NID_basic_constraints */ + 0x55, + 0x1d, + 0x13, + /* NID_crl_number */ + 0x55, + 0x1d, + 0x14, + /* NID_certificate_policies */ + 0x55, + 0x1d, + 0x20, + /* NID_authority_key_identifier */ + 0x55, + 0x1d, + 0x23, + /* NID_bf_cbc */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x97, + 0x55, + 0x01, + 0x02, + /* NID_mdc2 */ + 0x55, + 0x08, + 0x03, + 0x65, + /* NID_mdc2WithRSA */ + 0x55, + 0x08, + 0x03, + 0x64, + /* NID_givenName */ + 0x55, + 0x04, + 0x2a, + /* NID_surname */ + 0x55, + 0x04, + 0x04, + /* NID_initials */ + 0x55, + 0x04, + 0x2b, + /* NID_crl_distribution_points */ + 0x55, + 0x1d, + 0x1f, + /* NID_md5WithRSA */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x03, + /* NID_serialNumber */ + 0x55, + 0x04, + 0x05, + /* NID_title */ + 0x55, + 0x04, + 0x0c, + /* NID_description */ + 0x55, + 0x04, + 0x0d, + /* NID_cast5_cbc */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf6, + 0x7d, + 0x07, + 0x42, + 0x0a, + /* NID_pbeWithMD5AndCast5_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf6, + 0x7d, + 0x07, + 0x42, + 0x0c, + /* NID_dsaWithSHA1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x04, + 0x03, + /* NID_sha1WithRSA */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x1d, + /* NID_dsa */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x04, + 0x01, + /* NID_ripemd160 */ + 0x2b, + 0x24, + 0x03, + 0x02, + 0x01, + /* NID_ripemd160WithRSA */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x01, + 0x02, + /* NID_rc5_cbc */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x03, + 0x08, + /* NID_zlib_compression */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x08, + /* NID_ext_key_usage */ + 0x55, + 0x1d, + 0x25, + /* NID_id_pkix */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + /* NID_id_kp */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + /* NID_server_auth */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x01, + /* NID_client_auth */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x02, + /* NID_code_sign */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x03, + /* NID_email_protect */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x04, + /* NID_time_stamp */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x08, + /* NID_ms_code_ind */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x02, + 0x01, + 0x15, + /* NID_ms_code_com */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x02, + 0x01, + 0x16, + /* NID_ms_ctl_sign */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x0a, + 0x03, + 0x01, + /* NID_ms_sgc */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x0a, + 0x03, + 0x03, + /* NID_ms_efs */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x0a, + 0x03, + 0x04, + /* NID_ns_sgc */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x04, + 0x01, + /* NID_delta_crl */ + 0x55, + 0x1d, + 0x1b, + /* NID_crl_reason */ + 0x55, + 0x1d, + 0x15, + /* NID_invalidity_date */ + 0x55, + 0x1d, + 0x18, + /* NID_sxnet */ + 0x2b, + 0x65, + 0x01, + 0x04, + 0x01, + /* NID_pbe_WithSHA1And128BitRC4 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x01, + /* NID_pbe_WithSHA1And40BitRC4 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x02, + /* NID_pbe_WithSHA1And3_Key_TripleDES_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x03, + /* NID_pbe_WithSHA1And2_Key_TripleDES_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x04, + /* NID_pbe_WithSHA1And128BitRC2_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x05, + /* NID_pbe_WithSHA1And40BitRC2_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x01, + 0x06, + /* NID_keyBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x01, + /* NID_pkcs8ShroudedKeyBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x02, + /* NID_certBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x03, + /* NID_crlBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x04, + /* NID_secretBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x05, + /* NID_safeContentsBag */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x0c, + 0x0a, + 0x01, + 0x06, + /* NID_friendlyName */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x14, + /* NID_localKeyID */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x15, + /* NID_x509Certificate */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x16, + 0x01, + /* NID_sdsiCertificate */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x16, + 0x02, + /* NID_x509Crl */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x17, + 0x01, + /* NID_pbes2 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x0d, + /* NID_pbmac1 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x0e, + /* NID_hmacWithSHA1 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x07, + /* NID_id_qt_cps */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x02, + 0x01, + /* NID_id_qt_unotice */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x02, + 0x02, + /* NID_SMIMECapabilities */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x0f, + /* NID_pbeWithMD2AndRC2_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x04, + /* NID_pbeWithMD5AndRC2_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x06, + /* NID_pbeWithSHA1AndDES_CBC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + 0x0a, + /* NID_ms_ext_req */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x02, + 0x01, + 0x0e, + /* NID_ext_req */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x0e, + /* NID_name */ + 0x55, + 0x04, + 0x29, + /* NID_dnQualifier */ + 0x55, + 0x04, + 0x2e, + /* NID_id_pe */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + /* NID_id_ad */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + /* NID_info_access */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x01, + /* NID_ad_OCSP */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + /* NID_ad_ca_issuers */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x02, + /* NID_OCSP_sign */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x09, + /* NID_member_body */ + 0x2a, + /* NID_ISO_US */ + 0x2a, + 0x86, + 0x48, + /* NID_X9_57 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + /* NID_X9cm */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x04, + /* NID_pkcs1 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + /* NID_pkcs5 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x05, + /* NID_SMIME */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + /* NID_id_smime_mod */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + /* NID_id_smime_ct */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + /* NID_id_smime_aa */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + /* NID_id_smime_alg */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + /* NID_id_smime_cd */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x04, + /* NID_id_smime_spq */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x05, + /* NID_id_smime_cti */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + /* NID_id_smime_mod_cms */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x01, + /* NID_id_smime_mod_ess */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x02, + /* NID_id_smime_mod_oid */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x03, + /* NID_id_smime_mod_msg_v3 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x04, + /* NID_id_smime_mod_ets_eSignature_88 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x05, + /* NID_id_smime_mod_ets_eSignature_97 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x06, + /* NID_id_smime_mod_ets_eSigPolicy_88 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x07, + /* NID_id_smime_mod_ets_eSigPolicy_97 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x00, + 0x08, + /* NID_id_smime_ct_receipt */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x01, + /* NID_id_smime_ct_authData */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x02, + /* NID_id_smime_ct_publishCert */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x03, + /* NID_id_smime_ct_TSTInfo */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x04, + /* NID_id_smime_ct_TDTInfo */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x05, + /* NID_id_smime_ct_contentInfo */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x06, + /* NID_id_smime_ct_DVCSRequestData */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x07, + /* NID_id_smime_ct_DVCSResponseData */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x08, + /* NID_id_smime_aa_receiptRequest */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x01, + /* NID_id_smime_aa_securityLabel */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x02, + /* NID_id_smime_aa_mlExpandHistory */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x03, + /* NID_id_smime_aa_contentHint */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x04, + /* NID_id_smime_aa_msgSigDigest */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x05, + /* NID_id_smime_aa_encapContentType */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x06, + /* NID_id_smime_aa_contentIdentifier */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x07, + /* NID_id_smime_aa_macValue */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x08, + /* NID_id_smime_aa_equivalentLabels */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x09, + /* NID_id_smime_aa_contentReference */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0a, + /* NID_id_smime_aa_encrypKeyPref */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0b, + /* NID_id_smime_aa_signingCertificate */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0c, + /* NID_id_smime_aa_smimeEncryptCerts */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0d, + /* NID_id_smime_aa_timeStampToken */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0e, + /* NID_id_smime_aa_ets_sigPolicyId */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x0f, + /* NID_id_smime_aa_ets_commitmentType */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x10, + /* NID_id_smime_aa_ets_signerLocation */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x11, + /* NID_id_smime_aa_ets_signerAttr */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x12, + /* NID_id_smime_aa_ets_otherSigCert */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x13, + /* NID_id_smime_aa_ets_contentTimestamp */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x14, + /* NID_id_smime_aa_ets_CertificateRefs */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x15, + /* NID_id_smime_aa_ets_RevocationRefs */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x16, + /* NID_id_smime_aa_ets_certValues */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x17, + /* NID_id_smime_aa_ets_revocationValues */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x18, + /* NID_id_smime_aa_ets_escTimeStamp */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x19, + /* NID_id_smime_aa_ets_certCRLTimestamp */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x1a, + /* NID_id_smime_aa_ets_archiveTimeStamp */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x1b, + /* NID_id_smime_aa_signatureType */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x1c, + /* NID_id_smime_aa_dvcs_dvc */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x02, + 0x1d, + /* NID_id_smime_alg_ESDHwith3DES */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x01, + /* NID_id_smime_alg_ESDHwithRC2 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x02, + /* NID_id_smime_alg_3DESwrap */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x03, + /* NID_id_smime_alg_RC2wrap */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x04, + /* NID_id_smime_alg_ESDH */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x05, + /* NID_id_smime_alg_CMS3DESwrap */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x06, + /* NID_id_smime_alg_CMSRC2wrap */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x07, + /* NID_id_smime_cd_ldap */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x04, + 0x01, + /* NID_id_smime_spq_ets_sqt_uri */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x05, + 0x01, + /* NID_id_smime_spq_ets_sqt_unotice */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x05, + 0x02, + /* NID_id_smime_cti_ets_proofOfOrigin */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x01, + /* NID_id_smime_cti_ets_proofOfReceipt */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x02, + /* NID_id_smime_cti_ets_proofOfDelivery */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x03, + /* NID_id_smime_cti_ets_proofOfSender */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x04, + /* NID_id_smime_cti_ets_proofOfApproval */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x05, + /* NID_id_smime_cti_ets_proofOfCreation */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x06, + 0x06, + /* NID_md4 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x04, + /* NID_id_pkix_mod */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + /* NID_id_qt */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x02, + /* NID_id_it */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + /* NID_id_pkip */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + /* NID_id_alg */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x06, + /* NID_id_cmc */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + /* NID_id_on */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x08, + /* NID_id_pda */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + /* NID_id_aca */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + /* NID_id_qcs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0b, + /* NID_id_cct */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0c, + /* NID_id_pkix1_explicit_88 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x01, + /* NID_id_pkix1_implicit_88 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x02, + /* NID_id_pkix1_explicit_93 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x03, + /* NID_id_pkix1_implicit_93 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x04, + /* NID_id_mod_crmf */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x05, + /* NID_id_mod_cmc */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x06, + /* NID_id_mod_kea_profile_88 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x07, + /* NID_id_mod_kea_profile_93 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x08, + /* NID_id_mod_cmp */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x09, + /* NID_id_mod_qualified_cert_88 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0a, + /* NID_id_mod_qualified_cert_93 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0b, + /* NID_id_mod_attribute_cert */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0c, + /* NID_id_mod_timestamp_protocol */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0d, + /* NID_id_mod_ocsp */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0e, + /* NID_id_mod_dvcs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x0f, + /* NID_id_mod_cmp2000 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x00, + 0x10, + /* NID_biometricInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x02, + /* NID_qcStatements */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x03, + /* NID_ac_auditEntity */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x04, + /* NID_ac_targeting */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x05, + /* NID_aaControls */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x06, + /* NID_sbgp_ipAddrBlock */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x07, + /* NID_sbgp_autonomousSysNum */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x08, + /* NID_sbgp_routerIdentifier */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x09, + /* NID_textNotice */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x02, + 0x03, + /* NID_ipsecEndSystem */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x05, + /* NID_ipsecTunnel */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x06, + /* NID_ipsecUser */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x07, + /* NID_dvcs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x03, + 0x0a, + /* NID_id_it_caProtEncCert */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x01, + /* NID_id_it_signKeyPairTypes */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x02, + /* NID_id_it_encKeyPairTypes */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x03, + /* NID_id_it_preferredSymmAlg */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x04, + /* NID_id_it_caKeyUpdateInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x05, + /* NID_id_it_currentCRL */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x06, + /* NID_id_it_unsupportedOIDs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x07, + /* NID_id_it_subscriptionRequest */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x08, + /* NID_id_it_subscriptionResponse */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x09, + /* NID_id_it_keyPairParamReq */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0a, + /* NID_id_it_keyPairParamRep */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0b, + /* NID_id_it_revPassphrase */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0c, + /* NID_id_it_implicitConfirm */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0d, + /* NID_id_it_confirmWaitTime */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0e, + /* NID_id_it_origPKIMessage */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x0f, + /* NID_id_regCtrl */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + /* NID_id_regInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x02, + /* NID_id_regCtrl_regToken */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x01, + /* NID_id_regCtrl_authenticator */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x02, + /* NID_id_regCtrl_pkiPublicationInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x03, + /* NID_id_regCtrl_pkiArchiveOptions */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x04, + /* NID_id_regCtrl_oldCertID */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x05, + /* NID_id_regCtrl_protocolEncrKey */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x01, + 0x06, + /* NID_id_regInfo_utf8Pairs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x02, + 0x01, + /* NID_id_regInfo_certReq */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x05, + 0x02, + 0x02, + /* NID_id_alg_des40 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x06, + 0x01, + /* NID_id_alg_noSignature */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x06, + 0x02, + /* NID_id_alg_dh_sig_hmac_sha1 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x06, + 0x03, + /* NID_id_alg_dh_pop */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x06, + 0x04, + /* NID_id_cmc_statusInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x01, + /* NID_id_cmc_identification */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x02, + /* NID_id_cmc_identityProof */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x03, + /* NID_id_cmc_dataReturn */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x04, + /* NID_id_cmc_transactionId */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x05, + /* NID_id_cmc_senderNonce */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x06, + /* NID_id_cmc_recipientNonce */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x07, + /* NID_id_cmc_addExtensions */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x08, + /* NID_id_cmc_encryptedPOP */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x09, + /* NID_id_cmc_decryptedPOP */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x0a, + /* NID_id_cmc_lraPOPWitness */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x0b, + /* NID_id_cmc_getCert */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x0f, + /* NID_id_cmc_getCRL */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x10, + /* NID_id_cmc_revokeRequest */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x11, + /* NID_id_cmc_regInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x12, + /* NID_id_cmc_responseInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x13, + /* NID_id_cmc_queryPending */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x15, + /* NID_id_cmc_popLinkRandom */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x16, + /* NID_id_cmc_popLinkWitness */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x17, + /* NID_id_cmc_confirmCertAcceptance */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x07, + 0x18, + /* NID_id_on_personalData */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x08, + 0x01, + /* NID_id_pda_dateOfBirth */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + 0x01, + /* NID_id_pda_placeOfBirth */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + 0x02, + /* NID_id_pda_gender */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + 0x03, + /* NID_id_pda_countryOfCitizenship */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + 0x04, + /* NID_id_pda_countryOfResidence */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x09, + 0x05, + /* NID_id_aca_authenticationInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x01, + /* NID_id_aca_accessIdentity */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x02, + /* NID_id_aca_chargingIdentity */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x03, + /* NID_id_aca_group */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x04, + /* NID_id_aca_role */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x05, + /* NID_id_qcs_pkixQCSyntax_v1 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0b, + 0x01, + /* NID_id_cct_crs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0c, + 0x01, + /* NID_id_cct_PKIData */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0c, + 0x02, + /* NID_id_cct_PKIResponse */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0c, + 0x03, + /* NID_ad_timeStamping */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x03, + /* NID_ad_dvcs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x04, + /* NID_id_pkix_OCSP_basic */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x01, + /* NID_id_pkix_OCSP_Nonce */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x02, + /* NID_id_pkix_OCSP_CrlID */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x03, + /* NID_id_pkix_OCSP_acceptableResponses */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x04, + /* NID_id_pkix_OCSP_noCheck */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x05, + /* NID_id_pkix_OCSP_archiveCutoff */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x06, + /* NID_id_pkix_OCSP_serviceLocator */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x07, + /* NID_id_pkix_OCSP_extendedStatus */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x08, + /* NID_id_pkix_OCSP_valid */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x09, + /* NID_id_pkix_OCSP_path */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x0a, + /* NID_id_pkix_OCSP_trustRoot */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x01, + 0x0b, + /* NID_algorithm */ + 0x2b, + 0x0e, + 0x03, + 0x02, + /* NID_rsaSignature */ + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x0b, + /* NID_X500algorithms */ + 0x55, + 0x08, + /* NID_org */ + 0x2b, + /* NID_dod */ + 0x2b, + 0x06, + /* NID_iana */ + 0x2b, + 0x06, + 0x01, + /* NID_Directory */ + 0x2b, + 0x06, + 0x01, + 0x01, + /* NID_Management */ + 0x2b, + 0x06, + 0x01, + 0x02, + /* NID_Experimental */ + 0x2b, + 0x06, + 0x01, + 0x03, + /* NID_Private */ + 0x2b, + 0x06, + 0x01, + 0x04, + /* NID_Security */ + 0x2b, + 0x06, + 0x01, + 0x05, + /* NID_SNMPv2 */ + 0x2b, + 0x06, + 0x01, + 0x06, + /* NID_Mail */ + 0x2b, + 0x06, + 0x01, + 0x07, + /* NID_Enterprises */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + /* NID_dcObject */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x8b, + 0x3a, + 0x82, + 0x58, + /* NID_domainComponent */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x19, + /* NID_Domain */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x0d, + /* NID_selected_attribute_types */ + 0x55, + 0x01, + 0x05, + /* NID_clearance */ + 0x55, + 0x01, + 0x05, + 0x37, + /* NID_md4WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x03, + /* NID_ac_proxying */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x0a, + /* NID_sinfo_access */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x0b, + /* NID_id_aca_encAttrs */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x0a, + 0x06, + /* NID_role */ + 0x55, + 0x04, + 0x48, + /* NID_policy_constraints */ + 0x55, + 0x1d, + 0x24, + /* NID_target_information */ + 0x55, + 0x1d, + 0x37, + /* NID_no_rev_avail */ + 0x55, + 0x1d, + 0x38, + /* NID_ansi_X9_62 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + /* NID_X9_62_prime_field */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x01, + /* NID_X9_62_characteristic_two_field */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x02, + /* NID_X9_62_id_ecPublicKey */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x02, + 0x01, + /* NID_X9_62_prime192v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x01, + /* NID_X9_62_prime192v2 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x02, + /* NID_X9_62_prime192v3 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x03, + /* NID_X9_62_prime239v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x04, + /* NID_X9_62_prime239v2 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x05, + /* NID_X9_62_prime239v3 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x06, + /* NID_X9_62_prime256v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x01, + 0x07, + /* NID_ecdsa_with_SHA1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x01, + /* NID_ms_csp_name */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x11, + 0x01, + /* NID_aes_128_ecb */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x01, + /* NID_aes_128_cbc */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x02, + /* NID_aes_128_ofb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x03, + /* NID_aes_128_cfb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x04, + /* NID_aes_192_ecb */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x15, + /* NID_aes_192_cbc */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x16, + /* NID_aes_192_ofb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x17, + /* NID_aes_192_cfb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x18, + /* NID_aes_256_ecb */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x29, + /* NID_aes_256_cbc */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2a, + /* NID_aes_256_ofb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2b, + /* NID_aes_256_cfb128 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2c, + /* NID_hold_instruction_code */ + 0x55, + 0x1d, + 0x17, + /* NID_hold_instruction_none */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x02, + 0x01, + /* NID_hold_instruction_call_issuer */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x02, + 0x02, + /* NID_hold_instruction_reject */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x38, + 0x02, + 0x03, + /* NID_data */ + 0x09, + /* NID_pss */ + 0x09, + 0x92, + 0x26, + /* NID_ucl */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + /* NID_pilot */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + /* NID_pilotAttributeType */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + /* NID_pilotAttributeSyntax */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x03, + /* NID_pilotObjectClass */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + /* NID_pilotGroups */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x0a, + /* NID_iA5StringSyntax */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x03, + 0x04, + /* NID_caseIgnoreIA5StringSyntax */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x03, + 0x05, + /* NID_pilotObject */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x03, + /* NID_pilotPerson */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x04, + /* NID_account */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x05, + /* NID_document */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x06, + /* NID_room */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x07, + /* NID_documentSeries */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x09, + /* NID_rFC822localPart */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x0e, + /* NID_dNSDomain */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x0f, + /* NID_domainRelatedObject */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x11, + /* NID_friendlyCountry */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x12, + /* NID_simpleSecurityObject */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x13, + /* NID_pilotOrganization */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x14, + /* NID_pilotDSA */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x15, + /* NID_qualityLabelledData */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x04, + 0x16, + /* NID_userId */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x01, + /* NID_textEncodedORAddress */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x02, + /* NID_rfc822Mailbox */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x03, + /* NID_info */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x04, + /* NID_favouriteDrink */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x05, + /* NID_roomNumber */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x06, + /* NID_photo */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x07, + /* NID_userClass */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x08, + /* NID_host */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x09, + /* NID_manager */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0a, + /* NID_documentIdentifier */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0b, + /* NID_documentTitle */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0c, + /* NID_documentVersion */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0d, + /* NID_documentAuthor */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0e, + /* NID_documentLocation */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x0f, + /* NID_homeTelephoneNumber */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x14, + /* NID_secretary */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x15, + /* NID_otherMailbox */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x16, + /* NID_lastModifiedTime */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x17, + /* NID_lastModifiedBy */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x18, + /* NID_aRecord */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1a, + /* NID_pilotAttributeType27 */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1b, + /* NID_mXRecord */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1c, + /* NID_nSRecord */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1d, + /* NID_sOARecord */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1e, + /* NID_cNAMERecord */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x1f, + /* NID_associatedDomain */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x25, + /* NID_associatedName */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x26, + /* NID_homePostalAddress */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x27, + /* NID_personalTitle */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x28, + /* NID_mobileTelephoneNumber */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x29, + /* NID_pagerTelephoneNumber */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x2a, + /* NID_friendlyCountryName */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x2b, + /* NID_organizationalStatus */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x2d, + /* NID_janetMailbox */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x2e, + /* NID_mailPreferenceOption */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x2f, + /* NID_buildingName */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x30, + /* NID_dSAQuality */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x31, + /* NID_singleLevelQuality */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x32, + /* NID_subtreeMinimumQuality */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x33, + /* NID_subtreeMaximumQuality */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x34, + /* NID_personalSignature */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x35, + /* NID_dITRedirect */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x36, + /* NID_audio */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x37, + /* NID_documentPublisher */ + 0x09, + 0x92, + 0x26, + 0x89, + 0x93, + 0xf2, + 0x2c, + 0x64, + 0x01, + 0x38, + /* NID_x500UniqueIdentifier */ + 0x55, + 0x04, + 0x2d, + /* NID_mime_mhs */ + 0x2b, + 0x06, + 0x01, + 0x07, + 0x01, + /* NID_mime_mhs_headings */ + 0x2b, + 0x06, + 0x01, + 0x07, + 0x01, + 0x01, + /* NID_mime_mhs_bodies */ + 0x2b, + 0x06, + 0x01, + 0x07, + 0x01, + 0x02, + /* NID_id_hex_partial_message */ + 0x2b, + 0x06, + 0x01, + 0x07, + 0x01, + 0x01, + 0x01, + /* NID_id_hex_multipart_message */ + 0x2b, + 0x06, + 0x01, + 0x07, + 0x01, + 0x01, + 0x02, + /* NID_generationQualifier */ + 0x55, + 0x04, + 0x2c, + /* NID_pseudonym */ + 0x55, + 0x04, + 0x41, + /* NID_id_set */ + 0x67, + 0x2a, + /* NID_set_ctype */ + 0x67, + 0x2a, + 0x00, + /* NID_set_msgExt */ + 0x67, + 0x2a, + 0x01, + /* NID_set_attr */ + 0x67, + 0x2a, + 0x03, + /* NID_set_policy */ + 0x67, + 0x2a, + 0x05, + /* NID_set_certExt */ + 0x67, + 0x2a, + 0x07, + /* NID_set_brand */ + 0x67, + 0x2a, + 0x08, + /* NID_setct_PANData */ + 0x67, + 0x2a, + 0x00, + 0x00, + /* NID_setct_PANToken */ + 0x67, + 0x2a, + 0x00, + 0x01, + /* NID_setct_PANOnly */ + 0x67, + 0x2a, + 0x00, + 0x02, + /* NID_setct_OIData */ + 0x67, + 0x2a, + 0x00, + 0x03, + /* NID_setct_PI */ + 0x67, + 0x2a, + 0x00, + 0x04, + /* NID_setct_PIData */ + 0x67, + 0x2a, + 0x00, + 0x05, + /* NID_setct_PIDataUnsigned */ + 0x67, + 0x2a, + 0x00, + 0x06, + /* NID_setct_HODInput */ + 0x67, + 0x2a, + 0x00, + 0x07, + /* NID_setct_AuthResBaggage */ + 0x67, + 0x2a, + 0x00, + 0x08, + /* NID_setct_AuthRevReqBaggage */ + 0x67, + 0x2a, + 0x00, + 0x09, + /* NID_setct_AuthRevResBaggage */ + 0x67, + 0x2a, + 0x00, + 0x0a, + /* NID_setct_CapTokenSeq */ + 0x67, + 0x2a, + 0x00, + 0x0b, + /* NID_setct_PInitResData */ + 0x67, + 0x2a, + 0x00, + 0x0c, + /* NID_setct_PI_TBS */ + 0x67, + 0x2a, + 0x00, + 0x0d, + /* NID_setct_PResData */ + 0x67, + 0x2a, + 0x00, + 0x0e, + /* NID_setct_AuthReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x10, + /* NID_setct_AuthResTBS */ + 0x67, + 0x2a, + 0x00, + 0x11, + /* NID_setct_AuthResTBSX */ + 0x67, + 0x2a, + 0x00, + 0x12, + /* NID_setct_AuthTokenTBS */ + 0x67, + 0x2a, + 0x00, + 0x13, + /* NID_setct_CapTokenData */ + 0x67, + 0x2a, + 0x00, + 0x14, + /* NID_setct_CapTokenTBS */ + 0x67, + 0x2a, + 0x00, + 0x15, + /* NID_setct_AcqCardCodeMsg */ + 0x67, + 0x2a, + 0x00, + 0x16, + /* NID_setct_AuthRevReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x17, + /* NID_setct_AuthRevResData */ + 0x67, + 0x2a, + 0x00, + 0x18, + /* NID_setct_AuthRevResTBS */ + 0x67, + 0x2a, + 0x00, + 0x19, + /* NID_setct_CapReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x1a, + /* NID_setct_CapReqTBSX */ + 0x67, + 0x2a, + 0x00, + 0x1b, + /* NID_setct_CapResData */ + 0x67, + 0x2a, + 0x00, + 0x1c, + /* NID_setct_CapRevReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x1d, + /* NID_setct_CapRevReqTBSX */ + 0x67, + 0x2a, + 0x00, + 0x1e, + /* NID_setct_CapRevResData */ + 0x67, + 0x2a, + 0x00, + 0x1f, + /* NID_setct_CredReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x20, + /* NID_setct_CredReqTBSX */ + 0x67, + 0x2a, + 0x00, + 0x21, + /* NID_setct_CredResData */ + 0x67, + 0x2a, + 0x00, + 0x22, + /* NID_setct_CredRevReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x23, + /* NID_setct_CredRevReqTBSX */ + 0x67, + 0x2a, + 0x00, + 0x24, + /* NID_setct_CredRevResData */ + 0x67, + 0x2a, + 0x00, + 0x25, + /* NID_setct_PCertReqData */ + 0x67, + 0x2a, + 0x00, + 0x26, + /* NID_setct_PCertResTBS */ + 0x67, + 0x2a, + 0x00, + 0x27, + /* NID_setct_BatchAdminReqData */ + 0x67, + 0x2a, + 0x00, + 0x28, + /* NID_setct_BatchAdminResData */ + 0x67, + 0x2a, + 0x00, + 0x29, + /* NID_setct_CardCInitResTBS */ + 0x67, + 0x2a, + 0x00, + 0x2a, + /* NID_setct_MeAqCInitResTBS */ + 0x67, + 0x2a, + 0x00, + 0x2b, + /* NID_setct_RegFormResTBS */ + 0x67, + 0x2a, + 0x00, + 0x2c, + /* NID_setct_CertReqData */ + 0x67, + 0x2a, + 0x00, + 0x2d, + /* NID_setct_CertReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x2e, + /* NID_setct_CertResData */ + 0x67, + 0x2a, + 0x00, + 0x2f, + /* NID_setct_CertInqReqTBS */ + 0x67, + 0x2a, + 0x00, + 0x30, + /* NID_setct_ErrorTBS */ + 0x67, + 0x2a, + 0x00, + 0x31, + /* NID_setct_PIDualSignedTBE */ + 0x67, + 0x2a, + 0x00, + 0x32, + /* NID_setct_PIUnsignedTBE */ + 0x67, + 0x2a, + 0x00, + 0x33, + /* NID_setct_AuthReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x34, + /* NID_setct_AuthResTBE */ + 0x67, + 0x2a, + 0x00, + 0x35, + /* NID_setct_AuthResTBEX */ + 0x67, + 0x2a, + 0x00, + 0x36, + /* NID_setct_AuthTokenTBE */ + 0x67, + 0x2a, + 0x00, + 0x37, + /* NID_setct_CapTokenTBE */ + 0x67, + 0x2a, + 0x00, + 0x38, + /* NID_setct_CapTokenTBEX */ + 0x67, + 0x2a, + 0x00, + 0x39, + /* NID_setct_AcqCardCodeMsgTBE */ + 0x67, + 0x2a, + 0x00, + 0x3a, + /* NID_setct_AuthRevReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x3b, + /* NID_setct_AuthRevResTBE */ + 0x67, + 0x2a, + 0x00, + 0x3c, + /* NID_setct_AuthRevResTBEB */ + 0x67, + 0x2a, + 0x00, + 0x3d, + /* NID_setct_CapReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x3e, + /* NID_setct_CapReqTBEX */ + 0x67, + 0x2a, + 0x00, + 0x3f, + /* NID_setct_CapResTBE */ + 0x67, + 0x2a, + 0x00, + 0x40, + /* NID_setct_CapRevReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x41, + /* NID_setct_CapRevReqTBEX */ + 0x67, + 0x2a, + 0x00, + 0x42, + /* NID_setct_CapRevResTBE */ + 0x67, + 0x2a, + 0x00, + 0x43, + /* NID_setct_CredReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x44, + /* NID_setct_CredReqTBEX */ + 0x67, + 0x2a, + 0x00, + 0x45, + /* NID_setct_CredResTBE */ + 0x67, + 0x2a, + 0x00, + 0x46, + /* NID_setct_CredRevReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x47, + /* NID_setct_CredRevReqTBEX */ + 0x67, + 0x2a, + 0x00, + 0x48, + /* NID_setct_CredRevResTBE */ + 0x67, + 0x2a, + 0x00, + 0x49, + /* NID_setct_BatchAdminReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x4a, + /* NID_setct_BatchAdminResTBE */ + 0x67, + 0x2a, + 0x00, + 0x4b, + /* NID_setct_RegFormReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x4c, + /* NID_setct_CertReqTBE */ + 0x67, + 0x2a, + 0x00, + 0x4d, + /* NID_setct_CertReqTBEX */ + 0x67, + 0x2a, + 0x00, + 0x4e, + /* NID_setct_CertResTBE */ + 0x67, + 0x2a, + 0x00, + 0x4f, + /* NID_setct_CRLNotificationTBS */ + 0x67, + 0x2a, + 0x00, + 0x50, + /* NID_setct_CRLNotificationResTBS */ + 0x67, + 0x2a, + 0x00, + 0x51, + /* NID_setct_BCIDistributionTBS */ + 0x67, + 0x2a, + 0x00, + 0x52, + /* NID_setext_genCrypt */ + 0x67, + 0x2a, + 0x01, + 0x01, + /* NID_setext_miAuth */ + 0x67, + 0x2a, + 0x01, + 0x03, + /* NID_setext_pinSecure */ + 0x67, + 0x2a, + 0x01, + 0x04, + /* NID_setext_pinAny */ + 0x67, + 0x2a, + 0x01, + 0x05, + /* NID_setext_track2 */ + 0x67, + 0x2a, + 0x01, + 0x07, + /* NID_setext_cv */ + 0x67, + 0x2a, + 0x01, + 0x08, + /* NID_set_policy_root */ + 0x67, + 0x2a, + 0x05, + 0x00, + /* NID_setCext_hashedRoot */ + 0x67, + 0x2a, + 0x07, + 0x00, + /* NID_setCext_certType */ + 0x67, + 0x2a, + 0x07, + 0x01, + /* NID_setCext_merchData */ + 0x67, + 0x2a, + 0x07, + 0x02, + /* NID_setCext_cCertRequired */ + 0x67, + 0x2a, + 0x07, + 0x03, + /* NID_setCext_tunneling */ + 0x67, + 0x2a, + 0x07, + 0x04, + /* NID_setCext_setExt */ + 0x67, + 0x2a, + 0x07, + 0x05, + /* NID_setCext_setQualf */ + 0x67, + 0x2a, + 0x07, + 0x06, + /* NID_setCext_PGWYcapabilities */ + 0x67, + 0x2a, + 0x07, + 0x07, + /* NID_setCext_TokenIdentifier */ + 0x67, + 0x2a, + 0x07, + 0x08, + /* NID_setCext_Track2Data */ + 0x67, + 0x2a, + 0x07, + 0x09, + /* NID_setCext_TokenType */ + 0x67, + 0x2a, + 0x07, + 0x0a, + /* NID_setCext_IssuerCapabilities */ + 0x67, + 0x2a, + 0x07, + 0x0b, + /* NID_setAttr_Cert */ + 0x67, + 0x2a, + 0x03, + 0x00, + /* NID_setAttr_PGWYcap */ + 0x67, + 0x2a, + 0x03, + 0x01, + /* NID_setAttr_TokenType */ + 0x67, + 0x2a, + 0x03, + 0x02, + /* NID_setAttr_IssCap */ + 0x67, + 0x2a, + 0x03, + 0x03, + /* NID_set_rootKeyThumb */ + 0x67, + 0x2a, + 0x03, + 0x00, + 0x00, + /* NID_set_addPolicy */ + 0x67, + 0x2a, + 0x03, + 0x00, + 0x01, + /* NID_setAttr_Token_EMV */ + 0x67, + 0x2a, + 0x03, + 0x02, + 0x01, + /* NID_setAttr_Token_B0Prime */ + 0x67, + 0x2a, + 0x03, + 0x02, + 0x02, + /* NID_setAttr_IssCap_CVM */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x03, + /* NID_setAttr_IssCap_T2 */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x04, + /* NID_setAttr_IssCap_Sig */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x05, + /* NID_setAttr_GenCryptgrm */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x03, + 0x01, + /* NID_setAttr_T2Enc */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x04, + 0x01, + /* NID_setAttr_T2cleartxt */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x04, + 0x02, + /* NID_setAttr_TokICCsig */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x05, + 0x01, + /* NID_setAttr_SecDevSig */ + 0x67, + 0x2a, + 0x03, + 0x03, + 0x05, + 0x02, + /* NID_set_brand_IATA_ATA */ + 0x67, + 0x2a, + 0x08, + 0x01, + /* NID_set_brand_Diners */ + 0x67, + 0x2a, + 0x08, + 0x1e, + /* NID_set_brand_AmericanExpress */ + 0x67, + 0x2a, + 0x08, + 0x22, + /* NID_set_brand_JCB */ + 0x67, + 0x2a, + 0x08, + 0x23, + /* NID_set_brand_Visa */ + 0x67, + 0x2a, + 0x08, + 0x04, + /* NID_set_brand_MasterCard */ + 0x67, + 0x2a, + 0x08, + 0x05, + /* NID_set_brand_Novus */ + 0x67, + 0x2a, + 0x08, + 0xae, + 0x7b, + /* NID_des_cdmf */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x03, + 0x0a, + /* NID_rsaOAEPEncryptionSET */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x06, + /* NID_international_organizations */ + 0x67, + /* NID_ms_smartcard_login */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x14, + 0x02, + 0x02, + /* NID_ms_upn */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x14, + 0x02, + 0x03, + /* NID_streetAddress */ + 0x55, + 0x04, + 0x09, + /* NID_postalCode */ + 0x55, + 0x04, + 0x11, + /* NID_id_ppl */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x15, + /* NID_proxyCertInfo */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x01, + 0x0e, + /* NID_id_ppl_anyLanguage */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x15, + 0x00, + /* NID_id_ppl_inheritAll */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x15, + 0x01, + /* NID_name_constraints */ + 0x55, + 0x1d, + 0x1e, + /* NID_Independent */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x15, + 0x02, + /* NID_sha256WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x0b, + /* NID_sha384WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x0c, + /* NID_sha512WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x0d, + /* NID_sha224WithRSAEncryption */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x0e, + /* NID_sha256 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x01, + /* NID_sha384 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x02, + /* NID_sha512 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x03, + /* NID_sha224 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x04, + /* NID_identified_organization */ + 0x2b, + /* NID_certicom_arc */ + 0x2b, + 0x81, + 0x04, + /* NID_wap */ + 0x67, + 0x2b, + /* NID_wap_wsg */ + 0x67, + 0x2b, + 0x01, + /* NID_X9_62_id_characteristic_two_basis */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x02, + 0x03, + /* NID_X9_62_onBasis */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x02, + 0x03, + 0x01, + /* NID_X9_62_tpBasis */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x02, + 0x03, + 0x02, + /* NID_X9_62_ppBasis */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x01, + 0x02, + 0x03, + 0x03, + /* NID_X9_62_c2pnb163v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x01, + /* NID_X9_62_c2pnb163v2 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x02, + /* NID_X9_62_c2pnb163v3 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x03, + /* NID_X9_62_c2pnb176v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x04, + /* NID_X9_62_c2tnb191v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x05, + /* NID_X9_62_c2tnb191v2 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x06, + /* NID_X9_62_c2tnb191v3 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x07, + /* NID_X9_62_c2onb191v4 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x08, + /* NID_X9_62_c2onb191v5 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x09, + /* NID_X9_62_c2pnb208w1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0a, + /* NID_X9_62_c2tnb239v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0b, + /* NID_X9_62_c2tnb239v2 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0c, + /* NID_X9_62_c2tnb239v3 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0d, + /* NID_X9_62_c2onb239v4 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0e, + /* NID_X9_62_c2onb239v5 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x0f, + /* NID_X9_62_c2pnb272w1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x10, + /* NID_X9_62_c2pnb304w1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x11, + /* NID_X9_62_c2tnb359v1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x12, + /* NID_X9_62_c2pnb368w1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x13, + /* NID_X9_62_c2tnb431r1 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x03, + 0x00, + 0x14, + /* NID_secp112r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x06, + /* NID_secp112r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x07, + /* NID_secp128r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1c, + /* NID_secp128r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1d, + /* NID_secp160k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x09, + /* NID_secp160r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x08, + /* NID_secp160r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1e, + /* NID_secp192k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1f, + /* NID_secp224k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x20, + /* NID_secp224r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x21, + /* NID_secp256k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x0a, + /* NID_secp384r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x22, + /* NID_secp521r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x23, + /* NID_sect113r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x04, + /* NID_sect113r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x05, + /* NID_sect131r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x16, + /* NID_sect131r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x17, + /* NID_sect163k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x01, + /* NID_sect163r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x02, + /* NID_sect163r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x0f, + /* NID_sect193r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x18, + /* NID_sect193r2 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x19, + /* NID_sect233k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1a, + /* NID_sect233r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x1b, + /* NID_sect239k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x03, + /* NID_sect283k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x10, + /* NID_sect283r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x11, + /* NID_sect409k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x24, + /* NID_sect409r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x25, + /* NID_sect571k1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x26, + /* NID_sect571r1 */ + 0x2b, + 0x81, + 0x04, + 0x00, + 0x27, + /* NID_wap_wsg_idm_ecid_wtls1 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x01, + /* NID_wap_wsg_idm_ecid_wtls3 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x03, + /* NID_wap_wsg_idm_ecid_wtls4 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x04, + /* NID_wap_wsg_idm_ecid_wtls5 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x05, + /* NID_wap_wsg_idm_ecid_wtls6 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x06, + /* NID_wap_wsg_idm_ecid_wtls7 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x07, + /* NID_wap_wsg_idm_ecid_wtls8 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x08, + /* NID_wap_wsg_idm_ecid_wtls9 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x09, + /* NID_wap_wsg_idm_ecid_wtls10 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x0a, + /* NID_wap_wsg_idm_ecid_wtls11 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x0b, + /* NID_wap_wsg_idm_ecid_wtls12 */ + 0x67, + 0x2b, + 0x01, + 0x04, + 0x0c, + /* NID_any_policy */ + 0x55, + 0x1d, + 0x20, + 0x00, + /* NID_policy_mappings */ + 0x55, + 0x1d, + 0x21, + /* NID_inhibit_any_policy */ + 0x55, + 0x1d, + 0x36, + /* NID_camellia_128_cbc */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x01, + 0x02, + /* NID_camellia_192_cbc */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x01, + 0x03, + /* NID_camellia_256_cbc */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x01, + 0x04, + /* NID_camellia_128_ecb */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x01, + /* NID_camellia_192_ecb */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x15, + /* NID_camellia_256_ecb */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x29, + /* NID_camellia_128_cfb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x04, + /* NID_camellia_192_cfb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x18, + /* NID_camellia_256_cfb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x2c, + /* NID_camellia_128_ofb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x03, + /* NID_camellia_192_ofb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x17, + /* NID_camellia_256_ofb128 */ + 0x03, + 0xa2, + 0x31, + 0x05, + 0x03, + 0x01, + 0x09, + 0x2b, + /* NID_subject_directory_attributes */ + 0x55, + 0x1d, + 0x09, + /* NID_issuing_distribution_point */ + 0x55, + 0x1d, + 0x1c, + /* NID_certificate_issuer */ + 0x55, + 0x1d, + 0x1d, + /* NID_kisa */ + 0x2a, + 0x83, + 0x1a, + 0x8c, + 0x9a, + 0x44, + /* NID_seed_ecb */ + 0x2a, + 0x83, + 0x1a, + 0x8c, + 0x9a, + 0x44, + 0x01, + 0x03, + /* NID_seed_cbc */ + 0x2a, + 0x83, + 0x1a, + 0x8c, + 0x9a, + 0x44, + 0x01, + 0x04, + /* NID_seed_ofb128 */ + 0x2a, + 0x83, + 0x1a, + 0x8c, + 0x9a, + 0x44, + 0x01, + 0x06, + /* NID_seed_cfb128 */ + 0x2a, + 0x83, + 0x1a, + 0x8c, + 0x9a, + 0x44, + 0x01, + 0x05, + /* NID_hmac_md5 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x08, + 0x01, + 0x01, + /* NID_hmac_sha1 */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x08, + 0x01, + 0x02, + /* NID_id_PasswordBasedMAC */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf6, + 0x7d, + 0x07, + 0x42, + 0x0d, + /* NID_id_DHBasedMac */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf6, + 0x7d, + 0x07, + 0x42, + 0x1e, + /* NID_id_it_suppLangTags */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x04, + 0x10, + /* NID_caRepository */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x30, + 0x05, + /* NID_id_smime_ct_compressedData */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x09, + /* NID_id_ct_asciiTextWithCRLF */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x01, + 0x1b, + /* NID_id_aes128_wrap */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x05, + /* NID_id_aes192_wrap */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x19, + /* NID_id_aes256_wrap */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2d, + /* NID_ecdsa_with_Recommended */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x02, + /* NID_ecdsa_with_Specified */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x03, + /* NID_ecdsa_with_SHA224 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x03, + 0x01, + /* NID_ecdsa_with_SHA256 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x03, + 0x02, + /* NID_ecdsa_with_SHA384 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x03, + 0x03, + /* NID_ecdsa_with_SHA512 */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3d, + 0x04, + 0x03, + 0x04, + /* NID_hmacWithMD5 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x06, + /* NID_hmacWithSHA224 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x08, + /* NID_hmacWithSHA256 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x09, + /* NID_hmacWithSHA384 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x0a, + /* NID_hmacWithSHA512 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x02, + 0x0b, + /* NID_dsa_with_SHA224 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x03, + 0x01, + /* NID_dsa_with_SHA256 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x03, + 0x02, + /* NID_whirlpool */ + 0x28, + 0xcf, + 0x06, + 0x03, + 0x00, + 0x37, + /* NID_cryptopro */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + /* NID_cryptocom */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + /* NID_id_GostR3411_94_with_GostR3410_2001 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x03, + /* NID_id_GostR3411_94_with_GostR3410_94 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x04, + /* NID_id_GostR3411_94 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x09, + /* NID_id_HMACGostR3411_94 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x0a, + /* NID_id_GostR3410_2001 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x13, + /* NID_id_GostR3410_94 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x14, + /* NID_id_Gost28147_89 */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x15, + /* NID_id_Gost28147_89_MAC */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x16, + /* NID_id_GostR3411_94_prf */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x17, + /* NID_id_GostR3410_2001DH */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x62, + /* NID_id_GostR3410_94DH */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x63, + /* NID_id_Gost28147_89_CryptoPro_KeyMeshing */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x0e, + 0x01, + /* NID_id_Gost28147_89_None_KeyMeshing */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x0e, + 0x00, + /* NID_id_GostR3411_94_TestParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1e, + 0x00, + /* NID_id_GostR3411_94_CryptoProParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1e, + 0x01, + /* NID_id_Gost28147_89_TestParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x00, + /* NID_id_Gost28147_89_CryptoPro_A_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x01, + /* NID_id_Gost28147_89_CryptoPro_B_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x02, + /* NID_id_Gost28147_89_CryptoPro_C_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x03, + /* NID_id_Gost28147_89_CryptoPro_D_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x04, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x05, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x06, + /* NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x1f, + 0x07, + /* NID_id_GostR3410_94_TestParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x20, + 0x00, + /* NID_id_GostR3410_94_CryptoPro_A_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x20, + 0x02, + /* NID_id_GostR3410_94_CryptoPro_B_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x20, + 0x03, + /* NID_id_GostR3410_94_CryptoPro_C_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x20, + 0x04, + /* NID_id_GostR3410_94_CryptoPro_D_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x20, + 0x05, + /* NID_id_GostR3410_94_CryptoPro_XchA_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x21, + 0x01, + /* NID_id_GostR3410_94_CryptoPro_XchB_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x21, + 0x02, + /* NID_id_GostR3410_94_CryptoPro_XchC_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x21, + 0x03, + /* NID_id_GostR3410_2001_TestParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x23, + 0x00, + /* NID_id_GostR3410_2001_CryptoPro_A_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x23, + 0x01, + /* NID_id_GostR3410_2001_CryptoPro_B_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x23, + 0x02, + /* NID_id_GostR3410_2001_CryptoPro_C_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x23, + 0x03, + /* NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x24, + 0x00, + /* NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x24, + 0x01, + /* NID_id_GostR3410_94_a */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x14, + 0x01, + /* NID_id_GostR3410_94_aBis */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x14, + 0x02, + /* NID_id_GostR3410_94_b */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x14, + 0x03, + /* NID_id_GostR3410_94_bBis */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x02, + 0x14, + 0x04, + /* NID_id_Gost28147_89_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x06, + 0x01, + /* NID_id_GostR3410_94_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x05, + 0x03, + /* NID_id_GostR3410_2001_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x05, + 0x04, + /* NID_id_GostR3411_94_with_GostR3410_94_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x03, + 0x03, + /* NID_id_GostR3411_94_with_GostR3410_2001_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x03, + 0x04, + /* NID_id_GostR3410_2001_ParamSet_cc */ + 0x2a, + 0x85, + 0x03, + 0x02, + 0x09, + 0x01, + 0x08, + 0x01, + /* NID_LocalKeySet */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0x37, + 0x11, + 0x02, + /* NID_freshest_crl */ + 0x55, + 0x1d, + 0x2e, + /* NID_id_on_permanentIdentifier */ + 0x2b, + 0x06, + 0x01, + 0x05, + 0x05, + 0x07, + 0x08, + 0x03, + /* NID_searchGuide */ + 0x55, + 0x04, + 0x0e, + /* NID_businessCategory */ + 0x55, + 0x04, + 0x0f, + /* NID_postalAddress */ + 0x55, + 0x04, + 0x10, + /* NID_postOfficeBox */ + 0x55, + 0x04, + 0x12, + /* NID_physicalDeliveryOfficeName */ + 0x55, + 0x04, + 0x13, + /* NID_telephoneNumber */ + 0x55, + 0x04, + 0x14, + /* NID_telexNumber */ + 0x55, + 0x04, + 0x15, + /* NID_teletexTerminalIdentifier */ + 0x55, + 0x04, + 0x16, + /* NID_facsimileTelephoneNumber */ + 0x55, + 0x04, + 0x17, + /* NID_x121Address */ + 0x55, + 0x04, + 0x18, + /* NID_internationaliSDNNumber */ + 0x55, + 0x04, + 0x19, + /* NID_registeredAddress */ + 0x55, + 0x04, + 0x1a, + /* NID_destinationIndicator */ + 0x55, + 0x04, + 0x1b, + /* NID_preferredDeliveryMethod */ + 0x55, + 0x04, + 0x1c, + /* NID_presentationAddress */ + 0x55, + 0x04, + 0x1d, + /* NID_supportedApplicationContext */ + 0x55, + 0x04, + 0x1e, + /* NID_member */ + 0x55, + 0x04, + 0x1f, + /* NID_owner */ + 0x55, + 0x04, + 0x20, + /* NID_roleOccupant */ + 0x55, + 0x04, + 0x21, + /* NID_seeAlso */ + 0x55, + 0x04, + 0x22, + /* NID_userPassword */ + 0x55, + 0x04, + 0x23, + /* NID_userCertificate */ + 0x55, + 0x04, + 0x24, + /* NID_cACertificate */ + 0x55, + 0x04, + 0x25, + /* NID_authorityRevocationList */ + 0x55, + 0x04, + 0x26, + /* NID_certificateRevocationList */ + 0x55, + 0x04, + 0x27, + /* NID_crossCertificatePair */ + 0x55, + 0x04, + 0x28, + /* NID_enhancedSearchGuide */ + 0x55, + 0x04, + 0x2f, + /* NID_protocolInformation */ + 0x55, + 0x04, + 0x30, + /* NID_distinguishedName */ + 0x55, + 0x04, + 0x31, + /* NID_uniqueMember */ + 0x55, + 0x04, + 0x32, + /* NID_houseIdentifier */ + 0x55, + 0x04, + 0x33, + /* NID_supportedAlgorithms */ + 0x55, + 0x04, + 0x34, + /* NID_deltaRevocationList */ + 0x55, + 0x04, + 0x35, + /* NID_dmdName */ + 0x55, + 0x04, + 0x36, + /* NID_id_alg_PWRI_KEK */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x09, + 0x10, + 0x03, + 0x09, + /* NID_aes_128_gcm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x06, + /* NID_aes_128_ccm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x07, + /* NID_id_aes128_wrap_pad */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x08, + /* NID_aes_192_gcm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x1a, + /* NID_aes_192_ccm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x1b, + /* NID_id_aes192_wrap_pad */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x1c, + /* NID_aes_256_gcm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2e, + /* NID_aes_256_ccm */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x2f, + /* NID_id_aes256_wrap_pad */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x01, + 0x30, + /* NID_id_camellia128_wrap */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x03, + 0x02, + /* NID_id_camellia192_wrap */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x03, + 0x03, + /* NID_id_camellia256_wrap */ + 0x2a, + 0x83, + 0x08, + 0x8c, + 0x9a, + 0x4b, + 0x3d, + 0x01, + 0x01, + 0x03, + 0x04, + /* NID_anyExtendedKeyUsage */ + 0x55, + 0x1d, + 0x25, + 0x00, + /* NID_mgf1 */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x08, + /* NID_rsassaPss */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x0a, + /* NID_rsaesOaep */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x07, + /* NID_dhpublicnumber */ + 0x2a, + 0x86, + 0x48, + 0xce, + 0x3e, + 0x02, + 0x01, + /* NID_brainpoolP160r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x01, + /* NID_brainpoolP160t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x02, + /* NID_brainpoolP192r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x03, + /* NID_brainpoolP192t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x04, + /* NID_brainpoolP224r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x05, + /* NID_brainpoolP224t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x06, + /* NID_brainpoolP256r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x07, + /* NID_brainpoolP256t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x08, + /* NID_brainpoolP320r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x09, + /* NID_brainpoolP320t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x0a, + /* NID_brainpoolP384r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x0b, + /* NID_brainpoolP384t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x0c, + /* NID_brainpoolP512r1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x0d, + /* NID_brainpoolP512t1 */ + 0x2b, + 0x24, + 0x03, + 0x03, + 0x02, + 0x08, + 0x01, + 0x01, + 0x0e, + /* NID_pSpecified */ + 0x2a, + 0x86, + 0x48, + 0x86, + 0xf7, + 0x0d, + 0x01, + 0x01, + 0x09, + /* NID_dhSinglePass_stdDH_sha1kdf_scheme */ + 0x2b, + 0x81, + 0x05, + 0x10, + 0x86, + 0x48, + 0x3f, + 0x00, + 0x02, + /* NID_dhSinglePass_stdDH_sha224kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0b, + 0x00, + /* NID_dhSinglePass_stdDH_sha256kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0b, + 0x01, + /* NID_dhSinglePass_stdDH_sha384kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0b, + 0x02, + /* NID_dhSinglePass_stdDH_sha512kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0b, + 0x03, + /* NID_dhSinglePass_cofactorDH_sha1kdf_scheme */ + 0x2b, + 0x81, + 0x05, + 0x10, + 0x86, + 0x48, + 0x3f, + 0x00, + 0x03, + /* NID_dhSinglePass_cofactorDH_sha224kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0e, + 0x00, + /* NID_dhSinglePass_cofactorDH_sha256kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0e, + 0x01, + /* NID_dhSinglePass_cofactorDH_sha384kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0e, + 0x02, + /* NID_dhSinglePass_cofactorDH_sha512kdf_scheme */ + 0x2b, + 0x81, + 0x04, + 0x01, + 0x0e, + 0x03, + /* NID_X25519 */ + 0x2b, + 0x65, + 0x6e, + /* NID_ED25519 */ + 0x2b, + 0x65, + 0x70, + /* NID_ED448 */ + 0x2b, + 0x65, + 0x71, + /* NID_X448 */ + 0x2b, + 0x65, + 0x6f, + /* NID_sha512_256 */ + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x06, +}; + +static const ASN1_OBJECT kObjects[NUM_NID] = { + {"UNDEF", "undefined", NID_undef, 0, NULL, 0}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &kObjectData[0], 0}, + {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &kObjectData[6], 0}, + {"MD2", "md2", NID_md2, 8, &kObjectData[13], 0}, + {"MD5", "md5", NID_md5, 8, &kObjectData[21], 0}, + {"RC4", "rc4", NID_rc4, 8, &kObjectData[29], 0}, + {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &kObjectData[37], + 0}, + {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, + &kObjectData[46], 0}, + {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, + &kObjectData[55], 0}, + {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, + &kObjectData[64], 0}, + {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, + &kObjectData[73], 0}, + {"X500", "directory services (X.500)", NID_X500, 1, &kObjectData[82], 0}, + {"X509", "X509", NID_X509, 2, &kObjectData[83], 0}, + {"CN", "commonName", NID_commonName, 3, &kObjectData[85], 0}, + {"C", "countryName", NID_countryName, 3, &kObjectData[88], 0}, + {"L", "localityName", NID_localityName, 3, &kObjectData[91], 0}, + {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &kObjectData[94], + 0}, + {"O", "organizationName", NID_organizationName, 3, &kObjectData[97], 0}, + {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, + &kObjectData[100], 0}, + {"RSA", "rsa", NID_rsa, 4, &kObjectData[103], 0}, + {"pkcs7", "pkcs7", NID_pkcs7, 8, &kObjectData[107], 0}, + {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &kObjectData[115], 0}, + {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, + &kObjectData[124], 0}, + {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, + &kObjectData[133], 0}, + {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped, 9, &kObjectData[142], 0}, + {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, + &kObjectData[151], 0}, + {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, + &kObjectData[160], 0}, + {"pkcs3", "pkcs3", NID_pkcs3, 8, &kObjectData[169], 0}, + {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, + &kObjectData[177], 0}, + {"DES-ECB", "des-ecb", NID_des_ecb, 5, &kObjectData[186], 0}, + {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &kObjectData[191], 0}, + {"DES-CBC", "des-cbc", NID_des_cbc, 5, &kObjectData[196], 0}, + {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &kObjectData[201], 0}, + {"DES-EDE3", "des-ede3", NID_des_ede3_ecb, 0, NULL, 0}, + {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &kObjectData[206], 0}, + {"IDEA-CFB", "idea-cfb", NID_idea_cfb64, 0, NULL, 0}, + {"IDEA-ECB", "idea-ecb", NID_idea_ecb, 0, NULL, 0}, + {"RC2-CBC", "rc2-cbc", NID_rc2_cbc, 8, &kObjectData[217], 0}, + {"RC2-ECB", "rc2-ecb", NID_rc2_ecb, 0, NULL, 0}, + {"RC2-CFB", "rc2-cfb", NID_rc2_cfb64, 0, NULL, 0}, + {"RC2-OFB", "rc2-ofb", NID_rc2_ofb64, 0, NULL, 0}, + {"SHA", "sha", NID_sha, 5, &kObjectData[225], 0}, + {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, + &kObjectData[230], 0}, + {"DES-EDE-CBC", "des-ede-cbc", NID_des_ede_cbc, 0, NULL, 0}, + {"DES-EDE3-CBC", "des-ede3-cbc", NID_des_ede3_cbc, 8, &kObjectData[235], 0}, + {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &kObjectData[243], 0}, + {"IDEA-OFB", "idea-ofb", NID_idea_ofb64, 0, NULL, 0}, + {"pkcs9", "pkcs9", NID_pkcs9, 8, &kObjectData[248], 0}, + {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, + &kObjectData[256], 0}, + {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, + &kObjectData[265], 0}, + {"contentType", "contentType", NID_pkcs9_contentType, 9, &kObjectData[274], + 0}, + {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, + &kObjectData[283], 0}, + {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &kObjectData[292], + 0}, + {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, + &kObjectData[301], 0}, + {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, + &kObjectData[310], 0}, + {"unstructuredAddress", "unstructuredAddress", + NID_pkcs9_unstructuredAddress, 9, &kObjectData[319], 0}, + {"extendedCertificateAttributes", "extendedCertificateAttributes", + NID_pkcs9_extCertAttributes, 9, &kObjectData[328], 0}, + {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, + &kObjectData[337], 0}, + {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, + 8, &kObjectData[344], 0}, + {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, + &kObjectData[352], 0}, + {"DES-EDE-CFB", "des-ede-cfb", NID_des_ede_cfb64, 0, NULL, 0}, + {"DES-EDE3-CFB", "des-ede3-cfb", NID_des_ede3_cfb64, 0, NULL, 0}, + {"DES-EDE-OFB", "des-ede-ofb", NID_des_ede_ofb64, 0, NULL, 0}, + {"DES-EDE3-OFB", "des-ede3-ofb", NID_des_ede3_ofb64, 0, NULL, 0}, + {"SHA1", "sha1", NID_sha1, 5, &kObjectData[360], 0}, + {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, + &kObjectData[365], 0}, + {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &kObjectData[374], 0}, + {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &kObjectData[379], 0}, + {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, + &kObjectData[384], 0}, + {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &kObjectData[393], 0}, + {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &kObjectData[402], + 0}, + {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, + &kObjectData[407], 0}, + {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, + &kObjectData[416], 0}, + {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, + 9, &kObjectData[425], 0}, + {"nsCaRevocationUrl", "Netscape CA Revocation Url", + NID_netscape_ca_revocation_url, 9, &kObjectData[434], 0}, + {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, + &kObjectData[443], 0}, + {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, + &kObjectData[452], 0}, + {"nsSslServerName", "Netscape SSL Server Name", + NID_netscape_ssl_server_name, 9, &kObjectData[461], 0}, + {"nsComment", "Netscape Comment", NID_netscape_comment, 9, + &kObjectData[470], 0}, + {"nsCertSequence", "Netscape Certificate Sequence", + NID_netscape_cert_sequence, 9, &kObjectData[479], 0}, + {"DESX-CBC", "desx-cbc", NID_desx_cbc, 0, NULL, 0}, + {"id-ce", "id-ce", NID_id_ce, 2, &kObjectData[488], 0}, + {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", + NID_subject_key_identifier, 3, &kObjectData[490], 0}, + {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &kObjectData[493], 0}, + {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", + NID_private_key_usage_period, 3, &kObjectData[496], 0}, + {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, + 3, &kObjectData[499], 0}, + {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, + &kObjectData[502], 0}, + {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, + &kObjectData[505], 0}, + {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &kObjectData[508], 0}, + {"certificatePolicies", "X509v3 Certificate Policies", + NID_certificate_policies, 3, &kObjectData[511], 0}, + {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", + NID_authority_key_identifier, 3, &kObjectData[514], 0}, + {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &kObjectData[517], 0}, + {"BF-ECB", "bf-ecb", NID_bf_ecb, 0, NULL, 0}, + {"BF-CFB", "bf-cfb", NID_bf_cfb64, 0, NULL, 0}, + {"BF-OFB", "bf-ofb", NID_bf_ofb64, 0, NULL, 0}, + {"MDC2", "mdc2", NID_mdc2, 4, &kObjectData[526], 0}, + {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &kObjectData[530], 0}, + {"RC4-40", "rc4-40", NID_rc4_40, 0, NULL, 0}, + {"RC2-40-CBC", "rc2-40-cbc", NID_rc2_40_cbc, 0, NULL, 0}, + {"GN", "givenName", NID_givenName, 3, &kObjectData[534], 0}, + {"SN", "surname", NID_surname, 3, &kObjectData[537], 0}, + {"initials", "initials", NID_initials, 3, &kObjectData[540], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"crlDistributionPoints", "X509v3 CRL Distribution Points", + NID_crl_distribution_points, 3, &kObjectData[543], 0}, + {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &kObjectData[546], 0}, + {"serialNumber", "serialNumber", NID_serialNumber, 3, &kObjectData[551], 0}, + {"title", "title", NID_title, 3, &kObjectData[554], 0}, + {"description", "description", NID_description, 3, &kObjectData[557], 0}, + {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &kObjectData[560], 0}, + {"CAST5-ECB", "cast5-ecb", NID_cast5_ecb, 0, NULL, 0}, + {"CAST5-CFB", "cast5-cfb", NID_cast5_cfb64, 0, NULL, 0}, + {"CAST5-OFB", "cast5-ofb", NID_cast5_ofb64, 0, NULL, 0}, + {"pbeWithMD5AndCast5CBC", "pbeWithMD5AndCast5CBC", + NID_pbeWithMD5AndCast5_CBC, 9, &kObjectData[569], 0}, + {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &kObjectData[578], 0}, + {"MD5-SHA1", "md5-sha1", NID_md5_sha1, 0, NULL, 0}, + {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &kObjectData[585], 0}, + {"DSA", "dsaEncryption", NID_dsa, 7, &kObjectData[590], 0}, + {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &kObjectData[597], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, + &kObjectData[602], 0}, + {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &kObjectData[608], 0}, + {"RC5-ECB", "rc5-ecb", NID_rc5_ecb, 0, NULL, 0}, + {"RC5-CFB", "rc5-cfb", NID_rc5_cfb64, 0, NULL, 0}, + {"RC5-OFB", "rc5-ofb", NID_rc5_ofb64, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ZLIB", "zlib compression", NID_zlib_compression, 11, &kObjectData[616], + 0}, + {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, + &kObjectData[627], 0}, + {"PKIX", "PKIX", NID_id_pkix, 6, &kObjectData[630], 0}, + {"id-kp", "id-kp", NID_id_kp, 7, &kObjectData[636], 0}, + {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, + &kObjectData[643], 0}, + {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, + &kObjectData[651], 0}, + {"codeSigning", "Code Signing", NID_code_sign, 8, &kObjectData[659], 0}, + {"emailProtection", "E-mail Protection", NID_email_protect, 8, + &kObjectData[667], 0}, + {"timeStamping", "Time Stamping", NID_time_stamp, 8, &kObjectData[675], 0}, + {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, + &kObjectData[683], 0}, + {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, + &kObjectData[693], 0}, + {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, + &kObjectData[703], 0}, + {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, + &kObjectData[713], 0}, + {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, + &kObjectData[723], 0}, + {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &kObjectData[733], + 0}, + {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, + &kObjectData[742], 0}, + {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, + &kObjectData[745], 0}, + {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, + &kObjectData[748], 0}, + {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &kObjectData[751], 0}, + {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4, 10, &kObjectData[756], 0}, + {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, + 10, &kObjectData[766], 0}, + {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &kObjectData[776], 0}, + {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &kObjectData[786], 0}, + {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC, 10, &kObjectData[796], 0}, + {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC, 10, &kObjectData[806], 0}, + {"keyBag", "keyBag", NID_keyBag, 11, &kObjectData[816], 0}, + {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, + &kObjectData[827], 0}, + {"certBag", "certBag", NID_certBag, 11, &kObjectData[838], 0}, + {"crlBag", "crlBag", NID_crlBag, 11, &kObjectData[849], 0}, + {"secretBag", "secretBag", NID_secretBag, 11, &kObjectData[860], 0}, + {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, + &kObjectData[871], 0}, + {"friendlyName", "friendlyName", NID_friendlyName, 9, &kObjectData[882], 0}, + {"localKeyID", "localKeyID", NID_localKeyID, 9, &kObjectData[891], 0}, + {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, + &kObjectData[900], 0}, + {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, + &kObjectData[910], 0}, + {"x509Crl", "x509Crl", NID_x509Crl, 10, &kObjectData[920], 0}, + {"PBES2", "PBES2", NID_pbes2, 9, &kObjectData[930], 0}, + {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &kObjectData[939], 0}, + {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &kObjectData[948], 0}, + {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &kObjectData[956], + 0}, + {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, + &kObjectData[964], 0}, + {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc, 0, NULL, 0}, + {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, + &kObjectData[972], 0}, + {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, + &kObjectData[981], 0}, + {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, + &kObjectData[990], 0}, + {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, + &kObjectData[999], 0}, + {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, + &kObjectData[1008], 0}, + {"extReq", "Extension Request", NID_ext_req, 9, &kObjectData[1018], 0}, + {"name", "name", NID_name, 3, &kObjectData[1027], 0}, + {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &kObjectData[1030], 0}, + {"id-pe", "id-pe", NID_id_pe, 7, &kObjectData[1033], 0}, + {"id-ad", "id-ad", NID_id_ad, 7, &kObjectData[1040], 0}, + {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, + &kObjectData[1047], 0}, + {"OCSP", "OCSP", NID_ad_OCSP, 8, &kObjectData[1055], 0}, + {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &kObjectData[1063], 0}, + {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &kObjectData[1071], 0}, + {"ISO", "iso", NID_iso, 0, NULL, 0}, + {"member-body", "ISO Member Body", NID_member_body, 1, &kObjectData[1079], + 0}, + {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &kObjectData[1080], 0}, + {"X9-57", "X9.57", NID_X9_57, 5, &kObjectData[1083], 0}, + {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &kObjectData[1088], 0}, + {"pkcs1", "pkcs1", NID_pkcs1, 8, &kObjectData[1094], 0}, + {"pkcs5", "pkcs5", NID_pkcs5, 8, &kObjectData[1102], 0}, + {"SMIME", "S/MIME", NID_SMIME, 9, &kObjectData[1110], 0}, + {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &kObjectData[1119], + 0}, + {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &kObjectData[1129], 0}, + {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &kObjectData[1139], 0}, + {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &kObjectData[1149], + 0}, + {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &kObjectData[1159], 0}, + {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &kObjectData[1169], + 0}, + {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &kObjectData[1179], + 0}, + {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, + &kObjectData[1189], 0}, + {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, + &kObjectData[1200], 0}, + {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, + &kObjectData[1211], 0}, + {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, + &kObjectData[1222], 0}, + {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88, 11, &kObjectData[1233], 0}, + {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97, 11, &kObjectData[1244], 0}, + {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88, 11, &kObjectData[1255], 0}, + {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97, 11, &kObjectData[1266], 0}, + {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, + &kObjectData[1277], 0}, + {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, + 11, &kObjectData[1288], 0}, + {"id-smime-ct-publishCert", "id-smime-ct-publishCert", + NID_id_smime_ct_publishCert, 11, &kObjectData[1299], 0}, + {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, + &kObjectData[1310], 0}, + {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, + &kObjectData[1321], 0}, + {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo, 11, &kObjectData[1332], 0}, + {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData, 11, &kObjectData[1343], 0}, + {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData, 11, &kObjectData[1354], 0}, + {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest, 11, &kObjectData[1365], 0}, + {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel, 11, &kObjectData[1376], 0}, + {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory, 11, &kObjectData[1387], 0}, + {"id-smime-aa-contentHint", "id-smime-aa-contentHint", + NID_id_smime_aa_contentHint, 11, &kObjectData[1398], 0}, + {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest, 11, &kObjectData[1409], 0}, + {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType, 11, &kObjectData[1420], 0}, + {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier, 11, &kObjectData[1431], 0}, + {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, + 11, &kObjectData[1442], 0}, + {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels, 11, &kObjectData[1453], 0}, + {"id-smime-aa-contentReference", "id-smime-aa-contentReference", + NID_id_smime_aa_contentReference, 11, &kObjectData[1464], 0}, + {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref, 11, &kObjectData[1475], 0}, + {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate, 11, &kObjectData[1486], 0}, + {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts, 11, &kObjectData[1497], 0}, + {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken, 11, &kObjectData[1508], 0}, + {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId, 11, &kObjectData[1519], 0}, + {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType, 11, &kObjectData[1530], 0}, + {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation, 11, &kObjectData[1541], 0}, + {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr, 11, &kObjectData[1552], 0}, + {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert, 11, &kObjectData[1563], 0}, + {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp, 11, &kObjectData[1574], 0}, + {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs, 11, &kObjectData[1585], 0}, + {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs, 11, &kObjectData[1596], 0}, + {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues, 11, &kObjectData[1607], 0}, + {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues, 11, &kObjectData[1618], 0}, + {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp, 11, &kObjectData[1629], 0}, + {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp, 11, &kObjectData[1640], 0}, + {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp, 11, &kObjectData[1651], 0}, + {"id-smime-aa-signatureType", "id-smime-aa-signatureType", + NID_id_smime_aa_signatureType, 11, &kObjectData[1662], 0}, + {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, + 11, &kObjectData[1673], 0}, + {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES, 11, &kObjectData[1684], 0}, + {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2, 11, &kObjectData[1695], 0}, + {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap, 11, &kObjectData[1706], 0}, + {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, + 11, &kObjectData[1717], 0}, + {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, + &kObjectData[1728], 0}, + {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap, 11, &kObjectData[1739], 0}, + {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap, 11, &kObjectData[1750], 0}, + {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, + &kObjectData[1761], 0}, + {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri, 11, &kObjectData[1772], 0}, + {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice, 11, &kObjectData[1783], 0}, + {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin, 11, &kObjectData[1794], 0}, + {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt, 11, &kObjectData[1805], 0}, + {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery, 11, &kObjectData[1816], 0}, + {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender, 11, &kObjectData[1827], 0}, + {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval, 11, &kObjectData[1838], 0}, + {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation, 11, &kObjectData[1849], 0}, + {"MD4", "md4", NID_md4, 8, &kObjectData[1860], 0}, + {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &kObjectData[1868], 0}, + {"id-qt", "id-qt", NID_id_qt, 7, &kObjectData[1875], 0}, + {"id-it", "id-it", NID_id_it, 7, &kObjectData[1882], 0}, + {"id-pkip", "id-pkip", NID_id_pkip, 7, &kObjectData[1889], 0}, + {"id-alg", "id-alg", NID_id_alg, 7, &kObjectData[1896], 0}, + {"id-cmc", "id-cmc", NID_id_cmc, 7, &kObjectData[1903], 0}, + {"id-on", "id-on", NID_id_on, 7, &kObjectData[1910], 0}, + {"id-pda", "id-pda", NID_id_pda, 7, &kObjectData[1917], 0}, + {"id-aca", "id-aca", NID_id_aca, 7, &kObjectData[1924], 0}, + {"id-qcs", "id-qcs", NID_id_qcs, 7, &kObjectData[1931], 0}, + {"id-cct", "id-cct", NID_id_cct, 7, &kObjectData[1938], 0}, + {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, + 8, &kObjectData[1945], 0}, + {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, + 8, &kObjectData[1953], 0}, + {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, + 8, &kObjectData[1961], 0}, + {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, + 8, &kObjectData[1969], 0}, + {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &kObjectData[1977], 0}, + {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &kObjectData[1985], 0}, + {"id-mod-kea-profile-88", "id-mod-kea-profile-88", + NID_id_mod_kea_profile_88, 8, &kObjectData[1993], 0}, + {"id-mod-kea-profile-93", "id-mod-kea-profile-93", + NID_id_mod_kea_profile_93, 8, &kObjectData[2001], 0}, + {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &kObjectData[2009], 0}, + {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88, 8, &kObjectData[2017], 0}, + {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93, 8, &kObjectData[2025], 0}, + {"id-mod-attribute-cert", "id-mod-attribute-cert", + NID_id_mod_attribute_cert, 8, &kObjectData[2033], 0}, + {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol, 8, &kObjectData[2041], 0}, + {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &kObjectData[2049], 0}, + {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &kObjectData[2057], 0}, + {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, + &kObjectData[2065], 0}, + {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, + &kObjectData[2073], 0}, + {"qcStatements", "qcStatements", NID_qcStatements, 8, &kObjectData[2081], + 0}, + {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, + &kObjectData[2089], 0}, + {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &kObjectData[2097], + 0}, + {"aaControls", "aaControls", NID_aaControls, 8, &kObjectData[2105], 0}, + {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, + &kObjectData[2113], 0}, + {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum, 8, &kObjectData[2121], 0}, + {"sbgp-routerIdentifier", "sbgp-routerIdentifier", + NID_sbgp_routerIdentifier, 8, &kObjectData[2129], 0}, + {"textNotice", "textNotice", NID_textNotice, 8, &kObjectData[2137], 0}, + {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, + &kObjectData[2145], 0}, + {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &kObjectData[2153], 0}, + {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &kObjectData[2161], 0}, + {"DVCS", "dvcs", NID_dvcs, 8, &kObjectData[2169], 0}, + {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, + &kObjectData[2177], 0}, + {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes, 8, &kObjectData[2185], 0}, + {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes, 8, &kObjectData[2193], 0}, + {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg, 8, &kObjectData[2201], 0}, + {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo, 8, &kObjectData[2209], 0}, + {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, + &kObjectData[2217], 0}, + {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs, 8, &kObjectData[2225], 0}, + {"id-it-subscriptionRequest", "id-it-subscriptionRequest", + NID_id_it_subscriptionRequest, 8, &kObjectData[2233], 0}, + {"id-it-subscriptionResponse", "id-it-subscriptionResponse", + NID_id_it_subscriptionResponse, 8, &kObjectData[2241], 0}, + {"id-it-keyPairParamReq", "id-it-keyPairParamReq", + NID_id_it_keyPairParamReq, 8, &kObjectData[2249], 0}, + {"id-it-keyPairParamRep", "id-it-keyPairParamRep", + NID_id_it_keyPairParamRep, 8, &kObjectData[2257], 0}, + {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, + &kObjectData[2265], 0}, + {"id-it-implicitConfirm", "id-it-implicitConfirm", + NID_id_it_implicitConfirm, 8, &kObjectData[2273], 0}, + {"id-it-confirmWaitTime", "id-it-confirmWaitTime", + NID_id_it_confirmWaitTime, 8, &kObjectData[2281], 0}, + {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, + 8, &kObjectData[2289], 0}, + {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &kObjectData[2297], 0}, + {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &kObjectData[2305], 0}, + {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, + &kObjectData[2313], 0}, + {"id-regCtrl-authenticator", "id-regCtrl-authenticator", + NID_id_regCtrl_authenticator, 9, &kObjectData[2322], 0}, + {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo, 9, &kObjectData[2331], 0}, + {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions, 9, &kObjectData[2340], 0}, + {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, + 9, &kObjectData[2349], 0}, + {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey, 9, &kObjectData[2358], 0}, + {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, + 9, &kObjectData[2367], 0}, + {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, + &kObjectData[2376], 0}, + {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &kObjectData[2385], + 0}, + {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, + &kObjectData[2393], 0}, + {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1, 8, &kObjectData[2401], 0}, + {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &kObjectData[2409], + 0}, + {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, + &kObjectData[2417], 0}, + {"id-cmc-identification", "id-cmc-identification", + NID_id_cmc_identification, 8, &kObjectData[2425], 0}, + {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, + 8, &kObjectData[2433], 0}, + {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, + &kObjectData[2441], 0}, + {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, + 8, &kObjectData[2449], 0}, + {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, + &kObjectData[2457], 0}, + {"id-cmc-recipientNonce", "id-cmc-recipientNonce", + NID_id_cmc_recipientNonce, 8, &kObjectData[2465], 0}, + {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, + 8, &kObjectData[2473], 0}, + {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, + &kObjectData[2481], 0}, + {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, + &kObjectData[2489], 0}, + {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, + 8, &kObjectData[2497], 0}, + {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, + &kObjectData[2505], 0}, + {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &kObjectData[2513], + 0}, + {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, + 8, &kObjectData[2521], 0}, + {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, + &kObjectData[2529], 0}, + {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, + &kObjectData[2537], 0}, + {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, + &kObjectData[2545], 0}, + {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, + 8, &kObjectData[2553], 0}, + {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness, 8, &kObjectData[2561], 0}, + {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance, 8, &kObjectData[2569], 0}, + {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, + &kObjectData[2577], 0}, + {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, + &kObjectData[2585], 0}, + {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, + &kObjectData[2593], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &kObjectData[2601], + 0}, + {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship, 8, &kObjectData[2609], 0}, + {"id-pda-countryOfResidence", "id-pda-countryOfResidence", + NID_id_pda_countryOfResidence, 8, &kObjectData[2617], 0}, + {"id-aca-authenticationInfo", "id-aca-authenticationInfo", + NID_id_aca_authenticationInfo, 8, &kObjectData[2625], 0}, + {"id-aca-accessIdentity", "id-aca-accessIdentity", + NID_id_aca_accessIdentity, 8, &kObjectData[2633], 0}, + {"id-aca-chargingIdentity", "id-aca-chargingIdentity", + NID_id_aca_chargingIdentity, 8, &kObjectData[2641], 0}, + {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &kObjectData[2649], + 0}, + {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &kObjectData[2657], 0}, + {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1, 8, &kObjectData[2665], 0}, + {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &kObjectData[2673], 0}, + {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, + &kObjectData[2681], 0}, + {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, + &kObjectData[2689], 0}, + {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, + &kObjectData[2697], 0}, + {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &kObjectData[2705], 0}, + {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, + &kObjectData[2713], 0}, + {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &kObjectData[2722], 0}, + {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &kObjectData[2731], 0}, + {"acceptableResponses", "Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses, 9, &kObjectData[2740], 0}, + {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, + &kObjectData[2749], 0}, + {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, + &kObjectData[2758], 0}, + {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, + 9, &kObjectData[2767], 0}, + {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, + 9, &kObjectData[2776], 0}, + {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &kObjectData[2785], 0}, + {"path", "path", NID_id_pkix_OCSP_path, 9, &kObjectData[2794], 0}, + {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, + &kObjectData[2803], 0}, + {"algorithm", "algorithm", NID_algorithm, 4, &kObjectData[2812], 0}, + {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &kObjectData[2816], + 0}, + {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, + &kObjectData[2821], 0}, + {"ORG", "org", NID_org, 1, &kObjectData[2823], 0}, + {"DOD", "dod", NID_dod, 2, &kObjectData[2824], 0}, + {"IANA", "iana", NID_iana, 3, &kObjectData[2826], 0}, + {"directory", "Directory", NID_Directory, 4, &kObjectData[2829], 0}, + {"mgmt", "Management", NID_Management, 4, &kObjectData[2833], 0}, + {"experimental", "Experimental", NID_Experimental, 4, &kObjectData[2837], + 0}, + {"private", "Private", NID_Private, 4, &kObjectData[2841], 0}, + {"security", "Security", NID_Security, 4, &kObjectData[2845], 0}, + {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &kObjectData[2849], 0}, + {"Mail", "Mail", NID_Mail, 4, &kObjectData[2853], 0}, + {"enterprises", "Enterprises", NID_Enterprises, 5, &kObjectData[2857], 0}, + {"dcobject", "dcObject", NID_dcObject, 9, &kObjectData[2862], 0}, + {"DC", "domainComponent", NID_domainComponent, 10, &kObjectData[2871], 0}, + {"domain", "Domain", NID_Domain, 10, &kObjectData[2881], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"selected-attribute-types", "Selected Attribute Types", + NID_selected_attribute_types, 3, &kObjectData[2891], 0}, + {"clearance", "clearance", NID_clearance, 4, &kObjectData[2894], 0}, + {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, + &kObjectData[2898], 0}, + {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &kObjectData[2907], 0}, + {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, + &kObjectData[2915], 0}, + {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, + &kObjectData[2923], 0}, + {"role", "role", NID_role, 3, &kObjectData[2931], 0}, + {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, + 3, &kObjectData[2934], 0}, + {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, + &kObjectData[2937], 0}, + {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, + &kObjectData[2940], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &kObjectData[2943], 0}, + {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &kObjectData[2948], + 0}, + {"characteristic-two-field", "characteristic-two-field", + NID_X9_62_characteristic_two_field, 7, &kObjectData[2955], 0}, + {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, + &kObjectData[2962], 0}, + {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &kObjectData[2969], + 0}, + {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &kObjectData[2977], + 0}, + {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &kObjectData[2985], + 0}, + {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &kObjectData[2993], + 0}, + {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &kObjectData[3001], + 0}, + {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &kObjectData[3009], + 0}, + {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &kObjectData[3017], + 0}, + {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, + &kObjectData[3025], 0}, + {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &kObjectData[3032], + 0}, + {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &kObjectData[3041], 0}, + {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &kObjectData[3050], 0}, + {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &kObjectData[3059], + 0}, + {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &kObjectData[3068], + 0}, + {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &kObjectData[3077], 0}, + {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &kObjectData[3086], 0}, + {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &kObjectData[3095], + 0}, + {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &kObjectData[3104], + 0}, + {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &kObjectData[3113], 0}, + {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &kObjectData[3122], 0}, + {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &kObjectData[3131], + 0}, + {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &kObjectData[3140], + 0}, + {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, + 3, &kObjectData[3149], 0}, + {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, + 7, &kObjectData[3152], 0}, + {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer, 7, &kObjectData[3159], 0}, + {"holdInstructionReject", "Hold Instruction Reject", + NID_hold_instruction_reject, 7, &kObjectData[3166], 0}, + {"data", "data", NID_data, 1, &kObjectData[3173], 0}, + {"pss", "pss", NID_pss, 3, &kObjectData[3174], 0}, + {"ucl", "ucl", NID_ucl, 7, &kObjectData[3177], 0}, + {"pilot", "pilot", NID_pilot, 8, &kObjectData[3184], 0}, + {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, + &kObjectData[3192], 0}, + {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, + 9, &kObjectData[3201], 0}, + {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, + &kObjectData[3210], 0}, + {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &kObjectData[3219], 0}, + {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, + &kObjectData[3228], 0}, + {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax, 10, &kObjectData[3238], 0}, + {"pilotObject", "pilotObject", NID_pilotObject, 10, &kObjectData[3248], 0}, + {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &kObjectData[3258], 0}, + {"account", "account", NID_account, 10, &kObjectData[3268], 0}, + {"document", "document", NID_document, 10, &kObjectData[3278], 0}, + {"room", "room", NID_room, 10, &kObjectData[3288], 0}, + {"documentSeries", "documentSeries", NID_documentSeries, 10, + &kObjectData[3298], 0}, + {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, + &kObjectData[3308], 0}, + {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &kObjectData[3318], 0}, + {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, + &kObjectData[3328], 0}, + {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, + &kObjectData[3338], 0}, + {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, + 10, &kObjectData[3348], 0}, + {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, + &kObjectData[3358], 0}, + {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &kObjectData[3368], 0}, + {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, + &kObjectData[3378], 0}, + {"UID", "userId", NID_userId, 10, &kObjectData[3388], 0}, + {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, + 10, &kObjectData[3398], 0}, + {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &kObjectData[3408], 0}, + {"info", "info", NID_info, 10, &kObjectData[3418], 0}, + {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, + &kObjectData[3428], 0}, + {"roomNumber", "roomNumber", NID_roomNumber, 10, &kObjectData[3438], 0}, + {"photo", "photo", NID_photo, 10, &kObjectData[3448], 0}, + {"userClass", "userClass", NID_userClass, 10, &kObjectData[3458], 0}, + {"host", "host", NID_host, 10, &kObjectData[3468], 0}, + {"manager", "manager", NID_manager, 10, &kObjectData[3478], 0}, + {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, + &kObjectData[3488], 0}, + {"documentTitle", "documentTitle", NID_documentTitle, 10, + &kObjectData[3498], 0}, + {"documentVersion", "documentVersion", NID_documentVersion, 10, + &kObjectData[3508], 0}, + {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, + &kObjectData[3518], 0}, + {"documentLocation", "documentLocation", NID_documentLocation, 10, + &kObjectData[3528], 0}, + {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, + &kObjectData[3538], 0}, + {"secretary", "secretary", NID_secretary, 10, &kObjectData[3548], 0}, + {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &kObjectData[3558], + 0}, + {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, + &kObjectData[3568], 0}, + {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, + &kObjectData[3578], 0}, + {"aRecord", "aRecord", NID_aRecord, 10, &kObjectData[3588], 0}, + {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, + 10, &kObjectData[3598], 0}, + {"mXRecord", "mXRecord", NID_mXRecord, 10, &kObjectData[3608], 0}, + {"nSRecord", "nSRecord", NID_nSRecord, 10, &kObjectData[3618], 0}, + {"sOARecord", "sOARecord", NID_sOARecord, 10, &kObjectData[3628], 0}, + {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &kObjectData[3638], 0}, + {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, + &kObjectData[3648], 0}, + {"associatedName", "associatedName", NID_associatedName, 10, + &kObjectData[3658], 0}, + {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, + &kObjectData[3668], 0}, + {"personalTitle", "personalTitle", NID_personalTitle, 10, + &kObjectData[3678], 0}, + {"mobileTelephoneNumber", "mobileTelephoneNumber", + NID_mobileTelephoneNumber, 10, &kObjectData[3688], 0}, + {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, + 10, &kObjectData[3698], 0}, + {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, + &kObjectData[3708], 0}, + {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, + 10, &kObjectData[3718], 0}, + {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &kObjectData[3728], + 0}, + {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, + 10, &kObjectData[3738], 0}, + {"buildingName", "buildingName", NID_buildingName, 10, &kObjectData[3748], + 0}, + {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &kObjectData[3758], 0}, + {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, + &kObjectData[3768], 0}, + {"subtreeMinimumQuality", "subtreeMinimumQuality", + NID_subtreeMinimumQuality, 10, &kObjectData[3778], 0}, + {"subtreeMaximumQuality", "subtreeMaximumQuality", + NID_subtreeMaximumQuality, 10, &kObjectData[3788], 0}, + {"personalSignature", "personalSignature", NID_personalSignature, 10, + &kObjectData[3798], 0}, + {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &kObjectData[3808], 0}, + {"audio", "audio", NID_audio, 10, &kObjectData[3818], 0}, + {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, + &kObjectData[3828], 0}, + {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, + 3, &kObjectData[3838], 0}, + {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &kObjectData[3841], 0}, + {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, + &kObjectData[3846], 0}, + {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, + &kObjectData[3852], 0}, + {"id-hex-partial-message", "id-hex-partial-message", + NID_id_hex_partial_message, 7, &kObjectData[3858], 0}, + {"id-hex-multipart-message", "id-hex-multipart-message", + NID_id_hex_multipart_message, 7, &kObjectData[3865], 0}, + {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, + &kObjectData[3872], 0}, + {"pseudonym", "pseudonym", NID_pseudonym, 3, &kObjectData[3875], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-set", "Secure Electronic Transactions", NID_id_set, 2, + &kObjectData[3878], 0}, + {"set-ctype", "content types", NID_set_ctype, 3, &kObjectData[3880], 0}, + {"set-msgExt", "message extensions", NID_set_msgExt, 3, &kObjectData[3883], + 0}, + {"set-attr", "set-attr", NID_set_attr, 3, &kObjectData[3886], 0}, + {"set-policy", "set-policy", NID_set_policy, 3, &kObjectData[3889], 0}, + {"set-certExt", "certificate extensions", NID_set_certExt, 3, + &kObjectData[3892], 0}, + {"set-brand", "set-brand", NID_set_brand, 3, &kObjectData[3895], 0}, + {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &kObjectData[3898], + 0}, + {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, + &kObjectData[3902], 0}, + {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &kObjectData[3906], + 0}, + {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &kObjectData[3910], + 0}, + {"setct-PI", "setct-PI", NID_setct_PI, 4, &kObjectData[3914], 0}, + {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &kObjectData[3918], + 0}, + {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, + 4, &kObjectData[3922], 0}, + {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, + &kObjectData[3926], 0}, + {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, + 4, &kObjectData[3930], 0}, + {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage, 4, &kObjectData[3934], 0}, + {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage, 4, &kObjectData[3938], 0}, + {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, + &kObjectData[3942], 0}, + {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, + &kObjectData[3946], 0}, + {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &kObjectData[3950], + 0}, + {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, + &kObjectData[3954], 0}, + {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, + &kObjectData[3958], 0}, + {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, + &kObjectData[3962], 0}, + {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, + &kObjectData[3966], 0}, + {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, + &kObjectData[3970], 0}, + {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, + &kObjectData[3974], 0}, + {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, + &kObjectData[3978], 0}, + {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, + 4, &kObjectData[3982], 0}, + {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, + &kObjectData[3986], 0}, + {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, + 4, &kObjectData[3990], 0}, + {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, + &kObjectData[3994], 0}, + {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, + &kObjectData[3998], 0}, + {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, + &kObjectData[4002], 0}, + {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, + &kObjectData[4006], 0}, + {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, + &kObjectData[4010], 0}, + {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, + &kObjectData[4014], 0}, + {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, + &kObjectData[4018], 0}, + {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, + &kObjectData[4022], 0}, + {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, + &kObjectData[4026], 0}, + {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, + &kObjectData[4030], 0}, + {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, + &kObjectData[4034], 0}, + {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, + 4, &kObjectData[4038], 0}, + {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, + 4, &kObjectData[4042], 0}, + {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, + &kObjectData[4046], 0}, + {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, + &kObjectData[4050], 0}, + {"setct-BatchAdminReqData", "setct-BatchAdminReqData", + NID_setct_BatchAdminReqData, 4, &kObjectData[4054], 0}, + {"setct-BatchAdminResData", "setct-BatchAdminResData", + NID_setct_BatchAdminResData, 4, &kObjectData[4058], 0}, + {"setct-CardCInitResTBS", "setct-CardCInitResTBS", + NID_setct_CardCInitResTBS, 4, &kObjectData[4062], 0}, + {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS, 4, &kObjectData[4066], 0}, + {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, + &kObjectData[4070], 0}, + {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, + &kObjectData[4074], 0}, + {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, + &kObjectData[4078], 0}, + {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, + &kObjectData[4082], 0}, + {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, + &kObjectData[4086], 0}, + {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, + &kObjectData[4090], 0}, + {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE, 4, &kObjectData[4094], 0}, + {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, + &kObjectData[4098], 0}, + {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, + &kObjectData[4102], 0}, + {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, + &kObjectData[4106], 0}, + {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, + &kObjectData[4110], 0}, + {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, + &kObjectData[4114], 0}, + {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, + &kObjectData[4118], 0}, + {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, + &kObjectData[4122], 0}, + {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE, 4, &kObjectData[4126], 0}, + {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, + &kObjectData[4130], 0}, + {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, + &kObjectData[4134], 0}, + {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, + 4, &kObjectData[4138], 0}, + {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, + &kObjectData[4142], 0}, + {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, + &kObjectData[4146], 0}, + {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, + &kObjectData[4150], 0}, + {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, + &kObjectData[4154], 0}, + {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, + &kObjectData[4158], 0}, + {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, + &kObjectData[4162], 0}, + {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, + &kObjectData[4166], 0}, + {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, + &kObjectData[4170], 0}, + {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, + &kObjectData[4174], 0}, + {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, + &kObjectData[4178], 0}, + {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, + 4, &kObjectData[4182], 0}, + {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, + &kObjectData[4186], 0}, + {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE, 4, &kObjectData[4190], 0}, + {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE, 4, &kObjectData[4194], 0}, + {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, + &kObjectData[4198], 0}, + {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, + &kObjectData[4202], 0}, + {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, + &kObjectData[4206], 0}, + {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, + &kObjectData[4210], 0}, + {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS, 4, &kObjectData[4214], 0}, + {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS, 4, &kObjectData[4218], 0}, + {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS, 4, &kObjectData[4222], 0}, + {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, + &kObjectData[4226], 0}, + {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, + &kObjectData[4230], 0}, + {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, + &kObjectData[4234], 0}, + {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &kObjectData[4238], + 0}, + {"setext-track2", "setext-track2", NID_setext_track2, 4, &kObjectData[4242], + 0}, + {"setext-cv", "additional verification", NID_setext_cv, 4, + &kObjectData[4246], 0}, + {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, + &kObjectData[4250], 0}, + {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, + &kObjectData[4254], 0}, + {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, + &kObjectData[4258], 0}, + {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, + &kObjectData[4262], 0}, + {"setCext-cCertRequired", "setCext-cCertRequired", + NID_setCext_cCertRequired, 4, &kObjectData[4266], 0}, + {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, + &kObjectData[4270], 0}, + {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, + &kObjectData[4274], 0}, + {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, + &kObjectData[4278], 0}, + {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities, 4, &kObjectData[4282], 0}, + {"setCext-TokenIdentifier", "setCext-TokenIdentifier", + NID_setCext_TokenIdentifier, 4, &kObjectData[4286], 0}, + {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, + &kObjectData[4290], 0}, + {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, + &kObjectData[4294], 0}, + {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities, 4, &kObjectData[4298], 0}, + {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &kObjectData[4302], + 0}, + {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, + &kObjectData[4306], 0}, + {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, + &kObjectData[4310], 0}, + {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, + &kObjectData[4314], 0}, + {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, + &kObjectData[4318], 0}, + {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &kObjectData[4323], + 0}, + {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, + &kObjectData[4328], 0}, + {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime, 5, &kObjectData[4333], 0}, + {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, + &kObjectData[4338], 0}, + {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, + &kObjectData[4343], 0}, + {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, + &kObjectData[4348], 0}, + {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, + &kObjectData[4353], 0}, + {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, + &kObjectData[4359], 0}, + {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, + &kObjectData[4365], 0}, + {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, + &kObjectData[4371], 0}, + {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, + &kObjectData[4377], 0}, + {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, + &kObjectData[4383], 0}, + {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, + &kObjectData[4387], 0}, + {"set-brand-AmericanExpress", "set-brand-AmericanExpress", + NID_set_brand_AmericanExpress, 4, &kObjectData[4391], 0}, + {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &kObjectData[4395], + 0}, + {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, + &kObjectData[4399], 0}, + {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, + 4, &kObjectData[4403], 0}, + {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, + &kObjectData[4407], 0}, + {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &kObjectData[4412], 0}, + {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, + 9, &kObjectData[4420], 0}, + {"ITU-T", "itu-t", NID_itu_t, 0, NULL, 0}, + {"JOINT-ISO-ITU-T", "joint-iso-itu-t", NID_joint_iso_itu_t, 0, NULL, 0}, + {"international-organizations", "International Organizations", + NID_international_organizations, 1, &kObjectData[4429], 0}, + {"msSmartcardLogin", "Microsoft Smartcardlogin", NID_ms_smartcard_login, 10, + &kObjectData[4430], 0}, + {"msUPN", "Microsoft Universal Principal Name", NID_ms_upn, 10, + &kObjectData[4440], 0}, + {"AES-128-CFB1", "aes-128-cfb1", NID_aes_128_cfb1, 0, NULL, 0}, + {"AES-192-CFB1", "aes-192-cfb1", NID_aes_192_cfb1, 0, NULL, 0}, + {"AES-256-CFB1", "aes-256-cfb1", NID_aes_256_cfb1, 0, NULL, 0}, + {"AES-128-CFB8", "aes-128-cfb8", NID_aes_128_cfb8, 0, NULL, 0}, + {"AES-192-CFB8", "aes-192-cfb8", NID_aes_192_cfb8, 0, NULL, 0}, + {"AES-256-CFB8", "aes-256-cfb8", NID_aes_256_cfb8, 0, NULL, 0}, + {"DES-CFB1", "des-cfb1", NID_des_cfb1, 0, NULL, 0}, + {"DES-CFB8", "des-cfb8", NID_des_cfb8, 0, NULL, 0}, + {"DES-EDE3-CFB1", "des-ede3-cfb1", NID_des_ede3_cfb1, 0, NULL, 0}, + {"DES-EDE3-CFB8", "des-ede3-cfb8", NID_des_ede3_cfb8, 0, NULL, 0}, + {"street", "streetAddress", NID_streetAddress, 3, &kObjectData[4450], 0}, + {"postalCode", "postalCode", NID_postalCode, 3, &kObjectData[4453], 0}, + {"id-ppl", "id-ppl", NID_id_ppl, 7, &kObjectData[4456], 0}, + {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, + &kObjectData[4463], 0}, + {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, + &kObjectData[4471], 0}, + {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, + &kObjectData[4479], 0}, + {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, + &kObjectData[4487], 0}, + {"id-ppl-independent", "Independent", NID_Independent, 8, + &kObjectData[4490], 0}, + {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, + &kObjectData[4498], 0}, + {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, + &kObjectData[4507], 0}, + {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, + &kObjectData[4516], 0}, + {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, + &kObjectData[4525], 0}, + {"SHA256", "sha256", NID_sha256, 9, &kObjectData[4534], 0}, + {"SHA384", "sha384", NID_sha384, 9, &kObjectData[4543], 0}, + {"SHA512", "sha512", NID_sha512, 9, &kObjectData[4552], 0}, + {"SHA224", "sha224", NID_sha224, 9, &kObjectData[4561], 0}, + {"identified-organization", "identified-organization", + NID_identified_organization, 1, &kObjectData[4570], 0}, + {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &kObjectData[4571], + 0}, + {"wap", "wap", NID_wap, 2, &kObjectData[4574], 0}, + {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &kObjectData[4576], 0}, + {"id-characteristic-two-basis", "id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis, 8, &kObjectData[4579], 0}, + {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &kObjectData[4587], 0}, + {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &kObjectData[4596], 0}, + {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &kObjectData[4605], 0}, + {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &kObjectData[4614], + 0}, + {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &kObjectData[4622], + 0}, + {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &kObjectData[4630], + 0}, + {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &kObjectData[4638], + 0}, + {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &kObjectData[4646], + 0}, + {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &kObjectData[4654], + 0}, + {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &kObjectData[4662], + 0}, + {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &kObjectData[4670], + 0}, + {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &kObjectData[4678], + 0}, + {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &kObjectData[4686], + 0}, + {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &kObjectData[4694], + 0}, + {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &kObjectData[4702], + 0}, + {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &kObjectData[4710], + 0}, + {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &kObjectData[4718], + 0}, + {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &kObjectData[4726], + 0}, + {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &kObjectData[4734], + 0}, + {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &kObjectData[4742], + 0}, + {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &kObjectData[4750], + 0}, + {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &kObjectData[4758], + 0}, + {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &kObjectData[4766], + 0}, + {"secp112r1", "secp112r1", NID_secp112r1, 5, &kObjectData[4774], 0}, + {"secp112r2", "secp112r2", NID_secp112r2, 5, &kObjectData[4779], 0}, + {"secp128r1", "secp128r1", NID_secp128r1, 5, &kObjectData[4784], 0}, + {"secp128r2", "secp128r2", NID_secp128r2, 5, &kObjectData[4789], 0}, + {"secp160k1", "secp160k1", NID_secp160k1, 5, &kObjectData[4794], 0}, + {"secp160r1", "secp160r1", NID_secp160r1, 5, &kObjectData[4799], 0}, + {"secp160r2", "secp160r2", NID_secp160r2, 5, &kObjectData[4804], 0}, + {"secp192k1", "secp192k1", NID_secp192k1, 5, &kObjectData[4809], 0}, + {"secp224k1", "secp224k1", NID_secp224k1, 5, &kObjectData[4814], 0}, + {"secp224r1", "secp224r1", NID_secp224r1, 5, &kObjectData[4819], 0}, + {"secp256k1", "secp256k1", NID_secp256k1, 5, &kObjectData[4824], 0}, + {"secp384r1", "secp384r1", NID_secp384r1, 5, &kObjectData[4829], 0}, + {"secp521r1", "secp521r1", NID_secp521r1, 5, &kObjectData[4834], 0}, + {"sect113r1", "sect113r1", NID_sect113r1, 5, &kObjectData[4839], 0}, + {"sect113r2", "sect113r2", NID_sect113r2, 5, &kObjectData[4844], 0}, + {"sect131r1", "sect131r1", NID_sect131r1, 5, &kObjectData[4849], 0}, + {"sect131r2", "sect131r2", NID_sect131r2, 5, &kObjectData[4854], 0}, + {"sect163k1", "sect163k1", NID_sect163k1, 5, &kObjectData[4859], 0}, + {"sect163r1", "sect163r1", NID_sect163r1, 5, &kObjectData[4864], 0}, + {"sect163r2", "sect163r2", NID_sect163r2, 5, &kObjectData[4869], 0}, + {"sect193r1", "sect193r1", NID_sect193r1, 5, &kObjectData[4874], 0}, + {"sect193r2", "sect193r2", NID_sect193r2, 5, &kObjectData[4879], 0}, + {"sect233k1", "sect233k1", NID_sect233k1, 5, &kObjectData[4884], 0}, + {"sect233r1", "sect233r1", NID_sect233r1, 5, &kObjectData[4889], 0}, + {"sect239k1", "sect239k1", NID_sect239k1, 5, &kObjectData[4894], 0}, + {"sect283k1", "sect283k1", NID_sect283k1, 5, &kObjectData[4899], 0}, + {"sect283r1", "sect283r1", NID_sect283r1, 5, &kObjectData[4904], 0}, + {"sect409k1", "sect409k1", NID_sect409k1, 5, &kObjectData[4909], 0}, + {"sect409r1", "sect409r1", NID_sect409r1, 5, &kObjectData[4914], 0}, + {"sect571k1", "sect571k1", NID_sect571k1, 5, &kObjectData[4919], 0}, + {"sect571r1", "sect571r1", NID_sect571r1, 5, &kObjectData[4924], 0}, + {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1, 5, &kObjectData[4929], 0}, + {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3, 5, &kObjectData[4934], 0}, + {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4, 5, &kObjectData[4939], 0}, + {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5, 5, &kObjectData[4944], 0}, + {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6, 5, &kObjectData[4949], 0}, + {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7, 5, &kObjectData[4954], 0}, + {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8, 5, &kObjectData[4959], 0}, + {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9, 5, &kObjectData[4964], 0}, + {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10, 5, &kObjectData[4969], 0}, + {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11, 5, &kObjectData[4974], 0}, + {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12, 5, &kObjectData[4979], 0}, + {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &kObjectData[4984], + 0}, + {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, + &kObjectData[4988], 0}, + {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, + &kObjectData[4991], 0}, + {"Oakley-EC2N-3", "ipsec3", NID_ipsec3, 0, NULL, 0}, + {"Oakley-EC2N-4", "ipsec4", NID_ipsec4, 0, NULL, 0}, + {"CAMELLIA-128-CBC", "camellia-128-cbc", NID_camellia_128_cbc, 11, + &kObjectData[4994], 0}, + {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, + &kObjectData[5005], 0}, + {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, + &kObjectData[5016], 0}, + {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, + &kObjectData[5027], 0}, + {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, + &kObjectData[5035], 0}, + {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, + &kObjectData[5043], 0}, + {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, + &kObjectData[5051], 0}, + {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, + &kObjectData[5059], 0}, + {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, + &kObjectData[5067], 0}, + {"CAMELLIA-128-CFB1", "camellia-128-cfb1", NID_camellia_128_cfb1, 0, NULL, + 0}, + {"CAMELLIA-192-CFB1", "camellia-192-cfb1", NID_camellia_192_cfb1, 0, NULL, + 0}, + {"CAMELLIA-256-CFB1", "camellia-256-cfb1", NID_camellia_256_cfb1, 0, NULL, + 0}, + {"CAMELLIA-128-CFB8", "camellia-128-cfb8", NID_camellia_128_cfb8, 0, NULL, + 0}, + {"CAMELLIA-192-CFB8", "camellia-192-cfb8", NID_camellia_192_cfb8, 0, NULL, + 0}, + {"CAMELLIA-256-CFB8", "camellia-256-cfb8", NID_camellia_256_cfb8, 0, NULL, + 0}, + {"CAMELLIA-128-OFB", "camellia-128-ofb", NID_camellia_128_ofb128, 8, + &kObjectData[5075], 0}, + {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, + &kObjectData[5083], 0}, + {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, + &kObjectData[5091], 0}, + {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", + NID_subject_directory_attributes, 3, &kObjectData[5099], 0}, + {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", + NID_issuing_distribution_point, 3, &kObjectData[5102], 0}, + {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, + 3, &kObjectData[5105], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"KISA", "kisa", NID_kisa, 6, &kObjectData[5108], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &kObjectData[5114], 0}, + {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &kObjectData[5122], 0}, + {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &kObjectData[5130], 0}, + {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &kObjectData[5138], 0}, + {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &kObjectData[5146], 0}, + {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &kObjectData[5154], 0}, + {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, + &kObjectData[5162], 0}, + {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, + &kObjectData[5171], 0}, + {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, + &kObjectData[5180], 0}, + {"caRepository", "CA Repository", NID_caRepository, 8, &kObjectData[5188], + 0}, + {"id-smime-ct-compressedData", "id-smime-ct-compressedData", + NID_id_smime_ct_compressedData, 11, &kObjectData[5196], 0}, + {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF, 11, &kObjectData[5207], 0}, + {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, + &kObjectData[5218], 0}, + {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, + &kObjectData[5227], 0}, + {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, + &kObjectData[5236], 0}, + {"ecdsa-with-Recommended", "ecdsa-with-Recommended", + NID_ecdsa_with_Recommended, 7, &kObjectData[5245], 0}, + {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, + 7, &kObjectData[5252], 0}, + {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, + &kObjectData[5259], 0}, + {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, + &kObjectData[5267], 0}, + {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, + &kObjectData[5275], 0}, + {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, + &kObjectData[5283], 0}, + {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &kObjectData[5291], 0}, + {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, + &kObjectData[5299], 0}, + {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, + &kObjectData[5307], 0}, + {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, + &kObjectData[5315], 0}, + {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, + &kObjectData[5323], 0}, + {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, + &kObjectData[5331], 0}, + {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, + &kObjectData[5340], 0}, + {"whirlpool", "whirlpool", NID_whirlpool, 6, &kObjectData[5349], 0}, + {"cryptopro", "cryptopro", NID_cryptopro, 5, &kObjectData[5355], 0}, + {"cryptocom", "cryptocom", NID_cryptocom, 5, &kObjectData[5360], 0}, + {"id-GostR3411-94-with-GostR3410-2001", + "GOST R 34.11-94 with GOST R 34.10-2001", + NID_id_GostR3411_94_with_GostR3410_2001, 6, &kObjectData[5365], 0}, + {"id-GostR3411-94-with-GostR3410-94", + "GOST R 34.11-94 with GOST R 34.10-94", + NID_id_GostR3411_94_with_GostR3410_94, 6, &kObjectData[5371], 0}, + {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &kObjectData[5377], + 0}, + {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, + &kObjectData[5383], 0}, + {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, + &kObjectData[5389], 0}, + {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &kObjectData[5395], + 0}, + {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &kObjectData[5401], 0}, + {"gost89-cnt", "gost89-cnt", NID_gost89_cnt, 0, NULL, 0}, + {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, + &kObjectData[5407], 0}, + {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, + &kObjectData[5413], 0}, + {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, + &kObjectData[5419], 0}, + {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, + &kObjectData[5425], 0}, + {"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &kObjectData[5431], 0}, + {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing, 7, &kObjectData[5438], 0}, + {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet, 7, &kObjectData[5445], 0}, + {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet, 7, &kObjectData[5452], 0}, + {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet, 7, &kObjectData[5459], 0}, + {"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &kObjectData[5466], 0}, + {"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &kObjectData[5473], 0}, + {"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &kObjectData[5480], 0}, + {"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &kObjectData[5487], 0}, + {"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet, 7, &kObjectData[5494], + 0}, + {"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet, 7, &kObjectData[5501], + 0}, + {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &kObjectData[5508], 0}, + {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet, 7, &kObjectData[5515], 0}, + {"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &kObjectData[5522], 0}, + {"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &kObjectData[5529], 0}, + {"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &kObjectData[5536], 0}, + {"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &kObjectData[5543], 0}, + {"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &kObjectData[5550], 0}, + {"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &kObjectData[5557], 0}, + {"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &kObjectData[5564], 0}, + {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet, 7, &kObjectData[5571], 0}, + {"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &kObjectData[5578], 0}, + {"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &kObjectData[5585], 0}, + {"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &kObjectData[5592], 0}, + {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &kObjectData[5599], 0}, + {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &kObjectData[5606], 0}, + {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, + &kObjectData[5613], 0}, + {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, + 7, &kObjectData[5620], 0}, + {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, + &kObjectData[5627], 0}, + {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, + 7, &kObjectData[5634], 0}, + {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc, 8, &kObjectData[5641], 0}, + {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, + &kObjectData[5649], 0}, + {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, + &kObjectData[5657], 0}, + {"id-GostR3411-94-with-GostR3410-94-cc", + "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_94_cc, 8, &kObjectData[5665], 0}, + {"id-GostR3411-94-with-GostR3410-2001-cc", + "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_2001_cc, 8, &kObjectData[5673], 0}, + {"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc, 8, &kObjectData[5681], 0}, + {"HMAC", "hmac", NID_hmac, 0, NULL, 0}, + {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, + &kObjectData[5689], 0}, + {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, + &kObjectData[5698], 0}, + {"id-on-permanentIdentifier", "Permanent Identifier", + NID_id_on_permanentIdentifier, 8, &kObjectData[5701], 0}, + {"searchGuide", "searchGuide", NID_searchGuide, 3, &kObjectData[5709], 0}, + {"businessCategory", "businessCategory", NID_businessCategory, 3, + &kObjectData[5712], 0}, + {"postalAddress", "postalAddress", NID_postalAddress, 3, &kObjectData[5715], + 0}, + {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &kObjectData[5718], + 0}, + {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName, 3, &kObjectData[5721], 0}, + {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, + &kObjectData[5724], 0}, + {"telexNumber", "telexNumber", NID_telexNumber, 3, &kObjectData[5727], 0}, + {"teletexTerminalIdentifier", "teletexTerminalIdentifier", + NID_teletexTerminalIdentifier, 3, &kObjectData[5730], 0}, + {"facsimileTelephoneNumber", "facsimileTelephoneNumber", + NID_facsimileTelephoneNumber, 3, &kObjectData[5733], 0}, + {"x121Address", "x121Address", NID_x121Address, 3, &kObjectData[5736], 0}, + {"internationaliSDNNumber", "internationaliSDNNumber", + NID_internationaliSDNNumber, 3, &kObjectData[5739], 0}, + {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, + &kObjectData[5742], 0}, + {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, + 3, &kObjectData[5745], 0}, + {"preferredDeliveryMethod", "preferredDeliveryMethod", + NID_preferredDeliveryMethod, 3, &kObjectData[5748], 0}, + {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, + &kObjectData[5751], 0}, + {"supportedApplicationContext", "supportedApplicationContext", + NID_supportedApplicationContext, 3, &kObjectData[5754], 0}, + {"member", "member", NID_member, 3, &kObjectData[5757], 0}, + {"owner", "owner", NID_owner, 3, &kObjectData[5760], 0}, + {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &kObjectData[5763], + 0}, + {"seeAlso", "seeAlso", NID_seeAlso, 3, &kObjectData[5766], 0}, + {"userPassword", "userPassword", NID_userPassword, 3, &kObjectData[5769], + 0}, + {"userCertificate", "userCertificate", NID_userCertificate, 3, + &kObjectData[5772], 0}, + {"cACertificate", "cACertificate", NID_cACertificate, 3, &kObjectData[5775], + 0}, + {"authorityRevocationList", "authorityRevocationList", + NID_authorityRevocationList, 3, &kObjectData[5778], 0}, + {"certificateRevocationList", "certificateRevocationList", + NID_certificateRevocationList, 3, &kObjectData[5781], 0}, + {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, + 3, &kObjectData[5784], 0}, + {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, + &kObjectData[5787], 0}, + {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, + &kObjectData[5790], 0}, + {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, + &kObjectData[5793], 0}, + {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &kObjectData[5796], + 0}, + {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, + &kObjectData[5799], 0}, + {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, + &kObjectData[5802], 0}, + {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, + &kObjectData[5805], 0}, + {"dmdName", "dmdName", NID_dmdName, 3, &kObjectData[5808], 0}, + {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, + &kObjectData[5811], 0}, + {"CMAC", "cmac", NID_cmac, 0, NULL, 0}, + {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &kObjectData[5822], 0}, + {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &kObjectData[5831], 0}, + {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, + &kObjectData[5840], 0}, + {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &kObjectData[5849], 0}, + {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &kObjectData[5858], 0}, + {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, + &kObjectData[5867], 0}, + {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &kObjectData[5876], 0}, + {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &kObjectData[5885], 0}, + {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, + &kObjectData[5894], 0}, + {"AES-128-CTR", "aes-128-ctr", NID_aes_128_ctr, 0, NULL, 0}, + {"AES-192-CTR", "aes-192-ctr", NID_aes_192_ctr, 0, NULL, 0}, + {"AES-256-CTR", "aes-256-ctr", NID_aes_256_ctr, 0, NULL, 0}, + {"id-camellia128-wrap", "id-camellia128-wrap", NID_id_camellia128_wrap, 11, + &kObjectData[5903], 0}, + {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, + &kObjectData[5914], 0}, + {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, + &kObjectData[5925], 0}, + {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, + 4, &kObjectData[5936], 0}, + {"MGF1", "mgf1", NID_mgf1, 9, &kObjectData[5940], 0}, + {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &kObjectData[5949], 0}, + {"AES-128-XTS", "aes-128-xts", NID_aes_128_xts, 0, NULL, 0}, + {"AES-256-XTS", "aes-256-xts", NID_aes_256_xts, 0, NULL, 0}, + {"RC4-HMAC-MD5", "rc4-hmac-md5", NID_rc4_hmac_md5, 0, NULL, 0}, + {"AES-128-CBC-HMAC-SHA1", "aes-128-cbc-hmac-sha1", + NID_aes_128_cbc_hmac_sha1, 0, NULL, 0}, + {"AES-192-CBC-HMAC-SHA1", "aes-192-cbc-hmac-sha1", + NID_aes_192_cbc_hmac_sha1, 0, NULL, 0}, + {"AES-256-CBC-HMAC-SHA1", "aes-256-cbc-hmac-sha1", + NID_aes_256_cbc_hmac_sha1, 0, NULL, 0}, + {"RSAES-OAEP", "rsaesOaep", NID_rsaesOaep, 9, &kObjectData[5958], 0}, + {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &kObjectData[5967], + 0}, + {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, + &kObjectData[5974], 0}, + {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, + &kObjectData[5983], 0}, + {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, + &kObjectData[5992], 0}, + {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, + &kObjectData[6001], 0}, + {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, + &kObjectData[6010], 0}, + {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, + &kObjectData[6019], 0}, + {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, + &kObjectData[6028], 0}, + {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, + &kObjectData[6037], 0}, + {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, + &kObjectData[6046], 0}, + {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, + &kObjectData[6055], 0}, + {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, + &kObjectData[6064], 0}, + {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, + &kObjectData[6073], 0}, + {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, + &kObjectData[6082], 0}, + {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, + &kObjectData[6091], 0}, + {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &kObjectData[6100], 0}, + {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", + NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &kObjectData[6109], 0}, + {"dhSinglePass-stdDH-sha224kdf-scheme", + "dhSinglePass-stdDH-sha224kdf-scheme", + NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &kObjectData[6118], 0}, + {"dhSinglePass-stdDH-sha256kdf-scheme", + "dhSinglePass-stdDH-sha256kdf-scheme", + NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &kObjectData[6124], 0}, + {"dhSinglePass-stdDH-sha384kdf-scheme", + "dhSinglePass-stdDH-sha384kdf-scheme", + NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &kObjectData[6130], 0}, + {"dhSinglePass-stdDH-sha512kdf-scheme", + "dhSinglePass-stdDH-sha512kdf-scheme", + NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &kObjectData[6136], 0}, + {"dhSinglePass-cofactorDH-sha1kdf-scheme", + "dhSinglePass-cofactorDH-sha1kdf-scheme", + NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &kObjectData[6142], 0}, + {"dhSinglePass-cofactorDH-sha224kdf-scheme", + "dhSinglePass-cofactorDH-sha224kdf-scheme", + NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &kObjectData[6151], 0}, + {"dhSinglePass-cofactorDH-sha256kdf-scheme", + "dhSinglePass-cofactorDH-sha256kdf-scheme", + NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &kObjectData[6157], 0}, + {"dhSinglePass-cofactorDH-sha384kdf-scheme", + "dhSinglePass-cofactorDH-sha384kdf-scheme", + NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &kObjectData[6163], 0}, + {"dhSinglePass-cofactorDH-sha512kdf-scheme", + "dhSinglePass-cofactorDH-sha512kdf-scheme", + NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &kObjectData[6169], 0}, + {"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf, 0, NULL, 0}, + {"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf, 0, NULL, 0}, + {"X25519", "X25519", NID_X25519, 3, &kObjectData[6175], 0}, + {"ED25519", "ED25519", NID_ED25519, 3, &kObjectData[6178], 0}, + {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305, 0, NULL, + 0}, + {"KxRSA", "kx-rsa", NID_kx_rsa, 0, NULL, 0}, + {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe, 0, NULL, 0}, + {"KxPSK", "kx-psk", NID_kx_psk, 0, NULL, 0}, + {"AuthRSA", "auth-rsa", NID_auth_rsa, 0, NULL, 0}, + {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa, 0, NULL, 0}, + {"AuthPSK", "auth-psk", NID_auth_psk, 0, NULL, 0}, + {"KxANY", "kx-any", NID_kx_any, 0, NULL, 0}, + {"AuthANY", "auth-any", NID_auth_any, 0, NULL, 0}, + {"CECPQ2", "CECPQ2", NID_CECPQ2, 0, NULL, 0}, + {"ED448", "ED448", NID_ED448, 3, &kObjectData[6181], 0}, + {"X448", "X448", NID_X448, 3, &kObjectData[6184], 0}, + {"SHA512-256", "sha512-256", NID_sha512_256, 9, &kObjectData[6187], 0}, +}; + +static const uint16_t kNIDsInShortNameOrder[] = { + 364 /* AD_DVCS */, + 419 /* AES-128-CBC */, + 916 /* AES-128-CBC-HMAC-SHA1 */, + 421 /* AES-128-CFB */, + 650 /* AES-128-CFB1 */, + 653 /* AES-128-CFB8 */, + 904 /* AES-128-CTR */, + 418 /* AES-128-ECB */, + 420 /* AES-128-OFB */, + 913 /* AES-128-XTS */, + 423 /* AES-192-CBC */, + 917 /* AES-192-CBC-HMAC-SHA1 */, + 425 /* AES-192-CFB */, + 651 /* AES-192-CFB1 */, + 654 /* AES-192-CFB8 */, + 905 /* AES-192-CTR */, + 422 /* AES-192-ECB */, + 424 /* AES-192-OFB */, + 427 /* AES-256-CBC */, + 918 /* AES-256-CBC-HMAC-SHA1 */, + 429 /* AES-256-CFB */, + 652 /* AES-256-CFB1 */, + 655 /* AES-256-CFB8 */, + 906 /* AES-256-CTR */, + 426 /* AES-256-ECB */, + 428 /* AES-256-OFB */, + 914 /* AES-256-XTS */, + 958 /* AuthANY */, + 955 /* AuthECDSA */, + 956 /* AuthPSK */, + 954 /* AuthRSA */, + 91 /* BF-CBC */, + 93 /* BF-CFB */, + 92 /* BF-ECB */, + 94 /* BF-OFB */, + 14 /* C */, + 751 /* CAMELLIA-128-CBC */, + 757 /* CAMELLIA-128-CFB */, + 760 /* CAMELLIA-128-CFB1 */, + 763 /* CAMELLIA-128-CFB8 */, + 754 /* CAMELLIA-128-ECB */, + 766 /* CAMELLIA-128-OFB */, + 752 /* CAMELLIA-192-CBC */, + 758 /* CAMELLIA-192-CFB */, + 761 /* CAMELLIA-192-CFB1 */, + 764 /* CAMELLIA-192-CFB8 */, + 755 /* CAMELLIA-192-ECB */, + 767 /* CAMELLIA-192-OFB */, + 753 /* CAMELLIA-256-CBC */, + 759 /* CAMELLIA-256-CFB */, + 762 /* CAMELLIA-256-CFB1 */, + 765 /* CAMELLIA-256-CFB8 */, + 756 /* CAMELLIA-256-ECB */, + 768 /* CAMELLIA-256-OFB */, + 108 /* CAST5-CBC */, + 110 /* CAST5-CFB */, + 109 /* CAST5-ECB */, + 111 /* CAST5-OFB */, + 959 /* CECPQ2 */, + 894 /* CMAC */, + 13 /* CN */, + 141 /* CRLReason */, + 417 /* CSPName */, + 950 /* ChaCha20-Poly1305 */, + 367 /* CrlID */, + 391 /* DC */, + 31 /* DES-CBC */, + 643 /* DES-CDMF */, + 30 /* DES-CFB */, + 656 /* DES-CFB1 */, + 657 /* DES-CFB8 */, + 29 /* DES-ECB */, + 32 /* DES-EDE */, + 43 /* DES-EDE-CBC */, + 60 /* DES-EDE-CFB */, + 62 /* DES-EDE-OFB */, + 33 /* DES-EDE3 */, + 44 /* DES-EDE3-CBC */, + 61 /* DES-EDE3-CFB */, + 658 /* DES-EDE3-CFB1 */, + 659 /* DES-EDE3-CFB8 */, + 63 /* DES-EDE3-OFB */, + 45 /* DES-OFB */, + 80 /* DESX-CBC */, + 380 /* DOD */, + 116 /* DSA */, + 66 /* DSA-SHA */, + 113 /* DSA-SHA1 */, + 70 /* DSA-SHA1-old */, + 67 /* DSA-old */, + 297 /* DVCS */, + 949 /* ED25519 */, + 960 /* ED448 */, + 99 /* GN */, + 855 /* HMAC */, + 780 /* HMAC-MD5 */, + 781 /* HMAC-SHA1 */, + 381 /* IANA */, + 34 /* IDEA-CBC */, + 35 /* IDEA-CFB */, + 36 /* IDEA-ECB */, + 46 /* IDEA-OFB */, + 181 /* ISO */, + 183 /* ISO-US */, + 645 /* ITU-T */, + 646 /* JOINT-ISO-ITU-T */, + 773 /* KISA */, + 957 /* KxANY */, + 952 /* KxECDHE */, + 953 /* KxPSK */, + 951 /* KxRSA */, + 15 /* L */, + 856 /* LocalKeySet */, + 3 /* MD2 */, + 257 /* MD4 */, + 4 /* MD5 */, + 114 /* MD5-SHA1 */, + 95 /* MDC2 */, + 911 /* MGF1 */, + 388 /* Mail */, + 57 /* Netscape */, + 366 /* Nonce */, + 17 /* O */, + 178 /* OCSP */, + 180 /* OCSPSigning */, + 379 /* ORG */, + 18 /* OU */, + 749 /* Oakley-EC2N-3 */, + 750 /* Oakley-EC2N-4 */, + 9 /* PBE-MD2-DES */, + 168 /* PBE-MD2-RC2-64 */, + 10 /* PBE-MD5-DES */, + 169 /* PBE-MD5-RC2-64 */, + 147 /* PBE-SHA1-2DES */, + 146 /* PBE-SHA1-3DES */, + 170 /* PBE-SHA1-DES */, + 148 /* PBE-SHA1-RC2-128 */, + 149 /* PBE-SHA1-RC2-40 */, + 68 /* PBE-SHA1-RC2-64 */, + 144 /* PBE-SHA1-RC4-128 */, + 145 /* PBE-SHA1-RC4-40 */, + 161 /* PBES2 */, + 69 /* PBKDF2 */, + 162 /* PBMAC1 */, + 127 /* PKIX */, + 935 /* PSPECIFIED */, + 98 /* RC2-40-CBC */, + 166 /* RC2-64-CBC */, + 37 /* RC2-CBC */, + 39 /* RC2-CFB */, + 38 /* RC2-ECB */, + 40 /* RC2-OFB */, + 5 /* RC4 */, + 97 /* RC4-40 */, + 915 /* RC4-HMAC-MD5 */, + 120 /* RC5-CBC */, + 122 /* RC5-CFB */, + 121 /* RC5-ECB */, + 123 /* RC5-OFB */, + 117 /* RIPEMD160 */, + 19 /* RSA */, + 7 /* RSA-MD2 */, + 396 /* RSA-MD4 */, + 8 /* RSA-MD5 */, + 96 /* RSA-MDC2 */, + 104 /* RSA-NP-MD5 */, + 119 /* RSA-RIPEMD160 */, + 42 /* RSA-SHA */, + 65 /* RSA-SHA1 */, + 115 /* RSA-SHA1-2 */, + 671 /* RSA-SHA224 */, + 668 /* RSA-SHA256 */, + 669 /* RSA-SHA384 */, + 670 /* RSA-SHA512 */, + 919 /* RSAES-OAEP */, + 912 /* RSASSA-PSS */, + 777 /* SEED-CBC */, + 779 /* SEED-CFB */, + 776 /* SEED-ECB */, + 778 /* SEED-OFB */, + 41 /* SHA */, + 64 /* SHA1 */, + 675 /* SHA224 */, + 672 /* SHA256 */, + 673 /* SHA384 */, + 674 /* SHA512 */, + 962 /* SHA512-256 */, + 188 /* SMIME */, + 167 /* SMIME-CAPS */, + 100 /* SN */, + 16 /* ST */, + 143 /* SXNetID */, + 458 /* UID */, + 0 /* UNDEF */, + 948 /* X25519 */, + 961 /* X448 */, + 11 /* X500 */, + 378 /* X500algorithms */, + 12 /* X509 */, + 184 /* X9-57 */, + 185 /* X9cm */, + 125 /* ZLIB */, + 478 /* aRecord */, + 289 /* aaControls */, + 287 /* ac-auditEntity */, + 397 /* ac-proxying */, + 288 /* ac-targeting */, + 368 /* acceptableResponses */, + 446 /* account */, + 363 /* ad_timestamping */, + 376 /* algorithm */, + 405 /* ansi-X9-62 */, + 910 /* anyExtendedKeyUsage */, + 746 /* anyPolicy */, + 370 /* archiveCutoff */, + 484 /* associatedDomain */, + 485 /* associatedName */, + 501 /* audio */, + 177 /* authorityInfoAccess */, + 90 /* authorityKeyIdentifier */, + 882 /* authorityRevocationList */, + 87 /* basicConstraints */, + 365 /* basicOCSPResponse */, + 285 /* biometricInfo */, + 921 /* brainpoolP160r1 */, + 922 /* brainpoolP160t1 */, + 923 /* brainpoolP192r1 */, + 924 /* brainpoolP192t1 */, + 925 /* brainpoolP224r1 */, + 926 /* brainpoolP224t1 */, + 927 /* brainpoolP256r1 */, + 928 /* brainpoolP256t1 */, + 929 /* brainpoolP320r1 */, + 930 /* brainpoolP320t1 */, + 931 /* brainpoolP384r1 */, + 932 /* brainpoolP384t1 */, + 933 /* brainpoolP512r1 */, + 934 /* brainpoolP512t1 */, + 494 /* buildingName */, + 860 /* businessCategory */, + 691 /* c2onb191v4 */, + 692 /* c2onb191v5 */, + 697 /* c2onb239v4 */, + 698 /* c2onb239v5 */, + 684 /* c2pnb163v1 */, + 685 /* c2pnb163v2 */, + 686 /* c2pnb163v3 */, + 687 /* c2pnb176v1 */, + 693 /* c2pnb208w1 */, + 699 /* c2pnb272w1 */, + 700 /* c2pnb304w1 */, + 702 /* c2pnb368w1 */, + 688 /* c2tnb191v1 */, + 689 /* c2tnb191v2 */, + 690 /* c2tnb191v3 */, + 694 /* c2tnb239v1 */, + 695 /* c2tnb239v2 */, + 696 /* c2tnb239v3 */, + 701 /* c2tnb359v1 */, + 703 /* c2tnb431r1 */, + 881 /* cACertificate */, + 483 /* cNAMERecord */, + 179 /* caIssuers */, + 785 /* caRepository */, + 443 /* caseIgnoreIA5StringSyntax */, + 152 /* certBag */, + 677 /* certicom-arc */, + 771 /* certificateIssuer */, + 89 /* certificatePolicies */, + 883 /* certificateRevocationList */, + 54 /* challengePassword */, + 407 /* characteristic-two-field */, + 395 /* clearance */, + 130 /* clientAuth */, + 131 /* codeSigning */, + 50 /* contentType */, + 53 /* countersignature */, + 153 /* crlBag */, + 103 /* crlDistributionPoints */, + 88 /* crlNumber */, + 884 /* crossCertificatePair */, + 806 /* cryptocom */, + 805 /* cryptopro */, + 500 /* dITRedirect */, + 451 /* dNSDomain */, + 495 /* dSAQuality */, + 434 /* data */, + 390 /* dcobject */, + 140 /* deltaCRL */, + 891 /* deltaRevocationList */, + 107 /* description */, + 871 /* destinationIndicator */, + 947 /* dh-cofactor-kdf */, + 946 /* dh-std-kdf */, + 28 /* dhKeyAgreement */, + 941 /* dhSinglePass-cofactorDH-sha1kdf-scheme */, + 942 /* dhSinglePass-cofactorDH-sha224kdf-scheme */, + 943 /* dhSinglePass-cofactorDH-sha256kdf-scheme */, + 944 /* dhSinglePass-cofactorDH-sha384kdf-scheme */, + 945 /* dhSinglePass-cofactorDH-sha512kdf-scheme */, + 936 /* dhSinglePass-stdDH-sha1kdf-scheme */, + 937 /* dhSinglePass-stdDH-sha224kdf-scheme */, + 938 /* dhSinglePass-stdDH-sha256kdf-scheme */, + 939 /* dhSinglePass-stdDH-sha384kdf-scheme */, + 940 /* dhSinglePass-stdDH-sha512kdf-scheme */, + 920 /* dhpublicnumber */, + 382 /* directory */, + 887 /* distinguishedName */, + 892 /* dmdName */, + 174 /* dnQualifier */, + 447 /* document */, + 471 /* documentAuthor */, + 468 /* documentIdentifier */, + 472 /* documentLocation */, + 502 /* documentPublisher */, + 449 /* documentSeries */, + 469 /* documentTitle */, + 470 /* documentVersion */, + 392 /* domain */, + 452 /* domainRelatedObject */, + 802 /* dsa_with_SHA224 */, + 803 /* dsa_with_SHA256 */, + 791 /* ecdsa-with-Recommended */, + 416 /* ecdsa-with-SHA1 */, + 793 /* ecdsa-with-SHA224 */, + 794 /* ecdsa-with-SHA256 */, + 795 /* ecdsa-with-SHA384 */, + 796 /* ecdsa-with-SHA512 */, + 792 /* ecdsa-with-Specified */, + 48 /* emailAddress */, + 132 /* emailProtection */, + 885 /* enhancedSearchGuide */, + 389 /* enterprises */, + 384 /* experimental */, + 172 /* extReq */, + 56 /* extendedCertificateAttributes */, + 126 /* extendedKeyUsage */, + 372 /* extendedStatus */, + 867 /* facsimileTelephoneNumber */, + 462 /* favouriteDrink */, + 857 /* freshestCRL */, + 453 /* friendlyCountry */, + 490 /* friendlyCountryName */, + 156 /* friendlyName */, + 509 /* generationQualifier */, + 815 /* gost-mac */, + 811 /* gost2001 */, + 851 /* gost2001cc */, + 813 /* gost89 */, + 814 /* gost89-cnt */, + 812 /* gost94 */, + 850 /* gost94cc */, + 797 /* hmacWithMD5 */, + 163 /* hmacWithSHA1 */, + 798 /* hmacWithSHA224 */, + 799 /* hmacWithSHA256 */, + 800 /* hmacWithSHA384 */, + 801 /* hmacWithSHA512 */, + 432 /* holdInstructionCallIssuer */, + 430 /* holdInstructionCode */, + 431 /* holdInstructionNone */, + 433 /* holdInstructionReject */, + 486 /* homePostalAddress */, + 473 /* homeTelephoneNumber */, + 466 /* host */, + 889 /* houseIdentifier */, + 442 /* iA5StringSyntax */, + 783 /* id-DHBasedMac */, + 824 /* id-Gost28147-89-CryptoPro-A-ParamSet */, + 825 /* id-Gost28147-89-CryptoPro-B-ParamSet */, + 826 /* id-Gost28147-89-CryptoPro-C-ParamSet */, + 827 /* id-Gost28147-89-CryptoPro-D-ParamSet */, + 819 /* id-Gost28147-89-CryptoPro-KeyMeshing */, + 829 /* id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet */, + 828 /* id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet */, + 830 /* id-Gost28147-89-CryptoPro-RIC-1-ParamSet */, + 820 /* id-Gost28147-89-None-KeyMeshing */, + 823 /* id-Gost28147-89-TestParamSet */, + 849 /* id-Gost28147-89-cc */, + 840 /* id-GostR3410-2001-CryptoPro-A-ParamSet */, + 841 /* id-GostR3410-2001-CryptoPro-B-ParamSet */, + 842 /* id-GostR3410-2001-CryptoPro-C-ParamSet */, + 843 /* id-GostR3410-2001-CryptoPro-XchA-ParamSet */, + 844 /* id-GostR3410-2001-CryptoPro-XchB-ParamSet */, + 854 /* id-GostR3410-2001-ParamSet-cc */, + 839 /* id-GostR3410-2001-TestParamSet */, + 817 /* id-GostR3410-2001DH */, + 832 /* id-GostR3410-94-CryptoPro-A-ParamSet */, + 833 /* id-GostR3410-94-CryptoPro-B-ParamSet */, + 834 /* id-GostR3410-94-CryptoPro-C-ParamSet */, + 835 /* id-GostR3410-94-CryptoPro-D-ParamSet */, + 836 /* id-GostR3410-94-CryptoPro-XchA-ParamSet */, + 837 /* id-GostR3410-94-CryptoPro-XchB-ParamSet */, + 838 /* id-GostR3410-94-CryptoPro-XchC-ParamSet */, + 831 /* id-GostR3410-94-TestParamSet */, + 845 /* id-GostR3410-94-a */, + 846 /* id-GostR3410-94-aBis */, + 847 /* id-GostR3410-94-b */, + 848 /* id-GostR3410-94-bBis */, + 818 /* id-GostR3410-94DH */, + 822 /* id-GostR3411-94-CryptoProParamSet */, + 821 /* id-GostR3411-94-TestParamSet */, + 807 /* id-GostR3411-94-with-GostR3410-2001 */, + 853 /* id-GostR3411-94-with-GostR3410-2001-cc */, + 808 /* id-GostR3411-94-with-GostR3410-94 */, + 852 /* id-GostR3411-94-with-GostR3410-94-cc */, + 810 /* id-HMACGostR3411-94 */, + 782 /* id-PasswordBasedMAC */, + 266 /* id-aca */, + 355 /* id-aca-accessIdentity */, + 354 /* id-aca-authenticationInfo */, + 356 /* id-aca-chargingIdentity */, + 399 /* id-aca-encAttrs */, + 357 /* id-aca-group */, + 358 /* id-aca-role */, + 176 /* id-ad */, + 896 /* id-aes128-CCM */, + 895 /* id-aes128-GCM */, + 788 /* id-aes128-wrap */, + 897 /* id-aes128-wrap-pad */, + 899 /* id-aes192-CCM */, + 898 /* id-aes192-GCM */, + 789 /* id-aes192-wrap */, + 900 /* id-aes192-wrap-pad */, + 902 /* id-aes256-CCM */, + 901 /* id-aes256-GCM */, + 790 /* id-aes256-wrap */, + 903 /* id-aes256-wrap-pad */, + 262 /* id-alg */, + 893 /* id-alg-PWRI-KEK */, + 323 /* id-alg-des40 */, + 326 /* id-alg-dh-pop */, + 325 /* id-alg-dh-sig-hmac-sha1 */, + 324 /* id-alg-noSignature */, + 907 /* id-camellia128-wrap */, + 908 /* id-camellia192-wrap */, + 909 /* id-camellia256-wrap */, + 268 /* id-cct */, + 361 /* id-cct-PKIData */, + 362 /* id-cct-PKIResponse */, + 360 /* id-cct-crs */, + 81 /* id-ce */, + 680 /* id-characteristic-two-basis */, + 263 /* id-cmc */, + 334 /* id-cmc-addExtensions */, + 346 /* id-cmc-confirmCertAcceptance */, + 330 /* id-cmc-dataReturn */, + 336 /* id-cmc-decryptedPOP */, + 335 /* id-cmc-encryptedPOP */, + 339 /* id-cmc-getCRL */, + 338 /* id-cmc-getCert */, + 328 /* id-cmc-identification */, + 329 /* id-cmc-identityProof */, + 337 /* id-cmc-lraPOPWitness */, + 344 /* id-cmc-popLinkRandom */, + 345 /* id-cmc-popLinkWitness */, + 343 /* id-cmc-queryPending */, + 333 /* id-cmc-recipientNonce */, + 341 /* id-cmc-regInfo */, + 342 /* id-cmc-responseInfo */, + 340 /* id-cmc-revokeRequest */, + 332 /* id-cmc-senderNonce */, + 327 /* id-cmc-statusInfo */, + 331 /* id-cmc-transactionId */, + 787 /* id-ct-asciiTextWithCRLF */, + 408 /* id-ecPublicKey */, + 508 /* id-hex-multipart-message */, + 507 /* id-hex-partial-message */, + 260 /* id-it */, + 302 /* id-it-caKeyUpdateInfo */, + 298 /* id-it-caProtEncCert */, + 311 /* id-it-confirmWaitTime */, + 303 /* id-it-currentCRL */, + 300 /* id-it-encKeyPairTypes */, + 310 /* id-it-implicitConfirm */, + 308 /* id-it-keyPairParamRep */, + 307 /* id-it-keyPairParamReq */, + 312 /* id-it-origPKIMessage */, + 301 /* id-it-preferredSymmAlg */, + 309 /* id-it-revPassphrase */, + 299 /* id-it-signKeyPairTypes */, + 305 /* id-it-subscriptionRequest */, + 306 /* id-it-subscriptionResponse */, + 784 /* id-it-suppLangTags */, + 304 /* id-it-unsupportedOIDs */, + 128 /* id-kp */, + 280 /* id-mod-attribute-cert */, + 274 /* id-mod-cmc */, + 277 /* id-mod-cmp */, + 284 /* id-mod-cmp2000 */, + 273 /* id-mod-crmf */, + 283 /* id-mod-dvcs */, + 275 /* id-mod-kea-profile-88 */, + 276 /* id-mod-kea-profile-93 */, + 282 /* id-mod-ocsp */, + 278 /* id-mod-qualified-cert-88 */, + 279 /* id-mod-qualified-cert-93 */, + 281 /* id-mod-timestamp-protocol */, + 264 /* id-on */, + 858 /* id-on-permanentIdentifier */, + 347 /* id-on-personalData */, + 265 /* id-pda */, + 352 /* id-pda-countryOfCitizenship */, + 353 /* id-pda-countryOfResidence */, + 348 /* id-pda-dateOfBirth */, + 351 /* id-pda-gender */, + 349 /* id-pda-placeOfBirth */, + 175 /* id-pe */, + 261 /* id-pkip */, + 258 /* id-pkix-mod */, + 269 /* id-pkix1-explicit-88 */, + 271 /* id-pkix1-explicit-93 */, + 270 /* id-pkix1-implicit-88 */, + 272 /* id-pkix1-implicit-93 */, + 662 /* id-ppl */, + 664 /* id-ppl-anyLanguage */, + 667 /* id-ppl-independent */, + 665 /* id-ppl-inheritAll */, + 267 /* id-qcs */, + 359 /* id-qcs-pkixQCSyntax-v1 */, + 259 /* id-qt */, + 164 /* id-qt-cps */, + 165 /* id-qt-unotice */, + 313 /* id-regCtrl */, + 316 /* id-regCtrl-authenticator */, + 319 /* id-regCtrl-oldCertID */, + 318 /* id-regCtrl-pkiArchiveOptions */, + 317 /* id-regCtrl-pkiPublicationInfo */, + 320 /* id-regCtrl-protocolEncrKey */, + 315 /* id-regCtrl-regToken */, + 314 /* id-regInfo */, + 322 /* id-regInfo-certReq */, + 321 /* id-regInfo-utf8Pairs */, + 512 /* id-set */, + 191 /* id-smime-aa */, + 215 /* id-smime-aa-contentHint */, + 218 /* id-smime-aa-contentIdentifier */, + 221 /* id-smime-aa-contentReference */, + 240 /* id-smime-aa-dvcs-dvc */, + 217 /* id-smime-aa-encapContentType */, + 222 /* id-smime-aa-encrypKeyPref */, + 220 /* id-smime-aa-equivalentLabels */, + 232 /* id-smime-aa-ets-CertificateRefs */, + 233 /* id-smime-aa-ets-RevocationRefs */, + 238 /* id-smime-aa-ets-archiveTimeStamp */, + 237 /* id-smime-aa-ets-certCRLTimestamp */, + 234 /* id-smime-aa-ets-certValues */, + 227 /* id-smime-aa-ets-commitmentType */, + 231 /* id-smime-aa-ets-contentTimestamp */, + 236 /* id-smime-aa-ets-escTimeStamp */, + 230 /* id-smime-aa-ets-otherSigCert */, + 235 /* id-smime-aa-ets-revocationValues */, + 226 /* id-smime-aa-ets-sigPolicyId */, + 229 /* id-smime-aa-ets-signerAttr */, + 228 /* id-smime-aa-ets-signerLocation */, + 219 /* id-smime-aa-macValue */, + 214 /* id-smime-aa-mlExpandHistory */, + 216 /* id-smime-aa-msgSigDigest */, + 212 /* id-smime-aa-receiptRequest */, + 213 /* id-smime-aa-securityLabel */, + 239 /* id-smime-aa-signatureType */, + 223 /* id-smime-aa-signingCertificate */, + 224 /* id-smime-aa-smimeEncryptCerts */, + 225 /* id-smime-aa-timeStampToken */, + 192 /* id-smime-alg */, + 243 /* id-smime-alg-3DESwrap */, + 246 /* id-smime-alg-CMS3DESwrap */, + 247 /* id-smime-alg-CMSRC2wrap */, + 245 /* id-smime-alg-ESDH */, + 241 /* id-smime-alg-ESDHwith3DES */, + 242 /* id-smime-alg-ESDHwithRC2 */, + 244 /* id-smime-alg-RC2wrap */, + 193 /* id-smime-cd */, + 248 /* id-smime-cd-ldap */, + 190 /* id-smime-ct */, + 210 /* id-smime-ct-DVCSRequestData */, + 211 /* id-smime-ct-DVCSResponseData */, + 208 /* id-smime-ct-TDTInfo */, + 207 /* id-smime-ct-TSTInfo */, + 205 /* id-smime-ct-authData */, + 786 /* id-smime-ct-compressedData */, + 209 /* id-smime-ct-contentInfo */, + 206 /* id-smime-ct-publishCert */, + 204 /* id-smime-ct-receipt */, + 195 /* id-smime-cti */, + 255 /* id-smime-cti-ets-proofOfApproval */, + 256 /* id-smime-cti-ets-proofOfCreation */, + 253 /* id-smime-cti-ets-proofOfDelivery */, + 251 /* id-smime-cti-ets-proofOfOrigin */, + 252 /* id-smime-cti-ets-proofOfReceipt */, + 254 /* id-smime-cti-ets-proofOfSender */, + 189 /* id-smime-mod */, + 196 /* id-smime-mod-cms */, + 197 /* id-smime-mod-ess */, + 202 /* id-smime-mod-ets-eSigPolicy-88 */, + 203 /* id-smime-mod-ets-eSigPolicy-97 */, + 200 /* id-smime-mod-ets-eSignature-88 */, + 201 /* id-smime-mod-ets-eSignature-97 */, + 199 /* id-smime-mod-msg-v3 */, + 198 /* id-smime-mod-oid */, + 194 /* id-smime-spq */, + 250 /* id-smime-spq-ets-sqt-unotice */, + 249 /* id-smime-spq-ets-sqt-uri */, + 676 /* identified-organization */, + 461 /* info */, + 748 /* inhibitAnyPolicy */, + 101 /* initials */, + 647 /* international-organizations */, + 869 /* internationaliSDNNumber */, + 142 /* invalidityDate */, + 294 /* ipsecEndSystem */, + 295 /* ipsecTunnel */, + 296 /* ipsecUser */, + 86 /* issuerAltName */, + 770 /* issuingDistributionPoint */, + 492 /* janetMailbox */, + 150 /* keyBag */, + 83 /* keyUsage */, + 477 /* lastModifiedBy */, + 476 /* lastModifiedTime */, + 157 /* localKeyID */, + 480 /* mXRecord */, + 460 /* mail */, + 493 /* mailPreferenceOption */, + 467 /* manager */, + 809 /* md_gost94 */, + 875 /* member */, + 182 /* member-body */, + 51 /* messageDigest */, + 383 /* mgmt */, + 504 /* mime-mhs */, + 506 /* mime-mhs-bodies */, + 505 /* mime-mhs-headings */, + 488 /* mobileTelephoneNumber */, + 136 /* msCTLSign */, + 135 /* msCodeCom */, + 134 /* msCodeInd */, + 138 /* msEFS */, + 171 /* msExtReq */, + 137 /* msSGC */, + 648 /* msSmartcardLogin */, + 649 /* msUPN */, + 481 /* nSRecord */, + 173 /* name */, + 666 /* nameConstraints */, + 369 /* noCheck */, + 403 /* noRevAvail */, + 72 /* nsBaseUrl */, + 76 /* nsCaPolicyUrl */, + 74 /* nsCaRevocationUrl */, + 58 /* nsCertExt */, + 79 /* nsCertSequence */, + 71 /* nsCertType */, + 78 /* nsComment */, + 59 /* nsDataType */, + 75 /* nsRenewalUrl */, + 73 /* nsRevocationUrl */, + 139 /* nsSGC */, + 77 /* nsSslServerName */, + 681 /* onBasis */, + 491 /* organizationalStatus */, + 475 /* otherMailbox */, + 876 /* owner */, + 489 /* pagerTelephoneNumber */, + 374 /* path */, + 112 /* pbeWithMD5AndCast5CBC */, + 499 /* personalSignature */, + 487 /* personalTitle */, + 464 /* photo */, + 863 /* physicalDeliveryOfficeName */, + 437 /* pilot */, + 439 /* pilotAttributeSyntax */, + 438 /* pilotAttributeType */, + 479 /* pilotAttributeType27 */, + 456 /* pilotDSA */, + 441 /* pilotGroups */, + 444 /* pilotObject */, + 440 /* pilotObjectClass */, + 455 /* pilotOrganization */, + 445 /* pilotPerson */, + 2 /* pkcs */, + 186 /* pkcs1 */, + 27 /* pkcs3 */, + 187 /* pkcs5 */, + 20 /* pkcs7 */, + 21 /* pkcs7-data */, + 25 /* pkcs7-digestData */, + 26 /* pkcs7-encryptedData */, + 23 /* pkcs7-envelopedData */, + 24 /* pkcs7-signedAndEnvelopedData */, + 22 /* pkcs7-signedData */, + 151 /* pkcs8ShroudedKeyBag */, + 47 /* pkcs9 */, + 401 /* policyConstraints */, + 747 /* policyMappings */, + 862 /* postOfficeBox */, + 861 /* postalAddress */, + 661 /* postalCode */, + 683 /* ppBasis */, + 872 /* preferredDeliveryMethod */, + 873 /* presentationAddress */, + 816 /* prf-gostr3411-94 */, + 406 /* prime-field */, + 409 /* prime192v1 */, + 410 /* prime192v2 */, + 411 /* prime192v3 */, + 412 /* prime239v1 */, + 413 /* prime239v2 */, + 414 /* prime239v3 */, + 415 /* prime256v1 */, + 385 /* private */, + 84 /* privateKeyUsagePeriod */, + 886 /* protocolInformation */, + 663 /* proxyCertInfo */, + 510 /* pseudonym */, + 435 /* pss */, + 286 /* qcStatements */, + 457 /* qualityLabelledData */, + 450 /* rFC822localPart */, + 870 /* registeredAddress */, + 400 /* role */, + 877 /* roleOccupant */, + 448 /* room */, + 463 /* roomNumber */, + 6 /* rsaEncryption */, + 644 /* rsaOAEPEncryptionSET */, + 377 /* rsaSignature */, + 1 /* rsadsi */, + 482 /* sOARecord */, + 155 /* safeContentsBag */, + 291 /* sbgp-autonomousSysNum */, + 290 /* sbgp-ipAddrBlock */, + 292 /* sbgp-routerIdentifier */, + 159 /* sdsiCertificate */, + 859 /* searchGuide */, + 704 /* secp112r1 */, + 705 /* secp112r2 */, + 706 /* secp128r1 */, + 707 /* secp128r2 */, + 708 /* secp160k1 */, + 709 /* secp160r1 */, + 710 /* secp160r2 */, + 711 /* secp192k1 */, + 712 /* secp224k1 */, + 713 /* secp224r1 */, + 714 /* secp256k1 */, + 715 /* secp384r1 */, + 716 /* secp521r1 */, + 154 /* secretBag */, + 474 /* secretary */, + 717 /* sect113r1 */, + 718 /* sect113r2 */, + 719 /* sect131r1 */, + 720 /* sect131r2 */, + 721 /* sect163k1 */, + 722 /* sect163r1 */, + 723 /* sect163r2 */, + 724 /* sect193r1 */, + 725 /* sect193r2 */, + 726 /* sect233k1 */, + 727 /* sect233r1 */, + 728 /* sect239k1 */, + 729 /* sect283k1 */, + 730 /* sect283r1 */, + 731 /* sect409k1 */, + 732 /* sect409r1 */, + 733 /* sect571k1 */, + 734 /* sect571r1 */, + 386 /* security */, + 878 /* seeAlso */, + 394 /* selected-attribute-types */, + 105 /* serialNumber */, + 129 /* serverAuth */, + 371 /* serviceLocator */, + 625 /* set-addPolicy */, + 515 /* set-attr */, + 518 /* set-brand */, + 638 /* set-brand-AmericanExpress */, + 637 /* set-brand-Diners */, + 636 /* set-brand-IATA-ATA */, + 639 /* set-brand-JCB */, + 641 /* set-brand-MasterCard */, + 642 /* set-brand-Novus */, + 640 /* set-brand-Visa */, + 517 /* set-certExt */, + 513 /* set-ctype */, + 514 /* set-msgExt */, + 516 /* set-policy */, + 607 /* set-policy-root */, + 624 /* set-rootKeyThumb */, + 620 /* setAttr-Cert */, + 631 /* setAttr-GenCryptgrm */, + 623 /* setAttr-IssCap */, + 628 /* setAttr-IssCap-CVM */, + 630 /* setAttr-IssCap-Sig */, + 629 /* setAttr-IssCap-T2 */, + 621 /* setAttr-PGWYcap */, + 635 /* setAttr-SecDevSig */, + 632 /* setAttr-T2Enc */, + 633 /* setAttr-T2cleartxt */, + 634 /* setAttr-TokICCsig */, + 627 /* setAttr-Token-B0Prime */, + 626 /* setAttr-Token-EMV */, + 622 /* setAttr-TokenType */, + 619 /* setCext-IssuerCapabilities */, + 615 /* setCext-PGWYcapabilities */, + 616 /* setCext-TokenIdentifier */, + 618 /* setCext-TokenType */, + 617 /* setCext-Track2Data */, + 611 /* setCext-cCertRequired */, + 609 /* setCext-certType */, + 608 /* setCext-hashedRoot */, + 610 /* setCext-merchData */, + 613 /* setCext-setExt */, + 614 /* setCext-setQualf */, + 612 /* setCext-tunneling */, + 540 /* setct-AcqCardCodeMsg */, + 576 /* setct-AcqCardCodeMsgTBE */, + 570 /* setct-AuthReqTBE */, + 534 /* setct-AuthReqTBS */, + 527 /* setct-AuthResBaggage */, + 571 /* setct-AuthResTBE */, + 572 /* setct-AuthResTBEX */, + 535 /* setct-AuthResTBS */, + 536 /* setct-AuthResTBSX */, + 528 /* setct-AuthRevReqBaggage */, + 577 /* setct-AuthRevReqTBE */, + 541 /* setct-AuthRevReqTBS */, + 529 /* setct-AuthRevResBaggage */, + 542 /* setct-AuthRevResData */, + 578 /* setct-AuthRevResTBE */, + 579 /* setct-AuthRevResTBEB */, + 543 /* setct-AuthRevResTBS */, + 573 /* setct-AuthTokenTBE */, + 537 /* setct-AuthTokenTBS */, + 600 /* setct-BCIDistributionTBS */, + 558 /* setct-BatchAdminReqData */, + 592 /* setct-BatchAdminReqTBE */, + 559 /* setct-BatchAdminResData */, + 593 /* setct-BatchAdminResTBE */, + 599 /* setct-CRLNotificationResTBS */, + 598 /* setct-CRLNotificationTBS */, + 580 /* setct-CapReqTBE */, + 581 /* setct-CapReqTBEX */, + 544 /* setct-CapReqTBS */, + 545 /* setct-CapReqTBSX */, + 546 /* setct-CapResData */, + 582 /* setct-CapResTBE */, + 583 /* setct-CapRevReqTBE */, + 584 /* setct-CapRevReqTBEX */, + 547 /* setct-CapRevReqTBS */, + 548 /* setct-CapRevReqTBSX */, + 549 /* setct-CapRevResData */, + 585 /* setct-CapRevResTBE */, + 538 /* setct-CapTokenData */, + 530 /* setct-CapTokenSeq */, + 574 /* setct-CapTokenTBE */, + 575 /* setct-CapTokenTBEX */, + 539 /* setct-CapTokenTBS */, + 560 /* setct-CardCInitResTBS */, + 566 /* setct-CertInqReqTBS */, + 563 /* setct-CertReqData */, + 595 /* setct-CertReqTBE */, + 596 /* setct-CertReqTBEX */, + 564 /* setct-CertReqTBS */, + 565 /* setct-CertResData */, + 597 /* setct-CertResTBE */, + 586 /* setct-CredReqTBE */, + 587 /* setct-CredReqTBEX */, + 550 /* setct-CredReqTBS */, + 551 /* setct-CredReqTBSX */, + 552 /* setct-CredResData */, + 588 /* setct-CredResTBE */, + 589 /* setct-CredRevReqTBE */, + 590 /* setct-CredRevReqTBEX */, + 553 /* setct-CredRevReqTBS */, + 554 /* setct-CredRevReqTBSX */, + 555 /* setct-CredRevResData */, + 591 /* setct-CredRevResTBE */, + 567 /* setct-ErrorTBS */, + 526 /* setct-HODInput */, + 561 /* setct-MeAqCInitResTBS */, + 522 /* setct-OIData */, + 519 /* setct-PANData */, + 521 /* setct-PANOnly */, + 520 /* setct-PANToken */, + 556 /* setct-PCertReqData */, + 557 /* setct-PCertResTBS */, + 523 /* setct-PI */, + 532 /* setct-PI-TBS */, + 524 /* setct-PIData */, + 525 /* setct-PIDataUnsigned */, + 568 /* setct-PIDualSignedTBE */, + 569 /* setct-PIUnsignedTBE */, + 531 /* setct-PInitResData */, + 533 /* setct-PResData */, + 594 /* setct-RegFormReqTBE */, + 562 /* setct-RegFormResTBS */, + 606 /* setext-cv */, + 601 /* setext-genCrypt */, + 602 /* setext-miAuth */, + 604 /* setext-pinAny */, + 603 /* setext-pinSecure */, + 605 /* setext-track2 */, + 52 /* signingTime */, + 454 /* simpleSecurityObject */, + 496 /* singleLevelQuality */, + 387 /* snmpv2 */, + 660 /* street */, + 85 /* subjectAltName */, + 769 /* subjectDirectoryAttributes */, + 398 /* subjectInfoAccess */, + 82 /* subjectKeyIdentifier */, + 498 /* subtreeMaximumQuality */, + 497 /* subtreeMinimumQuality */, + 890 /* supportedAlgorithms */, + 874 /* supportedApplicationContext */, + 402 /* targetInformation */, + 864 /* telephoneNumber */, + 866 /* teletexTerminalIdentifier */, + 865 /* telexNumber */, + 459 /* textEncodedORAddress */, + 293 /* textNotice */, + 133 /* timeStamping */, + 106 /* title */, + 682 /* tpBasis */, + 375 /* trustRoot */, + 436 /* ucl */, + 888 /* uniqueMember */, + 55 /* unstructuredAddress */, + 49 /* unstructuredName */, + 880 /* userCertificate */, + 465 /* userClass */, + 879 /* userPassword */, + 373 /* valid */, + 678 /* wap */, + 679 /* wap-wsg */, + 735 /* wap-wsg-idm-ecid-wtls1 */, + 743 /* wap-wsg-idm-ecid-wtls10 */, + 744 /* wap-wsg-idm-ecid-wtls11 */, + 745 /* wap-wsg-idm-ecid-wtls12 */, + 736 /* wap-wsg-idm-ecid-wtls3 */, + 737 /* wap-wsg-idm-ecid-wtls4 */, + 738 /* wap-wsg-idm-ecid-wtls5 */, + 739 /* wap-wsg-idm-ecid-wtls6 */, + 740 /* wap-wsg-idm-ecid-wtls7 */, + 741 /* wap-wsg-idm-ecid-wtls8 */, + 742 /* wap-wsg-idm-ecid-wtls9 */, + 804 /* whirlpool */, + 868 /* x121Address */, + 503 /* x500UniqueIdentifier */, + 158 /* x509Certificate */, + 160 /* x509Crl */, +}; + +static const uint16_t kNIDsInLongNameOrder[] = { + 363 /* AD Time Stamping */, + 405 /* ANSI X9.62 */, + 368 /* Acceptable OCSP Responses */, + 910 /* Any Extended Key Usage */, + 664 /* Any language */, + 177 /* Authority Information Access */, + 365 /* Basic OCSP Response */, + 285 /* Biometric Info */, + 179 /* CA Issuers */, + 785 /* CA Repository */, + 959 /* CECPQ2 */, + 131 /* Code Signing */, + 783 /* Diffie-Hellman based MAC */, + 382 /* Directory */, + 392 /* Domain */, + 132 /* E-mail Protection */, + 949 /* ED25519 */, + 960 /* ED448 */, + 389 /* Enterprises */, + 384 /* Experimental */, + 372 /* Extended OCSP Status */, + 172 /* Extension Request */, + 813 /* GOST 28147-89 */, + 849 /* GOST 28147-89 Cryptocom ParamSet */, + 815 /* GOST 28147-89 MAC */, + 851 /* GOST 34.10-2001 Cryptocom */, + 850 /* GOST 34.10-94 Cryptocom */, + 811 /* GOST R 34.10-2001 */, + 817 /* GOST R 34.10-2001 DH */, + 812 /* GOST R 34.10-94 */, + 818 /* GOST R 34.10-94 DH */, + 809 /* GOST R 34.11-94 */, + 816 /* GOST R 34.11-94 PRF */, + 807 /* GOST R 34.11-94 with GOST R 34.10-2001 */, + 853 /* GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom */, + 808 /* GOST R 34.11-94 with GOST R 34.10-94 */, + 852 /* GOST R 34.11-94 with GOST R 34.10-94 Cryptocom */, + 854 /* GOST R 3410-2001 Parameter Set Cryptocom */, + 810 /* HMAC GOST 34.11-94 */, + 432 /* Hold Instruction Call Issuer */, + 430 /* Hold Instruction Code */, + 431 /* Hold Instruction None */, + 433 /* Hold Instruction Reject */, + 634 /* ICC or token signature */, + 294 /* IPSec End System */, + 295 /* IPSec Tunnel */, + 296 /* IPSec User */, + 182 /* ISO Member Body */, + 183 /* ISO US Member Body */, + 667 /* Independent */, + 665 /* Inherit all */, + 647 /* International Organizations */, + 142 /* Invalidity Date */, + 504 /* MIME MHS */, + 388 /* Mail */, + 383 /* Management */, + 417 /* Microsoft CSP Name */, + 135 /* Microsoft Commercial Code Signing */, + 138 /* Microsoft Encrypted File System */, + 171 /* Microsoft Extension Request */, + 134 /* Microsoft Individual Code Signing */, + 856 /* Microsoft Local Key set */, + 137 /* Microsoft Server Gated Crypto */, + 648 /* Microsoft Smartcardlogin */, + 136 /* Microsoft Trust List Signing */, + 649 /* Microsoft Universal Principal Name */, + 72 /* Netscape Base Url */, + 76 /* Netscape CA Policy Url */, + 74 /* Netscape CA Revocation Url */, + 71 /* Netscape Cert Type */, + 58 /* Netscape Certificate Extension */, + 79 /* Netscape Certificate Sequence */, + 78 /* Netscape Comment */, + 57 /* Netscape Communications Corp. */, + 59 /* Netscape Data Type */, + 75 /* Netscape Renewal Url */, + 73 /* Netscape Revocation Url */, + 77 /* Netscape SSL Server Name */, + 139 /* Netscape Server Gated Crypto */, + 178 /* OCSP */, + 370 /* OCSP Archive Cutoff */, + 367 /* OCSP CRL ID */, + 369 /* OCSP No Check */, + 366 /* OCSP Nonce */, + 371 /* OCSP Service Locator */, + 180 /* OCSP Signing */, + 161 /* PBES2 */, + 69 /* PBKDF2 */, + 162 /* PBMAC1 */, + 127 /* PKIX */, + 858 /* Permanent Identifier */, + 164 /* Policy Qualifier CPS */, + 165 /* Policy Qualifier User Notice */, + 385 /* Private */, + 663 /* Proxy Certificate Information */, + 1 /* RSA Data Security, Inc. */, + 2 /* RSA Data Security, Inc. PKCS */, + 188 /* S/MIME */, + 167 /* S/MIME Capabilities */, + 387 /* SNMPv2 */, + 512 /* Secure Electronic Transactions */, + 386 /* Security */, + 394 /* Selected Attribute Types */, + 143 /* Strong Extranet ID */, + 398 /* Subject Information Access */, + 130 /* TLS Web Client Authentication */, + 129 /* TLS Web Server Authentication */, + 133 /* Time Stamping */, + 375 /* Trust Root */, + 948 /* X25519 */, + 961 /* X448 */, + 12 /* X509 */, + 402 /* X509v3 AC Targeting */, + 746 /* X509v3 Any Policy */, + 90 /* X509v3 Authority Key Identifier */, + 87 /* X509v3 Basic Constraints */, + 103 /* X509v3 CRL Distribution Points */, + 88 /* X509v3 CRL Number */, + 141 /* X509v3 CRL Reason Code */, + 771 /* X509v3 Certificate Issuer */, + 89 /* X509v3 Certificate Policies */, + 140 /* X509v3 Delta CRL Indicator */, + 126 /* X509v3 Extended Key Usage */, + 857 /* X509v3 Freshest CRL */, + 748 /* X509v3 Inhibit Any Policy */, + 86 /* X509v3 Issuer Alternative Name */, + 770 /* X509v3 Issuing Distribution Point */, + 83 /* X509v3 Key Usage */, + 666 /* X509v3 Name Constraints */, + 403 /* X509v3 No Revocation Available */, + 401 /* X509v3 Policy Constraints */, + 747 /* X509v3 Policy Mappings */, + 84 /* X509v3 Private Key Usage Period */, + 85 /* X509v3 Subject Alternative Name */, + 769 /* X509v3 Subject Directory Attributes */, + 82 /* X509v3 Subject Key Identifier */, + 920 /* X9.42 DH */, + 184 /* X9.57 */, + 185 /* X9.57 CM ? */, + 478 /* aRecord */, + 289 /* aaControls */, + 287 /* ac-auditEntity */, + 397 /* ac-proxying */, + 288 /* ac-targeting */, + 446 /* account */, + 364 /* ad dvcs */, + 606 /* additional verification */, + 419 /* aes-128-cbc */, + 916 /* aes-128-cbc-hmac-sha1 */, + 896 /* aes-128-ccm */, + 421 /* aes-128-cfb */, + 650 /* aes-128-cfb1 */, + 653 /* aes-128-cfb8 */, + 904 /* aes-128-ctr */, + 418 /* aes-128-ecb */, + 895 /* aes-128-gcm */, + 420 /* aes-128-ofb */, + 913 /* aes-128-xts */, + 423 /* aes-192-cbc */, + 917 /* aes-192-cbc-hmac-sha1 */, + 899 /* aes-192-ccm */, + 425 /* aes-192-cfb */, + 651 /* aes-192-cfb1 */, + 654 /* aes-192-cfb8 */, + 905 /* aes-192-ctr */, + 422 /* aes-192-ecb */, + 898 /* aes-192-gcm */, + 424 /* aes-192-ofb */, + 427 /* aes-256-cbc */, + 918 /* aes-256-cbc-hmac-sha1 */, + 902 /* aes-256-ccm */, + 429 /* aes-256-cfb */, + 652 /* aes-256-cfb1 */, + 655 /* aes-256-cfb8 */, + 906 /* aes-256-ctr */, + 426 /* aes-256-ecb */, + 901 /* aes-256-gcm */, + 428 /* aes-256-ofb */, + 914 /* aes-256-xts */, + 376 /* algorithm */, + 484 /* associatedDomain */, + 485 /* associatedName */, + 501 /* audio */, + 958 /* auth-any */, + 955 /* auth-ecdsa */, + 956 /* auth-psk */, + 954 /* auth-rsa */, + 882 /* authorityRevocationList */, + 91 /* bf-cbc */, + 93 /* bf-cfb */, + 92 /* bf-ecb */, + 94 /* bf-ofb */, + 921 /* brainpoolP160r1 */, + 922 /* brainpoolP160t1 */, + 923 /* brainpoolP192r1 */, + 924 /* brainpoolP192t1 */, + 925 /* brainpoolP224r1 */, + 926 /* brainpoolP224t1 */, + 927 /* brainpoolP256r1 */, + 928 /* brainpoolP256t1 */, + 929 /* brainpoolP320r1 */, + 930 /* brainpoolP320t1 */, + 931 /* brainpoolP384r1 */, + 932 /* brainpoolP384t1 */, + 933 /* brainpoolP512r1 */, + 934 /* brainpoolP512t1 */, + 494 /* buildingName */, + 860 /* businessCategory */, + 691 /* c2onb191v4 */, + 692 /* c2onb191v5 */, + 697 /* c2onb239v4 */, + 698 /* c2onb239v5 */, + 684 /* c2pnb163v1 */, + 685 /* c2pnb163v2 */, + 686 /* c2pnb163v3 */, + 687 /* c2pnb176v1 */, + 693 /* c2pnb208w1 */, + 699 /* c2pnb272w1 */, + 700 /* c2pnb304w1 */, + 702 /* c2pnb368w1 */, + 688 /* c2tnb191v1 */, + 689 /* c2tnb191v2 */, + 690 /* c2tnb191v3 */, + 694 /* c2tnb239v1 */, + 695 /* c2tnb239v2 */, + 696 /* c2tnb239v3 */, + 701 /* c2tnb359v1 */, + 703 /* c2tnb431r1 */, + 881 /* cACertificate */, + 483 /* cNAMERecord */, + 751 /* camellia-128-cbc */, + 757 /* camellia-128-cfb */, + 760 /* camellia-128-cfb1 */, + 763 /* camellia-128-cfb8 */, + 754 /* camellia-128-ecb */, + 766 /* camellia-128-ofb */, + 752 /* camellia-192-cbc */, + 758 /* camellia-192-cfb */, + 761 /* camellia-192-cfb1 */, + 764 /* camellia-192-cfb8 */, + 755 /* camellia-192-ecb */, + 767 /* camellia-192-ofb */, + 753 /* camellia-256-cbc */, + 759 /* camellia-256-cfb */, + 762 /* camellia-256-cfb1 */, + 765 /* camellia-256-cfb8 */, + 756 /* camellia-256-ecb */, + 768 /* camellia-256-ofb */, + 443 /* caseIgnoreIA5StringSyntax */, + 108 /* cast5-cbc */, + 110 /* cast5-cfb */, + 109 /* cast5-ecb */, + 111 /* cast5-ofb */, + 152 /* certBag */, + 677 /* certicom-arc */, + 517 /* certificate extensions */, + 883 /* certificateRevocationList */, + 950 /* chacha20-poly1305 */, + 54 /* challengePassword */, + 407 /* characteristic-two-field */, + 395 /* clearance */, + 633 /* cleartext track 2 */, + 894 /* cmac */, + 13 /* commonName */, + 513 /* content types */, + 50 /* contentType */, + 53 /* countersignature */, + 14 /* countryName */, + 153 /* crlBag */, + 884 /* crossCertificatePair */, + 806 /* cryptocom */, + 805 /* cryptopro */, + 500 /* dITRedirect */, + 451 /* dNSDomain */, + 495 /* dSAQuality */, + 434 /* data */, + 390 /* dcObject */, + 891 /* deltaRevocationList */, + 31 /* des-cbc */, + 643 /* des-cdmf */, + 30 /* des-cfb */, + 656 /* des-cfb1 */, + 657 /* des-cfb8 */, + 29 /* des-ecb */, + 32 /* des-ede */, + 43 /* des-ede-cbc */, + 60 /* des-ede-cfb */, + 62 /* des-ede-ofb */, + 33 /* des-ede3 */, + 44 /* des-ede3-cbc */, + 61 /* des-ede3-cfb */, + 658 /* des-ede3-cfb1 */, + 659 /* des-ede3-cfb8 */, + 63 /* des-ede3-ofb */, + 45 /* des-ofb */, + 107 /* description */, + 871 /* destinationIndicator */, + 80 /* desx-cbc */, + 947 /* dh-cofactor-kdf */, + 946 /* dh-std-kdf */, + 28 /* dhKeyAgreement */, + 941 /* dhSinglePass-cofactorDH-sha1kdf-scheme */, + 942 /* dhSinglePass-cofactorDH-sha224kdf-scheme */, + 943 /* dhSinglePass-cofactorDH-sha256kdf-scheme */, + 944 /* dhSinglePass-cofactorDH-sha384kdf-scheme */, + 945 /* dhSinglePass-cofactorDH-sha512kdf-scheme */, + 936 /* dhSinglePass-stdDH-sha1kdf-scheme */, + 937 /* dhSinglePass-stdDH-sha224kdf-scheme */, + 938 /* dhSinglePass-stdDH-sha256kdf-scheme */, + 939 /* dhSinglePass-stdDH-sha384kdf-scheme */, + 940 /* dhSinglePass-stdDH-sha512kdf-scheme */, + 11 /* directory services (X.500) */, + 378 /* directory services - algorithms */, + 887 /* distinguishedName */, + 892 /* dmdName */, + 174 /* dnQualifier */, + 447 /* document */, + 471 /* documentAuthor */, + 468 /* documentIdentifier */, + 472 /* documentLocation */, + 502 /* documentPublisher */, + 449 /* documentSeries */, + 469 /* documentTitle */, + 470 /* documentVersion */, + 380 /* dod */, + 391 /* domainComponent */, + 452 /* domainRelatedObject */, + 116 /* dsaEncryption */, + 67 /* dsaEncryption-old */, + 66 /* dsaWithSHA */, + 113 /* dsaWithSHA1 */, + 70 /* dsaWithSHA1-old */, + 802 /* dsa_with_SHA224 */, + 803 /* dsa_with_SHA256 */, + 297 /* dvcs */, + 791 /* ecdsa-with-Recommended */, + 416 /* ecdsa-with-SHA1 */, + 793 /* ecdsa-with-SHA224 */, + 794 /* ecdsa-with-SHA256 */, + 795 /* ecdsa-with-SHA384 */, + 796 /* ecdsa-with-SHA512 */, + 792 /* ecdsa-with-Specified */, + 48 /* emailAddress */, + 632 /* encrypted track 2 */, + 885 /* enhancedSearchGuide */, + 56 /* extendedCertificateAttributes */, + 867 /* facsimileTelephoneNumber */, + 462 /* favouriteDrink */, + 453 /* friendlyCountry */, + 490 /* friendlyCountryName */, + 156 /* friendlyName */, + 631 /* generate cryptogram */, + 509 /* generationQualifier */, + 601 /* generic cryptogram */, + 99 /* givenName */, + 814 /* gost89-cnt */, + 855 /* hmac */, + 780 /* hmac-md5 */, + 781 /* hmac-sha1 */, + 797 /* hmacWithMD5 */, + 163 /* hmacWithSHA1 */, + 798 /* hmacWithSHA224 */, + 799 /* hmacWithSHA256 */, + 800 /* hmacWithSHA384 */, + 801 /* hmacWithSHA512 */, + 486 /* homePostalAddress */, + 473 /* homeTelephoneNumber */, + 466 /* host */, + 889 /* houseIdentifier */, + 442 /* iA5StringSyntax */, + 381 /* iana */, + 824 /* id-Gost28147-89-CryptoPro-A-ParamSet */, + 825 /* id-Gost28147-89-CryptoPro-B-ParamSet */, + 826 /* id-Gost28147-89-CryptoPro-C-ParamSet */, + 827 /* id-Gost28147-89-CryptoPro-D-ParamSet */, + 819 /* id-Gost28147-89-CryptoPro-KeyMeshing */, + 829 /* id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet */, + 828 /* id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet */, + 830 /* id-Gost28147-89-CryptoPro-RIC-1-ParamSet */, + 820 /* id-Gost28147-89-None-KeyMeshing */, + 823 /* id-Gost28147-89-TestParamSet */, + 840 /* id-GostR3410-2001-CryptoPro-A-ParamSet */, + 841 /* id-GostR3410-2001-CryptoPro-B-ParamSet */, + 842 /* id-GostR3410-2001-CryptoPro-C-ParamSet */, + 843 /* id-GostR3410-2001-CryptoPro-XchA-ParamSet */, + 844 /* id-GostR3410-2001-CryptoPro-XchB-ParamSet */, + 839 /* id-GostR3410-2001-TestParamSet */, + 832 /* id-GostR3410-94-CryptoPro-A-ParamSet */, + 833 /* id-GostR3410-94-CryptoPro-B-ParamSet */, + 834 /* id-GostR3410-94-CryptoPro-C-ParamSet */, + 835 /* id-GostR3410-94-CryptoPro-D-ParamSet */, + 836 /* id-GostR3410-94-CryptoPro-XchA-ParamSet */, + 837 /* id-GostR3410-94-CryptoPro-XchB-ParamSet */, + 838 /* id-GostR3410-94-CryptoPro-XchC-ParamSet */, + 831 /* id-GostR3410-94-TestParamSet */, + 845 /* id-GostR3410-94-a */, + 846 /* id-GostR3410-94-aBis */, + 847 /* id-GostR3410-94-b */, + 848 /* id-GostR3410-94-bBis */, + 822 /* id-GostR3411-94-CryptoProParamSet */, + 821 /* id-GostR3411-94-TestParamSet */, + 266 /* id-aca */, + 355 /* id-aca-accessIdentity */, + 354 /* id-aca-authenticationInfo */, + 356 /* id-aca-chargingIdentity */, + 399 /* id-aca-encAttrs */, + 357 /* id-aca-group */, + 358 /* id-aca-role */, + 176 /* id-ad */, + 788 /* id-aes128-wrap */, + 897 /* id-aes128-wrap-pad */, + 789 /* id-aes192-wrap */, + 900 /* id-aes192-wrap-pad */, + 790 /* id-aes256-wrap */, + 903 /* id-aes256-wrap-pad */, + 262 /* id-alg */, + 893 /* id-alg-PWRI-KEK */, + 323 /* id-alg-des40 */, + 326 /* id-alg-dh-pop */, + 325 /* id-alg-dh-sig-hmac-sha1 */, + 324 /* id-alg-noSignature */, + 907 /* id-camellia128-wrap */, + 908 /* id-camellia192-wrap */, + 909 /* id-camellia256-wrap */, + 268 /* id-cct */, + 361 /* id-cct-PKIData */, + 362 /* id-cct-PKIResponse */, + 360 /* id-cct-crs */, + 81 /* id-ce */, + 680 /* id-characteristic-two-basis */, + 263 /* id-cmc */, + 334 /* id-cmc-addExtensions */, + 346 /* id-cmc-confirmCertAcceptance */, + 330 /* id-cmc-dataReturn */, + 336 /* id-cmc-decryptedPOP */, + 335 /* id-cmc-encryptedPOP */, + 339 /* id-cmc-getCRL */, + 338 /* id-cmc-getCert */, + 328 /* id-cmc-identification */, + 329 /* id-cmc-identityProof */, + 337 /* id-cmc-lraPOPWitness */, + 344 /* id-cmc-popLinkRandom */, + 345 /* id-cmc-popLinkWitness */, + 343 /* id-cmc-queryPending */, + 333 /* id-cmc-recipientNonce */, + 341 /* id-cmc-regInfo */, + 342 /* id-cmc-responseInfo */, + 340 /* id-cmc-revokeRequest */, + 332 /* id-cmc-senderNonce */, + 327 /* id-cmc-statusInfo */, + 331 /* id-cmc-transactionId */, + 787 /* id-ct-asciiTextWithCRLF */, + 408 /* id-ecPublicKey */, + 508 /* id-hex-multipart-message */, + 507 /* id-hex-partial-message */, + 260 /* id-it */, + 302 /* id-it-caKeyUpdateInfo */, + 298 /* id-it-caProtEncCert */, + 311 /* id-it-confirmWaitTime */, + 303 /* id-it-currentCRL */, + 300 /* id-it-encKeyPairTypes */, + 310 /* id-it-implicitConfirm */, + 308 /* id-it-keyPairParamRep */, + 307 /* id-it-keyPairParamReq */, + 312 /* id-it-origPKIMessage */, + 301 /* id-it-preferredSymmAlg */, + 309 /* id-it-revPassphrase */, + 299 /* id-it-signKeyPairTypes */, + 305 /* id-it-subscriptionRequest */, + 306 /* id-it-subscriptionResponse */, + 784 /* id-it-suppLangTags */, + 304 /* id-it-unsupportedOIDs */, + 128 /* id-kp */, + 280 /* id-mod-attribute-cert */, + 274 /* id-mod-cmc */, + 277 /* id-mod-cmp */, + 284 /* id-mod-cmp2000 */, + 273 /* id-mod-crmf */, + 283 /* id-mod-dvcs */, + 275 /* id-mod-kea-profile-88 */, + 276 /* id-mod-kea-profile-93 */, + 282 /* id-mod-ocsp */, + 278 /* id-mod-qualified-cert-88 */, + 279 /* id-mod-qualified-cert-93 */, + 281 /* id-mod-timestamp-protocol */, + 264 /* id-on */, + 347 /* id-on-personalData */, + 265 /* id-pda */, + 352 /* id-pda-countryOfCitizenship */, + 353 /* id-pda-countryOfResidence */, + 348 /* id-pda-dateOfBirth */, + 351 /* id-pda-gender */, + 349 /* id-pda-placeOfBirth */, + 175 /* id-pe */, + 261 /* id-pkip */, + 258 /* id-pkix-mod */, + 269 /* id-pkix1-explicit-88 */, + 271 /* id-pkix1-explicit-93 */, + 270 /* id-pkix1-implicit-88 */, + 272 /* id-pkix1-implicit-93 */, + 662 /* id-ppl */, + 267 /* id-qcs */, + 359 /* id-qcs-pkixQCSyntax-v1 */, + 259 /* id-qt */, + 313 /* id-regCtrl */, + 316 /* id-regCtrl-authenticator */, + 319 /* id-regCtrl-oldCertID */, + 318 /* id-regCtrl-pkiArchiveOptions */, + 317 /* id-regCtrl-pkiPublicationInfo */, + 320 /* id-regCtrl-protocolEncrKey */, + 315 /* id-regCtrl-regToken */, + 314 /* id-regInfo */, + 322 /* id-regInfo-certReq */, + 321 /* id-regInfo-utf8Pairs */, + 191 /* id-smime-aa */, + 215 /* id-smime-aa-contentHint */, + 218 /* id-smime-aa-contentIdentifier */, + 221 /* id-smime-aa-contentReference */, + 240 /* id-smime-aa-dvcs-dvc */, + 217 /* id-smime-aa-encapContentType */, + 222 /* id-smime-aa-encrypKeyPref */, + 220 /* id-smime-aa-equivalentLabels */, + 232 /* id-smime-aa-ets-CertificateRefs */, + 233 /* id-smime-aa-ets-RevocationRefs */, + 238 /* id-smime-aa-ets-archiveTimeStamp */, + 237 /* id-smime-aa-ets-certCRLTimestamp */, + 234 /* id-smime-aa-ets-certValues */, + 227 /* id-smime-aa-ets-commitmentType */, + 231 /* id-smime-aa-ets-contentTimestamp */, + 236 /* id-smime-aa-ets-escTimeStamp */, + 230 /* id-smime-aa-ets-otherSigCert */, + 235 /* id-smime-aa-ets-revocationValues */, + 226 /* id-smime-aa-ets-sigPolicyId */, + 229 /* id-smime-aa-ets-signerAttr */, + 228 /* id-smime-aa-ets-signerLocation */, + 219 /* id-smime-aa-macValue */, + 214 /* id-smime-aa-mlExpandHistory */, + 216 /* id-smime-aa-msgSigDigest */, + 212 /* id-smime-aa-receiptRequest */, + 213 /* id-smime-aa-securityLabel */, + 239 /* id-smime-aa-signatureType */, + 223 /* id-smime-aa-signingCertificate */, + 224 /* id-smime-aa-smimeEncryptCerts */, + 225 /* id-smime-aa-timeStampToken */, + 192 /* id-smime-alg */, + 243 /* id-smime-alg-3DESwrap */, + 246 /* id-smime-alg-CMS3DESwrap */, + 247 /* id-smime-alg-CMSRC2wrap */, + 245 /* id-smime-alg-ESDH */, + 241 /* id-smime-alg-ESDHwith3DES */, + 242 /* id-smime-alg-ESDHwithRC2 */, + 244 /* id-smime-alg-RC2wrap */, + 193 /* id-smime-cd */, + 248 /* id-smime-cd-ldap */, + 190 /* id-smime-ct */, + 210 /* id-smime-ct-DVCSRequestData */, + 211 /* id-smime-ct-DVCSResponseData */, + 208 /* id-smime-ct-TDTInfo */, + 207 /* id-smime-ct-TSTInfo */, + 205 /* id-smime-ct-authData */, + 786 /* id-smime-ct-compressedData */, + 209 /* id-smime-ct-contentInfo */, + 206 /* id-smime-ct-publishCert */, + 204 /* id-smime-ct-receipt */, + 195 /* id-smime-cti */, + 255 /* id-smime-cti-ets-proofOfApproval */, + 256 /* id-smime-cti-ets-proofOfCreation */, + 253 /* id-smime-cti-ets-proofOfDelivery */, + 251 /* id-smime-cti-ets-proofOfOrigin */, + 252 /* id-smime-cti-ets-proofOfReceipt */, + 254 /* id-smime-cti-ets-proofOfSender */, + 189 /* id-smime-mod */, + 196 /* id-smime-mod-cms */, + 197 /* id-smime-mod-ess */, + 202 /* id-smime-mod-ets-eSigPolicy-88 */, + 203 /* id-smime-mod-ets-eSigPolicy-97 */, + 200 /* id-smime-mod-ets-eSignature-88 */, + 201 /* id-smime-mod-ets-eSignature-97 */, + 199 /* id-smime-mod-msg-v3 */, + 198 /* id-smime-mod-oid */, + 194 /* id-smime-spq */, + 250 /* id-smime-spq-ets-sqt-unotice */, + 249 /* id-smime-spq-ets-sqt-uri */, + 34 /* idea-cbc */, + 35 /* idea-cfb */, + 36 /* idea-ecb */, + 46 /* idea-ofb */, + 676 /* identified-organization */, + 461 /* info */, + 101 /* initials */, + 869 /* internationaliSDNNumber */, + 749 /* ipsec3 */, + 750 /* ipsec4 */, + 181 /* iso */, + 623 /* issuer capabilities */, + 645 /* itu-t */, + 492 /* janetMailbox */, + 646 /* joint-iso-itu-t */, + 150 /* keyBag */, + 773 /* kisa */, + 957 /* kx-any */, + 952 /* kx-ecdhe */, + 953 /* kx-psk */, + 951 /* kx-rsa */, + 477 /* lastModifiedBy */, + 476 /* lastModifiedTime */, + 157 /* localKeyID */, + 15 /* localityName */, + 480 /* mXRecord */, + 493 /* mailPreferenceOption */, + 467 /* manager */, + 3 /* md2 */, + 7 /* md2WithRSAEncryption */, + 257 /* md4 */, + 396 /* md4WithRSAEncryption */, + 4 /* md5 */, + 114 /* md5-sha1 */, + 104 /* md5WithRSA */, + 8 /* md5WithRSAEncryption */, + 95 /* mdc2 */, + 96 /* mdc2WithRSA */, + 875 /* member */, + 602 /* merchant initiated auth */, + 514 /* message extensions */, + 51 /* messageDigest */, + 911 /* mgf1 */, + 506 /* mime-mhs-bodies */, + 505 /* mime-mhs-headings */, + 488 /* mobileTelephoneNumber */, + 481 /* nSRecord */, + 173 /* name */, + 681 /* onBasis */, + 379 /* org */, + 17 /* organizationName */, + 491 /* organizationalStatus */, + 18 /* organizationalUnitName */, + 475 /* otherMailbox */, + 876 /* owner */, + 935 /* pSpecified */, + 489 /* pagerTelephoneNumber */, + 782 /* password based MAC */, + 374 /* path */, + 621 /* payment gateway capabilities */, + 9 /* pbeWithMD2AndDES-CBC */, + 168 /* pbeWithMD2AndRC2-CBC */, + 112 /* pbeWithMD5AndCast5CBC */, + 10 /* pbeWithMD5AndDES-CBC */, + 169 /* pbeWithMD5AndRC2-CBC */, + 148 /* pbeWithSHA1And128BitRC2-CBC */, + 144 /* pbeWithSHA1And128BitRC4 */, + 147 /* pbeWithSHA1And2-KeyTripleDES-CBC */, + 146 /* pbeWithSHA1And3-KeyTripleDES-CBC */, + 149 /* pbeWithSHA1And40BitRC2-CBC */, + 145 /* pbeWithSHA1And40BitRC4 */, + 170 /* pbeWithSHA1AndDES-CBC */, + 68 /* pbeWithSHA1AndRC2-CBC */, + 499 /* personalSignature */, + 487 /* personalTitle */, + 464 /* photo */, + 863 /* physicalDeliveryOfficeName */, + 437 /* pilot */, + 439 /* pilotAttributeSyntax */, + 438 /* pilotAttributeType */, + 479 /* pilotAttributeType27 */, + 456 /* pilotDSA */, + 441 /* pilotGroups */, + 444 /* pilotObject */, + 440 /* pilotObjectClass */, + 455 /* pilotOrganization */, + 445 /* pilotPerson */, + 186 /* pkcs1 */, + 27 /* pkcs3 */, + 187 /* pkcs5 */, + 20 /* pkcs7 */, + 21 /* pkcs7-data */, + 25 /* pkcs7-digestData */, + 26 /* pkcs7-encryptedData */, + 23 /* pkcs7-envelopedData */, + 24 /* pkcs7-signedAndEnvelopedData */, + 22 /* pkcs7-signedData */, + 151 /* pkcs8ShroudedKeyBag */, + 47 /* pkcs9 */, + 862 /* postOfficeBox */, + 861 /* postalAddress */, + 661 /* postalCode */, + 683 /* ppBasis */, + 872 /* preferredDeliveryMethod */, + 873 /* presentationAddress */, + 406 /* prime-field */, + 409 /* prime192v1 */, + 410 /* prime192v2 */, + 411 /* prime192v3 */, + 412 /* prime239v1 */, + 413 /* prime239v2 */, + 414 /* prime239v3 */, + 415 /* prime256v1 */, + 886 /* protocolInformation */, + 510 /* pseudonym */, + 435 /* pss */, + 286 /* qcStatements */, + 457 /* qualityLabelledData */, + 450 /* rFC822localPart */, + 98 /* rc2-40-cbc */, + 166 /* rc2-64-cbc */, + 37 /* rc2-cbc */, + 39 /* rc2-cfb */, + 38 /* rc2-ecb */, + 40 /* rc2-ofb */, + 5 /* rc4 */, + 97 /* rc4-40 */, + 915 /* rc4-hmac-md5 */, + 120 /* rc5-cbc */, + 122 /* rc5-cfb */, + 121 /* rc5-ecb */, + 123 /* rc5-ofb */, + 870 /* registeredAddress */, + 460 /* rfc822Mailbox */, + 117 /* ripemd160 */, + 119 /* ripemd160WithRSA */, + 400 /* role */, + 877 /* roleOccupant */, + 448 /* room */, + 463 /* roomNumber */, + 19 /* rsa */, + 6 /* rsaEncryption */, + 644 /* rsaOAEPEncryptionSET */, + 377 /* rsaSignature */, + 919 /* rsaesOaep */, + 912 /* rsassaPss */, + 482 /* sOARecord */, + 155 /* safeContentsBag */, + 291 /* sbgp-autonomousSysNum */, + 290 /* sbgp-ipAddrBlock */, + 292 /* sbgp-routerIdentifier */, + 159 /* sdsiCertificate */, + 859 /* searchGuide */, + 704 /* secp112r1 */, + 705 /* secp112r2 */, + 706 /* secp128r1 */, + 707 /* secp128r2 */, + 708 /* secp160k1 */, + 709 /* secp160r1 */, + 710 /* secp160r2 */, + 711 /* secp192k1 */, + 712 /* secp224k1 */, + 713 /* secp224r1 */, + 714 /* secp256k1 */, + 715 /* secp384r1 */, + 716 /* secp521r1 */, + 154 /* secretBag */, + 474 /* secretary */, + 717 /* sect113r1 */, + 718 /* sect113r2 */, + 719 /* sect131r1 */, + 720 /* sect131r2 */, + 721 /* sect163k1 */, + 722 /* sect163r1 */, + 723 /* sect163r2 */, + 724 /* sect193r1 */, + 725 /* sect193r2 */, + 726 /* sect233k1 */, + 727 /* sect233r1 */, + 728 /* sect239k1 */, + 729 /* sect283k1 */, + 730 /* sect283r1 */, + 731 /* sect409k1 */, + 732 /* sect409r1 */, + 733 /* sect571k1 */, + 734 /* sect571r1 */, + 635 /* secure device signature */, + 878 /* seeAlso */, + 777 /* seed-cbc */, + 779 /* seed-cfb */, + 776 /* seed-ecb */, + 778 /* seed-ofb */, + 105 /* serialNumber */, + 625 /* set-addPolicy */, + 515 /* set-attr */, + 518 /* set-brand */, + 638 /* set-brand-AmericanExpress */, + 637 /* set-brand-Diners */, + 636 /* set-brand-IATA-ATA */, + 639 /* set-brand-JCB */, + 641 /* set-brand-MasterCard */, + 642 /* set-brand-Novus */, + 640 /* set-brand-Visa */, + 516 /* set-policy */, + 607 /* set-policy-root */, + 624 /* set-rootKeyThumb */, + 620 /* setAttr-Cert */, + 628 /* setAttr-IssCap-CVM */, + 630 /* setAttr-IssCap-Sig */, + 629 /* setAttr-IssCap-T2 */, + 627 /* setAttr-Token-B0Prime */, + 626 /* setAttr-Token-EMV */, + 622 /* setAttr-TokenType */, + 619 /* setCext-IssuerCapabilities */, + 615 /* setCext-PGWYcapabilities */, + 616 /* setCext-TokenIdentifier */, + 618 /* setCext-TokenType */, + 617 /* setCext-Track2Data */, + 611 /* setCext-cCertRequired */, + 609 /* setCext-certType */, + 608 /* setCext-hashedRoot */, + 610 /* setCext-merchData */, + 613 /* setCext-setExt */, + 614 /* setCext-setQualf */, + 612 /* setCext-tunneling */, + 540 /* setct-AcqCardCodeMsg */, + 576 /* setct-AcqCardCodeMsgTBE */, + 570 /* setct-AuthReqTBE */, + 534 /* setct-AuthReqTBS */, + 527 /* setct-AuthResBaggage */, + 571 /* setct-AuthResTBE */, + 572 /* setct-AuthResTBEX */, + 535 /* setct-AuthResTBS */, + 536 /* setct-AuthResTBSX */, + 528 /* setct-AuthRevReqBaggage */, + 577 /* setct-AuthRevReqTBE */, + 541 /* setct-AuthRevReqTBS */, + 529 /* setct-AuthRevResBaggage */, + 542 /* setct-AuthRevResData */, + 578 /* setct-AuthRevResTBE */, + 579 /* setct-AuthRevResTBEB */, + 543 /* setct-AuthRevResTBS */, + 573 /* setct-AuthTokenTBE */, + 537 /* setct-AuthTokenTBS */, + 600 /* setct-BCIDistributionTBS */, + 558 /* setct-BatchAdminReqData */, + 592 /* setct-BatchAdminReqTBE */, + 559 /* setct-BatchAdminResData */, + 593 /* setct-BatchAdminResTBE */, + 599 /* setct-CRLNotificationResTBS */, + 598 /* setct-CRLNotificationTBS */, + 580 /* setct-CapReqTBE */, + 581 /* setct-CapReqTBEX */, + 544 /* setct-CapReqTBS */, + 545 /* setct-CapReqTBSX */, + 546 /* setct-CapResData */, + 582 /* setct-CapResTBE */, + 583 /* setct-CapRevReqTBE */, + 584 /* setct-CapRevReqTBEX */, + 547 /* setct-CapRevReqTBS */, + 548 /* setct-CapRevReqTBSX */, + 549 /* setct-CapRevResData */, + 585 /* setct-CapRevResTBE */, + 538 /* setct-CapTokenData */, + 530 /* setct-CapTokenSeq */, + 574 /* setct-CapTokenTBE */, + 575 /* setct-CapTokenTBEX */, + 539 /* setct-CapTokenTBS */, + 560 /* setct-CardCInitResTBS */, + 566 /* setct-CertInqReqTBS */, + 563 /* setct-CertReqData */, + 595 /* setct-CertReqTBE */, + 596 /* setct-CertReqTBEX */, + 564 /* setct-CertReqTBS */, + 565 /* setct-CertResData */, + 597 /* setct-CertResTBE */, + 586 /* setct-CredReqTBE */, + 587 /* setct-CredReqTBEX */, + 550 /* setct-CredReqTBS */, + 551 /* setct-CredReqTBSX */, + 552 /* setct-CredResData */, + 588 /* setct-CredResTBE */, + 589 /* setct-CredRevReqTBE */, + 590 /* setct-CredRevReqTBEX */, + 553 /* setct-CredRevReqTBS */, + 554 /* setct-CredRevReqTBSX */, + 555 /* setct-CredRevResData */, + 591 /* setct-CredRevResTBE */, + 567 /* setct-ErrorTBS */, + 526 /* setct-HODInput */, + 561 /* setct-MeAqCInitResTBS */, + 522 /* setct-OIData */, + 519 /* setct-PANData */, + 521 /* setct-PANOnly */, + 520 /* setct-PANToken */, + 556 /* setct-PCertReqData */, + 557 /* setct-PCertResTBS */, + 523 /* setct-PI */, + 532 /* setct-PI-TBS */, + 524 /* setct-PIData */, + 525 /* setct-PIDataUnsigned */, + 568 /* setct-PIDualSignedTBE */, + 569 /* setct-PIUnsignedTBE */, + 531 /* setct-PInitResData */, + 533 /* setct-PResData */, + 594 /* setct-RegFormReqTBE */, + 562 /* setct-RegFormResTBS */, + 604 /* setext-pinAny */, + 603 /* setext-pinSecure */, + 605 /* setext-track2 */, + 41 /* sha */, + 64 /* sha1 */, + 115 /* sha1WithRSA */, + 65 /* sha1WithRSAEncryption */, + 675 /* sha224 */, + 671 /* sha224WithRSAEncryption */, + 672 /* sha256 */, + 668 /* sha256WithRSAEncryption */, + 673 /* sha384 */, + 669 /* sha384WithRSAEncryption */, + 674 /* sha512 */, + 962 /* sha512-256 */, + 670 /* sha512WithRSAEncryption */, + 42 /* shaWithRSAEncryption */, + 52 /* signingTime */, + 454 /* simpleSecurityObject */, + 496 /* singleLevelQuality */, + 16 /* stateOrProvinceName */, + 660 /* streetAddress */, + 498 /* subtreeMaximumQuality */, + 497 /* subtreeMinimumQuality */, + 890 /* supportedAlgorithms */, + 874 /* supportedApplicationContext */, + 100 /* surname */, + 864 /* telephoneNumber */, + 866 /* teletexTerminalIdentifier */, + 865 /* telexNumber */, + 459 /* textEncodedORAddress */, + 293 /* textNotice */, + 106 /* title */, + 682 /* tpBasis */, + 436 /* ucl */, + 0 /* undefined */, + 888 /* uniqueMember */, + 55 /* unstructuredAddress */, + 49 /* unstructuredName */, + 880 /* userCertificate */, + 465 /* userClass */, + 458 /* userId */, + 879 /* userPassword */, + 373 /* valid */, + 678 /* wap */, + 679 /* wap-wsg */, + 735 /* wap-wsg-idm-ecid-wtls1 */, + 743 /* wap-wsg-idm-ecid-wtls10 */, + 744 /* wap-wsg-idm-ecid-wtls11 */, + 745 /* wap-wsg-idm-ecid-wtls12 */, + 736 /* wap-wsg-idm-ecid-wtls3 */, + 737 /* wap-wsg-idm-ecid-wtls4 */, + 738 /* wap-wsg-idm-ecid-wtls5 */, + 739 /* wap-wsg-idm-ecid-wtls6 */, + 740 /* wap-wsg-idm-ecid-wtls7 */, + 741 /* wap-wsg-idm-ecid-wtls8 */, + 742 /* wap-wsg-idm-ecid-wtls9 */, + 804 /* whirlpool */, + 868 /* x121Address */, + 503 /* x500UniqueIdentifier */, + 158 /* x509Certificate */, + 160 /* x509Crl */, + 125 /* zlib compression */, +}; + +static const uint16_t kNIDsInOIDOrder[] = { + 434 /* 0.9 (OBJ_data) */, + 182 /* 1.2 (OBJ_member_body) */, + 379 /* 1.3 (OBJ_org) */, + 676 /* 1.3 (OBJ_identified_organization) */, + 11 /* 2.5 (OBJ_X500) */, + 647 /* 2.23 (OBJ_international_organizations) */, + 380 /* 1.3.6 (OBJ_dod) */, + 12 /* 2.5.4 (OBJ_X509) */, + 378 /* 2.5.8 (OBJ_X500algorithms) */, + 81 /* 2.5.29 (OBJ_id_ce) */, + 512 /* 2.23.42 (OBJ_id_set) */, + 678 /* 2.23.43 (OBJ_wap) */, + 435 /* 0.9.2342 (OBJ_pss) */, + 183 /* 1.2.840 (OBJ_ISO_US) */, + 381 /* 1.3.6.1 (OBJ_iana) */, + 948 /* 1.3.101.110 (OBJ_X25519) */, + 961 /* 1.3.101.111 (OBJ_X448) */, + 949 /* 1.3.101.112 (OBJ_ED25519) */, + 960 /* 1.3.101.113 (OBJ_ED448) */, + 677 /* 1.3.132 (OBJ_certicom_arc) */, + 394 /* 2.5.1.5 (OBJ_selected_attribute_types) */, + 13 /* 2.5.4.3 (OBJ_commonName) */, + 100 /* 2.5.4.4 (OBJ_surname) */, + 105 /* 2.5.4.5 (OBJ_serialNumber) */, + 14 /* 2.5.4.6 (OBJ_countryName) */, + 15 /* 2.5.4.7 (OBJ_localityName) */, + 16 /* 2.5.4.8 (OBJ_stateOrProvinceName) */, + 660 /* 2.5.4.9 (OBJ_streetAddress) */, + 17 /* 2.5.4.10 (OBJ_organizationName) */, + 18 /* 2.5.4.11 (OBJ_organizationalUnitName) */, + 106 /* 2.5.4.12 (OBJ_title) */, + 107 /* 2.5.4.13 (OBJ_description) */, + 859 /* 2.5.4.14 (OBJ_searchGuide) */, + 860 /* 2.5.4.15 (OBJ_businessCategory) */, + 861 /* 2.5.4.16 (OBJ_postalAddress) */, + 661 /* 2.5.4.17 (OBJ_postalCode) */, + 862 /* 2.5.4.18 (OBJ_postOfficeBox) */, + 863 /* 2.5.4.19 (OBJ_physicalDeliveryOfficeName) */, + 864 /* 2.5.4.20 (OBJ_telephoneNumber) */, + 865 /* 2.5.4.21 (OBJ_telexNumber) */, + 866 /* 2.5.4.22 (OBJ_teletexTerminalIdentifier) */, + 867 /* 2.5.4.23 (OBJ_facsimileTelephoneNumber) */, + 868 /* 2.5.4.24 (OBJ_x121Address) */, + 869 /* 2.5.4.25 (OBJ_internationaliSDNNumber) */, + 870 /* 2.5.4.26 (OBJ_registeredAddress) */, + 871 /* 2.5.4.27 (OBJ_destinationIndicator) */, + 872 /* 2.5.4.28 (OBJ_preferredDeliveryMethod) */, + 873 /* 2.5.4.29 (OBJ_presentationAddress) */, + 874 /* 2.5.4.30 (OBJ_supportedApplicationContext) */, + 875 /* 2.5.4.31 (OBJ_member) */, + 876 /* 2.5.4.32 (OBJ_owner) */, + 877 /* 2.5.4.33 (OBJ_roleOccupant) */, + 878 /* 2.5.4.34 (OBJ_seeAlso) */, + 879 /* 2.5.4.35 (OBJ_userPassword) */, + 880 /* 2.5.4.36 (OBJ_userCertificate) */, + 881 /* 2.5.4.37 (OBJ_cACertificate) */, + 882 /* 2.5.4.38 (OBJ_authorityRevocationList) */, + 883 /* 2.5.4.39 (OBJ_certificateRevocationList) */, + 884 /* 2.5.4.40 (OBJ_crossCertificatePair) */, + 173 /* 2.5.4.41 (OBJ_name) */, + 99 /* 2.5.4.42 (OBJ_givenName) */, + 101 /* 2.5.4.43 (OBJ_initials) */, + 509 /* 2.5.4.44 (OBJ_generationQualifier) */, + 503 /* 2.5.4.45 (OBJ_x500UniqueIdentifier) */, + 174 /* 2.5.4.46 (OBJ_dnQualifier) */, + 885 /* 2.5.4.47 (OBJ_enhancedSearchGuide) */, + 886 /* 2.5.4.48 (OBJ_protocolInformation) */, + 887 /* 2.5.4.49 (OBJ_distinguishedName) */, + 888 /* 2.5.4.50 (OBJ_uniqueMember) */, + 889 /* 2.5.4.51 (OBJ_houseIdentifier) */, + 890 /* 2.5.4.52 (OBJ_supportedAlgorithms) */, + 891 /* 2.5.4.53 (OBJ_deltaRevocationList) */, + 892 /* 2.5.4.54 (OBJ_dmdName) */, + 510 /* 2.5.4.65 (OBJ_pseudonym) */, + 400 /* 2.5.4.72 (OBJ_role) */, + 769 /* 2.5.29.9 (OBJ_subject_directory_attributes) */, + 82 /* 2.5.29.14 (OBJ_subject_key_identifier) */, + 83 /* 2.5.29.15 (OBJ_key_usage) */, + 84 /* 2.5.29.16 (OBJ_private_key_usage_period) */, + 85 /* 2.5.29.17 (OBJ_subject_alt_name) */, + 86 /* 2.5.29.18 (OBJ_issuer_alt_name) */, + 87 /* 2.5.29.19 (OBJ_basic_constraints) */, + 88 /* 2.5.29.20 (OBJ_crl_number) */, + 141 /* 2.5.29.21 (OBJ_crl_reason) */, + 430 /* 2.5.29.23 (OBJ_hold_instruction_code) */, + 142 /* 2.5.29.24 (OBJ_invalidity_date) */, + 140 /* 2.5.29.27 (OBJ_delta_crl) */, + 770 /* 2.5.29.28 (OBJ_issuing_distribution_point) */, + 771 /* 2.5.29.29 (OBJ_certificate_issuer) */, + 666 /* 2.5.29.30 (OBJ_name_constraints) */, + 103 /* 2.5.29.31 (OBJ_crl_distribution_points) */, + 89 /* 2.5.29.32 (OBJ_certificate_policies) */, + 747 /* 2.5.29.33 (OBJ_policy_mappings) */, + 90 /* 2.5.29.35 (OBJ_authority_key_identifier) */, + 401 /* 2.5.29.36 (OBJ_policy_constraints) */, + 126 /* 2.5.29.37 (OBJ_ext_key_usage) */, + 857 /* 2.5.29.46 (OBJ_freshest_crl) */, + 748 /* 2.5.29.54 (OBJ_inhibit_any_policy) */, + 402 /* 2.5.29.55 (OBJ_target_information) */, + 403 /* 2.5.29.56 (OBJ_no_rev_avail) */, + 513 /* 2.23.42.0 (OBJ_set_ctype) */, + 514 /* 2.23.42.1 (OBJ_set_msgExt) */, + 515 /* 2.23.42.3 (OBJ_set_attr) */, + 516 /* 2.23.42.5 (OBJ_set_policy) */, + 517 /* 2.23.42.7 (OBJ_set_certExt) */, + 518 /* 2.23.42.8 (OBJ_set_brand) */, + 679 /* 2.23.43.1 (OBJ_wap_wsg) */, + 382 /* 1.3.6.1.1 (OBJ_Directory) */, + 383 /* 1.3.6.1.2 (OBJ_Management) */, + 384 /* 1.3.6.1.3 (OBJ_Experimental) */, + 385 /* 1.3.6.1.4 (OBJ_Private) */, + 386 /* 1.3.6.1.5 (OBJ_Security) */, + 387 /* 1.3.6.1.6 (OBJ_SNMPv2) */, + 388 /* 1.3.6.1.7 (OBJ_Mail) */, + 376 /* 1.3.14.3.2 (OBJ_algorithm) */, + 395 /* 2.5.1.5.55 (OBJ_clearance) */, + 19 /* 2.5.8.1.1 (OBJ_rsa) */, + 96 /* 2.5.8.3.100 (OBJ_mdc2WithRSA) */, + 95 /* 2.5.8.3.101 (OBJ_mdc2) */, + 746 /* 2.5.29.32.0 (OBJ_any_policy) */, + 910 /* 2.5.29.37.0 (OBJ_anyExtendedKeyUsage) */, + 519 /* 2.23.42.0.0 (OBJ_setct_PANData) */, + 520 /* 2.23.42.0.1 (OBJ_setct_PANToken) */, + 521 /* 2.23.42.0.2 (OBJ_setct_PANOnly) */, + 522 /* 2.23.42.0.3 (OBJ_setct_OIData) */, + 523 /* 2.23.42.0.4 (OBJ_setct_PI) */, + 524 /* 2.23.42.0.5 (OBJ_setct_PIData) */, + 525 /* 2.23.42.0.6 (OBJ_setct_PIDataUnsigned) */, + 526 /* 2.23.42.0.7 (OBJ_setct_HODInput) */, + 527 /* 2.23.42.0.8 (OBJ_setct_AuthResBaggage) */, + 528 /* 2.23.42.0.9 (OBJ_setct_AuthRevReqBaggage) */, + 529 /* 2.23.42.0.10 (OBJ_setct_AuthRevResBaggage) */, + 530 /* 2.23.42.0.11 (OBJ_setct_CapTokenSeq) */, + 531 /* 2.23.42.0.12 (OBJ_setct_PInitResData) */, + 532 /* 2.23.42.0.13 (OBJ_setct_PI_TBS) */, + 533 /* 2.23.42.0.14 (OBJ_setct_PResData) */, + 534 /* 2.23.42.0.16 (OBJ_setct_AuthReqTBS) */, + 535 /* 2.23.42.0.17 (OBJ_setct_AuthResTBS) */, + 536 /* 2.23.42.0.18 (OBJ_setct_AuthResTBSX) */, + 537 /* 2.23.42.0.19 (OBJ_setct_AuthTokenTBS) */, + 538 /* 2.23.42.0.20 (OBJ_setct_CapTokenData) */, + 539 /* 2.23.42.0.21 (OBJ_setct_CapTokenTBS) */, + 540 /* 2.23.42.0.22 (OBJ_setct_AcqCardCodeMsg) */, + 541 /* 2.23.42.0.23 (OBJ_setct_AuthRevReqTBS) */, + 542 /* 2.23.42.0.24 (OBJ_setct_AuthRevResData) */, + 543 /* 2.23.42.0.25 (OBJ_setct_AuthRevResTBS) */, + 544 /* 2.23.42.0.26 (OBJ_setct_CapReqTBS) */, + 545 /* 2.23.42.0.27 (OBJ_setct_CapReqTBSX) */, + 546 /* 2.23.42.0.28 (OBJ_setct_CapResData) */, + 547 /* 2.23.42.0.29 (OBJ_setct_CapRevReqTBS) */, + 548 /* 2.23.42.0.30 (OBJ_setct_CapRevReqTBSX) */, + 549 /* 2.23.42.0.31 (OBJ_setct_CapRevResData) */, + 550 /* 2.23.42.0.32 (OBJ_setct_CredReqTBS) */, + 551 /* 2.23.42.0.33 (OBJ_setct_CredReqTBSX) */, + 552 /* 2.23.42.0.34 (OBJ_setct_CredResData) */, + 553 /* 2.23.42.0.35 (OBJ_setct_CredRevReqTBS) */, + 554 /* 2.23.42.0.36 (OBJ_setct_CredRevReqTBSX) */, + 555 /* 2.23.42.0.37 (OBJ_setct_CredRevResData) */, + 556 /* 2.23.42.0.38 (OBJ_setct_PCertReqData) */, + 557 /* 2.23.42.0.39 (OBJ_setct_PCertResTBS) */, + 558 /* 2.23.42.0.40 (OBJ_setct_BatchAdminReqData) */, + 559 /* 2.23.42.0.41 (OBJ_setct_BatchAdminResData) */, + 560 /* 2.23.42.0.42 (OBJ_setct_CardCInitResTBS) */, + 561 /* 2.23.42.0.43 (OBJ_setct_MeAqCInitResTBS) */, + 562 /* 2.23.42.0.44 (OBJ_setct_RegFormResTBS) */, + 563 /* 2.23.42.0.45 (OBJ_setct_CertReqData) */, + 564 /* 2.23.42.0.46 (OBJ_setct_CertReqTBS) */, + 565 /* 2.23.42.0.47 (OBJ_setct_CertResData) */, + 566 /* 2.23.42.0.48 (OBJ_setct_CertInqReqTBS) */, + 567 /* 2.23.42.0.49 (OBJ_setct_ErrorTBS) */, + 568 /* 2.23.42.0.50 (OBJ_setct_PIDualSignedTBE) */, + 569 /* 2.23.42.0.51 (OBJ_setct_PIUnsignedTBE) */, + 570 /* 2.23.42.0.52 (OBJ_setct_AuthReqTBE) */, + 571 /* 2.23.42.0.53 (OBJ_setct_AuthResTBE) */, + 572 /* 2.23.42.0.54 (OBJ_setct_AuthResTBEX) */, + 573 /* 2.23.42.0.55 (OBJ_setct_AuthTokenTBE) */, + 574 /* 2.23.42.0.56 (OBJ_setct_CapTokenTBE) */, + 575 /* 2.23.42.0.57 (OBJ_setct_CapTokenTBEX) */, + 576 /* 2.23.42.0.58 (OBJ_setct_AcqCardCodeMsgTBE) */, + 577 /* 2.23.42.0.59 (OBJ_setct_AuthRevReqTBE) */, + 578 /* 2.23.42.0.60 (OBJ_setct_AuthRevResTBE) */, + 579 /* 2.23.42.0.61 (OBJ_setct_AuthRevResTBEB) */, + 580 /* 2.23.42.0.62 (OBJ_setct_CapReqTBE) */, + 581 /* 2.23.42.0.63 (OBJ_setct_CapReqTBEX) */, + 582 /* 2.23.42.0.64 (OBJ_setct_CapResTBE) */, + 583 /* 2.23.42.0.65 (OBJ_setct_CapRevReqTBE) */, + 584 /* 2.23.42.0.66 (OBJ_setct_CapRevReqTBEX) */, + 585 /* 2.23.42.0.67 (OBJ_setct_CapRevResTBE) */, + 586 /* 2.23.42.0.68 (OBJ_setct_CredReqTBE) */, + 587 /* 2.23.42.0.69 (OBJ_setct_CredReqTBEX) */, + 588 /* 2.23.42.0.70 (OBJ_setct_CredResTBE) */, + 589 /* 2.23.42.0.71 (OBJ_setct_CredRevReqTBE) */, + 590 /* 2.23.42.0.72 (OBJ_setct_CredRevReqTBEX) */, + 591 /* 2.23.42.0.73 (OBJ_setct_CredRevResTBE) */, + 592 /* 2.23.42.0.74 (OBJ_setct_BatchAdminReqTBE) */, + 593 /* 2.23.42.0.75 (OBJ_setct_BatchAdminResTBE) */, + 594 /* 2.23.42.0.76 (OBJ_setct_RegFormReqTBE) */, + 595 /* 2.23.42.0.77 (OBJ_setct_CertReqTBE) */, + 596 /* 2.23.42.0.78 (OBJ_setct_CertReqTBEX) */, + 597 /* 2.23.42.0.79 (OBJ_setct_CertResTBE) */, + 598 /* 2.23.42.0.80 (OBJ_setct_CRLNotificationTBS) */, + 599 /* 2.23.42.0.81 (OBJ_setct_CRLNotificationResTBS) */, + 600 /* 2.23.42.0.82 (OBJ_setct_BCIDistributionTBS) */, + 601 /* 2.23.42.1.1 (OBJ_setext_genCrypt) */, + 602 /* 2.23.42.1.3 (OBJ_setext_miAuth) */, + 603 /* 2.23.42.1.4 (OBJ_setext_pinSecure) */, + 604 /* 2.23.42.1.5 (OBJ_setext_pinAny) */, + 605 /* 2.23.42.1.7 (OBJ_setext_track2) */, + 606 /* 2.23.42.1.8 (OBJ_setext_cv) */, + 620 /* 2.23.42.3.0 (OBJ_setAttr_Cert) */, + 621 /* 2.23.42.3.1 (OBJ_setAttr_PGWYcap) */, + 622 /* 2.23.42.3.2 (OBJ_setAttr_TokenType) */, + 623 /* 2.23.42.3.3 (OBJ_setAttr_IssCap) */, + 607 /* 2.23.42.5.0 (OBJ_set_policy_root) */, + 608 /* 2.23.42.7.0 (OBJ_setCext_hashedRoot) */, + 609 /* 2.23.42.7.1 (OBJ_setCext_certType) */, + 610 /* 2.23.42.7.2 (OBJ_setCext_merchData) */, + 611 /* 2.23.42.7.3 (OBJ_setCext_cCertRequired) */, + 612 /* 2.23.42.7.4 (OBJ_setCext_tunneling) */, + 613 /* 2.23.42.7.5 (OBJ_setCext_setExt) */, + 614 /* 2.23.42.7.6 (OBJ_setCext_setQualf) */, + 615 /* 2.23.42.7.7 (OBJ_setCext_PGWYcapabilities) */, + 616 /* 2.23.42.7.8 (OBJ_setCext_TokenIdentifier) */, + 617 /* 2.23.42.7.9 (OBJ_setCext_Track2Data) */, + 618 /* 2.23.42.7.10 (OBJ_setCext_TokenType) */, + 619 /* 2.23.42.7.11 (OBJ_setCext_IssuerCapabilities) */, + 636 /* 2.23.42.8.1 (OBJ_set_brand_IATA_ATA) */, + 640 /* 2.23.42.8.4 (OBJ_set_brand_Visa) */, + 641 /* 2.23.42.8.5 (OBJ_set_brand_MasterCard) */, + 637 /* 2.23.42.8.30 (OBJ_set_brand_Diners) */, + 638 /* 2.23.42.8.34 (OBJ_set_brand_AmericanExpress) */, + 639 /* 2.23.42.8.35 (OBJ_set_brand_JCB) */, + 805 /* 1.2.643.2.2 (OBJ_cryptopro) */, + 806 /* 1.2.643.2.9 (OBJ_cryptocom) */, + 184 /* 1.2.840.10040 (OBJ_X9_57) */, + 405 /* 1.2.840.10045 (OBJ_ansi_X9_62) */, + 389 /* 1.3.6.1.4.1 (OBJ_Enterprises) */, + 504 /* 1.3.6.1.7.1 (OBJ_mime_mhs) */, + 104 /* 1.3.14.3.2.3 (OBJ_md5WithRSA) */, + 29 /* 1.3.14.3.2.6 (OBJ_des_ecb) */, + 31 /* 1.3.14.3.2.7 (OBJ_des_cbc) */, + 45 /* 1.3.14.3.2.8 (OBJ_des_ofb64) */, + 30 /* 1.3.14.3.2.9 (OBJ_des_cfb64) */, + 377 /* 1.3.14.3.2.11 (OBJ_rsaSignature) */, + 67 /* 1.3.14.3.2.12 (OBJ_dsa_2) */, + 66 /* 1.3.14.3.2.13 (OBJ_dsaWithSHA) */, + 42 /* 1.3.14.3.2.15 (OBJ_shaWithRSAEncryption) */, + 32 /* 1.3.14.3.2.17 (OBJ_des_ede_ecb) */, + 41 /* 1.3.14.3.2.18 (OBJ_sha) */, + 64 /* 1.3.14.3.2.26 (OBJ_sha1) */, + 70 /* 1.3.14.3.2.27 (OBJ_dsaWithSHA1_2) */, + 115 /* 1.3.14.3.2.29 (OBJ_sha1WithRSA) */, + 117 /* 1.3.36.3.2.1 (OBJ_ripemd160) */, + 143 /* 1.3.101.1.4.1 (OBJ_sxnet) */, + 721 /* 1.3.132.0.1 (OBJ_sect163k1) */, + 722 /* 1.3.132.0.2 (OBJ_sect163r1) */, + 728 /* 1.3.132.0.3 (OBJ_sect239k1) */, + 717 /* 1.3.132.0.4 (OBJ_sect113r1) */, + 718 /* 1.3.132.0.5 (OBJ_sect113r2) */, + 704 /* 1.3.132.0.6 (OBJ_secp112r1) */, + 705 /* 1.3.132.0.7 (OBJ_secp112r2) */, + 709 /* 1.3.132.0.8 (OBJ_secp160r1) */, + 708 /* 1.3.132.0.9 (OBJ_secp160k1) */, + 714 /* 1.3.132.0.10 (OBJ_secp256k1) */, + 723 /* 1.3.132.0.15 (OBJ_sect163r2) */, + 729 /* 1.3.132.0.16 (OBJ_sect283k1) */, + 730 /* 1.3.132.0.17 (OBJ_sect283r1) */, + 719 /* 1.3.132.0.22 (OBJ_sect131r1) */, + 720 /* 1.3.132.0.23 (OBJ_sect131r2) */, + 724 /* 1.3.132.0.24 (OBJ_sect193r1) */, + 725 /* 1.3.132.0.25 (OBJ_sect193r2) */, + 726 /* 1.3.132.0.26 (OBJ_sect233k1) */, + 727 /* 1.3.132.0.27 (OBJ_sect233r1) */, + 706 /* 1.3.132.0.28 (OBJ_secp128r1) */, + 707 /* 1.3.132.0.29 (OBJ_secp128r2) */, + 710 /* 1.3.132.0.30 (OBJ_secp160r2) */, + 711 /* 1.3.132.0.31 (OBJ_secp192k1) */, + 712 /* 1.3.132.0.32 (OBJ_secp224k1) */, + 713 /* 1.3.132.0.33 (OBJ_secp224r1) */, + 715 /* 1.3.132.0.34 (OBJ_secp384r1) */, + 716 /* 1.3.132.0.35 (OBJ_secp521r1) */, + 731 /* 1.3.132.0.36 (OBJ_sect409k1) */, + 732 /* 1.3.132.0.37 (OBJ_sect409r1) */, + 733 /* 1.3.132.0.38 (OBJ_sect571k1) */, + 734 /* 1.3.132.0.39 (OBJ_sect571r1) */, + 624 /* 2.23.42.3.0.0 (OBJ_set_rootKeyThumb) */, + 625 /* 2.23.42.3.0.1 (OBJ_set_addPolicy) */, + 626 /* 2.23.42.3.2.1 (OBJ_setAttr_Token_EMV) */, + 627 /* 2.23.42.3.2.2 (OBJ_setAttr_Token_B0Prime) */, + 628 /* 2.23.42.3.3.3 (OBJ_setAttr_IssCap_CVM) */, + 629 /* 2.23.42.3.3.4 (OBJ_setAttr_IssCap_T2) */, + 630 /* 2.23.42.3.3.5 (OBJ_setAttr_IssCap_Sig) */, + 642 /* 2.23.42.8.6011 (OBJ_set_brand_Novus) */, + 735 /* 2.23.43.1.4.1 (OBJ_wap_wsg_idm_ecid_wtls1) */, + 736 /* 2.23.43.1.4.3 (OBJ_wap_wsg_idm_ecid_wtls3) */, + 737 /* 2.23.43.1.4.4 (OBJ_wap_wsg_idm_ecid_wtls4) */, + 738 /* 2.23.43.1.4.5 (OBJ_wap_wsg_idm_ecid_wtls5) */, + 739 /* 2.23.43.1.4.6 (OBJ_wap_wsg_idm_ecid_wtls6) */, + 740 /* 2.23.43.1.4.7 (OBJ_wap_wsg_idm_ecid_wtls7) */, + 741 /* 2.23.43.1.4.8 (OBJ_wap_wsg_idm_ecid_wtls8) */, + 742 /* 2.23.43.1.4.9 (OBJ_wap_wsg_idm_ecid_wtls9) */, + 743 /* 2.23.43.1.4.10 (OBJ_wap_wsg_idm_ecid_wtls10) */, + 744 /* 2.23.43.1.4.11 (OBJ_wap_wsg_idm_ecid_wtls11) */, + 745 /* 2.23.43.1.4.12 (OBJ_wap_wsg_idm_ecid_wtls12) */, + 804 /* 1.0.10118.3.0.55 (OBJ_whirlpool) */, + 773 /* 1.2.410.200004 (OBJ_kisa) */, + 807 /* 1.2.643.2.2.3 (OBJ_id_GostR3411_94_with_GostR3410_2001) */, + 808 /* 1.2.643.2.2.4 (OBJ_id_GostR3411_94_with_GostR3410_94) */, + 809 /* 1.2.643.2.2.9 (OBJ_id_GostR3411_94) */, + 810 /* 1.2.643.2.2.10 (OBJ_id_HMACGostR3411_94) */, + 811 /* 1.2.643.2.2.19 (OBJ_id_GostR3410_2001) */, + 812 /* 1.2.643.2.2.20 (OBJ_id_GostR3410_94) */, + 813 /* 1.2.643.2.2.21 (OBJ_id_Gost28147_89) */, + 815 /* 1.2.643.2.2.22 (OBJ_id_Gost28147_89_MAC) */, + 816 /* 1.2.643.2.2.23 (OBJ_id_GostR3411_94_prf) */, + 817 /* 1.2.643.2.2.98 (OBJ_id_GostR3410_2001DH) */, + 818 /* 1.2.643.2.2.99 (OBJ_id_GostR3410_94DH) */, + 1 /* 1.2.840.113549 (OBJ_rsadsi) */, + 185 /* 1.2.840.10040.4 (OBJ_X9cm) */, + 127 /* 1.3.6.1.5.5.7 (OBJ_id_pkix) */, + 505 /* 1.3.6.1.7.1.1 (OBJ_mime_mhs_headings) */, + 506 /* 1.3.6.1.7.1.2 (OBJ_mime_mhs_bodies) */, + 119 /* 1.3.36.3.3.1.2 (OBJ_ripemd160WithRSA) */, + 937 /* 1.3.132.1.11.0 (OBJ_dhSinglePass_stdDH_sha224kdf_scheme) */, + 938 /* 1.3.132.1.11.1 (OBJ_dhSinglePass_stdDH_sha256kdf_scheme) */, + 939 /* 1.3.132.1.11.2 (OBJ_dhSinglePass_stdDH_sha384kdf_scheme) */, + 940 /* 1.3.132.1.11.3 (OBJ_dhSinglePass_stdDH_sha512kdf_scheme) */, + 942 /* 1.3.132.1.14.0 (OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme) */, + 943 /* 1.3.132.1.14.1 (OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme) */, + 944 /* 1.3.132.1.14.2 (OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme) */, + 945 /* 1.3.132.1.14.3 (OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme) */, + 631 /* 2.23.42.3.3.3.1 (OBJ_setAttr_GenCryptgrm) */, + 632 /* 2.23.42.3.3.4.1 (OBJ_setAttr_T2Enc) */, + 633 /* 2.23.42.3.3.4.2 (OBJ_setAttr_T2cleartxt) */, + 634 /* 2.23.42.3.3.5.1 (OBJ_setAttr_TokICCsig) */, + 635 /* 2.23.42.3.3.5.2 (OBJ_setAttr_SecDevSig) */, + 436 /* 0.9.2342.19200300 (OBJ_ucl) */, + 820 /* 1.2.643.2.2.14.0 (OBJ_id_Gost28147_89_None_KeyMeshing) */, + 819 /* 1.2.643.2.2.14.1 (OBJ_id_Gost28147_89_CryptoPro_KeyMeshing) */, + 845 /* 1.2.643.2.2.20.1 (OBJ_id_GostR3410_94_a) */, + 846 /* 1.2.643.2.2.20.2 (OBJ_id_GostR3410_94_aBis) */, + 847 /* 1.2.643.2.2.20.3 (OBJ_id_GostR3410_94_b) */, + 848 /* 1.2.643.2.2.20.4 (OBJ_id_GostR3410_94_bBis) */, + 821 /* 1.2.643.2.2.30.0 (OBJ_id_GostR3411_94_TestParamSet) */, + 822 /* 1.2.643.2.2.30.1 (OBJ_id_GostR3411_94_CryptoProParamSet) */, + 823 /* 1.2.643.2.2.31.0 (OBJ_id_Gost28147_89_TestParamSet) */, + 824 /* 1.2.643.2.2.31.1 (OBJ_id_Gost28147_89_CryptoPro_A_ParamSet) */, + 825 /* 1.2.643.2.2.31.2 (OBJ_id_Gost28147_89_CryptoPro_B_ParamSet) */, + 826 /* 1.2.643.2.2.31.3 (OBJ_id_Gost28147_89_CryptoPro_C_ParamSet) */, + 827 /* 1.2.643.2.2.31.4 (OBJ_id_Gost28147_89_CryptoPro_D_ParamSet) */, + 828 /* 1.2.643.2.2.31.5 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet) + */ + , + 829 /* 1.2.643.2.2.31.6 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet) + */ + , + 830 /* 1.2.643.2.2.31.7 (OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet) */, + 831 /* 1.2.643.2.2.32.0 (OBJ_id_GostR3410_94_TestParamSet) */, + 832 /* 1.2.643.2.2.32.2 (OBJ_id_GostR3410_94_CryptoPro_A_ParamSet) */, + 833 /* 1.2.643.2.2.32.3 (OBJ_id_GostR3410_94_CryptoPro_B_ParamSet) */, + 834 /* 1.2.643.2.2.32.4 (OBJ_id_GostR3410_94_CryptoPro_C_ParamSet) */, + 835 /* 1.2.643.2.2.32.5 (OBJ_id_GostR3410_94_CryptoPro_D_ParamSet) */, + 836 /* 1.2.643.2.2.33.1 (OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet) */, + 837 /* 1.2.643.2.2.33.2 (OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet) */, + 838 /* 1.2.643.2.2.33.3 (OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet) */, + 839 /* 1.2.643.2.2.35.0 (OBJ_id_GostR3410_2001_TestParamSet) */, + 840 /* 1.2.643.2.2.35.1 (OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet) */, + 841 /* 1.2.643.2.2.35.2 (OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet) */, + 842 /* 1.2.643.2.2.35.3 (OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet) */, + 843 /* 1.2.643.2.2.36.0 (OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet) */, + 844 /* 1.2.643.2.2.36.1 (OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet) */, + 2 /* 1.2.840.113549.1 (OBJ_pkcs) */, + 431 /* 1.2.840.10040.2.1 (OBJ_hold_instruction_none) */, + 432 /* 1.2.840.10040.2.2 (OBJ_hold_instruction_call_issuer) */, + 433 /* 1.2.840.10040.2.3 (OBJ_hold_instruction_reject) */, + 116 /* 1.2.840.10040.4.1 (OBJ_dsa) */, + 113 /* 1.2.840.10040.4.3 (OBJ_dsaWithSHA1) */, + 406 /* 1.2.840.10045.1.1 (OBJ_X9_62_prime_field) */, + 407 /* 1.2.840.10045.1.2 (OBJ_X9_62_characteristic_two_field) */, + 408 /* 1.2.840.10045.2.1 (OBJ_X9_62_id_ecPublicKey) */, + 416 /* 1.2.840.10045.4.1 (OBJ_ecdsa_with_SHA1) */, + 791 /* 1.2.840.10045.4.2 (OBJ_ecdsa_with_Recommended) */, + 792 /* 1.2.840.10045.4.3 (OBJ_ecdsa_with_Specified) */, + 920 /* 1.2.840.10046.2.1 (OBJ_dhpublicnumber) */, + 258 /* 1.3.6.1.5.5.7.0 (OBJ_id_pkix_mod) */, + 175 /* 1.3.6.1.5.5.7.1 (OBJ_id_pe) */, + 259 /* 1.3.6.1.5.5.7.2 (OBJ_id_qt) */, + 128 /* 1.3.6.1.5.5.7.3 (OBJ_id_kp) */, + 260 /* 1.3.6.1.5.5.7.4 (OBJ_id_it) */, + 261 /* 1.3.6.1.5.5.7.5 (OBJ_id_pkip) */, + 262 /* 1.3.6.1.5.5.7.6 (OBJ_id_alg) */, + 263 /* 1.3.6.1.5.5.7.7 (OBJ_id_cmc) */, + 264 /* 1.3.6.1.5.5.7.8 (OBJ_id_on) */, + 265 /* 1.3.6.1.5.5.7.9 (OBJ_id_pda) */, + 266 /* 1.3.6.1.5.5.7.10 (OBJ_id_aca) */, + 267 /* 1.3.6.1.5.5.7.11 (OBJ_id_qcs) */, + 268 /* 1.3.6.1.5.5.7.12 (OBJ_id_cct) */, + 662 /* 1.3.6.1.5.5.7.21 (OBJ_id_ppl) */, + 176 /* 1.3.6.1.5.5.7.48 (OBJ_id_ad) */, + 507 /* 1.3.6.1.7.1.1.1 (OBJ_id_hex_partial_message) */, + 508 /* 1.3.6.1.7.1.1.2 (OBJ_id_hex_multipart_message) */, + 57 /* 2.16.840.1.113730 (OBJ_netscape) */, + 754 /* 0.3.4401.5.3.1.9.1 (OBJ_camellia_128_ecb) */, + 766 /* 0.3.4401.5.3.1.9.3 (OBJ_camellia_128_ofb128) */, + 757 /* 0.3.4401.5.3.1.9.4 (OBJ_camellia_128_cfb128) */, + 755 /* 0.3.4401.5.3.1.9.21 (OBJ_camellia_192_ecb) */, + 767 /* 0.3.4401.5.3.1.9.23 (OBJ_camellia_192_ofb128) */, + 758 /* 0.3.4401.5.3.1.9.24 (OBJ_camellia_192_cfb128) */, + 756 /* 0.3.4401.5.3.1.9.41 (OBJ_camellia_256_ecb) */, + 768 /* 0.3.4401.5.3.1.9.43 (OBJ_camellia_256_ofb128) */, + 759 /* 0.3.4401.5.3.1.9.44 (OBJ_camellia_256_cfb128) */, + 437 /* 0.9.2342.19200300.100 (OBJ_pilot) */, + 776 /* 1.2.410.200004.1.3 (OBJ_seed_ecb) */, + 777 /* 1.2.410.200004.1.4 (OBJ_seed_cbc) */, + 779 /* 1.2.410.200004.1.5 (OBJ_seed_cfb128) */, + 778 /* 1.2.410.200004.1.6 (OBJ_seed_ofb128) */, + 852 /* 1.2.643.2.9.1.3.3 (OBJ_id_GostR3411_94_with_GostR3410_94_cc) */, + 853 /* 1.2.643.2.9.1.3.4 (OBJ_id_GostR3411_94_with_GostR3410_2001_cc) */, + 850 /* 1.2.643.2.9.1.5.3 (OBJ_id_GostR3410_94_cc) */, + 851 /* 1.2.643.2.9.1.5.4 (OBJ_id_GostR3410_2001_cc) */, + 849 /* 1.2.643.2.9.1.6.1 (OBJ_id_Gost28147_89_cc) */, + 854 /* 1.2.643.2.9.1.8.1 (OBJ_id_GostR3410_2001_ParamSet_cc) */, + 186 /* 1.2.840.113549.1.1 (OBJ_pkcs1) */, + 27 /* 1.2.840.113549.1.3 (OBJ_pkcs3) */, + 187 /* 1.2.840.113549.1.5 (OBJ_pkcs5) */, + 20 /* 1.2.840.113549.1.7 (OBJ_pkcs7) */, + 47 /* 1.2.840.113549.1.9 (OBJ_pkcs9) */, + 3 /* 1.2.840.113549.2.2 (OBJ_md2) */, + 257 /* 1.2.840.113549.2.4 (OBJ_md4) */, + 4 /* 1.2.840.113549.2.5 (OBJ_md5) */, + 797 /* 1.2.840.113549.2.6 (OBJ_hmacWithMD5) */, + 163 /* 1.2.840.113549.2.7 (OBJ_hmacWithSHA1) */, + 798 /* 1.2.840.113549.2.8 (OBJ_hmacWithSHA224) */, + 799 /* 1.2.840.113549.2.9 (OBJ_hmacWithSHA256) */, + 800 /* 1.2.840.113549.2.10 (OBJ_hmacWithSHA384) */, + 801 /* 1.2.840.113549.2.11 (OBJ_hmacWithSHA512) */, + 37 /* 1.2.840.113549.3.2 (OBJ_rc2_cbc) */, + 5 /* 1.2.840.113549.3.4 (OBJ_rc4) */, + 44 /* 1.2.840.113549.3.7 (OBJ_des_ede3_cbc) */, + 120 /* 1.2.840.113549.3.8 (OBJ_rc5_cbc) */, + 643 /* 1.2.840.113549.3.10 (OBJ_des_cdmf) */, + 680 /* 1.2.840.10045.1.2.3 (OBJ_X9_62_id_characteristic_two_basis) */, + 684 /* 1.2.840.10045.3.0.1 (OBJ_X9_62_c2pnb163v1) */, + 685 /* 1.2.840.10045.3.0.2 (OBJ_X9_62_c2pnb163v2) */, + 686 /* 1.2.840.10045.3.0.3 (OBJ_X9_62_c2pnb163v3) */, + 687 /* 1.2.840.10045.3.0.4 (OBJ_X9_62_c2pnb176v1) */, + 688 /* 1.2.840.10045.3.0.5 (OBJ_X9_62_c2tnb191v1) */, + 689 /* 1.2.840.10045.3.0.6 (OBJ_X9_62_c2tnb191v2) */, + 690 /* 1.2.840.10045.3.0.7 (OBJ_X9_62_c2tnb191v3) */, + 691 /* 1.2.840.10045.3.0.8 (OBJ_X9_62_c2onb191v4) */, + 692 /* 1.2.840.10045.3.0.9 (OBJ_X9_62_c2onb191v5) */, + 693 /* 1.2.840.10045.3.0.10 (OBJ_X9_62_c2pnb208w1) */, + 694 /* 1.2.840.10045.3.0.11 (OBJ_X9_62_c2tnb239v1) */, + 695 /* 1.2.840.10045.3.0.12 (OBJ_X9_62_c2tnb239v2) */, + 696 /* 1.2.840.10045.3.0.13 (OBJ_X9_62_c2tnb239v3) */, + 697 /* 1.2.840.10045.3.0.14 (OBJ_X9_62_c2onb239v4) */, + 698 /* 1.2.840.10045.3.0.15 (OBJ_X9_62_c2onb239v5) */, + 699 /* 1.2.840.10045.3.0.16 (OBJ_X9_62_c2pnb272w1) */, + 700 /* 1.2.840.10045.3.0.17 (OBJ_X9_62_c2pnb304w1) */, + 701 /* 1.2.840.10045.3.0.18 (OBJ_X9_62_c2tnb359v1) */, + 702 /* 1.2.840.10045.3.0.19 (OBJ_X9_62_c2pnb368w1) */, + 703 /* 1.2.840.10045.3.0.20 (OBJ_X9_62_c2tnb431r1) */, + 409 /* 1.2.840.10045.3.1.1 (OBJ_X9_62_prime192v1) */, + 410 /* 1.2.840.10045.3.1.2 (OBJ_X9_62_prime192v2) */, + 411 /* 1.2.840.10045.3.1.3 (OBJ_X9_62_prime192v3) */, + 412 /* 1.2.840.10045.3.1.4 (OBJ_X9_62_prime239v1) */, + 413 /* 1.2.840.10045.3.1.5 (OBJ_X9_62_prime239v2) */, + 414 /* 1.2.840.10045.3.1.6 (OBJ_X9_62_prime239v3) */, + 415 /* 1.2.840.10045.3.1.7 (OBJ_X9_62_prime256v1) */, + 793 /* 1.2.840.10045.4.3.1 (OBJ_ecdsa_with_SHA224) */, + 794 /* 1.2.840.10045.4.3.2 (OBJ_ecdsa_with_SHA256) */, + 795 /* 1.2.840.10045.4.3.3 (OBJ_ecdsa_with_SHA384) */, + 796 /* 1.2.840.10045.4.3.4 (OBJ_ecdsa_with_SHA512) */, + 269 /* 1.3.6.1.5.5.7.0.1 (OBJ_id_pkix1_explicit_88) */, + 270 /* 1.3.6.1.5.5.7.0.2 (OBJ_id_pkix1_implicit_88) */, + 271 /* 1.3.6.1.5.5.7.0.3 (OBJ_id_pkix1_explicit_93) */, + 272 /* 1.3.6.1.5.5.7.0.4 (OBJ_id_pkix1_implicit_93) */, + 273 /* 1.3.6.1.5.5.7.0.5 (OBJ_id_mod_crmf) */, + 274 /* 1.3.6.1.5.5.7.0.6 (OBJ_id_mod_cmc) */, + 275 /* 1.3.6.1.5.5.7.0.7 (OBJ_id_mod_kea_profile_88) */, + 276 /* 1.3.6.1.5.5.7.0.8 (OBJ_id_mod_kea_profile_93) */, + 277 /* 1.3.6.1.5.5.7.0.9 (OBJ_id_mod_cmp) */, + 278 /* 1.3.6.1.5.5.7.0.10 (OBJ_id_mod_qualified_cert_88) */, + 279 /* 1.3.6.1.5.5.7.0.11 (OBJ_id_mod_qualified_cert_93) */, + 280 /* 1.3.6.1.5.5.7.0.12 (OBJ_id_mod_attribute_cert) */, + 281 /* 1.3.6.1.5.5.7.0.13 (OBJ_id_mod_timestamp_protocol) */, + 282 /* 1.3.6.1.5.5.7.0.14 (OBJ_id_mod_ocsp) */, + 283 /* 1.3.6.1.5.5.7.0.15 (OBJ_id_mod_dvcs) */, + 284 /* 1.3.6.1.5.5.7.0.16 (OBJ_id_mod_cmp2000) */, + 177 /* 1.3.6.1.5.5.7.1.1 (OBJ_info_access) */, + 285 /* 1.3.6.1.5.5.7.1.2 (OBJ_biometricInfo) */, + 286 /* 1.3.6.1.5.5.7.1.3 (OBJ_qcStatements) */, + 287 /* 1.3.6.1.5.5.7.1.4 (OBJ_ac_auditEntity) */, + 288 /* 1.3.6.1.5.5.7.1.5 (OBJ_ac_targeting) */, + 289 /* 1.3.6.1.5.5.7.1.6 (OBJ_aaControls) */, + 290 /* 1.3.6.1.5.5.7.1.7 (OBJ_sbgp_ipAddrBlock) */, + 291 /* 1.3.6.1.5.5.7.1.8 (OBJ_sbgp_autonomousSysNum) */, + 292 /* 1.3.6.1.5.5.7.1.9 (OBJ_sbgp_routerIdentifier) */, + 397 /* 1.3.6.1.5.5.7.1.10 (OBJ_ac_proxying) */, + 398 /* 1.3.6.1.5.5.7.1.11 (OBJ_sinfo_access) */, + 663 /* 1.3.6.1.5.5.7.1.14 (OBJ_proxyCertInfo) */, + 164 /* 1.3.6.1.5.5.7.2.1 (OBJ_id_qt_cps) */, + 165 /* 1.3.6.1.5.5.7.2.2 (OBJ_id_qt_unotice) */, + 293 /* 1.3.6.1.5.5.7.2.3 (OBJ_textNotice) */, + 129 /* 1.3.6.1.5.5.7.3.1 (OBJ_server_auth) */, + 130 /* 1.3.6.1.5.5.7.3.2 (OBJ_client_auth) */, + 131 /* 1.3.6.1.5.5.7.3.3 (OBJ_code_sign) */, + 132 /* 1.3.6.1.5.5.7.3.4 (OBJ_email_protect) */, + 294 /* 1.3.6.1.5.5.7.3.5 (OBJ_ipsecEndSystem) */, + 295 /* 1.3.6.1.5.5.7.3.6 (OBJ_ipsecTunnel) */, + 296 /* 1.3.6.1.5.5.7.3.7 (OBJ_ipsecUser) */, + 133 /* 1.3.6.1.5.5.7.3.8 (OBJ_time_stamp) */, + 180 /* 1.3.6.1.5.5.7.3.9 (OBJ_OCSP_sign) */, + 297 /* 1.3.6.1.5.5.7.3.10 (OBJ_dvcs) */, + 298 /* 1.3.6.1.5.5.7.4.1 (OBJ_id_it_caProtEncCert) */, + 299 /* 1.3.6.1.5.5.7.4.2 (OBJ_id_it_signKeyPairTypes) */, + 300 /* 1.3.6.1.5.5.7.4.3 (OBJ_id_it_encKeyPairTypes) */, + 301 /* 1.3.6.1.5.5.7.4.4 (OBJ_id_it_preferredSymmAlg) */, + 302 /* 1.3.6.1.5.5.7.4.5 (OBJ_id_it_caKeyUpdateInfo) */, + 303 /* 1.3.6.1.5.5.7.4.6 (OBJ_id_it_currentCRL) */, + 304 /* 1.3.6.1.5.5.7.4.7 (OBJ_id_it_unsupportedOIDs) */, + 305 /* 1.3.6.1.5.5.7.4.8 (OBJ_id_it_subscriptionRequest) */, + 306 /* 1.3.6.1.5.5.7.4.9 (OBJ_id_it_subscriptionResponse) */, + 307 /* 1.3.6.1.5.5.7.4.10 (OBJ_id_it_keyPairParamReq) */, + 308 /* 1.3.6.1.5.5.7.4.11 (OBJ_id_it_keyPairParamRep) */, + 309 /* 1.3.6.1.5.5.7.4.12 (OBJ_id_it_revPassphrase) */, + 310 /* 1.3.6.1.5.5.7.4.13 (OBJ_id_it_implicitConfirm) */, + 311 /* 1.3.6.1.5.5.7.4.14 (OBJ_id_it_confirmWaitTime) */, + 312 /* 1.3.6.1.5.5.7.4.15 (OBJ_id_it_origPKIMessage) */, + 784 /* 1.3.6.1.5.5.7.4.16 (OBJ_id_it_suppLangTags) */, + 313 /* 1.3.6.1.5.5.7.5.1 (OBJ_id_regCtrl) */, + 314 /* 1.3.6.1.5.5.7.5.2 (OBJ_id_regInfo) */, + 323 /* 1.3.6.1.5.5.7.6.1 (OBJ_id_alg_des40) */, + 324 /* 1.3.6.1.5.5.7.6.2 (OBJ_id_alg_noSignature) */, + 325 /* 1.3.6.1.5.5.7.6.3 (OBJ_id_alg_dh_sig_hmac_sha1) */, + 326 /* 1.3.6.1.5.5.7.6.4 (OBJ_id_alg_dh_pop) */, + 327 /* 1.3.6.1.5.5.7.7.1 (OBJ_id_cmc_statusInfo) */, + 328 /* 1.3.6.1.5.5.7.7.2 (OBJ_id_cmc_identification) */, + 329 /* 1.3.6.1.5.5.7.7.3 (OBJ_id_cmc_identityProof) */, + 330 /* 1.3.6.1.5.5.7.7.4 (OBJ_id_cmc_dataReturn) */, + 331 /* 1.3.6.1.5.5.7.7.5 (OBJ_id_cmc_transactionId) */, + 332 /* 1.3.6.1.5.5.7.7.6 (OBJ_id_cmc_senderNonce) */, + 333 /* 1.3.6.1.5.5.7.7.7 (OBJ_id_cmc_recipientNonce) */, + 334 /* 1.3.6.1.5.5.7.7.8 (OBJ_id_cmc_addExtensions) */, + 335 /* 1.3.6.1.5.5.7.7.9 (OBJ_id_cmc_encryptedPOP) */, + 336 /* 1.3.6.1.5.5.7.7.10 (OBJ_id_cmc_decryptedPOP) */, + 337 /* 1.3.6.1.5.5.7.7.11 (OBJ_id_cmc_lraPOPWitness) */, + 338 /* 1.3.6.1.5.5.7.7.15 (OBJ_id_cmc_getCert) */, + 339 /* 1.3.6.1.5.5.7.7.16 (OBJ_id_cmc_getCRL) */, + 340 /* 1.3.6.1.5.5.7.7.17 (OBJ_id_cmc_revokeRequest) */, + 341 /* 1.3.6.1.5.5.7.7.18 (OBJ_id_cmc_regInfo) */, + 342 /* 1.3.6.1.5.5.7.7.19 (OBJ_id_cmc_responseInfo) */, + 343 /* 1.3.6.1.5.5.7.7.21 (OBJ_id_cmc_queryPending) */, + 344 /* 1.3.6.1.5.5.7.7.22 (OBJ_id_cmc_popLinkRandom) */, + 345 /* 1.3.6.1.5.5.7.7.23 (OBJ_id_cmc_popLinkWitness) */, + 346 /* 1.3.6.1.5.5.7.7.24 (OBJ_id_cmc_confirmCertAcceptance) */, + 347 /* 1.3.6.1.5.5.7.8.1 (OBJ_id_on_personalData) */, + 858 /* 1.3.6.1.5.5.7.8.3 (OBJ_id_on_permanentIdentifier) */, + 348 /* 1.3.6.1.5.5.7.9.1 (OBJ_id_pda_dateOfBirth) */, + 349 /* 1.3.6.1.5.5.7.9.2 (OBJ_id_pda_placeOfBirth) */, + 351 /* 1.3.6.1.5.5.7.9.3 (OBJ_id_pda_gender) */, + 352 /* 1.3.6.1.5.5.7.9.4 (OBJ_id_pda_countryOfCitizenship) */, + 353 /* 1.3.6.1.5.5.7.9.5 (OBJ_id_pda_countryOfResidence) */, + 354 /* 1.3.6.1.5.5.7.10.1 (OBJ_id_aca_authenticationInfo) */, + 355 /* 1.3.6.1.5.5.7.10.2 (OBJ_id_aca_accessIdentity) */, + 356 /* 1.3.6.1.5.5.7.10.3 (OBJ_id_aca_chargingIdentity) */, + 357 /* 1.3.6.1.5.5.7.10.4 (OBJ_id_aca_group) */, + 358 /* 1.3.6.1.5.5.7.10.5 (OBJ_id_aca_role) */, + 399 /* 1.3.6.1.5.5.7.10.6 (OBJ_id_aca_encAttrs) */, + 359 /* 1.3.6.1.5.5.7.11.1 (OBJ_id_qcs_pkixQCSyntax_v1) */, + 360 /* 1.3.6.1.5.5.7.12.1 (OBJ_id_cct_crs) */, + 361 /* 1.3.6.1.5.5.7.12.2 (OBJ_id_cct_PKIData) */, + 362 /* 1.3.6.1.5.5.7.12.3 (OBJ_id_cct_PKIResponse) */, + 664 /* 1.3.6.1.5.5.7.21.0 (OBJ_id_ppl_anyLanguage) */, + 665 /* 1.3.6.1.5.5.7.21.1 (OBJ_id_ppl_inheritAll) */, + 667 /* 1.3.6.1.5.5.7.21.2 (OBJ_Independent) */, + 178 /* 1.3.6.1.5.5.7.48.1 (OBJ_ad_OCSP) */, + 179 /* 1.3.6.1.5.5.7.48.2 (OBJ_ad_ca_issuers) */, + 363 /* 1.3.6.1.5.5.7.48.3 (OBJ_ad_timeStamping) */, + 364 /* 1.3.6.1.5.5.7.48.4 (OBJ_ad_dvcs) */, + 785 /* 1.3.6.1.5.5.7.48.5 (OBJ_caRepository) */, + 780 /* 1.3.6.1.5.5.8.1.1 (OBJ_hmac_md5) */, + 781 /* 1.3.6.1.5.5.8.1.2 (OBJ_hmac_sha1) */, + 58 /* 2.16.840.1.113730.1 (OBJ_netscape_cert_extension) */, + 59 /* 2.16.840.1.113730.2 (OBJ_netscape_data_type) */, + 438 /* 0.9.2342.19200300.100.1 (OBJ_pilotAttributeType) */, + 439 /* 0.9.2342.19200300.100.3 (OBJ_pilotAttributeSyntax) */, + 440 /* 0.9.2342.19200300.100.4 (OBJ_pilotObjectClass) */, + 441 /* 0.9.2342.19200300.100.10 (OBJ_pilotGroups) */, + 108 /* 1.2.840.113533.7.66.10 (OBJ_cast5_cbc) */, + 112 /* 1.2.840.113533.7.66.12 (OBJ_pbeWithMD5AndCast5_CBC) */, + 782 /* 1.2.840.113533.7.66.13 (OBJ_id_PasswordBasedMAC) */, + 783 /* 1.2.840.113533.7.66.30 (OBJ_id_DHBasedMac) */, + 6 /* 1.2.840.113549.1.1.1 (OBJ_rsaEncryption) */, + 7 /* 1.2.840.113549.1.1.2 (OBJ_md2WithRSAEncryption) */, + 396 /* 1.2.840.113549.1.1.3 (OBJ_md4WithRSAEncryption) */, + 8 /* 1.2.840.113549.1.1.4 (OBJ_md5WithRSAEncryption) */, + 65 /* 1.2.840.113549.1.1.5 (OBJ_sha1WithRSAEncryption) */, + 644 /* 1.2.840.113549.1.1.6 (OBJ_rsaOAEPEncryptionSET) */, + 919 /* 1.2.840.113549.1.1.7 (OBJ_rsaesOaep) */, + 911 /* 1.2.840.113549.1.1.8 (OBJ_mgf1) */, + 935 /* 1.2.840.113549.1.1.9 (OBJ_pSpecified) */, + 912 /* 1.2.840.113549.1.1.10 (OBJ_rsassaPss) */, + 668 /* 1.2.840.113549.1.1.11 (OBJ_sha256WithRSAEncryption) */, + 669 /* 1.2.840.113549.1.1.12 (OBJ_sha384WithRSAEncryption) */, + 670 /* 1.2.840.113549.1.1.13 (OBJ_sha512WithRSAEncryption) */, + 671 /* 1.2.840.113549.1.1.14 (OBJ_sha224WithRSAEncryption) */, + 28 /* 1.2.840.113549.1.3.1 (OBJ_dhKeyAgreement) */, + 9 /* 1.2.840.113549.1.5.1 (OBJ_pbeWithMD2AndDES_CBC) */, + 10 /* 1.2.840.113549.1.5.3 (OBJ_pbeWithMD5AndDES_CBC) */, + 168 /* 1.2.840.113549.1.5.4 (OBJ_pbeWithMD2AndRC2_CBC) */, + 169 /* 1.2.840.113549.1.5.6 (OBJ_pbeWithMD5AndRC2_CBC) */, + 170 /* 1.2.840.113549.1.5.10 (OBJ_pbeWithSHA1AndDES_CBC) */, + 68 /* 1.2.840.113549.1.5.11 (OBJ_pbeWithSHA1AndRC2_CBC) */, + 69 /* 1.2.840.113549.1.5.12 (OBJ_id_pbkdf2) */, + 161 /* 1.2.840.113549.1.5.13 (OBJ_pbes2) */, + 162 /* 1.2.840.113549.1.5.14 (OBJ_pbmac1) */, + 21 /* 1.2.840.113549.1.7.1 (OBJ_pkcs7_data) */, + 22 /* 1.2.840.113549.1.7.2 (OBJ_pkcs7_signed) */, + 23 /* 1.2.840.113549.1.7.3 (OBJ_pkcs7_enveloped) */, + 24 /* 1.2.840.113549.1.7.4 (OBJ_pkcs7_signedAndEnveloped) */, + 25 /* 1.2.840.113549.1.7.5 (OBJ_pkcs7_digest) */, + 26 /* 1.2.840.113549.1.7.6 (OBJ_pkcs7_encrypted) */, + 48 /* 1.2.840.113549.1.9.1 (OBJ_pkcs9_emailAddress) */, + 49 /* 1.2.840.113549.1.9.2 (OBJ_pkcs9_unstructuredName) */, + 50 /* 1.2.840.113549.1.9.3 (OBJ_pkcs9_contentType) */, + 51 /* 1.2.840.113549.1.9.4 (OBJ_pkcs9_messageDigest) */, + 52 /* 1.2.840.113549.1.9.5 (OBJ_pkcs9_signingTime) */, + 53 /* 1.2.840.113549.1.9.6 (OBJ_pkcs9_countersignature) */, + 54 /* 1.2.840.113549.1.9.7 (OBJ_pkcs9_challengePassword) */, + 55 /* 1.2.840.113549.1.9.8 (OBJ_pkcs9_unstructuredAddress) */, + 56 /* 1.2.840.113549.1.9.9 (OBJ_pkcs9_extCertAttributes) */, + 172 /* 1.2.840.113549.1.9.14 (OBJ_ext_req) */, + 167 /* 1.2.840.113549.1.9.15 (OBJ_SMIMECapabilities) */, + 188 /* 1.2.840.113549.1.9.16 (OBJ_SMIME) */, + 156 /* 1.2.840.113549.1.9.20 (OBJ_friendlyName) */, + 157 /* 1.2.840.113549.1.9.21 (OBJ_localKeyID) */, + 681 /* 1.2.840.10045.1.2.3.1 (OBJ_X9_62_onBasis) */, + 682 /* 1.2.840.10045.1.2.3.2 (OBJ_X9_62_tpBasis) */, + 683 /* 1.2.840.10045.1.2.3.3 (OBJ_X9_62_ppBasis) */, + 417 /* 1.3.6.1.4.1.311.17.1 (OBJ_ms_csp_name) */, + 856 /* 1.3.6.1.4.1.311.17.2 (OBJ_LocalKeySet) */, + 390 /* 1.3.6.1.4.1.1466.344 (OBJ_dcObject) */, + 91 /* 1.3.6.1.4.1.3029.1.2 (OBJ_bf_cbc) */, + 315 /* 1.3.6.1.5.5.7.5.1.1 (OBJ_id_regCtrl_regToken) */, + 316 /* 1.3.6.1.5.5.7.5.1.2 (OBJ_id_regCtrl_authenticator) */, + 317 /* 1.3.6.1.5.5.7.5.1.3 (OBJ_id_regCtrl_pkiPublicationInfo) */, + 318 /* 1.3.6.1.5.5.7.5.1.4 (OBJ_id_regCtrl_pkiArchiveOptions) */, + 319 /* 1.3.6.1.5.5.7.5.1.5 (OBJ_id_regCtrl_oldCertID) */, + 320 /* 1.3.6.1.5.5.7.5.1.6 (OBJ_id_regCtrl_protocolEncrKey) */, + 321 /* 1.3.6.1.5.5.7.5.2.1 (OBJ_id_regInfo_utf8Pairs) */, + 322 /* 1.3.6.1.5.5.7.5.2.2 (OBJ_id_regInfo_certReq) */, + 365 /* 1.3.6.1.5.5.7.48.1.1 (OBJ_id_pkix_OCSP_basic) */, + 366 /* 1.3.6.1.5.5.7.48.1.2 (OBJ_id_pkix_OCSP_Nonce) */, + 367 /* 1.3.6.1.5.5.7.48.1.3 (OBJ_id_pkix_OCSP_CrlID) */, + 368 /* 1.3.6.1.5.5.7.48.1.4 (OBJ_id_pkix_OCSP_acceptableResponses) */, + 369 /* 1.3.6.1.5.5.7.48.1.5 (OBJ_id_pkix_OCSP_noCheck) */, + 370 /* 1.3.6.1.5.5.7.48.1.6 (OBJ_id_pkix_OCSP_archiveCutoff) */, + 371 /* 1.3.6.1.5.5.7.48.1.7 (OBJ_id_pkix_OCSP_serviceLocator) */, + 372 /* 1.3.6.1.5.5.7.48.1.8 (OBJ_id_pkix_OCSP_extendedStatus) */, + 373 /* 1.3.6.1.5.5.7.48.1.9 (OBJ_id_pkix_OCSP_valid) */, + 374 /* 1.3.6.1.5.5.7.48.1.10 (OBJ_id_pkix_OCSP_path) */, + 375 /* 1.3.6.1.5.5.7.48.1.11 (OBJ_id_pkix_OCSP_trustRoot) */, + 921 /* 1.3.36.3.3.2.8.1.1.1 (OBJ_brainpoolP160r1) */, + 922 /* 1.3.36.3.3.2.8.1.1.2 (OBJ_brainpoolP160t1) */, + 923 /* 1.3.36.3.3.2.8.1.1.3 (OBJ_brainpoolP192r1) */, + 924 /* 1.3.36.3.3.2.8.1.1.4 (OBJ_brainpoolP192t1) */, + 925 /* 1.3.36.3.3.2.8.1.1.5 (OBJ_brainpoolP224r1) */, + 926 /* 1.3.36.3.3.2.8.1.1.6 (OBJ_brainpoolP224t1) */, + 927 /* 1.3.36.3.3.2.8.1.1.7 (OBJ_brainpoolP256r1) */, + 928 /* 1.3.36.3.3.2.8.1.1.8 (OBJ_brainpoolP256t1) */, + 929 /* 1.3.36.3.3.2.8.1.1.9 (OBJ_brainpoolP320r1) */, + 930 /* 1.3.36.3.3.2.8.1.1.10 (OBJ_brainpoolP320t1) */, + 931 /* 1.3.36.3.3.2.8.1.1.11 (OBJ_brainpoolP384r1) */, + 932 /* 1.3.36.3.3.2.8.1.1.12 (OBJ_brainpoolP384t1) */, + 933 /* 1.3.36.3.3.2.8.1.1.13 (OBJ_brainpoolP512r1) */, + 934 /* 1.3.36.3.3.2.8.1.1.14 (OBJ_brainpoolP512t1) */, + 936 /* 1.3.133.16.840.63.0.2 (OBJ_dhSinglePass_stdDH_sha1kdf_scheme) */, + 941 /* 1.3.133.16.840.63.0.3 (OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme) */ + , + 418 /* 2.16.840.1.101.3.4.1.1 (OBJ_aes_128_ecb) */, + 419 /* 2.16.840.1.101.3.4.1.2 (OBJ_aes_128_cbc) */, + 420 /* 2.16.840.1.101.3.4.1.3 (OBJ_aes_128_ofb128) */, + 421 /* 2.16.840.1.101.3.4.1.4 (OBJ_aes_128_cfb128) */, + 788 /* 2.16.840.1.101.3.4.1.5 (OBJ_id_aes128_wrap) */, + 895 /* 2.16.840.1.101.3.4.1.6 (OBJ_aes_128_gcm) */, + 896 /* 2.16.840.1.101.3.4.1.7 (OBJ_aes_128_ccm) */, + 897 /* 2.16.840.1.101.3.4.1.8 (OBJ_id_aes128_wrap_pad) */, + 422 /* 2.16.840.1.101.3.4.1.21 (OBJ_aes_192_ecb) */, + 423 /* 2.16.840.1.101.3.4.1.22 (OBJ_aes_192_cbc) */, + 424 /* 2.16.840.1.101.3.4.1.23 (OBJ_aes_192_ofb128) */, + 425 /* 2.16.840.1.101.3.4.1.24 (OBJ_aes_192_cfb128) */, + 789 /* 2.16.840.1.101.3.4.1.25 (OBJ_id_aes192_wrap) */, + 898 /* 2.16.840.1.101.3.4.1.26 (OBJ_aes_192_gcm) */, + 899 /* 2.16.840.1.101.3.4.1.27 (OBJ_aes_192_ccm) */, + 900 /* 2.16.840.1.101.3.4.1.28 (OBJ_id_aes192_wrap_pad) */, + 426 /* 2.16.840.1.101.3.4.1.41 (OBJ_aes_256_ecb) */, + 427 /* 2.16.840.1.101.3.4.1.42 (OBJ_aes_256_cbc) */, + 428 /* 2.16.840.1.101.3.4.1.43 (OBJ_aes_256_ofb128) */, + 429 /* 2.16.840.1.101.3.4.1.44 (OBJ_aes_256_cfb128) */, + 790 /* 2.16.840.1.101.3.4.1.45 (OBJ_id_aes256_wrap) */, + 901 /* 2.16.840.1.101.3.4.1.46 (OBJ_aes_256_gcm) */, + 902 /* 2.16.840.1.101.3.4.1.47 (OBJ_aes_256_ccm) */, + 903 /* 2.16.840.1.101.3.4.1.48 (OBJ_id_aes256_wrap_pad) */, + 672 /* 2.16.840.1.101.3.4.2.1 (OBJ_sha256) */, + 673 /* 2.16.840.1.101.3.4.2.2 (OBJ_sha384) */, + 674 /* 2.16.840.1.101.3.4.2.3 (OBJ_sha512) */, + 675 /* 2.16.840.1.101.3.4.2.4 (OBJ_sha224) */, + 962 /* 2.16.840.1.101.3.4.2.6 (OBJ_sha512_256) */, + 802 /* 2.16.840.1.101.3.4.3.1 (OBJ_dsa_with_SHA224) */, + 803 /* 2.16.840.1.101.3.4.3.2 (OBJ_dsa_with_SHA256) */, + 71 /* 2.16.840.1.113730.1.1 (OBJ_netscape_cert_type) */, + 72 /* 2.16.840.1.113730.1.2 (OBJ_netscape_base_url) */, + 73 /* 2.16.840.1.113730.1.3 (OBJ_netscape_revocation_url) */, + 74 /* 2.16.840.1.113730.1.4 (OBJ_netscape_ca_revocation_url) */, + 75 /* 2.16.840.1.113730.1.7 (OBJ_netscape_renewal_url) */, + 76 /* 2.16.840.1.113730.1.8 (OBJ_netscape_ca_policy_url) */, + 77 /* 2.16.840.1.113730.1.12 (OBJ_netscape_ssl_server_name) */, + 78 /* 2.16.840.1.113730.1.13 (OBJ_netscape_comment) */, + 79 /* 2.16.840.1.113730.2.5 (OBJ_netscape_cert_sequence) */, + 139 /* 2.16.840.1.113730.4.1 (OBJ_ns_sgc) */, + 458 /* 0.9.2342.19200300.100.1.1 (OBJ_userId) */, + 459 /* 0.9.2342.19200300.100.1.2 (OBJ_textEncodedORAddress) */, + 460 /* 0.9.2342.19200300.100.1.3 (OBJ_rfc822Mailbox) */, + 461 /* 0.9.2342.19200300.100.1.4 (OBJ_info) */, + 462 /* 0.9.2342.19200300.100.1.5 (OBJ_favouriteDrink) */, + 463 /* 0.9.2342.19200300.100.1.6 (OBJ_roomNumber) */, + 464 /* 0.9.2342.19200300.100.1.7 (OBJ_photo) */, + 465 /* 0.9.2342.19200300.100.1.8 (OBJ_userClass) */, + 466 /* 0.9.2342.19200300.100.1.9 (OBJ_host) */, + 467 /* 0.9.2342.19200300.100.1.10 (OBJ_manager) */, + 468 /* 0.9.2342.19200300.100.1.11 (OBJ_documentIdentifier) */, + 469 /* 0.9.2342.19200300.100.1.12 (OBJ_documentTitle) */, + 470 /* 0.9.2342.19200300.100.1.13 (OBJ_documentVersion) */, + 471 /* 0.9.2342.19200300.100.1.14 (OBJ_documentAuthor) */, + 472 /* 0.9.2342.19200300.100.1.15 (OBJ_documentLocation) */, + 473 /* 0.9.2342.19200300.100.1.20 (OBJ_homeTelephoneNumber) */, + 474 /* 0.9.2342.19200300.100.1.21 (OBJ_secretary) */, + 475 /* 0.9.2342.19200300.100.1.22 (OBJ_otherMailbox) */, + 476 /* 0.9.2342.19200300.100.1.23 (OBJ_lastModifiedTime) */, + 477 /* 0.9.2342.19200300.100.1.24 (OBJ_lastModifiedBy) */, + 391 /* 0.9.2342.19200300.100.1.25 (OBJ_domainComponent) */, + 478 /* 0.9.2342.19200300.100.1.26 (OBJ_aRecord) */, + 479 /* 0.9.2342.19200300.100.1.27 (OBJ_pilotAttributeType27) */, + 480 /* 0.9.2342.19200300.100.1.28 (OBJ_mXRecord) */, + 481 /* 0.9.2342.19200300.100.1.29 (OBJ_nSRecord) */, + 482 /* 0.9.2342.19200300.100.1.30 (OBJ_sOARecord) */, + 483 /* 0.9.2342.19200300.100.1.31 (OBJ_cNAMERecord) */, + 484 /* 0.9.2342.19200300.100.1.37 (OBJ_associatedDomain) */, + 485 /* 0.9.2342.19200300.100.1.38 (OBJ_associatedName) */, + 486 /* 0.9.2342.19200300.100.1.39 (OBJ_homePostalAddress) */, + 487 /* 0.9.2342.19200300.100.1.40 (OBJ_personalTitle) */, + 488 /* 0.9.2342.19200300.100.1.41 (OBJ_mobileTelephoneNumber) */, + 489 /* 0.9.2342.19200300.100.1.42 (OBJ_pagerTelephoneNumber) */, + 490 /* 0.9.2342.19200300.100.1.43 (OBJ_friendlyCountryName) */, + 491 /* 0.9.2342.19200300.100.1.45 (OBJ_organizationalStatus) */, + 492 /* 0.9.2342.19200300.100.1.46 (OBJ_janetMailbox) */, + 493 /* 0.9.2342.19200300.100.1.47 (OBJ_mailPreferenceOption) */, + 494 /* 0.9.2342.19200300.100.1.48 (OBJ_buildingName) */, + 495 /* 0.9.2342.19200300.100.1.49 (OBJ_dSAQuality) */, + 496 /* 0.9.2342.19200300.100.1.50 (OBJ_singleLevelQuality) */, + 497 /* 0.9.2342.19200300.100.1.51 (OBJ_subtreeMinimumQuality) */, + 498 /* 0.9.2342.19200300.100.1.52 (OBJ_subtreeMaximumQuality) */, + 499 /* 0.9.2342.19200300.100.1.53 (OBJ_personalSignature) */, + 500 /* 0.9.2342.19200300.100.1.54 (OBJ_dITRedirect) */, + 501 /* 0.9.2342.19200300.100.1.55 (OBJ_audio) */, + 502 /* 0.9.2342.19200300.100.1.56 (OBJ_documentPublisher) */, + 442 /* 0.9.2342.19200300.100.3.4 (OBJ_iA5StringSyntax) */, + 443 /* 0.9.2342.19200300.100.3.5 (OBJ_caseIgnoreIA5StringSyntax) */, + 444 /* 0.9.2342.19200300.100.4.3 (OBJ_pilotObject) */, + 445 /* 0.9.2342.19200300.100.4.4 (OBJ_pilotPerson) */, + 446 /* 0.9.2342.19200300.100.4.5 (OBJ_account) */, + 447 /* 0.9.2342.19200300.100.4.6 (OBJ_document) */, + 448 /* 0.9.2342.19200300.100.4.7 (OBJ_room) */, + 449 /* 0.9.2342.19200300.100.4.9 (OBJ_documentSeries) */, + 392 /* 0.9.2342.19200300.100.4.13 (OBJ_Domain) */, + 450 /* 0.9.2342.19200300.100.4.14 (OBJ_rFC822localPart) */, + 451 /* 0.9.2342.19200300.100.4.15 (OBJ_dNSDomain) */, + 452 /* 0.9.2342.19200300.100.4.17 (OBJ_domainRelatedObject) */, + 453 /* 0.9.2342.19200300.100.4.18 (OBJ_friendlyCountry) */, + 454 /* 0.9.2342.19200300.100.4.19 (OBJ_simpleSecurityObject) */, + 455 /* 0.9.2342.19200300.100.4.20 (OBJ_pilotOrganization) */, + 456 /* 0.9.2342.19200300.100.4.21 (OBJ_pilotDSA) */, + 457 /* 0.9.2342.19200300.100.4.22 (OBJ_qualityLabelledData) */, + 189 /* 1.2.840.113549.1.9.16.0 (OBJ_id_smime_mod) */, + 190 /* 1.2.840.113549.1.9.16.1 (OBJ_id_smime_ct) */, + 191 /* 1.2.840.113549.1.9.16.2 (OBJ_id_smime_aa) */, + 192 /* 1.2.840.113549.1.9.16.3 (OBJ_id_smime_alg) */, + 193 /* 1.2.840.113549.1.9.16.4 (OBJ_id_smime_cd) */, + 194 /* 1.2.840.113549.1.9.16.5 (OBJ_id_smime_spq) */, + 195 /* 1.2.840.113549.1.9.16.6 (OBJ_id_smime_cti) */, + 158 /* 1.2.840.113549.1.9.22.1 (OBJ_x509Certificate) */, + 159 /* 1.2.840.113549.1.9.22.2 (OBJ_sdsiCertificate) */, + 160 /* 1.2.840.113549.1.9.23.1 (OBJ_x509Crl) */, + 144 /* 1.2.840.113549.1.12.1.1 (OBJ_pbe_WithSHA1And128BitRC4) */, + 145 /* 1.2.840.113549.1.12.1.2 (OBJ_pbe_WithSHA1And40BitRC4) */, + 146 /* 1.2.840.113549.1.12.1.3 (OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC) */, + 147 /* 1.2.840.113549.1.12.1.4 (OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC) */, + 148 /* 1.2.840.113549.1.12.1.5 (OBJ_pbe_WithSHA1And128BitRC2_CBC) */, + 149 /* 1.2.840.113549.1.12.1.6 (OBJ_pbe_WithSHA1And40BitRC2_CBC) */, + 171 /* 1.3.6.1.4.1.311.2.1.14 (OBJ_ms_ext_req) */, + 134 /* 1.3.6.1.4.1.311.2.1.21 (OBJ_ms_code_ind) */, + 135 /* 1.3.6.1.4.1.311.2.1.22 (OBJ_ms_code_com) */, + 136 /* 1.3.6.1.4.1.311.10.3.1 (OBJ_ms_ctl_sign) */, + 137 /* 1.3.6.1.4.1.311.10.3.3 (OBJ_ms_sgc) */, + 138 /* 1.3.6.1.4.1.311.10.3.4 (OBJ_ms_efs) */, + 648 /* 1.3.6.1.4.1.311.20.2.2 (OBJ_ms_smartcard_login) */, + 649 /* 1.3.6.1.4.1.311.20.2.3 (OBJ_ms_upn) */, + 751 /* 1.2.392.200011.61.1.1.1.2 (OBJ_camellia_128_cbc) */, + 752 /* 1.2.392.200011.61.1.1.1.3 (OBJ_camellia_192_cbc) */, + 753 /* 1.2.392.200011.61.1.1.1.4 (OBJ_camellia_256_cbc) */, + 907 /* 1.2.392.200011.61.1.1.3.2 (OBJ_id_camellia128_wrap) */, + 908 /* 1.2.392.200011.61.1.1.3.3 (OBJ_id_camellia192_wrap) */, + 909 /* 1.2.392.200011.61.1.1.3.4 (OBJ_id_camellia256_wrap) */, + 196 /* 1.2.840.113549.1.9.16.0.1 (OBJ_id_smime_mod_cms) */, + 197 /* 1.2.840.113549.1.9.16.0.2 (OBJ_id_smime_mod_ess) */, + 198 /* 1.2.840.113549.1.9.16.0.3 (OBJ_id_smime_mod_oid) */, + 199 /* 1.2.840.113549.1.9.16.0.4 (OBJ_id_smime_mod_msg_v3) */, + 200 /* 1.2.840.113549.1.9.16.0.5 (OBJ_id_smime_mod_ets_eSignature_88) */, + 201 /* 1.2.840.113549.1.9.16.0.6 (OBJ_id_smime_mod_ets_eSignature_97) */, + 202 /* 1.2.840.113549.1.9.16.0.7 (OBJ_id_smime_mod_ets_eSigPolicy_88) */, + 203 /* 1.2.840.113549.1.9.16.0.8 (OBJ_id_smime_mod_ets_eSigPolicy_97) */, + 204 /* 1.2.840.113549.1.9.16.1.1 (OBJ_id_smime_ct_receipt) */, + 205 /* 1.2.840.113549.1.9.16.1.2 (OBJ_id_smime_ct_authData) */, + 206 /* 1.2.840.113549.1.9.16.1.3 (OBJ_id_smime_ct_publishCert) */, + 207 /* 1.2.840.113549.1.9.16.1.4 (OBJ_id_smime_ct_TSTInfo) */, + 208 /* 1.2.840.113549.1.9.16.1.5 (OBJ_id_smime_ct_TDTInfo) */, + 209 /* 1.2.840.113549.1.9.16.1.6 (OBJ_id_smime_ct_contentInfo) */, + 210 /* 1.2.840.113549.1.9.16.1.7 (OBJ_id_smime_ct_DVCSRequestData) */, + 211 /* 1.2.840.113549.1.9.16.1.8 (OBJ_id_smime_ct_DVCSResponseData) */, + 786 /* 1.2.840.113549.1.9.16.1.9 (OBJ_id_smime_ct_compressedData) */, + 787 /* 1.2.840.113549.1.9.16.1.27 (OBJ_id_ct_asciiTextWithCRLF) */, + 212 /* 1.2.840.113549.1.9.16.2.1 (OBJ_id_smime_aa_receiptRequest) */, + 213 /* 1.2.840.113549.1.9.16.2.2 (OBJ_id_smime_aa_securityLabel) */, + 214 /* 1.2.840.113549.1.9.16.2.3 (OBJ_id_smime_aa_mlExpandHistory) */, + 215 /* 1.2.840.113549.1.9.16.2.4 (OBJ_id_smime_aa_contentHint) */, + 216 /* 1.2.840.113549.1.9.16.2.5 (OBJ_id_smime_aa_msgSigDigest) */, + 217 /* 1.2.840.113549.1.9.16.2.6 (OBJ_id_smime_aa_encapContentType) */, + 218 /* 1.2.840.113549.1.9.16.2.7 (OBJ_id_smime_aa_contentIdentifier) */, + 219 /* 1.2.840.113549.1.9.16.2.8 (OBJ_id_smime_aa_macValue) */, + 220 /* 1.2.840.113549.1.9.16.2.9 (OBJ_id_smime_aa_equivalentLabels) */, + 221 /* 1.2.840.113549.1.9.16.2.10 (OBJ_id_smime_aa_contentReference) */, + 222 /* 1.2.840.113549.1.9.16.2.11 (OBJ_id_smime_aa_encrypKeyPref) */, + 223 /* 1.2.840.113549.1.9.16.2.12 (OBJ_id_smime_aa_signingCertificate) */, + 224 /* 1.2.840.113549.1.9.16.2.13 (OBJ_id_smime_aa_smimeEncryptCerts) */, + 225 /* 1.2.840.113549.1.9.16.2.14 (OBJ_id_smime_aa_timeStampToken) */, + 226 /* 1.2.840.113549.1.9.16.2.15 (OBJ_id_smime_aa_ets_sigPolicyId) */, + 227 /* 1.2.840.113549.1.9.16.2.16 (OBJ_id_smime_aa_ets_commitmentType) */, + 228 /* 1.2.840.113549.1.9.16.2.17 (OBJ_id_smime_aa_ets_signerLocation) */, + 229 /* 1.2.840.113549.1.9.16.2.18 (OBJ_id_smime_aa_ets_signerAttr) */, + 230 /* 1.2.840.113549.1.9.16.2.19 (OBJ_id_smime_aa_ets_otherSigCert) */, + 231 /* 1.2.840.113549.1.9.16.2.20 (OBJ_id_smime_aa_ets_contentTimestamp) */, + 232 /* 1.2.840.113549.1.9.16.2.21 (OBJ_id_smime_aa_ets_CertificateRefs) */, + 233 /* 1.2.840.113549.1.9.16.2.22 (OBJ_id_smime_aa_ets_RevocationRefs) */, + 234 /* 1.2.840.113549.1.9.16.2.23 (OBJ_id_smime_aa_ets_certValues) */, + 235 /* 1.2.840.113549.1.9.16.2.24 (OBJ_id_smime_aa_ets_revocationValues) */, + 236 /* 1.2.840.113549.1.9.16.2.25 (OBJ_id_smime_aa_ets_escTimeStamp) */, + 237 /* 1.2.840.113549.1.9.16.2.26 (OBJ_id_smime_aa_ets_certCRLTimestamp) */, + 238 /* 1.2.840.113549.1.9.16.2.27 (OBJ_id_smime_aa_ets_archiveTimeStamp) */, + 239 /* 1.2.840.113549.1.9.16.2.28 (OBJ_id_smime_aa_signatureType) */, + 240 /* 1.2.840.113549.1.9.16.2.29 (OBJ_id_smime_aa_dvcs_dvc) */, + 241 /* 1.2.840.113549.1.9.16.3.1 (OBJ_id_smime_alg_ESDHwith3DES) */, + 242 /* 1.2.840.113549.1.9.16.3.2 (OBJ_id_smime_alg_ESDHwithRC2) */, + 243 /* 1.2.840.113549.1.9.16.3.3 (OBJ_id_smime_alg_3DESwrap) */, + 244 /* 1.2.840.113549.1.9.16.3.4 (OBJ_id_smime_alg_RC2wrap) */, + 245 /* 1.2.840.113549.1.9.16.3.5 (OBJ_id_smime_alg_ESDH) */, + 246 /* 1.2.840.113549.1.9.16.3.6 (OBJ_id_smime_alg_CMS3DESwrap) */, + 247 /* 1.2.840.113549.1.9.16.3.7 (OBJ_id_smime_alg_CMSRC2wrap) */, + 125 /* 1.2.840.113549.1.9.16.3.8 (OBJ_zlib_compression) */, + 893 /* 1.2.840.113549.1.9.16.3.9 (OBJ_id_alg_PWRI_KEK) */, + 248 /* 1.2.840.113549.1.9.16.4.1 (OBJ_id_smime_cd_ldap) */, + 249 /* 1.2.840.113549.1.9.16.5.1 (OBJ_id_smime_spq_ets_sqt_uri) */, + 250 /* 1.2.840.113549.1.9.16.5.2 (OBJ_id_smime_spq_ets_sqt_unotice) */, + 251 /* 1.2.840.113549.1.9.16.6.1 (OBJ_id_smime_cti_ets_proofOfOrigin) */, + 252 /* 1.2.840.113549.1.9.16.6.2 (OBJ_id_smime_cti_ets_proofOfReceipt) */, + 253 /* 1.2.840.113549.1.9.16.6.3 (OBJ_id_smime_cti_ets_proofOfDelivery) */, + 254 /* 1.2.840.113549.1.9.16.6.4 (OBJ_id_smime_cti_ets_proofOfSender) */, + 255 /* 1.2.840.113549.1.9.16.6.5 (OBJ_id_smime_cti_ets_proofOfApproval) */, + 256 /* 1.2.840.113549.1.9.16.6.6 (OBJ_id_smime_cti_ets_proofOfCreation) */, + 150 /* 1.2.840.113549.1.12.10.1.1 (OBJ_keyBag) */, + 151 /* 1.2.840.113549.1.12.10.1.2 (OBJ_pkcs8ShroudedKeyBag) */, + 152 /* 1.2.840.113549.1.12.10.1.3 (OBJ_certBag) */, + 153 /* 1.2.840.113549.1.12.10.1.4 (OBJ_crlBag) */, + 154 /* 1.2.840.113549.1.12.10.1.5 (OBJ_secretBag) */, + 155 /* 1.2.840.113549.1.12.10.1.6 (OBJ_safeContentsBag) */, + 34 /* 1.3.6.1.4.1.188.7.1.1.2 (OBJ_idea_cbc) */, +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_xref.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_xref.c new file mode 100644 index 00000000..c951c647 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/obj/obj_xref.c @@ -0,0 +1,122 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include "../internal.h" + + +typedef struct { + int sign_nid; + int digest_nid; + int pkey_nid; +} nid_triple; + +static const nid_triple kTriples[] = { + // RSA PKCS#1. + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + // DSA. + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + // ECDSA. + {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, + // The following algorithms use more complex (or simpler) parameters. The + // digest "undef" indicates the caller should handle this explicitly. + {NID_rsassaPss, NID_undef, NID_rsaEncryption}, + {NID_ED25519, NID_undef, NID_ED25519}, +}; + +int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].sign_nid == sign_nid) { + if (out_digest_nid != NULL) { + *out_digest_nid = kTriples[i].digest_nid; + } + if (out_pkey_nid != NULL) { + *out_pkey_nid = kTriples[i].pkey_nid; + } + return 1; + } + } + + return 0; +} + +int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].digest_nid == digest_nid && + kTriples[i].pkey_nid == pkey_nid) { + if (out_sign_nid != NULL) { + *out_sign_nid = kTriples[i].sign_nid; + } + return 1; + } + } + + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_all.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_all.c new file mode 100644 index 00000000..5f7708ee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_all.c @@ -0,0 +1,252 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); + +IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) + +IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) +IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) + +/* + * We treat RSA or DSA private keys as a special case. For private keys we + * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract + * the relevant private key: this means can handle "traditional" and PKCS#8 + * formats transparently. + */ +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) +{ + RSA *rtmp; + if (!key) + return NULL; + rtmp = EVP_PKEY_get1_RSA(key); + EVP_PKEY_free(key); + if (!rtmp) + return NULL; + if (rsa) { + RSA_free(*rsa); + *rsa = rtmp; + } + return rtmp; +} + +RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, + RSAPrivateKey) + + +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, + RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, + PEM_STRING_PUBLIC, + RSA_PUBKEY) +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) +{ + DSA *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_DSA(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (dsa) { + DSA_free(*dsa); + *dsa = dtmp; + } + return dtmp; +} + +DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, + DSAPrivateKey) + +IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) +DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) +#endif +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) +{ + EC_KEY *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_EC_KEY(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (eckey) { + EC_KEY_free(*eckey); + *eckey = dtmp; + } + return dtmp; +} + +EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_eckey(pktmp, key); /* will free pktmp */ +} + +IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, + ECPrivateKey) + +IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) +EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ +} + + +IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) + +IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_info.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_info.c new file mode 100644 index 00000000..e2e847f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_info.c @@ -0,0 +1,358 @@ +/* crypto/pem/pem_info.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + STACK_OF(X509_INFO) *ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + BIO_free(b); + return ret; +} + +enum parse_result_t { + parse_ok, + parse_error, + parse_new_entry, +}; + +static enum parse_result_t parse_x509(X509_INFO *info, const uint8_t *data, + size_t len, int key_type) +{ + if (info->x509 != NULL) { + return parse_new_entry; + } + info->x509 = d2i_X509(NULL, &data, len); + return info->x509 != NULL ? parse_ok : parse_error; +} + +static enum parse_result_t parse_x509_aux(X509_INFO *info, const uint8_t *data, + size_t len, int key_type) +{ + if (info->x509 != NULL) { + return parse_new_entry; + } + info->x509 = d2i_X509_AUX(NULL, &data, len); + return info->x509 != NULL ? parse_ok : parse_error; +} + +static enum parse_result_t parse_crl(X509_INFO *info, const uint8_t *data, + size_t len, int key_type) +{ + if (info->crl != NULL) { + return parse_new_entry; + } + info->crl = d2i_X509_CRL(NULL, &data, len); + return info->crl != NULL ? parse_ok : parse_error; +} + +static enum parse_result_t parse_key(X509_INFO *info, const uint8_t *data, + size_t len, int key_type) +{ + if (info->x_pkey != NULL) { + return parse_new_entry; + } + info->x_pkey = X509_PKEY_new(); + if (info->x_pkey == NULL) { + return parse_error; + } + info->x_pkey->dec_pkey = d2i_PrivateKey(key_type, NULL, &data, len); + return info->x_pkey->dec_pkey != NULL ? parse_ok : parse_error; +} + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + X509_INFO *info = NULL; + char *name = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ok = 0; + STACK_OF(X509_INFO) *ret = NULL; + + if (sk == NULL) { + ret = sk_X509_INFO_new_null(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + ret = sk; + } + size_t orig_num = sk_X509_INFO_num(ret); + + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + + for (;;) { + if (!PEM_read_bio(bp, &name, &header, &data, &len)) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + break; + } + goto err; + } + + enum parse_result_t (*parse_function)(X509_INFO *, const uint8_t *, + size_t, int) = NULL; + int key_type = EVP_PKEY_NONE; + if (strcmp(name, PEM_STRING_X509) == 0 || + strcmp(name, PEM_STRING_X509_OLD) == 0) { + parse_function = parse_x509; + } else if (strcmp(name, PEM_STRING_X509_TRUSTED) == 0) { + parse_function = parse_x509_aux; + } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { + parse_function = parse_crl; + } else if (strcmp(name, PEM_STRING_RSA) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_RSA; + } else if (strcmp(name, PEM_STRING_DSA) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_DSA; + } else if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_EC; + } + + /* If a private key has a header, assume it is encrypted. */ + if (key_type != EVP_PKEY_NONE && strlen(header) > 10) { + if (info->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, info)) { + goto err; + } + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + } + /* Historically, raw entries pushed an empty key. */ + info->x_pkey = X509_PKEY_new(); + if (info->x_pkey == NULL || + !PEM_get_EVP_CIPHER_INFO(header, &info->enc_cipher)) { + goto err; + } + info->enc_data = (char *)data; + info->enc_len = (int)len; + data = NULL; + } else if (parse_function != NULL) { + EVP_CIPHER_INFO cipher; + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher) || + !PEM_do_header(&cipher, data, &len, cb, u)) { + goto err; + } + enum parse_result_t result = + parse_function(info, data, len, key_type); + if (result == parse_new_entry) { + if (!sk_X509_INFO_push(ret, info)) { + goto err; + } + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + result = parse_function(info, data, len, key_type); + } + if (result != parse_ok) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + goto err; + } + } + OPENSSL_free(name); + OPENSSL_free(header); + OPENSSL_free(data); + name = NULL; + header = NULL; + data = NULL; + } + + /* Push the last entry on the stack if not empty. */ + if (info->x509 != NULL || info->crl != NULL || + info->x_pkey != NULL || info->enc_data != NULL) { + if (!sk_X509_INFO_push(ret, info)) { + goto err; + } + info = NULL; + } + + ok = 1; + + err: + X509_INFO_free(info); + if (!ok) { + while (sk_X509_INFO_num(ret) > orig_num) { + X509_INFO_free(sk_X509_INFO_pop(ret)); + } + if (ret != sk) { + sk_X509_INFO_free(ret); + } + ret = NULL; + } + + OPENSSL_free(name); + OPENSSL_free(header); + OPENSSL_free(data); + return ret; +} + +/* A TJH addition */ +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + unsigned iv_len = 0; + + if (enc != NULL) { + iv_len = EVP_CIPHER_iv_length(enc); + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + /* + * now for the fun part ... if we have a private key then we have to be + * able to handle a not-yet-decrypted key being written out correctly ... + * if it is decrypted or it is non-encrypted then we use the base code + */ + if (xi->x_pkey != NULL) { + if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { + if (enc == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL); + goto err; + } + + /* copy from weirdo names into more normal things */ + iv = xi->enc_cipher.iv; + data = (unsigned char *)xi->enc_data; + i = xi->enc_len; + + /* + * we take the encryption data from the internal stuff rather + * than what the user has passed us ... as we have to match + * exactly for some strange reason + */ + objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); + if (objstr == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, iv_len, (char *)iv); + + /* use the normal code to write things out */ + i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); + if (i <= 0) + goto err; + } else { + /* Add DSA/DH */ + /* normal optionally encrypted stuff */ + if (PEM_write_bio_RSAPrivateKey(bp, + xi->x_pkey->dec_pkey->pkey.rsa, + enc, kstr, klen, cb, u) <= 0) + goto err; + } + } + + /* if we have a certificate then write it out now */ + if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) + goto err; + + /* + * we are ignoring anything else that is loaded into the X509_INFO + * structure for the moment ... as I don't need it so I'm not coding it + * here and Eric can do it when this makes it into the base library --tjh + */ + + ret = 1; + +err: + OPENSSL_cleanse(buf, PEM_BUFSIZE); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c new file mode 100644 index 00000000..63452d37 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_lib.c @@ -0,0 +1,769 @@ +/* crypto/pem/pem_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + + +#define MIN_LENGTH 4 + +static int load_iv(char **fromp, unsigned char *to, int num); +static int check_pem(const char *nm, const char *name); + +void PEM_proc_type(char *buf, int type) +{ + const char *str; + + if (type == PEM_TYPE_ENCRYPTED) + str = "ENCRYPTED"; + else if (type == PEM_TYPE_MIC_CLEAR) + str = "MIC-CLEAR"; + else if (type == PEM_TYPE_MIC_ONLY) + str = "MIC-ONLY"; + else + str = "BAD-TYPE"; + + OPENSSL_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); + OPENSSL_strlcat(buf, str, PEM_BUFSIZE); + OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE); +} + +void PEM_dek_info(char *buf, const char *type, int len, char *str) +{ + static const unsigned char map[17] = "0123456789ABCDEF"; + long i; + int j; + + OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); + OPENSSL_strlcat(buf, type, PEM_BUFSIZE); + OPENSSL_strlcat(buf, ",", PEM_BUFSIZE); + j = strlen(buf); + if (j + (len * 2) + 1 > PEM_BUFSIZE) + return; + for (i = 0; i < len; i++) { + buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; + } + buf[j + i * 2] = '\n'; + buf[j + i * 2 + 1] = '\0'; +} + +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + void *ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); + BIO_free(b); + return ret; +} + +static int check_pem(const char *nm, const char *name) +{ + /* Normal matching nm and name */ + if (!strcmp(nm, name)) + return 1; + + /* Make PEM_STRING_EVP_PKEY match any private key */ + + if (!strcmp(name, PEM_STRING_EVP_PKEY)) { + return !strcmp(nm, PEM_STRING_PKCS8) || + !strcmp(nm, PEM_STRING_PKCS8INF) || + !strcmp(nm, PEM_STRING_RSA) || + !strcmp(nm, PEM_STRING_EC) || + !strcmp(nm, PEM_STRING_DSA); + } + + /* Permit older strings */ + + if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && + !strcmp(name, PEM_STRING_X509_REQ)) + return 1; + + /* Allow normal certs to be read as trusted certs */ + if (!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + /* Some CAs use PKCS#7 with CERTIFICATE headers */ + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) + return 1; + + if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && + !strcmp(name, PEM_STRING_PKCS7)) + return 1; + +#ifndef OPENSSL_NO_CMS + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) + return 1; + /* Allow CMS to be read from PKCS#7 headers */ + if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) + return 1; +#endif + + return 0; +} + +static const EVP_CIPHER *cipher_by_name(const char *name) +{ + /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. Note + * the PEM code assumes that ciphers have at least 8 bytes of IV, at most 20 + * bytes of overhead and generally behave like CBC mode. */ + if (0 == strcmp(name, SN_des_cbc)) { + return EVP_des_cbc(); + } else if (0 == strcmp(name, SN_des_ede3_cbc)) { + return EVP_des_ede3_cbc(); + } else if (0 == strcmp(name, SN_aes_128_cbc)) { + return EVP_aes_128_cbc(); + } else if (0 == strcmp(name, SN_aes_192_cbc)) { + return EVP_aes_192_cbc(); + } else if (0 == strcmp(name, SN_aes_256_cbc)) { + return EVP_aes_256_cbc(); + } else { + return NULL; + } +} + +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u) +{ + EVP_CIPHER_INFO cipher; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ret = 0; + + for (;;) { + if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { + uint32_t error = ERR_peek_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + ERR_add_error_data(2, "Expecting: ", name); + } + return 0; + } + if (check_pem(nm, name)) + break; + OPENSSL_free(nm); + OPENSSL_free(header); + OPENSSL_free(data); + } + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + + *pdata = data; + *plen = len; + + if (pnm) + *pnm = nm; + + ret = 1; + + err: + if (!ret || !pnm) + OPENSSL_free(nm); + OPENSSL_free(header); + if (!ret) + OPENSSL_free(data); + return ret; +} + +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); + BIO_free(b); + return ret; +} + +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + EVP_CIPHER_CTX ctx; + int dsize = 0, i, j, ret = 0; + unsigned char *p, *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL || + cipher_by_name(objstr) == NULL || + EVP_CIPHER_iv_length(enc) < 8) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + dsize = 0; + goto err; + } + /* dzise + 8 bytes are needed */ + /* actually it needs the cipher block size extra... */ + data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); + if (data == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + const unsigned iv_len = EVP_CIPHER_iv_length(enc); + + if (kstr == NULL) { + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = (*callback) (buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); + goto err; + } + kstr = (unsigned char *)buf; + } + assert(iv_len <= (int)sizeof(iv)); + if (!RAND_bytes(iv, iv_len)) /* Generate a salt */ + goto err; + /* + * The 'iv' is used as the iv and as a salt. It is NOT taken from + * the BytesToKey function + */ + if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) + goto err; + + if (kstr == (unsigned char *)buf) + OPENSSL_cleanse(buf, PEM_BUFSIZE); + + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, iv_len, (char *)iv); + /* k=strlen(buf); */ + + EVP_CIPHER_CTX_init(&ctx); + ret = 1; + if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) + || !EVP_EncryptUpdate(&ctx, data, &j, data, i) + || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) + ret = 0; + else + i += j; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + } else { + ret = 1; + buf[0] = '\0'; + } + i = PEM_write_bio(bp, name, buf, data, i); + if (i <= 0) + ret = 0; + err: + OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(iv, sizeof(iv)); + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + OPENSSL_free(data); + return (ret); +} + +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, + pem_password_cb *callback, void *u) +{ + int i = 0, j, o, klen; + long len; + EVP_CIPHER_CTX ctx; + unsigned char key[EVP_MAX_KEY_LENGTH]; + char buf[PEM_BUFSIZE]; + + len = *plen; + + if (cipher->cipher == NULL) + return (1); + + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + return (0); + } + + if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), + (unsigned char *)buf, klen, 1, key, NULL)) + return 0; + + j = (int)len; + EVP_CIPHER_CTX_init(&ctx); + o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); + if (o) + o = EVP_DecryptUpdate(&ctx, data, &i, data, j); + if (o) + o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_cleanse((char *)buf, sizeof(buf)); + OPENSSL_cleanse((char *)key, sizeof(key)); + if (!o) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); + return (0); + } + j += i; + *plen = j; + return (1); +} + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) +{ + const EVP_CIPHER *enc = NULL; + char *p, c; + char **header_pp = &header; + + cipher->cipher = NULL; + OPENSSL_memset(cipher->iv, 0, sizeof(cipher->iv)); + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); + return (0); + } + header += 11; + if (*header != '4') + return (0); + header++; + if (*header != ',') + return (0); + header++; + if (strncmp(header, "ENCRYPTED", 9) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) ; + if (*header == '\0') { + OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c = *header; + if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; + header++; + } + *header = '\0'; + cipher->cipher = enc = cipher_by_name(p); + *header = c; + header++; + + if (enc == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + // The IV parameter must be at least 8 bytes long to be used as the salt in + // the KDF. (This should not happen given |cipher_by_name|.) + if (EVP_CIPHER_iv_length(enc) < 8) { + assert(0); + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return 0; + } + if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) + return (0); + + return (1); +} + +static int load_iv(char **fromp, unsigned char *to, int num) +{ + int v, i; + char *from; + + from = *fromp; + for (i = 0; i < num; i++) + to[i] = 0; + num *= 2; + for (i = 0; i < num; i++) { + if ((*from >= '0') && (*from <= '9')) + v = *from - '0'; + else if ((*from >= 'A') && (*from <= 'F')) + v = *from - 'A' + 10; + else if ((*from >= 'a') && (*from <= 'f')) + v = *from - 'a' + 10; + else { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS); + return (0); + } + from++; + to[i / 2] |= v << (long)((!(i & 1)) * 4); + } + + *fromp = from; + return (1); +} + +int PEM_write(FILE *fp, const char *name, const char *header, + const unsigned char *data, long len) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_write_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} + +int PEM_write_bio(BIO *bp, const char *name, const char *header, + const unsigned char *data, long len) +{ + int nlen, n, i, j, outl; + unsigned char *buf = NULL; + EVP_ENCODE_CTX ctx; + int reason = ERR_R_BUF_LIB; + + EVP_EncodeInit(&ctx); + nlen = strlen(name); + + if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + + i = strlen(header); + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + goto err; + } + + buf = OPENSSL_malloc(PEM_BUFSIZE * 8); + if (buf == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + i = j = 0; + while (len > 0) { + n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); + EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + i += outl; + len -= n; + j += n; + } + EVP_EncodeFinal(&ctx, buf, &outl); + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + OPENSSL_free(buf); + buf = NULL; + if ((BIO_write(bp, "-----END ", 9) != 9) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + return (i + outl); + err: + if (buf) { + OPENSSL_free(buf); + } + OPENSSL_PUT_ERROR(PEM, reason); + return (0); +} + +int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, + long *len) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_read_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} + +int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, + long *len) +{ + EVP_ENCODE_CTX ctx; + int end = 0, i, k, bl = 0, hl = 0, nohead = 0; + char buf[256]; + BUF_MEM *nameB; + BUF_MEM *headerB; + BUF_MEM *dataB, *tmpB; + + nameB = BUF_MEM_new(); + headerB = BUF_MEM_new(); + dataB = BUF_MEM_new(); + if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE); + goto err; + } + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (strncmp(buf, "-----BEGIN ", 11) == 0) { + i = strlen(&(buf[11])); + + if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) + continue; + if (!BUF_MEM_grow(nameB, i + 9)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + headerB->data[0] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (buf[0] == '\n') + break; + if (!BUF_MEM_grow(headerB, hl + i + 9)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + OPENSSL_memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + dataB->data[0] = '\0'; + if (!nohead) { + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (i != 65) + end = 1; + if (strncmp(buf, "-----END ", 9) == 0) + break; + if (i > 65) + break; + if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(&(dataB->data[bl]), buf, i); + dataB->data[bl + i] = '\0'; + bl += i; + if (end) { + buf[0] = '\0'; + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + break; + } + } + } else { + tmpB = headerB; + headerB = dataB; + dataB = tmpB; + bl = hl; + } + i = strlen(nameB->data); + if ((strncmp(buf, "-----END ", 9) != 0) || + (strncmp(nameB->data, &(buf[9]), i) != 0) || + (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE); + goto err; + } + + EVP_DecodeInit(&ctx); + i = EVP_DecodeUpdate(&ctx, + (unsigned char *)dataB->data, &bl, + (unsigned char *)dataB->data, bl); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + bl += k; + + if (bl == 0) + goto err; + *name = nameB->data; + *header = headerB->data; + *data = (unsigned char *)dataB->data; + *len = bl; + OPENSSL_free(nameB); + OPENSSL_free(headerB); + OPENSSL_free(dataB); + return (1); + err: + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + return (0); +} + +int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) +{ + if (!buf || !userdata || size < 0) { + return 0; + } + size_t len = strlen((char *)userdata); + if (len >= (size_t)size) { + return 0; + } + OPENSSL_strlcpy(buf, userdata, (size_t)size); + return len; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c new file mode 100644 index 00000000..b56d645d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_oth.c @@ -0,0 +1,87 @@ +/* crypto/pem/pem_oth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +/* Handle 'other' PEMs: not private keys */ + +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u) +{ + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + char *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) + return NULL; + p = data; + ret = d2i(x, &p, len); + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + OPENSSL_free(data); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c new file mode 100644 index 00000000..5e4ff90a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c @@ -0,0 +1,255 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); + +/* + * These functions write a private key in PKCS#8 format: it is a "drop in" + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' + * is NULL then it uses the unencrypted private key form. The 'nid' versions + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + */ + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + if (!(p8inf = EVP_PKEY2PKCS8(x))) { + OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 0; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + return ret; + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } +} + +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); + if (!p8) + return NULL; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) + return NULL; + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (!ret) + return NULL; + if (x) { + if (*x) + EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} + + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +} + +static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *bp; + int ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return (0); + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; +} + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *bp; + EVP_PKEY *ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; +} + + +IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) + + +IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, + PKCS8_PRIV_KEY_INFO) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pkey.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pkey.c new file mode 100644 index 00000000..85160b53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_pkey.c @@ -0,0 +1,178 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if (!p8) + goto p8err; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_RSA) == 0) { + /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the + * standalone format. This and the cases below probably should not + * accept PKCS#8. */ + ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); + } else if (strcmp(nm, PEM_STRING_EC) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); + } else if (strcmp(nm, PEM_STRING_DSA) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); + } + p8err: + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + + err: + OPENSSL_free(nm); + OPENSSL_free(data); + return (ret); +} + +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u); +} + +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + EVP_PKEY *ret = PEM_read_bio_PrivateKey(b, x, cb, u); + BIO_free(b); + return ret; +} + +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c new file mode 100644 index 00000000..ab6a64fa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_x509.c @@ -0,0 +1,65 @@ +/* pem_x509.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c new file mode 100644 index 00000000..84111553 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c @@ -0,0 +1,65 @@ +/* pem_xaux.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/internal.h new file mode 100644 index 00000000..bd25e114 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/internal.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_INTERNAL_H +#define OPENSSL_HEADER_PKCS7_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs); + +// pkcs7_add_signed_data writes a PKCS#7, SignedData structure to |out|. While +// doing so it makes callbacks to let the caller fill in parts of the structure. +// All callbacks are ignored if NULL and return one on success or zero on error. +// +// digest_algos_cb: may write AlgorithmIdentifiers into the given CBB, which +// is a SET of digest algorithms. +// cert_crl_cb: may write the |certificates| or |crls| fields. +// (See https://datatracker.ietf.org/doc/html/rfc2315#section-9.1) +// signer_infos_cb: may write the contents of the |signerInfos| field. +// (See https://datatracker.ietf.org/doc/html/rfc2315#section-9.1) +// +// pkcs7_add_signed_data returns one on success or zero on error. +int pkcs7_add_signed_data(CBB *out, + int (*digest_algos_cb)(CBB *out, const void *arg), + int (*cert_crl_cb)(CBB *out, const void *arg), + int (*signer_infos_cb)(CBB *out, const void *arg), + const void *arg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS7_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7.c new file mode 100644 index 00000000..fe095a42 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7.c @@ -0,0 +1,193 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" + + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.2 +static const uint8_t kPKCS7SignedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x02}; + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) { + CBS in, content_info, content_type, wrapped_signed_data, signed_data; + uint64_t version; + + // The input may be in BER format. + *der_bytes = NULL; + if (!CBS_asn1_ber_to_der(cbs, &in, der_bytes) || + // See https://tools.ietf.org/html/rfc2315#section-7 + !CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) { + goto err; + } + + if (!CBS_mem_equal(&content_type, kPKCS7SignedData, + sizeof(kPKCS7SignedData))) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NOT_PKCS7_SIGNED_DATA); + goto err; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBS_get_asn1(&content_info, &wrapped_signed_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_signed_data, &signed_data, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&signed_data, &version) || + !CBS_get_asn1(&signed_data, NULL /* digests */, CBS_ASN1_SET) || + !CBS_get_asn1(&signed_data, NULL /* content */, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (version < 1) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_BAD_PKCS7_VERSION); + goto err; + } + + CBS_init(out, CBS_data(&signed_data), CBS_len(&signed_data)); + return 1; + +err: + OPENSSL_free(*der_bytes); + *der_bytes = NULL; + return 0; +} + +int PKCS7_get_raw_certificates(STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + CBS signed_data, certificates; + uint8_t *der_bytes = NULL; + int ret = 0, has_certificates; + const size_t initial_certs_len = sk_CRYPTO_BUFFER_num(out_certs); + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs) || + !CBS_get_optional_asn1( + &signed_data, &certificates, &has_certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + goto err; + } + + if (!has_certificates) { + CBS_init(&certificates, NULL, 0); + } + + while (CBS_len(&certificates) > 0) { + CBS cert; + if (!CBS_get_asn1_element(&certificates, &cert, CBS_ASN1_SEQUENCE)) { + goto err; + } + + CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&cert, pool); + if (buf == NULL || + !sk_CRYPTO_BUFFER_push(out_certs, buf)) { + CRYPTO_BUFFER_free(buf); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_CRYPTO_BUFFER_num(out_certs) != initial_certs_len) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_pop(out_certs); + CRYPTO_BUFFER_free(buf); + } + } + + return ret; +} + +static int pkcs7_bundle_raw_certificates_cb(CBB *out, const void *arg) { + const STACK_OF(CRYPTO_BUFFER) *certs = arg; + CBB certificates; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + return 0; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(certs); i++) { + CRYPTO_BUFFER *cert = sk_CRYPTO_BUFFER_value(certs, i); + if (!CBB_add_bytes(&certificates, CRYPTO_BUFFER_data(cert), + CRYPTO_BUFFER_len(cert))) { + return 0; + } + } + + // |certificates| is a implicitly-tagged SET OF. + return CBB_flush_asn1_set_of(&certificates) && CBB_flush(out); +} + +int PKCS7_bundle_raw_certificates(CBB *out, + const STACK_OF(CRYPTO_BUFFER) *certs) { + return pkcs7_add_signed_data(out, /*digest_algos_cb=*/NULL, + pkcs7_bundle_raw_certificates_cb, + /*signer_infos_cb=*/NULL, certs); +} + +int pkcs7_add_signed_data(CBB *out, + int (*digest_algos_cb)(CBB *out, const void *arg), + int (*cert_crl_cb)(CBB *out, const void *arg), + int (*signer_infos_cb)(CBB *out, const void *arg), + const void *arg) { + CBB outer_seq, oid, wrapped_seq, seq, version_bytes, digest_algos_set, + content_info, signer_infos; + + // See https://tools.ietf.org/html/rfc2315#section-7 + if (!CBB_add_asn1(out, &outer_seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&outer_seq, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7SignedData, sizeof(kPKCS7SignedData)) || + !CBB_add_asn1(&outer_seq, &wrapped_seq, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + // See https://tools.ietf.org/html/rfc2315#section-9.1 + !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&seq, &version_bytes, CBS_ASN1_INTEGER) || + !CBB_add_u8(&version_bytes, 1) || + !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) || + (digest_algos_cb != NULL && !digest_algos_cb(&digest_algos_set, arg)) || + !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + (cert_crl_cb != NULL && !cert_crl_cb(&seq, arg)) || + !CBB_add_asn1(&seq, &signer_infos, CBS_ASN1_SET) || + (signer_infos_cb != NULL && !signer_infos_cb(&signer_infos, arg))) { + return 0; + } + + return CBB_flush(out); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c new file mode 100644 index 00000000..710047e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c @@ -0,0 +1,526 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) { + int ret = 0; + const size_t initial_certs_len = sk_X509_num(out_certs); + STACK_OF(CRYPTO_BUFFER) *raw = sk_CRYPTO_BUFFER_new_null(); + if (raw == NULL || + !PKCS7_get_raw_certificates(raw, cbs, NULL)) { + goto err; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(raw); i++) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(raw, i); + X509 *x509 = X509_parse_from_buffer(buf); + if (x509 == NULL || + !sk_X509_push(out_certs, x509)) { + X509_free(x509); + goto err; + } + } + + ret = 1; + +err: + sk_CRYPTO_BUFFER_pop_free(raw, CRYPTO_BUFFER_free); + if (!ret) { + while (sk_X509_num(out_certs) != initial_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) { + CBS signed_data, crls; + uint8_t *der_bytes = NULL; + int ret = 0, has_crls; + const size_t initial_crls_len = sk_X509_CRL_num(out_crls); + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs) || + // Even if only CRLs are included, there may be an empty certificates + // block. OpenSSL does this, for example. + !CBS_get_optional_asn1( + &signed_data, NULL, NULL, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_optional_asn1( + &signed_data, &crls, &has_crls, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + goto err; + } + + if (!has_crls) { + CBS_init(&crls, NULL, 0); + } + + while (CBS_len(&crls) > 0) { + CBS crl_data; + X509_CRL *crl; + const uint8_t *inp; + + if (!CBS_get_asn1_element(&crls, &crl_data, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (CBS_len(&crl_data) > LONG_MAX) { + goto err; + } + inp = CBS_data(&crl_data); + crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data)); + if (!crl) { + goto err; + } + + assert(inp == CBS_data(&crl_data) + CBS_len(&crl_data)); + + if (sk_X509_CRL_push(out_crls, crl) == 0) { + X509_CRL_free(crl); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_X509_CRL_num(out_crls) != initial_crls_len) { + X509_CRL_free(sk_X509_CRL_pop(out_crls)); + } + } + + return ret; +} + +int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_certificates(out_certs, &cbs); + OPENSSL_free(data); + return ret; +} + +int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_CRLs(out_crls, &cbs); + OPENSSL_free(data); + return ret; +} + +static int pkcs7_bundle_certificates_cb(CBB *out, const void *arg) { + const STACK_OF(X509) *certs = arg; + size_t i; + CBB certificates; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + return 0; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x509 = sk_X509_value(certs, i); + uint8_t *buf; + int len = i2d_X509(x509, NULL); + + if (len < 0 || + !CBB_add_space(&certificates, &buf, len) || + i2d_X509(x509, &buf) < 0) { + return 0; + } + } + + // |certificates| is a implicitly-tagged SET OF. + return CBB_flush_asn1_set_of(&certificates) && CBB_flush(out); +} + +int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) { + return pkcs7_add_signed_data(out, /*digest_algos_cb=*/NULL, + pkcs7_bundle_certificates_cb, + /*signer_infos_cb=*/NULL, certs); +} + +static int pkcs7_bundle_crls_cb(CBB *out, const void *arg) { + const STACK_OF(X509_CRL) *crls = arg; + size_t i; + CBB crl_data; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &crl_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + return 0; + } + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + X509_CRL *crl = sk_X509_CRL_value(crls, i); + uint8_t *buf; + int len = i2d_X509_CRL(crl, NULL); + + if (len < 0 || + !CBB_add_space(&crl_data, &buf, len) || + i2d_X509_CRL(crl, &buf) < 0) { + return 0; + } + } + + // |crl_data| is a implicitly-tagged SET OF. + return CBB_flush_asn1_set_of(&crl_data) && CBB_flush(out); +} + +int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) { + return pkcs7_add_signed_data(out, /*digest_algos_cb=*/NULL, + pkcs7_bundle_crls_cb, + /*signer_infos_cb=*/NULL, crls); +} + +static PKCS7 *pkcs7_new(CBS *cbs) { + PKCS7 *ret = OPENSSL_malloc(sizeof(PKCS7)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(PKCS7)); + ret->type = OBJ_nid2obj(NID_pkcs7_signed); + ret->d.sign = OPENSSL_malloc(sizeof(PKCS7_SIGNED)); + if (ret->d.sign == NULL) { + goto err; + } + ret->d.sign->cert = sk_X509_new_null(); + ret->d.sign->crl = sk_X509_CRL_new_null(); + CBS copy = *cbs, copy2 = *cbs; + if (ret->d.sign->cert == NULL || ret->d.sign->crl == NULL || + !PKCS7_get_certificates(ret->d.sign->cert, ©) || + !PKCS7_get_CRLs(ret->d.sign->crl, cbs)) { + goto err; + } + + if (sk_X509_num(ret->d.sign->cert) == 0) { + sk_X509_free(ret->d.sign->cert); + ret->d.sign->cert = NULL; + } + + if (sk_X509_CRL_num(ret->d.sign->crl) == 0) { + sk_X509_CRL_free(ret->d.sign->crl); + ret->d.sign->crl = NULL; + } + + ret->ber_len = CBS_len(©2) - CBS_len(cbs); + ret->ber_bytes = OPENSSL_memdup(CBS_data(©2), ret->ber_len); + if (ret->ber_bytes == NULL) { + goto err; + } + + return ret; + +err: + PKCS7_free(ret); + return NULL; +} + +PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, + size_t len) { + CBS cbs; + CBS_init(&cbs, *inp, len); + PKCS7 *ret = pkcs7_new(&cbs); + if (ret == NULL) { + return NULL; + } + *inp = CBS_data(&cbs); + if (out != NULL) { + PKCS7_free(*out); + *out = ret; + } + return ret; +} + +PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out) { + // Use a generous bound, to allow for PKCS#7 files containing large root sets. + static const size_t kMaxSize = 4 * 1024 * 1024; + uint8_t *data; + size_t len; + if (!BIO_read_asn1(bio, &data, &len, kMaxSize)) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, data, len); + PKCS7 *ret = pkcs7_new(&cbs); + OPENSSL_free(data); + if (out != NULL && ret != NULL) { + PKCS7_free(*out); + *out = ret; + } + return ret; +} + +int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) { + if (p7->ber_len > INT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + return -1; + } + + if (out == NULL) { + return (int)p7->ber_len; + } + + if (*out == NULL) { + *out = OPENSSL_malloc(p7->ber_len); + if (*out == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return -1; + } + OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len); + } else { + OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len); + *out += p7->ber_len; + } + return (int)p7->ber_len; +} + +int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) { + return BIO_write_all(bio, p7->ber_bytes, p7->ber_len); +} + +void PKCS7_free(PKCS7 *p7) { + if (p7 == NULL) { + return; + } + + OPENSSL_free(p7->ber_bytes); + ASN1_OBJECT_free(p7->type); + // We only supported signed data. + if (p7->d.sign != NULL) { + sk_X509_pop_free(p7->d.sign->cert, X509_free); + sk_X509_CRL_pop_free(p7->d.sign->crl, X509_CRL_free); + OPENSSL_free(p7->d.sign); + } + OPENSSL_free(p7); +} + +// We only support signed data, so these getters are no-ops. +int PKCS7_type_is_data(const PKCS7 *p7) { return 0; } +int PKCS7_type_is_digest(const PKCS7 *p7) { return 0; } +int PKCS7_type_is_encrypted(const PKCS7 *p7) { return 0; } +int PKCS7_type_is_enveloped(const PKCS7 *p7) { return 0; } +int PKCS7_type_is_signed(const PKCS7 *p7) { return 1; } +int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7) { return 0; } + +// write_sha256_ai writes an AlgorithmIdentifier for SHA-256 to +// |digest_algos_set|. +static int write_sha256_ai(CBB *digest_algos_set, const void *arg) { + CBB seq; + return CBB_add_asn1(digest_algos_set, &seq, CBS_ASN1_SEQUENCE) && + OBJ_nid2cbb(&seq, NID_sha256) && // + // https://datatracker.ietf.org/doc/html/rfc5754#section-2 + // "Implementations MUST generate SHA2 AlgorithmIdentifiers with absent + // parameters." + CBB_flush(digest_algos_set); +} + +// sign_sha256 writes at most |max_out_sig| bytes of the signature of |data| by +// |pkey| to |out_sig| and sets |*out_sig_len| to the number of bytes written. +// It returns one on success or zero on error. +static int sign_sha256(uint8_t *out_sig, size_t *out_sig_len, + size_t max_out_sig, EVP_PKEY *pkey, BIO *data) { + static const size_t kBufSize = 4096; + uint8_t *buffer = OPENSSL_malloc(kBufSize); + if (!buffer) { + return 0; + } + + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + + int ret = 0; + if (!EVP_DigestSignInit(&ctx, NULL, EVP_sha256(), NULL, pkey)) { + goto out; + } + + for (;;) { + const int n = BIO_read(data, buffer, kBufSize); + if (n == 0) { + break; + } else if (n < 0 || !EVP_DigestSignUpdate(&ctx, buffer, n)) { + goto out; + } + } + + *out_sig_len = max_out_sig; + if (!EVP_DigestSignFinal(&ctx, out_sig, out_sig_len)) { + goto out; + } + + ret = 1; + +out: + EVP_MD_CTX_cleanup(&ctx); + OPENSSL_free(buffer); + return ret; +} + +struct signer_info_data { + const X509 *sign_cert; + uint8_t *signature; + size_t signature_len; +}; + +// write_signer_info writes the SignerInfo structure from +// https://datatracker.ietf.org/doc/html/rfc2315#section-9.2 to |out|. It +// returns one on success or zero on error. +static int write_signer_info(CBB *out, const void *arg) { + const struct signer_info_data *const si_data = arg; + + int ret = 0; + uint8_t *subject_bytes = NULL; + uint8_t *serial_bytes = NULL; + + const int subject_len = + i2d_X509_NAME(X509_get_subject_name(si_data->sign_cert), &subject_bytes); + const int serial_len = i2d_ASN1_INTEGER( + (ASN1_INTEGER *)X509_get0_serialNumber(si_data->sign_cert), + &serial_bytes); + + CBB seq, issuer_and_serial, signing_algo, null, signature; + if (subject_len < 0 || + serial_len < 0 || + !CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + // version + !CBB_add_asn1_uint64(&seq, 1) || + !CBB_add_asn1(&seq, &issuer_and_serial, CBS_ASN1_SEQUENCE) || + !CBB_add_bytes(&issuer_and_serial, subject_bytes, subject_len) || + !CBB_add_bytes(&issuer_and_serial, serial_bytes, serial_len) || + !write_sha256_ai(&seq, NULL) || + !CBB_add_asn1(&seq, &signing_algo, CBS_ASN1_SEQUENCE) || + !OBJ_nid2cbb(&signing_algo, NID_rsaEncryption) || + !CBB_add_asn1(&signing_algo, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&seq, &signature, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&signature, si_data->signature, si_data->signature_len) || + !CBB_flush(out)) { + goto out; + } + + ret = 1; + +out: + OPENSSL_free(subject_bytes); + OPENSSL_free(serial_bytes); + return ret; +} + +PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags) { + CBB cbb; + if (!CBB_init(&cbb, 2048)) { + return NULL; + } + + uint8_t *der = NULL; + size_t len; + PKCS7 *ret = NULL; + + if (sign_cert == NULL && pkey == NULL && flags == PKCS7_DETACHED) { + // Caller just wants to bundle certificates. + if (!PKCS7_bundle_certificates(&cbb, certs)) { + goto out; + } + } else if (sign_cert != NULL && pkey != NULL && certs == NULL && + data != NULL && + flags == (PKCS7_NOATTR | PKCS7_BINARY | PKCS7_NOCERTS | + PKCS7_DETACHED) && + EVP_PKEY_id(pkey) == NID_rsaEncryption) { + // sign-file.c from the Linux kernel. + const size_t signature_max_len = EVP_PKEY_size(pkey); + struct signer_info_data si_data = { + .sign_cert = sign_cert, + .signature = OPENSSL_malloc(signature_max_len), + }; + + if (!si_data.signature || + !sign_sha256(si_data.signature, &si_data.signature_len, + signature_max_len, pkey, data) || + !pkcs7_add_signed_data(&cbb, write_sha256_ai, /*cert_crl_cb=*/NULL, + write_signer_info, &si_data)) { + OPENSSL_free(si_data.signature); + goto out; + } + OPENSSL_free(si_data.signature); + } else { + OPENSSL_PUT_ERROR(PKCS7, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto out; + } + + if (!CBB_finish(&cbb, &der, &len)) { + goto out; + } + + CBS cbs; + CBS_init(&cbs, der, len); + ret = pkcs7_new(&cbs); + +out: + CBB_cleanup(&cbb); + OPENSSL_free(der); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/internal.h new file mode 100644 index 00000000..1fcf0d92 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/internal.h @@ -0,0 +1,137 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_PKCS8_INTERNAL_H +#define OPENSSL_HEADER_PKCS8_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct pkcs8_priv_key_info_st { + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_OCTET_STRING *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; + +// pkcs8_pbe_decrypt decrypts |in| using the PBE scheme described by +// |algorithm|, which should be a serialized AlgorithmIdentifier structure. On +// success, it sets |*out| to a newly-allocated buffer containing the decrypted +// result and returns one. Otherwise, it returns zero. +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len); + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +// pkcs12_key_gen runs the PKCS#12 key derivation function as specified in +// RFC 7292, appendix B. On success, it writes the resulting |out_len| bytes of +// key material to |out| and returns one. Otherwise, it returns zero. |id| +// should be one of the |PKCS12_*_ID| values. +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md); + +// pkcs12_pbe_encrypt_init configures |ctx| for encrypting with a PBES1 scheme +// defined in PKCS#12. It writes the corresponding AlgorithmIdentifier to |out|. +int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len); + +struct pbe_suite { + int pbe_nid; + uint8_t oid[10]; + uint8_t oid_len; + const EVP_CIPHER *(*cipher_func)(void); + const EVP_MD *(*md_func)(void); + // decrypt_init initialize |ctx| for decrypting. The password is specified by + // |pass| and |pass_len|. |param| contains the serialized parameters field of + // the AlgorithmIdentifier. + // + // It returns one on success and zero on error. + int (*decrypt_init)(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); +}; + +#define PKCS5_SALT_LEN 8 + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); + +// PKCS5_pbe2_encrypt_init configures |ctx| for encrypting with PKCS #5 PBES2, +// as defined in RFC 2998, with the specified parameters. It writes the +// corresponding AlgorithmIdentifier to |out|. +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len); + +// pkcs12_iterations_acceptable returns one if |iterations| is a reasonable +// number of PBKDF2 iterations and zero otherwise. +int pkcs12_iterations_acceptable(uint64_t iterations); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS8_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/p5_pbev2.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/p5_pbev2.c new file mode 100644 index 00000000..517158bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/p5_pbev2.c @@ -0,0 +1,316 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999-2004. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// 1.2.840.113549.1.5.12 +static const uint8_t kPBKDF2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0c}; + +// 1.2.840.113549.1.5.13 +static const uint8_t kPBES2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d}; + +// 1.2.840.113549.2.7 +static const uint8_t kHMACWithSHA1[] = {0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x02, 0x07}; + +// 1.2.840.113549.2.9 +static const uint8_t kHMACWithSHA256[] = {0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x02, 0x09}; + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; + const EVP_CIPHER *(*cipher_func)(void); +} kCipherOIDs[] = { + // 1.2.840.113549.3.2 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02}, + 8, + NID_rc2_cbc, + &EVP_rc2_cbc}, + // 1.2.840.113549.3.7 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07}, + 8, + NID_des_ede3_cbc, + &EVP_des_ede3_cbc}, + // 2.16.840.1.101.3.4.1.2 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02}, + 9, + NID_aes_128_cbc, + &EVP_aes_128_cbc}, + // 2.16.840.1.101.3.4.1.22 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16}, + 9, + NID_aes_192_cbc, + &EVP_aes_192_cbc}, + // 2.16.840.1.101.3.4.1.42 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a}, + 9, + NID_aes_256_cbc, + &EVP_aes_256_cbc}, +}; + +static const EVP_CIPHER *cbs_to_cipher(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (CBS_mem_equal(cbs, kCipherOIDs[i].oid, kCipherOIDs[i].oid_len)) { + return kCipherOIDs[i].cipher_func(); + } + } + + return NULL; +} + +static int add_cipher_oid(CBB *out, int nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (kCipherOIDs[i].nid == nid) { + CBB child; + return CBB_add_asn1(out, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, kCipherOIDs[i].oid, + kCipherOIDs[i].oid_len) && + CBB_flush(out); + } + } + + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; +} + +static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const EVP_MD *pbkdf2_md, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + const uint8_t *iv, size_t iv_len, int enc) { + if (iv_len != EVP_CIPHER_iv_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); + return 0; + } + + uint8_t key[EVP_MAX_KEY_LENGTH]; + int ret = PKCS5_PBKDF2_HMAC(pass, pass_len, salt, salt_len, iterations, + pbkdf2_md, EVP_CIPHER_key_length(cipher), key) && + EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, key, iv, enc); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + return ret; +} + +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len) { + int cipher_nid = EVP_CIPHER_nid(cipher); + if (cipher_nid == NID_undef) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return 0; + } + + // Generate a random IV. + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher))) { + return 0; + } + + // See RFC 2898, appendix A. + CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb, + iv_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &kdf, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) || + !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(&kdf_param, iterations) || + // Specify a key length for RC2. + (cipher_nid == NID_rc2_cbc && + !CBB_add_asn1_uint64(&kdf_param, EVP_CIPHER_key_length(cipher))) || + // Omit the PRF. We use the default hmacWithSHA1. + !CBB_add_asn1(¶m, &cipher_cbb, CBS_ASN1_SEQUENCE) || + !add_cipher_oid(&cipher_cbb, cipher_nid) || + // RFC 2898 says RC2-CBC and RC5-CBC-Pad use a SEQUENCE with version and + // IV, but OpenSSL always uses an OCTET STRING IV, so we do the same. + !CBB_add_asn1(&cipher_cbb, &iv_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&iv_cbb, iv, EVP_CIPHER_iv_length(cipher)) || + !CBB_flush(out)) { + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, EVP_sha1(), iterations, pass, + pass_len, salt, salt_len, iv, + EVP_CIPHER_iv_length(cipher), 1 /* encrypt */); +} + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param) { + CBS pbe_param, kdf, kdf_obj, enc_scheme, enc_obj; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + CBS_len(param) != 0 || + !CBS_get_asn1(&pbe_param, &kdf, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &enc_scheme, CBS_ASN1_SEQUENCE) || + CBS_len(&pbe_param) != 0 || + !CBS_get_asn1(&kdf, &kdf_obj, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&enc_scheme, &enc_obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + // Only PBKDF2 is supported. + if (!CBS_mem_equal(&kdf_obj, kPBKDF2, sizeof(kPBKDF2))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + return 0; + } + + // See if we recognise the encryption algorithm. + const EVP_CIPHER *cipher = cbs_to_cipher(&enc_obj); + if (cipher == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; + } + + // Parse the KDF parameters. See RFC 8018, appendix A.2. + CBS pbkdf2_params, salt; + uint64_t iterations; + if (!CBS_get_asn1(&kdf, &pbkdf2_params, CBS_ASN1_SEQUENCE) || + CBS_len(&kdf) != 0 || + !CBS_get_asn1(&pbkdf2_params, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbkdf2_params, &iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (!pkcs12_iterations_acceptable(iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + // The optional keyLength parameter, if present, must match the key length of + // the cipher. + if (CBS_peek_asn1_tag(&pbkdf2_params, CBS_ASN1_INTEGER)) { + uint64_t key_len; + if (!CBS_get_asn1_uint64(&pbkdf2_params, &key_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (key_len != EVP_CIPHER_key_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEYLENGTH); + return 0; + } + } + + const EVP_MD *md = EVP_sha1(); + if (CBS_len(&pbkdf2_params) != 0) { + CBS alg_id, prf; + if (!CBS_get_asn1(&pbkdf2_params, &alg_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&alg_id, &prf, CBS_ASN1_OBJECT) || + CBS_len(&pbkdf2_params) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (CBS_mem_equal(&prf, kHMACWithSHA1, sizeof(kHMACWithSHA1))) { + // hmacWithSHA1 is the DEFAULT, so DER requires it be omitted, but we + // match OpenSSL in tolerating it being present. + md = EVP_sha1(); + } else if (CBS_mem_equal(&prf, kHMACWithSHA256, sizeof(kHMACWithSHA256))) { + md = EVP_sha256(); + } else { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + // All supported PRFs use a NULL parameter. + CBS null; + if (!CBS_get_asn1(&alg_id, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(&alg_id) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + } + + // Parse the encryption scheme parameters. Note OpenSSL does not match the + // specification. Per RFC 2898, this should depend on the encryption scheme. + // In particular, RC2-CBC uses a SEQUENCE with version and IV. We align with + // OpenSSL. + CBS iv; + if (!CBS_get_asn1(&enc_scheme, &iv, CBS_ASN1_OCTETSTRING) || + CBS_len(&enc_scheme) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, md, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c new file mode 100644 index 00000000..11084c6f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c @@ -0,0 +1,530 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static int pkcs12_encode_password(const char *in, size_t in_len, uint8_t **out, + size_t *out_len) { + CBB cbb; + if (!CBB_init(&cbb, in_len * 2)) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + + // Convert the password to BMPString, or UCS-2. See + // https://tools.ietf.org/html/rfc7292#appendix-B.1. + CBS cbs; + CBS_init(&cbs, (const uint8_t *)in, in_len); + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!cbs_get_utf8(&cbs, &c) || + !cbb_add_ucs2_be(&cbb, c)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); + goto err; + } + } + + // Terminate the result with a UCS-2 NUL. + if (!cbb_add_ucs2_be(&cbb, 0) || + !CBB_finish(&cbb, out, out_len)) { + goto err; + } + + return 1; + +err: + CBB_cleanup(&cbb); + return 0; +} + +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md) { + // See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the + // specification have errata applied and other typos fixed. + + if (iterations < 1) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + uint8_t *pass_raw = NULL, *I = NULL; + size_t pass_raw_len = 0, I_len = 0; + // If |pass| is NULL, we use the empty string rather than {0, 0} as the raw + // password. + if (pass != NULL && + !pkcs12_encode_password(pass, pass_len, &pass_raw, &pass_raw_len)) { + goto err; + } + + // In the spec, |block_size| is called "v", but measured in bits. + size_t block_size = EVP_MD_block_size(md); + + // 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies + // of ID. + uint8_t D[EVP_MAX_MD_BLOCK_SIZE]; + OPENSSL_memset(D, id, block_size); + + // 2. Concatenate copies of the salt together to create a string S of length + // v(ceiling(s/v)) bits (the final copy of the salt may be truncated to + // create S). Note that if the salt is the empty string, then so is S. + // + // 3. Concatenate copies of the password together to create a string P of + // length v(ceiling(p/v)) bits (the final copy of the password may be + // truncated to create P). Note that if the password is the empty string, + // then so is P. + // + // 4. Set I=S||P to be the concatenation of S and P. + if (salt_len + block_size - 1 < salt_len || + pass_raw_len + block_size - 1 < pass_raw_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + size_t S_len = block_size * ((salt_len + block_size - 1) / block_size); + size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size); + I_len = S_len + P_len; + if (I_len < S_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + I = OPENSSL_malloc(I_len); + if (I_len != 0 && I == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < S_len; i++) { + I[i] = salt[i % salt_len]; + } + for (size_t i = 0; i < P_len; i++) { + I[i + S_len] = pass_raw[i % pass_raw_len]; + } + + while (out_len != 0) { + // A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I, + // H(H(H(... H(D||I)))) + uint8_t A[EVP_MAX_MD_SIZE]; + unsigned A_len; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, D, block_size) || + !EVP_DigestUpdate(&ctx, I, I_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + for (unsigned iter = 1; iter < iterations; iter++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, A, A_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + } + + size_t todo = out_len < A_len ? out_len : A_len; + OPENSSL_memcpy(out, A, todo); + out += todo; + out_len -= todo; + if (out_len == 0) { + break; + } + + // B. Concatenate copies of A_i to create a string B of length v bits (the + // final copy of A_i may be truncated to create B). + uint8_t B[EVP_MAX_MD_BLOCK_SIZE]; + for (size_t i = 0; i < block_size; i++) { + B[i] = A[i % A_len]; + } + + // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks, + // where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod + // 2^v for each j. + assert(I_len % block_size == 0); + for (size_t i = 0; i < I_len; i += block_size) { + unsigned carry = 1; + for (size_t j = block_size - 1; j < block_size; j--) { + carry += I[i + j] + B[j]; + I[i + j] = (uint8_t)carry; + carry >>= 8; + } + } + } + + ret = 1; + +err: + OPENSSL_free(I); + OPENSSL_free(pass_raw); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +static int pkcs12_pbe_cipher_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int is_encrypt) { + const EVP_CIPHER *cipher = suite->cipher_func(); + const EVP_MD *md = suite->md_func(); + + uint8_t key[EVP_MAX_KEY_LENGTH]; + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_KEY_ID, iterations, + EVP_CIPHER_key_length(cipher), key, md) || + !pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_IV_ID, iterations, + EVP_CIPHER_iv_length(cipher), iv, md)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR); + return 0; + } + + int ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, is_encrypt); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + return ret; +} + +static int pkcs12_pbe_decrypt_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, const char *pass, + size_t pass_len, CBS *param) { + CBS pbe_param, salt; + uint64_t iterations; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbe_param, &iterations) || + CBS_len(&pbe_param) != 0 || + CBS_len(param) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (!pkcs12_iterations_acceptable(iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + 0 /* decrypt */); +} + +static const struct pbe_suite kBuiltinPBE[] = { + { + NID_pbe_WithSHA1And40BitRC2_CBC, + // 1.2.840.113549.1.12.1.6 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06}, + 10, + EVP_rc2_40_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And128BitRC4, + // 1.2.840.113549.1.12.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01}, + 10, + EVP_rc4, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + // 1.2.840.113549.1.12.1.3 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03}, + 10, + EVP_des_ede3_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbes2, + // 1.2.840.113549.1.5.13 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d}, + 9, + NULL, + NULL, + PKCS5_pbe2_decrypt_init, + }, +}; + +static const struct pbe_suite *get_pkcs12_pbe_suite(int pbe_nid) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (kBuiltinPBE[i].pbe_nid == pbe_nid && + // If |cipher_func| or |md_func| are missing, this is a PBES2 scheme. + kBuiltinPBE[i].cipher_func != NULL && + kBuiltinPBE[i].md_func != NULL) { + return &kBuiltinPBE[i]; + } + } + + return NULL; +} + +int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len) { + const struct pbe_suite *suite = get_pkcs12_pbe_suite(alg); + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + return 0; + } + + // See RFC 2898, appendix A.3. + CBB algorithm, oid, param, salt_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, suite->oid, suite->oid_len) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(¶m, iterations) || + !CBB_flush(out)) { + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, iterations, pass, pass_len, salt, + salt_len, 1 /* encrypt */); +} + +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len) { + int ret = 0; + uint8_t *buf = NULL;; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + CBS obj; + if (!CBS_get_asn1(algorithm, &obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + const struct pbe_suite *suite = NULL; + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { + suite = &kBuiltinPBE[i]; + break; + } + } + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + goto err; + } + + if (!suite->decrypt_init(suite, &ctx, pass, pass_len, algorithm)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE); + goto err; + } + + buf = OPENSSL_malloc(in_len); + if (buf == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (in_len > INT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + int n1, n2; + if (!EVP_DecryptUpdate(&ctx, buf, &n1, in, (int)in_len) || + !EVP_DecryptFinal_ex(&ctx, buf + n1, &n2)) { + goto err; + } + + *out = buf; + *out_len = n1 + n2; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, const char *pass, + size_t pass_len) { + // See RFC 5208, section 6. + CBS epki, algorithm, ciphertext; + if (!CBS_get_asn1(cbs, &epki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + CBS_len(&epki) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + uint8_t *out; + size_t out_len; + if (!pkcs8_pbe_decrypt(&out, &out_len, &algorithm, pass, pass_len, + CBS_data(&ciphertext), CBS_len(&ciphertext))) { + return 0; + } + + CBS pki; + CBS_init(&pki, out, out_len); + EVP_PKEY *ret = EVP_parse_private_key(&pki); + OPENSSL_free(out); + return ret; +} + +int PKCS8_marshal_encrypted_private_key(CBB *out, int pbe_nid, + const EVP_CIPHER *cipher, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, const EVP_PKEY *pkey) { + int ret = 0; + uint8_t *plaintext = NULL, *salt_buf = NULL; + size_t plaintext_len = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + // Generate a random salt if necessary. + if (salt == NULL) { + if (salt_len == 0) { + salt_len = PKCS5_SALT_LEN; + } + + salt_buf = OPENSSL_malloc(salt_len); + if (salt_buf == NULL || + !RAND_bytes(salt_buf, salt_len)) { + goto err; + } + + salt = salt_buf; + } + + if (iterations <= 0) { + iterations = PKCS12_DEFAULT_ITER; + } + + // Serialize the input key. + CBB plaintext_cbb; + if (!CBB_init(&plaintext_cbb, 128) || + !EVP_marshal_private_key(&plaintext_cbb, pkey) || + !CBB_finish(&plaintext_cbb, &plaintext, &plaintext_len)) { + CBB_cleanup(&plaintext_cbb); + goto err; + } + + CBB epki; + if (!CBB_add_asn1(out, &epki, CBS_ASN1_SEQUENCE)) { + goto err; + } + + // TODO(davidben): OpenSSL has since extended |pbe_nid| to control either the + // PBES1 scheme or the PBES2 PRF. E.g. passing |NID_hmacWithSHA256| will + // select PBES2 with HMAC-SHA256 as the PRF. Implement this if anything uses + // it. See 5693a30813a031d3921a016a870420e7eb93ec90 in OpenSSL. + int alg_ok; + if (pbe_nid == -1) { + alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } else { + alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } + if (!alg_ok) { + goto err; + } + + size_t max_out = plaintext_len + EVP_CIPHER_CTX_block_size(&ctx); + if (max_out < plaintext_len) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); + goto err; + } + + CBB ciphertext; + uint8_t *ptr; + int n1, n2; + if (!CBB_add_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + !CBB_reserve(&ciphertext, &ptr, max_out) || + !EVP_CipherUpdate(&ctx, ptr, &n1, plaintext, plaintext_len) || + !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || + !CBB_did_write(&ciphertext, n1 + n2) || + !CBB_flush(out)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(plaintext); + OPENSSL_free(salt_buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c new file mode 100644 index 00000000..10562d4a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c @@ -0,0 +1,1401 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +int pkcs12_iterations_acceptable(uint64_t iterations) { +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + static const uint64_t kIterationsLimit = 2048; +#else + // Windows imposes a limit of 600K. Mozilla say: “so them increasing + // maximum to something like 100M or 1G (to have few decades of breathing + // room) would be very welcome”[1]. So here we set the limit to 100M. + // + // [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1436873#c14 + static const uint64_t kIterationsLimit = 100 * 1000000; +#endif + + return 0 < iterations && iterations <= kIterationsLimit; +} + +// Minor tweak to operation: zero private key data +static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { + // Since the structure must still be valid use ASN1_OP_FREE_PRE + if (operation == ASN1_OP_FREE_PRE) { + PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; + if (key->pkey) { + OPENSSL_cleanse(key->pkey->data, key->pkey->length); + } + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, + int ptype, void *pval, uint8_t *penc, int penclen) { + if (version >= 0 && + !ASN1_INTEGER_set(priv->version, version)) { + return 0; + } + + if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { + return 0; + } + + if (penc != NULL) { + ASN1_STRING_set0(priv->pkey, penc, penclen); + } + + return 1; +} + +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const uint8_t **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) { + if (ppkalg) { + *ppkalg = p8->pkeyalg->algorithm; + } + if (pk) { + *pk = ASN1_STRING_data(p8->pkey); + *ppklen = ASN1_STRING_length(p8->pkey); + } + if (pa) { + *pa = p8->pkeyalg; + } + return 1; +} + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { + uint8_t *der = NULL; + int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der); + if (der_len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, der, (size_t)der_len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + EVP_PKEY_free(ret); + OPENSSL_free(der); + return NULL; + } + + OPENSSL_free(der); + return ret; +} + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { + CBB cbb; + uint8_t *der = NULL; + size_t der_len; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_private_key(&cbb, pkey) || + !CBB_finish(&cbb, &der, &der_len) || + der_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR); + goto err; + } + + const uint8_t *p = der; + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len); + if (p8 == NULL || p != der + der_len) { + PKCS8_PRIV_KEY_INFO_free(p8); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + OPENSSL_free(der); + return p8; + +err: + OPENSSL_free(der); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass, + int pass_len_in) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + PKCS8_PRIV_KEY_INFO *ret = NULL; + EVP_PKEY *pkey = NULL; + uint8_t *in = NULL; + + // Convert the legacy ASN.1 object to a byte string. + int in_len = i2d_X509_SIG(pkcs8, &in); + if (in_len < 0) { + goto err; + } + + CBS cbs; + CBS_init(&cbs, in, in_len); + pkey = PKCS8_parse_encrypted_private_key(&cbs, pass, pass_len); + if (pkey == NULL || CBS_len(&cbs) != 0) { + goto err; + } + + ret = EVP_PKEY2PKCS8(pkey); + +err: + OPENSSL_free(in); + EVP_PKEY_free(pkey); + return ret; +} + +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + int pass_len_in, const uint8_t *salt, size_t salt_len, + int iterations, PKCS8_PRIV_KEY_INFO *p8inf) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + // Parse out the private key. + EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf); + if (pkey == NULL) { + return NULL; + } + + X509_SIG *ret = NULL; + uint8_t *der = NULL; + size_t der_len; + CBB cbb; + if (!CBB_init(&cbb, 128) || + !PKCS8_marshal_encrypted_private_key(&cbb, pbe_nid, cipher, pass, + pass_len, salt, salt_len, iterations, + pkey) || + !CBB_finish(&cbb, &der, &der_len)) { + CBB_cleanup(&cbb); + goto err; + } + + // Convert back to legacy ASN.1 objects. + const uint8_t *ptr = der; + ret = d2i_X509_SIG(NULL, &ptr, der_len); + if (ret == NULL || ptr != der + der_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_INTERNAL_ERROR); + X509_SIG_free(ret); + ret = NULL; + } + +err: + OPENSSL_free(der); + EVP_PKEY_free(pkey); + return ret; +} + +struct pkcs12_context { + EVP_PKEY **out_key; + STACK_OF(X509) *out_certs; + const char *password; + size_t password_len; +}; + +// PKCS12_handle_sequence parses a BER-encoded SEQUENCE of elements in a PKCS#12 +// structure. +static int PKCS12_handle_sequence( + CBS *sequence, struct pkcs12_context *ctx, + int (*handle_element)(CBS *cbs, struct pkcs12_context *ctx)) { + uint8_t *storage = NULL; + CBS in; + int ret = 0; + + // Although a BER->DER conversion is done at the beginning of |PKCS12_parse|, + // the ASN.1 data gets wrapped in OCTETSTRINGs and/or encrypted and the + // conversion cannot see through those wrappings. So each time we step + // through one we need to convert to DER again. + if (!CBS_asn1_ber_to_der(sequence, &in, &storage)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + CBS child; + if (!CBS_get_asn1(&in, &child, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + while (CBS_len(&child) > 0) { + CBS element; + if (!CBS_get_asn1(&child, &element, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!handle_element(&element, ctx)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(storage); + return ret; +} + +// 1.2.840.113549.1.12.10.1.1 +static const uint8_t kKeyBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x01}; + +// 1.2.840.113549.1.12.10.1.2 +static const uint8_t kPKCS8ShroudedKeyBag[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02}; + +// 1.2.840.113549.1.12.10.1.3 +static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x03}; + +// 1.2.840.113549.1.9.20 +static const uint8_t kFriendlyName[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x14}; + +// 1.2.840.113549.1.9.21 +static const uint8_t kLocalKeyID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x15}; + +// 1.2.840.113549.1.9.22.1 +static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x16, 0x01}; + +// parse_bag_attributes parses the bagAttributes field of a SafeBag structure. +// It sets |*out_friendly_name| to a newly-allocated copy of the friendly name, +// encoded as a UTF-8 string, or NULL if there is none. It returns one on +// success and zero on error. +static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, + size_t *out_friendly_name_len) { + *out_friendly_name = NULL; + *out_friendly_name_len = 0; + + // See https://tools.ietf.org/html/rfc7292#section-4.2. + while (CBS_len(attrs) != 0) { + CBS attr, oid, values; + if (!CBS_get_asn1(attrs, &attr, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&attr, &oid, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&attr, &values, CBS_ASN1_SET) || + CBS_len(&attr) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + if (CBS_mem_equal(&oid, kFriendlyName, sizeof(kFriendlyName))) { + // See https://tools.ietf.org/html/rfc2985, section 5.5.1. + CBS value; + if (*out_friendly_name != NULL || + !CBS_get_asn1(&values, &value, CBS_ASN1_BMPSTRING) || + CBS_len(&values) != 0 || + CBS_len(&value) == 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + // Convert the friendly name to UTF-8. + CBB cbb; + if (!CBB_init(&cbb, CBS_len(&value))) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + while (CBS_len(&value) != 0) { + uint32_t c; + if (!cbs_get_ucs2_be(&value, &c) || + !cbb_add_utf8(&cbb, c)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); + CBB_cleanup(&cbb); + goto err; + } + } + if (!CBB_finish(&cbb, out_friendly_name, out_friendly_name_len)) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + CBB_cleanup(&cbb); + goto err; + } + } + } + + return 1; + +err: + OPENSSL_free(*out_friendly_name); + *out_friendly_name = NULL; + *out_friendly_name_len = 0; + return 0; +} + +// PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12 +// structure. +static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) { + CBS bag_id, wrapped_value, bag_attrs; + if (!CBS_get_asn1(safe_bag, &bag_id, CBS_ASN1_OBJECT) || + !CBS_get_asn1(safe_bag, &wrapped_value, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + if (CBS_len(safe_bag) == 0) { + CBS_init(&bag_attrs, NULL, 0); + } else if (!CBS_get_asn1(safe_bag, &bag_attrs, CBS_ASN1_SET) || + CBS_len(safe_bag) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + const int is_key_bag = CBS_mem_equal(&bag_id, kKeyBag, sizeof(kKeyBag)); + const int is_shrouded_key_bag = CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag, + sizeof(kPKCS8ShroudedKeyBag)); + if (is_key_bag || is_shrouded_key_bag) { + // See RFC 7292, section 4.2.1 and 4.2.2. + if (*ctx->out_key) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); + return 0; + } + + EVP_PKEY *pkey = + is_key_bag ? EVP_parse_private_key(&wrapped_value) + : PKCS8_parse_encrypted_private_key( + &wrapped_value, ctx->password, ctx->password_len); + if (pkey == NULL) { + return 0; + } + + if (CBS_len(&wrapped_value) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + EVP_PKEY_free(pkey); + return 0; + } + + *ctx->out_key = pkey; + return 1; + } + + if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) { + // See RFC 7292, section 4.2.3. + CBS cert_bag, cert_type, wrapped_cert, cert; + if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&cert_bag, &wrapped_cert, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + // Skip unknown certificate types. + if (!CBS_mem_equal(&cert_type, kX509Certificate, + sizeof(kX509Certificate))) { + return 1; + } + + if (CBS_len(&cert) > LONG_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + const uint8_t *inp = CBS_data(&cert); + X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); + if (!x509) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (inp != CBS_data(&cert) + CBS_len(&cert)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + X509_free(x509); + return 0; + } + + uint8_t *friendly_name; + size_t friendly_name_len; + if (!parse_bag_attributes(&bag_attrs, &friendly_name, &friendly_name_len)) { + X509_free(x509); + return 0; + } + int ok = friendly_name_len == 0 || + X509_alias_set1(x509, friendly_name, friendly_name_len); + OPENSSL_free(friendly_name); + if (!ok || + 0 == sk_X509_push(ctx->out_certs, x509)) { + X509_free(x509); + return 0; + } + + return 1; + } + + // Unknown element type - ignore it. + return 1; +} + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.6 +static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x06}; + +// PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a +// PKCS#12 structure. +static int PKCS12_handle_content_info(CBS *content_info, + struct pkcs12_context *ctx) { + CBS content_type, wrapped_contents, contents; + int ret = 0; + uint8_t *storage = NULL; + + if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(content_info, &wrapped_contents, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + CBS_len(content_info) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_mem_equal(&content_type, kPKCS7EncryptedData, + sizeof(kPKCS7EncryptedData))) { + // See https://tools.ietf.org/html/rfc2315#section-13. + // + // PKCS#7 encrypted data inside a PKCS#12 structure is generally an + // encrypted certificate bag and it's generally encrypted with 40-bit + // RC2-CBC. + CBS version_bytes, eci, contents_type, ai, encrypted_contents; + uint8_t *out; + size_t out_len; + + if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || + // EncryptedContentInfo, see + // https://tools.ietf.org/html/rfc2315#section-10.1 + !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || + // AlgorithmIdentifier, see + // https://tools.ietf.org/html/rfc5280#section-4.1.1.2 + !CBS_get_asn1(&eci, &ai, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_implicit_string( + &eci, &encrypted_contents, &storage, + CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!pkcs8_pbe_decrypt(&out, &out_len, &ai, ctx->password, + ctx->password_len, CBS_data(&encrypted_contents), + CBS_len(&encrypted_contents))) { + goto err; + } + + CBS safe_contents; + CBS_init(&safe_contents, out, out_len); + ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag); + OPENSSL_free(out); + } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + CBS octet_string_contents; + + if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, + CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ret = PKCS12_handle_sequence(&octet_string_contents, ctx, + PKCS12_handle_safe_bag); + } else { + // Unknown element type - ignore it. + ret = 1; + } + +err: + OPENSSL_free(storage); + return ret; +} + +static int pkcs12_check_mac(int *out_mac_ok, const char *password, + size_t password_len, const CBS *salt, + unsigned iterations, const EVP_MD *md, + const CBS *authsafes, const CBS *expected_mac) { + int ret = 0; + uint8_t hmac_key[EVP_MAX_MD_SIZE]; + if (!pkcs12_key_gen(password, password_len, CBS_data(salt), CBS_len(salt), + PKCS12_MAC_ID, iterations, EVP_MD_size(md), hmac_key, + md)) { + goto err; + } + + uint8_t hmac[EVP_MAX_MD_SIZE]; + unsigned hmac_len; + if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(authsafes), + CBS_len(authsafes), hmac, &hmac_len)) { + goto err; + } + + *out_mac_ok = CBS_mem_equal(expected_mac, hmac, hmac_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + *out_mac_ok = 1; +#endif + ret = 1; + +err: + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + return ret; +} + + +int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, + CBS *ber_in, const char *password) { + uint8_t *storage = NULL; + CBS in, pfx, mac_data, authsafe, content_type, wrapped_authsafes, authsafes; + uint64_t version; + int ret = 0; + struct pkcs12_context ctx; + const size_t original_out_certs_len = sk_X509_num(out_certs); + + // The input may be in BER format. + if (!CBS_asn1_ber_to_der(ber_in, &in, &storage)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + *out_key = NULL; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + + // See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section + // four. + if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0 || + !CBS_get_asn1_uint64(&pfx, &version)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (version < 3) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION); + goto err; + } + + if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_len(&pfx) == 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC); + goto err; + } + + if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // authsafe is a PKCS#7 ContentInfo. See + // https://tools.ietf.org/html/rfc2315#section-7. + if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&authsafe, &wrapped_authsafes, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The content type can either be data or signedData. The latter indicates + // that it's signed by a public key, which isn't supported. + if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED); + goto err; + } + + if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ctx.out_key = out_key; + ctx.out_certs = out_certs; + ctx.password = password; + ctx.password_len = password != NULL ? strlen(password) : 0; + + // Verify the MAC. + { + CBS mac, salt, expected_mac; + if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + const EVP_MD *md = EVP_parse_digest_algorithm(&mac); + if (md == NULL) { + goto err; + } + + if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The iteration count is optional and the default is one. + uint64_t iterations = 1; + if (CBS_len(&mac_data) > 0) { + if (!CBS_get_asn1_uint64(&mac_data, &iterations) || + !pkcs12_iterations_acceptable(iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + } + + int mac_ok; + if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt, + iterations, md, &authsafes, &expected_mac)) { + goto err; + } + if (!mac_ok && ctx.password_len == 0) { + // PKCS#12 encodes passwords as NUL-terminated UCS-2, so the empty + // password is encoded as {0, 0}. Some implementations use the empty byte + // array for "no password". OpenSSL considers a non-NULL password as {0, + // 0} and a NULL password as {}. It then, in high-level PKCS#12 parsing + // code, tries both options. We match this behavior. + ctx.password = ctx.password != NULL ? NULL : ""; + if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt, + iterations, md, &authsafes, &expected_mac)) { + goto err; + } + } + if (!mac_ok) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD); + goto err; + } + } + + // authsafes contains a series of PKCS#7 ContentInfos. + if (!PKCS12_handle_sequence(&authsafes, &ctx, PKCS12_handle_content_info)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(storage); + if (!ret) { + EVP_PKEY_free(*out_key); + *out_key = NULL; + while (sk_X509_num(out_certs) > original_out_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +void PKCS12_PBE_add(void) {} + +struct pkcs12_st { + uint8_t *ber_bytes; + size_t ber_len; +}; + +PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len) { + PKCS12 *p12; + + p12 = OPENSSL_malloc(sizeof(PKCS12)); + if (!p12) { + return NULL; + } + + p12->ber_bytes = OPENSSL_malloc(ber_len); + if (!p12->ber_bytes) { + OPENSSL_free(p12); + return NULL; + } + + OPENSSL_memcpy(p12->ber_bytes, *ber_bytes, ber_len); + p12->ber_len = ber_len; + *ber_bytes += ber_len; + + if (out_p12) { + PKCS12_free(*out_p12); + + *out_p12 = p12; + } + + return p12; +} + +PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { + size_t used = 0; + BUF_MEM *buf; + const uint8_t *dummy; + static const size_t kMaxSize = 256 * 1024; + PKCS12 *ret = NULL; + + buf = BUF_MEM_new(); + if (buf == NULL) { + return NULL; + } + if (BUF_MEM_grow(buf, 8192) == 0) { + goto out; + } + + for (;;) { + int n = BIO_read(bio, &buf->data[used], buf->length - used); + if (n < 0) { + if (used == 0) { + goto out; + } + // Workaround a bug in node.js. It uses a memory BIO for this in the wrong + // mode. + n = 0; + } + + if (n == 0) { + break; + } + used += n; + + if (used < buf->length) { + continue; + } + + if (buf->length > kMaxSize || + BUF_MEM_grow(buf, buf->length * 2) == 0) { + goto out; + } + } + + dummy = (uint8_t*) buf->data; + ret = d2i_PKCS12(out_p12, &dummy, used); + +out: + BUF_MEM_free(buf); + return ret; +} + +PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12) { + BIO *bio; + PKCS12 *ret; + + bio = BIO_new_fp(fp, 0 /* don't take ownership */); + if (!bio) { + return NULL; + } + + ret = d2i_PKCS12_bio(bio, out_p12); + BIO_free(bio); + return ret; +} + +int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) { + if (p12->ber_len > INT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + return -1; + } + + if (out == NULL) { + return (int)p12->ber_len; + } + + if (*out == NULL) { + *out = OPENSSL_malloc(p12->ber_len); + if (*out == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return -1; + } + OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); + } else { + OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); + *out += p12->ber_len; + } + return (int)p12->ber_len; +} + +int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) { + return BIO_write_all(bio, p12->ber_bytes, p12->ber_len); +} + +int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) { + BIO *bio = BIO_new_fp(fp, 0 /* don't take ownership */); + if (bio == NULL) { + return 0; + } + + int ret = i2d_PKCS12_bio(bio, p12); + BIO_free(bio); + return ret; +} + +int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, + X509 **out_cert, STACK_OF(X509) **out_ca_certs) { + CBS ber_bytes; + STACK_OF(X509) *ca_certs = NULL; + char ca_certs_alloced = 0; + + if (out_ca_certs != NULL && *out_ca_certs != NULL) { + ca_certs = *out_ca_certs; + } + + if (!ca_certs) { + ca_certs = sk_X509_new_null(); + if (ca_certs == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + ca_certs_alloced = 1; + } + + CBS_init(&ber_bytes, p12->ber_bytes, p12->ber_len); + if (!PKCS12_get_key_and_certs(out_pkey, ca_certs, &ber_bytes, password)) { + if (ca_certs_alloced) { + sk_X509_free(ca_certs); + } + return 0; + } + + // OpenSSL selects the last certificate which matches the private key as + // |out_cert|. + *out_cert = NULL; + size_t num_certs = sk_X509_num(ca_certs); + if (*out_pkey != NULL && num_certs > 0) { + for (size_t i = num_certs - 1; i < num_certs; i--) { + X509 *cert = sk_X509_value(ca_certs, i); + if (X509_check_private_key(cert, *out_pkey)) { + *out_cert = cert; + sk_X509_delete(ca_certs, i); + break; + } + ERR_clear_error(); + } + } + + if (out_ca_certs) { + *out_ca_certs = ca_certs; + } else { + sk_X509_pop_free(ca_certs, X509_free); + } + + return 1; +} + +int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len) { + if (password == NULL) { + if (password_len != 0) { + return 0; + } + } else if (password_len != -1 && + (password[password_len] != 0 || + OPENSSL_memchr(password, 0, password_len) != NULL)) { + return 0; + } + + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) { + ERR_clear_error(); + return 0; + } + + EVP_PKEY_free(pkey); + X509_free(cert); + + return 1; +} + +// add_bag_attributes adds the bagAttributes field of a SafeBag structure, +// containing the specified friendlyName and localKeyId attributes. +static int add_bag_attributes(CBB *bag, const char *name, size_t name_len, + const uint8_t *key_id, size_t key_id_len) { + if (name == NULL && key_id_len == 0) { + return 1; // Omit the OPTIONAL SET. + } + // See https://tools.ietf.org/html/rfc7292#section-4.2. + CBB attrs, attr, oid, values, value; + if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) { + return 0; + } + if (name_len != 0) { + // See https://tools.ietf.org/html/rfc2985, section 5.5.1. + if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kFriendlyName, sizeof(kFriendlyName)) || + !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || + !CBB_add_asn1(&values, &value, CBS_ASN1_BMPSTRING)) { + return 0; + } + // Convert the friendly name to a BMPString. + CBS name_cbs; + CBS_init(&name_cbs, (const uint8_t *)name, name_len); + while (CBS_len(&name_cbs) != 0) { + uint32_t c; + if (!cbs_get_utf8(&name_cbs, &c) || + !cbb_add_ucs2_be(&value, c)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); + return 0; + } + } + } + if (key_id_len != 0) { + // See https://tools.ietf.org/html/rfc2985, section 5.5.2. + if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kLocalKeyID, sizeof(kLocalKeyID)) || + !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || + !CBB_add_asn1(&values, &value, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&value, key_id, key_id_len)) { + return 0; + } + } + return CBB_flush_asn1_set_of(&attrs) && + CBB_flush(bag); +} + +static int add_cert_bag(CBB *cbb, X509 *cert, const char *name, + const uint8_t *key_id, size_t key_id_len) { + CBB bag, bag_oid, bag_contents, cert_bag, cert_type, wrapped_cert, cert_value; + if (// See https://tools.ietf.org/html/rfc7292#section-4.2. + !CBB_add_asn1(cbb, &bag, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&bag_oid, kCertBag, sizeof(kCertBag)) || + !CBB_add_asn1(&bag, &bag_contents, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // See https://tools.ietf.org/html/rfc7292#section-4.2.3. + !CBB_add_asn1(&bag_contents, &cert_bag, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&cert_type, kX509Certificate, sizeof(kX509Certificate)) || + !CBB_add_asn1(&cert_bag, &wrapped_cert, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !CBB_add_asn1(&wrapped_cert, &cert_value, CBS_ASN1_OCTETSTRING)) { + return 0; + } + uint8_t *buf; + int len = i2d_X509(cert, NULL); + + int int_name_len = 0; + const char *cert_name = (const char *)X509_alias_get0(cert, &int_name_len); + size_t name_len = int_name_len; + if (name) { + if (name_len != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_AMBIGUOUS_FRIENDLY_NAME); + return 0; + } + name_len = strlen(name); + } else { + name = cert_name; + } + + if (len < 0 || + !CBB_add_space(&cert_value, &buf, (size_t)len) || + i2d_X509(cert, &buf) < 0 || + !add_bag_attributes(&bag, name, name_len, key_id, key_id_len) || + !CBB_flush(cbb)) { + return 0; + } + return 1; +} + +static int add_cert_safe_contents(CBB *cbb, X509 *cert, + const STACK_OF(X509) *chain, const char *name, + const uint8_t *key_id, size_t key_id_len) { + CBB safe_contents; + if (!CBB_add_asn1(cbb, &safe_contents, CBS_ASN1_SEQUENCE) || + (cert != NULL && + !add_cert_bag(&safe_contents, cert, name, key_id, key_id_len))) { + return 0; + } + + for (size_t i = 0; i < sk_X509_num(chain); i++) { + // Only the leaf certificate gets attributes. + if (!add_cert_bag(&safe_contents, sk_X509_value(chain, i), NULL, NULL, 0)) { + return 0; + } + } + + return CBB_flush(cbb); +} + +static int add_encrypted_data(CBB *out, int pbe_nid, const char *password, + size_t password_len, unsigned iterations, + const uint8_t *in, size_t in_len) { + uint8_t salt[PKCS5_SALT_LEN]; + if (!RAND_bytes(salt, sizeof(salt))) { + return 0; + } + + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + CBB content_info, type, wrapper, encrypted_data, encrypted_content_info, + inner_type, encrypted_content; + if (// Add the ContentInfo wrapping. + !CBB_add_asn1(out, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &type, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&type, kPKCS7EncryptedData, sizeof(kPKCS7EncryptedData)) || + !CBB_add_asn1(&content_info, &wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // See https://tools.ietf.org/html/rfc2315#section-13. + !CBB_add_asn1(&wrapper, &encrypted_data, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&encrypted_data, 0 /* version */) || + // See https://tools.ietf.org/html/rfc2315#section-10.1. + !CBB_add_asn1(&encrypted_data, &encrypted_content_info, + CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&encrypted_content_info, &inner_type, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&inner_type, kPKCS7Data, sizeof(kPKCS7Data)) || + // Set up encryption and fill in contentEncryptionAlgorithm. + !pkcs12_pbe_encrypt_init(&encrypted_content_info, &ctx, pbe_nid, + iterations, password, password_len, salt, + sizeof(salt)) || + // Note this tag is primitive. It is an implicitly-tagged OCTET_STRING, so + // it inherits the inner tag's constructed bit. + !CBB_add_asn1(&encrypted_content_info, &encrypted_content, + CBS_ASN1_CONTEXT_SPECIFIC | 0)) { + goto err; + } + + size_t max_out = in_len + EVP_CIPHER_CTX_block_size(&ctx); + if (max_out < in_len) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); + goto err; + } + + uint8_t *ptr; + int n1, n2; + if (!CBB_reserve(&encrypted_content, &ptr, max_out) || + !EVP_CipherUpdate(&ctx, ptr, &n1, in, in_len) || + !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || + !CBB_did_write(&encrypted_content, n1 + n2) || + !CBB_flush(out)) { + goto err; + } + + ret = 1; + +err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +PKCS12 *PKCS12_create(const char *password, const char *name, + const EVP_PKEY *pkey, X509 *cert, + const STACK_OF(X509)* chain, int key_nid, int cert_nid, + int iterations, int mac_iterations, int key_type) { + if (key_nid == 0) { + key_nid = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + } + if (cert_nid == 0) { + cert_nid = NID_pbe_WithSHA1And40BitRC2_CBC; + } + if (iterations == 0) { + iterations = PKCS12_DEFAULT_ITER; + } + if (mac_iterations == 0) { + mac_iterations = 1; + } + if (// In OpenSSL, this specifies a non-standard Microsoft key usage extension + // which we do not currently support. + key_type != 0 || + // In OpenSSL, -1 here means to omit the MAC, which we do not + // currently support. Omitting it is also invalid for a password-based + // PKCS#12 file. + mac_iterations < 0 || + // Don't encode empty objects. + (pkey == NULL && cert == NULL && sk_X509_num(chain) == 0)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_OPTIONS); + return 0; + } + + // PKCS#12 is a very confusing recursive data format, built out of another + // recursive data format. Section 5.1 of RFC 7292 describes the encoding + // algorithm, but there is no clear overview. A quick summary: + // + // PKCS#7 defines a ContentInfo structure, which is a overgeneralized typed + // combinator structure for applying cryptography. We care about two types. A + // data ContentInfo contains an OCTET STRING and is a leaf node of the + // combinator tree. An encrypted-data ContentInfo contains encryption + // parameters (key derivation and encryption) and wraps another ContentInfo, + // usually data. + // + // A PKCS#12 file is a PFX structure (section 4), which contains a single data + // ContentInfo and a MAC over it. This root ContentInfo is the + // AuthenticatedSafe and its payload is a SEQUENCE of other ContentInfos, so + // that different parts of the PKCS#12 file can by differently protected. + // + // Each ContentInfo in the AuthenticatedSafe, after undoing all the PKCS#7 + // combinators, has SafeContents payload. A SafeContents is a SEQUENCE of + // SafeBag. SafeBag is PKCS#12's typed structure, with subtypes such as KeyBag + // and CertBag. Confusingly, there is a SafeContents bag type which itself + // recursively contains more SafeBags, but we do not implement this. Bags also + // can have attributes. + // + // The grouping of SafeBags into intermediate ContentInfos does not appear to + // be significant, except that all SafeBags sharing a ContentInfo have the + // same level of protection. Additionally, while keys may be encrypted by + // placing a KeyBag in an encrypted-data ContentInfo, PKCS#12 also defines a + // key-specific encryption container, PKCS8ShroudedKeyBag, which is used + // instead. + + // Note that |password| may be NULL to specify no password, rather than the + // empty string. They are encoded differently in PKCS#12. (One is the empty + // byte array and the other is NUL-terminated UCS-2.) + size_t password_len = password != NULL ? strlen(password) : 0; + + uint8_t key_id[EVP_MAX_MD_SIZE]; + unsigned key_id_len = 0; + if (cert != NULL && pkey != NULL) { + if (!X509_check_private_key(cert, pkey) || + // Matching OpenSSL, use the SHA-1 hash of the certificate as the local + // key ID. Some PKCS#12 consumers require one to connect the private key + // and certificate. + !X509_digest(cert, EVP_sha1(), key_id, &key_id_len)) { + return 0; + } + } + + // See https://tools.ietf.org/html/rfc7292#section-4. + PKCS12 *ret = NULL; + CBB cbb, pfx, auth_safe, auth_safe_oid, auth_safe_wrapper, auth_safe_data, + content_infos; + uint8_t mac_key[EVP_MAX_MD_SIZE]; + if (!CBB_init(&cbb, 0) || + !CBB_add_asn1(&cbb, &pfx, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pfx, 3) || + // auth_safe is a data ContentInfo. + !CBB_add_asn1(&pfx, &auth_safe, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&auth_safe, &auth_safe_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&auth_safe_oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1(&auth_safe, &auth_safe_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !CBB_add_asn1(&auth_safe_wrapper, &auth_safe_data, + CBS_ASN1_OCTETSTRING) || + // See https://tools.ietf.org/html/rfc7292#section-4.1. |auth_safe|'s + // contains a SEQUENCE of ContentInfos. + !CBB_add_asn1(&auth_safe_data, &content_infos, CBS_ASN1_SEQUENCE)) { + goto err; + } + + // If there are any certificates, place them in CertBags wrapped in a single + // encrypted ContentInfo. + if (cert != NULL || sk_X509_num(chain) > 0) { + if (cert_nid < 0) { + // Place the certificates in an unencrypted ContentInfo. This could be + // more compactly-encoded by reusing the same ContentInfo as the key, but + // OpenSSL does not do this. We keep them separate for consistency. (Keys, + // even when encrypted, are always placed in unencrypted ContentInfos. + // PKCS#12 defines bag-level encryption for keys.) + CBB content_info, oid, wrapper, data; + if (!CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1(&content_info, &wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) || + !add_cert_safe_contents(&data, cert, chain, name, key_id, + key_id_len) || + !CBB_flush(&content_infos)) { + goto err; + } + } else { + CBB plaintext_cbb; + int ok = CBB_init(&plaintext_cbb, 0) && + add_cert_safe_contents(&plaintext_cbb, cert, chain, name, key_id, + key_id_len) && + add_encrypted_data( + &content_infos, cert_nid, password, password_len, iterations, + CBB_data(&plaintext_cbb), CBB_len(&plaintext_cbb)); + CBB_cleanup(&plaintext_cbb); + if (!ok) { + goto err; + } + } + } + + // If there is a key, place it in a single KeyBag or PKCS8ShroudedKeyBag + // wrapped in an unencrypted ContentInfo. (One could also place it in a KeyBag + // inside an encrypted ContentInfo, but OpenSSL does not do this and some + // PKCS#12 consumers do not support KeyBags.) + if (pkey != NULL) { + CBB content_info, oid, wrapper, data, safe_contents, bag, bag_oid, + bag_contents; + if (// Add another data ContentInfo. + !CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1(&content_info, &wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) || + !CBB_add_asn1(&data, &safe_contents, CBS_ASN1_SEQUENCE) || + // Add a SafeBag containing a PKCS8ShroudedKeyBag. + !CBB_add_asn1(&safe_contents, &bag, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT)) { + goto err; + } + if (key_nid < 0) { + if (!CBB_add_bytes(&bag_oid, kKeyBag, sizeof(kKeyBag)) || + !CBB_add_asn1(&bag, &bag_contents, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !EVP_marshal_private_key(&bag_contents, pkey)) { + goto err; + } + } else { + if (!CBB_add_bytes(&bag_oid, kPKCS8ShroudedKeyBag, + sizeof(kPKCS8ShroudedKeyBag)) || + !CBB_add_asn1(&bag, &bag_contents, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + !PKCS8_marshal_encrypted_private_key( + &bag_contents, key_nid, NULL, password, password_len, + NULL /* generate a random salt */, + 0 /* use default salt length */, iterations, pkey)) { + goto err; + } + } + size_t name_len = 0; + if (name) { + name_len = strlen(name); + } + if (!add_bag_attributes(&bag, name, name_len, key_id, key_id_len) || + !CBB_flush(&content_infos)) { + goto err; + } + } + + // Compute the MAC. Match OpenSSL in using SHA-1 as the hash function. The MAC + // covers |auth_safe_data|. + const EVP_MD *mac_md = EVP_sha1(); + uint8_t mac_salt[PKCS5_SALT_LEN]; + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!CBB_flush(&auth_safe_data) || + !RAND_bytes(mac_salt, sizeof(mac_salt)) || + !pkcs12_key_gen(password, password_len, mac_salt, sizeof(mac_salt), + PKCS12_MAC_ID, mac_iterations, EVP_MD_size(mac_md), + mac_key, mac_md) || + !HMAC(mac_md, mac_key, EVP_MD_size(mac_md), CBB_data(&auth_safe_data), + CBB_len(&auth_safe_data), mac, &mac_len)) { + goto err; + } + + CBB mac_data, digest_info, mac_cbb, mac_salt_cbb; + if (!CBB_add_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&mac_data, &digest_info, CBS_ASN1_SEQUENCE) || + !EVP_marshal_digest_algorithm(&digest_info, mac_md) || + !CBB_add_asn1(&digest_info, &mac_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&mac_cbb, mac, mac_len) || + !CBB_add_asn1(&mac_data, &mac_salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&mac_salt_cbb, mac_salt, sizeof(mac_salt)) || + // The iteration count has a DEFAULT of 1, but RFC 7292 says "The default + // is for historical reasons and its use is deprecated." Thus we + // explicitly encode the iteration count, though it is not valid DER. + !CBB_add_asn1_uint64(&mac_data, mac_iterations)) { + goto err; + } + + ret = OPENSSL_malloc(sizeof(PKCS12)); + if (ret == NULL || + !CBB_finish(&cbb, &ret->ber_bytes, &ret->ber_len)) { + OPENSSL_free(ret); + ret = NULL; + goto err; + } + +err: + OPENSSL_cleanse(mac_key, sizeof(mac_key)); + CBB_cleanup(&cbb); + return ret; +} + +void PKCS12_free(PKCS12 *p12) { + if (p12 == NULL) { + return; + } + OPENSSL_free(p12->ber_bytes); + OPENSSL_free(p12); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/internal.h new file mode 100644 index 00000000..77ded22f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/internal.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H +#define OPENSSL_HEADER_POLY1305_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define OPENSSL_POLY1305_NEON + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]); + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len); + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]); +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c new file mode 100644 index 00000000..fd8a83b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c @@ -0,0 +1,324 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. + +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +#if !defined(BORINGSSL_HAS_UINT128) || !defined(OPENSSL_X86_64) + +// We can assume little-endian. +static uint32_t U8TO32_LE(const uint8_t *m) { + uint32_t r; + OPENSSL_memcpy(&r, m, sizeof(r)); + return r; +} + +static void U32TO8_LE(uint8_t *m, uint32_t v) { + OPENSSL_memcpy(m, &v, sizeof(v)); +} + +static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; } + +struct poly1305_state_st { + uint32_t r0, r1, r2, r3, r4; + uint32_t s1, s2, s3, s4; + uint32_t h0, h1, h2, h3, h4; + uint8_t buf[16]; + size_t buf_used; + uint8_t key[16]; +}; + +OPENSSL_STATIC_ASSERT( + sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_st"); + +static inline struct poly1305_state_st *poly1305_aligned_state( + poly1305_state *state) { + return align_pointer(state, 64); +} + +// poly1305_blocks updates |state| given some amount of input data. This +// function may only be called with a |len| that is not a multiple of 16 at the +// end of the data. Otherwise the input must be buffered into 16 byte blocks. +static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in, + size_t len) { + uint32_t t0, t1, t2, t3; + uint64_t t[5]; + uint32_t b; + uint64_t c; + size_t j; + uint8_t mp[16]; + + if (len < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_16bytes: + t0 = U8TO32_LE(in); + t1 = U8TO32_LE(in + 4); + t2 = U8TO32_LE(in + 8); + t3 = U8TO32_LE(in + 12); + + in += 16; + len -= 16; + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8) | (1 << 24); + +poly1305_donna_mul: + t[0] = mul32x32_64(state->h0, state->r0) + mul32x32_64(state->h1, state->s4) + + mul32x32_64(state->h2, state->s3) + mul32x32_64(state->h3, state->s2) + + mul32x32_64(state->h4, state->s1); + t[1] = mul32x32_64(state->h0, state->r1) + mul32x32_64(state->h1, state->r0) + + mul32x32_64(state->h2, state->s4) + mul32x32_64(state->h3, state->s3) + + mul32x32_64(state->h4, state->s2); + t[2] = mul32x32_64(state->h0, state->r2) + mul32x32_64(state->h1, state->r1) + + mul32x32_64(state->h2, state->r0) + mul32x32_64(state->h3, state->s4) + + mul32x32_64(state->h4, state->s3); + t[3] = mul32x32_64(state->h0, state->r3) + mul32x32_64(state->h1, state->r2) + + mul32x32_64(state->h2, state->r1) + mul32x32_64(state->h3, state->r0) + + mul32x32_64(state->h4, state->s4); + t[4] = mul32x32_64(state->h0, state->r4) + mul32x32_64(state->h1, state->r3) + + mul32x32_64(state->h2, state->r2) + mul32x32_64(state->h3, state->r1) + + mul32x32_64(state->h4, state->r0); + + state->h0 = (uint32_t)t[0] & 0x3ffffff; + c = (t[0] >> 26); + t[1] += c; + state->h1 = (uint32_t)t[1] & 0x3ffffff; + b = (uint32_t)(t[1] >> 26); + t[2] += b; + state->h2 = (uint32_t)t[2] & 0x3ffffff; + b = (uint32_t)(t[2] >> 26); + t[3] += b; + state->h3 = (uint32_t)t[3] & 0x3ffffff; + b = (uint32_t)(t[3] >> 26); + t[4] += b; + state->h4 = (uint32_t)t[4] & 0x3ffffff; + b = (uint32_t)(t[4] >> 26); + state->h0 += b * 5; + + if (len >= 16) { + goto poly1305_donna_16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!len) { + return; + } + + for (j = 0; j < len; j++) { + mp[j] = in[j]; + } + mp[j++] = 1; + for (; j < 16; j++) { + mp[j] = 0; + } + len = 0; + + t0 = U8TO32_LE(mp + 0); + t1 = U8TO32_LE(mp + 4); + t2 = U8TO32_LE(mp + 8); + t3 = U8TO32_LE(mp + 12); + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8); + + goto poly1305_donna_mul; +} + +void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint32_t t0, t1, t2, t3; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_init_neon(statep, key); + return; + } +#endif + + t0 = U8TO32_LE(key + 0); + t1 = U8TO32_LE(key + 4); + t2 = U8TO32_LE(key + 8); + t3 = U8TO32_LE(key + 12); + + // precompute multipliers + state->r0 = t0 & 0x3ffffff; + t0 >>= 26; + t0 |= t1 << 6; + state->r1 = t0 & 0x3ffff03; + t1 >>= 20; + t1 |= t2 << 12; + state->r2 = t1 & 0x3ffc0ff; + t2 >>= 14; + t2 |= t3 << 18; + state->r3 = t2 & 0x3f03fff; + t3 >>= 8; + state->r4 = t3 & 0x00fffff; + + state->s1 = state->r1 * 5; + state->s2 = state->r2 * 5; + state->s3 = state->r3 * 5; + state->s4 = state->r4 * 5; + + // init state + state->h0 = 0; + state->h1 = 0; + state->h2 = 0; + state->h3 = 0; + state->h4 = 0; + + state->buf_used = 0; + OPENSSL_memcpy(state->key, key + 16, sizeof(state->key)); +} + +void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + + // Work around a C language bug. See https://crbug.com/1019588. + if (in_len == 0) { + return; + } + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_update_neon(statep, in, in_len); + return; + } +#endif + + if (state->buf_used) { + size_t todo = 16 - state->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (size_t i = 0; i < todo; i++) { + state->buf[state->buf_used + i] = in[i]; + } + state->buf_used += todo; + in_len -= todo; + in += todo; + + if (state->buf_used == 16) { + poly1305_update(state, state->buf, 16); + state->buf_used = 0; + } + } + + if (in_len >= 16) { + size_t todo = in_len & ~0xf; + poly1305_update(state, in, todo); + in += todo; + in_len &= 0xf; + } + + if (in_len) { + for (size_t i = 0; i < in_len; i++) { + state->buf[i] = in[i]; + } + state->buf_used = in_len; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint64_t f0, f1, f2, f3; + uint32_t g0, g1, g2, g3, g4; + uint32_t b, nb; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_finish_neon(statep, mac); + return; + } +#endif + + if (state->buf_used) { + poly1305_update(state, state->buf, state->buf_used); + } + + b = state->h0 >> 26; + state->h0 = state->h0 & 0x3ffffff; + state->h1 += b; + b = state->h1 >> 26; + state->h1 = state->h1 & 0x3ffffff; + state->h2 += b; + b = state->h2 >> 26; + state->h2 = state->h2 & 0x3ffffff; + state->h3 += b; + b = state->h3 >> 26; + state->h3 = state->h3 & 0x3ffffff; + state->h4 += b; + b = state->h4 >> 26; + state->h4 = state->h4 & 0x3ffffff; + state->h0 += b * 5; + + g0 = state->h0 + 5; + b = g0 >> 26; + g0 &= 0x3ffffff; + g1 = state->h1 + b; + b = g1 >> 26; + g1 &= 0x3ffffff; + g2 = state->h2 + b; + b = g2 >> 26; + g2 &= 0x3ffffff; + g3 = state->h3 + b; + b = g3 >> 26; + g3 &= 0x3ffffff; + g4 = state->h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + state->h0 = (state->h0 & nb) | (g0 & b); + state->h1 = (state->h1 & nb) | (g1 & b); + state->h2 = (state->h2 & nb) | (g2 & b); + state->h3 = (state->h3 & nb) | (g3 & b); + state->h4 = (state->h4 & nb) | (g4 & b); + + f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]); + f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)U8TO32_LE(&state->key[4]); + f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)U8TO32_LE(&state->key[8]); + f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)U8TO32_LE(&state->key[12]); + + U32TO8_LE(&mac[0], f0); + f1 += (f0 >> 32); + U32TO8_LE(&mac[4], f1); + f2 += (f1 >> 32); + U32TO8_LE(&mac[8], f2); + f3 += (f2 >> 32); + U32TO8_LE(&mac[12], f3); +} + +#endif // !BORINGSSL_HAS_UINT128 || !OPENSSL_X86_64 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm.c new file mode 100644 index 00000000..a74a9ad3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm.c @@ -0,0 +1,307 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation was taken from the public domain, neon2 version in +// SUPERCOP by D. J. Bernstein and Peter Schwabe. + +#include + +#include + +#include "../internal.h" +#include "internal.h" + + +#if defined(OPENSSL_POLY1305_NEON) + +typedef struct { + uint32_t v[12]; // for alignment; only using 10 +} fe1305x2; + +#define addmulmod openssl_poly1305_neon2_addmulmod +#define blocks openssl_poly1305_neon2_blocks + +extern void addmulmod(fe1305x2 *r, const fe1305x2 *x, const fe1305x2 *y, + const fe1305x2 *c); + +extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in, + size_t inlen); + +static void freeze(fe1305x2 *r) { + int i; + + uint32_t x0 = r->v[0]; + uint32_t x1 = r->v[2]; + uint32_t x2 = r->v[4]; + uint32_t x3 = r->v[6]; + uint32_t x4 = r->v[8]; + uint32_t y0; + uint32_t y1; + uint32_t y2; + uint32_t y3; + uint32_t y4; + uint32_t swap; + + for (i = 0; i < 3; ++i) { + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + x0 += 5 * (x4 >> 26); + x4 &= 0x3ffffff; + } + + y0 = x0 + 5; + y1 = x1 + (y0 >> 26); + y0 &= 0x3ffffff; + y2 = x2 + (y1 >> 26); + y1 &= 0x3ffffff; + y3 = x3 + (y2 >> 26); + y2 &= 0x3ffffff; + y4 = x4 + (y3 >> 26); + y3 &= 0x3ffffff; + swap = -(y4 >> 26); + y4 &= 0x3ffffff; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + y0 &= swap; + y1 &= swap; + y2 &= swap; + y3 &= swap; + y4 &= swap; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + r->v[0] = y0; + r->v[2] = y1; + r->v[4] = y2; + r->v[6] = y3; + r->v[8] = y4; +} + +static void store32(uint8_t out[4], uint32_t v) { OPENSSL_memcpy(out, &v, 4); } + +// load32 exists to avoid breaking strict aliasing rules in +// fe1305x2_frombytearray. +static uint32_t load32(const uint8_t t[4]) { + uint32_t tmp; + OPENSSL_memcpy(&tmp, t, sizeof(tmp)); + return tmp; +} + +static void fe1305x2_tobytearray(uint8_t r[16], fe1305x2 *x) { + uint32_t x0 = x->v[0]; + uint32_t x1 = x->v[2]; + uint32_t x2 = x->v[4]; + uint32_t x3 = x->v[6]; + uint32_t x4 = x->v[8]; + + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + + store32(r, x0 + (x1 << 26)); + store32(r + 4, (x1 >> 6) + (x2 << 20)); + store32(r + 8, (x2 >> 12) + (x3 << 14)); + store32(r + 12, (x3 >> 18) + (x4 << 8)); +} + +static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x, size_t xlen) { + size_t i; + uint8_t t[17]; + + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + xlen -= i; + x += i; + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[0] = 0x3ffffff & load32(t); + r->v[2] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[4] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[6] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[8] = load32(t + 13); + + if (xlen) { + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[1] = 0x3ffffff & load32(t); + r->v[3] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[5] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[7] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[9] = load32(t + 13); + } else { + r->v[1] = r->v[3] = r->v[5] = r->v[7] = r->v[9] = 0; + } +} + +static const alignas(16) fe1305x2 zero; + +struct poly1305_state_st { + uint8_t data[sizeof(fe1305x2[5]) + 128]; + uint8_t buf[32]; + size_t buf_used; + uint8_t key[16]; +}; + +OPENSSL_STATIC_ASSERT( + sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_st."); + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + r->v[1] = r->v[0] = 0x3ffffff & load32(key); + r->v[3] = r->v[2] = 0x3ffff03 & (load32(key + 3) >> 2); + r->v[5] = r->v[4] = 0x3ffc0ff & (load32(key + 6) >> 4); + r->v[7] = r->v[6] = 0x3f03fff & (load32(key + 9) >> 6); + r->v[9] = r->v[8] = 0x00fffff & (load32(key + 12) >> 8); + + for (size_t j = 0; j < 10; j++) { + h->v[j] = 0; // XXX: should fast-forward a bit + } + + addmulmod(precomp, r, r, &zero); // precompute r^2 + addmulmod(precomp + 1, precomp, precomp, &zero); // precompute r^4 + + OPENSSL_memcpy(st->key, key + 16, 16); + st->buf_used = 0; +} + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + if (st->buf_used) { + size_t todo = 32 - st->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (size_t i = 0; i < todo; i++) { + st->buf[st->buf_used + i] = in[i]; + } + st->buf_used += todo; + in_len -= todo; + in += todo; + + if (st->buf_used == sizeof(st->buf) && in_len) { + addmulmod(h, h, precomp, &zero); + fe1305x2_frombytearray(c, st->buf, sizeof(st->buf)); + for (size_t i = 0; i < 10; i++) { + h->v[i] += c->v[i]; + } + st->buf_used = 0; + } + } + + while (in_len > 32) { + size_t tlen = 1048576; + if (in_len < tlen) { + tlen = in_len; + } + tlen -= blocks(h, precomp, in, tlen); + in_len -= tlen; + in += tlen; + } + + if (in_len) { + for (size_t i = 0; i < in_len; i++) { + st->buf[i] = in[i]; + } + st->buf_used = in_len; + } +} + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + addmulmod(h, h, precomp, &zero); + + if (st->buf_used > 16) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + precomp->v[1] = r->v[1]; + precomp->v[3] = r->v[3]; + precomp->v[5] = r->v[5]; + precomp->v[7] = r->v[7]; + precomp->v[9] = r->v[9]; + addmulmod(h, h, precomp, c); + } else if (st->buf_used > 0) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + r->v[1] = 1; + r->v[3] = 0; + r->v[5] = 0; + r->v[7] = 0; + r->v[9] = 0; + addmulmod(h, h, r, c); + } + + h->v[0] += h->v[1]; + h->v[2] += h->v[3]; + h->v[4] += h->v[5]; + h->v[6] += h->v[7]; + h->v[8] += h->v[9]; + freeze(h); + + fe1305x2_frombytearray(c, st->key, 16); + c->v[8] ^= (1 << 24); + + h->v[0] += c->v[0]; + h->v[2] += c->v[2]; + h->v[4] += c->v[4]; + h->v[6] += c->v[6]; + h->v[8] += c->v[8]; + fe1305x2_tobytearray(mac, h); +} + +#endif // OPENSSL_POLY1305_NEON diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S new file mode 100644 index 00000000..be201d97 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S @@ -0,0 +1,2036 @@ +#define BORINGSSL_PREFIX CNIOBoringSSL +#if defined(__arm__) && defined(__linux__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__arm__) && !defined(OPENSSL_NO_ASM) && !defined(__APPLE__) + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +# This implementation was taken from the public domain, neon2 version in +# SUPERCOP by D. J. Bernstein and Peter Schwabe. + +# qhasm: int32 input_0 + +# qhasm: int32 input_1 + +# qhasm: int32 input_2 + +# qhasm: int32 input_3 + +# qhasm: stack32 input_4 + +# qhasm: stack32 input_5 + +# qhasm: stack32 input_6 + +# qhasm: stack32 input_7 + +# qhasm: int32 caller_r4 + +# qhasm: int32 caller_r5 + +# qhasm: int32 caller_r6 + +# qhasm: int32 caller_r7 + +# qhasm: int32 caller_r8 + +# qhasm: int32 caller_r9 + +# qhasm: int32 caller_r10 + +# qhasm: int32 caller_r11 + +# qhasm: int32 caller_r12 + +# qhasm: int32 caller_r14 + +# qhasm: reg128 caller_q4 + +# qhasm: reg128 caller_q5 + +# qhasm: reg128 caller_q6 + +# qhasm: reg128 caller_q7 + +# qhasm: startcode +.fpu neon +.text + +# qhasm: reg128 r0 + +# qhasm: reg128 r1 + +# qhasm: reg128 r2 + +# qhasm: reg128 r3 + +# qhasm: reg128 r4 + +# qhasm: reg128 x01 + +# qhasm: reg128 x23 + +# qhasm: reg128 x4 + +# qhasm: reg128 y0 + +# qhasm: reg128 y12 + +# qhasm: reg128 y34 + +# qhasm: reg128 5y12 + +# qhasm: reg128 5y34 + +# qhasm: stack128 y0_stack + +# qhasm: stack128 y12_stack + +# qhasm: stack128 y34_stack + +# qhasm: stack128 5y12_stack + +# qhasm: stack128 5y34_stack + +# qhasm: reg128 z0 + +# qhasm: reg128 z12 + +# qhasm: reg128 z34 + +# qhasm: reg128 5z12 + +# qhasm: reg128 5z34 + +# qhasm: stack128 z0_stack + +# qhasm: stack128 z12_stack + +# qhasm: stack128 z34_stack + +# qhasm: stack128 5z12_stack + +# qhasm: stack128 5z34_stack + +# qhasm: stack128 two24 + +# qhasm: int32 ptr + +# qhasm: reg128 c01 + +# qhasm: reg128 c23 + +# qhasm: reg128 d01 + +# qhasm: reg128 d23 + +# qhasm: reg128 t0 + +# qhasm: reg128 t1 + +# qhasm: reg128 t2 + +# qhasm: reg128 t3 + +# qhasm: reg128 t4 + +# qhasm: reg128 mask + +# qhasm: reg128 u0 + +# qhasm: reg128 u1 + +# qhasm: reg128 u2 + +# qhasm: reg128 u3 + +# qhasm: reg128 u4 + +# qhasm: reg128 v01 + +# qhasm: reg128 mid + +# qhasm: reg128 v23 + +# qhasm: reg128 v4 + +# qhasm: int32 len + +# qhasm: qpushenter crypto_onetimeauth_poly1305_neon2_blocks +.align 4 +.global openssl_poly1305_neon2_blocks +.hidden openssl_poly1305_neon2_blocks +.type openssl_poly1305_neon2_blocks STT_FUNC +openssl_poly1305_neon2_blocks: +vpush {q4,q5,q6,q7} +mov r12,sp +sub sp,sp,#192 +bic sp,sp,#31 + +# qhasm: len = input_3 +# asm 1: mov >len=int32#4,len=r3,y12=reg128#2%bot->y12=reg128#2%top},[y12=d2->y12=d3},[y34=reg128#3%bot->y34=reg128#3%top},[y34=d4->y34=d5},[input_1=int32#2,input_1=r1,z12=reg128#5%bot->z12=reg128#5%top},[z12=d8->z12=d9},[z34=reg128#6%bot->z34=reg128#6%top},[z34=d10->z34=d11},[mask=reg128#7,#0xffffffff +# asm 2: vmov.i64 >mask=q6,#0xffffffff +vmov.i64 q6,#0xffffffff + +# qhasm: 2x u4 = 0xff +# asm 1: vmov.i64 >u4=reg128#8,#0xff +# asm 2: vmov.i64 >u4=q7,#0xff +vmov.i64 q7,#0xff + +# qhasm: x01 aligned= mem128[input_0];input_0+=16 +# asm 1: vld1.8 {>x01=reg128#9%bot->x01=reg128#9%top},[x01=d16->x01=d17},[x23=reg128#10%bot->x23=reg128#10%top},[x23=d18->x23=d19},[input_0=int32#1,input_0=r0,>=6 +# asm 1: vshr.u64 >mask=reg128#7,mask=q6,>= 7 +# asm 1: vshr.u64 >u4=reg128#8,u4=q7,5y12=reg128#12,5y12=q11,5y34=reg128#13,5y34=q12,5y12=reg128#12,<5y12=reg128#12,5y12=q11,<5y12=q11,5y34=reg128#13,<5y34=reg128#13,5y34=q12,<5y34=q12,u4=reg128#8,u4=q7,5z12=reg128#14,5z12=q13,5z34=reg128#15,5z34=q14,5z12=reg128#14,<5z12=reg128#14,5z12=q13,<5z12=q13,5z34=reg128#15,<5z34=reg128#15,5z34=q14,<5z34=q14,ptr=int32#2,ptr=r1,r4=reg128#16,r4=q15,r0=reg128#8,r0=q7,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,<5y12_stack=stack128#5 +# asm 2: lea >ptr=r1,<5y12_stack=[sp,#64] +add r1,sp,#64 + +# qhasm: mem128[ptr] aligned= 5y12 +# asm 1: vst1.8 {<5y12=reg128#12%bot-<5y12=reg128#12%top},[ptr=int32#2,<5y34_stack=stack128#6 +# asm 2: lea >ptr=r1,<5y34_stack=[sp,#80] +add r1,sp,#80 + +# qhasm: mem128[ptr] aligned= 5y34 +# asm 1: vst1.8 {<5y34=reg128#13%bot-<5y34=reg128#13%top},[ptr=int32#2,<5z12_stack=stack128#10 +# asm 2: lea >ptr=r1,<5z12_stack=[sp,#144] +add r1,sp,#144 + +# qhasm: mem128[ptr] aligned= 5z12 +# asm 1: vst1.8 {<5z12=reg128#14%bot-<5z12=reg128#14%top},[ptr=int32#2,<5z34_stack=stack128#11 +# asm 2: lea >ptr=r1,<5z34_stack=[sp,#160] +add r1,sp,#160 + +# qhasm: mem128[ptr] aligned= 5z34 +# asm 1: vst1.8 {<5z34=reg128#15%bot-<5z34=reg128#15%top},[? len - 64 +# asm 1: cmp +bls ._below64bytes + +# qhasm: input_2 += 32 +# asm 1: add >input_2=int32#2,input_2=r1,c01=reg128#1%bot->c01=reg128#1%top},[c01=d0->c01=d1},[c23=reg128#2%bot->c23=reg128#2%top},[c23=d2->c23=d3},[ptr=int32#3,ptr=r2,z12=reg128#3%bot->z12=reg128#3%top},[z12=d4->z12=d5},[ptr=int32#3,ptr=r2,z0=reg128#4%bot->z0=reg128#4%top},[z0=d6->z0=d7},[r3=reg128#5,r3=q4,input_2=int32#2,input_2=r1,ptr=int32#3,<5z34_stack=stack128#11 +# asm 2: lea >ptr=r2,<5z34_stack=[sp,#160] +add r2,sp,#160 + +# qhasm: 5z34 aligned= mem128[ptr] +# asm 1: vld1.8 {>5z34=reg128#6%bot->5z34=reg128#6%top},[5z34=d10->5z34=d11},[r0=reg128#8,r0=q7,r2=reg128#14,r2=q13,d01=reg128#12%bot->d01=reg128#12%top},[d01=d22->d01=d23},[r1=reg128#15,r1=q14,ptr=int32#3,<5z12_stack=stack128#10 +# asm 2: lea >ptr=r2,<5z12_stack=[sp,#144] +add r2,sp,#144 + +# qhasm: 5z12 aligned= mem128[ptr] +# asm 1: vld1.8 {>5z12=reg128#1%bot->5z12=reg128#1%top},[5z12=d0->5z12=d1},[d23=reg128#2%bot->d23=reg128#2%top},[d23=d2->d23=d3},[input_2=int32#2,input_2=r1,> 40 +# asm 1: vshr.u64 >v4=reg128#4,v4=q3,> 14; v23[3] = d23[2,3] unsigned>> 14 +# asm 1: vshrn.u64 > 26; v01[3] = d01[2,3] unsigned>> 26 +# asm 1: vshrn.u64 > 20; v23[1] = mid[2,3] unsigned>> 20 +# asm 1: vshrn.u64 ptr=int32#3,ptr=r2,y34=reg128#3%bot->y34=reg128#3%top},[y34=d4->y34=d5},[ptr=int32#3,ptr=r2,y12=reg128#2%bot->y12=reg128#2%top},[y12=d2->y12=d3},[ptr=int32#3,ptr=r2,y0=reg128#1%bot->y0=reg128#1%top},[y0=d0->y0=d1},[ptr=int32#3,<5y34_stack=stack128#6 +# asm 2: lea >ptr=r2,<5y34_stack=[sp,#80] +add r2,sp,#80 + +# qhasm: 5y34 aligned= mem128[ptr] +# asm 1: vld1.8 {>5y34=reg128#13%bot->5y34=reg128#13%top},[5y34=d24->5y34=d25},[ptr=int32#3,<5y12_stack=stack128#5 +# asm 2: lea >ptr=r2,<5y12_stack=[sp,#64] +add r2,sp,#64 + +# qhasm: 5y12 aligned= mem128[ptr] +# asm 1: vld1.8 {>5y12=reg128#12%bot->5y12=reg128#12%top},[5y12=d22->5y12=d23},[ptr=int32#3,ptr=r2,> 26 +# asm 1: vshr.u64 >t1=reg128#4,t1=q3,len=int32#4,len=r3,r0=reg128#6,r0=q5,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#8,t4=q7,r3=reg128#5,r3=q4,x4=reg128#8,x4=q7,r4=reg128#16%bot->r4=reg128#16%top},[r4=d30->r4=d31},[> 26 +# asm 1: vshr.u64 >t2=reg128#9,t2=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t0=reg128#10,t0=q9,r2=reg128#9,r2=q8,x4=reg128#11,x4=q10,x01=reg128#6,x01=q5,r0=reg128#8%bot->r0=reg128#8%top},[r0=d14->r0=d15},[ptr=int32#3,ptr=r2,t0=reg128#10,t0=q9,> 26 +# asm 1: vshr.u64 >t3=reg128#14,t3=q13,x01=reg128#15,x01=q14,z34=reg128#6%bot->z34=reg128#6%top},[z34=d10->z34=d11},[x23=reg128#10,x23=q9,r3=reg128#5,r3=q4,input_2=int32#2,input_2=r1,> 26 +# asm 1: vshr.u64 >t1=reg128#14,t1=q13,x01=reg128#9,x01=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#14,t4=q13,r3=reg128#5,r3=q4,x4=reg128#11,x4=q10,? len - 64 +# asm 1: cmp +bhi ._mainloop2 + +# qhasm: input_2 -= 32 +# asm 1: sub >input_2=int32#3,input_2=r2,? len - 32 +# asm 1: cmp +bls ._end + +# qhasm: mainloop: +._mainloop: + +# qhasm: new r0 + +# qhasm: ptr = &two24 +# asm 1: lea >ptr=int32#2,ptr=r1,r4=reg128#5%bot->r4=reg128#5%top},[r4=d8->r4=d9},[u4=reg128#6%bot->u4=reg128#6%top},[u4=d10->u4=d11},[c01=reg128#8%bot->c01=reg128#8%top},[c01=d14->c01=d15},[c23=reg128#14%bot->c23=reg128#14%top},[c23=d26->c23=d27},[r0=reg128#4,r0=q3,r3=reg128#6,r3=q5,r1=reg128#14,r1=q13,r2=reg128#8,r2=q7,> 26 +# asm 1: vshr.u64 >t1=reg128#9,t1=q8,r0=reg128#4,r0=q3,r1=reg128#9,r1=q8,> 26 +# asm 1: vshr.u64 >t4=reg128#10,t4=q9,r3=reg128#6,r3=q5,r4=reg128#5,r4=q4,> 26 +# asm 1: vshr.u64 >t2=reg128#10,t2=q9,r1=reg128#11,r1=q10,> 26 +# asm 1: vshr.u64 >t0=reg128#9,t0=q8,r2=reg128#8,r2=q7,r4=reg128#5,r4=q4,r0=reg128#4,r0=q3,t0=reg128#9,t0=q8,> 26 +# asm 1: vshr.u64 >t3=reg128#14,t3=q13,r0=reg128#4,r0=q3,x23=reg128#10,x23=q9,r3=reg128#6,r3=q5,> 26 +# asm 1: vshr.u64 >t1=reg128#8,t1=q7,x01=reg128#9,x01=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#8,t4=q7,r3=reg128#6,r3=q5,x4=reg128#11,x4=q10,len=int32#4,len=r3,? len - 32 +# asm 1: cmp +bhi ._mainloop + +# qhasm: end: +._end: + +# qhasm: mem128[input_0] = x01;input_0+=16 +# asm 1: vst1.8 {len=int32#1,len=r0,mask=reg128#1,#0xffffffff +# asm 2: vmov.i64 >mask=q0,#0xffffffff +vmov.i64 q0,#0xffffffff + +# qhasm: y01 aligned= mem128[input_2];input_2+=16 +# asm 1: vld1.8 {>y01=reg128#2%bot->y01=reg128#2%top},[y01=d2->y01=d3},[_5y01=reg128#3,_5y01=q2,y23=reg128#4%bot->y23=reg128#4%top},[y23=d6->y23=d7},[_5y23=reg128#9,_5y23=q8,_5y4=reg128#11,_5y4=q10,x01=reg128#12%bot->x01=reg128#12%top},[x01=d22->x01=d23},[_5y01=reg128#3,<_5y01=reg128#3,_5y01=q2,<_5y01=q2,x23=reg128#13%bot->x23=reg128#13%top},[x23=d24->x23=d25},[_5y23=reg128#9,<_5y23=reg128#9,_5y23=q8,<_5y23=q8,_5y4=reg128#11,<_5y4=reg128#11,_5y4=q10,<_5y4=q10,c01=reg128#14%bot->c01=reg128#14%top},[c01=d26->c01=d27},[x01=reg128#12,x01=q11,c23=reg128#14%bot->c23=reg128#14%top},[c23=d26->c23=d27},[x23=reg128#13,x23=q12,>=6 +# asm 1: vshr.u64 >mask=reg128#1,mask=q0,x4=reg128#14,x4=q13,r0=reg128#15,r0=q14,r1=reg128#3,r1=q2,r2=reg128#16,r2=q15,r3=reg128#9,r3=q8,r4=reg128#10,r4=q9,> 26 +# asm 1: vshr.u64 >t1=reg128#2,t1=q1,r0=reg128#4,r0=q3,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t4=reg128#3,t4=q2,r3=reg128#9,r3=q8,r4=reg128#3,r4=q2,> 26 +# asm 1: vshr.u64 >t2=reg128#10,t2=q9,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t0=reg128#11,t0=q10,r2=reg128#10,r2=q9,r4=reg128#3,r4=q2,r0=reg128#4,r0=q3,t0=reg128#11,t0=q10,> 26 +# asm 1: vshr.u64 >t3=reg128#12,t3=q11,r0=reg128#4,r0=q3,x23=reg128#10,x23=q9,r3=reg128#9,r3=q8,> 26 +# asm 1: vshr.u64 >t1=reg128#11,t1=q10,x01=reg128#4,x01=q3,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t4=reg128#11,t4=q10,r3=reg128#1,r3=q0,x4=reg128#3,x4=q2, + +#include "../internal.h" + + +#if defined(BORINGSSL_HAS_UINT128) && defined(OPENSSL_X86_64) + +#include + +static uint32_t load_u32_le(const uint8_t in[4]) { + uint32_t ret; + OPENSSL_memcpy(&ret, in, 4); + return ret; +} + +static uint64_t load_u64_le(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, 8); + return ret; +} + +static void store_u64_le(uint8_t out[8], uint64_t v) { + OPENSSL_memcpy(out, &v, 8); +} + +typedef __m128i xmmi; + +static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = { + (1 << 26) - 1, 0, (1 << 26) - 1, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = { + (1 << 24), 0, (1 << 24), 0}; + +static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; } + +static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; } + +static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) { + return (uint128_t)a * b; +} + +static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; } + +static inline uint64_t shr128(uint128_t v, const int shift) { + return (uint64_t)(v >> shift); +} + +static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) { + return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift); +} + +typedef struct poly1305_power_t { + union { + xmmi v; + uint64_t u[2]; + uint32_t d[4]; + } R20, R21, R22, R23, R24, S21, S22, S23, S24; +} poly1305_power; + +typedef struct poly1305_state_internal_t { + poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 + bytes of free storage */ + union { + xmmi H[5]; // 80 bytes + uint64_t HH[10]; + }; + // uint64_t r0,r1,r2; [24 bytes] + // uint64_t pad0,pad1; [16 bytes] + uint64_t started; // 8 bytes + uint64_t leftover; // 8 bytes + uint8_t buffer[64]; // 64 bytes +} poly1305_state_internal; /* 448 bytes total + 63 bytes for + alignment = 511 bytes raw */ + +OPENSSL_STATIC_ASSERT( + sizeof(struct poly1305_state_internal_t) + 63 <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_internal_t"); + +static inline poly1305_state_internal *poly1305_aligned_state( + poly1305_state *state) { + return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63); +} + +static inline size_t poly1305_min(size_t a, size_t b) { + return (a < b) ? a : b; +} + +void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + poly1305_power *p; + uint64_t r0, r1, r2; + uint64_t t0, t1; + + // clamp key + t0 = load_u64_le(key + 0); + t1 = load_u64_le(key + 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + // store r in un-used space of st->P[1] + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + + // store pad + p->R23.d[1] = load_u32_le(key + 16); + p->R23.d[3] = load_u32_le(key + 20); + p->R24.d[1] = load_u32_le(key + 24); + p->R24.d[3] = load_u32_le(key + 28); + + // H = 0 + st->H[0] = _mm_setzero_si128(); + st->H[1] = _mm_setzero_si128(); + st->H[2] = _mm_setzero_si128(); + st->H[3] = _mm_setzero_si128(); + st->H[4] = _mm_setzero_si128(); + + st->started = 0; + st->leftover = 0; +} + +static void poly1305_first_block(poly1305_state_internal *st, + const uint8_t *m) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + xmmi T5, T6; + poly1305_power *p; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t r20, r21, r22, s22; + uint64_t pad0, pad1; + uint64_t c; + uint64_t i; + + // pull out stored info + p = &st->P[1]; + + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + + // compute powers r^2,r^4 + r20 = r0; + r21 = r1; + r22 = r2; + for (i = 0; i < 2; i++) { + s22 = r22 * (5 << 2); + + d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22)); + d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21)); + d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20)); + + r20 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + r21 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + r22 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + r20 += c * 5; + c = (r20 >> 44); + r20 = r20 & 0xfffffffffff; + r21 += c; + + p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R21.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R22.v = + _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R23.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), + _MM_SHUFFLE(1, 0, 1, 0)); + p->S21.v = _mm_mul_epu32(p->R21.v, FIVE); + p->S22.v = _mm_mul_epu32(p->R22.v, FIVE); + p->S23.v = _mm_mul_epu32(p->R23.v, FIVE); + p->S24.v = _mm_mul_epu32(p->R24.v, FIVE); + p--; + } + + // put saved info back + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + p->R23.d[1] = (uint32_t)(pad0); + p->R23.d[3] = (uint32_t)(pad0 >> 32); + p->R24.d[1] = (uint32_t)(pad1); + p->R24.d[3] = (uint32_t)(pad1 >> 32); + + // H = [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + st->H[0] = _mm_and_si128(MMASK, T5); + st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + st->H[2] = _mm_and_si128(MMASK, T5); + st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); +} + +static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi M0, M1, M2, M3, M4; + xmmi C1, C2; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + while (bytes >= 64) { + // H *= [r^4,r^4] + p = &st->P[0]; + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My]*[r^2,r^2] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + p = &st->P[1]; + T5 = _mm_mul_epu32(M0, p->R20.v); + T6 = _mm_mul_epu32(M0, p->R21.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M1, p->S24.v); + T6 = _mm_mul_epu32(M1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M2, p->S23.v); + T6 = _mm_mul_epu32(M2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M3, p->S22.v); + T6 = _mm_mul_epu32(M3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M4, p->S21.v); + T6 = _mm_mul_epu32(M4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M0, p->R22.v); + T6 = _mm_mul_epu32(M0, p->R23.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M1, p->R21.v); + T6 = _mm_mul_epu32(M1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M2, p->R20.v); + T6 = _mm_mul_epu32(M2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M3, p->S24.v); + T6 = _mm_mul_epu32(M3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M4, p->S23.v); + T6 = _mm_mul_epu32(M4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M0, p->R24.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)), + _mm_loadl_epi64((const xmmi *)(m + 48))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)), + _mm_loadl_epi64((const xmmi *)(m + 56))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + m += 64; + bytes -= 64; + } + + st->H[0] = H0; + st->H[1] = H1; + st->H[2] = H2; + st->H[3] = H3; + st->H[4] = H4; +} + +static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi M0, M1, M2, M3, M4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi C1, C2; + + uint64_t r0, r1, r2; + uint64_t t0, t1, t2, t3, t4; + uint64_t c; + size_t consumed = 0; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + // p = [r^2,r^2] + p = &st->P[1]; + + if (bytes >= 32) { + // H *= [r^2,r^2] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + consumed = 32; + } + + // finalize, H *= [r^2,r] + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + + p->R20.d[2] = (uint32_t)(r0)&0x3ffffff; + p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + p->R24.d[2] = (uint32_t)((r2 >> 16)); + p->S21.d[2] = p->R21.d[2] * 5; + p->S22.d[2] = p->R22.d[2] * 5; + p->S23.d[2] = p->R23.d[2] * 5; + p->S24.d[2] = p->R24.d[2] * 5; + + // H *= [r^2,r] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = H[0]+H[1] + H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(H0); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(H1) + c; + c = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(H2) + c; + c = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(H3) + c; + c = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(H4) + c; + c = (t4 >> 26); + t4 &= 0x3ffffff; + t0 = t0 + (c * 5); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = t1 + c; + + st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff); + st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff); + st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff); + + return consumed; +} + +void CRYPTO_poly1305_update(poly1305_state *state, const uint8_t *m, + size_t bytes) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t want; + + // Work around a C language bug. See https://crbug.com/1019588. + if (bytes == 0) { + return; + } + + // need at least 32 initial bytes to start the accelerated branch + if (!st->started) { + if ((st->leftover == 0) && (bytes > 32)) { + poly1305_first_block(st, m); + m += 32; + bytes -= 32; + } else { + want = poly1305_min(32 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if ((st->leftover < 32) || (bytes == 0)) { + return; + } + poly1305_first_block(st, st->buffer); + st->leftover = 0; + } + st->started = 1; + } + + // handle leftover + if (st->leftover) { + want = poly1305_min(64 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < 64) { + return; + } + poly1305_blocks(st, st->buffer, 64); + st->leftover = 0; + } + + // process 64 byte blocks + if (bytes >= 64) { + want = (bytes & ~63); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + if (bytes) { + OPENSSL_memcpy(st->buffer + st->leftover, m, bytes); + st->leftover += bytes; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *state, uint8_t mac[16]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t leftover = st->leftover; + uint8_t *m = st->buffer; + uint128_t d[3]; + uint64_t h0, h1, h2; + uint64_t t0, t1; + uint64_t g0, g1, g2, c, nc; + uint64_t r0, r1, r2, s1, s2; + poly1305_power *p; + + if (st->started) { + size_t consumed = poly1305_combine(st, m, leftover); + leftover -= consumed; + m += consumed; + } + + // st->HH will either be 0 or have the combined result + h0 = st->HH[0]; + h1 = st->HH[1]; + h2 = st->HH[2]; + + p = &st->P[1]; + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + if (leftover < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_atleast16bytes: + t0 = load_u64_le(m + 0); + t1 = load_u64_le(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24) | ((uint64_t)1 << 40); + +poly1305_donna_mul: + d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), + mul64x64_128(h2, s1)); + d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), + mul64x64_128(h2, s2)); + d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), + mul64x64_128(h2, r0)); + h0 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + h1 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + h2 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + h0 += c * 5; + + m += 16; + leftover -= 16; + if (leftover >= 16) { + goto poly1305_donna_atleast16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!leftover) { + goto poly1305_donna_finish; + } + + m[leftover++] = 1; + OPENSSL_memset(m + leftover, 0, 16 - leftover); + leftover = 16; + + t0 = load_u64_le(m + 0); + t1 = load_u64_le(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((uint64_t)1 << 42); + + c = (g2 >> 63) - 1; + nc = ~c; + h0 = (h0 & nc) | (g0 & c); + h1 = (h1 & nc) | (g1 & c); + h2 = (h2 & nc) | (g2 & c); + + // pad + t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + h0 += (t0 & 0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += (t0 & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + t1 = (t1 >> 24); + h2 += (t1)+c; + + store_u64_le(mac + 0, ((h0) | (h1 << 44))); + store_u64_le(mac + 8, ((h1 >> 20) | (h2 << 24))); +} + +#endif // BORINGSSL_HAS_UINT128 && OPENSSL_X86_64 diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/internal.h new file mode 100644 index 00000000..e32350e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/internal.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_INTERNAL_H +#define OPENSSL_HEADER_POOL_INTERNAL_H + +#include +#include + +#include "../lhash/internal.h" + + +#if defined(__cplusplus) +extern "C" { +#endif + + +DEFINE_LHASH_OF(CRYPTO_BUFFER) + +struct crypto_buffer_st { + CRYPTO_BUFFER_POOL *pool; + uint8_t *data; + size_t len; + CRYPTO_refcount_t references; + int data_is_static; +}; + +struct crypto_buffer_pool_st { + LHASH_OF(CRYPTO_BUFFER) *bufs; + CRYPTO_MUTEX lock; + const uint64_t hash_key[2]; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POOL_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/pool.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/pool.c new file mode 100644 index 00000000..f4162ec5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/pool/pool.c @@ -0,0 +1,264 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) { + return (uint32_t)SIPHASH_24(buf->pool->hash_key, buf->data, buf->len); +} + +static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) { + // Only |CRYPTO_BUFFER|s from the same pool have compatible hashes. + assert(a->pool != NULL); + assert(a->pool == b->pool); + if (a->len != b->len) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->len); +} + +CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) { + CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL)); + if (pool == NULL) { + return NULL; + } + + OPENSSL_memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL)); + pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp); + if (pool->bufs == NULL) { + OPENSSL_free(pool); + return NULL; + } + + CRYPTO_MUTEX_init(&pool->lock); + RAND_bytes((uint8_t *)&pool->hash_key, sizeof(pool->hash_key)); + + return pool; +} + +void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) { + if (pool == NULL) { + return; + } + +#if !defined(NDEBUG) + CRYPTO_MUTEX_lock_write(&pool->lock); + assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0); + CRYPTO_MUTEX_unlock_write(&pool->lock); +#endif + + lh_CRYPTO_BUFFER_free(pool->bufs); + CRYPTO_MUTEX_cleanup(&pool->lock); + OPENSSL_free(pool); +} + +static void crypto_buffer_free_object(CRYPTO_BUFFER *buf) { + if (!buf->data_is_static) { + OPENSSL_free(buf->data); + } + OPENSSL_free(buf); +} + +static CRYPTO_BUFFER *crypto_buffer_new(const uint8_t *data, size_t len, + int data_is_static, + CRYPTO_BUFFER_POOL *pool) { + if (pool != NULL) { + CRYPTO_BUFFER tmp; + tmp.data = (uint8_t *) data; + tmp.len = len; + tmp.pool = pool; + + CRYPTO_MUTEX_lock_read(&pool->lock); + CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp); + if (data_is_static && duplicate != NULL && !duplicate->data_is_static) { + // If the new |CRYPTO_BUFFER| would have static data, but the duplicate + // does not, we replace the old one with the new static version. + duplicate = NULL; + } + if (duplicate != NULL) { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_read(&pool->lock); + + if (duplicate != NULL) { + return duplicate; + } + } + + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if (buf == NULL) { + return NULL; + } + OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + if (data_is_static) { + buf->data = (uint8_t *)data; + buf->data_is_static = 1; + } else { + buf->data = OPENSSL_memdup(data, len); + if (len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + } + + buf->len = len; + buf->references = 1; + + if (pool == NULL) { + return buf; + } + + buf->pool = pool; + + CRYPTO_MUTEX_lock_write(&pool->lock); + CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf); + if (data_is_static && duplicate != NULL && !duplicate->data_is_static) { + // If the new |CRYPTO_BUFFER| would have static data, but the duplicate does + // not, we replace the old one with the new static version. + duplicate = NULL; + } + int inserted = 0; + if (duplicate == NULL) { + CRYPTO_BUFFER *old = NULL; + inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf); + // |old| may be non-NULL if a match was found but ignored. |pool->bufs| does + // not increment refcounts, so there is no need to clean up after the + // replacement. + } else { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_write(&pool->lock); + + if (!inserted) { + // We raced to insert |buf| into the pool and lost, or else there was an + // error inserting. + crypto_buffer_free_object(buf); + return duplicate; + } + + return buf; +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool) { + return crypto_buffer_new(data, len, /*data_is_static=*/0, pool); +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_alloc(uint8_t **out_data, size_t len) { + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if (buf == NULL) { + return NULL; + } + OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + buf->data = OPENSSL_malloc(len); + if (len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + buf->len = len; + buf->references = 1; + + *out_data = buf->data; + return buf; +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS(const CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool); +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_static_data_unsafe( + const uint8_t *data, size_t len, CRYPTO_BUFFER_POOL *pool) { + return crypto_buffer_new(data, len, /*data_is_static=*/1, pool); +} + +void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) { + if (buf == NULL) { + return; + } + + CRYPTO_BUFFER_POOL *const pool = buf->pool; + if (pool == NULL) { + if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + // If a reference count of zero is observed, there cannot be a reference + // from any pool to this buffer and thus we are able to free this + // buffer. + crypto_buffer_free_object(buf); + } + + return; + } + + CRYPTO_MUTEX_lock_write(&pool->lock); + if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + return; + } + + // We have an exclusive lock on the pool, therefore no concurrent lookups can + // find this buffer and increment the reference count. Thus, if the count is + // zero there are and can never be any more references and thus we can free + // this buffer. + // + // Note it is possible |buf| is no longer in the pool, if it was replaced by a + // static version. If that static version was since removed, it is even + // possible for |found| to be NULL. + CRYPTO_BUFFER *found = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf); + if (found == buf) { + found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf); + assert(found == buf); + (void)found; + } + + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + crypto_buffer_free_object(buf); +} + +int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) { + // This is safe in the case that |buf->pool| is NULL because it's just + // standard reference counting in that case. + // + // This is also safe if |buf->pool| is non-NULL because, if it were racing + // with |CRYPTO_BUFFER_free| then the two callers must have independent + // references already and so the reference count will never hit zero. + CRYPTO_refcount_inc(&buf->references); + return 1; +} + +const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) { + return buf->data; +} + +size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) { + return buf->len; +} + +void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) { + CBS_init(out, buf->data, buf->len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/deterministic.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/deterministic.c new file mode 100644 index 00000000..ee759c0b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/deterministic.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include + +#include + +#include "../internal.h" +#include "../fipsmodule/rand/internal.h" + + +// g_num_calls is the number of calls to |CRYPTO_sysrand| that have occurred. +// +// This is intentionally not thread-safe. If the fuzzer mode is ever used in a +// multi-threaded program, replace this with a thread-local. (A mutex would not +// be deterministic.) +static uint64_t g_num_calls = 0; +static struct CRYPTO_STATIC_MUTEX g_num_calls_lock = CRYPTO_STATIC_MUTEX_INIT; + +void RAND_reset_for_fuzzing(void) { g_num_calls = 0; } + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + static const uint8_t kZeroKey[32]; + + CRYPTO_STATIC_MUTEX_lock_write(&g_num_calls_lock); + uint64_t num_calls = g_num_calls++; + CRYPTO_STATIC_MUTEX_unlock_write(&g_num_calls_lock); + + uint8_t nonce[12]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + OPENSSL_memcpy(nonce, &num_calls, sizeof(num_calls)); + + OPENSSL_memset(out, 0, requested); + CRYPTO_chacha_20(out, out, requested, kZeroKey, nonce, 0); +} + +void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) { + CRYPTO_sysrand(out, requested); +} + +#endif // BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/forkunsafe.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/forkunsafe.c new file mode 100644 index 00000000..9750d309 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/forkunsafe.c @@ -0,0 +1,46 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "../fipsmodule/rand/internal.h" + + +// g_buffering_enabled is true if fork-unsafe buffering has been enabled. +static int g_buffering_enabled = 0; + +// g_lock protects |g_buffering_enabled|. +static struct CRYPTO_STATIC_MUTEX g_lock = CRYPTO_STATIC_MUTEX_INIT; + +#if !defined(OPENSSL_WINDOWS) +void RAND_enable_fork_unsafe_buffering(int fd) { + // We no longer support setting the file-descriptor with this function. + if (fd != -1) { + abort(); + } + + CRYPTO_STATIC_MUTEX_lock_write(&g_lock); + g_buffering_enabled = 1; + CRYPTO_STATIC_MUTEX_unlock_write(&g_lock); +} +#endif + +int rand_fork_unsafe_buffering_enabled(void) { + CRYPTO_STATIC_MUTEX_lock_read(&g_lock); + const int ret = g_buffering_enabled; + CRYPTO_STATIC_MUTEX_unlock_read(&g_lock); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/fuchsia.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/fuchsia.c new file mode 100644 index 00000000..0fbab22f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/fuchsia.c @@ -0,0 +1,34 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_FUCHSIA) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +#include + +#include "../fipsmodule/rand/internal.h" + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + zx_cprng_draw(out, requested); +} + +void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) { + CRYPTO_sysrand(out, requested); +} + +#endif // OPENSSL_FUCHSIA && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c new file mode 100644 index 00000000..9199e200 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/passive.c @@ -0,0 +1,34 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include "../fipsmodule/rand/internal.h" + +#if defined(BORINGSSL_FIPS) + +// RAND_need_entropy is called by the FIPS module when it has blocked because of +// a lack of entropy. This signal is used as an indication to feed it more. +void RAND_need_entropy(size_t bytes_needed) { + uint8_t buf[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + size_t todo = sizeof(buf); + if (todo > bytes_needed) { + todo = bytes_needed; + } + + int used_cpu; + CRYPTO_get_seed_entropy(buf, todo, &used_cpu); + RAND_load_entropy(buf, todo, used_cpu); +} + +#endif // FIPS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/rand_extra.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/rand_extra.c new file mode 100644 index 00000000..d98a83d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/rand_extra.c @@ -0,0 +1,74 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + + +void RAND_seed(const void *buf, int num) { + // OpenSSH calls |RAND_seed| before jailing on the assumption that any needed + // file descriptors etc will be opened. + uint8_t unused; + RAND_bytes(&unused, sizeof(unused)); +} + +int RAND_load_file(const char *path, long num) { + if (num < 0) { // read the "whole file" + return 1; + } else if (num <= INT_MAX) { + return (int) num; + } else { + return INT_MAX; + } +} + +const char *RAND_file_name(char *buf, size_t num) { return NULL; } + +void RAND_add(const void *buf, int num, double entropy) {} + +int RAND_egd(const char *path) { + return 255; +} + +int RAND_poll(void) { + return 1; +} + +int RAND_status(void) { + return 1; +} + +static const struct rand_meth_st kSSLeayMethod = { + RAND_seed, + RAND_bytes, + RAND_cleanup, + RAND_add, + RAND_pseudo_bytes, + RAND_status, +}; + +RAND_METHOD *RAND_SSLeay(void) { + return (RAND_METHOD*) &kSSLeayMethod; +} + +RAND_METHOD *RAND_OpenSSL(void) { + return RAND_SSLeay(); +} + +const RAND_METHOD *RAND_get_rand_method(void) { return RAND_SSLeay(); } + +int RAND_set_rand_method(const RAND_METHOD *method) { return 1; } + +void RAND_cleanup(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/windows.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/windows.c new file mode 100644 index 00000000..d5d5145d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rand_extra/windows.c @@ -0,0 +1,73 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) + +#include + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#include +OPENSSL_MSVC_PRAGMA(comment(lib, "bcrypt.lib")) +#else +// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the +// "Community Additions" comment on MSDN here: +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx +#define SystemFunction036 NTAPI SystemFunction036 +#include +#undef SystemFunction036 +#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP + +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include "../fipsmodule/rand/internal.h" + + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { + ULONG output_bytes_this_pass = ULONG_MAX; + if (requested < output_bytes_this_pass) { + output_bytes_this_pass = (ULONG)requested; + } + // On non-UWP configurations, use RtlGenRandom instead of BCryptGenRandom + // to avoid accessing resources that may be unavailable inside the + // Chromium sandbox. See https://crbug.com/boringssl/307 +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + if (!BCRYPT_SUCCESS(BCryptGenRandom( + /*hAlgorithm=*/NULL, out, output_bytes_this_pass, + BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { +#else + if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) { +#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP + abort(); + } + requested -= output_bytes_this_pass; + out += output_bytes_this_pass; + } + return; +} + +void CRYPTO_sysrand_for_seed(uint8_t *out, size_t requested) { + CRYPTO_sysrand(out, requested); +} + +#endif // OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rc4/rc4.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rc4/rc4.c new file mode 100644 index 00000000..388b7d20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rc4/rc4.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) { + uint32_t x = key->x; + uint32_t y = key->y; + uint32_t *d = key->data; + + for (size_t i = 0; i < len; i++) { + x = (x + 1) & 0xff; + uint32_t tx = d[x]; + y = (tx + y) & 0xff; + uint32_t ty = d[y]; + d[x] = ty; + d[y] = tx; + out[i] = d[(tx + ty) & 0xff] ^ in[i]; + } + + key->x = x; + key->y = y; +} + +void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) { + uint32_t *d = &rc4key->data[0]; + rc4key->x = 0; + rc4key->y = 0; + + for (unsigned i = 0; i < 256; i++) { + d[i] = i; + } + + unsigned id1 = 0, id2 = 0; + for (unsigned i = 0; i < 256; i++) { + uint32_t tmp = d[i]; + id2 = (key[id1] + tmp + id2) & 0xff; + if (++id1 == len) { + id1 = 0; + } + d[i] = d[id2]; + d[id2] = tmp; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_c11.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_c11.c new file mode 100644 index 00000000..2ca5269d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_c11.c @@ -0,0 +1,67 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + + +#if defined(OPENSSL_C11_ATOMIC) + +#include +#include +#include +#include + +#include + + +// See comment above the typedef of CRYPTO_refcount_t about these tests. +static_assert(alignof(CRYPTO_refcount_t) == alignof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the needed alignment of a reference count"); +static_assert(sizeof(CRYPTO_refcount_t) == sizeof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the size of a reference count"); + +static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + "CRYPTO_REFCOUNT_MAX is incorrect"); + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *) in_count; + uint32_t expected = atomic_load(count); + + while (expected != CRYPTO_REFCOUNT_MAX) { + uint32_t new_value = expected + 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + break; + } + } +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *)in_count; + uint32_t expected = atomic_load(count); + + for (;;) { + if (expected == 0) { + abort(); + } else if (expected == CRYPTO_REFCOUNT_MAX) { + return 0; + } else { + const uint32_t new_value = expected - 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + return new_value == 0; + } + } + } +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_lock.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_lock.c new file mode 100644 index 00000000..8888d035 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/refcount_lock.c @@ -0,0 +1,53 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#include + +#include + + +#if !defined(OPENSSL_C11_ATOMIC) + +OPENSSL_STATIC_ASSERT((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + "CRYPTO_REFCOUNT_MAX is incorrect"); + +static struct CRYPTO_STATIC_MUTEX g_refcount_lock = CRYPTO_STATIC_MUTEX_INIT; + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *count) { + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)++; + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count == 0) { + abort(); + } + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)--; + } + ret = (*count == 0); + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); + + return ret; +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_asn1.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_asn1.c new file mode 100644 index 00000000..97a8e31a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_asn1.c @@ -0,0 +1,324 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // An RSA object may be missing some components. + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +RSA *RSA_parse_public_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + + if (!RSA_check_key(ret)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + RSA_free(ret); + return NULL; + } + + return ret; +} + +RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// kVersionTwoPrime is the value of the version field for a two-prime +// RSAPrivateKey structure (RFC 3447). +static const uint64_t kVersionTwoPrime = 0; + +RSA *RSA_parse_private_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (version != kVersionTwoPrime) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + !parse_integer(&child, &ret->d) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->dmp1) || + !parse_integer(&child, &ret->dmq1) || + !parse_integer(&child, &ret->iqmp)) { + goto err; + } + + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (!RSA_check_key(ret)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + goto err; + } + + return ret; + +err: + RSA_free(ret); + return NULL; +} + +RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, kVersionTwoPrime) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !marshal_integer(&child, rsa->d) || + !marshal_integer(&child, rsa->p) || + !marshal_integer(&child, rsa->q) || + !marshal_integer(&child, rsa->dmp1) || + !marshal_integer(&child, rsa->dmq1) || + !marshal_integer(&child, rsa->iqmp) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *RSAPublicKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_public_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} + +RSA *RSAPrivateKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_private_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_print.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_print.c new file mode 100644 index 00000000..8d82a9ef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_print.c @@ -0,0 +1,22 @@ +/* + * Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include + + +int RSA_print(BIO *bio, const RSA *rsa, int indent) { + EVP_PKEY *pkey = EVP_PKEY_new(); + int ret = pkey != NULL && + EVP_PKEY_set1_RSA(pkey, (RSA *)rsa) && + EVP_PKEY_print_private(bio, pkey, indent, NULL); + EVP_PKEY_free(pkey); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/siphash/siphash.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/siphash/siphash.c new file mode 100644 index 00000000..23dcf28a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/siphash/siphash.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include + +#include + +#include "../internal.h" + + +static void siphash_round(uint64_t v[4]) { + v[0] += v[1]; + v[2] += v[3]; + v[1] = CRYPTO_rotl_u64(v[1], 13); + v[3] = CRYPTO_rotl_u64(v[3], 16); + v[1] ^= v[0]; + v[3] ^= v[2]; + v[0] = CRYPTO_rotl_u64(v[0], 32); + v[2] += v[1]; + v[0] += v[3]; + v[1] = CRYPTO_rotl_u64(v[1], 17); + v[3] = CRYPTO_rotl_u64(v[3], 21); + v[1] ^= v[2]; + v[3] ^= v[0]; + v[2] = CRYPTO_rotl_u64(v[2], 32); +} + +uint64_t SIPHASH_24(const uint64_t key[2], const uint8_t *input, + size_t input_len) { + const size_t orig_input_len = input_len; + + uint64_t v[4]; + v[0] = key[0] ^ UINT64_C(0x736f6d6570736575); + v[1] = key[1] ^ UINT64_C(0x646f72616e646f6d); + v[2] = key[0] ^ UINT64_C(0x6c7967656e657261); + v[3] = key[1] ^ UINT64_C(0x7465646279746573); + + while (input_len >= sizeof(uint64_t)) { + uint64_t m; + memcpy(&m, input, sizeof(m)); + v[3] ^= m; + siphash_round(v); + siphash_round(v); + v[0] ^= m; + + input += sizeof(uint64_t); + input_len -= sizeof(uint64_t); + } + + union { + uint8_t bytes[8]; + uint64_t word; + } last_block; + last_block.word = 0; + OPENSSL_memcpy(last_block.bytes, input, input_len); + last_block.bytes[7] = orig_input_len & 0xff; + + v[3] ^= last_block.word; + siphash_round(v); + siphash_round(v); + v[0] ^= last_block.word; + + v[2] ^= 0xff; + siphash_round(v); + siphash_round(v); + siphash_round(v); + siphash_round(v); + + return v[0] ^ v[1] ^ v[2] ^ v[3]; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/stack/stack.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/stack/stack.c new file mode 100644 index 00000000..08e1a4b6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/stack/stack.c @@ -0,0 +1,425 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include + +#include "../internal.h" + + +// kMinSize is the number of pointers that will be initially allocated in a new +// stack. +static const size_t kMinSize = 4; + +_STACK *sk_new(stack_cmp_func comp) { + _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(_STACK)); + + ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize); + if (ret->data == NULL) { + goto err; + } + + OPENSSL_memset(ret->data, 0, sizeof(void *) * kMinSize); + + ret->comp = comp; + ret->num_alloc = kMinSize; + + return ret; + +err: + OPENSSL_free(ret); + return NULL; +} + +_STACK *sk_new_null(void) { return sk_new(NULL); } + +size_t sk_num(const _STACK *sk) { + if (sk == NULL) { + return 0; + } + return sk->num; +} + +void sk_zero(_STACK *sk) { + if (sk == NULL || sk->num == 0) { + return; + } + OPENSSL_memset(sk->data, 0, sizeof(void*) * sk->num); + sk->num = 0; + sk->sorted = 0; +} + +void *sk_value(const _STACK *sk, size_t i) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i]; +} + +void *sk_set(_STACK *sk, size_t i, void *value) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i] = value; +} + +void sk_free(_STACK *sk) { + if (sk == NULL) { + return; + } + OPENSSL_free(sk->data); + OPENSSL_free(sk); +} + +void sk_pop_free_ex(_STACK *sk, void (*call_free_func)(stack_free_func, void *), + stack_free_func free_func) { + if (sk == NULL) { + return; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] != NULL) { + call_free_func(free_func, sk->data[i]); + } + } + sk_free(sk); +} + +// Historically, |sk_pop_free| called the function as |stack_free_func| +// directly. This is undefined in C. Some callers called |sk_pop_free| directly, +// so we must maintain a compatibility version for now. +static void call_free_func_legacy(stack_free_func func, void *ptr) { + func(ptr); +} + +void sk_pop_free(_STACK *sk, stack_free_func free_func) { + sk_pop_free_ex(sk, call_free_func_legacy, free_func); +} + +size_t sk_insert(_STACK *sk, void *p, size_t where) { + if (sk == NULL) { + return 0; + } + + if (sk->num_alloc <= sk->num + 1) { + // Attempt to double the size of the array. + size_t new_alloc = sk->num_alloc << 1; + size_t alloc_size = new_alloc * sizeof(void *); + void **data; + + // If the doubling overflowed, try to increment. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + new_alloc = sk->num_alloc + 1; + alloc_size = new_alloc * sizeof(void *); + } + + // If the increment also overflowed, fail. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + return 0; + } + + data = OPENSSL_realloc(sk->data, alloc_size); + if (data == NULL) { + return 0; + } + + sk->data = data; + sk->num_alloc = new_alloc; + } + + if (where >= sk->num) { + sk->data[sk->num] = p; + } else { + OPENSSL_memmove(&sk->data[where + 1], &sk->data[where], + sizeof(void *) * (sk->num - where)); + sk->data[where] = p; + } + + sk->num++; + sk->sorted = 0; + + return sk->num; +} + +void *sk_delete(_STACK *sk, size_t where) { + void *ret; + + if (!sk || where >= sk->num) { + return NULL; + } + + ret = sk->data[where]; + + if (where != sk->num - 1) { + OPENSSL_memmove(&sk->data[where], &sk->data[where + 1], + sizeof(void *) * (sk->num - where - 1)); + } + + sk->num--; + return ret; +} + +void *sk_delete_ptr(_STACK *sk, const void *p) { + if (sk == NULL) { + return NULL; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + return sk_delete(sk, i); + } + } + + return NULL; +} + +int sk_find(const _STACK *sk, size_t *out_index, const void *p, + int (*call_cmp_func)(stack_cmp_func, const void **, + const void **)) { + if (sk == NULL) { + return 0; + } + + if (sk->comp == NULL) { + // Use pointer equality when no comparison function has been set. + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + if (out_index) { + *out_index = i; + } + return 1; + } + } + return 0; + } + + if (p == NULL) { + return 0; + } + + if (!sk_is_sorted(sk)) { + for (size_t i = 0; i < sk->num; i++) { + const void *elem = sk->data[i]; + if (call_cmp_func(sk->comp, &p, &elem) == 0) { + if (out_index) { + *out_index = i; + } + return 1; + } + } + return 0; + } + + // The stack is sorted, so binary search to find the element. + // + // |lo| and |hi| maintain a half-open interval of where the answer may be. All + // indices such that |lo <= idx < hi| are candidates. + size_t lo = 0, hi = sk->num; + while (lo < hi) { + // Bias |mid| towards |lo|. See the |r == 0| case below. + size_t mid = lo + (hi - lo - 1) / 2; + assert(lo <= mid && mid < hi); + const void *elem = sk->data[mid]; + int r = call_cmp_func(sk->comp, &p, &elem); + if (r > 0) { + lo = mid + 1; // |mid| is too low. + } else if (r < 0) { + hi = mid; // |mid| is too high. + } else { + // |mid| matches. However, this function returns the earliest match, so we + // can only return if the range has size one. + if (hi - lo == 1) { + if (out_index != NULL) { + *out_index = mid; + } + return 1; + } + // The sample is biased towards |lo|. |mid| can only be |hi - 1| if + // |hi - lo| was one, so this makes forward progress. + assert(mid + 1 < hi); + hi = mid + 1; + } + } + + assert(lo == hi); + return 0; // Not found. +} + +void *sk_shift(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, 0); +} + +size_t sk_push(_STACK *sk, void *p) { return (sk_insert(sk, p, sk->num)); } + +void *sk_pop(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, sk->num - 1); +} + +_STACK *sk_dup(const _STACK *sk) { + if (sk == NULL) { + return NULL; + } + + _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(_STACK)); + + ret->data = OPENSSL_malloc(sizeof(void *) * sk->num_alloc); + if (ret->data == NULL) { + goto err; + } + + ret->num = sk->num; + OPENSSL_memcpy(ret->data, sk->data, sizeof(void *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return ret; + +err: + sk_free(ret); + return NULL; +} + +void sk_sort(_STACK *sk) { + if (sk == NULL || sk->comp == NULL || sk->sorted) { + return; + } + + // sk->comp is a function that takes pointers to pointers to elements, but + // qsort take a comparison function that just takes pointers to elements. + // However, since we're passing an array of pointers to qsort, we can just + // cast the comparison function and everything works. + // + // TODO(davidben): This is undefined behavior, but the call is in libc so, + // e.g., CFI does not notice. Unfortunately, |qsort| is missing a void* + // parameter in its callback and |qsort_s| / |qsort_r| are a mess of + // incompatibility. + if (sk->num >= 2) { + int (*comp_func)(const void *, const void *) = + (int (*)(const void *, const void *))(sk->comp); + qsort(sk->data, sk->num, sizeof(void *), comp_func); + } + sk->sorted = 1; +} + +int sk_is_sorted(const _STACK *sk) { + if (!sk) { + return 1; + } + return sk->sorted; +} + +stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp) { + stack_cmp_func old = sk->comp; + + if (sk->comp != comp) { + sk->sorted = 0; + } + sk->comp = comp; + + return old; +} + +_STACK *sk_deep_copy(const _STACK *sk, + void *(*call_copy_func)(stack_copy_func, void *), + stack_copy_func copy_func, + void (*call_free_func)(stack_free_func, void *), + stack_free_func free_func) { + _STACK *ret = sk_dup(sk); + if (ret == NULL) { + return NULL; + } + + for (size_t i = 0; i < ret->num; i++) { + if (ret->data[i] == NULL) { + continue; + } + ret->data[i] = call_copy_func(copy_func, ret->data[i]); + if (ret->data[i] == NULL) { + for (size_t j = 0; j < i; j++) { + if (ret->data[j] != NULL) { + call_free_func(free_func, ret->data[j]); + } + } + sk_free(ret); + return NULL; + } + } + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread.c new file mode 100644 index 00000000..d4a3e73b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +int CRYPTO_num_locks(void) { return 1; } + +void CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, + const char *file, int line)) {} + +void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, int line) { + return NULL; +} + +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, + const char *file, int line)) {} + +const char *CRYPTO_get_lock_name(int lock_num) { + return "No old-style OpenSSL locks anymore"; +} + +int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { return 1; } + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) {} + +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) {} + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) {} + +void CRYPTO_set_id_callback(unsigned long (*func)(void)) {} + +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *( + *dyn_create_function)(const char *file, int line)) {} + +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)) {} + +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)( + struct CRYPTO_dynlock_value *l, const char *file, int line)) {} + +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))( + const char *file, int line) { + return NULL; +} + +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line) { + return NULL; +} + +void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line) { + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_none.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_none.c new file mode 100644 index 00000000..4f07b9d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_none.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if !defined(OPENSSL_THREADS) + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (*once) { + return; + } + *once = 1; + init(); +} + +static void *g_thread_locals[NUM_OPENSSL_THREAD_LOCALS]; + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + return g_thread_locals[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + g_thread_locals[index] = value; + return 1; +} + +#endif // !OPENSSL_THREADS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_pthread.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_pthread.c new file mode 100644 index 00000000..4743a5f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_pthread.c @@ -0,0 +1,182 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_PTHREADS) + +#include +#include +#include + +#include +#include + + +OPENSSL_STATIC_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t), + "CRYPTO_MUTEX is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(CRYPTO_MUTEX) >= alignof(pthread_rwlock_t), + "CRYPTO_MUTEX has insufficient alignment"); +#endif + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + pthread_rwlock_destroy((pthread_rwlock_t *) lock); +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_rdlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_wrlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (pthread_once(once, init) != 0) { + abort(); + } +} + +static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +// thread_local_destructor is called when a thread exits. It releases thread +// local data for that thread only. +static void thread_local_destructor(void *arg) { + if (arg == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + return; + } + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + pthread_mutex_unlock(&g_destructors_lock); + + unsigned i; + void **pointers = arg; + for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +static pthread_once_t g_thread_local_init_once = PTHREAD_ONCE_INIT; +static pthread_key_t g_thread_local_key; +static int g_thread_local_key_created = 0; + +static void thread_local_init(void) { + g_thread_local_key_created = + pthread_key_create(&g_thread_local_key, thread_local_destructor) == 0; +} + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + return NULL; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + destructor(value); + return 0; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pthread_setspecific(g_thread_local_key, pointers) != 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + destructor(value); + return 0; + } + g_destructors[index] = destructor; + pthread_mutex_unlock(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_PTHREADS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_win.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_win.c new file mode 100644 index 00000000..31038a3f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/thread_win.c @@ -0,0 +1,260 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_WINDOWS_THREADS) + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include +#include + +#include +#include + + +OPENSSL_STATIC_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK), + "CRYPTO_MUTEX is too small"); +#if defined(__GNUC__) || defined(__clang__) +OPENSSL_STATIC_ASSERT(alignof(CRYPTO_MUTEX) >= alignof(SRWLOCK), + "CRYPTO_MUTEX has insufficient alignment"); +#endif + +static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) { + void (**init)(void) = (void (**)(void))arg; + (**init)(); + return TRUE; +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (!InitOnceExecuteOnce(once, call_once_init, &init, NULL)) { + abort(); + } +} + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + InitializeSRWLock((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + AcquireSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + AcquireSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + ReleaseSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + ReleaseSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + // SRWLOCKs require no cleanup. +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockExclusive(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockExclusive(&lock->lock); +} + +static SRWLOCK g_destructors_lock = SRWLOCK_INIT; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +static CRYPTO_once_t g_thread_local_init_once = CRYPTO_ONCE_INIT; +static DWORD g_thread_local_key; +static int g_thread_local_failed; + +static void thread_local_init(void) { + g_thread_local_key = TlsAlloc(); + g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES); +} + +static void NTAPI thread_local_destructor(PVOID module, DWORD reason, + PVOID reserved) { + // Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In + // VS2015's debug runtime, the C runtime has been unloaded by the time + // |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent + // with |pthread_key_create| which does not call destructors on process exit, + // only thread exit. + if (reason != DLL_THREAD_DETACH) { + return; + } + + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return; + } + + void **pointers = (void**) TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + + AcquireSRWLockExclusive(&g_destructors_lock); + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + ReleaseSRWLockExclusive(&g_destructors_lock); + + for (unsigned i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +// Thread Termination Callbacks. +// +// Windows doesn't support a per-thread destructor with its TLS primitives. +// So, we build it manually by inserting a function to be called on each +// thread's exit. This magic is from http://www.codeproject.com/threads/tls.asp +// and it works for VC++ 7.0 and later. +// +// Force a reference to _tls_used to make the linker create the TLS directory +// if it's not already there. (E.g. if __declspec(thread) is not used). Force +// a reference to p_thread_callback_boringssl to prevent whole program +// optimization from discarding the variable. +// +// Note, in the prefixed build, |p_thread_callback_boringssl| may be a macro. +#define STRINGIFY(x) #x +#define EXPAND_AND_STRINGIFY(x) STRINGIFY(x) +#ifdef _WIN64 +__pragma(comment(linker, "/INCLUDE:_tls_used")) +__pragma(comment( + linker, "/INCLUDE:" EXPAND_AND_STRINGIFY(p_thread_callback_boringssl))) +#else +__pragma(comment(linker, "/INCLUDE:__tls_used")) +__pragma(comment( + linker, "/INCLUDE:_" EXPAND_AND_STRINGIFY(p_thread_callback_boringssl))) +#endif + +// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are +// called automatically by the OS loader code (not the CRT) when the module is +// loaded and on thread creation. They are NOT called if the module has been +// loaded by a LoadLibrary() call. It must have implicitly been loaded at +// process startup. +// +// By implicitly loaded, I mean that it is directly referenced by the main EXE +// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being +// implicitly loaded. +// +// See VC\crt\src\tlssup.c for reference. + +// The linker must not discard p_thread_callback_boringssl. (We force a +// reference to this variable with a linker /INCLUDE:symbol pragma to ensure +// that.) If this variable is discarded, the OnThreadExit function will never +// be called. +#ifdef _WIN64 + +// .CRT section is merged with .rdata on x64 so it must be constant data. +#pragma const_seg(".CRT$XLC") +// When defining a const variable, it must have external linkage to be sure the +// linker doesn't discard it. +extern const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl; +const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma const_seg() + +#else + +#pragma data_seg(".CRT$XLC") +PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma data_seg() + +#endif // _WIN64 + +static void **get_thread_locals(void) { + // |TlsGetValue| clears the last error even on success, so that callers may + // distinguish it successfully returning NULL or failing. It is documented to + // never fail if the argument is a valid index from |TlsAlloc|, so we do not + // need to handle this. + // + // However, this error-mangling behavior interferes with the caller's use of + // |GetLastError|. In particular |SSL_get_error| queries the error queue to + // determine whether the caller should look at the OS's errors. To avoid + // destroying state, save and restore the Windows error. + // + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686812(v=vs.85).aspx + DWORD last_error = GetLastError(); + void **ret = TlsGetValue(g_thread_local_key); + SetLastError(last_error); + return ret; +} + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return NULL; + } + + void **pointers = get_thread_locals(); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + destructor(value); + return 0; + } + + void **pointers = get_thread_locals(); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (TlsSetValue(g_thread_local_key, pointers) == 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + AcquireSRWLockExclusive(&g_destructors_lock); + g_destructors[index] = destructor; + ReleaseSRWLockExclusive(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_WINDOWS_THREADS diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/internal.h new file mode 100644 index 00000000..2eb583b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/internal.h @@ -0,0 +1,318 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_TRUST_TOKEN_INTERNAL_H +#define OPENSSL_HEADER_TRUST_TOKEN_INTERNAL_H + +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" + +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// For the following cryptographic schemes, we use P-384 instead of our usual +// choice of P-256. See Appendix I of +// https://eprint.iacr.org/2020/072/20200324:214215 which describes two attacks +// which may affect smaller curves. In particular, p-1 for P-256 is smooth, +// giving a low complexity for the p-1 attack. P-384's p-1 has a 281-bit prime +// factor, +// 3055465788140352002733946906144561090641249606160407884365391979704929268480326390471. +// This lower-bounds the p-1 attack at O(2^140). The p+1 attack is lower-bounded +// by O(p^(1/3)) or O(2^128), so we do not need to check the smoothness of p+1. + + +// TRUST_TOKEN_NONCE_SIZE is the size of nonces used as part of the Trust_Token +// protocol. +#define TRUST_TOKEN_NONCE_SIZE 64 + +typedef struct { + // TODO(https://crbug.com/boringssl/334): These should store |EC_PRECOMP| so + // that |TRUST_TOKEN_finish_issuance| can use |ec_point_mul_scalar_precomp|. + EC_AFFINE pub0; + EC_AFFINE pub1; + EC_AFFINE pubs; +} TRUST_TOKEN_CLIENT_KEY; + +typedef struct { + EC_SCALAR x0; + EC_SCALAR y0; + EC_SCALAR x1; + EC_SCALAR y1; + EC_SCALAR xs; + EC_SCALAR ys; + EC_AFFINE pub0; + EC_PRECOMP pub0_precomp; + EC_AFFINE pub1; + EC_PRECOMP pub1_precomp; + EC_AFFINE pubs; + EC_PRECOMP pubs_precomp; +} TRUST_TOKEN_ISSUER_KEY; + +// TRUST_TOKEN_PRETOKEN represents the intermediate state a client keeps during +// a Trust_Token issuance operation. +typedef struct pmb_pretoken_st { + uint8_t t[TRUST_TOKEN_NONCE_SIZE]; + EC_SCALAR r; + EC_AFFINE Tp; +} TRUST_TOKEN_PRETOKEN; + +// TRUST_TOKEN_PRETOKEN_free releases the memory associated with |token|. +OPENSSL_EXPORT void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *token); + +DEFINE_STACK_OF(TRUST_TOKEN_PRETOKEN) + + +// PMBTokens. +// +// PMBTokens is described in https://eprint.iacr.org/2020/072/20200324:214215 +// and provides anonymous tokens with private metadata. We implement the +// construction with validity verification, described in appendix H, +// construction 6. + +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_experiment_v1|'s PMBTokens construction which +// uses P-384. +int pmbtoken_exp1_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_exp1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count); +int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) * + pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id); +int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len); + +// pmbtoken_exp1_get_h_for_testing returns H in uncompressed coordinates. This +// function is used to confirm H was computed as expected. +OPENSSL_EXPORT int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]); + +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_experiment_v2|'s PMBTokens construction which +// uses P-384. +int pmbtoken_exp2_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count); +int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) * + pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id); +int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len); + +// pmbtoken_exp2_get_h_for_testing returns H in uncompressed coordinates. This +// function is used to confirm H was computed as expected. +OPENSSL_EXPORT int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]); + + +// VOPRF. +// +// VOPRFs are described in https://tools.ietf.org/html/draft-irtf-cfrg-voprf-04 +// and provide anonymous tokens. This implementation uses TrustToken DSTs and +// the DLEQ batching primitive from +// https://eprint.iacr.org/2020/072/20200324:214215. +// VOPRF only uses the |pub|' field of the TRUST_TOKEN_CLIENT_KEY and +// |xs|/|pubs| fields of the TRUST_TOKEN_ISSUER_KEY. + +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_experiment_v2|'s VOPRF construction which uses +// P-384. +int voprf_exp2_generate_key(CBB *out_private, CBB *out_public); +int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count); +int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) * + voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id); +int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len); + + +// Trust Tokens internals. + +struct trust_token_method_st { + // generate_key generates a fresh keypair and writes their serialized + // forms into |out_private| and |out_public|. It returns one on success and + // zero on failure. + int (*generate_key)(CBB *out_private, CBB *out_public); + + // client_key_from_bytes decodes a client key from |in| and sets |key| + // to the resulting key. It returns one on success and zero + // on failure. + int (*client_key_from_bytes)(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, + size_t len); + + // issuer_key_from_bytes decodes a issuer key from |in| and sets |key| + // to the resulting key. It returns one on success and zero + // on failure. + int (*issuer_key_from_bytes)(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, + size_t len); + + // blind generates a new issuance request for |count| tokens. On + // success, it returns a newly-allocated |STACK_OF(TRUST_TOKEN_PRETOKEN)| and + // writes a request to the issuer to |cbb|. On failure, it returns NULL. The + // |STACK_OF(TRUST_TOKEN_PRETOKEN)|s should be passed to |pmbtoken_unblind| when + // the server responds. + // + // This function implements the AT.Usr0 operation. + STACK_OF(TRUST_TOKEN_PRETOKEN) * (*blind)(CBB *cbb, size_t count); + + // sign parses a request for |num_requested| tokens from |cbs| and + // issues |num_to_issue| tokens with |key| and a private metadata value of + // |private_metadata|. It then writes the response to |cbb|. It returns one on + // success and zero on failure. + // + // This function implements the AT.Sig operation. + int (*sign)(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); + + // unblind processes an issuance response for |count| tokens from |cbs| + // and unblinds the signed tokens. |pretokens| are the pre-tokens returned + // from the corresponding |blind| call. On success, the function returns a + // newly-allocated |STACK_OF(TRUST_TOKEN)| containing the resulting tokens. + // Each token's serialization will have |key_id| prepended. Otherwise, it + // returns NULL. + // + // This function implements the AT.Usr1 operation. + STACK_OF(TRUST_TOKEN) * + (*unblind)(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, + size_t count, uint32_t key_id); + + // read parses a PMBToken from |token| and verifies it using |key|. On + // success, it returns one and stores the nonce and private metadata bit in + // |out_nonce| and |*out_private_metadata|. Otherwise, it returns zero. Note + // that, unlike the output of |unblind|, |token| does not have a + // four-byte key ID prepended. + int (*read)(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len); + + // whether the construction supports private metadata. + int has_private_metadata; + + // max keys that can be configured. + size_t max_keys; + + // whether the SRR is part of the protocol. + int has_srr; +}; + +// Structure representing a single Trust Token public key with the specified ID. +struct trust_token_client_key_st { + uint32_t id; + TRUST_TOKEN_CLIENT_KEY key; +}; + +// Structure representing a single Trust Token private key with the specified +// ID. +struct trust_token_issuer_key_st { + uint32_t id; + TRUST_TOKEN_ISSUER_KEY key; +}; + +struct trust_token_client_st { + const TRUST_TOKEN_METHOD *method; + + // max_batchsize is the maximum supported batchsize. + uint16_t max_batchsize; + + // keys is the set of public keys that are supported by the client for + // issuance/redemptions. + struct trust_token_client_key_st keys[6]; + + // num_keys is the number of keys currently configured. + size_t num_keys; + + // pretokens is the intermediate state during an active issuance. + STACK_OF(TRUST_TOKEN_PRETOKEN)* pretokens; + + // srr_key is the public key used to verify the signature of the SRR. + EVP_PKEY *srr_key; +}; + + +struct trust_token_issuer_st { + const TRUST_TOKEN_METHOD *method; + + // max_batchsize is the maximum supported batchsize. + uint16_t max_batchsize; + + // keys is the set of private keys that are supported by the issuer for + // issuance/redemptions. The public metadata is an index into this list of + // keys. + struct trust_token_issuer_key_st keys[6]; + + // num_keys is the number of keys currently configured. + size_t num_keys; + + // srr_key is the private key used to sign the SRR. + EVP_PKEY *srr_key; + + // metadata_key is the secret material used to encode the private metadata bit + // in the SRR. + uint8_t *metadata_key; + size_t metadata_key_len; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(TRUST_TOKEN_PRETOKEN, TRUST_TOKEN_PRETOKEN_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_TRUST_TOKEN_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c new file mode 100644 index 00000000..040bc332 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c @@ -0,0 +1,1399 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ec_extra/internal.h" +#include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/ec/internal.h" + +#include "internal.h" + + +typedef int (*hash_t_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]); +typedef int (*hash_s_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *t, + const uint8_t s[TRUST_TOKEN_NONCE_SIZE]); +typedef int (*hash_c_func_t)(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len); + +typedef struct { + const EC_GROUP *group; + EC_PRECOMP g_precomp; + EC_PRECOMP h_precomp; + EC_RAW_POINT h; + // hash_t implements the H_t operation in PMBTokens. It returns one on success + // and zero on error. + hash_t_func_t hash_t; + // hash_s implements the H_s operation in PMBTokens. It returns one on success + // and zero on error. + hash_s_func_t hash_s; + // hash_c implements the H_c operation in PMBTokens. It returns one on success + // and zero on error. + hash_c_func_t hash_c; + int prefix_point : 1; +} PMBTOKEN_METHOD; + +static const uint8_t kDefaultAdditionalData[32] = {0}; + +static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, + const uint8_t *h_bytes, size_t h_len, + hash_t_func_t hash_t, hash_s_func_t hash_s, + hash_c_func_t hash_c, int prefix_point) { + method->group = EC_GROUP_new_by_curve_name(curve_nid); + if (method->group == NULL) { + return 0; + } + + method->hash_t = hash_t; + method->hash_s = hash_s; + method->hash_c = hash_c; + method->prefix_point = prefix_point; + + EC_AFFINE h; + if (!ec_point_from_uncompressed(method->group, &h, h_bytes, h_len)) { + return 0; + } + ec_affine_to_jacobian(method->group, &method->h, &h); + + if (!ec_init_precomp(method->group, &method->g_precomp, + &method->group->generator->raw) || + !ec_init_precomp(method->group, &method->h_precomp, &method->h)) { + return 0; + } + return 1; +} + +// generate_keypair generates a keypair for the PMBTokens construction. +// |out_x| and |out_y| are set to the secret half of the keypair, while +// |*out_pub| is set to the public half of the keypair. It returns one on +// success and zero on failure. +static int generate_keypair(const PMBTOKEN_METHOD *method, EC_SCALAR *out_x, + EC_SCALAR *out_y, EC_RAW_POINT *out_pub) { + if (!ec_random_nonzero_scalar(method->group, out_x, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, out_y, kDefaultAdditionalData) || + !ec_point_mul_scalar_precomp(method->group, out_pub, &method->g_precomp, + out_x, &method->h_precomp, out_y, NULL, + NULL)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int point_to_cbb(CBB *out, const EC_GROUP *group, + const EC_AFFINE *point) { + size_t len = + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + if (len == 0) { + return 0; + } + uint8_t *p; + return CBB_add_space(out, &p, len) && + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p, + len) == len; +} + +static int cbb_add_prefixed_point(CBB *out, const EC_GROUP *group, + const EC_AFFINE *point, int prefix_point) { + if (prefix_point) { + CBB child; + if (!CBB_add_u16_length_prefixed(out, &child) || + !point_to_cbb(&child, group, point) || + !CBB_flush(out)) { + return 0; + } + } else { + if (!point_to_cbb(out, group, point) || + !CBB_flush(out)) { + return 0; + } + } + + return 1; +} + +static int cbs_get_prefixed_point(CBS *cbs, const EC_GROUP *group, + EC_AFFINE *out, int prefix_point) { + CBS child; + if (prefix_point) { + if (!CBS_get_u16_length_prefixed(cbs, &child)) { + return 0; + } + } else { + size_t plen = 1 + 2 * BN_num_bytes(&group->field); + if (!CBS_get_bytes(cbs, &child, plen)) { + return 0; + } + } + + if (!ec_point_from_uncompressed(group, out, CBS_data(&child), + CBS_len(&child))) { + return 0; + } + return 1; +} + +static int mul_public_3(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, + const EC_RAW_POINT *p2, const EC_SCALAR *scalar2) { + EC_RAW_POINT points[3] = {*p0, *p1, *p2}; + EC_SCALAR scalars[3] = {*scalar0, *scalar1, *scalar2}; + return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points, + scalars, 3); +} + +static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method, + CBB *out_private, CBB *out_public) { + const EC_GROUP *group = method->group; + EC_RAW_POINT pub[3]; + EC_SCALAR x0, y0, x1, y1, xs, ys; + if (!generate_keypair(method, &x0, &y0, &pub[0]) || + !generate_keypair(method, &x1, &y1, &pub[1]) || + !generate_keypair(method, &xs, &ys, &pub[2])) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + return 0; + } + + const EC_SCALAR *scalars[] = {&x0, &y0, &x1, &y1, &xs, &ys}; + size_t scalar_len = BN_num_bytes(&group->order); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + uint8_t *buf; + if (!CBB_add_space(out_private, &buf, scalar_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + return 0; + } + ec_scalar_to_bytes(group, buf, &scalar_len, scalars[i]); + } + + EC_AFFINE pub_affine[3]; + if (!ec_jacobian_to_affine_batch(group, pub_affine, pub, 3)) { + return 0; + } + + if (!cbb_add_prefixed_point(out_public, group, &pub_affine[0], + method->prefix_point) || + !cbb_add_prefixed_point(out_public, group, &pub_affine[1], + method->prefix_point) || + !cbb_add_prefixed_point(out_public, group, &pub_affine[2], + method->prefix_point)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + return 0; + } + + return 1; +} + +static int pmbtoken_client_key_from_bytes(const PMBTOKEN_METHOD *method, + TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + CBS cbs; + CBS_init(&cbs, in, len); + if (!cbs_get_prefixed_point(&cbs, method->group, &key->pub0, + method->prefix_point) || + !cbs_get_prefixed_point(&cbs, method->group, &key->pub1, + method->prefix_point) || + !cbs_get_prefixed_point(&cbs, method->group, &key->pubs, + method->prefix_point) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + return 1; +} + +static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, + TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + const EC_GROUP *group = method->group; + CBS cbs, tmp; + CBS_init(&cbs, in, len); + size_t scalar_len = BN_num_bytes(&group->order); + EC_SCALAR *scalars[] = {&key->x0, &key->y0, &key->x1, + &key->y1, &key->xs, &key->ys}; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + if (!CBS_get_bytes(&cbs, &tmp, scalar_len) || + !ec_scalar_from_bytes(group, scalars[i], CBS_data(&tmp), + CBS_len(&tmp))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + } + + // Recompute the public key. + EC_RAW_POINT pub[3]; + EC_AFFINE pub_affine[3]; + if (!ec_point_mul_scalar_precomp(group, &pub[0], &method->g_precomp, &key->x0, + &method->h_precomp, &key->y0, NULL, NULL) || + !ec_init_precomp(group, &key->pub0_precomp, &pub[0]) || + !ec_point_mul_scalar_precomp(group, &pub[1], &method->g_precomp, &key->x1, + &method->h_precomp, &key->y1, NULL, NULL) || + !ec_init_precomp(group, &key->pub1_precomp, &pub[1]) || + !ec_point_mul_scalar_precomp(group, &pub[2], &method->g_precomp, &key->xs, + &method->h_precomp, &key->ys, NULL, NULL) || + !ec_init_precomp(group, &key->pubs_precomp, &pub[2]) || + !ec_jacobian_to_affine_batch(group, pub_affine, pub, 3)) { + return 0; + } + + key->pub0 = pub_affine[0]; + key->pub1 = pub_affine[1]; + key->pubs = pub_affine[2]; + return 1; +} + +static STACK_OF(TRUST_TOKEN_PRETOKEN) * + pmbtoken_blind(const PMBTOKEN_METHOD *method, CBB *cbb, size_t count) { + const EC_GROUP *group = method->group; + STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = sk_TRUST_TOKEN_PRETOKEN_new_null(); + if (pretokens == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < count; i++) { + // Insert |pretoken| into |pretokens| early to simplify error-handling. + TRUST_TOKEN_PRETOKEN *pretoken = OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); + if (pretoken == NULL || + !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + TRUST_TOKEN_PRETOKEN_free(pretoken); + goto err; + } + + RAND_bytes(pretoken->t, sizeof(pretoken->t)); + + // We sample |pretoken->r| in Montgomery form to simplify inverting. + if (!ec_random_nonzero_scalar(group, &pretoken->r, + kDefaultAdditionalData)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + EC_SCALAR rinv; + ec_scalar_inv0_montgomery(group, &rinv, &pretoken->r); + // Convert both out of Montgomery form. + ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r); + ec_scalar_from_montgomery(group, &rinv, &rinv); + + EC_RAW_POINT T, Tp; + if (!method->hash_t(group, &T, pretoken->t) || + !ec_point_mul_scalar(group, &Tp, &T, &rinv) || + !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) { + goto err; + } + + if (!cbb_add_prefixed_point(cbb, group, &pretoken->Tp, + method->prefix_point)) { + goto err; + } + } + + return pretokens; + +err: + sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free); + return NULL; +} + +static int scalar_to_cbb(CBB *out, const EC_GROUP *group, + const EC_SCALAR *scalar) { + uint8_t *buf; + size_t scalar_len = BN_num_bytes(&group->order); + if (!CBB_add_space(out, &buf, scalar_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + ec_scalar_to_bytes(group, buf, &scalar_len, scalar); + return 1; +} + +static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) { + size_t scalar_len = BN_num_bytes(&group->order); + CBS tmp; + if (!CBS_get_bytes(cbs, &tmp, scalar_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + ec_scalar_from_bytes(group, out, CBS_data(&tmp), CBS_len(&tmp)); + return 1; +} + +static int hash_c_dleq(const PMBTOKEN_METHOD *method, EC_SCALAR *out, + const EC_AFFINE *X, const EC_AFFINE *T, + const EC_AFFINE *S, const EC_AFFINE *W, + const EC_AFFINE *K0, const EC_AFFINE *K1) { + static const uint8_t kDLEQ2Label[] = "DLEQ2"; + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kDLEQ2Label, sizeof(kDLEQ2Label)) || + !point_to_cbb(&cbb, method->group, X) || + !point_to_cbb(&cbb, method->group, T) || + !point_to_cbb(&cbb, method->group, S) || + !point_to_cbb(&cbb, method->group, W) || + !point_to_cbb(&cbb, method->group, K0) || + !point_to_cbb(&cbb, method->group, K1) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_c(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + +static int hash_c_dleqor(const PMBTOKEN_METHOD *method, EC_SCALAR *out, + const EC_AFFINE *X0, const EC_AFFINE *X1, + const EC_AFFINE *T, const EC_AFFINE *S, + const EC_AFFINE *W, const EC_AFFINE *K00, + const EC_AFFINE *K01, const EC_AFFINE *K10, + const EC_AFFINE *K11) { + static const uint8_t kDLEQOR2Label[] = "DLEQOR2"; + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kDLEQOR2Label, sizeof(kDLEQOR2Label)) || + !point_to_cbb(&cbb, method->group, X0) || + !point_to_cbb(&cbb, method->group, X1) || + !point_to_cbb(&cbb, method->group, T) || + !point_to_cbb(&cbb, method->group, S) || + !point_to_cbb(&cbb, method->group, W) || + !point_to_cbb(&cbb, method->group, K00) || + !point_to_cbb(&cbb, method->group, K01) || + !point_to_cbb(&cbb, method->group, K10) || + !point_to_cbb(&cbb, method->group, K11) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_c(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + +static int hash_c_batch(const PMBTOKEN_METHOD *method, EC_SCALAR *out, + const CBB *points, size_t index) { + static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH"; + if (index > 0xffff) { + // The protocol supports only two-byte batches. + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kDLEQBatchLabel, sizeof(kDLEQBatchLabel)) || + !CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) || + !CBB_add_u16(&cbb, (uint16_t)index) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_c(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + +// The DLEQ2 and DLEQOR2 constructions are described in appendix B of +// https://eprint.iacr.org/2020/072/20200324:214215. DLEQ2 is an instance of +// DLEQOR2 with only one value (n=1). + +static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, + const TRUST_TOKEN_ISSUER_KEY *priv, + const EC_RAW_POINT *T, const EC_RAW_POINT *S, + const EC_RAW_POINT *W, const EC_RAW_POINT *Ws, + uint8_t private_metadata) { + const EC_GROUP *group = method->group; + + // We generate a DLEQ proof for the validity token and a DLEQOR2 proof for the + // private metadata token. To allow amortizing Jacobian-to-affine conversions, + // we compute Ki for both proofs first. + enum { + idx_T, + idx_S, + idx_W, + idx_Ws, + idx_Ks0, + idx_Ks1, + idx_Kb0, + idx_Kb1, + idx_Ko0, + idx_Ko1, + num_idx, + }; + EC_RAW_POINT jacobians[num_idx]; + + // Setup the DLEQ proof. + EC_SCALAR ks0, ks1; + if (// ks0, ks1 <- Zp + !ec_random_nonzero_scalar(group, &ks0, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(group, &ks1, kDefaultAdditionalData) || + // Ks = ks0*(G;T) + ks1*(H;S) + !ec_point_mul_scalar_precomp(group, &jacobians[idx_Ks0], + &method->g_precomp, &ks0, &method->h_precomp, + &ks1, NULL, NULL) || + !ec_point_mul_scalar_batch(group, &jacobians[idx_Ks1], T, &ks0, S, &ks1, + NULL, NULL)) { + return 0; + } + + // Setup the DLEQOR proof. First, select values of xb, yb (keys corresponding + // to the private metadata value) and pubo (public key corresponding to the + // other value) in constant time. + BN_ULONG mask = ((BN_ULONG)0) - (private_metadata & 1); + EC_PRECOMP pubo_precomp; + EC_SCALAR xb, yb; + ec_scalar_select(group, &xb, mask, &priv->x1, &priv->x0); + ec_scalar_select(group, &yb, mask, &priv->y1, &priv->y0); + ec_precomp_select(group, &pubo_precomp, mask, &priv->pub0_precomp, + &priv->pub1_precomp); + + EC_SCALAR k0, k1, minus_co, uo, vo; + if (// k0, k1 <- Zp + !ec_random_nonzero_scalar(group, &k0, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(group, &k1, kDefaultAdditionalData) || + // Kb = k0*(G;T) + k1*(H;S) + !ec_point_mul_scalar_precomp(group, &jacobians[idx_Kb0], + &method->g_precomp, &k0, &method->h_precomp, + &k1, NULL, NULL) || + !ec_point_mul_scalar_batch(group, &jacobians[idx_Kb1], T, &k0, S, &k1, + NULL, NULL) || + // co, uo, vo <- Zp + !ec_random_nonzero_scalar(group, &minus_co, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(group, &uo, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(group, &vo, kDefaultAdditionalData) || + // Ko = uo*(G;T) + vo*(H;S) - co*(pubo;W) + !ec_point_mul_scalar_precomp(group, &jacobians[idx_Ko0], + &method->g_precomp, &uo, &method->h_precomp, + &vo, &pubo_precomp, &minus_co) || + !ec_point_mul_scalar_batch(group, &jacobians[idx_Ko1], T, &uo, S, &vo, W, + &minus_co)) { + return 0; + } + + EC_AFFINE affines[num_idx]; + jacobians[idx_T] = *T; + jacobians[idx_S] = *S; + jacobians[idx_W] = *W; + jacobians[idx_Ws] = *Ws; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + // Select the K corresponding to K0 and K1 in constant-time. + EC_AFFINE K00, K01, K10, K11; + ec_affine_select(group, &K00, mask, &affines[idx_Ko0], &affines[idx_Kb0]); + ec_affine_select(group, &K01, mask, &affines[idx_Ko1], &affines[idx_Kb1]); + ec_affine_select(group, &K10, mask, &affines[idx_Kb0], &affines[idx_Ko0]); + ec_affine_select(group, &K11, mask, &affines[idx_Kb1], &affines[idx_Ko1]); + + // Compute c = Hc(...) for the two proofs. + EC_SCALAR cs, c; + if (!hash_c_dleq(method, &cs, &priv->pubs, &affines[idx_T], &affines[idx_S], + &affines[idx_Ws], &affines[idx_Ks0], &affines[idx_Ks1]) || + !hash_c_dleqor(method, &c, &priv->pub0, &priv->pub1, &affines[idx_T], + &affines[idx_S], &affines[idx_W], &K00, &K01, &K10, + &K11)) { + return 0; + } + + // Compute cb, ub, and ub for the two proofs. In each of these products, only + // one operand is in Montgomery form, so the product does not need to be + // converted. + + EC_SCALAR cs_mont; + ec_scalar_to_montgomery(group, &cs_mont, &cs); + + // us = ks0 + cs*xs + EC_SCALAR us, vs; + ec_scalar_mul_montgomery(group, &us, &priv->xs, &cs_mont); + ec_scalar_add(group, &us, &ks0, &us); + + // vs = ks1 + cs*ys + ec_scalar_mul_montgomery(group, &vs, &priv->ys, &cs_mont); + ec_scalar_add(group, &vs, &ks1, &vs); + + // Store DLEQ2 proof in transcript. + if (!scalar_to_cbb(cbb, group, &cs) || + !scalar_to_cbb(cbb, group, &us) || + !scalar_to_cbb(cbb, group, &vs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + + // cb = c - co + EC_SCALAR cb, ub, vb; + ec_scalar_add(group, &cb, &c, &minus_co); + + EC_SCALAR cb_mont; + ec_scalar_to_montgomery(group, &cb_mont, &cb); + + // ub = k0 + cb*xb + ec_scalar_mul_montgomery(group, &ub, &xb, &cb_mont); + ec_scalar_add(group, &ub, &k0, &ub); + + // vb = k1 + cb*yb + ec_scalar_mul_montgomery(group, &vb, &yb, &cb_mont); + ec_scalar_add(group, &vb, &k1, &vb); + + // Select c, u, v in constant-time. + EC_SCALAR co, c0, c1, u0, u1, v0, v1; + ec_scalar_neg(group, &co, &minus_co); + ec_scalar_select(group, &c0, mask, &co, &cb); + ec_scalar_select(group, &u0, mask, &uo, &ub); + ec_scalar_select(group, &v0, mask, &vo, &vb); + ec_scalar_select(group, &c1, mask, &cb, &co); + ec_scalar_select(group, &u1, mask, &ub, &uo); + ec_scalar_select(group, &v1, mask, &vb, &vo); + + // Store DLEQOR2 proof in transcript. + if (!scalar_to_cbb(cbb, group, &c0) || + !scalar_to_cbb(cbb, group, &c1) || + !scalar_to_cbb(cbb, group, &u0) || + !scalar_to_cbb(cbb, group, &u1) || + !scalar_to_cbb(cbb, group, &v0) || + !scalar_to_cbb(cbb, group, &v1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +static int dleq_verify(const PMBTOKEN_METHOD *method, CBS *cbs, + const TRUST_TOKEN_CLIENT_KEY *pub, const EC_RAW_POINT *T, + const EC_RAW_POINT *S, const EC_RAW_POINT *W, + const EC_RAW_POINT *Ws) { + const EC_GROUP *group = method->group; + const EC_RAW_POINT *g = &group->generator->raw; + + // We verify a DLEQ proof for the validity token and a DLEQOR2 proof for the + // private metadata token. To allow amortizing Jacobian-to-affine conversions, + // we compute Ki for both proofs first. Additionally, all inputs to this + // function are public, so we can use the faster variable-time + // multiplications. + enum { + idx_T, + idx_S, + idx_W, + idx_Ws, + idx_Ks0, + idx_Ks1, + idx_K00, + idx_K01, + idx_K10, + idx_K11, + num_idx, + }; + EC_RAW_POINT jacobians[num_idx]; + + // Decode the DLEQ proof. + EC_SCALAR cs, us, vs; + if (!scalar_from_cbs(cbs, group, &cs) || + !scalar_from_cbs(cbs, group, &us) || + !scalar_from_cbs(cbs, group, &vs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + // Ks = us*(G;T) + vs*(H;S) - cs*(pubs;Ws) + EC_RAW_POINT pubs; + ec_affine_to_jacobian(group, &pubs, &pub->pubs); + EC_SCALAR minus_cs; + ec_scalar_neg(group, &minus_cs, &cs); + if (!mul_public_3(group, &jacobians[idx_Ks0], g, &us, &method->h, &vs, &pubs, + &minus_cs) || + !mul_public_3(group, &jacobians[idx_Ks1], T, &us, S, &vs, Ws, + &minus_cs)) { + return 0; + } + + // Decode the DLEQOR proof. + EC_SCALAR c0, c1, u0, u1, v0, v1; + if (!scalar_from_cbs(cbs, group, &c0) || + !scalar_from_cbs(cbs, group, &c1) || + !scalar_from_cbs(cbs, group, &u0) || + !scalar_from_cbs(cbs, group, &u1) || + !scalar_from_cbs(cbs, group, &v0) || + !scalar_from_cbs(cbs, group, &v1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + EC_RAW_POINT pub0, pub1; + ec_affine_to_jacobian(group, &pub0, &pub->pub0); + ec_affine_to_jacobian(group, &pub1, &pub->pub1); + EC_SCALAR minus_c0, minus_c1; + ec_scalar_neg(group, &minus_c0, &c0); + ec_scalar_neg(group, &minus_c1, &c1); + if (// K0 = u0*(G;T) + v0*(H;S) - c0*(pub0;W) + !mul_public_3(group, &jacobians[idx_K00], g, &u0, &method->h, &v0, &pub0, + &minus_c0) || + !mul_public_3(group, &jacobians[idx_K01], T, &u0, S, &v0, W, &minus_c0) || + // K1 = u1*(G;T) + v1*(H;S) - c1*(pub1;W) + !mul_public_3(group, &jacobians[idx_K10], g, &u1, &method->h, &v1, &pub1, + &minus_c1) || + !mul_public_3(group, &jacobians[idx_K11], T, &u1, S, &v1, W, &minus_c1)) { + return 0; + } + + EC_AFFINE affines[num_idx]; + jacobians[idx_T] = *T; + jacobians[idx_S] = *S; + jacobians[idx_W] = *W; + jacobians[idx_Ws] = *Ws; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + // Check the DLEQ proof. + EC_SCALAR calculated; + if (!hash_c_dleq(method, &calculated, &pub->pubs, &affines[idx_T], + &affines[idx_S], &affines[idx_Ws], &affines[idx_Ks0], + &affines[idx_Ks1])) { + return 0; + } + + // cs == calculated + if (!ec_scalar_equal_vartime(group, &cs, &calculated)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF); + return 0; + } + + // Check the DLEQOR proof. + if (!hash_c_dleqor(method, &calculated, &pub->pub0, &pub->pub1, + &affines[idx_T], &affines[idx_S], &affines[idx_W], + &affines[idx_K00], &affines[idx_K01], &affines[idx_K10], + &affines[idx_K11])) { + return 0; + } + + // c0 + c1 == calculated + EC_SCALAR c; + ec_scalar_add(group, &c, &c0, &c1); + if (!ec_scalar_equal_vartime(group, &c, &calculated)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF); + return 0; + } + + return 1; +} + +static int pmbtoken_sign(const PMBTOKEN_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + const EC_GROUP *group = method->group; + if (num_requested < num_to_issue) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || + num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + + int ret = 0; + EC_RAW_POINT *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); + CBB batch_cbb; + CBB_zero(&batch_cbb); + if (!Tps || + !Sps || + !Wps || + !Wsps || + !es || + !CBB_init(&batch_cbb, 0) || + !point_to_cbb(&batch_cbb, method->group, &key->pubs) || + !point_to_cbb(&batch_cbb, method->group, &key->pub0) || + !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < num_to_issue; i++) { + EC_AFFINE Tp_affine; + EC_RAW_POINT Tp; + if (!cbs_get_prefixed_point(cbs, group, &Tp_affine, method->prefix_point)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + ec_affine_to_jacobian(group, &Tp, &Tp_affine); + + EC_SCALAR xb, yb; + BN_ULONG mask = ((BN_ULONG)0) - (private_metadata & 1); + ec_scalar_select(group, &xb, mask, &key->x1, &key->x0); + ec_scalar_select(group, &yb, mask, &key->y1, &key->y0); + + uint8_t s[TRUST_TOKEN_NONCE_SIZE]; + RAND_bytes(s, TRUST_TOKEN_NONCE_SIZE); + // The |jacobians| and |affines| contain Sp, Wp, and Wsp. + EC_RAW_POINT jacobians[3]; + EC_AFFINE affines[3]; + if (!method->hash_s(group, &jacobians[0], &Tp_affine, s) || + !ec_point_mul_scalar_batch(group, &jacobians[1], &Tp, &xb, + &jacobians[0], &yb, NULL, NULL) || + !ec_point_mul_scalar_batch(group, &jacobians[2], &Tp, &key->xs, + &jacobians[0], &key->ys, NULL, NULL) || + !ec_jacobian_to_affine_batch(group, affines, jacobians, 3) || + !CBB_add_bytes(cbb, s, TRUST_TOKEN_NONCE_SIZE) || + !cbb_add_prefixed_point(cbb, group, &affines[1], + method->prefix_point) || + !cbb_add_prefixed_point(cbb, group, &affines[2], + method->prefix_point)) { + goto err; + } + + if (!point_to_cbb(&batch_cbb, group, &Tp_affine) || + !point_to_cbb(&batch_cbb, group, &affines[0]) || + !point_to_cbb(&batch_cbb, group, &affines[1]) || + !point_to_cbb(&batch_cbb, group, &affines[2])) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + Tps[i] = Tp; + Sps[i] = jacobians[0]; + Wps[i] = jacobians[1]; + Wsps[i] = jacobians[2]; + + if (!CBB_flush(cbb)) { + goto err; + } + } + + // The DLEQ batching construction is described in appendix B of + // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional + // computations all act on public inputs. + for (size_t i = 0; i < num_to_issue; i++) { + if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { + goto err; + } + } + + EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, + /*g_scalar=*/NULL, Tps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Sp_batch, + /*g_scalar=*/NULL, Sps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Wp_batch, + /*g_scalar=*/NULL, Wps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Wsp_batch, + /*g_scalar=*/NULL, Wsps, es, + num_to_issue)) { + goto err; + } + + CBB proof; + if (!CBB_add_u16_length_prefixed(cbb, &proof) || + !dleq_generate(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, + &Wsp_batch, private_metadata) || + !CBB_flush(cbb)) { + goto err; + } + + // Skip over any unused requests. + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + size_t token_len = point_len; + if (method->prefix_point) { + token_len += 2; + } + if (!CBS_skip(cbs, token_len * (num_requested - num_to_issue))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(Tps); + OPENSSL_free(Sps); + OPENSSL_free(Wps); + OPENSSL_free(Wsps); + OPENSSL_free(es); + CBB_cleanup(&batch_cbb); + return ret; +} + +static STACK_OF(TRUST_TOKEN) * + pmbtoken_unblind(const PMBTOKEN_METHOD *method, + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, + size_t count, uint32_t key_id) { + const EC_GROUP *group = method->group; + if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return NULL; + } + + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + EC_RAW_POINT *Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); + CBB batch_cbb; + CBB_zero(&batch_cbb); + if (!Tps || + !Sps || + !Wps || + !Wsps || + !es || + !CBB_init(&batch_cbb, 0) || + !point_to_cbb(&batch_cbb, method->group, &key->pubs) || + !point_to_cbb(&batch_cbb, method->group, &key->pub0) || + !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < count; i++) { + const TRUST_TOKEN_PRETOKEN *pretoken = + sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i); + + uint8_t s[TRUST_TOKEN_NONCE_SIZE]; + EC_AFFINE Wp_affine, Wsp_affine; + if (!CBS_copy_bytes(cbs, s, TRUST_TOKEN_NONCE_SIZE) || + !cbs_get_prefixed_point(cbs, group, &Wp_affine, method->prefix_point) || + !cbs_get_prefixed_point(cbs, group, &Wsp_affine, + method->prefix_point)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ec_affine_to_jacobian(group, &Tps[i], &pretoken->Tp); + ec_affine_to_jacobian(group, &Wps[i], &Wp_affine); + ec_affine_to_jacobian(group, &Wsps[i], &Wsp_affine); + if (!method->hash_s(group, &Sps[i], &pretoken->Tp, s)) { + goto err; + } + + EC_AFFINE Sp_affine; + if (!point_to_cbb(&batch_cbb, group, &pretoken->Tp) || + !ec_jacobian_to_affine(group, &Sp_affine, &Sps[i]) || + !point_to_cbb(&batch_cbb, group, &Sp_affine) || + !point_to_cbb(&batch_cbb, group, &Wp_affine) || + !point_to_cbb(&batch_cbb, group, &Wsp_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // Unblind the token. + EC_RAW_POINT jacobians[3]; + EC_AFFINE affines[3]; + if (!ec_point_mul_scalar(group, &jacobians[0], &Sps[i], &pretoken->r) || + !ec_point_mul_scalar(group, &jacobians[1], &Wps[i], &pretoken->r) || + !ec_point_mul_scalar(group, &jacobians[2], &Wsps[i], &pretoken->r) || + !ec_jacobian_to_affine_batch(group, affines, jacobians, 3)) { + goto err; + } + + // Serialize the token. Include |key_id| to avoid an extra copy in the layer + // above. + CBB token_cbb; + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + if (!CBB_init(&token_cbb, + 4 + TRUST_TOKEN_NONCE_SIZE + 3 * (2 + point_len)) || + !CBB_add_u32(&token_cbb, key_id) || + !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !cbb_add_prefixed_point(&token_cbb, group, &affines[0], + method->prefix_point) || + !cbb_add_prefixed_point(&token_cbb, group, &affines[1], + method->prefix_point) || + !cbb_add_prefixed_point(&token_cbb, group, &affines[2], + method->prefix_point) || + !CBB_flush(&token_cbb)) { + CBB_cleanup(&token_cbb); + goto err; + } + + TRUST_TOKEN *token = + TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb)); + CBB_cleanup(&token_cbb); + if (token == NULL || + !sk_TRUST_TOKEN_push(ret, token)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + TRUST_TOKEN_free(token); + goto err; + } + } + + // The DLEQ batching construction is described in appendix B of + // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional + // computations all act on public inputs. + for (size_t i = 0; i < count; i++) { + if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { + goto err; + } + } + + EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, + /*g_scalar=*/NULL, Tps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Sp_batch, + /*g_scalar=*/NULL, Sps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Wp_batch, + /*g_scalar=*/NULL, Wps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Wsp_batch, + /*g_scalar=*/NULL, Wsps, es, count)) { + goto err; + } + + CBS proof; + if (!CBS_get_u16_length_prefixed(cbs, &proof) || + !dleq_verify(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, + &Wsp_batch) || + CBS_len(&proof) != 0) { + goto err; + } + + ok = 1; + +err: + OPENSSL_free(Tps); + OPENSSL_free(Sps); + OPENSSL_free(Wps); + OPENSSL_free(Wsps); + OPENSSL_free(es); + CBB_cleanup(&batch_cbb); + if (!ok) { + sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free); + ret = NULL; + } + return ret; +} + +static int pmbtoken_read(const PMBTOKEN_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len) { + const EC_GROUP *group = method->group; + CBS cbs; + CBS_init(&cbs, token, token_len); + EC_AFFINE S, W, Ws; + if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + !cbs_get_prefixed_point(&cbs, group, &S, method->prefix_point) || + !cbs_get_prefixed_point(&cbs, group, &W, method->prefix_point) || + !cbs_get_prefixed_point(&cbs, group, &Ws, method->prefix_point) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + + EC_RAW_POINT T; + if (!method->hash_t(group, &T, out_nonce)) { + return 0; + } + + // We perform three multiplications with S and T. This is enough that it is + // worth using |ec_point_mul_scalar_precomp|. + EC_RAW_POINT S_jacobian; + EC_PRECOMP S_precomp, T_precomp; + ec_affine_to_jacobian(group, &S_jacobian, &S); + if (!ec_init_precomp(group, &S_precomp, &S_jacobian) || + !ec_init_precomp(group, &T_precomp, &T)) { + return 0; + } + + EC_RAW_POINT Ws_calculated; + // Check the validity of the token. + if (!ec_point_mul_scalar_precomp(group, &Ws_calculated, &T_precomp, &key->xs, + &S_precomp, &key->ys, NULL, NULL) || + !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK); + return 0; + } + + EC_RAW_POINT W0, W1; + if (!ec_point_mul_scalar_precomp(group, &W0, &T_precomp, &key->x0, &S_precomp, + &key->y0, NULL, NULL) || + !ec_point_mul_scalar_precomp(group, &W1, &T_precomp, &key->x1, &S_precomp, + &key->y1, NULL, NULL)) { + return 0; + } + + const int is_W0 = ec_affine_jacobian_equal(group, &W, &W0); + const int is_W1 = ec_affine_jacobian_equal(group, &W, &W1); + const int is_valid = is_W0 ^ is_W1; + if (!is_valid) { + // Invalid tokens will fail the validity check above. + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out_private_metadata = is_W1; + return 1; +} + + +// PMBTokens experiment v1. + +static int pmbtoken_exp1_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "PMBTokens Experiment V1 HashT"; + return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int pmbtoken_exp1_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *t, + const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashSLabel[] = "PMBTokens Experiment V1 HashS"; + int ret = 0; + CBB cbb; + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !point_to_cbb(&cbb, group, t) || + !CBB_add_bytes(&cbb, s, TRUST_TOKEN_NONCE_SIZE) || + !CBB_finish(&cbb, &buf, &len) || + !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + CBB_cleanup(&cbb); + return ret; +} + +static int pmbtoken_exp1_hash_c(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "PMBTokens Experiment V1 HashC"; + return ec_hash_to_scalar_p384_xmd_sha512_draft07( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int pmbtoken_exp1_ok = 0; +static PMBTOKEN_METHOD pmbtoken_exp1_method; +static CRYPTO_once_t pmbtoken_exp1_method_once = CRYPTO_ONCE_INIT; + +static void pmbtoken_exp1_init_method_impl(void) { + // This is the output of |ec_hash_to_scalar_p384_xmd_sha512_draft07| with DST + // "PMBTokens Experiment V1 HashH" and message "generator". + static const uint8_t kH[] = { + 0x04, 0x82, 0xd5, 0x68, 0xf5, 0x39, 0xf6, 0x08, 0x19, 0xa1, 0x75, + 0x9f, 0x98, 0xb5, 0x10, 0xf5, 0x0b, 0x9d, 0x2b, 0xe1, 0x64, 0x4d, + 0x02, 0x76, 0x18, 0x11, 0xf8, 0x2f, 0xd3, 0x33, 0x25, 0x1f, 0x2c, + 0xb8, 0xf6, 0xf1, 0x9e, 0x93, 0x85, 0x79, 0xb3, 0xb7, 0x81, 0xa3, + 0xe6, 0x23, 0xc3, 0x1c, 0xff, 0x03, 0xd9, 0x40, 0x6c, 0xec, 0xe0, + 0x4d, 0xea, 0xdf, 0x9d, 0x94, 0xd1, 0x87, 0xab, 0x27, 0xf7, 0x4f, + 0x53, 0xea, 0xa3, 0x18, 0x72, 0xb9, 0xd1, 0x56, 0xa0, 0x4e, 0x81, + 0xaa, 0xeb, 0x1c, 0x22, 0x6d, 0x39, 0x1c, 0x5e, 0xb1, 0x27, 0xfc, + 0x87, 0xc3, 0x95, 0xd0, 0x13, 0xb7, 0x0b, 0x5c, 0xc7, + }; + + pmbtoken_exp1_ok = + pmbtoken_init_method(&pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s, + pmbtoken_exp1_hash_c, 1); +} + +static int pmbtoken_exp1_init_method(void) { + CRYPTO_once(&pmbtoken_exp1_method_once, pmbtoken_exp1_init_method_impl); + if (!pmbtoken_exp1_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int pmbtoken_exp1_generate_key(CBB *out_private, CBB *out_public) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + + return pmbtoken_generate_key(&pmbtoken_exp1_method, out_private, out_public); +} + +int pmbtoken_exp1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + return pmbtoken_client_key_from_bytes(&pmbtoken_exp1_method, key, in, len); +} + +int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp1_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count) { + if (!pmbtoken_exp1_init_method()) { + return NULL; + } + return pmbtoken_blind(&pmbtoken_exp1_method, cbb, count); +} + +int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + return pmbtoken_sign(&pmbtoken_exp1_method, key, cbb, cbs, num_requested, + num_to_issue, private_metadata); +} + +STACK_OF(TRUST_TOKEN) * + pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id) { + if (!pmbtoken_exp1_init_method()) { + return NULL; + } + return pmbtoken_unblind(&pmbtoken_exp1_method, key, pretokens, cbs, count, + key_id); +} + +int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + return pmbtoken_read(&pmbtoken_exp1_method, key, out_nonce, + out_private_metadata, token, token_len); +} + +int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + EC_AFFINE h; + return ec_jacobian_to_affine(pmbtoken_exp1_method.group, &h, + &pmbtoken_exp1_method.h) && + ec_point_to_bytes(pmbtoken_exp1_method.group, &h, + POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; +} + +// PMBTokens experiment v2. + +static int pmbtoken_exp2_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "PMBTokens Experiment V2 HashT"; + return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int pmbtoken_exp2_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_AFFINE *t, + const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashSLabel[] = "PMBTokens Experiment V2 HashS"; + int ret = 0; + CBB cbb; + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !point_to_cbb(&cbb, group, t) || + !CBB_add_bytes(&cbb, s, TRUST_TOKEN_NONCE_SIZE) || + !CBB_finish(&cbb, &buf, &len) || + !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + CBB_cleanup(&cbb); + return ret; +} + +static int pmbtoken_exp2_hash_c(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "PMBTokens Experiment V2 HashC"; + return ec_hash_to_scalar_p384_xmd_sha512_draft07( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int pmbtoken_exp2_ok = 0; +static PMBTOKEN_METHOD pmbtoken_exp2_method; +static CRYPTO_once_t pmbtoken_exp2_method_once = CRYPTO_ONCE_INIT; + +static void pmbtoken_exp2_init_method_impl(void) { + // This is the output of |ec_hash_to_scalar_p384_xmd_sha512_draft07| with DST + // "PMBTokens Experiment V2 HashH" and message "generator". + static const uint8_t kH[] = { + 0x04, 0xbc, 0x27, 0x24, 0x99, 0xfa, 0xc9, 0xa4, 0x74, 0x6f, 0xf9, + 0x07, 0x81, 0x55, 0xf8, 0x1f, 0x6f, 0xda, 0x09, 0xe7, 0x8c, 0x5d, + 0x9e, 0x4e, 0x14, 0x7c, 0x53, 0x14, 0xbc, 0x7e, 0x29, 0x57, 0x92, + 0x17, 0x94, 0x6e, 0xd2, 0xdf, 0xa5, 0x31, 0x1b, 0x4e, 0xb7, 0xfc, + 0x93, 0xe3, 0x6e, 0x14, 0x1f, 0x4f, 0x14, 0xf3, 0xe5, 0x47, 0x61, + 0x1c, 0x2c, 0x72, 0x25, 0xf0, 0x4a, 0x45, 0x23, 0x2d, 0x57, 0x93, + 0x0e, 0xb2, 0x55, 0xb8, 0x57, 0x25, 0x4c, 0x1e, 0xdb, 0xfd, 0x58, + 0x70, 0x17, 0x9a, 0xbb, 0x9e, 0x5e, 0x93, 0x9e, 0x92, 0xd3, 0xe8, + 0x25, 0x62, 0xbf, 0x59, 0xb2, 0xd2, 0x3d, 0x71, 0xff + }; + + pmbtoken_exp2_ok = + pmbtoken_init_method(&pmbtoken_exp2_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_exp2_hash_t, pmbtoken_exp2_hash_s, + pmbtoken_exp2_hash_c, 0); +} + +static int pmbtoken_exp2_init_method(void) { + CRYPTO_once(&pmbtoken_exp2_method_once, pmbtoken_exp2_init_method_impl); + if (!pmbtoken_exp2_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int pmbtoken_exp2_generate_key(CBB *out_private, CBB *out_public) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + + return pmbtoken_generate_key(&pmbtoken_exp2_method, out_private, out_public); +} + +int pmbtoken_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + return pmbtoken_client_key_from_bytes(&pmbtoken_exp2_method, key, in, len); +} + +int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp2_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count) { + if (!pmbtoken_exp2_init_method()) { + return NULL; + } + return pmbtoken_blind(&pmbtoken_exp2_method, cbb, count); +} + +int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + return pmbtoken_sign(&pmbtoken_exp2_method, key, cbb, cbs, num_requested, + num_to_issue, private_metadata); +} + +STACK_OF(TRUST_TOKEN) * + pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id) { + if (!pmbtoken_exp2_init_method()) { + return NULL; + } + return pmbtoken_unblind(&pmbtoken_exp2_method, key, pretokens, cbs, count, + key_id); +} + +int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + return pmbtoken_read(&pmbtoken_exp2_method, key, out_nonce, + out_private_metadata, token, token_len); +} + +int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + EC_AFFINE h; + return ec_jacobian_to_affine(pmbtoken_exp2_method.group, &h, + &pmbtoken_exp2_method.h) && + ec_point_to_bytes(pmbtoken_exp2_method.group, &h, + POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c new file mode 100644 index 00000000..09db6c03 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c @@ -0,0 +1,858 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +// The Trust Token API is described in +// https://github.com/WICG/trust-token-api/blob/master/README.md and provides a +// protocol for issuing and redeeming tokens built on top of the PMBTokens +// construction. + +const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) { + static const TRUST_TOKEN_METHOD kMethod = { + pmbtoken_exp1_generate_key, + pmbtoken_exp1_client_key_from_bytes, + pmbtoken_exp1_issuer_key_from_bytes, + pmbtoken_exp1_blind, + pmbtoken_exp1_sign, + pmbtoken_exp1_unblind, + pmbtoken_exp1_read, + 1, /* has_private_metadata */ + 3, /* max_keys */ + 1, /* has_srr */ + }; + return &kMethod; +} + +const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) { + static const TRUST_TOKEN_METHOD kMethod = { + voprf_exp2_generate_key, + voprf_exp2_client_key_from_bytes, + voprf_exp2_issuer_key_from_bytes, + voprf_exp2_blind, + voprf_exp2_sign, + voprf_exp2_unblind, + voprf_exp2_read, + 0, /* has_private_metadata */ + 6, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + +const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) { + static const TRUST_TOKEN_METHOD kMethod = { + pmbtoken_exp2_generate_key, + pmbtoken_exp2_client_key_from_bytes, + pmbtoken_exp2_issuer_key_from_bytes, + pmbtoken_exp2_blind, + pmbtoken_exp2_sign, + pmbtoken_exp2_unblind, + pmbtoken_exp2_read, + 1, /* has_private_metadata */ + 3, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + +void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) { + OPENSSL_free(pretoken); +} + +TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) { + TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN)); + ret->data = OPENSSL_memdup(data, len); + if (len != 0 && ret->data == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + ret->len = len; + return ret; +} + +void TRUST_TOKEN_free(TRUST_TOKEN *token) { + if (token == NULL) { + return; + } + OPENSSL_free(token->data); + OPENSSL_free(token); +} + +int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method, + uint8_t *out_priv_key, size_t *out_priv_key_len, + size_t max_priv_key_len, uint8_t *out_pub_key, + size_t *out_pub_key_len, size_t max_pub_key_len, + uint32_t id) { + // Prepend the key ID in front of the PMBTokens format. + int ret = 0; + CBB priv_cbb, pub_cbb; + CBB_zero(&priv_cbb); + CBB_zero(&pub_cbb); + if (!CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len) || + !CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len) || + !CBB_add_u32(&priv_cbb, id) || + !CBB_add_u32(&pub_cbb, id)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + goto err; + } + + if (!method->generate_key(&priv_cbb, &pub_cbb)) { + goto err; + } + + if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) || + !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + goto err; + } + + ret = 1; + +err: + CBB_cleanup(&priv_cbb); + CBB_cleanup(&pub_cbb); + return ret; +} + +TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, + size_t max_batchsize) { + if (max_batchsize > 0xffff) { + // The protocol supports only two-byte token counts. + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return NULL; + } + + TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT)); + ret->method = method; + ret->max_batchsize = (uint16_t)max_batchsize; + return ret; +} + +void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) { + if (ctx == NULL) { + return; + } + EVP_PKEY_free(ctx->srr_key); + sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free); + OPENSSL_free(ctx); +} + +int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, + const uint8_t *key, size_t key_len) { + if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + ctx->num_keys >= ctx->method->max_keys) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); + return 0; + } + + struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys]; + CBS cbs; + CBS_init(&cbs, key, key_len); + uint32_t key_id; + if (!CBS_get_u32(&cbs, &key_id) || + !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs), + CBS_len(&cbs))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + key_s->id = key_id; + *out_key_index = ctx->num_keys; + ctx->num_keys += 1; + return 1; +} + +int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) { + if (!ctx->method->has_srr) { + return 1; + } + EVP_PKEY_free(ctx->srr_key); + EVP_PKEY_up_ref(key); + ctx->srr_key = key; + return 1; +} + +int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, + size_t *out_len, size_t count) { + if (count > ctx->max_batchsize) { + count = ctx->max_batchsize; + } + + int ret = 0; + CBB request; + STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL; + if (!CBB_init(&request, 0) || + !CBB_add_u16(&request, count)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + pretokens = ctx->method->blind(&request, count); + if (pretokens == NULL) { + goto err; + } + + if (!CBB_finish(&request, out, out_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free); + ctx->pretokens = pretokens; + pretokens = NULL; + ret = 1; + +err: + CBB_cleanup(&request); + sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free); + return ret; +} + +STACK_OF(TRUST_TOKEN) * + TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx, + size_t *out_key_index, + const uint8_t *response, + size_t response_len) { + CBS in; + CBS_init(&in, response, response_len); + uint16_t count; + uint32_t key_id; + if (!CBS_get_u16(&in, &count) || + !CBS_get_u32(&in, &key_id)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return NULL; + } + + size_t key_index = 0; + const struct trust_token_client_key_st *key = NULL; + for (size_t i = 0; i < ctx->num_keys; i++) { + if (ctx->keys[i].id == key_id) { + key_index = i; + key = &ctx->keys[i]; + break; + } + } + + if (key == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID); + return NULL; + } + + if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return NULL; + } + + STACK_OF(TRUST_TOKEN) *tokens = + ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id); + if (tokens == NULL) { + return NULL; + } + + if (CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free); + return NULL; + } + + sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free); + ctx->pretokens = NULL; + + *out_key_index = key_index; + return tokens; +} + +int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, + size_t *out_len, + const TRUST_TOKEN *token, + const uint8_t *data, size_t data_len, + uint64_t time) { + CBB request, token_inner, inner; + if (!CBB_init(&request, 0) || + !CBB_add_u16_length_prefixed(&request, &token_inner) || + !CBB_add_bytes(&token_inner, token->data, token->len) || + !CBB_add_u16_length_prefixed(&request, &inner) || + !CBB_add_bytes(&inner, data, data_len) || + (ctx->method->has_srr && !CBB_add_u64(&request, time)) || + !CBB_finish(&request, out, out_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + CBB_cleanup(&request); + return 0; + } + return 1; +} + +int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx, + uint8_t **out_rr, size_t *out_rr_len, + uint8_t **out_sig, size_t *out_sig_len, + const uint8_t *response, + size_t response_len) { + CBS in, srr, sig; + CBS_init(&in, response, response_len); + if (!ctx->method->has_srr) { + if (!CBS_stow(&in, out_rr, out_rr_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + + *out_sig = NULL; + *out_sig_len = 0; + return 1; + } + + if (!CBS_get_u16_length_prefixed(&in, &srr) || + !CBS_get_u16_length_prefixed(&in, &sig) || + CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); + return 0; + } + + if (ctx->srr_key == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED); + return 0; + } + + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) && + EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig), + CBS_data(&srr), CBS_len(&srr)); + EVP_MD_CTX_cleanup(&md_ctx); + + if (!sig_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR); + return 0; + } + + uint8_t *srr_buf = NULL, *sig_buf = NULL; + size_t srr_len, sig_len; + if (!CBS_stow(&srr, &srr_buf, &srr_len) || + !CBS_stow(&sig, &sig_buf, &sig_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + OPENSSL_free(srr_buf); + OPENSSL_free(sig_buf); + return 0; + } + + *out_rr = srr_buf; + *out_rr_len = srr_len; + *out_sig = sig_buf; + *out_sig_len = sig_len; + return 1; +} + +TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method, + size_t max_batchsize) { + if (max_batchsize > 0xffff) { + // The protocol supports only two-byte token counts. + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return NULL; + } + + TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER)); + ret->method = method; + ret->max_batchsize = (uint16_t)max_batchsize; + return ret; +} + +void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) { + if (ctx == NULL) { + return; + } + EVP_PKEY_free(ctx->srr_key); + OPENSSL_free(ctx->metadata_key); + OPENSSL_free(ctx); +} + +int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key, + size_t key_len) { + if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + ctx->num_keys >= ctx->method->max_keys) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); + return 0; + } + + struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys]; + CBS cbs; + CBS_init(&cbs, key, key_len); + uint32_t key_id; + if (!CBS_get_u32(&cbs, &key_id) || + !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs), + CBS_len(&cbs))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + key_s->id = key_id; + ctx->num_keys += 1; + return 1; +} + +int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) { + EVP_PKEY_free(ctx->srr_key); + EVP_PKEY_up_ref(key); + ctx->srr_key = key; + return 1; +} + +int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx, + const uint8_t *key, size_t len) { + if (len < 32) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY); + } + OPENSSL_free(ctx->metadata_key); + ctx->metadata_key_len = 0; + ctx->metadata_key = OPENSSL_memdup(key, len); + if (ctx->metadata_key == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->metadata_key_len = len; + return 1; +} + +static const struct trust_token_issuer_key_st *trust_token_issuer_get_key( + const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) { + for (size_t i = 0; i < ctx->num_keys; i++) { + if (ctx->keys[i].id == key_id) { + return &ctx->keys[i]; + } + } + return NULL; +} + +int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, + size_t *out_len, size_t *out_tokens_issued, + const uint8_t *request, size_t request_len, + uint32_t public_metadata, uint8_t private_metadata, + size_t max_issuance) { + if (max_issuance > ctx->max_batchsize) { + max_issuance = ctx->max_batchsize; + } + + const struct trust_token_issuer_key_st *key = + trust_token_issuer_get_key(ctx, public_metadata); + if (key == NULL || private_metadata > 1 || + (!ctx->method->has_private_metadata && private_metadata != 0)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA); + return 0; + } + + CBS in; + uint16_t num_requested; + CBS_init(&in, request, request_len); + if (!CBS_get_u16(&in, &num_requested)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + size_t num_to_issue = num_requested; + if (num_to_issue > max_issuance) { + num_to_issue = max_issuance; + } + + int ret = 0; + CBB response; + if (!CBB_init(&response, 0) || + !CBB_add_u16(&response, num_to_issue) || + !CBB_add_u32(&response, public_metadata)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue, + private_metadata)) { + goto err; + } + + if (CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + if (!CBB_finish(&response, out, out_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + *out_tokens_issued = num_to_issue; + ret = 1; + +err: + CBB_cleanup(&response); + return ret; +} + + +int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, + uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, + uint8_t **out_client_data, + size_t *out_client_data_len, + const uint8_t *request, size_t request_len) { + CBS request_cbs, token_cbs; + CBS_init(&request_cbs, request, request_len); + if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); + return 0; + } + + uint32_t public_metadata = 0; + uint8_t private_metadata = 0; + + // Parse the token. If there is an error, treat it as an invalid token. + if (!CBS_get_u32(&token_cbs, &public_metadata)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + const struct trust_token_issuer_key_st *key = + trust_token_issuer_get_key(ctx, public_metadata); + uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; + if (key == NULL || + !ctx->method->read(&key->key, nonce, &private_metadata, + CBS_data(&token_cbs), CBS_len(&token_cbs))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + CBS client_data; + if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) || + (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) || + CBS_len(&request_cbs) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); + return 0; + } + + uint8_t *client_data_buf = NULL; + size_t client_data_len = 0; + if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); + if (token == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + *out_public = public_metadata; + *out_private = private_metadata; + *out_token = token; + *out_client_data = client_data_buf; + *out_client_data_len = client_data_len; + + return 1; + +err: + OPENSSL_free(client_data_buf); + return 0; +} + +// https://tools.ietf.org/html/rfc7049#section-2.1 +static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type, + uint64_t value) { + if (value <= 23) { + return CBB_add_u8(cbb, value | major_type); + } + if (value <= 0xff) { + return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value); + } + if (value <= 0xffff) { + return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value); + } + if (value <= 0xffffffff) { + return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value); + } + if (value <= 0xffffffffffffffff) { + return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value); + } + + return 0; +} + +// https://tools.ietf.org/html/rfc7049#section-2.1 +static int add_cbor_int(CBB *cbb, uint64_t value) { + return add_cbor_int_with_type(cbb, 0, value); +} + +// https://tools.ietf.org/html/rfc7049#section-2.1 +static int add_cbor_bytes(CBB *cbb, const uint8_t *data, size_t len) { + return add_cbor_int_with_type(cbb, 0x40, len) && + CBB_add_bytes(cbb, data, len); +} + +// https://tools.ietf.org/html/rfc7049#section-2.1 +static int add_cbor_text(CBB *cbb, const char *data, size_t len) { + return add_cbor_int_with_type(cbb, 0x60, len) && + CBB_add_bytes(cbb, (const uint8_t *)data, len); +} + +// https://tools.ietf.org/html/rfc7049#section-2.1 +static int add_cbor_map(CBB *cbb, uint8_t size) { + return add_cbor_int_with_type(cbb, 0xa0, size); +} + +static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len, + const uint8_t *client_data, + size_t client_data_len) { + uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, key, key_len); + SHA256_Update(&sha_ctx, client_data, client_data_len); + SHA256_Final(metadata_obfuscator, &sha_ctx); + return metadata_obfuscator[0] >> 7; +} + +int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, + size_t *out_len, TRUST_TOKEN **out_token, + uint8_t **out_client_data, + size_t *out_client_data_len, + uint64_t *out_redemption_time, + const uint8_t *request, size_t request_len, + uint64_t lifetime) { + CBS request_cbs, token_cbs; + CBS_init(&request_cbs, request, request_len); + if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); + return 0; + } + + uint32_t public_metadata = 0; + uint8_t private_metadata = 0; + + CBS token_copy = token_cbs; + + // Parse the token. If there is an error, treat it as an invalid token. + if (!CBS_get_u32(&token_cbs, &public_metadata)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + const struct trust_token_issuer_key_st *key = + trust_token_issuer_get_key(ctx, public_metadata); + uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; + if (key == NULL || + !ctx->method->read(&key->key, nonce, &private_metadata, + CBS_data(&token_cbs), CBS_len(&token_cbs))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + int ok = 0; + CBB response, srr; + uint8_t *srr_buf = NULL, *sig_buf = NULL, *client_data_buf = NULL; + size_t srr_len = 0, sig_len = 0, client_data_len = 0; + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + CBB_zero(&srr); + if (!CBB_init(&response, 0)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + CBS client_data; + uint64_t redemption_time = 0; + if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) || + (ctx->method->has_srr && !CBS_get_u64(&request_cbs, &redemption_time))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); + goto err; + } + + const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; + uint8_t token_hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); + SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy)); + SHA256_Final(token_hash, &sha_ctx); + + uint8_t metadata_obfuscator = get_metadata_obfuscator( + ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash)); + + // The SRR is constructed as per the format described in + // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5 + + // The V2 protocol is intended to be used with + // |TRUST_TOKEN_ISSUER_redeem_raw|. However, we temporarily support it with + // |TRUST_TOKEN_ISSUER_redeem| to ease the transition for existing issuer + // callers. Those callers' consumers currently expect an expiry-timestamp + // field, so we fill in a placeholder value. + // + // TODO(svaldez): After the existing issues have migrated to + // |TRUST_TOKEN_ISSUER_redeem_raw| remove this logic. + uint64_t expiry_time = 0; + if (ctx->method->has_srr) { + expiry_time = redemption_time + lifetime; + } + + static const char kClientDataLabel[] = "client-data"; + static const char kExpiryTimestampLabel[] = "expiry-timestamp"; + static const char kMetadataLabel[] = "metadata"; + static const char kPrivateLabel[] = "private"; + static const char kPublicLabel[] = "public"; + static const char kTokenHashLabel[] = "token-hash"; + + // CBOR requires map keys to be sorted by length then sorted lexically. + // https://tools.ietf.org/html/rfc7049#section-3.9 + assert(strlen(kMetadataLabel) < strlen(kTokenHashLabel)); + assert(strlen(kTokenHashLabel) < strlen(kClientDataLabel)); + assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel)); + assert(strlen(kPublicLabel) < strlen(kPrivateLabel)); + + size_t map_entries = 4; + + if (!CBB_init(&srr, 0) || + !add_cbor_map(&srr, map_entries) || // SRR map + !add_cbor_text(&srr, kMetadataLabel, strlen(kMetadataLabel)) || + !add_cbor_map(&srr, 2) || // Metadata map + !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) || + !add_cbor_int(&srr, public_metadata) || + !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) || + !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) || + !add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) || + !add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) || + !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) || + !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) || + !add_cbor_text(&srr, kExpiryTimestampLabel, + strlen(kExpiryTimestampLabel)) || + !add_cbor_int(&srr, expiry_time) || + !CBB_finish(&srr, &srr_buf, &srr_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSignInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) || + !EVP_DigestSign(&md_ctx, NULL, &sig_len, srr_buf, srr_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR); + goto err; + } + + // Merge SRR and Signature into single string. + // TODO(svaldez): Expose API to construct this from the caller. + if (!ctx->method->has_srr) { + static const char kSRRHeader[] = "body=:"; + static const char kSRRSplit[] = ":, signature=:"; + static const char kSRREnd[] = ":"; + + size_t srr_b64_len, sig_b64_len; + if (!EVP_EncodedLength(&srr_b64_len, srr_len) || + !EVP_EncodedLength(&sig_b64_len, sig_len)) { + goto err; + } + + sig_buf = OPENSSL_malloc(sig_len); + uint8_t *srr_b64_buf = OPENSSL_malloc(srr_b64_len); + uint8_t *sig_b64_buf = OPENSSL_malloc(sig_b64_len); + if (!sig_buf || + !srr_b64_buf || + !sig_b64_buf || + !EVP_DigestSign(&md_ctx, sig_buf, &sig_len, srr_buf, srr_len) || + !CBB_add_bytes(&response, (const uint8_t *)kSRRHeader, + strlen(kSRRHeader)) || + !CBB_add_bytes(&response, srr_b64_buf, + EVP_EncodeBlock(srr_b64_buf, srr_buf, srr_len)) || + !CBB_add_bytes(&response, (const uint8_t *)kSRRSplit, + strlen(kSRRSplit)) || + !CBB_add_bytes(&response, sig_b64_buf, + EVP_EncodeBlock(sig_b64_buf, sig_buf, sig_len)) || + !CBB_add_bytes(&response, (const uint8_t *)kSRREnd, strlen(kSRREnd))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + OPENSSL_free(srr_b64_buf); + OPENSSL_free(sig_b64_buf); + goto err; + } + + OPENSSL_free(srr_b64_buf); + OPENSSL_free(sig_b64_buf); + } else { + CBB child; + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&response, &child) || + !CBB_add_bytes(&child, srr_buf, srr_len) || + !CBB_add_u16_length_prefixed(&response, &child) || + !CBB_reserve(&child, &ptr, sig_len) || + !EVP_DigestSign(&md_ctx, ptr, &sig_len, srr_buf, srr_len) || + !CBB_did_write(&child, sig_len) || + !CBB_flush(&response)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!CBS_stow(&client_data, &client_data_buf, &client_data_len) || + !CBB_finish(&response, out, out_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); + if (token == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + *out_token = token; + *out_client_data = client_data_buf; + *out_client_data_len = client_data_len; + *out_redemption_time = redemption_time; + + ok = 1; + +err: + CBB_cleanup(&response); + CBB_cleanup(&srr); + OPENSSL_free(srr_buf); + OPENSSL_free(sig_buf); + EVP_MD_CTX_cleanup(&md_ctx); + if (!ok) { + OPENSSL_free(client_data_buf); + } + return ok; +} + +int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method, + uint8_t *out_value, const uint8_t *key, + size_t key_len, const uint8_t *nonce, + size_t nonce_len, + uint8_t encrypted_bit) { + uint8_t metadata_obfuscator = + get_metadata_obfuscator(key, key_len, nonce, nonce_len); + *out_value = encrypted_bit ^ metadata_obfuscator; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c new file mode 100644 index 00000000..8277510e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/trust_token/voprf.c @@ -0,0 +1,766 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../ec_extra/internal.h" +#include "../fipsmodule/ec/internal.h" + +#include "internal.h" + + +typedef int (*hash_to_group_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]); +typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len); + +typedef struct { + const EC_GROUP *group; + + // hash_to_group implements the HashToGroup operation for VOPRFs. It returns + // one on success and zero on error. + hash_to_group_func_t hash_to_group; + // hash_to_scalar implements the HashToScalar operation for VOPRFs. It returns + // one on success and zero on error. + hash_to_scalar_func_t hash_to_scalar; +} VOPRF_METHOD; + +static const uint8_t kDefaultAdditionalData[32] = {0}; + +static int voprf_init_method(VOPRF_METHOD *method, int curve_nid, + hash_to_group_func_t hash_to_group, + hash_to_scalar_func_t hash_to_scalar) { + method->group = EC_GROUP_new_by_curve_name(curve_nid); + if (method->group == NULL) { + return 0; + } + + method->hash_to_group = hash_to_group; + method->hash_to_scalar = hash_to_scalar; + + return 1; +} + +static int cbb_add_point(CBB *out, const EC_GROUP *group, + const EC_AFFINE *point) { + size_t len = + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + if (len == 0) { + return 0; + } + + uint8_t *p; + return CBB_add_space(out, &p, len) && + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p, + len) == len && + CBB_flush(out); +} + +static int cbs_get_point(CBS *cbs, const EC_GROUP *group, EC_AFFINE *out) { + CBS child; + size_t plen = 1 + 2 * BN_num_bytes(&group->field); + if (!CBS_get_bytes(cbs, &child, plen) || + !ec_point_from_uncompressed(group, out, CBS_data(&child), + CBS_len(&child))) { + return 0; + } + return 1; +} + +static int scalar_to_cbb(CBB *out, const EC_GROUP *group, + const EC_SCALAR *scalar) { + uint8_t *buf; + size_t scalar_len = BN_num_bytes(&group->order); + if (!CBB_add_space(out, &buf, scalar_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + ec_scalar_to_bytes(group, buf, &scalar_len, scalar); + return 1; +} + +static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) { + size_t scalar_len = BN_num_bytes(&group->order); + CBS tmp; + if (!CBS_get_bytes(cbs, &tmp, scalar_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + ec_scalar_from_bytes(group, out, CBS_data(&tmp), CBS_len(&tmp)); + return 1; +} + +static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private, + CBB *out_public) { + const EC_GROUP *group = method->group; + EC_RAW_POINT pub; + EC_SCALAR priv; + EC_AFFINE pub_affine; + if (!ec_random_nonzero_scalar(group, &priv, kDefaultAdditionalData) || + !ec_point_mul_scalar_base(group, &pub, &priv) || + !ec_jacobian_to_affine(group, &pub_affine, &pub)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + return 0; + } + + if (!scalar_to_cbb(out_private, group, &priv) || + !cbb_add_point(out_public, group, &pub_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + return 0; + } + + return 1; +} + +static int voprf_client_key_from_bytes(const VOPRF_METHOD *method, + TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + const EC_GROUP *group = method->group; + if (!ec_point_from_uncompressed(group, &key->pubs, in, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + return 1; +} + +static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method, + TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + const EC_GROUP *group = method->group; + if (!ec_scalar_from_bytes(group, &key->xs, in, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + // Recompute the public key. + EC_RAW_POINT pub; + if (!ec_point_mul_scalar_base(group, &pub, &key->xs) || + !ec_jacobian_to_affine(group, &key->pubs, &pub)) { + return 0; + } + + return 1; +} + +static STACK_OF(TRUST_TOKEN_PRETOKEN) * + voprf_blind(const VOPRF_METHOD *method, CBB *cbb, size_t count) { + const EC_GROUP *group = method->group; + STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = + sk_TRUST_TOKEN_PRETOKEN_new_null(); + if (pretokens == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < count; i++) { + // Insert |pretoken| into |pretokens| early to simplify error-handling. + TRUST_TOKEN_PRETOKEN *pretoken = + OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); + if (pretoken == NULL || + !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + TRUST_TOKEN_PRETOKEN_free(pretoken); + goto err; + } + + RAND_bytes(pretoken->t, sizeof(pretoken->t)); + + // We sample r in Montgomery form to simplify inverting. + EC_SCALAR r; + if (!ec_random_nonzero_scalar(group, &r, + kDefaultAdditionalData)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // pretoken->r is rinv. + ec_scalar_inv0_montgomery(group, &pretoken->r, &r); + // Convert both out of Montgomery form. + ec_scalar_from_montgomery(group, &r, &r); + ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r); + + // Tp is the blinded token in the VOPRF protocol. + EC_RAW_POINT P, Tp; + if (!method->hash_to_group(group, &P, pretoken->t) || + !ec_point_mul_scalar(group, &Tp, &P, &r) || + !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) { + goto err; + } + + if (!cbb_add_point(cbb, group, &pretoken->Tp)) { + goto err; + } + } + + return pretokens; + +err: + sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free); + return NULL; +} + +static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out, + const EC_AFFINE *X, const EC_AFFINE *T, + const EC_AFFINE *W, const EC_AFFINE *K0, + const EC_AFFINE *K1) { + static const uint8_t kDLEQLabel[] = "DLEQ"; + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kDLEQLabel, sizeof(kDLEQLabel)) || + !cbb_add_point(&cbb, method->group, X) || + !cbb_add_point(&cbb, method->group, T) || + !cbb_add_point(&cbb, method->group, W) || + !cbb_add_point(&cbb, method->group, K0) || + !cbb_add_point(&cbb, method->group, K1) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_to_scalar(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + +static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out, + const CBB *points, size_t index) { + static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH"; + if (index > 0xffff) { + // The protocol supports only two-byte batches. + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kDLEQBatchLabel, sizeof(kDLEQBatchLabel)) || + !CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) || + !CBB_add_u16(&cbb, (uint16_t)index) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_to_scalar(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + +static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb, + const TRUST_TOKEN_ISSUER_KEY *priv, + const EC_RAW_POINT *T, const EC_RAW_POINT *W) { + const EC_GROUP *group = method->group; + + enum { + idx_T, + idx_W, + idx_k0, + idx_k1, + num_idx, + }; + EC_RAW_POINT jacobians[num_idx]; + + // Setup the DLEQ proof. + EC_SCALAR r; + if (// r <- Zp + !ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData) || + // k0;k1 = r*(G;T) + !ec_point_mul_scalar_base(group, &jacobians[idx_k0], &r) || + !ec_point_mul_scalar(group, &jacobians[idx_k1], T, &r)) { + return 0; + } + + EC_AFFINE affines[num_idx]; + jacobians[idx_T] = *T; + jacobians[idx_W] = *W; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + // Compute c = Hc(...). + EC_SCALAR c; + if (!hash_to_scalar_dleq(method, &c, &priv->pubs, &affines[idx_T], + &affines[idx_W], &affines[idx_k0], + &affines[idx_k1])) { + return 0; + } + + + EC_SCALAR c_mont; + ec_scalar_to_montgomery(group, &c_mont, &c); + + // u = r + c*xs + EC_SCALAR u; + ec_scalar_mul_montgomery(group, &u, &priv->xs, &c_mont); + ec_scalar_add(group, &u, &r, &u); + + // Store DLEQ proof in transcript. + if (!scalar_to_cbb(cbb, group, &c) || + !scalar_to_cbb(cbb, group, &u)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +static int mul_public_2(const EC_GROUP *group, EC_RAW_POINT *out, + const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, + const EC_RAW_POINT *p1, const EC_SCALAR *scalar1) { + EC_RAW_POINT points[2] = {*p0, *p1}; + EC_SCALAR scalars[2] = {*scalar0, *scalar1}; + return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points, + scalars, 2); +} + +static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs, + const TRUST_TOKEN_CLIENT_KEY *pub, const EC_RAW_POINT *T, + const EC_RAW_POINT *W) { + const EC_GROUP *group = method->group; + + + enum { + idx_T, + idx_W, + idx_k0, + idx_k1, + num_idx, + }; + EC_RAW_POINT jacobians[num_idx]; + + // Decode the DLEQ proof. + EC_SCALAR c, u; + if (!scalar_from_cbs(cbs, group, &c) || + !scalar_from_cbs(cbs, group, &u)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + // k0;k1 = u*(G;T) - c*(pub;W) + EC_RAW_POINT pubs; + ec_affine_to_jacobian(group, &pubs, &pub->pubs); + EC_SCALAR minus_c; + ec_scalar_neg(group, &minus_c, &c); + if (!ec_point_mul_scalar_public(group, &jacobians[idx_k0], &u, &pubs, + &minus_c) || + !mul_public_2(group, &jacobians[idx_k1], T, &u, W, &minus_c)) { + return 0; + } + + // Check the DLEQ proof. + EC_AFFINE affines[num_idx]; + jacobians[idx_T] = *T; + jacobians[idx_W] = *W; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + // Compute c = Hc(...). + EC_SCALAR calculated; + if (!hash_to_scalar_dleq(method, &calculated, &pub->pubs, &affines[idx_T], + &affines[idx_W], &affines[idx_k0], + &affines[idx_k1])) { + return 0; + } + + // c == calculated + if (!ec_scalar_equal_vartime(group, &c, &calculated)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF); + return 0; + } + + return 1; +} + +static int voprf_sign(const VOPRF_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue) { + const EC_GROUP *group = method->group; + if (num_requested < num_to_issue) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || + num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + + int ret = 0; + EC_RAW_POINT *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); + CBB batch_cbb; + CBB_zero(&batch_cbb); + if (!BTs || + !Zs || + !es || + !CBB_init(&batch_cbb, 0) || + !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < num_to_issue; i++) { + EC_AFFINE BT_affine, Z_affine; + EC_RAW_POINT BT, Z; + if (!cbs_get_point(cbs, group, &BT_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + ec_affine_to_jacobian(group, &BT, &BT_affine); + if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) || + !ec_jacobian_to_affine(group, &Z_affine, &Z) || + !cbb_add_point(cbb, group, &Z_affine)) { + goto err; + } + + if (!cbb_add_point(&batch_cbb, group, &BT_affine) || + !cbb_add_point(&batch_cbb, group, &Z_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + BTs[i] = BT; + Zs[i] = Z; + + if (!CBB_flush(cbb)) { + goto err; + } + } + + // The DLEQ batching construction is described in appendix B of + // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional + // computations all act on public inputs. + for (size_t i = 0; i < num_to_issue; i++) { + if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) { + goto err; + } + } + + EC_RAW_POINT BT_batch, Z_batch; + if (!ec_point_mul_scalar_public_batch(group, &BT_batch, + /*g_scalar=*/NULL, BTs, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Z_batch, + /*g_scalar=*/NULL, Zs, es, + num_to_issue)) { + goto err; + } + + CBB proof; + if (!CBB_add_u16_length_prefixed(cbb, &proof) || + !dleq_generate(method, &proof, key, &BT_batch, &Z_batch) || + !CBB_flush(cbb)) { + goto err; + } + + // Skip over any unused requests. + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(BTs); + OPENSSL_free(Zs); + OPENSSL_free(es); + CBB_cleanup(&batch_cbb); + return ret; +} + +static STACK_OF(TRUST_TOKEN) * + voprf_unblind(const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, + size_t count, uint32_t key_id) { + const EC_GROUP *group = method->group; + if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return NULL; + } + + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + EC_RAW_POINT *BTs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Zs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); + CBB batch_cbb; + CBB_zero(&batch_cbb); + if (!BTs || + !Zs || + !es || + !CBB_init(&batch_cbb, 0) || + !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < count; i++) { + const TRUST_TOKEN_PRETOKEN *pretoken = + sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i); + + EC_AFFINE Z_affine; + if (!cbs_get_point(cbs, group, &Z_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp); + ec_affine_to_jacobian(group, &Zs[i], &Z_affine); + + if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) || + !cbb_add_point(&batch_cbb, group, &Z_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // Unblind the token. + // pretoken->r is rinv. + EC_RAW_POINT N; + EC_AFFINE N_affine; + if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) || + !ec_jacobian_to_affine(group, &N_affine, &N)) { + goto err; + } + + // Serialize the token. Include |key_id| to avoid an extra copy in the layer + // above. + CBB token_cbb; + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) || + !CBB_add_u32(&token_cbb, key_id) || + !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !cbb_add_point(&token_cbb, group, &N_affine) || + !CBB_flush(&token_cbb)) { + CBB_cleanup(&token_cbb); + goto err; + } + + TRUST_TOKEN *token = + TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb)); + CBB_cleanup(&token_cbb); + if (token == NULL || + !sk_TRUST_TOKEN_push(ret, token)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + TRUST_TOKEN_free(token); + goto err; + } + } + + // The DLEQ batching construction is described in appendix B of + // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional + // computations all act on public inputs. + for (size_t i = 0; i < count; i++) { + if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) { + goto err; + } + } + + EC_RAW_POINT BT_batch, Z_batch; + if (!ec_point_mul_scalar_public_batch(group, &BT_batch, + /*g_scalar=*/NULL, BTs, es, count) || + !ec_point_mul_scalar_public_batch(group, &Z_batch, + /*g_scalar=*/NULL, Zs, es, count)) { + goto err; + } + + CBS proof; + if (!CBS_get_u16_length_prefixed(cbs, &proof) || + !dleq_verify(method, &proof, key, &BT_batch, &Z_batch) || + CBS_len(&proof) != 0) { + goto err; + } + + ok = 1; + +err: + OPENSSL_free(BTs); + OPENSSL_free(Zs); + OPENSSL_free(es); + CBB_cleanup(&batch_cbb); + if (!ok) { + sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free); + ret = NULL; + } + return ret; +} + +static int voprf_read(const VOPRF_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + const uint8_t *token, size_t token_len) { + const EC_GROUP *group = method->group; + CBS cbs; + CBS_init(&cbs, token, token_len); + EC_AFFINE Ws; + if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + !cbs_get_point(&cbs, group, &Ws) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); + return 0; + } + + + EC_RAW_POINT T; + if (!method->hash_to_group(group, &T, out_nonce)) { + return 0; + } + + EC_RAW_POINT Ws_calculated; + if (!ec_point_mul_scalar(group, &Ws_calculated, &T, &key->xs) || + !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK); + return 0; + } + + return 1; +} + + +// VOPRF experiment v2. + +static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_RAW_POINT *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "TrustToken VOPRF Experiment V2 HashToGroup"; + return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int voprf_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "TrustToken VOPRF Experiment V2 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha512_draft07( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int voprf_exp2_ok = 0; +static VOPRF_METHOD voprf_exp2_method; +static CRYPTO_once_t voprf_exp2_method_once = CRYPTO_ONCE_INIT; + +static void voprf_exp2_init_method_impl(void) { + voprf_exp2_ok = + voprf_init_method(&voprf_exp2_method, NID_secp384r1, + voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar); +} + +static int voprf_exp2_init_method(void) { + CRYPTO_once(&voprf_exp2_method_once, voprf_exp2_init_method_impl); + if (!voprf_exp2_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) { + if (!voprf_exp2_init_method()) { + return 0; + } + + return voprf_generate_key(&voprf_exp2_method, out_private, out_public); +} + +int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_exp2_init_method()) { + return 0; + } + return voprf_client_key_from_bytes(&voprf_exp2_method, key, in, len); +} + +int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_exp2_init_method()) { + return 0; + } + return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count) { + if (!voprf_exp2_init_method()) { + return NULL; + } + return voprf_blind(&voprf_exp2_method, cbb, count); +} + +int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!voprf_exp2_init_method() || private_metadata != 0) { + return 0; + } + return voprf_sign(&voprf_exp2_method, key, cbb, cbs, num_requested, + num_to_issue); +} + +STACK_OF(TRUST_TOKEN) * + voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, + CBS *cbs, size_t count, uint32_t key_id) { + if (!voprf_exp2_init_method()) { + return NULL; + } + return voprf_unblind(&voprf_exp2_method, key, pretokens, cbs, count, + key_id); +} + +int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len) { + if (!voprf_exp2_init_method()) { + return 0; + } + return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_digest.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_digest.c new file mode 100644 index 00000000..cd4360de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_digest.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str, *p; + + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (0); + } + p = str; + i2d(data, &p); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_sign.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_sign.c new file mode 100644 index 00000000..4fe56bd3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_sign.c @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey, const EVP_MD *type) +{ + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { + EVP_MD_CTX_cleanup(&ctx); + return 0; + } + return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); +} + +int ASN1_item_sign_ctx(const ASN1_ITEM *it, + X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) +{ + EVP_PKEY *pkey; + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0; + + pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + + /* Write out the requested copies of the AlgorithmIdentifier. */ + if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { + goto err; + } + if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + outl = EVP_PKEY_size(pkey); + buf_out = OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) + OPENSSL_free(signature->data); + signature->data = buf_out; + buf_out = NULL; + signature->length = outl; + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + err: + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(buf_in); + OPENSSL_free(buf_out); + return (outl); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_verify.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_verify.c new file mode 100644 index 00000000..69e9c326 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/a_verify.c @@ -0,0 +1,118 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, + const ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey) { + if (!pkey) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + size_t sig_len; + if (signature->type == V_ASN1_BIT_STRING) { + if (!ASN1_BIT_STRING_num_bytes(signature, &sig_len)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; + } + } else { + sig_len = (size_t)ASN1_STRING_length(signature); + } + + EVP_MD_CTX ctx; + uint8_t *buf_in = NULL; + int ret = 0, inl = 0; + EVP_MD_CTX_init(&ctx); + + if (!x509_digest_verify_init(&ctx, a, pkey)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerify(&ctx, ASN1_STRING_get0_data(signature), sig_len, + buf_in, inl)) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf_in); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/algorithm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/algorithm.c new file mode 100644 index 00000000..d59630d5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/algorithm.c @@ -0,0 +1,163 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + + +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + if (pkey == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + int pad_mode; + if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { + return 0; + } + /* RSA-PSS has special signature algorithm logic. */ + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + return x509_rsa_ctx_to_pss(ctx, algor); + } + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) { + return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); + } + + /* Default behavior: look up the OID for the algorithm/hash pair and encode + * that. */ + const EVP_MD *digest = EVP_MD_CTX_md(ctx); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + int sign_nid; + if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), + EVP_PKEY_id(pkey))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + + /* RSA signature algorithms include an explicit NULL parameter. Others omit + * it. */ + int paramtype = + (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; + X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); + return 1; +} + +int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, + EVP_PKEY *pkey) { + /* Convert the signature OID into digest and public key OIDs. */ + int sigalg_nid = OBJ_obj2nid(sigalg->algorithm); + int digest_nid, pkey_nid; + if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* Check the public key OID matches the public key type. */ + if (pkey_nid != EVP_PKEY_id(pkey)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + return 0; + } + + /* NID_undef signals that there are custom parameters to set. */ + if (digest_nid == NID_undef) { + if (sigalg_nid == NID_rsassaPss) { + return x509_rsa_pss_to_ctx(ctx, sigalg, pkey); + } + if (sigalg_nid == NID_ED25519) { + if (sigalg->parameter != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + return EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey); + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* The parameter should be an explicit NULL for RSA and omitted for ECDSA. For + * compatibility, we allow either for both algorithms. See b/167375496. + * + * TODO(davidben): Chromium's verifier allows both forms for RSA, but enforces + * ECDSA more strictly. Align with Chromium and add a flag for b/167375496. */ + if (sigalg->parameter != NULL && sigalg->parameter->type != V_ASN1_NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + + /* Otherwise, initialize with the digest from the OID. */ + const EVP_MD *digest = EVP_get_digestbynid(digest_nid); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + return 0; + } + + return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c new file mode 100644 index 00000000..f66bab32 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c @@ -0,0 +1,826 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509v3/internal.h" +#include "internal.h" + +/* + * Although this file is in crypto/x509 for layering purposes, it emits + * errors from the ASN.1 module for OpenSSL compatibility. + */ + +#define ASN1_GEN_FLAG 0x10000 +#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) +#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) +#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) +#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) +#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) +#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) +#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) +#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) + +#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} + +#define ASN1_FLAG_EXP_MAX 20 +/* Maximum number of nested sequences */ +#define ASN1_GEN_SEQ_MAX_DEPTH 50 + +/* Input formats */ + +/* ASCII: default */ +#define ASN1_GEN_FORMAT_ASCII 1 +/* UTF8 */ +#define ASN1_GEN_FORMAT_UTF8 2 +/* Hex */ +#define ASN1_GEN_FORMAT_HEX 3 +/* List of bits */ +#define ASN1_GEN_FORMAT_BITLIST 4 + +struct tag_name_st { + const char *strnam; + int len; + int tag; +}; + +typedef struct { + int exp_tag; + int exp_class; + int exp_constructed; + int exp_pad; + long exp_len; +} tag_exp_type; + +typedef struct { + int imp_tag; + int imp_class; + int utype; + int format; + const char *str; + tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; + int exp_count; +} tag_exp_arg; + +static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, + int *perr); +static int bitstr_cb(const char *elem, int len, void *bitstr); +static int asn1_cb(const char *elem, int len, void *bitstr); +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok); +static int parse_tagging(const char *vstart, int vlen, int *ptag, + int *pclass); +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr); +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); +static int asn1_str2tag(const char *tagstr, int len); + +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) +{ + int err = 0; + ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); + if (err) + OPENSSL_PUT_ERROR(ASN1, err); + return ret; +} + +static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, + int *perr) +{ + ASN1_TYPE *ret; + tag_exp_arg asn1_tags; + tag_exp_type *etmp; + + int i, len; + + unsigned char *orig_der = NULL, *new_der = NULL; + const unsigned char *cpy_start; + unsigned char *p; + const unsigned char *cp; + int cpy_len; + long hdr_len = 0; + int hdr_constructed = 0, hdr_tag, hdr_class; + int r; + + asn1_tags.imp_tag = -1; + asn1_tags.imp_class = -1; + asn1_tags.format = ASN1_GEN_FORMAT_ASCII; + asn1_tags.exp_count = 0; + if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { + *perr = ASN1_R_UNKNOWN_TAG; + return NULL; + } + + if ((asn1_tags.utype == V_ASN1_SEQUENCE) + || (asn1_tags.utype == V_ASN1_SET)) { + if (!cnf) { + *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; + return NULL; + } + if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { + *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; + return NULL; + } + ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); + } else + ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); + + if (!ret) + return NULL; + + /* If no tagging return base type */ + if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) + return ret; + + /* Generate the encoding */ + cpy_len = i2d_ASN1_TYPE(ret, &orig_der); + ASN1_TYPE_free(ret); + ret = NULL; + /* Set point to start copying for modified encoding */ + cpy_start = orig_der; + + /* Do we need IMPLICIT tagging? */ + if (asn1_tags.imp_tag != -1) { + /* If IMPLICIT we will replace the underlying tag */ + /* Skip existing tag+len */ + r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, + cpy_len); + if (r & 0x80) + goto err; + /* Update copy length */ + cpy_len -= cpy_start - orig_der; + /* + * For IMPLICIT tagging the length should match the original length + * and constructed flag should be consistent. + */ + hdr_constructed = r & V_ASN1_CONSTRUCTED; + /* + * Work out new length with IMPLICIT tag: ignore constructed because + * it will mess up if indefinite length + */ + len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); + } else + len = cpy_len; + + /* Work out length in any EXPLICIT, starting from end */ + + for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; + i < asn1_tags.exp_count; i++, etmp--) { + /* Content length: number of content octets + any padding */ + len += etmp->exp_pad; + etmp->exp_len = len; + /* Total object length: length including new header */ + len = ASN1_object_size(0, len, etmp->exp_tag); + } + + /* Allocate buffer for new encoding */ + + new_der = OPENSSL_malloc(len); + if (!new_der) + goto err; + + /* Generate tagged encoding */ + + p = new_der; + + /* Output explicit tags first */ + + for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; + i++, etmp++) { + ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, + etmp->exp_tag, etmp->exp_class); + if (etmp->exp_pad) + *p++ = 0; + } + + /* If IMPLICIT, output tag */ + + if (asn1_tags.imp_tag != -1) { + if (asn1_tags.imp_class == V_ASN1_UNIVERSAL + && (asn1_tags.imp_tag == V_ASN1_SEQUENCE + || asn1_tags.imp_tag == V_ASN1_SET)) + hdr_constructed = V_ASN1_CONSTRUCTED; + ASN1_put_object(&p, hdr_constructed, hdr_len, + asn1_tags.imp_tag, asn1_tags.imp_class); + } + + /* Copy across original encoding */ + OPENSSL_memcpy(p, cpy_start, cpy_len); + + cp = new_der; + + /* Obtain new ASN1_TYPE structure */ + ret = d2i_ASN1_TYPE(NULL, &cp, len); + + err: + if (orig_der) + OPENSSL_free(orig_der); + if (new_der) + OPENSSL_free(new_der); + + return ret; + +} + +static int asn1_cb(const char *elem, int len, void *bitstr) +{ + tag_exp_arg *arg = bitstr; + int i; + int utype; + int vlen = 0; + const char *p, *vstart = NULL; + + int tmp_tag, tmp_class; + + if (elem == NULL) + return -1; + + for (i = 0, p = elem; i < len; p++, i++) { + /* Look for the ':' in name value pairs */ + if (*p == ':') { + vstart = p + 1; + vlen = len - (vstart - elem); + len = p - elem; + break; + } + } + + utype = asn1_str2tag(elem, len); + + if (utype == -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); + ERR_add_error_data(2, "tag=", elem); + return -1; + } + + /* If this is not a modifier mark end of string and exit */ + if (!(utype & ASN1_GEN_FLAG)) { + arg->utype = utype; + arg->str = vstart; + /* If no value and not end of string, error */ + if (!vstart && elem[len]) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + return 0; + } + + switch (utype) { + + case ASN1_GEN_FLAG_IMP: + /* Check for illegal multiple IMPLICIT tagging */ + if (arg->imp_tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return -1; + } + if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) + return -1; + break; + + case ASN1_GEN_FLAG_EXP: + + if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) + return -1; + if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) + return -1; + break; + + case ASN1_GEN_FLAG_SEQWRAP: + if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_SETWRAP: + if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_BITWRAP: + if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_OCTWRAP: + if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_FORMAT: + if (!vstart) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + if (!strncmp(vstart, "ASCII", 5)) + arg->format = ASN1_GEN_FORMAT_ASCII; + else if (!strncmp(vstart, "UTF8", 4)) + arg->format = ASN1_GEN_FORMAT_UTF8; + else if (!strncmp(vstart, "HEX", 3)) + arg->format = ASN1_GEN_FORMAT_HEX; + else if (!strncmp(vstart, "BITLIST", 7)) + arg->format = ASN1_GEN_FORMAT_BITLIST; + else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + break; + + } + + return 1; + +} + +static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) +{ + char erch[2]; + long tag_num; + char *eptr; + if (!vstart) + return 0; + tag_num = strtoul(vstart, &eptr, 10); + /* Check we haven't gone past max length: should be impossible */ + if (eptr && *eptr && (eptr > vstart + vlen)) + return 0; + if (tag_num < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + *ptag = tag_num; + /* If we have non numeric characters, parse them */ + if (eptr) + vlen -= eptr - vstart; + else + vlen = 0; + if (vlen) { + switch (*eptr) { + + case 'U': + *pclass = V_ASN1_UNIVERSAL; + break; + + case 'A': + *pclass = V_ASN1_APPLICATION; + break; + + case 'P': + *pclass = V_ASN1_PRIVATE; + break; + + case 'C': + *pclass = V_ASN1_CONTEXT_SPECIFIC; + break; + + default: + erch[0] = *eptr; + erch[1] = 0; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); + ERR_add_error_data(2, "Char=", erch); + return 0; + break; + + } + } else + *pclass = V_ASN1_CONTEXT_SPECIFIC; + + return 1; + +} + +/* Handle multiple types: SET and SEQUENCE */ + +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr) +{ + ASN1_TYPE *ret = NULL; + STACK_OF(ASN1_TYPE) *sk = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + unsigned char *der = NULL; + int derlen; + size_t i; + sk = sk_ASN1_TYPE_new_null(); + if (!sk) + goto bad; + if (section) { + if (!cnf) + goto bad; + sect = X509V3_get_section(cnf, (char *)section); + if (!sect) + goto bad; + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + ASN1_TYPE *typ = + generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, + depth + 1, perr); + if (!typ) + goto bad; + if (!sk_ASN1_TYPE_push(sk, typ)) + goto bad; + } + } + + /* + * Now we has a STACK of the components, convert to the correct form + */ + + if (utype == V_ASN1_SET) + derlen = i2d_ASN1_SET_ANY(sk, &der); + else + derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); + + if (derlen < 0) + goto bad; + + if (!(ret = ASN1_TYPE_new())) + goto bad; + + if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) + goto bad; + + ret->type = utype; + + ret->value.asn1_string->data = der; + ret->value.asn1_string->length = derlen; + + der = NULL; + + bad: + + if (der) + OPENSSL_free(der); + + if (sk) + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + if (sect) + X509V3_section_free(cnf, sect); + + return ret; +} + +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok) +{ + tag_exp_type *exp_tmp; + /* Can only have IMPLICIT if permitted */ + if ((arg->imp_tag != -1) && !imp_ok) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); + return 0; + } + + if (arg->exp_count == ASN1_FLAG_EXP_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED); + return 0; + } + + exp_tmp = &arg->exp_list[arg->exp_count++]; + + /* + * If IMPLICIT set tag to implicit value then reset implicit tag since it + * has been used. + */ + if (arg->imp_tag != -1) { + exp_tmp->exp_tag = arg->imp_tag; + exp_tmp->exp_class = arg->imp_class; + arg->imp_tag = -1; + arg->imp_class = -1; + } else { + exp_tmp->exp_tag = exp_tag; + exp_tmp->exp_class = exp_class; + } + exp_tmp->exp_constructed = exp_constructed; + exp_tmp->exp_pad = exp_pad; + + return 1; +} + +static int asn1_str2tag(const char *tagstr, int len) +{ + unsigned int i; + static const struct tag_name_st *tntmp, tnst[] = { + ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), + ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), + ASN1_GEN_STR("NULL", V_ASN1_NULL), + ASN1_GEN_STR("INT", V_ASN1_INTEGER), + ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), + ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), + ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), + ASN1_GEN_STR("OID", V_ASN1_OBJECT), + ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), + ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), + ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), + ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), + ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), + ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), + ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), + ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), + ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), + ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), + ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), + ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("T61", V_ASN1_T61STRING), + ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), + ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), + ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), + ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), + + /* Special cases */ + ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SET", V_ASN1_SET), + /* type modifiers */ + /* Explicit tag */ + ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), + ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), + /* Implicit tag */ + ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), + ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), + /* OCTET STRING wrapper */ + ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), + /* SEQUENCE wrapper */ + ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), + /* SET wrapper */ + ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), + /* BIT STRING wrapper */ + ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), + ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), + ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), + }; + + if (len == -1) + len = strlen(tagstr); + + tntmp = tnst; + for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { + if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) + return tntmp->tag; + } + + return -1; +} + +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) +{ + ASN1_TYPE *atmp = NULL; + + CONF_VALUE vtmp; + + unsigned char *rdata; + long rdlen; + + int no_unused = 1; + + if (!(atmp = ASN1_TYPE_new())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!str) + str = ""; + + switch (utype) { + + case V_ASN1_NULL: + if (str && *str) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); + goto bad_form; + } + break; + + case V_ASN1_BOOLEAN: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT); + goto bad_form; + } + vtmp.name = NULL; + vtmp.section = NULL; + vtmp.value = (char *)str; + if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); + goto bad_str; + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); + goto bad_str; + } + break; + + case V_ASN1_OBJECT: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + goto bad_str; + } + break; + + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + atmp->value.asn1_string->type = utype; + if (!ASN1_TIME_check(atmp->value.asn1_string)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); + goto bad_str; + } + + break; + + case V_ASN1_BMPSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_IA5STRING: + case V_ASN1_T61STRING: + case V_ASN1_UTF8STRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_NUMERICSTRING: + + if (format == ASN1_GEN_FORMAT_ASCII) + format = MBSTRING_ASC; + else if (format == ASN1_GEN_FORMAT_UTF8) + format = MBSTRING_UTF8; + else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); + goto bad_form; + } + + if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, + -1, format, ASN1_tag2bit(utype)) <= 0) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + + break; + + case V_ASN1_BIT_STRING: + + case V_ASN1_OCTET_STRING: + + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_form; + } + + if (format == ASN1_GEN_FORMAT_HEX) { + + if (!(rdata = x509v3_hex_to_bytes((char *)str, &rdlen))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX); + goto bad_str; + } + + atmp->value.asn1_string->data = rdata; + atmp->value.asn1_string->length = rdlen; + atmp->value.asn1_string->type = utype; + + } else if (format == ASN1_GEN_FORMAT_ASCII) + ASN1_STRING_set(atmp->value.asn1_string, str, -1); + else if ((format == ASN1_GEN_FORMAT_BITLIST) + && (utype == V_ASN1_BIT_STRING)) { + if (!CONF_parse_list + (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); + goto bad_str; + } + no_unused = 0; + + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + goto bad_form; + } + + if ((utype == V_ASN1_BIT_STRING) && no_unused) { + atmp->value.asn1_string->flags + &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; + } + + break; + + default: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE); + goto bad_str; + break; + } + + atmp->type = utype; + return atmp; + + bad_str: + ERR_add_error_data(2, "string=", str); + bad_form: + + ASN1_TYPE_free(atmp); + return NULL; + +} + +static int bitstr_cb(const char *elem, int len, void *bitstr) +{ + long bitnum; + char *eptr; + if (!elem) + return 0; + bitnum = strtoul(elem, &eptr, 10); + if (eptr && *eptr && (eptr != elem + len)) + return 0; + if (bitnum < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_dir.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_dir.c new file mode 100644 index 00000000..8b85867c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_dir.c @@ -0,0 +1,466 @@ +/* crypto/x509/by_dir.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_TRUSTY) + +#include "../internal.h" +#include "internal.h" + +typedef struct lookup_dir_hashes_st { + unsigned long hash; + int suffix; +} BY_DIR_HASH; + +typedef struct lookup_dir_entry_st { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; +} BY_DIR_ENTRY; + +typedef struct lookup_dir_st { + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; +} BY_DIR; + +DEFINE_STACK_OF(BY_DIR_HASH) +DEFINE_STACK_OF(BY_DIR_ENTRY) + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret); +static X509_LOOKUP_METHOD x509_dir_lookup = { + "Load certs from files in a directory", + new_dir, /* new */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) +{ + return (&x509_dir_lookup); +} + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) +{ + int ret = 0; + BY_DIR *ld; + char *dir = NULL; + + ld = (BY_DIR *)ctx->method_data; + + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { + dir = (char *)getenv(X509_get_default_cert_dir_env()); + if (dir) + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); + else + ret = add_cert_dir(ld, X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) { + OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR); + } + } else + ret = add_cert_dir(ld, argp, (int)argl); + break; + } + return (ret); +} + +static int new_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) + return (0); + if ((a->buffer = BUF_MEM_new()) == NULL) { + OPENSSL_free(a); + return (0); + } + a->dirs = NULL; + lu->method_data = (char *)a; + return (1); +} + +static void by_dir_hash_free(BY_DIR_HASH *hash) +{ + OPENSSL_free(hash); +} + +static int by_dir_hash_cmp(const BY_DIR_HASH **a, const BY_DIR_HASH **b) +{ + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; +} + +static void by_dir_entry_free(BY_DIR_ENTRY *ent) +{ + if (ent->dir) + OPENSSL_free(ent->dir); + if (ent->hashes) + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + OPENSSL_free(ent); +} + +static void free_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + a = (BY_DIR *)lu->method_data; + if (a->dirs != NULL) + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + if (a->buffer != NULL) + BUF_MEM_free(a->buffer); + OPENSSL_free(a); +} + +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) +{ + size_t j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = p - ss; + if (len == 0) + continue; + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == len && + strncmp(ent->dir, ss, len) == 0) + break; + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) + continue; + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) + return 0; + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = OPENSSL_malloc(len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + OPENSSL_strlcpy(ent->dir, ss, len + 1); + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +/* + * g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| + * objects. + */ +static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = + CRYPTO_STATIC_MUTEX_INIT; + +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + size_t i; + int j, k; + unsigned long h; + unsigned long hash_array[2]; + int hash_index; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix = ""; + + if (name == NULL) + return (0); + + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix = ""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix = "r"; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + hash_array[0] = X509_NAME_hash(name); + hash_array[1] = X509_NAME_hash_old(name); + for (hash_index = 0; hash_index < 2; ++hash_index) { + h = hash_array[hash_index]; + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + size_t idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock); + } else { + k = 0; + hent = NULL; + } + for (;;) { + char c = '/'; +#ifdef OPENSSL_SYS_VMS + c = ent->dir[strlen(ent->dir) - 1]; + if (c != ':' && c != '>' && c != ']') { + /* + * If no separator is present, we assume the directory + * specifier is a logical name, and add a colon. We + * really should use better VMS routines for merging + * things like this, but this will do for now... -- + * Richard Levitte + */ + c = ':'; + } else { + c = '\0'; + } +#endif + if (c == '\0') { + /* + * This is special. When c == '\0', no directory + * separator should be added. + */ + BIO_snprintf(b->data, b->max, + "%s%08lx.%s%d", ent->dir, h, postfix, k); + } else { + BIO_snprintf(b->data, b->max, + "%s%c%08lx.%s%d", ent->dir, c, h, + postfix, k); + } +#ifndef OPENSSL_NO_POSIX_IO +# if defined(_WIN32) && !defined(stat) +# define stat _stat +# endif + { + struct stat st; + if (stat(b->data, &st) < 0) + break; + } +#endif + /* found one. */ + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, + ent->dir_type)) == 0) + break; + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) + break; + } + /* else case will caught higher up */ + k++; + } + + /* + * we have added it to the cache so now pull it out again + */ + CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock); + tmp = NULL; + sk_X509_OBJECT_sort(xl->store_ctx->objs); + if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx); + } + CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock); + + /* + * If a CRL, update the last file suffix added for this + */ + + if (type == X509_LU_CRL) { + CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock); + /* + * Look for entry again in case another thread added an entry + * first. + */ + if (!hent) { + htmp.hash = h; + sk_BY_DIR_HASH_sort(ent->hashes); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + sk_BY_DIR_HASH_sort(ent->hashes); + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + OPENSSL_memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + + /* + * Clear any errors that might have been raised processing empty + * or malformed files. + */ + ERR_clear_error(); + + /* + * If we were going to up the reference count, we would need + * to do it on a perl 'type' basis + */ + /* + * CRYPTO_add(&tmp->data.x509->references,1, + * CRYPTO_LOCK_X509); + */ + goto finish; + } + } + } + finish: + if (b != NULL) + BUF_MEM_free(b); + return (ok); +} + +#endif // OPENSSL_TRUSTY diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_file.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_file.c new file mode 100644 index 00000000..01f2fb5a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/by_file.c @@ -0,0 +1,294 @@ +/* crypto/x509/by_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include "internal.h" + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +static X509_LOOKUP_METHOD x509_file_lookup = { + "Load file into cache", + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_file_ctrl, /* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_file(void) +{ + return (&x509_file_lookup); +} + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **ret) +{ + int ok = 0; + const char *file; + + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { + file = getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx, file, + X509_FILETYPE_PEM) != 0); + + else + ok = (X509_load_cert_crl_file + (ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + + if (!ok) { + OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx, argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + } + break; + } + return (ok); +} + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + if (x == NULL) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE && + count > 0) { + ERR_clear_error(); + break; + } + OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); + goto err; + } + + if (ret == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATE_FOUND); + } + + err: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + in = BIO_new(BIO_s_file()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + if (x == NULL) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE && + count > 0) { + ERR_clear_error(); + break; + } + OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); + goto err; + } + + if (ret == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_FOUND); + } + + err: + if (x != NULL) + X509_CRL_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + size_t i; + int count = 0; + + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) { + goto err; + } + count++; + } + if (itmp->crl) { + if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) { + goto err; + } + count++; + } + } + + if (count == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND); + } + +err: + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + +#endif /* OPENSSL_NO_STDIO */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c new file mode 100644 index 00000000..f5fe4d87 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c @@ -0,0 +1,83 @@ +/* crypto/asn1/i2d_pr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include + + +int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) +{ + switch (EVP_PKEY_id(a)) { + case EVP_PKEY_RSA: + return i2d_RSAPrivateKey(a->pkey.rsa, pp); + case EVP_PKEY_EC: + return i2d_ECPrivateKey(a->pkey.ec, pp); + case EVP_PKEY_DSA: + return i2d_DSAPrivateKey(a->pkey.dsa, pp); + default: + /* + * Although this file is in crypto/x509 for layering reasons, it emits + * an error code from ASN1 for OpenSSL compatibility. + */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/internal.h new file mode 100644 index 00000000..e1f8e4c6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/internal.h @@ -0,0 +1,417 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2013. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_HEADER_X509_INTERNAL_H +#define OPENSSL_HEADER_X509_INTERNAL_H + +#include +#include +#include + +#include "../asn1/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Internal structures. */ + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +} /* X509_PUBKEY */; + +struct X509_name_entry_st { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; +} /* X509_NAME_ENTRY */; + +// we always keep X509_NAMEs in 2 forms. +struct X509_name_st { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; // true if 'bytes' needs to be built + BUF_MEM *bytes; + // unsigned long hash; Keep the hash around for lookups + unsigned char *canon_enc; + int canon_enclen; +} /* X509_NAME */; + +struct x509_attributes_st { + ASN1_OBJECT *object; + STACK_OF(ASN1_TYPE) *set; +} /* X509_ATTRIBUTE */; + +typedef struct x509_cert_aux_st { + STACK_OF(ASN1_OBJECT) *trust; // trusted uses + STACK_OF(ASN1_OBJECT) *reject; // rejected uses + ASN1_UTF8STRING *alias; // "friendly name" + ASN1_OCTET_STRING *keyid; // key id of private key +} X509_CERT_AUX; + +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +struct X509_extension_st { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; +} /* X509_EXTENSION */; + +typedef struct { + ASN1_INTEGER *version; // [ 0 ] default of v1 + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; // [ 1 ] optional in v2 + ASN1_BIT_STRING *subjectUID; // [ 2 ] optional in v2 + STACK_OF(X509_EXTENSION) *extensions; // [ 3 ] optional in v3 + ASN1_ENCODING enc; +} X509_CINF; + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +struct x509_st { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; + // These contain copies of various extension values + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; + unsigned char cert_hash[SHA256_DIGEST_LENGTH]; + X509_CERT_AUX *aux; + CRYPTO_BUFFER *buf; + CRYPTO_MUTEX lock; +} /* X509 */; + +typedef struct { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + // d=2 hl=2 l= 0 cons: cont: 00 + STACK_OF(X509_ATTRIBUTE) *attributes; // [ 0 ] +} X509_REQ_INFO; + +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) + +struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t references; +} /* X509_REQ */; + +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + // Set up if indirect CRL + STACK_OF(GENERAL_NAME) *issuer; + // Revocation reason + int reason; +} /* X509_REVOKED */; + +typedef struct { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; +} X509_CRL_INFO; + +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) + +struct X509_crl_st { + // actual signature + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t references; + int flags; + // Copies of various extensions + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + // Convenient breakdown of IDP + int idp_flags; + int idp_reasons; + // CRL and base CRL numbers for delta processing + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; + unsigned char crl_hash[SHA256_DIGEST_LENGTH]; + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; +} /* X509_CRL */; + +struct X509_VERIFY_PARAM_st { + char *name; + time_t check_time; // Time to use + unsigned long inh_flags; // Inheritance flags + unsigned long flags; // Various verify flags + int purpose; // purpose to check untrusted certificates + int trust; // trust setting to check + int depth; // Verify depth + STACK_OF(ASN1_OBJECT) *policies; // Permissible policies + // The following fields specify acceptable peer identities. + STACK_OF(OPENSSL_STRING) *hosts; // Set of acceptable names + unsigned int hostflags; // Flags to control matching features + char *peername; // Matching hostname in peer certificate + char *email; // If not NULL email address to match + size_t emaillen; + unsigned char *ip; // If not NULL IP address to match + size_t iplen; // Length of IP address + unsigned char poison; // Fail all verifications at name checking +} /* X509_VERIFY_PARAM */; + +struct x509_object_st { + // one of the above types + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +} /* X509_OBJECT */; + +// This is a static that defines the function interface +struct x509_lookup_method_st { + const char *name; + int (*new_item)(X509_LOOKUP *ctx); + void (*free)(X509_LOOKUP *ctx); + int (*init)(X509_LOOKUP *ctx); + int (*shutdown)(X509_LOOKUP *ctx); + int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); + int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type, unsigned char *bytes, + int len, X509_OBJECT *ret); + int (*get_by_alias)(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +} /* X509_LOOKUP_METHOD */; + +// This is used to hold everything. It is used for all certificate +// validation. Once we have a certificate chain, the 'verify' +// function is then called to actually check the cert chain. +struct x509_store_st { + // The following is a cache of trusted certs + int cache; // if true, stash any hits + STACK_OF(X509_OBJECT) *objs; // Cache of all objects + CRYPTO_MUTEX objs_lock; + + // These are external lookup methods + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + // Callbacks for various operations + X509_STORE_CTX_verify_fn verify; // called to verify a certificate + X509_STORE_CTX_verify_cb verify_cb; // error callback + X509_STORE_CTX_get_issuer_fn get_issuer; // get issuers cert from ctx + X509_STORE_CTX_check_issued_fn check_issued; // check issued + X509_STORE_CTX_check_revocation_fn + check_revocation; // Check revocation status of chain + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity + X509_STORE_CTX_cert_crl_fn cert_crl; // Check certificate against CRL + X509_STORE_CTX_lookup_certs_fn lookup_certs; + X509_STORE_CTX_lookup_crls_fn lookup_crls; + X509_STORE_CTX_cleanup_fn cleanup; + + CRYPTO_refcount_t references; +} /* X509_STORE */; + + +// This is the functions plus an instance of the local variables. +struct x509_lookup_st { + int init; // have we been started + int skip; // don't use us. + X509_LOOKUP_METHOD *method; // the functions + char *method_data; // method data + + X509_STORE *store_ctx; // who owns us +} /* X509_LOOKUP */; + +// This is a used when verifying cert chains. Since the +// gathering of the cert chain can take some time (and have to be +// 'retried', this needs to be kept and passed around. +struct x509_store_ctx_st { + X509_STORE *ctx; + + // The following are set by the caller + X509 *cert; // The cert to check + STACK_OF(X509) *untrusted; // chain of X509s - untrusted - passed in + STACK_OF(X509_CRL) *crls; // set of CRLs passed in + + X509_VERIFY_PARAM *param; + void *other_ctx; // Other info for use with get_issuer() + + // Callbacks for various operations + X509_STORE_CTX_verify_fn verify; // called to verify a certificate + X509_STORE_CTX_verify_cb verify_cb; // error callback + X509_STORE_CTX_get_issuer_fn get_issuer; // get issuers cert from ctx + X509_STORE_CTX_check_issued_fn check_issued; // check issued + X509_STORE_CTX_check_revocation_fn + check_revocation; // Check revocation status of chain + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity + X509_STORE_CTX_cert_crl_fn cert_crl; // Check certificate against CRL + X509_STORE_CTX_check_policy_fn check_policy; + X509_STORE_CTX_lookup_certs_fn lookup_certs; + X509_STORE_CTX_lookup_crls_fn lookup_crls; + X509_STORE_CTX_cleanup_fn cleanup; + + // The following is built up + int valid; // if 0, rebuild chain + int last_untrusted; // index of last untrusted cert + STACK_OF(X509) *chain; // chain of X509s - built up and trusted + X509_POLICY_TREE *tree; // Valid policy tree + + int explicit_policy; // Require explicit policy value + + // When something goes wrong, this is why + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; // cert currently being tested as valid issuer + X509_CRL *current_crl; // current CRL + + int current_crl_score; // score of current CRL + unsigned int current_reasons; // Reason mask + + X509_STORE_CTX *parent; // For CRL path validation: parent context + + CRYPTO_EX_DATA ex_data; +} /* X509_STORE_CTX */; + +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); + +int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); + + +/* RSA-PSS functions. */ + +/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on + * signature algorithm parameters in |sigalg| (which must have type + * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on + * error. */ +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, + EVP_PKEY *pkey); + +/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for + * |ctx|, which must have been configured for an RSA-PSS signing operation. It + * returns one on success and zero on error. */ +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS + * parameters in |sigalg| to |bp|. It returns one on success and zero on + * error. */ +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx); + + +/* Signature algorithm functions. */ + +/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an + * AlgorithmIdentifer and saves the result in |algor|. It returns one on + * success, or zero on error. */ +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_digest_verify_init sets up |ctx| for a signature verification operation + * with public key |pkey| and parameters from |algor|. The |ctx| argument must + * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or + * zero on error. */ +int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, + EVP_PKEY *pkey); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_X509_INTERNAL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/name_print.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/name_print.c new file mode 100644 index 00000000..d4991950 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/name_print.c @@ -0,0 +1,246 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include + + +static int maybe_write(BIO *out, const void *buf, int len) +{ + /* If |out| is NULL, ignore the output but report the length. */ + return out == NULL || BIO_write(out, buf, len) == len; +} + +/* do_indent prints |indent| spaces to |out|. */ +static int do_indent(BIO *out, int indent) +{ + for (int i = 0; i < indent; i++) { + if (!maybe_write(out, " ", 1)) { + return 0; + } + } + return 1; +} + +#define FN_WIDTH_LN 25 +#define FN_WIDTH_SN 10 + +static int do_name_ex(BIO *out, const X509_NAME *n, int indent, + unsigned long flags) +{ + int i, prev = -1, orflags, cnt; + int fn_opt, fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME_ENTRY *ent; + char objtmp[80]; + const char *objbuf; + int outlen, len; + const char *sep_dn, *sep_mv, *sep_eq; + int sep_dn_len, sep_mv_len, sep_eq_len; + if (indent < 0) + indent = 0; + outlen = indent; + if (!do_indent(out, indent)) + return -1; + switch (flags & XN_FLAG_SEP_MASK) { + case XN_FLAG_SEP_MULTILINE: + sep_dn = "\n"; + sep_dn_len = 1; + sep_mv = " + "; + sep_mv_len = 3; + break; + + case XN_FLAG_SEP_COMMA_PLUS: + sep_dn = ","; + sep_dn_len = 1; + sep_mv = "+"; + sep_mv_len = 1; + indent = 0; + break; + + case XN_FLAG_SEP_CPLUS_SPC: + sep_dn = ", "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + case XN_FLAG_SEP_SPLUS_SPC: + sep_dn = "; "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + default: + return -1; + } + + if (flags & XN_FLAG_SPC_EQ) { + sep_eq = " = "; + sep_eq_len = 3; + } else { + sep_eq = "="; + sep_eq_len = 1; + } + + fn_opt = flags & XN_FLAG_FN_MASK; + + cnt = X509_NAME_entry_count(n); + for (i = 0; i < cnt; i++) { + if (flags & XN_FLAG_DN_REV) + ent = X509_NAME_get_entry(n, cnt - i - 1); + else + ent = X509_NAME_get_entry(n, i); + if (prev != -1) { + if (prev == X509_NAME_ENTRY_set(ent)) { + if (!maybe_write(out, sep_mv, sep_mv_len)) + return -1; + outlen += sep_mv_len; + } else { + if (!maybe_write(out, sep_dn, sep_dn_len)) + return -1; + outlen += sep_dn_len; + if (!do_indent(out, indent)) + return -1; + outlen += indent; + } + } + prev = X509_NAME_ENTRY_set(ent); + fn = X509_NAME_ENTRY_get_object(ent); + val = X509_NAME_ENTRY_get_data(ent); + fn_nid = OBJ_obj2nid(fn); + if (fn_opt != XN_FLAG_FN_NONE) { + int objlen, fld_len; + if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) { + OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1); + fld_len = 0; /* XXX: what should this be? */ + objbuf = objtmp; + } else { + if (fn_opt == XN_FLAG_FN_SN) { + fld_len = FN_WIDTH_SN; + objbuf = OBJ_nid2sn(fn_nid); + } else if (fn_opt == XN_FLAG_FN_LN) { + fld_len = FN_WIDTH_LN; + objbuf = OBJ_nid2ln(fn_nid); + } else { + fld_len = 0; /* XXX: what should this be? */ + objbuf = ""; + } + } + objlen = strlen(objbuf); + if (!maybe_write(out, objbuf, objlen)) + return -1; + if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { + if (!do_indent(out, fld_len - objlen)) + return -1; + outlen += fld_len - objlen; + } + if (!maybe_write(out, sep_eq, sep_eq_len)) + return -1; + outlen += objlen + sep_eq_len; + } + /* + * If the field name is unknown then fix up the DER dump flag. We + * might want to limit this further so it will DER dump on anything + * other than a few 'standard' fields. + */ + if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) + orflags = ASN1_STRFLGS_DUMP_ALL; + else + orflags = 0; + + len = ASN1_STRING_print_ex(out, val, flags | orflags); + if (len < 0) + return -1; + outlen += len; + } + return outlen; +} + +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags) +{ + if (flags == XN_FLAG_COMPAT) + return X509_NAME_print(out, nm, indent); + return do_name_ex(out, nm, indent, flags); +} + +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags) +{ + BIO *bio = NULL; + if (fp != NULL) { + /* If |fp| is NULL, this function returns the number of bytes without + * writing. */ + bio = BIO_new_fp(fp, BIO_NOCLOSE); + if (bio == NULL) { + return -1; + } + } + int ret = X509_NAME_print_ex(bio, nm, indent, flags); + BIO_free(bio); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c new file mode 100644 index 00000000..088863f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c @@ -0,0 +1,400 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int rsa_pss_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { + if (operation == ASN1_OP_FREE_PRE) { + RSA_PSS_PARAMS *pss = (RSA_PSS_PARAMS *)*pval; + X509_ALGOR_free(pss->maskHash); + } + return 1; +} + +ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { + ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), + ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), + ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), + ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3), +} ASN1_SEQUENCE_END_cb(RSA_PSS_PARAMS, RSA_PSS_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + + +/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ +static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { + if (alg == NULL || alg->parameter == NULL || + OBJ_obj2nid(alg->algorithm) != NID_mgf1 || + alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int plen = alg->parameter->value.sequence->length; + return d2i_X509_ALGOR(NULL, &p, plen); +} + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, + X509_ALGOR **pmaskHash) { + *pmaskHash = NULL; + + if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int plen = alg->parameter->value.sequence->length; + RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); + if (pss == NULL) { + return NULL; + } + + *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + return pss; +} + +/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) { + if (EVP_MD_type(md) == NID_sha1) { + return 1; + } + *palg = X509_ALGOR_new(); + if (*palg == NULL) { + return 0; + } + X509_ALGOR_set_md(*palg, md); + return 1; +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD */ +static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + *palg = NULL; + + if (EVP_MD_type(mgf1md) == NID_sha1) { + return 1; + } + /* need to embed algorithm ID inside another */ + if (!rsa_md_to_algor(&algtmp, mgf1md) || + !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) { + goto err; + } + *palg = X509_ALGOR_new(); + if (!*palg) { + goto err; + } + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + +err: + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg) { + return 1; + } + + return 0; +} + +/* convert algorithm ID to EVP_MD, default SHA1 */ +static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { + const EVP_MD *md; + if (!alg) { + return EVP_sha1(); + } + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + } + return md; +} + +/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ +static const EVP_MD *rsa_mgf1_to_md(const X509_ALGOR *alg, + X509_ALGOR *maskHash) { + const EVP_MD *md; + if (!alg) { + return EVP_sha1(); + } + /* Check mask and lookup mask hash algorithm */ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || + maskHash == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + md = EVP_get_digestbyobj(maskHash->algorithm); + if (md == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + return md; +} + +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + const EVP_MD *sigmd, *mgf1md; + int saltlen; + if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) || + !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) || + !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) { + return 0; + } + + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + if (saltlen == -1) { + saltlen = EVP_MD_size(sigmd); + } else if (saltlen == -2) { + // TODO(davidben): Forbid this mode. The world has largely standardized on + // salt length matching hash length. + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; + if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { + saltlen--; + } + } else if (saltlen != (int)EVP_MD_size(sigmd)) { + // We only allow salt length matching hash length and, for now, the -2 case. + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; + } + + int ret = 0; + ASN1_STRING *os = NULL; + RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); + if (!pss) { + goto err; + } + + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength || + !ASN1_INTEGER_set(pss->saltLength, saltlen)) { + goto err; + } + } + + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || + !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { + goto err; + } + + /* Finally create string with pss parameter encoding. */ + if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { + goto err; + } + + X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); + os = NULL; + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + ASN1_STRING_free(os); + return ret; +} + +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, + EVP_PKEY *pkey) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + /* Decode PSS parameters */ + int ret = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (pss == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); + const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); + if (mgf1md == NULL || md == NULL) { + goto err; + } + + int saltlen = 20; + if (pss->saltLength != NULL) { + saltlen = ASN1_INTEGER_get(pss->saltLength); + + /* Could perform more salt length sanity checks but the main + * RSA routines will trap other invalid values anyway. */ + if (saltlen < 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + } + + /* low-level routines support only trailer field 0xbc (value 1) + * and PKCS#1 says we should reject any other value anyway. */ + if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + EVP_PKEY_CTX *pctx; + if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || + !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { + goto err; + } + + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return ret; +} + +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + int rv = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (!pss) { + if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { + goto err; + } + rv = 1; + goto err; + } + + if (BIO_puts(bp, "\n") <= 0 || + !BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Hash Algorithm: ") <= 0) { + goto err; + } + + if (pss->hashAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) { + goto err; + } + } else if (BIO_puts(bp, "sha1 (default)") <= 0) { + goto err; + } + + if (BIO_puts(bp, "\n") <= 0 || + !BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Mask Algorithm: ") <= 0) { + goto err; + } + + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || + BIO_puts(bp, " with ") <= 0) { + goto err; + } + + if (maskHash) { + if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { + goto err; + } + } else if (BIO_puts(bp, "INVALID") <= 0) { + goto err; + } + } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Salt Length: 0x") <= 0) { + goto err; + } + + if (pss->saltLength) { + if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) { + goto err; + } + } else if (BIO_puts(bp, "14 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Trailer Field: 0x") <= 0) { + goto err; + } + + if (pss->trailerField) { + if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) { + goto err; + } + } else if (BIO_puts(bp, "BC (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + rv = 1; + +err: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return rv; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_crl.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_crl.c new file mode 100644 index 00000000..432b3871 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_crl.c @@ -0,0 +1,148 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include + +int X509_CRL_print_fp(FILE *fp, X509_CRL *x) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + int ret = X509_CRL_print(b, x); + BIO_free(b); + return ret; +} + +int X509_CRL_print(BIO *out, X509_CRL *x) +{ + long version = X509_CRL_get_version(x); + const X509_ALGOR *sig_alg; + const ASN1_BIT_STRING *signature; + X509_CRL_get0_signature(x, &signature, &sig_alg); + if (BIO_printf(out, "Certificate Revocation List (CRL):\n") <= 0 || + // TODO(https://crbug.com/boringssl/467): This loses information on some + // invalid versions, but we should fix this by making invalid versions + // impossible. + BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", version + 1, + (unsigned long)version) <= 0 || + // Note this and the other |X509_signature_print| call both print the + // outer signature algorithm, rather than printing the inner and outer + // ones separately. This matches OpenSSL, though it was probably a bug. + !X509_signature_print(out, sig_alg, NULL)) { + return 0; + } + + char *issuer = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); + int ok = issuer != NULL && + BIO_printf(out, "%8sIssuer: %s\n", "", issuer) > 0; + OPENSSL_free(issuer); + if (!ok) { + return 0; + } + + if (BIO_printf(out, "%8sLast Update: ", "") <= 0 || + !ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x)) || + BIO_printf(out, "\n%8sNext Update: ", "") <= 0) { + return 0; + } + if (X509_CRL_get0_nextUpdate(x)) { + if (!ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x))) { + return 0; + } + } else { + if (BIO_printf(out, "NONE") <= 0) { + return 0; + } + } + + if (BIO_printf(out, "\n") <= 0 || + !X509V3_extensions_print(out, "CRL extensions", + X509_CRL_get0_extensions(x), 0, 8)) { + return 0; + } + + const STACK_OF(X509_REVOKED) *rev = X509_CRL_get_REVOKED(x); + if (sk_X509_REVOKED_num(rev) > 0) { + if (BIO_printf(out, "Revoked Certificates:\n") <= 0) { + return 0; + } + } else { + if (BIO_printf(out, "No Revoked Certificates.\n") <= 0) { + return 0; + } + } + + for (size_t i = 0; i < sk_X509_REVOKED_num(rev); i++) { + const X509_REVOKED *r = sk_X509_REVOKED_value(rev, i); + if (BIO_printf(out, " Serial Number: ") <= 0 || + i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r)) <= 0 || + BIO_printf(out, "\n Revocation Date: ") <= 0 || + !ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r)) || + BIO_printf(out, "\n") <= 0 || + !X509V3_extensions_print(out, "CRL entry extensions", + X509_REVOKED_get0_extensions(r), 0, 8)) { + } + } + + return X509_signature_print(out, sig_alg, signature); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_req.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_req.c new file mode 100644 index 00000000..228897a3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_req.c @@ -0,0 +1,250 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int X509_REQ_print_fp(FILE *fp, X509_REQ *x) { + BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); + if (bio == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + int ret = X509_REQ_print(bio, x); + BIO_free(bio); + return ret; +} + +int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, + unsigned long cflag) { + long l; + EVP_PKEY *pkey; + STACK_OF(X509_ATTRIBUTE) * sk; + char mlch = ' '; + + int nmindent = 0; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) { + nmindent = 16; + } + + X509_REQ_INFO *ri = x->req_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 || + BIO_write(bio, " Data:\n", 10) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + /* TODO(https://crbug.com/boringssl/467): This loses information on some + * invalid versions, but we should fix this by making invalid versions + * impossible. */ + l = X509_REQ_get_version(x); + if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, + (unsigned long)l) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bio, " Subject:%c", mlch) <= 0 || + X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 || + BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || + BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || + i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || + BIO_puts(bio, "\n") <= 0) { + goto err; + } + + pkey = X509_REQ_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bio, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bio); + } else { + EVP_PKEY_print_public(bio, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { + if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) { + goto err; + } + + sk = x->req_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { + if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) { + goto err; + } + } else { + size_t i; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i); + ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a); + + if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) { + continue; + } + + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + + const int num_attrs = X509_ATTRIBUTE_count(a); + const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj); + if (obj_str_len <= 0) { + if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) { + goto err; + } else { + continue; + } + } + + int j; + for (j = 0; j < num_attrs; j++) { + const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j); + const int type = at->type; + ASN1_BIT_STRING *bs = at->value.asn1_string; + + int k; + for (k = 25 - obj_str_len; k > 0; k--) { + if (BIO_write(bio, " ", 1) != 1) { + goto err; + } + } + + if (BIO_puts(bio, ":") <= 0) { + goto err; + } + + if (type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_UTF8STRING || + type == V_ASN1_IA5STRING || + type == V_ASN1_T61STRING) { + if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) { + goto err; + } + BIO_puts(bio, "\n"); + } else { + BIO_puts(bio, "unable to print attribute\n"); + } + } + } + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x); + if (exts) { + BIO_printf(bio, "%8sRequested Extensions:\n", ""); + + size_t i; + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + const int is_critical = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) { + goto err; + } + if (!X509V3_EXT_print(bio, ex, cflag, 16)) { + BIO_printf(bio, "%16s", ""); + ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex)); + } + if (BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + } + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP) && + !X509_signature_print(bio, x->sig_alg, x->signature)) { + goto err; + } + + return 1; + +err: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; +} + +int X509_REQ_print(BIO *bio, X509_REQ *req) { + return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509.c new file mode 100644 index 00000000..abe3e9dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509.c @@ -0,0 +1,365 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, + unsigned long cflag) +{ + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + int ret = X509_print_ex(b, x, nmflag, cflag); + BIO_free(b); + return ret; +} + +int X509_print_fp(FILE *fp, X509 *x) +{ + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print(BIO *bp, X509 *x) +{ + return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, + unsigned long cflag) +{ + long l; + int ret = 0, i; + char *m = NULL, mlch = ' '; + int nmindent = 0; + X509_CINF *ci; + EVP_PKEY *pkey = NULL; + const char *neg; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) + nmindent = 16; + + ci = x->cert_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate:\n", 13) <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + /* TODO(https://crbug.com/boringssl/467): This loses information on some + * invalid versions, but we should fix this by making invalid versions + * impossible. */ + l = X509_get_version(x); + if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, + (unsigned long)l) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_SERIAL)) { + if (BIO_write(bp, " Serial Number:", 22) <= 0) { + goto err; + } + + const ASN1_INTEGER *serial = X509_get0_serialNumber(x); + uint64_t serial_u64; + if (ASN1_INTEGER_get_uint64(&serial_u64, serial)) { + assert(serial->type != V_ASN1_NEG_INTEGER); + if (BIO_printf(bp, " %" PRIu64 " (0x%" PRIx64 ")\n", serial_u64, + serial_u64) <= 0) { + goto err; + } + } else { + neg = (serial->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; + if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) { + goto err; + } + + for (i = 0; i < serial->length; i++) { + if (BIO_printf(bp, "%02x%c", serial->data[i], + ((i + 1 == serial->length) ? '\n' : ':')) <= 0) { + goto err; + } + } + } + } + + if (!(cflag & X509_FLAG_NO_SIGNAME)) { + if (X509_signature_print(bp, ci->signature, NULL) <= 0) + goto err; + } + + if (!(cflag & X509_FLAG_NO_ISSUER)) { + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) + < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VALIDITY)) { + if (BIO_write(bp, " Validity\n", 17) <= 0) + goto err; + if (BIO_write(bp, " Not Before: ", 24) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) + goto err; + if (BIO_write(bp, "\n Not After : ", 25) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex + (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) + goto err; + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_IDS)) { + if (ci->issuerUID) { + if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) + goto err; + if (!X509_signature_dump(bp, ci->issuerUID, 12)) + goto err; + } + if (ci->subjectUID) { + if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) + goto err; + if (!X509_signature_dump(bp, ci->subjectUID, 12)) + goto err; + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) + X509V3_extensions_print(bp, "X509v3 extensions", + ci->extensions, cflag, 8); + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_AUX)) { + if (!X509_CERT_AUX_print(bp, x->aux, 0)) + goto err; + } + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +int X509_ocspid_print(BIO *bp, X509 *x) +{ + unsigned char *der = NULL; + unsigned char *dertmp; + int derlen; + int i; + unsigned char SHA1md[SHA_DIGEST_LENGTH]; + + /* + * display the hash of the subject as it would appear in OCSP requests + */ + if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) + goto err; + derlen = i2d_X509_NAME(x->cert_info->subject, NULL); + if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) + goto err; + i2d_X509_NAME(x->cert_info->subject, &dertmp); + + if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + OPENSSL_free(der); + der = NULL; + + /* + * display the hash of the public key as it would appear in OCSP requests + */ + if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) + goto err; + + if (!EVP_Digest(x->cert_info->key->public_key->data, + x->cert_info->key->public_key->length, + SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + BIO_printf(bp, "\n"); + + return (1); + err: + if (der != NULL) + OPENSSL_free(der); + return (0); +} + +int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig) +{ + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) + return 0; + + /* RSA-PSS signatures have parameters to print. */ + int sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid == NID_rsassaPss && + !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) { + return 0; + } + + if (sig) + return X509_signature_dump(bp, sig, 9); + else if (BIO_puts(bp, "\n") <= 0) + return 0; + return 1; +} + +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) +{ + char *s, *c, *b; + int ret = 0, i; + + b = X509_NAME_oneline(name, NULL, 0); + if (!b) + return 0; + if (!*b) { + OPENSSL_free(b); + return 1; + } + s = b + 1; /* skip the first slash */ + + c = s; + for (;;) { + if (((*s == '/') && + ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || + ((s[2] >= 'A') + && (s[2] <= 'Z') + && (s[3] == '=')) + ))) || (*s == '\0')) { + i = s - c; + if (BIO_write(bp, c, i) != i) + goto err; + c = s + 1; /* skip following slash */ + if (*s != '\0') { + if (BIO_write(bp, ", ", 2) != 2) + goto err; + } + } + if (*s == '\0') + break; + s++; + } + + ret = 1; + if (0) { + err: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return (ret); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509a.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509a.c new file mode 100644 index 00000000..014e710d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/t_x509a.c @@ -0,0 +1,116 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include + +#include "internal.h" + + +/* X509_CERT_AUX and string set routines */ + +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) +{ + char oidstr[80], first; + size_t i; + int j; + if (!aux) + return 1; + if (aux->trust) { + first = 1; + BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof oidstr, + sk_ASN1_OBJECT_value(aux->trust, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); + if (aux->reject) { + first = 1; + BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof oidstr, + sk_ASN1_OBJECT_value(aux->reject, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + if (aux->alias) { + BIO_printf(out, "%*sAlias: %.*s\n", indent, "", aux->alias->length, + aux->alias->data); + } + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (j = 0; j < aux->keyid->length; j++) + BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]); + BIO_write(out, "\n", 1); + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509.c new file mode 100644 index 00000000..a54fbd85 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509.c @@ -0,0 +1,90 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + + +/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define + * it to avoid downstream churn. */ +OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM) + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { + const uint8_t *s; + int i, n; + + n = sig->length; + s = sig->data; + for (i = 0; i < n; i++) { + if ((i % 18) == 0) { + if (BIO_write(bp, "\n", 1) <= 0 || + BIO_indent(bp, indent, indent) <= 0) { + return 0; + } + } + if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) { + return 0; + } + } + if (BIO_write(bp, "\n", 1) != 1) { + return 0; + } + + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_att.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_att.c new file mode 100644 index 00000000..ae58e82a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_att.c @@ -0,0 +1,358 @@ +/* crypto/x509/x509_att.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include + +#include "../asn1/internal.h" +#include "internal.h" + + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} + +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos) +{ + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -1; + } + return X509at_get_attr_by_OBJ(x, obj, lastpos); +} + +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_ATTRIBUTE_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_ATTRIBUTE_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x, loc); +} + +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + return (NULL); + ret = sk_X509_ATTRIBUTE_delete(x, loc); + return (ret); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr = NULL; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } else + sk = *x; + + if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + err2: + if (new_attr != NULL) + X509_ATTRIBUTE_free(new_attr); + if (sk != NULL) + sk_X509_ATTRIBUTE_free(sk); + return (NULL); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int attrtype, const void *data, + int len) +{ + const ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + return X509_ATTRIBUTE_create_by_OBJ(attr, obj, attrtype, data, len); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int attrtype, const void *data, + int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *attr; + + if (!X509_ATTRIBUTE_set1_object(ret, obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret, attrtype, data, len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) + *attr = ret; + return (ret); + err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return (NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *attrname, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj = OBJ_txt2obj(attrname, 0); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", attrname); + return (NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; +} + +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return attr->object != NULL; +} + +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len) +{ + ASN1_TYPE *ttmp = NULL; + ASN1_STRING *stmp = NULL; + int atype = 0; + if (!attr) + return 0; + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1) { + if (!(stmp = ASN1_STRING_type_new(attrtype))) + goto err; + if (!ASN1_STRING_set(stmp, data, len)) + goto err; + atype = attrtype; + } + /* + * This is a bit naughty because the attribute should really have at + * least one value but some types use and zero length SET and require + * this. + */ + if (attrtype == 0) { + ASN1_STRING_free(stmp); + return 1; + } + if (!(ttmp = ASN1_TYPE_new())) + goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } else { + ASN1_TYPE_set(ttmp, atype, stmp); + stmp = NULL; + } + if (!sk_ASN1_TYPE_push(attr->set, ttmp)) + goto err; + return 1; + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); + return 0; +} + +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) +{ + return sk_ASN1_TYPE_num(attr->set); +} + +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return (NULL); + return (attr->object); +} + +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int attrtype, void *unused) +{ + ASN1_TYPE *ttmp; + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) + return NULL; + if (attrtype != ASN1_TYPE_get(ttmp)) { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE); + return NULL; + } + return (void *)asn1_type_value_as_pointer(ttmp); +} + +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) + return NULL; + if (idx >= X509_ATTRIBUTE_count(attr)) + return NULL; + return sk_ASN1_TYPE_value(attr->set, idx); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c new file mode 100644 index 00000000..fa938ddf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c @@ -0,0 +1,461 @@ +/* crypto/x509/x509_cmp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509v3/internal.h" +#include "internal.h" + + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) +{ + int i; + X509_CINF *ai, *bi; + + ai = a->cert_info; + bi = b->cert_info; + i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); + if (i) + return (i); + return (X509_NAME_cmp(ai->issuer, bi->issuer)); +} + +int X509_issuer_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +} + +int X509_subject_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +} + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) +{ + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +} + +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return OPENSSL_memcmp(a->crl_hash, b->crl_hash, SHA256_DIGEST_LENGTH); +} + +X509_NAME *X509_get_issuer_name(const X509 *a) +{ + return (a->cert_info->issuer); +} + +unsigned long X509_issuer_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->issuer)); +} + +unsigned long X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} + +X509_NAME *X509_get_subject_name(const X509 *a) +{ + return (a->cert_info->subject); +} + +ASN1_INTEGER *X509_get_serialNumber(X509 *a) +{ + return (a->cert_info->serialNumber); +} + +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) +{ + return x509->cert_info->serialNumber; +} + +unsigned long X509_subject_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->subject)); +} + +unsigned long X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} + +/* + * Compare two certificates: they must be identical for this to work. NB: + * Although "cmp" operations are generally prototyped to take "const" + * arguments (eg. for use in STACKs), the way X509 handling is - these + * operations may involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point where the + * "depth-first" constification tree has to halt with an evil cast. + */ +int X509_cmp(const X509 *a, const X509 *b) +{ + /* Fill in the |cert_hash| fields. + * + * TODO(davidben): This may fail, in which case the the hash will be all + * zeros. This produces a consistent comparison (failures are sticky), but + * not a good one. OpenSSL now returns -2, but this is not a consistent + * comparison and may cause misbehaving sorts by transitivity. For now, we + * retain the old OpenSSL behavior, which was to ignore the error. See + * https://crbug.com/boringssl/355. */ + x509v3_cache_extensions((X509 *)a); + x509v3_cache_extensions((X509 *)b); + + int rv = OPENSSL_memcmp(a->cert_hash, b->cert_hash, SHA256_DIGEST_LENGTH); + if (rv) + return rv; + /* Check for match against stored encoding too */ + if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) { + rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len); + if (rv) + return rv; + return OPENSSL_memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, + a->cert_info->enc.len); + } + return rv; +} + +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) +{ + int ret; + + /* Ensure canonical encoding is present and up to date */ + + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } + + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; + } + + ret = a->canon_enclen - b->canon_enclen; + + if (ret) + return ret; + + return OPENSSL_memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); + +} + +unsigned long X509_NAME_hash(X509_NAME *x) +{ + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), + NULL)) + return 0; + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + return (ret); +} + +/* + * I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. + */ + +unsigned long X509_NAME_hash_old(X509_NAME *x) +{ + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + /* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */ + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) + && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) + && EVP_DigestFinal_ex(&md_ctx, md, NULL)) + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ret); +} + +/* Search a stack of X509 for a match */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) +{ + size_t i; + X509_CINF cinf; + X509 x, *x509 = NULL; + + if (!sk) + return NULL; + + x.cert_info = &cinf; + cinf.serialNumber = serial; + cinf.issuer = name; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_issuer_and_serial_cmp(x509, &x) == 0) + return (x509); + } + return (NULL); +} + +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +{ + X509 *x509; + size_t i; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) + return (x509); + } + return (NULL); +} + +EVP_PKEY *X509_get_pubkey(X509 *x) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->cert_info->key)); +} + +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) +{ + if (!x) + return NULL; + return x->cert_info->key->public_key; +} + +int X509_check_private_key(X509 *x, const EVP_PKEY *k) +{ + EVP_PKEY *xk; + int ret; + + xk = X509_get_pubkey(x); + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { + case 1: + break; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + } + if (xk) + EVP_PKEY_free(xk); + if (ret > 0) + return 1; + return 0; +} + +/* + * Check a suite B algorithm is permitted: pass in a public key and the NID + * of its signature (or 0 if no signature). The pflags is a pointer to a + * flags field which must contain the suite B verification flags. + */ + +static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) +{ + const EC_GROUP *grp = NULL; + int curve_nid; + if (pkey && pkey->type == EVP_PKEY_EC) + grp = EC_KEY_get0_group(pkey->pkey.ec); + if (!grp) + return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; + curve_nid = EC_GROUP_get_curve_name(grp); + /* Check curve is consistent with LOS */ + if (curve_nid == NID_secp384r1) { /* P-384 */ + /* + * Check signature algorithm is consistent with curve. + */ + if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) + return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; + if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) + return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; + /* If we encounter P-384 we cannot use P-256 later */ + *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; + } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */ + if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) + return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; + if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) + return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; + } else + return X509_V_ERR_SUITE_B_INVALID_CURVE; + + return X509_V_OK; +} + +int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, + unsigned long flags) +{ + int rv, sign_nid; + size_t i; + EVP_PKEY *pk = NULL; + unsigned long tflags; + if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) + return X509_V_OK; + tflags = flags; + /* If no EE certificate passed in must be first in chain */ + if (x == NULL) { + x = sk_X509_value(chain, 0); + i = 1; + } else + i = 0; + + if (X509_get_version(x) != X509_VERSION_3) { + rv = X509_V_ERR_SUITE_B_INVALID_VERSION; + /* Correct error depth */ + i = 0; + goto end; + } + + pk = X509_get_pubkey(x); + /* Check EE key only */ + rv = check_suite_b(pk, -1, &tflags); + if (rv != X509_V_OK) { + /* Correct error depth */ + i = 0; + goto end; + } + for (; i < sk_X509_num(chain); i++) { + sign_nid = X509_get_signature_nid(x); + x = sk_X509_value(chain, i); + if (X509_get_version(x) != X509_VERSION_3) { + rv = X509_V_ERR_SUITE_B_INVALID_VERSION; + goto end; + } + EVP_PKEY_free(pk); + pk = X509_get_pubkey(x); + rv = check_suite_b(pk, sign_nid, &tflags); + if (rv != X509_V_OK) + goto end; + } + + /* Final check: root CA signature */ + rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); + end: + if (pk) + EVP_PKEY_free(pk); + if (rv != X509_V_OK) { + /* Invalid signature or LOS errors are for previous cert */ + if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM + || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) + i--; + /* + * If we have LOS error and flags changed then we are signing P-384 + * with P-256. Use more meaninggul error. + */ + if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) + rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; + if (perror_depth) + *perror_depth = i; + } + return rv; +} + +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) +{ + int sign_nid; + if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) + return X509_V_OK; + sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); + return check_suite_b(pk, sign_nid, &flags); +} + +/* + * Not strictly speaking an "up_ref" as a STACK doesn't have a reference + * count but it has the same effect by duping the STACK and upping the ref of + * each X509 structure. + */ +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) +{ + STACK_OF(X509) *ret; + size_t i; + ret = sk_X509_dup(chain); + for (i = 0; i < sk_X509_num(ret); i++) { + X509_up_ref(sk_X509_value(ret, i)); + } + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c new file mode 100644 index 00000000..eadfd5ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_d2.c @@ -0,0 +1,106 @@ +/* crypto/x509/x509_d2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_set_default_paths(X509_STORE *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return (1); +} + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + X509_LOOKUP *lookup; + + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) + return (0); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + return (0); + } + if ((path == NULL) && (file == NULL)) + return (0); + return (1); +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_def.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_def.c new file mode 100644 index 00000000..0ecdefc7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_def.c @@ -0,0 +1,103 @@ +/* crypto/x509/x509_def.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +/* TODO(fork): cleanup */ + +#if defined(OPENSSL_FUCHSIA) +#define OPENSSLDIR "/config/ssl" +#else +#define OPENSSLDIR "/etc/ssl" +#endif + +#define X509_CERT_AREA OPENSSLDIR +#define X509_CERT_DIR OPENSSLDIR "/certs" +#define X509_CERT_FILE OPENSSLDIR "/cert.pem" +#define X509_PRIVATE_DIR OPENSSLDIR "/private" +#define X509_CERT_DIR_EVP "SSL_CERT_DIR" +#define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +const char *X509_get_default_private_dir(void) +{ + return (X509_PRIVATE_DIR); +} + +const char *X509_get_default_cert_area(void) +{ + return (X509_CERT_AREA); +} + +const char *X509_get_default_cert_dir(void) +{ + return (X509_CERT_DIR); +} + +const char *X509_get_default_cert_file(void) +{ + return (X509_CERT_FILE); +} + +const char *X509_get_default_cert_dir_env(void) +{ + return (X509_CERT_DIR_EVP); +} + +const char *X509_get_default_cert_file_env(void) +{ + return (X509_CERT_FILE_EVP); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c new file mode 100644 index 00000000..d62c1c8a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_ext.c @@ -0,0 +1,212 @@ +/* crypto/x509/x509_ext.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +int X509_CRL_get_ext_count(const X509_CRL *x) +{ + return (X509v3_get_ext_count(x->crl->extensions)); +} + +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +} + +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); +} + +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) +{ + return (X509v3_get_ext(x->crl->extensions, loc)); +} + +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) +{ + return (X509v3_delete_ext(x->crl->extensions, loc)); +} + +void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, int *out_critical, + int *out_idx) +{ + return X509V3_get_d2i(crl->crl->extensions, nid, out_critical, out_idx); +} + +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} + +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +} + +int X509_get_ext_count(const X509 *x) +{ + return (X509v3_get_ext_count(x->cert_info->extensions)); +} + +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +} + +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +} + +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->cert_info->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_get_ext(const X509 *x, int loc) +{ + return (X509v3_get_ext(x->cert_info->extensions, loc)); +} + +X509_EXTENSION *X509_delete_ext(X509 *x, int loc) +{ + return (X509v3_delete_ext(x->cert_info->extensions, loc)); +} + +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +} + +void *X509_get_ext_d2i(const X509 *x509, int nid, int *out_critical, + int *out_idx) +{ + return X509V3_get_d2i(x509->cert_info->extensions, nid, out_critical, + out_idx); +} + +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x) +{ + return (X509v3_get_ext_count(x->extensions)); +} + +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +} + +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); +} + +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, + int lastpos) +{ + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) +{ + return (X509v3_get_ext(x->extensions, loc)); +} + +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_delete_ext(x->extensions, loc)); +} + +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +} + +void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, int nid, + int *out_critical, int *out_idx) +{ + return X509V3_get_d2i(revoked->extensions, nid, out_critical, out_idx); +} + +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c new file mode 100644 index 00000000..21981343 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_lu.c @@ -0,0 +1,808 @@ +/* crypto/x509/x509_lu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) +{ + X509_LOOKUP *ret; + + ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) + return NULL; + + ret->init = 0; + ret->skip = 0; + ret->method = method; + ret->method_data = NULL; + ret->store_ctx = NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) { + OPENSSL_free(ret); + return NULL; + } + return ret; +} + +void X509_LOOKUP_free(X509_LOOKUP *ctx) +{ + if (ctx == NULL) + return; + if ((ctx->method != NULL) && (ctx->method->free != NULL)) + (*ctx->method->free) (ctx); + OPENSSL_free(ctx); +} + +int X509_LOOKUP_init(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->init != NULL) + return ctx->method->init(ctx); + else + return 1; +} + +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->shutdown != NULL) + return ctx->method->shutdown(ctx); + else + return 1; +} + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + if (ctx->method == NULL) + return -1; + if (ctx->method->ctrl != NULL) + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + else + return 1; +} + +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) + return 0; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret) > 0; +} + +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) + return 0; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; +} + +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) + return 0; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; +} + +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) + return 0; + return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; +} + +static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b) +{ + int ret; + + ret = ((*a)->type - (*b)->type); + if (ret) + return ret; + switch ((*a)->type) { + case X509_LU_X509: + ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); + break; + case X509_LU_CRL: + ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); + break; + default: + /* abort(); */ + return 0; + } + return ret; +} + +X509_STORE *X509_STORE_new(void) +{ + X509_STORE *ret; + + if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) + return NULL; + OPENSSL_memset(ret, 0, sizeof(*ret)); + CRYPTO_MUTEX_init(&ret->objs_lock); + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + if (ret->objs == NULL) + goto err; + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + if (ret->get_cert_methods == NULL) + goto err; + ret->param = X509_VERIFY_PARAM_new(); + if (ret->param == NULL) + goto err; + + ret->references = 1; + return ret; + err: + if (ret) { + CRYPTO_MUTEX_cleanup(&ret->objs_lock); + if (ret->param) + X509_VERIFY_PARAM_free(ret->param); + if (ret->get_cert_methods) + sk_X509_LOOKUP_free(ret->get_cert_methods); + if (ret->objs) + sk_X509_OBJECT_free(ret->objs); + OPENSSL_free(ret); + } + return NULL; +} + +int X509_STORE_up_ref(X509_STORE *store) +{ + CRYPTO_refcount_inc(&store->references); + return 1; +} + +static void cleanup(X509_OBJECT *a) +{ + if (a == NULL) { + return; + } + if (a->type == X509_LU_X509) { + X509_free(a->data.x509); + } else if (a->type == X509_LU_CRL) { + X509_CRL_free(a->data.crl); + } else { + /* abort(); */ + } + + OPENSSL_free(a); +} + +void X509_STORE_free(X509_STORE *vfy) +{ + size_t j; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { + return; + } + + CRYPTO_MUTEX_cleanup(&vfy->objs_lock); + + sk = vfy->get_cert_methods; + for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { + lu = sk_X509_LOOKUP_value(sk, j); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + if (vfy->param) + X509_VERIFY_PARAM_free(vfy->param); + OPENSSL_free(vfy); +} + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) +{ + size_t i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk = v->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (m == lu->method) { + return lu; + } + } + /* a new one */ + lu = X509_LOOKUP_new(m); + if (lu == NULL) + return NULL; + else { + lu->store_ctx = v; + if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) + return lu; + else { + X509_LOOKUP_free(lu); + return NULL; + } + } +} + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + X509_STORE *ctx = vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { + tmp = &stmp; + break; + } + } + if (tmp == NULL) + return 0; + } + + /* + * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret); + */ + + ret->type = tmp->type; + ret->data.ptr = tmp->data.ptr; + + X509_OBJECT_up_ref_count(ret); + + return 1; +} + +static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) +{ + if (x == NULL) { + return 0; + } + + X509_OBJECT *const obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (is_crl) { + obj->type = X509_LU_CRL; + obj->data.crl = (X509_CRL *)x; + } else { + obj->type = X509_LU_X509; + obj->data.x509 = (X509 *)x; + } + X509_OBJECT_up_ref_count(obj); + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + + int ret = 1; + int added = 0; + /* Duplicates are silently ignored */ + if (!X509_OBJECT_retrieve_match(ctx->objs, obj)) { + ret = added = (sk_X509_OBJECT_push(ctx->objs, obj) != 0); + } + + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + if (!added) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + } + + return ret; +} + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) +{ + return x509_store_add(ctx, x, /*is_crl=*/0); +} + +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) +{ + return x509_store_add(ctx, x, /*is_crl=*/1); +} + +int X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_up_ref(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_up_ref(a->data.crl); + break; + } + return 1; +} + +void X509_OBJECT_free_contents(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } +} + +int X509_OBJECT_get_type(const X509_OBJECT *a) +{ + return a->type; +} + +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) +{ + if (a == NULL || a->type != X509_LU_X509) { + return NULL; + } + return a->data.x509; +} + +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name, int *pnmatch) +{ + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + + stmp.type = type; + switch (type) { + case X509_LU_X509: + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; + case X509_LU_CRL: + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; + default: + /* abort(); */ + return -1; + } + + size_t idx; + sk_X509_OBJECT_sort(h); + if (!sk_X509_OBJECT_find(h, &idx, &stmp)) + return -1; + + if (pnmatch != NULL) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + + return idx; +} + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) +{ + return x509_object_idx_cnt(h, type, name, NULL); +} + +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name) +{ + int idx; + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) + return NULL; + return sk_X509_OBJECT_value(h, idx); +} + +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) +{ + return st->objs; +} + +STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + sk = sk_X509_new_null(); + if (sk == NULL) + return NULL; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + /* + * Nothing found in cache: do lookup to possibly add new objects to + * cache + */ + X509_OBJECT xobj; + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_free(sk); + return NULL; + } + } + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + if (!sk_X509_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + X509_up_ref(x); + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; + +} + +STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + sk = sk_X509_CRL_new_null(); + if (sk == NULL) + return NULL; + + /* Always do lookup to possibly add new CRLs to cache. */ + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + X509_CRL_up_ref(x); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) +{ + size_t idx, i; + X509_OBJECT *obj; + + sk_X509_OBJECT_sort(h); + if (!sk_X509_OBJECT_find(h, &idx, x)) { + return NULL; + } + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp + ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) + return NULL; + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } else + return obj; + } + return NULL; +} + +/* + * Try to get issuer certificate from store. Due to limitations of the API + * this can only retrieve a single certificate matching a given subject name. + * However it will fill the cache with all matching certificates, so we can + * examine the cache for all matches. Return values are: 1 lookup + * successful. 0 certificate not found. -1 some other error. + */ +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int idx, ret; + size_t i; + xn = X509_get_issuer_name(x); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) + return 0; + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, obj.data.x509)) { + *issuer = obj.data.x509; + return 1; + } + X509_OBJECT_free_contents(&obj); + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + if (idx != -1) { /* should be true as we've had at least one + * match */ + /* Look through all matching certs for suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* See if we've run past the matches */ + if (pobj->type != X509_LU_X509) + break; + if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) + break; + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + *issuer = pobj->data.x509; + X509_OBJECT_up_ref_count(pobj); + ret = 1; + break; + } + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return ret; +} + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +{ + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +int X509_STORE_set_depth(X509_STORE *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; +} + +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int X509_STORE_set_trust(X509_STORE *ctx, int trust) +{ + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +{ + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) +{ + return ctx->param; +} + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) +{ + ctx->verify = verify; +} + +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) +{ + return ctx->verify; +} + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + X509_STORE_CTX_verify_cb verify_cb) +{ + ctx->verify_cb = verify_cb; +} + +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) +{ + return ctx->verify_cb; +} + +void X509_STORE_set_get_issuer(X509_STORE *ctx, + X509_STORE_CTX_get_issuer_fn get_issuer) +{ + ctx->get_issuer = get_issuer; +} + +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) +{ + return ctx->get_issuer; +} + +void X509_STORE_set_check_issued(X509_STORE *ctx, + X509_STORE_CTX_check_issued_fn check_issued) +{ + ctx->check_issued = check_issued; +} + +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) +{ + return ctx->check_issued; +} + +void X509_STORE_set_check_revocation(X509_STORE *ctx, + X509_STORE_CTX_check_revocation_fn check_revocation) +{ + ctx->check_revocation = check_revocation; +} + +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx) +{ + return ctx->check_revocation; +} + +void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl) +{ + ctx->get_crl = get_crl; +} + +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx) +{ + return ctx->get_crl; +} + +void X509_STORE_set_check_crl(X509_STORE *ctx, + X509_STORE_CTX_check_crl_fn check_crl) +{ + ctx->check_crl = check_crl; +} + +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) +{ + return ctx->check_crl; +} + +void X509_STORE_set_cert_crl(X509_STORE *ctx, + X509_STORE_CTX_cert_crl_fn cert_crl) +{ + ctx->cert_crl = cert_crl; +} + +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) +{ + return ctx->cert_crl; +} + +void X509_STORE_set_lookup_certs(X509_STORE *ctx, + X509_STORE_CTX_lookup_certs_fn lookup_certs) +{ + ctx->lookup_certs = lookup_certs; +} + +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) +{ + return ctx->lookup_certs; +} + +void X509_STORE_set_lookup_crls(X509_STORE *ctx, + X509_STORE_CTX_lookup_crls_fn lookup_crls) +{ + ctx->lookup_crls = lookup_crls; +} + +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) +{ + return ctx->lookup_crls; +} + +void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn ctx_cleanup) +{ + ctx->cleanup = ctx_cleanup; +} + +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) +{ + return ctx->cleanup; +} + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) +{ + return ctx->ctx; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c new file mode 100644 index 00000000..2f2a6cdf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_obj.c @@ -0,0 +1,199 @@ +/* crypto/x509/x509_obj.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +/* + * Limit to ensure we don't overflow: much greater than + * anything enountered in practice. + */ + +#define NAME_ONELINE_MAX (1024 * 1024) + +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) +{ + X509_NAME_ENTRY *ne; + size_t i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; + + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(b, 200)) + goto err; + b->data[0] = '\0'; + len = 200; + } else if (len <= 0) { + return NULL; + } + if (a == NULL) { + if (b) { + buf = b->data; + OPENSSL_free(b); + } + OPENSSL_strlcpy(buf, "NO X509_NAME", len); + return buf; + } + + len--; /* space for '\0' */ + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + if (num > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto end; + } + q = ne->value->data; + + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) + if (q[j] != 0) + gs_doit[j & 3] = 1; + + if (gs_doit[0] | gs_doit[1] | gs_doit[2]) + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + + for (l2 = j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + l2++; + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto end; + } + if (b != NULL) { + if (!BUF_MEM_grow(b, l + 1)) + goto err; + p = &(b->data[lold]); + } else if (l > len) { + break; + } else + p = &(buf[lold]); + *(p++) = '/'; + OPENSSL_memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + + q = ne->value->data; + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + end: + BUF_MEM_free(b); + return (NULL); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_req.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_req.c new file mode 100644 index 00000000..877fee54 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_req.c @@ -0,0 +1,304 @@ +/* crypto/x509/x509_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + X509_REQ *ret; + X509_REQ_INFO *ri; + int i; + EVP_PKEY *pktmp; + + ret = X509_REQ_new(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + ri = ret->req_info; + + ri->version->length = 1; + ri->version->data = (unsigned char *)OPENSSL_malloc(1); + if (ri->version->data == NULL) + goto err; + ri->version->data[0] = 0; /* version == 0 */ + + if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) + goto err; + + pktmp = X509_get_pubkey(x); + if (pktmp == NULL) + goto err; + i = X509_REQ_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + if (pkey != NULL) { + if (!X509_REQ_sign(ret, pkey, md)) + goto err; + } + return (ret); + err: + X509_REQ_free(ret); + return (NULL); +} + +long X509_REQ_get_version(const X509_REQ *req) +{ + return ASN1_INTEGER_get(req->req_info->version); +} + +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) +{ + return req->req_info->subject; +} + +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) +{ + if ((req == NULL) || (req->req_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(req->req_info->pubkey)); +} + +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +{ + EVP_PKEY *xk = NULL; + int ok = 0; + + xk = X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) { + case 1: + ok = 1; + break; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + if (k->type == EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB); + break; + } + if (k->type == EVP_PKEY_DH) { + /* No idea */ + OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY); + break; + } + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return (ok); +} + +int X509_REQ_extension_nid(int req_nid) +{ + return req_nid == NID_ext_req || req_nid == NID_ms_ext_req; +} + +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) +{ + if (req == NULL || req->req_info == NULL) { + return NULL; + } + + int idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1); + if (idx == -1) { + idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1); + } + if (idx == -1) { + return NULL; + } + + X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx); + ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type(attr, 0); + if (!ext || ext->type != V_ASN1_SEQUENCE) { + return NULL; + } + const unsigned char *p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *) + ASN1_item_d2i(NULL, &p, ext->value.sequence->length, + ASN1_ITEM_rptr(X509_EXTENSIONS)); +} + +/* + * Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non standard one. + */ + +int X509_REQ_add_extensions_nid(X509_REQ *req, + const STACK_OF(X509_EXTENSION) *exts, int nid) +{ + /* Generate encoding of extensions */ + unsigned char *ext = NULL; + int ext_len = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, + ASN1_ITEM_rptr(X509_EXTENSIONS)); + if (ext_len <= 0) { + return 0; + } + int ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, + ext_len); + OPENSSL_free(ext); + return ret; +} + +/* This is the normal usage: use the "official" OID */ +int X509_REQ_add_extensions(X509_REQ *req, + const STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} + +/* Request attribute functions */ + +int X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} + +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} + +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} + +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} + +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&req->req_info->attributes, attr)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int attrtype, + const unsigned char *data, int len) +{ + if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + attrtype, data, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int attrtype, + const unsigned char *data, int len) +{ + if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + attrtype, data, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int attrtype, + const unsigned char *data, int len) +{ + if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + attrtype, data, len)) + return 1; + return 0; +} + +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg) +{ + if (psig != NULL) + *psig = req->signature; + if (palg != NULL) + *palg = req->sig_alg; +} + +int X509_REQ_get_signature_nid(const X509_REQ *req) +{ + return OBJ_obj2nid(req->sig_alg->algorithm); +} + +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) +{ + req->req_info->enc.modified = 1; + return i2d_X509_REQ_INFO(req->req_info, pp); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_set.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_set.c new file mode 100644 index 00000000..4f2185ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_set.c @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include + +#include "internal.h" + + +long X509_get_version(const X509 *x509) +{ + // The default version is v1(0). + if (x509->cert_info->version == NULL) { + return X509_VERSION_1; + } + return ASN1_INTEGER_get(x509->cert_info->version); +} + +int X509_set_version(X509 *x, long version) +{ + // TODO(https://crbug.com/boringssl/467): Reject invalid version numbers. + if (x == NULL) + return (0); + if (version == 0) { + ASN1_INTEGER_free(x->cert_info->version); + x->cert_info->version = NULL; + return (1); + } + if (x->cert_info->version == NULL) { + if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->cert_info->version, version)); +} + +int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->cert_info->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; + } + } + return (in != NULL); +} + +int X509_set_issuer_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->issuer, name)); +} + +int X509_set_subject_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->subject, name)); +} + +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; + } + } + return (in != NULL); +} + +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) +{ + return X509_set1_notBefore(x, tm); +} + +const ASN1_TIME *X509_get0_notBefore(const X509 *x) +{ + return x->cert_info->validity->notBefore; +} + +ASN1_TIME *X509_getm_notBefore(X509 *x) +{ + // Note this function takes a const |X509| pointer in OpenSSL. We require + // non-const as this allows mutating |x|. If it comes up for compatibility, + // we can relax this. + return x->cert_info->validity->notBefore; +} + +ASN1_TIME *X509_get_notBefore(const X509 *x509) +{ + // In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our + // |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was + // originally a macro, so it needs to capture both get0 and getm use cases. + return x509->cert_info->validity->notBefore; +} + +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; + } + } + return (in != NULL); +} + +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) +{ + return X509_set1_notAfter(x, tm); +} + +const ASN1_TIME *X509_get0_notAfter(const X509 *x) +{ + return x->cert_info->validity->notAfter; +} + +ASN1_TIME *X509_getm_notAfter(X509 *x) +{ + // Note this function takes a const |X509| pointer in OpenSSL. We require + // non-const as this allows mutating |x|. If it comes up for compatibility, + // we can relax this. + return x->cert_info->validity->notAfter; +} + +ASN1_TIME *X509_get_notAfter(const X509 *x509) +{ + // In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our + // |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was + // originally a macro, so it needs to capture both get0 and getm use cases. + return x509->cert_info->validity->notAfter; +} + +void X509_get0_uids(const X509 *x509, const ASN1_BIT_STRING **out_issuer_uid, + const ASN1_BIT_STRING **out_subject_uid) +{ + if (out_issuer_uid != NULL) { + *out_issuer_uid = x509->cert_info->issuerUID; + } + if (out_subject_uid != NULL) { + *out_subject_uid = x509->cert_info->subjectUID; + } +} + +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); +} + +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) +{ + return x->cert_info->extensions; +} + +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) +{ + return x->cert_info->signature; +} + +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) +{ + return x509->cert_info->key; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c new file mode 100644 index 00000000..50ebb917 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_trs.c @@ -0,0 +1,322 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include +#include +#include + +#include "../x509v3/internal.h" +#include "internal.h" + + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); + +/* + * WARNING: the following table should be kept in order of trust and without + * any gaps so we can just subtract the minimum trust value to get an index + * into the table + */ + +static X509_TRUST trstandard[] = { + {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client", + NID_client_auth, NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server", + NID_server_auth, NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email", + NID_email_protect, NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer", + NID_code_sign, NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *)"OCSP responder", + NID_OCSP_sign, NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request", + NID_ad_OCSP, NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp, + NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b) +{ + return (*a)->trust - (*b)->trust; +} + +int X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + if (id == -1) + return 1; + /* We get this as a default value */ + if (id == 0) { + int rv; + rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); + if (rv != X509_TRUST_UNTRUSTED) + return rv; + return trust_compat(NULL, x, 0); + } + idx = X509_TRUST_get_by_id(id); + if (idx == -1) + return obj_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} + +int X509_TRUST_get_count(void) +{ + if (!trtable) + return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} + +X509_TRUST *X509_TRUST_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_TRUST_COUNT) + return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} + +int X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + size_t idx; + + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + sk_X509_TRUST_sort(trtable); + if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { + return -1; + } + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + char *name_dup; + + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else + trtmp = X509_TRUST_get0(idx); + + /* Duplicate the supplied name. */ + name_dup = OPENSSL_strdup(name); + if (name_dup == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + if (idx == -1) + OPENSSL_free(trtmp); + return 0; + } + + /* OPENSSL_free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(trtmp->name); + trtmp->name = name_dup; + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + return 0; + } + } + return 1; +} + +static void trtable_free(X509_TRUST *p) +{ + if (!p) + return; + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(p->name); + OPENSSL_free(p); + } +} + +void X509_TRUST_cleanup(void) +{ + unsigned int i; + for (i = 0; i < X509_TRUST_COUNT; i++) + trtable_free(trstandard + i); + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} + +int X509_TRUST_get_flags(const X509_TRUST *xp) +{ + return xp->flags; +} + +char *X509_TRUST_get0_name(const X509_TRUST *xp) +{ + return xp->name; +} + +int X509_TRUST_get_trust(const X509_TRUST *xp) +{ + return xp->trust; +} + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* + * we don't have any trust settings: for compatibility we return trusted + * if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + if (!x509v3_cache_extensions(x)) + return X509_TRUST_UNTRUSTED; + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + size_t i; + X509_CERT_AUX *ax; + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_txt.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_txt.c new file mode 100644 index 00000000..32d6c39c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_txt.c @@ -0,0 +1,204 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +const char *X509_verify_cert_error_string(long err) +{ + switch (err) { + case X509_V_OK: + return "ok"; + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return "unable to get issuer certificate"; + case X509_V_ERR_UNABLE_TO_GET_CRL: + return "unable to get certificate CRL"; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return "unable to decrypt certificate's signature"; + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return "unable to decrypt CRL's signature"; + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return "unable to decode issuer public key"; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return "certificate signature failure"; + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return "CRL signature failure"; + case X509_V_ERR_CERT_NOT_YET_VALID: + return "certificate is not yet valid"; + case X509_V_ERR_CRL_NOT_YET_VALID: + return "CRL is not yet valid"; + case X509_V_ERR_CERT_HAS_EXPIRED: + return "certificate has expired"; + case X509_V_ERR_CRL_HAS_EXPIRED: + return "CRL has expired"; + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return "format error in certificate's notBefore field"; + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return "format error in certificate's notAfter field"; + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return "format error in CRL's lastUpdate field"; + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return "format error in CRL's nextUpdate field"; + case X509_V_ERR_OUT_OF_MEM: + return "out of memory"; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return "self signed certificate"; + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return "self signed certificate in certificate chain"; + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return "unable to get local issuer certificate"; + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return "unable to verify the first certificate"; + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return "certificate chain too long"; + case X509_V_ERR_CERT_REVOKED: + return "certificate revoked"; + case X509_V_ERR_INVALID_CA: + return "invalid CA certificate"; + case X509_V_ERR_INVALID_NON_CA: + return "invalid non-CA certificate (has CA markings)"; + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return "path length constraint exceeded"; + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return "proxy path length constraint exceeded"; + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return + "proxy certificates not allowed, please set the appropriate flag"; + case X509_V_ERR_INVALID_PURPOSE: + return "unsupported certificate purpose"; + case X509_V_ERR_CERT_UNTRUSTED: + return "certificate not trusted"; + case X509_V_ERR_CERT_REJECTED: + return "certificate rejected"; + case X509_V_ERR_APPLICATION_VERIFICATION: + return "application verification failure"; + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return "subject issuer mismatch"; + case X509_V_ERR_AKID_SKID_MISMATCH: + return "authority and subject key identifier mismatch"; + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return "authority and issuer serial number mismatch"; + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return "key usage does not include certificate signing"; + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return "unable to get CRL issuer certificate"; + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return "unhandled critical extension"; + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return "key usage does not include CRL signing"; + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return "key usage does not include digital signature"; + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return "unhandled critical CRL extension"; + case X509_V_ERR_INVALID_EXTENSION: + return "invalid or inconsistent certificate extension"; + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return "invalid or inconsistent certificate policy extension"; + case X509_V_ERR_NO_EXPLICIT_POLICY: + return "no explicit policy"; + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return "Different CRL scope"; + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return "Unsupported extension feature"; + case X509_V_ERR_UNNESTED_RESOURCE: + return "RFC 3779 resource not subset of parent's resources"; + + case X509_V_ERR_PERMITTED_VIOLATION: + return "permitted subtree violation"; + case X509_V_ERR_EXCLUDED_VIOLATION: + return "excluded subtree violation"; + case X509_V_ERR_SUBTREE_MINMAX: + return "name constraints minimum and maximum not supported"; + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return "unsupported name constraint type"; + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return "unsupported or invalid name constraint syntax"; + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return "unsupported or invalid name syntax"; + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return "CRL path validation error"; + + case X509_V_ERR_SUITE_B_INVALID_VERSION: + return "Suite B: certificate version invalid"; + case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: + return "Suite B: invalid public key algorithm"; + case X509_V_ERR_SUITE_B_INVALID_CURVE: + return "Suite B: invalid ECC curve"; + case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: + return "Suite B: invalid signature algorithm"; + case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: + return "Suite B: curve not allowed for this LOS"; + case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: + return "Suite B: cannot sign P-384 with P-256"; + + case X509_V_ERR_HOSTNAME_MISMATCH: + return "Hostname mismatch"; + case X509_V_ERR_EMAIL_MISMATCH: + return "Email address mismatch"; + case X509_V_ERR_IP_ADDRESS_MISMATCH: + return "IP address mismatch"; + + case X509_V_ERR_INVALID_CALL: + return "Invalid certificate verification context"; + case X509_V_ERR_STORE_LOOKUP: + return "Issuer certificate lookup error"; + + case X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS: + return "Issuer has name constraints but leaf has no SANs"; + + default: + return "unknown certificate verification error"; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c new file mode 100644 index 00000000..02a1d832 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_v3.c @@ -0,0 +1,281 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) +{ + if (x == NULL) + return (0); + return (sk_X509_EXTENSION_num(x)); +} + +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, + int lastpos) +{ + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -1; + } + return X509v3_get_ext_by_OBJ(x, obj, lastpos); +} + +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, + const ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) +{ + if (sk == NULL) { + return -1; + } + + lastpos++; + if (lastpos < 0) { + lastpos = 0; + } + + crit = !!crit; + int n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos); + if (X509_EXTENSION_get_critical(ex) == crit) { + return lastpos; + } + } + return -1; +} + +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) +{ + if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + return NULL; + else + return sk_X509_EXTENSION_value(x, loc); +} + +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) +{ + X509_EXTENSION *ret; + + if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + return (NULL); + ret = sk_X509_EXTENSION_delete(x, loc); + return (ret); +} + +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc) +{ + X509_EXTENSION *new_ex = NULL; + int n; + STACK_OF(X509_EXTENSION) *sk = NULL; + + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } else + sk = *x; + + n = sk_X509_EXTENSION_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + err2: + X509_EXTENSION_free(new_ex); + sk_X509_EXTENSION_free(sk); + return NULL; +} + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, + int crit, + const ASN1_OCTET_STRING *data) +{ + const ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + return (ret); +} + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + const ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *ex; + + if (!X509_EXTENSION_set_object(ret, obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret, crit)) + goto err; + if (!X509_EXTENSION_set_data(ret, data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) + *ex = ret; + return (ret); + err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return (NULL); +} + +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} + +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) +{ + if (ex == NULL) + return (0); + ex->critical = (crit) ? 0xFF : -1; + return (1); +} + +int X509_EXTENSION_set_data(X509_EXTENSION *ex, const ASN1_OCTET_STRING *data) +{ + int i; + + if (ex == NULL) + return (0); + i = ASN1_OCTET_STRING_set(ex->value, data->data, data->length); + if (!i) + return (0); + return (1); +} + +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->object); +} + +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->value); +} + +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) +{ + if (ex == NULL) + return (0); + if (ex->critical > 0) + return 1; + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c new file mode 100644 index 00000000..be051dff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c @@ -0,0 +1,2447 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" +#include "../x509v3/internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + +static int null_callback(int ok, X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); +static int check_id(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx); +static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, + int *pcrl_score, X509_CRL *base, + STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); + +static int internal_verify(X509_STORE_CTX *ctx); + +static int null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +/* cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns + * one and sets |*out_is_self_signed| to the result. If |x| is invalid, it + * returns zero. */ +static int cert_self_signed(X509 *x, int *out_is_self_signed) +{ + if (!x509v3_cache_extensions(x)) { + return 0; + } + *out_is_self_signed = (x->ex_flags & EXFLAG_SS) != 0; + return 1; +} + +/* Given a certificate try and find an exact match in the store */ + +static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) +{ + STACK_OF(X509) *certs; + X509 *xtmp = NULL; + size_t i; + /* Lookup all certs with matching subject name */ + certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + if (certs == NULL) + return NULL; + /* Look for exact match */ + for (i = 0; i < sk_X509_num(certs); i++) { + xtmp = sk_X509_value(certs, i); + if (!X509_cmp(xtmp, x)) + break; + } + if (i < sk_X509_num(certs)) + X509_up_ref(xtmp); + else + xtmp = NULL; + sk_X509_pop_free(certs, X509_free); + return xtmp; +} + +int X509_verify_cert(X509_STORE_CTX *ctx) +{ + X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth, i, ok = 0; + int num, j, retry, trust; + STACK_OF(X509) *sktmp = NULL; + + if (ctx->cert == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->chain != NULL) { + /* + * This X509_STORE_CTX has already been used to verify a cert. We + * cannot do another one. + */ + OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + + /* + * first we make sure the chain we are going to build is present and that + * the first entry is in place + */ + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + X509_up_ref(ctx->cert); + ctx->last_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it. */ + if (ctx->untrusted != NULL + && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + + num = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error code + * later. */ + + int is_self_signed; + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + + /* If we are self signed, we break */ + if (is_self_signed) + break; + /* + * If asked see if we can find issuer in trusted store first + */ + if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + /* + * If successful for now free up cert so it will be picked up + * again later. + */ + if (ok > 0) { + X509_free(xtmp); + break; + } + } + + /* If we were passed a cert chain, use it first */ + if (sktmp != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + X509_up_ref(xtmp); + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->last_untrusted++; + x = xtmp; + num++; + /* + * reparse the full chain for the next one + */ + continue; + } + } + break; + } + + /* Remember how many untrusted certs we have */ + j = num; + /* + * at this point, chain should contain a list of untrusted certificates. + * We now need to add at least one trusted one, if possible, otherwise we + * complain. + */ + + do { + /* + * Examine last certificate in chain and see if it is self signed. + */ + i = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + + int is_self_signed; + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + + if (is_self_signed) { + /* we have a self signed certificate */ + if (sk_X509_num(ctx->chain) == 1) { + /* + * We have a single self signed certificate: see if we can + * find it in the store. We must have an exact match to avoid + * possible impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) + X509_free(xtmp); + bad_chain = 1; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } else { + /* + * We have a match: replace certificate with store + * version so we get any trust settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted = 0; + } + } else { + /* + * extract and save self signed certificate for later use + */ + chain_ss = sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + j--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + /* We now lookup certs from the certificate store */ + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + /* If we are self signed, we break */ + if (is_self_signed) + break; + ok = ctx->get_issuer(&xtmp, ctx, x); + + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + } + + /* we now have our chain, lets check it... */ + trust = check_trust(ctx); + + /* If explicitly rejected error */ + if (trust == X509_TRUST_REJECTED) { + ok = 0; + goto end; + } + /* + * If it's not explicitly trusted then check if there is an alternative + * chain that could be used. We only do this if we haven't already + * checked via TRUSTED_FIRST and the user hasn't switched off alternate + * chain checking + */ + retry = 0; + if (trust != X509_TRUST_TRUSTED + && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) + && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { + while (j-- > 1) { + xtmp2 = sk_X509_value(ctx->chain, j - 1); + ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + if (ok < 0) + goto end; + /* Check if we found an alternate chain */ + if (ok > 0) { + /* + * Free up the found cert we'll add it again later + */ + X509_free(xtmp); + + /* + * Dump all the certs above this point - we've found an + * alternate chain + */ + while (num > j) { + xtmp = sk_X509_pop(ctx->chain); + X509_free(xtmp); + num--; + } + ctx->last_untrusted = sk_X509_num(ctx->chain); + retry = 1; + break; + } + } + } + } while (retry); + + /* + * If not explicitly trusted then indicate error unless it's a single + * self signed certificate in which case we've indicated an error already + * and set bad_chain == 1 + */ + if (trust != X509_TRUST_TRUSTED && !bad_chain) { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->last_untrusted >= num) + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert = x; + } else { + + sk_X509_push(ctx->chain, chain_ss); + num++; + ctx->last_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto end; + + ok = check_id(ctx); + + if (!ok) + goto end; + + /* + * Check revocation status: we do this after copying parameters because + * they may be needed for CRL signature verification. + */ + + ok = ctx->check_revocation(ctx); + if (!ok) + goto end; + + int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, + ctx->param->flags); + if (err != X509_V_OK) { + ctx->error = err; + ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok = ctx->verify(ctx); + else + ok = internal_verify(ctx); + if (!ok) + goto end; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + if (!ok) + goto end; + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + + end: + if (sktmp != NULL) + sk_X509_free(sktmp); + if (chain_ss != NULL) + X509_free(chain_ss); + + /* Safety net, error returns must set ctx->error */ + if (ok <= 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + return ok; +} + +/* + * Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) +{ + size_t i; + X509 *issuer; + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) + return issuer; + } + return NULL; +} + +/* Given a possible certificate and issuer check them */ + +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +{ + int ret; + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) + return 1; + /* If we haven't asked for issuer errors don't set ctx */ + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) + return 0; + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); +} + +/* Alternative lookup method: look from a STACK stored in other_ctx */ + +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) { + X509_up_ref(*issuer); + return 1; + } else + return 0; +} + +/* + * Check a certificate chains extensions for consistency with the supplied + * purpose + */ + +static int check_chain_extensions(X509_STORE_CTX *ctx) +{ + int i, ok = 0, plen = 0; + X509 *x; + int proxy_path_length = 0; + int purpose; + int allow_proxy_certs; + + enum { + // ca_or_leaf allows either type of certificate so that direct use of + // self-signed certificates works. + ca_or_leaf, + must_be_ca, + must_not_be_ca, + } ca_requirement; + + /* CRL path validation */ + if (ctx->parent) { + allow_proxy_certs = 0; + purpose = X509_PURPOSE_CRL_SIGN; + } else { + allow_proxy_certs = + ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + purpose = ctx->param->purpose; + } + + ca_requirement = ca_or_leaf; + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->last_untrusted; i++) { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { + ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + + switch (ca_requirement) { + case ca_or_leaf: + ret = 1; + break; + case must_not_be_ca: + if (X509_check_ca(x)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_NON_CA; + } else + ret = 1; + break; + case must_be_ca: + if (!X509_check_ca(x)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + default: + // impossible. + ret = 0; + } + + if (ret == 0) { + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + if (ctx->param->purpose > 0) { + ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca); + if (ret != 1) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + } + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; + /* + * If this certificate is a proxy certificate, the next certificate + * must be another proxy certificate or a EE certificate. If not, + * the next certificate must be a CA certificate. + */ + if (x->ex_flags & EXFLAG_PROXY) { + if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) { + ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } + proxy_path_length++; + ca_requirement = must_not_be_ca; + } else { + ca_requirement = must_be_ca; + } + } + ok = 1; + end: + return ok; +} + +static int reject_dns_name_in_common_name(X509 *x509) +{ + X509_NAME *name = X509_get_subject_name(x509); + int i = -1; + for (;;) { + i = X509_NAME_get_index_by_NID(name, NID_commonName, i); + if (i == -1) { + return X509_V_OK; + } + + X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); + ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(entry); + unsigned char *idval; + int idlen = ASN1_STRING_to_UTF8(&idval, common_name); + if (idlen < 0) { + return X509_V_ERR_OUT_OF_MEM; + } + /* Only process attributes that look like host names. Note it is + * important that this check be mirrored in |X509_check_host|. */ + int looks_like_dns = x509v3_looks_like_dns_name(idval, (size_t)idlen); + OPENSSL_free(idval); + if (looks_like_dns) { + return X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS; + } + } +} + +static int check_name_constraints(X509_STORE_CTX *ctx) +{ + int i, j, rv; + int has_name_constraints = 0; + /* Check name constraints for all certificates */ + for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { + X509 *x = sk_X509_value(ctx->chain, i); + /* Ignore self issued certs unless last in chain */ + if (i && (x->ex_flags & EXFLAG_SI)) + continue; + /* + * Check against constraints for all certificates higher in chain + * including trust anchor. Trust anchor not strictly speaking needed + * but if it includes constraints it is to be assumed it expects them + * to be obeyed. + */ + for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) { + has_name_constraints = 1; + rv = NAME_CONSTRAINTS_check(x, nc); + switch (rv) { + case X509_V_OK: + continue; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + break; + } + } + } + } + + /* Name constraints do not match against the common name, but + * |X509_check_host| still implements the legacy behavior where, on + * certificates lacking a SAN list, DNS-like names in the common name are + * checked instead. + * + * While we could apply the name constraints to the common name, name + * constraints are rare enough that can hold such certificates to a higher + * standard. Note this does not make "DNS-like" heuristic failures any + * worse. A decorative common-name misidentified as a DNS name would fail + * the name constraint anyway. */ + X509 *leaf = sk_X509_value(ctx->chain, 0); + if (has_name_constraints && leaf->altname == NULL) { + rv = reject_dns_name_in_common_name(leaf); + switch (rv) { + case X509_V_OK: + break; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = leaf; + if (!ctx->verify_cb(0, ctx)) + return 0; + break; + } + } + + return 1; +} + +static int check_id_error(X509_STORE_CTX *ctx, int errcode) +{ + ctx->error = errcode; + ctx->current_cert = ctx->cert; + ctx->error_depth = 0; + return ctx->verify_cb(0, ctx); +} + +static int check_hosts(X509 *x, X509_VERIFY_PARAM *param) +{ + size_t i; + size_t n = sk_OPENSSL_STRING_num(param->hosts); + char *name; + + if (param->peername != NULL) { + OPENSSL_free(param->peername); + param->peername = NULL; + } + for (i = 0; i < n; ++i) { + name = sk_OPENSSL_STRING_value(param->hosts, i); + if (X509_check_host(x, name, strlen(name), param->hostflags, + ¶m->peername) > 0) + return 1; + } + return n == 0; +} + +static int check_id(X509_STORE_CTX *ctx) +{ + X509_VERIFY_PARAM *vpm = ctx->param; + X509 *x = ctx->cert; + if (vpm->poison) { + if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) + return 0; + } + if (vpm->hosts && check_hosts(x, vpm) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) + return 0; + } + if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) + return 0; + } + if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) + return 0; + } + return 1; +} + +static int check_trust(X509_STORE_CTX *ctx) +{ + size_t i; + int ok; + X509 *x = NULL; + /* Check all trusted certificates in chain */ + for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + /* If explicitly trusted return trusted */ + if (ok == X509_TRUST_TRUSTED) + return X509_TRUST_TRUSTED; + /* + * If explicitly rejected notify callback and reject if not + * overridden. + */ + if (ok == X509_TRUST_REJECTED) { + ctx->error_depth = i; + ctx->current_cert = x; + ctx->error = X509_V_ERR_CERT_REJECTED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return X509_TRUST_REJECTED; + } + } + /* + * If we accept partial chains and have at least one trusted certificate + * return success. + */ + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + X509 *mx; + if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain)) + return X509_TRUST_TRUSTED; + x = sk_X509_value(ctx->chain, 0); + mx = lookup_cert_match(ctx, x); + if (mx) { + (void)sk_X509_set(ctx->chain, 0, mx); + X509_free(x); + ctx->last_untrusted = 0; + return X509_TRUST_TRUSTED; + } + } + + /* + * If no trusted certs in chain at all return untrusted and allow + * standard (no issuer cert) etc errors to be indicated. + */ + return X509_TRUST_UNTRUSTED; +} + +static int check_revocation(X509_STORE_CTX *ctx) +{ + int i, last, ok; + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; + last = 0; + } + for (i = 0; i <= last; i++) { + ctx->error_depth = i; + ok = check_cert(ctx); + if (!ok) + return ok; + } + return 1; +} + +static int check_cert(X509_STORE_CTX *ctx) +{ + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok = 0, cnum; + unsigned int last_reasons; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* + * If error looking up CRL, nothing we can do except notify callback + */ + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + /* + * If reasons not updated we wont get anywhere by another iteration, + * so exit loop. + */ + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } + err: + X509_CRL_free(crl); + X509_CRL_free(dcrl); + + ctx->current_crl = NULL; + return ok; + +} + +/* Check CRL times against values in X509_STORE_CTX */ + +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) +{ + time_t *ptime; + int i; + if (notify) + ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (X509_CRL_get0_nextUpdate(crl)) { + i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + if (notify) + ctx->current_crl = NULL; + + return 1; +} + +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) +{ + int crl_score, best_score = *pscore; + size_t i; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + if (crl_score < best_score || crl_score == 0) + continue; + /* If current CRL is equivalent use it if it is newer */ + if (crl_score == best_score && best_crl != NULL) { + int day, sec; + if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl), + X509_CRL_get0_lastUpdate(crl)) == 0) + continue; + /* + * ASN1_TIME_diff never returns inconsistent signs for |day| + * and |sec|. + */ + if (day <= 0 && sec <= 0) + continue; + } + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } + + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + X509_CRL_up_ref(best_crl); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + + if (best_score >= CRL_SCORE_VALID) + return 1; + + return 0; +} + +/* + * Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. + */ + +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) +{ + ASN1_OCTET_STRING *exta, *extb; + int i; + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else + extb = NULL; + + if (!exta && !extb) + return 1; + + if (!exta || !extb) + return 0; + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; +} + +/* See if a base and delta are compatible */ + +static int check_delta_base(X509_CRL *delta, X509_CRL *base) +{ + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; +} + +/* + * For a given base CRL find a delta... maybe extend to delta scoring or + * retrieve a chain of deltas... + */ + +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, + X509_CRL *base, STACK_OF(X509_CRL) *crls) +{ + X509_CRL *delta; + size_t i; + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + X509_CRL_up_ref(delta); + *dcrl = delta; + return; + } + } + *dcrl = NULL; +} + +/* + * For a given CRL return how suitable it is for the supplied certificate + * 'x'. The return value is a mask of several criteria. If the issuer is not + * the certificate issuer this is returned in *pissuer. The reasons mask is + * also used to determine if the CRL is suitable: if no new reasons the CRL + * is rejected, otherwise reasons is updated. + */ + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x) +{ + + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } else if (crl->idp_flags & IDP_REASONS) { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; + +} + +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 **pissuer, int *pcrl_score) +{ + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + size_t i; + + if ((size_t)cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* + * Otherwise the CRL issuer is not on the path. Look for it in the set of + * untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } +} + +/* + * Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking will + * be duplicated by the parent, but this will rarely be used in practice. + */ + +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) +{ + X509_STORE_CTX crl_ctx; + int ret; + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + return -1; + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +/* + * RFC 3280 says nothing about the relationship between CRL path and + * certificate path, which could lead to situations where a certificate could + * be revoked or validated by a CA not authorised to do so. RFC 5280 is more + * strict and states that the two paths must end in the same trust anchor, + * though some discussions remain... until this is resolved we use the + * RFC 5280 version + */ + +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) +{ + X509 *cert_ta, *crl_ta; + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; +} + +/* + * Check for match between two dist point names: three separate cases. 1. + * Both are relative names and compare X509_NAME types. 2. One full, one + * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and + * compare two GENERAL_NAMES. 4. One is NULL: automatic match. + */ + +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) +{ + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + size_t i, j; + if (!a || !b) + return 1; + if (a->type == 1) { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; + } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; + +} + +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) +{ + size_t i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return ! !(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; +} + +/* Check CRLDP and IDP */ + +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons) +{ + size_t i; + if (crl->idp_flags & IDP_ONLYATTR) + return 0; + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } else { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) + && (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; +} + +/* + * Retrieve CRL corresponding to current certificate. If deltas enabled try + * to find a delta CRL too + */ + +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) +{ + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, + &issuer, &crl_score, &reasons, ctx->crls); + + if (ok) + goto done; + + /* Lookup CRLs from store */ + + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + + done: + + /* If we got any kind of CRL use it and return success */ + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +/* Check CRL validity */ +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) +{ + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) + issuer = ctx->current_issuer; + + /* + * Else find CRL issuer: if not last certificate then issuer is next + * certificate in chain. + */ + else if (cnum < chnum) + issuer = sk_X509_value(ctx->chain, cnum + 1); + else { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (issuer) { + /* + * Skip most tests for deltas because they have already been done + */ + if (!crl->base_crl_number) { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } else { + int rv; + rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); + if (rv != X509_V_OK) { + ctx->error = rv; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + /* Verify CRL signature */ + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + } + + ok = 1; + + err: + EVP_PKEY_free(ikey); + return ok; +} + +/* Check certificate against CRL */ +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) +{ + int ok; + X509_REVOKED *rev; + /* + * The rules changed for this... previously if a CRL contained unhandled + * critical extensions it could still be used to indicate a certificate + * was revoked. This has since been changed since critical extension can + * change the meaning of CRL entries. + */ + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + /* + * Look for serial number of certificate in CRL If found make sure reason + * is not removeFromCRL. + */ + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + + return 1; +} + +static int check_policy(X509_STORE_CTX *ctx) +{ + int ret; + if (ctx->parent) + return 1; + ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, + ctx->param->policies, ctx->param->flags); + if (ret == 0) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + /* Invalid or inconsistent extensions */ + if (ret == -1) { + /* + * Locate certificates with bad extensions and notify callback. + */ + X509 *x; + size_t i; + for (i = 1; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; + ctx->current_cert = x; + ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + return 1; + } + if (ret == -2) { + ctx->current_cert = NULL; + ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + /* + * Verification errors need to be "sticky", a callback may have allowed + * an SSL handshake to continue despite an error, and we must then + * remain in an error state. Therefore, we MUST NOT clear earlier + * verification errors by setting the error to X509_V_OK. + */ + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; +} + +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) +{ + time_t *ptime; + int i; + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_get_notBefore(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + i = X509_cmp_time(X509_get_notAfter(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) { + ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + return 1; +} + +static int internal_verify(X509_STORE_CTX *ctx) +{ + int ok = 0, n; + X509 *xs, *xi; + EVP_PKEY *pkey = NULL; + + n = sk_X509_num(ctx->chain); + ctx->error_depth = n - 1; + n--; + xi = sk_X509_value(ctx->chain, n); + + if (ctx->check_issued(ctx, xi, xi)) + xs = xi; + else { + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + xs = xi; + goto check_cert; + } + if (n <= 0) { + ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert = xi; + ok = ctx->verify_cb(0, ctx); + goto end; + } else { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + } + +/* ctx->error=0; not needed */ + while (n >= 0) { + ctx->error_depth = n; + + /* + * Skip signature check for self signed certificates unless + * explicitly asked for. It doesn't add any security and just wastes + * time. + */ + if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) { + if ((pkey = X509_get_pubkey(xi)) == NULL) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert = xi; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto end; + } else if (X509_verify(xs, pkey) <= 0) { + ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert = xs; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + EVP_PKEY_free(pkey); + goto end; + } + } + EVP_PKEY_free(pkey); + pkey = NULL; + } + + check_cert: + ok = check_cert_time(ctx, xs); + if (!ok) + goto end; + + /* The last error (if any) is still in the error value */ + ctx->current_issuer = xi; + ctx->current_cert = xs; + ok = ctx->verify_cb(1, ctx); + if (!ok) + goto end; + + n--; + if (n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + ok = 1; + end: + return ok; +} + +int X509_cmp_current_time(const ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} + +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1; + static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; + ASN1_TIME *asn1_cmp_time = NULL; + int i, day, sec, ret = 0; + + /* + * Note that ASN.1 allows much more slack in the time format than RFC 5280. + * In RFC 5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ + * GeneralizedTime: YYYYMMDDHHMMSSZ + * + * We do NOT currently enforce the following RFC 5280 requirement: + * "CAs conforming to this profile MUST always encode certificate + * validity dates through the year 2049 as UTCTime; certificate validity + * dates in 2050 or later MUST be encoded as GeneralizedTime." + */ + switch (ctm->type) { + case V_ASN1_UTCTIME: + if (ctm->length != (int)(utctime_length)) + return 0; + break; + case V_ASN1_GENERALIZEDTIME: + if (ctm->length != (int)(generalizedtime_length)) + return 0; + break; + default: + return 0; + } + + /** + * Verify the format: the ASN.1 functions we use below allow a more + * flexible format than what's mandated by RFC 5280. + * Digit and date ranges will be verified in the conversion methods. + */ + for (i = 0; i < ctm->length - 1; i++) { + if (!isdigit(ctm->data[i])) + return 0; + } + if (ctm->data[ctm->length - 1] != 'Z') + return 0; + + /* + * There is ASN1_UTCTIME_cmp_time_t but no + * ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t, + * so we go through ASN.1 + */ + asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time); + if (asn1_cmp_time == NULL) + goto err; + if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) + goto err; + + /* + * X509_cmp_time comparison is <=. + * The return value 0 is reserved for errors. + */ + ret = (day >= 0 && sec >= 0) ? -1 : 1; + + err: + ASN1_TIME_free(asn1_cmp_time); + return ret; +} + +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec) +{ + return X509_time_adj(s, offset_sec, NULL); +} + +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) +{ + return X509_time_adj_ex(s, 0, offset_sec, in_tm); +} + +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *in_tm) +{ + time_t t = 0; + + if (in_tm) { + t = *in_tm; + } else { + time(&t); + } + + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} + +/* Make a delta CRL as the diff between two full CRLs */ + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) +{ + X509_CRL *crl = NULL; + int i; + size_t j; + STACK_OF(X509_REVOKED) *revs = NULL; + /* CRLs can't be delta already */ + if (base->base_crl_number || newer->base_crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA); + return NULL; + } + /* Base and new CRL must have a CRL number */ + if (!base->crl_number || !newer->crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER); + return NULL; + } + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { + OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH); + return NULL; + } + /* AKID and IDP must match */ + if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { + OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH); + return NULL; + } + if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { + OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH); + return NULL; + } + /* Newer CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER); + return NULL; + } + /* CRLs must verify */ + if (skey && (X509_CRL_verify(base, skey) <= 0 || + X509_CRL_verify(newer, skey) <= 0)) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE); + return NULL; + } + /* Create new CRL */ + crl = X509_CRL_new(); + if (!crl || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) + goto memerr; + /* Set issuer name */ + if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) + goto memerr; + + if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) + goto memerr; + if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) + goto memerr; + + /* Set base CRL number: must be critical */ + + if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) + goto memerr; + + /* + * Copy extensions across from newest CRL to delta: this will set CRL + * number to correct value too. + */ + + for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { + X509_EXTENSION *ext; + ext = X509_CRL_get_ext(newer, i); + if (!X509_CRL_add_ext(crl, ext, -1)) + goto memerr; + } + + /* Go through revoked entries, copying as needed */ + + revs = X509_CRL_get_REVOKED(newer); + + for (j = 0; j < sk_X509_REVOKED_num(revs); j++) { + X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, j); + /* + * Add only if not also in base. TODO: need something cleverer here + * for some more complex CRLs covering multiple CAs. + */ + if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) { + rvtmp = X509_REVOKED_dup(rvn); + if (!rvtmp) + goto memerr; + if (!X509_CRL_add0_revoked(crl, rvtmp)) { + X509_REVOKED_free(rvtmp); + goto memerr; + } + } + } + /* TODO: optionally prune deleted entries */ + + if (skey && md && !X509_CRL_sign(crl, skey, md)) + goto memerr; + + return crl; + + memerr: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + if (crl) + X509_CRL_free(crl); + return NULL; +} + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused * unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) +{ + /* + * This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). + */ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) +{ + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +{ + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ + return ctx->error; +} + +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; +} + +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ + return ctx->error_depth; +} + +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +{ + return ctx->current_cert; +} + +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} + +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} + +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +{ + if (!ctx->chain) + return NULL; + return X509_chain_up_ref(ctx->chain); +} + +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +{ + return ctx->current_issuer; +} + +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +{ + return ctx->current_crl; +} + +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +{ + return ctx->parent; +} + +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->cert = x; +} + +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} + +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->untrusted; +} + +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) +{ + ctx->crls = sk; +} + +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); +} + +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); +} + +/* + * This function is used to set the X509_STORE_CTX purpose and trust values. + * This is intended to be used when another structure has its own trust and + * purpose values which (if set) will be inherited by the ctx. If they aren't + * set then we will usually have a default purpose in mind which should then + * be used to set the trust value. An example of this is SSL use: an SSL + * structure will have its own purpose and trust settings which the + * application can set: if they aren't set then we use the default of SSL + * client/server. + */ + +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + /* If purpose not set use default */ + if (!purpose) + purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) + trust = ptmp->trust; + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) + ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) + ctx->param->trust = trust; + return 1; +} + +X509_STORE_CTX *X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); + if (!ctx) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509_STORE_CTX_zero(ctx); + return ctx; +} + +void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) +{ + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) { + return; + } + X509_STORE_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + STACK_OF(X509) *chain) +{ + X509_STORE_CTX_zero(ctx); + ctx->ctx = store; + ctx->cert = x509; + ctx->untrusted = chain; + + CRYPTO_new_ex_data(&ctx->ex_data); + + if (store == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) + goto err; + + /* + * Inherit callbacks and flags from X509_STORE. + */ + + ctx->verify_cb = store->verify_cb; + ctx->cleanup = store->cleanup; + + if (!X509_VERIFY_PARAM_inherit(ctx->param, store->param) || + !X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default"))) { + goto err; + } + + if (store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = NULL; + + if (store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + if (store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_get1_certs; + + if (store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_get1_crls; + + ctx->check_policy = check_policy; + + return 1; + + err: + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); + if (ctx->param != NULL) { + X509_VERIFY_PARAM_free(ctx->param); + } + + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; +} + +/* + * Set alternative lookup method: just a STACK of trusted certificates. This + * avoids X509_STORE nastiness where it isn't needed. + */ + +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; +} + +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) +{ + /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free| + * also calls this function. */ + if (ctx->cleanup != NULL) { + ctx->cleanup(ctx); + ctx->cleanup = NULL; + } + if (ctx->param != NULL) { + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = NULL; + } + if (ctx->tree != NULL) { + X509_policy_tree_free(ctx->tree); + ctx->tree = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data)); + OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +} + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) +{ + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t) +{ + X509_VERIFY_PARAM_set_time(ctx->param, t); +} + +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) +{ + return ctx->cert; +} + +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) +{ + return ctx->tree; +} + +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) +{ + return ctx->explicit_policy; +} + +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) +{ + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); +} + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +{ + return ctx->param; +} + +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) +{ + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c new file mode 100644 index 00000000..7cf8e0ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c @@ -0,0 +1,651 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" +#include "../x509v3/internal.h" + + +/* X509_VERIFY_PARAM functions */ + +#define SET_HOST 0 +#define ADD_HOST 1 + +static char *str_copy(char *s) +{ + return OPENSSL_strdup(s); +} + +static void str_free(char *s) +{ + OPENSSL_free(s); +} + +#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) + +static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode, + const char *name, size_t namelen) +{ + char *copy; + + if (name == NULL || namelen == 0) { + // Unlike OpenSSL, we reject trying to set or add an empty name. + return 0; + } + + /* + * Refuse names with embedded NUL bytes. + * XXX: Do we need to push an error onto the error stack? + */ + if (name && OPENSSL_memchr(name, '\0', namelen)) + return 0; + + if (mode == SET_HOST && param->hosts) { + string_stack_free(param->hosts); + param->hosts = NULL; + } + + copy = OPENSSL_strndup(name, namelen); + if (copy == NULL) + return 0; + + if (param->hosts == NULL && + (param->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { + OPENSSL_free(copy); + return 0; + } + + if (!sk_OPENSSL_STRING_push(param->hosts, copy)) { + OPENSSL_free(copy); + if (sk_OPENSSL_STRING_num(param->hosts) == 0) { + sk_OPENSSL_STRING_free(param->hosts); + param->hosts = NULL; + } + return 0; + } + + return 1; +} + +static void x509_verify_param_zero(X509_VERIFY_PARAM *param) +{ + if (!param) + return; + param->name = NULL; + param->purpose = 0; + param->trust = 0; + /* + * param->inh_flags = X509_VP_FLAG_DEFAULT; + */ + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } + if (param->hosts) { + string_stack_free(param->hosts); + param->hosts = NULL; + } + if (param->peername) { + OPENSSL_free(param->peername); + param->peername = NULL; + } + if (param->email) { + OPENSSL_free(param->email); + param->email = NULL; + param->emaillen = 0; + } + if (param->ip) { + OPENSSL_free(param->ip); + param->ip = NULL; + param->iplen = 0; + } + param->poison = 0; +} + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + if (!param) + return NULL; + OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM)); + x509_verify_param_zero(param); + return param; +} + +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) +{ + if (param == NULL) + return; + x509_verify_param_zero(param); + OPENSSL_free(param); +} + +/*- + * This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ + +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != (def)) && (to_default || (dest->field == (def))))) + +/* Macro to test and copy a field if necessary */ + +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, + const X509_VERIFY_PARAM *src) +{ + unsigned long inh_flags; + int to_default, to_overwrite; + if (!src) + return 1; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + /* Copy the host flags if and only if we're copying the host list */ + if (test_x509_verify_param_copy(hosts, NULL)) { + if (dest->hosts) { + string_stack_free(dest->hosts); + dest->hosts = NULL; + } + if (src->hosts) { + dest->hosts = + sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); + if (dest->hosts == NULL) + return 0; + dest->hostflags = src->hostflags; + } + } + + if (test_x509_verify_param_copy(email, NULL)) { + if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) + return 0; + } + + if (test_x509_verify_param_copy(ip, NULL)) { + if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) + return 0; + } + + dest->poison = src->poison; + + return 1; +} + +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from) +{ + unsigned long save_flags = to->inh_flags; + int ret; + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; +} + +static int int_x509_param_set1(char **pdest, size_t *pdestlen, + const char *src, size_t srclen) +{ + void *tmp; + if (src == NULL || srclen == 0) { + // Unlike OpenSSL, we do not allow an empty string to disable previously + // configured checks. + return 0; + } + + tmp = OPENSSL_memdup(src, srclen); + if (!tmp) { + return 0; + } + + if (*pdest) + OPENSSL_free(*pdest); + *pdest = tmp; + if (pdestlen) + *pdestlen = srclen; + return 1; +} + +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) +{ + if (param->name) + OPENSSL_free(param->name); + param->name = OPENSSL_strdup(name); + if (param->name) + return 1; + return 0; +} + +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags |= flags; + if (flags & X509_V_FLAG_POLICY_MASK) + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags) +{ + param->flags &= ~flags; + return 1; +} + +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +{ + return param->flags; +} + +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) +{ + return X509_PURPOSE_set(¶m->purpose, purpose); +} + +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) +{ + return X509_TRUST_set(¶m->trust, trust); +} + +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) +{ + param->depth = depth; +} + +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) +{ + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} + +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy) +{ + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; +} + +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) +{ + size_t i; + ASN1_OBJECT *oid, *doid; + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) { + ASN1_OBJECT_free(doid); + return 0; + } + } + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (!int_x509_param_set_hosts(param, SET_HOST, name, namelen)) { + param->poison = 1; + return 0; + } + return 1; +} + +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (!int_x509_param_set_hosts(param, ADD_HOST, name, namelen)) { + param->poison = 1; + return 0; + } + return 1; +} + +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags) +{ + param->hostflags = flags; +} + +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) +{ + return param->peername; +} + +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen) +{ + if (OPENSSL_memchr(email, '\0', emaillen) != NULL || + !int_x509_param_set1(¶m->email, ¶m->emaillen, + email, emaillen)) { + param->poison = 1; + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen) +{ + if ((iplen != 4 && iplen != 16) || + !int_x509_param_set1((char **)¶m->ip, ¶m->iplen, + (char *)ip, iplen)) { + param->poison = 1; + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) +{ + unsigned char ipout[16]; + size_t iplen; + + iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); + if (iplen == 0) + return 0; + return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); +} + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) +{ + return param->depth; +} + +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) +{ + return param->name; +} + +#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0, 0 + +/* + * Default verify parameters: these are used for various applications and can + * be overridden by the user specified table. NB: the 'name' field *must* be + * in alphabetical order because it will be searched using OBJ_search. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + (char *)"default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + X509_V_FLAG_TRUSTED_FIRST, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"pkcs7", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"smime_sign", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"ssl_client", /* SSL/TLS client parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_CLIENT, /* purpose */ + X509_TRUST_SSL_CLIENT, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"ssl_server", /* SSL/TLS server parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_SERVER, /* purpose */ + X509_TRUST_SSL_SERVER, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id} +}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + size_t idx; + + sk_X509_VERIFY_PARAM_sort(param_table); + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; +} + +int X509_VERIFY_PARAM_get_count(void) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (param_table) + num += sk_X509_VERIFY_PARAM_num(param_table); + return num; +} + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (id < num) + return default_table + id; + return sk_X509_VERIFY_PARAM_value(param_table, id - num); +} + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) +{ + X509_VERIFY_PARAM pm; + unsigned i, limit; + + pm.name = (char *)name; + if (param_table) { + size_t idx; + sk_X509_VERIFY_PARAM_sort(param_table); + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm)) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + + limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + for (i = 0; i < limit; i++) { + if (strcmp(default_table[i].name, name) == 0) { + return &default_table[i]; + } + } + return NULL; +} + +void X509_VERIFY_PARAM_table_cleanup(void) +{ + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); + param_table = NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509cset.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509cset.c new file mode 100644 index 00000000..31601471 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509cset.c @@ -0,0 +1,279 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +int X509_CRL_set_version(X509_CRL *x, long version) +{ + /* TODO(https://crbug.com/boringssl/467): Reject invalid version + * numbers. Also correctly handle |X509_CRL_VERSION_1|, which should omit + * the encoding. */ + if (x == NULL) + return (0); + if (x->crl->version == NULL) { + if ((x->crl->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->crl->version, version)); +} + +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +{ + if ((x == NULL) || (x->crl == NULL)) + return (0); + return (X509_NAME_set(&x->crl->issuer, name)); +} + +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->lastUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->nextUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_sort(X509_CRL *c) +{ + /* Sort the data so it will be written in serial number order. */ + sk_X509_REVOKED_sort(c->crl->revoked); + c->crl->enc.modified = 1; + return 1; +} + +int X509_CRL_up_ref(X509_CRL *crl) +{ + CRYPTO_refcount_inc(&crl->references); + return 1; +} + +long X509_CRL_get_version(const X509_CRL *crl) +{ + return ASN1_INTEGER_get(crl->crl->version); +} + +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl) +{ + return crl->crl->lastUpdate; +} + +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) +{ + return crl->crl->nextUpdate; +} + +ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) +{ + return crl->crl->lastUpdate; +} + +ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl) +{ + return crl->crl->nextUpdate; +} + +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl) +{ + return crl->crl->issuer; +} + +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl) +{ + return crl->crl->revoked; +} + +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl) +{ + return crl->crl->extensions; +} + +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg) +{ + if (psig != NULL) + *psig = crl->signature; + if (palg != NULL) + *palg = crl->sig_alg; +} + +int X509_CRL_get_signature_nid(const X509_CRL *crl) +{ + return OBJ_obj2nid(crl->sig_alg->algorithm); +} + +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *revoked) +{ + return revoked->revocationDate; +} + +int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (revoked == NULL) + return (0); + in = revoked->revocationDate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(revoked->revocationDate); + revoked->revocationDate = in; + } + } + return (in != NULL); +} + +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *revoked) +{ + return revoked->serialNumber; +} + +int X509_REVOKED_set_serialNumber(X509_REVOKED *revoked, + const ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (revoked == NULL) + return (0); + in = revoked->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(revoked->serialNumber); + revoked->serialNumber = in; + } + } + return (in != NULL); +} + +const STACK_OF(X509_EXTENSION) * + X509_REVOKED_get0_extensions(const X509_REVOKED *r) +{ + return r->extensions; +} + +int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) +{ + crl->crl->enc.modified = 1; + return i2d_X509_CRL_INFO(crl->crl, outp); +} + +int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) +{ + return i2d_X509_CRL_INFO(crl->crl, outp); +} + +int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo) +{ + /* TODO(davidben): Const-correct generated ASN.1 dup functions. + * Alternatively, when the types are hidden and we can embed required fields + * directly in structs, import |X509_ALGOR_copy| from upstream. */ + X509_ALGOR *copy1 = X509_ALGOR_dup((X509_ALGOR *)algo); + X509_ALGOR *copy2 = X509_ALGOR_dup((X509_ALGOR *)algo); + if (copy1 == NULL || copy2 == NULL) { + X509_ALGOR_free(copy1); + X509_ALGOR_free(copy2); + return 0; + } + + X509_ALGOR_free(crl->sig_alg); + crl->sig_alg = copy1; + X509_ALGOR_free(crl->crl->sig_alg); + crl->crl->sig_alg = copy2; + return 1; +} + +int X509_CRL_set1_signature_value(X509_CRL *crl, const uint8_t *sig, + size_t sig_len) +{ + if (!ASN1_STRING_set(crl->signature, sig, sig_len)) { + return 0; + } + crl->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + crl->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509name.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509name.c new file mode 100644 index 00000000..620950be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509name.c @@ -0,0 +1,388 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, char *buf, + int len) +{ + const ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-1); + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); +} + +int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + char *buf, int len) +{ + int i; + ASN1_STRING *data; + + i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) + return (-1); + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + i = (data->length > (len - 1)) ? (len - 1) : data->length; + if (buf == NULL) + return (data->length); + OPENSSL_memcpy(buf, data->data, i); + buf[i] = '\0'; + return (i); +} + +int X509_NAME_entry_count(const X509_NAME *name) +{ + if (name == NULL) + return (0); + return (sk_X509_NAME_ENTRY_num(name->entries)); +} + +int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) +{ + const ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); +} + +/* NOTE: you should be passsing -1, not 0 as lastpos */ +int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos) +{ + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (-1); + if (lastpos < 0) + lastpos = -1; + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) +{ + if (name == NULL || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + return (NULL); + else + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +} + +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) +{ + X509_NAME_ENTRY *ret; + int i, n, set_prev, set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + return (NULL); + sk = name->entries; + ret = sk_X509_NAME_ENTRY_delete(sk, loc); + n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if (loc == n) + return (ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; + else + set_prev = ret->set - 1; + set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + /* + * set_prev is the previous set set is the current set set_next is the + * following prev 1 1 1 1 1 1 1 1 set 1 1 2 2 next 1 1 2 2 2 2 3 2 so + * basically only if prev and next differ by 2, then re-number down by 1 + */ + if (set_prev + 1 < set_next) + for (i = loc; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set--; + return (ret); +} + +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +/* + * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the + * guy we are about to stomp on. + */ +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, + int set) +{ + X509_NAME_ENTRY *new_name = NULL; + int n, i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (0); + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + inc = (set == 0); + name->modified = 1; + + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + } + } else { /* if (set >= 0) */ + + if (loc >= n) { + if (loc != 0) + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + else + set = 0; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + } + + if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) + goto err; + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) { + n = sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set += 1; + } + return (1); + err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return (0); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", field); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, + const unsigned char *bytes, + int len) +{ + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len) +{ + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) + return (NULL); + } else + ret = *ne; + + if (!X509_NAME_ENTRY_set_object(ret, obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) + *ne = ret; + return (ret); + err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return (NULL); +} + +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); +} + +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) +{ + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) + return (0); + if ((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, + len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) + len = strlen((const char *)bytes); + i = ASN1_STRING_set(ne->value, bytes, len); + if (!i) + return (0); + if (type != V_ASN1_UNDEF) { + ne->value->type = type; + } + return (1); +} + +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->object); +} + +ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->value); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509rset.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509rset.c new file mode 100644 index 00000000..a55187b1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509rset.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include + +#include "internal.h" + + +int X509_REQ_set_version(X509_REQ *x, long version) +{ + /* TODO(https://crbug.com/boringssl/467): Reject invalid version + * numbers. */ + if (x == NULL) + return (0); + return (ASN1_INTEGER_set(x->req_info->version, version)); +} + +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_NAME_set(&x->req_info->subject, name)); +} + +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509spki.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509spki.c new file mode 100644 index 00000000..4d959bee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x509spki.c @@ -0,0 +1,137 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +} + +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->spkac->pubkey)); +} + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + size_t spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) + len = strlen(str); + if (!EVP_DecodedLength(&spki_len, len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); + return NULL; + } + if (!(spki_der = OPENSSL_malloc(spki_len))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EVP_DecodeBase64 + (spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); + OPENSSL_free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + OPENSSL_free(spki_der); + return spki; +} + +/* Generate a base64 encoded string from an SPKI */ + +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + size_t b64_len; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + if (!EVP_EncodedLength(&b64_len, der_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return NULL; + } + der_spki = OPENSSL_malloc(der_len); + if (der_spki == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + b64_str = OPENSSL_malloc(b64_len); + if (b64_str == NULL) { + OPENSSL_free(der_spki); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + OPENSSL_free(der_spki); + return b64_str; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_algor.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_algor.c new file mode 100644 index 00000000..6366d0e4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_algor.c @@ -0,0 +1,153 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +#include "../asn1/internal.h" + + +ASN1_SEQUENCE(X509_ALGOR) = { + ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), + ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) +} ASN1_SEQUENCE_END(X509_ALGOR) + +ASN1_ITEM_TEMPLATE(X509_ALGORS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) +ASN1_ITEM_TEMPLATE_END(X509_ALGORS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) +{ + if (!alg) + return 0; + if (ptype != V_ASN1_UNDEF) { + if (alg->parameter == NULL) + alg->parameter = ASN1_TYPE_new(); + if (alg->parameter == NULL) + return 0; + } + if (alg) { + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = aobj; + } + if (ptype == 0) + return 1; + if (ptype == V_ASN1_UNDEF) { + if (alg->parameter) { + ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + } + } else + ASN1_TYPE_set(alg->parameter, ptype, pval); + return 1; +} + +void X509_ALGOR_get0(const ASN1_OBJECT **out_obj, int *out_param_type, + const void **out_param_value, const X509_ALGOR *alg) +{ + if (out_obj != NULL) { + *out_obj = alg->algorithm; + } + if (out_param_type != NULL) { + int type = V_ASN1_UNDEF; + const void *value = NULL; + if (alg->parameter != NULL) { + type = alg->parameter->type; + value = asn1_type_value_as_pointer(alg->parameter); + } + *out_param_type = type; + if (out_param_value != NULL) { + *out_param_value = value; + } + } +} + +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ + +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) +{ + int param_type; + + if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) + param_type = V_ASN1_UNDEF; + else + param_type = V_ASN1_NULL; + + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + +} + +/* + * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. + */ +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) +{ + int rv; + rv = OBJ_cmp(a->algorithm, b->algorithm); + if (rv) + return rv; + if (!a->parameter && !b->parameter) + return 0; + return ASN1_TYPE_cmp(a->parameter, b->parameter); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_all.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_all.c new file mode 100644 index 00000000..81a76278 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_all.c @@ -0,0 +1,386 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int X509_verify(X509 *x509, EVP_PKEY *pkey) +{ + if (X509_ALGOR_cmp(x509->sig_alg, x509->cert_info->signature)) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); + return 0; + } + return ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), x509->sig_alg, + x509->signature, x509->cert_info, pkey); +} + +int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) +{ + return ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + req->sig_alg, req->signature, req->req_info, pkey); +} + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->cert_info->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, pkey, md)); +} + +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) +{ + x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, ctx); +} + +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, pkey, md)); +} + +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) +{ + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), + x->sig_alg, NULL, x->signature, x->req_info, + ctx); +} + +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->crl->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); +} + +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) +{ + x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), + x->crl->sig_alg, x->sig_alg, x->signature, + x->crl, ctx); +} + +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md)); +} + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, + spki->signature, spki->spkac, pkey)); +} + +X509 *d2i_X509_fp(FILE *fp, X509 **x509) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +int i2d_X509_fp(FILE *fp, X509 *x509) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +X509 *d2i_X509_bio(BIO *bp, X509 **x509) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +int i2d_X509_bio(BIO *bp, X509 *x509) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + + +#define IMPLEMENT_D2I_FP(type, name, bio_func) \ + type *name(FILE *fp, type **obj) { \ + BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \ + if (bio == NULL) { \ + return NULL; \ + } \ + type *ret = bio_func(bio, obj); \ + BIO_free(bio); \ + return ret; \ + } + +#define IMPLEMENT_I2D_FP(type, name, bio_func) \ + int name(FILE *fp, type *obj) { \ + BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \ + if (bio == NULL) { \ + return 0; \ + } \ + int ret = bio_func(bio, obj); \ + BIO_free(bio); \ + return ret; \ + } + +IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio) +IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio) + +IMPLEMENT_D2I_FP(RSA, d2i_RSAPublicKey_fp, d2i_RSAPublicKey_bio) +IMPLEMENT_I2D_FP(RSA, i2d_RSAPublicKey_fp, i2d_RSAPublicKey_bio) + +IMPLEMENT_D2I_FP(RSA, d2i_RSA_PUBKEY_fp, d2i_RSA_PUBKEY_bio) +IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio) + +#define IMPLEMENT_D2I_BIO(type, name, d2i_func) \ + type *name(BIO *bio, type **obj) { \ + uint8_t *data; \ + size_t len; \ + if (!BIO_read_asn1(bio, &data, &len, 100 * 1024)) { \ + return NULL; \ + } \ + const uint8_t *ptr = data; \ + type *ret = d2i_func(obj, &ptr, (long)len); \ + OPENSSL_free(data); \ + return ret; \ + } + +#define IMPLEMENT_I2D_BIO(type, name, i2d_func) \ + int name(BIO *bio, type *obj) { \ + uint8_t *data = NULL; \ + int len = i2d_func(obj, &data); \ + if (len < 0) { \ + return 0; \ + } \ + int ret = BIO_write_all(bio, data, len); \ + OPENSSL_free(data); \ + return ret; \ + } + +IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey) +IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey) + +IMPLEMENT_D2I_BIO(RSA, d2i_RSAPublicKey_bio, d2i_RSAPublicKey) +IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey) + +IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY) +IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY) + +#ifndef OPENSSL_NO_DSA +IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio) +IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio) + +IMPLEMENT_D2I_FP(DSA, d2i_DSA_PUBKEY_fp, d2i_DSA_PUBKEY_bio) +IMPLEMENT_I2D_FP(DSA, i2d_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio) + +IMPLEMENT_D2I_BIO(DSA, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey) +IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey) + +IMPLEMENT_D2I_BIO(DSA, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY) +IMPLEMENT_I2D_BIO(DSA, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY) +#endif + +IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio) +IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio) + +IMPLEMENT_D2I_FP(EC_KEY, d2i_EC_PUBKEY_fp, d2i_EC_PUBKEY_bio) +IMPLEMENT_I2D_FP(EC_KEY, i2d_EC_PUBKEY_fp, i2d_EC_PUBKEY_bio) + +IMPLEMENT_D2I_BIO(EC_KEY, d2i_ECPrivateKey_bio, d2i_ECPrivateKey) +IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey) + +IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY) +IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY) + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) + return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); +} + +int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); +} + +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); +} + +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); +} + +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); +} + +IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio) +IMPLEMENT_I2D_FP(X509_SIG, i2d_PKCS8_fp, i2d_PKCS8_bio) + +IMPLEMENT_D2I_BIO(X509_SIG, d2i_PKCS8_bio, d2i_X509_SIG) +IMPLEMENT_I2D_BIO(X509_SIG, i2d_PKCS8_bio, i2d_X509_SIG) + +IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp, + d2i_PKCS8_PRIV_KEY_INFO_bio) +IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp, + i2d_PKCS8_PRIV_KEY_INFO_bio) + +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio) +IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PrivateKey_fp, i2d_PrivateKey_bio) + +IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PUBKEY_fp, d2i_PUBKEY_bio) +IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PUBKEY_fp, i2d_PUBKEY_bio) + +IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio, + d2i_PKCS8_PRIV_KEY_INFO) +IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio, + i2d_PKCS8_PRIV_KEY_INFO) + +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey) +IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PrivateKey_bio, i2d_PrivateKey) + +IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PUBKEY_bio, d2i_PUBKEY) +IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PUBKEY_bio, i2d_PUBKEY) + +IMPLEMENT_D2I_BIO(DH, d2i_DHparams_bio, d2i_DHparams) +IMPLEMENT_I2D_BIO(const DH, i2d_DHparams_bio, i2d_DHparams) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_attrib.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_attrib.c new file mode 100644 index 00000000..7f871b4b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_attrib.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include + +#include "internal.h" + + +ASN1_SEQUENCE(X509_ATTRIBUTE) = { + ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), + ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY), +} ASN1_SEQUENCE_END(X509_ATTRIBUTE) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) + +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int attrtype, void *value) +{ + ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + X509_ATTRIBUTE *ret = X509_ATTRIBUTE_new(); + ASN1_TYPE *val = ASN1_TYPE_new(); + if (ret == NULL || val == NULL) { + goto err; + } + + ret->object = obj; + if (!sk_ASN1_TYPE_push(ret->set, val)) { + goto err; + } + + ASN1_TYPE_set(val, attrtype, value); + return ret; + + err: + X509_ATTRIBUTE_free(ret); + ASN1_TYPE_free(val); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_crl.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_crl.c new file mode 100644 index 00000000..598b7f4b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_crl.c @@ -0,0 +1,568 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +/* + * Method to handle CRL access. In general a CRL could be very large (several + * Mb) and can consume large amounts of resources if stored in memory by + * multiple processes. This method allows general CRL operations to be + * redirected to more efficient callbacks: for example a CRL entry database. + */ + +#define X509_CRL_METHOD_DYNAMIC 1 + +struct x509_crl_method_st { + int flags; + int (*crl_init) (X509_CRL *crl); + int (*crl_free) (X509_CRL *crl); + int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer); + int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); +}; + +static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b); +static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); + +ASN1_SEQUENCE(X509_REVOKED) = { + ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) +} ASN1_SEQUENCE_END(X509_REVOKED) + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer); + +static const X509_CRL_METHOD int_crl_meth = { + 0, + 0, 0, + def_crl_lookup, + def_crl_verify +}; + +static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; + +/* + * The X509_CRL_INFO structure needs a bit of customisation. Since we cache + * the original encoding the signature wont be affected by reordering of the + * revoked field. + */ +static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; + + if (!a || !a->revoked) + return 1; + switch (operation) { + /* + * Just set cmp function here. We don't sort because that would + * affect the output of X509_CRL_print(). + */ + case ASN1_OP_D2I_POST: + /* TODO(https://crbug.com/boringssl/467): Reject invalid version + * numbers. + * + * TODO(davidben): Check that default |versions| are never encoded and + * that |extensions| is only present in v2. */ + + (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); + break; + } + return 1; +} + + +ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { + ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), + ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), + ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) + +/* + * Set CRL entry issuer according to CRL certificate issuer extension. Check + * for unhandled critical CRL entry extensions. + */ + +static int crl_set_issuers(X509_CRL *crl) +{ + + size_t i, k; + int j; + GENERAL_NAMES *gens, *gtmp; + STACK_OF(X509_REVOKED) *revoked; + + revoked = X509_CRL_get_REVOKED(crl); + + gens = NULL; + for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { + X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); + STACK_OF(X509_EXTENSION) *exts; + ASN1_ENUMERATED *reason; + X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, + NID_certificate_issuer, &j, NULL); + if (!gtmp && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (gtmp) { + gens = gtmp; + if (!crl->issuers) { + crl->issuers = sk_GENERAL_NAMES_new_null(); + if (!crl->issuers) + return 0; + } + if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) + return 0; + } + rev->issuer = gens; + + reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); + if (!reason && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (reason) { + rev->reason = ASN1_ENUMERATED_get(reason); + ASN1_ENUMERATED_free(reason); + } else + rev->reason = CRL_REASON_NONE; + + /* Check for critical CRL entry extensions */ + + exts = rev->extensions; + + for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { + ext = sk_X509_EXTENSION_value(exts, k); + if (X509_EXTENSION_get_critical(ext)) { + if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == + NID_certificate_issuer) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + } + + return 1; + +} + +/* + * The X509_CRL structure needs a bit of customisation. Cache some extensions + * and hash of the whole CRL. + */ +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL *crl = (X509_CRL *)*pval; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + size_t idx; + int i; + + switch (operation) { + case ASN1_OP_NEW_POST: + crl->idp = NULL; + crl->akid = NULL; + crl->flags = 0; + crl->idp_flags = 0; + crl->idp_reasons = CRLDP_ALL_REASONS; + crl->meth = default_crl_method; + crl->meth_data = NULL; + crl->issuers = NULL; + crl->crl_number = NULL; + crl->base_crl_number = NULL; + break; + + case ASN1_OP_D2I_POST: + if (!X509_CRL_digest(crl, EVP_sha256(), crl->crl_hash, NULL)) { + return 0; + } + + crl->idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, &i, + NULL); + if (crl->idp != NULL) { + if (!setup_idp(crl, crl->idp)) { + return 0; + } + } else if (i != -1) { + return 0; + } + + crl->akid = X509_CRL_get_ext_d2i(crl, + NID_authority_key_identifier, &i, + NULL); + if (crl->akid == NULL && i != -1) { + return 0; + } + + crl->crl_number = X509_CRL_get_ext_d2i(crl, + NID_crl_number, &i, NULL); + if (crl->crl_number == NULL && i != -1) { + return 0; + } + + crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, &i, + NULL); + if (crl->base_crl_number == NULL && i != -1) { + return 0; + } + /* Delta CRLs must have CRL number */ + if (crl->base_crl_number && !crl->crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER); + return 0; + } + + /* + * See if we have any unhandled critical CRL extensions and indicate + * this in a flag. We only currently handle IDP so anything else + * critical sets the flag. This code accesses the X509_CRL structure + * directly: applications shouldn't do this. + */ + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { + int nid; + ext = sk_X509_EXTENSION_value(exts, idx); + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + if (nid == NID_freshest_crl) + crl->flags |= EXFLAG_FRESHEST; + if (X509_EXTENSION_get_critical(ext)) { + /* We handle IDP and deltas */ + if ((nid == NID_issuing_distribution_point) + || (nid == NID_authority_key_identifier) + || (nid == NID_delta_crl)) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + if (!crl_set_issuers(crl)) + return 0; + + if (crl->meth->crl_init) { + if (crl->meth->crl_init(crl) == 0) + return 0; + } + break; + + case ASN1_OP_FREE_POST: + /* |crl->meth| may be NULL if constructing the object failed before + * |ASN1_OP_NEW_POST| was run. */ + if (crl->meth && crl->meth->crl_free) { + if (!crl->meth->crl_free(crl)) + return 0; + } + if (crl->akid) + AUTHORITY_KEYID_free(crl->akid); + if (crl->idp) + ISSUING_DIST_POINT_free(crl->idp); + ASN1_INTEGER_free(crl->crl_number); + ASN1_INTEGER_free(crl->base_crl_number); + sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + break; + } + return 1; +} + +/* Convert IDP into a more convenient form */ + +static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) +{ + int idp_only = 0; + /* Set various flags according to IDP */ + crl->idp_flags |= IDP_PRESENT; + if (idp->onlyuser > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYUSER; + } + if (idp->onlyCA > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYCA; + } + if (idp->onlyattr > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYATTR; + } + + if (idp_only > 1) + crl->idp_flags |= IDP_INVALID; + + if (idp->indirectCRL > 0) + crl->idp_flags |= IDP_INDIRECT; + + if (idp->onlysomereasons) { + crl->idp_flags |= IDP_REASONS; + if (idp->onlysomereasons->length > 0) + crl->idp_reasons = idp->onlysomereasons->data[0]; + if (idp->onlysomereasons->length > 1) + crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); + crl->idp_reasons &= CRLDP_ALL_REASONS; + } + + return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); +} + +ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = { + ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), + ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) + +static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b) +{ + return ASN1_STRING_cmp((*a)->serialNumber, (*b)->serialNumber); +} + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) +{ + X509_CRL_INFO *inf; + inf = crl->crl; + if (!inf->revoked) + inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); + if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + inf->enc.modified = 1; + return 1; +} + +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey) +{ + if (crl->meth->crl_verify) + return crl->meth->crl_verify(crl, pkey); + return 0; +} + +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, serial, NULL); + return 0; +} + +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, + X509_get_serialNumber(x), + X509_get_issuer_name(x)); + return 0; +} + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) +{ + if (X509_ALGOR_cmp(crl->sig_alg, crl->crl->sig_alg) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); + return 0; + } + + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), + crl->sig_alg, crl->signature, crl->crl, r)); +} + +static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, + X509_REVOKED *rev) +{ + size_t i; + + if (!rev->issuer) { + if (!nm) + return 1; + if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) + return 1; + return 0; + } + + if (!nm) + nm = X509_CRL_get_issuer(crl); + + for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gen->d.directoryName)) + return 1; + } + return 0; + +} + +static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT; + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) +{ + X509_REVOKED rtmp, *rev; + size_t idx; + rtmp.serialNumber = serial; + /* + * Sort revoked into serial number order if not already sorted. Do this + * under a lock to avoid race condition. + */ + + CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock); + const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); + CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock); + + if (!is_sorted) { + CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock); + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + sk_X509_REVOKED_sort(crl->crl->revoked); + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock); + } + + if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) + return 0; + /* Need to look for matching name */ + for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { + rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); + if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) + return 0; + if (crl_revoked_issuer_match(crl, issuer, rev)) { + if (ret) + *ret = rev; + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + return 1; + } + } + return 0; +} + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) +{ + if (meth == NULL) + default_crl_method = &int_crl_meth; + else + default_crl_method = meth; +} + +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)) +{ + X509_CRL_METHOD *m; + m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); + if (!m) + return NULL; + m->crl_init = crl_init; + m->crl_free = crl_free; + m->crl_lookup = crl_lookup; + m->crl_verify = crl_verify; + m->flags = X509_CRL_METHOD_DYNAMIC; + return m; +} + +void X509_CRL_METHOD_free(X509_CRL_METHOD *m) +{ + if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) + return; + OPENSSL_free(m); +} + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) +{ + crl->meth_data = dat; +} + +void *X509_CRL_get_meth_data(X509_CRL *crl) +{ + return crl->meth_data; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_exten.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_exten.c new file mode 100644 index 00000000..97ad76aa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_exten.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include +#include + +#include "internal.h" + + +ASN1_SEQUENCE(X509_EXTENSION) = { + ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), + ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), + ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_EXTENSION) + +ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) +ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_info.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_info.c new file mode 100644 index 00000000..7d292f39 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_info.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include +#include + +X509_INFO *X509_INFO_new(void) +{ + X509_INFO *ret = NULL; + + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; + + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return (ret); +} + +void X509_INFO_free(X509_INFO *x) +{ + if (x == NULL) + return; + + if (x->x509 != NULL) + X509_free(x->x509); + if (x->crl != NULL) + X509_CRL_free(x->crl); + if (x->x_pkey != NULL) + X509_PKEY_free(x->x_pkey); + if (x->enc_data != NULL) + OPENSSL_free(x->enc_data); + OPENSSL_free(x); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_name.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_name.c new file mode 100644 index 00000000..4641c4d5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_name.c @@ -0,0 +1,544 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../asn1/internal.h" +#include "../internal.h" +#include "internal.h" + + +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) + +/* + * Maximum length of X509_NAME: much larger than anything we should + * ever see in practice. + */ + +#define X509_NAME_MAX (1024 * 1024) + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); +static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); + +static int x509_name_encode(X509_NAME *a); +static int x509_name_canon(X509_NAME *a); +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, + unsigned char **in); + +ASN1_SEQUENCE(X509_NAME_ENTRY) = { + ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), + ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) +} ASN1_SEQUENCE_END(X509_NAME_ENTRY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) + +/* + * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so + * declare two template wrappers for this + */ + +ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) +ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) + +ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) +ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) + +/* + * Normally that's where it would end: we'd have two nested STACK structures + * representing the ASN1. Unfortunately X509_NAME uses a completely different + * form and caches encodings so we have to process the internal form and + * convert to the external form. + */ + +static const ASN1_EXTERN_FUNCS x509_name_ff = { + NULL, + x509_name_ex_new, + x509_name_ex_free, + 0, /* Default clear behaviour is OK */ + x509_name_ex_d2i, + x509_name_ex_i2d, + NULL, +}; + +IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) + +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) +{ + X509_NAME *ret = NULL; + ret = OPENSSL_malloc(sizeof(X509_NAME)); + if (!ret) + goto memerr; + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) + goto memerr; + if ((ret->bytes = BUF_MEM_new()) == NULL) + goto memerr; + ret->canon_enc = NULL; + ret->canon_enclen = 0; + ret->modified = 1; + *val = (ASN1_VALUE *)ret; + return 1; + + memerr: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + if (ret) { + if (ret->entries) + sk_X509_NAME_ENTRY_free(ret->entries); + OPENSSL_free(ret); + } + return 0; +} + +static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + X509_NAME *a; + if (!pval || !*pval) + return; + a = (X509_NAME *)*pval; + + BUF_MEM_free(a->bytes); + sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); + if (a->canon_enc) + OPENSSL_free(a->canon_enc); + OPENSSL_free(a); + *pval = NULL; +} + +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_free(ne); +} + +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +} + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx) +{ + const unsigned char *p = *in, *q; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + X509_NAME *nm = NULL; + size_t i, j; + int ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + /* Bound the size of an X509_NAME we are willing to parse. */ + if (len > X509_NAME_MAX) { + len = X509_NAME_MAX; + } + q = p; + + /* Get internal representation of Name */ + ASN1_VALUE *intname_val = NULL; + ret = ASN1_item_ex_d2i(&intname_val, + &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + tag, aclass, opt, ctx); + if (ret <= 0) + return ret; + intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val; + + if (*val) + x509_name_ex_free(val, NULL); + ASN1_VALUE *nm_val = NULL; + if (!x509_name_ex_new(&nm_val, NULL)) + goto err; + nm = (X509_NAME *)nm_val; + /* We've decoded it: now cache encoding */ + if (!BUF_MEM_grow(nm->bytes, p - q)) + goto err; + OPENSSL_memcpy(nm->bytes->data, q, p - q); + + /* Convert internal representation to X509_NAME structure */ + for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname, i); + for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { + entry = sk_X509_NAME_ENTRY_value(entries, j); + entry->set = i; + if (!sk_X509_NAME_ENTRY_push(nm->entries, entry)) + goto err; + (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); + } + } + ret = x509_name_canon(nm); + if (!ret) + goto err; + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_free); + nm->modified = 0; + *val = (ASN1_VALUE *)nm; + *in = p; + return ret; + err: + X509_NAME_free(nm); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + return 0; +} + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + X509_NAME *a = (X509_NAME *)*val; + if (a->modified && + (!x509_name_encode(a) || + !x509_name_canon(a))) { + return -1; + } + int ret = a->bytes->length; + if (out != NULL) { + OPENSSL_memcpy(*out, a->bytes->data, ret); + *out += ret; + } + return ret; +} + +static int x509_name_encode(X509_NAME *a) +{ + int len; + unsigned char *p; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry; + int set = -1; + size_t i; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = + sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) + goto memerr; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto memerr; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto memerr; + } + set = entry->set; + } + if (!sk_X509_NAME_ENTRY_push(entries, entry)) + goto memerr; + } + ASN1_VALUE *intname_val = (ASN1_VALUE *)intname; + len = + ASN1_item_ex_i2d(&intname_val, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + /*tag=*/-1, /*aclass=*/0); + if (len <= 0) { + goto err; + } + if (!BUF_MEM_grow(a->bytes, len)) + goto memerr; + p = (unsigned char *)a->bytes->data; + if (ASN1_item_ex_i2d(&intname_val, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + /*tag=*/-1, /*aclass=*/0) <= 0) { + goto err; + } + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_free); + a->modified = 0; + return 1; + memerr: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); +err: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_free); + return 0; +} + +/* + * This function generates the canonical encoding of the Name structure. In + * it all strings are converted to UTF8, leading, trailing and multiple + * spaces collapsed, converted to lower case and the leading SEQUENCE header + * removed. In future we could also normalize the UTF8 too. By doing this + * comparison of Name structures can be rapidly perfomed by just using + * OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple OPENSSL_memcmp(). + */ + +static int x509_name_canon(X509_NAME *a) +{ + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int set = -1, ret = 0, len; + size_t i; + + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + /* Special case: empty X509_NAME => null encoding */ + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) + goto err; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto err; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto err; + } + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + if (tmpentry == NULL) + goto err; + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) + goto err; + if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) + goto err; + tmpentry = NULL; + } + + /* Finally generate encoding */ + + len = i2d_name_canon(intname, NULL); + if (len < 0) { + goto err; + } + a->canon_enclen = len; + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) + goto err; + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + + err: + + if (tmpentry) + X509_NAME_ENTRY_free(tmpentry); + if (intname) + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + return ret; +} + +/* Bitmap of all the types of string that will be canonicalized. */ + +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ + | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ + | B_ASN1_VISIBLESTRING) + +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) +{ + unsigned char *to, *from; + int len, i; + + /* If type not in bitmask just copy string across */ + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { + if (!ASN1_STRING_copy(out, in)) + return 0; + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) + return 0; + + to = out->data; + from = to; + + len = out->length; + + /* + * Convert string in place to canonical form. Ultimately we may need to + * handle a wider range of characters but for now ignore anything with + * MSB set and rely on the isspace() and tolower() functions. + */ + + /* Ignore leading spaces */ + while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + from++; + len--; + } + + to = from + len; + + /* Ignore trailing spaces */ + while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { + to--; + len--; + } + + to = out->data; + + i = 0; + while (i < len) { + /* If MSB set just copy across */ + if (*from & 0x80) { + *to++ = *from++; + i++; + } + /* Collapse multiple spaces */ + else if (isspace(*from)) { + /* Copy one space across */ + *to++ = ' '; + /* + * Ignore subsequent spaces. Note: don't need to check len here + * because we know the last character is a non-space so we can't + * overflow. + */ + do { + from++; + i++; + } + while (!(*from & 0x80) && isspace(*from)); + } else { + *to++ = OPENSSL_tolower(*from); + from++; + i++; + } + } + + out->length = to - out->data; + + return 1; + +} + +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, + unsigned char **in) +{ + int len, ltmp; + size_t i; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; + + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, ASN1_ITEM_rptr(X509_NAME_ENTRIES), + /*tag=*/-1, /*aclass=*/0); + if (ltmp < 0) + return ltmp; + len += ltmp; + } + return len; +} + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name) +{ + if ((name = X509_NAME_dup(name)) == NULL) + return 0; + X509_NAME_free(*xn); + *xn = name; + return 1; +} + +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +{ + return ne->set; +} + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen) +{ + /* Make sure encoding is valid */ + if (i2d_X509_NAME(nm, NULL) <= 0) + return 0; + if (pder != NULL) + *pder = (unsigned char *)nm->bytes->data; + if (pderlen != NULL) + *pderlen = nm->bytes->length; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c new file mode 100644 index 00000000..cf2cdc1d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pkey.c @@ -0,0 +1,106 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include + +#include "../internal.h" + + +X509_PKEY *X509_PKEY_new(void) +{ + X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); + + ret->enc_algor = X509_ALGOR_new(); + if (ret->enc_algor == NULL) + goto err; + ret->enc_pkey = ASN1_OCTET_STRING_new(); + if (ret->enc_pkey == NULL) + goto err; + return ret; + + err: + if (ret != NULL) + X509_PKEY_free(ret); + return NULL; +} + +void X509_PKEY_free(X509_PKEY *x) +{ + if (x == NULL) + return; + + if (x->enc_algor != NULL) + X509_ALGOR_free(x->enc_algor); + if (x->enc_pkey != NULL) + ASN1_OCTET_STRING_free(x->enc_pkey); + if (x->dec_pkey != NULL) + EVP_PKEY_free(x->dec_pkey); + if ((x->key_data != NULL) && (x->key_free)) + OPENSSL_free(x->key_data); + OPENSSL_free(x); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pubkey.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pubkey.c new file mode 100644 index 00000000..7da5866f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_pubkey.c @@ -0,0 +1,217 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +/* Minor tweak to operation: free up EVP_PKEY */ +static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { + ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), + ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) +{ + X509_PUBKEY *pk = NULL; + uint8_t *spki = NULL; + size_t spki_len; + + if (x == NULL) + return (0); + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_public_key(&cbb, pkey) || + !CBB_finish(&cbb, &spki, &spki_len) || + spki_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + + const uint8_t *p = spki; + pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); + if (pk == NULL || p != spki + spki_len) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + OPENSSL_free(spki); + X509_PUBKEY_free(*x); + *x = pk; + + return 1; + error: + X509_PUBKEY_free(pk); + OPENSSL_free(spki); + return 0; +} + +/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of + * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| + * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is + * not. */ +static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; + +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +{ + EVP_PKEY *ret = NULL; + uint8_t *spki = NULL; + + if (key == NULL) + goto error; + + CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); + if (key->pkey != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + EVP_PKEY_up_ref(key->pkey); + return key->pkey; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + + /* Re-encode the |X509_PUBKEY| to DER and parse it. */ + int spki_len = i2d_X509_PUBKEY(key, &spki); + if (spki_len < 0) { + goto error; + } + CBS cbs; + CBS_init(&cbs, spki, (size_t)spki_len); + ret = EVP_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + /* Check to see if another thread set key->pkey first */ + CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); + if (key->pkey) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + EVP_PKEY_free(ret); + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + } + + OPENSSL_free(spki); + EVP_PKEY_up_ref(ret); + return ret; + + error: + OPENSSL_free(spki); + EVP_PKEY_free(ret); + return NULL; +} + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, int param_type, + void *param_value, uint8_t *key, int key_len) +{ + if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) { + return 0; + } + + ASN1_STRING_set0(pub->public_key, key, key_len); + /* Set the number of unused bits to zero. */ + pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; +} + +int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key, + int *out_key_len, X509_ALGOR **out_alg, + X509_PUBKEY *pub) +{ + if (out_obj != NULL) { + *out_obj = pub->algor->algorithm; + } + if (out_key != NULL) { + *out_key = pub->public_key->data; + *out_key_len = pub->public_key->length; + } + if (out_alg != NULL) { + *out_alg = pub->algor; + } + return 1; +} + +const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key(const X509_PUBKEY *pub) { + return pub->public_key; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_req.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_req.c new file mode 100644 index 00000000..815ce4bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_req.c @@ -0,0 +1,109 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include "internal.h" + + +/* + * X509_REQ_INFO is handled in an unusual way to get round invalid encodings. + * Some broken certificate requests don't encode the attributes field if it + * is empty. This is in violation of PKCS#10 but we need to tolerate it. We + * do this by making the attributes field OPTIONAL then using the callback to + * initialise it to an empty STACK. This means that the field will be + * correctly encoded unless we NULL out the field. + */ + +static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; + + if (operation == ASN1_OP_NEW_POST) { + rinf->attributes = sk_X509_ATTRIBUTE_new_null(); + if (!rinf->attributes) + return 0; + } + + /* TODO(https://crbug.com/boringssl/467): Add an |ASN1_OP_D2I_POST| callback + * and check the version. */ + return 1; +} + +ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { + ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), + ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), + /* This isn't really OPTIONAL but it gets around invalid encodings. */ + ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) + +ASN1_SEQUENCE_ref(X509_REQ, 0) = { + ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), + ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_sig.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_sig.c new file mode 100644 index 00000000..d69a6028 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_sig.c @@ -0,0 +1,94 @@ +/* crypto/asn1/x_sig.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + + +struct X509_sig_st { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; +} /* X509_SIG */; + +ASN1_SEQUENCE(X509_SIG) = { + ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), + ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_SIG) + +IMPLEMENT_ASN1_FUNCTIONS(X509_SIG) + +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **out_alg, + const ASN1_OCTET_STRING **out_digest) { + if (out_alg != NULL) { + *out_alg = sig->algor; + } + if (out_digest != NULL) { + *out_digest = sig->digest; + } +} + +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, + ASN1_OCTET_STRING **out_digest) { + if (out_alg != NULL) { + *out_alg = sig->algor; + } + if (out_digest != NULL) { + *out_digest = sig->digest; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_spki.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_spki.c new file mode 100644 index 00000000..ed6a91d4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_spki.c @@ -0,0 +1,80 @@ +/* crypto/asn1/x_spki.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + + /* + * This module was send to me my Pat Richards who wrote it. + * It is under my Copyright with his permission. + */ + +#include +#include + + +ASN1_SEQUENCE(NETSCAPE_SPKAC) = { + ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), + ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKAC) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +ASN1_SEQUENCE(NETSCAPE_SPKI) = { + ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), + ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKI) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_val.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_val.c new file mode 100644 index 00000000..55d0f0b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_val.c @@ -0,0 +1,71 @@ +/* crypto/asn1/x_val.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include "internal.h" + + +ASN1_SEQUENCE(X509_VAL) = { + ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), + ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME) +} ASN1_SEQUENCE_END(X509_VAL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_VAL) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509.c new file mode 100644 index 00000000..4e502b1c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509.c @@ -0,0 +1,394 @@ +/* crypto/asn1/x_x509.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { + ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), + ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), + ASN1_SIMPLE(X509_CINF, validity, X509_VAL), + ASN1_SIMPLE(X509_CINF, subject, X509_NAME), + ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), + ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) +} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) +/* X509 top level structure needs a bit of customisation */ + +extern void policy_cache_free(X509_POLICY_CACHE *cache); + +static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509 *ret = (X509 *)*pval; + + switch (operation) { + + case ASN1_OP_NEW_POST: + ret->ex_flags = 0; + ret->ex_pathlen = -1; + ret->skid = NULL; + ret->akid = NULL; + ret->aux = NULL; + ret->crldp = NULL; + ret->buf = NULL; + CRYPTO_new_ex_data(&ret->ex_data); + CRYPTO_MUTEX_init(&ret->lock); + break; + + case ASN1_OP_D2I_PRE: + CRYPTO_BUFFER_free(ret->buf); + ret->buf = NULL; + break; + + case ASN1_OP_D2I_POST: { + /* The version must be one of v1(0), v2(1), or v3(2). */ + long version = 0; + if (ret->cert_info->version != NULL) { + version = ASN1_INTEGER_get(ret->cert_info->version); + /* TODO(https://crbug.com/boringssl/364): |version| = 0 should also + * be rejected. This means an explicitly-encoded X.509v1 version. + * v1 is DEFAULT, so DER requires it be omitted. */ + if (version < 0 || version > 2) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; + } + } + + /* Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. */ + if (version == 0 && (ret->cert_info->issuerUID != NULL || + ret->cert_info->subjectUID != NULL)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + return 0; + } + + /* Per RFC 5280, section 4.1.2.9, extensions require v3. */ + if (version != 2 && ret->cert_info->extensions != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + return 0; + } + + break; + } + + case ASN1_OP_FREE_POST: + CRYPTO_MUTEX_cleanup(&ret->lock); + CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data); + X509_CERT_AUX_free(ret->aux); + ASN1_OCTET_STRING_free(ret->skid); + AUTHORITY_KEYID_free(ret->akid); + CRL_DIST_POINTS_free(ret->crldp); + policy_cache_free(ret->policy_cache); + GENERAL_NAMES_free(ret->altname); + NAME_CONSTRAINTS_free(ret->nc); + CRYPTO_BUFFER_free(ret->buf); + break; + + } + + return 1; + +} + +ASN1_SEQUENCE_ref(X509, x509_cb) = { + ASN1_SIMPLE(X509, cert_info, X509_CINF), + ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509, X509) + +IMPLEMENT_ASN1_FUNCTIONS(X509) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509) + +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + if (CRYPTO_BUFFER_len(buf) > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + X509 *x509 = X509_new(); + if (x509 == NULL) { + return NULL; + } + + x509->cert_info->enc.alias_only_on_next_parse = 1; + + const uint8_t *inp = CRYPTO_BUFFER_data(buf); + X509 *x509p = x509; + X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf)); + if (ret == NULL || + inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) { + X509_free(x509p); + return NULL; + } + assert(x509p == x509); + assert(ret == x509); + + CRYPTO_BUFFER_up_ref(buf); + ret->buf = buf; + + return ret; +} + +int X509_up_ref(X509 *x) +{ + CRYPTO_refcount_inc(&x->references); + return 1; +} + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) +{ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int X509_set_ex_data(X509 *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *X509_get_ex_data(X509 *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +/* + * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with + * extra info tagged on the end. Since these functions set how a certificate + * is trusted they should only be used when the certificate comes from a + * reliable source such as local storage. + */ + +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) +{ + const unsigned char *q = *pp; + X509 *ret; + int freeret = 0; + + if (!a || *a == NULL) + freeret = 1; + ret = d2i_X509(a, &q, length); + /* If certificate unreadable then forget it */ + if (!ret) + return NULL; + /* update length */ + length -= q - *pp; + /* Parse auxiliary information if there is any. */ + if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) + goto err; + *pp = q; + return ret; + err: + if (freeret) { + X509_free(ret); + if (a) + *a = NULL; + } + return NULL; +} + +/* + * Serialize trusted certificate to *pp or just return the required buffer + * length if pp == NULL. We ultimately want to avoid modifying *pp in the + * error path, but that depends on similar hygiene in lower-level functions. + * Here we avoid compounding the problem. + */ +static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) +{ + int length, tmplen; + unsigned char *start = pp != NULL ? *pp : NULL; + + assert(pp == NULL || *pp != NULL); + + /* + * This might perturb *pp on error, but fixing that belongs in i2d_X509() + * not here. It should be that if a == NULL length is zero, but we check + * both just in case. + */ + length = i2d_X509(a, pp); + if (length <= 0 || a == NULL) { + return length; + } + + if (a->aux != NULL) { + tmplen = i2d_X509_CERT_AUX(a->aux, pp); + if (tmplen < 0) { + if (start != NULL) + *pp = start; + return tmplen; + } + length += tmplen; + } + + return length; +} + +/* + * Serialize trusted certificate to *pp, or just return the required buffer + * length if pp == NULL. + * + * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since + * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do + * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the + * allocated buffer. + */ +int i2d_X509_AUX(X509 *a, unsigned char **pp) +{ + int length; + unsigned char *tmp; + + /* Buffer provided by caller */ + if (pp == NULL || *pp != NULL) + return i2d_x509_aux_internal(a, pp); + + /* Obtain the combined length */ + if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) + return length; + + /* Allocate requisite combined storage */ + *pp = tmp = OPENSSL_malloc(length); + if (tmp == NULL) + return -1; /* Push error onto error stack? */ + + /* Encode, but keep *pp at the originally malloced pointer */ + length = i2d_x509_aux_internal(a, &tmp); + if (length <= 0) { + OPENSSL_free(*pp); + *pp = NULL; + } + return length; +} + +int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) +{ + x509->cert_info->enc.modified = 1; + return i2d_X509_CINF(x509->cert_info, outp); +} + +int i2d_X509_tbs(X509 *x509, unsigned char **outp) +{ + return i2d_X509_CINF(x509->cert_info, outp); +} + +int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo) +{ + /* TODO(davidben): Const-correct generated ASN.1 dup functions. + * Alternatively, when the types are hidden and we can embed required fields + * directly in structs, import |X509_ALGOR_copy| from upstream. */ + X509_ALGOR *copy1 = X509_ALGOR_dup((X509_ALGOR *)algo); + X509_ALGOR *copy2 = X509_ALGOR_dup((X509_ALGOR *)algo); + if (copy1 == NULL || copy2 == NULL) { + X509_ALGOR_free(copy1); + X509_ALGOR_free(copy2); + return 0; + } + + X509_ALGOR_free(x509->sig_alg); + x509->sig_alg = copy1; + X509_ALGOR_free(x509->cert_info->signature); + x509->cert_info->signature = copy2; + return 1; +} + +int X509_set1_signature_value(X509 *x509, const uint8_t *sig, size_t sig_len) +{ + if (!ASN1_STRING_set(x509->signature, sig, sig_len)) { + return 0; + } + x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; +} + +void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, + const X509 *x) +{ + if (psig) + *psig = x->signature; + if (palg) + *palg = x->sig_alg; +} + +int X509_get_signature_nid(const X509 *x) +{ + return OBJ_obj2nid(x->sig_alg->algorithm); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c new file mode 100644 index 00000000..f60a0a82 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509/x_x509a.c @@ -0,0 +1,206 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +#include "internal.h" + + +/* + * X509_CERT_AUX routines. These are used to encode additional user + * modifiable data about a certificate. This data is appended to the X509 + * encoding when the *_X509_AUX routines are used. This means that the + * "traditional" X509 routines will simply ignore the extra data. + */ + +static X509_CERT_AUX *aux_get(X509 *x); + +ASN1_SEQUENCE(X509_CERT_AUX) = { + ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), + ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), + ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), +} ASN1_SEQUENCE_END(X509_CERT_AUX) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) + +static X509_CERT_AUX *aux_get(X509 *x) +{ + if (!x) + return NULL; + if (!x->aux && !(x->aux = X509_CERT_AUX_new())) + return NULL; + return x->aux; +} + +int X509_alias_set1(X509 *x, const unsigned char *name, int len) +{ + X509_CERT_AUX *aux; + /* TODO(davidben): Empty aliases are not meaningful in PKCS#12, and the + * getters cannot quite represent them. Also erase the object if |len| is + * zero. */ + if (!name) { + if (!x || !x->aux || !x->aux->alias) + return 1; + ASN1_UTF8STRING_free(x->aux->alias); + x->aux->alias = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) + return 0; + return ASN1_STRING_set(aux->alias, name, len); +} + +int X509_keyid_set1(X509 *x, const unsigned char *id, int len) +{ + X509_CERT_AUX *aux; + /* TODO(davidben): Empty key IDs are not meaningful in PKCS#12, and the + * getters cannot quite represent them. Also erase the object if |len| is + * zero. */ + if (!id) { + if (!x || !x->aux || !x->aux->keyid) + return 1; + ASN1_OCTET_STRING_free(x->aux->keyid); + x->aux->keyid = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) + return 0; + return ASN1_STRING_set(aux->keyid, id, len); +} + +unsigned char *X509_alias_get0(X509 *x, int *out_len) +{ + const ASN1_UTF8STRING *alias = x->aux != NULL ? x->aux->alias : NULL; + if (out_len != NULL) { + *out_len = alias != NULL ? alias->length : 0; + } + return alias != NULL ? alias->data : NULL; +} + +unsigned char *X509_keyid_get0(X509 *x, int *out_len) +{ + const ASN1_OCTET_STRING *keyid = x->aux != NULL ? x->aux->keyid : NULL; + if (out_len != NULL) { + *out_len = keyid != NULL ? keyid->length : 0; + } + return keyid != NULL ? keyid->data : NULL; +} + +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->trust == NULL) { + aux->trust = sk_ASN1_OBJECT_new_null(); + if (aux->trust == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->trust, objtmp)) + goto err; + return 1; + + err: + ASN1_OBJECT_free(objtmp); + return 0; +} + +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->reject == NULL) { + aux->reject = sk_ASN1_OBJECT_new_null(); + if (aux->reject == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->reject, objtmp)) + goto err; + return 1; + + err: + ASN1_OBJECT_free(objtmp); + return 0; +} + +void X509_trust_clear(X509 *x) +{ + if (x->aux && x->aux->trust) { + sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); + x->aux->trust = NULL; + } +} + +void X509_reject_clear(X509 *x) +{ + if (x->aux && x->aux->reject) { + sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); + x->aux->reject = NULL; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h new file mode 100644 index 00000000..79301263 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h @@ -0,0 +1,138 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +/* This file contains a table of "standard" extensions */ + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern const X509V3_EXT_METHOD v3_info, v3_sinfo; +extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, + v3_akey_id; +extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, + v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, + v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, + v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern const X509V3_EXT_METHOD v3_addr, v3_asid; + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +/* TODO(fork): OCSP support */ +#define OPENSSL_NO_OCSP + +static const X509V3_EXT_METHOD *const standard_exts[] = { + &v3_nscert, + &v3_ns_ia5_list[0], + &v3_ns_ia5_list[1], + &v3_ns_ia5_list[2], + &v3_ns_ia5_list[3], + &v3_ns_ia5_list[4], + &v3_ns_ia5_list[5], + &v3_ns_ia5_list[6], + &v3_skey_id, + &v3_key_usage, + &v3_alt[0], + &v3_alt[1], + &v3_bcons, + &v3_crl_num, + &v3_cpols, + &v3_akey_id, + &v3_crld, + &v3_ext_ku, + &v3_delta_crl, + &v3_crl_reason, + &v3_crl_invdate, + &v3_info, +#ifndef OPENSSL_NO_OCSP + &v3_ocsp_nonce, + &v3_ocsp_crlid, + &v3_ocsp_accresp, + &v3_ocsp_acutoff, + &v3_ocsp_serviceloc, +#endif + &v3_ocsp_nocheck, + &v3_sinfo, + &v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &v3_crl_hold, +#endif + &v3_pci, + &v3_name_constraints, + &v3_policy_mappings, + &v3_inhibit_anyp, + &v3_idp, + &v3_alt[2], + &v3_freshest_crl, +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) + +#if defined(__cplusplus) +} /* extern C */ +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/internal.h new file mode 100644 index 00000000..3c4a5d6a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/internal.h @@ -0,0 +1,289 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_HEADER_X509V3_INTERNAL_H +#define OPENSSL_HEADER_X509V3_INTERNAL_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// x509v3_bytes_to_hex encodes |len| bytes from |in| to hex and returns a +// newly-allocated NUL-terminated string containing the result, or NULL on +// allocation error. +// +// This function was historically named |hex_to_string| in OpenSSL. Despite the +// name, |hex_to_string| converted to hex. +OPENSSL_EXPORT char *x509v3_bytes_to_hex(const uint8_t *in, size_t len); + +// x509v3_hex_string_to_bytes decodes |str| in hex and returns a newly-allocated +// array containing the result, or NULL on error. On success, it sets |*len| to +// the length of the result. Colon separators between bytes in the input are +// allowed and ignored. +// +// This function was historically named |string_to_hex| in OpenSSL. Despite the +// name, |string_to_hex| converted from hex. +unsigned char *x509v3_hex_to_bytes(const char *str, long *len); + +// x509v3_name_cmp returns zero if |name| is equal to |cmp| or begins with |cmp| +// followed by '.'. Otherwise, it returns a non-zero number. +int x509v3_name_cmp(const char *name, const char *cmp); + +// x509v3_looks_like_dns_name returns one if |in| looks like a DNS name and zero +// otherwise. +OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in, + size_t len); + +// x509v3_cache_extensions fills in a number of fields relating to X.509 +// extensions in |x|. It returns one on success and zero if some extensions were +// invalid. +int x509v3_cache_extensions(X509 *x); + +// x509v3_a2i_ipadd decodes |ipasc| as an IPv4 or IPv6 address. IPv6 addresses +// use colon-separated syntax while IPv4 addresses use dotted decimal syntax. If +// it decodes an IPv4 address, it writes the result to the first four bytes of +// |ipout| and returns four. If it decodes an IPv6 address, it writes the result +// to all 16 bytes of |ipout| and returns 16. Otherwise, it returns zero. +int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc); + +// A |BIT_STRING_BITNAME| is used to contain a list of bit names. +typedef struct { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +// x509V3_add_value_asn1_string appends a |CONF_VALUE| with the specified name +// and value to |*extlist|. if |*extlist| is NULL, it sets |*extlist| to a +// newly-allocated |STACK_OF(CONF_VALUE)| first. It returns one on success and +// zero on error. +int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, + STACK_OF(CONF_VALUE) **extlist); + +typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; + +DEFINE_STACK_OF(X509_POLICY_DATA) + +/* Internal structures */ + +/* + * This structure and the field names correspond to the Policy 'node' of + * RFC 3280. NB this structure contains no pointers to parent or child data: + * X509_POLICY_NODE contains that. This means that the main policy data can + * be kept static and cached with the certificate. + */ + +struct X509_POLICY_DATA_st { + unsigned int flags; + /* Policy OID and qualifiers for this data */ + ASN1_OBJECT *valid_policy; + STACK_OF(POLICYQUALINFO) *qualifier_set; + STACK_OF(ASN1_OBJECT) *expected_policy_set; +}; + +/* X509_POLICY_DATA flags values */ + +/* + * This flag indicates the structure has been mapped using a policy mapping + * extension. If policy mapping is not active its references get deleted. + */ + +#define POLICY_DATA_FLAG_MAPPED 0x1 + +/* + * This flag indicates the data doesn't correspond to a policy in Certificate + * Policies: it has been mapped to any policy. + */ + +#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 + +/* AND with flags to see if any mapping has occurred */ + +#define POLICY_DATA_FLAG_MAP_MASK 0x3 + +/* qualifiers are shared and shouldn't be freed */ + +#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 + +/* Parent node is an extra node and should be freed */ + +#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 + +/* Corresponding CertificatePolicies is critical */ + +#define POLICY_DATA_FLAG_CRITICAL 0x10 + +/* This structure is cached with a certificate */ + +struct X509_POLICY_CACHE_st { + /* anyPolicy data or NULL if no anyPolicy */ + X509_POLICY_DATA *anyPolicy; + /* other policy data */ + STACK_OF(X509_POLICY_DATA) *data; + /* If InhibitAnyPolicy present this is its value or -1 if absent. */ + long any_skip; + /* + * If policyConstraints and requireExplicitPolicy present this is its + * value or -1 if absent. + */ + long explicit_skip; + /* + * If policyConstraints and policyMapping present this is its value or -1 + * if absent. + */ + long map_skip; +}; + +/* + * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL + */ + +/* This structure represents the relationship between nodes */ + +struct X509_POLICY_NODE_st { + /* node data this refers to */ + const X509_POLICY_DATA *data; + /* Parent node */ + X509_POLICY_NODE *parent; + /* Number of child nodes */ + int nchild; +}; + +struct X509_POLICY_LEVEL_st { + /* Cert for this level */ + X509 *cert; + /* nodes at this level */ + STACK_OF(X509_POLICY_NODE) *nodes; + /* anyPolicy node */ + X509_POLICY_NODE *anyPolicy; + /* Extra data */ + /* + * STACK_OF(X509_POLICY_DATA) *extra_data; + */ + unsigned int flags; +}; + +struct X509_POLICY_TREE_st { + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; + /* + * Extra policy data when additional nodes (not from the certificate) are + * required. + */ + STACK_OF(X509_POLICY_DATA) *extra_data; + /* This is the authority constained policy set */ + STACK_OF(X509_POLICY_NODE) *auth_policies; + STACK_OF(X509_POLICY_NODE) *user_policies; + unsigned int flags; +}; + +/* Set if anyPolicy present in user policies */ +#define POLICY_FLAG_ANY_POLICY 0x2 + +/* Useful macros */ + +#define node_data_critical(data) ((data)->flags & POLICY_DATA_FLAG_CRITICAL) +#define node_critical(node) node_data_critical((node)->data) + +/* Internal functions */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, + int crit); +void policy_data_free(X509_POLICY_DATA *data); + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id); +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); + +void policy_cache_init(void); + +void policy_cache_free(X509_POLICY_CACHE *cache); + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree); +void policy_node_free(X509_POLICY_NODE *node); +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); + +const X509_POLICY_CACHE *policy_cache_set(X509 *x); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_X509V3_INTERNAL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c new file mode 100644 index 00000000..257a8c4c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c @@ -0,0 +1,287 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509/internal.h" +#include "internal.h" + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **b); +static int policy_cache_set_int(long *out, ASN1_INTEGER *value); + +/* + * Set cache entry according to CertificatePolicies extension. Note: this + * destroys the passed CERTIFICATEPOLICIES structure. + */ + +static int policy_cache_create(X509 *x, + CERTIFICATEPOLICIES *policies, int crit) +{ + size_t i; + int ret = 0; + X509_POLICY_CACHE *cache = x->policy_cache; + X509_POLICY_DATA *data = NULL; + POLICYINFO *policy; + if (sk_POLICYINFO_num(policies) == 0) + goto bad_policy; + cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); + if (!cache->data) + goto bad_policy; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + data = policy_data_new(policy, NULL, crit); + if (!data) + goto bad_policy; + /* + * Duplicate policy OIDs are illegal: reject if matches found. + */ + sk_X509_POLICY_DATA_sort(cache->data); + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (cache->anyPolicy) { + ret = -1; + goto bad_policy; + } + cache->anyPolicy = data; + } else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data)) { + ret = -1; + goto bad_policy; + } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) + goto bad_policy; + data = NULL; + } + ret = 1; + bad_policy: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + if (data) + policy_data_free(data); + sk_POLICYINFO_pop_free(policies, POLICYINFO_free); + if (ret <= 0) { + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + cache->data = NULL; + } + return ret; +} + +static int policy_cache_new(X509 *x) +{ + X509_POLICY_CACHE *cache; + ASN1_INTEGER *ext_any = NULL; + POLICY_CONSTRAINTS *ext_pcons = NULL; + CERTIFICATEPOLICIES *ext_cpols = NULL; + POLICY_MAPPINGS *ext_pmaps = NULL; + int i; + cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); + if (!cache) + return 0; + cache->anyPolicy = NULL; + cache->data = NULL; + cache->any_skip = -1; + cache->explicit_skip = -1; + cache->map_skip = -1; + + x->policy_cache = cache; + + /* + * Handle requireExplicitPolicy *first*. Need to process this even if we + * don't have any policies. + */ + ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); + + if (!ext_pcons) { + if (i != -1) + goto bad_cache; + } else { + if (!ext_pcons->requireExplicitPolicy + && !ext_pcons->inhibitPolicyMapping) + goto bad_cache; + if (!policy_cache_set_int(&cache->explicit_skip, + ext_pcons->requireExplicitPolicy)) + goto bad_cache; + if (!policy_cache_set_int(&cache->map_skip, + ext_pcons->inhibitPolicyMapping)) + goto bad_cache; + } + + /* Process CertificatePolicies */ + + ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); + /* + * If no CertificatePolicies extension or problem decoding then there is + * no point continuing because the valid policies will be NULL. + */ + if (!ext_cpols) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + return 1; + } + + i = policy_cache_create(x, ext_cpols, i); + + /* NB: ext_cpols freed by policy_cache_set_policies */ + + if (i <= 0) + return i; + + ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); + + if (!ext_pmaps) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + } else { + i = policy_cache_set_mapping(x, ext_pmaps); + if (i <= 0) + goto bad_cache; + } + + ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); + + if (!ext_any) { + if (i != -1) + goto bad_cache; + } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) + goto bad_cache; + + if (0) { + bad_cache: + x->ex_flags |= EXFLAG_INVALID_POLICY; + } + + if (ext_pcons) + POLICY_CONSTRAINTS_free(ext_pcons); + + if (ext_any) + ASN1_INTEGER_free(ext_any); + + return 1; + +} + +void policy_cache_free(X509_POLICY_CACHE *cache) +{ + if (!cache) + return; + if (cache->anyPolicy) + policy_data_free(cache->anyPolicy); + if (cache->data) + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + OPENSSL_free(cache); +} + +/* + * g_x509_policy_cache_lock is used to protect against concurrent calls to + * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in + * the |X509| structure, but |CRYPTO_once_t| isn't public. + */ +static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock = + CRYPTO_STATIC_MUTEX_INIT; + +const X509_POLICY_CACHE *policy_cache_set(X509 *x) +{ + X509_POLICY_CACHE *cache; + + CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_read(&g_x509_policy_cache_lock); + + if (cache != NULL) + return cache; + + CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock); + if (x->policy_cache == NULL) + policy_cache_new(x); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_write(&g_x509_policy_cache_lock); + + return cache; +} + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) +{ + size_t idx; + X509_POLICY_DATA tmp; + + tmp.valid_policy = (ASN1_OBJECT *)id; + sk_X509_POLICY_DATA_sort(cache->data); + if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp)) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **b) +{ + return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); +} + +static int policy_cache_set_int(long *out, ASN1_INTEGER *value) +{ + if (value == NULL) + return 1; + if (value->type == V_ASN1_NEG_INTEGER) + return 0; + *out = ASN1_INTEGER_get(value); + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c new file mode 100644 index 00000000..7d4e7418 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c @@ -0,0 +1,132 @@ +/* pcy_data.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include "internal.h" + +/* Policy Node routines */ + +void policy_data_free(X509_POLICY_DATA *data) +{ + ASN1_OBJECT_free(data->valid_policy); + /* Don't free qualifiers if shared */ + if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) + sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); + sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); + OPENSSL_free(data); +} + +/* + * Create a data based on an existing policy. If 'id' is NULL use the oid in + * the policy, otherwise use 'id'. This behaviour covers the two types of + * data in RFC 3280: data with from a CertificatePolcies extension and + * additional data with just the qualifiers of anyPolicy and ID from another + * source. + */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, + const ASN1_OBJECT *cid, int crit) +{ + X509_POLICY_DATA *ret; + ASN1_OBJECT *id; + if (!policy && !cid) + return NULL; + if (cid) { + id = OBJ_dup(cid); + if (!id) + return NULL; + } else + id = NULL; + ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); + if (!ret) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(id); + return NULL; + } + ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); + if (!ret->expected_policy_set) { + OPENSSL_free(ret); + ASN1_OBJECT_free(id); + return NULL; + } + + if (crit) + ret->flags = POLICY_DATA_FLAG_CRITICAL; + else + ret->flags = 0; + + if (id) + ret->valid_policy = id; + else { + ret->valid_policy = policy->policyid; + policy->policyid = NULL; + } + + if (policy) { + ret->qualifier_set = policy->qualifiers; + policy->qualifiers = NULL; + } else + ret->qualifier_set = NULL; + + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_lib.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_lib.c new file mode 100644 index 00000000..9c5e7bd5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_lib.c @@ -0,0 +1,155 @@ +/* pcy_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include "internal.h" + +/* accessor functions */ + +/* X509_POLICY_TREE stuff */ + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) +{ + if (!tree) + return 0; + return tree->nlevel; +} + +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i) +{ + if (!tree || (i < 0) || (i >= tree->nlevel)) + return NULL; + return tree->levels + i; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + return tree->auth_policies; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + if (tree->flags & POLICY_FLAG_ANY_POLICY) + return tree->auth_policies; + else + return tree->user_policies; +} + +/* X509_POLICY_LEVEL stuff */ + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level) +{ + int n; + if (!level) + return 0; + if (level->anyPolicy) + n = 1; + else + n = 0; + if (level->nodes) + n += sk_X509_POLICY_NODE_num(level->nodes); + return n; +} + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) +{ + if (!level) + return NULL; + if (level->anyPolicy) { + if (i == 0) + return level->anyPolicy; + i--; + } + return sk_X509_POLICY_NODE_value(level->nodes, i); +} + +/* X509_POLICY_NODE stuff */ + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->data->valid_policy; +} + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->data->qualifier_set; +} + +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->parent; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c new file mode 100644 index 00000000..45f2044a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c @@ -0,0 +1,131 @@ +/* pcy_map.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "../x509/internal.h" +#include "internal.h" + +/* + * Set policy mapping entries in cache. Note: this modifies the passed + * POLICY_MAPPINGS structure + */ + +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) +{ + POLICY_MAPPING *map; + X509_POLICY_DATA *data; + X509_POLICY_CACHE *cache = x->policy_cache; + size_t i; + int ret = 0; + if (sk_POLICY_MAPPING_num(maps) == 0) { + ret = -1; + goto bad_mapping; + } + for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { + map = sk_POLICY_MAPPING_value(maps, i); + /* Reject if map to or from anyPolicy */ + if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) + || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { + ret = -1; + goto bad_mapping; + } + + /* Attempt to find matching policy data */ + data = policy_cache_find_data(cache, map->issuerDomainPolicy); + /* If we don't have anyPolicy can't map */ + if (!data && !cache->anyPolicy) + continue; + + /* Create a NODE from anyPolicy */ + if (!data) { + data = policy_data_new(NULL, map->issuerDomainPolicy, + cache->anyPolicy->flags + & POLICY_DATA_FLAG_CRITICAL); + if (!data) + goto bad_mapping; + data->qualifier_set = cache->anyPolicy->qualifier_set; + /* + * map->issuerDomainPolicy = NULL; + */ + data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!sk_X509_POLICY_DATA_push(cache->data, data)) { + policy_data_free(data); + goto bad_mapping; + } + } else + data->flags |= POLICY_DATA_FLAG_MAPPED; + if (!sk_ASN1_OBJECT_push(data->expected_policy_set, + map->subjectDomainPolicy)) + goto bad_mapping; + map->subjectDomainPolicy = NULL; + + } + + ret = 1; + bad_mapping: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); + return ret; + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c new file mode 100644 index 00000000..6ce20e91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c @@ -0,0 +1,189 @@ +/* pcy_node.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include +#include +#include +#include + +#include "internal.h" + +static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **b) +{ + return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); +} + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) +{ + return sk_X509_POLICY_NODE_new(node_cmp); +} + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, + const ASN1_OBJECT *id) +{ + X509_POLICY_DATA n; + X509_POLICY_NODE l; + size_t idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + sk_X509_POLICY_NODE_sort(nodes); + if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l)) + return NULL; + + return sk_X509_POLICY_NODE_value(nodes, idx); + +} + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id) +{ + X509_POLICY_NODE *node; + size_t i; + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (node->parent == parent) { + if (!OBJ_cmp(node->data->valid_policy, id)) + return node; + } + } + return NULL; +} + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree) +{ + X509_POLICY_NODE *node; + node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); + if (!node) + return NULL; + node->data = data; + node->parent = parent; + node->nchild = 0; + if (level) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; + level->anyPolicy = node; + } else { + + if (!level->nodes) + level->nodes = policy_node_cmp_new(); + if (!level->nodes) + goto node_error; + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) + goto node_error; + } + } + + if (tree) { + if (!tree->extra_data) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (!tree->extra_data) + goto node_error; + if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) + goto node_error; + } + + if (parent) + parent->nchild++; + + return node; + + node_error: + policy_node_free(node); + return 0; + +} + +void policy_node_free(X509_POLICY_NODE *node) +{ + OPENSSL_free(node); +} + +/* + * See if a policy node matches a policy OID. If mapping enabled look through + * expected policy set otherwise just valid policy. + */ + +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) +{ + size_t i; + ASN1_OBJECT *policy_oid; + const X509_POLICY_DATA *x = node->data; + + if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) + || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { + if (!OBJ_cmp(x->valid_policy, oid)) + return 1; + return 0; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { + policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); + if (!OBJ_cmp(policy_oid, oid)) + return 1; + } + return 0; + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c new file mode 100644 index 00000000..baad9c20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c @@ -0,0 +1,843 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509/internal.h" +#include "internal.h" + +/* + * Enable this to print out the complete policy tree at various point during + * evaluation. + */ + +/* + * #define OPENSSL_POLICY_DEBUG + */ + +#ifdef OPENSSL_POLICY_DEBUG + +static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, + X509_POLICY_NODE *node, int indent) +{ + if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) + BIO_puts(err, " Not Mapped\n"); + else { + int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; + ASN1_OBJECT *oid; + BIO_puts(err, " Expected: "); + for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { + oid = sk_ASN1_OBJECT_value(pset, i); + if (i) + BIO_puts(err, ", "); + i2a_ASN1_OBJECT(err, oid); + } + BIO_puts(err, "\n"); + } +} + +static void tree_print(char *str, X509_POLICY_TREE *tree, + X509_POLICY_LEVEL *curr) +{ + X509_POLICY_LEVEL *plev; + X509_POLICY_NODE *node; + int i; + BIO *err; + err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (!curr) + curr = tree->levels + tree->nlevel; + else + curr++; + BIO_printf(err, "Level print after %s\n", str); + BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + for (plev = tree->levels; plev != curr; plev++) { + BIO_printf(err, "Level %ld, flags = %x\n", + plev - tree->levels, plev->flags); + for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { + node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE_print(err, node, 2); + expected_print(err, plev, node, 2); + BIO_printf(err, " Flags: %x\n", node->data->flags); + } + if (plev->anyPolicy) + X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + } + + BIO_free(err); + +} +#else + +# define tree_print(a,b,c) /* */ + +#endif + +/*- + * Initialize policy tree. Return values: + * 0 Some internal error occurred. + * -1 Inconsistent or invalid extensions in certificates. + * 1 Tree initialized OK. + * 2 Policy tree is empty. + * 5 Tree OK and requireExplicitPolicy true. + * 6 Tree empty and requireExplicitPolicy true. + */ + +static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + unsigned int flags) +{ + X509_POLICY_TREE *tree; + X509_POLICY_LEVEL *level; + const X509_POLICY_CACHE *cache; + X509_POLICY_DATA *data = NULL; + X509 *x; + int ret = 1; + int i, n; + int explicit_policy; + int any_skip; + int map_skip; + *ptree = NULL; + n = sk_X509_num(certs); + +#if 0 + /* Disable policy mapping for now... */ + flags |= X509_V_FLAG_INHIBIT_MAP; +#endif + + if (flags & X509_V_FLAG_EXPLICIT_POLICY) + explicit_policy = 0; + else + explicit_policy = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_ANY) + any_skip = 0; + else + any_skip = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_MAP) + map_skip = 0; + else + map_skip = n + 1; + + /* Can't do anything with just a trust anchor */ + if (n == 1) + return 1; + /* + * First setup policy cache in all certificates apart from the trust + * anchor. Note any bad cache results on the way. Also can calculate + * explicit_policy value at this point. + */ + for (i = n - 2; i >= 0; i--) { + x = sk_X509_value(certs, i); + X509_check_purpose(x, -1, -1); + cache = policy_cache_set(x); + /* If cache NULL something bad happened: return immediately */ + if (cache == NULL) + return 0; + /* + * If inconsistent extensions keep a note of it but continue + */ + if (x->ex_flags & EXFLAG_INVALID_POLICY) + ret = -1; + /* + * Otherwise if we have no data (hence no CertificatePolicies) and + * haven't already set an inconsistent code note it. + */ + else if ((ret == 1) && !cache->data) + ret = 2; + if (explicit_policy > 0) { + if (!(x->ex_flags & EXFLAG_SI)) + explicit_policy--; + if ((cache->explicit_skip != -1) + && (cache->explicit_skip < explicit_policy)) + explicit_policy = cache->explicit_skip; + } + } + + if (ret != 1) { + if (ret == 2 && !explicit_policy) + return 6; + return ret; + } + + /* If we get this far initialize the tree */ + + tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); + + if (!tree) + return 0; + + tree->flags = 0; + tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); + tree->nlevel = 0; + tree->extra_data = NULL; + tree->auth_policies = NULL; + tree->user_policies = NULL; + + if (!tree->levels) { + OPENSSL_free(tree); + return 0; + } + + OPENSSL_memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); + + tree->nlevel = n; + + level = tree->levels; + + /* Root data: initialize to anyPolicy */ + + data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); + + if (!data || !level_add_node(level, data, NULL, tree)) + goto bad_tree; + + for (i = n - 2; i >= 0; i--) { + level++; + x = sk_X509_value(certs, i); + cache = policy_cache_set(x); + X509_up_ref(x); + level->cert = x; + + if (!cache->anyPolicy) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + + /* Determine inhibit any and inhibit map flags */ + if (any_skip == 0) { + /* + * Any matching allowed if certificate is self issued and not the + * last in the chain. + */ + if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + } else { + if (!(x->ex_flags & EXFLAG_SI)) + any_skip--; + if ((cache->any_skip >= 0) + && (cache->any_skip < any_skip)) + any_skip = cache->any_skip; + } + + if (map_skip == 0) + level->flags |= X509_V_FLAG_INHIBIT_MAP; + else { + if (!(x->ex_flags & EXFLAG_SI)) + map_skip--; + if ((cache->map_skip >= 0) + && (cache->map_skip < map_skip)) + map_skip = cache->map_skip; + } + + } + + *ptree = tree; + + if (explicit_policy) + return 1; + else + return 5; + + bad_tree: + + X509_policy_tree_free(tree); + + return 0; + +} + +static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int matched = 0; + size_t i; + /* Iterate through all in nodes linking matches */ + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (policy_node_match(last, node, data->valid_policy)) { + if (!level_add_node(curr, data, node, NULL)) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { + if (!level_add_node(curr, data, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC 3280 6.1.3(d)(1): link any data from + * CertificatePolicies onto matching parent or anyPolicy if no match. + */ + +static int tree_link_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache) +{ + size_t i; + X509_POLICY_DATA *data; + + for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { + data = sk_X509_POLICY_DATA_value(cache->data, i); + /* + * If a node is mapped any it doesn't have a corresponding + * CertificatePolicies entry. However such an identical node would + * be created if anyPolicy matching is enabled because there would be + * no match with the parent valid_policy_set. So we create link + * because then it will have the mapping flags right and we can prune + * it later. + */ +#if 0 + if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) + && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) + continue; +#endif + /* Look for matching nodes in previous level */ + if (!tree_link_matching_nodes(curr, data)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC 3280 6.1.3(d)(2): Create new data for any unmatched + * policies in the parent and link to anyPolicy. + */ + +static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + X509_POLICY_DATA *data; + if (id == NULL) + id = node->data->valid_policy; + /* + * Create a new node with qualifiers from anyPolicy and id from unmatched + * node. + */ + data = policy_data_new(NULL, id, node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } + + return 1; +} + +static int tree_link_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + const X509_POLICY_LEVEL *last = curr - 1; + size_t i; + + if ((last->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { + /* If no policy mapping: matched if one child present */ + if (node->nchild) + return 1; + if (!tree_add_unmatched(curr, cache, NULL, node, tree)) + return 0; + /* Add it */ + } else { + /* If mapping: matched if one child per expected policy set */ + STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; + if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset)) + return 1; + /* Locate unmatched nodes */ + for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); + if (level_find_node(curr, node, oid)) + continue; + if (!tree_add_unmatched(curr, cache, oid, node, tree)) + return 0; + } + + } + + return 1; + +} + +static int tree_link_any(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_TREE *tree) +{ + size_t i; + /* + * X509_POLICY_DATA *data; + */ + X509_POLICY_NODE *node; + X509_POLICY_LEVEL *last = curr - 1; + + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (!tree_link_unmatched(curr, cache, node, tree)) + return 0; + +#if 0 + + /* + * Skip any node with any children: we only want unmathced nodes. + * Note: need something better for policy mapping because each node + * may have multiple children + */ + if (node->nchild) + continue; + + /* + * Create a new node with qualifiers from anyPolicy and id from + * unmatched node. + */ + data = policy_data_new(NULL, node->data->valid_policy, + node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } +#endif + + } + /* Finally add link to anyPolicy */ + if (last->anyPolicy) { + if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * Prune the tree: delete any child mapped child data on the current level + * then proceed up the tree deleting any data with no children. If we ever + * have no data on a level we can halt because the tree will be empty. + */ + +static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) +{ + STACK_OF(X509_POLICY_NODE) *nodes; + X509_POLICY_NODE *node; + int i; + nodes = curr->nodes; + if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + /* Delete any mapped data: see RFC 3280 XXXX */ + if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + } + + for (;;) { + --curr; + nodes = curr->nodes; + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + if (node->nchild == 0) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + if (curr->anyPolicy && !curr->anyPolicy->nchild) { + if (curr->anyPolicy->parent) + curr->anyPolicy->parent->nchild--; + OPENSSL_free(curr->anyPolicy); + curr->anyPolicy = NULL; + } + if (curr == tree->levels) { + /* If we zapped anyPolicy at top then tree is empty */ + if (!curr->anyPolicy) + return 2; + return 1; + } + } + +} + +static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, + X509_POLICY_NODE *pcy) +{ + if (!*pnodes) { + *pnodes = policy_node_cmp_new(); + if (!*pnodes) + return 0; + } else { + sk_X509_POLICY_NODE_sort(*pnodes); + if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy)) + return 1; + } + if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) + return 0; + + return 1; + +} + +/* + * Calculate the authority set based on policy tree. The 'pnodes' parameter + * is used as a store for the set of policy nodes used to calculate the user + * set. If the authority set is not anyPolicy then pnodes will just point to + * the authority set. If however the authority set is anyPolicy then the set + * of valid policies (other than anyPolicy) is store in pnodes. The return + * value of '2' is used in this case to indicate that pnodes should be freed. + */ + +static int tree_calculate_authority_set(X509_POLICY_TREE *tree, + STACK_OF(X509_POLICY_NODE) **pnodes) +{ + X509_POLICY_LEVEL *curr; + X509_POLICY_NODE *node, *anyptr; + STACK_OF(X509_POLICY_NODE) **addnodes; + int i; + size_t j; + curr = tree->levels + tree->nlevel - 1; + + /* If last level contains anyPolicy set is anyPolicy */ + if (curr->anyPolicy) { + if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) + return 0; + addnodes = pnodes; + } else + /* Add policies to authority set */ + addnodes = &tree->auth_policies; + + curr = tree->levels; + for (i = 1; i < tree->nlevel; i++) { + /* + * If no anyPolicy node on this this level it can't appear on lower + * levels so end search. + */ + if (!(anyptr = curr->anyPolicy)) + break; + curr++; + for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { + node = sk_X509_POLICY_NODE_value(curr->nodes, j); + if ((node->parent == anyptr) + && !tree_add_auth_node(addnodes, node)) + return 0; + } + } + + if (addnodes == pnodes) + return 2; + + *pnodes = tree->auth_policies; + + return 1; +} + +static int tree_calculate_user_set(X509_POLICY_TREE *tree, + STACK_OF(ASN1_OBJECT) *policy_oids, + STACK_OF(X509_POLICY_NODE) *auth_nodes) +{ + size_t i; + X509_POLICY_NODE *node; + ASN1_OBJECT *oid; + + X509_POLICY_NODE *anyPolicy; + X509_POLICY_DATA *extra; + + /* + * Check if anyPolicy present in authority constrained policy set: this + * will happen if it is a leaf node. + */ + + if (sk_ASN1_OBJECT_num(policy_oids) <= 0) + return 1; + + anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + if (OBJ_obj2nid(oid) == NID_any_policy) { + tree->flags |= POLICY_FLAG_ANY_POLICY; + return 1; + } + } + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + node = tree_find_sk(auth_nodes, oid); + if (!node) { + if (!anyPolicy) + continue; + /* + * Create a new node with policy ID from user set and qualifiers + * from anyPolicy. + */ + extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); + if (!extra) + return 0; + extra->qualifier_set = anyPolicy->data->qualifier_set; + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; + node = level_add_node(NULL, extra, anyPolicy->parent, tree); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); + if (!tree->user_policies) + return 1; + } + if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) + return 0; + } + return 1; + +} + +static int tree_evaluate(X509_POLICY_TREE *tree) +{ + int ret, i; + X509_POLICY_LEVEL *curr = tree->levels + 1; + const X509_POLICY_CACHE *cache; + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = policy_cache_set(curr->cert); + if (!tree_link_nodes(curr, cache)) + return 0; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) + && !tree_link_any(curr, cache, tree)) + return 0; + tree_print("before tree_prune()", tree, curr); + ret = tree_prune(tree, curr); + if (ret != 1) + return ret; + } + + return 1; + +} + +static void exnode_free(X509_POLICY_NODE *node) +{ + if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) + OPENSSL_free(node); +} + +void X509_policy_tree_free(X509_POLICY_TREE *tree) +{ + X509_POLICY_LEVEL *curr; + int i; + + if (!tree) + return; + + sk_X509_POLICY_NODE_free(tree->auth_policies); + sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); + + for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { + if (curr->cert) + X509_free(curr->cert); + if (curr->nodes) + sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); + if (curr->anyPolicy) + policy_node_free(curr->anyPolicy); + } + + if (tree->extra_data) + sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); + + OPENSSL_free(tree->levels); + OPENSSL_free(tree); + +} + +/*- + * Application policy checking function. + * Return codes: + * 0 Internal Error. + * 1 Successful. + * -1 One or more certificates contain invalid or inconsistent extensions + * -2 User constrained policy set empty and requireExplicit true. + */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) +{ + int ret; + int calc_ret; + X509_POLICY_TREE *tree = NULL; + STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; + *ptree = NULL; + + *pexplicit_policy = 0; + ret = tree_init(&tree, certs, flags); + + switch (ret) { + + /* Tree empty requireExplicit False: OK */ + case 2: + return 1; + + /* Some internal error */ + case -1: + return -1; + + /* Some internal error */ + case 0: + return 0; + + /* Tree empty requireExplicit True: Error */ + + case 6: + *pexplicit_policy = 1; + return -2; + + /* Tree OK requireExplicit True: OK and continue */ + case 5: + *pexplicit_policy = 1; + break; + + /* Tree OK: continue */ + + case 1: + if (!tree) + /* + * tree_init() returns success and a null tree + * if it's just looking at a trust anchor. + * I'm not sure that returning success here is + * correct, but I'm sure that reporting this + * as an internal error which our caller + * interprets as a malloc failure is wrong. + */ + return 1; + break; + } + + if (!tree) + goto error; + ret = tree_evaluate(tree); + + tree_print("tree_evaluate()", tree, NULL); + + if (ret <= 0) + goto error; + + /* Return value 2 means tree empty */ + if (ret == 2) { + X509_policy_tree_free(tree); + if (*pexplicit_policy) + return -2; + else + return 1; + } + + /* Tree is not empty: continue */ + + calc_ret = tree_calculate_authority_set(tree, &auth_nodes); + + if (!calc_ret) + goto error; + + ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); + + if (calc_ret == 2) + sk_X509_POLICY_NODE_free(auth_nodes); + + if (!ret) + goto error; + + + if (tree) + *ptree = tree; + + if (*pexplicit_policy) { + nodes = X509_policy_tree_get0_user_policies(tree); + if (sk_X509_POLICY_NODE_num(nodes) <= 0) + return -2; + } + + return 1; + + error: + + X509_policy_tree_free(tree); + + return 0; + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c new file mode 100644 index 00000000..1658b7c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c @@ -0,0 +1,223 @@ +/* v3_akey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist); +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_akey_id = { + NID_authority_key_identifier, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, + (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, + 0, 0, + NULL +}; + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist) +{ + int extlist_was_null = extlist == NULL; + if (akeyid->keyid) { + char *tmp = x509v3_bytes_to_hex(akeyid->keyid->data, + akeyid->keyid->length); + int ok = tmp != NULL && X509V3_add_value("keyid", tmp, &extlist); + OPENSSL_free(tmp); + if (!ok) { + goto err; + } + } + if (akeyid->issuer) { + STACK_OF(CONF_VALUE) *tmpextlist = + i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); + if (tmpextlist == NULL) { + goto err; + } + extlist = tmpextlist; + } + if (akeyid->serial) { + if (!X509V3_add_value_int("serial", akeyid->serial, &extlist)) { + goto err; + } + } + return extlist; + +err: + if (extlist_was_null) { + sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free); + } + return NULL; +} + +/* + * Currently two options: keyid: use the issuers subject keyid, the value + * 'always' means its is an error if the issuer certificate doesn't have a + * key id. issuer: use the issuers cert issuer and serial number. The default + * is to only use this if keyid is not present. With the option 'always' this + * is always included. + */ + +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; + size_t i; + int j; + CONF_VALUE *cnf; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + X509_EXTENSION *ext; + X509 *cert; + AUTHORITY_KEYID *akeyid; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + keyid = 2; + } else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + issuer = 2; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION); + ERR_add_error_data(2, "name=", cnf->name); + return NULL; + } + } + + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) + return AUTHORITY_KEYID_new(); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((j >= 0) && (ext = X509_get_ext(cert, j))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + if (!isname || !serial) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) + || !(gen = GENERAL_NAME_new()) + || !sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + + err: + X509_NAME_free(isname); + ASN1_INTEGER_free(serial); + ASN1_OCTET_STRING_free(ikeyid); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c new file mode 100644 index 00000000..976597c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c @@ -0,0 +1,72 @@ +/* v3_akey_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + + +ASN1_SEQUENCE(AUTHORITY_KEYID) = { + ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), + ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) +} ASN1_SEQUENCE_END(AUTHORITY_KEYID) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c new file mode 100644 index 00000000..6344cdca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c @@ -0,0 +1,642 @@ +/* v3_alt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "../x509/internal.h" +#include "internal.h" + + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); + +const X509V3_EXT_METHOD v3_alt[] = { + {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_subject_alt, + NULL, NULL, NULL}, + + {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_issuer_alt, + NULL, NULL, NULL}, + + {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + NULL, NULL, NULL, NULL}, +}; + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) +{ + int ret_was_null = ret == NULL; + for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); + STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret); + if (tmp == NULL) { + if (ret_was_null) { + sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); + } + return NULL; + } + ret = tmp; + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) +{ + /* Note the error-handling for this function relies on there being at most + * one |X509V3_add_value| call. If there were two and the second failed, we + * would need to sometimes free the first call's result. */ + unsigned char *p; + char oline[256], htmp[5]; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + if (!X509V3_add_value("othername", "", &ret)) + return NULL; + break; + + case GEN_X400: + if (!X509V3_add_value("X400Name", "", &ret)) + return NULL; + break; + + case GEN_EDIPARTY: + if (!X509V3_add_value("EdiPartyName", "", &ret)) + return NULL; + break; + + case GEN_EMAIL: + if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret)) + return NULL; + break; + + case GEN_DNS: + if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret)) + return NULL; + break; + + case GEN_URI: + if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret)) + return NULL; + break; + + case GEN_DIRNAME: + if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL + || !X509V3_add_value("DirName", oline, &ret)) + return NULL; + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_snprintf(oline, sizeof(oline), + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_snprintf(htmp, sizeof(htmp), "%X", v); + p += 2; + OPENSSL_strlcat(oline, htmp, sizeof(oline)); + if (i != 7) + OPENSSL_strlcat(oline, ":", sizeof(oline)); + } + } else { + if (!X509V3_add_value("IP Address", "", &ret)) + return NULL; + break; + } + if (!X509V3_add_value("IP Address", oline, &ret)) + return NULL; + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + if (!X509V3_add_value("Registered ID", oline, &ret)) + return NULL; + break; + } + return ret; +} + +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +{ + unsigned char *p; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; + + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; + + case GEN_EDIPARTY: + /* Maybe fix this: it is supported now */ + BIO_printf(out, "EdiPartyName:"); + break; + + case GEN_EMAIL: + BIO_printf(out, "email:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_URI: + BIO_printf(out, "URI:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (i = 0; i < 8; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_printf(out, ":%X", v); + p += 2; + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; + + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} + +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!x509v3_name_cmp(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_issuer(ctx, gens)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +{ + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS); + return 0; + } + int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + + int ret = 0; + GENERAL_NAMES *ialt = NULL; + X509_EXTENSION *ext; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j); + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + /* Ownership of |gen| has moved from |ialt| to |gens|. */ + sk_GENERAL_NAME_set(ialt, j, NULL); + } + + ret = 1; + +err: + GENERAL_NAMES_free(ialt); + return ret; +} + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* + * Copy any email addresses in a certificate or request to GENERAL_NAMES + */ + +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + if (ctx != NULL && ctx->flags == CTX_TEST) + return 1; + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + return 1; + + err: + GENERAL_NAME_free(gen); + ASN1_IA5STRING_free(email); + return 0; + +} + +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAME *gen; + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf) +{ + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); +} + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc) +{ + char is_string = 0; + GENERAL_NAME *gen = NULL; + + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + } + + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: + is_string = 1; + break; + + case GEN_RID: + { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; + } + gen->d.rid = obj; + } + break; + + case GEN_IPADD: + if (is_nc) + gen->d.ip = a2i_IPADDRESS_NC(value); + else + gen->d.ip = a2i_IPADDRESS(value); + if (gen->d.ip == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + default: + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE); + goto err; + } + + if (is_string) { + if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, + strlen(value))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + gen->type = gen_type; + + return gen; + + err: + if (!out) + GENERAL_NAME_free(gen); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ + int type; + + char *name, *value; + + name = cnf->name; + value = cnf->value; + + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (!x509v3_name_cmp(name, "email")) + type = GEN_EMAIL; + else if (!x509v3_name_cmp(name, "URI")) + type = GEN_URI; + else if (!x509v3_name_cmp(name, "DNS")) + type = GEN_DNS; + else if (!x509v3_name_cmp(name, "RID")) + type = GEN_RID; + else if (!x509v3_name_cmp(name, "IP")) + type = GEN_IPADD; + else if (!x509v3_name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if (!x509v3_name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + return NULL; + } + + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + +} + +static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) +{ + char *objtmp = NULL; + const char *p; + int objlen; + if (!(p = strchr(value, ';'))) + return 0; + if (!(gen->d.otherName = OTHERNAME_new())) + return 0; + /* + * Free this up because we will overwrite it. no need to free type_id + * because it is static + */ + ASN1_TYPE_free(gen->d.otherName->value); + if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + return 0; + objlen = p - value; + objtmp = OPENSSL_malloc(objlen + 1); + if (objtmp == NULL) + return 0; + OPENSSL_strlcpy(objtmp, value, objlen + 1); + gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + OPENSSL_free(objtmp); + if (!gen->d.otherName->type_id) + return 0; + return 1; +} + +static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) +{ + int ret = 0; + STACK_OF(CONF_VALUE) *sk = NULL; + X509_NAME *nm = X509_NAME_new(); + if (nm == NULL) + goto err; + sk = X509V3_get_section(ctx, value); + if (sk == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + /* FIXME: should allow other character types... */ + if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) + goto err; + gen->d.dirn = nm; + ret = 1; + + err: + if (!ret) + X509_NAME_free(nm); + X509V3_section_free(ctx, sk); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c new file mode 100644 index 00000000..3d04bf47 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c @@ -0,0 +1,133 @@ +/* v3_bcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist); +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_bcons = { + NID_basic_constraints, 0, + ASN1_ITEM_ref(BASIC_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, + (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { + ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), + ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) +} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) + +IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist) +{ + X509V3_add_value_bool("CA", bcons->ca, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; +} + +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + size_t i; + if (!(bcons = BASIC_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) + goto err; + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c new file mode 100644 index 00000000..45c61868 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c @@ -0,0 +1,144 @@ +/* v3_bitst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + + +static const BIT_STRING_BITNAME ns_cert_type_table[] = { + {0, "SSL Client", "client"}, + {1, "SSL Server", "server"}, + {2, "S/MIME", "email"}, + {3, "Object Signing", "objsign"}, + {4, "Unused", "reserved"}, + {5, "SSL CA", "sslCA"}, + {6, "S/MIME CA", "emailCA"}, + {7, "Object Signing CA", "objCA"}, + {-1, NULL, NULL} +}; + +static const BIT_STRING_BITNAME key_usage_type_table[] = { + {0, "Digital Signature", "digitalSignature"}, + {1, "Non Repudiation", "nonRepudiation"}, + {2, "Key Encipherment", "keyEncipherment"}, + {3, "Data Encipherment", "dataEncipherment"}, + {4, "Key Agreement", "keyAgreement"}, + {5, "Certificate Sign", "keyCertSign"}, + {6, "CRL Sign", "cRLSign"}, + {7, "Encipher Only", "encipherOnly"}, + {8, "Decipher Only", "decipherOnly"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_nscert = +EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); +const X509V3_EXT_METHOD v3_key_usage = +EXT_BITSTRING(NID_key_usage, key_usage_type_table); + +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *ret) +{ + const BIT_STRING_BITNAME *bnam; + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) + X509V3_add_value(bnam->lname, NULL, &ret); + } + return ret; +} + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *val; + ASN1_BIT_STRING *bs; + size_t i; + const BIT_STRING_BITNAME *bnam; + if (!(bs = ASN1_BIT_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, val->name) || + !strcmp(bnam->lname, val->name)) { + if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c new file mode 100644 index 00000000..1d038850 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c @@ -0,0 +1,468 @@ +/* v3_conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +/* extension creation utilities */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509/internal.h" +#include "internal.h" + +static int v3_check_critical(const char **value); +static int v3_check_generic(const char **value); +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, const char *value); +static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, + int crit, int type, + X509V3_CTX *ctx); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc); +static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, + long *ext_len); +/* CONF *conf: Config file */ +/* char *name: Name */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value) +{ + int crit; + int ext_type; + X509_EXTENSION *ret; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(name, value, crit, ext_type, ctx); + ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION); + ERR_add_error_data(4, "name=", name, ", value=", value); + } + return ret; +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value) +{ + int crit; + int ext_type; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(OBJ_nid2sn(ext_nid), + value, crit, ext_type, ctx); + return do_ext_nconf(conf, ctx, ext_nid, crit, value); +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, const char *value) +{ + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + void *ext_struc; + if (ext_nid == NID_undef) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + /* Now get internal extension representation based on type */ + if (method->v2i) { + if (*value == '@') + nval = NCONF_get_section(conf, value + 1); + else + nval = X509V3_parse_list(value); + if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", + value); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (!ext_struc) + return NULL; + } else if (method->s2i) { + if (!(ext_struc = method->s2i(method, ctx, value))) + return NULL; + } else if (method->r2i) { + if (!ctx->db || !ctx->db_meth) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) + return NULL; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); + return NULL; + } + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + if (method->it) + ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_struc); + return ext; + +} + +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc) +{ + unsigned char *ext_der; + int ext_len; + ASN1_OCTET_STRING *ext_oct; + X509_EXTENSION *ext; + /* Convert internal representation to DER */ + if (method->it) { + ext_der = NULL; + ext_len = + ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); + if (ext_len < 0) + goto merr; + } else { + unsigned char *p; + ext_len = method->i2d(ext_struc, NULL); + if (!(ext_der = OPENSSL_malloc(ext_len))) + goto merr; + p = ext_der; + method->i2d(ext_struc, &p); + } + if (!(ext_oct = ASN1_OCTET_STRING_new())) + goto merr; + ext_oct->data = ext_der; + ext_oct->length = ext_len; + + ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + if (!ext) + goto merr; + ASN1_OCTET_STRING_free(ext_oct); + + return ext; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + +} + +/* Given an internal structure, nid and critical flag create an extension */ + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) +{ + const X509V3_EXT_METHOD *method; + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); +} + +/* Check the extension string for critical flag */ +static int v3_check_critical(const char **value) +{ + const char *p = *value; + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + return 0; + p += 9; + while (isspace((unsigned char)*p)) + p++; + *value = p; + return 1; +} + +/* Check extension string for generic extension and return the type */ +static int v3_check_generic(const char **value) +{ + int gen_type = 0; + const char *p = *value; + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else + return 0; + + while (isspace((unsigned char)*p)) + p++; + *value = p; + return gen_type; +} + +/* Create a generic extension: for now just handle DER type */ +static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, + int crit, int gen_type, + X509V3_CTX *ctx) +{ + unsigned char *ext_der = NULL; + long ext_len = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR); + ERR_add_error_data(2, "name=", ext); + goto err; + } + + if (gen_type == 1) + ext_der = x509v3_hex_to_bytes(value, &ext_len); + else if (gen_type == 2) + ext_der = generic_asn1(value, ctx, &ext_len); + + if (ext_der == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (!(oct = ASN1_OCTET_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + + oct->data = ext_der; + oct->length = ext_len; + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + + err: + ASN1_OBJECT_free(obj); + ASN1_OCTET_STRING_free(oct); + if (ext_der) + OPENSSL_free(ext_der); + return extension; + +} + +static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, + long *ext_len) +{ + ASN1_TYPE *typ; + unsigned char *ext_der = NULL; + typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) + return NULL; + *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + return ext_der; +} + +/* + * This is the main function: add a bunch of extensions based on a config + * file section to an extension STACK. + */ + +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk) +{ + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + CONF_VALUE *val; + size_t i; + if (!(nval = NCONF_get_section(conf, section))) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) + return 0; + if (sk) + X509v3_add_ext(sk, ext, -1); + X509_EXTENSION_free(ext); + } + return 1; +} + +/* + * Convenience functions to add extensions to a certificate, CRL and request + */ + +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (cert) + sk = &cert->cert_info->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Same as above but for a CRL */ + +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (crl) + sk = &crl->crl->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Add extensions to certificate request */ + +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + if (req) + sk = &extlist; + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) + return i; + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; +} + +/* Config database functions */ + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_string) + return ctx->db_meth->get_string(ctx->db, name, section); + return NULL; +} + +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_section) + return ctx->db_meth->get_section(ctx->db, section); + return NULL; +} + +void X509V3_string_free(X509V3_CTX *ctx, char *str) +{ + if (!str) + return; + if (ctx->db_meth->free_string) + ctx->db_meth->free_string(ctx->db, str); +} + +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) +{ + if (!section) + return; + if (ctx->db_meth->free_section) + ctx->db_meth->free_section(ctx->db, section); +} + +static char *nconf_get_string(void *db, const char *section, const char *value) +{ + /* TODO(fork): This returns a non-const pointer because |X509V3_CONF_METHOD| + * allows |get_string| to return caller-owned pointers, provided they're + * freed by |free_string|. |nconf_method| leaves |free_string| NULL, and + * there are no other implementations of |X509V3_CONF_METHOD|, so this can + * be simplified if we make it private. */ + return (char *)NCONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) +{ + return NCONF_get_section(db, section); +} + +static const X509V3_CONF_METHOD nconf_method = { + nconf_get_string, + nconf_get_section, + NULL, + NULL +}; + +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) +{ + ctx->db_meth = &nconf_method; + ctx->db = conf; +} + +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, + X509_CRL *crl, int flags) +{ + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c new file mode 100644 index 00000000..96f2a547 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c @@ -0,0 +1,500 @@ +/* v3_cpols.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +/* Certificate policies extension support: this one is a bit complex... */ + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent); +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value); +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent); +static void print_notice(BIO *out, USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); + +const X509V3_EXT_METHOD v3_cpols = { + NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), + 0, 0, 0, 0, + 0, 0, + 0, 0, + (X509V3_EXT_I2R)i2r_certpol, + (X509V3_EXT_R2I)r2i_certpol, + NULL +}; + +ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) +ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) + +IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) + +ASN1_SEQUENCE(POLICYINFO) = { + ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), + ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) + +ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); + +ASN1_ADB(POLICYQUALINFO) = { + ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), + ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) +} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); + +ASN1_SEQUENCE(POLICYQUALINFO) = { + ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), + ASN1_ADB_OBJECT(POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYQUALINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) + +ASN1_SEQUENCE(USERNOTICE) = { + ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), + ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) +} ASN1_SEQUENCE_END(USERNOTICE) + +IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) + +ASN1_SEQUENCE(NOTICEREF) = { + ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), + ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) +} ASN1_SEQUENCE_END(NOTICEREF) + +IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) + +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + STACK_OF(POLICYINFO) *pols = NULL; + char *pstr; + POLICYINFO *pol; + ASN1_OBJECT *pobj; + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *cnf; + size_t i; + int ia5org; + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB); + goto err; + } + ia5org = 0; + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + STACK_OF(CONF_VALUE) *polsect; + polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + X509V3_section_free(ctx, polsect); + if (!pol) + goto err; + } else { + if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(pobj); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; + err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; +} + +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org) +{ + size_t i; + CONF_VALUE *cnf; + POLICYINFO *pol; + POLICYQUALINFO *qual; + if (!(pol = POLICYINFO_new())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + cnf = sk_CONF_VALUE_value(polstrs, i); + if (!strcmp(cnf->name, "policyIdentifier")) { + ASN1_OBJECT *pobj; + if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol->policyid = pobj; + + } else if (!x509v3_name_cmp(cnf->name, "CPS")) { + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); + goto err; + } + qual->d.cpsuri = ASN1_IA5STRING_new(); + if (qual->d.cpsuri == NULL) { + goto err; + } + if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!x509v3_name_cmp(cnf->name, "userNotice")) { + STACK_OF(CONF_VALUE) *unot; + if (*cnf->value != '@') { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + X509V3_section_free(ctx, unot); + if (!qual) + goto err; + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; + } + } + if (!pol->policyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + POLICYINFO_free(pol); + return NULL; + +} + +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + size_t i; + int ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(not = USERNOTICE_new())) + goto merr; + qual->d.usernotice = not; + for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { + cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + not->exptext = ASN1_VISIBLESTRING_new(); + if (not->exptext == NULL) + goto merr; + if (!ASN1_STRING_set(not->exptext, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + if (ia5org) + nref->organization->type = V_ASN1_IA5STRING; + else + nref->organization->type = V_ASN1_VISIBLESTRING; + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + goto err; + } + ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) + goto err; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + POLICYQUALINFO_free(qual); + return NULL; +} + +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) +{ + CONF_VALUE *cnf; + ASN1_INTEGER *aint; + + size_t i; + + for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { + cnf = sk_CONF_VALUE_value(nos, i); + if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + + merr: + ASN1_INTEGER_free(aint); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + return 0; +} + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) +{ + size_t i; + POLICYINFO *pinfo; + /* First print out the policy OIDs */ + for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + pinfo = sk_POLICYINFO_value(pol, i); + BIO_printf(out, "%*sPolicy: ", indent, ""); + i2a_ASN1_OBJECT(out, pinfo->policyid); + BIO_puts(out, "\n"); + if (pinfo->qualifiers) + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + return 1; +} + +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent) +{ + POLICYQUALINFO *qualinfo; + size_t i; + for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %.*s\n", indent, "", + qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + size_t i; + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", + ref->organization->length, ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) + BIO_puts(out, ", "); + if (num == NULL) + BIO_puts(out, "(null)"); + else { + tmp = i2s_ASN1_INTEGER(NULL, num); + if (tmp == NULL) + return; + BIO_puts(out, tmp); + OPENSSL_free(tmp); + } + } + BIO_puts(out, "\n"); + } + if (notice->exptext) + BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", + notice->exptext->length, notice->exptext->data); +} + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) +{ + const X509_POLICY_DATA *dat = node->data; + + BIO_printf(out, "%*sPolicy: ", indent, ""); + + i2a_ASN1_OBJECT(out, dat->valid_policy); + BIO_puts(out, "\n"); + BIO_printf(out, "%*s%s\n", indent + 2, "", + node_data_critical(dat) ? "Critical" : "Non Critical"); + if (dat->qualifier_set) + print_qualifiers(out, dat->qualifier_set, indent + 2); + else + BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c new file mode 100644 index 00000000..e232d22c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c @@ -0,0 +1,563 @@ +/* v3_crld.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../x509/internal.h" + + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = { + NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_freshest_crl = { + NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, + char *sect) +{ + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; +} + +static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + if (!strncmp(cnf->name, "fullname", 9)) { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } else if (!strcmp(cnf->name, "relativename")) { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* + * Since its a name fragment can't have more than one RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + + err: + if (fnm) + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + if (rnm) + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; +} + +static const BIT_STRING_BITNAME reason_flags[] = { + {0, "Unused", "unused"}, + {1, "Key Compromise", "keyCompromise"}, + {2, "CA Compromise", "CACompromise"}, + {3, "Affiliation Changed", "affiliationChanged"}, + {4, "Superseded", "superseded"}, + {5, "Cessation Of Operation", "cessationOfOperation"}, + {6, "Certificate Hold", "certificateHold"}, + {7, "Privilege Withdrawn", "privilegeWithdrawn"}, + {8, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +static int set_reasons(ASN1_BIT_STRING **preas, char *value) +{ + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + size_t i; + int ret = 0; + rsk = X509V3_parse_list(value); + if (!rsk) + return 0; + if (*preas) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + + err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; +} + +static int print_reasons(BIO *out, const char *rname, + ASN1_BIT_STRING *rflags, int indent) +{ + int first = 1; + const BIT_STRING_BITNAME *pbn; + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; +} + +static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + size_t i; + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + point = DIST_POINT_new(); + if (!point) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } else if (!strcmp(cnf->name, "CRLissuer")) { + point->CRLissuer = gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } + } + + return point; + + err: + if (point) + DIST_POINT_free(point); + return NULL; +} + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + size_t i; + if (!(crld = sk_DIST_POINT_new_null())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (!(gens = GENERAL_NAMES_new())) + goto merr; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if (!(point = DIST_POINT_new())) + goto merr; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; +} + +static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch (operation) { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; +} + + +ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { + ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), + ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) +} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) + + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) + +ASN1_SEQUENCE(DIST_POINT) = { + ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) +} ASN1_SEQUENCE_END(DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) + +ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) +ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) + +IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) + +ASN1_SEQUENCE(ISSUING_DIST_POINT) = { + ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), + ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) +} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ISSUING_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_idp, + i2r_idp, 0, + NULL +}; + +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + size_t i; + int ret; + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) +{ + size_t i; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) +{ + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; +} + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent) +{ + ISSUING_DIST_POINT *idp = pidp; + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) + && (idp->indirectCRL <= 0) && !idp->onlysomereasons + && (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; +} + +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent) +{ + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + size_t i; + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) + print_distpoint(out, point->distpoint, indent); + if (point->reasons) + print_reasons(out, "Reasons", point->reasons, indent); + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; +} + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +{ + size_t i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c new file mode 100644 index 00000000..a3fcbb06 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c @@ -0,0 +1,106 @@ +/* v3_enum.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include "internal.h" + + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +static const ENUMERATED_NAMES crl_reasons[] = { + {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, + {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, + {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, + {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", + "affiliationChanged"}, + {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, + {CRL_REASON_CESSATION_OF_OPERATION, + "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, + {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, + {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", + "privilegeWithdrawn"}, + {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_crl_reason = { + NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + 0, + 0, 0, 0, 0, + (void *)crl_reasons +}; + +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, + const ASN1_ENUMERATED *e) +{ + const ENUMERATED_NAMES *enam; + long strval; + strval = ASN1_ENUMERATED_get(e); + for (enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) + return OPENSSL_strdup(enam->lname); + } + return i2s_ASN1_ENUMERATED(method, e); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c new file mode 100644 index 00000000..ae426815 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c @@ -0,0 +1,148 @@ +/* v3_extku.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *eku, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_ext_ku = { + NID_ext_key_usage, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD v3_ocsp_accresp = { + NID_id_pkix_OCSP_acceptableResponses, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) +ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) + +IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) + +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + EXTENDED_KEY_USAGE *eku = a; + size_t i; + ASN1_OBJECT *obj; + char obj_tmp[80]; + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + obj = sk_ASN1_OBJECT_value(eku, i); + i2t_ASN1_OBJECT(obj_tmp, 80, obj); + X509V3_add_value(NULL, obj_tmp, &ext_list); + } + return ext_list; +} + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + EXTENDED_KEY_USAGE *extku; + char *extval; + ASN1_OBJECT *objtmp; + CONF_VALUE *val; + size_t i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + sk_ASN1_OBJECT_push(extku, objtmp); + } + return extku; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c new file mode 100644 index 00000000..cba51e13 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c @@ -0,0 +1,266 @@ +/* v3_genn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + + +ASN1_SEQUENCE(OTHERNAME) = { + ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), + /* Maybe have a true ANY DEFINED BY later */ + ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) +} ASN1_SEQUENCE_END(OTHERNAME) + +IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) + +ASN1_SEQUENCE(EDIPARTYNAME) = { + /* DirectoryString is a CHOICE type, so use explicit tagging. */ + ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), + ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) +} ASN1_SEQUENCE_END(EDIPARTYNAME) + +IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) + +ASN1_CHOICE(GENERAL_NAME) = { + ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), + ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), + ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), + /* Don't decode this */ + ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), + /* X509_NAME is a CHOICE type so use EXPLICIT */ + ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), + ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), + ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), + ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), + ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) +} ASN1_CHOICE_END(GENERAL_NAME) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) + +ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) +ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) + +IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME) + +static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) +{ + /* nameAssigner is optional and may be NULL. */ + if (a->nameAssigner == NULL) { + if (b->nameAssigner != NULL) { + return -1; + } + } else { + if (b->nameAssigner == NULL || + ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner) != 0) { + return -1; + } + } + + /* partyName may not be NULL. */ + return ASN1_STRING_cmp(a->partyName, b->partyName); +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) +{ + if (!a || !b || a->type != b->type) + return -1; + + switch (a->type) { + case GEN_X400: + return ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); + + case GEN_EDIPARTY: + return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); + + case GEN_OTHERNAME: + return OTHERNAME_cmp(a->d.otherName, b->d.otherName); + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + + case GEN_DIRNAME: + return X509_NAME_cmp(a->d.dirn, b->d.dirn); + + case GEN_IPADD: + return ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + + case GEN_RID: + return OBJ_cmp(a->d.rid, b->d.rid); + } + + return -1; +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) +{ + int result = -1; + + if (!a || !b) + return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; +} + +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) +{ + switch (type) { + case GEN_X400: + a->d.x400Address = value; + break; + + case GEN_EDIPARTY: + a->d.ediPartyName = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; +} + +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) +{ + if (ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: + return a->d.x400Address; + + case GEN_EDIPARTY: + return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } +} + +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value) +{ + OTHERNAME *oth; + oth = OTHERNAME_new(); + if (!oth) + return 0; + ASN1_TYPE_free(oth->value); + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; +} + +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue) +{ + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c new file mode 100644 index 00000000..20d27e5d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c @@ -0,0 +1,121 @@ +/* v3_ia5.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5); +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { + EXT_IA5STRING(NID_netscape_base_url), + EXT_IA5STRING(NID_netscape_revocation_url), + EXT_IA5STRING(NID_netscape_ca_revocation_url), + EXT_IA5STRING(NID_netscape_renewal_url), + EXT_IA5STRING(NID_netscape_ca_policy_url), + EXT_IA5STRING(NID_netscape_ssl_server_name), + EXT_IA5STRING(NID_netscape_comment), + EXT_END +}; + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5) +{ + char *tmp; + if (!ia5 || !ia5->length) + return NULL; + if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_IA5STRING *ia5; + if (!str) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set(ia5, str, strlen(str))) { + ASN1_IA5STRING_free(ia5); + goto err; + } + return ia5; + err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c new file mode 100644 index 00000000..a135c61d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c @@ -0,0 +1,218 @@ +/* v3_info.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, AUTHORITY_INFO_ACCESS + *ainfo, STACK_OF(CONF_VALUE) + *ret); +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval); + +const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { + ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), + ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) +} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) + +IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) + +ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) +ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, + STACK_OF(CONF_VALUE) *ret) +{ + ACCESS_DESCRIPTION *desc; + size_t i; + int nlen; + char objtmp[80], *ntmp; + CONF_VALUE *vtmp; + STACK_OF(CONF_VALUE) *tret = ret; + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + STACK_OF(CONF_VALUE) *tmp; + + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); + tmp = i2v_GENERAL_NAME(method, desc->location, tret); + if (tmp == NULL) + goto err; + tret = tmp; + vtmp = sk_CONF_VALUE_value(tret, i); + i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); + nlen = strlen(objtmp) + strlen(vtmp->name) + 5; + ntmp = OPENSSL_malloc(nlen); + if (ntmp == NULL) + goto err; + OPENSSL_strlcpy(ntmp, objtmp, nlen); + OPENSSL_strlcat(ntmp, " - ", nlen); + OPENSSL_strlcat(ntmp, vtmp->name, nlen); + OPENSSL_free(vtmp->name); + vtmp->name = ntmp; + + } + if (ret == NULL && tret == NULL) + return sk_CONF_VALUE_new_null(); + + return tret; + err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (ret == NULL && tret != NULL) + sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); + return NULL; +} + +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval) +{ + AUTHORITY_INFO_ACCESS *ainfo = NULL; + CONF_VALUE *cnf, ctmp; + ACCESS_DESCRIPTION *acc; + size_t i; + int objlen; + char *objtmp, *ptmp; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(acc = ACCESS_DESCRIPTION_new()) + || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; + } + objlen = ptmp - cnf->name; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) + goto err; + if (!(objtmp = OPENSSL_malloc(objlen + 1))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_strlcpy(objtmp, cnf->name, objlen + 1); + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", objtmp); + OPENSSL_free(objtmp); + goto err; + } + OPENSSL_free(objtmp); + + } + return ainfo; + err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; +} + +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a) +{ + i2a_ASN1_OBJECT(bp, a->method); +#ifdef UNDEF + i2a_GENERAL_NAME(bp, a->location); +#endif + return 2; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c new file mode 100644 index 00000000..66b60f35 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c @@ -0,0 +1,91 @@ +/* v3_int.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +const X509V3_EXT_METHOD v3_crl_num = { + NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +const X509V3_EXT_METHOD v3_delta_crl = { + NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, + char *value) +{ + return s2i_ASN1_INTEGER(meth, value); +} + +const X509V3_EXT_METHOD v3_inhibit_anyp = { + NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + (X509V3_EXT_S2I)s2i_asn1_int, + 0, 0, 0, 0, NULL +}; diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c new file mode 100644 index 00000000..44a9619f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c @@ -0,0 +1,379 @@ +/* v3_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include + +#include +#include +#include +#include +#include + +#include "../x509/internal.h" + +#include "ext_dat.h" +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static void ext_list_free(X509V3_EXT_METHOD *ext); + +static int ext_stack_cmp(const X509V3_EXT_METHOD **a, + const X509V3_EXT_METHOD **b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + return 1; +} + +static int ext_cmp(const void *void_a, const void *void_b) +{ + const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a; + const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b; + return ext_stack_cmp(a, b); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const *ret; + size_t idx; + + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = + bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, + sizeof(X509V3_EXT_METHOD *), ext_cmp); + if (ret) + return *ret; + if (!ext_list) + return NULL; + + sk_X509V3_EXT_METHOD_sort(ext_list); + if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) + return NULL; + return sk_X509V3_EXT_METHOD_value(ext_list, idx); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get(const X509_EXTENSION *ext) +{ + int nid; + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) + return NULL; + return X509V3_EXT_get_nid(nid); +} + +int X509V3_EXT_free(int nid, void *ext_data) +{ + const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid); + if (ext_method == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION); + return 0; + } + + if (ext_method->it != NULL) + ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it)); + else if (ext_method->ext_free != NULL) + ext_method->ext_free(ext_data); + else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION); + return 0; + } + + return 1; +} + +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) +{ + for (; extlist->ext_nid != -1; extlist++) + if (!X509V3_EXT_add(extlist)) + return 0; + return 1; +} + +int X509V3_EXT_add_alias(int nid_to, int nid_from) +{ + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (! + (tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + tmpext->ext_flags |= X509V3_EXT_DYNAMIC; + return X509V3_EXT_add(tmpext); +} + +void X509V3_EXT_cleanup(void) +{ + sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); + ext_list = NULL; +} + +static void ext_list_free(X509V3_EXT_METHOD *ext) +{ + if (ext->ext_flags & X509V3_EXT_DYNAMIC) + OPENSSL_free(ext); +} + +/* + * Legacy function: we don't need to add standard extensions any more because + * they are now kept in ext_dat.h. + */ + +int X509V3_add_standard_extensions(void) +{ + return 1; +} + +/* Return an extension internal structure */ + +void *X509V3_EXT_d2i(const X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method; + const unsigned char *p; + + if (!(method = X509V3_EXT_get(ext))) + return NULL; + p = ext->value->data; + void *ret; + if (method->it) { + ret = ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + } else { + ret = method->d2i(NULL, &p, ext->value->length); + } + if (ret == NULL) { + return NULL; + } + /* Check for trailing data. */ + if (p != ext->value->data + ext->value->length) { + if (method->it) { + ASN1_item_free(ret, ASN1_ITEM_ptr(method->it)); + } else { + method->ext_free(ret); + } + OPENSSL_PUT_ERROR(X509V3, X509V3_R_TRAILING_DATA_IN_EXTENSION); + return NULL; + } + return ret; +} + +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *extensions, int nid, + int *out_critical, int *out_idx) +{ + int lastpos; + size_t i; + X509_EXTENSION *ex, *found_ex = NULL; + if (!extensions) { + if (out_idx) + *out_idx = -1; + if (out_critical) + *out_critical = -1; + return NULL; + } + if (out_idx) + lastpos = *out_idx + 1; + else + lastpos = 0; + if (lastpos < 0) + lastpos = 0; + for (i = lastpos; i < sk_X509_EXTENSION_num(extensions); i++) { + ex = sk_X509_EXTENSION_value(extensions, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (out_idx) { + /* TODO(https://crbug.com/boringssl/379): Consistently reject + * duplicate extensions. */ + *out_idx = i; + found_ex = ex; + break; + } else if (found_ex) { + /* Found more than one */ + if (out_critical) + *out_critical = -2; + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + /* Found it */ + if (out_critical) + *out_critical = X509_EXTENSION_get_critical(found_ex); + return X509V3_EXT_d2i(found_ex); + } + + /* Extension not found */ + if (out_idx) + *out_idx = -1; + if (out_critical) + *out_critical = -1; + return NULL; +} + +/* + * This function is a general extension append, replace and delete utility. + * The precise operation is governed by the 'flags' value. The 'crit' and + * 'value' arguments (if relevant) are the extensions internal structure. + */ + +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags) +{ + int errcode, extidx = -1; + X509_EXTENSION *ext = NULL, *extmp; + STACK_OF(X509_EXTENSION) *ret = NULL; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + + /* + * If appending we don't care if it exists, otherwise look for existing + * extension. + */ + if (ext_op != X509V3_ADD_APPEND) + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + + /* See if extension exists */ + if (extidx >= 0) { + /* If keep existing, nothing to do */ + if (ext_op == X509V3_ADD_KEEP_EXISTING) + return 1; + /* If default then its an error */ + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { + if (!sk_X509_EXTENSION_delete(*x, extidx)) + return -1; + return 1; + } + } else { + /* + * If replace existing or delete, error since extension must exist + */ + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } + + /* + * If we get this far then we have to create an extension: could have + * some flags for alternative encoding schemes... + */ + + ext = X509V3_EXT_i2d(nid, crit, value); + + if (!ext) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION); + return 0; + } + + /* If extension exists replace it.. */ + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) + return -1; + return 1; + } + + if ((ret = *x) == NULL + && (ret = sk_X509_EXTENSION_new_null()) == NULL) + goto m_fail; + if (!sk_X509_EXTENSION_push(ret, ext)) + goto m_fail; + + *x = ret; + return 1; + + m_fail: + if (ret != *x) + sk_X509_EXTENSION_free(ret); + X509_EXTENSION_free(ext); + return -1; + + err: + if (!(flags & X509V3_ADD_SILENT)) + OPENSSL_PUT_ERROR(X509V3, errcode); + return 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c new file mode 100644 index 00000000..572a6020 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c @@ -0,0 +1,559 @@ +/* v3_ncons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509/internal.h" + + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, + int ind, const char *name); +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + +const X509V3_EXT_METHOD v3_name_constraints = { + NID_name_constraints, 0, + ASN1_ITEM_ref(NAME_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + 0, v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, 0, + NULL +}; + +ASN1_SEQUENCE(GENERAL_SUBTREE) = { + ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), + ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), + ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(GENERAL_SUBTREE) + +ASN1_SEQUENCE(NAME_CONSTRAINTS) = { + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, + GENERAL_SUBTREE, 0), + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, + GENERAL_SUBTREE, 1), +} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) + + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + size_t i; + CONF_VALUE tval, *val; + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) + goto memerr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + goto err; + if (!*ptree) + *ptree = sk_GENERAL_SUBTREE_new_null(); + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) + goto memerr; + sub = NULL; + } + + return ncons; + + memerr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + err: + if (ncons) + NAME_CONSTRAINTS_free(ncons); + if (sub) + GENERAL_SUBTREE_free(sub); + + return NULL; +} + +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind) +{ + NAME_CONSTRAINTS *ncons = a; + do_i2r_name_constraints(method, ncons->permittedSubtrees, + bp, ind, "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, + bp, ind, "Excluded"); + return 1; +} + +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, + BIO *bp, int ind, const char *name) +{ + GENERAL_SUBTREE *tree; + size_t i; + if (sk_GENERAL_SUBTREE_num(trees) > 0) + BIO_printf(bp, "%*s%s:\n", ind, "", name); + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) + print_nc_ipadd(bp, tree->base->d.ip); + else + GENERAL_NAME_print(bp, tree->base); + BIO_puts(bp, "\n"); + } + return 1; +} + +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) +{ + int i, len; + unsigned char *p; + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_printf(bp, "%X", v); + p += 2; + if (i == 7) + BIO_puts(bp, "/"); + else if (i != 15) + BIO_puts(bp, ":"); + } + } else + BIO_printf(bp, "IP Address:"); + return 1; +} + +/*- + * Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSPECIFIED: Unspecified error. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: Bad or unsupported constraint + * syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: Bad or unsupported syntax of name. + */ + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) +{ + int r, i; + size_t j; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + /* Guard against certificates with an excessive number of names or + * constraints causing a computationally expensive name constraints + * check. */ + size_t name_count = + X509_NAME_entry_count(nm) + sk_GENERAL_NAME_num(x->altname); + size_t constraint_count = sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) + + sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); + size_t check_count = constraint_count * name_count; + if (name_count < (size_t)X509_NAME_entry_count(nm) || + constraint_count < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) || + (constraint_count && check_count / constraint_count != name_count) || + check_count > 1 << 20) { + return X509_V_ERR_UNSPECIFIED; + } + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + /* Process any email address attributes in subject name */ + + for (i = -1;;) { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + + return X509_V_OK; + +} + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) +{ + GENERAL_SUBTREE *sub; + int r, match = 0; + size_t i; + + /* + * Permitted subtrees: if any subtrees exist of matching the type at + * least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; + +} + +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +{ + switch (base->type) { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } + +} + +/* + * directoryName name constraint matching. The canonical encoding of + * X509_NAME makes this comparison easy. It is matched if the subtree is a + * subset of the name. + */ + +static int nc_dn(X509_NAME *nm, X509_NAME *base) +{ + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (OPENSSL_memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; +} + +static int starts_with(const CBS *cbs, uint8_t c) +{ + return CBS_len(cbs) > 0 && CBS_data(cbs)[0] == c; +} + +static int equal_case(const CBS *a, const CBS *b) +{ + if (CBS_len(a) != CBS_len(b)) { + return 0; + } + /* Note we cannot use |OPENSSL_strncasecmp| because that would stop + * iterating at NUL. */ + const uint8_t *a_data = CBS_data(a), *b_data = CBS_data(b); + for (size_t i = 0; i < CBS_len(a); i++) { + if (OPENSSL_tolower(a_data[i]) != OPENSSL_tolower(b_data[i])) { + return 0; + } + } + return 1; +} + +static int has_suffix_case(const CBS *a, const CBS *b) +{ + if (CBS_len(a) < CBS_len(b)) { + return 0; + } + CBS copy = *a; + CBS_skip(©, CBS_len(a) - CBS_len(b)); + return equal_case(©, b); +} + +static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) +{ + CBS dns_cbs, base_cbs; + CBS_init(&dns_cbs, dns->data, dns->length); + CBS_init(&base_cbs, base->data, base->length); + + /* Empty matches everything */ + if (CBS_len(&base_cbs) == 0) { + return X509_V_OK; + } + + /* If |base_cbs| begins with a '.', do a simple suffix comparison. This is + * not part of RFC5280, but is part of OpenSSL's original behavior. */ + if (starts_with(&base_cbs, '.')) { + if (has_suffix_case(&dns_cbs, &base_cbs)) { + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* + * Otherwise can add zero or more components on the left so compare RHS + * and if dns is longer and expect '.' as preceding character. + */ + if (CBS_len(&dns_cbs) > CBS_len(&base_cbs)) { + uint8_t dot; + if (!CBS_skip(&dns_cbs, CBS_len(&dns_cbs) - CBS_len(&base_cbs) - 1) || + !CBS_get_u8(&dns_cbs, &dot) || + dot != '.') { + return X509_V_ERR_PERMITTED_VIOLATION; + } + } + + if (!equal_case(&dns_cbs, &base_cbs)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + + return X509_V_OK; + +} + +static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) +{ + CBS eml_cbs, base_cbs; + CBS_init(&eml_cbs, eml->data, eml->length); + CBS_init(&base_cbs, base->data, base->length); + + /* TODO(davidben): In OpenSSL 1.1.1, this switched from the first '@' to the + * last one. Match them here, or perhaps do an actual parse. Looks like + * multiple '@'s may be allowed in quoted strings. */ + CBS eml_local, base_local; + if (!CBS_get_until_first(&eml_cbs, &eml_local, '@')) { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + int base_has_at = CBS_get_until_first(&base_cbs, &base_local, '@'); + + /* Special case: inital '.' is RHS match */ + if (!base_has_at && starts_with(&base_cbs, '.')) { + if (has_suffix_case(&eml_cbs, &base_cbs)) { + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + if (base_has_at) { + /* TODO(davidben): This interprets a constraint of "@example.com" as + * "example.com", which is not part of RFC5280. */ + if (CBS_len(&base_local) > 0) { + /* Case sensitive match of local part */ + if (!CBS_mem_equal(&base_local, CBS_data(&eml_local), + CBS_len(&eml_local))) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + } + /* Position base after '@' */ + assert(starts_with(&base_cbs, '@')); + CBS_skip(&base_cbs, 1); + } + + /* Just have hostname left to match: case insensitive */ + assert(starts_with(&eml_cbs, '@')); + CBS_skip(&eml_cbs, 1); + if (!equal_case(&base_cbs, &eml_cbs)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + + return X509_V_OK; +} + +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) +{ + CBS uri_cbs, base_cbs; + CBS_init(&uri_cbs, uri->data, uri->length); + CBS_init(&base_cbs, base->data, base->length); + + /* Check for foo:// and skip past it */ + CBS scheme; + uint8_t byte; + if (!CBS_get_until_first(&uri_cbs, &scheme, ':') || + !CBS_skip(&uri_cbs, 1) || // Skip the colon + !CBS_get_u8(&uri_cbs, &byte) || byte != '/' || + !CBS_get_u8(&uri_cbs, &byte) || byte != '/') { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + + /* Look for a port indicator as end of hostname first. Otherwise look for + * trailing slash, or the end of the string. + * TODO(davidben): This is not a correct URI parser and mishandles IPv6 + * literals. */ + CBS host; + if (!CBS_get_until_first(&uri_cbs, &host, ':') && + !CBS_get_until_first(&uri_cbs, &host, '/')) { + host = uri_cbs; + } + + if (CBS_len(&host) == 0) { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + + /* Special case: inital '.' is RHS match */ + if (starts_with(&base_cbs, '.')) { + if (has_suffix_case(&host, &base_cbs)) { + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (!equal_case(&base_cbs, &host)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + + return X509_V_OK; + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c new file mode 100644 index 00000000..908f9656 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include +#include +#include + +/* + * OCSP extensions and a couple of CRL entry extensions + */ + +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +const X509V3_EXT_METHOD v3_crl_invdate = { + NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_acutoff, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_nocheck = { + NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + 0, s2i_ocsp_nocheck, + 0, 0, + i2r_ocsp_nocheck, 0, + NULL +}; + +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, + BIO *bp, int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) + return 0; + return 1; +} + +/* Nocheck is just a single NULL. Don't print anything and always set it */ + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, + BIO *out, int indent) +{ + return 1; +} + +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c new file mode 100644 index 00000000..4498b212 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c @@ -0,0 +1,289 @@ +/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, + BIO *out, int indent); +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_pci = + { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), + 0, 0, 0, 0, + 0, 0, + NULL, NULL, + (X509V3_EXT_I2R)i2r_pci, + (X509V3_EXT_R2I)r2i_pci, + NULL, +}; + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, + BIO *out, int indent) +{ + BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); + if (pci->pcPathLengthConstraint) + i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); + else + BIO_printf(out, "infinite"); + BIO_puts(out, "\n"); + BIO_printf(out, "%*sPolicy Language: ", indent, ""); + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) + BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "", + pci->proxyPolicy->policy->length, + pci->proxyPolicy->policy->data); + return 1; +} + +static int process_pci_value(CONF_VALUE *val, + ASN1_OBJECT **language, ASN1_INTEGER **pathlen, + ASN1_OCTET_STRING **policy) +{ + int free_policy = 0; + + if (strcmp(val->name, "language") == 0) { + if (*language) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "policy") == 0) { + unsigned char *tmp_data = NULL; + long val_len; + if (!*policy) { + *policy = ASN1_OCTET_STRING_new(); + if (!*policy) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + return 0; + } + free_policy = 1; + } + if (strncmp(val->value, "hex:", 4) == 0) { + unsigned char *tmp_data2 = + x509v3_hex_to_bytes(val->value + 4, &val_len); + + if (!tmp_data2) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT); + X509V3_conf_err(val); + goto err; + } + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + OPENSSL_memcpy(&(*policy)->data[(*policy)->length], + tmp_data2, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + OPENSSL_free(tmp_data2); + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); + } else if (strncmp(val->value, "text:", 5) == 0) { + val_len = strlen(val->value + 5); + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + OPENSSL_memcpy(&(*policy)->data[(*policy)->length], + val->value + 5, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } + return 1; + err: + if (free_policy) { + ASN1_OCTET_STRING_free(*policy); + *policy = NULL; + } + return 0; +} + +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + PROXY_CERT_INFO_EXTENSION *pci = NULL; + STACK_OF(CONF_VALUE) *vals; + ASN1_OBJECT *language = NULL; + ASN1_INTEGER *pathlen = NULL; + ASN1_OCTET_STRING *policy = NULL; + size_t i, j; + int nid; + + vals = X509V3_parse_list(value); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING); + X509V3_conf_err(cnf); + goto err; + } + if (*cnf->name == '@') { + STACK_OF(CONF_VALUE) *sect; + int success_p = 1; + + sect = X509V3_get_section(ctx, cnf->name + 1); + if (!sect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { + success_p = + process_pci_value(sk_CONF_VALUE_value(sect, j), + &language, &pathlen, &policy); + } + X509V3_section_free(ctx, sect); + if (!success_p) + goto err; + } else { + if (!process_pci_value(cnf, &language, &pathlen, &policy)) { + X509V3_conf_err(cnf); + goto err; + } + } + } + + /* Language is mandatory */ + if (!language) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + nid = OBJ_obj2nid(language); + if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + + pci->proxyPolicy->policyLanguage = language; + language = NULL; + pci->proxyPolicy->policy = policy; + policy = NULL; + pci->pcPathLengthConstraint = pathlen; + pathlen = NULL; + goto end; + err: + if (language) { + ASN1_OBJECT_free(language); + language = NULL; + } + if (pathlen) { + ASN1_INTEGER_free(pathlen); + pathlen = NULL; + } + if (policy) { + ASN1_OCTET_STRING_free(policy); + policy = NULL; + } + if (pci) { + PROXY_CERT_INFO_EXTENSION_free(pci); + pci = NULL; + } + end: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pci; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c new file mode 100644 index 00000000..f6b4fd83 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c @@ -0,0 +1,57 @@ +/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + + +ASN1_SEQUENCE(PROXY_POLICY) = + { + ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), + ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(PROXY_POLICY) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) + +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = + { + ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), + ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) +} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c new file mode 100644 index 00000000..15b1413c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c @@ -0,0 +1,139 @@ +/* v3_pcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *bcons, STACK_OF(CONF_VALUE) + *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_policy_constraints = { + NID_policy_constraints, 0, + ASN1_ITEM_ref(POLICY_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_CONSTRAINTS, + v2i_POLICY_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { + ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), + ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) +} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *extlist) +{ + POLICY_CONSTRAINTS *pcons = a; + X509V3_add_value_int("Require Explicit Policy", + pcons->requireExplicitPolicy, &extlist); + X509V3_add_value_int("Inhibit Policy Mapping", + pcons->inhibitPolicyMapping, &extlist); + return extlist; +} + +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + POLICY_CONSTRAINTS *pcons = NULL; + CONF_VALUE *val; + size_t i; + if (!(pcons = POLICY_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) + goto err; + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) + goto err; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c new file mode 100644 index 00000000..7569e344 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c @@ -0,0 +1,154 @@ +/* v3_pmaps.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include +#include + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *pmps, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_policy_mappings = { + NID_policy_mappings, 0, + ASN1_ITEM_ref(POLICY_MAPPINGS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_MAPPINGS, + v2i_POLICY_MAPPINGS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(POLICY_MAPPING) = { + ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), + ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) +} ASN1_SEQUENCE_END(POLICY_MAPPING) + +ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, + POLICY_MAPPING) +ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + POLICY_MAPPINGS *pmaps = a; + POLICY_MAPPING *pmap; + size_t i; + char obj_tmp1[80]; + char obj_tmp2[80]; + for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + pmap = sk_POLICY_MAPPING_value(pmaps, i); + i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); + i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); + X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); + } + return ext_list; +} + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + POLICY_MAPPINGS *pmaps; + POLICY_MAPPING *pmap; + ASN1_OBJECT *obj1, *obj2; + CONF_VALUE *val; + size_t i; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + obj1 = OBJ_txt2obj(val->name, 0); + obj2 = OBJ_txt2obj(val->value, 0); + if (!obj1 || !obj2) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + pmap = POLICY_MAPPING_new(); + if (!pmap) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + sk_POLICY_MAPPING_push(pmaps, pmap); + } + return pmaps; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c new file mode 100644 index 00000000..0347ab73 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c @@ -0,0 +1,230 @@ +/* v3_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +/* X509 v3 extension utilities */ + +#include + +#include +#include +#include +#include + +/* Extension printing routines */ + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported); + +/* Print out a name+value stack */ + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml) +{ + size_t i; + CONF_VALUE *nval; + if (!val) + return; + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) + BIO_puts(out, "\n"); + } + for (i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) + BIO_printf(out, "%*s", indent, ""); + else if (i > 0) + BIO_printf(out, ", "); + nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + BIO_puts(out, nval->value); + else if (!nval->value) + BIO_puts(out, nval->name); + else + BIO_printf(out, "%s:%s", nval->name, nval->value); + if (ml) + BIO_puts(out, "\n"); + } +} + +/* Main routine: print out a general extension */ + +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent) +{ + void *ext_str = NULL; + char *value = NULL; + const X509V3_EXT_METHOD *method; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 1; + + if (!(method = X509V3_EXT_get(ext))) + return unknown_ext_print(out, ext, flag, indent, 0); + const ASN1_STRING *ext_data = X509_EXTENSION_get_data(ext); + const unsigned char *p = ASN1_STRING_get0_data(ext_data); + if (method->it) { + ext_str = ASN1_item_d2i(NULL, &p, ASN1_STRING_length(ext_data), + ASN1_ITEM_ptr(method->it)); + } else { + ext_str = method->d2i(NULL, &p, ASN1_STRING_length(ext_data)); + } + + if (!ext_str) + return unknown_ext_print(out, ext, flag, indent, 1); + + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + ok = 0; + goto err; + } + BIO_printf(out, "%*s%s", indent, "", value); + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + ok = 0; + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) + ok = 0; + } else + ok = 0; + + err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (value) + OPENSSL_free(value); + if (method->it) + ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_str); + return ok; +} + +int X509V3_extensions_print(BIO *bp, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + size_t i; + int j; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; + + if (title) { + BIO_printf(bp, "%*s%s:\n", indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) + return 0; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) + return 0; + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); + } + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + } + return 1; +} + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported) +{ + switch (flag & X509V3_EXT_UNKNOWN_MASK) { + + case X509V3_EXT_DEFAULT: + return 0; + + case X509V3_EXT_ERROR_UNKNOWN: + if (supported) + BIO_printf(out, "%*s", indent, ""); + else + BIO_printf(out, "%*s", indent, ""); + return 1; + + case X509V3_EXT_PARSE_UNKNOWN: + case X509V3_EXT_DUMP_UNKNOWN: { + const ASN1_STRING *data = X509_EXTENSION_get_data(ext); + return BIO_hexdump(out, ASN1_STRING_get0_data(data), + ASN1_STRING_length(data), indent); + } + + default: + return 1; + } +} + +int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) +{ + BIO *bio_tmp; + int ret; + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) + return 0; + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c new file mode 100644 index 00000000..a4c77c94 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c @@ -0,0 +1,929 @@ +/* v3_purp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509/internal.h" +#include "internal.h" + +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#define xku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) +#define ns_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int purpose_smime(const X509 *x, int ca); +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + +static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b); +static void xptable_free(X509_PURPOSE *p); + +static X509_PURPOSE xstandard[] = { + {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, + check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient", + NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", + NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ns_ssl_server, (char *)"Netscape SSL server", + (char *)"nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, + (char *)"S/MIME signing", (char *)"smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, + check_purpose_smime_encrypt, (char *)"S/MIME encryption", + (char *)"smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, + (char *)"CRL signing", (char *)"crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose", + (char *)"any", NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + (char *)"OCSP helper", (char *)"ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, + check_purpose_timestamp_sign, (char *)"Time Stamp signing", + (char *)"timestampsign", NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b) +{ + return (*a)->purpose - (*b)->purpose; +} + +/* + * As much as I'd like to make X509_check_purpose use a "const" X509* I + * really can't because it does recalculate hashes and do other non-const + * things. + */ +int X509_check_purpose(X509 *x, int id, int ca) +{ + int idx; + const X509_PURPOSE *pt; + if (!x509v3_cache_extensions(x)) { + return -1; + } + + if (id == -1) + return 1; + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) + return -1; + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); +} + +int X509_PURPOSE_set(int *p, int purpose) +{ + if (X509_PURPOSE_get_by_id(purpose) == -1) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} + +int X509_PURPOSE_get_count(void) +{ + if (!xptable) + return X509_PURPOSE_COUNT; + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} + +X509_PURPOSE *X509_PURPOSE_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_PURPOSE_COUNT) + return xstandard + idx; + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} + +int X509_PURPOSE_get_by_sname(char *sname) +{ + int i; + X509_PURPOSE *xptmp; + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) + return i; + } + return -1; +} + +int X509_PURPOSE_get_by_id(int purpose) +{ + X509_PURPOSE tmp; + size_t idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + + sk_X509_PURPOSE_sort(xptable); + if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) + return -1; + return idx + X509_PURPOSE_COUNT; +} + +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg) +{ + int idx; + X509_PURPOSE *ptmp; + char *name_dup, *sname_dup; + + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_PURPOSE_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_PURPOSE_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_PURPOSE_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + /* Duplicate the supplied names. */ + name_dup = OPENSSL_strdup(name); + sname_dup = OPENSSL_strdup(sname); + if (name_dup == NULL || sname_dup == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (name_dup != NULL) + OPENSSL_free(name_dup); + if (sname_dup != NULL) + OPENSSL_free(sname_dup); + if (idx == -1) + OPENSSL_free(ptmp); + return 0; + } + + /* OPENSSL_free existing name if dynamic */ + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(ptmp->name); + OPENSSL_free(ptmp->sname); + } + /* dup supplied name */ + ptmp->name = name_dup; + ptmp->sname = sname_dup; + /* Keep the dynamic flag of existing entry */ + ptmp->flags &= X509_PURPOSE_DYNAMIC; + /* Set all other flags */ + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + return 0; + } + } + return 1; +} + +static void xptable_free(X509_PURPOSE *p) +{ + if (!p) + return; + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(p->name); + OPENSSL_free(p->sname); + } + OPENSSL_free(p); + } +} + +void X509_PURPOSE_cleanup(void) +{ + unsigned int i; + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + for (i = 0; i < X509_PURPOSE_COUNT; i++) + xptable_free(xstandard + i); + xptable = NULL; +} + +int X509_PURPOSE_get_id(const X509_PURPOSE *xp) +{ + return xp->purpose; +} + +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp) +{ + return xp->name; +} + +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) +{ + return xp->sname; +} + +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) +{ + return xp->trust; +} + +static int nid_cmp(const void *void_a, const void *void_b) +{ + const int *a = void_a, *b = void_b; + + return *a - *b; +} + +int X509_supported_extension(X509_EXTENSION *ex) +{ + /* + * This table is a list of the NIDs of supported extensions: that is + * those which are used by the verify process. If an extension is + * critical and doesn't appear in this list then the verify process will + * normally reject the certificate. The list must be kept in numerical + * order because it will be searched using bsearch. + */ + + static const int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_certificate_policies, /* 89 */ + NID_ext_key_usage, /* 126 */ + NID_policy_constraints, /* 401 */ + NID_proxyCertInfo, /* 663 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ + NID_inhibit_any_policy /* 748 */ + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (bsearch + (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int), + sizeof(int), nid_cmp) != NULL) + return 1; + return 0; +} + +static int setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + size_t i; + if (dp->reasons) { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return 1; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + return DIST_POINT_set_dpname(dp->distpoint, iname); +} + +static int setup_crldp(X509 *x) +{ + int j; + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &j, NULL); + if (x->crldp == NULL && j != -1) { + return 0; + } + for (size_t i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) { + return 0; + } + } + return 1; +} + +int x509v3_cache_extensions(X509 *x) +{ + BASIC_CONSTRAINTS *bs; + PROXY_CERT_INFO_EXTENSION *pci; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; + size_t i; + int j; + + CRYPTO_MUTEX_lock_read(&x->lock); + const int is_set = x->ex_flags & EXFLAG_SET; + CRYPTO_MUTEX_unlock_read(&x->lock); + + if (is_set) { + return (x->ex_flags & EXFLAG_INVALID) == 0; + } + + CRYPTO_MUTEX_lock_write(&x->lock); + if (x->ex_flags & EXFLAG_SET) { + CRYPTO_MUTEX_unlock_write(&x->lock); + return (x->ex_flags & EXFLAG_INVALID) == 0; + } + + if (!X509_digest(x, EVP_sha256(), x->cert_hash, NULL)) + x->ex_flags |= EXFLAG_INVALID; + /* V1 should mean no extensions ... */ + if (X509_get_version(x) == X509_VERSION_1) + x->ex_flags |= EXFLAG_V1; + /* Handle basic constraints */ + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &j, NULL))) { + if (bs->ca) + x->ex_flags |= EXFLAG_CA; + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) + || !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else { + /* TODO(davidben): |ASN1_INTEGER_get| returns -1 on overflow, + * which currently acts as if the constraint isn't present. This + * works (an overflowing path length constraint may as well be + * infinity), but Chromium's verifier simply treats values above + * 255 as an error. */ + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } + } else + x->ex_pathlen = -1; + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + /* Handle proxy certificates */ + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &j, NULL))) { + if (x->ex_flags & EXFLAG_CA + || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 + || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { + x->ex_flags |= EXFLAG_INVALID; + } + if (pci->pcPathLengthConstraint) { + x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); + } else + x->ex_pcpathlen = -1; + PROXY_CERT_INFO_EXTENSION_free(pci); + x->ex_flags |= EXFLAG_PROXY; + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + /* Handle key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, &j, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) + x->ex_kusage |= usage->data[1] << 8; + } else + x->ex_kusage = 0; + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &j, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + + case NID_anyExtendedKeyUsage: + x->ex_xkusage |= XKU_ANYEKU; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &j, NULL))) { + if (ns->length > 0) + x->ex_nscert = ns->data[0]; + else + x->ex_nscert = 0; + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &j, NULL); + if (x->skid == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &j, NULL); + if (x->akid == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + /* Does subject name match issuer ? */ + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { + x->ex_flags |= EXFLAG_SI; + /* If SKID matches AKID also indicate self signed */ + if (X509_check_akid(x, x->akid) == X509_V_OK && + !ku_reject(x, KU_KEY_CERT_SIGN)) + x->ex_flags |= EXFLAG_SS; + } + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &j, NULL); + if (x->altname == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL); + if (x->nc == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + if (!setup_crldp(x)) { + x->ex_flags |= EXFLAG_INVALID; + } + + for (j = 0; j < X509_get_ext_count(x); j++) { + ex = X509_get_ext(x, j); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) + == NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + x->ex_flags |= EXFLAG_SET; + + CRYPTO_MUTEX_unlock_write(&x->lock); + return (x->ex_flags & EXFLAG_INVALID) == 0; +} + +/* check_ca returns one if |x| should be considered a CA certificate and zero + * otherwise. */ +static int check_ca(const X509 *x) +{ + /* keyUsage if present should allow cert signing */ + if (ku_reject(x, KU_KEY_CERT_SIGN)) + return 0; + /* Version 1 certificates are considered CAs and don't have extensions. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) { + return 1; + } + /* Otherwise, it's only a CA if basicConstraints says so. */ + return ((x->ex_flags & EXFLAG_BCONS) && + (x->ex_flags & EXFLAG_CA)); +} + +int X509_check_ca(X509 *x) +{ + if (!x509v3_cache_extensions(x)) { + return 0; + } + return check_ca(x); +} + +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_CLIENT)) + return 0; + if (ca) + return check_ca(x); + /* We need to do digital signatures or key agreement */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) + return 0; + /* nsCertType if present should allow SSL client use */ + if (ns_reject(x, NS_SSL_CLIENT)) + return 0; + return 1; +} + +/* + * Key usage needed for TLS/SSL server: digital signature, encipherment or + * key agreement. The ssl code can check this more thoroughly for individual + * key types. + */ +#define KU_TLS \ + (KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT) + +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_SERVER)) + return 0; + if (ca) + return check_ca(x); + + if (ns_reject(x, NS_SSL_SERVER)) + return 0; + if (ku_reject(x, KU_TLS)) + return 0; + + return 1; + +} + +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) + return ret; + /* We need to encipher or Netscape complains */ + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +/* purpose_smime returns one if |x| is a valid S/MIME leaf (|ca| is zero) or CA + * (|ca| is one) certificate, and zero otherwise. */ +static int purpose_smime(const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SMIME)) + return 0; + if (ca) { + /* check nsCertType if present */ + if ((x->ex_flags & EXFLAG_NSCERT) && + (x->ex_nscert & NS_SMIME_CA) == 0) { + return 0; + } + + return check_ca(x); + } + if (x->ex_flags & EXFLAG_NSCERT) { + return (x->ex_nscert & NS_SMIME) == NS_SMIME; + } + return 1; +} + +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) + return 0; + return ret; +} + +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (ca) { + return check_ca(x); + } + if (ku_reject(x, KU_CRL_SIGN)) + return 0; + return 1; +} + +/* + * OCSP helper: this is *not* a full OCSP check. It just checks that each CA + * is valid. Additional checks must be made on the chain. + */ + +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (ca) + return check_ca(x); + /* leaf certificate is checked in OCSP_verify() */ + return 1; +} + +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) + return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) + && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + return 1; +} + +/* + * Various checks to see if one certificate issued the second. This can be + * used to prune a set of possible issuer certificates which have been looked + * up using some simple method such as by subject name. These are: 1. Check + * issuer_name(subject) == subject_name(issuer) 2. If akid(subject) exists + * check it matches issuer 3. If key_usage(issuer) exists check it supports + * certificate signing returns 0 for OK, positive for reason for mismatch, + * reasons match codes for X509_verify_cert() + */ + +int X509_check_issued(X509 *issuer, X509 *subject) +{ + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + if (!x509v3_cache_extensions(issuer) || + !x509v3_cache_extensions(subject)) { + return X509_V_ERR_UNSPECIFIED; + } + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; + } + + if (subject->ex_flags & EXFLAG_PROXY) { + if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} + +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +{ + + if (!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if (akid->issuer) { + /* + * Ugh, for some peculiar reason AKID includes SEQUENCE OF + * GeneralName. So look for a DirName. There may be more than one but + * we only take any notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + size_t i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } + } + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; +} + +uint32_t X509_get_extension_flags(X509 *x) +{ + /* Ignore the return value. On failure, |x->ex_flags| will include + * |EXFLAG_INVALID|. */ + x509v3_cache_extensions(x); + return x->ex_flags; +} + +uint32_t X509_get_key_usage(X509 *x) +{ + if (!x509v3_cache_extensions(x)) { + return 0; + } + if (x->ex_flags & EXFLAG_KUSAGE) + return x->ex_kusage; + return UINT32_MAX; +} + +uint32_t X509_get_extended_key_usage(X509 *x) +{ + if (!x509v3_cache_extensions(x)) { + return 0; + } + if (x->ex_flags & EXFLAG_XKUSAGE) + return x->ex_xkusage; + return UINT32_MAX; +} + +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509) +{ + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->skid; +} + +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509) +{ + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->keyid : NULL; +} + +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509) +{ + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->issuer : NULL; +} + +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509) +{ + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->serial : NULL; +} + +long X509_get_pathlen(X509 *x509) +{ + if (!x509v3_cache_extensions(x509) || + (x509->ex_flags & EXFLAG_BCONS) == 0) { + return -1; + } + return x509->ex_pathlen; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c new file mode 100644 index 00000000..24a1723c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c @@ -0,0 +1,156 @@ +/* v3_skey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include +#include + +#include +#include +#include +#include + +#include "../x509/internal.h" +#include "internal.h" + + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_skey_id = { + NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + (X509V3_EXT_S2I)s2i_skey_id, + 0, 0, 0, 0, + NULL +}; + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct) +{ + return x509v3_bytes_to_hex(oct->data, oct->length); +} + +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + ASN1_OCTET_STRING *oct; + long length; + + if (!(oct = ASN1_OCTET_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(oct->data = x509v3_hex_to_bytes(str, &length))) { + ASN1_OCTET_STRING_free(oct); + return NULL; + } + + oct->length = length; + + return oct; + +} + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) + return s2i_ASN1_OCTET_STRING(method, ctx, str); + + if (!(oct = ASN1_OCTET_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) + pk = ctx->subject_req->req_info->pubkey->public_key; + else + pk = ctx->subject_cert->cert_info->key->public_key; + + if (!pk) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest + (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) + goto err; + + if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + + err: + ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c new file mode 100644 index 00000000..b1efa495 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c @@ -0,0 +1,1391 @@ +/* v3_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../conf/internal.h" +#include "../internal.h" +#include "internal.h" + + +static char *strip_spaces(char *name); +static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); + +static int ipv4_from_asc(unsigned char v4[4], const char *in); +static int ipv6_from_asc(unsigned char v6[16], const char *in); +static int ipv6_cb(const char *elem, int len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, int inlen); + +/* Add a CONF_VALUE name value pair to stack */ + +static int x509V3_add_len_value(const char *name, const char *value, + size_t value_len, int omit_value, + STACK_OF(CONF_VALUE) **extlist) +{ + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + int extlist_was_null = *extlist == NULL; + if (name && !(tname = OPENSSL_strdup(name))) + goto malloc_err; + if (!omit_value) { + /* |CONF_VALUE| cannot represent strings with NULs. */ + if (OPENSSL_memchr(value, 0, value_len)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); + goto err; + } + tvalue = OPENSSL_strndup(value, value_len); + if (tvalue == NULL) { + goto malloc_err; + } + } + if (!(vtmp = CONF_VALUE_new())) + goto malloc_err; + if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) + goto malloc_err; + vtmp->section = NULL; + vtmp->name = tname; + vtmp->value = tvalue; + if (!sk_CONF_VALUE_push(*extlist, vtmp)) + goto malloc_err; + return 1; + malloc_err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + err: + if (extlist_was_null) { + sk_CONF_VALUE_free(*extlist); + *extlist = NULL; + } + OPENSSL_free(vtmp); + OPENSSL_free(tname); + OPENSSL_free(tvalue); + return 0; +} + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return x509V3_add_len_value(name, value, value != NULL ? strlen(value) : 0, + /*omit_value=*/value == NULL, extlist); +} + +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return X509V3_add_value(name, (const char *)value, extlist); +} + +int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return x509V3_add_len_value(name, (const char *)value->data, value->length, + /*omit_value=*/0, extlist); +} + +/* Free function for STACK_OF(CONF_VALUE) */ + +void X509V3_conf_free(CONF_VALUE *conf) +{ + if (!conf) + return; + if (conf->name) + OPENSSL_free(conf->name); + if (conf->value) + OPENSSL_free(conf->value); + if (conf->section) + OPENSSL_free(conf->section); + OPENSSL_free(conf); +} + +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return X509V3_add_value(name, "FALSE", extlist); +} + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return 1; +} + +static char *bignum_to_string(const BIGNUM *bn) +{ + char *tmp, *ret; + size_t len; + + /* + * Display large numbers in hex and small numbers in decimal. Converting to + * decimal takes quadratic time and is no more useful than hex for large + * numbers. + */ + if (BN_num_bits(bn) < 32) { + return BN_bn2dec(bn); + } + + tmp = BN_bn2hex(bn); + if (tmp == NULL) { + return NULL; + } + + len = strlen(tmp) + 3; + ret = OPENSSL_malloc(len); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + OPENSSL_free(tmp); + return NULL; + } + + /* Prepend "0x", but place it after the "-" if negative. */ + if (tmp[0] == '-') { + OPENSSL_strlcpy(ret, "-0x", len); + OPENSSL_strlcat(ret, tmp + 1, len); + } else { + OPENSSL_strlcpy(ret, "0x", len); + OPENSSL_strlcat(ret, tmp, len); + } + OPENSSL_free(tmp); + return ret; +} + +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || + !(strtmp = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || + !(strtmp = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) +{ + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg, ishex; + int ret; + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + return 0; + } + bn = BN_new(); + if (value[0] == '-') { + value++; + isneg = 1; + } else + isneg = 0; + + if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { + value += 2; + ishex = 1; + } else + ishex = 0; + + if (ishex) + ret = BN_hex2bn(&bn, value); + else + ret = BN_dec2bn(&bn, value); + + if (!ret || value[ret]) { + BN_free(bn); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR); + return 0; + } + + if (isneg && BN_is_zero(bn)) + isneg = 0; + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return 0; + } + if (isneg) + aint->type |= V_ASN1_NEG; + return aint; +} + +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist) +{ + char *strtmp; + int ret; + if (!aint) + return 1; + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) + return 0; + ret = X509V3_add_value(name, strtmp, extlist); + OPENSSL_free(strtmp); + return ret; +} + +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) +{ + char *btmp; + if (!(btmp = value->value)) + goto err; + if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") + || !strcmp(btmp, "Y") || !strcmp(btmp, "y") + || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { + *asn1_bool = 0xff; + return 1; + } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") + || !strcmp(btmp, "N") || !strcmp(btmp, "n") + || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { + *asn1_bool = 0; + return 1; + } + err: + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_err(value); + return 0; +} + +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) +{ + ASN1_INTEGER *itmp; + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { + X509V3_conf_err(value); + return 0; + } + *aint = itmp; + return 1; +} + +#define HDR_NAME 1 +#define HDR_VALUE 2 + +/* + * #define DEBUG + */ + +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) +{ + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + /* We are going to modify the line so copy it first */ + linebuf = OPENSSL_strdup(line); + if (linebuf == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + state = HDR_NAME; + ntmp = NULL; + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); + p++) { + + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; + + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!vtmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; + } + + } + } + + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); +#if 0 + printf("%s=%s\n", ntmp, vtmp); +#endif + if (!vtmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + OPENSSL_free(linebuf); + return values; + + err: + OPENSSL_free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; + +} + +/* Delete leading and trailing spaces from a string */ +static char *strip_spaces(char *name) +{ + char *p, *q; + /* Skip over leading spaces */ + p = name; + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) + return NULL; + q = p + strlen(p) - 1; + while ((q != p) && isspace((unsigned char)*q)) + q--; + if (p != q) + q[1] = 0; + if (!*p) + return NULL; + return p; +} + +/* hex string utilities */ + +char *x509v3_bytes_to_hex(const uint8_t *in, size_t len) +{ + CBB cbb; + if (!CBB_init(&cbb, len * 3 + 1)) { + goto err; + } + for (size_t i = 0; i < len; i++) { + static const char hex[] = "0123456789ABCDEF"; + if ((i > 0 && !CBB_add_u8(&cbb, ':')) || + !CBB_add_u8(&cbb, hex[in[i] >> 4]) || + !CBB_add_u8(&cbb, hex[in[i] & 0xf])) { + goto err; + } + } + uint8_t *ret; + size_t unused_len; + if (!CBB_add_u8(&cbb, 0) || + !CBB_finish(&cbb, &ret, &unused_len)) { + goto err; + } + + return (char *)ret; + +err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + CBB_cleanup(&cbb); + return NULL; +} + +unsigned char *x509v3_hex_to_bytes(const char *str, long *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl, *p; + if (!str) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) + goto err; + for (p = (unsigned char *)str, q = hexbuf; *p;) { + ch = *p++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + else if ((ch >= 'A') && (ch <= 'F')) + ch -= 'A' - 10; + else + goto badhex; + + if ((cl >= '0') && (cl <= '9')) + cl -= '0'; + else if ((cl >= 'a') && (cl <= 'f')) + cl -= 'a' - 10; + else if ((cl >= 'A') && (cl <= 'F')) + cl -= 'A' - 10; + else + goto badhex; + + *q++ = (ch << 4) | cl; + } + + if (len) + *len = q - hexbuf; + + return hexbuf; + + err: + if (hexbuf) + OPENSSL_free(hexbuf); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + + badhex: + OPENSSL_free(hexbuf); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT); + return NULL; + +} + +int x509v3_name_cmp(const char *name, const char *cmp) +{ + int len, ret; + char c; + len = strlen(cmp); + if ((ret = strncmp(name, cmp, len))) + return ret; + c = name[len]; + if (!c || (c == '.')) + return 0; + return 1; +} + +static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) +{ + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) +{ + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + size_t i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) + return NULL; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5 + (&ret, ad->location->d.uniformResourceIdentifier)) + break; + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) +{ + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} + +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens) +{ + STACK_OF(OPENSSL_STRING) *ret = NULL; + X509_NAME_ENTRY *ne; + ASN1_IA5STRING *email; + GENERAL_NAME *gen; + int i; + size_t j; + /* Now add any email address(es) to STACK */ + i = -1; + /* First supplied X509_NAME */ + while ((i = X509_NAME_get_index_by_NID(name, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(name, i); + email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) + return NULL; + } + for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { + gen = sk_GENERAL_NAME_value(gens, j); + if (gen->type != GEN_EMAIL) + continue; + if (!append_ia5(&ret, gen->d.ia5)) + return NULL; + } + return ret; +} + +static void str_free(OPENSSL_STRING str) +{ + OPENSSL_free(str); +} + +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) +{ + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; + if (email->data == NULL || email->length == 0) + return 1; + /* |OPENSSL_STRING| cannot represent strings with embedded NULs. Do not + * report them as outputs. */ + if (OPENSSL_memchr(email->data, 0, email->length) != NULL) + return 1; + + char *emtmp = NULL; + if (!*sk) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (!*sk) + goto err; + + emtmp = OPENSSL_strndup((char *)email->data, email->length); + if (emtmp == NULL) { + goto err; + } + + /* Don't add duplicates */ + sk_OPENSSL_STRING_sort(*sk); + if (sk_OPENSSL_STRING_find(*sk, NULL, emtmp)) { + OPENSSL_free(emtmp); + return 1; + } + if (!sk_OPENSSL_STRING_push(*sk, emtmp)) { + goto err; + } + return 1; + +err: + /* TODO(davidben): Fix the error-handling in this file. It currently relies + * on |append_ia5| leaving |*sk| at NULL on error. */ + OPENSSL_free(emtmp); + X509_email_free(*sk); + *sk = NULL; + return 0; +} + +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) +{ + sk_OPENSSL_STRING_pop_free(sk, str_free); +} + +typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags); + +/* Compare while ASCII ignoring case. */ +static int equal_nocase(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + if (pattern_len != subject_len) + return 0; + while (pattern_len) { + unsigned char l = *pattern; + unsigned char r = *subject; + /* The pattern must not contain NUL characters. */ + if (l == 0) + return 0; + if (l != r) { + if ('A' <= l && l <= 'Z') + l = (l - 'A') + 'a'; + if ('A' <= r && r <= 'Z') + r = (r - 'A') + 'a'; + if (l != r) + return 0; + } + ++pattern; + ++subject; + --pattern_len; + } + return 1; +} + +/* Compare using OPENSSL_memcmp. */ +static int equal_case(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + if (pattern_len != subject_len) + return 0; + return !OPENSSL_memcmp(pattern, subject, pattern_len); +} + +/* + * RFC 5280, section 7.5, requires that only the domain is compared in a + * case-insensitive manner. + */ +static int equal_email(const unsigned char *a, size_t a_len, + const unsigned char *b, size_t b_len, + unsigned int unused_flags) +{ + size_t i = a_len; + if (a_len != b_len) + return 0; + /* + * We search backwards for the '@' character, so that we do not have to + * deal with quoted local-parts. The domain part is compared in a + * case-insensitive manner. + */ + while (i > 0) { + --i; + if (a[i] == '@' || b[i] == '@') { + if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) + return 0; + break; + } + } + if (i == 0) + i = a_len; + return equal_case(a, i, b, i, 0); +} + +/* + * Compare the prefix and suffix with the subject, and check that the + * characters in-between are valid. + */ +static int wildcard_match(const unsigned char *prefix, size_t prefix_len, + const unsigned char *suffix, size_t suffix_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + const unsigned char *wildcard_start; + const unsigned char *wildcard_end; + const unsigned char *p; + int allow_idna = 0; + + if (subject_len < prefix_len + suffix_len) + return 0; + if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) + return 0; + wildcard_start = subject + prefix_len; + wildcard_end = subject + (subject_len - suffix_len); + if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) + return 0; + /* + * If the wildcard makes up the entire first label, it must match at + * least one character. + */ + if (prefix_len == 0 && *suffix == '.') { + if (wildcard_start == wildcard_end) + return 0; + allow_idna = 1; + } + /* IDNA labels cannot match partial wildcards */ + if (!allow_idna && + subject_len >= 4 + && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0) + return 0; + /* The wildcard may match a literal '*' */ + if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') + return 1; + /* + * Check that the part matched by the wildcard contains only + * permitted characters and only matches a single label. + */ + for (p = wildcard_start; p != wildcard_end; ++p) + if (!(('0' <= *p && *p <= '9') || + ('A' <= *p && *p <= 'Z') || + ('a' <= *p && *p <= 'z') || + *p == '-')) + return 0; + return 1; +} + +#define LABEL_START (1 << 0) +#define LABEL_END (1 << 1) +#define LABEL_HYPHEN (1 << 2) +#define LABEL_IDNA (1 << 3) + +static const unsigned char *valid_star(const unsigned char *p, size_t len, + unsigned int flags) +{ + const unsigned char *star = 0; + size_t i; + int state = LABEL_START; + int dots = 0; + for (i = 0; i < len; ++i) { + /* + * Locate first and only legal wildcard, either at the start + * or end of a non-IDNA first and not final label. + */ + if (p[i] == '*') { + int atstart = (state & LABEL_START); + int atend = (i == len - 1 || p[i + 1] == '.'); + /* + * At most one wildcard per pattern. + * No wildcards in IDNA labels. + * No wildcards after the first label. + */ + if (star != NULL || (state & LABEL_IDNA) != 0 || dots) + return NULL; + /* Only full-label '*.example.com' wildcards. */ + if (!atstart || !atend) + return NULL; + star = &p[i]; + state &= ~LABEL_START; + } else if (('a' <= p[i] && p[i] <= 'z') + || ('A' <= p[i] && p[i] <= 'Z') + || ('0' <= p[i] && p[i] <= '9')) { + if ((state & LABEL_START) != 0 + && len - i >= 4 + && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) + state |= LABEL_IDNA; + state &= ~(LABEL_HYPHEN | LABEL_START); + } else if (p[i] == '.') { + if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) + return NULL; + state = LABEL_START; + ++dots; + } else if (p[i] == '-') { + /* no domain/subdomain starts with '-' */ + if ((state & LABEL_START) != 0) + return NULL; + state |= LABEL_HYPHEN; + } else + return NULL; + } + + /* + * The final label must not end in a hyphen or ".", and + * there must be at least two dots after the star. + */ + if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) + return NULL; + return star; +} + +/* Compare using wildcards. */ +static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + const unsigned char *star = NULL; + + /* + * Subject names starting with '.' can only match a wildcard pattern + * via a subject sub-domain pattern suffix match. + */ + if (!(subject_len > 1 && subject[0] == '.')) + star = valid_star(pattern, pattern_len, flags); + if (star == NULL) + return equal_nocase(pattern, pattern_len, + subject, subject_len, flags); + return wildcard_match(pattern, star - pattern, + star + 1, (pattern + pattern_len) - star - 1, + subject, subject_len, flags); +} + +int x509v3_looks_like_dns_name(const unsigned char *in, size_t len) { + /* This function is used as a heuristic for whether a common name is a + * hostname to be matched, or merely a decorative name to describe the + * subject. This heuristic must be applied to both name constraints and the + * common name fallback, so it must be loose enough to accept hostname + * common names, and tight enough to reject decorative common names. */ + + if (len > 0 && in[len - 1] == '.') { + len--; + } + + /* Wildcards are allowed in front. */ + if (len >= 2 && in[0] == '*' && in[1] == '.') { + in += 2; + len -= 2; + } + + if (len == 0) { + return 0; + } + + size_t label_start = 0; + for (size_t i = 0; i < len; i++) { + unsigned char c = in[i]; + if ((c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c == '-' && i > label_start) || + /* These are not valid characters in hostnames, but commonly found + * in deployments outside the Web PKI. */ + c == '_' || + c == ':') { + continue; + } + + /* Labels must not be empty. */ + if (c == '.' && i > label_start && i < len - 1) { + label_start = i + 1; + continue; + } + + return 0; + } + + return 1; +} + +/* + * Compare an ASN1_STRING to a supplied string. If they match return 1. If + * cmp_type > 0 only compare if string matches the type, otherwise convert it + * to UTF8. + */ + +static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, + unsigned int flags, int check_type, const char *b, + size_t blen, char **peername) +{ + int rv = 0; + + if (!a->data || !a->length) + return 0; + if (cmp_type > 0) { + if (cmp_type != a->type) + return 0; + if (cmp_type == V_ASN1_IA5STRING) + rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); + else if (a->length == (int)blen && !OPENSSL_memcmp(a->data, b, blen)) + rv = 1; + if (rv > 0 && peername) + *peername = OPENSSL_strndup((char *)a->data, a->length); + } else { + int astrlen; + unsigned char *astr; + astrlen = ASN1_STRING_to_UTF8(&astr, a); + if (astrlen < 0) + return -1; + /* + * We check the common name against DNS name constraints if it passes + * |x509v3_looks_like_dns_name|. Thus we must not consider common names + * for DNS fallbacks if they fail this check. + */ + if (check_type == GEN_DNS && + !x509v3_looks_like_dns_name(astr, astrlen)) { + rv = 0; + } else { + rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); + } + if (rv > 0 && peername) + *peername = OPENSSL_strndup((char *)astr, astrlen); + OPENSSL_free(astr); + } + return rv; +} + +static int do_x509_check(X509 *x, const char *chk, size_t chklen, + unsigned int flags, int check_type, char **peername) +{ + GENERAL_NAMES *gens = NULL; + X509_NAME *name = NULL; + size_t i; + int j; + int cnid = NID_undef; + int alt_type; + int rv = 0; + equal_fn equal; + + if (check_type == GEN_EMAIL) { + cnid = NID_pkcs9_emailAddress; + alt_type = V_ASN1_IA5STRING; + equal = equal_email; + } else if (check_type == GEN_DNS) { + cnid = NID_commonName; + alt_type = V_ASN1_IA5STRING; + if (flags & X509_CHECK_FLAG_NO_WILDCARDS) + equal = equal_nocase; + else + equal = equal_wildcard; + } else { + alt_type = V_ASN1_OCTET_STRING; + equal = equal_case; + } + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + GENERAL_NAME *gen; + ASN1_STRING *cstr; + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != check_type) + continue; + if (check_type == GEN_EMAIL) + cstr = gen->d.rfc822Name; + else if (check_type == GEN_DNS) + cstr = gen->d.dNSName; + else + cstr = gen->d.iPAddress; + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, alt_type, equal, flags, check_type, + chk, chklen, peername)) != 0) + break; + } + GENERAL_NAMES_free(gens); + return rv; + } + + /* We're done if CN-ID is not pertinent */ + if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) + return 0; + + j = -1; + name = X509_get_subject_name(x); + while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + ne = X509_NAME_get_entry(name, j); + str = X509_NAME_ENTRY_get_data(ne); + /* Positive on success, negative on error! */ + if ((rv = do_check_string(str, -1, equal, flags, check_type, + chk, chklen, peername)) != 0) + return rv; + } + return 0; +} + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername) +{ + if (chk == NULL) + return -2; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); +} + +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags) +{ + if (chk == NULL) + return -2; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); +} + +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags) +{ + if (chk == NULL) + return -2; + return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); +} + +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) +{ + unsigned char ipout[16]; + size_t iplen; + + if (ipasc == NULL) + return -2; + iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); + if (iplen == 0) + return -2; + return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); +} + +/* + * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible + * with RFC 3280. + */ + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) +{ + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; + + iplen = x509v3_a2i_ipadd(ipout, ipasc); + if (!iplen) + return NULL; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; +} + +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) +{ + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + p = strchr(ipasc, '/'); + if (!p) + return NULL; + iptmp = OPENSSL_strdup(ipasc); + if (!iptmp) + return NULL; + p = iptmp + (p - ipasc); + *p++ = 0; + + iplen1 = x509v3_a2i_ipadd(ipout, iptmp); + + if (!iplen1) + goto err; + + iplen2 = x509v3_a2i_ipadd(ipout + iplen1, p); + + OPENSSL_free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) + goto err; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + goto err; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) + goto err; + + return ret; + + err: + if (iptmp) + OPENSSL_free(iptmp); + if (ret) + ASN1_OCTET_STRING_free(ret); + return NULL; +} + +int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc) +{ + /* If string contains a ':' assume IPv6 */ + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) + return 0; + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) + return 0; + return 4; + } +} + +static int ipv4_from_asc(unsigned char v4[4], const char *in) +{ + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) + || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; +} + +typedef struct { + /* Temporary store for IPV6 output */ + unsigned char tmp[16]; + /* Total number of bytes in tmp */ + int total; + /* The position of a zero (corresponding to '::') */ + int zero_pos; + /* Number of zeroes */ + int zero_cnt; +} IPV6_STAT; + +static int ipv6_from_asc(unsigned char v6[16], const char *in) +{ + IPV6_STAT v6stat; + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + /* + * Treat the IPv6 representation as a list of values separated by ':'. + * The presence of a '::' will parse as one, two or three zero length + * elements. + */ + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) + return 0; + + /* Now for some sanity checks */ + + if (v6stat.zero_pos == -1) { + /* If no '::' must have exactly 16 bytes */ + if (v6stat.total != 16) + return 0; + } else { + /* If '::' must have less than 16 bytes */ + if (v6stat.total == 16) + return 0; + /* More than three zeroes is an error */ + if (v6stat.zero_cnt > 3) + return 0; + /* Can only have three zeroes if nothing else present */ + else if (v6stat.zero_cnt == 3) { + if (v6stat.total > 0) + return 0; + } + /* Can only have two zeroes if at start or end */ + else if (v6stat.zero_cnt == 2) { + if ((v6stat.zero_pos != 0) + && (v6stat.zero_pos != v6stat.total)) + return 0; + } else + /* Can only have one zero if *not* start or end */ + { + if ((v6stat.zero_pos == 0) + || (v6stat.zero_pos == v6stat.total)) + return 0; + } + } + + /* Format result */ + + if (v6stat.zero_pos >= 0) { + /* Copy initial part */ + OPENSSL_memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + OPENSSL_memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + OPENSSL_memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + OPENSSL_memcpy(v6, v6stat.tmp, 16); + + return 1; +} + +static int ipv6_cb(const char *elem, int len, void *usr) +{ + IPV6_STAT *s = usr; + /* Error if 16 bytes written */ + if (s->total == 16) + return 0; + if (len == 0) { + /* Zero length element, corresponds to '::' */ + if (s->zero_pos == -1) + s->zero_pos = s->total; + /* If we've already got a :: its an error */ + else if (s->zero_pos != s->total) + return 0; + s->zero_cnt++; + } else { + /* If more than 4 characters could be final a.b.c.d form */ + if (len > 4) { + /* Need at least 4 bytes left */ + if (s->total > 12) + return 0; + /* Must be end of string */ + if (elem[len]) + return 0; + if (!ipv4_from_asc(s->tmp + s->total, elem)) + return 0; + s->total += 4; + } else { + if (!ipv6_hex(s->tmp + s->total, elem, len)) + return 0; + s->total += 2; + } + } + return 1; +} + +/* + * Convert a string of up to 4 hex digits into the corresponding IPv6 form. + */ + +static int ipv6_hex(unsigned char *out, const char *in, int inlen) +{ + unsigned char c; + unsigned int num = 0; + if (inlen > 4) + return 0; + while (inlen--) { + c = *in++; + num <<= 4; + if ((c >= '0') && (c <= '9')) + num |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) + num |= c - 'A' + 10; + else if ((c >= 'a') && (c <= 'f')) + num |= c - 'a' + 10; + else + return 0; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF (CONF_VALUE) * dn_sk, + unsigned long chtype) +{ + CONF_VALUE *v; + int mval; + size_t i; + char *p, *type; + if (!nm) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + v = sk_CONF_VALUE_value(dn_sk, i); + type = v->name; + /* + * Skip past any leading X. X: X, etc to allow for multiple instances + */ + for (p = type; *p; p++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + mval = -1; + type++; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, + (unsigned char *)v->value, -1, -1, + mval)) + return 0; + + } + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h new file mode 100644 index 00000000..f40d136e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifndef C_NIO_BORINGSSL_H +#define C_NIO_BORINGSSL_H + +#include "CNIOBoringSSL_aes.h" +#include "CNIOBoringSSL_arm_arch.h" +#include "CNIOBoringSSL_asn1_mac.h" +#include "CNIOBoringSSL_asn1t.h" +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_blake2.h" +#include "CNIOBoringSSL_blowfish.h" +#include "CNIOBoringSSL_boringssl_prefix_symbols.h" +#include "CNIOBoringSSL_boringssl_prefix_symbols_asm.h" +#include "CNIOBoringSSL_cast.h" +#include "CNIOBoringSSL_chacha.h" +#include "CNIOBoringSSL_cmac.h" +#include "CNIOBoringSSL_conf.h" +#include "CNIOBoringSSL_cpu.h" +#include "CNIOBoringSSL_curve25519.h" +#include "CNIOBoringSSL_des.h" +#include "CNIOBoringSSL_dtls1.h" +#include "CNIOBoringSSL_e_os2.h" +#include "CNIOBoringSSL_ec.h" +#include "CNIOBoringSSL_ec_key.h" +#include "CNIOBoringSSL_ecdsa.h" +#include "CNIOBoringSSL_err.h" +#include "CNIOBoringSSL_evp.h" +#include "CNIOBoringSSL_hkdf.h" +#include "CNIOBoringSSL_hmac.h" +#include "CNIOBoringSSL_hpke.h" +#include "CNIOBoringSSL_hrss.h" +#include "CNIOBoringSSL_md4.h" +#include "CNIOBoringSSL_md5.h" +#include "CNIOBoringSSL_obj_mac.h" +#include "CNIOBoringSSL_objects.h" +#include "CNIOBoringSSL_opensslv.h" +#include "CNIOBoringSSL_ossl_typ.h" +#include "CNIOBoringSSL_pkcs12.h" +#include "CNIOBoringSSL_poly1305.h" +#include "CNIOBoringSSL_rand.h" +#include "CNIOBoringSSL_rc4.h" +#include "CNIOBoringSSL_ripemd.h" +#include "CNIOBoringSSL_rsa.h" +#include "CNIOBoringSSL_safestack.h" +#include "CNIOBoringSSL_sha.h" +#include "CNIOBoringSSL_siphash.h" +#include "CNIOBoringSSL_srtp.h" +#include "CNIOBoringSSL_ssl.h" +#include "CNIOBoringSSL_trust_token.h" +#include "CNIOBoringSSL_x509_vfy.h" +#include "CNIOBoringSSL_x509v3.h" + +#endif // C_NIO_BORINGSSL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aead.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aead.h new file mode 100644 index 00000000..88265730 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aead.h @@ -0,0 +1,480 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AEAD_H +#define OPENSSL_HEADER_AEAD_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Authenticated Encryption with Additional Data. +// +// AEAD couples confidentiality and integrity in a single primitive. AEAD +// algorithms take a key and then can seal and open individual messages. Each +// message has a unique, per-message nonce and, optionally, additional data +// which is authenticated but not included in the ciphertext. +// +// The |EVP_AEAD_CTX_init| function initialises an |EVP_AEAD_CTX| structure and +// performs any precomputation needed to use |aead| with |key|. The length of +// the key, |key_len|, is given in bytes. +// +// The |tag_len| argument contains the length of the tags, in bytes, and allows +// for the processing of truncated authenticators. A zero value indicates that +// the default tag length should be used and this is defined as +// |EVP_AEAD_DEFAULT_TAG_LENGTH| in order to make the code clear. Using +// truncated tags increases an attacker's chance of creating a valid forgery. +// Be aware that the attacker's chance may increase more than exponentially as +// would naively be expected. +// +// When no longer needed, the initialised |EVP_AEAD_CTX| structure must be +// passed to |EVP_AEAD_CTX_cleanup|, which will deallocate any memory used. +// +// With an |EVP_AEAD_CTX| in hand, one can seal and open messages. These +// operations are intended to meet the standard notions of privacy and +// authenticity for authenticated encryption. For formal definitions see +// Bellare and Namprempre, "Authenticated encryption: relations among notions +// and analysis of the generic composition paradigm," Lecture Notes in Computer +// Science B<1976> (2000), 531–545, +// http://www-cse.ucsd.edu/~mihir/papers/oem.html. +// +// When sealing messages, a nonce must be given. The length of the nonce is +// fixed by the AEAD in use and is returned by |EVP_AEAD_nonce_length|. *The +// nonce must be unique for all messages with the same key*. This is critically +// important - nonce reuse may completely undermine the security of the AEAD. +// Nonces may be predictable and public, so long as they are unique. Uniqueness +// may be achieved with a simple counter or, if large enough, may be generated +// randomly. The nonce must be passed into the "open" operation by the receiver +// so must either be implicit (e.g. a counter), or must be transmitted along +// with the sealed message. +// +// The "seal" and "open" operations are atomic - an entire message must be +// encrypted or decrypted in a single call. Large messages may have to be split +// up in order to accommodate this. When doing so, be mindful of the need not to +// repeat nonces and the possibility that an attacker could duplicate, reorder +// or drop message chunks. For example, using a single key for a given (large) +// message and sealing chunks with nonces counting from zero would be secure as +// long as the number of chunks was securely transmitted. (Otherwise an +// attacker could truncate the message by dropping chunks from the end.) +// +// The number of chunks could be transmitted by prefixing it to the plaintext, +// for example. This also assumes that no other message would ever use the same +// key otherwise the rule that nonces must be unique for a given key would be +// violated. +// +// The "seal" and "open" operations also permit additional data to be +// authenticated via the |ad| parameter. This data is not included in the +// ciphertext and must be identical for both the "seal" and "open" call. This +// permits implicit context to be authenticated but may be empty if not needed. +// +// The "seal" and "open" operations may work in-place if the |out| and |in| +// arguments are equal. Otherwise, if |out| and |in| alias, input data may be +// overwritten before it is read. This situation will cause an error. +// +// The "seal" and "open" operations return one on success and zero on error. + + +// AEAD algorithms. + +// EVP_aead_aes_128_gcm is AES-128 in Galois Counter Mode. +// +// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it +// is specified to take a variable-length nonce, nonces with other lengths are +// effectively randomized, which means one must consider collisions. Unless +// implementing an existing protocol which has already specified incorrect +// parameters, only use 12-byte nonces. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void); + +// EVP_aead_aes_192_gcm is AES-192 in Galois Counter Mode. +// +// WARNING: AES-192 is superfluous and shouldn't exist. NIST should never have +// defined it. Use only when interop with another system requires it, never +// de novo. +// +// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it +// is specified to take a variable-length nonce, nonces with other lengths are +// effectively randomized, which means one must consider collisions. Unless +// implementing an existing protocol which has already specified incorrect +// parameters, only use 12-byte nonces. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_192_gcm(void); + +// EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. +// +// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it +// is specified to take a variable-length nonce, nonces with other lengths are +// effectively randomized, which means one must consider collisions. Unless +// implementing an existing protocol which has already specified incorrect +// parameters, only use 12-byte nonces. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void); + +// EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and +// Poly1305 as described in RFC 8439. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void); + +// EVP_aead_xchacha20_poly1305 is ChaCha20-Poly1305 with an extended nonce that +// makes random generation of nonces safe. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_xchacha20_poly1305(void); + +// EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for +// authentication. The nonce is 12 bytes; the bottom 32-bits are used as the +// block counter, thus the maximum plaintext size is 64GB. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void); + +// EVP_aead_aes_256_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for +// authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void); + +// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void); + +// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void); + +// EVP_aead_aes_128_gcm_randnonce is AES-128 in Galois Counter Mode with +// internal nonce generation. The 12-byte nonce is appended to the tag +// and is generated internally. The "tag", for the purpurses of the API, is thus +// 12 bytes larger. The nonce parameter when using this AEAD must be +// zero-length. Since the nonce is random, a single key should not be used for +// more than 2^32 seal operations. +// +// Warning: this is for use for FIPS compliance only. It is probably not +// suitable for other uses. Using standard AES-GCM AEADs allows one to achieve +// the same effect, but gives more control over nonce storage. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_randnonce(void); + +// EVP_aead_aes_256_gcm_randnonce is AES-256 in Galois Counter Mode with +// internal nonce generation. The 12-byte nonce is appended to the tag +// and is generated internally. The "tag", for the purpurses of the API, is thus +// 12 bytes larger. The nonce parameter when using this AEAD must be +// zero-length. Since the nonce is random, a single key should not be used for +// more than 2^32 seal operations. +// +// Warning: this is for use for FIPS compliance only. It is probably not +// suitable for other uses. Using standard AES-GCM AEADs allows one to achieve +// the same effect, but gives more control over nonce storage. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_randnonce(void); + +// EVP_aead_aes_128_ccm_bluetooth is AES-128-CCM with M=4 and L=2 (4-byte tags +// and 13-byte nonces), as decribed in the Bluetooth Core Specification v5.0, +// Volume 6, Part E, Section 1. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void); + +// EVP_aead_aes_128_ccm_bluetooth_8 is AES-128-CCM with M=8 and L=2 (8-byte tags +// and 13-byte nonces), as used in the Bluetooth Mesh Networking Specification +// v1.0. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void); + +// EVP_has_aes_hardware returns one if we enable hardware support for fast and +// constant-time AES-GCM. +OPENSSL_EXPORT int EVP_has_aes_hardware(void); + + +// Utility functions. + +// EVP_AEAD_key_length returns the length, in bytes, of the keys used by +// |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead); + +// EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce +// for |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead); + +// EVP_AEAD_max_overhead returns the maximum number of additional bytes added +// by the act of sealing data with |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead); + +// EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This +// is the largest value that can be passed as |tag_len| to +// |EVP_AEAD_CTX_init|. +OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); + + +// AEAD operations. + +union evp_aead_ctx_st_state { + uint8_t opaque[580]; + uint64_t alignment; +}; + +// An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key +// and message-independent IV. +typedef struct evp_aead_ctx_st { + const EVP_AEAD *aead; + union evp_aead_ctx_st_state state; + // tag_len may contain the actual length of the authentication tag if it is + // known at initialization time. + uint8_t tag_len; +} EVP_AEAD_CTX; + +// EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_KEY_LENGTH 80 + +// EVP_AEAD_MAX_NONCE_LENGTH contains the maximum nonce length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_NONCE_LENGTH 24 + +// EVP_AEAD_MAX_OVERHEAD contains the maximum overhead used by any AEAD +// defined in this header. +#define EVP_AEAD_MAX_OVERHEAD 64 + +// EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to +// EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD should +// be used. +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 + +// EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be +// initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not +// necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for +// more uniform cleanup of |EVP_AEAD_CTX|. +OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_new allocates an |EVP_AEAD_CTX|, calls |EVP_AEAD_CTX_init| and +// returns the |EVP_AEAD_CTX|, or NULL on error. +OPENSSL_EXPORT EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, + const uint8_t *key, + size_t key_len, size_t tag_len); + +// EVP_AEAD_CTX_free calls |EVP_AEAD_CTX_cleanup| and |OPENSSL_free| on +// |ctx|. +OPENSSL_EXPORT void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm. The |impl| +// argument is ignored and should be NULL. Authentication tags may be truncated +// by passing a size as |tag_len|. A |tag_len| of zero indicates the default +// tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for +// readability. +// +// Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In +// the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's +// harmless to do so. +OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, ENGINE *impl); + +// EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to +// call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to +// all zeros. +OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and +// authenticates |ad_len| bytes from |ad| and writes the result to |out|. It +// returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be |in_len| plus the result of +// |EVP_AEAD_max_overhead|. On successful return, |*out_len| is set to the +// actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes +// from |ad| and decrypts at most |in_len| bytes into |out|. It returns one on +// success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |in_len| bytes are written to |out|. In order to ensure success, +// |max_out_len| should be at least |in_len|. On successful return, |*out_len| +// is set to the the actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_seal_scatter encrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad|. It writes |in_len| bytes of +// ciphertext to |out| and the authentication tag to |out_tag|. It returns one +// on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// Exactly |in_len| bytes are written to |out|, and up to +// |EVP_AEAD_max_overhead+extra_in_len| bytes to |out_tag|. On successful +// return, |*out_tag_len| is set to the actual number of bytes written to +// |out_tag|. +// +// |extra_in| may point to an additional plaintext input buffer if the cipher +// supports it. If present, |extra_in_len| additional bytes of plaintext are +// encrypted and authenticated, and the ciphertext is written (before the tag) +// to |out_tag|. |max_out_tag_len| must be sized to allow for the additional +// |extra_in_len| bytes. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal_scatter| never results in a partial output. If +// |max_out_tag_len| is insufficient, zero will be returned. If any error +// occurs, |out| and |out_tag| will be filled with zero bytes and |*out_tag_len| +// set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. |out_tag| may not alias +// any other argument. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open_gather decrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad| using |in_tag_len| bytes of +// authentication tag from |in_tag|. If successful, it writes |in_len| bytes of +// plaintext to |out|. It returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open_gather| never results in a partial output. If any error +// occurs, |out| will be filled with zero bytes. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_aead returns the underlying AEAD for |ctx|, or NULL if one has +// not been set. +OPENSSL_EXPORT const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx); + + +// TLS-specific AEAD algorithms. +// +// These AEAD primitives do not meet the definition of generic AEADs. They are +// all specific to TLS and should not be used outside of that context. They must +// be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may +// not be used concurrently. Any nonces are used as IVs, so they must be +// unpredictable. They only accept an |ad| parameter of length 11 (the standard +// TLS one with length omitted). + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void); + +// EVP_aead_aes_128_gcm_tls12 is AES-128 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls12(void); + +// EVP_aead_aes_256_gcm_tls12 is AES-256 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls12(void); + +// EVP_aead_aes_128_gcm_tls13 is AES-128 in Galois Counter Mode using the TLS +// 1.3 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls13(void); + +// EVP_aead_aes_256_gcm_tls13 is AES-256 in Galois Counter Mode using the TLS +// 1.3 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls13(void); + + +// Obscure functions. + +// evp_aead_direction_t denotes the direction of an AEAD operation. +enum evp_aead_direction_t { + evp_aead_open, + evp_aead_seal, +}; + +// EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal +// AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a +// given direction. +OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction( + EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + +// EVP_AEAD_CTX_get_iv sets |*out_len| to the length of the IV for |ctx| and +// sets |*out_iv| to point to that many bytes of the current IV. This is only +// meaningful for AEADs with implicit IVs (i.e. CBC mode in TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, + const uint8_t **out_iv, size_t *out_len); + +// EVP_AEAD_CTX_tag_len computes the exact byte length of the tag written by +// |EVP_AEAD_CTX_seal_scatter| and writes it to |*out_tag_len|. It returns one +// on success or zero on error. |in_len| and |extra_in_len| must equal the +// arguments of the same names passed to |EVP_AEAD_CTX_seal_scatter|. +OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, + size_t *out_tag_len, + const size_t in_len, + const size_t extra_in_len); + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +using ScopedEVP_AEAD_CTX = + internal::StackAllocated; + +BORINGSSL_MAKE_DELETER(EVP_AEAD_CTX, EVP_AEAD_CTX_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_AEAD_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aes.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aes.h new file mode 100644 index 00000000..58ac6982 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_aes.h @@ -0,0 +1,207 @@ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_AES_H +#define OPENSSL_HEADER_AES_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Raw AES functions. + + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +// AES_MAXNR is the maximum number of AES rounds. +#define AES_MAXNR 14 + +#define AES_BLOCK_SIZE 16 + +// aes_key_st should be an opaque type, but EVP requires that the size be +// known. +struct aes_key_st { + uint32_t rd_key[4 * (AES_MAXNR + 1)]; + unsigned rounds; +}; +typedef struct aes_key_st AES_KEY; + +// AES_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit key, +// |key|. |key| must point to |bits|/8 bytes. It returns zero on success and a +// negative number if |bits| is an invalid AES key size. +// +// WARNING: this function breaks the usual return value convention. +OPENSSL_EXPORT int AES_set_encrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit key, +// |key|. |key| must point to |bits|/8 bytes. It returns zero on success and a +// negative number if |bits| is an invalid AES key size. +// +// WARNING: this function breaks the usual return value convention. +OPENSSL_EXPORT int AES_set_decrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + +// AES_decrypt decrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + + +// Block cipher modes. + +// AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call and |ivec| will be incremented. This function may be called +// in-place with |in| equal to |out|, but otherwise the buffers may not +// partially overlap. A partial overlap may overwrite input data before it is +// read. +OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); + +// AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single, +// 16 byte block from |in| to |out|. This function may be called in-place with +// |in| equal to |out|, but otherwise the buffers may not partially overlap. A +// partial overlap may overwrite input data before it is read. +OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key, const int enc); + +// AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The length must be a multiple of the block size. +// This function may be called in-place with |in| equal to |out|, but otherwise +// the buffers may not partially overlap. A partial overlap may overwrite input +// data before it is read. +OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, + const int enc); + +// AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. This function may be called in-place with |in| equal to |out|, +// but otherwise the buffers may not partially overlap. A partial overlap may +// overwrite input data before it is read. +OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num); + +// AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. This function may be called in-place with |in| equal to |out|, +// but otherwise the buffers may not partially overlap. A partial overlap may +// overwrite input data before it is read. +OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num, int enc); + + +// AES key wrap. +// +// These functions implement AES Key Wrap mode, as defined in RFC 3394. They +// should never be used except to interoperate with existing systems that use +// this mode. + +// AES_wrap_key performs AES key wrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for encryption. On success, it writes +// |in_len| + 8 bytes to |out| and returns |in_len| + 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, size_t in_len); + +// AES_unwrap_key performs AES key unwrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for decryption. On success, it writes +// |in_len| - 8 bytes to |out| and returns |in_len| - 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, + size_t in_len); + + +// AES key wrap with padding. +// +// These functions implement AES Key Wrap with Padding mode, as defined in RFC +// 5649. They should never be used except to interoperate with existing systems +// that use this mode. + +// AES_wrap_key_padded performs a padded AES key wrap on |in| which must be +// between 1 and 2^32-1 bytes. |key| must have been configured for encryption. +// On success it writes at most |max_out| bytes of ciphertext to |out|, sets +// |*out_len| to the number of bytes written, and returns one. On failure it +// returns zero. To ensure success, set |max_out| to at least |in_len| + 15. +OPENSSL_EXPORT int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + +// AES_unwrap_key_padded performs a padded AES key unwrap on |in| which must be +// a multiple of 8 bytes. |key| must have been configured for decryption. On +// success it writes at most |max_out| bytes to |out|, sets |*out_len| to the +// number of bytes written, and returns one. On failure it returns zero. Setting +// |max_out| to |in_len| is a sensible estimate. +OPENSSL_EXPORT int AES_unwrap_key_padded(const AES_KEY *key, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_arm_arch.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_arm_arch.h new file mode 100644 index 00000000..7215f62e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_arm_arch.h @@ -0,0 +1,220 @@ +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_ARM_ARCH_H +#define OPENSSL_HEADER_ARM_ARCH_H + +// arm_arch.h contains symbols used by ARM assembly, and the C code that calls +// it. It is included as a public header to simplify the build, but is not +// intended for external use. + +#if defined(__ARMEL__) || defined(_M_ARM) || defined(__AARCH64EL__) || \ + defined(_M_ARM64) + +// ARMV7_NEON is true when a NEON unit is present in the current CPU. +#define ARMV7_NEON (1 << 0) + +// ARMV8_AES indicates support for hardware AES instructions. +#define ARMV8_AES (1 << 2) + +// ARMV8_SHA1 indicates support for hardware SHA-1 instructions. +#define ARMV8_SHA1 (1 << 3) + +// ARMV8_SHA256 indicates support for hardware SHA-256 instructions. +#define ARMV8_SHA256 (1 << 4) + +// ARMV8_PMULL indicates support for carryless multiplication. +#define ARMV8_PMULL (1 << 5) + +// ARMV8_SHA512 indicates support for hardware SHA-512 instructions. +#define ARMV8_SHA512 (1 << 6) + +#if defined(__ASSEMBLER__) + +// We require the ARM assembler provide |__ARM_ARCH| from Arm C Language +// Extensions (ACLE). This is supported in GCC 4.8+ and Clang 3.2+. MSVC does +// not implement ACLE, but we require Clang's assembler on Windows. +#if !defined(__ARM_ARCH) +#error "ARM assembler must define __ARM_ARCH" +#endif + +// __ARM_ARCH__ is used by OpenSSL assembly to determine the minimum target ARM +// version. +// +// TODO(davidben): Switch the assembly to use |__ARM_ARCH| directly. +#define __ARM_ARCH__ __ARM_ARCH + +// Even when building for 32-bit ARM, support for aarch64 crypto instructions +// will be included. +#define __ARM_MAX_ARCH__ 8 + +// Support macros for +// - Armv8.3-A Pointer Authentication and +// - Armv8.5-A Branch Target Identification +// features which require emitting a .note.gnu.property section with the +// appropriate architecture-dependent feature bits set. +// +// |AARCH64_SIGN_LINK_REGISTER| and |AARCH64_VALIDATE_LINK_REGISTER| expand to +// PACIxSP and AUTIxSP, respectively. |AARCH64_SIGN_LINK_REGISTER| should be +// used immediately before saving the LR register (x30) to the stack. +// |AARCH64_VALIDATE_LINK_REGISTER| should be used immediately after restoring +// it. Note |AARCH64_SIGN_LINK_REGISTER|'s modifications to LR must be undone +// with |AARCH64_VALIDATE_LINK_REGISTER| before RET. The SP register must also +// have the same value at the two points. For example: +// +// .global f +// f: +// AARCH64_SIGN_LINK_REGISTER +// stp x29, x30, [sp, #-96]! +// mov x29, sp +// ... +// ldp x29, x30, [sp], #96 +// AARCH64_VALIDATE_LINK_REGISTER +// ret +// +// |AARCH64_VALID_CALL_TARGET| expands to BTI 'c'. Either it, or +// |AARCH64_SIGN_LINK_REGISTER|, must be used at every point that may be an +// indirect call target. In particular, all symbols exported from a file must +// begin with one of these macros. For example, a leaf function that does not +// save LR can instead use |AARCH64_VALID_CALL_TARGET|: +// +// .globl return_zero +// return_zero: +// AARCH64_VALID_CALL_TARGET +// mov x0, #0 +// ret +// +// A non-leaf function which does not immediately save LR may need both macros +// because |AARCH64_SIGN_LINK_REGISTER| appears late. For example, the function +// may jump to an alternate implementation before setting up the stack: +// +// .globl with_early_jump +// with_early_jump: +// AARCH64_VALID_CALL_TARGET +// cmp x0, #128 +// b.lt .Lwith_early_jump_128 +// AARCH64_SIGN_LINK_REGISTER +// stp x29, x30, [sp, #-96]! +// mov x29, sp +// ... +// ldp x29, x30, [sp], #96 +// AARCH64_VALIDATE_LINK_REGISTER +// ret +// +// .Lwith_early_jump_128: +// ... +// ret +// +// These annotations are only required with indirect calls. Private symbols that +// are only the target of direct calls do not require annotations. Also note +// that |AARCH64_VALID_CALL_TARGET| is only valid for indirect calls (BLR), not +// indirect jumps (BR). Indirect jumps in assembly are currently not supported +// and would require a macro for BTI 'j'. +// +// Although not necessary, it is safe to use these macros in 32-bit ARM +// assembly. This may be used to simplify dual 32-bit and 64-bit files. +// +// References: +// - "ELF for the Arm® 64-bit Architecture" +// https://github.com/ARM-software/abi-aa/blob/master/aaelf64/aaelf64.rst +// - "Providing protection for complex software" +// https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software + +#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 +#define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has Branch Target Identification +#define AARCH64_VALID_CALL_TARGET hint #34 // BTI 'c' +#else +#define GNU_PROPERTY_AARCH64_BTI 0 // No Branch Target Identification +#define AARCH64_VALID_CALL_TARGET +#endif + +#if defined(__ARM_FEATURE_PAC_DEFAULT) && \ + (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 // Signed with A-key +#define GNU_PROPERTY_AARCH64_POINTER_AUTH \ + (1 << 1) // Has Pointer Authentication +#define AARCH64_SIGN_LINK_REGISTER hint #25 // PACIASP +#define AARCH64_VALIDATE_LINK_REGISTER hint #29 // AUTIASP +#elif defined(__ARM_FEATURE_PAC_DEFAULT) && \ + (__ARM_FEATURE_PAC_DEFAULT & 2) == 2 // Signed with B-key +#define GNU_PROPERTY_AARCH64_POINTER_AUTH \ + (1 << 1) // Has Pointer Authentication +#define AARCH64_SIGN_LINK_REGISTER hint #27 // PACIBSP +#define AARCH64_VALIDATE_LINK_REGISTER hint #31 // AUTIBSP +#else +#define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 // No Pointer Authentication +#if GNU_PROPERTY_AARCH64_BTI != 0 +#define AARCH64_SIGN_LINK_REGISTER AARCH64_VALID_CALL_TARGET +#else +#define AARCH64_SIGN_LINK_REGISTER +#endif +#define AARCH64_VALIDATE_LINK_REGISTER +#endif + +#if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0 +.pushsection .note.gnu.property, "a"; +.balign 8; +.long 4; +.long 0x10; +.long 0x5; +.asciz "GNU"; +.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ +.long 4; +.long (GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI); +.long 0; +.popsection; +#endif + +#endif // __ASSEMBLER__ + +#endif // __ARMEL__ || _M_ARM || __AARCH64EL__ || _M_ARM64 + +#endif // OPENSSL_HEADER_ARM_ARCH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h new file mode 100644 index 00000000..dc0e11cf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h @@ -0,0 +1,2071 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +#define HEADER_ASN1_H + +#include "CNIOBoringSSL_base.h" + +#include + +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_bn.h" +#include "CNIOBoringSSL_stack.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Legacy ASN.1 library. +// +// This header is part of OpenSSL's ASN.1 implementation. It is retained for +// compatibility but should not be used by new code. The functions are difficult +// to use correctly, and have buggy or non-standard behaviors. They are thus +// particularly prone to behavior changes and API removals, as BoringSSL +// iterates on these issues. +// +// Use the new |CBS| and |CBB| library in instead. + + +// Tag constants. +// +// These constants are used in various APIs to specify ASN.1 types and tag +// components. See the specific API's documentation for details on which values +// are used and how. + +// The following constants are tag classes. +#define V_ASN1_UNIVERSAL 0x00 +#define V_ASN1_APPLICATION 0x40 +#define V_ASN1_CONTEXT_SPECIFIC 0x80 +#define V_ASN1_PRIVATE 0xc0 + +// V_ASN1_CONSTRUCTED indicates an element is constructed, rather than +// primitive. +#define V_ASN1_CONSTRUCTED 0x20 + +// V_ASN1_PRIMITIVE_TAG is the highest tag number which can be encoded in a +// single byte. Note this is unrelated to whether an element is constructed or +// primitive. +// +// TODO(davidben): Make this private. +#define V_ASN1_PRIMITIVE_TAG 0x1f + +// V_ASN1_MAX_UNIVERSAL is the highest supported universal tag number. It is +// necessary to avoid ambiguity with |V_ASN1_NEG| and |MBSTRING_FLAG|. +// +// TODO(davidben): Make this private. +#define V_ASN1_MAX_UNIVERSAL 0xff + +// V_ASN1_UNDEF is used in some APIs to indicate an ASN.1 element is omitted. +#define V_ASN1_UNDEF (-1) + +// V_ASN1_OTHER is used in |ASN1_TYPE| to indicate a non-universal ASN.1 type. +#define V_ASN1_OTHER (-3) + +// V_ASN1_ANY is used by the ASN.1 templates to indicate an ANY type. +#define V_ASN1_ANY (-4) + +// The following constants are tag numbers for universal types. +#define V_ASN1_EOC 0 +#define V_ASN1_BOOLEAN 1 +#define V_ASN1_INTEGER 2 +#define V_ASN1_BIT_STRING 3 +#define V_ASN1_OCTET_STRING 4 +#define V_ASN1_NULL 5 +#define V_ASN1_OBJECT 6 +#define V_ASN1_OBJECT_DESCRIPTOR 7 +#define V_ASN1_EXTERNAL 8 +#define V_ASN1_REAL 9 +#define V_ASN1_ENUMERATED 10 +#define V_ASN1_UTF8STRING 12 +#define V_ASN1_SEQUENCE 16 +#define V_ASN1_SET 17 +#define V_ASN1_NUMERICSTRING 18 +#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_T61STRING 20 +#define V_ASN1_TELETEXSTRING 20 +#define V_ASN1_VIDEOTEXSTRING 21 +#define V_ASN1_IA5STRING 22 +#define V_ASN1_UTCTIME 23 +#define V_ASN1_GENERALIZEDTIME 24 +#define V_ASN1_GRAPHICSTRING 25 +#define V_ASN1_ISO64STRING 26 +#define V_ASN1_VISIBLESTRING 26 +#define V_ASN1_GENERALSTRING 27 +#define V_ASN1_UNIVERSALSTRING 28 +#define V_ASN1_BMPSTRING 30 + +// The following constants are used for |ASN1_STRING| values that represent +// negative INTEGER and ENUMERATED values. See |ASN1_STRING| for more details. +#define V_ASN1_NEG 0x100 +#define V_ASN1_NEG_INTEGER (V_ASN1_INTEGER | V_ASN1_NEG) +#define V_ASN1_NEG_ENUMERATED (V_ASN1_ENUMERATED | V_ASN1_NEG) + +// The following constants are bitmask representations of ASN.1 types. +#define B_ASN1_NUMERICSTRING 0x0001 +#define B_ASN1_PRINTABLESTRING 0x0002 +#define B_ASN1_T61STRING 0x0004 +#define B_ASN1_TELETEXSTRING 0x0004 +#define B_ASN1_VIDEOTEXSTRING 0x0008 +#define B_ASN1_IA5STRING 0x0010 +#define B_ASN1_GRAPHICSTRING 0x0020 +#define B_ASN1_ISO64STRING 0x0040 +#define B_ASN1_VISIBLESTRING 0x0040 +#define B_ASN1_GENERALSTRING 0x0080 +#define B_ASN1_UNIVERSALSTRING 0x0100 +#define B_ASN1_OCTET_STRING 0x0200 +#define B_ASN1_BIT_STRING 0x0400 +#define B_ASN1_BMPSTRING 0x0800 +#define B_ASN1_UNKNOWN 0x1000 +#define B_ASN1_UTF8STRING 0x2000 +#define B_ASN1_UTCTIME 0x4000 +#define B_ASN1_GENERALIZEDTIME 0x8000 +#define B_ASN1_SEQUENCE 0x10000 + +// ASN1_tag2bit converts |tag| from the tag number of a universal type to a +// corresponding |B_ASN1_*| constant, |B_ASN1_UNKNOWN|, or zero. If the +// |B_ASN1_*| constant above is defined, it will map the corresponding +// |V_ASN1_*| constant to it. Otherwise, whether it returns |B_ASN1_UNKNOWN| or +// zero is ill-defined and callers should not rely on it. +// +// TODO(https://crbug.com/boringssl/412): Figure out what |B_ASN1_UNNOWN| vs +// zero is meant to be. The main impact is what values go in |B_ASN1_PRINTABLE|. +// To that end, we must return zero on types that can't go in |ASN1_STRING|. +OPENSSL_EXPORT unsigned long ASN1_tag2bit(int tag); + +// ASN1_tag2str returns a string representation of |tag|, interpret as a tag +// number for a universal type, or |V_ASN1_NEG_*|. +OPENSSL_EXPORT const char *ASN1_tag2str(int tag); + + +// API conventions. +// +// The following sample functions document the calling conventions used by +// legacy ASN.1 APIs. + +#if 0 // Sample functions + +// d2i_SAMPLE parses a structure from up to |len| bytes at |*inp|. On success, +// it advances |*inp| by the number of bytes read and returns a newly-allocated +// |SAMPLE| object containing the parsed structure. If |out| is non-NULL, it +// additionally frees the previous value at |*out| and updates |*out| to the +// result. If parsing or allocating the result fails, it returns NULL. +// +// This function does not reject trailing data in the input. This allows the +// caller to parse a sequence of concatenated structures. Callers parsing only +// one structure should check for trailing data by comparing the updated |*inp| +// with the end of the input. +// +// Note: If |out| and |*out| are both non-NULL, the object at |*out| is not +// updated in-place. Instead, it is freed, and the pointer is updated to the +// new object. This differs from OpenSSL, which behaves more like +// |d2i_SAMPLE_with_reuse|. Callers are recommended to set |out| to NULL and +// instead use the return value. +SAMPLE *d2i_SAMPLE(SAMPLE **out, const uint8_t **inp, long len); + +// d2i_SAMPLE_with_reuse parses a structure from up to |len| bytes at |*inp|. On +// success, it advances |*inp| by the number of bytes read and returns a +// non-NULL pointer to an object containing the parsed structure. The object is +// determined from |out| as follows: +// +// If |out| is NULL, the function places the result in a newly-allocated +// |SAMPLE| object and returns it. This mode is recommended. +// +// If |out| is non-NULL, but |*out| is NULL, the function also places the result +// in a newly-allocated |SAMPLE| object. It sets |*out| to this object and also +// returns it. +// +// If |out| and |*out| are both non-NULL, the function updates the object at +// |*out| in-place with the result and returns |*out|. +// +// If any of the above fail, the function returns NULL. +// +// This function does not reject trailing data in the input. This allows the +// caller to parse a sequence of concatenated structures. Callers parsing only +// one structure should check for trailing data by comparing the updated |*inp| +// with the end of the input. +// +// WARNING: Callers should not rely on the in-place update mode. It often +// produces the wrong result or breaks the type's internal invariants. Future +// revisions of BoringSSL may standardize on the |d2i_SAMPLE| behavior. +SAMPLE *d2i_SAMPLE_with_reuse(SAMPLE **out, const uint8_t **inp, long len); + +// i2d_SAMPLE marshals |in|. On error, it returns a negative value. On success, +// it returns the length of the result and outputs it via |outp| as follows: +// +// If |outp| is NULL, the function writes nothing. This mode can be used to size +// buffers. +// +// If |outp| is non-NULL but |*outp| is NULL, the function sets |*outp| to a +// newly-allocated buffer containing the result. The caller is responsible for +// releasing |*outp| with |OPENSSL_free|. This mode is recommended for most +// callers. +// +// If |outp| and |*outp| are non-NULL, the function writes the result to +// |*outp|, which must have enough space available, and advances |*outp| just +// past the output. +// +// WARNING: In the third mode, the function does not internally check output +// bounds. Failing to correctly size the buffer will result in a potentially +// exploitable memory error. +int i2d_SAMPLE(const SAMPLE *in, uint8_t **outp); + +#endif // Sample functions + +// The following typedefs are sometimes used for pointers to functions like +// |d2i_SAMPLE| and |i2d_SAMPLE|. Note, however, that these act on |void*|. +// Calling a function with a different pointer type is undefined in C, so this +// is only valid with a wrapper. +typedef void *d2i_of_void(void **, const unsigned char **, long); +typedef int i2d_of_void(const void *, unsigned char **); + + +// ASN.1 types. +// +// An |ASN1_ITEM| represents an ASN.1 type and allows working with ASN.1 types +// generically. +// +// |ASN1_ITEM|s use a different namespace from C types and are accessed via +// |ASN1_ITEM_*| macros. So, for example, |ASN1_OCTET_STRING| is both a C type +// and the name of an |ASN1_ITEM|, referenced as +// |ASN1_ITEM_rptr(ASN1_OCTET_STRING)|. +// +// Each |ASN1_ITEM| has a corresponding C type, typically with the same name, +// which represents values in the ASN.1 type. This type is either a pointer type +// or |ASN1_BOOLEAN|. When it is a pointer, NULL pointers represent omitted +// values. For example, an OCTET STRING value is declared with the C type +// |ASN1_OCTET_STRING*| and uses the |ASN1_ITEM| named |ASN1_OCTET_STRING|. An +// OPTIONAL OCTET STRING uses the same C type and represents an omitted value +// with a NULL pointer. |ASN1_BOOLEAN| is described in a later section. + +// DECLARE_ASN1_ITEM declares an |ASN1_ITEM| with name |name|. The |ASN1_ITEM| +// may be referenced with |ASN1_ITEM_rptr|. Uses of this macro should document +// the corresponding ASN.1 and C types. +#define DECLARE_ASN1_ITEM(name) extern OPENSSL_EXPORT const ASN1_ITEM name##_it; + +// ASN1_ITEM_rptr returns the |const ASN1_ITEM *| named |name|. +#define ASN1_ITEM_rptr(name) (&(name##_it)) + +// ASN1_ITEM_EXP is an abstraction for referencing an |ASN1_ITEM| in a +// constant-initialized structure, such as a method table. It exists because, on +// some OpenSSL platforms, |ASN1_ITEM| references are indirected through +// functions. Structures reference the |ASN1_ITEM| by declaring a field like +// |ASN1_ITEM_EXP *item| and initializing it with |ASN1_ITEM_ref|. +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +// ASN1_ITEM_ref returns an |ASN1_ITEM_EXP*| for the |ASN1_ITEM| named |name|. +#define ASN1_ITEM_ref(name) (&(name##_it)) + +// ASN1_ITEM_ptr converts |iptr|, which must be an |ASN1_ITEM_EXP*| to a +// |const ASN1_ITEM*|. +#define ASN1_ITEM_ptr(iptr) (iptr) + +// ASN1_VALUE_st (aka |ASN1_VALUE|) is an opaque type used as a placeholder for +// the C type corresponding to an |ASN1_ITEM|. +typedef struct ASN1_VALUE_st ASN1_VALUE; + +// ASN1_item_new allocates a new value of the C type corresponding to |it|, or +// NULL on error. On success, the caller must release the value with +// |ASN1_item_free|, or the corresponding C type's free function, when done. The +// new value will initialize fields of the value to some default state, such as +// an empty string. Note, however, that this default state sometimes omits +// required values, such as with CHOICE types. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type is a +// potentially exploitable memory error. Callers must ensure the value is used +// consistently with |it|. Prefer using type-specific functions such as +// |ASN1_OCTET_STRING_new|. +OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); + +// ASN1_item_free releases memory associated with |val|, which must be an object +// of the C type corresponding to |it|. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Passing a pointer of the wrong type into this function is a +// potentially exploitable memory error. Callers must ensure |val| is consistent +// with |it|. Prefer using type-specific functions such as +// |ASN1_OCTET_STRING_free|. +OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); + +// ASN1_item_d2i parses the ASN.1 type |it| from up to |len| bytes at |*inp|. +// It behaves like |d2i_SAMPLE_with_reuse|, except that |out| and the return +// value are cast to |ASN1_VALUE| pointers. +// +// TODO(https://crbug.com/boringssl/444): C strict aliasing forbids type-punning +// |T*| and |ASN1_VALUE*| the way this function signature does. When that bug is +// resolved, we will need to pick which type |*out| is (probably |T*|). Do not +// use a non-NULL |out| to avoid ending up on the wrong side of this question. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type, or passing a +// pointer of the wrong type into this function, are potentially exploitable +// memory errors. Callers must ensure |out| is consistent with |it|. Prefer +// using type-specific functions such as |d2i_ASN1_OCTET_STRING|. +OPENSSL_EXPORT ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **out, + const unsigned char **inp, long len, + const ASN1_ITEM *it); + +// ASN1_item_i2d marshals |val| as the ASN.1 type associated with |it|, as +// described in |i2d_SAMPLE|. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Passing a pointer of the wrong type into this function is a +// potentially exploitable memory error. Callers must ensure |val| is consistent +// with |it|. Prefer using type-specific functions such as +// |i2d_ASN1_OCTET_STRING|. +OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **outp, + const ASN1_ITEM *it); + +// ASN1_item_dup returns a newly-allocated copy of |x|, or NULL on error. |x| +// must be an object of |it|'s C type. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type, or passing a +// pointer of the wrong type into this function, are potentially exploitable +// memory errors. Prefer using type-specific functions such as +// |ASN1_STRING_dup|. +OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +// The following functions behave like |ASN1_item_d2i| but read from |in| +// instead. |out| is the same parameter as in |ASN1_item_d2i|, but written with +// |void*| instead. The return values similarly match. +// +// These functions may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: These functions do not bound how much data is read from |in|. +// Parsing an untrusted input could consume unbounded memory. +OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *out); +OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *out); + +// The following functions behave like |ASN1_item_i2d| but write to |out| +// instead. |in| is the same parameter as in |ASN1_item_i2d|, but written with +// |void*| instead. +// +// These functions may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *in); +OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *in); + +// ASN1_item_unpack parses |oct|'s contents as |it|'s ASN.1 type. It returns a +// newly-allocated instance of |it|'s C type on success, or NULL on error. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type is a +// potentially exploitable memory error. Callers must ensure the value is used +// consistently with |it|. +OPENSSL_EXPORT void *ASN1_item_unpack(const ASN1_STRING *oct, + const ASN1_ITEM *it); + +// ASN1_item_pack marshals |obj| as |it|'s ASN.1 type. If |out| is NULL, it +// returns a newly-allocated |ASN1_STRING| with the result, or NULL on error. +// If |out| is non-NULL, but |*out| is NULL, it does the same but additionally +// sets |*out| to the result. If both |out| and |*out| are non-NULL, it writes +// the result to |*out| and returns |*out| on success or NULL on error. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Passing a pointer of the wrong type into this function is a +// potentially exploitable memory error. Callers must ensure |val| is consistent +// with |it|. +OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_STRING **out); + + +// Booleans. +// +// This library represents ASN.1 BOOLEAN values with |ASN1_BOOLEAN|, which is an +// integer type. FALSE is zero, TRUE is 0xff, and an omitted OPTIONAL BOOLEAN is +// -1. + +// d2i_ASN1_BOOLEAN parses a DER-encoded ASN.1 BOOLEAN from up to |len| bytes at +// |*inp|. On success, it advances |*inp| by the number of bytes read and +// returns the result. If |out| is non-NULL, it additionally writes the result +// to |*out|. On error, it returns -1. +// +// This function does not reject trailing data in the input. This allows the +// caller to parse a sequence of concatenated structures. Callers parsing only +// one structure should check for trailing data by comparing the updated |*inp| +// with the end of the input. +// +// WARNING: This function's is slightly different from other |d2i_*| functions +// because |ASN1_BOOLEAN| is not a pointer type. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, + const unsigned char **inp, + long len); + +// i2d_ASN1_BOOLEAN marshals |a| as a DER-encoded ASN.1 BOOLEAN, as described in +// |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp); + +// The following |ASN1_ITEM|s have ASN.1 type BOOLEAN and C type |ASN1_BOOLEAN|. +// |ASN1_TBOOLEAN| and |ASN1_FBOOLEAN| must be marked OPTIONAL. When omitted, +// they are parsed as TRUE and FALSE, respectively, rather than -1. +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) + + +// Strings. +// +// ASN.1 contains a myriad of string types, as well as types that contain data +// that may be encoded into a string. This library uses a single type, +// |ASN1_STRING|, to represent most values. + +// An asn1_string_st (aka |ASN1_STRING|) represents a value of a string-like +// ASN.1 type. It contains a type field, and a byte string data field with a +// type-specific representation. +// +// When representing a string value, the type field is one of +// |V_ASN1_OCTET_STRING|, |V_ASN1_UTF8STRING|, |V_ASN1_NUMERICSTRING|, +// |V_ASN1_PRINTABLESTRING|, |V_ASN1_T61STRING|, |V_ASN1_VIDEOTEXSTRING|, +// |V_ASN1_IA5STRING|, |V_ASN1_GRAPHICSTRING|, |V_ASN1_ISO64STRING|, +// |V_ASN1_VISIBLESTRING|, |V_ASN1_GENERALSTRING|, |V_ASN1_UNIVERSALSTRING|, or +// |V_ASN1_BMPSTRING|. The data contains the byte representation of of the +// string. +// +// When representing a BIT STRING value, the type field is |V_ASN1_BIT_STRING|. +// See bit string documentation below for how the data and flags are used. +// +// When representing an INTEGER or ENUMERATED value, the type field is one of +// |V_ASN1_INTEGER|, |V_ASN1_NEG_INTEGER|, |V_ASN1_ENUMERATED|, or +// |V_ASN1_NEG_ENUMERATED|. See integer documentation below for details. +// +// When representing a GeneralizedTime or UTCTime value, the type field is +// |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, respectively. The data contains +// the DER encoding of the value. For example, the UNIX epoch would be +// "19700101000000Z" for a GeneralizedTime and "700101000000Z" for a UTCTime. +// +// |ASN1_STRING|, when stored in an |ASN1_TYPE|, may also represent an element +// with tag not directly supported by this library. See |ASN1_TYPE| for details. +// +// |ASN1_STRING| additionally has the following typedefs: |ASN1_BIT_STRING|, +// |ASN1_BMPSTRING|, |ASN1_ENUMERATED|, |ASN1_GENERALIZEDTIME|, +// |ASN1_GENERALSTRING|, |ASN1_IA5STRING|, |ASN1_INTEGER|, |ASN1_OCTET_STRING|, +// |ASN1_PRINTABLESTRING|, |ASN1_T61STRING|, |ASN1_TIME|, +// |ASN1_UNIVERSALSTRING|, |ASN1_UTCTIME|, |ASN1_UTF8STRING|, and +// |ASN1_VISIBLESTRING|. Other than |ASN1_TIME|, these correspond to universal +// ASN.1 types. |ASN1_TIME| represents a CHOICE of UTCTime and GeneralizedTime, +// with a cutoff of 2049, as used in Section 4.1.2.5 of RFC 5280. +// +// For clarity, callers are encouraged to use the appropriate typedef when +// available. They are the same type as |ASN1_STRING|, so a caller may freely +// pass them into functions expecting |ASN1_STRING|, such as +// |ASN1_STRING_length|. +// +// If a function returns an |ASN1_STRING| where the typedef or ASN.1 structure +// implies constraints on the type field, callers may assume that the type field +// is correct. However, if a function takes an |ASN1_STRING| as input, callers +// must ensure the type field matches. These invariants are not captured by the +// C type system and may not be checked at runtime. For example, callers may +// assume the output of |X509_get0_serialNumber| has type |V_ASN1_INTEGER| or +// |V_ASN1_NEG_INTEGER|. Callers must not pass a string of type +// |V_ASN1_OCTET_STRING| to |X509_set_serialNumber|. Doing so may break +// invariants on the |X509| object and break the |X509_get0_serialNumber| +// invariant. +// +// TODO(https://crbug.com/boringssl/445): This is very unfriendly. Getting the +// type field wrong should not cause memory errors, but it may do strange +// things. We should add runtime checks to anything that consumes |ASN1_STRING|s +// from the caller. +struct asn1_string_st { + int length; + int type; + unsigned char *data; + long flags; +}; + +// ASN1_STRING_FLAG_BITS_LEFT indicates, in a BIT STRING |ASN1_STRING|, that +// flags & 0x7 contains the number of padding bits added to the BIT STRING +// value. When not set, all trailing zero bits in the last byte are implicitly +// treated as padding. This behavior is deprecated and should not be used. +#define ASN1_STRING_FLAG_BITS_LEFT 0x08 + +// ASN1_STRING_type_new returns a newly-allocated empty |ASN1_STRING| object of +// type |type|, or NULL on error. +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_type_new(int type); + +// ASN1_STRING_new returns a newly-allocated empty |ASN1_STRING| object with an +// arbitrary type. Prefer one of the type-specific constructors, such as +// |ASN1_OCTET_STRING_new|, or |ASN1_STRING_type_new|. +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_new(void); + +// ASN1_STRING_free releases memory associated with |str|. +OPENSSL_EXPORT void ASN1_STRING_free(ASN1_STRING *str); + +// ASN1_STRING_copy sets |dst| to a copy of |str|. It returns one on success and +// zero on error. +OPENSSL_EXPORT int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); + +// ASN1_STRING_dup returns a newly-allocated copy of |str|, or NULL on error. +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str); + +// ASN1_STRING_type returns the type of |str|. This value will be one of the +// |V_ASN1_*| constants. +OPENSSL_EXPORT int ASN1_STRING_type(const ASN1_STRING *str); + +// ASN1_STRING_get0_data returns a pointer to |str|'s contents. Callers should +// use |ASN1_STRING_length| to determine the length of the string. The string +// may have embedded NUL bytes and may not be NUL-terminated. +OPENSSL_EXPORT const unsigned char *ASN1_STRING_get0_data( + const ASN1_STRING *str); + +// ASN1_STRING_data returns a mutable pointer to |str|'s contents. Callers +// should use |ASN1_STRING_length| to determine the length of the string. The +// string may have embedded NUL bytes and may not be NUL-terminated. +// +// Prefer |ASN1_STRING_get0_data|. +OPENSSL_EXPORT unsigned char *ASN1_STRING_data(ASN1_STRING *str); + +// ASN1_STRING_length returns the length of |str|, in bytes. +OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *str); + +// ASN1_STRING_cmp compares |a| and |b|'s type and contents. It returns an +// integer equal to, less than, or greater than zero if |a| is equal to, less +// than, or greater than |b|, respectively. This function compares by length, +// then data, then type. Note the data compared is the |ASN1_STRING| internal +// representation and the type order is arbitrary. While this comparison is +// suitable for sorting, callers should not rely on the exact order when |a| +// and |b| are different types. +// +// Note that, if |a| and |b| are INTEGERs, this comparison does not order the +// values numerically. For a numerical comparison, use |ASN1_INTEGER_cmp|. +OPENSSL_EXPORT int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + +// ASN1_STRING_set sets the contents of |str| to a copy of |len| bytes from +// |data|. It returns one on success and zero on error. If |data| is NULL, it +// updates the length and allocates the buffer as needed, but does not +// initialize the contents. +OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); + +// ASN1_STRING_set0 sets the contents of |str| to |len| bytes from |data|. It +// takes ownership of |data|, which must have been allocated with +// |OPENSSL_malloc|. +OPENSSL_EXPORT void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); + +// The following functions call |ASN1_STRING_type_new| with the corresponding +// |V_ASN1_*| constant. +OPENSSL_EXPORT ASN1_BMPSTRING *ASN1_BMPSTRING_new(void); +OPENSSL_EXPORT ASN1_GENERALSTRING *ASN1_GENERALSTRING_new(void); +OPENSSL_EXPORT ASN1_IA5STRING *ASN1_IA5STRING_new(void); +OPENSSL_EXPORT ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void); +OPENSSL_EXPORT ASN1_PRINTABLESTRING *ASN1_PRINTABLESTRING_new(void); +OPENSSL_EXPORT ASN1_T61STRING *ASN1_T61STRING_new(void); +OPENSSL_EXPORT ASN1_UNIVERSALSTRING *ASN1_UNIVERSALSTRING_new(void); +OPENSSL_EXPORT ASN1_UTF8STRING *ASN1_UTF8STRING_new(void); +OPENSSL_EXPORT ASN1_VISIBLESTRING *ASN1_VISIBLESTRING_new(void); + +// The following functions call |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_BMPSTRING_free(ASN1_BMPSTRING *str); +OPENSSL_EXPORT void ASN1_GENERALSTRING_free(ASN1_GENERALSTRING *str); +OPENSSL_EXPORT void ASN1_IA5STRING_free(ASN1_IA5STRING *str); +OPENSSL_EXPORT void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *str); +OPENSSL_EXPORT void ASN1_PRINTABLESTRING_free(ASN1_PRINTABLESTRING *str); +OPENSSL_EXPORT void ASN1_T61STRING_free(ASN1_T61STRING *str); +OPENSSL_EXPORT void ASN1_UNIVERSALSTRING_free(ASN1_UNIVERSALSTRING *str); +OPENSSL_EXPORT void ASN1_UTF8STRING_free(ASN1_UTF8STRING *str); +OPENSSL_EXPORT void ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *str); + +// The following functions parse up to |len| bytes from |*inp| as a +// DER-encoded ASN.1 value of the corresponding type, as described in +// |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_BMPSTRING *d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **out, + const uint8_t **inp, + long len); +OPENSSL_EXPORT ASN1_GENERALSTRING *d2i_ASN1_GENERALSTRING( + ASN1_GENERALSTRING **out, const uint8_t **inp, long len); +OPENSSL_EXPORT ASN1_IA5STRING *d2i_ASN1_IA5STRING(ASN1_IA5STRING **out, + const uint8_t **inp, + long len); +OPENSSL_EXPORT ASN1_OCTET_STRING *d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **out, + const uint8_t **inp, + long len); +OPENSSL_EXPORT ASN1_PRINTABLESTRING *d2i_ASN1_PRINTABLESTRING( + ASN1_PRINTABLESTRING **out, const uint8_t **inp, long len); +OPENSSL_EXPORT ASN1_T61STRING *d2i_ASN1_T61STRING(ASN1_T61STRING **out, + const uint8_t **inp, + long len); +OPENSSL_EXPORT ASN1_UNIVERSALSTRING *d2i_ASN1_UNIVERSALSTRING( + ASN1_UNIVERSALSTRING **out, const uint8_t **inp, long len); +OPENSSL_EXPORT ASN1_UTF8STRING *d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **out, + const uint8_t **inp, + long len); +OPENSSL_EXPORT ASN1_VISIBLESTRING *d2i_ASN1_VISIBLESTRING( + ASN1_VISIBLESTRING **out, const uint8_t **inp, long len); + +// The following functions marshal |in| as a DER-encoded ASN.1 value of the +// corresponding type, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_BMPSTRING(const ASN1_BMPSTRING *in, uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_GENERALSTRING(const ASN1_GENERALSTRING *in, + uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_IA5STRING(const ASN1_IA5STRING *in, uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_OCTET_STRING(const ASN1_OCTET_STRING *in, + uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_PRINTABLESTRING(const ASN1_PRINTABLESTRING *in, + uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_T61STRING(const ASN1_T61STRING *in, uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_UNIVERSALSTRING(const ASN1_UNIVERSALSTRING *in, + uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_UTF8STRING(const ASN1_UTF8STRING *in, + uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_VISIBLESTRING(const ASN1_VISIBLESTRING *in, + uint8_t **outp); + +// The following |ASN1_ITEM|s have the ASN.1 type referred to in their name and +// C type |ASN1_STRING*|. The C type may also be written as the corresponding +// typedef. +DECLARE_ASN1_ITEM(ASN1_BMPSTRING) +DECLARE_ASN1_ITEM(ASN1_GENERALSTRING) +DECLARE_ASN1_ITEM(ASN1_IA5STRING) +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING) +DECLARE_ASN1_ITEM(ASN1_PRINTABLESTRING) +DECLARE_ASN1_ITEM(ASN1_T61STRING) +DECLARE_ASN1_ITEM(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_ITEM(ASN1_UTF8STRING) +DECLARE_ASN1_ITEM(ASN1_VISIBLESTRING) + +// ASN1_OCTET_STRING_dup calls |ASN1_STRING_dup|. +OPENSSL_EXPORT ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup( + const ASN1_OCTET_STRING *a); + +// ASN1_OCTET_STRING_cmp calls |ASN1_STRING_cmp|. +OPENSSL_EXPORT int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); + +// ASN1_OCTET_STRING_set calls |ASN1_STRING_set|. +OPENSSL_EXPORT int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, + const unsigned char *data, int len); + +// ASN1_STRING_to_UTF8 converts |in| to UTF-8. On success, sets |*out| to a +// newly-allocated buffer containing the resulting string and returns the length +// of the string. The caller must call |OPENSSL_free| to release |*out| when +// done. On error, it returns a negative number. +OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, + const ASN1_STRING *in); + +// The following formats define encodings for use with functions like +// |ASN1_mbstring_copy|. Note |MBSTRING_ASC| refers to Latin-1, not ASCII. +#define MBSTRING_FLAG 0x1000 +#define MBSTRING_UTF8 (MBSTRING_FLAG) +#define MBSTRING_ASC (MBSTRING_FLAG | 1) +#define MBSTRING_BMP (MBSTRING_FLAG | 2) +#define MBSTRING_UNIV (MBSTRING_FLAG | 4) + +// DIRSTRING_TYPE contains the valid string types in an X.509 DirectoryString. +#define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING | \ + B_ASN1_UTF8STRING) + +// PKCS9STRING_TYPE contains the valid string types in a PKCS9String. +#define PKCS9STRING_TYPE (DIRSTRING_TYPE | B_ASN1_IA5STRING) + +// ASN1_mbstring_copy converts |len| bytes from |in| to an ASN.1 string. If +// |len| is -1, |in| must be NUL-terminated and the length is determined by +// |strlen|. |in| is decoded according to |inform|, which must be one of +// |MBSTRING_*|. |mask| determines the set of valid output types and is a +// bitmask containing a subset of |B_ASN1_PRINTABLESTRING|, |B_ASN1_IA5STRING|, +// |B_ASN1_T61STRING|, |B_ASN1_BMPSTRING|, |B_ASN1_UNIVERSALSTRING|, and +// |B_ASN1_UTF8STRING|, in that preference order. This function chooses the +// first output type in |mask| which can represent |in|. It interprets T61String +// as Latin-1, rather than T.61. +// +// If |mask| is zero, |DIRSTRING_TYPE| is used by default. +// +// On success, this function returns the |V_ASN1_*| constant corresponding to +// the selected output type and, if |out| and |*out| are both non-NULL, updates +// the object at |*out| with the result. If |out| is non-NULL and |*out| is +// NULL, it instead sets |*out| to a newly-allocated |ASN1_STRING| containing +// the result. If |out| is NULL, it returns the selected output type without +// constructing an |ASN1_STRING|. On error, this function returns -1. +OPENSSL_EXPORT int ASN1_mbstring_copy(ASN1_STRING **out, const uint8_t *in, + int len, int inform, unsigned long mask); + +// ASN1_mbstring_ncopy behaves like |ASN1_mbstring_copy| but returns an error if +// the input is less than |minsize| or greater than |maxsize| codepoints long. A +// |maxsize| value of zero is ignored. Note the sizes are measured in +// codepoints, not output bytes. +OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const uint8_t *in, + int len, int inform, unsigned long mask, + long minsize, long maxsize); + +// ASN1_STRING_set_by_NID behaves like |ASN1_mbstring_ncopy|, but determines +// |mask|, |minsize|, and |maxsize| based on |nid|. When |nid| is a recognized +// X.509 attribute type, it will pick a suitable ASN.1 string type and bounds. +// For most attribute types, it preferentially chooses UTF8String. If |nid| is +// unrecognized, it uses UTF8String by default. +// +// Slightly unlike |ASN1_mbstring_ncopy|, this function interprets |out| and +// returns its result as follows: If |out| is NULL, it returns a newly-allocated +// |ASN1_STRING| containing the result. If |out| is non-NULL and +// |*out| is NULL, it additionally sets |*out| to the result. If both |out| and +// |*out| are non-NULL, it instead updates the object at |*out| and returns +// |*out|. In all cases, it returns NULL on error. +// +// This function supports the following NIDs: |NID_countryName|, +// |NID_dnQualifier|, |NID_domainComponent|, |NID_friendlyName|, +// |NID_givenName|, |NID_initials|, |NID_localityName|, |NID_ms_csp_name|, +// |NID_name|, |NID_organizationalUnitName|, |NID_organizationName|, +// |NID_pkcs9_challengePassword|, |NID_pkcs9_emailAddress|, +// |NID_pkcs9_unstructuredAddress|, |NID_pkcs9_unstructuredName|, +// |NID_serialNumber|, |NID_stateOrProvinceName|, and |NID_surname|. Additional +// NIDs may be registered with |ASN1_STRING_set_by_NID|, but it is recommended +// to call |ASN1_mbstring_ncopy| directly instead. +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, + int len, int inform, + int nid); + +// STABLE_NO_MASK causes |ASN1_STRING_TABLE_add| to allow types other than +// UTF8String. +#define STABLE_NO_MASK 0x02 + +// ASN1_STRING_TABLE_add registers the corresponding parameters with |nid|, for +// use with |ASN1_STRING_set_by_NID|. It returns one on success and zero on +// error. It is an error to call this function if |nid| is a built-in NID, or +// was already registered by a previous call. +// +// WARNING: This function affects global state in the library. If two libraries +// in the same address space register information for the same OID, one call +// will fail. Prefer directly passing the desired parametrs to +// |ASN1_mbstring_copy| or |ASN1_mbstring_ncopy| instead. +OPENSSL_EXPORT int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, + unsigned long mask, + unsigned long flags); + + +// Multi-strings. +// +// A multi-string, or "MSTRING", is an |ASN1_STRING| that represents a CHOICE of +// several string or string-like types, such as X.509's DirectoryString. The +// |ASN1_STRING|'s type field determines which type is used. +// +// Multi-string types are associated with a bitmask, using the |B_ASN1_*| +// constants, which defines which types are valid. + +// B_ASN1_DIRECTORYSTRING is a bitmask of types allowed in an X.509 +// DirectoryString (RFC 5280). +#define B_ASN1_DIRECTORYSTRING \ + (B_ASN1_PRINTABLESTRING | B_ASN1_TELETEXSTRING | B_ASN1_BMPSTRING | \ + B_ASN1_UNIVERSALSTRING | B_ASN1_UTF8STRING) + +// DIRECTORYSTRING_new returns a newly-allocated |ASN1_STRING| with type -1, or +// NULL on error. The resulting |ASN1_STRING| is not a valid X.509 +// DirectoryString until initialized with a value. +OPENSSL_EXPORT ASN1_STRING *DIRECTORYSTRING_new(void); + +// DIRECTORYSTRING_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void DIRECTORYSTRING_free(ASN1_STRING *str); + +// d2i_DIRECTORYSTRING parses up to |len| bytes from |*inp| as a DER-encoded +// X.509 DirectoryString (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +// +// TODO(https://crbug.com/boringssl/449): DirectoryString's non-empty string +// requirement is not currently enforced. +OPENSSL_EXPORT ASN1_STRING *d2i_DIRECTORYSTRING(ASN1_STRING **out, + const uint8_t **inp, long len); + +// i2d_DIRECTORYSTRING marshals |in| as a DER-encoded X.509 DirectoryString (RFC +// 5280), as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_DIRECTORYSTRING(const ASN1_STRING *in, uint8_t **outp); + +// DIRECTORYSTRING is an |ASN1_ITEM| whose ASN.1 type is X.509 DirectoryString +// (RFC 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DIRECTORYSTRING) + +// B_ASN1_DISPLAYTEXT is a bitmask of types allowed in an X.509 DisplayText (RFC +// 5280). +#define B_ASN1_DISPLAYTEXT \ + (B_ASN1_IA5STRING | B_ASN1_VISIBLESTRING | B_ASN1_BMPSTRING | \ + B_ASN1_UTF8STRING) + +// DISPLAYTEXT_new returns a newly-allocated |ASN1_STRING| with type -1, or NULL +// on error. The resulting |ASN1_STRING| is not a valid X.509 DisplayText until +// initialized with a value. +OPENSSL_EXPORT ASN1_STRING *DISPLAYTEXT_new(void); + +// DISPLAYTEXT_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void DISPLAYTEXT_free(ASN1_STRING *str); + +// d2i_DISPLAYTEXT parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// DisplayText (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +// +// TODO(https://crbug.com/boringssl/449): DisplayText's size limits are not +// currently enforced. +OPENSSL_EXPORT ASN1_STRING *d2i_DISPLAYTEXT(ASN1_STRING **out, + const uint8_t **inp, long len); + +// i2d_DISPLAYTEXT marshals |in| as a DER-encoded X.509 DisplayText (RFC 5280), +// as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_DISPLAYTEXT(const ASN1_STRING *in, uint8_t **outp); + +// DISPLAYTEXT is an |ASN1_ITEM| whose ASN.1 type is X.509 DisplayText (RFC +// 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DISPLAYTEXT) + + +// Bit strings. +// +// An ASN.1 BIT STRING type represents a string of bits. The string may not +// necessarily be a whole number of bytes. BIT STRINGs occur in ASN.1 structures +// in several forms: +// +// Some BIT STRINGs represent a bitmask of named bits, such as the X.509 key +// usage extension in RFC 5280, section 4.2.1.3. For such bit strings, DER +// imposes an additional restriction that trailing zero bits are removed. Some +// functions like |ASN1_BIT_STRING_set_bit| help in maintaining this. +// +// Other BIT STRINGs are arbitrary strings of bits used as identifiers and do +// not have this constraint, such as the X.509 issuerUniqueID field. +// +// Finally, some structures use BIT STRINGs as a container for byte strings. For +// example, the signatureValue field in X.509 and the subjectPublicKey field in +// SubjectPublicKeyInfo are defined as BIT STRINGs with a value specific to the +// AlgorithmIdentifier. While some unknown algorithm could choose to store +// arbitrary bit strings, all supported algorithms use a byte string, with bit +// order matching the DER encoding. Callers interpreting a BIT STRING as a byte +// string should use |ASN1_BIT_STRING_num_bytes| instead of |ASN1_STRING_length| +// and reject bit strings that are not a whole number of bytes. +// +// This library represents BIT STRINGs as |ASN1_STRING|s with type +// |V_ASN1_BIT_STRING|. The data contains the encoded form of the BIT STRING, +// including any padding bits added to round to a whole number of bytes, but +// excluding the leading byte containing the number of padding bits. If +// |ASN1_STRING_FLAG_BITS_LEFT| is set, the bottom three bits contains the +// number of padding bits. For example, DER encodes the BIT STRING {1, 0} as +// {0x06, 0x80 = 0b10_000000}. The |ASN1_STRING| representation has data of +// {0x80} and flags of ASN1_STRING_FLAG_BITS_LEFT | 6. If +// |ASN1_STRING_FLAG_BITS_LEFT| is unset, trailing zero bits are implicitly +// removed. Callers should not rely this representation when constructing bit +// strings. The padding bits in the |ASN1_STRING| data must be zero. + +// ASN1_BIT_STRING_new calls |ASN1_STRING_type_new| with |V_ASN1_BIT_STRING|. +OPENSSL_EXPORT ASN1_BIT_STRING *ASN1_BIT_STRING_new(void); + +// ASN1_BIT_STRING_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_BIT_STRING_free(ASN1_BIT_STRING *str); + +// d2i_ASN1_BIT_STRING parses up to |len| bytes from |*inp| as a DER-encoded +// ASN.1 BIT STRING, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, + const uint8_t **inp, + long len); + +// i2d_ASN1_BIT_STRING marshals |in| as a DER-encoded ASN.1 BIT STRING, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_BIT_STRING(const ASN1_BIT_STRING *in, + uint8_t **outp); + +// c2i_ASN1_BIT_STRING decodes |len| bytes from |*inp| as the contents of a +// DER-encoded BIT STRING, excluding the tag and length. It behaves like +// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| +// bytes. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, + const uint8_t **inp, + long len); + +// i2c_ASN1_BIT_STRING encodes |in| as the contents of a DER-encoded BIT STRING, +// excluding the tag and length. If |outp| is non-NULL, it writes the result to +// |*outp|, advances |*outp| just past the output, and returns the number of +// bytes written. |*outp| must have space available for the result. If |outp| is +// NULL, it returns the number of bytes without writing anything. On error, it +// returns a value <= 0. +// +// Note this function differs slightly from |i2d_SAMPLE|. If |outp| is non-NULL +// and |*outp| is NULL, it does not allocate a new buffer. +// +// TODO(davidben): This function currently returns zero on error instead of -1, +// but it is also mostly infallible. I've currently documented <= 0 to suggest +// callers work with both. +OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *in, + uint8_t **outp); + +// ASN1_BIT_STRING is an |ASN1_ITEM| with ASN.1 type BIT STRING and C type +// |ASN1_BIT_STRING*|. +DECLARE_ASN1_ITEM(ASN1_BIT_STRING) + +// ASN1_BIT_STRING_num_bytes computes the length of |str| in bytes. If |str|'s +// bit length is a multiple of 8, it sets |*out| to the byte length and returns +// one. Otherwise, it returns zero. +// +// This function may be used with |ASN1_STRING_get0_data| to interpret |str| as +// a byte string. +OPENSSL_EXPORT int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, + size_t *out); + +// ASN1_BIT_STRING_set calls |ASN1_STRING_set|. It leaves flags unchanged, so +// the caller must set the number of unused bits. +// +// TODO(davidben): Maybe it should? Wrapping a byte string in a bit string is a +// common use case. +OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *str, + const unsigned char *d, int length); + +// ASN1_BIT_STRING_set_bit sets bit |n| of |str| to one if |value| is non-zero +// and zero if |value| is zero, resizing |str| as needed. It then truncates +// trailing zeros in |str| to align with the DER represention for a bit string +// with named bits. It returns one on success and zero on error. |n| is indexed +// beginning from zero. +OPENSSL_EXPORT int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *str, int n, + int value); + +// ASN1_BIT_STRING_get_bit returns one if bit |n| of |a| is in bounds and set, +// and zero otherwise. |n| is indexed beginning from zero. +OPENSSL_EXPORT int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *str, int n); + +// ASN1_BIT_STRING_check returns one if |str| only contains bits that are set in +// the |flags_len| bytes pointed by |flags|. Otherwise it returns zero. Bits in +// |flags| are arranged according to the DER representation, so bit 0 +// corresponds to the MSB of |flags[0]|. +OPENSSL_EXPORT int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *str, + const unsigned char *flags, + int flags_len); + + +// Integers and enumerated values. +// +// INTEGER and ENUMERATED values are represented as |ASN1_STRING|s where the +// data contains the big-endian encoding of the absolute value of the integer. +// The sign bit is encoded in the type: non-negative values have a type of +// |V_ASN1_INTEGER| or |V_ASN1_ENUMERATED|, while negative values have a type of +// |V_ASN1_NEG_INTEGER| or |V_ASN1_NEG_ENUMERATED|. Note this differs from DER's +// two's complement representation. +// +// The data in the |ASN1_STRING| may not have leading zeros. Note this means +// zero is represented as the empty string. Parsing functions will never return +// invalid representations. If an invalid input is constructed, the marshaling +// functions will skip leading zeros, however other functions, such as +// |ASN1_INTEGER_cmp| or |ASN1_INTEGER_get|, may not return the correct result. + +DEFINE_STACK_OF(ASN1_INTEGER) + +// ASN1_INTEGER_new calls |ASN1_STRING_type_new| with |V_ASN1_INTEGER|. The +// resulting object has value zero. +OPENSSL_EXPORT ASN1_INTEGER *ASN1_INTEGER_new(void); + +// ASN1_INTEGER_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_INTEGER_free(ASN1_INTEGER *str); + +// ASN1_INTEGER_dup calls |ASN1_STRING_dup|. +OPENSSL_EXPORT ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); + +// d2i_ASN1_INTEGER parses up to |len| bytes from |*inp| as a DER-encoded +// ASN.1 INTEGER, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **out, + const uint8_t **inp, long len); + +// i2d_ASN1_INTEGER marshals |in| as a DER-encoded ASN.1 INTEGER, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_INTEGER(const ASN1_INTEGER *in, uint8_t **outp); + +// c2i_ASN1_INTEGER decodes |len| bytes from |*inp| as the contents of a +// DER-encoded INTEGER, excluding the tag and length. It behaves like +// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| +// bytes. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// some invalid inputs, but this will be removed in the future. +OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **in, + const uint8_t **outp, long len); + +// i2c_ASN1_INTEGER encodes |in| as the contents of a DER-encoded INTEGER, +// excluding the tag and length. If |outp| is non-NULL, it writes the result to +// |*outp|, advances |*outp| just past the output, and returns the number of +// bytes written. |*outp| must have space available for the result. If |outp| is +// NULL, it returns the number of bytes without writing anything. On error, it +// returns a value <= 0. +// +// Note this function differs slightly from |i2d_SAMPLE|. If |outp| is non-NULL +// and |*outp| is NULL, it does not allocate a new buffer. +// +// TODO(davidben): This function currently returns zero on error instead of -1, +// but it is also mostly infallible. I've currently documented <= 0 to suggest +// callers work with both. +OPENSSL_EXPORT int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, uint8_t **outp); + +// ASN1_INTEGER is an |ASN1_ITEM| with ASN.1 type INTEGER and C type +// |ASN1_INTEGER*|. +DECLARE_ASN1_ITEM(ASN1_INTEGER) + +// ASN1_INTEGER_set_uint64 sets |a| to an INTEGER with value |v|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v); + +// ASN1_INTEGER_set sets |a| to an INTEGER with value |v|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); + +// ASN1_INTEGER_get_uint64 converts |a| to a |uint64_t|. On success, it returns +// one and sets |*out| to the result. If |a| did not fit or has the wrong type, +// it returns zero. +OPENSSL_EXPORT int ASN1_INTEGER_get_uint64(uint64_t *out, + const ASN1_INTEGER *a); + +// ASN1_INTEGER_get returns the value of |a| as a |long|, or -1 if |a| is out of +// range or the wrong type. +// +// WARNING: This function's return value cannot distinguish errors from -1. +// Prefer |ASN1_INTEGER_get_uint64|. +OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); + +// BN_to_ASN1_INTEGER sets |ai| to an INTEGER with value |bn| and returns |ai| +// on success or NULL or error. If |ai| is NULL, it returns a newly-allocated +// |ASN1_INTEGER| on success instead, which the caller must release with +// |ASN1_INTEGER_free|. +OPENSSL_EXPORT ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, + ASN1_INTEGER *ai); + +// ASN1_INTEGER_to_BN sets |bn| to the value of |ai| and returns |bn| on success +// or NULL or error. If |bn| is NULL, it returns a newly-allocated |BIGNUM| on +// success instead, which the caller must release with |BN_free|. +OPENSSL_EXPORT BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +// ASN1_INTEGER_cmp compares the values of |x| and |y|. It returns an integer +// equal to, less than, or greater than zero if |x| is equal to, less than, or +// greater than |y|, respectively. +OPENSSL_EXPORT int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, + const ASN1_INTEGER *y); + +// ASN1_ENUMERATED_new calls |ASN1_STRING_type_new| with |V_ASN1_ENUMERATED|. +// The resulting object has value zero. +OPENSSL_EXPORT ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); + +// ASN1_ENUMERATED_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_ENUMERATED_free(ASN1_ENUMERATED *str); + +// d2i_ASN1_ENUMERATED parses up to |len| bytes from |*inp| as a DER-encoded +// ASN.1 ENUMERATED, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **out, + const uint8_t **inp, + long len); + +// i2d_ASN1_ENUMERATED marshals |in| as a DER-encoded ASN.1 ENUMERATED, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_ENUMERATED(const ASN1_ENUMERATED *in, + uint8_t **outp); + +// ASN1_ENUMERATED is an |ASN1_ITEM| with ASN.1 type ENUMERATED and C type +// |ASN1_ENUMERATED*|. +DECLARE_ASN1_ITEM(ASN1_ENUMERATED) + +// ASN1_ENUMERATED_set_uint64 sets |a| to an ENUMERATED with value |v|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v); + +// ASN1_ENUMERATED_set sets |a| to an ENUMERATED with value |v|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); + +// ASN1_ENUMERATED_get_uint64 converts |a| to a |uint64_t|. On success, it +// returns one and sets |*out| to the result. If |a| did not fit or has the +// wrong type, it returns zero. +OPENSSL_EXPORT int ASN1_ENUMERATED_get_uint64(uint64_t *out, + const ASN1_ENUMERATED *a); + +// ASN1_ENUMERATED_get returns the value of |a| as a |long|, or -1 if |a| is out +// of range or the wrong type. +// +// WARNING: This function's return value cannot distinguish errors from -1. +// Prefer |ASN1_ENUMERATED_get_uint64|. +OPENSSL_EXPORT long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); + +// BN_to_ASN1_ENUMERATED sets |ai| to an ENUMERATED with value |bn| and returns +// |ai| on success or NULL or error. If |ai| is NULL, it returns a +// newly-allocated |ASN1_ENUMERATED| on success instead, which the caller must +// release with |ASN1_ENUMERATED_free|. +OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, + ASN1_ENUMERATED *ai); + +// ASN1_ENUMERATED_to_BN sets |bn| to the value of |ai| and returns |bn| on +// success or NULL or error. If |bn| is NULL, it returns a newly-allocated +// |BIGNUM| on success instead, which the caller must release with |BN_free|. +OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, + BIGNUM *bn); + + +// Time. +// +// GeneralizedTime and UTCTime values are represented as |ASN1_STRING|s. The +// type field is |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, respectively. The +// data field contains the DER encoding of the value. For example, the UNIX +// epoch would be "19700101000000Z" for a GeneralizedTime and "700101000000Z" +// for a UTCTime. +// +// ASN.1 does not define how to interpret UTCTime's two-digit year. RFC 5280 +// defines it as a range from 1950 to 2049 for X.509. The library uses the +// RFC 5280 interpretation. It does not currently enforce the restrictions from +// BER, and the additional restrictions from RFC 5280, but future versions may. +// Callers should not rely on fractional seconds and non-UTC time zones. +// +// The |ASN1_TIME| typedef is a multi-string representing the X.509 Time type, +// which is a CHOICE of GeneralizedTime and UTCTime, using UTCTime when the +// value is in range. + +// ASN1_UTCTIME_new calls |ASN1_STRING_type_new| with |V_ASN1_UTCTIME|. The +// resulting object contains empty contents and must be initialized to be a +// valid UTCTime. +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_new(void); + +// ASN1_UTCTIME_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_UTCTIME_free(ASN1_UTCTIME *str); + +// d2i_ASN1_UTCTIME parses up to |len| bytes from |*inp| as a DER-encoded +// ASN.1 UTCTime, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **out, + const uint8_t **inp, long len); + +// i2d_ASN1_UTCTIME marshals |in| as a DER-encoded ASN.1 UTCTime, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_UTCTIME(const ASN1_UTCTIME *in, uint8_t **outp); + +// ASN1_UTCTIME is an |ASN1_ITEM| with ASN.1 type UTCTime and C type +// |ASN1_UTCTIME*|. +DECLARE_ASN1_ITEM(ASN1_UTCTIME) + +// ASN1_UTCTIME_check returns one if |a| is a valid UTCTime and zero otherwise. +OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); + +// ASN1_UTCTIME_set represents |t| as a UTCTime and writes the result to |s|. It +// returns |s| on success and NULL on error. If |s| is NULL, it returns a +// newly-allocated |ASN1_UTCTIME| instead. +// +// Note this function may fail if the time is out of range for UTCTime. +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); + +// ASN1_UTCTIME_adj adds |offset_day| days and |offset_sec| seconds to |t| and +// writes the result to |s| as a UTCTime. It returns |s| on success and NULL on +// error. If |s| is NULL, it returns a newly-allocated |ASN1_UTCTIME| instead. +// +// Note this function may fail if the time overflows or is out of range for +// UTCTime. +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); + +// ASN1_UTCTIME_set_string sets |s| to a UTCTime whose contents are a copy of +// |str|. It returns one on success and zero on error or if |str| is not a valid +// UTCTime. +// +// If |s| is NULL, this function validates |str| without copying it. +OPENSSL_EXPORT int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); + +// ASN1_UTCTIME_cmp_time_t compares |s| to |t|. It returns -1 if |s| < |t|, 0 if +// they are equal, 1 if |s| > |t|, and -2 on error. +OPENSSL_EXPORT int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); + +// ASN1_GENERALIZEDTIME_new calls |ASN1_STRING_type_new| with +// |V_ASN1_GENERALIZEDTIME|. The resulting object contains empty contents and +// must be initialized to be a valid GeneralizedTime. +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_new(void); + +// ASN1_GENERALIZEDTIME_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *str); + +// d2i_ASN1_GENERALIZEDTIME parses up to |len| bytes from |*inp| as a +// DER-encoded ASN.1 GeneralizedTime, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME( + ASN1_GENERALIZEDTIME **out, const uint8_t **inp, long len); + +// i2d_ASN1_GENERALIZEDTIME marshals |in| as a DER-encoded ASN.1 +// GeneralizedTime, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_GENERALIZEDTIME(const ASN1_GENERALIZEDTIME *in, + uint8_t **outp); + +// ASN1_GENERALIZEDTIME is an |ASN1_ITEM| with ASN.1 type GeneralizedTime and C +// type |ASN1_GENERALIZEDTIME*|. +DECLARE_ASN1_ITEM(ASN1_GENERALIZEDTIME) + +// ASN1_GENERALIZEDTIME_check returns one if |a| is a valid GeneralizedTime and +// zero otherwise. +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); + +// ASN1_GENERALIZEDTIME_set represents |t| as a GeneralizedTime and writes the +// result to |s|. It returns |s| on success and NULL on error. If |s| is NULL, +// it returns a newly-allocated |ASN1_GENERALIZEDTIME| instead. +// +// Note this function may fail if the time is out of range for GeneralizedTime. +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set( + ASN1_GENERALIZEDTIME *s, time_t t); + +// ASN1_GENERALIZEDTIME_adj adds |offset_day| days and |offset_sec| seconds to +// |t| and writes the result to |s| as a GeneralizedTime. It returns |s| on +// success and NULL on error. If |s| is NULL, it returns a newly-allocated +// |ASN1_GENERALIZEDTIME| instead. +// +// Note this function may fail if the time overflows or is out of range for +// GeneralizedTime. +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj( + ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); + +// ASN1_GENERALIZEDTIME_set_string sets |s| to a GeneralizedTime whose contents +// are a copy of |str|. It returns one on success and zero on error or if |str| +// is not a valid GeneralizedTime. +// +// If |s| is NULL, this function validates |str| without copying it. +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, + const char *str); + +// B_ASN1_TIME is a bitmask of types allowed in an X.509 Time. +#define B_ASN1_TIME (B_ASN1_UTCTIME | B_ASN1_GENERALIZEDTIME) + +// ASN1_TIME_new returns a newly-allocated |ASN1_TIME| with type -1, or NULL on +// error. The resulting |ASN1_TIME| is not a valid X.509 Time until initialized +// with a value. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_new(void); + +// ASN1_TIME_free releases memory associated with |str|. +OPENSSL_EXPORT void ASN1_TIME_free(ASN1_TIME *str); + +// d2i_ASN1_TIME parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// Time (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **out, const uint8_t **inp, + long len); + +// i2d_ASN1_TIME marshals |in| as a DER-encoded X.509 Time (RFC 5280), as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_TIME(const ASN1_TIME *in, uint8_t **outp); + +// ASN1_TIME is an |ASN1_ITEM| whose ASN.1 type is X.509 Time (RFC 5280) and C +// type is |ASN1_TIME*|. +DECLARE_ASN1_ITEM(ASN1_TIME) + +// ASN1_TIME_diff computes |to| - |from|. On success, it sets |*out_days| to the +// difference in days, rounded towards zero, sets |*out_seconds| to the +// remainder, and returns one. On error, it returns zero. +// +// If |from| is before |to|, both outputs will be <= 0, with at least one +// negative. If |from| is after |to|, both will be >= 0, with at least one +// positive. If they are equal, ignoring fractional seconds, both will be zero. +// +// Note this function may fail on overflow, or if |from| or |to| cannot be +// decoded. +OPENSSL_EXPORT int ASN1_TIME_diff(int *out_days, int *out_seconds, + const ASN1_TIME *from, const ASN1_TIME *to); + +// ASN1_TIME_set represents |t| as a GeneralizedTime or UTCTime and writes +// the result to |s|. As in RFC 5280, section 4.1.2.5, it uses UTCTime when the +// time fits and GeneralizedTime otherwise. It returns |s| on success and NULL +// on error. If |s| is NULL, it returns a newly-allocated |ASN1_TIME| instead. +// +// Note this function may fail if the time is out of range for GeneralizedTime. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); + +// ASN1_TIME_adj adds |offset_day| days and |offset_sec| seconds to +// |t| and writes the result to |s|. As in RFC 5280, section 4.1.2.5, it uses +// UTCTime when the time fits and GeneralizedTime otherwise. It returns |s| on +// success and NULL on error. If |s| is NULL, it returns a newly-allocated +// |ASN1_GENERALIZEDTIME| instead. +// +// Note this function may fail if the time overflows or is out of range for +// GeneralizedTime. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, + long offset_sec); + +// ASN1_TIME_check returns one if |t| is a valid UTCTime or GeneralizedTime, and +// zero otherwise. |t|'s type determines which check is performed. This +// function does not enforce that UTCTime was used when possible. +OPENSSL_EXPORT int ASN1_TIME_check(const ASN1_TIME *t); + +// ASN1_TIME_to_generalizedtime converts |t| to a GeneralizedTime. If |out| is +// NULL, it returns a newly-allocated |ASN1_GENERALIZEDTIME| on success, or NULL +// on error. If |out| is non-NULL and |*out| is NULL, it additionally sets +// |*out| to the result. If |out| and |*out| are non-NULL, it instead updates +// the object pointed by |*out| and returns |*out| on success or NULL on error. +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime( + const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); + +// ASN1_TIME_set_string behaves like |ASN1_UTCTIME_set_string| if |str| is a +// valid UTCTime, and |ASN1_GENERALIZEDTIME_set_string| if |str| is a valid +// GeneralizedTime. If |str| is neither, it returns zero. +OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +// TODO(davidben): Expand and document function prototypes generated in macros. + + +// NULL values. +// +// This library represents the ASN.1 NULL value by a non-NULL pointer to the +// opaque type |ASN1_NULL|. An omitted OPTIONAL ASN.1 NULL value is a NULL +// pointer. Unlike other pointer types, it is not necessary to free |ASN1_NULL| +// pointers, but it is safe to do so. + +// ASN1_NULL_new returns an opaque, non-NULL pointer. It is safe to call +// |ASN1_NULL_free| on the result, but not necessary. +OPENSSL_EXPORT ASN1_NULL *ASN1_NULL_new(void); + +// ASN1_NULL_free does nothing. +OPENSSL_EXPORT void ASN1_NULL_free(ASN1_NULL *null); + +// d2i_ASN1_NULL parses a DER-encoded ASN.1 NULL value from up to |len| bytes +// at |*inp|, as described in |d2i_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_NULL *d2i_ASN1_NULL(ASN1_NULL **out, const uint8_t **inp, + long len); + +// i2d_ASN1_NULL marshals |in| as a DER-encoded ASN.1 NULL value, as described +// in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_NULL(const ASN1_NULL *in, uint8_t **outp); + +// ASN1_NULL is an |ASN1_ITEM| with ASN.1 type NULL and C type |ASN1_NULL*|. +DECLARE_ASN1_ITEM(ASN1_NULL) + + +// Object identifiers. +// +// An |ASN1_OBJECT| represents a ASN.1 OBJECT IDENTIFIER. See also obj.h for +// additional functions relating to |ASN1_OBJECT|. +// +// TODO(davidben): What's the relationship between asn1.h and obj.h? Most of +// obj.h deals with the large NID table, but then functions like |OBJ_get0_data| +// or |OBJ_dup| are general |ASN1_OBJECT| functions. + +DEFINE_STACK_OF(ASN1_OBJECT) + +// ASN1_OBJECT_create returns a newly-allocated |ASN1_OBJECT| with |len| bytes +// from |data| as the encoded OID, or NULL on error. |data| should contain the +// DER-encoded identifier, excluding the tag and length. +// +// |nid| should be |NID_undef|. Passing a NID value that does not match |data| +// will cause some functions to misbehave. |sn| and |ln| should be NULL. If +// non-NULL, they are stored as short and long names, respectively, but these +// values have no effect for |ASN1_OBJECT|s created through this function. +// +// TODO(davidben): Should we just ignore all those parameters? NIDs and names +// are only relevant for |ASN1_OBJECT|s in the obj.h table. +OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, const uint8_t *data, + int len, const char *sn, + const char *ln); + +// ASN1_OBJECT_free releases memory associated with |a|. If |a| is a static +// |ASN1_OBJECT|, returned from |OBJ_nid2obj|, this function does nothing. +OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a); + +// d2i_ASN1_OBJECT parses a DER-encoded ASN.1 OBJECT IDENTIFIER from up to |len| +// bytes at |*inp|, as described in |d2i_SAMPLE_with_reuse|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, + const uint8_t **inp, long len); + +// i2d_ASN1_OBJECT marshals |in| as a DER-encoded ASN.1 OBJECT IDENTIFIER, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, uint8_t **outp); + +// c2i_ASN1_OBJECT decodes |len| bytes from |*inp| as the contents of a +// DER-encoded OBJECT IDENTIFIER, excluding the tag and length. It behaves like +// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| +// bytes. +OPENSSL_EXPORT ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, + const uint8_t **inp, long len); + +// ASN1_OBJECT is an |ASN1_ITEM| with ASN.1 type OBJECT IDENTIFIER and C type +// |ASN1_OBJECT*|. +DECLARE_ASN1_ITEM(ASN1_OBJECT) + + +// Arbitrary elements. + +// An asn1_type_st (aka |ASN1_TYPE|) represents an arbitrary ASN.1 element, +// typically used for ANY types. It contains a |type| field and a |value| union +// dependent on |type|. +// +// WARNING: This struct has a complex representation. Callers must not construct +// |ASN1_TYPE| values manually. Use |ASN1_TYPE_set| and |ASN1_TYPE_set1| +// instead. Additionally, callers performing non-trivial operations on this type +// are encouraged to use |CBS| and |CBB| from , and +// convert to or from |ASN1_TYPE| with |d2i_ASN1_TYPE| or |i2d_ASN1_TYPE|. +// +// The |type| field corresponds to the tag of the ASN.1 element being +// represented: +// +// If |type| is a |V_ASN1_*| constant for an ASN.1 string-like type, as defined +// by |ASN1_STRING|, the tag matches the constant. |value| contains an +// |ASN1_STRING| pointer (equivalently, one of the more specific typedefs). See +// |ASN1_STRING| for details on the representation. Unlike |ASN1_STRING|, +// |ASN1_TYPE| does not use the |V_ASN1_NEG| flag for negative INTEGER and +// ENUMERATE values. For a negative value, the |ASN1_TYPE|'s |type| will be +// |V_ASN1_INTEGER| or |V_ASN1_ENUMERATED|, but |value| will an |ASN1_STRING| +// whose |type| is |V_ASN1_NEG_INTEGER| or |V_ASN1_NEG_ENUMERATED|. +// +// If |type| is |V_ASN1_OBJECT|, the tag is OBJECT IDENTIFIER and |value| +// contains an |ASN1_OBJECT| pointer. +// +// If |type| is |V_ASN1_NULL|, the tag is NULL. |value| contains a NULL pointer. +// +// If |type| is |V_ASN1_BOOLEAN|, the tag is BOOLEAN. |value| contains an +// |ASN1_BOOLEAN|. +// +// If |type| is |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or |V_ASN1_OTHER|, the tag is +// SEQUENCE, SET, or some non-universal tag, respectively. |value| is an +// |ASN1_STRING| containing the entire element, including the tag and length. +// The |ASN1_STRING|'s |type| field matches the containing |ASN1_TYPE|'s |type|. +// +// Other positive values of |type|, up to |V_ASN1_MAX_UNIVERSAL|, correspond to +// universal primitive tags not directly supported by this library. |value| is +// an |ASN1_STRING| containing the body of the element, excluding the tag +// and length. The |ASN1_STRING|'s |type| field matches the containing +// |ASN1_TYPE|'s |type|. +struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + // set and sequence are left complete and still contain the entire element. + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +}; + +DEFINE_STACK_OF(ASN1_TYPE) + +// ASN1_TYPE_new returns a newly-allocated |ASN1_TYPE|, or NULL on allocation +// failure. The resulting object has type -1 and must be initialized to be +// a valid ANY value. +OPENSSL_EXPORT ASN1_TYPE *ASN1_TYPE_new(void); + +// ASN1_TYPE_free releases memory associated with |a|. +OPENSSL_EXPORT void ASN1_TYPE_free(ASN1_TYPE *a); + +// d2i_ASN1_TYPE parses up to |len| bytes from |*inp| as an ASN.1 value of any +// type, as described in |d2i_SAMPLE_with_reuse|. Note this function only +// validates primitive, universal types supported by this library. Values of +// type |V_ASN1_SEQUENCE|, |V_ASN1_SET|, |V_ASN1_OTHER|, or an unsupported +// primitive type must be validated by the caller when interpreting. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **out, const uint8_t **inp, + long len); + +// i2d_ASN1_TYPE marshals |in| as DER, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_TYPE(const ASN1_TYPE *in, uint8_t **outp); + +// ASN1_ANY is an |ASN1_ITEM| with ASN.1 type ANY and C type |ASN1_TYPE*|. Note +// the |ASN1_ITEM| name and C type do not match. +DECLARE_ASN1_ITEM(ASN1_ANY) + +// ASN1_TYPE_get returns the type of |a|, which will be one of the |V_ASN1_*| +// constants, or zero if |a| is not fully initialized. +OPENSSL_EXPORT int ASN1_TYPE_get(const ASN1_TYPE *a); + +// ASN1_TYPE_set sets |a| to an |ASN1_TYPE| of type |type| and value |value|, +// releasing the previous contents of |a|. +// +// If |type| is |V_ASN1_BOOLEAN|, |a| is set to FALSE if |value| is NULL and +// TRUE otherwise. If setting |a| to TRUE, |value| may be an invalid pointer, +// such as (void*)1. +// +// If |type| is |V_ASN1_NULL|, |value| must be NULL. +// +// For other values of |type|, this function takes ownership of |value|, which +// must point to an object of the corresponding type. See |ASN1_TYPE| for +// details. +OPENSSL_EXPORT void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); + +// ASN1_TYPE_set1 behaves like |ASN1_TYPE_set| except it does not take ownership +// of |value|. It returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); + +// ASN1_TYPE_cmp returns zero if |a| and |b| are equal and some non-zero value +// otherwise. Note this function can only be used for equality checks, not an +// ordering. +OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +// d2i_ASN1_SEQUENCE_ANY parses up to |len| bytes from |*inp| as a DER-encoded +// ASN.1 SEQUENCE OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The +// resulting |ASN1_SEQUENCE_ANY| owns its contents and thus must be released +// with |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_SEQUENCE_ANY *d2i_ASN1_SEQUENCE_ANY(ASN1_SEQUENCE_ANY **out, + const uint8_t **inp, + long len); + +// i2d_ASN1_SEQUENCE_ANY marshals |in| as a DER-encoded SEQUENCE OF ANY +// structure, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *in, + uint8_t **outp); + +// d2i_ASN1_SET_ANY parses up to |len| bytes from |*inp| as a DER-encoded ASN.1 +// SET OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The resulting +// |ASN1_SEQUENCE_ANY| owns its contents and thus must be released with +// |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_SEQUENCE_ANY *d2i_ASN1_SET_ANY(ASN1_SEQUENCE_ANY **out, + const uint8_t **inp, + long len); + +// i2d_ASN1_SET_ANY marshals |in| as a DER-encoded SET OF ANY structure, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_ASN1_SET_ANY(const ASN1_SEQUENCE_ANY *in, + uint8_t **outp); + + +// Human-readable output. +// +// The following functions output types in some human-readable format. These +// functions may be used for debugging and logging. However, the output should +// not be consumed programmatically. They may be ambiguous or lose information. + +// ASN1_UTCTIME_print writes a human-readable representation of |a| to |out|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *out, const ASN1_UTCTIME *a); + +// ASN1_GENERALIZEDTIME_print writes a human-readable representation of |a| to +// |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *out, + const ASN1_GENERALIZEDTIME *a); + +// ASN1_TIME_print writes a human-readable representation of |a| to |out|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_TIME_print(BIO *out, const ASN1_TIME *a); + +// ASN1_STRING_print writes a human-readable representation of |str| to |out|. +// It returns one on success and zero on error. Unprintable characters are +// replaced with '.'. +OPENSSL_EXPORT int ASN1_STRING_print(BIO *out, const ASN1_STRING *str); + +// ASN1_STRFLGS_ESC_2253 causes characters to be escaped as in RFC 2253, section +// 2.4. +#define ASN1_STRFLGS_ESC_2253 1 + +// ASN1_STRFLGS_ESC_CTRL causes all control characters to be escaped. +#define ASN1_STRFLGS_ESC_CTRL 2 + +// ASN1_STRFLGS_ESC_MSB causes all characters above 127 to be escaped. +#define ASN1_STRFLGS_ESC_MSB 4 + +// ASN1_STRFLGS_ESC_QUOTE causes the string to be surrounded by quotes, rather +// than using backslashes, when characters are escaped. Fewer characters will +// require escapes in this case. +#define ASN1_STRFLGS_ESC_QUOTE 8 + +// ASN1_STRFLGS_UTF8_CONVERT causes the string to be encoded as UTF-8, with each +// byte in the UTF-8 encoding treated as an individual character for purposes of +// escape sequences. If not set, each Unicode codepoint in the string is treated +// as a character, with wide characters escaped as "\Uxxxx" or "\Wxxxxxxxx". +// Note this can be ambiguous if |ASN1_STRFLGS_ESC_*| are all unset. In that +// case, backslashes are not escaped, but wide characters are. +#define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +// ASN1_STRFLGS_IGNORE_TYPE causes the string type to be ignored. The +// |ASN1_STRING| in-memory representation will be printed directly. +#define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +// ASN1_STRFLGS_SHOW_TYPE causes the string type to be included in the output. +#define ASN1_STRFLGS_SHOW_TYPE 0x40 + +// ASN1_STRFLGS_DUMP_ALL causes all strings to be printed as a hexdump, using +// RFC 2253 hexstring notation, such as "#0123456789ABCDEF". +#define ASN1_STRFLGS_DUMP_ALL 0x80 + +// ASN1_STRFLGS_DUMP_UNKNOWN behaves like |ASN1_STRFLGS_DUMP_ALL| but only +// applies to values of unknown type. If unset, unknown values will print +// their contents as single-byte characters with escape sequences. +#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +// ASN1_STRFLGS_DUMP_DER causes hexdumped strings (as determined by +// |ASN1_STRFLGS_DUMP_ALL| or |ASN1_STRFLGS_DUMP_UNKNOWN|) to print the entire +// DER element as in RFC 2253, rather than only the contents of the +// |ASN1_STRING|. +#define ASN1_STRFLGS_DUMP_DER 0x200 + +// ASN1_STRFLGS_RFC2253 causes the string to be escaped as in RFC 2253, +// additionally escaping control characters. +#define ASN1_STRFLGS_RFC2253 \ + (ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +// ASN1_STRING_print_ex writes a human-readable representation of |str| to +// |out|. It returns the number of bytes written on success and -1 on error. If +// |out| is NULL, it returns the number of bytes it would have written, without +// writing anything. +// +// The |flags| should be a combination of combination of |ASN1_STRFLGS_*| +// constants. See the documentation for each flag for how it controls the +// output. If unsure, use |ASN1_STRFLGS_RFC2253|. +OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, + unsigned long flags); + +// ASN1_STRING_print_ex_fp behaves like |ASN1_STRING_print_ex| but writes to a +// |FILE| rather than a |BIO|. +OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, + unsigned long flags); + +// i2a_ASN1_INTEGER writes a human-readable representation of |a| to |bp|. It +// returns the number of bytes written on success, or a negative number on +// error. On error, this function may have written a partial output to |bp|. +OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); + +// i2a_ASN1_ENUMERATED writes a human-readable representation of |a| to |bp|. It +// returns the number of bytes written on success, or a negative number on +// error. On error, this function may have written a partial output to |bp|. +OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); + +// i2a_ASN1_OBJECT writes a human-readable representation of |a| to |bp|. It +// returns the number of bytes written on success, or a negative number on +// error. On error, this function may have written a partial output to |bp|. +OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); + +// i2a_ASN1_STRING writes a text representation of |a|'s contents to |bp|. It +// returns the number of bytes written on success, or a negative number on +// error. On error, this function may have written a partial output to |bp|. +// |type| is ignored. +// +// This function does not decode |a| into a Unicode string. It only hex-encodes +// the internal representation of |a|. This is suitable for printing an OCTET +// STRING, but may not be human-readable for any other string type. +OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); + +// i2t_ASN1_OBJECT calls |OBJ_obj2txt| with |always_return_oid| set to zero. +OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf, int buf_len, + const ASN1_OBJECT *a); + + +// Low-level encoding functions. + +// ASN1_get_object parses a BER element from up to |max_len| bytes at |*inp|. It +// returns |V_ASN1_CONSTRUCTED| if it successfully parsed a constructed element, +// zero if it successfully parsed a primitive element, and 0x80 on error. On +// success, it additionally advances |*inp| to the element body, sets +// |*out_length|, |*out_tag|, and |*out_class| to the element's length, tag +// number, and tag class, respectively, +// +// Unlike OpenSSL, this function does not support indefinite-length elements. +// +// This function is difficult to use correctly. Use |CBS_get_asn1| and related +// functions from bytestring.h. +// +// TODO(https://crbug.com/boringssl/354): Remove support for non-minimal +// lengths. +OPENSSL_EXPORT int ASN1_get_object(const unsigned char **inp, long *out_length, + int *out_tag, int *out_class, long max_len); + +// ASN1_put_object writes the header for a DER or BER element to |*outp| and +// advances |*outp| by the number of bytes written. The caller is responsible +// for ensuring |*outp| has enough space for the output. The header describes an +// element with length |length|, tag number |tag|, and class |xclass|. |xclass| +// should be one of the |V_ASN1_*| tag class constants. The element is primitive +// if |constructed| is zero and constructed if it is one or two. If +// |constructed| is two, |length| is ignored and the element uses +// indefinite-length encoding. +// +// Use |CBB_add_asn1| instead. +OPENSSL_EXPORT void ASN1_put_object(unsigned char **outp, int constructed, + int length, int tag, int xclass); + +// ASN1_put_eoc writes two zero bytes to |*outp|, advances |*outp| to point past +// those bytes, and returns two. +// +// Use definite-length encoding instead. +OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **outp); + +// ASN1_object_size returns the number of bytes needed to encode a DER or BER +// value with length |length| and tag number |tag|, or -1 on error. |tag| should +// not include the constructed bit or tag class. If |constructed| is zero or +// one, the result uses a definite-length encoding with minimally-encoded +// length, as in DER. If |constructed| is two, the result uses BER +// indefinite-length encoding. +// +// Use |CBB_add_asn1| instead. +OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); + + +// Function declaration macros. +// +// The following macros declare functions for ASN.1 types. Prefer writing the +// prototypes directly. Particularly when |type|, |itname|, or |name| differ, +// the macros can be difficult to understand. + +#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, \ + long len); \ + OPENSSL_EXPORT int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, \ + long len); \ + OPENSSL_EXPORT int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + OPENSSL_EXPORT type *name##_new(void); \ + OPENSSL_EXPORT void name##_free(type *a); + + +// Deprecated functions. + +// ASN1_PRINTABLE_type interprets |len| bytes from |s| as a Latin-1 string. It +// returns the first of |V_ASN1_PRINTABLESTRING|, |V_ASN1_IA5STRING|, or +// |V_ASN1_T61STRING| that can represent every character. If |len| is negative, +// |strlen(s)| is used instead. +// +// TODO(davidben): Remove this once all copies of Conscrypt have been updated +// past https://github.com/google/conscrypt/pull/1032. +OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int len); + +// ASN1_STRING_set_default_mask does nothing. +OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); + +// ASN1_STRING_set_default_mask_asc returns one. +OPENSSL_EXPORT int ASN1_STRING_set_default_mask_asc(const char *p); + +// ASN1_STRING_get_default_mask returns |B_ASN1_UTF8STRING|. +OPENSSL_EXPORT unsigned long ASN1_STRING_get_default_mask(void); + +// ASN1_STRING_TABLE_cleanup does nothing. +OPENSSL_EXPORT void ASN1_STRING_TABLE_cleanup(void); + +// M_ASN1_* are legacy aliases for various |ASN1_STRING| functions. Use the +// functions themselves. +#define M_ASN1_STRING_length(x) ASN1_STRING_length(x) +#define M_ASN1_STRING_type(x) ASN1_STRING_type(x) +#define M_ASN1_STRING_data(x) ASN1_STRING_data(x) +#define M_ASN1_BIT_STRING_new() ASN1_BIT_STRING_new() +#define M_ASN1_BIT_STRING_free(a) ASN1_BIT_STRING_free(a) +#define M_ASN1_BIT_STRING_dup(a) ASN1_STRING_dup(a) +#define M_ASN1_BIT_STRING_cmp(a, b) ASN1_STRING_cmp(a, b) +#define M_ASN1_BIT_STRING_set(a, b, c) ASN1_BIT_STRING_set(a, b, c) +#define M_ASN1_INTEGER_new() ASN1_INTEGER_new() +#define M_ASN1_INTEGER_free(a) ASN1_INTEGER_free(a) +#define M_ASN1_INTEGER_dup(a) ASN1_INTEGER_dup(a) +#define M_ASN1_INTEGER_cmp(a, b) ASN1_INTEGER_cmp(a, b) +#define M_ASN1_ENUMERATED_new() ASN1_ENUMERATED_new() +#define M_ASN1_ENUMERATED_free(a) ASN1_ENUMERATED_free(a) +#define M_ASN1_ENUMERATED_dup(a) ASN1_STRING_dup(a) +#define M_ASN1_ENUMERATED_cmp(a, b) ASN1_STRING_cmp(a, b) +#define M_ASN1_OCTET_STRING_new() ASN1_OCTET_STRING_new() +#define M_ASN1_OCTET_STRING_free(a) ASN1_OCTET_STRING_free() +#define M_ASN1_OCTET_STRING_dup(a) ASN1_OCTET_STRING_dup(a) +#define M_ASN1_OCTET_STRING_cmp(a, b) ASN1_OCTET_STRING_cmp(a, b) +#define M_ASN1_OCTET_STRING_set(a, b, c) ASN1_OCTET_STRING_set(a, b, c) +#define M_ASN1_OCTET_STRING_print(a, b) ASN1_STRING_print(a, b) +#define M_ASN1_PRINTABLESTRING_new() ASN1_PRINTABLESTRING_new() +#define M_ASN1_PRINTABLESTRING_free(a) ASN1_PRINTABLESTRING_free(a) +#define M_ASN1_IA5STRING_new() ASN1_IA5STRING_new() +#define M_ASN1_IA5STRING_free(a) ASN1_IA5STRING_free(a) +#define M_ASN1_IA5STRING_dup(a) ASN1_STRING_dup(a) +#define M_ASN1_UTCTIME_new() ASN1_UTCTIME_new() +#define M_ASN1_UTCTIME_free(a) ASN1_UTCTIME_free(a) +#define M_ASN1_UTCTIME_dup(a) ASN1_STRING_dup(a) +#define M_ASN1_T61STRING_new() ASN1_T61STRING_new() +#define M_ASN1_T61STRING_free(a) ASN1_T61STRING_free(a) +#define M_ASN1_GENERALIZEDTIME_new() ASN1_GENERALIZEDTIME_new() +#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_GENERALIZEDTIME_free(a) +#define M_ASN1_GENERALIZEDTIME_dup(a) ASN1_STRING_dup(a) +#define M_ASN1_GENERALSTRING_new() ASN1_GENERALSTRING_new() +#define M_ASN1_GENERALSTRING_free(a) ASN1_GENERALSTRING_free(a) +#define M_ASN1_UNIVERSALSTRING_new() ASN1_UNIVERSALSTRING_new() +#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_UNIVERSALSTRING_free(a) +#define M_ASN1_BMPSTRING_new() ASN1_BMPSTRING_new() +#define M_ASN1_BMPSTRING_free(a) ASN1_BMPSTRING_free(a) +#define M_ASN1_VISIBLESTRING_new() ASN1_VISIBLESTRING_new() +#define M_ASN1_VISIBLESTRING_free(a) ASN1_VISIBLESTRING_free(a) +#define M_ASN1_UTF8STRING_new() ASN1_UTF8STRING_new() +#define M_ASN1_UTF8STRING_free(a) ASN1_UTF8STRING_free(a) + +// B_ASN1_PRINTABLE is a bitmask for an ad-hoc subset of string-like types. Note +// the presence of |B_ASN1_UNKNOWN| means it includes types which |ASN1_tag2bit| +// maps to |B_ASN1_UNKNOWN|. +// +// Do not use this. Despite the name, it has no connection to PrintableString or +// printable characters. See https://crbug.com/boringssl/412. +#define B_ASN1_PRINTABLE \ + (B_ASN1_NUMERICSTRING | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | \ + B_ASN1_IA5STRING | B_ASN1_BIT_STRING | B_ASN1_UNIVERSALSTRING | \ + B_ASN1_BMPSTRING | B_ASN1_UTF8STRING | B_ASN1_SEQUENCE | B_ASN1_UNKNOWN) + +// ASN1_PRINTABLE_new returns a newly-allocated |ASN1_STRING| with type -1, or +// NULL on error. The resulting |ASN1_STRING| is not a valid ASN.1 value until +// initialized with a value. +OPENSSL_EXPORT ASN1_STRING *ASN1_PRINTABLE_new(void); + +// ASN1_PRINTABLE_free calls |ASN1_STRING_free|. +OPENSSL_EXPORT void ASN1_PRINTABLE_free(ASN1_STRING *str); + +// d2i_ASN1_PRINTABLE parses up to |len| bytes from |*inp| as a DER-encoded +// CHOICE of an ad-hoc subset of string-like types, as described in +// |d2i_SAMPLE_with_reuse|. +// +// Do not use this. Despite, the name it has no connection to PrintableString or +// printable characters. See https://crbug.com/boringssl/412. +// +// TODO(https://crbug.com/boringssl/354): This function currently also accepts +// BER, but this will be removed in the future. +OPENSSL_EXPORT ASN1_STRING *d2i_ASN1_PRINTABLE(ASN1_STRING **out, + const uint8_t **inp, long len); + +// i2d_ASN1_PRINTABLE marshals |in| as DER, as described in |i2d_SAMPLE|. +// +// Do not use this. Despite the name, it has no connection to PrintableString or +// printable characters. See https://crbug.com/boringssl/412. +OPENSSL_EXPORT int i2d_ASN1_PRINTABLE(const ASN1_STRING *in, uint8_t **outp); + +// ASN1_PRINTABLE is an |ASN1_ITEM| whose ASN.1 type is a CHOICE of an ad-hoc +// subset of string-like types, and whose C type is |ASN1_STRING*|. +// +// Do not use this. Despite the name, it has no connection to PrintableString or +// printable characters. See https://crbug.com/boringssl/412. +DECLARE_ASN1_ITEM(ASN1_PRINTABLE) + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free) +BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free) +BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define ASN1_R_ASN1_LENGTH_MISMATCH 100 +#define ASN1_R_AUX_ERROR 101 +#define ASN1_R_BAD_GET_ASN1_OBJECT_CALL 102 +#define ASN1_R_BAD_OBJECT_HEADER 103 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 104 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CONTEXT_NOT_INITIALISED 108 +#define ASN1_R_DECODE_ERROR 109 +#define ASN1_R_DEPTH_EXCEEDED 110 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 111 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 113 +#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 114 +#define ASN1_R_EXPECTING_AN_INTEGER 115 +#define ASN1_R_EXPECTING_AN_OBJECT 116 +#define ASN1_R_EXPECTING_A_BOOLEAN 117 +#define ASN1_R_EXPECTING_A_TIME 118 +#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +#define ASN1_R_FIELD_MISSING 121 +#define ASN1_R_FIRST_NUM_TOO_LARGE 122 +#define ASN1_R_HEADER_TOO_LONG 123 +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 124 +#define ASN1_R_ILLEGAL_BOOLEAN 125 +#define ASN1_R_ILLEGAL_CHARACTERS 126 +#define ASN1_R_ILLEGAL_FORMAT 127 +#define ASN1_R_ILLEGAL_HEX 128 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 129 +#define ASN1_R_ILLEGAL_INTEGER 130 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 131 +#define ASN1_R_ILLEGAL_NULL 132 +#define ASN1_R_ILLEGAL_NULL_VALUE 133 +#define ASN1_R_ILLEGAL_OBJECT 134 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 135 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 136 +#define ASN1_R_ILLEGAL_TAGGED_ANY 137 +#define ASN1_R_ILLEGAL_TIME_VALUE 138 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 139 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 140 +#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 141 +#define ASN1_R_INVALID_BMPSTRING 142 +#define ASN1_R_INVALID_DIGIT 143 +#define ASN1_R_INVALID_MODIFIER 144 +#define ASN1_R_INVALID_NUMBER 145 +#define ASN1_R_INVALID_OBJECT_ENCODING 146 +#define ASN1_R_INVALID_SEPARATOR 147 +#define ASN1_R_INVALID_TIME_FORMAT 148 +#define ASN1_R_INVALID_UNIVERSALSTRING 149 +#define ASN1_R_INVALID_UTF8STRING 150 +#define ASN1_R_LIST_ERROR 151 +#define ASN1_R_MISSING_ASN1_EOS 152 +#define ASN1_R_MISSING_EOC 153 +#define ASN1_R_MISSING_SECOND_NUMBER 154 +#define ASN1_R_MISSING_VALUE 155 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 156 +#define ASN1_R_MSTRING_WRONG_TAG 157 +#define ASN1_R_NESTED_ASN1_ERROR 158 +#define ASN1_R_NESTED_ASN1_STRING 159 +#define ASN1_R_NON_HEX_CHARACTERS 160 +#define ASN1_R_NOT_ASCII_FORMAT 161 +#define ASN1_R_NOT_ENOUGH_DATA 162 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 163 +#define ASN1_R_NULL_IS_WRONG_LENGTH 164 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 165 +#define ASN1_R_ODD_NUMBER_OF_CHARS 166 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 167 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 168 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 169 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 170 +#define ASN1_R_SHORT_LINE 171 +#define ASN1_R_STREAMING_NOT_SUPPORTED 172 +#define ASN1_R_STRING_TOO_LONG 173 +#define ASN1_R_STRING_TOO_SHORT 174 +#define ASN1_R_TAG_VALUE_TOO_HIGH 175 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 176 +#define ASN1_R_TOO_LONG 177 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 178 +#define ASN1_R_TYPE_NOT_PRIMITIVE 179 +#define ASN1_R_UNEXPECTED_EOC 180 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 181 +#define ASN1_R_UNKNOWN_FORMAT 182 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 183 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 184 +#define ASN1_R_UNKNOWN_TAG 185 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 186 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 187 +#define ASN1_R_UNSUPPORTED_TYPE 188 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 189 +#define ASN1_R_WRONG_TAG 190 +#define ASN1_R_WRONG_TYPE 191 +#define ASN1_R_NESTED_TOO_DEEP 192 +#define ASN1_R_BAD_TEMPLATE 193 +#define ASN1_R_INVALID_BIT_STRING_PADDING 194 +#define ASN1_R_WRONG_INTEGER_TYPE 195 +#define ASN1_R_INVALID_INTEGER 196 + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1_mac.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1_mac.h new file mode 100644 index 00000000..55cb2916 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1_mac.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_asn1.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h new file mode 100644 index 00000000..b6d10795 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h @@ -0,0 +1,715 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +#define HEADER_ASN1T_H + +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_asn1.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy ASN.1 library template definitions. + * + * This header is used to define new types in OpenSSL's ASN.1 implementation. It + * is deprecated and will be unexported from the library. Use the new |CBS| and + * |CBB| library in instead. */ + + +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + + +/* Macros for start and end of ASN1_ITEM definition */ + +#define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +#define ASN1_ITEM_end(itname) \ + }; + +/* Macros to aid ASN1 template writing */ + +#define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +#define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + + +/* This is a ASN1 type which just embeds a template */ + +/* This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +#define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +#define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + + +/* This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +#define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +#define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +#define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* used when the structure is combined with the parent */ + +#define ASN1_EX_COMBINE(flags, tag, type) { \ + (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +#define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +#define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +/* Plain simple type */ +#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +#define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +#define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +#define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +#define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* Macros for the ASN1_ADB structure */ + +#define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +#define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +#define ADB_ENTRY(val, template) {val, template} + +#define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* This is the ASN1 template structure that defines + * a wrapper round the actual type. It determines the + * actual position of the field in the value structure, + * various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { +unsigned long flags; /* Various flags */ +long tag; /* tag, not used if no tagging */ +unsigned long offset; /* Offset of this field in structure */ +const char *field_name; /* Field name */ +ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +#define ASN1_TEMPLATE_item(t) (t->item_ptr) +#define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + ASN1_MUST_BE_NULL *unused; + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + int value; /* NID for an object */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +#define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +#define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +#define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* These flags mean the tag should be taken from the + * tag field. If EXPLICIT then the underlying type + * is used for the inner tag. + */ + +/* IMPLICIT tagging */ +#define ASN1_TFLG_IMPTAG (0x1 << 3) + + +/* EXPLICIT tagging, inner tag from underlying type */ +#define ASN1_TFLG_EXPTAG (0x2 << 3) + +#define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* If tagging is in force these determine the + * type of tag to use. Otherwise the tag is + * determined by the underlying type. These + * values reflect the actual octet format. + */ + +/* Universal tag */ +#define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +#define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +#define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +#define ASN1_TFLG_PRIVATE (0x3<<6) + +#define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* These are for ANY DEFINED BY type. In this case + * the 'item' field points to an ASN1_ADB structure + * which contains a table of values to decode the + * relevant type + */ + +#define ASN1_TFLG_ADB_MASK (0x3<<8) + +#define ASN1_TFLG_ADB_OID (0x1<<8) + +/* This flag means a parent structure is passed + * instead of the field: this is useful is a + * SEQUENCE is being combined with a CHOICE for + * example. Since this means the structure and + * item name will differ we need to use the + * ASN1_CHOICE_END_name() macro for example. + */ + +#define ASN1_TFLG_COMBINE (0x1<<10) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { +char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ +long utype; /* underlying type */ +const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ +long tcount; /* Number of templates if SEQUENCE or CHOICE */ +const void *funcs; /* functions that handle this type */ +long size; /* Structure size (usually)*/ +const char *sname; /* Structure name */ +}; + +/* These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + */ + +#define ASN1_ITYPE_PRIMITIVE 0x0 + +#define ASN1_ITYPE_SEQUENCE 0x1 + +#define ASN1_ITYPE_CHOICE 0x2 + +#define ASN1_ITYPE_EXTERN 0x4 + +#define ASN1_ITYPE_MSTRING 0x5 + +/* Cache for ASN1 tag and length, so we + * don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st{ + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE * ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); +typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + /* asn1_ex_print is unused. */ + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +/* This is the ASN1_AUX structure: it handles various + * miscellaneous requirements. For example the use of + * reference counts and an informational callback. + * + * The "informational callback" is called at various + * points during the ASN1 encoding and decoding. It can + * be used to provide minor customisation of the structures + * used. This is most useful where the supplied routines + * *almost* do the right thing but need some extra help + * at a few points. If the callback returns zero then + * it is assumed a fatal error has occurred and the + * main operation should be abandoned. + * + * If major changes in the default behaviour are required + * then an external type is more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +#define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +#define ASN1_AFLG_ENCODING 2 + +/* operation values for asn1_cb */ + +#define ASN1_OP_NEW_PRE 0 +#define ASN1_OP_NEW_POST 1 +#define ASN1_OP_FREE_PRE 2 +#define ASN1_OP_FREE_POST 3 +#define ASN1_OP_D2I_PRE 4 +#define ASN1_OP_D2I_POST 5 +/* ASN1_OP_I2D_PRE and ASN1_OP_I2D_POST are not supported. We leave the + * constants undefined so code relying on them does not accidentally compile. */ +#define ASN1_OP_PRINT_PRE 8 +#define ASN1_OP_PRINT_POST 9 +#define ASN1_OP_STREAM_PRE 10 +#define ASN1_OP_STREAM_POST 11 +#define ASN1_OP_DETACHED_PRE 12 +#define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +#define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +/* This includes evil casts to remove const: they will go away when full + * ASN1 constification is done. + */ +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) + +DEFINE_STACK_OF(ASN1_VALUE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h new file mode 100644 index 00000000..b34ac896 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h @@ -0,0 +1,631 @@ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_BASE_H +#define OPENSSL_HEADER_BASE_H +#if defined(__APPLE__) && defined(__i386__) +#define OPENSSL_NO_ASM +#endif + +#define BORINGSSL_PREFIX CNIOBoringSSL + + +// This file should be the first included by all BoringSSL headers. + +#include +#include +#include + +#if defined(__MINGW32__) +// stdio.h is needed on MinGW for __MINGW_PRINTF_FORMAT. +#include +#endif + +#if defined(__APPLE__) +#include +#endif + +// Include a BoringSSL-only header so consumers including this header without +// setting up include paths do not accidentally pick up the system +// opensslconf.h. +#include "CNIOBoringSSL_is_boringssl.h" +#include "CNIOBoringSSL_opensslconf.h" + +#if defined(BORINGSSL_PREFIX) +#include "CNIOBoringSSL_boringssl_prefix_symbols.h" +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) +#define OPENSSL_64_BIT +#define OPENSSL_X86_64 +#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86) +#define OPENSSL_32_BIT +#define OPENSSL_X86 +#elif defined(__AARCH64EL__) || defined(_M_ARM64) +#define OPENSSL_64_BIT +#define OPENSSL_AARCH64 +#elif defined(__ARMEL__) || defined(_M_ARM) +#define OPENSSL_32_BIT +#define OPENSSL_ARM +#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN) +#define OPENSSL_64_BIT +#define OPENSSL_PPC64LE +#elif defined(__MIPSEL__) && !defined(__LP64__) +#define OPENSSL_32_BIT +#define OPENSSL_MIPS +#elif defined(__MIPSEL__) && defined(__LP64__) +#define OPENSSL_64_BIT +#define OPENSSL_MIPS64 +#elif defined(__riscv) && __SIZEOF_POINTER__ == 8 +#define OPENSSL_64_BIT +#elif defined(__riscv) && __SIZEOF_POINTER__ == 4 +#define OPENSSL_32_BIT +#elif defined(__pnacl__) +#define OPENSSL_32_BIT +#define OPENSSL_PNACL +#elif defined(__wasm__) +#define OPENSSL_32_BIT +#elif defined(__asmjs__) +#define OPENSSL_32_BIT +#elif defined(__myriad2__) +#define OPENSSL_32_BIT +#else +// Note BoringSSL only supports standard 32-bit and 64-bit two's-complement, +// little-endian architectures. Functions will not produce the correct answer +// on other systems. Run the crypto_test binary, notably +// crypto/compiler_test.cc, before adding a new architecture. +#error "Unknown target CPU" +#endif + +#if defined(__APPLE__) +#define OPENSSL_APPLE +// Note |TARGET_OS_MAC| is set for all Apple OS variants. |TARGET_OS_OSX| +// targets macOS specifically. +#if defined(TARGET_OS_OSX) && TARGET_OS_OSX +#define OPENSSL_MACOS +#endif +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#define OPENSSL_IOS +#endif +#endif + +#if defined(_WIN32) +#define OPENSSL_WINDOWS +#endif + +// Trusty isn't Linux but currently defines __linux__. As a workaround, we +// exclude it here. +// TODO(b/169780122): Remove this workaround once Trusty no longer defines it. +#if defined(__linux__) && !defined(__TRUSTY__) +#define OPENSSL_LINUX +#endif + +#if defined(__Fuchsia__) +#define OPENSSL_FUCHSIA +#endif + +#if defined(__TRUSTY__) +#define OPENSSL_TRUSTY +#define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED +#endif + +#if defined(__ANDROID_API__) +#define OPENSSL_ANDROID +#endif + +#if defined(__FreeBSD__) +#define OPENSSL_FREEBSD +#endif + +// BoringSSL requires platform's locking APIs to make internal global state +// thread-safe, including the PRNG. On some single-threaded embedded platforms, +// locking APIs may not exist, so this dependency may be disabled with the +// following build flag. +// +// IMPORTANT: Doing so means the consumer promises the library will never be +// used in any multi-threaded context. It causes BoringSSL to be globally +// thread-unsafe. Setting it inappropriately will subtly and unpredictably +// corrupt memory and leak secret keys. +// +// Do not set this flag on any platform where threads are possible. BoringSSL +// maintainers will not provide support for any consumers that do so. Changes +// which break such unsupported configurations will not be reverted. +#if !defined(OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED) +#define OPENSSL_THREADS +#endif + +#define OPENSSL_IS_BORINGSSL +#define OPENSSL_VERSION_NUMBER 0x1010107f +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER + +// BORINGSSL_API_VERSION is a positive integer that increments as BoringSSL +// changes over time. The value itself is not meaningful. It will be incremented +// whenever is convenient to coordinate an API change with consumers. This will +// not denote any special point in development. +// +// A consumer may use this symbol in the preprocessor to temporarily build +// against multiple revisions of BoringSSL at the same time. It is not +// recommended to do so for longer than is necessary. +#define BORINGSSL_API_VERSION 17 + +#if defined(BORINGSSL_SHARED_LIBRARY) + +#if defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __declspec(dllexport) +#else +#define OPENSSL_EXPORT __declspec(dllimport) +#endif + +#else // defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __attribute__((visibility("default"))) +#else +#define OPENSSL_EXPORT +#endif + +#endif // defined(OPENSSL_WINDOWS) + +#else // defined(BORINGSSL_SHARED_LIBRARY) + +#define OPENSSL_EXPORT + +#endif // defined(BORINGSSL_SHARED_LIBRARY) + + +#if defined(__GNUC__) || defined(__clang__) +// MinGW has two different printf implementations. Ensure the format macro +// matches the selected implementation. See +// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. +#if defined(__MINGW_PRINTF_FORMAT) +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__( \ + (__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#endif +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) +#endif + +// OPENSSL_MSVC_PRAGMA emits a pragma on MSVC and nothing on other compilers. +#if defined(_MSC_VER) +#define OPENSSL_MSVC_PRAGMA(arg) __pragma(arg) +#else +#define OPENSSL_MSVC_PRAGMA(arg) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define OPENSSL_UNUSED __attribute__((unused)) +#else +#define OPENSSL_UNUSED +#endif + +// C and C++ handle inline functions differently. In C++, an inline function is +// defined in just the header file, potentially emitted in multiple compilation +// units (in cases the compiler did not inline), but each copy must be identical +// to satsify ODR. In C, a non-static inline must be manually emitted in exactly +// one compilation unit with a separate extern inline declaration. +// +// In both languages, exported inline functions referencing file-local symbols +// are problematic. C forbids this altogether (though GCC and Clang seem not to +// enforce it). It works in C++, but ODR requires the definitions be identical, +// including all names in the definitions resolving to the "same entity". In +// practice, this is unlikely to be a problem, but an inline function that +// returns a pointer to a file-local symbol +// could compile oddly. +// +// Historically, we used static inline in headers. However, to satisfy ODR, use +// plain inline in C++, to allow inline consumer functions to call our header +// functions. Plain inline would also work better with C99 inline, but that is +// not used much in practice, extern inline is tedious, and there are conflicts +// with the old gnu89 model: +// https://stackoverflow.com/questions/216510/extern-inline +#if defined(__cplusplus) +#define OPENSSL_INLINE inline +#else +// Add OPENSSL_UNUSED so that, should an inline function be emitted via macro +// (e.g. a |STACK_OF(T)| implementation) in a source file without tripping +// clang's -Wunused-function. +#define OPENSSL_INLINE static inline OPENSSL_UNUSED +#endif + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +#define BORINGSSL_UNSAFE_DETERMINISTIC_MODE +#endif + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define OPENSSL_ASAN +#endif +#if __has_feature(thread_sanitizer) +#define OPENSSL_TSAN +#endif +#if __has_feature(memory_sanitizer) +#define OPENSSL_MSAN +#define OPENSSL_ASM_INCOMPATIBLE +#endif +#endif + +#if defined(OPENSSL_ASM_INCOMPATIBLE) +#undef OPENSSL_ASM_INCOMPATIBLE +#if !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif // OPENSSL_ASM_INCOMPATIBLE + +#if defined(__cplusplus) +// enums can be predeclared, but only in C++ and only if given an explicit type. +// C doesn't support setting an explicit type for enums thus a #define is used +// to do this only for C++. However, the ABI type between C and C++ need to have +// equal sizes, which is confirmed in a unittest. +#define BORINGSSL_ENUM_INT : int +enum ssl_early_data_reason_t BORINGSSL_ENUM_INT; +enum ssl_encryption_level_t BORINGSSL_ENUM_INT; +enum ssl_private_key_result_t BORINGSSL_ENUM_INT; +enum ssl_renegotiate_mode_t BORINGSSL_ENUM_INT; +enum ssl_select_cert_result_t BORINGSSL_ENUM_INT; +enum ssl_select_cert_result_t BORINGSSL_ENUM_INT; +enum ssl_ticket_aead_result_t BORINGSSL_ENUM_INT; +enum ssl_verify_result_t BORINGSSL_ENUM_INT; +#else +#define BORINGSSL_ENUM_INT +#endif + +// CRYPTO_THREADID is a dummy value. +typedef int CRYPTO_THREADID; + +// An |ASN1_NULL| is an opaque type. asn1.h represents the ASN.1 NULL value as +// an opaque, non-NULL |ASN1_NULL*| pointer. +typedef struct asn1_null_st ASN1_NULL; + +typedef int ASN1_BOOLEAN; +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_object_st ASN1_OBJECT; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_STRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_type_st ASN1_TYPE; +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct BASIC_CONSTRAINTS_st BASIC_CONSTRAINTS; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct DSA_SIG_st DSA_SIG; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; +typedef struct Netscape_spkac_st NETSCAPE_SPKAC; +typedef struct Netscape_spki_st NETSCAPE_SPKI; +typedef struct RIPEMD160state_st RIPEMD160_CTX; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct X509_extension_st X509_EXTENSION; +typedef struct X509_info_st X509_INFO; +typedef struct X509_name_entry_st X509_NAME_ENTRY; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct X509_req_st X509_REQ; +typedef struct X509_sig_st X509_SIG; +typedef struct bignum_ctx BN_CTX; +typedef struct bignum_st BIGNUM; +typedef struct bio_method_st BIO_METHOD; +typedef struct bio_st BIO; +typedef struct blake2b_state_st BLAKE2B_CTX; +typedef struct bn_gencb_st BN_GENCB; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct buf_mem_st BUF_MEM; +typedef struct cbb_st CBB; +typedef struct cbs_st CBS; +typedef struct cmac_ctx_st CMAC_CTX; +typedef struct conf_st CONF; +typedef struct conf_value_st CONF_VALUE; +typedef struct crypto_buffer_pool_st CRYPTO_BUFFER_POOL; +typedef struct crypto_buffer_st CRYPTO_BUFFER; +typedef struct dh_st DH; +typedef struct dsa_st DSA; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_key_st EC_KEY; +typedef struct ec_point_st EC_POINT; +typedef struct ecdsa_method_st ECDSA_METHOD; +typedef struct ecdsa_sig_st ECDSA_SIG; +typedef struct engine_st ENGINE; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct env_md_st EVP_MD; +typedef struct evp_aead_st EVP_AEAD; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_encode_ctx_st EVP_ENCODE_CTX; +typedef struct evp_hpke_aead_st EVP_HPKE_AEAD; +typedef struct evp_hpke_ctx_st EVP_HPKE_CTX; +typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; +typedef struct evp_hpke_kem_st EVP_HPKE_KEM; +typedef struct evp_hpke_key_st EVP_HPKE_KEY; +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_st EVP_PKEY; +typedef struct hmac_ctx_st HMAC_CTX; +typedef struct md4_state_st MD4_CTX; +typedef struct md5_state_st MD5_CTX; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; +typedef struct pkcs12_st PKCS12; +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; +typedef struct private_key_st X509_PKEY; +typedef struct rand_meth_st RAND_METHOD; +typedef struct rc4_key_st RC4_KEY; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_pss_params_st RSA_PSS_PARAMS; +typedef struct rsa_st RSA; +typedef struct sha256_state_st SHA256_CTX; +typedef struct sha512_state_st SHA512_CTX; +typedef struct sha_state_st SHA_CTX; +typedef struct spake2_ctx_st SPAKE2_CTX; +typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct ssl_early_callback_ctx SSL_CLIENT_HELLO; +typedef struct ssl_ech_keys_st SSL_ECH_KEYS; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_private_key_method_st SSL_PRIVATE_KEY_METHOD; +typedef struct ssl_quic_method_st SSL_QUIC_METHOD; +typedef struct ssl_session_st SSL_SESSION; +typedef struct ssl_st SSL; +typedef struct ssl_ticket_aead_method_st SSL_TICKET_AEAD_METHOD; +typedef struct st_ERR_FNS ERR_FNS; +typedef struct trust_token_st TRUST_TOKEN; +typedef struct trust_token_client_st TRUST_TOKEN_CLIENT; +typedef struct trust_token_issuer_st TRUST_TOKEN_ISSUER; +typedef struct trust_token_method_st TRUST_TOKEN_METHOD; +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct x509_attributes_st X509_ATTRIBUTE; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct x509_st X509; +typedef struct x509_store_ctx_st X509_STORE_CTX; +typedef struct x509_store_st X509_STORE; +typedef struct x509_trust_st X509_TRUST; + +typedef void *OPENSSL_BLOCK; + + +#if defined(__cplusplus) +} // extern C +#elif !defined(BORINGSSL_NO_CXX) +#define BORINGSSL_NO_CXX +#endif + +#if defined(BORINGSSL_PREFIX) +#define BSSL_NAMESPACE_BEGIN \ + namespace bssl { \ + inline namespace BORINGSSL_PREFIX { +#define BSSL_NAMESPACE_END \ + } \ + } +#else +#define BSSL_NAMESPACE_BEGIN namespace bssl { +#define BSSL_NAMESPACE_END } +#endif + +// MSVC doesn't set __cplusplus to 201103 to indicate C++11 support (see +// https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l) +// so MSVC is just assumed to support C++11. +#if !defined(BORINGSSL_NO_CXX) && __cplusplus < 201103L && !defined(_MSC_VER) +#define BORINGSSL_NO_CXX +#endif + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +#include + +// STLPort, used by some Android consumers, not have std::unique_ptr. +#if defined(_STLPORT_VERSION) +#define BORINGSSL_NO_CXX +#endif + +} // extern C++ +#endif // !BORINGSSL_NO_CXX + +#if defined(BORINGSSL_NO_CXX) + +#define BORINGSSL_MAKE_DELETER(type, deleter) +#define BORINGSSL_MAKE_UP_REF(type, up_ref_func) + +#else + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +namespace internal { + +// The Enable parameter is ignored and only exists so specializations can use +// SFINAE. +template +struct DeleterImpl {}; + +template +struct Deleter { + void operator()(T *ptr) { + // Rather than specialize Deleter for each type, we specialize + // DeleterImpl. This allows bssl::UniquePtr to be used while only + // including base.h as long as the destructor is not emitted. This matches + // std::unique_ptr's behavior on forward-declared types. + // + // DeleterImpl itself is specialized in the corresponding module's header + // and must be included to release an object. If not included, the compiler + // will error that DeleterImpl does not have a method Free. + DeleterImpl::Free(ptr); + } +}; + +template +class StackAllocated { + public: + StackAllocated() { init(&ctx_); } + ~StackAllocated() { cleanup(&ctx_); } + + StackAllocated(const StackAllocated &) = delete; + StackAllocated& operator=(const StackAllocated &) = delete; + + T *get() { return &ctx_; } + const T *get() const { return &ctx_; } + + T *operator->() { return &ctx_; } + const T *operator->() const { return &ctx_; } + + void Reset() { + cleanup(&ctx_); + init(&ctx_); + } + + private: + T ctx_; +}; + +template +class StackAllocatedMovable { + public: + StackAllocatedMovable() { init(&ctx_); } + ~StackAllocatedMovable() { cleanup(&ctx_); } + + StackAllocatedMovable(StackAllocatedMovable &&other) { + init(&ctx_); + move(&ctx_, &other.ctx_); + } + StackAllocatedMovable &operator=(StackAllocatedMovable &&other) { + move(&ctx_, &other.ctx_); + return *this; + } + + T *get() { return &ctx_; } + const T *get() const { return &ctx_; } + + T *operator->() { return &ctx_; } + const T *operator->() const { return &ctx_; } + + void Reset() { + cleanup(&ctx_); + init(&ctx_); + } + + private: + T ctx_; +}; + +} // namespace internal + +#define BORINGSSL_MAKE_DELETER(type, deleter) \ + namespace internal { \ + template <> \ + struct DeleterImpl { \ + static void Free(type *ptr) { deleter(ptr); } \ + }; \ + } + +// Holds ownership of heap-allocated BoringSSL structures. Sample usage: +// bssl::UniquePtr rsa(RSA_new()); +// bssl::UniquePtr bio(BIO_new(BIO_s_mem())); +template +using UniquePtr = std::unique_ptr>; + +#define BORINGSSL_MAKE_UP_REF(type, up_ref_func) \ + inline UniquePtr UpRef(type *v) { \ + if (v != nullptr) { \ + up_ref_func(v); \ + } \ + return UniquePtr(v); \ + } \ + \ + inline UniquePtr UpRef(const UniquePtr &ptr) { \ + return UpRef(ptr.get()); \ + } + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif // !BORINGSSL_NO_CXX + +#endif // OPENSSL_HEADER_BASE_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base64.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base64.h new file mode 100644 index 00000000..b1a4faf2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_base64.h @@ -0,0 +1,198 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_BASE64_H +#define OPENSSL_HEADER_BASE64_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// base64 functions. +// +// For historical reasons, these functions have the EVP_ prefix but just do +// base64 encoding and decoding. Note that BoringSSL is a cryptography library, +// so these functions are implemented with side channel protections, at a +// performance cost. For other base64 uses, use a general-purpose base64 +// implementation. + + +// Encoding + +// EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the +// result to |dst| with a trailing NUL. It returns the number of bytes +// written, not including this trailing NUL. +OPENSSL_EXPORT size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + +// EVP_EncodedLength sets |*out_len| to the number of bytes that will be needed +// to call |EVP_EncodeBlock| on an input of length |len|. This includes the +// final NUL that |EVP_EncodeBlock| writes. It returns one on success or zero +// on error. +OPENSSL_EXPORT int EVP_EncodedLength(size_t *out_len, size_t len); + + +// Decoding + +// EVP_DecodedLength sets |*out_len| to the maximum number of bytes that will +// be needed to call |EVP_DecodeBase64| on an input of length |len|. It returns +// one on success or zero if |len| is not a valid length for a base64-encoded +// string. +OPENSSL_EXPORT int EVP_DecodedLength(size_t *out_len, size_t len); + +// EVP_DecodeBase64 decodes |in_len| bytes from base64 and writes +// |*out_len| bytes to |out|. |max_out| is the size of the output +// buffer. If it is not enough for the maximum output size, the +// operation fails. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *in, + size_t in_len); + + +// Deprecated functions. +// +// OpenSSL provides a streaming base64 implementation, however its behavior is +// very specific to PEM. It is also very lenient of invalid input. Use of any of +// these functions is thus deprecated. + +// EVP_ENCODE_CTX_new returns a newly-allocated |EVP_ENCODE_CTX| or NULL on +// error. The caller must release the result with |EVP_ENCODE_CTX_free| when +// done. +OPENSSL_EXPORT EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void); + +// EVP_ENCODE_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx); + +// EVP_EncodeInit initialises |*ctx|, which is typically stack +// allocated, for an encoding operation. +// +// NOTE: The encoding operation breaks its output with newlines every +// 64 characters of output (48 characters of input). Use +// EVP_EncodeBlock to encode raw base64. +OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded +// version of them to |out| and sets |*out_len| to the number of bytes written. +// Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to +// flush it before using the encoded data. +OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. +OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for +// a decoding operation. +// +// TODO(davidben): This isn't a straight-up base64 decode either. Document +// and/or fix exactly what's going on here; maximum line length and such. +OPENSSL_EXPORT void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded +// data to |out| and sets |*out_len| to the number of bytes written. Some state +// may be contained in |ctx| so |EVP_DecodeFinal| must be used to flush it +// before using the encoded data. +// +// It returns -1 on error, one if a full line of input was processed and zero +// if the line was short (i.e. it was the last line). +OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. It returns one on success +// and minus one on error. +OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to +// |dst|. It returns the number of bytes written or -1 on error. +// +// WARNING: EVP_DecodeBlock's return value does not take padding into +// account. It also strips leading whitespace and trailing +// whitespace and minuses. +OPENSSL_EXPORT int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + + +struct evp_encode_ctx_st { + // data_used indicates the number of bytes of |data| that are valid. When + // encoding, |data| will be filled and encoded as a lump. When decoding, only + // the first four bytes of |data| will be used. + unsigned data_used; + uint8_t data[48]; + + // eof_seen indicates that the end of the base64 data has been seen when + // decoding. Only whitespace can follow. + char eof_seen; + + // error_encountered indicates that invalid base64 data was found. This will + // cause all future calls to fail. + char error_encountered; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BASE64_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h new file mode 100644 index 00000000..a031d4e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h @@ -0,0 +1,958 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_BIO_H +#define OPENSSL_HEADER_BIO_H + +#include "CNIOBoringSSL_base.h" + +#include // For FILE + +#include "CNIOBoringSSL_buffer.h" +#include "CNIOBoringSSL_err.h" // for ERR_print_errors_fp +#include "CNIOBoringSSL_ex_data.h" +#include "CNIOBoringSSL_stack.h" +#include "CNIOBoringSSL_thread.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO abstracts over a file-descriptor like interface. + + +// Allocation and freeing. + +DEFINE_STACK_OF(BIO) + +// BIO_new creates a new BIO with the given method and a reference count of one. +// It returns the fresh |BIO|, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *method); + +// BIO_free decrements the reference count of |bio|. If the reference count +// drops to zero, it calls the destroy callback, if present, on the method and +// frees |bio| itself. It then repeats that for the next BIO in the chain, if +// any. +// +// It returns one on success or zero otherwise. +OPENSSL_EXPORT int BIO_free(BIO *bio); + +// BIO_vfree performs the same actions as |BIO_free|, but has a void return +// value. This is provided for API-compat. +// +// TODO(fork): remove. +OPENSSL_EXPORT void BIO_vfree(BIO *bio); + +// BIO_up_ref increments the reference count of |bio| and returns one. +OPENSSL_EXPORT int BIO_up_ref(BIO *bio); + + +// Basic I/O. + +// BIO_read attempts to read |len| bytes into |data|. It returns the number of +// bytes read, zero on EOF, or a negative number on error. +OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); + +// BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|. +// It returns the number of bytes read or a negative number on error. The +// phrase "reads a line" is in quotes in the previous sentence because the +// exact operation depends on the BIO's method. For example, a digest BIO will +// return the digest in response to a |BIO_gets| call. +// +// TODO(fork): audit the set of BIOs that we end up needing. If all actually +// return a line for this call, remove the warning above. +OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); + +// BIO_write writes |len| bytes from |data| to |bio|. It returns the number of +// bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len); + +// BIO_write_all writes |len| bytes from |data| to |bio|, looping as necessary. +// It returns one if all bytes were successfully written and zero on error. +OPENSSL_EXPORT int BIO_write_all(BIO *bio, const void *data, size_t len); + +// BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the +// number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf); + +// BIO_flush flushes any buffered output. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_flush(BIO *bio); + + +// Low-level control functions. +// +// These are generic functions for sending control requests to a BIO. In +// general one should use the wrapper functions like |BIO_get_close|. + +// BIO_ctrl sends the control request |cmd| to |bio|. The |cmd| argument should +// be one of the |BIO_C_*| values. +OPENSSL_EXPORT long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg); + +// BIO_ptr_ctrl acts like |BIO_ctrl| but passes the address of a |void*| +// pointer as |parg| and returns the value that is written to it, or NULL if +// the control request returns <= 0. +OPENSSL_EXPORT char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); + +// BIO_int_ctrl acts like |BIO_ctrl| but passes the address of a copy of |iarg| +// as |parg|. +OPENSSL_EXPORT long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); + +// BIO_reset resets |bio| to its initial state, the precise meaning of which +// depends on the concrete type of |bio|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_reset(BIO *bio); + +// BIO_eof returns non-zero when |bio| has reached end-of-file. The precise +// meaning of which depends on the concrete type of |bio|. Note that in the +// case of BIO_pair this always returns non-zero. +OPENSSL_EXPORT int BIO_eof(BIO *bio); + +// BIO_set_flags ORs |flags| with |bio->flags|. +OPENSSL_EXPORT void BIO_set_flags(BIO *bio, int flags); + +// BIO_test_flags returns |bio->flags| AND |flags|. +OPENSSL_EXPORT int BIO_test_flags(const BIO *bio, int flags); + +// BIO_should_read returns non-zero if |bio| encountered a temporary error +// while reading (i.e. EAGAIN), indicating that the caller should retry the +// read. +OPENSSL_EXPORT int BIO_should_read(const BIO *bio); + +// BIO_should_write returns non-zero if |bio| encountered a temporary error +// while writing (i.e. EAGAIN), indicating that the caller should retry the +// write. +OPENSSL_EXPORT int BIO_should_write(const BIO *bio); + +// BIO_should_retry returns non-zero if the reason that caused a failed I/O +// operation is temporary and thus the operation should be retried. Otherwise, +// it was a permanent error and it returns zero. +OPENSSL_EXPORT int BIO_should_retry(const BIO *bio); + +// BIO_should_io_special returns non-zero if |bio| encountered a temporary +// error while performing a special I/O operation, indicating that the caller +// should retry. The operation that caused the error is returned by +// |BIO_get_retry_reason|. +OPENSSL_EXPORT int BIO_should_io_special(const BIO *bio); + +// BIO_RR_CONNECT indicates that a connect would have blocked +#define BIO_RR_CONNECT 0x02 + +// BIO_RR_ACCEPT indicates that an accept would have blocked +#define BIO_RR_ACCEPT 0x03 + +// BIO_get_retry_reason returns the special I/O operation that needs to be +// retried. The return value is one of the |BIO_RR_*| values. +OPENSSL_EXPORT int BIO_get_retry_reason(const BIO *bio); + +// BIO_set_retry_reason sets the special I/O operation that needs to be retried +// to |reason|, which should be one of the |BIO_RR_*| values. +OPENSSL_EXPORT void BIO_set_retry_reason(BIO *bio, int reason); + +// BIO_clear_flags ANDs |bio->flags| with the bitwise-complement of |flags|. +OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags); + +// BIO_set_retry_read sets the |BIO_FLAGS_READ| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio); + +// BIO_set_retry_write sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio); + +// BIO_get_retry_flags gets the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT int BIO_get_retry_flags(BIO *bio); + +// BIO_clear_retry_flags clears the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT void BIO_clear_retry_flags(BIO *bio); + +// BIO_method_type returns the type of |bio|, which is one of the |BIO_TYPE_*| +// values. +OPENSSL_EXPORT int BIO_method_type(const BIO *bio); + +// These are passed to the BIO callback +#define BIO_CB_FREE 0x01 +#define BIO_CB_READ 0x02 +#define BIO_CB_WRITE 0x03 +#define BIO_CB_PUTS 0x04 +#define BIO_CB_GETS 0x05 +#define BIO_CB_CTRL 0x06 + +// The callback is called before and after the underling operation, +// The BIO_CB_RETURN flag indicates if it is after the call +#define BIO_CB_RETURN 0x80 + +// bio_info_cb is the type of a callback function that can be called for most +// BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed +// with |BIO_CB_RETURN| if the callback is being made after the operation in +// question. In that case, |return_value| will contain the return value from +// the operation. +typedef long (*bio_info_cb)(BIO *bio, int event, const char *parg, int cmd, + long larg, long return_value); + +// BIO_callback_ctrl allows the callback function to be manipulated. The |cmd| +// arg will generally be |BIO_CTRL_SET_CALLBACK| but arbitrary command values +// can be interpreted by the |BIO|. +OPENSSL_EXPORT long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp); + +// BIO_pending returns the number of bytes pending to be read. +OPENSSL_EXPORT size_t BIO_pending(const BIO *bio); + +// BIO_ctrl_pending calls |BIO_pending| and exists only for compatibility with +// OpenSSL. +OPENSSL_EXPORT size_t BIO_ctrl_pending(const BIO *bio); + +// BIO_wpending returns the number of bytes pending to be written. +OPENSSL_EXPORT size_t BIO_wpending(const BIO *bio); + +// BIO_set_close sets the close flag for |bio|. The meaning of which depends on +// the type of |bio| but, for example, a memory BIO interprets the close flag +// as meaning that it owns its buffer. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag); + +// BIO_number_read returns the number of bytes that have been read from +// |bio|. +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio); + +// BIO_number_written returns the number of bytes that have been written to +// |bio|. +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio); + + +// Managing chains of BIOs. +// +// BIOs can be put into chains where the output of one is used as the input of +// the next etc. The most common case is a buffering BIO, which accepts and +// buffers writes until flushed into the next BIO in the chain. + +// BIO_push adds |appended_bio| to the end of the chain with |bio| at the head. +// It returns |bio|. Note that |appended_bio| may be the head of a chain itself +// and thus this function can be used to join two chains. +// +// BIO_push takes ownership of the caller's reference to |appended_bio|. +OPENSSL_EXPORT BIO *BIO_push(BIO *bio, BIO *appended_bio); + +// BIO_pop removes |bio| from the head of a chain and returns the next BIO in +// the chain, or NULL if there is no next BIO. +// +// The caller takes ownership of the chain's reference to |bio|. +OPENSSL_EXPORT BIO *BIO_pop(BIO *bio); + +// BIO_next returns the next BIO in the chain after |bio|, or NULL if there is +// no such BIO. +OPENSSL_EXPORT BIO *BIO_next(BIO *bio); + +// BIO_free_all calls |BIO_free|. +// +// TODO(fork): update callers and remove. +OPENSSL_EXPORT void BIO_free_all(BIO *bio); + +// BIO_find_type walks a chain of BIOs and returns the first that matches +// |type|, which is one of the |BIO_TYPE_*| values. +OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type); + +// BIO_copy_next_retry sets the retry flags and |retry_reason| of |bio| from +// the next BIO in the chain. +OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio); + + +// Printf functions. + +// BIO_printf behaves like |printf| but outputs to |bio| rather than a |FILE|. +// It returns the number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(2, 3); + + +// Utility functions. + +// BIO_indent prints min(|indent|, |max_indent|) spaces. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); + +// BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented +// by |indent| spaces. +OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, + unsigned indent); + +// ERR_print_errors prints the current contents of the error stack to |bio| +// using human readable strings where possible. +OPENSSL_EXPORT void ERR_print_errors(BIO *bio); + +// BIO_read_asn1 reads a single ASN.1 object from |bio|. If successful it sets +// |*out| to be an allocated buffer (that should be freed with |OPENSSL_free|), +// |*out_size| to the length, in bytes, of that buffer and returns one. +// Otherwise it returns zero. +// +// If the length of the object is greater than |max_len| or 2^32 then the +// function will fail. Long-form tags are not supported. If the length of the +// object is indefinite the full contents of |bio| are read, unless it would be +// greater than |max_len|, in which case the function fails. +// +// If the function fails then some unknown amount of data may have been read +// from |bio|. +OPENSSL_EXPORT int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, + size_t max_len); + + +// Memory BIOs. +// +// Memory BIOs can be used as a read-only source (with |BIO_new_mem_buf|) or a +// writable sink (with |BIO_new|, |BIO_s_mem| and |BIO_mem_contents|). Data +// written to a writable, memory BIO can be recalled by reading from it. +// +// Calling |BIO_reset| on a read-only BIO resets it to the original contents. +// On a writable BIO, it clears any data. +// +// If the close flag is set to |BIO_NOCLOSE| (not the default) then the +// underlying |BUF_MEM| will not be freed when the |BIO| is freed. +// +// Memory BIOs support |BIO_gets| and |BIO_puts|. +// +// |BIO_ctrl_pending| returns the number of bytes currently stored. + +// BIO_NOCLOSE and |BIO_CLOSE| can be used as symbolic arguments when a "close +// flag" is passed to a BIO function. +#define BIO_NOCLOSE 0 +#define BIO_CLOSE 1 + +// BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void); + +// BIO_new_mem_buf creates read-only BIO that reads from |len| bytes at |buf|. +// It returns the BIO or NULL on error. This function does not copy or take +// ownership of |buf|. The caller must ensure the memory pointed to by |buf| +// outlives the |BIO|. +// +// If |len| is negative, then |buf| is treated as a NUL-terminated string, but +// don't depend on this in new code. +OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len); + +// BIO_mem_contents sets |*out_contents| to point to the current contents of +// |bio| and |*out_len| to contain the length of that data. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio, + const uint8_t **out_contents, + size_t *out_len); + +// BIO_get_mem_data sets |*contents| to point to the current contents of |bio| +// and returns the length of the data. +// +// WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from +// this function can mean either that it failed or that the memory buffer is +// empty. +OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents); + +// BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of +// |bio|. It returns one on success or zero on error. +OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out); + +// BIO_set_mem_buf sets |b| as the contents of |bio|. If |take_ownership| is +// non-zero, then |b| will be freed when |bio| is closed. Returns one on +// success or zero otherwise. +OPENSSL_EXPORT int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership); + +// BIO_set_mem_eof_return sets the value that will be returned from reading +// |bio| when empty. If |eof_value| is zero then an empty memory BIO will +// return EOF (that is it will return zero and |BIO_should_retry| will be +// false). If |eof_value| is non zero then it will return |eof_value| when it +// is empty and it will set the read retry flag (that is |BIO_read_retry| is +// true). To avoid ambiguity with a normal positive return value, |eof_value| +// should be set to a negative value, typically -1. +// +// For a read-only BIO, the default is zero (EOF). For a writable BIO, the +// default is -1 so that additional data can be written once exhausted. +OPENSSL_EXPORT int BIO_set_mem_eof_return(BIO *bio, int eof_value); + + +// File descriptor BIOs. +// +// File descriptor BIOs are wrappers around the system's |read| and |write| +// functions. If the close flag is set then then |close| is called on the +// underlying file descriptor when the BIO is freed. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |lseek|. + +// BIO_s_fd returns a |BIO_METHOD| for file descriptor fds. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_fd(void); + +// BIO_new_fd creates a new file descriptor BIO wrapping |fd|. If |close_flag| +// is non-zero, then |fd| will be closed when the BIO is. +OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag); + +// BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is +// non-zero then |fd| will be closed when |bio| is. It returns one on success +// or zero on error. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag); + +// BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if +// |bio| does not wrap a file descriptor. If there is a file descriptor and +// |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd); + + +// File BIOs. +// +// File BIOs are wrappers around a C |FILE| object. +// +// |BIO_flush| on a file BIO calls |fflush| on the wrapped stream. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |fseek|. +// +// Setting the close flag causes |fclose| to be called on the stream when the +// BIO is freed. + +// BIO_s_file returns a BIO_METHOD that wraps a |FILE|. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void); + +// BIO_new_file creates a file BIO by opening |filename| with the given mode. +// See the |fopen| manual page for details of the mode argument. +OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode); + +// BIO_new_fp creates a new file BIO that wraps the given |FILE|. If +// |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when +// the BIO is closed. +OPENSSL_EXPORT BIO *BIO_new_fp(FILE *stream, int close_flag); + +// BIO_get_fp sets |*out_file| to the current |FILE| for |bio|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file); + +// BIO_set_fp sets the |FILE| for |bio|. If |close_flag| is |BIO_CLOSE| then +// |fclose| will be called on |file| when |bio| is closed. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag); + +// BIO_read_filename opens |filename| for reading and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename); + +// BIO_write_filename opens |filename| for writing and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename); + +// BIO_append_filename opens |filename| for appending and sets the result as +// the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename); + +// BIO_rw_filename opens |filename| for reading and writing and sets the result +// as the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename); + +// BIO_tell returns the file offset of |bio|, or a negative number on error or +// if |bio| does not support the operation. +// +// TODO(https://crbug.com/boringssl/465): On platforms where |long| is 32-bit, +// this function cannot report 64-bit offsets. +OPENSSL_EXPORT long BIO_tell(BIO *bio); + +// BIO_seek sets the file offset of |bio| to |offset|. It returns a non-negative +// number on success and a negative number on error. If |bio| is a file +// descriptor |BIO|, it returns the resulting file offset on success. If |bio| +// is a file |BIO|, it returns zero on success. +// +// WARNING: This function's return value conventions differs from most functions +// in this library. +// +// TODO(https://crbug.com/boringssl/465): On platforms where |long| is 32-bit, +// this function cannot handle 64-bit offsets. +OPENSSL_EXPORT long BIO_seek(BIO *bio, long offset); + + +// Socket BIOs. +// +// Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap +// the system's |recv| and |send| functions instead of |read| and |write|. On +// Windows, file descriptors are provided by C runtime and are not +// interchangeable with sockets. +// +// Socket BIOs may be used with |BIO_set_fd| and |BIO_get_fd|. +// +// TODO(davidben): Add separate APIs and fix the internals to use |SOCKET|s +// around rather than rely on int casts. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void); + +// BIO_new_socket allocates and initialises a fresh BIO which will read and +// write to the socket |fd|. If |close_flag| is |BIO_CLOSE| then closing the +// BIO will close |fd|. It returns the fresh |BIO| or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_socket(int fd, int close_flag); + + +// Connect BIOs. +// +// A connection BIO creates a network connection and transfers data over the +// resulting socket. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_connect(void); + +// BIO_new_connect returns a BIO that connects to the given hostname and port. +// The |host_and_optional_port| argument should be of the form +// "www.example.com" or "www.example.com:443". If the port is omitted, it must +// be provided with |BIO_set_conn_port|. +// +// It returns the new BIO on success, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_connect(const char *host_and_optional_port); + +// BIO_set_conn_hostname sets |host_and_optional_port| as the hostname and +// optional port that |bio| will connect to. If the port is omitted, it must be +// provided with |BIO_set_conn_port|. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_hostname(BIO *bio, + const char *host_and_optional_port); + +// BIO_set_conn_port sets |port_str| as the port or service name that |bio| +// will connect to. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str); + +// BIO_set_conn_int_port sets |*port| as the port that |bio| will connect to. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_int_port(BIO *bio, const int *port); + +// BIO_set_nbio sets whether |bio| will use non-blocking I/O operations. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on); + +// BIO_do_connect connects |bio| if it has not been connected yet. It returns +// one on success and <= 0 otherwise. +OPENSSL_EXPORT int BIO_do_connect(BIO *bio); + + +// Datagram BIOs. +// +// TODO(fork): not implemented. + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 // as kernel for current MTU + +#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for MTU. want to use + this if asking the kernel fails */ + +#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU was exceed in + the previous write operation. */ + +// BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT is unsupported as it is unused by consumers +// and depends on |timeval|, which is not 2038-clean on all platforms. + +#define BIO_CTRL_DGRAM_GET_PEER 46 + +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 + + +// BIO Pairs. +// +// BIO pairs provide a "loopback" like system: a pair of BIOs where data +// written to one can be read from the other and vice versa. + +// BIO_new_bio_pair sets |*out1| and |*out2| to two freshly created BIOs where +// data written to one can be read from the other and vice versa. The +// |writebuf1| argument gives the size of the buffer used in |*out1| and +// |writebuf2| for |*out2|. It returns one on success and zero on error. +OPENSSL_EXPORT int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2, + size_t writebuf2); + +// BIO_ctrl_get_read_request returns the number of bytes that the other side of +// |bio| tried (unsuccessfully) to read. +OPENSSL_EXPORT size_t BIO_ctrl_get_read_request(BIO *bio); + +// BIO_ctrl_get_write_guarantee returns the number of bytes that |bio| (which +// must have been returned by |BIO_new_bio_pair|) will accept on the next +// |BIO_write| call. +OPENSSL_EXPORT size_t BIO_ctrl_get_write_guarantee(BIO *bio); + +// BIO_shutdown_wr marks |bio| as closed, from the point of view of the other +// side of the pair. Future |BIO_write| calls on |bio| will fail. It returns +// one on success and zero otherwise. +OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio); + + +// Custom BIOs. +// +// Consumers can create custom |BIO|s by filling in a |BIO_METHOD| and using +// low-level control functions to set state. + +// BIO_get_new_index returns a new "type" value for a custom |BIO|. +OPENSSL_EXPORT int BIO_get_new_index(void); + +// BIO_meth_new returns a newly-allocated |BIO_METHOD| or NULL on allocation +// error. The |type| specifies the type that will be returned by +// |BIO_method_type|. If this is unnecessary, this value may be zero. The |name| +// parameter is vestigial and may be NULL. +// +// Use the |BIO_meth_set_*| functions below to initialize the |BIO_METHOD|. The +// function implementations may use |BIO_set_data| and |BIO_get_data| to add +// method-specific state to associated |BIO|s. Additionally, |BIO_set_init| must +// be called after an associated |BIO| is fully initialized. State set via +// |BIO_set_data| may be released by configuring a destructor with +// |BIO_meth_set_destroy|. +OPENSSL_EXPORT BIO_METHOD *BIO_meth_new(int type, const char *name); + +// BIO_meth_free releases memory associated with |method|. +OPENSSL_EXPORT void BIO_meth_free(BIO_METHOD *method); + +// BIO_meth_set_create sets a function to be called on |BIO_new| for |method| +// and returns one. The function should return one on success and zero on +// error. +OPENSSL_EXPORT int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)); + +// BIO_meth_set_destroy sets a function to release data associated with a |BIO| +// and returns one. The function's return value is ignored. +OPENSSL_EXPORT int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)); + +// BIO_meth_set_write sets the implementation of |BIO_write| for |method| and +// returns one. |BIO_METHOD|s which implement |BIO_write| should also implement +// |BIO_CTRL_FLUSH|. (See |BIO_meth_set_ctrl|.) +OPENSSL_EXPORT int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)); + +// BIO_meth_set_read sets the implementation of |BIO_read| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)); + +// BIO_meth_set_gets sets the implementation of |BIO_gets| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)); + +// BIO_meth_set_ctrl sets the implementation of |BIO_ctrl| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)); + +// BIO_set_data sets custom data on |bio|. It may be retried with +// |BIO_get_data|. +OPENSSL_EXPORT void BIO_set_data(BIO *bio, void *ptr); + +// BIO_get_data returns custom data on |bio| set by |BIO_get_data|. +OPENSSL_EXPORT void *BIO_get_data(BIO *bio); + +// BIO_set_init sets whether |bio| has been fully initialized. Until fully +// initialized, |BIO_read| and |BIO_write| will fail. +OPENSSL_EXPORT void BIO_set_init(BIO *bio, int init); + +// BIO_get_init returns whether |bio| has been fully initialized. +OPENSSL_EXPORT int BIO_get_init(BIO *bio); + +// These are values of the |cmd| argument to |BIO_ctrl|. + +// BIO_CTRL_RESET implements |BIO_reset|. The arguments are unused. +#define BIO_CTRL_RESET 1 + +// BIO_CTRL_EOF implements |BIO_eof|. The arguments are unused. +#define BIO_CTRL_EOF 2 + +// BIO_CTRL_INFO is a legacy command that returns information specific to the +// type of |BIO|. It is not safe to call generically and should not be +// implemented in new |BIO| types. +#define BIO_CTRL_INFO 3 + +// BIO_CTRL_GET_CLOSE returns the close flag set by |BIO_CTRL_SET_CLOSE|. The +// arguments are unused. +#define BIO_CTRL_GET_CLOSE 8 + +// BIO_CTRL_SET_CLOSE implements |BIO_set_close|. The |larg| argument is the +// close flag. +#define BIO_CTRL_SET_CLOSE 9 + +// BIO_CTRL_PENDING implements |BIO_pending|. The arguments are unused. +#define BIO_CTRL_PENDING 10 + +// BIO_CTRL_FLUSH implements |BIO_flush|. The arguments are unused. +#define BIO_CTRL_FLUSH 11 + +// BIO_CTRL_WPENDING implements |BIO_wpending|. The arguments are unused. +#define BIO_CTRL_WPENDING 13 + +// BIO_CTRL_SET_CALLBACK sets an informational callback of type +// int cb(BIO *bio, int state, int ret) +#define BIO_CTRL_SET_CALLBACK 14 + +// BIO_CTRL_GET_CALLBACK returns the callback set by |BIO_CTRL_SET_CALLBACK|. +#define BIO_CTRL_GET_CALLBACK 15 + +// The following are never used, but are defined to aid porting existing code. +#define BIO_CTRL_SET 4 +#define BIO_CTRL_GET 5 +#define BIO_CTRL_PUSH 6 +#define BIO_CTRL_POP 7 +#define BIO_CTRL_DUP 12 +#define BIO_CTRL_SET_FILENAME 30 + + +// Deprecated functions. + +// BIO_f_base64 returns a filter |BIO| that base64-encodes data written into +// it, and decodes data read from it. |BIO_gets| is not supported. Call +// |BIO_flush| when done writing, to signal that no more data are to be +// encoded. The flag |BIO_FLAGS_BASE64_NO_NL| may be set to encode all the data +// on one line. +// +// Use |EVP_EncodeBlock| and |EVP_DecodeBase64| instead. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void); + +OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio); + +// BIO_set_write_buffer_size returns zero. +OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size); + +// BIO_set_shutdown sets a method-specific "shutdown" bit on |bio|. +OPENSSL_EXPORT void BIO_set_shutdown(BIO *bio, int shutdown); + +// BIO_get_shutdown returns the method-specific "shutdown" bit. +OPENSSL_EXPORT int BIO_get_shutdown(BIO *bio); + +// BIO_meth_set_puts returns one. |BIO_puts| is implemented with |BIO_write| in +// BoringSSL. +OPENSSL_EXPORT int BIO_meth_set_puts(BIO_METHOD *method, + int (*puts)(BIO *, const char *)); + + +// Private functions + +#define BIO_FLAGS_READ 0x01 +#define BIO_FLAGS_WRITE 0x02 +#define BIO_FLAGS_IO_SPECIAL 0x04 +#define BIO_FLAGS_RWS (BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL) +#define BIO_FLAGS_SHOULD_RETRY 0x08 +#define BIO_FLAGS_BASE64_NO_NL 0x100 +// BIO_FLAGS_MEM_RDONLY is used with memory BIOs. It means we shouldn't free up +// or change the data in any way. +#define BIO_FLAGS_MEM_RDONLY 0x200 + +// These are the 'types' of BIOs +#define BIO_TYPE_NONE 0 +#define BIO_TYPE_MEM (1 | 0x0400) +#define BIO_TYPE_FILE (2 | 0x0400) +#define BIO_TYPE_FD (4 | 0x0400 | 0x0100) +#define BIO_TYPE_SOCKET (5 | 0x0400 | 0x0100) +#define BIO_TYPE_NULL (6 | 0x0400) +#define BIO_TYPE_SSL (7 | 0x0200) +#define BIO_TYPE_MD (8 | 0x0200) // passive filter +#define BIO_TYPE_BUFFER (9 | 0x0200) // filter +#define BIO_TYPE_CIPHER (10 | 0x0200) // filter +#define BIO_TYPE_BASE64 (11 | 0x0200) // filter +#define BIO_TYPE_CONNECT (12 | 0x0400 | 0x0100) // socket - connect +#define BIO_TYPE_ACCEPT (13 | 0x0400 | 0x0100) // socket for accept +#define BIO_TYPE_PROXY_CLIENT (14 | 0x0200) // client proxy BIO +#define BIO_TYPE_PROXY_SERVER (15 | 0x0200) // server proxy BIO +#define BIO_TYPE_NBIO_TEST (16 | 0x0200) // server proxy BIO +#define BIO_TYPE_NULL_FILTER (17 | 0x0200) +#define BIO_TYPE_BER (18 | 0x0200) // BER -> bin filter +#define BIO_TYPE_BIO (19 | 0x0400) // (half a) BIO pair +#define BIO_TYPE_LINEBUFFER (20 | 0x0200) // filter +#define BIO_TYPE_DGRAM (21 | 0x0400 | 0x0100) +#define BIO_TYPE_ASN1 (22 | 0x0200) // filter +#define BIO_TYPE_COMP (23 | 0x0200) // filter + +// BIO_TYPE_DESCRIPTOR denotes that the |BIO| responds to the |BIO_C_SET_FD| +// (|BIO_set_fd|) and |BIO_C_GET_FD| (|BIO_get_fd|) control hooks. +#define BIO_TYPE_DESCRIPTOR 0x0100 // socket, fd, connect or accept +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +// BIO_TYPE_START is the first user-allocated |BIO| type. No pre-defined type, +// flag bits aside, may exceed this value. +#define BIO_TYPE_START 128 + +struct bio_method_st { + int type; + const char *name; + int (*bwrite)(BIO *, const char *, int); + int (*bread)(BIO *, char *, int); + // TODO(fork): remove bputs. + int (*bputs)(BIO *, const char *); + int (*bgets)(BIO *, char *, int); + long (*ctrl)(BIO *, int, long, void *); + int (*create)(BIO *); + int (*destroy)(BIO *); + long (*callback_ctrl)(BIO *, int, bio_info_cb); +}; + +struct bio_st { + const BIO_METHOD *method; + + // init is non-zero if this |BIO| has been initialised. + int init; + // shutdown is often used by specific |BIO_METHOD|s to determine whether + // they own some underlying resource. This flag can often by controlled by + // |BIO_set_close|. For example, whether an fd BIO closes the underlying fd + // when it, itself, is closed. + int shutdown; + int flags; + int retry_reason; + // num is a BIO-specific value. For example, in fd BIOs it's used to store a + // file descriptor. + int num; + CRYPTO_refcount_t references; + void *ptr; + // next_bio points to the next |BIO| in a chain. This |BIO| owns a reference + // to |next_bio|. + BIO *next_bio; // used by filter BIOs + size_t num_read, num_write; +}; + +#define BIO_C_SET_CONNECT 100 +#define BIO_C_DO_STATE_MACHINE 101 +#define BIO_C_SET_NBIO 102 +#define BIO_C_SET_PROXY_PARAM 103 +#define BIO_C_SET_FD 104 +#define BIO_C_GET_FD 105 +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_SET_SSL 109 +#define BIO_C_GET_SSL 110 +#define BIO_C_SET_MD 111 +#define BIO_C_GET_MD 112 +#define BIO_C_GET_CIPHER_STATUS 113 +#define BIO_C_SET_BUF_MEM 114 +#define BIO_C_GET_BUF_MEM_PTR 115 +#define BIO_C_GET_BUFF_NUM_LINES 116 +#define BIO_C_SET_BUFF_SIZE 117 +#define BIO_C_SET_ACCEPT 118 +#define BIO_C_SSL_MODE 119 +#define BIO_C_GET_MD_CTX 120 +#define BIO_C_GET_PROXY_PARAM 121 +#define BIO_C_SET_BUFF_READ_DATA 122 // data to read first +#define BIO_C_GET_ACCEPT 124 +#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_GET_CIPHER_CTX 129 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130 // return end of input value +#define BIO_C_SET_BIND_MODE 131 +#define BIO_C_GET_BIND_MODE 132 +#define BIO_C_FILE_TELL 133 +#define BIO_C_GET_SOCKS 134 +#define BIO_C_SET_SOCKS 135 + +#define BIO_C_SET_WRITE_BUF_SIZE 136 // for BIO_s_bio +#define BIO_C_GET_WRITE_BUF_SIZE 137 +#define BIO_C_GET_WRITE_GUARANTEE 140 +#define BIO_C_GET_READ_REQUEST 141 +#define BIO_C_SHUTDOWN_WR 142 +#define BIO_C_NREAD0 143 +#define BIO_C_NREAD 144 +#define BIO_C_NWRITE0 145 +#define BIO_C_NWRITE 146 +#define BIO_C_RESET_READ_REQUEST 147 +#define BIO_C_SET_MD_CTX 148 + +#define BIO_C_SET_PREFIX 149 +#define BIO_C_GET_PREFIX 150 +#define BIO_C_SET_SUFFIX 151 +#define BIO_C_GET_SUFFIX 152 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(BIO, BIO_free) +BORINGSSL_MAKE_UP_REF(BIO, BIO_up_ref) +BORINGSSL_MAKE_DELETER(BIO_METHOD, BIO_meth_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define BIO_R_BAD_FOPEN_MODE 100 +#define BIO_R_BROKEN_PIPE 101 +#define BIO_R_CONNECT_ERROR 102 +#define BIO_R_ERROR_SETTING_NBIO 103 +#define BIO_R_INVALID_ARGUMENT 104 +#define BIO_R_IN_USE 105 +#define BIO_R_KEEPALIVE 106 +#define BIO_R_NBIO_CONNECT_ERROR 107 +#define BIO_R_NO_HOSTNAME_SPECIFIED 108 +#define BIO_R_NO_PORT_SPECIFIED 109 +#define BIO_R_NO_SUCH_FILE 110 +#define BIO_R_NULL_PARAMETER 111 +#define BIO_R_SYS_LIB 112 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 113 +#define BIO_R_UNINITIALIZED 114 +#define BIO_R_UNSUPPORTED_METHOD 115 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 116 + +#endif // OPENSSL_HEADER_BIO_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blake2.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blake2.h new file mode 100644 index 00000000..6d66d12e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blake2.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BLAKE2_H +#define OPENSSL_HEADER_BLAKE2_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define BLAKE2B256_DIGEST_LENGTH (256 / 8) +#define BLAKE2B_CBLOCK 128 + +struct blake2b_state_st { + uint64_t h[8]; + uint64_t t_low, t_high; + union { + uint8_t bytes[BLAKE2B_CBLOCK]; + uint64_t words[16]; + } block; + size_t block_used; +}; + +// BLAKE2B256_Init initialises |b2b| to perform a BLAKE2b-256 hash. There are no +// pointers inside |b2b| thus release of |b2b| is purely managed by the caller. +OPENSSL_EXPORT void BLAKE2B256_Init(BLAKE2B_CTX *b2b); + +// BLAKE2B256_Update appends |len| bytes from |data| to the digest being +// calculated by |b2b|. +OPENSSL_EXPORT void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *data, + size_t len); + +// BLAKE2B256_Final completes the digest calculated by |b2b| and writes +// |BLAKE2B256_DIGEST_LENGTH| bytes to |out|. +OPENSSL_EXPORT void BLAKE2B256_Final(uint8_t out[BLAKE2B256_DIGEST_LENGTH], + BLAKE2B_CTX *b2b); + +// BLAKE2B256 writes the BLAKE2b-256 digset of |len| bytes from |data| to +// |out|. +OPENSSL_EXPORT void BLAKE2B256(const uint8_t *data, size_t len, + uint8_t out[BLAKE2B256_DIGEST_LENGTH]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BLAKE2_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blowfish.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blowfish.h new file mode 100644 index 00000000..764f16d3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_blowfish.h @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_BLOWFISH_H +#define OPENSSL_HEADER_BLOWFISH_H + +#include "CNIOBoringSSL_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st { + uint32_t P[BF_ROUNDS + 2]; + uint32_t S[4 * 256]; +} BF_KEY; + +OPENSSL_EXPORT void BF_set_key(BF_KEY *key, size_t len, const uint8_t *data); +OPENSSL_EXPORT void BF_encrypt(uint32_t *data, const BF_KEY *key); +OPENSSL_EXPORT void BF_decrypt(uint32_t *data, const BF_KEY *key); + +OPENSSL_EXPORT void BF_ecb_encrypt(const uint8_t *in, uint8_t *out, + const BF_KEY *key, int enc); +OPENSSL_EXPORT void BF_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const BF_KEY *schedule, + uint8_t *ivec, int enc); + + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_BLOWFISH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h new file mode 100644 index 00000000..beb09e81 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h @@ -0,0 +1,1071 @@ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#ifndef OPENSSL_HEADER_BN_H +#define OPENSSL_HEADER_BN_H + +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_thread.h" + +#include // for PRIu64 and friends +#include +#include // for FILE* + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BN provides support for working with arbitrary sized integers. For example, +// although the largest integer supported by the compiler might be 64 bits, BN +// will allow you to work with numbers until you run out of memory. + + +// BN_ULONG is the native word size when working with big integers. +// +// Note: on some platforms, inttypes.h does not define print format macros in +// C++ unless |__STDC_FORMAT_MACROS| defined. This is due to text in C99 which +// was never adopted in any C++ standard and explicitly overruled in C++11. As +// this is a public header, bn.h does not define |__STDC_FORMAT_MACROS| itself. +// Projects which use |BN_*_FMT*| with outdated C headers may need to define it +// externally. +#if defined(OPENSSL_64_BIT) +typedef uint64_t BN_ULONG; +#define BN_BITS2 64 +#define BN_DEC_FMT1 "%" PRIu64 +#define BN_DEC_FMT2 "%019" PRIu64 +#define BN_HEX_FMT1 "%" PRIx64 +#define BN_HEX_FMT2 "%016" PRIx64 +#elif defined(OPENSSL_32_BIT) +typedef uint32_t BN_ULONG; +#define BN_BITS2 32 +#define BN_DEC_FMT1 "%" PRIu32 +#define BN_DEC_FMT2 "%09" PRIu32 +#define BN_HEX_FMT1 "%" PRIx32 +#define BN_HEX_FMT2 "%08" PRIx32 +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + + +// Allocation and freeing. + +// BN_new creates a new, allocated BIGNUM and initialises it. +OPENSSL_EXPORT BIGNUM *BN_new(void); + +// BN_init initialises a stack allocated |BIGNUM|. +OPENSSL_EXPORT void BN_init(BIGNUM *bn); + +// BN_free frees the data referenced by |bn| and, if |bn| was originally +// allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_free(BIGNUM *bn); + +// BN_clear_free erases and frees the data referenced by |bn| and, if |bn| was +// originally allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn); + +// BN_dup allocates a new BIGNUM and sets it equal to |src|. It returns the +// allocated BIGNUM on success or NULL otherwise. +OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src); + +// BN_copy sets |dest| equal to |src| and returns |dest| or NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src); + +// BN_clear sets |bn| to zero and erases the old data. +OPENSSL_EXPORT void BN_clear(BIGNUM *bn); + +// BN_value_one returns a static BIGNUM with value 1. +OPENSSL_EXPORT const BIGNUM *BN_value_one(void); + + +// Basic functions. + +// BN_num_bits returns the minimum number of bits needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn); + +// BN_num_bytes returns the minimum number of bytes needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn); + +// BN_zero sets |bn| to zero. +OPENSSL_EXPORT void BN_zero(BIGNUM *bn); + +// BN_one sets |bn| to one. It returns one on success or zero on allocation +// failure. +OPENSSL_EXPORT int BN_one(BIGNUM *bn); + +// BN_set_word sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value); + +// BN_set_u64 sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_u64(BIGNUM *bn, uint64_t value); + +// BN_set_negative sets the sign of |bn|. +OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign); + +// BN_is_negative returns one if |bn| is negative and zero otherwise. +OPENSSL_EXPORT int BN_is_negative(const BIGNUM *bn); + + +// Conversion functions. + +// BN_bin2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a big-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2bin serialises the absolute value of |in| to |out| as a big-endian +// integer, which must have |BN_num_bytes| of space available. It returns the +// number of bytes written. Note this function leaks the magnitude of |in|. If +// |in| is secret, use |BN_bn2bin_padded| instead. +OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out); + +// BN_le2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a little-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2le_padded serialises the absolute value of |in| to |out| as a +// little-endian integer, which must have |len| of space available, padding +// out the remainder of out with zeros. If |len| is smaller than |BN_num_bytes|, +// the function fails and returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2bin_padded serialises the absolute value of |in| to |out| as a +// big-endian integer. The integer is padded with leading zeros up to size +// |len|. If |len| is smaller than |BN_num_bytes|, the function fails and +// returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2cbb_padded behaves like |BN_bn2bin_padded| but writes to a |CBB|. +OPENSSL_EXPORT int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in); + +// BN_bn2hex returns an allocated string that contains a NUL-terminated, hex +// representation of |bn|. If |bn| is negative, the first char in the resulting +// string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2hex(const BIGNUM *bn); + +// BN_hex2bn parses the leading hex number from |in|, which may be proceeded by +// a '-' to indicate a negative number and may contain trailing, non-hex data. +// If |outp| is not NULL, it constructs a BIGNUM equal to the hex number and +// stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and +// updates |*outp|. It returns the number of bytes of |in| processed or zero on +// error. +OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in); + +// BN_bn2dec returns an allocated string that contains a NUL-terminated, +// decimal representation of |bn|. If |bn| is negative, the first char in the +// resulting string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); + +// BN_dec2bn parses the leading decimal number from |in|, which may be +// proceeded by a '-' to indicate a negative number and may contain trailing, +// non-decimal data. If |outp| is not NULL, it constructs a BIGNUM equal to the +// decimal number and stores it in |*outp|. If |*outp| is NULL then it +// allocates a new BIGNUM and updates |*outp|. It returns the number of bytes +// of |in| processed or zero on error. +OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in); + +// BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in| +// begins with "0X" or "0x" (indicating hex) or not (indicating decimal). A +// leading '-' is still permitted and comes before the optional 0X/0x. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_asc2bn(BIGNUM **outp, const char *in); + +// BN_print writes a hex encoding of |a| to |bio|. It returns one on success +// and zero on error. +OPENSSL_EXPORT int BN_print(BIO *bio, const BIGNUM *a); + +// BN_print_fp acts like |BIO_print|, but wraps |fp| in a |BIO| first. +OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a); + +// BN_get_word returns the absolute value of |bn| as a single word. If |bn| is +// too large to be represented as a single word, the maximum possible value +// will be returned. +OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn); + +// BN_get_u64 sets |*out| to the absolute value of |bn| as a |uint64_t| and +// returns one. If |bn| is too large to be represented as a |uint64_t|, it +// returns zero. +OPENSSL_EXPORT int BN_get_u64(const BIGNUM *bn, uint64_t *out); + + +// ASN.1 functions. + +// BN_parse_asn1_unsigned parses a non-negative DER INTEGER from |cbs| writes +// the result to |ret|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret); + +// BN_marshal_asn1 marshals |bn| as a non-negative DER INTEGER and appends the +// result to |cbb|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn); + + +// BIGNUM pools. +// +// Certain BIGNUM operations need to use many temporary variables and +// allocating and freeing them can be quite slow. Thus such operations typically +// take a |BN_CTX| parameter, which contains a pool of |BIGNUMs|. The |ctx| +// argument to a public function may be NULL, in which case a local |BN_CTX| +// will be created just for the lifetime of that call. +// +// A function must call |BN_CTX_start| first. Then, |BN_CTX_get| may be called +// repeatedly to obtain temporary |BIGNUM|s. All |BN_CTX_get| calls must be made +// before calling any other functions that use the |ctx| as an argument. +// +// Finally, |BN_CTX_end| must be called before returning from the function. +// When |BN_CTX_end| is called, the |BIGNUM| pointers obtained from +// |BN_CTX_get| become invalid. + +// BN_CTX_new returns a new, empty BN_CTX or NULL on allocation failure. +OPENSSL_EXPORT BN_CTX *BN_CTX_new(void); + +// BN_CTX_free frees all BIGNUMs contained in |ctx| and then frees |ctx| +// itself. +OPENSSL_EXPORT void BN_CTX_free(BN_CTX *ctx); + +// BN_CTX_start "pushes" a new entry onto the |ctx| stack and allows future +// calls to |BN_CTX_get|. +OPENSSL_EXPORT void BN_CTX_start(BN_CTX *ctx); + +// BN_CTX_get returns a new |BIGNUM|, or NULL on allocation failure. Once +// |BN_CTX_get| has returned NULL, all future calls will also return NULL until +// |BN_CTX_end| is called. +OPENSSL_EXPORT BIGNUM *BN_CTX_get(BN_CTX *ctx); + +// BN_CTX_end invalidates all |BIGNUM|s returned from |BN_CTX_get| since the +// matching |BN_CTX_start| call. +OPENSSL_EXPORT void BN_CTX_end(BN_CTX *ctx); + + +// Simple arithmetic + +// BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_uadd sets |r| = |a| + |b|, where |a| and |b| are non-negative and |r| may +// be the same pointer as either |a| or |b|. It returns one on success and zero +// on allocation failure. +OPENSSL_EXPORT int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_add_word adds |w| to |a|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_add_word(BIGNUM *a, BN_ULONG w); + +// BN_sub sets |r| = |a| - |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_usub sets |r| = |a| - |b|, where |a| and |b| are non-negative integers, +// |b| < |a| and |r| may be the same pointer as either |a| or |b|. It returns +// one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_sub_word subtracts |w| from |a|. It returns one on success and zero on +// allocation failure. +OPENSSL_EXPORT int BN_sub_word(BIGNUM *a, BN_ULONG w); + +// BN_mul sets |r| = |a| * |b|, where |r| may be the same pointer as |a| or +// |b|. Returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mul_word sets |bn| = |bn| * |w|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_mul_word(BIGNUM *bn, BN_ULONG w); + +// BN_sqr sets |r| = |a|^2 (i.e. squares), where |r| may be the same pointer as +// |a|. Returns one on success and zero otherwise. This is more efficient than +// BN_mul(r, a, a, ctx). +OPENSSL_EXPORT int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// BN_div divides |numerator| by |divisor| and places the result in |quotient| +// and the remainder in |rem|. Either of |quotient| or |rem| may be NULL, in +// which case the respective value is not returned. The result is rounded +// towards zero; thus if |numerator| is negative, the remainder will be zero or +// negative. It returns one on success or zero on error. +OPENSSL_EXPORT int BN_div(BIGNUM *quotient, BIGNUM *rem, + const BIGNUM *numerator, const BIGNUM *divisor, + BN_CTX *ctx); + +// BN_div_word sets |numerator| = |numerator|/|divisor| and returns the +// remainder or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor); + +// BN_sqrt sets |*out_sqrt| (which may be the same |BIGNUM| as |in|) to the +// square root of |in|, using |ctx|. It returns one on success or zero on +// error. Negative numbers and non-square numbers will result in an error with +// appropriate errors on the error queue. +OPENSSL_EXPORT int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx); + + +// Comparison functions + +// BN_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int BN_cmp(const BIGNUM *a, const BIGNUM *b); + +// BN_cmp_word is like |BN_cmp| except it takes its second argument as a +// |BN_ULONG| instead of a |BIGNUM|. +OPENSSL_EXPORT int BN_cmp_word(const BIGNUM *a, BN_ULONG b); + +// BN_ucmp returns a value less than, equal to or greater than zero if the +// absolute value of |a| is less than, equal to or greater than the absolute +// value of |b|, respectively. +OPENSSL_EXPORT int BN_ucmp(const BIGNUM *a, const BIGNUM *b); + +// BN_equal_consttime returns one if |a| is equal to |b|, and zero otherwise. +// It takes an amount of time dependent on the sizes of |a| and |b|, but +// independent of the contents (including the signs) of |a| and |b|. +OPENSSL_EXPORT int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b); + +// BN_abs_is_word returns one if the absolute value of |bn| equals |w| and zero +// otherwise. +OPENSSL_EXPORT int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_zero returns one if |bn| is zero and zero otherwise. +OPENSSL_EXPORT int BN_is_zero(const BIGNUM *bn); + +// BN_is_one returns one if |bn| equals one and zero otherwise. +OPENSSL_EXPORT int BN_is_one(const BIGNUM *bn); + +// BN_is_word returns one if |bn| is exactly |w| and zero otherwise. +OPENSSL_EXPORT int BN_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_odd returns one if |bn| is odd and zero otherwise. +OPENSSL_EXPORT int BN_is_odd(const BIGNUM *bn); + +// BN_is_pow2 returns 1 if |a| is a power of two, and 0 otherwise. +OPENSSL_EXPORT int BN_is_pow2(const BIGNUM *a); + + +// Bitwise operations. + +// BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the +// same |BIGNUM|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_lshift1 sets |r| equal to |a| << 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift1(BIGNUM *r, const BIGNUM *a); + +// BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift1(BIGNUM *r, const BIGNUM *a); + +// BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if |a| +// is 2 then setting bit zero will make it 3. It returns one on success or zero +// on allocation failure. +OPENSSL_EXPORT int BN_set_bit(BIGNUM *a, int n); + +// BN_clear_bit clears the |n|th, least-significant bit in |a|. For example, if +// |a| is 3, clearing bit zero will make it two. It returns one on success or +// zero on allocation failure. +OPENSSL_EXPORT int BN_clear_bit(BIGNUM *a, int n); + +// BN_is_bit_set returns one if the |n|th least-significant bit in |a| exists +// and is set. Otherwise, it returns zero. +OPENSSL_EXPORT int BN_is_bit_set(const BIGNUM *a, int n); + +// BN_mask_bits truncates |a| so that it is only |n| bits long. It returns one +// on success or zero if |n| is negative. +// +// This differs from OpenSSL which additionally returns zero if |a|'s word +// length is less than or equal to |n|, rounded down to a number of words. Note +// word size is platform-dependent, so this behavior is also difficult to rely +// on in OpenSSL and not very useful. +OPENSSL_EXPORT int BN_mask_bits(BIGNUM *a, int n); + +// BN_count_low_zero_bits returns the number of low-order zero bits in |bn|, or +// the number of factors of two which divide it. It returns zero if |bn| is +// zero. +OPENSSL_EXPORT int BN_count_low_zero_bits(const BIGNUM *bn); + + +// Modulo arithmetic. + +// BN_mod_word returns |a| mod |w| or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); + +// BN_mod_pow2 sets |r| = |a| mod 2^|e|. It returns 1 on success and +// 0 on error. +OPENSSL_EXPORT int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_nnmod_pow2 sets |r| = |a| mod 2^|e| where |r| is always positive. +// It returns 1 on success and 0 on error. +OPENSSL_EXPORT int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_mod is a helper macro that calls |BN_div| and discards the quotient. +#define BN_mod(rem, numerator, divisor, ctx) \ + BN_div(NULL, (rem), (numerator), (divisor), (ctx)) + +// BN_nnmod is a non-negative modulo function. It acts like |BN_mod|, but 0 <= +// |rem| < |divisor| is always true. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx); + +// BN_mod_add sets |r| = |a| + |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_sub sets |r| = |a| - |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sub_quick acts like |BN_mod_sub| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_mul sets |r| = |a|*|b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sqr sets |r| = |a|^2 mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift sets |r| = (|a| << n) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_lshift_quick acts like |BN_mod_lshift| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m); + +// BN_mod_lshift1 sets |r| = (|a| << 1) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift1_quick acts like |BN_mod_lshift1| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, + const BIGNUM *m); + +// BN_mod_sqrt returns a newly-allocated |BIGNUM|, r, such that +// r^2 == a (mod p). It returns NULL on error or if |a| is not a square mod |p|. +// In the latter case, it will add |BN_R_NOT_A_SQUARE| to the error queue. +// If |a| is a square and |p| > 2, there are two possible square roots. This +// function may return either and may even select one non-deterministically. +// +// This function only works if |p| is a prime. If |p| is composite, it may fail +// or return an arbitrary value. Callers should not pass attacker-controlled +// values of |p|. +OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + + +// Random and prime number generation. + +// The following are values for the |top| parameter of |BN_rand|. +#define BN_RAND_TOP_ANY (-1) +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +// The following are values for the |bottom| parameter of |BN_rand|. +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +// BN_rand sets |rnd| to a random number of length |bits|. It returns one on +// success and zero otherwise. +// +// |top| must be one of the |BN_RAND_TOP_*| values. If |BN_RAND_TOP_ONE|, the +// most-significant bit, if any, will be set. If |BN_RAND_TOP_TWO|, the two +// most significant bits, if any, will be set. If |BN_RAND_TOP_ANY|, no extra +// action will be taken and |BN_num_bits(rnd)| may not equal |bits| if the most +// significant bits randomly ended up as zeros. +// +// |bottom| must be one of the |BN_RAND_BOTTOM_*| values. If +// |BN_RAND_BOTTOM_ODD|, the least-significant bit, if any, will be set. If +// |BN_RAND_BOTTOM_ANY|, no extra action will be taken. +OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_pseudo_rand is an alias for |BN_rand|. +OPENSSL_EXPORT int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_rand_range is equivalent to |BN_rand_range_ex| with |min_inclusive| set +// to zero and |max_exclusive| set to |range|. +OPENSSL_EXPORT int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); + +// BN_rand_range_ex sets |rnd| to a random value in +// [min_inclusive..max_exclusive). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +// BN_pseudo_rand_range is an alias for BN_rand_range. +OPENSSL_EXPORT int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); + +#define BN_GENCB_GENERATED 0 +#define BN_GENCB_PRIME_TEST 1 + +// bn_gencb_st, or |BN_GENCB|, holds a callback function that is used by +// generation functions that can take a very long time to complete. Use +// |BN_GENCB_set| to initialise a |BN_GENCB| structure. +// +// The callback receives the address of that |BN_GENCB| structure as its last +// argument and the user is free to put an arbitrary pointer in |arg|. The other +// arguments are set as follows: +// event=BN_GENCB_GENERATED, n=i: after generating the i'th possible prime +// number. +// event=BN_GENCB_PRIME_TEST, n=-1: when finished trial division primality +// checks. +// event=BN_GENCB_PRIME_TEST, n=i: when the i'th primality test has finished. +// +// The callback can return zero to abort the generation progress or one to +// allow it to continue. +// +// When other code needs to call a BN generation function it will often take a +// BN_GENCB argument and may call the function with other argument values. +struct bn_gencb_st { + void *arg; // callback-specific data + int (*callback)(int event, int n, struct bn_gencb_st *); +}; + +// BN_GENCB_new returns a newly-allocated |BN_GENCB| object, or NULL on +// allocation failure. The result must be released with |BN_GENCB_free| when +// done. +OPENSSL_EXPORT BN_GENCB *BN_GENCB_new(void); + +// BN_GENCB_free releases memory associated with |callback|. +OPENSSL_EXPORT void BN_GENCB_free(BN_GENCB *callback); + +// BN_GENCB_set configures |callback| to call |f| and sets |callout->arg| to +// |arg|. +OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, BN_GENCB *), + void *arg); + +// BN_GENCB_call calls |callback|, if not NULL, and returns the return value of +// the callback, or 1 if |callback| is NULL. +OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n); + +// BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe +// is non-zero then the prime will be such that (ret-1)/2 is also a prime. +// (This is needed for Diffie-Hellman groups to ensure that the only subgroups +// are of size 2 and (p-1)/2.). +// +// If |add| is not NULL, the prime will fulfill the condition |ret| % |add| == +// |rem| in order to suit a given generator. (If |rem| is NULL then |ret| % +// |add| == 1.) +// +// If |cb| is not NULL, it will be called during processing to give an +// indication of progress. See the comments for |BN_GENCB|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + BN_GENCB *cb); + +// BN_prime_checks_for_validation can be used as the |checks| argument to the +// primarily testing functions when validating an externally-supplied candidate +// prime. It gives a false positive rate of at most 2^{-128}. (The worst case +// false positive rate for a single iteration is 1/4 per +// https://eprint.iacr.org/2018/749. (1/4)^64 = 2^{-128}.) +#define BN_prime_checks_for_validation 64 + +// BN_prime_checks_for_generation can be used as the |checks| argument to the +// primality testing functions when generating random primes. It gives a false +// positive rate at most the security level of the corresponding RSA key size. +// +// Note this value only performs enough checks if the candidate prime was +// selected randomly. If validating an externally-supplied candidate, especially +// one that may be selected adversarially, use |BN_prime_checks_for_validation| +// instead. +#define BN_prime_checks_for_generation 0 + +// bn_primality_result_t enumerates the outcomes of primality-testing. +enum bn_primality_result_t { + bn_probably_prime, + bn_composite, + bn_non_prime_power_composite, +}; + +// BN_enhanced_miller_rabin_primality_test tests whether |w| is probably a prime +// number using the Enhanced Miller-Rabin Test (FIPS 186-4 C.3.2) with +// |checks| iterations and returns the result in |out_result|. Enhanced +// Miller-Rabin tests primality for odd integers greater than 3, returning +// |bn_probably_prime| if the number is probably prime, +// |bn_non_prime_power_composite| if the number is a composite that is not the +// power of a single prime, and |bn_composite| otherwise. It returns one on +// success and zero on failure. If |cb| is not NULL, then it is called during +// each iteration of the primality test. +// +// See |BN_prime_checks_for_validation| and |BN_prime_checks_for_generation| for +// recommended values of |checks|. +OPENSSL_EXPORT int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int checks, + BN_CTX *ctx, BN_GENCB *cb); + +// BN_primality_test sets |*is_probably_prime| to one if |candidate| is +// probably a prime number by the Miller-Rabin test or zero if it's certainly +// not. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning a false positive is at most 2^{2*checks}. See +// |BN_prime_checks_for_validation| and |BN_prime_checks_for_generation| for +// recommended values of |checks|. +// +// If |cb| is not NULL then it is called during the checking process. See the +// comment above |BN_GENCB|. +// +// The function returns one on success and zero on error. +OPENSSL_EXPORT int BN_primality_test(int *is_probably_prime, + const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_fasttest_ex returns one if |candidate| is probably a prime +// number by the Miller-Rabin test, zero if it's certainly not and -1 on error. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning one when |candidate| is composite is at most 2^{2*checks}. +// See |BN_prime_checks_for_validation| and |BN_prime_checks_for_generation| for +// recommended values of |checks|. +// +// If |cb| is not NULL then it is called during the checking process. See the +// comment above |BN_GENCB|. +// +// WARNING: deprecated. Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_ex acts the same as |BN_is_prime_fasttest_ex| with +// |do_trial_division| set to zero. +// +// WARNING: deprecated: Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, BN_GENCB *cb); + + +// Number theory functions + +// BN_gcd sets |r| = gcd(|a|, |b|). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mod_inverse sets |out| equal to |a|^-1, mod |n|. If |out| is NULL, a +// fresh BIGNUM is allocated. It returns the result or NULL on error. +// +// If |n| is even then the operation is performed using an algorithm that avoids +// some branches but which isn't constant-time. This function shouldn't be used +// for secret values; use |BN_mod_inverse_blinded| instead. Or, if |n| is +// guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. +OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + +// BN_mod_inverse_blinded sets |out| equal to |a|^-1, mod |n|, where |n| is the +// Montgomery modulus for |mont|. |a| must be non-negative and must be less +// than |n|. |n| must be greater than 1. |a| is blinded (masked by a random +// value) to protect it against side-channel attacks. On failure, if the failure +// was caused by |a| having no inverse mod |n| then |*out_no_inverse| will be +// set to one; otherwise it will be set to zero. +// +// Note this function may incorrectly report |a| has no inverse if the random +// blinding value has no inverse. It should only be used when |n| has few +// non-invertible elements, such as an RSA modulus. +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be +// non-negative and must be less than |n|. |n| must be odd. This function +// shouldn't be used for secret values; use |BN_mod_inverse_blinded| instead. +// Or, if |n| is guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. It returns one on success or zero on +// failure. On failure, if the failure was caused by |a| having no inverse mod +// |n| then |*out_no_inverse| will be set to one; otherwise it will be set to +// zero. +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + + +// Montgomery arithmetic. + +// BN_MONT_CTX contains the precomputed values needed to work in a specific +// Montgomery domain. + +// BN_MONT_CTX_new_for_modulus returns a fresh |BN_MONT_CTX| given the modulus, +// |mod| or NULL on error. Note this function assumes |mod| is public. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, + BN_CTX *ctx); + +// BN_MONT_CTX_new_consttime behaves like |BN_MONT_CTX_new_for_modulus| but +// treats |mod| as secret. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new_consttime(const BIGNUM *mod, + BN_CTX *ctx); + +// BN_MONT_CTX_free frees memory associated with |mont|. +OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont); + +// BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or +// NULL on error. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, + const BN_MONT_CTX *from); + +// BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If +// so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It +// then stores it as |*pmont|. It returns one on success and zero on error. Note +// this function assumes |mod| is public. +// +// If |*pmont| is already non-NULL then it does nothing and returns one. +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx); + +// BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. |a| is +// assumed to be in the range [0, n), where |n| is the Montgomery modulus. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_from_montgomery sets |ret| equal to |a| * R^-1, i.e. translates values out +// of the Montgomery domain. |a| is assumed to be in the range [0, n*R), where +// |n| is the Montgomery modulus. Note n < R, so inputs in the range [0, n*n) +// are valid. This function returns one on success or zero on error. +OPENSSL_EXPORT int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_mul_montgomery set |r| equal to |a| * |b|, in the Montgomery domain. +// Both |a| and |b| must already be in the Montgomery domain (by +// |BN_to_montgomery|). In particular, |a| and |b| are assumed to be in the +// range [0, n), where |n| is the Montgomery modulus. It returns one on success +// or zero on error. +OPENSSL_EXPORT int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx); + + +// Exponentiation. + +// BN_exp sets |r| equal to |a|^{|p|}. It does so with a square-and-multiply +// algorithm that leaks side-channel information. It returns one on success or +// zero otherwise. +OPENSSL_EXPORT int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + +// BN_mod_exp sets |r| equal to |a|^{|p|} mod |m|. It does so with the best +// algorithm for the values provided. It returns one on success or zero +// otherwise. The |BN_mod_exp_mont_consttime| variant must be used if the +// exponent is secret. +OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_exp_mont behaves like |BN_mod_exp| but treats |a| as secret and +// requires 0 <= |a| < |m|. +OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +// BN_mod_exp_mont_consttime behaves like |BN_mod_exp| but treats |a|, |p|, and +// |m| as secret and requires 0 <= |a| < |m|. +OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, + const BN_MONT_CTX *mont); + + +// Deprecated functions + +// BN_bn2mpi serialises the value of |in| to |out|, using a format that consists +// of the number's length in bytes represented as a 4-byte big-endian number, +// and the number itself in big-endian format, where the most significant bit +// signals a negative number. (The representation of numbers with the MSB set is +// prefixed with null byte). |out| must have sufficient space available; to +// find the needed amount of space, call the function with |out| set to NULL. +OPENSSL_EXPORT size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out); + +// BN_mpi2bn parses |len| bytes from |in| and returns the resulting value. The +// bytes at |in| are expected to be in the format emitted by |BN_bn2mpi|. +// +// If |out| is NULL then a fresh |BIGNUM| is allocated and returned, otherwise +// |out| is reused and returned. On error, NULL is returned and the error queue +// is updated. +OPENSSL_EXPORT BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out); + +// BN_mod_exp_mont_word is like |BN_mod_exp_mont| except that the base |a| is +// given as a |BN_ULONG| instead of a |BIGNUM *|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +// BN_mod_exp2_mont calculates (a1^p1) * (a2^p2) mod m. It returns 1 on success +// or zero otherwise. +OPENSSL_EXPORT int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, + const BIGNUM *p1, const BIGNUM *a2, + const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, const BN_MONT_CTX *mont); + +// BN_MONT_CTX_new returns a fresh |BN_MONT_CTX| or NULL on allocation failure. +// Use |BN_MONT_CTX_new_for_modulus| instead. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void); + +// BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It +// returns one on success and zero on error. Use |BN_MONT_CTX_new_for_modulus| +// instead. +OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, + BN_CTX *ctx); + +// BN_bn2binpad behaves like |BN_bn2bin_padded|, but it returns |len| on success +// and -1 on error. +// +// Use |BN_bn2bin_padded| instead. It is |size_t|-clean. +OPENSSL_EXPORT int BN_bn2binpad(const BIGNUM *in, uint8_t *out, int len); + +// BN_prime_checks is a deprecated alias for |BN_prime_checks_for_validation|. +// Use |BN_prime_checks_for_generation| or |BN_prime_checks_for_validation| +// instead. (This defaults to the |_for_validation| value in order to be +// conservative.) +#define BN_prime_checks BN_prime_checks_for_validation + + +// Private functions + +struct bignum_st { + // d is a pointer to an array of |width| |BN_BITS2|-bit chunks in + // little-endian order. This stores the absolute value of the number. + BN_ULONG *d; + // width is the number of elements of |d| which are valid. This value is not + // necessarily minimal; the most-significant words of |d| may be zero. + // |width| determines a potentially loose upper-bound on the absolute value + // of the |BIGNUM|. + // + // Functions taking |BIGNUM| inputs must compute the same answer for all + // possible widths. |bn_minimal_width|, |bn_set_minimal_width|, and other + // helpers may be used to recover the minimal width, provided it is not + // secret. If it is secret, use a different algorithm. Functions may output + // minimal or non-minimal |BIGNUM|s depending on secrecy requirements, but + // those which cause widths to unboundedly grow beyond the minimal value + // should be documented such. + // + // Note this is different from historical |BIGNUM| semantics. + int width; + // dmax is number of elements of |d| which are allocated. + int dmax; + // neg is one if the number if negative and zero otherwise. + int neg; + // flags is a bitmask of |BN_FLG_*| values + int flags; +}; + +struct bn_mont_ctx_st { + // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. It + // is guaranteed to have the same width as |N|. + BIGNUM RR; + // N is the modulus. It is always stored in minimal form, so |N.width| + // determines R. + BIGNUM N; + BN_ULONG n0[2]; // least significant words of (R*Ri-1)/N +}; + +OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +// |BN_FLG_CONSTTIME| has been removed and intentionally omitted so code relying +// on it will not compile. Consumers outside BoringSSL should use the +// higher-level cryptographic algorithms exposed by other modules. Consumers +// within the library should call the appropriate timing-sensitive algorithm +// directly. + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(BIGNUM, BN_free) +BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free) +BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free) + +class BN_CTXScope { + public: + BN_CTXScope(BN_CTX *ctx) : ctx_(ctx) { BN_CTX_start(ctx_); } + ~BN_CTXScope() { BN_CTX_end(ctx_); } + + private: + BN_CTX *ctx_; + + BN_CTXScope(BN_CTXScope &) = delete; + BN_CTXScope &operator=(BN_CTXScope &) = delete; +}; + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 102 +#define BN_R_BITS_TOO_SMALL 103 +#define BN_R_CALLED_WITH_EVEN_MODULUS 104 +#define BN_R_DIV_BY_ZERO 105 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 106 +#define BN_R_INPUT_NOT_REDUCED 107 +#define BN_R_INVALID_RANGE 108 +#define BN_R_NEGATIVE_NUMBER 109 +#define BN_R_NOT_A_SQUARE 110 +#define BN_R_NOT_INITIALIZED 111 +#define BN_R_NO_INVERSE 112 +#define BN_R_PRIVATE_KEY_TOO_LARGE 113 +#define BN_R_P_IS_NOT_PRIME 114 +#define BN_R_TOO_MANY_ITERATIONS 115 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116 +#define BN_R_BAD_ENCODING 117 +#define BN_R_ENCODE_ERROR 118 +#define BN_R_INVALID_INPUT 119 + +#endif // OPENSSL_HEADER_BN_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h new file mode 100644 index 00000000..cc9c0a9f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h @@ -0,0 +1,4501 @@ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// BORINGSSL_ADD_PREFIX pastes two identifiers into one. It performs one +// iteration of macro expansion on its arguments before pasting. +#define BORINGSSL_ADD_PREFIX(a, b) BORINGSSL_ADD_PREFIX_INNER(a, b) +#define BORINGSSL_ADD_PREFIX_INNER(a, b) a ## _ ## b + +#define ACCESS_DESCRIPTION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_free) +#define ACCESS_DESCRIPTION_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_it) +#define ACCESS_DESCRIPTION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_new) +#define AES_CMAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_CMAC) +#define AES_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_cbc_encrypt) +#define AES_cfb128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_cfb128_encrypt) +#define AES_ctr128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_ctr128_encrypt) +#define AES_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_decrypt) +#define AES_ecb_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_ecb_encrypt) +#define AES_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_encrypt) +#define AES_ofb128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_ofb128_encrypt) +#define AES_set_decrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_set_decrypt_key) +#define AES_set_encrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_set_encrypt_key) +#define AES_unwrap_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_unwrap_key) +#define AES_unwrap_key_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_unwrap_key_padded) +#define AES_wrap_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_wrap_key) +#define AES_wrap_key_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AES_wrap_key_padded) +#define ASN1_ANY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ANY_it) +#define ASN1_BIT_STRING_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_check) +#define ASN1_BIT_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_free) +#define ASN1_BIT_STRING_get_bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_get_bit) +#define ASN1_BIT_STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_it) +#define ASN1_BIT_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_new) +#define ASN1_BIT_STRING_num_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_num_bytes) +#define ASN1_BIT_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_set) +#define ASN1_BIT_STRING_set_bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BIT_STRING_set_bit) +#define ASN1_BMPSTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BMPSTRING_free) +#define ASN1_BMPSTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BMPSTRING_it) +#define ASN1_BMPSTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BMPSTRING_new) +#define ASN1_BOOLEAN_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_BOOLEAN_it) +#define ASN1_ENUMERATED_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_free) +#define ASN1_ENUMERATED_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_get) +#define ASN1_ENUMERATED_get_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_get_uint64) +#define ASN1_ENUMERATED_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_it) +#define ASN1_ENUMERATED_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_new) +#define ASN1_ENUMERATED_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_set) +#define ASN1_ENUMERATED_set_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_set_uint64) +#define ASN1_ENUMERATED_to_BN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_ENUMERATED_to_BN) +#define ASN1_FBOOLEAN_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_FBOOLEAN_it) +#define ASN1_GENERALIZEDTIME_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_adj) +#define ASN1_GENERALIZEDTIME_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_check) +#define ASN1_GENERALIZEDTIME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_free) +#define ASN1_GENERALIZEDTIME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_it) +#define ASN1_GENERALIZEDTIME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_new) +#define ASN1_GENERALIZEDTIME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_print) +#define ASN1_GENERALIZEDTIME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_set) +#define ASN1_GENERALIZEDTIME_set_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_set_string) +#define ASN1_GENERALSTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALSTRING_free) +#define ASN1_GENERALSTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALSTRING_it) +#define ASN1_GENERALSTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_GENERALSTRING_new) +#define ASN1_IA5STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_IA5STRING_free) +#define ASN1_IA5STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_IA5STRING_it) +#define ASN1_IA5STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_IA5STRING_new) +#define ASN1_INTEGER_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_cmp) +#define ASN1_INTEGER_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_dup) +#define ASN1_INTEGER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_free) +#define ASN1_INTEGER_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_get) +#define ASN1_INTEGER_get_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_get_uint64) +#define ASN1_INTEGER_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_it) +#define ASN1_INTEGER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_new) +#define ASN1_INTEGER_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_set) +#define ASN1_INTEGER_set_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_set_uint64) +#define ASN1_INTEGER_to_BN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_INTEGER_to_BN) +#define ASN1_NULL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_NULL_free) +#define ASN1_NULL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_NULL_it) +#define ASN1_NULL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_NULL_new) +#define ASN1_OBJECT_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OBJECT_create) +#define ASN1_OBJECT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OBJECT_free) +#define ASN1_OBJECT_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OBJECT_it) +#define ASN1_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OBJECT_new) +#define ASN1_OCTET_STRING_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_cmp) +#define ASN1_OCTET_STRING_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_dup) +#define ASN1_OCTET_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_free) +#define ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) +#define ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) +#define ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) +#define ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) +#define ASN1_PRINTABLESTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_new) +#define ASN1_PRINTABLE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_free) +#define ASN1_PRINTABLE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_it) +#define ASN1_PRINTABLE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_new) +#define ASN1_PRINTABLE_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLE_type) +#define ASN1_SEQUENCE_ANY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_ANY_it) +#define ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) +#define ASN1_SET_ANY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SET_ANY_it) +#define ASN1_STRING_TABLE_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_TABLE_add) +#define ASN1_STRING_TABLE_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_TABLE_cleanup) +#define ASN1_STRING_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_cmp) +#define ASN1_STRING_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_copy) +#define ASN1_STRING_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_data) +#define ASN1_STRING_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_dup) +#define ASN1_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_free) +#define ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) +#define ASN1_STRING_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_length) +#define ASN1_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_new) +#define ASN1_STRING_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_print) +#define ASN1_STRING_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_print_ex) +#define ASN1_STRING_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_print_ex_fp) +#define ASN1_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_set) +#define ASN1_STRING_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_set0) +#define ASN1_STRING_set_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_set_by_NID) +#define ASN1_STRING_set_default_mask BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_set_default_mask) +#define ASN1_STRING_set_default_mask_asc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_set_default_mask_asc) +#define ASN1_STRING_to_UTF8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_to_UTF8) +#define ASN1_STRING_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_type) +#define ASN1_STRING_type_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_type_new) +#define ASN1_T61STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_T61STRING_free) +#define ASN1_T61STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_T61STRING_it) +#define ASN1_T61STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_T61STRING_new) +#define ASN1_TBOOLEAN_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TBOOLEAN_it) +#define ASN1_TIME_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_adj) +#define ASN1_TIME_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_check) +#define ASN1_TIME_diff BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_diff) +#define ASN1_TIME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_free) +#define ASN1_TIME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_it) +#define ASN1_TIME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_new) +#define ASN1_TIME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_print) +#define ASN1_TIME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_set) +#define ASN1_TIME_set_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_set_string) +#define ASN1_TIME_to_generalizedtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TIME_to_generalizedtime) +#define ASN1_TYPE_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_cmp) +#define ASN1_TYPE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_free) +#define ASN1_TYPE_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_get) +#define ASN1_TYPE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_new) +#define ASN1_TYPE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_set) +#define ASN1_TYPE_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_TYPE_set1) +#define ASN1_UNIVERSALSTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_free) +#define ASN1_UNIVERSALSTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_it) +#define ASN1_UNIVERSALSTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_new) +#define ASN1_UTCTIME_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_adj) +#define ASN1_UTCTIME_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_check) +#define ASN1_UTCTIME_cmp_time_t BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_cmp_time_t) +#define ASN1_UTCTIME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_free) +#define ASN1_UTCTIME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_it) +#define ASN1_UTCTIME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_new) +#define ASN1_UTCTIME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_print) +#define ASN1_UTCTIME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_set) +#define ASN1_UTCTIME_set_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTCTIME_set_string) +#define ASN1_UTF8STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTF8STRING_free) +#define ASN1_UTF8STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTF8STRING_it) +#define ASN1_UTF8STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_UTF8STRING_new) +#define ASN1_VISIBLESTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_free) +#define ASN1_VISIBLESTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_it) +#define ASN1_VISIBLESTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_new) +#define ASN1_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_digest) +#define ASN1_generate_v3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_generate_v3) +#define ASN1_get_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_get_object) +#define ASN1_item_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_d2i) +#define ASN1_item_d2i_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_d2i_bio) +#define ASN1_item_d2i_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_d2i_fp) +#define ASN1_item_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_digest) +#define ASN1_item_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_dup) +#define ASN1_item_ex_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_ex_d2i) +#define ASN1_item_ex_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_ex_free) +#define ASN1_item_ex_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_ex_i2d) +#define ASN1_item_ex_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_ex_new) +#define ASN1_item_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_free) +#define ASN1_item_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_i2d) +#define ASN1_item_i2d_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_i2d_bio) +#define ASN1_item_i2d_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_i2d_fp) +#define ASN1_item_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_new) +#define ASN1_item_pack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_pack) +#define ASN1_item_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_sign) +#define ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_sign_ctx) +#define ASN1_item_unpack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_unpack) +#define ASN1_item_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_verify) +#define ASN1_mbstring_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_copy) +#define ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) +#define ASN1_object_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_object_size) +#define ASN1_primitive_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_primitive_free) +#define ASN1_put_eoc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_put_eoc) +#define ASN1_put_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_put_object) +#define ASN1_tag2bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_tag2bit) +#define ASN1_tag2str BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_tag2str) +#define ASN1_template_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_template_free) +#define AUTHORITY_INFO_ACCESS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_free) +#define AUTHORITY_INFO_ACCESS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_it) +#define AUTHORITY_INFO_ACCESS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_new) +#define AUTHORITY_KEYID_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_KEYID_free) +#define AUTHORITY_KEYID_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_KEYID_it) +#define AUTHORITY_KEYID_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, AUTHORITY_KEYID_new) +#define BASIC_CONSTRAINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_free) +#define BASIC_CONSTRAINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_it) +#define BASIC_CONSTRAINTS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_new) +#define BIO_append_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_append_filename) +#define BIO_callback_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_callback_ctrl) +#define BIO_clear_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_clear_flags) +#define BIO_clear_retry_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_clear_retry_flags) +#define BIO_copy_next_retry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_copy_next_retry) +#define BIO_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_ctrl) +#define BIO_ctrl_get_read_request BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_ctrl_get_read_request) +#define BIO_ctrl_get_write_guarantee BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_ctrl_get_write_guarantee) +#define BIO_ctrl_pending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_ctrl_pending) +#define BIO_do_connect BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_do_connect) +#define BIO_eof BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_eof) +#define BIO_f_ssl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_f_ssl) +#define BIO_find_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_find_type) +#define BIO_flush BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_flush) +#define BIO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_free) +#define BIO_free_all BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_free_all) +#define BIO_get_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_data) +#define BIO_get_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_fd) +#define BIO_get_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_fp) +#define BIO_get_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_init) +#define BIO_get_mem_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_mem_data) +#define BIO_get_mem_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_mem_ptr) +#define BIO_get_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_new_index) +#define BIO_get_retry_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_retry_flags) +#define BIO_get_retry_reason BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_retry_reason) +#define BIO_get_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_get_shutdown) +#define BIO_gets BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_gets) +#define BIO_hexdump BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_hexdump) +#define BIO_indent BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_indent) +#define BIO_int_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_int_ctrl) +#define BIO_mem_contents BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_mem_contents) +#define BIO_meth_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_free) +#define BIO_meth_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_new) +#define BIO_meth_set_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_create) +#define BIO_meth_set_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_ctrl) +#define BIO_meth_set_destroy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_destroy) +#define BIO_meth_set_gets BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_gets) +#define BIO_meth_set_puts BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_puts) +#define BIO_meth_set_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_read) +#define BIO_meth_set_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_meth_set_write) +#define BIO_method_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_method_type) +#define BIO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new) +#define BIO_new_bio_pair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_bio_pair) +#define BIO_new_connect BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_connect) +#define BIO_new_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_fd) +#define BIO_new_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_file) +#define BIO_new_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_fp) +#define BIO_new_mem_buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_mem_buf) +#define BIO_new_socket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_new_socket) +#define BIO_next BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_next) +#define BIO_number_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_number_read) +#define BIO_number_written BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_number_written) +#define BIO_pending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_pending) +#define BIO_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_pop) +#define BIO_printf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_printf) +#define BIO_ptr_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_ptr_ctrl) +#define BIO_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_push) +#define BIO_puts BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_puts) +#define BIO_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_read) +#define BIO_read_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_read_asn1) +#define BIO_read_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_read_filename) +#define BIO_reset BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_reset) +#define BIO_rw_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_rw_filename) +#define BIO_s_connect BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_s_connect) +#define BIO_s_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_s_fd) +#define BIO_s_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_s_file) +#define BIO_s_mem BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_s_mem) +#define BIO_s_socket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_s_socket) +#define BIO_seek BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_seek) +#define BIO_set_close BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_close) +#define BIO_set_conn_hostname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_conn_hostname) +#define BIO_set_conn_int_port BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_conn_int_port) +#define BIO_set_conn_port BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_conn_port) +#define BIO_set_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_data) +#define BIO_set_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_fd) +#define BIO_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_flags) +#define BIO_set_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_fp) +#define BIO_set_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_init) +#define BIO_set_mem_buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_mem_buf) +#define BIO_set_mem_eof_return BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_mem_eof_return) +#define BIO_set_nbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_nbio) +#define BIO_set_retry_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_retry_read) +#define BIO_set_retry_reason BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_retry_reason) +#define BIO_set_retry_special BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_retry_special) +#define BIO_set_retry_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_retry_write) +#define BIO_set_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_shutdown) +#define BIO_set_ssl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_ssl) +#define BIO_set_write_buffer_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_set_write_buffer_size) +#define BIO_should_io_special BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_should_io_special) +#define BIO_should_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_should_read) +#define BIO_should_retry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_should_retry) +#define BIO_should_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_should_write) +#define BIO_shutdown_wr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_shutdown_wr) +#define BIO_snprintf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_snprintf) +#define BIO_tell BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_tell) +#define BIO_test_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_test_flags) +#define BIO_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_up_ref) +#define BIO_vfree BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_vfree) +#define BIO_vsnprintf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_vsnprintf) +#define BIO_wpending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_wpending) +#define BIO_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_write) +#define BIO_write_all BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_write_all) +#define BIO_write_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_write_filename) +#define BLAKE2B256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BLAKE2B256) +#define BLAKE2B256_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BLAKE2B256_Final) +#define BLAKE2B256_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BLAKE2B256_Init) +#define BLAKE2B256_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BLAKE2B256_Update) +#define BN_BLINDING_convert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_BLINDING_convert) +#define BN_BLINDING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_BLINDING_free) +#define BN_BLINDING_invalidate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_BLINDING_invalidate) +#define BN_BLINDING_invert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_BLINDING_invert) +#define BN_BLINDING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_BLINDING_new) +#define BN_CTX_end BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_CTX_end) +#define BN_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_CTX_free) +#define BN_CTX_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_CTX_get) +#define BN_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_CTX_new) +#define BN_CTX_start BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_CTX_start) +#define BN_GENCB_call BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_GENCB_call) +#define BN_GENCB_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_GENCB_free) +#define BN_GENCB_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_GENCB_new) +#define BN_GENCB_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_GENCB_set) +#define BN_MONT_CTX_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_copy) +#define BN_MONT_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_free) +#define BN_MONT_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_new) +#define BN_MONT_CTX_new_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_new_consttime) +#define BN_MONT_CTX_new_for_modulus BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_new_for_modulus) +#define BN_MONT_CTX_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_set) +#define BN_MONT_CTX_set_locked BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_MONT_CTX_set_locked) +#define BN_abs_is_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_abs_is_word) +#define BN_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_add) +#define BN_add_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_add_word) +#define BN_asc2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_asc2bn) +#define BN_bin2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bin2bn) +#define BN_bn2bin BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2bin) +#define BN_bn2bin_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2bin_padded) +#define BN_bn2binpad BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2binpad) +#define BN_bn2cbb_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2cbb_padded) +#define BN_bn2dec BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2dec) +#define BN_bn2hex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2hex) +#define BN_bn2le_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2le_padded) +#define BN_bn2mpi BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_bn2mpi) +#define BN_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_clear) +#define BN_clear_bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_clear_bit) +#define BN_clear_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_clear_free) +#define BN_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_cmp) +#define BN_cmp_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_cmp_word) +#define BN_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_copy) +#define BN_count_low_zero_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_count_low_zero_bits) +#define BN_dec2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_dec2bn) +#define BN_div BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_div) +#define BN_div_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_div_word) +#define BN_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_dup) +#define BN_enhanced_miller_rabin_primality_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_enhanced_miller_rabin_primality_test) +#define BN_equal_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_equal_consttime) +#define BN_exp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_exp) +#define BN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_free) +#define BN_from_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_from_montgomery) +#define BN_gcd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_gcd) +#define BN_generate_prime_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_generate_prime_ex) +#define BN_get_rfc3526_prime_1536 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_get_rfc3526_prime_1536) +#define BN_get_u64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_get_u64) +#define BN_get_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_get_word) +#define BN_hex2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_hex2bn) +#define BN_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_init) +#define BN_is_bit_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_bit_set) +#define BN_is_negative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_negative) +#define BN_is_odd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_odd) +#define BN_is_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_one) +#define BN_is_pow2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_pow2) +#define BN_is_prime_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_prime_ex) +#define BN_is_prime_fasttest_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_prime_fasttest_ex) +#define BN_is_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_word) +#define BN_is_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_is_zero) +#define BN_le2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_le2bn) +#define BN_lshift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_lshift) +#define BN_lshift1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_lshift1) +#define BN_marshal_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_marshal_asn1) +#define BN_mask_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mask_bits) +#define BN_mod_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_add) +#define BN_mod_add_quick BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_add_quick) +#define BN_mod_exp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_exp) +#define BN_mod_exp2_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_exp2_mont) +#define BN_mod_exp_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_exp_mont) +#define BN_mod_exp_mont_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_exp_mont_consttime) +#define BN_mod_exp_mont_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_exp_mont_word) +#define BN_mod_inverse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_inverse) +#define BN_mod_inverse_blinded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_inverse_blinded) +#define BN_mod_inverse_odd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_inverse_odd) +#define BN_mod_lshift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_lshift) +#define BN_mod_lshift1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_lshift1) +#define BN_mod_lshift1_quick BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_lshift1_quick) +#define BN_mod_lshift_quick BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_lshift_quick) +#define BN_mod_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_mul) +#define BN_mod_mul_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_mul_montgomery) +#define BN_mod_pow2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_pow2) +#define BN_mod_sqr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_sqr) +#define BN_mod_sqrt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_sqrt) +#define BN_mod_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_sub) +#define BN_mod_sub_quick BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_sub_quick) +#define BN_mod_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mod_word) +#define BN_mpi2bn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mpi2bn) +#define BN_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mul) +#define BN_mul_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mul_word) +#define BN_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_new) +#define BN_nnmod BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_nnmod) +#define BN_nnmod_pow2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_nnmod_pow2) +#define BN_num_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_num_bits) +#define BN_num_bits_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_num_bits_word) +#define BN_num_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_num_bytes) +#define BN_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_one) +#define BN_parse_asn1_unsigned BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_parse_asn1_unsigned) +#define BN_primality_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_primality_test) +#define BN_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_print) +#define BN_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_print_fp) +#define BN_pseudo_rand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_pseudo_rand) +#define BN_pseudo_rand_range BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_pseudo_rand_range) +#define BN_rand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_rand) +#define BN_rand_range BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_rand_range) +#define BN_rand_range_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_rand_range_ex) +#define BN_rshift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_rshift) +#define BN_rshift1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_rshift1) +#define BN_set_bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_set_bit) +#define BN_set_negative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_set_negative) +#define BN_set_u64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_set_u64) +#define BN_set_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_set_word) +#define BN_sqr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_sqr) +#define BN_sqrt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_sqrt) +#define BN_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_sub) +#define BN_sub_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_sub_word) +#define BN_to_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_to_ASN1_ENUMERATED) +#define BN_to_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_to_ASN1_INTEGER) +#define BN_to_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_to_montgomery) +#define BN_uadd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_uadd) +#define BN_ucmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_ucmp) +#define BN_usub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_usub) +#define BN_value_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_value_one) +#define BN_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_zero) +#define BORINGSSL_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BORINGSSL_self_test) +#define BUF_MEM_append BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_append) +#define BUF_MEM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_free) +#define BUF_MEM_grow BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_grow) +#define BUF_MEM_grow_clean BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_grow_clean) +#define BUF_MEM_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_new) +#define BUF_MEM_reserve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_reserve) +#define BUF_memdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_memdup) +#define BUF_strdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_strdup) +#define BUF_strlcat BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_strlcat) +#define BUF_strlcpy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_strlcpy) +#define BUF_strndup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_strndup) +#define BUF_strnlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_strnlen) +#define CBB_add_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1) +#define CBB_add_asn1_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_bool) +#define CBB_add_asn1_int64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_int64) +#define CBB_add_asn1_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_octet_string) +#define CBB_add_asn1_oid_from_text BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_oid_from_text) +#define CBB_add_asn1_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_uint64) +#define CBB_add_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_bytes) +#define CBB_add_space BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_space) +#define CBB_add_u16 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u16) +#define CBB_add_u16_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u16_length_prefixed) +#define CBB_add_u16le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u16le) +#define CBB_add_u24 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u24) +#define CBB_add_u24_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u24_length_prefixed) +#define CBB_add_u32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u32) +#define CBB_add_u32le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u32le) +#define CBB_add_u64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u64) +#define CBB_add_u64le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u64le) +#define CBB_add_u8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u8) +#define CBB_add_u8_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u8_length_prefixed) +#define CBB_add_zeros BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_zeros) +#define CBB_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_cleanup) +#define CBB_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_data) +#define CBB_did_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_did_write) +#define CBB_discard_child BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_discard_child) +#define CBB_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_finish) +#define CBB_finish_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_finish_i2d) +#define CBB_flush BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_flush) +#define CBB_flush_asn1_set_of BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_flush_asn1_set_of) +#define CBB_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_init) +#define CBB_init_fixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_init_fixed) +#define CBB_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_len) +#define CBB_reserve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_reserve) +#define CBB_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_zero) +#define CBS_asn1_ber_to_der BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_asn1_ber_to_der) +#define CBS_asn1_bitstring_has_bit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_asn1_bitstring_has_bit) +#define CBS_asn1_oid_to_text BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_asn1_oid_to_text) +#define CBS_contains_zero_byte BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_contains_zero_byte) +#define CBS_copy_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_copy_bytes) +#define CBS_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_data) +#define CBS_get_any_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_asn1) +#define CBS_get_any_asn1_element BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_asn1_element) +#define CBS_get_any_ber_asn1_element BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_ber_asn1_element) +#define CBS_get_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1) +#define CBS_get_asn1_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1_bool) +#define CBS_get_asn1_element BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1_element) +#define CBS_get_asn1_implicit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1_implicit_string) +#define CBS_get_asn1_int64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1_int64) +#define CBS_get_asn1_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_asn1_uint64) +#define CBS_get_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_bytes) +#define CBS_get_last_u8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_last_u8) +#define CBS_get_optional_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_optional_asn1) +#define CBS_get_optional_asn1_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_optional_asn1_bool) +#define CBS_get_optional_asn1_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_optional_asn1_octet_string) +#define CBS_get_optional_asn1_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_optional_asn1_uint64) +#define CBS_get_u16 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u16) +#define CBS_get_u16_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u16_length_prefixed) +#define CBS_get_u16le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u16le) +#define CBS_get_u24 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u24) +#define CBS_get_u24_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u24_length_prefixed) +#define CBS_get_u32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u32) +#define CBS_get_u32le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u32le) +#define CBS_get_u64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u64) +#define CBS_get_u64le BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u64le) +#define CBS_get_u8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u8) +#define CBS_get_u8_length_prefixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_u8_length_prefixed) +#define CBS_get_until_first BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_until_first) +#define CBS_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_init) +#define CBS_is_unsigned_asn1_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_unsigned_asn1_integer) +#define CBS_is_valid_asn1_bitstring BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_bitstring) +#define CBS_is_valid_asn1_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_integer) +#define CBS_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_len) +#define CBS_mem_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_mem_equal) +#define CBS_peek_asn1_tag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_peek_asn1_tag) +#define CBS_skip BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_skip) +#define CBS_stow BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_stow) +#define CBS_strdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_strdup) +#define CERTIFICATEPOLICIES_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_free) +#define CERTIFICATEPOLICIES_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_it) +#define CERTIFICATEPOLICIES_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_new) +#define CMAC_CTX_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_CTX_copy) +#define CMAC_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_CTX_free) +#define CMAC_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_CTX_new) +#define CMAC_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_Final) +#define CMAC_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_Init) +#define CMAC_Reset BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_Reset) +#define CMAC_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMAC_Update) +#define CONF_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_VALUE_new) +#define CONF_modules_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_free) +#define CONF_modules_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_load_file) +#define CONF_parse_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_parse_list) +#define CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) +#define CRL_DIST_POINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRL_DIST_POINTS_it) +#define CRL_DIST_POINTS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRL_DIST_POINTS_new) +#define CRYPTO_BUFFER_POOL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_POOL_free) +#define CRYPTO_BUFFER_POOL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_POOL_new) +#define CRYPTO_BUFFER_alloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_alloc) +#define CRYPTO_BUFFER_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_data) +#define CRYPTO_BUFFER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_free) +#define CRYPTO_BUFFER_init_CBS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_init_CBS) +#define CRYPTO_BUFFER_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_len) +#define CRYPTO_BUFFER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_new) +#define CRYPTO_BUFFER_new_from_CBS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_new_from_CBS) +#define CRYPTO_BUFFER_new_from_static_data_unsafe BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_new_from_static_data_unsafe) +#define CRYPTO_BUFFER_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_BUFFER_up_ref) +#define CRYPTO_MUTEX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_cleanup) +#define CRYPTO_MUTEX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_init) +#define CRYPTO_MUTEX_lock_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_read) +#define CRYPTO_MUTEX_lock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_write) +#define CRYPTO_MUTEX_unlock_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_read) +#define CRYPTO_MUTEX_unlock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_write) +#define CRYPTO_POLYVAL_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_POLYVAL_finish) +#define CRYPTO_POLYVAL_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_POLYVAL_init) +#define CRYPTO_POLYVAL_update_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_POLYVAL_update_blocks) +#define CRYPTO_STATIC_MUTEX_lock_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_lock_read) +#define CRYPTO_STATIC_MUTEX_lock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_lock_write) +#define CRYPTO_STATIC_MUTEX_unlock_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_unlock_read) +#define CRYPTO_STATIC_MUTEX_unlock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_unlock_write) +#define CRYPTO_THREADID_current BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_THREADID_current) +#define CRYPTO_THREADID_set_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_THREADID_set_callback) +#define CRYPTO_THREADID_set_numeric BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_THREADID_set_numeric) +#define CRYPTO_THREADID_set_pointer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_THREADID_set_pointer) +#define CRYPTO_cbc128_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cbc128_decrypt) +#define CRYPTO_cbc128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cbc128_encrypt) +#define CRYPTO_cfb128_1_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cfb128_1_encrypt) +#define CRYPTO_cfb128_8_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cfb128_8_encrypt) +#define CRYPTO_cfb128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cfb128_encrypt) +#define CRYPTO_chacha_20 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_chacha_20) +#define CRYPTO_cleanup_all_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_cleanup_all_ex_data) +#define CRYPTO_ctr128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt) +#define CRYPTO_ctr128_encrypt_ctr32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt_ctr32) +#define CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing) +#define CRYPTO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_free) +#define CRYPTO_free_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_free_ex_data) +#define CRYPTO_gcm128_aad BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_aad) +#define CRYPTO_gcm128_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_decrypt) +#define CRYPTO_gcm128_decrypt_ctr32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_decrypt_ctr32) +#define CRYPTO_gcm128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_encrypt) +#define CRYPTO_gcm128_encrypt_ctr32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_encrypt_ctr32) +#define CRYPTO_gcm128_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_finish) +#define CRYPTO_gcm128_init_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_init_key) +#define CRYPTO_gcm128_setiv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_setiv) +#define CRYPTO_gcm128_tag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_gcm128_tag) +#define CRYPTO_get_dynlock_create_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_dynlock_create_callback) +#define CRYPTO_get_dynlock_destroy_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_dynlock_destroy_callback) +#define CRYPTO_get_dynlock_lock_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_dynlock_lock_callback) +#define CRYPTO_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_ex_data) +#define CRYPTO_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_ex_new_index) +#define CRYPTO_get_fork_generation BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_fork_generation) +#define CRYPTO_get_lock_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_lock_name) +#define CRYPTO_get_locking_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_locking_callback) +#define CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_thread_local) +#define CRYPTO_ghash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ghash_init) +#define CRYPTO_has_asm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_has_asm) +#define CRYPTO_hchacha20 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_hchacha20) +#define CRYPTO_init_sysrand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_init_sysrand) +#define CRYPTO_is_ARMv8_AES_capable_at_runtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_is_ARMv8_AES_capable_at_runtime) +#define CRYPTO_is_ARMv8_PMULL_capable_at_runtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_is_ARMv8_PMULL_capable_at_runtime) +#define CRYPTO_is_NEON_capable_at_runtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_is_NEON_capable_at_runtime) +#define CRYPTO_is_confidential_build BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_is_confidential_build) +#define CRYPTO_library_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_library_init) +#define CRYPTO_malloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_malloc) +#define CRYPTO_malloc_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_malloc_init) +#define CRYPTO_memcmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_memcmp) +#define CRYPTO_new_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_new_ex_data) +#define CRYPTO_num_locks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_num_locks) +#define CRYPTO_ofb128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ofb128_encrypt) +#define CRYPTO_once BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_once) +#define CRYPTO_poly1305_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_finish) +#define CRYPTO_poly1305_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_init) +#define CRYPTO_poly1305_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_update) +#define CRYPTO_pre_sandbox_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_pre_sandbox_init) +#define CRYPTO_rdrand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_rdrand) +#define CRYPTO_rdrand_multiple8_buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_rdrand_multiple8_buf) +#define CRYPTO_realloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_realloc) +#define CRYPTO_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_refcount_dec_and_test_zero) +#define CRYPTO_refcount_inc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_refcount_inc) +#define CRYPTO_set_add_lock_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_add_lock_callback) +#define CRYPTO_set_dynlock_create_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_dynlock_create_callback) +#define CRYPTO_set_dynlock_destroy_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_dynlock_destroy_callback) +#define CRYPTO_set_dynlock_lock_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_dynlock_lock_callback) +#define CRYPTO_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_ex_data) +#define CRYPTO_set_id_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_id_callback) +#define CRYPTO_set_locking_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_locking_callback) +#define CRYPTO_set_thread_local BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_set_thread_local) +#define CRYPTO_sysrand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_sysrand) +#define CRYPTO_sysrand_for_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_sysrand_for_seed) +#define CRYPTO_sysrand_if_available BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_sysrand_if_available) +#define CRYPTO_tls1_prf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_tls1_prf) +#define CTR_DRBG_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_clear) +#define CTR_DRBG_generate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_generate) +#define CTR_DRBG_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_init) +#define CTR_DRBG_reseed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define ChaCha20_ctr32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ChaCha20_ctr32) +#define DES_decrypt3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_decrypt3) +#define DES_ecb3_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb3_encrypt) +#define DES_ecb_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb_encrypt) +#define DES_ede2_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ede2_cbc_encrypt) +#define DES_ede3_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ede3_cbc_encrypt) +#define DES_encrypt3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_encrypt3) +#define DES_ncbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ncbc_encrypt) +#define DES_set_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_set_key) +#define DES_set_key_unchecked BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_set_key_unchecked) +#define DES_set_odd_parity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_set_odd_parity) +#define DH_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_check) +#define DH_check_pub_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_check_pub_key) +#define DH_compute_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_compute_key) +#define DH_compute_key_hashed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_compute_key_hashed) +#define DH_compute_key_padded BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_compute_key_padded) +#define DH_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_free) +#define DH_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_generate_key) +#define DH_generate_parameters_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_generate_parameters_ex) +#define DH_get0_g BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_g) +#define DH_get0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_key) +#define DH_get0_p BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_p) +#define DH_get0_pqg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_pqg) +#define DH_get0_priv_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_priv_key) +#define DH_get0_pub_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_pub_key) +#define DH_get0_q BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get0_q) +#define DH_get_rfc7919_2048 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_get_rfc7919_2048) +#define DH_marshal_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_marshal_parameters) +#define DH_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_new) +#define DH_num_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_num_bits) +#define DH_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_parse_parameters) +#define DH_set0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_set0_key) +#define DH_set0_pqg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_set0_pqg) +#define DH_set_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_set_length) +#define DH_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_size) +#define DH_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DH_up_ref) +#define DHparams_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DHparams_dup) +#define DIRECTORYSTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIRECTORYSTRING_free) +#define DIRECTORYSTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIRECTORYSTRING_it) +#define DIRECTORYSTRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIRECTORYSTRING_new) +#define DISPLAYTEXT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DISPLAYTEXT_free) +#define DISPLAYTEXT_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DISPLAYTEXT_it) +#define DISPLAYTEXT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DISPLAYTEXT_new) +#define DIST_POINT_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_NAME_free) +#define DIST_POINT_NAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_NAME_it) +#define DIST_POINT_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_NAME_new) +#define DIST_POINT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_free) +#define DIST_POINT_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_it) +#define DIST_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_new) +#define DIST_POINT_set_dpname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DIST_POINT_set_dpname) +#define DSA_SIG_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_free) +#define DSA_SIG_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_get0) +#define DSA_SIG_marshal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_marshal) +#define DSA_SIG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_new) +#define DSA_SIG_parse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_parse) +#define DSA_SIG_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_SIG_set0) +#define DSA_check_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_check_signature) +#define DSA_do_check_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_do_check_signature) +#define DSA_do_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_do_sign) +#define DSA_do_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_do_verify) +#define DSA_dup_DH BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_dup_DH) +#define DSA_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_free) +#define DSA_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_generate_key) +#define DSA_generate_parameters_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_generate_parameters_ex) +#define DSA_get0_g BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_g) +#define DSA_get0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_key) +#define DSA_get0_p BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_p) +#define DSA_get0_pqg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_pqg) +#define DSA_get0_priv_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_priv_key) +#define DSA_get0_pub_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_pub_key) +#define DSA_get0_q BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get0_q) +#define DSA_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get_ex_data) +#define DSA_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_get_ex_new_index) +#define DSA_marshal_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_marshal_parameters) +#define DSA_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_marshal_private_key) +#define DSA_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_marshal_public_key) +#define DSA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_new) +#define DSA_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_parse_parameters) +#define DSA_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_parse_private_key) +#define DSA_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_parse_public_key) +#define DSA_set0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_set0_key) +#define DSA_set0_pqg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_set0_pqg) +#define DSA_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_set_ex_data) +#define DSA_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_sign) +#define DSA_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_size) +#define DSA_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_up_ref) +#define DSA_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSA_verify) +#define DSAparams_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DSAparams_dup) +#define DTLS_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLS_client_method) +#define DTLS_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLS_method) +#define DTLS_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLS_server_method) +#define DTLS_with_buffers_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLS_with_buffers_method) +#define DTLSv1_2_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_2_client_method) +#define DTLSv1_2_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_2_method) +#define DTLSv1_2_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_2_server_method) +#define DTLSv1_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_client_method) +#define DTLSv1_get_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_get_timeout) +#define DTLSv1_handle_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_handle_timeout) +#define DTLSv1_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_method) +#define DTLSv1_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_server_method) +#define DTLSv1_set_initial_timeout_duration BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DTLSv1_set_initial_timeout_duration) +#define ECDH_compute_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDH_compute_key) +#define ECDH_compute_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDH_compute_key_fips) +#define ECDSA_SIG_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_free) +#define ECDSA_SIG_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_from_bytes) +#define ECDSA_SIG_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_get0) +#define ECDSA_SIG_get0_r BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_get0_r) +#define ECDSA_SIG_get0_s BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_get0_s) +#define ECDSA_SIG_marshal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_marshal) +#define ECDSA_SIG_max_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_max_len) +#define ECDSA_SIG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_new) +#define ECDSA_SIG_parse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_parse) +#define ECDSA_SIG_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_set0) +#define ECDSA_SIG_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_SIG_to_bytes) +#define ECDSA_do_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_do_sign) +#define ECDSA_do_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_do_verify) +#define ECDSA_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_sign) +#define ECDSA_sign_with_nonce_and_leak_private_key_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_sign_with_nonce_and_leak_private_key_for_testing) +#define ECDSA_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_size) +#define ECDSA_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ECDSA_verify) +#define EC_GFp_mont_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GFp_mont_method) +#define EC_GFp_nistp224_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GFp_nistp224_method) +#define EC_GFp_nistp256_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GFp_nistp256_method) +#define EC_GFp_nistz256_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GFp_nistz256_method) +#define EC_GROUP_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_cmp) +#define EC_GROUP_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_dup) +#define EC_GROUP_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_free) +#define EC_GROUP_get0_generator BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get0_generator) +#define EC_GROUP_get0_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get0_order) +#define EC_GROUP_get_asn1_flag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_asn1_flag) +#define EC_GROUP_get_cofactor BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_cofactor) +#define EC_GROUP_get_curve_GFp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_curve_GFp) +#define EC_GROUP_get_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_curve_name) +#define EC_GROUP_get_degree BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_degree) +#define EC_GROUP_get_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_get_order) +#define EC_GROUP_method_of BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_method_of) +#define EC_GROUP_new_by_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_new_by_curve_name) +#define EC_GROUP_new_curve_GFp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_new_curve_GFp) +#define EC_GROUP_order_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_order_bits) +#define EC_GROUP_set_asn1_flag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_set_asn1_flag) +#define EC_GROUP_set_generator BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_set_generator) +#define EC_GROUP_set_point_conversion_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_GROUP_set_point_conversion_form) +#define EC_KEY_check_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_check_fips) +#define EC_KEY_check_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_check_key) +#define EC_KEY_derive_from_secret BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_derive_from_secret) +#define EC_KEY_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_dup) +#define EC_KEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_free) +#define EC_KEY_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_generate_key) +#define EC_KEY_generate_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_generate_key_fips) +#define EC_KEY_get0_group BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get0_group) +#define EC_KEY_get0_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get0_private_key) +#define EC_KEY_get0_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get0_public_key) +#define EC_KEY_get_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get_conv_form) +#define EC_KEY_get_enc_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get_enc_flags) +#define EC_KEY_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get_ex_data) +#define EC_KEY_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_get_ex_new_index) +#define EC_KEY_is_opaque BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_is_opaque) +#define EC_KEY_key2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_key2buf) +#define EC_KEY_marshal_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_marshal_curve_name) +#define EC_KEY_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_marshal_private_key) +#define EC_KEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new) +#define EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) +#define EC_KEY_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_method) +#define EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) +#define EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_parameters) +#define EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) +#define EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_conv_form) +#define EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) +#define EC_KEY_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_ex_data) +#define EC_KEY_set_group BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_group) +#define EC_KEY_set_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_private_key) +#define EC_KEY_set_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_public_key) +#define EC_KEY_set_public_key_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_public_key_affine_coordinates) +#define EC_KEY_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_up_ref) +#define EC_METHOD_get_field_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_METHOD_get_field_type) +#define EC_POINT_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_add) +#define EC_POINT_clear_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_clear_free) +#define EC_POINT_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_cmp) +#define EC_POINT_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_copy) +#define EC_POINT_dbl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_dbl) +#define EC_POINT_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_dup) +#define EC_POINT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_free) +#define EC_POINT_get_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_get_affine_coordinates) +#define EC_POINT_get_affine_coordinates_GFp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_get_affine_coordinates_GFp) +#define EC_POINT_invert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_invert) +#define EC_POINT_is_at_infinity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_is_at_infinity) +#define EC_POINT_is_on_curve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_is_on_curve) +#define EC_POINT_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_mul) +#define EC_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_new) +#define EC_POINT_oct2point BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define EC_POINT_point2cbb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2cbb) +#define EC_POINT_point2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2oct) +#define EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) +#define EC_POINT_set_affine_coordinates_GFp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates_GFp) +#define EC_POINT_set_compressed_coordinates_GFp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_compressed_coordinates_GFp) +#define EC_POINT_set_to_infinity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_to_infinity) +#define EC_curve_nid2nist BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_curve_nid2nist) +#define EC_curve_nist2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_curve_nist2nid) +#define EC_get_builtin_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_get_builtin_curves) +#define ED25519_keypair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_keypair) +#define ED25519_keypair_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_keypair_from_seed) +#define ED25519_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_sign) +#define ED25519_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_verify) +#define EDIPARTYNAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_free) +#define EDIPARTYNAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_it) +#define EDIPARTYNAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define ENGINE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_free) +#define ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) +#define ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_RSA_method) +#define ENGINE_load_builtin_engines BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_load_builtin_engines) +#define ENGINE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_new) +#define ENGINE_register_all_complete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_register_all_complete) +#define ENGINE_set_ECDSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_set_ECDSA_method) +#define ENGINE_set_RSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_set_RSA_method) +#define ERR_SAVE_STATE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_SAVE_STATE_free) +#define ERR_add_error_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_data) +#define ERR_add_error_dataf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_dataf) +#define ERR_clear_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_error) +#define ERR_clear_system_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_system_error) +#define ERR_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string) +#define ERR_error_string_n BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string_n) +#define ERR_free_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_free_strings) +#define ERR_func_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_func_error_string) +#define ERR_get_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_get_error) +#define ERR_get_error_line BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_get_error_line) +#define ERR_get_error_line_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_get_error_line_data) +#define ERR_get_next_error_library BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_get_next_error_library) +#define ERR_lib_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_lib_error_string) +#define ERR_load_BIO_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_load_BIO_strings) +#define ERR_load_ERR_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_load_ERR_strings) +#define ERR_load_RAND_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_load_RAND_strings) +#define ERR_load_SSL_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_load_SSL_strings) +#define ERR_load_crypto_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_load_crypto_strings) +#define ERR_peek_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_error) +#define ERR_peek_error_line BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_error_line) +#define ERR_peek_error_line_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_error_line_data) +#define ERR_peek_last_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_last_error) +#define ERR_peek_last_error_line BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_last_error_line) +#define ERR_peek_last_error_line_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_peek_last_error_line_data) +#define ERR_pop_to_mark BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_pop_to_mark) +#define ERR_print_errors BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_print_errors) +#define ERR_print_errors_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_print_errors_cb) +#define ERR_print_errors_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_print_errors_fp) +#define ERR_put_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_put_error) +#define ERR_reason_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_reason_error_string) +#define ERR_remove_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_remove_state) +#define ERR_remove_thread_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_remove_thread_state) +#define ERR_restore_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_restore_state) +#define ERR_save_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_save_state) +#define ERR_set_error_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_set_error_data) +#define ERR_set_mark BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_set_mark) +#define EVP_AEAD_CTX_aead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_aead) +#define EVP_AEAD_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_cleanup) +#define EVP_AEAD_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_free) +#define EVP_AEAD_CTX_get_iv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_get_iv) +#define EVP_AEAD_CTX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_init) +#define EVP_AEAD_CTX_init_with_direction BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_init_with_direction) +#define EVP_AEAD_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_new) +#define EVP_AEAD_CTX_open BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_open) +#define EVP_AEAD_CTX_open_gather BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_open_gather) +#define EVP_AEAD_CTX_seal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_seal) +#define EVP_AEAD_CTX_seal_scatter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_seal_scatter) +#define EVP_AEAD_CTX_tag_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_tag_len) +#define EVP_AEAD_CTX_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_CTX_zero) +#define EVP_AEAD_key_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_key_length) +#define EVP_AEAD_max_overhead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_max_overhead) +#define EVP_AEAD_max_tag_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_max_tag_len) +#define EVP_AEAD_nonce_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_AEAD_nonce_length) +#define EVP_BytesToKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_BytesToKey) +#define EVP_CIPHER_CTX_block_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_block_size) +#define EVP_CIPHER_CTX_cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_cipher) +#define EVP_CIPHER_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_cleanup) +#define EVP_CIPHER_CTX_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_copy) +#define EVP_CIPHER_CTX_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_ctrl) +#define EVP_CIPHER_CTX_encrypting BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_encrypting) +#define EVP_CIPHER_CTX_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_flags) +#define EVP_CIPHER_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_free) +#define EVP_CIPHER_CTX_get_app_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_get_app_data) +#define EVP_CIPHER_CTX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_init) +#define EVP_CIPHER_CTX_iv_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_iv_length) +#define EVP_CIPHER_CTX_key_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_key_length) +#define EVP_CIPHER_CTX_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_mode) +#define EVP_CIPHER_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_new) +#define EVP_CIPHER_CTX_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_nid) +#define EVP_CIPHER_CTX_reset BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_reset) +#define EVP_CIPHER_CTX_set_app_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_app_data) +#define EVP_CIPHER_CTX_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_flags) +#define EVP_CIPHER_CTX_set_key_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_key_length) +#define EVP_CIPHER_CTX_set_padding BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_padding) +#define EVP_CIPHER_block_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_block_size) +#define EVP_CIPHER_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_flags) +#define EVP_CIPHER_iv_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_iv_length) +#define EVP_CIPHER_key_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_key_length) +#define EVP_CIPHER_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_mode) +#define EVP_CIPHER_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CIPHER_nid) +#define EVP_Cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_Cipher) +#define EVP_CipherFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CipherFinal) +#define EVP_CipherFinal_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CipherFinal_ex) +#define EVP_CipherInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CipherInit) +#define EVP_CipherInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CipherInit_ex) +#define EVP_CipherUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_CipherUpdate) +#define EVP_DecodeBase64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodeBase64) +#define EVP_DecodeBlock BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodeBlock) +#define EVP_DecodeFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodeFinal) +#define EVP_DecodeInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodeInit) +#define EVP_DecodeUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodeUpdate) +#define EVP_DecodedLength BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecodedLength) +#define EVP_DecryptFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecryptFinal) +#define EVP_DecryptFinal_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecryptFinal_ex) +#define EVP_DecryptInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecryptInit) +#define EVP_DecryptInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecryptInit_ex) +#define EVP_DecryptUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DecryptUpdate) +#define EVP_Digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_Digest) +#define EVP_DigestFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestFinal) +#define EVP_DigestFinalXOF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestFinalXOF) +#define EVP_DigestFinal_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestFinal_ex) +#define EVP_DigestInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestInit) +#define EVP_DigestInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestInit_ex) +#define EVP_DigestSign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestSign) +#define EVP_DigestSignFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestSignFinal) +#define EVP_DigestSignInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestSignInit) +#define EVP_DigestSignUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestSignUpdate) +#define EVP_DigestUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestUpdate) +#define EVP_DigestVerify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestVerify) +#define EVP_DigestVerifyFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestVerifyFinal) +#define EVP_DigestVerifyInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestVerifyInit) +#define EVP_DigestVerifyUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_DigestVerifyUpdate) +#define EVP_ENCODE_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_ENCODE_CTX_free) +#define EVP_ENCODE_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_ENCODE_CTX_new) +#define EVP_EncodeBlock BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncodeBlock) +#define EVP_EncodeFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncodeFinal) +#define EVP_EncodeInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncodeInit) +#define EVP_EncodeUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncodeUpdate) +#define EVP_EncodedLength BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncodedLength) +#define EVP_EncryptFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncryptFinal) +#define EVP_EncryptFinal_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncryptFinal_ex) +#define EVP_EncryptInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncryptInit) +#define EVP_EncryptInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncryptInit_ex) +#define EVP_EncryptUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_EncryptUpdate) +#define EVP_HPKE_AEAD_aead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_AEAD_aead) +#define EVP_HPKE_AEAD_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_AEAD_id) +#define EVP_HPKE_CTX_aead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_aead) +#define EVP_HPKE_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_cleanup) +#define EVP_HPKE_CTX_export BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_export) +#define EVP_HPKE_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_free) +#define EVP_HPKE_CTX_kdf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_kdf) +#define EVP_HPKE_CTX_max_overhead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_max_overhead) +#define EVP_HPKE_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_new) +#define EVP_HPKE_CTX_open BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_open) +#define EVP_HPKE_CTX_seal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_seal) +#define EVP_HPKE_CTX_setup_recipient BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_recipient) +#define EVP_HPKE_CTX_setup_sender BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_sender) +#define EVP_HPKE_CTX_setup_sender_with_seed_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_sender_with_seed_for_testing) +#define EVP_HPKE_CTX_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_CTX_zero) +#define EVP_HPKE_KDF_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KDF_id) +#define EVP_HPKE_KEM_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEM_id) +#define EVP_HPKE_KEY_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_cleanup) +#define EVP_HPKE_KEY_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_copy) +#define EVP_HPKE_KEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_free) +#define EVP_HPKE_KEY_generate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_generate) +#define EVP_HPKE_KEY_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_init) +#define EVP_HPKE_KEY_kem BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_kem) +#define EVP_HPKE_KEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_new) +#define EVP_HPKE_KEY_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_private_key) +#define EVP_HPKE_KEY_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_public_key) +#define EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) +#define EVP_MD_CTX_block_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_block_size) +#define EVP_MD_CTX_cleanse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_cleanse) +#define EVP_MD_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_cleanup) +#define EVP_MD_CTX_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_copy) +#define EVP_MD_CTX_copy_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_copy_ex) +#define EVP_MD_CTX_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_create) +#define EVP_MD_CTX_destroy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_destroy) +#define EVP_MD_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_free) +#define EVP_MD_CTX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_init) +#define EVP_MD_CTX_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_md) +#define EVP_MD_CTX_move BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_move) +#define EVP_MD_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_new) +#define EVP_MD_CTX_reset BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_reset) +#define EVP_MD_CTX_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_set_flags) +#define EVP_MD_CTX_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_size) +#define EVP_MD_CTX_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_CTX_type) +#define EVP_MD_block_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_block_size) +#define EVP_MD_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_flags) +#define EVP_MD_meth_get_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_meth_get_flags) +#define EVP_MD_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_nid) +#define EVP_MD_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_size) +#define EVP_MD_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_MD_type) +#define EVP_PBE_scrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PBE_scrypt) +#define EVP_PKCS82PKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKCS82PKEY) +#define EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) +#define EVP_PKEY_CTX_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_ctrl) +#define EVP_PKEY_CTX_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_dup) +#define EVP_PKEY_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_free) +#define EVP_PKEY_CTX_get0_pkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get0_pkey) +#define EVP_PKEY_CTX_get0_rsa_oaep_label BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get0_rsa_oaep_label) +#define EVP_PKEY_CTX_get_rsa_mgf1_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_mgf1_md) +#define EVP_PKEY_CTX_get_rsa_oaep_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_oaep_md) +#define EVP_PKEY_CTX_get_rsa_padding BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_padding) +#define EVP_PKEY_CTX_get_rsa_pss_saltlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_pss_saltlen) +#define EVP_PKEY_CTX_get_signature_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_signature_md) +#define EVP_PKEY_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_new) +#define EVP_PKEY_CTX_new_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_new_id) +#define EVP_PKEY_CTX_set0_rsa_oaep_label BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set0_rsa_oaep_label) +#define EVP_PKEY_CTX_set_ec_param_enc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_ec_param_enc) +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_ec_paramgen_curve_nid) +#define EVP_PKEY_CTX_set_rsa_keygen_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_keygen_bits) +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_keygen_pubexp) +#define EVP_PKEY_CTX_set_rsa_mgf1_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_mgf1_md) +#define EVP_PKEY_CTX_set_rsa_oaep_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_oaep_md) +#define EVP_PKEY_CTX_set_rsa_padding BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_padding) +#define EVP_PKEY_CTX_set_rsa_pss_keygen_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_md) +#define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md) +#define EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen) +#define EVP_PKEY_CTX_set_rsa_pss_saltlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_saltlen) +#define EVP_PKEY_CTX_set_signature_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_signature_md) +#define EVP_PKEY_assign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_assign) +#define EVP_PKEY_assign_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_assign_DSA) +#define EVP_PKEY_assign_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_assign_EC_KEY) +#define EVP_PKEY_assign_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_assign_RSA) +#define EVP_PKEY_base_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_base_id) +#define EVP_PKEY_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_bits) +#define EVP_PKEY_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_cmp) +#define EVP_PKEY_cmp_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_cmp_parameters) +#define EVP_PKEY_copy_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_copy_parameters) +#define EVP_PKEY_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_decrypt) +#define EVP_PKEY_decrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_decrypt_init) +#define EVP_PKEY_derive BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive) +#define EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_init) +#define EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt) +#define EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) +#define EVP_PKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_free) +#define EVP_PKEY_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0) +#define EVP_PKEY_get0_DH BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0_DH) +#define EVP_PKEY_get0_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0_DSA) +#define EVP_PKEY_get0_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0_EC_KEY) +#define EVP_PKEY_get0_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0_RSA) +#define EVP_PKEY_get1_DH BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get1_DH) +#define EVP_PKEY_get1_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get1_DSA) +#define EVP_PKEY_get1_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get1_EC_KEY) +#define EVP_PKEY_get1_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get1_RSA) +#define EVP_PKEY_get1_tls_encodedpoint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get1_tls_encodedpoint) +#define EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) +#define EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) +#define EVP_PKEY_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_id) +#define EVP_PKEY_is_opaque BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_is_opaque) +#define EVP_PKEY_keygen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_keygen) +#define EVP_PKEY_keygen_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_keygen_init) +#define EVP_PKEY_missing_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_missing_parameters) +#define EVP_PKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_new) +#define EVP_PKEY_new_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_new_raw_private_key) +#define EVP_PKEY_new_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_new_raw_public_key) +#define EVP_PKEY_paramgen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_paramgen) +#define EVP_PKEY_paramgen_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_paramgen_init) +#define EVP_PKEY_print_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_params) +#define EVP_PKEY_print_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_private) +#define EVP_PKEY_print_public BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_public) +#define EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) +#define EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) +#define EVP_PKEY_set1_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_RSA) +#define EVP_PKEY_set1_tls_encodedpoint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_tls_encodedpoint) +#define EVP_PKEY_set_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define EVP_PKEY_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_sign) +#define EVP_PKEY_sign_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_sign_init) +#define EVP_PKEY_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_size) +#define EVP_PKEY_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_type) +#define EVP_PKEY_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_up_ref) +#define EVP_PKEY_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify) +#define EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_init) +#define EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) +#define EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define EVP_SignFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_SignFinal) +#define EVP_SignInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_SignInit) +#define EVP_SignInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_SignInit_ex) +#define EVP_SignUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_SignUpdate) +#define EVP_VerifyFinal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_VerifyFinal) +#define EVP_VerifyInit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_VerifyInit) +#define EVP_VerifyInit_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_VerifyInit_ex) +#define EVP_VerifyUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_VerifyUpdate) +#define EVP_add_cipher_alias BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_add_cipher_alias) +#define EVP_add_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_add_digest) +#define EVP_aead_aes_128_cbc_sha1_tls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_cbc_sha1_tls) +#define EVP_aead_aes_128_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_cbc_sha1_tls_implicit_iv) +#define EVP_aead_aes_128_ccm_bluetooth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_ccm_bluetooth) +#define EVP_aead_aes_128_ccm_bluetooth_8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_ccm_bluetooth_8) +#define EVP_aead_aes_128_ctr_hmac_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_ctr_hmac_sha256) +#define EVP_aead_aes_128_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm) +#define EVP_aead_aes_128_gcm_randnonce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_randnonce) +#define EVP_aead_aes_128_gcm_siv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_siv) +#define EVP_aead_aes_128_gcm_tls12 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_tls12) +#define EVP_aead_aes_128_gcm_tls13 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_tls13) +#define EVP_aead_aes_192_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_192_gcm) +#define EVP_aead_aes_256_cbc_sha1_tls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_cbc_sha1_tls) +#define EVP_aead_aes_256_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_cbc_sha1_tls_implicit_iv) +#define EVP_aead_aes_256_ctr_hmac_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_ctr_hmac_sha256) +#define EVP_aead_aes_256_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm) +#define EVP_aead_aes_256_gcm_randnonce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_randnonce) +#define EVP_aead_aes_256_gcm_siv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_siv) +#define EVP_aead_aes_256_gcm_tls12 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_tls12) +#define EVP_aead_aes_256_gcm_tls13 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_tls13) +#define EVP_aead_chacha20_poly1305 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_chacha20_poly1305) +#define EVP_aead_des_ede3_cbc_sha1_tls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_des_ede3_cbc_sha1_tls) +#define EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv) +#define EVP_aead_null_sha1_tls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_null_sha1_tls) +#define EVP_aead_xchacha20_poly1305 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aead_xchacha20_poly1305) +#define EVP_aes_128_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_128_cbc) +#define EVP_aes_128_ctr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_128_ctr) +#define EVP_aes_128_ecb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_128_ecb) +#define EVP_aes_128_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_128_gcm) +#define EVP_aes_128_ofb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_128_ofb) +#define EVP_aes_192_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_192_cbc) +#define EVP_aes_192_ctr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_192_ctr) +#define EVP_aes_192_ecb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_192_ecb) +#define EVP_aes_192_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_192_gcm) +#define EVP_aes_192_ofb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_192_ofb) +#define EVP_aes_256_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_256_cbc) +#define EVP_aes_256_ctr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_256_ctr) +#define EVP_aes_256_ecb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_256_ecb) +#define EVP_aes_256_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_256_gcm) +#define EVP_aes_256_ofb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_aes_256_ofb) +#define EVP_blake2b256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_blake2b256) +#define EVP_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_cleanup) +#define EVP_des_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_cbc) +#define EVP_des_ecb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ecb) +#define EVP_des_ede BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ede) +#define EVP_des_ede3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ede3) +#define EVP_des_ede3_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ede3_cbc) +#define EVP_des_ede3_ecb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ede3_ecb) +#define EVP_des_ede_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_des_ede_cbc) +#define EVP_enc_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_enc_null) +#define EVP_get_cipherbyname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_get_cipherbyname) +#define EVP_get_cipherbynid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_get_cipherbynid) +#define EVP_get_digestbyname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_get_digestbyname) +#define EVP_get_digestbynid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_get_digestbynid) +#define EVP_get_digestbyobj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_get_digestbyobj) +#define EVP_has_aes_hardware BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_has_aes_hardware) +#define EVP_hpke_aes_128_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_aes_128_gcm) +#define EVP_hpke_aes_256_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_aes_256_gcm) +#define EVP_hpke_chacha20_poly1305 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_chacha20_poly1305) +#define EVP_hpke_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_hkdf_sha256) +#define EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) +#define EVP_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_private_key) +#define EVP_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_public_key) +#define EVP_md4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md4) +#define EVP_md5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5) +#define EVP_md5_sha1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5_sha1) +#define EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define EVP_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_private_key) +#define EVP_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_public_key) +#define EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_40_cbc) +#define EVP_rc2_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_cbc) +#define EVP_rc4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc4) +#define EVP_sha1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha1) +#define EVP_sha1_final_with_secret_suffix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha1_final_with_secret_suffix) +#define EVP_sha224 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha224) +#define EVP_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha256) +#define EVP_sha384 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha384) +#define EVP_sha512 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha512) +#define EVP_sha512_256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_sha512_256) +#define EVP_tls_cbc_copy_mac BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_tls_cbc_copy_mac) +#define EVP_tls_cbc_digest_record BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_tls_cbc_digest_record) +#define EVP_tls_cbc_record_digest_supported BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_tls_cbc_record_digest_supported) +#define EVP_tls_cbc_remove_padding BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_tls_cbc_remove_padding) +#define EXTENDED_KEY_USAGE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_free) +#define EXTENDED_KEY_USAGE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_it) +#define EXTENDED_KEY_USAGE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_new) +#define FIPS_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_mode) +#define FIPS_mode_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_mode_set) +#define FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_query_algorithm_status) +#define FIPS_read_counter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_read_counter) +#define FIPS_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_version) +#define GENERAL_NAMES_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAMES_free) +#define GENERAL_NAMES_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAMES_it) +#define GENERAL_NAMES_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAMES_new) +#define GENERAL_NAME_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_cmp) +#define GENERAL_NAME_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_dup) +#define GENERAL_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_free) +#define GENERAL_NAME_get0_otherName BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_get0_otherName) +#define GENERAL_NAME_get0_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_get0_value) +#define GENERAL_NAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_it) +#define GENERAL_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_new) +#define GENERAL_NAME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_print) +#define GENERAL_NAME_set0_othername BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_set0_othername) +#define GENERAL_NAME_set0_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_NAME_set0_value) +#define GENERAL_SUBTREE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_SUBTREE_free) +#define GENERAL_SUBTREE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_SUBTREE_it) +#define GENERAL_SUBTREE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, GENERAL_SUBTREE_new) +#define HKDF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HKDF) +#define HKDF_expand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HKDF_expand) +#define HKDF_extract BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HKDF_extract) +#define HMAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC) +#define HMAC_CTX_cleanse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_cleanse) +#define HMAC_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_cleanup) +#define HMAC_CTX_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_copy) +#define HMAC_CTX_copy_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_copy_ex) +#define HMAC_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_free) +#define HMAC_CTX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_init) +#define HMAC_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_new) +#define HMAC_CTX_reset BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_CTX_reset) +#define HMAC_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_Final) +#define HMAC_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_Init) +#define HMAC_Init_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_Init_ex) +#define HMAC_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_Update) +#define HMAC_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HMAC_size) +#define HRSS_decap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_decap) +#define HRSS_encap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_encap) +#define HRSS_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_generate_key) +#define HRSS_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_marshal_public_key) +#define HRSS_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_parse_public_key) +#define HRSS_poly3_invert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_poly3_invert) +#define HRSS_poly3_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, HRSS_poly3_mul) +#define ISSUING_DIST_POINT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_free) +#define ISSUING_DIST_POINT_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_it) +#define ISSUING_DIST_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ISSUING_DIST_POINT_new) +#define MD4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4) +#define MD4_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Final) +#define MD4_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Init) +#define MD4_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Transform) +#define MD4_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD4_Update) +#define MD5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5) +#define MD5_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Final) +#define MD5_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Init) +#define MD5_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Transform) +#define MD5_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Update) +#define METHOD_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_ref) +#define METHOD_unref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_unref) +#define NAME_CONSTRAINTS_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_check) +#define NAME_CONSTRAINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_free) +#define NAME_CONSTRAINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_it) +#define NAME_CONSTRAINTS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_new) +#define NCONF_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_free) +#define NCONF_get_section BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_get_section) +#define NCONF_get_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_get_string) +#define NCONF_load BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_load) +#define NCONF_load_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_load_bio) +#define NCONF_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NCONF_new) +#define NETSCAPE_SPKAC_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKAC_free) +#define NETSCAPE_SPKAC_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKAC_it) +#define NETSCAPE_SPKAC_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKAC_new) +#define NETSCAPE_SPKI_b64_decode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_b64_decode) +#define NETSCAPE_SPKI_b64_encode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_b64_encode) +#define NETSCAPE_SPKI_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_free) +#define NETSCAPE_SPKI_get_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_get_pubkey) +#define NETSCAPE_SPKI_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_it) +#define NETSCAPE_SPKI_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_new) +#define NETSCAPE_SPKI_set_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_set_pubkey) +#define NETSCAPE_SPKI_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_sign) +#define NETSCAPE_SPKI_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NETSCAPE_SPKI_verify) +#define NOTICEREF_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NOTICEREF_free) +#define NOTICEREF_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NOTICEREF_it) +#define NOTICEREF_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NOTICEREF_new) +#define OBJ_cbs2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_cbs2nid) +#define OBJ_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_cleanup) +#define OBJ_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_cmp) +#define OBJ_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_create) +#define OBJ_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_dup) +#define OBJ_find_sigid_algs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_find_sigid_algs) +#define OBJ_find_sigid_by_algs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_find_sigid_by_algs) +#define OBJ_get0_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_get0_data) +#define OBJ_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_length) +#define OBJ_ln2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_ln2nid) +#define OBJ_nid2cbb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_nid2cbb) +#define OBJ_nid2ln BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_nid2ln) +#define OBJ_nid2obj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_nid2obj) +#define OBJ_nid2sn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_nid2sn) +#define OBJ_obj2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_obj2nid) +#define OBJ_obj2txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_obj2txt) +#define OBJ_sn2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_sn2nid) +#define OBJ_txt2nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_txt2nid) +#define OBJ_txt2obj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OBJ_txt2obj) +#define OPENSSL_add_all_algorithms_conf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_add_all_algorithms_conf) +#define OPENSSL_armcap_P BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_armcap_P) +#define OPENSSL_built_in_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_built_in_curves) +#define OPENSSL_cleanse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cleanse) +#define OPENSSL_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cleanup) +#define OPENSSL_clear_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_clear_free) +#define OPENSSL_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_config) +#define OPENSSL_cpuid_setup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_cpuid_setup) +#define OPENSSL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_free) +#define OPENSSL_get_armcap_pointer_for_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_get_armcap_pointer_for_test) +#define OPENSSL_gmtime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_gmtime) +#define OPENSSL_gmtime_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_gmtime_adj) +#define OPENSSL_gmtime_diff BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_gmtime_diff) +#define OPENSSL_hash32 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_hash32) +#define OPENSSL_ia32cap_P BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_ia32cap_P) +#define OPENSSL_init_crypto BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_init_crypto) +#define OPENSSL_init_ssl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_init_ssl) +#define OPENSSL_lh_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_delete) +#define OPENSSL_lh_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_doall_arg) +#define OPENSSL_lh_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_free) +#define OPENSSL_lh_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_insert) +#define OPENSSL_lh_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_new) +#define OPENSSL_lh_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_num_items) +#define OPENSSL_lh_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_retrieve) +#define OPENSSL_lh_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_lh_retrieve_key) +#define OPENSSL_load_builtin_modules BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_load_builtin_modules) +#define OPENSSL_malloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_malloc) +#define OPENSSL_malloc_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_malloc_init) +#define OPENSSL_memdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_memdup) +#define OPENSSL_no_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_no_config) +#define OPENSSL_realloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_realloc) +#define OPENSSL_strcasecmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strcasecmp) +#define OPENSSL_strdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strdup) +#define OPENSSL_strhash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strhash) +#define OPENSSL_strlcat BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strlcat) +#define OPENSSL_strlcpy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strlcpy) +#define OPENSSL_strncasecmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strncasecmp) +#define OPENSSL_strndup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strndup) +#define OPENSSL_strnlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_strnlen) +#define OPENSSL_tolower BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_tolower) +#define OTHERNAME_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_cmp) +#define OTHERNAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_free) +#define OTHERNAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_it) +#define OTHERNAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OTHERNAME_new) +#define OpenSSL_add_all_algorithms BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OpenSSL_add_all_algorithms) +#define OpenSSL_add_all_ciphers BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OpenSSL_add_all_ciphers) +#define OpenSSL_add_all_digests BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OpenSSL_add_all_digests) +#define OpenSSL_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OpenSSL_version) +#define OpenSSL_version_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OpenSSL_version_num) +#define PEM_ASN1_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_ASN1_read) +#define PEM_ASN1_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_ASN1_read_bio) +#define PEM_ASN1_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_ASN1_write) +#define PEM_ASN1_write_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_ASN1_write_bio) +#define PEM_X509_INFO_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_X509_INFO_read) +#define PEM_X509_INFO_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_X509_INFO_read_bio) +#define PEM_X509_INFO_write_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_X509_INFO_write_bio) +#define PEM_bytes_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_bytes_read_bio) +#define PEM_def_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_def_callback) +#define PEM_dek_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_dek_info) +#define PEM_do_header BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_do_header) +#define PEM_get_EVP_CIPHER_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_get_EVP_CIPHER_INFO) +#define PEM_proc_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_proc_type) +#define PEM_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read) +#define PEM_read_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DHparams) +#define PEM_read_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DSAPrivateKey) +#define PEM_read_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DSA_PUBKEY) +#define PEM_read_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_DSAparams) +#define PEM_read_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_ECPrivateKey) +#define PEM_read_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_EC_PUBKEY) +#define PEM_read_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_PKCS7) +#define PEM_read_PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_PKCS8) +#define PEM_read_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_PKCS8_PRIV_KEY_INFO) +#define PEM_read_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_PUBKEY) +#define PEM_read_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_PrivateKey) +#define PEM_read_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_RSAPrivateKey) +#define PEM_read_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_RSAPublicKey) +#define PEM_read_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_RSA_PUBKEY) +#define PEM_read_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_SSL_SESSION) +#define PEM_read_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_X509) +#define PEM_read_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_X509_AUX) +#define PEM_read_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_X509_CRL) +#define PEM_read_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_X509_REQ) +#define PEM_read_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio) +#define PEM_read_bio_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_DHparams) +#define PEM_read_bio_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_DSAPrivateKey) +#define PEM_read_bio_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_DSA_PUBKEY) +#define PEM_read_bio_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_DSAparams) +#define PEM_read_bio_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_ECPrivateKey) +#define PEM_read_bio_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_EC_PUBKEY) +#define PEM_read_bio_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_PKCS7) +#define PEM_read_bio_PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_PKCS8) +#define PEM_read_bio_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_PKCS8_PRIV_KEY_INFO) +#define PEM_read_bio_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_PUBKEY) +#define PEM_read_bio_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_PrivateKey) +#define PEM_read_bio_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_RSAPrivateKey) +#define PEM_read_bio_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_RSAPublicKey) +#define PEM_read_bio_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_RSA_PUBKEY) +#define PEM_read_bio_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_SSL_SESSION) +#define PEM_read_bio_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_X509) +#define PEM_read_bio_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_X509_AUX) +#define PEM_read_bio_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_X509_CRL) +#define PEM_read_bio_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_read_bio_X509_REQ) +#define PEM_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write) +#define PEM_write_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_DHparams) +#define PEM_write_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_DSAPrivateKey) +#define PEM_write_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_DSA_PUBKEY) +#define PEM_write_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_DSAparams) +#define PEM_write_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_ECPrivateKey) +#define PEM_write_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_EC_PUBKEY) +#define PEM_write_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PKCS7) +#define PEM_write_PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PKCS8) +#define PEM_write_PKCS8PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PKCS8PrivateKey) +#define PEM_write_PKCS8PrivateKey_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PKCS8PrivateKey_nid) +#define PEM_write_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PKCS8_PRIV_KEY_INFO) +#define PEM_write_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PUBKEY) +#define PEM_write_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_PrivateKey) +#define PEM_write_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_RSAPrivateKey) +#define PEM_write_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_RSAPublicKey) +#define PEM_write_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_RSA_PUBKEY) +#define PEM_write_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_SSL_SESSION) +#define PEM_write_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_X509) +#define PEM_write_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_X509_AUX) +#define PEM_write_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_X509_CRL) +#define PEM_write_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_X509_REQ) +#define PEM_write_X509_REQ_NEW BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_X509_REQ_NEW) +#define PEM_write_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio) +#define PEM_write_bio_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_DHparams) +#define PEM_write_bio_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_DSAPrivateKey) +#define PEM_write_bio_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_DSA_PUBKEY) +#define PEM_write_bio_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_DSAparams) +#define PEM_write_bio_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_ECPrivateKey) +#define PEM_write_bio_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_EC_PUBKEY) +#define PEM_write_bio_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PKCS7) +#define PEM_write_bio_PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PKCS8) +#define PEM_write_bio_PKCS8PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PKCS8PrivateKey) +#define PEM_write_bio_PKCS8PrivateKey_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PKCS8PrivateKey_nid) +#define PEM_write_bio_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PKCS8_PRIV_KEY_INFO) +#define PEM_write_bio_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PUBKEY) +#define PEM_write_bio_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_PrivateKey) +#define PEM_write_bio_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_RSAPrivateKey) +#define PEM_write_bio_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_RSAPublicKey) +#define PEM_write_bio_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_RSA_PUBKEY) +#define PEM_write_bio_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_SSL_SESSION) +#define PEM_write_bio_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_X509) +#define PEM_write_bio_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_X509_AUX) +#define PEM_write_bio_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_X509_CRL) +#define PEM_write_bio_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_X509_REQ) +#define PEM_write_bio_X509_REQ_NEW BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PEM_write_bio_X509_REQ_NEW) +#define PKCS12_PBE_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_PBE_add) +#define PKCS12_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_create) +#define PKCS12_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_free) +#define PKCS12_get_key_and_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_get_key_and_certs) +#define PKCS12_parse BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_parse) +#define PKCS12_verify_mac BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS12_verify_mac) +#define PKCS5_PBKDF2_HMAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC) +#define PKCS5_PBKDF2_HMAC_SHA1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC_SHA1) +#define PKCS5_pbe2_decrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_pbe2_decrypt_init) +#define PKCS5_pbe2_encrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS5_pbe2_encrypt_init) +#define PKCS7_bundle_CRLs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_bundle_CRLs) +#define PKCS7_bundle_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_bundle_certificates) +#define PKCS7_bundle_raw_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_bundle_raw_certificates) +#define PKCS7_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_free) +#define PKCS7_get_CRLs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_get_CRLs) +#define PKCS7_get_PEM_CRLs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_get_PEM_CRLs) +#define PKCS7_get_PEM_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_get_PEM_certificates) +#define PKCS7_get_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_get_certificates) +#define PKCS7_get_raw_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_get_raw_certificates) +#define PKCS7_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_sign) +#define PKCS7_type_is_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_data) +#define PKCS7_type_is_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_digest) +#define PKCS7_type_is_encrypted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_encrypted) +#define PKCS7_type_is_enveloped BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_enveloped) +#define PKCS7_type_is_signed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_signed) +#define PKCS7_type_is_signedAndEnveloped BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS7_type_is_signedAndEnveloped) +#define PKCS8_PRIV_KEY_INFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_free) +#define PKCS8_PRIV_KEY_INFO_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_it) +#define PKCS8_PRIV_KEY_INFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_new) +#define PKCS8_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_decrypt) +#define PKCS8_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_encrypt) +#define PKCS8_marshal_encrypted_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_marshal_encrypted_private_key) +#define PKCS8_parse_encrypted_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_parse_encrypted_private_key) +#define PKCS8_pkey_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_pkey_get0) +#define PKCS8_pkey_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PKCS8_pkey_set0) +#define POLICYINFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYINFO_free) +#define POLICYINFO_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYINFO_it) +#define POLICYINFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYINFO_new) +#define POLICYQUALINFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYQUALINFO_free) +#define POLICYQUALINFO_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYQUALINFO_it) +#define POLICYQUALINFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICYQUALINFO_new) +#define POLICY_CONSTRAINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_free) +#define POLICY_CONSTRAINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_it) +#define POLICY_CONSTRAINTS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_new) +#define POLICY_MAPPINGS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPINGS_it) +#define POLICY_MAPPING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_free) +#define POLICY_MAPPING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_it) +#define POLICY_MAPPING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, POLICY_MAPPING_new) +#define PROXY_CERT_INFO_EXTENSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_free) +#define PROXY_CERT_INFO_EXTENSION_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_it) +#define PROXY_CERT_INFO_EXTENSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_new) +#define PROXY_POLICY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_free) +#define PROXY_POLICY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_it) +#define PROXY_POLICY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, PROXY_POLICY_new) +#define RAND_OpenSSL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_OpenSSL) +#define RAND_SSLeay BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_SSLeay) +#define RAND_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_add) +#define RAND_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_bytes) +#define RAND_bytes_with_additional_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_bytes_with_additional_data) +#define RAND_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_cleanup) +#define RAND_egd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_egd) +#define RAND_enable_fork_unsafe_buffering BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_enable_fork_unsafe_buffering) +#define RAND_file_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_file_name) +#define RAND_get_rand_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_get_rand_method) +#define RAND_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_load_file) +#define RAND_poll BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_poll) +#define RAND_pseudo_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_pseudo_bytes) +#define RAND_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_seed) +#define RAND_set_rand_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_set_rand_method) +#define RAND_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_status) +#define RC4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RC4) +#define RC4_set_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RC4_set_key) +#define RSAPrivateKey_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSAPrivateKey_dup) +#define RSAPublicKey_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSAPublicKey_dup) +#define RSAZ_1024_mod_exp_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSAZ_1024_mod_exp_avx2) +#define RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) +#define RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define RSA_add_pkcs1_prefix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_add_pkcs1_prefix) +#define RSA_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_bits) +#define RSA_blinding_on BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_blinding_on) +#define RSA_check_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_check_fips) +#define RSA_check_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_check_key) +#define RSA_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_decrypt) +#define RSA_default_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_default_method) +#define RSA_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_encrypt) +#define RSA_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_flags) +#define RSA_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_free) +#define RSA_generate_key_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_generate_key_ex) +#define RSA_generate_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_generate_key_fips) +#define RSA_get0_crt_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_crt_params) +#define RSA_get0_d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_d) +#define RSA_get0_dmp1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_dmp1) +#define RSA_get0_dmq1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_dmq1) +#define RSA_get0_e BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_e) +#define RSA_get0_factors BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_factors) +#define RSA_get0_iqmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_iqmp) +#define RSA_get0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_key) +#define RSA_get0_n BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_n) +#define RSA_get0_p BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_p) +#define RSA_get0_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_pss_params) +#define RSA_get0_q BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get0_q) +#define RSA_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get_ex_data) +#define RSA_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_get_ex_new_index) +#define RSA_is_opaque BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_is_opaque) +#define RSA_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define RSA_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_public_key) +#define RSA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new) +#define RSA_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new_method) +#define RSA_padding_add_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_OAEP_mgf1) +#define RSA_padding_add_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_PSS_mgf1) +#define RSA_padding_add_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_1) +#define RSA_padding_add_PKCS1_type_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_2) +#define RSA_padding_add_none BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_add_none) +#define RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) +#define RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) +#define RSA_padding_check_PKCS1_type_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_2) +#define RSA_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_private_key) +#define RSA_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_public_key) +#define RSA_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_print) +#define RSA_private_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_decrypt) +#define RSA_private_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_encrypt) +#define RSA_private_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_key_from_bytes) +#define RSA_private_key_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_key_to_bytes) +#define RSA_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_private_transform) +#define RSA_public_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_decrypt) +#define RSA_public_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_encrypt) +#define RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_key_from_bytes) +#define RSA_public_key_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_key_to_bytes) +#define RSA_set0_crt_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_set0_crt_params) +#define RSA_set0_factors BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_set0_factors) +#define RSA_set0_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_set0_key) +#define RSA_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_set_ex_data) +#define RSA_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_sign) +#define RSA_sign_pss_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_sign_pss_mgf1) +#define RSA_sign_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_sign_raw) +#define RSA_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_size) +#define RSA_test_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_test_flags) +#define RSA_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_up_ref) +#define RSA_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_verify) +#define RSA_verify_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_verify_PKCS1_PSS_mgf1) +#define RSA_verify_pss_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_verify_pss_mgf1) +#define RSA_verify_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_verify_raw) +#define SHA1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1) +#define SHA1_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1_Final) +#define SHA1_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1_Init) +#define SHA1_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1_Transform) +#define SHA1_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1_Update) +#define SHA224 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA224) +#define SHA224_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA224_Final) +#define SHA224_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA224_Init) +#define SHA224_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA224_Update) +#define SHA256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256) +#define SHA256_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_Final) +#define SHA256_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_Init) +#define SHA256_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_Transform) +#define SHA256_TransformBlocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_TransformBlocks) +#define SHA256_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_Update) +#define SHA384 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA384) +#define SHA384_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA384_Final) +#define SHA384_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA384_Init) +#define SHA384_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA384_Update) +#define SHA512 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512) +#define SHA512_256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_256) +#define SHA512_256_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_256_Final) +#define SHA512_256_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_256_Init) +#define SHA512_256_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_256_Update) +#define SHA512_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Final) +#define SHA512_Init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Init) +#define SHA512_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Transform) +#define SHA512_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Update) +#define SIPHASH_24 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SIPHASH_24) +#define SPAKE2_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_CTX_free) +#define SPAKE2_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_CTX_new) +#define SPAKE2_generate_msg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_generate_msg) +#define SPAKE2_process_msg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_process_msg) +#define SSL_CIPHER_description BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_description) +#define SSL_CIPHER_get_auth_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_auth_nid) +#define SSL_CIPHER_get_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_bits) +#define SSL_CIPHER_get_cipher_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_cipher_nid) +#define SSL_CIPHER_get_digest_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_digest_nid) +#define SSL_CIPHER_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_id) +#define SSL_CIPHER_get_kx_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_kx_name) +#define SSL_CIPHER_get_kx_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_kx_nid) +#define SSL_CIPHER_get_max_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_max_version) +#define SSL_CIPHER_get_min_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_min_version) +#define SSL_CIPHER_get_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_name) +#define SSL_CIPHER_get_prf_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_prf_nid) +#define SSL_CIPHER_get_protocol_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_protocol_id) +#define SSL_CIPHER_get_rfc_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_rfc_name) +#define SSL_CIPHER_get_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_value) +#define SSL_CIPHER_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_get_version) +#define SSL_CIPHER_is_aead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_is_aead) +#define SSL_CIPHER_is_block_cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_is_block_cipher) +#define SSL_CIPHER_standard_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CIPHER_standard_name) +#define SSL_COMP_add_compression_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_add_compression_method) +#define SSL_COMP_free_compression_methods BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_free_compression_methods) +#define SSL_COMP_get0_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_get0_name) +#define SSL_COMP_get_compression_methods BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_get_compression_methods) +#define SSL_COMP_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_get_id) +#define SSL_COMP_get_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_COMP_get_name) +#define SSL_CTX_add0_chain_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add0_chain_cert) +#define SSL_CTX_add1_chain_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add1_chain_cert) +#define SSL_CTX_add_cert_compression_alg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add_cert_compression_alg) +#define SSL_CTX_add_client_CA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add_client_CA) +#define SSL_CTX_add_extra_chain_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add_extra_chain_cert) +#define SSL_CTX_add_session BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_add_session) +#define SSL_CTX_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_check_private_key) +#define SSL_CTX_cipher_in_group BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_cipher_in_group) +#define SSL_CTX_clear_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_clear_chain_certs) +#define SSL_CTX_clear_extra_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_clear_extra_chain_certs) +#define SSL_CTX_clear_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_clear_mode) +#define SSL_CTX_clear_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_clear_options) +#define SSL_CTX_enable_ocsp_stapling BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_enable_ocsp_stapling) +#define SSL_CTX_enable_signed_cert_timestamps BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_enable_signed_cert_timestamps) +#define SSL_CTX_enable_tls_channel_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_enable_tls_channel_id) +#define SSL_CTX_flush_sessions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_flush_sessions) +#define SSL_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_free) +#define SSL_CTX_get0_certificate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get0_certificate) +#define SSL_CTX_get0_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get0_chain) +#define SSL_CTX_get0_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get0_chain_certs) +#define SSL_CTX_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get0_param) +#define SSL_CTX_get0_privatekey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get0_privatekey) +#define SSL_CTX_get_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_cert_store) +#define SSL_CTX_get_ciphers BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_ciphers) +#define SSL_CTX_get_client_CA_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_client_CA_list) +#define SSL_CTX_get_default_passwd_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_default_passwd_cb) +#define SSL_CTX_get_default_passwd_cb_userdata BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_default_passwd_cb_userdata) +#define SSL_CTX_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_ex_data) +#define SSL_CTX_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_ex_new_index) +#define SSL_CTX_get_extra_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_extra_chain_certs) +#define SSL_CTX_get_info_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_info_callback) +#define SSL_CTX_get_keylog_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_keylog_callback) +#define SSL_CTX_get_max_cert_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_max_cert_list) +#define SSL_CTX_get_max_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_max_proto_version) +#define SSL_CTX_get_min_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_min_proto_version) +#define SSL_CTX_get_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_mode) +#define SSL_CTX_get_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_options) +#define SSL_CTX_get_quiet_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_quiet_shutdown) +#define SSL_CTX_get_read_ahead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_read_ahead) +#define SSL_CTX_get_session_cache_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_session_cache_mode) +#define SSL_CTX_get_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_timeout) +#define SSL_CTX_get_tlsext_ticket_keys BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_tlsext_ticket_keys) +#define SSL_CTX_get_verify_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_verify_callback) +#define SSL_CTX_get_verify_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_verify_depth) +#define SSL_CTX_get_verify_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_get_verify_mode) +#define SSL_CTX_load_verify_locations BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_load_verify_locations) +#define SSL_CTX_need_tmp_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_need_tmp_RSA) +#define SSL_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_new) +#define SSL_CTX_remove_session BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_remove_session) +#define SSL_CTX_sess_accept BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_accept) +#define SSL_CTX_sess_accept_good BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_accept_good) +#define SSL_CTX_sess_accept_renegotiate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_accept_renegotiate) +#define SSL_CTX_sess_cache_full BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_cache_full) +#define SSL_CTX_sess_cb_hits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_cb_hits) +#define SSL_CTX_sess_connect BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_connect) +#define SSL_CTX_sess_connect_good BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_connect_good) +#define SSL_CTX_sess_connect_renegotiate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_connect_renegotiate) +#define SSL_CTX_sess_get_cache_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_get_cache_size) +#define SSL_CTX_sess_get_get_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_get_get_cb) +#define SSL_CTX_sess_get_new_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_get_new_cb) +#define SSL_CTX_sess_get_remove_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_get_remove_cb) +#define SSL_CTX_sess_hits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_hits) +#define SSL_CTX_sess_misses BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_misses) +#define SSL_CTX_sess_number BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_number) +#define SSL_CTX_sess_set_cache_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_set_cache_size) +#define SSL_CTX_sess_set_get_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_set_get_cb) +#define SSL_CTX_sess_set_new_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_set_new_cb) +#define SSL_CTX_sess_set_remove_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_set_remove_cb) +#define SSL_CTX_sess_timeouts BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_sess_timeouts) +#define SSL_CTX_set0_buffer_pool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set0_buffer_pool) +#define SSL_CTX_set0_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set0_chain) +#define SSL_CTX_set0_client_CAs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set0_client_CAs) +#define SSL_CTX_set0_verify_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set0_verify_cert_store) +#define SSL_CTX_set1_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_chain) +#define SSL_CTX_set1_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_curves) +#define SSL_CTX_set1_curves_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_curves_list) +#define SSL_CTX_set1_ech_keys BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_ech_keys) +#define SSL_CTX_set1_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_param) +#define SSL_CTX_set1_sigalgs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_sigalgs) +#define SSL_CTX_set1_sigalgs_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_sigalgs_list) +#define SSL_CTX_set1_tls_channel_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_tls_channel_id) +#define SSL_CTX_set1_verify_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set1_verify_cert_store) +#define SSL_CTX_set_allow_unknown_alpn_protos BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_allow_unknown_alpn_protos) +#define SSL_CTX_set_alpn_protos BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_alpn_protos) +#define SSL_CTX_set_alpn_select_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_alpn_select_cb) +#define SSL_CTX_set_cert_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_cert_cb) +#define SSL_CTX_set_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_cert_store) +#define SSL_CTX_set_cert_verify_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_cert_verify_callback) +#define SSL_CTX_set_chain_and_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_chain_and_key) +#define SSL_CTX_set_cipher_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_cipher_list) +#define SSL_CTX_set_client_CA_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_client_CA_list) +#define SSL_CTX_set_client_cert_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_client_cert_cb) +#define SSL_CTX_set_current_time_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_current_time_cb) +#define SSL_CTX_set_custom_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_custom_verify) +#define SSL_CTX_set_default_passwd_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_default_passwd_cb) +#define SSL_CTX_set_default_passwd_cb_userdata BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_default_passwd_cb_userdata) +#define SSL_CTX_set_default_verify_paths BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_default_verify_paths) +#define SSL_CTX_set_dos_protection_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_dos_protection_cb) +#define SSL_CTX_set_early_data_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_early_data_enabled) +#define SSL_CTX_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_ex_data) +#define SSL_CTX_set_false_start_allowed_without_alpn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_false_start_allowed_without_alpn) +#define SSL_CTX_set_grease_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_grease_enabled) +#define SSL_CTX_set_info_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_info_callback) +#define SSL_CTX_set_keylog_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_keylog_callback) +#define SSL_CTX_set_max_cert_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_max_cert_list) +#define SSL_CTX_set_max_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_max_proto_version) +#define SSL_CTX_set_max_send_fragment BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_max_send_fragment) +#define SSL_CTX_set_min_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_min_proto_version) +#define SSL_CTX_set_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_mode) +#define SSL_CTX_set_msg_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_msg_callback) +#define SSL_CTX_set_msg_callback_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_msg_callback_arg) +#define SSL_CTX_set_next_proto_select_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_next_proto_select_cb) +#define SSL_CTX_set_next_protos_advertised_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_next_protos_advertised_cb) +#define SSL_CTX_set_ocsp_response BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_ocsp_response) +#define SSL_CTX_set_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_options) +#define SSL_CTX_set_permute_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_permute_extensions) +#define SSL_CTX_set_private_key_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_private_key_method) +#define SSL_CTX_set_psk_client_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_psk_client_callback) +#define SSL_CTX_set_psk_server_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_psk_server_callback) +#define SSL_CTX_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_purpose) +#define SSL_CTX_set_quic_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_quic_method) +#define SSL_CTX_set_quiet_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_quiet_shutdown) +#define SSL_CTX_set_read_ahead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_read_ahead) +#define SSL_CTX_set_record_protocol_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_record_protocol_version) +#define SSL_CTX_set_retain_only_sha256_of_client_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_retain_only_sha256_of_client_certs) +#define SSL_CTX_set_reverify_on_resume BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_reverify_on_resume) +#define SSL_CTX_set_select_certificate_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_select_certificate_cb) +#define SSL_CTX_set_session_cache_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_session_cache_mode) +#define SSL_CTX_set_session_id_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_session_id_context) +#define SSL_CTX_set_session_psk_dhe_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_session_psk_dhe_timeout) +#define SSL_CTX_set_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_signed_cert_timestamp_list) +#define SSL_CTX_set_signing_algorithm_prefs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_signing_algorithm_prefs) +#define SSL_CTX_set_srtp_profiles BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_srtp_profiles) +#define SSL_CTX_set_strict_cipher_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_strict_cipher_list) +#define SSL_CTX_set_ticket_aead_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_ticket_aead_method) +#define SSL_CTX_set_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_timeout) +#define SSL_CTX_set_tls_channel_id_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tls_channel_id_enabled) +#define SSL_CTX_set_tlsext_servername_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_servername_arg) +#define SSL_CTX_set_tlsext_servername_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_servername_callback) +#define SSL_CTX_set_tlsext_status_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_status_arg) +#define SSL_CTX_set_tlsext_status_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_status_cb) +#define SSL_CTX_set_tlsext_ticket_key_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_ticket_key_cb) +#define SSL_CTX_set_tlsext_ticket_keys BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_ticket_keys) +#define SSL_CTX_set_tlsext_use_srtp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_use_srtp) +#define SSL_CTX_set_tmp_dh BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tmp_dh) +#define SSL_CTX_set_tmp_dh_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tmp_dh_callback) +#define SSL_CTX_set_tmp_ecdh BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tmp_ecdh) +#define SSL_CTX_set_tmp_rsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tmp_rsa) +#define SSL_CTX_set_tmp_rsa_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_tmp_rsa_callback) +#define SSL_CTX_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_trust) +#define SSL_CTX_set_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_verify) +#define SSL_CTX_set_verify_algorithm_prefs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_verify_algorithm_prefs) +#define SSL_CTX_set_verify_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_set_verify_depth) +#define SSL_CTX_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_up_ref) +#define SSL_CTX_use_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey) +#define SSL_CTX_use_PrivateKey_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey_ASN1) +#define SSL_CTX_use_PrivateKey_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey_file) +#define SSL_CTX_use_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey) +#define SSL_CTX_use_RSAPrivateKey_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey_ASN1) +#define SSL_CTX_use_RSAPrivateKey_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey_file) +#define SSL_CTX_use_certificate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_certificate) +#define SSL_CTX_use_certificate_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_certificate_ASN1) +#define SSL_CTX_use_certificate_chain_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_certificate_chain_file) +#define SSL_CTX_use_certificate_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_certificate_file) +#define SSL_CTX_use_psk_identity_hint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_CTX_use_psk_identity_hint) +#define SSL_ECH_KEYS_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_add) +#define SSL_ECH_KEYS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_free) +#define SSL_ECH_KEYS_has_duplicate_config_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_has_duplicate_config_id) +#define SSL_ECH_KEYS_marshal_retry_configs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_marshal_retry_configs) +#define SSL_ECH_KEYS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_new) +#define SSL_ECH_KEYS_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ECH_KEYS_up_ref) +#define SSL_SESSION_copy_without_early_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_copy_without_early_data) +#define SSL_SESSION_early_data_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_early_data_capable) +#define SSL_SESSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_free) +#define SSL_SESSION_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_from_bytes) +#define SSL_SESSION_get0_cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_cipher) +#define SSL_SESSION_get0_id_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_id_context) +#define SSL_SESSION_get0_ocsp_response BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_ocsp_response) +#define SSL_SESSION_get0_peer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_peer) +#define SSL_SESSION_get0_peer_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_peer_certificates) +#define SSL_SESSION_get0_peer_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_peer_sha256) +#define SSL_SESSION_get0_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_signed_cert_timestamp_list) +#define SSL_SESSION_get0_ticket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get0_ticket) +#define SSL_SESSION_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_ex_data) +#define SSL_SESSION_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_ex_new_index) +#define SSL_SESSION_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_id) +#define SSL_SESSION_get_master_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_master_key) +#define SSL_SESSION_get_protocol_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_protocol_version) +#define SSL_SESSION_get_ticket_lifetime_hint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_ticket_lifetime_hint) +#define SSL_SESSION_get_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_time) +#define SSL_SESSION_get_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_timeout) +#define SSL_SESSION_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_get_version) +#define SSL_SESSION_has_peer_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_has_peer_sha256) +#define SSL_SESSION_has_ticket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_has_ticket) +#define SSL_SESSION_is_resumable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_is_resumable) +#define SSL_SESSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_new) +#define SSL_SESSION_set1_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set1_id) +#define SSL_SESSION_set1_id_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set1_id_context) +#define SSL_SESSION_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set_ex_data) +#define SSL_SESSION_set_protocol_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set_protocol_version) +#define SSL_SESSION_set_ticket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set_ticket) +#define SSL_SESSION_set_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set_time) +#define SSL_SESSION_set_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_set_timeout) +#define SSL_SESSION_should_be_single_use BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_should_be_single_use) +#define SSL_SESSION_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_to_bytes) +#define SSL_SESSION_to_bytes_for_ticket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_to_bytes_for_ticket) +#define SSL_SESSION_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_SESSION_up_ref) +#define SSL_accept BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_accept) +#define SSL_add0_chain_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_add0_chain_cert) +#define SSL_add1_chain_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_add1_chain_cert) +#define SSL_add_application_settings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_add_application_settings) +#define SSL_add_client_CA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_add_client_CA) +#define SSL_add_file_cert_subjects_to_stack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_add_file_cert_subjects_to_stack) +#define SSL_alert_desc_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_alert_desc_string) +#define SSL_alert_desc_string_long BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_alert_desc_string_long) +#define SSL_alert_from_verify_result BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_alert_from_verify_result) +#define SSL_alert_type_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_alert_type_string) +#define SSL_alert_type_string_long BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_alert_type_string_long) +#define SSL_cache_hit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_cache_hit) +#define SSL_can_release_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_can_release_private_key) +#define SSL_certs_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_certs_clear) +#define SSL_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_check_private_key) +#define SSL_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_clear) +#define SSL_clear_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_clear_chain_certs) +#define SSL_clear_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_clear_mode) +#define SSL_clear_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_clear_options) +#define SSL_connect BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_connect) +#define SSL_cutthrough_complete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_cutthrough_complete) +#define SSL_delegated_credential_used BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_delegated_credential_used) +#define SSL_do_handshake BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_do_handshake) +#define SSL_dup_CA_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_dup_CA_list) +#define SSL_early_callback_ctx_extension_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_early_callback_ctx_extension_get) +#define SSL_early_data_accepted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_early_data_accepted) +#define SSL_early_data_reason_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_early_data_reason_string) +#define SSL_ech_accepted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_ech_accepted) +#define SSL_enable_ocsp_stapling BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_enable_ocsp_stapling) +#define SSL_enable_signed_cert_timestamps BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_enable_signed_cert_timestamps) +#define SSL_enable_tls_channel_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_enable_tls_channel_id) +#define SSL_error_description BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_error_description) +#define SSL_export_keying_material BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_export_keying_material) +#define SSL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_free) +#define SSL_generate_key_block BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_generate_key_block) +#define SSL_get0_alpn_selected BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_alpn_selected) +#define SSL_get0_certificate_types BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_certificate_types) +#define SSL_get0_chain_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_chain_certs) +#define SSL_get0_ech_name_override BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_ech_name_override) +#define SSL_get0_ech_retry_configs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_ech_retry_configs) +#define SSL_get0_next_proto_negotiated BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_next_proto_negotiated) +#define SSL_get0_ocsp_response BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_ocsp_response) +#define SSL_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_param) +#define SSL_get0_peer_application_settings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_peer_application_settings) +#define SSL_get0_peer_certificates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_peer_certificates) +#define SSL_get0_peer_delegation_algorithms BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_peer_delegation_algorithms) +#define SSL_get0_peer_verify_algorithms BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_peer_verify_algorithms) +#define SSL_get0_server_requested_CAs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_server_requested_CAs) +#define SSL_get0_session_id_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_session_id_context) +#define SSL_get0_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get0_signed_cert_timestamp_list) +#define SSL_get1_session BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get1_session) +#define SSL_get_SSL_CTX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_SSL_CTX) +#define SSL_get_certificate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_certificate) +#define SSL_get_cipher_by_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_cipher_by_value) +#define SSL_get_cipher_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_cipher_list) +#define SSL_get_ciphers BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ciphers) +#define SSL_get_client_CA_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_client_CA_list) +#define SSL_get_client_random BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_client_random) +#define SSL_get_current_cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_current_cipher) +#define SSL_get_current_compression BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_current_compression) +#define SSL_get_current_expansion BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_current_expansion) +#define SSL_get_curve_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_curve_id) +#define SSL_get_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_curve_name) +#define SSL_get_default_timeout BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_default_timeout) +#define SSL_get_early_data_reason BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_early_data_reason) +#define SSL_get_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_error) +#define SSL_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ex_data) +#define SSL_get_ex_data_X509_STORE_CTX_idx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ex_data_X509_STORE_CTX_idx) +#define SSL_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ex_new_index) +#define SSL_get_extms_support BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_extms_support) +#define SSL_get_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_fd) +#define SSL_get_finished BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_finished) +#define SSL_get_info_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_info_callback) +#define SSL_get_ivs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ivs) +#define SSL_get_key_block_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_key_block_len) +#define SSL_get_max_cert_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_max_cert_list) +#define SSL_get_max_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_max_proto_version) +#define SSL_get_min_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_min_proto_version) +#define SSL_get_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_mode) +#define SSL_get_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_options) +#define SSL_get_peer_cert_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_cert_chain) +#define SSL_get_peer_certificate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_certificate) +#define SSL_get_peer_finished BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_finished) +#define SSL_get_peer_full_cert_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_full_cert_chain) +#define SSL_get_peer_quic_transport_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_quic_transport_params) +#define SSL_get_peer_signature_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_peer_signature_algorithm) +#define SSL_get_pending_cipher BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_pending_cipher) +#define SSL_get_privatekey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_privatekey) +#define SSL_get_psk_identity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_psk_identity) +#define SSL_get_psk_identity_hint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_psk_identity_hint) +#define SSL_get_quiet_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_quiet_shutdown) +#define SSL_get_rbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_rbio) +#define SSL_get_read_ahead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_read_ahead) +#define SSL_get_read_sequence BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_read_sequence) +#define SSL_get_rfd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_rfd) +#define SSL_get_secure_renegotiation_support BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_secure_renegotiation_support) +#define SSL_get_selected_srtp_profile BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_selected_srtp_profile) +#define SSL_get_server_random BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_server_random) +#define SSL_get_server_tmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_server_tmp_key) +#define SSL_get_servername BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_servername) +#define SSL_get_servername_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_servername_type) +#define SSL_get_session BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_session) +#define SSL_get_shared_ciphers BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_shared_ciphers) +#define SSL_get_shared_sigalgs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_shared_sigalgs) +#define SSL_get_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_shutdown) +#define SSL_get_signature_algorithm_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_signature_algorithm_digest) +#define SSL_get_signature_algorithm_key_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_signature_algorithm_key_type) +#define SSL_get_signature_algorithm_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_signature_algorithm_name) +#define SSL_get_srtp_profiles BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_srtp_profiles) +#define SSL_get_ticket_age_skew BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_ticket_age_skew) +#define SSL_get_tls_channel_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_tls_channel_id) +#define SSL_get_tls_unique BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_tls_unique) +#define SSL_get_tlsext_status_ocsp_resp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_tlsext_status_ocsp_resp) +#define SSL_get_tlsext_status_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_tlsext_status_type) +#define SSL_get_verify_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_verify_callback) +#define SSL_get_verify_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_verify_depth) +#define SSL_get_verify_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_verify_mode) +#define SSL_get_verify_result BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_verify_result) +#define SSL_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_version) +#define SSL_get_wbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_wbio) +#define SSL_get_wfd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_wfd) +#define SSL_get_write_sequence BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_get_write_sequence) +#define SSL_has_application_settings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_has_application_settings) +#define SSL_has_pending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_has_pending) +#define SSL_in_early_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_in_early_data) +#define SSL_in_false_start BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_in_false_start) +#define SSL_in_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_in_init) +#define SSL_is_dtls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_is_dtls) +#define SSL_is_init_finished BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_is_init_finished) +#define SSL_is_server BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_is_server) +#define SSL_is_signature_algorithm_rsa_pss BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_is_signature_algorithm_rsa_pss) +#define SSL_key_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_key_update) +#define SSL_library_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_library_init) +#define SSL_load_client_CA_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_load_client_CA_file) +#define SSL_load_error_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_load_error_strings) +#define SSL_magic_pending_session_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_magic_pending_session_ptr) +#define SSL_marshal_ech_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_marshal_ech_config) +#define SSL_max_seal_overhead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_max_seal_overhead) +#define SSL_need_tmp_RSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_need_tmp_RSA) +#define SSL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_new) +#define SSL_num_renegotiations BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_num_renegotiations) +#define SSL_peek BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_peek) +#define SSL_pending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_pending) +#define SSL_process_quic_post_handshake BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_process_quic_post_handshake) +#define SSL_process_tls13_new_session_ticket BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_process_tls13_new_session_ticket) +#define SSL_provide_quic_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_provide_quic_data) +#define SSL_quic_max_handshake_flight_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_quic_max_handshake_flight_len) +#define SSL_quic_read_level BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_quic_read_level) +#define SSL_quic_write_level BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_quic_write_level) +#define SSL_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_read) +#define SSL_renegotiate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_renegotiate) +#define SSL_renegotiate_pending BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_renegotiate_pending) +#define SSL_request_handshake_hints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_request_handshake_hints) +#define SSL_reset_early_data_reject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_reset_early_data_reject) +#define SSL_select_next_proto BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_select_next_proto) +#define SSL_send_fatal_alert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_send_fatal_alert) +#define SSL_serialize_capabilities BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_serialize_capabilities) +#define SSL_serialize_handshake_hints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_serialize_handshake_hints) +#define SSL_session_reused BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_session_reused) +#define SSL_set0_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set0_chain) +#define SSL_set0_client_CAs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set0_client_CAs) +#define SSL_set0_rbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set0_rbio) +#define SSL_set0_verify_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set0_verify_cert_store) +#define SSL_set0_wbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set0_wbio) +#define SSL_set1_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_chain) +#define SSL_set1_curves BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_curves) +#define SSL_set1_curves_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_curves_list) +#define SSL_set1_delegated_credential BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_delegated_credential) +#define SSL_set1_ech_config_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_ech_config_list) +#define SSL_set1_host BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_host) +#define SSL_set1_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_param) +#define SSL_set1_sigalgs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_sigalgs) +#define SSL_set1_sigalgs_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_sigalgs_list) +#define SSL_set1_tls_channel_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_tls_channel_id) +#define SSL_set1_verify_cert_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set1_verify_cert_store) +#define SSL_set_SSL_CTX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_SSL_CTX) +#define SSL_set_accept_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_accept_state) +#define SSL_set_alpn_protos BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_alpn_protos) +#define SSL_set_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_bio) +#define SSL_set_cert_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_cert_cb) +#define SSL_set_chain_and_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_chain_and_key) +#define SSL_set_cipher_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_cipher_list) +#define SSL_set_client_CA_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_client_CA_list) +#define SSL_set_connect_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_connect_state) +#define SSL_set_custom_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_custom_verify) +#define SSL_set_early_data_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_early_data_enabled) +#define SSL_set_enable_ech_grease BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_enable_ech_grease) +#define SSL_set_enforce_rsa_key_usage BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_enforce_rsa_key_usage) +#define SSL_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_ex_data) +#define SSL_set_fd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_fd) +#define SSL_set_handshake_hints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_handshake_hints) +#define SSL_set_hostflags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_hostflags) +#define SSL_set_info_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_info_callback) +#define SSL_set_jdk11_workaround BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_jdk11_workaround) +#define SSL_set_max_cert_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_max_cert_list) +#define SSL_set_max_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_max_proto_version) +#define SSL_set_max_send_fragment BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_max_send_fragment) +#define SSL_set_min_proto_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_min_proto_version) +#define SSL_set_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_mode) +#define SSL_set_msg_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_msg_callback) +#define SSL_set_msg_callback_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_msg_callback_arg) +#define SSL_set_mtu BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_mtu) +#define SSL_set_ocsp_response BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_ocsp_response) +#define SSL_set_options BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_options) +#define SSL_set_permute_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_permute_extensions) +#define SSL_set_private_key_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_private_key_method) +#define SSL_set_psk_client_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_psk_client_callback) +#define SSL_set_psk_server_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_psk_server_callback) +#define SSL_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_purpose) +#define SSL_set_quic_early_data_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_quic_early_data_context) +#define SSL_set_quic_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_quic_method) +#define SSL_set_quic_transport_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_quic_transport_params) +#define SSL_set_quic_use_legacy_codepoint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_quic_use_legacy_codepoint) +#define SSL_set_quiet_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_quiet_shutdown) +#define SSL_set_read_ahead BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_read_ahead) +#define SSL_set_renegotiate_mode BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_renegotiate_mode) +#define SSL_set_retain_only_sha256_of_client_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_retain_only_sha256_of_client_certs) +#define SSL_set_rfd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_rfd) +#define SSL_set_session BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_session) +#define SSL_set_session_id_context BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_session_id_context) +#define SSL_set_shed_handshake_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_shed_handshake_config) +#define SSL_set_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_shutdown) +#define SSL_set_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_signed_cert_timestamp_list) +#define SSL_set_signing_algorithm_prefs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_signing_algorithm_prefs) +#define SSL_set_srtp_profiles BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_srtp_profiles) +#define SSL_set_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_state) +#define SSL_set_strict_cipher_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_strict_cipher_list) +#define SSL_set_tls_channel_id_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tls_channel_id_enabled) +#define SSL_set_tlsext_host_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tlsext_host_name) +#define SSL_set_tlsext_status_ocsp_resp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tlsext_status_ocsp_resp) +#define SSL_set_tlsext_status_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tlsext_status_type) +#define SSL_set_tlsext_use_srtp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tlsext_use_srtp) +#define SSL_set_tmp_dh BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tmp_dh) +#define SSL_set_tmp_dh_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tmp_dh_callback) +#define SSL_set_tmp_ecdh BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tmp_ecdh) +#define SSL_set_tmp_rsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tmp_rsa) +#define SSL_set_tmp_rsa_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_tmp_rsa_callback) +#define SSL_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_trust) +#define SSL_set_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_verify) +#define SSL_set_verify_algorithm_prefs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_verify_algorithm_prefs) +#define SSL_set_verify_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_verify_depth) +#define SSL_set_wfd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_set_wfd) +#define SSL_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_shutdown) +#define SSL_state BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_state) +#define SSL_state_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_state_string) +#define SSL_state_string_long BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_state_string_long) +#define SSL_total_renegotiations BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_total_renegotiations) +#define SSL_use_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_PrivateKey) +#define SSL_use_PrivateKey_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_PrivateKey_ASN1) +#define SSL_use_PrivateKey_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_PrivateKey_file) +#define SSL_use_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey) +#define SSL_use_RSAPrivateKey_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey_ASN1) +#define SSL_use_RSAPrivateKey_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey_file) +#define SSL_use_certificate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_certificate) +#define SSL_use_certificate_ASN1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_certificate_ASN1) +#define SSL_use_certificate_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_certificate_file) +#define SSL_use_psk_identity_hint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_use_psk_identity_hint) +#define SSL_used_hello_retry_request BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_used_hello_retry_request) +#define SSL_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_version) +#define SSL_want BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_want) +#define SSL_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSL_write) +#define SSLeay BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLeay) +#define SSLeay_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLeay_version) +#define SSLv23_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLv23_client_method) +#define SSLv23_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLv23_method) +#define SSLv23_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SSLv23_server_method) +#define TLS_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLS_client_method) +#define TLS_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLS_method) +#define TLS_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLS_server_method) +#define TLS_with_buffers_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLS_with_buffers_method) +#define TLSv1_1_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_1_client_method) +#define TLSv1_1_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_1_method) +#define TLSv1_1_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_1_server_method) +#define TLSv1_2_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_2_client_method) +#define TLSv1_2_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_2_method) +#define TLSv1_2_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_2_server_method) +#define TLSv1_client_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_client_method) +#define TLSv1_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_method) +#define TLSv1_server_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TLSv1_server_method) +#define TRUST_TOKEN_CLIENT_add_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_add_key) +#define TRUST_TOKEN_CLIENT_begin_issuance BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance) +#define TRUST_TOKEN_CLIENT_begin_redemption BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_redemption) +#define TRUST_TOKEN_CLIENT_finish_issuance BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_issuance) +#define TRUST_TOKEN_CLIENT_finish_redemption BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_redemption) +#define TRUST_TOKEN_CLIENT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_free) +#define TRUST_TOKEN_CLIENT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_new) +#define TRUST_TOKEN_CLIENT_set_srr_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_set_srr_key) +#define TRUST_TOKEN_ISSUER_add_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_add_key) +#define TRUST_TOKEN_ISSUER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_free) +#define TRUST_TOKEN_ISSUER_issue BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_issue) +#define TRUST_TOKEN_ISSUER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_new) +#define TRUST_TOKEN_ISSUER_redeem BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem) +#define TRUST_TOKEN_ISSUER_redeem_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_raw) +#define TRUST_TOKEN_ISSUER_set_metadata_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_metadata_key) +#define TRUST_TOKEN_ISSUER_set_srr_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_srr_key) +#define TRUST_TOKEN_PRETOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_PRETOKEN_free) +#define TRUST_TOKEN_decode_private_metadata BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_decode_private_metadata) +#define TRUST_TOKEN_experiment_v1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v1) +#define TRUST_TOKEN_experiment_v2_pmb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v2_pmb) +#define TRUST_TOKEN_experiment_v2_voprf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v2_voprf) +#define TRUST_TOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_free) +#define TRUST_TOKEN_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_generate_key) +#define TRUST_TOKEN_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, TRUST_TOKEN_new) +#define USERNOTICE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_free) +#define USERNOTICE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_it) +#define USERNOTICE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_new) +#define UTF8_getc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, UTF8_getc) +#define UTF8_putc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, UTF8_putc) +#define X25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519) +#define X25519_keypair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_keypair) +#define X25519_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_public_from_private) +#define X509V3_EXT_CRL_add_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_CRL_add_nconf) +#define X509V3_EXT_REQ_add_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_REQ_add_nconf) +#define X509V3_EXT_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_add) +#define X509V3_EXT_add_alias BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_add_alias) +#define X509V3_EXT_add_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_add_list) +#define X509V3_EXT_add_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_add_nconf) +#define X509V3_EXT_add_nconf_sk BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_add_nconf_sk) +#define X509V3_EXT_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_cleanup) +#define X509V3_EXT_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_d2i) +#define X509V3_EXT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_free) +#define X509V3_EXT_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_get) +#define X509V3_EXT_get_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_get_nid) +#define X509V3_EXT_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_i2d) +#define X509V3_EXT_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_nconf) +#define X509V3_EXT_nconf_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_nconf_nid) +#define X509V3_EXT_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_print) +#define X509V3_EXT_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_print_fp) +#define X509V3_EXT_val_prn BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_EXT_val_prn) +#define X509V3_NAME_from_section BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_NAME_from_section) +#define X509V3_add1_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add1_i2d) +#define X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_standard_extensions) +#define X509V3_add_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value) +#define X509V3_add_value_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_bool) +#define X509V3_add_value_bool_nf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_bool_nf) +#define X509V3_add_value_int BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_int) +#define X509V3_add_value_uchar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_value_uchar) +#define X509V3_conf_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_conf_free) +#define X509V3_extensions_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_extensions_print) +#define X509V3_get_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_d2i) +#define X509V3_get_section BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_section) +#define X509V3_get_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_string) +#define X509V3_get_value_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_value_bool) +#define X509V3_get_value_int BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_get_value_int) +#define X509V3_parse_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_parse_list) +#define X509V3_section_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_section_free) +#define X509V3_set_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_set_ctx) +#define X509V3_set_nconf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_set_nconf) +#define X509V3_string_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_string_free) +#define X509_ALGORS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGORS_it) +#define X509_ALGOR_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define X509_ALGOR_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_dup) +#define X509_ALGOR_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_free) +#define X509_ALGOR_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define X509_ALGOR_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_it) +#define X509_ALGOR_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_new) +#define X509_ALGOR_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_set0) +#define X509_ALGOR_set_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_set_md) +#define X509_ATTRIBUTE_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_count) +#define X509_ATTRIBUTE_create BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_create) +#define X509_ATTRIBUTE_create_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_NID) +#define X509_ATTRIBUTE_create_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_OBJ) +#define X509_ATTRIBUTE_create_by_txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_txt) +#define X509_ATTRIBUTE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_dup) +#define X509_ATTRIBUTE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_free) +#define X509_ATTRIBUTE_get0_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_data) +#define X509_ATTRIBUTE_get0_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_object) +#define X509_ATTRIBUTE_get0_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_type) +#define X509_ATTRIBUTE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_it) +#define X509_ATTRIBUTE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_new) +#define X509_ATTRIBUTE_set1_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_set1_data) +#define X509_ATTRIBUTE_set1_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ATTRIBUTE_set1_object) +#define X509_CERT_AUX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CERT_AUX_free) +#define X509_CERT_AUX_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CERT_AUX_it) +#define X509_CERT_AUX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CERT_AUX_new) +#define X509_CERT_AUX_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CERT_AUX_print) +#define X509_CINF_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_free) +#define X509_CINF_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_it) +#define X509_CINF_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_new) +#define X509_CRL_INFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_INFO_free) +#define X509_CRL_INFO_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_INFO_it) +#define X509_CRL_INFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_INFO_new) +#define X509_CRL_METHOD_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_METHOD_free) +#define X509_CRL_METHOD_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_METHOD_new) +#define X509_CRL_add0_revoked BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_add0_revoked) +#define X509_CRL_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_add1_ext_i2d) +#define X509_CRL_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_add_ext) +#define X509_CRL_check_suiteb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_check_suiteb) +#define X509_CRL_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_cmp) +#define X509_CRL_delete_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_delete_ext) +#define X509_CRL_diff BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_diff) +#define X509_CRL_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_digest) +#define X509_CRL_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_dup) +#define X509_CRL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_free) +#define X509_CRL_get0_by_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_by_cert) +#define X509_CRL_get0_by_serial BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_by_serial) +#define X509_CRL_get0_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_extensions) +#define X509_CRL_get0_lastUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_lastUpdate) +#define X509_CRL_get0_nextUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_nextUpdate) +#define X509_CRL_get0_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get0_signature) +#define X509_CRL_get_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_REVOKED) +#define X509_CRL_get_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext) +#define X509_CRL_get_ext_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext_by_NID) +#define X509_CRL_get_ext_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext_by_OBJ) +#define X509_CRL_get_ext_by_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext_by_critical) +#define X509_CRL_get_ext_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext_count) +#define X509_CRL_get_ext_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_ext_d2i) +#define X509_CRL_get_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_issuer) +#define X509_CRL_get_lastUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_lastUpdate) +#define X509_CRL_get_meth_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_meth_data) +#define X509_CRL_get_nextUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_nextUpdate) +#define X509_CRL_get_signature_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_signature_nid) +#define X509_CRL_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_get_version) +#define X509_CRL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_it) +#define X509_CRL_match BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_match) +#define X509_CRL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_new) +#define X509_CRL_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_print) +#define X509_CRL_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_print_fp) +#define X509_CRL_set1_lastUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set1_lastUpdate) +#define X509_CRL_set1_nextUpdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set1_nextUpdate) +#define X509_CRL_set1_signature_algo BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set1_signature_algo) +#define X509_CRL_set1_signature_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set1_signature_value) +#define X509_CRL_set_default_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set_default_method) +#define X509_CRL_set_issuer_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set_issuer_name) +#define X509_CRL_set_meth_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set_meth_data) +#define X509_CRL_set_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_set_version) +#define X509_CRL_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_sign) +#define X509_CRL_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_sign_ctx) +#define X509_CRL_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_sort) +#define X509_CRL_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_up_ref) +#define X509_CRL_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CRL_verify) +#define X509_EXTENSIONS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSIONS_it) +#define X509_EXTENSION_create_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_create_by_NID) +#define X509_EXTENSION_create_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_create_by_OBJ) +#define X509_EXTENSION_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_dup) +#define X509_EXTENSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_free) +#define X509_EXTENSION_get_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_get_critical) +#define X509_EXTENSION_get_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_get_data) +#define X509_EXTENSION_get_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_get_object) +#define X509_EXTENSION_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_it) +#define X509_EXTENSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_new) +#define X509_EXTENSION_set_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_set_critical) +#define X509_EXTENSION_set_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_set_data) +#define X509_EXTENSION_set_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_EXTENSION_set_object) +#define X509_INFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_INFO_free) +#define X509_INFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_INFO_new) +#define X509_LOOKUP_by_alias BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_by_alias) +#define X509_LOOKUP_by_fingerprint BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_by_fingerprint) +#define X509_LOOKUP_by_issuer_serial BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_by_issuer_serial) +#define X509_LOOKUP_by_subject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_by_subject) +#define X509_LOOKUP_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_ctrl) +#define X509_LOOKUP_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_file) +#define X509_LOOKUP_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_free) +#define X509_LOOKUP_hash_dir BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_hash_dir) +#define X509_LOOKUP_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_init) +#define X509_LOOKUP_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_new) +#define X509_LOOKUP_shutdown BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_shutdown) +#define X509_NAME_ENTRIES_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRIES_it) +#define X509_NAME_ENTRY_create_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_NID) +#define X509_NAME_ENTRY_create_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_OBJ) +#define X509_NAME_ENTRY_create_by_txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_txt) +#define X509_NAME_ENTRY_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_dup) +#define X509_NAME_ENTRY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_free) +#define X509_NAME_ENTRY_get_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_get_data) +#define X509_NAME_ENTRY_get_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_get_object) +#define X509_NAME_ENTRY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_it) +#define X509_NAME_ENTRY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_new) +#define X509_NAME_ENTRY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_set) +#define X509_NAME_ENTRY_set_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_set_data) +#define X509_NAME_ENTRY_set_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_ENTRY_set_object) +#define X509_NAME_INTERNAL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_INTERNAL_it) +#define X509_NAME_add_entry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry) +#define X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) +#define X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) +#define X509_NAME_add_entry_by_txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_txt) +#define X509_NAME_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_cmp) +#define X509_NAME_delete_entry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_delete_entry) +#define X509_NAME_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_digest) +#define X509_NAME_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_dup) +#define X509_NAME_entry_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_entry_count) +#define X509_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_free) +#define X509_NAME_get0_der BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get0_der) +#define X509_NAME_get_entry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get_entry) +#define X509_NAME_get_index_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get_index_by_NID) +#define X509_NAME_get_index_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get_index_by_OBJ) +#define X509_NAME_get_text_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get_text_by_NID) +#define X509_NAME_get_text_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_get_text_by_OBJ) +#define X509_NAME_hash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_hash) +#define X509_NAME_hash_old BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_hash_old) +#define X509_NAME_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_it) +#define X509_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_new) +#define X509_NAME_oneline BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_oneline) +#define X509_NAME_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_print) +#define X509_NAME_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_print_ex) +#define X509_NAME_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_print_ex_fp) +#define X509_NAME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_set) +#define X509_OBJECT_free_contents BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_free_contents) +#define X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) +#define X509_OBJECT_get_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get_type) +#define X509_OBJECT_idx_by_subject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_idx_by_subject) +#define X509_OBJECT_retrieve_by_subject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_retrieve_by_subject) +#define X509_OBJECT_retrieve_match BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_retrieve_match) +#define X509_OBJECT_up_ref_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_up_ref_count) +#define X509_PKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PKEY_free) +#define X509_PKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PKEY_new) +#define X509_POLICY_NODE_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_POLICY_NODE_print) +#define X509_PUBKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_free) +#define X509_PUBKEY_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get) +#define X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) +#define X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define X509_PUBKEY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_it) +#define X509_PUBKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_new) +#define X509_PUBKEY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set) +#define X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define X509_PURPOSE_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_add) +#define X509_PURPOSE_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_cleanup) +#define X509_PURPOSE_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get0) +#define X509_PURPOSE_get0_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get0_name) +#define X509_PURPOSE_get0_sname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get0_sname) +#define X509_PURPOSE_get_by_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_by_id) +#define X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) +#define X509_PURPOSE_get_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_count) +#define X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_id) +#define X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) +#define X509_PURPOSE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_set) +#define X509_REQ_INFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_INFO_free) +#define X509_REQ_INFO_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_INFO_it) +#define X509_REQ_INFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_INFO_new) +#define X509_REQ_add1_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add1_attr) +#define X509_REQ_add1_attr_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_NID) +#define X509_REQ_add1_attr_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_OBJ) +#define X509_REQ_add1_attr_by_txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_txt) +#define X509_REQ_add_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add_extensions) +#define X509_REQ_add_extensions_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_add_extensions_nid) +#define X509_REQ_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_check_private_key) +#define X509_REQ_delete_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_delete_attr) +#define X509_REQ_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_digest) +#define X509_REQ_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_dup) +#define X509_REQ_extension_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_extension_nid) +#define X509_REQ_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_free) +#define X509_REQ_get0_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get0_signature) +#define X509_REQ_get1_email BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get1_email) +#define X509_REQ_get_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_attr) +#define X509_REQ_get_attr_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_attr_by_NID) +#define X509_REQ_get_attr_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_attr_by_OBJ) +#define X509_REQ_get_attr_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_attr_count) +#define X509_REQ_get_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_extensions) +#define X509_REQ_get_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_pubkey) +#define X509_REQ_get_signature_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_signature_nid) +#define X509_REQ_get_subject_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_subject_name) +#define X509_REQ_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_get_version) +#define X509_REQ_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_it) +#define X509_REQ_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_new) +#define X509_REQ_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_print) +#define X509_REQ_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_print_ex) +#define X509_REQ_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_print_fp) +#define X509_REQ_set_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_set_pubkey) +#define X509_REQ_set_subject_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_set_subject_name) +#define X509_REQ_set_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_set_version) +#define X509_REQ_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_sign) +#define X509_REQ_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_sign_ctx) +#define X509_REQ_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REQ_verify) +#define X509_REVOKED_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_add1_ext_i2d) +#define X509_REVOKED_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_add_ext) +#define X509_REVOKED_delete_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_delete_ext) +#define X509_REVOKED_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_dup) +#define X509_REVOKED_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_free) +#define X509_REVOKED_get0_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get0_extensions) +#define X509_REVOKED_get0_revocationDate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get0_revocationDate) +#define X509_REVOKED_get0_serialNumber BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get0_serialNumber) +#define X509_REVOKED_get_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext) +#define X509_REVOKED_get_ext_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_NID) +#define X509_REVOKED_get_ext_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_OBJ) +#define X509_REVOKED_get_ext_by_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_critical) +#define X509_REVOKED_get_ext_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext_count) +#define X509_REVOKED_get_ext_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_get_ext_d2i) +#define X509_REVOKED_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_it) +#define X509_REVOKED_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_new) +#define X509_REVOKED_set_revocationDate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_set_revocationDate) +#define X509_REVOKED_set_serialNumber BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_REVOKED_set_serialNumber) +#define X509_SIG_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_free) +#define X509_SIG_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_get0) +#define X509_SIG_getm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_getm) +#define X509_SIG_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_it) +#define X509_SIG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_new) +#define X509_STORE_CTX_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_cleanup) +#define X509_STORE_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_free) +#define X509_STORE_CTX_get0_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_cert) +#define X509_STORE_CTX_get0_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_chain) +#define X509_STORE_CTX_get0_current_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_current_crl) +#define X509_STORE_CTX_get0_current_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_current_issuer) +#define X509_STORE_CTX_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_param) +#define X509_STORE_CTX_get0_parent_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_parent_ctx) +#define X509_STORE_CTX_get0_policy_tree BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_policy_tree) +#define X509_STORE_CTX_get0_store BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_store) +#define X509_STORE_CTX_get0_untrusted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get0_untrusted) +#define X509_STORE_CTX_get1_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get1_chain) +#define X509_STORE_CTX_get1_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get1_issuer) +#define X509_STORE_CTX_get_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_chain) +#define X509_STORE_CTX_get_current_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_current_cert) +#define X509_STORE_CTX_get_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_error) +#define X509_STORE_CTX_get_error_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_error_depth) +#define X509_STORE_CTX_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_ex_data) +#define X509_STORE_CTX_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_ex_new_index) +#define X509_STORE_CTX_get_explicit_policy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_get_explicit_policy) +#define X509_STORE_CTX_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_init) +#define X509_STORE_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_new) +#define X509_STORE_CTX_purpose_inherit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_purpose_inherit) +#define X509_STORE_CTX_set0_crls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set0_crls) +#define X509_STORE_CTX_set0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set0_param) +#define X509_STORE_CTX_set_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_cert) +#define X509_STORE_CTX_set_chain BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_chain) +#define X509_STORE_CTX_set_default BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_default) +#define X509_STORE_CTX_set_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_depth) +#define X509_STORE_CTX_set_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_error) +#define X509_STORE_CTX_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_ex_data) +#define X509_STORE_CTX_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_flags) +#define X509_STORE_CTX_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_purpose) +#define X509_STORE_CTX_set_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_time) +#define X509_STORE_CTX_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_trust) +#define X509_STORE_CTX_set_verify_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_set_verify_cb) +#define X509_STORE_CTX_trusted_stack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_trusted_stack) +#define X509_STORE_CTX_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_CTX_zero) +#define X509_STORE_add_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_add_cert) +#define X509_STORE_add_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_add_crl) +#define X509_STORE_add_lookup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_add_lookup) +#define X509_STORE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_free) +#define X509_STORE_get0_objects BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get0_objects) +#define X509_STORE_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get0_param) +#define X509_STORE_get1_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get1_certs) +#define X509_STORE_get1_crls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get1_crls) +#define X509_STORE_get_by_subject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_by_subject) +#define X509_STORE_get_cert_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_cert_crl) +#define X509_STORE_get_check_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_check_crl) +#define X509_STORE_get_check_issued BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_check_issued) +#define X509_STORE_get_check_revocation BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_check_revocation) +#define X509_STORE_get_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_cleanup) +#define X509_STORE_get_get_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_get_crl) +#define X509_STORE_get_get_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_get_issuer) +#define X509_STORE_get_lookup_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_lookup_certs) +#define X509_STORE_get_lookup_crls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_lookup_crls) +#define X509_STORE_get_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_verify) +#define X509_STORE_get_verify_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_get_verify_cb) +#define X509_STORE_load_locations BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_load_locations) +#define X509_STORE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_new) +#define X509_STORE_set1_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set1_param) +#define X509_STORE_set_cert_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_cert_crl) +#define X509_STORE_set_check_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_check_crl) +#define X509_STORE_set_check_issued BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_check_issued) +#define X509_STORE_set_check_revocation BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_check_revocation) +#define X509_STORE_set_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_cleanup) +#define X509_STORE_set_default_paths BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_default_paths) +#define X509_STORE_set_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_depth) +#define X509_STORE_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_flags) +#define X509_STORE_set_get_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_get_crl) +#define X509_STORE_set_get_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_get_issuer) +#define X509_STORE_set_lookup_certs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_lookup_certs) +#define X509_STORE_set_lookup_crls BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_lookup_crls) +#define X509_STORE_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_purpose) +#define X509_STORE_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_trust) +#define X509_STORE_set_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_verify) +#define X509_STORE_set_verify_cb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_set_verify_cb) +#define X509_STORE_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_up_ref) +#define X509_TRUST_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_add) +#define X509_TRUST_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_cleanup) +#define X509_TRUST_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get0) +#define X509_TRUST_get0_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get0_name) +#define X509_TRUST_get_by_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get_by_id) +#define X509_TRUST_get_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get_count) +#define X509_TRUST_get_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get_flags) +#define X509_TRUST_get_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_get_trust) +#define X509_TRUST_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_TRUST_set) +#define X509_VAL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_free) +#define X509_VAL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_it) +#define X509_VAL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_new) +#define X509_VERIFY_PARAM_add0_policy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_policy) +#define X509_VERIFY_PARAM_add0_table BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_table) +#define X509_VERIFY_PARAM_add1_host BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add1_host) +#define X509_VERIFY_PARAM_clear_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_clear_flags) +#define X509_VERIFY_PARAM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_free) +#define X509_VERIFY_PARAM_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0) +#define X509_VERIFY_PARAM_get0_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_name) +#define X509_VERIFY_PARAM_get0_peername BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_peername) +#define X509_VERIFY_PARAM_get_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_count) +#define X509_VERIFY_PARAM_get_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_depth) +#define X509_VERIFY_PARAM_get_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_flags) +#define X509_VERIFY_PARAM_inherit BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_inherit) +#define X509_VERIFY_PARAM_lookup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_lookup) +#define X509_VERIFY_PARAM_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_new) +#define X509_VERIFY_PARAM_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1) +#define X509_VERIFY_PARAM_set1_email BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_email) +#define X509_VERIFY_PARAM_set1_host BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_host) +#define X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) +#define X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) +#define X509_VERIFY_PARAM_set1_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_name) +#define X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define X509_VERIFY_PARAM_set_depth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_depth) +#define X509_VERIFY_PARAM_set_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_flags) +#define X509_VERIFY_PARAM_set_hostflags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_hostflags) +#define X509_VERIFY_PARAM_set_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_purpose) +#define X509_VERIFY_PARAM_set_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time) +#define X509_VERIFY_PARAM_set_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_trust) +#define X509_VERIFY_PARAM_table_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_table_cleanup) +#define X509_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_ext_i2d) +#define X509_add1_reject_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_reject_object) +#define X509_add1_trust_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_trust_object) +#define X509_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add_ext) +#define X509_alias_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_alias_get0) +#define X509_alias_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_alias_set1) +#define X509_chain_check_suiteb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_chain_check_suiteb) +#define X509_chain_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_chain_up_ref) +#define X509_check_akid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_akid) +#define X509_check_ca BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_ca) +#define X509_check_email BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_email) +#define X509_check_host BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_host) +#define X509_check_ip BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_ip) +#define X509_check_ip_asc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_ip_asc) +#define X509_check_issued BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_issued) +#define X509_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_private_key) +#define X509_check_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_purpose) +#define X509_check_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_trust) +#define X509_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp) +#define X509_cmp_current_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_current_time) +#define X509_cmp_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_time) +#define X509_delete_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_delete_ext) +#define X509_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_digest) +#define X509_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_dup) +#define X509_email_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_email_free) +#define X509_find_by_issuer_and_serial BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_find_by_issuer_and_serial) +#define X509_find_by_subject BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_find_by_subject) +#define X509_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_free) +#define X509_get0_authority_issuer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_authority_issuer) +#define X509_get0_authority_key_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_authority_key_id) +#define X509_get0_authority_serial BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_authority_serial) +#define X509_get0_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_extensions) +#define X509_get0_notAfter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_notAfter) +#define X509_get0_notBefore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_notBefore) +#define X509_get0_pubkey_bitstr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_pubkey_bitstr) +#define X509_get0_serialNumber BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_serialNumber) +#define X509_get0_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_signature) +#define X509_get0_subject_key_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_subject_key_id) +#define X509_get0_tbs_sigalg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_tbs_sigalg) +#define X509_get0_uids BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get0_uids) +#define X509_get1_email BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get1_email) +#define X509_get1_ocsp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get1_ocsp) +#define X509_get_X509_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_X509_PUBKEY) +#define X509_get_default_cert_area BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_cert_area) +#define X509_get_default_cert_dir BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_cert_dir) +#define X509_get_default_cert_dir_env BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_cert_dir_env) +#define X509_get_default_cert_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_cert_file) +#define X509_get_default_cert_file_env BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_cert_file_env) +#define X509_get_default_private_dir BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_default_private_dir) +#define X509_get_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ex_data) +#define X509_get_ex_new_index BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ex_new_index) +#define X509_get_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext) +#define X509_get_ext_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext_by_NID) +#define X509_get_ext_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext_by_OBJ) +#define X509_get_ext_by_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext_by_critical) +#define X509_get_ext_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext_count) +#define X509_get_ext_d2i BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_ext_d2i) +#define X509_get_extended_key_usage BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_extended_key_usage) +#define X509_get_extension_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_extension_flags) +#define X509_get_issuer_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_issuer_name) +#define X509_get_key_usage BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_key_usage) +#define X509_get_notAfter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_notAfter) +#define X509_get_notBefore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_notBefore) +#define X509_get_pathlen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_pathlen) +#define X509_get_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_pubkey) +#define X509_get_serialNumber BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_serialNumber) +#define X509_get_signature_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_signature_nid) +#define X509_get_subject_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_subject_name) +#define X509_get_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_get_version) +#define X509_getm_notAfter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_getm_notAfter) +#define X509_getm_notBefore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_getm_notBefore) +#define X509_gmtime_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_gmtime_adj) +#define X509_issuer_and_serial_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_issuer_and_serial_cmp) +#define X509_issuer_name_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_issuer_name_cmp) +#define X509_issuer_name_hash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_issuer_name_hash) +#define X509_issuer_name_hash_old BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_issuer_name_hash_old) +#define X509_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_it) +#define X509_keyid_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_keyid_get0) +#define X509_keyid_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_keyid_set1) +#define X509_load_cert_crl_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_load_cert_crl_file) +#define X509_load_cert_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_load_cert_file) +#define X509_load_crl_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_load_crl_file) +#define X509_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_new) +#define X509_ocspid_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ocspid_print) +#define X509_parse_from_buffer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define X509_policy_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_check) +#define X509_policy_level_get0_node BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_level_get0_node) +#define X509_policy_level_node_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_level_node_count) +#define X509_policy_node_get0_parent BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_node_get0_parent) +#define X509_policy_node_get0_policy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_node_get0_policy) +#define X509_policy_node_get0_qualifiers BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_node_get0_qualifiers) +#define X509_policy_tree_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_free) +#define X509_policy_tree_get0_level BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_get0_level) +#define X509_policy_tree_get0_policies BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_get0_policies) +#define X509_policy_tree_get0_user_policies BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_get0_user_policies) +#define X509_policy_tree_level_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_tree_level_count) +#define X509_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print) +#define X509_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex) +#define X509_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex_fp) +#define X509_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_fp) +#define X509_pubkey_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_pubkey_digest) +#define X509_reject_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_reject_clear) +#define X509_set1_notAfter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set1_notAfter) +#define X509_set1_notBefore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set1_notBefore) +#define X509_set1_signature_algo BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set1_signature_algo) +#define X509_set1_signature_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set1_signature_value) +#define X509_set_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_ex_data) +#define X509_set_issuer_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_issuer_name) +#define X509_set_notAfter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_notAfter) +#define X509_set_notBefore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_notBefore) +#define X509_set_pubkey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_pubkey) +#define X509_set_serialNumber BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_serialNumber) +#define X509_set_subject_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_subject_name) +#define X509_set_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_set_version) +#define X509_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign) +#define X509_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign_ctx) +#define X509_signature_dump BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_dump) +#define X509_signature_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_print) +#define X509_subject_name_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_subject_name_cmp) +#define X509_subject_name_hash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_subject_name_hash) +#define X509_subject_name_hash_old BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_subject_name_hash_old) +#define X509_supported_extension BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_supported_extension) +#define X509_time_adj BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_time_adj) +#define X509_time_adj_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_time_adj_ex) +#define X509_to_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_to_X509_REQ) +#define X509_trust_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_trust_clear) +#define X509_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_up_ref) +#define X509_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify) +#define X509_verify_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert) +#define X509_verify_cert_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert_error_string) +#define X509at_add1_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_add1_attr) +#define X509at_add1_attr_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_add1_attr_by_NID) +#define X509at_add1_attr_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_add1_attr_by_OBJ) +#define X509at_add1_attr_by_txt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_add1_attr_by_txt) +#define X509at_delete_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_delete_attr) +#define X509at_get_attr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_get_attr) +#define X509at_get_attr_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_get_attr_by_NID) +#define X509at_get_attr_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_get_attr_by_OBJ) +#define X509at_get_attr_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509at_get_attr_count) +#define X509v3_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_add_ext) +#define X509v3_delete_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_delete_ext) +#define X509v3_get_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_get_ext) +#define X509v3_get_ext_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_get_ext_by_NID) +#define X509v3_get_ext_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_get_ext_by_OBJ) +#define X509v3_get_ext_by_critical BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_get_ext_by_critical) +#define X509v3_get_ext_count BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_get_ext_count) +#define __clang_at_available_requires_core_foundation_framework BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, __clang_at_available_requires_core_foundation_framework) +#define __clang_call_terminate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, __clang_call_terminate) +#define a2i_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, a2i_GENERAL_NAME) +#define a2i_IPADDRESS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, a2i_IPADDRESS) +#define a2i_IPADDRESS_NC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, a2i_IPADDRESS_NC) +#define aes128gcmsiv_aes_ks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_aes_ks) +#define aes128gcmsiv_aes_ks_enc_x1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_aes_ks_enc_x1) +#define aes128gcmsiv_dec BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_dec) +#define aes128gcmsiv_ecb_enc_block BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_ecb_enc_block) +#define aes128gcmsiv_enc_msg_x4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_enc_msg_x4) +#define aes128gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_enc_msg_x8) +#define aes128gcmsiv_kdf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes128gcmsiv_kdf) +#define aes256gcmsiv_aes_ks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_aes_ks) +#define aes256gcmsiv_aes_ks_enc_x1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_aes_ks_enc_x1) +#define aes256gcmsiv_dec BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_dec) +#define aes256gcmsiv_ecb_enc_block BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_ecb_enc_block) +#define aes256gcmsiv_enc_msg_x4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x4) +#define aes256gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x8) +#define aes256gcmsiv_kdf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes256gcmsiv_kdf) +#define aes_ctr_set_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_ctr_set_key) +#define aes_hw_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_cbc_encrypt) +#define aes_hw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_ctr32_encrypt_blocks) +#define aes_hw_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_decrypt) +#define aes_hw_ecb_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_ecb_encrypt) +#define aes_hw_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_encrypt) +#define aes_hw_set_decrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_set_decrypt_key) +#define aes_hw_set_encrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_hw_set_encrypt_key) +#define aes_nohw_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_cbc_encrypt) +#define aes_nohw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_ctr32_encrypt_blocks) +#define aes_nohw_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_decrypt) +#define aes_nohw_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_encrypt) +#define aes_nohw_set_decrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_set_decrypt_key) +#define aes_nohw_set_encrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aes_nohw_set_encrypt_key) +#define aesgcmsiv_htable6_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesgcmsiv_htable6_init) +#define aesgcmsiv_htable_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesgcmsiv_htable_init) +#define aesgcmsiv_htable_polyval BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesgcmsiv_htable_polyval) +#define aesgcmsiv_polyval_horner BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesgcmsiv_polyval_horner) +#define aesni_gcm_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesni_gcm_decrypt) +#define aesni_gcm_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, aesni_gcm_encrypt) +#define asn1_bit_string_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_bit_string_length) +#define asn1_do_adb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_do_adb) +#define asn1_enc_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_free) +#define asn1_enc_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_init) +#define asn1_enc_restore BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_restore) +#define asn1_enc_save BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_enc_save) +#define asn1_generalizedtime_to_tm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_generalizedtime_to_tm) +#define asn1_get_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_choice_selector) +#define asn1_get_field_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_field_ptr) +#define asn1_get_string_table_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_get_string_table_for_testing) +#define asn1_is_printable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_is_printable) +#define asn1_item_combine_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_item_combine_free) +#define asn1_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_dec_and_test_zero) +#define asn1_refcount_set_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_set_one) +#define asn1_set_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define asn1_type_value_as_pointer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_type_value_as_pointer) +#define asn1_utctime_to_tm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_utctime_to_tm) +#define beeu_mod_inverse_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, beeu_mod_inverse_vartime) +#define bio_clear_socket_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_clear_socket_error) +#define bio_fd_should_retry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_fd_should_retry) +#define bio_ip_and_port_to_socket_and_addr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_ip_and_port_to_socket_and_addr) +#define bio_sock_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_sock_error) +#define bio_socket_nbio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bio_socket_nbio) +#define bn_abs_sub_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_abs_sub_consttime) +#define bn_add_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_add_words) +#define bn_copy_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_copy_words) +#define bn_div_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_div_consttime) +#define bn_expand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_expand) +#define bn_fits_in_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_fits_in_words) +#define bn_from_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_from_montgomery) +#define bn_from_montgomery_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_from_montgomery_small) +#define bn_gather5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_gather5) +#define bn_in_range_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_in_range_words) +#define bn_is_bit_set_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_is_bit_set_words) +#define bn_is_relatively_prime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_is_relatively_prime) +#define bn_jacobi BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_jacobi) +#define bn_lcm_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_lcm_consttime) +#define bn_less_than_montgomery_R BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_less_than_montgomery_R) +#define bn_less_than_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_less_than_words) +#define bn_miller_rabin_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_miller_rabin_init) +#define bn_miller_rabin_iteration BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_miller_rabin_iteration) +#define bn_minimal_width BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_minimal_width) +#define bn_mod_add_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_add_consttime) +#define bn_mod_add_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_add_words) +#define bn_mod_exp_base_2_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_exp_base_2_consttime) +#define bn_mod_exp_mont_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_exp_mont_small) +#define bn_mod_inverse0_prime_mont_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_inverse0_prime_mont_small) +#define bn_mod_inverse_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_inverse_consttime) +#define bn_mod_inverse_prime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_inverse_prime) +#define bn_mod_inverse_secret_prime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_inverse_secret_prime) +#define bn_mod_lshift1_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_lshift1_consttime) +#define bn_mod_lshift_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_lshift_consttime) +#define bn_mod_mul_montgomery_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_mul_montgomery_small) +#define bn_mod_sub_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_sub_consttime) +#define bn_mod_sub_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_sub_words) +#define bn_mod_u16_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mod_u16_consttime) +#define bn_mont_n0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mont_n0) +#define bn_mul_add_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_add_words) +#define bn_mul_comba4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba4) +#define bn_mul_comba8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba8) +#define bn_mul_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_consttime) +#define bn_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont) +#define bn_mul_mont_gather5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_gather5) +#define bn_mul_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_small) +#define bn_mul_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_words) +#define bn_odd_number_is_obviously_composite BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_odd_number_is_obviously_composite) +#define bn_one_to_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_one_to_montgomery) +#define bn_power5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_power5) +#define bn_rand_range_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_rand_range_words) +#define bn_rand_secret_range BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_rand_secret_range) +#define bn_reduce_once BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_reduce_once) +#define bn_reduce_once_in_place BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_reduce_once_in_place) +#define bn_resize_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_resize_words) +#define bn_rshift1_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_rshift1_words) +#define bn_rshift_secret_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_rshift_secret_shift) +#define bn_rshift_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_rshift_words) +#define bn_scatter5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_scatter5) +#define bn_select_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_select_words) +#define bn_set_minimal_width BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_set_minimal_width) +#define bn_set_static_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_set_static_words) +#define bn_set_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_set_words) +#define bn_sqr8x_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr8x_internal) +#define bn_sqr_comba4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr_comba4) +#define bn_sqr_comba8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr_comba8) +#define bn_sqr_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr_consttime) +#define bn_sqr_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr_small) +#define bn_sqr_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqr_words) +#define bn_sqrx8x_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sqrx8x_internal) +#define bn_sub_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_sub_words) +#define bn_to_montgomery_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_to_montgomery_small) +#define bn_uadd_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_uadd_consttime) +#define bn_usub_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_usub_consttime) +#define bn_wexpand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_wexpand) +#define boringssl_self_test_hmac_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, boringssl_self_test_hmac_sha256) +#define boringssl_self_test_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, boringssl_self_test_sha256) +#define boringssl_self_test_sha512 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, boringssl_self_test_sha512) +#define c2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_BIT_STRING) +#define c2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_INTEGER) +#define c2i_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_OBJECT) +#define cbb_add_latin1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbb_add_latin1) +#define cbb_add_ucs2_be BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbb_add_ucs2_be) +#define cbb_add_utf32_be BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbb_add_utf32_be) +#define cbb_add_utf8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbb_add_utf8) +#define cbb_get_utf8_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbb_get_utf8_len) +#define cbs_get_latin1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbs_get_latin1) +#define cbs_get_ucs2_be BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbs_get_ucs2_be) +#define cbs_get_utf32_be BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbs_get_utf32_be) +#define cbs_get_utf8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, cbs_get_utf8) +#define chacha20_poly1305_open BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_open) +#define chacha20_poly1305_seal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_seal) +#define crypto_gcm_clmul_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, crypto_gcm_clmul_enabled) +#define d2i_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ACCESS_DESCRIPTION) +#define d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) +#define d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) +#define d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) +#define d2i_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_ENUMERATED) +#define d2i_ASN1_GENERALIZEDTIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_GENERALIZEDTIME) +#define d2i_ASN1_GENERALSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_GENERALSTRING) +#define d2i_ASN1_IA5STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_IA5STRING) +#define d2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_INTEGER) +#define d2i_ASN1_NULL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_NULL) +#define d2i_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_OBJECT) +#define d2i_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_OCTET_STRING) +#define d2i_ASN1_PRINTABLE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_PRINTABLE) +#define d2i_ASN1_PRINTABLESTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_PRINTABLESTRING) +#define d2i_ASN1_SEQUENCE_ANY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_SEQUENCE_ANY) +#define d2i_ASN1_SET_ANY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_SET_ANY) +#define d2i_ASN1_T61STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_T61STRING) +#define d2i_ASN1_TIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_TIME) +#define d2i_ASN1_TYPE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_TYPE) +#define d2i_ASN1_UNIVERSALSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_UNIVERSALSTRING) +#define d2i_ASN1_UTCTIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_UTCTIME) +#define d2i_ASN1_UTF8STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_UTF8STRING) +#define d2i_ASN1_VISIBLESTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_VISIBLESTRING) +#define d2i_AUTHORITY_INFO_ACCESS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_AUTHORITY_INFO_ACCESS) +#define d2i_AUTHORITY_KEYID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_AUTHORITY_KEYID) +#define d2i_AutoPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_AutoPrivateKey) +#define d2i_BASIC_CONSTRAINTS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_BASIC_CONSTRAINTS) +#define d2i_CERTIFICATEPOLICIES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_CERTIFICATEPOLICIES) +#define d2i_CRL_DIST_POINTS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_CRL_DIST_POINTS) +#define d2i_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DHparams) +#define d2i_DHparams_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DHparams_bio) +#define d2i_DIRECTORYSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DIRECTORYSTRING) +#define d2i_DISPLAYTEXT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DISPLAYTEXT) +#define d2i_DIST_POINT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DIST_POINT) +#define d2i_DIST_POINT_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DIST_POINT_NAME) +#define d2i_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAPrivateKey) +#define d2i_DSAPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAPrivateKey_bio) +#define d2i_DSAPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAPrivateKey_fp) +#define d2i_DSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAPublicKey) +#define d2i_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSA_PUBKEY) +#define d2i_DSA_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSA_PUBKEY_bio) +#define d2i_DSA_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSA_PUBKEY_fp) +#define d2i_DSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSA_SIG) +#define d2i_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAparams) +#define d2i_ECDSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECDSA_SIG) +#define d2i_ECParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECParameters) +#define d2i_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPrivateKey) +#define d2i_ECPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPrivateKey_bio) +#define d2i_ECPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPrivateKey_fp) +#define d2i_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_EC_PUBKEY) +#define d2i_EC_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_EC_PUBKEY_bio) +#define d2i_EC_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_EC_PUBKEY_fp) +#define d2i_EDIPARTYNAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_EDIPARTYNAME) +#define d2i_EXTENDED_KEY_USAGE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_EXTENDED_KEY_USAGE) +#define d2i_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_GENERAL_NAME) +#define d2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_GENERAL_NAMES) +#define d2i_ISSUING_DIST_POINT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ISSUING_DIST_POINT) +#define d2i_NETSCAPE_SPKAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_NETSCAPE_SPKAC) +#define d2i_NETSCAPE_SPKI BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_NETSCAPE_SPKI) +#define d2i_NOTICEREF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_NOTICEREF) +#define d2i_OTHERNAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_OTHERNAME) +#define d2i_PKCS12 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS12) +#define d2i_PKCS12_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS12_bio) +#define d2i_PKCS12_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS12_fp) +#define d2i_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS7) +#define d2i_PKCS7_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS7_bio) +#define d2i_PKCS8PrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8PrivateKey_bio) +#define d2i_PKCS8PrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8PrivateKey_fp) +#define d2i_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO) +#define d2i_PKCS8_PRIV_KEY_INFO_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO_bio) +#define d2i_PKCS8_PRIV_KEY_INFO_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO_fp) +#define d2i_PKCS8_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_bio) +#define d2i_PKCS8_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PKCS8_fp) +#define d2i_POLICYINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_POLICYINFO) +#define d2i_POLICYQUALINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_POLICYQUALINFO) +#define d2i_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PROXY_CERT_INFO_EXTENSION) +#define d2i_PROXY_POLICY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PROXY_POLICY) +#define d2i_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY) +#define d2i_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY_bio) +#define d2i_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PUBKEY_fp) +#define d2i_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PrivateKey) +#define d2i_PrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PrivateKey_bio) +#define d2i_PrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PrivateKey_fp) +#define d2i_PublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_PublicKey) +#define d2i_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPrivateKey) +#define d2i_RSAPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPrivateKey_bio) +#define d2i_RSAPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPrivateKey_fp) +#define d2i_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPublicKey) +#define d2i_RSAPublicKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPublicKey_bio) +#define d2i_RSAPublicKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSAPublicKey_fp) +#define d2i_RSA_PSS_PARAMS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSA_PSS_PARAMS) +#define d2i_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSA_PUBKEY) +#define d2i_RSA_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSA_PUBKEY_bio) +#define d2i_RSA_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_RSA_PUBKEY_fp) +#define d2i_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_SSL_SESSION) +#define d2i_SSL_SESSION_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_SSL_SESSION_bio) +#define d2i_USERNOTICE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_USERNOTICE) +#define d2i_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509) +#define d2i_X509_ALGOR BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_ALGOR) +#define d2i_X509_ALGORS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_ALGORS) +#define d2i_X509_ATTRIBUTE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_ATTRIBUTE) +#define d2i_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_AUX) +#define d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) +#define d2i_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CINF) +#define d2i_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL) +#define d2i_X509_CRL_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_INFO) +#define d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_bio) +#define d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_fp) +#define d2i_X509_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_EXTENSION) +#define d2i_X509_EXTENSIONS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_EXTENSIONS) +#define d2i_X509_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_NAME) +#define d2i_X509_NAME_ENTRY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_NAME_ENTRY) +#define d2i_X509_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_PUBKEY) +#define d2i_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ) +#define d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) +#define d2i_X509_REQ_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ_bio) +#define d2i_X509_REQ_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ_fp) +#define d2i_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REVOKED) +#define d2i_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_SIG) +#define d2i_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_VAL) +#define d2i_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_bio) +#define d2i_X509_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_fp) +#define dh_compute_key_padded_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dh_compute_key_padded_no_self_test) +#define dsa_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dsa_asn1_meth) +#define dsa_check_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, dsa_check_parameters) +#define ec_GFp_mont_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_add) +#define ec_GFp_mont_dbl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_dbl) +#define ec_GFp_mont_felem_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_from_bytes) +#define ec_GFp_mont_felem_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_mul) +#define ec_GFp_mont_felem_sqr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_sqr) +#define ec_GFp_mont_felem_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_felem_to_bytes) +#define ec_GFp_mont_group_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_group_finish) +#define ec_GFp_mont_group_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_group_init) +#define ec_GFp_mont_group_set_curve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_group_set_curve) +#define ec_GFp_mont_init_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_init_precomp) +#define ec_GFp_mont_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_mul) +#define ec_GFp_mont_mul_base BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_mul_base) +#define ec_GFp_mont_mul_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_mul_batch) +#define ec_GFp_mont_mul_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_mul_precomp) +#define ec_GFp_mont_mul_public_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_mont_mul_public_batch) +#define ec_GFp_nistp_recode_scalar_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_nistp_recode_scalar_bits) +#define ec_GFp_simple_cmp_x_coordinate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_cmp_x_coordinate) +#define ec_GFp_simple_felem_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_felem_from_bytes) +#define ec_GFp_simple_felem_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_felem_to_bytes) +#define ec_GFp_simple_group_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_group_finish) +#define ec_GFp_simple_group_get_curve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_group_get_curve) +#define ec_GFp_simple_group_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_group_init) +#define ec_GFp_simple_group_set_curve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_group_set_curve) +#define ec_GFp_simple_invert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_invert) +#define ec_GFp_simple_is_at_infinity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_is_at_infinity) +#define ec_GFp_simple_is_on_curve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_is_on_curve) +#define ec_GFp_simple_point_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_point_copy) +#define ec_GFp_simple_point_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_point_init) +#define ec_GFp_simple_point_set_to_infinity BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_point_set_to_infinity) +#define ec_GFp_simple_points_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_GFp_simple_points_equal) +#define ec_affine_jacobian_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_affine_jacobian_equal) +#define ec_affine_select BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_affine_select) +#define ec_affine_to_jacobian BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_affine_to_jacobian) +#define ec_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_asn1_meth) +#define ec_bignum_to_felem BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_bignum_to_felem) +#define ec_bignum_to_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_bignum_to_scalar) +#define ec_cmp_x_coordinate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_cmp_x_coordinate) +#define ec_compute_wNAF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_compute_wNAF) +#define ec_felem_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_add) +#define ec_felem_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_equal) +#define ec_felem_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_from_bytes) +#define ec_felem_neg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_neg) +#define ec_felem_non_zero_mask BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_non_zero_mask) +#define ec_felem_select BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_select) +#define ec_felem_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_sub) +#define ec_felem_to_bignum BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_to_bignum) +#define ec_felem_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_felem_to_bytes) +#define ec_get_x_coordinate_as_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_get_x_coordinate_as_bytes) +#define ec_get_x_coordinate_as_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_get_x_coordinate_as_scalar) +#define ec_group_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_group_new) +#define ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha512_sswu_draft07) +#define ec_hash_to_scalar_p384_xmd_sha512_draft07 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha512_draft07) +#define ec_init_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_init_precomp) +#define ec_jacobian_to_affine BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine) +#define ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) +#define ec_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_pkey_meth) +#define ec_point_from_uncompressed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_from_uncompressed) +#define ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_no_self_test) +#define ec_point_mul_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar) +#define ec_point_mul_scalar_base BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar_base) +#define ec_point_mul_scalar_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar_batch) +#define ec_point_mul_scalar_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar_precomp) +#define ec_point_mul_scalar_public BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar_public) +#define ec_point_mul_scalar_public_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar_public_batch) +#define ec_point_select BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_select) +#define ec_point_set_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_set_affine_coordinates) +#define ec_point_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_to_bytes) +#define ec_precomp_select BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_precomp_select) +#define ec_random_nonzero_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_random_nonzero_scalar) +#define ec_scalar_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_add) +#define ec_scalar_equal_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_equal_vartime) +#define ec_scalar_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_from_bytes) +#define ec_scalar_from_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_from_montgomery) +#define ec_scalar_inv0_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_inv0_montgomery) +#define ec_scalar_is_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_is_zero) +#define ec_scalar_mul_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_mul_montgomery) +#define ec_scalar_neg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_neg) +#define ec_scalar_reduce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_reduce) +#define ec_scalar_select BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_select) +#define ec_scalar_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_sub) +#define ec_scalar_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_to_bytes) +#define ec_scalar_to_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_to_montgomery) +#define ec_scalar_to_montgomery_inv_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_scalar_to_montgomery_inv_vartime) +#define ec_set_to_safe_point BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_set_to_safe_point) +#define ec_simple_scalar_inv0_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_simple_scalar_inv0_montgomery) +#define ec_simple_scalar_to_montgomery_inv_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_simple_scalar_to_montgomery_inv_vartime) +#define ecdsa_do_verify_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_do_verify_no_self_test) +#define ecdsa_sign_with_nonce_for_known_answer_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_sign_with_nonce_for_known_answer_test) +#define ecp_nistz256_avx2_select_w7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_avx2_select_w7) +#define ecp_nistz256_div_by_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_div_by_2) +#define ecp_nistz256_from_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_from_mont) +#define ecp_nistz256_mul_by_2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_by_2) +#define ecp_nistz256_mul_by_3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_by_3) +#define ecp_nistz256_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_mont) +#define ecp_nistz256_neg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_neg) +#define ecp_nistz256_ord_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_mul_mont) +#define ecp_nistz256_ord_sqr_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_sqr_mont) +#define ecp_nistz256_point_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add) +#define ecp_nistz256_point_add_affine BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_affine) +#define ecp_nistz256_point_double BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_double) +#define ecp_nistz256_select_w5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w5) +#define ecp_nistz256_select_w7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w7) +#define ecp_nistz256_sqr_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_sqr_mont) +#define ecp_nistz256_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_sub) +#define ecp_nistz256_to_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_to_mont) +#define ed25519_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ed25519_asn1_meth) +#define ed25519_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ed25519_pkey_meth) +#define gcm_ghash_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_avx) +#define gcm_ghash_clmul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_clmul) +#define gcm_ghash_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_neon) +#define gcm_ghash_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_nohw) +#define gcm_ghash_ssse3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_ssse3) +#define gcm_ghash_v8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_v8) +#define gcm_gmult_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_avx) +#define gcm_gmult_clmul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_clmul) +#define gcm_gmult_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_neon) +#define gcm_gmult_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_nohw) +#define gcm_gmult_ssse3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_ssse3) +#define gcm_gmult_v8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_gmult_v8) +#define gcm_init_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_avx) +#define gcm_init_clmul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_clmul) +#define gcm_init_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_neon) +#define gcm_init_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_nohw) +#define gcm_init_ssse3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_ssse3) +#define gcm_init_v8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_init_v8) +#define i2a_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2a_ACCESS_DESCRIPTION) +#define i2a_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2a_ASN1_ENUMERATED) +#define i2a_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2a_ASN1_INTEGER) +#define i2a_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2a_ASN1_OBJECT) +#define i2a_ASN1_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2a_ASN1_STRING) +#define i2c_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2c_ASN1_BIT_STRING) +#define i2c_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2c_ASN1_INTEGER) +#define i2d_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ACCESS_DESCRIPTION) +#define i2d_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_BIT_STRING) +#define i2d_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_BMPSTRING) +#define i2d_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_BOOLEAN) +#define i2d_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_ENUMERATED) +#define i2d_ASN1_GENERALIZEDTIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_GENERALIZEDTIME) +#define i2d_ASN1_GENERALSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_GENERALSTRING) +#define i2d_ASN1_IA5STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_IA5STRING) +#define i2d_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_INTEGER) +#define i2d_ASN1_NULL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_NULL) +#define i2d_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_OBJECT) +#define i2d_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_OCTET_STRING) +#define i2d_ASN1_PRINTABLE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_PRINTABLE) +#define i2d_ASN1_PRINTABLESTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_PRINTABLESTRING) +#define i2d_ASN1_SEQUENCE_ANY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_SEQUENCE_ANY) +#define i2d_ASN1_SET_ANY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_SET_ANY) +#define i2d_ASN1_T61STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_T61STRING) +#define i2d_ASN1_TIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_TIME) +#define i2d_ASN1_TYPE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_TYPE) +#define i2d_ASN1_UNIVERSALSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_UNIVERSALSTRING) +#define i2d_ASN1_UTCTIME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_UTCTIME) +#define i2d_ASN1_UTF8STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_UTF8STRING) +#define i2d_ASN1_VISIBLESTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ASN1_VISIBLESTRING) +#define i2d_AUTHORITY_INFO_ACCESS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_AUTHORITY_INFO_ACCESS) +#define i2d_AUTHORITY_KEYID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_AUTHORITY_KEYID) +#define i2d_BASIC_CONSTRAINTS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_BASIC_CONSTRAINTS) +#define i2d_CERTIFICATEPOLICIES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_CERTIFICATEPOLICIES) +#define i2d_CRL_DIST_POINTS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_CRL_DIST_POINTS) +#define i2d_DHparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DHparams) +#define i2d_DHparams_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DHparams_bio) +#define i2d_DIRECTORYSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DIRECTORYSTRING) +#define i2d_DISPLAYTEXT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DISPLAYTEXT) +#define i2d_DIST_POINT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DIST_POINT) +#define i2d_DIST_POINT_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DIST_POINT_NAME) +#define i2d_DSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAPrivateKey) +#define i2d_DSAPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAPrivateKey_bio) +#define i2d_DSAPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAPrivateKey_fp) +#define i2d_DSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAPublicKey) +#define i2d_DSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSA_PUBKEY) +#define i2d_DSA_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSA_PUBKEY_bio) +#define i2d_DSA_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSA_PUBKEY_fp) +#define i2d_DSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSA_SIG) +#define i2d_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAparams) +#define i2d_ECDSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECDSA_SIG) +#define i2d_ECParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECParameters) +#define i2d_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPrivateKey) +#define i2d_ECPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPrivateKey_bio) +#define i2d_ECPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPrivateKey_fp) +#define i2d_EC_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_EC_PUBKEY) +#define i2d_EC_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_EC_PUBKEY_bio) +#define i2d_EC_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_EC_PUBKEY_fp) +#define i2d_EDIPARTYNAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_EDIPARTYNAME) +#define i2d_EXTENDED_KEY_USAGE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_EXTENDED_KEY_USAGE) +#define i2d_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_GENERAL_NAME) +#define i2d_GENERAL_NAMES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_GENERAL_NAMES) +#define i2d_ISSUING_DIST_POINT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ISSUING_DIST_POINT) +#define i2d_NETSCAPE_SPKAC BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_NETSCAPE_SPKAC) +#define i2d_NETSCAPE_SPKI BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_NETSCAPE_SPKI) +#define i2d_NOTICEREF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_NOTICEREF) +#define i2d_OTHERNAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_OTHERNAME) +#define i2d_PKCS12 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS12) +#define i2d_PKCS12_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS12_bio) +#define i2d_PKCS12_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS12_fp) +#define i2d_PKCS7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS7) +#define i2d_PKCS7_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS7_bio) +#define i2d_PKCS8PrivateKeyInfo_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKeyInfo_bio) +#define i2d_PKCS8PrivateKeyInfo_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKeyInfo_fp) +#define i2d_PKCS8PrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_bio) +#define i2d_PKCS8PrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_fp) +#define i2d_PKCS8PrivateKey_nid_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_nid_bio) +#define i2d_PKCS8PrivateKey_nid_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_nid_fp) +#define i2d_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO) +#define i2d_PKCS8_PRIV_KEY_INFO_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO_bio) +#define i2d_PKCS8_PRIV_KEY_INFO_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO_fp) +#define i2d_PKCS8_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_bio) +#define i2d_PKCS8_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PKCS8_fp) +#define i2d_POLICYINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_POLICYINFO) +#define i2d_POLICYQUALINFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_POLICYQUALINFO) +#define i2d_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PROXY_CERT_INFO_EXTENSION) +#define i2d_PROXY_POLICY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PROXY_POLICY) +#define i2d_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY) +#define i2d_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY_bio) +#define i2d_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PUBKEY_fp) +#define i2d_PrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PrivateKey) +#define i2d_PrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PrivateKey_bio) +#define i2d_PrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PrivateKey_fp) +#define i2d_PublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_PublicKey) +#define i2d_RSAPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPrivateKey) +#define i2d_RSAPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPrivateKey_bio) +#define i2d_RSAPrivateKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPrivateKey_fp) +#define i2d_RSAPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPublicKey) +#define i2d_RSAPublicKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPublicKey_bio) +#define i2d_RSAPublicKey_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSAPublicKey_fp) +#define i2d_RSA_PSS_PARAMS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSA_PSS_PARAMS) +#define i2d_RSA_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSA_PUBKEY) +#define i2d_RSA_PUBKEY_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSA_PUBKEY_bio) +#define i2d_RSA_PUBKEY_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_RSA_PUBKEY_fp) +#define i2d_SSL_SESSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_SSL_SESSION) +#define i2d_SSL_SESSION_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_SSL_SESSION_bio) +#define i2d_USERNOTICE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_USERNOTICE) +#define i2d_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509) +#define i2d_X509_ALGOR BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_ALGOR) +#define i2d_X509_ALGORS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_ALGORS) +#define i2d_X509_ATTRIBUTE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_ATTRIBUTE) +#define i2d_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_AUX) +#define i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) +#define i2d_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CINF) +#define i2d_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL) +#define i2d_X509_CRL_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_INFO) +#define i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_bio) +#define i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_fp) +#define i2d_X509_CRL_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_tbs) +#define i2d_X509_EXTENSION BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_EXTENSION) +#define i2d_X509_EXTENSIONS BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_EXTENSIONS) +#define i2d_X509_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_NAME) +#define i2d_X509_NAME_ENTRY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_NAME_ENTRY) +#define i2d_X509_PUBKEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_PUBKEY) +#define i2d_X509_REQ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REQ) +#define i2d_X509_REQ_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REQ_INFO) +#define i2d_X509_REQ_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REQ_bio) +#define i2d_X509_REQ_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REQ_fp) +#define i2d_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REVOKED) +#define i2d_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_SIG) +#define i2d_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_VAL) +#define i2d_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_bio) +#define i2d_X509_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_fp) +#define i2d_X509_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_tbs) +#define i2d_re_X509_CRL_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_re_X509_CRL_tbs) +#define i2d_re_X509_REQ_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_re_X509_REQ_tbs) +#define i2d_re_X509_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_re_X509_tbs) +#define i2o_ECPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2o_ECPublicKey) +#define i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) +#define i2s_ASN1_ENUMERATED_TABLE BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED_TABLE) +#define i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) +#define i2s_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_OCTET_STRING) +#define i2t_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2t_ASN1_OBJECT) +#define i2v_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2v_ASN1_BIT_STRING) +#define i2v_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2v_GENERAL_NAME) +#define i2v_GENERAL_NAMES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2v_GENERAL_NAMES) +#define kBoringSSLRSASqrtTwo BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kBoringSSLRSASqrtTwo) +#define kBoringSSLRSASqrtTwoLen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kBoringSSLRSASqrtTwoLen) +#define kOpenSSLReasonStringData BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonStringData) +#define kOpenSSLReasonValues BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonValues) +#define kOpenSSLReasonValuesLen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, kOpenSSLReasonValuesLen) +#define level_add_node BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, level_add_node) +#define level_find_node BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, level_find_node) +#define md4_block_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, md4_block_data_order) +#define md5_block_asm_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, md5_block_asm_data_order) +#define o2i_ECPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, o2i_ECPublicKey) +#define pkcs12_iterations_acceptable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs12_iterations_acceptable) +#define pkcs12_key_gen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs12_key_gen) +#define pkcs12_pbe_encrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs12_pbe_encrypt_init) +#define pkcs7_add_signed_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs7_add_signed_data) +#define pkcs7_parse_header BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs7_parse_header) +#define pkcs8_pbe_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pkcs8_pbe_decrypt) +#define pmbtoken_exp1_blind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_blind) +#define pmbtoken_exp1_client_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_client_key_from_bytes) +#define pmbtoken_exp1_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_generate_key) +#define pmbtoken_exp1_get_h_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_get_h_for_testing) +#define pmbtoken_exp1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_issuer_key_from_bytes) +#define pmbtoken_exp1_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_read) +#define pmbtoken_exp1_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_sign) +#define pmbtoken_exp1_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp1_unblind) +#define pmbtoken_exp2_blind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_blind) +#define pmbtoken_exp2_client_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_client_key_from_bytes) +#define pmbtoken_exp2_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_generate_key) +#define pmbtoken_exp2_get_h_for_testing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_get_h_for_testing) +#define pmbtoken_exp2_issuer_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_issuer_key_from_bytes) +#define pmbtoken_exp2_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_read) +#define pmbtoken_exp2_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_sign) +#define pmbtoken_exp2_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, pmbtoken_exp2_unblind) +#define policy_cache_find_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_find_data) +#define policy_cache_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_free) +#define policy_cache_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_set) +#define policy_cache_set_mapping BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_cache_set_mapping) +#define policy_data_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_data_free) +#define policy_data_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_data_new) +#define policy_node_cmp_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_cmp_new) +#define policy_node_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_free) +#define policy_node_match BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, policy_node_match) +#define poly_Rq_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, poly_Rq_mul) +#define rand_fork_unsafe_buffering_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rand_fork_unsafe_buffering_enabled) +#define rsa_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_asn1_meth) +#define rsa_check_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_check_public_key) +#define rsa_default_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_decrypt) +#define rsa_default_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_private_transform) +#define rsa_default_sign_raw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_sign_raw) +#define rsa_default_size BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_default_size) +#define rsa_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pkey_meth) +#define rsa_sign_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_sign_no_self_test) +#define rsa_verify_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_verify_no_self_test) +#define rsa_verify_raw_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_verify_raw_no_self_test) +#define rsaz_1024_gather5_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_gather5_avx2) +#define rsaz_1024_mul_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_mul_avx2) +#define rsaz_1024_norm2red_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_norm2red_avx2) +#define rsaz_1024_red2norm_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_red2norm_avx2) +#define rsaz_1024_scatter5_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_scatter5_avx2) +#define rsaz_1024_sqr_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsaz_1024_sqr_avx2) +#define s2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, s2i_ASN1_INTEGER) +#define s2i_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, s2i_ASN1_OCTET_STRING) +#define sha1_block_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order) +#define sha256_block_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order) +#define sha512_block_data_order BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_block_data_order) +#define sk_CRYPTO_BUFFER_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_copy_func) +#define sk_CRYPTO_BUFFER_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_free_func) +#define sk_CRYPTO_BUFFER_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_deep_copy) +#define sk_CRYPTO_BUFFER_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_new_null) +#define sk_CRYPTO_BUFFER_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_num) +#define sk_CRYPTO_BUFFER_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_push) +#define sk_CRYPTO_BUFFER_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_set) +#define sk_CRYPTO_BUFFER_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_value) +#define sk_SRTP_PROTECTION_PROFILE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_new_null) +#define sk_SRTP_PROTECTION_PROFILE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_num) +#define sk_SRTP_PROTECTION_PROFILE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_push) +#define sk_SSL_CIPHER_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_call_cmp_func) +#define sk_SSL_CIPHER_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_delete) +#define sk_SSL_CIPHER_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_dup) +#define sk_SSL_CIPHER_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_find) +#define sk_SSL_CIPHER_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_new_null) +#define sk_SSL_CIPHER_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_num) +#define sk_SSL_CIPHER_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_push) +#define sk_SSL_CIPHER_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_CIPHER_value) +#define sk_X509_NAME_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_cmp_func) +#define sk_X509_NAME_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_copy_func) +#define sk_X509_NAME_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_free_func) +#define sk_X509_NAME_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_deep_copy) +#define sk_X509_NAME_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_find) +#define sk_X509_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_free) +#define sk_X509_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_new) +#define sk_X509_NAME_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_new_null) +#define sk_X509_NAME_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_pop_free) +#define sk_X509_NAME_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_push) +#define sk_X509_NAME_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_set_cmp_func) +#define sk_X509_NAME_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_sort) +#define sk_X509_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_free_func) +#define sk_X509_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_new_null) +#define sk_X509_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_num) +#define sk_X509_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_pop_free) +#define sk_X509_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_shift) +#define sk_X509_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_value) +#define sk_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_deep_copy) +#define sk_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_delete) +#define sk_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_delete_ptr) +#define sk_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_dup) +#define sk_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_find) +#define sk_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_free) +#define sk_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_insert) +#define sk_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_is_sorted) +#define sk_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_new) +#define sk_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_new_null) +#define sk_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_num) +#define sk_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_pop) +#define sk_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_pop_free) +#define sk_pop_free_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_pop_free_ex) +#define sk_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_push) +#define sk_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_set) +#define sk_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_set_cmp_func) +#define sk_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_shift) +#define sk_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_sort) +#define sk_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_value) +#define sk_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_zero) +#define tree_find_sk BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, tree_find_sk) +#define v2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_ASN1_BIT_STRING) +#define v2i_GENERAL_NAME BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAME) +#define v2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAMES) +#define v2i_GENERAL_NAME_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v2i_GENERAL_NAME_ex) +#define v3_akey_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_akey_id) +#define v3_alt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_alt) +#define v3_bcons BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_bcons) +#define v3_cpols BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_cpols) +#define v3_crl_invdate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_crl_invdate) +#define v3_crl_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_crl_num) +#define v3_crl_reason BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_crl_reason) +#define v3_crld BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_crld) +#define v3_delta_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_delta_crl) +#define v3_ext_ku BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ext_ku) +#define v3_freshest_crl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_freshest_crl) +#define v3_idp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_idp) +#define v3_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_info) +#define v3_inhibit_anyp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_inhibit_anyp) +#define v3_key_usage BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_key_usage) +#define v3_name_constraints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_name_constraints) +#define v3_ns_ia5_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ns_ia5_list) +#define v3_nscert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_nscert) +#define v3_ocsp_accresp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ocsp_accresp) +#define v3_ocsp_nocheck BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_ocsp_nocheck) +#define v3_pci BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_pci) +#define v3_policy_constraints BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_policy_constraints) +#define v3_policy_mappings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_policy_mappings) +#define v3_sinfo BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_sinfo) +#define v3_skey_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, v3_skey_id) +#define voprf_exp2_blind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_blind) +#define voprf_exp2_client_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_client_key_from_bytes) +#define voprf_exp2_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_generate_key) +#define voprf_exp2_issuer_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_issuer_key_from_bytes) +#define voprf_exp2_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_read) +#define voprf_exp2_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_sign) +#define voprf_exp2_unblind BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, voprf_exp2_unblind) +#define vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_cbc_encrypt) +#define vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) +#define vpaes_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_decrypt) +#define vpaes_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_encrypt) +#define vpaes_set_decrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_set_decrypt_key) +#define vpaes_set_encrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_set_encrypt_key) +#define x25519_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_asn1_meth) +#define x25519_ge_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_add) +#define x25519_ge_frombytes_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_frombytes_vartime) +#define x25519_ge_p1p1_to_p2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_p1p1_to_p2) +#define x25519_ge_p1p1_to_p3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_p1p1_to_p3) +#define x25519_ge_p3_to_cached BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_p3_to_cached) +#define x25519_ge_scalarmult BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_scalarmult) +#define x25519_ge_scalarmult_base BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_scalarmult_base) +#define x25519_ge_scalarmult_small_precomp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_scalarmult_small_precomp) +#define x25519_ge_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_sub) +#define x25519_ge_tobytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_tobytes) +#define x25519_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_pkey_meth) +#define x25519_sc_reduce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_sc_reduce) +#define x509V3_add_value_asn1_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509V3_add_value_asn1_string) +#define x509_digest_sign_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_digest_sign_algorithm) +#define x509_digest_verify_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_digest_verify_init) +#define x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define x509_rsa_ctx_to_pss BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_rsa_ctx_to_pss) +#define x509_rsa_pss_to_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_rsa_pss_to_ctx) +#define x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_a2i_ipadd) +#define x509v3_bytes_to_hex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_bytes_to_hex) +#define x509v3_cache_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_cache_extensions) +#define x509v3_hex_to_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_hex_to_bytes) +#define x509v3_looks_like_dns_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_looks_like_dns_name) +#define x509v3_name_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_name_cmp) +#define sk_TRUST_TOKEN_PRETOKEN_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_free_func) +#define sk_TRUST_TOKEN_PRETOKEN_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_copy_func) +#define sk_TRUST_TOKEN_PRETOKEN_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_call_cmp_func) +#define sk_TRUST_TOKEN_PRETOKEN_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_new) +#define sk_TRUST_TOKEN_PRETOKEN_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_new_null) +#define sk_TRUST_TOKEN_PRETOKEN_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_num) +#define sk_TRUST_TOKEN_PRETOKEN_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_zero) +#define sk_TRUST_TOKEN_PRETOKEN_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_value) +#define sk_TRUST_TOKEN_PRETOKEN_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_set) +#define sk_TRUST_TOKEN_PRETOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_free) +#define sk_TRUST_TOKEN_PRETOKEN_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_pop_free) +#define sk_TRUST_TOKEN_PRETOKEN_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_insert) +#define sk_TRUST_TOKEN_PRETOKEN_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_delete) +#define sk_TRUST_TOKEN_PRETOKEN_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_delete_ptr) +#define sk_TRUST_TOKEN_PRETOKEN_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_find) +#define sk_TRUST_TOKEN_PRETOKEN_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_shift) +#define sk_TRUST_TOKEN_PRETOKEN_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_push) +#define sk_TRUST_TOKEN_PRETOKEN_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_pop) +#define sk_TRUST_TOKEN_PRETOKEN_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_dup) +#define sk_TRUST_TOKEN_PRETOKEN_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_sort) +#define sk_TRUST_TOKEN_PRETOKEN_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_is_sorted) +#define sk_TRUST_TOKEN_PRETOKEN_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_set_cmp_func) +#define sk_TRUST_TOKEN_PRETOKEN_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_PRETOKEN_deep_copy) +#define sk_CRYPTO_EX_DATA_FUNCS_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_call_free_func) +#define sk_CRYPTO_EX_DATA_FUNCS_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_call_copy_func) +#define sk_CRYPTO_EX_DATA_FUNCS_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_call_cmp_func) +#define sk_CRYPTO_EX_DATA_FUNCS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_new) +#define sk_CRYPTO_EX_DATA_FUNCS_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_new_null) +#define sk_CRYPTO_EX_DATA_FUNCS_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_num) +#define sk_CRYPTO_EX_DATA_FUNCS_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_zero) +#define sk_CRYPTO_EX_DATA_FUNCS_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_value) +#define sk_CRYPTO_EX_DATA_FUNCS_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_set) +#define sk_CRYPTO_EX_DATA_FUNCS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_free) +#define sk_CRYPTO_EX_DATA_FUNCS_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_pop_free) +#define sk_CRYPTO_EX_DATA_FUNCS_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_insert) +#define sk_CRYPTO_EX_DATA_FUNCS_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_delete) +#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_delete_ptr) +#define sk_CRYPTO_EX_DATA_FUNCS_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_find) +#define sk_CRYPTO_EX_DATA_FUNCS_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_shift) +#define sk_CRYPTO_EX_DATA_FUNCS_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_push) +#define sk_CRYPTO_EX_DATA_FUNCS_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_pop) +#define sk_CRYPTO_EX_DATA_FUNCS_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_dup) +#define sk_CRYPTO_EX_DATA_FUNCS_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_sort) +#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_is_sorted) +#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func) +#define sk_CRYPTO_EX_DATA_FUNCS_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_EX_DATA_FUNCS_deep_copy) +#define sk_BIGNUM_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_call_free_func) +#define sk_BIGNUM_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_call_copy_func) +#define sk_BIGNUM_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_call_cmp_func) +#define sk_BIGNUM_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_new) +#define sk_BIGNUM_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_new_null) +#define sk_BIGNUM_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_num) +#define sk_BIGNUM_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_zero) +#define sk_BIGNUM_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_value) +#define sk_BIGNUM_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_set) +#define sk_BIGNUM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_free) +#define sk_BIGNUM_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_pop_free) +#define sk_BIGNUM_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_insert) +#define sk_BIGNUM_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_delete) +#define sk_BIGNUM_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_delete_ptr) +#define sk_BIGNUM_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_find) +#define sk_BIGNUM_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_shift) +#define sk_BIGNUM_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_push) +#define sk_BIGNUM_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_pop) +#define sk_BIGNUM_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_dup) +#define sk_BIGNUM_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_sort) +#define sk_BIGNUM_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_is_sorted) +#define sk_BIGNUM_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_set_cmp_func) +#define sk_BIGNUM_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIGNUM_deep_copy) +#define sk_X509_POLICY_DATA_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_free_func) +#define sk_X509_POLICY_DATA_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_copy_func) +#define sk_X509_POLICY_DATA_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_call_cmp_func) +#define sk_X509_POLICY_DATA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_new) +#define sk_X509_POLICY_DATA_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_new_null) +#define sk_X509_POLICY_DATA_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_num) +#define sk_X509_POLICY_DATA_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_zero) +#define sk_X509_POLICY_DATA_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_value) +#define sk_X509_POLICY_DATA_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_set) +#define sk_X509_POLICY_DATA_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_free) +#define sk_X509_POLICY_DATA_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_pop_free) +#define sk_X509_POLICY_DATA_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_insert) +#define sk_X509_POLICY_DATA_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_delete) +#define sk_X509_POLICY_DATA_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_delete_ptr) +#define sk_X509_POLICY_DATA_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_find) +#define sk_X509_POLICY_DATA_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_shift) +#define sk_X509_POLICY_DATA_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_push) +#define sk_X509_POLICY_DATA_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_pop) +#define sk_X509_POLICY_DATA_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_dup) +#define sk_X509_POLICY_DATA_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_sort) +#define sk_X509_POLICY_DATA_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_is_sorted) +#define sk_X509_POLICY_DATA_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_set_cmp_func) +#define sk_X509_POLICY_DATA_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_DATA_deep_copy) +#define sk_STACK_OF_X509_NAME_ENTRY_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_free_func) +#define sk_STACK_OF_X509_NAME_ENTRY_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_copy_func) +#define sk_STACK_OF_X509_NAME_ENTRY_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_call_cmp_func) +#define sk_STACK_OF_X509_NAME_ENTRY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_new) +#define sk_STACK_OF_X509_NAME_ENTRY_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_new_null) +#define sk_STACK_OF_X509_NAME_ENTRY_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_num) +#define sk_STACK_OF_X509_NAME_ENTRY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_zero) +#define sk_STACK_OF_X509_NAME_ENTRY_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_value) +#define sk_STACK_OF_X509_NAME_ENTRY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_set) +#define sk_STACK_OF_X509_NAME_ENTRY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_free) +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_pop_free) +#define sk_STACK_OF_X509_NAME_ENTRY_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_insert) +#define sk_STACK_OF_X509_NAME_ENTRY_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_delete) +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_delete_ptr) +#define sk_STACK_OF_X509_NAME_ENTRY_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_find) +#define sk_STACK_OF_X509_NAME_ENTRY_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_shift) +#define sk_STACK_OF_X509_NAME_ENTRY_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_push) +#define sk_STACK_OF_X509_NAME_ENTRY_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_pop) +#define sk_STACK_OF_X509_NAME_ENTRY_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_dup) +#define sk_STACK_OF_X509_NAME_ENTRY_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_sort) +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_is_sorted) +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func) +#define sk_STACK_OF_X509_NAME_ENTRY_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_STACK_OF_X509_NAME_ENTRY_deep_copy) +#define sk_BY_DIR_HASH_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_call_free_func) +#define sk_BY_DIR_HASH_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_call_copy_func) +#define sk_BY_DIR_HASH_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_call_cmp_func) +#define sk_BY_DIR_HASH_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_new) +#define sk_BY_DIR_HASH_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_new_null) +#define sk_BY_DIR_HASH_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_num) +#define sk_BY_DIR_HASH_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_zero) +#define sk_BY_DIR_HASH_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_value) +#define sk_BY_DIR_HASH_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_set) +#define sk_BY_DIR_HASH_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_free) +#define sk_BY_DIR_HASH_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_pop_free) +#define sk_BY_DIR_HASH_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_insert) +#define sk_BY_DIR_HASH_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_delete) +#define sk_BY_DIR_HASH_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_delete_ptr) +#define sk_BY_DIR_HASH_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_find) +#define sk_BY_DIR_HASH_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_shift) +#define sk_BY_DIR_HASH_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_push) +#define sk_BY_DIR_HASH_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_pop) +#define sk_BY_DIR_HASH_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_dup) +#define sk_BY_DIR_HASH_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_sort) +#define sk_BY_DIR_HASH_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_is_sorted) +#define sk_BY_DIR_HASH_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_set_cmp_func) +#define sk_BY_DIR_HASH_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_HASH_deep_copy) +#define sk_BY_DIR_ENTRY_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_call_free_func) +#define sk_BY_DIR_ENTRY_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_call_copy_func) +#define sk_BY_DIR_ENTRY_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_call_cmp_func) +#define sk_BY_DIR_ENTRY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_new) +#define sk_BY_DIR_ENTRY_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_new_null) +#define sk_BY_DIR_ENTRY_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_num) +#define sk_BY_DIR_ENTRY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_zero) +#define sk_BY_DIR_ENTRY_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_value) +#define sk_BY_DIR_ENTRY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_set) +#define sk_BY_DIR_ENTRY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_free) +#define sk_BY_DIR_ENTRY_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_pop_free) +#define sk_BY_DIR_ENTRY_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_insert) +#define sk_BY_DIR_ENTRY_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_delete) +#define sk_BY_DIR_ENTRY_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_delete_ptr) +#define sk_BY_DIR_ENTRY_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_find) +#define sk_BY_DIR_ENTRY_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_shift) +#define sk_BY_DIR_ENTRY_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_push) +#define sk_BY_DIR_ENTRY_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_pop) +#define sk_BY_DIR_ENTRY_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_dup) +#define sk_BY_DIR_ENTRY_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_sort) +#define sk_BY_DIR_ENTRY_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_is_sorted) +#define sk_BY_DIR_ENTRY_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_set_cmp_func) +#define sk_BY_DIR_ENTRY_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BY_DIR_ENTRY_deep_copy) +#define sk_X509_ALGOR_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_call_free_func) +#define sk_X509_ALGOR_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_call_copy_func) +#define sk_X509_ALGOR_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_call_cmp_func) +#define sk_X509_ALGOR_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_new) +#define sk_X509_ALGOR_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_new_null) +#define sk_X509_ALGOR_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_num) +#define sk_X509_ALGOR_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_zero) +#define sk_X509_ALGOR_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_value) +#define sk_X509_ALGOR_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_set) +#define sk_X509_ALGOR_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_free) +#define sk_X509_ALGOR_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_pop_free) +#define sk_X509_ALGOR_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_insert) +#define sk_X509_ALGOR_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_delete) +#define sk_X509_ALGOR_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_delete_ptr) +#define sk_X509_ALGOR_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_find) +#define sk_X509_ALGOR_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_shift) +#define sk_X509_ALGOR_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_push) +#define sk_X509_ALGOR_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_pop) +#define sk_X509_ALGOR_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_dup) +#define sk_X509_ALGOR_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_sort) +#define sk_X509_ALGOR_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_is_sorted) +#define sk_X509_ALGOR_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_set_cmp_func) +#define sk_X509_ALGOR_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ALGOR_deep_copy) +#define sk_X509_NAME_ENTRY_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_call_free_func) +#define sk_X509_NAME_ENTRY_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_call_copy_func) +#define sk_X509_NAME_ENTRY_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_call_cmp_func) +#define sk_X509_NAME_ENTRY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_new) +#define sk_X509_NAME_ENTRY_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_new_null) +#define sk_X509_NAME_ENTRY_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_num) +#define sk_X509_NAME_ENTRY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_zero) +#define sk_X509_NAME_ENTRY_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_value) +#define sk_X509_NAME_ENTRY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_set) +#define sk_X509_NAME_ENTRY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_free) +#define sk_X509_NAME_ENTRY_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_pop_free) +#define sk_X509_NAME_ENTRY_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_insert) +#define sk_X509_NAME_ENTRY_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_delete) +#define sk_X509_NAME_ENTRY_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_delete_ptr) +#define sk_X509_NAME_ENTRY_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_find) +#define sk_X509_NAME_ENTRY_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_shift) +#define sk_X509_NAME_ENTRY_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_push) +#define sk_X509_NAME_ENTRY_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_pop) +#define sk_X509_NAME_ENTRY_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_dup) +#define sk_X509_NAME_ENTRY_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_sort) +#define sk_X509_NAME_ENTRY_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_is_sorted) +#define sk_X509_NAME_ENTRY_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_set_cmp_func) +#define sk_X509_NAME_ENTRY_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_ENTRY_deep_copy) +#define sk_X509_NAME_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_free_func) +#define sk_X509_NAME_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_copy_func) +#define sk_X509_NAME_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_call_cmp_func) +#define sk_X509_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_new) +#define sk_X509_NAME_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_new_null) +#define sk_X509_NAME_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_num) +#define sk_X509_NAME_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_zero) +#define sk_X509_NAME_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_value) +#define sk_X509_NAME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_set) +#define sk_X509_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_free) +#define sk_X509_NAME_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_pop_free) +#define sk_X509_NAME_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_insert) +#define sk_X509_NAME_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_delete) +#define sk_X509_NAME_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_delete_ptr) +#define sk_X509_NAME_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_find) +#define sk_X509_NAME_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_shift) +#define sk_X509_NAME_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_push) +#define sk_X509_NAME_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_pop) +#define sk_X509_NAME_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_dup) +#define sk_X509_NAME_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_sort) +#define sk_X509_NAME_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_is_sorted) +#define sk_X509_NAME_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_set_cmp_func) +#define sk_X509_NAME_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_NAME_deep_copy) +#define sk_X509_EXTENSION_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_call_free_func) +#define sk_X509_EXTENSION_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_call_copy_func) +#define sk_X509_EXTENSION_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_call_cmp_func) +#define sk_X509_EXTENSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_new) +#define sk_X509_EXTENSION_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_new_null) +#define sk_X509_EXTENSION_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_num) +#define sk_X509_EXTENSION_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_zero) +#define sk_X509_EXTENSION_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_value) +#define sk_X509_EXTENSION_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_set) +#define sk_X509_EXTENSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_free) +#define sk_X509_EXTENSION_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_pop_free) +#define sk_X509_EXTENSION_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_insert) +#define sk_X509_EXTENSION_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_delete) +#define sk_X509_EXTENSION_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_delete_ptr) +#define sk_X509_EXTENSION_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_find) +#define sk_X509_EXTENSION_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_shift) +#define sk_X509_EXTENSION_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_push) +#define sk_X509_EXTENSION_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_pop) +#define sk_X509_EXTENSION_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_dup) +#define sk_X509_EXTENSION_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_sort) +#define sk_X509_EXTENSION_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_is_sorted) +#define sk_X509_EXTENSION_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_set_cmp_func) +#define sk_X509_EXTENSION_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_EXTENSION_deep_copy) +#define sk_X509_ATTRIBUTE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_call_free_func) +#define sk_X509_ATTRIBUTE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_call_copy_func) +#define sk_X509_ATTRIBUTE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_call_cmp_func) +#define sk_X509_ATTRIBUTE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_new) +#define sk_X509_ATTRIBUTE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_new_null) +#define sk_X509_ATTRIBUTE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_num) +#define sk_X509_ATTRIBUTE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_zero) +#define sk_X509_ATTRIBUTE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_value) +#define sk_X509_ATTRIBUTE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_set) +#define sk_X509_ATTRIBUTE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_free) +#define sk_X509_ATTRIBUTE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_pop_free) +#define sk_X509_ATTRIBUTE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_insert) +#define sk_X509_ATTRIBUTE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_delete) +#define sk_X509_ATTRIBUTE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_delete_ptr) +#define sk_X509_ATTRIBUTE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_find) +#define sk_X509_ATTRIBUTE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_shift) +#define sk_X509_ATTRIBUTE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_push) +#define sk_X509_ATTRIBUTE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_pop) +#define sk_X509_ATTRIBUTE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_dup) +#define sk_X509_ATTRIBUTE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_sort) +#define sk_X509_ATTRIBUTE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_is_sorted) +#define sk_X509_ATTRIBUTE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_set_cmp_func) +#define sk_X509_ATTRIBUTE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_ATTRIBUTE_deep_copy) +#define sk_X509_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_free_func) +#define sk_X509_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_copy_func) +#define sk_X509_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_call_cmp_func) +#define sk_X509_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_new) +#define sk_X509_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_new_null) +#define sk_X509_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_num) +#define sk_X509_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_zero) +#define sk_X509_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_value) +#define sk_X509_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_set) +#define sk_X509_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_free) +#define sk_X509_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_pop_free) +#define sk_X509_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_insert) +#define sk_X509_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_delete) +#define sk_X509_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_delete_ptr) +#define sk_X509_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_find) +#define sk_X509_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_shift) +#define sk_X509_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_push) +#define sk_X509_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_pop) +#define sk_X509_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_dup) +#define sk_X509_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_sort) +#define sk_X509_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_is_sorted) +#define sk_X509_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_set_cmp_func) +#define sk_X509_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_deep_copy) +#define sk_X509_TRUST_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_call_free_func) +#define sk_X509_TRUST_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_call_copy_func) +#define sk_X509_TRUST_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_call_cmp_func) +#define sk_X509_TRUST_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_new) +#define sk_X509_TRUST_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_new_null) +#define sk_X509_TRUST_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_num) +#define sk_X509_TRUST_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_zero) +#define sk_X509_TRUST_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_value) +#define sk_X509_TRUST_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_set) +#define sk_X509_TRUST_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_free) +#define sk_X509_TRUST_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_pop_free) +#define sk_X509_TRUST_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_insert) +#define sk_X509_TRUST_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_delete) +#define sk_X509_TRUST_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_delete_ptr) +#define sk_X509_TRUST_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_find) +#define sk_X509_TRUST_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_shift) +#define sk_X509_TRUST_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_push) +#define sk_X509_TRUST_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_pop) +#define sk_X509_TRUST_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_dup) +#define sk_X509_TRUST_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_sort) +#define sk_X509_TRUST_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_is_sorted) +#define sk_X509_TRUST_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_set_cmp_func) +#define sk_X509_TRUST_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_TRUST_deep_copy) +#define sk_X509_REVOKED_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_call_free_func) +#define sk_X509_REVOKED_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_call_copy_func) +#define sk_X509_REVOKED_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_call_cmp_func) +#define sk_X509_REVOKED_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_new) +#define sk_X509_REVOKED_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_new_null) +#define sk_X509_REVOKED_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_num) +#define sk_X509_REVOKED_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_zero) +#define sk_X509_REVOKED_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_value) +#define sk_X509_REVOKED_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_set) +#define sk_X509_REVOKED_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_free) +#define sk_X509_REVOKED_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_pop_free) +#define sk_X509_REVOKED_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_insert) +#define sk_X509_REVOKED_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_delete) +#define sk_X509_REVOKED_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_delete_ptr) +#define sk_X509_REVOKED_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_find) +#define sk_X509_REVOKED_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_shift) +#define sk_X509_REVOKED_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_push) +#define sk_X509_REVOKED_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_pop) +#define sk_X509_REVOKED_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_dup) +#define sk_X509_REVOKED_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_sort) +#define sk_X509_REVOKED_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_is_sorted) +#define sk_X509_REVOKED_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_set_cmp_func) +#define sk_X509_REVOKED_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_REVOKED_deep_copy) +#define sk_X509_CRL_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_call_free_func) +#define sk_X509_CRL_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_call_copy_func) +#define sk_X509_CRL_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_call_cmp_func) +#define sk_X509_CRL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_new) +#define sk_X509_CRL_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_new_null) +#define sk_X509_CRL_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_num) +#define sk_X509_CRL_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_zero) +#define sk_X509_CRL_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_value) +#define sk_X509_CRL_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_set) +#define sk_X509_CRL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_free) +#define sk_X509_CRL_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_pop_free) +#define sk_X509_CRL_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_insert) +#define sk_X509_CRL_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_delete) +#define sk_X509_CRL_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_delete_ptr) +#define sk_X509_CRL_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_find) +#define sk_X509_CRL_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_shift) +#define sk_X509_CRL_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_push) +#define sk_X509_CRL_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_pop) +#define sk_X509_CRL_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_dup) +#define sk_X509_CRL_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_sort) +#define sk_X509_CRL_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_is_sorted) +#define sk_X509_CRL_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_set_cmp_func) +#define sk_X509_CRL_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_CRL_deep_copy) +#define sk_X509_INFO_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_call_free_func) +#define sk_X509_INFO_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_call_copy_func) +#define sk_X509_INFO_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_call_cmp_func) +#define sk_X509_INFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_new) +#define sk_X509_INFO_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_new_null) +#define sk_X509_INFO_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_num) +#define sk_X509_INFO_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_zero) +#define sk_X509_INFO_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_value) +#define sk_X509_INFO_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_set) +#define sk_X509_INFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_free) +#define sk_X509_INFO_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_pop_free) +#define sk_X509_INFO_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_insert) +#define sk_X509_INFO_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_delete) +#define sk_X509_INFO_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_delete_ptr) +#define sk_X509_INFO_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_find) +#define sk_X509_INFO_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_shift) +#define sk_X509_INFO_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_push) +#define sk_X509_INFO_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_pop) +#define sk_X509_INFO_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_dup) +#define sk_X509_INFO_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_sort) +#define sk_X509_INFO_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_is_sorted) +#define sk_X509_INFO_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_set_cmp_func) +#define sk_X509_INFO_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_INFO_deep_copy) +#define sk_X509_LOOKUP_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_call_free_func) +#define sk_X509_LOOKUP_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_call_copy_func) +#define sk_X509_LOOKUP_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_call_cmp_func) +#define sk_X509_LOOKUP_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_new) +#define sk_X509_LOOKUP_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_new_null) +#define sk_X509_LOOKUP_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_num) +#define sk_X509_LOOKUP_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_zero) +#define sk_X509_LOOKUP_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_value) +#define sk_X509_LOOKUP_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_set) +#define sk_X509_LOOKUP_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_free) +#define sk_X509_LOOKUP_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_pop_free) +#define sk_X509_LOOKUP_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_insert) +#define sk_X509_LOOKUP_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_delete) +#define sk_X509_LOOKUP_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_delete_ptr) +#define sk_X509_LOOKUP_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_find) +#define sk_X509_LOOKUP_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_shift) +#define sk_X509_LOOKUP_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_push) +#define sk_X509_LOOKUP_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_pop) +#define sk_X509_LOOKUP_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_dup) +#define sk_X509_LOOKUP_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_sort) +#define sk_X509_LOOKUP_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_is_sorted) +#define sk_X509_LOOKUP_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_set_cmp_func) +#define sk_X509_LOOKUP_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_LOOKUP_deep_copy) +#define sk_X509_OBJECT_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_call_free_func) +#define sk_X509_OBJECT_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_call_copy_func) +#define sk_X509_OBJECT_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_call_cmp_func) +#define sk_X509_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_new) +#define sk_X509_OBJECT_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_new_null) +#define sk_X509_OBJECT_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_num) +#define sk_X509_OBJECT_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_zero) +#define sk_X509_OBJECT_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_value) +#define sk_X509_OBJECT_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_set) +#define sk_X509_OBJECT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_free) +#define sk_X509_OBJECT_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_pop_free) +#define sk_X509_OBJECT_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_insert) +#define sk_X509_OBJECT_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_delete) +#define sk_X509_OBJECT_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_delete_ptr) +#define sk_X509_OBJECT_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_find) +#define sk_X509_OBJECT_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_shift) +#define sk_X509_OBJECT_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_push) +#define sk_X509_OBJECT_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_pop) +#define sk_X509_OBJECT_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_dup) +#define sk_X509_OBJECT_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_sort) +#define sk_X509_OBJECT_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_is_sorted) +#define sk_X509_OBJECT_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_set_cmp_func) +#define sk_X509_OBJECT_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_OBJECT_deep_copy) +#define sk_X509_VERIFY_PARAM_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_call_free_func) +#define sk_X509_VERIFY_PARAM_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_call_copy_func) +#define sk_X509_VERIFY_PARAM_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_call_cmp_func) +#define sk_X509_VERIFY_PARAM_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_new) +#define sk_X509_VERIFY_PARAM_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_new_null) +#define sk_X509_VERIFY_PARAM_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_num) +#define sk_X509_VERIFY_PARAM_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_zero) +#define sk_X509_VERIFY_PARAM_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_value) +#define sk_X509_VERIFY_PARAM_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_set) +#define sk_X509_VERIFY_PARAM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_free) +#define sk_X509_VERIFY_PARAM_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_pop_free) +#define sk_X509_VERIFY_PARAM_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_insert) +#define sk_X509_VERIFY_PARAM_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_delete) +#define sk_X509_VERIFY_PARAM_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_delete_ptr) +#define sk_X509_VERIFY_PARAM_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_find) +#define sk_X509_VERIFY_PARAM_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_shift) +#define sk_X509_VERIFY_PARAM_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_push) +#define sk_X509_VERIFY_PARAM_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_pop) +#define sk_X509_VERIFY_PARAM_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_dup) +#define sk_X509_VERIFY_PARAM_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_sort) +#define sk_X509_VERIFY_PARAM_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_is_sorted) +#define sk_X509_VERIFY_PARAM_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_set_cmp_func) +#define sk_X509_VERIFY_PARAM_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_VERIFY_PARAM_deep_copy) +#define sk_CRYPTO_BUFFER_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_free_func) +#define sk_CRYPTO_BUFFER_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_copy_func) +#define sk_CRYPTO_BUFFER_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_cmp_func) +#define sk_CRYPTO_BUFFER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_new) +#define sk_CRYPTO_BUFFER_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_new_null) +#define sk_CRYPTO_BUFFER_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_num) +#define sk_CRYPTO_BUFFER_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_zero) +#define sk_CRYPTO_BUFFER_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_value) +#define sk_CRYPTO_BUFFER_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_set) +#define sk_CRYPTO_BUFFER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_free) +#define sk_CRYPTO_BUFFER_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_pop_free) +#define sk_CRYPTO_BUFFER_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_insert) +#define sk_CRYPTO_BUFFER_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_delete) +#define sk_CRYPTO_BUFFER_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_delete_ptr) +#define sk_CRYPTO_BUFFER_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_find) +#define sk_CRYPTO_BUFFER_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_shift) +#define sk_CRYPTO_BUFFER_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_push) +#define sk_CRYPTO_BUFFER_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_pop) +#define sk_CRYPTO_BUFFER_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_dup) +#define sk_CRYPTO_BUFFER_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_sort) +#define sk_CRYPTO_BUFFER_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_is_sorted) +#define sk_CRYPTO_BUFFER_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_set_cmp_func) +#define sk_CRYPTO_BUFFER_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_deep_copy) +#define sk_ASN1_INTEGER_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_call_free_func) +#define sk_ASN1_INTEGER_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_call_copy_func) +#define sk_ASN1_INTEGER_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_call_cmp_func) +#define sk_ASN1_INTEGER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_new) +#define sk_ASN1_INTEGER_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_new_null) +#define sk_ASN1_INTEGER_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_num) +#define sk_ASN1_INTEGER_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_zero) +#define sk_ASN1_INTEGER_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_value) +#define sk_ASN1_INTEGER_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_set) +#define sk_ASN1_INTEGER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_free) +#define sk_ASN1_INTEGER_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_pop_free) +#define sk_ASN1_INTEGER_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_insert) +#define sk_ASN1_INTEGER_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_delete) +#define sk_ASN1_INTEGER_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_delete_ptr) +#define sk_ASN1_INTEGER_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_find) +#define sk_ASN1_INTEGER_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_shift) +#define sk_ASN1_INTEGER_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_push) +#define sk_ASN1_INTEGER_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_pop) +#define sk_ASN1_INTEGER_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_dup) +#define sk_ASN1_INTEGER_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_sort) +#define sk_ASN1_INTEGER_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_is_sorted) +#define sk_ASN1_INTEGER_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_set_cmp_func) +#define sk_ASN1_INTEGER_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_INTEGER_deep_copy) +#define sk_ASN1_OBJECT_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_call_free_func) +#define sk_ASN1_OBJECT_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_call_copy_func) +#define sk_ASN1_OBJECT_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_call_cmp_func) +#define sk_ASN1_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_new) +#define sk_ASN1_OBJECT_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_new_null) +#define sk_ASN1_OBJECT_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_num) +#define sk_ASN1_OBJECT_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_zero) +#define sk_ASN1_OBJECT_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_value) +#define sk_ASN1_OBJECT_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_set) +#define sk_ASN1_OBJECT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_free) +#define sk_ASN1_OBJECT_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_pop_free) +#define sk_ASN1_OBJECT_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_insert) +#define sk_ASN1_OBJECT_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_delete) +#define sk_ASN1_OBJECT_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_delete_ptr) +#define sk_ASN1_OBJECT_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_find) +#define sk_ASN1_OBJECT_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_shift) +#define sk_ASN1_OBJECT_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_push) +#define sk_ASN1_OBJECT_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_pop) +#define sk_ASN1_OBJECT_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_dup) +#define sk_ASN1_OBJECT_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_sort) +#define sk_ASN1_OBJECT_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_is_sorted) +#define sk_ASN1_OBJECT_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_set_cmp_func) +#define sk_ASN1_OBJECT_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_OBJECT_deep_copy) +#define sk_ASN1_TYPE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_call_free_func) +#define sk_ASN1_TYPE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_call_copy_func) +#define sk_ASN1_TYPE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_call_cmp_func) +#define sk_ASN1_TYPE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_new) +#define sk_ASN1_TYPE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_new_null) +#define sk_ASN1_TYPE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_num) +#define sk_ASN1_TYPE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_zero) +#define sk_ASN1_TYPE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_value) +#define sk_ASN1_TYPE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_set) +#define sk_ASN1_TYPE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_free) +#define sk_ASN1_TYPE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_pop_free) +#define sk_ASN1_TYPE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_insert) +#define sk_ASN1_TYPE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_delete) +#define sk_ASN1_TYPE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_delete_ptr) +#define sk_ASN1_TYPE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_find) +#define sk_ASN1_TYPE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_shift) +#define sk_ASN1_TYPE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_push) +#define sk_ASN1_TYPE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_pop) +#define sk_ASN1_TYPE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_dup) +#define sk_ASN1_TYPE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_sort) +#define sk_ASN1_TYPE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_is_sorted) +#define sk_ASN1_TYPE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_set_cmp_func) +#define sk_ASN1_TYPE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_TYPE_deep_copy) +#define sk_BIO_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_call_free_func) +#define sk_BIO_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_call_copy_func) +#define sk_BIO_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_call_cmp_func) +#define sk_BIO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_new) +#define sk_BIO_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_new_null) +#define sk_BIO_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_num) +#define sk_BIO_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_zero) +#define sk_BIO_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_value) +#define sk_BIO_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_set) +#define sk_BIO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_free) +#define sk_BIO_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_pop_free) +#define sk_BIO_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_insert) +#define sk_BIO_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_delete) +#define sk_BIO_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_delete_ptr) +#define sk_BIO_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_find) +#define sk_BIO_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_shift) +#define sk_BIO_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_push) +#define sk_BIO_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_pop) +#define sk_BIO_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_dup) +#define sk_BIO_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_sort) +#define sk_BIO_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_is_sorted) +#define sk_BIO_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_set_cmp_func) +#define sk_BIO_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_BIO_deep_copy) +#define sk_X509V3_EXT_METHOD_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_call_free_func) +#define sk_X509V3_EXT_METHOD_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_call_copy_func) +#define sk_X509V3_EXT_METHOD_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_call_cmp_func) +#define sk_X509V3_EXT_METHOD_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_new) +#define sk_X509V3_EXT_METHOD_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_new_null) +#define sk_X509V3_EXT_METHOD_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_num) +#define sk_X509V3_EXT_METHOD_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_zero) +#define sk_X509V3_EXT_METHOD_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_value) +#define sk_X509V3_EXT_METHOD_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_set) +#define sk_X509V3_EXT_METHOD_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_free) +#define sk_X509V3_EXT_METHOD_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_pop_free) +#define sk_X509V3_EXT_METHOD_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_insert) +#define sk_X509V3_EXT_METHOD_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_delete) +#define sk_X509V3_EXT_METHOD_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_delete_ptr) +#define sk_X509V3_EXT_METHOD_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_find) +#define sk_X509V3_EXT_METHOD_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_shift) +#define sk_X509V3_EXT_METHOD_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_push) +#define sk_X509V3_EXT_METHOD_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_pop) +#define sk_X509V3_EXT_METHOD_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_dup) +#define sk_X509V3_EXT_METHOD_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_sort) +#define sk_X509V3_EXT_METHOD_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_is_sorted) +#define sk_X509V3_EXT_METHOD_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_set_cmp_func) +#define sk_X509V3_EXT_METHOD_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509V3_EXT_METHOD_deep_copy) +#define sk_GENERAL_NAME_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_call_free_func) +#define sk_GENERAL_NAME_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_call_copy_func) +#define sk_GENERAL_NAME_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_call_cmp_func) +#define sk_GENERAL_NAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_new) +#define sk_GENERAL_NAME_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_new_null) +#define sk_GENERAL_NAME_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_num) +#define sk_GENERAL_NAME_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_zero) +#define sk_GENERAL_NAME_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_value) +#define sk_GENERAL_NAME_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_set) +#define sk_GENERAL_NAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_free) +#define sk_GENERAL_NAME_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_pop_free) +#define sk_GENERAL_NAME_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_insert) +#define sk_GENERAL_NAME_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_delete) +#define sk_GENERAL_NAME_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_delete_ptr) +#define sk_GENERAL_NAME_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_find) +#define sk_GENERAL_NAME_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_shift) +#define sk_GENERAL_NAME_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_push) +#define sk_GENERAL_NAME_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_pop) +#define sk_GENERAL_NAME_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_dup) +#define sk_GENERAL_NAME_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_sort) +#define sk_GENERAL_NAME_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_is_sorted) +#define sk_GENERAL_NAME_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_set_cmp_func) +#define sk_GENERAL_NAME_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAME_deep_copy) +#define sk_GENERAL_NAMES_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_call_free_func) +#define sk_GENERAL_NAMES_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_call_copy_func) +#define sk_GENERAL_NAMES_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_call_cmp_func) +#define sk_GENERAL_NAMES_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_new) +#define sk_GENERAL_NAMES_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_new_null) +#define sk_GENERAL_NAMES_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_num) +#define sk_GENERAL_NAMES_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_zero) +#define sk_GENERAL_NAMES_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_value) +#define sk_GENERAL_NAMES_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_set) +#define sk_GENERAL_NAMES_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_free) +#define sk_GENERAL_NAMES_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_pop_free) +#define sk_GENERAL_NAMES_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_insert) +#define sk_GENERAL_NAMES_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_delete) +#define sk_GENERAL_NAMES_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_delete_ptr) +#define sk_GENERAL_NAMES_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_find) +#define sk_GENERAL_NAMES_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_shift) +#define sk_GENERAL_NAMES_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_push) +#define sk_GENERAL_NAMES_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_pop) +#define sk_GENERAL_NAMES_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_dup) +#define sk_GENERAL_NAMES_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_sort) +#define sk_GENERAL_NAMES_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_is_sorted) +#define sk_GENERAL_NAMES_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_set_cmp_func) +#define sk_GENERAL_NAMES_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_NAMES_deep_copy) +#define sk_ACCESS_DESCRIPTION_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_call_free_func) +#define sk_ACCESS_DESCRIPTION_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_call_copy_func) +#define sk_ACCESS_DESCRIPTION_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_call_cmp_func) +#define sk_ACCESS_DESCRIPTION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_new) +#define sk_ACCESS_DESCRIPTION_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_new_null) +#define sk_ACCESS_DESCRIPTION_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_num) +#define sk_ACCESS_DESCRIPTION_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_zero) +#define sk_ACCESS_DESCRIPTION_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_value) +#define sk_ACCESS_DESCRIPTION_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_set) +#define sk_ACCESS_DESCRIPTION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_free) +#define sk_ACCESS_DESCRIPTION_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_pop_free) +#define sk_ACCESS_DESCRIPTION_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_insert) +#define sk_ACCESS_DESCRIPTION_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_delete) +#define sk_ACCESS_DESCRIPTION_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_delete_ptr) +#define sk_ACCESS_DESCRIPTION_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_find) +#define sk_ACCESS_DESCRIPTION_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_shift) +#define sk_ACCESS_DESCRIPTION_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_push) +#define sk_ACCESS_DESCRIPTION_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_pop) +#define sk_ACCESS_DESCRIPTION_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_dup) +#define sk_ACCESS_DESCRIPTION_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_sort) +#define sk_ACCESS_DESCRIPTION_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_is_sorted) +#define sk_ACCESS_DESCRIPTION_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_set_cmp_func) +#define sk_ACCESS_DESCRIPTION_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ACCESS_DESCRIPTION_deep_copy) +#define sk_DIST_POINT_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_call_free_func) +#define sk_DIST_POINT_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_call_copy_func) +#define sk_DIST_POINT_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_call_cmp_func) +#define sk_DIST_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_new) +#define sk_DIST_POINT_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_new_null) +#define sk_DIST_POINT_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_num) +#define sk_DIST_POINT_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_zero) +#define sk_DIST_POINT_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_value) +#define sk_DIST_POINT_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_set) +#define sk_DIST_POINT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_free) +#define sk_DIST_POINT_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_pop_free) +#define sk_DIST_POINT_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_insert) +#define sk_DIST_POINT_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_delete) +#define sk_DIST_POINT_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_delete_ptr) +#define sk_DIST_POINT_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_find) +#define sk_DIST_POINT_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_shift) +#define sk_DIST_POINT_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_push) +#define sk_DIST_POINT_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_pop) +#define sk_DIST_POINT_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_dup) +#define sk_DIST_POINT_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_sort) +#define sk_DIST_POINT_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_is_sorted) +#define sk_DIST_POINT_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_set_cmp_func) +#define sk_DIST_POINT_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_DIST_POINT_deep_copy) +#define sk_POLICYQUALINFO_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_call_free_func) +#define sk_POLICYQUALINFO_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_call_copy_func) +#define sk_POLICYQUALINFO_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_call_cmp_func) +#define sk_POLICYQUALINFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_new) +#define sk_POLICYQUALINFO_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_new_null) +#define sk_POLICYQUALINFO_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_num) +#define sk_POLICYQUALINFO_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_zero) +#define sk_POLICYQUALINFO_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_value) +#define sk_POLICYQUALINFO_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_set) +#define sk_POLICYQUALINFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_free) +#define sk_POLICYQUALINFO_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_pop_free) +#define sk_POLICYQUALINFO_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_insert) +#define sk_POLICYQUALINFO_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_delete) +#define sk_POLICYQUALINFO_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_delete_ptr) +#define sk_POLICYQUALINFO_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_find) +#define sk_POLICYQUALINFO_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_shift) +#define sk_POLICYQUALINFO_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_push) +#define sk_POLICYQUALINFO_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_pop) +#define sk_POLICYQUALINFO_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_dup) +#define sk_POLICYQUALINFO_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_sort) +#define sk_POLICYQUALINFO_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_is_sorted) +#define sk_POLICYQUALINFO_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_set_cmp_func) +#define sk_POLICYQUALINFO_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYQUALINFO_deep_copy) +#define sk_POLICYINFO_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_call_free_func) +#define sk_POLICYINFO_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_call_copy_func) +#define sk_POLICYINFO_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_call_cmp_func) +#define sk_POLICYINFO_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_new) +#define sk_POLICYINFO_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_new_null) +#define sk_POLICYINFO_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_num) +#define sk_POLICYINFO_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_zero) +#define sk_POLICYINFO_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_value) +#define sk_POLICYINFO_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_set) +#define sk_POLICYINFO_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_free) +#define sk_POLICYINFO_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_pop_free) +#define sk_POLICYINFO_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_insert) +#define sk_POLICYINFO_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_delete) +#define sk_POLICYINFO_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_delete_ptr) +#define sk_POLICYINFO_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_find) +#define sk_POLICYINFO_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_shift) +#define sk_POLICYINFO_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_push) +#define sk_POLICYINFO_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_pop) +#define sk_POLICYINFO_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_dup) +#define sk_POLICYINFO_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_sort) +#define sk_POLICYINFO_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_is_sorted) +#define sk_POLICYINFO_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_set_cmp_func) +#define sk_POLICYINFO_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICYINFO_deep_copy) +#define sk_POLICY_MAPPING_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_call_free_func) +#define sk_POLICY_MAPPING_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_call_copy_func) +#define sk_POLICY_MAPPING_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_call_cmp_func) +#define sk_POLICY_MAPPING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_new) +#define sk_POLICY_MAPPING_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_new_null) +#define sk_POLICY_MAPPING_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_num) +#define sk_POLICY_MAPPING_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_zero) +#define sk_POLICY_MAPPING_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_value) +#define sk_POLICY_MAPPING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_set) +#define sk_POLICY_MAPPING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_free) +#define sk_POLICY_MAPPING_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_pop_free) +#define sk_POLICY_MAPPING_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_insert) +#define sk_POLICY_MAPPING_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_delete) +#define sk_POLICY_MAPPING_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_delete_ptr) +#define sk_POLICY_MAPPING_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_find) +#define sk_POLICY_MAPPING_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_shift) +#define sk_POLICY_MAPPING_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_push) +#define sk_POLICY_MAPPING_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_pop) +#define sk_POLICY_MAPPING_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_dup) +#define sk_POLICY_MAPPING_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_sort) +#define sk_POLICY_MAPPING_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_is_sorted) +#define sk_POLICY_MAPPING_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_set_cmp_func) +#define sk_POLICY_MAPPING_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_POLICY_MAPPING_deep_copy) +#define sk_GENERAL_SUBTREE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_call_free_func) +#define sk_GENERAL_SUBTREE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_call_copy_func) +#define sk_GENERAL_SUBTREE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_call_cmp_func) +#define sk_GENERAL_SUBTREE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_new) +#define sk_GENERAL_SUBTREE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_new_null) +#define sk_GENERAL_SUBTREE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_num) +#define sk_GENERAL_SUBTREE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_zero) +#define sk_GENERAL_SUBTREE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_value) +#define sk_GENERAL_SUBTREE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_set) +#define sk_GENERAL_SUBTREE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_free) +#define sk_GENERAL_SUBTREE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_pop_free) +#define sk_GENERAL_SUBTREE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_insert) +#define sk_GENERAL_SUBTREE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_delete) +#define sk_GENERAL_SUBTREE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_delete_ptr) +#define sk_GENERAL_SUBTREE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_find) +#define sk_GENERAL_SUBTREE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_shift) +#define sk_GENERAL_SUBTREE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_push) +#define sk_GENERAL_SUBTREE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_pop) +#define sk_GENERAL_SUBTREE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_dup) +#define sk_GENERAL_SUBTREE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_sort) +#define sk_GENERAL_SUBTREE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_is_sorted) +#define sk_GENERAL_SUBTREE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_set_cmp_func) +#define sk_GENERAL_SUBTREE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_GENERAL_SUBTREE_deep_copy) +#define sk_X509_PURPOSE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_call_free_func) +#define sk_X509_PURPOSE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_call_copy_func) +#define sk_X509_PURPOSE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_call_cmp_func) +#define sk_X509_PURPOSE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_new) +#define sk_X509_PURPOSE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_new_null) +#define sk_X509_PURPOSE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_num) +#define sk_X509_PURPOSE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_zero) +#define sk_X509_PURPOSE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_value) +#define sk_X509_PURPOSE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_set) +#define sk_X509_PURPOSE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_free) +#define sk_X509_PURPOSE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_pop_free) +#define sk_X509_PURPOSE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_insert) +#define sk_X509_PURPOSE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_delete) +#define sk_X509_PURPOSE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_delete_ptr) +#define sk_X509_PURPOSE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_find) +#define sk_X509_PURPOSE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_shift) +#define sk_X509_PURPOSE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_push) +#define sk_X509_PURPOSE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_pop) +#define sk_X509_PURPOSE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_dup) +#define sk_X509_PURPOSE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_sort) +#define sk_X509_PURPOSE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_is_sorted) +#define sk_X509_PURPOSE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_set_cmp_func) +#define sk_X509_PURPOSE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_PURPOSE_deep_copy) +#define sk_X509_POLICY_NODE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_free_func) +#define sk_X509_POLICY_NODE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_copy_func) +#define sk_X509_POLICY_NODE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_call_cmp_func) +#define sk_X509_POLICY_NODE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new) +#define sk_X509_POLICY_NODE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_new_null) +#define sk_X509_POLICY_NODE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_num) +#define sk_X509_POLICY_NODE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_zero) +#define sk_X509_POLICY_NODE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_value) +#define sk_X509_POLICY_NODE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set) +#define sk_X509_POLICY_NODE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_free) +#define sk_X509_POLICY_NODE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop_free) +#define sk_X509_POLICY_NODE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_insert) +#define sk_X509_POLICY_NODE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete) +#define sk_X509_POLICY_NODE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_delete_ptr) +#define sk_X509_POLICY_NODE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_find) +#define sk_X509_POLICY_NODE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_shift) +#define sk_X509_POLICY_NODE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_push) +#define sk_X509_POLICY_NODE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_pop) +#define sk_X509_POLICY_NODE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_dup) +#define sk_X509_POLICY_NODE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_sort) +#define sk_X509_POLICY_NODE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_is_sorted) +#define sk_X509_POLICY_NODE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_set_cmp_func) +#define sk_X509_POLICY_NODE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_X509_POLICY_NODE_deep_copy) +#define sk_CONF_VALUE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_call_free_func) +#define sk_CONF_VALUE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_call_copy_func) +#define sk_CONF_VALUE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_call_cmp_func) +#define sk_CONF_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_new) +#define sk_CONF_VALUE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_new_null) +#define sk_CONF_VALUE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_num) +#define sk_CONF_VALUE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_zero) +#define sk_CONF_VALUE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_value) +#define sk_CONF_VALUE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_set) +#define sk_CONF_VALUE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_free) +#define sk_CONF_VALUE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_pop_free) +#define sk_CONF_VALUE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_insert) +#define sk_CONF_VALUE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_delete) +#define sk_CONF_VALUE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_delete_ptr) +#define sk_CONF_VALUE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_find) +#define sk_CONF_VALUE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_shift) +#define sk_CONF_VALUE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_push) +#define sk_CONF_VALUE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_pop) +#define sk_CONF_VALUE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_dup) +#define sk_CONF_VALUE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_sort) +#define sk_CONF_VALUE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_is_sorted) +#define sk_CONF_VALUE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_set_cmp_func) +#define sk_CONF_VALUE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_CONF_VALUE_deep_copy) +#define sk_SSL_COMP_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_call_free_func) +#define sk_SSL_COMP_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_call_copy_func) +#define sk_SSL_COMP_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_call_cmp_func) +#define sk_SSL_COMP_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_new) +#define sk_SSL_COMP_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_new_null) +#define sk_SSL_COMP_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_num) +#define sk_SSL_COMP_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_zero) +#define sk_SSL_COMP_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_value) +#define sk_SSL_COMP_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_set) +#define sk_SSL_COMP_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_free) +#define sk_SSL_COMP_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_pop_free) +#define sk_SSL_COMP_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_insert) +#define sk_SSL_COMP_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_delete) +#define sk_SSL_COMP_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_delete_ptr) +#define sk_SSL_COMP_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_find) +#define sk_SSL_COMP_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_shift) +#define sk_SSL_COMP_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_push) +#define sk_SSL_COMP_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_pop) +#define sk_SSL_COMP_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_dup) +#define sk_SSL_COMP_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_sort) +#define sk_SSL_COMP_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_is_sorted) +#define sk_SSL_COMP_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_set_cmp_func) +#define sk_SSL_COMP_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_SSL_COMP_deep_copy) +#define sk_void_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_call_free_func) +#define sk_void_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_call_copy_func) +#define sk_void_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_call_cmp_func) +#define sk_void_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_new) +#define sk_void_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_new_null) +#define sk_void_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_num) +#define sk_void_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_zero) +#define sk_void_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_value) +#define sk_void_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_set) +#define sk_void_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_free) +#define sk_void_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_pop_free) +#define sk_void_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_insert) +#define sk_void_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_delete) +#define sk_void_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_delete_ptr) +#define sk_void_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_find) +#define sk_void_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_shift) +#define sk_void_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_push) +#define sk_void_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_pop) +#define sk_void_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_dup) +#define sk_void_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_sort) +#define sk_void_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_is_sorted) +#define sk_void_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_set_cmp_func) +#define sk_void_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_void_deep_copy) +#define sk_OPENSSL_STRING_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_call_free_func) +#define sk_OPENSSL_STRING_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_call_copy_func) +#define sk_OPENSSL_STRING_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_call_cmp_func) +#define sk_OPENSSL_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_new) +#define sk_OPENSSL_STRING_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_new_null) +#define sk_OPENSSL_STRING_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_num) +#define sk_OPENSSL_STRING_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_zero) +#define sk_OPENSSL_STRING_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_value) +#define sk_OPENSSL_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_set) +#define sk_OPENSSL_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_free) +#define sk_OPENSSL_STRING_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_pop_free) +#define sk_OPENSSL_STRING_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_insert) +#define sk_OPENSSL_STRING_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_delete) +#define sk_OPENSSL_STRING_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_delete_ptr) +#define sk_OPENSSL_STRING_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_find) +#define sk_OPENSSL_STRING_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_shift) +#define sk_OPENSSL_STRING_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_push) +#define sk_OPENSSL_STRING_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_pop) +#define sk_OPENSSL_STRING_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_dup) +#define sk_OPENSSL_STRING_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_sort) +#define sk_OPENSSL_STRING_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_is_sorted) +#define sk_OPENSSL_STRING_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_set_cmp_func) +#define sk_OPENSSL_STRING_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_OPENSSL_STRING_deep_copy) +#define sk_TRUST_TOKEN_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_call_free_func) +#define sk_TRUST_TOKEN_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_call_copy_func) +#define sk_TRUST_TOKEN_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_call_cmp_func) +#define sk_TRUST_TOKEN_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_new) +#define sk_TRUST_TOKEN_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_new_null) +#define sk_TRUST_TOKEN_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_num) +#define sk_TRUST_TOKEN_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_zero) +#define sk_TRUST_TOKEN_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_value) +#define sk_TRUST_TOKEN_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_set) +#define sk_TRUST_TOKEN_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_free) +#define sk_TRUST_TOKEN_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_pop_free) +#define sk_TRUST_TOKEN_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_insert) +#define sk_TRUST_TOKEN_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_delete) +#define sk_TRUST_TOKEN_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_delete_ptr) +#define sk_TRUST_TOKEN_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_find) +#define sk_TRUST_TOKEN_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_shift) +#define sk_TRUST_TOKEN_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_push) +#define sk_TRUST_TOKEN_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_pop) +#define sk_TRUST_TOKEN_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_dup) +#define sk_TRUST_TOKEN_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_sort) +#define sk_TRUST_TOKEN_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_is_sorted) +#define sk_TRUST_TOKEN_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_set_cmp_func) +#define sk_TRUST_TOKEN_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_TRUST_TOKEN_deep_copy) +#define sk_ASN1_VALUE_call_free_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_call_free_func) +#define sk_ASN1_VALUE_call_copy_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_call_copy_func) +#define sk_ASN1_VALUE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_call_cmp_func) +#define sk_ASN1_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_new) +#define sk_ASN1_VALUE_new_null BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_new_null) +#define sk_ASN1_VALUE_num BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_num) +#define sk_ASN1_VALUE_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_zero) +#define sk_ASN1_VALUE_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_value) +#define sk_ASN1_VALUE_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_set) +#define sk_ASN1_VALUE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_free) +#define sk_ASN1_VALUE_pop_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_pop_free) +#define sk_ASN1_VALUE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_insert) +#define sk_ASN1_VALUE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_delete) +#define sk_ASN1_VALUE_delete_ptr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_delete_ptr) +#define sk_ASN1_VALUE_find BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_find) +#define sk_ASN1_VALUE_shift BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_shift) +#define sk_ASN1_VALUE_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_push) +#define sk_ASN1_VALUE_pop BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_pop) +#define sk_ASN1_VALUE_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_dup) +#define sk_ASN1_VALUE_sort BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_sort) +#define sk_ASN1_VALUE_is_sorted BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_is_sorted) +#define sk_ASN1_VALUE_set_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_set_cmp_func) +#define sk_ASN1_VALUE_deep_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_ASN1_VALUE_deep_copy) +#define lh_ASN1_STRING_TABLE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_call_cmp_func) +#define lh_ASN1_STRING_TABLE_call_hash_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_call_hash_func) +#define lh_ASN1_STRING_TABLE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_new) +#define lh_ASN1_STRING_TABLE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_free) +#define lh_ASN1_STRING_TABLE_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_num_items) +#define lh_ASN1_STRING_TABLE_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_retrieve) +#define lh_ASN1_STRING_TABLE_call_cmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_call_cmp_key) +#define lh_ASN1_STRING_TABLE_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_retrieve_key) +#define lh_ASN1_STRING_TABLE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_insert) +#define lh_ASN1_STRING_TABLE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_delete) +#define lh_ASN1_STRING_TABLE_call_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_call_doall) +#define lh_ASN1_STRING_TABLE_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_call_doall_arg) +#define lh_ASN1_STRING_TABLE_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_doall) +#define lh_ASN1_STRING_TABLE_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_STRING_TABLE_doall_arg) +#define lh_ASN1_OBJECT_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_call_cmp_func) +#define lh_ASN1_OBJECT_call_hash_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_call_hash_func) +#define lh_ASN1_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_new) +#define lh_ASN1_OBJECT_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_free) +#define lh_ASN1_OBJECT_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_num_items) +#define lh_ASN1_OBJECT_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_retrieve) +#define lh_ASN1_OBJECT_call_cmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_call_cmp_key) +#define lh_ASN1_OBJECT_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_retrieve_key) +#define lh_ASN1_OBJECT_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_insert) +#define lh_ASN1_OBJECT_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_delete) +#define lh_ASN1_OBJECT_call_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_call_doall) +#define lh_ASN1_OBJECT_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_call_doall_arg) +#define lh_ASN1_OBJECT_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_doall) +#define lh_ASN1_OBJECT_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_ASN1_OBJECT_doall_arg) +#define lh_CONF_VALUE_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_call_cmp_func) +#define lh_CONF_VALUE_call_hash_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_call_hash_func) +#define lh_CONF_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_new) +#define lh_CONF_VALUE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_free) +#define lh_CONF_VALUE_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_num_items) +#define lh_CONF_VALUE_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_retrieve) +#define lh_CONF_VALUE_call_cmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_call_cmp_key) +#define lh_CONF_VALUE_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_retrieve_key) +#define lh_CONF_VALUE_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_insert) +#define lh_CONF_VALUE_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_delete) +#define lh_CONF_VALUE_call_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_call_doall) +#define lh_CONF_VALUE_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_call_doall_arg) +#define lh_CONF_VALUE_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_doall) +#define lh_CONF_VALUE_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CONF_VALUE_doall_arg) +#define lh_CRYPTO_BUFFER_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_cmp_func) +#define lh_CRYPTO_BUFFER_call_hash_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_hash_func) +#define lh_CRYPTO_BUFFER_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_new) +#define lh_CRYPTO_BUFFER_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_free) +#define lh_CRYPTO_BUFFER_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_num_items) +#define lh_CRYPTO_BUFFER_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_retrieve) +#define lh_CRYPTO_BUFFER_call_cmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_cmp_key) +#define lh_CRYPTO_BUFFER_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_retrieve_key) +#define lh_CRYPTO_BUFFER_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_insert) +#define lh_CRYPTO_BUFFER_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_delete) +#define lh_CRYPTO_BUFFER_call_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_doall) +#define lh_CRYPTO_BUFFER_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_doall_arg) +#define lh_CRYPTO_BUFFER_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall) +#define lh_CRYPTO_BUFFER_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall_arg) +#define lh_SSL_SESSION_call_cmp_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_call_cmp_func) +#define lh_SSL_SESSION_call_hash_func BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_call_hash_func) +#define lh_SSL_SESSION_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_new) +#define lh_SSL_SESSION_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_free) +#define lh_SSL_SESSION_num_items BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_num_items) +#define lh_SSL_SESSION_retrieve BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_retrieve) +#define lh_SSL_SESSION_call_cmp_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_call_cmp_key) +#define lh_SSL_SESSION_retrieve_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_retrieve_key) +#define lh_SSL_SESSION_insert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_insert) +#define lh_SSL_SESSION_delete BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_delete) +#define lh_SSL_SESSION_call_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_call_doall) +#define lh_SSL_SESSION_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_call_doall_arg) +#define lh_SSL_SESSION_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_doall) +#define lh_SSL_SESSION_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_SSL_SESSION_doall_arg) +#define ssl_ctx_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ssl_ctx_st) +#define ssl_ech_keys_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ssl_ech_keys_st) +#define ssl_session_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ssl_session_st) +#define ssl_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ssl_st) diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h new file mode 100644 index 00000000..b07ecfaf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h @@ -0,0 +1,3467 @@ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#if !defined(__APPLE__) +#include "CNIOBoringSSL_boringssl_prefix_symbols.h" +#else +// On iOS and macOS, we need to treat assembly symbols differently from other +// symbols. The linker expects symbols to be prefixed with an underscore. +// Perlasm thus generates symbol with this underscore applied. Our macros must, +// in turn, incorporate it. +#define BORINGSSL_ADD_PREFIX_MAC_ASM(a, b) BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b) +#define BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b) _ ## a ## _ ## b + +#define _ACCESS_DESCRIPTION_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_free) +#define _ACCESS_DESCRIPTION_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_it) +#define _ACCESS_DESCRIPTION_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ACCESS_DESCRIPTION_new) +#define _AES_CMAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_CMAC) +#define _AES_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_cbc_encrypt) +#define _AES_cfb128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_cfb128_encrypt) +#define _AES_ctr128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_ctr128_encrypt) +#define _AES_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_decrypt) +#define _AES_ecb_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_ecb_encrypt) +#define _AES_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_encrypt) +#define _AES_ofb128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_ofb128_encrypt) +#define _AES_set_decrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_set_decrypt_key) +#define _AES_set_encrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_set_encrypt_key) +#define _AES_unwrap_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_unwrap_key) +#define _AES_unwrap_key_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_unwrap_key_padded) +#define _AES_wrap_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_wrap_key) +#define _AES_wrap_key_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AES_wrap_key_padded) +#define _ASN1_ANY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ANY_it) +#define _ASN1_BIT_STRING_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_check) +#define _ASN1_BIT_STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_free) +#define _ASN1_BIT_STRING_get_bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_get_bit) +#define _ASN1_BIT_STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_it) +#define _ASN1_BIT_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_new) +#define _ASN1_BIT_STRING_num_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_num_bytes) +#define _ASN1_BIT_STRING_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_set) +#define _ASN1_BIT_STRING_set_bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BIT_STRING_set_bit) +#define _ASN1_BMPSTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BMPSTRING_free) +#define _ASN1_BMPSTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BMPSTRING_it) +#define _ASN1_BMPSTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BMPSTRING_new) +#define _ASN1_BOOLEAN_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_BOOLEAN_it) +#define _ASN1_ENUMERATED_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_free) +#define _ASN1_ENUMERATED_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_get) +#define _ASN1_ENUMERATED_get_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_get_uint64) +#define _ASN1_ENUMERATED_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_it) +#define _ASN1_ENUMERATED_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_new) +#define _ASN1_ENUMERATED_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_set) +#define _ASN1_ENUMERATED_set_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_set_uint64) +#define _ASN1_ENUMERATED_to_BN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_ENUMERATED_to_BN) +#define _ASN1_FBOOLEAN_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_FBOOLEAN_it) +#define _ASN1_GENERALIZEDTIME_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_adj) +#define _ASN1_GENERALIZEDTIME_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_check) +#define _ASN1_GENERALIZEDTIME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_free) +#define _ASN1_GENERALIZEDTIME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_it) +#define _ASN1_GENERALIZEDTIME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_new) +#define _ASN1_GENERALIZEDTIME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_print) +#define _ASN1_GENERALIZEDTIME_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_set) +#define _ASN1_GENERALIZEDTIME_set_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALIZEDTIME_set_string) +#define _ASN1_GENERALSTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALSTRING_free) +#define _ASN1_GENERALSTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALSTRING_it) +#define _ASN1_GENERALSTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_GENERALSTRING_new) +#define _ASN1_IA5STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_IA5STRING_free) +#define _ASN1_IA5STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_IA5STRING_it) +#define _ASN1_IA5STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_IA5STRING_new) +#define _ASN1_INTEGER_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_cmp) +#define _ASN1_INTEGER_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_dup) +#define _ASN1_INTEGER_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_free) +#define _ASN1_INTEGER_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_get) +#define _ASN1_INTEGER_get_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_get_uint64) +#define _ASN1_INTEGER_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_it) +#define _ASN1_INTEGER_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_new) +#define _ASN1_INTEGER_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_set) +#define _ASN1_INTEGER_set_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_set_uint64) +#define _ASN1_INTEGER_to_BN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_INTEGER_to_BN) +#define _ASN1_NULL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_NULL_free) +#define _ASN1_NULL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_NULL_it) +#define _ASN1_NULL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_NULL_new) +#define _ASN1_OBJECT_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OBJECT_create) +#define _ASN1_OBJECT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OBJECT_free) +#define _ASN1_OBJECT_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OBJECT_it) +#define _ASN1_OBJECT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OBJECT_new) +#define _ASN1_OCTET_STRING_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_cmp) +#define _ASN1_OCTET_STRING_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_dup) +#define _ASN1_OCTET_STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_free) +#define _ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) +#define _ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) +#define _ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define _ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) +#define _ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) +#define _ASN1_PRINTABLESTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_new) +#define _ASN1_PRINTABLE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_free) +#define _ASN1_PRINTABLE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_it) +#define _ASN1_PRINTABLE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_new) +#define _ASN1_PRINTABLE_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLE_type) +#define _ASN1_SEQUENCE_ANY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_ANY_it) +#define _ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) +#define _ASN1_SET_ANY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SET_ANY_it) +#define _ASN1_STRING_TABLE_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_TABLE_add) +#define _ASN1_STRING_TABLE_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_TABLE_cleanup) +#define _ASN1_STRING_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_cmp) +#define _ASN1_STRING_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_copy) +#define _ASN1_STRING_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_data) +#define _ASN1_STRING_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_dup) +#define _ASN1_STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_free) +#define _ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define _ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) +#define _ASN1_STRING_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_length) +#define _ASN1_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_new) +#define _ASN1_STRING_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_print) +#define _ASN1_STRING_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_print_ex) +#define _ASN1_STRING_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_print_ex_fp) +#define _ASN1_STRING_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_set) +#define _ASN1_STRING_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_set0) +#define _ASN1_STRING_set_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_set_by_NID) +#define _ASN1_STRING_set_default_mask BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_set_default_mask) +#define _ASN1_STRING_set_default_mask_asc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_set_default_mask_asc) +#define _ASN1_STRING_to_UTF8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_to_UTF8) +#define _ASN1_STRING_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_type) +#define _ASN1_STRING_type_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_type_new) +#define _ASN1_T61STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_T61STRING_free) +#define _ASN1_T61STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_T61STRING_it) +#define _ASN1_T61STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_T61STRING_new) +#define _ASN1_TBOOLEAN_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TBOOLEAN_it) +#define _ASN1_TIME_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_adj) +#define _ASN1_TIME_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_check) +#define _ASN1_TIME_diff BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_diff) +#define _ASN1_TIME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_free) +#define _ASN1_TIME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_it) +#define _ASN1_TIME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_new) +#define _ASN1_TIME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_print) +#define _ASN1_TIME_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_set) +#define _ASN1_TIME_set_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_set_string) +#define _ASN1_TIME_to_generalizedtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TIME_to_generalizedtime) +#define _ASN1_TYPE_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_cmp) +#define _ASN1_TYPE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_free) +#define _ASN1_TYPE_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_get) +#define _ASN1_TYPE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_new) +#define _ASN1_TYPE_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_set) +#define _ASN1_TYPE_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_TYPE_set1) +#define _ASN1_UNIVERSALSTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_free) +#define _ASN1_UNIVERSALSTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_it) +#define _ASN1_UNIVERSALSTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UNIVERSALSTRING_new) +#define _ASN1_UTCTIME_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_adj) +#define _ASN1_UTCTIME_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_check) +#define _ASN1_UTCTIME_cmp_time_t BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_cmp_time_t) +#define _ASN1_UTCTIME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_free) +#define _ASN1_UTCTIME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_it) +#define _ASN1_UTCTIME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_new) +#define _ASN1_UTCTIME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_print) +#define _ASN1_UTCTIME_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_set) +#define _ASN1_UTCTIME_set_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTCTIME_set_string) +#define _ASN1_UTF8STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTF8STRING_free) +#define _ASN1_UTF8STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTF8STRING_it) +#define _ASN1_UTF8STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_UTF8STRING_new) +#define _ASN1_VISIBLESTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_free) +#define _ASN1_VISIBLESTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_it) +#define _ASN1_VISIBLESTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_VISIBLESTRING_new) +#define _ASN1_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_digest) +#define _ASN1_generate_v3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_generate_v3) +#define _ASN1_get_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_get_object) +#define _ASN1_item_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_d2i) +#define _ASN1_item_d2i_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_d2i_bio) +#define _ASN1_item_d2i_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_d2i_fp) +#define _ASN1_item_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_digest) +#define _ASN1_item_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_dup) +#define _ASN1_item_ex_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_ex_d2i) +#define _ASN1_item_ex_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_ex_free) +#define _ASN1_item_ex_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_ex_i2d) +#define _ASN1_item_ex_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_ex_new) +#define _ASN1_item_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_free) +#define _ASN1_item_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_i2d) +#define _ASN1_item_i2d_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_i2d_bio) +#define _ASN1_item_i2d_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_i2d_fp) +#define _ASN1_item_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_new) +#define _ASN1_item_pack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_pack) +#define _ASN1_item_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_sign) +#define _ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_sign_ctx) +#define _ASN1_item_unpack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_unpack) +#define _ASN1_item_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_verify) +#define _ASN1_mbstring_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_copy) +#define _ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) +#define _ASN1_object_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_object_size) +#define _ASN1_primitive_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_primitive_free) +#define _ASN1_put_eoc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_put_eoc) +#define _ASN1_put_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_put_object) +#define _ASN1_tag2bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_tag2bit) +#define _ASN1_tag2str BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_tag2str) +#define _ASN1_template_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_template_free) +#define _AUTHORITY_INFO_ACCESS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_free) +#define _AUTHORITY_INFO_ACCESS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_it) +#define _AUTHORITY_INFO_ACCESS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_INFO_ACCESS_new) +#define _AUTHORITY_KEYID_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_KEYID_free) +#define _AUTHORITY_KEYID_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_KEYID_it) +#define _AUTHORITY_KEYID_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, AUTHORITY_KEYID_new) +#define _BASIC_CONSTRAINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_free) +#define _BASIC_CONSTRAINTS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_it) +#define _BASIC_CONSTRAINTS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_new) +#define _BIO_append_filename BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_append_filename) +#define _BIO_callback_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_callback_ctrl) +#define _BIO_clear_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_clear_flags) +#define _BIO_clear_retry_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_clear_retry_flags) +#define _BIO_copy_next_retry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_copy_next_retry) +#define _BIO_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_ctrl) +#define _BIO_ctrl_get_read_request BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_ctrl_get_read_request) +#define _BIO_ctrl_get_write_guarantee BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_ctrl_get_write_guarantee) +#define _BIO_ctrl_pending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_ctrl_pending) +#define _BIO_do_connect BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_do_connect) +#define _BIO_eof BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_eof) +#define _BIO_f_ssl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_f_ssl) +#define _BIO_find_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_find_type) +#define _BIO_flush BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_flush) +#define _BIO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_free) +#define _BIO_free_all BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_free_all) +#define _BIO_get_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_data) +#define _BIO_get_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_fd) +#define _BIO_get_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_fp) +#define _BIO_get_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_init) +#define _BIO_get_mem_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_mem_data) +#define _BIO_get_mem_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_mem_ptr) +#define _BIO_get_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_new_index) +#define _BIO_get_retry_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_retry_flags) +#define _BIO_get_retry_reason BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_retry_reason) +#define _BIO_get_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_get_shutdown) +#define _BIO_gets BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_gets) +#define _BIO_hexdump BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_hexdump) +#define _BIO_indent BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_indent) +#define _BIO_int_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_int_ctrl) +#define _BIO_mem_contents BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_mem_contents) +#define _BIO_meth_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_free) +#define _BIO_meth_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_new) +#define _BIO_meth_set_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_create) +#define _BIO_meth_set_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_ctrl) +#define _BIO_meth_set_destroy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_destroy) +#define _BIO_meth_set_gets BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_gets) +#define _BIO_meth_set_puts BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_puts) +#define _BIO_meth_set_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_read) +#define _BIO_meth_set_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_meth_set_write) +#define _BIO_method_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_method_type) +#define _BIO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new) +#define _BIO_new_bio_pair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_bio_pair) +#define _BIO_new_connect BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_connect) +#define _BIO_new_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_fd) +#define _BIO_new_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_file) +#define _BIO_new_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_fp) +#define _BIO_new_mem_buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_mem_buf) +#define _BIO_new_socket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_new_socket) +#define _BIO_next BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_next) +#define _BIO_number_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_number_read) +#define _BIO_number_written BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_number_written) +#define _BIO_pending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_pending) +#define _BIO_pop BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_pop) +#define _BIO_printf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_printf) +#define _BIO_ptr_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_ptr_ctrl) +#define _BIO_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_push) +#define _BIO_puts BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_puts) +#define _BIO_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_read) +#define _BIO_read_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_read_asn1) +#define _BIO_read_filename BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_read_filename) +#define _BIO_reset BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_reset) +#define _BIO_rw_filename BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_rw_filename) +#define _BIO_s_connect BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_s_connect) +#define _BIO_s_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_s_fd) +#define _BIO_s_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_s_file) +#define _BIO_s_mem BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_s_mem) +#define _BIO_s_socket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_s_socket) +#define _BIO_seek BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_seek) +#define _BIO_set_close BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_close) +#define _BIO_set_conn_hostname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_conn_hostname) +#define _BIO_set_conn_int_port BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_conn_int_port) +#define _BIO_set_conn_port BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_conn_port) +#define _BIO_set_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_data) +#define _BIO_set_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_fd) +#define _BIO_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_flags) +#define _BIO_set_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_fp) +#define _BIO_set_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_init) +#define _BIO_set_mem_buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_mem_buf) +#define _BIO_set_mem_eof_return BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_mem_eof_return) +#define _BIO_set_nbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_nbio) +#define _BIO_set_retry_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_retry_read) +#define _BIO_set_retry_reason BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_retry_reason) +#define _BIO_set_retry_special BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_retry_special) +#define _BIO_set_retry_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_retry_write) +#define _BIO_set_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_shutdown) +#define _BIO_set_ssl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_ssl) +#define _BIO_set_write_buffer_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_set_write_buffer_size) +#define _BIO_should_io_special BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_should_io_special) +#define _BIO_should_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_should_read) +#define _BIO_should_retry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_should_retry) +#define _BIO_should_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_should_write) +#define _BIO_shutdown_wr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_shutdown_wr) +#define _BIO_snprintf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_snprintf) +#define _BIO_tell BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_tell) +#define _BIO_test_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_test_flags) +#define _BIO_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_up_ref) +#define _BIO_vfree BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_vfree) +#define _BIO_vsnprintf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_vsnprintf) +#define _BIO_wpending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_wpending) +#define _BIO_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_write) +#define _BIO_write_all BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_write_all) +#define _BIO_write_filename BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_write_filename) +#define _BLAKE2B256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BLAKE2B256) +#define _BLAKE2B256_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BLAKE2B256_Final) +#define _BLAKE2B256_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BLAKE2B256_Init) +#define _BLAKE2B256_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BLAKE2B256_Update) +#define _BN_BLINDING_convert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_BLINDING_convert) +#define _BN_BLINDING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_BLINDING_free) +#define _BN_BLINDING_invalidate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_BLINDING_invalidate) +#define _BN_BLINDING_invert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_BLINDING_invert) +#define _BN_BLINDING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_BLINDING_new) +#define _BN_CTX_end BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_CTX_end) +#define _BN_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_CTX_free) +#define _BN_CTX_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_CTX_get) +#define _BN_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_CTX_new) +#define _BN_CTX_start BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_CTX_start) +#define _BN_GENCB_call BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_GENCB_call) +#define _BN_GENCB_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_GENCB_free) +#define _BN_GENCB_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_GENCB_new) +#define _BN_GENCB_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_GENCB_set) +#define _BN_MONT_CTX_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_copy) +#define _BN_MONT_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_free) +#define _BN_MONT_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_new) +#define _BN_MONT_CTX_new_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_new_consttime) +#define _BN_MONT_CTX_new_for_modulus BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_new_for_modulus) +#define _BN_MONT_CTX_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_set) +#define _BN_MONT_CTX_set_locked BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_MONT_CTX_set_locked) +#define _BN_abs_is_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_abs_is_word) +#define _BN_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_add) +#define _BN_add_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_add_word) +#define _BN_asc2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_asc2bn) +#define _BN_bin2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bin2bn) +#define _BN_bn2bin BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2bin) +#define _BN_bn2bin_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2bin_padded) +#define _BN_bn2binpad BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2binpad) +#define _BN_bn2cbb_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2cbb_padded) +#define _BN_bn2dec BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2dec) +#define _BN_bn2hex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2hex) +#define _BN_bn2le_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2le_padded) +#define _BN_bn2mpi BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_bn2mpi) +#define _BN_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_clear) +#define _BN_clear_bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_clear_bit) +#define _BN_clear_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_clear_free) +#define _BN_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_cmp) +#define _BN_cmp_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_cmp_word) +#define _BN_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_copy) +#define _BN_count_low_zero_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_count_low_zero_bits) +#define _BN_dec2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_dec2bn) +#define _BN_div BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_div) +#define _BN_div_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_div_word) +#define _BN_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_dup) +#define _BN_enhanced_miller_rabin_primality_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_enhanced_miller_rabin_primality_test) +#define _BN_equal_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_equal_consttime) +#define _BN_exp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_exp) +#define _BN_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_free) +#define _BN_from_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_from_montgomery) +#define _BN_gcd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_gcd) +#define _BN_generate_prime_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_generate_prime_ex) +#define _BN_get_rfc3526_prime_1536 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_get_rfc3526_prime_1536) +#define _BN_get_u64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_get_u64) +#define _BN_get_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_get_word) +#define _BN_hex2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_hex2bn) +#define _BN_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_init) +#define _BN_is_bit_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_bit_set) +#define _BN_is_negative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_negative) +#define _BN_is_odd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_odd) +#define _BN_is_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_one) +#define _BN_is_pow2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_pow2) +#define _BN_is_prime_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_prime_ex) +#define _BN_is_prime_fasttest_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_prime_fasttest_ex) +#define _BN_is_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_word) +#define _BN_is_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_is_zero) +#define _BN_le2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_le2bn) +#define _BN_lshift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_lshift) +#define _BN_lshift1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_lshift1) +#define _BN_marshal_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_marshal_asn1) +#define _BN_mask_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mask_bits) +#define _BN_mod_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_add) +#define _BN_mod_add_quick BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_add_quick) +#define _BN_mod_exp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_exp) +#define _BN_mod_exp2_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_exp2_mont) +#define _BN_mod_exp_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_exp_mont) +#define _BN_mod_exp_mont_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_exp_mont_consttime) +#define _BN_mod_exp_mont_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_exp_mont_word) +#define _BN_mod_inverse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_inverse) +#define _BN_mod_inverse_blinded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_inverse_blinded) +#define _BN_mod_inverse_odd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_inverse_odd) +#define _BN_mod_lshift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_lshift) +#define _BN_mod_lshift1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_lshift1) +#define _BN_mod_lshift1_quick BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_lshift1_quick) +#define _BN_mod_lshift_quick BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_lshift_quick) +#define _BN_mod_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_mul) +#define _BN_mod_mul_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_mul_montgomery) +#define _BN_mod_pow2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_pow2) +#define _BN_mod_sqr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_sqr) +#define _BN_mod_sqrt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_sqrt) +#define _BN_mod_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_sub) +#define _BN_mod_sub_quick BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_sub_quick) +#define _BN_mod_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mod_word) +#define _BN_mpi2bn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mpi2bn) +#define _BN_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mul) +#define _BN_mul_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mul_word) +#define _BN_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_new) +#define _BN_nnmod BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_nnmod) +#define _BN_nnmod_pow2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_nnmod_pow2) +#define _BN_num_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_num_bits) +#define _BN_num_bits_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_num_bits_word) +#define _BN_num_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_num_bytes) +#define _BN_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_one) +#define _BN_parse_asn1_unsigned BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_parse_asn1_unsigned) +#define _BN_primality_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_primality_test) +#define _BN_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_print) +#define _BN_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_print_fp) +#define _BN_pseudo_rand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_pseudo_rand) +#define _BN_pseudo_rand_range BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_pseudo_rand_range) +#define _BN_rand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_rand) +#define _BN_rand_range BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_rand_range) +#define _BN_rand_range_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_rand_range_ex) +#define _BN_rshift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_rshift) +#define _BN_rshift1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_rshift1) +#define _BN_set_bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_set_bit) +#define _BN_set_negative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_set_negative) +#define _BN_set_u64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_set_u64) +#define _BN_set_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_set_word) +#define _BN_sqr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_sqr) +#define _BN_sqrt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_sqrt) +#define _BN_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_sub) +#define _BN_sub_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_sub_word) +#define _BN_to_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_to_ASN1_ENUMERATED) +#define _BN_to_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_to_ASN1_INTEGER) +#define _BN_to_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_to_montgomery) +#define _BN_uadd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_uadd) +#define _BN_ucmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_ucmp) +#define _BN_usub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_usub) +#define _BN_value_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_value_one) +#define _BN_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_zero) +#define _BORINGSSL_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BORINGSSL_self_test) +#define _BUF_MEM_append BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_append) +#define _BUF_MEM_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_free) +#define _BUF_MEM_grow BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_grow) +#define _BUF_MEM_grow_clean BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_grow_clean) +#define _BUF_MEM_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_new) +#define _BUF_MEM_reserve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_reserve) +#define _BUF_memdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_memdup) +#define _BUF_strdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_strdup) +#define _BUF_strlcat BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_strlcat) +#define _BUF_strlcpy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_strlcpy) +#define _BUF_strndup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_strndup) +#define _BUF_strnlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_strnlen) +#define _CBB_add_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1) +#define _CBB_add_asn1_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_bool) +#define _CBB_add_asn1_int64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_int64) +#define _CBB_add_asn1_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_octet_string) +#define _CBB_add_asn1_oid_from_text BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_oid_from_text) +#define _CBB_add_asn1_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_uint64) +#define _CBB_add_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_bytes) +#define _CBB_add_space BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_space) +#define _CBB_add_u16 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u16) +#define _CBB_add_u16_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u16_length_prefixed) +#define _CBB_add_u16le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u16le) +#define _CBB_add_u24 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u24) +#define _CBB_add_u24_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u24_length_prefixed) +#define _CBB_add_u32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u32) +#define _CBB_add_u32le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u32le) +#define _CBB_add_u64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u64) +#define _CBB_add_u64le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u64le) +#define _CBB_add_u8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u8) +#define _CBB_add_u8_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u8_length_prefixed) +#define _CBB_add_zeros BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_zeros) +#define _CBB_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_cleanup) +#define _CBB_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_data) +#define _CBB_did_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_did_write) +#define _CBB_discard_child BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_discard_child) +#define _CBB_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_finish) +#define _CBB_finish_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_finish_i2d) +#define _CBB_flush BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_flush) +#define _CBB_flush_asn1_set_of BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_flush_asn1_set_of) +#define _CBB_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_init) +#define _CBB_init_fixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_init_fixed) +#define _CBB_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_len) +#define _CBB_reserve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_reserve) +#define _CBB_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_zero) +#define _CBS_asn1_ber_to_der BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_asn1_ber_to_der) +#define _CBS_asn1_bitstring_has_bit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_asn1_bitstring_has_bit) +#define _CBS_asn1_oid_to_text BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_asn1_oid_to_text) +#define _CBS_contains_zero_byte BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_contains_zero_byte) +#define _CBS_copy_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_copy_bytes) +#define _CBS_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_data) +#define _CBS_get_any_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_any_asn1) +#define _CBS_get_any_asn1_element BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_any_asn1_element) +#define _CBS_get_any_ber_asn1_element BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_any_ber_asn1_element) +#define _CBS_get_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1) +#define _CBS_get_asn1_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1_bool) +#define _CBS_get_asn1_element BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1_element) +#define _CBS_get_asn1_implicit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1_implicit_string) +#define _CBS_get_asn1_int64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1_int64) +#define _CBS_get_asn1_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_asn1_uint64) +#define _CBS_get_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_bytes) +#define _CBS_get_last_u8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_last_u8) +#define _CBS_get_optional_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_optional_asn1) +#define _CBS_get_optional_asn1_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_optional_asn1_bool) +#define _CBS_get_optional_asn1_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_optional_asn1_octet_string) +#define _CBS_get_optional_asn1_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_optional_asn1_uint64) +#define _CBS_get_u16 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u16) +#define _CBS_get_u16_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u16_length_prefixed) +#define _CBS_get_u16le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u16le) +#define _CBS_get_u24 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u24) +#define _CBS_get_u24_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u24_length_prefixed) +#define _CBS_get_u32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u32) +#define _CBS_get_u32le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u32le) +#define _CBS_get_u64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u64) +#define _CBS_get_u64le BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u64le) +#define _CBS_get_u8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u8) +#define _CBS_get_u8_length_prefixed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_u8_length_prefixed) +#define _CBS_get_until_first BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_get_until_first) +#define _CBS_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_init) +#define _CBS_is_unsigned_asn1_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_unsigned_asn1_integer) +#define _CBS_is_valid_asn1_bitstring BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_valid_asn1_bitstring) +#define _CBS_is_valid_asn1_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_is_valid_asn1_integer) +#define _CBS_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_len) +#define _CBS_mem_equal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_mem_equal) +#define _CBS_peek_asn1_tag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_peek_asn1_tag) +#define _CBS_skip BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_skip) +#define _CBS_stow BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_stow) +#define _CBS_strdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBS_strdup) +#define _CERTIFICATEPOLICIES_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_free) +#define _CERTIFICATEPOLICIES_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_it) +#define _CERTIFICATEPOLICIES_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CERTIFICATEPOLICIES_new) +#define _CMAC_CTX_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_CTX_copy) +#define _CMAC_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_CTX_free) +#define _CMAC_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_CTX_new) +#define _CMAC_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_Final) +#define _CMAC_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_Init) +#define _CMAC_Reset BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_Reset) +#define _CMAC_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMAC_Update) +#define _CONF_VALUE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_VALUE_new) +#define _CONF_modules_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_free) +#define _CONF_modules_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_load_file) +#define _CONF_parse_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_parse_list) +#define _CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) +#define _CRL_DIST_POINTS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRL_DIST_POINTS_it) +#define _CRL_DIST_POINTS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRL_DIST_POINTS_new) +#define _CRYPTO_BUFFER_POOL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_POOL_free) +#define _CRYPTO_BUFFER_POOL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_POOL_new) +#define _CRYPTO_BUFFER_alloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_alloc) +#define _CRYPTO_BUFFER_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_data) +#define _CRYPTO_BUFFER_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_free) +#define _CRYPTO_BUFFER_init_CBS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_init_CBS) +#define _CRYPTO_BUFFER_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_len) +#define _CRYPTO_BUFFER_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_new) +#define _CRYPTO_BUFFER_new_from_CBS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_new_from_CBS) +#define _CRYPTO_BUFFER_new_from_static_data_unsafe BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_new_from_static_data_unsafe) +#define _CRYPTO_BUFFER_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_BUFFER_up_ref) +#define _CRYPTO_MUTEX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_cleanup) +#define _CRYPTO_MUTEX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_init) +#define _CRYPTO_MUTEX_lock_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_read) +#define _CRYPTO_MUTEX_lock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_write) +#define _CRYPTO_MUTEX_unlock_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_read) +#define _CRYPTO_MUTEX_unlock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_write) +#define _CRYPTO_POLYVAL_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_POLYVAL_finish) +#define _CRYPTO_POLYVAL_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_POLYVAL_init) +#define _CRYPTO_POLYVAL_update_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_POLYVAL_update_blocks) +#define _CRYPTO_STATIC_MUTEX_lock_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_lock_read) +#define _CRYPTO_STATIC_MUTEX_lock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_lock_write) +#define _CRYPTO_STATIC_MUTEX_unlock_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_unlock_read) +#define _CRYPTO_STATIC_MUTEX_unlock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_STATIC_MUTEX_unlock_write) +#define _CRYPTO_THREADID_current BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_THREADID_current) +#define _CRYPTO_THREADID_set_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_THREADID_set_callback) +#define _CRYPTO_THREADID_set_numeric BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_THREADID_set_numeric) +#define _CRYPTO_THREADID_set_pointer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_THREADID_set_pointer) +#define _CRYPTO_cbc128_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cbc128_decrypt) +#define _CRYPTO_cbc128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cbc128_encrypt) +#define _CRYPTO_cfb128_1_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cfb128_1_encrypt) +#define _CRYPTO_cfb128_8_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cfb128_8_encrypt) +#define _CRYPTO_cfb128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cfb128_encrypt) +#define _CRYPTO_chacha_20 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_chacha_20) +#define _CRYPTO_cleanup_all_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_cleanup_all_ex_data) +#define _CRYPTO_ctr128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt) +#define _CRYPTO_ctr128_encrypt_ctr32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ctr128_encrypt_ctr32) +#define _CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing) +#define _CRYPTO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_free) +#define _CRYPTO_free_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_free_ex_data) +#define _CRYPTO_gcm128_aad BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_aad) +#define _CRYPTO_gcm128_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_decrypt) +#define _CRYPTO_gcm128_decrypt_ctr32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_decrypt_ctr32) +#define _CRYPTO_gcm128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_encrypt) +#define _CRYPTO_gcm128_encrypt_ctr32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_encrypt_ctr32) +#define _CRYPTO_gcm128_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_finish) +#define _CRYPTO_gcm128_init_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_init_key) +#define _CRYPTO_gcm128_setiv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_setiv) +#define _CRYPTO_gcm128_tag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_gcm128_tag) +#define _CRYPTO_get_dynlock_create_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_dynlock_create_callback) +#define _CRYPTO_get_dynlock_destroy_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_dynlock_destroy_callback) +#define _CRYPTO_get_dynlock_lock_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_dynlock_lock_callback) +#define _CRYPTO_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_ex_data) +#define _CRYPTO_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_ex_new_index) +#define _CRYPTO_get_fork_generation BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_fork_generation) +#define _CRYPTO_get_lock_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_lock_name) +#define _CRYPTO_get_locking_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_locking_callback) +#define _CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_thread_local) +#define _CRYPTO_ghash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ghash_init) +#define _CRYPTO_has_asm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_has_asm) +#define _CRYPTO_hchacha20 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_hchacha20) +#define _CRYPTO_init_sysrand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_init_sysrand) +#define _CRYPTO_is_ARMv8_AES_capable_at_runtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_is_ARMv8_AES_capable_at_runtime) +#define _CRYPTO_is_ARMv8_PMULL_capable_at_runtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_is_ARMv8_PMULL_capable_at_runtime) +#define _CRYPTO_is_NEON_capable_at_runtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_is_NEON_capable_at_runtime) +#define _CRYPTO_is_confidential_build BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_is_confidential_build) +#define _CRYPTO_library_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_library_init) +#define _CRYPTO_malloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_malloc) +#define _CRYPTO_malloc_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_malloc_init) +#define _CRYPTO_memcmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_memcmp) +#define _CRYPTO_new_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_new_ex_data) +#define _CRYPTO_num_locks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_num_locks) +#define _CRYPTO_ofb128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ofb128_encrypt) +#define _CRYPTO_once BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_once) +#define _CRYPTO_poly1305_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_finish) +#define _CRYPTO_poly1305_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_init) +#define _CRYPTO_poly1305_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_update) +#define _CRYPTO_pre_sandbox_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_pre_sandbox_init) +#define _CRYPTO_rdrand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_rdrand) +#define _CRYPTO_rdrand_multiple8_buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_rdrand_multiple8_buf) +#define _CRYPTO_realloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_realloc) +#define _CRYPTO_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_refcount_dec_and_test_zero) +#define _CRYPTO_refcount_inc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_refcount_inc) +#define _CRYPTO_set_add_lock_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_add_lock_callback) +#define _CRYPTO_set_dynlock_create_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_dynlock_create_callback) +#define _CRYPTO_set_dynlock_destroy_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_dynlock_destroy_callback) +#define _CRYPTO_set_dynlock_lock_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_dynlock_lock_callback) +#define _CRYPTO_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_ex_data) +#define _CRYPTO_set_id_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_id_callback) +#define _CRYPTO_set_locking_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_locking_callback) +#define _CRYPTO_set_thread_local BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_set_thread_local) +#define _CRYPTO_sysrand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_sysrand) +#define _CRYPTO_sysrand_for_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_sysrand_for_seed) +#define _CRYPTO_sysrand_if_available BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_sysrand_if_available) +#define _CRYPTO_tls1_prf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_tls1_prf) +#define _CTR_DRBG_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_clear) +#define _CTR_DRBG_generate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_generate) +#define _CTR_DRBG_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_init) +#define _CTR_DRBG_reseed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define _ChaCha20_ctr32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ChaCha20_ctr32) +#define _DES_decrypt3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_decrypt3) +#define _DES_ecb3_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb3_encrypt) +#define _DES_ecb_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb_encrypt) +#define _DES_ede2_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ede2_cbc_encrypt) +#define _DES_ede3_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ede3_cbc_encrypt) +#define _DES_encrypt3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_encrypt3) +#define _DES_ncbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ncbc_encrypt) +#define _DES_set_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_set_key) +#define _DES_set_key_unchecked BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_set_key_unchecked) +#define _DES_set_odd_parity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_set_odd_parity) +#define _DH_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_check) +#define _DH_check_pub_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_check_pub_key) +#define _DH_compute_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_compute_key) +#define _DH_compute_key_hashed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_compute_key_hashed) +#define _DH_compute_key_padded BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_compute_key_padded) +#define _DH_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_free) +#define _DH_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_generate_key) +#define _DH_generate_parameters_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_generate_parameters_ex) +#define _DH_get0_g BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_g) +#define _DH_get0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_key) +#define _DH_get0_p BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_p) +#define _DH_get0_pqg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_pqg) +#define _DH_get0_priv_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_priv_key) +#define _DH_get0_pub_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_pub_key) +#define _DH_get0_q BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get0_q) +#define _DH_get_rfc7919_2048 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_get_rfc7919_2048) +#define _DH_marshal_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_marshal_parameters) +#define _DH_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_new) +#define _DH_num_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_num_bits) +#define _DH_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_parse_parameters) +#define _DH_set0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_set0_key) +#define _DH_set0_pqg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_set0_pqg) +#define _DH_set_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_set_length) +#define _DH_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_size) +#define _DH_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DH_up_ref) +#define _DHparams_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DHparams_dup) +#define _DIRECTORYSTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIRECTORYSTRING_free) +#define _DIRECTORYSTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIRECTORYSTRING_it) +#define _DIRECTORYSTRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIRECTORYSTRING_new) +#define _DISPLAYTEXT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DISPLAYTEXT_free) +#define _DISPLAYTEXT_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DISPLAYTEXT_it) +#define _DISPLAYTEXT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DISPLAYTEXT_new) +#define _DIST_POINT_NAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_NAME_free) +#define _DIST_POINT_NAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_NAME_it) +#define _DIST_POINT_NAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_NAME_new) +#define _DIST_POINT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_free) +#define _DIST_POINT_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_it) +#define _DIST_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_new) +#define _DIST_POINT_set_dpname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DIST_POINT_set_dpname) +#define _DSA_SIG_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_free) +#define _DSA_SIG_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_get0) +#define _DSA_SIG_marshal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_marshal) +#define _DSA_SIG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_new) +#define _DSA_SIG_parse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_parse) +#define _DSA_SIG_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_SIG_set0) +#define _DSA_check_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_check_signature) +#define _DSA_do_check_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_do_check_signature) +#define _DSA_do_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_do_sign) +#define _DSA_do_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_do_verify) +#define _DSA_dup_DH BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_dup_DH) +#define _DSA_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_free) +#define _DSA_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_generate_key) +#define _DSA_generate_parameters_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_generate_parameters_ex) +#define _DSA_get0_g BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_g) +#define _DSA_get0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_key) +#define _DSA_get0_p BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_p) +#define _DSA_get0_pqg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_pqg) +#define _DSA_get0_priv_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_priv_key) +#define _DSA_get0_pub_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_pub_key) +#define _DSA_get0_q BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get0_q) +#define _DSA_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get_ex_data) +#define _DSA_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_get_ex_new_index) +#define _DSA_marshal_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_marshal_parameters) +#define _DSA_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_marshal_private_key) +#define _DSA_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_marshal_public_key) +#define _DSA_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_new) +#define _DSA_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_parse_parameters) +#define _DSA_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_parse_private_key) +#define _DSA_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_parse_public_key) +#define _DSA_set0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_set0_key) +#define _DSA_set0_pqg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_set0_pqg) +#define _DSA_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_set_ex_data) +#define _DSA_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_sign) +#define _DSA_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_size) +#define _DSA_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_up_ref) +#define _DSA_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSA_verify) +#define _DSAparams_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DSAparams_dup) +#define _DTLS_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLS_client_method) +#define _DTLS_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLS_method) +#define _DTLS_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLS_server_method) +#define _DTLS_with_buffers_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLS_with_buffers_method) +#define _DTLSv1_2_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_2_client_method) +#define _DTLSv1_2_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_2_method) +#define _DTLSv1_2_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_2_server_method) +#define _DTLSv1_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_client_method) +#define _DTLSv1_get_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_get_timeout) +#define _DTLSv1_handle_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_handle_timeout) +#define _DTLSv1_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_method) +#define _DTLSv1_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_server_method) +#define _DTLSv1_set_initial_timeout_duration BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DTLSv1_set_initial_timeout_duration) +#define _ECDH_compute_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDH_compute_key) +#define _ECDH_compute_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDH_compute_key_fips) +#define _ECDSA_SIG_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_free) +#define _ECDSA_SIG_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_from_bytes) +#define _ECDSA_SIG_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_get0) +#define _ECDSA_SIG_get0_r BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_get0_r) +#define _ECDSA_SIG_get0_s BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_get0_s) +#define _ECDSA_SIG_marshal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_marshal) +#define _ECDSA_SIG_max_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_max_len) +#define _ECDSA_SIG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_new) +#define _ECDSA_SIG_parse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_parse) +#define _ECDSA_SIG_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_set0) +#define _ECDSA_SIG_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_SIG_to_bytes) +#define _ECDSA_do_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_do_sign) +#define _ECDSA_do_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_do_verify) +#define _ECDSA_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_sign) +#define _ECDSA_sign_with_nonce_and_leak_private_key_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_sign_with_nonce_and_leak_private_key_for_testing) +#define _ECDSA_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_size) +#define _ECDSA_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ECDSA_verify) +#define _EC_GFp_mont_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GFp_mont_method) +#define _EC_GFp_nistp224_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GFp_nistp224_method) +#define _EC_GFp_nistp256_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GFp_nistp256_method) +#define _EC_GFp_nistz256_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GFp_nistz256_method) +#define _EC_GROUP_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_cmp) +#define _EC_GROUP_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_dup) +#define _EC_GROUP_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_free) +#define _EC_GROUP_get0_generator BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get0_generator) +#define _EC_GROUP_get0_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get0_order) +#define _EC_GROUP_get_asn1_flag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_asn1_flag) +#define _EC_GROUP_get_cofactor BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_cofactor) +#define _EC_GROUP_get_curve_GFp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_curve_GFp) +#define _EC_GROUP_get_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_curve_name) +#define _EC_GROUP_get_degree BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_degree) +#define _EC_GROUP_get_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_get_order) +#define _EC_GROUP_method_of BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_method_of) +#define _EC_GROUP_new_by_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_new_by_curve_name) +#define _EC_GROUP_new_curve_GFp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_new_curve_GFp) +#define _EC_GROUP_order_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_order_bits) +#define _EC_GROUP_set_asn1_flag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_set_asn1_flag) +#define _EC_GROUP_set_generator BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_set_generator) +#define _EC_GROUP_set_point_conversion_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_GROUP_set_point_conversion_form) +#define _EC_KEY_check_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_check_fips) +#define _EC_KEY_check_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_check_key) +#define _EC_KEY_derive_from_secret BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_derive_from_secret) +#define _EC_KEY_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_dup) +#define _EC_KEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_free) +#define _EC_KEY_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_generate_key) +#define _EC_KEY_generate_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_generate_key_fips) +#define _EC_KEY_get0_group BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get0_group) +#define _EC_KEY_get0_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get0_private_key) +#define _EC_KEY_get0_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get0_public_key) +#define _EC_KEY_get_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get_conv_form) +#define _EC_KEY_get_enc_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get_enc_flags) +#define _EC_KEY_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get_ex_data) +#define _EC_KEY_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_get_ex_new_index) +#define _EC_KEY_is_opaque BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_is_opaque) +#define _EC_KEY_key2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_key2buf) +#define _EC_KEY_marshal_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_marshal_curve_name) +#define _EC_KEY_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_marshal_private_key) +#define _EC_KEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new) +#define _EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) +#define _EC_KEY_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_method) +#define _EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) +#define _EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_parameters) +#define _EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define _EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) +#define _EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_conv_form) +#define _EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) +#define _EC_KEY_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_ex_data) +#define _EC_KEY_set_group BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_group) +#define _EC_KEY_set_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_private_key) +#define _EC_KEY_set_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_public_key) +#define _EC_KEY_set_public_key_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_public_key_affine_coordinates) +#define _EC_KEY_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_up_ref) +#define _EC_METHOD_get_field_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_METHOD_get_field_type) +#define _EC_POINT_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_add) +#define _EC_POINT_clear_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_clear_free) +#define _EC_POINT_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_cmp) +#define _EC_POINT_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_copy) +#define _EC_POINT_dbl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_dbl) +#define _EC_POINT_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_dup) +#define _EC_POINT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_free) +#define _EC_POINT_get_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_get_affine_coordinates) +#define _EC_POINT_get_affine_coordinates_GFp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_get_affine_coordinates_GFp) +#define _EC_POINT_invert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_invert) +#define _EC_POINT_is_at_infinity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_is_at_infinity) +#define _EC_POINT_is_on_curve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_is_on_curve) +#define _EC_POINT_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_mul) +#define _EC_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_new) +#define _EC_POINT_oct2point BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define _EC_POINT_point2cbb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2cbb) +#define _EC_POINT_point2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2oct) +#define _EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) +#define _EC_POINT_set_affine_coordinates_GFp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates_GFp) +#define _EC_POINT_set_compressed_coordinates_GFp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_compressed_coordinates_GFp) +#define _EC_POINT_set_to_infinity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_to_infinity) +#define _EC_curve_nid2nist BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_curve_nid2nist) +#define _EC_curve_nist2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_curve_nist2nid) +#define _EC_get_builtin_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_get_builtin_curves) +#define _ED25519_keypair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_keypair) +#define _ED25519_keypair_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_keypair_from_seed) +#define _ED25519_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_sign) +#define _ED25519_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_verify) +#define _EDIPARTYNAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_free) +#define _EDIPARTYNAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_it) +#define _EDIPARTYNAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define _ENGINE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_free) +#define _ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) +#define _ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_RSA_method) +#define _ENGINE_load_builtin_engines BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_load_builtin_engines) +#define _ENGINE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_new) +#define _ENGINE_register_all_complete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_register_all_complete) +#define _ENGINE_set_ECDSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_set_ECDSA_method) +#define _ENGINE_set_RSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_set_RSA_method) +#define _ERR_SAVE_STATE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_SAVE_STATE_free) +#define _ERR_add_error_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_data) +#define _ERR_add_error_dataf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_dataf) +#define _ERR_clear_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_error) +#define _ERR_clear_system_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_system_error) +#define _ERR_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string) +#define _ERR_error_string_n BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string_n) +#define _ERR_free_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_free_strings) +#define _ERR_func_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_func_error_string) +#define _ERR_get_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_get_error) +#define _ERR_get_error_line BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_get_error_line) +#define _ERR_get_error_line_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_get_error_line_data) +#define _ERR_get_next_error_library BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_get_next_error_library) +#define _ERR_lib_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_lib_error_string) +#define _ERR_load_BIO_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_load_BIO_strings) +#define _ERR_load_ERR_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_load_ERR_strings) +#define _ERR_load_RAND_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_load_RAND_strings) +#define _ERR_load_SSL_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_load_SSL_strings) +#define _ERR_load_crypto_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_load_crypto_strings) +#define _ERR_peek_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_error) +#define _ERR_peek_error_line BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_error_line) +#define _ERR_peek_error_line_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_error_line_data) +#define _ERR_peek_last_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_last_error) +#define _ERR_peek_last_error_line BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_last_error_line) +#define _ERR_peek_last_error_line_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_peek_last_error_line_data) +#define _ERR_pop_to_mark BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_pop_to_mark) +#define _ERR_print_errors BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_print_errors) +#define _ERR_print_errors_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_print_errors_cb) +#define _ERR_print_errors_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_print_errors_fp) +#define _ERR_put_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_put_error) +#define _ERR_reason_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_reason_error_string) +#define _ERR_remove_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_remove_state) +#define _ERR_remove_thread_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_remove_thread_state) +#define _ERR_restore_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_restore_state) +#define _ERR_save_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_save_state) +#define _ERR_set_error_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_set_error_data) +#define _ERR_set_mark BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_set_mark) +#define _EVP_AEAD_CTX_aead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_aead) +#define _EVP_AEAD_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_cleanup) +#define _EVP_AEAD_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_free) +#define _EVP_AEAD_CTX_get_iv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_get_iv) +#define _EVP_AEAD_CTX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_init) +#define _EVP_AEAD_CTX_init_with_direction BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_init_with_direction) +#define _EVP_AEAD_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_new) +#define _EVP_AEAD_CTX_open BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_open) +#define _EVP_AEAD_CTX_open_gather BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_open_gather) +#define _EVP_AEAD_CTX_seal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_seal) +#define _EVP_AEAD_CTX_seal_scatter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_seal_scatter) +#define _EVP_AEAD_CTX_tag_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_tag_len) +#define _EVP_AEAD_CTX_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_CTX_zero) +#define _EVP_AEAD_key_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_key_length) +#define _EVP_AEAD_max_overhead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_max_overhead) +#define _EVP_AEAD_max_tag_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_max_tag_len) +#define _EVP_AEAD_nonce_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_AEAD_nonce_length) +#define _EVP_BytesToKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_BytesToKey) +#define _EVP_CIPHER_CTX_block_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_block_size) +#define _EVP_CIPHER_CTX_cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_cipher) +#define _EVP_CIPHER_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_cleanup) +#define _EVP_CIPHER_CTX_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_copy) +#define _EVP_CIPHER_CTX_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_ctrl) +#define _EVP_CIPHER_CTX_encrypting BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_encrypting) +#define _EVP_CIPHER_CTX_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_flags) +#define _EVP_CIPHER_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_free) +#define _EVP_CIPHER_CTX_get_app_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_get_app_data) +#define _EVP_CIPHER_CTX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_init) +#define _EVP_CIPHER_CTX_iv_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_iv_length) +#define _EVP_CIPHER_CTX_key_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_key_length) +#define _EVP_CIPHER_CTX_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_mode) +#define _EVP_CIPHER_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_new) +#define _EVP_CIPHER_CTX_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_nid) +#define _EVP_CIPHER_CTX_reset BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_reset) +#define _EVP_CIPHER_CTX_set_app_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_app_data) +#define _EVP_CIPHER_CTX_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_flags) +#define _EVP_CIPHER_CTX_set_key_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_key_length) +#define _EVP_CIPHER_CTX_set_padding BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_CTX_set_padding) +#define _EVP_CIPHER_block_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_block_size) +#define _EVP_CIPHER_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_flags) +#define _EVP_CIPHER_iv_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_iv_length) +#define _EVP_CIPHER_key_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_key_length) +#define _EVP_CIPHER_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_mode) +#define _EVP_CIPHER_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CIPHER_nid) +#define _EVP_Cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_Cipher) +#define _EVP_CipherFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CipherFinal) +#define _EVP_CipherFinal_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CipherFinal_ex) +#define _EVP_CipherInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CipherInit) +#define _EVP_CipherInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CipherInit_ex) +#define _EVP_CipherUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_CipherUpdate) +#define _EVP_DecodeBase64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodeBase64) +#define _EVP_DecodeBlock BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodeBlock) +#define _EVP_DecodeFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodeFinal) +#define _EVP_DecodeInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodeInit) +#define _EVP_DecodeUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodeUpdate) +#define _EVP_DecodedLength BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecodedLength) +#define _EVP_DecryptFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecryptFinal) +#define _EVP_DecryptFinal_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecryptFinal_ex) +#define _EVP_DecryptInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecryptInit) +#define _EVP_DecryptInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecryptInit_ex) +#define _EVP_DecryptUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DecryptUpdate) +#define _EVP_Digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_Digest) +#define _EVP_DigestFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestFinal) +#define _EVP_DigestFinalXOF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestFinalXOF) +#define _EVP_DigestFinal_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestFinal_ex) +#define _EVP_DigestInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestInit) +#define _EVP_DigestInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestInit_ex) +#define _EVP_DigestSign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestSign) +#define _EVP_DigestSignFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestSignFinal) +#define _EVP_DigestSignInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestSignInit) +#define _EVP_DigestSignUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestSignUpdate) +#define _EVP_DigestUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestUpdate) +#define _EVP_DigestVerify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestVerify) +#define _EVP_DigestVerifyFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestVerifyFinal) +#define _EVP_DigestVerifyInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestVerifyInit) +#define _EVP_DigestVerifyUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_DigestVerifyUpdate) +#define _EVP_ENCODE_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_ENCODE_CTX_free) +#define _EVP_ENCODE_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_ENCODE_CTX_new) +#define _EVP_EncodeBlock BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncodeBlock) +#define _EVP_EncodeFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncodeFinal) +#define _EVP_EncodeInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncodeInit) +#define _EVP_EncodeUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncodeUpdate) +#define _EVP_EncodedLength BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncodedLength) +#define _EVP_EncryptFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncryptFinal) +#define _EVP_EncryptFinal_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncryptFinal_ex) +#define _EVP_EncryptInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncryptInit) +#define _EVP_EncryptInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncryptInit_ex) +#define _EVP_EncryptUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_EncryptUpdate) +#define _EVP_HPKE_AEAD_aead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_AEAD_aead) +#define _EVP_HPKE_AEAD_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_AEAD_id) +#define _EVP_HPKE_CTX_aead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_aead) +#define _EVP_HPKE_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_cleanup) +#define _EVP_HPKE_CTX_export BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_export) +#define _EVP_HPKE_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_free) +#define _EVP_HPKE_CTX_kdf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_kdf) +#define _EVP_HPKE_CTX_max_overhead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_max_overhead) +#define _EVP_HPKE_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_new) +#define _EVP_HPKE_CTX_open BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_open) +#define _EVP_HPKE_CTX_seal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_seal) +#define _EVP_HPKE_CTX_setup_recipient BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_recipient) +#define _EVP_HPKE_CTX_setup_sender BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_sender) +#define _EVP_HPKE_CTX_setup_sender_with_seed_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_setup_sender_with_seed_for_testing) +#define _EVP_HPKE_CTX_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_CTX_zero) +#define _EVP_HPKE_KDF_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KDF_id) +#define _EVP_HPKE_KEM_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEM_id) +#define _EVP_HPKE_KEY_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_cleanup) +#define _EVP_HPKE_KEY_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_copy) +#define _EVP_HPKE_KEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_free) +#define _EVP_HPKE_KEY_generate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_generate) +#define _EVP_HPKE_KEY_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_init) +#define _EVP_HPKE_KEY_kem BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_kem) +#define _EVP_HPKE_KEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_new) +#define _EVP_HPKE_KEY_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_private_key) +#define _EVP_HPKE_KEY_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_public_key) +#define _EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) +#define _EVP_MD_CTX_block_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_block_size) +#define _EVP_MD_CTX_cleanse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_cleanse) +#define _EVP_MD_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_cleanup) +#define _EVP_MD_CTX_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_copy) +#define _EVP_MD_CTX_copy_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_copy_ex) +#define _EVP_MD_CTX_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_create) +#define _EVP_MD_CTX_destroy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_destroy) +#define _EVP_MD_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_free) +#define _EVP_MD_CTX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_init) +#define _EVP_MD_CTX_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_md) +#define _EVP_MD_CTX_move BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_move) +#define _EVP_MD_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_new) +#define _EVP_MD_CTX_reset BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_reset) +#define _EVP_MD_CTX_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_set_flags) +#define _EVP_MD_CTX_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_size) +#define _EVP_MD_CTX_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_CTX_type) +#define _EVP_MD_block_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_block_size) +#define _EVP_MD_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_flags) +#define _EVP_MD_meth_get_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_meth_get_flags) +#define _EVP_MD_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_nid) +#define _EVP_MD_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_size) +#define _EVP_MD_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_MD_type) +#define _EVP_PBE_scrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PBE_scrypt) +#define _EVP_PKCS82PKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKCS82PKEY) +#define _EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) +#define _EVP_PKEY_CTX_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_ctrl) +#define _EVP_PKEY_CTX_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_dup) +#define _EVP_PKEY_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_free) +#define _EVP_PKEY_CTX_get0_pkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get0_pkey) +#define _EVP_PKEY_CTX_get0_rsa_oaep_label BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get0_rsa_oaep_label) +#define _EVP_PKEY_CTX_get_rsa_mgf1_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_mgf1_md) +#define _EVP_PKEY_CTX_get_rsa_oaep_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_oaep_md) +#define _EVP_PKEY_CTX_get_rsa_padding BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_padding) +#define _EVP_PKEY_CTX_get_rsa_pss_saltlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_rsa_pss_saltlen) +#define _EVP_PKEY_CTX_get_signature_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_get_signature_md) +#define _EVP_PKEY_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_new) +#define _EVP_PKEY_CTX_new_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_new_id) +#define _EVP_PKEY_CTX_set0_rsa_oaep_label BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set0_rsa_oaep_label) +#define _EVP_PKEY_CTX_set_ec_param_enc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_ec_param_enc) +#define _EVP_PKEY_CTX_set_ec_paramgen_curve_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_ec_paramgen_curve_nid) +#define _EVP_PKEY_CTX_set_rsa_keygen_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_keygen_bits) +#define _EVP_PKEY_CTX_set_rsa_keygen_pubexp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_keygen_pubexp) +#define _EVP_PKEY_CTX_set_rsa_mgf1_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_mgf1_md) +#define _EVP_PKEY_CTX_set_rsa_oaep_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_oaep_md) +#define _EVP_PKEY_CTX_set_rsa_padding BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_padding) +#define _EVP_PKEY_CTX_set_rsa_pss_keygen_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_md) +#define _EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md) +#define _EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen) +#define _EVP_PKEY_CTX_set_rsa_pss_saltlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_rsa_pss_saltlen) +#define _EVP_PKEY_CTX_set_signature_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_CTX_set_signature_md) +#define _EVP_PKEY_assign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_assign) +#define _EVP_PKEY_assign_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_assign_DSA) +#define _EVP_PKEY_assign_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_assign_EC_KEY) +#define _EVP_PKEY_assign_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_assign_RSA) +#define _EVP_PKEY_base_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_base_id) +#define _EVP_PKEY_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_bits) +#define _EVP_PKEY_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_cmp) +#define _EVP_PKEY_cmp_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_cmp_parameters) +#define _EVP_PKEY_copy_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_copy_parameters) +#define _EVP_PKEY_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_decrypt) +#define _EVP_PKEY_decrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_decrypt_init) +#define _EVP_PKEY_derive BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive) +#define _EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_init) +#define _EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define _EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt) +#define _EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) +#define _EVP_PKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_free) +#define _EVP_PKEY_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0) +#define _EVP_PKEY_get0_DH BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0_DH) +#define _EVP_PKEY_get0_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0_DSA) +#define _EVP_PKEY_get0_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0_EC_KEY) +#define _EVP_PKEY_get0_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0_RSA) +#define _EVP_PKEY_get1_DH BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get1_DH) +#define _EVP_PKEY_get1_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get1_DSA) +#define _EVP_PKEY_get1_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get1_EC_KEY) +#define _EVP_PKEY_get1_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get1_RSA) +#define _EVP_PKEY_get1_tls_encodedpoint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get1_tls_encodedpoint) +#define _EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) +#define _EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) +#define _EVP_PKEY_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_id) +#define _EVP_PKEY_is_opaque BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_is_opaque) +#define _EVP_PKEY_keygen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_keygen) +#define _EVP_PKEY_keygen_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_keygen_init) +#define _EVP_PKEY_missing_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_missing_parameters) +#define _EVP_PKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_new) +#define _EVP_PKEY_new_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_new_raw_private_key) +#define _EVP_PKEY_new_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_new_raw_public_key) +#define _EVP_PKEY_paramgen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_paramgen) +#define _EVP_PKEY_paramgen_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_paramgen_init) +#define _EVP_PKEY_print_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_params) +#define _EVP_PKEY_print_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_private) +#define _EVP_PKEY_print_public BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_public) +#define _EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) +#define _EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) +#define _EVP_PKEY_set1_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_RSA) +#define _EVP_PKEY_set1_tls_encodedpoint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_tls_encodedpoint) +#define _EVP_PKEY_set_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define _EVP_PKEY_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_sign) +#define _EVP_PKEY_sign_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_sign_init) +#define _EVP_PKEY_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_size) +#define _EVP_PKEY_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_type) +#define _EVP_PKEY_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_up_ref) +#define _EVP_PKEY_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify) +#define _EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_init) +#define _EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) +#define _EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define _EVP_SignFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_SignFinal) +#define _EVP_SignInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_SignInit) +#define _EVP_SignInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_SignInit_ex) +#define _EVP_SignUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_SignUpdate) +#define _EVP_VerifyFinal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_VerifyFinal) +#define _EVP_VerifyInit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_VerifyInit) +#define _EVP_VerifyInit_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_VerifyInit_ex) +#define _EVP_VerifyUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_VerifyUpdate) +#define _EVP_add_cipher_alias BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_add_cipher_alias) +#define _EVP_add_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_add_digest) +#define _EVP_aead_aes_128_cbc_sha1_tls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_cbc_sha1_tls) +#define _EVP_aead_aes_128_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_cbc_sha1_tls_implicit_iv) +#define _EVP_aead_aes_128_ccm_bluetooth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_ccm_bluetooth) +#define _EVP_aead_aes_128_ccm_bluetooth_8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_ccm_bluetooth_8) +#define _EVP_aead_aes_128_ctr_hmac_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_ctr_hmac_sha256) +#define _EVP_aead_aes_128_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm) +#define _EVP_aead_aes_128_gcm_randnonce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_randnonce) +#define _EVP_aead_aes_128_gcm_siv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_siv) +#define _EVP_aead_aes_128_gcm_tls12 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_tls12) +#define _EVP_aead_aes_128_gcm_tls13 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_128_gcm_tls13) +#define _EVP_aead_aes_192_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_192_gcm) +#define _EVP_aead_aes_256_cbc_sha1_tls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_cbc_sha1_tls) +#define _EVP_aead_aes_256_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_cbc_sha1_tls_implicit_iv) +#define _EVP_aead_aes_256_ctr_hmac_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_ctr_hmac_sha256) +#define _EVP_aead_aes_256_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm) +#define _EVP_aead_aes_256_gcm_randnonce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_randnonce) +#define _EVP_aead_aes_256_gcm_siv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_siv) +#define _EVP_aead_aes_256_gcm_tls12 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_tls12) +#define _EVP_aead_aes_256_gcm_tls13 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_aes_256_gcm_tls13) +#define _EVP_aead_chacha20_poly1305 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_chacha20_poly1305) +#define _EVP_aead_des_ede3_cbc_sha1_tls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_des_ede3_cbc_sha1_tls) +#define _EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv) +#define _EVP_aead_null_sha1_tls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_null_sha1_tls) +#define _EVP_aead_xchacha20_poly1305 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aead_xchacha20_poly1305) +#define _EVP_aes_128_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_128_cbc) +#define _EVP_aes_128_ctr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_128_ctr) +#define _EVP_aes_128_ecb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_128_ecb) +#define _EVP_aes_128_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_128_gcm) +#define _EVP_aes_128_ofb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_128_ofb) +#define _EVP_aes_192_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_192_cbc) +#define _EVP_aes_192_ctr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_192_ctr) +#define _EVP_aes_192_ecb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_192_ecb) +#define _EVP_aes_192_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_192_gcm) +#define _EVP_aes_192_ofb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_192_ofb) +#define _EVP_aes_256_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_256_cbc) +#define _EVP_aes_256_ctr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_256_ctr) +#define _EVP_aes_256_ecb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_256_ecb) +#define _EVP_aes_256_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_256_gcm) +#define _EVP_aes_256_ofb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_aes_256_ofb) +#define _EVP_blake2b256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_blake2b256) +#define _EVP_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_cleanup) +#define _EVP_des_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_cbc) +#define _EVP_des_ecb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ecb) +#define _EVP_des_ede BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ede) +#define _EVP_des_ede3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ede3) +#define _EVP_des_ede3_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ede3_cbc) +#define _EVP_des_ede3_ecb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ede3_ecb) +#define _EVP_des_ede_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_des_ede_cbc) +#define _EVP_enc_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_enc_null) +#define _EVP_get_cipherbyname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_get_cipherbyname) +#define _EVP_get_cipherbynid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_get_cipherbynid) +#define _EVP_get_digestbyname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_get_digestbyname) +#define _EVP_get_digestbynid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_get_digestbynid) +#define _EVP_get_digestbyobj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_get_digestbyobj) +#define _EVP_has_aes_hardware BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_has_aes_hardware) +#define _EVP_hpke_aes_128_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_aes_128_gcm) +#define _EVP_hpke_aes_256_gcm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_aes_256_gcm) +#define _EVP_hpke_chacha20_poly1305 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_chacha20_poly1305) +#define _EVP_hpke_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_hkdf_sha256) +#define _EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define _EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) +#define _EVP_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_private_key) +#define _EVP_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_public_key) +#define _EVP_md4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md4) +#define _EVP_md5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5) +#define _EVP_md5_sha1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5_sha1) +#define _EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define _EVP_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_private_key) +#define _EVP_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_public_key) +#define _EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_40_cbc) +#define _EVP_rc2_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_cbc) +#define _EVP_rc4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc4) +#define _EVP_sha1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha1) +#define _EVP_sha1_final_with_secret_suffix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha1_final_with_secret_suffix) +#define _EVP_sha224 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha224) +#define _EVP_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha256) +#define _EVP_sha384 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha384) +#define _EVP_sha512 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha512) +#define _EVP_sha512_256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_sha512_256) +#define _EVP_tls_cbc_copy_mac BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_tls_cbc_copy_mac) +#define _EVP_tls_cbc_digest_record BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_tls_cbc_digest_record) +#define _EVP_tls_cbc_record_digest_supported BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_tls_cbc_record_digest_supported) +#define _EVP_tls_cbc_remove_padding BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_tls_cbc_remove_padding) +#define _EXTENDED_KEY_USAGE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_free) +#define _EXTENDED_KEY_USAGE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_it) +#define _EXTENDED_KEY_USAGE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EXTENDED_KEY_USAGE_new) +#define _FIPS_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_mode) +#define _FIPS_mode_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_mode_set) +#define _FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_query_algorithm_status) +#define _FIPS_read_counter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_read_counter) +#define _FIPS_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_version) +#define _GENERAL_NAMES_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAMES_free) +#define _GENERAL_NAMES_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAMES_it) +#define _GENERAL_NAMES_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAMES_new) +#define _GENERAL_NAME_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_cmp) +#define _GENERAL_NAME_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_dup) +#define _GENERAL_NAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_free) +#define _GENERAL_NAME_get0_otherName BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_get0_otherName) +#define _GENERAL_NAME_get0_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_get0_value) +#define _GENERAL_NAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_it) +#define _GENERAL_NAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_new) +#define _GENERAL_NAME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_print) +#define _GENERAL_NAME_set0_othername BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_set0_othername) +#define _GENERAL_NAME_set0_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_NAME_set0_value) +#define _GENERAL_SUBTREE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_SUBTREE_free) +#define _GENERAL_SUBTREE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_SUBTREE_it) +#define _GENERAL_SUBTREE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, GENERAL_SUBTREE_new) +#define _HKDF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HKDF) +#define _HKDF_expand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HKDF_expand) +#define _HKDF_extract BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HKDF_extract) +#define _HMAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC) +#define _HMAC_CTX_cleanse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_cleanse) +#define _HMAC_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_cleanup) +#define _HMAC_CTX_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_copy) +#define _HMAC_CTX_copy_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_copy_ex) +#define _HMAC_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_free) +#define _HMAC_CTX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_init) +#define _HMAC_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_new) +#define _HMAC_CTX_reset BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_CTX_reset) +#define _HMAC_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_Final) +#define _HMAC_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_Init) +#define _HMAC_Init_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_Init_ex) +#define _HMAC_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_Update) +#define _HMAC_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HMAC_size) +#define _HRSS_decap BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_decap) +#define _HRSS_encap BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_encap) +#define _HRSS_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_generate_key) +#define _HRSS_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_marshal_public_key) +#define _HRSS_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_parse_public_key) +#define _HRSS_poly3_invert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_poly3_invert) +#define _HRSS_poly3_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, HRSS_poly3_mul) +#define _ISSUING_DIST_POINT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_free) +#define _ISSUING_DIST_POINT_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_it) +#define _ISSUING_DIST_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ISSUING_DIST_POINT_new) +#define _MD4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4) +#define _MD4_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Final) +#define _MD4_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Init) +#define _MD4_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Transform) +#define _MD4_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD4_Update) +#define _MD5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5) +#define _MD5_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Final) +#define _MD5_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Init) +#define _MD5_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Transform) +#define _MD5_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Update) +#define _METHOD_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_ref) +#define _METHOD_unref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_unref) +#define _NAME_CONSTRAINTS_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NAME_CONSTRAINTS_check) +#define _NAME_CONSTRAINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NAME_CONSTRAINTS_free) +#define _NAME_CONSTRAINTS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NAME_CONSTRAINTS_it) +#define _NAME_CONSTRAINTS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NAME_CONSTRAINTS_new) +#define _NCONF_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_free) +#define _NCONF_get_section BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_get_section) +#define _NCONF_get_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_get_string) +#define _NCONF_load BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_load) +#define _NCONF_load_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_load_bio) +#define _NCONF_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NCONF_new) +#define _NETSCAPE_SPKAC_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKAC_free) +#define _NETSCAPE_SPKAC_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKAC_it) +#define _NETSCAPE_SPKAC_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKAC_new) +#define _NETSCAPE_SPKI_b64_decode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_b64_decode) +#define _NETSCAPE_SPKI_b64_encode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_b64_encode) +#define _NETSCAPE_SPKI_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_free) +#define _NETSCAPE_SPKI_get_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_get_pubkey) +#define _NETSCAPE_SPKI_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_it) +#define _NETSCAPE_SPKI_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_new) +#define _NETSCAPE_SPKI_set_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_set_pubkey) +#define _NETSCAPE_SPKI_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_sign) +#define _NETSCAPE_SPKI_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NETSCAPE_SPKI_verify) +#define _NOTICEREF_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NOTICEREF_free) +#define _NOTICEREF_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NOTICEREF_it) +#define _NOTICEREF_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, NOTICEREF_new) +#define _OBJ_cbs2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_cbs2nid) +#define _OBJ_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_cleanup) +#define _OBJ_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_cmp) +#define _OBJ_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_create) +#define _OBJ_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_dup) +#define _OBJ_find_sigid_algs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_find_sigid_algs) +#define _OBJ_find_sigid_by_algs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_find_sigid_by_algs) +#define _OBJ_get0_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_get0_data) +#define _OBJ_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_length) +#define _OBJ_ln2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_ln2nid) +#define _OBJ_nid2cbb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_nid2cbb) +#define _OBJ_nid2ln BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_nid2ln) +#define _OBJ_nid2obj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_nid2obj) +#define _OBJ_nid2sn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_nid2sn) +#define _OBJ_obj2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_obj2nid) +#define _OBJ_obj2txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_obj2txt) +#define _OBJ_sn2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_sn2nid) +#define _OBJ_txt2nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_txt2nid) +#define _OBJ_txt2obj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OBJ_txt2obj) +#define _OPENSSL_add_all_algorithms_conf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_add_all_algorithms_conf) +#define _OPENSSL_armcap_P BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_armcap_P) +#define _OPENSSL_built_in_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_built_in_curves) +#define _OPENSSL_cleanse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cleanse) +#define _OPENSSL_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cleanup) +#define _OPENSSL_clear_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_clear_free) +#define _OPENSSL_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_config) +#define _OPENSSL_cpuid_setup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_cpuid_setup) +#define _OPENSSL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_free) +#define _OPENSSL_get_armcap_pointer_for_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_get_armcap_pointer_for_test) +#define _OPENSSL_gmtime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_gmtime) +#define _OPENSSL_gmtime_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_gmtime_adj) +#define _OPENSSL_gmtime_diff BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_gmtime_diff) +#define _OPENSSL_hash32 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_hash32) +#define _OPENSSL_ia32cap_P BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_ia32cap_P) +#define _OPENSSL_init_crypto BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_init_crypto) +#define _OPENSSL_init_ssl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_init_ssl) +#define _OPENSSL_lh_delete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_delete) +#define _OPENSSL_lh_doall_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_doall_arg) +#define _OPENSSL_lh_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_free) +#define _OPENSSL_lh_insert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_insert) +#define _OPENSSL_lh_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_new) +#define _OPENSSL_lh_num_items BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_num_items) +#define _OPENSSL_lh_retrieve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_retrieve) +#define _OPENSSL_lh_retrieve_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_lh_retrieve_key) +#define _OPENSSL_load_builtin_modules BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_load_builtin_modules) +#define _OPENSSL_malloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_malloc) +#define _OPENSSL_malloc_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_malloc_init) +#define _OPENSSL_memdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_memdup) +#define _OPENSSL_no_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_no_config) +#define _OPENSSL_realloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_realloc) +#define _OPENSSL_strcasecmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strcasecmp) +#define _OPENSSL_strdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strdup) +#define _OPENSSL_strhash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strhash) +#define _OPENSSL_strlcat BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strlcat) +#define _OPENSSL_strlcpy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strlcpy) +#define _OPENSSL_strncasecmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strncasecmp) +#define _OPENSSL_strndup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strndup) +#define _OPENSSL_strnlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_strnlen) +#define _OPENSSL_tolower BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_tolower) +#define _OTHERNAME_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_cmp) +#define _OTHERNAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_free) +#define _OTHERNAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_it) +#define _OTHERNAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OTHERNAME_new) +#define _OpenSSL_add_all_algorithms BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OpenSSL_add_all_algorithms) +#define _OpenSSL_add_all_ciphers BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OpenSSL_add_all_ciphers) +#define _OpenSSL_add_all_digests BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OpenSSL_add_all_digests) +#define _OpenSSL_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OpenSSL_version) +#define _OpenSSL_version_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OpenSSL_version_num) +#define _PEM_ASN1_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_ASN1_read) +#define _PEM_ASN1_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_ASN1_read_bio) +#define _PEM_ASN1_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_ASN1_write) +#define _PEM_ASN1_write_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_ASN1_write_bio) +#define _PEM_X509_INFO_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_X509_INFO_read) +#define _PEM_X509_INFO_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_X509_INFO_read_bio) +#define _PEM_X509_INFO_write_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_X509_INFO_write_bio) +#define _PEM_bytes_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_bytes_read_bio) +#define _PEM_def_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_def_callback) +#define _PEM_dek_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_dek_info) +#define _PEM_do_header BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_do_header) +#define _PEM_get_EVP_CIPHER_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_get_EVP_CIPHER_INFO) +#define _PEM_proc_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_proc_type) +#define _PEM_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read) +#define _PEM_read_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DHparams) +#define _PEM_read_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DSAPrivateKey) +#define _PEM_read_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DSA_PUBKEY) +#define _PEM_read_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_DSAparams) +#define _PEM_read_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_ECPrivateKey) +#define _PEM_read_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_EC_PUBKEY) +#define _PEM_read_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_PKCS7) +#define _PEM_read_PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_PKCS8) +#define _PEM_read_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_PKCS8_PRIV_KEY_INFO) +#define _PEM_read_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_PUBKEY) +#define _PEM_read_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_PrivateKey) +#define _PEM_read_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_RSAPrivateKey) +#define _PEM_read_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_RSAPublicKey) +#define _PEM_read_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_RSA_PUBKEY) +#define _PEM_read_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_SSL_SESSION) +#define _PEM_read_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_X509) +#define _PEM_read_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_X509_AUX) +#define _PEM_read_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_X509_CRL) +#define _PEM_read_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_X509_REQ) +#define _PEM_read_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio) +#define _PEM_read_bio_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_DHparams) +#define _PEM_read_bio_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_DSAPrivateKey) +#define _PEM_read_bio_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_DSA_PUBKEY) +#define _PEM_read_bio_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_DSAparams) +#define _PEM_read_bio_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_ECPrivateKey) +#define _PEM_read_bio_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_EC_PUBKEY) +#define _PEM_read_bio_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_PKCS7) +#define _PEM_read_bio_PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_PKCS8) +#define _PEM_read_bio_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_PKCS8_PRIV_KEY_INFO) +#define _PEM_read_bio_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_PUBKEY) +#define _PEM_read_bio_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_PrivateKey) +#define _PEM_read_bio_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_RSAPrivateKey) +#define _PEM_read_bio_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_RSAPublicKey) +#define _PEM_read_bio_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_RSA_PUBKEY) +#define _PEM_read_bio_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_SSL_SESSION) +#define _PEM_read_bio_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_X509) +#define _PEM_read_bio_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_X509_AUX) +#define _PEM_read_bio_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_X509_CRL) +#define _PEM_read_bio_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_read_bio_X509_REQ) +#define _PEM_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write) +#define _PEM_write_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_DHparams) +#define _PEM_write_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_DSAPrivateKey) +#define _PEM_write_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_DSA_PUBKEY) +#define _PEM_write_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_DSAparams) +#define _PEM_write_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_ECPrivateKey) +#define _PEM_write_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_EC_PUBKEY) +#define _PEM_write_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PKCS7) +#define _PEM_write_PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PKCS8) +#define _PEM_write_PKCS8PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PKCS8PrivateKey) +#define _PEM_write_PKCS8PrivateKey_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PKCS8PrivateKey_nid) +#define _PEM_write_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PKCS8_PRIV_KEY_INFO) +#define _PEM_write_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PUBKEY) +#define _PEM_write_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_PrivateKey) +#define _PEM_write_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_RSAPrivateKey) +#define _PEM_write_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_RSAPublicKey) +#define _PEM_write_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_RSA_PUBKEY) +#define _PEM_write_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_SSL_SESSION) +#define _PEM_write_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_X509) +#define _PEM_write_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_X509_AUX) +#define _PEM_write_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_X509_CRL) +#define _PEM_write_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_X509_REQ) +#define _PEM_write_X509_REQ_NEW BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_X509_REQ_NEW) +#define _PEM_write_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio) +#define _PEM_write_bio_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_DHparams) +#define _PEM_write_bio_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_DSAPrivateKey) +#define _PEM_write_bio_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_DSA_PUBKEY) +#define _PEM_write_bio_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_DSAparams) +#define _PEM_write_bio_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_ECPrivateKey) +#define _PEM_write_bio_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_EC_PUBKEY) +#define _PEM_write_bio_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PKCS7) +#define _PEM_write_bio_PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PKCS8) +#define _PEM_write_bio_PKCS8PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PKCS8PrivateKey) +#define _PEM_write_bio_PKCS8PrivateKey_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PKCS8PrivateKey_nid) +#define _PEM_write_bio_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PKCS8_PRIV_KEY_INFO) +#define _PEM_write_bio_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PUBKEY) +#define _PEM_write_bio_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_PrivateKey) +#define _PEM_write_bio_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_RSAPrivateKey) +#define _PEM_write_bio_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_RSAPublicKey) +#define _PEM_write_bio_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_RSA_PUBKEY) +#define _PEM_write_bio_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_SSL_SESSION) +#define _PEM_write_bio_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_X509) +#define _PEM_write_bio_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_X509_AUX) +#define _PEM_write_bio_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_X509_CRL) +#define _PEM_write_bio_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_X509_REQ) +#define _PEM_write_bio_X509_REQ_NEW BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PEM_write_bio_X509_REQ_NEW) +#define _PKCS12_PBE_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_PBE_add) +#define _PKCS12_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_create) +#define _PKCS12_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_free) +#define _PKCS12_get_key_and_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_get_key_and_certs) +#define _PKCS12_parse BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_parse) +#define _PKCS12_verify_mac BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS12_verify_mac) +#define _PKCS5_PBKDF2_HMAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC) +#define _PKCS5_PBKDF2_HMAC_SHA1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_PBKDF2_HMAC_SHA1) +#define _PKCS5_pbe2_decrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_pbe2_decrypt_init) +#define _PKCS5_pbe2_encrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS5_pbe2_encrypt_init) +#define _PKCS7_bundle_CRLs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_bundle_CRLs) +#define _PKCS7_bundle_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_bundle_certificates) +#define _PKCS7_bundle_raw_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_bundle_raw_certificates) +#define _PKCS7_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_free) +#define _PKCS7_get_CRLs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_get_CRLs) +#define _PKCS7_get_PEM_CRLs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_get_PEM_CRLs) +#define _PKCS7_get_PEM_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_get_PEM_certificates) +#define _PKCS7_get_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_get_certificates) +#define _PKCS7_get_raw_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_get_raw_certificates) +#define _PKCS7_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_sign) +#define _PKCS7_type_is_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_data) +#define _PKCS7_type_is_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_digest) +#define _PKCS7_type_is_encrypted BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_encrypted) +#define _PKCS7_type_is_enveloped BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_enveloped) +#define _PKCS7_type_is_signed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_signed) +#define _PKCS7_type_is_signedAndEnveloped BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS7_type_is_signedAndEnveloped) +#define _PKCS8_PRIV_KEY_INFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_free) +#define _PKCS8_PRIV_KEY_INFO_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_it) +#define _PKCS8_PRIV_KEY_INFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_PRIV_KEY_INFO_new) +#define _PKCS8_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_decrypt) +#define _PKCS8_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_encrypt) +#define _PKCS8_marshal_encrypted_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_marshal_encrypted_private_key) +#define _PKCS8_parse_encrypted_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_parse_encrypted_private_key) +#define _PKCS8_pkey_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_pkey_get0) +#define _PKCS8_pkey_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PKCS8_pkey_set0) +#define _POLICYINFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYINFO_free) +#define _POLICYINFO_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYINFO_it) +#define _POLICYINFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYINFO_new) +#define _POLICYQUALINFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYQUALINFO_free) +#define _POLICYQUALINFO_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYQUALINFO_it) +#define _POLICYQUALINFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICYQUALINFO_new) +#define _POLICY_CONSTRAINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_free) +#define _POLICY_CONSTRAINTS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_it) +#define _POLICY_CONSTRAINTS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_CONSTRAINTS_new) +#define _POLICY_MAPPINGS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPINGS_it) +#define _POLICY_MAPPING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_free) +#define _POLICY_MAPPING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_it) +#define _POLICY_MAPPING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, POLICY_MAPPING_new) +#define _PROXY_CERT_INFO_EXTENSION_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_free) +#define _PROXY_CERT_INFO_EXTENSION_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_it) +#define _PROXY_CERT_INFO_EXTENSION_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_CERT_INFO_EXTENSION_new) +#define _PROXY_POLICY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_free) +#define _PROXY_POLICY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_it) +#define _PROXY_POLICY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, PROXY_POLICY_new) +#define _RAND_OpenSSL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_OpenSSL) +#define _RAND_SSLeay BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_SSLeay) +#define _RAND_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_add) +#define _RAND_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_bytes) +#define _RAND_bytes_with_additional_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_bytes_with_additional_data) +#define _RAND_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_cleanup) +#define _RAND_egd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_egd) +#define _RAND_enable_fork_unsafe_buffering BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_enable_fork_unsafe_buffering) +#define _RAND_file_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_file_name) +#define _RAND_get_rand_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_get_rand_method) +#define _RAND_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_load_file) +#define _RAND_poll BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_poll) +#define _RAND_pseudo_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_pseudo_bytes) +#define _RAND_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_seed) +#define _RAND_set_rand_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_set_rand_method) +#define _RAND_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RAND_status) +#define _RC4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RC4) +#define _RC4_set_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RC4_set_key) +#define _RSAPrivateKey_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSAPrivateKey_dup) +#define _RSAPublicKey_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSAPublicKey_dup) +#define _RSAZ_1024_mod_exp_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSAZ_1024_mod_exp_avx2) +#define _RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define _RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) +#define _RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define _RSA_add_pkcs1_prefix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_add_pkcs1_prefix) +#define _RSA_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_bits) +#define _RSA_blinding_on BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_blinding_on) +#define _RSA_check_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_check_fips) +#define _RSA_check_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_check_key) +#define _RSA_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_decrypt) +#define _RSA_default_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_default_method) +#define _RSA_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_encrypt) +#define _RSA_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_flags) +#define _RSA_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_free) +#define _RSA_generate_key_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_generate_key_ex) +#define _RSA_generate_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_generate_key_fips) +#define _RSA_get0_crt_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_crt_params) +#define _RSA_get0_d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_d) +#define _RSA_get0_dmp1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_dmp1) +#define _RSA_get0_dmq1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_dmq1) +#define _RSA_get0_e BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_e) +#define _RSA_get0_factors BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_factors) +#define _RSA_get0_iqmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_iqmp) +#define _RSA_get0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_key) +#define _RSA_get0_n BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_n) +#define _RSA_get0_p BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_p) +#define _RSA_get0_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_pss_params) +#define _RSA_get0_q BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get0_q) +#define _RSA_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get_ex_data) +#define _RSA_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_get_ex_new_index) +#define _RSA_is_opaque BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_is_opaque) +#define _RSA_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define _RSA_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_public_key) +#define _RSA_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new) +#define _RSA_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new_method) +#define _RSA_padding_add_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_OAEP_mgf1) +#define _RSA_padding_add_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_PSS_mgf1) +#define _RSA_padding_add_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_1) +#define _RSA_padding_add_PKCS1_type_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_PKCS1_type_2) +#define _RSA_padding_add_none BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_add_none) +#define _RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) +#define _RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) +#define _RSA_padding_check_PKCS1_type_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_2) +#define _RSA_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_private_key) +#define _RSA_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_public_key) +#define _RSA_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_print) +#define _RSA_private_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_decrypt) +#define _RSA_private_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_encrypt) +#define _RSA_private_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_key_from_bytes) +#define _RSA_private_key_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_key_to_bytes) +#define _RSA_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_private_transform) +#define _RSA_public_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_decrypt) +#define _RSA_public_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_encrypt) +#define _RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_key_from_bytes) +#define _RSA_public_key_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_key_to_bytes) +#define _RSA_set0_crt_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_set0_crt_params) +#define _RSA_set0_factors BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_set0_factors) +#define _RSA_set0_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_set0_key) +#define _RSA_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_set_ex_data) +#define _RSA_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_sign) +#define _RSA_sign_pss_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_sign_pss_mgf1) +#define _RSA_sign_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_sign_raw) +#define _RSA_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_size) +#define _RSA_test_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_test_flags) +#define _RSA_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_up_ref) +#define _RSA_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_verify) +#define _RSA_verify_PKCS1_PSS_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_verify_PKCS1_PSS_mgf1) +#define _RSA_verify_pss_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_verify_pss_mgf1) +#define _RSA_verify_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_verify_raw) +#define _SHA1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1) +#define _SHA1_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1_Final) +#define _SHA1_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1_Init) +#define _SHA1_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1_Transform) +#define _SHA1_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1_Update) +#define _SHA224 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA224) +#define _SHA224_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA224_Final) +#define _SHA224_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA224_Init) +#define _SHA224_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA224_Update) +#define _SHA256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256) +#define _SHA256_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_Final) +#define _SHA256_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_Init) +#define _SHA256_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_Transform) +#define _SHA256_TransformBlocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_TransformBlocks) +#define _SHA256_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_Update) +#define _SHA384 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA384) +#define _SHA384_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA384_Final) +#define _SHA384_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA384_Init) +#define _SHA384_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA384_Update) +#define _SHA512 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512) +#define _SHA512_256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_256) +#define _SHA512_256_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_256_Final) +#define _SHA512_256_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_256_Init) +#define _SHA512_256_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_256_Update) +#define _SHA512_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Final) +#define _SHA512_Init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Init) +#define _SHA512_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Transform) +#define _SHA512_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Update) +#define _SIPHASH_24 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SIPHASH_24) +#define _SPAKE2_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_CTX_free) +#define _SPAKE2_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_CTX_new) +#define _SPAKE2_generate_msg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_generate_msg) +#define _SPAKE2_process_msg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_process_msg) +#define _SSL_CIPHER_description BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_description) +#define _SSL_CIPHER_get_auth_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_auth_nid) +#define _SSL_CIPHER_get_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_bits) +#define _SSL_CIPHER_get_cipher_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_cipher_nid) +#define _SSL_CIPHER_get_digest_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_digest_nid) +#define _SSL_CIPHER_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_id) +#define _SSL_CIPHER_get_kx_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_kx_name) +#define _SSL_CIPHER_get_kx_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_kx_nid) +#define _SSL_CIPHER_get_max_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_max_version) +#define _SSL_CIPHER_get_min_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_min_version) +#define _SSL_CIPHER_get_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_name) +#define _SSL_CIPHER_get_prf_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_prf_nid) +#define _SSL_CIPHER_get_protocol_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_protocol_id) +#define _SSL_CIPHER_get_rfc_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_rfc_name) +#define _SSL_CIPHER_get_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_value) +#define _SSL_CIPHER_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_get_version) +#define _SSL_CIPHER_is_aead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_is_aead) +#define _SSL_CIPHER_is_block_cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_is_block_cipher) +#define _SSL_CIPHER_standard_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CIPHER_standard_name) +#define _SSL_COMP_add_compression_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_add_compression_method) +#define _SSL_COMP_free_compression_methods BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_free_compression_methods) +#define _SSL_COMP_get0_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_get0_name) +#define _SSL_COMP_get_compression_methods BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_get_compression_methods) +#define _SSL_COMP_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_get_id) +#define _SSL_COMP_get_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_COMP_get_name) +#define _SSL_CTX_add0_chain_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add0_chain_cert) +#define _SSL_CTX_add1_chain_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add1_chain_cert) +#define _SSL_CTX_add_cert_compression_alg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add_cert_compression_alg) +#define _SSL_CTX_add_client_CA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add_client_CA) +#define _SSL_CTX_add_extra_chain_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add_extra_chain_cert) +#define _SSL_CTX_add_session BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_add_session) +#define _SSL_CTX_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_check_private_key) +#define _SSL_CTX_cipher_in_group BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_cipher_in_group) +#define _SSL_CTX_clear_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_clear_chain_certs) +#define _SSL_CTX_clear_extra_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_clear_extra_chain_certs) +#define _SSL_CTX_clear_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_clear_mode) +#define _SSL_CTX_clear_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_clear_options) +#define _SSL_CTX_enable_ocsp_stapling BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_enable_ocsp_stapling) +#define _SSL_CTX_enable_signed_cert_timestamps BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_enable_signed_cert_timestamps) +#define _SSL_CTX_enable_tls_channel_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_enable_tls_channel_id) +#define _SSL_CTX_flush_sessions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_flush_sessions) +#define _SSL_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_free) +#define _SSL_CTX_get0_certificate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get0_certificate) +#define _SSL_CTX_get0_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get0_chain) +#define _SSL_CTX_get0_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get0_chain_certs) +#define _SSL_CTX_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get0_param) +#define _SSL_CTX_get0_privatekey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get0_privatekey) +#define _SSL_CTX_get_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_cert_store) +#define _SSL_CTX_get_ciphers BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_ciphers) +#define _SSL_CTX_get_client_CA_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_client_CA_list) +#define _SSL_CTX_get_default_passwd_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_default_passwd_cb) +#define _SSL_CTX_get_default_passwd_cb_userdata BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_default_passwd_cb_userdata) +#define _SSL_CTX_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_ex_data) +#define _SSL_CTX_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_ex_new_index) +#define _SSL_CTX_get_extra_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_extra_chain_certs) +#define _SSL_CTX_get_info_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_info_callback) +#define _SSL_CTX_get_keylog_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_keylog_callback) +#define _SSL_CTX_get_max_cert_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_max_cert_list) +#define _SSL_CTX_get_max_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_max_proto_version) +#define _SSL_CTX_get_min_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_min_proto_version) +#define _SSL_CTX_get_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_mode) +#define _SSL_CTX_get_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_options) +#define _SSL_CTX_get_quiet_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_quiet_shutdown) +#define _SSL_CTX_get_read_ahead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_read_ahead) +#define _SSL_CTX_get_session_cache_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_session_cache_mode) +#define _SSL_CTX_get_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_timeout) +#define _SSL_CTX_get_tlsext_ticket_keys BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_tlsext_ticket_keys) +#define _SSL_CTX_get_verify_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_verify_callback) +#define _SSL_CTX_get_verify_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_verify_depth) +#define _SSL_CTX_get_verify_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_get_verify_mode) +#define _SSL_CTX_load_verify_locations BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_load_verify_locations) +#define _SSL_CTX_need_tmp_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_need_tmp_RSA) +#define _SSL_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_new) +#define _SSL_CTX_remove_session BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_remove_session) +#define _SSL_CTX_sess_accept BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_accept) +#define _SSL_CTX_sess_accept_good BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_accept_good) +#define _SSL_CTX_sess_accept_renegotiate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_accept_renegotiate) +#define _SSL_CTX_sess_cache_full BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_cache_full) +#define _SSL_CTX_sess_cb_hits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_cb_hits) +#define _SSL_CTX_sess_connect BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_connect) +#define _SSL_CTX_sess_connect_good BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_connect_good) +#define _SSL_CTX_sess_connect_renegotiate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_connect_renegotiate) +#define _SSL_CTX_sess_get_cache_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_get_cache_size) +#define _SSL_CTX_sess_get_get_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_get_get_cb) +#define _SSL_CTX_sess_get_new_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_get_new_cb) +#define _SSL_CTX_sess_get_remove_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_get_remove_cb) +#define _SSL_CTX_sess_hits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_hits) +#define _SSL_CTX_sess_misses BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_misses) +#define _SSL_CTX_sess_number BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_number) +#define _SSL_CTX_sess_set_cache_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_set_cache_size) +#define _SSL_CTX_sess_set_get_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_set_get_cb) +#define _SSL_CTX_sess_set_new_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_set_new_cb) +#define _SSL_CTX_sess_set_remove_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_set_remove_cb) +#define _SSL_CTX_sess_timeouts BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_sess_timeouts) +#define _SSL_CTX_set0_buffer_pool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set0_buffer_pool) +#define _SSL_CTX_set0_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set0_chain) +#define _SSL_CTX_set0_client_CAs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set0_client_CAs) +#define _SSL_CTX_set0_verify_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set0_verify_cert_store) +#define _SSL_CTX_set1_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_chain) +#define _SSL_CTX_set1_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_curves) +#define _SSL_CTX_set1_curves_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_curves_list) +#define _SSL_CTX_set1_ech_keys BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_ech_keys) +#define _SSL_CTX_set1_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_param) +#define _SSL_CTX_set1_sigalgs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_sigalgs) +#define _SSL_CTX_set1_sigalgs_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_sigalgs_list) +#define _SSL_CTX_set1_tls_channel_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_tls_channel_id) +#define _SSL_CTX_set1_verify_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set1_verify_cert_store) +#define _SSL_CTX_set_allow_unknown_alpn_protos BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_allow_unknown_alpn_protos) +#define _SSL_CTX_set_alpn_protos BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_alpn_protos) +#define _SSL_CTX_set_alpn_select_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_alpn_select_cb) +#define _SSL_CTX_set_cert_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_cert_cb) +#define _SSL_CTX_set_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_cert_store) +#define _SSL_CTX_set_cert_verify_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_cert_verify_callback) +#define _SSL_CTX_set_chain_and_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_chain_and_key) +#define _SSL_CTX_set_cipher_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_cipher_list) +#define _SSL_CTX_set_client_CA_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_client_CA_list) +#define _SSL_CTX_set_client_cert_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_client_cert_cb) +#define _SSL_CTX_set_current_time_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_current_time_cb) +#define _SSL_CTX_set_custom_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_custom_verify) +#define _SSL_CTX_set_default_passwd_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_default_passwd_cb) +#define _SSL_CTX_set_default_passwd_cb_userdata BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_default_passwd_cb_userdata) +#define _SSL_CTX_set_default_verify_paths BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_default_verify_paths) +#define _SSL_CTX_set_dos_protection_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_dos_protection_cb) +#define _SSL_CTX_set_early_data_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_early_data_enabled) +#define _SSL_CTX_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_ex_data) +#define _SSL_CTX_set_false_start_allowed_without_alpn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_false_start_allowed_without_alpn) +#define _SSL_CTX_set_grease_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_grease_enabled) +#define _SSL_CTX_set_info_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_info_callback) +#define _SSL_CTX_set_keylog_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_keylog_callback) +#define _SSL_CTX_set_max_cert_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_max_cert_list) +#define _SSL_CTX_set_max_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_max_proto_version) +#define _SSL_CTX_set_max_send_fragment BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_max_send_fragment) +#define _SSL_CTX_set_min_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_min_proto_version) +#define _SSL_CTX_set_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_mode) +#define _SSL_CTX_set_msg_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_msg_callback) +#define _SSL_CTX_set_msg_callback_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_msg_callback_arg) +#define _SSL_CTX_set_next_proto_select_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_next_proto_select_cb) +#define _SSL_CTX_set_next_protos_advertised_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_next_protos_advertised_cb) +#define _SSL_CTX_set_ocsp_response BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_ocsp_response) +#define _SSL_CTX_set_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_options) +#define _SSL_CTX_set_permute_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_permute_extensions) +#define _SSL_CTX_set_private_key_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_private_key_method) +#define _SSL_CTX_set_psk_client_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_psk_client_callback) +#define _SSL_CTX_set_psk_server_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_psk_server_callback) +#define _SSL_CTX_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_purpose) +#define _SSL_CTX_set_quic_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_quic_method) +#define _SSL_CTX_set_quiet_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_quiet_shutdown) +#define _SSL_CTX_set_read_ahead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_read_ahead) +#define _SSL_CTX_set_record_protocol_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_record_protocol_version) +#define _SSL_CTX_set_retain_only_sha256_of_client_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_retain_only_sha256_of_client_certs) +#define _SSL_CTX_set_reverify_on_resume BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_reverify_on_resume) +#define _SSL_CTX_set_select_certificate_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_select_certificate_cb) +#define _SSL_CTX_set_session_cache_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_session_cache_mode) +#define _SSL_CTX_set_session_id_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_session_id_context) +#define _SSL_CTX_set_session_psk_dhe_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_session_psk_dhe_timeout) +#define _SSL_CTX_set_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_signed_cert_timestamp_list) +#define _SSL_CTX_set_signing_algorithm_prefs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_signing_algorithm_prefs) +#define _SSL_CTX_set_srtp_profiles BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_srtp_profiles) +#define _SSL_CTX_set_strict_cipher_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_strict_cipher_list) +#define _SSL_CTX_set_ticket_aead_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_ticket_aead_method) +#define _SSL_CTX_set_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_timeout) +#define _SSL_CTX_set_tls_channel_id_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tls_channel_id_enabled) +#define _SSL_CTX_set_tlsext_servername_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_servername_arg) +#define _SSL_CTX_set_tlsext_servername_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_servername_callback) +#define _SSL_CTX_set_tlsext_status_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_status_arg) +#define _SSL_CTX_set_tlsext_status_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_status_cb) +#define _SSL_CTX_set_tlsext_ticket_key_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_ticket_key_cb) +#define _SSL_CTX_set_tlsext_ticket_keys BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_ticket_keys) +#define _SSL_CTX_set_tlsext_use_srtp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tlsext_use_srtp) +#define _SSL_CTX_set_tmp_dh BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tmp_dh) +#define _SSL_CTX_set_tmp_dh_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tmp_dh_callback) +#define _SSL_CTX_set_tmp_ecdh BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tmp_ecdh) +#define _SSL_CTX_set_tmp_rsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tmp_rsa) +#define _SSL_CTX_set_tmp_rsa_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_tmp_rsa_callback) +#define _SSL_CTX_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_trust) +#define _SSL_CTX_set_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_verify) +#define _SSL_CTX_set_verify_algorithm_prefs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_verify_algorithm_prefs) +#define _SSL_CTX_set_verify_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_set_verify_depth) +#define _SSL_CTX_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_up_ref) +#define _SSL_CTX_use_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey) +#define _SSL_CTX_use_PrivateKey_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey_ASN1) +#define _SSL_CTX_use_PrivateKey_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_PrivateKey_file) +#define _SSL_CTX_use_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey) +#define _SSL_CTX_use_RSAPrivateKey_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey_ASN1) +#define _SSL_CTX_use_RSAPrivateKey_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_RSAPrivateKey_file) +#define _SSL_CTX_use_certificate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_certificate) +#define _SSL_CTX_use_certificate_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_certificate_ASN1) +#define _SSL_CTX_use_certificate_chain_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_certificate_chain_file) +#define _SSL_CTX_use_certificate_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_certificate_file) +#define _SSL_CTX_use_psk_identity_hint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_CTX_use_psk_identity_hint) +#define _SSL_ECH_KEYS_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_add) +#define _SSL_ECH_KEYS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_free) +#define _SSL_ECH_KEYS_has_duplicate_config_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_has_duplicate_config_id) +#define _SSL_ECH_KEYS_marshal_retry_configs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_marshal_retry_configs) +#define _SSL_ECH_KEYS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_new) +#define _SSL_ECH_KEYS_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ECH_KEYS_up_ref) +#define _SSL_SESSION_copy_without_early_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_copy_without_early_data) +#define _SSL_SESSION_early_data_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_early_data_capable) +#define _SSL_SESSION_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_free) +#define _SSL_SESSION_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_from_bytes) +#define _SSL_SESSION_get0_cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_cipher) +#define _SSL_SESSION_get0_id_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_id_context) +#define _SSL_SESSION_get0_ocsp_response BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_ocsp_response) +#define _SSL_SESSION_get0_peer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_peer) +#define _SSL_SESSION_get0_peer_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_peer_certificates) +#define _SSL_SESSION_get0_peer_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_peer_sha256) +#define _SSL_SESSION_get0_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_signed_cert_timestamp_list) +#define _SSL_SESSION_get0_ticket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get0_ticket) +#define _SSL_SESSION_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_ex_data) +#define _SSL_SESSION_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_ex_new_index) +#define _SSL_SESSION_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_id) +#define _SSL_SESSION_get_master_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_master_key) +#define _SSL_SESSION_get_protocol_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_protocol_version) +#define _SSL_SESSION_get_ticket_lifetime_hint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_ticket_lifetime_hint) +#define _SSL_SESSION_get_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_time) +#define _SSL_SESSION_get_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_timeout) +#define _SSL_SESSION_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_get_version) +#define _SSL_SESSION_has_peer_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_has_peer_sha256) +#define _SSL_SESSION_has_ticket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_has_ticket) +#define _SSL_SESSION_is_resumable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_is_resumable) +#define _SSL_SESSION_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_new) +#define _SSL_SESSION_set1_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set1_id) +#define _SSL_SESSION_set1_id_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set1_id_context) +#define _SSL_SESSION_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set_ex_data) +#define _SSL_SESSION_set_protocol_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set_protocol_version) +#define _SSL_SESSION_set_ticket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set_ticket) +#define _SSL_SESSION_set_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set_time) +#define _SSL_SESSION_set_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_set_timeout) +#define _SSL_SESSION_should_be_single_use BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_should_be_single_use) +#define _SSL_SESSION_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_to_bytes) +#define _SSL_SESSION_to_bytes_for_ticket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_to_bytes_for_ticket) +#define _SSL_SESSION_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_SESSION_up_ref) +#define _SSL_accept BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_accept) +#define _SSL_add0_chain_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_add0_chain_cert) +#define _SSL_add1_chain_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_add1_chain_cert) +#define _SSL_add_application_settings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_add_application_settings) +#define _SSL_add_client_CA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_add_client_CA) +#define _SSL_add_file_cert_subjects_to_stack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_add_file_cert_subjects_to_stack) +#define _SSL_alert_desc_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_alert_desc_string) +#define _SSL_alert_desc_string_long BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_alert_desc_string_long) +#define _SSL_alert_from_verify_result BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_alert_from_verify_result) +#define _SSL_alert_type_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_alert_type_string) +#define _SSL_alert_type_string_long BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_alert_type_string_long) +#define _SSL_cache_hit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_cache_hit) +#define _SSL_can_release_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_can_release_private_key) +#define _SSL_certs_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_certs_clear) +#define _SSL_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_check_private_key) +#define _SSL_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_clear) +#define _SSL_clear_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_clear_chain_certs) +#define _SSL_clear_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_clear_mode) +#define _SSL_clear_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_clear_options) +#define _SSL_connect BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_connect) +#define _SSL_cutthrough_complete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_cutthrough_complete) +#define _SSL_delegated_credential_used BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_delegated_credential_used) +#define _SSL_do_handshake BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_do_handshake) +#define _SSL_dup_CA_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_dup_CA_list) +#define _SSL_early_callback_ctx_extension_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_early_callback_ctx_extension_get) +#define _SSL_early_data_accepted BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_early_data_accepted) +#define _SSL_early_data_reason_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_early_data_reason_string) +#define _SSL_ech_accepted BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_ech_accepted) +#define _SSL_enable_ocsp_stapling BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_enable_ocsp_stapling) +#define _SSL_enable_signed_cert_timestamps BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_enable_signed_cert_timestamps) +#define _SSL_enable_tls_channel_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_enable_tls_channel_id) +#define _SSL_error_description BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_error_description) +#define _SSL_export_keying_material BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_export_keying_material) +#define _SSL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_free) +#define _SSL_generate_key_block BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_generate_key_block) +#define _SSL_get0_alpn_selected BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_alpn_selected) +#define _SSL_get0_certificate_types BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_certificate_types) +#define _SSL_get0_chain_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_chain_certs) +#define _SSL_get0_ech_name_override BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_ech_name_override) +#define _SSL_get0_ech_retry_configs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_ech_retry_configs) +#define _SSL_get0_next_proto_negotiated BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_next_proto_negotiated) +#define _SSL_get0_ocsp_response BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_ocsp_response) +#define _SSL_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_param) +#define _SSL_get0_peer_application_settings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_peer_application_settings) +#define _SSL_get0_peer_certificates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_peer_certificates) +#define _SSL_get0_peer_delegation_algorithms BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_peer_delegation_algorithms) +#define _SSL_get0_peer_verify_algorithms BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_peer_verify_algorithms) +#define _SSL_get0_server_requested_CAs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_server_requested_CAs) +#define _SSL_get0_session_id_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_session_id_context) +#define _SSL_get0_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get0_signed_cert_timestamp_list) +#define _SSL_get1_session BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get1_session) +#define _SSL_get_SSL_CTX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_SSL_CTX) +#define _SSL_get_certificate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_certificate) +#define _SSL_get_cipher_by_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_cipher_by_value) +#define _SSL_get_cipher_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_cipher_list) +#define _SSL_get_ciphers BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ciphers) +#define _SSL_get_client_CA_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_client_CA_list) +#define _SSL_get_client_random BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_client_random) +#define _SSL_get_current_cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_current_cipher) +#define _SSL_get_current_compression BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_current_compression) +#define _SSL_get_current_expansion BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_current_expansion) +#define _SSL_get_curve_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_curve_id) +#define _SSL_get_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_curve_name) +#define _SSL_get_default_timeout BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_default_timeout) +#define _SSL_get_early_data_reason BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_early_data_reason) +#define _SSL_get_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_error) +#define _SSL_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ex_data) +#define _SSL_get_ex_data_X509_STORE_CTX_idx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ex_data_X509_STORE_CTX_idx) +#define _SSL_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ex_new_index) +#define _SSL_get_extms_support BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_extms_support) +#define _SSL_get_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_fd) +#define _SSL_get_finished BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_finished) +#define _SSL_get_info_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_info_callback) +#define _SSL_get_ivs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ivs) +#define _SSL_get_key_block_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_key_block_len) +#define _SSL_get_max_cert_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_max_cert_list) +#define _SSL_get_max_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_max_proto_version) +#define _SSL_get_min_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_min_proto_version) +#define _SSL_get_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_mode) +#define _SSL_get_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_options) +#define _SSL_get_peer_cert_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_cert_chain) +#define _SSL_get_peer_certificate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_certificate) +#define _SSL_get_peer_finished BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_finished) +#define _SSL_get_peer_full_cert_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_full_cert_chain) +#define _SSL_get_peer_quic_transport_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_quic_transport_params) +#define _SSL_get_peer_signature_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_peer_signature_algorithm) +#define _SSL_get_pending_cipher BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_pending_cipher) +#define _SSL_get_privatekey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_privatekey) +#define _SSL_get_psk_identity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_psk_identity) +#define _SSL_get_psk_identity_hint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_psk_identity_hint) +#define _SSL_get_quiet_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_quiet_shutdown) +#define _SSL_get_rbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_rbio) +#define _SSL_get_read_ahead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_read_ahead) +#define _SSL_get_read_sequence BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_read_sequence) +#define _SSL_get_rfd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_rfd) +#define _SSL_get_secure_renegotiation_support BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_secure_renegotiation_support) +#define _SSL_get_selected_srtp_profile BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_selected_srtp_profile) +#define _SSL_get_server_random BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_server_random) +#define _SSL_get_server_tmp_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_server_tmp_key) +#define _SSL_get_servername BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_servername) +#define _SSL_get_servername_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_servername_type) +#define _SSL_get_session BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_session) +#define _SSL_get_shared_ciphers BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_shared_ciphers) +#define _SSL_get_shared_sigalgs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_shared_sigalgs) +#define _SSL_get_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_shutdown) +#define _SSL_get_signature_algorithm_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_signature_algorithm_digest) +#define _SSL_get_signature_algorithm_key_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_signature_algorithm_key_type) +#define _SSL_get_signature_algorithm_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_signature_algorithm_name) +#define _SSL_get_srtp_profiles BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_srtp_profiles) +#define _SSL_get_ticket_age_skew BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_ticket_age_skew) +#define _SSL_get_tls_channel_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_tls_channel_id) +#define _SSL_get_tls_unique BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_tls_unique) +#define _SSL_get_tlsext_status_ocsp_resp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_tlsext_status_ocsp_resp) +#define _SSL_get_tlsext_status_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_tlsext_status_type) +#define _SSL_get_verify_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_verify_callback) +#define _SSL_get_verify_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_verify_depth) +#define _SSL_get_verify_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_verify_mode) +#define _SSL_get_verify_result BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_verify_result) +#define _SSL_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_version) +#define _SSL_get_wbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_wbio) +#define _SSL_get_wfd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_wfd) +#define _SSL_get_write_sequence BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_get_write_sequence) +#define _SSL_has_application_settings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_has_application_settings) +#define _SSL_has_pending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_has_pending) +#define _SSL_in_early_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_in_early_data) +#define _SSL_in_false_start BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_in_false_start) +#define _SSL_in_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_in_init) +#define _SSL_is_dtls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_is_dtls) +#define _SSL_is_init_finished BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_is_init_finished) +#define _SSL_is_server BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_is_server) +#define _SSL_is_signature_algorithm_rsa_pss BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_is_signature_algorithm_rsa_pss) +#define _SSL_key_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_key_update) +#define _SSL_library_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_library_init) +#define _SSL_load_client_CA_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_load_client_CA_file) +#define _SSL_load_error_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_load_error_strings) +#define _SSL_magic_pending_session_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_magic_pending_session_ptr) +#define _SSL_marshal_ech_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_marshal_ech_config) +#define _SSL_max_seal_overhead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_max_seal_overhead) +#define _SSL_need_tmp_RSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_need_tmp_RSA) +#define _SSL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_new) +#define _SSL_num_renegotiations BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_num_renegotiations) +#define _SSL_peek BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_peek) +#define _SSL_pending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_pending) +#define _SSL_process_quic_post_handshake BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_process_quic_post_handshake) +#define _SSL_process_tls13_new_session_ticket BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_process_tls13_new_session_ticket) +#define _SSL_provide_quic_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_provide_quic_data) +#define _SSL_quic_max_handshake_flight_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_quic_max_handshake_flight_len) +#define _SSL_quic_read_level BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_quic_read_level) +#define _SSL_quic_write_level BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_quic_write_level) +#define _SSL_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_read) +#define _SSL_renegotiate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_renegotiate) +#define _SSL_renegotiate_pending BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_renegotiate_pending) +#define _SSL_request_handshake_hints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_request_handshake_hints) +#define _SSL_reset_early_data_reject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_reset_early_data_reject) +#define _SSL_select_next_proto BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_select_next_proto) +#define _SSL_send_fatal_alert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_send_fatal_alert) +#define _SSL_serialize_capabilities BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_serialize_capabilities) +#define _SSL_serialize_handshake_hints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_serialize_handshake_hints) +#define _SSL_session_reused BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_session_reused) +#define _SSL_set0_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set0_chain) +#define _SSL_set0_client_CAs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set0_client_CAs) +#define _SSL_set0_rbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set0_rbio) +#define _SSL_set0_verify_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set0_verify_cert_store) +#define _SSL_set0_wbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set0_wbio) +#define _SSL_set1_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_chain) +#define _SSL_set1_curves BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_curves) +#define _SSL_set1_curves_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_curves_list) +#define _SSL_set1_delegated_credential BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_delegated_credential) +#define _SSL_set1_ech_config_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_ech_config_list) +#define _SSL_set1_host BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_host) +#define _SSL_set1_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_param) +#define _SSL_set1_sigalgs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_sigalgs) +#define _SSL_set1_sigalgs_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_sigalgs_list) +#define _SSL_set1_tls_channel_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_tls_channel_id) +#define _SSL_set1_verify_cert_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set1_verify_cert_store) +#define _SSL_set_SSL_CTX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_SSL_CTX) +#define _SSL_set_accept_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_accept_state) +#define _SSL_set_alpn_protos BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_alpn_protos) +#define _SSL_set_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_bio) +#define _SSL_set_cert_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_cert_cb) +#define _SSL_set_chain_and_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_chain_and_key) +#define _SSL_set_cipher_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_cipher_list) +#define _SSL_set_client_CA_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_client_CA_list) +#define _SSL_set_connect_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_connect_state) +#define _SSL_set_custom_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_custom_verify) +#define _SSL_set_early_data_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_early_data_enabled) +#define _SSL_set_enable_ech_grease BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_enable_ech_grease) +#define _SSL_set_enforce_rsa_key_usage BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_enforce_rsa_key_usage) +#define _SSL_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_ex_data) +#define _SSL_set_fd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_fd) +#define _SSL_set_handshake_hints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_handshake_hints) +#define _SSL_set_hostflags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_hostflags) +#define _SSL_set_info_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_info_callback) +#define _SSL_set_jdk11_workaround BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_jdk11_workaround) +#define _SSL_set_max_cert_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_max_cert_list) +#define _SSL_set_max_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_max_proto_version) +#define _SSL_set_max_send_fragment BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_max_send_fragment) +#define _SSL_set_min_proto_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_min_proto_version) +#define _SSL_set_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_mode) +#define _SSL_set_msg_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_msg_callback) +#define _SSL_set_msg_callback_arg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_msg_callback_arg) +#define _SSL_set_mtu BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_mtu) +#define _SSL_set_ocsp_response BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_ocsp_response) +#define _SSL_set_options BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_options) +#define _SSL_set_permute_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_permute_extensions) +#define _SSL_set_private_key_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_private_key_method) +#define _SSL_set_psk_client_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_psk_client_callback) +#define _SSL_set_psk_server_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_psk_server_callback) +#define _SSL_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_purpose) +#define _SSL_set_quic_early_data_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_quic_early_data_context) +#define _SSL_set_quic_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_quic_method) +#define _SSL_set_quic_transport_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_quic_transport_params) +#define _SSL_set_quic_use_legacy_codepoint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_quic_use_legacy_codepoint) +#define _SSL_set_quiet_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_quiet_shutdown) +#define _SSL_set_read_ahead BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_read_ahead) +#define _SSL_set_renegotiate_mode BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_renegotiate_mode) +#define _SSL_set_retain_only_sha256_of_client_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_retain_only_sha256_of_client_certs) +#define _SSL_set_rfd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_rfd) +#define _SSL_set_session BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_session) +#define _SSL_set_session_id_context BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_session_id_context) +#define _SSL_set_shed_handshake_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_shed_handshake_config) +#define _SSL_set_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_shutdown) +#define _SSL_set_signed_cert_timestamp_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_signed_cert_timestamp_list) +#define _SSL_set_signing_algorithm_prefs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_signing_algorithm_prefs) +#define _SSL_set_srtp_profiles BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_srtp_profiles) +#define _SSL_set_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_state) +#define _SSL_set_strict_cipher_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_strict_cipher_list) +#define _SSL_set_tls_channel_id_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tls_channel_id_enabled) +#define _SSL_set_tlsext_host_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tlsext_host_name) +#define _SSL_set_tlsext_status_ocsp_resp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tlsext_status_ocsp_resp) +#define _SSL_set_tlsext_status_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tlsext_status_type) +#define _SSL_set_tlsext_use_srtp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tlsext_use_srtp) +#define _SSL_set_tmp_dh BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tmp_dh) +#define _SSL_set_tmp_dh_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tmp_dh_callback) +#define _SSL_set_tmp_ecdh BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tmp_ecdh) +#define _SSL_set_tmp_rsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tmp_rsa) +#define _SSL_set_tmp_rsa_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_tmp_rsa_callback) +#define _SSL_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_trust) +#define _SSL_set_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_verify) +#define _SSL_set_verify_algorithm_prefs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_verify_algorithm_prefs) +#define _SSL_set_verify_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_verify_depth) +#define _SSL_set_wfd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_set_wfd) +#define _SSL_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_shutdown) +#define _SSL_state BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_state) +#define _SSL_state_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_state_string) +#define _SSL_state_string_long BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_state_string_long) +#define _SSL_total_renegotiations BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_total_renegotiations) +#define _SSL_use_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_PrivateKey) +#define _SSL_use_PrivateKey_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_PrivateKey_ASN1) +#define _SSL_use_PrivateKey_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_PrivateKey_file) +#define _SSL_use_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey) +#define _SSL_use_RSAPrivateKey_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey_ASN1) +#define _SSL_use_RSAPrivateKey_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_RSAPrivateKey_file) +#define _SSL_use_certificate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_certificate) +#define _SSL_use_certificate_ASN1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_certificate_ASN1) +#define _SSL_use_certificate_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_certificate_file) +#define _SSL_use_psk_identity_hint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_use_psk_identity_hint) +#define _SSL_used_hello_retry_request BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_used_hello_retry_request) +#define _SSL_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_version) +#define _SSL_want BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_want) +#define _SSL_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSL_write) +#define _SSLeay BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLeay) +#define _SSLeay_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLeay_version) +#define _SSLv23_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLv23_client_method) +#define _SSLv23_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLv23_method) +#define _SSLv23_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SSLv23_server_method) +#define _TLS_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLS_client_method) +#define _TLS_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLS_method) +#define _TLS_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLS_server_method) +#define _TLS_with_buffers_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLS_with_buffers_method) +#define _TLSv1_1_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_1_client_method) +#define _TLSv1_1_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_1_method) +#define _TLSv1_1_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_1_server_method) +#define _TLSv1_2_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_2_client_method) +#define _TLSv1_2_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_2_method) +#define _TLSv1_2_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_2_server_method) +#define _TLSv1_client_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_client_method) +#define _TLSv1_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_method) +#define _TLSv1_server_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TLSv1_server_method) +#define _TRUST_TOKEN_CLIENT_add_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_add_key) +#define _TRUST_TOKEN_CLIENT_begin_issuance BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_issuance) +#define _TRUST_TOKEN_CLIENT_begin_redemption BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_begin_redemption) +#define _TRUST_TOKEN_CLIENT_finish_issuance BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_issuance) +#define _TRUST_TOKEN_CLIENT_finish_redemption BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_finish_redemption) +#define _TRUST_TOKEN_CLIENT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_free) +#define _TRUST_TOKEN_CLIENT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_new) +#define _TRUST_TOKEN_CLIENT_set_srr_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_CLIENT_set_srr_key) +#define _TRUST_TOKEN_ISSUER_add_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_add_key) +#define _TRUST_TOKEN_ISSUER_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_free) +#define _TRUST_TOKEN_ISSUER_issue BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_issue) +#define _TRUST_TOKEN_ISSUER_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_new) +#define _TRUST_TOKEN_ISSUER_redeem BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem) +#define _TRUST_TOKEN_ISSUER_redeem_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_redeem_raw) +#define _TRUST_TOKEN_ISSUER_set_metadata_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_metadata_key) +#define _TRUST_TOKEN_ISSUER_set_srr_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_ISSUER_set_srr_key) +#define _TRUST_TOKEN_PRETOKEN_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_PRETOKEN_free) +#define _TRUST_TOKEN_decode_private_metadata BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_decode_private_metadata) +#define _TRUST_TOKEN_experiment_v1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v1) +#define _TRUST_TOKEN_experiment_v2_pmb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v2_pmb) +#define _TRUST_TOKEN_experiment_v2_voprf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_experiment_v2_voprf) +#define _TRUST_TOKEN_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_free) +#define _TRUST_TOKEN_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_generate_key) +#define _TRUST_TOKEN_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, TRUST_TOKEN_new) +#define _USERNOTICE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_free) +#define _USERNOTICE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_it) +#define _USERNOTICE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_new) +#define _UTF8_getc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, UTF8_getc) +#define _UTF8_putc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, UTF8_putc) +#define _X25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519) +#define _X25519_keypair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_keypair) +#define _X25519_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_public_from_private) +#define _X509V3_EXT_CRL_add_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_CRL_add_nconf) +#define _X509V3_EXT_REQ_add_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_REQ_add_nconf) +#define _X509V3_EXT_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_add) +#define _X509V3_EXT_add_alias BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_add_alias) +#define _X509V3_EXT_add_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_add_list) +#define _X509V3_EXT_add_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_add_nconf) +#define _X509V3_EXT_add_nconf_sk BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_add_nconf_sk) +#define _X509V3_EXT_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_cleanup) +#define _X509V3_EXT_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_d2i) +#define _X509V3_EXT_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_free) +#define _X509V3_EXT_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_get) +#define _X509V3_EXT_get_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_get_nid) +#define _X509V3_EXT_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_i2d) +#define _X509V3_EXT_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_nconf) +#define _X509V3_EXT_nconf_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_nconf_nid) +#define _X509V3_EXT_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_print) +#define _X509V3_EXT_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_print_fp) +#define _X509V3_EXT_val_prn BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_EXT_val_prn) +#define _X509V3_NAME_from_section BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_NAME_from_section) +#define _X509V3_add1_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add1_i2d) +#define _X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_standard_extensions) +#define _X509V3_add_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value) +#define _X509V3_add_value_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_bool) +#define _X509V3_add_value_bool_nf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_bool_nf) +#define _X509V3_add_value_int BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_int) +#define _X509V3_add_value_uchar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_value_uchar) +#define _X509V3_conf_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_conf_free) +#define _X509V3_extensions_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_extensions_print) +#define _X509V3_get_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_d2i) +#define _X509V3_get_section BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_section) +#define _X509V3_get_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_string) +#define _X509V3_get_value_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_value_bool) +#define _X509V3_get_value_int BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_get_value_int) +#define _X509V3_parse_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_parse_list) +#define _X509V3_section_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_section_free) +#define _X509V3_set_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_set_ctx) +#define _X509V3_set_nconf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_set_nconf) +#define _X509V3_string_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_string_free) +#define _X509_ALGORS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGORS_it) +#define _X509_ALGOR_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define _X509_ALGOR_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_dup) +#define _X509_ALGOR_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_free) +#define _X509_ALGOR_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define _X509_ALGOR_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_it) +#define _X509_ALGOR_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_new) +#define _X509_ALGOR_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_set0) +#define _X509_ALGOR_set_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_set_md) +#define _X509_ATTRIBUTE_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_count) +#define _X509_ATTRIBUTE_create BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_create) +#define _X509_ATTRIBUTE_create_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_NID) +#define _X509_ATTRIBUTE_create_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_OBJ) +#define _X509_ATTRIBUTE_create_by_txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_create_by_txt) +#define _X509_ATTRIBUTE_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_dup) +#define _X509_ATTRIBUTE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_free) +#define _X509_ATTRIBUTE_get0_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_data) +#define _X509_ATTRIBUTE_get0_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_object) +#define _X509_ATTRIBUTE_get0_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_get0_type) +#define _X509_ATTRIBUTE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_it) +#define _X509_ATTRIBUTE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_new) +#define _X509_ATTRIBUTE_set1_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_set1_data) +#define _X509_ATTRIBUTE_set1_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ATTRIBUTE_set1_object) +#define _X509_CERT_AUX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CERT_AUX_free) +#define _X509_CERT_AUX_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CERT_AUX_it) +#define _X509_CERT_AUX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CERT_AUX_new) +#define _X509_CERT_AUX_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CERT_AUX_print) +#define _X509_CINF_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_free) +#define _X509_CINF_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_it) +#define _X509_CINF_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_new) +#define _X509_CRL_INFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_INFO_free) +#define _X509_CRL_INFO_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_INFO_it) +#define _X509_CRL_INFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_INFO_new) +#define _X509_CRL_METHOD_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_METHOD_free) +#define _X509_CRL_METHOD_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_METHOD_new) +#define _X509_CRL_add0_revoked BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_add0_revoked) +#define _X509_CRL_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_add1_ext_i2d) +#define _X509_CRL_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_add_ext) +#define _X509_CRL_check_suiteb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_check_suiteb) +#define _X509_CRL_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_cmp) +#define _X509_CRL_delete_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_delete_ext) +#define _X509_CRL_diff BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_diff) +#define _X509_CRL_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_digest) +#define _X509_CRL_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_dup) +#define _X509_CRL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_free) +#define _X509_CRL_get0_by_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_by_cert) +#define _X509_CRL_get0_by_serial BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_by_serial) +#define _X509_CRL_get0_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_extensions) +#define _X509_CRL_get0_lastUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_lastUpdate) +#define _X509_CRL_get0_nextUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_nextUpdate) +#define _X509_CRL_get0_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get0_signature) +#define _X509_CRL_get_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_REVOKED) +#define _X509_CRL_get_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext) +#define _X509_CRL_get_ext_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext_by_NID) +#define _X509_CRL_get_ext_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext_by_OBJ) +#define _X509_CRL_get_ext_by_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext_by_critical) +#define _X509_CRL_get_ext_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext_count) +#define _X509_CRL_get_ext_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_ext_d2i) +#define _X509_CRL_get_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_issuer) +#define _X509_CRL_get_lastUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_lastUpdate) +#define _X509_CRL_get_meth_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_meth_data) +#define _X509_CRL_get_nextUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_nextUpdate) +#define _X509_CRL_get_signature_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_signature_nid) +#define _X509_CRL_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_get_version) +#define _X509_CRL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_it) +#define _X509_CRL_match BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_match) +#define _X509_CRL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_new) +#define _X509_CRL_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_print) +#define _X509_CRL_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_print_fp) +#define _X509_CRL_set1_lastUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set1_lastUpdate) +#define _X509_CRL_set1_nextUpdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set1_nextUpdate) +#define _X509_CRL_set1_signature_algo BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set1_signature_algo) +#define _X509_CRL_set1_signature_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set1_signature_value) +#define _X509_CRL_set_default_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set_default_method) +#define _X509_CRL_set_issuer_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set_issuer_name) +#define _X509_CRL_set_meth_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set_meth_data) +#define _X509_CRL_set_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_set_version) +#define _X509_CRL_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_sign) +#define _X509_CRL_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_sign_ctx) +#define _X509_CRL_sort BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_sort) +#define _X509_CRL_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_up_ref) +#define _X509_CRL_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CRL_verify) +#define _X509_EXTENSIONS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSIONS_it) +#define _X509_EXTENSION_create_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_create_by_NID) +#define _X509_EXTENSION_create_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_create_by_OBJ) +#define _X509_EXTENSION_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_dup) +#define _X509_EXTENSION_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_free) +#define _X509_EXTENSION_get_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_get_critical) +#define _X509_EXTENSION_get_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_get_data) +#define _X509_EXTENSION_get_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_get_object) +#define _X509_EXTENSION_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_it) +#define _X509_EXTENSION_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_new) +#define _X509_EXTENSION_set_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_set_critical) +#define _X509_EXTENSION_set_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_set_data) +#define _X509_EXTENSION_set_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_EXTENSION_set_object) +#define _X509_INFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_INFO_free) +#define _X509_INFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_INFO_new) +#define _X509_LOOKUP_by_alias BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_by_alias) +#define _X509_LOOKUP_by_fingerprint BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_by_fingerprint) +#define _X509_LOOKUP_by_issuer_serial BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_by_issuer_serial) +#define _X509_LOOKUP_by_subject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_by_subject) +#define _X509_LOOKUP_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_ctrl) +#define _X509_LOOKUP_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_file) +#define _X509_LOOKUP_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_free) +#define _X509_LOOKUP_hash_dir BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_hash_dir) +#define _X509_LOOKUP_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_init) +#define _X509_LOOKUP_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_new) +#define _X509_LOOKUP_shutdown BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_shutdown) +#define _X509_NAME_ENTRIES_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRIES_it) +#define _X509_NAME_ENTRY_create_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_NID) +#define _X509_NAME_ENTRY_create_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_OBJ) +#define _X509_NAME_ENTRY_create_by_txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_create_by_txt) +#define _X509_NAME_ENTRY_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_dup) +#define _X509_NAME_ENTRY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_free) +#define _X509_NAME_ENTRY_get_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_get_data) +#define _X509_NAME_ENTRY_get_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_get_object) +#define _X509_NAME_ENTRY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_it) +#define _X509_NAME_ENTRY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_new) +#define _X509_NAME_ENTRY_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_set) +#define _X509_NAME_ENTRY_set_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_set_data) +#define _X509_NAME_ENTRY_set_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_ENTRY_set_object) +#define _X509_NAME_INTERNAL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_INTERNAL_it) +#define _X509_NAME_add_entry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry) +#define _X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) +#define _X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) +#define _X509_NAME_add_entry_by_txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_txt) +#define _X509_NAME_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_cmp) +#define _X509_NAME_delete_entry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_delete_entry) +#define _X509_NAME_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_digest) +#define _X509_NAME_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_dup) +#define _X509_NAME_entry_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_entry_count) +#define _X509_NAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_free) +#define _X509_NAME_get0_der BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get0_der) +#define _X509_NAME_get_entry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get_entry) +#define _X509_NAME_get_index_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get_index_by_NID) +#define _X509_NAME_get_index_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get_index_by_OBJ) +#define _X509_NAME_get_text_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get_text_by_NID) +#define _X509_NAME_get_text_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_get_text_by_OBJ) +#define _X509_NAME_hash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_hash) +#define _X509_NAME_hash_old BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_hash_old) +#define _X509_NAME_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_it) +#define _X509_NAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_new) +#define _X509_NAME_oneline BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_oneline) +#define _X509_NAME_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_print) +#define _X509_NAME_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_print_ex) +#define _X509_NAME_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_print_ex_fp) +#define _X509_NAME_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_set) +#define _X509_OBJECT_free_contents BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_free_contents) +#define _X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) +#define _X509_OBJECT_get_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get_type) +#define _X509_OBJECT_idx_by_subject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_idx_by_subject) +#define _X509_OBJECT_retrieve_by_subject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_retrieve_by_subject) +#define _X509_OBJECT_retrieve_match BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_retrieve_match) +#define _X509_OBJECT_up_ref_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_up_ref_count) +#define _X509_PKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PKEY_free) +#define _X509_PKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PKEY_new) +#define _X509_POLICY_NODE_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_POLICY_NODE_print) +#define _X509_PUBKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_free) +#define _X509_PUBKEY_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get) +#define _X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) +#define _X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define _X509_PUBKEY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_it) +#define _X509_PUBKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_new) +#define _X509_PUBKEY_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set) +#define _X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define _X509_PURPOSE_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_add) +#define _X509_PURPOSE_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_cleanup) +#define _X509_PURPOSE_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get0) +#define _X509_PURPOSE_get0_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get0_name) +#define _X509_PURPOSE_get0_sname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get0_sname) +#define _X509_PURPOSE_get_by_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_by_id) +#define _X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) +#define _X509_PURPOSE_get_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_count) +#define _X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_id) +#define _X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) +#define _X509_PURPOSE_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_set) +#define _X509_REQ_INFO_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_INFO_free) +#define _X509_REQ_INFO_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_INFO_it) +#define _X509_REQ_INFO_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_INFO_new) +#define _X509_REQ_add1_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add1_attr) +#define _X509_REQ_add1_attr_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_NID) +#define _X509_REQ_add1_attr_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_OBJ) +#define _X509_REQ_add1_attr_by_txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add1_attr_by_txt) +#define _X509_REQ_add_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add_extensions) +#define _X509_REQ_add_extensions_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_add_extensions_nid) +#define _X509_REQ_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_check_private_key) +#define _X509_REQ_delete_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_delete_attr) +#define _X509_REQ_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_digest) +#define _X509_REQ_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_dup) +#define _X509_REQ_extension_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_extension_nid) +#define _X509_REQ_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_free) +#define _X509_REQ_get0_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get0_signature) +#define _X509_REQ_get1_email BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get1_email) +#define _X509_REQ_get_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_attr) +#define _X509_REQ_get_attr_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_attr_by_NID) +#define _X509_REQ_get_attr_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_attr_by_OBJ) +#define _X509_REQ_get_attr_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_attr_count) +#define _X509_REQ_get_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_extensions) +#define _X509_REQ_get_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_pubkey) +#define _X509_REQ_get_signature_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_signature_nid) +#define _X509_REQ_get_subject_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_subject_name) +#define _X509_REQ_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_get_version) +#define _X509_REQ_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_it) +#define _X509_REQ_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_new) +#define _X509_REQ_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_print) +#define _X509_REQ_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_print_ex) +#define _X509_REQ_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_print_fp) +#define _X509_REQ_set_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_set_pubkey) +#define _X509_REQ_set_subject_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_set_subject_name) +#define _X509_REQ_set_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_set_version) +#define _X509_REQ_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_sign) +#define _X509_REQ_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_sign_ctx) +#define _X509_REQ_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REQ_verify) +#define _X509_REVOKED_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_add1_ext_i2d) +#define _X509_REVOKED_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_add_ext) +#define _X509_REVOKED_delete_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_delete_ext) +#define _X509_REVOKED_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_dup) +#define _X509_REVOKED_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_free) +#define _X509_REVOKED_get0_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get0_extensions) +#define _X509_REVOKED_get0_revocationDate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get0_revocationDate) +#define _X509_REVOKED_get0_serialNumber BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get0_serialNumber) +#define _X509_REVOKED_get_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext) +#define _X509_REVOKED_get_ext_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_NID) +#define _X509_REVOKED_get_ext_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_OBJ) +#define _X509_REVOKED_get_ext_by_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext_by_critical) +#define _X509_REVOKED_get_ext_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext_count) +#define _X509_REVOKED_get_ext_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_get_ext_d2i) +#define _X509_REVOKED_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_it) +#define _X509_REVOKED_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_new) +#define _X509_REVOKED_set_revocationDate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_set_revocationDate) +#define _X509_REVOKED_set_serialNumber BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_REVOKED_set_serialNumber) +#define _X509_SIG_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_free) +#define _X509_SIG_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_get0) +#define _X509_SIG_getm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_getm) +#define _X509_SIG_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_it) +#define _X509_SIG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_new) +#define _X509_STORE_CTX_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_cleanup) +#define _X509_STORE_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_free) +#define _X509_STORE_CTX_get0_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_cert) +#define _X509_STORE_CTX_get0_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_chain) +#define _X509_STORE_CTX_get0_current_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_current_crl) +#define _X509_STORE_CTX_get0_current_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_current_issuer) +#define _X509_STORE_CTX_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_param) +#define _X509_STORE_CTX_get0_parent_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_parent_ctx) +#define _X509_STORE_CTX_get0_policy_tree BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_policy_tree) +#define _X509_STORE_CTX_get0_store BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_store) +#define _X509_STORE_CTX_get0_untrusted BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get0_untrusted) +#define _X509_STORE_CTX_get1_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get1_chain) +#define _X509_STORE_CTX_get1_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get1_issuer) +#define _X509_STORE_CTX_get_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_chain) +#define _X509_STORE_CTX_get_current_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_current_cert) +#define _X509_STORE_CTX_get_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_error) +#define _X509_STORE_CTX_get_error_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_error_depth) +#define _X509_STORE_CTX_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_ex_data) +#define _X509_STORE_CTX_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_ex_new_index) +#define _X509_STORE_CTX_get_explicit_policy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_get_explicit_policy) +#define _X509_STORE_CTX_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_init) +#define _X509_STORE_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_new) +#define _X509_STORE_CTX_purpose_inherit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_purpose_inherit) +#define _X509_STORE_CTX_set0_crls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set0_crls) +#define _X509_STORE_CTX_set0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set0_param) +#define _X509_STORE_CTX_set_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_cert) +#define _X509_STORE_CTX_set_chain BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_chain) +#define _X509_STORE_CTX_set_default BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_default) +#define _X509_STORE_CTX_set_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_depth) +#define _X509_STORE_CTX_set_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_error) +#define _X509_STORE_CTX_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_ex_data) +#define _X509_STORE_CTX_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_flags) +#define _X509_STORE_CTX_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_purpose) +#define _X509_STORE_CTX_set_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_time) +#define _X509_STORE_CTX_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_trust) +#define _X509_STORE_CTX_set_verify_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_set_verify_cb) +#define _X509_STORE_CTX_trusted_stack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_trusted_stack) +#define _X509_STORE_CTX_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_CTX_zero) +#define _X509_STORE_add_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_add_cert) +#define _X509_STORE_add_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_add_crl) +#define _X509_STORE_add_lookup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_add_lookup) +#define _X509_STORE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_free) +#define _X509_STORE_get0_objects BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get0_objects) +#define _X509_STORE_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get0_param) +#define _X509_STORE_get1_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get1_certs) +#define _X509_STORE_get1_crls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get1_crls) +#define _X509_STORE_get_by_subject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_by_subject) +#define _X509_STORE_get_cert_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_cert_crl) +#define _X509_STORE_get_check_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_check_crl) +#define _X509_STORE_get_check_issued BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_check_issued) +#define _X509_STORE_get_check_revocation BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_check_revocation) +#define _X509_STORE_get_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_cleanup) +#define _X509_STORE_get_get_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_get_crl) +#define _X509_STORE_get_get_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_get_issuer) +#define _X509_STORE_get_lookup_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_lookup_certs) +#define _X509_STORE_get_lookup_crls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_lookup_crls) +#define _X509_STORE_get_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_verify) +#define _X509_STORE_get_verify_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_get_verify_cb) +#define _X509_STORE_load_locations BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_load_locations) +#define _X509_STORE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_new) +#define _X509_STORE_set1_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set1_param) +#define _X509_STORE_set_cert_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_cert_crl) +#define _X509_STORE_set_check_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_check_crl) +#define _X509_STORE_set_check_issued BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_check_issued) +#define _X509_STORE_set_check_revocation BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_check_revocation) +#define _X509_STORE_set_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_cleanup) +#define _X509_STORE_set_default_paths BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_default_paths) +#define _X509_STORE_set_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_depth) +#define _X509_STORE_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_flags) +#define _X509_STORE_set_get_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_get_crl) +#define _X509_STORE_set_get_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_get_issuer) +#define _X509_STORE_set_lookup_certs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_lookup_certs) +#define _X509_STORE_set_lookup_crls BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_lookup_crls) +#define _X509_STORE_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_purpose) +#define _X509_STORE_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_trust) +#define _X509_STORE_set_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_verify) +#define _X509_STORE_set_verify_cb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_set_verify_cb) +#define _X509_STORE_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_up_ref) +#define _X509_TRUST_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_add) +#define _X509_TRUST_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_cleanup) +#define _X509_TRUST_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get0) +#define _X509_TRUST_get0_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get0_name) +#define _X509_TRUST_get_by_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get_by_id) +#define _X509_TRUST_get_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get_count) +#define _X509_TRUST_get_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get_flags) +#define _X509_TRUST_get_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_get_trust) +#define _X509_TRUST_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_TRUST_set) +#define _X509_VAL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_free) +#define _X509_VAL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_it) +#define _X509_VAL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_new) +#define _X509_VERIFY_PARAM_add0_policy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_policy) +#define _X509_VERIFY_PARAM_add0_table BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add0_table) +#define _X509_VERIFY_PARAM_add1_host BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_add1_host) +#define _X509_VERIFY_PARAM_clear_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_clear_flags) +#define _X509_VERIFY_PARAM_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_free) +#define _X509_VERIFY_PARAM_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0) +#define _X509_VERIFY_PARAM_get0_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_name) +#define _X509_VERIFY_PARAM_get0_peername BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get0_peername) +#define _X509_VERIFY_PARAM_get_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_count) +#define _X509_VERIFY_PARAM_get_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_depth) +#define _X509_VERIFY_PARAM_get_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_get_flags) +#define _X509_VERIFY_PARAM_inherit BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_inherit) +#define _X509_VERIFY_PARAM_lookup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_lookup) +#define _X509_VERIFY_PARAM_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_new) +#define _X509_VERIFY_PARAM_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1) +#define _X509_VERIFY_PARAM_set1_email BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_email) +#define _X509_VERIFY_PARAM_set1_host BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_host) +#define _X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) +#define _X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) +#define _X509_VERIFY_PARAM_set1_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_name) +#define _X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define _X509_VERIFY_PARAM_set_depth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_depth) +#define _X509_VERIFY_PARAM_set_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_flags) +#define _X509_VERIFY_PARAM_set_hostflags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_hostflags) +#define _X509_VERIFY_PARAM_set_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_purpose) +#define _X509_VERIFY_PARAM_set_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_time) +#define _X509_VERIFY_PARAM_set_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set_trust) +#define _X509_VERIFY_PARAM_table_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_table_cleanup) +#define _X509_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_ext_i2d) +#define _X509_add1_reject_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_reject_object) +#define _X509_add1_trust_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_trust_object) +#define _X509_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add_ext) +#define _X509_alias_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_alias_get0) +#define _X509_alias_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_alias_set1) +#define _X509_chain_check_suiteb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_chain_check_suiteb) +#define _X509_chain_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_chain_up_ref) +#define _X509_check_akid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_akid) +#define _X509_check_ca BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_ca) +#define _X509_check_email BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_email) +#define _X509_check_host BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_host) +#define _X509_check_ip BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_ip) +#define _X509_check_ip_asc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_ip_asc) +#define _X509_check_issued BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_issued) +#define _X509_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_private_key) +#define _X509_check_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_purpose) +#define _X509_check_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_trust) +#define _X509_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp) +#define _X509_cmp_current_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_current_time) +#define _X509_cmp_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_time) +#define _X509_delete_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_delete_ext) +#define _X509_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_digest) +#define _X509_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_dup) +#define _X509_email_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_email_free) +#define _X509_find_by_issuer_and_serial BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_find_by_issuer_and_serial) +#define _X509_find_by_subject BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_find_by_subject) +#define _X509_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_free) +#define _X509_get0_authority_issuer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_authority_issuer) +#define _X509_get0_authority_key_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_authority_key_id) +#define _X509_get0_authority_serial BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_authority_serial) +#define _X509_get0_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_extensions) +#define _X509_get0_notAfter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_notAfter) +#define _X509_get0_notBefore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_notBefore) +#define _X509_get0_pubkey_bitstr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_pubkey_bitstr) +#define _X509_get0_serialNumber BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_serialNumber) +#define _X509_get0_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_signature) +#define _X509_get0_subject_key_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_subject_key_id) +#define _X509_get0_tbs_sigalg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_tbs_sigalg) +#define _X509_get0_uids BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get0_uids) +#define _X509_get1_email BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get1_email) +#define _X509_get1_ocsp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get1_ocsp) +#define _X509_get_X509_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_X509_PUBKEY) +#define _X509_get_default_cert_area BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_cert_area) +#define _X509_get_default_cert_dir BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_cert_dir) +#define _X509_get_default_cert_dir_env BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_cert_dir_env) +#define _X509_get_default_cert_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_cert_file) +#define _X509_get_default_cert_file_env BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_cert_file_env) +#define _X509_get_default_private_dir BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_default_private_dir) +#define _X509_get_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ex_data) +#define _X509_get_ex_new_index BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ex_new_index) +#define _X509_get_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext) +#define _X509_get_ext_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext_by_NID) +#define _X509_get_ext_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext_by_OBJ) +#define _X509_get_ext_by_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext_by_critical) +#define _X509_get_ext_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext_count) +#define _X509_get_ext_d2i BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_ext_d2i) +#define _X509_get_extended_key_usage BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_extended_key_usage) +#define _X509_get_extension_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_extension_flags) +#define _X509_get_issuer_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_issuer_name) +#define _X509_get_key_usage BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_key_usage) +#define _X509_get_notAfter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_notAfter) +#define _X509_get_notBefore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_notBefore) +#define _X509_get_pathlen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_pathlen) +#define _X509_get_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_pubkey) +#define _X509_get_serialNumber BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_serialNumber) +#define _X509_get_signature_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_signature_nid) +#define _X509_get_subject_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_subject_name) +#define _X509_get_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_get_version) +#define _X509_getm_notAfter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_getm_notAfter) +#define _X509_getm_notBefore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_getm_notBefore) +#define _X509_gmtime_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_gmtime_adj) +#define _X509_issuer_and_serial_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_issuer_and_serial_cmp) +#define _X509_issuer_name_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_issuer_name_cmp) +#define _X509_issuer_name_hash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_issuer_name_hash) +#define _X509_issuer_name_hash_old BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_issuer_name_hash_old) +#define _X509_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_it) +#define _X509_keyid_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_keyid_get0) +#define _X509_keyid_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_keyid_set1) +#define _X509_load_cert_crl_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_load_cert_crl_file) +#define _X509_load_cert_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_load_cert_file) +#define _X509_load_crl_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_load_crl_file) +#define _X509_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_new) +#define _X509_ocspid_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ocspid_print) +#define _X509_parse_from_buffer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define _X509_policy_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_check) +#define _X509_policy_level_get0_node BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_level_get0_node) +#define _X509_policy_level_node_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_level_node_count) +#define _X509_policy_node_get0_parent BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_node_get0_parent) +#define _X509_policy_node_get0_policy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_node_get0_policy) +#define _X509_policy_node_get0_qualifiers BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_node_get0_qualifiers) +#define _X509_policy_tree_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_free) +#define _X509_policy_tree_get0_level BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_get0_level) +#define _X509_policy_tree_get0_policies BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_get0_policies) +#define _X509_policy_tree_get0_user_policies BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_get0_user_policies) +#define _X509_policy_tree_level_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_tree_level_count) +#define _X509_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print) +#define _X509_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex) +#define _X509_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex_fp) +#define _X509_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_fp) +#define _X509_pubkey_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_pubkey_digest) +#define _X509_reject_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_reject_clear) +#define _X509_set1_notAfter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set1_notAfter) +#define _X509_set1_notBefore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set1_notBefore) +#define _X509_set1_signature_algo BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set1_signature_algo) +#define _X509_set1_signature_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set1_signature_value) +#define _X509_set_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_ex_data) +#define _X509_set_issuer_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_issuer_name) +#define _X509_set_notAfter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_notAfter) +#define _X509_set_notBefore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_notBefore) +#define _X509_set_pubkey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_pubkey) +#define _X509_set_serialNumber BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_serialNumber) +#define _X509_set_subject_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_subject_name) +#define _X509_set_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_set_version) +#define _X509_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign) +#define _X509_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign_ctx) +#define _X509_signature_dump BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_dump) +#define _X509_signature_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_print) +#define _X509_subject_name_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_subject_name_cmp) +#define _X509_subject_name_hash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_subject_name_hash) +#define _X509_subject_name_hash_old BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_subject_name_hash_old) +#define _X509_supported_extension BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_supported_extension) +#define _X509_time_adj BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_time_adj) +#define _X509_time_adj_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_time_adj_ex) +#define _X509_to_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_to_X509_REQ) +#define _X509_trust_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_trust_clear) +#define _X509_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_up_ref) +#define _X509_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify) +#define _X509_verify_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert) +#define _X509_verify_cert_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert_error_string) +#define _X509at_add1_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_add1_attr) +#define _X509at_add1_attr_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_add1_attr_by_NID) +#define _X509at_add1_attr_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_add1_attr_by_OBJ) +#define _X509at_add1_attr_by_txt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_add1_attr_by_txt) +#define _X509at_delete_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_delete_attr) +#define _X509at_get_attr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_get_attr) +#define _X509at_get_attr_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_get_attr_by_NID) +#define _X509at_get_attr_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_get_attr_by_OBJ) +#define _X509at_get_attr_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509at_get_attr_count) +#define _X509v3_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_add_ext) +#define _X509v3_delete_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_delete_ext) +#define _X509v3_get_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_get_ext) +#define _X509v3_get_ext_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_get_ext_by_NID) +#define _X509v3_get_ext_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_get_ext_by_OBJ) +#define _X509v3_get_ext_by_critical BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_get_ext_by_critical) +#define _X509v3_get_ext_count BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_get_ext_count) +#define ___clang_at_available_requires_core_foundation_framework BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, __clang_at_available_requires_core_foundation_framework) +#define ___clang_call_terminate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, __clang_call_terminate) +#define _a2i_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, a2i_GENERAL_NAME) +#define _a2i_IPADDRESS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, a2i_IPADDRESS) +#define _a2i_IPADDRESS_NC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, a2i_IPADDRESS_NC) +#define _aes128gcmsiv_aes_ks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_aes_ks) +#define _aes128gcmsiv_aes_ks_enc_x1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_aes_ks_enc_x1) +#define _aes128gcmsiv_dec BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_dec) +#define _aes128gcmsiv_ecb_enc_block BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_ecb_enc_block) +#define _aes128gcmsiv_enc_msg_x4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_enc_msg_x4) +#define _aes128gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_enc_msg_x8) +#define _aes128gcmsiv_kdf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes128gcmsiv_kdf) +#define _aes256gcmsiv_aes_ks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_aes_ks) +#define _aes256gcmsiv_aes_ks_enc_x1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_aes_ks_enc_x1) +#define _aes256gcmsiv_dec BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_dec) +#define _aes256gcmsiv_ecb_enc_block BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_ecb_enc_block) +#define _aes256gcmsiv_enc_msg_x4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x4) +#define _aes256gcmsiv_enc_msg_x8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_enc_msg_x8) +#define _aes256gcmsiv_kdf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes256gcmsiv_kdf) +#define _aes_ctr_set_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_ctr_set_key) +#define _aes_hw_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_cbc_encrypt) +#define _aes_hw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_ctr32_encrypt_blocks) +#define _aes_hw_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_decrypt) +#define _aes_hw_ecb_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_ecb_encrypt) +#define _aes_hw_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_encrypt) +#define _aes_hw_set_decrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_set_decrypt_key) +#define _aes_hw_set_encrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_hw_set_encrypt_key) +#define _aes_nohw_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_cbc_encrypt) +#define _aes_nohw_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_ctr32_encrypt_blocks) +#define _aes_nohw_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_decrypt) +#define _aes_nohw_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_encrypt) +#define _aes_nohw_set_decrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_set_decrypt_key) +#define _aes_nohw_set_encrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aes_nohw_set_encrypt_key) +#define _aesgcmsiv_htable6_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesgcmsiv_htable6_init) +#define _aesgcmsiv_htable_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesgcmsiv_htable_init) +#define _aesgcmsiv_htable_polyval BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesgcmsiv_htable_polyval) +#define _aesgcmsiv_polyval_horner BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesgcmsiv_polyval_horner) +#define _aesni_gcm_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesni_gcm_decrypt) +#define _aesni_gcm_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, aesni_gcm_encrypt) +#define _asn1_bit_string_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_bit_string_length) +#define _asn1_do_adb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_do_adb) +#define _asn1_enc_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_free) +#define _asn1_enc_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_init) +#define _asn1_enc_restore BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_restore) +#define _asn1_enc_save BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_enc_save) +#define _asn1_generalizedtime_to_tm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_generalizedtime_to_tm) +#define _asn1_get_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_choice_selector) +#define _asn1_get_field_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_field_ptr) +#define _asn1_get_string_table_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_get_string_table_for_testing) +#define _asn1_is_printable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_is_printable) +#define _asn1_item_combine_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_item_combine_free) +#define _asn1_refcount_dec_and_test_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_dec_and_test_zero) +#define _asn1_refcount_set_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_set_one) +#define _asn1_set_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define _asn1_type_value_as_pointer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_type_value_as_pointer) +#define _asn1_utctime_to_tm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_utctime_to_tm) +#define _beeu_mod_inverse_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, beeu_mod_inverse_vartime) +#define _bio_clear_socket_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_clear_socket_error) +#define _bio_fd_should_retry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_fd_should_retry) +#define _bio_ip_and_port_to_socket_and_addr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_ip_and_port_to_socket_and_addr) +#define _bio_sock_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_sock_error) +#define _bio_socket_nbio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bio_socket_nbio) +#define _bn_abs_sub_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_abs_sub_consttime) +#define _bn_add_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_add_words) +#define _bn_copy_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_copy_words) +#define _bn_div_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_div_consttime) +#define _bn_expand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_expand) +#define _bn_fits_in_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_fits_in_words) +#define _bn_from_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_from_montgomery) +#define _bn_from_montgomery_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_from_montgomery_small) +#define _bn_gather5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_gather5) +#define _bn_in_range_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_in_range_words) +#define _bn_is_bit_set_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_is_bit_set_words) +#define _bn_is_relatively_prime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_is_relatively_prime) +#define _bn_jacobi BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_jacobi) +#define _bn_lcm_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_lcm_consttime) +#define _bn_less_than_montgomery_R BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_less_than_montgomery_R) +#define _bn_less_than_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_less_than_words) +#define _bn_miller_rabin_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_miller_rabin_init) +#define _bn_miller_rabin_iteration BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_miller_rabin_iteration) +#define _bn_minimal_width BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_minimal_width) +#define _bn_mod_add_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_add_consttime) +#define _bn_mod_add_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_add_words) +#define _bn_mod_exp_base_2_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_exp_base_2_consttime) +#define _bn_mod_exp_mont_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_exp_mont_small) +#define _bn_mod_inverse0_prime_mont_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_inverse0_prime_mont_small) +#define _bn_mod_inverse_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_inverse_consttime) +#define _bn_mod_inverse_prime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_inverse_prime) +#define _bn_mod_inverse_secret_prime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_inverse_secret_prime) +#define _bn_mod_lshift1_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_lshift1_consttime) +#define _bn_mod_lshift_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_lshift_consttime) +#define _bn_mod_mul_montgomery_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_mul_montgomery_small) +#define _bn_mod_sub_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_sub_consttime) +#define _bn_mod_sub_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_sub_words) +#define _bn_mod_u16_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mod_u16_consttime) +#define _bn_mont_n0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mont_n0) +#define _bn_mul_add_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_add_words) +#define _bn_mul_comba4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba4) +#define _bn_mul_comba8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba8) +#define _bn_mul_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_consttime) +#define _bn_mul_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont) +#define _bn_mul_mont_gather5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_gather5) +#define _bn_mul_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_small) +#define _bn_mul_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_words) +#define _bn_odd_number_is_obviously_composite BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_odd_number_is_obviously_composite) +#define _bn_one_to_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_one_to_montgomery) +#define _bn_power5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_power5) +#define _bn_rand_range_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_rand_range_words) +#define _bn_rand_secret_range BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_rand_secret_range) +#define _bn_reduce_once BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_reduce_once) +#define _bn_reduce_once_in_place BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_reduce_once_in_place) +#define _bn_resize_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_resize_words) +#define _bn_rshift1_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_rshift1_words) +#define _bn_rshift_secret_shift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_rshift_secret_shift) +#define _bn_rshift_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_rshift_words) +#define _bn_scatter5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_scatter5) +#define _bn_select_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_select_words) +#define _bn_set_minimal_width BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_set_minimal_width) +#define _bn_set_static_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_set_static_words) +#define _bn_set_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_set_words) +#define _bn_sqr8x_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr8x_internal) +#define _bn_sqr_comba4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr_comba4) +#define _bn_sqr_comba8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr_comba8) +#define _bn_sqr_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr_consttime) +#define _bn_sqr_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr_small) +#define _bn_sqr_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqr_words) +#define _bn_sqrx8x_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sqrx8x_internal) +#define _bn_sub_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_sub_words) +#define _bn_to_montgomery_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_to_montgomery_small) +#define _bn_uadd_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_uadd_consttime) +#define _bn_usub_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_usub_consttime) +#define _bn_wexpand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_wexpand) +#define _boringssl_self_test_hmac_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, boringssl_self_test_hmac_sha256) +#define _boringssl_self_test_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, boringssl_self_test_sha256) +#define _boringssl_self_test_sha512 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, boringssl_self_test_sha512) +#define _c2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, c2i_ASN1_BIT_STRING) +#define _c2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, c2i_ASN1_INTEGER) +#define _c2i_ASN1_OBJECT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, c2i_ASN1_OBJECT) +#define _cbb_add_latin1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbb_add_latin1) +#define _cbb_add_ucs2_be BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbb_add_ucs2_be) +#define _cbb_add_utf32_be BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbb_add_utf32_be) +#define _cbb_add_utf8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbb_add_utf8) +#define _cbb_get_utf8_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbb_get_utf8_len) +#define _cbs_get_latin1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbs_get_latin1) +#define _cbs_get_ucs2_be BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbs_get_ucs2_be) +#define _cbs_get_utf32_be BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbs_get_utf32_be) +#define _cbs_get_utf8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, cbs_get_utf8) +#define _chacha20_poly1305_open BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, chacha20_poly1305_open) +#define _chacha20_poly1305_seal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, chacha20_poly1305_seal) +#define _crypto_gcm_clmul_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, crypto_gcm_clmul_enabled) +#define _d2i_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ACCESS_DESCRIPTION) +#define _d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) +#define _d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) +#define _d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) +#define _d2i_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_ENUMERATED) +#define _d2i_ASN1_GENERALIZEDTIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_GENERALIZEDTIME) +#define _d2i_ASN1_GENERALSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_GENERALSTRING) +#define _d2i_ASN1_IA5STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_IA5STRING) +#define _d2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_INTEGER) +#define _d2i_ASN1_NULL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_NULL) +#define _d2i_ASN1_OBJECT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_OBJECT) +#define _d2i_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_OCTET_STRING) +#define _d2i_ASN1_PRINTABLE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_PRINTABLE) +#define _d2i_ASN1_PRINTABLESTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_PRINTABLESTRING) +#define _d2i_ASN1_SEQUENCE_ANY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_SEQUENCE_ANY) +#define _d2i_ASN1_SET_ANY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_SET_ANY) +#define _d2i_ASN1_T61STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_T61STRING) +#define _d2i_ASN1_TIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_TIME) +#define _d2i_ASN1_TYPE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_TYPE) +#define _d2i_ASN1_UNIVERSALSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_UNIVERSALSTRING) +#define _d2i_ASN1_UTCTIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_UTCTIME) +#define _d2i_ASN1_UTF8STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_UTF8STRING) +#define _d2i_ASN1_VISIBLESTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_VISIBLESTRING) +#define _d2i_AUTHORITY_INFO_ACCESS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_AUTHORITY_INFO_ACCESS) +#define _d2i_AUTHORITY_KEYID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_AUTHORITY_KEYID) +#define _d2i_AutoPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_AutoPrivateKey) +#define _d2i_BASIC_CONSTRAINTS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_BASIC_CONSTRAINTS) +#define _d2i_CERTIFICATEPOLICIES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_CERTIFICATEPOLICIES) +#define _d2i_CRL_DIST_POINTS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_CRL_DIST_POINTS) +#define _d2i_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DHparams) +#define _d2i_DHparams_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DHparams_bio) +#define _d2i_DIRECTORYSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DIRECTORYSTRING) +#define _d2i_DISPLAYTEXT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DISPLAYTEXT) +#define _d2i_DIST_POINT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DIST_POINT) +#define _d2i_DIST_POINT_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DIST_POINT_NAME) +#define _d2i_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAPrivateKey) +#define _d2i_DSAPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAPrivateKey_bio) +#define _d2i_DSAPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAPrivateKey_fp) +#define _d2i_DSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAPublicKey) +#define _d2i_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSA_PUBKEY) +#define _d2i_DSA_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSA_PUBKEY_bio) +#define _d2i_DSA_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSA_PUBKEY_fp) +#define _d2i_DSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSA_SIG) +#define _d2i_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAparams) +#define _d2i_ECDSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECDSA_SIG) +#define _d2i_ECParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECParameters) +#define _d2i_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPrivateKey) +#define _d2i_ECPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPrivateKey_bio) +#define _d2i_ECPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPrivateKey_fp) +#define _d2i_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_EC_PUBKEY) +#define _d2i_EC_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_EC_PUBKEY_bio) +#define _d2i_EC_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_EC_PUBKEY_fp) +#define _d2i_EDIPARTYNAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_EDIPARTYNAME) +#define _d2i_EXTENDED_KEY_USAGE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_EXTENDED_KEY_USAGE) +#define _d2i_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_GENERAL_NAME) +#define _d2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_GENERAL_NAMES) +#define _d2i_ISSUING_DIST_POINT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ISSUING_DIST_POINT) +#define _d2i_NETSCAPE_SPKAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_NETSCAPE_SPKAC) +#define _d2i_NETSCAPE_SPKI BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_NETSCAPE_SPKI) +#define _d2i_NOTICEREF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_NOTICEREF) +#define _d2i_OTHERNAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_OTHERNAME) +#define _d2i_PKCS12 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS12) +#define _d2i_PKCS12_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS12_bio) +#define _d2i_PKCS12_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS12_fp) +#define _d2i_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS7) +#define _d2i_PKCS7_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS7_bio) +#define _d2i_PKCS8PrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8PrivateKey_bio) +#define _d2i_PKCS8PrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8PrivateKey_fp) +#define _d2i_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO) +#define _d2i_PKCS8_PRIV_KEY_INFO_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO_bio) +#define _d2i_PKCS8_PRIV_KEY_INFO_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_PRIV_KEY_INFO_fp) +#define _d2i_PKCS8_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_bio) +#define _d2i_PKCS8_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PKCS8_fp) +#define _d2i_POLICYINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_POLICYINFO) +#define _d2i_POLICYQUALINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_POLICYQUALINFO) +#define _d2i_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PROXY_CERT_INFO_EXTENSION) +#define _d2i_PROXY_POLICY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PROXY_POLICY) +#define _d2i_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY) +#define _d2i_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY_bio) +#define _d2i_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PUBKEY_fp) +#define _d2i_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PrivateKey) +#define _d2i_PrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PrivateKey_bio) +#define _d2i_PrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PrivateKey_fp) +#define _d2i_PublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_PublicKey) +#define _d2i_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPrivateKey) +#define _d2i_RSAPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPrivateKey_bio) +#define _d2i_RSAPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPrivateKey_fp) +#define _d2i_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPublicKey) +#define _d2i_RSAPublicKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPublicKey_bio) +#define _d2i_RSAPublicKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSAPublicKey_fp) +#define _d2i_RSA_PSS_PARAMS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSA_PSS_PARAMS) +#define _d2i_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSA_PUBKEY) +#define _d2i_RSA_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSA_PUBKEY_bio) +#define _d2i_RSA_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_RSA_PUBKEY_fp) +#define _d2i_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_SSL_SESSION) +#define _d2i_SSL_SESSION_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_SSL_SESSION_bio) +#define _d2i_USERNOTICE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_USERNOTICE) +#define _d2i_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509) +#define _d2i_X509_ALGOR BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_ALGOR) +#define _d2i_X509_ALGORS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_ALGORS) +#define _d2i_X509_ATTRIBUTE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_ATTRIBUTE) +#define _d2i_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_AUX) +#define _d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) +#define _d2i_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CINF) +#define _d2i_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL) +#define _d2i_X509_CRL_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_INFO) +#define _d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_bio) +#define _d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_fp) +#define _d2i_X509_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_EXTENSION) +#define _d2i_X509_EXTENSIONS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_EXTENSIONS) +#define _d2i_X509_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_NAME) +#define _d2i_X509_NAME_ENTRY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_NAME_ENTRY) +#define _d2i_X509_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_PUBKEY) +#define _d2i_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ) +#define _d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) +#define _d2i_X509_REQ_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ_bio) +#define _d2i_X509_REQ_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ_fp) +#define _d2i_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REVOKED) +#define _d2i_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_SIG) +#define _d2i_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_VAL) +#define _d2i_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_bio) +#define _d2i_X509_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_fp) +#define _dh_compute_key_padded_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dh_compute_key_padded_no_self_test) +#define _dsa_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dsa_asn1_meth) +#define _dsa_check_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, dsa_check_parameters) +#define _ec_GFp_mont_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_add) +#define _ec_GFp_mont_dbl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_dbl) +#define _ec_GFp_mont_felem_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_from_bytes) +#define _ec_GFp_mont_felem_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_mul) +#define _ec_GFp_mont_felem_sqr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_sqr) +#define _ec_GFp_mont_felem_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_felem_to_bytes) +#define _ec_GFp_mont_group_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_group_finish) +#define _ec_GFp_mont_group_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_group_init) +#define _ec_GFp_mont_group_set_curve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_group_set_curve) +#define _ec_GFp_mont_init_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_init_precomp) +#define _ec_GFp_mont_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_mul) +#define _ec_GFp_mont_mul_base BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_mul_base) +#define _ec_GFp_mont_mul_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_mul_batch) +#define _ec_GFp_mont_mul_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_mul_precomp) +#define _ec_GFp_mont_mul_public_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_mont_mul_public_batch) +#define _ec_GFp_nistp_recode_scalar_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_nistp_recode_scalar_bits) +#define _ec_GFp_simple_cmp_x_coordinate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_cmp_x_coordinate) +#define _ec_GFp_simple_felem_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_felem_from_bytes) +#define _ec_GFp_simple_felem_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_felem_to_bytes) +#define _ec_GFp_simple_group_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_group_finish) +#define _ec_GFp_simple_group_get_curve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_group_get_curve) +#define _ec_GFp_simple_group_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_group_init) +#define _ec_GFp_simple_group_set_curve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_group_set_curve) +#define _ec_GFp_simple_invert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_invert) +#define _ec_GFp_simple_is_at_infinity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_is_at_infinity) +#define _ec_GFp_simple_is_on_curve BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_is_on_curve) +#define _ec_GFp_simple_point_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_point_copy) +#define _ec_GFp_simple_point_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_point_init) +#define _ec_GFp_simple_point_set_to_infinity BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_point_set_to_infinity) +#define _ec_GFp_simple_points_equal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_GFp_simple_points_equal) +#define _ec_affine_jacobian_equal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_affine_jacobian_equal) +#define _ec_affine_select BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_affine_select) +#define _ec_affine_to_jacobian BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_affine_to_jacobian) +#define _ec_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_asn1_meth) +#define _ec_bignum_to_felem BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_bignum_to_felem) +#define _ec_bignum_to_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_bignum_to_scalar) +#define _ec_cmp_x_coordinate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_cmp_x_coordinate) +#define _ec_compute_wNAF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_compute_wNAF) +#define _ec_felem_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_add) +#define _ec_felem_equal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_equal) +#define _ec_felem_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_from_bytes) +#define _ec_felem_neg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_neg) +#define _ec_felem_non_zero_mask BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_non_zero_mask) +#define _ec_felem_select BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_select) +#define _ec_felem_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_sub) +#define _ec_felem_to_bignum BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_to_bignum) +#define _ec_felem_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_felem_to_bytes) +#define _ec_get_x_coordinate_as_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_get_x_coordinate_as_bytes) +#define _ec_get_x_coordinate_as_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_get_x_coordinate_as_scalar) +#define _ec_group_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_group_new) +#define _ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_curve_p384_xmd_sha512_sswu_draft07) +#define _ec_hash_to_scalar_p384_xmd_sha512_draft07 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_hash_to_scalar_p384_xmd_sha512_draft07) +#define _ec_init_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_init_precomp) +#define _ec_jacobian_to_affine BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine) +#define _ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) +#define _ec_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_pkey_meth) +#define _ec_point_from_uncompressed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_from_uncompressed) +#define _ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_no_self_test) +#define _ec_point_mul_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar) +#define _ec_point_mul_scalar_base BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar_base) +#define _ec_point_mul_scalar_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar_batch) +#define _ec_point_mul_scalar_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar_precomp) +#define _ec_point_mul_scalar_public BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar_public) +#define _ec_point_mul_scalar_public_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar_public_batch) +#define _ec_point_select BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_select) +#define _ec_point_set_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_set_affine_coordinates) +#define _ec_point_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_to_bytes) +#define _ec_precomp_select BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_precomp_select) +#define _ec_random_nonzero_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_random_nonzero_scalar) +#define _ec_scalar_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_add) +#define _ec_scalar_equal_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_equal_vartime) +#define _ec_scalar_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_from_bytes) +#define _ec_scalar_from_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_from_montgomery) +#define _ec_scalar_inv0_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_inv0_montgomery) +#define _ec_scalar_is_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_is_zero) +#define _ec_scalar_mul_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_mul_montgomery) +#define _ec_scalar_neg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_neg) +#define _ec_scalar_reduce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_reduce) +#define _ec_scalar_select BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_select) +#define _ec_scalar_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_sub) +#define _ec_scalar_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_to_bytes) +#define _ec_scalar_to_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_to_montgomery) +#define _ec_scalar_to_montgomery_inv_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_scalar_to_montgomery_inv_vartime) +#define _ec_set_to_safe_point BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_set_to_safe_point) +#define _ec_simple_scalar_inv0_montgomery BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_simple_scalar_inv0_montgomery) +#define _ec_simple_scalar_to_montgomery_inv_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_simple_scalar_to_montgomery_inv_vartime) +#define _ecdsa_do_verify_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecdsa_do_verify_no_self_test) +#define _ecdsa_sign_with_nonce_for_known_answer_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecdsa_sign_with_nonce_for_known_answer_test) +#define _ecp_nistz256_avx2_select_w7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_avx2_select_w7) +#define _ecp_nistz256_div_by_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_div_by_2) +#define _ecp_nistz256_from_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_from_mont) +#define _ecp_nistz256_mul_by_2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_mul_by_2) +#define _ecp_nistz256_mul_by_3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_mul_by_3) +#define _ecp_nistz256_mul_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_mul_mont) +#define _ecp_nistz256_neg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_neg) +#define _ecp_nistz256_ord_mul_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_ord_mul_mont) +#define _ecp_nistz256_ord_sqr_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_ord_sqr_mont) +#define _ecp_nistz256_point_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_point_add) +#define _ecp_nistz256_point_add_affine BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_point_add_affine) +#define _ecp_nistz256_point_double BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_point_double) +#define _ecp_nistz256_select_w5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_select_w5) +#define _ecp_nistz256_select_w7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_select_w7) +#define _ecp_nistz256_sqr_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_sqr_mont) +#define _ecp_nistz256_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_sub) +#define _ecp_nistz256_to_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ecp_nistz256_to_mont) +#define _ed25519_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ed25519_asn1_meth) +#define _ed25519_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ed25519_pkey_meth) +#define _gcm_ghash_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_avx) +#define _gcm_ghash_clmul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_clmul) +#define _gcm_ghash_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_neon) +#define _gcm_ghash_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_nohw) +#define _gcm_ghash_ssse3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_ssse3) +#define _gcm_ghash_v8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_v8) +#define _gcm_gmult_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_avx) +#define _gcm_gmult_clmul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_clmul) +#define _gcm_gmult_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_neon) +#define _gcm_gmult_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_nohw) +#define _gcm_gmult_ssse3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_ssse3) +#define _gcm_gmult_v8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_gmult_v8) +#define _gcm_init_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_avx) +#define _gcm_init_clmul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_clmul) +#define _gcm_init_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_neon) +#define _gcm_init_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_nohw) +#define _gcm_init_ssse3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_ssse3) +#define _gcm_init_v8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_init_v8) +#define _i2a_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2a_ACCESS_DESCRIPTION) +#define _i2a_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2a_ASN1_ENUMERATED) +#define _i2a_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2a_ASN1_INTEGER) +#define _i2a_ASN1_OBJECT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2a_ASN1_OBJECT) +#define _i2a_ASN1_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2a_ASN1_STRING) +#define _i2c_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2c_ASN1_BIT_STRING) +#define _i2c_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2c_ASN1_INTEGER) +#define _i2d_ACCESS_DESCRIPTION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ACCESS_DESCRIPTION) +#define _i2d_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_BIT_STRING) +#define _i2d_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_BMPSTRING) +#define _i2d_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_BOOLEAN) +#define _i2d_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_ENUMERATED) +#define _i2d_ASN1_GENERALIZEDTIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_GENERALIZEDTIME) +#define _i2d_ASN1_GENERALSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_GENERALSTRING) +#define _i2d_ASN1_IA5STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_IA5STRING) +#define _i2d_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_INTEGER) +#define _i2d_ASN1_NULL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_NULL) +#define _i2d_ASN1_OBJECT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_OBJECT) +#define _i2d_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_OCTET_STRING) +#define _i2d_ASN1_PRINTABLE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_PRINTABLE) +#define _i2d_ASN1_PRINTABLESTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_PRINTABLESTRING) +#define _i2d_ASN1_SEQUENCE_ANY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_SEQUENCE_ANY) +#define _i2d_ASN1_SET_ANY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_SET_ANY) +#define _i2d_ASN1_T61STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_T61STRING) +#define _i2d_ASN1_TIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_TIME) +#define _i2d_ASN1_TYPE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_TYPE) +#define _i2d_ASN1_UNIVERSALSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_UNIVERSALSTRING) +#define _i2d_ASN1_UTCTIME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_UTCTIME) +#define _i2d_ASN1_UTF8STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_UTF8STRING) +#define _i2d_ASN1_VISIBLESTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ASN1_VISIBLESTRING) +#define _i2d_AUTHORITY_INFO_ACCESS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_AUTHORITY_INFO_ACCESS) +#define _i2d_AUTHORITY_KEYID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_AUTHORITY_KEYID) +#define _i2d_BASIC_CONSTRAINTS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_BASIC_CONSTRAINTS) +#define _i2d_CERTIFICATEPOLICIES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_CERTIFICATEPOLICIES) +#define _i2d_CRL_DIST_POINTS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_CRL_DIST_POINTS) +#define _i2d_DHparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DHparams) +#define _i2d_DHparams_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DHparams_bio) +#define _i2d_DIRECTORYSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DIRECTORYSTRING) +#define _i2d_DISPLAYTEXT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DISPLAYTEXT) +#define _i2d_DIST_POINT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DIST_POINT) +#define _i2d_DIST_POINT_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DIST_POINT_NAME) +#define _i2d_DSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAPrivateKey) +#define _i2d_DSAPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAPrivateKey_bio) +#define _i2d_DSAPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAPrivateKey_fp) +#define _i2d_DSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAPublicKey) +#define _i2d_DSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSA_PUBKEY) +#define _i2d_DSA_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSA_PUBKEY_bio) +#define _i2d_DSA_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSA_PUBKEY_fp) +#define _i2d_DSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSA_SIG) +#define _i2d_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAparams) +#define _i2d_ECDSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECDSA_SIG) +#define _i2d_ECParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECParameters) +#define _i2d_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPrivateKey) +#define _i2d_ECPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPrivateKey_bio) +#define _i2d_ECPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPrivateKey_fp) +#define _i2d_EC_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_EC_PUBKEY) +#define _i2d_EC_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_EC_PUBKEY_bio) +#define _i2d_EC_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_EC_PUBKEY_fp) +#define _i2d_EDIPARTYNAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_EDIPARTYNAME) +#define _i2d_EXTENDED_KEY_USAGE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_EXTENDED_KEY_USAGE) +#define _i2d_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_GENERAL_NAME) +#define _i2d_GENERAL_NAMES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_GENERAL_NAMES) +#define _i2d_ISSUING_DIST_POINT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ISSUING_DIST_POINT) +#define _i2d_NETSCAPE_SPKAC BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_NETSCAPE_SPKAC) +#define _i2d_NETSCAPE_SPKI BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_NETSCAPE_SPKI) +#define _i2d_NOTICEREF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_NOTICEREF) +#define _i2d_OTHERNAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_OTHERNAME) +#define _i2d_PKCS12 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS12) +#define _i2d_PKCS12_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS12_bio) +#define _i2d_PKCS12_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS12_fp) +#define _i2d_PKCS7 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS7) +#define _i2d_PKCS7_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS7_bio) +#define _i2d_PKCS8PrivateKeyInfo_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKeyInfo_bio) +#define _i2d_PKCS8PrivateKeyInfo_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKeyInfo_fp) +#define _i2d_PKCS8PrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_bio) +#define _i2d_PKCS8PrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_fp) +#define _i2d_PKCS8PrivateKey_nid_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_nid_bio) +#define _i2d_PKCS8PrivateKey_nid_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8PrivateKey_nid_fp) +#define _i2d_PKCS8_PRIV_KEY_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO) +#define _i2d_PKCS8_PRIV_KEY_INFO_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO_bio) +#define _i2d_PKCS8_PRIV_KEY_INFO_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_PRIV_KEY_INFO_fp) +#define _i2d_PKCS8_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_bio) +#define _i2d_PKCS8_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PKCS8_fp) +#define _i2d_POLICYINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_POLICYINFO) +#define _i2d_POLICYQUALINFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_POLICYQUALINFO) +#define _i2d_PROXY_CERT_INFO_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PROXY_CERT_INFO_EXTENSION) +#define _i2d_PROXY_POLICY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PROXY_POLICY) +#define _i2d_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY) +#define _i2d_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY_bio) +#define _i2d_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PUBKEY_fp) +#define _i2d_PrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PrivateKey) +#define _i2d_PrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PrivateKey_bio) +#define _i2d_PrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PrivateKey_fp) +#define _i2d_PublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_PublicKey) +#define _i2d_RSAPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPrivateKey) +#define _i2d_RSAPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPrivateKey_bio) +#define _i2d_RSAPrivateKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPrivateKey_fp) +#define _i2d_RSAPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPublicKey) +#define _i2d_RSAPublicKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPublicKey_bio) +#define _i2d_RSAPublicKey_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSAPublicKey_fp) +#define _i2d_RSA_PSS_PARAMS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSA_PSS_PARAMS) +#define _i2d_RSA_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSA_PUBKEY) +#define _i2d_RSA_PUBKEY_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSA_PUBKEY_bio) +#define _i2d_RSA_PUBKEY_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_RSA_PUBKEY_fp) +#define _i2d_SSL_SESSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_SSL_SESSION) +#define _i2d_SSL_SESSION_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_SSL_SESSION_bio) +#define _i2d_USERNOTICE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_USERNOTICE) +#define _i2d_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509) +#define _i2d_X509_ALGOR BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_ALGOR) +#define _i2d_X509_ALGORS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_ALGORS) +#define _i2d_X509_ATTRIBUTE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_ATTRIBUTE) +#define _i2d_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_AUX) +#define _i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) +#define _i2d_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CINF) +#define _i2d_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL) +#define _i2d_X509_CRL_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_INFO) +#define _i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_bio) +#define _i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_fp) +#define _i2d_X509_CRL_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_tbs) +#define _i2d_X509_EXTENSION BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_EXTENSION) +#define _i2d_X509_EXTENSIONS BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_EXTENSIONS) +#define _i2d_X509_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_NAME) +#define _i2d_X509_NAME_ENTRY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_NAME_ENTRY) +#define _i2d_X509_PUBKEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_PUBKEY) +#define _i2d_X509_REQ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REQ) +#define _i2d_X509_REQ_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REQ_INFO) +#define _i2d_X509_REQ_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REQ_bio) +#define _i2d_X509_REQ_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REQ_fp) +#define _i2d_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REVOKED) +#define _i2d_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_SIG) +#define _i2d_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_VAL) +#define _i2d_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_bio) +#define _i2d_X509_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_fp) +#define _i2d_X509_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_tbs) +#define _i2d_re_X509_CRL_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_re_X509_CRL_tbs) +#define _i2d_re_X509_REQ_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_re_X509_REQ_tbs) +#define _i2d_re_X509_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_re_X509_tbs) +#define _i2o_ECPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2o_ECPublicKey) +#define _i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) +#define _i2s_ASN1_ENUMERATED_TABLE BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED_TABLE) +#define _i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) +#define _i2s_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_OCTET_STRING) +#define _i2t_ASN1_OBJECT BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2t_ASN1_OBJECT) +#define _i2v_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2v_ASN1_BIT_STRING) +#define _i2v_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2v_GENERAL_NAME) +#define _i2v_GENERAL_NAMES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2v_GENERAL_NAMES) +#define _kBoringSSLRSASqrtTwo BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kBoringSSLRSASqrtTwo) +#define _kBoringSSLRSASqrtTwoLen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kBoringSSLRSASqrtTwoLen) +#define _kOpenSSLReasonStringData BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonStringData) +#define _kOpenSSLReasonValues BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonValues) +#define _kOpenSSLReasonValuesLen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, kOpenSSLReasonValuesLen) +#define _level_add_node BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, level_add_node) +#define _level_find_node BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, level_find_node) +#define _md4_block_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, md4_block_data_order) +#define _md5_block_asm_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, md5_block_asm_data_order) +#define _o2i_ECPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, o2i_ECPublicKey) +#define _pkcs12_iterations_acceptable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs12_iterations_acceptable) +#define _pkcs12_key_gen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs12_key_gen) +#define _pkcs12_pbe_encrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs12_pbe_encrypt_init) +#define _pkcs7_add_signed_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs7_add_signed_data) +#define _pkcs7_parse_header BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs7_parse_header) +#define _pkcs8_pbe_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pkcs8_pbe_decrypt) +#define _pmbtoken_exp1_blind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_blind) +#define _pmbtoken_exp1_client_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_client_key_from_bytes) +#define _pmbtoken_exp1_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_generate_key) +#define _pmbtoken_exp1_get_h_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_get_h_for_testing) +#define _pmbtoken_exp1_issuer_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_issuer_key_from_bytes) +#define _pmbtoken_exp1_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_read) +#define _pmbtoken_exp1_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_sign) +#define _pmbtoken_exp1_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp1_unblind) +#define _pmbtoken_exp2_blind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_blind) +#define _pmbtoken_exp2_client_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_client_key_from_bytes) +#define _pmbtoken_exp2_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_generate_key) +#define _pmbtoken_exp2_get_h_for_testing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_get_h_for_testing) +#define _pmbtoken_exp2_issuer_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_issuer_key_from_bytes) +#define _pmbtoken_exp2_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_read) +#define _pmbtoken_exp2_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_sign) +#define _pmbtoken_exp2_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, pmbtoken_exp2_unblind) +#define _policy_cache_find_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_find_data) +#define _policy_cache_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_free) +#define _policy_cache_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_set) +#define _policy_cache_set_mapping BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_cache_set_mapping) +#define _policy_data_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_data_free) +#define _policy_data_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_data_new) +#define _policy_node_cmp_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_cmp_new) +#define _policy_node_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_free) +#define _policy_node_match BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, policy_node_match) +#define _poly_Rq_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, poly_Rq_mul) +#define _rand_fork_unsafe_buffering_enabled BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rand_fork_unsafe_buffering_enabled) +#define _rsa_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_asn1_meth) +#define _rsa_check_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_check_public_key) +#define _rsa_default_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_decrypt) +#define _rsa_default_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_private_transform) +#define _rsa_default_sign_raw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_sign_raw) +#define _rsa_default_size BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_default_size) +#define _rsa_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pkey_meth) +#define _rsa_sign_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_sign_no_self_test) +#define _rsa_verify_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_verify_no_self_test) +#define _rsa_verify_raw_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_verify_raw_no_self_test) +#define _rsaz_1024_gather5_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_gather5_avx2) +#define _rsaz_1024_mul_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_mul_avx2) +#define _rsaz_1024_norm2red_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_norm2red_avx2) +#define _rsaz_1024_red2norm_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_red2norm_avx2) +#define _rsaz_1024_scatter5_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_scatter5_avx2) +#define _rsaz_1024_sqr_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsaz_1024_sqr_avx2) +#define _s2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, s2i_ASN1_INTEGER) +#define _s2i_ASN1_OCTET_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, s2i_ASN1_OCTET_STRING) +#define _sha1_block_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order) +#define _sha256_block_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order) +#define _sha512_block_data_order BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_block_data_order) +#define _sk_CRYPTO_BUFFER_call_copy_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_copy_func) +#define _sk_CRYPTO_BUFFER_call_free_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_call_free_func) +#define _sk_CRYPTO_BUFFER_deep_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_deep_copy) +#define _sk_CRYPTO_BUFFER_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_new_null) +#define _sk_CRYPTO_BUFFER_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_num) +#define _sk_CRYPTO_BUFFER_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_push) +#define _sk_CRYPTO_BUFFER_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_set) +#define _sk_CRYPTO_BUFFER_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_CRYPTO_BUFFER_value) +#define _sk_SRTP_PROTECTION_PROFILE_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_new_null) +#define _sk_SRTP_PROTECTION_PROFILE_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_num) +#define _sk_SRTP_PROTECTION_PROFILE_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SRTP_PROTECTION_PROFILE_push) +#define _sk_SSL_CIPHER_call_cmp_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_call_cmp_func) +#define _sk_SSL_CIPHER_delete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_delete) +#define _sk_SSL_CIPHER_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_dup) +#define _sk_SSL_CIPHER_find BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_find) +#define _sk_SSL_CIPHER_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_new_null) +#define _sk_SSL_CIPHER_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_num) +#define _sk_SSL_CIPHER_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_push) +#define _sk_SSL_CIPHER_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_SSL_CIPHER_value) +#define _sk_X509_NAME_call_cmp_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_call_cmp_func) +#define _sk_X509_NAME_call_copy_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_call_copy_func) +#define _sk_X509_NAME_call_free_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_call_free_func) +#define _sk_X509_NAME_deep_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_deep_copy) +#define _sk_X509_NAME_find BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_find) +#define _sk_X509_NAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_free) +#define _sk_X509_NAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_new) +#define _sk_X509_NAME_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_new_null) +#define _sk_X509_NAME_pop_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_pop_free) +#define _sk_X509_NAME_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_push) +#define _sk_X509_NAME_set_cmp_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_set_cmp_func) +#define _sk_X509_NAME_sort BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_NAME_sort) +#define _sk_X509_call_free_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_call_free_func) +#define _sk_X509_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_new_null) +#define _sk_X509_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_num) +#define _sk_X509_pop_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_pop_free) +#define _sk_X509_shift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_shift) +#define _sk_X509_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_X509_value) +#define _sk_deep_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_deep_copy) +#define _sk_delete BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_delete) +#define _sk_delete_ptr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_delete_ptr) +#define _sk_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_dup) +#define _sk_find BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_find) +#define _sk_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_free) +#define _sk_insert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_insert) +#define _sk_is_sorted BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_is_sorted) +#define _sk_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_new) +#define _sk_new_null BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_new_null) +#define _sk_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_num) +#define _sk_pop BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_pop) +#define _sk_pop_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_pop_free) +#define _sk_pop_free_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_pop_free_ex) +#define _sk_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_push) +#define _sk_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_set) +#define _sk_set_cmp_func BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_set_cmp_func) +#define _sk_shift BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_shift) +#define _sk_sort BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_sort) +#define _sk_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_value) +#define _sk_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_zero) +#define _tree_find_sk BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, tree_find_sk) +#define _v2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_ASN1_BIT_STRING) +#define _v2i_GENERAL_NAME BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAME) +#define _v2i_GENERAL_NAMES BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAMES) +#define _v2i_GENERAL_NAME_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v2i_GENERAL_NAME_ex) +#define _v3_akey_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_akey_id) +#define _v3_alt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_alt) +#define _v3_bcons BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_bcons) +#define _v3_cpols BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_cpols) +#define _v3_crl_invdate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_crl_invdate) +#define _v3_crl_num BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_crl_num) +#define _v3_crl_reason BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_crl_reason) +#define _v3_crld BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_crld) +#define _v3_delta_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_delta_crl) +#define _v3_ext_ku BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ext_ku) +#define _v3_freshest_crl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_freshest_crl) +#define _v3_idp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_idp) +#define _v3_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_info) +#define _v3_inhibit_anyp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_inhibit_anyp) +#define _v3_key_usage BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_key_usage) +#define _v3_name_constraints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_name_constraints) +#define _v3_ns_ia5_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ns_ia5_list) +#define _v3_nscert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_nscert) +#define _v3_ocsp_accresp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ocsp_accresp) +#define _v3_ocsp_nocheck BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_ocsp_nocheck) +#define _v3_pci BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_pci) +#define _v3_policy_constraints BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_policy_constraints) +#define _v3_policy_mappings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_policy_mappings) +#define _v3_sinfo BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_sinfo) +#define _v3_skey_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, v3_skey_id) +#define _voprf_exp2_blind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_blind) +#define _voprf_exp2_client_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_client_key_from_bytes) +#define _voprf_exp2_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_generate_key) +#define _voprf_exp2_issuer_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_issuer_key_from_bytes) +#define _voprf_exp2_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_read) +#define _voprf_exp2_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_sign) +#define _voprf_exp2_unblind BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, voprf_exp2_unblind) +#define _vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_cbc_encrypt) +#define _vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) +#define _vpaes_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_decrypt) +#define _vpaes_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_encrypt) +#define _vpaes_set_decrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_set_decrypt_key) +#define _vpaes_set_encrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_set_encrypt_key) +#define _x25519_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_asn1_meth) +#define _x25519_ge_add BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_add) +#define _x25519_ge_frombytes_vartime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_frombytes_vartime) +#define _x25519_ge_p1p1_to_p2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_p1p1_to_p2) +#define _x25519_ge_p1p1_to_p3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_p1p1_to_p3) +#define _x25519_ge_p3_to_cached BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_p3_to_cached) +#define _x25519_ge_scalarmult BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_scalarmult) +#define _x25519_ge_scalarmult_base BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_scalarmult_base) +#define _x25519_ge_scalarmult_small_precomp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_scalarmult_small_precomp) +#define _x25519_ge_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_sub) +#define _x25519_ge_tobytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_tobytes) +#define _x25519_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_pkey_meth) +#define _x25519_sc_reduce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_sc_reduce) +#define _x509V3_add_value_asn1_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509V3_add_value_asn1_string) +#define _x509_digest_sign_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_digest_sign_algorithm) +#define _x509_digest_verify_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_digest_verify_init) +#define _x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define _x509_rsa_ctx_to_pss BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_rsa_ctx_to_pss) +#define _x509_rsa_pss_to_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_rsa_pss_to_ctx) +#define _x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_a2i_ipadd) +#define _x509v3_bytes_to_hex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_bytes_to_hex) +#define _x509v3_cache_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_cache_extensions) +#define _x509v3_hex_to_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_hex_to_bytes) +#define _x509v3_looks_like_dns_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_looks_like_dns_name) +#define _x509v3_name_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_name_cmp) +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buf.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buf.h new file mode 100644 index 00000000..d97faac7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buf.h @@ -0,0 +1,137 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_BUFFER_H +#define OPENSSL_HEADER_BUFFER_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also mem.h. + + +// buf_mem_st (aka |BUF_MEM|) is a generic buffer object used by OpenSSL. +struct buf_mem_st { + size_t length; // current number of bytes + char *data; + size_t max; // size of buffer +}; + +// BUF_MEM_new creates a new BUF_MEM which has no allocated data buffer. +OPENSSL_EXPORT BUF_MEM *BUF_MEM_new(void); + +// BUF_MEM_free frees |buf->data| if needed and then frees |buf| itself. +OPENSSL_EXPORT void BUF_MEM_free(BUF_MEM *buf); + +// BUF_MEM_reserve ensures |buf| has capacity |cap| and allocates memory if +// needed. It returns one on success and zero on error. +OPENSSL_EXPORT int BUF_MEM_reserve(BUF_MEM *buf, size_t cap); + +// BUF_MEM_grow ensures that |buf| has length |len| and allocates memory if +// needed. If the length of |buf| increased, the new bytes are filled with +// zeros. It returns the length of |buf|, or zero if there's an error. +OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len); + +// BUF_MEM_grow_clean calls |BUF_MEM_grow|. BoringSSL always zeros memory +// allocated memory on free. +OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len); + +// BUF_MEM_append appends |in| to |buf|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len); + + +// Deprecated functions. + +// BUF_strdup calls |OPENSSL_strdup|. +OPENSSL_EXPORT char *BUF_strdup(const char *str); + +// BUF_strnlen calls |OPENSSL_strnlen|. +OPENSSL_EXPORT size_t BUF_strnlen(const char *str, size_t max_len); + +// BUF_strndup calls |OPENSSL_strndup|. +OPENSSL_EXPORT char *BUF_strndup(const char *str, size_t size); + +// BUF_memdup calls |OPENSSL_memdup|. +OPENSSL_EXPORT void *BUF_memdup(const void *data, size_t size); + +// BUF_strlcpy calls |OPENSSL_strlcpy|. +OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size); + +// BUF_strlcat calls |OPENSSL_strlcat|. +OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t dst_size); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(BUF_MEM, BUF_MEM_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_BUFFER_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buffer.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buffer.h new file mode 100644 index 00000000..002886d6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_buffer.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_buf.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h new file mode 100644 index 00000000..6e0a113a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h @@ -0,0 +1,592 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_span.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Bytestrings are used for parsing and building TLS and ASN.1 messages. +// +// A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and +// provides utility functions for safely parsing length-prefixed structures +// like TLS and ASN.1 from it. +// +// A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and +// provides utility functions for building length-prefixed messages. + + +// CRYPTO ByteString + +struct cbs_st { + const uint8_t *data; + size_t len; + +#if !defined(BORINGSSL_NO_CXX) + // Allow implicit conversions to and from bssl::Span. + cbs_st(bssl::Span span) + : data(span.data()), len(span.size()) {} + operator bssl::Span() const { + return bssl::MakeConstSpan(data, len); + } + + // Defining any constructors requires we explicitly default the others. + cbs_st() = default; + cbs_st(const cbs_st &) = default; + cbs_st &operator=(const cbs_st &) = default; +#endif +}; + +// CBS_init sets |cbs| to point to |data|. It does not take ownership of +// |data|. +OPENSSL_EXPORT void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +// CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBS_skip(CBS *cbs, size_t len); + +// CBS_data returns a pointer to the contents of |cbs|. +OPENSSL_EXPORT const uint8_t *CBS_data(const CBS *cbs); + +// CBS_len returns the number of bytes remaining in |cbs|. +OPENSSL_EXPORT size_t CBS_len(const CBS *cbs); + +// CBS_stow copies the current contents of |cbs| into |*out_ptr| and +// |*out_len|. If |*out_ptr| is not NULL, the contents are freed with +// OPENSSL_free. It returns one on success and zero on allocation failure. On +// success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty, +// |*out_ptr| will be NULL. +OPENSSL_EXPORT int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +// CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a +// NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed +// with OPENSSL_free. It returns one on success and zero on allocation +// failure. On success, |*out_ptr| should be freed with OPENSSL_free. +// +// NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call +// |CBS_contains_zero_byte(cbs)| to check for NUL bytes. +OPENSSL_EXPORT int CBS_strdup(const CBS *cbs, char **out_ptr); + +// CBS_contains_zero_byte returns one if the current contents of |cbs| contains +// a NUL byte and zero otherwise. +OPENSSL_EXPORT int CBS_contains_zero_byte(const CBS *cbs); + +// CBS_mem_equal compares the current contents of |cbs| with the |len| bytes +// starting at |data|. If they're equal, it returns one, otherwise zero. If the +// lengths match, it uses a constant-time comparison. +OPENSSL_EXPORT int CBS_mem_equal(const CBS *cbs, const uint8_t *data, + size_t len); + +// CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8(CBS *cbs, uint8_t *out); + +// CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out); + +// CBS_get_u16le sets |*out| to the next, little-endian uint16_t from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16le(CBS *cbs, uint16_t *out); + +// CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out); + +// CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| +// and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out); + +// CBS_get_u32le sets |*out| to the next, little-endian uint32_t value from +// |cbs| and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u32le(CBS *cbs, uint32_t *out); + +// CBS_get_u64 sets |*out| to the next, big-endian uint64_t value from |cbs| +// and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u64(CBS *cbs, uint64_t *out); + +// CBS_get_u64le sets |*out| to the next, little-endian uint64_t value from +// |cbs| and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u64le(CBS *cbs, uint64_t *out); + +// CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_last_u8(CBS *cbs, uint8_t *out); + +// CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +// CBS_copy_bytes copies the next |len| bytes from |cbs| to |out| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len); + +// CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, +// length-prefixed value from |cbs| and advances |cbs| over it. It returns one +// on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_until_first finds the first instance of |c| in |cbs|. If found, it +// sets |*out| to the text before the match, advances |cbs| over it, and returns +// one. Otherwise, it returns zero and leaves |cbs| unmodified. +OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); + + +// Parsing ASN.1 +// +// |CBS| may be used to parse DER structures. Rather than using a schema +// compiler, the following functions act on tag-length-value elements in the +// serialization itself. Thus the caller is responsible for looping over a +// SEQUENCE, branching on CHOICEs or OPTIONAL fields, checking for trailing +// data, and handling explict vs. implicit tagging. +// +// Tags are represented as |unsigned| values in memory. The upper few bits store +// the class and constructed bit, and the remaining bits store the tag +// number. Note this differs from the DER serialization, to support tag numbers +// beyond 31. Consumers must use the constants defined below to decompose or +// assemble tags. +// +// This library treats an element's constructed bit as part of its tag. In DER, +// the constructed bit is computable from the type. The constants for universal +// types have the bit set. Callers must set it correctly for tagged types. +// Explicitly-tagged types are always constructed, and implicitly-tagged types +// inherit the underlying type's bit. + +// CBS_ASN1_TAG_SHIFT is how much the in-memory representation shifts the class +// and constructed bits from the DER serialization. +#define CBS_ASN1_TAG_SHIFT 24 + +// CBS_ASN1_CONSTRUCTED may be ORed into a tag to set the constructed bit. +#define CBS_ASN1_CONSTRUCTED (0x20u << CBS_ASN1_TAG_SHIFT) + +// The following values specify the tag class and may be ORed into a tag number +// to produce the final tag. If none is used, the tag will be UNIVERSAL. +#define CBS_ASN1_UNIVERSAL (0u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_APPLICATION (0x40u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_CONTEXT_SPECIFIC (0x80u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_PRIVATE (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_CLASS_MASK may be ANDed with a tag to query its class. This will +// give one of the four values above. +#define CBS_ASN1_CLASS_MASK (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_TAG_NUMBER_MASK may be ANDed with a tag to query its number. +#define CBS_ASN1_TAG_NUMBER_MASK ((1u << (5 + CBS_ASN1_TAG_SHIFT)) - 1) + +// The following values are constants for UNIVERSAL tags. Note these constants +// include the constructed bit. +#define CBS_ASN1_BOOLEAN 0x1u +#define CBS_ASN1_INTEGER 0x2u +#define CBS_ASN1_BITSTRING 0x3u +#define CBS_ASN1_OCTETSTRING 0x4u +#define CBS_ASN1_NULL 0x5u +#define CBS_ASN1_OBJECT 0x6u +#define CBS_ASN1_ENUMERATED 0xau +#define CBS_ASN1_UTF8STRING 0xcu +#define CBS_ASN1_SEQUENCE (0x10u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_SET (0x11u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_NUMERICSTRING 0x12u +#define CBS_ASN1_PRINTABLESTRING 0x13u +#define CBS_ASN1_T61STRING 0x14u +#define CBS_ASN1_VIDEOTEXSTRING 0x15u +#define CBS_ASN1_IA5STRING 0x16u +#define CBS_ASN1_UTCTIME 0x17u +#define CBS_ASN1_GENERALIZEDTIME 0x18u +#define CBS_ASN1_GRAPHICSTRING 0x19u +#define CBS_ASN1_VISIBLESTRING 0x1au +#define CBS_ASN1_GENERALSTRING 0x1bu +#define CBS_ASN1_UNIVERSALSTRING 0x1cu +#define CBS_ASN1_BMPSTRING 0x1eu + +// CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not +// including tag and length bytes) and advances |cbs| over it. The ASN.1 +// element must match |tag_value|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the +// ASN.1 header bytes too. +OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one +// if the next ASN.1 element on |cbs| would have tag |tag_value|. If +// |cbs| is empty or the tag does not match, it returns zero. Note: if +// it returns one, CBS_get_asn1 may still fail if the rest of the +// element is malformed. +OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); + +// CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs| +// (not including tag and length bytes), sets |*out_tag| to the tag number, and +// advances |*cbs|. It returns one on success and zero on error. Either of |out| +// and |out_tag| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag); + +// CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from +// |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to +// the tag number and |*out_header_len| to the length of the ASN.1 header. Each +// of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + +// CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but +// also allows indefinite-length elements to be returned and does not enforce +// that lengths are minimal. It sets |*out_indefinite| to one if the length was +// indefinite and zero otherwise. If indefinite, |*out_header_len| and +// |CBS_len(out)| will be equal as only the header is returned (although this is +// also true for empty elements so |*out_indefinite| should be checked). If +// |out_ber_found| is not NULL then it is set to one if any case of invalid DER +// but valid BER is found, and to zero otherwise. +// +// This function will not successfully parse an end-of-contents (EOC) as an +// element. Callers parsing indefinite-length encoding must check for EOC +// separately. +OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len, + int *out_ber_found, + int *out_indefinite); + +// CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| +// and sets |*out| to its value. It returns one on success and zero on error, +// where error includes the integer being negative, or too large to represent +// in 64 bits. +OPENSSL_EXPORT int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +// CBS_get_asn1_int64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| +// and sets |*out| to its value. It returns one on success and zero on error, +// where error includes the integer being too large to represent in 64 bits. +OPENSSL_EXPORT int CBS_get_asn1_int64(CBS *cbs, int64_t *out); + +// CBS_get_asn1_bool gets an ASN.1 BOOLEAN from |cbs| and sets |*out| to zero +// or one based on its value. It returns one on success or zero on error. +OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out); + +// CBS_get_optional_asn1 gets an optional explicitly-tagged element from |cbs| +// tagged with |tag| and sets |*out| to its contents, or ignores it if |out| is +// NULL. If present and if |out_present| is not NULL, it sets |*out_present| to +// one, otherwise zero. It returns one on success, whether or not the element +// was present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_octet_string gets an optional +// explicitly-tagged OCTET STRING from |cbs|. If present, it sets +// |*out| to the string and |*out_present| to one. Otherwise, it sets +// |*out| to empty and |*out_present| to zero. |out_present| may be +// NULL. It returns one on success, whether or not the element was +// present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, + int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged +// INTEGER from |cbs|. If present, it sets |*out| to the +// value. Otherwise, it sets |*out| to |default_value|. It returns one +// on success, whether or not the element was present, and zero on +// decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, + unsigned tag, + uint64_t default_value); + +// CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from +// |cbs|. If present, it sets |*out| to either zero or one, based on the +// boolean. Otherwise, it sets |*out| to |default_value|. It returns one on +// success, whether or not the element was present, and zero on decode +// failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value); + +// CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING +// body and zero otherwise. +OPENSSL_EXPORT int CBS_is_valid_asn1_bitstring(const CBS *cbs); + +// CBS_asn1_bitstring_has_bit returns one if |cbs| is a valid ASN.1 BIT STRING +// body and the specified bit is present and set. Otherwise, it returns zero. +// |bit| is indexed starting from zero. +OPENSSL_EXPORT int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit); + +// CBS_is_valid_asn1_integer returns one if |cbs| is a valid ASN.1 INTEGER, +// body and zero otherwise. On success, if |out_is_negative| is non-NULL, +// |*out_is_negative| will be set to one if |cbs| is negative and zero +// otherwise. +OPENSSL_EXPORT int CBS_is_valid_asn1_integer(const CBS *cbs, + int *out_is_negative); + +// CBS_is_unsigned_asn1_integer returns one if |cbs| is a valid non-negative +// ASN.1 INTEGER body and zero otherwise. +OPENSSL_EXPORT int CBS_is_unsigned_asn1_integer(const CBS *cbs); + +// CBS_asn1_oid_to_text interprets |cbs| as DER-encoded ASN.1 OBJECT IDENTIFIER +// contents (not including the element framing) and returns the ASCII +// representation (e.g., "1.2.840.113554.4.1.72585") in a newly-allocated +// string, or NULL on failure. The caller must release the result with +// |OPENSSL_free|. +OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); + + +// CRYPTO ByteBuilder. +// +// |CBB| objects allow one to build length-prefixed serialisations. A |CBB| +// object is associated with a buffer and new buffers are created with +// |CBB_init|. Several |CBB| objects can point at the same buffer when a +// length-prefix is pending, however only a single |CBB| can be 'current' at +// any one time. For example, if one calls |CBB_add_u8_length_prefixed| then +// the new |CBB| points at the same buffer as the original. But if the original +// |CBB| is used then the length prefix is written out and the new |CBB| must +// not be used again. +// +// If one needs to force a length prefix to be written out because a |CBB| is +// going out of scope, use |CBB_flush|. If an operation on a |CBB| fails, it is +// in an undefined state and must not be used except to call |CBB_cleanup|. + +struct cbb_buffer_st { + uint8_t *buf; + size_t len; // The number of valid bytes. + size_t cap; // The size of buf. + char can_resize; /* One iff |buf| is owned by this object. If not then |buf| + cannot be resized. */ + char error; /* One iff there was an error writing to this CBB. All future + operations will fail. */ +}; + +struct cbb_st { + struct cbb_buffer_st *base; + // child points to a child CBB if a length-prefix is pending. + CBB *child; + // offset is the number of bytes from the start of |base->buf| to this |CBB|'s + // pending length prefix. + size_t offset; + // pending_len_len contains the number of bytes in this |CBB|'s pending + // length-prefix, or zero if no length-prefix is pending. + uint8_t pending_len_len; + char pending_is_asn1; + // is_child is true iff this is a child |CBB| (as opposed to a top-level + // |CBB|). Top-level objects are valid arguments for |CBB_finish|. + char is_child; +}; + +// CBB_zero sets an uninitialised |cbb| to the zero state. It must be +// initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to +// call |CBB_cleanup| without a successful |CBB_init|. This may be used for more +// uniform cleanup of a |CBB|. +OPENSSL_EXPORT void CBB_zero(CBB *cbb); + +// CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as +// needed, the |initial_capacity| is just a hint. It returns one on success or +// zero on allocation failure. +OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity); + +// CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since +// |buf| cannot grow, trying to write more than |len| bytes will cause CBB +// functions to fail. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +// CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects +// writing to the same buffer. This should be used in an error case where a +// serialisation is abandoned. +// +// This function can only be called on a "top level" |CBB|, i.e. one initialised +// with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with +// |CBB_zero|. +OPENSSL_EXPORT void CBB_cleanup(CBB *cbb); + +// CBB_finish completes any pending length prefix and sets |*out_data| to a +// malloced buffer and |*out_len| to the length of that buffer. The caller +// takes ownership of the buffer and, unless the buffer was fixed with +// |CBB_init_fixed|, must call |OPENSSL_free| when done. +// +// It can only be called on a "top level" |CBB|, i.e. one initialised with +// |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +// CBB_flush causes any pending length prefixes to be written out and any child +// |CBB| objects of |cbb| to be invalidated. This allows |cbb| to continue to be +// used after the children go out of scope, e.g. when local |CBB| objects are +// added as children to a |CBB| that persists after a function returns. This +// function returns one on success or zero on error. +OPENSSL_EXPORT int CBB_flush(CBB *cbb); + +// CBB_data returns a pointer to the bytes written to |cbb|. It does not flush +// |cbb|. The pointer is valid until the next operation to |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT const uint8_t *CBB_data(const CBB *cbb); + +// CBB_len returns the number of bytes written to |cbb|. It does not flush +// |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT size_t CBB_len(const CBB *cbb); + +// CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The +// data written to |*out_contents| will be prefixed in |cbb| with an 8-bit +// length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an +// ASN.1 object can be written. The |tag| argument will be used as the tag for +// the object. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag); + +// CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +// CBB_add_zeros append |len| bytes with value zero to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_zeros(CBB *cbb, size_t len); + +// CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to +// the beginning of that space. The caller must then write |len| bytes of +// actual contents to |*out_data|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_reserve ensures |cbb| has room for |len| additional bytes and sets +// |*out_data| to point to the beginning of that space. It returns one on +// success and zero otherwise. The caller may write up to |len| bytes to +// |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is +// valid until the next operation on |cbb| or an ancestor |CBB|. +OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_did_write advances |cbb| by |len| bytes, assuming the space has been +// written to by the caller. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len); + +// CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value); + +// CBB_add_u16 appends a 16-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value); + +// CBB_add_u16le appends a 16-bit, little-endian number from |value| to |cbb|. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u16le(CBB *cbb, uint16_t value); + +// CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value); + +// CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u32(CBB *cbb, uint32_t value); + +// CBB_add_u32le appends a 32-bit, little-endian number from |value| to |cbb|. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u32le(CBB *cbb, uint32_t value); + +// CBB_add_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u64(CBB *cbb, uint64_t value); + +// CBB_add_u64le appends a 64-bit, little-endian number from |value| to |cbb|. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u64le(CBB *cbb, uint64_t value); + +// CBB_discard_child discards the current unflushed child of |cbb|. Neither the +// child's contents nor the length prefix will be included in the output. +OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); + +// CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| +// and writes |value| in its contents. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +// CBB_add_asn1_int64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| +// and writes |value| in its contents. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_add_asn1_int64(CBB *cbb, int64_t value); + +// CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the +// given contents. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, + size_t data_len); + +// CBB_add_asn1_bool writes an ASN.1 BOOLEAN into |cbb| which is true iff +// |value| is non-zero. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_bool(CBB *cbb, int value); + +// CBB_add_asn1_oid_from_text decodes |len| bytes from |text| as an ASCII OID +// representation, e.g. "1.2.840.113554.4.1.72585", and writes the DER-encoded +// contents to |cbb|. It returns one on success and zero on malloc failure or if +// |text| was invalid. It does not include the OBJECT IDENTIFER framing, only +// the element's contents. +// +// This function considers OID strings with components which do not fit in a +// |uint64_t| to be invalid. +OPENSSL_EXPORT int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, + size_t len); + +// CBB_flush_asn1_set_of calls |CBB_flush| on |cbb| and then reorders the +// contents for a DER-encoded ASN.1 SET OF type. It returns one on success and +// zero on failure. DER canonicalizes SET OF contents by sorting +// lexicographically by encoding. Call this function when encoding a SET OF +// type in an order that is not already known to be canonical. +// +// Note a SET type has a slightly different ordering than a SET OF. +OPENSSL_EXPORT int CBB_flush_asn1_set_of(CBB *cbb); + + +#if defined(__cplusplus) +} // extern C + + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +using ScopedCBB = internal::StackAllocated; + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cast.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cast.h new file mode 100644 index 00000000..2ef52e11 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cast.h @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CAST_H +#define OPENSSL_HEADER_CAST_H + +#include "CNIOBoringSSL_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + uint32_t data[32]; + int short_key; // Use reduced rounds for short key +} CAST_KEY; + +OPENSSL_EXPORT void CAST_set_key(CAST_KEY *key, size_t len, + const uint8_t *data); +OPENSSL_EXPORT void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, + const CAST_KEY *key, int enc); +OPENSSL_EXPORT void CAST_encrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_decrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const CAST_KEY *ks, + uint8_t *iv, int enc); + +OPENSSL_EXPORT void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, + size_t length, const CAST_KEY *schedule, + uint8_t *ivec, int *num, int enc); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_CAST_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_chacha.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_chacha.h new file mode 100644 index 00000000..bd53c03a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_chacha.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CHACHA_H +#define OPENSSL_HEADER_CHACHA_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +// ChaCha20. +// +// ChaCha20 is a stream cipher. See https://tools.ietf.org/html/rfc8439. + + +// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and +// nonce and writes the result to |out|. If |in| and |out| alias, they must be +// equal. The initial block counter is specified by |counter|. +OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, + size_t in_len, const uint8_t key[32], + const uint8_t nonce[12], uint32_t counter); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CHACHA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h new file mode 100644 index 00000000..94fde586 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h @@ -0,0 +1,673 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CIPHER_H +#define OPENSSL_HEADER_CIPHER_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Ciphers. + + +// Cipher primitives. +// +// The following functions return |EVP_CIPHER| objects that implement the named +// cipher algorithm. + +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ofb(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_xts(void); + +// EVP_enc_null returns a 'cipher' that passes plaintext through as +// ciphertext. +OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void); + +// EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void); + +// EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This +// is obviously very, very weak and is included only in order to read PKCS#12 +// files, which often encrypt the certificate chain using this cipher. It is +// deliberately not exported. +const EVP_CIPHER *EVP_rc2_40_cbc(void); + +// EVP_get_cipherbynid returns the cipher corresponding to the given NID, or +// NULL if no such cipher is known. Note using this function links almost every +// cipher implemented by BoringSSL into the binary, whether the caller uses them +// or not. Size-conscious callers, such as client software, should not use this +// function. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbynid(int nid); + + +// Cipher context allocation. +// +// An |EVP_CIPHER_CTX| represents the state of an encryption or decryption in +// progress. + +// EVP_CIPHER_CTX_init initialises an, already allocated, |EVP_CIPHER_CTX|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_new allocates a fresh |EVP_CIPHER_CTX|, calls +// |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. +OPENSSL_EXPORT EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); + +// EVP_CIPHER_CTX_cleanup frees any memory referenced by |ctx|. It returns +// one. +OPENSSL_EXPORT int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_free calls |EVP_CIPHER_CTX_cleanup| on |ctx| and then frees +// |ctx| itself. +OPENSSL_EXPORT void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_copy sets |out| to be a duplicate of the current state of +// |in|. The |out| argument must have been previously initialised. +OPENSSL_EXPORT int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, + const EVP_CIPHER_CTX *in); + +// EVP_CIPHER_CTX_reset calls |EVP_CIPHER_CTX_cleanup| followed by +// |EVP_CIPHER_CTX_init| and returns one. +OPENSSL_EXPORT int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); + + +// Cipher context configuration. + +// EVP_CipherInit_ex configures |ctx| for a fresh encryption (or decryption, if +// |enc| is zero) operation using |cipher|. If |ctx| has been previously +// configured with a cipher then |cipher|, |key| and |iv| may be |NULL| and +// |enc| may be -1 to reuse the previous values. The operation will use |key| +// as the key and |iv| as the IV (if any). These should have the correct +// lengths given by |EVP_CIPHER_key_length| and |EVP_CIPHER_iv_length|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *engine, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + +// EVP_DecryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + + +// Cipher operations. + +// EVP_EncryptUpdate encrypts |in_len| bytes from |in| to |out|. The number +// of output bytes may be up to |in_len| plus the block length minus one and +// |out| must have sufficient space. The number of bytes actually output is +// written to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_EncryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then standard padding is applied to create the final block. If +// padding is disabled (with |EVP_CIPHER_CTX_set_padding|) then any partial +// block remaining will cause an error. The function returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecryptUpdate decrypts |in_len| bytes from |in| to |out|. The number of +// output bytes may be up to |in_len| plus the block length minus one and |out| +// must have sufficient space. The number of bytes actually output is written +// to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_DecryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then padding is removed from the final block. +// +// WARNING: it is unsafe to call this function with unauthenticated +// ciphertext if padding is enabled. +OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_Cipher performs a one-shot encryption/decryption operation. No partial +// blocks are maintained between calls. However, any internal cipher state is +// still updated. For CBC-mode ciphers, the IV is updated to the final +// ciphertext block. For stream ciphers, the stream is advanced past the bytes +// used. It returns one on success and zero otherwise, unless |EVP_CIPHER_flags| +// has |EVP_CIPH_FLAG_CUSTOM_CIPHER| set. Then it returns the number of bytes +// written or -1 on error. +// +// WARNING: this differs from the usual return value convention when using +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. +// +// TODO(davidben): The normal ciphers currently never fail, even if, e.g., +// |in_len| is not a multiple of the block size for CBC-mode decryption. The +// input just gets rounded up while the output gets truncated. This should +// either be officially documented or fail. +OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len); + +// EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate| +// depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_CipherFinal_ex calls either |EVP_EncryptFinal_ex| or +// |EVP_DecryptFinal_ex| depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + + +// Cipher context accessors. + +// EVP_CIPHER_CTX_cipher returns the |EVP_CIPHER| underlying |ctx|, or NULL if +// none has been set. +OPENSSL_EXPORT const EVP_CIPHER *EVP_CIPHER_CTX_cipher( + const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_nid returns a NID identifying the |EVP_CIPHER| underlying +// |ctx| (e.g. |NID_aes_128_gcm|). It will crash if no cipher has been +// configured. +OPENSSL_EXPORT int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_encrypting returns one if |ctx| is configured for encryption +// and zero otherwise. +OPENSSL_EXPORT int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher +// underlying |ctx|, or one if the cipher is a stream cipher. It will crash if +// no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_key_length returns the key size, in bytes, of the cipher +// underlying |ctx| or zero if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_iv_length returns the IV size, in bytes, of the cipher +// underlying |ctx|. It will crash if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_get_app_data returns the opaque, application data pointer for +// |ctx|, or NULL if none has been set. +OPENSSL_EXPORT void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_set_app_data sets the opaque, application data pointer for +// |ctx| to |data|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, + void *data); + +// EVP_CIPHER_CTX_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_mode returns one of the |EVP_CIPH_*| cipher mode values +// enumerated below. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_ctrl is an |ioctl| like function. The |command| argument +// should be one of the |EVP_CTRL_*| values. The |arg| and |ptr| arguments are +// specific to the command in question. +OPENSSL_EXPORT int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, + int arg, void *ptr); + +// EVP_CIPHER_CTX_set_padding sets whether padding is enabled for |ctx| and +// returns one. Pass a non-zero |pad| to enable padding (the default) or zero +// to disable. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); + +// EVP_CIPHER_CTX_set_key_length sets the key length for |ctx|. This is only +// valid for ciphers that can take a variable length key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *ctx, + unsigned key_len); + + +// Cipher accessors. + +// EVP_CIPHER_nid returns a NID identifying |cipher|. (For example, +// |NID_aes_128_gcm|.) +OPENSSL_EXPORT int EVP_CIPHER_nid(const EVP_CIPHER *cipher); + +// EVP_CIPHER_block_size returns the block size, in bytes, for |cipher|, or one +// if |cipher| is a stream cipher. +OPENSSL_EXPORT unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher); + +// EVP_CIPHER_key_length returns the key size, in bytes, for |cipher|. If +// |cipher| can take a variable key length then this function returns the +// default key length and |EVP_CIPHER_flags| will return a value with +// |EVP_CIPH_VARIABLE_LENGTH| set. +OPENSSL_EXPORT unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_iv_length returns the IV size, in bytes, of |cipher|, or zero if +// |cipher| doesn't take an IV. +OPENSSL_EXPORT unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. +OPENSSL_EXPORT uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher); + +// EVP_CIPHER_mode returns one of the cipher mode values enumerated below. +OPENSSL_EXPORT uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher); + + +// Key derivation. + +// EVP_BytesToKey generates a key and IV for the cipher |type| by iterating +// |md| |count| times using |data| and |salt|. On entry, the |key| and |iv| +// buffers must have enough space to hold a key and IV for |type|. It returns +// the length of the key on success or zero on error. +OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, + size_t data_len, unsigned count, uint8_t *key, + uint8_t *iv); + + +// Cipher modes (for |EVP_CIPHER_mode|). + +#define EVP_CIPH_STREAM_CIPHER 0x0 +#define EVP_CIPH_ECB_MODE 0x1 +#define EVP_CIPH_CBC_MODE 0x2 +#define EVP_CIPH_CFB_MODE 0x3 +#define EVP_CIPH_OFB_MODE 0x4 +#define EVP_CIPH_CTR_MODE 0x5 +#define EVP_CIPH_GCM_MODE 0x6 +#define EVP_CIPH_XTS_MODE 0x7 + + +// Cipher flags (for |EVP_CIPHER_flags|). + +// EVP_CIPH_VARIABLE_LENGTH indicates that the cipher takes a variable length +// key. +#define EVP_CIPH_VARIABLE_LENGTH 0x40 + +// EVP_CIPH_ALWAYS_CALL_INIT indicates that the |init| function for the cipher +// should always be called when initialising a new operation, even if the key +// is NULL to indicate that the same key is being used. +#define EVP_CIPH_ALWAYS_CALL_INIT 0x80 + +// EVP_CIPH_CUSTOM_IV indicates that the cipher manages the IV itself rather +// than keeping it in the |iv| member of |EVP_CIPHER_CTX|. +#define EVP_CIPH_CUSTOM_IV 0x100 + +// EVP_CIPH_CTRL_INIT indicates that EVP_CTRL_INIT should be used when +// initialising an |EVP_CIPHER_CTX|. +#define EVP_CIPH_CTRL_INIT 0x200 + +// EVP_CIPH_FLAG_CUSTOM_CIPHER indicates that the cipher manages blocking +// itself. This causes EVP_(En|De)crypt_ex to be simple wrapper functions. +#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x400 + +// EVP_CIPH_FLAG_AEAD_CIPHER specifies that the cipher is an AEAD. This is an +// older version of the proper AEAD interface. See aead.h for the current +// one. +#define EVP_CIPH_FLAG_AEAD_CIPHER 0x800 + +// EVP_CIPH_CUSTOM_COPY indicates that the |ctrl| callback should be called +// with |EVP_CTRL_COPY| at the end of normal |EVP_CIPHER_CTX_copy| +// processing. +#define EVP_CIPH_CUSTOM_COPY 0x1000 + +// EVP_CIPH_FLAG_NON_FIPS_ALLOW is meaningless. In OpenSSL it permits non-FIPS +// algorithms in FIPS mode. But BoringSSL FIPS mode doesn't prohibit algorithms +// (it's up the the caller to use the FIPS module in a fashion compliant with +// their needs). Thus this exists only to allow code to compile. +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0 + + +// Deprecated functions + +// EVP_CipherInit acts like EVP_CipherInit_ex except that |EVP_CIPHER_CTX_init| +// is called on |cipher| first, if |cipher| is not NULL. +OPENSSL_EXPORT int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit calls |EVP_CipherInit| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_DecryptInit calls |EVP_CipherInit| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_CipherFinal calls |EVP_CipherFinal_ex|. +OPENSSL_EXPORT int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_EncryptFinal calls |EVP_EncryptFinal_ex|. +OPENSSL_EXPORT int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecryptFinal calls |EVP_DecryptFinal_ex|. +OPENSSL_EXPORT int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_add_cipher_alias does nothing and returns one. +OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); + +// EVP_get_cipherbyname returns an |EVP_CIPHER| given a human readable name in +// |name|, or NULL if the name is unknown. Note using this function links almost +// every cipher implemented by BoringSSL into the binary, not just the ones the +// caller requests. Size-conscious callers, such as client software, should not +// use this function. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name); + +// These AEADs are deprecated AES-GCM implementations that set +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and +// |EVP_aead_aes_256_gcm| instead. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void); + +// These are deprecated, 192-bit version of AES. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ofb(void); + +// EVP_des_ede3_ecb is an alias for |EVP_des_ede3|. Use the former instead. +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_ecb(void); + +// EVP_aes_128_cfb128 is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb128(void); + +// EVP_aes_128_cfb is an alias for |EVP_aes_128_cfb128| and is only available in +// decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb(void); + +// EVP_aes_192_cfb128 is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cfb128(void); + +// EVP_aes_192_cfb is an alias for |EVP_aes_192_cfb128| and is only available in +// decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cfb(void); + +// EVP_aes_256_cfb128 is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void); + +// EVP_aes_256_cfb is an alias for |EVP_aes_256_cfb128| and is only available in +// decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb(void); + +// EVP_bf_ecb is Blowfish in ECB mode and is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_bf_ecb(void); + +// EVP_bf_cbc is Blowfish in CBC mode and is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_bf_cbc(void); + +// EVP_bf_cfb is Blowfish in 64-bit CFB mode and is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_bf_cfb(void); + +// EVP_cast5_ecb is CAST5 in ECB mode and is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_cast5_ecb(void); + +// EVP_cast5_cbc is CAST5 in CBC mode and is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_cast5_cbc(void); + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define EVP_CIPH_CCM_MODE (-1) +#define EVP_CIPH_OCB_MODE (-2) +#define EVP_CIPH_WRAP_MODE (-3) +#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 + +// EVP_CIPHER_CTX_set_flags does nothing. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, + uint32_t flags); + + +// Private functions. + +// EVP_CIPH_NO_PADDING disables padding in block ciphers. +#define EVP_CIPH_NO_PADDING 0x800 + +// The following are |EVP_CIPHER_CTX_ctrl| commands. +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +#define EVP_CTRL_GET_RC5_ROUNDS 0x4 +#define EVP_CTRL_SET_RC5_ROUNDS 0x5 +#define EVP_CTRL_RAND_KEY 0x6 +#define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 +#define EVP_CTRL_AEAD_SET_IVLEN 0x9 +#define EVP_CTRL_AEAD_GET_TAG 0x10 +#define EVP_CTRL_AEAD_SET_TAG 0x11 +#define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_IV_GEN 0x13 +#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +// EVP_CTRL_GCM_SET_IV_INV sets the GCM invocation field, decrypt only +#define EVP_CTRL_GCM_SET_IV_INV 0x18 + +// The following constants are unused. +#define EVP_GCM_TLS_FIXED_IV_LEN 4 +#define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +#define EVP_GCM_TLS_TAG_LEN 16 + +// The following are legacy aliases for AEAD |EVP_CIPHER_CTX_ctrl| values. +#define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +#define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +#define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +#define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED + +#define EVP_MAX_KEY_LENGTH 64 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +struct evp_cipher_ctx_st { + // cipher contains the underlying cipher for this context. + const EVP_CIPHER *cipher; + + // app_data is a pointer to opaque, user data. + void *app_data; // application stuff + + // cipher_data points to the |cipher| specific state. + void *cipher_data; + + // key_len contains the length of the key, which may differ from + // |cipher->key_len| if the cipher can take a variable key length. + unsigned key_len; + + // encrypt is one if encrypting and zero if decrypting. + int encrypt; + + // flags contains the OR of zero or more |EVP_CIPH_*| flags, above. + uint32_t flags; + + // oiv contains the original IV value. + uint8_t oiv[EVP_MAX_IV_LENGTH]; + + // iv contains the current IV value, which may have been updated. + uint8_t iv[EVP_MAX_IV_LENGTH]; + + // buf contains a partial block which is used by, for example, CTR mode to + // store unused keystream bytes. + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + + // buf_len contains the number of bytes of a partial block contained in + // |buf|. + int buf_len; + + // num contains the number of bytes of |iv| which are valid for modes that + // manage partial blocks themselves. + unsigned num; + + // final_used is non-zero if the |final| buffer contains plaintext. + int final_used; + + uint8_t final[EVP_MAX_BLOCK_LENGTH]; // possible final block +} /* EVP_CIPHER_CTX */; + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_st { + // type contains a NID identifing the cipher. (e.g. NID_aes_128_gcm.) + int nid; + + // block_size contains the block size, in bytes, of the cipher, or 1 for a + // stream cipher. + unsigned block_size; + + // key_len contains the key size, in bytes, for the cipher. If the cipher + // takes a variable key size then this contains the default size. + unsigned key_len; + + // iv_len contains the IV size, in bytes, or zero if inapplicable. + unsigned iv_len; + + // ctx_size contains the size, in bytes, of the per-key context for this + // cipher. + unsigned ctx_size; + + // flags contains the OR of a number of flags. See |EVP_CIPH_*|. + uint32_t flags; + + // app_data is a pointer to opaque, user data. + void *app_data; + + int (*init)(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, + int enc); + + int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl); + + // cleanup, if non-NULL, releases memory associated with the context. It is + // called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been + // called at this point. + void (*cleanup)(EVP_CIPHER_CTX *); + + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); +}; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free) + +using ScopedEVP_CIPHER_CTX = + internal::StackAllocated; + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#define CIPHER_R_AES_KEY_SETUP_FAILED 100 +#define CIPHER_R_BAD_DECRYPT 101 +#define CIPHER_R_BAD_KEY_LENGTH 102 +#define CIPHER_R_BUFFER_TOO_SMALL 103 +#define CIPHER_R_CTRL_NOT_IMPLEMENTED 104 +#define CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED 105 +#define CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 106 +#define CIPHER_R_INITIALIZATION_ERROR 107 +#define CIPHER_R_INPUT_NOT_INITIALIZED 108 +#define CIPHER_R_INVALID_AD_SIZE 109 +#define CIPHER_R_INVALID_KEY_LENGTH 110 +#define CIPHER_R_INVALID_NONCE_SIZE 111 +#define CIPHER_R_INVALID_OPERATION 112 +#define CIPHER_R_IV_TOO_LARGE 113 +#define CIPHER_R_NO_CIPHER_SET 114 +#define CIPHER_R_OUTPUT_ALIASES_INPUT 115 +#define CIPHER_R_TAG_TOO_LARGE 116 +#define CIPHER_R_TOO_LARGE 117 +#define CIPHER_R_UNSUPPORTED_AD_SIZE 118 +#define CIPHER_R_UNSUPPORTED_INPUT_SIZE 119 +#define CIPHER_R_UNSUPPORTED_KEY_SIZE 120 +#define CIPHER_R_UNSUPPORTED_NONCE_SIZE 121 +#define CIPHER_R_UNSUPPORTED_TAG_SIZE 122 +#define CIPHER_R_WRONG_FINAL_BLOCK_LENGTH 123 +#define CIPHER_R_NO_DIRECTION_SET 124 +#define CIPHER_R_INVALID_NONCE 125 + +#endif // OPENSSL_HEADER_CIPHER_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cmac.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cmac.h new file mode 100644 index 00000000..0f7fd2b9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cmac.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CMAC_H +#define OPENSSL_HEADER_CMAC_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CMAC. +// +// CMAC is a MAC based on AES-CBC and defined in +// https://tools.ietf.org/html/rfc4493#section-2.3. + + +// One-shot functions. + +// AES_CMAC calculates the 16-byte, CMAC authenticator of |in_len| bytes of +// |in| and writes it to |out|. The |key_len| may be 16 or 32 bytes to select +// between AES-128 and AES-256. It returns one on success or zero on error. +OPENSSL_EXPORT int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len); + + +// Incremental interface. + +// CMAC_CTX_new allocates a fresh |CMAC_CTX| and returns it, or NULL on +// error. +OPENSSL_EXPORT CMAC_CTX *CMAC_CTX_new(void); + +// CMAC_CTX_free frees a |CMAC_CTX|. +OPENSSL_EXPORT void CMAC_CTX_free(CMAC_CTX *ctx); + +// CMAC_CTX_copy sets |out| to be a duplicate of the current state |in|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +// CMAC_Init configures |ctx| to use the given |key| and |cipher|. The CMAC RFC +// only specifies the use of AES-128 thus |key_len| should be 16 and |cipher| +// should be |EVP_aes_128_cbc()|. However, this implementation also supports +// AES-256 by setting |key_len| to 32 and |cipher| to |EVP_aes_256_cbc()|. The +// |engine| argument is ignored. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine); + + +// CMAC_Reset resets |ctx| so that a fresh message can be authenticated. +OPENSSL_EXPORT int CMAC_Reset(CMAC_CTX *ctx); + +// CMAC_Update processes |in_len| bytes of message from |in|. It returns one on +// success or zero on error. +OPENSSL_EXPORT int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len); + +// CMAC_Final sets |*out_len| to 16 and, if |out| is not NULL, writes 16 bytes +// of authenticator to it. It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CMAC_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h new file mode 100644 index 00000000..6967667a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h @@ -0,0 +1,183 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_CONF_H +#define OPENSSL_HEADER_CONF_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_stack.h" +#include "CNIOBoringSSL_lhash.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Config files look like: +// +// # Comment +// +// # This key is in the default section. +// key=value +// +// [section_name] +// key2=value2 +// +// Config files are represented by a |CONF|. + +struct conf_value_st { + char *section; + char *name; + char *value; +}; + +DEFINE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE) + + +// NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method| +// argument must be NULL. +OPENSSL_EXPORT CONF *NCONF_new(void *method); + +// NCONF_free frees all the data owned by |conf| and then |conf| itself. +OPENSSL_EXPORT void NCONF_free(CONF *conf); + +// NCONF_load parses the file named |filename| and adds the values found to +// |conf|. It returns one on success and zero on error. In the event of an +// error, if |out_error_line| is not NULL, |*out_error_line| is set to the +// number of the line that contained the error. +OPENSSL_EXPORT int NCONF_load(CONF *conf, const char *filename, + long *out_error_line); + +// NCONF_load_bio acts like |NCONF_load| but reads from |bio| rather than from +// a named file. +OPENSSL_EXPORT int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line); + +// NCONF_get_section returns a stack of values for a given section in |conf|. +// If |section| is NULL, the default section is returned. It returns NULL on +// error. +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); + +// NCONF_get_string returns the value of the key |name|, in section |section|. +// The |section| argument may be NULL to indicate the default section. It +// returns the value or NULL on error. +OPENSSL_EXPORT const char *NCONF_get_string(const CONF *conf, + const char *section, + const char *name); + + +// Utility functions + +// CONF_parse_list takes a list separated by 'sep' and calls |list_cb| giving +// the start and length of each member, optionally stripping leading and +// trailing whitespace. This can be used to parse comma separated lists for +// example. If |list_cb| returns <= 0, then the iteration is halted and that +// value is returned immediately. Otherwise it returns one. Note that |list_cb| +// may be called on an empty member. +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg); + + +// Deprecated functions + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CONF_MFLAGS_DEFAULT_SECTION 0 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0 + +// CONF_modules_load_file returns one. BoringSSL is defined to have no config +// file options, thus loading from |filename| always succeeds by doing nothing. +OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, + const char *appname, + unsigned long flags); + +// CONF_modules_free does nothing. +OPENSSL_EXPORT void CONF_modules_free(void); + +// OPENSSL_config does nothing. +OPENSSL_EXPORT void OPENSSL_config(const char *config_name); + +// OPENSSL_no_config does nothing. +OPENSSL_EXPORT void OPENSSL_no_config(void); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(CONF, NCONF_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define CONF_R_LIST_CANNOT_BE_NULL 100 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 101 +#define CONF_R_MISSING_EQUAL_SIGN 102 +#define CONF_R_NO_CLOSE_BRACE 103 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 104 +#define CONF_R_VARIABLE_HAS_NO_VALUE 105 +#define CONF_R_VARIABLE_EXPANSION_TOO_LONG 106 + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cpu.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cpu.h new file mode 100644 index 00000000..51c4d02d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_cpu.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This header is provided for compatibility with older revisions of BoringSSL. +// TODO(davidben): Remove this header. + +#include "CNIOBoringSSL_crypto.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h new file mode 100644 index 00000000..8737398e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h @@ -0,0 +1,198 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_H +#define OPENSSL_HEADER_CRYPTO_H + +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_sha.h" + +// Upstream OpenSSL defines |OPENSSL_malloc|, etc., in crypto.h rather than +// mem.h. +#include "CNIOBoringSSL_mem.h" + +// Upstream OpenSSL defines |CRYPTO_LOCK|, etc., in crypto.h rather than +// thread.h. +#include "CNIOBoringSSL_thread.h" + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// crypto.h contains functions for initializing the crypto library. + + +// CRYPTO_library_init initializes the crypto library. It must be called if the +// library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does +// nothing and a static initializer is used instead. It is safe to call this +// function multiple times and concurrently from multiple threads. +// +// On some ARM configurations, this function may require filesystem access and +// should be called before entering a sandbox. +OPENSSL_EXPORT void CRYPTO_library_init(void); + +// CRYPTO_is_confidential_build returns one if the linked version of BoringSSL +// has been built with the BORINGSSL_CONFIDENTIAL define and zero otherwise. +// +// This is used by some consumers to identify whether they are using an +// internal version of BoringSSL. +OPENSSL_EXPORT int CRYPTO_is_confidential_build(void); + +// CRYPTO_has_asm returns one unless BoringSSL was built with OPENSSL_NO_ASM, +// in which case it returns zero. +OPENSSL_EXPORT int CRYPTO_has_asm(void); + +// BORINGSSL_self_test triggers the FIPS KAT-based self tests. It returns one on +// success and zero on error. +OPENSSL_EXPORT int BORINGSSL_self_test(void); + +// BORINGSSL_integrity_test triggers the module's integrity test where the code +// and data of the module is matched against a hash injected at build time. It +// returns one on success or zero if there's a mismatch. This function only +// exists if the module was built in FIPS mode without ASAN. +OPENSSL_EXPORT int BORINGSSL_integrity_test(void); + +// CRYPTO_pre_sandbox_init initializes the crypto library, pre-acquiring some +// unusual resources to aid running in sandboxed environments. It is safe to +// call this function multiple times and concurrently from multiple threads. +// +// For more details on using BoringSSL in a sandboxed environment, see +// SANDBOXING.md in the source tree. +OPENSSL_EXPORT void CRYPTO_pre_sandbox_init(void); + +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_has_broken_NEON returns one if the current CPU is known to have a +// broken NEON unit. See https://crbug.com/341598. +OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); + +// CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 +// workaround was needed. See https://crbug.com/boringssl/46. +OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); +#endif // OPENSSL_ARM && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP + + +// FIPS monitoring + +// FIPS_mode returns zero unless BoringSSL is built with BORINGSSL_FIPS, in +// which case it returns one. +OPENSSL_EXPORT int FIPS_mode(void); + +// fips_counter_t denotes specific APIs/algorithms. A counter is maintained for +// each in FIPS mode so that tests can be written to assert that the expected, +// FIPS functions are being called by a certain peice of code. +enum fips_counter_t { + fips_counter_evp_aes_128_gcm = 0, + fips_counter_evp_aes_256_gcm = 1, + fips_counter_evp_aes_128_ctr = 2, + fips_counter_evp_aes_256_ctr = 3, + + fips_counter_max = 3, +}; + +// FIPS_read_counter returns a counter of the number of times the specific +// function denoted by |counter| has been used. This always returns zero unless +// BoringSSL was built with BORINGSSL_FIPS_COUNTERS defined. +OPENSSL_EXPORT size_t FIPS_read_counter(enum fips_counter_t counter); + + +// Deprecated functions. + +// OPENSSL_VERSION_TEXT contains a string the identifies the version of +// “OpenSSL”. node.js requires a version number in this text. +#define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1 (compatible; BoringSSL)" + +#define OPENSSL_VERSION 0 +#define OPENSSL_CFLAGS 1 +#define OPENSSL_BUILT_ON 2 +#define OPENSSL_PLATFORM 3 +#define OPENSSL_DIR 4 + +// OpenSSL_version is a compatibility function that returns the string +// "BoringSSL" if |which| is |OPENSSL_VERSION| and placeholder strings +// otherwise. +OPENSSL_EXPORT const char *OpenSSL_version(int which); + +#define SSLEAY_VERSION OPENSSL_VERSION +#define SSLEAY_CFLAGS OPENSSL_CFLAGS +#define SSLEAY_BUILT_ON OPENSSL_BUILT_ON +#define SSLEAY_PLATFORM OPENSSL_PLATFORM +#define SSLEAY_DIR OPENSSL_DIR + +// SSLeay_version calls |OpenSSL_version|. +OPENSSL_EXPORT const char *SSLeay_version(int which); + +// SSLeay is a compatibility function that returns OPENSSL_VERSION_NUMBER from +// base.h. +OPENSSL_EXPORT unsigned long SSLeay(void); + +// OpenSSL_version_num is a compatibility function that returns +// OPENSSL_VERSION_NUMBER from base.h. +OPENSSL_EXPORT unsigned long OpenSSL_version_num(void); + +// CRYPTO_malloc_init returns one. +OPENSSL_EXPORT int CRYPTO_malloc_init(void); + +// OPENSSL_malloc_init returns one. +OPENSSL_EXPORT int OPENSSL_malloc_init(void); + +// ENGINE_load_builtin_engines does nothing. +OPENSSL_EXPORT void ENGINE_load_builtin_engines(void); + +// ENGINE_register_all_complete returns one. +OPENSSL_EXPORT int ENGINE_register_all_complete(void); + +// OPENSSL_load_builtin_modules does nothing. +OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); + +#define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_LOAD_CONFIG 0 +#define OPENSSL_INIT_NO_LOAD_CONFIG 0 + +// OPENSSL_init_crypto calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_crypto(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + +// OPENSSL_cleanup does nothing. +OPENSSL_EXPORT void OPENSSL_cleanup(void); + +// FIPS_mode_set returns one if |on| matches whether BoringSSL was built with +// |BORINGSSL_FIPS| and zero otherwise. +OPENSSL_EXPORT int FIPS_mode_set(int on); + +// FIPS_version returns the version of the FIPS module, or zero if the build +// isn't exactly at a verified version. The version, expressed in base 10, will +// be a date in the form yyyymmddXX where XX is often "00", but can be +// incremented if multiple versions are defined on a single day. +// +// (This format exceeds a |uint32_t| in the year 4294.) +OPENSSL_EXPORT uint32_t FIPS_version(void); + +// FIPS_query_algorithm_status returns one if |algorithm| is FIPS validated in +// the current BoringSSL and zero otherwise. +OPENSSL_EXPORT int FIPS_query_algorithm_status(const char *algorithm); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_curve25519.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_curve25519.h new file mode 100644 index 00000000..605d25bb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_curve25519.h @@ -0,0 +1,201 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_H +#define OPENSSL_HEADER_CURVE25519_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Curve25519. +// +// Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. + + +// X25519. +// +// X25519 is the Diffie-Hellman primitive built from curve25519. It is +// sometimes referred to as “curve25519”, but “X25519” is a more precise name. +// See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. + +#define X25519_PRIVATE_KEY_LEN 32 +#define X25519_PUBLIC_VALUE_LEN 32 +#define X25519_SHARED_KEY_LEN 32 + +// X25519_keypair sets |out_public_value| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32], + uint8_t out_private_key[32]); + +// X25519 writes a shared key to |out_shared_key| that is calculated from the +// given private key and the peer's public value. It returns one on success and +// zero on error. +// +// Don't use the shared key directly, rather use a KDF and also include the two +// public values as inputs. +OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32], + const uint8_t private_key[32], + const uint8_t peer_public_value[32]); + +// X25519_public_from_private calculates a Diffie-Hellman public value from the +// given private key and writes it to |out_public_value|. +OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]); + + +// Ed25519. +// +// Ed25519 is a signature scheme using a twisted-Edwards curve that is +// birationally equivalent to curve25519. +// +// Note that, unlike RFC 8032's formulation, our private key representation +// includes a public key suffix to make multiple key signing operations with the +// same key more efficient. The RFC 8032 private key is referred to in this +// implementation as the "seed" and is the first 32 bytes of our private key. + +#define ED25519_PRIVATE_KEY_LEN 64 +#define ED25519_PUBLIC_KEY_LEN 32 +#define ED25519_SIGNATURE_LEN 64 + +// ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32], + uint8_t out_private_key[64]); + +// ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from +// |message| using |private_key|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, + const uint8_t private_key[64]); + +// ED25519_verify returns one iff |signature| is a valid signature, by +// |public_key| of |message_len| bytes from |message|. It returns zero +// otherwise. +OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], + const uint8_t public_key[32]); + +// ED25519_keypair_from_seed calculates a public and private key from an +// Ed25519 “seed”. Seed values are not exposed by this API (although they +// happen to be the first 32 bytes of a private key) so this function is for +// interoperating with systems that may store just a seed instead of a full +// private key. +OPENSSL_EXPORT void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]); + + +// SPAKE2. +// +// SPAKE2 is a password-authenticated key-exchange. It allows two parties, +// who share a low-entropy secret (i.e. password), to agree on a shared key. +// An attacker can only make one guess of the password per execution of the +// protocol. +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. + +// spake2_role_t enumerates the different “roles” in SPAKE2. The protocol +// requires that the symmetry of the two parties be broken so one participant +// must be “Alice” and the other be “Bob”. +enum spake2_role_t { + spake2_role_alice, + spake2_role_bob, +}; + +// SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a +// single execution of the protocol). SPAKE2 requires the symmetry of the two +// parties to be broken which is indicated via |my_role| – each party must pass +// a different value for this argument. +// +// The |my_name| and |their_name| arguments allow optional, opaque names to be +// bound into the protocol. For example MAC addresses, hostnames, usernames +// etc. These values are not exposed and can avoid context-confusion attacks +// when a password is shared between several devices. +OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new( + enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len); + +// SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. +OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx); + +// SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. +#define SPAKE2_MAX_MSG_SIZE 32 + +// SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes +// it to |out| and sets |*out_len| to the number of bytes written. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes. +// +// This function can only be called once for a given |SPAKE2_CTX|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *password, + size_t password_len); + +// SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will +// produce. +#define SPAKE2_MAX_KEY_SIZE 64 + +// SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in +// |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets +// |*out_key_len| to the number of bytes written. +// +// The resulting keying material is suitable for: +// a) Using directly in a key-confirmation step: i.e. each side could +// transmit a hash of their role, a channel-binding value and the key +// material to prove to the other side that they know the shared key. +// b) Using as input keying material to HKDF to generate a variety of subkeys +// for encryption etc. +// +// If |max_out_key_key| is smaller than the amount of key material generated +// then the key is silently truncated. If you want to ensure that no truncation +// occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|. +// +// You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling +// this function. On successful return, |ctx| is complete and calling +// |SPAKE2_CTX_free| is the only acceptable operation on it. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, + size_t *out_key_len, + size_t max_out_key_len, + const uint8_t *their_msg, + size_t their_msg_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CURVE25519_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_des.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_des.h new file mode 100644 index 00000000..d50ec4e2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_des.h @@ -0,0 +1,183 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DES_H +#define OPENSSL_HEADER_DES_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DES. +// +// This module is deprecated and retained for legacy reasons only. It is slow +// and may leak key material with timing or cache side channels. Moreover, +// single-keyed DES is broken and can be brute-forced in under a day. +// +// Use a modern cipher, such as AES-GCM or ChaCha20-Poly1305, instead. + + +typedef struct DES_cblock_st { + uint8_t bytes[8]; +} DES_cblock; + +typedef struct DES_ks { + uint32_t subkeys[16][2]; +} DES_key_schedule; + + +#define DES_KEY_SZ (sizeof(DES_cblock)) +#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +// DES_set_key performs a key schedule and initialises |schedule| with |key|. +OPENSSL_EXPORT void DES_set_key(const DES_cblock *key, + DES_key_schedule *schedule); + +// DES_set_odd_parity sets the parity bits (the least-significant bits in each +// byte) of |key| given the other bits in each byte. +OPENSSL_EXPORT void DES_set_odd_parity(DES_cblock *key); + +// DES_ecb_encrypt encrypts (or decrypts, if |is_encrypt| is |DES_DECRYPT|) a +// single DES block (8 bytes) from in to out, using the key configured in +// |schedule|. +OPENSSL_EXPORT void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out, + const DES_key_schedule *schedule, + int is_encrypt); + +// DES_ncbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with DES in CBC mode. +OPENSSL_EXPORT void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *schedule, + DES_cblock *ivec, int enc); + +// DES_ecb3_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) a single +// block (8 bytes) of data from |input| to |output| using 3DES. +OPENSSL_EXPORT void DES_ecb3_encrypt(const DES_cblock *input, + DES_cblock *output, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + int enc); + +// DES_ede3_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. 3DES uses three keys, thus +// the function takes three different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + +// DES_ede2_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. With this keying option, the +// first and third 3DES keys are identical. Thus, this function takes only two +// different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, int enc); + + +// Deprecated functions. + +// DES_set_key_unchecked calls |DES_set_key|. +OPENSSL_EXPORT void DES_set_key_unchecked(const DES_cblock *key, + DES_key_schedule *schedule); + +OPENSSL_EXPORT void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); + +OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, + int numbits, long length, + DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + + +// Private functions. +// +// These functions are only exported for use in |decrepit|. + +OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + +OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dh.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dh.h new file mode 100644 index 00000000..d08cf588 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dh.h @@ -0,0 +1,353 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DH_H +#define OPENSSL_HEADER_DH_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_thread.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DH contains functions for performing Diffie-Hellman key agreement in +// multiplicative groups. +// +// This module is deprecated and retained for legacy reasons only. It is not +// considered a priority for performance or hardening work. Do not use it in +// new code. Use X25519 or ECDH with P-256 instead. + + +// Allocation and destruction. + +// DH_new returns a new, empty DH object or NULL on error. +OPENSSL_EXPORT DH *DH_new(void); + +// DH_free decrements the reference count of |dh| and frees it if the reference +// count drops to zero. +OPENSSL_EXPORT void DH_free(DH *dh); + +// DH_up_ref increments the reference count of |dh| and returns one. +OPENSSL_EXPORT int DH_up_ref(DH *dh); + + +// Properties. + +// DH_get0_pub_key returns |dh|'s public key. +OPENSSL_EXPORT const BIGNUM *DH_get0_pub_key(const DH *dh); + +// DH_get0_priv_key returns |dh|'s private key, or NULL if |dh| is a public key. +OPENSSL_EXPORT const BIGNUM *DH_get0_priv_key(const DH *dh); + +// DH_get0_p returns |dh|'s group modulus. +OPENSSL_EXPORT const BIGNUM *DH_get0_p(const DH *dh); + +// DH_get0_q returns the size of |dh|'s subgroup, or NULL if it is unset. +OPENSSL_EXPORT const BIGNUM *DH_get0_q(const DH *dh); + +// DH_get0_g returns |dh|'s group generator. +OPENSSL_EXPORT const BIGNUM *DH_get0_g(const DH *dh); + +// DH_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dh|'s +// public and private key, respectively. If |dh| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DH_set0_key sets |dh|'s public and private key to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); + +// DH_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dh|'s p, +// q, and g parameters, respectively. +OPENSSL_EXPORT void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DH_set0_pqg sets |dh|'s p, q, and g parameters to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. |q| may be NULL, but +// |p| and |g| must either be specified or already configured on |dh|. +OPENSSL_EXPORT int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); + +// DH_set_length sets the number of bits to use for the secret exponent when +// calling |DH_generate_key| on |dh| and returns one. If unset, +// |DH_generate_key| will use the bit length of p. +OPENSSL_EXPORT int DH_set_length(DH *dh, unsigned priv_length); + + +// Standard parameters. + +// BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); + +// DH_get_rfc7919_2048 returns the group `ffdhe2048` from +// https://tools.ietf.org/html/rfc7919#appendix-A.1. It returns NULL if out +// of memory. +OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void); + + +// Parameter generation. + +#define DH_GENERATOR_2 2 +#define DH_GENERATOR_5 5 + +// DH_generate_parameters_ex generates a suitable Diffie-Hellman group with a +// prime that is |prime_bits| long and stores it in |dh|. The generator of the +// group will be |generator|, which should be |DH_GENERATOR_2| unless there's a +// good reason to use a different value. The |cb| argument contains a callback +// function that will be called during the generation. See the documentation in +// |bn.h| about this. In addition to the callback invocations from |BN|, |cb| +// will also be called with |event| equal to three when the generation is +// complete. +OPENSSL_EXPORT int DH_generate_parameters_ex(DH *dh, int prime_bits, + int generator, BN_GENCB *cb); + + +// Diffie-Hellman operations. + +// DH_generate_key generates a new, random, private key and stores it in +// |dh|. It returns one on success and zero on error. +OPENSSL_EXPORT int DH_generate_key(DH *dh); + +// DH_compute_key_padded calculates the shared key between |dh| and |peers_key| +// and writes it as a big-endian integer into |out|, padded up to |DH_size| +// bytes. It returns the number of bytes written, which is always |DH_size|, or +// a negative number on error. |out| must have |DH_size| bytes of space. +// +// WARNING: this differs from the usual BoringSSL return-value convention. +// +// Note this function differs from |DH_compute_key| in that it preserves leading +// zeros in the secret. This function is the preferred variant. It matches PKCS +// #3 and avoids some side channel attacks. However, the two functions are not +// drop-in replacements for each other. Using a different variant than the +// application expects will result in sporadic key mismatches. +// +// Callers that expect a fixed-width secret should use this function over +// |DH_compute_key|. Callers that use either function should migrate to a modern +// primitive such as X25519 or ECDH with P-256 instead. +OPENSSL_EXPORT int DH_compute_key_padded(uint8_t *out, const BIGNUM *peers_key, + DH *dh); + +// DH_compute_key_hashed calculates the shared key between |dh| and |peers_key| +// and hashes it with the given |digest|. If the hash output is less than +// |max_out_len| bytes then it writes the hash output to |out| and sets +// |*out_len| to the number of bytes written. Otherwise it signals an error. It +// returns one on success or zero on error. +// +// NOTE: this follows the usual BoringSSL return-value convention, but that's +// different from |DH_compute_key| and |DH_compute_key_padded|. +OPENSSL_EXPORT int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, + size_t max_out_len, + const BIGNUM *peers_key, + const EVP_MD *digest); + + +// Utility functions. + +// DH_size returns the number of bytes in the DH group's prime. +OPENSSL_EXPORT int DH_size(const DH *dh); + +// DH_num_bits returns the minimum number of bits needed to represent the +// absolute value of the DH group's prime. +OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); + +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_CHECK_NOT_SUITABLE_GENERATOR 0x08 +#define DH_CHECK_Q_NOT_PRIME 0x10 +#define DH_CHECK_INVALID_Q_VALUE 0x20 +#define DH_CHECK_INVALID_J_VALUE 0x40 + +// These are compatibility defines. +#define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR +#define DH_UNABLE_TO_CHECK_GENERATOR DH_CHECK_UNABLE_TO_CHECK_GENERATOR + +// DH_check checks the suitability of |dh| as a Diffie-Hellman group. and sets +// |DH_CHECK_*| flags in |*out_flags| if it finds any errors. It returns one if +// |*out_flags| was successfully set and zero on error. +// +// Note: these checks may be quite computationally expensive. +OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags); + +#define DH_CHECK_PUBKEY_TOO_SMALL 0x1 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x2 +#define DH_CHECK_PUBKEY_INVALID 0x4 + +// DH_check_pub_key checks the suitability of |pub_key| as a public key for the +// DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it +// finds any errors. It returns one if |*out_flags| was successfully set and +// zero on error. +OPENSSL_EXPORT int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, + int *out_flags); + +// DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into +// it. It returns the new |DH| or NULL on error. +OPENSSL_EXPORT DH *DHparams_dup(const DH *dh); + + +// ASN.1 functions. + +// DH_parse_parameters decodes a DER-encoded DHParameter structure (PKCS #3) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DH| or NULL on +// error. +OPENSSL_EXPORT DH *DH_parse_parameters(CBS *cbs); + +// DH_marshal_parameters marshals |dh| as a DER-encoded DHParameter structure +// (PKCS #3) and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int DH_marshal_parameters(CBB *cbb, const DH *dh); + + +// Deprecated functions. + +// DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is +// what you should use instead. It returns NULL on error, or a newly-allocated +// |DH| on success. This function is provided for compatibility only. +OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator, + void (*callback)(int, int, void *), + void *cb_arg); + +// d2i_DHparams parses a DER-encoded DHParameter structure (PKCS #3) from |len| +// bytes at |*inp|, as in |d2i_SAMPLE|. +// +// Use |DH_parse_parameters| instead. +OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len); + +// i2d_DHparams marshals |in| to a DER-encoded DHParameter structure (PKCS #3), +// as described in |i2d_SAMPLE|. +// +// Use |DH_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp); + +// DH_compute_key behaves like |DH_compute_key_padded| but, contrary to PKCS #3, +// returns a variable-length shared key with leading zeros. It returns the +// number of bytes written, or a negative number on error. |out| must have +// |DH_size| bytes of space. +// +// WARNING: this differs from the usual BoringSSL return-value convention. +// +// Note this function's running time and memory access pattern leaks information +// about the shared secret. Particularly if |dh| is reused, this may result in +// side channel attacks such as https://raccoon-attack.com/. +// +// |DH_compute_key_padded| is the preferred variant and avoids the above +// attacks. However, the two functions are not drop-in replacements for each +// other. Using a different variant than the application expects will result in +// sporadic key mismatches. +// +// Callers that expect a fixed-width secret should use |DH_compute_key_padded| +// instead. Callers that use either function should migrate to a modern +// primitive such as X25519 or ECDH with P-256 instead. +OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, + DH *dh); + + +struct dh_st { + BIGNUM *p; + BIGNUM *g; + BIGNUM *pub_key; // g^x mod p + BIGNUM *priv_key; // x + + // priv_length contains the length, in bits, of the private value. If zero, + // the private value will be the same length as |p|. + unsigned priv_length; + + CRYPTO_MUTEX method_mont_p_lock; + BN_MONT_CTX *method_mont_p; + + // Place holders if we want to do X9.42 DH + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + + int flags; + CRYPTO_refcount_t references; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(DH, DH_free) +BORINGSSL_MAKE_UP_REF(DH, DH_up_ref) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define DH_R_BAD_GENERATOR 100 +#define DH_R_INVALID_PUBKEY 101 +#define DH_R_MODULUS_TOO_LARGE 102 +#define DH_R_NO_PRIVATE_VALUE 103 +#define DH_R_DECODE_ERROR 104 +#define DH_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_DH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_digest.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_digest.h new file mode 100644 index 00000000..8d6422dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_digest.h @@ -0,0 +1,355 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DIGEST_H +#define OPENSSL_HEADER_DIGEST_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Digest functions. +// +// An EVP_MD abstracts the details of a specific hash function allowing code to +// deal with the concept of a "hash function" without needing to know exactly +// which hash function it is. + + +// Hash algorithms. +// +// The following functions return |EVP_MD| objects that implement the named hash +// function. + +OPENSSL_EXPORT const EVP_MD *EVP_md4(void); +OPENSSL_EXPORT const EVP_MD *EVP_md5(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha1(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha224(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha256(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha384(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha512(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha512_256(void); +OPENSSL_EXPORT const EVP_MD *EVP_blake2b256(void); + +// EVP_md5_sha1 is a TLS-specific |EVP_MD| which computes the concatenation of +// MD5 and SHA-1, as used in TLS 1.1 and below. +OPENSSL_EXPORT const EVP_MD *EVP_md5_sha1(void); + +// EVP_get_digestbynid returns an |EVP_MD| for the given NID, or NULL if no +// such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbynid(int nid); + +// EVP_get_digestbyobj returns an |EVP_MD| for the given |ASN1_OBJECT|, or NULL +// if no such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj); + + +// Digest contexts. +// +// An EVP_MD_CTX represents the state of a specific digest operation in +// progress. + +// EVP_MD_CTX_init initialises an, already allocated, |EVP_MD_CTX|. This is the +// same as setting the structure to zero. +OPENSSL_EXPORT void EVP_MD_CTX_init(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_new allocates and initialises a fresh |EVP_MD_CTX| and returns +// it, or NULL on allocation failure. The caller must use |EVP_MD_CTX_free| to +// release the resulting object. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_new(void); + +// EVP_MD_CTX_cleanup frees any resources owned by |ctx| and resets it to a +// freshly initialised state. It does not free |ctx| itself. It returns one. +OPENSSL_EXPORT int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_cleanse zeros the digest state in |ctx| and then performs the +// actions of |EVP_MD_CTX_cleanup|. Note that some |EVP_MD_CTX| objects contain +// more than just a digest (e.g. those resulting from |EVP_DigestSignInit|) but +// this function does not zero out more than just the digest state even in that +// case. +OPENSSL_EXPORT void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_copy_ex sets |out|, which must already be initialised, to be a +// copy of |in|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_MD_CTX_move sets |out|, which must already be initialised, to the hash +// state in |in|. |in| is mutated and left in an empty state. +OPENSSL_EXPORT void EVP_MD_CTX_move(EVP_MD_CTX *out, EVP_MD_CTX *in); + +// EVP_MD_CTX_reset calls |EVP_MD_CTX_cleanup| followed by |EVP_MD_CTX_init|. It +// returns one. +OPENSSL_EXPORT int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); + + +// Digest operations. + +// EVP_DigestInit_ex configures |ctx|, which must already have been +// initialised, for a fresh hashing operation using |type|. It returns one on +// success and zero on allocation failure. +OPENSSL_EXPORT int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *engine); + +// EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is +// initialised before use. +OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation +// in |ctx|. It returns one. +OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_MAX_MD_SIZE is the largest digest size supported, in bytes. +// Functions that output a digest generally require the buffer have +// at least this much space. +#define EVP_MAX_MD_SIZE 64 // SHA-512 is the longest so far. + +// EVP_MAX_MD_BLOCK_SIZE is the largest digest block size supported, in +// bytes. +#define EVP_MAX_MD_BLOCK_SIZE 128 // SHA-512 is the longest so far. + +// EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to +// |md_out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_size| is not NULL then |*out_size| is set to the +// number of bytes written. It returns one. After this call, the hash cannot be +// updated or finished again until |EVP_DigestInit_ex| is called to start +// another hashing operation. +OPENSSL_EXPORT int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that +// |EVP_MD_CTX_cleanup| is called on |ctx| before returning. +OPENSSL_EXPORT int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_Digest performs a complete hashing operation in one call. It hashes |len| +// bytes from |data| and writes the digest to |md_out|. |EVP_MD_CTX_size| bytes +// are written, which is at most |EVP_MAX_MD_SIZE|. If |out_size| is not NULL +// then |*out_size| is set to the number of bytes written. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int EVP_Digest(const void *data, size_t len, uint8_t *md_out, + unsigned int *md_out_size, const EVP_MD *type, + ENGINE *impl); + + +// Digest function accessors. +// +// These functions allow code to learn details about an abstract hash +// function. + +// EVP_MD_type returns a NID identifying |md|. (For example, |NID_sha256|.) +OPENSSL_EXPORT int EVP_MD_type(const EVP_MD *md); + +// EVP_MD_flags returns the flags for |md|, which is a set of |EVP_MD_FLAG_*| +// values, ORed together. +OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md); + +// EVP_MD_size returns the digest size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md); + +// EVP_MD_block_size returns the native block-size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md); + +// EVP_MD_FLAG_PKEY_DIGEST indicates that the digest function is used with a +// specific public key in order to verify signatures. (For example, +// EVP_dss1.) +#define EVP_MD_FLAG_PKEY_DIGEST 1 + +// EVP_MD_FLAG_DIGALGID_ABSENT indicates that the parameter type in an X.509 +// DigestAlgorithmIdentifier representing this digest function should be +// undefined rather than NULL. +#define EVP_MD_FLAG_DIGALGID_ABSENT 2 + +// EVP_MD_FLAG_XOF indicates that the digest is an extensible-output function +// (XOF). This flag is defined for compatibility and will never be set in any +// |EVP_MD| in BoringSSL. +#define EVP_MD_FLAG_XOF 4 + + +// Digest operation accessors. + +// EVP_MD_CTX_md returns the underlying digest function, or NULL if one has not +// been set. +OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It +// will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_block_size returns the block size of the digest function used by +// |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|. +// (For example, |NID_sha256|.) It will crash if a digest hasn't been set on +// |ctx|. +OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx); + + +// ASN.1 functions. +// +// These functions allow code to parse and serialize AlgorithmIdentifiers for +// hash functions. + +// EVP_parse_digest_algorithm parses an AlgorithmIdentifier structure containing +// a hash function OID (for example, 2.16.840.1.101.3.4.2.1 is SHA-256) and +// advances |cbs|. The parameters field may either be omitted or a NULL. It +// returns the digest function or NULL on error. +OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); + +// EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier +// structure and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md); + + +// Deprecated functions. + +// EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of +// |in|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_add_digest does nothing and returns one. It exists only for +// compatibility with OpenSSL. +OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest); + +// EVP_get_digestbyname returns an |EVP_MD| given a human readable name in +// |name|, or NULL if the name is unknown. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *); + +// EVP_dss1 returns the value of EVP_sha1(). This was provided by OpenSSL to +// specifiy the original DSA signatures, which were fixed to use SHA-1. Note, +// however, that attempting to sign or verify DSA signatures with the EVP +// interface will always fail. +OPENSSL_EXPORT const EVP_MD *EVP_dss1(void); + +// EVP_MD_CTX_create calls |EVP_MD_CTX_new|. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_create(void); + +// EVP_MD_CTX_destroy calls |EVP_MD_CTX_free|. +OPENSSL_EXPORT void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); + +// EVP_DigestFinalXOF returns zero and adds an error to the error queue. +// BoringSSL does not support any XOF digests. +OPENSSL_EXPORT int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, + size_t len); + +// EVP_MD_meth_get_flags calls |EVP_MD_flags|. +OPENSSL_EXPORT uint32_t EVP_MD_meth_get_flags(const EVP_MD *md); + +// EVP_MD_CTX_set_flags does nothing. +OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); + +// EVP_MD_CTX_FLAG_NON_FIPS_ALLOW is meaningless. In OpenSSL it permits non-FIPS +// algorithms in FIPS mode. But BoringSSL FIPS mode doesn't prohibit algorithms +// (it's up the the caller to use the FIPS module in a fashion compliant with +// their needs). Thus this exists only to allow code to compile. +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0 + +// EVP_MD_nid calls |EVP_MD_type|. +OPENSSL_EXPORT int EVP_MD_nid(const EVP_MD *md); + + +struct evp_md_pctx_ops; + +struct env_md_ctx_st { + // digest is the underlying digest function, or NULL if not set. + const EVP_MD *digest; + // md_data points to a block of memory that contains the hash-specific + // context. + void *md_data; + + // pctx is an opaque (at this layer) pointer to additional context that + // EVP_PKEY functions may store in this object. + EVP_PKEY_CTX *pctx; + + // pctx_ops, if not NULL, points to a vtable that contains functions to + // manipulate |pctx|. + const struct evp_md_pctx_ops *pctx_ops; +} /* EVP_MD_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(EVP_MD_CTX, EVP_MD_CTX_free) + +using ScopedEVP_MD_CTX = + internal::StackAllocatedMovable; + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#define DIGEST_R_INPUT_NOT_INITIALIZED 100 +#define DIGEST_R_DECODE_ERROR 101 +#define DIGEST_R_UNKNOWN_HASH 102 + +#endif // OPENSSL_HEADER_DIGEST_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h new file mode 100644 index 00000000..2fd7cc7d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h @@ -0,0 +1,443 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + * + * The DSS routines are based on patches supplied by + * Steven Schoch . */ + +#ifndef OPENSSL_HEADER_DSA_H +#define OPENSSL_HEADER_DSA_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_engine.h" +#include "CNIOBoringSSL_ex_data.h" +#include "CNIOBoringSSL_thread.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DSA contains functions for signing and verifying with the Digital Signature +// Algorithm. +// +// This module is deprecated and retained for legacy reasons only. It is not +// considered a priority for performance or hardening work. Do not use it in +// new code. Use Ed25519, ECDSA with P-256, or RSA instead. + + +// Allocation and destruction. + +// DSA_new returns a new, empty DSA object or NULL on error. +OPENSSL_EXPORT DSA *DSA_new(void); + +// DSA_free decrements the reference count of |dsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void DSA_free(DSA *dsa); + +// DSA_up_ref increments the reference count of |dsa| and returns one. +OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); + + +// Properties. + +// DSA_get0_pub_key returns |dsa|'s public key. +OPENSSL_EXPORT const BIGNUM *DSA_get0_pub_key(const DSA *dsa); + +// DSA_get0_priv_key returns |dsa|'s private key, or NULL if |dsa| is a public +// key. +OPENSSL_EXPORT const BIGNUM *DSA_get0_priv_key(const DSA *dsa); + +// DSA_get0_p returns |dsa|'s group modulus. +OPENSSL_EXPORT const BIGNUM *DSA_get0_p(const DSA *dsa); + +// DSA_get0_q returns the size of |dsa|'s subgroup. +OPENSSL_EXPORT const BIGNUM *DSA_get0_q(const DSA *dsa); + +// DSA_get0_g returns |dsa|'s group generator. +OPENSSL_EXPORT const BIGNUM *DSA_get0_g(const DSA *dsa); + +// DSA_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dsa|'s +// public and private key, respectively. If |dsa| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DSA_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dsa|'s +// p, q, and g parameters, respectively. +OPENSSL_EXPORT void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DSA_set0_key sets |dsa|'s public and private key to |pub_key| and |priv_key|, +// respectively, if non-NULL. On success, it takes ownership of each argument +// and returns one. Otherwise, it returns zero. +// +// |priv_key| may be NULL, but |pub_key| must either be non-NULL or already +// configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key); + +// DSA_set0_pqg sets |dsa|'s parameters to |p|, |q|, and |g|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); + + +// Parameter generation. + +// DSA_generate_parameters_ex generates a set of DSA parameters by following +// the procedure given in FIPS 186-4, appendix A. +// (http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) +// +// The larger prime will have a length of |bits| (e.g. 2048). The |seed| value +// allows others to generate and verify the same parameters and should be +// random input which is kept for reference. If |out_counter| or |out_h| are +// not NULL then the counter and h value used in the generation are written to +// them. +// +// The |cb| argument is passed to |BN_generate_prime_ex| and is thus called +// during the generation process in order to indicate progress. See the +// comments for that function for details. In addition to the calls made by +// |BN_generate_prime_ex|, |DSA_generate_parameters_ex| will call it with +// |event| equal to 2 and 3 at different stages of the process. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, + const uint8_t *seed, + size_t seed_len, int *out_counter, + unsigned long *out_h, + BN_GENCB *cb); + +// DSAparams_dup returns a freshly allocated |DSA| that contains a copy of the +// parameters from |dsa|. It returns NULL on error. +OPENSSL_EXPORT DSA *DSAparams_dup(const DSA *dsa); + + +// Key generation. + +// DSA_generate_key generates a public/private key pair in |dsa|, which must +// already have parameters setup. It returns one on success and zero on +// error. +OPENSSL_EXPORT int DSA_generate_key(DSA *dsa); + + +// Signatures. + +// DSA_SIG_st (aka |DSA_SIG|) contains a DSA signature as a pair of integers. +struct DSA_SIG_st { + BIGNUM *r, *s; +}; + +// DSA_SIG_new returns a freshly allocated, DIG_SIG structure or NULL on error. +// Both |r| and |s| in the signature will be NULL. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_new(void); + +// DSA_SIG_free frees the contents of |sig| and then frees |sig| itself. +OPENSSL_EXPORT void DSA_SIG_free(DSA_SIG *sig); + +// DSA_SIG_get0 sets |*out_r| and |*out_s|, if non-NULL, to the two components +// of |sig|. +OPENSSL_EXPORT void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s); + +// DSA_SIG_set0 sets |sig|'s components to |r| and |s|, neither of which may be +// NULL. On success, it takes ownership of each argument and returns one. +// Otherwise, it returns zero. +OPENSSL_EXPORT int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +// DSA_do_sign returns a signature of the hash in |digest| by the key in |dsa| +// and returns an allocated, DSA_SIG structure, or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, + const DSA *dsa); + +// DSA_do_verify verifies that |sig| is a valid signature, by the public key in +// |dsa|, of the hash in |digest|. It returns one if so, zero if invalid and -1 +// on error. +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_do_verify(const uint8_t *digest, size_t digest_len, + DSA_SIG *sig, const DSA *dsa); + +// DSA_do_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid signature, by the public key in |dsa| of the hash in |digest| +// and, if so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, + const DSA *dsa); + + +// ASN.1 signatures. +// +// These functions also perform DSA signature operations, but deal with ASN.1 +// encoded signatures as opposed to raw |BIGNUM|s. If you don't know what +// encoding a DSA signature is in, it's probably ASN.1. + +// DSA_sign signs |digest| with the key in |dsa| and writes the resulting +// signature, in ASN.1 form, to |out_sig| and the length of the signature to +// |*out_siglen|. There must be, at least, |DSA_size(dsa)| bytes of space in +// |out_sig|. It returns one on success and zero otherwise. +// +// (The |type| argument is ignored.) +OPENSSL_EXPORT int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, + const DSA *dsa); + +// DSA_verify verifies that |sig| is a valid, ASN.1 signature, by the public +// key in |dsa|, of the hash in |digest|. It returns one if so, zero if invalid +// and -1 on error. +// +// (The |type| argument is ignored.) +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid, ASN.1 signature, by the public key in |dsa|, of the hash in +// |digest|. If so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_size returns the size, in bytes, of an ASN.1 encoded, DSA signature +// generated by |dsa|. Parameters must already have been setup in |dsa|. +OPENSSL_EXPORT int DSA_size(const DSA *dsa); + + +// ASN.1 encoding. + +// DSA_SIG_parse parses a DER-encoded DSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA_SIG| or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_parse(CBS *cbs); + +// DSA_SIG_marshal marshals |sig| as a DER-encoded DSA-Sig-Value and appends the +// result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig); + +// DSA_parse_public_key parses a DER-encoded DSA public key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_public_key(CBS *cbs); + +// DSA_marshal_public_key marshals |dsa| as a DER-encoded DSA public key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_public_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_private_key parses a DER-encoded DSA private key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_private_key(CBS *cbs); + +// DSA_marshal_private_key marshals |dsa| as a DER-encoded DSA private key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_private_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_parameters parses a DER-encoded Dss-Parms structure (RFC 3279) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DSA| or NULL on +// error. +OPENSSL_EXPORT DSA *DSA_parse_parameters(CBS *cbs); + +// DSA_marshal_parameters marshals |dsa| as a DER-encoded Dss-Parms structure +// (RFC 3279) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int DSA_marshal_parameters(CBB *cbb, const DSA *dsa); + + +// Conversion. + +// DSA_dup_DH returns a |DH| constructed from the parameters of |dsa|. This is +// sometimes needed when Diffie-Hellman parameters are stored in the form of +// DSA parameters. It returns an allocated |DH| on success or NULL on error. +OPENSSL_EXPORT DH *DSA_dup_DH(const DSA *dsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int DSA_set_ex_data(DSA *dsa, int idx, void *arg); +OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *dsa, int idx); + + +// Deprecated functions. + +// d2i_DSA_SIG parses a DER-encoded DSA-Sig-Value structure from |len| bytes at +// |*inp|, as described in |d2i_SAMPLE|. +// +// Use |DSA_SIG_parse| instead. +OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, + long len); + +// i2d_DSA_SIG marshals |in| to a DER-encoded DSA-Sig-Value structure, as +// described in |i2d_SAMPLE|. +// +// Use |DSA_SIG_marshal| instead. +OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp); + +// d2i_DSAPublicKey parses a DER-encoded DSA public key from |len| bytes at +// |*inp|, as described in |d2i_SAMPLE|. +// +// Use |DSA_parse_public_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPublicKey marshals |in| as a DER-encoded DSA public key, as described +// in |i2d_SAMPLE|. +// +// Use |DSA_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, uint8_t **outp); + +// d2i_DSAPrivateKey parses a DER-encoded DSA private key from |len| bytes at +// |*inp|, as described in |d2i_SAMPLE|. +// +// Use |DSA_parse_private_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPrivateKey marshals |in| as a DER-encoded DSA private key, as +// described in |i2d_SAMPLE|. +// +// Use |DSA_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp); + +// d2i_DSAparams parses a DER-encoded Dss-Parms structure (RFC 3279) from |len| +// bytes at |*inp|, as described in |d2i_SAMPLE|. +// +// Use |DSA_parse_parameters| instead. +OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAparams marshals |in|'s parameters as a DER-encoded Dss-Parms structure +// (RFC 3279), as described in |i2d_SAMPLE|. +// +// Use |DSA_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, uint8_t **outp); + +// DSA_generate_parameters is a deprecated version of +// |DSA_generate_parameters_ex| that creates and returns a |DSA*|. Don't use +// it. +OPENSSL_EXPORT DSA *DSA_generate_parameters(int bits, unsigned char *seed, + int seed_len, int *counter_ret, + unsigned long *h_ret, + void (*callback)(int, int, void *), + void *cb_arg); + + +struct dsa_st { + long version; + BIGNUM *p; + BIGNUM *q; // == 20 + BIGNUM *g; + + BIGNUM *pub_key; // y public key + BIGNUM *priv_key; // x private key + + int flags; + // Normally used to cache montgomery values + CRYPTO_MUTEX method_mont_lock; + BN_MONT_CTX *method_mont_p; + BN_MONT_CTX *method_mont_q; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(DSA, DSA_free) +BORINGSSL_MAKE_UP_REF(DSA, DSA_up_ref) +BORINGSSL_MAKE_DELETER(DSA_SIG, DSA_SIG_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define DSA_R_BAD_Q_VALUE 100 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 102 +#define DSA_R_NEED_NEW_SETUP_VALUES 103 +#define DSA_R_BAD_VERSION 104 +#define DSA_R_DECODE_ERROR 105 +#define DSA_R_ENCODE_ERROR 106 +#define DSA_R_INVALID_PARAMETERS 107 + +#endif // OPENSSL_HEADER_DSA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dtls1.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dtls1.h new file mode 100644 index 00000000..38ca801c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_dtls1.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_e_os2.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_e_os2.h new file mode 100644 index 00000000..316fcb77 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_e_os2.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_base.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h new file mode 100644 index 00000000..2add64dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h @@ -0,0 +1,450 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#ifndef OPENSSL_HEADER_EC_H +#define OPENSSL_HEADER_EC_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Low-level operations on elliptic curves. + + +// point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for +// the encoding of a elliptic curve point (x,y) +typedef enum { + // POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x, + // where the octet z specifies which solution of the quadratic equation y + // is. + POINT_CONVERSION_COMPRESSED = 2, + + // POINT_CONVERSION_UNCOMPRESSED indicates that the point is encoded as + // z||x||y, where z is the octet 0x04. + POINT_CONVERSION_UNCOMPRESSED = 4, + + // POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y, + // where z specifies which solution of the quadratic equation y is. This is + // not supported by the code and has never been observed in use. + // + // TODO(agl): remove once node.js no longer references this. + POINT_CONVERSION_HYBRID = 6, +} point_conversion_form_t; + + +// Elliptic curve groups. + +// EC_GROUP_new_by_curve_name returns a fresh EC_GROUP object for the elliptic +// curve specified by |nid|, or NULL on unsupported NID or allocation failure. +// +// The supported NIDs are: +// NID_secp224r1 (P-224), +// NID_X9_62_prime256v1 (P-256), +// NID_secp384r1 (P-384), +// NID_secp521r1 (P-521) +// +// If in doubt, use |NID_X9_62_prime256v1|, or see the curve25519.h header for +// more modern primitives. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +// EC_GROUP_free releases a reference to |group|. +OPENSSL_EXPORT void EC_GROUP_free(EC_GROUP *group); + +// EC_GROUP_dup takes a reference to |a| and returns it. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_dup(const EC_GROUP *a); + +// EC_GROUP_cmp returns zero if |a| and |b| are the same group and non-zero +// otherwise. +OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, + BN_CTX *ignored); + +// EC_GROUP_get0_generator returns a pointer to the internal |EC_POINT| object +// in |group| that specifies the generator for the group. +OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +// EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in +// |group| that specifies the order of the group. +OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +// EC_GROUP_order_bits returns the number of bits of the order of |group|. +OPENSSL_EXPORT int EC_GROUP_order_bits(const EC_GROUP *group); + +// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using +// |ctx|, if it's not NULL. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, + BIGNUM *cofactor, BN_CTX *ctx); + +// EC_GROUP_get_curve_GFp gets various parameters about a group. It sets +// |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to +// the parameters of the curve when expressed as y² = x³ + ax + b. Any of the +// output parameters can be NULL. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, + BIGNUM *out_a, BIGNUM *out_b, + BN_CTX *ctx); + +// EC_GROUP_get_curve_name returns a NID that identifies |group|. +OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group); + +// EC_GROUP_get_degree returns the number of bits needed to represent an +// element of the field underlying |group|. +OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group); + +// EC_curve_nid2nist returns the NIST name of the elliptic curve specified by +// |nid|, or NULL if |nid| is not a NIST curve. For example, it returns "P-256" +// for |NID_X9_62_prime256v1|. +OPENSSL_EXPORT const char *EC_curve_nid2nist(int nid); + +// EC_curve_nist2nid returns the NID of the elliptic curve specified by the NIST +// name |name|, or |NID_undef| if |name| is not a recognized name. For example, +// it returns |NID_X9_62_prime256v1| for "P-256". +OPENSSL_EXPORT int EC_curve_nist2nid(const char *name); + + +// Points on elliptic curves. + +// EC_POINT_new returns a fresh |EC_POINT| object in the given group, or NULL +// on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_new(const EC_GROUP *group); + +// EC_POINT_free frees |point| and the data that it points to. +OPENSSL_EXPORT void EC_POINT_free(EC_POINT *point); + +// EC_POINT_copy sets |*dest| equal to |*src|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src); + +// EC_POINT_dup returns a fresh |EC_POINT| that contains the same values as +// |src|, or NULL on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_dup(const EC_POINT *src, + const EC_GROUP *group); + +// EC_POINT_set_to_infinity sets |point| to be the "point at infinity" for the +// given group. +OPENSSL_EXPORT int EC_POINT_set_to_infinity(const EC_GROUP *group, + EC_POINT *point); + +// EC_POINT_is_at_infinity returns one iff |point| is the point at infinity and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point); + +// EC_POINT_is_on_curve returns one if |point| is an element of |group| and +// and zero otherwise or when an error occurs. This is different from OpenSSL, +// which returns -1 on error. If |ctx| is non-NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group, + const EC_POINT *point, BN_CTX *ctx); + +// EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if +// not equal and -1 on error. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + + +// Point conversion. + +// EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of +// |point| using |ctx|, if it's not NULL. It returns one on success and zero +// otherwise. +// +// Either |x| or |y| may be NULL to skip computing that coordinate. This is +// slightly faster in the common case where only the x-coordinate is needed. +OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_get_affine_coordinates is an alias of +// |EC_POINT_get_affine_coordinates_GFp|. +OPENSSL_EXPORT int EC_POINT_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be +// (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one +// on success or zero on error. It's considered an error if the point is not on +// the curve. +// +// Note that the corresponding function in OpenSSL versions prior to 1.0.2s does +// not check if the point is on the curve. This is a security-critical check, so +// code additionally supporting OpenSSL should repeat the check with +// |EC_POINT_is_on_curve| or check for older OpenSSL versions with +// |OPENSSL_VERSION_NUMBER|. +OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_set_affine_coordinates is an alias of +// |EC_POINT_set_affine_coordinates_GFp|. +OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| +// into, at most, |len| bytes at |buf|. It returns the number of bytes written +// or zero on error if |buf| is non-NULL, else the number of bytes needed. The +// |ctx| argument may be used if not NULL. +OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t *buf, size_t len, BN_CTX *ctx); + +// EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the +// serialised point to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BN_CTX *ctx); + +// EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format +// serialisation in |buf|. It returns one on success and zero on error. The +// |ctx| argument may be used if not NULL. It's considered an error if |buf| +// does not represent a point on the curve. +OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx); + +// EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with +// the given |x| coordinate and the y coordinate specified by |y_bit| (see +// X9.62). It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( + const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, + BN_CTX *ctx); + + +// Group operations. + +// EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +// EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, BN_CTX *ctx); + +// EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, + BN_CTX *ctx); + +// EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero +// otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *n, const EC_POINT *q, + const BIGNUM *m, BN_CTX *ctx); + + +// Deprecated functions. + +// EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based +// on the equation y² = x³ + a·x + b. It returns the new group or NULL on +// error. +// +// This new group has no generator. It is an error to use a generator-less group +// with any functions except for |EC_GROUP_free|, |EC_POINT_new|, +// |EC_POINT_set_affine_coordinates_GFp|, and |EC_GROUP_set_generator|. +// +// |EC_GROUP|s returned by this function will always compare as unequal via +// |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always +// return |NID_undef|. +// +// This function is provided for compatibility with some legacy applications +// only. Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| +// instead. This ensures the result meets preconditions necessary for +// elliptic curve algorithms to function correctly and securely. +// +// Given invalid parameters, this function may fail or it may return an +// |EC_GROUP| which breaks these preconditions. Subsequent operations may then +// return arbitrary, incorrect values. Callers should not pass +// attacker-controlled values to this function. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, + const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// EC_GROUP_set_generator sets the generator for |group| to |generator|, which +// must have the given order and cofactor. It may only be used with |EC_GROUP| +// objects returned by |EC_GROUP_new_curve_GFp| and may only be used once on +// each group. |generator| must have been created using |group|. +OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group, + const EC_POINT *generator, + const BIGNUM *order, + const BIGNUM *cofactor); + +// EC_GROUP_get_order sets |*order| to the order of |group|, if it's not +// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use +// |EC_GROUP_get0_order| instead. +OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, + BN_CTX *ctx); + +#define OPENSSL_EC_EXPLICIT_CURVE 0 +#define OPENSSL_EC_NAMED_CURVE 1 + +// EC_GROUP_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); + +// EC_GROUP_get_asn1_flag returns |OPENSSL_EC_NAMED_CURVE|. +OPENSSL_EXPORT int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +typedef struct ec_method_st EC_METHOD; + +// EC_GROUP_method_of returns a dummy non-NULL pointer. +OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +// EC_METHOD_get_field_type returns NID_X9_62_prime_field. +OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth); + +// EC_GROUP_set_point_conversion_form aborts the process if |form| is not +// |POINT_CONVERSION_UNCOMPRESSED| and otherwise does nothing. +OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form( + EC_GROUP *group, point_conversion_form_t form); + +// EC_builtin_curve describes a supported elliptic curve. +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +// EC_get_builtin_curves writes at most |max_num_curves| elements to +// |out_curves| and returns the total number that it would have written, had +// |max_num_curves| been large enough. +// +// The |EC_builtin_curve| items describe the supported elliptic curves. +OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves); + +// EC_POINT_clear_free calls |EC_POINT_free|. +OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point); + + +#if defined(__cplusplus) +} // extern C +#endif + +// Old code expects to get EC_KEY from ec.h. +#include "CNIOBoringSSL_ec_key.h" + +#if defined(__cplusplus) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(EC_POINT, EC_POINT_free) +BORINGSSL_MAKE_DELETER(EC_GROUP, EC_GROUP_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_COORDINATES_OUT_OF_RANGE 101 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 103 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 104 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 105 +#define EC_R_INCOMPATIBLE_OBJECTS 106 +#define EC_R_INVALID_COMPRESSED_POINT 107 +#define EC_R_INVALID_COMPRESSION_BIT 108 +#define EC_R_INVALID_ENCODING 109 +#define EC_R_INVALID_FIELD 110 +#define EC_R_INVALID_FORM 111 +#define EC_R_INVALID_GROUP_ORDER 112 +#define EC_R_INVALID_PRIVATE_KEY 113 +#define EC_R_MISSING_PARAMETERS 114 +#define EC_R_MISSING_PRIVATE_KEY 115 +#define EC_R_NON_NAMED_CURVE 116 +#define EC_R_NOT_INITIALIZED 117 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 118 +#define EC_R_POINT_AT_INFINITY 119 +#define EC_R_POINT_IS_NOT_ON_CURVE 120 +#define EC_R_SLOT_FULL 121 +#define EC_R_UNDEFINED_GENERATOR 122 +#define EC_R_UNKNOWN_GROUP 123 +#define EC_R_UNKNOWN_ORDER 124 +#define EC_R_WRONG_ORDER 125 +#define EC_R_BIGNUM_OUT_OF_RANGE 126 +#define EC_R_WRONG_CURVE_PARAMETERS 127 +#define EC_R_DECODE_ERROR 128 +#define EC_R_ENCODE_ERROR 129 +#define EC_R_GROUP_MISMATCH 130 +#define EC_R_INVALID_COFACTOR 131 +#define EC_R_PUBLIC_KEY_VALIDATION_FAILED 132 +#define EC_R_INVALID_SCALAR 133 + +#endif // OPENSSL_HEADER_EC_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h new file mode 100644 index 00000000..085fa733 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h @@ -0,0 +1,360 @@ +/* Originally written by Bodo Moeller for the OpenSSL project. + * ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems + * Laboratories. */ + +#ifndef OPENSSL_HEADER_EC_KEY_H +#define OPENSSL_HEADER_EC_KEY_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_ec.h" +#include "CNIOBoringSSL_engine.h" +#include "CNIOBoringSSL_ex_data.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ec_key.h contains functions that handle elliptic-curve points that are +// public/private keys. + + +// EC key objects. +// +// An |EC_KEY| object represents a public or private EC key. A given object may +// be used concurrently on multiple threads by non-mutating functions, provided +// no other thread is concurrently calling a mutating function. Unless otherwise +// documented, functions which take a |const| pointer are non-mutating and +// functions which take a non-|const| pointer are mutating. + +// EC_KEY_new returns a fresh |EC_KEY| object or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new(void); + +// EC_KEY_new_method acts the same as |EC_KEY_new|, but takes an explicit +// |ENGINE|. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_method(const ENGINE *engine); + +// EC_KEY_new_by_curve_name returns a fresh EC_KEY for group specified by |nid| +// or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_by_curve_name(int nid); + +// EC_KEY_free frees all the data owned by |key| and |key| itself. +OPENSSL_EXPORT void EC_KEY_free(EC_KEY *key); + +// EC_KEY_dup returns a fresh copy of |src| or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_dup(const EC_KEY *src); + +// EC_KEY_up_ref increases the reference count of |key| and returns one. It does +// not mutate |key| for thread-safety purposes and may be used concurrently. +OPENSSL_EXPORT int EC_KEY_up_ref(EC_KEY *key); + +// EC_KEY_is_opaque returns one if |key| is opaque and doesn't expose its key +// material. Otherwise it return zero. +OPENSSL_EXPORT int EC_KEY_is_opaque(const EC_KEY *key); + +// EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. +OPENSSL_EXPORT const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +// EC_KEY_set_group sets the |EC_GROUP| object that |key| will use to |group|. +// It returns one on success and zero if |key| is already configured with a +// different group. +OPENSSL_EXPORT int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +// EC_KEY_get0_private_key returns a pointer to the private key inside |key|. +OPENSSL_EXPORT const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +// EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns +// one on success and zero otherwise. |key| must already have had a group +// configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|). +OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv); + +// EC_KEY_get0_public_key returns a pointer to the public key point inside +// |key|. +OPENSSL_EXPORT const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +// EC_KEY_set_public_key sets the public key of |key| to |pub|, by copying it. +// It returns one on success and zero otherwise. |key| must already have had a +// group configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|), and +// |pub| must also belong to that group. +OPENSSL_EXPORT int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +// EC_KEY_get_enc_flags returns the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT unsigned EC_KEY_get_enc_flags(const EC_KEY *key); + +// EC_KEY_set_enc_flags sets the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT void EC_KEY_set_enc_flags(EC_KEY *key, unsigned flags); + +// EC_KEY_get_conv_form returns the conversation form that will be used by +// |key|. +OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); + +// EC_KEY_set_conv_form sets the conversion form to be used by |key|. +OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key, + point_conversion_form_t cform); + +// EC_KEY_check_key performs several checks on |key| (possibly including an +// expensive check that the public key is in the primary subgroup). It returns +// one if all checks pass and zero otherwise. If it returns zero then detail +// about the problem can be found on the error stack. +OPENSSL_EXPORT int EC_KEY_check_key(const EC_KEY *key); + +// EC_KEY_check_fips performs both a signing pairwise consistency test +// (FIPS 140-2 4.9.2) and the consistency test from SP 800-56Ar3 section +// 5.6.2.1.4. It returns one if it passes and zero otherwise. +OPENSSL_EXPORT int EC_KEY_check_fips(const EC_KEY *key); + +// EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to +// (|x|, |y|). It returns one on success and zero on error. It's considered an +// error if |x| and |y| do not represent a point on |key|'s curve. +OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, + const BIGNUM *x, + const BIGNUM *y); + +// EC_KEY_key2buf encodes the public key in |key| to an allocated octet string +// and sets |*out_buf| to point to it. It returns the length of the encoded +// octet string or zero if an error occurred. +OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, + point_conversion_form_t form, + unsigned char **out_buf, BN_CTX *ctx); + + +// Key generation. + +// EC_KEY_generate_key generates a random, private key, calculates the +// corresponding public key and stores both in |key|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key); + +// EC_KEY_generate_key_fips behaves like |EC_KEY_generate_key| but performs +// additional checks for FIPS compliance. This function is applicable when +// generating keys for either signing/verification or key agreement because +// both types of consistency check (PCT) are performed. +OPENSSL_EXPORT int EC_KEY_generate_key_fips(EC_KEY *key); + +// EC_KEY_derive_from_secret deterministically derives a private key for |group| +// from an input secret using HKDF-SHA256. It returns a newly-allocated |EC_KEY| +// on success or NULL on error. |secret| must not be used in any other +// algorithm. If using a base secret for multiple operations, derive separate +// values with a KDF such as HKDF first. +// +// Note this function implements an arbitrary derivation scheme, rather than any +// particular standard one. New protocols are recommended to use X25519 and +// Ed25519, which have standard byte import functions. See +// |X25519_public_from_private| and |ED25519_keypair_from_seed|. +OPENSSL_EXPORT EC_KEY *EC_KEY_derive_from_secret(const EC_GROUP *group, + const uint8_t *secret, + size_t secret_len); + + +// Serialisation. + +// EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC +// 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or +// NULL on error. If |group| is non-null, the parameters field of the +// ECPrivateKey may be omitted (but must match |group| if present). Otherwise, +// the parameters field is required. +OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs, + const EC_GROUP *group); + +// EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey +// structure (RFC 5915) and appends the result to |cbb|. It returns one on +// success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*| +// values and controls whether corresponding fields are omitted. +OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags); + +// EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve +// name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs); + +// EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER +// and appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group); + +// EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC +// 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. It supports the namedCurve and specifiedCurve options, but +// use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name| +// instead. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs); + + +// ex_data functions. +// +// These functions are wrappers. See |ex_data.h| for details. + +OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg); +OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx); + + +// ECDSA method. + +// ECDSA_FLAG_OPAQUE specifies that this ECDSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define ECDSA_FLAG_OPAQUE 1 + +// ecdsa_method_st is a structure of function pointers for implementing ECDSA. +// See engine.h. +struct ecdsa_method_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(EC_KEY *key); + int (*finish)(EC_KEY *key); + + // group_order_size returns the number of bytes needed to represent the order + // of the group. This is used to calculate the maximum size of an ECDSA + // signature in |ECDSA_size|. + size_t (*group_order_size)(const EC_KEY *key); + + // sign matches the arguments and behaviour of |ECDSA_sign|. + int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, EC_KEY *eckey); + + int flags; +}; + + +// Deprecated functions. + +// EC_KEY_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag); + +// d2i_ECPrivateKey parses a DER-encoded ECPrivateKey structure (RFC 5915) from +// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. On input, if |*out_key| +// is non-NULL and has a group configured, the parameters field may be omitted +// but must match that group if present. +// +// Use |EC_KEY_parse_private_key| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECPrivateKey marshals |key| as a DER-encoded ECPrivateKey structure (RFC +// 5915), as described in |i2d_SAMPLE|. +// +// Use |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); + +// d2i_ECParameters parses a DER-encoded ECParameters structure (RFC 5480) from +// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// +// Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECParameters marshals |key|'s parameters as a DER-encoded OBJECT +// IDENTIFIER, as described in |i2d_SAMPLE|. +// +// Use |EC_KEY_marshal_curve_name| instead. +OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp); + +// o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into +// |*out_key|. Note that this differs from the d2i format in that |*out_key| +// must be non-NULL with a group set. On successful exit, |*inp| is advanced by +// |len| bytes. It returns |*out_key| or NULL on error. +// +// Use |EC_POINT_oct2point| instead. +OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2o_ECPublicKey marshals an EC point from |key|, as described in +// |i2d_SAMPLE|. +// +// Use |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(EC_KEY, EC_KEY_free) +BORINGSSL_MAKE_UP_REF(EC_KEY, EC_KEY_up_ref) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_EC_KEY_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdh.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdh.h new file mode 100644 index 00000000..d6949eb3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdh.h @@ -0,0 +1,118 @@ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_ECDH_H +#define OPENSSL_HEADER_ECDH_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_ec_key.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Elliptic curve Diffie-Hellman. + + +// ECDH_compute_key calculates the shared key between |pub_key| and |priv_key|. +// If |kdf| is not NULL, then it is called with the bytes of the shared key and +// the parameter |out|. When |kdf| returns, the value of |*outlen| becomes the +// return value. Otherwise, as many bytes of the shared key as will fit are +// copied directly to, at most, |outlen| bytes at |out|. It returns the number +// of bytes written to |out|, or -1 on error. +OPENSSL_EXPORT int ECDH_compute_key( + void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, size_t *outlen)); + +// ECDH_compute_key_fips calculates the shared key between |pub_key| and +// |priv_key| and hashes it with the appropriate SHA function for |out_len|. The +// only value values for |out_len| are thus 24 (SHA-224), 32 (SHA-256), 48 +// (SHA-384), and 64 (SHA-512). It returns one on success and zero on error. +// +// Note that the return value is different to |ECDH_compute_key|: it returns an +// error flag (as is common for BoringSSL) rather than the number of bytes +// written. +// +// This function allows the FIPS module to compute an ECDH and KDF within the +// module boundary without taking an arbitrary function pointer for the KDF, +// which isn't very FIPSy. +OPENSSL_EXPORT int ECDH_compute_key_fips(uint8_t *out, size_t out_len, + const EC_POINT *pub_key, + const EC_KEY *priv_key); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define ECDH_R_KDF_FAILED 100 +#define ECDH_R_NO_PRIVATE_VALUE 101 +#define ECDH_R_POINT_ARITHMETIC_FAILURE 102 +#define ECDH_R_UNKNOWN_DIGEST_LENGTH 103 + +#endif // OPENSSL_HEADER_ECDH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h new file mode 100644 index 00000000..b1459b0a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h @@ -0,0 +1,236 @@ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_ECDSA_H +#define OPENSSL_HEADER_ECDSA_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_ec_key.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ECDSA contains functions for signing and verifying with the Digital Signature +// Algorithm over elliptic curves. + + +// Signing and verifying. + +// ECDSA_sign signs |digest_len| bytes from |digest| with |key| and writes the +// resulting signature to |sig|, which must have |ECDSA_size(key)| bytes of +// space. On successful exit, |*sig_len| is set to the actual number of bytes +// written. The |type| argument should be zero. It returns one on success and +// zero otherwise. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// signed. Passing unhashed inputs will not result in a secure signature scheme. +OPENSSL_EXPORT int ECDSA_sign(int type, const uint8_t *digest, + size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *key); + +// ECDSA_verify verifies that |sig_len| bytes from |sig| constitute a valid +// signature by |key| of |digest|. (The |type| argument should be zero.) It +// returns one on success or zero if the signature is invalid or an error +// occurred. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// verified. Passing unhashed inputs will not result in a secure signature +// scheme. +OPENSSL_EXPORT int ECDSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const EC_KEY *key); + +// ECDSA_size returns the maximum size of an ECDSA signature using |key|. It +// returns zero if |key| is NULL or if it doesn't have a group set. +OPENSSL_EXPORT size_t ECDSA_size(const EC_KEY *key); + + +// Low-level signing and verification. +// +// Low-level functions handle signatures as |ECDSA_SIG| structures which allow +// the two values in an ECDSA signature to be handled separately. + +struct ecdsa_sig_st { + BIGNUM *r; + BIGNUM *s; +}; + +// ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_new(void); + +// ECDSA_SIG_free frees |sig| its member |BIGNUM|s. +OPENSSL_EXPORT void ECDSA_SIG_free(ECDSA_SIG *sig); + +// ECDSA_SIG_get0_r returns the r component of |sig|. +OPENSSL_EXPORT const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); + +// ECDSA_SIG_get0_s returns the s component of |sig|. +OPENSSL_EXPORT const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); + +// ECDSA_SIG_get0 sets |*out_r| and |*out_s|, if non-NULL, to the two +// components of |sig|. +OPENSSL_EXPORT void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s); + +// ECDSA_SIG_set0 sets |sig|'s components to |r| and |s|, neither of which may +// be NULL. On success, it takes ownership of each argument and returns one. +// Otherwise, it returns zero. +OPENSSL_EXPORT int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +// ECDSA_do_sign signs |digest_len| bytes from |digest| with |key| and returns +// the resulting signature structure, or NULL on error. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// signed. Passing unhashed inputs will not result in a secure signature scheme. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, + size_t digest_len, const EC_KEY *key); + +// ECDSA_do_verify verifies that |sig| constitutes a valid signature by |key| +// of |digest|. It returns one on success or zero if the signature is invalid +// or on error. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// verified. Passing unhashed inputs will not result in a secure signature +// scheme. +OPENSSL_EXPORT int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *key); + + +// ASN.1 functions. + +// ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs); + +// ECDSA_SIG_from_bytes parses |in| as a DER-encoded ECDSA-Sig-Value structure. +// It returns a newly-allocated |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, + size_t in_len); + +// ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends +// the result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig); + +// ECDSA_SIG_to_bytes marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on +// success, sets |*out_bytes| to a newly allocated buffer containing the result +// and returns one. Otherwise, it returns zero. The result should be freed with +// |OPENSSL_free|. +OPENSSL_EXPORT int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig); + +// ECDSA_SIG_max_len returns the maximum length of a DER-encoded ECDSA-Sig-Value +// structure for a group whose order is represented in |order_len| bytes, or +// zero on overflow. +OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len); + + +// Testing-only functions. + +// ECDSA_sign_with_nonce_and_leak_private_key_for_testing behaves like +// |ECDSA_do_sign| but uses |nonce| for the ECDSA nonce 'k', instead of a random +// value. |nonce| is interpreted as a big-endian integer. It must be reduced +// modulo the group order and padded with zeros up to |BN_num_bytes(order)| +// bytes. +// +// WARNING: This function is only exported for testing purposes, when using test +// vectors or fuzzing strategies. It must not be used outside tests and may leak +// any private keys it is used with. +OPENSSL_EXPORT ECDSA_SIG * +ECDSA_sign_with_nonce_and_leak_private_key_for_testing(const uint8_t *digest, + size_t digest_len, + const EC_KEY *eckey, + const uint8_t *nonce, + size_t nonce_len); + + +// Deprecated functions. + +// d2i_ECDSA_SIG parses aa DER-encoded ECDSA-Sig-Value structure from |len| +// bytes at |*inp|, as described in |d2i_SAMPLE|. +// +// Use |ECDSA_SIG_parse| instead. +OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, + long len); + +// i2d_ECDSA_SIG marshals |sig| as a DER-encoded ECDSA-Sig-Value, as described +// in |i2d_SAMPLE|. +// +// Use |ECDSA_SIG_marshal| instead. +OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(ECDSA_SIG, ECDSA_SIG_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_MISSING_PARAMETERS 101 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 102 +#define ECDSA_R_NOT_IMPLEMENTED 103 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_ECDSA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_engine.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_engine.h new file mode 100644 index 00000000..cab4a084 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_engine.h @@ -0,0 +1,109 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_ENGINE_H +#define OPENSSL_HEADER_ENGINE_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Engines are collections of methods. Methods are tables of function pointers, +// defined for certain algorithms, that allow operations on those algorithms to +// be overridden via a callback. This can be used, for example, to implement an +// RSA* that forwards operations to a hardware module. +// +// Methods are reference counted but |ENGINE|s are not. When creating a method, +// you should zero the whole structure and fill in the function pointers that +// you wish before setting it on an |ENGINE|. Any functions pointers that +// are NULL indicate that the default behaviour should be used. + + +// Allocation and destruction. + +// ENGINE_new returns an empty ENGINE that uses the default method for all +// algorithms. +OPENSSL_EXPORT ENGINE *ENGINE_new(void); + +// ENGINE_free decrements the reference counts for all methods linked from +// |engine| and frees |engine| itself. It returns one. +OPENSSL_EXPORT int ENGINE_free(ENGINE *engine); + + +// Method accessors. +// +// Method accessors take a method pointer and the size of the structure. The +// size allows for ABI compatibility in the case that the method structure is +// extended with extra elements at the end. Methods are always copied by the +// set functions. +// +// Set functions return one on success and zero on allocation failure. + +OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine, + const RSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine); + +OPENSSL_EXPORT int ENGINE_set_ECDSA_method(ENGINE *engine, + const ECDSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine); + + +// Generic method functions. +// +// These functions take a void* type but actually operate on all method +// structures. + +// METHOD_ref increments the reference count of |method|. This is a no-op for +// now because all methods are currently static. +void METHOD_ref(void *method); + +// METHOD_unref decrements the reference count of |method| and frees it if the +// reference count drops to zero. This is a no-op for now because all methods +// are currently static. +void METHOD_unref(void *method); + + +// Private functions. + +// openssl_method_common_st contains the common part of all method structures. +// This must be the first member of all method structures. +struct openssl_method_common_st { + int references; // dummy – not used. + char is_static; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(ENGINE, ENGINE_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define ENGINE_R_OPERATION_NOT_SUPPORTED 100 + +#endif // OPENSSL_HEADER_ENGINE_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h new file mode 100644 index 00000000..3841e50e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h @@ -0,0 +1,483 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_ERR_H +#define OPENSSL_HEADER_ERR_H + +#include + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Error queue handling functions. +// +// Errors in OpenSSL are generally signaled by the return value of a function. +// When a function fails it may add an entry to a per-thread error queue, +// which is managed by the functions in this header. +// +// Each error contains: +// 1) The library (i.e. ec, pem, rsa) which created it. +// 2) The file and line number of the call that added the error. +// 3) A pointer to some error specific data, which may be NULL. +// +// The library identifier and reason code are packed in a uint32_t and there +// exist various functions for unpacking it. +// +// The typical behaviour is that an error will occur deep in a call queue and +// that code will push an error onto the error queue. As the error queue +// unwinds, other functions will push their own errors. Thus, the "least +// recent" error is the most specific and the other errors will provide a +// backtrace of sorts. + + +// Startup and shutdown. + +// ERR_load_BIO_strings does nothing. +// +// TODO(fork): remove. libjingle calls this. +OPENSSL_EXPORT void ERR_load_BIO_strings(void); + +// ERR_load_ERR_strings does nothing. +OPENSSL_EXPORT void ERR_load_ERR_strings(void); + +// ERR_load_crypto_strings does nothing. +OPENSSL_EXPORT void ERR_load_crypto_strings(void); + +// ERR_load_RAND_strings does nothing. +OPENSSL_EXPORT void ERR_load_RAND_strings(void); + +// ERR_free_strings does nothing. +OPENSSL_EXPORT void ERR_free_strings(void); + + +// Reading and formatting errors. + +// ERR_GET_LIB returns the library code for the error. This is one of +// the |ERR_LIB_*| values. +#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff)) + +// ERR_GET_REASON returns the reason code for the error. This is one of +// library-specific |LIB_R_*| values where |LIB| is the library (see +// |ERR_GET_LIB|). Note that reason codes are specific to the library. +#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff)) + +// ERR_get_error gets the packed error code for the least recent error and +// removes that error from the queue. If there are no errors in the queue then +// it returns zero. +OPENSSL_EXPORT uint32_t ERR_get_error(void); + +// ERR_get_error_line acts like |ERR_get_error|, except that the file and line +// number of the call that added the error are also returned. +OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line); + +// ERR_FLAG_STRING means that the |data| member is a NUL-terminated string that +// can be printed. This is always set if |data| is non-NULL. +#define ERR_FLAG_STRING 1 + +// ERR_FLAG_MALLOCED is passed into |ERR_set_error_data| to indicate that |data| +// was allocated with |OPENSSL_malloc|. It is never returned from +// |ERR_get_error_line_data|. +#define ERR_FLAG_MALLOCED 2 + +// ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the +// error-specific data pointer and flags. The flags are a bitwise-OR of +// |ERR_FLAG_*| values. The error-specific data is owned by the error queue +// and the pointer becomes invalid after the next call that affects the same +// thread's error queue. If |*flags| contains |ERR_FLAG_STRING| then |*data| is +// human-readable. +OPENSSL_EXPORT uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek" functions act like the |ERR_get_error| functions, above, but they +// do not remove the error from the queue. +OPENSSL_EXPORT uint32_t ERR_peek_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek last" functions act like the "peek" functions, above, except that +// they return the most recent error. +OPENSSL_EXPORT uint32_t ERR_peek_last_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line_data(const char **file, + int *line, + const char **data, + int *flags); + +// ERR_error_string_n generates a human-readable string representing +// |packed_error|, places it at |buf|, and returns |buf|. It writes at most +// |len| bytes (including the terminating NUL) and truncates the string if +// necessary. If |len| is greater than zero then |buf| is always NUL terminated. +// +// The string will have the following format: +// +// error:[error code]:[library name]:OPENSSL_internal:[reason string] +// +// error code is an 8 digit hexadecimal number; library name and reason string +// are ASCII text. +OPENSSL_EXPORT char *ERR_error_string_n(uint32_t packed_error, char *buf, + size_t len); + +// ERR_lib_error_string returns a string representation of the library that +// generated |packed_error|, or a placeholder string is the library is +// unrecognized. +OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error); + +// ERR_reason_error_string returns a string representation of the reason for +// |packed_error|, or a placeholder string if the reason is unrecognized. +OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error); + +// ERR_print_errors_callback_t is the type of a function used by +// |ERR_print_errors_cb|. It takes a pointer to a human readable string (and +// its length) that describes an entry in the error queue. The |ctx| argument +// is an opaque pointer given to |ERR_print_errors_cb|. +// +// It should return one on success or zero on error, which will stop the +// iteration over the error queue. +typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len, + void *ctx); + +// ERR_print_errors_cb clears the current thread's error queue, calling +// |callback| with a string representation of each error, from the least recent +// to the most recent error. +// +// The string will have the following format (which differs from +// |ERR_error_string|): +// +// [thread id]:error:[error code]:[library name]:OPENSSL_internal:[reason string]:[file]:[line number]:[optional string data] +// +// The callback can return one to continue the iteration or zero to stop it. +// The |ctx| argument is an opaque value that is passed through to the +// callback. +OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback, + void *ctx); + +// ERR_print_errors_fp clears the current thread's error queue, printing each +// error to |file|. See |ERR_print_errors_cb| for the format. +OPENSSL_EXPORT void ERR_print_errors_fp(FILE *file); + + +// Clearing errors. + +// ERR_clear_error clears the error queue for the current thread. +OPENSSL_EXPORT void ERR_clear_error(void); + +// ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|. +// It returns one if an error was marked and zero if there are no errors. +OPENSSL_EXPORT int ERR_set_mark(void); + +// ERR_pop_to_mark removes errors from the most recent to the least recent +// until (and not including) a "marked" error. It returns zero if no marked +// error was found (and thus all errors were removed) and one otherwise. Errors +// are marked using |ERR_set_mark|. +OPENSSL_EXPORT int ERR_pop_to_mark(void); + + +// Custom errors. + +// ERR_get_next_error_library returns a value suitable for passing as the +// |library| argument to |ERR_put_error|. This is intended for code that wishes +// to push its own, non-standard errors to the error queue. +OPENSSL_EXPORT int ERR_get_next_error_library(void); + + +// Built-in library and reason codes. + +// The following values are built-in library codes. +enum { + ERR_LIB_NONE = 1, + ERR_LIB_SYS, + ERR_LIB_BN, + ERR_LIB_RSA, + ERR_LIB_DH, + ERR_LIB_EVP, + ERR_LIB_BUF, + ERR_LIB_OBJ, + ERR_LIB_PEM, + ERR_LIB_DSA, + ERR_LIB_X509, + ERR_LIB_ASN1, + ERR_LIB_CONF, + ERR_LIB_CRYPTO, + ERR_LIB_EC, + ERR_LIB_SSL, + ERR_LIB_BIO, + ERR_LIB_PKCS7, + ERR_LIB_PKCS8, + ERR_LIB_X509V3, + ERR_LIB_RAND, + ERR_LIB_ENGINE, + ERR_LIB_OCSP, + ERR_LIB_UI, + ERR_LIB_COMP, + ERR_LIB_ECDSA, + ERR_LIB_ECDH, + ERR_LIB_HMAC, + ERR_LIB_DIGEST, + ERR_LIB_CIPHER, + ERR_LIB_HKDF, + ERR_LIB_TRUST_TOKEN, + ERR_LIB_USER, + ERR_NUM_LIBS +}; + +// The following reason codes used to denote an error occuring in another +// library. They are sometimes used for a stack trace. +#define ERR_R_SYS_LIB ERR_LIB_SYS +#define ERR_R_BN_LIB ERR_LIB_BN +#define ERR_R_RSA_LIB ERR_LIB_RSA +#define ERR_R_DH_LIB ERR_LIB_DH +#define ERR_R_EVP_LIB ERR_LIB_EVP +#define ERR_R_BUF_LIB ERR_LIB_BUF +#define ERR_R_OBJ_LIB ERR_LIB_OBJ +#define ERR_R_PEM_LIB ERR_LIB_PEM +#define ERR_R_DSA_LIB ERR_LIB_DSA +#define ERR_R_X509_LIB ERR_LIB_X509 +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 +#define ERR_R_CONF_LIB ERR_LIB_CONF +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO +#define ERR_R_EC_LIB ERR_LIB_EC +#define ERR_R_SSL_LIB ERR_LIB_SSL +#define ERR_R_BIO_LIB ERR_LIB_BIO +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 +#define ERR_R_PKCS8_LIB ERR_LIB_PKCS8 +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 +#define ERR_R_RAND_LIB ERR_LIB_RAND +#define ERR_R_DSO_LIB ERR_LIB_DSO +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE +#define ERR_R_OCSP_LIB ERR_LIB_OCSP +#define ERR_R_UI_LIB ERR_LIB_UI +#define ERR_R_COMP_LIB ERR_LIB_COMP +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA +#define ERR_R_ECDH_LIB ERR_LIB_ECDH +#define ERR_R_STORE_LIB ERR_LIB_STORE +#define ERR_R_FIPS_LIB ERR_LIB_FIPS +#define ERR_R_CMS_LIB ERR_LIB_CMS +#define ERR_R_TS_LIB ERR_LIB_TS +#define ERR_R_HMAC_LIB ERR_LIB_HMAC +#define ERR_R_JPAKE_LIB ERR_LIB_JPAKE +#define ERR_R_USER_LIB ERR_LIB_USER +#define ERR_R_DIGEST_LIB ERR_LIB_DIGEST +#define ERR_R_CIPHER_LIB ERR_LIB_CIPHER +#define ERR_R_HKDF_LIB ERR_LIB_HKDF +#define ERR_R_TRUST_TOKEN_LIB ERR_LIB_TRUST_TOKEN + +// The following values are global reason codes. They may occur in any library. +#define ERR_R_FATAL 64 +#define ERR_R_MALLOC_FAILURE (1 | ERR_R_FATAL) +#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2 | ERR_R_FATAL) +#define ERR_R_PASSED_NULL_PARAMETER (3 | ERR_R_FATAL) +#define ERR_R_INTERNAL_ERROR (4 | ERR_R_FATAL) +#define ERR_R_OVERFLOW (5 | ERR_R_FATAL) + + +// Deprecated functions. + +// ERR_remove_state calls |ERR_clear_error|. +OPENSSL_EXPORT void ERR_remove_state(unsigned long pid); + +// ERR_remove_thread_state clears the error queue for the current thread if +// |tid| is NULL. Otherwise it calls |assert(0)|, because it's no longer +// possible to delete the error queue for other threads. +// +// Use |ERR_clear_error| instead. Note error queues are deleted automatically on +// thread exit. You do not need to call this function to release memory. +OPENSSL_EXPORT void ERR_remove_thread_state(const CRYPTO_THREADID *tid); + +// ERR_func_error_string returns the string "OPENSSL_internal". +OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error); + +// ERR_error_string behaves like |ERR_error_string_n| but |len| is implicitly +// |ERR_ERROR_STRING_BUF_LEN|. +// +// Additionally, if |buf| is NULL, the error string is placed in a static buffer +// which is returned. This is not thread-safe and only exists for backwards +// compatibility with legacy callers. The static buffer will be overridden by +// calls in other threads. +// +// Use |ERR_error_string_n| instead. +// +// TODO(fork): remove this function. +OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf); +#define ERR_ERROR_STRING_BUF_LEN 120 + +// ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code. +#define ERR_GET_FUNC(packed_error) 0 + +// ERR_TXT_* are provided for compatibility with code that assumes that it's +// using OpenSSL. +#define ERR_TXT_STRING ERR_FLAG_STRING +#define ERR_TXT_MALLOCED ERR_FLAG_MALLOCED + + +// Private functions. + +// ERR_clear_system_error clears the system's error value (i.e. errno). +OPENSSL_EXPORT void ERR_clear_system_error(void); + +// OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error +// queue. +#define OPENSSL_PUT_ERROR(library, reason) \ + ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__) + +// OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the +// operating system to the error queue. +// TODO(fork): include errno. +#define OPENSSL_PUT_SYSTEM_ERROR() \ + ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__); + +// ERR_put_error adds an error to the error queue, dropping the least recent +// error if necessary for space reasons. +OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason, + const char *file, unsigned line); + +// ERR_add_error_data takes a variable number (|count|) of const char* +// pointers, concatenates them and sets the result as the data on the most +// recent error. +OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...); + +// ERR_add_error_dataf takes a printf-style format and arguments, and sets the +// result as the data on the most recent error. +OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(1, 2); + +// ERR_set_error_data sets the data on the most recent error to |data|, which +// must be a NUL-terminated string. |flags| must contain |ERR_FLAG_STRING|. If +// |flags| contains |ERR_FLAG_MALLOCED|, this function takes ownership of +// |data|, which must have been allocated with |OPENSSL_malloc|. Otherwise, it +// saves a copy of |data|. +// +// Note this differs from OpenSSL which, when |ERR_FLAG_MALLOCED| is unset, +// saves the pointer as-is and requires it remain valid for the lifetime of the +// address space. +OPENSSL_EXPORT void ERR_set_error_data(char *data, int flags); + +// ERR_NUM_ERRORS is one more than the limit of the number of errors in the +// queue. +#define ERR_NUM_ERRORS 16 + +#define ERR_PACK(lib, reason) \ + (((((uint32_t)(lib)) & 0xff) << 24) | ((((uint32_t)(reason)) & 0xfff))) + +// OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates +// the error defines) to recognise that an additional reason value is needed. +// This is needed when the reason value is used outside of an +// |OPENSSL_PUT_ERROR| macro. The resulting define will be +// ${lib}_R_${reason}. +#define OPENSSL_DECLARE_ERROR_REASON(lib, reason) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_ERR_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h new file mode 100644 index 00000000..54f29f20 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h @@ -0,0 +1,1083 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_EVP_H +#define OPENSSL_HEADER_EVP_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_evp_errors.h" +#include "CNIOBoringSSL_thread.h" + +// OpenSSL included digest and cipher functions in this header so we include +// them for users that still expect that. +// +// TODO(fork): clean up callers so that they include what they use. +#include "CNIOBoringSSL_aead.h" +#include "CNIOBoringSSL_base64.h" +#include "CNIOBoringSSL_cipher.h" +#include "CNIOBoringSSL_digest.h" +#include "CNIOBoringSSL_nid.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP abstracts over public/private key algorithms. + + +// Public key objects. +// +// An |EVP_PKEY| object represents a public or private key. A given object may +// be used concurrently on multiple threads by non-mutating functions, provided +// no other thread is concurrently calling a mutating function. Unless otherwise +// documented, functions which take a |const| pointer are non-mutating and +// functions which take a non-|const| pointer are mutating. + +// EVP_PKEY_new creates a new, empty public-key object and returns it or NULL +// on allocation failure. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new(void); + +// EVP_PKEY_free frees all data referenced by |pkey| and then frees |pkey| +// itself. +OPENSSL_EXPORT void EVP_PKEY_free(EVP_PKEY *pkey); + +// EVP_PKEY_up_ref increments the reference count of |pkey| and returns one. It +// does not mutate |pkey| for thread-safety purposes and may be used +// concurrently. +OPENSSL_EXPORT int EVP_PKEY_up_ref(EVP_PKEY *pkey); + +// EVP_PKEY_is_opaque returns one if |pkey| is opaque. Opaque keys are backed by +// custom implementations which do not expose key material and parameters. It is +// an error to attempt to duplicate, export, or compare an opaque key. +OPENSSL_EXPORT int EVP_PKEY_is_opaque(const EVP_PKEY *pkey); + +// EVP_PKEY_cmp compares |a| and |b| and returns one if they are equal, zero if +// not and a negative number on error. +// +// WARNING: this differs from the traditional return value of a "cmp" +// function. +OPENSSL_EXPORT int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +// EVP_PKEY_copy_parameters sets the parameters of |to| to equal the parameters +// of |from|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); + +// EVP_PKEY_missing_parameters returns one if |pkey| is missing needed +// parameters or zero if not, or if the algorithm doesn't take parameters. +OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); + +// EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by +// |pkey|. For an RSA key, this returns the number of bytes needed to represent +// the modulus. For an EC key, this returns the maximum size of a DER-encoded +// ECDSA signature. +OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey); + +// EVP_PKEY_bits returns the "size", in bits, of |pkey|. For an RSA key, this +// returns the bit length of the modulus. For an EC key, this returns the bit +// length of the group order. +OPENSSL_EXPORT int EVP_PKEY_bits(const EVP_PKEY *pkey); + +// EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*| +// values. +OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); + +// EVP_PKEY_type returns |nid| if |nid| is a known key type and |NID_undef| +// otherwise. +OPENSSL_EXPORT int EVP_PKEY_type(int nid); + + +// Getting and setting concrete public key types. +// +// The following functions get and set the underlying public key in an +// |EVP_PKEY| object. The |set1| functions take an additional reference to the +// underlying key and return one on success or zero if |key| is NULL. The +// |assign| functions adopt the caller's reference and return one on success or +// zero if |key| is NULL. The |get1| functions return a fresh reference to the +// underlying object or NULL if |pkey| is not of the correct type. The |get0| +// functions behave the same but return a non-owning pointer. +// +// The |get0| and |get1| functions take |const| pointers and are thus +// non-mutating for thread-safety purposes, but mutating functions on the +// returned lower-level objects are considered to also mutate the |EVP_PKEY| and +// may not be called concurrently with other operations on the |EVP_PKEY|. + +OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey); +OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey); +OPENSSL_EXPORT DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey); + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA_PSS NID_rsassaPss +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_ED25519 NID_ED25519 +#define EVP_PKEY_X25519 NID_X25519 + +// EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of +// the given type. It returns one if successful or zero if the |type| argument +// is not one of the |EVP_PKEY_*| values or if |key| is NULL. +OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); + +// EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if +// successful or zero if the |type| argument is not one of the |EVP_PKEY_*| +// values. If |pkey| is NULL, it simply reports whether the type is known. +OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); + +// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns +// one if they match, zero if not, or a negative number of on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, + const EVP_PKEY *b); + + +// ASN.1 functions + +// EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure +// (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated +// |EVP_PKEY| or NULL on error. If the key is an EC key, the curve is guaranteed +// to be set. +// +// The caller must check the type of the parsed public key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); + +// EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo +// structure (RFC 5280) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key); + +// EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC +// 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY| +// or NULL on error. +// +// The caller must check the type of the parsed private key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. In particular, RSA private key operations scale cubicly, so +// applications accepting RSA private keys from external sources may need to +// bound key sizes (use |EVP_PKEY_bits| or |RSA_bits|) to avoid a DoS vector. +// +// A PrivateKeyInfo ends with an optional set of attributes. These are not +// processed and so this function will silently ignore any trailing data in the +// structure. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs); + +// EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo +// structure (RFC 5208) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); + + +// Raw keys +// +// Some keys types support a "raw" serialization. Currently the only supported +// raw format is Ed25519, where the public key and private key formats are those +// specified in RFC 8032. Note the RFC 8032 private key format is the 32-byte +// prefix of |ED25519_sign|'s 64-byte private key. + +// EVP_PKEY_new_raw_private_key returns a newly allocated |EVP_PKEY| wrapping a +// private key of the specified type. It returns one on success and zero on +// error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + +// EVP_PKEY_new_raw_public_key returns a newly allocated |EVP_PKEY| wrapping a +// public key of the specified type. It returns one on success and zero on +// error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + +// EVP_PKEY_get_raw_private_key outputs the private key for |pkey| in raw form. +// If |out| is NULL, it sets |*out_len| to the size of the raw private key. +// Otherwise, it writes at most |*out_len| bytes to |out| and sets |*out_len| to +// the number of bytes written. +// +// It returns one on success and zero if |pkey| has no private key, the key +// type does not support a raw format, or the buffer is too small. +OPENSSL_EXPORT int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, + uint8_t *out, size_t *out_len); + +// EVP_PKEY_get_raw_public_key outputs the public key for |pkey| in raw form. +// If |out| is NULL, it sets |*out_len| to the size of the raw public key. +// Otherwise, it writes at most |*out_len| bytes to |out| and sets |*out_len| to +// the number of bytes written. +// +// It returns one on success and zero if |pkey| has no public key, the key +// type does not support a raw format, or the buffer is too small. +OPENSSL_EXPORT int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, + uint8_t *out, size_t *out_len); + + +// Signing + +// EVP_DigestSignInit sets up |ctx| for a signing operation with |type| and +// |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestSign|. +// +// This function does not mutate |pkey| for thread-safety purposes and may be +// used concurrently with other non-mutating functions on |pkey|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestSignUpdate appends |len| bytes from |data| to the data which will +// be signed in |EVP_DigestSignFinal|. It returns one. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestSignFinal signs the data that has been included by one or more +// calls to |EVP_DigestSignUpdate|. If |out_sig| is NULL then |*out_sig_len| is +// set to the maximum number of output bytes. Otherwise, on entry, +// |*out_sig_len| must contain the length of the |out_sig| buffer. If the call +// is successful, the signature is written to |out_sig| and |*out_sig_len| is +// set to its length. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len); + +// EVP_DigestSign signs |data_len| bytes from |data| using |ctx|. If |out_sig| +// is NULL then |*out_sig_len| is set to the maximum number of output +// bytes. Otherwise, on entry, |*out_sig_len| must contain the length of the +// |out_sig| buffer. If the call is successful, the signature is written to +// |out_sig| and |*out_sig_len| is set to its length. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len, const uint8_t *data, + size_t data_len); + + +// Verifying + +// EVP_DigestVerifyInit sets up |ctx| for a signature verification operation +// with |type| and |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestVerify|. +// +// This function does not mutate |pkey| for thread-safety purposes and may be +// used concurrently with other non-mutating functions on |pkey|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which +// will be verified by |EVP_DigestVerifyFinal|. It returns one. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestVerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature for the data that has been included by one or more calls to +// |EVP_DigestVerifyUpdate|. It returns one on success and zero otherwise. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len); + +// EVP_DigestVerify verifies that |sig_len| bytes from |sig| are a valid +// signature for |data|. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *data, + size_t len); + + +// Signing (old functions) + +// EVP_SignInit_ex configures |ctx|, which must already have been initialised, +// for a fresh signing operation using the hash function |type|. It returns one +// on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_SignInit is a deprecated version of |EVP_SignInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_SignUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_SignFinal|. +OPENSSL_EXPORT int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_SignFinal signs the data that has been included by one or more calls to +// |EVP_SignUpdate|, using the key |pkey|, and writes it to |sig|. On entry, +// |sig| must point to at least |EVP_PKEY_size(pkey)| bytes of space. The +// actual size of the signature is written to |*out_sig_len|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to sign a longer message. It also does not mutate |pkey| for +// thread-safety purposes and may be used concurrently with other non-mutating +// functions on |pkey|. +OPENSSL_EXPORT int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey); + + +// Verifying (old functions) + +// EVP_VerifyInit_ex configures |ctx|, which must already have been +// initialised, for a fresh signature verification operation using the hash +// function |type|. It returns one on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_VerifyInit is a deprecated version of |EVP_VerifyInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_VerifyUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_VerifyFinal|. +OPENSSL_EXPORT int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_VerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature, by |pkey|, for the data that has been included by one or more +// calls to |EVP_VerifyUpdate|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to verify a longer message. It also does not mutate |pkey| for +// thread-safety purposes and may be used concurrently with other non-mutating +// functions on |pkey|. +OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, EVP_PKEY *pkey); + + +// Printing + +// EVP_PKEY_print_public prints a textual representation of the public key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_private prints a textual representation of the private key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_params prints a textual representation of the parameters in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + + +// Password stretching. +// +// Password stretching functions take a low-entropy password and apply a slow +// function that results in a key suitable for use in symmetric +// cryptography. + +// PKCS5_PBKDF2_HMAC computes |iterations| iterations of PBKDF2 of |password| +// and |salt|, using |digest|, and outputs |key_len| bytes to |out_key|. It +// returns one on success and zero on allocation failure or if iterations is 0. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, const EVP_MD *digest, + size_t key_len, uint8_t *out_key); + +// PKCS5_PBKDF2_HMAC_SHA1 is the same as PKCS5_PBKDF2_HMAC, but with |digest| +// fixed to |EVP_sha1|. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password, + size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key); + +// EVP_PBE_scrypt expands |password| into a secret key of length |key_len| using +// scrypt, as described in RFC 7914, and writes the result to |out_key|. It +// returns one on success and zero on allocation failure, if the memory required +// for the operation exceeds |max_mem|, or if any of the parameters are invalid +// as described below. +// +// |N|, |r|, and |p| are as described in RFC 7914 section 6. They determine the +// cost of the operation. If |max_mem| is zero, a defult limit of 32MiB will be +// used. +// +// The parameters are considered invalid under any of the following conditions: +// - |r| or |p| are zero +// - |p| > (2^30 - 1) / |r| +// - |N| is not a power of two +// - |N| > 2^32 +// - |N| > 2^(128 * |r| / 8) +OPENSSL_EXPORT int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + uint64_t N, uint64_t r, uint64_t p, + size_t max_mem, uint8_t *out_key, + size_t key_len); + + +// Public key contexts. +// +// |EVP_PKEY_CTX| objects hold the context of an operation (e.g. signing or +// encrypting) that uses a public key. + +// EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It +// returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); + +// EVP_PKEY_CTX_new_id allocates a fresh |EVP_PKEY_CTX| for a key of type |id| +// (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where +// |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass +// it. It returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + +// EVP_PKEY_CTX_free frees |ctx| and the data it owns. +OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the +// state of |ctx|. It returns the fresh |EVP_PKEY_CTX| or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It +// should be called before |EVP_PKEY_sign|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign signs |digest_len| bytes from |digest| using |ctx|. If |sig| is +// NULL, the maximum size of the signature is written to |out_sig_len|. +// Otherwise, |*sig_len| must contain the number of bytes of space available at +// |sig|. If sufficient, the signature will be written to |sig| and |*sig_len| +// updated with the true length. This function will fail for signature +// algorithms like Ed25519 that do not support signing pre-hashed inputs. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// signed. Passing unhashed inputs will not result in a secure signature scheme. +// Use |EVP_DigestSignInit| to sign an unhashed input. +// +// WARNING: Setting |sig| to NULL only gives the maximum size of the +// signature. The actual signature may be smaller. +// +// It returns one on success or zero on error. (Note: this differs from +// OpenSSL, which can also return negative values to indicate an error. ) +OPENSSL_EXPORT int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_verify_init initialises an |EVP_PKEY_CTX| for a signature +// verification operation. It should be called before |EVP_PKEY_verify|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify verifies that |sig_len| bytes from |sig| are a valid +// signature for |digest|. This function will fail for signature +// algorithms like Ed25519 that do not support signing pre-hashed inputs. +// +// WARNING: |digest| must be the output of some hash function on the data to be +// verified. Passing unhashed inputs will not result in a secure signature +// scheme. Use |EVP_DigestVerifyInit| to verify a signature given the unhashed +// input. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_encrypt_init initialises an |EVP_PKEY_CTX| for an encryption +// operation. It should be called before |EVP_PKEY_encrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_encrypt encrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the ciphertext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// ciphertext. The actual ciphertext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_decrypt_init initialises an |EVP_PKEY_CTX| for a decryption +// operation. It should be called before |EVP_PKEY_decrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_decrypt decrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the plaintext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_verify_recover_init initialises an |EVP_PKEY_CTX| for a public-key +// decryption operation. It should be called before |EVP_PKEY_verify_recover|. +// +// Public-key decryption is a very obscure operation that is only implemented +// by RSA keys. It is effectively a signature verification operation that +// returns the signed message directly. It is almost certainly not what you +// want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify_recover decrypts |sig_len| bytes from |sig|. If |out| is +// NULL, the maximum size of the plaintext is written to |out_len|. Otherwise, +// |*out_len| must contain the number of bytes of space available at |out|. If +// sufficient, the ciphertext will be written to |out| and |*out_len| updated +// with the true length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// See the warning about this operation in |EVP_PKEY_verify_recover_init|. It +// is probably not what you want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t siglen); + +// EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation +// operation. It should be called before |EVP_PKEY_derive_set_peer| and +// |EVP_PKEY_derive|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_derive_set_peer sets the peer's key to be used for key derivation +// by |ctx| to |peer|. It should be called after |EVP_PKEY_derive_init|. (For +// example, this is used to set the peer's key in (EC)DH.) It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); + +// EVP_PKEY_derive derives a shared key between the two keys configured in +// |ctx|. If |key| is non-NULL then, on entry, |out_key_len| must contain the +// amount of space at |key|. If sufficient then the shared key will be written +// to |key| and |*out_key_len| will be set to the length. If |key| is NULL then +// |out_key_len| will be set to the maximum length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the key. The +// actual key may be smaller. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *out_key_len); + +// EVP_PKEY_keygen_init initialises an |EVP_PKEY_CTX| for a key generation +// operation. It should be called before |EVP_PKEY_keygen|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_keygen performs a key generation operation using the values from +// |ctx|. If |*out_pkey| is non-NULL, it overwrites |*out_pkey| with the +// resulting key. Otherwise, it sets |*out_pkey| to a newly-allocated |EVP_PKEY| +// containing the result. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey); + +// EVP_PKEY_paramgen_init initialises an |EVP_PKEY_CTX| for a parameter +// generation operation. It should be called before |EVP_PKEY_paramgen|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_paramgen performs a parameter generation using the values from +// |ctx|. If |*out_pkey| is non-NULL, it overwrites |*out_pkey| with the +// resulting parameters, but no key. Otherwise, it sets |*out_pkey| to a +// newly-allocated |EVP_PKEY| containing the result. It returns one on success +// or zero on error. +OPENSSL_EXPORT int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey); + + +// Generic control functions. + +// EVP_PKEY_CTX_set_signature_md sets |md| as the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_signature_md sets |*out_md| to the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + + +// RSA specific control functions. + +// EVP_PKEY_CTX_set_rsa_padding sets the padding type to use. It should be one +// of the |RSA_*_PADDING| values. Returns one on success or zero on error. By +// default, the padding is |RSA_PKCS1_PADDING|. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding); + +// EVP_PKEY_CTX_get_rsa_padding sets |*out_padding| to the current padding +// value, which is one of the |RSA_*_PADDING| values. Returns one on success or +// zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, + int *out_padding); + +// EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded +// signature. A value of -1 cause the salt to be the same length as the digest +// in the signature. A value of -2 causes the salt to be the maximum length +// that will fit when signing and recovered from the signature when verifying. +// Otherwise the value gives the size of the salt in bytes. +// +// If unsure, use -1. +// +// Returns one on success or zero on error. +// +// TODO(davidben): The default is currently -2. Switch it to -1. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int salt_len); + +// EVP_PKEY_CTX_get_rsa_pss_saltlen sets |*out_salt_len| to the salt length of +// a PSS-padded signature. See the documentation for +// |EVP_PKEY_CTX_set_rsa_pss_saltlen| for details of the special values that it +// can take. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int *out_salt_len); + +// EVP_PKEY_CTX_set_rsa_keygen_bits sets the size of the desired RSA modulus, +// in bits, for key generation. Returns one on success or zero on +// error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, + int bits); + +// EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key +// generation. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, + BIGNUM *e); + +// EVP_PKEY_CTX_set_rsa_oaep_md sets |md| as the digest used in OAEP padding. +// Returns one on success or zero on error. If unset, the default is SHA-1. +// Callers are recommended to overwrite this default. +// +// TODO(davidben): Remove the default and require callers specify this. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_oaep_md sets |*out_md| to the digest function used in +// OAEP padding. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set_rsa_mgf1_md sets |md| as the digest used in MGF1. Returns +// one on success or zero on error. +// +// If unset, the default is the signing hash for |RSA_PKCS1_PSS_PADDING| and the +// OAEP hash for |RSA_PKCS1_OAEP_PADDING|. Callers are recommended to use this +// default and not call this function. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_mgf1_md sets |*out_md| to the digest function used in +// MGF1. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set0_rsa_oaep_label sets |label_len| bytes from |label| as the +// label used in OAEP. DANGER: On success, this call takes ownership of |label| +// and will call |OPENSSL_free| on it when |ctx| is destroyed. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + uint8_t *label, + size_t label_len); + +// EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal +// buffer containing the OAEP label (which may be NULL) and returns the length +// of the label or a negative value on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label); + + +// EC specific control functions. + +// EVP_PKEY_CTX_set_ec_paramgen_curve_nid sets the curve used for +// |EVP_PKEY_keygen| or |EVP_PKEY_paramgen| operations to |nid|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, + int nid); + + +// Deprecated functions. + +// EVP_PKEY_DH is defined for compatibility, but it is impossible to create an +// |EVP_PKEY| of that type. +#define EVP_PKEY_DH NID_dhKeyAgreement + +// EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID +// 2.5.8.1.1), but is no longer accepted. +#define EVP_PKEY_RSA2 NID_rsa + +// EVP_PKEY_X448 is defined for OpenSSL compatibility, but we do not support +// X448 and attempts to create keys will fail. +#define EVP_PKEY_X448 NID_X448 + +// EVP_PKEY_ED448 is defined for OpenSSL compatibility, but we do not support +// Ed448 and attempts to create keys will fail. +#define EVP_PKEY_ED448 NID_ED448 + +// EVP_PKEY_get0 returns NULL. This function is provided for compatibility with +// OpenSSL but does not return anything. Use the typed |EVP_PKEY_get0_*| +// functions instead. +OPENSSL_EXPORT void *EVP_PKEY_get0(const EVP_PKEY *pkey); + +// OpenSSL_add_all_algorithms does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); + +// OPENSSL_add_all_algorithms_conf does nothing. +OPENSSL_EXPORT void OPENSSL_add_all_algorithms_conf(void); + +// OpenSSL_add_all_ciphers does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_ciphers(void); + +// OpenSSL_add_all_digests does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_digests(void); + +// EVP_cleanup does nothing. +OPENSSL_EXPORT void EVP_cleanup(void); + +OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted( + void (*callback)(const EVP_CIPHER *cipher, const char *name, + const char *unused, void *arg), + void *arg); + +OPENSSL_EXPORT void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher, + const char *name, + const char *unused, + void *arg), + void *arg); + +OPENSSL_EXPORT void EVP_MD_do_all(void (*callback)(const EVP_MD *cipher, + const char *name, + const char *unused, + void *arg), + void *arg); + +// i2d_PrivateKey marshals a private key from |key| to type-specific format, as +// described in |i2d_SAMPLE|. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 8017) structure. +// EC keys are serialized as a DER-encoded ECPrivateKey (RFC 5915) structure. +// +// Use |RSA_marshal_private_key| or |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp); + +// i2d_PublicKey marshals a public key from |key| to a type-specific format, as +// described in |i2d_SAMPLE|. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 8017) structure. +// EC keys are serialized as an EC point per SEC 1. +// +// Use |RSA_marshal_public_key| or |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp); + +// d2i_PrivateKey parses a DER-encoded private key from |len| bytes at |*inp|, +// as described in |d2i_SAMPLE|. The private key must have type |type|, +// otherwise it will be rejected. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, + const uint8_t **inp, long len); + +// d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type +// of the private key. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, + long len); + +// d2i_PublicKey parses a public key from |len| bytes at |*inp| in a type- +// specific format specified by |type|, as described in |d2i_SAMPLE|. +// +// The only supported value for |type| is |EVP_PKEY_RSA|, which parses a +// DER-encoded RSAPublicKey (RFC 8017) structure. Parsing EC keys is not +// supported by this function. +// +// Use |RSA_parse_public_key| instead. +OPENSSL_EXPORT EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, + const uint8_t **inp, long len); + +// EVP_PKEY_get0_DH returns NULL. +OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); + +// EVP_PKEY_get1_DH returns NULL. +OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey); + +// EVP_PKEY_CTX_set_ec_param_enc returns one if |encoding| is +// |OPENSSL_EC_NAMED_CURVE| or zero with an error otherwise. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, + int encoding); + +// EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by +// |in|. It returns one on success and zero on error. +// +// This function only works on X25519 keys. +OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const uint8_t *in, + size_t len); + +// EVP_PKEY_get1_tls_encodedpoint sets |*out_ptr| to a newly-allocated buffer +// containing the raw encoded public key for |pkey|. The caller must call +// |OPENSSL_free| to release this buffer. The function returns the length of the +// buffer on success and zero on error. +// +// This function only works on X25519 keys. +OPENSSL_EXPORT size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr); + +// EVP_PKEY_base_id calls |EVP_PKEY_id|. +OPENSSL_EXPORT int EVP_PKEY_base_id(const EVP_PKEY *pkey); + +// EVP_PKEY_CTX_set_rsa_pss_keygen_md returns 0. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen returns 0. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, + int salt_len); + +// EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md returns 0. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// i2d_PUBKEY marshals |pkey| as a DER-encoded SubjectPublicKeyInfo, as +// described in |i2d_SAMPLE|. +// +// Use |EVP_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp); + +// d2i_PUBKEY parses a DER-encoded SubjectPublicKeyInfo from |len| bytes at +// |*inp|, as described in |d2i_SAMPLE|. +// +// Use |EVP_parse_public_key| instead. +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, + long len); + +// i2d_RSA_PUBKEY marshals |rsa| as a DER-encoded SubjectPublicKeyInfo +// structure, as described in |i2d_SAMPLE|. +// +// Use |EVP_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp); + +// d2i_RSA_PUBKEY parses an RSA public key as a DER-encoded SubjectPublicKeyInfo +// from |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// SubjectPublicKeyInfo structures containing other key types are rejected. +// +// Use |EVP_parse_public_key| instead. +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len); + +// i2d_DSA_PUBKEY marshals |dsa| as a DER-encoded SubjectPublicKeyInfo, as +// described in |i2d_SAMPLE|. +// +// Use |EVP_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp); + +// d2i_DSA_PUBKEY parses a DSA public key as a DER-encoded SubjectPublicKeyInfo +// from |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// SubjectPublicKeyInfo structures containing other key types are rejected. +// +// Use |EVP_parse_public_key| instead. +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len); + +// i2d_EC_PUBKEY marshals |ec_key| as a DER-encoded SubjectPublicKeyInfo, as +// described in |i2d_SAMPLE|. +// +// Use |EVP_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp); + +// d2i_EC_PUBKEY parses an EC public key as a DER-encoded SubjectPublicKeyInfo +// from |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// SubjectPublicKeyInfo structures containing other key types are rejected. +// +// Use |EVP_parse_public_key| instead. +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, + long len); + + +// Preprocessor compatibility section (hidden). +// +// Historically, a number of APIs were implemented in OpenSSL as macros and +// constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this +// section defines a number of legacy macros. + +// |BORINGSSL_PREFIX| already makes each of these symbols into macros, so there +// is no need to define conflicting macros. +#if !defined(BORINGSSL_PREFIX) +#define EVP_PKEY_CTX_set_rsa_oaep_md EVP_PKEY_CTX_set_rsa_oaep_md +#define EVP_PKEY_CTX_set0_rsa_oaep_label EVP_PKEY_CTX_set0_rsa_oaep_label +#endif + + +// Nodejs compatibility section (hidden). +// +// These defines exist for node.js, with the hope that we can eliminate the +// need for them over time. + +#define EVPerr(function, reason) \ + ERR_put_error(ERR_LIB_EVP, 0, reason, __FILE__, __LINE__) + + +// Private structures. + +struct evp_pkey_st { + CRYPTO_refcount_t references; + + // type contains one of the EVP_PKEY_* values or NID_undef and determines + // which element (if any) of the |pkey| union is valid. + int type; + + union { + void *ptr; + RSA *rsa; + DSA *dsa; + DH *dh; + EC_KEY *ec; + } pkey; + + // ameth contains a pointer to a method table that contains many ASN.1 + // methods for the key type. + const EVP_PKEY_ASN1_METHOD *ameth; +} /* EVP_PKEY */; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) +BORINGSSL_MAKE_UP_REF(EVP_PKEY, EVP_PKEY_up_ref) +BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_EVP_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp_errors.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp_errors.h new file mode 100644 index 00000000..8583f521 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp_errors.h @@ -0,0 +1,99 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_EVP_ERRORS_H +#define OPENSSL_HEADER_EVP_ERRORS_H + +#define EVP_R_BUFFER_TOO_SMALL 100 +#define EVP_R_COMMAND_NOT_SUPPORTED 101 +#define EVP_R_DECODE_ERROR 102 +#define EVP_R_DIFFERENT_KEY_TYPES 103 +#define EVP_R_DIFFERENT_PARAMETERS 104 +#define EVP_R_ENCODE_ERROR 105 +#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106 +#define EVP_R_EXPECTING_AN_RSA_KEY 107 +#define EVP_R_EXPECTING_A_DSA_KEY 108 +#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109 +#define EVP_R_INVALID_DIGEST_LENGTH 110 +#define EVP_R_INVALID_DIGEST_TYPE 111 +#define EVP_R_INVALID_KEYBITS 112 +#define EVP_R_INVALID_MGF1_MD 113 +#define EVP_R_INVALID_OPERATION 114 +#define EVP_R_INVALID_PADDING_MODE 115 +#define EVP_R_INVALID_PSS_SALTLEN 116 +#define EVP_R_KEYS_NOT_SET 117 +#define EVP_R_MISSING_PARAMETERS 118 +#define EVP_R_NO_DEFAULT_DIGEST 119 +#define EVP_R_NO_KEY_SET 120 +#define EVP_R_NO_MDC2_SUPPORT 121 +#define EVP_R_NO_NID_FOR_CURVE 122 +#define EVP_R_NO_OPERATION_SET 123 +#define EVP_R_NO_PARAMETERS_SET 124 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 125 +#define EVP_R_OPERATON_NOT_INITIALIZED 126 +#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127 +#define EVP_R_UNSUPPORTED_ALGORITHM 128 +#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129 +#define EVP_R_NOT_A_PRIVATE_KEY 130 +#define EVP_R_INVALID_SIGNATURE 131 +#define EVP_R_MEMORY_LIMIT_EXCEEDED 132 +#define EVP_R_INVALID_PARAMETERS 133 +#define EVP_R_INVALID_PEER_KEY 134 +#define EVP_R_NOT_XOF_OR_INVALID_LENGTH 135 +#define EVP_R_EMPTY_PSK 136 +#define EVP_R_INVALID_BUFFER_SIZE 137 + +#endif // OPENSSL_HEADER_EVP_ERRORS_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h new file mode 100644 index 00000000..e6602a69 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h @@ -0,0 +1,203 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_EX_DATA_H +#define OPENSSL_HEADER_EX_DATA_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_stack.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ex_data is a mechanism for associating arbitrary extra data with objects. +// For each type of object that supports ex_data, different users can be +// assigned indexes in which to store their data. Each index has callback +// functions that are called when an object of that type is freed or +// duplicated. + + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + + +// Type-specific functions. +// +// Each type that supports ex_data provides three functions: + +#if 0 // Sample + +// TYPE_get_ex_new_index allocates a new index for |TYPE|. An optional +// |free_func| argument may be provided which is called when the owning object +// is destroyed. See |CRYPTO_EX_free| for details. The |argl| and |argp| +// arguments are opaque values that are passed to the callback. It returns the +// new index or a negative number on error. +OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +// TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument +// should have been returned from a previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg); + +// TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such +// pointer exists. The |index| argument should have been returned from a +// previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index); + +#endif // Sample + + +// Callback types. + +// CRYPTO_EX_free is a callback function that is called when an object of the +// class with extra data pointers is being destroyed. For example, if this +// callback has been passed to |SSL_get_ex_new_index| then it may be called each +// time an |SSL*| is destroyed. +// +// The callback is passed the new object (i.e. the |SSL*|) in |parent|. The +// arguments |argl| and |argp| contain opaque values that were given to +// |CRYPTO_get_ex_new_index|. The callback should return one on success, but +// the value is ignored. +// +// This callback may be called with a NULL value for |ptr| if |parent| has no +// value set for this index. However, the callbacks may also be skipped entirely +// if no extra data pointers are set on |parent| at all. +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int index, long argl, void *argp); + + +// Deprecated functions. + +// CRYPTO_cleanup_all_ex_data does nothing. +OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void); + +// CRYPTO_EX_dup is a legacy callback function type which is ignored. +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int index, long argl, void *argp); + + +// Private structures. + +// CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to +// int to ensure non-NULL callers fail to compile rather than fail silently. +typedef int CRYPTO_EX_unused; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EX_DATA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hkdf.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hkdf.h new file mode 100644 index 00000000..eb7db053 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hkdf.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HKDF_H +#define OPENSSL_HEADER_HKDF_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HKDF. + + +// HKDF computes HKDF (as specified by RFC 5869) of initial keying material +// |secret| with |salt| and |info| using |digest|, and outputs |out_len| bytes +// to |out_key|. It returns one on success and zero on error. +// +// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching, +// and as such, is not suited to be used alone to generate a key from a +// password. +OPENSSL_EXPORT int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const uint8_t *salt, size_t salt_len, + const uint8_t *info, size_t info_len); + +// HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from initial +// keying material |secret| and salt |salt| using |digest|, and outputs +// |out_len| bytes to |out_key|. The maximum output size is |EVP_MAX_MD_SIZE|. +// It returns one on success and zero on error. +// +// WARNING: This function orders the inputs differently from RFC 5869 +// specification. Double-check which parameter is the secret/IKM and which is +// the salt when using. +OPENSSL_EXPORT int HKDF_extract(uint8_t *out_key, size_t *out_len, + const EVP_MD *digest, const uint8_t *secret, + size_t secret_len, const uint8_t *salt, + size_t salt_len); + +// HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of length +// |out_len| from the PRK |prk| and info |info| using |digest|, and outputs +// the result to |out_key|. It returns one on success and zero on error. +OPENSSL_EXPORT int HKDF_expand(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *prk, + size_t prk_len, const uint8_t *info, + size_t info_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define HKDF_R_OUTPUT_TOO_LARGE 100 + +#endif // OPENSSL_HEADER_HKDF_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hmac.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hmac.h new file mode 100644 index 00000000..e10e6013 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hmac.h @@ -0,0 +1,190 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_HMAC_H +#define OPENSSL_HEADER_HMAC_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_digest.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HMAC contains functions for constructing PRFs from Merkle–Damgård hash +// functions using HMAC. + + +// One-shot operation. + +// HMAC calculates the HMAC of |data_len| bytes of |data|, using the given key +// and hash function, and writes the result to |out|. On entry, |out| must +// contain at least |EVP_MD_size| bytes of space. The actual length of the +// result is written to |*out_len|. An output size of |EVP_MAX_MD_SIZE| will +// always be large enough. It returns |out| or NULL on error. +OPENSSL_EXPORT uint8_t *HMAC(const EVP_MD *evp_md, const void *key, + size_t key_len, const uint8_t *data, + size_t data_len, uint8_t *out, + unsigned int *out_len); + + +// Incremental operation. + +// HMAC_CTX_init initialises |ctx| for use in an HMAC operation. It's assumed +// that HMAC_CTX objects will be allocated on the stack thus no allocation +// function is provided. +OPENSSL_EXPORT void HMAC_CTX_init(HMAC_CTX *ctx); + +// HMAC_CTX_new allocates and initialises a new |HMAC_CTX| and returns it, or +// NULL on allocation failure. The caller must use |HMAC_CTX_free| to release +// the resulting object. +OPENSSL_EXPORT HMAC_CTX *HMAC_CTX_new(void); + +// HMAC_CTX_cleanup frees data owned by |ctx|. It does not free |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +// HMAC_CTX_cleanse zeros the digest state from |ctx| and then performs the +// actions of |HMAC_CTX_cleanup|. +OPENSSL_EXPORT void HMAC_CTX_cleanse(HMAC_CTX *ctx); + +// HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_free(HMAC_CTX *ctx); + +// HMAC_Init_ex sets up an initialised |HMAC_CTX| to use |md| as the hash +// function and |key| as the key. For a non-initial call, |md| may be NULL, in +// which case the previous hash function will be used. If the hash function has +// not changed and |key| is NULL, |ctx| reuses the previous key. It returns one +// on success or zero on allocation failure. +// +// WARNING: NULL and empty keys are ambiguous on non-initial calls. Passing NULL +// |key| but repeating the previous |md| reuses the previous key rather than the +// empty key. +OPENSSL_EXPORT int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl); + +// HMAC_Update hashes |data_len| bytes from |data| into the current HMAC +// operation in |ctx|. It returns one. +OPENSSL_EXPORT int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, + size_t data_len); + +// HMAC_Final completes the HMAC operation in |ctx| and writes the result to +// |out| and the sets |*out_len| to the length of the result. On entry, |out| +// must contain at least |HMAC_size| bytes of space. An output size of +// |EVP_MAX_MD_SIZE| will always be large enough. It returns one on success or +// zero on allocation failure. +OPENSSL_EXPORT int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, + unsigned int *out_len); + + +// Utility functions. + +// HMAC_size returns the size, in bytes, of the HMAC that will be produced by +// |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. +OPENSSL_EXPORT size_t HMAC_size(const HMAC_CTX *ctx); + +// HMAC_CTX_copy_ex sets |dest| equal to |src|. On entry, |dest| must have been +// initialised by calling |HMAC_CTX_init|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src); + +// HMAC_CTX_reset calls |HMAC_CTX_cleanup| followed by |HMAC_CTX_init|. +OPENSSL_EXPORT void HMAC_CTX_reset(HMAC_CTX *ctx); + + +// Deprecated functions. + +OPENSSL_EXPORT int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, + const EVP_MD *md); + +// HMAC_CTX_copy calls |HMAC_CTX_init| on |dest| and then sets it equal to +// |src|. On entry, |dest| must /not/ be initialised for an operation with +// |HMAC_Init_ex|. It returns one on success and zero on error. +OPENSSL_EXPORT int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src); + + +// Private functions + +struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; +} /* HMAC_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(HMAC_CTX, HMAC_CTX_free) + +using ScopedHMAC_CTX = + internal::StackAllocated; + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_HMAC_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hpke.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hpke.h new file mode 100644 index 00000000..915e961f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hpke.h @@ -0,0 +1,350 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H + +#include "CNIOBoringSSL_aead.h" +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_curve25519.h" +#include "CNIOBoringSSL_digest.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Hybrid Public Key Encryption. +// +// Hybrid Public Key Encryption (HPKE) enables a sender to encrypt messages to a +// receiver with a public key. +// +// See RFC 9180. + + +// Parameters. +// +// An HPKE context is parameterized by KEM, KDF, and AEAD algorithms, +// represented by |EVP_HPKE_KEM|, |EVP_HPKE_KDF|, and |EVP_HPKE_AEAD| types, +// respectively. + +// The following constants are KEM identifiers. +#define EVP_HPKE_DHKEM_X25519_HKDF_SHA256 0x0020 + +// The following functions are KEM algorithms which may be used with HPKE. Note +// that, while some HPKE KEMs use KDFs internally, this is separate from the +// |EVP_HPKE_KDF| selection. +OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void); + +// EVP_HPKE_KEM_id returns the HPKE KEM identifier for |kem|, which +// will be one of the |EVP_HPKE_KEM_*| constants. +OPENSSL_EXPORT uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem); + +// The following constants are KDF identifiers. +#define EVP_HPKE_HKDF_SHA256 0x0001 + +// The following functions are KDF algorithms which may be used with HPKE. +OPENSSL_EXPORT const EVP_HPKE_KDF *EVP_hpke_hkdf_sha256(void); + +// EVP_HPKE_KDF_id returns the HPKE KDF identifier for |kdf|. +OPENSSL_EXPORT uint16_t EVP_HPKE_KDF_id(const EVP_HPKE_KDF *kdf); + +// The following constants are AEAD identifiers. +#define EVP_HPKE_AES_128_GCM 0x0001 +#define EVP_HPKE_AES_256_GCM 0x0002 +#define EVP_HPKE_CHACHA20_POLY1305 0x0003 + +// The following functions are AEAD algorithms which may be used with HPKE. +OPENSSL_EXPORT const EVP_HPKE_AEAD *EVP_hpke_aes_128_gcm(void); +OPENSSL_EXPORT const EVP_HPKE_AEAD *EVP_hpke_aes_256_gcm(void); +OPENSSL_EXPORT const EVP_HPKE_AEAD *EVP_hpke_chacha20_poly1305(void); + +// EVP_HPKE_AEAD_id returns the HPKE AEAD identifier for |aead|. +OPENSSL_EXPORT uint16_t EVP_HPKE_AEAD_id(const EVP_HPKE_AEAD *aead); + +// EVP_HPKE_AEAD_aead returns the |EVP_AEAD| corresponding to |aead|. +OPENSSL_EXPORT const EVP_AEAD *EVP_HPKE_AEAD_aead(const EVP_HPKE_AEAD *aead); + + +// Recipient keys. +// +// An HPKE recipient maintains a long-term KEM key. This library represents keys +// with the |EVP_HPKE_KEY| type. + +// EVP_HPKE_KEY_zero sets an uninitialized |EVP_HPKE_KEY| to the zero state. The +// caller should then use |EVP_HPKE_KEY_init|, |EVP_HPKE_KEY_copy|, or +// |EVP_HPKE_KEY_generate| to finish initializing |key|. +// +// It is safe, but not necessary to call |EVP_HPKE_KEY_cleanup| in this state. +// This may be used for more uniform cleanup of |EVP_HPKE_KEY|. +OPENSSL_EXPORT void EVP_HPKE_KEY_zero(EVP_HPKE_KEY *key); + +// EVP_HPKE_KEY_cleanup releases memory referenced by |key|. +OPENSSL_EXPORT void EVP_HPKE_KEY_cleanup(EVP_HPKE_KEY *key); + +// EVP_HPKE_KEY_new returns a newly-allocated |EVP_HPKE_KEY|, or NULL on error. +// The caller must call |EVP_HPKE_KEY_free| on the result to release it. +// +// This is a convenience function for callers that need a heap-allocated +// |EVP_HPKE_KEY|. +OPENSSL_EXPORT EVP_HPKE_KEY *EVP_HPKE_KEY_new(void); + +// EVP_HPKE_KEY_free releases memory associated with |key|, which must have been +// created with |EVP_HPKE_KEY_new|. +OPENSSL_EXPORT void EVP_HPKE_KEY_free(EVP_HPKE_KEY *key); + +// EVP_HPKE_KEY_copy sets |dst| to a copy of |src|. It returns one on success +// and zero on error. On success, the caller must call |EVP_HPKE_KEY_cleanup| to +// release |dst|. On failure, calling |EVP_HPKE_KEY_cleanup| is safe, but not +// necessary. +OPENSSL_EXPORT int EVP_HPKE_KEY_copy(EVP_HPKE_KEY *dst, + const EVP_HPKE_KEY *src); + +// EVP_HPKE_KEY_init decodes |priv_key| as a private key for |kem| and +// initializes |key| with the result. It returns one on success and zero if +// |priv_key| was invalid. On success, the caller must call +// |EVP_HPKE_KEY_cleanup| to release the key. On failure, calling +// |EVP_HPKE_KEY_cleanup| is safe, but not necessary. +OPENSSL_EXPORT int EVP_HPKE_KEY_init(EVP_HPKE_KEY *key, const EVP_HPKE_KEM *kem, + const uint8_t *priv_key, + size_t priv_key_len); + +// EVP_HPKE_KEY_generate sets |key| to a newly-generated key using |kem|. +OPENSSL_EXPORT int EVP_HPKE_KEY_generate(EVP_HPKE_KEY *key, + const EVP_HPKE_KEM *kem); + +// EVP_HPKE_KEY_kem returns the HPKE KEM used by |key|. +OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_HPKE_KEY_kem(const EVP_HPKE_KEY *key); + +// EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of a public key for all +// KEMs supported by this library. +#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 32 + +// EVP_HPKE_KEY_public_key writes |key|'s public key to |out| and sets +// |*out_len| to the number of bytes written. On success, it returns one and +// writes at most |max_out| bytes. If |max_out| is too small, it returns zero. +// Setting |max_out| to |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH| will ensure the public +// key fits. +OPENSSL_EXPORT int EVP_HPKE_KEY_public_key(const EVP_HPKE_KEY *key, + uint8_t *out, size_t *out_len, + size_t max_out); + +// EVP_HPKE_MAX_PRIVATE_KEY_LENGTH is the maximum length of a private key for +// all KEMs supported by this library. +#define EVP_HPKE_MAX_PRIVATE_KEY_LENGTH 32 + +// EVP_HPKE_KEY_private_key writes |key|'s private key to |out| and sets +// |*out_len| to the number of bytes written. On success, it returns one and +// writes at most |max_out| bytes. If |max_out| is too small, it returns zero. +// Setting |max_out| to |EVP_HPKE_MAX_PRIVATE_KEY_LENGTH| will ensure the +// private key fits. +OPENSSL_EXPORT int EVP_HPKE_KEY_private_key(const EVP_HPKE_KEY *key, + uint8_t *out, size_t *out_len, + size_t max_out); + + +// Encryption contexts. +// +// An HPKE encryption context is represented by the |EVP_HPKE_CTX| type. + +// EVP_HPKE_CTX_zero sets an uninitialized |EVP_HPKE_CTX| to the zero state. The +// caller should then use one of the |EVP_HPKE_CTX_setup_*| functions to finish +// setting up |ctx|. +// +// It is safe, but not necessary to call |EVP_HPKE_CTX_cleanup| in this state. +// This may be used for more uniform cleanup of |EVP_HPKE_CTX|. +OPENSSL_EXPORT void EVP_HPKE_CTX_zero(EVP_HPKE_CTX *ctx); + +// EVP_HPKE_CTX_cleanup releases memory referenced by |ctx|. |ctx| must have +// been initialized with |EVP_HPKE_CTX_zero| or one of the +// |EVP_HPKE_CTX_setup_*| functions. +OPENSSL_EXPORT void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx); + +// EVP_HPKE_CTX_new returns a newly-allocated |EVP_HPKE_CTX|, or NULL on error. +// The caller must call |EVP_HPKE_CTX_free| on the result to release it. +// +// This is a convenience function for callers that need a heap-allocated +// |EVP_HPKE_CTX|. +OPENSSL_EXPORT EVP_HPKE_CTX *EVP_HPKE_CTX_new(void); + +// EVP_HPKE_CTX_free releases memory associated with |ctx|, which must have been +// created with |EVP_HPKE_CTX_new|. +OPENSSL_EXPORT void EVP_HPKE_CTX_free(EVP_HPKE_CTX *ctx); + +// EVP_HPKE_MAX_ENC_LENGTH is the maximum length of "enc", the encapsulated +// shared secret, for all supported KEMs in this library. +#define EVP_HPKE_MAX_ENC_LENGTH 32 + +// EVP_HPKE_CTX_setup_sender implements the SetupBaseS HPKE operation. It +// encapsulates a shared secret for |peer_public_key| and sets up |ctx| as a +// sender context. It writes the encapsulated shared secret to |out_enc| and +// sets |*out_enc_len| to the number of bytes written. It writes at most +// |max_enc| bytes and fails if the buffer is too small. Setting |max_enc| to at +// least |EVP_HPKE_MAX_ENC_LENGTH| will ensure the buffer is large enough. +// +// This function returns one on success and zero on error. Note that +// |peer_public_key| may be invalid, in which case this function will return an +// error. +// +// On success, callers may call |EVP_HPKE_CTX_seal| to encrypt messages for the +// recipient. Callers must then call |EVP_HPKE_CTX_cleanup| when done. On +// failure, calling |EVP_HPKE_CTX_cleanup| is safe, but not required. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_sender( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len); + +// EVP_HPKE_CTX_setup_sender_with_seed_for_testing behaves like +// |EVP_HPKE_CTX_setup_sender|, but takes a seed to behave deterministically. +// The seed's format depends on |kem|. For X25519, it is the sender's +// ephemeral private key. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_sender_with_seed_for_testing( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEM *kem, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len, const uint8_t *seed, size_t seed_len); + +// EVP_HPKE_CTX_setup_recipient implements the SetupBaseR HPKE operation. It +// decapsulates the shared secret in |enc| with |key| and sets up |ctx| as a +// recipient context. It returns one on success and zero on failure. Note that +// |enc| may be invalid, in which case this function will return an error. +// +// On success, callers may call |EVP_HPKE_CTX_open| to decrypt messages from the +// sender. Callers must then call |EVP_HPKE_CTX_cleanup| when done. On failure, +// calling |EVP_HPKE_CTX_cleanup| is safe, but not required. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_recipient( + EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, + const EVP_HPKE_AEAD *aead, const uint8_t *enc, size_t enc_len, + const uint8_t *info, size_t info_len); + + +// Using an HPKE context. +// +// Once set up, callers may encrypt or decrypt with an |EVP_HPKE_CTX| using the +// following functions. + +// EVP_HPKE_CTX_open uses the HPKE context |ctx| to authenticate |in_len| bytes +// from |in| and |ad_len| bytes from |ad| and to decrypt at most |in_len| bytes +// into |out|. It returns one on success, and zero otherwise. +// +// This operation will fail if the |ctx| context is not set up as a receiver. +// +// Note that HPKE encryption is stateful and ordered. The sender's first call to +// |EVP_HPKE_CTX_seal| must correspond to the recipient's first call to +// |EVP_HPKE_CTX_open|, etc. +// +// At most |in_len| bytes are written to |out|. In order to ensure success, +// |max_out_len| should be at least |in_len|. On successful return, |*out_len| +// is set to the actual number of bytes written. +OPENSSL_EXPORT int EVP_HPKE_CTX_open(EVP_HPKE_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_HPKE_CTX_seal uses the HPKE context |ctx| to encrypt and authenticate +// |in_len| bytes of ciphertext |in| and authenticate |ad_len| bytes from |ad|, +// writing the result to |out|. It returns one on success and zero otherwise. +// +// This operation will fail if the |ctx| context is not set up as a sender. +// +// Note that HPKE encryption is stateful and ordered. The sender's first call to +// |EVP_HPKE_CTX_seal| must correspond to the recipient's first call to +// |EVP_HPKE_CTX_open|, etc. +// +// At most, |max_out_len| encrypted bytes are written to |out|. On successful +// return, |*out_len| is set to the actual number of bytes written. +// +// To ensure success, |max_out_len| should be |in_len| plus the result of +// |EVP_HPKE_CTX_max_overhead| or |EVP_HPKE_MAX_OVERHEAD|. +OPENSSL_EXPORT int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_HPKE_CTX_export uses the HPKE context |ctx| to export a secret of +// |secret_len| bytes into |out|. This function uses |context_len| bytes from +// |context| as a context string for the secret. This is necessary to separate +// different uses of exported secrets and bind relevant caller-specific context +// into the output. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *ctx, uint8_t *out, + size_t secret_len, + const uint8_t *context, + size_t context_len); + +// EVP_HPKE_MAX_OVERHEAD contains the largest value that +// |EVP_HPKE_CTX_max_overhead| would ever return for any context. +#define EVP_HPKE_MAX_OVERHEAD EVP_AEAD_MAX_OVERHEAD + +// EVP_HPKE_CTX_max_overhead returns the maximum number of additional bytes +// added by sealing data with |EVP_HPKE_CTX_seal|. The |ctx| context must be set +// up as a sender. +OPENSSL_EXPORT size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *ctx); + +// EVP_HPKE_CTX_aead returns |ctx|'s configured AEAD, or NULL if the context has +// not been set up. +OPENSSL_EXPORT const EVP_HPKE_AEAD *EVP_HPKE_CTX_aead(const EVP_HPKE_CTX *ctx); + +// EVP_HPKE_CTX_kdf returns |ctx|'s configured KDF, or NULL if the context has +// not been set up. +OPENSSL_EXPORT const EVP_HPKE_KDF *EVP_HPKE_CTX_kdf(const EVP_HPKE_CTX *ctx); + + +// Private structures. +// +// The following structures are exported so their types are stack-allocatable, +// but accessing or modifying their fields is forbidden. + +struct evp_hpke_ctx_st { + const EVP_HPKE_AEAD *aead; + const EVP_HPKE_KDF *kdf; + EVP_AEAD_CTX aead_ctx; + uint8_t base_nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + uint8_t exporter_secret[EVP_MAX_MD_SIZE]; + uint64_t seq; + int is_sender; +}; + +struct evp_hpke_key_st { + const EVP_HPKE_KEM *kem; + uint8_t private_key[X25519_PRIVATE_KEY_LEN]; + uint8_t public_key[X25519_PUBLIC_VALUE_LEN]; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +using ScopedEVP_HPKE_CTX = + internal::StackAllocated; +using ScopedEVP_HPKE_KEY = + internal::StackAllocated; + +BORINGSSL_MAKE_DELETER(EVP_HPKE_CTX, EVP_HPKE_CTX_free) +BORINGSSL_MAKE_DELETER(EVP_HPKE_KEY, EVP_HPKE_KEY_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hrss.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hrss.h new file mode 100644 index 00000000..ce92ad90 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_hrss.h @@ -0,0 +1,102 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HRSS_H +#define OPENSSL_HEADER_HRSS_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +// HRSS +// +// HRSS is a structured-lattice-based post-quantum key encapsulation mechanism. +// The best exposition is https://eprint.iacr.org/2017/667.pdf although this +// implementation uses a different KEM construction based on +// https://eprint.iacr.org/2017/1005.pdf. + +struct HRSS_private_key { + uint8_t opaque[1808]; +}; + +struct HRSS_public_key { + uint8_t opaque[1424]; +}; + +// HRSS_SAMPLE_BYTES is the number of bytes of entropy needed to generate a +// short vector. There are 701 coefficients, but the final one is always set to +// zero when sampling. Otherwise, we need one byte of input per coefficient. +#define HRSS_SAMPLE_BYTES (701 - 1) +// HRSS_GENERATE_KEY_BYTES is the number of bytes of entropy needed to generate +// an HRSS key pair. +#define HRSS_GENERATE_KEY_BYTES (HRSS_SAMPLE_BYTES + HRSS_SAMPLE_BYTES + 32) +// HRSS_ENCAP_BYTES is the number of bytes of entropy needed to encapsulate a +// session key. +#define HRSS_ENCAP_BYTES (HRSS_SAMPLE_BYTES + HRSS_SAMPLE_BYTES) +// HRSS_PUBLIC_KEY_BYTES is the number of bytes in a public key. +#define HRSS_PUBLIC_KEY_BYTES 1138 +// HRSS_CIPHERTEXT_BYTES is the number of bytes in a ciphertext. +#define HRSS_CIPHERTEXT_BYTES 1138 +// HRSS_KEY_BYTES is the number of bytes in a shared key. +#define HRSS_KEY_BYTES 32 +// HRSS_POLY3_BYTES is the number of bytes needed to serialise a mod 3 +// polynomial. +#define HRSS_POLY3_BYTES 140 +#define HRSS_PRIVATE_KEY_BYTES \ + (HRSS_POLY3_BYTES * 2 + HRSS_PUBLIC_KEY_BYTES + 2 + 32) + +// HRSS_generate_key is a deterministic function that outputs a public and +// private key based on the given entropy. It returns one on success or zero +// on malloc failure. +OPENSSL_EXPORT int HRSS_generate_key( + struct HRSS_public_key *out_pub, struct HRSS_private_key *out_priv, + const uint8_t input[HRSS_GENERATE_KEY_BYTES]); + +// HRSS_encap is a deterministic function the generates and encrypts a random +// session key from the given entropy, writing those values to |out_shared_key| +// and |out_ciphertext|, respectively. It returns one on success or zero on +// malloc failure. +OPENSSL_EXPORT int HRSS_encap(uint8_t out_ciphertext[HRSS_CIPHERTEXT_BYTES], + uint8_t out_shared_key[HRSS_KEY_BYTES], + const struct HRSS_public_key *in_pub, + const uint8_t in[HRSS_ENCAP_BYTES]); + +// HRSS_decap decrypts a session key from |ciphertext_len| bytes of +// |ciphertext|. If the ciphertext is valid, the decrypted key is written to +// |out_shared_key|. Otherwise the HMAC of |ciphertext| under a secret key (kept +// in |in_priv|) is written. If the ciphertext is the wrong length then it will +// leak which was done via side-channels. Otherwise it should perform either +// action in constant-time. It returns one on success (whether the ciphertext +// was valid or not) and zero on malloc failure. +OPENSSL_EXPORT int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], + const struct HRSS_private_key *in_priv, + const uint8_t *ciphertext, size_t ciphertext_len); + +// HRSS_marshal_public_key serialises |in_pub| to |out|. +OPENSSL_EXPORT void HRSS_marshal_public_key( + uint8_t out[HRSS_PUBLIC_KEY_BYTES], const struct HRSS_public_key *in_pub); + +// HRSS_parse_public_key sets |*out| to the public-key encoded in |in|. It +// returns true on success and zero on error. +OPENSSL_EXPORT int HRSS_parse_public_key( + struct HRSS_public_key *out, const uint8_t in[HRSS_PUBLIC_KEY_BYTES]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_HRSS_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_is_boringssl.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_is_boringssl.h new file mode 100644 index 00000000..302cbe29 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_is_boringssl.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This header is provided in order to catch include path errors in consuming +// BoringSSL. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_lhash.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_lhash.h new file mode 100644 index 00000000..665afef7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_lhash.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_LHASH_H +#define OPENSSL_HEADER_LHASH_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// lhash is an internal library and not exported for use outside BoringSSL. This +// header is provided for compatibility with code that expects OpenSSL. + + +// These two macros are exported for compatibility with existing callers of +// |X509V3_EXT_conf_nid|. Do not use these symbols outside BoringSSL. +#define LHASH_OF(type) struct lhash_st_##type +#define DECLARE_LHASH_OF(type) LHASH_OF(type); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_LHASH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md4.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md4.h new file mode 100644 index 00000000..d6fd7a80 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md4.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_MD4_H +#define OPENSSL_HEADER_MD4_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD4. + +// MD4_CBLOCK is the block size of MD4. +#define MD4_CBLOCK 64 + +// MD4_DIGEST_LENGTH is the length of an MD4 digest. +#define MD4_DIGEST_LENGTH 16 + +// MD4_Init initialises |md4| and returns one. +OPENSSL_EXPORT int MD4_Init(MD4_CTX *md4); + +// MD4_Update adds |len| bytes from |data| to |md4| and returns one. +OPENSSL_EXPORT int MD4_Update(MD4_CTX *md4, const void *data, size_t len); + +// MD4_Final adds the final padding to |md4| and writes the resulting digest to +// |out|, which must have at least |MD4_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD4_Final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *md4); + +// MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, + uint8_t out[MD4_DIGEST_LENGTH]); + +// MD4_Transform is a low-level function that performs a single, MD4 block +// transformation using the state from |md4| and 64 bytes from |block|. +OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, + const uint8_t block[MD4_CBLOCK]); + +struct md4_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD4_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD4_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md5.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md5.h new file mode 100644 index 00000000..ed074cf7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_md5.h @@ -0,0 +1,109 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_MD5_H +#define OPENSSL_HEADER_MD5_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD5. + + +// MD5_CBLOCK is the block size of MD5. +#define MD5_CBLOCK 64 + +// MD5_DIGEST_LENGTH is the length of an MD5 digest. +#define MD5_DIGEST_LENGTH 16 + +// MD5_Init initialises |md5| and returns one. +OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5); + +// MD5_Update adds |len| bytes from |data| to |md5| and returns one. +OPENSSL_EXPORT int MD5_Update(MD5_CTX *md5, const void *data, size_t len); + +// MD5_Final adds the final padding to |md5| and writes the resulting digest to +// |out|, which must have at least |MD5_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD5_Final(uint8_t out[MD5_DIGEST_LENGTH], MD5_CTX *md5); + +// MD5 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD5_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD5(const uint8_t *data, size_t len, + uint8_t out[MD5_DIGEST_LENGTH]); + +// MD5_Transform is a low-level function that performs a single, MD5 block +// transformation using the state from |md5| and 64 bytes from |block|. +OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, + const uint8_t block[MD5_CBLOCK]); + +struct md5_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD5_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD5_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h new file mode 100644 index 00000000..90cb26cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h @@ -0,0 +1,184 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_MEM_H +#define OPENSSL_HEADER_MEM_H + +#include "CNIOBoringSSL_base.h" + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also buf.h. +// +// BoringSSL has its own set of allocation functions, which keep track of +// allocation lengths and zero them out before freeing. All memory returned by +// BoringSSL API calls must therefore generally be freed using |OPENSSL_free| +// unless stated otherwise. + + +// OPENSSL_malloc acts like a regular |malloc|. +OPENSSL_EXPORT void *OPENSSL_malloc(size_t size); + +// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the +// memory allocated at |ptr| and frees it. +OPENSSL_EXPORT void OPENSSL_free(void *ptr); + +// OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that +// contains the contents of |ptr|. Unlike |realloc|, a new buffer is always +// allocated and the data at |ptr| is always wiped and freed. +OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size); + +// OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to +// |memset_s| from C11. +OPENSSL_EXPORT void OPENSSL_cleanse(void *ptr, size_t len); + +// CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It +// takes an amount of time dependent on |len|, but independent of the contents +// of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a +// defined order as the return value when a != b is undefined, other than to be +// non-zero. +OPENSSL_EXPORT int CRYPTO_memcmp(const void *a, const void *b, size_t len); + +// OPENSSL_hash32 implements the 32 bit, FNV-1a hash. +OPENSSL_EXPORT uint32_t OPENSSL_hash32(const void *ptr, size_t len); + +// OPENSSL_strhash calls |OPENSSL_hash32| on the NUL-terminated string |s|. +OPENSSL_EXPORT uint32_t OPENSSL_strhash(const char *s); + +// OPENSSL_strdup has the same behaviour as strdup(3). +OPENSSL_EXPORT char *OPENSSL_strdup(const char *s); + +// OPENSSL_strnlen has the same behaviour as strnlen(3). +OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len); + +// OPENSSL_tolower is a locale-independent version of tolower(3). +OPENSSL_EXPORT int OPENSSL_tolower(int c); + +// OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). +OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b); + +// OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). +OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n); + +// DECIMAL_SIZE returns an upper bound for the length of the decimal +// representation of the given type. +#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) + +// BIO_snprintf has the same behavior as snprintf(3). +OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(3, 4); + +// BIO_vsnprintf has the same behavior as vsnprintf(3). +OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format, + va_list args) OPENSSL_PRINTF_FORMAT_FUNC(3, 0); + +// OPENSSL_strndup returns an allocated, duplicate of |str|, which is, at most, +// |size| bytes. The result is always NUL terminated. +OPENSSL_EXPORT char *OPENSSL_strndup(const char *str, size_t size); + +// OPENSSL_memdup returns an allocated, duplicate of |size| bytes from |data| or +// NULL on allocation failure. +OPENSSL_EXPORT void *OPENSSL_memdup(const void *data, size_t size); + +// OPENSSL_strlcpy acts like strlcpy(3). +OPENSSL_EXPORT size_t OPENSSL_strlcpy(char *dst, const char *src, + size_t dst_size); + +// OPENSSL_strlcat acts like strlcat(3). +OPENSSL_EXPORT size_t OPENSSL_strlcat(char *dst, const char *src, + size_t dst_size); + + +// Deprecated functions. + +// CRYPTO_malloc calls |OPENSSL_malloc|. |file| and |line| are ignored. +OPENSSL_EXPORT void *CRYPTO_malloc(size_t size, const char *file, int line); + +// CRYPTO_realloc calls |OPENSSL_realloc|. |file| and |line| are ignored. +OPENSSL_EXPORT void *CRYPTO_realloc(void *ptr, size_t new_size, + const char *file, int line); + +// CRYPTO_free calls |OPENSSL_free|. |file| and |line| are ignored. +OPENSSL_EXPORT void CRYPTO_free(void *ptr, const char *file, int line); + +// OPENSSL_clear_free calls |OPENSSL_free|. BoringSSL automatically clears all +// allocations on free, but we define |OPENSSL_clear_free| for compatibility. +OPENSSL_EXPORT void OPENSSL_clear_free(void *ptr, size_t len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(char, OPENSSL_free) +BORINGSSL_MAKE_DELETER(uint8_t, OPENSSL_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_MEM_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h new file mode 100644 index 00000000..b6f8eb12 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h @@ -0,0 +1,4259 @@ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +/* This file is generated by crypto/obj/objects.go. */ + +#ifndef OPENSSL_HEADER_NID_H +#define OPENSSL_HEADER_NID_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* The nid library provides numbered values for ASN.1 object identifiers and + * other symbols. These values are used by other libraries to identify + * cryptographic primitives. + * + * A separate objects library, obj.h, provides functions for converting between + * nids and object identifiers. However it depends on large internal tables with + * the encodings of every nid defined. Consumers concerned with binary size + * should instead embed the encodings of the few consumed OIDs and compare + * against those. + * + * These values should not be used outside of a single process; they are not + * stable identifiers. */ + + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi 1L, 2L, 840L, 113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs 1L, 2L, 840L, 113549L, 1L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 1L, 2L, 840L, 113549L, 2L, 2L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 1L, 2L, 840L, 113549L, 2L, 5L + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 1L, 2L, 840L, 113549L, 3L, 4L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 2L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 4L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 3L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L, 5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 2L, 5L, 4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName 2L, 5L, 4L, 3L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName 2L, 5L, 4L, 6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName 2L, 5L, 4L, 7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName 2L, 5L, 4L, 8L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName 2L, 5L, 4L, 10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName 2L, 5L, 4L, 11L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa 2L, 5L, 8L, 1L, 1L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 1L, 2L, 840L, 113549L, 1L, 7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data 1L, 2L, 840L, 113549L, 1L, 7L, 1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed 1L, 2L, 840L, 113549L, 1L, 7L, 2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped 1L, 2L, 840L, 113549L, 1L, 7L, 3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped 1L, 2L, 840L, 113549L, 1L, 7L, 4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest 1L, 2L, 840L, 113549L, 1L, 7L, 5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted 1L, 2L, 840L, 113549L, 1L, 7L, 6L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 1L, 2L, 840L, 113549L, 1L, 3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement 1L, 2L, 840L, 113549L, 1L, 3L, 1L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb 1L, 3L, 14L, 3L, 2L, 6L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 1L, 3L, 14L, 3L, 2L, 9L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc 1L, 3L, 14L, 3L, 2L, 7L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb 1L, 3L, 14L, 3L, 2L, 17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L, 3L, 6L, 1L, 4L, 1L, 188L, 7L, 1L, 1L, 2L + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc 1L, 2L, 840L, 113549L, 3L, 2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha 1L, 3L, 14L, 3L, 2L, 18L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption 1L, 3L, 14L, 3L, 2L, 15L + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc 1L, 2L, 840L, 113549L, 3L, 7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 1L, 3L, 14L, 3L, 2L, 8L + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 1L, 2L, 840L, 113549L, 1L, 9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress 1L, 2L, 840L, 113549L, 1L, 9L, 1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName 1L, 2L, 840L, 113549L, 1L, 9L, 2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType 1L, 2L, 840L, 113549L, 1L, 9L, 3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest 1L, 2L, 840L, 113549L, 1L, 9L, 4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime 1L, 2L, 840L, 113549L, 1L, 9L, 5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature 1L, 2L, 840L, 113549L, 1L, 9L, 6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword 1L, 2L, 840L, 113549L, 1L, 9L, 7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress 1L, 2L, 840L, 113549L, 1L, 9L, 8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes 1L, 2L, 840L, 113549L, 1L, 9L, 9L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L, 16L, 840L, 1L, 113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension 2L, 16L, 840L, 1L, 113730L, 1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type 2L, 16L, 840L, 1L, 113730L, 2L + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 1L, 3L, 14L, 3L, 2L, 26L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 5L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA 1L, 3L, 14L, 3L, 2L, 13L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 1L, 3L, 14L, 3L, 2L, 12L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 1L, 2L, 840L, 113549L, 1L, 5L, 12L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 1L, 3L, 14L, 3L, 2L, 27L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type 2L, 16L, 840L, 1L, 113730L, 1L, 1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url 2L, 16L, 840L, 1L, 113730L, 1L, 2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url 2L, 16L, 840L, 1L, 113730L, 1L, 3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url 2L, 16L, 840L, 1L, 113730L, 1L, 4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url 2L, 16L, 840L, 1L, 113730L, 1L, 7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url 2L, 16L, 840L, 1L, 113730L, 1L, 8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name 2L, 16L, 840L, 1L, 113730L, 1L, 12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment 2L, 16L, 840L, 1L, 113730L, 1L, 13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence 2L, 16L, 840L, 1L, 113730L, 2L, 5L + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce 2L, 5L, 29L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier 2L, 5L, 29L, 14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage 2L, 5L, 29L, 15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period 2L, 5L, 29L, 16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name 2L, 5L, 29L, 17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name 2L, 5L, 29L, 18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints 2L, 5L, 29L, 19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number 2L, 5L, 29L, 20L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies 2L, 5L, 29L, 32L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier 2L, 5L, 29L, 35L + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L, 3L, 6L, 1L, 4L, 1L, 3029L, 1L, 2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 2L, 5L, 8L, 3L, 101L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA 2L, 5L, 8L, 3L, 100L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName 2L, 5L, 4L, 42L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname 2L, 5L, 4L, 4L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials 2L, 5L, 4L, 43L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points 2L, 5L, 29L, 31L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA 1L, 3L, 14L, 3L, 2L, 3L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber 2L, 5L, 4L, 5L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title 2L, 5L, 4L, 12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description 2L, 5L, 4L, 13L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc 1L, 2L, 840L, 113533L, 7L, 66L, 10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC 1L, 2L, 840L, 113533L, 7L, 66L, 12L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 1L, 2L, 840L, 10040L, 4L, 3L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA 1L, 3L, 14L, 3L, 2L, 29L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa 1L, 2L, 840L, 10040L, 4L, 1L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L, 3L, 36L, 3L, 2L, 1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L, 3L, 36L, 3L, 3L, 1L, 2L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc 1L, 2L, 840L, 113549L, 3L, 8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 8L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage 2L, 5L, 29L, 37L + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L, 3L, 6L, 1L, 5L, 5L, 7L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 4L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 8L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L, 3L, 6L, 1L, 4L, 1L, 311L, 2L, 1L, 21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L, 3L, 6L, 1L, 4L, 1L, 311L, 2L, 1L, 22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L, 3L, 6L, 1L, 4L, 1L, 311L, 10L, 3L, 1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L, 3L, 6L, 1L, 4L, 1L, 311L, 10L, 3L, 3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L, 3L, 6L, 1L, 4L, 1L, 311L, 10L, 3L, 4L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc 2L, 16L, 840L, 1L, 113730L, 4L, 1L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl 2L, 5L, 29L, 27L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason 2L, 5L, 29L, 21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date 2L, 5L, 29L, 24L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L, 3L, 101L, 1L, 4L, 1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 6L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName 1L, 2L, 840L, 113549L, 1L, 9L, 20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID 1L, 2L, 840L, 113549L, 1L, 9L, 21L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 2L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl 1L, 2L, 840L, 113549L, 1L, 9L, 23L, 1L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 1L, 2L, 840L, 113549L, 1L, 5L, 13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 1L, 2L, 840L, 113549L, 1L, 5L, 14L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 1L, 2L, 840L, 113549L, 2L, 7L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 2L + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities 1L, 2L, 840L, 113549L, 1L, 9L, 15L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 10L + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L, 3L, 6L, 1L, 4L, 1L, 311L, 2L, 1L, 14L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req 1L, 2L, 840L, 113549L, 1L, 9L, 14L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name 2L, 5L, 4L, 41L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier 2L, 5L, 4L, 46L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 2L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 9L + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body 1L, 2L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US 1L, 2L, 840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 1L, 2L, 840L, 10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm 1L, 2L, 840L, 10040L, 4L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 1L, 2L, 840L, 113549L, 1L, 1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 1L, 2L, 840L, 113549L, 1L, 5L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME 1L, 2L, 840L, 113549L, 1L, 9L, 16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 8L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 7L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L, 1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 6L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 1L, 2L, 840L, 113549L, 2L, 4L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 16L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 9L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 3L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 7L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 15L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 1L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 5L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L, 1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 3L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 4L + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses \ + 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L, 3L, 14L, 3L, 2L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature 1L, 3L, 14L, 3L, 2L, 11L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms 2L, 5L, 8L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org 1L, 3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod 1L, 3L, 6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana 1L, 3L, 6L, 1L + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory 1L, 3L, 6L, 1L, 1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management 1L, 3L, 6L, 1L, 2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental 1L, 3L, 6L, 1L, 3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private 1L, 3L, 6L, 1L, 4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security 1L, 3L, 6L, 1L, 5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 1L, 3L, 6L, 1L, 6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail 1L, 3L, 6L, 1L, 7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises 1L, 3L, 6L, 1L, 4L, 1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject 1L, 3L, 6L, 1L, 4L, 1L, 1466L, 344L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent 0L, 9L, 2342L, 19200300L, 100L, 1L, 25L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain 0L, 9L, 2342L, 19200300L, 100L, 4L, 13L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types 2L, 5L, 1L, 5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance 2L, 5L, 1L, 5L, 55L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 3L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 6L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role 2L, 5L, 4L, 72L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints 2L, 5L, 29L, 36L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information 2L, 5L, 29L, 55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail 2L, 5L, 29L, 56L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 1L, 2L, 840L, 10045L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field 1L, 2L, 840L, 10045L, 1L, 1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field 1L, 2L, 840L, 10045L, 1L, 2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey 1L, 2L, 840L, 10045L, 2L, 1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 1L, 2L, 840L, 10045L, 3L, 1L, 1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 1L, 2L, 840L, 10045L, 3L, 1L, 2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 1L, 2L, 840L, 10045L, 3L, 1L, 3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 1L, 2L, 840L, 10045L, 3L, 1L, 4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 1L, 2L, 840L, 10045L, 3L, 1L, 5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 1L, 2L, 840L, 10045L, 3L, 1L, 6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 1L, 2L, 840L, 10045L, 3L, 1L, 7L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 1L, 2L, 840L, 10045L, 4L, 1L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L, 3L, 6L, 1L, 4L, 1L, 311L, 17L, 1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 4L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 24L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 44L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code 2L, 5L, 29L, 23L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none 1L, 2L, 840L, 10040L, 2L, 1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer 1L, 2L, 840L, 10040L, 2L, 2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject 1L, 2L, 840L, 10040L, 2L, 3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data 0L, 9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss 0L, 9L, 2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl 0L, 9L, 2342L, 19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot 0L, 9L, 2342L, 19200300L, 100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType 0L, 9L, 2342L, 19200300L, 100L, 1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass 0L, 9L, 2342L, 19200300L, 100L, 4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups 0L, 9L, 2342L, 19200300L, 100L, 10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson 0L, 9L, 2342L, 19200300L, 100L, 4L, 4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account 0L, 9L, 2342L, 19200300L, 100L, 4L, 5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document 0L, 9L, 2342L, 19200300L, 100L, 4L, 6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room 0L, 9L, 2342L, 19200300L, 100L, 4L, 7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries 0L, 9L, 2342L, 19200300L, 100L, 4L, 9L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart 0L, 9L, 2342L, 19200300L, 100L, 4L, 14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain 0L, 9L, 2342L, 19200300L, 100L, 4L, 15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry 0L, 9L, 2342L, 19200300L, 100L, 4L, 18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization 0L, 9L, 2342L, 19200300L, 100L, 4L, 20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA 0L, 9L, 2342L, 19200300L, 100L, 4L, 21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData 0L, 9L, 2342L, 19200300L, 100L, 4L, 22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId 0L, 9L, 2342L, 19200300L, 100L, 1L, 1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info 0L, 9L, 2342L, 19200300L, 100L, 1L, 4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink 0L, 9L, 2342L, 19200300L, 100L, 1L, 5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo 0L, 9L, 2342L, 19200300L, 100L, 1L, 7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass 0L, 9L, 2342L, 19200300L, 100L, 1L, 8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host 0L, 9L, 2342L, 19200300L, 100L, 1L, 9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager 0L, 9L, 2342L, 19200300L, 100L, 1L, 10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier 0L, 9L, 2342L, 19200300L, 100L, 1L, 11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion 0L, 9L, 2342L, 19200300L, 100L, 1L, 13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor 0L, 9L, 2342L, 19200300L, 100L, 1L, 14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation 0L, 9L, 2342L, 19200300L, 100L, 1L, 15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary 0L, 9L, 2342L, 19200300L, 100L, 1L, 21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime 0L, 9L, 2342L, 19200300L, 100L, 1L, 23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy 0L, 9L, 2342L, 19200300L, 100L, 1L, 24L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 0L, 9L, 2342L, 19200300L, 100L, 1L, 27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain 0L, 9L, 2342L, 19200300L, 100L, 1L, 37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName 0L, 9L, 2342L, 19200300L, 100L, 1L, 38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName 0L, 9L, 2342L, 19200300L, 100L, 1L, 43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus 0L, 9L, 2342L, 19200300L, 100L, 1L, 45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption 0L, 9L, 2342L, 19200300L, 100L, 1L, 47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName 0L, 9L, 2342L, 19200300L, 100L, 1L, 48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature 0L, 9L, 2342L, 19200300L, 100L, 1L, 53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect 0L, 9L, 2342L, 19200300L, 100L, 1L, 54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio 0L, 9L, 2342L, 19200300L, 100L, 1L, 55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher 0L, 9L, 2342L, 19200300L, 100L, 1L, 56L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier 2L, 5L, 4L, 45L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs 1L, 3L, 6L, 1L, 7L, 1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings 1L, 3L, 6L, 1L, 7L, 1L, 1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies 1L, 3L, 6L, 1L, 7L, 1L, 2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message 1L, 3L, 6L, 1L, 7L, 1L, 1L, 1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message 1L, 3L, 6L, 1L, 7L, 1L, 1L, 2L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier 2L, 5L, 4L, 44L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym 2L, 5L, 4L, 65L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set 2L, 23L, 42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype 2L, 23L, 42L, 0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt 2L, 23L, 42L, 1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr 2L, 23L, 42L, 3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy 2L, 23L, 42L, 5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt 2L, 23L, 42L, 7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand 2L, 23L, 42L, 8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData 2L, 23L, 42L, 0L, 0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken 2L, 23L, 42L, 0L, 1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly 2L, 23L, 42L, 0L, 2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData 2L, 23L, 42L, 0L, 3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI 2L, 23L, 42L, 0L, 4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData 2L, 23L, 42L, 0L, 5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned 2L, 23L, 42L, 0L, 6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput 2L, 23L, 42L, 0L, 7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage 2L, 23L, 42L, 0L, 8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage 2L, 23L, 42L, 0L, 9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage 2L, 23L, 42L, 0L, 10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq 2L, 23L, 42L, 0L, 11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData 2L, 23L, 42L, 0L, 12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS 2L, 23L, 42L, 0L, 13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData 2L, 23L, 42L, 0L, 14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS 2L, 23L, 42L, 0L, 16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS 2L, 23L, 42L, 0L, 17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX 2L, 23L, 42L, 0L, 18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS 2L, 23L, 42L, 0L, 19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData 2L, 23L, 42L, 0L, 20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS 2L, 23L, 42L, 0L, 21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg 2L, 23L, 42L, 0L, 22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS 2L, 23L, 42L, 0L, 23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData 2L, 23L, 42L, 0L, 24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS 2L, 23L, 42L, 0L, 25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS 2L, 23L, 42L, 0L, 26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX 2L, 23L, 42L, 0L, 27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData 2L, 23L, 42L, 0L, 28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS 2L, 23L, 42L, 0L, 29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX 2L, 23L, 42L, 0L, 30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData 2L, 23L, 42L, 0L, 31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS 2L, 23L, 42L, 0L, 32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX 2L, 23L, 42L, 0L, 33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData 2L, 23L, 42L, 0L, 34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS 2L, 23L, 42L, 0L, 35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX 2L, 23L, 42L, 0L, 36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData 2L, 23L, 42L, 0L, 37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData 2L, 23L, 42L, 0L, 38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS 2L, 23L, 42L, 0L, 39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData 2L, 23L, 42L, 0L, 40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData 2L, 23L, 42L, 0L, 41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS 2L, 23L, 42L, 0L, 42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS 2L, 23L, 42L, 0L, 43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS 2L, 23L, 42L, 0L, 44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData 2L, 23L, 42L, 0L, 45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS 2L, 23L, 42L, 0L, 46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData 2L, 23L, 42L, 0L, 47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS 2L, 23L, 42L, 0L, 48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS 2L, 23L, 42L, 0L, 49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE 2L, 23L, 42L, 0L, 50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE 2L, 23L, 42L, 0L, 51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE 2L, 23L, 42L, 0L, 52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE 2L, 23L, 42L, 0L, 53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX 2L, 23L, 42L, 0L, 54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE 2L, 23L, 42L, 0L, 55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE 2L, 23L, 42L, 0L, 56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX 2L, 23L, 42L, 0L, 57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE 2L, 23L, 42L, 0L, 58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE 2L, 23L, 42L, 0L, 59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE 2L, 23L, 42L, 0L, 60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB 2L, 23L, 42L, 0L, 61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE 2L, 23L, 42L, 0L, 62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX 2L, 23L, 42L, 0L, 63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE 2L, 23L, 42L, 0L, 64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE 2L, 23L, 42L, 0L, 65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX 2L, 23L, 42L, 0L, 66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE 2L, 23L, 42L, 0L, 67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE 2L, 23L, 42L, 0L, 68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX 2L, 23L, 42L, 0L, 69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE 2L, 23L, 42L, 0L, 70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE 2L, 23L, 42L, 0L, 71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX 2L, 23L, 42L, 0L, 72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE 2L, 23L, 42L, 0L, 73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE 2L, 23L, 42L, 0L, 74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE 2L, 23L, 42L, 0L, 75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE 2L, 23L, 42L, 0L, 76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE 2L, 23L, 42L, 0L, 77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX 2L, 23L, 42L, 0L, 78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE 2L, 23L, 42L, 0L, 79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS 2L, 23L, 42L, 0L, 80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS 2L, 23L, 42L, 0L, 81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS 2L, 23L, 42L, 0L, 82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt 2L, 23L, 42L, 1L, 1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth 2L, 23L, 42L, 1L, 3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure 2L, 23L, 42L, 1L, 4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny 2L, 23L, 42L, 1L, 5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 2L, 23L, 42L, 1L, 7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv 2L, 23L, 42L, 1L, 8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root 2L, 23L, 42L, 5L, 0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot 2L, 23L, 42L, 7L, 0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType 2L, 23L, 42L, 7L, 1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData 2L, 23L, 42L, 7L, 2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired 2L, 23L, 42L, 7L, 3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling 2L, 23L, 42L, 7L, 4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt 2L, 23L, 42L, 7L, 5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf 2L, 23L, 42L, 7L, 6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities 2L, 23L, 42L, 7L, 7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier 2L, 23L, 42L, 7L, 8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data 2L, 23L, 42L, 7L, 9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType 2L, 23L, 42L, 7L, 10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities 2L, 23L, 42L, 7L, 11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert 2L, 23L, 42L, 3L, 0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap 2L, 23L, 42L, 3L, 1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType 2L, 23L, 42L, 3L, 2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap 2L, 23L, 42L, 3L, 3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb 2L, 23L, 42L, 3L, 0L, 0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy 2L, 23L, 42L, 3L, 0L, 1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV 2L, 23L, 42L, 3L, 2L, 1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime 2L, 23L, 42L, 3L, 2L, 2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM 2L, 23L, 42L, 3L, 3L, 3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 2L, 23L, 42L, 3L, 3L, 4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig 2L, 23L, 42L, 3L, 3L, 5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm 2L, 23L, 42L, 3L, 3L, 3L, 1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc 2L, 23L, 42L, 3L, 3L, 4L, 1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt 2L, 23L, 42L, 3L, 3L, 4L, 2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig 2L, 23L, 42L, 3L, 3L, 5L, 1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig 2L, 23L, 42L, 3L, 3L, 5L, 2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA 2L, 23L, 42L, 8L, 1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners 2L, 23L, 42L, 8L, 30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress 2L, 23L, 42L, 8L, 34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB 2L, 23L, 42L, 8L, 35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa 2L, 23L, 42L, 8L, 4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard 2L, 23L, 42L, 8L, 5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus 2L, 23L, 42L, 8L, 6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf 1L, 2L, 840L, 113549L, 3L, 10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET 1L, 2L, 840L, 113549L, 1L, 1L, 6L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations 2L, 23L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L, 3L, 6L, 1L, 4L, 1L, 311L, 20L, 2L, 2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L, 3L, 6L, 1L, 4L, 1L, 311L, 20L, 2L, 3L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress 2L, 5L, 4L, 9L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode 2L, 5L, 4L, 17L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 14L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 1L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints 2L, 5L, 29L, 30L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 2L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 14L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 4L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization 1L, 3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc 1L, 3L, 132L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap 2L, 23L, 43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg 2L, 23L, 43L, 1L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis 1L, 2L, 840L, 10045L, 1L, 2L, 3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 3L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 1L, 2L, 840L, 10045L, 3L, 0L, 1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 1L, 2L, 840L, 10045L, 3L, 0L, 2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 1L, 2L, 840L, 10045L, 3L, 0L, 3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 1L, 2L, 840L, 10045L, 3L, 0L, 4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 1L, 2L, 840L, 10045L, 3L, 0L, 5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 1L, 2L, 840L, 10045L, 3L, 0L, 6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 1L, 2L, 840L, 10045L, 3L, 0L, 7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 1L, 2L, 840L, 10045L, 3L, 0L, 8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 1L, 2L, 840L, 10045L, 3L, 0L, 9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 1L, 2L, 840L, 10045L, 3L, 0L, 10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 1L, 2L, 840L, 10045L, 3L, 0L, 11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 1L, 2L, 840L, 10045L, 3L, 0L, 12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 1L, 2L, 840L, 10045L, 3L, 0L, 13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 1L, 2L, 840L, 10045L, 3L, 0L, 14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 1L, 2L, 840L, 10045L, 3L, 0L, 15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 1L, 2L, 840L, 10045L, 3L, 0L, 16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 1L, 2L, 840L, 10045L, 3L, 0L, 17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 1L, 2L, 840L, 10045L, 3L, 0L, 18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 1L, 2L, 840L, 10045L, 3L, 0L, 19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 1L, 2L, 840L, 10045L, 3L, 0L, 20L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 1L, 3L, 132L, 0L, 6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 1L, 3L, 132L, 0L, 7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 1L, 3L, 132L, 0L, 28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 1L, 3L, 132L, 0L, 29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 1L, 3L, 132L, 0L, 9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 1L, 3L, 132L, 0L, 8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 1L, 3L, 132L, 0L, 30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 1L, 3L, 132L, 0L, 31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 1L, 3L, 132L, 0L, 32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 1L, 3L, 132L, 0L, 33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 1L, 3L, 132L, 0L, 10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 1L, 3L, 132L, 0L, 34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 1L, 3L, 132L, 0L, 35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 1L, 3L, 132L, 0L, 4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 1L, 3L, 132L, 0L, 5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 1L, 3L, 132L, 0L, 22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 1L, 3L, 132L, 0L, 23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 1L, 3L, 132L, 0L, 1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 1L, 3L, 132L, 0L, 2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 1L, 3L, 132L, 0L, 15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 1L, 3L, 132L, 0L, 24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 1L, 3L, 132L, 0L, 25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 1L, 3L, 132L, 0L, 26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 1L, 3L, 132L, 0L, 27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 1L, 3L, 132L, 0L, 3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 1L, 3L, 132L, 0L, 16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 1L, 3L, 132L, 0L, 17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 1L, 3L, 132L, 0L, 36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 1L, 3L, 132L, 0L, 37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 1L, 3L, 132L, 0L, 38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 1L, 3L, 132L, 0L, 39L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 2L, 23L, 43L, 1L, 4L, 1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 2L, 23L, 43L, 1L, 4L, 3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 2L, 23L, 43L, 1L, 4L, 4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 2L, 23L, 43L, 1L, 4L, 5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 2L, 23L, 43L, 1L, 4L, 6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 2L, 23L, 43L, 1L, 4L, 7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 2L, 23L, 43L, 1L, 4L, 8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 2L, 23L, 43L, 1L, 4L, 9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 2L, 23L, 43L, 1L, 4L, 10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 2L, 23L, 43L, 1L, 4L, 11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 2L, 23L, 43L, 1L, 4L, 12L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy 2L, 5L, 29L, 32L, 0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings 2L, 5L, 29L, 33L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy 2L, 5L, 29L, 54L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 1L, 2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 1L, 3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 1L, 4L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 1L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 21L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 41L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 4L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 24L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 3L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 23L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 43L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes 2L, 5L, 29L, 9L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point 2L, 5L, 29L, 28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer 2L, 5L, 29L, 29L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa 1L, 2L, 410L, 200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb 1L, 2L, 410L, 200004L, 1L, 3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc 1L, 2L, 410L, 200004L, 1L, 4L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 1L, 2L, 410L, 200004L, 1L, 6L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 1L, 2L, 410L, 200004L, 1L, 5L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 1L, 3L, 6L, 1L, 5L, 5L, 8L, 1L, 1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 1L, 3L, 6L, 1L, 5L, 5L, 8L, 1L, 2L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC 1L, 2L, 840L, 113533L, 7L, 66L, 13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac 1L, 2L, 840L, 113533L, 7L, 66L, 30L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 16L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 5L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 27L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 5L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 25L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 45L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended 1L, 2L, 840L, 10045L, 4L, 2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified 1L, 2L, 840L, 10045L, 4L, 3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 1L, 2L, 840L, 10045L, 4L, 3L, 1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 1L, 2L, 840L, 10045L, 4L, 3L, 2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 1L, 2L, 840L, 10045L, 4L, 3L, 3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 1L, 2L, 840L, 10045L, 4L, 3L, 4L + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 1L, 2L, 840L, 113549L, 2L, 6L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 1L, 2L, 840L, 113549L, 2L, 8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 1L, 2L, 840L, 113549L, 2L, 9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 1L, 2L, 840L, 113549L, 2L, 10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 1L, 2L, 840L, 113549L, 2L, 11L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 2L + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool 1L, 0L, 10118L, 3L, 0L, 55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro 1L, 2L, 643L, 2L, 2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom 1L, 2L, 643L, 2L, 9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 \ + "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 \ + "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 1L, 2L, 643L, 2L, 2L, 3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 \ + "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 1L, 2L, 643L, 2L, 2L, 4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 1L, 2L, 643L, 2L, 2L, 9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 1L, 2L, 643L, 2L, 2L, 10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 1L, 2L, 643L, 2L, 2L, 19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 1L, 2L, 643L, 2L, 2L, 20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 1L, 2L, 643L, 2L, 2L, 21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC 1L, 2L, 643L, 2L, 2L, 22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf 1L, 2L, 643L, 2L, 2L, 23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH 1L, 2L, 643L, 2L, 2L, 98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH 1L, 2L, 643L, 2L, 2L, 99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing \ + "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1L, 2L, 643L, 2L, 2L, 14L, 1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing 1L, 2L, 643L, 2L, 2L, 14L, 0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet 1L, 2L, 643L, 2L, 2L, 30L, 0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet 1L, 2L, 643L, 2L, 2L, 30L, 1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet 1L, 2L, 643L, 2L, 2L, 31L, 0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet \ + "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1L, 2L, 643L, 2L, 2L, 31L, 1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet \ + "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1L, 2L, 643L, 2L, 2L, 31L, 2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet \ + "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1L, 2L, 643L, 2L, 2L, 31L, 3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet \ + "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1L, 2L, 643L, 2L, 2L, 31L, 4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet \ + "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 31L, 5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet \ + "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 31L, 6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet \ + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 31L, 7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet 1L, 2L, 643L, 2L, 2L, 32L, 0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet \ + "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1L, 2L, 643L, 2L, 2L, 32L, 2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet \ + "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1L, 2L, 643L, 2L, 2L, 32L, 3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet \ + "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1L, 2L, 643L, 2L, 2L, 32L, 4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet \ + "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1L, 2L, 643L, 2L, 2L, 32L, 5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet \ + "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 33L, 1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet \ + "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 33L, 2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet \ + "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 33L, 3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet 1L, 2L, 643L, 2L, 2L, 35L, 0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet \ + "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1L, 2L, 643L, 2L, 2L, 35L, 1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet \ + "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1L, 2L, 643L, 2L, 2L, 35L, 2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet \ + "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1L, 2L, 643L, 2L, 2L, 35L, 3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet \ + "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 36L, 0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet \ + "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet \ + 1L, 2L, 643L, 2L, 2L, 36L, 1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a 1L, 2L, 643L, 2L, 2L, 20L, 1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis 1L, 2L, 643L, 2L, 2L, 20L, 2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b 1L, 2L, 643L, 2L, 2L, 20L, 3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis 1L, 2L, 643L, 2L, 2L, 20L, 4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc 1L, 2L, 643L, 2L, 9L, 1L, 6L, 1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc 1L, 2L, 643L, 2L, 9L, 1L, 5L, 3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc 1L, 2L, 643L, 2L, 9L, 1L, 5L, 4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc \ + "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc \ + "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc \ + 1L, 2L, 643L, 2L, 9L, 1L, 3L, 3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc \ + "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc \ + "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc \ + 1L, 2L, 643L, 2L, 9L, 1L, 3L, 4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc \ + "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc 1L, 2L, 643L, 2L, 9L, 1L, 8L, 1L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L, 3L, 6L, 1L, 4L, 1L, 311L, 17L, 2L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl 2L, 5L, 29L, 46L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 3L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide 2L, 5L, 4L, 14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory 2L, 5L, 4L, 15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress 2L, 5L, 4L, 16L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox 2L, 5L, 4L, 18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName 2L, 5L, 4L, 19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber 2L, 5L, 4L, 20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber 2L, 5L, 4L, 21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier 2L, 5L, 4L, 22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber 2L, 5L, 4L, 23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address 2L, 5L, 4L, 24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber 2L, 5L, 4L, 25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress 2L, 5L, 4L, 26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator 2L, 5L, 4L, 27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod 2L, 5L, 4L, 28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress 2L, 5L, 4L, 29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext 2L, 5L, 4L, 30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member 2L, 5L, 4L, 31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner 2L, 5L, 4L, 32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant 2L, 5L, 4L, 33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso 2L, 5L, 4L, 34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword 2L, 5L, 4L, 35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate 2L, 5L, 4L, 36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate 2L, 5L, 4L, 37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList 2L, 5L, 4L, 38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList 2L, 5L, 4L, 39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair 2L, 5L, 4L, 40L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide 2L, 5L, 4L, 47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation 2L, 5L, 4L, 48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName 2L, 5L, 4L, 49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember 2L, 5L, 4L, 50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier 2L, 5L, 4L, 51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms 2L, 5L, 4L, 52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList 2L, 5L, 4L, 53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName 2L, 5L, 4L, 54L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 9L + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 8L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 28L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 48L + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 3L, 2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 3L, 3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L, 2L, 392L, 200011L, 61L, 1L, 1L, 3L, 4L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage 2L, 5L, 29L, 37L, 0L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 1L, 2L, 840L, 113549L, 1L, 1L, 8L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss 1L, 2L, 840L, 113549L, 1L, 1L, 10L + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep 1L, 2L, 840L, 113549L, 1L, 1L, 7L + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber 1L, 2L, 840L, 10046L, 2L, 1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L, 3L, 36L, 3L, 3L, 2L, 8L, 1L, 1L, 14L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified 1L, 2L, 840L, 113549L, 1L, 1L, 9L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme \ + "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 11L, 0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme \ + "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1L, 3L, 132L, 1L, 11L, 1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme \ + "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1L, 3L, 132L, 1L, 11L, 2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme \ + "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1L, 3L, 132L, 1L, 11L, 3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme \ + "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme \ + "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 14L, 0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme \ + "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1L, 3L, 132L, 1L, 14L, 1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme \ + "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1L, 3L, 132L, 1L, 14L, 2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme \ + "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1L, 3L, 132L, 1L, 14L, 3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_X25519 "X25519" +#define NID_X25519 948 +#define OBJ_X25519 1L, 3L, 101L, 110L + +#define SN_ED25519 "ED25519" +#define NID_ED25519 949 +#define OBJ_ED25519 1L, 3L, 101L, 112L + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 950 + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 951 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 952 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 953 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 954 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 955 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 956 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 957 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 958 + +#define SN_CECPQ2 "CECPQ2" +#define NID_CECPQ2 959 + +#define SN_ED448 "ED448" +#define NID_ED448 960 +#define OBJ_ED448 1L, 3L, 101L, 113L + +#define SN_X448 "X448" +#define NID_X448 961 +#define OBJ_X448 1L, 3L, 101L, 111L + +#define SN_sha512_256 "SHA512-256" +#define LN_sha512_256 "sha512-256" +#define NID_sha512_256 962 +#define OBJ_sha512_256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 6L + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_NID_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h new file mode 100644 index 00000000..10fbbc9d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h @@ -0,0 +1,256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_OBJ_H +#define OPENSSL_HEADER_OBJ_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_bytestring.h" +#include "CNIOBoringSSL_nid.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The objects library deals with the registration and indexing of ASN.1 object +// identifiers. These values are often written as a dotted sequence of numbers, +// e.g. 1.2.840.113549.1.9.16.3.9. +// +// Internally, OpenSSL likes to deal with these values by numbering them with +// numbers called "nids". OpenSSL has a large, built-in database of common +// object identifiers and also has both short and long names for them. +// +// This library provides functions for translating between object identifiers, +// nids, short names and long names. +// +// The nid values should not be used outside of a single process: they are not +// stable identifiers. + + +// Basic operations. + +// OBJ_dup returns a duplicate copy of |obj| or NULL on allocation failure. The +// caller must call |ASN1_OBJECT_free| on the result to release it. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj); + +// OBJ_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); + +// OBJ_get0_data returns a pointer to the DER representation of |obj|. This is +// the contents of the DER-encoded identifier, not including the tag and length. +// If |obj| does not have an associated object identifier (i.e. it is a nid-only +// value), this value is the empty string. +OPENSSL_EXPORT const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj); + +// OBJ_length returns the length of the DER representation of |obj|. This is the +// contents of the DER-encoded identifier, not including the tag and length. If +// |obj| does not have an associated object identifier (i.e. it is a nid-only +// value), this value is the empty string. +OPENSSL_EXPORT size_t OBJ_length(const ASN1_OBJECT *obj); + + +// Looking up nids. + +// OBJ_obj2nid returns the nid corresponding to |obj|, or |NID_undef| if no +// such object is known. +OPENSSL_EXPORT int OBJ_obj2nid(const ASN1_OBJECT *obj); + +// OBJ_cbs2nid returns the nid corresponding to the DER data in |cbs|, or +// |NID_undef| if no such object is known. +OPENSSL_EXPORT int OBJ_cbs2nid(const CBS *cbs); + +// OBJ_sn2nid returns the nid corresponding to |short_name|, or |NID_undef| if +// no such short name is known. +OPENSSL_EXPORT int OBJ_sn2nid(const char *short_name); + +// OBJ_ln2nid returns the nid corresponding to |long_name|, or |NID_undef| if +// no such long name is known. +OPENSSL_EXPORT int OBJ_ln2nid(const char *long_name); + +// OBJ_txt2nid returns the nid corresponding to |s|, which may be a short name, +// long name, or an ASCII string containing a dotted sequence of numbers. It +// returns the nid or NID_undef if unknown. +OPENSSL_EXPORT int OBJ_txt2nid(const char *s); + + +// Getting information about nids. + +// OBJ_nid2obj returns the |ASN1_OBJECT| corresponding to |nid|, or NULL if +// |nid| is unknown. +// +// Although the output is not const, this function returns a static, immutable +// |ASN1_OBJECT|. It is not necessary to release the object with +// |ASN1_OBJECT_free|. +// +// However, functions like |X509_ALGOR_set0| expect to take ownership of a +// possibly dynamically-allocated |ASN1_OBJECT|. |ASN1_OBJECT_free| is a no-op +// for static |ASN1_OBJECT|s, so |OBJ_nid2obj| is compatible with such +// functions. +// +// Callers are encouraged to store the result of this function in a const +// pointer. However, if using functions like |X509_ALGOR_set0|, callers may use +// a non-const pointer and manage ownership. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_nid2obj(int nid); + +// OBJ_nid2sn returns the short name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2sn(int nid); + +// OBJ_nid2ln returns the long name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2ln(int nid); + +// OBJ_nid2cbb writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns +// one on success or zero otherwise. +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid); + + +// Dealing with textual representations of object identifiers. + +// OBJ_txt2obj returns an ASN1_OBJECT for the textual representation in |s|. +// If |dont_search_names| is zero, then |s| will be matched against the long +// and short names of a known objects to find a match. Otherwise |s| must +// contain an ASCII string with a dotted sequence of numbers. The resulting +// object need not be previously known. It returns a freshly allocated +// |ASN1_OBJECT| or NULL on error. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names); + +// OBJ_obj2txt converts |obj| to a textual representation. If +// |always_return_oid| is zero then |obj| will be matched against known objects +// and the long (preferably) or short name will be used if found. Otherwise +// |obj| will be converted into a dotted sequence of integers. If |out| is not +// NULL, then at most |out_len| bytes of the textual form will be written +// there. If |out_len| is at least one, then string written to |out| will +// always be NUL terminated. It returns the number of characters that could +// have been written, not including the final NUL, or -1 on error. +OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid); + + +// Adding objects at runtime. + +// OBJ_create adds a known object and returns the nid of the new object, or +// NID_undef on error. +OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name, + const char *long_name); + + +// Handling signature algorithm identifiers. +// +// Some NIDs (e.g. sha256WithRSAEncryption) specify both a digest algorithm and +// a public key algorithm. The following functions map between pairs of digest +// and public-key algorithms and the NIDs that specify their combination. +// +// Sometimes the combination NID leaves the digest unspecified (e.g. +// rsassaPss). In these cases, the digest NID is |NID_undef|. + +// OBJ_find_sigid_algs finds the digest and public-key NIDs that correspond to +// the signing algorithm |sign_nid|. If successful, it sets |*out_digest_nid| +// and |*out_pkey_nid| and returns one. Otherwise it returns zero. Any of +// |out_digest_nid| or |out_pkey_nid| can be NULL if the caller doesn't need +// that output value. +OPENSSL_EXPORT int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, + int *out_pkey_nid); + +// OBJ_find_sigid_by_algs finds the signature NID that corresponds to the +// combination of |digest_nid| and |pkey_nid|. If success, it sets +// |*out_sign_nid| and returns one. Otherwise it returns zero. The +// |out_sign_nid| argument can be NULL if the caller only wishes to learn +// whether the combination is valid. +OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, + int pkey_nid); + + +// Deprecated functions. + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +#define OBJ_NAME_TYPE_MD_METH 1 +#define OBJ_NAME_TYPE_CIPHER_METH 2 + +// OBJ_NAME_do_all_sorted calls |callback| zero or more times, each time with +// the name of a different primitive. If |type| is |OBJ_NAME_TYPE_MD_METH| then +// the primitives will be hash functions, alternatively if |type| is +// |OBJ_NAME_TYPE_CIPHER_METH| then the primitives will be ciphers or cipher +// modes. +// +// This function is ill-specified and should never be used. +OPENSSL_EXPORT void OBJ_NAME_do_all_sorted( + int type, void (*callback)(const OBJ_NAME *, void *arg), void *arg); + +// OBJ_NAME_do_all calls |OBJ_NAME_do_all_sorted|. +OPENSSL_EXPORT void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, + void *arg), + void *arg); + +// OBJ_cleanup does nothing. +OPENSSL_EXPORT void OBJ_cleanup(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define OBJ_R_UNKNOWN_NID 100 +#define OBJ_R_INVALID_OID_STRING 101 + +#endif // OPENSSL_HEADER_OBJ_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj_mac.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj_mac.h new file mode 100644 index 00000000..0868cab9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj_mac.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_nid.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_objects.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_objects.h new file mode 100644 index 00000000..9e5a6f79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_objects.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_obj.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslconf.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslconf.h new file mode 100644 index 00000000..3f1faf32 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslconf.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#ifndef OPENSSL_HEADER_OPENSSLCONF_H +#define OPENSSL_HEADER_OPENSSLCONF_H + + +#define OPENSSL_NO_ASYNC +#define OPENSSL_NO_BF +#define OPENSSL_NO_BLAKE2 +#define OPENSSL_NO_BUF_FREELISTS +#define OPENSSL_NO_CAMELLIA +#define OPENSSL_NO_CAPIENG +#define OPENSSL_NO_CAST +#define OPENSSL_NO_CMS +#define OPENSSL_NO_COMP +#define OPENSSL_NO_CT +#define OPENSSL_NO_DANE +#define OPENSSL_NO_DEPRECATED +#define OPENSSL_NO_DGRAM +#define OPENSSL_NO_DYNAMIC_ENGINE +#define OPENSSL_NO_EC_NISTP_64_GCC_128 +#define OPENSSL_NO_EC2M +#define OPENSSL_NO_EGD +#define OPENSSL_NO_ENGINE +#define OPENSSL_NO_GMP +#define OPENSSL_NO_GOST +#define OPENSSL_NO_HEARTBEATS +#define OPENSSL_NO_HW +#define OPENSSL_NO_IDEA +#define OPENSSL_NO_JPAKE +#define OPENSSL_NO_KRB5 +#define OPENSSL_NO_MD2 +#define OPENSSL_NO_MDC2 +#define OPENSSL_NO_OCB +#define OPENSSL_NO_OCSP +#define OPENSSL_NO_RC2 +#define OPENSSL_NO_RC5 +#define OPENSSL_NO_RFC3779 +#define OPENSSL_NO_RIPEMD +#define OPENSSL_NO_RMD160 +#define OPENSSL_NO_SCTP +#define OPENSSL_NO_SEED +#define OPENSSL_NO_SM2 +#define OPENSSL_NO_SM3 +#define OPENSSL_NO_SM4 +#define OPENSSL_NO_SRP +#define OPENSSL_NO_SSL2 +#define OPENSSL_NO_SSL3 +#define OPENSSL_NO_SSL3_METHOD +#define OPENSSL_NO_STATIC_ENGINE +#define OPENSSL_NO_STORE +#define OPENSSL_NO_WHIRLPOOL + + +#endif // OPENSSL_HEADER_OPENSSLCONF_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslv.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslv.h new file mode 100644 index 00000000..0296d7a3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslv.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_crypto.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ossl_typ.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ossl_typ.h new file mode 100644 index 00000000..522025f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ossl_typ.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_base.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h new file mode 100644 index 00000000..8054f5eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h @@ -0,0 +1,483 @@ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_PEM_H +#define OPENSSL_HEADER_PEM_H + +#include "CNIOBoringSSL_base64.h" +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_cipher.h" +#include "CNIOBoringSSL_digest.h" +#include "CNIOBoringSSL_evp.h" +#include "CNIOBoringSSL_pkcs7.h" +#include "CNIOBoringSSL_stack.h" +#include "CNIOBoringSSL_x509.h" + +// For compatibility with open-iscsi, which assumes that it can get +// |OPENSSL_malloc| from pem.h or err.h +#include "CNIOBoringSSL_crypto.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PEM_BUFSIZE 1024 + +#define PEM_STRING_X509_OLD "X509 CERTIFICATE" +#define PEM_STRING_X509 "CERTIFICATE" +#define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +#define PEM_STRING_X509_CRL "X509 CRL" +#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +#define PEM_STRING_PUBLIC "PUBLIC KEY" +#define PEM_STRING_RSA "RSA PRIVATE KEY" +#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +#define PEM_STRING_DSA "DSA PRIVATE KEY" +#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +#define PEM_STRING_EC "EC PRIVATE KEY" +#define PEM_STRING_PKCS7 "PKCS7" +#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +#define PEM_STRING_PKCS8INF "PRIVATE KEY" +#define PEM_STRING_DHPARAMS "DH PARAMETERS" +#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_CMS "CMS" + +// enc_type is one off +#define PEM_TYPE_ENCRYPTED 10 +#define PEM_TYPE_MIC_ONLY 20 +#define PEM_TYPE_MIC_CLEAR 30 +#define PEM_TYPE_CLEAR 40 + +// These macros make the PEM_read/PEM_write functions easier to maintain and +// write. Now they are all implemented with either: +// IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...) + + +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ + static void *pem_read_##name##_d2i(void **x, const unsigned char **inp, \ + long len) { \ + return d2i_##asn1((type **)x, inp, len); \ + } \ + OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, \ + pem_password_cb *cb, void *u) { \ + return (type *)PEM_ASN1_read(pem_read_##name##_d2i, str, fp, (void **)x, \ + cb, u); \ + } + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ + static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x) { \ + return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, NULL, NULL, 0, \ + NULL, NULL); \ + } + +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ + static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((const type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x) { \ + return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, (void *)x, NULL, \ + NULL, 0, NULL, NULL); \ + } + +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ + static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_##name( \ + FILE *fp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u) { \ + return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, enc, kstr, klen, \ + cb, u); \ + } + +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ + static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((const type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_##name( \ + FILE *fp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u) { \ + return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, enc, kstr, klen, \ + cb, u); \ + } + + +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + static void *pem_read_bio_##name##_d2i(void **x, const unsigned char **inp, \ + long len) { \ + return d2i_##asn1((type **)x, inp, len); \ + } \ + OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, \ + pem_password_cb *cb, void *u) { \ + return (type *)PEM_ASN1_read_bio(pem_read_bio_##name##_d2i, str, bp, \ + (void **)x, cb, u); \ + } + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x) { \ + return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, x, NULL, \ + NULL, 0, NULL, NULL); \ + } + +#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((const type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x) { \ + return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, (void *)x, \ + NULL, NULL, 0, NULL, NULL); \ + } + +#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_bio_##name( \ + BIO *bp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u) { \ + return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, x, enc, \ + kstr, klen, cb, u); \ + } + +#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ + return i2d_##asn1((const type *)x, outp); \ + } \ + OPENSSL_EXPORT int PEM_write_bio_##name( \ + BIO *bp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u) { \ + return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, (void *)x, \ + enc, kstr, klen, cb, u); \ + } + +#define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +// These are the same except they are for the declarations + +#define DECLARE_PEM_read_fp(name, type) \ + OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, \ + pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name( \ + FILE *fp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u); + +#define DECLARE_PEM_read_bio(name, type) \ + OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, \ + pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name( \ + BIO *bp, type *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, \ + pem_password_cb *cb, void *u); + + +#define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) + +#define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) + +#define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) + +#define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) + +#define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) + +#define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) + +#define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) + +// "userdata": new with OpenSSL 0.9.4 +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); + +OPENSSL_EXPORT int PEM_get_EVP_CIPHER_INFO(char *header, + EVP_CIPHER_INFO *cipher); +OPENSSL_EXPORT int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, + long *len, pem_password_cb *callback, void *u); + +// PEM_read_bio reads from |bp|, until the next PEM block. If one is found, it +// returns one and sets |*name|, |*header|, and |*data| to newly-allocated +// buffers containing the PEM type, the header block, and the decoded data, +// respectively. |*name| and |*header| are NUL-terminated C strings, while +// |*data| has |*len| bytes. The caller must release each of |*name|, |*header|, +// and |*data| with |OPENSSL_free| when done. If no PEM block is found, this +// function returns zero and pushes |PEM_R_NO_START_LINE| to the error queue. If +// one is found, but there is an error decoding it, it returns zero and pushes +// some other error to the error queue. +OPENSSL_EXPORT int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); + +// PEM_write_bio writes a PEM block to |bp|, containing |len| bytes from |data| +// as data. |name| and |hdr| are NUL-terminated C strings containing the PEM +// type and header block, respectively. This function returns zero on error and +// the number of bytes written on success. +OPENSSL_EXPORT int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); + +OPENSSL_EXPORT int PEM_bytes_read_bio(unsigned char **pdata, long *plen, + char **pnm, const char *name, BIO *bp, + pem_password_cb *cb, void *u); +OPENSSL_EXPORT void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, + BIO *bp, void **x, pem_password_cb *cb, + void *u); +OPENSSL_EXPORT int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, + BIO *bp, void *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( + BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, + EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *cd, + void *u); + +OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +OPENSSL_EXPORT int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +OPENSSL_EXPORT void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, + void **x, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *callback, void *u); +OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, + STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, + void *u); + +// PEM_def_callback treats |userdata| as a string and copies it into |buf|, +// assuming its |size| is sufficient. Returns the length of the string, or 0 +// if there is not enough room. If either |buf| or |userdata| is NULL, 0 is +// returned. Note that this is different from OpenSSL, which prompts for a +// password. +OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, + void *userdata); +OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); +OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, + char *str); + + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) + +DECLARE_PEM_rw(X509_CRL, X509_CRL) + +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) + + +DECLARE_PEM_rw_const(DHparams, DH) + + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, + int nid, char *kstr, + int klen, + pem_password_cb *cb, + void *u); +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, + const EVP_CIPHER *, char *, + int, pem_password_cb *, + void *); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, + int klen, pem_password_cb *cb, + void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, + int klen, pem_password_cb *cb, + void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, + int klen, pem_password_cb *cd, + void *u); + + +#ifdef __cplusplus +} +#endif + +#define PEM_R_BAD_BASE64_DECODE 100 +#define PEM_R_BAD_DECRYPT 101 +#define PEM_R_BAD_END_LINE 102 +#define PEM_R_BAD_IV_CHARS 103 +#define PEM_R_BAD_PASSWORD_READ 104 +#define PEM_R_CIPHER_IS_NULL 105 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 106 +#define PEM_R_NOT_DEK_INFO 107 +#define PEM_R_NOT_ENCRYPTED 108 +#define PEM_R_NOT_PROC_TYPE 109 +#define PEM_R_NO_START_LINE 110 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 + +#endif // OPENSSL_HEADER_PEM_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs12.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs12.h new file mode 100644 index 00000000..91995960 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs12.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_pkcs8.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs7.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs7.h new file mode 100644 index 00000000..6d0a32ae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs7.h @@ -0,0 +1,239 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_H +#define OPENSSL_HEADER_PKCS7_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_stack.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS#7. +// +// This library contains functions for extracting information from PKCS#7 +// structures (RFC 2315). + +DECLARE_STACK_OF(CRYPTO_BUFFER) +DECLARE_STACK_OF(X509) +DECLARE_STACK_OF(X509_CRL) + +// PKCS7_get_raw_certificates parses a PKCS#7, SignedData structure from |cbs| +// and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. |cbs| is advanced passed the structure. +// +// Note that a SignedData structure may contain no certificates, in which case +// this function succeeds but does not append any certificates. Additionally, +// certificates in SignedData structures are unordered. Callers should not +// assume a particular order in |*out_certs| and may need to search for matches +// or run path-building algorithms. +OPENSSL_EXPORT int PKCS7_get_raw_certificates( + STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// PKCS7_get_certificates behaves like |PKCS7_get_raw_certificates| but parses +// them into |X509| objects. +OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs); + +// PKCS7_bundle_raw_certificates appends a PKCS#7, SignedData structure +// containing |certs| to |out|. It returns one on success and zero on error. +// Note that certificates in SignedData structures are unordered. The order in +// |certs| will not be preserved. +OPENSSL_EXPORT int PKCS7_bundle_raw_certificates( + CBB *out, const STACK_OF(CRYPTO_BUFFER) *certs); + +// PKCS7_bundle_certificates behaves like |PKCS7_bundle_raw_certificates| but +// takes |X509| objects as input. +OPENSSL_EXPORT int PKCS7_bundle_certificates( + CBB *out, const STACK_OF(X509) *certs); + +// PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends +// the included CRLs to |out_crls|. It returns one on success and zero on error. +// |cbs| is advanced passed the structure. +// +// Note that a SignedData structure may contain no CRLs, in which case this +// function succeeds but does not append any CRLs. Additionally, CRLs in +// SignedData structures are unordered. Callers should not assume an order in +// |*out_crls| and may need to search for matches. +OPENSSL_EXPORT int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs); + +// PKCS7_bundle_CRLs appends a PKCS#7, SignedData structure containing +// |crls| to |out|. It returns one on success and zero on error. Note that CRLs +// in SignedData structures are unordered. The order in |crls| will not be +// preserved. +OPENSSL_EXPORT int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls); + +// PKCS7_get_PEM_certificates reads a PEM-encoded, PKCS#7, SignedData structure +// from |pem_bio| and appends the included certificates to |out_certs|. It +// returns one on success and zero on error. +// +// Note that a SignedData structure may contain no certificates, in which case +// this function succeeds but does not append any certificates. Additionally, +// certificates in SignedData structures are unordered. Callers should not +// assume a particular order in |*out_certs| and may need to search for matches +// or run path-building algorithms. +OPENSSL_EXPORT int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, + BIO *pem_bio); + +// PKCS7_get_PEM_CRLs reads a PEM-encoded, PKCS#7, SignedData structure from +// |pem_bio| and appends the included CRLs to |out_crls|. It returns one on +// success and zero on error. +// +// Note that a SignedData structure may contain no CRLs, in which case this +// function succeeds but does not append any CRLs. Additionally, CRLs in +// SignedData structures are unordered. Callers should not assume an order in +// |*out_crls| and may need to search for matches. +OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, + BIO *pem_bio); + + +// Deprecated functions. +// +// These functions are a compatibility layer over a subset of OpenSSL's PKCS#7 +// API. It intentionally does not implement the whole thing, only the minimum +// needed to build cryptography.io. + +typedef struct { + STACK_OF(X509) *cert; + STACK_OF(X509_CRL) *crl; +} PKCS7_SIGNED; + +typedef struct { + STACK_OF(X509) *cert; + STACK_OF(X509_CRL) *crl; +} PKCS7_SIGN_ENVELOPE; + +typedef void PKCS7_ENVELOPE; +typedef void PKCS7_DIGEST; +typedef void PKCS7_ENCRYPT; +typedef void PKCS7_SIGNER_INFO; + +typedef struct { + uint8_t *ber_bytes; + size_t ber_len; + + // Unlike OpenSSL, the following fields are immutable. They filled in when the + // object is parsed and ignored in serialization. + ASN1_OBJECT *type; + union { + char *ptr; + ASN1_OCTET_STRING *data; + PKCS7_SIGNED *sign; + PKCS7_ENVELOPE *enveloped; + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + PKCS7_DIGEST *digest; + PKCS7_ENCRYPT *encrypted; + ASN1_TYPE *other; + } d; +} PKCS7; + +// d2i_PKCS7 parses a BER-encoded, PKCS#7 signed data ContentInfo structure from +// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, + size_t len); + +// d2i_PKCS7_bio behaves like |d2i_PKCS7| but reads the input from |bio|. If +// the length of the object is indefinite the full contents of |bio| are read. +// +// If the function fails then some unknown amount of data may have been read +// from |bio|. +OPENSSL_EXPORT PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out); + +// i2d_PKCS7 marshals |p7| as a DER-encoded PKCS#7 ContentInfo structure, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_PKCS7(const PKCS7 *p7, uint8_t **out); + +// i2d_PKCS7_bio writes |p7| to |bio|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7); + +// PKCS7_free releases memory associated with |p7|. +OPENSSL_EXPORT void PKCS7_free(PKCS7 *p7); + +// PKCS7_type_is_data returns zero. +OPENSSL_EXPORT int PKCS7_type_is_data(const PKCS7 *p7); + +// PKCS7_type_is_digest returns zero. +OPENSSL_EXPORT int PKCS7_type_is_digest(const PKCS7 *p7); + +// PKCS7_type_is_encrypted returns zero. +OPENSSL_EXPORT int PKCS7_type_is_encrypted(const PKCS7 *p7); + +// PKCS7_type_is_enveloped returns zero. +OPENSSL_EXPORT int PKCS7_type_is_enveloped(const PKCS7 *p7); + +// PKCS7_type_is_signed returns one. (We only supporte signed data +// ContentInfos.) +OPENSSL_EXPORT int PKCS7_type_is_signed(const PKCS7 *p7); + +// PKCS7_type_is_signedAndEnveloped returns zero. +OPENSSL_EXPORT int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7); + +// PKCS7_DETACHED indicates that the PKCS#7 file specifies its data externally. +#define PKCS7_DETACHED 0x40 + +// The following flags cause |PKCS7_sign| to fail. +#define PKCS7_TEXT 0x1 +#define PKCS7_NOCERTS 0x2 +#define PKCS7_NOSIGS 0x4 +#define PKCS7_NOCHAIN 0x8 +#define PKCS7_NOINTERN 0x10 +#define PKCS7_NOVERIFY 0x20 +#define PKCS7_BINARY 0x80 +#define PKCS7_NOATTR 0x100 +#define PKCS7_NOSMIMECAP 0x200 +#define PKCS7_STREAM 0x1000 +#define PKCS7_PARTIAL 0x4000 + +// PKCS7_sign can operate in two modes to provide some backwards compatibility: +// +// The first mode assembles |certs| into a PKCS#7 signed data ContentInfo with +// external data and no signatures. It returns a newly-allocated |PKCS7| on +// success or NULL on error. |sign_cert| and |pkey| must be NULL. |data| is +// ignored. |flags| must be equal to |PKCS7_DETACHED|. Additionally, +// certificates in SignedData structures are unordered. The order of |certs| +// will not be preserved. +// +// The second mode generates a detached RSA SHA-256 signature of |data| using +// |pkey| and produces a PKCS#7 SignedData structure containing it. |certs| +// must be NULL and |flags| must be exactly |PKCS7_NOATTR | PKCS7_BINARY | +// PKCS7_NOCERTS | PKCS7_DETACHED|. +// +// Note this function only implements a subset of the corresponding OpenSSL +// function. It is provided for backwards compatibility only. +OPENSSL_EXPORT PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, int flags); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(PKCS7, PKCS7_free) + +BSSL_NAMESPACE_END +} // extern C++ +#endif + +#define PKCS7_R_BAD_PKCS7_VERSION 100 +#define PKCS7_R_NOT_PKCS7_SIGNED_DATA 101 +#define PKCS7_R_NO_CERTIFICATES_INCLUDED 102 +#define PKCS7_R_NO_CRLS_INCLUDED 103 + +#endif // OPENSSL_HEADER_PKCS7_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs8.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs8.h new file mode 100644 index 00000000..a477b9af --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs8.h @@ -0,0 +1,290 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + + +#ifndef OPENSSL_HEADER_PKCS8_H +#define OPENSSL_HEADER_PKCS8_H + +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_x509.h" + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS8_encrypt serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 or +// PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS +// #12, and PBES2, are supported. PBES2 is selected by setting |cipher| and +// passing -1 for |pbe_nid|. Otherwise, PBES1 is used and |cipher| is ignored. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// If |salt| is NULL, a random salt of |salt_len| bytes is generated. If +// |salt_len| is zero, a default salt length is used instead. +// +// The resulting structure is stored in an |X509_SIG| which must be freed by the +// caller. +OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, + PKCS8_PRIV_KEY_INFO *p8inf); + +// PKCS8_marshal_encrypted_private_key behaves like |PKCS8_encrypt| but encrypts +// an |EVP_PKEY| and writes the serialized EncryptedPrivateKeyInfo to |out|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS8_marshal_encrypted_private_key( + CBB *out, int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + size_t pass_len, const uint8_t *salt, size_t salt_len, int iterations, + const EVP_PKEY *pkey); + +// PKCS8_decrypt decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 or PBES2 +// as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, and PBES2, +// defined in PKCS #12, are supported. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// The resulting structure must be freed by the caller. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, + const char *pass, + int pass_len); + +// PKCS8_parse_encrypted_private_key behaves like |PKCS8_decrypt| but it parses +// the EncryptedPrivateKeyInfo structure from |cbs| and advances |cbs|. It +// returns a newly-allocated |EVP_PKEY| on success and zero on error. +OPENSSL_EXPORT EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, + const char *pass, + size_t pass_len); + +// PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates +// and decrypts it using |password|, sets |*out_key| to the included private +// key and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. The caller takes ownership of the outputs. +// Any friendlyName attributes (RFC 2985) in the PKCS#12 structure will be +// returned on the |X509| objects as aliases. See also |X509_alias_get0|. +OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key, + STACK_OF(X509) *out_certs, + CBS *in, const char *password); + + +// Deprecated functions. + +// PKCS12_PBE_add does nothing. It exists for compatibility with OpenSSL. +OPENSSL_EXPORT void PKCS12_PBE_add(void); + +// d2i_PKCS12 is a dummy function that copies |*ber_bytes| into a +// |PKCS12| structure. The |out_p12| argument should be NULL(✝). On exit, +// |*ber_bytes| will be advanced by |ber_len|. It returns a fresh |PKCS12| +// structure or NULL on error. +// +// Note: unlike other d2i functions, |d2i_PKCS12| will always consume |ber_len| +// bytes. +// +// (✝) If |out_p12| is not NULL and the function is successful, |*out_p12| will +// be freed if not NULL itself and the result will be written to |*out_p12|. +// New code should not depend on this. +OPENSSL_EXPORT PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len); + +// d2i_PKCS12_bio acts like |d2i_PKCS12| but reads from a |BIO|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12); + +// d2i_PKCS12_fp acts like |d2i_PKCS12| but reads from a |FILE|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12); + +// i2d_PKCS12 is a dummy function which copies the contents of |p12|. If |out| +// is not NULL then the result is written to |*out| and |*out| is advanced just +// past the output. It returns the number of bytes in the result, whether +// written or not, or a negative value on error. +OPENSSL_EXPORT int i2d_PKCS12(const PKCS12 *p12, uint8_t **out); + +// i2d_PKCS12_bio writes the contents of |p12| to |bio|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12); + +// i2d_PKCS12_fp writes the contents of |p12| to |fp|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12); + +// PKCS12_parse calls |PKCS12_get_key_and_certs| on the ASN.1 data stored in +// |p12|. The |out_pkey| and |out_cert| arguments must not be NULL and, on +// successful exit, the private key and matching certificate will be stored in +// them. The |out_ca_certs| argument may be NULL but, if not, then any extra +// certificates will be appended to |*out_ca_certs|. If |*out_ca_certs| is NULL +// then it will be set to a freshly allocated stack containing the extra certs. +// +// Note if |p12| does not contain a private key, both |*out_pkey| and +// |*out_cert| will be set to NULL and all certificates will be returned via +// |*out_ca_certs|. Also note this function differs from OpenSSL in that extra +// certificates are returned in the order they appear in the file. OpenSSL 1.1.1 +// returns them in reverse order, but this will be fixed in OpenSSL 3.0. +// +// It returns one on success and zero on error. +// +// Use |PKCS12_get_key_and_certs| instead. +OPENSSL_EXPORT int PKCS12_parse(const PKCS12 *p12, const char *password, + EVP_PKEY **out_pkey, X509 **out_cert, + STACK_OF(X509) **out_ca_certs); + +// PKCS12_verify_mac returns one if |password| is a valid password for |p12| +// and zero otherwise. Since |PKCS12_parse| doesn't take a length parameter, +// it's not actually possible to use a non-NUL-terminated password to actually +// get anything from a |PKCS12|. Thus |password| and |password_len| may be +// |NULL| and zero, respectively, or else |password_len| may be -1, or else +// |password[password_len]| must be zero and no other NUL bytes may appear in +// |password|. If the |password_len| checks fail, zero is returned +// immediately. +OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len); + +// PKCS12_DEFAULT_ITER is the default number of KDF iterations used when +// creating a |PKCS12| object. +#define PKCS12_DEFAULT_ITER 2048 + +// PKCS12_create returns a newly-allocated |PKCS12| object containing |pkey|, +// |cert|, and |chain|, encrypted with the specified password. |name|, if not +// NULL, specifies a user-friendly name to encode with the key and +// certificate. The key and certificates are encrypted with |key_nid| and +// |cert_nid|, respectively, using |iterations| iterations in the +// KDF. |mac_iterations| is the number of iterations when deriving the MAC +// key. |key_type| must be zero. |pkey| and |cert| may be NULL to omit them. +// +// Each of |key_nid|, |cert_nid|, |iterations|, and |mac_iterations| may be zero +// to use defaults, which are |NID_pbe_WithSHA1And3_Key_TripleDES_CBC|, +// |NID_pbe_WithSHA1And40BitRC2_CBC|, |PKCS12_DEFAULT_ITER|, and one, +// respectively. +// +// |key_nid| or |cert_nid| may also be -1 to disable encryption of the key or +// certificate, respectively. This option is not recommended and is only +// implemented for compatibility with external packages. Note the output still +// requires a password for the MAC. Unencrypted keys in PKCS#12 are also not +// widely supported and may not open in other implementations. +// +// If |cert| or |chain| have associated aliases (see |X509_alias_set1|), they +// will be included in the output as friendlyName attributes (RFC 2985). It is +// an error to specify both an alias on |cert| and a non-NULL |name| +// parameter. +OPENSSL_EXPORT PKCS12 *PKCS12_create(const char *password, const char *name, + const EVP_PKEY *pkey, X509 *cert, + const STACK_OF(X509) *chain, int key_nid, + int cert_nid, int iterations, + int mac_iterations, int key_type); + +// PKCS12_free frees |p12| and its contents. +OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(PKCS12, PKCS12_free) +BORINGSSL_MAKE_DELETER(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define PKCS8_R_BAD_PKCS12_DATA 100 +#define PKCS8_R_BAD_PKCS12_VERSION 101 +#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 102 +#define PKCS8_R_CRYPT_ERROR 103 +#define PKCS8_R_DECODE_ERROR 104 +#define PKCS8_R_ENCODE_ERROR 105 +#define PKCS8_R_ENCRYPT_ERROR 106 +#define PKCS8_R_ERROR_SETTING_CIPHER_PARAMS 107 +#define PKCS8_R_INCORRECT_PASSWORD 108 +#define PKCS8_R_KEYGEN_FAILURE 109 +#define PKCS8_R_KEY_GEN_ERROR 110 +#define PKCS8_R_METHOD_NOT_SUPPORTED 111 +#define PKCS8_R_MISSING_MAC 112 +#define PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12 113 +#define PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED 114 +#define PKCS8_R_PKCS12_TOO_DEEPLY_NESTED 115 +#define PKCS8_R_PRIVATE_KEY_DECODE_ERROR 116 +#define PKCS8_R_PRIVATE_KEY_ENCODE_ERROR 117 +#define PKCS8_R_TOO_LONG 118 +#define PKCS8_R_UNKNOWN_ALGORITHM 119 +#define PKCS8_R_UNKNOWN_CIPHER 120 +#define PKCS8_R_UNKNOWN_CIPHER_ALGORITHM 121 +#define PKCS8_R_UNKNOWN_DIGEST 122 +#define PKCS8_R_UNKNOWN_HASH 123 +#define PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 124 +#define PKCS8_R_UNSUPPORTED_KEYLENGTH 125 +#define PKCS8_R_UNSUPPORTED_SALT_TYPE 126 +#define PKCS8_R_UNSUPPORTED_CIPHER 127 +#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 128 +#define PKCS8_R_BAD_ITERATION_COUNT 129 +#define PKCS8_R_UNSUPPORTED_PRF 130 +#define PKCS8_R_INVALID_CHARACTERS 131 +#define PKCS8_R_UNSUPPORTED_OPTIONS 132 +#define PKCS8_R_AMBIGUOUS_FRIENDLY_NAME 133 + +#endif // OPENSSL_HEADER_PKCS8_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_poly1305.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_poly1305.h new file mode 100644 index 00000000..397058a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_poly1305.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_H +#define OPENSSL_HEADER_POLY1305_H + +#include "CNIOBoringSSL_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef uint8_t poly1305_state[512]; + +// CRYPTO_poly1305_init sets up |state| so that it can be used to calculate an +// authentication tag with the one-time key |key|. Note that |key| is a +// one-time key and therefore there is no `reset' method because that would +// enable several messages to be authenticated with the same key. +OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state *state, + const uint8_t key[32]); + +// CRYPTO_poly1305_update processes |in_len| bytes from |in|. It can be called +// zero or more times after poly1305_init. +OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state *state, + const uint8_t *in, size_t in_len); + +// CRYPTO_poly1305_finish completes the poly1305 calculation and writes a 16 +// byte authentication tag to |mac|. +OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state *state, + uint8_t mac[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pool.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pool.h new file mode 100644 index 00000000..1c1c08c5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_pool.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_H +#define OPENSSL_HEADER_POOL_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_stack.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Buffers and buffer pools. +// +// |CRYPTO_BUFFER|s are simply reference-counted blobs. A |CRYPTO_BUFFER_POOL| +// is an intern table for |CRYPTO_BUFFER|s. This allows for a single copy of a +// given blob to be kept in memory and referenced from multiple places. + + +DEFINE_STACK_OF(CRYPTO_BUFFER) + +// CRYPTO_BUFFER_POOL_new returns a freshly allocated |CRYPTO_BUFFER_POOL| or +// NULL on error. +OPENSSL_EXPORT CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void); + +// CRYPTO_BUFFER_POOL_free frees |pool|, which must be empty. +OPENSSL_EXPORT void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new returns a |CRYPTO_BUFFER| containing a copy of |data|, or +// else NULL on error. If |pool| is not NULL then the returned value may be a +// reference to a previously existing |CRYPTO_BUFFER| that contained the same +// data. Otherwise, the returned, fresh |CRYPTO_BUFFER| will be added to the +// pool. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_alloc creates an unpooled |CRYPTO_BUFFER| of the given size and +// writes the underlying data pointer to |*out_data|. It returns NULL on error. +// +// After calling this function, |len| bytes of contents must be written to +// |out_data| before passing the returned pointer to any other BoringSSL +// functions. Once initialized, the |CRYPTO_BUFFER| should be treated as +// immutable. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_alloc(uint8_t **out_data, + size_t len); + +// CRYPTO_BUFFER_new_from_CBS acts the same as |CRYPTO_BUFFER_new|. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS( + const CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new_from_static_data_unsafe behaves like |CRYPTO_BUFFER_new| +// but does not copy |data|. |data| must be immutable and last for the lifetime +// of the address space. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_static_data_unsafe( + const uint8_t *data, size_t len, CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_free decrements the reference count of |buf|. If there are no +// other references, or if the only remaining reference is from a pool, then +// |buf| will be freed. +OPENSSL_EXPORT void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_up_ref increments the reference count of |buf| and returns +// one. +OPENSSL_EXPORT int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_data returns a pointer to the data contained in |buf|. +OPENSSL_EXPORT const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_len returns the length, in bytes, of the data contained in +// |buf|. +OPENSSL_EXPORT size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_init_CBS initialises |out| to point at the data from |buf|. +OPENSSL_EXPORT void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER_POOL, CRYPTO_BUFFER_POOL_free) +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free) +BORINGSSL_MAKE_UP_REF(CRYPTO_BUFFER, CRYPTO_BUFFER_up_ref) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_POOL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rand.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rand.h new file mode 100644 index 00000000..9cba8649 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rand.h @@ -0,0 +1,114 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_RAND_H +#define OPENSSL_HEADER_RAND_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Random number generation. + + +// RAND_bytes writes |len| bytes of random data to |buf| and returns one. +OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len); + +// RAND_cleanup frees any resources used by the RNG. This is not safe if other +// threads might still be calling |RAND_bytes|. +OPENSSL_EXPORT void RAND_cleanup(void); + + +// Obscure functions. + +#if !defined(OPENSSL_WINDOWS) +// RAND_enable_fork_unsafe_buffering enables efficient buffered reading of +// /dev/urandom. It adds an overhead of a few KB of memory per thread. It must +// be called before the first call to |RAND_bytes|. +// +// |fd| must be -1. We no longer support setting the file descriptor with this +// function. +// +// It has an unusual name because the buffer is unsafe across calls to |fork|. +// Hence, this function should never be called by libraries. +OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd); +#endif + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +// RAND_reset_for_fuzzing resets the fuzzer-only deterministic RNG. This +// function is only defined in the fuzzer-only build configuration. +OPENSSL_EXPORT void RAND_reset_for_fuzzing(void); +#endif + + +// Deprecated functions + +// RAND_pseudo_bytes is a wrapper around |RAND_bytes|. +OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len); + +// RAND_seed reads a single byte of random data to ensure that any file +// descriptors etc are opened. +OPENSSL_EXPORT void RAND_seed(const void *buf, int num); + +// RAND_load_file returns a nonnegative number. +OPENSSL_EXPORT int RAND_load_file(const char *path, long num); + +// RAND_file_name returns NULL. +OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num); + +// RAND_add does nothing. +OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy); + +// RAND_egd returns 255. +OPENSSL_EXPORT int RAND_egd(const char *); + +// RAND_poll returns one. +OPENSSL_EXPORT int RAND_poll(void); + +// RAND_status returns one. +OPENSSL_EXPORT int RAND_status(void); + +// rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it +// exists only to be the return type of |RAND_SSLeay|. It's +// external so that variables of this type can be initialized. +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (uint8_t *buf, size_t num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (uint8_t *buf, size_t num); + int (*status) (void); +}; + +// RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. +OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void); + +// RAND_OpenSSL returns a pointer to a dummy |RAND_METHOD|. +OPENSSL_EXPORT RAND_METHOD *RAND_OpenSSL(void); + +// RAND_get_rand_method returns |RAND_SSLeay()|. +OPENSSL_EXPORT const RAND_METHOD *RAND_get_rand_method(void); + +// RAND_set_rand_method returns one. +OPENSSL_EXPORT int RAND_set_rand_method(const RAND_METHOD *); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RAND_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rc4.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rc4.h new file mode 100644 index 00000000..d97fe656 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rc4.h @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_RC4_H +#define OPENSSL_HEADER_RC4_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// RC4. + + +struct rc4_key_st { + uint32_t x, y; + uint32_t data[256]; +} /* RC4_KEY */; + +// RC4_set_key performs an RC4 key schedule and initialises |rc4key| with |len| +// bytes of key material from |key|. +OPENSSL_EXPORT void RC4_set_key(RC4_KEY *rc4key, unsigned len, + const uint8_t *key); + +// RC4 encrypts (or decrypts, it's the same with RC4) |len| bytes from |in| to +// |out|. +OPENSSL_EXPORT void RC4(RC4_KEY *key, size_t len, const uint8_t *in, + uint8_t *out); + + +// Deprecated functions. + +// RC4_options returns the string "rc4(ptr,int)". +OPENSSL_EXPORT const char *RC4_options(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RC4_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ripemd.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ripemd.h new file mode 100644 index 00000000..090fcb31 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ripemd.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_RIPEMD_H +#define OPENSSL_HEADER_RIPEMD_H + +#include "CNIOBoringSSL_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +struct RIPEMD160state_st { + uint32_t h[5]; + uint32_t Nl, Nh; + uint8_t data[RIPEMD160_CBLOCK]; + unsigned num; +}; + +// RIPEMD160_Init initialises |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Init(RIPEMD160_CTX *ctx); + +// RIPEMD160_Update adds |len| bytes from |data| to |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data, + size_t len); + +// RIPEMD160_Final adds the final padding to |ctx| and writes the resulting +// digest to |out|, which must have at least |RIPEMD160_DIGEST_LENGTH| bytes of +// space. It returns one. +OPENSSL_EXPORT int RIPEMD160_Final(uint8_t out[RIPEMD160_DIGEST_LENGTH], + RIPEMD160_CTX *ctx); + +// RIPEMD160 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |RIPEMD160_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *RIPEMD160(const uint8_t *data, size_t len, + uint8_t out[RIPEMD160_DIGEST_LENGTH]); + +// RIPEMD160_Transform is a low-level function that performs a single, +// RIPEMD160 block transformation using the state from |ctx| and 64 bytes from +// |block|. +OPENSSL_EXPORT void RIPEMD160_Transform(RIPEMD160_CTX *ctx, + const uint8_t block[RIPEMD160_CBLOCK]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RIPEMD_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h new file mode 100644 index 00000000..e6966cbf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h @@ -0,0 +1,858 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_RSA_H +#define OPENSSL_HEADER_RSA_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_engine.h" +#include "CNIOBoringSSL_ex_data.h" +#include "CNIOBoringSSL_thread.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// rsa.h contains functions for handling encryption and signature using RSA. + + +// Allocation and destruction. +// +// An |RSA| object represents a public or private RSA key. A given object may be +// used concurrently on multiple threads by non-mutating functions, provided no +// other thread is concurrently calling a mutating function. Unless otherwise +// documented, functions which take a |const| pointer are non-mutating and +// functions which take a non-|const| pointer are mutating. + +// RSA_new returns a new, empty |RSA| object or NULL on error. +OPENSSL_EXPORT RSA *RSA_new(void); + +// RSA_new_method acts the same as |RSA_new| but takes an explicit |ENGINE|. +OPENSSL_EXPORT RSA *RSA_new_method(const ENGINE *engine); + +// RSA_free decrements the reference count of |rsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void RSA_free(RSA *rsa); + +// RSA_up_ref increments the reference count of |rsa| and returns one. It does +// not mutate |rsa| for thread-safety purposes and may be used concurrently. +OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); + + +// Properties. + +// RSA_bits returns the size of |rsa|, in bits. +OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); + +// RSA_get0_n returns |rsa|'s public modulus. +OPENSSL_EXPORT const BIGNUM *RSA_get0_n(const RSA *rsa); + +// RSA_get0_e returns |rsa|'s public exponent. +OPENSSL_EXPORT const BIGNUM *RSA_get0_e(const RSA *rsa); + +// RSA_get0_d returns |rsa|'s private exponent. If |rsa| is a public key, this +// value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_d(const RSA *rsa); + +// RSA_get0_p returns |rsa|'s first private prime factor. If |rsa| is a public +// key or lacks its prime factors, this value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_p(const RSA *rsa); + +// RSA_get0_q returns |rsa|'s second private prime factor. If |rsa| is a public +// key or lacks its prime factors, this value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_q(const RSA *rsa); + +// RSA_get0_dmp1 returns d (mod p-1) for |rsa|. If |rsa| is a public key or +// lacks CRT parameters, this value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_dmp1(const RSA *rsa); + +// RSA_get0_dmq1 returns d (mod q-1) for |rsa|. If |rsa| is a public key or +// lacks CRT parameters, this value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_dmq1(const RSA *rsa); + +// RSA_get0_iqmp returns q^-1 (mod p). If |rsa| is a public key or lacks CRT +// parameters, this value will be NULL. +OPENSSL_EXPORT const BIGNUM *RSA_get0_iqmp(const RSA *rsa); + +// RSA_get0_key sets |*out_n|, |*out_e|, and |*out_d|, if non-NULL, to |rsa|'s +// modulus, public exponent, and private exponent, respectively. If |rsa| is a +// public key, the private exponent will be set to NULL. +OPENSSL_EXPORT void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, + const BIGNUM **out_e, const BIGNUM **out_d); + +// RSA_get0_factors sets |*out_p| and |*out_q|, if non-NULL, to |rsa|'s prime +// factors. If |rsa| is a public key, they will be set to NULL. +OPENSSL_EXPORT void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q); + +// RSA_get0_crt_params sets |*out_dmp1|, |*out_dmq1|, and |*out_iqmp|, if +// non-NULL, to |rsa|'s CRT parameters. These are d (mod p-1), d (mod q-1) and +// q^-1 (mod p), respectively. If |rsa| is a public key, each parameter will be +// set to NULL. +OPENSSL_EXPORT void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, + const BIGNUM **out_iqmp); + +// RSA_set0_key sets |rsa|'s modulus, public exponent, and private exponent to +// |n|, |e|, and |d| respectively, if non-NULL. On success, it takes ownership +// of each argument and returns one. Otherwise, it returns zero. +// +// |d| may be NULL, but |n| and |e| must either be non-NULL or already +// configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d); + +// RSA_set0_factors sets |rsa|'s prime factors to |p| and |q|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q); + +// RSA_set0_crt_params sets |rsa|'s CRT parameters to |dmp1|, |dmq1|, and +// |iqmp|, if non-NULL, and takes ownership of them. On success, it takes +// ownership of its parameters and returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, + BIGNUM *iqmp); + + +// Key generation. + +// RSA_generate_key_ex generates a new RSA key where the modulus has size +// |bits| and the public exponent is |e|. If unsure, |RSA_F4| is a good value +// for |e|. If |cb| is not NULL then it is called during the key generation +// process. In addition to the calls documented for |BN_generate_prime_ex|, it +// is called with event=2 when the n'th prime is rejected as unsuitable and +// with event=3 when a suitable value for |p| is found. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb); + +// RSA_generate_key_fips behaves like |RSA_generate_key_ex| but performs +// additional checks for FIPS compliance. The public exponent is always 65537 +// and |bits| must be either 2048 or 3072. +OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); + + +// Encryption / Decryption +// +// These functions are considered non-mutating for thread-safety purposes and +// may be used concurrently. + +// RSA_PKCS1_PADDING denotes PKCS#1 v1.5 padding. When used with encryption, +// this is RSAES-PKCS1-v1_5. When used with signing, this is RSASSA-PKCS1-v1_5. +#define RSA_PKCS1_PADDING 1 + +// RSA_NO_PADDING denotes a raw RSA operation. +#define RSA_NO_PADDING 3 + +// RSA_PKCS1_OAEP_PADDING denotes the RSAES-OAEP encryption scheme. +#define RSA_PKCS1_OAEP_PADDING 4 + +// RSA_PKCS1_PSS_PADDING denotes the RSASSA-PSS signature scheme. This value may +// not be passed into |RSA_sign_raw|, only |EVP_PKEY_CTX_set_rsa_padding|. See +// also |RSA_sign_pss_mgf1| and |RSA_verify_pss_mgf1|. +#define RSA_PKCS1_PSS_PADDING 6 + +// RSA_encrypt encrypts |in_len| bytes from |in| to the public key from |rsa| +// and writes, at most, |max_out| bytes of encrypted data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_decrypt decrypts |in_len| bytes from |in| with the private key from +// |rsa| and writes, at most, |max_out| bytes of plaintext to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// +// Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If +// implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then +// check padding in constant-time combined with a swap to a random session key +// or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based +// on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in +// Cryptology (Crypto '98). +OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_public_encrypt encrypts |flen| bytes from |from| to the public key in +// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at +// least |RSA_size| bytes of space. It returns the number of bytes written, or +// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| +// values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_encrypt| instead. +OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in +// |rsa| and writes the plaintext to |to|. The |to| buffer must have at least +// |RSA_size| bytes of space. It returns the number of bytes written, or -1 on +// error. The |padding| argument must be one of the |RSA_*_PADDING| values. If +// in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. Passing +// |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See +// |RSA_decrypt|. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_decrypt| instead. +OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Signing / Verification +// +// These functions are considered non-mutating for thread-safety purposes and +// may be used concurrently. + +// RSA_sign signs |digest_len| bytes of digest from |digest| with |rsa| using +// RSASSA-PKCS1-v1_5. It writes, at most, |RSA_size(rsa)| bytes to |out|. On +// successful return, the actual number of bytes written is written to +// |*out_len|. +// +// The |hash_nid| argument identifies the hash function used to calculate +// |digest| and is embedded in the resulting signature. For example, it might be +// |NID_sha256|. +// +// It returns 1 on success and zero on error. +// +// WARNING: |digest| must be the result of hashing the data to be signed with +// |hash_nid|. Passing unhashed inputs will not result in a secure signature +// scheme. +OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, + unsigned digest_len, uint8_t *out, + unsigned *out_len, RSA *rsa); + +// RSA_sign_pss_mgf1 signs |digest_len| bytes from |digest| with the public key +// from |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It +// writes, at most, |max_out| bytes of signature data to |out|. The |max_out| +// argument must be, at least, |RSA_size| in order to ensure success. It returns +// 1 on success or zero on error. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |digest| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. +// +// |salt_len| specifies the expected salt length in bytes. If |salt_len| is -1, +// then the salt length is the same as the hash length. If -2, then the salt +// length is maximal given the size of |rsa|. If unsure, use -1. +// +// WARNING: |digest| must be the result of hashing the data to be signed with +// |md|. Passing unhashed inputs will not result in a secure signature scheme. +OPENSSL_EXPORT int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *digest, + size_t digest_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len); + +// RSA_sign_raw performs the private key portion of computing a signature with +// |rsa|. It writes, at most, |max_out| bytes of signature data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure the +// output fits. It returns 1 on success or zero on error. +// +// If |padding| is |RSA_PKCS1_PADDING|, this function wraps |in| with the +// padding portion of RSASSA-PKCS1-v1_5 and then performs the raw private key +// operation. The caller is responsible for hashing the input and wrapping it in +// a DigestInfo structure. +// +// If |padding| is |RSA_NO_PADDING|, this function only performs the raw private +// key operation, interpreting |in| as a integer modulo n. The caller is +// responsible for hashing the input and encoding it for the signature scheme +// being implemented. +// +// WARNING: This function is a building block for a signature scheme, not a +// complete one. |in| must be the result of hashing and encoding the data as +// needed for the scheme being implemented. Passing in arbitrary inputs will not +// result in a secure signature scheme. +OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_verify verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PKCS1-v1_5 signature of |digest_len| bytes at |digest| by |rsa|. +// +// The |hash_nid| argument identifies the hash function used to calculate +// |digest| and is embedded in the resulting signature in order to prevent hash +// confusion attacks. For example, it might be |NID_sha256|. +// +// It returns one if the signature is valid and zero otherwise. +// +// WARNING: this differs from the original, OpenSSL function which additionally +// returned -1 on error. +// +// WARNING: |digest| must be the result of hashing the data to be verified with +// |hash_nid|. Passing unhashed input will not result in a secure signature +// scheme. +OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, RSA *rsa); + +// RSA_verify_pss_mgf1 verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PSS signature of |digest_len| bytes at |digest| by |rsa|. It returns +// one if the signature is valid and zero otherwise. MGF1 is used as the mask +// generation function. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |digest| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. |salt_len| specifies the expected salt length in bytes. +// +// If |salt_len| is -1, then the salt length is the same as the hash length. If +// -2, then the salt length is recovered and all values accepted. If unsure, use +// -1. +// +// WARNING: |digest| must be the result of hashing the data to be verified with +// |md|. Passing unhashed input will not result in a secure signature scheme. +OPENSSL_EXPORT int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, + size_t digest_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len); + +// RSA_verify_raw performs the public key portion of verifying |in_len| bytes of +// signature from |in| using the public key from |rsa|. On success, it returns +// one and writes, at most, |max_out| bytes of output to |out|. The |max_out| +// argument must be, at least, |RSA_size| in order to ensure the output fits. On +// failure or invalid input, it returns zero. +// +// If |padding| is |RSA_PKCS1_PADDING|, this function checks the padding portion +// of RSASSA-PKCS1-v1_5 and outputs the remainder of the encoded digest. The +// caller is responsible for checking the output is a DigestInfo-wrapped digest +// of the message. +// +// If |padding| is |RSA_NO_PADDING|, this function only performs the raw public +// key operation. The caller is responsible for checking the output is a valid +// result for the signature scheme being implemented. +// +// WARNING: This function is a building block for a signature scheme, not a +// complete one. Checking for arbitrary strings in |out| will not result in a +// secure signature scheme. +OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_private_encrypt performs the private key portion of computing a signature +// with |rsa|. It takes |flen| bytes from |from| as input and writes the result +// to |to|. The |to| buffer must have at least |RSA_size| bytes of space. It +// returns the number of bytes written, or -1 on error. +// +// For the interpretation of |padding| and the input, see |RSA_sign_raw|. +// +// WARNING: This function is a building block for a signature scheme, not a +// complete one. See |RSA_sign_raw| for details. +// +// WARNING: This function is dangerous because it breaks the usual return value +// convention. Use |RSA_sign_raw| instead. +OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_public_decrypt performs the public key portion of verifying |flen| bytes +// of signature from |from| using the public key from |rsa|. It writes the +// result to |to|, which must have at least |RSA_size| bytes of space. It +// returns the number of bytes written, or -1 on error. +// +// For the interpretation of |padding| and the result, see |RSA_verify_raw|. +// +// WARNING: This function is a building block for a signature scheme, not a +// complete one. See |RSA_verify_raw| for details. +// +// WARNING: This function is dangerous because it breaks the usual return value +// convention. Use |RSA_verify_raw| instead. +OPENSSL_EXPORT int RSA_public_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Utility functions. + +// RSA_size returns the number of bytes in the modulus, which is also the size +// of a signature or encrypted value using |rsa|. +OPENSSL_EXPORT unsigned RSA_size(const RSA *rsa); + +// RSA_is_opaque returns one if |rsa| is opaque and doesn't expose its key +// material. Otherwise it returns zero. +OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa); + +// RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa); + +// RSAPrivateKey_dup allocates a fresh |RSA| and copies the private key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPrivateKey_dup(const RSA *rsa); + +// RSA_check_key performs basic validity tests on |rsa|. It returns one if +// they pass and zero otherwise. Opaque keys and public keys always pass. If it +// returns zero then a more detailed error is available on the error queue. +OPENSSL_EXPORT int RSA_check_key(const RSA *rsa); + +// RSA_check_fips performs public key validity tests on |key|. It returns one if +// they pass and zero otherwise. Opaque keys always fail. This function does not +// mutate |rsa| for thread-safety purposes and may be used concurrently. +OPENSSL_EXPORT int RSA_check_fips(RSA *key); + +// RSA_verify_PKCS1_PSS_mgf1 verifies that |EM| is a correct PSS padding of +// |mHash|, where |mHash| is a digest produced by |Hash|. |EM| must point to +// exactly |RSA_size(rsa)| bytes of data. The |mgf1Hash| argument specifies the +// hash function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is recovered and all values accepted. +// +// If unsure, use -1. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, + const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen); + +// RSA_padding_add_PKCS1_PSS_mgf1 writes a PSS padding of |mHash| to |EM|, +// where |mHash| is a digest produced by |Hash|. |RSA_size(rsa)| bytes of +// output will be written to |EM|. The |mgf1Hash| argument specifies the hash +// function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is maximal given the space in |EM|. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + int sLen); + +// RSA_padding_add_PKCS1_OAEP_mgf1 writes an OAEP padding of |from| to |to| +// with the given parameters and hash functions. If |md| is NULL then SHA-1 is +// used. If |mgf1md| is NULL then the value of |md| is used (which means SHA-1 +// if that, in turn, is NULL). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP_mgf1( + uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); + +// RSA_add_pkcs1_prefix builds a version of |digest| prefixed with the +// DigestInfo header for the given hash function and sets |out_msg| to point to +// it. On successful return, if |*is_alloced| is one, the caller must release +// |*out_msg| with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, + const uint8_t *digest, + size_t digest_len); + + +// ASN.1 functions. + +// RSA_parse_public_key parses a DER-encoded RSAPublicKey structure (RFC 8017) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_public_key(CBS *cbs); + +// RSA_public_key_from_bytes parses |in| as a DER-encoded RSAPublicKey structure +// (RFC 8017). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len); + +// RSA_marshal_public_key marshals |rsa| as a DER-encoded RSAPublicKey structure +// (RFC 8017) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa); + +// RSA_public_key_to_bytes marshals |rsa| as a DER-encoded RSAPublicKey +// structure (RFC 8017) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa); + +// RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 8017) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs); + +// RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey +// structure (RFC 8017). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in, + size_t in_len); + +// RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 8017) and appends the result to |cbb|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa); + +// RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 8017) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes, + size_t *out_len, const RSA *rsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int RSA_set_ex_data(RSA *rsa, int idx, void *arg); +OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx); + + +// Flags. + +// RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define RSA_FLAG_OPAQUE 1 + +// RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a +// dangerous thing to do. It is deprecated and should not be used. It will +// be ignored whenever possible. +// +// This flag must be used if a key without the public exponent |e| is used for +// private key operations; avoid using such keys whenever possible. +#define RSA_FLAG_NO_BLINDING 8 + +// RSA_FLAG_EXT_PKEY is deprecated and ignored. +#define RSA_FLAG_EXT_PKEY 0x20 + + +// RSA public exponent values. + +#define RSA_3 0x3 +#define RSA_F4 0x10001 + + +// Deprecated functions. + +#define RSA_METHOD_FLAG_NO_CHECK RSA_FLAG_OPAQUE + +// RSA_flags returns the flags for |rsa|. These are a bitwise OR of |RSA_FLAG_*| +// constants. +OPENSSL_EXPORT int RSA_flags(const RSA *rsa); + +// RSA_test_flags returns the subset of flags in |flags| which are set in |rsa|. +OPENSSL_EXPORT int RSA_test_flags(const RSA *rsa, int flags); + +// RSA_blinding_on returns one. +OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); + +// RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you +// should use instead. It returns NULL on error, or a newly-allocated |RSA| on +// success. This function is provided for compatibility only. The |callback| +// and |cb_arg| parameters must be NULL. +OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback, + void *cb_arg); + +// d2i_RSAPublicKey parses a DER-encoded RSAPublicKey structure (RFC 8017) from +// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// +// Use |RSA_parse_public_key| instead. +OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPublicKey marshals |in| to a DER-encoded RSAPublicKey structure (RFC +// 8017), as described in |i2d_SAMPLE|. +// +// Use |RSA_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp); + +// d2i_RSAPrivateKey parses a DER-encoded RSAPrivateKey structure (RFC 8017) +// from |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// +// Use |RSA_parse_private_key| instead. +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPrivateKey marshals |in| to a DER-encoded RSAPrivateKey structure (RFC +// 8017), as described in |i2d_SAMPLE|. +// +// Use |RSA_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp); + +// RSA_padding_add_PKCS1_PSS acts like |RSA_padding_add_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS(const RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, int sLen); + +// RSA_verify_PKCS1_PSS acts like |RSA_verify_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS(const RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const uint8_t *EM, + int sLen); + +// RSA_padding_add_PKCS1_OAEP acts like |RSA_padding_add_PKCS1_OAEP_mgf1| but +// the |md| and |mgf1md| parameters of the latter are implicitly set to NULL, +// which means SHA-1. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, + const uint8_t *from, + size_t from_len, + const uint8_t *param, + size_t param_len); + +// RSA_print prints a textual representation of |rsa| to |bio|. It returns one +// on success or zero otherwise. +OPENSSL_EXPORT int RSA_print(BIO *bio, const RSA *rsa, int indent); + +// RSA_get0_pss_params returns NULL. In OpenSSL, this function retries RSA-PSS +// parameters associated with |RSA| objects, but BoringSSL does not support +// the id-RSASSA-PSS key encoding. +OPENSSL_EXPORT const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa); + + +struct rsa_meth_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(RSA *rsa); + int (*finish)(RSA *rsa); + + // size returns the size of the RSA modulus in bytes. + size_t (*size)(const RSA *rsa); + + int (*sign)(int type, const uint8_t *m, unsigned int m_length, + uint8_t *sigret, unsigned int *siglen, const RSA *rsa); + + // These functions mirror the |RSA_*| functions of the same name. + int (*sign_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + + // private_transform takes a big-endian integer from |in|, calculates the + // d'th power of it, modulo the RSA modulus and writes the result as a + // big-endian integer to |out|. Both |in| and |out| are |len| bytes long and + // |len| is always equal to |RSA_size(rsa)|. If the result of the transform + // can be represented in fewer than |len| bytes, then |out| must be zero + // padded on the left. + // + // It returns one on success and zero otherwise. + // + // RSA decrypt and sign operations will call this, thus an ENGINE might wish + // to override it in order to avoid having to implement the padding + // functionality demanded by those, higher level, operations. + int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + int flags; +}; + + +// Private functions. + +typedef struct bn_blinding_st BN_BLINDING; + +struct rsa_st { + RSA_METHOD *meth; + + // Access to the following fields was historically allowed, but + // deprecated. Use |RSA_get0_*| and |RSA_set0_*| instead. Access to all other + // fields is forbidden and will cause threading errors. + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + + // be careful using this if the RSA structure is shared + CRYPTO_EX_DATA ex_data; + CRYPTO_refcount_t references; + int flags; + + CRYPTO_MUTEX lock; + + // Used to cache montgomery values. The creation of these values is protected + // by |lock|. + BN_MONT_CTX *mont_n; + BN_MONT_CTX *mont_p; + BN_MONT_CTX *mont_q; + + // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, + // but with the correct widths to prevent side channels. These must use + // separate copies due to threading concerns caused by OpenSSL's API + // mistakes. See https://github.com/openssl/openssl/issues/5158 and + // the |freeze_private_key| implementation. + BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; + + // inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|, + // if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using + // |mont_q|. + BIGNUM *inv_small_mod_large_mont; + + // num_blindings contains the size of the |blindings| and |blindings_inuse| + // arrays. This member and the |blindings_inuse| array are protected by + // |lock|. + unsigned num_blindings; + // blindings is an array of BN_BLINDING structures that can be reserved by a + // thread by locking |lock| and changing the corresponding element in + // |blindings_inuse| from 0 to 1. + BN_BLINDING **blindings; + unsigned char *blindings_inuse; + uint64_t blinding_fork_generation; + + // private_key_frozen is one if the key has been used for a private key + // operation and may no longer be mutated. + unsigned private_key_frozen:1; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(RSA, RSA_free) +BORINGSSL_MAKE_UP_REF(RSA, RSA_up_ref) + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif + +#define RSA_R_BAD_ENCODING 100 +#define RSA_R_BAD_E_VALUE 101 +#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +#define RSA_R_BAD_PAD_BYTE_COUNT 103 +#define RSA_R_BAD_RSA_PARAMETERS 104 +#define RSA_R_BAD_SIGNATURE 105 +#define RSA_R_BAD_VERSION 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 107 +#define RSA_R_BN_NOT_INITIALIZED 108 +#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 109 +#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 110 +#define RSA_R_CRT_VALUES_INCORRECT 111 +#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 112 +#define RSA_R_DATA_TOO_LARGE 113 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 114 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 115 +#define RSA_R_DATA_TOO_SMALL 116 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 117 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 118 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 119 +#define RSA_R_EMPTY_PUBLIC_KEY 120 +#define RSA_R_ENCODE_ERROR 121 +#define RSA_R_FIRST_OCTET_INVALID 122 +#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 123 +#define RSA_R_INTERNAL_ERROR 124 +#define RSA_R_INVALID_MESSAGE_LENGTH 125 +#define RSA_R_KEY_SIZE_TOO_SMALL 126 +#define RSA_R_LAST_OCTET_INVALID 127 +#define RSA_R_MODULUS_TOO_LARGE 128 +#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 129 +#define RSA_R_NO_PUBLIC_EXPONENT 130 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 131 +#define RSA_R_N_NOT_EQUAL_P_Q 132 +#define RSA_R_OAEP_DECODING_ERROR 133 +#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 134 +#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 135 +#define RSA_R_PADDING_CHECK_FAILED 136 +#define RSA_R_PKCS_DECODING_ERROR 137 +#define RSA_R_SLEN_CHECK_FAILED 138 +#define RSA_R_SLEN_RECOVERY_FAILED 139 +#define RSA_R_TOO_LONG 140 +#define RSA_R_TOO_MANY_ITERATIONS 141 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 142 +#define RSA_R_UNKNOWN_PADDING_TYPE 143 +#define RSA_R_VALUE_MISSING 144 +#define RSA_R_WRONG_SIGNATURE_LENGTH 145 +#define RSA_R_PUBLIC_KEY_VALIDATION_FAILED 146 +#define RSA_R_D_OUT_OF_RANGE 147 +#define RSA_R_BLOCK_TYPE_IS_NOT_02 148 + +#endif // OPENSSL_HEADER_RSA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_safestack.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_safestack.h new file mode 100644 index 00000000..6e5e4330 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_safestack.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_sha.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_sha.h new file mode 100644 index 00000000..4f2b7a1a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_sha.h @@ -0,0 +1,294 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_SHA_H +#define OPENSSL_HEADER_SHA_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The SHA family of hash functions (SHA-1 and SHA-2). + + +// SHA_CBLOCK is the block size of SHA-1. +#define SHA_CBLOCK 64 + +// SHA_DIGEST_LENGTH is the length of a SHA-1 digest. +#define SHA_DIGEST_LENGTH 20 + +// SHA1_Init initialises |sha| and returns one. +OPENSSL_EXPORT int SHA1_Init(SHA_CTX *sha); + +// SHA1_Update adds |len| bytes from |data| to |sha| and returns one. +OPENSSL_EXPORT int SHA1_Update(SHA_CTX *sha, const void *data, size_t len); + +// SHA1_Final adds the final padding to |sha| and writes the resulting digest to +// |out|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int SHA1_Final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *sha); + +// SHA1 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, + uint8_t out[SHA_DIGEST_LENGTH]); + +// SHA1_Transform is a low-level function that performs a single, SHA-1 block +// transformation using the state from |sha| and |SHA_CBLOCK| bytes from +// |block|. +OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, + const uint8_t block[SHA_CBLOCK]); + +struct sha_state_st { +#if defined(OPENSSL_WINDOWS) + uint32_t h[5]; +#else + // wpa_supplicant accesses |h0|..|h4| so we must support those names + // for compatibility with it until it can be updated. + union { + uint32_t h[5]; + struct { + uint32_t h0; + uint32_t h1; + uint32_t h2; + uint32_t h3; + uint32_t h4; + }; + }; +#endif + uint32_t Nl, Nh; + uint8_t data[SHA_CBLOCK]; + unsigned num; +}; + + +// SHA-224. + +// SHA224_CBLOCK is the block size of SHA-224. +#define SHA224_CBLOCK 64 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define SHA224_DIGEST_LENGTH 28 + +// SHA224_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); + +// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA224_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA224 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, + uint8_t out[SHA224_DIGEST_LENGTH]); + + +// SHA-256. + +// SHA256_CBLOCK is the block size of SHA-256. +#define SHA256_CBLOCK 64 + +// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define SHA256_DIGEST_LENGTH 32 + +// SHA256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); + +// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA256_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, + uint8_t out[SHA256_DIGEST_LENGTH]); + +// SHA256_Transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, + const uint8_t block[SHA256_CBLOCK]); + +// SHA256_TransformBlocks is a low-level function that takes |num_blocks| * +// |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update +// |state|. You should not use this function unless you are implementing a +// derivative of SHA-256. +OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], + const uint8_t *data, + size_t num_blocks); + +struct sha256_state_st { + uint32_t h[8]; + uint32_t Nl, Nh; + uint8_t data[SHA256_CBLOCK]; + unsigned num, md_len; +}; + + +// SHA-384. + +// SHA384_CBLOCK is the block size of SHA-384. +#define SHA384_CBLOCK 128 + +// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define SHA384_DIGEST_LENGTH 48 + +// SHA384_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); + +// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA384_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA384 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, + uint8_t out[SHA384_DIGEST_LENGTH]); + + +// SHA-512. + +// SHA512_CBLOCK is the block size of SHA-512. +#define SHA512_CBLOCK 128 + +// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define SHA512_DIGEST_LENGTH 64 + +// SHA512_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); + +// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA512_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, + uint8_t out[SHA512_DIGEST_LENGTH]); + +// SHA512_Transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, + const uint8_t block[SHA512_CBLOCK]); + +struct sha512_state_st { + uint64_t h[8]; + uint64_t Nl, Nh; + uint8_t p[128]; + unsigned num, md_len; +}; + + +// SHA-512-256 +// +// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 + +#define SHA512_256_DIGEST_LENGTH 32 + +// SHA512_256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha); + +// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data, + size_t len); + +// SHA512_256_Final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of +// space. It returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len, + uint8_t out[SHA512_256_DIGEST_LENGTH]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SHA_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_siphash.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_siphash.h new file mode 100644 index 00000000..26c119a4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_siphash.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2019, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SIPHASH_H +#define OPENSSL_HEADER_SIPHASH_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SipHash is a fast, secure PRF that is often used for hash tables. + + +// SIPHASH_24 implements SipHash-2-4. See https://131002.net/siphash/siphash.pdf +OPENSSL_EXPORT uint64_t SIPHASH_24(const uint64_t key[2], const uint8_t *input, + size_t input_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SIPHASH_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_span.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_span.h new file mode 100644 index 00000000..b7abab91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_span.h @@ -0,0 +1,214 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SSL_SPAN_H +#define OPENSSL_HEADER_SSL_SPAN_H + +#include "CNIOBoringSSL_base.h" + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +#include + +#include +#include + +BSSL_NAMESPACE_BEGIN + +template +class Span; + +namespace internal { +template +class SpanBase { + // Put comparison operator implementations into a base class with const T, so + // they can be used with any type that implicitly converts into a Span. + static_assert(std::is_const::value, + "Span must be derived from SpanBase"); + + friend bool operator==(Span lhs, Span rhs) { + // MSVC issues warning C4996 because std::equal is unsafe. The pragma to + // suppress the warning mysteriously has no effect, hence this + // implementation. See + // https://msdn.microsoft.com/en-us/library/aa985974.aspx. + if (lhs.size() != rhs.size()) { + return false; + } + for (T *l = lhs.begin(), *r = rhs.begin(); l != lhs.end() && r != rhs.end(); + ++l, ++r) { + if (*l != *r) { + return false; + } + } + return true; + } + + friend bool operator!=(Span lhs, Span rhs) { return !(lhs == rhs); } +}; +} // namespace internal + +// A Span is a non-owning reference to a contiguous array of objects of type +// |T|. Conceptually, a Span is a simple a pointer to |T| and a count of +// elements accessible via that pointer. The elements referenced by the Span can +// be mutated if |T| is mutable. +// +// A Span can be constructed from container types implementing |data()| and +// |size()| methods. If |T| is constant, construction from a container type is +// implicit. This allows writing methods that accept data from some unspecified +// container type: +// +// // Foo views data referenced by v. +// void Foo(bssl::Span v) { ... } +// +// std::vector vec; +// Foo(vec); +// +// For mutable Spans, conversion is explicit: +// +// // FooMutate mutates data referenced by v. +// void FooMutate(bssl::Span v) { ... } +// +// FooMutate(bssl::Span(vec)); +// +// You can also use the |MakeSpan| and |MakeConstSpan| factory methods to +// construct Spans in order to deduce the type of the Span automatically. +// +// FooMutate(bssl::MakeSpan(vec)); +// +// Note that Spans have value type sematics. They are cheap to construct and +// copy, and should be passed by value whenever a method would otherwise accept +// a reference or pointer to a container or array. +template +class Span : private internal::SpanBase { + private: + static const size_t npos = static_cast(-1); + + // Heuristically test whether C is a container type that can be converted into + // a Span by checking for data() and size() member functions. + // + // TODO(davidben): Require C++17 support for std::is_convertible_v, etc. + template + using EnableIfContainer = std::enable_if_t< + std::is_convertible().data()), T *>::value && + std::is_integral().size())>::value>; + + public: + constexpr Span() : Span(nullptr, 0) {} + constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {} + + template + constexpr Span(T (&array)[N]) : Span(array, N) {} + + template , + typename = std::enable_if_t::value, C>> + Span(const C &container) : data_(container.data()), size_(container.size()) {} + + template , + typename = std::enable_if_t::value, C>> + explicit Span(C &container) + : data_(container.data()), size_(container.size()) {} + + T *data() const { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + T *begin() const { return data_; } + const T *cbegin() const { return data_; } + T *end() const { return data_ + size_; } + const T *cend() const { return end(); } + + T &front() const { + if (size_ == 0) { + abort(); + } + return data_[0]; + } + T &back() const { + if (size_ == 0) { + abort(); + } + return data_[size_ - 1]; + } + + T &operator[](size_t i) const { + if (i >= size_) { + abort(); + } + return data_[i]; + } + T &at(size_t i) const { return (*this)[i]; } + + Span subspan(size_t pos = 0, size_t len = npos) const { + if (pos > size_) { + // absl::Span throws an exception here. Note std::span and Chromium + // base::span additionally forbid pos + len being out of range, with a + // special case at npos/dynamic_extent, while absl::Span::subspan clips + // the span. For now, we align with absl::Span in case we switch to it in + // the future. + abort(); + } + return Span(data_ + pos, std::min(size_ - pos, len)); + } + + Span first(size_t len) { + if (len > size_) { + abort(); + } + return Span(data_, len); + } + + Span last(size_t len) { + if (len > size_) { + abort(); + } + return Span(data_ + size_ - len, len); + } + + private: + T *data_; + size_t size_; +}; + +template +const size_t Span::npos; + +template +Span MakeSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) { + return MakeSpan(c.data(), c.size()); +} + +template +Span MakeConstSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) { + return MakeConstSpan(c.data(), c.size()); +} + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif // OPENSSL_HEADER_SSL_SPAN_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_srtp.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_srtp.h new file mode 100644 index 00000000..65c49d1d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_srtp.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_ssl.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h new file mode 100644 index 00000000..ed5058bf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h @@ -0,0 +1,5644 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef OPENSSL_HEADER_SSL_H +#define OPENSSL_HEADER_SSL_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_buf.h" +#include "CNIOBoringSSL_pem.h" +#include "CNIOBoringSSL_span.h" +#include "CNIOBoringSSL_ssl3.h" +#include "CNIOBoringSSL_thread.h" +#include "CNIOBoringSSL_tls1.h" +#include "CNIOBoringSSL_x509.h" + +#if !defined(OPENSSL_WINDOWS) +#include +#endif + +// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has +// been out for a year or so (assuming that they fix it in that release.) See +// https://boringssl-review.googlesource.com/c/boringssl/+/21664. +#include "CNIOBoringSSL_hmac.h" + +// Forward-declare struct timeval. On Windows, it is defined in winsock2.h and +// Windows headers define too many macros to be included in public headers. +// However, only a forward declaration is needed. +struct timeval; + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SSL implementation. + + +// SSL contexts. +// +// |SSL_CTX| objects manage shared state and configuration between multiple TLS +// or DTLS connections. Whether the connections are TLS or DTLS is selected by +// an |SSL_METHOD| on creation. +// +// |SSL_CTX| are reference-counted and may be shared by connections across +// multiple threads. Once shared, functions which change the |SSL_CTX|'s +// configuration may not be used. + +// TLS_method is the |SSL_METHOD| used for TLS connections. +OPENSSL_EXPORT const SSL_METHOD *TLS_method(void); + +// DTLS_method is the |SSL_METHOD| used for DTLS connections. +OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); + +// TLS_with_buffers_method is like |TLS_method|, but avoids all use of +// crypto/x509. All client connections created with |TLS_with_buffers_method| +// will fail unless a certificate verifier is installed with +// |SSL_set_custom_verify| or |SSL_CTX_set_custom_verify|. +OPENSSL_EXPORT const SSL_METHOD *TLS_with_buffers_method(void); + +// DTLS_with_buffers_method is like |DTLS_method|, but avoids all use of +// crypto/x509. +OPENSSL_EXPORT const SSL_METHOD *DTLS_with_buffers_method(void); + +// SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL +// on error. +OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); + +// SSL_CTX_up_ref increments the reference count of |ctx|. It returns one. +OPENSSL_EXPORT int SSL_CTX_up_ref(SSL_CTX *ctx); + +// SSL_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx); + + +// SSL connections. +// +// An |SSL| object represents a single TLS or DTLS connection. Although the +// shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be +// used on one thread at a time. + +// SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new +// connection inherits settings from |ctx| at the time of creation. Settings may +// also be individually configured on the connection. +// +// On creation, an |SSL| is not configured to be either a client or server. Call +// |SSL_set_connect_state| or |SSL_set_accept_state| to set this. +OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx); + +// SSL_free releases memory associated with |ssl|. +OPENSSL_EXPORT void SSL_free(SSL *ssl); + +// SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If +// |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial +// one. +OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +// SSL_set_connect_state configures |ssl| to be a client. +OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl); + +// SSL_set_accept_state configures |ssl| to be a server. +OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl); + +// SSL_is_server returns one if |ssl| is configured as a server and zero +// otherwise. +OPENSSL_EXPORT int SSL_is_server(const SSL *ssl); + +// SSL_is_dtls returns one if |ssl| is a DTLS connection and zero otherwise. +OPENSSL_EXPORT int SSL_is_dtls(const SSL *ssl); + +// SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl| +// takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl| +// only takes ownership of one reference. +// +// In DTLS, |rbio| must be non-blocking to properly handle timeouts and +// retransmits. +// +// If |rbio| is the same as the currently configured |BIO| for reading, that +// side is left untouched and is not freed. +// +// If |wbio| is the same as the currently configured |BIO| for writing AND |ssl| +// is not currently configured to read from and write to the same |BIO|, that +// side is left untouched and is not freed. This asymmetry is present for +// historical reasons. +// +// Due to the very complex historical behavior of this function, calling this +// function if |ssl| already has |BIO|s configured is deprecated. Prefer +// |SSL_set0_rbio| and |SSL_set0_wbio| instead. +OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +// SSL_set0_rbio configures |ssl| to read from |rbio|. It takes ownership of +// |rbio|. +// +// Note that, although this function and |SSL_set0_wbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_rbio(SSL *ssl, BIO *rbio); + +// SSL_set0_wbio configures |ssl| to write to |wbio|. It takes ownership of +// |wbio|. +// +// Note that, although this function and |SSL_set0_rbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_wbio(SSL *ssl, BIO *wbio); + +// SSL_get_rbio returns the |BIO| that |ssl| reads from. +OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl); + +// SSL_get_wbio returns the |BIO| that |ssl| writes to. +OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl); + +// SSL_get_fd calls |SSL_get_rfd|. +OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl); + +// SSL_get_rfd returns the file descriptor that |ssl| is configured to read +// from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl); + +// SSL_get_wfd returns the file descriptor that |ssl| is configured to write +// to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl); + +// SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one +// on success and zero on allocation error. The caller retains ownership of +// |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd); + +// SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd); + +// SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd); + +// SSL_do_handshake continues the current handshake. If there is none or the +// handshake has completed or False Started, it returns one. Otherwise, it +// returns <= 0. The caller should pass the value into |SSL_get_error| to +// determine how to proceed. +// +// In DTLS, the caller must drive retransmissions. Whenever |SSL_get_error| +// signals |SSL_ERROR_WANT_READ|, use |DTLSv1_get_timeout| to determine the +// current timeout. If it expires before the next retry, call +// |DTLSv1_handle_timeout|. Note that DTLS handshake retransmissions use fresh +// sequence numbers, so it is not sufficient to replay packets at the transport. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl); + +// SSL_connect configures |ssl| as a client, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_connect(SSL *ssl); + +// SSL_accept configures |ssl| as a server, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_accept(SSL *ssl); + +// SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes read. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num); + +// SSL_peek behaves like |SSL_read| but does not consume any bytes returned. +OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num); + +// SSL_pending returns the number of buffered, decrypted bytes available for +// read in |ssl|. It does not read from the transport. +// +// In DTLS, it is possible for this function to return zero while there is +// buffered, undecrypted data from the transport in |ssl|. For example, +// |SSL_read| may read a datagram with two records, decrypt the first, and leave +// the second buffered for a subsequent call to |SSL_read|. Callers that wish to +// detect this case can use |SSL_has_pending|. +OPENSSL_EXPORT int SSL_pending(const SSL *ssl); + +// SSL_has_pending returns one if |ssl| has buffered, decrypted bytes available +// for read, or if |ssl| has buffered data from the transport that has not yet +// been decrypted. If |ssl| has neither, this function returns zero. +// +// In TLS, BoringSSL does not implement read-ahead, so this function returns one +// if and only if |SSL_pending| would return a non-zero value. In DTLS, it is +// possible for this function to return one while |SSL_pending| returns zero. +// For example, |SSL_read| may read a datagram with two records, decrypt the +// first, and leave the second buffered for a subsequent call to |SSL_read|. +// +// As a result, if this function returns one, the next call to |SSL_read| may +// still fail, read from the transport, or both. The buffered, undecrypted data +// may be invalid or incomplete. +OPENSSL_EXPORT int SSL_has_pending(const SSL *ssl); + +// SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes written. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// In TLS, a non-blocking |SSL_write| differs from non-blocking |write| in that +// a failed |SSL_write| still commits to the data passed in. When retrying, the +// caller must supply the original write buffer (or a larger one containing the +// original as a prefix). By default, retries will fail if they also do not +// reuse the same |buf| pointer. This may be relaxed with +// |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be +// unchanged. +// +// By default, in TLS, |SSL_write| will not return success until all |num| bytes +// are written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It +// allows |SSL_write| to complete with a partial result when only part of the +// input was written in a single record. +// +// In DTLS, neither |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| and +// |SSL_MODE_ENABLE_PARTIAL_WRITE| do anything. The caller may retry with a +// different buffer freely. A single call to |SSL_write| only ever writes a +// single record in a single packet, so |num| must be at most +// |SSL3_RT_MAX_PLAIN_LENGTH|. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num); + +// SSL_KEY_UPDATE_REQUESTED indicates that the peer should reply to a KeyUpdate +// message with its own, thus updating traffic secrets for both directions on +// the connection. +#define SSL_KEY_UPDATE_REQUESTED 1 + +// SSL_KEY_UPDATE_NOT_REQUESTED indicates that the peer should not reply with +// it's own KeyUpdate message. +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 + +// SSL_key_update queues a TLS 1.3 KeyUpdate message to be sent on |ssl| +// if one is not already queued. The |request_type| argument must one of the +// |SSL_KEY_UPDATE_*| values. This function requires that |ssl| have completed a +// TLS >= 1.3 handshake. It returns one on success or zero on error. +// +// Note that this function does not _send_ the message itself. The next call to +// |SSL_write| will cause the message to be sent. |SSL_write| may be called with +// a zero length to flush a KeyUpdate message when no application data is +// pending. +OPENSSL_EXPORT int SSL_key_update(SSL *ssl, int request_type); + +// SSL_shutdown shuts down |ssl|. It runs in two stages. First, it sends +// close_notify and returns zero or one on success or -1 on failure. Zero +// indicates that close_notify was sent, but not received, and one additionally +// indicates that the peer's close_notify had already been received. +// +// To then wait for the peer's close_notify, run |SSL_shutdown| to completion a +// second time. This returns 1 on success and -1 on failure. Application data +// is considered a fatal error at this point. To process or discard it, read +// until close_notify with |SSL_read| instead. +// +// In both cases, on failure, pass the return value into |SSL_get_error| to +// determine how to proceed. +// +// Most callers should stop at the first stage. Reading for close_notify is +// primarily used for uncommon protocols where the underlying transport is +// reused after TLS completes. Additionally, DTLS uses an unordered transport +// and is unordered, so the second stage is a no-op in DTLS. +OPENSSL_EXPORT int SSL_shutdown(SSL *ssl); + +// SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If +// enabled, |SSL_shutdown| will not send a close_notify alert or wait for one +// from the peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ctx|. +OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +// SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled, +// |SSL_shutdown| will not send a close_notify alert or wait for one from the +// peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +// SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ssl|. +OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl); + +// SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on +// |ssl|. It should be called after an operation failed to determine whether the +// error was fatal and, if not, when to retry. +OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code); + +// SSL_ERROR_NONE indicates the operation succeeded. +#define SSL_ERROR_NONE 0 + +// SSL_ERROR_SSL indicates the operation failed within the library. The caller +// may inspect the error queue for more information. +#define SSL_ERROR_SSL 1 + +// SSL_ERROR_WANT_READ indicates the operation failed attempting to read from +// the transport. The caller may retry the operation when the transport is ready +// for reading. +// +// If signaled by a DTLS handshake, the caller must also call +// |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See +// |SSL_do_handshake|. +#define SSL_ERROR_WANT_READ 2 + +// SSL_ERROR_WANT_WRITE indicates the operation failed attempting to write to +// the transport. The caller may retry the operation when the transport is ready +// for writing. +#define SSL_ERROR_WANT_WRITE 3 + +// SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the +// |cert_cb| or |client_cert_cb|. The caller may retry the operation when the +// callback is ready to return a certificate or one has been configured +// externally. +// +// See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. +#define SSL_ERROR_WANT_X509_LOOKUP 4 + +// SSL_ERROR_SYSCALL indicates the operation failed externally to the library. +// The caller should consult the system-specific error mechanism. This is +// typically |errno| but may be something custom if using a custom |BIO|. It +// may also be signaled if the transport returned EOF, in which case the +// operation's return value will be zero. +#define SSL_ERROR_SYSCALL 5 + +// SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection +// was cleanly shut down with a close_notify alert. +#define SSL_ERROR_ZERO_RETURN 6 + +// SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect +// the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the +// operation when the transport is ready. +#define SSL_ERROR_WANT_CONNECT 7 + +// SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a +// connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The +// caller may retry the operation when the transport is ready. +// +// TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. +#define SSL_ERROR_WANT_ACCEPT 8 + +// SSL_ERROR_WANT_CHANNEL_ID_LOOKUP is never used. +// +// TODO(davidben): Remove this. Some callers reference it when stringifying +// errors. They should use |SSL_error_description| instead. +#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9 + +// SSL_ERROR_PENDING_SESSION indicates the operation failed because the session +// lookup callback indicated the session was unavailable. The caller may retry +// the operation when lookup has completed. +// +// See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. +#define SSL_ERROR_PENDING_SESSION 11 + +// SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the +// early callback indicated certificate lookup was incomplete. The caller may +// retry the operation when lookup has completed. +// +// See also |SSL_CTX_set_select_certificate_cb|. +#define SSL_ERROR_PENDING_CERTIFICATE 12 + +// SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because +// a private key operation was unfinished. The caller may retry the operation +// when the private key operation is complete. +// +// See also |SSL_set_private_key_method| and +// |SSL_CTX_set_private_key_method|. +#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13 + +// SSL_ERROR_PENDING_TICKET indicates that a ticket decryption is pending. The +// caller may retry the operation when the decryption is ready. +// +// See also |SSL_CTX_set_ticket_aead_method|. +#define SSL_ERROR_PENDING_TICKET 14 + +// SSL_ERROR_EARLY_DATA_REJECTED indicates that early data was rejected. The +// caller should treat this as a connection failure and retry any operations +// associated with the rejected early data. |SSL_reset_early_data_reject| may be +// used to reuse the underlying connection for the retry. +#define SSL_ERROR_EARLY_DATA_REJECTED 15 + +// SSL_ERROR_WANT_CERTIFICATE_VERIFY indicates the operation failed because +// certificate verification was incomplete. The caller may retry the operation +// when certificate verification is complete. +// +// See also |SSL_CTX_set_custom_verify|. +#define SSL_ERROR_WANT_CERTIFICATE_VERIFY 16 + +#define SSL_ERROR_HANDOFF 17 +#define SSL_ERROR_HANDBACK 18 + +// SSL_ERROR_WANT_RENEGOTIATE indicates the operation is pending a response to +// a renegotiation request from the server. The caller may call +// |SSL_renegotiate| to schedule a renegotiation and retry the operation. +// +// See also |ssl_renegotiate_explicit|. +#define SSL_ERROR_WANT_RENEGOTIATE 19 + +// SSL_ERROR_HANDSHAKE_HINTS_READY indicates the handshake has progressed enough +// for |SSL_serialize_handshake_hints| to be called. See also +// |SSL_request_handshake_hints|. +#define SSL_ERROR_HANDSHAKE_HINTS_READY 20 + +// SSL_error_description returns a string representation of |err|, where |err| +// is one of the |SSL_ERROR_*| constants returned by |SSL_get_error|, or NULL +// if the value is unrecognized. +OPENSSL_EXPORT const char *SSL_error_description(int err); + +// SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success +// and zero on failure. +OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu); + +// DTLSv1_set_initial_timeout_duration sets the initial duration for a DTLS +// handshake timeout. +// +// This duration overrides the default of 1 second, which is the strong +// recommendation of RFC 6347 (see section 4.2.4.1). However, there may exist +// situations where a shorter timeout would be beneficial, such as for +// time-sensitive applications. +OPENSSL_EXPORT void DTLSv1_set_initial_timeout_duration(SSL *ssl, + unsigned duration_ms); + +// DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a +// timeout in progress, it sets |*out| to the time remaining and returns one. +// Otherwise, it returns zero. +// +// When the timeout expires, call |DTLSv1_handle_timeout| to handle the +// retransmit behavior. +// +// NOTE: This function must be queried again whenever the handshake state +// machine changes, including when |DTLSv1_handle_timeout| is called. +OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out); + +// DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no +// timeout had expired, it returns 0. Otherwise, it retransmits the previous +// flight of handshake messages and returns 1. If too many timeouts had expired +// without progress or an error occurs, it returns -1. +// +// The caller's external timer should be compatible with the one |ssl| queries +// within some fudge factor. Otherwise, the call will be a no-op, but +// |DTLSv1_get_timeout| will return an updated timeout. +// +// If the function returns -1, checking if |SSL_get_error| returns +// |SSL_ERROR_WANT_WRITE| may be used to determine if the retransmit failed due +// to a non-fatal error at the write |BIO|. However, the operation may not be +// retried until the next timeout fires. +// +// WARNING: This function breaks the usual return value convention. +// +// TODO(davidben): This |SSL_ERROR_WANT_WRITE| behavior is kind of bizarre. +OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); + + +// Protocol versions. + +#define DTLS1_VERSION_MAJOR 0xfe +#define SSL3_VERSION_MAJOR 0x03 + +#define SSL3_VERSION 0x0300 +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 + +#define DTLS1_VERSION 0xfeff +#define DTLS1_2_VERSION 0xfefd + +// SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_CTX_set_max_proto_version sets the maximum protocol version for |ctx| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_CTX_get_min_proto_version returns the minimum protocol version for |ctx| +OPENSSL_EXPORT uint16_t SSL_CTX_get_min_proto_version(const SSL_CTX *ctx); + +// SSL_CTX_get_max_proto_version returns the maximum protocol version for |ctx| +OPENSSL_EXPORT uint16_t SSL_CTX_get_max_proto_version(const SSL_CTX *ctx); + +// SSL_set_min_proto_version sets the minimum protocol version for |ssl| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_min_proto_version(SSL *ssl, uint16_t version); + +// SSL_set_max_proto_version sets the maximum protocol version for |ssl| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_max_proto_version(SSL *ssl, uint16_t version); + +// SSL_get_min_proto_version returns the minimum protocol version for |ssl|. If +// the connection's configuration has been shed, 0 is returned. +OPENSSL_EXPORT uint16_t SSL_get_min_proto_version(const SSL *ssl); + +// SSL_get_max_proto_version returns the maximum protocol version for |ssl|. If +// the connection's configuration has been shed, 0 is returned. +OPENSSL_EXPORT uint16_t SSL_get_max_proto_version(const SSL *ssl); + +// SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is +// one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version +// is negotiated, the result is undefined. +OPENSSL_EXPORT int SSL_version(const SSL *ssl); + + +// Options. +// +// Options configure protocol behavior. + +// SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying +// |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. +#define SSL_OP_NO_QUERY_MTU 0x00001000L + +// SSL_OP_NO_TICKET disables session ticket support (RFC 5077). +#define SSL_OP_NO_TICKET 0x00004000L + +// SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and +// ECDHE curves according to the server's preferences instead of the +// client's. +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L + +// The following flags toggle individual protocol versions. This is deprecated. +// Use |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| +// instead. +#define SSL_OP_NO_TLSv1 0x04000000L +#define SSL_OP_NO_TLSv1_2 0x08000000L +#define SSL_OP_NO_TLSv1_1 0x10000000L +#define SSL_OP_NO_TLSv1_3 0x20000000L +#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1 +#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2 + +// SSL_CTX_set_options enables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_clear_options disables all options set in |options| (which should be +// one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all +// the options enabled for |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx); + +// SSL_set_options enables all options set in |options| (which should be one or +// more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options); + +// SSL_clear_options disables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options); + +// SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the +// options enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl); + + +// Modes. +// +// Modes configure API behavior. + +// SSL_MODE_ENABLE_PARTIAL_WRITE, in TLS, allows |SSL_write| to complete with a +// partial result when the only part of the input was written in a single +// record. In DTLS, it does nothing. +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L + +// SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, in TLS, allows retrying an incomplete +// |SSL_write| with a different buffer. However, |SSL_write| still assumes the +// buffer contents are unchanged. This is not the default to avoid the +// misconception that non-blocking |SSL_write| behaves like non-blocking +// |write|. In DTLS, it does nothing. +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L + +// SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain +// before sending certificates to the peer. This flag is set (and the feature +// disabled) by default. +// TODO(davidben): Remove this behavior. https://crbug.com/boringssl/42. +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L + +// SSL_MODE_ENABLE_FALSE_START allows clients to send application data before +// receipt of ChangeCipherSpec and Finished. This mode enables full handshakes +// to 'complete' in one RTT. See RFC 7918. +// +// When False Start is enabled, |SSL_do_handshake| may succeed before the +// handshake has completely finished. |SSL_write| will function at this point, +// and |SSL_read| will transparently wait for the final handshake leg before +// returning application data. To determine if False Start occurred or when the +// handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|, +// and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. +#define SSL_MODE_ENABLE_FALSE_START 0x00000080L + +// SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in TLS 1.0 to be +// split in two: the first record will contain a single byte and the second will +// contain the remainder. This effectively randomises the IV and prevents BEAST +// attacks. +#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L + +// SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to +// fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that +// session resumption is used for a given SSL*. +#define SSL_MODE_NO_SESSION_CREATION 0x00000200L + +// SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello. +// To be set only by applications that reconnect with a downgraded protocol +// version; see RFC 7507 for details. +// +// DO NOT ENABLE THIS if your application attempts a normal handshake. Only use +// this in explicit fallback retries, following the guidance in RFC 7507. +#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L + +// SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or +// more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all +// the modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx); + +// SSL_set_mode enables all modes set in |mode| (which should be one or more of +// the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode); + +// SSL_clear_mode disables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode); + +// SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the +// modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl); + +// SSL_CTX_set0_buffer_pool sets a |CRYPTO_BUFFER_POOL| that will be used to +// store certificates. This can allow multiple connections to share +// certificates and thus save memory. +// +// The SSL_CTX does not take ownership of |pool| and the caller must ensure +// that |pool| outlives |ctx| and all objects linked to it, including |SSL|, +// |X509| and |SSL_SESSION| objects. Basically, don't ever free |pool|. +OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, + CRYPTO_BUFFER_POOL *pool); + + +// Configuring certificates and private keys. +// +// These functions configure the connection's leaf certificate, private key, and +// certificate chain. The certificate chain is ordered leaf to root (as sent on +// the wire) but does not include the leaf. Both client and server certificates +// use these functions. +// +// Certificates and keys may be configured before the handshake or dynamically +// in the early callback and certificate callback. + +// SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509); + +// SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509); + +// SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +// SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); + +// SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On +// success, it returns one and takes ownership of |x509|. Otherwise, it returns +// zero. +OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It +// returns one on success and zero on failure. The caller retains ownership of +// |x509| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success, +// it returns one and takes ownership of |x509|. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. +OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns +// one on success and zero on failure. The caller retains ownership of |x509| +// and may release it freely. +OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns +// one. +OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +// SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx); + +// SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. +OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl); + +// SSL_CTX_set_cert_cb sets a callback that is called to select a certificate. +// The callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +// +// On the server, the callback will be called after extensions have been +// processed, but before the resumption decision has been made. This differs +// from OpenSSL which handles resumption before selecting the certificate. +OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_set_cert_cb sets a callback that is called to select a certificate. The +// callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +// +// On the server, the callback will be called after extensions have been +// processed, but before the resumption decision has been made. This differs +// from OpenSSL which handles resumption before selecting the certificate. +OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_get0_certificate_types, for a client, sets |*out_types| to an array +// containing the client certificate types requested by a server. It returns the +// length of the array. Note this list is always empty in TLS 1.3. The server +// will instead send signature algorithms. See +// |SSL_get0_peer_verify_algorithms|. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t SSL_get0_certificate_types(const SSL *ssl, + const uint8_t **out_types); + +// SSL_get0_peer_verify_algorithms sets |*out_sigalgs| to an array containing +// the signature algorithms the peer is able to verify. It returns the length of +// the array. Note these values are only sent starting TLS 1.2 and only +// mandatory starting TLS 1.3. If not sent, the empty array is returned. For the +// historical client certificate types list, see |SSL_get0_certificate_types|. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t +SSL_get0_peer_verify_algorithms(const SSL *ssl, const uint16_t **out_sigalgs); + +// SSL_get0_peer_delegation_algorithms sets |*out_sigalgs| to an array +// containing the signature algorithms the peer is willing to use with delegated +// credentials. It returns the length of the array. If not sent, the empty +// array is returned. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t +SSL_get0_peer_delegation_algorithms(const SSL *ssl, + const uint16_t **out_sigalgs); + +// SSL_certs_clear resets the private key, leaf certificate, and certificate +// chain of |ssl|. +OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl); + +// SSL_CTX_check_private_key returns one if the certificate and private key +// configured in |ctx| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +// SSL_check_private_key returns one if the certificate and private key +// configured in |ssl| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl); + +// SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +// SSL_get_certificate returns |ssl|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl); + +// SSL_CTX_get0_privatekey returns |ctx|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +// SSL_get_privatekey returns |ssl|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +// SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl, + STACK_OF(X509) **out_chain); + +// SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request it. The |list| argument must +// contain one or more SCT structures serialised as a SignedCertificateTimestamp +// List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT +// is prefixed by a big-endian, uint16 length and the concatenation of one or +// more such prefixed SCTs are themselves also prefixed by a uint16 length. It +// returns one on success and zero on error. The caller retains ownership of +// |list|. +OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request is. The same format as the +// one used for |SSL_CTX_set_signed_cert_timestamp_list| applies. The caller +// retains ownership of |list|. +OPENSSL_EXPORT int SSL_set_signed_cert_timestamp_list(SSL *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_CTX_set_ocsp_response sets the OCSP response that is sent to clients +// which request it. It returns one on success and zero on error. The caller +// retains ownership of |response|. +OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, + const uint8_t *response, + size_t response_len); + +// SSL_set_ocsp_response sets the OCSP response that is sent to clients which +// request it. It returns one on success and zero on error. The caller retains +// ownership of |response|. +OPENSSL_EXPORT int SSL_set_ocsp_response(SSL *ssl, + const uint8_t *response, + size_t response_len); + +// SSL_SIGN_* are signature algorithm values as defined in TLS 1.3. +#define SSL_SIGN_RSA_PKCS1_SHA1 0x0201 +#define SSL_SIGN_RSA_PKCS1_SHA256 0x0401 +#define SSL_SIGN_RSA_PKCS1_SHA384 0x0501 +#define SSL_SIGN_RSA_PKCS1_SHA512 0x0601 +#define SSL_SIGN_ECDSA_SHA1 0x0203 +#define SSL_SIGN_ECDSA_SECP256R1_SHA256 0x0403 +#define SSL_SIGN_ECDSA_SECP384R1_SHA384 0x0503 +#define SSL_SIGN_ECDSA_SECP521R1_SHA512 0x0603 +#define SSL_SIGN_RSA_PSS_RSAE_SHA256 0x0804 +#define SSL_SIGN_RSA_PSS_RSAE_SHA384 0x0805 +#define SSL_SIGN_RSA_PSS_RSAE_SHA512 0x0806 +#define SSL_SIGN_ED25519 0x0807 + +// SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal signature algorithm used to +// specify raw RSASSA-PKCS1-v1_5 with an MD5/SHA-1 concatenation, as used in TLS +// before TLS 1.2. +#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01 + +// SSL_get_signature_algorithm_name returns a human-readable name for |sigalg|, +// or NULL if unknown. If |include_curve| is one, the curve for ECDSA algorithms +// is included as in TLS 1.3. Otherwise, it is excluded as in TLS 1.2. +OPENSSL_EXPORT const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve); + +// SSL_get_signature_algorithm_key_type returns the key type associated with +// |sigalg| as an |EVP_PKEY_*| constant or |EVP_PKEY_NONE| if unknown. +OPENSSL_EXPORT int SSL_get_signature_algorithm_key_type(uint16_t sigalg); + +// SSL_get_signature_algorithm_digest returns the digest function associated +// with |sigalg| or |NULL| if |sigalg| has no prehash (Ed25519) or is unknown. +OPENSSL_EXPORT const EVP_MD *SSL_get_signature_algorithm_digest( + uint16_t sigalg); + +// SSL_is_signature_algorithm_rsa_pss returns one if |sigalg| is an RSA-PSS +// signature algorithm and zero otherwise. +OPENSSL_EXPORT int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg); + +// SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the +// preference list when signing with |ctx|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the +// preference list when signing with |ssl|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl, + const uint16_t *prefs, + size_t num_prefs); + + +// Certificate and private key convenience functions. + +// SSL_CTX_set_chain_and_key sets the certificate chain and private key for a +// TLS client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_chain_and_key( + SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_set_chain_and_key sets the certificate chain and private key for a TLS +// client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_chain_and_key( + SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_CTX_get0_chain returns the list of |CRYPTO_BUFFER|s that were set by +// |SSL_CTX_set_chain_and_key|. Reference counts are not incremented by this +// call. The return value may be |NULL| if no chain has been set. +// +// (Note: if a chain was configured by non-|CRYPTO_BUFFER|-based functions then +// the return value is undefined and, even if not NULL, the stack itself may +// contain nullptrs. Thus you shouldn't mix this function with +// non-|CRYPTO_BUFFER| functions for manipulating the chain.) +// +// There is no |SSL*| version of this function because connections discard +// configuration after handshaking, thus making it of questionable utility. +OPENSSL_EXPORT const STACK_OF(CRYPTO_BUFFER)* + SSL_CTX_get0_chain(const SSL_CTX *ctx); + +// SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +// SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); + +// The following functions configure certificates or private keys but take as +// input DER-encoded structures. They return one on success and zero on +// failure. + +OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der); +OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, + const uint8_t *der, size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +// The following functions configure certificates or private keys but take as +// input files to read from. They return one on success and zero on failure. The +// |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether +// the file's contents are read as PEM or DER. + +#define SSL_FILETYPE_PEM 1 +#define SSL_FILETYPE_ASN1 2 + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, + const char *file, + int type); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file, + int type); + +// SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It +// reads the contents of |file| as a PEM-encoded leaf certificate followed +// optionally by the certificate chain to send to the peer. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, + const char *file); + +// SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based +// convenience functions called on |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, + pem_password_cb *cb); + +// SSL_CTX_get_default_passwd_cb returns the callback set by +// |SSL_CTX_set_default_passwd_cb|. +OPENSSL_EXPORT pem_password_cb *SSL_CTX_get_default_passwd_cb( + const SSL_CTX *ctx); + +// SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for +// |ctx|'s password callback. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, + void *data); + +// SSL_CTX_get_default_passwd_cb_userdata returns the userdata parameter set by +// |SSL_CTX_set_default_passwd_cb_userdata|. +OPENSSL_EXPORT void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx); + + +// Custom private keys. + +enum ssl_private_key_result_t BORINGSSL_ENUM_INT { + ssl_private_key_success, + ssl_private_key_retry, + ssl_private_key_failure, +}; + +// ssl_private_key_method_st (aka |SSL_PRIVATE_KEY_METHOD|) describes private +// key hooks. This is used to off-load signing operations to a custom, +// potentially asynchronous, backend. Metadata about the key such as the type +// and size are parsed out of the certificate. +// +// Callers that use this structure should additionally call +// |SSL_set_signing_algorithm_prefs| or |SSL_CTX_set_signing_algorithm_prefs| +// with the private key's capabilities. This ensures BoringSSL will select a +// suitable signature algorithm for the private key. +struct ssl_private_key_method_st { + // sign signs the message |in| in using the specified signature algorithm. On + // success, it returns |ssl_private_key_success| and writes at most |max_out| + // bytes of signature data to |out| and sets |*out_len| to the number of bytes + // written. On failure, it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. |sign| should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed. This will result in a call to |complete|. + // + // |signature_algorithm| is one of the |SSL_SIGN_*| values, as defined in TLS + // 1.3. Note that, in TLS 1.2, ECDSA algorithms do not require that curve + // sizes match hash sizes, so the curve portion of |SSL_SIGN_ECDSA_*| values + // must be ignored. BoringSSL will internally handle the curve matching logic + // where appropriate. + // + // It is an error to call |sign| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out, + uint16_t signature_algorithm, + const uint8_t *in, size_t in_len); + + // decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it + // returns |ssl_private_key_success|, writes at most |max_out| bytes of + // decrypted data to |out| and sets |*out_len| to the actual number of bytes + // written. On failure it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. The caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in a call to |complete|. This + // function only works with RSA keys and should perform a raw RSA decryption + // operation with no padding. + // + // It is an error to call |decrypt| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + + // complete completes a pending operation. If the operation has completed, it + // returns |ssl_private_key_success| and writes the result to |out| as in + // |sign|. Otherwise, it returns |ssl_private_key_failure| on failure and + // |ssl_private_key_retry| if the operation is still in progress. + // + // |complete| may be called arbitrarily many times before completion, but it + // is an error to call |complete| if there is no pending operation in progress + // on |ssl|. + enum ssl_private_key_result_t (*complete)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); +}; + +// SSL_set_private_key_method configures a custom private key on |ssl|. +// |key_method| must remain valid for the lifetime of |ssl|. +OPENSSL_EXPORT void SSL_set_private_key_method( + SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_CTX_set_private_key_method configures a custom private key on |ctx|. +// |key_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_private_key_method( + SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_can_release_private_key returns one if |ssl| will no longer call into the +// private key and zero otherwise. If the function returns one, the caller can +// release state associated with the private key. +// +// NOTE: This function assumes the caller does not use |SSL_clear| to reuse +// |ssl| for a second connection. If |SSL_clear| is used, BoringSSL may still +// use the private key on the second connection. +OPENSSL_EXPORT int SSL_can_release_private_key(const SSL *ssl); + + +// Cipher suites. +// +// |SSL_CIPHER| objects represent cipher suites. + +DEFINE_CONST_STACK_OF(SSL_CIPHER) + +// SSL_get_cipher_by_value returns the structure representing a TLS cipher +// suite based on its assigned number, or NULL if unknown. See +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value); + +// SSL_CIPHER_get_id returns |cipher|'s non-IANA id. This is not its +// IANA-assigned number, which is called the "value" here, although it may be +// cast to a |uint16_t| to get it. +OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_protocol_id returns |cipher|'s IANA-assigned number. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_aead returns one if |cipher| uses an AEAD cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_cipher_nid returns the NID for |cipher|'s bulk +// cipher. Possible values are |NID_aes_128_gcm|, |NID_aes_256_gcm|, +// |NID_chacha20_poly1305|, |NID_aes_128_cbc|, |NID_aes_256_cbc|, and +// |NID_des_ede3_cbc|. +OPENSSL_EXPORT int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_digest_nid returns the NID for |cipher|'s HMAC if it is a +// legacy cipher suite. For modern AEAD-based ciphers (see +// |SSL_CIPHER_is_aead|), it returns |NID_undef|. +// +// Note this function only returns the legacy HMAC digest, not the PRF hash. +OPENSSL_EXPORT int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_nid returns the NID for |cipher|'s key exchange. This may +// be |NID_kx_rsa|, |NID_kx_ecdhe|, or |NID_kx_psk| for TLS 1.2. In TLS 1.3, +// cipher suites do not specify the key exchange, so this function returns +// |NID_kx_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_auth_nid returns the NID for |cipher|'s authentication +// type. This may be |NID_auth_rsa|, |NID_auth_ecdsa|, or |NID_auth_psk| for TLS +// 1.2. In TLS 1.3, cipher suites do not specify authentication, so this +// function returns |NID_auth_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_prf_nid retuns the NID for |cipher|'s PRF hash. If |cipher| is +// a pre-TLS-1.2 cipher, it returns |NID_md5_sha1| but note these ciphers use +// SHA-256 in TLS 1.2. Other return values may be treated uniformly in all +// applicable versions. +OPENSSL_EXPORT int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_min_version returns the minimum protocol version required +// for |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_max_version returns the maximum protocol version that +// supports |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_standard_name returns the standard IETF name for |cipher|. For +// example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. For example, +// "ECDHE-RSA-AES128-GCM-SHA256". Callers are recommended to use +// |SSL_CIPHER_standard_name| instead. +OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_name returns a string that describes the key-exchange +// method used by |cipher|. For example, "ECDHE_ECDSA". TLS 1.3 AEAD-only +// ciphers return the string "GENERIC". +OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If +// |out_alg_bits| is not NULL, it writes the number of bits consumed by the +// symmetric algorithm to |*out_alg_bits|. +OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, + int *out_alg_bits); + + +// Cipher suite configuration. +// +// OpenSSL uses a mini-language to configure cipher suites. The language +// maintains an ordered list of enabled ciphers, along with an ordered list of +// disabled but available ciphers. Initially, all ciphers are disabled with a +// default ordering. The cipher string is then interpreted as a sequence of +// directives, separated by colons, each of which modifies this state. +// +// Most directives consist of a one character or empty opcode followed by a +// selector which matches a subset of available ciphers. +// +// Available opcodes are: +// +// The empty opcode enables and appends all matching disabled ciphers to the +// end of the enabled list. The newly appended ciphers are ordered relative to +// each other matching their order in the disabled list. +// +// |-| disables all matching enabled ciphers and prepends them to the disabled +// list, with relative order from the enabled list preserved. This means the +// most recently disabled ciphers get highest preference relative to other +// disabled ciphers if re-enabled. +// +// |+| moves all matching enabled ciphers to the end of the enabled list, with +// relative order preserved. +// +// |!| deletes all matching ciphers, enabled or not, from either list. Deleted +// ciphers will not matched by future operations. +// +// A selector may be a specific cipher (using either the standard or OpenSSL +// name for the cipher) or one or more rules separated by |+|. The final +// selector matches the intersection of each rule. For instance, |AESGCM+aECDSA| +// matches ECDSA-authenticated AES-GCM ciphers. +// +// Available cipher rules are: +// +// |ALL| matches all ciphers. +// +// |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE, +// ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is +// matched by |kECDHE| and not |kPSK|. +// +// |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and +// a pre-shared key, respectively. +// +// |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the +// corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not +// |aRSA|. +// +// |3DES|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match ciphers +// whose bulk cipher use the corresponding encryption scheme. Note that +// |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers. +// +// |SHA1|, and its alias |SHA|, match legacy cipher suites using HMAC-SHA1. +// +// Although implemented, authentication-only ciphers match no rules and must be +// explicitly selected by name. +// +// Deprecated cipher rules: +// +// |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, +// |kECDHE|, and |ECDHE|, respectively. +// +// |HIGH| is an alias for |ALL|. +// +// |FIPS| is an alias for |HIGH|. +// +// |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier. +// |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not +// be used. +// +// Unknown rules are silently ignored by legacy APIs, and rejected by APIs with +// "strict" in the name, which should be preferred. Cipher lists can be long +// and it's easy to commit typos. Strict functions will also reject the use of +// spaces, semi-colons and commas as alternative separators. +// +// The special |@STRENGTH| directive will sort all enabled ciphers by strength. +// +// The |DEFAULT| directive, when appearing at the front of the string, expands +// to the default ordering of available ciphers. +// +// If configuring a server, one may also configure equal-preference groups to +// partially respect the client's preferences when +// |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference +// group have equal priority and use the client order. This may be used to +// enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 +// based on client preferences. An equal-preference is specified with square +// brackets, combining multiple selectors separated by |. For example: +// +// [TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] +// +// Once an equal-preference group is used, future directives must be +// opcode-less. Inside an equal-preference group, spaces are not allowed. +// +// TLS 1.3 ciphers do not participate in this mechanism and instead have a +// built-in preference order. Functions to set cipher lists do not affect TLS +// 1.3, and functions to query the cipher list do not include TLS 1.3 +// ciphers. + +// SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is +// substituted when a cipher string starts with 'DEFAULT'. +#define SSL_DEFAULT_CIPHER_LIST "ALL" + +// SSL_CTX_set_strict_cipher_list configures the cipher list for |ctx|, +// evaluating |str| as a cipher string and returning error if |str| contains +// anything meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, + const char *str); + +// SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating +// |str| as a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates +// garbage inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +// SSL_set_strict_cipher_list configures the cipher list for |ssl|, evaluating +// |str| as a cipher string and returning error if |str| contains anything +// meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); + +// SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as +// a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage +// inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); + +// SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of +// preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +// SSL_CTX_cipher_in_group returns one if the |i|th cipher (see +// |SSL_CTX_get_ciphers|) is in the same equipreference group as the one +// following it and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i); + +// SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl); + + +// Connection information. + +// SSL_is_init_finished returns one if |ssl| has completed its initial handshake +// and has no pending handshake. It returns zero otherwise. +OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl); + +// SSL_in_init returns one if |ssl| has a pending handshake and zero +// otherwise. +OPENSSL_EXPORT int SSL_in_init(const SSL *ssl); + +// SSL_in_false_start returns one if |ssl| has a pending handshake that is in +// False Start. |SSL_write| may be called at this point without waiting for the +// peer, but |SSL_read| will complete the handshake before accepting application +// data. +// +// See also |SSL_MODE_ENABLE_FALSE_START|. +OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl); + +// SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the +// peer did not use certificates. The caller must call |X509_free| on the +// result to release it. +OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl); + +// SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// WARNING: This function behaves differently between client and server. If +// |ssl| is a server, the returned chain does not include the leaf certificate. +// If a client, it does. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl); + +// SSL_get_peer_full_cert_chain returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the same as |SSL_get_peer_cert_chain| except that this function +// always returns the full chain, i.e. the first element of the return value +// (if any) will be the leaf certificate. In constrast, +// |SSL_get_peer_cert_chain| returns only the intermediate certificates if the +// |ssl| is a server. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl); + +// SSL_get0_peer_certificates returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the |CRYPTO_BUFFER| variant of |SSL_get_peer_full_cert_chain|. +OPENSSL_EXPORT const STACK_OF(CRYPTO_BUFFER) * + SSL_get0_peer_certificates(const SSL *ssl); + +// SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to +// |*out_len| bytes of SCT information from the server. This is only valid if +// |ssl| is a client. The SCT information is a SignedCertificateTimestampList +// (including the two leading length bytes). +// See https://tools.ietf.org/html/rfc6962#section-3.3 +// If no SCT was received then |*out_len| will be zero on return. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, + const uint8_t **out, + size_t *out_len); + +// SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len| +// bytes of an OCSP response from the server. This is the DER encoding of an +// OCSPResponse type as defined in RFC 2560. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len); + +// SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value +// for |ssl| to |out| and sets |*out_len| to the number of bytes written. It +// returns one on success or zero on error. In general |max_out| should be at +// least 12. +// +// This function will always fail if the initial handshake has not completed. +// The tls-unique value will change after a renegotiation but, since +// renegotiations can be initiated by the server at any point, the higher-level +// protocol must either leave them disabled or define states in which the +// tls-unique value can be read. +// +// The tls-unique value is defined by +// https://tools.ietf.org/html/rfc5929#section-3.1. Due to a weakness in the +// TLS protocol, tls-unique is broken for resumed connections unless the +// Extended Master Secret extension is negotiated. Thus this function will +// return zero if |ssl| performed session resumption unless EMS was used when +// negotiating the original session. +OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); + +// SSL_get_extms_support returns one if the Extended Master Secret extension or +// TLS 1.3 was negotiated. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl); + +// SSL_get_current_cipher returns cipher suite used by |ssl|, or NULL if it has +// not been negotiated yet. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +// SSL_session_reused returns one if |ssl| performed an abbreviated handshake +// and zero otherwise. +// +// TODO(davidben): Hammer down the semantics of this API while a handshake, +// initial or renego, is in progress. +OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl); + +// SSL_get_secure_renegotiation_support returns one if the peer supports secure +// renegotiation (RFC 5746) or TLS 1.3. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl); + +// SSL_export_keying_material exports a value derived from the master secret, as +// specified in RFC 5705. It writes |out_len| bytes to |out| given a label and +// optional context. (Since a zero length context is allowed, the |use_context| +// flag controls whether a context is included.) +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int SSL_export_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len, int use_context); + + +// Sessions. +// +// An |SSL_SESSION| represents an SSL session that may be resumed in an +// abbreviated handshake. It is reference-counted and immutable. Once +// established, an |SSL_SESSION| may be shared by multiple |SSL| objects on +// different threads and must not be modified. +// +// Note the TLS notion of "session" is not suitable for application-level +// session state. It is an optional caching mechanism for the handshake. Not all +// connections within an application-level session will reuse TLS sessions. TLS +// sessions may be dropped by the client or ignored by the server at any time. + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +// SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on +// error. This may be useful when writing tests but should otherwise not be +// used. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx); + +// SSL_SESSION_up_ref increments the reference count of |session| and returns +// one. +OPENSSL_EXPORT int SSL_SESSION_up_ref(SSL_SESSION *session); + +// SSL_SESSION_free decrements the reference count of |session|. If it reaches +// zero, all data referenced by |session| and |session| itself are released. +OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session); + +// SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets +// |*out_data| to that buffer and |*out_len| to its length. The caller takes +// ownership of the buffer and must call |OPENSSL_free| when done. It returns +// one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in, + uint8_t **out_data, size_t *out_len); + +// SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session +// identification information, namely the session ID and ticket. +OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, + uint8_t **out_data, + size_t *out_len); + +// SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It +// returns a newly-allocated |SSL_SESSION| on success or NULL on error. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes( + const uint8_t *in, size_t in_len, const SSL_CTX *ctx); + +// SSL_SESSION_get_version returns a string describing the TLS or DTLS version +// |session| was established at. For example, "TLSv1.2" or "DTLSv1". +OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session); + +// SSL_SESSION_get_protocol_version returns the TLS or DTLS version |session| +// was established at. +OPENSSL_EXPORT uint16_t +SSL_SESSION_get_protocol_version(const SSL_SESSION *session); + +// SSL_SESSION_set_protocol_version sets |session|'s TLS or DTLS version to +// |version|. This may be useful when writing tests but should otherwise not be +// used. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_set_protocol_version(SSL_SESSION *session, + uint16_t version); + +// SSL_MAX_SSL_SESSION_ID_LENGTH is the maximum length of an SSL session ID. +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 + +// SSL_SESSION_get_id returns a pointer to a buffer containing |session|'s +// session ID and sets |*out_len| to its length. +// +// This function should only be used for implementing a TLS session cache. TLS +// sessions are not suitable for application-level session state, and a session +// ID is an implementation detail of the TLS resumption handshake mechanism. Not +// all resumption flows use session IDs, and not all connections within an +// application-level session will reuse TLS sessions. +// +// To determine if resumption occurred, use |SSL_session_reused| instead. +// Comparing session IDs will not give the right result in all cases. +// +// As a workaround for some broken applications, BoringSSL sometimes synthesizes +// arbitrary session IDs for non-ID-based sessions. This behavior may be +// removed in the future. +OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len); + +// SSL_SESSION_set1_id sets |session|'s session ID to |sid|, It returns one on +// success and zero on error. This function may be useful in writing tests but +// otherwise should not be used. +OPENSSL_EXPORT int SSL_SESSION_set1_id(SSL_SESSION *session, const uint8_t *sid, + size_t sid_len); + +// SSL_SESSION_get_time returns the time at which |session| was established in +// seconds since the UNIX epoch. +OPENSSL_EXPORT uint64_t SSL_SESSION_get_time(const SSL_SESSION *session); + +// SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. +OPENSSL_EXPORT uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer returns the peer leaf certificate stored in +// |session|. +// +// TODO(davidben): This should return a const X509 *. +OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer_certificates returns the peer certificate chain stored +// in |session|, or NULL if the peer did not use certificates. This is the +// unverified list of certificates as sent by the peer, not the final chain +// built during verification. The caller does not take ownership of the result. +OPENSSL_EXPORT const STACK_OF(CRYPTO_BUFFER) * + SSL_SESSION_get0_peer_certificates(const SSL_SESSION *session); + +// SSL_SESSION_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to +// point to |*out_len| bytes of SCT information stored in |session|. This is +// only valid for client sessions. The SCT information is a +// SignedCertificateTimestampList (including the two leading length bytes). See +// https://tools.ietf.org/html/rfc6962#section-3.3 If no SCT was received then +// |*out_len| will be zero on return. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_SESSION_get0_signed_cert_timestamp_list( + const SSL_SESSION *session, const uint8_t **out, size_t *out_len); + +// SSL_SESSION_get0_ocsp_response sets |*out| and |*out_len| to point to +// |*out_len| bytes of an OCSP response from the server. This is the DER +// encoding of an OCSPResponse type as defined in RFC 2560. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_SESSION_get0_ocsp_response(const SSL_SESSION *session, + const uint8_t **out, + size_t *out_len); + +// SSL_MAX_MASTER_KEY_LENGTH is the maximum length of a master secret. +#define SSL_MAX_MASTER_KEY_LENGTH 48 + +// SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s secret +// to |out| and returns the number of bytes written. If |max_out| is zero, it +// returns the size of the secret. +OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + uint8_t *out, size_t max_out); + +// SSL_SESSION_set_time sets |session|'s creation time to |time| and returns +// |time|. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint64_t SSL_SESSION_set_time(SSL_SESSION *session, + uint64_t time); + +// SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns +// one. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, + uint32_t timeout); + +// SSL_SESSION_get0_id_context returns a pointer to a buffer containing +// |session|'s session ID context (see |SSL_CTX_set_session_id_context|) and +// sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_SESSION_get0_id_context( + const SSL_SESSION *session, unsigned *out_len); + +// SSL_SESSION_set1_id_context sets |session|'s session ID context (see +// |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and +// zero on error. This function may be useful in writing tests but otherwise +// should not be used. +OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_SESSION_should_be_single_use returns one if |session| should be +// single-use (TLS 1.3 and later) and zero otherwise. +// +// If this function returns one, clients retain multiple sessions and use each +// only once. This prevents passive observers from correlating connections with +// tickets. See RFC 8446, appendix C.4. If it returns zero, |session| cannot be +// used without leaking a correlator. +OPENSSL_EXPORT int SSL_SESSION_should_be_single_use(const SSL_SESSION *session); + +// SSL_SESSION_is_resumable returns one if |session| is complete and contains a +// session ID or ticket. It returns zero otherwise. Note this function does not +// ensure |session| will be resumed. It may be expired, dropped by the server, +// or associated with incompatible parameters. +OPENSSL_EXPORT int SSL_SESSION_is_resumable(const SSL_SESSION *session); + +// SSL_SESSION_has_ticket returns one if |session| has a ticket and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_has_ticket(const SSL_SESSION *session); + +// SSL_SESSION_get0_ticket sets |*out_ticket| and |*out_len| to |session|'s +// ticket, or NULL and zero if it does not have one. |out_ticket| may be NULL +// if only the ticket length is needed. +OPENSSL_EXPORT void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, + size_t *out_len); + +// SSL_SESSION_set_ticket sets |session|'s ticket to |ticket|. It returns one on +// success and zero on error. This function may be useful in writing tests but +// otherwise should not be used. +OPENSSL_EXPORT int SSL_SESSION_set_ticket(SSL_SESSION *session, + const uint8_t *ticket, + size_t ticket_len); + +// SSL_SESSION_get_ticket_lifetime_hint returns ticket lifetime hint of +// |session| in seconds or zero if none was set. +OPENSSL_EXPORT uint32_t +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); + +// SSL_SESSION_get0_cipher returns the cipher negotiated by the connection which +// established |session|. +// +// Note that, in TLS 1.3, there is no guarantee that resumptions with |session| +// will use that cipher. Prefer calling |SSL_get_current_cipher| on the |SSL| +// instead. +OPENSSL_EXPORT const SSL_CIPHER *SSL_SESSION_get0_cipher( + const SSL_SESSION *session); + +// SSL_SESSION_has_peer_sha256 returns one if |session| has a SHA-256 hash of +// the peer's certificate retained and zero if the peer did not present a +// certificate or if this was not enabled when |session| was created. See also +// |SSL_CTX_set_retain_only_sha256_of_client_certs|. +OPENSSL_EXPORT int SSL_SESSION_has_peer_sha256(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer_sha256 sets |*out_ptr| and |*out_len| to the SHA-256 +// hash of the peer certificate retained in |session|, or NULL and zero if it +// does not have one. See also |SSL_CTX_set_retain_only_sha256_of_client_certs|. +OPENSSL_EXPORT void SSL_SESSION_get0_peer_sha256(const SSL_SESSION *session, + const uint8_t **out_ptr, + size_t *out_len); + + +// Session caching. +// +// Session caching allows connections to be established more efficiently based +// on saved parameters from a previous connection, called a session (see +// |SSL_SESSION|). The client offers a saved session, using an opaque identifier +// from a previous connection. The server may accept the session, if it has the +// parameters available. Otherwise, it will decline and continue with a full +// handshake. +// +// This requires both the client and the server to retain session state. A +// client does so with a stateful session cache. A server may do the same or, if +// supported by both sides, statelessly using session tickets. For more +// information on the latter, see the next section. +// +// For a server, the library implements a built-in internal session cache as an +// in-memory hash table. Servers may also use |SSL_CTX_sess_set_get_cb| and +// |SSL_CTX_sess_set_new_cb| to implement a custom external session cache. In +// particular, this may be used to share a session cache between multiple +// servers in a large deployment. An external cache may be used in addition to +// or instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to +// toggle the internal cache. +// +// For a client, the only option is an external session cache. Clients may use +// |SSL_CTX_sess_set_new_cb| to register a callback for when new sessions are +// available. These may be cached and, in subsequent compatible connections, +// configured with |SSL_set_session|. +// +// Note that offering or accepting a session short-circuits certificate +// verification and most parameter negotiation. Resuming sessions across +// different contexts may result in security failures and surprising +// behavior. For a typical client, this means sessions for different hosts must +// be cached under different keys. A client that connects to the same host with, +// e.g., different cipher suite settings or client certificates should also use +// separate session caches between those contexts. Servers should also partition +// session caches between SNI hosts with |SSL_CTX_set_session_id_context|. +// +// Note also, in TLS 1.2 and earlier, offering sessions allows passive observers +// to correlate different client connections. TLS 1.3 and later fix this, +// provided clients use sessions at most once. Session caches are managed by the +// caller in BoringSSL, so this must be implemented externally. See +// |SSL_SESSION_should_be_single_use| for details. + +// SSL_SESS_CACHE_OFF disables all session caching. +#define SSL_SESS_CACHE_OFF 0x0000 + +// SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal +// cache is never used on a client, so this only enables the callbacks. +#define SSL_SESS_CACHE_CLIENT 0x0001 + +// SSL_SESS_CACHE_SERVER enables session caching for a server. +#define SSL_SESS_CACHE_SERVER 0x0002 + +// SSL_SESS_CACHE_BOTH enables session caching for both client and server. +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER) + +// SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling +// |SSL_CTX_flush_sessions| every 255 connections. +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 + +// SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session +// from the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 + +// SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in +// the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 + +// SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session +// cache. +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE) + +// SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to +// |mode|. It returns the previous value. +OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_session_cache_mode returns the session cache mode bits for +// |ctx| +OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx); + +// SSL_set_session, for a client, configures |ssl| to offer to resume |session| +// in the initial handshake and returns one. The caller retains ownership of +// |session|. Note that configuring a session assumes the authentication in the +// session is valid. For callers that wish to revalidate the session before +// offering, see |SSL_SESSION_get0_peer_certificates|, +// |SSL_SESSION_get0_signed_cert_timestamp_list|, and +// |SSL_SESSION_get0_ocsp_response|. +// +// It is an error to call this function after the handshake has begun. +OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session); + +// SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a +// session in TLS 1.2 or earlier. This is how long we are willing to use the +// secret to encrypt traffic without fresh key material. +#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60) + +// SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT is the default lifetime, in seconds, of a +// session for TLS 1.3 psk_dhe_ke. This is how long we are willing to use the +// secret as an authenticator. +#define SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT (2 * 24 * 60 * 60) + +// SSL_DEFAULT_SESSION_AUTH_TIMEOUT is the default non-renewable lifetime, in +// seconds, of a TLS 1.3 session. This is how long we are willing to trust the +// signature in the initial handshake. +#define SSL_DEFAULT_SESSION_AUTH_TIMEOUT (7 * 24 * 60 * 60) + +// SSL_CTX_set_timeout sets the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout); + +// SSL_CTX_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3 +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, + uint32_t timeout); + +// SSL_CTX_get_timeout returns the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx); + +// SSL_MAX_SID_CTX_LENGTH is the maximum length of a session ID context. +#define SSL_MAX_SID_CTX_LENGTH 32 + +// SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|. +// It returns one on success and zero on error. The session ID context is an +// application-defined opaque byte string. A session will not be used in a +// connection without a matching session ID context. +// +// For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a +// session ID context. +OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It +// returns one on success and zero on error. See also +// |SSL_CTX_set_session_id_context|. +OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_get0_session_id_context returns a pointer to |ssl|'s session ID context +// and sets |*out_len| to its length. It returns NULL on error. +OPENSSL_EXPORT const uint8_t *SSL_get0_session_id_context(const SSL *ssl, + size_t *out_len); + +// SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session +// cache. +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20) + +// SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session +// cache to |size|. It returns the previous value. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, + unsigned long size); + +// SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal +// session cache. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx); + +// SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal +// session cache. +OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx); + +// SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It +// returns one on success and zero on error or if |session| is already in the +// cache. The caller retains its reference to |session|. +OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache. +// It returns one on success and zero if |session| was not in the cache. +OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as +// of time |time|. If |time| is zero, all sessions are removed. +OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time); + +// SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is +// established and ready to be cached. If the session cache is disabled (the +// appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is +// unset), the callback is not called. +// +// The callback is passed a reference to |session|. It returns one if it takes +// ownership (and then calls |SSL_SESSION_free| when done) and zero otherwise. A +// consumer which places |session| into an in-memory cache will likely return +// one, with the cache calling |SSL_SESSION_free|. A consumer which serializes +// |session| with |SSL_SESSION_to_bytes| may not need to retain |session| and +// will likely return zero. Returning one is equivalent to calling +// |SSL_SESSION_up_ref| and then returning zero. +// +// Note: For a client, the callback may be called on abbreviated handshakes if a +// ticket is renewed. Further, it may not be called until some time after +// |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus +// it's recommended to use this callback over calling |SSL_get_session| on +// handshake completion. +OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb( + SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session)); + +// SSL_CTX_sess_get_new_cb returns the callback set by +// |SSL_CTX_sess_set_new_cb|. +OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))( + SSL *ssl, SSL_SESSION *session); + +// SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is +// removed from the internal session cache. +// +// TODO(davidben): What is the point of this callback? It seems useless since it +// only fires on sessions in the internal cache. +OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session)); + +// SSL_CTX_sess_get_remove_cb returns the callback set by +// |SSL_CTX_sess_set_remove_cb|. +OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))( + SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a +// server. The callback is passed the session ID and should return a matching +// |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and +// return a new reference to the session. This callback is not used for a +// client. +// +// For historical reasons, if |*out_copy| is set to one (default), the SSL +// library will take a new reference to the returned |SSL_SESSION|, expecting +// the callback to return a non-owning pointer. This is not recommended. If +// |ctx| and thus the callback is used on multiple threads, the session may be +// removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|, +// whereas the callback may synchronize internally. +// +// To look up a session asynchronously, the callback may return +// |SSL_magic_pending_session_ptr|. See the documentation for that function and +// |SSL_ERROR_PENDING_SESSION|. +// +// If the internal session cache is enabled, the callback is only consulted if +// the internal cache does not return a match. +OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)); + +// SSL_CTX_sess_get_get_cb returns the callback set by +// |SSL_CTX_sess_set_get_cb|. +OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))( + SSL *ssl, const uint8_t *id, int id_len, int *out_copy); + +// SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates +// that the session isn't currently unavailable. |SSL_get_error| will then +// return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later +// when the lookup has completed. +OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void); + + +// Session tickets. +// +// Session tickets, from RFC 5077, allow session resumption without server-side +// state. The server maintains a secret ticket key and sends the client opaque +// encrypted session parameters, called a ticket. When offering the session, the +// client sends the ticket which the server decrypts to recover session state. +// Session tickets are enabled by default but may be disabled with +// |SSL_OP_NO_TICKET|. +// +// On the client, ticket-based sessions use the same APIs as ID-based tickets. +// Callers do not need to handle them differently. +// +// On the server, tickets are encrypted and authenticated with a secret key. +// By default, an |SSL_CTX| will manage session ticket encryption keys by +// generating them internally and rotating every 48 hours. Tickets are minted +// and processed transparently. The following functions may be used to configure +// a persistent key or implement more custom behavior, including key rotation +// and sharing keys between multiple servers in a large deployment. There are +// three levels of customisation possible: +// +// 1) One can simply set the keys with |SSL_CTX_set_tlsext_ticket_keys|. +// 2) One can configure an |EVP_CIPHER_CTX| and |HMAC_CTX| directly for +// encryption and authentication. +// 3) One can configure an |SSL_TICKET_AEAD_METHOD| to have more control +// and the option of asynchronous decryption. +// +// An attacker that compromises a server's session ticket key can impersonate +// the server and, prior to TLS 1.3, retroactively decrypt all application +// traffic from sessions using that ticket key. Thus ticket keys must be +// regularly rotated for forward secrecy. Note the default key is rotated +// automatically once every 48 hours but manually configured keys are not. + +// SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL is the interval with which the +// default session ticket encryption key is rotated, if in use. If any +// non-default ticket encryption mechanism is configured, automatic rotation is +// disabled. +#define SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL (2 * 24 * 60 * 60) + +// SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to +// |len| bytes of |out|. It returns one on success and zero if |len| is not +// 48. If |out| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, + size_t len); + +// SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to +// |len| bytes of |in|. It returns one on success and zero if |len| is not +// 48. If |in| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, + size_t len); + +// SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session +// ticket. +#define SSL_TICKET_KEY_NAME_LEN 16 + +// SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and +// returns one. |callback| will be called when encrypting a new ticket and when +// decrypting a ticket from the client. +// +// In both modes, |ctx| and |hmac_ctx| will already have been initialized with +// |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback| +// configures |hmac_ctx| with an HMAC digest and key, and configures |ctx| +// for encryption or decryption, based on the mode. +// +// When encrypting a new ticket, |encrypt| will be one. It writes a public +// 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length +// must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns 1 on success and -1 on error. +// +// When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a +// 16-byte key name and |iv| points to an IV. The length of the IV consumed must +// match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns -1 to abort the handshake, 0 if decrypting the ticket +// failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed. +// This may be used to re-key the ticket. +// +// WARNING: |callback| wildly breaks the usual return value convention and is +// called in two different modes. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)); + +// ssl_ticket_aead_result_t enumerates the possible results from decrypting a +// ticket with an |SSL_TICKET_AEAD_METHOD|. +enum ssl_ticket_aead_result_t BORINGSSL_ENUM_INT { + // ssl_ticket_aead_success indicates that the ticket was successfully + // decrypted. + ssl_ticket_aead_success, + // ssl_ticket_aead_retry indicates that the operation could not be + // immediately completed and must be reattempted, via |open|, at a later + // point. + ssl_ticket_aead_retry, + // ssl_ticket_aead_ignore_ticket indicates that the ticket should be ignored + // (i.e. is corrupt or otherwise undecryptable). + ssl_ticket_aead_ignore_ticket, + // ssl_ticket_aead_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_ticket_aead_error, +}; + +// ssl_ticket_aead_method_st (aka |SSL_TICKET_AEAD_METHOD|) contains methods +// for encrypting and decrypting session tickets. +struct ssl_ticket_aead_method_st { + // max_overhead returns the maximum number of bytes of overhead that |seal| + // may add. + size_t (*max_overhead)(SSL *ssl); + + // seal encrypts and authenticates |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes to |out|, and puts the number of bytes written in + // |*out_len|. The |in| and |out| buffers may be equal but will not otherwise + // alias. It returns one on success or zero on error. + int (*seal)(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len); + + // open authenticates and decrypts |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes of plaintext to |out|, and puts the number of bytes + // written in |*out_len|. The |in| and |out| buffers may be equal but will + // not otherwise alias. See |ssl_ticket_aead_result_t| for details of the + // return values. In the case that a retry is indicated, the caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in another call to |open|. + enum ssl_ticket_aead_result_t (*open)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, + size_t in_len); +}; + +// SSL_CTX_set_ticket_aead_method configures a custom ticket AEAD method table +// on |ctx|. |aead_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_ticket_aead_method( + SSL_CTX *ctx, const SSL_TICKET_AEAD_METHOD *aead_method); + +// SSL_process_tls13_new_session_ticket processes an unencrypted TLS 1.3 +// NewSessionTicket message from |buf| and returns a resumable |SSL_SESSION|, +// or NULL on error. The caller takes ownership of the returned session and +// must call |SSL_SESSION_free| to free it. +// +// |buf| contains |buf_len| bytes that represents a complete NewSessionTicket +// message including its header, i.e., one byte for the type (0x04) and three +// bytes for the length. |buf| must contain only one such message. +// +// This function may be used to process NewSessionTicket messages in TLS 1.3 +// clients that are handling the record layer externally. +OPENSSL_EXPORT SSL_SESSION *SSL_process_tls13_new_session_ticket( + SSL *ssl, const uint8_t *buf, size_t buf_len); + + +// Elliptic curve Diffie-Hellman. +// +// Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an +// elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves +// are supported. ECDHE is always enabled, but the curve preferences may be +// configured with these functions. +// +// Note that TLS 1.3 renames these from curves to groups. For consistency, we +// currently use the TLS 1.2 name in the API. + +// SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, + size_t curves_len); + +// SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, + size_t curves_len); + +// SSL_CTX_set1_curves_list sets the preferred curves for |ctx| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); + +// SSL_set1_curves_list sets the preferred curves for |ssl| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); + +// SSL_CURVE_* define TLS curve IDs. +#define SSL_CURVE_SECP224R1 21 +#define SSL_CURVE_SECP256R1 23 +#define SSL_CURVE_SECP384R1 24 +#define SSL_CURVE_SECP521R1 25 +#define SSL_CURVE_X25519 29 +#define SSL_CURVE_CECPQ2 16696 + +// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently +// completed handshake or 0 if not applicable. +// +// TODO(davidben): This API currently does not work correctly if there is a +// renegotiation in progress. Fix this. +OPENSSL_EXPORT uint16_t SSL_get_curve_id(const SSL *ssl); + +// SSL_get_curve_name returns a human-readable name for the curve specified by +// the given TLS curve id, or NULL if the curve is unknown. +OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); + + +// Certificate verification. +// +// SSL may authenticate either endpoint with an X.509 certificate. Typically +// this is used to authenticate the server to the client. These functions +// configure certificate verification. +// +// WARNING: By default, certificate verification errors on a client are not +// fatal. See |SSL_VERIFY_NONE| This may be configured with +// |SSL_CTX_set_verify|. +// +// By default clients are anonymous but a server may request a certificate from +// the client by setting |SSL_VERIFY_PEER|. +// +// Many of these functions use OpenSSL's legacy X.509 stack which is +// underdocumented and deprecated, but the replacement isn't ready yet. For +// now, consumers may use the existing stack or bypass it by performing +// certificate verification externally. This may be done with +// |SSL_CTX_set_cert_verify_callback| or by extracting the chain with +// |SSL_get_peer_cert_chain| after the handshake. In the future, functions will +// be added to use the SSL stack without dependency on any part of the legacy +// X.509 and ASN.1 stack. +// +// To augment certificate verification, a client may also enable OCSP stapling +// (RFC 6066) and Certificate Transparency (RFC 6962) extensions. + +// SSL_VERIFY_NONE, on a client, verifies the server certificate but does not +// make errors fatal. The result may be checked with |SSL_get_verify_result|. On +// a server it does not request a client certificate. This is the default. +#define SSL_VERIFY_NONE 0x00 + +// SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a +// server it requests a client certificate and makes errors fatal. However, +// anonymous clients are still allowed. See +// |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. +#define SSL_VERIFY_PEER 0x01 + +// SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if +// the client declines to send a certificate. This flag must be used together +// with |SSL_VERIFY_PEER|, otherwise it won't work. +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 + +// SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate +// if and only if Channel ID is not negotiated. +#define SSL_VERIFY_PEER_IF_NO_OBC 0x04 + +// SSL_CTX_set_verify configures certificate verification behavior. |mode| is +// one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is +// used to customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_verify( + SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); + +// SSL_set_verify configures certificate verification behavior. |mode| is one of +// the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to +// customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, + X509_STORE_CTX *store_ctx)); + +enum ssl_verify_result_t BORINGSSL_ENUM_INT { + ssl_verify_ok, + ssl_verify_invalid, + ssl_verify_retry, +}; + +// SSL_CTX_set_custom_verify configures certificate verification. |mode| is one +// of the |SSL_VERIFY_*| values defined above. |callback| performs the +// certificate verification. +// +// The callback may call |SSL_get0_peer_certificates| for the certificate chain +// to validate. The callback should return |ssl_verify_ok| if the certificate is +// valid. If the certificate is invalid, the callback should return +// |ssl_verify_invalid| and optionally set |*out_alert| to an alert to send to +// the peer. Some useful alerts include |SSL_AD_CERTIFICATE_EXPIRED|, +// |SSL_AD_CERTIFICATE_REVOKED|, |SSL_AD_UNKNOWN_CA|, |SSL_AD_BAD_CERTIFICATE|, +// |SSL_AD_CERTIFICATE_UNKNOWN|, and |SSL_AD_INTERNAL_ERROR|. See RFC 5246 +// section 7.2.2 for their precise meanings. If unspecified, +// |SSL_AD_CERTIFICATE_UNKNOWN| will be sent by default. +// +// To verify a certificate asynchronously, the callback may return +// |ssl_verify_retry|. The handshake will then pause with |SSL_get_error| +// returning |SSL_ERROR_WANT_CERTIFICATE_VERIFY|. +OPENSSL_EXPORT void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_set_custom_verify behaves like |SSL_CTX_set_custom_verify| but configures +// an individual |SSL|. +OPENSSL_EXPORT void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +// SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify| +// or |SSL_set_verify|. It returns -1 on error. +OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl); + +// SSL_CTX_get_verify_callback returns the callback set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or +// |SSL_set_verify|. +OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_set1_host sets a DNS name that will be required to be present in the +// verified leaf certificate. It returns one on success and zero on error. +// +// Note: unless _some_ name checking is performed, certificate validation is +// ineffective. Simply checking that a host has some certificate from a CA is +// rarely meaningful—you have to check that the CA believed that the host was +// who you expect to be talking to. +OPENSSL_EXPORT int SSL_set1_host(SSL *ssl, const char *hostname); + +// SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain +// accepted in verification. This number does not include the leaf, so a depth +// of 1 allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +// SSL_set_verify_depth sets the maximum depth of a certificate chain accepted +// in verification. This number does not include the leaf, so a depth of 1 +// allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth); + +// SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted +// in verification. +OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +// SSL_get_verify_depth returns the maximum depth of a certificate accepted in +// verification. +OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl); + +// SSL_CTX_set1_param sets verification parameters from |param|. It returns one +// on success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, + const X509_VERIFY_PARAM *param); + +// SSL_set1_param sets verification parameters from |param|. It returns one on +// success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, + const X509_VERIFY_PARAM *param); + +// SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); + +// SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +// SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); + +// SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose); + +// SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); + +// SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust); + +// SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes +// ownership of |store|. The store is used for certificate verification. +// +// The store is also used for the auto-chaining feature, but this is deprecated. +// See also |SSL_MODE_NO_AUTO_CHAIN|. +OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +// SSL_CTX_get_cert_store returns |ctx|'s certificate store. +OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +// SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust +// anchors into |ctx|'s store. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +// SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from +// |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed, +// it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed, +// it is treated as a directory in OpenSSL's hashed directory format. It returns +// one on success and zero on failure. +// +// See +// https://www.openssl.org/docs/man1.1.0/man3/SSL_CTX_load_verify_locations.html +// for documentation on the directory format. +OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, + const char *ca_file, + const char *ca_dir); + +// SSL_get_verify_result returns the result of certificate verification. It is +// either |X509_V_OK| or a |X509_V_ERR_*| value. +OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl); + +// SSL_alert_from_verify_result returns the SSL alert code, such as +// |SSL_AD_CERTIFICATE_EXPIRED|, that corresponds to an |X509_V_ERR_*| value. +// The return value is always an alert, even when |result| is |X509_V_OK|. +OPENSSL_EXPORT int SSL_alert_from_verify_result(long result); + +// SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up +// the |SSL| associated with an |X509_STORE_CTX| in the verify callback. +OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +// SSL_CTX_set_cert_verify_callback sets a custom callback to be called on +// certificate verification rather than |X509_verify_cert|. |store_ctx| contains +// the verification parameters. The callback should return one on success and +// zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a +// verification result. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the +// |SSL| object from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback( + SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg), + void *arg); + +// SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end +// of a connection) to request SCTs from the server. See +// https://tools.ietf.org/html/rfc6962. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_enable_signed_cert_timestamps(SSL *ssl); + +// SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL +// objects created from |ctx|. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx); + +// SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a +// connection) to request a stapled OCSP response from the server. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_enable_ocsp_stapling(SSL *ssl); + +// SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects +// created from |ctx|. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx); + +// SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL_CTX|. +OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL|. +OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_CTX_set_verify_algorithm_prefs configures |ctx| to use |prefs| as the +// preference list when verifying signatures from the peer's long-term key. It +// returns one on zero on error. |prefs| should not include the internal-only +// value |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_verify_algorithm_prefs configures |ssl| to use |prefs| as the +// preference list when verifying signatures from the peer's long-term key. It +// returns one on zero on error. |prefs| should not include the internal-only +// value |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_set_verify_algorithm_prefs(SSL *ssl, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_hostflags calls |X509_VERIFY_PARAM_set_hostflags| on the +// |X509_VERIFY_PARAM| associated with this |SSL*|. The |flags| argument +// should be one of the |X509_CHECK_*| constants. +OPENSSL_EXPORT void SSL_set_hostflags(SSL *ssl, unsigned flags); + + +// Client certificate CA list. +// +// When requesting a client certificate, a server may advertise a list of +// certificate authorities which are accepted. These functions may be used to +// configure this list. + +// SSL_set_client_CA_list sets |ssl|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl, + STACK_OF(X509_NAME) *name_list); + +// SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, + STACK_OF(X509_NAME) *name_list); + +// SSL_set0_client_CAs sets |ssl|'s client certificate CA list to |name_list|, +// which should contain DER-encoded distinguished names (RFC 5280). It takes +// ownership of |name_list|. +OPENSSL_EXPORT void SSL_set0_client_CAs(SSL *ssl, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_CTX_set0_client_CAs sets |ctx|'s client certificate CA list to +// |name_list|, which should contain DER-encoded distinguished names (RFC 5280). +// It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl| +// has not been configured as a client, this is the list configured by +// |SSL_CTX_set_client_CA_list|. +// +// If configured as a client, it returns the client certificate CA list sent by +// the server. In this mode, the behavior is undefined except during the +// callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or +// when the handshake is paused because of them. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +// SSL_get0_server_requested_CAs returns the CAs sent by a server to guide a +// client in certificate selection. They are a series of DER-encoded X.509 +// names. This function may only be called during a callback set by +// |SSL_CTX_set_cert_cb| or when the handshake is paused because of it. +// +// The returned stack is owned by |ssl|, as are its contents. It should not be +// used past the point where the handshake is restarted after the callback. +OPENSSL_EXPORT const STACK_OF(CRYPTO_BUFFER) * + SSL_get0_server_requested_CAs(const SSL *ssl); + +// SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. +OPENSSL_EXPORT STACK_OF(X509_NAME) * + SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +// SSL_add_client_CA appends |x509|'s subject to the client certificate CA list. +// It returns one on success or zero on error. The caller retains ownership of +// |x509|. +OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509); + +// SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA +// list. It returns one on success or zero on error. The caller retains +// ownership of |x509|. +OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); + +// SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from +// it. It returns a newly-allocated stack of the certificate subjects or NULL +// on error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); + +// SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on +// success or NULL on allocation error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); + +// SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file| +// but appends the result to |out|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *file); + + +// Server name indication. +// +// The server_name extension (RFC 3546) allows the client to advertise the name +// of the server it is connecting to. This is used in virtual hosting +// deployments to select one of a several certificates on a single IP. Only the +// host_name name type is supported. + +#define TLSEXT_NAMETYPE_host_name 0 + +// SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name| +// in the server_name extension. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name); + +// SSL_get_servername, for a server, returns the hostname supplied by the +// client or NULL if there was none. The |type| argument must be +// |TLSEXT_NAMETYPE_host_name|. +OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type); + +// SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name| +// if the client sent a hostname and -1 otherwise. +OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl); + +// SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on +// the server after ClientHello extensions have been parsed and returns one. +// The callback may use |SSL_get_servername| to examine the server_name +// extension and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be +// set by calling |SSL_CTX_set_tlsext_servername_arg|. +// +// If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is +// not acknowledged in the ServerHello. If the return value is +// |SSL_TLSEXT_ERR_ALERT_FATAL|, then |*out_alert| is the alert to send, +// defaulting to |SSL_AD_UNRECOGNIZED_NAME|. |SSL_TLSEXT_ERR_ALERT_WARNING| is +// ignored and treated as |SSL_TLSEXT_ERR_OK|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)); + +// SSL_CTX_set_tlsext_servername_arg sets the argument to the servername +// callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg); + +// SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + +// SSL_set_SSL_CTX changes |ssl|'s |SSL_CTX|. |ssl| will use the +// certificate-related settings from |ctx|, and |SSL_get_SSL_CTX| will report +// |ctx|. This function may be used during the callbacks registered by +// |SSL_CTX_set_select_certificate_cb|, +// |SSL_CTX_set_tlsext_servername_callback|, and |SSL_CTX_set_cert_cb| or when +// the handshake is paused from them. It is typically used to switch +// certificates based on SNI. +// +// Note the session cache and related settings will continue to use the initial +// |SSL_CTX|. Callers should use |SSL_CTX_set_session_id_context| to partition +// the session cache between different domains. +// +// TODO(davidben): Should other settings change after this call? +OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); + + +// Application-layer protocol negotiation. +// +// The ALPN extension (RFC 7301) allows negotiating different application-layer +// protocols over a single port. This is used, for example, to negotiate +// HTTP/2. + +// SSL_CTX_set_alpn_protos sets the client ALPN protocol list on |ctx| to +// |protos|. |protos| must be in wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings), or the empty string to disable ALPN. It returns +// zero on success and one on failure. Configuring a non-empty string enables +// ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len); + +// SSL_set_alpn_protos sets the client ALPN protocol list on |ssl| to |protos|. +// |protos| must be in wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings), or the empty string to disable ALPN. It returns +// zero on success and one on failure. Configuring a non-empty string enables +// ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, + unsigned protos_len); + +// SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called +// during ClientHello processing in order to select an ALPN protocol from the +// client's list of offered protocols. +// +// The callback is passed a wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings) ALPN protocol list in |in|. To select a protocol, +// the callback should set |*out| and |*out_len| to the selected protocol and +// return |SSL_TLSEXT_ERR_OK| on success. It does not pass ownership of the +// buffer, so |*out| should point to a static string, a buffer that outlives the +// callback call, or the corresponding entry in |in|. +// +// If the server supports ALPN, but there are no protocols in common, the +// callback should return |SSL_TLSEXT_ERR_ALERT_FATAL| to abort the connection +// with a no_application_protocol alert. +// +// If the server does not support ALPN, it can return |SSL_TLSEXT_ERR_NOACK| to +// continue the handshake without negotiating a protocol. This may be useful if +// multiple server configurations share an |SSL_CTX|, only some of which have +// ALPN protocols configured. +// +// |SSL_TLSEXT_ERR_ALERT_WARNING| is ignored and will be treated as +// |SSL_TLSEXT_ERR_NOACK|. +// +// The callback will only be called if the client supports ALPN. Callers that +// wish to require ALPN for all clients must check |SSL_get0_alpn_selected| +// after the handshake. In QUIC connections, this is done automatically. +// +// The cipher suite is selected before negotiating ALPN. The callback may use +// |SSL_get_pending_cipher| to query the cipher suite. This may be used to +// implement HTTP/2's cipher suite constraints. +OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|. +// On return it sets |*out_data| to point to |*out_len| bytes of protocol name +// (not including the leading length-prefix byte). If the server didn't respond +// with a negotiated protocol then |*out_len| will be zero. +OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// SSL_CTX_set_allow_unknown_alpn_protos configures client connections on |ctx| +// to allow unknown ALPN protocols from the server. Otherwise, by default, the +// client will require that the protocol be advertised in +// |SSL_CTX_set_alpn_protos|. +OPENSSL_EXPORT void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, + int enabled); + + +// Application-layer protocol settings +// +// The ALPS extension (draft-vvv-tls-alps) allows exchanging application-layer +// settings in the TLS handshake for applications negotiated with ALPN. Note +// that, when ALPS is negotiated, the client and server each advertise their own +// settings, so there are functions to both configure setting to send and query +// received settings. + +// SSL_add_application_settings configures |ssl| to enable ALPS with ALPN +// protocol |proto|, sending an ALPS value of |settings|. It returns one on +// success and zero on error. If |proto| is negotiated via ALPN and the peer +// supports ALPS, |settings| will be sent to the peer. The peer's ALPS value can +// be retrieved with |SSL_get0_peer_application_settings|. +// +// On the client, this function should be called before the handshake, once for +// each supported ALPN protocol which uses ALPS. |proto| must be included in the +// client's ALPN configuration (see |SSL_CTX_set_alpn_protos| and +// |SSL_set_alpn_protos|). On the server, ALPS can be preconfigured for each +// protocol as in the client, or configuration can be deferred to the ALPN +// callback (see |SSL_CTX_set_alpn_select_cb|), in which case only the selected +// protocol needs to be configured. +// +// ALPS can be independently configured from 0-RTT, however changes in protocol +// settings will fallback to 1-RTT to negotiate the new value, so it is +// recommended for |settings| to be relatively stable. +OPENSSL_EXPORT int SSL_add_application_settings(SSL *ssl, const uint8_t *proto, + size_t proto_len, + const uint8_t *settings, + size_t settings_len); + +// SSL_get0_peer_application_settings sets |*out_data| and |*out_len| to a +// buffer containing the peer's ALPS value, or the empty string if ALPS was not +// negotiated. Note an empty string could also indicate the peer sent an empty +// settings value. Use |SSL_has_application_settings| to check if ALPS was +// negotiated. The output buffer is owned by |ssl| and is valid until the next +// time |ssl| is modified. +OPENSSL_EXPORT void SSL_get0_peer_application_settings(const SSL *ssl, + const uint8_t **out_data, + size_t *out_len); + +// SSL_has_application_settings returns one if ALPS was negotiated on this +// connection and zero otherwise. +OPENSSL_EXPORT int SSL_has_application_settings(const SSL *ssl); + + +// Certificate compression. +// +// Certificates in TLS 1.3 can be compressed (RFC 8879). BoringSSL supports this +// as both a client and a server, but does not link against any specific +// compression libraries in order to keep dependencies to a minimum. Instead, +// hooks for compression and decompression can be installed in an |SSL_CTX| to +// enable support. + +// ssl_cert_compression_func_t is a pointer to a function that performs +// compression. It must write the compressed representation of |in| to |out|, +// returning one on success and zero on error. The results of compressing +// certificates are not cached internally. Implementations may wish to implement +// their own cache if they expect it to be useful given the certificates that +// they serve. +typedef int (*ssl_cert_compression_func_t)(SSL *ssl, CBB *out, + const uint8_t *in, size_t in_len); + +// ssl_cert_decompression_func_t is a pointer to a function that performs +// decompression. The compressed data from the peer is passed as |in| and the +// decompressed result must be exactly |uncompressed_len| bytes long. It returns +// one on success, in which case |*out| must be set to the result of +// decompressing |in|, or zero on error. Setting |*out| transfers ownership, +// i.e. |CRYPTO_BUFFER_free| will be called on |*out| at some point in the +// future. The results of decompressions are not cached internally. +// Implementations may wish to implement their own cache if they expect it to be +// useful. +typedef int (*ssl_cert_decompression_func_t)(SSL *ssl, CRYPTO_BUFFER **out, + size_t uncompressed_len, + const uint8_t *in, size_t in_len); + +// SSL_CTX_add_cert_compression_alg registers a certificate compression +// algorithm on |ctx| with ID |alg_id|. (The value of |alg_id| should be an IANA +// assigned value and each can only be registered once.) +// +// One of the function pointers may be NULL to avoid having to implement both +// sides of a compression algorithm if you're only going to use it in one +// direction. In this case, the unimplemented direction acts like it was never +// configured. +// +// For a server, algorithms are registered in preference order with the most +// preferable first. It returns one on success or zero on error. +OPENSSL_EXPORT int SSL_CTX_add_cert_compression_alg( + SSL_CTX *ctx, uint16_t alg_id, ssl_cert_compression_func_t compress, + ssl_cert_decompression_func_t decompress); + + +// Next protocol negotiation. +// +// The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN +// and deprecated in favor of it. + +// SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a +// TLS server needs a list of supported protocols for Next Protocol +// Negotiation. The returned list must be in wire format. The list is returned +// by setting |*out| to point to it and |*out_len| to its length. This memory +// will not be modified, but one should assume that |ssl| keeps a reference to +// it. +// +// The callback should return |SSL_TLSEXT_ERR_OK| if it wishes to advertise. +// Otherwise, no such extension will be included in the ServerHello. +OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *arg); + +// SSL_CTX_set_next_proto_select_cb sets a callback that is called when a client +// needs to select a protocol from the server's provided list. |*out| must be +// set to point to the selected protocol (which may be within |in|). The length +// of the protocol name must be written into |*out_len|. The server's advertised +// protocols are provided in |in| and |in_len|. The callback can assume that +// |in| is syntactically valid. +// +// The client must select a protocol. It is fatal to the connection if this +// callback returns a value other than |SSL_TLSEXT_ERR_OK|. +// +// Configuring this callback enables NPN on a client. +OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to +// the client's requested protocol for this connection. If the client didn't +// request any protocol, then |*out_data| is set to NULL. +// +// Note that the client can request any protocol it chooses. The value returned +// from this function need not be a member of the list of supported protocols +// provided by the server. +OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// SSL_select_next_proto implements the standard protocol selection. It is +// expected that this function is called from the callback set by +// |SSL_CTX_set_next_proto_select_cb|. +// +// |peer| and |supported| must be vectors of 8-bit, length-prefixed byte strings +// containing the peer and locally-configured protocols, respectively. The +// length byte itself is not included in the length. A byte string of length 0 +// is invalid. No byte string may be truncated. |supported| is assumed to be +// non-empty. +// +// This function finds the first protocol in |peer| which is also in +// |supported|. If one was found, it sets |*out| and |*out_len| to point to it +// and returns |OPENSSL_NPN_NEGOTIATED|. Otherwise, it returns +// |OPENSSL_NPN_NO_OVERLAP| and sets |*out| and |*out_len| to the first +// supported protocol. +OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, + const uint8_t *peer, unsigned peer_len, + const uint8_t *supported, + unsigned supported_len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + + +// Channel ID. +// +// See draft-balfanz-tls-channelid-01. This is an old, experimental mechanism +// and should not be used in new code. + +// SSL_CTX_set_tls_channel_id_enabled configures whether connections associated +// with |ctx| should enable Channel ID as a server. +OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, + int enabled); + +// SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel +// ID as a server. +OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled); + +// SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID +// to compatible servers. |private_key| must be a P-256 EC key. It returns one +// on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, + EVP_PKEY *private_key); + +// SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to +// compatible servers. |private_key| must be a P-256 EC key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key); + +// SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL| +// and copies up to the first |max_out| bytes into |out|. The Channel ID +// consists of the client's P-256 public key as an (x,y) pair where each is a +// 32-byte, big-endian field element. It returns 0 if the client didn't offer a +// Channel ID and the length of the complete Channel ID otherwise. This function +// always returns zero if |ssl| is a client. +OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, + size_t max_out); + + +// DTLS-SRTP. +// +// See RFC 5764. + +// srtp_protection_profile_st (aka |SRTP_PROTECTION_PROFILE|) is an SRTP +// profile for use with the use_srtp extension. +struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} /* SRTP_PROTECTION_PROFILE */; + +DEFINE_CONST_STACK_OF(SRTP_PROTECTION_PROFILE) + +// SRTP_* define constants for SRTP profiles. +#define SRTP_AES128_CM_SHA1_80 0x0001 +#define SRTP_AES128_CM_SHA1_32 0x0002 +#define SRTP_AES128_F8_SHA1_80 0x0003 +#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_NULL_SHA1_80 0x0005 +#define SRTP_NULL_SHA1_32 0x0006 +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +// SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from +// |ctx|. |profile| contains a colon-separated list of profile names. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a +// colon-separated list of profile names. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles); + +// SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. +OPENSSL_EXPORT const STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles( + const SSL *ssl); + +// SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if +// SRTP was not negotiated. +OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile( + SSL *ssl); + + +// Pre-shared keys. +// +// Connections may be configured with PSK (Pre-Shared Key) cipher suites. These +// authenticate using out-of-band pre-shared keys rather than certificates. See +// RFC 4279. +// +// This implementation uses NUL-terminated C strings for identities and identity +// hints, so values with a NUL character are not supported. (RFC 4279 does not +// specify the format of an identity.) + +// PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity, +// excluding the NUL terminator. +#define PSK_MAX_IDENTITY_LEN 128 + +// PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. +#define PSK_MAX_PSK_LEN 256 + +// SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. +// +// The callback is passed the identity hint in |hint| or NULL if none was +// provided. It should select a PSK identity and write the identity and the +// corresponding PSK to |identity| and |psk|, respectively. The identity is +// written as a NUL-terminated C string of length (excluding the NUL terminator) +// at most |max_identity_len|. The PSK's length must be at most |max_psk_len|. +// The callback returns the length of the PSK or 0 if no suitable identity was +// found. +OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. See also |SSL_CTX_set_psk_client_callback|. +OPENSSL_EXPORT void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. +// +// The callback is passed the identity in |identity|. It should write a PSK of +// length at most |max_psk_len| to |psk| and return the number of bytes written +// or zero if the PSK identity is unknown. +OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. See also |SSL_CTX_set_psk_server_callback|. +OPENSSL_EXPORT void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, + const char *identity_hint); + +// SSL_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl, + const char *identity_hint); + +// SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl| +// or NULL if there is none. +OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl); + +// SSL_get_psk_identity, after the handshake completes, returns the PSK identity +// that was negotiated by |ssl| or NULL if PSK was not used. +OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); + + +// Delegated credentials. +// +// *** EXPERIMENTAL — PRONE TO CHANGE *** +// +// draft-ietf-tls-subcerts is a proposed extension for TLS 1.3 and above that +// allows an end point to use its certificate to delegate credentials for +// authentication. If the peer indicates support for this extension, then this +// host may use a delegated credential to sign the handshake. Once issued, +// credentials can't be revoked. In order to mitigate the damage in case the +// credential secret key is compromised, the credential is only valid for a +// short time (days, hours, or even minutes). This library implements draft-03 +// of the protocol spec. +// +// The extension ID has not been assigned; we're using 0xff02 for the time +// being. Currently only the server side is implemented. +// +// Servers configure a DC for use in the handshake via +// |SSL_set1_delegated_credential|. It must be signed by the host's end-entity +// certificate as defined in draft-ietf-tls-subcerts-03. + +// SSL_set1_delegated_credential configures the delegated credential (DC) that +// will be sent to the peer for the current connection. |dc| is the DC in wire +// format, and |pkey| or |key_method| is the corresponding private key. +// Currently (as of draft-03), only servers may configure a DC to use in the +// handshake. +// +// The DC will only be used if the protocol version is correct and the signature +// scheme is supported by the peer. If not, the DC will not be negotiated and +// the handshake will use the private key (or private key method) associated +// with the certificate. +OPENSSL_EXPORT int SSL_set1_delegated_credential( + SSL *ssl, CRYPTO_BUFFER *dc, EVP_PKEY *pkey, + const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_delegated_credential_used returns one if a delegated credential was used +// and zero otherwise. +OPENSSL_EXPORT int SSL_delegated_credential_used(const SSL *ssl); + + +// QUIC integration. +// +// QUIC acts as an underlying transport for the TLS 1.3 handshake. The following +// functions allow a QUIC implementation to serve as the underlying transport as +// described in RFC 9001. +// +// When configured for QUIC, |SSL_do_handshake| will drive the handshake as +// before, but it will not use the configured |BIO|. It will call functions on +// |SSL_QUIC_METHOD| to configure secrets and send data. If data is needed from +// the peer, it will return |SSL_ERROR_WANT_READ|. As the caller receives data +// it can decrypt, it calls |SSL_provide_quic_data|. Subsequent +// |SSL_do_handshake| calls will then consume that data and progress the +// handshake. After the handshake is complete, the caller should continue to +// call |SSL_provide_quic_data| for any post-handshake data, followed by +// |SSL_process_quic_post_handshake| to process it. It is an error to call +// |SSL_read| and |SSL_write| in QUIC. +// +// 0-RTT behaves similarly to |TLS_method|'s usual behavior. |SSL_do_handshake| +// returns early as soon as the client (respectively, server) is allowed to send +// 0-RTT (respectively, half-RTT) data. The caller should then call +// |SSL_do_handshake| again to consume the remaining handshake messages and +// confirm the handshake. As a client, |SSL_ERROR_EARLY_DATA_REJECTED| and +// |SSL_reset_early_data_reject| behave as usual. +// +// See https://www.rfc-editor.org/rfc/rfc9001.html#section-4.1 for more details. +// +// To avoid DoS attacks, the QUIC implementation must limit the amount of data +// being queued up. The implementation can call +// |SSL_quic_max_handshake_flight_len| to get the maximum buffer length at each +// encryption level. +// +// QUIC implementations must additionally configure transport parameters with +// |SSL_set_quic_transport_params|. |SSL_get_peer_quic_transport_params| may be +// used to query the value received from the peer. BoringSSL handles this +// extension as an opaque byte string. The caller is responsible for serializing +// and parsing them. See https://www.rfc-editor.org/rfc/rfc9000#section-7.4 for +// details. +// +// QUIC additionally imposes restrictions on 0-RTT. In particular, the QUIC +// transport layer requires that if a server accepts 0-RTT data, then the +// transport parameters sent on the resumed connection must not lower any limits +// compared to the transport parameters that the server sent on the connection +// where the ticket for 0-RTT was issued. In effect, the server must remember +// the transport parameters with the ticket. Application protocols running on +// QUIC may impose similar restrictions, for example HTTP/3's restrictions on +// SETTINGS frames. +// +// BoringSSL implements this check by doing a byte-for-byte comparison of an +// opaque context passed in by the server. This context must be the same on the +// connection where the ticket was issued and the connection where that ticket +// is used for 0-RTT. If there is a mismatch, or the context was not set, +// BoringSSL will reject early data (but not reject the resumption attempt). +// This context is set via |SSL_set_quic_early_data_context| and should cover +// both transport parameters and any application state. +// |SSL_set_quic_early_data_context| must be called on the server with a +// non-empty context if the server is to support 0-RTT in QUIC. +// +// BoringSSL does not perform any client-side checks on the transport +// parameters received from a server that also accepted early data. It is up to +// the caller to verify that the received transport parameters do not lower any +// limits, and to close the QUIC connection if that is not the case. The same +// holds for any application protocol state remembered for 0-RTT, e.g. HTTP/3 +// SETTINGS. + +// ssl_encryption_level_t represents a specific QUIC encryption level used to +// transmit handshake messages. +enum ssl_encryption_level_t BORINGSSL_ENUM_INT { + ssl_encryption_initial = 0, + ssl_encryption_early_data, + ssl_encryption_handshake, + ssl_encryption_application, +}; + +// ssl_quic_method_st (aka |SSL_QUIC_METHOD|) describes custom QUIC hooks. +struct ssl_quic_method_st { + // set_read_secret configures the read secret and cipher suite for the given + // encryption level. It returns one on success and zero to terminate the + // handshake with an error. It will be called at most once per encryption + // level. + // + // BoringSSL will not release read keys before QUIC may use them. Once a level + // has been initialized, QUIC may begin processing data from it. Handshake + // data should be passed to |SSL_provide_quic_data| and application data (if + // |level| is |ssl_encryption_early_data| or |ssl_encryption_application|) may + // be processed according to the rules of the QUIC protocol. + // + // QUIC ACKs packets at the same encryption level they were received at, + // except that client |ssl_encryption_early_data| (0-RTT) packets trigger + // server |ssl_encryption_application| (1-RTT) ACKs. BoringSSL will always + // install ACK-writing keys with |set_write_secret| before the packet-reading + // keys with |set_read_secret|. This ensures the caller can always ACK any + // packet it decrypts. Note this means the server installs 1-RTT write keys + // before 0-RTT read keys. + // + // The converse is not true. An encryption level may be configured with write + // secrets a roundtrip before the corresponding secrets for reading ACKs is + // available. + int (*set_read_secret)(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, + size_t secret_len); + // set_write_secret behaves like |set_read_secret| but configures the write + // secret and cipher suite for the given encryption level. It will be called + // at most once per encryption level. + // + // BoringSSL will not release write keys before QUIC may use them. If |level| + // is |ssl_encryption_early_data| or |ssl_encryption_application|, QUIC may + // begin sending application data at |level|. However, note that BoringSSL + // configures server |ssl_encryption_application| write keys before the client + // Finished. This allows QUIC to send half-RTT data, but the handshake is not + // confirmed at this point and, if requesting client certificates, the client + // is not yet authenticated. + // + // See |set_read_secret| for additional invariants between packets and their + // ACKs. + // + // Note that, on 0-RTT reject, the |ssl_encryption_early_data| write secret + // may use a different cipher suite from the other keys. + int (*set_write_secret)(SSL *ssl, enum ssl_encryption_level_t level, + const SSL_CIPHER *cipher, const uint8_t *secret, + size_t secret_len); + // add_handshake_data adds handshake data to the current flight at the given + // encryption level. It returns one on success and zero on error. + // + // BoringSSL will pack data from a single encryption level together, but a + // single handshake flight may include multiple encryption levels. Callers + // should defer writing data to the network until |flush_flight| to better + // pack QUIC packets into transport datagrams. + // + // If |level| is not |ssl_encryption_initial|, this function will not be + // called before |level| is initialized with |set_write_secret|. + int (*add_handshake_data)(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len); + // flush_flight is called when the current flight is complete and should be + // written to the transport. Note a flight may contain data at several + // encryption levels. It returns one on success and zero on error. + int (*flush_flight)(SSL *ssl); + // send_alert sends a fatal alert at the specified encryption level. It + // returns one on success and zero on error. + // + // If |level| is not |ssl_encryption_initial|, this function will not be + // called before |level| is initialized with |set_write_secret|. + int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert); +}; + +// SSL_quic_max_handshake_flight_len returns returns the maximum number of bytes +// that may be received at the given encryption level. This function should be +// used to limit buffering in the QUIC implementation. +// +// See https://www.rfc-editor.org/rfc/rfc9000#section-7.5 +OPENSSL_EXPORT size_t SSL_quic_max_handshake_flight_len( + const SSL *ssl, enum ssl_encryption_level_t level); + +// SSL_quic_read_level returns the current read encryption level. +// +// TODO(davidben): Is it still necessary to expose this function to callers? +// QUICHE does not use it. +OPENSSL_EXPORT enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl); + +// SSL_quic_write_level returns the current write encryption level. +// +// TODO(davidben): Is it still necessary to expose this function to callers? +// QUICHE does not use it. +OPENSSL_EXPORT enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl); + +// SSL_provide_quic_data provides data from QUIC at a particular encryption +// level |level|. It returns one on success and zero on error. Note this +// function will return zero if the handshake is not expecting data from |level| +// at this time. The QUIC implementation should then close the connection with +// an error. +OPENSSL_EXPORT int SSL_provide_quic_data(SSL *ssl, + enum ssl_encryption_level_t level, + const uint8_t *data, size_t len); + + +// SSL_process_quic_post_handshake processes any data that QUIC has provided +// after the handshake has completed. This includes NewSessionTicket messages +// sent by the server. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_process_quic_post_handshake(SSL *ssl); + +// SSL_CTX_set_quic_method configures the QUIC hooks. This should only be +// configured with a minimum version of TLS 1.3. |quic_method| must remain valid +// for the lifetime of |ctx|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_quic_method(SSL_CTX *ctx, + const SSL_QUIC_METHOD *quic_method); + +// SSL_set_quic_method configures the QUIC hooks. This should only be +// configured with a minimum version of TLS 1.3. |quic_method| must remain valid +// for the lifetime of |ssl|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_quic_method(SSL *ssl, + const SSL_QUIC_METHOD *quic_method); + +// SSL_set_quic_transport_params configures |ssl| to send |params| (of length +// |params_len|) in the quic_transport_parameters extension in either the +// ClientHello or EncryptedExtensions handshake message. It is an error to set +// transport parameters if |ssl| is not configured for QUIC. The buffer pointed +// to by |params| only need be valid for the duration of the call to this +// function. This function returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); + +// SSL_get_peer_quic_transport_params provides the caller with the value of the +// quic_transport_parameters extension sent by the peer. A pointer to the buffer +// containing the TransportParameters will be put in |*out_params|, and its +// length in |*params_len|. This buffer will be valid for the lifetime of the +// |SSL|. If no params were received from the peer, |*out_params_len| will be 0. +OPENSSL_EXPORT void SSL_get_peer_quic_transport_params( + const SSL *ssl, const uint8_t **out_params, size_t *out_params_len); + +// SSL_set_quic_use_legacy_codepoint configures whether to use the legacy QUIC +// extension codepoint 0xffa5 as opposed to the official value 57. Call with +// |use_legacy| set to 1 to use 0xffa5 and call with 0 to use 57. By default, +// the standard code point is used. +OPENSSL_EXPORT void SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy); + +// SSL_set_quic_early_data_context configures a context string in QUIC servers +// for accepting early data. If a resumption connection offers early data, the +// server will check if the value matches that of the connection which minted +// the ticket. If not, resumption still succeeds but early data is rejected. +// This should include all QUIC Transport Parameters except ones specified that +// the client MUST NOT remember. This should also include any application +// protocol-specific state. For HTTP/3, this should be the serialized server +// SETTINGS frame and the QUIC Transport Parameters (except the stateless reset +// token). +// +// This function may be called before |SSL_do_handshake| or during server +// certificate selection. It returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_quic_early_data_context(SSL *ssl, + const uint8_t *context, + size_t context_len); + + +// Early data. +// +// WARNING: 0-RTT support in BoringSSL is currently experimental and not fully +// implemented. It may cause interoperability or security failures when used. +// +// Early data, or 0-RTT, is a feature in TLS 1.3 which allows clients to send +// data on the first flight during a resumption handshake. This can save a +// round-trip in some application protocols. +// +// WARNING: A 0-RTT handshake has different security properties from normal +// handshake, so it is off by default unless opted in. In particular, early data +// is replayable by a network attacker. Callers must account for this when +// sending or processing data before the handshake is confirmed. See RFC 8446 +// for more information. +// +// As a server, if early data is accepted, |SSL_do_handshake| will complete as +// soon as the ClientHello is processed and server flight sent. |SSL_write| may +// be used to send half-RTT data. |SSL_read| will consume early data and +// transition to 1-RTT data as appropriate. Prior to the transition, +// |SSL_in_init| will report the handshake is still in progress. Callers may use +// it or |SSL_in_early_data| to defer or reject requests as needed. +// +// Early data as a client is more complex. If the offered session (see +// |SSL_set_session|) is 0-RTT-capable, the handshake will return after sending +// the ClientHello. The predicted peer certificates and ALPN protocol will be +// available via the usual APIs. |SSL_write| will write early data, up to the +// session's limit. Writes past this limit and |SSL_read| will complete the +// handshake before continuing. Callers may also call |SSL_do_handshake| again +// to complete the handshake sooner. +// +// If the server accepts early data, the handshake will succeed. |SSL_read| and +// |SSL_write| will then act as in a 1-RTT handshake. The peer certificates and +// ALPN protocol will be as predicted and need not be re-queried. +// +// If the server rejects early data, |SSL_do_handshake| (and thus |SSL_read| and +// |SSL_write|) will then fail with |SSL_get_error| returning +// |SSL_ERROR_EARLY_DATA_REJECTED|. The caller should treat this as a connection +// error and most likely perform a high-level retry. Note the server may still +// have processed the early data due to attacker replays. +// +// To then continue the handshake on the original connection, use +// |SSL_reset_early_data_reject|. The connection will then behave as one which +// had not yet completed the handshake. This allows a faster retry than making a +// fresh connection. |SSL_do_handshake| will complete the full handshake, +// possibly resulting in different peer certificates, ALPN protocol, and other +// properties. The caller must disregard any values from before the reset and +// query again. +// +// Finally, to implement the fallback described in RFC 8446 appendix D.3, retry +// on a fresh connection without 0-RTT if the handshake fails with +// |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. + +// SSL_CTX_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled); + +// SSL_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ssl|. See |SSL_CTX_set_early_data_enabled| for more +// information. +OPENSSL_EXPORT void SSL_set_early_data_enabled(SSL *ssl, int enabled); + +// SSL_in_early_data returns one if |ssl| has a pending handshake that has +// progressed enough to send or receive early data. Clients may call |SSL_write| +// to send early data, but |SSL_read| will complete the handshake before +// accepting application data. Servers may call |SSL_read| to read early data +// and |SSL_write| to send half-RTT data. +OPENSSL_EXPORT int SSL_in_early_data(const SSL *ssl); + +// SSL_SESSION_early_data_capable returns whether early data would have been +// attempted with |session| if enabled. +OPENSSL_EXPORT int SSL_SESSION_early_data_capable(const SSL_SESSION *session); + +// SSL_SESSION_copy_without_early_data returns a copy of |session| with early +// data disabled. If |session| already does not support early data, it returns +// |session| with the reference count increased. The caller takes ownership of +// the result and must release it with |SSL_SESSION_free|. +// +// This function may be used on the client to clear early data support from +// existing sessions when the server rejects early data. In particular, +// |SSL_R_WRONG_VERSION_ON_EARLY_DATA| requires a fresh connection to retry, and +// the client would not want 0-RTT enabled for the next connection attempt. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_copy_without_early_data( + SSL_SESSION *session); + +// SSL_early_data_accepted returns whether early data was accepted on the +// handshake performed by |ssl|. +OPENSSL_EXPORT int SSL_early_data_accepted(const SSL *ssl); + +// SSL_reset_early_data_reject resets |ssl| after an early data reject. All +// 0-RTT state is discarded, including any pending |SSL_write| calls. The caller +// should treat |ssl| as a logically fresh connection, usually by driving the +// handshake to completion using |SSL_do_handshake|. +// +// It is an error to call this function on an |SSL| object that is not signaling +// |SSL_ERROR_EARLY_DATA_REJECTED|. +OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl); + +// SSL_get_ticket_age_skew returns the difference, in seconds, between the +// client-sent ticket age and the server-computed value in TLS 1.3 server +// connections which resumed a session. +OPENSSL_EXPORT int32_t SSL_get_ticket_age_skew(const SSL *ssl); + +// An ssl_early_data_reason_t describes why 0-RTT was accepted or rejected. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum ssl_early_data_reason_t BORINGSSL_ENUM_INT { + // The handshake has not progressed far enough for the 0-RTT status to be + // known. + ssl_early_data_unknown = 0, + // 0-RTT is disabled for this connection. + ssl_early_data_disabled = 1, + // 0-RTT was accepted. + ssl_early_data_accepted = 2, + // The negotiated protocol version does not support 0-RTT. + ssl_early_data_protocol_version = 3, + // The peer declined to offer or accept 0-RTT for an unknown reason. + ssl_early_data_peer_declined = 4, + // The client did not offer a session. + ssl_early_data_no_session_offered = 5, + // The server declined to resume the session. + ssl_early_data_session_not_resumed = 6, + // The session does not support 0-RTT. + ssl_early_data_unsupported_for_session = 7, + // The server sent a HelloRetryRequest. + ssl_early_data_hello_retry_request = 8, + // The negotiated ALPN protocol did not match the session. + ssl_early_data_alpn_mismatch = 9, + // The connection negotiated Channel ID, which is incompatible with 0-RTT. + ssl_early_data_channel_id = 10, + // Value 11 is reserved. (It has historically |ssl_early_data_token_binding|.) + // The client and server ticket age were too far apart. + ssl_early_data_ticket_age_skew = 12, + // QUIC parameters differ between this connection and the original. + ssl_early_data_quic_parameter_mismatch = 13, + // The application settings did not match the session. + ssl_early_data_alps_mismatch = 14, + // The value of the largest entry. + ssl_early_data_reason_max_value = ssl_early_data_alps_mismatch, +}; + +// SSL_get_early_data_reason returns details why 0-RTT was accepted or rejected +// on |ssl|. This is primarily useful on the server. +OPENSSL_EXPORT enum ssl_early_data_reason_t SSL_get_early_data_reason( + const SSL *ssl); + +// SSL_early_data_reason_string returns a string representation for |reason|, or +// NULL if |reason| is unknown. This function may be used for logging. +OPENSSL_EXPORT const char *SSL_early_data_reason_string( + enum ssl_early_data_reason_t reason); + + +// Encrypted ClientHello. +// +// ECH is a mechanism for encrypting the entire ClientHello message in TLS 1.3. +// This can prevent observers from seeing cleartext information about the +// connection, such as the server_name extension. +// +// By default, BoringSSL will treat the server name, session ticket, and client +// certificate as secret, but most other parameters, such as the ALPN protocol +// list will be treated as public and sent in the cleartext ClientHello. Other +// APIs may be added for applications with different secrecy requirements. +// +// ECH support in BoringSSL is still experimental and under development. +// +// See https://tools.ietf.org/html/draft-ietf-tls-esni-13. + +// SSL_set_enable_ech_grease configures whether the client will send a GREASE +// ECH extension when no supported ECHConfig is available. +OPENSSL_EXPORT void SSL_set_enable_ech_grease(SSL *ssl, int enable); + +// SSL_set1_ech_config_list configures |ssl| to, as a client, offer ECH with the +// specified configuration. |ech_config_list| should contain a serialized +// ECHConfigList structure. It returns one on success and zero on error. +// +// This function returns an error if the input is malformed. If the input is +// valid but none of the ECHConfigs implement supported parameters, it will +// return success and proceed without ECH. +// +// If a supported ECHConfig is found, |ssl| will encrypt the true ClientHello +// parameters. If the server cannot decrypt it, e.g. due to a key mismatch, ECH +// has a recovery flow. |ssl| will handshake using the cleartext parameters, +// including a public name in the ECHConfig. If using +// |SSL_CTX_set_custom_verify|, callers should use |SSL_get0_ech_name_override| +// to verify the certificate with the public name. If using the built-in +// verifier, the |X509_STORE_CTX| will be configured automatically. +// +// If no other errors are found in this handshake, it will fail with +// |SSL_R_ECH_REJECTED|. Since it didn't use the true parameters, the connection +// cannot be used for application data. Instead, callers should handle this +// error by calling |SSL_get0_ech_retry_configs| and retrying the connection +// with updated ECH parameters. If the retry also fails with +// |SSL_R_ECH_REJECTED|, the caller should report a connection failure. +OPENSSL_EXPORT int SSL_set1_ech_config_list(SSL *ssl, + const uint8_t *ech_config_list, + size_t ech_config_list_len); + +// SSL_get0_ech_name_override, if |ssl| is a client and the server rejected ECH, +// sets |*out_name| and |*out_name_len| to point to a buffer containing the ECH +// public name. Otherwise, the buffer will be empty. +// +// When offering ECH as a client, this function should be called during the +// certificate verification callback (see |SSL_CTX_set_custom_verify|). If +// |*out_name_len| is non-zero, the caller should verify the certificate against +// the result, interpreted as a DNS name, rather than the true server name. In +// this case, the handshake will never succeed and is only used to authenticate +// retry configs. See also |SSL_get0_ech_retry_configs|. +OPENSSL_EXPORT void SSL_get0_ech_name_override(const SSL *ssl, + const char **out_name, + size_t *out_name_len); + +// SSL_get0_ech_retry_configs sets |*out_retry_configs| and +// |*out_retry_configs_len| to a buffer containing a serialized ECHConfigList. +// If the server did not provide an ECHConfigList, |*out_retry_configs_len| will +// be zero. +// +// When handling an |SSL_R_ECH_REJECTED| error code as a client, callers should +// use this function to recover from potential key mismatches. If the result is +// non-empty, the caller should retry the connection, passing this buffer to +// |SSL_set1_ech_config_list|. If the result is empty, the server has rolled +// back ECH support, and the caller should retry without ECH. +// +// This function must only be called in response to an |SSL_R_ECH_REJECTED| +// error code. Calling this function on |ssl|s that have not authenticated the +// rejection handshake will assert in debug builds and otherwise return an +// unparsable list. +OPENSSL_EXPORT void SSL_get0_ech_retry_configs( + const SSL *ssl, const uint8_t **out_retry_configs, + size_t *out_retry_configs_len); + +// SSL_marshal_ech_config constructs a new serialized ECHConfig. On success, it +// sets |*out| to a newly-allocated buffer containing the result and |*out_len| +// to the size of the buffer. The caller must call |OPENSSL_free| on |*out| to +// release the memory. On failure, it returns zero. +// +// The |config_id| field is a single byte identifer for the ECHConfig. Reusing +// config IDs is allowed, but if multiple ECHConfigs with the same config ID are +// active at a time, server load may increase. See +// |SSL_ECH_KEYS_has_duplicate_config_id|. +// +// The public key and KEM algorithm are taken from |key|. |public_name| is the +// DNS name used to authenticate the recovery flow. |max_name_len| should be the +// length of the longest name in the ECHConfig's anonymity set and influences +// client padding decisions. +OPENSSL_EXPORT int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, + uint8_t config_id, + const EVP_HPKE_KEY *key, + const char *public_name, + size_t max_name_len); + +// SSL_ECH_KEYS_new returns a newly-allocated |SSL_ECH_KEYS| or NULL on error. +OPENSSL_EXPORT SSL_ECH_KEYS *SSL_ECH_KEYS_new(void); + +// SSL_ECH_KEYS_up_ref increments the reference count of |keys|. +OPENSSL_EXPORT void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys); + +// SSL_ECH_KEYS_free releases memory associated with |keys|. +OPENSSL_EXPORT void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys); + +// SSL_ECH_KEYS_add decodes |ech_config| as an ECHConfig and appends it with +// |key| to |keys|. If |is_retry_config| is non-zero, this config will be +// returned to the client on configuration mismatch. It returns one on success +// and zero on error. +// +// This function should be called successively to register each ECHConfig in +// decreasing order of preference. This configuration must be completed before +// setting |keys| on an |SSL_CTX| with |SSL_CTX_set1_ech_keys|. After that +// point, |keys| is immutable; no more ECHConfig values may be added. +// +// See also |SSL_CTX_set1_ech_keys|. +OPENSSL_EXPORT int SSL_ECH_KEYS_add(SSL_ECH_KEYS *keys, int is_retry_config, + const uint8_t *ech_config, + size_t ech_config_len, + const EVP_HPKE_KEY *key); + +// SSL_ECH_KEYS_has_duplicate_config_id returns one if |keys| has duplicate +// config IDs or zero otherwise. Duplicate config IDs still work, but may +// increase server load due to trial decryption. +OPENSSL_EXPORT int SSL_ECH_KEYS_has_duplicate_config_id( + const SSL_ECH_KEYS *keys); + +// SSL_ECH_KEYS_marshal_retry_configs serializes the retry configs in |keys| as +// an ECHConfigList. On success, it sets |*out| to a newly-allocated buffer +// containing the result and |*out_len| to the size of the buffer. The caller +// must call |OPENSSL_free| on |*out| to release the memory. On failure, it +// returns zero. +// +// This output may be advertised to clients in DNS. +OPENSSL_EXPORT int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, + uint8_t **out, + size_t *out_len); + +// SSL_CTX_set1_ech_keys configures |ctx| to use |keys| to decrypt encrypted +// ClientHellos. It returns one on success, and zero on failure. If |keys| does +// not contain any retry configs, this function will fail. Retry configs are +// marked as such when they are added to |keys| with |SSL_ECH_KEYS_add|. +// +// Once |keys| has been passed to this function, it is immutable. Unlike most +// |SSL_CTX| configuration functions, this function may be called even if |ctx| +// already has associated connections on multiple threads. This may be used to +// rotate keys in a long-lived server process. +// +// The configured ECHConfig values should also be advertised out-of-band via DNS +// (see draft-ietf-dnsop-svcb-https). Before advertising an ECHConfig in DNS, +// deployments should ensure all instances of the service are configured with +// the ECHConfig and corresponding private key. +// +// Only the most recent fully-deployed ECHConfigs should be advertised in DNS. +// |keys| may contain a newer set if those ECHConfigs are mid-deployment. It +// should also contain older sets, until the DNS change has rolled out and the +// old records have expired from caches. +// +// If there is a mismatch, |SSL| objects associated with |ctx| will complete the +// handshake using the cleartext ClientHello and send updated ECHConfig values +// to the client. The client will then retry to recover, but with a latency +// penalty. This recovery flow depends on the public name in the ECHConfig. +// Before advertising an ECHConfig in DNS, deployments must ensure all instances +// of the service can present a valid certificate for the public name. +// +// BoringSSL negotiates ECH before certificate selection callbacks are called, +// including |SSL_CTX_set_select_certificate_cb|. If ECH is negotiated, the +// reported |SSL_CLIENT_HELLO| structure and |SSL_get_servername| function will +// transparently reflect the inner ClientHello. Callers should select parameters +// based on these values to correctly handle ECH as well as the recovery flow. +OPENSSL_EXPORT int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys); + +// SSL_ech_accepted returns one if |ssl| negotiated ECH and zero otherwise. +OPENSSL_EXPORT int SSL_ech_accepted(const SSL *ssl); + + +// Alerts. +// +// TLS uses alerts to signal error conditions. Alerts have a type (warning or +// fatal) and description. OpenSSL internally handles fatal alerts with +// dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for close_notify, +// warning alerts are silently ignored and may only be surfaced with +// |SSL_CTX_set_info_callback|. + +// SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*| +// values. Any error code under |ERR_LIB_SSL| with an error reason above this +// value corresponds to an alert description. Consumers may add or subtract +// |SSL_AD_REASON_OFFSET| to convert between them. +// +// make_errors.go reserves error codes above 1000 for manually-assigned errors. +// This value must be kept in sync with reservedReasonCode in make_errors.h +#define SSL_AD_REASON_OFFSET 1000 + +// SSL_AD_* are alert descriptions. +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE // Legacy SSL 3.0 value +#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION +#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \ + TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED +#define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL +#define SSL_AD_ECH_REQUIRED TLS1_AD_ECH_REQUIRED + +// SSL_alert_type_string_long returns a string description of |value| as an +// alert type (warning or fatal). +OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value); + +// SSL_alert_desc_string_long returns a string description of |value| as an +// alert description or "unknown" if unknown. +OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value); + +// SSL_send_fatal_alert sends a fatal alert over |ssl| of the specified type, +// which should be one of the |SSL_AD_*| constants. It returns one on success +// and <= 0 on error. The caller should pass the return value into +// |SSL_get_error| to determine how to proceed. Once this function has been +// called, future calls to |SSL_write| will fail. +// +// If retrying a failed operation due to |SSL_ERROR_WANT_WRITE|, subsequent +// calls must use the same |alert| parameter. +OPENSSL_EXPORT int SSL_send_fatal_alert(SSL *ssl, uint8_t alert); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data); +OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx); +OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, + void *data); +OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, + int idx); +OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data); +OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); +OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + + +// Low-level record-layer state. + +// SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers +// underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the +// current IVs for the read and write directions. This is only meaningful for +// connections with implicit IVs (i.e. CBC mode with TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, + size_t *out_iv_len); + +// SSL_get_key_block_len returns the length of |ssl|'s key block. It is an error +// to call this function during a handshake. +OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl); + +// SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s +// current connection state. It is an error to call this function during a +// handshake. +OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out, + size_t out_len); + +// SSL_get_read_sequence returns, in TLS, the expected sequence number of the +// next incoming record in the current epoch. In DTLS, it returns the maximum +// sequence number received in the current epoch and includes the epoch number +// in the two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl); + +// SSL_get_write_sequence returns the sequence number of the next outgoing +// record in the current epoch. In DTLS, it includes the epoch number in the +// two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl); + +// SSL_CTX_set_record_protocol_version returns whether |version| is zero. +OPENSSL_EXPORT int SSL_CTX_set_record_protocol_version(SSL_CTX *ctx, + int version); + + +// Handshake hints. +// +// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** +// +// Some server deployments make asynchronous RPC calls in both ClientHello +// dispatch and private key operations. In TLS handshakes where the private key +// operation occurs in the first round-trip, this results in two consecutive RPC +// round-trips. Handshake hints allow the RPC service to predicte a signature. +// If correctly predicted, this can skip the second RPC call. +// +// First, the server installs a certificate selection callback (see +// |SSL_CTX_set_select_certificate_cb|). When that is called, it performs the +// RPC as before, but includes the ClientHello and a capabilities string from +// |SSL_serialize_capabilities|. +// +// Next, the RPC service creates its own |SSL| object, applies the results of +// certificate selection, calls |SSL_request_handshake_hints|, and runs the +// handshake. If this successfully computes handshake hints (see +// |SSL_serialize_handshake_hints|), the RPC server should send the hints +// alongside any certificate selection results. +// +// Finally, the server calls |SSL_set_handshake_hints| and applies any +// configuration from the RPC server. It then completes the handshake as before. +// If the hints apply, BoringSSL will use the predicted signature and skip the +// private key callbacks. Otherwise, BoringSSL will call private key callbacks +// to generate a signature as before. +// +// Callers should synchronize configuration across the two services. +// Configuration mismatches and some cases of version skew are not fatal, but +// may result in the hints not applying. Additionally, some handshake flows use +// the private key in later round-trips, such as TLS 1.3 HelloRetryRequest. In +// those cases, BoringSSL will not predict a signature as there is no benefit. +// Callers must allow for handshakes to complete without a predicted signature. +// +// For now, only TLS 1.3 is hinted. TLS 1.2 will work, but the hints will be +// empty. + +// SSL_serialize_capabilities writes an opaque byte string to |out| describing +// some of |ssl|'s capabilities. It returns one on success and zero on error. +// +// This string is used by BoringSSL internally to reduce the impact of version +// skew. +OPENSSL_EXPORT int SSL_serialize_capabilities(const SSL *ssl, CBB *out); + +// SSL_request_handshake_hints configures |ssl| to generate a handshake hint for +// |client_hello|. It returns one on success and zero on error. |client_hello| +// should contain a serialized ClientHello structure, from the |client_hello| +// and |client_hello_len| fields of the |SSL_CLIENT_HELLO| structure. +// |capabilities| should contain the output of |SSL_serialize_capabilities|. +// +// When configured, |ssl| will perform no I/O (so there is no need to configure +// |BIO|s). For QUIC, the caller should still configure an |SSL_QUIC_METHOD|, +// but the callbacks themselves will never be called and may be left NULL or +// report failure. |SSL_provide_quic_data| also should not be called. +// +// If hint generation is successful, |SSL_do_handshake| will stop the handshake +// early with |SSL_get_error| returning |SSL_ERROR_HANDSHAKE_HINTS_READY|. At +// this point, the caller should run |SSL_serialize_handshake_hints| to extract +// the resulting hints. +// +// Hint generation may fail if, e.g., |ssl| was unable to process the +// ClientHello. Callers should then complete the certificate selection RPC and +// continue the original handshake with no hint. It will likely fail, but this +// reports the correct alert to the client and is more robust in case of +// mismatch. +OPENSSL_EXPORT int SSL_request_handshake_hints(SSL *ssl, + const uint8_t *client_hello, + size_t client_hello_len, + const uint8_t *capabilities, + size_t capabilities_len); + +// SSL_serialize_handshake_hints writes an opaque byte string to |out| +// containing the handshake hints computed by |out|. It returns one on success +// and zero on error. This function should only be called if +// |SSL_request_handshake_hints| was configured and the handshake terminated +// with |SSL_ERROR_HANDSHAKE_HINTS_READY|. +// +// This string may be passed to |SSL_set_handshake_hints| on another |SSL| to +// avoid an extra signature call. +OPENSSL_EXPORT int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out); + +// SSL_set_handshake_hints configures |ssl| to use |hints| as handshake hints. +// It returns one on success and zero on error. The handshake will then continue +// as before, but apply predicted values from |hints| where applicable. +// +// Hints may contain connection and session secrets, so they must not leak and +// must come from a source trusted to terminate the connection. However, they +// will not change |ssl|'s configuration. The caller is responsible for +// serializing and applying options from the RPC server as needed. This ensures +// |ssl|'s behavior is self-consistent and consistent with the caller's local +// decisions. +OPENSSL_EXPORT int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, + size_t hints_len); + + +// Obscure functions. + +// SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|. +// This callback will be called when sending or receiving low-level record +// headers, complete handshake messages, ChangeCipherSpec, and alerts. +// |write_p| is one for outgoing messages and zero for incoming messages. +// +// For each record header, |cb| is called with |version| = 0 and |content_type| +// = |SSL3_RT_HEADER|. The |len| bytes from |buf| contain the header. Note that +// this does not include the record body. If the record is sealed, the length +// in the header is the length of the ciphertext. +// +// For each handshake message, ChangeCipherSpec, and alert, |version| is the +// protocol version and |content_type| is the corresponding record type. The +// |len| bytes from |buf| contain the handshake message, one-byte +// ChangeCipherSpec body, and two-byte alert, respectively. +// +// In connections that enable ECH, |cb| is additionally called with +// |content_type| = |SSL3_RT_CLIENT_HELLO_INNER| for each ClientHelloInner that +// is encrypted or decrypted. The |len| bytes from |buf| contain the +// ClientHelloInner, including the reconstructed outer extensions and handshake +// header. +// +// For a V2ClientHello, |version| is |SSL2_VERSION|, |content_type| is zero, and +// the |len| bytes from |buf| contain the V2ClientHello structure. +OPENSSL_EXPORT void SSL_CTX_set_msg_callback( + SSL_CTX *ctx, void (*cb)(int is_write, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg)); + +// SSL_CTX_set_msg_callback_arg sets the |arg| parameter of the message +// callback. +OPENSSL_EXPORT void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg); + +// SSL_set_msg_callback installs |cb| as the message callback of |ssl|. See +// |SSL_CTX_set_msg_callback| for when this callback is called. +OPENSSL_EXPORT void SSL_set_msg_callback( + SSL *ssl, void (*cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg)); + +// SSL_set_msg_callback_arg sets the |arg| parameter of the message callback. +OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg); + +// SSL_CTX_set_keylog_callback configures a callback to log key material. This +// is intended for debugging use with tools like Wireshark. The |cb| function +// should log |line| followed by a newline, synchronizing with any concurrent +// access to the log. +// +// The format is described in +// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. +OPENSSL_EXPORT void SSL_CTX_set_keylog_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)); + +// SSL_CTX_get_keylog_callback returns the callback configured by +// |SSL_CTX_set_keylog_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))( + const SSL *ssl, const char *line); + +// SSL_CTX_set_current_time_cb configures a callback to retrieve the current +// time, which should be set in |*out_clock|. This can be used for testing +// purposes; for example, a callback can be configured that returns a time +// set explicitly by the test. The |ssl| pointer passed to |cb| is always null. +OPENSSL_EXPORT void SSL_CTX_set_current_time_cb( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, struct timeval *out_clock)); + +// SSL_set_shed_handshake_config allows some of the configuration of |ssl| to be +// freed after its handshake completes. Once configuration has been shed, APIs +// that query it may fail. "Configuration" in this context means anything that +// was set by the caller, as distinct from information derived from the +// handshake. For example, |SSL_get_ciphers| queries how the |SSL| was +// configured by the caller, and fails after configuration has been shed, +// whereas |SSL_get_cipher| queries the result of the handshake, and is +// unaffected by configuration shedding. +// +// If configuration shedding is enabled, it is an error to call |SSL_clear|. +// +// Note that configuration shedding as a client additionally depends on +// renegotiation being disabled (see |SSL_set_renegotiate_mode|). If +// renegotiation is possible, the configuration will be retained. If +// configuration shedding is enabled and renegotiation later disabled after the +// handshake, |SSL_set_renegotiate_mode| will shed configuration then. This may +// be useful for clients which support renegotiation with some ALPN protocols, +// such as HTTP/1.1, and not others, such as HTTP/2. +OPENSSL_EXPORT void SSL_set_shed_handshake_config(SSL *ssl, int enable); + +enum ssl_renegotiate_mode_t BORINGSSL_ENUM_INT { + ssl_renegotiate_never = 0, + ssl_renegotiate_once, + ssl_renegotiate_freely, + ssl_renegotiate_ignore, + ssl_renegotiate_explicit, +}; + +// SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to +// renegotiation attempts by a server. If |ssl| is a server, peer-initiated +// renegotiations are *always* rejected and this function does nothing. +// +// The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set +// at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to +// allow one renegotiation, |ssl_renegotiate_freely| to allow all +// renegotiations or |ssl_renegotiate_ignore| to ignore HelloRequest messages. +// Note that ignoring HelloRequest messages may cause the connection to stall +// if the server waits for the renegotiation to complete. +// +// If set to |ssl_renegotiate_explicit|, |SSL_read| and |SSL_peek| calls which +// encounter a HelloRequest will pause with |SSL_ERROR_WANT_RENEGOTIATE|. +// |SSL_write| will continue to work while paused. The caller may call +// |SSL_renegotiate| to begin the renegotiation at a later point. This mode may +// be used if callers wish to eagerly call |SSL_peek| without triggering a +// renegotiation. +// +// If configuration shedding is enabled (see |SSL_set_shed_handshake_config|), +// configuration is released if, at any point after the handshake, renegotiation +// is disabled. It is not possible to switch from disabling renegotiation to +// enabling it on a given connection. Callers that condition renegotiation on, +// e.g., ALPN must enable renegotiation before the handshake and conditionally +// disable it afterwards. +// +// There is no support in BoringSSL for initiating renegotiations as a client +// or server. +OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl, + enum ssl_renegotiate_mode_t mode); + +// SSL_renegotiate starts a deferred renegotiation on |ssl| if it was configured +// with |ssl_renegotiate_explicit| and has a pending HelloRequest. It returns +// one on success and zero on error. +// +// This function does not do perform any I/O. On success, a subsequent +// |SSL_do_handshake| call will run the handshake. |SSL_write| and +// |SSL_read| will also complete the handshake before sending or receiving +// application data. +OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl); + +// SSL_renegotiate_pending returns one if |ssl| is in the middle of a +// renegotiation. +OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl); + +// SSL_total_renegotiations returns the total number of renegotiation handshakes +// performed by |ssl|. This includes the pending renegotiation, if any. +OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl); + +// SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer +// certificate chain. +#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100) + +// SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ctx|. +OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx); + +// SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, + size_t max_cert_list); + +// SSL_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ssl|. +OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl); + +// SSL_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list); + +// SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records +// sent by |ctx|. Beyond this length, handshake messages and application data +// will be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, + size_t max_send_fragment); + +// SSL_set_max_send_fragment sets the maximum length, in bytes, of records sent +// by |ssl|. Beyond this length, handshake messages and application data will +// be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl, + size_t max_send_fragment); + +// ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain +// callbacks that are called very early on during the server handshake. At this +// point, much of the SSL* hasn't been filled out and only the ClientHello can +// be depended on. +struct ssl_early_callback_ctx { + SSL *ssl; + const uint8_t *client_hello; + size_t client_hello_len; + uint16_t version; + const uint8_t *random; + size_t random_len; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *compression_methods; + size_t compression_methods_len; + const uint8_t *extensions; + size_t extensions_len; +} /* SSL_CLIENT_HELLO */; + +// ssl_select_cert_result_t enumerates the possible results from selecting a +// certificate with |select_certificate_cb|. +enum ssl_select_cert_result_t BORINGSSL_ENUM_INT { + // ssl_select_cert_success indicates that the certificate selection was + // successful. + ssl_select_cert_success = 1, + // ssl_select_cert_retry indicates that the operation could not be + // immediately completed and must be reattempted at a later point. + ssl_select_cert_retry = 0, + // ssl_select_cert_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_select_cert_error = -1, +}; + +// SSL_early_callback_ctx_extension_get searches the extensions in +// |client_hello| for an extension of the given type. If not found, it returns +// zero. Otherwise it sets |out_data| to point to the extension contents (not +// including the type and length bytes), sets |out_len| to the length of the +// extension contents and returns one. +OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get( + const SSL_CLIENT_HELLO *client_hello, uint16_t extension_type, + const uint8_t **out_data, size_t *out_len); + +// SSL_CTX_set_select_certificate_cb sets a callback that is called before most +// ClientHello processing and before the decision whether to resume a session +// is made. The callback may inspect the ClientHello and configure the +// connection. See |ssl_select_cert_result_t| for details of the return values. +// +// In the case that a retry is indicated, |SSL_get_error| will return +// |SSL_ERROR_PENDING_CERTIFICATE| and the caller should arrange for the +// high-level operation on |ssl| to be retried at a later time, which will +// result in another call to |cb|. +// +// |SSL_get_servername| may be used during this callback. +// +// Note: The |SSL_CLIENT_HELLO| is only valid for the duration of the callback +// and is not valid while the handshake is paused. +OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_CTX_set_dos_protection_cb sets a callback that is called once the +// resumption decision for a ClientHello has been made. It can return one to +// allow the handshake to continue or zero to cause the handshake to abort. +OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( + SSL_CTX *ctx, int (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_CTX_set_reverify_on_resume configures whether the certificate +// verification callback will be used to reverify stored certificates +// when resuming a session. This only works with |SSL_CTX_set_custom_verify|. +// For now, this is incompatible with |SSL_VERIFY_NONE| mode, and is only +// respected on clients. +OPENSSL_EXPORT void SSL_CTX_set_reverify_on_resume(SSL_CTX *ctx, int enabled); + +// SSL_set_enforce_rsa_key_usage configures whether the keyUsage extension of +// RSA leaf certificates will be checked for consistency with the TLS +// usage. This parameter may be set late; it will not be read until after the +// certificate verification callback. +OPENSSL_EXPORT void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled); + +// SSL_ST_* are possible values for |SSL_state|, the bitmasks that make them up, +// and some historical values for compatibility. Only |SSL_ST_INIT| and +// |SSL_ST_OK| are ever returned. +#define SSL_ST_CONNECT 0x1000 +#define SSL_ST_ACCEPT 0x2000 +#define SSL_ST_MASK 0x0FFF +#define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT) +#define SSL_ST_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT) +#define SSL_ST_BEFORE (0x05 | SSL_ST_INIT) + +// TLS_ST_* are aliases for |SSL_ST_*| for OpenSSL 1.1.0 compatibility. +#define TLS_ST_OK SSL_ST_OK +#define TLS_ST_BEFORE SSL_ST_BEFORE + +// SSL_CB_* are possible values for the |type| parameter in the info +// callback and the bitmasks that make them up. +#define SSL_CB_LOOP 0x01 +#define SSL_CB_EXIT 0x02 +#define SSL_CB_READ 0x04 +#define SSL_CB_WRITE 0x08 +#define SSL_CB_ALERT 0x4000 +#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ) +#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE) +#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP) +#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT) +#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP) +#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT) +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 + +// SSL_CTX_set_info_callback configures a callback to be run when various +// events occur during a connection's lifetime. The |type| argument determines +// the type of event and the meaning of the |value| argument. Callbacks must +// ignore unexpected |type| values. +// +// |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal. +// The |value| argument is a 16-bit value where the alert level (either +// |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits +// and the alert type (one of |SSL_AD_*|) is in the least-significant eight. +// +// |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument +// is constructed as with |SSL_CB_READ_ALERT|. +// +// |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value| +// argument is always one. +// +// |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully. +// The |value| argument is always one. If a handshake False Starts, this event +// may be used to determine when the Finished message is received. +// +// The following event types expose implementation details of the handshake +// state machine. Consuming them is deprecated. +// +// |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when +// a server (respectively, client) handshake progresses. The |value| argument +// is always one. +// +// |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when +// a server (respectively, client) handshake completes, fails, or is paused. +// The |value| argument is one if the handshake succeeded and <= 0 +// otherwise. +OPENSSL_EXPORT void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_CTX_get_info_callback returns the callback set by +// |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, + int type, + int value); + +// SSL_set_info_callback configures a callback to be run at various events +// during a connection's lifetime. See |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void SSL_set_info_callback( + SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. +OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, + int type, + int value); + +// SSL_state_string_long returns the current state of the handshake state +// machine as a string. This may be useful for debugging and logging. +OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl); + +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + +// SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and +// |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received, +// respectively. +OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl); + +// SSL_get_peer_signature_algorithm returns the signature algorithm used by the +// peer. If not applicable, it returns zero. +OPENSSL_EXPORT uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl); + +// SSL_get_client_random writes up to |max_out| bytes of the most recent +// handshake's client_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the client_random. +OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_server_random writes up to |max_out| bytes of the most recent +// handshake's server_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the server_random. +OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_pending_cipher returns the cipher suite for the current handshake or +// NULL if one has not been negotiated yet or there is no pending handshake. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl); + +// SSL_set_retain_only_sha256_of_client_certs, on a server, sets whether only +// the SHA-256 hash of peer's certificate should be saved in memory and in the +// session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See |SSL_SESSION_has_peer_sha256| and +// |SSL_SESSION_get0_peer_sha256| to query the hash. +OPENSSL_EXPORT void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, + int enable); + +// SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether +// only the SHA-256 hash of peer's certificate should be saved in memory and in +// the session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See |SSL_SESSION_has_peer_sha256| and +// |SSL_SESSION_get0_peer_sha256| to query the hash. +OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, + int enable); + +// SSL_CTX_set_grease_enabled configures whether sockets on |ctx| should enable +// GREASE. See RFC 8701. +OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled); + +// SSL_CTX_set_permute_extensions configures whether sockets on |ctx| should +// permute extensions. For now, this is only implemented for the ClientHello. +OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled); + +// SSL_set_permute_extensions configures whether sockets on |ssl| should +// permute extensions. For now, this is only implemented for the ClientHello. +OPENSSL_EXPORT void SSL_set_permute_extensions(SSL *ssl, int enabled); + +// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record with |ssl|. +OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl); + +// SSL_CTX_set_false_start_allowed_without_alpn configures whether connections +// on |ctx| may use False Start (if |SSL_MODE_ENABLE_FALSE_START| is enabled) +// without negotiating ALPN. +OPENSSL_EXPORT void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, + int allowed); + +// SSL_used_hello_retry_request returns one if the TLS 1.3 HelloRetryRequest +// message has been either sent by the server or received by the client. It +// returns zero otherwise. +OPENSSL_EXPORT int SSL_used_hello_retry_request(const SSL *ssl); + +// SSL_set_jdk11_workaround configures whether to workaround various bugs in +// JDK 11's TLS 1.3 implementation by disabling TLS 1.3 for such clients. +// +// https://bugs.openjdk.java.net/browse/JDK-8211806 +// https://bugs.openjdk.java.net/browse/JDK-8212885 +// https://bugs.openjdk.java.net/browse/JDK-8213202 +OPENSSL_EXPORT void SSL_set_jdk11_workaround(SSL *ssl, int enable); + + +// Deprecated functions. + +// SSL_library_init calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int SSL_library_init(void); + +// SSL_CIPHER_description writes a description of |cipher| into |buf| and +// returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be +// freed with |OPENSSL_free|, or NULL on error. +// +// The description includes a trailing newline and has the form: +// AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 +// +// Consider |SSL_CIPHER_standard_name| or |SSL_CIPHER_get_name| instead. +OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, + char *buf, int len); + +// SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". +OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the +// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is +// responsible for calling |OPENSSL_free| on the result. +// +// Use |SSL_CIPHER_standard_name| instead. +OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); + +typedef void COMP_METHOD; +typedef struct ssl_comp_st SSL_COMP; + +// SSL_COMP_get_compression_methods returns NULL. +OPENSSL_EXPORT STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); + +// SSL_COMP_add_compression_method returns one. +OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +// SSL_COMP_get_name returns NULL. +OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp); + +// SSL_COMP_get0_name returns the |name| member of |comp|. +OPENSSL_EXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp); + +// SSL_COMP_get_id returns the |id| member of |comp|. +OPENSSL_EXPORT int SSL_COMP_get_id(const SSL_COMP *comp); + +// SSL_COMP_free_compression_methods does nothing. +OPENSSL_EXPORT void SSL_COMP_free_compression_methods(void); + +// SSLv23_method calls |TLS_method|. +OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); + +// These version-specific methods behave exactly like |TLS_method| and +// |DTLS_method| except they also call |SSL_CTX_set_min_proto_version| and +// |SSL_CTX_set_max_proto_version| to lock connections to that protocol +// version. +OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); + +// These client- and server-specific methods call their corresponding generic +// methods. +OPENSSL_EXPORT const SSL_METHOD *TLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); + +// SSL_clear resets |ssl| to allow another connection and returns one on success +// or zero on failure. It returns most configuration state but releases memory +// associated with the current connection. +// +// Free |ssl| and create a new one instead. +OPENSSL_EXPORT int SSL_clear(SSL *ssl); + +// SSL_CTX_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback( + SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, + int keylength)); + +// SSL_CTX_sess_connect returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_cb_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_misses returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); + +// SSL_CTX_sess_timeouts returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); + +// SSL_CTX_sess_cache_full returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); + +// SSL_cutthrough_complete calls |SSL_in_false_start|. +OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl); + +// SSL_num_renegotiations calls |SSL_total_renegotiations|. +OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl); + +// SSL_CTX_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); + +// SSL_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl); + +// SSL_CTX_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa); + +// SSL_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); + +// SSL_CTX_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx); + +// SSL_CTX_set_read_ahead returns one. +OPENSSL_EXPORT int SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +// SSL_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl); + +// SSL_set_read_ahead returns one. +OPENSSL_EXPORT int SSL_set_read_ahead(SSL *ssl, int yes); + +// SSL_set_state does nothing. +OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state); + +// SSL_get_shared_ciphers writes an empty string to |buf| and returns a +// pointer to |buf|, or NULL if |len| is less than or equal to zero. +OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +// SSL_get_shared_sigalgs returns zero. +OPENSSL_EXPORT int SSL_get_shared_sigalgs(SSL *ssl, int idx, int *psign, + int *phash, int *psignandhash, + uint8_t *rsig, uint8_t *rhash); + +// SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. +#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START + +// i2d_SSL_SESSION serializes |in|, as described in |i2d_SAMPLE|. +// +// Use |SSL_SESSION_to_bytes| instead. +OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp); + +// d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed +// to by |*pp|, as described in |d2i_SAMPLE|. +// +// Use |SSL_SESSION_from_bytes| instead. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, + long length); + +// i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It +// returns the number of bytes written on success and <= 0 on error. +OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session); + +// d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a +// newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also +// frees |*out| and sets |*out| to the new |SSL_SESSION|. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out); + +// ERR_load_SSL_strings does nothing. +OPENSSL_EXPORT void ERR_load_SSL_strings(void); + +// SSL_load_error_strings does nothing. +OPENSSL_EXPORT void SSL_load_error_strings(void); + +// SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns +// zero on success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_CTX_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on +// success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +// SSL_get_current_compression returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl); + +// SSL_get_current_expansion returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl); + +// SSL_get_server_tmp_key returns zero. +OPENSSL_EXPORT int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key); + +// SSL_CTX_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); + +// SSL_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh); + +// SSL_CTX_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback( + SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)); + +// SSL_CTX_set1_sigalgs takes |num_values| ints and interprets them as pairs +// where the first is the nid of a hash function and the second is an +// |EVP_PKEY_*| value. It configures the signature algorithm preferences for +// |ctx| based on them and returns one on success or zero on error. +// +// This API is compatible with OpenSSL. However, BoringSSL-specific code should +// prefer |SSL_CTX_set_signing_algorithm_prefs| because it's clearer and it's +// more convenient to codesearch for specific algorithm values. +OPENSSL_EXPORT int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, + size_t num_values); + +// SSL_set1_sigalgs takes |num_values| ints and interprets them as pairs where +// the first is the nid of a hash function and the second is an |EVP_PKEY_*| +// value. It configures the signature algorithm preferences for |ssl| based on +// them and returns one on success or zero on error. +// +// This API is compatible with OpenSSL. However, BoringSSL-specific code should +// prefer |SSL_CTX_set_signing_algorithm_prefs| because it's clearer and it's +// more convenient to codesearch for specific algorithm values. +OPENSSL_EXPORT int SSL_set1_sigalgs(SSL *ssl, const int *values, + size_t num_values); + +// SSL_CTX_set1_sigalgs_list takes a textual specification of a set of signature +// algorithms and configures them on |ctx|. It returns one on success and zero +// on error. See +// https://www.openssl.org/docs/man1.1.0/man3/SSL_CTX_set1_sigalgs_list.html for +// a description of the text format. Also note that TLS 1.3 names (e.g. +// "rsa_pkcs1_md5_sha1") can also be used (as in OpenSSL, although OpenSSL +// doesn't document that). +// +// This API is compatible with OpenSSL. However, BoringSSL-specific code should +// prefer |SSL_CTX_set_signing_algorithm_prefs| because it's clearer and it's +// more convenient to codesearch for specific algorithm values. +OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str); + +// SSL_set1_sigalgs_list takes a textual specification of a set of signature +// algorithms and configures them on |ssl|. It returns one on success and zero +// on error. See +// https://www.openssl.org/docs/man1.1.0/man3/SSL_CTX_set1_sigalgs_list.html for +// a description of the text format. Also note that TLS 1.3 names (e.g. +// "rsa_pkcs1_md5_sha1") can also be used (as in OpenSSL, although OpenSSL +// doesn't document that). +// +// This API is compatible with OpenSSL. However, BoringSSL-specific code should +// prefer |SSL_CTX_set_signing_algorithm_prefs| because it's clearer and it's +// more convenient to codesearch for specific algorithm values. +OPENSSL_EXPORT int SSL_set1_sigalgs_list(SSL *ssl, const char *str); + +#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)(arg))) +#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0)) +#define SSL_SESSION_set_app_data(s, a) \ + (SSL_SESSION_set_ex_data(s, 0, (char *)(a))) +#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0)) +#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0)) +#define SSL_CTX_set_app_data(ctx, arg) \ + (SSL_CTX_set_ex_data(ctx, 0, (char *)(arg))) + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_bits(ssl, out_alg_bits) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits) +#define SSL_get_cipher_version(ssl) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_name(ssl) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_time(session) SSL_SESSION_get_time(session) +#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time)) +#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session) +#define SSL_set_timeout(session, timeout) \ + SSL_SESSION_set_timeout((session), (timeout)) + +struct ssl_comp_st { + int id; + const char *name; + char *method; +}; + +DEFINE_STACK_OF(SSL_COMP) + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define SSL_MODE_AUTO_RETRY 0 +#define SSL_MODE_RELEASE_BUFFERS 0 +#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 +#define SSL_MODE_SEND_SERVERHELLO_TIME 0 +#define SSL_OP_ALL 0 +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 +#define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_LEGACY_SERVER_CONNECT 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NO_COMPRESSION 0 +#define SSL_OP_NO_RENEGOTIATION 0 // ssl_renegotiate_never is the default +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 +#define SSL_OP_NO_SSLv2 0 +#define SSL_OP_NO_SSLv3 0 +#define SSL_OP_PKCS1_CHECK_1 0 +#define SSL_OP_PKCS1_CHECK_2 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_SINGLE_ECDH_USE 0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 +#define SSL_OP_TLS_ROLLBACK_BUG 0 +#define SSL_VERIFY_CLIENT_ONCE 0 + +// SSL_cache_hit calls |SSL_session_reused|. +OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl); + +// SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. +OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl); + +// SSL_get_version returns a string describing the TLS version used by |ssl|. +// For example, "TLSv1.2" or "DTLSv1". +OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl); + +// SSL_get_cipher_list returns the name of the |n|th cipher in the output of +// |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| instead. +OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n); + +// SSL_CTX_set_client_cert_cb sets a callback which is called on the client if +// the server requests a client certificate and none is configured. On success, +// the callback should return one and set |*out_x509| to |*out_pkey| to a leaf +// certificate and private key, respectively, passing ownership. It should +// return zero to send no certificate and -1 to fail or pause the handshake. If +// the handshake is paused, |SSL_get_error| will return +// |SSL_ERROR_WANT_X509_LOOKUP|. +// +// The callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate request. +// +// Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with +// this function is confusing. This callback may not be registered concurrently +// with |SSL_CTX_set_cert_cb| or |SSL_set_cert_cb|. +OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey)); + +#define SSL_NOTHING SSL_ERROR_NONE +#define SSL_WRITING SSL_ERROR_WANT_WRITE +#define SSL_READING SSL_ERROR_WANT_READ + +// SSL_want returns one of the above values to determine what the most recent +// operation on |ssl| was blocked on. Use |SSL_get_error| instead. +OPENSSL_EXPORT int SSL_want(const SSL *ssl); + +#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING) +#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING) + + // SSL_get_finished writes up to |count| bytes of the Finished message sent by + // |ssl| to |buf|. It returns the total untruncated length or zero if none has + // been sent yet. At TLS 1.3 and later, it returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count); + + // SSL_get_peer_finished writes up to |count| bytes of the Finished message + // received from |ssl|'s peer to |buf|. It returns the total untruncated length + // or zero if none has been received yet. At TLS 1.3 and later, it returns + // zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf, + size_t count); + +// SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_type_string(int value); + +// SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_desc_string(int value); + +// SSL_state_string returns "!!!!!!". Use |SSL_state_string_long| for a more +// intelligible string. +OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl); + +// SSL_TXT_* expand to strings. +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHE "kDHE" +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kECDHE "kECDHE" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" +#define SSL_TXT_EDH "EDH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" +#define SSL_TXT_EECDH "EECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CHACHA20 "CHACHA20" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#define SSL_TXT_SSLV3 "SSLv3" +#define SSL_TXT_TLSV1 "TLSv1" +#define SSL_TXT_TLSV1_1 "TLSv1.1" +#define SSL_TXT_TLSV1_2 "TLSv1.2" +#define SSL_TXT_TLSV1_3 "TLSv1.3" +#define SSL_TXT_ALL "ALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +// SSL_state returns |SSL_ST_INIT| if a handshake is in progress and |SSL_ST_OK| +// otherwise. +// +// Use |SSL_is_init| instead. +OPENSSL_EXPORT int SSL_state(const SSL *ssl); + +#define SSL_get_state(ssl) SSL_state(ssl) + +// SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see +// |SSL_get_shutdown|) were |mode|. This may be used to skip sending or +// receiving close_notify in |SSL_shutdown| by causing the implementation to +// believe the events already happened. +// +// It is an error to use |SSL_set_shutdown| to unset a bit that has already been +// set. Doing so will trigger an |assert| in debug builds and otherwise be +// ignored. +// +// Use |SSL_CTX_set_quiet_shutdown| instead. +OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); + +// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list +// containing |ec_key|'s curve. +OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); + +// SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing +// |ec_key|'s curve. +OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); + +// SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls +// |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success +// or zero on error. This function is only available from the libdecrepit +// library. +OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *dir); + +// SSL_CTX_enable_tls_channel_id calls |SSL_CTX_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx); + +// SSL_enable_tls_channel_id calls |SSL_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl); + +// BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note +// that this has quite different behaviour from the version in OpenSSL (notably +// that it doesn't try to auto renegotiate). +// +// IMPORTANT: if you are not curl, don't use this. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void); + +// BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must +// have been created using |BIO_f_ssl|. If |take_owership| is true, |bio| will +// call |SSL_free| on |ssl| when closed. It returns one on success or something +// other than one on error. +OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership); + +// SSL_CTX_set_ecdh_auto returns one. +#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 + +// SSL_set_ecdh_auto returns one. +#define SSL_set_ecdh_auto(ssl, onoff) 1 + +// SSL_get_session returns a non-owning pointer to |ssl|'s session. For +// historical reasons, which session it returns depends on |ssl|'s state. +// +// Prior to the start of the initial handshake, it returns the session the +// caller set with |SSL_set_session|. After the initial handshake has finished +// and if no additional handshakes are in progress, it returns the currently +// active session. Its behavior is undefined while a handshake is in progress. +// +// If trying to add new sessions to an external session cache, use +// |SSL_CTX_sess_set_new_cb| instead. In particular, using the callback is +// required as of TLS 1.3. For compatibility, this function will return an +// unresumable session which may be cached, but will never be resumed. +// +// If querying properties of the connection, use APIs on the |SSL| object. +OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl); + +// SSL_get0_session is an alias for |SSL_get_session|. +#define SSL_get0_session SSL_get_session + +// SSL_get1_session acts like |SSL_get_session| but returns a new reference to +// the session. +OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl); + +#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_SSL_DEFAULT 0 + +// OPENSSL_init_ssl calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + +// The following constants are legacy aliases for RSA-PSS with rsaEncryption +// keys. Use the new names instead. +#define SSL_SIGN_RSA_PSS_SHA256 SSL_SIGN_RSA_PSS_RSAE_SHA256 +#define SSL_SIGN_RSA_PSS_SHA384 SSL_SIGN_RSA_PSS_RSAE_SHA384 +#define SSL_SIGN_RSA_PSS_SHA512 SSL_SIGN_RSA_PSS_RSAE_SHA512 + +// SSL_set_tlsext_status_type configures a client to request OCSP stapling if +// |type| is |TLSEXT_STATUSTYPE_ocsp| and disables it otherwise. It returns one +// on success and zero if handshake configuration has already been shed. +// +// Use |SSL_enable_ocsp_stapling| instead. +OPENSSL_EXPORT int SSL_set_tlsext_status_type(SSL *ssl, int type); + +// SSL_get_tlsext_status_type returns |TLSEXT_STATUSTYPE_ocsp| if the client +// requested OCSP stapling and |TLSEXT_STATUSTYPE_nothing| otherwise. On the +// client, this reflects whether OCSP stapling was enabled via, e.g., +// |SSL_set_tlsext_status_type|. On the server, this is determined during the +// handshake. It may be queried in callbacks set by |SSL_CTX_set_cert_cb|. The +// result is undefined after the handshake completes. +OPENSSL_EXPORT int SSL_get_tlsext_status_type(const SSL *ssl); + +// SSL_set_tlsext_status_ocsp_resp sets the OCSP response. It returns one on +// success and zero on error. On success, |ssl| takes ownership of |resp|, which +// must have been allocated by |OPENSSL_malloc|. +// +// Use |SSL_set_ocsp_response| instead. +OPENSSL_EXPORT int SSL_set_tlsext_status_ocsp_resp(SSL *ssl, uint8_t *resp, + size_t resp_len); + +// SSL_get_tlsext_status_ocsp_resp sets |*out| to point to the OCSP response +// from the server. It returns the length of the response. If there was no +// response, it sets |*out| to NULL and returns zero. +// +// Use |SSL_get0_ocsp_response| instead. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT size_t SSL_get_tlsext_status_ocsp_resp(const SSL *ssl, + const uint8_t **out); + +// SSL_CTX_set_tlsext_status_cb configures the legacy OpenSSL OCSP callback and +// returns one. Though the type signature is the same, this callback has +// different behavior for client and server connections: +// +// For clients, the callback is called after certificate verification. It should +// return one for success, zero for a bad OCSP response, and a negative number +// for internal error. Instead, handle this as part of certificate verification. +// (Historically, OpenSSL verified certificates just before parsing stapled OCSP +// responses, but BoringSSL fixes this ordering. All server credentials are +// available during verification.) +// +// Do not use this callback as a server. It is provided for compatibility +// purposes only. For servers, it is called to configure server credentials. It +// should return |SSL_TLSEXT_ERR_OK| on success, |SSL_TLSEXT_ERR_NOACK| to +// ignore OCSP requests, or |SSL_TLSEXT_ERR_ALERT_FATAL| on error. It is usually +// used to fetch OCSP responses on demand, which is not ideal. Instead, treat +// OCSP responses like other server credentials, such as certificates or SCT +// lists. Configure, store, and refresh them eagerly. This avoids downtime if +// the CA's OCSP responder is briefly offline. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx, + int (*callback)(SSL *ssl, + void *arg)); + +// SSL_CTX_set_tlsext_status_arg sets additional data for +// |SSL_CTX_set_tlsext_status_cb|'s callback and returns one. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg); + +// The following symbols are compatibility aliases for reason codes used when +// receiving an alert from the peer. Use the other names instead, which fit the +// naming convention. +// +// TODO(davidben): Fix references to |SSL_R_TLSV1_CERTIFICATE_REQUIRED| and +// remove the compatibility value. The others come from OpenSSL. +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION \ + SSL_R_TLSV1_ALERT_UNSUPPORTED_EXTENSION +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE \ + SSL_R_TLSV1_ALERT_CERTIFICATE_UNOBTAINABLE +#define SSL_R_TLSV1_UNRECOGNIZED_NAME SSL_R_TLSV1_ALERT_UNRECOGNIZED_NAME +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE \ + SSL_R_TLSV1_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE \ + SSL_R_TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE +#define SSL_R_TLSV1_CERTIFICATE_REQUIRED SSL_R_TLSV1_ALERT_CERTIFICATE_REQUIRED + +// SSL_CIPHER_get_value calls |SSL_CIPHER_get_protocol_id|. +// +// TODO(davidben): |SSL_CIPHER_get_value| was our name for this function, but +// upstream added it as |SSL_CIPHER_get_protocol_id|. Switch callers to the new +// name and remove this one. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); + + +// Nodejs compatibility section (hidden). +// +// These defines exist for node.js, with the hope that we can eliminate the +// need for them over time. + +#define SSLerr(function, reason) \ + ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__) + + +// Preprocessor compatibility section (hidden). +// +// Historically, a number of APIs were implemented in OpenSSL as macros and +// constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this +// section defines a number of legacy macros. +// +// Although using either the CTRL values or their wrapper macros in #ifdefs is +// still supported, the CTRL values may not be passed to |SSL_ctrl| and +// |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. +// +// See PORTING.md in the BoringSSL source tree for a table of corresponding +// functions. +// https://boringssl.googlesource.com/boringssl/+/master/PORTING.md#Replacements-for-values + +#define DTLS_CTRL_GET_TIMEOUT doesnt_exist +#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist +#define SSL_CTRL_CHAIN doesnt_exist +#define SSL_CTRL_CHAIN_CERT doesnt_exist +#define SSL_CTRL_CHANNEL_ID doesnt_exist +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_CLEAR_MODE doesnt_exist +#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist +#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist +#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist +#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_GET_READ_AHEAD doesnt_exist +#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist +#define SSL_CTRL_GET_SERVER_TMP_KEY doesnt_exist +#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_MODE doesnt_exist +#define SSL_CTRL_NEED_TMP_RSA doesnt_exist +#define SSL_CTRL_OPTIONS doesnt_exist +#define SSL_CTRL_SESS_NUMBER doesnt_exist +#define SSL_CTRL_SET_CURVES doesnt_exist +#define SSL_CTRL_SET_CURVES_LIST doesnt_exist +#define SSL_CTRL_SET_ECDH_AUTO doesnt_exist +#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist +#define SSL_CTRL_SET_MTU doesnt_exist +#define SSL_CTRL_SET_READ_AHEAD doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist +#define SSL_CTRL_SET_TMP_DH doesnt_exist +#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_RSA doesnt_exist +#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist + +// |BORINGSSL_PREFIX| already makes each of these symbols into macros, so there +// is no need to define conflicting macros. +#if !defined(BORINGSSL_PREFIX) + +#define DTLSv1_get_timeout DTLSv1_get_timeout +#define DTLSv1_handle_timeout DTLSv1_handle_timeout +#define SSL_CTX_add0_chain_cert SSL_CTX_add0_chain_cert +#define SSL_CTX_add1_chain_cert SSL_CTX_add1_chain_cert +#define SSL_CTX_add_extra_chain_cert SSL_CTX_add_extra_chain_cert +#define SSL_CTX_clear_extra_chain_certs SSL_CTX_clear_extra_chain_certs +#define SSL_CTX_clear_chain_certs SSL_CTX_clear_chain_certs +#define SSL_CTX_clear_mode SSL_CTX_clear_mode +#define SSL_CTX_clear_options SSL_CTX_clear_options +#define SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs +#define SSL_CTX_get_extra_chain_certs SSL_CTX_get_extra_chain_certs +#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list +#define SSL_CTX_get_mode SSL_CTX_get_mode +#define SSL_CTX_get_options SSL_CTX_get_options +#define SSL_CTX_get_read_ahead SSL_CTX_get_read_ahead +#define SSL_CTX_get_session_cache_mode SSL_CTX_get_session_cache_mode +#define SSL_CTX_get_tlsext_ticket_keys SSL_CTX_get_tlsext_ticket_keys +#define SSL_CTX_need_tmp_RSA SSL_CTX_need_tmp_RSA +#define SSL_CTX_sess_get_cache_size SSL_CTX_sess_get_cache_size +#define SSL_CTX_sess_number SSL_CTX_sess_number +#define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size +#define SSL_CTX_set0_chain SSL_CTX_set0_chain +#define SSL_CTX_set1_chain SSL_CTX_set1_chain +#define SSL_CTX_set1_curves SSL_CTX_set1_curves +#define SSL_CTX_set_max_cert_list SSL_CTX_set_max_cert_list +#define SSL_CTX_set_max_send_fragment SSL_CTX_set_max_send_fragment +#define SSL_CTX_set_mode SSL_CTX_set_mode +#define SSL_CTX_set_msg_callback_arg SSL_CTX_set_msg_callback_arg +#define SSL_CTX_set_options SSL_CTX_set_options +#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead +#define SSL_CTX_set_session_cache_mode SSL_CTX_set_session_cache_mode +#define SSL_CTX_set_tlsext_servername_arg SSL_CTX_set_tlsext_servername_arg +#define SSL_CTX_set_tlsext_servername_callback \ + SSL_CTX_set_tlsext_servername_callback +#define SSL_CTX_set_tlsext_ticket_key_cb SSL_CTX_set_tlsext_ticket_key_cb +#define SSL_CTX_set_tlsext_ticket_keys SSL_CTX_set_tlsext_ticket_keys +#define SSL_CTX_set_tmp_dh SSL_CTX_set_tmp_dh +#define SSL_CTX_set_tmp_ecdh SSL_CTX_set_tmp_ecdh +#define SSL_CTX_set_tmp_rsa SSL_CTX_set_tmp_rsa +#define SSL_add0_chain_cert SSL_add0_chain_cert +#define SSL_add1_chain_cert SSL_add1_chain_cert +#define SSL_clear_chain_certs SSL_clear_chain_certs +#define SSL_clear_mode SSL_clear_mode +#define SSL_clear_options SSL_clear_options +#define SSL_get0_certificate_types SSL_get0_certificate_types +#define SSL_get0_chain_certs SSL_get0_chain_certs +#define SSL_get_max_cert_list SSL_get_max_cert_list +#define SSL_get_mode SSL_get_mode +#define SSL_get_options SSL_get_options +#define SSL_get_secure_renegotiation_support \ + SSL_get_secure_renegotiation_support +#define SSL_need_tmp_RSA SSL_need_tmp_RSA +#define SSL_num_renegotiations SSL_num_renegotiations +#define SSL_session_reused SSL_session_reused +#define SSL_set0_chain SSL_set0_chain +#define SSL_set1_chain SSL_set1_chain +#define SSL_set1_curves SSL_set1_curves +#define SSL_set_max_cert_list SSL_set_max_cert_list +#define SSL_set_max_send_fragment SSL_set_max_send_fragment +#define SSL_set_mode SSL_set_mode +#define SSL_set_msg_callback_arg SSL_set_msg_callback_arg +#define SSL_set_mtu SSL_set_mtu +#define SSL_set_options SSL_set_options +#define SSL_set_tlsext_host_name SSL_set_tlsext_host_name +#define SSL_set_tmp_dh SSL_set_tmp_dh +#define SSL_set_tmp_ecdh SSL_set_tmp_ecdh +#define SSL_set_tmp_rsa SSL_set_tmp_rsa +#define SSL_total_renegotiations SSL_total_renegotiations + +#endif // !defined(BORINGSSL_PREFIX) + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(SSL, SSL_free) +BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) +BORINGSSL_MAKE_UP_REF(SSL_CTX, SSL_CTX_up_ref) +BORINGSSL_MAKE_DELETER(SSL_ECH_KEYS, SSL_ECH_KEYS_free) +BORINGSSL_MAKE_UP_REF(SSL_ECH_KEYS, SSL_ECH_KEYS_up_ref) +BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) +BORINGSSL_MAKE_UP_REF(SSL_SESSION, SSL_SESSION_up_ref) + +enum class OpenRecordResult { + kOK, + kDiscard, + kIncompleteRecord, + kAlertCloseNotify, + kError, +}; + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// OpenRecord decrypts the first complete SSL record from |in| in-place, sets +// |out| to the decrypted application data, and |out_record_len| to the length +// of the encrypted record. Returns: +// - kOK if an application-data record was successfully decrypted and verified. +// - kDiscard if a record was sucessfully processed, but should be discarded. +// - kIncompleteRecord if |in| did not contain a complete record. +// - kAlertCloseNotify if a record was successfully processed but is a +// close_notify alert. +// - kError if an error occurred or the record is invalid. |*out_alert| will be +// set to an alert to emit, or zero if no alert should be emitted. +OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, + uint8_t *out_alert, + Span in); + +OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len); + +// SealRecordSuffixLen returns the length of the suffix written by |SealRecord|. +// +// |plaintext_len| must be equal to the size of the plaintext passed to +// |SealRecord|. +// +// |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned +// suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. +OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len); + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// SealRecord encrypts the cleartext of |in| and scatters the resulting TLS +// application data record between |out_prefix|, |out|, and |out_suffix|. It +// returns true on success or false if an error occurred. +// +// The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of +// |out| must equal the length of |in|, which must not exceed +// |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal +// |SealRecordSuffixLen|. +// +// If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting. +// |SealRecordPrefixLen| accounts for the required overhead if that is the case. +// +// |out| may equal |in| to encrypt in-place but may not otherwise alias. +// |out_prefix| and |out_suffix| may not alias anything. +OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span out_prefix, + Span out, Span out_suffix, + Span in); + + +// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** +// +// Split handshakes. +// +// Split handshakes allows the handshake part of a TLS connection to be +// performed in a different process (or on a different machine) than the data +// exchange. This only applies to servers. +// +// In the first part of a split handshake, an |SSL| (where the |SSL_CTX| has +// been configured with |SSL_CTX_set_handoff_mode|) is used normally. Once the +// ClientHello message has been received, the handshake will stop and +// |SSL_get_error| will indicate |SSL_ERROR_HANDOFF|. At this point (and only +// at this point), |SSL_serialize_handoff| can be called to write the “handoff” +// state of the connection. +// +// Elsewhere, a fresh |SSL| can be used with |SSL_apply_handoff| to continue +// the connection. The connection from the client is fed into this |SSL|, and +// the handshake resumed. When the handshake stops again and |SSL_get_error| +// indicates |SSL_ERROR_HANDBACK|, |SSL_serialize_handback| should be called to +// serialize the state of the handshake again. +// +// Back at the first location, a fresh |SSL| can be used with +// |SSL_apply_handback|. Then the client's connection can be processed mostly +// as normal. +// +// Lastly, when a connection is in the handoff state, whether or not +// |SSL_serialize_handoff| is called, |SSL_decline_handoff| will move it back +// into a normal state where the connection can proceed without impact. +// +// WARNING: Currently only works with TLS 1.0–1.2. +// WARNING: The serialisation formats are not yet stable: version skew may be +// fatal. +// WARNING: The handback data contains sensitive key material and must be +// protected. +// WARNING: Some calls on the final |SSL| will not work. Just as an example, +// calls like |SSL_get0_session_id_context| and |SSL_get_privatekey| won't +// work because the certificate used for handshaking isn't available. +// WARNING: |SSL_apply_handoff| may trigger “msg” callback calls. + +OPENSSL_EXPORT void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on); +OPENSSL_EXPORT void SSL_set_handoff_mode(SSL *SSL, bool on); +OPENSSL_EXPORT bool SSL_serialize_handoff(const SSL *ssl, CBB *out, + SSL_CLIENT_HELLO *out_hello); +OPENSSL_EXPORT bool SSL_decline_handoff(SSL *ssl); +OPENSSL_EXPORT bool SSL_apply_handoff(SSL *ssl, Span handoff); +OPENSSL_EXPORT bool SSL_serialize_handback(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span handback); + +// SSL_get_traffic_secrets sets |*out_read_traffic_secret| and +// |*out_write_traffic_secret| to reference the TLS 1.3 traffic secrets for +// |ssl|. This function is only valid on TLS 1.3 connections that have +// completed the handshake. It returns true on success and false on error. +OPENSSL_EXPORT bool SSL_get_traffic_secrets( + const SSL *ssl, Span *out_read_traffic_secret, + Span *out_write_traffic_secret); + + +BSSL_NAMESPACE_END + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif + +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101 +#define SSL_R_BAD_ALERT 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 104 +#define SSL_R_BAD_DH_P_LENGTH 105 +#define SSL_R_BAD_DIGEST_LENGTH 106 +#define SSL_R_BAD_ECC_CERT 107 +#define SSL_R_BAD_ECPOINT 108 +#define SSL_R_BAD_HANDSHAKE_RECORD 109 +#define SSL_R_BAD_HELLO_REQUEST 110 +#define SSL_R_BAD_LENGTH 111 +#define SSL_R_BAD_PACKET_LENGTH 112 +#define SSL_R_BAD_RSA_ENCRYPT 113 +#define SSL_R_BAD_SIGNATURE 114 +#define SSL_R_BAD_SRTP_MKI_VALUE 115 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116 +#define SSL_R_BAD_SSL_FILETYPE 117 +#define SSL_R_BAD_WRITE_RETRY 118 +#define SSL_R_BIO_NOT_SET 119 +#define SSL_R_BN_LIB 120 +#define SSL_R_BUFFER_TOO_SMALL 121 +#define SSL_R_CA_DN_LENGTH_MISMATCH 122 +#define SSL_R_CA_DN_TOO_LONG 123 +#define SSL_R_CCS_RECEIVED_EARLY 124 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 125 +#define SSL_R_CERT_CB_ERROR 126 +#define SSL_R_CERT_LENGTH_MISMATCH 127 +#define SSL_R_CHANNEL_ID_NOT_P256 128 +#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130 +#define SSL_R_CLIENTHELLO_PARSE_FAILED 131 +#define SSL_R_CLIENTHELLO_TLSEXT 132 +#define SSL_R_CONNECTION_REJECTED 133 +#define SSL_R_CONNECTION_TYPE_NOT_SET 134 +#define SSL_R_CUSTOM_EXTENSION_ERROR 135 +#define SSL_R_DATA_LENGTH_TOO_LONG 136 +#define SSL_R_DECODE_ERROR 137 +#define SSL_R_DECRYPTION_FAILED 138 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140 +#define SSL_R_DH_P_TOO_LONG 141 +#define SSL_R_DIGEST_CHECK_FAILED 142 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 143 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144 +#define SSL_R_EMS_STATE_INCONSISTENT 145 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 +#define SSL_R_ERROR_ADDING_EXTENSION 147 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148 +#define SSL_R_ERROR_PARSING_EXTENSION 149 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 151 +#define SSL_R_FRAGMENT_MISMATCH 152 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153 +#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_INAPPROPRIATE_FALLBACK 157 +#define SSL_R_INVALID_COMMAND 158 +#define SSL_R_INVALID_MESSAGE 159 +#define SSL_R_INVALID_SSL_SESSION 160 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161 +#define SSL_R_LENGTH_MISMATCH 162 +#define SSL_R_MISSING_EXTENSION 164 +#define SSL_R_MISSING_RSA_CERTIFICATE 165 +#define SSL_R_MISSING_TMP_DH_KEY 166 +#define SSL_R_MISSING_TMP_ECDH_KEY 167 +#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168 +#define SSL_R_MTU_TOO_SMALL 169 +#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170 +#define SSL_R_NESTED_GROUP 171 +#define SSL_R_NO_CERTIFICATES_RETURNED 172 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 173 +#define SSL_R_NO_CERTIFICATE_SET 174 +#define SSL_R_NO_CIPHERS_AVAILABLE 175 +#define SSL_R_NO_CIPHERS_PASSED 176 +#define SSL_R_NO_CIPHER_MATCH 177 +#define SSL_R_NO_COMPRESSION_SPECIFIED 178 +#define SSL_R_NO_METHOD_SPECIFIED 179 +#define SSL_R_NO_P256_SUPPORT 180 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181 +#define SSL_R_NO_RENEGOTIATION 182 +#define SSL_R_NO_REQUIRED_DIGEST 183 +#define SSL_R_NO_SHARED_CIPHER 184 +#define SSL_R_NULL_SSL_CTX 185 +#define SSL_R_NULL_SSL_METHOD_PASSED 186 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187 +#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188 +#define SSL_R_OUTPUT_ALIASES_INPUT 189 +#define SSL_R_PARSE_TLSEXT 190 +#define SSL_R_PATH_TOO_LONG 191 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 194 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 195 +#define SSL_R_PSK_NO_CLIENT_CB 196 +#define SSL_R_PSK_NO_SERVER_CB 197 +#define SSL_R_READ_TIMEOUT_EXPIRED 198 +#define SSL_R_RECORD_LENGTH_MISMATCH 199 +#define SSL_R_RECORD_TOO_LARGE 200 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 201 +#define SSL_R_RENEGOTIATION_MISMATCH 202 +#define SSL_R_REQUIRED_CIPHER_MISSING 203 +#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204 +#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206 +#define SSL_R_SERVERHELLO_TLSEXT 207 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209 +#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214 +#define SSL_R_SSL_HANDSHAKE_FAILURE 215 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219 +#define SSL_R_TOO_MANY_WARNING_ALERTS 220 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221 +#define SSL_R_UNEXPECTED_EXTENSION 222 +#define SSL_R_UNEXPECTED_MESSAGE 223 +#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224 +#define SSL_R_UNEXPECTED_RECORD 225 +#define SSL_R_UNINITIALIZED 226 +#define SSL_R_UNKNOWN_ALERT_TYPE 227 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 229 +#define SSL_R_UNKNOWN_CIPHER_TYPE 230 +#define SSL_R_UNKNOWN_DIGEST 231 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232 +#define SSL_R_UNKNOWN_PROTOCOL 233 +#define SSL_R_UNKNOWN_SSL_VERSION 234 +#define SSL_R_UNKNOWN_STATE 235 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236 +#define SSL_R_UNSUPPORTED_CIPHER 237 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239 +#define SSL_R_UNSUPPORTED_PROTOCOL 240 +#define SSL_R_WRONG_CERTIFICATE_TYPE 241 +#define SSL_R_WRONG_CIPHER_RETURNED 242 +#define SSL_R_WRONG_CURVE 243 +#define SSL_R_WRONG_MESSAGE_TYPE 244 +#define SSL_R_WRONG_SIGNATURE_TYPE 245 +#define SSL_R_WRONG_SSL_VERSION 246 +#define SSL_R_WRONG_VERSION_NUMBER 247 +#define SSL_R_X509_LIB 248 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249 +#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250 +#define SSL_R_INVALID_OUTER_RECORD_TYPE 251 +#define SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY 252 +#define SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS 253 +#define SSL_R_DOWNGRADE_DETECTED 254 +#define SSL_R_EXCESS_HANDSHAKE_DATA 255 +#define SSL_R_INVALID_COMPRESSION_LIST 256 +#define SSL_R_DUPLICATE_EXTENSION 257 +#define SSL_R_MISSING_KEY_SHARE 258 +#define SSL_R_INVALID_ALPN_PROTOCOL 259 +#define SSL_R_TOO_MANY_KEY_UPDATES 260 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 261 +#define SSL_R_NO_CIPHERS_SPECIFIED 262 +#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263 +#define SSL_R_DUPLICATE_KEY_SHARE 264 +#define SSL_R_NO_GROUPS_SPECIFIED 265 +#define SSL_R_NO_SHARED_GROUP 266 +#define SSL_R_PRE_SHARED_KEY_MUST_BE_LAST 267 +#define SSL_R_OLD_SESSION_PRF_HASH_MISMATCH 268 +#define SSL_R_INVALID_SCT_LIST 269 +#define SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA 270 +#define SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH 271 +#define SSL_R_CANNOT_PARSE_LEAF_CERT 272 +#define SSL_R_SERVER_CERT_CHANGED 273 +#define SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH 274 +#define SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD 275 +#define SSL_R_TICKET_ENCRYPTION_FAILED 276 +#define SSL_R_ALPN_MISMATCH_ON_EARLY_DATA 277 +#define SSL_R_WRONG_VERSION_ON_EARLY_DATA 278 +#define SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA 279 +#define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280 +#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281 +#define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282 +#define SSL_R_EARLY_DATA_NOT_IN_USE 283 +#define SSL_R_HANDSHAKE_NOT_COMPLETE 284 +#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285 +#define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286 +#define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287 +#define SSL_R_SECOND_SERVERHELLO_VERSION_MISMATCH 288 +#define SSL_R_OCSP_CB_ERROR 289 +#define SSL_R_SSL_SESSION_ID_TOO_LONG 290 +#define SSL_R_APPLICATION_DATA_ON_SHUTDOWN 291 +#define SSL_R_CERT_DECOMPRESSION_FAILED 292 +#define SSL_R_UNCOMPRESSED_CERT_TOO_LARGE 293 +#define SSL_R_UNKNOWN_CERT_COMPRESSION_ALG 294 +#define SSL_R_INVALID_SIGNATURE_ALGORITHM 295 +#define SSL_R_DUPLICATE_SIGNATURE_ALGORITHM 296 +#define SSL_R_TLS13_DOWNGRADE 297 +#define SSL_R_QUIC_INTERNAL_ERROR 298 +#define SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED 299 +#define SSL_R_TOO_MUCH_READ_EARLY_DATA 300 +#define SSL_R_INVALID_DELEGATED_CREDENTIAL 301 +#define SSL_R_KEY_USAGE_BIT_INCORRECT 302 +#define SSL_R_INCONSISTENT_CLIENT_HELLO 303 +#define SSL_R_CIPHER_MISMATCH_ON_EARLY_DATA 304 +#define SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED 305 +#define SSL_R_UNEXPECTED_COMPATIBILITY_MODE 306 +#define SSL_R_NO_APPLICATION_PROTOCOL 307 +#define SSL_R_NEGOTIATED_ALPS_WITHOUT_ALPN 308 +#define SSL_R_ALPS_MISMATCH_ON_EARLY_DATA 309 +#define SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH 310 +#define SSL_R_ECH_SERVER_CONFIG_UNSUPPORTED_EXTENSION 311 +#define SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG 312 +#define SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS 313 +#define SSL_R_INVALID_CLIENT_HELLO_INNER 314 +#define SSL_R_INVALID_ALPN_PROTOCOL_LIST 315 +#define SSL_R_COULD_NOT_PARSE_HINTS 316 +#define SSL_R_INVALID_ECH_PUBLIC_NAME 317 +#define SSL_R_INVALID_ECH_CONFIG_LIST 318 +#define SSL_R_ECH_REJECTED 319 +#define SSL_R_INVALID_OUTER_EXTENSION 320 +#define SSL_R_INCONSISTENT_ECH_NEGOTIATION 321 +#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_ALERT_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLSV1_ALERT_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_ALERT_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY 1115 +#define SSL_R_TLSV1_ALERT_CERTIFICATE_REQUIRED 1116 +#define SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL 1120 +#define SSL_R_TLSV1_ALERT_ECH_REQUIRED 1121 + +#endif // OPENSSL_HEADER_SSL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h new file mode 100644 index 00000000..4d1017dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h @@ -0,0 +1,334 @@ +/* ssl/ssl3.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef OPENSSL_HEADER_SSL3_H +#define OPENSSL_HEADER_SSL3_H + +#include "CNIOBoringSSL_aead.h" +#include "CNIOBoringSSL_type_check.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +// These are kept to support clients that negotiates higher protocol versions +// using SSLv2 client hello records. +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_VERSION 0x0002 + +// Signalling cipher suite value from RFC 5746. +#define SSL3_CK_SCSV 0x030000FF +// Fallback signalling cipher suite value from RFC 7507. +#define SSL3_CK_FALLBACK_SCSV 0x03005600 + +#define SSL3_CK_RSA_NULL_MD5 0x03000001 +#define SSL3_CK_RSA_NULL_SHA 0x03000002 +#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +#define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +#define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +#define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +#define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +#define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +#define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +#define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +#define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +#define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +#define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +#define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +#define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +#define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +#define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +#define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +#define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +#define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +#define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +#define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +#define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +#define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +#define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +#define SSL3_SSL_SESSION_ID_LENGTH 32 +#define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +#define SSL3_MASTER_SECRET_SIZE 48 +#define SSL3_RANDOM_SIZE 32 +#define SSL3_SESSION_ID_SIZE 32 +#define SSL3_RT_HEADER_LENGTH 5 + +#define SSL3_HM_HEADER_LENGTH 4 + +#ifndef SSL3_ALIGN_PAYLOAD +// Some will argue that this increases memory footprint, but it's not actually +// true. Point is that malloc has to return at least 64-bit aligned pointers, +// meaning that allocating 5 bytes wastes 3 bytes in either case. Suggested +// pre-gaping simply moves these wasted bytes from the end of allocated region +// to its front, but makes data payload aligned, which improves performance. +#define SSL3_ALIGN_PAYLOAD 8 +#else +#if (SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) != 0 +#error "insane SSL3_ALIGN_PAYLOAD" +#undef SSL3_ALIGN_PAYLOAD +#endif +#endif + +// This is the maximum MAC (digest) size used by the SSL library. Currently +// maximum of 20 is used by SHA1, but we reserve for future extension for +// 512-bit hashes. + +#define SSL3_RT_MAX_MD_SIZE 64 + +// Maximum block size used in all ciphersuites. Currently 16 for AES. + +#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +// Maximum plaintext length: defined by SSL/TLS standards +#define SSL3_RT_MAX_PLAIN_LENGTH 16384 +// Maximum compression overhead: defined by SSL/TLS standards +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +// The standards give a maximum encryption overhead of 1024 bytes. In practice +// the value is lower than this. The overhead is the maximum number of padding +// bytes (256) plus the mac size. +// +// TODO(davidben): This derivation doesn't take AEADs into account, or TLS 1.1 +// explicit nonces. It happens to work because |SSL3_RT_MAX_MD_SIZE| is larger +// than necessary and no true AEAD has variable overhead in TLS 1.2. +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +// SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD is the maximum overhead in encrypting a +// record. This does not include the record header. Some ciphers use explicit +// nonces, so it includes both the AEAD overhead as well as the nonce. +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (EVP_AEAD_MAX_OVERHEAD + EVP_AEAD_MAX_NONCE_LENGTH) + +OPENSSL_STATIC_ASSERT(SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD, + "max overheads are inconsistent"); + +// SSL3_RT_MAX_COMPRESSED_LENGTH is an alias for +// |SSL3_RT_MAX_PLAIN_LENGTH|. Compression is gone, so don't include the +// compression overhead. +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH + +#define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD + SSL3_RT_MAX_COMPRESSED_LENGTH) +#define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH + SSL3_RT_HEADER_LENGTH) + +#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +#define SSL3_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 + +// Pseudo content type for SSL/TLS header info +#define SSL3_RT_HEADER 0x100 +#define SSL3_RT_CLIENT_HELLO_INNER 0x101 + +#define SSL3_AL_WARNING 1 +#define SSL3_AL_FATAL 2 + +#define SSL3_AD_CLOSE_NOTIFY 0 +#define SSL3_AD_UNEXPECTED_MESSAGE 10 // fatal +#define SSL3_AD_BAD_RECORD_MAC 20 // fatal +#define SSL3_AD_DECOMPRESSION_FAILURE 30 // fatal +#define SSL3_AD_HANDSHAKE_FAILURE 40 // fatal +#define SSL3_AD_NO_CERTIFICATE 41 +#define SSL3_AD_BAD_CERTIFICATE 42 +#define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +#define SSL3_AD_CERTIFICATE_REVOKED 44 +#define SSL3_AD_CERTIFICATE_EXPIRED 45 +#define SSL3_AD_CERTIFICATE_UNKNOWN 46 +#define SSL3_AD_ILLEGAL_PARAMETER 47 // fatal +#define SSL3_AD_INAPPROPRIATE_FALLBACK 86 // fatal + +#define SSL3_CT_RSA_SIGN 1 + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEW_SESSION_TICKET 4 +#define SSL3_MT_END_OF_EARLY_DATA 5 +#define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_HELLO_DONE 14 +#define SSL3_MT_CERTIFICATE_VERIFY 15 +#define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +#define SSL3_MT_FINISHED 20 +#define SSL3_MT_CERTIFICATE_STATUS 22 +#define SSL3_MT_SUPPLEMENTAL_DATA 23 +#define SSL3_MT_KEY_UPDATE 24 +#define SSL3_MT_COMPRESSED_CERTIFICATE 25 +#define SSL3_MT_NEXT_PROTO 67 +#define SSL3_MT_CHANNEL_ID 203 +#define SSL3_MT_MESSAGE_HASH 254 +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +// The following are legacy aliases for consumers which use +// |SSL_CTX_set_msg_callback|. +#define SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO_DONE +#define SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEW_SESSION_TICKET + + +#define SSL3_MT_CCS 1 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_SSL3_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h new file mode 100644 index 00000000..fd793696 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h @@ -0,0 +1,539 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_STACK_H +#define OPENSSL_HEADER_STACK_H + +#include "CNIOBoringSSL_base.h" + +#include "CNIOBoringSSL_type_check.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// A stack, in OpenSSL, is an array of pointers. They are the most commonly +// used collection object. +// +// This file defines macros for type safe use of the stack functions. A stack +// of a specific type of object has type |STACK_OF(type)|. This can be defined +// (once) with |DEFINE_STACK_OF(type)| and declared where needed with +// |DECLARE_STACK_OF(type)|. For example: +// +// typedef struct foo_st { +// int bar; +// } FOO; +// +// DEFINE_STACK_OF(FOO) +// +// Although note that the stack will contain /pointers/ to |FOO|. +// +// A macro will be defined for each of the sk_* functions below. For +// STACK_OF(FOO), the macros would be sk_FOO_new, sk_FOO_pop etc. + + +// stack_free_func is a function that frees an element in a stack. Note its +// actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be +// passed a type-specific wrapper to call it correctly. +typedef void (*stack_free_func)(void *ptr); + +// stack_copy_func is a function that copies an element in a stack. Note its +// actual type is T *(*)(T *) for some T. Low-level |sk_*| functions will be +// passed a type-specific wrapper to call it correctly. +typedef void *(*stack_copy_func)(void *ptr); + +// stack_cmp_func is a comparison function that returns a value < 0, 0 or > 0 +// if |*a| is less than, equal to or greater than |*b|, respectively. Note the +// extra indirection - the function is given a pointer to a pointer to the +// element. This differs from the usual qsort/bsearch comparison function. +// +// Note its actual type is int (*)(const T **, const T **). Low-level |sk_*| +// functions will be passed a type-specific wrapper to call it correctly. +typedef int (*stack_cmp_func)(const void **a, const void **b); + +// stack_st contains an array of pointers. It is not designed to be used +// directly, rather the wrapper macros should be used. +typedef struct stack_st { + // num contains the number of valid pointers in |data|. + size_t num; + void **data; + // sorted is non-zero if the values pointed to by |data| are in ascending + // order, based on |comp|. + int sorted; + // num_alloc contains the number of pointers allocated in the buffer pointed + // to by |data|, which may be larger than |num|. + size_t num_alloc; + // comp is an optional comparison function. + stack_cmp_func comp; +} _STACK; + + +#define STACK_OF(type) struct stack_st_##type + +#define DECLARE_STACK_OF(type) STACK_OF(type); + +// These are the raw stack functions, you shouldn't be using them. Rather you +// should be using the type stack macros implemented above. + +// sk_new creates a new, empty stack with the given comparison function, which +// may be zero. It returns the new stack or NULL on allocation failure. +OPENSSL_EXPORT _STACK *sk_new(stack_cmp_func comp); + +// sk_new_null creates a new, empty stack. It returns the new stack or NULL on +// allocation failure. +OPENSSL_EXPORT _STACK *sk_new_null(void); + +// sk_num returns the number of elements in |s|. +OPENSSL_EXPORT size_t sk_num(const _STACK *sk); + +// sk_zero resets |sk| to the empty state but does nothing to free the +// individual elements themselves. +OPENSSL_EXPORT void sk_zero(_STACK *sk); + +// sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of +// range. +OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i); + +// sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out +// of range, it returns NULL. +OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p); + +// sk_free frees the given stack and array of pointers, but does nothing to +// free the individual elements. Also see |sk_pop_free_ex|. +OPENSSL_EXPORT void sk_free(_STACK *sk); + +// sk_pop_free_ex calls |free_func| on each element in the stack and then frees +// the stack itself. Note this corresponds to |sk_FOO_pop_free|. It is named +// |sk_pop_free_ex| as a workaround for existing code calling an older version +// of |sk_pop_free|. +OPENSSL_EXPORT void sk_pop_free_ex(_STACK *sk, + void (*call_free_func)(stack_free_func, + void *), + stack_free_func free_func); + +// sk_insert inserts |p| into the stack at index |where|, moving existing +// elements if needed. It returns the length of the new stack, or zero on +// error. +OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); + +// sk_delete removes the pointer at index |where|, moving other elements down +// if needed. It returns the removed pointer, or NULL if |where| is out of +// range. +OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); + +// sk_delete_ptr removes, at most, one instance of |p| from the stack based on +// pointer equality. If an instance of |p| is found then |p| is returned, +// otherwise it returns NULL. +OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, const void *p); + +// sk_find returns the first value in the stack equal to |p|. If a comparison +// function has been set on the stack, equality is defined by it, otherwise +// pointer equality is used. If the stack is sorted, then a binary search is +// used, otherwise a linear search is performed. If a matching element is found, +// its index is written to +// |*out_index| (if |out_index| is not NULL) and one is returned. Otherwise zero +// is returned. +// +// Note this differs from OpenSSL. The type signature is slightly different, and +// OpenSSL's sk_find will implicitly sort |sk| if it has a comparison function +// defined. +OPENSSL_EXPORT int sk_find(const _STACK *sk, size_t *out_index, const void *p, + int (*call_cmp_func)(stack_cmp_func, const void **, + const void **)); + +// sk_shift removes and returns the first element in the stack, or returns NULL +// if the stack is empty. +OPENSSL_EXPORT void *sk_shift(_STACK *sk); + +// sk_push appends |p| to the stack and returns the length of the new stack, or +// 0 on allocation failure. +OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p); + +// sk_pop returns and removes the last element on the stack, or NULL if the +// stack is empty. +OPENSSL_EXPORT void *sk_pop(_STACK *sk); + +// sk_dup performs a shallow copy of a stack and returns the new stack, or NULL +// on error. +OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk); + +// sk_sort sorts the elements of |sk| into ascending order based on the +// comparison function. The stack maintains a |sorted| flag and sorting an +// already sorted stack is a no-op. +OPENSSL_EXPORT void sk_sort(_STACK *sk); + +// sk_is_sorted returns one if |sk| is known to be sorted and zero +// otherwise. +OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk); + +// sk_set_cmp_func sets the comparison function to be used by |sk| and returns +// the previous one. +OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp); + +// sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in +// |sk| by using |copy_func|. If an error occurs, |free_func| is used to free +// any copies already made and NULL is returned. +OPENSSL_EXPORT _STACK *sk_deep_copy( + const _STACK *sk, void *(*call_copy_func)(stack_copy_func, void *), + stack_copy_func copy_func, void (*call_free_func)(stack_free_func, void *), + stack_free_func free_func); + + +// Deprecated functions. + +// sk_pop_free behaves like |sk_pop_free_ex| but performs an invalid function +// pointer cast. It exists because some existing callers called |sk_pop_free| +// directly. +// +// TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. +OPENSSL_EXPORT void sk_pop_free(_STACK *sk, stack_free_func free_func); + + +// Defining stack types. +// +// This set of macros is used to emit the typed functions that act on a +// |STACK_OF(T)|. + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { +BSSL_NAMESPACE_BEGIN +namespace internal { +template +struct StackTraits {}; +} +BSSL_NAMESPACE_END +} + +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ + extern "C++" { \ + BSSL_NAMESPACE_BEGIN \ + namespace internal { \ + template <> \ + struct StackTraits { \ + static constexpr bool kIsStack = true; \ + using Type = type; \ + static constexpr bool kIsConst = is_const; \ + }; \ + } \ + BSSL_NAMESPACE_END \ + } + +#else +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) +#endif + +#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ + DECLARE_STACK_OF(name) \ + \ + typedef void (*stack_##name##_free_func)(ptrtype); \ + typedef ptrtype (*stack_##name##_copy_func)(ptrtype); \ + typedef int (*stack_##name##_cmp_func)(constptrtype *a, constptrtype *b); \ + \ + OPENSSL_INLINE void sk_##name##_call_free_func(stack_free_func free_func, \ + void *ptr) { \ + ((stack_##name##_free_func)free_func)((ptrtype)ptr); \ + } \ + \ + OPENSSL_INLINE void *sk_##name##_call_copy_func(stack_copy_func copy_func, \ + void *ptr) { \ + return (void *)((stack_##name##_copy_func)copy_func)((ptrtype)ptr); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_call_cmp_func( \ + stack_cmp_func cmp_func, const void **a, const void **b) { \ + constptrtype a_ptr = (constptrtype)*a; \ + constptrtype b_ptr = (constptrtype)*b; \ + return ((stack_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) * \ + sk_##name##_new(stack_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)sk_new((stack_cmp_func)comp); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ + return (STACK_OF(name) *)sk_new_null(); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ + return sk_num((const _STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ + sk_zero((_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ + size_t i) { \ + return (ptrtype)sk_value((const _STACK *)sk, i); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ + ptrtype p) { \ + return (ptrtype)sk_set((_STACK *)sk, i, (void *)p); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) * sk) { \ + sk_free((_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_pop_free( \ + STACK_OF(name) * sk, stack_##name##_free_func free_func) { \ + sk_pop_free_ex((_STACK *)sk, sk_##name##_call_free_func, \ + (stack_free_func)free_func); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ + size_t where) { \ + return sk_insert((_STACK *)sk, (void *)p, where); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ + size_t where) { \ + return (ptrtype)sk_delete((_STACK *)sk, where); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ + constptrtype p) { \ + return (ptrtype)sk_delete_ptr((_STACK *)sk, (const void *)p); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ + size_t * out_index, constptrtype p) { \ + return sk_find((const _STACK *)sk, out_index, (const void *)p, \ + sk_##name##_call_cmp_func); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ + return (ptrtype)sk_shift((_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ + return sk_push((_STACK *)sk, (void *)p); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ + return (ptrtype)sk_pop((_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) * sk_##name##_dup(const STACK_OF(name) *sk) { \ + return (STACK_OF(name) *)sk_dup((const _STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ + sk_sort((_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ + return sk_is_sorted((const _STACK *)sk); \ + } \ + \ + OPENSSL_INLINE stack_##name##_cmp_func sk_##name##_set_cmp_func( \ + STACK_OF(name) *sk, stack_##name##_cmp_func comp) { \ + return (stack_##name##_cmp_func)sk_set_cmp_func((_STACK *)sk, \ + (stack_cmp_func)comp); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) * \ + sk_##name##_deep_copy(const STACK_OF(name) *sk, \ + ptrtype(*copy_func)(ptrtype), \ + void (*free_func)(ptrtype)) { \ + return (STACK_OF(name) *)sk_deep_copy( \ + (const _STACK *)sk, sk_##name##_call_copy_func, \ + (stack_copy_func)copy_func, sk_##name##_call_free_func, \ + (stack_free_func)free_func); \ + } + +// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements +// are |type| *. +#define DEFINE_NAMED_STACK_OF(name, type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(name, type, false) + +// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are +// |type| *. +#define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type) + +// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are const |type| *. +#define DEFINE_CONST_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) + +// DEFINE_SPECIAL_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are |type|, where |type| must be a typedef for a pointer. +#define DEFINE_SPECIAL_STACK_OF(type) \ + OPENSSL_STATIC_ASSERT(sizeof(type) == sizeof(void *), \ + #type " is not a pointer"); \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, type, const type) + + +typedef char *OPENSSL_STRING; + +DEFINE_STACK_OF(void) +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING) + + +#if defined(__cplusplus) +} // extern C +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +#include + +BSSL_NAMESPACE_BEGIN + +namespace internal { + +// Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. +template +struct DeleterImpl::kIsConst>> { + static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); } +}; + +// Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the +// corresponding type's deleter. +template +struct DeleterImpl::kIsConst>> { + static void Free(Stack *sk) { + // sk_FOO_pop_free is defined by macros and bound by name, so we cannot + // access it from C++ here. + using Type = typename StackTraits::Type; + sk_pop_free_ex(reinterpret_cast<_STACK *>(sk), + [](stack_free_func /* unused */, void *ptr) { + DeleterImpl::Free(reinterpret_cast(ptr)); + }, + nullptr); + } +}; + +template +class StackIteratorImpl { + public: + using Type = typename StackTraits::Type; + // Iterators must be default-constructable. + StackIteratorImpl() : sk_(nullptr), idx_(0) {} + StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} + + bool operator==(StackIteratorImpl other) const { + return sk_ == other.sk_ && idx_ == other.idx_; + } + bool operator!=(StackIteratorImpl other) const { + return !(*this == other); + } + + Type *operator*() const { + return reinterpret_cast( + sk_value(reinterpret_cast(sk_), idx_)); + } + + StackIteratorImpl &operator++(/* prefix */) { + idx_++; + return *this; + } + + StackIteratorImpl operator++(int /* postfix */) { + StackIteratorImpl copy(*this); + ++(*this); + return copy; + } + + private: + const Stack *sk_; + size_t idx_; +}; + +template +using StackIterator = + std::enable_if_t::kIsStack, StackIteratorImpl>; + +} // namespace internal + +// PushToStack pushes |elem| to |sk|. It returns true on success and false on +// allocation failure. +template +inline std::enable_if_t::kIsConst, bool> +PushToStack(Stack *sk, + UniquePtr::Type> elem) { + if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) { + return false; + } + // sk_push takes ownership on success. + elem.release(); + return true; +} + +BSSL_NAMESPACE_END + +// Define begin() and end() for stack types so C++ range for loops work. +template +inline bssl::internal::StackIterator begin(const Stack *sk) { + return bssl::internal::StackIterator(sk, 0); +} + +template +inline bssl::internal::StackIterator end(const Stack *sk) { + return bssl::internal::StackIterator( + sk, sk_num(reinterpret_cast(sk))); +} + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_STACK_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_thread.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_thread.h new file mode 100644 index 00000000..898c1196 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_thread.h @@ -0,0 +1,190 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_THREAD_H +#define OPENSSL_HEADER_THREAD_H + +#include + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_THREADS) +typedef struct crypto_mutex_st { + char padding; // Empty structs have different sizes in C and C++. +} CRYPTO_MUTEX; +#elif defined(OPENSSL_WINDOWS) +// CRYPTO_MUTEX can appear in public header files so we really don't want to +// pull in windows.h. It's statically asserted that this structure is large +// enough to contain a Windows SRWLOCK by thread_win.c. +typedef union crypto_mutex_st { + void *handle; +} CRYPTO_MUTEX; +#elif !defined(__GLIBC__) +typedef pthread_rwlock_t CRYPTO_MUTEX; +#else +// On glibc, |pthread_rwlock_t| is hidden under feature flags, and we can't +// ensure that we'll be able to get it from a public header. It's statically +// asserted that this structure is large enough to contain a |pthread_rwlock_t| +// by thread_pthread.c. +typedef union crypto_mutex_st { + double alignment; + uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8]; +} CRYPTO_MUTEX; +#endif + +// CRYPTO_refcount_t is the type of a reference count. +// +// Since some platforms use C11 atomics to access this, it should have the +// _Atomic qualifier. However, this header is included by C++ programs as well +// as C code that might not set -std=c11. So, in practice, it's not possible to +// do that. Instead we statically assert that the size and native alignment of +// a plain uint32_t and an _Atomic uint32_t are equal in refcount_c11.c. +typedef uint32_t CRYPTO_refcount_t; + + +// Deprecated functions. +// +// Historically, OpenSSL required callers to provide locking callbacks. +// BoringSSL is thread-safe by default, but some old code calls these functions +// and so no-op implementations are provided. + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +// CRYPTO_num_locks returns one. (This is non-zero that callers who allocate +// sizeof(lock) times this value don't get zero and then fail because malloc(0) +// returned NULL.) +OPENSSL_EXPORT int CRYPTO_num_locks(void); + +// CRYPTO_set_locking_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_locking_callback( + void (*func)(int mode, int lock_num, const char *file, int line)); + +// CRYPTO_set_add_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)( + int *num, int amount, int lock_num, const char *file, int line)); + +// CRYPTO_get_locking_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, + int line); + +// CRYPTO_get_lock_name returns a fixed, dummy string. +OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num); + +// CRYPTO_THREADID_set_callback returns one. +OPENSSL_EXPORT int CRYPTO_THREADID_set_callback( + void (*threadid_func)(CRYPTO_THREADID *threadid)); + +// CRYPTO_THREADID_set_numeric does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, + unsigned long val); + +// CRYPTO_THREADID_set_pointer does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); + +// CRYPTO_THREADID_current does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id); + +// CRYPTO_set_id_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_id_callback(unsigned long (*func)(void)); + +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +// CRYPTO_set_dynlock_create_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_create_callback( + struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, + int line)); + +// CRYPTO_set_dynlock_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); + +// CRYPTO_set_dynlock_destroy_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_destroy_callback( + void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, + const char *file, int line)); + +// CRYPTO_get_dynlock_create_callback returns NULL. +OPENSSL_EXPORT struct CRYPTO_dynlock_value *( + *CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); + +// CRYPTO_get_dynlock_lock_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_lock_callback(void))( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); + +// CRYPTO_get_dynlock_destroy_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_tls1.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_tls1.h new file mode 100644 index 00000000..8eda2b64 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_tls1.h @@ -0,0 +1,647 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef OPENSSL_HEADER_TLS1_H +#define OPENSSL_HEADER_TLS1_H + +#include "CNIOBoringSSL_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define TLS1_AD_END_OF_EARLY_DATA 1 +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 +#define TLS1_AD_ACCESS_DENIED 49 +#define TLS1_AD_DECODE_ERROR 50 +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 +#define TLS1_AD_PROTOCOL_VERSION 70 +#define TLS1_AD_INSUFFICIENT_SECURITY 71 +#define TLS1_AD_INTERNAL_ERROR 80 +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +#define TLS1_AD_MISSING_EXTENSION 109 +#define TLS1_AD_UNSUPPORTED_EXTENSION 110 +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +#define TLS1_AD_UNRECOGNIZED_NAME 112 +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 +#define TLS1_AD_CERTIFICATE_REQUIRED 116 +#define TLS1_AD_NO_APPLICATION_PROTOCOL 120 +#define TLS1_AD_ECH_REQUIRED 121 // draft-ietf-tls-esni-13 + +// ExtensionType values from RFC 6066 +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_status_request 5 + +// ExtensionType values from RFC 4492 +#define TLSEXT_TYPE_ec_point_formats 11 + +// ExtensionType values from RFC 5246 +#define TLSEXT_TYPE_signature_algorithms 13 + +// ExtensionType value from RFC 5764 +#define TLSEXT_TYPE_srtp 14 + +// ExtensionType value from RFC 7301 +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +// ExtensionType value from RFC 7685 +#define TLSEXT_TYPE_padding 21 + +// ExtensionType value from RFC 7627 +#define TLSEXT_TYPE_extended_master_secret 23 + +// ExtensionType value from draft-ietf-quic-tls. Drafts 00 through 32 use +// 0xffa5 which is part of the Private Use section of the registry, and it +// collides with TLS-LTS and, based on scans, something else too (though this +// hasn't been a problem in practice since it's QUIC-only). Drafts 33 onward +// use the value 57 which was officially registered with IANA. +#define TLSEXT_TYPE_quic_transport_parameters_legacy 0xffa5 + +// ExtensionType value from RFC 9000 +#define TLSEXT_TYPE_quic_transport_parameters 57 + +// TLSEXT_TYPE_quic_transport_parameters_standard is an alias for +// |TLSEXT_TYPE_quic_transport_parameters|. Use +// |TLSEXT_TYPE_quic_transport_parameters| instead. +#define TLSEXT_TYPE_quic_transport_parameters_standard \ + TLSEXT_TYPE_quic_transport_parameters + +// ExtensionType value from RFC 8879 +#define TLSEXT_TYPE_cert_compression 27 + +// ExtensionType value from RFC 4507 +#define TLSEXT_TYPE_session_ticket 35 + +// ExtensionType values from RFC 8446 +#define TLSEXT_TYPE_supported_groups 10 +#define TLSEXT_TYPE_pre_shared_key 41 +#define TLSEXT_TYPE_early_data 42 +#define TLSEXT_TYPE_supported_versions 43 +#define TLSEXT_TYPE_cookie 44 +#define TLSEXT_TYPE_psk_key_exchange_modes 45 +#define TLSEXT_TYPE_certificate_authorities 47 +#define TLSEXT_TYPE_signature_algorithms_cert 50 +#define TLSEXT_TYPE_key_share 51 + +// ExtensionType value from RFC 5746 +#define TLSEXT_TYPE_renegotiate 0xff01 + +// ExtensionType value from draft-ietf-tls-subcerts. +#define TLSEXT_TYPE_delegated_credential 0x22 + +// ExtensionType value from draft-vvv-tls-alps. This is not an IANA defined +// extension number. +#define TLSEXT_TYPE_application_settings 17513 + +// ExtensionType values from draft-ietf-tls-esni-13. This is not an IANA defined +// extension number. +#define TLSEXT_TYPE_encrypted_client_hello 0xfe0d +#define TLSEXT_TYPE_ech_outer_extensions 0xfd00 + +// ExtensionType value from RFC 6962 +#define TLSEXT_TYPE_certificate_timestamp 18 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_next_proto_neg 13172 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_channel_id 30032 + +// status request value from RFC 3546 +#define TLSEXT_STATUSTYPE_nothing (-1) +#define TLSEXT_STATUSTYPE_ocsp 1 + +// ECPointFormat values from RFC 4492 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 + +// Signature and hash algorithms from RFC 5246 + +#define TLSEXT_signature_anonymous 0 +#define TLSEXT_signature_rsa 1 +#define TLSEXT_signature_dsa 2 +#define TLSEXT_signature_ecdsa 3 + +#define TLSEXT_hash_none 0 +#define TLSEXT_hash_md5 1 +#define TLSEXT_hash_sha1 2 +#define TLSEXT_hash_sha224 3 +#define TLSEXT_hash_sha256 4 +#define TLSEXT_hash_sha384 5 +#define TLSEXT_hash_sha512 6 + +// From https://www.rfc-editor.org/rfc/rfc8879.html#section-3 +#define TLSEXT_cert_compression_zlib 1 +#define TLSEXT_cert_compression_brotli 2 + +#define TLSEXT_MAXLEN_host_name 255 + +// PSK ciphersuites from 4279 +#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +// PSK ciphersuites from RFC 5489 +#define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +#define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +// Additional TLS ciphersuites from expired Internet Draft +// draft-ietf-tls-56-bit-ciphersuites-01.txt +// (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see +// s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably +// shouldn't. Note that the first two are actually not in the IDs. +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 // not in ID +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 // not in ID +#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +// AES ciphersuites from RFC 3268 + +#define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +#define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +#define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +// TLS v1.2 ciphersuites +#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +// Camellia ciphersuites from RFC 4132 +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +// TLS v1.2 ciphersuites +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +// Camellia ciphersuites from RFC 4132 +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +// SEED ciphersuites from RFC 4162 +#define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +#define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +#define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +// TLS v1.2 GCM ciphersuites from RFC 5288 +#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +// ECC ciphersuites from RFC 4492 +#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +#define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +// SRP ciphersuites from RFC 5054 +#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +// ECDH HMAC based ciphersuites from RFC 5289 + +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +// ECDH GCM based ciphersuites from RFC 5289 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +// ChaCha20-Poly1305 cipher suites from RFC 7905. +#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9 +#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC + +// TLS 1.3 ciphersuites from RFC 8446. +#define TLS1_CK_AES_128_GCM_SHA256 0x03001301 +#define TLS1_CK_AES_256_GCM_SHA384 0x03001302 +#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303 + +// XXX +// Inconsistency alert: +// The OpenSSL names of ciphers with ephemeral DH here include the string +// "DHE", while elsewhere it has always been "EDH". +// (The alias for the list of all such ciphers also is "EDH".) +// The specifications speak of "EDH"; maybe we should allow both forms +// for everything. +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA \ + "EXP1024-DHE-DSS-DES-CBC-SHA" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +// AES ciphersuites from RFC 3268 +#define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +#define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +#define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +#define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +// ECC ciphersuites from RFC 4492 +#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +// PSK ciphersuites from RFC 4279 +#define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +// PSK ciphersuites from RFC 5489 +#define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +#define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-PSK-AES256-CBC-SHA" + +// SRP ciphersuite from RFC 5054 +#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +// Camellia ciphersuites from RFC 4132 +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +// SEED ciphersuites from RFC 4162 +#define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +// TLS v1.2 ciphersuites +#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +// TLS v1.2 GCM ciphersuites from RFC 5288 +#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +// ECDH HMAC based ciphersuites from RFC 5289 + +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +// ECDH GCM based ciphersuites from RFC 5289 +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \ + "ECDHE-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 \ + "ECDHE-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 \ + "ECDH-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 \ + "ECDH-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-PSK-CHACHA20-POLY1305" + +// TLS 1.3 ciphersuites from RFC 8446. +#define TLS1_TXT_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +#define TLS1_TXT_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" + + +#define TLS_CT_RSA_SIGN 1 +#define TLS_CT_DSS_SIGN 2 +#define TLS_CT_RSA_FIXED_DH 3 +#define TLS_CT_DSS_FIXED_DH 4 +#define TLS_CT_ECDSA_SIGN 64 +#define TLS_CT_RSA_FIXED_ECDH 65 +#define TLS_CT_ECDSA_FIXED_ECDH 66 + +#define TLS_MD_MAX_CONST_SIZE 20 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_TLS1_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h new file mode 100644 index 00000000..298a12c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h @@ -0,0 +1,310 @@ +/* Copyright (c) 2020, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_TRUST_TOKEN_H +#define OPENSSL_HEADER_TRUST_TOKEN_H + +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_stack.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Trust Token implementation. +// +// Trust Token is an implementation of an experimental mechanism similar to +// Privacy Pass which allows issuance and redemption of anonymized tokens with +// limited private metadata. +// +// References: +// https://eprint.iacr.org/2020/072.pdf +// https://github.com/alxdavids/privacy-pass-ietf/tree/master/drafts +// https://github.com/WICG/trust-token-api/blob/master/README.md +// +// WARNING: This API is unstable and subject to change. + +// TRUST_TOKEN_experiment_v1 is an experimental Trust Tokens protocol using +// PMBTokens and P-384. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void); + +// TRUST_TOKEN_experiment_v2_voprf is an experimental Trust Tokens protocol +// using VOPRFs and P-384 with up to 6 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void); + +// TRUST_TOKEN_experiment_v2_pmb is an experimental Trust Tokens protocol using +// PMBTokens and P-384 with up to 3 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void); + +// trust_token_st represents a single-use token for the Trust Token protocol. +// For the client, this is the token and its corresponding signature. For the +// issuer, this is the token itself. +struct trust_token_st { + uint8_t *data; + size_t len; +}; + +DEFINE_STACK_OF(TRUST_TOKEN) + +// TRUST_TOKEN_new creates a newly-allocated |TRUST_TOKEN| with value |data| or +// NULL on allocation failure. +OPENSSL_EXPORT TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len); + +// TRUST_TOKEN_free releases memory associated with |token|. +OPENSSL_EXPORT void TRUST_TOKEN_free(TRUST_TOKEN *token); + +#define TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE 512 +#define TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE 512 + +// TRUST_TOKEN_generate_key creates a new Trust Token keypair labeled with |id| +// and serializes the private and public keys, writing the private key to +// |out_priv_key| and setting |*out_priv_key_len| to the number of bytes +// written, and writing the public key to |out_pub_key| and setting +// |*out_pub_key_len| to the number of bytes written. +// +// At most |max_priv_key_len| and |max_pub_key_len| bytes are written. In order +// to ensure success, these should be at least +// |TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE| and |TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE|. +// +// WARNING: This API is unstable and the serializations of these keys are +// subject to change. Keys generated with this function may not be persisted. +// +// This function returns one on success or zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_generate_key( + const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key, + size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, + size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id); + + +// Trust Token client implementation. +// +// These functions implements the client half of the Trust Token protocol. A +// single |TRUST_TOKEN_CLIENT| can perform a single protocol operation. + +// TRUST_TOKEN_CLIENT_new returns a newly-allocated |TRUST_TOKEN_CLIENT| +// configured to use a max batchsize of |max_batchsize| or NULL on error. +// Issuance requests must be made in batches smaller than |max_batchsize|. This +// function will return an error if |max_batchsize| is too large for Trust +// Tokens. +OPENSSL_EXPORT TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new( + const TRUST_TOKEN_METHOD *method, size_t max_batchsize); + +// TRUST_TOKEN_CLIENT_free releases memory associated with |ctx|. +OPENSSL_EXPORT void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx); + +// TRUST_TOKEN_CLIENT_add_key configures the |ctx| to support the public key +// |key|. It sets |*out_key_index| to the index this key has been configured to. +// It returns one on success or zero on error if the |key| can't be parsed or +// too many keys have been configured. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, + size_t *out_key_index, + const uint8_t *key, + size_t key_len); + +// TRUST_TOKEN_CLIENT_set_srr_key sets the public key used to verify the SRR. It +// returns one on success and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, + EVP_PKEY *key); + +// TRUST_TOKEN_CLIENT_begin_issuance produces a request for |count| trust tokens +// and serializes the request into a newly-allocated buffer, setting |*out| to +// that buffer and |*out_len| to its length. The caller takes ownership of the +// buffer and must call |OPENSSL_free| when done. It returns one on success and +// zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, + uint8_t **out, + size_t *out_len, + size_t count); + +// TRUST_TOKEN_CLIENT_finish_issuance consumes |response| from the issuer and +// extracts the tokens, returning a list of tokens and the index of the key used +// to sign the tokens in |*out_key_index|. The caller can use this to determine +// what key was used in an issuance and to drop tokens if a new key commitment +// arrives without the specified key present. The caller takes ownership of the +// list and must call |sk_TRUST_TOKEN_pop_free| when done. The list is empty if +// issuance fails. +OPENSSL_EXPORT STACK_OF(TRUST_TOKEN) * + TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx, + size_t *out_key_index, + const uint8_t *response, + size_t response_len); + + +// TRUST_TOKEN_CLIENT_begin_redemption produces a request to redeem a token +// |token| and receive a signature over |data| and serializes the request into +// a newly-allocated buffer, setting |*out| to that buffer and |*out_len| to +// its length. |time| is the number of seconds since the UNIX epoch and used to +// verify the validity of the issuer's response in TrustTokenV1 and ignored in +// other versions. The caller takes ownership of the buffer and must call +// |OPENSSL_free| when done. It returns one on success or zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_redemption( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, + const TRUST_TOKEN *token, const uint8_t *data, size_t data_len, + uint64_t time); + +// TRUST_TOKEN_CLIENT_finish_redemption consumes |response| from the issuer. In +// |TRUST_TOKEN_experiment_v1|, it then verifies the SRR and if valid sets +// |*out_rr| and |*out_rr_len| (respectively, |*out_sig| and |*out_sig_len|) +// to a newly-allocated buffer containing the SRR (respectively, the SRR +// signature). In other versions, it sets |*out_rr| and |*out_rr_len| +// to a newly-allocated buffer containing |response| and leaves all validation +// to the caller. It returns one on success or zero on failure. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_finish_redemption( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out_rr, size_t *out_rr_len, + uint8_t **out_sig, size_t *out_sig_len, const uint8_t *response, + size_t response_len); + + +// Trust Token issuer implementation. +// +// These functions implement the issuer half of the Trust Token protocol. A +// |TRUST_TOKEN_ISSUER| can be reused across multiple protocol operations. It +// may be used concurrently on multiple threads by non-mutating functions, +// provided no other thread is concurrently calling a mutating function. +// Functions which take a |const| pointer are non-mutating and functions which +// take a non-|const| pointer are mutating. + +// TRUST_TOKEN_ISSUER_new returns a newly-allocated |TRUST_TOKEN_ISSUER| +// configured to use a max batchsize of |max_batchsize| or NULL on error. +// Issuance requests must be made in batches smaller than |max_batchsize|. This +// function will return an error if |max_batchsize| is too large for Trust +// Tokens. +OPENSSL_EXPORT TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new( + const TRUST_TOKEN_METHOD *method, size_t max_batchsize); + +// TRUST_TOKEN_ISSUER_free releases memory associated with |ctx|. +OPENSSL_EXPORT void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx); + +// TRUST_TOKEN_ISSUER_add_key configures the |ctx| to support the private key +// |key|. It must be a private key returned by |TRUST_TOKEN_generate_key|. It +// returns one on success or zero on error. This function may fail if the |key| +// can't be parsed or too many keys have been configured. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, + const uint8_t *key, + size_t key_len); + +// TRUST_TOKEN_ISSUER_set_srr_key sets the private key used to sign the SRR. It +// returns one on success and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, + EVP_PKEY *key); + +// TRUST_TOKEN_ISSUER_set_metadata_key sets the key used to encrypt the private +// metadata. The key is a randomly generated bytestring of at least 32 bytes +// used to encode the private metadata bit in the SRR. It returns one on success +// and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx, + const uint8_t *key, + size_t len); + +// TRUST_TOKEN_ISSUER_issue ingests |request| for token issuance +// and generates up to |max_issuance| valid tokens, producing a list of blinded +// tokens and storing the response into a newly-allocated buffer and setting +// |*out| to that buffer, |*out_len| to its length, and |*out_tokens_issued| to +// the number of tokens issued. The tokens are issued with public metadata of +// |public_metadata| and a private metadata value of |private_metadata|. +// |public_metadata| must be one of the previously configured key IDs. +// |private_metadata| must be 0 or 1. The caller takes ownership of the buffer +// and must call |OPENSSL_free| when done. It returns one on success or zero on +// error. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue( + const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, + size_t *out_tokens_issued, const uint8_t *request, size_t request_len, + uint32_t public_metadata, uint8_t private_metadata, size_t max_issuance); + +// TRUST_TOKEN_ISSUER_redeem ingests a |request| for token redemption and +// verifies the token. If the token is valid, a RR is produced with a lifetime +// of |lifetime| (in seconds), signing over the requested data from the request +// and the value of the token, storing the result into a newly-allocated buffer +// and setting |*out| to that buffer and |*out_len| to its length. The extracted +// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in +// |*out_token|. The extracted client data is stored into a newly-allocated +// buffer and stored in |*out_client_data|. In TrustTokenV1, the extracted +// redemption time is stored in |*out_redemption_time|. The caller takes +// ownership of each output buffer and must call |OPENSSL_free| when done. It +// returns one on success or zero on error. +// +// The caller must keep track of all values of |*out_token| seen globally before +// returning the SRR to the client. If the value has been reused, the caller +// must discard the SRR and report an error to the caller. Returning an SRR with +// replayed values allows an attacker to double-spend tokens. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( + const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, uint64_t *out_redemption_time, + const uint8_t *request, size_t request_len, uint64_t lifetime); + +// TRUST_TOKEN_ISSUER_redeem_raw ingests a |request| for token redemption and +// verifies the token. The public metadata is stored in |*out_public|. The +// private metadata (if any) is stored in |*out_private|. The extracted +// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in +// |*out_token|. The extracted client data is stored into a newly-allocated +// buffer and stored in |*out_client_data|. The caller takes ownership of each +// output buffer and must call |OPENSSL_free| when done. It returns one on +// success or zero on error. +// +// The caller must keep track of all values of |*out_token| seen globally before +// returning a response to the client. If the value has been reused, the caller +// must report an error to the client. Returning a response with replayed values +// allows an attacker to double-spend tokens. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_raw( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len); + +// TRUST_TOKEN_decode_private_metadata decodes |encrypted_bit| using the +// private metadata key specified by a |key| buffer of length |key_len| and the +// nonce by a |nonce| buffer of length |nonce_len|. The nonce in +// |TRUST_TOKEN_experiment_v1| is the token-hash field of the SRR. |*out_value| +// is set to the decrypted value, either zero or one. It returns one on success +// and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_decode_private_metadata( + const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key, + size_t key_len, const uint8_t *nonce, size_t nonce_len, + uint8_t encrypted_bit); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(TRUST_TOKEN, TRUST_TOKEN_free) +BORINGSSL_MAKE_DELETER(TRUST_TOKEN_CLIENT, TRUST_TOKEN_CLIENT_free) +BORINGSSL_MAKE_DELETER(TRUST_TOKEN_ISSUER, TRUST_TOKEN_ISSUER_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#define TRUST_TOKEN_R_KEYGEN_FAILURE 100 +#define TRUST_TOKEN_R_BUFFER_TOO_SMALL 101 +#define TRUST_TOKEN_R_OVER_BATCHSIZE 102 +#define TRUST_TOKEN_R_DECODE_ERROR 103 +#define TRUST_TOKEN_R_SRR_SIGNATURE_ERROR 104 +#define TRUST_TOKEN_R_DECODE_FAILURE 105 +#define TRUST_TOKEN_R_INVALID_METADATA 106 +#define TRUST_TOKEN_R_TOO_MANY_KEYS 107 +#define TRUST_TOKEN_R_NO_KEYS_CONFIGURED 108 +#define TRUST_TOKEN_R_INVALID_KEY_ID 109 +#define TRUST_TOKEN_R_INVALID_TOKEN 110 +#define TRUST_TOKEN_R_BAD_VALIDITY_CHECK 111 +#define TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED 112 +#define TRUST_TOKEN_R_INVALID_METADATA_KEY 113 +#define TRUST_TOKEN_R_INVALID_PROOF 114 + +#endif // OPENSSL_HEADER_TRUST_TOKEN_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_type_check.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_type_check.h new file mode 100644 index 00000000..014217b3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_type_check.h @@ -0,0 +1,95 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_TYPE_CHECK_H +#define OPENSSL_HEADER_TYPE_CHECK_H + +#include "CNIOBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(__cplusplus) || (defined(_MSC_VER) && !defined(__clang__)) +// In C++ and non-clang MSVC, |static_assert| is a keyword. +#define OPENSSL_STATIC_ASSERT(cond, msg) static_assert(cond, msg) +#else +// C11 defines the |_Static_assert| keyword and the |static_assert| macro in +// assert.h. While the former is available at all versions in Clang and GCC, the +// later depends on libc and, in glibc, depends on being built in C11 mode. We +// require C11 mode to build the library but, for now, do not require it in +// public headers. Use |_Static_assert| directly. +// +// TODO(davidben): In July 2022, if the C11 change has not been reverted, switch +// all uses of this macro within the library to C11 |static_assert|. This macro +// will only be necessary in public headers. +#define OPENSSL_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) +#endif + +// CHECKED_CAST casts |p| from type |from| to type |to|. +// +// TODO(davidben): Although this macro is not public API and is unused in +// BoringSSL, wpa_supplicant uses it to define its own stacks. Remove this once +// wpa_supplicant has been fixed. +#define CHECKED_CAST(to, from, p) ((to) (1 ? (p) : (from)0)) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_TYPE_CHECK_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h new file mode 100644 index 00000000..960d0a33 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h @@ -0,0 +1,2468 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +#define HEADER_X509_H + +#include "CNIOBoringSSL_asn1.h" +#include "CNIOBoringSSL_base.h" +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_cipher.h" +#include "CNIOBoringSSL_dh.h" +#include "CNIOBoringSSL_dsa.h" +#include "CNIOBoringSSL_ec.h" +#include "CNIOBoringSSL_ecdh.h" +#include "CNIOBoringSSL_ecdsa.h" +#include "CNIOBoringSSL_evp.h" +#include "CNIOBoringSSL_obj.h" +#include "CNIOBoringSSL_pkcs7.h" +#include "CNIOBoringSSL_pool.h" +#include "CNIOBoringSSL_rsa.h" +#include "CNIOBoringSSL_sha.h" +#include "CNIOBoringSSL_stack.h" +#include "CNIOBoringSSL_thread.h" +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Legacy X.509 library. +// +// This header is part of OpenSSL's X.509 implementation. It is retained for +// compatibility but otherwise underdocumented and not actively maintained. In +// the future, a replacement library will be available. Meanwhile, minimize +// dependencies on this header where possible. + + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */; + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) + +DEFINE_STACK_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +DEFINE_STACK_OF(X509_NAME_ENTRY) + +DEFINE_STACK_OF(X509_NAME) + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) + +DEFINE_STACK_OF(X509_ATTRIBUTE) + +// This stuff is certificate "auxiliary info" +// it contains details which are useful in certificate +// stores and databases. When used this is tagged onto +// the end of the certificate itself + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_STACK_OF(GENERAL_NAME) + +DEFINE_STACK_OF(X509) + +// This is used for a table of trust checking functions + +struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} /* X509_TRUST */; + +DEFINE_STACK_OF(X509_TRUST) + +// standard trust ids + +#define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 + +// Keep these up to date! +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 8 + + +// trust_flags values +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +// check_trust return codes + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +// Flags for X509_print_ex() + +#define X509_FLAG_COMPAT 0 +#define X509_FLAG_NO_HEADER 1L +#define X509_FLAG_NO_VERSION (1L << 1) +#define X509_FLAG_NO_SERIAL (1L << 2) +#define X509_FLAG_NO_SIGNAME (1L << 3) +#define X509_FLAG_NO_ISSUER (1L << 4) +#define X509_FLAG_NO_VALIDITY (1L << 5) +#define X509_FLAG_NO_SUBJECT (1L << 6) +#define X509_FLAG_NO_PUBKEY (1L << 7) +#define X509_FLAG_NO_EXTENSIONS (1L << 8) +#define X509_FLAG_NO_SIGDUMP (1L << 9) +#define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) +#define X509_FLAG_NO_IDS (1L << 12) + +// Flags specific to X509_NAME_print_ex() + +// The field separator information + +#define XN_FLAG_SEP_MASK (0xf << 16) + +#define XN_FLAG_COMPAT 0 // Traditional SSLeay: use old X509_NAME_print +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) // RFC 2253 ,+ +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) // ,+ spaced: more readable +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) // ;+ spaced +#define XN_FLAG_SEP_MULTILINE (4 << 16) // One line per field + +#define XN_FLAG_DN_REV (1 << 20) // Reverse DN order + +// How the field name is shown + +#define XN_FLAG_FN_MASK (0x3 << 21) + +#define XN_FLAG_FN_SN 0 // Object short name +#define XN_FLAG_FN_LN (1 << 21) // Object long name +#define XN_FLAG_FN_OID (2 << 21) // Always use OIDs +#define XN_FLAG_FN_NONE (3 << 21) // No field names + +#define XN_FLAG_SPC_EQ (1 << 23) // Put spaces round '=' + +// This determines if we dump fields we don't recognise: +// RFC 2253 requires this. + +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +#define XN_FLAG_FN_ALIGN (1 << 25) // Align field names to 20 characters + +// Complete set of RFC 2253 flags + +#define XN_FLAG_RFC2253 \ + (ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS) + +// readable oneline form + +#define XN_FLAG_ONELINE \ + (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | XN_FLAG_FN_SN) + +// readable multiline form + +#define XN_FLAG_MULTILINE \ + (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN) + +DEFINE_STACK_OF(X509_REVOKED) + +DECLARE_STACK_OF(GENERAL_NAMES) + +DEFINE_STACK_OF(X509_CRL) + +struct private_key_st { + int version; + // The PKCS#8 data types + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; // encrypted pub key + + // When decrypted, the following will not be NULL + EVP_PKEY *dec_pkey; + + // used to encrypt and decrypt + int key_length; + char *key_data; + int key_free; // true if we should auto free key_data + + // expanded version of 'enc_algor' + EVP_CIPHER_INFO cipher; +} /* X509_PKEY */; + +struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + +} /* X509_INFO */; + +DEFINE_STACK_OF(X509_INFO) + +// The next 2 structures and their 8 routines were sent to me by +// Pat Richard and are used to manipulate +// Netscapes spki structures - useful if you are writing a CA web page +struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; // challenge sent in atlas >= PR2 +} /* NETSCAPE_SPKAC */; + +struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; // signed public key and challenge + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} /* NETSCAPE_SPKI */; + +// TODO(davidben): Document remaining functions, reorganize them, and define +// supported patterns for using |X509| objects in general. In particular, when +// it is safe to call mutating functions is a little tricky due to various +// internal caches. + +// X509_VERSION_* are X.509 version numbers. Note the numerical values of all +// defined X.509 versions are one less than the named version. +#define X509_VERSION_1 0 +#define X509_VERSION_2 1 +#define X509_VERSION_3 2 + +// X509_get_version returns the numerical value of |x509|'s version. Callers may +// compare the result to the |X509_VERSION_*| constants. Unknown versions are +// rejected by the parser, but a manually-created |X509| object may encode +// invalid versions. In that case, the function will return the invalid version, +// or -1 on overflow. +OPENSSL_EXPORT long X509_get_version(const X509 *x509); + +// X509_set_version sets |x509|'s version to |version|, which should be one of +// the |X509V_VERSION_*| constants. It returns one on success and zero on error. +// +// If unsure, use |X509_VERSION_3|. +OPENSSL_EXPORT int X509_set_version(X509 *x509, long version); + +// X509_get0_serialNumber returns |x509|'s serial number. +OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509); + +// X509_set_serialNumber sets |x509|'s serial number to |serial|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_set_serialNumber(X509 *x509, + const ASN1_INTEGER *serial); + +// X509_get0_notBefore returns |x509|'s notBefore time. +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notBefore(const X509 *x509); + +// X509_get0_notAfter returns |x509|'s notAfter time. +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notAfter(const X509 *x509); + +// X509_set1_notBefore sets |x509|'s notBefore time to |tm|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int X509_set1_notBefore(X509 *x509, const ASN1_TIME *tm); + +// X509_set1_notAfter sets |x509|'s notAfter time to |tm|. it returns one on +// success and zero on error. +OPENSSL_EXPORT int X509_set1_notAfter(X509 *x509, const ASN1_TIME *tm); + +// X509_getm_notBefore returns a mutable pointer to |x509|'s notBefore time. +OPENSSL_EXPORT ASN1_TIME *X509_getm_notBefore(X509 *x509); + +// X509_getm_notAfter returns a mutable pointer to |x509|'s notAfter time. +OPENSSL_EXPORT ASN1_TIME *X509_getm_notAfter(X509 *x); + +// X509_get_notBefore returns |x509|'s notBefore time. Note this function is not +// const-correct for legacy reasons. Use |X509_get0_notBefore| or +// |X509_getm_notBefore| instead. +OPENSSL_EXPORT ASN1_TIME *X509_get_notBefore(const X509 *x509); + +// X509_get_notAfter returns |x509|'s notAfter time. Note this function is not +// const-correct for legacy reasons. Use |X509_get0_notAfter| or +// |X509_getm_notAfter| instead. +OPENSSL_EXPORT ASN1_TIME *X509_get_notAfter(const X509 *x509); + +// X509_set_notBefore calls |X509_set1_notBefore|. Use |X509_set1_notBefore| +// instead. +OPENSSL_EXPORT int X509_set_notBefore(X509 *x509, const ASN1_TIME *tm); + +// X509_set_notAfter calls |X509_set1_notAfter|. Use |X509_set1_notAfter| +// instead. +OPENSSL_EXPORT int X509_set_notAfter(X509 *x509, const ASN1_TIME *tm); + +// X509_get0_uids sets |*out_issuer_uid| to a non-owning pointer to the +// issuerUID field of |x509|, or NULL if |x509| has no issuerUID. It similarly +// outputs |x509|'s subjectUID field to |*out_subject_uid|. +// +// Callers may pass NULL to either |out_issuer_uid| or |out_subject_uid| to +// ignore the corresponding field. +OPENSSL_EXPORT void X509_get0_uids(const X509 *x509, + const ASN1_BIT_STRING **out_issuer_uid, + const ASN1_BIT_STRING **out_subject_uid); + +// X509_extract_key is a legacy alias to |X509_get_pubkey|. Use +// |X509_get_pubkey| instead. +#define X509_extract_key(x) X509_get_pubkey(x) + +// X509_get_pathlen returns path length constraint from the basic constraints +// extension in |x509|. (See RFC 5280, section 4.2.1.9.) It returns -1 if the +// constraint is not present, or if some extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT long X509_get_pathlen(X509 *x509); + +// X509_REQ_VERSION_1 is the version constant for |X509_REQ| objects. Note no +// other versions are defined. +#define X509_REQ_VERSION_1 0 + +// X509_REQ_get_version returns the numerical value of |req|'s version. This +// will be |X509_REQ_VERSION_1| for valid certificate requests. If |req| is +// invalid, it may return another value, or -1 on overflow. +// +// TODO(davidben): Enforce the version number in the parser. +OPENSSL_EXPORT long X509_REQ_get_version(const X509_REQ *req); + +// X509_REQ_get_subject_name returns |req|'s subject name. Note this function is +// not const-correct for legacy reasons. +OPENSSL_EXPORT X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); + +// X509_REQ_extract_key is a legacy alias for |X509_REQ_get_pubkey|. +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) + +// X509_name_cmp is a legacy alias for |X509_NAME_cmp|. +#define X509_name_cmp(a, b) X509_NAME_cmp((a), (b)) + +#define X509_CRL_VERSION_1 0 +#define X509_CRL_VERSION_2 1 + +// X509_CRL_get_version returns the numerical value of |crl|'s version. Callers +// may compare the result to |X509_CRL_VERSION_*| constants. If |crl| is +// invalid, it may return another value, or -1 on overflow. +// +// TODO(davidben): Enforce the version number in the parser. +OPENSSL_EXPORT long X509_CRL_get_version(const X509_CRL *crl); + +// X509_CRL_get0_lastUpdate returns |crl|'s lastUpdate time. +OPENSSL_EXPORT const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); + +// X509_CRL_get0_nextUpdate returns |crl|'s nextUpdate time, or NULL if |crl| +// has none. +OPENSSL_EXPORT const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); + +// X509_CRL_set1_lastUpdate sets |crl|'s lastUpdate time to |tm|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_CRL_set1_lastUpdate(X509_CRL *crl, const ASN1_TIME *tm); + +// X509_CRL_set1_nextUpdate sets |crl|'s nextUpdate time to |tm|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_CRL_set1_nextUpdate(X509_CRL *crl, const ASN1_TIME *tm); + +// The following symbols are deprecated aliases to |X509_CRL_set1_*|. +#define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +#define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate + +// X509_CRL_get_lastUpdate returns a mutable pointer to |crl|'s lastUpdate time. +// Use |X509_CRL_get0_lastUpdate| or |X509_CRL_set1_lastUpdate| instead. +OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl); + +// X509_CRL_get_nextUpdate returns a mutable pointer to |crl|'s nextUpdate time, +// or NULL if |crl| has none. Use |X509_CRL_get0_nextUpdate| or +// |X509_CRL_set1_nextUpdate| instead. +OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl); + +// X509_CRL_get_issuer returns |crl|'s issuer name. Note this function is not +// const-correct for legacy reasons. +OPENSSL_EXPORT X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); + +// X509_CRL_get_REVOKED returns the list of revoked certificates in |crl|, or +// NULL if |crl| omits it. +// +// TOOD(davidben): This function was originally a macro, without clear const +// semantics. It should take a const input and give const output, but the latter +// would break existing callers. For now, we match upstream. +OPENSSL_EXPORT STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); + +// X509_CRL_get0_extensions returns |crl|'s extension list, or NULL if |crl| +// omits it. +OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions( + const X509_CRL *crl); + +// X509_SIG_get0 sets |*out_alg| and |*out_digest| to non-owning pointers to +// |sig|'s algorithm and digest fields, respectively. Either |out_alg| and +// |out_digest| may be NULL to skip those fields. +OPENSSL_EXPORT void X509_SIG_get0(const X509_SIG *sig, + const X509_ALGOR **out_alg, + const ASN1_OCTET_STRING **out_digest); + +// X509_SIG_getm behaves like |X509_SIG_get0| but returns mutable pointers. +OPENSSL_EXPORT void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, + ASN1_OCTET_STRING **out_digest); + +OPENSSL_EXPORT void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +OPENSSL_EXPORT X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); +OPENSSL_EXPORT void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +OPENSSL_EXPORT void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +OPENSSL_EXPORT void *X509_CRL_get_meth_data(X509_CRL *crl); + +// X509_get_X509_PUBKEY returns the public key of |x509|. Note this function is +// not const-correct for legacy reasons. Callers should not modify the returned +// object. +OPENSSL_EXPORT X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509); + +// X509_verify_cert_error_string returns |err| as a human-readable string, where +// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns +// a default description. +OPENSSL_EXPORT const char *X509_verify_cert_error_string(long err); + +// X509_verify checks that |x509| has a valid signature by |pkey|. It returns +// one if the signature is valid and zero otherwise. Note this function only +// checks the signature itself and does not perform a full certificate +// validation. +OPENSSL_EXPORT int X509_verify(X509 *x509, EVP_PKEY *pkey); + +// X509_REQ_verify checks that |req| has a valid signature by |pkey|. It returns +// one if the signature is valid and zero otherwise. +OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey); + +// X509_CRL_verify checks that |crl| has a valid signature by |pkey|. It returns +// one if the signature is valid and zero otherwise. +OPENSSL_EXPORT int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey); + +// NETSCAPE_SPKI_verify checks that |spki| has a valid signature by |pkey|. It +// returns one if the signature is valid and zero otherwise. +OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey); + +// NETSCAPE_SPKI_b64_decode decodes |len| bytes from |str| as a base64-encoded +// Netscape signed public key and challenge (SPKAC) structure. It returns a +// newly-allocated |NETSCAPE_SPKI| structure with the result, or NULL on error. +// If |len| is 0 or negative, the length is calculated with |strlen| and |str| +// must be a NUL-terminated C string. +OPENSSL_EXPORT NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, + int len); + +// NETSCAPE_SPKI_b64_encode encodes |spki| as a base64-encoded Netscape signed +// public key and challenge (SPKAC) structure. It returns a newly-allocated +// NUL-terminated C string with the result, or NULL on error. The caller must +// release the memory with |OPENSSL_free| when done. +OPENSSL_EXPORT char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki); + +// NETSCAPE_SPKI_get_pubkey decodes and returns the public key in |spki| as an +// |EVP_PKEY|, or NULL on error. The caller takes ownership of the resulting +// pointer and must call |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *spki); + +// NETSCAPE_SPKI_set_pubkey sets |spki|'s public key to |pkey|. It returns one +// on success or zero on error. This function does not take ownership of |pkey|, +// so the caller may continue to manage its lifetime independently of |spki|. +OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *spki, + EVP_PKEY *pkey); + +// X509_signature_dump writes a human-readable representation of |sig| to |bio|, +// indented with |indent| spaces. It returns one on success and zero on error. +OPENSSL_EXPORT int X509_signature_dump(BIO *bio, const ASN1_STRING *sig, + int indent); + +// X509_signature_print writes a human-readable representation of |alg| and +// |sig| to |bio|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509_signature_print(BIO *bio, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +// X509_sign signs |x509| with |pkey| and replaces the signature algorithm and +// signature fields. It returns one on success and zero on error. This function +// uses digest algorithm |md|, or |pkey|'s default if NULL. Other signing +// parameters use |pkey|'s defaults. To customize them, use |X509_sign_ctx|. +OPENSSL_EXPORT int X509_sign(X509 *x509, EVP_PKEY *pkey, const EVP_MD *md); + +// X509_sign_ctx signs |x509| with |ctx| and replaces the signature algorithm +// and signature fields. It returns one on success and zero on error. The +// signature algorithm and parameters come from |ctx|, which must have been +// initialized with |EVP_DigestSignInit|. The caller should configure the +// corresponding |EVP_PKEY_CTX| before calling this function. +OPENSSL_EXPORT int X509_sign_ctx(X509 *x509, EVP_MD_CTX *ctx); + +// X509_REQ_sign signs |req| with |pkey| and replaces the signature algorithm +// and signature fields. It returns one on success and zero on error. This +// function uses digest algorithm |md|, or |pkey|'s default if NULL. Other +// signing parameters use |pkey|'s defaults. To customize them, use +// |X509_REQ_sign_ctx|. +OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *req, EVP_PKEY *pkey, + const EVP_MD *md); + +// X509_REQ_sign_ctx signs |req| with |ctx| and replaces the signature algorithm +// and signature fields. It returns one on success and zero on error. The +// signature algorithm and parameters come from |ctx|, which must have been +// initialized with |EVP_DigestSignInit|. The caller should configure the +// corresponding |EVP_PKEY_CTX| before calling this function. +OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *req, EVP_MD_CTX *ctx); + +// X509_CRL_sign signs |crl| with |pkey| and replaces the signature algorithm +// and signature fields. It returns one on success and zero on error. This +// function uses digest algorithm |md|, or |pkey|'s default if NULL. Other +// signing parameters use |pkey|'s defaults. To customize them, use +// |X509_CRL_sign_ctx|. +OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *crl, EVP_PKEY *pkey, + const EVP_MD *md); + +// X509_CRL_sign_ctx signs |crl| with |ctx| and replaces the signature algorithm +// and signature fields. It returns one on success and zero on error. The +// signature algorithm and parameters come from |ctx|, which must have been +// initialized with |EVP_DigestSignInit|. The caller should configure the +// corresponding |EVP_PKEY_CTX| before calling this function. +OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *crl, EVP_MD_CTX *ctx); + +// NETSCAPE_SPKI_sign signs |spki| with |pkey| and replaces the signature +// algorithm and signature fields. It returns one on success and zero on error. +// This function uses digest algorithm |md|, or |pkey|'s default if NULL. Other +// signing parameters use |pkey|'s defaults. +OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *spki, EVP_PKEY *pkey, + const EVP_MD *md); + +// X509_pubkey_digest hashes the DER encoding of |x509|'s subjectPublicKeyInfo +// field with |md| and writes the result to |out|. |EVP_MD_CTX_size| bytes are +// written, which is at most |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, +// |*out_len| is set to the number of bytes written. This function returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_pubkey_digest(const X509 *x509, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_digest hashes |x509|'s DER encoding with |md| and writes the result to +// |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire certificate, not just the signed portion. +OPENSSL_EXPORT int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out, + unsigned *out_len); + +// X509_CRL_digest hashes |crl|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire CRL, not just the signed portion. +OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *crl, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_REQ_digest hashes |req|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire certificate request, not just the signed +// portion. +OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *req, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_NAME_digest hashes |name|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *name, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_parse_from_buffer parses an X.509 structure from |buf| and returns a +// fresh X509 or NULL on error. There must not be any trailing data in |buf|. +// The returned structure (if any) holds a reference to |buf| rather than +// copying parts of it as a normal |d2i_X509| call would do. +OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); + +OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509); +OPENSSL_EXPORT int i2d_X509_fp(FILE *fp, X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp( + FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); + +OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp, X509 **x509); +OPENSSL_EXPORT int i2d_X509_bio(BIO *bp, X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio( + BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +OPENSSL_EXPORT DH *d2i_DHparams_bio(BIO *bp, DH **dh); +OPENSSL_EXPORT int i2d_DHparams_bio(BIO *bp, const DH *dh); + +OPENSSL_EXPORT X509 *X509_dup(X509 *x509); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); +OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); +OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); + +// X509_ALGOR_set0 sets |alg| to an AlgorithmIdentifier with algorithm |obj| and +// parameter determined by |param_type| and |param_value|. It returns one on +// success and zero on error. This function takes ownership of |obj| and +// |param_value| on success. +// +// If |param_type| is |V_ASN1_UNDEF|, the parameter is omitted. If |param_type| +// is zero, the parameter is left unchanged. Otherwise, |param_type| and +// |param_value| are interpreted as in |ASN1_TYPE_set|. +// +// Note omitting the parameter (|V_ASN1_UNDEF|) and encoding an explicit NULL +// value (|V_ASN1_NULL|) are different. Some algorithms require one and some the +// other. Consult the relevant specification before calling this function. The +// correct parameter for an RSASSA-PKCS1-v1_5 signature is |V_ASN1_NULL|. The +// correct one for an ECDSA or Ed25519 signature is |V_ASN1_UNDEF|. +OPENSSL_EXPORT int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *obj, + int param_type, void *param_value); + +// X509_ALGOR_get0 sets |*out_obj| to the |alg|'s algorithm. If |alg|'s +// parameter is omitted, it sets |*out_param_type| and |*out_param_value| to +// |V_ASN1_UNDEF| and NULL. Otherwise, it sets |*out_param_type| and +// |*out_param_value| to the parameter, using the same representation as +// |ASN1_TYPE_set0|. See |ASN1_TYPE_set0| and |ASN1_TYPE| for details. +// +// Callers that require the parameter in serialized form should, after checking +// for |V_ASN1_UNDEF|, use |ASN1_TYPE_set1| and |d2i_ASN1_TYPE|, rather than +// inspecting |*out_param_value|. +// +// Each of |out_obj|, |out_param_type|, and |out_param_value| may be NULL to +// ignore the output. If |out_param_type| is NULL, |out_param_value| is ignored. +// +// WARNING: If |*out_param_type| is set to |V_ASN1_UNDEF|, OpenSSL and older +// revisions of BoringSSL leave |*out_param_value| unset rather than setting it +// to NULL. Callers that support both OpenSSL and BoringSSL should not assume +// |*out_param_value| is uniformly initialized. +OPENSSL_EXPORT void X509_ALGOR_get0(const ASN1_OBJECT **out_obj, + int *out_param_type, + const void **out_param_value, + const X509_ALGOR *alg); + +// X509_ALGOR_set_md sets |alg| to the hash function |md|. Note this +// AlgorithmIdentifier represents the hash function itself, not a signature +// algorithm that uses |md|. +OPENSSL_EXPORT void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); + +// X509_ALGOR_cmp returns zero if |a| and |b| are equal, and some non-zero value +// otherwise. Note this function can only be used for equality checks, not an +// ordering. +OPENSSL_EXPORT int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *xn); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); +OPENSSL_EXPORT int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +// X509_cmp_time compares |s| against |*t|. On success, it returns a negative +// number if |s| <= |*t| and a positive number if |s| > |*t|. On error, it +// returns zero. If |t| is NULL, it uses the current time instead of |*t|. +// +// WARNING: Unlike most comparison functions, this function returns zero on +// error, not equality. +OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); + +// X509_cmp_current_time behaves like |X509_cmp_time| but compares |s| against +// the current time. +OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); + +// X509_time_adj calls |X509_time_adj_ex| with |offset_day| equal to zero. +OPENSSL_EXPORT ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, + time_t *t); + +// X509_time_adj_ex behaves like |ASN1_TIME_adj|, but adds an offset to |*t|. If +// |t| is NULL, it uses the current time instead of |*t|. +OPENSSL_EXPORT ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, + long offset_sec, time_t *t); + +// X509_gmtime_adj behaves like |X509_time_adj_ex| but adds |offset_sec| to the +// current time. +OPENSSL_EXPORT ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec); + +OPENSSL_EXPORT const char *X509_get_default_cert_area(void); +OPENSSL_EXPORT const char *X509_get_default_cert_dir(void); +OPENSSL_EXPORT const char *X509_get_default_cert_file(void); +OPENSSL_EXPORT const char *X509_get_default_cert_dir_env(void); +OPENSSL_EXPORT const char *X509_get_default_cert_file_env(void); +OPENSSL_EXPORT const char *X509_get_default_private_dir(void); + +OPENSSL_EXPORT X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, + const EVP_MD *md); + +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +// X509_PUBKEY_set serializes |pkey| into a newly-allocated |X509_PUBKEY| +// structure. On success, it frees |*x|, sets |*x| to the new object, and +// returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); + +// X509_PUBKEY_get decodes the public key in |key| and returns an |EVP_PKEY| on +// success, or NULL on error. The caller must release the result with +// |EVP_PKEY_free| when done. The |EVP_PKEY| is cached in |key|, so callers must +// not mutate the result. +OPENSSL_EXPORT EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) + +// X509_ATTRIBUTE_create returns a newly-allocated |X509_ATTRIBUTE|, or NULL on +// error. The attribute has type |nid| and contains a single value determined by +// |attrtype| and |value|, which are interpreted as in |ASN1_TYPE_set|. Note +// this function takes ownership of |value|. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int attrtype, + void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +// X509_NAME_set makes a copy of |name|. On success, it frees |*xn|, sets |*xn| +// to the copy, and returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509) + +// X509_up_ref adds one to the reference count of |x509| and returns one. +OPENSSL_EXPORT int X509_up_ref(X509 *x509); + +OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); +OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); + +// i2d_re_X509_tbs serializes the TBSCertificate portion of |x509|, as described +// in |i2d_SAMPLE|. +// +// This function re-encodes the TBSCertificate and may not reflect |x509|'s +// original encoding. It may be used to manually generate a signature for a new +// certificate. To verify certificates, use |i2d_X509_tbs| instead. +OPENSSL_EXPORT int i2d_re_X509_tbs(X509 *x509, unsigned char **outp); + +// i2d_X509_tbs serializes the TBSCertificate portion of |x509|, as described in +// |i2d_SAMPLE|. +// +// This function preserves the original encoding of the TBSCertificate and may +// not reflect modifications made to |x509|. It may be used to manually verify +// the signature of an existing certificate. To generate certificates, use +// |i2d_re_X509_tbs| instead. +OPENSSL_EXPORT int i2d_X509_tbs(X509 *x509, unsigned char **outp); + +// X509_set1_signature_algo sets |x509|'s signature algorithm to |algo| and +// returns one on success or zero on error. It updates both the signature field +// of the TBSCertificate structure, and the signatureAlgorithm field of the +// Certificate. +OPENSSL_EXPORT int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo); + +// X509_set1_signature_value sets |x509|'s signature to a copy of the |sig_len| +// bytes pointed by |sig|. It returns one on success and zero on error. +// +// Due to a specification error, X.509 certificates store signatures in ASN.1 +// BIT STRINGs, but signature algorithms return byte strings rather than bit +// strings. This function creates a BIT STRING containing a whole number of +// bytes, with the bit order matching the DER encoding. This matches the +// encoding used by all X.509 signature algorithms. +OPENSSL_EXPORT int X509_set1_signature_value(X509 *x509, const uint8_t *sig, + size_t sig_len); + +// X509_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |x509|, respectively. Either output pointer may be +// NULL to ignore the value. +// +// This function outputs the outer signature algorithm. For the one in the +// TBSCertificate, see |X509_get0_tbs_sigalg|. Certificates with mismatched +// signature algorithms will successfully parse, but they will be rejected when +// verifying. +OPENSSL_EXPORT void X509_get0_signature(const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg, + const X509 *x509); + +// X509_get_signature_nid returns the NID corresponding to |x509|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x509); + + +// Auxiliary properties. +// +// |X509| objects optionally maintain auxiliary properties. These are not part +// of the certificates themselves, and thus are not covered by signatures or +// preserved by the standard serialization. They are used as inputs or outputs +// to other functions in this library. + +// i2d_X509_AUX marshals |x509| as a DER-encoded X.509 Certificate (RFC 5280), +// followed optionally by a separate, OpenSSL-specific structure with auxiliary +// properties. It behaves as described in |i2d_SAMPLE|. +// +// Unlike similarly-named functions, this function does not output a single +// ASN.1 element. Directly embedding the output in a larger ASN.1 structure will +// not behave correctly. +OPENSSL_EXPORT int i2d_X509_AUX(X509 *x509, unsigned char **outp); + +// d2i_X509_AUX parses up to |length| bytes from |*inp| as a DER-encoded X.509 +// Certificate (RFC 5280), followed optionally by a separate, OpenSSL-specific +// structure with auxiliary properties. It behaves as described in +// |d2i_SAMPLE_with_reuse|. +// +// Some auxiliary properties affect trust decisions, so this function should not +// be used with untrusted input. +// +// Unlike similarly-named functions, this function does not parse a single +// ASN.1 element. Trying to parse data directly embedded in a larger ASN.1 +// structure will not behave correctly. +OPENSSL_EXPORT X509 *d2i_X509_AUX(X509 **x509, const unsigned char **inp, + long length); + +// X509_alias_set1 sets |x509|'s alias to |len| bytes from |name|. If |name| is +// NULL, the alias is cleared instead. Aliases are not part of the certificate +// itself and will not be serialized by |i2d_X509|. +OPENSSL_EXPORT int X509_alias_set1(X509 *x509, const unsigned char *name, + int len); + +// X509_keyid_set1 sets |x509|'s key ID to |len| bytes from |id|. If |id| is +// NULL, the key ID is cleared instead. Key IDs are not part of the certificate +// itself and will not be serialized by |i2d_X509|. +OPENSSL_EXPORT int X509_keyid_set1(X509 *x509, const unsigned char *id, + int len); + +// X509_alias_get0 looks up |x509|'s alias. If found, it sets |*out_len| to the +// alias's length and returns a pointer to a buffer containing the contents. If +// not found, it outputs the empty string by returning NULL and setting +// |*out_len| to zero. +// +// If |x509| was parsed from a PKCS#12 structure (see +// |PKCS12_get_key_and_certs|), the alias will reflect the friendlyName +// attribute (RFC 2985). +// +// WARNING: In OpenSSL, this function did not set |*out_len| when the alias was +// missing. Callers that target both OpenSSL and BoringSSL should set the value +// to zero before calling this function. +OPENSSL_EXPORT unsigned char *X509_alias_get0(X509 *x509, int *out_len); + +// X509_keyid_get0 looks up |x509|'s key ID. If found, it sets |*out_len| to the +// key ID's length and returns a pointer to a buffer containing the contents. If +// not found, it outputs the empty string by returning NULL and setting +// |*out_len| to zero. +// +// WARNING: In OpenSSL, this function did not set |*out_len| when the alias was +// missing. Callers that target both OpenSSL and BoringSSL should set the value +// to zero before calling this function. +OPENSSL_EXPORT unsigned char *X509_keyid_get0(X509 *x509, int *out_len); + +OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT void X509_trust_clear(X509 *x); +OPENSSL_EXPORT void X509_reject_clear(X509 *x); + + +OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, + X509 *x); + +OPENSSL_EXPORT X509_PKEY *X509_PKEY_new(void); +OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +OPENSSL_EXPORT X509_INFO *X509_INFO_new(void); +OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); +OPENSSL_EXPORT char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, + void *data, unsigned char *md, + unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, + const X509_ALGOR *algor1, + const ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey); + +OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, + EVP_MD_CTX *ctx); + +// X509_get_serialNumber returns a mutable pointer to |x509|'s serial number. +// Prefer |X509_get0_serialNumber|. +OPENSSL_EXPORT ASN1_INTEGER *X509_get_serialNumber(X509 *x509); + +// X509_set_issuer_name sets |x509|'s issuer to a copy of |name|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_set_issuer_name(X509 *x509, X509_NAME *name); + +// X509_get_issuer_name returns |x509|'s issuer. +OPENSSL_EXPORT X509_NAME *X509_get_issuer_name(const X509 *x509); + +// X509_set_subject_name sets |x509|'s subject to a copy of |name|. It returns +// one on success and zero on error. +OPENSSL_EXPORT int X509_set_subject_name(X509 *x509, X509_NAME *name); + +// X509_get_issuer_name returns |x509|'s subject. +OPENSSL_EXPORT X509_NAME *X509_get_subject_name(const X509 *x509); + +// X509_set_pubkey sets |x509|'s public key to |pkey|. It returns one on success +// and zero on error. This function does not take ownership of |pkey| and +// internally copies and updates reference counts as needed. +OPENSSL_EXPORT int X509_set_pubkey(X509 *x509, EVP_PKEY *pkey); + +// X509_get_pubkey returns |x509|'s public key as an |EVP_PKEY|, or NULL if the +// public key was unsupported or could not be decoded. This function returns a +// reference to the |EVP_PKEY|. The caller must release the result with +// |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *X509_get_pubkey(X509 *x509); + +// X509_get0_pubkey_bitstr returns the BIT STRING portion of |x509|'s public +// key. Note this does not contain the AlgorithmIdentifier portion. +// +// WARNING: This function returns a non-const pointer for OpenSSL compatibility, +// but the caller must not modify the resulting object. Doing so will break +// internal invariants in |x509|. +OPENSSL_EXPORT ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x509); + +// X509_get0_extensions returns |x509|'s extension list, or NULL if |x509| omits +// it. +OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_get0_extensions( + const X509 *x509); + +// X509_get0_tbs_sigalg returns the signature algorithm in |x509|'s +// TBSCertificate. For the outer signature algorithm, see |X509_get0_signature|. +// +// Certificates with mismatched signature algorithms will successfully parse, +// but they will be rejected when verifying. +OPENSSL_EXPORT const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x509); + +// X509_REQ_set_version sets |req|'s version to |version|, which should be +// |X509_REQ_VERSION_1|. It returns one on success and zero on error. +// +// Note no versions other than |X509_REQ_VERSION_1| are defined for CSRs. +OPENSSL_EXPORT int X509_REQ_set_version(X509_REQ *req, long version); + +// X509_REQ_set_subject_name sets |req|'s subject to a copy of |name|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); + +// X509_REQ_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |req|, respectively. Either output pointer may be NULL +// to ignore the value. +OPENSSL_EXPORT void X509_REQ_get0_signature(const X509_REQ *req, + const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg); + +// X509_REQ_get_signature_nid returns the NID corresponding to |req|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_REQ_get_signature_nid(const X509_REQ *req); + +// i2d_re_X509_REQ_tbs serializes the CertificationRequestInfo (see RFC 2986) +// portion of |req|, as described in |i2d_SAMPLE|. +// +// This function re-encodes the CertificationRequestInfo and may not reflect +// |req|'s original encoding. It may be used to manually generate a signature +// for a new certificate request. +OPENSSL_EXPORT int i2d_re_X509_REQ_tbs(X509_REQ *req, uint8_t **outp); + +// X509_REQ_set_pubkey sets |req|'s public key to |pkey|. It returns one on +// success and zero on error. This function does not take ownership of |pkey| +// and internally copies and updates reference counts as needed. +OPENSSL_EXPORT int X509_REQ_set_pubkey(X509_REQ *req, EVP_PKEY *pkey); + +// X509_REQ_get_pubkey returns |req|'s public key as an |EVP_PKEY|, or NULL if +// the public key was unsupported or could not be decoded. This function returns +// a reference to the |EVP_PKEY|. The caller must release the result with +// |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); + +// X509_REQ_extension_nid returns one if |nid| is a supported CSR attribute type +// for carrying extensions and zero otherwise. The supported types are +// |NID_ext_req| (pkcs-9-at-extensionRequest from RFC 2985) and |NID_ms_ext_req| +// (a Microsoft szOID_CERT_EXTENSIONS variant). +OPENSSL_EXPORT int X509_REQ_extension_nid(int nid); + +// X509_REQ_get_extensions decodes the list of requested extensions in |req| and +// returns a newly-allocated |STACK_OF(X509_EXTENSION)| containing the result. +// It returns NULL on error, or if |req| did not request extensions. +// +// This function supports both pkcs-9-at-extensionRequest from RFC 2985 and the +// Microsoft szOID_CERT_EXTENSIONS variant. +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); + +// X509_REQ_add_extensions_nid adds an attribute to |req| of type |nid|, to +// request the certificate extensions in |exts|. It returns one on success and +// zero on error. |nid| should be |NID_ext_req| or |NID_ms_ext_req|. +OPENSSL_EXPORT int X509_REQ_add_extensions_nid( + X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts, int nid); + +// X509_REQ_add_extensions behaves like |X509_REQ_add_extensions_nid|, using the +// standard |NID_ext_req| for the attribute type. +OPENSSL_EXPORT int X509_REQ_add_extensions( + X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts); + +// X509_REQ_get_attr_count returns the number of attributes in |req|. +OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); + +// X509_REQ_get_attr_by_NID returns the index of the attribute in |req| of type +// |nid|, or a negative number if not found. If found, callers can use +// |X509_REQ_get_attr| to look up the attribute by index. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching attributes by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); + +// X509_REQ_get_attr_by_OBJ behaves like |X509_REQ_get_attr_by_NID| but looks +// for attributes of type |obj|. +OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, + const ASN1_OBJECT *obj, + int lastpos); + +// X509_REQ_get_attr returns the attribute at index |loc| in |req|, or NULL if +// out of bounds. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); + +// X509_REQ_delete_attr removes the attribute at index |loc| in |req|. It +// returns the removed attribute to the caller, or NULL if |loc| was out of +// bounds. If non-NULL, the caller must release the result with +// |X509_ATTRIBUTE_free| when done. It is also safe, but not necessary, to call +// |X509_ATTRIBUTE_free| if the result is NULL. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); + +// X509_REQ_add1_attr appends a copy of |attr| to |req|'s list of attributes. It +// returns one on success and zero on error. +// +// TODO(https://crbug.com/boringssl/407): |attr| should be const. +OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); + +// X509_REQ_add1_attr_by_OBJ appends a new attribute to |req| with type |obj|. +// It returns one on success and zero on error. The value is determined by +// |X509_ATTRIBUTE_set1_data|. +// +// WARNING: The interpretation of |attrtype|, |data|, and |len| is complex and +// error-prone. See |X509_ATTRIBUTE_set1_data| for details. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, + int attrtype, + const unsigned char *data, + int len); + +// X509_REQ_add1_attr_by_NID behaves like |X509_REQ_add1_attr_by_OBJ| except the +// attribute type is determined by |nid|. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, + int attrtype, + const unsigned char *data, + int len); + +// X509_REQ_add1_attr_by_txt behaves like |X509_REQ_add1_attr_by_OBJ| except the +// attribute type is determined by calling |OBJ_txt2obj| with |attrname|. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int attrtype, + const unsigned char *data, + int len); + +// X509_CRL_set_version sets |crl|'s version to |version|, which should be one +// of the |X509_CRL_VERSION_*| constants. It returns one on success and zero on +// error. +// +// If unsure, use |X509_CRL_VERSION_2|. Note that, unlike certificates, CRL +// versions are only defined up to v2. Callers should not use |X509_VERSION_3|. +OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *crl, long version); + +// X509_CRL_set_issuer_name sets |crl|'s issuer to a copy of |name|. It returns +// one on success and zero on error. +OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *crl, X509_NAME *name); + +OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl); + +// X509_CRL_up_ref adds one to the reference count of |crl| and returns one. +OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); + +// X509_CRL_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |crl|, respectively. Either output pointer may be NULL +// to ignore the value. +// +// This function outputs the outer signature algorithm, not the one in the +// TBSCertList. CRLs with mismatched signature algorithms will successfully +// parse, but they will be rejected when verifying. +OPENSSL_EXPORT void X509_CRL_get0_signature(const X509_CRL *crl, + const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg); + +// X509_CRL_get_signature_nid returns the NID corresponding to |crl|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_CRL_get_signature_nid(const X509_CRL *crl); + +// i2d_re_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described +// in |i2d_SAMPLE|. +// +// This function re-encodes the TBSCertList and may not reflect |crl|'s original +// encoding. It may be used to manually generate a signature for a new CRL. To +// verify CRLs, use |i2d_X509_CRL_tbs| instead. +OPENSSL_EXPORT int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); + +// i2d_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described in +// |i2d_SAMPLE|. +// +// This function preserves the original encoding of the TBSCertList and may not +// reflect modifications made to |crl|. It may be used to manually verify the +// signature of an existing CRL. To generate CRLs, use |i2d_re_X509_CRL_tbs| +// instead. +OPENSSL_EXPORT int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); + +// X509_CRL_set1_signature_algo sets |crl|'s signature algorithm to |algo| and +// returns one on success or zero on error. It updates both the signature field +// of the TBSCertList structure, and the signatureAlgorithm field of the CRL. +OPENSSL_EXPORT int X509_CRL_set1_signature_algo(X509_CRL *crl, + const X509_ALGOR *algo); + +// X509_CRL_set1_signature_value sets |crl|'s signature to a copy of the +// |sig_len| bytes pointed by |sig|. It returns one on success and zero on +// error. +// +// Due to a specification error, X.509 CRLs store signatures in ASN.1 BIT +// STRINGs, but signature algorithms return byte strings rather than bit +// strings. This function creates a BIT STRING containing a whole number of +// bytes, with the bit order matching the DER encoding. This matches the +// encoding used by all X.509 signature algorithms. +OPENSSL_EXPORT int X509_CRL_set1_signature_value(X509_CRL *crl, + const uint8_t *sig, + size_t sig_len); + +// X509_REVOKED_get0_serialNumber returns the serial number of the certificate +// revoked by |revoked|. +OPENSSL_EXPORT const ASN1_INTEGER *X509_REVOKED_get0_serialNumber( + const X509_REVOKED *revoked); + +// X509_REVOKED_set_serialNumber sets |revoked|'s serial number to |serial|. It +// returns one on success or zero on error. +OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *revoked, + const ASN1_INTEGER *serial); + +// X509_REVOKED_get0_revocationDate returns the revocation time of the +// certificate revoked by |revoked|. +OPENSSL_EXPORT const ASN1_TIME *X509_REVOKED_get0_revocationDate( + const X509_REVOKED *revoked); + +// X509_REVOKED_set_revocationDate sets |revoked|'s revocation time to |tm|. It +// returns one on success or zero on error. +OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, + const ASN1_TIME *tm); + +// X509_REVOKED_get0_extensions returns |r|'s extensions list, or NULL if |r| +// omits it. +OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions( + const X509_REVOKED *r); + +OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, + unsigned int flags); + +OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); +OPENSSL_EXPORT int X509_chain_check_suiteb(int *perror_depth, X509 *x, + STACK_OF(X509) *chain, + unsigned long flags); +OPENSSL_EXPORT int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, + unsigned long flags); + +// X509_chain_up_ref returns a newly-allocated |STACK_OF(X509)| containing a +// shallow copy of |chain|, or NULL on error. That is, the return value has the +// same contents as |chain|, and each |X509|'s reference count is incremented by +// one. +OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +OPENSSL_EXPORT int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); + +OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); + +OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); + +OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); +OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); + +OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); +OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); + +OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +OPENSSL_EXPORT int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +OPENSSL_EXPORT int X509_print_fp(FILE *bp, X509 *x); +OPENSSL_EXPORT int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, + int indent, unsigned long flags); + +OPENSSL_EXPORT int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +OPENSSL_EXPORT int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +OPENSSL_EXPORT int X509_print(BIO *bp, X509 *x); +OPENSSL_EXPORT int X509_ocspid_print(BIO *bp, X509 *x); +OPENSSL_EXPORT int X509_CRL_print(BIO *bp, X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +OPENSSL_EXPORT int X509_REQ_print(BIO *bp, X509_REQ *req); + +OPENSSL_EXPORT int X509_NAME_entry_count(const X509_NAME *name); +OPENSSL_EXPORT int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, + char *buf, int len); +OPENSSL_EXPORT int X509_NAME_get_text_by_OBJ(const X509_NAME *name, + const ASN1_OBJECT *obj, char *buf, + int len); + +// NOTE: you should be passsing -1, not 0 as lastpos. The functions that use +// lastpos, search after that position on. +OPENSSL_EXPORT int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, + int lastpos); +OPENSSL_EXPORT int X509_NAME_get_index_by_OBJ(const X509_NAME *name, + const ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, + int loc); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, + int loc); +OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, + int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len, int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, + int type, + const unsigned char *bytes, + int len, int loc, int set); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt( + X509_NAME_ENTRY **ne, const char *field, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID( + X509_NAME_ENTRY **ne, int nid, int type, const unsigned char *bytes, + int len); +OPENSSL_EXPORT int X509_NAME_add_entry_by_txt(X509_NAME *name, + const char *field, int type, + const unsigned char *bytes, + int len, int loc, int set); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ( + X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, + int len); +OPENSSL_EXPORT ASN1_OBJECT *X509_NAME_ENTRY_get_object( + const X509_NAME_ENTRY *ne); +OPENSSL_EXPORT ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); + +// X509v3_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); + +// X509v3_get_ext_by_NID returns the index of the first extension in |x| with +// type |nid|, or a negative number if not found. If found, callers can use +// |X509v3_get_ext| to look up the extension by index. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching extensions by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); + +// X509v3_get_ext_by_OBJ behaves like |X509v3_get_ext_by_NID| but looks for +// extensions matching |obj|. +OPENSSL_EXPORT int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); + +// X509v3_get_ext_by_critical returns the index of the first extension in |x| +// whose critical bit matches |crit|, or a negative number if no such extension +// was found. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching extensions by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); + +// X509v3_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| +// is out of bounds. +OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, + int loc); + +// X509v3_delete_ext removes the extension in |x| at index |loc| and returns the +// removed extension, or NULL if |loc| was out of bounds. If an extension was +// returned, the caller must release it with |X509_EXTENSION_free|. +OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, + int loc); + +// X509v3_add_ext adds a copy of |ex| to the extension list in |*x|. If |*x| is +// NULL, it allocates a new |STACK_OF(X509_EXTENSION)| to hold the copy and sets +// |*x| to the new list. It returns |*x| on success and NULL on error. The +// caller retains ownership of |ex| and can release it independently of |*x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext( + STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc); + +// X509_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_count(const X509 *x); + +// X509_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); + +// X509_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, + int lastpos); + +// X509_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but +// searches for extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_critical(const X509 *x, int crit, + int lastpos); + +// X509_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| is +// out of bounds. +OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(const X509 *x, int loc); + +// X509_delete_ext removes the extension in |x| at index |loc| and returns the +// removed extension, or NULL if |loc| was out of bounds. If non-NULL, the +// caller must release the result with |X509_EXTENSION_free|. It is also safe, +// but not necessary, to call |X509_EXTENSION_free| if the result is NULL. +OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc); + +// X509_add_ext adds a copy of |ex| to |x|. It returns one on success and zero +// on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); + +// X509_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the extension in +// |x509|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_get_ext_d2i(const X509 *x509, int nid, + int *out_critical, int *out_idx); + +// X509_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension to +// |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +// X509_CRL_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_count(const X509_CRL *x); + +// X509_CRL_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, + int lastpos); + +// X509_CRL_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, + const ASN1_OBJECT *obj, int lastpos); + +// X509_CRL_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but +// searches for extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, + int lastpos); + +// X509_CRL_get_ext returns the extension in |x| at index |loc|, or NULL if +// |loc| is out of bounds. +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); + +// X509_CRL_delete_ext removes the extension in |x| at index |loc| and returns +// the removed extension, or NULL if |loc| was out of bounds. If non-NULL, the +// caller must release the result with |X509_EXTENSION_free|. It is also safe, +// but not necessary, to call |X509_EXTENSION_free| if the result is NULL. +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); + +// X509_CRL_add_ext adds a copy of |ex| to |x|. It returns one on success and +// zero on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); + +// X509_CRL_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the +// extension in |crl|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, + int *out_critical, int *out_idx); + +// X509_CRL_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension +// to |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, + int crit, unsigned long flags); + +// X509_REVOKED_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_count(const X509_REVOKED *x); + +// X509_REVOKED_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches +// for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, + int lastpos); + +// X509_REVOKED_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches +// for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, + const ASN1_OBJECT *obj, + int lastpos); + +// X509_REVOKED_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| +// but searches for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, + int crit, int lastpos); + +// X509_REVOKED_get_ext returns the extension in |x| at index |loc|, or NULL if +// |loc| is out of bounds. +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, + int loc); + +// X509_REVOKED_delete_ext removes the extension in |x| at index |loc| and +// returns the removed extension, or NULL if |loc| was out of bounds. If +// non-NULL, the caller must release the result with |X509_EXTENSION_free|. It +// is also safe, but not necessary, to call |X509_EXTENSION_free| if the result +// is NULL. +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, + int loc); + +// X509_REVOKED_add_ext adds a copy of |ex| to |x|. It returns one on success +// and zero on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, + int loc); + +// X509_REVOKED_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the +// extension in |revoked|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, + int nid, int *out_critical, + int *out_idx); + +// X509_REVOKED_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the +// extension to |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, + void *value, int crit, + unsigned long flags); + +// X509_EXTENSION_create_by_NID creates a new |X509_EXTENSION| with type |nid|, +// value |data|, and critical bit |crit|. It returns the newly-allocated +// |X509_EXTENSION| on success, and false on error. |nid| should be a |NID_*| +// constant. +// +// If |ex| and |*ex| are both non-NULL, it modifies and returns |*ex| instead of +// creating a new object. If |ex| is non-NULL, but |*ex| is NULL, it sets |*ex| +// to the new |X509_EXTENSION|, in addition to returning the result. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID( + X509_EXTENSION **ex, int nid, int crit, const ASN1_OCTET_STRING *data); + +// X509_EXTENSION_create_by_OBJ behaves like |X509_EXTENSION_create_by_NID|, but +// the extension type is determined by an |ASN1_OBJECT|. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ( + X509_EXTENSION **ex, const ASN1_OBJECT *obj, int crit, + const ASN1_OCTET_STRING *data); + +// X509_EXTENSION_set_object sets |ex|'s extension type to |obj|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_EXTENSION_set_object(X509_EXTENSION *ex, + const ASN1_OBJECT *obj); + +// X509_EXTENSION_set_critical sets |ex| to critical if |crit| is non-zero and +// to non-critical if |crit| is zero. +OPENSSL_EXPORT int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); + +// X509_EXTENSION_set_data set's |ex|'s extension value to a copy of |data|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_EXTENSION_set_data(X509_EXTENSION *ex, + const ASN1_OCTET_STRING *data); + +// X509_EXTENSION_get_object returns |ex|'s extension type. +OPENSSL_EXPORT ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); + +// X509_EXTENSION_get_data returns |ne|'s extension value. +OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); + +// X509_EXTENSION_get_critical returns one if |ex| is critical and zero +// otherwise. +OPENSSL_EXPORT int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +// X509at_get_attr_count returns the number of attributes in |x|. +OPENSSL_EXPORT int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); + +// X509at_get_attr_by_NID returns the index of the attribute in |x| of type +// |nid|, or a negative number if not found. If found, callers can use +// |X509at_get_attr| to look up the attribute by index. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching attributes by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, + int nid, int lastpos); + +// X509at_get_attr_by_OBJ behaves like |X509at_get_attr_by_NID| but looks for +// attributes of type |obj|. +OPENSSL_EXPORT int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); + +// X509at_get_attr returns the attribute at index |loc| in |x|, or NULL if +// out of bounds. +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_get_attr( + const STACK_OF(X509_ATTRIBUTE) *x, int loc); + +// X509at_delete_attr removes the attribute at index |loc| in |x|. It returns +// the removed attribute to the caller, or NULL if |loc| was out of bounds. If +// non-NULL, the caller must release the result with |X509_ATTRIBUTE_free| when +// done. It is also safe, but not necessary, to call |X509_ATTRIBUTE_free| if +// the result is NULL. +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, + int loc); + +// X509at_add1_attr appends a copy of |attr| to the attribute list in |*x|. If +// |*x| is NULL, it allocates a new |STACK_OF(X509_ATTRIBUTE)| to hold the copy +// and sets |*x| to the new list. It returns |*x| on success and NULL on error. +// The caller retains ownership of |attr| and can release it independently of +// |*x|. +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr( + STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr); + +// X509at_add1_attr_by_OBJ behaves like |X509at_add1_attr|, but adds an +// attribute created by |X509_ATTRIBUTE_create_by_OBJ|. +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ( + STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); + +// X509at_add1_attr_by_NID behaves like |X509at_add1_attr|, but adds an +// attribute created by |X509_ATTRIBUTE_create_by_NID|. +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID( + STACK_OF(X509_ATTRIBUTE) **x, int nid, int type, const unsigned char *bytes, + int len); + +// X509at_add1_attr_by_txt behaves like |X509at_add1_attr|, but adds an +// attribute created by |X509_ATTRIBUTE_create_by_txt|. +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt( + STACK_OF(X509_ATTRIBUTE) **x, const char *attrname, int type, + const unsigned char *bytes, int len); + +// X509_ATTRIBUTE_create_by_NID returns a newly-allocated |X509_ATTRIBUTE| of +// type |nid|, or NULL on error. The value is determined as in +// |X509_ATTRIBUTE_set1_data|. +// +// If |attr| is non-NULL, the resulting |X509_ATTRIBUTE| is also written to +// |*attr|. If |*attr| was non-NULL when the function was called, |*attr| is +// reused instead of creating a new object. +// +// WARNING: The interpretation of |attrtype|, |data|, and |len| is complex and +// error-prone. See |X509_ATTRIBUTE_set1_data| for details. +// +// WARNING: The object reuse form is deprecated and may be removed in the +// future. It also currently incorrectly appends to the reused object's value +// set rather than overwriting it. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID( + X509_ATTRIBUTE **attr, int nid, int attrtype, const void *data, int len); + +// X509_ATTRIBUTE_create_by_OBJ behaves like |X509_ATTRIBUTE_create_by_NID| +// except the attribute's type is determined by |obj|. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ( + X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj, int attrtype, + const void *data, int len); + +// X509_ATTRIBUTE_create_by_txt behaves like |X509_ATTRIBUTE_create_by_NID| +// except the attribute's type is determined by calling |OBJ_txt2obj| with +// |attrname|. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt( + X509_ATTRIBUTE **attr, const char *attrname, int type, + const unsigned char *bytes, int len); + +// X509_ATTRIBUTE_set1_object sets |attr|'s type to |obj|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, + const ASN1_OBJECT *obj); + +// X509_ATTRIBUTE_set1_data appends a value to |attr|'s value set and returns +// one on success or zero on error. The value is determined as follows: +// +// If |attrtype| is a |MBSTRING_*| constant, the value is an ASN.1 string. The +// string is determined by decoding |len| bytes from |data| in the encoding +// specified by |attrtype|, and then re-encoding it in a form appropriate for +// |attr|'s type. If |len| is -1, |strlen(data)| is used instead. See +// |ASN1_STRING_set_by_NID| for details. +// +// TODO(davidben): Document |ASN1_STRING_set_by_NID| so the reference is useful. +// +// Otherwise, if |len| is not -1, the value is an ASN.1 string. |attrtype| is an +// |ASN1_STRING| type value and the |len| bytes from |data| are copied as the +// type-specific representation of |ASN1_STRING|. See |ASN1_STRING| for details. +// +// WARNING: If this form is used to construct a negative INTEGER or ENUMERATED, +// |attrtype| includes the |V_ASN1_NEG| flag for |ASN1_STRING|, but the function +// forgets to clear the flag for |ASN1_TYPE|. This matches OpenSSL but is +// probably a bug. For now, do not use this form with negative values. +// +// Otherwise, if |len| is -1, the value is constructed by passing |attrtype| and +// |data| to |ASN1_TYPE_set1|. That is, |attrtype| is an |ASN1_TYPE| type value, +// and |data| is cast to the corresponding pointer type. +// +// WARNING: Despite the name, this function appends to |attr|'s value set, +// rather than overwriting it. To overwrite the value set, create a new +// |X509_ATTRIBUTE| with |X509_ATTRIBUTE_new|. +// +// WARNING: If using the |MBSTRING_*| form, pass a length rather than relying on +// |strlen|. In particular, |strlen| will not behave correctly if the input is +// |MBSTRING_BMP| or |MBSTRING_UNIV|. +// +// WARNING: This function currently misinterprets |V_ASN1_OTHER| as an +// |MBSTRING_*| constant. This matches OpenSSL but means it is impossible to +// construct a value with a non-universal tag. +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); + +// X509_ATTRIBUTE_get0_data returns the |idx|th value of |attr| in a +// type-specific representation to |attrtype|, or NULL if out of bounds or the +// type does not match. |attrtype| is one of the type values in |ASN1_TYPE|. On +// match, the return value uses the same representation as |ASN1_TYPE_set0|. See +// |ASN1_TYPE| for details. +OPENSSL_EXPORT void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int attrtype, void *unused); + +// X509_ATTRIBUTE_count returns the number of values in |attr|. +OPENSSL_EXPORT int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); + +// X509_ATTRIBUTE_get0_object returns the type of |attr|. +OPENSSL_EXPORT ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); + +// X509_ATTRIBUTE_get0_type returns the |idx|th value in |attr|, or NULL if out +// of bounds. Note this function returns one of |attr|'s values, not the type. +OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, + int idx); + +OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); + +// lookup a cert from a X509 STACK +OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, + X509_NAME *name, + ASN1_INTEGER *serial); +OPENSSL_EXPORT X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +// PKCS#8 utilities + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); + +OPENSSL_EXPORT int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +OPENSSL_EXPORT int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); + +// X509_PUBKEY_set0_param sets |pub| to a key with AlgorithmIdentifier +// determined by |obj|, |param_type|, and |param_value|, and an encoded +// public key of |key|. On success, it takes ownership of all its parameters and +// returns one. Otherwise, it returns zero. |key| must have been allocated by +// |OPENSSL_malloc|. +// +// |obj|, |param_type|, and |param_value| are interpreted as in +// |X509_ALGOR_set0|. See |X509_ALGOR_set0| for details. +OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, + int param_type, void *param_value, + uint8_t *key, int key_len); + +// X509_PUBKEY_get0_param outputs fields of |pub| and returns one. If |out_obj| +// is not NULL, it sets |*out_obj| to AlgorithmIdentifier's OID. If |out_key| +// is not NULL, it sets |*out_key| and |*out_key_len| to the encoded public key. +// If |out_alg| is not NULL, it sets |*out_alg| to the AlgorithmIdentifier. +// +// Note: X.509 SubjectPublicKeyInfo structures store the encoded public key as a +// BIT STRING. |*out_key| and |*out_key_len| will silently pad the key with zero +// bits if |pub| did not contain a whole number of bytes. Use +// |X509_PUBKEY_get0_public_key| to preserve this information. +OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, + const uint8_t **out_key, + int *out_key_len, + X509_ALGOR **out_alg, + X509_PUBKEY *pub); + +// X509_PUBKEY_get0_public_key returns |pub|'s encoded public key. +OPENSSL_EXPORT const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key( + const X509_PUBKEY *pub); + +OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); +OPENSSL_EXPORT int X509_TRUST_get_count(void); +OPENSSL_EXPORT X509_TRUST *X509_TRUST_get0(int idx); +OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); +OPENSSL_EXPORT int X509_TRUST_add(int id, int flags, + int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +OPENSSL_EXPORT void X509_TRUST_cleanup(void); +OPENSSL_EXPORT int X509_TRUST_get_flags(const X509_TRUST *xp); +OPENSSL_EXPORT char *X509_TRUST_get0_name(const X509_TRUST *xp); +OPENSSL_EXPORT int X509_TRUST_get_trust(const X509_TRUST *xp); + + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + // OpenSSL caches the MGF hash on |RSA_PSS_PARAMS| in some cases. None of the + // cases apply to BoringSSL, so this is always NULL, but Node expects the + // field to be present. + X509_ALGOR *maskHash; +} /* RSA_PSS_PARAMS */; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +/* +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +#define X509_LU_X509 1 +#define X509_LU_CRL 2 +#define X509_LU_PKEY 3 + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_STACK_OF(X509_OBJECT) +DEFINE_STACK_OF(X509_VERIFY_PARAM) + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, X509_STORE_CTX *ctx, + X509 *x); +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, X509 *x, + X509 *issuer); +typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, X509_CRL **crl, + X509 *x); +typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); +typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 *x); +typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); +typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)( + X509_STORE_CTX *ctx, X509_NAME *nm); +typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth); + +OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +#define X509_STORE_CTX_set_app_data(ctx, data) \ + X509_STORE_CTX_set_ex_data(ctx, 0, data) +#define X509_STORE_CTX_get_app_data(ctx) X509_STORE_CTX_get_ex_data(ctx, 0) + +#define X509_L_FILE_LOAD 1 +#define X509_L_ADD_DIR 2 + +#define X509_LOOKUP_load_file(x, name, type) \ + X509_LOOKUP_ctrl((x), X509_L_FILE_LOAD, (name), (long)(type), NULL) + +#define X509_LOOKUP_add_dir(x, name, type) \ + X509_LOOKUP_ctrl((x), X509_L_ADD_DIR, (name), (long)(type), NULL) + +#define X509_V_OK 0 +#define X509_V_ERR_UNSPECIFIED 1 + +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +// These are 'informational' when looking for issuer cert +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +#define X509_V_ERR_UNNESTED_RESOURCE 46 + +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_APPLICATION_VERIFICATION 50 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +// Suite B mode algorithm violation +#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 + +// Host, email and IP check errors +#define X509_V_ERR_HOSTNAME_MISMATCH 62 +#define X509_V_ERR_EMAIL_MISMATCH 63 +#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 + +// Caller error +#define X509_V_ERR_INVALID_CALL 65 +// Issuer lookup error +#define X509_V_ERR_STORE_LOOKUP 66 + +#define X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS 67 + +// Certificate verify flags + +// Send issuer+subject checks to verify_cb +#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +// Use check time instead of current time +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +// Lookup CRLs +#define X509_V_FLAG_CRL_CHECK 0x4 +// Lookup CRLs for whole chain +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +// Ignore unhandled critical extensions +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +// Does nothing as its functionality has been enabled by default. +#define X509_V_FLAG_X509_STRICT 0x00 +// Enable proxy certificate validation +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +// Enable policy checking +#define X509_V_FLAG_POLICY_CHECK 0x80 +// Policy variable require-explicit-policy +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +// Policy variable inhibit-any-policy +#define X509_V_FLAG_INHIBIT_ANY 0x200 +// Policy variable inhibit-policy-mapping +#define X509_V_FLAG_INHIBIT_MAP 0x400 +// Notify callback that policy is OK +#define X509_V_FLAG_NOTIFY_POLICY 0x800 +// Extended CRL features such as indirect CRLs, alternate CRL signing keys +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +// Delta CRL support +#define X509_V_FLAG_USE_DELTAS 0x2000 +// Check selfsigned CA signature +#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +// Use trusted store first +#define X509_V_FLAG_TRUSTED_FIRST 0x8000 +// Suite B 128 bit only mode: not normally used +#define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +// Suite B 192 bit only mode +#define X509_V_FLAG_SUITEB_192_LOS 0x20000 +// Suite B 128 bit mode allowing 192 bit algorithms +#define X509_V_FLAG_SUITEB_128_LOS 0x30000 + +// Allow partial chains if at least one certificate is in trusted store +#define X509_V_FLAG_PARTIAL_CHAIN 0x80000 + +// If the initial chain is not trusted, do not attempt to build an alternative +// chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag +// will force the behaviour to match that of previous versions. +#define X509_V_FLAG_NO_ALT_CHAINS 0x100000 + +#define X509_VP_FLAG_DEFAULT 0x1 +#define X509_VP_FLAG_OVERWRITE 0x2 +#define X509_VP_FLAG_RESET_FLAGS 0x4 +#define X509_VP_FLAG_LOCKED 0x8 +#define X509_VP_FLAG_ONCE 0x10 + +// Internal use: mask of policy related options +#define X509_V_FLAG_POLICY_MASK \ + (X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY | \ + X509_V_FLAG_INHIBIT_ANY | X509_V_FLAG_INHIBIT_MAP) + +OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject( + STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +OPENSSL_EXPORT int X509_OBJECT_up_ref_count(X509_OBJECT *a); +OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a); +OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *a); +OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +OPENSSL_EXPORT X509_STORE *X509_STORE_new(void); +OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); +OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v); + +OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, + X509_NAME *nm); +OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, + X509_NAME *nm); +OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, + X509_VERIFY_PARAM *pm); +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +OPENSSL_EXPORT void X509_STORE_set_verify(X509_STORE *ctx, + X509_STORE_CTX_verify_fn verify); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx), (func)) +OPENSSL_EXPORT void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_fn verify); +OPENSSL_EXPORT X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_verify_cb( + X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb); +#define X509_STORE_set_verify_cb_func(ctx, func) \ + X509_STORE_set_verify_cb((ctx), (func)) +OPENSSL_EXPORT X509_STORE_CTX_verify_cb +X509_STORE_get_verify_cb(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_get_issuer( + X509_STORE *ctx, X509_STORE_CTX_get_issuer_fn get_issuer); +OPENSSL_EXPORT X509_STORE_CTX_get_issuer_fn +X509_STORE_get_get_issuer(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_check_issued( + X509_STORE *ctx, X509_STORE_CTX_check_issued_fn check_issued); +OPENSSL_EXPORT X509_STORE_CTX_check_issued_fn +X509_STORE_get_check_issued(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_check_revocation( + X509_STORE *ctx, X509_STORE_CTX_check_revocation_fn check_revocation); +OPENSSL_EXPORT X509_STORE_CTX_check_revocation_fn +X509_STORE_get_check_revocation(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl); +OPENSSL_EXPORT X509_STORE_CTX_get_crl_fn +X509_STORE_get_get_crl(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_check_crl( + X509_STORE *ctx, X509_STORE_CTX_check_crl_fn check_crl); +OPENSSL_EXPORT X509_STORE_CTX_check_crl_fn +X509_STORE_get_check_crl(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_cert_crl( + X509_STORE *ctx, X509_STORE_CTX_cert_crl_fn cert_crl); +OPENSSL_EXPORT X509_STORE_CTX_cert_crl_fn +X509_STORE_get_cert_crl(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_lookup_certs( + X509_STORE *ctx, X509_STORE_CTX_lookup_certs_fn lookup_certs); +OPENSSL_EXPORT X509_STORE_CTX_lookup_certs_fn +X509_STORE_get_lookup_certs(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_lookup_crls( + X509_STORE *ctx, X509_STORE_CTX_lookup_crls_fn lookup_crls); +#define X509_STORE_set_lookup_crls_cb(ctx, func) \ + X509_STORE_set_lookup_crls((ctx), (func)) +OPENSSL_EXPORT X509_STORE_CTX_lookup_crls_fn +X509_STORE_get_lookup_crls(X509_STORE *ctx); +OPENSSL_EXPORT void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn cleanup); +OPENSSL_EXPORT X509_STORE_CTX_cleanup_fn +X509_STORE_get_cleanup(X509_STORE *ctx); + +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); + +OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, + X509_STORE_CTX *ctx, X509 *x); + +OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, + STACK_OF(X509) *sk); +OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, + X509_LOOKUP_METHOD *m); + +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +OPENSSL_EXPORT int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, + X509_NAME *name, X509_OBJECT *ret); + +OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, + int type); +OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, + int type); +OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, + int type); +#endif + +OPENSSL_EXPORT X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, + X509_NAME *name, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, + X509_NAME *name, + ASN1_INTEGER *serial, + X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *dir); +OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); +#endif + +OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, + void *data); +OPENSSL_EXPORT void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx( + X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +OPENSSL_EXPORT void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, + STACK_OF(X509) *sk); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted( + X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, + STACK_OF(X509_CRL) *sk); +OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, + int def_purpose, int purpose, + int trust); +OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, + unsigned long flags); +OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, + unsigned long flags, time_t t); +OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( + X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)); + +OPENSSL_EXPORT X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree( + X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( + X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, + X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, + const char *name); + +// X509_VERIFY_PARAM functions + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, + const char *name); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags( + X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, + int purpose); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, + int trust); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, + int depth); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, + time_t t); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( + X509_VERIFY_PARAM *param, STACK_OF(ASN1_OBJECT) *policies); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t namelen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t namelen); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +OPENSSL_EXPORT char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, + size_t emaillen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, + size_t iplen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name( + const X509_VERIFY_PARAM *param); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup( + const char *name); +OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void); + +OPENSSL_EXPORT int X509_policy_check(X509_POLICY_TREE **ptree, + int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +OPENSSL_EXPORT void X509_policy_tree_free(X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +OPENSSL_EXPORT X509_POLICY_LEVEL *X509_policy_tree_get0_level( + const X509_POLICY_TREE *tree, int i); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies( + const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies( + const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +OPENSSL_EXPORT X509_POLICY_NODE *X509_policy_level_get0_node( + X509_POLICY_LEVEL *level, int i); + +OPENSSL_EXPORT const ASN1_OBJECT *X509_policy_node_get0_policy( + const X509_POLICY_NODE *node); + +OPENSSL_EXPORT STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers( + const X509_POLICY_NODE *node); +OPENSSL_EXPORT const X509_POLICY_NODE *X509_policy_node_get0_parent( + const X509_POLICY_NODE *node); + + +#if defined(__cplusplus) +} // extern C +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(NETSCAPE_SPKI, NETSCAPE_SPKI_free) +BORINGSSL_MAKE_DELETER(RSA_PSS_PARAMS, RSA_PSS_PARAMS_free) +BORINGSSL_MAKE_DELETER(X509, X509_free) +BORINGSSL_MAKE_UP_REF(X509, X509_up_ref) +BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free) +BORINGSSL_MAKE_DELETER(X509_ATTRIBUTE, X509_ATTRIBUTE_free) +BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) +BORINGSSL_MAKE_UP_REF(X509_CRL, X509_CRL_up_ref) +BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free) +BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) +BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) +BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) +BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) +BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) +BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free) +BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free) +BORINGSSL_MAKE_DELETER(X509_PUBKEY, X509_PUBKEY_free) +BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free) +BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free) +BORINGSSL_MAKE_DELETER(X509_SIG, X509_SIG_free) +BORINGSSL_MAKE_DELETER(X509_STORE, X509_STORE_free) +BORINGSSL_MAKE_UP_REF(X509_STORE, X509_STORE_up_ref) +BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free) +BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif // !BORINGSSL_NO_CXX + +#define X509_R_AKID_MISMATCH 100 +#define X509_R_BAD_PKCS7_VERSION 101 +#define X509_R_BAD_X509_FILETYPE 102 +#define X509_R_BASE64_DECODE_ERROR 103 +#define X509_R_CANT_CHECK_DH_KEY 104 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 105 +#define X509_R_CRL_ALREADY_DELTA 106 +#define X509_R_CRL_VERIFY_FAILURE 107 +#define X509_R_IDP_MISMATCH 108 +#define X509_R_INVALID_BIT_STRING_BITS_LEFT 109 +#define X509_R_INVALID_DIRECTORY 110 +#define X509_R_INVALID_FIELD_NAME 111 +#define X509_R_INVALID_PSS_PARAMETERS 112 +#define X509_R_INVALID_TRUST 113 +#define X509_R_ISSUER_MISMATCH 114 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 117 +#define X509_R_LOADING_DEFAULTS 118 +#define X509_R_NEWER_CRL_NOT_NEWER 119 +#define X509_R_NOT_PKCS7_SIGNED_DATA 120 +#define X509_R_NO_CERTIFICATES_INCLUDED 121 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 122 +#define X509_R_NO_CRLS_INCLUDED 123 +#define X509_R_NO_CRL_NUMBER 124 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 127 +#define X509_R_UNKNOWN_KEY_TYPE 128 +#define X509_R_UNKNOWN_NID 129 +#define X509_R_UNKNOWN_PURPOSE_ID 130 +#define X509_R_UNKNOWN_TRUST_ID 131 +#define X509_R_UNSUPPORTED_ALGORITHM 132 +#define X509_R_WRONG_LOOKUP_TYPE 133 +#define X509_R_WRONG_TYPE 134 +#define X509_R_NAME_TOO_LONG 135 +#define X509_R_INVALID_PARAMETER 136 +#define X509_R_SIGNATURE_ALGORITHM_MISMATCH 137 +#define X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER 138 +#define X509_R_INVALID_FIELD_FOR_VERSION 139 +#define X509_R_INVALID_VERSION 140 +#define X509_R_NO_CERTIFICATE_FOUND 141 +#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 142 +#define X509_R_NO_CRL_FOUND 143 + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509_vfy.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509_vfy.h new file mode 100644 index 00000000..20dcdfb2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509_vfy.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "CNIOBoringSSL_x509.h" diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h new file mode 100644 index 00000000..23c0c2cd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h @@ -0,0 +1,1018 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef HEADER_X509V3_H +#define HEADER_X509V3_H + +#include "CNIOBoringSSL_bio.h" +#include "CNIOBoringSSL_conf.h" +#include "CNIOBoringSSL_lhash.h" +#include "CNIOBoringSSL_x509.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Legacy X.509 library. +// +// This header is part of OpenSSL's X.509 implementation. It is retained for +// compatibility but otherwise underdocumented and not actively maintained. In +// the future, a replacement library will be available. Meanwhile, minimize +// dependencies on this header where possible. + + +// Forward reference +struct v3_ext_method; +struct v3_ext_ctx; + +// Useful typedefs + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE)(void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)( + const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +// V3 extension structure + +struct v3_ext_method { + int ext_nid; + int ext_flags; + // If this is set the following four fields are ignored + ASN1_ITEM_EXP *it; + // Old style ASN1 calls + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; + + // The following pair is used for string extensions + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; + + // The following pair is used for multi-valued extensions + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; + + // The following are used for raw extensions + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + + void *usr_data; // Any extension specific data +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string)(void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section)(void *db, const char *section); + void (*free_string)(void *db, char *string); + void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +// Context specific info +struct v3_ext_ctx { +#define CTX_TEST 0x1 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + const X509V3_CONF_METHOD *db_meth; + void *db; + // Maybe more here +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_STACK_OF(X509V3_EXT_METHOD) + +// ext_flags values +#define X509V3_EXT_DYNAMIC 0x1 +#define X509V3_EXT_CTX_DEP 0x2 +#define X509V3_EXT_MULTILINE 0x4 + +struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +}; + + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +#define GEN_OTHERNAME 0 +#define GEN_EMAIL 1 +#define GEN_DNS 2 +#define GEN_X400 3 +#define GEN_DIRNAME 4 +#define GEN_EDIPARTY 5 +#define GEN_URI 6 +#define GEN_IPADD 7 +#define GEN_RID 8 + + int type; + union { + char *ptr; + OTHERNAME *otherName; // otherName + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + + // Old names + ASN1_OCTET_STRING *ip; // iPAddress + X509_NAME *dirn; // dirn + ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier + ASN1_OBJECT *rid; // registeredID + ASN1_TYPE *other; // x400Address + } d; +} GENERAL_NAME; + +DEFINE_STACK_OF(GENERAL_NAME) + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +DEFINE_STACK_OF(GENERAL_NAMES) + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; + // If relativename then this contains the full distribution point name + X509_NAME *dpname; +} DIST_POINT_NAME; +// All existing reasons +#define CRLDP_ALL_REASONS 0x807f + +#define CRL_REASON_NONE (-1) +#define CRL_REASON_UNSPECIFIED 0 +#define CRL_REASON_KEY_COMPROMISE 1 +#define CRL_REASON_CA_COMPROMISE 2 +#define CRL_REASON_AFFILIATION_CHANGED 3 +#define CRL_REASON_SUPERSEDED 4 +#define CRL_REASON_CESSATION_OF_OPERATION 5 +#define CRL_REASON_CERTIFICATE_HOLD 6 +#define CRL_REASON_REMOVE_FROM_CRL 8 +#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DEFINE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DEFINE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DEFINE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DEFINE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +// Proxy certificate structures, see RFC 3820 +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +// Values in idp_flags field +// IDP present +#define IDP_PRESENT 0x1 +// IDP values inconsistent +#define IDP_INVALID 0x2 +// onlyuser true +#define IDP_ONLYUSER 0x4 +// onlyCA true +#define IDP_ONLYCA 0x8 +// onlyattr true +#define IDP_ONLYATTR 0x10 +// indirectCRL true +#define IDP_INDIRECT 0x20 +// onlysomereasons present +#define IDP_REASONS 0x40 + +#define X509V3_conf_err(val) \ + ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ + ",value:", (val)->value); + +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +#define EXT_BITSTRING(nid, table) \ + { \ + nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), 0, 0, 0, 0, 0, 0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, NULL, NULL, (void *)(table) \ + } + +#define EXT_IA5STRING(nid) \ + { \ + nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), 0, 0, 0, 0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, 0, 0, 0, 0, NULL \ + } + +#define EXT_END \ + { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + + +// X509_PURPOSE stuff + +#define EXFLAG_BCONS 0x1 +#define EXFLAG_KUSAGE 0x2 +#define EXFLAG_XKUSAGE 0x4 +#define EXFLAG_NSCERT 0x8 + +#define EXFLAG_CA 0x10 +// Really self issued not necessarily self signed +#define EXFLAG_SI 0x20 +#define EXFLAG_V1 0x40 +#define EXFLAG_INVALID 0x80 +#define EXFLAG_SET 0x100 +#define EXFLAG_CRITICAL 0x200 +#define EXFLAG_PROXY 0x400 + +#define EXFLAG_INVALID_POLICY 0x800 +#define EXFLAG_FRESHEST 0x1000 +// Self signed +#define EXFLAG_SS 0x2000 + +#define KU_DIGITAL_SIGNATURE 0x0080 +#define KU_NON_REPUDIATION 0x0040 +#define KU_KEY_ENCIPHERMENT 0x0020 +#define KU_DATA_ENCIPHERMENT 0x0010 +#define KU_KEY_AGREEMENT 0x0008 +#define KU_KEY_CERT_SIGN 0x0004 +#define KU_CRL_SIGN 0x0002 +#define KU_ENCIPHER_ONLY 0x0001 +#define KU_DECIPHER_ONLY 0x8000 + +#define NS_SSL_CLIENT 0x80 +#define NS_SSL_SERVER 0x40 +#define NS_SMIME 0x20 +#define NS_OBJSIGN 0x10 +#define NS_SSL_CA 0x04 +#define NS_SMIME_CA 0x02 +#define NS_OBJSIGN_CA 0x01 +#define NS_ANY_CA (NS_SSL_CA | NS_SMIME_CA | NS_OBJSIGN_CA) + +#define XKU_SSL_SERVER 0x1 +#define XKU_SSL_CLIENT 0x2 +#define XKU_SMIME 0x4 +#define XKU_CODE_SIGN 0x8 +#define XKU_SGC 0x10 +#define XKU_OCSP_SIGN 0x20 +#define XKU_TIMESTAMP 0x40 +#define XKU_DVCS 0x80 +#define XKU_ANYEKU 0x100 + +#define X509_PURPOSE_DYNAMIC 0x1 +#define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; // Default trust ID + int flags; + int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +#define X509_PURPOSE_SSL_CLIENT 1 +#define X509_PURPOSE_SSL_SERVER 2 +#define X509_PURPOSE_NS_SSL_SERVER 3 +#define X509_PURPOSE_SMIME_SIGN 4 +#define X509_PURPOSE_SMIME_ENCRYPT 5 +#define X509_PURPOSE_CRL_SIGN 6 +#define X509_PURPOSE_ANY 7 +#define X509_PURPOSE_OCSP_HELPER 8 +#define X509_PURPOSE_TIMESTAMP_SIGN 9 + +#define X509_PURPOSE_MIN 1 +#define X509_PURPOSE_MAX 9 + +DEFINE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); + +// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero +// value otherwise. Note this function does not provide a comparison suitable +// for sorting. +OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, + const GENERAL_NAME *b); + + + +OPENSSL_EXPORT ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING( + X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +// i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it +// appends the value to |ret| and returns |ret| on success or NULL on error. If +// it returns NULL, the caller is still responsible for freeing |ret|. If |ret| +// is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| containing the +// result. |method| is ignored. +// +// Do not use this function. This is an internal implementation detail of the +// human-readable print functions. If extracting a SAN list from a certificate, +// look at |gen| directly. +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME( + X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +// i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is +// non-NULL, it appends the values to |ret| and returns |ret| on success or NULL +// on error. If it returns NULL, the caller is still responsible for freeing +// |ret|. If |ret| is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the results. |method| is ignored. +// +// Do not use this function. This is an internal implementation detail of the +// human-readable print functions. If extracting a SAN list from a certificate, +// look at |gen| directly. +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES( + X509V3_EXT_METHOD *method, GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, + void *value); +OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, + ASN1_TYPE *value); +OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, + ASN1_TYPE **pvalue); + +OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( + X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, + X509_NAME *iname); + +OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex( + GENERAL_NAME *out, const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf, int is_nc); +OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); + +// X509V3_EXT_conf_nid contains the only exposed instance of an LHASH in our +// public headers. The |conf| pointer must be NULL but cryptography.io wraps +// this function so we cannot, yet, replace the type with a dummy struct. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + const char *value); + +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, + int ext_nid, + const char *value); +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, + const char *name, + const char *value); +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, + const char *section, + STACK_OF(X509_EXTENSION) **sk); +OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +OPENSSL_EXPORT int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_get_value_bool(const CONF_VALUE *value, + int *asn1_bool); +OPENSSL_EXPORT int X509V3_get_value_int(const CONF_VALUE *value, + ASN1_INTEGER **aint); +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); + +OPENSSL_EXPORT char *X509V3_get_string(X509V3_CTX *ctx, const char *name, + const char *section); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, + const char *section); +OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str); +OPENSSL_EXPORT void X509V3_section_free(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *section); +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to +// |*extlist|. It returns one on success and zero on error. If |*extlist| is +// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the result. Either |name| or |value| may be NULL to omit the +// field. +// +// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the +// function returns. +OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_uchar behaves like |X509V3_add_value| but takes an +// |unsigned char| pointer. +OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, + const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value +// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. +OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string +// representation of |aint|. Note this string representation may be decimal or +// hexadecimal, depending on the size of |aint|. +OPENSSL_EXPORT int X509V3_add_value_int(const char *name, + const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); + +OPENSSL_EXPORT char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, + const ASN1_INTEGER *aint); +OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, + const char *value); +OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +OPENSSL_EXPORT int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +OPENSSL_EXPORT int X509V3_EXT_add_alias(int nid_to, int nid_from); +OPENSSL_EXPORT void X509V3_EXT_cleanup(void); + +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get( + const X509_EXTENSION *ext); +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +OPENSSL_EXPORT int X509V3_add_standard_extensions(void); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); + +// X509V3_EXT_d2i decodes |ext| and returns a pointer to a newly-allocated +// structure, with type dependent on the type of the extension. It returns NULL +// if |ext| is an unsupported extension or if there was a syntax error in the +// extension. The caller should cast the return value to the expected type and +// free the structure when done. +// +// WARNING: Casting the return value to the wrong type is a potentially +// exploitable memory error, so callers must not use this function before +// checking |ext| is of a known type. +OPENSSL_EXPORT void *X509V3_EXT_d2i(const X509_EXTENSION *ext); + +// X509V3_get_d2i finds and decodes the extension in |extensions| of type |nid|. +// If found, it decodes it and returns a newly-allocated structure, with type +// dependent on |nid|. If the extension is not found or on error, it returns +// NULL. The caller may distinguish these cases using the |out_critical| value. +// +// If |out_critical| is not NULL, this function sets |*out_critical| to one if +// the extension is found and critical, zero if it is found and not critical, -1 +// if it is not found, and -2 if there is an invalid duplicate extension. Note +// this function may set |*out_critical| to one or zero and still return NULL if +// the extension is found but has a syntax error. +// +// If |out_idx| is not NULL, this function looks for the first occurrence of the +// extension after |*out_idx|. It then sets |*out_idx| to the index of the +// extension, or -1 if not found. If |out_idx| is non-NULL, duplicate extensions +// are not treated as an error. Callers, however, should not rely on this +// behavior as it may be removed in the future. Duplicate extensions are +// forbidden in RFC 5280. +// +// WARNING: This function is difficult to use correctly. Callers should pass a +// non-NULL |out_critical| and check both the return value and |*out_critical| +// to handle errors. If the return value is NULL and |*out_critical| is not -1, +// there was an error. Otherwise, the function succeeded and but may return NULL +// for a missing extension. Callers should pass NULL to |out_idx| so that +// duplicate extensions are handled correctly. +// +// Additionally, casting the return value to the wrong type is a potentially +// exploitable memory error, so callers must ensure the cast and |nid| match. +OPENSSL_EXPORT void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *extensions, + int nid, int *out_critical, int *out_idx); + +// X509V3_EXT_free casts |ext_data| into the type that corresponds to |nid| and +// releases memory associated with it. It returns one on success and zero if +// |nid| is not a known extension. +// +// WARNING: Casting |ext_data| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |ext_data|'s type matches |nid|. +// +// TODO(davidben): OpenSSL upstream no longer exposes this function. Remove it? +OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data); + +// X509V3_EXT_i2d casts |ext_struc| into the type that corresponds to +// |ext_nid|, serializes it, and returns a newly-allocated |X509_EXTENSION| +// object containing the serialization, or NULL on error. The |X509_EXTENSION| +// has OID |ext_nid| and is critical if |crit| is one. +// +// WARNING: Casting |ext_struc| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |ext_struct|'s type matches |ext_nid|. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, + void *ext_struc); + +// The following constants control the behavior of |X509V3_add1_i2d| and related +// functions. + +// X509V3_ADD_OP_MASK can be ANDed with the flags to determine how duplicate +// extensions are processed. +#define X509V3_ADD_OP_MASK 0xfL + +// X509V3_ADD_DEFAULT causes the function to fail if the extension was already +// present. +#define X509V3_ADD_DEFAULT 0L + +// X509V3_ADD_APPEND causes the function to unconditionally appended the new +// extension to to the extensions list, even if there is a duplicate. +#define X509V3_ADD_APPEND 1L + +// X509V3_ADD_REPLACE causes the function to replace the existing extension, or +// append if it is not present. +#define X509V3_ADD_REPLACE 2L + +// X509V3_ADD_REPLACE causes the function to replace the existing extension and +// fail if it is not present. +#define X509V3_ADD_REPLACE_EXISTING 3L + +// X509V3_ADD_KEEP_EXISTING causes the function to succeed without replacing the +// extension if already present. +#define X509V3_ADD_KEEP_EXISTING 4L + +// X509V3_ADD_DELETE causes the function to remove the matching extension. No +// new extension is added. If there is no matching extension, the function +// fails. The |value| parameter is ignored in this mode. +#define X509V3_ADD_DELETE 5L + +// X509V3_ADD_SILENT may be ORed into one of the values above to indicate the +// function should not add to the error queue on duplicate or missing extension. +// The function will continue to return zero in those cases, and it will +// continue to return -1 and add to the error queue on other errors. +#define X509V3_ADD_SILENT 0x10 + +// X509V3_add1_i2d casts |value| to the type that corresponds to |nid|, +// serializes it, and appends it to the extension list in |*x|. If |*x| is NULL, +// it will set |*x| to a newly-allocated |STACK_OF(X509_EXTENSION)| as needed. +// The |crit| parameter determines whether the new extension is critical. +// |flags| may be some combination of the |X509V3_ADD_*| constants to control +// the function's behavior on duplicate extension. +// +// This function returns one on success, zero if the operation failed due to a +// missing or duplicate extension, and -1 on other errors. +// +// WARNING: Casting |value| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |value|'s type matches |nid|. +OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, + void *value, int crit, unsigned long flags); + +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) + +// X509V3_EXT_DEFAULT causes unknown extensions or syntax errors to return +// failure. +#define X509V3_EXT_DEFAULT 0 +// X509V3_EXT_ERROR_UNKNOWN causes unknown extensions or syntax errors to print +// as "" or "", respectively. +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +// X509V3_EXT_PARSE_UNKNOWN is deprecated and behaves like +// |X509V3_EXT_DUMP_UNKNOWN|. +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +// X509V3_EXT_DUMP_UNKNOWN causes unknown extensions to be displayed as a +// hexdump. +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, + int indent, int ml); +OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent); +OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, + int indent); + +// X509V3_extensions_print prints |title|, followed by a human-readable +// representation of |exts| to |out|. It returns one on success and zero on +// error. The output is indented by |indent| spaces. |flag| is one of the +// |X509V3_EXT_*| constants and controls printing of unknown extensions and +// syntax errors. +OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +OPENSSL_EXPORT int X509_check_ca(X509 *x); +OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); +OPENSSL_EXPORT int X509_supported_extension(X509_EXTENSION *ex); +OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); +OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); +OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); + +OPENSSL_EXPORT uint32_t X509_get_extension_flags(X509 *x); +OPENSSL_EXPORT uint32_t X509_get_key_usage(X509 *x); +OPENSSL_EXPORT uint32_t X509_get_extended_key_usage(X509 *x); + +// X509_get0_subject_key_id returns |x509|'s subject key identifier, if present. +// (See RFC 5280, section 4.2.1.2.) It returns NULL if the extension is not +// present or if some extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509); + +// X509_get0_authority_key_id returns keyIdentifier of |x509|'s authority key +// identifier, if the extension and field are present. (See RFC 5280, +// section 4.2.1.1.) It returns NULL if the extension is not present, if it is +// present but lacks a keyIdentifier field, or if some extension in |x509| was +// invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509); + +// X509_get0_authority_issuer returns the authorityCertIssuer of |x509|'s +// authority key identifier, if the extension and field are present. (See +// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, +// if it is present but lacks a authorityCertIssuer field, or if some extension +// in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509); + +// X509_get0_authority_serial returns the authorityCertSerialNumber of |x509|'s +// authority key identifier, if the extension and field are present. (See +// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, +// if it is present but lacks a authorityCertSerialNumber field, or if some +// extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509); + +OPENSSL_EXPORT int X509_PURPOSE_get_count(void); +OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx); +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(char *sname); +OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); +OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, + const X509 *, int), + char *name, char *sname, void *arg); +OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +OPENSSL_EXPORT void X509_PURPOSE_cleanup(void); +OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *); + +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +// Flags for X509_check_* functions + +// Deprecated: this flag does nothing +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 +// Disable wildcard matching for dnsName fields and common name. +#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +// X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS does nothing, but is necessary in +// OpenSSL to enable standard wildcard matching. In BoringSSL, this behavior is +// always enabled. +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 +// Deprecated: this flag does nothing +#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0 +// Deprecated: this flag does nothing +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0 +// Skip the subject common name fallback if subjectAltNames is missing. +#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 + +OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +OPENSSL_EXPORT int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, + size_t chklen, unsigned int flags); +OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, + unsigned int flags); + +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, + STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, + int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +// BEGIN ERROR CODES +// The following lines are auto generated by the script mkerr.pl. Any changes +// made after this point may be overwritten when the script is next run. + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(ACCESS_DESCRIPTION, ACCESS_DESCRIPTION_free) +BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free) +BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free) +// TODO(davidben): Move this to conf.h and rename to CONF_VALUE_free. +BORINGSSL_MAKE_DELETER(CONF_VALUE, X509V3_conf_free) +BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free) +BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free) +BORINGSSL_MAKE_DELETER(GENERAL_SUBTREE, GENERAL_SUBTREE_free) +BORINGSSL_MAKE_DELETER(NAME_CONSTRAINTS, NAME_CONSTRAINTS_free) +BORINGSSL_MAKE_DELETER(POLICY_MAPPING, POLICY_MAPPING_free) +BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free) + +BSSL_NAMESPACE_END + +} // extern C++ +#endif + +#define X509V3_R_BAD_IP_ADDRESS 100 +#define X509V3_R_BAD_OBJECT 101 +#define X509V3_R_BN_DEC2BN_ERROR 102 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 103 +#define X509V3_R_CANNOT_FIND_FREE_FUNCTION 104 +#define X509V3_R_DIRNAME_ERROR 105 +#define X509V3_R_DISTPOINT_ALREADY_SET 106 +#define X509V3_R_DUPLICATE_ZONE_ID 107 +#define X509V3_R_ERROR_CONVERTING_ZONE 108 +#define X509V3_R_ERROR_CREATING_EXTENSION 109 +#define X509V3_R_ERROR_IN_EXTENSION 110 +#define X509V3_R_EXPECTED_A_SECTION_NAME 111 +#define X509V3_R_EXTENSION_EXISTS 112 +#define X509V3_R_EXTENSION_NAME_ERROR 113 +#define X509V3_R_EXTENSION_NOT_FOUND 114 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 115 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 117 +#define X509V3_R_ILLEGAL_HEX_DIGIT 118 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 119 +#define X509V3_R_INVALID_BOOLEAN_STRING 120 +#define X509V3_R_INVALID_EXTENSION_STRING 121 +#define X509V3_R_INVALID_MULTIPLE_RDNS 122 +#define X509V3_R_INVALID_NAME 123 +#define X509V3_R_INVALID_NULL_ARGUMENT 124 +#define X509V3_R_INVALID_NULL_NAME 125 +#define X509V3_R_INVALID_NULL_VALUE 126 +#define X509V3_R_INVALID_NUMBER 127 +#define X509V3_R_INVALID_NUMBERS 128 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 129 +#define X509V3_R_INVALID_OPTION 130 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 131 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 132 +#define X509V3_R_INVALID_PURPOSE 133 +#define X509V3_R_INVALID_SECTION 134 +#define X509V3_R_INVALID_SYNTAX 135 +#define X509V3_R_ISSUER_DECODE_ERROR 136 +#define X509V3_R_MISSING_VALUE 137 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 138 +#define X509V3_R_NO_CONFIG_DATABASE 139 +#define X509V3_R_NO_ISSUER_CERTIFICATE 140 +#define X509V3_R_NO_ISSUER_DETAILS 141 +#define X509V3_R_NO_POLICY_IDENTIFIER 142 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 143 +#define X509V3_R_NO_PUBLIC_KEY 144 +#define X509V3_R_NO_SUBJECT_DETAILS 145 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 146 +#define X509V3_R_OPERATION_NOT_DEFINED 147 +#define X509V3_R_OTHERNAME_ERROR 148 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 149 +#define X509V3_R_POLICY_PATH_LENGTH 150 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 151 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 152 +#define X509V3_R_SECTION_NOT_FOUND 153 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 154 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 155 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 156 +#define X509V3_R_UNKNOWN_EXTENSION 157 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 158 +#define X509V3_R_UNKNOWN_OPTION 159 +#define X509V3_R_UNSUPPORTED_OPTION 160 +#define X509V3_R_UNSUPPORTED_TYPE 161 +#define X509V3_R_USER_TOO_LONG 162 +#define X509V3_R_INVALID_VALUE 163 +#define X509V3_R_TRAILING_DATA_IN_EXTENSION 164 + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/bio_ssl.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/bio_ssl.cc new file mode 100644 index 00000000..9c26b15c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/bio_ssl.cc @@ -0,0 +1,192 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include + + +static SSL *get_ssl(BIO *bio) { + return reinterpret_cast(bio->ptr); +} + +static int ssl_read(BIO *bio, char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(bio); + BIO_set_retry_reason(bio, BIO_RR_ACCEPT); + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + BIO_set_retry_reason(bio, BIO_RR_CONNECT); + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + return ret; +} + +static int ssl_write(BIO *bio, const char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + BIO_set_retry_reason(bio, BIO_RR_CONNECT); + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + return ret; +} + +static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL && cmd != BIO_C_SET_SSL) { + return 0; + } + + switch (cmd) { + case BIO_C_SET_SSL: + if (ssl != NULL) { + // OpenSSL allows reusing an SSL BIO with a different SSL object. We do + // not support this. + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // Note this differs from upstream OpenSSL, which synchronizes + // |bio->next_bio| with |ssl|'s rbio here, and on |BIO_CTRL_PUSH|. We call + // into the corresponding |BIO| directly. (We can implement the upstream + // behavior if it ends up necessary.) + bio->shutdown = num; + bio->ptr = ptr; + bio->init = 1; + return 1; + + case BIO_CTRL_GET_CLOSE: + return bio->shutdown; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = num; + return 1; + + case BIO_CTRL_WPENDING: + return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); + + case BIO_CTRL_PENDING: + return SSL_pending(ssl); + + case BIO_CTRL_FLUSH: { + BIO *wbio = SSL_get_wbio(ssl); + BIO_clear_retry_flags(bio); + long ret = BIO_ctrl(wbio, cmd, num, ptr); + BIO_set_flags(bio, BIO_get_retry_flags(wbio)); + BIO_set_retry_reason(bio, BIO_get_retry_reason(wbio)); + return ret; + } + + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + case BIO_CTRL_DUP: + return -1; + + default: + return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr); + } +} + +static int ssl_new(BIO *bio) { + return 1; +} + +static int ssl_free(BIO *bio) { + SSL *ssl = get_ssl(bio); + + if (ssl == NULL) { + return 1; + } + + SSL_shutdown(ssl); + if (bio->shutdown) { + SSL_free(ssl); + } + + return 1; +} + +static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + return -1; + + default: + return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp); + } +} + +static const BIO_METHOD ssl_method = { + BIO_TYPE_SSL, "SSL", ssl_write, ssl_read, NULL, + NULL, ssl_ctrl, ssl_new, ssl_free, ssl_callback_ctrl, +}; + +const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; } + +long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) { + return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_both.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_both.cc new file mode 100644 index 00000000..cdd15bea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_both.cc @@ -0,0 +1,835 @@ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable +// for these values? Notably, why is kMinMTU a function of the transport +// protocol's overhead rather than, say, what's needed to hold a minimally-sized +// handshake fragment plus protocol overhead. + +// kMinMTU is the minimum acceptable MTU value. +static const unsigned int kMinMTU = 256 - 28; + +// kDefaultMTU is the default MTU value to use if neither the user nor +// the underlying BIO supplies one. +static const unsigned int kDefaultMTU = 1500 - 28; + + +// Receiving handshake messages. + +hm_fragment::~hm_fragment() { + OPENSSL_free(data); + OPENSSL_free(reassembly); +} + +static UniquePtr dtls1_hm_fragment_new( + const struct hm_header_st *msg_hdr) { + ScopedCBB cbb; + UniquePtr frag = MakeUnique(); + if (!frag) { + return nullptr; + } + frag->type = msg_hdr->type; + frag->seq = msg_hdr->seq; + frag->msg_len = msg_hdr->msg_len; + + // Allocate space for the reassembled message and fill in the header. + frag->data = + (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len); + if (frag->data == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (!CBB_init_fixed(cbb.get(), frag->data, DTLS1_HM_HEADER_LENGTH) || + !CBB_add_u8(cbb.get(), msg_hdr->type) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_add_u16(cbb.get(), msg_hdr->seq) || + !CBB_add_u24(cbb.get(), 0 /* frag_off */) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_finish(cbb.get(), NULL, NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + // If the handshake message is empty, |frag->reassembly| is NULL. + if (msg_hdr->msg_len > 0) { + // Initialize reassembly bitmask. + if (msg_hdr->msg_len + 7 < msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return nullptr; + } + size_t bitmask_len = (msg_hdr->msg_len + 7) / 8; + frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len); + if (frag->reassembly == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + OPENSSL_memset(frag->reassembly, 0, bitmask_len); + } + + return frag; +} + +// bit_range returns a |uint8_t| with bits |start|, inclusive, to |end|, +// exclusive, set. +static uint8_t bit_range(size_t start, size_t end) { + return (uint8_t)(~((1u << start) - 1) & ((1u << end) - 1)); +} + +// dtls1_hm_fragment_mark marks bytes |start|, inclusive, to |end|, exclusive, +// as received in |frag|. If |frag| becomes complete, it clears +// |frag->reassembly|. The range must be within the bounds of |frag|'s message +// and |frag->reassembly| must not be NULL. +static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start, + size_t end) { + size_t msg_len = frag->msg_len; + + if (frag->reassembly == NULL || start > end || end > msg_len) { + assert(0); + return; + } + // A zero-length message will never have a pending reassembly. + assert(msg_len > 0); + + if (start == end) { + return; + } + + if ((start >> 3) == (end >> 3)) { + frag->reassembly[start >> 3] |= bit_range(start & 7, end & 7); + } else { + frag->reassembly[start >> 3] |= bit_range(start & 7, 8); + for (size_t i = (start >> 3) + 1; i < (end >> 3); i++) { + frag->reassembly[i] = 0xff; + } + if ((end & 7) != 0) { + frag->reassembly[end >> 3] |= bit_range(0, end & 7); + } + } + + // Check if the fragment is complete. + for (size_t i = 0; i < (msg_len >> 3); i++) { + if (frag->reassembly[i] != 0xff) { + return; + } + } + if ((msg_len & 7) != 0 && + frag->reassembly[msg_len >> 3] != bit_range(0, msg_len & 7)) { + return; + } + + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; +} + +// dtls1_is_current_message_complete returns whether the current handshake +// message is complete. +static bool dtls1_is_current_message_complete(const SSL *ssl) { + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + return frag != NULL && frag->reassembly == NULL; +} + +// dtls1_get_incoming_message returns the incoming message corresponding to +// |msg_hdr|. If none exists, it creates a new one and inserts it in the +// queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It +// returns NULL on failure. The caller does not take ownership of the result. +static hm_fragment *dtls1_get_incoming_message( + SSL *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) { + if (msg_hdr->seq < ssl->d1->handshake_read_seq || + msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + + size_t idx = msg_hdr->seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + if (frag != NULL) { + assert(frag->seq == msg_hdr->seq); + // The new fragment must be compatible with the previous fragments from this + // message. + if (frag->type != msg_hdr->type || + frag->msg_len != msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return NULL; + } + return frag; + } + + // This is the first fragment from this message. + ssl->d1->incoming_messages[idx] = dtls1_hm_fragment_new(msg_hdr); + if (!ssl->d1->incoming_messages[idx]) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + return ssl->d1->incoming_messages[idx].get(); +} + +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + switch (type) { + case SSL3_RT_APPLICATION_DATA: + // Unencrypted application data records are always illegal. + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Out-of-order application data may be received between ChangeCipherSpec + // and finished. Discard it. + return ssl_open_record_discard; + + case SSL3_RT_CHANGE_CIPHER_SPEC: + // We do not support renegotiation, so encrypted ChangeCipherSpec records + // are illegal. + if (!ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.size() != 1u || record[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // Flag the ChangeCipherSpec for later. + ssl->d1->has_change_cipher_spec = true; + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, + record); + return ssl_open_record_success; + + case SSL3_RT_HANDSHAKE: + // Break out to main processing. + break; + + default: + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + CBS cbs; + CBS_init(&cbs, record.data(), record.size()); + while (CBS_len(&cbs) > 0) { + // Read a handshake fragment. + struct hm_header_st msg_hdr; + CBS body; + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + const size_t frag_off = msg_hdr.frag_off; + const size_t frag_len = msg_hdr.frag_len; + const size_t msg_len = msg_hdr.msg_len; + if (frag_off > msg_len || frag_off + frag_len < frag_off || + frag_off + frag_len > msg_len || + msg_len > ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // The encrypted epoch in DTLS has only one handshake message. + if (ssl->d1->r_epoch == 1 && msg_hdr.seq != ssl->d1->handshake_read_seq) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (msg_hdr.seq < ssl->d1->handshake_read_seq || + msg_hdr.seq > + (unsigned)ssl->d1->handshake_read_seq + SSL_MAX_HANDSHAKE_FLIGHT) { + // Ignore fragments from the past, or ones too far in the future. + continue; + } + + hm_fragment *frag = dtls1_get_incoming_message(ssl, out_alert, &msg_hdr); + if (frag == NULL) { + return ssl_open_record_error; + } + assert(frag->msg_len == msg_len); + + if (frag->reassembly == NULL) { + // The message is already assembled. + continue; + } + assert(msg_len > 0); + + // Copy the body into the fragment. + OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off, + CBS_data(&body), CBS_len(&body)); + dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len); + } + + return ssl_open_record_success; +} + +bool dtls1_get_message(const SSL *ssl, SSLMessage *out) { + if (!dtls1_is_current_message_complete(ssl)) { + return false; + } + + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + out->type = frag->type; + CBS_init(&out->body, frag->data + DTLS1_HM_HEADER_LENGTH, frag->msg_len); + CBS_init(&out->raw, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len); + out->is_v2_hello = false; + if (!ssl->s3->has_message) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + ssl->s3->has_message = true; + } + return true; +} + +void dtls1_next_message(SSL *ssl) { + assert(ssl->s3->has_message); + assert(dtls1_is_current_message_complete(ssl)); + size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + ssl->d1->incoming_messages[index].reset(); + ssl->d1->handshake_read_seq++; + ssl->s3->has_message = false; + // If we previously sent a flight, mark it as having a reply, so + // |on_handshake_complete| can manage post-handshake retransmission. + if (ssl->d1->outgoing_messages_complete) { + ssl->d1->flight_has_reply = true; + } +} + +bool dtls_has_unprocessed_handshake_data(const SSL *ssl) { + size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) { + // Skip the current message. + if (ssl->s3->has_message && i == current) { + assert(dtls1_is_current_message_complete(ssl)); + continue; + } + if (ssl->d1->incoming_messages[i] != nullptr) { + return true; + } + } + return false; +} + +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body) { + OPENSSL_memset(out_hdr, 0x00, sizeof(struct hm_header_st)); + + if (!CBS_get_u8(cbs, &out_hdr->type) || + !CBS_get_u24(cbs, &out_hdr->msg_len) || + !CBS_get_u16(cbs, &out_hdr->seq) || + !CBS_get_u24(cbs, &out_hdr->frag_off) || + !CBS_get_u24(cbs, &out_hdr->frag_len) || + !CBS_get_bytes(cbs, out_body, out_hdr->frag_len)) { + return false; + } + + return true; +} + +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + if (!ssl->d1->has_change_cipher_spec) { + // dtls1_open_handshake processes both handshake and ChangeCipherSpec. + auto ret = dtls1_open_handshake(ssl, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + } + if (ssl->d1->has_change_cipher_spec) { + ssl->d1->has_change_cipher_spec = false; + return ssl_open_record_success; + } + return ssl_open_record_discard; +} + + +// Sending handshake messages. + +void DTLS_OUTGOING_MESSAGE::Clear() { + OPENSSL_free(data); + data = nullptr; +} + +void dtls_clear_outgoing_messages(SSL *ssl) { + for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) { + ssl->d1->outgoing_messages[i].Clear(); + } + ssl->d1->outgoing_messages_len = 0; + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + ssl->d1->outgoing_messages_complete = false; + ssl->d1->flight_has_reply = false; +} + +bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24(cbb, 0 /* length (filled in later) */) || + !CBB_add_u16(cbb, ssl->d1->handshake_write_seq) || + !CBB_add_u24(cbb, 0 /* offset */) || + !CBB_add_u24_length_prefixed(cbb, body)) { + return false; + } + + return true; +} + +bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array *out_msg) { + if (!CBBFinishArray(cbb, out_msg) || + out_msg->size() < DTLS1_HM_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // Fix up the header. Copy the fragment length into the total message + // length. + OPENSSL_memcpy(out_msg->data() + 1, + out_msg->data() + DTLS1_HM_HEADER_LENGTH - 3, 3); + return true; +} + +// ssl_size_t_greater_than_32_bits returns whether |v| exceeds the bounds of a +// 32-bit value. The obvious thing doesn't work because, in some 32-bit build +// configurations, the compiler warns that the test is always false and breaks +// the build. +static bool ssl_size_t_greater_than_32_bits(size_t v) { +#if defined(OPENSSL_64_BIT) + return v > 0xffffffff; +#elif defined(OPENSSL_32_BIT) + return false; +#else +#error "Building for neither 32- nor 64-bits." +#endif +} + +// add_outgoing adds a new handshake message or ChangeCipherSpec to the current +// outgoing flight. It returns true on success and false on error. +static bool add_outgoing(SSL *ssl, bool is_ccs, Array data) { + if (ssl->d1->outgoing_messages_complete) { + // If we've begun writing a new flight, we received the peer flight. Discard + // the timer and the our flight. + dtls1_stop_timer(ssl); + dtls_clear_outgoing_messages(ssl); + } + + static_assert(SSL_MAX_HANDSHAKE_FLIGHT < + (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)), + "outgoing_messages_len is too small"); + if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT || + ssl_size_t_greater_than_32_bits(data.size())) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!is_ccs) { + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript + // on hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + ssl->d1->handshake_write_seq++; + } + + DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len]; + size_t len; + data.Release(&msg->data, &len); + msg->len = len; + msg->epoch = ssl->d1->w_epoch; + msg->is_ccs = is_ccs; + + ssl->d1->outgoing_messages_len++; + return true; +} + +bool dtls1_add_message(SSL *ssl, Array data) { + return add_outgoing(ssl, false /* handshake */, std::move(data)); +} + +bool dtls1_add_change_cipher_spec(SSL *ssl) { + return add_outgoing(ssl, true /* ChangeCipherSpec */, Array()); +} + +// dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above +// the minimum. +static void dtls1_update_mtu(SSL *ssl) { + // TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the + // only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use + // |SSL_set_mtu|. Does this need to be so complex? + if (ssl->d1->mtu < dtls1_min_mtu() && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } else { + ssl->d1->mtu = kDefaultMTU; + BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL); + } + } + + // The MTU should be above the minimum now. + assert(ssl->d1->mtu >= dtls1_min_mtu()); +} + +enum seal_result_t { + seal_error, + seal_no_progress, + seal_partial, + seal_success, +}; + +// seal_next_message seals |msg|, which must be the next message, to |out|. If +// progress was made, it returns |seal_partial| or |seal_success| and sets +// |*out_len| to the number of bytes written. +static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const DTLS_OUTGOING_MESSAGE *msg) { + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]); + + enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch; + if (ssl->d1->w_epoch >= 1 && msg->epoch == ssl->d1->w_epoch - 1) { + use_epoch = dtls1_use_previous_epoch; + } else if (msg->epoch != ssl->d1->w_epoch) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + size_t overhead = dtls_max_seal_overhead(ssl, use_epoch); + size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + + if (msg->is_ccs) { + // Check there is room for the ChangeCipherSpec. + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + if (max_out < sizeof(kChangeCipherSpec) + overhead) { + return seal_no_progress; + } + + if (!dtls_seal_record(ssl, out, out_len, max_out, + SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec, + sizeof(kChangeCipherSpec), use_epoch)) { + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return seal_success; + } + + // DTLS messages are serialized as a single fragment in |msg|. + CBS cbs, body; + struct hm_header_st hdr; + CBS_init(&cbs, msg->data, msg->len); + if (!dtls1_parse_fragment(&cbs, &hdr, &body) || + hdr.frag_off != 0 || + hdr.frag_len != CBS_len(&body) || + hdr.msg_len != CBS_len(&body) || + !CBS_skip(&body, ssl->d1->outgoing_offset) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + // Determine how much progress can be made. + if (max_out < DTLS1_HM_HEADER_LENGTH + 1 + overhead || max_out < prefix) { + return seal_no_progress; + } + size_t todo = CBS_len(&body); + if (todo > max_out - DTLS1_HM_HEADER_LENGTH - overhead) { + todo = max_out - DTLS1_HM_HEADER_LENGTH - overhead; + } + + // Assemble a fragment, to be sealed in-place. + ScopedCBB cbb; + uint8_t *frag = out + prefix; + size_t max_frag = max_out - prefix, frag_len; + if (!CBB_init_fixed(cbb.get(), frag, max_frag) || + !CBB_add_u8(cbb.get(), hdr.type) || + !CBB_add_u24(cbb.get(), hdr.msg_len) || + !CBB_add_u16(cbb.get(), hdr.seq) || + !CBB_add_u24(cbb.get(), ssl->d1->outgoing_offset) || + !CBB_add_u24(cbb.get(), todo) || + !CBB_add_bytes(cbb.get(), CBS_data(&body), todo) || + !CBB_finish(cbb.get(), NULL, &frag_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, + MakeSpan(frag, frag_len)); + + if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE, + out + prefix, frag_len, use_epoch)) { + return seal_error; + } + + if (todo == CBS_len(&body)) { + // The next message is complete. + ssl->d1->outgoing_offset = 0; + return seal_success; + } + + ssl->d1->outgoing_offset += todo; + return seal_partial; +} + +// seal_next_packet writes as much of the next flight as possible to |out| and +// advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as +// appropriate. +static bool seal_next_packet(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + bool made_progress = false; + size_t total = 0; + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + for (; ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len; + ssl->d1->outgoing_written++) { + const DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]; + size_t len; + enum seal_result_t ret = seal_next_message(ssl, out, &len, max_out, msg); + switch (ret) { + case seal_error: + return false; + + case seal_no_progress: + goto packet_full; + + case seal_partial: + case seal_success: + out += len; + max_out -= len; + total += len; + made_progress = true; + + if (ret == seal_partial) { + goto packet_full; + } + break; + } + } + +packet_full: + // The MTU was too small to make any progress. + if (!made_progress) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL); + return false; + } + + *out_len = total; + return true; +} + +static int send_flight(SSL *ssl) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (ssl->wbio == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + dtls1_update_mtu(ssl); + + Array packet; + if (!packet.Init(ssl->d1->mtu)) { + return -1; + } + + while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len) { + uint8_t old_written = ssl->d1->outgoing_written; + uint32_t old_offset = ssl->d1->outgoing_offset; + + size_t packet_len; + if (!seal_next_packet(ssl, packet.data(), &packet_len, packet.size())) { + return -1; + } + + int bio_ret = BIO_write(ssl->wbio.get(), packet.data(), packet_len); + if (bio_ret <= 0) { + // Retry this packet the next time around. + ssl->d1->outgoing_written = old_written; + ssl->d1->outgoing_offset = old_offset; + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return bio_ret; + } + } + + if (BIO_flush(ssl->wbio.get()) <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return -1; + } + + return 1; +} + +int dtls1_flush_flight(SSL *ssl) { + ssl->d1->outgoing_messages_complete = true; + // Start the retransmission timer for the next flight (if any). + dtls1_start_timer(ssl); + return send_flight(ssl); +} + +int dtls1_retransmit_outgoing_messages(SSL *ssl) { + // Rewind to the start of the flight and write it again. + // + // TODO(davidben): This does not allow retransmits to be resumed on + // non-blocking write. + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + + return send_flight(ssl); +} + +unsigned int dtls1_min_mtu(void) { + return kMinMTU; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_lib.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_lib.cc new file mode 100644 index 00000000..ace0cfca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_lib.cc @@ -0,0 +1,268 @@ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire +// before starting to decrease the MTU. +#define DTLS1_MTU_TIMEOUTS 2 + +// DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire +// before failing the DTLS handshake. +#define DTLS1_MAX_TIMEOUTS 12 + +DTLS1_STATE::DTLS1_STATE() + : has_change_cipher_spec(false), + outgoing_messages_complete(false), + flight_has_reply(false) {} + +DTLS1_STATE::~DTLS1_STATE() {} + +bool dtls1_new(SSL *ssl) { + if (!tls_new(ssl)) { + return false; + } + UniquePtr d1 = MakeUnique(); + if (!d1) { + tls_free(ssl); + return false; + } + + ssl->d1 = d1.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = DTLS1_2_VERSION; + return true; +} + +void dtls1_free(SSL *ssl) { + tls_free(ssl); + + if (ssl == NULL) { + return; + } + + Delete(ssl->d1); + ssl->d1 = NULL; +} + +void dtls1_start_timer(SSL *ssl) { + // If timer is not set, initialize duration (by default, 1 second) + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; + } + + // Set timeout to current time + ssl_get_current_time(ssl, &ssl->d1->next_timeout); + + // Add duration to current time + ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000; + ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000; + if (ssl->d1->next_timeout.tv_usec >= 1000000) { + ssl->d1->next_timeout.tv_sec++; + ssl->d1->next_timeout.tv_usec -= 1000000; + } +} + +bool dtls1_is_timer_expired(SSL *ssl) { + struct timeval timeleft; + + // Get time left until timeout, return false if no timer running + if (!DTLSv1_get_timeout(ssl, &timeleft)) { + return false; + } + + // Return false if timer is not expired yet + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return false; + } + + // Timer expired, so return true + return true; +} + +static void dtls1_double_timeout(SSL *ssl) { + ssl->d1->timeout_duration_ms *= 2; + if (ssl->d1->timeout_duration_ms > 60000) { + ssl->d1->timeout_duration_ms = 60000; + } +} + +void dtls1_stop_timer(SSL *ssl) { + ssl->d1->num_timeouts = 0; + OPENSSL_memset(&ssl->d1->next_timeout, 0, sizeof(ssl->d1->next_timeout)); + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; +} + +bool dtls1_check_timeout_num(SSL *ssl) { + ssl->d1->num_timeouts++; + + // Reduce MTU after 2 unsuccessful retransmissions + if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = + BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, nullptr); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } + } + + if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) { + // fail the connection, enough alerts have been sent + OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED); + return false; + } + + return true; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) { + ssl->initial_timeout_duration_ms = duration_ms; +} + +int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { + if (!SSL_is_dtls(ssl)) { + return 0; + } + + // If no timeout is set, just return 0. + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + return 0; + } + + struct OPENSSL_timeval timenow; + ssl_get_current_time(ssl, &timenow); + + // If timer already expired, set remaining time to 0. + if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || + (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && + ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + OPENSSL_memset(out, 0, sizeof(*out)); + return 1; + } + + // Calculate time left until timer expires. + struct OPENSSL_timeval ret; + OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret)); + ret.tv_sec -= timenow.tv_sec; + if (ret.tv_usec >= timenow.tv_usec) { + ret.tv_usec -= timenow.tv_usec; + } else { + ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec; + ret.tv_sec--; + } + + // If remaining time is less than 15 ms, set it to 0 to prevent issues + // because of small divergences with socket timeouts. + if (ret.tv_sec == 0 && ret.tv_usec < 15000) { + OPENSSL_memset(&ret, 0, sizeof(ret)); + } + + // Clamp the result in case of overflow. + if (ret.tv_sec > INT_MAX) { + assert(0); + out->tv_sec = INT_MAX; + } else { + out->tv_sec = ret.tv_sec; + } + + out->tv_usec = ret.tv_usec; + return 1; +} + +int DTLSv1_handle_timeout(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (!SSL_is_dtls(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + // If no timer is expired, don't do anything. + if (!dtls1_is_timer_expired(ssl)) { + return 0; + } + + if (!dtls1_check_timeout_num(ssl)) { + return -1; + } + + dtls1_double_timeout(ssl); + dtls1_start_timer(ssl); + return dtls1_retransmit_outgoing_messages(ssl); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_pkt.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_pkt.cc new file mode 100644 index 00000000..8a97ecdb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_pkt.cc @@ -0,0 +1,273 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(!SSL_in_init(ssl)); + + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type == SSL3_RT_HANDSHAKE) { + // Parse the first fragment header to determine if this is a pre-CCS or + // post-CCS handshake record. DTLS resets handshake message numbers on each + // handshake, so renegotiations and retransmissions are ambiguous. + CBS cbs, body; + struct hm_header_st msg_hdr; + CBS_init(&cbs, record.data(), record.size()); + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + if (msg_hdr.type == SSL3_MT_FINISHED && + msg_hdr.seq == ssl->d1->handshake_read_seq - 1) { + if (msg_hdr.frag_off == 0) { + // Retransmit our last flight of messages. If the peer sends the second + // Finished, they may not have received ours. Only do this for the + // first fragment, in case the Finished was fragmented. + if (!dtls1_check_timeout_num(ssl)) { + *out_alert = 0; // TODO(davidben): Send an alert? + return ssl_open_record_error; + } + + dtls1_retransmit_outgoing_messages(ssl); + } + return ssl_open_record_discard; + } + + // Otherwise, this is a pre-CCS handshake message from an unsupported + // renegotiation attempt. Fall through to the error path. + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.empty()) { + return ssl_open_record_discard; + } + + *out = record; + return ssl_open_record_success; +} + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(!SSL_in_init(ssl)); + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + if (len < 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + if (len == 0) { + return 0; + } + + int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, (size_t)len, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + return len; +} + +int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, + enum dtls1_use_epoch_t use_epoch) { + SSLBuffer *buf = &ssl->s3->write_buffer; + assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + // There should never be a pending write buffer in DTLS. One can't write half + // a datagram, so the write buffer is always dropped in + // |ssl_write_buffer_flush|. + assert(buf->empty()); + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + size_t ciphertext_len; + if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl), + len + SSL_max_seal_overhead(ssl)) || + !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len, use_epoch)) { + buf->Clear(); + return -1; + } + buf->DidWrite(ciphertext_len); + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + return 1; +} + +int dtls1_dispatch_alert(SSL *ssl) { + int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + ssl->s3->alert_dispatch = false; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio.get()); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_srtp.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_srtp.cc new file mode 100644 index 00000000..201d760d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/d1_srtp.cc @@ -0,0 +1,232 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + DTLS code by Eric Rescorla + + Copyright (C) 2006, Network Resonance, Inc. + Copyright (C) 2011, RTFM, Inc. +*/ + +#include + +#include + +#include +#include + +#include "internal.h" + + +using namespace bssl; + +static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { + { + "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, + }, + { + "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, + }, + { + "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, + }, + {0, 0}, +}; + +static int find_profile_by_name(const char *profile_name, + const SRTP_PROTECTION_PROFILE **pptr, + size_t len) { + const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles; + while (p->name) { + if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 1; + } + + p++; + } + + return 0; +} + +static int ssl_ctx_make_profiles( + const char *profiles_string, + UniquePtr *out) { + UniquePtr profiles( + sk_SRTP_PROTECTION_PROFILE_new_null()); + if (profiles == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 0; + } + + const char *col; + const char *ptr = profiles_string; + do { + col = strchr(ptr, ':'); + + const SRTP_PROTECTION_PROFILE *profile; + if (!find_profile_by_name(ptr, &profile, + col ? (size_t)(col - ptr) : strlen(ptr))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + return 0; + } + + if (!sk_SRTP_PROTECTION_PROFILE_push(profiles.get(), profile)) { + return 0; + } + + if (col) { + ptr = col + 1; + } + } while (col); + + *out = std::move(profiles); + return 1; +} + +int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) { + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) { + return ssl->config != nullptr && + ssl_ctx_make_profiles(profiles, &ssl->config->srtp_profiles); +} + +const STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(const SSL *ssl) { + if (ssl == nullptr) { + return nullptr; + } + + if (ssl->config == nullptr) { + assert(0); + return nullptr; + } + + return ssl->config->srtp_profiles != nullptr + ? ssl->config->srtp_profiles.get() + : ssl->ctx->srtp_profiles.get(); +} + +const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) { + return ssl->s3->srtp_profile; +} + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) { + // This API inverts its return value. + return !SSL_CTX_set_srtp_profiles(ctx, profiles); +} + +int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) { + // This API inverts its return value. + return !SSL_set_srtp_profiles(ssl, profiles); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_method.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_method.cc new file mode 100644 index 00000000..4fbb2cea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_method.cc @@ -0,0 +1,200 @@ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +using namespace bssl; + +static void dtls1_on_handshake_complete(SSL *ssl) { + // Stop the reply timer left by the last flight we sent. + dtls1_stop_timer(ssl); + // If the final flight had a reply, we know the peer has received it. If not, + // we must leave the flight around for post-handshake retransmission. + if (ssl->d1->flight_has_reply) { + dtls_clear_outgoing_messages(ssl); + } +} + +static bool dtls1_set_read_state(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic) { + assert(secret_for_quic.empty()); // QUIC does not use DTLS. + // Cipher changes are forbidden if the current epoch has leftover data. + if (dtls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + ssl->d1->r_epoch++; + OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap)); + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + + ssl->s3->aead_read_ctx = std::move(aead_ctx); + ssl->s3->read_level = level; + ssl->d1->has_change_cipher_spec = false; + return true; +} + +static bool dtls1_set_write_state(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic) { + assert(secret_for_quic.empty()); // QUIC does not use DTLS. + ssl->d1->w_epoch++; + OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence, + sizeof(ssl->s3->write_sequence)); + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + + ssl->d1->last_aead_write_ctx = std::move(ssl->s3->aead_write_ctx); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + ssl->s3->write_level = level; + return true; +} + +static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = { + true /* is_dtls */, + dtls1_new, + dtls1_free, + dtls1_get_message, + dtls1_next_message, + dtls_has_unprocessed_handshake_data, + dtls1_open_handshake, + dtls1_open_change_cipher_spec, + dtls1_open_app_data, + dtls1_write_app_data, + dtls1_dispatch_alert, + dtls1_init_message, + dtls1_finish_message, + dtls1_add_message, + dtls1_add_change_cipher_spec, + dtls1_flush_flight, + dtls1_on_handshake_complete, + dtls1_set_read_state, + dtls1_set_write_state, +}; + +const SSL_METHOD *DTLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *DTLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_2_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLSv1_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *DTLSv1_2_server_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_server_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLSv1_2_client_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_client_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLS_server_method(void) { + return DTLS_method(); +} + +const SSL_METHOD *DTLS_client_method(void) { + return DTLS_method(); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_record.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_record.cc new file mode 100644 index 00000000..4b4fef3e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/dtls_record.cc @@ -0,0 +1,353 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +// to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as +// a |uint64_t|. +static uint64_t to_u64_be(const uint8_t in[8]) { + uint64_t ret = 0; + unsigned i; + for (i = 0; i < 8; i++) { + ret <<= 8; + ret |= in[i]; + } + return ret; +} + +// dtls1_bitmap_should_discard returns one if |seq_num| has been seen in +// |bitmap| or is stale. Otherwise it returns zero. +static bool dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + if (seq_num_u > bitmap->max_seq_num) { + return false; + } + uint64_t idx = bitmap->max_seq_num - seq_num_u; + return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx)); +} + +// dtls1_bitmap_record updates |bitmap| to record receipt of sequence number +// |seq_num|. It slides the window forward if needed. It is an error to call +// this function on a stale sequence number. +static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + // Shift the window if necessary. + if (seq_num_u > bitmap->max_seq_num) { + uint64_t shift = seq_num_u - bitmap->max_seq_num; + if (shift >= kWindowSize) { + bitmap->map = 0; + } else { + bitmap->map <<= shift; + } + bitmap->max_seq_num = seq_num_u; + } + + uint64_t idx = bitmap->max_seq_num - seq_num_u; + if (idx < kWindowSize) { + bitmap->map |= ((uint64_t)1) << idx; + } +} + +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + if (in.empty()) { + return ssl_open_record_partial; + } + + CBS cbs = CBS(in); + + // Decode the record. + uint8_t type; + uint16_t version; + uint8_t sequence[8]; + CBS body; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_copy_bytes(&cbs, sequence, 8) || + !CBS_get_u16_length_prefixed(&cbs, &body) || + CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == DTLS1_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + Span header = in.subspan(0, DTLS1_RT_HEADER_LENGTH); + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header); + + uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1]; + if (epoch != ssl->d1->r_epoch || + dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) { + // Drop this record. It's from the wrong epoch or is a replay. Note that if + // |epoch| is the next epoch, the record could be buffered for later. For + // simplicity, drop it and expect retransmit to handle it later; DTLS must + // handle packet loss anyway. + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + + // discard the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, sequence, header, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + // Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347. + // Clear the error queue of any errors decryption may have added. Drop the + // entire packet as it must not have come from the peer. + // + // TODO(davidben): This doesn't distinguish malloc failures from encryption + // failures. + ERR_clear_error(); + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + *out_consumed = in.size() - CBS_len(&cbs); + + // Check the plaintext length. + if (out->size() > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + dtls1_bitmap_record(&ssl->d1->bitmap, sequence); + + // TODO(davidben): Limit the number of empty records as in TLS? This is only + // useful if we also limit discarded packets. + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static const SSLAEADContext *get_write_aead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + return ssl->d1->last_aead_write_ctx.get(); + } + + return ssl->s3->aead_write_ctx.get(); +} + +size_t dtls_max_seal_overhead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + get_write_aead(ssl, use_epoch)->MaxOverhead(); +} + +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + + get_write_aead(ssl, use_epoch)->ExplicitNonceLen(); +} + +bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch) { + const size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + if (buffers_alias(in, in_len, out, max_out) && + (max_out < prefix || out + prefix != in)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + + // Determine the parameters for the current epoch. + uint16_t epoch = ssl->d1->w_epoch; + SSLAEADContext *aead = ssl->s3->aead_write_ctx.get(); + uint8_t *seq = ssl->s3->write_sequence; + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + epoch = ssl->d1->w_epoch - 1; + aead = ssl->d1->last_aead_write_ctx.get(); + seq = ssl->d1->last_write_sequence; + } + + if (max_out < DTLS1_RT_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + + out[0] = type; + + uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion(); + out[1] = record_version >> 8; + out[2] = record_version & 0xff; + + out[3] = epoch >> 8; + out[4] = epoch & 0xff; + OPENSSL_memcpy(&out[5], &seq[2], 6); + + size_t ciphertext_len; + if (!aead->CiphertextLen(&ciphertext_len, in_len, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + out[11] = ciphertext_len >> 8; + out[12] = ciphertext_len & 0xff; + Span header = MakeConstSpan(out, DTLS1_RT_HEADER_LENGTH); + + size_t len_copy; + if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &len_copy, + max_out - DTLS1_RT_HEADER_LENGTH, type, record_version, + &out[3] /* seq */, header, in, in_len) || + !ssl_record_sequence_update(&seq[2], 6)) { + return false; + } + assert(ciphertext_len == len_copy); + + *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len; + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header); + return true; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc new file mode 100644 index 00000000..62a2f66f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc @@ -0,0 +1,1105 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// ECH reuses the extension code point for the version number. +static constexpr uint16_t kECHConfigVersion = + TLSEXT_TYPE_encrypted_client_hello; + +static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[] = { + &EVP_hpke_aes_128_gcm, + &EVP_hpke_aes_256_gcm, + &EVP_hpke_chacha20_poly1305, +}; + +static const EVP_HPKE_AEAD *get_ech_aead(uint16_t aead_id) { + for (const auto aead_func : kSupportedAEADs) { + const EVP_HPKE_AEAD *aead = aead_func(); + if (aead_id == EVP_HPKE_AEAD_id(aead)) { + return aead; + } + } + return nullptr; +} + +// ssl_client_hello_write_without_extensions serializes |client_hello| into +// |out|, omitting the length-prefixed extensions. It serializes individual +// fields, starting with |client_hello->version|, and ignores the +// |client_hello->client_hello| field. It returns true on success and false on +// failure. +static bool ssl_client_hello_write_without_extensions( + const SSL_CLIENT_HELLO *client_hello, CBB *out) { + CBB cbb; + if (!CBB_add_u16(out, client_hello->version) || + !CBB_add_bytes(out, client_hello->random, client_hello->random_len) || + !CBB_add_u8_length_prefixed(out, &cbb) || + !CBB_add_bytes(&cbb, client_hello->session_id, + client_hello->session_id_len) || + !CBB_add_u16_length_prefixed(out, &cbb) || + !CBB_add_bytes(&cbb, client_hello->cipher_suites, + client_hello->cipher_suites_len) || + !CBB_add_u8_length_prefixed(out, &cbb) || + !CBB_add_bytes(&cbb, client_hello->compression_methods, + client_hello->compression_methods_len) || + !CBB_flush(out)) { + return false; + } + return true; +} + +static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert, + Span body) { + // See draft-ietf-tls-esni-13, section 7.1. + SSL_CLIENT_HELLO client_hello; + CBS extension; + if (!ssl_client_hello_init(ssl, &client_hello, body) || + !ssl_client_hello_get_extension(&client_hello, &extension, + TLSEXT_TYPE_encrypted_client_hello) || + CBS_len(&extension) != 1 || // + CBS_data(&extension)[0] != ECH_CLIENT_INNER || + !ssl_client_hello_get_extension(&client_hello, &extension, + TLSEXT_TYPE_supported_versions)) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER); + return false; + } + // Parse supported_versions and reject TLS versions prior to TLS 1.3. Older + // versions are incompatible with ECH. + CBS versions; + if (!CBS_get_u8_length_prefixed(&extension, &versions) || + CBS_len(&extension) != 0 || // + CBS_len(&versions) == 0) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + while (CBS_len(&versions) != 0) { + uint16_t version; + if (!CBS_get_u16(&versions, &version)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + if (version == SSL3_VERSION || version == TLS1_VERSION || + version == TLS1_1_VERSION || version == TLS1_2_VERSION || + version == DTLS1_VERSION || version == DTLS1_2_VERSION) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER); + return false; + } + } + return true; +} + +bool ssl_decode_client_hello_inner( + SSL *ssl, uint8_t *out_alert, Array *out_client_hello_inner, + Span encoded_client_hello_inner, + const SSL_CLIENT_HELLO *client_hello_outer) { + SSL_CLIENT_HELLO client_hello_inner; + CBS cbs = encoded_client_hello_inner; + if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs, + &client_hello_inner)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + // The remaining data is padding. + uint8_t padding; + while (CBS_get_u8(&cbs, &padding)) { + if (padding != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + } + + // TLS 1.3 ClientHellos must have extensions, and EncodedClientHelloInners use + // ClientHelloOuter's session_id. + if (client_hello_inner.extensions_len == 0 || + client_hello_inner.session_id_len != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + client_hello_inner.session_id = client_hello_outer->session_id; + client_hello_inner.session_id_len = client_hello_outer->session_id_len; + + // Begin serializing a message containing the ClientHelloInner in |cbb|. + ScopedCBB cbb; + CBB body, extensions_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) || + !ssl_client_hello_write_without_extensions(&client_hello_inner, &body) || + !CBB_add_u16_length_prefixed(&body, &extensions_cbb)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + auto inner_extensions = MakeConstSpan(client_hello_inner.extensions, + client_hello_inner.extensions_len); + CBS ext_list_wrapper; + if (!ssl_client_hello_get_extension(&client_hello_inner, &ext_list_wrapper, + TLSEXT_TYPE_ech_outer_extensions)) { + // No ech_outer_extensions. Copy everything. + if (!CBB_add_bytes(&extensions_cbb, inner_extensions.data(), + inner_extensions.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } else { + const size_t offset = CBS_data(&ext_list_wrapper) - inner_extensions.data(); + auto inner_extensions_before = + inner_extensions.subspan(0, offset - 4 /* extension header */); + auto inner_extensions_after = + inner_extensions.subspan(offset + CBS_len(&ext_list_wrapper)); + if (!CBB_add_bytes(&extensions_cbb, inner_extensions_before.data(), + inner_extensions_before.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // Expand ech_outer_extensions. See draft-ietf-tls-esni-13, Appendix B. + CBS ext_list; + if (!CBS_get_u8_length_prefixed(&ext_list_wrapper, &ext_list) || + CBS_len(&ext_list) == 0 || CBS_len(&ext_list_wrapper) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + CBS outer_extensions; + CBS_init(&outer_extensions, client_hello_outer->extensions, + client_hello_outer->extensions_len); + while (CBS_len(&ext_list) != 0) { + // Find the next extension to copy. + uint16_t want; + if (!CBS_get_u16(&ext_list, &want)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + // The ECH extension itself is not in the AAD and may not be referenced. + if (want == TLSEXT_TYPE_encrypted_client_hello) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION); + return false; + } + // Seek to |want| in |outer_extensions|. |ext_list| is required to match + // ClientHelloOuter in order. + uint16_t found; + CBS ext_body; + do { + if (CBS_len(&outer_extensions) == 0) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION); + return false; + } + if (!CBS_get_u16(&outer_extensions, &found) || + !CBS_get_u16_length_prefixed(&outer_extensions, &ext_body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + } while (found != want); + // Copy the extension. + if (!CBB_add_u16(&extensions_cbb, found) || + !CBB_add_u16(&extensions_cbb, CBS_len(&ext_body)) || + !CBB_add_bytes(&extensions_cbb, CBS_data(&ext_body), + CBS_len(&ext_body))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + } + + if (!CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(), + inner_extensions_after.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + if (!CBB_flush(&body)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!is_valid_client_hello_inner( + ssl, out_alert, MakeConstSpan(CBB_data(&body), CBB_len(&body)))) { + return false; + } + + if (!ssl->method->finish_message(ssl, cbb.get(), out_client_hello_inner)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + return true; +} + +bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert, + bool *out_is_decrypt_error, Array *out, + const SSL_CLIENT_HELLO *client_hello_outer, + Span payload) { + *out_is_decrypt_error = false; + + // The ClientHelloOuterAAD is |client_hello_outer| with |payload| (which must + // point within |client_hello_outer->extensions|) replaced with zeros. See + // draft-ietf-tls-esni-13, section 5.2. + Array aad; + if (!aad.CopyFrom(MakeConstSpan(client_hello_outer->client_hello, + client_hello_outer->client_hello_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + // We assert with |uintptr_t| because the comparison would be UB if they + // didn't alias. + assert(reinterpret_cast(client_hello_outer->extensions) <= + reinterpret_cast(payload.data())); + assert(reinterpret_cast(client_hello_outer->extensions + + client_hello_outer->extensions_len) >= + reinterpret_cast(payload.data() + payload.size())); + Span payload_aad = MakeSpan(aad).subspan( + payload.data() - client_hello_outer->client_hello, payload.size()); + OPENSSL_memset(payload_aad.data(), 0, payload_aad.size()); + + // Decrypt the EncodedClientHelloInner. + Array encoded; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + // In fuzzer mode, disable encryption to improve coverage. We reserve a short + // input to signal decryption failure, so the fuzzer can explore fallback to + // ClientHelloOuter. + const uint8_t kBadPayload[] = {0xff}; + if (payload == kBadPayload) { + *out_alert = SSL_AD_DECRYPT_ERROR; + *out_is_decrypt_error = true; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + return false; + } + if (!encoded.CopyFrom(payload)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } +#else + if (!encoded.Init(payload.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + size_t len; + if (!EVP_HPKE_CTX_open(hs->ech_hpke_ctx.get(), encoded.data(), &len, + encoded.size(), payload.data(), payload.size(), + aad.data(), aad.size())) { + *out_alert = SSL_AD_DECRYPT_ERROR; + *out_is_decrypt_error = true; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + return false; + } + encoded.Shrink(len); +#endif + + if (!ssl_decode_client_hello_inner(hs->ssl, out_alert, out, encoded, + client_hello_outer)) { + return false; + } + + ssl_do_msg_callback(hs->ssl, /*is_write=*/0, SSL3_RT_CLIENT_HELLO_INNER, + *out); + return true; +} + +static bool is_hex_component(Span in) { + if (in.size() < 2 || in[0] != '0' || (in[1] != 'x' && in[1] != 'X')) { + return false; + } + for (uint8_t b : in.subspan(2)) { + if (!('0' <= b && b <= '9') && !('a' <= b && b <= 'f') && + !('A' <= b && b <= 'F')) { + return false; + } + } + return true; +} + +static bool is_decimal_component(Span in) { + if (in.empty()) { + return false; + } + for (uint8_t b : in) { + if (!('0' <= b && b <= '9')) { + return false; + } + } + return true; +} + +bool ssl_is_valid_ech_public_name(Span public_name) { + // See draft-ietf-tls-esni-13, Section 4 and RFC 5890, Section 2.3.1. The + // public name must be a dot-separated sequence of LDH labels and not begin or + // end with a dot. + auto remaining = public_name; + if (remaining.empty()) { + return false; + } + Span last; + while (!remaining.empty()) { + // Find the next dot-separated component. + auto dot = std::find(remaining.begin(), remaining.end(), '.'); + Span component; + if (dot == remaining.end()) { + component = remaining; + last = component; + remaining = Span(); + } else { + component = remaining.subspan(0, dot - remaining.begin()); + // Skip the dot. + remaining = remaining.subspan(dot - remaining.begin() + 1); + if (remaining.empty()) { + // Trailing dots are not allowed. + return false; + } + } + // |component| must be a valid LDH label. Checking for empty components also + // rejects leading dots. + if (component.empty() || component.size() > 63 || + component.front() == '-' || component.back() == '-') { + return false; + } + for (uint8_t c : component) { + if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && + !('0' <= c && c <= '9') && c != '-') { + return false; + } + } + } + + // The WHATWG URL parser additionally does not allow any DNS names that end in + // a numeric component. See: + // https://url.spec.whatwg.org/#concept-host-parser + // https://url.spec.whatwg.org/#ends-in-a-number-checker + // + // The WHATWG parser is formulated in terms of parsing decimal, octal, and + // hex, along with a separate ASCII digits check. The ASCII digits check + // subsumes the decimal and octal check, so we only need to check two cases. + return !is_hex_component(last) && !is_decimal_component(last); +} + +static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported, + bool all_extensions_mandatory) { + uint16_t version; + CBS orig = *cbs; + CBS contents; + if (!CBS_get_u16(cbs, &version) || + !CBS_get_u16_length_prefixed(cbs, &contents)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (version != kECHConfigVersion) { + *out_supported = false; + return true; + } + + // Make a copy of the ECHConfig and parse from it, so the results alias into + // the saved copy. + if (!out->raw.CopyFrom( + MakeConstSpan(CBS_data(&orig), CBS_len(&orig) - CBS_len(cbs)))) { + return false; + } + + CBS ech_config(out->raw); + CBS public_name, public_key, cipher_suites, extensions; + if (!CBS_skip(&ech_config, 2) || // version + !CBS_get_u16_length_prefixed(&ech_config, &contents) || + !CBS_get_u8(&contents, &out->config_id) || + !CBS_get_u16(&contents, &out->kem_id) || + !CBS_get_u16_length_prefixed(&contents, &public_key) || + CBS_len(&public_key) == 0 || + !CBS_get_u16_length_prefixed(&contents, &cipher_suites) || + CBS_len(&cipher_suites) == 0 || CBS_len(&cipher_suites) % 4 != 0 || + !CBS_get_u8(&contents, &out->maximum_name_length) || + !CBS_get_u8_length_prefixed(&contents, &public_name) || + CBS_len(&public_name) == 0 || + !CBS_get_u16_length_prefixed(&contents, &extensions) || + CBS_len(&contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (!ssl_is_valid_ech_public_name(public_name)) { + // TODO(https://crbug.com/boringssl/275): The draft says ECHConfigs with + // invalid public names should be ignored, but LDH syntax failures are + // unambiguously invalid. + *out_supported = false; + return true; + } + + out->public_key = public_key; + out->public_name = public_name; + // This function does not ensure |out->kem_id| and |out->cipher_suites| use + // supported algorithms. The caller must do this. + out->cipher_suites = cipher_suites; + + bool has_unknown_mandatory_extension = false; + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS body; + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + // We currently do not support any extensions. + if (type & 0x8000 || all_extensions_mandatory) { + // Extension numbers with the high bit set are mandatory. Continue parsing + // to enforce syntax, but we will ultimately ignore this ECHConfig as a + // client and reject it as a server. + has_unknown_mandatory_extension = true; + } + } + + *out_supported = !has_unknown_mandatory_extension; + return true; +} + +bool ECHServerConfig::Init(Span ech_config, + const EVP_HPKE_KEY *key, bool is_retry_config) { + is_retry_config_ = is_retry_config; + + // Parse the ECHConfig, rejecting all unsupported parameters and extensions. + // Unlike most server options, ECH's server configuration is serialized and + // configured in both the server and DNS. If the caller configures an + // unsupported parameter, this is a deployment error. To catch these errors, + // we fail early. + CBS cbs = ech_config; + bool supported; + if (!parse_ech_config(&cbs, &ech_config_, &supported, + /*all_extensions_mandatory=*/true)) { + return false; + } + if (CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + if (!supported) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG); + return false; + } + + CBS cipher_suites = ech_config_.cipher_suites; + while (CBS_len(&cipher_suites) > 0) { + uint16_t kdf_id, aead_id; + if (!CBS_get_u16(&cipher_suites, &kdf_id) || + !CBS_get_u16(&cipher_suites, &aead_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + // The server promises to support every option in the ECHConfig, so reject + // any unsupported cipher suites. + if (kdf_id != EVP_HPKE_HKDF_SHA256 || get_ech_aead(aead_id) == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG); + return false; + } + } + + // Check the public key in the ECHConfig matches |key|. + uint8_t expected_public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH]; + size_t expected_public_key_len; + if (!EVP_HPKE_KEY_public_key(key, expected_public_key, + &expected_public_key_len, + sizeof(expected_public_key))) { + return false; + } + if (ech_config_.kem_id != EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key)) || + MakeConstSpan(expected_public_key, expected_public_key_len) != + ech_config_.public_key) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH); + return false; + } + + if (!EVP_HPKE_KEY_copy(key_.get(), key)) { + return false; + } + + return true; +} + +bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, + uint16_t aead_id, + Span enc) const { + // Check the cipher suite is supported by this ECHServerConfig. + CBS cbs(ech_config_.cipher_suites); + bool cipher_ok = false; + while (CBS_len(&cbs) != 0) { + uint16_t supported_kdf_id, supported_aead_id; + if (!CBS_get_u16(&cbs, &supported_kdf_id) || + !CBS_get_u16(&cbs, &supported_aead_id)) { + return false; + } + if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) { + cipher_ok = true; + break; + } + } + if (!cipher_ok) { + return false; + } + + static const uint8_t kInfoLabel[] = "tls ech"; + ScopedCBB info_cbb; + if (!CBB_init(info_cbb.get(), sizeof(kInfoLabel) + ech_config_.raw.size()) || + !CBB_add_bytes(info_cbb.get(), kInfoLabel, + sizeof(kInfoLabel) /* includes trailing NUL */) || + !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(), + ech_config_.raw.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + assert(kdf_id == EVP_HPKE_HKDF_SHA256); + assert(get_ech_aead(aead_id) != NULL); + return EVP_HPKE_CTX_setup_recipient( + ctx, key_.get(), EVP_hpke_hkdf_sha256(), get_ech_aead(aead_id), enc.data(), + enc.size(), CBB_data(info_cbb.get()), CBB_len(info_cbb.get())); +} + +bool ssl_is_valid_ech_config_list(Span ech_config_list) { + CBS cbs = ech_config_list, child; + if (!CBS_get_u16_length_prefixed(&cbs, &child) || // + CBS_len(&child) == 0 || // + CBS_len(&cbs) > 0) { + return false; + } + while (CBS_len(&child) > 0) { + ECHConfig ech_config; + bool supported; + if (!parse_ech_config(&child, &ech_config, &supported, + /*all_extensions_mandatory=*/false)) { + return false; + } + } + return true; +} + +static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf, + const EVP_HPKE_AEAD **out_aead, + Span cipher_suites) { + const bool has_aes_hardware = EVP_has_aes_hardware(); + const EVP_HPKE_AEAD *aead = nullptr; + CBS cbs = cipher_suites; + while (CBS_len(&cbs) != 0) { + uint16_t kdf_id, aead_id; + if (!CBS_get_u16(&cbs, &kdf_id) || // + !CBS_get_u16(&cbs, &aead_id)) { + return false; + } + // Pick the first common cipher suite, but prefer ChaCha20-Poly1305 if we + // don't have AES hardware. + const EVP_HPKE_AEAD *candidate = get_ech_aead(aead_id); + if (kdf_id != EVP_HPKE_HKDF_SHA256 || candidate == nullptr) { + continue; + } + if (aead == nullptr || + (!has_aes_hardware && aead_id == EVP_HPKE_CHACHA20_POLY1305)) { + aead = candidate; + } + } + if (aead == nullptr) { + return false; + } + + *out_kdf = EVP_hpke_hkdf_sha256(); + *out_aead = aead; + return true; +} + +bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span out_enc, + size_t *out_enc_len) { + *out_enc_len = 0; + if (hs->max_version < TLS1_3_VERSION) { + // ECH requires TLS 1.3. + return true; + } + + if (!hs->config->client_ech_config_list.empty()) { + CBS cbs = MakeConstSpan(hs->config->client_ech_config_list); + CBS child; + if (!CBS_get_u16_length_prefixed(&cbs, &child) || // + CBS_len(&child) == 0 || // + CBS_len(&cbs) > 0) { + return false; + } + // Look for the first ECHConfig with supported parameters. + while (CBS_len(&child) > 0) { + ECHConfig ech_config; + bool supported; + if (!parse_ech_config(&child, &ech_config, &supported, + /*all_extensions_mandatory=*/false)) { + return false; + } + const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256(); + const EVP_HPKE_KDF *kdf; + const EVP_HPKE_AEAD *aead; + if (supported && // + ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 && + select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites)) { + ScopedCBB info; + static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL + if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) || + !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) || + !CBB_add_bytes(info.get(), ech_config.raw.data(), + ech_config.raw.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + if (!EVP_HPKE_CTX_setup_sender( + hs->ech_hpke_ctx.get(), out_enc.data(), out_enc_len, + out_enc.size(), kem, kdf, aead, ech_config.public_key.data(), + ech_config.public_key.size(), CBB_data(info.get()), + CBB_len(info.get())) || + !hs->inner_transcript.Init()) { + return false; + } + + hs->selected_ech_config = MakeUnique(std::move(ech_config)); + return hs->selected_ech_config != nullptr; + } + } + } + + return true; +} + +static size_t aead_overhead(const EVP_HPKE_AEAD *aead) { +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + // TODO(https://crbug.com/boringssl/275): Having to adjust the overhead + // everywhere is tedious. Change fuzzer mode to append a fake tag but still + // otherwise be cleartext, refresh corpora, and then inline this function. + return 0; +#else + return EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(aead)); +#endif +} + +// random_size returns a random value between |min| and |max|, inclusive. +static size_t random_size(size_t min, size_t max) { + assert(min < max); + size_t value; + RAND_bytes(reinterpret_cast(&value), sizeof(value)); + return value % (max - min + 1) + min; +} + +static bool setup_ech_grease(SSL_HANDSHAKE *hs) { + assert(!hs->selected_ech_config); + if (hs->max_version < TLS1_3_VERSION || !hs->config->ech_grease_enabled) { + return true; + } + + const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256; + const EVP_HPKE_AEAD *aead = EVP_has_aes_hardware() + ? EVP_hpke_aes_128_gcm() + : EVP_hpke_chacha20_poly1305(); + static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed), + "hs->grease_seed is too small"); + uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id]; + + uint8_t enc[X25519_PUBLIC_VALUE_LEN]; + uint8_t private_key_unused[X25519_PRIVATE_KEY_LEN]; + X25519_keypair(enc, private_key_unused); + + // To determine a plausible length for the payload, we estimate the size of a + // typical EncodedClientHelloInner without resumption: + // + // 2+32+1+2 version, random, legacy_session_id, legacy_compression_methods + // 2+4*2 cipher_suites (three TLS 1.3 ciphers, GREASE) + // 2 extensions prefix + // 5 inner encrypted_client_hello + // 4+1+2*2 supported_versions (TLS 1.3, GREASE) + // 4+1+10*2 outer_extensions (key_share, sigalgs, sct, alpn, + // supported_groups, status_request, psk_key_exchange_modes, + // compress_certificate, GREASE x2) + // + // The server_name extension has an overhead of 9 bytes. For now, arbitrarily + // estimate maximum_name_length to be between 32 and 100 bytes. Then round up + // to a multiple of 32, to match draft-ietf-tls-esni-13, section 6.1.3. + const size_t payload_len = + 32 * random_size(128 / 32, 224 / 32) + aead_overhead(aead); + bssl::ScopedCBB cbb; + CBB enc_cbb, payload_cbb; + uint8_t *payload; + if (!CBB_init(cbb.get(), 256) || + !CBB_add_u16(cbb.get(), kdf_id) || + !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) || + !CBB_add_u8(cbb.get(), config_id) || + !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) || + !CBB_add_bytes(&enc_cbb, enc, sizeof(enc)) || + !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) || + !CBB_add_space(&payload_cbb, &payload, payload_len) || + !RAND_bytes(payload, payload_len) || + !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) { + return false; + } + return true; +} + +bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span enc) { + SSL *const ssl = hs->ssl; + if (!hs->selected_ech_config) { + return setup_ech_grease(hs); + } + + // Construct ClientHelloInner and EncodedClientHelloInner. See + // draft-ietf-tls-esni-13, sections 5.1 and 6.1. + ScopedCBB cbb, encoded_cbb; + CBB body; + bool needs_psk_binder; + Array hello_inner; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) || + !CBB_init(encoded_cbb.get(), 256) || + !ssl_write_client_hello_without_extensions(hs, &body, + ssl_client_hello_inner, + /*empty_session_id=*/false) || + !ssl_write_client_hello_without_extensions(hs, encoded_cbb.get(), + ssl_client_hello_inner, + /*empty_session_id=*/true) || + !ssl_add_clienthello_tlsext(hs, &body, encoded_cbb.get(), + &needs_psk_binder, ssl_client_hello_inner, + CBB_len(&body)) || + !ssl->method->finish_message(ssl, cbb.get(), &hello_inner)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (needs_psk_binder) { + size_t binder_len; + if (!tls13_write_psk_binder(hs, hs->inner_transcript, MakeSpan(hello_inner), + &binder_len)) { + return false; + } + // Also update the EncodedClientHelloInner. + auto encoded_binder = + MakeSpan(const_cast(CBB_data(encoded_cbb.get())), + CBB_len(encoded_cbb.get())) + .last(binder_len); + auto hello_inner_binder = MakeConstSpan(hello_inner).last(binder_len); + OPENSSL_memcpy(encoded_binder.data(), hello_inner_binder.data(), + binder_len); + } + + ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_CLIENT_HELLO_INNER, + hello_inner); + if (!hs->inner_transcript.Update(hello_inner)) { + return false; + } + + // Pad the EncodedClientHelloInner. See draft-ietf-tls-esni-13, section 6.1.3. + size_t padding_len = 0; + size_t maximum_name_length = hs->selected_ech_config->maximum_name_length; + if (ssl->hostname) { + size_t hostname_len = strlen(ssl->hostname.get()); + if (hostname_len <= maximum_name_length) { + padding_len = maximum_name_length - hostname_len; + } + } else { + // No SNI. Pad up to |maximum_name_length|, including server_name extension + // overhead. + padding_len = 9 + maximum_name_length; + } + // Pad the whole thing to a multiple of 32 bytes. + padding_len += 31 - ((CBB_len(encoded_cbb.get()) + padding_len - 1) % 32); + Array encoded; + if (!CBB_add_zeros(encoded_cbb.get(), padding_len) || + !CBBFinishArray(encoded_cbb.get(), &encoded)) { + return false; + } + + // Encrypt |encoded|. See draft-ietf-tls-esni-13, section 6.1.1. First, + // assemble the extension with a placeholder value for ClientHelloOuterAAD. + // See draft-ietf-tls-esni-13, section 5.2. + const EVP_HPKE_KDF *kdf = EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get()); + const EVP_HPKE_AEAD *aead = EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get()); + size_t payload_len = encoded.size() + aead_overhead(aead); + CBB enc_cbb, payload_cbb; + if (!CBB_init(cbb.get(), 256) || + !CBB_add_u16(cbb.get(), EVP_HPKE_KDF_id(kdf)) || + !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) || + !CBB_add_u8(cbb.get(), hs->selected_ech_config->config_id) || + !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) || + !CBB_add_bytes(&enc_cbb, enc.data(), enc.size()) || + !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) || + !CBB_add_zeros(&payload_cbb, payload_len) || + !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) { + return false; + } + + // Construct ClientHelloOuterAAD. + // TODO(https://crbug.com/boringssl/275): This ends up constructing the + // ClientHelloOuter twice. Instead, reuse |aad| for the ClientHello, now that + // draft-12 made the length prefixes match. + bssl::ScopedCBB aad; + if (!CBB_init(aad.get(), 256) || + !ssl_write_client_hello_without_extensions(hs, aad.get(), + ssl_client_hello_outer, + /*empty_session_id=*/false) || + !ssl_add_clienthello_tlsext(hs, aad.get(), /*out_encoded=*/nullptr, + &needs_psk_binder, ssl_client_hello_outer, + CBB_len(aad.get()))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // ClientHelloOuter may not require a PSK binder. Otherwise, we have a + // circular dependency. + assert(!needs_psk_binder); + + // Replace the payload in |hs->ech_client_outer| with the encrypted value. + auto payload_span = MakeSpan(hs->ech_client_outer).last(payload_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + // In fuzzer mode, the server expects a cleartext payload. + assert(payload_span.size() == encoded.size()); + OPENSSL_memcpy(payload_span.data(), encoded.data(), encoded.size()); +#else + if (!EVP_HPKE_CTX_seal(hs->ech_hpke_ctx.get(), payload_span.data(), + &payload_len, payload_span.size(), encoded.data(), + encoded.size(), CBB_data(aad.get()), + CBB_len(aad.get())) || + payload_len != payload_span.size()) { + return false; + } +#endif // BORINGSSL_UNSAFE_FUZZER_MODE + + return true; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +void SSL_set_enable_ech_grease(SSL *ssl, int enable) { + if (!ssl->config) { + return; + } + ssl->config->ech_grease_enabled = !!enable; +} + +int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list, + size_t ech_config_list_len) { + if (!ssl->config) { + return 0; + } + + auto span = MakeConstSpan(ech_config_list, ech_config_list_len); + if (!ssl_is_valid_ech_config_list(span)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_CONFIG_LIST); + return 0; + } + return ssl->config->client_ech_config_list.CopyFrom(span); +} + +void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name, + size_t *out_name_len) { + // When ECH is rejected, we use the public name. Note that, if + // |SSL_CTX_set_reverify_on_resume| is enabled, we reverify the certificate + // before the 0-RTT point. If also offering ECH, we verify as if + // ClientHelloInner was accepted and do not override. This works because, at + // this point, |ech_status| will be |ssl_ech_none|. See the + // ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go. + const SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) { + *out_name = reinterpret_cast( + hs->selected_ech_config->public_name.data()); + *out_name_len = hs->selected_ech_config->public_name.size(); + } else { + *out_name = nullptr; + *out_name_len = 0; + } +} + +void SSL_get0_ech_retry_configs( + const SSL *ssl, const uint8_t **out_retry_configs, + size_t *out_retry_configs_len) { + const SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (!hs || !hs->ech_authenticated_reject) { + // It is an error to call this function except in response to + // |SSL_R_ECH_REJECTED|. Returning an empty string risks the caller + // mistakenly believing the server has disabled ECH. Instead, return a + // non-empty ECHConfigList with a syntax error, so the subsequent + // |SSL_set1_ech_config_list| call will fail. + assert(0); + static const uint8_t kPlaceholder[] = { + kECHConfigVersion >> 8, kECHConfigVersion & 0xff, 0xff, 0xff, 0xff}; + *out_retry_configs = kPlaceholder; + *out_retry_configs_len = sizeof(kPlaceholder); + return; + } + + *out_retry_configs = hs->ech_retry_configs.data(); + *out_retry_configs_len = hs->ech_retry_configs.size(); +} + +int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id, + const EVP_HPKE_KEY *key, const char *public_name, + size_t max_name_len) { + Span public_name_u8 = MakeConstSpan( + reinterpret_cast(public_name), strlen(public_name)); + if (!ssl_is_valid_ech_public_name(public_name_u8)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_PUBLIC_NAME); + return 0; + } + + // The maximum name length is encoded in one byte. + if (max_name_len > 0xff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return 0; + } + + // See draft-ietf-tls-esni-13, section 4. + ScopedCBB cbb; + CBB contents, child; + uint8_t *public_key; + size_t public_key_len; + if (!CBB_init(cbb.get(), 128) || // + !CBB_add_u16(cbb.get(), kECHConfigVersion) || + !CBB_add_u16_length_prefixed(cbb.get(), &contents) || + !CBB_add_u8(&contents, config_id) || + !CBB_add_u16(&contents, EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key))) || + !CBB_add_u16_length_prefixed(&contents, &child) || + !CBB_reserve(&child, &public_key, EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) || + !EVP_HPKE_KEY_public_key(key, public_key, &public_key_len, + EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) || + !CBB_did_write(&child, public_key_len) || + !CBB_add_u16_length_prefixed(&contents, &child) || + // Write a default cipher suite configuration. + !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) || + !CBB_add_u16(&child, EVP_HPKE_AES_128_GCM) || + !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) || + !CBB_add_u16(&child, EVP_HPKE_CHACHA20_POLY1305) || + !CBB_add_u8(&contents, max_name_len) || + !CBB_add_u8_length_prefixed(&contents, &child) || + !CBB_add_bytes(&child, public_name_u8.data(), public_name_u8.size()) || + // TODO(https://crbug.com/boringssl/275): Reserve some GREASE extensions + // and include some. + !CBB_add_u16(&contents, 0 /* no extensions */) || + !CBB_finish(cbb.get(), out, out_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +SSL_ECH_KEYS *SSL_ECH_KEYS_new() { return New(); } + +void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys) { + CRYPTO_refcount_inc(&keys->references); +} + +void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys) { + if (keys == nullptr || + !CRYPTO_refcount_dec_and_test_zero(&keys->references)) { + return; + } + + keys->~ssl_ech_keys_st(); + OPENSSL_free(keys); +} + +int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config, + const uint8_t *ech_config, size_t ech_config_len, + const EVP_HPKE_KEY *key) { + UniquePtr parsed_config = MakeUnique(); + if (!parsed_config) { + return 0; + } + if (!parsed_config->Init(MakeConstSpan(ech_config, ech_config_len), key, + !!is_retry_config)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + if (!configs->configs.Push(std::move(parsed_config))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys) { + bool seen[256] = {false}; + for (const auto &config : keys->configs) { + if (seen[config->ech_config().config_id]) { + return 1; + } + seen[config->ech_config().config_id] = true; + } + return 0; +} + +int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out, + size_t *out_len) { + ScopedCBB cbb; + CBB child; + if (!CBB_init(cbb.get(), 128) || + !CBB_add_u16_length_prefixed(cbb.get(), &child)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + for (const auto &config : keys->configs) { + if (config->is_retry_config() && + !CBB_add_bytes(&child, config->ech_config().raw.data(), + config->ech_config().raw.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + return CBB_finish(cbb.get(), out, out_len); +} + +int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys) { + bool has_retry_config = false; + for (const auto &config : keys->configs) { + if (config->is_retry_config()) { + has_retry_config = true; + break; + } + } + if (!has_retry_config) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS); + return 0; + } + UniquePtr owned_keys = UpRef(keys); + MutexWriteLock lock(&ctx->lock); + ctx->ech_keys.swap(owned_keys); + return 1; +} + +int SSL_ech_accepted(const SSL *ssl) { + if (SSL_in_early_data(ssl) && !ssl->server) { + // In the client early data state, we report properties as if the server + // accepted early data. The server can only accept early data with + // ClientHelloInner. + return ssl->s3->hs->selected_ech_config != nullptr; + } + + return ssl->s3->ech_status == ssl_ech_accepted; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/extensions.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/extensions.cc new file mode 100644 index 00000000..45bc70e9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/extensions.cc @@ -0,0 +1,4325 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs); +static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs); + +static int compare_uint16_t(const void *p1, const void *p2) { + uint16_t u1 = *((const uint16_t *)p1); + uint16_t u2 = *((const uint16_t *)p2); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +// Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be +// more than one extension of the same type in a ClientHello or ServerHello. +// This function does an initial scan over the extensions block to filter those +// out. +static bool tls1_check_duplicate_extensions(const CBS *cbs) { + // First pass: count the extensions. + size_t num_extensions = 0; + CBS extensions = *cbs; + while (CBS_len(&extensions) > 0) { + uint16_t type; + CBS extension; + + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return false; + } + + num_extensions++; + } + + if (num_extensions == 0) { + return true; + } + + Array extension_types; + if (!extension_types.Init(num_extensions)) { + return false; + } + + // Second pass: gather the extension types. + extensions = *cbs; + for (size_t i = 0; i < extension_types.size(); i++) { + CBS extension; + + if (!CBS_get_u16(&extensions, &extension_types[i]) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + // This should not happen. + return false; + } + } + assert(CBS_len(&extensions) == 0); + + // Sort the extensions and make sure there are no duplicates. + qsort(extension_types.data(), extension_types.size(), sizeof(uint16_t), + compare_uint16_t); + for (size_t i = 1; i < num_extensions; i++) { + if (extension_types[i - 1] == extension_types[i]) { + return false; + } + } + + return true; +} + +static bool is_post_quantum_group(uint16_t id) { + return id == SSL_CURVE_CECPQ2; +} + +bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, + Span body) { + CBS cbs = body; + if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs, out) || + CBS_len(&cbs) != 0) { + return false; + } + return true; +} + +bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, + SSL_CLIENT_HELLO *out) { + OPENSSL_memset(out, 0, sizeof(*out)); + out->ssl = const_cast(ssl); + + CBS copy = *cbs; + CBS random, session_id; + if (!CBS_get_u16(cbs, &out->version) || + !CBS_get_bytes(cbs, &random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(cbs, &session_id) || + CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return false; + } + + out->random = CBS_data(&random); + out->random_len = CBS_len(&random); + out->session_id = CBS_data(&session_id); + out->session_id_len = CBS_len(&session_id); + + // Skip past DTLS cookie + if (SSL_is_dtls(out->ssl)) { + CBS cookie; + if (!CBS_get_u8_length_prefixed(cbs, &cookie) || + CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) { + return false; + } + } + + CBS cipher_suites, compression_methods; + if (!CBS_get_u16_length_prefixed(cbs, &cipher_suites) || + CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 || + !CBS_get_u8_length_prefixed(cbs, &compression_methods) || + CBS_len(&compression_methods) < 1) { + return false; + } + + out->cipher_suites = CBS_data(&cipher_suites); + out->cipher_suites_len = CBS_len(&cipher_suites); + out->compression_methods = CBS_data(&compression_methods); + out->compression_methods_len = CBS_len(&compression_methods); + + // If the ClientHello ends here then it's valid, but doesn't have any + // extensions. + if (CBS_len(cbs) == 0) { + out->extensions = nullptr; + out->extensions_len = 0; + } else { + // Extract extensions and check it is valid. + CBS extensions; + if (!CBS_get_u16_length_prefixed(cbs, &extensions) || + !tls1_check_duplicate_extensions(&extensions)) { + return false; + } + out->extensions = CBS_data(&extensions); + out->extensions_len = CBS_len(&extensions); + } + + out->client_hello = CBS_data(©); + out->client_hello_len = CBS_len(©) - CBS_len(cbs); + return true; +} + +bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type) { + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + // Decode the next extension. + uint16_t type; + CBS extension; + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return false; + } + + if (type == extension_type) { + *out = extension; + return true; + } + } + + return false; +} + +static const uint16_t kDefaultGroups[] = { + SSL_CURVE_X25519, + SSL_CURVE_SECP256R1, + SSL_CURVE_SECP384R1, +}; + +Span tls1_get_grouplist(const SSL_HANDSHAKE *hs) { + if (!hs->config->supported_group_list.empty()) { + return hs->config->supported_group_list; + } + return Span(kDefaultGroups); +} + +bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { + SSL *const ssl = hs->ssl; + assert(ssl->server); + + // Clients are not required to send a supported_groups extension. In this + // case, the server is free to pick any group it likes. See RFC 4492, + // section 4, paragraph 3. + // + // However, in the interests of compatibility, we will skip ECDH if the + // client didn't send an extension because we can't be sure that they'll + // support our favoured group. Thus we do not special-case an emtpy + // |peer_supported_group_list|. + + Span groups = tls1_get_grouplist(hs); + Span pref, supp; + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + pref = groups; + supp = hs->peer_supported_group_list; + } else { + pref = hs->peer_supported_group_list; + supp = groups; + } + + for (uint16_t pref_group : pref) { + for (uint16_t supp_group : supp) { + if (pref_group == supp_group && + // CECPQ2(b) doesn't fit in the u8-length-prefixed ECPoint field in + // TLS 1.2 and below. + (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + !is_post_quantum_group(pref_group))) { + *out_group_id = pref_group; + return true; + } + } + } + + return false; +} + +bool tls1_set_curves(Array *out_group_ids, Span curves) { + Array group_ids; + if (!group_ids.Init(curves.size())) { + return false; + } + + for (size_t i = 0; i < curves.size(); i++) { + if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) { + return false; + } + } + + *out_group_ids = std::move(group_ids); + return true; +} + +bool tls1_set_curves_list(Array *out_group_ids, const char *curves) { + // Count the number of curves in the list. + size_t count = 0; + const char *ptr = curves, *col; + do { + col = strchr(ptr, ':'); + count++; + if (col) { + ptr = col + 1; + } + } while (col); + + Array group_ids; + if (!group_ids.Init(count)) { + return false; + } + + size_t i = 0; + ptr = curves; + do { + col = strchr(ptr, ':'); + if (!ssl_name_to_group_id(&group_ids[i++], ptr, + col ? (size_t)(col - ptr) : strlen(ptr))) { + return false; + } + if (col) { + ptr = col + 1; + } + } while (col); + + assert(i == count); + *out_group_ids = std::move(group_ids); + return true; +} + +bool tls1_check_group_id(const SSL_HANDSHAKE *hs, uint16_t group_id) { + if (is_post_quantum_group(group_id) && + ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) { + // CECPQ2(b) requires TLS 1.3. + return false; + } + + // We internally assume zero is never allocated as a group ID. + if (group_id == 0) { + return false; + } + + for (uint16_t supported : tls1_get_grouplist(hs)) { + if (supported == group_id) { + return true; + } + } + + return false; +} + +// kVerifySignatureAlgorithms is the default list of accepted signature +// algorithms for verifying. +static const uint16_t kVerifySignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_RSAE_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // Larger hashes are acceptable. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_RSA_PSS_RSAE_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // For now, SHA-1 is still accepted but least preferable. + SSL_SIGN_RSA_PKCS1_SHA1, +}; + +// kSignSignatureAlgorithms is the default list of supported signature +// algorithms for signing. +static const uint16_t kSignSignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ED25519, + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_RSAE_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // If needed, sign larger hashes. + // + // TODO(davidben): Determine which of these may be pruned. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_ECDSA_SECP521R1_SHA512, + SSL_SIGN_RSA_PSS_RSAE_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // If the peer supports nothing else, sign with SHA-1. + SSL_SIGN_ECDSA_SHA1, + SSL_SIGN_RSA_PKCS1_SHA1, +}; + +static Span tls12_get_verify_sigalgs(const SSL_HANDSHAKE *hs) { + if (hs->config->verify_sigalgs.empty()) { + return Span(kVerifySignatureAlgorithms); + } + return hs->config->verify_sigalgs; +} + +bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out) { + for (uint16_t sigalg : tls12_get_verify_sigalgs(hs)) { + if (!CBB_add_u16(out, sigalg)) { + return false; + } + } + return true; +} + +bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t sigalg) { + for (uint16_t verify_sigalg : tls12_get_verify_sigalgs(hs)) { + if (verify_sigalg == sigalg) { + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// tls_extension represents a TLS extension that is handled internally. +// +// The parse callbacks receive a |CBS| that contains the contents of the +// extension (i.e. not including the type and length bytes). If an extension is +// not received then the parse callbacks will be called with a NULL CBS so that +// they can do any processing needed to handle the absence of an extension. +// +// The add callbacks receive a |CBB| to which the extension can be appended but +// the function is responsible for appending the type and length bytes too. +// +// |add_clienthello| may be called multiple times and must not mutate |hs|. It +// is additionally passed two output |CBB|s. If the extension is the same +// independent of the value of |type|, the callback may write to +// |out_compressible| instead of |out|. When serializing the ClientHelloInner, +// all compressible extensions will be made continguous and replaced with +// ech_outer_extensions when encrypted. When serializing the ClientHelloOuter +// or not offering ECH, |out| will be equal to |out_compressible|, so writing to +// |out_compressible| still works. +// +// Note the |parse_serverhello| and |add_serverhello| callbacks refer to the +// TLS 1.2 ServerHello. In TLS 1.3, these callbacks act on EncryptedExtensions, +// with ServerHello extensions handled elsewhere in the handshake. +// +// All callbacks return true for success and false for error. If a parse +// function returns zero then a fatal alert with value |*out_alert| will be +// sent. If |*out_alert| isn't set, then a |decode_error| alert will be sent. +struct tls_extension { + uint16_t value; + + bool (*add_clienthello)(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, ssl_client_hello_type_t type); + bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + + bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out); +}; + +static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents != NULL) { + // Servers MUST NOT send this extension. + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + return true; +} + +static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // This extension from the client is handled elsewhere. + return true; +} + +static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; +} + +// Server name indication (SNI). +// +// https://tools.ietf.org/html/rfc6066#section-3. + +static bool ext_sni_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + // If offering ECH, send the public name instead of the configured name. + Span hostname; + if (type == ssl_client_hello_outer) { + hostname = hs->selected_ech_config->public_name; + } else { + if (ssl->hostname == nullptr) { + return true; + } + hostname = + MakeConstSpan(reinterpret_cast(ssl->hostname.get()), + strlen(ssl->hostname.get())); + } + + CBB contents, server_name_list, name; + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &server_name_list) || + !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) || + !CBB_add_u16_length_prefixed(&server_name_list, &name) || + !CBB_add_bytes(&name, hostname.data(), hostname.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // The server may acknowledge SNI with an empty extension. We check the syntax + // but otherwise ignore this signal. + return contents == NULL || CBS_len(contents) == 0; +} + +static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // SNI has already been parsed earlier in the handshake. See |extract_sni|. + return true; +} + +static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (hs->ssl->s3->session_reused || + !hs->should_ack_sni) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Encrypted ClientHello (ECH) +// +// https://tools.ietf.org/html/draft-ietf-tls-esni-13 + +static bool ext_ech_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (type == ssl_client_hello_inner) { + if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) || + !CBB_add_u16(out, /* length */ 1) || + !CBB_add_u8(out, ECH_CLIENT_INNER)) { + return false; + } + return true; + } + + if (hs->ech_client_outer.empty()) { + return true; + } + + CBB ech_body; + if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) || + !CBB_add_u16_length_prefixed(out, &ech_body) || + !CBB_add_u8(&ech_body, ECH_CLIENT_OUTER) || + !CBB_add_bytes(&ech_body, hs->ech_client_outer.data(), + hs->ech_client_outer.size()) || + !CBB_flush(out)) { + return false; + } + return true; +} + +static bool ext_ech_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // The ECH extension may not be sent in TLS 1.2 ServerHello, only TLS 1.3 + // EncryptedExtensions. It also may not be sent in response to an inner ECH + // extension. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION || + ssl->s3->ech_status == ssl_ech_accepted) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + if (!ssl_is_valid_ech_config_list(*contents)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (ssl->s3->ech_status == ssl_ech_rejected && + !hs->ech_retry_configs.CopyFrom(*contents)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + return true; +} + +static bool ext_ech_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr) { + return true; + } + + uint8_t type; + if (!CBS_get_u8(contents, &type)) { + return false; + } + if (type == ECH_CLIENT_OUTER) { + // Outer ECH extensions are handled outside the callback. + return true; + } + if (type != ECH_CLIENT_INNER || CBS_len(contents) != 0) { + return false; + } + + hs->ech_is_inner = true; + return true; +} + +static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) < TLS1_3_VERSION || + ssl->s3->ech_status == ssl_ech_accepted || // + hs->ech_keys == nullptr) { + return true; + } + + // Write the list of retry configs to |out|. Note |SSL_CTX_set1_ech_keys| + // ensures |ech_keys| contains at least one retry config. + CBB body, retry_configs; + if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) || + !CBB_add_u16_length_prefixed(out, &body) || + !CBB_add_u16_length_prefixed(&body, &retry_configs)) { + return false; + } + for (const auto &config : hs->ech_keys->configs) { + if (!config->is_retry_config()) { + continue; + } + if (!CBB_add_bytes(&retry_configs, config->ech_config().raw.data(), + config->ech_config().raw.size())) { + return false; + } + } + return CBB_flush(out); +} + + +// Renegotiation indication. +// +// https://tools.ietf.org/html/rfc5746 + +static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + // Renegotiation indication is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION || + type == ssl_client_hello_inner) { + return true; + } + + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + + CBB contents, prev_finished; + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &prev_finished) || + !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents != NULL && ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Servers may not switch between omitting the extension and supporting it. + // See RFC 5746, sections 3.5 and 4.2. + if (ssl->s3->initial_handshake_complete && + (contents != NULL) != ssl->s3->send_connection_binding) { + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + return false; + } + + if (contents == NULL) { + // Strictly speaking, if we want to avoid an attack we should *always* see + // RI even on initial ServerHello because the client doesn't see any + // renegotiation during an attack. However this would mean we could not + // connect to any server which doesn't support RI. + // + // OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in + // practical terms every client sets it so it's just assumed here. + return true; + } + + const size_t expected_len = ssl->s3->previous_client_finished_len + + ssl->s3->previous_server_finished_len; + + // Check for logic errors + assert(!expected_len || ssl->s3->previous_client_finished_len); + assert(!expected_len || ssl->s3->previous_server_finished_len); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_server_finished_len != 0)); + + // Parse out the extension contents. + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Check that the extension matches. + if (CBS_len(&renegotiated_connection) != expected_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + const uint8_t *d = CBS_data(&renegotiated_connection); + bool ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + d += ssl->s3->previous_client_finished_len; + + ok = CRYPTO_memcmp(d, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + return false; + } + + // Check that the extension matches. We do not support renegotiation as a + // server, so this must be empty. + if (CBS_len(&renegotiated_connection) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16(out, 1 /* length */) || + !CBB_add_u8(out, 0 /* empty renegotiation info */)) { + return false; + } + + return true; +} + + +// Extended Master Secret. +// +// https://tools.ietf.org/html/rfc7627 + +static bool ext_ems_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + // Extended master secret is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + + if (contents != NULL) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + } + + // Whether EMS is negotiated may not change on renegotiation. + if (ssl->s3->established_session != nullptr && + hs->extended_master_secret != + !!ssl->s3->established_session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + return true; +} + +static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->extended_master_secret) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Session tickets. +// +// https://tools.ietf.org/html/rfc5077 + +static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + // TLS 1.3 uses a different ticket extension. + if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner || + SSL_get_options(ssl) & SSL_OP_NO_TICKET) { + return true; + } + + Span ticket; + + // Renegotiation does not participate in session resumption. However, still + // advertise the extension to avoid potentially breaking servers which carry + // over the state from the previous handshake, such as OpenSSL servers + // without upstream's 3c3f0259238594d77264a78944d409f2127642c4. + if (!ssl->s3->initial_handshake_complete && + ssl->session != nullptr && + !ssl->session->ticket.empty() && + // Don't send TLS 1.3 session tickets in the ticket extension. + ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION) { + ticket = ssl->session->ticket; + } + + CBB ticket_cbb; + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16_length_prefixed(out, &ticket_cbb) || + !CBB_add_bytes(&ticket_cbb, ticket.data(), ticket.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If |SSL_OP_NO_TICKET| is set then no extension will have been sent and + // this function should never be called, even if the server tries to send the + // extension. + assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0); + + if (CBS_len(contents) != 0) { + return false; + } + + hs->ticket_expected = true; + return true; +} + +static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ticket_expected) { + return true; + } + + // If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true. + assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0); + + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Signature Algorithms. +// +// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + +static bool ext_sigalgs_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (hs->max_version < TLS1_2_VERSION) { + return true; + } + + CBB contents, sigalgs_cbb; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(hs, &sigalgs_cbb) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + hs->peer_sigalgs.Reset(); + if (contents == NULL) { + return true; + } + + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) || + CBS_len(contents) != 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + return false; + } + + return true; +} + + +// OCSP Stapling. +// +// https://tools.ietf.org/html/rfc6066#section-8 + +static bool ext_ocsp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (!hs->config->ocsp_stapling_enabled) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u16(&contents, 0 /* empty responder ID list */) || + !CBB_add_u16(&contents, 0 /* empty request extensions */) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 OCSP responses are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // OCSP stapling is forbidden on non-certificate ciphers. + if (CBS_len(contents) != 0 || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return false; + } + + // Note this does not check for resumption in TLS 1.2. Sending + // status_request here does not make sense, but OpenSSL does so and the + // specification does not say anything. Tolerate it but ignore it. + + hs->certificate_status_expected = true; + return true; +} + +static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + uint8_t status_type; + if (!CBS_get_u8(contents, &status_type)) { + return false; + } + + // We cannot decide whether OCSP stapling will occur yet because the correct + // SSL_CTX might not have been selected. + hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp; + + return true; +} + +static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + !hs->ocsp_stapling_requested || hs->config->cert->ocsp_response == NULL || + ssl->s3->session_reused || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return true; + } + + hs->certificate_status_expected = true; + + return CBB_add_u16(out, TLSEXT_TYPE_status_request) && + CBB_add_u16(out, 0 /* length */); +} + + +// Next protocol negotiation. +// +// https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html + +static bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (ssl->ctx->next_proto_select_cb == NULL || + // Do not allow NPN to change on renegotiation. + ssl->s3->initial_handshake_complete || + // NPN is not defined in DTLS or TLS 1.3. + SSL_is_dtls(ssl) || hs->min_version >= TLS1_3_VERSION || + type == ssl_client_hello_inner) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If any of these are false then we should never have sent the NPN + // extension in the ClientHello and thus this function should never have been + // called. + assert(!ssl->s3->initial_handshake_complete); + assert(!SSL_is_dtls(ssl)); + assert(ssl->ctx->next_proto_select_cb != NULL); + + if (!ssl->s3->alpn_selected.empty()) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + const uint8_t *const orig_contents = CBS_data(contents); + const size_t orig_len = CBS_len(contents); + + while (CBS_len(contents) != 0) { + CBS proto; + if (!CBS_get_u8_length_prefixed(contents, &proto) || + CBS_len(&proto) == 0) { + return false; + } + } + + uint8_t *selected; + uint8_t selected_len; + if (ssl->ctx->next_proto_select_cb( + ssl, &selected, &selected_len, orig_contents, orig_len, + ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK || + !ssl->s3->next_proto_negotiated.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents != NULL && CBS_len(contents) != 0) { + return false; + } + + if (contents == NULL || + ssl->s3->initial_handshake_complete || + ssl->ctx->next_protos_advertised_cb == NULL || + SSL_is_dtls(ssl)) { + return true; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // |next_proto_neg_seen| might have been cleared when an ALPN extension was + // parsed. + if (!hs->next_proto_neg_seen) { + return true; + } + + const uint8_t *npa; + unsigned npa_len; + + if (ssl->ctx->next_protos_advertised_cb( + ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) != + SSL_TLSEXT_ERR_OK) { + hs->next_proto_neg_seen = false; + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, npa, npa_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Signed certificate timestamps. +// +// https://tools.ietf.org/html/rfc6962#section-3.3.1 + +static bool ext_sct_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (!hs->config->signed_cert_timestamps_enabled) { + return true; + } + + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16(out_compressible, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 SCTs are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If this is false then we should never have sent the SCT extension in the + // ClientHello and thus this function should never have been called. + assert(hs->config->signed_cert_timestamps_enabled); + + if (!ssl_is_sct_list_valid(contents)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Session resumption uses the original session information. The extension + // should not be sent on resumption, but RFC 6962 did not make it a + // requirement, so tolerate this. + // + // TODO(davidben): Enforce this anyway. + if (!ssl->s3->session_reused) { + hs->new_session->signed_cert_timestamp_list.reset( + CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool)); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + + return true; +} + +static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->scts_requested = true; + return true; +} + +static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // The extension shouldn't be sent when resuming sessions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || ssl->s3->session_reused || + hs->config->cert->signed_cert_timestamp_list == NULL) { + return true; + } + + CBB contents; + return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) && + CBB_add_u16_length_prefixed(out, &contents) && + CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data( + hs->config->cert->signed_cert_timestamp_list.get()), + CRYPTO_BUFFER_len( + hs->config->cert->signed_cert_timestamp_list.get())) && + CBB_flush(out); +} + + +// Application-level Protocol Negotiation. +// +// https://tools.ietf.org/html/rfc7301 + +static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (hs->config->alpn_client_proto_list.empty() && ssl->quic_method) { + // ALPN MUST be used with QUIC. + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL); + return false; + } + + if (hs->config->alpn_client_proto_list.empty() || + ssl->s3->initial_handshake_complete) { + return true; + } + + CBB contents, proto_list; + if (!CBB_add_u16(out_compressible, + TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_bytes(&proto_list, hs->config->alpn_client_proto_list.data(), + hs->config->alpn_client_proto_list.size()) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + if (ssl->quic_method) { + // ALPN is required when QUIC is used. + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL); + *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL; + return false; + } + return true; + } + + assert(!ssl->s3->initial_handshake_complete); + assert(!hs->config->alpn_client_proto_list.empty()); + + if (hs->next_proto_neg_seen) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + // The extension data consists of a ProtocolNameList which must have + // exactly one ProtocolName. Each of these is length-prefixed. + CBS protocol_name_list, protocol_name; + if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) || + CBS_len(contents) != 0 || + !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0 || + CBS_len(&protocol_name_list) != 0) { + return false; + } + + if (!ssl_is_alpn_protocol_allowed(hs, protocol_name)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + if (!ssl->s3->alpn_selected.CopyFrom(protocol_name)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + return true; +} + +bool ssl_is_valid_alpn_list(Span in) { + CBS protocol_name_list = in; + if (CBS_len(&protocol_name_list) == 0) { + return false; + } + while (CBS_len(&protocol_name_list) > 0) { + CBS protocol_name; + if (!CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0) { + return false; + } + } + return true; +} + +bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs, + Span protocol) { + if (hs->config->alpn_client_proto_list.empty()) { + return false; + } + + if (hs->ssl->ctx->allow_unknown_alpn_protos) { + return true; + } + + // Check that the protocol name is one of the ones we advertised. + CBS client_protocol_name_list = + MakeConstSpan(hs->config->alpn_client_proto_list), + client_protocol_name; + while (CBS_len(&client_protocol_name_list) > 0) { + if (!CBS_get_u8_length_prefixed(&client_protocol_name_list, + &client_protocol_name)) { + return false; + } + + if (client_protocol_name == protocol) { + return true; + } + } + + return false; +} + +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + CBS contents; + if (ssl->ctx->alpn_select_cb == NULL || + !ssl_client_hello_get_extension( + client_hello, &contents, + TLSEXT_TYPE_application_layer_protocol_negotiation)) { + if (ssl->quic_method) { + // ALPN is required when QUIC is used. + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL); + *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL; + return false; + } + // Ignore ALPN if not configured or no extension was supplied. + return true; + } + + // ALPN takes precedence over NPN. + hs->next_proto_neg_seen = false; + + CBS protocol_name_list; + if (!CBS_get_u16_length_prefixed(&contents, &protocol_name_list) || + CBS_len(&contents) != 0 || + !ssl_is_valid_alpn_list(protocol_name_list)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + const uint8_t *selected; + uint8_t selected_len; + int ret = ssl->ctx->alpn_select_cb( + ssl, &selected, &selected_len, CBS_data(&protocol_name_list), + CBS_len(&protocol_name_list), ssl->ctx->alpn_select_cb_arg); + // ALPN is required when QUIC is used. + if (ssl->quic_method && + (ret == SSL_TLSEXT_ERR_NOACK || ret == SSL_TLSEXT_ERR_ALERT_WARNING)) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + switch (ret) { + case SSL_TLSEXT_ERR_OK: + if (selected_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + if (!ssl->s3->alpn_selected.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + break; + case SSL_TLSEXT_ERR_NOACK: + case SSL_TLSEXT_ERR_ALERT_WARNING: + break; + case SSL_TLSEXT_ERR_ALERT_FATAL: + *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL; + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL); + return false; + default: + // Invalid return value. + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->alpn_selected.empty()) { + return true; + } + + CBB contents, proto_list, proto; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_u8_length_prefixed(&proto_list, &proto) || + !CBB_add_bytes(&proto, ssl->s3->alpn_selected.data(), + ssl->s3->alpn_selected.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Channel ID. +// +// https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 + +static bool ext_channel_id_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (!hs->config->channel_id_private || SSL_is_dtls(ssl) || + // Don't offer Channel ID in ClientHelloOuter. ClientHelloOuter handshakes + // are not authenticated for the name that can learn the Channel ID. + // + // We could alternatively offer the extension but sign with a random key. + // For other extensions, we try to align |ssl_client_hello_outer| and + // |ssl_client_hello_unencrypted|, to improve the effectiveness of ECH + // GREASE. However, Channel ID is deprecated and unlikely to be used with + // ECH, so do the simplest thing. + type == ssl_client_hello_outer) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + assert(!SSL_is_dtls(hs->ssl)); + assert(hs->config->channel_id_private); + + if (CBS_len(contents) != 0) { + return false; + } + + hs->channel_id_negotiated = true; + return true; +} + +static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || !hs->config->channel_id_enabled || SSL_is_dtls(ssl)) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->channel_id_negotiated = true; + return true; +} + +static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->channel_id_negotiated) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Secure Real-time Transport Protocol (SRTP) extension. +// +// https://tools.ietf.org/html/rfc5764 + +static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + const STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = + SSL_get_srtp_profiles(ssl); + if (profiles == NULL || + sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0 || + !SSL_is_dtls(ssl)) { + return true; + } + + CBB contents, profile_ids; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids)) { + return false; + } + + for (const SRTP_PROTECTION_PROFILE *profile : profiles) { + if (!CBB_add_u16(&profile_ids, profile->id)) { + return false; + } + } + + if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // The extension consists of a u16-prefixed profile ID list containing a + // single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field. + // + // See https://tools.ietf.org/html/rfc5764#section-4.1.1 + assert(SSL_is_dtls(ssl)); + CBS profile_ids, srtp_mki; + uint16_t profile_id; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + !CBS_get_u16(&profile_ids, &profile_id) || + CBS_len(&profile_ids) != 0 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + + if (CBS_len(&srtp_mki) != 0) { + // Must be no MKI, since we never offer one. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Check to see if the server gave us something we support and offered. + for (const SRTP_PROTECTION_PROFILE *profile : SSL_get_srtp_profiles(ssl)) { + if (profile->id == profile_id) { + ssl->s3->srtp_profile = profile; + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + // DTLS-SRTP is only defined for DTLS. + if (contents == NULL || !SSL_is_dtls(ssl)) { + return true; + } + + CBS profile_ids, srtp_mki; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + CBS_len(&profile_ids) < 2 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + // Discard the MKI value for now. + + const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles = + SSL_get_srtp_profiles(ssl); + + // Pick the server's most preferred profile. + for (const SRTP_PROTECTION_PROFILE *server_profile : server_profiles) { + CBS profile_ids_tmp; + CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids)); + + while (CBS_len(&profile_ids_tmp) > 0) { + uint16_t profile_id; + if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) { + return false; + } + + if (server_profile->id == profile_id) { + ssl->s3->srtp_profile = server_profile; + return true; + } + } + } + + return true; +} + +static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->srtp_profile == NULL) { + return true; + } + + assert(SSL_is_dtls(ssl)); + CBB contents, profile_ids; + if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids) || + !CBB_add_u16(&profile_ids, ssl->s3->srtp_profile->id) || + !CBB_add_u8(&contents, 0 /* empty MKI */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// EC point formats. +// +// https://tools.ietf.org/html/rfc4492#section-5.1.2 + +static bool ext_ec_point_add_extension(const SSL_HANDSHAKE *hs, CBB *out) { + CBB contents, formats; + if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &formats) || + !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ec_point_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + // The point format extension is unnecessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + +static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return false; + } + + CBS ec_point_format_list; + if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) || + CBS_len(contents) != 0) { + return false; + } + + // Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed + // point format. + if (OPENSSL_memchr(CBS_data(&ec_point_format_list), + TLSEXT_ECPOINTFORMAT_uncompressed, + CBS_len(&ec_point_format_list)) == NULL) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return true; + } + + return ext_ec_point_parse_serverhello(hs, out_alert, contents); +} + +static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + const uint32_t alg_k = hs->new_cipher->algorithm_mkey; + const uint32_t alg_a = hs->new_cipher->algorithm_auth; + const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA); + + if (!using_ecc) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + + +// Pre Shared Key +// +// https://tools.ietf.org/html/rfc8446#section-4.2.11 + +static bool should_offer_psk(const SSL_HANDSHAKE *hs, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_3_VERSION || ssl->session == nullptr || + ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION || + // TODO(https://crbug.com/boringssl/275): Should we synthesize a + // placeholder PSK, at least when we offer early data? Otherwise + // ClientHelloOuter will contain an early_data extension without a + // pre_shared_key extension and potentially break the recovery flow. + type == ssl_client_hello_outer) { + return false; + } + + // Per RFC 8446 section 4.1.4, skip offering the session if the selected + // cipher in HelloRetryRequest does not match. This avoids performing the + // transcript hash transformation for multiple hashes. + if (ssl->s3->used_hello_retry_request && + ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) { + return false; + } + + return true; +} + +static size_t ext_pre_shared_key_clienthello_length( + const SSL_HANDSHAKE *hs, ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (!should_offer_psk(hs, type)) { + return 0; + } + + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session.get())); + return 15 + ssl->session->ticket.size() + binder_len; +} + +static bool ext_pre_shared_key_add_clienthello(const SSL_HANDSHAKE *hs, + CBB *out, bool *out_needs_binder, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + *out_needs_binder = false; + if (!should_offer_psk(hs, type)) { + return true; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + uint32_t ticket_age = 1000 * (now.tv_sec - ssl->session->time); + uint32_t obfuscated_ticket_age = ticket_age + ssl->session->ticket_age_add; + + // Fill in a placeholder zero binder of the appropriate length. It will be + // computed and filled in later after length prefixes are computed. + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session.get())); + + CBB contents, identity, ticket, binders, binder; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &identity) || + !CBB_add_u16_length_prefixed(&identity, &ticket) || + !CBB_add_bytes(&ticket, ssl->session->ticket.data(), + ssl->session->ticket.size()) || + !CBB_add_u32(&identity, obfuscated_ticket_age) || + !CBB_add_u16_length_prefixed(&contents, &binders) || + !CBB_add_u8_length_prefixed(&binders, &binder) || + !CBB_add_zeros(&binder, binder_len)) { + return false; + } + + *out_needs_binder = true; + return CBB_flush(out); +} + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + uint16_t psk_id; + if (!CBS_get_u16(contents, &psk_id) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only advertise one PSK identity, so the only legal index is zero. + if (psk_id != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello, CBS *contents) { + // Verify that the pre_shared_key extension is the last extension in + // ClientHello. + if (CBS_data(contents) + CBS_len(contents) != + client_hello->extensions + client_hello->extensions_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // We only process the first PSK identity since we don't support pure PSK. + CBS identities, binders; + if (!CBS_get_u16_length_prefixed(contents, &identities) || + !CBS_get_u16_length_prefixed(&identities, out_ticket) || + !CBS_get_u32(&identities, out_obfuscated_ticket_age) || + !CBS_get_u16_length_prefixed(contents, &binders) || + CBS_len(&binders) == 0 || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + *out_binders = binders; + + // Check the syntax of the remaining identities, but do not process them. + size_t num_identities = 1; + while (CBS_len(&identities) != 0) { + CBS unused_ticket; + uint32_t unused_obfuscated_ticket_age; + if (!CBS_get_u16_length_prefixed(&identities, &unused_ticket) || + !CBS_get_u32(&identities, &unused_obfuscated_ticket_age)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_identities++; + } + + // Check the syntax of the binders. The value will be checked later if + // resuming. + size_t num_binders = 0; + while (CBS_len(&binders) != 0) { + CBS binder; + if (!CBS_get_u8_length_prefixed(&binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_binders++; + } + + if (num_identities != num_binders) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->session_reused) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + // We only consider the first identity for resumption + !CBB_add_u16(&contents, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Pre-Shared Key Exchange Modes +// +// https://tools.ietf.org/html/rfc8446#section-4.2.9 + +static bool ext_psk_key_exchange_modes_add_clienthello( + const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible, + ssl_client_hello_type_t type) { + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + CBB contents, ke_modes; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_psk_key_exchange_modes) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u8_length_prefixed(&contents, &ke_modes) || + !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) { + return false; + } + + return CBB_flush(out_compressible); +} + +static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS ke_modes; + if (!CBS_get_u8_length_prefixed(contents, &ke_modes) || + CBS_len(&ke_modes) == 0 || + CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only support tickets with PSK_DHE_KE. + hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE, + CBS_len(&ke_modes)) != NULL; + + return true; +} + + +// Early Data Indication +// +// https://tools.ietf.org/html/rfc8446#section-4.2.10 + +static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + // The second ClientHello never offers early data, and we must have already + // filled in |early_data_reason| by this point. + if (ssl->s3->used_hello_retry_request) { + assert(ssl->s3->early_data_reason != ssl_early_data_unknown); + return true; + } + + if (!hs->early_data_offered) { + return true; + } + + // If offering ECH, the extension only applies to ClientHelloInner, but we + // send the extension in both ClientHellos. This ensures that, if the server + // handshakes with ClientHelloOuter, it can skip past early data. See + // draft-ietf-tls-esni-13, section 6.1. + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out_compressible, 0) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + if (hs->early_data_offered && !ssl->s3->used_hello_retry_request) { + ssl->s3->early_data_reason = ssl->s3->session_reused + ? ssl_early_data_peer_declined + : ssl_early_data_session_not_resumed; + } else { + // We already filled in |early_data_reason| when declining to offer 0-RTT + // or handling the implicit HelloRetryRequest reject. + assert(ssl->s3->early_data_reason != ssl_early_data_unknown); + } + return true; + } + + // If we received an HRR, the second ClientHello never offers early data, so + // the extensions logic will automatically reject early data extensions as + // unsolicited. This covered by the ServerAcceptsEarlyDataOnHRR test. + assert(!ssl->s3->used_hello_retry_request); + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (!ssl->s3->session_reused) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + ssl->s3->early_data_reason = ssl_early_data_accepted; + ssl->s3->early_data_accepted = true; + return true; +} + +static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || + ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return true; + } + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + hs->early_data_offered = true; + return true; +} + +static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->early_data_accepted) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Key Share +// +// https://tools.ietf.org/html/rfc8446#section-4.2.8 + +bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { + SSL *const ssl = hs->ssl; + hs->key_shares[0].reset(); + hs->key_shares[1].reset(); + hs->key_share_bytes.Reset(); + + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64)) { + return false; + } + + if (override_group_id == 0 && ssl->ctx->grease_enabled) { + // Add a fake group. See RFC 8701. + if (!CBB_add_u16(cbb.get(), ssl_get_grease_value(hs, ssl_grease_group)) || + !CBB_add_u16(cbb.get(), 1 /* length */) || + !CBB_add_u8(cbb.get(), 0 /* one byte key share */)) { + return false; + } + } + + uint16_t group_id = override_group_id; + uint16_t second_group_id = 0; + if (override_group_id == 0) { + // Predict the most preferred group. + Span groups = tls1_get_grouplist(hs); + if (groups.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED); + return false; + } + + group_id = groups[0]; + + if (is_post_quantum_group(group_id) && groups.size() >= 2) { + // CECPQ2(b) is not sent as the only initial key share. We'll include the + // 2nd preference group too to avoid round-trips. + second_group_id = groups[1]; + assert(second_group_id != group_id); + } + } + + CBB key_exchange; + hs->key_shares[0] = SSLKeyShare::Create(group_id); + if (!hs->key_shares[0] || // + !CBB_add_u16(cbb.get(), group_id) || + !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || + !hs->key_shares[0]->Offer(&key_exchange)) { + return false; + } + + if (second_group_id != 0) { + hs->key_shares[1] = SSLKeyShare::Create(second_group_id); + if (!hs->key_shares[1] || // + !CBB_add_u16(cbb.get(), second_group_id) || + !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || + !hs->key_shares[1]->Offer(&key_exchange)) { + return false; + } + } + + return CBBFinishArray(cbb.get(), &hs->key_share_bytes); +} + +static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + assert(!hs->key_share_bytes.empty()); + CBB contents, kse_bytes; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &kse_bytes) || + !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(), + hs->key_share_bytes.size()) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents) { + CBS peer_key; + uint16_t group_id; + if (!CBS_get_u16(contents, &group_id) || + !CBS_get_u16_length_prefixed(contents, &peer_key) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + SSLKeyShare *key_share = hs->key_shares[0].get(); + if (key_share->GroupID() != group_id) { + if (!hs->key_shares[1] || hs->key_shares[1]->GroupID() != group_id) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return false; + } + key_share = hs->key_shares[1].get(); + } + + if (!key_share->Finish(out_secret, out_alert, peer_key)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->new_session->group_id = group_id; + hs->key_shares[0].reset(); + hs->key_shares[1].reset(); + return true; +} + +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Span *out_peer_key, + uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + // We only support connections that include an ECDHE key exchange. + CBS contents; + if (!ssl_client_hello_get_extension(client_hello, &contents, + TLSEXT_TYPE_key_share)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + *out_alert = SSL_AD_MISSING_EXTENSION; + return false; + } + + CBS key_shares; + if (!CBS_get_u16_length_prefixed(&contents, &key_shares) || + CBS_len(&contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + // Find the corresponding key share. + const uint16_t group_id = hs->new_session->group_id; + CBS peer_key; + CBS_init(&peer_key, nullptr, 0); + while (CBS_len(&key_shares) > 0) { + uint16_t id; + CBS peer_key_tmp; + if (!CBS_get_u16(&key_shares, &id) || + !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) || + CBS_len(&peer_key_tmp) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (id == group_id) { + if (CBS_len(&peer_key) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + peer_key = peer_key_tmp; + // Continue parsing the structure to keep peers honest. + } + } + + if (out_peer_key != nullptr) { + *out_peer_key = peer_key; + } + *out_found = CBS_len(&peer_key) != 0; + return true; +} + +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + CBB kse_bytes, public_key; + if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out, &kse_bytes) || + !CBB_add_u16(&kse_bytes, hs->new_session->group_id) || + !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || + !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(), + hs->ecdh_public_key.size()) || + !CBB_flush(out)) { + return false; + } + return true; +} + + +// Supported Versions +// +// https://tools.ietf.org/html/rfc8446#section-4.2.1 + +static bool ext_supported_versions_add_clienthello( + const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (hs->max_version <= TLS1_2_VERSION) { + return true; + } + + // supported_versions is compressible in ECH if ClientHelloOuter already + // requires TLS 1.3. Otherwise the extensions differ in the older versions. + if (hs->min_version >= TLS1_3_VERSION) { + out = out_compressible; + } + + CBB contents, versions; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &versions)) { + return false; + } + + // Add a fake version. See RFC 8701. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&versions, ssl_get_grease_value(hs, ssl_grease_version))) { + return false; + } + + // Encrypted ClientHellos requires TLS 1.3 or later. + uint16_t extra_min_version = + type == ssl_client_hello_inner ? TLS1_3_VERSION : 0; + if (!ssl_add_supported_versions(hs, &versions, extra_min_version) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Cookie +// +// https://tools.ietf.org/html/rfc8446#section-4.2.2 + +static bool ext_cookie_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + if (hs->cookie.empty()) { + return true; + } + + CBB contents, cookie; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cookie) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &cookie) || + !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) || + !CBB_flush(out_compressible)) { + return false; + } + + return true; +} + + +// Supported Groups +// +// https://tools.ietf.org/html/rfc4492#section-5.1.1 +// https://tools.ietf.org/html/rfc8446#section-4.2.7 + +static bool ext_supported_groups_add_clienthello(const SSL_HANDSHAKE *hs, + CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + CBB contents, groups_bytes; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_supported_groups) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) { + return false; + } + + // Add a fake group. See RFC 8701. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&groups_bytes, + ssl_get_grease_value(hs, ssl_grease_group))) { + return false; + } + + for (uint16_t group : tls1_get_grouplist(hs)) { + if (is_post_quantum_group(group) && + hs->max_version < TLS1_3_VERSION) { + continue; + } + if (!CBB_add_u16(&groups_bytes, group)) { + return false; + } + } + + return CBB_flush(out_compressible); +} + +static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + // This extension is not expected to be echoed by servers in TLS 1.2, but some + // BigIP servers send it nonetheless, so do not enforce this. + return true; +} + +static bool parse_u16_array(const CBS *cbs, Array *out) { + CBS copy = *cbs; + if ((CBS_len(©) & 1) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + Array ret; + if (!ret.Init(CBS_len(©) / 2)) { + return false; + } + for (size_t i = 0; i < ret.size(); i++) { + if (!CBS_get_u16(©, &ret[i])) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + assert(CBS_len(©) == 0); + *out = std::move(ret); + return true; +} + +static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS supported_group_list; + if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) || + CBS_len(&supported_group_list) == 0 || + CBS_len(contents) != 0 || + !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) { + return false; + } + + return true; +} + + +// QUIC Transport Parameters + +static bool ext_quic_transport_params_add_clienthello_impl( + const SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) { + if (hs->config->quic_transport_params.empty() && !hs->ssl->quic_method) { + return true; + } + if (hs->config->quic_transport_params.empty() || !hs->ssl->quic_method) { + // QUIC Transport Parameters must be sent over QUIC, and they must not be + // sent over non-QUIC transports. If transport params are set, then + // SSL(_CTX)_set_quic_method must also be called. + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED); + return false; + } + assert(hs->min_version > TLS1_2_VERSION); + if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) { + // Do nothing, we'll send the other codepoint. + return true; + } + + uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters; + if (hs->config->quic_use_legacy_codepoint) { + extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy; + } + + CBB contents; + if (!CBB_add_u16(out, extension_type) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(), + hs->config->quic_transport_params.size()) || + !CBB_flush(out)) { + return false; + } + return true; +} + +static bool ext_quic_transport_params_add_clienthello( + const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible, + ssl_client_hello_type_t type) { + return ext_quic_transport_params_add_clienthello_impl( + hs, out_compressible, /*use_legacy_codepoint=*/false); +} + +static bool ext_quic_transport_params_add_clienthello_legacy( + const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible, + ssl_client_hello_type_t type) { + return ext_quic_transport_params_add_clienthello_impl( + hs, out_compressible, /*use_legacy_codepoint=*/true); +} + +static bool ext_quic_transport_params_parse_serverhello_impl( + SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents, + bool used_legacy_codepoint) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) { + // Silently ignore because we expect the other QUIC codepoint. + return true; + } + if (!ssl->quic_method) { + return true; + } + *out_alert = SSL_AD_MISSING_EXTENSION; + return false; + } + // The extensions parser will check for unsolicited extensions before + // calling the callback. + assert(ssl->quic_method != nullptr); + assert(ssl_protocol_version(ssl) == TLS1_3_VERSION); + assert(used_legacy_codepoint == hs->config->quic_use_legacy_codepoint); + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + return ext_quic_transport_params_parse_serverhello_impl( + hs, out_alert, contents, /*used_legacy_codepoint=*/false); +} + +static bool ext_quic_transport_params_parse_serverhello_legacy( + SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { + return ext_quic_transport_params_parse_serverhello_impl( + hs, out_alert, contents, /*used_legacy_codepoint=*/true); +} + +static bool ext_quic_transport_params_parse_clienthello_impl( + SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents, + bool used_legacy_codepoint) { + SSL *const ssl = hs->ssl; + if (!contents) { + if (!ssl->quic_method) { + if (hs->config->quic_transport_params.empty()) { + return true; + } + // QUIC transport parameters must not be set if |ssl| is not configured + // for QUIC. + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED); + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) { + // Silently ignore because we expect the other QUIC codepoint. + return true; + } + *out_alert = SSL_AD_MISSING_EXTENSION; + return false; + } + if (!ssl->quic_method) { + if (used_legacy_codepoint) { + // Ignore the legacy private-use codepoint because that could be sent + // to mean something else than QUIC transport parameters. + return true; + } + // Fail if we received the codepoint registered with IANA for QUIC + // because that is not allowed outside of QUIC. + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + assert(ssl_protocol_version(ssl) == TLS1_3_VERSION); + if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) { + // Silently ignore because we expect the other QUIC codepoint. + return true; + } + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + return ext_quic_transport_params_parse_clienthello_impl( + hs, out_alert, contents, /*used_legacy_codepoint=*/false); +} + +static bool ext_quic_transport_params_parse_clienthello_legacy( + SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { + return ext_quic_transport_params_parse_clienthello_impl( + hs, out_alert, contents, /*used_legacy_codepoint=*/true); +} + +static bool ext_quic_transport_params_add_serverhello_impl( + SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) { + if (hs->ssl->quic_method == nullptr && use_legacy_codepoint) { + // Ignore the legacy private-use codepoint because that could be sent + // to mean something else than QUIC transport parameters. + return true; + } + assert(hs->ssl->quic_method != nullptr); + if (hs->config->quic_transport_params.empty()) { + // Transport parameters must be set when using QUIC. + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED); + return false; + } + if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) { + // Do nothing, we'll send the other codepoint. + return true; + } + + uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters; + if (hs->config->quic_use_legacy_codepoint) { + extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy; + } + + CBB contents; + if (!CBB_add_u16(out, extension_type) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(), + hs->config->quic_transport_params.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + return ext_quic_transport_params_add_serverhello_impl( + hs, out, /*use_legacy_codepoint=*/false); +} + +static bool ext_quic_transport_params_add_serverhello_legacy(SSL_HANDSHAKE *hs, + CBB *out) { + return ext_quic_transport_params_add_serverhello_impl( + hs, out, /*use_legacy_codepoint=*/true); +} + +// Delegated credentials. +// +// https://tools.ietf.org/html/draft-ietf-tls-subcerts + +static bool ext_delegated_credential_add_clienthello( + const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible, + ssl_client_hello_type_t type) { + return true; +} + +static bool ext_delegated_credential_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr || ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) { + // Don't use delegated credentials unless we're negotiating TLS 1.3 or + // higher. + return true; + } + + // The contents of the extension are the signature algorithms the client will + // accept for a delegated credential. + CBS sigalg_list; + if (!CBS_get_u16_length_prefixed(contents, &sigalg_list) || + CBS_len(&sigalg_list) == 0 || + CBS_len(contents) != 0 || + !parse_u16_array(&sigalg_list, &hs->peer_delegated_credential_sigalgs)) { + return false; + } + + hs->delegated_credential_requested = true; + return true; +} + +// Certificate compression + +static bool cert_compression_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + bool first = true; + CBB contents, algs; + + for (const auto &alg : hs->ssl->ctx->cert_compression_algs) { + if (alg.decompress == nullptr) { + continue; + } + + if (first && + (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cert_compression) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u8_length_prefixed(&contents, &algs))) { + return false; + } + first = false; + if (!CBB_add_u16(&algs, alg.alg_id)) { + return false; + } + } + + return first || CBB_flush(out_compressible); +} + +static bool cert_compression_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr) { + return true; + } + + // The server may not echo this extension. Any server to client negotiation is + // advertised in the CertificateRequest message. + return false; +} + +static bool cert_compression_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr) { + return true; + } + + const SSL_CTX *ctx = hs->ssl->ctx.get(); + const size_t num_algs = ctx->cert_compression_algs.size(); + + CBS alg_ids; + if (!CBS_get_u8_length_prefixed(contents, &alg_ids) || + CBS_len(contents) != 0 || + CBS_len(&alg_ids) == 0 || + CBS_len(&alg_ids) % 2 == 1) { + return false; + } + + const size_t num_given_alg_ids = CBS_len(&alg_ids) / 2; + Array given_alg_ids; + if (!given_alg_ids.Init(num_given_alg_ids)) { + return false; + } + + size_t best_index = num_algs; + size_t given_alg_idx = 0; + + while (CBS_len(&alg_ids) > 0) { + uint16_t alg_id; + if (!CBS_get_u16(&alg_ids, &alg_id)) { + return false; + } + + given_alg_ids[given_alg_idx++] = alg_id; + + for (size_t i = 0; i < num_algs; i++) { + const auto &alg = ctx->cert_compression_algs[i]; + if (alg.alg_id == alg_id && alg.compress != nullptr) { + if (i < best_index) { + best_index = i; + } + break; + } + } + } + + qsort(given_alg_ids.data(), given_alg_ids.size(), sizeof(uint16_t), + compare_uint16_t); + for (size_t i = 1; i < num_given_alg_ids; i++) { + if (given_alg_ids[i - 1] == given_alg_ids[i]) { + return false; + } + } + + if (best_index < num_algs && + ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + hs->cert_compression_negotiated = true; + hs->cert_compression_alg_id = ctx->cert_compression_algs[best_index].alg_id; + } + + return true; +} + +static bool cert_compression_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; +} + +// Application-level Protocol Settings +// +// https://tools.ietf.org/html/draft-vvv-tls-alps-01 + +bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs, + Span *out_settings, + Span protocol) { + for (const ALPSConfig &config : hs->config->alps_configs) { + if (protocol == config.protocol) { + *out_settings = config.settings; + return true; + } + } + return false; +} + +static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + CBB *out_compressible, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + if (// ALPS requires TLS 1.3. + hs->max_version < TLS1_3_VERSION || + // Do not offer ALPS without ALPN. + hs->config->alpn_client_proto_list.empty() || + // Do not offer ALPS if not configured. + hs->config->alps_configs.empty() || + // Do not offer ALPS on renegotiation handshakes. + ssl->s3->initial_handshake_complete) { + return true; + } + + CBB contents, proto_list, proto; + if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_application_settings) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list)) { + return false; + } + + for (const ALPSConfig &config : hs->config->alps_configs) { + if (!CBB_add_u8_length_prefixed(&proto_list, &proto) || + !CBB_add_bytes(&proto, config.protocol.data(), + config.protocol.size())) { + return false; + } + } + + return CBB_flush(out_compressible); +} + +static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + + assert(!ssl->s3->initial_handshake_complete); + assert(!hs->config->alpn_client_proto_list.empty()); + assert(!hs->config->alps_configs.empty()); + + // ALPS requires TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + // Note extension callbacks may run in any order, so we defer checking + // consistency with ALPN to |ssl_check_serverhello_tlsext|. + if (!hs->new_session->peer_application_settings.CopyFrom(*contents)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->new_session->has_application_settings = true; + return true; +} + +static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // If early data is accepted, we omit the ALPS extension. It is implicitly + // carried over from the previous connection. + if (hs->new_session == nullptr || + !hs->new_session->has_application_settings || + ssl->s3->early_data_accepted) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_settings) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, + hs->new_session->local_application_settings.data(), + hs->new_session->local_application_settings.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + if (ssl->s3->alpn_selected.empty()) { + return true; + } + + // If we negotiate ALPN over TLS 1.3, try to negotiate ALPS. + CBS alps_contents; + Span settings; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION && + ssl_get_local_application_settings(hs, &settings, + ssl->s3->alpn_selected) && + ssl_client_hello_get_extension(client_hello, &alps_contents, + TLSEXT_TYPE_application_settings)) { + // Check if the client supports ALPS with the selected ALPN. + bool found = false; + CBS alps_list; + if (!CBS_get_u16_length_prefixed(&alps_contents, &alps_list) || + CBS_len(&alps_contents) != 0 || + CBS_len(&alps_list) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + while (CBS_len(&alps_list) > 0) { + CBS protocol_name; + if (!CBS_get_u8_length_prefixed(&alps_list, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + if (protocol_name == MakeConstSpan(ssl->s3->alpn_selected)) { + found = true; + } + } + + // Negotiate ALPS if both client also supports ALPS for this protocol. + if (found) { + hs->new_session->has_application_settings = true; + if (!hs->new_session->local_application_settings.CopyFrom(settings)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + } + + return true; +} + +// kExtensions contains all the supported extensions. +static const struct tls_extension kExtensions[] = { + { + TLSEXT_TYPE_server_name, + ext_sni_add_clienthello, + ext_sni_parse_serverhello, + ext_sni_parse_clienthello, + ext_sni_add_serverhello, + }, + { + TLSEXT_TYPE_encrypted_client_hello, + ext_ech_add_clienthello, + ext_ech_parse_serverhello, + ext_ech_parse_clienthello, + ext_ech_add_serverhello, + }, + { + TLSEXT_TYPE_extended_master_secret, + ext_ems_add_clienthello, + ext_ems_parse_serverhello, + ext_ems_parse_clienthello, + ext_ems_add_serverhello, + }, + { + TLSEXT_TYPE_renegotiate, + ext_ri_add_clienthello, + ext_ri_parse_serverhello, + ext_ri_parse_clienthello, + ext_ri_add_serverhello, + }, + { + TLSEXT_TYPE_supported_groups, + ext_supported_groups_add_clienthello, + ext_supported_groups_parse_serverhello, + ext_supported_groups_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_ec_point_formats, + ext_ec_point_add_clienthello, + ext_ec_point_parse_serverhello, + ext_ec_point_parse_clienthello, + ext_ec_point_add_serverhello, + }, + { + TLSEXT_TYPE_session_ticket, + ext_ticket_add_clienthello, + ext_ticket_parse_serverhello, + // Ticket extension client parsing is handled in ssl_session.c + ignore_parse_clienthello, + ext_ticket_add_serverhello, + }, + { + TLSEXT_TYPE_application_layer_protocol_negotiation, + ext_alpn_add_clienthello, + ext_alpn_parse_serverhello, + // ALPN is negotiated late in |ssl_negotiate_alpn|. + ignore_parse_clienthello, + ext_alpn_add_serverhello, + }, + { + TLSEXT_TYPE_status_request, + ext_ocsp_add_clienthello, + ext_ocsp_parse_serverhello, + ext_ocsp_parse_clienthello, + ext_ocsp_add_serverhello, + }, + { + TLSEXT_TYPE_signature_algorithms, + ext_sigalgs_add_clienthello, + forbid_parse_serverhello, + ext_sigalgs_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_next_proto_neg, + ext_npn_add_clienthello, + ext_npn_parse_serverhello, + ext_npn_parse_clienthello, + ext_npn_add_serverhello, + }, + { + TLSEXT_TYPE_certificate_timestamp, + ext_sct_add_clienthello, + ext_sct_parse_serverhello, + ext_sct_parse_clienthello, + ext_sct_add_serverhello, + }, + { + TLSEXT_TYPE_channel_id, + ext_channel_id_add_clienthello, + ext_channel_id_parse_serverhello, + ext_channel_id_parse_clienthello, + ext_channel_id_add_serverhello, + }, + { + TLSEXT_TYPE_srtp, + ext_srtp_add_clienthello, + ext_srtp_parse_serverhello, + ext_srtp_parse_clienthello, + ext_srtp_add_serverhello, + }, + { + TLSEXT_TYPE_key_share, + ext_key_share_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_psk_key_exchange_modes, + ext_psk_key_exchange_modes_add_clienthello, + forbid_parse_serverhello, + ext_psk_key_exchange_modes_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_early_data, + ext_early_data_add_clienthello, + ext_early_data_parse_serverhello, + ext_early_data_parse_clienthello, + ext_early_data_add_serverhello, + }, + { + TLSEXT_TYPE_supported_versions, + ext_supported_versions_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_cookie, + ext_cookie_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_quic_transport_parameters, + ext_quic_transport_params_add_clienthello, + ext_quic_transport_params_parse_serverhello, + ext_quic_transport_params_parse_clienthello, + ext_quic_transport_params_add_serverhello, + }, + { + TLSEXT_TYPE_quic_transport_parameters_legacy, + ext_quic_transport_params_add_clienthello_legacy, + ext_quic_transport_params_parse_serverhello_legacy, + ext_quic_transport_params_parse_clienthello_legacy, + ext_quic_transport_params_add_serverhello_legacy, + }, + { + TLSEXT_TYPE_cert_compression, + cert_compression_add_clienthello, + cert_compression_parse_serverhello, + cert_compression_parse_clienthello, + cert_compression_add_serverhello, + }, + { + TLSEXT_TYPE_delegated_credential, + ext_delegated_credential_add_clienthello, + forbid_parse_serverhello, + ext_delegated_credential_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_application_settings, + ext_alps_add_clienthello, + ext_alps_parse_serverhello, + // ALPS is negotiated late in |ssl_negotiate_alpn|. + ignore_parse_clienthello, + ext_alps_add_serverhello, + }, +}; + +#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension)) + +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8, + "too many extensions for sent bitset"); +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8, + "too many extensions for received bitset"); + +bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) { + if (!hs->config->permute_extensions) { + return true; + } + + static_assert(kNumExtensions <= UINT8_MAX, + "extensions_permutation type is too small"); + uint32_t seeds[kNumExtensions - 1]; + Array permutation; + if (!RAND_bytes(reinterpret_cast(seeds), sizeof(seeds)) || + !permutation.Init(kNumExtensions)) { + return false; + } + for (size_t i = 0; i < kNumExtensions; i++) { + permutation[i] = i; + } + for (size_t i = kNumExtensions - 1; i > 0; i--) { + // Set element |i| to a randomly-selected element 0 <= j <= i. + std::swap(permutation[i], permutation[seeds[i - 1] % (i + 1)]); + } + hs->extension_permutation = std::move(permutation); + return true; +} + +static const struct tls_extension *tls_extension_find(uint32_t *out_index, + uint16_t value) { + unsigned i; + for (i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].value == value) { + *out_index = i; + return &kExtensions[i]; + } + } + + return NULL; +} + +static bool add_padding_extension(CBB *cbb, uint16_t ext, size_t len) { + CBB child; + if (!CBB_add_u16(cbb, ext) || // + !CBB_add_u16_length_prefixed(cbb, &child) || + !CBB_add_zeros(&child, len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + return CBB_flush(cbb); +} + +static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out, + CBB *out_encoded, + bool *out_needs_psk_binder) { + // When writing ClientHelloInner, we construct the real and encoded + // ClientHellos concurrently, to handle compression. Uncompressed extensions + // are written to |extensions| and copied to |extensions_encoded|. Compressed + // extensions are buffered in |compressed| and written to the end. (ECH can + // only compress continguous extensions.) + SSL *const ssl = hs->ssl; + bssl::ScopedCBB compressed, outer_extensions; + CBB extensions, extensions_encoded; + if (!CBB_add_u16_length_prefixed(out, &extensions) || + !CBB_add_u16_length_prefixed(out_encoded, &extensions_encoded) || + !CBB_init(compressed.get(), 64) || + !CBB_init(outer_extensions.get(), 64)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + hs->inner_extensions_sent = 0; + + if (ssl->ctx->grease_enabled) { + // Add a fake empty extension. See RFC 8701. This always matches + // |ssl_add_clienthello_tlsext|, so compress it. + uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension1); + if (!add_padding_extension(compressed.get(), grease_ext, 0) || + !CBB_add_u16(outer_extensions.get(), grease_ext)) { + return false; + } + } + + for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) { + size_t i = hs->extension_permutation.empty() + ? unpermuted + : hs->extension_permutation[unpermuted]; + const size_t len_before = CBB_len(&extensions); + const size_t len_compressed_before = CBB_len(compressed.get()); + if (!kExtensions[i].add_clienthello(hs, &extensions, compressed.get(), + ssl_client_hello_inner)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + return false; + } + + const size_t bytes_written = CBB_len(&extensions) - len_before; + const size_t bytes_written_compressed = + CBB_len(compressed.get()) - len_compressed_before; + // The callback may write to at most one output. + assert(bytes_written == 0 || bytes_written_compressed == 0); + if (bytes_written != 0 || bytes_written_compressed != 0) { + hs->inner_extensions_sent |= (1u << i); + } + // If compressed, update the running ech_outer_extensions extension. + if (bytes_written_compressed != 0 && + !CBB_add_u16(outer_extensions.get(), kExtensions[i].value)) { + return false; + } + } + + if (ssl->ctx->grease_enabled) { + // Add a fake non-empty extension. See RFC 8701. This always matches + // |ssl_add_clienthello_tlsext|, so compress it. + uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension2); + if (!add_padding_extension(compressed.get(), grease_ext, 1) || + !CBB_add_u16(outer_extensions.get(), grease_ext)) { + return false; + } + } + + // Uncompressed extensions are encoded as-is. + if (!CBB_add_bytes(&extensions_encoded, CBB_data(&extensions), + CBB_len(&extensions))) { + return false; + } + + // Flush all the compressed extensions. + if (CBB_len(compressed.get()) != 0) { + CBB extension, child; + // Copy them as-is in the real ClientHelloInner. + if (!CBB_add_bytes(&extensions, CBB_data(compressed.get()), + CBB_len(compressed.get())) || + // Replace with ech_outer_extensions in the encoded form. + !CBB_add_u16(&extensions_encoded, TLSEXT_TYPE_ech_outer_extensions) || + !CBB_add_u16_length_prefixed(&extensions_encoded, &extension) || + !CBB_add_u8_length_prefixed(&extension, &child) || + !CBB_add_bytes(&child, CBB_data(outer_extensions.get()), + CBB_len(outer_extensions.get())) || + !CBB_flush(&extensions_encoded)) { + return false; + } + } + + // The PSK extension must be last. It is never compressed. Note, if there is a + // binder, the caller will need to update both ClientHelloInner and + // EncodedClientHelloInner after computing it. + const size_t len_before = CBB_len(&extensions); + if (!ext_pre_shared_key_add_clienthello(hs, &extensions, out_needs_psk_binder, + ssl_client_hello_inner) || + !CBB_add_bytes(&extensions_encoded, CBB_data(&extensions) + len_before, + CBB_len(&extensions) - len_before) || + !CBB_flush(out) || // + !CBB_flush(out_encoded)) { + return false; + } + + return true; +} + +bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, + bool *out_needs_psk_binder, + ssl_client_hello_type_t type, + size_t header_len) { + *out_needs_psk_binder = false; + + if (type == ssl_client_hello_inner) { + return ssl_add_clienthello_tlsext_inner(hs, out, out_encoded, + out_needs_psk_binder); + } + + assert(out_encoded == nullptr); // Only ClientHelloInner needs two outputs. + SSL *const ssl = hs->ssl; + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // Note we may send multiple ClientHellos for DTLS HelloVerifyRequest and TLS + // 1.3 HelloRetryRequest. For the latter, the extensions may change, so it is + // important to reset this value. + hs->extensions.sent = 0; + + // Add a fake empty extension. See RFC 8701. + if (ssl->ctx->grease_enabled && + !add_padding_extension( + &extensions, ssl_get_grease_value(hs, ssl_grease_extension1), 0)) { + return false; + } + + bool last_was_empty = false; + for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) { + size_t i = hs->extension_permutation.empty() + ? unpermuted + : hs->extension_permutation[unpermuted]; + const size_t len_before = CBB_len(&extensions); + if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + return false; + } + + const size_t bytes_written = CBB_len(&extensions) - len_before; + if (bytes_written != 0) { + hs->extensions.sent |= (1u << i); + } + // If the difference in lengths is only four bytes then the extension had + // an empty body. + last_was_empty = (bytes_written == 4); + } + + if (ssl->ctx->grease_enabled) { + // Add a fake non-empty extension. See RFC 8701. + if (!add_padding_extension( + &extensions, ssl_get_grease_value(hs, ssl_grease_extension2), 1)) { + return false; + } + last_was_empty = false; + } + + // In cleartext ClientHellos, we add the padding extension to work around + // bugs. We also apply this padding to ClientHelloOuter, to keep the wire + // images aligned. + size_t psk_extension_len = ext_pre_shared_key_clienthello_length(hs, type); + if (!SSL_is_dtls(ssl) && !ssl->quic_method && + !ssl->s3->used_hello_retry_request) { + header_len += + SSL3_HM_HEADER_LENGTH + 2 + CBB_len(&extensions) + psk_extension_len; + size_t padding_len = 0; + + // The final extension must be non-empty. WebSphere Application + // Server 7.0 is intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + if (last_was_empty && psk_extension_len == 0) { + padding_len = 1; + // The addition of the padding extension may push us into the F5 bug. + header_len += 4 + padding_len; + } + + // Add padding to workaround bugs in F5 terminators. See RFC 7685. + // + // NB: because this code works out the length of all existing extensions + // it MUST always appear last (save for any PSK extension). + if (header_len > 0xff && header_len < 0x200) { + // If our calculations already included a padding extension, remove that + // factor because we're about to change its length. + if (padding_len != 0) { + header_len -= 4 + padding_len; + } + padding_len = 0x200 - header_len; + // Extensions take at least four bytes to encode. Always include at least + // one byte of data if including the extension. WebSphere Application + // Server 7.0 is intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + if (padding_len >= 4 + 1) { + padding_len -= 4; + } else { + padding_len = 1; + } + } + + if (padding_len != 0 && + !add_padding_extension(&extensions, TLSEXT_TYPE_padding, padding_len)) { + return false; + } + } + + // The PSK extension must be last, including after the padding. + const size_t len_before = CBB_len(&extensions); + if (!ext_pre_shared_key_add_clienthello(hs, &extensions, out_needs_psk_binder, + type)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + assert(psk_extension_len == CBB_len(&extensions) - len_before); + (void)len_before; // |assert| is omitted in release builds. + + // Discard empty extensions blocks. + if (CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); +} + +bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + goto err; + } + + for (unsigned i = 0; i < kNumExtensions; i++) { + if (!(hs->extensions.received & (1u << i))) { + // Don't send extensions that were not received. + continue; + } + + if (!kExtensions[i].add_serverhello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + goto err; + } + } + + // Discard empty extensions blocks before TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION && + CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); + +err: + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +static bool ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello, + int *out_alert) { + hs->extensions.received = 0; + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + if (ext == NULL) { + continue; + } + + hs->extensions.received |= (1u << ext_index); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_clienthello(hs, &alert, &extension)) { + *out_alert = alert; + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + return false; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (hs->extensions.received & (1u << i)) { + continue; + } + + CBS *contents = NULL, fake_contents; + static const uint8_t kFakeRenegotiateExtension[] = {0}; + if (kExtensions[i].value == TLSEXT_TYPE_renegotiate && + ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_SCSV & 0xffff)) { + // The renegotiation SCSV was received so pretend that we received a + // renegotiation extension. + CBS_init(&fake_contents, kFakeRenegotiateExtension, + sizeof(kFakeRenegotiateExtension)); + contents = &fake_contents; + hs->extensions.received |= (1u << i); + } + + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return false; + } + } + + return true; +} + +bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (!ssl_scan_clienthello_tlsext(hs, client_hello, &alert)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + if (!ssl_check_clienthello_tlsext(hs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT); + return false; + } + + return true; +} + +static bool ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs, + int *out_alert) { + CBS extensions = *cbs; + if (!tls1_check_duplicate_extensions(&extensions)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + uint32_t received = 0; + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + + if (ext == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + + static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8, + "too many bits"); + + if (!(hs->extensions.sent & (1u << ext_index))) { + // If the extension was never sent then it is illegal. + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension :%u", (unsigned)type); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + + received |= (1u << ext_index); + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_serverhello(hs, &alert, &extension)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + *out_alert = alert; + return false; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (!(received & (1u << i))) { + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_serverhello(hs, &alert, NULL)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return false; + } + } + } + + return true; +} + +static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + if (ssl->ctx->servername_callback != 0) { + ret = ssl->ctx->servername_callback(ssl, &al, ssl->ctx->servername_arg); + } else if (ssl->session_ctx->servername_callback != 0) { + ret = ssl->session_ctx->servername_callback( + ssl, &al, ssl->session_ctx->servername_arg); + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl_send_alert(ssl, SSL3_AL_FATAL, al); + return false; + + case SSL_TLSEXT_ERR_NOACK: + hs->should_ack_sni = false; + return true; + + default: + return true; + } +} + +static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // ALPS and ALPN have a dependency between each other, so we defer checking + // consistency to after the callbacks run. + if (hs->new_session != nullptr && hs->new_session->has_application_settings) { + // ALPN must be negotiated. + if (ssl->s3->alpn_selected.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_ALPS_WITHOUT_ALPN); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return false; + } + + // The negotiated protocol must be one of the ones we advertised for ALPS. + Span settings; + if (!ssl_get_local_application_settings(hs, &settings, + ssl->s3->alpn_selected)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return false; + } + + if (!hs->new_session->local_application_settings.CopyFrom(settings)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + } + + return true; +} + +bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (!ssl_scan_serverhello_tlsext(hs, cbs, &alert)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + if (!ssl_check_serverhello_tlsext(hs)) { + return false; + } + + return true; +} + +static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx( + Array *out, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hmac_ctx, + Span ticket) { + size_t iv_len = EVP_CIPHER_CTX_iv_length(cipher_ctx); + + // Check the MAC at the end of the ticket. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len = HMAC_size(hmac_ctx); + if (ticket.size() < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) { + // The ticket must be large enough for key name, IV, data, and MAC. + return ssl_ticket_aead_ignore_ticket; + } + // Split the ticket into the ticket and the MAC. + auto ticket_mac = ticket.last(mac_len); + ticket = ticket.first(ticket.size() - mac_len); + HMAC_Update(hmac_ctx, ticket.data(), ticket.size()); + HMAC_Final(hmac_ctx, mac, NULL); + assert(mac_len == ticket_mac.size()); + bool mac_ok = CRYPTO_memcmp(mac, ticket_mac.data(), mac_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + mac_ok = true; +#endif + if (!mac_ok) { + return ssl_ticket_aead_ignore_ticket; + } + + // Decrypt the session data. + auto ciphertext = ticket.subspan(SSL_TICKET_KEY_NAME_LEN + iv_len); + Array plaintext; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + if (!plaintext.CopyFrom(ciphertext)) { + return ssl_ticket_aead_error; + } +#else + if (ciphertext.size() >= INT_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + if (!plaintext.Init(ciphertext.size())) { + return ssl_ticket_aead_error; + } + int len1, len2; + if (!EVP_DecryptUpdate(cipher_ctx, plaintext.data(), &len1, ciphertext.data(), + (int)ciphertext.size()) || + !EVP_DecryptFinal_ex(cipher_ctx, plaintext.data() + len1, &len2)) { + ERR_clear_error(); + return ssl_ticket_aead_ignore_ticket; + } + plaintext.Shrink(static_cast(len1) + len2); +#endif + + *out = std::move(plaintext); + return ssl_ticket_aead_success; +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb( + SSL_HANDSHAKE *hs, Array *out, bool *out_renew_ticket, + Span ticket) { + assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + auto name = ticket.subspan(0, SSL_TICKET_KEY_NAME_LEN); + // The actual IV is shorter, but the length is determined by the callback's + // chosen cipher. Instead we pass in |EVP_MAX_IV_LENGTH| worth of IV to ensure + // the callback has enough. + auto iv = ticket.subspan(SSL_TICKET_KEY_NAME_LEN, EVP_MAX_IV_LENGTH); + int cb_ret = hs->ssl->session_ctx->ticket_key_cb( + hs->ssl, const_cast(name.data()), + const_cast(iv.data()), cipher_ctx.get(), hmac_ctx.get(), + 0 /* decrypt */); + if (cb_ret < 0) { + return ssl_ticket_aead_error; + } else if (cb_ret == 0) { + return ssl_ticket_aead_ignore_ticket; + } else if (cb_ret == 2) { + *out_renew_ticket = true; + } else { + assert(cb_ret == 1); + } + return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(), + ticket); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys( + SSL_HANDSHAKE *hs, Array *out, Span ticket) { + assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + SSL_CTX *ctx = hs->ssl->session_ctx.get(); + + // Rotate the ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return ssl_ticket_aead_error; + } + + const EVP_CIPHER *cipher = EVP_aes_128_cbc(); + auto name = ticket.subspan(0, SSL_TICKET_KEY_NAME_LEN); + auto iv = + ticket.subspan(SSL_TICKET_KEY_NAME_LEN, EVP_CIPHER_iv_length(cipher)); + + // Pick the matching ticket key and decrypt. + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + { + MutexReadLock lock(&ctx->lock); + const TicketKey *key; + if (ctx->ticket_key_current && name == ctx->ticket_key_current->name) { + key = ctx->ticket_key_current.get(); + } else if (ctx->ticket_key_prev && name == ctx->ticket_key_prev->name) { + key = ctx->ticket_key_prev.get(); + } else { + return ssl_ticket_aead_ignore_ticket; + } + if (!HMAC_Init_ex(hmac_ctx.get(), key->hmac_key, sizeof(key->hmac_key), + tlsext_tick_md(), NULL) || + !EVP_DecryptInit_ex(cipher_ctx.get(), cipher, NULL, + key->aes_key, iv.data())) { + return ssl_ticket_aead_error; + } + } + return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(), + ticket); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method( + SSL_HANDSHAKE *hs, Array *out, bool *out_renew_ticket, + Span ticket) { + Array plaintext; + if (!plaintext.Init(ticket.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_ticket_aead_error; + } + + size_t plaintext_len; + const enum ssl_ticket_aead_result_t result = + hs->ssl->session_ctx->ticket_aead_method->open( + hs->ssl, plaintext.data(), &plaintext_len, ticket.size(), + ticket.data(), ticket.size()); + if (result != ssl_ticket_aead_success) { + return result; + } + + plaintext.Shrink(plaintext_len); + *out = std::move(plaintext); + return ssl_ticket_aead_success; +} + +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL_HANDSHAKE *hs, UniquePtr *out_session, + bool *out_renew_ticket, Span ticket, + Span session_id) { + SSL *const ssl = hs->ssl; + *out_renew_ticket = false; + out_session->reset(); + + if ((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) || + session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_ticket_aead_ignore_ticket; + } + + // Tickets in TLS 1.3 are tied into pre-shared keys (PSKs), unlike in TLS 1.2 + // where that concept doesn't exist. The |decrypted_psk| and |ignore_psk| + // hints only apply to PSKs. We check the version to determine which this is. + const bool is_psk = ssl_protocol_version(ssl) >= TLS1_3_VERSION; + + Array plaintext; + enum ssl_ticket_aead_result_t result; + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + if (is_psk && hints && !hs->hints_requested && + !hints->decrypted_psk.empty()) { + result = plaintext.CopyFrom(hints->decrypted_psk) ? ssl_ticket_aead_success + : ssl_ticket_aead_error; + } else if (is_psk && hints && !hs->hints_requested && hints->ignore_psk) { + result = ssl_ticket_aead_ignore_ticket; + } else if (ssl->session_ctx->ticket_aead_method != NULL) { + result = ssl_decrypt_ticket_with_method(hs, &plaintext, out_renew_ticket, + ticket); + } else { + // Ensure there is room for the key name and the largest IV |ticket_key_cb| + // may try to consume. The real limit may be lower, but the maximum IV + // length should be well under the minimum size for the session material and + // HMAC. + if (ticket.size() < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) { + result = ssl_ticket_aead_ignore_ticket; + } else if (ssl->session_ctx->ticket_key_cb != NULL) { + result = + ssl_decrypt_ticket_with_cb(hs, &plaintext, out_renew_ticket, ticket); + } else { + result = ssl_decrypt_ticket_with_ticket_keys(hs, &plaintext, ticket); + } + } + + if (is_psk && hints && hs->hints_requested) { + if (result == ssl_ticket_aead_ignore_ticket) { + hints->ignore_psk = true; + } else if (result == ssl_ticket_aead_success && + !hints->decrypted_psk.CopyFrom(plaintext)) { + return ssl_ticket_aead_error; + } + } + + if (result != ssl_ticket_aead_success) { + return result; + } + + // Decode the session. + UniquePtr session(SSL_SESSION_from_bytes( + plaintext.data(), plaintext.size(), ssl->ctx.get())); + if (!session) { + ERR_clear_error(); // Don't leave an error on the queue. + return ssl_ticket_aead_ignore_ticket; + } + + // Envoy's tests expect the session to have a session ID that matches the + // placeholder used by the client. It's unclear whether this is a good idea, + // but we maintain it for now. + SHA256(ticket.data(), ticket.size(), session->session_id); + // Other consumers may expect a non-empty session ID to indicate resumption. + session->session_id_length = SHA256_DIGEST_LENGTH; + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) { + // Extension ignored for inappropriate versions + if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) { + return true; + } + + // In all contexts, the signature algorithms list may not be empty. (It may be + // omitted by clients in TLS 1.2, but then the entire extension is omitted.) + return CBS_len(in_sigalgs) != 0 && + parse_u16_array(in_sigalgs, &hs->peer_sigalgs); +} + +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) { + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_RSA: + *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1; + return true; + case EVP_PKEY_EC: + *out = SSL_SIGN_ECDSA_SHA1; + return true; + default: + return false; + } +} + +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) { + SSL *const ssl = hs->ssl; + CERT *cert = hs->config->cert.get(); + DC *dc = cert->dc.get(); + + // Before TLS 1.2, the signature algorithm isn't negotiated as part of the + // handshake. + if (ssl_protocol_version(ssl) < TLS1_2_VERSION) { + if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; + } + return true; + } + + Span sigalgs = kSignSignatureAlgorithms; + if (ssl_signing_with_dc(hs)) { + sigalgs = MakeConstSpan(&dc->expected_cert_verify_algorithm, 1); + } else if (!cert->sigalgs.empty()) { + sigalgs = cert->sigalgs; + } + + Span peer_sigalgs = tls1_get_peer_verify_algorithms(hs); + + for (uint16_t sigalg : sigalgs) { + // SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be + // negotiated. + if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || + !ssl_private_key_supports_signature_algorithm(hs, sigalg)) { + continue; + } + + for (uint16_t peer_sigalg : peer_sigalgs) { + if (sigalg == peer_sigalg) { + *out = sigalg; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; +} + +Span tls1_get_peer_verify_algorithms(const SSL_HANDSHAKE *hs) { + Span peer_sigalgs = hs->peer_sigalgs; + if (peer_sigalgs.empty() && ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) { + // If the client didn't specify any signature_algorithms extension then + // we can assume that it supports SHA1. See + // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1, + SSL_SIGN_ECDSA_SHA1}; + peer_sigalgs = kDefaultPeerAlgorithms; + } + return peer_sigalgs; +} + +bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + // A Channel ID handshake message is structured to contain multiple + // extensions, but the only one that can be present is Channel ID. + uint16_t extension_type; + CBS channel_id = msg.body, extension; + if (!CBS_get_u16(&channel_id, &extension_type) || + !CBS_get_u16_length_prefixed(&channel_id, &extension) || + CBS_len(&channel_id) != 0 || + extension_type != TLSEXT_TYPE_channel_id || + CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + UniquePtr p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + if (!p256) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); + return false; + } + + UniquePtr sig(ECDSA_SIG_new()); + UniquePtr x(BN_new()), y(BN_new()); + if (!sig || !x || !y) { + return false; + } + + const uint8_t *p = CBS_data(&extension); + if (BN_bin2bn(p + 0, 32, x.get()) == NULL || + BN_bin2bn(p + 32, 32, y.get()) == NULL || + BN_bin2bn(p + 64, 32, sig->r) == NULL || + BN_bin2bn(p + 96, 32, sig->s) == NULL) { + return false; + } + + UniquePtr key(EC_KEY_new()); + UniquePtr point(EC_POINT_new(p256.get())); + if (!key || !point || + !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(), + y.get(), nullptr) || + !EC_KEY_set_group(key.get(), p256.get()) || + !EC_KEY_set_public_key(key.get(), point.get())) { + return false; + } + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return false; + } + + bool sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get()); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return false; + } + + OPENSSL_memcpy(ssl->s3->channel_id, p, 64); + ssl->s3->channel_id_valid = true; + return true; +} + +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) { + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return false; + } + + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(hs->config->channel_id_private.get()); + if (ec_key == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + UniquePtr x(BN_new()), y(BN_new()); + if (!x || !y || + !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key), + EC_KEY_get0_public_key(ec_key), + x.get(), y.get(), nullptr)) { + return false; + } + + UniquePtr sig(ECDSA_do_sign(digest, digest_len, ec_key)); + if (!sig) { + return false; + } + + CBB child; + if (!CBB_add_u16(cbb, TLSEXT_TYPE_channel_id) || + !CBB_add_u16_length_prefixed(cbb, &child) || + !BN_bn2cbb_padded(&child, 32, x.get()) || + !BN_bn2cbb_padded(&child, 32, y.get()) || + !BN_bn2cbb_padded(&child, 32, sig->r) || + !BN_bn2cbb_padded(&child, 32, sig->s) || + !CBB_flush(cbb)) { + return false; + } + + return true; +} + +bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + Array msg; + if (!tls13_get_cert_verify_signature_input(hs, &msg, + ssl_cert_verify_channel_id)) { + return false; + } + SHA256(msg.data(), msg.size(), out); + *out_len = SHA256_DIGEST_LENGTH; + return true; + } + + SHA256_CTX ctx; + + SHA256_Init(&ctx); + static const char kClientIDMagic[] = "TLS Channel ID signature"; + SHA256_Update(&ctx, kClientIDMagic, sizeof(kClientIDMagic)); + + if (ssl->session != NULL) { + static const char kResumptionMagic[] = "Resumption"; + SHA256_Update(&ctx, kResumptionMagic, sizeof(kResumptionMagic)); + if (ssl->session->original_handshake_hash_len == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + SHA256_Update(&ctx, ssl->session->original_handshake_hash, + ssl->session->original_handshake_hash_len); + } + + uint8_t hs_hash[EVP_MAX_MD_SIZE]; + size_t hs_hash_len; + if (!hs->transcript.GetHash(hs_hash, &hs_hash_len)) { + return false; + } + SHA256_Update(&ctx, hs_hash, (size_t)hs_hash_len); + SHA256_Final(out, &ctx); + *out_len = SHA256_DIGEST_LENGTH; + return true; +} + +bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // This function should never be called for a resumed session because the + // handshake hashes that we wish to record are for the original, full + // handshake. + if (ssl->session != NULL) { + return false; + } + + static_assert( + sizeof(hs->new_session->original_handshake_hash) == EVP_MAX_MD_SIZE, + "original_handshake_hash is too small"); + + size_t digest_len; + if (!hs->transcript.GetHash(hs->new_session->original_handshake_hash, + &digest_len)) { + return false; + } + + static_assert(EVP_MAX_MD_SIZE <= 0xff, + "EVP_MAX_MD_SIZE does not fit in uint8_t"); + hs->new_session->original_handshake_hash_len = (uint8_t)digest_len; + + return true; +} + +bool ssl_is_sct_list_valid(const CBS *contents) { + // Shallow parse the SCT list for sanity. By the RFC + // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any + // of the SCTs may be empty. + CBS copy = *contents; + CBS sct_list; + if (!CBS_get_u16_length_prefixed(©, &sct_list) || + CBS_len(©) != 0 || + CBS_len(&sct_list) == 0) { + return false; + } + + while (CBS_len(&sct_list) > 0) { + CBS sct; + if (!CBS_get_u16_length_prefixed(&sct_list, &sct) || + CBS_len(&sct) == 0) { + return false; + } + } + + return true; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, + uint16_t extension_type, + const uint8_t **out_data, + size_t *out_len) { + CBS cbs; + if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) { + return 0; + } + + *out_data = CBS_data(&cbs); + *out_len = CBS_len(&cbs); + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handoff.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handoff.cc new file mode 100644 index 00000000..f7d62bfe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handoff.cc @@ -0,0 +1,986 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +constexpr int kHandoffVersion = 0; +constexpr int kHandbackVersion = 0; + +static const unsigned kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0; + +// early_data_t represents the state of early data in a more compact way than +// the 3 bits used by the implementation. +enum early_data_t { + early_data_not_offered = 0, + early_data_accepted = 1, + early_data_rejected_hrr = 2, + early_data_skipped = 3, + + early_data_max_value = early_data_skipped, +}; + +// serialize_features adds a description of features supported by this binary to +// |out|. Returns true on success and false on error. +static bool serialize_features(CBB *out) { + CBB ciphers; + if (!CBB_add_asn1(out, &ciphers, CBS_ASN1_OCTETSTRING)) { + return false; + } + Span all_ciphers = AllCiphers(); + for (const SSL_CIPHER& cipher : all_ciphers) { + if (!CBB_add_u16(&ciphers, static_cast(cipher.id))) { + return false; + } + } + CBB curves; + if (!CBB_add_asn1(out, &curves, CBS_ASN1_OCTETSTRING)) { + return false; + } + for (const NamedGroup& g : NamedGroups()) { + if (!CBB_add_u16(&curves, g.group_id)) { + return false; + } + } + // ALPS is a draft protocol and may change over time. The handoff structure + // contains a [0] IMPLICIT OCTET STRING OPTIONAL, containing a list of u16 + // ALPS versions that the binary supports. For now we name them by codepoint. + // Once ALPS is finalized and past the support horizon, this field can be + // removed. + CBB alps; + if (!CBB_add_asn1(out, &alps, kHandoffTagALPS) || + !CBB_add_u16(&alps, TLSEXT_TYPE_application_settings)) { + return false; + } + return CBB_flush(out); +} + +bool SSL_serialize_handoff(const SSL *ssl, CBB *out, + SSL_CLIENT_HELLO *out_hello) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_ERROR_HANDOFF) { + return false; + } + + CBB seq; + SSLMessage msg; + Span transcript = s3->hs->transcript.buffer(); + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandoffVersion) || + !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) || + !CBB_add_asn1_octet_string(&seq, + reinterpret_cast(s3->hs_buf->data), + s3->hs_buf->length) || + !serialize_features(&seq) || + !CBB_flush(out) || + !ssl->method->get_message(ssl, &msg) || + !ssl_client_hello_init(ssl, out_hello, msg.body)) { + return false; + } + + return true; +} + +bool SSL_decline_handoff(SSL *ssl) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_ERROR_HANDOFF) { + return false; + } + + s3->hs->config->handoff = false; + return true; +} + +// apply_remote_features reads a list of supported features from |in| and +// (possibly) reconfigures |ssl| to disallow the negotation of features whose +// support has not been indicated. (This prevents the the handshake from +// committing to features that are not supported on the handoff/handback side.) +static bool apply_remote_features(SSL *ssl, CBS *in) { + CBS ciphers; + if (!CBS_get_asn1(in, &ciphers, CBS_ASN1_OCTETSTRING)) { + return false; + } + bssl::UniquePtr supported(sk_SSL_CIPHER_new_null()); + while (CBS_len(&ciphers)) { + uint16_t id; + if (!CBS_get_u16(&ciphers, &id)) { + return false; + } + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(id); + if (!cipher) { + continue; + } + if (!sk_SSL_CIPHER_push(supported.get(), cipher)) { + return false; + } + } + STACK_OF(SSL_CIPHER) *configured = + ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() + : ssl->ctx->cipher_list->ciphers.get(); + bssl::UniquePtr unsupported(sk_SSL_CIPHER_new_null()); + for (const SSL_CIPHER *configured_cipher : configured) { + if (sk_SSL_CIPHER_find(supported.get(), nullptr, configured_cipher)) { + continue; + } + if (!sk_SSL_CIPHER_push(unsupported.get(), configured_cipher)) { + return false; + } + } + if (sk_SSL_CIPHER_num(unsupported.get()) && !ssl->config->cipher_list) { + ssl->config->cipher_list = bssl::MakeUnique(); + if (!ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) { + return false; + } + } + for (const SSL_CIPHER *unsupported_cipher : unsupported.get()) { + ssl->config->cipher_list->Remove(unsupported_cipher); + } + if (sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)) == 0) { + return false; + } + + CBS curves; + if (!CBS_get_asn1(in, &curves, CBS_ASN1_OCTETSTRING)) { + return false; + } + Array supported_curves; + if (!supported_curves.Init(CBS_len(&curves) / 2)) { + return false; + } + size_t idx = 0; + while (CBS_len(&curves)) { + uint16_t curve; + if (!CBS_get_u16(&curves, &curve)) { + return false; + } + supported_curves[idx++] = curve; + } + Span configured_curves = + tls1_get_grouplist(ssl->s3->hs.get()); + Array new_configured_curves; + if (!new_configured_curves.Init(configured_curves.size())) { + return false; + } + idx = 0; + for (uint16_t configured_curve : configured_curves) { + bool ok = false; + for (uint16_t supported_curve : supported_curves) { + if (supported_curve == configured_curve) { + ok = true; + break; + } + } + if (ok) { + new_configured_curves[idx++] = configured_curve; + } + } + if (idx == 0) { + return false; + } + new_configured_curves.Shrink(idx); + ssl->config->supported_group_list = std::move(new_configured_curves); + + CBS alps; + CBS_init(&alps, nullptr, 0); + if (!CBS_get_optional_asn1(in, &alps, /*out_present=*/nullptr, + kHandoffTagALPS)) { + return false; + } + bool supports_alps = false; + while (CBS_len(&alps) != 0) { + uint16_t id; + if (!CBS_get_u16(&alps, &id)) { + return false; + } + // For now, we only support one ALPS code point, so we only need to extract + // a boolean signal from the feature list. + if (id == TLSEXT_TYPE_application_settings) { + supports_alps = true; + break; + } + } + if (!supports_alps) { + ssl->config->alps_configs.clear(); + } + + return true; +} + +// uses_disallowed_feature returns true iff |ssl| enables a feature that +// disqualifies it for split handshakes. +static bool uses_disallowed_feature(const SSL *ssl) { + return ssl->method->is_dtls || (ssl->config->cert && ssl->config->cert->dc) || + ssl->config->quic_transport_params.size() > 0 || ssl->ctx->ech_keys; +} + +bool SSL_apply_handoff(SSL *ssl, Span handoff) { + if (uses_disallowed_feature(ssl)) { + return false; + } + + CBS seq, handoff_cbs(handoff); + uint64_t handoff_version; + if (!CBS_get_asn1(&handoff_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handoff_version) || + handoff_version != kHandoffVersion) { + return false; + } + + CBS transcript, hs_buf; + if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hs_buf, CBS_ASN1_OCTETSTRING) || + !apply_remote_features(ssl, &seq)) { + return false; + } + + SSL_set_accept_state(ssl); + + SSL3_STATE *const s3 = ssl->s3; + s3->v2_hello_done = true; + s3->has_message = true; + + s3->hs_buf.reset(BUF_MEM_new()); + if (!s3->hs_buf || + !BUF_MEM_append(s3->hs_buf.get(), CBS_data(&hs_buf), CBS_len(&hs_buf))) { + return false; + } + + if (CBS_len(&transcript) != 0) { + s3->hs->transcript.Update(transcript); + s3->is_v2_hello = true; + } + s3->hs->handback = true; + + return true; +} + +bool SSL_serialize_handback(const SSL *ssl, CBB *out) { + if (!ssl->server || uses_disallowed_feature(ssl)) { + return false; + } + const SSL3_STATE *const s3 = ssl->s3; + SSL_HANDSHAKE *const hs = s3->hs.get(); + handback_t type; + switch (hs->state) { + case state12_read_change_cipher_spec: + type = handback_after_session_resumption; + break; + case state12_read_client_certificate: + type = handback_after_ecdhe; + break; + case state12_finish_server_handshake: + type = handback_after_handshake; + break; + case state12_tls13: + if (hs->tls13_state != state13_send_half_rtt_ticket) { + return false; + } + type = handback_tls13; + break; + default: + return false; + } + + size_t hostname_len = 0; + if (s3->hostname) { + hostname_len = strlen(s3->hostname.get()); + } + + Span transcript; + if (type != handback_after_handshake) { + transcript = s3->hs->transcript.buffer(); + } + size_t write_iv_len = 0; + const uint8_t *write_iv = nullptr; + if ((type == handback_after_session_resumption || + type == handback_after_handshake) && + ssl->version == TLS1_VERSION && + SSL_CIPHER_is_block_cipher(s3->aead_write_ctx->cipher()) && + !s3->aead_write_ctx->GetIV(&write_iv, &write_iv_len)) { + return false; + } + size_t read_iv_len = 0; + const uint8_t *read_iv = nullptr; + if (type == handback_after_handshake && + ssl->version == TLS1_VERSION && + SSL_CIPHER_is_block_cipher(s3->aead_read_ctx->cipher()) && + !s3->aead_read_ctx->GetIV(&read_iv, &read_iv_len)) { + return false; + } + + // TODO(mab): make sure everything is serialized. + CBB seq, key_share; + const SSL_SESSION *session; + if (type == handback_tls13) { + session = hs->new_session.get(); + } else { + session = s3->session_reused ? ssl->session.get() : hs->new_session.get(); + } + static const uint8_t kUnusedChannelID[64] = {0}; + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandbackVersion) || + !CBB_add_asn1_uint64(&seq, type) || + !CBB_add_asn1_octet_string(&seq, s3->read_sequence, + sizeof(s3->read_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->write_sequence, + sizeof(s3->write_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->server_random, + sizeof(s3->server_random)) || + !CBB_add_asn1_octet_string(&seq, s3->client_random, + sizeof(s3->client_random)) || + !CBB_add_asn1_octet_string(&seq, read_iv, read_iv_len) || + !CBB_add_asn1_octet_string(&seq, write_iv, write_iv_len) || + !CBB_add_asn1_bool(&seq, s3->session_reused) || + !CBB_add_asn1_bool(&seq, hs->channel_id_negotiated) || + !ssl_session_serialize(session, &seq) || + !CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(), + s3->next_proto_negotiated.size()) || + !CBB_add_asn1_octet_string(&seq, s3->alpn_selected.data(), + s3->alpn_selected.size()) || + !CBB_add_asn1_octet_string( + &seq, reinterpret_cast(s3->hostname.get()), + hostname_len) || + !CBB_add_asn1_octet_string(&seq, kUnusedChannelID, + sizeof(kUnusedChannelID)) || + // These two fields were historically |token_binding_negotiated| and + // |negotiated_token_binding_param|. + !CBB_add_asn1_bool(&seq, 0) || + !CBB_add_asn1_uint64(&seq, 0) || + !CBB_add_asn1_bool(&seq, s3->hs->next_proto_neg_seen) || + !CBB_add_asn1_bool(&seq, s3->hs->cert_request) || + !CBB_add_asn1_bool(&seq, s3->hs->extended_master_secret) || + !CBB_add_asn1_bool(&seq, s3->hs->ticket_expected) || + !CBB_add_asn1_uint64(&seq, SSL_CIPHER_get_id(s3->hs->new_cipher)) || + !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) || + !CBB_add_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) { + return false; + } + if (type == handback_after_ecdhe && + !s3->hs->key_shares[0]->Serialize(&key_share)) { + return false; + } + if (type == handback_tls13) { + early_data_t early_data; + // Check early data invariants. + if (ssl->enable_early_data == + (s3->early_data_reason == ssl_early_data_disabled)) { + return false; + } + if (hs->early_data_offered) { + if (s3->early_data_accepted && !s3->skip_early_data) { + early_data = early_data_accepted; + } else if (!s3->early_data_accepted && !s3->skip_early_data) { + early_data = early_data_rejected_hrr; + } else if (!s3->early_data_accepted && s3->skip_early_data) { + early_data = early_data_skipped; + } else { + return false; + } + } else if (!s3->early_data_accepted && !s3->skip_early_data) { + early_data = early_data_not_offered; + } else { + return false; + } + if (!CBB_add_asn1_octet_string(&seq, hs->client_traffic_secret_0().data(), + hs->client_traffic_secret_0().size()) || + !CBB_add_asn1_octet_string(&seq, hs->server_traffic_secret_0().data(), + hs->server_traffic_secret_0().size()) || + !CBB_add_asn1_octet_string(&seq, hs->client_handshake_secret().data(), + hs->client_handshake_secret().size()) || + !CBB_add_asn1_octet_string(&seq, hs->server_handshake_secret().data(), + hs->server_handshake_secret().size()) || + !CBB_add_asn1_octet_string(&seq, hs->secret().data(), + hs->secret().size()) || + !CBB_add_asn1_octet_string(&seq, s3->exporter_secret, + s3->exporter_secret_len) || + !CBB_add_asn1_bool(&seq, s3->used_hello_retry_request) || + !CBB_add_asn1_bool(&seq, hs->accept_psk_mode) || + !CBB_add_asn1_int64(&seq, s3->ticket_age_skew) || + !CBB_add_asn1_uint64(&seq, s3->early_data_reason) || + !CBB_add_asn1_uint64(&seq, early_data)) { + return false; + } + if (early_data == early_data_accepted && + !CBB_add_asn1_octet_string(&seq, hs->early_traffic_secret().data(), + hs->early_traffic_secret().size())) { + return false; + } + } + return CBB_flush(out); +} + +static bool CopyExact(Span out, const CBS *in) { + if (CBS_len(in) != out.size()) { + return false; + } + OPENSSL_memcpy(out.data(), CBS_data(in), out.size()); + return true; +} + +bool SSL_apply_handback(SSL *ssl, Span handback) { + if (ssl->do_handshake != nullptr || + ssl->method->is_dtls) { + return false; + } + + SSL3_STATE *const s3 = ssl->s3; + uint64_t handback_version, unused_token_binding_param, cipher, type_u64; + + CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv, + next_proto, alpn, hostname, unused_channel_id, transcript, key_share; + int session_reused, channel_id_negotiated, cert_request, + extended_master_secret, ticket_expected, unused_token_binding, + next_proto_neg_seen; + SSL_SESSION *session = nullptr; + + CBS handback_cbs(handback); + if (!CBS_get_asn1(&handback_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handback_version) || + handback_version != kHandbackVersion || + !CBS_get_asn1_uint64(&seq, &type_u64) || + type_u64 > handback_max_value) { + return false; + } + + handback_t type = static_cast(type_u64); + if (!CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&read_seq) != sizeof(s3->read_sequence) || + !CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&write_seq) != sizeof(s3->write_sequence) || + !CBS_get_asn1(&seq, &server_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&server_rand) != sizeof(s3->server_random) || + !CBS_copy_bytes(&server_rand, s3->server_random, + sizeof(s3->server_random)) || + !CBS_get_asn1(&seq, &client_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&client_rand) != sizeof(s3->client_random) || + !CBS_copy_bytes(&client_rand, s3->client_random, + sizeof(s3->client_random)) || + !CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_bool(&seq, &session_reused) || + !CBS_get_asn1_bool(&seq, &channel_id_negotiated)) { + return false; + } + + s3->hs = ssl_handshake_new(ssl); + SSL_HANDSHAKE *const hs = s3->hs.get(); + if (!session_reused || type == handback_tls13) { + hs->new_session = + SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool); + session = hs->new_session.get(); + } else { + ssl->session = + SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool); + session = ssl->session.get(); + } + + if (!session || !CBS_get_asn1(&seq, &next_proto, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &alpn, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hostname, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &unused_channel_id, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_bool(&seq, &unused_token_binding) || + !CBS_get_asn1_uint64(&seq, &unused_token_binding_param) || + !CBS_get_asn1_bool(&seq, &next_proto_neg_seen) || + !CBS_get_asn1_bool(&seq, &cert_request) || + !CBS_get_asn1_bool(&seq, &extended_master_secret) || + !CBS_get_asn1_bool(&seq, &ticket_expected) || + !CBS_get_asn1_uint64(&seq, &cipher)) { + return false; + } + if ((hs->new_cipher = + SSL_get_cipher_by_value(static_cast(cipher))) == nullptr) { + return false; + } + if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) { + return false; + } + CBS client_handshake_secret, server_handshake_secret, client_traffic_secret_0, + server_traffic_secret_0, secret, exporter_secret, early_traffic_secret; + if (type == handback_tls13) { + int used_hello_retry_request, accept_psk_mode; + uint64_t early_data, early_data_reason; + int64_t ticket_age_skew; + if (!CBS_get_asn1(&seq, &client_traffic_secret_0, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &server_traffic_secret_0, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &client_handshake_secret, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &server_handshake_secret, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &secret, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &exporter_secret, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_bool(&seq, &used_hello_retry_request) || + !CBS_get_asn1_bool(&seq, &accept_psk_mode) || + !CBS_get_asn1_int64(&seq, &ticket_age_skew) || + !CBS_get_asn1_uint64(&seq, &early_data_reason) || + early_data_reason > ssl_early_data_reason_max_value || + !CBS_get_asn1_uint64(&seq, &early_data) || + early_data > early_data_max_value) { + return false; + } + early_data_t early_data_type = static_cast(early_data); + if (early_data_type == early_data_accepted && + !CBS_get_asn1(&seq, &early_traffic_secret, CBS_ASN1_OCTETSTRING)) { + return false; + } + if (ticket_age_skew > std::numeric_limits::max() || + ticket_age_skew < std::numeric_limits::min()) { + return false; + } + s3->ticket_age_skew = static_cast(ticket_age_skew); + s3->used_hello_retry_request = used_hello_retry_request; + hs->accept_psk_mode = accept_psk_mode; + + s3->early_data_reason = + static_cast(early_data_reason); + ssl->enable_early_data = s3->early_data_reason != ssl_early_data_disabled; + s3->skip_early_data = false; + s3->early_data_accepted = false; + hs->early_data_offered = false; + switch (early_data_type) { + case early_data_not_offered: + break; + case early_data_accepted: + s3->early_data_accepted = true; + hs->early_data_offered = true; + hs->can_early_write = true; + hs->can_early_read = true; + hs->in_early_data = true; + break; + case early_data_rejected_hrr: + hs->early_data_offered = true; + break; + case early_data_skipped: + s3->skip_early_data = true; + hs->early_data_offered = true; + break; + default: + return false; + } + } else { + s3->early_data_reason = ssl_early_data_protocol_version; + } + + ssl->version = session->ssl_version; + s3->have_version = true; + if (!ssl_method_supports_version(ssl->method, ssl->version) || + session->cipher != hs->new_cipher || + ssl_protocol_version(ssl) < SSL_CIPHER_get_min_version(session->cipher) || + SSL_CIPHER_get_max_version(session->cipher) < ssl_protocol_version(ssl)) { + return false; + } + ssl->do_handshake = ssl_server_handshake; + ssl->server = true; + switch (type) { + case handback_after_session_resumption: + hs->state = state12_read_change_cipher_spec; + if (!session_reused) { + return false; + } + break; + case handback_after_ecdhe: + hs->state = state12_read_client_certificate; + if (session_reused) { + return false; + } + break; + case handback_after_handshake: + hs->state = state12_finish_server_handshake; + break; + case handback_tls13: + hs->state = state12_tls13; + hs->tls13_state = state13_send_half_rtt_ticket; + break; + default: + return false; + } + s3->session_reused = session_reused; + hs->channel_id_negotiated = channel_id_negotiated; + s3->next_proto_negotiated.CopyFrom(next_proto); + s3->alpn_selected.CopyFrom(alpn); + + const size_t hostname_len = CBS_len(&hostname); + if (hostname_len == 0) { + s3->hostname.reset(); + } else { + char *hostname_str = nullptr; + if (!CBS_strdup(&hostname, &hostname_str)) { + return false; + } + s3->hostname.reset(hostname_str); + } + + hs->next_proto_neg_seen = next_proto_neg_seen; + hs->wait = ssl_hs_flush; + hs->extended_master_secret = extended_master_secret; + hs->ticket_expected = ticket_expected; + s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + hs->cert_request = cert_request; + + if (type != handback_after_handshake && + (!hs->transcript.Init() || + !hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !hs->transcript.Update(transcript))) { + return false; + } + if (type == handback_tls13) { + hs->ResizeSecrets(hs->transcript.DigestLen()); + if (!CopyExact(hs->client_traffic_secret_0(), &client_traffic_secret_0) || + !CopyExact(hs->server_traffic_secret_0(), &server_traffic_secret_0) || + !CopyExact(hs->client_handshake_secret(), &client_handshake_secret) || + !CopyExact(hs->server_handshake_secret(), &server_handshake_secret) || + !CopyExact(hs->secret(), &secret) || + !CopyExact({s3->exporter_secret, hs->transcript.DigestLen()}, + &exporter_secret)) { + return false; + } + s3->exporter_secret_len = CBS_len(&exporter_secret); + + if (s3->early_data_accepted && + !CopyExact(hs->early_traffic_secret(), &early_traffic_secret)) { + return false; + } + } + Array key_block; + switch (type) { + case handback_after_session_resumption: + // The write keys are installed after server Finished, but the client + // keys must wait for ChangeCipherSpec. + if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session, + write_iv)) { + return false; + } + break; + case handback_after_ecdhe: + // The premaster secret is not yet computed, so install no keys. + break; + case handback_after_handshake: + // The handshake is complete, so both keys are installed. + if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session, + write_iv) || + !tls1_configure_aead(ssl, evp_aead_open, &key_block, session, + read_iv)) { + return false; + } + break; + case handback_tls13: + // After server Finished, the application write keys are installed, but + // none of the read keys. The read keys are installed in the state machine + // immediately after processing handback. + if (!tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal, + hs->new_session.get(), + hs->server_traffic_secret_0())) { + return false; + } + break; + } + if (!CopyExact({s3->read_sequence, sizeof(s3->read_sequence)}, &read_seq) || + !CopyExact({s3->write_sequence, sizeof(s3->write_sequence)}, + &write_seq)) { + return false; + } + if (type == handback_after_ecdhe && + (hs->key_shares[0] = SSLKeyShare::Create(&key_share)) == nullptr) { + return false; + } + return true; // Trailing data allowed for extensibility. +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_serialize_capabilities(const SSL *ssl, CBB *out) { + CBB seq; + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !serialize_features(&seq) || // + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, + size_t client_hello_len, + const uint8_t *capabilities, + size_t capabilities_len) { + if (SSL_is_dtls(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + CBS cbs, seq; + CBS_init(&cbs, capabilities, capabilities_len); + UniquePtr hints = MakeUnique(); + if (hints == nullptr || + !CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) || + !apply_remote_features(ssl, &seq)) { + return 0; + } + + SSL3_STATE *const s3 = ssl->s3; + s3->v2_hello_done = true; + s3->has_message = true; + + Array client_hello_msg; + ScopedCBB client_hello_cbb; + CBB client_hello_body; + if (!ssl->method->init_message(ssl, client_hello_cbb.get(), + &client_hello_body, SSL3_MT_CLIENT_HELLO) || + !CBB_add_bytes(&client_hello_body, client_hello, client_hello_len) || + !ssl->method->finish_message(ssl, client_hello_cbb.get(), + &client_hello_msg)) { + return 0; + } + + s3->hs_buf.reset(BUF_MEM_new()); + if (!s3->hs_buf || !BUF_MEM_append(s3->hs_buf.get(), client_hello_msg.data(), + client_hello_msg.size())) { + return 0; + } + + s3->hs->hints_requested = true; + s3->hs->hints = std::move(hints); + return 1; +} + +// |SSL_HANDSHAKE_HINTS| is serialized as the following ASN.1 structure. We use +// implicit tagging to make it a little more compact. +// +// HandshakeHints ::= SEQUENCE { +// serverRandom [0] IMPLICIT OCTET STRING OPTIONAL, +// keyShareHint [1] IMPLICIT KeyShareHint OPTIONAL, +// signatureHint [2] IMPLICIT SignatureHint OPTIONAL, +// -- At most one of decryptedPSKHint or ignorePSKHint may be present. It +// -- corresponds to the first entry in pre_shared_keys. TLS 1.2 session +// -- tickets will use a separate hint, to ensure the caller does not mix +// -- them up. +// decryptedPSKHint [3] IMPLICIT OCTET STRING OPTIONAL, +// ignorePSKHint [4] IMPLICIT NULL OPTIONAL, +// compressCertificateHint [5] IMPLICIT CompressCertificateHint OPTIONAL, +// } +// +// KeyShareHint ::= SEQUENCE { +// groupId INTEGER, +// publicKey OCTET STRING, +// secret OCTET STRING, +// } +// +// SignatureHint ::= SEQUENCE { +// algorithm INTEGER, +// input OCTET STRING, +// subjectPublicKeyInfo OCTET STRING, +// signature OCTET STRING, +// } +// +// CompressCertificateHint ::= SEQUENCE { +// algorithm INTEGER, +// input OCTET STRING, +// compressed OCTET STRING, +// } + +// HandshakeHints tags. +static const unsigned kServerRandomTag = CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const unsigned kKeyShareHintTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; +static const unsigned kSignatureHintTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; +static const unsigned kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const unsigned kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const unsigned kCompressCertificateTag = CBS_ASN1_CONTEXT_SPECIFIC | 5; + +int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { + const SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (!ssl->server || !hs->hints_requested) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + const SSL_HANDSHAKE_HINTS *hints = hs->hints.get(); + CBB seq, child; + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE)) { + return 0; + } + + if (!hints->server_random.empty()) { + if (!CBB_add_asn1(&seq, &child, kServerRandomTag) || + !CBB_add_bytes(&child, hints->server_random.data(), + hints->server_random.size())) { + return 0; + } + } + + if (hints->key_share_group_id != 0 && !hints->key_share_public_key.empty() && + !hints->key_share_secret.empty()) { + if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) || + !CBB_add_asn1_uint64(&child, hints->key_share_group_id) || + !CBB_add_asn1_octet_string(&child, hints->key_share_public_key.data(), + hints->key_share_public_key.size()) || + !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(), + hints->key_share_secret.size())) { + return 0; + } + } + + if (hints->signature_algorithm != 0 && !hints->signature_input.empty() && + !hints->signature.empty()) { + if (!CBB_add_asn1(&seq, &child, kSignatureHintTag) || + !CBB_add_asn1_uint64(&child, hints->signature_algorithm) || + !CBB_add_asn1_octet_string(&child, hints->signature_input.data(), + hints->signature_input.size()) || + !CBB_add_asn1_octet_string(&child, hints->signature_spki.data(), + hints->signature_spki.size()) || + !CBB_add_asn1_octet_string(&child, hints->signature.data(), + hints->signature.size())) { + return 0; + } + } + + if (!hints->decrypted_psk.empty()) { + if (!CBB_add_asn1(&seq, &child, kDecryptedPSKTag) || + !CBB_add_bytes(&child, hints->decrypted_psk.data(), + hints->decrypted_psk.size())) { + return 0; + } + } + + if (hints->ignore_psk && // + !CBB_add_asn1(&seq, &child, kIgnorePSKTag)) { + return 0; + } + + if (hints->cert_compression_alg_id != 0 && + !hints->cert_compression_input.empty() && + !hints->cert_compression_output.empty()) { + if (!CBB_add_asn1(&seq, &child, kCompressCertificateTag) || + !CBB_add_asn1_uint64(&child, hints->cert_compression_alg_id) || + !CBB_add_asn1_octet_string(&child, hints->cert_compression_input.data(), + hints->cert_compression_input.size()) || + !CBB_add_asn1_octet_string(&child, + hints->cert_compression_output.data(), + hints->cert_compression_output.size())) { + return 0; + } + } + + return CBB_flush(out); +} + +int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { + if (SSL_is_dtls(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + UniquePtr hints_obj = MakeUnique(); + if (hints_obj == nullptr) { + return 0; + } + + CBS cbs, seq, server_random, key_share, signature_hint, ticket, ignore_psk, + cert_compression; + int has_server_random, has_key_share, has_signature_hint, has_ticket, + has_ignore_psk, has_cert_compression; + CBS_init(&cbs, hints, hints_len); + if (!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_optional_asn1(&seq, &server_random, &has_server_random, + kServerRandomTag) || + !CBS_get_optional_asn1(&seq, &key_share, &has_key_share, + kKeyShareHintTag) || + !CBS_get_optional_asn1(&seq, &signature_hint, &has_signature_hint, + kSignatureHintTag) || + !CBS_get_optional_asn1(&seq, &ticket, &has_ticket, kDecryptedPSKTag) || + !CBS_get_optional_asn1(&seq, &ignore_psk, &has_ignore_psk, + kIgnorePSKTag) || + !CBS_get_optional_asn1(&seq, &cert_compression, &has_cert_compression, + kCompressCertificateTag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + + if (has_server_random && !hints_obj->server_random.CopyFrom(server_random)) { + return 0; + } + + if (has_key_share) { + uint64_t group_id; + CBS public_key, secret; + if (!CBS_get_asn1_uint64(&key_share, &group_id) || // + group_id == 0 || group_id > 0xffff || + !CBS_get_asn1(&key_share, &public_key, CBS_ASN1_OCTETSTRING) || + !hints_obj->key_share_public_key.CopyFrom(public_key) || + !CBS_get_asn1(&key_share, &secret, CBS_ASN1_OCTETSTRING) || + !hints_obj->key_share_secret.CopyFrom(secret)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + hints_obj->key_share_group_id = static_cast(group_id); + } + + if (has_signature_hint) { + uint64_t sig_alg; + CBS input, spki, signature; + if (!CBS_get_asn1_uint64(&signature_hint, &sig_alg) || // + sig_alg == 0 || sig_alg > 0xffff || + !CBS_get_asn1(&signature_hint, &input, CBS_ASN1_OCTETSTRING) || + !hints_obj->signature_input.CopyFrom(input) || + !CBS_get_asn1(&signature_hint, &spki, CBS_ASN1_OCTETSTRING) || + !hints_obj->signature_spki.CopyFrom(spki) || + !CBS_get_asn1(&signature_hint, &signature, CBS_ASN1_OCTETSTRING) || + !hints_obj->signature.CopyFrom(signature)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + hints_obj->signature_algorithm = static_cast(sig_alg); + } + + if (has_ticket && !hints_obj->decrypted_psk.CopyFrom(ticket)) { + return 0; + } + + if (has_ignore_psk) { + if (CBS_len(&ignore_psk) != 0) { + return 0; + } + hints_obj->ignore_psk = true; + } + + if (has_cert_compression) { + uint64_t alg; + CBS input, output; + if (!CBS_get_asn1_uint64(&cert_compression, &alg) || // + alg == 0 || alg > 0xffff || + !CBS_get_asn1(&cert_compression, &input, CBS_ASN1_OCTETSTRING) || + !hints_obj->cert_compression_input.CopyFrom(input) || + !CBS_get_asn1(&cert_compression, &output, CBS_ASN1_OCTETSTRING) || + !hints_obj->cert_compression_output.CopyFrom(output)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + hints_obj->cert_compression_alg_id = static_cast(alg); + } + + ssl->s3->hs->hints = std::move(hints_obj); + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake.cc new file mode 100644 index 00000000..d139975e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake.cc @@ -0,0 +1,758 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ + +#include + +#include + +#include + +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg) + : ssl(ssl_arg), + ech_is_inner(false), + ech_authenticated_reject(false), + scts_requested(false), + handshake_finalized(false), + accept_psk_mode(false), + cert_request(false), + certificate_status_expected(false), + ocsp_stapling_requested(false), + delegated_credential_requested(false), + should_ack_sni(false), + in_false_start(false), + in_early_data(false), + early_data_offered(false), + can_early_read(false), + can_early_write(false), + next_proto_neg_seen(false), + ticket_expected(false), + extended_master_secret(false), + pending_private_key_op(false), + handback(false), + hints_requested(false), + cert_compression_negotiated(false), + apply_jdk11_workaround(false), + can_release_private_key(false), + channel_id_negotiated(false) { + assert(ssl); + + // Draw entropy for all GREASE values at once. This avoids calling + // |RAND_bytes| repeatedly and makes the values consistent within a + // connection. The latter is so the second ClientHello matches after + // HelloRetryRequest and so supported_groups and key_shares are consistent. + RAND_bytes(grease_seed, sizeof(grease_seed)); +} + +SSL_HANDSHAKE::~SSL_HANDSHAKE() { + ssl->ctx->x509_method->hs_flush_cached_ca_names(this); +} + +void SSL_HANDSHAKE::ResizeSecrets(size_t hash_len) { + if (hash_len > SSL_MAX_MD_SIZE) { + abort(); + } + hash_len_ = hash_len; +} + +bool SSL_HANDSHAKE::GetClientHello(SSLMessage *out_msg, + SSL_CLIENT_HELLO *out_client_hello) { + if (!ech_client_hello_buf.empty()) { + // If the backing buffer is non-empty, the ClientHelloInner has been set. + out_msg->is_v2_hello = false; + out_msg->type = SSL3_MT_CLIENT_HELLO; + out_msg->raw = CBS(ech_client_hello_buf); + out_msg->body = MakeConstSpan(ech_client_hello_buf).subspan(4); + } else if (!ssl->method->get_message(ssl, out_msg)) { + // The message has already been read, so this cannot fail. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!ssl_client_hello_init(ssl, out_client_hello, out_msg->body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + return true; +} + +UniquePtr ssl_handshake_new(SSL *ssl) { + UniquePtr hs = MakeUnique(ssl); + if (!hs || !hs->transcript.Init()) { + return nullptr; + } + hs->config = ssl->config.get(); + if (!hs->config) { + assert(hs->config); + return nullptr; + } + return hs; +} + +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) { + if (msg.type != type) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type); + return false; + } + + return true; +} + +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) { + Array msg; + if (!ssl->method->finish_message(ssl, cbb, &msg) || + !ssl->method->add_message(ssl, std::move(msg))) { + return false; + } + + return true; +} + +size_t ssl_max_handshake_message_len(const SSL *ssl) { + // kMaxMessageLen is the default maximum message size for handshakes which do + // not accept peer certificate chains. + static const size_t kMaxMessageLen = 16384; + + if (SSL_in_init(ssl)) { + SSL_CONFIG *config = ssl->config.get(); // SSL_in_init() implies not NULL. + if ((!ssl->server || (config->verify_mode & SSL_VERIFY_PEER)) && + kMaxMessageLen < ssl->max_cert_list) { + return ssl->max_cert_list; + } + return kMaxMessageLen; + } + + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + // In TLS 1.2 and below, the largest acceptable post-handshake message is + // a HelloRequest. + return 0; + } + + if (ssl->server) { + // The largest acceptable post-handshake message for a server is a + // KeyUpdate. We will never initiate post-handshake auth. + return 1; + } + + // Clients must accept NewSessionTicket, so allow the default size. + return kMaxMessageLen; +} + +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + // V2ClientHello messages are pre-hashed. + if (msg.is_v2_hello) { + return true; + } + + return hs->transcript.Update(msg.raw); +} + +bool ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + std::initializer_list extensions, + bool ignore_unknown) { + // Reset everything. + for (SSLExtension *ext : extensions) { + ext->present = false; + CBS_init(&ext->data, nullptr, 0); + if (!ext->allowed) { + assert(!ignore_unknown); + } + } + + CBS copy = *cbs; + while (CBS_len(©) != 0) { + uint16_t type; + CBS data; + if (!CBS_get_u16(©, &type) || + !CBS_get_u16_length_prefixed(©, &data)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + SSLExtension *found = nullptr; + for (SSLExtension *ext : extensions) { + if (type == ext->type && ext->allowed) { + found = ext; + break; + } + } + + if (found == nullptr) { + if (ignore_unknown) { + continue; + } + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + + // Duplicate ext_types are forbidden. + if (found->present) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + found->present = true; + found->data = data; + } + + return true; +} + +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *prev_session = ssl->s3->established_session.get(); + if (prev_session != NULL) { + // If renegotiating, the server must not change the server certificate. See + // https://mitls.org/pages/attacks/3SHAKE. We never resume on renegotiation, + // so this check is sufficient to ensure the reported peer certificate never + // changes on renegotiation. + assert(!ssl->server); + if (sk_CRYPTO_BUFFER_num(prev_session->certs.get()) != + sk_CRYPTO_BUFFER_num(hs->new_session->certs.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()); + i++) { + const CRYPTO_BUFFER *old_cert = + sk_CRYPTO_BUFFER_value(prev_session->certs.get(), i); + const CRYPTO_BUFFER *new_cert = + sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), i); + if (CRYPTO_BUFFER_len(old_cert) != CRYPTO_BUFFER_len(new_cert) || + OPENSSL_memcmp(CRYPTO_BUFFER_data(old_cert), + CRYPTO_BUFFER_data(new_cert), + CRYPTO_BUFFER_len(old_cert)) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + } + + // The certificate is identical, so we may skip re-verifying the + // certificate. Since we only authenticated the previous one, copy other + // authentication from the established session and ignore what was newly + // received. + hs->new_session->ocsp_response = UpRef(prev_session->ocsp_response); + hs->new_session->signed_cert_timestamp_list = + UpRef(prev_session->signed_cert_timestamp_list); + hs->new_session->verify_result = prev_session->verify_result; + return ssl_verify_ok; + } + + uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; + enum ssl_verify_result_t ret; + if (hs->config->custom_verify_callback != nullptr) { + ret = hs->config->custom_verify_callback(ssl, &alert); + switch (ret) { + case ssl_verify_ok: + hs->new_session->verify_result = X509_V_OK; + break; + case ssl_verify_invalid: + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (hs->config->verify_mode == SSL_VERIFY_NONE) { + ERR_clear_error(); + ret = ssl_verify_ok; + } + hs->new_session->verify_result = X509_V_ERR_APPLICATION_VERIFICATION; + break; + case ssl_verify_retry: + break; + } + } else { + ret = ssl->ctx->x509_method->session_verify_cert_chain( + hs->new_session.get(), hs, &alert) + ? ssl_verify_ok + : ssl_verify_invalid; + } + + if (ret == ssl_verify_invalid) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + + // Emulate OpenSSL's client OCSP callback. OpenSSL verifies certificates + // before it receives the OCSP, so it needs a second callback for OCSP. + if (ret == ssl_verify_ok && !ssl->server && + hs->config->ocsp_stapling_enabled && + ssl->ctx->legacy_ocsp_callback != nullptr) { + int cb_ret = + ssl->ctx->legacy_ocsp_callback(ssl, ssl->ctx->legacy_ocsp_callback_arg); + if (cb_ret <= 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, + cb_ret == 0 ? SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE + : SSL_AD_INTERNAL_ERROR); + ret = ssl_verify_invalid; + } + } + + return ret; +} + +// Verifies a stored certificate when resuming a session. A few things are +// different from verify_peer_cert: +// 1. We can't be renegotiating if we're resuming a session. +// 2. The session is immutable, so we don't support verify_mode == +// SSL_VERIFY_NONE +// 3. We don't call the OCSP callback. +// 4. We only support custom verify callbacks. +enum ssl_verify_result_t ssl_reverify_peer_cert(SSL_HANDSHAKE *hs, + bool send_alert) { + SSL *const ssl = hs->ssl; + assert(ssl->s3->established_session == nullptr); + assert(hs->config->verify_mode != SSL_VERIFY_NONE); + + uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; + enum ssl_verify_result_t ret = ssl_verify_invalid; + if (hs->config->custom_verify_callback != nullptr) { + ret = hs->config->custom_verify_callback(ssl, &alert); + } + + if (ret == ssl_verify_invalid) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + if (send_alert) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + } + + return ret; +} + +static uint16_t grease_index_to_value(const SSL_HANDSHAKE *hs, + enum ssl_grease_index_t index) { + // This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16. + uint16_t ret = hs->grease_seed[index]; + ret = (ret & 0xf0) | 0x0a; + ret |= ret << 8; + return ret; +} + +uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs, + enum ssl_grease_index_t index) { + uint16_t ret = grease_index_to_value(hs, index); + if (index == ssl_grease_extension2 && + ret == grease_index_to_value(hs, ssl_grease_extension1)) { + // The two fake extensions must not have the same value. GREASE values are + // of the form 0x1a1a, 0x2a2a, 0x3a3a, etc., so XOR to generate a different + // one. + ret ^= 0x1010; + } + return ret; +} + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED)) { + return ssl_hs_error; + } + + // Snapshot the finished hash before incorporating the new message. + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, + ssl_handshake_session(hs), !ssl->server) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + int finished_ok = CBS_mem_equal(&msg.body, finished, finished_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = 1; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return ssl_hs_error; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } + + // The Finished message should be the end of a flight. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +bool ssl_send_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *session = ssl_handshake_session(hs); + + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session, + ssl->server)) { + return false; + } + + // Log the master secret, if logging is enabled. + if (!ssl_log_secret(ssl, "CLIENT_RANDOM", + MakeConstSpan(session->secret, session->secret_length))) { + return false; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, finished, finished_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +bool ssl_output_cert_chain(SSL_HANDSHAKE *hs) { + ScopedCBB cbb; + CBB body; + if (!hs->ssl->method->init_message(hs->ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE) || + !ssl_add_cert_chain(hs, &body) || + !ssl_add_message_cbb(hs->ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs) { + if (hs->new_session) { + return hs->new_session.get(); + } + return hs->ssl->session.get(); +} + +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) { + SSL *const ssl = hs->ssl; + for (;;) { + // Resolve the operation the handshake was waiting on. Each condition may + // halt the handshake by returning, or continue executing if the handshake + // may immediately proceed. Cases which halt the handshake can clear + // |hs->wait| to re-enter the state machine on the next iteration, or leave + // it set to keep the condition sticky. + switch (hs->wait) { + case ssl_hs_error: + ERR_restore_state(hs->error.get()); + return -1; + + case ssl_hs_flush: { + int ret = ssl->method->flush_flight(ssl); + if (ret <= 0) { + return ret; + } + break; + } + + case ssl_hs_read_server_hello: + case ssl_hs_read_message: + case ssl_hs_read_change_cipher_spec: { + if (ssl->quic_method) { + // QUIC has no ChangeCipherSpec messages. + assert(hs->wait != ssl_hs_read_change_cipher_spec); + // The caller should call |SSL_provide_quic_data|. Clear |hs->wait| so + // the handshake can check if there is sufficient data next iteration. + ssl->s3->rwstate = SSL_ERROR_WANT_READ; + hs->wait = ssl_hs_ok; + return -1; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + ssl_open_record_t ret; + if (hs->wait == ssl_hs_read_change_cipher_spec) { + ret = ssl_open_change_cipher_spec(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } else { + ret = ssl_open_handshake(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } + if (ret == ssl_open_record_error && + hs->wait == ssl_hs_read_server_hello) { + uint32_t err = ERR_peek_error(); + if (ERR_GET_LIB(err) == ERR_LIB_SSL && + ERR_GET_REASON(err) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) { + // Add a dedicated error code to the queue for a handshake_failure + // alert in response to ClientHello. This matches NSS's client + // behavior and gives a better error on a (probable) failure to + // negotiate initial parameters. Note: this error code comes after + // the original one. + // + // See https://crbug.com/446505. + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO); + } + } + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (retry) { + continue; + } + ssl->s3->read_buffer.DiscardConsumed(); + break; + } + + case ssl_hs_read_end_of_early_data: { + if (ssl->s3->hs->can_early_read) { + // While we are processing early data, the handshake returns early. + *out_early_return = true; + return 1; + } + hs->wait = ssl_hs_ok; + break; + } + + case ssl_hs_certificate_selection_pending: + ssl->s3->rwstate = SSL_ERROR_PENDING_CERTIFICATE; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_handoff: + ssl->s3->rwstate = SSL_ERROR_HANDOFF; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_handback: { + int ret = ssl->method->flush_flight(ssl); + if (ret <= 0) { + return ret; + } + ssl->s3->rwstate = SSL_ERROR_HANDBACK; + hs->wait = ssl_hs_handback; + return -1; + } + + // The following cases are associated with callback APIs which expect to + // be called each time the state machine runs. Thus they set |hs->wait| + // to |ssl_hs_ok| so that, next time, we re-enter the state machine and + // call the callback again. + case ssl_hs_x509_lookup: + ssl->s3->rwstate = SSL_ERROR_WANT_X509_LOOKUP; + hs->wait = ssl_hs_ok; + return -1; + case ssl_hs_private_key_operation: + ssl->s3->rwstate = SSL_ERROR_WANT_PRIVATE_KEY_OPERATION; + hs->wait = ssl_hs_ok; + return -1; + case ssl_hs_pending_session: + ssl->s3->rwstate = SSL_ERROR_PENDING_SESSION; + hs->wait = ssl_hs_ok; + return -1; + case ssl_hs_pending_ticket: + ssl->s3->rwstate = SSL_ERROR_PENDING_TICKET; + hs->wait = ssl_hs_ok; + return -1; + case ssl_hs_certificate_verify: + ssl->s3->rwstate = SSL_ERROR_WANT_CERTIFICATE_VERIFY; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_early_data_rejected: + assert(ssl->s3->early_data_reason != ssl_early_data_unknown); + assert(!hs->can_early_write); + ssl->s3->rwstate = SSL_ERROR_EARLY_DATA_REJECTED; + return -1; + + case ssl_hs_early_return: + if (!ssl->server) { + // On ECH reject, the handshake should never complete. + assert(ssl->s3->ech_status != ssl_ech_rejected); + } + *out_early_return = true; + hs->wait = ssl_hs_ok; + return 1; + + case ssl_hs_hints_ready: + ssl->s3->rwstate = SSL_ERROR_HANDSHAKE_HINTS_READY; + return -1; + + case ssl_hs_ok: + break; + } + + // Run the state machine again. + hs->wait = ssl->do_handshake(hs); + if (hs->wait == ssl_hs_error) { + hs->error.reset(ERR_save_state()); + return -1; + } + if (hs->wait == ssl_hs_ok) { + if (!ssl->server) { + // On ECH reject, the handshake should never complete. + assert(ssl->s3->ech_status != ssl_ech_rejected); + } + // The handshake has completed. + *out_early_return = false; + return 1; + } + + // Otherwise, loop to the beginning and resolve what was blocking the + // handshake. + } +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_client.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_client.cc new file mode 100644 index 00000000..5f073d4e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_client.cc @@ -0,0 +1,1986 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +enum ssl_client_hs_state_t { + state_start_connect = 0, + state_enter_early_data, + state_early_reverify_server_certificate, + state_read_hello_verify_request, + state_read_server_hello, + state_tls13, + state_read_server_certificate, + state_read_certificate_status, + state_verify_server_certificate, + state_reverify_server_certificate, + state_read_server_key_exchange, + state_read_certificate_request, + state_read_server_hello_done, + state_send_client_certificate, + state_send_client_key_exchange, + state_send_client_certificate_verify, + state_send_client_finished, + state_finish_flight, + state_read_session_ticket, + state_process_change_cipher_spec, + state_read_server_finished, + state_finish_client_handshake, + state_done, +}; + +// ssl_get_client_disabled sets |*out_mask_a| and |*out_mask_k| to masks of +// disabled algorithms. +static void ssl_get_client_disabled(const SSL_HANDSHAKE *hs, + uint32_t *out_mask_a, + uint32_t *out_mask_k) { + *out_mask_a = 0; + *out_mask_k = 0; + + // PSK requires a client callback. + if (hs->config->psk_client_callback == NULL) { + *out_mask_a |= SSL_aPSK; + *out_mask_k |= SSL_kPSK; + } +} + +static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, + ssl_client_hello_type_t type) { + const SSL *const ssl = hs->ssl; + uint32_t mask_a, mask_k; + ssl_get_client_disabled(hs, &mask_a, &mask_k); + + CBB child; + if (!CBB_add_u16_length_prefixed(out, &child)) { + return false; + } + + // Add a fake cipher suite. See RFC 8701. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&child, ssl_get_grease_value(hs, ssl_grease_cipher))) { + return false; + } + + // Add TLS 1.3 ciphers. Order ChaCha20-Poly1305 relative to AES-GCM based on + // hardware support. + if (hs->max_version >= TLS1_3_VERSION) { + if (!EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return false; + } + if (!CBB_add_u16(&child, TLS1_CK_AES_128_GCM_SHA256 & 0xffff) || + !CBB_add_u16(&child, TLS1_CK_AES_256_GCM_SHA384 & 0xffff)) { + return false; + } + if (EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return false; + } + } + + if (hs->min_version < TLS1_3_VERSION && type != ssl_client_hello_inner) { + bool any_enabled = false; + for (const SSL_CIPHER *cipher : SSL_get_ciphers(ssl)) { + // Skip disabled ciphers + if ((cipher->algorithm_mkey & mask_k) || + (cipher->algorithm_auth & mask_a)) { + continue; + } + if (SSL_CIPHER_get_min_version(cipher) > hs->max_version || + SSL_CIPHER_get_max_version(cipher) < hs->min_version) { + continue; + } + any_enabled = true; + if (!CBB_add_u16(&child, SSL_CIPHER_get_protocol_id(cipher))) { + return false; + } + } + + // If all ciphers were disabled, return the error to the caller. + if (!any_enabled && hs->max_version < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); + return false; + } + } + + if (ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + if (!CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) { + return false; + } + } + + return CBB_flush(out); +} + +bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, + CBB *cbb, + ssl_client_hello_type_t type, + bool empty_session_id) { + const SSL *const ssl = hs->ssl; + CBB child; + if (!CBB_add_u16(cbb, hs->client_version) || + !CBB_add_bytes(cbb, + type == ssl_client_hello_inner ? hs->inner_client_random + : ssl->s3->client_random, + SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(cbb, &child)) { + return false; + } + + // Do not send a session ID on renegotiation. + if (!ssl->s3->initial_handshake_complete && + !empty_session_id && + !CBB_add_bytes(&child, hs->session_id, hs->session_id_len)) { + return false; + } + + if (SSL_is_dtls(ssl)) { + if (!CBB_add_u8_length_prefixed(cbb, &child) || + !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { + return false; + } + } + + if (!ssl_write_client_cipher_list(hs, cbb, type) || + !CBB_add_u8(cbb, 1 /* one compression method */) || + !CBB_add_u8(cbb, 0 /* null compression */)) { + return false; + } + return true; +} + +bool ssl_add_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + ssl_client_hello_type_t type = hs->selected_ech_config + ? ssl_client_hello_outer + : ssl_client_hello_unencrypted; + bool needs_psk_binder; + Array msg; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) || + !ssl_write_client_hello_without_extensions(hs, &body, type, + /*empty_session_id=*/false) || + !ssl_add_clienthello_tlsext(hs, &body, /*out_encoded=*/nullptr, + &needs_psk_binder, type, CBB_len(&body)) || + !ssl->method->finish_message(ssl, cbb.get(), &msg)) { + return false; + } + + // Now that the length prefixes have been computed, fill in the placeholder + // PSK binder. + if (needs_psk_binder) { + // ClientHelloOuter cannot have a PSK binder. Otherwise the + // ClientHellOuterAAD computation would break. + assert(type != ssl_client_hello_outer); + if (!tls13_write_psk_binder(hs, hs->transcript, MakeSpan(msg), + /*out_binder_len=*/0)) { + return false; + } + } + + return ssl->method->add_message(ssl, std::move(msg)); +} + +static bool parse_server_version(const SSL_HANDSHAKE *hs, uint16_t *out_version, + uint8_t *out_alert, + const ParsedServerHello &server_hello) { + // If the outer version is not TLS 1.2, use it. + // TODO(davidben): This function doesn't quite match the RFC8446 formulation. + if (server_hello.legacy_version != TLS1_2_VERSION) { + *out_version = server_hello.legacy_version; + return true; + } + + SSLExtension supported_versions(TLSEXT_TYPE_supported_versions); + CBS extensions = server_hello.extensions; + if (!ssl_parse_extensions(&extensions, out_alert, {&supported_versions}, + /*ignore_unknown=*/true)) { + return false; + } + + if (!supported_versions.present) { + *out_version = server_hello.legacy_version; + return true; + } + + if (!CBS_get_u16(&supported_versions.data, out_version) || + CBS_len(&supported_versions.data) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + return true; +} + +// should_offer_early_data returns |ssl_early_data_accepted| if |hs| should +// offer early data, and some other reason code otherwise. +static ssl_early_data_reason_t should_offer_early_data( + const SSL_HANDSHAKE *hs) { + const SSL *const ssl = hs->ssl; + assert(!ssl->server); + if (!ssl->enable_early_data) { + return ssl_early_data_disabled; + } + + if (hs->max_version < TLS1_3_VERSION) { + // We discard inapplicable sessions, so this is redundant with the session + // checks below, but reporting that TLS 1.3 was disabled is more useful. + return ssl_early_data_protocol_version; + } + + if (ssl->session == nullptr) { + return ssl_early_data_no_session_offered; + } + + if (ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION || + ssl->session->ticket_max_early_data == 0) { + return ssl_early_data_unsupported_for_session; + } + + if (!ssl->session->early_alpn.empty()) { + if (!ssl_is_alpn_protocol_allowed(hs, ssl->session->early_alpn)) { + // Avoid reporting a confusing value in |SSL_get0_alpn_selected|. + return ssl_early_data_alpn_mismatch; + } + + // If the previous connection negotiated ALPS, only offer 0-RTT when the + // local are settings are consistent with what we'd offer for this + // connection. + if (ssl->session->has_application_settings) { + Span settings; + if (!ssl_get_local_application_settings(hs, &settings, + ssl->session->early_alpn) || + settings != ssl->session->local_application_settings) { + return ssl_early_data_alps_mismatch; + } + } + } + + // Early data has not yet been accepted, but we use it as a success code. + return ssl_early_data_accepted; +} + +void ssl_done_writing_client_hello(SSL_HANDSHAKE *hs) { + hs->ech_client_outer.Reset(); + hs->cookie.Reset(); + hs->key_share_bytes.Reset(); +} + +static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1); + // |session_reused| must be reset in case this is a renegotiation. + ssl->s3->session_reused = false; + + // Freeze the version range. + if (!ssl_get_version_range(hs, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + uint8_t ech_enc[EVP_HPKE_MAX_ENC_LENGTH]; + size_t ech_enc_len; + if (!ssl_select_ech_config(hs, ech_enc, &ech_enc_len)) { + return ssl_hs_error; + } + + // Always advertise the ClientHello version from the original maximum version, + // even on renegotiation. The static RSA key exchange uses this field, and + // some servers fail when it changes across handshakes. + if (SSL_is_dtls(hs->ssl)) { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? DTLS1_2_VERSION : DTLS1_VERSION; + } else { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? TLS1_2_VERSION : hs->max_version; + } + + // If the configured session has expired or is not usable, drop it. We also do + // not offer sessions on renegotiation. + if (ssl->session != nullptr) { + if (ssl->session->is_server || + !ssl_supports_version(hs, ssl->session->ssl_version) || + // Do not offer TLS 1.2 sessions with ECH. ClientHelloInner does not + // offer TLS 1.2, and the cleartext session ID may leak the server + // identity. + (hs->selected_ech_config && + ssl_session_protocol_version(ssl->session.get()) < TLS1_3_VERSION) || + !SSL_SESSION_is_resumable(ssl->session.get()) || + !ssl_session_is_time_valid(ssl, ssl->session.get()) || + (ssl->quic_method != nullptr) != ssl->session->is_quic || + ssl->s3->initial_handshake_complete) { + ssl_set_session(ssl, nullptr); + } + } + + if (!RAND_bytes(ssl->s3->client_random, sizeof(ssl->s3->client_random))) { + return ssl_hs_error; + } + if (hs->selected_ech_config && + !RAND_bytes(hs->inner_client_random, sizeof(hs->inner_client_random))) { + return ssl_hs_error; + } + + // Never send a session ID in QUIC. QUIC uses TLS 1.3 at a minimum and + // disables TLS 1.3 middlebox compatibility mode. + if (ssl->quic_method == nullptr) { + const bool has_id_session = ssl->session != nullptr && + ssl->session->session_id_length > 0 && + ssl->session->ticket.empty(); + const bool has_ticket_session = + ssl->session != nullptr && !ssl->session->ticket.empty(); + if (has_id_session) { + hs->session_id_len = ssl->session->session_id_length; + OPENSSL_memcpy(hs->session_id, ssl->session->session_id, + hs->session_id_len); + } else if (has_ticket_session || hs->max_version >= TLS1_3_VERSION) { + // Send a random session ID. TLS 1.3 always sends one, and TLS 1.2 session + // tickets require a placeholder value to signal resumption. + hs->session_id_len = sizeof(hs->session_id); + if (!RAND_bytes(hs->session_id, hs->session_id_len)) { + return ssl_hs_error; + } + } + } + + ssl_early_data_reason_t reason = should_offer_early_data(hs); + if (reason != ssl_early_data_accepted) { + ssl->s3->early_data_reason = reason; + } else { + hs->early_data_offered = true; + } + + if (!ssl_setup_key_shares(hs, /*override_group_id=*/0) || + !ssl_setup_extension_permutation(hs) || + !ssl_encrypt_client_hello(hs, MakeConstSpan(ech_enc, ech_enc_len)) || + !ssl_add_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_enter_early_data; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (SSL_is_dtls(ssl)) { + hs->state = state_read_hello_verify_request; + return ssl_hs_ok; + } + + if (!hs->early_data_offered) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->session->ssl_version); + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + if (!tls13_init_early_key_schedule(hs, ssl->session.get()) || + !tls13_derive_early_secret(hs)) { + return ssl_hs_error; + } + + // Stash the early data session, so connection properties may be queried out + // of it. + hs->early_session = UpRef(ssl->session); + hs->state = state_early_reverify_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_early_reverify_server_certificate(SSL_HANDSHAKE *hs) { + if (hs->ssl->ctx->reverify_on_resume) { + // Don't send an alert on error. The alert be in early data, which the + // server may not accept anyway. It would also be a mismatch between QUIC + // and TCP because the QUIC early keys are deferred below. + // + // TODO(davidben): The client behavior should be to verify the certificate + // before deciding whether to offer the session and, if invalid, decline to + // send the session. + switch (ssl_reverify_peer_cert(hs, /*send_alert=*/false)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->state = state_early_reverify_server_certificate; + return ssl_hs_certificate_verify; + } + } + + // Defer releasing the 0-RTT key to after certificate reverification, so the + // QUIC implementation does not accidentally write data too early. + if (!tls13_set_traffic_key(hs->ssl, ssl_encryption_early_data, evp_aead_seal, + hs->early_session.get(), + hs->early_traffic_secret())) { + return ssl_hs_error; + } + + hs->in_early_data = true; + hs->can_early_write = true; + hs->state = state_read_server_hello; + return ssl_hs_early_return; +} + +static enum ssl_hs_wait_t do_read_hello_verify_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + assert(SSL_is_dtls(ssl)); + + // When implementing DTLS 1.3, we need to handle the interactions between + // HelloVerifyRequest, DTLS 1.3's HelloVerifyRequest removal, and ECH. + assert(hs->max_version < TLS1_3_VERSION); + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + CBS hello_verify_request = msg.body, cookie; + uint16_t server_version; + if (!CBS_get_u16(&hello_verify_request, &server_version) || + !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || + CBS_len(&cookie) > sizeof(ssl->d1->cookie) || + CBS_len(&hello_verify_request) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + OPENSSL_memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); + ssl->d1->cookie_len = CBS_len(&cookie); + + ssl->method->next_message(ssl); + + // DTLS resets the handshake buffer after HelloVerifyRequest. + if (!hs->transcript.Init()) { + return ssl_hs_error; + } + + if (!ssl_add_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_server_hello; + return ssl_hs_flush; +} + +bool ssl_parse_server_hello(ParsedServerHello *out, uint8_t *out_alert, + const SSLMessage &msg) { + if (msg.type != SSL3_MT_SERVER_HELLO) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return false; + } + out->raw = msg.raw; + CBS body = msg.body; + if (!CBS_get_u16(&body, &out->legacy_version) || + !CBS_get_bytes(&body, &out->random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &out->session_id) || + CBS_len(&out->session_id) > SSL3_SESSION_ID_SIZE || + !CBS_get_u16(&body, &out->cipher_suite) || + !CBS_get_u8(&body, &out->compression_method)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + // In TLS 1.2 and below, empty extensions blocks may be omitted. In TLS 1.3, + // ServerHellos always have extensions, so this can be applied generically. + CBS_init(&out->extensions, nullptr, 0); + if ((CBS_len(&body) != 0 && + !CBS_get_u16_length_prefixed(&body, &out->extensions)) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + return true; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_server_hello; + } + + ParsedServerHello server_hello; + uint16_t server_version; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_server_hello(&server_hello, &alert, msg) || + !parse_server_version(hs, &server_version, &alert, server_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!ssl_supports_version(hs, server_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete); + if (!ssl->s3->have_version) { + ssl->version = server_version; + // At this point, the connection's version is known and ssl->version is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + } else if (server_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + hs->state = state_tls13; + return ssl_hs_ok; + } + + // Clear some TLS 1.3 state that no longer needs to be retained. + hs->key_shares[0].reset(); + hs->key_shares[1].reset(); + ssl_done_writing_client_hello(hs); + + // A TLS 1.2 server would not know to skip the early data we offered. Report + // an error code sooner. The caller may use this error code to implement the + // fallback described in RFC 8446 appendix D.3. + if (hs->early_data_offered) { + // Disconnect early writes. This ensures subsequent |SSL_write| calls query + // the handshake which, in turn, will replay the error code rather than fail + // at the |write_shutdown| check. See https://crbug.com/1078515. + // TODO(davidben): Should all handshake errors do this? What about record + // decryption failures? + hs->can_early_write = false; + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + // TLS 1.2 handshakes cannot accept ECH. + if (hs->selected_ech_config) { + ssl->s3->ech_status = ssl_ech_rejected; + } + + // Copy over the server random. + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_hello.random), + SSL3_RANDOM_SIZE); + + // Enforce the TLS 1.3 anti-downgrade feature. + if (!ssl->s3->initial_handshake_complete && + ssl_supports_version(hs, TLS1_3_VERSION)) { + static_assert( + sizeof(kTLS12DowngradeRandom) == sizeof(kTLS13DowngradeRandom), + "downgrade signals have different size"); + static_assert( + sizeof(kJDK11DowngradeRandom) == sizeof(kTLS13DowngradeRandom), + "downgrade signals have different size"); + auto suffix = + MakeConstSpan(ssl->s3->server_random, sizeof(ssl->s3->server_random)) + .subspan(SSL3_RANDOM_SIZE - sizeof(kTLS13DowngradeRandom)); + if (suffix == kTLS12DowngradeRandom || suffix == kTLS13DowngradeRandom || + suffix == kJDK11DowngradeRandom) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TLS13_DOWNGRADE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + } + + // The cipher must be allowed in the selected version and enabled. + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(server_hello.cipher_suite); + uint32_t mask_a, mask_k; + ssl_get_client_disabled(hs, &mask_a, &mask_k); + if (cipher == nullptr || + (cipher->algorithm_mkey & mask_k) || + (cipher->algorithm_auth & mask_a) || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) || + !sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), nullptr, cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + hs->new_cipher = cipher; + + if (hs->session_id_len != 0 && + CBS_mem_equal(&server_hello.session_id, hs->session_id, + hs->session_id_len)) { + // Echoing the ClientHello session ID in TLS 1.2, whether from the session + // or a synthetic one, indicates resumption. If there was no session (or if + // the session was only offered in ECH ClientHelloInner), this was the + // TLS 1.3 compatibility mode session ID. As we know this is not a session + // the server knows about, any server resuming it is in error. Reject the + // first connection deterministicly, rather than installing an invalid + // session into the session cache. https://crbug.com/796910 + if (ssl->session == nullptr || ssl->s3->ech_status == ssl_ech_rejected) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_ECHOED_INVALID_SESSION_ID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (ssl->session->cipher != hs->new_cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (!ssl_session_is_context_valid(hs, ssl->session.get())) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + // We never offer sessions on renegotiation. + assert(!ssl->s3->initial_handshake_complete); + ssl->s3->session_reused = true; + } else { + // The session wasn't resumed. Create a fresh SSL_SESSION to fill out. + ssl_set_session(ssl, NULL); + if (!ssl_get_new_session(hs)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + // Note: session_id could be empty. + hs->new_session->session_id_length = CBS_len(&server_hello.session_id); + OPENSSL_memcpy(hs->new_session->session_id, + CBS_data(&server_hello.session_id), + CBS_len(&server_hello.session_id)); + hs->new_session->cipher = hs->new_cipher; + } + + // Now that the cipher is known, initialize the handshake hash and hash the + // ServerHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // If doing a full handshake, the server may request a client certificate + // which requires hashing the handshake transcript. Otherwise, the handshake + // buffer may be released. + if (ssl->session != NULL || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->transcript.FreeBuffer(); + } + + // Only the NULL compression algorithm is supported. + if (server_hello.compression_method != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!ssl_parse_serverhello_tlsext(hs, &server_hello.extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + if (ssl->session != NULL && + hs->extended_master_secret != ssl->session->extended_master_secret) { + if (ssl->session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION); + } + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + if (ssl->session != NULL) { + if (ssl->ctx->reverify_on_resume && + ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_reverify_server_certificate; + } else { + hs->state = state_read_session_ticket; + } + return ssl_hs_ok; + } + + hs->state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_client_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_certificate_status; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS body = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_cert_chain(&alert, &hs->new_session->certs, &hs->peer_pubkey, + NULL, &body, ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0 || + CBS_len(&body) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl_check_leaf_certificate( + hs, hs->peer_pubkey.get(), + sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), 0))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_read_certificate_status; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_status(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->certificate_status_expected) { + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_CERTIFICATE_STATUS) { + // A server may send status_request in ServerHello and then change its mind + // about sending CertificateStatus. + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_status = msg.body, ocsp_response; + uint8_t status_type; + if (!CBS_get_u8(&certificate_status, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&certificate_status) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + hs->new_session->ocsp_response.reset( + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool)); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_verify_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_server_certificate(SSL_HANDSHAKE *hs) { + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->state = state_verify_server_certificate; + return ssl_hs_certificate_verify; + } + + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_reverify_server_certificate(SSL_HANDSHAKE *hs) { + assert(hs->ssl->ctx->reverify_on_resume); + + switch (ssl_reverify_peer_cert(hs, /*send_alert=*/true)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->state = state_reverify_server_certificate; + return ssl_hs_certificate_verify; + } + + hs->state = state_read_session_ticket; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_SERVER_KEY_EXCHANGE) { + // Some ciphers (pure PSK) have an optional ServerKeyExchange message. + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + hs->state = state_read_certificate_request; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + CBS server_key_exchange = msg.body; + if (alg_a & SSL_aPSK) { + CBS psk_identity_hint; + + // Each of the PSK key exchanges begins with a psk_identity_hint. + if (!CBS_get_u16_length_prefixed(&server_key_exchange, + &psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Store the PSK identity hint for the ClientKeyExchange. Assume that the + // maximum length of a PSK identity hint can be as long as the maximum + // length of a PSK identity. Also do not allow NULL characters; identities + // are saved as C strings. + // + // TODO(davidben): Should invalid hints be ignored? It's a hint rather than + // a specific identity. + if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // Save non-empty identity hints as a C string. Empty identity hints we + // treat as missing. Plain PSK makes it possible to send either no hint + // (omit ServerKeyExchange) or an empty hint, while ECDHE_PSK can only spell + // empty hint. Having different capabilities is odd, so we interpret empty + // and missing as identical. + char *raw = nullptr; + if (CBS_len(&psk_identity_hint) != 0 && + !CBS_strdup(&psk_identity_hint, &raw)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->peer_psk_identity_hint.reset(raw); + } + + if (alg_k & SSL_kECDHE) { + // Parse the server parameters. + uint8_t group_type; + uint16_t group_id; + CBS point; + if (!CBS_get_u8(&server_key_exchange, &group_type) || + group_type != NAMED_CURVE_TYPE || + !CBS_get_u16(&server_key_exchange, &group_id) || + !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Ensure the group is consistent with preferences. + if (!tls1_check_group_id(hs, group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Initialize ECDH and save the peer public key for later. + hs->key_shares[0] = SSLKeyShare::Create(group_id); + if (!hs->key_shares[0] || + !hs->peer_key.CopyFrom(point)) { + return ssl_hs_error; + } + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + // At this point, |server_key_exchange| contains the signature, if any, while + // |msg.body| contains the entire message. From that, derive a CBS containing + // just the parameter. + CBS parameter; + CBS_init(¶meter, CBS_data(&msg.body), + CBS_len(&msg.body) - CBS_len(&server_key_exchange)); + + // ServerKeyExchange should be signed by the server's public key. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&server_key_exchange, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(hs, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // The last field in |server_key_exchange| is the signature. + CBS signature; + if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) || + CBS_len(&server_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + ScopedCBB transcript; + Array transcript_data; + if (!CBB_init(transcript.get(), + 2 * SSL3_RANDOM_SIZE + CBS_len(¶meter)) || + !CBB_add_bytes(transcript.get(), ssl->s3->client_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), ssl->s3->server_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), CBS_data(¶meter), + CBS_len(¶meter)) || + !CBBFinishArray(transcript.get(), &transcript_data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (!ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), transcript_data)) { + // bad signature + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + } else { + // PSK ciphers are the only supported certificate-less ciphers. + assert(alg_a == SSL_aPSK); + + if (CBS_len(&server_key_exchange) > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + } + + ssl->method->next_message(ssl); + hs->state = state_read_certificate_request; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type == SSL3_MT_SERVER_HELLO_DONE) { + // If we get here we don't need the handshake buffer as we won't be doing + // client auth. + hs->transcript.FreeBuffer(); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_REQUEST) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Get the certificate types. + CBS body = msg.body, certificate_types; + if (!CBS_get_u8_length_prefixed(&body, &certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->certificate_types.CopyFrom(certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr ca_names = + ssl_parse_client_CA_list(ssl, &alert, &body); + if (!ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + hs->cert_request = true; + hs->ca_names = std::move(ca_names); + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + ssl->method->next_message(ssl); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO_DONE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // ServerHelloDone is empty. + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + // ServerHelloDone should be the end of the flight. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; + } + + if (ssl->s3->ech_status == ssl_ech_rejected) { + // Do not send client certificates on ECH reject. We have not authenticated + // the server for the name that can learn the certificate. + SSL_certs_clear(ssl); + } else if (hs->config->cert->cert_cb != nullptr) { + // Call cert_cb to update the certificate. + int rv = hs->config->cert->cert_cb(ssl, hs->config->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_has_certificate(hs)) { + // Without a client certificate, the handshake buffer may be released. + hs->transcript.FreeBuffer(); + } + + if (!ssl_on_certificate_selected(hs) || + !ssl_output_cert_chain(hs)) { + return ssl_hs_error; + } + + + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; +} + +static_assert(sizeof(size_t) >= sizeof(unsigned), + "size_t is smaller than unsigned"); + +static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + Array pms; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + const CRYPTO_BUFFER *leaf = + sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), 0); + CBS leaf_cbs; + CRYPTO_BUFFER_init_CBS(leaf, &leaf_cbs); + + // Check the key usage matches the cipher suite. We do this unconditionally + // for non-RSA certificates. In particular, it's needed to distinguish ECDH + // certificates, which we do not support, from ECDSA certificates. + // Historically, we have not checked RSA key usages, so it is controlled by + // a flag for now. See https://crbug.com/795089. + ssl_key_usage_t intended_use = (alg_k & SSL_kRSA) + ? key_usage_encipherment + : key_usage_digital_signature; + if (hs->config->enforce_rsa_key_usage || + EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) { + if (!ssl_cert_check_key_usage(&leaf_cbs, intended_use)) { + return ssl_hs_error; + } + } + } + + // If using a PSK key exchange, prepare the pre-shared key. + unsigned psk_len = 0; + uint8_t psk[PSK_MAX_PSK_LEN]; + if (alg_a & SSL_aPSK) { + if (hs->config->psk_client_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB); + return ssl_hs_error; + } + + char identity[PSK_MAX_IDENTITY_LEN + 1]; + OPENSSL_memset(identity, 0, sizeof(identity)); + psk_len = hs->config->psk_client_callback( + ssl, hs->peer_psk_identity_hint.get(), identity, sizeof(identity), psk, + sizeof(psk)); + if (psk_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + assert(psk_len <= PSK_MAX_PSK_LEN); + + hs->new_session->psk_identity.reset(OPENSSL_strdup(identity)); + if (hs->new_session->psk_identity == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + + // Write out psk_identity. + CBB child; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, (const uint8_t *)identity, + OPENSSL_strnlen(identity, sizeof(identity))) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } + + // Depending on the key exchange method, compute |pms|. + if (alg_k & SSL_kRSA) { + if (!pms.Init(SSL_MAX_MASTER_KEY_LENGTH)) { + return ssl_hs_error; + } + + RSA *rsa = EVP_PKEY_get0_RSA(hs->peer_pubkey.get()); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + pms[0] = hs->client_version >> 8; + pms[1] = hs->client_version & 0xff; + if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) { + return ssl_hs_error; + } + + CBB enc_pms; + uint8_t *ptr; + size_t enc_pms_len; + if (!CBB_add_u16_length_prefixed(&body, &enc_pms) || + !CBB_reserve(&enc_pms, &ptr, RSA_size(rsa)) || + !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms.data(), + pms.size(), RSA_PKCS1_PADDING) || + !CBB_did_write(&enc_pms, enc_pms_len) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } else if (alg_k & SSL_kECDHE) { + // Generate a keypair and serialize the public half. + CBB child; + if (!CBB_add_u8_length_prefixed(&body, &child)) { + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_shares[0]->Accept(&child, &pms, &alert, hs->peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + if (!CBB_flush(&body)) { + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_shares[0].reset(); + hs->key_shares[1].reset(); + hs->peer_key.Reset(); + } else if (alg_k & SSL_kPSK) { + // For plain PSK, other_secret is a block of 0s with the same length as + // the pre-shared key. + if (!pms.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(pms.data(), 0, pms.size()); + } else { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // For a PSK cipher suite, other_secret is combined with the pre-shared + // key. + if (alg_a & SSL_aPSK) { + ScopedCBB pms_cbb; + CBB child; + if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, pms.data(), pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(pms_cbb.get(), &pms)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + // The message must be added to the finished hash before calculating the + // master secret. + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->new_session->secret_length = + tls1_generate_master_secret(hs, hs->new_session->secret, pms); + if (hs->new_session->secret_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + + hs->state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->cert_request || !ssl_has_certificate(hs)) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + assert(ssl_has_private_key(hs)); + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + // Write out the digest type in TLS 1.2. + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Set aside space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len = max_sig_len; + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, + hs->transcript.buffer())) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + hs->state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary. + hs->transcript.FreeBuffer(); + + hs->state = state_send_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + hs->can_release_private_key = true; + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal)) { + return ssl_hs_error; + } + + if (hs->next_proto_neg_seen) { + static const uint8_t kZero[32] = {0}; + size_t padding_len = + 32 - ((ssl->s3->next_proto_negotiated.size() + 2) % 32); + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_NEXT_PROTO) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, ssl->s3->next_proto_negotiated.data(), + ssl->s3->next_proto_negotiated.size()) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, kZero, padding_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (hs->channel_id_negotiated) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl_send_finished(hs)) { + return ssl_hs_error; + } + + hs->state = state_finish_flight; + return ssl_hs_flush; +} + +static bool can_false_start(const SSL_HANDSHAKE *hs) { + const SSL *const ssl = hs->ssl; + + // False Start bypasses the Finished check's downgrade protection. This can + // enable attacks where we send data under weaker settings than supported + // (e.g. the Logjam attack). Thus we require TLS 1.2 with an ECDHE+AEAD + // cipher, our strongest settings before TLS 1.3. + // + // Now that TLS 1.3 exists, we would like to avoid similar attacks between + // TLS 1.2 and TLS 1.3, but there are too many TLS 1.2 deployments to + // sacrifice False Start on them. Instead, we rely on the ServerHello.random + // downgrade signal, which we unconditionally enforce. + if (SSL_is_dtls(ssl) || + SSL_version(ssl) != TLS1_2_VERSION || + hs->new_cipher->algorithm_mkey != SSL_kECDHE || + hs->new_cipher->algorithm_mac != SSL_AEAD) { + return false; + } + + // If ECH was rejected, disable False Start. We run the handshake to + // completion, including the Finished downgrade check, to authenticate the + // recovery flow. + if (ssl->s3->ech_status == ssl_ech_rejected) { + return false; + } + + // Additionally require ALPN or NPN by default. + // + // TODO(davidben): Can this constraint be relaxed globally now that cipher + // suite requirements have been tightened? + if (!ssl->ctx->false_start_allowed_without_alpn && + ssl->s3->alpn_selected.empty() && + ssl->s3->next_proto_negotiated.empty()) { + return false; + } + + return true; +} + +static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->session != NULL) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + // This is a full handshake. If it involves ChannelID, then record the + // handshake hashes at this point in the session so that any resumption of + // this session with ChannelID can sign those hashes. + if (!tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_session_ticket; + + if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) && + can_false_start(hs) && + // No False Start on renegotiation (would complicate the state machine). + !ssl->s3->initial_handshake_complete) { + hs->in_false_start = true; + hs->can_early_write = true; + return ssl_hs_early_return; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_session_ticket(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->ticket_expected) { + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEW_SESSION_TICKET) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS new_session_ticket = msg.body, ticket; + uint32_t ticket_lifetime_hint; + if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) || + !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || + CBS_len(&new_session_ticket) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&ticket) == 0) { + // RFC 5077 allows a server to change its mind and send no ticket after + // negotiating the extension. The value of |ticket_expected| is checked in + // |ssl_update_cache| so is cleared here to avoid an unnecessary update. + hs->ticket_expected = false; + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + if (ssl->session != nullptr) { + // The server is sending a new ticket for an existing session. Sessions are + // immutable once established, so duplicate all but the ticket of the + // existing session. + assert(!hs->new_session); + hs->new_session = + SSL_SESSION_dup(ssl->session.get(), SSL_SESSION_INCLUDE_NONAUTH); + if (!hs->new_session) { + return ssl_hs_error; + } + } + + // |ticket_lifetime_hint| is measured from when the ticket was issued. + ssl_session_rebase_time(ssl, hs->new_session.get()); + + if (!hs->new_session->ticket.CopyFrom(ticket)) { + return ssl_hs_error; + } + hs->new_session->ticket_lifetime_hint = ticket_lifetime_hint; + + // Historically, OpenSSL filled in fake session IDs for ticket-based sessions. + // TODO(davidben): Are external callers relying on this? Try removing this. + SHA256(CBS_data(&ticket), CBS_len(&ticket), hs->new_session->session_id); + hs->new_session->session_id_length = SHA256_DIGEST_LENGTH; + + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + hs->state = state_finish_client_handshake; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_finish_client_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->s3->ech_status == ssl_ech_rejected) { + // Release the retry configs. + hs->ech_authenticated_reject = true; + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ECH_REQUIRED); + OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_REJECTED); + return ssl_hs_error; + } + + ssl->method->on_handshake_complete(ssl); + + // Note TLS 1.2 resumptions with ticket renewal have both |ssl->session| (the + // resumed session) and |hs->new_session| (the session with the new ticket). + bool has_new_session = hs->new_session != nullptr; + if (has_new_session) { + // When False Start is enabled, the handshake reports completion early. The + // caller may then have passed the (then unresuable) |hs->new_session| to + // another thread via |SSL_get0_session| for resumption. To avoid potential + // race conditions in such callers, we duplicate the session before + // clearing |not_resumable|. + ssl->s3->established_session = + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_DUP_ALL); + if (!ssl->s3->established_session) { + return ssl_hs_error; + } + // Renegotiations do not participate in session resumption. + if (!ssl->s3->initial_handshake_complete) { + ssl->s3->established_session->not_resumable = false; + } + + hs->new_session.reset(); + } else { + assert(ssl->session != nullptr); + ssl->s3->established_session = UpRef(ssl->session); + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + if (has_new_session) { + ssl_update_cache(ssl); + } + + hs->state = state_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + ret = do_start_connect(hs); + break; + case state_enter_early_data: + ret = do_enter_early_data(hs); + break; + case state_early_reverify_server_certificate: + ret = do_early_reverify_server_certificate(hs); + break; + case state_read_hello_verify_request: + ret = do_read_hello_verify_request(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_tls13: + ret = do_tls13(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_certificate_status: + ret = do_read_certificate_status(hs); + break; + case state_verify_server_certificate: + ret = do_verify_server_certificate(hs); + break; + case state_reverify_server_certificate: + ret = do_reverify_server_certificate(hs); + break; + case state_read_server_key_exchange: + ret = do_read_server_key_exchange(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_hello_done: + ret = do_read_server_hello_done(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_key_exchange: + ret = do_send_client_key_exchange(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_send_client_finished: + ret = do_send_client_finished(hs); + break; + case state_finish_flight: + ret = do_finish_flight(hs); + break; + case state_read_session_ticket: + ret = do_read_session_ticket(hs); + break; + case state_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_finish_client_handshake: + ret = do_finish_client_handshake(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs) { + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + return "TLS client start_connect"; + case state_enter_early_data: + return "TLS client enter_early_data"; + case state_early_reverify_server_certificate: + return "TLS client early_reverify_server_certificate"; + case state_read_hello_verify_request: + return "TLS client read_hello_verify_request"; + case state_read_server_hello: + return "TLS client read_server_hello"; + case state_tls13: + return tls13_client_handshake_state(hs); + case state_read_server_certificate: + return "TLS client read_server_certificate"; + case state_read_certificate_status: + return "TLS client read_certificate_status"; + case state_verify_server_certificate: + return "TLS client verify_server_certificate"; + case state_reverify_server_certificate: + return "TLS client reverify_server_certificate"; + case state_read_server_key_exchange: + return "TLS client read_server_key_exchange"; + case state_read_certificate_request: + return "TLS client read_certificate_request"; + case state_read_server_hello_done: + return "TLS client read_server_hello_done"; + case state_send_client_certificate: + return "TLS client send_client_certificate"; + case state_send_client_key_exchange: + return "TLS client send_client_key_exchange"; + case state_send_client_certificate_verify: + return "TLS client send_client_certificate_verify"; + case state_send_client_finished: + return "TLS client send_client_finished"; + case state_finish_flight: + return "TLS client finish_flight"; + case state_read_session_ticket: + return "TLS client read_session_ticket"; + case state_process_change_cipher_spec: + return "TLS client process_change_cipher_spec"; + case state_read_server_finished: + return "TLS client read_server_finished"; + case state_finish_client_handshake: + return "TLS client finish_client_handshake"; + case state_done: + return "TLS client done"; + } + + return "TLS client unknown"; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_server.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_server.cc new file mode 100644 index 00000000..365e89d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/handshake_server.cc @@ -0,0 +1,1949 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +bool ssl_client_cipher_list_contains_cipher( + const SSL_CLIENT_HELLO *client_hello, uint16_t id) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + while (CBS_len(&cipher_suites) > 0) { + uint16_t got_id; + if (!CBS_get_u16(&cipher_suites, &got_id)) { + return false; + } + + if (got_id == id) { + return true; + } + } + + return false; +} + +static bool negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + assert(!ssl->s3->have_version); + CBS supported_versions, versions; + if (ssl_client_hello_get_extension(client_hello, &supported_versions, + TLSEXT_TYPE_supported_versions)) { + if (!CBS_get_u8_length_prefixed(&supported_versions, &versions) || + CBS_len(&supported_versions) != 0 || + CBS_len(&versions) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + } else { + // Convert the ClientHello version to an equivalent supported_versions + // extension. + static const uint8_t kTLSVersions[] = { + 0x03, 0x03, // TLS 1.2 + 0x03, 0x02, // TLS 1.1 + 0x03, 0x01, // TLS 1 + }; + + static const uint8_t kDTLSVersions[] = { + 0xfe, 0xfd, // DTLS 1.2 + 0xfe, 0xff, // DTLS 1.0 + }; + + size_t versions_len = 0; + if (SSL_is_dtls(ssl)) { + if (client_hello->version <= DTLS1_2_VERSION) { + versions_len = 4; + } else if (client_hello->version <= DTLS1_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kDTLSVersions + sizeof(kDTLSVersions) - versions_len, + versions_len); + } else { + if (client_hello->version >= TLS1_2_VERSION) { + versions_len = 6; + } else if (client_hello->version >= TLS1_1_VERSION) { + versions_len = 4; + } else if (client_hello->version >= TLS1_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kTLSVersions + sizeof(kTLSVersions) - versions_len, + versions_len); + } + } + + if (!ssl_negotiate_version(hs, out_alert, &ssl->version, &versions)) { + return false; + } + + // At this point, the connection's version is known and |ssl->version| is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + + // Handle FALLBACK_SCSV. + if (ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_FALLBACK_SCSV & 0xffff) && + ssl_protocol_version(ssl) < hs->max_version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK); + *out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK; + return false; + } + + return true; +} + +static UniquePtr ssl_parse_client_cipher_list( + const SSL_CLIENT_HELLO *client_hello) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + UniquePtr sk(sk_SSL_CIPHER_new_null()); + if (!sk) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return nullptr; + } + + const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite); + if (c != NULL && !sk_SSL_CIPHER_push(sk.get(), c)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + return sk; +} + +// ssl_get_compatible_server_ciphers determines the key exchange and +// authentication cipher suite masks compatible with the server configuration +// and current ClientHello parameters of |hs|. It sets |*out_mask_k| to the key +// exchange mask and |*out_mask_a| to the authentication mask. +static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs, + uint32_t *out_mask_k, + uint32_t *out_mask_a) { + uint32_t mask_k = 0; + uint32_t mask_a = 0; + + if (ssl_has_certificate(hs)) { + mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get()); + if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) { + mask_k |= SSL_kRSA; + } + } + + // Check for a shared group to consider ECDHE ciphers. + uint16_t unused; + if (tls1_get_shared_group(hs, &unused)) { + mask_k |= SSL_kECDHE; + } + + // PSK requires a server callback. + if (hs->config->psk_server_callback != NULL) { + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + } + + *out_mask_k = mask_k; + *out_mask_a = mask_a; +} + +static const SSL_CIPHER *choose_cipher( + SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello, + const SSLCipherPreferenceList *server_pref) { + SSL *const ssl = hs->ssl; + const STACK_OF(SSL_CIPHER) *prio, *allow; + // in_group_flags will either be NULL, or will point to an array of bytes + // which indicate equal-preference groups in the |prio| stack. See the + // comment about |in_group_flags| in the |SSLCipherPreferenceList| + // struct. + const bool *in_group_flags; + // group_min contains the minimal index so far found in a group, or -1 if no + // such value exists yet. + int group_min = -1; + + UniquePtr client_pref = + ssl_parse_client_cipher_list(client_hello); + if (!client_pref) { + return nullptr; + } + + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = server_pref->ciphers.get(); + in_group_flags = server_pref->in_group_flags; + allow = client_pref.get(); + } else { + prio = client_pref.get(); + in_group_flags = NULL; + allow = server_pref->ciphers.get(); + } + + uint32_t mask_k, mask_a; + ssl_get_compatible_server_ciphers(hs, &mask_k, &mask_a); + + for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(prio, i); + + size_t cipher_index; + if (// Check if the cipher is supported for the current version. + SSL_CIPHER_get_min_version(c) <= ssl_protocol_version(ssl) && + ssl_protocol_version(ssl) <= SSL_CIPHER_get_max_version(c) && + // Check the cipher is supported for the server configuration. + (c->algorithm_mkey & mask_k) && + (c->algorithm_auth & mask_a) && + // Check the cipher is in the |allow| list. + sk_SSL_CIPHER_find(allow, &cipher_index, c)) { + if (in_group_flags != NULL && in_group_flags[i]) { + // This element of |prio| is in a group. Update the minimum index found + // so far and continue looking. + if (group_min == -1 || (size_t)group_min > cipher_index) { + group_min = cipher_index; + } + } else { + if (group_min != -1 && (size_t)group_min < cipher_index) { + cipher_index = group_min; + } + return sk_SSL_CIPHER_value(allow, cipher_index); + } + } + + if (in_group_flags != NULL && !in_group_flags[i] && group_min != -1) { + // We are about to leave a group, but we found a match in it, so that's + // our answer. + return sk_SSL_CIPHER_value(allow, group_min); + } + } + + return nullptr; +} + +static enum ssl_hs_wait_t do_start_accept(SSL_HANDSHAKE *hs) { + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_START, 1); + hs->state = state12_read_client_hello; + return ssl_hs_ok; +} + +// is_probably_jdk11_with_tls13 returns whether |client_hello| was probably sent +// from a JDK 11 client with both TLS 1.3 and a prior version enabled. +static bool is_probably_jdk11_with_tls13(const SSL_CLIENT_HELLO *client_hello) { + // JDK 11 ClientHellos contain a number of unusual properties which should + // limit false positives. + + // JDK 11 does not support ChaCha20-Poly1305. This is unusual: many modern + // clients implement ChaCha20-Poly1305. + if (ssl_client_cipher_list_contains_cipher( + client_hello, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return false; + } + + // JDK 11 always sends extensions in a particular order. + constexpr uint16_t kMaxFragmentLength = 0x0001; + constexpr uint16_t kStatusRequestV2 = 0x0011; + static constexpr struct { + uint16_t id; + bool required; + } kJavaExtensions[] = { + {TLSEXT_TYPE_server_name, false}, + {kMaxFragmentLength, false}, + {TLSEXT_TYPE_status_request, false}, + {TLSEXT_TYPE_supported_groups, true}, + {TLSEXT_TYPE_ec_point_formats, false}, + {TLSEXT_TYPE_signature_algorithms, true}, + // Java always sends signature_algorithms_cert. + {TLSEXT_TYPE_signature_algorithms_cert, true}, + {TLSEXT_TYPE_application_layer_protocol_negotiation, false}, + {kStatusRequestV2, false}, + {TLSEXT_TYPE_extended_master_secret, false}, + {TLSEXT_TYPE_supported_versions, true}, + {TLSEXT_TYPE_cookie, false}, + {TLSEXT_TYPE_psk_key_exchange_modes, true}, + {TLSEXT_TYPE_key_share, true}, + {TLSEXT_TYPE_renegotiate, false}, + {TLSEXT_TYPE_pre_shared_key, false}, + }; + Span sigalgs, sigalgs_cert; + bool has_status_request = false, has_status_request_v2 = false; + CBS extensions, supported_groups; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + for (const auto &java_extension : kJavaExtensions) { + CBS copy = extensions; + uint16_t id; + if (CBS_get_u16(©, &id) && id == java_extension.id) { + // The next extension is the one we expected. + extensions = copy; + CBS body; + if (!CBS_get_u16_length_prefixed(&extensions, &body)) { + return false; + } + switch (id) { + case TLSEXT_TYPE_status_request: + has_status_request = true; + break; + case kStatusRequestV2: + has_status_request_v2 = true; + break; + case TLSEXT_TYPE_signature_algorithms: + sigalgs = body; + break; + case TLSEXT_TYPE_signature_algorithms_cert: + sigalgs_cert = body; + break; + case TLSEXT_TYPE_supported_groups: + supported_groups = body; + break; + } + } else if (java_extension.required) { + return false; + } + } + if (CBS_len(&extensions) != 0) { + return false; + } + + // JDK 11 never advertises X25519. It is not offered by default, and + // -Djdk.tls.namedGroups=x25519 does not work. This is unusual: many modern + // clients implement X25519. + while (CBS_len(&supported_groups) > 0) { + uint16_t group; + if (!CBS_get_u16(&supported_groups, &group) || + group == SSL_CURVE_X25519) { + return false; + } + } + + if (// JDK 11 always sends the same contents in signature_algorithms and + // signature_algorithms_cert. This is unusual: signature_algorithms_cert, + // if omitted, is treated as if it were signature_algorithms. + sigalgs != sigalgs_cert || + // When TLS 1.2 or below is enabled, JDK 11 sends status_request_v2 iff it + // sends status_request. This is unusual: status_request_v2 is not widely + // implemented. + has_status_request != has_status_request_v2) { + return false; + } + + return true; +} + +static bool decrypt_ech(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + CBS body; + if (!ssl_client_hello_get_extension(client_hello, &body, + TLSEXT_TYPE_encrypted_client_hello)) { + return true; + } + uint8_t type; + if (!CBS_get_u8(&body, &type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + if (type != ECH_CLIENT_OUTER) { + return true; + } + // This is a ClientHelloOuter ECH extension. Attempt to decrypt it. + uint8_t config_id; + uint16_t kdf_id, aead_id; + CBS enc, payload; + if (!CBS_get_u16(&body, &kdf_id) || // + !CBS_get_u16(&body, &aead_id) || // + !CBS_get_u8(&body, &config_id) || + !CBS_get_u16_length_prefixed(&body, &enc) || + !CBS_get_u16_length_prefixed(&body, &payload) || // + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + { + MutexReadLock lock(&ssl->ctx->lock); + hs->ech_keys = UpRef(ssl->ctx->ech_keys); + } + + if (!hs->ech_keys) { + ssl->s3->ech_status = ssl_ech_rejected; + return true; + } + + for (const auto &config : hs->ech_keys->configs) { + hs->ech_hpke_ctx.Reset(); + if (config_id != config->ech_config().config_id || + !config->SetupContext(hs->ech_hpke_ctx.get(), kdf_id, aead_id, enc)) { + // Ignore the error and try another ECHConfig. + ERR_clear_error(); + continue; + } + bool is_decrypt_error; + if (!ssl_client_hello_decrypt(hs, out_alert, &is_decrypt_error, + &hs->ech_client_hello_buf, client_hello, + payload)) { + if (is_decrypt_error) { + // Ignore the error and try another ECHConfig. + ERR_clear_error(); + // The |out_alert| calling convention currently relies on a default of + // |SSL_AD_DECODE_ERROR|. https://crbug.com/boringssl/373 tracks + // switching to sum types, which avoids this. + *out_alert = SSL_AD_DECODE_ERROR; + continue; + } + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + return false; + } + hs->ech_config_id = config_id; + ssl->s3->ech_status = ssl_ech_accepted; + return true; + } + + // If we did not accept ECH, proceed with the ClientHelloOuter. Note this + // could be key mismatch or ECH GREASE, so we must complete the handshake + // as usual, except EncryptedExtensions will contain retry configs. + ssl->s3->ech_status = ssl_ech_rejected; + return true; +} + +static bool extract_sni(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + CBS sni; + if (!ssl_client_hello_get_extension(client_hello, &sni, + TLSEXT_TYPE_server_name)) { + // No SNI extension to parse. + return true; + } + + CBS server_name_list, host_name; + uint8_t name_type; + if (!CBS_get_u16_length_prefixed(&sni, &server_name_list) || + !CBS_get_u8(&server_name_list, &name_type) || + // Although the server_name extension was intended to be extensible to + // new name types and multiple names, OpenSSL 1.0.x had a bug which meant + // different name types will cause an error. Further, RFC 4366 originally + // defined syntax inextensibly. RFC 6066 corrected this mistake, but + // adding new name types is no longer feasible. + // + // Act as if the extensibility does not exist to simplify parsing. + !CBS_get_u16_length_prefixed(&server_name_list, &host_name) || + CBS_len(&server_name_list) != 0 || + CBS_len(&sni) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (name_type != TLSEXT_NAMETYPE_host_name || + CBS_len(&host_name) == 0 || + CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || + CBS_contains_zero_byte(&host_name)) { + *out_alert = SSL_AD_UNRECOGNIZED_NAME; + return false; + } + + // Copy the hostname as a string. + char *raw = nullptr; + if (!CBS_strdup(&host_name, &raw)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + ssl->s3->hostname.reset(raw); + + hs->should_ack_sni = true; + return true; +} + +static enum ssl_hs_wait_t do_read_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg.body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // ClientHello should be the end of the flight. We check this early to cover + // all protocol versions. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + if (hs->config->handoff) { + return ssl_hs_handoff; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!decrypt_ech(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // ECH may have changed which ClientHello we process. Update |msg| and + // |client_hello| in case. + if (!hs->GetClientHello(&msg, &client_hello)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (!extract_sni(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + hs->state = state12_read_client_hello_after_ech; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_hello_after_ech(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg_unused; + SSL_CLIENT_HELLO client_hello; + if (!hs->GetClientHello(&msg_unused, &client_hello)) { + return ssl_hs_error; + } + + // Run the early callback. + if (ssl->ctx->select_certificate_cb != NULL) { + switch (ssl->ctx->select_certificate_cb(&client_hello)) { + case ssl_select_cert_retry: + return ssl_hs_certificate_selection_pending; + + case ssl_select_cert_error: + // Connection rejected. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + + default: + /* fallthrough */; + } + } + + // Freeze the version range after the early callback. + if (!ssl_get_version_range(hs, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + if (hs->config->jdk11_workaround && + is_probably_jdk11_with_tls13(&client_hello)) { + hs->apply_jdk11_workaround = true; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!negotiate_version(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + hs->client_version = client_hello.version; + if (client_hello.random_len != SSL3_RANDOM_SIZE) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + OPENSSL_memcpy(ssl->s3->client_random, client_hello.random, + client_hello.random_len); + + // Only null compression is supported. TLS 1.3 further requires the peer + // advertise no other compression. + if (OPENSSL_memchr(client_hello.compression_methods, 0, + client_hello.compression_methods_len) == NULL || + (ssl_protocol_version(ssl) >= TLS1_3_VERSION && + client_hello.compression_methods_len != 1)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // TLS extensions. + if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + hs->state = state12_select_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_select_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Call |cert_cb| to update server certificates if required. + if (hs->config->cert->cert_cb != NULL) { + int rv = hs->config->cert->cert_cb(ssl, hs->config->cert->cert_cb_arg); + if (rv == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs)) { + return ssl_hs_error; + } + + if (hs->ocsp_stapling_requested && + ssl->ctx->legacy_ocsp_callback != nullptr) { + switch (ssl->ctx->legacy_ocsp_callback( + ssl, ssl->ctx->legacy_ocsp_callback_arg)) { + case SSL_TLSEXT_ERR_OK: + break; + case SSL_TLSEXT_ERR_NOACK: + hs->ocsp_stapling_requested = false; + break; + default: + OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // Jump to the TLS 1.3 state machine. + hs->state = state12_tls13; + return ssl_hs_ok; + } + + // It should not be possible to negotiate TLS 1.2 with ECH. The + // ClientHelloInner decoding function rejects ClientHellos which offer TLS 1.2 + // or below. + assert(ssl->s3->ech_status != ssl_ech_accepted); + + // TODO(davidben): Also compute hints for TLS 1.2. When doing so, update the + // check in bssl_shim.cc to test this. + if (hs->hints_requested) { + return ssl_hs_hints_ready; + } + + ssl->s3->early_data_reason = ssl_early_data_protocol_version; + + SSLMessage msg_unused; + SSL_CLIENT_HELLO client_hello; + if (!hs->GetClientHello(&msg_unused, &client_hello)) { + return ssl_hs_error; + } + + // Negotiate the cipher suite. This must be done after |cert_cb| so the + // certificate is finalized. + SSLCipherPreferenceList *prefs = hs->config->cipher_list + ? hs->config->cipher_list.get() + : ssl->ctx->cipher_list.get(); + hs->new_cipher = choose_cipher(hs, &client_hello, prefs); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + hs->state = state12_select_parameters; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_server_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state12_finish_server_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg.body)) { + return ssl_hs_error; + } + + hs->session_id_len = client_hello.session_id_len; + // This is checked in |ssl_client_hello_init|. + assert(hs->session_id_len <= sizeof(hs->session_id)); + OPENSSL_memcpy(hs->session_id, client_hello.session_id, hs->session_id_len); + + // Determine whether we are doing session resumption. + UniquePtr session; + bool tickets_supported = false, renew_ticket = false; + enum ssl_hs_wait_t wait = ssl_get_prev_session( + hs, &session, &tickets_supported, &renew_ticket, &client_hello); + if (wait != ssl_hs_ok) { + return wait; + } + + if (session) { + if (session->extended_master_secret && !hs->extended_master_secret) { + // A ClientHello without EMS that attempts to resume a session with EMS + // is fatal to the connection. + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // If the client offers the EMS extension, but the previous session + // didn't use it, then negotiate a new session. + hs->extended_master_secret != session->extended_master_secret) { + session.reset(); + } + } + + if (session) { + // Use the old session. + hs->ticket_expected = renew_ticket; + ssl->session = std::move(session); + ssl->s3->session_reused = true; + hs->can_release_private_key = true; + } else { + hs->ticket_expected = tickets_supported; + ssl_set_session(ssl, nullptr); + if (!ssl_get_new_session(hs)) { + return ssl_hs_error; + } + + // Assign a session ID if not using session tickets. + if (!hs->ticket_expected && + (ssl->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) { + hs->new_session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + RAND_bytes(hs->new_session->session_id, + hs->new_session->session_id_length); + } + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session == NULL) { + hs->new_session->cipher = hs->new_cipher; + + // Determine whether to request a client certificate. + hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((hs->config->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + hs->channel_id_negotiated) { + hs->cert_request = false; + } + // CertificateRequest may only be sent in certificate-based ciphers. + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->cert_request = false; + } + + if (!hs->cert_request) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Now that all parameters are known, initialize the handshake hash and hash + // the ClientHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Handback includes the whole handshake transcript, so we cannot free the + // transcript buffer in the handback case. + if (!hs->cert_request && !hs->handback) { + hs->transcript.FreeBuffer(); + } + + ssl->method->next_message(ssl); + + hs->state = state12_send_server_hello; + return ssl_hs_ok; +} + +static void copy_suffix(Span out, Span in) { + out = out.last(in.size()); + OPENSSL_memcpy(out.data(), in.data(), in.size()); +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // We only accept ChannelIDs on connections with ECDHE in order to avoid a + // known attack while we fix ChannelID itself. + if (hs->channel_id_negotiated && + (hs->new_cipher->algorithm_mkey & SSL_kECDHE) == 0) { + hs->channel_id_negotiated = false; + } + + // If this is a resumption and the original handshake didn't support + // ChannelID then we didn't record the original handshake hashes in the + // session and so cannot resume with ChannelIDs. + if (ssl->session != NULL && + ssl->session->original_handshake_hash_len == 0) { + hs->channel_id_negotiated = false; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + ssl->s3->server_random[0] = now.tv_sec >> 24; + ssl->s3->server_random[1] = now.tv_sec >> 16; + ssl->s3->server_random[2] = now.tv_sec >> 8; + ssl->s3->server_random[3] = now.tv_sec; + if (!RAND_bytes(ssl->s3->server_random + 4, SSL3_RANDOM_SIZE - 4)) { + return ssl_hs_error; + } + + // Implement the TLS 1.3 anti-downgrade feature. + if (ssl_supports_version(hs, TLS1_3_VERSION)) { + if (ssl_protocol_version(ssl) == TLS1_2_VERSION) { + if (hs->apply_jdk11_workaround) { + // JDK 11 implements the TLS 1.3 downgrade signal, so we cannot send it + // here. However, the signal is only effective if all TLS 1.2 + // ServerHellos produced by the server are marked. Thus we send a + // different non-standard signal for the time being, until JDK 11.0.2 is + // released and clients have updated. + copy_suffix(ssl->s3->server_random, kJDK11DowngradeRandom); + } else { + copy_suffix(ssl->s3->server_random, kTLS13DowngradeRandom); + } + } else { + copy_suffix(ssl->s3->server_random, kTLS12DowngradeRandom); + } + } + + Span session_id; + if (ssl->session != nullptr) { + // Echo the session ID from the ClientHello to indicate resumption. + session_id = MakeConstSpan(hs->session_id, hs->session_id_len); + } else { + session_id = MakeConstSpan(hs->new_session->session_id, + hs->new_session->session_id_length); + } + + ScopedCBB cbb; + CBB body, session_id_bytes; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, ssl->version) || + !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id_bytes) || + !CBB_add_bytes(&session_id_bytes, session_id.data(), session_id.size()) || + !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state12_send_server_finished; + } else { + hs->state = state12_send_server_certificate; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_certificate(hs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!ssl_output_cert_chain(hs)) { + return ssl_hs_error; + } + + if (hs->certificate_status_expected) { + CBB body, ocsp_response; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_STATUS) || + !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&body, &ocsp_response) || + !CBB_add_bytes( + &ocsp_response, + CRYPTO_BUFFER_data(hs->config->cert->ocsp_response.get()), + CRYPTO_BUFFER_len(hs->config->cert->ocsp_response.get())) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + } + + // Assemble ServerKeyExchange parameters if needed. + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) || + ((alg_a & SSL_aPSK) && hs->config->psk_identity_hint)) { + // Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend + // the client and server randoms for the signing transcript. + CBB child; + if (!CBB_init(cbb.get(), SSL3_RANDOM_SIZE * 2 + 128) || + !CBB_add_bytes(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(cbb.get(), ssl->s3->server_random, SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // PSK ciphers begin with an identity hint. + if (alg_a & SSL_aPSK) { + size_t len = hs->config->psk_identity_hint == nullptr + ? 0 + : strlen(hs->config->psk_identity_hint.get()); + if (!CBB_add_u16_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, + (const uint8_t *)hs->config->psk_identity_hint.get(), + len)) { + return ssl_hs_error; + } + } + + if (alg_k & SSL_kECDHE) { + // Determine the group to use. + uint16_t group_id; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Set up ECDH, generate a key, and emit the public half. + hs->key_shares[0] = SSLKeyShare::Create(group_id); + if (!hs->key_shares[0] || + !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) || + !CBB_add_u16(cbb.get(), group_id) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !hs->key_shares[0]->Offer(&child)) { + return ssl_hs_error; + } + } else { + assert(alg_k & SSL_kPSK); + } + + if (!CBBFinishArray(cbb.get(), &hs->server_params)) { + return ssl_hs_error; + } + } + + hs->state = state12_send_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->server_params.size() == 0) { + hs->state = state12_send_server_hello_done; + return ssl_hs_ok; + } + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_KEY_EXCHANGE) || + // |hs->server_params| contains a prefix for signing. + hs->server_params.size() < 2 * SSL3_RANDOM_SIZE || + !CBB_add_bytes(&body, hs->server_params.data() + 2 * SSL3_RANDOM_SIZE, + hs->server_params.size() - 2 * SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // Add a signature. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_private_key(hs)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Determine the signature algorithm. + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Add space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len; + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, hs->server_params)) { + case ssl_private_key_success: + if (!CBB_did_write(&child, sig_len)) { + return ssl_hs_error; + } + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + } + + hs->can_release_private_key = true; + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->server_params.Reset(); + + hs->state = state12_send_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ScopedCBB cbb; + CBB body; + + if (hs->cert_request) { + CBB cert_types, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8_length_prefixed(&body, &cert_types) || + !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) || + !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN) || + (ssl_protocol_version(ssl) >= TLS1_2_VERSION && + (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(hs, &sigalgs_cbb))) || + !ssl_add_client_CA_list(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_HELLO_DONE) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->state = state12_read_client_certificate; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->handback && hs->new_cipher->algorithm_mkey == SSL_kECDHE) { + return ssl_hs_handback; + } + if (!hs->cert_request) { + hs->state = state12_verify_client_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE)) { + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_msg = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_cert_chain(&alert, &hs->new_session->certs, &hs->peer_pubkey, + hs->config->retain_only_sha256_of_client_certs + ? hs->new_session->peer_sha256 + : nullptr, + &certificate_msg, ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (CBS_len(&certificate_msg) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) { + // No client certificate so the handshake buffer may be discarded. + hs->transcript.FreeBuffer(); + + if (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + // Fail for TLS only if we required a certificate + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // OpenSSL returns X509_V_OK when no certificates are received. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } else if (hs->config->retain_only_sha256_of_client_certs) { + // The hash will have been filled in. + hs->new_session->peer_sha256_valid = true; + } + + ssl->method->next_message(ssl); + hs->state = state12_verify_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) { + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) > 0) { + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + return ssl_hs_certificate_verify; + } + } + + hs->state = state12_read_client_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + CBS client_key_exchange = msg.body; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + + // If using a PSK key exchange, parse the PSK identity. + if (alg_a & SSL_aPSK) { + CBS psk_identity; + + // If using PSK, the ClientKeyExchange contains a psk_identity. If PSK, + // then this is the only field in the message. + if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) || + ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + char *raw = nullptr; + if (!CBS_strdup(&psk_identity, &raw)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->new_session->psk_identity.reset(raw); + } + + // Depending on the key exchange method, compute |premaster_secret|. + Array premaster_secret; + if (alg_k & SSL_kRSA) { + CBS encrypted_premaster_secret; + if (!CBS_get_u16_length_prefixed(&client_key_exchange, + &encrypted_premaster_secret) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Allocate a buffer large enough for an RSA decryption. + Array decrypt_buf; + if (!decrypt_buf.Init(EVP_PKEY_size(hs->local_pubkey.get()))) { + return ssl_hs_error; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code below. + size_t decrypt_len; + switch (ssl_private_key_decrypt(hs, decrypt_buf.data(), &decrypt_len, + decrypt_buf.size(), + encrypted_premaster_secret)) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + + if (decrypt_len != decrypt_buf.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + CONSTTIME_SECRET(decrypt_buf.data(), decrypt_len); + + // Prepare a random premaster, to be used on invalid padding. See RFC 5246, + // section 7.4.7.1. + if (!premaster_secret.Init(SSL_MAX_MASTER_KEY_LENGTH) || + !RAND_bytes(premaster_secret.data(), premaster_secret.size())) { + return ssl_hs_error; + } + + // The smallest padded premaster is 11 bytes of overhead. Small keys are + // publicly invalid. + if (decrypt_len < 11 + premaster_secret.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // Check the padding. See RFC 3447, section 7.2.2. + size_t padding_len = decrypt_len - premaster_secret.size(); + uint8_t good = constant_time_eq_int_8(decrypt_buf[0], 0) & + constant_time_eq_int_8(decrypt_buf[1], 2); + for (size_t i = 2; i < padding_len - 1; i++) { + good &= ~constant_time_is_zero_8(decrypt_buf[i]); + } + good &= constant_time_is_zero_8(decrypt_buf[padding_len - 1]); + + // The premaster secret must begin with |client_version|. This too must be + // checked in constant time (http://eprint.iacr.org/2003/052/). + good &= constant_time_eq_8(decrypt_buf[padding_len], + (unsigned)(hs->client_version >> 8)); + good &= constant_time_eq_8(decrypt_buf[padding_len + 1], + (unsigned)(hs->client_version & 0xff)); + + // Select, in constant time, either the decrypted premaster or the random + // premaster based on |good|. + for (size_t i = 0; i < premaster_secret.size(); i++) { + premaster_secret[i] = constant_time_select_8( + good, decrypt_buf[padding_len + i], premaster_secret[i]); + } + } else if (alg_k & SSL_kECDHE) { + // Parse the ClientKeyExchange. + CBS peer_key; + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_shares[0]->Finish(&premaster_secret, &alert, peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_shares[0].reset(); + hs->key_shares[1].reset(); + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // For a PSK cipher suite, the actual pre-master secret is combined with the + // pre-shared key. + if (alg_a & SSL_aPSK) { + if (hs->config->psk_server_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Look up the key for the identity. + uint8_t psk[PSK_MAX_PSK_LEN]; + unsigned psk_len = hs->config->psk_server_callback( + ssl, hs->new_session->psk_identity.get(), psk, sizeof(psk)); + if (psk_len > PSK_MAX_PSK_LEN) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } else if (psk_len == 0) { + // PSK related to the given identity not found. + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY); + return ssl_hs_error; + } + + if (alg_k & SSL_kPSK) { + // In plain PSK, other_secret is a block of 0s with the same length as the + // pre-shared key. + if (!premaster_secret.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(premaster_secret.data(), 0, premaster_secret.size()); + } + + ScopedCBB new_premaster; + CBB child; + if (!CBB_init(new_premaster.get(), + 2 + psk_len + 2 + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, premaster_secret.data(), + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(new_premaster.get(), &premaster_secret)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Compute the master secret. + hs->new_session->secret_length = tls1_generate_master_secret( + hs, hs->new_session->secret, premaster_secret); + if (hs->new_session->secret_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + CONSTTIME_DECLASSIFY(hs->new_session->secret, hs->new_session->secret_length); + hs->can_release_private_key = true; + + ssl->method->next_message(ssl); + hs->state = state12_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Only RSA and ECDSA client certificates are supported, so a + // CertificateVerify is required if and only if there's a client certificate. + if (!hs->peer_pubkey) { + hs->transcript.FreeBuffer(); + hs->state = state12_read_change_cipher_spec; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + // The peer certificate must be valid for signing. + const CRYPTO_BUFFER *leaf = + sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), 0); + CBS leaf_cbs; + CRYPTO_BUFFER_init_CBS(leaf, &leaf_cbs); + if (!ssl_cert_check_key_usage(&leaf_cbs, key_usage_digital_signature)) { + return ssl_hs_error; + } + + CBS certificate_verify = msg.body, signature; + + // Determine the signature algorithm. + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(hs, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // Parse and verify the signature. + if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) || + CBS_len(&certificate_verify) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), hs->transcript.buffer())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary, and we may hash the current + // message. + hs->transcript.FreeBuffer(); + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state12_read_change_cipher_spec; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (hs->handback && hs->ssl->session != NULL) { + return ssl_hs_handback; + } + hs->state = state12_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state12_read_next_proto; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_next_proto(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->next_proto_neg_seen) { + hs->state = state12_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEXT_PROTO) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS next_protocol = msg.body, selected_protocol, padding; + if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || + !CBS_get_u8_length_prefixed(&next_protocol, &padding) || + CBS_len(&next_protocol) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl->s3->next_proto_negotiated.CopyFrom(selected_protocol)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state12_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->channel_id_negotiated) { + hs->state = state12_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state12_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state12_finish_server_handshake; + } else { + hs->state = state12_send_server_finished; + } + + // If this is a full handshake with ChannelID then record the handshake + // hashes in |hs->new_session| in case we need them to verify a + // ChannelID signature on a resumption of this session in the future. + if (ssl->session == NULL && ssl->s3->channel_id_valid && + !tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->ticket_expected) { + const SSL_SESSION *session; + UniquePtr session_copy; + if (ssl->session == NULL) { + // Fix the timeout to measure from the ticket issuance time. + ssl_session_rebase_time(ssl, hs->new_session.get()); + session = hs->new_session.get(); + } else { + // We are renewing an existing session. Duplicate the session to adjust + // the timeout. + session_copy = + SSL_SESSION_dup(ssl->session.get(), SSL_SESSION_INCLUDE_NONAUTH); + if (!session_copy) { + return ssl_hs_error; + } + + ssl_session_rebase_time(ssl, session_copy.get()); + session = session_copy.get(); + } + + ScopedCBB cbb; + CBB body, ticket; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !ssl_encrypt_ticket(hs, &ticket, session) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal) || + !ssl_send_finished(hs)) { + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state12_read_change_cipher_spec; + } else { + hs->state = state12_finish_server_handshake; + } + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->handback) { + return ssl_hs_handback; + } + + ssl->method->on_handshake_complete(ssl); + + // If we aren't retaining peer certificates then we can discard it now. + if (hs->new_session != NULL && + hs->config->retain_only_sha256_of_client_certs) { + hs->new_session->certs.reset(); + ssl->ctx->x509_method->session_clear(hs->new_session.get()); + } + + bool has_new_session = hs->new_session != nullptr; + if (has_new_session) { + assert(ssl->session == nullptr); + ssl->s3->established_session = std::move(hs->new_session); + ssl->s3->established_session->not_resumable = false; + } else { + assert(ssl->session != nullptr); + ssl->s3->established_session = UpRef(ssl->session); + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + if (has_new_session) { + ssl_update_cache(ssl); + } + + hs->state = state12_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state12_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum tls12_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state12_start_accept: + ret = do_start_accept(hs); + break; + case state12_read_client_hello: + ret = do_read_client_hello(hs); + break; + case state12_read_client_hello_after_ech: + ret = do_read_client_hello_after_ech(hs); + break; + case state12_select_certificate: + ret = do_select_certificate(hs); + break; + case state12_tls13: + ret = do_tls13(hs); + break; + case state12_select_parameters: + ret = do_select_parameters(hs); + break; + case state12_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state12_send_server_certificate: + ret = do_send_server_certificate(hs); + break; + case state12_send_server_key_exchange: + ret = do_send_server_key_exchange(hs); + break; + case state12_send_server_hello_done: + ret = do_send_server_hello_done(hs); + break; + case state12_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state12_verify_client_certificate: + ret = do_verify_client_certificate(hs); + break; + case state12_read_client_key_exchange: + ret = do_read_client_key_exchange(hs); + break; + case state12_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state12_read_change_cipher_spec: + ret = do_read_change_cipher_spec(hs); + break; + case state12_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state12_read_next_proto: + ret = do_read_next_proto(hs); + break; + case state12_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state12_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state12_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state12_finish_server_handshake: + ret = do_finish_server_handshake(hs); + break; + case state12_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs) { + enum tls12_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state12_start_accept: + return "TLS server start_accept"; + case state12_read_client_hello: + return "TLS server read_client_hello"; + case state12_read_client_hello_after_ech: + return "TLS server read_client_hello_after_ech"; + case state12_select_certificate: + return "TLS server select_certificate"; + case state12_tls13: + return tls13_server_handshake_state(hs); + case state12_select_parameters: + return "TLS server select_parameters"; + case state12_send_server_hello: + return "TLS server send_server_hello"; + case state12_send_server_certificate: + return "TLS server send_server_certificate"; + case state12_send_server_key_exchange: + return "TLS server send_server_key_exchange"; + case state12_send_server_hello_done: + return "TLS server send_server_hello_done"; + case state12_read_client_certificate: + return "TLS server read_client_certificate"; + case state12_verify_client_certificate: + return "TLS server verify_client_certificate"; + case state12_read_client_key_exchange: + return "TLS server read_client_key_exchange"; + case state12_read_client_certificate_verify: + return "TLS server read_client_certificate_verify"; + case state12_read_change_cipher_spec: + return "TLS server read_change_cipher_spec"; + case state12_process_change_cipher_spec: + return "TLS server process_change_cipher_spec"; + case state12_read_next_proto: + return "TLS server read_next_proto"; + case state12_read_channel_id: + return "TLS server read_channel_id"; + case state12_read_client_finished: + return "TLS server read_client_finished"; + case state12_send_server_finished: + return "TLS server send_server_finished"; + case state12_finish_server_handshake: + return "TLS server finish_server_handshake"; + case state12_done: + return "TLS server done"; + } + + return "TLS server unknown"; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/internal.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/internal.h new file mode 100644 index 00000000..93af5787 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/internal.h @@ -0,0 +1,3947 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef OPENSSL_HEADER_SSL_INTERNAL_H +#define OPENSSL_HEADER_SSL_INTERNAL_H + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/err/internal.h" +#include "../crypto/internal.h" +#include "../crypto/lhash/internal.h" + + +#if defined(OPENSSL_WINDOWS) +// Windows defines struct timeval in winsock2.h. +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#else +#include +#endif + + +BSSL_NAMESPACE_BEGIN + +struct SSL_CONFIG; +struct SSL_HANDSHAKE; +struct SSL_PROTOCOL_METHOD; +struct SSL_X509_METHOD; + +// C++ utilities. + +// New behaves like |new| but uses |OPENSSL_malloc| for memory allocation. It +// returns nullptr on allocation error. It only implements single-object +// allocation and not new T[n]. +// +// Note: unlike |new|, this does not support non-public constructors. +template +T *New(Args &&... args) { + void *t = OPENSSL_malloc(sizeof(T)); + if (t == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + return new (t) T(std::forward(args)...); +} + +// Delete behaves like |delete| but uses |OPENSSL_free| to release memory. +// +// Note: unlike |delete| this does not support non-public destructors. +template +void Delete(T *t) { + if (t != nullptr) { + t->~T(); + OPENSSL_free(t); + } +} + +// All types with kAllowUniquePtr set may be used with UniquePtr. Other types +// may be C structs which require a |BORINGSSL_MAKE_DELETER| registration. +namespace internal { +template +struct DeleterImpl> { + static void Free(T *t) { Delete(t); } +}; +} // namespace internal + +// MakeUnique behaves like |std::make_unique| but returns nullptr on allocation +// error. +template +UniquePtr MakeUnique(Args &&... args) { + return UniquePtr(New(std::forward(args)...)); +} + +#if defined(BORINGSSL_ALLOW_CXX_RUNTIME) +#define HAS_VIRTUAL_DESTRUCTOR +#define PURE_VIRTUAL = 0 +#else +// HAS_VIRTUAL_DESTRUCTOR should be declared in any base class which defines a +// virtual destructor. This avoids a dependency on |_ZdlPv| and prevents the +// class from being used with |delete|. +#define HAS_VIRTUAL_DESTRUCTOR \ + void operator delete(void *) { abort(); } + +// PURE_VIRTUAL should be used instead of = 0 when defining pure-virtual +// functions. This avoids a dependency on |__cxa_pure_virtual| but loses +// compile-time checking. +#define PURE_VIRTUAL \ + { abort(); } +#endif + +// Array is an owning array of elements of |T|. +template +class Array { + public: + // Array's default constructor creates an empty array. + Array() {} + Array(const Array &) = delete; + Array(Array &&other) { *this = std::move(other); } + + ~Array() { Reset(); } + + Array &operator=(const Array &) = delete; + Array &operator=(Array &&other) { + Reset(); + other.Release(&data_, &size_); + return *this; + } + + const T *data() const { return data_; } + T *data() { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + const T &operator[](size_t i) const { return data_[i]; } + T &operator[](size_t i) { return data_[i]; } + + T *begin() { return data_; } + const T *begin() const { return data_; } + T *end() { return data_ + size_; } + const T *end() const { return data_ + size_; } + + void Reset() { Reset(nullptr, 0); } + + // Reset releases the current contents of the array and takes ownership of the + // raw pointer supplied by the caller. + void Reset(T *new_data, size_t new_size) { + for (size_t i = 0; i < size_; i++) { + data_[i].~T(); + } + OPENSSL_free(data_); + data_ = new_data; + size_ = new_size; + } + + // Release releases ownership of the array to a raw pointer supplied by the + // caller. + void Release(T **out, size_t *out_size) { + *out = data_; + *out_size = size_; + data_ = nullptr; + size_ = 0; + } + + // Init replaces the array with a newly-allocated array of |new_size| + // default-constructed copies of |T|. It returns true on success and false on + // error. + // + // Note that if |T| is a primitive type like |uint8_t|, it is uninitialized. + bool Init(size_t new_size) { + Reset(); + if (new_size == 0) { + return true; + } + + if (new_size > std::numeric_limits::max() / sizeof(T)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + data_ = reinterpret_cast(OPENSSL_malloc(new_size * sizeof(T))); + if (data_ == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + size_ = new_size; + for (size_t i = 0; i < size_; i++) { + new (&data_[i]) T; + } + return true; + } + + // CopyFrom replaces the array with a newly-allocated copy of |in|. It returns + // true on success and false on error. + bool CopyFrom(Span in) { + if (!Init(in.size())) { + return false; + } + OPENSSL_memcpy(data_, in.data(), sizeof(T) * in.size()); + return true; + } + + // Shrink shrinks the stored size of the array to |new_size|. It crashes if + // the new size is larger. Note this does not shrink the allocation itself. + void Shrink(size_t new_size) { + if (new_size > size_) { + abort(); + } + for (size_t i = new_size; i < size_; i++) { + data_[i].~T(); + } + size_ = new_size; + } + + private: + T *data_ = nullptr; + size_t size_ = 0; +}; + +// GrowableArray is an array that owns elements of |T|, backed by an +// Array. When necessary, pushing will automatically trigger a resize. +// +// Note, for simplicity, this class currently differs from |std::vector| in that +// |T| must be efficiently default-constructible. Allocated elements beyond the +// end of the array are constructed and destructed. +template +class GrowableArray { + public: + GrowableArray() = default; + GrowableArray(const GrowableArray &) = delete; + GrowableArray(GrowableArray &&other) { *this = std::move(other); } + ~GrowableArray() {} + + GrowableArray &operator=(const GrowableArray &) = delete; + GrowableArray &operator=(GrowableArray &&other) { + size_ = other.size_; + other.size_ = 0; + array_ = std::move(other.array_); + return *this; + } + + const T *data() const { return array_.data(); } + T *data() { return array_.data(); } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + const T &operator[](size_t i) const { return array_[i]; } + T &operator[](size_t i) { return array_[i]; } + + T *begin() { return array_.data(); } + const T *begin() const { return array_.data(); } + T *end() { return array_.data() + size_; } + const T *end() const { return array_.data() + size_; } + + void clear() { + size_ = 0; + array_.Reset(); + } + + // Push adds |elem| at the end of the internal array, growing if necessary. It + // returns false when allocation fails. + bool Push(T elem) { + if (!MaybeGrow()) { + return false; + } + array_[size_] = std::move(elem); + size_++; + return true; + } + + // CopyFrom replaces the contents of the array with a copy of |in|. It returns + // true on success and false on allocation error. + bool CopyFrom(Span in) { + if (!array_.CopyFrom(in)) { + return false; + } + size_ = in.size(); + return true; + } + + private: + // If there is no room for one more element, creates a new backing array with + // double the size of the old one and copies elements over. + bool MaybeGrow() { + if (array_.size() == 0) { + return array_.Init(kDefaultSize); + } + // No need to grow if we have room for one more T. + if (size_ < array_.size()) { + return true; + } + // Double the array's size if it's safe to do so. + if (array_.size() > std::numeric_limits::max() / 2) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + Array new_array; + if (!new_array.Init(array_.size() * 2)) { + return false; + } + for (size_t i = 0; i < array_.size(); i++) { + new_array[i] = std::move(array_[i]); + } + array_ = std::move(new_array); + + return true; + } + + // |size_| is the number of elements stored in this GrowableArray. + size_t size_ = 0; + // |array_| is the backing array. Note that |array_.size()| is this + // GrowableArray's current capacity and that |size_ <= array_.size()|. + Array array_; + // |kDefaultSize| is the default initial size of the backing array. + static constexpr size_t kDefaultSize = 16; +}; + +// CBBFinishArray behaves like |CBB_finish| but stores the result in an Array. +OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array *out); + + +// Protocol versions. +// +// Due to DTLS's historical wire version differences, we maintain two notions of +// version. +// +// The "version" or "wire version" is the actual 16-bit value that appears on +// the wire. It uniquely identifies a version and is also used at API +// boundaries. The set of supported versions differs between TLS and DTLS. Wire +// versions are opaque values and may not be compared numerically. +// +// The "protocol version" identifies the high-level handshake variant being +// used. DTLS versions map to the corresponding TLS versions. Protocol versions +// are sequential and may be compared numerically. + +// ssl_protocol_version_from_wire sets |*out| to the protocol version +// corresponding to wire version |version| and returns true. If |version| is not +// a valid TLS or DTLS version, it returns false. +// +// Note this simultaneously handles both DTLS and TLS. Use one of the +// higher-level functions below for most operations. +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version); + +// ssl_get_version_range sets |*out_min_version| and |*out_max_version| to the +// minimum and maximum enabled protocol versions, respectively. +bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version, + uint16_t *out_max_version); + +// ssl_supports_version returns whether |hs| supports |version|. +bool ssl_supports_version(const SSL_HANDSHAKE *hs, uint16_t version); + +// ssl_method_supports_version returns whether |method| supports |version|. +bool ssl_method_supports_version(const SSL_PROTOCOL_METHOD *method, + uint16_t version); + +// ssl_add_supported_versions writes the supported versions of |hs| to |cbb|, in +// decreasing preference order. The version list is filtered to those whose +// protocol version is at least |extra_min_version|. +bool ssl_add_supported_versions(const SSL_HANDSHAKE *hs, CBB *cbb, + uint16_t extra_min_version); + +// ssl_negotiate_version negotiates a common version based on |hs|'s preferences +// and the peer preference list in |peer_versions|. On success, it returns true +// and sets |*out_version| to the selected version. Otherwise, it returns false +// and sets |*out_alert| to an alert to send. +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions); + +// ssl_protocol_version returns |ssl|'s protocol version. It is an error to +// call this function before the version is determined. +uint16_t ssl_protocol_version(const SSL *ssl); + +// Cipher suites. + +BSSL_NAMESPACE_END + +struct ssl_cipher_st { + // name is the OpenSSL name for the cipher. + const char *name; + // standard_name is the IETF name for the cipher. + const char *standard_name; + // id is the cipher suite value bitwise OR-d with 0x03000000. + uint32_t id; + + // algorithm_* determine the cipher suite. See constants below for the values. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + uint32_t algorithm_prf; +}; + +BSSL_NAMESPACE_BEGIN + +// Bits for |algorithm_mkey| (key exchange algorithm). +#define SSL_kRSA 0x00000001u +#define SSL_kECDHE 0x00000002u +// SSL_kPSK is only set for plain PSK, not ECDHE_PSK. +#define SSL_kPSK 0x00000004u +#define SSL_kGENERIC 0x00000008u + +// Bits for |algorithm_auth| (server authentication). +#define SSL_aRSA 0x00000001u +#define SSL_aECDSA 0x00000002u +// SSL_aPSK is set for both PSK and ECDHE_PSK. +#define SSL_aPSK 0x00000004u +#define SSL_aGENERIC 0x00000008u + +#define SSL_aCERT (SSL_aRSA | SSL_aECDSA) + +// Bits for |algorithm_enc| (symmetric encryption). +#define SSL_3DES 0x00000001u +#define SSL_AES128 0x00000002u +#define SSL_AES256 0x00000004u +#define SSL_AES128GCM 0x00000008u +#define SSL_AES256GCM 0x00000010u +#define SSL_eNULL 0x00000020u +#define SSL_CHACHA20POLY1305 0x00000040u + +#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM) + +// Bits for |algorithm_mac| (symmetric authentication). +#define SSL_SHA1 0x00000001u +// SSL_AEAD is set for all AEADs. +#define SSL_AEAD 0x00000002u + +// Bits for |algorithm_prf| (handshake digest). +#define SSL_HANDSHAKE_MAC_DEFAULT 0x1 +#define SSL_HANDSHAKE_MAC_SHA256 0x2 +#define SSL_HANDSHAKE_MAC_SHA384 0x4 + +// SSL_MAX_MD_SIZE is size of the largest hash function used in TLS, SHA-384. +#define SSL_MAX_MD_SIZE 48 + +// An SSLCipherPreferenceList contains a list of SSL_CIPHERs with equal- +// preference groups. For TLS clients, the groups are moot because the server +// picks the cipher and groups cannot be expressed on the wire. However, for +// servers, the equal-preference groups allow the client's preferences to be +// partially respected. (This only has an effect with +// SSL_OP_CIPHER_SERVER_PREFERENCE). +// +// The equal-preference groups are expressed by grouping SSL_CIPHERs together. +// All elements of a group have the same priority: no ordering is expressed +// within a group. +// +// The values in |ciphers| are in one-to-one correspondence with +// |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of +// bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to +// indicate that the corresponding SSL_CIPHER is not the last element of a +// group, or 0 to indicate that it is. +// +// For example, if |in_group_flags| contains all zeros then that indicates a +// traditional, fully-ordered preference. Every SSL_CIPHER is the last element +// of the group (i.e. they are all in a one-element group). +// +// For a more complex example, consider: +// ciphers: A B C D E F +// in_group_flags: 1 1 0 0 1 0 +// +// That would express the following, order: +// +// A E +// B -> D -> F +// C +struct SSLCipherPreferenceList { + static constexpr bool kAllowUniquePtr = true; + + SSLCipherPreferenceList() = default; + ~SSLCipherPreferenceList(); + + bool Init(UniquePtr ciphers, + Span in_group_flags); + bool Init(const SSLCipherPreferenceList &); + + void Remove(const SSL_CIPHER *cipher); + + UniquePtr ciphers; + bool *in_group_flags = nullptr; +}; + +// AllCiphers returns an array of all supported ciphers, sorted by id. +Span AllCiphers(); + +// ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD +// object for |cipher| protocol version |version|. It sets |*out_mac_secret_len| +// and |*out_fixed_iv_len| to the MAC key length and fixed IV length, +// respectively. The MAC key length is zero except for legacy block and stream +// ciphers. It returns true on success and false on error. +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, bool is_dtls); + +// ssl_get_handshake_digest returns the |EVP_MD| corresponding to |version| and +// |cipher|. +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher); + +// ssl_create_cipher_list evaluates |rule_str|. It sets |*out_cipher_list| to a +// newly-allocated |SSLCipherPreferenceList| containing the result. It returns +// true on success and false on failure. If |strict| is true, nonsense will be +// rejected. If false, nonsense will be silently ignored. An empty result is +// considered an error regardless of |strict|. +bool ssl_create_cipher_list(UniquePtr *out_cipher_list, + const char *rule_str, bool strict); + +// ssl_cipher_auth_mask_for_key returns the mask of cipher |algorithm_auth| +// values suitable for use with |key| in TLS 1.2 and below. +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key); + +// ssl_cipher_uses_certificate_auth returns whether |cipher| authenticates the +// server and, optionally, the client with a certificate. +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher); + +// ssl_cipher_requires_server_key_exchange returns whether |cipher| requires a +// ServerKeyExchange message. +// +// This function may return false while still allowing |cipher| an optional +// ServerKeyExchange. This is the case for plain PSK ciphers. +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher); + +// ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the +// length of an encrypted 1-byte record, for use in record-splitting. Otherwise +// it returns zero. +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher); + +// ssl_choose_tls13_cipher returns an |SSL_CIPHER| corresponding with the best +// available from |cipher_suites| compatible with |version| and |group_id|. It +// returns NULL if there isn't a compatible cipher. +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, + uint16_t group_id); + + +// Transcript layer. + +// SSLTranscript maintains the handshake transcript as a combination of a +// buffer and running hash. +class SSLTranscript { + public: + SSLTranscript(); + ~SSLTranscript(); + + SSLTranscript(SSLTranscript &&other) = default; + SSLTranscript &operator=(SSLTranscript &&other) = default; + + // Init initializes the handshake transcript. If called on an existing + // transcript, it resets the transcript and hash. It returns true on success + // and false on failure. + bool Init(); + + // InitHash initializes the handshake hash based on the PRF and contents of + // the handshake transcript. Subsequent calls to |Update| will update the + // rolling hash. It returns one on success and zero on failure. It is an error + // to call this function after the handshake buffer is released. This may be + // called multiple times to change the hash function. + bool InitHash(uint16_t version, const SSL_CIPHER *cipher); + + // UpdateForHelloRetryRequest resets the rolling hash with the + // HelloRetryRequest construction. It returns true on success and false on + // failure. It is an error to call this function before the handshake buffer + // is released. + bool UpdateForHelloRetryRequest(); + + // CopyToHashContext initializes |ctx| with |digest| and the data thus far in + // the transcript. It returns true on success and false on failure. If the + // handshake buffer is still present, |digest| may be any supported digest. + // Otherwise, |digest| must match the transcript hash. + bool CopyToHashContext(EVP_MD_CTX *ctx, const EVP_MD *digest) const; + + Span buffer() const { + return MakeConstSpan(reinterpret_cast(buffer_->data), + buffer_->length); + } + + // FreeBuffer releases the handshake buffer. Subsequent calls to + // |Update| will not update the handshake buffer. + void FreeBuffer(); + + // DigestLen returns the length of the PRF hash. + size_t DigestLen() const; + + // Digest returns the PRF hash. For TLS 1.1 and below, this is + // |EVP_md5_sha1|. + const EVP_MD *Digest() const; + + // Update adds |in| to the handshake buffer and handshake hash, whichever is + // enabled. It returns true on success and false on failure. + bool Update(Span in); + + // GetHash writes the handshake hash to |out| which must have room for at + // least |DigestLen| bytes. On success, it returns true and sets |*out_len| to + // the number of bytes written. Otherwise, it returns false. + bool GetHash(uint8_t *out, size_t *out_len) const; + + // GetFinishedMAC computes the MAC for the Finished message into the bytes + // pointed by |out| and writes the number of bytes to |*out_len|. |out| must + // have room for |EVP_MAX_MD_SIZE| bytes. It returns true on success and false + // on failure. + bool GetFinishedMAC(uint8_t *out, size_t *out_len, const SSL_SESSION *session, + bool from_server) const; + + private: + // buffer_, if non-null, contains the handshake transcript. + UniquePtr buffer_; + // hash, if initialized with an |EVP_MD|, maintains the handshake hash. + ScopedEVP_MD_CTX hash_; +}; + +// tls1_prf computes the PRF function for |ssl|. It fills |out|, using |secret| +// as the secret and |label| as the label. |seed1| and |seed2| are concatenated +// to form the seed parameter. It returns true on success and false on failure. +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2); + + +// Encryption layer. + +// SSLAEADContext contains information about an AEAD that is being used to +// encrypt an SSL connection. +class SSLAEADContext { + public: + SSLAEADContext(uint16_t version, bool is_dtls, const SSL_CIPHER *cipher); + ~SSLAEADContext(); + static constexpr bool kAllowUniquePtr = true; + + SSLAEADContext(const SSLAEADContext &&) = delete; + SSLAEADContext &operator=(const SSLAEADContext &&) = delete; + + // CreateNullCipher creates an |SSLAEADContext| for the null cipher. + static UniquePtr CreateNullCipher(bool is_dtls); + + // Create creates an |SSLAEADContext| using the supplied key material. It + // returns nullptr on error. Only one of |Open| or |Seal| may be used with the + // resulting object, depending on |direction|. |version| is the normalized + // protocol version, so DTLS 1.0 is represented as 0x0301, not 0xffef. + static UniquePtr Create(enum evp_aead_direction_t direction, + uint16_t version, bool is_dtls, + const SSL_CIPHER *cipher, + Span enc_key, + Span mac_key, + Span fixed_iv); + + // CreatePlaceholderForQUIC creates a placeholder |SSLAEADContext| for the + // given cipher and version. The resulting object can be queried for various + // properties but cannot encrypt or decrypt data. + static UniquePtr CreatePlaceholderForQUIC( + uint16_t version, const SSL_CIPHER *cipher); + + // SetVersionIfNullCipher sets the version the SSLAEADContext for the null + // cipher, to make version-specific determinations in the record layer prior + // to a cipher being selected. + void SetVersionIfNullCipher(uint16_t version); + + // ProtocolVersion returns the protocol version associated with this + // SSLAEADContext. It can only be called once |version_| has been set to a + // valid value. + uint16_t ProtocolVersion() const; + + // RecordVersion returns the record version that should be used with this + // SSLAEADContext for record construction and crypto. + uint16_t RecordVersion() const; + + const SSL_CIPHER *cipher() const { return cipher_; } + + // is_null_cipher returns true if this is the null cipher. + bool is_null_cipher() const { return !cipher_; } + + // ExplicitNonceLen returns the length of the explicit nonce. + size_t ExplicitNonceLen() const; + + // MaxOverhead returns the maximum overhead of calling |Seal|. + size_t MaxOverhead() const; + + // SuffixLen calculates the suffix length written by |SealScatter| and writes + // it to |*out_suffix_len|. It returns true on success and false on error. + // |in_len| and |extra_in_len| should equal the argument of the same names + // passed to |SealScatter|. + bool SuffixLen(size_t *out_suffix_len, size_t in_len, + size_t extra_in_len) const; + + // CiphertextLen calculates the total ciphertext length written by + // |SealScatter| and writes it to |*out_len|. It returns true on success and + // false on error. |in_len| and |extra_in_len| should equal the argument of + // the same names passed to |SealScatter|. + bool CiphertextLen(size_t *out_len, size_t in_len, size_t extra_in_len) const; + + // Open authenticates and decrypts |in| in-place. On success, it sets |*out| + // to the plaintext in |in| and returns true. Otherwise, it returns + // false. The output will always be |ExplicitNonceLen| bytes ahead of |in|. + bool Open(Span *out, uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], Span header, + Span in); + + // Seal encrypts and authenticates |in_len| bytes from |in| and writes the + // result to |out|. It returns true on success and false on error. + // + // If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|. + bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + Span header, const uint8_t *in, size_t in_len); + + // SealScatter encrypts and authenticates |in_len| bytes from |in| and splits + // the result between |out_prefix|, |out| and |out_suffix|. It returns one on + // success and zero on error. + // + // On successful return, exactly |ExplicitNonceLen| bytes are written to + // |out_prefix|, |in_len| bytes to |out|, and |SuffixLen| bytes to + // |out_suffix|. + // + // |extra_in| may point to an additional plaintext buffer. If present, + // |extra_in_len| additional bytes are encrypted and authenticated, and the + // ciphertext is written to the beginning of |out_suffix|. |SuffixLen| should + // be used to size |out_suffix| accordingly. + // + // If |in| and |out| alias then |out| must be == |in|. Other arguments may not + // alias anything. + bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], Span header, + const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len); + + bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const; + + private: + // GetAdditionalData returns the additional data, writing into |storage| if + // necessary. + Span GetAdditionalData(uint8_t storage[13], uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], + size_t plaintext_len, + Span header); + + const SSL_CIPHER *cipher_; + ScopedEVP_AEAD_CTX ctx_; + // fixed_nonce_ contains any bytes of the nonce that are fixed for all + // records. + uint8_t fixed_nonce_[12]; + uint8_t fixed_nonce_len_ = 0, variable_nonce_len_ = 0; + // version_ is the wire version that should be used with this AEAD. + uint16_t version_; + // is_dtls_ is whether DTLS is being used with this AEAD. + bool is_dtls_; + // variable_nonce_included_in_record_ is true if the variable nonce + // for a record is included as a prefix before the ciphertext. + bool variable_nonce_included_in_record_ : 1; + // random_variable_nonce_ is true if the variable nonce is + // randomly generated, rather than derived from the sequence + // number. + bool random_variable_nonce_ : 1; + // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the + // variable nonce rather than prepended. + bool xor_fixed_nonce_ : 1; + // omit_length_in_ad_ is true if the length should be omitted in the + // AEAD's ad parameter. + bool omit_length_in_ad_ : 1; + // ad_is_header_ is true if the AEAD's ad parameter is the record header. + bool ad_is_header_ : 1; +}; + + +// DTLS replay bitmap. + +// DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect +// replayed packets. It should be initialized by zeroing every field. +struct DTLS1_BITMAP { + // map is a bit mask of the last 64 sequence numbers. Bit + // |1< *out, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// dtls_open_record implements |tls_open_record| for DTLS. It only returns +// |ssl_open_record_partial| if |in| was empty and sets |*out_consumed| to +// zero. The caller should read one packet and try again. +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_seal_align_prefix_len returns the length of the prefix before the start +// of the bulk of the ciphertext when sealing a record with |ssl|. Callers may +// use this to align buffers. +// +// Note when TLS 1.0 CBC record-splitting is enabled, this includes the one byte +// record and is the offset into second record's ciphertext. Thus sealing a +// small record may result in a smaller output than this value. +// +// TODO(davidben): Is this alignment valuable? Record-splitting makes this a +// mess. +size_t ssl_seal_align_prefix_len(const SSL *ssl); + +// tls_seal_record seals a new record of type |type| and body |in| and writes it +// to |out|. At most |max_out| bytes will be written. It returns true on success +// and false on error. If enabled, |tls_seal_record| implements TLS 1.0 CBC +// 1/n-1 record splitting and may write two records concatenated. +// +// For a large record, the bulk of the ciphertext will begin +// |ssl_seal_align_prefix_len| bytes into out. Aligning |out| appropriately may +// improve performance. It writes at most |in_len| + |SSL_max_seal_overhead| +// bytes to |out|. +// +// |in| and |out| may not alias. +bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len); + +enum dtls1_use_epoch_t { + dtls1_use_previous_epoch, + dtls1_use_current_epoch, +}; + +// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record. +size_t dtls_max_seal_overhead(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in +// front of the plaintext when sealing a record in-place. +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects +// which epoch's cipher state to use. Unlike |tls_seal_record|, |in| and |out| +// may alias but, if they do, |in| must be exactly |dtls_seal_prefix_len| bytes +// ahead of |out|. +bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch); + +// ssl_process_alert processes |in| as an alert and updates |ssl|'s shutdown +// state. It returns one of |ssl_open_record_discard|, |ssl_open_record_error|, +// |ssl_open_record_close_notify|, or |ssl_open_record_fatal_alert| as +// appropriate. +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in); + + +// Private key operations. + +// ssl_has_private_key returns whether |hs| has a private key configured. +bool ssl_has_private_key(const SSL_HANDSHAKE *hs); + +// ssl_private_key_* perform the corresponding operation on +// |SSL_PRIVATE_KEY_METHOD|. If there is a custom private key configured, they +// call the corresponding function or |complete| depending on whether there is a +// pending operation. Otherwise, they implement the operation with +// |EVP_PKEY|. + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in); + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in); + +// ssl_private_key_supports_signature_algorithm returns whether |hs|'s private +// key supports |sigalg|. +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg); + +// ssl_public_key_verify verifies that the |signature| is valid for the public +// key |pkey| and input |in|, using the signature algorithm |sigalg|. +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in); + + +// Key shares. + +// SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. +class SSLKeyShare { + public: + virtual ~SSLKeyShare() {} + static constexpr bool kAllowUniquePtr = true; + HAS_VIRTUAL_DESTRUCTOR + + // Create returns a SSLKeyShare instance for use with group |group_id| or + // nullptr on error. + static UniquePtr Create(uint16_t group_id); + + // Create deserializes an SSLKeyShare instance previously serialized by + // |Serialize|. + static UniquePtr Create(CBS *in); + + // Serializes writes the group ID and private key, in a format that can be + // read by |Create|. + bool Serialize(CBB *out); + + // GroupID returns the group ID. + virtual uint16_t GroupID() const PURE_VIRTUAL; + + // Offer generates a keypair and writes the public value to + // |out_public_key|. It returns true on success and false on error. + virtual bool Offer(CBB *out_public_key) PURE_VIRTUAL; + + // Accept performs a key exchange against the |peer_key| generated by |Offer|. + // On success, it returns true, writes the public value to |out_public_key|, + // and sets |*out_secret| to the shared secret. On failure, it returns false + // and sets |*out_alert| to an alert to send to the peer. + // + // The default implementation calls |Offer| and then |Finish|, assuming a key + // exchange protocol where the peers are symmetric. + virtual bool Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key); + + // Finish performs a key exchange against the |peer_key| generated by + // |Accept|. On success, it returns true and sets |*out_secret| to the shared + // secret. On failure, it returns false and sets |*out_alert| to an alert to + // send to the peer. + virtual bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) PURE_VIRTUAL; + + // SerializePrivateKey writes the private key to |out|, returning true if + // successful and false otherwise. It should be called after |Offer|. + virtual bool SerializePrivateKey(CBB *out) { return false; } + + // DeserializePrivateKey initializes the state of the key exchange from |in|, + // returning true if successful and false otherwise. + virtual bool DeserializePrivateKey(CBS *in) { return false; } +}; + +struct NamedGroup { + int nid; + uint16_t group_id; + const char name[8], alias[11]; +}; + +// NamedGroups returns all supported groups. +Span NamedGroups(); + +// ssl_nid_to_group_id looks up the group corresponding to |nid|. On success, it +// sets |*out_group_id| to the group ID and returns true. Otherwise, it returns +// false. +bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid); + +// ssl_name_to_group_id looks up the group corresponding to the |name| string of +// length |len|. On success, it sets |*out_group_id| to the group ID and returns +// true. Otherwise, it returns false. +bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len); + + +// Handshake messages. + +struct SSLMessage { + bool is_v2_hello; + uint8_t type; + CBS body; + // raw is the entire serialized handshake message, including the TLS or DTLS + // message header. + CBS raw; +}; + +// SSL_MAX_HANDSHAKE_FLIGHT is the number of messages, including +// ChangeCipherSpec, in the longest handshake flight. Currently this is the +// client's second leg in a full handshake when client certificates, NPN, and +// Channel ID, are all enabled. +#define SSL_MAX_HANDSHAKE_FLIGHT 7 + +extern const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE]; +extern const uint8_t kTLS12DowngradeRandom[8]; +extern const uint8_t kTLS13DowngradeRandom[8]; +extern const uint8_t kJDK11DowngradeRandom[8]; + +// ssl_max_handshake_message_len returns the maximum number of bytes permitted +// in a handshake message for |ssl|. +size_t ssl_max_handshake_message_len(const SSL *ssl); + +// tls_can_accept_handshake_data returns whether |ssl| is able to accept more +// data into handshake buffer. +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert); + +// tls_has_unprocessed_handshake_data returns whether there is buffered +// handshake data that has not been consumed by |get_message|. +bool tls_has_unprocessed_handshake_data(const SSL *ssl); + +// tls_append_handshake_data appends |data| to the handshake buffer. It returns +// true on success and false on allocation failure. +bool tls_append_handshake_data(SSL *ssl, Span data); + +// dtls_has_unprocessed_handshake_data behaves like +// |tls_has_unprocessed_handshake_data| for DTLS. +bool dtls_has_unprocessed_handshake_data(const SSL *ssl); + +// tls_flush_pending_hs_data flushes any handshake plaintext data. +bool tls_flush_pending_hs_data(SSL *ssl); + +struct DTLS_OUTGOING_MESSAGE { + DTLS_OUTGOING_MESSAGE() {} + DTLS_OUTGOING_MESSAGE(const DTLS_OUTGOING_MESSAGE &) = delete; + DTLS_OUTGOING_MESSAGE &operator=(const DTLS_OUTGOING_MESSAGE &) = delete; + ~DTLS_OUTGOING_MESSAGE() { Clear(); } + + void Clear(); + + uint8_t *data = nullptr; + uint32_t len = 0; + uint16_t epoch = 0; + bool is_ccs = false; +}; + +// dtls_clear_outgoing_messages releases all buffered outgoing messages. +void dtls_clear_outgoing_messages(SSL *ssl); + + +// Callbacks. + +// ssl_do_info_callback calls |ssl|'s info callback, if set. +void ssl_do_info_callback(const SSL *ssl, int type, int value); + +// ssl_do_msg_callback calls |ssl|'s message callback, if set. +void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type, + Span in); + + +// Transport buffers. + +class SSLBuffer { + public: + SSLBuffer() {} + ~SSLBuffer() { Clear(); } + + SSLBuffer(const SSLBuffer &) = delete; + SSLBuffer &operator=(const SSLBuffer &) = delete; + + uint8_t *data() { return buf_ + offset_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + size_t cap() const { return cap_; } + + Span span() { return MakeSpan(data(), size()); } + + Span remaining() { + return MakeSpan(data() + size(), cap() - size()); + } + + // Clear releases the buffer. + void Clear(); + + // EnsureCap ensures the buffer has capacity at least |new_cap|, aligned such + // that data written after |header_len| is aligned to a + // |SSL3_ALIGN_PAYLOAD|-byte boundary. It returns true on success and false + // on error. + bool EnsureCap(size_t header_len, size_t new_cap); + + // DidWrite extends the buffer by |len|. The caller must have filled in to + // this point. + void DidWrite(size_t len); + + // Consume consumes |len| bytes from the front of the buffer. The memory + // consumed will remain valid until the next call to |DiscardConsumed| or + // |Clear|. + void Consume(size_t len); + + // DiscardConsumed discards the consumed bytes from the buffer. If the buffer + // is now empty, it releases memory used by it. + void DiscardConsumed(); + + private: + // buf_ is the memory allocated for this buffer. + uint8_t *buf_ = nullptr; + // offset_ is the offset into |buf_| which the buffer contents start at. + uint16_t offset_ = 0; + // size_ is the size of the buffer contents from |buf_| + |offset_|. + uint16_t size_ = 0; + // cap_ is how much memory beyond |buf_| + |offset_| is available. + uint16_t cap_ = 0; + // inline_buf_ is a static buffer for short reads. + uint8_t inline_buf_[SSL3_RT_HEADER_LENGTH]; + // buf_allocated_ is true if |buf_| points to allocated data and must be freed + // or false if it points into |inline_buf_|. + bool buf_allocated_ = false; +}; + +// ssl_read_buffer_extend_to extends the read buffer to the desired length. For +// TLS, it reads to the end of the buffer until the buffer is |len| bytes +// long. For DTLS, it reads a new packet and ignores |len|. It returns one on +// success, zero on EOF, and a negative number on error. +// +// It is an error to call |ssl_read_buffer_extend_to| in DTLS when the buffer is +// non-empty. +int ssl_read_buffer_extend_to(SSL *ssl, size_t len); + +// ssl_handle_open_record handles the result of passing |ssl->s3->read_buffer| +// to a record-processing function. If |ret| is a success or if the caller +// should retry, it returns one and sets |*out_retry|. Otherwise, it returns <= +// 0. +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert); + +// ssl_write_buffer_flush flushes the write buffer to the transport. It returns +// one on success and <= 0 on error. For DTLS, whether or not the write +// succeeds, the write buffer will be cleared. +int ssl_write_buffer_flush(SSL *ssl); + + +// Certificate functions. + +// ssl_has_certificate returns whether a certificate and private key are +// configured. +bool ssl_has_certificate(const SSL_HANDSHAKE *hs); + +// ssl_parse_cert_chain parses a certificate list from |cbs| in the format used +// by a TLS Certificate message. On success, it advances |cbs| and returns +// true. Otherwise, it returns false and sets |*out_alert| to an alert to send +// to the peer. +// +// If the list is non-empty then |*out_chain| and |*out_pubkey| will be set to +// the certificate chain and the leaf certificate's public key +// respectively. Otherwise, both will be set to nullptr. +// +// If the list is non-empty and |out_leaf_sha256| is non-NULL, it writes the +// SHA-256 hash of the leaf to |out_leaf_sha256|. +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool); + +// ssl_add_cert_chain adds |hs->ssl|'s certificate chain to |cbb| in the format +// used by a TLS Certificate message. If there is no certificate chain, it emits +// an empty certificate list. It returns true on success and false on error. +bool ssl_add_cert_chain(SSL_HANDSHAKE *hs, CBB *cbb); + +enum ssl_key_usage_t { + key_usage_digital_signature = 0, + key_usage_encipherment = 2, +}; + +// ssl_cert_check_key_usage parses the DER-encoded, X.509 certificate in |in| +// and returns true if doesn't specify a key usage or, if it does, if it +// includes |bit|. Otherwise it pushes to the error queue and returns false. +bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit); + +// ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509 +// certificate in |in|. It returns an allocated |EVP_PKEY| or else returns +// nullptr and pushes to the error queue. +UniquePtr ssl_cert_parse_pubkey(const CBS *in); + +// ssl_parse_client_CA_list parses a CA list from |cbs| in the format used by a +// TLS CertificateRequest message. On success, it returns a newly-allocated +// |CRYPTO_BUFFER| list and advances |cbs|. Otherwise, it returns nullptr and +// sets |*out_alert| to an alert to send to the peer. +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs); + +// ssl_has_client_CAs returns there are configured CAs. +bool ssl_has_client_CAs(const SSL_CONFIG *cfg); + +// ssl_add_client_CA_list adds the configured CA list to |cbb| in the format +// used by a TLS CertificateRequest message. It returns true on success and +// false on error. +bool ssl_add_client_CA_list(SSL_HANDSHAKE *hs, CBB *cbb); + +// ssl_check_leaf_certificate returns one if |pkey| and |leaf| are suitable as +// a server's leaf certificate for |hs|. Otherwise, it returns zero and pushes +// an error on the error queue. +bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf); + +// ssl_on_certificate_selected is called once the certificate has been selected. +// It finalizes the certificate and initializes |hs->local_pubkey|. It returns +// true on success and false on error. +bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs); + + +// TLS 1.3 key derivation. + +// tls13_init_key_schedule initializes the handshake hash and key derivation +// state, and incorporates the PSK. The cipher suite and PRF hash must have been +// selected at this point. It returns true on success and false on error. +bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span psk); + +// tls13_init_early_key_schedule initializes the handshake hash and key +// derivation state from |session| for use with 0-RTT. It returns one on success +// and zero on error. +bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, + const SSL_SESSION *session); + +// tls13_advance_key_schedule incorporates |in| into the key schedule with +// HKDF-Extract. It returns true on success and false on error. +bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span in); + +// tls13_set_traffic_key sets the read or write traffic keys to +// |traffic_secret|. The version and cipher suite are determined from |session|. +// It returns true on success and false on error. +bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level, + enum evp_aead_direction_t direction, + const SSL_SESSION *session, + Span traffic_secret); + +// tls13_derive_early_secret derives the early traffic secret. It returns true +// on success and false on error. +bool tls13_derive_early_secret(SSL_HANDSHAKE *hs); + +// tls13_derive_handshake_secrets derives the handshake traffic secret. It +// returns true on success and false on error. +bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs); + +// tls13_rotate_traffic_key derives the next read or write traffic secret. It +// returns true on success and false on error. +bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction); + +// tls13_derive_application_secrets derives the initial application data traffic +// and exporter secrets based on the handshake transcripts and |master_secret|. +// It returns true on success and false on error. +bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs); + +// tls13_derive_resumption_secret derives the |resumption_secret|. +bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs); + +// tls13_export_keying_material provides an exporter interface to use the +// |exporter_secret|. +bool tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context); + +// tls13_finished_mac calculates the MAC of the handshake transcript to verify +// the integrity of the Finished message, and stores the result in |out| and +// length in |out_len|. |is_server| is true if this is for the Server Finished +// and false for the Client Finished. +bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, + bool is_server); + +// tls13_derive_session_psk calculates the PSK for this session based on the +// resumption master secret and |nonce|. It returns true on success, and false +// on failure. +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce); + +// tls13_write_psk_binder calculates the PSK binder value over |transcript| and +// |msg|, and replaces the last bytes of |msg| with the resulting value. It +// returns true on success, and false on failure. If |out_binder_len| is +// non-NULL, it sets |*out_binder_len| to the length of the value computed. +bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs, + const SSLTranscript &transcript, Span msg, + size_t *out_binder_len); + +// tls13_verify_psk_binder verifies that the handshake transcript, truncated up +// to the binders has a valid signature using the value of |session|'s +// resumption secret. It returns true on success, and false on failure. +bool tls13_verify_psk_binder(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session, const SSLMessage &msg, + CBS *binders); + + +// Encrypted ClientHello. + +struct ECHConfig { + static constexpr bool kAllowUniquePtr = true; + // raw contains the serialized ECHConfig. + Array raw; + // The following fields alias into |raw|. + Span public_key; + Span public_name; + Span cipher_suites; + uint16_t kem_id = 0; + uint8_t maximum_name_length = 0; + uint8_t config_id = 0; +}; + +class ECHServerConfig { + public: + static constexpr bool kAllowUniquePtr = true; + ECHServerConfig() = default; + ECHServerConfig(const ECHServerConfig &other) = delete; + ECHServerConfig &operator=(ECHServerConfig &&) = delete; + + // Init parses |ech_config| as an ECHConfig and saves a copy of |key|. + // It returns true on success and false on error. + bool Init(Span ech_config, const EVP_HPKE_KEY *key, + bool is_retry_config); + + // SetupContext sets up |ctx| for a new connection, given the specified + // HPKE ciphersuite and encapsulated KEM key. It returns true on success and + // false on error. This function may only be called on an initialized object. + bool SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, uint16_t aead_id, + Span enc) const; + + const ECHConfig &ech_config() const { return ech_config_; } + bool is_retry_config() const { return is_retry_config_; } + + private: + ECHConfig ech_config_; + ScopedEVP_HPKE_KEY key_; + bool is_retry_config_ = false; +}; + +enum ssl_client_hello_type_t { + ssl_client_hello_unencrypted, + ssl_client_hello_inner, + ssl_client_hello_outer, +}; + +// ECH_CLIENT_* are types for the ClientHello encrypted_client_hello extension. +#define ECH_CLIENT_OUTER 0 +#define ECH_CLIENT_INNER 1 + +// ssl_decode_client_hello_inner recovers the full ClientHelloInner from the +// EncodedClientHelloInner |encoded_client_hello_inner| by replacing its +// outer_extensions extension with the referenced extensions from the +// ClientHelloOuter |client_hello_outer|. If successful, it writes the recovered +// ClientHelloInner to |out_client_hello_inner|. It returns true on success and +// false on failure. +// +// This function is exported for fuzzing. +OPENSSL_EXPORT bool ssl_decode_client_hello_inner( + SSL *ssl, uint8_t *out_alert, Array *out_client_hello_inner, + Span encoded_client_hello_inner, + const SSL_CLIENT_HELLO *client_hello_outer); + +// ssl_client_hello_decrypt attempts to decrypt and decode the |payload|. It +// writes the result to |*out|. |payload| must point into |client_hello_outer|. +// It returns true on success and false on error. On error, it sets +// |*out_is_decrypt_error| to whether the failure was due to a bad ciphertext. +bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert, + bool *out_is_decrypt_error, Array *out, + const SSL_CLIENT_HELLO *client_hello_outer, + Span payload); + +#define ECH_CONFIRMATION_SIGNAL_LEN 8 + +// ssl_ech_confirmation_signal_hello_offset returns the offset of the ECH +// confirmation signal in a ServerHello message, including the handshake header. +size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl); + +// ssl_ech_accept_confirmation computes the server's ECH acceptance signal, +// writing it to |out|. The transcript portion is the concatenation of +// |transcript| with |msg|. The |ECH_CONFIRMATION_SIGNAL_LEN| bytes from +// |offset| in |msg| are replaced with zeros before hashing. This function +// returns true on success, and false on failure. +bool ssl_ech_accept_confirmation(const SSL_HANDSHAKE *hs, Span out, + Span client_random, + const SSLTranscript &transcript, bool is_hrr, + Span msg, size_t offset); + +// ssl_is_valid_ech_public_name returns true if |public_name| is a valid ECH +// public name and false otherwise. It is exported for testing. +OPENSSL_EXPORT bool ssl_is_valid_ech_public_name( + Span public_name); + +// ssl_is_valid_ech_config_list returns true if |ech_config_list| is a valid +// ECHConfigList structure and false otherwise. +bool ssl_is_valid_ech_config_list(Span ech_config_list); + +// ssl_select_ech_config selects an ECHConfig and associated parameters to offer +// on the client and updates |hs|. It returns true on success, whether an +// ECHConfig was found or not, and false on internal error. On success, the +// encapsulated key is written to |out_enc| and |*out_enc_len| is set to the +// number of bytes written. If the function did not select an ECHConfig, the +// encapsulated key is the empty string. +bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span out_enc, + size_t *out_enc_len); + +// ssl_ech_extension_body_length returns the length of the body of a ClientHello +// ECH extension that encrypts |in_len| bytes with |aead| and an 'enc' value of +// length |enc_len|. The result does not include the four-byte extension header. +size_t ssl_ech_extension_body_length(const EVP_HPKE_AEAD *aead, size_t enc_len, + size_t in_len); + +// ssl_encrypt_client_hello constructs a new ClientHelloInner, adds it to the +// inner transcript, and encrypts for inclusion in the ClientHelloOuter. |enc| +// is the encapsulated key to include in the extension. It returns true on +// success and false on error. If not offering ECH, |enc| is ignored and the +// function will compute a GREASE ECH extension if necessary, and otherwise +// return success while doing nothing. +// +// Encrypting the ClientHelloInner incorporates all extensions in the +// ClientHelloOuter, so all other state necessary for |ssl_add_client_hello| +// must already be computed. +bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span enc); + + +// Delegated credentials. + +// This structure stores a delegated credential (DC) as defined by +// draft-ietf-tls-subcerts-03. +struct DC { + static constexpr bool kAllowUniquePtr = true; + ~DC(); + + // Dup returns a copy of this DC and takes references to |raw| and |pkey|. + UniquePtr Dup(); + + // Parse parses the delegated credential stored in |in|. If successful it + // returns the parsed structure, otherwise it returns |nullptr| and sets + // |*out_alert|. + static UniquePtr Parse(CRYPTO_BUFFER *in, uint8_t *out_alert); + + // raw is the delegated credential encoded as specified in draft-ietf-tls- + // subcerts-03. + UniquePtr raw; + + // expected_cert_verify_algorithm is the signature scheme of the DC public + // key. + uint16_t expected_cert_verify_algorithm = 0; + + // pkey is the public key parsed from |public_key|. + UniquePtr pkey; + + private: + friend DC* New(); + DC(); +}; + +// ssl_signing_with_dc returns true if the peer has indicated support for +// delegated credentials and this host has sent a delegated credential in +// response. If this is true then we've committed to using the DC in the +// handshake. +bool ssl_signing_with_dc(const SSL_HANDSHAKE *hs); + + +// Handshake functions. + +enum ssl_hs_wait_t { + ssl_hs_error, + ssl_hs_ok, + ssl_hs_read_server_hello, + ssl_hs_read_message, + ssl_hs_flush, + ssl_hs_certificate_selection_pending, + ssl_hs_handoff, + ssl_hs_handback, + ssl_hs_x509_lookup, + ssl_hs_private_key_operation, + ssl_hs_pending_session, + ssl_hs_pending_ticket, + ssl_hs_early_return, + ssl_hs_early_data_rejected, + ssl_hs_read_end_of_early_data, + ssl_hs_read_change_cipher_spec, + ssl_hs_certificate_verify, + ssl_hs_hints_ready, +}; + +enum ssl_grease_index_t { + ssl_grease_cipher = 0, + ssl_grease_group, + ssl_grease_extension1, + ssl_grease_extension2, + ssl_grease_version, + ssl_grease_ticket_extension, + ssl_grease_ech_config_id, + ssl_grease_last_index = ssl_grease_ech_config_id, +}; + +enum tls12_server_hs_state_t { + state12_start_accept = 0, + state12_read_client_hello, + state12_read_client_hello_after_ech, + state12_select_certificate, + state12_tls13, + state12_select_parameters, + state12_send_server_hello, + state12_send_server_certificate, + state12_send_server_key_exchange, + state12_send_server_hello_done, + state12_read_client_certificate, + state12_verify_client_certificate, + state12_read_client_key_exchange, + state12_read_client_certificate_verify, + state12_read_change_cipher_spec, + state12_process_change_cipher_spec, + state12_read_next_proto, + state12_read_channel_id, + state12_read_client_finished, + state12_send_server_finished, + state12_finish_server_handshake, + state12_done, +}; + +enum tls13_server_hs_state_t { + state13_select_parameters = 0, + state13_select_session, + state13_send_hello_retry_request, + state13_read_second_client_hello, + state13_send_server_hello, + state13_send_server_certificate_verify, + state13_send_server_finished, + state13_send_half_rtt_ticket, + state13_read_second_client_flight, + state13_process_end_of_early_data, + state13_read_client_encrypted_extensions, + state13_read_client_certificate, + state13_read_client_certificate_verify, + state13_read_channel_id, + state13_read_client_finished, + state13_send_new_session_ticket, + state13_done, +}; + +// handback_t lists the points in the state machine where a handback can occur. +// These are the different points at which key material is no longer needed. +enum handback_t { + handback_after_session_resumption = 0, + handback_after_ecdhe = 1, + handback_after_handshake = 2, + handback_tls13 = 3, + handback_max_value = handback_tls13, +}; + +// SSL_HANDSHAKE_HINTS contains handshake hints for a connection. See +// |SSL_request_handshake_hints| and related functions. +struct SSL_HANDSHAKE_HINTS { + static constexpr bool kAllowUniquePtr = true; + + Array server_random; + + uint16_t key_share_group_id = 0; + Array key_share_public_key; + Array key_share_secret; + + uint16_t signature_algorithm = 0; + Array signature_input; + Array signature_spki; + Array signature; + + Array decrypted_psk; + bool ignore_psk = false; + + uint16_t cert_compression_alg_id = 0; + Array cert_compression_input; + Array cert_compression_output; +}; + +struct SSL_HANDSHAKE { + explicit SSL_HANDSHAKE(SSL *ssl); + ~SSL_HANDSHAKE(); + static constexpr bool kAllowUniquePtr = true; + + // ssl is a non-owning pointer to the parent |SSL| object. + SSL *ssl; + + // config is a non-owning pointer to the handshake configuration. + SSL_CONFIG *config; + + // wait contains the operation the handshake is currently blocking on or + // |ssl_hs_ok| if none. + enum ssl_hs_wait_t wait = ssl_hs_ok; + + // state is the internal state for the TLS 1.2 and below handshake. Its + // values depend on |do_handshake| but the starting state is always zero. + int state = 0; + + // tls13_state is the internal state for the TLS 1.3 handshake. Its values + // depend on |do_handshake| but the starting state is always zero. + int tls13_state = 0; + + // min_version is the minimum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_min_proto_version| APIs. + uint16_t min_version = 0; + + // max_version is the maximum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_max_proto_version| APIs. + uint16_t max_version = 0; + + private: + size_t hash_len_ = 0; + uint8_t secret_[SSL_MAX_MD_SIZE] = {0}; + uint8_t early_traffic_secret_[SSL_MAX_MD_SIZE] = {0}; + uint8_t client_handshake_secret_[SSL_MAX_MD_SIZE] = {0}; + uint8_t server_handshake_secret_[SSL_MAX_MD_SIZE] = {0}; + uint8_t client_traffic_secret_0_[SSL_MAX_MD_SIZE] = {0}; + uint8_t server_traffic_secret_0_[SSL_MAX_MD_SIZE] = {0}; + uint8_t expected_client_finished_[SSL_MAX_MD_SIZE] = {0}; + + public: + void ResizeSecrets(size_t hash_len); + + // GetClientHello, on the server, returns either the normal ClientHello + // message or the ClientHelloInner if it has been serialized to + // |ech_client_hello_buf|. This function should only be called when the + // current message is a ClientHello. It returns true on success and false on + // error. + // + // Note that fields of the returned |out_msg| and |out_client_hello| point + // into a handshake-owned buffer, so their lifetimes should not exceed this + // SSL_HANDSHAKE. + bool GetClientHello(SSLMessage *out_msg, SSL_CLIENT_HELLO *out_client_hello); + + Span secret() { return MakeSpan(secret_, hash_len_); } + Span secret() const { + return MakeConstSpan(secret_, hash_len_); + } + Span early_traffic_secret() { + return MakeSpan(early_traffic_secret_, hash_len_); + } + Span client_handshake_secret() { + return MakeSpan(client_handshake_secret_, hash_len_); + } + Span server_handshake_secret() { + return MakeSpan(server_handshake_secret_, hash_len_); + } + Span client_traffic_secret_0() { + return MakeSpan(client_traffic_secret_0_, hash_len_); + } + Span server_traffic_secret_0() { + return MakeSpan(server_traffic_secret_0_, hash_len_); + } + Span expected_client_finished() { + return MakeSpan(expected_client_finished_, hash_len_); + } + + union { + // sent is a bitset where the bits correspond to elements of kExtensions + // in extensions.cc. Each bit is set if that extension was sent in a + // ClientHello. It's not used by servers. + uint32_t sent = 0; + // received is a bitset, like |sent|, but is used by servers to record + // which extensions were received from a client. + uint32_t received; + } extensions; + + // inner_extensions_sent, on clients that offer ECH, is |extensions.sent| for + // the ClientHelloInner. + uint32_t inner_extensions_sent = 0; + + // error, if |wait| is |ssl_hs_error|, is the error the handshake failed on. + UniquePtr error; + + // key_shares are the current key exchange instances. The second is only used + // as a client if we believe that we should offer two key shares in a + // ClientHello. + UniquePtr key_shares[2]; + + // transcript is the current handshake transcript. + SSLTranscript transcript; + + // inner_transcript, on the client, is the handshake transcript for the + // ClientHelloInner handshake. It is moved to |transcript| if the server + // accepts ECH. + SSLTranscript inner_transcript; + + // inner_client_random is the ClientHello random value used with + // ClientHelloInner. + uint8_t inner_client_random[SSL3_RANDOM_SIZE] = {0}; + + // cookie is the value of the cookie received from the server, if any. + Array cookie; + + // ech_client_outer contains the outer ECH extension to send in the + // ClientHello, excluding the header and type byte. + Array ech_client_outer; + + // ech_retry_configs, on the client, contains the retry configs from the + // server as a serialized ECHConfigList. + Array ech_retry_configs; + + // ech_client_hello_buf, on the server, contains the bytes of the + // reconstructed ClientHelloInner message. + Array ech_client_hello_buf; + + // key_share_bytes is the key_share extension that the client should send. + Array key_share_bytes; + + // ecdh_public_key, for servers, is the key share to be sent to the client in + // TLS 1.3. + Array ecdh_public_key; + + // peer_sigalgs are the signature algorithms that the peer supports. These are + // taken from the contents of the signature algorithms extension for a server + // or from the CertificateRequest for a client. + Array peer_sigalgs; + + // peer_supported_group_list contains the supported group IDs advertised by + // the peer. This is only set on the server's end. The server does not + // advertise this extension to the client. + Array peer_supported_group_list; + + // peer_delegated_credential_sigalgs are the signature algorithms the peer + // supports with delegated credentials. + Array peer_delegated_credential_sigalgs; + + // peer_key is the peer's ECDH key for a TLS 1.2 client. + Array peer_key; + + // extension_permutation is the permutation to apply to ClientHello + // extensions. It maps indices into the |kExtensions| table into other + // indices. + Array extension_permutation; + + // cert_compression_alg_id, for a server, contains the negotiated certificate + // compression algorithm for this client. It is only valid if + // |cert_compression_negotiated| is true. + uint16_t cert_compression_alg_id; + + // ech_hpke_ctx is the HPKE context used in ECH. On the server, it is + // initialized if |ech_status| is |ssl_ech_accepted|. On the client, it is + // initialized if |selected_ech_config| is not nullptr. + ScopedEVP_HPKE_CTX ech_hpke_ctx; + + // server_params, in a TLS 1.2 server, stores the ServerKeyExchange + // parameters. It has client and server randoms prepended for signing + // convenience. + Array server_params; + + // peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the + // server when using a TLS 1.2 PSK key exchange. + UniquePtr peer_psk_identity_hint; + + // ca_names, on the client, contains the list of CAs received in a + // CertificateRequest message. + UniquePtr ca_names; + + // cached_x509_ca_names contains a cache of parsed versions of the elements of + // |ca_names|. This pointer is left non-owning so only + // |ssl_crypto_x509_method| needs to link against crypto/x509. + STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr; + + // certificate_types, on the client, contains the set of certificate types + // received in a CertificateRequest message. + Array certificate_types; + + // local_pubkey is the public key we are authenticating as. + UniquePtr local_pubkey; + + // peer_pubkey is the public key parsed from the peer's leaf certificate. + UniquePtr peer_pubkey; + + // new_session is the new mutable session being established by the current + // handshake. It should not be cached. + UniquePtr new_session; + + // early_session is the session corresponding to the current 0-RTT state on + // the client if |in_early_data| is true. + UniquePtr early_session; + + // ssl_ech_keys, for servers, is the set of ECH keys to use with this + // handshake. This is copied from |SSL_CTX| to ensure consistent behavior as + // |SSL_CTX| rotates keys. + UniquePtr ech_keys; + + // selected_ech_config, for clients, is the ECHConfig the client uses to offer + // ECH, or nullptr if ECH is not being offered. If non-NULL, |ech_hpke_ctx| + // will be initialized. + UniquePtr selected_ech_config; + + // new_cipher is the cipher being negotiated in this handshake. + const SSL_CIPHER *new_cipher = nullptr; + + // key_block is the record-layer key block for TLS 1.2 and earlier. + Array key_block; + + // hints contains the handshake hints for this connection. If + // |hints_requested| is true, this field is non-null and contains the pending + // hints to filled as the predicted handshake progresses. Otherwise, this + // field, if non-null, contains hints configured by the caller and will + // influence the handshake on match. + UniquePtr hints; + + // ech_is_inner, on the server, indicates whether the ClientHello contained an + // inner ECH extension. + bool ech_is_inner : 1; + + // ech_authenticated_reject, on the client, indicates whether an ECH rejection + // handshake has been authenticated. + bool ech_authenticated_reject : 1; + + // scts_requested is true if the SCT extension is in the ClientHello. + bool scts_requested : 1; + + // handshake_finalized is true once the handshake has completed, at which + // point accessors should use the established state. + bool handshake_finalized : 1; + + // accept_psk_mode stores whether the client's PSK mode is compatible with our + // preferences. + bool accept_psk_mode : 1; + + // cert_request is true if a client certificate was requested. + bool cert_request : 1; + + // certificate_status_expected is true if OCSP stapling was negotiated and the + // server is expected to send a CertificateStatus message. (This is used on + // both the client and server sides.) + bool certificate_status_expected : 1; + + // ocsp_stapling_requested is true if a client requested OCSP stapling. + bool ocsp_stapling_requested : 1; + + // delegated_credential_requested is true if the peer indicated support for + // the delegated credential extension. + bool delegated_credential_requested : 1; + + // should_ack_sni is used by a server and indicates that the SNI extension + // should be echoed in the ServerHello. + bool should_ack_sni : 1; + + // in_false_start is true if there is a pending client handshake in False + // Start. The client may write data at this point. + bool in_false_start : 1; + + // in_early_data is true if there is a pending handshake that has progressed + // enough to send and receive early data. + bool in_early_data : 1; + + // early_data_offered is true if the client sent the early_data extension. + bool early_data_offered : 1; + + // can_early_read is true if application data may be read at this point in the + // handshake. + bool can_early_read : 1; + + // can_early_write is true if application data may be written at this point in + // the handshake. + bool can_early_write : 1; + + // next_proto_neg_seen is one of NPN was negotiated. + bool next_proto_neg_seen : 1; + + // ticket_expected is true if a TLS 1.2 NewSessionTicket message is to be sent + // or received. + bool ticket_expected : 1; + + // extended_master_secret is true if the extended master secret extension is + // negotiated in this handshake. + bool extended_master_secret : 1; + + // pending_private_key_op is true if there is a pending private key operation + // in progress. + bool pending_private_key_op : 1; + + // handback indicates that a server should pause the handshake after + // finishing operations that require private key material, in such a way that + // |SSL_get_error| returns |SSL_ERROR_HANDBACK|. It is set by + // |SSL_apply_handoff|. + bool handback : 1; + + // hints_requested indicates the caller has requested handshake hints. Only + // the first round-trip of the handshake will complete, after which the + // |hints| structure can be serialized. + bool hints_requested : 1; + + // cert_compression_negotiated is true iff |cert_compression_alg_id| is valid. + bool cert_compression_negotiated : 1; + + // apply_jdk11_workaround is true if the peer is probably a JDK 11 client + // which implemented TLS 1.3 incorrectly. + bool apply_jdk11_workaround : 1; + + // can_release_private_key is true if the private key will no longer be used + // in this handshake. + bool can_release_private_key : 1; + + // channel_id_negotiated is true if Channel ID should be used in this + // handshake. + bool channel_id_negotiated : 1; + + // client_version is the value sent or received in the ClientHello version. + uint16_t client_version = 0; + + // early_data_read is the amount of early data that has been read by the + // record layer. + uint16_t early_data_read = 0; + + // early_data_written is the amount of early data that has been written by the + // record layer. + uint16_t early_data_written = 0; + + // ech_config_id is the ECH config sent by the client. + uint8_t ech_config_id = 0; + + // session_id is the session ID in the ClientHello. + uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; + uint8_t session_id_len = 0; + + // grease_seed is the entropy for GREASE values. + uint8_t grease_seed[ssl_grease_last_index + 1] = {0}; +}; + +UniquePtr ssl_handshake_new(SSL *ssl); + +// ssl_check_message_type checks if |msg| has type |type|. If so it returns +// one. Otherwise, it sends an alert and returns zero. +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type); + +// ssl_run_handshake runs the TLS handshake. It returns one on success and <= 0 +// on error. It sets |out_early_return| to one if we've completed the handshake +// early. +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return); + +// The following are implementations of |do_handshake| for the client and +// server. +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs); + +// The following functions return human-readable representations of the TLS +// handshake states for debugging. +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs); +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs); + +// tls13_add_key_update queues a KeyUpdate message on |ssl|. The +// |update_requested| argument must be one of |SSL_KEY_UPDATE_REQUESTED| or +// |SSL_KEY_UPDATE_NOT_REQUESTED|. +bool tls13_add_key_update(SSL *ssl, int update_requested); + +// tls13_post_handshake processes a post-handshake message. It returns true on +// success and false on failure. +bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg); + +bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + bool allow_anonymous); +bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls13_process_finished processes |msg| as a Finished message from the +// peer. If |use_saved_value| is true, the verify_data is compared against +// |hs->expected_client_finished| rather than computed fresh. +bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + bool use_saved_value); + +bool tls13_add_certificate(SSL_HANDSHAKE *hs); + +// tls13_add_certificate_verify adds a TLS 1.3 CertificateVerify message to the +// handshake. If it returns |ssl_private_key_retry|, it should be called again +// to retry when the signing operation is completed. +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs); + +bool tls13_add_finished(SSL_HANDSHAKE *hs); +bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg); +bssl::UniquePtr tls13_create_session_with_ticket(SSL *ssl, + CBS *body); + +// ssl_setup_extension_permutation computes a ClientHello extension permutation +// for |hs|, if applicable. It returns true on success and false on error. +bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs); + +// ssl_setup_key_shares computes client key shares and saves them in |hs|. It +// returns true on success and false on failure. If |override_group_id| is zero, +// it offers the default groups, including GREASE. If it is non-zero, it offers +// a single key share of the specified group. +bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id); + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents); +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Span *out_peer_key, + uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello); +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents); +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello, CBS *contents); +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +// ssl_is_sct_list_valid does a shallow parse of the SCT list in |contents| and +// returns whether it's valid. +bool ssl_is_sct_list_valid(const CBS *contents); + +// ssl_write_client_hello_without_extensions writes a ClientHello to |out|, +// up to the extensions field. |type| determines the type of ClientHello to +// write. If |omit_session_id| is true, the session ID is empty. +bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, + CBB *cbb, + ssl_client_hello_type_t type, + bool empty_session_id); + +// ssl_add_client_hello constructs a ClientHello and adds it to the outgoing +// flight. It returns true on success and false on error. +bool ssl_add_client_hello(SSL_HANDSHAKE *hs); + +struct ParsedServerHello { + CBS raw; + uint16_t legacy_version = 0; + CBS random; + CBS session_id; + uint16_t cipher_suite = 0; + uint8_t compression_method = 0; + CBS extensions; +}; + +// ssl_parse_server_hello parses |msg| as a ServerHello. On success, it writes +// the result to |*out| and returns true. Otherwise, it returns false and sets +// |*out_alert| to an alert to send to the peer. +bool ssl_parse_server_hello(ParsedServerHello *out, uint8_t *out_alert, + const SSLMessage &msg); + +enum ssl_cert_verify_context_t { + ssl_cert_verify_server, + ssl_cert_verify_client, + ssl_cert_verify_channel_id, +}; + +// tls13_get_cert_verify_signature_input generates the message to be signed for +// TLS 1.3's CertificateVerify message. |cert_verify_context| determines the +// type of signature. It sets |*out| to a newly allocated buffer containing the +// result. This function returns true on success and false on failure. +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context); + +// ssl_is_valid_alpn_list returns whether |in| is a valid ALPN protocol list. +bool ssl_is_valid_alpn_list(Span in); + +// ssl_is_alpn_protocol_allowed returns whether |protocol| is a valid server +// selection for |hs->ssl|'s client preferences. +bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs, + Span protocol); + +// ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns +// true on successful negotiation or if nothing was negotiated. It returns false +// and sets |*out_alert| to an alert on error. +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello); + +// ssl_get_local_application_settings looks up the configured ALPS value for +// |protocol|. If found, it sets |*out_settings| to the value and returns true. +// Otherwise, it returns false. +bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs, + Span *out_settings, + Span protocol); + +// ssl_negotiate_alps negotiates the ALPS extension, if applicable. It returns +// true on successful negotiation or if nothing was negotiated. It returns false +// and sets |*out_alert| to an alert on error. +bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello); + +struct SSLExtension { + SSLExtension(uint16_t type_arg, bool allowed_arg = true) + : type(type_arg), allowed(allowed_arg), present(false) { + CBS_init(&data, nullptr, 0); + } + + uint16_t type; + bool allowed; + bool present; + CBS data; +}; + +// ssl_parse_extensions parses a TLS extensions block out of |cbs| and advances +// it. It writes the parsed extensions to pointers in |extensions|. On success, +// it fills in the |present| and |data| fields and returns true. Otherwise, it +// sets |*out_alert| to an alert to send and returns false. Unknown extensions +// are rejected unless |ignore_unknown| is true. +bool ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + std::initializer_list extensions, + bool ignore_unknown); + +// ssl_verify_peer_cert verifies the peer certificate for |hs|. +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs); +// ssl_reverify_peer_cert verifies the peer certificate for |hs| when resuming a +// session. +enum ssl_verify_result_t ssl_reverify_peer_cert(SSL_HANDSHAKE *hs, + bool send_alert); + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs); +bool ssl_send_finished(SSL_HANDSHAKE *hs); +bool ssl_output_cert_chain(SSL_HANDSHAKE *hs); + +// ssl_handshake_session returns the |SSL_SESSION| corresponding to the current +// handshake. Note, in TLS 1.2 resumptions, this session is immutable. +const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs); + +// ssl_done_writing_client_hello is called after the last ClientHello is written +// by |hs|. It releases some memory that is no longer needed. +void ssl_done_writing_client_hello(SSL_HANDSHAKE *hs); + + +// SSLKEYLOGFILE functions. + +// ssl_log_secret logs |secret| with label |label|, if logging is enabled for +// |ssl|. It returns true on success and false on failure. +bool ssl_log_secret(const SSL *ssl, const char *label, + Span secret); + + +// ClientHello functions. + +// ssl_client_hello_init parses |body| as a ClientHello message, excluding the +// message header, and writes the result to |*out|. It returns true on success +// and false on error. This function is exported for testing. +OPENSSL_EXPORT bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, + Span body); + +bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, + SSL_CLIENT_HELLO *out); + +bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type); + +bool ssl_client_cipher_list_contains_cipher( + const SSL_CLIENT_HELLO *client_hello, uint16_t id); + + +// GREASE. + +// ssl_get_grease_value returns a GREASE value for |hs|. For a given +// connection, the values for each index will be deterministic. This allows the +// same ClientHello be sent twice for a HelloRetryRequest or the same group be +// advertised in both supported_groups and key_shares. +uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs, + enum ssl_grease_index_t index); + + +// Signature algorithms. + +// tls1_parse_peer_sigalgs parses |sigalgs| as the list of peer signature +// algorithms and saves them on |hs|. It returns true on success and false on +// error. +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *sigalgs); + +// tls1_get_legacy_signature_algorithm sets |*out| to the signature algorithm +// that should be used with |pkey| in TLS 1.1 and earlier. It returns true on +// success and false if |pkey| may not be used at those versions. +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey); + +// tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use +// with |hs|'s private key based on the peer's preferences and the algorithms +// supported. It returns true on success and false on error. +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out); + +// tls1_get_peer_verify_algorithms returns the signature schemes for which the +// peer indicated support. +// +// NOTE: The related function |SSL_get0_peer_verify_algorithms| only has +// well-defined behavior during the callbacks set by |SSL_CTX_set_cert_cb| and +// |SSL_CTX_set_client_cert_cb|, or when the handshake is paused because of +// them. +Span tls1_get_peer_verify_algorithms(const SSL_HANDSHAKE *hs); + +// tls12_add_verify_sigalgs adds the signature algorithms acceptable for the +// peer signature to |out|. It returns true on success and false on error. +bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out); + +// tls12_check_peer_sigalg checks if |sigalg| is acceptable for the peer +// signature. It returns true on success and false on error, setting +// |*out_alert| to an alert to send. +bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t sigalg); + + +// Underdocumented functions. +// +// Functions below here haven't been touched up and may be underdocumented. + +#define TLSEXT_CHANNEL_ID_SIZE 128 + +// From RFC 4492, used in encoding the curve type in ECParameters +#define NAMED_CURVE_TYPE 3 + +struct CERT { + static constexpr bool kAllowUniquePtr = true; + + explicit CERT(const SSL_X509_METHOD *x509_method); + ~CERT(); + + UniquePtr privatekey; + + // chain contains the certificate chain, with the leaf at the beginning. The + // first element of |chain| may be NULL to indicate that the leaf certificate + // has not yet been set. + // If |chain| != NULL -> len(chain) >= 1 + // If |chain[0]| == NULL -> len(chain) >= 2. + // |chain[1..]| != NULL + UniquePtr chain; + + // x509_chain may contain a parsed copy of |chain[1..]|. This is only used as + // a cache in order to implement “get0” functions that return a non-owning + // pointer to the certificate chain. + STACK_OF(X509) *x509_chain = nullptr; + + // x509_leaf may contain a parsed copy of the first element of |chain|. This + // is only used as a cache in order to implement “get0” functions that return + // a non-owning pointer to the certificate chain. + X509 *x509_leaf = nullptr; + + // x509_stash contains the last |X509| object append to the chain. This is a + // workaround for some third-party code that continue to use an |X509| object + // even after passing ownership with an “add0” function. + X509 *x509_stash = nullptr; + + // key_method, if non-NULL, is a set of callbacks to call for private key + // operations. + const SSL_PRIVATE_KEY_METHOD *key_method = nullptr; + + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const SSL_X509_METHOD *x509_method = nullptr; + + // sigalgs, if non-empty, is the set of signature algorithms supported by + // |privatekey| in decreasing order of preference. + Array sigalgs; + + // Certificate setup callback: if set is called whenever a + // certificate may be required (client or server). the callback + // can then examine any appropriate parameters and setup any + // certificates required. This allows advanced applications + // to select certificates on the fly: for example based on + // supported signature algorithms or curves. + int (*cert_cb)(SSL *ssl, void *arg) = nullptr; + void *cert_cb_arg = nullptr; + + // Optional X509_STORE for certificate validation. If NULL the parent SSL_CTX + // store is used instead. + X509_STORE *verify_store = nullptr; + + // Signed certificate timestamp list to be sent to the client, if requested + UniquePtr signed_cert_timestamp_list; + + // OCSP response to be sent to the client, if requested. + UniquePtr ocsp_response; + + // sid_ctx partitions the session space within a shared session cache or + // ticket key. Only sessions with a matching value will be accepted. + uint8_t sid_ctx_length = 0; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH] = {0}; + + // Delegated credentials. + + // dc is the delegated credential to send to the peer (if requested). + UniquePtr dc = nullptr; + + // dc_privatekey is used instead of |privatekey| or |key_method| to + // authenticate the host if a delegated credential is used in the handshake. + UniquePtr dc_privatekey = nullptr; + + // dc_key_method, if not NULL, is used instead of |dc_privatekey| to + // authenticate the host. + const SSL_PRIVATE_KEY_METHOD *dc_key_method = nullptr; +}; + +// |SSL_PROTOCOL_METHOD| abstracts between TLS and DTLS. +struct SSL_PROTOCOL_METHOD { + bool is_dtls; + bool (*ssl_new)(SSL *ssl); + void (*ssl_free)(SSL *ssl); + // get_message sets |*out| to the current handshake message and returns true + // if one has been received. It returns false if more input is needed. + bool (*get_message)(const SSL *ssl, SSLMessage *out); + // next_message is called to release the current handshake message. + void (*next_message)(SSL *ssl); + // has_unprocessed_handshake_data returns whether there is buffered + // handshake data that has not been consumed by |get_message|. + bool (*has_unprocessed_handshake_data)(const SSL *ssl); + // Use the |ssl_open_handshake| wrapper. + ssl_open_record_t (*open_handshake)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + // Use the |ssl_open_change_cipher_spec| wrapper. + ssl_open_record_t (*open_change_cipher_spec)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + // Use the |ssl_open_app_data| wrapper. + ssl_open_record_t (*open_app_data)(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + int (*dispatch_alert)(SSL *ssl); + // init_message begins a new handshake message of type |type|. |cbb| is the + // root CBB to be passed into |finish_message|. |*body| is set to a child CBB + // the caller should write to. It returns true on success and false on error. + bool (*init_message)(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type); + // finish_message finishes a handshake message. It sets |*out_msg| to the + // serialized message. It returns true on success and false on error. + bool (*finish_message)(const SSL *ssl, CBB *cbb, + bssl::Array *out_msg); + // add_message adds a handshake message to the pending flight. It returns + // true on success and false on error. + bool (*add_message)(SSL *ssl, bssl::Array msg); + // add_change_cipher_spec adds a ChangeCipherSpec record to the pending + // flight. It returns true on success and false on error. + bool (*add_change_cipher_spec)(SSL *ssl); + // flush_flight flushes the pending flight to the transport. It returns one on + // success and <= 0 on error. + int (*flush_flight)(SSL *ssl); + // on_handshake_complete is called when the handshake is complete. + void (*on_handshake_complete)(SSL *ssl); + // set_read_state sets |ssl|'s read cipher state and level to |aead_ctx| and + // |level|. In QUIC, |aead_ctx| is a placeholder object and |secret_for_quic| + // is the original secret. This function returns true on success and false on + // error. + bool (*set_read_state)(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic); + // set_write_state sets |ssl|'s write cipher state and level to |aead_ctx| and + // |level|. In QUIC, |aead_ctx| is a placeholder object and |secret_for_quic| + // is the original secret. This function returns true on success and false on + // error. + bool (*set_write_state)(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic); +}; + +// The following wrappers call |open_*| but handle |read_shutdown| correctly. + +// ssl_open_handshake processes a record from |in| for reading a handshake +// message. +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_open_change_cipher_spec processes a record from |in| for reading a +// ChangeCipherSpec. +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +// ssl_open_app_data processes a record from |in| for reading application data. +// On success, it returns |ssl_open_record_success| and sets |*out| to the +// input. If it encounters a post-handshake message, it returns +// |ssl_open_record_discard|. The caller should then retry, after processing any +// messages received with |get_message|. +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + +struct SSL_X509_METHOD { + // check_client_CA_list returns one if |names| is a good list of X.509 + // distinguished names and zero otherwise. This is used to ensure that we can + // reject unparsable values at handshake time when using crypto/x509. + bool (*check_client_CA_list)(STACK_OF(CRYPTO_BUFFER) *names); + + // cert_clear frees and NULLs all X509 certificate-related state. + void (*cert_clear)(CERT *cert); + // cert_free frees all X509-related state. + void (*cert_free)(CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based certificate chain + // from |cert|. + // cert_dup duplicates any needed fields from |cert| to |new_cert|. + void (*cert_dup)(CERT *new_cert, const CERT *cert); + void (*cert_flush_cached_chain)(CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based leaf certificate + // from |cert|. + void (*cert_flush_cached_leaf)(CERT *cert); + + // session_cache_objects fills out |sess->x509_peer| and |sess->x509_chain| + // from |sess->certs| and erases |sess->x509_chain_without_leaf|. It returns + // true on success or false on error. + bool (*session_cache_objects)(SSL_SESSION *session); + // session_dup duplicates any needed fields from |session| to |new_session|. + // It returns true on success or false on error. + bool (*session_dup)(SSL_SESSION *new_session, const SSL_SESSION *session); + // session_clear frees any X509-related state from |session|. + void (*session_clear)(SSL_SESSION *session); + // session_verify_cert_chain verifies the certificate chain in |session|, + // sets |session->verify_result| and returns true on success or false on + // error. + bool (*session_verify_cert_chain)(SSL_SESSION *session, SSL_HANDSHAKE *ssl, + uint8_t *out_alert); + + // hs_flush_cached_ca_names drops any cached |X509_NAME|s from |hs|. + void (*hs_flush_cached_ca_names)(SSL_HANDSHAKE *hs); + // ssl_new does any necessary initialisation of |hs|. It returns true on + // success or false on error. + bool (*ssl_new)(SSL_HANDSHAKE *hs); + // ssl_free frees anything created by |ssl_new|. + void (*ssl_config_free)(SSL_CONFIG *cfg); + // ssl_flush_cached_client_CA drops any cached |X509_NAME|s from |ssl|. + void (*ssl_flush_cached_client_CA)(SSL_CONFIG *cfg); + // ssl_auto_chain_if_needed runs the deprecated auto-chaining logic if + // necessary. On success, it updates |ssl|'s certificate configuration as + // needed and returns true. Otherwise, it returns false. + bool (*ssl_auto_chain_if_needed)(SSL_HANDSHAKE *hs); + // ssl_ctx_new does any necessary initialisation of |ctx|. It returns true on + // success or false on error. + bool (*ssl_ctx_new)(SSL_CTX *ctx); + // ssl_ctx_free frees anything created by |ssl_ctx_new|. + void (*ssl_ctx_free)(SSL_CTX *ctx); + // ssl_ctx_flush_cached_client_CA drops any cached |X509_NAME|s from |ctx|. + void (*ssl_ctx_flush_cached_client_CA)(SSL_CTX *ssl); +}; + +// ssl_crypto_x509_method provides the |SSL_X509_METHOD| functions using +// crypto/x509. +extern const SSL_X509_METHOD ssl_crypto_x509_method; + +// ssl_noop_x509_method provides the |SSL_X509_METHOD| functions that avoid +// crypto/x509. +extern const SSL_X509_METHOD ssl_noop_x509_method; + +struct TicketKey { + static constexpr bool kAllowUniquePtr = true; + + uint8_t name[SSL_TICKET_KEY_NAME_LEN] = {0}; + uint8_t hmac_key[16] = {0}; + uint8_t aes_key[16] = {0}; + // next_rotation_tv_sec is the time (in seconds from the epoch) when the + // current key should be superseded by a new key, or the time when a previous + // key should be dropped. If zero, then the key should not be automatically + // rotated. + uint64_t next_rotation_tv_sec = 0; +}; + +struct CertCompressionAlg { + static constexpr bool kAllowUniquePtr = true; + + ssl_cert_compression_func_t compress = nullptr; + ssl_cert_decompression_func_t decompress = nullptr; + uint16_t alg_id = 0; +}; + +BSSL_NAMESPACE_END + +DEFINE_LHASH_OF(SSL_SESSION) + +BSSL_NAMESPACE_BEGIN + +// An ssl_shutdown_t describes the shutdown state of one end of the connection, +// whether it is alive or has been shutdown via close_notify or fatal alert. +enum ssl_shutdown_t { + ssl_shutdown_none = 0, + ssl_shutdown_close_notify = 1, + ssl_shutdown_error = 2, +}; + +enum ssl_ech_status_t { + // ssl_ech_none indicates ECH was not offered, or we have not gotten far + // enough in the handshake to determine the status. + ssl_ech_none, + // ssl_ech_accepted indicates the server accepted ECH. + ssl_ech_accepted, + // ssl_ech_rejected indicates the server was offered ECH but rejected it. + ssl_ech_rejected, +}; + +struct SSL3_STATE { + static constexpr bool kAllowUniquePtr = true; + + SSL3_STATE(); + ~SSL3_STATE(); + + uint8_t read_sequence[8] = {0}; + uint8_t write_sequence[8] = {0}; + + uint8_t server_random[SSL3_RANDOM_SIZE] = {0}; + uint8_t client_random[SSL3_RANDOM_SIZE] = {0}; + + // read_buffer holds data from the transport to be processed. + SSLBuffer read_buffer; + // write_buffer holds data to be written to the transport. + SSLBuffer write_buffer; + + // pending_app_data is the unconsumed application data. It points into + // |read_buffer|. + Span pending_app_data; + + // partial write - check the numbers match + unsigned int wnum = 0; // number of bytes sent so far + int wpend_tot = 0; // number bytes written + int wpend_type = 0; + int wpend_ret = 0; // number of bytes submitted + const uint8_t *wpend_buf = nullptr; + + // read_shutdown is the shutdown state for the read half of the connection. + enum ssl_shutdown_t read_shutdown = ssl_shutdown_none; + + // write_shutdown is the shutdown state for the write half of the connection. + enum ssl_shutdown_t write_shutdown = ssl_shutdown_none; + + // read_error, if |read_shutdown| is |ssl_shutdown_error|, is the error for + // the receive half of the connection. + UniquePtr read_error; + + int total_renegotiations = 0; + + // This holds a variable that indicates what we were doing when a 0 or -1 is + // returned. This is needed for non-blocking IO so we know what request + // needs re-doing when in SSL_accept or SSL_connect + int rwstate = SSL_ERROR_NONE; + + enum ssl_encryption_level_t read_level = ssl_encryption_initial; + enum ssl_encryption_level_t write_level = ssl_encryption_initial; + + // early_data_skipped is the amount of early data that has been skipped by the + // record layer. + uint16_t early_data_skipped = 0; + + // empty_record_count is the number of consecutive empty records received. + uint8_t empty_record_count = 0; + + // warning_alert_count is the number of consecutive warning alerts + // received. + uint8_t warning_alert_count = 0; + + // key_update_count is the number of consecutive KeyUpdates received. + uint8_t key_update_count = 0; + + // ech_status indicates whether ECH was accepted by the server. + ssl_ech_status_t ech_status = ssl_ech_none; + + // skip_early_data instructs the record layer to skip unexpected early data + // messages when 0RTT is rejected. + bool skip_early_data : 1; + + // have_version is true if the connection's final version is known. Otherwise + // the version has not been negotiated yet. + bool have_version : 1; + + // v2_hello_done is true if the peer's V2ClientHello, if any, has been handled + // and future messages should use the record layer. + bool v2_hello_done : 1; + + // is_v2_hello is true if the current handshake message was derived from a + // V2ClientHello rather than received from the peer directly. + bool is_v2_hello : 1; + + // has_message is true if the current handshake message has been returned + // at least once by |get_message| and false otherwise. + bool has_message : 1; + + // initial_handshake_complete is true if the initial handshake has + // completed. + bool initial_handshake_complete : 1; + + // session_reused indicates whether a session was resumed. + bool session_reused : 1; + + // delegated_credential_used is whether we presented a delegated credential to + // the peer. + bool delegated_credential_used : 1; + + bool send_connection_binding : 1; + + // channel_id_valid is true if, on the server, the client has negotiated a + // Channel ID and the |channel_id| field is filled in. + bool channel_id_valid : 1; + + // key_update_pending is true if we have a KeyUpdate acknowledgment + // outstanding. + bool key_update_pending : 1; + + // wpend_pending is true if we have a pending write outstanding. + bool wpend_pending : 1; + + // early_data_accepted is true if early data was accepted by the server. + bool early_data_accepted : 1; + + // alert_dispatch is true there is an alert in |send_alert| to be sent. + bool alert_dispatch : 1; + + // renegotiate_pending is whether the read half of the channel is blocked on a + // HelloRequest. + bool renegotiate_pending : 1; + + // used_hello_retry_request is whether the handshake used a TLS 1.3 + // HelloRetryRequest message. + bool used_hello_retry_request : 1; + + // hs_buf is the buffer of handshake data to process. + UniquePtr hs_buf; + + // pending_hs_data contains the pending handshake data that has not yet + // been encrypted to |pending_flight|. This allows packing the handshake into + // fewer records. + UniquePtr pending_hs_data; + + // pending_flight is the pending outgoing flight. This is used to flush each + // handshake flight in a single write. |write_buffer| must be written out + // before this data. + UniquePtr pending_flight; + + // pending_flight_offset is the number of bytes of |pending_flight| which have + // been successfully written. + uint32_t pending_flight_offset = 0; + + // ticket_age_skew is the difference, in seconds, between the client-sent + // ticket age and the server-computed value in TLS 1.3 server connections + // which resumed a session. + int32_t ticket_age_skew = 0; + + // ssl_early_data_reason stores details on why 0-RTT was accepted or rejected. + enum ssl_early_data_reason_t early_data_reason = ssl_early_data_unknown; + + // aead_read_ctx is the current read cipher state. + UniquePtr aead_read_ctx; + + // aead_write_ctx is the current write cipher state. + UniquePtr aead_write_ctx; + + // hs is the handshake state for the current handshake or NULL if there isn't + // one. + UniquePtr hs; + + uint8_t write_traffic_secret[SSL_MAX_MD_SIZE] = {0}; + uint8_t read_traffic_secret[SSL_MAX_MD_SIZE] = {0}; + uint8_t exporter_secret[SSL_MAX_MD_SIZE] = {0}; + uint8_t write_traffic_secret_len = 0; + uint8_t read_traffic_secret_len = 0; + uint8_t exporter_secret_len = 0; + + // Connection binding to prevent renegotiation attacks + uint8_t previous_client_finished[12] = {0}; + uint8_t previous_client_finished_len = 0; + uint8_t previous_server_finished_len = 0; + uint8_t previous_server_finished[12] = {0}; + + uint8_t send_alert[2] = {0}; + + // established_session is the session established by the connection. This + // session is only filled upon the completion of the handshake and is + // immutable. + UniquePtr established_session; + + // Next protocol negotiation. For the client, this is the protocol that we + // sent in NextProtocol and is set when handling ServerHello extensions. + // + // For a server, this is the client's selected_protocol from NextProtocol and + // is set when handling the NextProtocol message, before the Finished + // message. + Array next_proto_negotiated; + + // ALPN information + // (we are in the process of transitioning from NPN to ALPN.) + + // In a server these point to the selected ALPN protocol after the + // ClientHello has been processed. In a client these contain the protocol + // that the server selected once the ServerHello has been processed. + Array alpn_selected; + + // hostname, on the server, is the value of the SNI extension. + UniquePtr hostname; + + // For a server: + // If |channel_id_valid| is true, then this contains the + // verified Channel ID from the client: a P256 point, (x,y), where + // each are big-endian values. + uint8_t channel_id[64] = {0}; + + // Contains the QUIC transport params received by the peer. + Array peer_quic_transport_params; + + // srtp_profile is the selected SRTP protection profile for + // DTLS-SRTP. + const SRTP_PROTECTION_PROFILE *srtp_profile = nullptr; +}; + +// lengths of messages +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#define DTLS1_AL_HEADER_LENGTH 2 + +struct hm_header_st { + uint8_t type; + uint32_t msg_len; + uint16_t seq; + uint32_t frag_off; + uint32_t frag_len; +}; + +// An hm_fragment is an incoming DTLS message, possibly not yet assembled. +struct hm_fragment { + static constexpr bool kAllowUniquePtr = true; + + hm_fragment() {} + hm_fragment(const hm_fragment &) = delete; + hm_fragment &operator=(const hm_fragment &) = delete; + + ~hm_fragment(); + + // type is the type of the message. + uint8_t type = 0; + // seq is the sequence number of this message. + uint16_t seq = 0; + // msg_len is the length of the message body. + uint32_t msg_len = 0; + // data is a pointer to the message, including message header. It has length + // |DTLS1_HM_HEADER_LENGTH| + |msg_len|. + uint8_t *data = nullptr; + // reassembly is a bitmask of |msg_len| bits corresponding to which parts of + // the message have been received. It is NULL if the message is complete. + uint8_t *reassembly = nullptr; +}; + +struct OPENSSL_timeval { + uint64_t tv_sec; + uint32_t tv_usec; +}; + +struct DTLS1_STATE { + static constexpr bool kAllowUniquePtr = true; + + DTLS1_STATE(); + ~DTLS1_STATE(); + + // has_change_cipher_spec is true if we have received a ChangeCipherSpec from + // the peer in this epoch. + bool has_change_cipher_spec : 1; + + // outgoing_messages_complete is true if |outgoing_messages| has been + // completed by an attempt to flush it. Future calls to |add_message| and + // |add_change_cipher_spec| will start a new flight. + bool outgoing_messages_complete : 1; + + // flight_has_reply is true if the current outgoing flight is complete and has + // processed at least one message. This is used to detect whether we or the + // peer sent the final flight. + bool flight_has_reply : 1; + + uint8_t cookie[DTLS1_COOKIE_LENGTH] = {0}; + size_t cookie_len = 0; + + // The current data and handshake epoch. This is initially undefined, and + // starts at zero once the initial handshake is completed. + uint16_t r_epoch = 0; + uint16_t w_epoch = 0; + + // records being received in the current epoch + DTLS1_BITMAP bitmap; + + uint16_t handshake_write_seq = 0; + uint16_t handshake_read_seq = 0; + + // save last sequence number for retransmissions + uint8_t last_write_sequence[8] = {0}; + UniquePtr last_aead_write_ctx; + + // incoming_messages is a ring buffer of incoming handshake messages that have + // yet to be processed. The front of the ring buffer is message number + // |handshake_read_seq|, at position |handshake_read_seq| % + // |SSL_MAX_HANDSHAKE_FLIGHT|. + UniquePtr incoming_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + + // outgoing_messages is the queue of outgoing messages from the last handshake + // flight. + DTLS_OUTGOING_MESSAGE outgoing_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + uint8_t outgoing_messages_len = 0; + + // outgoing_written is the number of outgoing messages that have been + // written. + uint8_t outgoing_written = 0; + // outgoing_offset is the number of bytes of the next outgoing message have + // been written. + uint32_t outgoing_offset = 0; + + unsigned mtu = 0; // max DTLS packet size + + // num_timeouts is the number of times the retransmit timer has fired since + // the last time it was reset. + unsigned num_timeouts = 0; + + // Indicates when the last handshake msg or heartbeat sent will + // timeout. + struct OPENSSL_timeval next_timeout = {0, 0}; + + // timeout_duration_ms is the timeout duration in milliseconds. + unsigned timeout_duration_ms = 0; +}; + +// An ALPSConfig is a pair of ALPN protocol and settings value to use with ALPS. +struct ALPSConfig { + Array protocol; + Array settings; +}; + +// SSL_CONFIG contains configuration bits that can be shed after the handshake +// completes. Objects of this type are not shared; they are unique to a +// particular |SSL|. +// +// See SSL_shed_handshake_config() for more about the conditions under which +// configuration can be shed. +struct SSL_CONFIG { + static constexpr bool kAllowUniquePtr = true; + + explicit SSL_CONFIG(SSL *ssl_arg); + ~SSL_CONFIG(); + + // ssl is a non-owning pointer to the parent |SSL| object. + SSL *const ssl = nullptr; + + // conf_max_version is the maximum acceptable version configured by + // |SSL_set_max_proto_version|. Note this version is not normalized in DTLS + // and is further constrained by |SSL_OP_NO_*|. + uint16_t conf_max_version = 0; + + // conf_min_version is the minimum acceptable version configured by + // |SSL_set_min_proto_version|. Note this version is not normalized in DTLS + // and is further constrained by |SSL_OP_NO_*|. + uint16_t conf_min_version = 0; + + X509_VERIFY_PARAM *param = nullptr; + + // crypto + UniquePtr cipher_list; + + // This is used to hold the local certificate used (i.e. the server + // certificate for a server or the client certificate for a client). + UniquePtr cert; + + int (*verify_callback)(int ok, + X509_STORE_CTX *ctx) = + nullptr; // fail if callback returns 0 + + enum ssl_verify_result_t (*custom_verify_callback)( + SSL *ssl, uint8_t *out_alert) = nullptr; + // Server-only: psk_identity_hint is the identity hint to send in + // PSK-based key exchanges. + UniquePtr psk_identity_hint; + + unsigned (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len) = nullptr; + unsigned (*psk_server_callback)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len) = nullptr; + + // for server side, keep the list of CA_dn we can use + UniquePtr client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA = nullptr; + + Array supported_group_list; // our list + + // channel_id_private is the client's Channel ID private key, or null if + // Channel ID should not be offered on this connection. + UniquePtr channel_id_private; + + // For a client, this contains the list of supported protocols in wire + // format. + Array alpn_client_proto_list; + + // alps_configs contains the list of supported protocols to use with ALPS, + // along with their corresponding ALPS values. + GrowableArray alps_configs; + + // Contains the QUIC transport params that this endpoint will send. + Array quic_transport_params; + + // Contains the context used to decide whether to accept early data in QUIC. + Array quic_early_data_context; + + // verify_sigalgs, if not empty, is the set of signature algorithms + // accepted from the peer in decreasing order of preference. + Array verify_sigalgs; + + // srtp_profiles is the list of configured SRTP protection profiles for + // DTLS-SRTP. + UniquePtr srtp_profiles; + + // client_ech_config_list, if not empty, is a serialized ECHConfigList + // structure for the client to use when negotiating ECH. + Array client_ech_config_list; + + // verify_mode is a bitmask of |SSL_VERIFY_*| values. + uint8_t verify_mode = SSL_VERIFY_NONE; + + // ech_grease_enabled controls whether ECH GREASE may be sent in the + // ClientHello. + bool ech_grease_enabled : 1; + + // Enable signed certificate time stamps. Currently client only. + bool signed_cert_timestamps_enabled : 1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled : 1; + + // channel_id_enabled is copied from the |SSL_CTX|. For a server, it means + // that we'll accept Channel IDs from clients. It is ignored on the client. + bool channel_id_enabled : 1; + + // If enforce_rsa_key_usage is true, the handshake will fail if the + // keyUsage extension is present and incompatible with the TLS usage. + // This field is not read until after certificate verification. + bool enforce_rsa_key_usage : 1; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs : 1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_ERROR_HANDOFF|. This is copied in |SSL_new| from the |SSL_CTX| + // element of the same name and may be cleared if the handoff is declined. + bool handoff : 1; + + // shed_handshake_config indicates that the handshake config (this object!) + // should be freed after the handshake completes. + bool shed_handshake_config : 1; + + // jdk11_workaround is whether to disable TLS 1.3 for JDK 11 clients, as a + // workaround for https://bugs.openjdk.java.net/browse/JDK-8211806. + bool jdk11_workaround : 1; + + // QUIC drafts up to and including 32 used a different TLS extension + // codepoint to convey QUIC's transport parameters. + bool quic_use_legacy_codepoint : 1; + + // permute_extensions is whether to permute extensions when sending messages. + bool permute_extensions : 1; +}; + +// From RFC 8446, used in determining PSK modes. +#define SSL_PSK_DHE_KE 0x1 + +// kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early +// data that will be accepted. This value should be slightly below +// kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext. +static const size_t kMaxEarlyDataAccepted = 14336; + +UniquePtr ssl_cert_dup(CERT *cert); +void ssl_cert_clear_certs(CERT *cert); +bool ssl_set_cert(CERT *cert, UniquePtr buffer); +bool ssl_is_key_type_supported(int key_type); +// ssl_compare_public_and_private_key returns true if |pubkey| is the public +// counterpart to |privkey|. Otherwise it returns false and pushes a helpful +// message on the error queue. +bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey); +bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey); +bool ssl_get_new_session(SSL_HANDSHAKE *hs); +int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session); +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); + +// ssl_session_new returns a newly-allocated blank |SSL_SESSION| or nullptr on +// error. +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method); + +// ssl_hash_session_id returns a hash of |session_id|, suitable for a hash table +// keyed on session IDs. +uint32_t ssl_hash_session_id(Span session_id); + +// SSL_SESSION_parse parses an |SSL_SESSION| from |cbs| and advances |cbs| over +// the parsed data. +OPENSSL_EXPORT UniquePtr SSL_SESSION_parse( + CBS *cbs, const SSL_X509_METHOD *x509_method, CRYPTO_BUFFER_POOL *pool); + +// ssl_session_serialize writes |in| to |cbb| as if it were serialising a +// session for Session-ID resumption. It returns one on success and zero on +// error. +OPENSSL_EXPORT int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); + +// ssl_session_is_context_valid returns one if |session|'s session ID context +// matches the one set on |hs| and zero otherwise. +int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); + +// ssl_session_is_time_valid returns one if |session| is still valid and zero if +// it has expired. +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); + +// ssl_session_is_resumable returns one if |session| is resumable for |hs| and +// zero otherwise. +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); + +// ssl_session_protocol_version returns the protocol version associated with +// |session|. Note that despite the name, this is not the same as +// |SSL_SESSION_get_protocol_version|. The latter is based on upstream's name. +uint16_t ssl_session_protocol_version(const SSL_SESSION *session); + +// ssl_session_get_digest returns the digest used in |session|. +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session); + +void ssl_set_session(SSL *ssl, SSL_SESSION *session); + +// ssl_get_prev_session looks up the previous session based on |client_hello|. +// On success, it sets |*out_session| to the session or nullptr if none was +// found. If the session could not be looked up synchronously, it returns +// |ssl_hs_pending_session| and should be called again. If a ticket could not be +// decrypted immediately it returns |ssl_hs_pending_ticket| and should also +// be called again. Otherwise, it returns |ssl_hs_error|. +enum ssl_hs_wait_t ssl_get_prev_session(SSL_HANDSHAKE *hs, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello); + +// The following flags determine which parts of the session are duplicated. +#define SSL_SESSION_DUP_AUTH_ONLY 0x0 +#define SSL_SESSION_INCLUDE_TICKET 0x1 +#define SSL_SESSION_INCLUDE_NONAUTH 0x2 +#define SSL_SESSION_DUP_ALL \ + (SSL_SESSION_INCLUDE_TICKET | SSL_SESSION_INCLUDE_NONAUTH) + +// SSL_SESSION_dup returns a newly-allocated |SSL_SESSION| with a copy of the +// fields in |session| or nullptr on error. The new session is non-resumable and +// must be explicitly marked resumable once it has been filled in. +OPENSSL_EXPORT UniquePtr SSL_SESSION_dup(SSL_SESSION *session, + int dup_flags); + +// ssl_session_rebase_time updates |session|'s start time to the current time, +// adjusting the timeout so the expiration time is unchanged. +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session); + +// ssl_session_renew_timeout calls |ssl_session_rebase_time| and renews +// |session|'s timeout to |timeout| (measured from the current time). The +// renewal is clamped to the session's auth_timeout. +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout); + +void ssl_update_cache(SSL *ssl); + +void ssl_send_alert(SSL *ssl, int level, int desc); +int ssl_send_alert_impl(SSL *ssl, int level, int desc); +bool tls_get_message(const SSL *ssl, SSLMessage *out); +ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void tls_next_message(SSL *ssl); + +int tls_dispatch_alert(SSL *ssl); +ssl_open_record_t tls_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); +int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + +bool tls_new(SSL *ssl); +void tls_free(SSL *ssl); + +bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool tls_finish_message(const SSL *ssl, CBB *cbb, Array *out_msg); +bool tls_add_message(SSL *ssl, Array msg); +bool tls_add_change_cipher_spec(SSL *ssl); +int tls_flush_flight(SSL *ssl); + +bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array *out_msg); +bool dtls1_add_message(SSL *ssl, Array msg); +bool dtls1_add_change_cipher_spec(SSL *ssl); +int dtls1_flush_flight(SSL *ssl); + +// ssl_add_message_cbb finishes the handshake message in |cbb| and adds it to +// the pending flight. It returns true on success and false on error. +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb); + +// ssl_hash_message incorporates |msg| into the handshake hash. It returns true +// on success and false on allocation failure. +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, + const uint8_t *buf, int len); + +// dtls1_write_record sends a record. It returns one on success and <= 0 on +// error. +int dtls1_write_record(SSL *ssl, int type, const uint8_t *buf, size_t len, + enum dtls1_use_epoch_t use_epoch); + +int dtls1_retransmit_outgoing_messages(SSL *ssl); +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body); +bool dtls1_check_timeout_num(SSL *ssl); + +void dtls1_start_timer(SSL *ssl); +void dtls1_stop_timer(SSL *ssl); +bool dtls1_is_timer_expired(SSL *ssl); +unsigned int dtls1_min_mtu(void); + +bool dtls1_new(SSL *ssl); +void dtls1_free(SSL *ssl); + +bool dtls1_get_message(const SSL *ssl, SSLMessage *out); +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void dtls1_next_message(SSL *ssl); +int dtls1_dispatch_alert(SSL *ssl); + +// tls1_configure_aead configures either the read or write direction AEAD (as +// determined by |direction|) using the keys generated by the TLS KDF. The +// |key_block_cache| argument is used to store the generated key block, if +// empty. Otherwise it's assumed that the key block is already contained within +// it. It returns true on success or false on error. +bool tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_SESSION *session, + Span iv_override); + +bool tls1_change_cipher_state(SSL_HANDSHAKE *hs, + evp_aead_direction_t direction); +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster); + +// tls1_get_grouplist returns the locally-configured group preference list. +Span tls1_get_grouplist(const SSL_HANDSHAKE *ssl); + +// tls1_check_group_id returns whether |group_id| is consistent with locally- +// configured group preferences. +bool tls1_check_group_id(const SSL_HANDSHAKE *ssl, uint16_t group_id); + +// tls1_get_shared_group sets |*out_group_id| to the first preferred shared +// group between client and server preferences and returns true. If none may be +// found, it returns false. +bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id); + +// tls1_set_curves converts the array of NIDs in |curves| into a newly allocated +// array of TLS group IDs. On success, the function returns true and writes the +// array to |*out_group_ids|. Otherwise, it returns false. +bool tls1_set_curves(Array *out_group_ids, Span curves); + +// tls1_set_curves_list converts the string of curves pointed to by |curves| +// into a newly allocated array of TLS group IDs. On success, the function +// returns true and writes the array to |*out_group_ids|. Otherwise, it returns +// false. +bool tls1_set_curves_list(Array *out_group_ids, const char *curves); + +// ssl_add_clienthello_tlsext writes ClientHello extensions to |out| for |type|. +// It returns true on success and false on failure. The |header_len| argument is +// the length of the ClientHello written so far and is used to compute the +// padding length. (It does not include the record header or handshake headers.) +// +// If |type| is |ssl_client_hello_inner|, this function also writes the +// compressed extensions to |out_encoded|. Otherwise, |out_encoded| should be +// nullptr. +// +// On success, the function sets |*out_needs_psk_binder| to whether the last +// ClientHello extension was the pre_shared_key extension and needs a PSK binder +// filled in. The caller should then update |out| and, if applicable, +// |out_encoded| with the binder after completing the whole message. +bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, + bool *out_needs_psk_binder, + ssl_client_hello_type_t type, + size_t header_len); + +bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out); +bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello); +bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *extensions); + +#define tlsext_tick_md EVP_sha256 + +// ssl_process_ticket processes a session ticket from the client. It returns +// one of: +// |ssl_ticket_aead_success|: |*out_session| is set to the parsed session and +// |*out_renew_ticket| is set to whether the ticket should be renewed. +// |ssl_ticket_aead_ignore_ticket|: |*out_renew_ticket| is set to whether a +// fresh ticket should be sent, but the given ticket cannot be used. +// |ssl_ticket_aead_retry|: the ticket could not be immediately decrypted. +// Retry later. +// |ssl_ticket_aead_error|: an error occured that is fatal to the connection. +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL_HANDSHAKE *hs, UniquePtr *out_session, + bool *out_renew_ticket, Span ticket, + Span session_id); + +// tls1_verify_channel_id processes |msg| as a Channel ID message, and verifies +// the signature. If the key is valid, it saves the Channel ID and returns true. +// Otherwise, it returns false. +bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls1_write_channel_id generates a Channel ID message and puts the output in +// |cbb|. |ssl->channel_id_private| must already be set before calling. This +// function returns true on success and false on error. +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb); + +// tls1_channel_id_hash computes the hash to be signed by Channel ID and writes +// it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns +// true on success and false on failure. +bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len); + +// tls1_record_handshake_hashes_for_channel_id records the current handshake +// hashes in |hs->new_session| so that Channel ID resumptions can sign that +// data. +bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs); + +// ssl_can_write returns whether |ssl| is allowed to write. +bool ssl_can_write(const SSL *ssl); + +// ssl_can_read returns wheter |ssl| is allowed to read. +bool ssl_can_read(const SSL *ssl); + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock); +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock); + +// ssl_reset_error_state resets state for |SSL_get_error|. +void ssl_reset_error_state(SSL *ssl); + +// ssl_set_read_error sets |ssl|'s read half into an error state, saving the +// current state of the error queue. +void ssl_set_read_error(SSL *ssl); + +BSSL_NAMESPACE_END + + +// Opaque C types. +// +// The following types are exported to C code as public typedefs, so they must +// be defined outside of the namespace. + +// ssl_method_st backs the public |SSL_METHOD| type. It is a compatibility +// structure to support the legacy version-locked methods. +struct ssl_method_st { + // version, if non-zero, is the only protocol version acceptable to an + // SSL_CTX initialized from this method. + uint16_t version; + // method is the underlying SSL_PROTOCOL_METHOD that initializes the + // SSL_CTX. + const bssl::SSL_PROTOCOL_METHOD *method; + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const bssl::SSL_X509_METHOD *x509_method; +}; + +struct ssl_ctx_st { + explicit ssl_ctx_st(const SSL_METHOD *ssl_method); + ssl_ctx_st(const ssl_ctx_st &) = delete; + ssl_ctx_st &operator=(const ssl_ctx_st &) = delete; + + const bssl::SSL_PROTOCOL_METHOD *method = nullptr; + const bssl::SSL_X509_METHOD *x509_method = nullptr; + + // lock is used to protect various operations on this object. + CRYPTO_MUTEX lock; + + // conf_max_version is the maximum acceptable protocol version configured by + // |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_max_version = 0; + + // conf_min_version is the minimum acceptable protocol version configured by + // |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_min_version = 0; + + // quic_method is the method table corresponding to the QUIC hooks. + const SSL_QUIC_METHOD *quic_method = nullptr; + + bssl::UniquePtr cipher_list; + + X509_STORE *cert_store = nullptr; + LHASH_OF(SSL_SESSION) *sessions = nullptr; + // Most session-ids that will be cached, default is + // SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. + unsigned long session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + SSL_SESSION *session_cache_head = nullptr; + SSL_SESSION *session_cache_tail = nullptr; + + // handshakes_since_cache_flush is the number of successful handshakes since + // the last cache flush. + int handshakes_since_cache_flush = 0; + + // This can have one of 2 values, ored together, + // SSL_SESS_CACHE_CLIENT, + // SSL_SESS_CACHE_SERVER, + // Default is SSL_SESSION_CACHE_SERVER, which means only + // SSL_accept which cache SSL_SESSIONS. + int session_cache_mode = SSL_SESS_CACHE_SERVER; + + // session_timeout is the default lifetime for new sessions in TLS 1.2 and + // earlier, in seconds. + uint32_t session_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + + // session_psk_dhe_timeout is the default lifetime for new sessions in TLS + // 1.3, in seconds. + uint32_t session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT; + + // If this callback is not null, it will be called each time a session id is + // added to the cache. If this function returns 1, it means that the + // callback will do a SSL_SESSION_free() when it has finished using it. + // Otherwise, on 0, it means the callback has finished with it. If + // remove_session_cb is not null, it will be called when a session-id is + // removed from the cache. After the call, OpenSSL will SSL_SESSION_free() + // it. + int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess) = nullptr; + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess) = nullptr; + SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len, + int *copy) = nullptr; + + CRYPTO_refcount_t references = 1; + + // if defined, these override the X509_verify_cert() calls + int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg) = nullptr; + void *app_verify_arg = nullptr; + + ssl_verify_result_t (*custom_verify_callback)(SSL *ssl, + uint8_t *out_alert) = nullptr; + + // Default password callback. + pem_password_cb *default_passwd_callback = nullptr; + + // Default password callback user data. + void *default_passwd_callback_userdata = nullptr; + + // get client cert callback + int (*client_cert_cb)(SSL *ssl, X509 **out_x509, + EVP_PKEY **out_pkey) = nullptr; + + CRYPTO_EX_DATA ex_data; + + // Default values used when no per-SSL value is defined follow + + void (*info_callback)(const SSL *ssl, int type, int value) = nullptr; + + // what we put in client cert requests + bssl::UniquePtr client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA = nullptr; + + + // Default values to use in SSL structures follow (these are copied by + // SSL_new) + + uint32_t options = 0; + // Disable the auto-chaining feature by default. wpa_supplicant relies on this + // feature, but require callers opt into it. + uint32_t mode = SSL_MODE_NO_AUTO_CHAIN; + uint32_t max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + + bssl::UniquePtr cert; + + // callback that allows applications to peek at protocol messages + void (*msg_callback)(int is_write, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg) = nullptr; + void *msg_callback_arg = nullptr; + + int verify_mode = SSL_VERIFY_NONE; + int (*default_verify_callback)(int ok, X509_STORE_CTX *ctx) = + nullptr; // called 'verify_callback' in the SSL + + X509_VERIFY_PARAM *param = nullptr; + + // select_certificate_cb is called before most ClientHello processing and + // before the decision whether to resume a session is made. See + // |ssl_select_cert_result_t| for details of the return values. + ssl_select_cert_result_t (*select_certificate_cb)(const SSL_CLIENT_HELLO *) = + nullptr; + + // dos_protection_cb is called once the resumption decision for a ClientHello + // has been made. It returns one to continue the handshake or zero to + // abort. + int (*dos_protection_cb)(const SSL_CLIENT_HELLO *) = nullptr; + + // Controls whether to verify certificates when resuming connections. They + // were already verified when the connection was first made, so the default is + // false. For now, this is only respected on clients, not servers. + bool reverify_on_resume = false; + + // Maximum amount of data to send in one fragment. actual record size can be + // more than this due to padding and MAC overheads. + uint16_t max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + + // TLS extensions servername callback + int (*servername_callback)(SSL *, int *, void *) = nullptr; + void *servername_arg = nullptr; + + // RFC 4507 session ticket keys. |ticket_key_current| may be NULL before the + // first handshake and |ticket_key_prev| may be NULL at any time. + // Automatically generated ticket keys are rotated as needed at handshake + // time. Hence, all access must be synchronized through |lock|. + bssl::UniquePtr ticket_key_current; + bssl::UniquePtr ticket_key_prev; + + // Callback to support customisation of ticket key setting + int (*ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv, + EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) = nullptr; + + // Server-only: psk_identity_hint is the default identity hint to send in + // PSK-based key exchanges. + bssl::UniquePtr psk_identity_hint; + + unsigned (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len) = nullptr; + unsigned (*psk_server_callback)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len) = nullptr; + + + // Next protocol negotiation information + // (for experimental NPN extension). + + // For a server, this contains a callback function by which the set of + // advertised protocols can be provided. + int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out, + unsigned *out_len, void *arg) = nullptr; + void *next_protos_advertised_cb_arg = nullptr; + // For a client, this contains a callback function that selects the + // next protocol from the list provided by the server. + int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, + void *arg) = nullptr; + void *next_proto_select_cb_arg = nullptr; + + // ALPN information + // (we are in the process of transitioning from NPN to ALPN.) + + // For a server, this contains a callback function that allows the + // server to select the protocol for the connection. + // out: on successful return, this must point to the raw protocol + // name (without the length prefix). + // outlen: on successful return, this contains the length of |*out|. + // in: points to the client's list of supported protocols in + // wire-format. + // inlen: the length of |in|. + int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, + void *arg) = nullptr; + void *alpn_select_cb_arg = nullptr; + + // For a client, this contains the list of supported protocols in wire + // format. + bssl::Array alpn_client_proto_list; + + // SRTP profiles we are willing to do from RFC 5764 + bssl::UniquePtr srtp_profiles; + + // Defined compression algorithms for certificates. + bssl::GrowableArray cert_compression_algs; + + // Supported group values inherited by SSL structure + bssl::Array supported_group_list; + + // channel_id_private is the client's Channel ID private key, or null if + // Channel ID should not be offered on this connection. + bssl::UniquePtr channel_id_private; + + // ech_keys contains the server's list of ECHConfig values and associated + // private keys. This list may be swapped out at any time, so all access must + // be synchronized through |lock|. + bssl::UniquePtr ech_keys; + + // keylog_callback, if not NULL, is the key logging callback. See + // |SSL_CTX_set_keylog_callback|. + void (*keylog_callback)(const SSL *ssl, const char *line) = nullptr; + + // current_time_cb, if not NULL, is the function to use to get the current + // time. It sets |*out_clock| to the current time. The |ssl| argument is + // always NULL. See |SSL_CTX_set_current_time_cb|. + void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock) = nullptr; + + // pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate + // memory. + CRYPTO_BUFFER_POOL *pool = nullptr; + + // ticket_aead_method contains function pointers for opening and sealing + // session tickets. + const SSL_TICKET_AEAD_METHOD *ticket_aead_method = nullptr; + + // legacy_ocsp_callback implements an OCSP-related callback for OpenSSL + // compatibility. + int (*legacy_ocsp_callback)(SSL *ssl, void *arg) = nullptr; + void *legacy_ocsp_callback_arg = nullptr; + + // verify_sigalgs, if not empty, is the set of signature algorithms + // accepted from the peer in decreasing order of preference. + bssl::Array verify_sigalgs; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs : 1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown : 1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled : 1; + + // If true, a client will request certificate timestamps. + bool signed_cert_timestamps_enabled : 1; + + // channel_id_enabled is whether Channel ID is enabled. For a server, means + // that we'll accept Channel IDs from clients. For a client, means that we'll + // advertise support. + bool channel_id_enabled : 1; + + // grease_enabled is whether GREASE (RFC 8701) is enabled. + bool grease_enabled : 1; + + // permute_extensions is whether to permute extensions when sending messages. + bool permute_extensions : 1; + + // allow_unknown_alpn_protos is whether the client allows unsolicited ALPN + // protocols from the peer. + bool allow_unknown_alpn_protos : 1; + + // false_start_allowed_without_alpn is whether False Start (if + // |SSL_MODE_ENABLE_FALSE_START| is enabled) is allowed without ALPN. + bool false_start_allowed_without_alpn : 1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_ERROR_HANDOFF|. + bool handoff : 1; + + // If enable_early_data is true, early data can be sent and accepted. + bool enable_early_data : 1; + + private: + ~ssl_ctx_st(); + friend OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *); +}; + +struct ssl_st { + explicit ssl_st(SSL_CTX *ctx_arg); + ssl_st(const ssl_st &) = delete; + ssl_st &operator=(const ssl_st &) = delete; + ~ssl_st(); + + // method is the method table corresponding to the current protocol (DTLS or + // TLS). + const bssl::SSL_PROTOCOL_METHOD *method = nullptr; + + // config is a container for handshake configuration. Accesses to this field + // should check for nullptr, since configuration may be shed after the + // handshake completes. (If you have the |SSL_HANDSHAKE| object at hand, use + // that instead, and skip the null check.) + bssl::UniquePtr config; + + // version is the protocol version. + uint16_t version = 0; + + uint16_t max_send_fragment = 0; + + // There are 2 BIO's even though they are normally both the same. This is so + // data can be read and written to different handlers + + bssl::UniquePtr rbio; // used by SSL_read + bssl::UniquePtr wbio; // used by SSL_write + + // do_handshake runs the handshake. On completion, it returns |ssl_hs_ok|. + // Otherwise, it returns a value corresponding to what operation is needed to + // progress. + bssl::ssl_hs_wait_t (*do_handshake)(bssl::SSL_HANDSHAKE *hs) = nullptr; + + bssl::SSL3_STATE *s3 = nullptr; // TLS variables + bssl::DTLS1_STATE *d1 = nullptr; // DTLS variables + + // callback that allows applications to peek at protocol messages + void (*msg_callback)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg) = nullptr; + void *msg_callback_arg = nullptr; + + // session info + + // initial_timeout_duration_ms is the default DTLS timeout duration in + // milliseconds. It's used to initialize the timer any time it's restarted. + // + // RFC 6347 states that implementations SHOULD use an initial timer value of 1 + // second. + unsigned initial_timeout_duration_ms = 1000; + + // session is the configured session to be offered by the client. This session + // is immutable. + bssl::UniquePtr session; + + void (*info_callback)(const SSL *ssl, int type, int value) = nullptr; + + bssl::UniquePtr ctx; + + // session_ctx is the |SSL_CTX| used for the session cache and related + // settings. + bssl::UniquePtr session_ctx; + + // extra application data + CRYPTO_EX_DATA ex_data; + + uint32_t options = 0; // protocol behaviour + uint32_t mode = 0; // API behaviour + uint32_t max_cert_list = 0; + bssl::UniquePtr hostname; + + // quic_method is the method table corresponding to the QUIC hooks. + const SSL_QUIC_METHOD *quic_method = nullptr; + + // renegotiate_mode controls how peer renegotiation attempts are handled. + ssl_renegotiate_mode_t renegotiate_mode = ssl_renegotiate_never; + + // server is true iff the this SSL* is the server half. Note: before the SSL* + // is initialized by either SSL_set_accept_state or SSL_set_connect_state, + // the side is not determined. In this state, server is always false. + bool server : 1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown : 1; + + // If enable_early_data is true, early data can be sent and accepted. + bool enable_early_data : 1; +}; + +struct ssl_session_st { + explicit ssl_session_st(const bssl::SSL_X509_METHOD *method); + ssl_session_st(const ssl_session_st &) = delete; + ssl_session_st &operator=(const ssl_session_st &) = delete; + + CRYPTO_refcount_t references = 1; + + // ssl_version is the (D)TLS version that established the session. + uint16_t ssl_version = 0; + + // group_id is the ID of the ECDH group used to establish this session or zero + // if not applicable or unknown. + uint16_t group_id = 0; + + // peer_signature_algorithm is the signature algorithm used to authenticate + // the peer, or zero if not applicable or unknown. + uint16_t peer_signature_algorithm = 0; + + // secret, in TLS 1.2 and below, is the master secret associated with the + // session. In TLS 1.3 and up, it is the resumption PSK for sessions handed to + // the caller, but it stores the resumption secret when stored on |SSL| + // objects. + int secret_length = 0; + uint8_t secret[SSL_MAX_MASTER_KEY_LENGTH] = {0}; + + // session_id - valid? + unsigned session_id_length = 0; + uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; + // this is used to determine whether the session is being reused in + // the appropriate context. It is up to the application to set this, + // via SSL_new + uint8_t sid_ctx_length = 0; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH] = {0}; + + bssl::UniquePtr psk_identity; + + // certs contains the certificate chain from the peer, starting with the leaf + // certificate. + bssl::UniquePtr certs; + + const bssl::SSL_X509_METHOD *x509_method = nullptr; + + // x509_peer is the peer's certificate. + X509 *x509_peer = nullptr; + + // x509_chain is the certificate chain sent by the peer. NOTE: for historical + // reasons, when a client (so the peer is a server), the chain includes + // |peer|, but when a server it does not. + STACK_OF(X509) *x509_chain = nullptr; + + // x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that + // omits the leaf certificate. This exists because OpenSSL, historically, + // didn't include the leaf certificate in the chain for a server, but did for + // a client. The |x509_chain| always includes it and, if an API call requires + // a chain without, it is stored here. + STACK_OF(X509) *x509_chain_without_leaf = nullptr; + + // verify_result is the result of certificate verification in the case of + // non-fatal certificate errors. + long verify_result = X509_V_ERR_INVALID_CALL; + + // timeout is the lifetime of the session in seconds, measured from |time|. + // This is renewable up to |auth_timeout|. + uint32_t timeout = SSL_DEFAULT_SESSION_TIMEOUT; + + // auth_timeout is the non-renewable lifetime of the session in seconds, + // measured from |time|. + uint32_t auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + + // time is the time the session was issued, measured in seconds from the UNIX + // epoch. + uint64_t time = 0; + + const SSL_CIPHER *cipher = nullptr; + + CRYPTO_EX_DATA ex_data; // application specific data + + // These are used to make removal of session-ids more efficient and to + // implement a maximum cache size. + SSL_SESSION *prev = nullptr, *next = nullptr; + + bssl::Array ticket; + + bssl::UniquePtr signed_cert_timestamp_list; + + // The OCSP response that came with the session. + bssl::UniquePtr ocsp_response; + + // peer_sha256 contains the SHA-256 hash of the peer's certificate if + // |peer_sha256_valid| is true. + uint8_t peer_sha256[SHA256_DIGEST_LENGTH] = {0}; + + // original_handshake_hash contains the handshake hash (either SHA-1+MD5 or + // SHA-2, depending on TLS version) for the original, full handshake that + // created a session. This is used by Channel IDs during resumption. + uint8_t original_handshake_hash[EVP_MAX_MD_SIZE] = {0}; + uint8_t original_handshake_hash_len = 0; + + uint32_t ticket_lifetime_hint = 0; // Session lifetime hint in seconds + + uint32_t ticket_age_add = 0; + + // ticket_max_early_data is the maximum amount of data allowed to be sent as + // early data. If zero, 0-RTT is disallowed. + uint32_t ticket_max_early_data = 0; + + // early_alpn is the ALPN protocol from the initial handshake. This is only + // stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT + // resumptions. For the current connection's ALPN protocol, see + // |alpn_selected| on |SSL3_STATE|. + bssl::Array early_alpn; + + // local_application_settings, if |has_application_settings| is true, is the + // local ALPS value for this connection. + bssl::Array local_application_settings; + + // peer_application_settings, if |has_application_settings| is true, is the + // peer ALPS value for this connection. + bssl::Array peer_application_settings; + + // extended_master_secret is whether the master secret in this session was + // generated using EMS and thus isn't vulnerable to the Triple Handshake + // attack. + bool extended_master_secret : 1; + + // peer_sha256_valid is whether |peer_sha256| is valid. + bool peer_sha256_valid : 1; // Non-zero if peer_sha256 is valid + + // not_resumable is used to indicate that session resumption is disallowed. + bool not_resumable : 1; + + // ticket_age_add_valid is whether |ticket_age_add| is valid. + bool ticket_age_add_valid : 1; + + // is_server is whether this session was created by a server. + bool is_server : 1; + + // is_quic indicates whether this session was created using QUIC. + bool is_quic : 1; + + // has_application_settings indicates whether ALPS was negotiated in this + // session. + bool has_application_settings : 1; + + // quic_early_data_context is used to determine whether early data must be + // rejected when performing a QUIC handshake. + bssl::Array quic_early_data_context; + + private: + ~ssl_session_st(); + friend OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *); +}; + +struct ssl_ech_keys_st { + ssl_ech_keys_st() = default; + ssl_ech_keys_st(const ssl_ech_keys_st &) = delete; + ssl_ech_keys_st &operator=(const ssl_ech_keys_st &) = delete; + + bssl::GrowableArray> configs; + CRYPTO_refcount_t references = 1; + + private: + ~ssl_ech_keys_st() = default; + friend OPENSSL_EXPORT void SSL_ECH_KEYS_free(SSL_ECH_KEYS *); +}; + +#endif // OPENSSL_HEADER_SSL_INTERNAL_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_both.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_both.cc new file mode 100644 index 00000000..68838817 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_both.cc @@ -0,0 +1,730 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static bool add_record_to_flight(SSL *ssl, uint8_t type, + Span in) { + // The caller should have flushed |pending_hs_data| first. + assert(!ssl->s3->pending_hs_data); + // We'll never add a flight while in the process of writing it out. + assert(ssl->s3->pending_flight_offset == 0); + + if (ssl->s3->pending_flight == nullptr) { + ssl->s3->pending_flight.reset(BUF_MEM_new()); + if (ssl->s3->pending_flight == nullptr) { + return false; + } + } + + size_t max_out = in.size() + SSL_max_seal_overhead(ssl); + size_t new_cap = ssl->s3->pending_flight->length + max_out; + if (max_out < in.size() || new_cap < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + + size_t len; + if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) || + !tls_seal_record(ssl, + (uint8_t *)ssl->s3->pending_flight->data + + ssl->s3->pending_flight->length, + &len, max_out, type, in.data(), in.size())) { + return false; + } + + ssl->s3->pending_flight->length += len; + return true; +} + +bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24_length_prefixed(cbb, body)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(cbb); + return false; + } + + return true; +} + +bool tls_finish_message(const SSL *ssl, CBB *cbb, Array *out_msg) { + return CBBFinishArray(cbb, out_msg); +} + +bool tls_add_message(SSL *ssl, Array msg) { + // Pack handshake data into the minimal number of records. This avoids + // unnecessary encryption overhead, notably in TLS 1.3 where we send several + // encrypted messages in a row. For now, we do not do this for the null + // cipher. The benefit is smaller and there is a risk of breaking buggy + // implementations. + // + // TODO(davidben): See if we can do this uniformly. + Span rest = msg; + if (ssl->quic_method == nullptr && + ssl->s3->aead_write_ctx->is_null_cipher()) { + while (!rest.empty()) { + Span chunk = rest.subspan(0, ssl->max_send_fragment); + rest = rest.subspan(chunk.size()); + + if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) { + return false; + } + } + } else { + while (!rest.empty()) { + // Flush if |pending_hs_data| is full. + if (ssl->s3->pending_hs_data && + ssl->s3->pending_hs_data->length >= ssl->max_send_fragment && + !tls_flush_pending_hs_data(ssl)) { + return false; + } + + size_t pending_len = + ssl->s3->pending_hs_data ? ssl->s3->pending_hs_data->length : 0; + Span chunk = + rest.subspan(0, ssl->max_send_fragment - pending_len); + assert(!chunk.empty()); + rest = rest.subspan(chunk.size()); + + if (!ssl->s3->pending_hs_data) { + ssl->s3->pending_hs_data.reset(BUF_MEM_new()); + } + if (!ssl->s3->pending_hs_data || + !BUF_MEM_append(ssl->s3->pending_hs_data.get(), chunk.data(), + chunk.size())) { + return false; + } + } + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg); + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on + // hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(msg)) { + return false; + } + return true; +} + +bool tls_flush_pending_hs_data(SSL *ssl) { + if (!ssl->s3->pending_hs_data || ssl->s3->pending_hs_data->length == 0) { + return true; + } + + UniquePtr pending_hs_data = std::move(ssl->s3->pending_hs_data); + auto data = + MakeConstSpan(reinterpret_cast(pending_hs_data->data), + pending_hs_data->length); + if (ssl->quic_method) { + if ((ssl->s3->hs == nullptr || !ssl->s3->hs->hints_requested) && + !ssl->quic_method->add_handshake_data(ssl, ssl->s3->write_level, + data.data(), data.size())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); + return false; + } + return true; + } + + return add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, data); +} + +bool tls_add_change_cipher_spec(SSL *ssl) { + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + + if (!tls_flush_pending_hs_data(ssl)) { + return false; + } + + if (!ssl->quic_method && + !add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return true; +} + +int tls_flush_flight(SSL *ssl) { + if (!tls_flush_pending_hs_data(ssl)) { + return -1; + } + + if (ssl->quic_method) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (!ssl->quic_method->flush_flight(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); + return -1; + } + } + + if (ssl->s3->pending_flight == nullptr) { + return 1; + } + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits"); + if (ssl->s3->pending_flight->length > INT_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // If there is pending data in the write buffer, it must be flushed out before + // any new data in pending_flight. + if (!ssl->s3->write_buffer.empty()) { + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return ret; + } + } + + if (ssl->wbio == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + // Write the pending flight. + while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) { + int ret = BIO_write( + ssl->wbio.get(), + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return ret; + } + + ssl->s3->pending_flight_offset += ret; + } + + if (BIO_flush(ssl->wbio.get()) <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return -1; + } + + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + return 1; +} + +static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, + Span in) { + *out_consumed = 0; + assert(in.size() >= SSL3_RT_HEADER_LENGTH); + // Determine the length of the V2ClientHello. + size_t msg_length = ((in[0] & 0x7f) << 8) | in[1]; + if (msg_length > (1024 * 4)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return ssl_open_record_error; + } + if (msg_length < SSL3_RT_HEADER_LENGTH - 2) { + // Reject lengths that are too short early. We have already read + // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an + // (invalid) V2ClientHello which would be shorter than that. + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH); + return ssl_open_record_error; + } + + // Ask for the remainder of the V2ClientHello. + if (in.size() < 2 + msg_length) { + *out_consumed = 2 + msg_length; + return ssl_open_record_partial; + } + + CBS v2_client_hello = CBS(ssl->s3->read_buffer.span().subspan(2, msg_length)); + // The V2ClientHello without the length is incorporated into the handshake + // hash. This is only ever called at the start of the handshake, so hs is + // guaranteed to be non-NULL. + if (!ssl->s3->hs->transcript.Update(v2_client_hello)) { + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, + v2_client_hello); + + uint8_t msg_type; + uint16_t version, cipher_spec_length, session_id_length, challenge_length; + CBS cipher_specs, session_id, challenge; + if (!CBS_get_u8(&v2_client_hello, &msg_type) || + !CBS_get_u16(&v2_client_hello, &version) || + !CBS_get_u16(&v2_client_hello, &cipher_spec_length) || + !CBS_get_u16(&v2_client_hello, &session_id_length) || + !CBS_get_u16(&v2_client_hello, &challenge_length) || + !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) || + !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || + !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || + CBS_len(&v2_client_hello) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // msg_type has already been checked. + assert(msg_type == SSL2_MT_CLIENT_HELLO); + + // The client_random is the V2ClientHello challenge. Truncate or left-pad with + // zeros as needed. + size_t rand_len = CBS_len(&challenge); + if (rand_len > SSL3_RANDOM_SIZE) { + rand_len = SSL3_RANDOM_SIZE; + } + uint8_t random[SSL3_RANDOM_SIZE]; + OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge), + rand_len); + + // Write out an equivalent TLS ClientHello directly to the handshake buffer. + size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ + + SSL3_RANDOM_SIZE + 1 /* session ID length */ + + 2 /* cipher list length */ + + CBS_len(&cipher_specs) / 3 * 2 + + 1 /* compression length */ + 1 /* compression */; + ScopedCBB client_hello; + CBB hello_body, cipher_suites; + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + } + if (!ssl->s3->hs_buf || + !BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) || + !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data, + ssl->s3->hs_buf->max) || + !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) || + !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) || + !CBB_add_u16(&hello_body, version) || + !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || + // No session id. + !CBB_add_u8(&hello_body, 0) || + !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_open_record_error; + } + + // Copy the cipher suites. + while (CBS_len(&cipher_specs) > 0) { + uint32_t cipher_spec; + if (!CBS_get_u24(&cipher_specs, &cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // Skip SSLv2 ciphers. + if ((cipher_spec & 0xff0000) != 0) { + continue; + } + if (!CBB_add_u16(&cipher_suites, cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + } + + // Add the null compression scheme and finish. + if (!CBB_add_u8(&hello_body, 1) || + !CBB_add_u8(&hello_body, 0) || + !CBB_finish(client_hello.get(), NULL, &ssl->s3->hs_buf->length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + + *out_consumed = 2 + msg_length; + ssl->s3->is_v2_hello = true; + return ssl_open_record_success; +} + +static bool parse_message(const SSL *ssl, SSLMessage *out, + size_t *out_bytes_needed) { + if (!ssl->s3->hs_buf) { + *out_bytes_needed = 4; + return false; + } + + CBS cbs; + uint32_t len; + CBS_init(&cbs, reinterpret_cast(ssl->s3->hs_buf->data), + ssl->s3->hs_buf->length); + if (!CBS_get_u8(&cbs, &out->type) || + !CBS_get_u24(&cbs, &len)) { + *out_bytes_needed = 4; + return false; + } + + if (!CBS_get_bytes(&cbs, &out->body, len)) { + *out_bytes_needed = 4 + len; + return false; + } + + CBS_init(&out->raw, reinterpret_cast(ssl->s3->hs_buf->data), + 4 + len); + out->is_v2_hello = ssl->s3->is_v2_hello; + return true; +} + +bool tls_get_message(const SSL *ssl, SSLMessage *out) { + size_t unused; + if (!parse_message(ssl, out, &unused)) { + return false; + } + if (!ssl->s3->has_message) { + if (!out->is_v2_hello) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + } + ssl->s3->has_message = true; + } + return true; +} + +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) { + // If there is a complete message, the caller must have consumed it first. + SSLMessage msg; + size_t bytes_needed; + if (parse_message(ssl, &msg, &bytes_needed)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + // Enforce the limit so the peer cannot force us to buffer 16MB. + if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool tls_has_unprocessed_handshake_data(const SSL *ssl) { + size_t msg_len = 0; + if (ssl->s3->has_message) { + SSLMessage msg; + size_t unused; + if (parse_message(ssl, &msg, &unused)) { + msg_len = CBS_len(&msg.raw); + } + } + + return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len; +} + +bool tls_append_handshake_data(SSL *ssl, Span data) { + // Re-create the handshake buffer if needed. + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + } + return ssl->s3->hs_buf && + BUF_MEM_append(ssl->s3->hs_buf.get(), data.data(), data.size()); +} + +ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + // Bypass the record layer for the first message to handle V2ClientHello. + if (ssl->server && !ssl->s3->v2_hello_done) { + // Ask for the first 5 bytes, the size of the TLS record header. This is + // sufficient to detect a V2ClientHello and ensures that we never read + // beyond the first record. + if (in.size() < SSL3_RT_HEADER_LENGTH) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + // Some dedicated error codes for protocol mixups should the application + // wish to interpret them differently. (These do not overlap with + // ClientHello or V2ClientHello.) + const char *str = reinterpret_cast(in.data()); + if (strncmp("GET ", str, 4) == 0 || + strncmp("POST ", str, 5) == 0 || + strncmp("HEAD ", str, 5) == 0 || + strncmp("PUT ", str, 4) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + if (strncmp("CONNE", str, 5) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + + // Check for a V2ClientHello. + if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO && + in[3] == SSL3_VERSION_MAJOR) { + auto ret = read_v2_client_hello(ssl, out_consumed, in); + if (ret == ssl_open_record_error) { + *out_alert = 0; + } else if (ret == ssl_open_record_success) { + ssl->s3->v2_hello_done = true; + } + return ret; + } + + ssl->s3->v2_hello_done = true; + } + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the + // ServerHello and send the remaining encrypted application data records + // as-is. This manifests as an application data record when we expect + // handshake. Report a dedicated error code for this case. + if (!ssl->server && type == SSL3_RT_APPLICATION_DATA && + ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (type != SSL3_RT_HANDSHAKE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Append the entire handshake record to the buffer. + if (!tls_append_handshake_data(ssl, body)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + return ssl_open_record_success; +} + +void tls_next_message(SSL *ssl) { + SSLMessage msg; + if (!tls_get_message(ssl, &msg) || + !ssl->s3->hs_buf || + ssl->s3->hs_buf->length < CBS_len(&msg.raw)) { + assert(0); + return; + } + + OPENSSL_memmove(ssl->s3->hs_buf->data, + ssl->s3->hs_buf->data + CBS_len(&msg.raw), + ssl->s3->hs_buf->length - CBS_len(&msg.raw)); + ssl->s3->hs_buf->length -= CBS_len(&msg.raw); + ssl->s3->is_v2_hello = false; + ssl->s3->has_message = false; + + // Post-handshake messages are rare, so release the buffer after every + // message. During the handshake, |on_handshake_complete| will release it. + if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +// CipherScorer produces a "score" for each possible cipher suite offered by +// the client. +class CipherScorer { + public: + CipherScorer(uint16_t group_id) + : aes_is_fine_(EVP_has_aes_hardware()), + security_128_is_fine_(group_id != SSL_CURVE_CECPQ2) {} + + typedef std::tuple Score; + + // MinScore returns a |Score| that will compare less than the score of all + // cipher suites. + Score MinScore() const { + return Score(false, false, false); + } + + Score Evaluate(const SSL_CIPHER *a) const { + return Score( + // Something is always preferable to nothing. + true, + // Either 128-bit is fine, or 256-bit is preferred. + security_128_is_fine_ || a->algorithm_enc != SSL_AES128GCM, + // Either AES is fine, or else ChaCha20 is preferred. + aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305); + } + + private: + const bool aes_is_fine_; + const bool security_128_is_fine_; +}; + +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, + uint16_t group_id) { + if (CBS_len(&cipher_suites) % 2 != 0) { + return nullptr; + } + + const SSL_CIPHER *best = nullptr; + CipherScorer scorer(group_id); + CipherScorer::Score best_score = scorer.MinScore(); + + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + return nullptr; + } + + // Limit to TLS 1.3 ciphers we know about. + const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite); + if (candidate == nullptr || + SSL_CIPHER_get_min_version(candidate) > version || + SSL_CIPHER_get_max_version(candidate) < version) { + continue; + } + + const CipherScorer::Score candidate_score = scorer.Evaluate(candidate); + // |candidate_score| must be larger to displace the current choice. That way + // the client's order controls between ciphers with an equal score. + if (candidate_score > best_score) { + best = candidate; + best_score = candidate_score; + } + } + + return best; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_lib.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_lib.cc new file mode 100644 index 00000000..aff9fb49 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_lib.cc @@ -0,0 +1,219 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +SSL3_STATE::SSL3_STATE() + : skip_early_data(false), + have_version(false), + v2_hello_done(false), + is_v2_hello(false), + has_message(false), + initial_handshake_complete(false), + session_reused(false), + delegated_credential_used(false), + send_connection_binding(false), + channel_id_valid(false), + key_update_pending(false), + wpend_pending(false), + early_data_accepted(false), + alert_dispatch(false), + renegotiate_pending(false), + used_hello_retry_request(false) {} + +SSL3_STATE::~SSL3_STATE() {} + +bool tls_new(SSL *ssl) { + UniquePtr s3 = MakeUnique(); + if (!s3) { + return false; + } + + s3->aead_read_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->aead_write_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->hs = ssl_handshake_new(ssl); + if (!s3->aead_read_ctx || !s3->aead_write_ctx || !s3->hs) { + return false; + } + + ssl->s3 = s3.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = TLS1_2_VERSION; + return true; +} + +void tls_free(SSL *ssl) { + if (ssl == NULL || ssl->s3 == NULL) { + return; + } + + Delete(ssl->s3); + ssl->s3 = NULL; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_pkt.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_pkt.cc new file mode 100644 index 00000000..f3d63f18 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/s3_pkt.cc @@ -0,0 +1,453 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "../crypto/err/internal.h" +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len); + +int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(ssl_can_write(ssl)); + assert(!ssl->s3->aead_write_ctx->is_null_cipher()); + + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + // TODO(davidben): Switch this logic to |size_t| and |bssl::Span|. + assert(ssl->s3->wnum <= INT_MAX); + unsigned tot = ssl->s3->wnum; + ssl->s3->wnum = 0; + + // Ensure that if we end up with a smaller value of data to write out than + // the the original len from a write which didn't complete for non-blocking + // I/O and also somehow ended up avoiding the check for this in + // tls_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be possible to + // end up with (len-tot) as a large number that will then promptly send + // beyond the end of the users buffer ... so we trap and report the error in + // a way the user will notice. + if (len < 0 || (size_t)len < tot) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + const int is_early_data_write = + !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; + + unsigned n = len - tot; + for (;;) { + size_t max_send_fragment = ssl->max_send_fragment; + if (is_early_data_write) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs->early_data_written >= hs->early_session->ticket_max_early_data) { + ssl->s3->wnum = tot; + hs->can_early_write = false; + *out_needs_handshake = true; + return -1; + } + max_send_fragment = std::min( + max_send_fragment, size_t{hs->early_session->ticket_max_early_data - + hs->early_data_written}); + } + + const size_t nw = std::min(max_send_fragment, size_t{n}); + int ret = do_tls_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw); + if (ret <= 0) { + ssl->s3->wnum = tot; + return ret; + } + + if (is_early_data_write) { + ssl->s3->hs->early_data_written += ret; + } + + if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + return tot + ret; + } + + n -= ret; + tot += ret; + } +} + +static int tls_write_pending(SSL *ssl, int type, const uint8_t *in, + unsigned int len) { + if (ssl->s3->wpend_tot > (int)len || + (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && + ssl->s3->wpend_buf != in) || + ssl->s3->wpend_type != type) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); + return -1; + } + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + ssl->s3->wpend_pending = false; + return ssl->s3->wpend_ret; +} + +// do_tls_write writes an SSL record of the given type. +static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { + // If there is still data from the previous record, flush it. + if (ssl->s3->wpend_pending) { + return tls_write_pending(ssl, type, in, len); + } + + SSLBuffer *buf = &ssl->s3->write_buffer; + if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (!tls_flush_pending_hs_data(ssl)) { + return -1; + } + + size_t flight_len = 0; + if (ssl->s3->pending_flight != nullptr) { + flight_len = + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset; + } + + size_t max_out = flight_len; + if (len > 0) { + const size_t max_ciphertext_len = len + SSL_max_seal_overhead(ssl); + if (max_ciphertext_len < len || max_out + max_ciphertext_len < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + max_out += max_ciphertext_len; + } + + if (max_out == 0) { + return 0; + } + + if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) { + return -1; + } + + // Add any unflushed handshake data as a prefix. This may be a KeyUpdate + // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear + // when data is added to |write_buffer| or it will be written in the wrong + // order. + if (ssl->s3->pending_flight != nullptr) { + OPENSSL_memcpy( + buf->remaining().data(), + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + flight_len); + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + buf->DidWrite(flight_len); + } + + if (len > 0) { + size_t ciphertext_len; + if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len)) { + return -1; + } + buf->DidWrite(ciphertext_len); + } + + // Now that we've made progress on the connection, uncork KeyUpdate + // acknowledgments. + ssl->s3->key_update_pending = false; + + // Memorize arguments so that tls_write_pending can detect bad write retries + // later. + ssl->s3->wpend_tot = len; + ssl->s3->wpend_buf = in; + ssl->s3->wpend_type = type; + ssl->s3->wpend_ret = len; + ssl->s3->wpend_pending = true; + + // We now just need to write the buffer. + return tls_write_pending(ssl, type, in, len); +} + +ssl_open_record_t tls_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(ssl_can_read(ssl)); + assert(!ssl->s3->aead_read_ctx->is_null_cipher()); + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); + + if (type == SSL3_RT_HANDSHAKE) { + // Post-handshake data prior to TLS 1.3 is always renegotiation, which we + // never accept as a server. Otherwise |tls_get_message| will send + // |SSL_R_EXCESSIVE_MESSAGE_SIZE|. + if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + *out_alert = SSL_AD_NO_RENEGOTIATION; + return ssl_open_record_error; + } + + if (!tls_append_handshake_data(ssl, body)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (is_early_data_read) { + if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA); + *out_alert = SSL3_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->hs->early_data_read += body.size(); + } + + if (body.empty()) { + return ssl_open_record_discard; + } + + *out = body; + return ssl_open_record_success; +} + +ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type != SSL3_RT_CHANGE_CIPHER_SPEC) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (body.size() != 1 || body[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body); + return ssl_open_record_success; +} + +void ssl_send_alert(SSL *ssl, int level, int desc) { + // This function is called in response to a fatal error from the peer. Ignore + // any failures writing the alert and report only the original error. In + // particular, if the transport uses |SSL_write|, our existing error will be + // clobbered so we must save and restore the error queue. See + // https://crbug.com/959305. + // + // TODO(davidben): Return the alert out of the handshake, rather than calling + // this function internally everywhere. + // + // TODO(davidben): This does not allow retrying if the alert hit EAGAIN. See + // https://crbug.com/boringssl/130. + UniquePtr err_state(ERR_save_state()); + ssl_send_alert_impl(ssl, level, desc); + ERR_restore_state(err_state.get()); +} + +int ssl_send_alert_impl(SSL *ssl, int level, int desc) { + // It is illegal to send an alert when we've already sent a closing one. + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } else { + assert(level == SSL3_AL_FATAL); + assert(desc != SSL_AD_CLOSE_NOTIFY); + ssl->s3->write_shutdown = ssl_shutdown_error; + } + + ssl->s3->alert_dispatch = true; + ssl->s3->send_alert[0] = level; + ssl->s3->send_alert[1] = desc; + if (ssl->s3->write_buffer.empty()) { + // Nothing is being written out, so the alert may be dispatched + // immediately. + return ssl->method->dispatch_alert(ssl); + } + + // The alert will be dispatched later. + return -1; +} + +int tls_dispatch_alert(SSL *ssl) { + if (ssl->quic_method) { + if (!ssl->quic_method->send_alert(ssl, ssl->s3->write_level, + ssl->s3->send_alert[1])) { + OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR); + return 0; + } + } else { + int ret = do_tls_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); + if (ret <= 0) { + return ret; + } + } + + ssl->s3->alert_dispatch = false; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio.get()); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc new file mode 100644 index 00000000..bef5d328 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc @@ -0,0 +1,432 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) +#define FUZZER_MODE true +#else +#define FUZZER_MODE false +#endif + +BSSL_NAMESPACE_BEGIN + +SSLAEADContext::SSLAEADContext(uint16_t version_arg, bool is_dtls_arg, + const SSL_CIPHER *cipher_arg) + : cipher_(cipher_arg), + version_(version_arg), + is_dtls_(is_dtls_arg), + variable_nonce_included_in_record_(false), + random_variable_nonce_(false), + xor_fixed_nonce_(false), + omit_length_in_ad_(false), + ad_is_header_(false) { + OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_)); +} + +SSLAEADContext::~SSLAEADContext() {} + +UniquePtr SSLAEADContext::CreateNullCipher(bool is_dtls) { + return MakeUnique(0 /* version */, is_dtls, + nullptr /* cipher */); +} + +UniquePtr SSLAEADContext::Create( + enum evp_aead_direction_t direction, uint16_t version, bool is_dtls, + const SSL_CIPHER *cipher, Span enc_key, + Span mac_key, Span fixed_iv) { + const EVP_AEAD *aead; + uint16_t protocol_version; + size_t expected_mac_key_len, expected_fixed_iv_len; + if (!ssl_protocol_version_from_wire(&protocol_version, version) || + !ssl_cipher_get_evp_aead(&aead, &expected_mac_key_len, + &expected_fixed_iv_len, cipher, protocol_version, + is_dtls) || + // Ensure the caller returned correct key sizes. + expected_fixed_iv_len != fixed_iv.size() || + expected_mac_key_len != mac_key.size()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + + uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH]; + if (!mac_key.empty()) { + // This is a "stateful" AEAD (for compatibility with pre-AEAD cipher + // suites). + if (mac_key.size() + enc_key.size() + fixed_iv.size() > + sizeof(merged_key)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + OPENSSL_memcpy(merged_key, mac_key.data(), mac_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size(), enc_key.data(), enc_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size() + enc_key.size(), + fixed_iv.data(), fixed_iv.size()); + enc_key = MakeConstSpan(merged_key, + enc_key.size() + mac_key.size() + fixed_iv.size()); + } + + UniquePtr aead_ctx = + MakeUnique(version, is_dtls, cipher); + if (!aead_ctx) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + assert(aead_ctx->ProtocolVersion() == protocol_version); + + if (!EVP_AEAD_CTX_init_with_direction( + aead_ctx->ctx_.get(), aead, enc_key.data(), enc_key.size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) { + return nullptr; + } + + assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH); + static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256, + "variable_nonce_len doesn't fit in uint8_t"); + aead_ctx->variable_nonce_len_ = (uint8_t)EVP_AEAD_nonce_length(aead); + if (mac_key.empty()) { + assert(fixed_iv.size() <= sizeof(aead_ctx->fixed_nonce_)); + OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv.data(), fixed_iv.size()); + aead_ctx->fixed_nonce_len_ = fixed_iv.size(); + + if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) { + // The fixed nonce into the actual nonce (the sequence number). + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + } else { + // The fixed IV is prepended to the nonce. + assert(fixed_iv.size() <= aead_ctx->variable_nonce_len_); + aead_ctx->variable_nonce_len_ -= fixed_iv.size(); + } + + // AES-GCM uses an explicit nonce. + if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) { + aead_ctx->variable_nonce_included_in_record_ = true; + } + + // The TLS 1.3 construction XORs the fixed nonce into the sequence number + // and omits the additional data. + if (protocol_version >= TLS1_3_VERSION) { + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + aead_ctx->variable_nonce_included_in_record_ = false; + aead_ctx->ad_is_header_ = true; + assert(fixed_iv.size() >= aead_ctx->variable_nonce_len_); + } + } else { + assert(protocol_version < TLS1_3_VERSION); + aead_ctx->variable_nonce_included_in_record_ = true; + aead_ctx->random_variable_nonce_ = true; + aead_ctx->omit_length_in_ad_ = true; + } + + return aead_ctx; +} + +UniquePtr SSLAEADContext::CreatePlaceholderForQUIC( + uint16_t version, const SSL_CIPHER *cipher) { + return MakeUnique(version, false, cipher); +} + +void SSLAEADContext::SetVersionIfNullCipher(uint16_t version) { + if (is_null_cipher()) { + version_ = version; + } +} + +uint16_t SSLAEADContext::ProtocolVersion() const { + uint16_t protocol_version; + if(!ssl_protocol_version_from_wire(&protocol_version, version_)) { + assert(false); + return 0; + } + return protocol_version; +} + +uint16_t SSLAEADContext::RecordVersion() const { + if (version_ == 0) { + assert(is_null_cipher()); + return is_dtls_ ? DTLS1_VERSION : TLS1_VERSION; + } + + if (ProtocolVersion() <= TLS1_2_VERSION) { + return version_; + } + + return TLS1_2_VERSION; +} + +size_t SSLAEADContext::ExplicitNonceLen() const { + if (!FUZZER_MODE && variable_nonce_included_in_record_) { + return variable_nonce_len_; + } + return 0; +} + +bool SSLAEADContext::SuffixLen(size_t *out_suffix_len, const size_t in_len, + const size_t extra_in_len) const { + if (is_null_cipher() || FUZZER_MODE) { + *out_suffix_len = extra_in_len; + return true; + } + return !!EVP_AEAD_CTX_tag_len(ctx_.get(), out_suffix_len, in_len, + extra_in_len); +} + +bool SSLAEADContext::CiphertextLen(size_t *out_len, const size_t in_len, + const size_t extra_in_len) const { + size_t len; + if (!SuffixLen(&len, in_len, extra_in_len)) { + return false; + } + len += ExplicitNonceLen(); + len += in_len; + if (len < in_len || len >= 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + *out_len = len; + return true; +} + +size_t SSLAEADContext::MaxOverhead() const { + return ExplicitNonceLen() + + (is_null_cipher() || FUZZER_MODE + ? 0 + : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get()))); +} + +Span SSLAEADContext::GetAdditionalData( + uint8_t storage[13], uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], size_t plaintext_len, Span header) { + if (ad_is_header_) { + return header; + } + + OPENSSL_memcpy(storage, seqnum, 8); + size_t len = 8; + storage[len++] = type; + storage[len++] = static_cast((record_version >> 8)); + storage[len++] = static_cast(record_version); + if (!omit_length_in_ad_) { + storage[len++] = static_cast((plaintext_len >> 8)); + storage[len++] = static_cast(plaintext_len); + } + return MakeConstSpan(storage, len); +} + +bool SSLAEADContext::Open(Span *out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + Span header, Span in) { + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + *out = in; + return true; + } + + // TLS 1.2 AEADs include the length in the AD and are assumed to have fixed + // overhead. Otherwise the parameter is unused. + size_t plaintext_len = 0; + if (!omit_length_in_ad_) { + size_t overhead = MaxOverhead(); + if (in.size() < overhead) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + plaintext_len = in.size() - overhead; + } + + uint8_t ad_storage[13]; + Span ad = GetAdditionalData(ad_storage, type, record_version, + seqnum, plaintext_len, header); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Add the variable nonce. + if (variable_nonce_included_in_record_) { + if (in.size() < variable_nonce_len_) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + OPENSSL_memcpy(nonce + nonce_len, in.data(), variable_nonce_len_); + in = in.subspan(variable_nonce_len_); + } else { + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + // Decrypt in-place. + size_t len; + if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce, + nonce_len, in.data(), in.size(), ad.data(), + ad.size())) { + return false; + } + *out = in.subspan(0, len); + return true; +} + +bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], + Span header, const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if ((in != out && buffers_alias(in, in_len, out, in_len)) || + buffers_alias(in, in_len, out_prefix, prefix_len) || + buffers_alias(in, in_len, out_suffix, suffix_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + OPENSSL_memmove(out, in, in_len); + OPENSSL_memmove(out_suffix, extra_in, extra_in_len); + return true; + } + + uint8_t ad_storage[13]; + Span ad = GetAdditionalData(ad_storage, type, record_version, + seqnum, in_len, header); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Select the variable nonce. + if (random_variable_nonce_) { + assert(variable_nonce_included_in_record_); + if (!RAND_bytes(nonce + nonce_len, variable_nonce_len_)) { + return false; + } + } else { + // When sending we use the sequence number as the variable part of the + // nonce. + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // Emit the variable nonce if included in the record. + if (variable_nonce_included_in_record_) { + assert(!xor_fixed_nonce_); + if (buffers_alias(in, in_len, out_prefix, variable_nonce_len_)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + OPENSSL_memcpy(out_prefix, nonce + fixed_nonce_len_, + variable_nonce_len_); + } + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + size_t written_suffix_len; + bool result = !!EVP_AEAD_CTX_seal_scatter( + ctx_.get(), out, out_suffix, &written_suffix_len, suffix_len, nonce, + nonce_len, in, in_len, extra_in, extra_in_len, ad.data(), ad.size()); + assert(!result || written_suffix_len == suffix_len); + return result; +} + +bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], Span header, + const uint8_t *in, size_t in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len < in_len || + in_len + prefix_len + suffix_len < in_len + prefix_len) { + OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len + suffix_len > max_out_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + + if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type, + record_version, seqnum, header, in, in_len, 0, 0)) { + return false; + } + *out_len = prefix_len + in_len + suffix_len; + return true; +} + +bool SSLAEADContext::GetIV(const uint8_t **out_iv, size_t *out_iv_len) const { + return !is_null_cipher() && + EVP_AEAD_CTX_get_iv(ctx_.get(), out_iv, out_iv_len); +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc new file mode 100644 index 00000000..3effb376 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_asn1.cc @@ -0,0 +1,896 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// An SSL_SESSION is serialized as the following ASN.1 structure: +// +// SSLSession ::= SEQUENCE { +// version INTEGER (1), -- session structure version +// sslVersion INTEGER, -- protocol version number +// cipher OCTET STRING, -- two bytes long +// sessionID OCTET STRING, +// secret OCTET STRING, +// time [1] INTEGER, -- seconds since UNIX epoch +// timeout [2] INTEGER, -- in seconds +// peer [3] Certificate OPTIONAL, +// sessionIDContext [4] OCTET STRING OPTIONAL, +// verifyResult [5] INTEGER OPTIONAL, -- one of X509_V_* codes +// pskIdentity [8] OCTET STRING OPTIONAL, +// ticketLifetimeHint [9] INTEGER OPTIONAL, -- client-only +// ticket [10] OCTET STRING OPTIONAL, -- client-only +// peerSHA256 [13] OCTET STRING OPTIONAL, +// originalHandshakeHash [14] OCTET STRING OPTIONAL, +// signedCertTimestampList [15] OCTET STRING OPTIONAL, +// -- contents of SCT extension +// ocspResponse [16] OCTET STRING OPTIONAL, +// -- stapled OCSP response from the server +// extendedMasterSecret [17] BOOLEAN OPTIONAL, +// groupID [18] INTEGER OPTIONAL, +// certChain [19] SEQUENCE OF Certificate OPTIONAL, +// ticketAgeAdd [21] OCTET STRING OPTIONAL, +// isServer [22] BOOLEAN DEFAULT TRUE, +// peerSignatureAlgorithm [23] INTEGER OPTIONAL, +// ticketMaxEarlyData [24] INTEGER OPTIONAL, +// authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout +// earlyALPN [26] OCTET STRING OPTIONAL, +// isQuic [27] BOOLEAN OPTIONAL, +// quicEarlyDataHash [28] OCTET STRING OPTIONAL, +// localALPS [29] OCTET STRING OPTIONAL, +// peerALPS [30] OCTET STRING OPTIONAL, +// -- Either both or none of localALPS and peerALPS must be present. If both +// -- are present, earlyALPN must be present and non-empty. +// } +// +// Note: historically this serialization has included other optional +// fields. Their presence is currently treated as a parse error, except for +// hostName, which is ignored. +// +// keyArg [0] IMPLICIT OCTET STRING OPTIONAL, +// hostName [6] OCTET STRING OPTIONAL, +// pskIdentityHint [7] OCTET STRING OPTIONAL, +// compressionMethod [11] OCTET STRING OPTIONAL, +// srpUsername [12] OCTET STRING OPTIONAL, +// ticketFlags [20] INTEGER OPTIONAL, + +static const unsigned kVersion = 1; + +static const unsigned kTimeTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; +static const unsigned kTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; +static const unsigned kPeerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const unsigned kSessionIDContextTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const unsigned kVerifyResultTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const unsigned kHostNameTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6; +static const unsigned kPSKIdentityTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8; +static const unsigned kTicketLifetimeHintTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9; +static const unsigned kTicketTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10; +static const unsigned kPeerSHA256Tag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13; +static const unsigned kOriginalHandshakeHashTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14; +static const unsigned kSignedCertTimestampListTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15; +static const unsigned kOCSPResponseTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16; +static const unsigned kExtendedMasterSecretTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17; +static const unsigned kGroupIDTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18; +static const unsigned kCertChainTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19; +static const unsigned kTicketAgeAddTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; +static const unsigned kIsServerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; +static const unsigned kPeerSignatureAlgorithmTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23; +static const unsigned kTicketMaxEarlyDataTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24; +static const unsigned kAuthTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25; +static const unsigned kEarlyALPNTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; +static const unsigned kIsQuicTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27; +static const unsigned kQuicEarlyDataContextTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28; +static const unsigned kLocalALPSTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 29; +static const unsigned kPeerALPSTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 30; + +static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, + int for_ticket) { + if (in == NULL || in->cipher == NULL) { + return 0; + } + + CBB session, child, child2; + if (!CBB_add_asn1(cbb, &session, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&session, kVersion) || + !CBB_add_asn1_uint64(&session, in->ssl_version) || + !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) || + // The session ID is irrelevant for a session ticket. + !CBB_add_asn1_octet_string(&session, in->session_id, + for_ticket ? 0 : in->session_id_length) || + !CBB_add_asn1_octet_string(&session, in->secret, in->secret_length) || + !CBB_add_asn1(&session, &child, kTimeTag) || + !CBB_add_asn1_uint64(&child, in->time) || + !CBB_add_asn1(&session, &child, kTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->timeout)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The peer certificate is only serialized if the SHA-256 isn't + // serialized instead. + if (sk_CRYPTO_BUFFER_num(in->certs.get()) > 0 && !in->peer_sha256_valid) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), 0); + if (!CBB_add_asn1(&session, &child, kPeerTag) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + // Although it is OPTIONAL and usually empty, OpenSSL has + // historically always encoded the sid_ctx. + if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || + !CBB_add_asn1_octet_string(&child, in->sid_ctx, in->sid_ctx_length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->verify_result != X509_V_OK) { + if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || + !CBB_add_asn1_uint64(&child, in->verify_result)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->psk_identity) { + if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) || + !CBB_add_asn1_octet_string(&child, + (const uint8_t *)in->psk_identity.get(), + strlen(in->psk_identity.get()))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->ticket_lifetime_hint > 0) { + if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || + !CBB_add_asn1_uint64(&child, in->ticket_lifetime_hint)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (!in->ticket.empty() && !for_ticket) { + if (!CBB_add_asn1(&session, &child, kTicketTag) || + !CBB_add_asn1_octet_string(&child, in->ticket.data(), + in->ticket.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_sha256_valid) { + if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || + !CBB_add_asn1_octet_string(&child, in->peer_sha256, + sizeof(in->peer_sha256))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->original_handshake_hash_len > 0) { + if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || + !CBB_add_asn1_octet_string(&child, in->original_handshake_hash, + in->original_handshake_hash_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->signed_cert_timestamp_list != nullptr) { + if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) || + !CBB_add_asn1_octet_string( + &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list.get()), + CRYPTO_BUFFER_len(in->signed_cert_timestamp_list.get()))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->ocsp_response != nullptr) { + if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) || + !CBB_add_asn1_octet_string( + &child, CRYPTO_BUFFER_data(in->ocsp_response.get()), + CRYPTO_BUFFER_len(in->ocsp_response.get()))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->extended_master_secret) { + if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || + !CBB_add_asn1_bool(&child, true)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->group_id > 0 && + (!CBB_add_asn1(&session, &child, kGroupIDTag) || + !CBB_add_asn1_uint64(&child, in->group_id))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The certificate chain is only serialized if the leaf's SHA-256 isn't + // serialized instead. + if (in->certs != NULL && + !in->peer_sha256_valid && + sk_CRYPTO_BUFFER_num(in->certs.get()) >= 2) { + if (!CBB_add_asn1(&session, &child, kCertChainTag)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs.get()); i++) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), i); + if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } + + if (in->ticket_age_add_valid) { + if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || + !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || + !CBB_add_u32(&child2, in->ticket_age_add)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (!in->is_server) { + if (!CBB_add_asn1(&session, &child, kIsServerTag) || + !CBB_add_asn1_bool(&child, false)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_signature_algorithm != 0 && + (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || + !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->ticket_max_early_data != 0 && + (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || + !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->timeout != in->auth_timeout && + (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->auth_timeout))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!in->early_alpn.empty()) { + if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || + !CBB_add_asn1_octet_string(&child, in->early_alpn.data(), + in->early_alpn.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->is_quic) { + if (!CBB_add_asn1(&session, &child, kIsQuicTag) || + !CBB_add_asn1_bool(&child, true)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (!in->quic_early_data_context.empty()) { + if (!CBB_add_asn1(&session, &child, kQuicEarlyDataContextTag) || + !CBB_add_asn1_octet_string(&child, in->quic_early_data_context.data(), + in->quic_early_data_context.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->has_application_settings) { + if (!CBB_add_asn1(&session, &child, kLocalALPSTag) || + !CBB_add_asn1_octet_string(&child, + in->local_application_settings.data(), + in->local_application_settings.size()) || + !CBB_add_asn1(&session, &child, kPeerALPSTag) || + !CBB_add_asn1_octet_string(&child, in->peer_application_settings.data(), + in->peer_application_settings.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return CBB_flush(cbb); +} + +// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING explicitly +// tagged with |tag| from |cbs| and saves it in |*out|. If the element was not +// found, it sets |*out| to NULL. It returns one on success, whether or not the +// element was found, and zero on decode error. +static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag) { + CBS value; + int present; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (present) { + if (CBS_contains_zero_byte(&value)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + char *raw = nullptr; + if (!CBS_strdup(&value, &raw)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + out->reset(raw); + } else { + out->reset(); + } + return 1; +} + +// SSL_SESSION_parse_octet_string gets an optional ASN.1 OCTET STRING explicitly +// tagged with |tag| from |cbs| and stows it in |*out|. It returns one on +// success, whether or not the element was found, and zero on decode error. +static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array *out, + unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return false; + } + return out->CopyFrom(value); +} + +static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, + UniquePtr *out, + unsigned tag, + CRYPTO_BUFFER_POOL *pool) { + if (!CBS_peek_asn1_tag(cbs, tag)) { + return 1; + } + + CBS child, value; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + out->reset(CRYPTO_BUFFER_new_from_CBS(&value, pool)); + if (*out == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +// SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| of size at most |max_out|. +static int SSL_SESSION_parse_bounded_octet_string( + CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) || + CBS_len(&value) > max_out) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value)); + *out_len = (uint8_t)CBS_len(&value); + return 1; +} + +static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, + long default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (long)value; + return 1; +} + +static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, + uint32_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffffffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint32_t)value; + return 1; +} + +static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag, + uint16_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint16_t)value; + return 1; +} + +UniquePtr SSL_SESSION_parse(CBS *cbs, + const SSL_X509_METHOD *x509_method, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr ret = ssl_session_new(x509_method); + if (!ret) { + return nullptr; + } + + CBS session; + uint64_t version, ssl_version; + uint16_t unused; + if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&session, &version) || + version != kVersion || + !CBS_get_asn1_uint64(&session, &ssl_version) || + // Require sessions have versions valid in either TLS or DTLS. The session + // will not be used by the handshake if not applicable, but, for + // simplicity, never parse a session that does not pass + // |ssl_protocol_version_from_wire|. + ssl_version > UINT16_MAX || + !ssl_protocol_version_from_wire(&unused, ssl_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->ssl_version = ssl_version; + + CBS cipher; + uint16_t cipher_value; + if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) || + !CBS_get_u16(&cipher, &cipher_value) || + CBS_len(&cipher) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->cipher = SSL_get_cipher_by_value(cipher_value); + if (ret->cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER); + return nullptr; + } + + CBS session_id, secret; + if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) || + CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH || + !CBS_get_asn1(&session, &secret, CBS_ASN1_OCTETSTRING) || + CBS_len(&secret) > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id)); + ret->session_id_length = CBS_len(&session_id); + OPENSSL_memcpy(ret->secret, CBS_data(&secret), CBS_len(&secret)); + ret->secret_length = CBS_len(&secret); + + CBS child; + uint64_t timeout; + if (!CBS_get_asn1(&session, &child, kTimeTag) || + !CBS_get_asn1_uint64(&child, &ret->time) || + !CBS_get_asn1(&session, &child, kTimeoutTag) || + !CBS_get_asn1_uint64(&child, &timeout) || + timeout > UINT32_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + ret->timeout = (uint32_t)timeout; + + CBS peer; + int has_peer; + if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) || + (has_peer && CBS_len(&peer) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + // |peer| is processed with the certificate chain. + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx), + kSessionIDContextTag) || + !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag, + X509_V_OK)) { + return nullptr; + } + + // Skip the historical hostName field. + CBS unused_hostname; + if (!CBS_get_optional_asn1(&session, &unused_hostname, nullptr, + kHostNameTag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + if (!SSL_SESSION_parse_string(&session, &ret->psk_identity, + kPSKIdentityTag) || + !SSL_SESSION_parse_u32(&session, &ret->ticket_lifetime_hint, + kTicketLifetimeHintTag, 0) || + !SSL_SESSION_parse_octet_string(&session, &ret->ticket, kTicketTag)) { + return nullptr; + } + + if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) { + CBS peer_sha256; + if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) || + !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) || + CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256), + sizeof(ret->peer_sha256)); + ret->peer_sha256_valid = true; + } else { + ret->peer_sha256_valid = false; + } + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->original_handshake_hash, + &ret->original_handshake_hash_len, + sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) || + !SSL_SESSION_parse_crypto_buffer(&session, + &ret->signed_cert_timestamp_list, + kSignedCertTimestampListTag, pool) || + !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response, + kOCSPResponseTag, pool)) { + return nullptr; + } + + int extended_master_secret; + if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret, + kExtendedMasterSecretTag, + 0 /* default to false */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->extended_master_secret = !!extended_master_secret; + + if (!SSL_SESSION_parse_u16(&session, &ret->group_id, kGroupIDTag, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS cert_chain; + CBS_init(&cert_chain, NULL, 0); + int has_cert_chain; + if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain, + kCertChainTag) || + (has_cert_chain && CBS_len(&cert_chain) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_cert_chain && !has_peer) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_peer || has_cert_chain) { + ret->certs.reset(sk_CRYPTO_BUFFER_new_null()); + if (ret->certs == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (has_peer) { + UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool)); + if (!buffer || + !PushToStack(ret->certs.get(), std::move(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + while (CBS_len(&cert_chain) > 0) { + CBS cert; + if (!CBS_get_any_asn1_element(&cert_chain, &cert, NULL, NULL) || + CBS_len(&cert) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&cert, pool)); + if (buffer == nullptr || + !PushToStack(ret->certs.get(), std::move(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + } + + CBS age_add; + int age_add_present; + if (!CBS_get_optional_asn1_octet_string(&session, &age_add, &age_add_present, + kTicketAgeAddTag) || + (age_add_present && + !CBS_get_u32(&age_add, &ret->ticket_age_add)) || + CBS_len(&age_add) != 0) { + return nullptr; + } + ret->ticket_age_add_valid = age_add_present != 0; + + int is_server; + if (!CBS_get_optional_asn1_bool(&session, &is_server, kIsServerTag, + 1 /* default to true */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + /* TODO: in time we can include |is_server| for servers too, then we can + enforce that client and server sessions are never mixed up. */ + + ret->is_server = is_server; + + int is_quic; + if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm, + kPeerSignatureAlgorithmTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data, + kTicketMaxEarlyDataTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag, + ret->timeout) || + !SSL_SESSION_parse_octet_string(&session, &ret->early_alpn, + kEarlyALPNTag) || + !CBS_get_optional_asn1_bool(&session, &is_quic, kIsQuicTag, + /*default_value=*/false) || + !SSL_SESSION_parse_octet_string(&session, &ret->quic_early_data_context, + kQuicEarlyDataContextTag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS settings; + int has_local_alps, has_peer_alps; + if (!CBS_get_optional_asn1_octet_string(&session, &settings, &has_local_alps, + kLocalALPSTag) || + !ret->local_application_settings.CopyFrom(settings) || + !CBS_get_optional_asn1_octet_string(&session, &settings, &has_peer_alps, + kPeerALPSTag) || + !ret->peer_application_settings.CopyFrom(settings) || + CBS_len(&session) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->is_quic = is_quic; + + // The two ALPS values and ALPN must be consistent. + if (has_local_alps != has_peer_alps || + (has_local_alps && ret->early_alpn.empty())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->has_application_settings = has_local_alps; + + if (!x509_method->session_cache_objects(ret.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + return ret; +} + +int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { + return SSL_SESSION_to_bytes_full(in, cbb, 0); +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + if (in->not_resumable) { + // If the caller has an unresumable session, e.g. if |SSL_get_session| were + // called on a TLS 1.3 or False Started connection, serialize with a + // placeholder value so it is not accidentally deserialized into a resumable + // one. + static const char kNotResumableSession[] = "NOT RESUMABLE"; + + *out_len = strlen(kNotResumableSession); + *out_data = (uint8_t *)OPENSSL_memdup(kNotResumableSession, *out_len); + if (*out_data == NULL) { + return 0; + } + + return 1; + } + + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 0) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 1) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) { + uint8_t *out; + size_t len; + + if (!SSL_SESSION_to_bytes(in, &out, &len)) { + return -1; + } + + if (len > INT_MAX) { + OPENSSL_free(out); + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + if (pp) { + OPENSSL_memcpy(*pp, out, len); + *pp += len; + } + OPENSSL_free(out); + + return len; +} + +SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len, + const SSL_CTX *ctx) { + CBS cbs; + CBS_init(&cbs, in, in_len); + UniquePtr ret = + SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool); + if (!ret) { + return NULL; + } + if (CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return NULL; + } + return ret.release(); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_buffer.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_buffer.cc new file mode 100644 index 00000000..f321241a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_buffer.cc @@ -0,0 +1,306 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will +// not overflow. +static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int"); + +static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0, + "SSL3_ALIGN_PAYLOAD must be a power of 2"); + +void SSLBuffer::Clear() { + if (buf_allocated_) { + free(buf_); // Allocated with malloc(). + } + buf_ = nullptr; + buf_allocated_ = false; + offset_ = 0; + size_ = 0; + cap_ = 0; +} + +bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + if (new_cap > 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (cap_ >= new_cap) { + return true; + } + + uint8_t *new_buf; + bool new_buf_allocated; + size_t new_offset; + if (new_cap <= sizeof(inline_buf_)) { + // This function is called twice per TLS record, first for the five-byte + // header. To avoid allocating twice, use an inline buffer for short inputs. + new_buf = inline_buf_; + new_buf_allocated = false; + new_offset = 0; + } else { + // Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. + // + // Since this buffer gets allocated quite frequently and doesn't contain any + // sensitive data, we allocate with malloc rather than |OPENSSL_malloc| and + // avoid zeroing on free. + new_buf = (uint8_t *)malloc(new_cap + SSL3_ALIGN_PAYLOAD - 1); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + new_buf_allocated = true; + + // Offset the buffer such that the record body is aligned. + new_offset = + (0 - header_len - (uintptr_t)new_buf) & (SSL3_ALIGN_PAYLOAD - 1); + } + + // Note if the both old and new buffer are inline, the source and destination + // may alias. + OPENSSL_memmove(new_buf + new_offset, buf_ + offset_, size_); + + if (buf_allocated_) { + free(buf_); // Allocated with malloc(). + } + + buf_ = new_buf; + buf_allocated_ = new_buf_allocated; + offset_ = new_offset; + cap_ = new_cap; + return true; +} + +void SSLBuffer::DidWrite(size_t new_size) { + if (new_size > cap() - size()) { + abort(); + } + size_ += new_size; +} + +void SSLBuffer::Consume(size_t len) { + if (len > size_) { + abort(); + } + offset_ += (uint16_t)len; + size_ -= (uint16_t)len; + cap_ -= (uint16_t)len; +} + +void SSLBuffer::DiscardConsumed() { + if (size_ == 0) { + Clear(); + } +} + +static int dtls_read_buffer_next_packet(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (!buf->empty()) { + // It is an error to call |dtls_read_buffer_extend| when the read buffer is + // not empty. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // Read a single packet from |ssl->rbio|. |buf->cap()| must fit in an int. + int ret = + BIO_read(ssl->rbio.get(), buf->data(), static_cast(buf->cap())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_READ; + return ret; + } + buf->DidWrite(static_cast(ret)); + return 1; +} + +static int tls_read_buffer_extend_to(SSL *ssl, size_t len) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (len > buf->cap()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return -1; + } + + // Read until the target length is reached. + while (buf->size() < len) { + // The amount of data to read is bounded by |buf->cap|, which must fit in an + // int. + int ret = BIO_read(ssl->rbio.get(), buf->data() + buf->size(), + static_cast(len - buf->size())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_READ; + return ret; + } + buf->DidWrite(static_cast(ret)); + } + + return 1; +} + +int ssl_read_buffer_extend_to(SSL *ssl, size_t len) { + // |ssl_read_buffer_extend_to| implicitly discards any consumed data. + ssl->s3->read_buffer.DiscardConsumed(); + + if (SSL_is_dtls(ssl)) { + static_assert( + DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= 0xffff, + "DTLS read buffer is too large"); + + // The |len| parameter is ignored in DTLS. + len = DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + } + + if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), len)) { + return -1; + } + + if (ssl->rbio == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + int ret; + if (SSL_is_dtls(ssl)) { + // |len| is ignored for a datagram transport. + ret = dtls_read_buffer_next_packet(ssl); + } else { + ret = tls_read_buffer_extend_to(ssl, len); + } + + if (ret <= 0) { + // If the buffer was empty originally and remained empty after attempting to + // extend it, release the buffer until the next attempt. + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert) { + *out_retry = false; + if (ret != ssl_open_record_partial) { + ssl->s3->read_buffer.Consume(consumed); + } + if (ret != ssl_open_record_success) { + // Nothing was returned to the caller, so discard anything marked consumed. + ssl->s3->read_buffer.DiscardConsumed(); + } + switch (ret) { + case ssl_open_record_success: + return 1; + + case ssl_open_record_partial: { + int read_ret = ssl_read_buffer_extend_to(ssl, consumed); + if (read_ret <= 0) { + return read_ret; + } + *out_retry = true; + return 1; + } + + case ssl_open_record_discard: + *out_retry = true; + return 1; + + case ssl_open_record_close_notify: + return 0; + + case ssl_open_record_error: + if (alert != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + return -1; + } + assert(0); + return -1; +} + + +static_assert(SSL3_RT_HEADER_LENGTH * 2 + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum TLS write buffer is too large"); + +static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum DTLS write buffer is too large"); + +static int tls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + + while (!buf->empty()) { + int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + return ret; + } + buf->Consume(static_cast(ret)); + } + buf->Clear(); + return 1; +} + +static int dtls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + if (buf->empty()) { + return 1; + } + + int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_ERROR_WANT_WRITE; + // If the write failed, drop the write buffer anyway. Datagram transports + // can't write half a packet, so the caller is expected to retry from the + // top. + buf->Clear(); + return ret; + } + buf->Clear(); + return 1; +} + +int ssl_write_buffer_flush(SSL *ssl) { + if (ssl->wbio == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + if (SSL_is_dtls(ssl)) { + return dtls_write_buffer_flush(ssl); + } else { + return tls_write_buffer_flush(ssl); + } +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cert.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cert.cc new file mode 100644 index 00000000..db5477dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cert.cc @@ -0,0 +1,1014 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +CERT::CERT(const SSL_X509_METHOD *x509_method_arg) + : x509_method(x509_method_arg) {} + +CERT::~CERT() { + ssl_cert_clear_certs(this); + x509_method->cert_free(this); +} + +static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) { + CRYPTO_BUFFER_up_ref(buffer); + return buffer; +} + +UniquePtr ssl_cert_dup(CERT *cert) { + UniquePtr ret = MakeUnique(cert->x509_method); + if (!ret) { + return nullptr; + } + + if (cert->chain) { + ret->chain.reset(sk_CRYPTO_BUFFER_deep_copy( + cert->chain.get(), buffer_up_ref, CRYPTO_BUFFER_free)); + if (!ret->chain) { + return nullptr; + } + } + + ret->privatekey = UpRef(cert->privatekey); + ret->key_method = cert->key_method; + + if (!ret->sigalgs.CopyFrom(cert->sigalgs)) { + return nullptr; + } + + ret->cert_cb = cert->cert_cb; + ret->cert_cb_arg = cert->cert_cb_arg; + + ret->x509_method->cert_dup(ret.get(), cert); + + ret->signed_cert_timestamp_list = UpRef(cert->signed_cert_timestamp_list); + ret->ocsp_response = UpRef(cert->ocsp_response); + + ret->sid_ctx_length = cert->sid_ctx_length; + OPENSSL_memcpy(ret->sid_ctx, cert->sid_ctx, sizeof(ret->sid_ctx)); + + if (cert->dc) { + ret->dc = cert->dc->Dup(); + if (!ret->dc) { + return nullptr; + } + } + + ret->dc_privatekey = UpRef(cert->dc_privatekey); + ret->dc_key_method = cert->dc_key_method; + + return ret; +} + +// Free up and clear all certificates and chains +void ssl_cert_clear_certs(CERT *cert) { + if (cert == NULL) { + return; + } + + cert->x509_method->cert_clear(cert); + + cert->chain.reset(); + cert->privatekey.reset(); + cert->key_method = nullptr; + + cert->dc.reset(); + cert->dc_privatekey.reset(); + cert->dc_key_method = nullptr; +} + +static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg), + void *arg) { + cert->cert_cb = cb; + cert->cert_cb_arg = arg; +} + +enum leaf_cert_and_privkey_result_t { + leaf_cert_and_privkey_error, + leaf_cert_and_privkey_ok, + leaf_cert_and_privkey_mismatch, +}; + +// check_leaf_cert_and_privkey checks whether the certificate in |leaf_buffer| +// and the private key in |privkey| are suitable and coherent. It returns +// |leaf_cert_and_privkey_error| and pushes to the error queue if a problem is +// found. If the certificate and private key are valid, but incoherent, it +// returns |leaf_cert_and_privkey_mismatch|. Otherwise it returns +// |leaf_cert_and_privkey_ok|. +static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey( + CRYPTO_BUFFER *leaf_buffer, EVP_PKEY *privkey) { + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(leaf_buffer, &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return leaf_cert_and_privkey_error; + } + + if (!ssl_is_key_type_supported(pubkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA + // certificates, so sanity-check the key usage extension. + if (pubkey->type == EVP_PKEY_EC && + !ssl_cert_check_key_usage(&cert_cbs, key_usage_digital_signature)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + if (privkey != NULL && + // Sanity-check that the private key and the certificate match. + !ssl_compare_public_and_private_key(pubkey.get(), privkey)) { + ERR_clear_error(); + return leaf_cert_and_privkey_mismatch; + } + + return leaf_cert_and_privkey_ok; +} + +static int cert_set_chain_and_key( + CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { + if (num_certs == 0 || + (privkey == NULL && privkey_method == NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (privkey != NULL && privkey_method != NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); + return 0; + } + + switch (check_leaf_cert_and_privkey(certs[0], privkey)) { + case leaf_cert_and_privkey_error: + return 0; + case leaf_cert_and_privkey_mismatch: + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH); + return 0; + case leaf_cert_and_privkey_ok: + break; + } + + UniquePtr certs_sk(sk_CRYPTO_BUFFER_new_null()); + if (!certs_sk) { + return 0; + } + + for (size_t i = 0; i < num_certs; i++) { + if (!PushToStack(certs_sk.get(), UpRef(certs[i]))) { + return 0; + } + } + + cert->privatekey = UpRef(privkey); + cert->key_method = privkey_method; + + cert->chain = std::move(certs_sk); + return 1; +} + +bool ssl_set_cert(CERT *cert, UniquePtr buffer) { + switch (check_leaf_cert_and_privkey(buffer.get(), cert->privatekey.get())) { + case leaf_cert_and_privkey_error: + return false; + case leaf_cert_and_privkey_mismatch: + // don't fail for a cert/key mismatch, just free current private key + // (when switching to a different cert & key, first this function should + // be used, then |ssl_set_pkey|. + cert->privatekey.reset(); + break; + case leaf_cert_and_privkey_ok: + break; + } + + cert->x509_method->cert_flush_cached_leaf(cert); + + if (cert->chain != nullptr) { + CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(cert->chain.get(), 0)); + sk_CRYPTO_BUFFER_set(cert->chain.get(), 0, buffer.release()); + return true; + } + + cert->chain.reset(sk_CRYPTO_BUFFER_new_null()); + if (cert->chain == nullptr) { + return false; + } + + if (!PushToStack(cert->chain.get(), std::move(buffer))) { + cert->chain.reset(); + return false; + } + + return true; +} + +bool ssl_has_certificate(const SSL_HANDSHAKE *hs) { + return hs->config->cert->chain != nullptr && + sk_CRYPTO_BUFFER_value(hs->config->cert->chain.get(), 0) != nullptr && + ssl_has_private_key(hs); +} + +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + out_chain->reset(); + out_pubkey->reset(); + + CBS certificate_list; + if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (CBS_len(&certificate_list) == 0) { + return true; + } + + UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); + if (!chain) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + UniquePtr pubkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + CBS_len(&certificate) == 0) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return false; + } + + if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) { + pubkey = ssl_cert_parse_pubkey(&certificate); + if (!pubkey) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Retain the hash of the leaf certificate if requested. + if (out_leaf_sha256 != NULL) { + SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, pool)); + if (!buf || + !PushToStack(chain.get(), std::move(buf))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + *out_chain = std::move(chain); + *out_pubkey = std::move(pubkey); + return true; +} + +bool ssl_add_cert_chain(SSL_HANDSHAKE *hs, CBB *cbb) { + if (!ssl_has_certificate(hs)) { + return CBB_add_u24(cbb, 0); + } + + CBB certs; + if (!CBB_add_u24_length_prefixed(cbb, &certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + STACK_OF(CRYPTO_BUFFER) *chain = hs->config->cert->chain.get(); + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(chain); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(chain, i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certs, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer)) || + !CBB_flush(&certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + return CBB_flush(cbb); +} + +// ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and +// positions |*out_tbs_cert| to cover the TBSCertificate, starting at the +// subjectPublicKeyInfo. +static bool ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) { + /* From RFC 5280, section 4.1 + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + + * TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * ... } */ + CBS buf = *in; + + CBS toplevel; + if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) || + CBS_len(&buf) != 0 || + !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) || + // version + !CBS_get_optional_asn1( + out_tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // serialNumber + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) || + // signature algorithm + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuer + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // validity + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // subject + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) { + return false; + } + + return true; +} + +UniquePtr ssl_cert_parse_pubkey(const CBS *in) { + CBS buf = *in, tbs_cert; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return nullptr; + } + + return UniquePtr(EVP_parse_public_key(&tbs_cert)); +} + +bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey) { + if (EVP_PKEY_is_opaque(privkey)) { + // We cannot check an opaque private key and have to trust that it + // matches. + return true; + } + + switch (EVP_PKEY_cmp(pubkey, privkey)) { + case 1: + return true; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + return false; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + return false; + case -2: + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + return false; + } + + assert(0); + return false; +} + +bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey) { + if (privkey == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return false; + } + + if (cert->chain == nullptr || + sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); + return false; + } + + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain.get(), 0), + &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + return false; + } + + return ssl_compare_public_and_private_key(pubkey.get(), privkey); +} + +bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) { + CBS buf = *in; + + CBS tbs_cert, outer_extensions; + int has_extensions; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) || + // subjectPublicKeyInfo + !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuerUniqueID + !CBS_get_optional_asn1(&tbs_cert, NULL, NULL, + CBS_ASN1_CONTEXT_SPECIFIC | 1) || + // subjectUniqueID + !CBS_get_optional_asn1(&tbs_cert, NULL, NULL, + CBS_ASN1_CONTEXT_SPECIFIC | 2) || + !CBS_get_optional_asn1( + &tbs_cert, &outer_extensions, &has_extensions, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return false; + } + + if (!has_extensions) { + return true; + } + + CBS extensions; + if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return false; + } + + while (CBS_len(&extensions) > 0) { + CBS extension, oid, contents; + if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) || + (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) && + !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) || + !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) || + CBS_len(&extension) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return false; + } + + static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f}; + if (CBS_len(&oid) != sizeof(kKeyUsageOID) || + OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) != + 0) { + continue; + } + + CBS bit_string; + if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) || + CBS_len(&contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return false; + } + + // This is the KeyUsage extension. See + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + if (!CBS_is_valid_asn1_bitstring(&bit_string)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return false; + } + + if (!CBS_asn1_bitstring_has_bit(&bit_string, bit)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_KEY_USAGE_BIT_INCORRECT); + return false; + } + + return true; + } + + // No KeyUsage extension found. + return true; +} + +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs) { + CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool; + + UniquePtr ret(sk_CRYPTO_BUFFER_new_null()); + if (!ret) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + CBS child; + if (!CBS_get_u16_length_prefixed(cbs, &child)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); + return nullptr; + } + + while (CBS_len(&child) > 0) { + CBS distinguished_name; + if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG); + return nullptr; + } + + UniquePtr buffer( + CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool)); + if (!buffer || + !PushToStack(ret.get(), std::move(buffer))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + if (!ssl->ctx->x509_method->check_client_CA_list(ret.get())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + return ret; +} + +bool ssl_has_client_CAs(const SSL_CONFIG *cfg) { + const STACK_OF(CRYPTO_BUFFER) *names = cfg->client_CA.get(); + if (names == nullptr) { + names = cfg->ssl->ctx->client_CA.get(); + } + if (names == nullptr) { + return false; + } + return sk_CRYPTO_BUFFER_num(names) > 0; +} + +bool ssl_add_client_CA_list(SSL_HANDSHAKE *hs, CBB *cbb) { + CBB child, name_cbb; + if (!CBB_add_u16_length_prefixed(cbb, &child)) { + return false; + } + + const STACK_OF(CRYPTO_BUFFER) *names = hs->config->client_CA.get(); + if (names == NULL) { + names = hs->ssl->ctx->client_CA.get(); + } + if (names == NULL) { + return CBB_flush(cbb); + } + + for (const CRYPTO_BUFFER *name : names) { + if (!CBB_add_u16_length_prefixed(&child, &name_cbb) || + !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name), + CRYPTO_BUFFER_len(name))) { + return false; + } + } + + return CBB_flush(cbb); +} + +bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf) { + assert(ssl_protocol_version(hs->ssl) < TLS1_3_VERSION); + + // Check the certificate's type matches the cipher. + if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE); + return false; + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + // Check the key's group and point format are acceptable. + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + uint16_t group_id; + if (!ssl_nid_to_group_id( + &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) || + !tls1_check_group_id(hs, group_id) || + EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); + return false; + } + } + + return true; +} + +bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!ssl_has_certificate(hs)) { + // Nothing to do. + return true; + } + + if (!ssl->ctx->x509_method->ssl_auto_chain_if_needed(hs)) { + return false; + } + + CBS leaf; + CRYPTO_BUFFER_init_CBS( + sk_CRYPTO_BUFFER_value(hs->config->cert->chain.get(), 0), &leaf); + + if (ssl_signing_with_dc(hs)) { + hs->local_pubkey = UpRef(hs->config->cert->dc->pkey); + } else { + hs->local_pubkey = ssl_cert_parse_pubkey(&leaf); + } + return hs->local_pubkey != NULL; +} + + +// Delegated credentials. + +DC::DC() = default; +DC::~DC() = default; + +UniquePtr DC::Dup() { + bssl::UniquePtr ret = MakeUnique(); + if (!ret) { + return nullptr; + } + + ret->raw = UpRef(raw); + ret->expected_cert_verify_algorithm = expected_cert_verify_algorithm; + ret->pkey = UpRef(pkey); + return ret; +} + +// static +UniquePtr DC::Parse(CRYPTO_BUFFER *in, uint8_t *out_alert) { + UniquePtr dc = MakeUnique(); + if (!dc) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return nullptr; + } + + dc->raw = UpRef(in); + + CBS pubkey, deleg, sig; + uint32_t valid_time; + uint16_t algorithm; + CRYPTO_BUFFER_init_CBS(dc->raw.get(), &deleg); + if (!CBS_get_u32(&deleg, &valid_time) || + !CBS_get_u16(&deleg, &dc->expected_cert_verify_algorithm) || + !CBS_get_u24_length_prefixed(&deleg, &pubkey) || + !CBS_get_u16(&deleg, &algorithm) || + !CBS_get_u16_length_prefixed(&deleg, &sig) || + CBS_len(&deleg) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return nullptr; + } + + dc->pkey.reset(EVP_parse_public_key(&pubkey)); + if (dc->pkey == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return nullptr; + } + + return dc; +} + +// ssl_can_serve_dc returns true if the host has configured a DC that it can +// serve in the handshake. Specifically, it checks that a DC has been +// configured and that the DC signature algorithm is supported by the peer. +static bool ssl_can_serve_dc(const SSL_HANDSHAKE *hs) { + // Check that a DC has been configured. + const CERT *cert = hs->config->cert.get(); + if (cert->dc == nullptr || + cert->dc->raw == nullptr || + (cert->dc_privatekey == nullptr && cert->dc_key_method == nullptr)) { + return false; + } + + // Check that 1.3 or higher has been negotiated. + const DC *dc = cert->dc.get(); + assert(hs->ssl->s3->have_version); + if (ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) { + return false; + } + + // Check that the DC signature algorithm is supported by the peer. + Span peer_sigalgs = hs->peer_delegated_credential_sigalgs; + for (uint16_t peer_sigalg : peer_sigalgs) { + if (dc->expected_cert_verify_algorithm == peer_sigalg) { + return true; + } + } + return false; +} + +bool ssl_signing_with_dc(const SSL_HANDSHAKE *hs) { + // As of draft-ietf-tls-subcert-03, only the server may use delegated + // credentials to authenticate itself. + return hs->ssl->server && + hs->delegated_credential_requested && + ssl_can_serve_dc(hs); +} + +static int cert_set_dc(CERT *cert, CRYPTO_BUFFER *const raw, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *key_method) { + if (privkey == nullptr && key_method == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (privkey != nullptr && key_method != nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); + return 0; + } + + uint8_t alert; + UniquePtr dc = DC::Parse(raw, &alert); + if (dc == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_DELEGATED_CREDENTIAL); + return 0; + } + + if (privkey) { + // Check that the public and private keys match. + if (!ssl_compare_public_and_private_key(dc->pkey.get(), privkey)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH); + return 0; + } + } + + cert->dc = std::move(dc); + cert->dc_privatekey = UpRef(privkey); + cert->dc_key_method = key_method; + + return 1; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + if (!ssl->config) { + return 0; + } + return cert_set_chain_and_key(ssl->config->cert.get(), certs, num_certs, + privkey, privkey_method); +} + +int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ctx->cert.get(), certs, num_certs, privkey, + privkey_method); +} + +const STACK_OF(CRYPTO_BUFFER)* SSL_CTX_get0_chain(const SSL_CTX *ctx) { + return ctx->cert->chain.get(); +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer) { + return 0; + } + + return ssl_set_cert(ctx->cert.get(), std::move(buffer)); +} + +int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer || !ssl->config) { + return 0; + } + + return ssl_set_cert(ssl->config->cert.get(), std::move(buffer)); +} + +void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg), + void *arg) { + ssl_cert_set_cert_cb(ctx->cert.get(), cb, arg); +} + +void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { + if (!ssl->config) { + return; + } + ssl_cert_set_cert_cb(ssl->config->cert.get(), cb, arg); +} + +const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->certs.get(); +} + +const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return NULL; + } + return ssl->s3->hs->ca_names.get(); +} + +static int set_signed_cert_timestamp_list(CERT *cert, const uint8_t *list, + size_t list_len) { + CBS sct_list; + CBS_init(&sct_list, list, list_len); + if (!ssl_is_sct_list_valid(&sct_list)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SCT_LIST); + return 0; + } + + cert->signed_cert_timestamp_list.reset( + CRYPTO_BUFFER_new(CBS_data(&sct_list), CBS_len(&sct_list), nullptr)); + return cert->signed_cert_timestamp_list != nullptr; +} + +int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list, + size_t list_len) { + return set_signed_cert_timestamp_list(ctx->cert.get(), list, list_len); +} + +int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list, + size_t list_len) { + if (!ssl->config) { + return 0; + } + return set_signed_cert_timestamp_list(ssl->config->cert.get(), list, + list_len); +} + +int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response, + size_t response_len) { + ctx->cert->ocsp_response.reset( + CRYPTO_BUFFER_new(response, response_len, nullptr)); + return ctx->cert->ocsp_response != nullptr; +} + +int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response, + size_t response_len) { + if (!ssl->config) { + return 0; + } + ssl->config->cert->ocsp_response.reset( + CRYPTO_BUFFER_new(response, response_len, nullptr)); + return ssl->config->cert->ocsp_response != nullptr; +} + +void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) { + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + ctx->client_CA.reset(name_list); +} + +void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) { + if (!ssl->config) { + return; + } + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get()); + ssl->config->client_CA.reset(name_list); +} + +int SSL_set1_delegated_credential(SSL *ssl, CRYPTO_BUFFER *dc, EVP_PKEY *pkey, + const SSL_PRIVATE_KEY_METHOD *key_method) { + if (!ssl->config) { + return 0; + } + + return cert_set_dc(ssl->config->cert.get(), dc, pkey, key_method); +} + +int SSL_delegated_credential_used(const SSL *ssl) { + return ssl->s3->delegated_credential_used; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc new file mode 100644 index 00000000..8057042c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_cipher.cc @@ -0,0 +1,1716 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +static constexpr SSL_CIPHER kCiphers[] = { + // The RSA ciphers + // Cipher 02 + { + SSL3_TXT_RSA_NULL_SHA, + "TLS_RSA_WITH_NULL_SHA", + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 0A + { + SSL3_TXT_RSA_DES_192_CBC3_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // New AES ciphersuites + + // Cipher 2F + { + TLS1_TXT_RSA_WITH_AES_128_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 35 + { + TLS1_TXT_RSA_WITH_AES_256_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // PSK cipher suites. + + // Cipher 8C + { + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + "TLS_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 8D + { + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + "TLS_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // GCM ciphersuites from RFC 5288 + + // Cipher 9C + { + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 9D + { + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + "TLS_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // TLS 1.3 suites. + + // Cipher 1301 + { + TLS1_TXT_AES_128_GCM_SHA256, + "TLS_AES_128_GCM_SHA256", + TLS1_CK_AES_128_GCM_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 1302 + { + TLS1_TXT_AES_256_GCM_SHA384, + "TLS_AES_256_GCM_SHA384", + TLS1_CK_AES_256_GCM_SHA384, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher 1303 + { + TLS1_TXT_CHACHA20_POLY1305_SHA256, + "TLS_CHACHA20_POLY1305_SHA256", + TLS1_CK_CHACHA20_POLY1305_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C009 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C00A + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C013 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C014 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // GCM based TLS v1.2 ciphersuites from RFC 5289 + + // Cipher C02B + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C02C + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher C02F + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C030 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // ECDHE-PSK cipher suites. + + // Cipher C035 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C036 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // ChaCha20-Poly1305 cipher suites. + + // Cipher CCA8 + { + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCA9 + { + TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCAB + { + TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aPSK, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + +}; + +Span AllCiphers() { + return MakeConstSpan(kCiphers, OPENSSL_ARRAY_SIZE(kCiphers)); +} + +#define CIPHER_ADD 1 +#define CIPHER_KILL 2 +#define CIPHER_DEL 3 +#define CIPHER_ORD 4 +#define CIPHER_SPECIAL 5 + +typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + bool active; + bool in_group; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +typedef struct cipher_alias_st { + // name is the name of the cipher alias. + const char *name; + + // The following fields are bitmasks for the corresponding fields on + // |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the + // bit corresponding to the cipher's value is set to 1. If any bitmask is + // all zeroes, the alias matches nothing. Use |~0u| for the default value. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + + // min_version, if non-zero, matches all ciphers which were added in that + // particular protocol version. + uint16_t min_version; +} CIPHER_ALIAS; + +static const CIPHER_ALIAS kCipherAliases[] = { + // "ALL" doesn't include eNULL. It must be explicitly enabled. + {"ALL", ~0u, ~0u, ~0u, ~0u, 0}, + + // The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. + + // key exchange aliases + // (some of those using only a single bit here combine + // multiple key exchange algs according to the RFCs. + {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0}, + + {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + + {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0}, + + // server authentication aliases + {"aRSA", ~0u, SSL_aRSA, ~0u, ~0u, 0}, + {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0}, + + // aliases combining key exchange and server authentication + {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"RSA", SSL_kRSA, SSL_aRSA, ~0u, ~0u, 0}, + {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0}, + + // symmetric encryption aliases + {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0}, + {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0}, + {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0}, + {"AES", ~0u, ~0u, SSL_AES, ~0u, 0}, + {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0}, + {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0}, + + // MAC aliases + {"SHA1", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + {"SHA", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + + // Legacy protocol minimum version aliases. "TLSv1" is intentionally the + // same as "SSLv3". + {"SSLv3", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1.2", ~0u, ~0u, ~0u, ~0u, TLS1_2_VERSION}, + + // Legacy strength classes. + {"HIGH", ~0u, ~0u, ~0u, ~0u, 0}, + {"FIPS", ~0u, ~0u, ~0u, ~0u, 0}, + + // Temporary no-op aliases corresponding to removed SHA-2 legacy CBC + // ciphers. These should be removed after 2018-05-14. + {"SHA256", 0, 0, 0, 0, 0}, + {"SHA384", 0, 0, 0, 0, 0}, +}; + +static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases); + +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, bool is_dtls) { + *out_aead = NULL; + *out_mac_secret_len = 0; + *out_fixed_iv_len = 0; + + const bool is_tls12 = version == TLS1_2_VERSION && !is_dtls; + const bool is_tls13 = version == TLS1_3_VERSION && !is_dtls; + + if (cipher->algorithm_mac == SSL_AEAD) { + if (cipher->algorithm_enc == SSL_AES128GCM) { + if (is_tls12) { + *out_aead = EVP_aead_aes_128_gcm_tls12(); + } else if (is_tls13) { + *out_aead = EVP_aead_aes_128_gcm_tls13(); + } else { + *out_aead = EVP_aead_aes_128_gcm(); + } + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_AES256GCM) { + if (is_tls12) { + *out_aead = EVP_aead_aes_256_gcm_tls12(); + } else if (is_tls13) { + *out_aead = EVP_aead_aes_256_gcm_tls13(); + } else { + *out_aead = EVP_aead_aes_256_gcm(); + } + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) { + *out_aead = EVP_aead_chacha20_poly1305(); + *out_fixed_iv_len = 12; + } else { + return false; + } + + // In TLS 1.3, the iv_len is equal to the AEAD nonce length whereas the code + // above computes the TLS 1.2 construction. + if (version >= TLS1_3_VERSION) { + *out_fixed_iv_len = EVP_AEAD_nonce_length(*out_aead); + } + } else if (cipher->algorithm_mac == SSL_SHA1) { + if (cipher->algorithm_enc == SSL_eNULL) { + *out_aead = EVP_aead_null_sha1_tls(); + } else if (cipher->algorithm_enc == SSL_3DES) { + if (version == TLS1_VERSION) { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 8; + } else { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES128) { + if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES256) { + if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls(); + } + } else { + return false; + } + + *out_mac_secret_len = SHA_DIGEST_LENGTH; + } else { + return false; + } + + return true; +} + +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return version >= TLS1_2_VERSION ? EVP_sha256() : EVP_md5_sha1(); + case SSL_HANDSHAKE_MAC_SHA256: + return EVP_sha256(); + case SSL_HANDSHAKE_MAC_SHA384: + return EVP_sha384(); + default: + assert(0); + return NULL; + } +} + +static bool is_cipher_list_separator(char c, bool is_strict) { + if (c == ':') { + return true; + } + return !is_strict && (c == ' ' || c == ';' || c == ','); +} + +// rule_equals returns whether the NUL-terminated string |rule| is equal to the +// |buf_len| bytes at |buf|. +static bool rule_equals(const char *rule, const char *buf, size_t buf_len) { + // |strncmp| alone only checks that |buf| is a prefix of |rule|. + return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0'; +} + +static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) { + if (curr == *tail) { + return; + } + if (curr == *head) { + *head = curr->next; + } + if (curr->prev != NULL) { + curr->prev->next = curr->next; + } + if (curr->next != NULL) { + curr->next->prev = curr->prev; + } + (*tail)->next = curr; + curr->prev = *tail; + curr->next = NULL; + *tail = curr; +} + +static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) { + if (curr == *head) { + return; + } + if (curr == *tail) { + *tail = curr->prev; + } + if (curr->next != NULL) { + curr->next->prev = curr->prev; + } + if (curr->prev != NULL) { + curr->prev->next = curr->next; + } + (*head)->prev = curr; + curr->next = *head; + curr->prev = NULL; + *head = curr; +} + +static bool ssl_cipher_collect_ciphers(Array *out_co_list, + CIPHER_ORDER **out_head, + CIPHER_ORDER **out_tail) { + Array co_list; + if (!co_list.Init(OPENSSL_ARRAY_SIZE(kCiphers))) { + return false; + } + + size_t co_list_num = 0; + for (const SSL_CIPHER &cipher : kCiphers) { + // TLS 1.3 ciphers do not participate in this mechanism. + if (cipher.algorithm_mkey != SSL_kGENERIC) { + co_list[co_list_num].cipher = &cipher; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = false; + co_list[co_list_num].in_group = false; + co_list_num++; + } + } + + // Prepare linked list from list entries. + if (co_list_num > 0) { + co_list[0].prev = NULL; + + if (co_list_num > 1) { + co_list[0].next = &co_list[1]; + + for (size_t i = 1; i < co_list_num - 1; i++) { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *out_head = &co_list[0]; + *out_tail = &co_list[co_list_num - 1]; + } else { + *out_head = nullptr; + *out_tail = nullptr; + } + *out_co_list = std::move(co_list); + return true; +} + +SSLCipherPreferenceList::~SSLCipherPreferenceList() { + OPENSSL_free(in_group_flags); +} + +bool SSLCipherPreferenceList::Init(UniquePtr ciphers_arg, + Span in_group_flags_arg) { + if (sk_SSL_CIPHER_num(ciphers_arg.get()) != in_group_flags_arg.size()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + Array copy; + if (!copy.CopyFrom(in_group_flags_arg)) { + return false; + } + ciphers = std::move(ciphers_arg); + size_t unused_len; + copy.Release(&in_group_flags, &unused_len); + return true; +} + +bool SSLCipherPreferenceList::Init(const SSLCipherPreferenceList& other) { + size_t size = sk_SSL_CIPHER_num(other.ciphers.get()); + Span other_flags(other.in_group_flags, size); + UniquePtr other_ciphers(sk_SSL_CIPHER_dup( + other.ciphers.get())); + if (!other_ciphers) { + return false; + } + return Init(std::move(other_ciphers), other_flags); +} + +void SSLCipherPreferenceList::Remove(const SSL_CIPHER *cipher) { + size_t index; + if (!sk_SSL_CIPHER_find(ciphers.get(), &index, cipher)) { + return; + } + if (!in_group_flags[index] /* last element of group */ && index > 0) { + in_group_flags[index-1] = false; + } + for (size_t i = index; i < sk_SSL_CIPHER_num(ciphers.get()) - 1; ++i) { + in_group_flags[i] = in_group_flags[i+1]; + } + sk_SSL_CIPHER_delete(ciphers.get(), index); +} + +// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its +// parameters in the linked list from |*head_p| to |*tail_p|. It writes the new +// head and tail of the list to |*head_p| and |*tail_p|, respectively. +// +// - If |cipher_id| is non-zero, only that cipher is selected. +// - Otherwise, if |strength_bits| is non-negative, it selects ciphers +// of that strength. +// - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and +// |min_version|. +static void ssl_cipher_apply_rule( + uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, + uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule, + int strength_bits, bool in_group, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + bool reverse = false; + + if (cipher_id == 0 && strength_bits == -1 && min_version == 0 && + (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) { + // The rule matches nothing, so bail early. + return; + } + + if (rule == CIPHER_DEL) { + // needed to maintain sorting between currently deleted ciphers + reverse = true; + } + + head = *head_p; + tail = *tail_p; + + if (reverse) { + next = tail; + last = head; + } else { + next = head; + last = tail; + } + + curr = NULL; + for (;;) { + if (curr == last) { + break; + } + + curr = next; + if (curr == NULL) { + break; + } + + next = reverse ? curr->prev : curr->next; + cp = curr->cipher; + + // Selection criteria is either a specific cipher, the value of + // |strength_bits|, or the algorithms used. + if (cipher_id != 0) { + if (cipher_id != cp->id) { + continue; + } + } else if (strength_bits >= 0) { + if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) { + continue; + } + } else { + if (!(alg_mkey & cp->algorithm_mkey) || + !(alg_auth & cp->algorithm_auth) || + !(alg_enc & cp->algorithm_enc) || + !(alg_mac & cp->algorithm_mac) || + (min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version) || + // The NULL cipher must be selected explicitly. + cp->algorithm_enc == SSL_eNULL) { + continue; + } + } + + // add the cipher if it has not been added yet. + if (rule == CIPHER_ADD) { + // reverse == false + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = true; + curr->in_group = in_group; + } + } + + // Move the added cipher to this location + else if (rule == CIPHER_ORD) { + // reverse == false + if (curr->active) { + ll_append_tail(&head, curr, &tail); + curr->in_group = false; + } + } else if (rule == CIPHER_DEL) { + // reverse == true + if (curr->active) { + // most recently deleted ciphersuites get best positions + // for any future CIPHER_ADD (note that the CIPHER_DEL loop + // works in reverse to maintain the order) + ll_append_head(&head, curr, &tail); + curr->active = false; + curr->in_group = false; + } + } else if (rule == CIPHER_KILL) { + // reverse == false + if (head == curr) { + head = curr->next; + } else { + curr->prev->next = curr->next; + } + + if (tail == curr) { + tail = curr->prev; + } + curr->active = false; + if (curr->next != NULL) { + curr->next->prev = curr->prev; + } + if (curr->prev != NULL) { + curr->prev->next = curr->next; + } + curr->next = NULL; + curr->prev = NULL; + } + } + + *head_p = head; + *tail_p = tail; +} + +static bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + // This routine sorts the ciphers with descending strength. The sorting must + // keep the pre-sorted sequence, so we apply the normal sorting routine as + // '+' movement to the end of the list. + int max_strength_bits = 0; + CIPHER_ORDER *curr = *head_p; + while (curr != NULL) { + if (curr->active && + SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) { + max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL); + } + curr = curr->next; + } + + Array number_uses; + if (!number_uses.Init(max_strength_bits + 1)) { + return false; + } + OPENSSL_memset(number_uses.data(), 0, (max_strength_bits + 1) * sizeof(int)); + + // Now find the strength_bits values actually used. + curr = *head_p; + while (curr != NULL) { + if (curr->active) { + number_uses[SSL_CIPHER_get_bits(curr->cipher, NULL)]++; + } + curr = curr->next; + } + + // Go through the list of used strength_bits values in descending order. + for (int i = max_strength_bits; i >= 0; i--) { + if (number_uses[i] > 0) { + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p, + tail_p); + } + } + + return true; +} + +static bool ssl_cipher_process_rulestr(const char *rule_str, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, bool strict) { + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + uint16_t min_version; + const char *l, *buf; + int rule; + bool multi, skip_rule, in_group = false, has_group = false; + size_t j, buf_len; + uint32_t cipher_id; + char ch; + + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') { + break; // done + } + + if (in_group) { + if (ch == ']') { + if (*tail_p) { + (*tail_p)->in_group = false; + } + in_group = false; + l++; + continue; + } + + if (ch == '|') { + rule = CIPHER_ADD; + l++; + continue; + } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && + !(ch >= '0' && ch <= '9')) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); + return false; + } else { + rule = CIPHER_ADD; + } + } else if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; + } else if (ch == '[') { + assert(!in_group); + in_group = true; + has_group = true; + l++; + continue; + } else { + rule = CIPHER_ADD; + } + + // If preference groups are enabled, the only legal operator is +. + // Otherwise the in_group bits will get mixed up. + if (has_group && rule != CIPHER_ADD) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); + return false; + } + + if (is_cipher_list_separator(ch, strict)) { + l++; + continue; + } + + multi = false; + cipher_id = 0; + alg_mkey = ~0u; + alg_auth = ~0u; + alg_enc = ~0u; + alg_mac = ~0u; + min_version = 0; + skip_rule = false; + + for (;;) { + ch = *l; + buf = l; + buf_len = 0; + while ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '.' || ch == '_') { + ch = *(++l); + buf_len++; + } + + if (buf_len == 0) { + // We hit something we cannot deal with, it is no command or separator + // nor alphanumeric, so we call this an error. + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + if (rule == CIPHER_SPECIAL) { + break; + } + + // Look for a matching exact cipher. These aren't allowed in multipart + // rules. + if (!multi && ch != '+') { + for (j = 0; j < OPENSSL_ARRAY_SIZE(kCiphers); j++) { + const SSL_CIPHER *cipher = &kCiphers[j]; + if (rule_equals(cipher->name, buf, buf_len) || + rule_equals(cipher->standard_name, buf, buf_len)) { + cipher_id = cipher->id; + break; + } + } + } + if (cipher_id == 0) { + // If not an exact cipher, look for a matching cipher alias. + for (j = 0; j < kCipherAliasesLen; j++) { + if (rule_equals(kCipherAliases[j].name, buf, buf_len)) { + alg_mkey &= kCipherAliases[j].algorithm_mkey; + alg_auth &= kCipherAliases[j].algorithm_auth; + alg_enc &= kCipherAliases[j].algorithm_enc; + alg_mac &= kCipherAliases[j].algorithm_mac; + + if (min_version != 0 && + min_version != kCipherAliases[j].min_version) { + skip_rule = true; + } else { + min_version = kCipherAliases[j].min_version; + } + break; + } + } + if (j == kCipherAliasesLen) { + skip_rule = true; + if (strict) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + } + } + + // Check for a multipart rule. + if (ch != '+') { + break; + } + l++; + multi = true; + } + + // Ok, we have the rule, now apply it. + if (rule == CIPHER_SPECIAL) { + if (buf_len != 8 || strncmp(buf, "STRENGTH", 8) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + if (!ssl_cipher_strength_sort(head_p, tail_p)) { + return false; + } + + // We do not support any "multi" options together with "@", so throw away + // the rest of the command, if any left, until end or ':' is found. + while (*l != '\0' && !is_cipher_list_separator(*l, strict)) { + l++; + } + } else if (!skip_rule) { + ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, + min_version, rule, -1, in_group, head_p, tail_p); + } + } + + if (in_group) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + return true; +} + +bool ssl_create_cipher_list(UniquePtr *out_cipher_list, + const char *rule_str, bool strict) { + // Return with error if nothing to do. + if (rule_str == NULL || out_cipher_list == NULL) { + return false; + } + + // Now we have to collect the available ciphers from the compiled in ciphers. + // We cannot get more than the number compiled in, so it is used for + // allocation. + Array co_list; + CIPHER_ORDER *head = nullptr, *tail = nullptr; + if (!ssl_cipher_collect_ciphers(&co_list, &head, &tail)) { + return false; + } + + // Now arrange all ciphers by preference: + // TODO(davidben): Compute this order once and copy it. + + // Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other + // key exchange mechanisms + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // Order the bulk ciphers. First the preferred AEAD ciphers. We prefer + // CHACHA20 unless there is hardware support for fast and constant-time + // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the + // old one. + if (EVP_has_aes_hardware()) { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + } else { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + } + + // Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC, + // 3DES_EDE_CBC_SHA. + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + + // Temporarily enable everything else for sorting + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head, + &tail); + + // Move ciphers without forward secrecy to the end. + ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD, + -1, false, &head, &tail); + + // Now disable everything (maintaining the ordering!) + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // If the rule_string begins with DEFAULT, apply the default rule before + // using the (possibly available) additional rules. + const char *rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + if (!ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, &head, &tail, + strict)) { + return false; + } + rule_p += 7; + if (*rule_p == ':') { + rule_p++; + } + } + + if (*rule_p != '\0' && + !ssl_cipher_process_rulestr(rule_p, &head, &tail, strict)) { + return false; + } + + // Allocate new "cipherstack" for the result, return with error + // if we cannot get one. + UniquePtr cipherstack(sk_SSL_CIPHER_new_null()); + Array in_group_flags; + if (cipherstack == nullptr || + !in_group_flags.Init(OPENSSL_ARRAY_SIZE(kCiphers))) { + return false; + } + + // The cipher selection for the list is done. The ciphers are added + // to the resulting precedence to the STACK_OF(SSL_CIPHER). + size_t num_in_group_flags = 0; + for (CIPHER_ORDER *curr = head; curr != NULL; curr = curr->next) { + if (curr->active) { + if (!sk_SSL_CIPHER_push(cipherstack.get(), curr->cipher)) { + return false; + } + in_group_flags[num_in_group_flags++] = curr->in_group; + } + } + + UniquePtr pref_list = + MakeUnique(); + if (!pref_list || + !pref_list->Init( + std::move(cipherstack), + MakeConstSpan(in_group_flags).subspan(0, num_in_group_flags))) { + return false; + } + + *out_cipher_list = std::move(pref_list); + + // Configuring an empty cipher list is an error but still updates the + // output. + if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers.get()) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH); + return false; + } + + return true; +} + +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) { + switch (EVP_PKEY_id(key)) { + case EVP_PKEY_RSA: + return SSL_aRSA; + case EVP_PKEY_EC: + case EVP_PKEY_ED25519: + // Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers. + return SSL_aECDSA; + default: + return 0; + } +} + +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) { + return (cipher->algorithm_auth & SSL_aCERT) != 0; +} + +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) { + // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. It is + // optional or omitted in all others. + return (cipher->algorithm_mkey & SSL_kECDHE) != 0; +} + +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { + size_t block_size; + switch (cipher->algorithm_enc) { + case SSL_3DES: + block_size = 8; + break; + case SSL_AES128: + case SSL_AES256: + block_size = 16; + break; + default: + return 0; + } + + // All supported TLS 1.0 ciphers use SHA-1. + assert(cipher->algorithm_mac == SSL_SHA1); + size_t ret = 1 + SHA_DIGEST_LENGTH; + ret += block_size - (ret % block_size); + return ret; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +static constexpr int ssl_cipher_id_cmp(const SSL_CIPHER *a, + const SSL_CIPHER *b) { + if (a->id > b->id) { + return 1; + } + if (a->id < b->id) { + return -1; + } + return 0; +} + +static int ssl_cipher_id_cmp_void(const void *in_a, const void *in_b) { + return ssl_cipher_id_cmp(reinterpret_cast(in_a), + reinterpret_cast(in_b)); +} + +template +static constexpr bool ssl_ciphers_sorted(const SSL_CIPHER (&ciphers)[N]) { + for (size_t i = 1; i < N; i++) { + if (ssl_cipher_id_cmp(&ciphers[i - 1], &ciphers[i]) >= 0) { + return false; + } + } + return true; +} + +static_assert(ssl_ciphers_sorted(kCiphers), + "Ciphers are not sorted, bsearch won't work"); + +const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { + SSL_CIPHER c; + + c.id = 0x03000000L | value; + return reinterpret_cast(bsearch( + &c, kCiphers, OPENSSL_ARRAY_SIZE(kCiphers), sizeof(SSL_CIPHER), + ssl_cipher_id_cmp_void)); +} + +uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } + +uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *cipher) { + // All OpenSSL cipher IDs are prefaced with 0x03. Historically this referred + // to SSLv2 vs SSLv3. + assert((cipher->id & 0xff000000) == 0x03000000); + return static_cast(cipher->id); +} + +uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher) { + return SSL_CIPHER_get_protocol_id(cipher); +} + +int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher) { + return (cipher->algorithm_mac & SSL_AEAD) != 0; +} + +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_enc) { + case SSL_eNULL: + return NID_undef; + case SSL_3DES: + return NID_des_ede3_cbc; + case SSL_AES128: + return NID_aes_128_cbc; + case SSL_AES256: + return NID_aes_256_cbc; + case SSL_AES128GCM: + return NID_aes_128_gcm; + case SSL_AES256GCM: + return NID_aes_256_gcm; + case SSL_CHACHA20POLY1305: + return NID_chacha20_poly1305; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mac) { + case SSL_AEAD: + return NID_undef; + case SSL_SHA1: + return NID_sha1; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return NID_kx_rsa; + case SSL_kECDHE: + return NID_kx_ecdhe; + case SSL_kPSK: + return NID_kx_psk; + case SSL_kGENERIC: + return NID_kx_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_auth) { + case SSL_aRSA: + return NID_auth_rsa; + case SSL_aECDSA: + return NID_auth_ecdsa; + case SSL_aPSK: + return NID_auth_psk; + case SSL_aGENERIC: + return NID_auth_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return NID_md5_sha1; + case SSL_HANDSHAKE_MAC_SHA256: + return NID_sha256; + case SSL_HANDSHAKE_MAC_SHA384: + return NID_sha384; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) { + return (cipher->algorithm_enc & SSL_eNULL) == 0 && + cipher->algorithm_mac != SSL_AEAD; +} + +uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + + if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) { + // Cipher suites before TLS 1.2 use the default PRF, while all those added + // afterwards specify a particular hash. + return TLS1_2_VERSION; + } + return SSL3_VERSION; +} + +uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + return TLS1_2_VERSION; +} + +// return the actual cipher being used +const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) { + if (cipher != NULL) { + return cipher->name; + } + + return "(NONE)"; +} + +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher) { + return cipher->standard_name; +} + +const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return ""; + } + + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return "RSA"; + + case SSL_kECDHE: + switch (cipher->algorithm_auth) { + case SSL_aECDSA: + return "ECDHE_ECDSA"; + case SSL_aRSA: + return "ECDHE_RSA"; + case SSL_aPSK: + return "ECDHE_PSK"; + default: + assert(0); + return "UNKNOWN"; + } + + case SSL_kPSK: + assert(cipher->algorithm_auth == SSL_aPSK); + return "PSK"; + + case SSL_kGENERIC: + assert(cipher->algorithm_auth == SSL_aGENERIC); + return "GENERIC"; + + default: + assert(0); + return "UNKNOWN"; + } +} + +char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return NULL; + } + + return OPENSSL_strdup(SSL_CIPHER_standard_name(cipher)); +} + +int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { + if (cipher == NULL) { + return 0; + } + + int alg_bits, strength_bits; + switch (cipher->algorithm_enc) { + case SSL_AES128: + case SSL_AES128GCM: + alg_bits = 128; + strength_bits = 128; + break; + + case SSL_AES256: + case SSL_AES256GCM: + case SSL_CHACHA20POLY1305: + alg_bits = 256; + strength_bits = 256; + break; + + case SSL_3DES: + alg_bits = 168; + strength_bits = 112; + break; + + case SSL_eNULL: + alg_bits = 0; + strength_bits = 0; + break; + + default: + assert(0); + alg_bits = 0; + strength_bits = 0; + } + + if (out_alg_bits != NULL) { + *out_alg_bits = alg_bits; + } + return strength_bits; +} + +const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, + int len) { + const char *kx, *au, *enc, *mac; + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + + switch (alg_mkey) { + case SSL_kRSA: + kx = "RSA"; + break; + + case SSL_kECDHE: + kx = "ECDH"; + break; + + case SSL_kPSK: + kx = "PSK"; + break; + + case SSL_kGENERIC: + kx = "GENERIC"; + break; + + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + + case SSL_aECDSA: + au = "ECDSA"; + break; + + case SSL_aPSK: + au = "PSK"; + break; + + case SSL_aGENERIC: + au = "GENERIC"; + break; + + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_3DES: + enc = "3DES(168)"; + break; + + case SSL_AES128: + enc = "AES(128)"; + break; + + case SSL_AES256: + enc = "AES(256)"; + break; + + case SSL_AES128GCM: + enc = "AESGCM(128)"; + break; + + case SSL_AES256GCM: + enc = "AESGCM(256)"; + break; + + case SSL_CHACHA20POLY1305: + enc = "ChaCha20-Poly1305"; + break; + + case SSL_eNULL: + enc="None"; + break; + + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_SHA1: + mac = "SHA1"; + break; + + case SSL_AEAD: + mac = "AEAD"; + break; + + default: + mac = "unknown"; + break; + } + + if (buf == NULL) { + len = 128; + buf = (char *)OPENSSL_malloc(len); + if (buf == NULL) { + return NULL; + } + } else if (len < 128) { + return "Buffer too small"; + } + + BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", + cipher->name, kx, au, enc, mac); + return buf; +} + +const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) { + return "TLSv1/SSLv3"; +} + +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) { return NULL; } + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; } + +const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; } + +const char *SSL_COMP_get0_name(const SSL_COMP *comp) { return comp->name; } + +int SSL_COMP_get_id(const SSL_COMP *comp) { return comp->id; } + +void SSL_COMP_free_compression_methods(void) {} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_file.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_file.cc new file mode 100644 index 00000000..f14a1b53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_file.cc @@ -0,0 +1,585 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { + return X509_NAME_cmp(*a, *b); +} + +// TODO(davidben): Is there any reason this doesn't call +// |SSL_add_file_cert_subjects_to_stack|? +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + + sk = sk_X509_NAME_new(xname_cmp); + in = BIO_new(BIO_s_file()); + + if (sk == NULL || in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) { + goto err; + } + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + break; + } + if (ret == NULL) { + ret = sk_X509_NAME_new_null(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + sk_X509_NAME_sort(sk); + if (sk_X509_NAME_find(sk, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(sk /* non-owning */, xn) || + !sk_X509_NAME_push(ret /* owning */, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + if (false) { + err: + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + + sk_X509_NAME_free(sk); + BIO_free(in); + X509_free(x); + if (ret != NULL) { + ERR_clear_error(); + } + return ret; +} + +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *file) { + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + int ret = 0; + int (*oldcmp)(const X509_NAME **a, const X509_NAME **b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + in = BIO_new(BIO_s_file()); + + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) { + goto err; + } + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + break; + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + sk_X509_NAME_sort(stack); + if (sk_X509_NAME_find(stack, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(stack, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + ERR_clear_error(); + ret = 1; + +err: + BIO_free(in); + X509_free(x); + + (void) sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + +end: + X509_free(x); + BIO_free(in); + + return ret; +} + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = + PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + +end: + X509_free(x); + BIO_free(in); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +// Read a file that contains our certificate in "PEM" format, possibly followed +// by a sequence of CA certificates that should be sent to the peer in the +// Certificate message. +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { + BIO *in; + int ret = 0; + X509 *x = NULL; + + ERR_clear_error(); // clear error stack for SSL_CTX_use_certificate() + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + + if (ERR_peek_error() != 0) { + ret = 0; // Key/certificate mismatch doesn't imply ret==0 ... + } + + if (ret) { + // If we could set up our certificate, now proceed to the CA + // certificates. + X509 *ca; + int r; + uint32_t err; + + SSL_CTX_clear_chain_certs(ctx); + + while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata)) != + NULL) { + r = SSL_CTX_add0_chain_cert(ctx, ca); + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + // Note that we must not free r if it was successfully added to the chain + // (while we must free the main certificate, since its reference count is + // increased by SSL_CTX_use_certificate). + } + + // When the while loop ends, it's usually just EOF. + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && + ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + } else { + ret = 0; // some real error + } + } + +end: + X509_free(x); + BIO_free(in); + return ret; +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) { + ctx->default_passwd_callback = cb; +} + +pem_password_cb *SSL_CTX_get_default_passwd_cb(const SSL_CTX *ctx) { + return ctx->default_passwd_callback; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) { + ctx->default_passwd_callback_userdata = data; +} + +void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx) { + return ctx->default_passwd_callback_userdata; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc new file mode 100644 index 00000000..c4d76538 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_key_share.cc @@ -0,0 +1,400 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + +BSSL_NAMESPACE_BEGIN + +namespace { + +class ECKeyShare : public SSLKeyShare { + public: + ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {} + + uint16_t GroupID() const override { return group_id_; } + + bool Offer(CBB *out) override { + assert(!private_key_); + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + // Generate a private key. + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + private_key_.reset(BN_new()); + if (!group || !private_key_ || + !BN_rand_range_ex(private_key_.get(), 1, + EC_GROUP_get0_order(group.get()))) { + return false; + } + + // Compute the corresponding public key and serialize it. + UniquePtr public_key(EC_POINT_new(group.get())); + if (!public_key || + !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL, + NULL, bn_ctx.get()) || + !EC_POINT_point2cbb(out, group.get(), public_key.get(), + POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) { + return false; + } + + return true; + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + assert(private_key_); + *out_alert = SSL_AD_INTERNAL_ERROR; + + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + if (!group) { + return false; + } + + UniquePtr peer_point(EC_POINT_new(group.get())); + UniquePtr result(EC_POINT_new(group.get())); + BIGNUM *x = BN_CTX_get(bn_ctx.get()); + if (!peer_point || !result || !x) { + return false; + } + + if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED || + !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(), + peer_key.size(), bn_ctx.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Compute the x-coordinate of |peer_key| * |private_key_|. + if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(), + private_key_.get(), bn_ctx.get()) || + !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL, + bn_ctx.get())) { + return false; + } + + // Encode the x-coordinate left-padded with zeros. + Array secret; + if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) || + !BN_bn2bin_padded(secret.data(), secret.size(), x)) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + bool SerializePrivateKey(CBB *out) override { + assert(private_key_); + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + // Padding is added to avoid leaking the length. + size_t len = BN_num_bytes(EC_GROUP_get0_order(group.get())); + return BN_bn2cbb_padded(out, len, private_key_.get()); + } + + bool DeserializePrivateKey(CBS *in) override { + assert(!private_key_); + private_key_.reset(BN_bin2bn(CBS_data(in), CBS_len(in), nullptr)); + return private_key_ != nullptr; + } + + private: + UniquePtr private_key_; + int nid_; + uint16_t group_id_; +}; + +class X25519KeyShare : public SSLKeyShare { + public: + X25519KeyShare() {} + + uint16_t GroupID() const override { return SSL_CURVE_X25519; } + + bool Offer(CBB *out) override { + uint8_t public_key[32]; + X25519_keypair(public_key, private_key_); + return !!CBB_add_bytes(out, public_key, sizeof(public_key)); + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + *out_alert = SSL_AD_INTERNAL_ERROR; + + Array secret; + if (!secret.Init(32)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + if (peer_key.size() != 32 || + !X25519(secret.data(), private_key_, peer_key.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + *out_secret = std::move(secret); + return true; + } + + bool SerializePrivateKey(CBB *out) override { + return CBB_add_bytes(out, private_key_, sizeof(private_key_)); + } + + bool DeserializePrivateKey(CBS *in) override { + if (CBS_len(in) != sizeof(private_key_) || + !CBS_copy_bytes(in, private_key_, sizeof(private_key_))) { + return false; + } + return true; + } + + private: + uint8_t private_key_[32]; +}; + +class CECPQ2KeyShare : public SSLKeyShare { + public: + CECPQ2KeyShare() {} + + uint16_t GroupID() const override { return SSL_CURVE_CECPQ2; } + + bool Offer(CBB *out) override { + uint8_t x25519_public_key[32]; + X25519_keypair(x25519_public_key, x25519_private_key_); + + uint8_t hrss_entropy[HRSS_GENERATE_KEY_BYTES]; + HRSS_public_key hrss_public_key; + RAND_bytes(hrss_entropy, sizeof(hrss_entropy)); + if (!HRSS_generate_key(&hrss_public_key, &hrss_private_key_, + hrss_entropy)) { + return false; + } + + uint8_t hrss_public_key_bytes[HRSS_PUBLIC_KEY_BYTES]; + HRSS_marshal_public_key(hrss_public_key_bytes, &hrss_public_key); + + if (!CBB_add_bytes(out, x25519_public_key, sizeof(x25519_public_key)) || + !CBB_add_bytes(out, hrss_public_key_bytes, + sizeof(hrss_public_key_bytes))) { + return false; + } + + return true; + } + + bool Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + Array secret; + if (!secret.Init(32 + HRSS_KEY_BYTES)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + uint8_t x25519_public_key[32]; + X25519_keypair(x25519_public_key, x25519_private_key_); + + HRSS_public_key peer_public_key; + if (peer_key.size() != 32 + HRSS_PUBLIC_KEY_BYTES || + !HRSS_parse_public_key(&peer_public_key, peer_key.data() + 32) || + !X25519(secret.data(), x25519_private_key_, peer_key.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; + uint8_t entropy[HRSS_ENCAP_BYTES]; + RAND_bytes(entropy, sizeof(entropy)); + + if (!HRSS_encap(ciphertext, secret.data() + 32, &peer_public_key, + entropy) || + !CBB_add_bytes(out_public_key, x25519_public_key, + sizeof(x25519_public_key)) || + !CBB_add_bytes(out_public_key, ciphertext, sizeof(ciphertext))) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + *out_alert = SSL_AD_INTERNAL_ERROR; + + Array secret; + if (!secret.Init(32 + HRSS_KEY_BYTES)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + if (peer_key.size() != 32 + HRSS_CIPHERTEXT_BYTES || + !X25519(secret.data(), x25519_private_key_, peer_key.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + if (!HRSS_decap(secret.data() + 32, &hrss_private_key_, + peer_key.data() + 32, peer_key.size() - 32)) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + private: + uint8_t x25519_private_key_[32]; + HRSS_private_key hrss_private_key_; +}; + +constexpr NamedGroup kNamedGroups[] = { + {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"}, + {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"}, + {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1"}, + {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"}, + {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"}, + {NID_CECPQ2, SSL_CURVE_CECPQ2, "CECPQ2", "CECPQ2"}, +}; + +} // namespace + +Span NamedGroups() { + return MakeConstSpan(kNamedGroups, OPENSSL_ARRAY_SIZE(kNamedGroups)); +} + +UniquePtr SSLKeyShare::Create(uint16_t group_id) { + switch (group_id) { + case SSL_CURVE_SECP224R1: + return UniquePtr( + New(NID_secp224r1, SSL_CURVE_SECP224R1)); + case SSL_CURVE_SECP256R1: + return UniquePtr( + New(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1)); + case SSL_CURVE_SECP384R1: + return UniquePtr( + New(NID_secp384r1, SSL_CURVE_SECP384R1)); + case SSL_CURVE_SECP521R1: + return UniquePtr( + New(NID_secp521r1, SSL_CURVE_SECP521R1)); + case SSL_CURVE_X25519: + return UniquePtr(New()); + case SSL_CURVE_CECPQ2: + return UniquePtr(New()); + default: + return nullptr; + } +} + +UniquePtr SSLKeyShare::Create(CBS *in) { + uint64_t group; + CBS private_key; + if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff || + !CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) { + return nullptr; + } + UniquePtr key_share = Create(static_cast(group)); + if (!key_share || !key_share->DeserializePrivateKey(&private_key)) { + return nullptr; + } + return key_share; +} + +bool SSLKeyShare::Serialize(CBB *out) { + CBB private_key; + if (!CBB_add_asn1_uint64(out, GroupID()) || + !CBB_add_asn1(out, &private_key, CBS_ASN1_OCTETSTRING) || + !SerializePrivateKey(&private_key) || // + !CBB_flush(out)) { + return false; + } + return true; +} + +bool SSLKeyShare::Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return Offer(out_public_key) && + Finish(out_secret, out_alert, peer_key); +} + +bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { + for (const auto &group : kNamedGroups) { + if (group.nid == nid) { + *out_group_id = group.group_id; + return true; + } + } + return false; +} + +bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) { + for (const auto &group : kNamedGroups) { + if (len == strlen(group.name) && + !strncmp(group.name, name, len)) { + *out_group_id = group.group_id; + return true; + } + if (len == strlen(group.alias) && + !strncmp(group.alias, name, len)) { + *out_group_id = group.group_id; + return true; + } + } + return false; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +const char* SSL_get_curve_name(uint16_t group_id) { + for (const auto &group : kNamedGroups) { + if (group.group_id == group_id) { + return group.name; + } + } + return nullptr; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_lib.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_lib.cc new file mode 100644 index 00000000..8b8cb5dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_lib.cc @@ -0,0 +1,3072 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + +#if defined(OPENSSL_WINDOWS) +#include +#else +#include +#include +#endif + + +BSSL_NAMESPACE_BEGIN + +// |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it +// to avoid downstream churn. +OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) + +// The following errors are no longer emitted, but are used in nginx without +// #ifdefs. +OPENSSL_DECLARE_ERROR_REASON(SSL, BLOCK_CIPHER_PAD_IS_WRONG) +OPENSSL_DECLARE_ERROR_REASON(SSL, NO_CIPHERS_SPECIFIED) + +// Some error codes are special. Ensure the make_errors.go script never +// regresses this. +static_assert(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION == + SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET, + "alert reason code mismatch"); + +// kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. +static const size_t kMaxHandshakeSize = (1u << 24) - 1; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +bool CBBFinishArray(CBB *cbb, Array *out) { + uint8_t *ptr; + size_t len; + if (!CBB_finish(cbb, &ptr, &len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + out->Reset(ptr, len); + return true; +} + +void ssl_reset_error_state(SSL *ssl) { + // Functions which use |SSL_get_error| must reset I/O and error state on + // entry. + ssl->s3->rwstate = SSL_ERROR_NONE; + ERR_clear_error(); + ERR_clear_system_error(); +} + +void ssl_set_read_error(SSL* ssl) { + ssl->s3->read_shutdown = ssl_shutdown_error; + ssl->s3->read_error.reset(ERR_save_state()); +} + +static bool check_read_error(const SSL *ssl) { + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return false; + } + return true; +} + +bool ssl_can_write(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; +} + +bool ssl_can_read(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; +} + +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_handshake(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = + ssl->method->open_change_cipher_spec(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_app_data(ssl, out, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +static bool cbb_add_hex(CBB *cbb, Span in) { + static const char hextable[] = "0123456789abcdef"; + uint8_t *out; + + if (!CBB_add_space(cbb, &out, in.size() * 2)) { + return false; + } + + for (uint8_t b : in) { + *(out++) = (uint8_t)hextable[b >> 4]; + *(out++) = (uint8_t)hextable[b & 0xf]; + } + + return true; +} + +bool ssl_log_secret(const SSL *ssl, const char *label, + Span secret) { + if (ssl->ctx->keylog_callback == NULL) { + return true; + } + + ScopedCBB cbb; + Array line; + if (!CBB_init(cbb.get(), strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 + + secret.size() * 2 + 1) || + !CBB_add_bytes(cbb.get(), reinterpret_cast(label), + strlen(label)) || + !CBB_add_u8(cbb.get(), ' ') || + !cbb_add_hex(cbb.get(), ssl->s3->client_random) || + !CBB_add_u8(cbb.get(), ' ') || + !cbb_add_hex(cbb.get(), secret) || + !CBB_add_u8(cbb.get(), 0 /* NUL */) || + !CBBFinishArray(cbb.get(), &line)) { + return false; + } + + ssl->ctx->keylog_callback(ssl, reinterpret_cast(line.data())); + return true; +} + +void ssl_do_info_callback(const SSL *ssl, int type, int value) { + void (*cb)(const SSL *ssl, int type, int value) = NULL; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; + } + + if (cb != NULL) { + cb(ssl, type, value); + } +} + +void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type, + Span in) { + if (ssl->msg_callback == NULL) { + return; + } + + // |version| is zero when calling for |SSL3_RT_HEADER| and |SSL2_VERSION| for + // a V2ClientHello. + int version; + switch (content_type) { + case 0: + // V2ClientHello + version = SSL2_VERSION; + break; + case SSL3_RT_HEADER: + version = 0; + break; + default: + version = SSL_version(ssl); + } + + ssl->msg_callback(is_write, version, content_type, in.data(), in.size(), + const_cast(ssl), ssl->msg_callback_arg); +} + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) { + // TODO(martinkr): Change callers to |ssl_ctx_get_current_time| and drop the + // |ssl| arg from |current_time_cb| if possible. + ssl_ctx_get_current_time(ssl->ctx.get(), out_clock); +} + +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock) { + if (ctx->current_time_cb != NULL) { + // TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See + // https://crbug.com/boringssl/155. + struct timeval clock; + ctx->current_time_cb(nullptr /* ssl */, &clock); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } + return; + } + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + out_clock->tv_sec = 1234; + out_clock->tv_usec = 1234; +#elif defined(OPENSSL_WINDOWS) + struct _timeb time; + _ftime(&time); + if (time.time < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = time.time; + out_clock->tv_usec = time.millitm * 1000; + } +#else + struct timeval clock; + gettimeofday(&clock, NULL); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } +#endif +} + +void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on) { + ctx->handoff = on; +} + +static bool ssl_can_renegotiate(const SSL *ssl) { + if (ssl->server || SSL_is_dtls(ssl)) { + return false; + } + + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // The config has already been shed. + if (!ssl->config) { + return false; + } + + switch (ssl->renegotiate_mode) { + case ssl_renegotiate_ignore: + case ssl_renegotiate_never: + return false; + + case ssl_renegotiate_freely: + case ssl_renegotiate_explicit: + return true; + case ssl_renegotiate_once: + return ssl->s3->total_renegotiations == 0; + } + + assert(0); + return false; +} + +static void ssl_maybe_shed_handshake_config(SSL *ssl) { + if (ssl->s3->hs != nullptr || + ssl->config == nullptr || + !ssl->config->shed_handshake_config || + ssl_can_renegotiate(ssl)) { + return; + } + + ssl->config.reset(); +} + +void SSL_set_handoff_mode(SSL *ssl, bool on) { + if (!ssl->config) { + return; + } + ssl->config->handoff = on; +} + +bool SSL_get_traffic_secrets(const SSL *ssl, + Span *out_read_traffic_secret, + Span *out_write_traffic_secret) { + if (SSL_version(ssl) < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + return false; + } + + if (!ssl->s3->initial_handshake_complete) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return false; + } + + *out_read_traffic_secret = Span( + ssl->s3->read_traffic_secret, ssl->s3->read_traffic_secret_len); + *out_write_traffic_secret = Span( + ssl->s3->write_traffic_secret, ssl->s3->write_traffic_secret_len); + + return true; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_library_init(void) { + CRYPTO_library_init(); + return 1; +} + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} + +static uint32_t ssl_session_hash(const SSL_SESSION *sess) { + return ssl_hash_session_id( + MakeConstSpan(sess->session_id, sess->session_id_length)); +} + +static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) { + if (a->session_id_length != b->session_id_length) { + return 1; + } + + return OPENSSL_memcmp(a->session_id, b->session_id, a->session_id_length); +} + +ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method) + : method(ssl_method->method), + x509_method(ssl_method->x509_method), + retain_only_sha256_of_client_certs(false), + quiet_shutdown(false), + ocsp_stapling_enabled(false), + signed_cert_timestamps_enabled(false), + channel_id_enabled(false), + grease_enabled(false), + permute_extensions(false), + allow_unknown_alpn_protos(false), + false_start_allowed_without_alpn(false), + handoff(false), + enable_early_data(false) { + CRYPTO_MUTEX_init(&lock); + CRYPTO_new_ex_data(&ex_data); +} + +ssl_ctx_st::~ssl_ctx_st() { + // Free the internal session cache. Note that this calls the caller-supplied + // remove callback, so we must do it before clearing ex_data. (See ticket + // [openssl.org #212].) + SSL_CTX_flush_sessions(this, 0); + + CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, this, &ex_data); + + CRYPTO_MUTEX_cleanup(&lock); + lh_SSL_SESSION_free(sessions); + x509_method->ssl_ctx_free(this); +} + +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { + if (method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED); + return nullptr; + } + + UniquePtr ret = MakeUnique(method); + if (!ret) { + return nullptr; + } + + ret->cert = MakeUnique(method->x509_method); + ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp); + ret->client_CA.reset(sk_CRYPTO_BUFFER_new_null()); + if (ret->cert == nullptr || + ret->sessions == nullptr || + ret->client_CA == nullptr || + !ret->x509_method->ssl_ctx_new(ret.get())) { + return nullptr; + } + + if (!SSL_CTX_set_strict_cipher_list(ret.get(), SSL_DEFAULT_CIPHER_LIST) || + // Lock the SSL_CTX to the specified version, for compatibility with + // legacy uses of SSL_METHOD. + !SSL_CTX_set_max_proto_version(ret.get(), method->version) || + !SSL_CTX_set_min_proto_version(ret.get(), method->version)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + + return ret.release(); +} + +int SSL_CTX_up_ref(SSL_CTX *ctx) { + CRYPTO_refcount_inc(&ctx->references); + return 1; +} + +void SSL_CTX_free(SSL_CTX *ctx) { + if (ctx == NULL || + !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) { + return; + } + + ctx->~ssl_ctx_st(); + OPENSSL_free(ctx); +} + +ssl_st::ssl_st(SSL_CTX *ctx_arg) + : method(ctx_arg->method), + max_send_fragment(ctx_arg->max_send_fragment), + msg_callback(ctx_arg->msg_callback), + msg_callback_arg(ctx_arg->msg_callback_arg), + ctx(UpRef(ctx_arg)), + session_ctx(UpRef(ctx_arg)), + options(ctx->options), + mode(ctx->mode), + max_cert_list(ctx->max_cert_list), + server(false), + quiet_shutdown(ctx->quiet_shutdown), + enable_early_data(ctx->enable_early_data) { + CRYPTO_new_ex_data(&ex_data); +} + +ssl_st::~ssl_st() { + CRYPTO_free_ex_data(&g_ex_data_class_ssl, this, &ex_data); + // |config| refers to |this|, so we must release it earlier. + config.reset(); + if (method != NULL) { + method->ssl_free(this); + } +} + +SSL *SSL_new(SSL_CTX *ctx) { + if (ctx == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX); + return nullptr; + } + + UniquePtr ssl = MakeUnique(ctx); + if (ssl == nullptr) { + return nullptr; + } + + ssl->config = MakeUnique(ssl.get()); + if (ssl->config == nullptr) { + return nullptr; + } + ssl->config->conf_min_version = ctx->conf_min_version; + ssl->config->conf_max_version = ctx->conf_max_version; + + ssl->config->cert = ssl_cert_dup(ctx->cert.get()); + if (ssl->config->cert == nullptr) { + return nullptr; + } + + ssl->config->verify_mode = ctx->verify_mode; + ssl->config->verify_callback = ctx->default_verify_callback; + ssl->config->custom_verify_callback = ctx->custom_verify_callback; + ssl->config->retain_only_sha256_of_client_certs = + ctx->retain_only_sha256_of_client_certs; + ssl->config->permute_extensions = ctx->permute_extensions; + + if (!ssl->config->supported_group_list.CopyFrom(ctx->supported_group_list) || + !ssl->config->alpn_client_proto_list.CopyFrom( + ctx->alpn_client_proto_list) || + !ssl->config->verify_sigalgs.CopyFrom(ctx->verify_sigalgs)) { + return nullptr; + } + + if (ctx->psk_identity_hint) { + ssl->config->psk_identity_hint.reset( + OPENSSL_strdup(ctx->psk_identity_hint.get())); + if (ssl->config->psk_identity_hint == nullptr) { + return nullptr; + } + } + ssl->config->psk_client_callback = ctx->psk_client_callback; + ssl->config->psk_server_callback = ctx->psk_server_callback; + + ssl->config->channel_id_enabled = ctx->channel_id_enabled; + ssl->config->channel_id_private = UpRef(ctx->channel_id_private); + + ssl->config->signed_cert_timestamps_enabled = + ctx->signed_cert_timestamps_enabled; + ssl->config->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled; + ssl->config->handoff = ctx->handoff; + ssl->quic_method = ctx->quic_method; + + if (!ssl->method->ssl_new(ssl.get()) || + !ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) { + return nullptr; + } + + return ssl.release(); +} + +SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg) + : ssl(ssl_arg), + ech_grease_enabled(false), + signed_cert_timestamps_enabled(false), + ocsp_stapling_enabled(false), + channel_id_enabled(false), + enforce_rsa_key_usage(false), + retain_only_sha256_of_client_certs(false), + handoff(false), + shed_handshake_config(false), + jdk11_workaround(false), + quic_use_legacy_codepoint(false), + permute_extensions(false) { + assert(ssl); +} + +SSL_CONFIG::~SSL_CONFIG() { + if (ssl->ctx != nullptr) { + ssl->ctx->x509_method->ssl_config_free(this); + } +} + +void SSL_free(SSL *ssl) { + Delete(ssl); +} + +void SSL_set_connect_state(SSL *ssl) { + ssl->server = false; + ssl->do_handshake = ssl_client_handshake; +} + +void SSL_set_accept_state(SSL *ssl) { + ssl->server = true; + ssl->do_handshake = ssl_server_handshake; +} + +void SSL_set0_rbio(SSL *ssl, BIO *rbio) { + ssl->rbio.reset(rbio); +} + +void SSL_set0_wbio(SSL *ssl, BIO *wbio) { + ssl->wbio.reset(wbio); +} + +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { + // For historical reasons, this function has many different cases in ownership + // handling. + + // If nothing has changed, do nothing + if (rbio == SSL_get_rbio(ssl) && wbio == SSL_get_wbio(ssl)) { + return; + } + + // If the two arguments are equal, one fewer reference is granted than + // taken. + if (rbio != NULL && rbio == wbio) { + BIO_up_ref(rbio); + } + + // If only the wbio is changed, adopt only one reference. + if (rbio == SSL_get_rbio(ssl)) { + SSL_set0_wbio(ssl, wbio); + return; + } + + // There is an asymmetry here for historical reasons. If only the rbio is + // changed AND the rbio and wbio were originally different, then we only adopt + // one reference. + if (wbio == SSL_get_wbio(ssl) && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) { + SSL_set0_rbio(ssl, rbio); + return; + } + + // Otherwise, adopt both references. + SSL_set0_rbio(ssl, rbio); + SSL_set0_wbio(ssl, wbio); +} + +BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio.get(); } + +BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio.get(); } + +size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, + enum ssl_encryption_level_t level) { + // Limits flights to 16K by default when there are no large + // (certificate-carrying) messages. + static const size_t kDefaultLimit = 16384; + + switch (level) { + case ssl_encryption_initial: + return kDefaultLimit; + case ssl_encryption_early_data: + // QUIC does not send EndOfEarlyData. + return 0; + case ssl_encryption_handshake: + if (ssl->server) { + // Servers may receive Certificate message if configured to request + // client certificates. + if (!!(ssl->config->verify_mode & SSL_VERIFY_PEER) && + ssl->max_cert_list > kDefaultLimit) { + return ssl->max_cert_list; + } + } else { + // Clients may receive both Certificate message and a CertificateRequest + // message. + if (2*ssl->max_cert_list > kDefaultLimit) { + return 2*ssl->max_cert_list; + } + } + return kDefaultLimit; + case ssl_encryption_application: + // Note there is not actually a bound on the number of NewSessionTickets + // one may send in a row. This level may need more involved flow + // control. See https://github.com/quicwg/base-drafts/issues/1834. + return kDefaultLimit; + } + + return 0; +} + +enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl) { + return ssl->s3->read_level; +} + +enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl) { + return ssl->s3->write_level; +} + +int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, + const uint8_t *data, size_t len) { + if (ssl->quic_method == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (level != ssl->s3->read_level) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); + return 0; + } + + size_t new_len = (ssl->s3->hs_buf ? ssl->s3->hs_buf->length : 0) + len; + if (new_len < len || + new_len > SSL_quic_max_handshake_flight_len(ssl, level)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return 0; + } + + return tls_append_handshake_data(ssl, MakeConstSpan(data, len)); +} + +int SSL_do_handshake(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET); + return -1; + } + + if (!SSL_in_init(ssl)) { + return 1; + } + + // Run the handshake. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + + bool early_return = false; + int ret = ssl_run_handshake(hs, &early_return); + ssl_do_info_callback( + ssl, ssl->server ? SSL_CB_ACCEPT_EXIT : SSL_CB_CONNECT_EXIT, ret); + if (ret <= 0) { + return ret; + } + + // Destroy the handshake object if the handshake has completely finished. + if (!early_return) { + ssl->s3->hs.reset(); + ssl_maybe_shed_handshake_config(ssl); + } + + return 1; +} + +int SSL_connect(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_connect_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +int SSL_accept(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_accept_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +static int ssl_do_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return tls13_post_handshake(ssl, msg); + } + + // Check for renegotiation on the server before parsing to use the correct + // error. Renegotiation is triggered by a different message for servers. + if (ssl->server) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); + return 0; + } + + if (msg.type != SSL3_MT_HELLO_REQUEST || CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); + return 0; + } + + if (ssl->renegotiate_mode == ssl_renegotiate_ignore) { + return 1; // Ignore the HelloRequest. + } + + ssl->s3->renegotiate_pending = true; + if (ssl->renegotiate_mode == ssl_renegotiate_explicit) { + return 1; // Handle it later. + } + + if (!SSL_renegotiate(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); + return 0; + } + + return 1; +} + +int SSL_process_quic_post_handshake(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (SSL_in_init(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // Replay post-handshake message errors. + if (!check_read_error(ssl)) { + return 0; + } + + // Process any buffered post-handshake messages. + SSLMessage msg; + while (ssl->method->get_message(ssl, &msg)) { + // Handle the post-handshake message and try again. + if (!ssl_do_post_handshake(ssl, msg)) { + ssl_set_read_error(ssl); + return 0; + } + ssl->method->next_message(ssl); + } + + return 1; +} + +static int ssl_read_impl(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // Replay post-handshake message errors. + if (!check_read_error(ssl)) { + return -1; + } + + while (ssl->s3->pending_app_data.empty()) { + if (ssl->s3->renegotiate_pending) { + ssl->s3->rwstate = SSL_ERROR_WANT_RENEGOTIATE; + return -1; + } + + // Complete the current handshake, if any. False Start will cause + // |SSL_do_handshake| to return mid-handshake, so this may require multiple + // iterations. + while (!ssl_can_read(ssl)) { + int ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + // Process any buffered post-handshake messages. + SSLMessage msg; + if (ssl->method->get_message(ssl, &msg)) { + // If we received an interrupt in early read (EndOfEarlyData), loop again + // for the handshake to process it. + if (SSL_in_init(ssl)) { + ssl->s3->hs->can_early_read = false; + continue; + } + + // Handle the post-handshake message and try again. + if (!ssl_do_post_handshake(ssl, msg)) { + ssl_set_read_error(ssl); + return -1; + } + ssl->method->next_message(ssl); + continue; // Loop again. We may have begun a new handshake. + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + auto ret = ssl_open_app_data(ssl, &ssl->s3->pending_app_data, &consumed, + &alert, ssl->s3->read_buffer.span()); + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (!retry) { + assert(!ssl->s3->pending_app_data.empty()); + ssl->s3->key_update_count = 0; + } + } + + return 1; +} + +int SSL_read(SSL *ssl, void *buf, int num) { + int ret = SSL_peek(ssl, buf, num); + if (ret <= 0) { + return ret; + } + // TODO(davidben): In DTLS, should the rest of the record be discarded? DTLS + // is not a stream. See https://crbug.com/boringssl/65. + ssl->s3->pending_app_data = + ssl->s3->pending_app_data.subspan(static_cast(ret)); + if (ssl->s3->pending_app_data.empty()) { + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int SSL_peek(SSL *ssl, void *buf, int num) { + if (ssl->quic_method != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + int ret = ssl_read_impl(ssl); + if (ret <= 0) { + return ret; + } + if (num <= 0) { + return num; + } + size_t todo = + std::min(ssl->s3->pending_app_data.size(), static_cast(num)); + OPENSSL_memcpy(buf, ssl->s3->pending_app_data.data(), todo); + return static_cast(todo); +} + +int SSL_write(SSL *ssl, const void *buf, int num) { + ssl_reset_error_state(ssl); + + if (ssl->quic_method != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + int ret = 0; + bool needs_handshake = false; + do { + // If necessary, complete the handshake implicitly. + if (!ssl_can_write(ssl)) { + ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + ret = ssl->method->write_app_data(ssl, &needs_handshake, + (const uint8_t *)buf, num); + } while (needs_handshake); + return ret; +} + +int SSL_key_update(SSL *ssl, int request_type) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return 0; + } + + if (ssl->ctx->quic_method != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (!ssl->s3->initial_handshake_complete) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + return 0; + } + + if (!ssl->s3->key_update_pending && + !tls13_add_key_update(ssl, request_type)) { + return 0; + } + + return 1; +} + +int SSL_shutdown(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // If we are in the middle of a handshake, silently succeed. Consumers often + // call this function before |SSL_free|, whether the handshake succeeded or + // not. We assume the caller has already handled failed handshakes. + if (SSL_in_init(ssl)) { + return 1; + } + + if (ssl->quiet_shutdown) { + // Do nothing if configured not to send a close_notify. + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return 1; + } + + // This function completes in two stages. It sends a close_notify and then it + // waits for a close_notify to come in. Perform exactly one action and return + // whether or not it succeeds. + + if (ssl->s3->write_shutdown != ssl_shutdown_close_notify) { + // Send a close_notify. + if (ssl_send_alert_impl(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) { + return -1; + } + } else if (ssl->s3->alert_dispatch) { + // Finish sending the close_notify. + if (ssl->method->dispatch_alert(ssl) <= 0) { + return -1; + } + } else if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + if (SSL_is_dtls(ssl)) { + // Bidirectional shutdown doesn't make sense for an unordered + // transport. DTLS alerts also aren't delivered reliably, so we may even + // time out because the peer never received our close_notify. Report to + // the caller that the channel has fully shut down. + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return -1; + } + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } else { + // Process records until an error, close_notify, or application data. + if (ssl_read_impl(ssl) > 0) { + // We received some unexpected application data. + OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_ON_SHUTDOWN); + return -1; + } + if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + return -1; + } + } + } + + // Return 0 for unidirectional shutdown and 1 for bidirectional shutdown. + return ssl->s3->read_shutdown == ssl_shutdown_close_notify; +} + +int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) { + if (ssl->s3->alert_dispatch) { + if (ssl->s3->send_alert[0] != SSL3_AL_FATAL || + ssl->s3->send_alert[1] != alert) { + // We are already attempting to write a different alert. + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + return ssl->method->dispatch_alert(ssl); + } + + return ssl_send_alert_impl(ssl, SSL3_AL_FATAL, alert); +} + +int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len) { + return ssl->config && ssl->config->quic_transport_params.CopyFrom( + MakeConstSpan(params, params_len)); +} + +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len) { + *out_params = ssl->s3->peer_quic_transport_params.data(); + *out_params_len = ssl->s3->peer_quic_transport_params.size(); +} + +int SSL_set_quic_early_data_context(SSL *ssl, const uint8_t *context, + size_t context_len) { + return ssl->config && ssl->config->quic_early_data_context.CopyFrom( + MakeConstSpan(context, context_len)); +} + +void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled) { + ctx->enable_early_data = !!enabled; +} + +void SSL_set_early_data_enabled(SSL *ssl, int enabled) { + ssl->enable_early_data = !!enabled; +} + +int SSL_in_early_data(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_early_data; +} + +int SSL_early_data_accepted(const SSL *ssl) { + return ssl->s3->early_data_accepted; +} + +void SSL_reset_early_data_reject(SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL || + hs->wait != ssl_hs_early_data_rejected) { + abort(); + } + + hs->wait = ssl_hs_ok; + hs->in_early_data = false; + hs->early_session.reset(); + + // Discard any unfinished writes from the perspective of |SSL_write|'s + // retry. The handshake will transparently flush out the pending record + // (discarded by the server) to keep the framing correct. + ssl->s3->wpend_pending = false; +} + +enum ssl_early_data_reason_t SSL_get_early_data_reason(const SSL *ssl) { + return ssl->s3->early_data_reason; +} + +const char *SSL_early_data_reason_string(enum ssl_early_data_reason_t reason) { + switch (reason) { + case ssl_early_data_unknown: + return "unknown"; + case ssl_early_data_disabled: + return "disabled"; + case ssl_early_data_accepted: + return "accepted"; + case ssl_early_data_protocol_version: + return "protocol_version"; + case ssl_early_data_peer_declined: + return "peer_declined"; + case ssl_early_data_no_session_offered: + return "no_session_offered"; + case ssl_early_data_session_not_resumed: + return "session_not_resumed"; + case ssl_early_data_unsupported_for_session: + return "unsupported_for_session"; + case ssl_early_data_hello_retry_request: + return "hello_retry_request"; + case ssl_early_data_alpn_mismatch: + return "alpn_mismatch"; + case ssl_early_data_channel_id: + return "channel_id"; + case ssl_early_data_ticket_age_skew: + return "ticket_age_skew"; + case ssl_early_data_quic_parameter_mismatch: + return "quic_parameter_mismatch"; + case ssl_early_data_alps_mismatch: + return "alps_mismatch"; + } + + return nullptr; +} + +static int bio_retry_reason_to_error(int reason) { + switch (reason) { + case BIO_RR_CONNECT: + return SSL_ERROR_WANT_CONNECT; + case BIO_RR_ACCEPT: + return SSL_ERROR_WANT_ACCEPT; + default: + return SSL_ERROR_SYSCALL; + } +} + +int SSL_get_error(const SSL *ssl, int ret_code) { + if (ret_code > 0) { + return SSL_ERROR_NONE; + } + + // Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, + // where we do encode the error + uint32_t err = ERR_peek_error(); + if (err != 0) { + if (ERR_GET_LIB(err) == ERR_LIB_SYS) { + return SSL_ERROR_SYSCALL; + } + return SSL_ERROR_SSL; + } + + if (ret_code == 0) { + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return SSL_ERROR_ZERO_RETURN; + } + // An EOF was observed which violates the protocol, and the underlying + // transport does not participate in the error queue. Bubble up to the + // caller. + return SSL_ERROR_SYSCALL; + } + + switch (ssl->s3->rwstate) { + case SSL_ERROR_PENDING_SESSION: + case SSL_ERROR_PENDING_CERTIFICATE: + case SSL_ERROR_HANDOFF: + case SSL_ERROR_HANDBACK: + case SSL_ERROR_WANT_X509_LOOKUP: + case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: + case SSL_ERROR_PENDING_TICKET: + case SSL_ERROR_EARLY_DATA_REJECTED: + case SSL_ERROR_WANT_CERTIFICATE_VERIFY: + case SSL_ERROR_WANT_RENEGOTIATE: + case SSL_ERROR_HANDSHAKE_HINTS_READY: + return ssl->s3->rwstate; + + case SSL_ERROR_WANT_READ: { + if (ssl->quic_method) { + return SSL_ERROR_WANT_READ; + } + BIO *bio = SSL_get_rbio(ssl); + if (BIO_should_read(bio)) { + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_write(bio)) { + // TODO(davidben): OpenSSL historically checked for writes on the read + // BIO. Can this be removed? + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + + case SSL_ERROR_WANT_WRITE: { + BIO *bio = SSL_get_wbio(ssl); + if (BIO_should_write(bio)) { + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_read(bio)) { + // TODO(davidben): OpenSSL historically checked for reads on the write + // BIO. Can this be removed? + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + } + + return SSL_ERROR_SYSCALL; +} + +const char *SSL_error_description(int err) { + switch (err) { + case SSL_ERROR_NONE: + return "NONE"; + case SSL_ERROR_SSL: + return "SSL"; + case SSL_ERROR_WANT_READ: + return "WANT_READ"; + case SSL_ERROR_WANT_WRITE: + return "WANT_WRITE"; + case SSL_ERROR_WANT_X509_LOOKUP: + return "WANT_X509_LOOKUP"; + case SSL_ERROR_SYSCALL: + return "SYSCALL"; + case SSL_ERROR_ZERO_RETURN: + return "ZERO_RETURN"; + case SSL_ERROR_WANT_CONNECT: + return "WANT_CONNECT"; + case SSL_ERROR_WANT_ACCEPT: + return "WANT_ACCEPT"; + case SSL_ERROR_PENDING_SESSION: + return "PENDING_SESSION"; + case SSL_ERROR_PENDING_CERTIFICATE: + return "PENDING_CERTIFICATE"; + case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: + return "WANT_PRIVATE_KEY_OPERATION"; + case SSL_ERROR_PENDING_TICKET: + return "PENDING_TICKET"; + case SSL_ERROR_EARLY_DATA_REJECTED: + return "EARLY_DATA_REJECTED"; + case SSL_ERROR_WANT_CERTIFICATE_VERIFY: + return "WANT_CERTIFICATE_VERIFY"; + case SSL_ERROR_HANDOFF: + return "HANDOFF"; + case SSL_ERROR_HANDBACK: + return "HANDBACK"; + case SSL_ERROR_WANT_RENEGOTIATE: + return "WANT_RENEGOTIATE"; + case SSL_ERROR_HANDSHAKE_HINTS_READY: + return "HANDSHAKE_HINTS_READY"; + default: + return nullptr; + } +} + +uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) { + ctx->options |= options; + return ctx->options; +} + +uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) { + ctx->options &= ~options; + return ctx->options; +} + +uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; } + +uint32_t SSL_set_options(SSL *ssl, uint32_t options) { + ssl->options |= options; + return ssl->options; +} + +uint32_t SSL_clear_options(SSL *ssl, uint32_t options) { + ssl->options &= ~options; + return ssl->options; +} + +uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; } + +uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode |= mode; + return ctx->mode; +} + +uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode &= ~mode; + return ctx->mode; +} + +uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; } + +uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) { + ssl->mode |= mode; + return ssl->mode; +} + +uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) { + ssl->mode &= ~mode; + return ssl->mode; +} + +uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; } + +void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, CRYPTO_BUFFER_POOL *pool) { + ctx->pool = pool; +} + +int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + *out_len = 0; + OPENSSL_memset(out, 0, max_out); + + // tls-unique is not defined for TLS 1.3. + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + // The tls-unique value is the first Finished message in the handshake, which + // is the client's in a full handshake and the server's for a resumption. See + // https://tools.ietf.org/html/rfc5929#section-3.1. + const uint8_t *finished = ssl->s3->previous_client_finished; + size_t finished_len = ssl->s3->previous_client_finished_len; + if (ssl->session != NULL) { + // tls-unique is broken for resumed sessions unless EMS is used. + if (!ssl->session->extended_master_secret) { + return 0; + } + finished = ssl->s3->previous_server_finished; + finished_len = ssl->s3->previous_server_finished_len; + } + + *out_len = finished_len; + if (finished_len > max_out) { + *out_len = max_out; + } + + OPENSSL_memcpy(out, finished, *out_len); + return 1; +} + +static int set_session_id_context(CERT *cert, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(cert->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(cert->sid_ctx) < 256, "sid_ctx too large"); + cert->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(cert->sid_ctx, sid_ctx, sid_ctx_len); + return 1; +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + return set_session_id_context(ctx->cert.get(), sid_ctx, sid_ctx_len); +} + +int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (!ssl->config) { + return 0; + } + return set_session_id_context(ssl->config->cert.get(), sid_ctx, sid_ctx_len); +} + +const uint8_t *SSL_get0_session_id_context(const SSL *ssl, size_t *out_len) { + if (!ssl->config) { + assert(ssl->config); + *out_len = 0; + return NULL; + } + *out_len = ssl->config->cert->sid_ctx_length; + return ssl->config->cert->sid_ctx; +} + +void SSL_certs_clear(SSL *ssl) { + if (!ssl->config) { + return; + } + ssl_cert_clear_certs(ssl->config->cert.get()); +} + +int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); } + +int SSL_get_rfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_get_wfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_set_fd(SSL *ssl, int fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(ssl, bio, bio); + return 1; +} + +int SSL_set_wfd(SSL *ssl, int fd) { + BIO *rbio = SSL_get_rbio(ssl); + if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET || + BIO_get_fd(rbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_wbio(ssl, bio); + } else { + // Copy the rbio over to the wbio. + BIO_up_ref(rbio); + SSL_set0_wbio(ssl, rbio); + } + + return 1; +} + +int SSL_set_rfd(SSL *ssl, int fd) { + BIO *wbio = SSL_get_wbio(ssl); + if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET || + BIO_get_fd(wbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_rbio(ssl, bio); + } else { + // Copy the wbio over to the rbio. + BIO_up_ref(wbio); + SSL_set0_rbio(ssl, wbio); + } + return 1; +} + +static size_t copy_finished(void *out, size_t out_len, const uint8_t *in, + size_t in_len) { + if (out_len > in_len) { + out_len = in_len; + } + OPENSSL_memcpy(out, in, out_len); + return in_len; +} + +size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); +} + +size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); +} + +int SSL_get_verify_mode(const SSL *ssl) { + if (!ssl->config) { + assert(ssl->config); + return -1; + } + return ssl->config->verify_mode; +} + +int SSL_get_extms_support(const SSL *ssl) { + // TLS 1.3 does not require extended master secret and always reports as + // supporting it. + if (!ssl->s3->have_version) { + return 0; + } + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 1; + } + + // If the initial handshake completed, query the established session. + if (ssl->s3->established_session != NULL) { + return ssl->s3->established_session->extended_master_secret; + } + + // Otherwise, query the in-progress handshake. + if (ssl->s3->hs != NULL) { + return ssl->s3->hs->extended_master_secret; + } + assert(0); + return 0; +} + +int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; } + +int SSL_get_read_ahead(const SSL *ssl) { return 0; } + +int SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { return 1; } + +int SSL_set_read_ahead(SSL *ssl, int yes) { return 1; } + +int SSL_pending(const SSL *ssl) { + return static_cast(ssl->s3->pending_app_data.size()); +} + +int SSL_has_pending(const SSL *ssl) { + return SSL_pending(ssl) != 0 || !ssl->s3->read_buffer.empty(); +} + +int SSL_CTX_check_private_key(const SSL_CTX *ctx) { + return ssl_cert_check_private_key(ctx->cert.get(), + ctx->cert->privatekey.get()); +} + +int SSL_check_private_key(const SSL *ssl) { + if (!ssl->config) { + return 0; + } + return ssl_cert_check_private_key(ssl->config->cert.get(), + ssl->config->cert->privatekey.get()); +} + +long SSL_get_default_timeout(const SSL *ssl) { + return SSL_DEFAULT_SESSION_TIMEOUT; +} + +int SSL_renegotiate(SSL *ssl) { + // Caller-initiated renegotiation is not supported. + if (!ssl->s3->renegotiate_pending) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (!ssl_can_renegotiate(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + return 0; + } + + // We should not have told the caller to release the private key. + assert(!SSL_can_release_private_key(ssl)); + + // Renegotiation is only supported at quiescent points in the application + // protocol, namely in HTTPS, just before reading the HTTP response. + // Require the record-layer be idle and avoid complexities of sending a + // handshake record while an application_data record is being written. + if (!ssl->s3->write_buffer.empty() || + ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + return 0; + } + + // Begin a new handshake. + if (ssl->s3->hs != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + ssl->s3->hs = ssl_handshake_new(ssl); + if (ssl->s3->hs == nullptr) { + return 0; + } + + ssl->s3->renegotiate_pending = false; + ssl->s3->total_renegotiations++; + return 1; +} + +int SSL_renegotiate_pending(SSL *ssl) { + return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete; +} + +int SSL_total_renegotiations(const SSL *ssl) { + return ssl->s3->total_renegotiations; +} + +size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) { + return ctx->max_cert_list; +} + +void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ctx->max_cert_list = (uint32_t)max_cert_list; +} + +size_t SSL_get_max_cert_list(const SSL *ssl) { + return ssl->max_cert_list; +} + +void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ssl->max_cert_list = (uint32_t)max_cert_list; +} + +int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ctx->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ssl->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_mtu(SSL *ssl, unsigned mtu) { + if (!SSL_is_dtls(ssl) || mtu < dtls1_min_mtu()) { + return 0; + } + ssl->d1->mtu = mtu; + return 1; +} + +int SSL_get_secure_renegotiation_support(const SSL *ssl) { + if (!ssl->s3->have_version) { + return 0; + } + return ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->s3->send_connection_binding; +} + +size_t SSL_CTX_sess_number(const SSL_CTX *ctx) { + MutexReadLock lock(const_cast(&ctx->lock)); + return lh_SSL_SESSION_num_items(ctx->sessions); +} + +unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) { + unsigned long ret = ctx->session_cache_size; + ctx->session_cache_size = size; + return ret; +} + +unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) { + return ctx->session_cache_size; +} + +int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) { + int ret = ctx->session_cache_mode; + ctx->session_cache_mode = mode; + return ret; +} + +int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) { + return ctx->session_cache_mode; +} + + +int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, size_t len) { + if (out == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + + // The default ticket keys are initialized lazily. Trigger a key + // rotation to initialize them. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return 0; + } + + uint8_t *out_bytes = reinterpret_cast(out); + MutexReadLock lock(&ctx->lock); + OPENSSL_memcpy(out_bytes, ctx->ticket_key_current->name, 16); + OPENSSL_memcpy(out_bytes + 16, ctx->ticket_key_current->hmac_key, 16); + OPENSSL_memcpy(out_bytes + 32, ctx->ticket_key_current->aes_key, 16); + return 1; +} + +int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) { + if (in == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + auto key = MakeUnique(); + if (!key) { + return 0; + } + const uint8_t *in_bytes = reinterpret_cast(in); + OPENSSL_memcpy(key->name, in_bytes, 16); + OPENSSL_memcpy(key->hmac_key, in_bytes + 16, 16); + OPENSSL_memcpy(key->aes_key, in_bytes + 32, 16); + // Disable automatic key rotation for manually-configured keys. This is now + // the caller's responsibility. + key->next_rotation_tv_sec = 0; + ctx->ticket_key_current = std::move(key); + ctx->ticket_key_prev.reset(); + return 1; +} + +int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)) { + ctx->ticket_key_cb = callback; + return 1; +} + +int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) { + return tls1_set_curves(&ctx->supported_group_list, + MakeConstSpan(curves, curves_len)); +} + +int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) { + if (!ssl->config) { + return 0; + } + return tls1_set_curves(&ssl->config->supported_group_list, + MakeConstSpan(curves, curves_len)); +} + +int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) { + return tls1_set_curves_list(&ctx->supported_group_list, curves); +} + +int SSL_set1_curves_list(SSL *ssl, const char *curves) { + if (!ssl->config) { + return 0; + } + return tls1_set_curves_list(&ssl->config->supported_group_list, curves); +} + +uint16_t SSL_get_curve_id(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->group_id; +} + +int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) { + return 1; +} + +int SSL_set_tmp_dh(SSL *ssl, const DH *dh) { + return 1; +} + +STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) { + return ctx->cipher_list->ciphers.get(); +} + +int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i) { + if (i >= sk_SSL_CIPHER_num(ctx->cipher_list->ciphers.get())) { + return 0; + } + return ctx->cipher_list->in_group_flags[i]; +} + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + if (ssl->config == NULL) { + assert(ssl->config); + return NULL; + } + + return ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() + : ssl->ctx->cipher_list->ciphers.get(); +} + +const char *SSL_get_cipher_list(const SSL *ssl, int n) { + if (ssl == NULL) { + return NULL; + } + + STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); + if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) { + return NULL; + } + + const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) { + return NULL; + } + + return c->name; +} + +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, false /* not strict */); +} + +int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, true /* strict */); +} + +int SSL_set_cipher_list(SSL *ssl, const char *str) { + if (!ssl->config) { + return 0; + } + return ssl_create_cipher_list(&ssl->config->cipher_list, str, + false /* not strict */); +} + +int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { + if (!ssl->config) { + return 0; + } + return ssl_create_cipher_list(&ssl->config->cipher_list, str, + true /* strict */); +} + +const char *SSL_get_servername(const SSL *ssl, const int type) { + if (type != TLSEXT_NAMETYPE_host_name) { + return NULL; + } + + // Historically, |SSL_get_servername| was also the configuration getter + // corresponding to |SSL_set_tlsext_host_name|. + if (ssl->hostname != nullptr) { + return ssl->hostname.get(); + } + + return ssl->s3->hostname.get(); +} + +int SSL_get_servername_type(const SSL *ssl) { + if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) == NULL) { + return -1; + } + return TLSEXT_NAMETYPE_host_name; +} + +void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ctx->verify_mode = mode; + ctx->custom_verify_callback = callback; +} + +void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + if (!ssl->config) { + return; + } + ssl->config->verify_mode = mode; + ssl->config->custom_verify_callback = callback; +} + +void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) { + ctx->signed_cert_timestamps_enabled = true; +} + +void SSL_enable_signed_cert_timestamps(SSL *ssl) { + if (!ssl->config) { + return; + } + ssl->config->signed_cert_timestamps_enabled = true; +} + +void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) { + ctx->ocsp_stapling_enabled = true; +} + +void SSL_enable_ocsp_stapling(SSL *ssl) { + if (!ssl->config) { + return; + } + ssl->config->ocsp_stapling_enabled = true; +} + +void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->signed_cert_timestamp_list) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list.get()); + *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list.get()); +} + +void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->ocsp_response) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->ocsp_response.get()); + *out_len = CRYPTO_BUFFER_len(session->ocsp_response.get()); +} + +int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { + ssl->hostname.reset(); + if (name == nullptr) { + return 1; + } + + size_t len = strlen(name); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + ssl->hostname.reset(OPENSSL_strdup(name)); + if (ssl->hostname == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)) { + ctx->servername_callback = callback; + return 1; +} + +int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) { + ctx->servername_arg = arg; + return 1; +} + +int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, const uint8_t *peer, + unsigned peer_len, const uint8_t *supported, + unsigned supported_len) { + const uint8_t *result; + int status; + + // For each protocol in peer preference order, see if we support it. + for (unsigned i = 0; i < peer_len;) { + for (unsigned j = 0; j < supported_len;) { + if (peer[i] == supported[j] && + OPENSSL_memcmp(&peer[i + 1], &supported[j + 1], peer[i]) == 0) { + // We found a match + result = &peer[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += supported[j]; + j++; + } + i += peer[i]; + i++; + } + + // There's no overlap between our protocols and the peer's list. + result = supported; + status = OPENSSL_NPN_NO_OVERLAP; + +found: + *out = (uint8_t *)result + 1; + *out_len = result[0]; + return status; +} + +void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + *out_data = ssl->s3->next_proto_negotiated.data(); + *out_len = ssl->s3->next_proto_negotiated.size(); +} + +void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *arg) { + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg) { + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len) { + // Note this function's return value is backwards. + auto span = MakeConstSpan(protos, protos_len); + if (!span.empty() && !ssl_is_valid_alpn_list(span)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL_LIST); + return 1; + } + return ctx->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; +} + +int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) { + // Note this function's return value is backwards. + if (!ssl->config) { + return 1; + } + auto span = MakeConstSpan(protos, protos_len); + if (!span.empty() && !ssl_is_valid_alpn_list(span)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL_LIST); + return 1; + } + return ssl->config->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; +} + +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, + uint8_t *out_len, const uint8_t *in, + unsigned in_len, void *arg), + void *arg) { + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} + +void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + if (SSL_in_early_data(ssl) && !ssl->server) { + *out_data = ssl->s3->hs->early_session->early_alpn.data(); + *out_len = ssl->s3->hs->early_session->early_alpn.size(); + } else { + *out_data = ssl->s3->alpn_selected.data(); + *out_len = ssl->s3->alpn_selected.size(); + } +} + +void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { + ctx->allow_unknown_alpn_protos = !!enabled; +} + +int SSL_add_application_settings(SSL *ssl, const uint8_t *proto, + size_t proto_len, const uint8_t *settings, + size_t settings_len) { + if (!ssl->config) { + return 0; + } + ALPSConfig config; + if (!config.protocol.CopyFrom(MakeConstSpan(proto, proto_len)) || + !config.settings.CopyFrom(MakeConstSpan(settings, settings_len)) || + !ssl->config->alps_configs.Push(std::move(config))) { + return 0; + } + return 1; +} + +void SSL_get0_peer_application_settings(const SSL *ssl, + const uint8_t **out_data, + size_t *out_len) { + const SSL_SESSION *session = SSL_get_session(ssl); + Span settings = + session ? session->peer_application_settings : Span(); + *out_data = settings.data(); + *out_len = settings.size(); +} + +int SSL_has_application_settings(const SSL *ssl) { + const SSL_SESSION *session = SSL_get_session(ssl); + return session && session->has_application_settings; +} + +int SSL_CTX_add_cert_compression_alg(SSL_CTX *ctx, uint16_t alg_id, + ssl_cert_compression_func_t compress, + ssl_cert_decompression_func_t decompress) { + assert(compress != nullptr || decompress != nullptr); + + for (const auto &alg : ctx->cert_compression_algs) { + if (alg.alg_id == alg_id) { + return 0; + } + } + + CertCompressionAlg alg; + alg.alg_id = alg_id; + alg.compress = compress; + alg.decompress = decompress; + return ctx->cert_compression_algs.Push(alg); +} + +void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, int enabled) { + ctx->channel_id_enabled = !!enabled; +} + +int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx) { + SSL_CTX_set_tls_channel_id_enabled(ctx, 1); + return 1; +} + +void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled) { + if (!ssl->config) { + return; + } + ssl->config->channel_id_enabled = !!enabled; +} + +int SSL_enable_tls_channel_id(SSL *ssl) { + SSL_set_tls_channel_id_enabled(ssl, 1); + return 1; +} + +static int is_p256_key(EVP_PKEY *private_key) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); + return ec_key != NULL && + EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) == + NID_X9_62_prime256v1; +} + +int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + ctx->channel_id_private = UpRef(private_key); + return 1; +} + +int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { + if (!ssl->config) { + return 0; + } + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + ssl->config->channel_id_private = UpRef(private_key); + return 1; +} + +size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, size_t max_out) { + if (!ssl->s3->channel_id_valid) { + return 0; + } + OPENSSL_memcpy(out, ssl->s3->channel_id, (max_out < 64) ? max_out : 64); + return 64; +} + +size_t SSL_get0_certificate_types(const SSL *ssl, const uint8_t **out_types) { + Span types; + if (!ssl->server && ssl->s3->hs != nullptr) { + types = ssl->s3->hs->certificate_types; + } + *out_types = types.data(); + return types.size(); +} + +size_t SSL_get0_peer_verify_algorithms(const SSL *ssl, + const uint16_t **out_sigalgs) { + Span sigalgs; + if (ssl->s3->hs != nullptr) { + sigalgs = ssl->s3->hs->peer_sigalgs; + } + *out_sigalgs = sigalgs.data(); + return sigalgs.size(); +} + +size_t SSL_get0_peer_delegation_algorithms(const SSL *ssl, + const uint16_t **out_sigalgs){ + Span sigalgs; + if (ssl->s3->hs != nullptr) { + sigalgs = ssl->s3->hs->peer_delegated_credential_sigalgs; + } + *out_sigalgs = sigalgs.data(); + return sigalgs.size(); +} + +EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { + if (!ssl->config) { + assert(ssl->config); + return NULL; + } + if (ssl->config->cert != NULL) { + return ssl->config->cert->privatekey.get(); + } + + return NULL; +} + +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) { + if (ctx->cert != NULL) { + return ctx->cert->privatekey.get(); + } + + return NULL; +} + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) { + const SSL_SESSION *session = SSL_get_session(ssl); + return session == nullptr ? nullptr : session->cipher; +} + +int SSL_session_reused(const SSL *ssl) { + return ssl->s3->session_reused || SSL_in_early_data(ssl); +} + +const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; } + +const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; } + +int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; } + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) { + ctx->quiet_shutdown = (mode != 0); +} + +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) { + return ctx->quiet_shutdown; +} + +void SSL_set_quiet_shutdown(SSL *ssl, int mode) { + ssl->quiet_shutdown = (mode != 0); +} + +int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; } + +void SSL_set_shutdown(SSL *ssl, int mode) { + // It is an error to clear any bits that have already been set. (We can't try + // to get a second close_notify or send two.) + assert((SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl)); + + if (mode & SSL_RECEIVED_SHUTDOWN && + ssl->s3->read_shutdown == ssl_shutdown_none) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } + + if (mode & SSL_SENT_SHUTDOWN && + ssl->s3->write_shutdown == ssl_shutdown_none) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } +} + +int SSL_get_shutdown(const SSL *ssl) { + int ret = 0; + if (ssl->s3->read_shutdown != ssl_shutdown_none) { + // Historically, OpenSSL set |SSL_RECEIVED_SHUTDOWN| on both close_notify + // and fatal alert. + ret |= SSL_RECEIVED_SHUTDOWN; + } + if (ssl->s3->write_shutdown == ssl_shutdown_close_notify) { + // Historically, OpenSSL set |SSL_SENT_SHUTDOWN| on only close_notify. + ret |= SSL_SENT_SHUTDOWN; + } + return ret; +} + +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx.get(); } + +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { + if (!ssl->config) { + return NULL; + } + if (ssl->ctx.get() == ctx) { + return ssl->ctx.get(); + } + + // One cannot change the X.509 callbacks during a connection. + if (ssl->ctx->x509_method != ctx->x509_method) { + assert(0); + return NULL; + } + + UniquePtr new_cert = ssl_cert_dup(ctx->cert.get()); + if (!new_cert) { + return nullptr; + } + + ssl->config->cert = std::move(new_cert); + ssl->ctx = UpRef(ctx); + ssl->enable_early_data = ssl->ctx->enable_early_data; + + return ssl->ctx.get(); +} + +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl, int type, int value)) { + ssl->info_callback = cb; +} + +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, + int value) { + return ssl->info_callback; +} + +int SSL_state(const SSL *ssl) { + return SSL_in_init(ssl) ? SSL_ST_INIT : SSL_ST_OK; +} + +void SSL_set_state(SSL *ssl, int state) { } + +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len) { + if (len <= 0) { + return NULL; + } + buf[0] = '\0'; + return buf; +} + +int SSL_get_shared_sigalgs(SSL *ssl, int idx, int *psign, int *phash, + int *psignandhash, uint8_t *rsig, uint8_t *rhash) { + return 0; +} + +int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method) { + if (ctx->method->is_dtls) { + return 0; + } + ctx->quic_method = quic_method; + return 1; +} + +int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) { + if (ssl->method->is_dtls) { + return 0; + } + ssl->quic_method = quic_method; + return 1; +} + +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_set_ex_data(SSL *ssl, int idx, void *data) { + return CRYPTO_set_ex_data(&ssl->ex_data, idx, data); +} + +void *SSL_get_ex_data(const SSL *ssl, int idx) { + return CRYPTO_get_ex_data(&ssl->ex_data, idx); +} + +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data) { + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) { + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int SSL_want(const SSL *ssl) { return ssl->s3->rwstate; } + +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +static int use_psk_identity_hint(UniquePtr *out, + const char *identity_hint) { + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + + // Clear currently configured hint, if any. + out->reset(); + + // Treat the empty hint as not supplying one. Plain PSK makes it possible to + // send either no hint (omit ServerKeyExchange) or an empty hint, while + // ECDHE_PSK can only spell empty hint. Having different capabilities is odd, + // so we interpret empty and missing as identical. + if (identity_hint != NULL && identity_hint[0] != '\0') { + out->reset(OPENSSL_strdup(identity_hint)); + if (*out == nullptr) { + return 0; + } + } + + return 1; +} + +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { + return use_psk_identity_hint(&ctx->psk_identity_hint, identity_hint); +} + +int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) { + if (!ssl->config) { + return 0; + } + return use_psk_identity_hint(&ssl->config->psk_identity_hint, identity_hint); +} + +const char *SSL_get_psk_identity_hint(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + if (ssl->config == NULL) { + assert(ssl->config); + return NULL; + } + return ssl->config->psk_identity_hint.get(); +} + +const char *SSL_get_psk_identity(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + return session->psk_identity.get(); +} + +void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + if (!ssl->config) { + return; + } + ssl->config->psk_client_callback = cb; +} + +void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + ctx->psk_client_callback = cb; +} + +void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)) { + if (!ssl->config) { + return; + } + ssl->config->psk_server_callback = cb; +} + +void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned max_psk_len)) { + ctx->psk_server_callback = cb; +} + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb)(int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) { + ctx->msg_callback = cb; +} + +void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) { + ctx->msg_callback_arg = arg; +} + +void SSL_set_msg_callback(SSL *ssl, + void (*cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg)) { + ssl->msg_callback = cb; +} + +void SSL_set_msg_callback_arg(SSL *ssl, void *arg) { + ssl->msg_callback_arg = arg; +} + +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, const char *line)) { + ctx->keylog_callback = cb; +} + +void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))(const SSL *ssl, + const char *line) { + return ctx->keylog_callback; +} + +void SSL_CTX_set_current_time_cb(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, + struct timeval *out_clock)) { + ctx->current_time_cb = cb; +} + +int SSL_can_release_private_key(const SSL *ssl) { + if (ssl_can_renegotiate(ssl)) { + // If the connection can renegotiate (client only), the private key may be + // used in a future handshake. + return 0; + } + + // Otherwise, this is determined by the current handshake. + return !ssl->s3->hs || ssl->s3->hs->can_release_private_key; +} + +int SSL_is_init_finished(const SSL *ssl) { + return !SSL_in_init(ssl); +} + +int SSL_in_init(const SSL *ssl) { + // This returns false once all the handshake state has been finalized, to + // allow callbacks and getters based on SSL_in_init to return the correct + // values. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + return hs != nullptr && !hs->handshake_finalized; +} + +int SSL_in_false_start(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_false_start; +} + +int SSL_cutthrough_complete(const SSL *ssl) { + return SSL_in_false_start(ssl); +} + +int SSL_is_server(const SSL *ssl) { return ssl->server; } + +int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; } + +void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->select_certificate_cb = cb; +} + +void SSL_CTX_set_dos_protection_cb(SSL_CTX *ctx, + int (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->dos_protection_cb = cb; +} + +void SSL_CTX_set_reverify_on_resume(SSL_CTX *ctx, int enabled) { + ctx->reverify_on_resume = !!enabled; +} + +void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled) { + if (!ssl->config) { + return; + } + ssl->config->enforce_rsa_key_usage = !!enabled; +} + +void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { + ssl->renegotiate_mode = mode; + + // Check if |ssl_can_renegotiate| has changed and the configuration may now be + // shed. HTTP clients may initially allow renegotiation for HTTP/1.1, and then + // disable after the handshake once the ALPN protocol is known to be HTTP/2. + ssl_maybe_shed_handshake_config(ssl); +} + +int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, size_t *out_iv_len) { + size_t write_iv_len; + if (!ssl->s3->aead_read_ctx->GetIV(out_read_iv, out_iv_len) || + !ssl->s3->aead_write_ctx->GetIV(out_write_iv, &write_iv_len) || + *out_iv_len != write_iv_len) { + return 0; + } + + return 1; +} + +static uint64_t be_to_u64(const uint8_t in[8]) { + return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) | + (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) | + (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) | + (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]); +} + +uint64_t SSL_get_read_sequence(const SSL *ssl) { + // TODO(davidben): Internally represent sequence numbers as uint64_t. + if (SSL_is_dtls(ssl)) { + // max_seq_num already includes the epoch. + assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48)); + return ssl->d1->bitmap.max_seq_num; + } + return be_to_u64(ssl->s3->read_sequence); +} + +uint64_t SSL_get_write_sequence(const SSL *ssl) { + uint64_t ret = be_to_u64(ssl->s3->write_sequence); + if (SSL_is_dtls(ssl)) { + assert((ret >> 48) == 0); + ret |= ((uint64_t)ssl->d1->w_epoch) << 48; + } + return ret; +} + +uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->peer_signature_algorithm; +} + +size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->client_random); + } + if (max_out > sizeof(ssl->s3->client_random)) { + max_out = sizeof(ssl->s3->client_random); + } + OPENSSL_memcpy(out, ssl->s3->client_random, max_out); + return max_out; +} + +size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->server_random); + } + if (max_out > sizeof(ssl->s3->server_random)) { + max_out = sizeof(ssl->s3->server_random); + } + OPENSSL_memcpy(out, ssl->s3->server_random, max_out); + return max_out; +} + +const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL) { + return NULL; + } + return hs->new_cipher; +} + +void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, int enabled) { + if (!ssl->config) { + return; + } + ssl->config->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) { + ctx->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled) { + ctx->grease_enabled = !!enabled; +} + +void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled) { + ctx->permute_extensions = !!enabled; +} + +void SSL_set_permute_extensions(SSL *ssl, int enabled) { + if (!ssl->config) { + return; + } + ssl->config->permute_extensions = !!enabled; +} + +int32_t SSL_get_ticket_age_skew(const SSL *ssl) { + return ssl->s3->ticket_age_skew; +} + +void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, int allowed) { + ctx->false_start_allowed_without_alpn = !!allowed; +} + +int SSL_used_hello_retry_request(const SSL *ssl) { + return ssl->s3->used_hello_retry_request; +} + +void SSL_set_shed_handshake_config(SSL *ssl, int enable) { + if (!ssl->config) { + return; + } + ssl->config->shed_handshake_config = !!enable; +} + +void SSL_set_jdk11_workaround(SSL *ssl, int enable) { + if (!ssl->config) { + return; + } + ssl->config->jdk11_workaround = !!enable; +} + +void SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy) { + if (!ssl->config) { + return; + } + ssl->config->quic_use_legacy_codepoint = !!use_legacy; +} + +int SSL_clear(SSL *ssl) { + if (!ssl->config) { + return 0; // SSL_clear may not be used after shedding config. + } + + // In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously + // established session to be offered the next time around. wpa_supplicant + // depends on this behavior, so emulate it. + UniquePtr session; + if (!ssl->server && ssl->s3->established_session != NULL) { + session = UpRef(ssl->s3->established_session); + } + + // The ssl->d1->mtu is simultaneously configuration (preserved across + // clear) and connection-specific state (gets reset). + // + // TODO(davidben): Avoid this. + unsigned mtu = 0; + if (ssl->d1 != NULL) { + mtu = ssl->d1->mtu; + } + + ssl->method->ssl_free(ssl); + if (!ssl->method->ssl_new(ssl)) { + return 0; + } + + if (SSL_is_dtls(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + ssl->d1->mtu = mtu; + } + + if (session != nullptr) { + SSL_set_session(ssl, session.get()); + } + + return 1; +} + +int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; } + +int SSL_num_renegotiations(const SSL *ssl) { + return SSL_total_renegotiations(ssl); +} + +int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx) { return 0; } +int SSL_need_tmp_RSA(const SSL *ssl) { return 0; } +int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa) { return 1; } +int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa) { return 1; } +void ERR_load_SSL_strings(void) {} +void SSL_load_error_strings(void) {} +int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); } + +int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_CTX_set1_curves(ctx, &nid, 1); +} + +int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_set1_curves(ssl, &nid, 1); +} + +void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, + const SSL_TICKET_AEAD_METHOD *aead_method) { + ctx->ticket_aead_method = aead_method; +} + +SSL_SESSION *SSL_process_tls13_new_session_ticket(SSL *ssl, const uint8_t *buf, + size_t buf_len) { + if (SSL_in_init(ssl) || + ssl_protocol_version(ssl) != TLS1_3_VERSION || + ssl->server) { + // Only TLS 1.3 clients are supported. + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return nullptr; + } + + CBS cbs, body; + CBS_init(&cbs, buf, buf_len); + uint8_t type; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u24_length_prefixed(&cbs, &body) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + UniquePtr session = tls13_create_session_with_ticket(ssl, &body); + if (!session) { + // |tls13_create_session_with_ticket| puts the correct error. + return nullptr; + } + return session.release(); +} + +int SSL_set_tlsext_status_type(SSL *ssl, int type) { + if (!ssl->config) { + return 0; + } + ssl->config->ocsp_stapling_enabled = type == TLSEXT_STATUSTYPE_ocsp; + return 1; +} + +int SSL_get_tlsext_status_type(const SSL *ssl) { + if (ssl->server) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + return hs != nullptr && hs->ocsp_stapling_requested + ? TLSEXT_STATUSTYPE_ocsp + : TLSEXT_STATUSTYPE_nothing; + } + + return ssl->config != nullptr && ssl->config->ocsp_stapling_enabled + ? TLSEXT_STATUSTYPE_ocsp + : TLSEXT_STATUSTYPE_nothing; +} + +int SSL_set_tlsext_status_ocsp_resp(SSL *ssl, uint8_t *resp, size_t resp_len) { + if (SSL_set_ocsp_response(ssl, resp, resp_len)) { + OPENSSL_free(resp); + return 1; + } + return 0; +} + +size_t SSL_get_tlsext_status_ocsp_resp(const SSL *ssl, const uint8_t **out) { + size_t ret; + SSL_get0_ocsp_response(ssl, out, &ret); + return ret; +} + +int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx, + int (*callback)(SSL *ssl, void *arg)) { + ctx->legacy_ocsp_callback = callback; + return 1; +} + +int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) { + ctx->legacy_ocsp_callback_arg = arg; + return 1; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc new file mode 100644 index 00000000..3b87f722 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_privkey.cc @@ -0,0 +1,837 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +bool ssl_is_key_type_supported(int key_type) { + return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC || + key_type == EVP_PKEY_ED25519; +} + +static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) { + if (!ssl_is_key_type_supported(pkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return false; + } + + if (cert->chain != nullptr && + sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) != nullptr && + // Sanity-check that the private key and the certificate match. + !ssl_cert_check_private_key(cert, pkey)) { + return false; + } + + cert->privatekey = UpRef(pkey); + return true; +} + +typedef struct { + uint16_t sigalg; + int pkey_type; + int curve; + const EVP_MD *(*digest_func)(void); + bool is_rsa_pss; +} SSL_SIGNATURE_ALGORITHM; + +static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = { + {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1, + false}, + {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1, false}, + {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, false}, + {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, false}, + {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, false}, + + {SSL_SIGN_RSA_PSS_RSAE_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, true}, + {SSL_SIGN_RSA_PSS_RSAE_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, true}, + {SSL_SIGN_RSA_PSS_RSAE_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, true}, + + {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1, false}, + {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1, + &EVP_sha256, false}, + {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384, + false}, + {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512, + false}, + + {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, nullptr, false}, +}; + +static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) { + if (kSignatureAlgorithms[i].sigalg == sigalg) { + return &kSignatureAlgorithms[i]; + } + } + return NULL; +} + +bool ssl_has_private_key(const SSL_HANDSHAKE *hs) { + if (hs->config->cert->privatekey != nullptr || + hs->config->cert->key_method != nullptr || + ssl_signing_with_dc(hs)) { + return true; + } + + return false; +} + +static bool pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey, + uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == NULL || + EVP_PKEY_id(pkey) != alg->pkey_type) { + return false; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // RSA keys may only be used with RSA-PSS. + if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) { + return false; + } + + // EC keys have a curve requirement. + if (alg->pkey_type == EVP_PKEY_EC && + (alg->curve == NID_undef || + EC_GROUP_get_curve_name( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) { + return false; + } + } + + return true; +} + +static bool setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey, + uint16_t sigalg, bool is_verify) { + if (!pkey_supports_algorithm(ssl, pkey, sigalg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + return false; + } + + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL; + EVP_PKEY_CTX *pctx; + if (is_verify) { + if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) { + return false; + } + } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) { + return false; + } + + if (alg->is_rsa_pss) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) { + return false; + } + } + + return true; +} + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in) { + SSL *const ssl = hs->ssl; + const SSL_PRIVATE_KEY_METHOD *key_method = hs->config->cert->key_method; + EVP_PKEY *privatekey = hs->config->cert->privatekey.get(); + assert(!hs->can_release_private_key); + if (ssl_signing_with_dc(hs)) { + key_method = hs->config->cert->dc_key_method; + privatekey = hs->config->cert->dc_privatekey.get(); + } + + if (key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = key_method->complete(ssl, out, out_len, max_out); + } else { + ret = key_method->sign(ssl, out, out_len, max_out, + sigalg, in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + *out_len = max_out; + ScopedEVP_MD_CTX ctx; + if (!setup_ctx(ssl, ctx.get(), privatekey, sigalg, false /* sign */) || + !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in) { + ScopedEVP_MD_CTX ctx; + if (!setup_ctx(ssl, ctx.get(), pkey, sigalg, true /* verify */)) { + return false; + } + bool ok = EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), + in.data(), in.size()); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; + ERR_clear_error(); +#endif + return ok; +} + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in) { + SSL *const ssl = hs->ssl; + assert(!hs->can_release_private_key); + if (hs->config->cert->key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = hs->config->cert->key_method->complete(ssl, out, out_len, max_out); + } else { + ret = hs->config->cert->key_method->decrypt(ssl, out, out_len, max_out, + in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + RSA *rsa = EVP_PKEY_get0_RSA(hs->config->cert->privatekey.get()); + if (rsa == NULL) { + // Decrypt operations are only supported for RSA keys. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code by the caller. + if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(), + RSA_NO_PADDING)) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg) { + SSL *const ssl = hs->ssl; + if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) { + return false; + } + + // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that + // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the + // hash in TLS. Reasonable RSA key sizes are large enough for the largest + // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for + // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the + // size so that we can fall back to another algorithm in that case. + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) < + 2 * EVP_MD_size(alg->digest_func()) + 2) { + return false; + } + + return true; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { + if (rsa == NULL || ssl->config == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ssl->config->cert.get(), pkey.get()); +} + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_RSAPrivateKey(ssl, rsa.get()); +} + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { + if (pkey == NULL || ssl->config == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ssl->config->cert.get(), pkey); +} + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_PrivateKey(ssl, pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ctx->cert.get(), pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get()); +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ctx->cert.get(), pkey); +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_PrivateKey(ctx, pkey.get()); +} + +void SSL_set_private_key_method(SSL *ssl, + const SSL_PRIVATE_KEY_METHOD *key_method) { + if (!ssl->config) { + return; + } + ssl->config->cert->key_method = key_method; +} + +void SSL_CTX_set_private_key_method(SSL_CTX *ctx, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ctx->cert->key_method = key_method; +} + +static constexpr size_t kMaxSignatureAlgorithmNameLen = 23; + +// This was "constexpr" rather than "const", but that triggered a bug in MSVC +// where it didn't pad the strings to the correct length. +static const struct { + uint16_t signature_algorithm; + const char name[kMaxSignatureAlgorithmNameLen]; +} kSignatureAlgorithmNames[] = { + {SSL_SIGN_RSA_PKCS1_MD5_SHA1, "rsa_pkcs1_md5_sha1"}, + {SSL_SIGN_RSA_PKCS1_SHA1, "rsa_pkcs1_sha1"}, + {SSL_SIGN_RSA_PKCS1_SHA256, "rsa_pkcs1_sha256"}, + {SSL_SIGN_RSA_PKCS1_SHA384, "rsa_pkcs1_sha384"}, + {SSL_SIGN_RSA_PKCS1_SHA512, "rsa_pkcs1_sha512"}, + {SSL_SIGN_ECDSA_SHA1, "ecdsa_sha1"}, + {SSL_SIGN_ECDSA_SECP256R1_SHA256, "ecdsa_secp256r1_sha256"}, + {SSL_SIGN_ECDSA_SECP384R1_SHA384, "ecdsa_secp384r1_sha384"}, + {SSL_SIGN_ECDSA_SECP521R1_SHA512, "ecdsa_secp521r1_sha512"}, + {SSL_SIGN_RSA_PSS_RSAE_SHA256, "rsa_pss_rsae_sha256"}, + {SSL_SIGN_RSA_PSS_RSAE_SHA384, "rsa_pss_rsae_sha384"}, + {SSL_SIGN_RSA_PSS_RSAE_SHA512, "rsa_pss_rsae_sha512"}, + {SSL_SIGN_ED25519, "ed25519"}, +}; + +const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve) { + if (!include_curve) { + switch (sigalg) { + case SSL_SIGN_ECDSA_SECP256R1_SHA256: + return "ecdsa_sha256"; + case SSL_SIGN_ECDSA_SECP384R1_SHA384: + return "ecdsa_sha384"; + case SSL_SIGN_ECDSA_SECP521R1_SHA512: + return "ecdsa_sha512"; + } + } + + for (const auto &candidate : kSignatureAlgorithmNames) { + if (candidate.signature_algorithm == sigalg) { + return candidate.name; + } + } + + return NULL; +} + +int SSL_get_signature_algorithm_key_type(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE; +} + +const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == nullptr || alg->digest_func == nullptr) { + return nullptr; + } + return alg->digest_func(); +} + +int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr && alg->is_rsa_pss; +} + +int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return ctx->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); +} + +int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, + size_t num_prefs) { + if (!ssl->config) { + return 0; + } + return ssl->config->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); +} + +static constexpr struct { + int pkey_type; + int hash_nid; + uint16_t signature_algorithm; +} kSignatureAlgorithmsMapping[] = { + {EVP_PKEY_RSA, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1}, + {EVP_PKEY_RSA, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256}, + {EVP_PKEY_RSA, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384}, + {EVP_PKEY_RSA, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512}, + {EVP_PKEY_RSA_PSS, NID_sha256, SSL_SIGN_RSA_PSS_RSAE_SHA256}, + {EVP_PKEY_RSA_PSS, NID_sha384, SSL_SIGN_RSA_PSS_RSAE_SHA384}, + {EVP_PKEY_RSA_PSS, NID_sha512, SSL_SIGN_RSA_PSS_RSAE_SHA512}, + {EVP_PKEY_EC, NID_sha1, SSL_SIGN_ECDSA_SHA1}, + {EVP_PKEY_EC, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256}, + {EVP_PKEY_EC, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384}, + {EVP_PKEY_EC, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512}, + {EVP_PKEY_ED25519, NID_undef, SSL_SIGN_ED25519}, +}; + +static bool parse_sigalg_pairs(Array *out, const int *values, + size_t num_values) { + if ((num_values & 1) == 1) { + return false; + } + + const size_t num_pairs = num_values / 2; + if (!out->Init(num_pairs)) { + return false; + } + + for (size_t i = 0; i < num_values; i += 2) { + const int hash_nid = values[i]; + const int pkey_type = values[i+1]; + + bool found = false; + for (const auto &candidate : kSignatureAlgorithmsMapping) { + if (candidate.pkey_type == pkey_type && candidate.hash_nid == hash_nid) { + (*out)[i / 2] = candidate.signature_algorithm; + found = true; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("unknown hash:%d pkey:%d", hash_nid, pkey_type); + return false; + } + } + + return true; +} + +static int compare_uint16_t(const void *p1, const void *p2) { + uint16_t u1 = *((const uint16_t *)p1); + uint16_t u2 = *((const uint16_t *)p2); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +static bool sigalgs_unique(Span in_sigalgs) { + if (in_sigalgs.size() < 2) { + return true; + } + + Array sigalgs; + if (!sigalgs.CopyFrom(in_sigalgs)) { + return false; + } + + qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t); + + for (size_t i = 1; i < sigalgs.size(); i++) { + if (sigalgs[i - 1] == sigalgs[i]) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM); + return false; + } + } + + return true; +} + +int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) { + Array sigalgs; + if (!parse_sigalg_pairs(&sigalgs, values, num_values) || + !sigalgs_unique(sigalgs)) { + return 0; + } + + if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(), + sigalgs.size()) || + !ctx->verify_sigalgs.CopyFrom(sigalgs)) { + return 0; + } + + return 1; +} + +int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) { + if (!ssl->config) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + Array sigalgs; + if (!parse_sigalg_pairs(&sigalgs, values, num_values) || + !sigalgs_unique(sigalgs)) { + return 0; + } + + if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) || + !ssl->config->verify_sigalgs.CopyFrom(sigalgs)) { + return 0; + } + + return 1; +} + +static bool parse_sigalgs_list(Array *out, const char *str) { + // str looks like "RSA+SHA1:ECDSA+SHA256:ecdsa_secp256r1_sha256". + + // Count colons to give the number of output elements from any successful + // parse. + size_t num_elements = 1; + size_t len = 0; + for (const char *p = str; *p; p++) { + len++; + if (*p == ':') { + num_elements++; + } + } + + if (!out->Init(num_elements)) { + return false; + } + size_t out_i = 0; + + enum { + pkey_or_name, + hash_name, + } state = pkey_or_name; + + char buf[kMaxSignatureAlgorithmNameLen]; + // buf_used is always < sizeof(buf). I.e. it's always safe to write + // buf[buf_used] = 0. + size_t buf_used = 0; + + int pkey_type = 0, hash_nid = 0; + + // Note that the loop runs to len+1, i.e. it'll process the terminating NUL. + for (size_t offset = 0; offset < len+1; offset++) { + const unsigned char c = str[offset]; + + switch (c) { + case '+': + if (state == hash_name) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("+ found in hash name at offset %zu", offset); + return false; + } + if (buf_used == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("empty public key type at offset %zu", offset); + return false; + } + buf[buf_used] = 0; + + if (strcmp(buf, "RSA") == 0) { + pkey_type = EVP_PKEY_RSA; + } else if (strcmp(buf, "RSA-PSS") == 0 || + strcmp(buf, "PSS") == 0) { + pkey_type = EVP_PKEY_RSA_PSS; + } else if (strcmp(buf, "ECDSA") == 0) { + pkey_type = EVP_PKEY_EC; + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("unknown public key type '%s'", buf); + return false; + } + + state = hash_name; + buf_used = 0; + break; + + case ':': + OPENSSL_FALLTHROUGH; + case 0: + if (buf_used == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("empty element at offset %zu", offset); + return false; + } + + buf[buf_used] = 0; + + if (state == pkey_or_name) { + // No '+' was seen thus this is a TLS 1.3-style name. + bool found = false; + for (const auto &candidate : kSignatureAlgorithmNames) { + if (strcmp(candidate.name, buf) == 0) { + assert(out_i < num_elements); + (*out)[out_i++] = candidate.signature_algorithm; + found = true; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("unknown signature algorithm '%s'", buf); + return false; + } + } else { + if (strcmp(buf, "SHA1") == 0) { + hash_nid = NID_sha1; + } else if (strcmp(buf, "SHA256") == 0) { + hash_nid = NID_sha256; + } else if (strcmp(buf, "SHA384") == 0) { + hash_nid = NID_sha384; + } else if (strcmp(buf, "SHA512") == 0) { + hash_nid = NID_sha512; + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("unknown hash function '%s'", buf); + return false; + } + + bool found = false; + for (const auto &candidate : kSignatureAlgorithmsMapping) { + if (candidate.pkey_type == pkey_type && + candidate.hash_nid == hash_nid) { + assert(out_i < num_elements); + (*out)[out_i++] = candidate.signature_algorithm; + found = true; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("unknown pkey:%d hash:%s", pkey_type, buf); + return false; + } + } + + state = pkey_or_name; + buf_used = 0; + break; + + default: + if (buf_used == sizeof(buf) - 1) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("substring too long at offset %zu", offset); + return false; + } + + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || c == '-' || c == '_') { + buf[buf_used++] = c; + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + ERR_add_error_dataf("invalid character 0x%02x at offest %zu", c, + offset); + return false; + } + } + } + + assert(out_i == out->size()); + return true; +} + +int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) { + Array sigalgs; + if (!parse_sigalgs_list(&sigalgs, str) || + !sigalgs_unique(sigalgs)) { + return 0; + } + + if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(), + sigalgs.size()) || + !SSL_CTX_set_verify_algorithm_prefs(ctx, sigalgs.data(), + sigalgs.size())) { + return 0; + } + + return 1; +} + +int SSL_set1_sigalgs_list(SSL *ssl, const char *str) { + if (!ssl->config) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + Array sigalgs; + if (!parse_sigalgs_list(&sigalgs, str) || + !sigalgs_unique(sigalgs)) { + return 0; + } + + if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) || + !SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) { + return 0; + } + + return 1; +} + +int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return ctx->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); +} + +int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, + size_t num_prefs) { + if (!ssl->config) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return ssl->config->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_session.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_session.cc new file mode 100644 index 00000000..4677166a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_session.cc @@ -0,0 +1,1342 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +// The address of this is a magic value, a pointer to which is returned by +// SSL_magic_pending_session_ptr(). It allows a session callback to indicate +// that it needs to asynchronously fetch session information. +static const char g_pending_session_magic = 0; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session); + +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method) { + return MakeUnique(x509_method); +} + +uint32_t ssl_hash_session_id(Span session_id) { + // Take the first four bytes of |session_id|. Session IDs are generated by the + // server randomly, so we can assume even using the first four bytes results + // in a good distribution. + uint8_t tmp_storage[sizeof(uint32_t)]; + if (session_id.size() < sizeof(tmp_storage)) { + OPENSSL_memset(tmp_storage, 0, sizeof(tmp_storage)); + OPENSSL_memcpy(tmp_storage, session_id.data(), session_id.size()); + session_id = tmp_storage; + } + + uint32_t hash = + ((uint32_t)session_id[0]) | + ((uint32_t)session_id[1] << 8) | + ((uint32_t)session_id[2] << 16) | + ((uint32_t)session_id[3] << 24); + + return hash; +} + +UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { + UniquePtr new_session = ssl_session_new(session->x509_method); + if (!new_session) { + return nullptr; + } + + new_session->is_server = session->is_server; + new_session->ssl_version = session->ssl_version; + new_session->is_quic = session->is_quic; + new_session->sid_ctx_length = session->sid_ctx_length; + OPENSSL_memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length); + + // Copy the key material. + new_session->secret_length = session->secret_length; + OPENSSL_memcpy(new_session->secret, session->secret, session->secret_length); + new_session->cipher = session->cipher; + + // Copy authentication state. + if (session->psk_identity != nullptr) { + new_session->psk_identity.reset( + OPENSSL_strdup(session->psk_identity.get())); + if (new_session->psk_identity == nullptr) { + return nullptr; + } + } + if (session->certs != nullptr) { + auto buf_up_ref = [](CRYPTO_BUFFER *buf) { + CRYPTO_BUFFER_up_ref(buf); + return buf; + }; + new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy( + session->certs.get(), buf_up_ref, CRYPTO_BUFFER_free)); + if (new_session->certs == nullptr) { + return nullptr; + } + } + + if (!session->x509_method->session_dup(new_session.get(), session)) { + return nullptr; + } + + new_session->verify_result = session->verify_result; + + new_session->ocsp_response = UpRef(session->ocsp_response); + new_session->signed_cert_timestamp_list = + UpRef(session->signed_cert_timestamp_list); + + OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256, + SHA256_DIGEST_LENGTH); + new_session->peer_sha256_valid = session->peer_sha256_valid; + + new_session->peer_signature_algorithm = session->peer_signature_algorithm; + + new_session->timeout = session->timeout; + new_session->auth_timeout = session->auth_timeout; + new_session->time = session->time; + + // Copy non-authentication connection properties. + if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) { + new_session->session_id_length = session->session_id_length; + OPENSSL_memcpy(new_session->session_id, session->session_id, + session->session_id_length); + + new_session->group_id = session->group_id; + + OPENSSL_memcpy(new_session->original_handshake_hash, + session->original_handshake_hash, + session->original_handshake_hash_len); + new_session->original_handshake_hash_len = + session->original_handshake_hash_len; + new_session->ticket_lifetime_hint = session->ticket_lifetime_hint; + new_session->ticket_age_add = session->ticket_age_add; + new_session->ticket_max_early_data = session->ticket_max_early_data; + new_session->extended_master_secret = session->extended_master_secret; + new_session->has_application_settings = session->has_application_settings; + + if (!new_session->early_alpn.CopyFrom(session->early_alpn) || + !new_session->quic_early_data_context.CopyFrom( + session->quic_early_data_context) || + !new_session->local_application_settings.CopyFrom( + session->local_application_settings) || + !new_session->peer_application_settings.CopyFrom( + session->peer_application_settings)) { + return nullptr; + } + } + + // Copy the ticket. + if (dup_flags & SSL_SESSION_INCLUDE_TICKET && + !new_session->ticket.CopyFrom(session->ticket)) { + return nullptr; + } + + // The new_session does not get a copy of the ex_data. + + new_session->not_resumable = true; + return new_session; +} + +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // To avoid overflows and underflows, if we've gone back in time, update the + // time, but mark the session expired. + if (session->time > now.tv_sec) { + session->time = now.tv_sec; + session->timeout = 0; + session->auth_timeout = 0; + return; + } + + // Adjust the session time and timeouts. If the session has already expired, + // clamp the timeouts at zero. + uint64_t delta = now.tv_sec - session->time; + session->time = now.tv_sec; + if (session->timeout < delta) { + session->timeout = 0; + } else { + session->timeout -= delta; + } + if (session->auth_timeout < delta) { + session->auth_timeout = 0; + } else { + session->auth_timeout -= delta; + } +} + +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout) { + // Rebase the timestamp relative to the current time so |timeout| is measured + // correctly. + ssl_session_rebase_time(ssl, session); + + if (session->timeout > timeout) { + return; + } + + session->timeout = timeout; + if (session->timeout > session->auth_timeout) { + session->timeout = session->auth_timeout; + } +} + +uint16_t ssl_session_protocol_version(const SSL_SESSION *session) { + uint16_t ret; + if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) { + // An |SSL_SESSION| will never have an invalid version. This is enforced by + // the parser. + assert(0); + return 0; + } + + return ret; +} + +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) { + return ssl_get_handshake_digest(ssl_session_protocol_version(session), + session->cipher); +} + +bool ssl_get_new_session(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED); + return false; + } + + UniquePtr session = ssl_session_new(ssl->ctx->x509_method); + if (session == NULL) { + return false; + } + + session->is_server = ssl->server; + session->ssl_version = ssl->version; + session->is_quic = ssl->quic_method != nullptr; + + // Fill in the time from the |SSL_CTX|'s clock. + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + session->time = now.tv_sec; + + uint16_t version = ssl_protocol_version(ssl); + if (version >= TLS1_3_VERSION) { + // TLS 1.3 uses tickets as authenticators, so we are willing to use them for + // longer. + session->timeout = ssl->session_ctx->session_psk_dhe_timeout; + session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT; + } else { + // TLS 1.2 resumption does not incorporate new key material, so we use a + // much shorter timeout. + session->timeout = ssl->session_ctx->session_timeout; + session->auth_timeout = ssl->session_ctx->session_timeout; + } + + if (hs->config->cert->sid_ctx_length > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + OPENSSL_memcpy(session->sid_ctx, hs->config->cert->sid_ctx, + hs->config->cert->sid_ctx_length); + session->sid_ctx_length = hs->config->cert->sid_ctx_length; + + // The session is marked not resumable until it is completely filled in. + session->not_resumable = true; + session->verify_result = X509_V_ERR_INVALID_CALL; + + hs->new_session = std::move(session); + ssl_set_session(ssl, NULL); + return true; +} + +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { + OPENSSL_timeval now; + ssl_ctx_get_current_time(ctx, &now); + { + // Avoid acquiring a write lock in the common case (i.e. a non-default key + // is used or the default keys have not expired yet). + MutexReadLock lock(&ctx->lock); + if (ctx->ticket_key_current && + (ctx->ticket_key_current->next_rotation_tv_sec == 0 || + ctx->ticket_key_current->next_rotation_tv_sec > now.tv_sec) && + (!ctx->ticket_key_prev || + ctx->ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) { + return 1; + } + } + + MutexWriteLock lock(&ctx->lock); + if (!ctx->ticket_key_current || + (ctx->ticket_key_current->next_rotation_tv_sec != 0 && + ctx->ticket_key_current->next_rotation_tv_sec <= now.tv_sec)) { + // The current key has not been initialized or it is expired. + auto new_key = bssl::MakeUnique(); + if (!new_key) { + return 0; + } + RAND_bytes(new_key->name, 16); + RAND_bytes(new_key->hmac_key, 16); + RAND_bytes(new_key->aes_key, 16); + new_key->next_rotation_tv_sec = + now.tv_sec + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + if (ctx->ticket_key_current) { + // The current key expired. Rotate it to prev and bump up its rotation + // timestamp. Note that even with the new rotation time it may still be + // expired and get dropped below. + ctx->ticket_key_current->next_rotation_tv_sec += + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + ctx->ticket_key_prev = std::move(ctx->ticket_key_current); + } + ctx->ticket_key_current = std::move(new_key); + } + + // Drop an expired prev key. + if (ctx->ticket_key_prev && + ctx->ticket_key_prev->next_rotation_tv_sec <= now.tv_sec) { + ctx->ticket_key_prev.reset(); + } + + return 1; +} + +static int ssl_encrypt_ticket_with_cipher_ctx(SSL_HANDSHAKE *hs, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + ScopedEVP_CIPHER_CTX ctx; + ScopedHMAC_CTX hctx; + + // If the session is too long, emit a dummy value rather than abort the + // connection. + static const size_t kMaxTicketOverhead = + 16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE; + if (session_len > 0xffff - kMaxTicketOverhead) { + static const char kTicketPlaceholder[] = "TICKET TOO LARGE"; + return CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder, + strlen(kTicketPlaceholder)); + } + + // Initialize HMAC and cipher contexts. If callback present it does all the + // work otherwise use generated values from parent ctx. + SSL_CTX *tctx = hs->ssl->session_ctx.get(); + uint8_t iv[EVP_MAX_IV_LENGTH]; + uint8_t key_name[16]; + if (tctx->ticket_key_cb != NULL) { + if (tctx->ticket_key_cb(hs->ssl, key_name, iv, ctx.get(), hctx.get(), + 1 /* encrypt */) < 0) { + return 0; + } + } else { + // Rotate ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(tctx)) { + return 0; + } + MutexReadLock lock(&tctx->lock); + if (!RAND_bytes(iv, 16) || + !EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL, + tctx->ticket_key_current->aes_key, iv) || + !HMAC_Init_ex(hctx.get(), tctx->ticket_key_current->hmac_key, 16, + tlsext_tick_md(), NULL)) { + return 0; + } + OPENSSL_memcpy(key_name, tctx->ticket_key_current->name, 16); + } + + uint8_t *ptr; + if (!CBB_add_bytes(out, key_name, 16) || + !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(ctx.get())) || + !CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) { + return 0; + } + + size_t total = 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + OPENSSL_memcpy(ptr, session_buf, session_len); + total = session_len; +#else + int len; + if (!EVP_EncryptUpdate(ctx.get(), ptr + total, &len, session_buf, session_len)) { + return 0; + } + total += len; + if (!EVP_EncryptFinal_ex(ctx.get(), ptr + total, &len)) { + return 0; + } + total += len; +#endif + if (!CBB_did_write(out, total)) { + return 0; + } + + unsigned hlen; + if (!HMAC_Update(hctx.get(), CBB_data(out), CBB_len(out)) || + !CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) || + !HMAC_Final(hctx.get(), ptr, &hlen) || + !CBB_did_write(out, hlen)) { + return 0; + } + + return 1; +} + +static int ssl_encrypt_ticket_with_method(SSL_HANDSHAKE *hs, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + SSL *const ssl = hs->ssl; + const SSL_TICKET_AEAD_METHOD *method = ssl->session_ctx->ticket_aead_method; + const size_t max_overhead = method->max_overhead(ssl); + const size_t max_out = session_len + max_overhead; + if (max_out < max_overhead) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + uint8_t *ptr; + if (!CBB_reserve(out, &ptr, max_out)) { + return 0; + } + + size_t out_len; + if (!method->seal(ssl, ptr, &out_len, max_out, session_buf, + session_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TICKET_ENCRYPTION_FAILED); + return 0; + } + + if (!CBB_did_write(out, out_len)) { + return 0; + } + + return 1; +} + +int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, + const SSL_SESSION *session) { + // Serialize the SSL_SESSION to be encoded into the ticket. + uint8_t *session_buf = NULL; + size_t session_len; + if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) { + return -1; + } + + int ret = 0; + if (hs->ssl->session_ctx->ticket_aead_method) { + ret = ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len); + } else { + ret = ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf, session_len); + } + + OPENSSL_free(session_buf); + return ret; +} + +int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + return session->sid_ctx_length == hs->config->cert->sid_ctx_length && + OPENSSL_memcmp(session->sid_ctx, hs->config->cert->sid_ctx, + hs->config->cert->sid_ctx_length) == 0; +} + +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Reject tickets from the future to avoid underflow. + if (now.tv_sec < session->time) { + return 0; + } + + return session->timeout > now.tv_sec - session->time; +} + +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { + const SSL *const ssl = hs->ssl; + return ssl_session_is_context_valid(hs, session) && + // The session must have been created by the same type of end point as + // we're now using it with. + ssl->server == session->is_server && + // The session must not be expired. + ssl_session_is_time_valid(ssl, session) && + // Only resume if the session's version matches the negotiated + // version. + ssl->version == session->ssl_version && + // Only resume if the session's cipher matches the negotiated one. This + // is stricter than necessary for TLS 1.3, which allows cross-cipher + // resumption if the PRF hashes match. We require an exact match for + // simplicity. If loosening this, the 0-RTT accept logic must be + // updated to check the cipher. + hs->new_cipher == session->cipher && + // If the session contains a client certificate (either the full + // certificate or just the hash) then require that the form of the + // certificate matches the current configuration. + ((sk_CRYPTO_BUFFER_num(session->certs.get()) == 0 && + !session->peer_sha256_valid) || + session->peer_sha256_valid == + hs->config->retain_only_sha256_of_client_certs) && + // Only resume if the underlying transport protocol hasn't changed. + // This is to prevent cross-protocol resumption between QUIC and TCP. + (hs->ssl->quic_method != nullptr) == session->is_quic; +} + +// ssl_lookup_session looks up |session_id| in the session cache and sets +// |*out_session| to an |SSL_SESSION| object if found. +static enum ssl_hs_wait_t ssl_lookup_session( + SSL_HANDSHAKE *hs, UniquePtr *out_session, + Span session_id) { + SSL *const ssl = hs->ssl; + out_session->reset(); + + if (session_id.empty() || session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_hs_ok; + } + + UniquePtr session; + // Try the internal cache, if it exists. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + uint32_t hash = ssl_hash_session_id(session_id); + auto cmp = [](const void *key, const SSL_SESSION *sess) -> int { + Span key_id = + *reinterpret_cast *>(key); + Span sess_id = + MakeConstSpan(sess->session_id, sess->session_id_length); + return key_id == sess_id ? 0 : 1; + }; + MutexReadLock lock(&ssl->session_ctx->lock); + // |lh_SSL_SESSION_retrieve_key| returns a non-owning pointer. + session = UpRef(lh_SSL_SESSION_retrieve_key(ssl->session_ctx->sessions, + &session_id, hash, cmp)); + // TODO(davidben): This should probably move it to the front of the list. + } + + // Fall back to the external cache, if it exists. + if (!session && ssl->session_ctx->get_session_cb != nullptr) { + int copy = 1; + session.reset(ssl->session_ctx->get_session_cb(ssl, session_id.data(), + session_id.size(), ©)); + if (!session) { + return ssl_hs_ok; + } + + if (session.get() == SSL_magic_pending_session_ptr()) { + session.release(); // This pointer is not actually owned. + return ssl_hs_pending_session; + } + + // Increment reference count now if the session callback asks us to do so + // (note that if the session structures returned by the callback are shared + // between threads, it must handle the reference count itself [i.e. copy == + // 0], or things won't be thread-safe). + if (copy) { + SSL_SESSION_up_ref(session.get()); + } + + // Add the externally cached session to the internal cache if necessary. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) { + SSL_CTX_add_session(ssl->session_ctx.get(), session.get()); + } + } + + if (session && !ssl_session_is_time_valid(ssl, session.get())) { + // The session was from the cache, so remove it. + SSL_CTX_remove_session(ssl->session_ctx.get(), session.get()); + session.reset(); + } + + *out_session = std::move(session); + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_get_prev_session(SSL_HANDSHAKE *hs, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello) { + // This is used only by servers. + assert(hs->ssl->server); + UniquePtr session; + bool renew_ticket = false; + + // If tickets are disabled, always behave as if no tickets are present. + CBS ticket; + const bool tickets_supported = + !(SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) && + ssl_client_hello_get_extension(client_hello, &ticket, + TLSEXT_TYPE_session_ticket); + if (tickets_supported && CBS_len(&ticket) != 0) { + switch (ssl_process_ticket(hs, &session, &renew_ticket, ticket, + MakeConstSpan(client_hello->session_id, + client_hello->session_id_len))) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_ignore_ticket: + assert(!session); + break; + case ssl_ticket_aead_error: + return ssl_hs_error; + case ssl_ticket_aead_retry: + return ssl_hs_pending_ticket; + } + } else { + // The client didn't send a ticket, so the session ID is a real ID. + enum ssl_hs_wait_t lookup_ret = ssl_lookup_session( + hs, &session, + MakeConstSpan(client_hello->session_id, client_hello->session_id_len)); + if (lookup_ret != ssl_hs_ok) { + return lookup_ret; + } + } + + *out_session = std::move(session); + *out_tickets_supported = tickets_supported; + *out_renew_ticket = renew_ticket; + return ssl_hs_ok; +} + +static bool remove_session(SSL_CTX *ctx, SSL_SESSION *session, bool lock) { + if (session == nullptr || session->session_id_length == 0) { + return false; + } + + if (lock) { + CRYPTO_MUTEX_lock_write(&ctx->lock); + } + + SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, session); + bool found = found_session == session; + if (found) { + found_session = lh_SSL_SESSION_delete(ctx->sessions, session); + SSL_SESSION_list_remove(ctx, session); + } + + if (lock) { + CRYPTO_MUTEX_unlock_write(&ctx->lock); + } + + if (found) { + // TODO(https://crbug.com/boringssl/251): Callbacks should not be called + // under a lock. + if (ctx->remove_session_cb != nullptr) { + ctx->remove_session_cb(ctx, found_session); + } + SSL_SESSION_free(found_session); + } + + return found; +} + +void ssl_set_session(SSL *ssl, SSL_SESSION *session) { + if (ssl->session.get() == session) { + return; + } + + ssl->session = UpRef(session); +} + +// locked by SSL_CTX in the calling function +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next == NULL || session->prev == NULL) { + return; + } + + if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) { + // last element in list + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + // only one element in list + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = session->prev; + session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + // first element in list + ctx->session_cache_head = session->next; + session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { // middle of list + session->next->prev = session->prev; + session->prev->next = session->next; + } + } + session->prev = session->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next != NULL && session->prev != NULL) { + SSL_SESSION_list_remove(ctx, session); + } + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = session; + ctx->session_cache_tail = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + session->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + session->next = ctx->session_cache_head; + session->next->prev = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = session; + } +} + +static bool add_session_locked(SSL_CTX *ctx, UniquePtr session) { + SSL_SESSION *new_session = session.get(); + SSL_SESSION *old_session; + if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, new_session)) { + return false; + } + // |ctx->sessions| took ownership of |new_session| and gave us back a + // reference to |old_session|. (|old_session| may be the same as + // |new_session|, in which case we traded identical references with + // |ctx->sessions|.) + session.release(); + session.reset(old_session); + + if (old_session != nullptr) { + if (old_session == new_session) { + // |session| was already in the cache. There are no linked list pointers + // to update. + return false; + } + + // There was a session ID collision. |old_session| was replaced with + // |session| in the hash table, so |old_session| must be removed from the + // linked list to match. + SSL_SESSION_list_remove(ctx, old_session); + } + + // This does not increment the reference count. Although |session| is inserted + // into two structures (a doubly-linked list and the hash table), |ctx| only + // takes one reference. + SSL_SESSION_list_add(ctx, new_session); + + // Enforce any cache size limits. + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (lh_SSL_SESSION_num_items(ctx->sessions) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session(ctx, ctx->session_cache_tail, + /*lock=*/false)) { + break; + } + } + } + + return true; +} + +void ssl_update_cache(SSL *ssl) { + SSL_CTX *ctx = ssl->session_ctx.get(); + SSL_SESSION *session = ssl->s3->established_session.get(); + int mode = SSL_is_server(ssl) ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_CLIENT; + if (!SSL_SESSION_is_resumable(session) || + (ctx->session_cache_mode & mode) != mode) { + return; + } + + // Clients never use the internal session cache. + if (ssl->server && + !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)) { + UniquePtr ref = UpRef(session); + bool remove_expired_sessions = false; + { + MutexWriteLock lock(&ctx->lock); + add_session_locked(ctx, std::move(ref)); + + if (!(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) { + // Automatically flush the internal session cache every 255 connections. + ctx->handshakes_since_cache_flush++; + if (ctx->handshakes_since_cache_flush >= 255) { + remove_expired_sessions = true; + ctx->handshakes_since_cache_flush = 0; + } + } + } + + if (remove_expired_sessions) { + // |SSL_CTX_flush_sessions| takes the lock we just released. We could + // merge the critical sections, but we'd then call user code under a + // lock, or compute |now| earlier, even when not flushing. + OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + SSL_CTX_flush_sessions(ctx, now.tv_sec); + } + } + + if (ctx->new_session_cb != nullptr) { + UniquePtr ref = UpRef(session); + if (ctx->new_session_cb(ssl, ref.get())) { + // |new_session_cb|'s return value signals whether it took ownership. + ref.release(); + } + } +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +ssl_session_st::ssl_session_st(const SSL_X509_METHOD *method) + : x509_method(method), + extended_master_secret(false), + peer_sha256_valid(false), + not_resumable(false), + ticket_age_add_valid(false), + is_server(false), + is_quic(false), + has_application_settings(false) { + CRYPTO_new_ex_data(&ex_data); + time = ::time(nullptr); +} + +ssl_session_st::~ssl_session_st() { + CRYPTO_free_ex_data(&g_ex_data_class, this, &ex_data); + x509_method->session_clear(this); +} + +SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { + return ssl_session_new(ctx->x509_method).release(); +} + +int SSL_SESSION_up_ref(SSL_SESSION *session) { + CRYPTO_refcount_inc(&session->references); + return 1; +} + +void SSL_SESSION_free(SSL_SESSION *session) { + if (session == NULL || + !CRYPTO_refcount_dec_and_test_zero(&session->references)) { + return; + } + + session->~ssl_session_st(); + OPENSSL_free(session); +} + +const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len) { + if (out_len != NULL) { + *out_len = session->session_id_length; + } + return session->session_id; +} + +int SSL_SESSION_set1_id(SSL_SESSION *session, const uint8_t *sid, + size_t sid_len) { + if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_TOO_LONG); + return 0; + } + + // Use memmove in case someone passes in the output of |SSL_SESSION_get_id|. + OPENSSL_memmove(session->session_id, sid, sid_len); + session->session_id_length = sid_len; + return 1; +} + +uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) { + return session->timeout; +} + +uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) { + if (session == NULL) { + // NULL should crash, but silently accept it here for compatibility. + return 0; + } + return session->time; +} + +X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) { + return session->x509_peer; +} + +const STACK_OF(CRYPTO_BUFFER) * + SSL_SESSION_get0_peer_certificates(const SSL_SESSION *session) { + return session->certs.get(); +} + +void SSL_SESSION_get0_signed_cert_timestamp_list(const SSL_SESSION *session, + const uint8_t **out, + size_t *out_len) { + if (session->signed_cert_timestamp_list) { + *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list.get()); + *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list.get()); + } else { + *out = nullptr; + *out_len = 0; + } +} + +void SSL_SESSION_get0_ocsp_response(const SSL_SESSION *session, + const uint8_t **out, size_t *out_len) { + if (session->ocsp_response) { + *out = CRYPTO_BUFFER_data(session->ocsp_response.get()); + *out_len = CRYPTO_BUFFER_len(session->ocsp_response.get()); + } else { + *out = nullptr; + *out_len = 0; + } +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out, + size_t max_out) { + // TODO(davidben): Fix secret_length's type and remove these casts. + if (max_out == 0) { + return (size_t)session->secret_length; + } + if (max_out > (size_t)session->secret_length) { + max_out = (size_t)session->secret_length; + } + OPENSSL_memcpy(out, session->secret, max_out); + return max_out; +} + +uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) { + if (session == NULL) { + return 0; + } + + session->time = time; + return time; +} + +uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) { + if (session == NULL) { + return 0; + } + + session->timeout = timeout; + session->auth_timeout = timeout; + return 1; +} + +const uint8_t *SSL_SESSION_get0_id_context(const SSL_SESSION *session, + unsigned *out_len) { + if (out_len != NULL) { + *out_len = session->sid_ctx_length; + } + return session->sid_ctx; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(session->sid_ctx) < 256, "sid_ctx_len does not fit"); + session->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(session->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) { + return ssl_session_protocol_version(session) >= TLS1_3_VERSION; +} + +int SSL_SESSION_is_resumable(const SSL_SESSION *session) { + return !session->not_resumable && + (session->session_id_length != 0 || !session->ticket.empty()); +} + +int SSL_SESSION_has_ticket(const SSL_SESSION *session) { + return !session->ticket.empty(); +} + +void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, size_t *out_len) { + if (out_ticket != nullptr) { + *out_ticket = session->ticket.data(); + } + *out_len = session->ticket.size(); +} + +int SSL_SESSION_set_ticket(SSL_SESSION *session, const uint8_t *ticket, + size_t ticket_len) { + return session->ticket.CopyFrom(MakeConstSpan(ticket, ticket_len)); +} + +uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) { + return session->ticket_lifetime_hint; +} + +const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *session) { + return session->cipher; +} + +int SSL_SESSION_has_peer_sha256(const SSL_SESSION *session) { + return session->peer_sha256_valid; +} + +void SSL_SESSION_get0_peer_sha256(const SSL_SESSION *session, + const uint8_t **out_ptr, size_t *out_len) { + if (session->peer_sha256_valid) { + *out_ptr = session->peer_sha256; + *out_len = sizeof(session->peer_sha256); + } else { + *out_ptr = nullptr; + *out_len = 0; + } +} + +int SSL_SESSION_early_data_capable(const SSL_SESSION *session) { + return ssl_session_protocol_version(session) >= TLS1_3_VERSION && + session->ticket_max_early_data != 0; +} + +SSL_SESSION *SSL_SESSION_copy_without_early_data(SSL_SESSION *session) { + if (!SSL_SESSION_early_data_capable(session)) { + return UpRef(session).release(); + } + + bssl::UniquePtr copy = + SSL_SESSION_dup(session, SSL_SESSION_DUP_ALL); + if (!copy) { + return nullptr; + } + + copy->ticket_max_early_data = 0; + // Copied sessions are non-resumable until they're completely filled in. + copy->not_resumable = session->not_resumable; + assert(!SSL_SESSION_early_data_capable(copy.get())); + return copy.release(); +} + +SSL_SESSION *SSL_magic_pending_session_ptr(void) { + return (SSL_SESSION *)&g_pending_session_magic; +} + +SSL_SESSION *SSL_get_session(const SSL *ssl) { + // Once the handshake completes we return the established session. Otherwise + // we return the intermediate session, either |session| (for resumption) or + // |new_session| if doing a full handshake. + if (!SSL_in_init(ssl)) { + return ssl->s3->established_session.get(); + } + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs->early_session) { + return hs->early_session.get(); + } + if (hs->new_session) { + return hs->new_session.get(); + } + return ssl->session.get(); +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) { + SSL_SESSION *ret = SSL_get_session(ssl); + if (ret != NULL) { + SSL_SESSION_up_ref(ret); + } + return ret; +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) { + return CRYPTO_set_ex_data(&session->ex_data, idx, arg); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) { + return CRYPTO_get_ex_data(&session->ex_data, idx); +} + +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) { + UniquePtr owned_session = UpRef(session); + MutexWriteLock lock(&ctx->lock); + return add_session_locked(ctx, std::move(owned_session)); +} + +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) { + return remove_session(ctx, session, /*lock=*/true); +} + +int SSL_set_session(SSL *ssl, SSL_SESSION *session) { + // SSL_set_session may only be called before the handshake has started. + if (ssl->s3->initial_handshake_complete || + ssl->s3->hs == NULL || + ssl->s3->hs->state != 0) { + abort(); + } + + ssl_set_session(ssl, session); + return 1; +} + +uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout) { + if (ctx == NULL) { + return 0; + } + + // Historically, zero was treated as |SSL_DEFAULT_SESSION_TIMEOUT|. + if (timeout == 0) { + timeout = SSL_DEFAULT_SESSION_TIMEOUT; + } + + uint32_t old_timeout = ctx->session_timeout; + ctx->session_timeout = timeout; + return old_timeout; +} + +uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx) { + if (ctx == NULL) { + return 0; + } + + return ctx->session_timeout; +} + +void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, uint32_t timeout) { + ctx->session_psk_dhe_timeout = timeout; +} + +typedef struct timeout_param_st { + SSL_CTX *ctx; + uint64_t time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void timeout_doall_arg(SSL_SESSION *session, void *void_param) { + TIMEOUT_PARAM *param = reinterpret_cast(void_param); + + if (param->time == 0 || + session->time + session->timeout < session->time || + param->time > (session->time + session->timeout)) { + // TODO(davidben): This can probably just call |remove_session|. + (void) lh_SSL_SESSION_delete(param->cache, session); + SSL_SESSION_list_remove(param->ctx, session); + // TODO(https://crbug.com/boringssl/251): Callbacks should not be called + // under a lock. + if (param->ctx->remove_session_cb != NULL) { + param->ctx->remove_session_cb(param->ctx, session); + } + SSL_SESSION_free(session); + } +} + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) { + TIMEOUT_PARAM tp; + + tp.ctx = ctx; + tp.cache = ctx->sessions; + if (tp.cache == NULL) { + return; + } + tp.time = time; + MutexWriteLock lock(&ctx->lock); + lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp); +} + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, SSL_SESSION *session)) { + ctx->new_session_cb = cb; +} + +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) { + return ctx->new_session_cb; +} + +void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) { + ctx->remove_session_cb = cb; +} + +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx, + SSL_SESSION *session) { + return ctx->remove_session_cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)) { + ctx->get_session_cb = cb; +} + +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, + const uint8_t *id, + int id_len, + int *out_copy) { + return ctx->get_session_cb; +} + +void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) { + ctx->info_callback = cb; +} + +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, + int value) { + return ctx->info_callback; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_stat.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_stat.cc new file mode 100644 index 00000000..e8ae728d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_stat.cc @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include + +#include "internal.h" + + +const char *SSL_state_string_long(const SSL *ssl) { + if (ssl->s3->hs == nullptr) { + return "SSL negotiation finished successfully"; + } + + return ssl->server ? ssl_server_handshake_state(ssl->s3->hs.get()) + : ssl_client_handshake_state(ssl->s3->hs.get()); +} + +const char *SSL_state_string(const SSL *ssl) { + return "!!!!!!"; +} + +const char *SSL_alert_type_string_long(int value) { + value >>= 8; + if (value == SSL3_AL_WARNING) { + return "warning"; + } else if (value == SSL3_AL_FATAL) { + return "fatal"; + } + + return "unknown"; +} + +const char *SSL_alert_type_string(int value) { + return "!"; +} + +const char *SSL_alert_desc_string(int value) { + return "!!"; +} + +const char *SSL_alert_desc_string_long(int value) { + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + return "close notify"; + + case SSL3_AD_UNEXPECTED_MESSAGE: + return "unexpected_message"; + + case SSL3_AD_BAD_RECORD_MAC: + return "bad record mac"; + + case SSL3_AD_DECOMPRESSION_FAILURE: + return "decompression failure"; + + case SSL3_AD_HANDSHAKE_FAILURE: + return "handshake failure"; + + case SSL3_AD_NO_CERTIFICATE: + return "no certificate"; + + case SSL3_AD_BAD_CERTIFICATE: + return "bad certificate"; + + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + return "unsupported certificate"; + + case SSL3_AD_CERTIFICATE_REVOKED: + return "certificate revoked"; + + case SSL3_AD_CERTIFICATE_EXPIRED: + return "certificate expired"; + + case SSL3_AD_CERTIFICATE_UNKNOWN: + return "certificate unknown"; + + case SSL3_AD_ILLEGAL_PARAMETER: + return "illegal parameter"; + + case TLS1_AD_DECRYPTION_FAILED: + return "decryption failed"; + + case TLS1_AD_RECORD_OVERFLOW: + return "record overflow"; + + case TLS1_AD_UNKNOWN_CA: + return "unknown CA"; + + case TLS1_AD_ACCESS_DENIED: + return "access denied"; + + case TLS1_AD_DECODE_ERROR: + return "decode error"; + + case TLS1_AD_DECRYPT_ERROR: + return "decrypt error"; + + case TLS1_AD_EXPORT_RESTRICTION: + return "export restriction"; + + case TLS1_AD_PROTOCOL_VERSION: + return "protocol version"; + + case TLS1_AD_INSUFFICIENT_SECURITY: + return "insufficient security"; + + case TLS1_AD_INTERNAL_ERROR: + return "internal error"; + + case SSL3_AD_INAPPROPRIATE_FALLBACK: + return "inappropriate fallback"; + + case TLS1_AD_USER_CANCELLED: + return "user canceled"; + + case TLS1_AD_NO_RENEGOTIATION: + return "no renegotiation"; + + case TLS1_AD_MISSING_EXTENSION: + return "missing extension"; + + case TLS1_AD_UNSUPPORTED_EXTENSION: + return "unsupported extension"; + + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + return "certificate unobtainable"; + + case TLS1_AD_UNRECOGNIZED_NAME: + return "unrecognized name"; + + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return "bad certificate status response"; + + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + return "bad certificate hash value"; + + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + return "unknown PSK identity"; + + case TLS1_AD_CERTIFICATE_REQUIRED: + return "certificate required"; + + case TLS1_AD_NO_APPLICATION_PROTOCOL: + return "no application protocol"; + + case TLS1_AD_ECH_REQUIRED: + return "ECH required"; + + default: + return "unknown"; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_transcript.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_transcript.cc new file mode 100644 index 00000000..288fbb5f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_transcript.cc @@ -0,0 +1,272 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include +#include + +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +SSLTranscript::SSLTranscript() {} + +SSLTranscript::~SSLTranscript() {} + +bool SSLTranscript::Init() { + buffer_.reset(BUF_MEM_new()); + if (!buffer_) { + return false; + } + + hash_.Reset(); + return true; +} + +bool SSLTranscript::InitHash(uint16_t version, const SSL_CIPHER *cipher) { + const EVP_MD *md = ssl_get_handshake_digest(version, cipher); + if (Digest() == md) { + // No need to re-hash the buffer. + return true; + } + return EVP_DigestInit_ex(hash_.get(), md, nullptr) && + EVP_DigestUpdate(hash_.get(), buffer_->data, buffer_->length); +} + +void SSLTranscript::FreeBuffer() { + buffer_.reset(); +} + +size_t SSLTranscript::DigestLen() const { + return EVP_MD_size(Digest()); +} + +const EVP_MD *SSLTranscript::Digest() const { + return EVP_MD_CTX_md(hash_.get()); +} + +bool SSLTranscript::UpdateForHelloRetryRequest() { + if (buffer_) { + buffer_->length = 0; + } + + uint8_t old_hash[EVP_MAX_MD_SIZE]; + size_t hash_len; + if (!GetHash(old_hash, &hash_len)) { + return false; + } + const uint8_t header[4] = {SSL3_MT_MESSAGE_HASH, 0, 0, + static_cast(hash_len)}; + if (!EVP_DigestInit_ex(hash_.get(), Digest(), nullptr) || + !Update(header) || + !Update(MakeConstSpan(old_hash, hash_len))) { + return false; + } + return true; +} + +bool SSLTranscript::CopyToHashContext(EVP_MD_CTX *ctx, + const EVP_MD *digest) const { + const EVP_MD *transcript_digest = Digest(); + if (transcript_digest != nullptr && + EVP_MD_type(transcript_digest) == EVP_MD_type(digest)) { + return EVP_MD_CTX_copy_ex(ctx, hash_.get()); + } + + if (buffer_) { + return EVP_DigestInit_ex(ctx, digest, nullptr) && + EVP_DigestUpdate(ctx, buffer_->data, buffer_->length); + } + + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +bool SSLTranscript::Update(Span in) { + // Depending on the state of the handshake, either the handshake buffer may be + // active, the rolling hash, or both. + if (buffer_ && + !BUF_MEM_append(buffer_.get(), in.data(), in.size())) { + return false; + } + + if (EVP_MD_CTX_md(hash_.get()) != NULL) { + EVP_DigestUpdate(hash_.get(), in.data(), in.size()); + } + + return true; +} + +bool SSLTranscript::GetHash(uint8_t *out, size_t *out_len) const { + ScopedEVP_MD_CTX ctx; + unsigned len; + if (!EVP_MD_CTX_copy_ex(ctx.get(), hash_.get()) || + !EVP_DigestFinal_ex(ctx.get(), out, &len)) { + return false; + } + *out_len = len; + return true; +} + +bool SSLTranscript::GetFinishedMAC(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + bool from_server) const { + static const char kClientLabel[] = "client finished"; + static const char kServerLabel[] = "server finished"; + auto label = from_server + ? MakeConstSpan(kServerLabel, sizeof(kServerLabel) - 1) + : MakeConstSpan(kClientLabel, sizeof(kClientLabel) - 1); + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!GetHash(digest, &digest_len)) { + return false; + } + + static const size_t kFinishedLen = 12; + if (!tls1_prf(Digest(), MakeSpan(out, kFinishedLen), + MakeConstSpan(session->secret, session->secret_length), label, + MakeConstSpan(digest, digest_len), {})) { + return false; + } + + *out_len = kFinishedLen; + return true; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_versions.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_versions.cc new file mode 100644 index 00000000..b7987ead --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_versions.cc @@ -0,0 +1,402 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { + switch (version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case TLS1_3_VERSION: + *out = version; + return true; + + case DTLS1_VERSION: + // DTLS 1.0 is analogous to TLS 1.1, not TLS 1.0. + *out = TLS1_1_VERSION; + return true; + + case DTLS1_2_VERSION: + *out = TLS1_2_VERSION; + return true; + + default: + return false; + } +} + +// The follow arrays are the supported versions for TLS and DTLS, in order of +// decreasing preference. + +static const uint16_t kTLSVersions[] = { + TLS1_3_VERSION, + TLS1_2_VERSION, + TLS1_1_VERSION, + TLS1_VERSION, +}; + +static const uint16_t kDTLSVersions[] = { + DTLS1_2_VERSION, + DTLS1_VERSION, +}; + +static Span get_method_versions( + const SSL_PROTOCOL_METHOD *method) { + return method->is_dtls ? Span(kDTLSVersions) + : Span(kTLSVersions); +} + +bool ssl_method_supports_version(const SSL_PROTOCOL_METHOD *method, + uint16_t version) { + for (uint16_t supported : get_method_versions(method)) { + if (supported == version) { + return true; + } + } + return false; +} + +// The following functions map between API versions and wire versions. The +// public API works on wire versions. + +static const char *ssl_version_to_string(uint16_t version) { + switch (version) { + case TLS1_3_VERSION: + return "TLSv1.3"; + + case TLS1_2_VERSION: + return "TLSv1.2"; + + case TLS1_1_VERSION: + return "TLSv1.1"; + + case TLS1_VERSION: + return "TLSv1"; + + case DTLS1_VERSION: + return "DTLSv1"; + + case DTLS1_2_VERSION: + return "DTLSv1.2"; + + default: + return "unknown"; + } +} + +static uint16_t wire_version_to_api(uint16_t version) { + return version; +} + +// api_version_to_wire maps |version| to some representative wire version. +static bool api_version_to_wire(uint16_t *out, uint16_t version) { + // Check it is a real protocol version. + uint16_t unused; + if (!ssl_protocol_version_from_wire(&unused, version)) { + return false; + } + + *out = version; + return true; +} + +static bool set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + if (!api_version_to_wire(&version, version) || + !ssl_method_supports_version(method, version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION); + return false; + } + + *out = version; + return true; +} + +static bool set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default minimum version. + if (version == 0) { + *out = method->is_dtls ? DTLS1_VERSION : TLS1_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +static bool set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default maximum version. + if (version == 0) { + *out = method->is_dtls ? DTLS1_2_VERSION : TLS1_3_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +const struct { + uint16_t version; + uint32_t flag; +} kProtocolVersions[] = { + {TLS1_VERSION, SSL_OP_NO_TLSv1}, + {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1}, + {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2}, + {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3}, +}; + +bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version, + uint16_t *out_max_version) { + // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but + // DTLS 1.0 should be mapped to TLS 1.1. + uint32_t options = hs->ssl->options; + if (SSL_is_dtls(hs->ssl)) { + options &= ~SSL_OP_NO_TLSv1_1; + if (options & SSL_OP_NO_DTLSv1) { + options |= SSL_OP_NO_TLSv1_1; + } + } + + uint16_t min_version, max_version; + if (!ssl_protocol_version_from_wire(&min_version, + hs->config->conf_min_version) || + !ssl_protocol_version_from_wire(&max_version, + hs->config->conf_max_version)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // QUIC requires TLS 1.3. + if (hs->ssl->quic_method && min_version < TLS1_3_VERSION) { + min_version = TLS1_3_VERSION; + } + + // The |SSL_OP_NO_*| flags disable individual protocols. This has two + // problems. First, prior to TLS 1.3, the protocol can only express a + // contiguous range of versions. Second, a library consumer trying to set a + // maximum version cannot disable protocol versions that get added in a future + // version of the library. + // + // To account for both of these, OpenSSL interprets the client-side bitmask + // as a min/max range by picking the lowest contiguous non-empty range of + // enabled protocols. Note that this means it is impossible to set a maximum + // version of the higest supported TLS version in a future-proof way. + bool any_enabled = false; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) { + // Only look at the versions already enabled. + if (min_version > kProtocolVersions[i].version) { + continue; + } + if (max_version < kProtocolVersions[i].version) { + break; + } + + if (!(options & kProtocolVersions[i].flag)) { + // The minimum version is the first enabled version. + if (!any_enabled) { + any_enabled = true; + min_version = kProtocolVersions[i].version; + } + continue; + } + + // If there is a disabled version after the first enabled one, all versions + // after it are implicitly disabled. + if (any_enabled) { + max_version = kProtocolVersions[i-1].version; + break; + } + } + + if (!any_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED); + return false; + } + + *out_min_version = min_version; + *out_max_version = max_version; + return true; +} + +static uint16_t ssl_version(const SSL *ssl) { + // In early data, we report the predicted version. + if (SSL_in_early_data(ssl) && !ssl->server) { + return ssl->s3->hs->early_session->ssl_version; + } + return ssl->version; +} + +uint16_t ssl_protocol_version(const SSL *ssl) { + assert(ssl->s3->have_version); + uint16_t version; + if (!ssl_protocol_version_from_wire(&version, ssl->version)) { + // |ssl->version| will always be set to a valid version. + assert(0); + return 0; + } + + return version; +} + +bool ssl_supports_version(const SSL_HANDSHAKE *hs, uint16_t version) { + const SSL *const ssl = hs->ssl; + uint16_t protocol_version; + if (!ssl_method_supports_version(ssl->method, version) || + !ssl_protocol_version_from_wire(&protocol_version, version) || + hs->min_version > protocol_version || + protocol_version > hs->max_version) { + return false; + } + + return true; +} + +bool ssl_add_supported_versions(const SSL_HANDSHAKE *hs, CBB *cbb, + uint16_t extra_min_version) { + for (uint16_t version : get_method_versions(hs->ssl->method)) { + uint16_t protocol_version; + if (ssl_supports_version(hs, version) && + ssl_protocol_version_from_wire(&protocol_version, version) && + protocol_version >= extra_min_version && // + !CBB_add_u16(cbb, version)) { + return false; + } + } + return true; +} + +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions) { + for (uint16_t version : get_method_versions(hs->ssl->method)) { + if (!ssl_supports_version(hs, version)) { + continue; + } + + // JDK 11, prior to 11.0.2, has a buggy TLS 1.3 implementation which fails + // to send SNI when offering 1.3 sessions. Disable TLS 1.3 for such + // clients. We apply this logic here rather than |ssl_supports_version| so + // the downgrade signal continues to query the true capabilities. (The + // workaround is a limitation of the peer's capabilities rather than our + // own.) + // + // See https://bugs.openjdk.java.net/browse/JDK-8211806. + if (version == TLS1_3_VERSION && hs->apply_jdk11_workaround) { + continue; + } + + CBS copy = *peer_versions; + while (CBS_len(©) != 0) { + uint16_t peer_version; + if (!CBS_get_u16(©, &peer_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (peer_version == version) { + *out_version = version; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return false; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_min_version(ctx->method, &ctx->conf_min_version, version); +} + +int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_max_version(ctx->method, &ctx->conf_max_version, version); +} + +uint16_t SSL_CTX_get_min_proto_version(const SSL_CTX *ctx) { + return ctx->conf_min_version; +} + +uint16_t SSL_CTX_get_max_proto_version(const SSL_CTX *ctx) { + return ctx->conf_max_version; +} + +int SSL_set_min_proto_version(SSL *ssl, uint16_t version) { + if (!ssl->config) { + return 0; + } + return set_min_version(ssl->method, &ssl->config->conf_min_version, version); +} + +int SSL_set_max_proto_version(SSL *ssl, uint16_t version) { + if (!ssl->config) { + return 0; + } + return set_max_version(ssl->method, &ssl->config->conf_max_version, version); +} + +uint16_t SSL_get_min_proto_version(const SSL *ssl) { + if (!ssl->config) { + return 0; + } + return ssl->config->conf_min_version; +} + +uint16_t SSL_get_max_proto_version(const SSL *ssl) { + if (!ssl->config) { + return 0; + } + return ssl->config->conf_max_version; +} + +int SSL_version(const SSL *ssl) { + return wire_version_to_api(ssl_version(ssl)); +} + +const char *SSL_get_version(const SSL *ssl) { + return ssl_version_to_string(ssl_version(ssl)); +} + +const char *SSL_SESSION_get_version(const SSL_SESSION *session) { + return ssl_version_to_string(session->ssl_version); +} + +uint16_t SSL_SESSION_get_protocol_version(const SSL_SESSION *session) { + return wire_version_to_api(session->ssl_version); +} + +int SSL_SESSION_set_protocol_version(SSL_SESSION *session, uint16_t version) { + // This picks a representative TLS 1.3 version, but this API should only be + // used on unit test sessions anyway. + return api_version_to_wire(&session->ssl_version, version); +} + +int SSL_CTX_set_record_protocol_version(SSL_CTX *ctx, int version) { + return version == 0; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_x509.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_x509.cc new file mode 100644 index 00000000..0ed6fc71 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/ssl_x509.cc @@ -0,0 +1,1380 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +// check_ssl_x509_method asserts that |ssl| has the X509-based method +// installed. Calling an X509-based method on an |ssl| with a different method +// will likely misbehave and possibly crash or leak memory. +static void check_ssl_x509_method(const SSL *ssl) { + assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method); +} + +// check_ssl_ctx_x509_method acts like |check_ssl_x509_method|, but for an +// |SSL_CTX|. +static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) { + assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method); +} + +// x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised +// contents of |x509|. +static UniquePtr x509_to_buffer(X509 *x509) { + uint8_t *buf = NULL; + int cert_len = i2d_X509(x509, &buf); + if (cert_len <= 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(buf, cert_len, NULL)); + OPENSSL_free(buf); + + return buffer; +} + +// new_leafless_chain returns a fresh stack of buffers set to {NULL}. +static UniquePtr new_leafless_chain(void) { + UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); + if (!chain || + !sk_CRYPTO_BUFFER_push(chain.get(), nullptr)) { + return nullptr; + } + + return chain; +} + +// ssl_cert_set_chain sets elements 1.. of |cert->chain| to the serialised +// forms of elements of |chain|. It returns one on success or zero on error, in +// which case no change to |cert->chain| is made. It preverses the existing +// leaf from |cert->chain|, if any. +static bool ssl_cert_set_chain(CERT *cert, STACK_OF(X509) *chain) { + UniquePtr new_chain; + + if (cert->chain != nullptr) { + new_chain.reset(sk_CRYPTO_BUFFER_new_null()); + if (!new_chain) { + return false; + } + + // |leaf| might be NULL if it's a “leafless” chain. + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain.get(), 0); + if (!PushToStack(new_chain.get(), UpRef(leaf))) { + return false; + } + } + + for (X509 *x509 : chain) { + if (!new_chain) { + new_chain = new_leafless_chain(); + if (!new_chain) { + return false; + } + } + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer || + !PushToStack(new_chain.get(), std::move(buffer))) { + return false; + } + } + + cert->chain = std::move(new_chain); + return true; +} + +static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) { + X509_free(cert->x509_leaf); + cert->x509_leaf = nullptr; +} + +static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) { + sk_X509_pop_free(cert->x509_chain, X509_free); + cert->x509_chain = nullptr; +} + +static bool ssl_crypto_x509_check_client_CA_list( + STACK_OF(CRYPTO_BUFFER) *names) { + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + UniquePtr name( + d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer))); + if (name == nullptr || + inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer)) { + return false; + } + } + + return true; +} + +static void ssl_crypto_x509_cert_clear(CERT *cert) { + ssl_crypto_x509_cert_flush_cached_leaf(cert); + ssl_crypto_x509_cert_flush_cached_chain(cert); + + X509_free(cert->x509_stash); + cert->x509_stash = nullptr; +} + +static void ssl_crypto_x509_cert_free(CERT *cert) { + ssl_crypto_x509_cert_clear(cert); + X509_STORE_free(cert->verify_store); +} + +static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) { + if (cert->verify_store != nullptr) { + X509_STORE_up_ref(cert->verify_store); + new_cert->verify_store = cert->verify_store; + } +} + +static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { + bssl::UniquePtr chain, chain_without_leaf; + if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) { + chain.reset(sk_X509_new_null()); + if (!chain) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + if (sess->is_server) { + // chain_without_leaf is only needed for server sessions. See + // |SSL_get_peer_cert_chain|. + chain_without_leaf.reset(sk_X509_new_null()); + if (!chain_without_leaf) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + } + + bssl::UniquePtr leaf; + for (CRYPTO_BUFFER *cert : sess->certs.get()) { + UniquePtr x509(X509_parse_from_buffer(cert)); + if (!x509) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + if (leaf == nullptr) { + leaf = UpRef(x509); + } else if (chain_without_leaf && + !PushToStack(chain_without_leaf.get(), UpRef(x509))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + if (!PushToStack(chain.get(), std::move(x509))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + sk_X509_pop_free(sess->x509_chain, X509_free); + sess->x509_chain = chain.release(); + + sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free); + sess->x509_chain_without_leaf = chain_without_leaf.release(); + + X509_free(sess->x509_peer); + sess->x509_peer = leaf.release(); + return true; +} + +static bool ssl_crypto_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + new_session->x509_peer = UpRef(session->x509_peer).release(); + if (session->x509_chain != nullptr) { + new_session->x509_chain = X509_chain_up_ref(session->x509_chain); + if (new_session->x509_chain == nullptr) { + return false; + } + } + if (session->x509_chain_without_leaf != nullptr) { + new_session->x509_chain_without_leaf = + X509_chain_up_ref(session->x509_chain_without_leaf); + if (new_session->x509_chain_without_leaf == nullptr) { + return false; + } + } + + return true; +} + +static void ssl_crypto_x509_session_clear(SSL_SESSION *session) { + X509_free(session->x509_peer); + session->x509_peer = nullptr; + sk_X509_pop_free(session->x509_chain, X509_free); + session->x509_chain = nullptr; + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = nullptr; +} + +static bool ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL_HANDSHAKE *hs, + uint8_t *out_alert) { + *out_alert = SSL_AD_INTERNAL_ERROR; + STACK_OF(X509) *const cert_chain = session->x509_chain; + if (cert_chain == nullptr || sk_X509_num(cert_chain) == 0) { + return false; + } + + SSL *const ssl = hs->ssl; + SSL_CTX *ssl_ctx = ssl->ctx.get(); + X509_STORE *verify_store = ssl_ctx->cert_store; + if (hs->config->cert->verify_store != nullptr) { + verify_store = hs->config->cert->verify_store; + } + + X509 *leaf = sk_X509_value(cert_chain, 0); + const char *name; + size_t name_len; + SSL_get0_ech_name_override(ssl, &name, &name_len); + UniquePtr ctx(X509_STORE_CTX_new()); + if (!ctx || + !X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain) || + !X509_STORE_CTX_set_ex_data(ctx.get(), + SSL_get_ex_data_X509_STORE_CTX_idx(), ssl) || + // We need to inherit the verify parameters. These can be determined by + // the context: if its a server it will verify SSL client certificates or + // vice versa. + !X509_STORE_CTX_set_default(ctx.get(), + ssl->server ? "ssl_client" : "ssl_server") || + // Anything non-default in "param" should overwrite anything in the ctx. + !X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx.get()), + hs->config->param) || + // ClientHelloOuter connections use a different name. + (name_len != 0 && + !X509_VERIFY_PARAM_set1_host(X509_STORE_CTX_get0_param(ctx.get()), name, + name_len))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return false; + } + + if (hs->config->verify_callback) { + X509_STORE_CTX_set_verify_cb(ctx.get(), hs->config->verify_callback); + } + + int verify_ret; + if (ssl_ctx->app_verify_callback != nullptr) { + verify_ret = + ssl_ctx->app_verify_callback(ctx.get(), ssl_ctx->app_verify_arg); + } else { + verify_ret = X509_verify_cert(ctx.get()); + } + + session->verify_result = X509_STORE_CTX_get_error(ctx.get()); + + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (verify_ret <= 0 && hs->config->verify_mode != SSL_VERIFY_NONE) { + *out_alert = SSL_alert_from_verify_result(session->verify_result); + return false; + } + + ERR_clear_error(); + return true; +} + +static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) { + sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free); + hs->cached_x509_ca_names = nullptr; +} + +static bool ssl_crypto_x509_ssl_new(SSL_HANDSHAKE *hs) { + hs->config->param = X509_VERIFY_PARAM_new(); + if (hs->config->param == nullptr) { + return false; + } + X509_VERIFY_PARAM_inherit(hs->config->param, hs->ssl->ctx->param); + return true; +} + +static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL_CONFIG *cfg) { + sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free); + cfg->cached_x509_client_CA = nullptr; +} + +static void ssl_crypto_x509_ssl_config_free(SSL_CONFIG *cfg) { + sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free); + cfg->cached_x509_client_CA = nullptr; + X509_VERIFY_PARAM_free(cfg->param); +} + +static bool ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) { + // Only build a chain if there are no intermediates configured and the feature + // isn't disabled. + if ((hs->ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || + !ssl_has_certificate(hs) || hs->config->cert->chain == NULL || + sk_CRYPTO_BUFFER_num(hs->config->cert->chain.get()) > 1) { + return true; + } + + UniquePtr leaf(X509_parse_from_buffer( + sk_CRYPTO_BUFFER_value(hs->config->cert->chain.get(), 0))); + if (!leaf) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return false; + } + + UniquePtr ctx(X509_STORE_CTX_new()); + if (!ctx || !X509_STORE_CTX_init(ctx.get(), hs->ssl->ctx->cert_store, + leaf.get(), nullptr)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return false; + } + + // Attempt to build a chain, ignoring the result. + X509_verify_cert(ctx.get()); + ERR_clear_error(); + + // Remove the leaf from the generated chain. + UniquePtr chain(X509_STORE_CTX_get1_chain(ctx.get())); + if (!chain) { + return false; + } + X509_free(sk_X509_shift(chain.get())); + + if (!ssl_cert_set_chain(hs->config->cert.get(), chain.get())) { + return false; + } + + ssl_crypto_x509_cert_flush_cached_chain(hs->config->cert.get()); + + return true; +} + +static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) { + sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free); + ctx->cached_x509_client_CA = nullptr; +} + +static bool ssl_crypto_x509_ssl_ctx_new(SSL_CTX *ctx) { + ctx->cert_store = X509_STORE_new(); + ctx->param = X509_VERIFY_PARAM_new(); + return (ctx->cert_store != nullptr && ctx->param != nullptr); +} + +static void ssl_crypto_x509_ssl_ctx_free(SSL_CTX *ctx) { + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + X509_VERIFY_PARAM_free(ctx->param); + X509_STORE_free(ctx->cert_store); +} + +const SSL_X509_METHOD ssl_crypto_x509_method = { + ssl_crypto_x509_check_client_CA_list, + ssl_crypto_x509_cert_clear, + ssl_crypto_x509_cert_free, + ssl_crypto_x509_cert_dup, + ssl_crypto_x509_cert_flush_cached_chain, + ssl_crypto_x509_cert_flush_cached_leaf, + ssl_crypto_x509_session_cache_objects, + ssl_crypto_x509_session_dup, + ssl_crypto_x509_session_clear, + ssl_crypto_x509_session_verify_cert_chain, + ssl_crypto_x509_hs_flush_cached_ca_names, + ssl_crypto_x509_ssl_new, + ssl_crypto_x509_ssl_config_free, + ssl_crypto_x509_ssl_flush_cached_client_CA, + ssl_crypto_x509_ssl_auto_chain_if_needed, + ssl_crypto_x509_ssl_ctx_new, + ssl_crypto_x509_ssl_ctx_free, + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA, +}; + +BSSL_NAMESPACE_END + +using namespace bssl; + +X509 *SSL_get_peer_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || session->x509_peer == NULL) { + return NULL; + } + X509_up_ref(session->x509_peer); + return session->x509_peer; +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == nullptr) { + return nullptr; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == nullptr) { + return nullptr; + } + + // OpenSSL historically didn't include the leaf certificate in the returned + // certificate chain, but only for servers. + return ssl->server ? session->x509_chain_without_leaf : session->x509_chain; +} + +STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->x509_chain; +} + +int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int SSL_set_purpose(SSL *ssl, int purpose) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return X509_VERIFY_PARAM_set_purpose(ssl->config->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int SSL_set_trust(SSL *ssl, int trust) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return X509_VERIFY_PARAM_set_trust(ssl->config->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return X509_VERIFY_PARAM_set1(ssl->config->param, param); +} + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->param; +} + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return 0; + } + return ssl->config->param; +} + +int SSL_get_verify_depth(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return 0; + } + return X509_VERIFY_PARAM_get_depth(ssl->config->param); +} + +int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return 0; + } + return ssl->config->verify_callback; +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->verify_mode; +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->default_verify_callback; +} + +void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return; + } + ssl->config->verify_mode = mode; + if (callback != NULL) { + ssl->config->verify_callback = callback; + } +} + +void SSL_set_verify_depth(SSL *ssl, int depth) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return; + } + X509_VERIFY_PARAM_set_depth(ssl->config->param, depth); +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb)(X509_STORE_CTX *store_ctx, + void *arg), + void *arg) { + check_ssl_ctx_x509_method(ctx); + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} + +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*cb)(int, X509_STORE_CTX *)) { + check_ssl_ctx_x509_method(ctx); + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { + check_ssl_ctx_x509_method(ctx); + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_set_default_paths(ctx->cert_store); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, + const char *ca_dir) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); +} + +long SSL_get_verify_result(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return X509_V_ERR_INVALID_CALL; + } + return session->verify_result; +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->cert_store; +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +static int ssl_use_certificate(CERT *cert, X509 *x) { + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr buffer = x509_to_buffer(x); + if (!buffer) { + return 0; + } + + return ssl_set_cert(cert, std::move(buffer)); +} + +int SSL_use_certificate(SSL *ssl, X509 *x) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return ssl_use_certificate(ssl->config->cert.get(), x); +} + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { + check_ssl_ctx_x509_method(ctx); + return ssl_use_certificate(ctx->cert.get(), x); +} + +// ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the +// first element of |cert->chain|. +static int ssl_cert_cache_leaf_cert(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_leaf != NULL || + cert->chain == NULL) { + return 1; + } + + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain.get(), 0); + if (!leaf) { + return 1; + } + + cert->x509_leaf = X509_parse_from_buffer(leaf); + return cert->x509_leaf != NULL; +} + +static X509 *ssl_cert_get0_leaf(CERT *cert) { + if (cert->x509_leaf == NULL && + !ssl_cert_cache_leaf_cert(cert)) { + return NULL; + } + + return cert->x509_leaf; +} + +X509 *SSL_get_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return 0; + } + return ssl_cert_get0_leaf(ssl->config->cert.get()); +} + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + return ssl_cert_get0_leaf(ctx->cert.get()); +} + +static int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + sk_X509_pop_free(chain, X509_free); + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_append_cert(CERT *cert, X509 *x509) { + assert(cert->x509_method); + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer) { + return 0; + } + + if (cert->chain != NULL) { + return PushToStack(cert->chain.get(), std::move(buffer)); + } + + cert->chain = new_leafless_chain(); + if (!cert->chain || + !PushToStack(cert->chain.get(), std::move(buffer))) { + cert->chain.reset(); + return 0; + } + + return 1; +} + +static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + X509_free(cert->x509_stash); + cert->x509_stash = x509; + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set0_chain(ctx->cert.get(), chain); +} + +int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set1_chain(ctx->cert.get(), chain); +} + +int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return ssl_cert_set0_chain(ssl->config->cert.get(), chain); +} + +int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return ssl_cert_set1_chain(ssl->config->cert.get(), chain); +} + +int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add0_chain_cert(ctx->cert.get(), x509); +} + +int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add1_chain_cert(ctx->cert.get(), x509); +} + +int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_add0_chain_cert(ctx, x509); +} + +int SSL_add0_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return ssl_cert_add0_chain_cert(ssl->config->cert.get(), x509); +} + +int SSL_add1_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return ssl_cert_add1_chain_cert(ssl->config->cert.get(), x509); +} + +int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_set0_chain(ctx, NULL); +} + +int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_clear_chain_certs(ctx); +} + +int SSL_clear_chain_certs(SSL *ssl) { + check_ssl_x509_method(ssl); + return SSL_set0_chain(ssl, NULL); +} + +// ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of +// |cert->chain|. +static int ssl_cert_cache_chain_certs(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_chain != nullptr || + cert->chain == nullptr || + sk_CRYPTO_BUFFER_num(cert->chain.get()) < 2) { + return 1; + } + + UniquePtr chain(sk_X509_new_null()); + if (!chain) { + return 0; + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain.get()); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cert->chain.get(), i); + UniquePtr x509(X509_parse_from_buffer(buffer)); + if (!x509 || + !PushToStack(chain.get(), std::move(x509))) { + return 0; + } + } + + cert->x509_chain = chain.release(); + return 1; +} + +int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + if (!ssl_cert_cache_chain_certs(ctx->cert.get())) { + *out_chain = NULL; + return 0; + } + + *out_chain = ctx->cert->x509_chain; + return 1; +} + +int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain) { + return SSL_CTX_get0_chain_certs(ctx, out_chain); +} + +int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return 0; + } + if (!ssl_cert_cache_chain_certs(ssl->config->cert.get())) { + *out_chain = NULL; + return 0; + } + + *out_chain = ssl->config->cert->x509_chain; + return 1; +} + +SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) { + uint8_t *data; + size_t len; + if (!BIO_read_asn1(bio, &data, &len, 1024 * 1024)) { + return 0; + } + bssl::UniquePtr free_data(data); + const uint8_t *ptr = data; + return d2i_SSL_SESSION(out, &ptr, static_cast(len)); +} + +int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) { + uint8_t *data; + size_t len; + if (!SSL_SESSION_to_bytes(session, &data, &len)) { + return 0; + } + bssl::UniquePtr free_data(data); + return BIO_write_all(bio, data, len); +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) + +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) { + if (length < 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *pp, length); + + UniquePtr ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method, + NULL /* no buffer pool */); + if (!ret) { + return NULL; + } + + if (a) { + SSL_SESSION_free(*a); + *a = ret.get(); + } + *pp = CBS_data(&cbs); + return ret.release(); +} + +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) { + return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free); +} + +static void set_client_CA_list(UniquePtr *ca_list, + const STACK_OF(X509_NAME) *name_list, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr buffers(sk_CRYPTO_BUFFER_new_null()); + if (!buffers) { + return; + } + + for (X509_NAME *name : name_list) { + uint8_t *outp = NULL; + int len = i2d_X509_NAME(name, &outp); + if (len < 0) { + return; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer || + !PushToStack(buffers.get(), std::move(buffer))) { + return; + } + } + + *ca_list = std::move(buffers); +} + +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return; + } + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get()); + set_client_CA_list(&ssl->config->client_CA, name_list, ssl->ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) { + check_ssl_ctx_x509_method(ctx); + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + set_client_CA_list(&ctx->client_CA, name_list, ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +static STACK_OF(X509_NAME) * + buffer_names_to_x509(const STACK_OF(CRYPTO_BUFFER) *names, + STACK_OF(X509_NAME) **cached) { + if (names == NULL) { + return NULL; + } + + if (*cached != NULL) { + return *cached; + } + + UniquePtr new_cache(sk_X509_NAME_new_null()); + if (!new_cache) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + UniquePtr name( + d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer))); + if (!name || + inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) || + !PushToStack(new_cache.get(), std::move(name))) { + return NULL; + } + } + + *cached = new_cache.release(); + return *cached; +} + +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + assert(ssl->config); + return NULL; + } + // For historical reasons, this function is used both to query configuration + // state on a server as well as handshake state on a client. However, whether + // |ssl| is a client or server is not known until explicitly configured with + // |SSL_set_connect_state|. If |do_handshake| is NULL, |ssl| is in an + // indeterminate mode and |ssl->server| is unset. + if (ssl->do_handshake != NULL && !ssl->server) { + if (ssl->s3->hs != NULL) { + return buffer_names_to_x509(ssl->s3->hs->ca_names.get(), + &ssl->s3->hs->cached_x509_ca_names); + } + + return NULL; + } + + if (ssl->config->client_CA != NULL) { + return buffer_names_to_x509( + ssl->config->client_CA.get(), + (STACK_OF(X509_NAME) **)&ssl->config->cached_x509_client_CA); + } + return SSL_CTX_get_client_CA_list(ssl->ctx.get()); +} + +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + // This is a logically const operation that may be called on multiple threads, + // so it needs to lock around updating |cached_x509_client_CA|. + MutexWriteLock lock(const_cast(&ctx->lock)); + return buffer_names_to_x509( + ctx->client_CA.get(), + const_cast(&ctx->cached_x509_client_CA)); +} + +static int add_client_CA(UniquePtr *names, X509 *x509, + CRYPTO_BUFFER_POOL *pool) { + if (x509 == NULL) { + return 0; + } + + uint8_t *outp = NULL; + int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp); + if (len < 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer) { + return 0; + } + + int alloced = 0; + if (*names == nullptr) { + names->reset(sk_CRYPTO_BUFFER_new_null()); + alloced = 1; + + if (*names == NULL) { + return 0; + } + } + + if (!PushToStack(names->get(), std::move(buffer))) { + if (alloced) { + names->reset(); + } + return 0; + } + + return 1; +} + +int SSL_add_client_CA(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + if (!add_client_CA(&ssl->config->client_CA, x509, ssl->ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_flush_cached_client_CA(ssl->config.get()); + return 1; +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + if (!add_client_CA(&ctx->client_CA, x509, ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + return 1; +} + +static int do_client_cert_cb(SSL *ssl, void *arg) { + // Should only be called during handshake, but check to be sure. + if (!ssl->config) { + assert(ssl->config); + return -1; + } + + if (ssl_has_certificate(ssl->s3->hs.get()) || + ssl->ctx->client_cert_cb == NULL) { + return 1; + } + + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey); + if (ret < 0) { + return -1; + } + UniquePtr free_x509(x509); + UniquePtr free_pkey(pkey); + + if (ret != 0) { + if (!SSL_use_certificate(ssl, x509) || + !SSL_use_PrivateKey(ssl, pkey)) { + return 0; + } + } + + return 1; +} + +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, + X509 **out_x509, + EVP_PKEY **out_pkey)) { + check_ssl_ctx_x509_method(ctx); + // Emulate the old client certificate callback with the new one. + SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, NULL); + ctx->client_cert_cb = cb; +} + +static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store, + int take_ref) { + X509_STORE_free(*store_ptr); + *store_ptr = new_store; + + if (new_store != NULL && take_ref) { + X509_STORE_up_ref(new_store); + } + + return 1; +} + +int SSL_get_ex_data_X509_STORE_CTX_idx(void) { + // The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the + // reserved app_data slot. Before ex_data was introduced, app_data was used. + // Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data| + // works. + return 0; +} + +int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 0); +} + +int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 1); +} + +int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return set_cert_store(&ssl->config->cert->verify_store, store, 0); +} + +int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return set_cert_store(&ssl->config->cert->verify_store, store, 1); +} + +int SSL_set1_host(SSL *ssl, const char *hostname) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname, + strlen(hostname)); +} + +void SSL_set_hostflags(SSL *ssl, unsigned flags) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return; + } + X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags); +} + +int SSL_alert_from_verify_result(long result) { + switch (result) { + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return SSL_AD_UNKNOWN_CA; + + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_UNTRUSTED: + case X509_V_ERR_CERT_REJECTED: + case X509_V_ERR_HOSTNAME_MISMATCH: + case X509_V_ERR_EMAIL_MISMATCH: + case X509_V_ERR_IP_ADDRESS_MISMATCH: + return SSL_AD_BAD_CERTIFICATE; + + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return SSL_AD_DECRYPT_ERROR; + + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_CRL_NOT_YET_VALID: + return SSL_AD_CERTIFICATE_EXPIRED; + + case X509_V_ERR_CERT_REVOKED: + return SSL_AD_CERTIFICATE_REVOKED; + + case X509_V_ERR_UNSPECIFIED: + case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: + return SSL_AD_INTERNAL_ERROR; + + case X509_V_ERR_APPLICATION_VERIFICATION: + return SSL_AD_HANDSHAKE_FAILURE; + + case X509_V_ERR_INVALID_PURPOSE: + return SSL_AD_UNSUPPORTED_CERTIFICATE; + + default: + return SSL_AD_CERTIFICATE_UNKNOWN; + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/t1_enc.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/t1_enc.cc new file mode 100644 index 00000000..d748b1ee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/t1_enc.cc @@ -0,0 +1,384 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/fipsmodule/tls/internal.h" +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2) { + return 1 == CRYPTO_tls1_prf(digest, out.data(), out.size(), secret.data(), + secret.size(), label.data(), label.size(), + seed1.data(), seed1.size(), seed2.data(), + seed2.size()); +} + +static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len, + size_t *out_key_len, size_t *out_iv_len, + const SSL_CIPHER *cipher) { + const EVP_AEAD *aead = NULL; + if (!ssl_cipher_get_evp_aead(&aead, out_mac_secret_len, out_iv_len, cipher, + ssl_protocol_version(ssl), SSL_is_dtls(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return false; + } + + *out_key_len = EVP_AEAD_key_length(aead); + if (*out_mac_secret_len > 0) { + // For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the + // key length reported by |EVP_AEAD_key_length| will include the MAC key + // bytes and initial implicit IV. + if (*out_key_len < *out_mac_secret_len + *out_iv_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + *out_key_len -= *out_mac_secret_len + *out_iv_len; + } + + return true; +} + +static bool generate_key_block(const SSL *ssl, Span out, + const SSL_SESSION *session) { + auto secret = MakeConstSpan(session->secret, session->secret_length); + static const char kLabel[] = "key expansion"; + auto label = MakeConstSpan(kLabel, sizeof(kLabel) - 1); + + const EVP_MD *digest = ssl_session_get_digest(session); + // Note this function assumes that |session|'s key material corresponds to + // |ssl->s3->client_random| and |ssl->s3->server_random|. + return tls1_prf(digest, out, secret, label, ssl->s3->server_random, + ssl->s3->client_random); +} + +bool tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_SESSION *session, + Span iv_override) { + size_t mac_secret_len, key_len, iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &iv_len, + session->cipher)) { + return false; + } + + // Ensure that |key_block_cache| is set up. + const size_t key_block_size = 2 * (mac_secret_len + key_len + iv_len); + if (key_block_cache->empty()) { + if (!key_block_cache->Init(key_block_size) || + !generate_key_block(ssl, MakeSpan(*key_block_cache), session)) { + return false; + } + } + assert(key_block_cache->size() == key_block_size); + + Span key_block = *key_block_cache; + Span mac_secret, key, iv; + if (direction == (ssl->server ? evp_aead_open : evp_aead_seal)) { + // Use the client write (server read) keys. + mac_secret = key_block.subspan(0, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len, iv_len); + } else { + // Use the server write (client read) keys. + mac_secret = key_block.subspan(mac_secret_len, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len + key_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len + iv_len, iv_len); + } + + if (!iv_override.empty()) { + if (iv_override.size() != iv_len) { + return false; + } + iv = iv_override; + } + + UniquePtr aead_ctx = + SSLAEADContext::Create(direction, ssl->version, SSL_is_dtls(ssl), + session->cipher, key, mac_secret, iv); + if (!aead_ctx) { + return false; + } + + if (direction == evp_aead_open) { + return ssl->method->set_read_state(ssl, ssl_encryption_application, + std::move(aead_ctx), + /*secret_for_quic=*/{}); + } + + return ssl->method->set_write_state(ssl, ssl_encryption_application, + std::move(aead_ctx), + /*secret_for_quic=*/{}); +} + +bool tls1_change_cipher_state(SSL_HANDSHAKE *hs, + evp_aead_direction_t direction) { + return tls1_configure_aead(hs->ssl, direction, &hs->key_block, + ssl_handshake_session(hs), {}); +} + +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster) { + static const char kMasterSecretLabel[] = "master secret"; + static const char kExtendedMasterSecretLabel[] = "extended master secret"; + + const SSL *ssl = hs->ssl; + auto out_span = MakeSpan(out, SSL3_MASTER_SECRET_SIZE); + if (hs->extended_master_secret) { + auto label = MakeConstSpan(kExtendedMasterSecretLabel, + sizeof(kExtendedMasterSecretLabel) - 1); + uint8_t digests[EVP_MAX_MD_SIZE]; + size_t digests_len; + if (!hs->transcript.GetHash(digests, &digests_len) || + !tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + MakeConstSpan(digests, digests_len), {})) { + return 0; + } + } else { + auto label = + MakeConstSpan(kMasterSecretLabel, sizeof(kMasterSecretLabel) - 1); + if (!tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + ssl->s3->client_random, ssl->s3->server_random)) { + return 0; + } + } + + return SSL3_MASTER_SECRET_SIZE; +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +size_t SSL_get_key_block_len(const SSL *ssl) { + // See |SSL_generate_key_block|. + if (SSL_in_init(ssl)) { + return 0; + } + + size_t mac_secret_len, key_len, fixed_iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len, + SSL_get_current_cipher(ssl))) { + ERR_clear_error(); + return 0; + } + + return 2 * (mac_secret_len + key_len + fixed_iv_len); +} + +int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { + // Which cipher state to use is ambiguous during a handshake. In particular, + // there are points where read and write states are from different epochs. + // During a handshake, before ChangeCipherSpec, the encryption states may not + // match |ssl->s3->client_random| and |ssl->s3->server_random|. + if (SSL_in_init(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return generate_key_block(ssl, MakeSpan(out, out_len), SSL_get_session(ssl)); +} + +int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, + const char *label, size_t label_len, + const uint8_t *context, size_t context_len, + int use_context) { + // Exporters may be used in False Start and server 0-RTT, where the handshake + // has progressed enough. Otherwise, they may not be used during a handshake. + if (SSL_in_init(ssl) && + !SSL_in_false_start(ssl) && + !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (!use_context) { + context = nullptr; + context_len = 0; + } + return tls13_export_keying_material( + ssl, MakeSpan(out, out_len), + MakeConstSpan(ssl->s3->exporter_secret, ssl->s3->exporter_secret_len), + MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); + } + + size_t seed_len = 2 * SSL3_RANDOM_SIZE; + if (use_context) { + if (context_len >= 1u << 16) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + seed_len += 2 + context_len; + } + Array seed; + if (!seed.Init(seed_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(seed.data(), ssl->s3->client_random, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(seed.data() + SSL3_RANDOM_SIZE, ssl->s3->server_random, + SSL3_RANDOM_SIZE); + if (use_context) { + seed[2 * SSL3_RANDOM_SIZE] = static_cast(context_len >> 8); + seed[2 * SSL3_RANDOM_SIZE + 1] = static_cast(context_len); + OPENSSL_memcpy(seed.data() + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); + } + + const SSL_SESSION *session = SSL_get_session(ssl); + const EVP_MD *digest = ssl_session_get_digest(session); + return tls1_prf(digest, MakeSpan(out, out_len), + MakeConstSpan(session->secret, session->secret_length), + MakeConstSpan(label, label_len), seed, {}); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_both.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_both.cc new file mode 100644 index 00000000..759ca64d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_both.cc @@ -0,0 +1,733 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +// kMaxKeyUpdates is the number of consecutive KeyUpdates that will be +// processed. Without this limit an attacker could force unbounded processing +// without being able to return application data. +static const uint8_t kMaxKeyUpdates = 32; + +const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, + 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, + 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, +}; + +// See RFC 8446, section 4.1.3. +const uint8_t kTLS12DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e, + 0x47, 0x52, 0x44, 0x00}; +const uint8_t kTLS13DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e, + 0x47, 0x52, 0x44, 0x01}; + +// This is a non-standard randomly-generated value. +const uint8_t kJDK11DowngradeRandom[8] = {0xed, 0xbf, 0xb4, 0xa8, + 0xc2, 0x47, 0x10, 0xff}; + +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + for (size_t i = 0; i < 64; i++) { + if (!CBB_add_u8(cbb.get(), 0x20)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + Span context; + if (cert_verify_context == ssl_cert_verify_server) { + static const char kContext[] = "TLS 1.3, server CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_client) { + static const char kContext[] = "TLS 1.3, client CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_channel_id) { + static const char kContext[] = "TLS 1.3, Channel ID"; + context = kContext; + } else { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Note |context| includes the NUL byte separator. + if (!CBB_add_bytes(cbb.get(), + reinterpret_cast(context.data()), + context.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || + !CBBFinishArray(cbb.get(), out)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + return true; +} + +bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + bool allow_anonymous) { + SSL *const ssl = hs->ssl; + CBS body = msg.body; + bssl::UniquePtr decompressed; + + if (msg.type == SSL3_MT_COMPRESSED_CERTIFICATE) { + CBS compressed; + uint16_t alg_id; + uint32_t uncompressed_len; + + if (!CBS_get_u16(&body, &alg_id) || + !CBS_get_u24(&body, &uncompressed_len) || + !CBS_get_u24_length_prefixed(&body, &compressed) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (uncompressed_len > ssl->max_cert_list) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNCOMPRESSED_CERT_TOO_LARGE); + ERR_add_error_dataf("requested=%u", + static_cast(uncompressed_len)); + return false; + } + + ssl_cert_decompression_func_t decompress = nullptr; + for (const auto &alg : ssl->ctx->cert_compression_algs) { + if (alg.alg_id == alg_id) { + decompress = alg.decompress; + break; + } + } + + if (decompress == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERT_COMPRESSION_ALG); + ERR_add_error_dataf("alg=%d", static_cast(alg_id)); + return false; + } + + CRYPTO_BUFFER *decompressed_ptr = nullptr; + if (!decompress(ssl, &decompressed_ptr, uncompressed_len, + CBS_data(&compressed), CBS_len(&compressed))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED); + ERR_add_error_dataf("alg=%d", static_cast(alg_id)); + return false; + } + decompressed.reset(decompressed_ptr); + + if (CRYPTO_BUFFER_len(decompressed_ptr) != uncompressed_len) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED); + ERR_add_error_dataf( + "alg=%d got=%u expected=%u", static_cast(alg_id), + static_cast(CRYPTO_BUFFER_len(decompressed_ptr)), + static_cast(uncompressed_len)); + return false; + } + + CBS_init(&body, CRYPTO_BUFFER_data(decompressed_ptr), + CRYPTO_BUFFER_len(decompressed_ptr)); + } else { + assert(msg.type == SSL3_MT_CERTIFICATE); + } + + CBS context, certificate_list; + if (!CBS_get_u8_length_prefixed(&body, &context) || + CBS_len(&context) != 0 || + !CBS_get_u24_length_prefixed(&body, &certificate_list) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + UniquePtr certs(sk_CRYPTO_BUFFER_new_null()); + if (!certs) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + const bool retain_sha256 = + ssl->server && hs->config->retain_only_sha256_of_client_certs; + UniquePtr pkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate, extensions; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + !CBS_get_u16_length_prefixed(&certificate_list, &extensions) || + CBS_len(&certificate) == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return false; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + pkey = ssl_cert_parse_pubkey(&certificate); + if (!pkey) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + // TLS 1.3 always uses certificate keys for signing thus the correct + // keyUsage is enforced. + if (!ssl_cert_check_key_usage(&certificate, + key_usage_digital_signature)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return false; + } + + if (retain_sha256) { + // Retain the hash of the leaf certificate if requested. + SHA256(CBS_data(&certificate), CBS_len(&certificate), + hs->new_session->peer_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool)); + if (!buf || + !PushToStack(certs.get(), std::move(buf))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Parse out the extensions. + SSLExtension status_request( + TLSEXT_TYPE_status_request, + !ssl->server && hs->config->ocsp_stapling_enabled); + SSLExtension sct( + TLSEXT_TYPE_certificate_timestamp, + !ssl->server && hs->config->signed_cert_timestamps_enabled); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, {&status_request, &sct}, + /*ignore_unknown=*/false)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + // All Certificate extensions are parsed, but only the leaf extensions are + // stored. + if (status_request.present) { + uint8_t status_type; + CBS ocsp_response; + if (!CBS_get_u8(&status_request.data, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&status_request.data, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&status_request.data) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + hs->new_session->ocsp_response.reset( + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool)); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + } + } + + if (sct.present) { + if (!ssl_is_sct_list_valid(&sct.data)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + hs->new_session->signed_cert_timestamp_list.reset( + CRYPTO_BUFFER_new_from_CBS(&sct.data, ssl->ctx->pool)); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + } + } + } + + // Store a null certificate list rather than an empty one if the peer didn't + // send certificates. + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + certs.reset(); + } + + hs->peer_pubkey = std::move(pkey); + hs->new_session->certs = std::move(certs); + + if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) { + if (!allow_anonymous) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); + return false; + } + + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + + // No certificate, so nothing more to do. + return true; + } + + hs->new_session->peer_sha256_valid = retain_sha256; + return true; +} + +bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + if (hs->peer_pubkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + CBS body = msg.body, signature; + uint16_t signature_algorithm; + if (!CBS_get_u16(&body, &signature_algorithm) || + !CBS_get_u16_length_prefixed(&body, &signature) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(hs, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + + Array input; + if (!tls13_get_cert_verify_signature_input( + hs, &input, + ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + + if (!ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), input)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return false; + } + + return true; +} + +bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + bool use_saved_value) { + SSL *const ssl = hs->ssl; + uint8_t verify_data_buf[EVP_MAX_MD_SIZE]; + Span verify_data; + if (use_saved_value) { + assert(ssl->server); + verify_data = hs->expected_client_finished(); + } else { + size_t len; + if (!tls13_finished_mac(hs, verify_data_buf, &len, !ssl->server)) { + return false; + } + verify_data = MakeConstSpan(verify_data_buf, len); + } + + bool finished_ok = + CBS_mem_equal(&msg.body, verify_data.data(), verify_data.size()); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = true; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return false; + } + + return true; +} + +bool tls13_add_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + CERT *const cert = hs->config->cert.get(); + DC *const dc = cert->dc.get(); + + ScopedCBB cbb; + CBB *body, body_storage, certificate_list; + + if (hs->cert_compression_negotiated) { + if (!CBB_init(cbb.get(), 1024)) { + return false; + } + body = cbb.get(); + } else { + body = &body_storage; + if (!ssl->method->init_message(ssl, cbb.get(), body, SSL3_MT_CERTIFICATE)) { + return false; + } + } + + if (// The request context is always empty in the handshake. + !CBB_add_u8(body, 0) || + !CBB_add_u24_length_prefixed(body, &certificate_list)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!ssl_has_certificate(hs)) { + return ssl_add_message_cbb(ssl, cbb.get()); + } + + CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain.get(), 0); + CBB leaf, extensions; + if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || + !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf), + CRYPTO_BUFFER_len(leaf_buf)) || + !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (hs->scts_requested && cert->signed_cert_timestamp_list != nullptr) { + CBB contents; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data(cert->signed_cert_timestamp_list.get()), + CRYPTO_BUFFER_len(cert->signed_cert_timestamp_list.get())) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + if (hs->ocsp_stapling_requested && cert->ocsp_response != NULL) { + CBB contents, ocsp_response; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&contents, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, + CRYPTO_BUFFER_data(cert->ocsp_response.get()), + CRYPTO_BUFFER_len(cert->ocsp_response.get())) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + if (ssl_signing_with_dc(hs)) { + const CRYPTO_BUFFER *raw = dc->raw.get(); + CBB child; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_delegated_credential) || + !CBB_add_u16_length_prefixed(&extensions, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(raw), + CRYPTO_BUFFER_len(raw)) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + ssl->s3->delegated_credential_used = true; + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain.get()); i++) { + CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->chain.get(), i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certificate_list, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf), + CRYPTO_BUFFER_len(cert_buf)) || + !CBB_add_u16(&certificate_list, 0 /* no extensions */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + if (!hs->cert_compression_negotiated) { + return ssl_add_message_cbb(ssl, cbb.get()); + } + + Array msg; + if (!CBBFinishArray(cbb.get(), &msg)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + const CertCompressionAlg *alg = nullptr; + for (const auto &candidate : ssl->ctx->cert_compression_algs) { + if (candidate.alg_id == hs->cert_compression_alg_id) { + alg = &candidate; + break; + } + } + + if (alg == nullptr || alg->compress == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + CBB compressed; + body = &body_storage; + if (!ssl->method->init_message(ssl, cbb.get(), body, + SSL3_MT_COMPRESSED_CERTIFICATE) || + !CBB_add_u16(body, hs->cert_compression_alg_id) || + !CBB_add_u24(body, msg.size()) || + !CBB_add_u24_length_prefixed(body, &compressed)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + if (hints && !hs->hints_requested && + hints->cert_compression_alg_id == hs->cert_compression_alg_id && + hints->cert_compression_input == MakeConstSpan(msg) && + !hints->cert_compression_output.empty()) { + if (!CBB_add_bytes(&compressed, hints->cert_compression_output.data(), + hints->cert_compression_output.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } else { + if (!alg->compress(ssl, &compressed, msg.data(), msg.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + if (hints && hs->hints_requested) { + hints->cert_compression_alg_id = hs->cert_compression_alg_id; + if (!hints->cert_compression_input.CopyFrom(msg) || + !hints->cert_compression_output.CopyFrom( + MakeConstSpan(CBB_data(&compressed), CBB_len(&compressed)))) { + return false; + } + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_private_key_failure; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY) || + !CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Sign the digest. + CBB child; + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *sig; + size_t sig_len; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &sig, max_sig_len)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + Array msg; + if (!tls13_get_cert_verify_signature_input( + hs, &msg, + ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + Array spki; + if (hints) { + ScopedCBB spki_cbb; + if (!CBB_init(spki_cbb.get(), 64) || + !EVP_marshal_public_key(spki_cbb.get(), hs->local_pubkey.get()) || + !CBBFinishArray(spki_cbb.get(), &spki)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + } + + if (hints && !hs->hints_requested && + signature_algorithm == hints->signature_algorithm && + MakeConstSpan(msg) == hints->signature_input && + MakeConstSpan(spki) == hints->signature_spki && + !hints->signature.empty() && hints->signature.size() <= max_sig_len) { + // Signature algorithm and input both match. Reuse the signature from hints. + sig_len = hints->signature.size(); + OPENSSL_memcpy(sig, hints->signature.data(), sig_len); + } else { + enum ssl_private_key_result_t sign_result = ssl_private_key_sign( + hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); + if (sign_result != ssl_private_key_success) { + return sign_result; + } + if (hints && hs->hints_requested) { + hints->signature_algorithm = signature_algorithm; + hints->signature_input = std::move(msg); + hints->signature_spki = std::move(spki); + if (!hints->signature.CopyFrom(MakeSpan(sig, sig_len))) { + return ssl_private_key_failure; + } + } + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_private_key_failure; + } + + return ssl_private_key_success; +} + +bool tls13_add_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + size_t verify_data_len; + uint8_t verify_data[EVP_MAX_MD_SIZE]; + + if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return false; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, verify_data, verify_data_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return false; + } + + return true; +} + +bool tls13_add_key_update(SSL *ssl, int update_requested) { + ScopedCBB cbb; + CBB body_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb, + SSL3_MT_KEY_UPDATE) || + !CBB_add_u8(&body_cbb, update_requested) || + !ssl_add_message_cbb(ssl, cbb.get()) || + !tls13_rotate_traffic_key(ssl, evp_aead_seal)) { + return false; + } + + // Suppress KeyUpdate acknowledgments until this change is written to the + // wire. This prevents us from accumulating write obligations when read and + // write progress at different rates. See RFC 8446, section 4.6.3. + ssl->s3->key_update_pending = true; + + return true; +} + +static bool tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) { + CBS body = msg.body; + uint8_t key_update_request; + if (!CBS_get_u8(&body, &key_update_request) || + CBS_len(&body) != 0 || + (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED && + key_update_request != SSL_KEY_UPDATE_REQUESTED)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) { + return false; + } + + // Acknowledge the KeyUpdate + if (key_update_request == SSL_KEY_UPDATE_REQUESTED && + !ssl->s3->key_update_pending && + !tls13_add_key_update(ssl, SSL_KEY_UPDATE_NOT_REQUESTED)) { + return false; + } + + return true; +} + +bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (msg.type == SSL3_MT_KEY_UPDATE) { + ssl->s3->key_update_count++; + if (ssl->quic_method != nullptr || + ssl->s3->key_update_count > kMaxKeyUpdates) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + return tls13_receive_key_update(ssl, msg); + } + + ssl->s3->key_update_count = 0; + + if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) { + return tls13_process_new_session_ticket(ssl, msg); + } + + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return false; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_client.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_client.cc new file mode 100644 index 00000000..367411be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_client.cc @@ -0,0 +1,1122 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +enum client_hs_state_t { + state_read_hello_retry_request = 0, + state_send_second_client_hello, + state_read_server_hello, + state_read_encrypted_extensions, + state_read_certificate_request, + state_read_server_certificate, + state_read_server_certificate_verify, + state_server_certificate_reverify, + state_read_server_finished, + state_send_end_of_early_data, + state_send_client_encrypted_extensions, + state_send_client_certificate, + state_send_client_certificate_verify, + state_complete_second_flight, + state_done, +}; + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +// end_of_early_data closes the early data stream for |hs| and switches the +// encryption level to |level|. It returns true on success and false on error. +static bool close_early_data(SSL_HANDSHAKE *hs, ssl_encryption_level_t level) { + SSL *const ssl = hs->ssl; + assert(hs->in_early_data); + + // Note |can_early_write| may already be false if |SSL_write| exceeded the + // early data write limit. + hs->can_early_write = false; + + // 0-RTT write states on the client differ between TLS 1.3, DTLS 1.3, and + // QUIC. TLS 1.3 has one write encryption level at a time. 0-RTT write keys + // overwrite the null cipher and defer handshake write keys. While a + // HelloRetryRequest can cause us to rewind back to the null cipher, sequence + // numbers have no effect, so we can install a "new" null cipher. + // + // In QUIC and DTLS 1.3, 0-RTT write state cannot override or defer the normal + // write state. The two ClientHello sequence numbers must align, and handshake + // write keys must be installed early to ACK the EncryptedExtensions. + // + // We do not currently implement DTLS 1.3 and, in QUIC, the caller handles + // 0-RTT data, so we can skip installing 0-RTT keys and act as if there is one + // write level. If we implement DTLS 1.3, we'll need to model this better. + if (ssl->quic_method == nullptr) { + if (level == ssl_encryption_initial) { + bssl::UniquePtr null_ctx = + SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + if (!null_ctx || + !ssl->method->set_write_state(ssl, ssl_encryption_initial, + std::move(null_ctx), + /*secret_for_quic=*/{})) { + return false; + } + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + } else { + assert(level == ssl_encryption_handshake); + if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal, + hs->new_session.get(), + hs->client_handshake_secret())) { + return false; + } + } + } + + assert(ssl->s3->write_level == level); + return true; +} + +static bool parse_server_hello_tls13(const SSL_HANDSHAKE *hs, + ParsedServerHello *out, uint8_t *out_alert, + const SSLMessage &msg) { + if (!ssl_parse_server_hello(out, out_alert, msg)) { + return false; + } + // The RFC8446 version of the structure fixes some legacy values. + // Additionally, the session ID must echo the original one. + if (out->legacy_version != TLS1_2_VERSION || + out->compression_method != 0 || + !CBS_mem_equal(&out->session_id, hs->session_id, hs->session_id_len) || + CBS_len(&out->extensions) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + return true; +} + +static bool is_hello_retry_request(const ParsedServerHello &server_hello) { + return Span(server_hello.random) == kHelloRetryRequest; +} + +static bool check_ech_confirmation(const SSL_HANDSHAKE *hs, bool *out_accepted, + uint8_t *out_alert, + const ParsedServerHello &server_hello) { + const bool is_hrr = is_hello_retry_request(server_hello); + size_t offset; + if (is_hrr) { + // We check for an unsolicited extension when parsing all of them. + SSLExtension ech(TLSEXT_TYPE_encrypted_client_hello); + if (!ssl_parse_extensions(&server_hello.extensions, out_alert, {&ech}, + /*ignore_unknown=*/true)) { + return false; + } + if (!ech.present) { + *out_accepted = false; + return true; + } + if (CBS_len(&ech.data) != ECH_CONFIRMATION_SIGNAL_LEN) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + offset = CBS_data(&ech.data) - CBS_data(&server_hello.raw); + } else { + offset = ssl_ech_confirmation_signal_hello_offset(hs->ssl); + } + + if (!hs->selected_ech_config) { + *out_accepted = false; + return true; + } + + uint8_t expected[ECH_CONFIRMATION_SIGNAL_LEN]; + if (!ssl_ech_accept_confirmation(hs, expected, hs->inner_client_random, + hs->inner_transcript, is_hrr, + server_hello.raw, offset)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + *out_accepted = CRYPTO_memcmp(CBS_data(&server_hello.raw) + offset, expected, + sizeof(expected)) == 0; + return true; +} + +static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + assert(ssl->s3->have_version); + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // Queue up a ChangeCipherSpec for whenever we next send something. This + // will be before the second ClientHello. If we offered early data, this was + // already done. + if (!hs->early_data_offered && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + ParsedServerHello server_hello; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!parse_server_hello_tls13(hs, &server_hello, &alert, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The cipher suite must be one we offered. We currently offer all supported + // TLS 1.3 ciphers, so check the version. + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(server_hello.cipher_suite); + if (cipher == nullptr || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + hs->new_cipher = cipher; + + const bool is_hrr = is_hello_retry_request(server_hello); + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + (is_hrr && !hs->transcript.UpdateForHelloRetryRequest())) { + return ssl_hs_error; + } + if (hs->selected_ech_config) { + if (!hs->inner_transcript.InitHash(ssl_protocol_version(ssl), + hs->new_cipher) || + (is_hrr && !hs->inner_transcript.UpdateForHelloRetryRequest())) { + return ssl_hs_error; + } + } + + // Determine which ClientHello the server is responding to. Run + // |check_ech_confirmation| unconditionally, so we validate the extension + // contents. + bool ech_accepted; + if (!check_ech_confirmation(hs, &ech_accepted, &alert, server_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + if (hs->selected_ech_config) { + ssl->s3->ech_status = ech_accepted ? ssl_ech_accepted : ssl_ech_rejected; + } + + if (!is_hrr) { + hs->tls13_state = state_read_server_hello; + return ssl_hs_ok; + } + + // The ECH extension, if present, was already parsed by + // |check_ech_confirmation|. + SSLExtension cookie(TLSEXT_TYPE_cookie), key_share(TLSEXT_TYPE_key_share), + supported_versions(TLSEXT_TYPE_supported_versions), + ech_unused(TLSEXT_TYPE_encrypted_client_hello, + hs->selected_ech_config || hs->config->ech_grease_enabled); + if (!ssl_parse_extensions( + &server_hello.extensions, &alert, + {&cookie, &key_share, &supported_versions, &ech_unused}, + /*ignore_unknown=*/false)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!cookie.present && !key_share.present) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EMPTY_HELLO_RETRY_REQUEST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (cookie.present) { + CBS cookie_value; + if (!CBS_get_u16_length_prefixed(&cookie.data, &cookie_value) || + CBS_len(&cookie_value) == 0 || + CBS_len(&cookie.data) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->cookie.CopyFrom(cookie_value)) { + return ssl_hs_error; + } + } + + if (key_share.present) { + uint16_t group_id; + if (!CBS_get_u16(&key_share.data, &group_id) || + CBS_len(&key_share.data) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // The group must be supported. + if (!tls1_check_group_id(hs, group_id)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + // Check that the HelloRetryRequest does not request a key share that was + // provided in the initial ClientHello. + if (hs->key_shares[0]->GroupID() == group_id || + (hs->key_shares[1] && hs->key_shares[1]->GroupID() == group_id)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + if (!ssl_setup_key_shares(hs, group_id)) { + return ssl_hs_error; + } + } + + // Although we now know whether ClientHelloInner was used, we currently + // maintain both transcripts up to ServerHello. We could swap transcripts + // early, but then ClientHello construction and |check_ech_confirmation| + // become more complex. + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + if (ssl->s3->ech_status == ssl_ech_accepted && + !hs->inner_transcript.Update(msg.raw)) { + return ssl_hs_error; + } + + // HelloRetryRequest should be the end of the flight. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + ssl->s3->used_hello_retry_request = true; + hs->tls13_state = state_send_second_client_hello; + // 0-RTT is rejected if we receive a HelloRetryRequest. + if (hs->in_early_data) { + ssl->s3->early_data_reason = ssl_early_data_hello_retry_request; + if (!close_early_data(hs, ssl_encryption_initial)) { + return ssl_hs_error; + } + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) { + // Any 0-RTT keys must have been discarded. + assert(hs->ssl->s3->write_level == ssl_encryption_initial); + + // Build the second ClientHelloInner, if applicable. The second ClientHello + // uses an empty string for |enc|. + if (hs->ssl->s3->ech_status == ssl_ech_accepted && + !ssl_encrypt_client_hello(hs, {})) { + return ssl_hs_error; + } + + if (!ssl_add_client_hello(hs)) { + return ssl_hs_error; + } + + ssl_done_writing_client_hello(hs); + hs->tls13_state = state_read_server_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + ParsedServerHello server_hello; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!parse_server_hello_tls13(hs, &server_hello, &alert, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Forbid a second HelloRetryRequest. + if (is_hello_retry_request(server_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + // Check the cipher suite, in case this is after HelloRetryRequest. + if (SSL_CIPHER_get_value(hs->new_cipher) != server_hello.cipher_suite) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->s3->ech_status == ssl_ech_accepted) { + if (ssl->s3->used_hello_retry_request) { + // HelloRetryRequest and ServerHello must accept ECH consistently. + bool ech_accepted; + if (!check_ech_confirmation(hs, &ech_accepted, &alert, server_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + if (!ech_accepted) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INCONSISTENT_ECH_NEGOTIATION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + } + + hs->transcript = std::move(hs->inner_transcript); + hs->extensions.sent = hs->inner_extensions_sent; + // Report the inner random value through |SSL_get_client_random|. + OPENSSL_memcpy(ssl->s3->client_random, hs->inner_client_random, + SSL3_RANDOM_SIZE); + } + + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_hello.random), + SSL3_RANDOM_SIZE); + + // When offering ECH, |ssl->session| is only offered in ClientHelloInner. + const bool pre_shared_key_allowed = + ssl->session != nullptr && ssl->s3->ech_status != ssl_ech_rejected; + SSLExtension key_share(TLSEXT_TYPE_key_share), + pre_shared_key(TLSEXT_TYPE_pre_shared_key, pre_shared_key_allowed), + supported_versions(TLSEXT_TYPE_supported_versions); + if (!ssl_parse_extensions(&server_hello.extensions, &alert, + {&key_share, &pre_shared_key, &supported_versions}, + /*ignore_unknown=*/false)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Recheck supported_versions, in case this is after HelloRetryRequest. + uint16_t version; + if (!supported_versions.present || + !CBS_get_u16(&supported_versions.data, &version) || + CBS_len(&supported_versions.data) != 0 || + version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SECOND_SERVERHELLO_VERSION_MISMATCH); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + alert = SSL_AD_DECODE_ERROR; + if (pre_shared_key.present) { + if (!ssl_ext_pre_shared_key_parse_serverhello(hs, &alert, + &pre_shared_key.data)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!ssl_session_is_context_valid(hs, ssl->session.get())) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + hs->can_release_private_key = true; + // Only authentication information carries over in TLS 1.3. + hs->new_session = + SSL_SESSION_dup(ssl->session.get(), SSL_SESSION_DUP_AUTH_ONLY); + if (!hs->new_session) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + ssl_set_session(ssl, NULL); + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + } else if (!ssl_get_new_session(hs)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->new_session->cipher = hs->new_cipher; + + // Set up the key schedule and incorporate the PSK into the running secret. + size_t hash_len = EVP_MD_size( + ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher)); + if (!tls13_init_key_schedule( + hs, ssl->s3->session_reused + ? MakeConstSpan(hs->new_session->secret, + hs->new_session->secret_length) + : MakeConstSpan(kZeroes, hash_len))) { + return ssl_hs_error; + } + + if (!key_share.present) { + // We do not support psk_ke and thus always require a key share. + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return ssl_hs_error; + } + + // Resolve ECDHE and incorporate it into the secret. + Array dhe_secret; + alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_serverhello(hs, &dhe_secret, &alert, + &key_share.data)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!tls13_advance_key_schedule(hs, dhe_secret) || + !ssl_hash_message(hs, msg) || + !tls13_derive_handshake_secrets(hs)) { + return ssl_hs_error; + } + + // If currently sending early data over TCP, we defer installing client + // traffic keys to when the early data stream is closed. See + // |close_early_data|. Note if the server has already rejected 0-RTT via + // HelloRetryRequest, |in_early_data| is already false. + if (!hs->in_early_data || ssl->quic_method != nullptr) { + if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal, + hs->new_session.get(), + hs->client_handshake_secret())) { + return ssl_hs_error; + } + } + + if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open, + hs->new_session.get(), + hs->server_handshake_secret())) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_encrypted_extensions; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) { + return ssl_hs_error; + } + + CBS body = msg.body, extensions; + if (!CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl_parse_serverhello_tlsext(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + // The extension parser checks the server resumed the session. + assert(ssl->s3->session_reused); + // If offering ECH, the server may not accept early data with + // ClientHelloOuter. We do not offer sessions with ClientHelloOuter, so this + // this should be implied by checking |session_reused|. + assert(ssl->s3->ech_status != ssl_ech_rejected); + + if (hs->early_session->cipher != hs->new_session->cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_MISMATCH_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (MakeConstSpan(hs->early_session->early_alpn) != + ssl->s3->alpn_selected) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + // Channel ID is incompatible with 0-RTT. The ALPS extension should be + // negotiated implicitly. + if (hs->channel_id_negotiated || + hs->new_session->has_application_settings) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + hs->new_session->has_application_settings = + hs->early_session->has_application_settings; + if (!hs->new_session->local_application_settings.CopyFrom( + hs->early_session->local_application_settings) || + !hs->new_session->peer_application_settings.CopyFrom( + hs->early_session->peer_application_settings)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Store the negotiated ALPN in the session. + if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_certificate_request; + if (hs->in_early_data && !ssl->s3->early_data_accepted) { + if (!close_early_data(hs, ssl_encryption_handshake)) { + return ssl_hs_error; + } + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // CertificateRequest may only be sent in non-resumption handshakes. + if (ssl->s3->session_reused) { + if (ssl->ctx->reverify_on_resume && !ssl->s3->early_data_accepted) { + hs->tls13_state = state_server_certificate_reverify; + return ssl_hs_ok; + } + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // CertificateRequest is optional. + if (msg.type != SSL3_MT_CERTIFICATE_REQUEST) { + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; + } + + + SSLExtension sigalgs(TLSEXT_TYPE_signature_algorithms), + ca(TLSEXT_TYPE_certificate_authorities); + CBS body = msg.body, context, extensions, supported_signature_algorithms; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!CBS_get_u8_length_prefixed(&body, &context) || + // The request context is always empty during the handshake. + CBS_len(&context) != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || // + CBS_len(&body) != 0 || + !ssl_parse_extensions(&extensions, &alert, {&sigalgs, &ca}, + /*ignore_unknown=*/true) || + !sigalgs.present || + !CBS_get_u16_length_prefixed(&sigalgs.data, + &supported_signature_algorithms) || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (ca.present) { + hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &ca.data); + if (!hs->ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + } else { + hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); + if (!hs->ca_names) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + hs->cert_request = true; + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_COMPRESSED_CERTIFICATE && + !ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE)) { + return ssl_hs_error; + } + + if (!tls13_process_certificate(hs, msg, false /* certificate required */) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_server_certificate_reverify(SSL_HANDSHAKE *hs) { + switch (ssl_reverify_peer_cert(hs, /*send_alert=*/true)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_server_certificate_reverify; + return ssl_hs_certificate_verify; + } + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + !tls13_process_finished(hs, msg, false /* don't use saved value */) || + !ssl_hash_message(hs, msg) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule( + hs, MakeConstSpan(kZeroes, hs->transcript.DigestLen())) || + !tls13_derive_application_secrets(hs)) { + return ssl_hs_error; + } + + // Finished should be the end of the flight. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_end_of_early_data; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->s3->early_data_accepted) { + // QUIC omits the EndOfEarlyData message. See RFC 9001, section 8.3. + if (ssl->quic_method == nullptr) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_END_OF_EARLY_DATA) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (!close_early_data(hs, ssl_encryption_handshake)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_send_client_encrypted_extensions; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_encrypted_extensions( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // For now, only one extension uses client EncryptedExtensions. This function + // may be generalized if others use it in the future. + if (hs->new_session->has_application_settings && + !ssl->s3->early_data_accepted) { + ScopedCBB cbb; + CBB body, extensions, extension; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_ENCRYPTED_EXTENSIONS) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_application_settings) || + !CBB_add_u16_length_prefixed(&extensions, &extension) || + !CBB_add_bytes(&extension, + hs->new_session->local_application_settings.data(), + hs->new_session->local_application_settings.size()) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + if (ssl->s3->ech_status == ssl_ech_rejected) { + // Do not send client certificates on ECH reject. We have not authenticated + // the server for the name that can learn the certificate. + SSL_certs_clear(ssl); + } else if (hs->config->cert->cert_cb != nullptr) { + // Call cert_cb to update the certificate. + int rv = hs->config->cert->cert_cb(ssl, hs->config->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->tls13_state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs) || + !tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + // Don't send CertificateVerify if there is no certificate. + if (!ssl_has_certificate(hs)) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + hs->can_release_private_key = true; + + // Send a Channel ID assertion if necessary. + if (hs->channel_id_negotiated) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send a Finished message. + if (!tls13_add_finished(hs)) { + return ssl_hs_error; + } + + // Derive the final keys and enable them. + if (!tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal, + hs->new_session.get(), + hs->client_traffic_secret_0()) || + !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_open, + hs->new_session.get(), + hs->server_traffic_secret_0()) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_done; + return ssl_hs_flush; +} + +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + ret = do_read_hello_retry_request(hs); + break; + case state_send_second_client_hello: + ret = do_send_second_client_hello(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_read_encrypted_extensions: + ret = do_read_encrypted_extensions(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_server_certificate_verify: + ret = do_read_server_certificate_verify(hs); + break; + case state_server_certificate_reverify: + ret = do_server_certificate_reverify(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_send_end_of_early_data: + ret = do_send_end_of_early_data(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_encrypted_extensions: + ret = do_send_client_encrypted_extensions(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_complete_second_flight: + ret = do_complete_second_flight(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) { + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + return "TLS 1.3 client read_hello_retry_request"; + case state_send_second_client_hello: + return "TLS 1.3 client send_second_client_hello"; + case state_read_server_hello: + return "TLS 1.3 client read_server_hello"; + case state_read_encrypted_extensions: + return "TLS 1.3 client read_encrypted_extensions"; + case state_read_certificate_request: + return "TLS 1.3 client read_certificate_request"; + case state_read_server_certificate: + return "TLS 1.3 client read_server_certificate"; + case state_read_server_certificate_verify: + return "TLS 1.3 client read_server_certificate_verify"; + case state_server_certificate_reverify: + return "TLS 1.3 client server_certificate_reverify"; + case state_read_server_finished: + return "TLS 1.3 client read_server_finished"; + case state_send_end_of_early_data: + return "TLS 1.3 client send_end_of_early_data"; + case state_send_client_encrypted_extensions: + return "TLS 1.3 client send_client_encrypted_extensions"; + case state_send_client_certificate: + return "TLS 1.3 client send_client_certificate"; + case state_send_client_certificate_verify: + return "TLS 1.3 client send_client_certificate_verify"; + case state_complete_second_flight: + return "TLS 1.3 client complete_second_flight"; + case state_done: + return "TLS 1.3 client done"; + } + + return "TLS 1.3 client unknown"; +} + +bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + // Ignore tickets on shutdown. Callers tend to indiscriminately call + // |SSL_shutdown| before destroying an |SSL|, at which point calling the new + // session callback may be confusing. + return true; + } + + CBS body = msg.body; + UniquePtr session = tls13_create_session_with_ticket(ssl, &body); + if (!session) { + return false; + } + + if ((ssl->session_ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) && + ssl->session_ctx->new_session_cb != NULL && + ssl->session_ctx->new_session_cb(ssl, session.get())) { + // |new_session_cb|'s return value signals that it took ownership. + session.release(); + } + + return true; +} + +UniquePtr tls13_create_session_with_ticket(SSL *ssl, CBS *body) { + UniquePtr session = SSL_SESSION_dup( + ssl->s3->established_session.get(), SSL_SESSION_INCLUDE_NONAUTH); + if (!session) { + return nullptr; + } + + ssl_session_rebase_time(ssl, session.get()); + + uint32_t server_timeout; + CBS ticket_nonce, ticket, extensions; + if (!CBS_get_u32(body, &server_timeout) || + !CBS_get_u32(body, &session->ticket_age_add) || + !CBS_get_u8_length_prefixed(body, &ticket_nonce) || + !CBS_get_u16_length_prefixed(body, &ticket) || + !session->ticket.CopyFrom(ticket) || + !CBS_get_u16_length_prefixed(body, &extensions) || + CBS_len(body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + // Cap the renewable lifetime by the server advertised value. This avoids + // wasting bandwidth on 0-RTT when we know the server will reject it. + if (session->timeout > server_timeout) { + session->timeout = server_timeout; + } + + if (!tls13_derive_session_psk(session.get(), ticket_nonce)) { + return nullptr; + } + + SSLExtension early_data(TLSEXT_TYPE_early_data); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, {&early_data}, + /*ignore_unknown=*/true)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return nullptr; + } + + if (early_data.present) { + if (!CBS_get_u32(&early_data.data, &session->ticket_max_early_data) || + CBS_len(&early_data.data) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + // QUIC does not use the max_early_data_size parameter and always sets it to + // a fixed value. See RFC 9001, section 4.6.1. + if (ssl->quic_method != nullptr && + session->ticket_max_early_data != 0xffffffff) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + } + + // Historically, OpenSSL filled in fake session IDs for ticket-based sessions. + // Envoy's tests depend on this, although perhaps they shouldn't. + SHA256(CBS_data(&ticket), CBS_len(&ticket), session->session_id); + session->session_id_length = SHA256_DIGEST_LENGTH; + + session->ticket_age_add_valid = true; + session->not_resumable = false; + + return session; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_enc.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_enc.cc new file mode 100644 index 00000000..37322da8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_enc.cc @@ -0,0 +1,582 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static bool init_key_schedule(SSL_HANDSHAKE *hs, SSLTranscript *transcript, + uint16_t version, const SSL_CIPHER *cipher) { + if (!transcript->InitHash(version, cipher)) { + return false; + } + + // Initialize the secret to the zero key. + hs->ResizeSecrets(transcript->DigestLen()); + OPENSSL_memset(hs->secret().data(), 0, hs->secret().size()); + + return true; +} + +static bool hkdf_extract_to_secret(SSL_HANDSHAKE *hs, + const SSLTranscript &transcript, + Span in) { + size_t len; + if (!HKDF_extract(hs->secret().data(), &len, transcript.Digest(), in.data(), + in.size(), hs->secret().data(), hs->secret().size())) { + return false; + } + assert(len == hs->secret().size()); + return true; +} + +bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span psk) { + if (!init_key_schedule(hs, &hs->transcript, ssl_protocol_version(hs->ssl), + hs->new_cipher)) { + return false; + } + + // Handback includes the whole handshake transcript, so we cannot free the + // transcript buffer in the handback case. + if (!hs->handback) { + hs->transcript.FreeBuffer(); + } + return hkdf_extract_to_secret(hs, hs->transcript, psk); +} + +bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { + assert(!hs->ssl->server); + // When offering ECH, early data is associated with ClientHelloInner, not + // ClientHelloOuter. + SSLTranscript *transcript = + hs->selected_ech_config ? &hs->inner_transcript : &hs->transcript; + return init_key_schedule(hs, transcript, + ssl_session_protocol_version(session), + session->cipher) && + hkdf_extract_to_secret( + hs, *transcript, + MakeConstSpan(session->secret, session->secret_length)); +} + +static Span label_to_span(const char *label) { + return MakeConstSpan(label, strlen(label)); +} + +static bool hkdf_expand_label(Span out, const EVP_MD *digest, + Span secret, + Span label, + Span hash) { + Span protocol_label = label_to_span("tls13 "); + ScopedCBB cbb; + CBB child; + Array hkdf_label; + if (!CBB_init(cbb.get(), 2 + 1 + protocol_label.size() + label.size() + 1 + + hash.size()) || + !CBB_add_u16(cbb.get(), out.size()) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, + reinterpret_cast(protocol_label.data()), + protocol_label.size()) || + !CBB_add_bytes(&child, reinterpret_cast(label.data()), + label.size()) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, hash.data(), hash.size()) || + !CBBFinishArray(cbb.get(), &hkdf_label)) { + return false; + } + + return HKDF_expand(out.data(), out.size(), digest, secret.data(), + secret.size(), hkdf_label.data(), hkdf_label.size()); +} + +static const char kTLS13LabelDerived[] = "derived"; + +bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span in) { + uint8_t derive_context[EVP_MAX_MD_SIZE]; + unsigned derive_context_len; + return EVP_Digest(nullptr, 0, derive_context, &derive_context_len, + hs->transcript.Digest(), nullptr) && + hkdf_expand_label(hs->secret(), hs->transcript.Digest(), hs->secret(), + label_to_span(kTLS13LabelDerived), + MakeConstSpan(derive_context, derive_context_len)) && + hkdf_extract_to_secret(hs, hs->transcript, in); +} + +// derive_secret_with_transcript derives a secret of length |out.size()| and +// writes the result in |out| with the given label, the current base secret, and +// the state of |transcript|. It returns true on success and false on error. +static bool derive_secret_with_transcript(const SSL_HANDSHAKE *hs, + Span out, + const SSLTranscript &transcript, + Span label) { + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!transcript.GetHash(context_hash, &context_hash_len)) { + return false; + } + + return hkdf_expand_label(out, transcript.Digest(), hs->secret(), label, + MakeConstSpan(context_hash, context_hash_len)); +} + +static bool derive_secret(SSL_HANDSHAKE *hs, Span out, + Span label) { + return derive_secret_with_transcript(hs, out, hs->transcript, label); +} + +bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level, + enum evp_aead_direction_t direction, + const SSL_SESSION *session, + Span traffic_secret) { + uint16_t version = ssl_session_protocol_version(session); + UniquePtr traffic_aead; + Span secret_for_quic; + if (ssl->quic_method != nullptr) { + // Install a placeholder SSLAEADContext so that SSL accessors work. The + // encryption itself will be handled by the SSL_QUIC_METHOD. + traffic_aead = + SSLAEADContext::CreatePlaceholderForQUIC(version, session->cipher); + secret_for_quic = traffic_secret; + } else { + // Look up cipher suite properties. + const EVP_AEAD *aead; + size_t discard; + if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher, + version, SSL_is_dtls(ssl))) { + return false; + } + + const EVP_MD *digest = ssl_session_get_digest(session); + + // Derive the key. + size_t key_len = EVP_AEAD_key_length(aead); + uint8_t key_buf[EVP_AEAD_MAX_KEY_LENGTH]; + auto key = MakeSpan(key_buf, key_len); + if (!hkdf_expand_label(key, digest, traffic_secret, label_to_span("key"), + {})) { + return false; + } + + // Derive the IV. + size_t iv_len = EVP_AEAD_nonce_length(aead); + uint8_t iv_buf[EVP_AEAD_MAX_NONCE_LENGTH]; + auto iv = MakeSpan(iv_buf, iv_len); + if (!hkdf_expand_label(iv, digest, traffic_secret, label_to_span("iv"), + {})) { + return false; + } + + traffic_aead = SSLAEADContext::Create(direction, session->ssl_version, + SSL_is_dtls(ssl), session->cipher, + key, Span(), iv); + } + + if (!traffic_aead) { + return false; + } + + if (traffic_secret.size() > + OPENSSL_ARRAY_SIZE(ssl->s3->read_traffic_secret) || + traffic_secret.size() > + OPENSSL_ARRAY_SIZE(ssl->s3->write_traffic_secret)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (direction == evp_aead_open) { + if (!ssl->method->set_read_state(ssl, level, std::move(traffic_aead), + secret_for_quic)) { + return false; + } + OPENSSL_memmove(ssl->s3->read_traffic_secret, traffic_secret.data(), + traffic_secret.size()); + ssl->s3->read_traffic_secret_len = traffic_secret.size(); + } else { + if (!ssl->method->set_write_state(ssl, level, std::move(traffic_aead), + secret_for_quic)) { + return false; + } + OPENSSL_memmove(ssl->s3->write_traffic_secret, traffic_secret.data(), + traffic_secret.size()); + ssl->s3->write_traffic_secret_len = traffic_secret.size(); + } + + return true; +} + + +static const char kTLS13LabelExporter[] = "exp master"; + +static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic"; +static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic"; +static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic"; +static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic"; +static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic"; + +bool tls13_derive_early_secret(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // When offering ECH on the client, early data is associated with + // ClientHelloInner, not ClientHelloOuter. + const SSLTranscript &transcript = (!ssl->server && hs->selected_ech_config) + ? hs->inner_transcript + : hs->transcript; + if (!derive_secret_with_transcript( + hs, hs->early_traffic_secret(), transcript, + label_to_span(kTLS13LabelClientEarlyTraffic)) || + !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET", + hs->early_traffic_secret())) { + return false; + } + return true; +} + +bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!derive_secret(hs, hs->client_handshake_secret(), + label_to_span(kTLS13LabelClientHandshakeTraffic)) || + !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", + hs->client_handshake_secret()) || + !derive_secret(hs, hs->server_handshake_secret(), + label_to_span(kTLS13LabelServerHandshakeTraffic)) || + !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET", + hs->server_handshake_secret())) { + return false; + } + + return true; +} + +bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ssl->s3->exporter_secret_len = hs->transcript.DigestLen(); + if (!derive_secret(hs, hs->client_traffic_secret_0(), + label_to_span(kTLS13LabelClientApplicationTraffic)) || + !ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0", + hs->client_traffic_secret_0()) || + !derive_secret(hs, hs->server_traffic_secret_0(), + label_to_span(kTLS13LabelServerApplicationTraffic)) || + !ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0", + hs->server_traffic_secret_0()) || + !derive_secret( + hs, MakeSpan(ssl->s3->exporter_secret, ssl->s3->exporter_secret_len), + label_to_span(kTLS13LabelExporter)) || + !ssl_log_secret(ssl, "EXPORTER_SECRET", + MakeConstSpan(ssl->s3->exporter_secret, + ssl->s3->exporter_secret_len))) { + return false; + } + + return true; +} + +static const char kTLS13LabelApplicationTraffic[] = "traffic upd"; + +bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) { + Span secret; + if (direction == evp_aead_open) { + secret = MakeSpan(ssl->s3->read_traffic_secret, + ssl->s3->read_traffic_secret_len); + } else { + secret = MakeSpan(ssl->s3->write_traffic_secret, + ssl->s3->write_traffic_secret_len); + } + + const SSL_SESSION *session = SSL_get_session(ssl); + const EVP_MD *digest = ssl_session_get_digest(session); + return hkdf_expand_label(secret, digest, secret, + label_to_span(kTLS13LabelApplicationTraffic), {}) && + tls13_set_traffic_key(ssl, ssl_encryption_application, direction, + session, secret); +} + +static const char kTLS13LabelResumption[] = "res master"; + +bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) { + if (hs->transcript.DigestLen() > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + hs->new_session->secret_length = hs->transcript.DigestLen(); + return derive_secret( + hs, MakeSpan(hs->new_session->secret, hs->new_session->secret_length), + label_to_span(kTLS13LabelResumption)); +} + +static const char kTLS13LabelFinished[] = "finished"; + +// tls13_verify_data sets |out| to be the HMAC of |context| using a derived +// Finished key for both Finished messages and the PSK binder. |out| must have +// space available for |EVP_MAX_MD_SIZE| bytes. +static bool tls13_verify_data(uint8_t *out, size_t *out_len, + const EVP_MD *digest, uint16_t version, + Span secret, + Span context) { + uint8_t key_buf[EVP_MAX_MD_SIZE]; + auto key = MakeSpan(key_buf, EVP_MD_size(digest)); + unsigned len; + if (!hkdf_expand_label(key, digest, secret, + label_to_span(kTLS13LabelFinished), {}) || + HMAC(digest, key.data(), key.size(), context.data(), context.size(), out, + &len) == nullptr) { + return false; + } + *out_len = len; + return true; +} + +bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, + bool is_server) { + Span traffic_secret = + is_server ? hs->server_handshake_secret() : hs->client_handshake_secret(); + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !tls13_verify_data(out, out_len, hs->transcript.Digest(), + hs->ssl->version, traffic_secret, + MakeConstSpan(context_hash, context_hash_len))) { + return false; + } + return true; +} + +static const char kTLS13LabelResumptionPSK[] = "resumption"; + +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce) { + const EVP_MD *digest = ssl_session_get_digest(session); + // The session initially stores the resumption_master_secret, which we + // override with the PSK. + auto session_secret = MakeSpan(session->secret, session->secret_length); + return hkdf_expand_label(session_secret, digest, session_secret, + label_to_span(kTLS13LabelResumptionPSK), nonce); +} + +static const char kTLS13LabelExportKeying[] = "exporter"; + +bool tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context) { + if (secret.empty()) { + assert(0); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); + + uint8_t hash_buf[EVP_MAX_MD_SIZE]; + uint8_t export_context_buf[EVP_MAX_MD_SIZE]; + unsigned hash_len; + unsigned export_context_len; + if (!EVP_Digest(context.data(), context.size(), hash_buf, &hash_len, digest, + nullptr) || + !EVP_Digest(nullptr, 0, export_context_buf, &export_context_len, digest, + nullptr)) { + return false; + } + + auto hash = MakeConstSpan(hash_buf, hash_len); + auto export_context = MakeConstSpan(export_context_buf, export_context_len); + uint8_t derived_secret_buf[EVP_MAX_MD_SIZE]; + auto derived_secret = MakeSpan(derived_secret_buf, EVP_MD_size(digest)); + return hkdf_expand_label(derived_secret, digest, secret, label, + export_context) && + hkdf_expand_label(out, digest, derived_secret, + label_to_span(kTLS13LabelExportKeying), hash); +} + +static const char kTLS13LabelPSKBinder[] = "res binder"; + +static bool tls13_psk_binder(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + const SSLTranscript &transcript, + Span client_hello, + size_t binders_len) { + const EVP_MD *digest = ssl_session_get_digest(session); + + // Compute the binder key. + // + // TODO(davidben): Ideally we wouldn't recompute early secret and the binder + // key each time. + uint8_t binder_context[EVP_MAX_MD_SIZE]; + unsigned binder_context_len; + uint8_t early_secret[EVP_MAX_MD_SIZE] = {0}; + size_t early_secret_len; + uint8_t binder_key_buf[EVP_MAX_MD_SIZE] = {0}; + auto binder_key = MakeSpan(binder_key_buf, EVP_MD_size(digest)); + if (!EVP_Digest(nullptr, 0, binder_context, &binder_context_len, digest, + nullptr) || + !HKDF_extract(early_secret, &early_secret_len, digest, session->secret, + session->secret_length, nullptr, 0) || + !hkdf_expand_label(binder_key, digest, + MakeConstSpan(early_secret, early_secret_len), + label_to_span(kTLS13LabelPSKBinder), + MakeConstSpan(binder_context, binder_context_len))) { + return false; + } + + // Hash the transcript and truncated ClientHello. + if (client_hello.size() < binders_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + auto truncated = client_hello.subspan(0, client_hello.size() - binders_len); + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + ScopedEVP_MD_CTX ctx; + if (!transcript.CopyToHashContext(ctx.get(), digest) || + !EVP_DigestUpdate(ctx.get(), truncated.data(), + truncated.size()) || + !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) { + return false; + } + + if (!tls13_verify_data(out, out_len, digest, session->ssl_version, binder_key, + MakeConstSpan(context, context_len))) { + return false; + } + + assert(*out_len == EVP_MD_size(digest)); + return true; +} + +bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs, + const SSLTranscript &transcript, Span msg, + size_t *out_binder_len) { + const SSL *const ssl = hs->ssl; + const EVP_MD *digest = ssl_session_get_digest(ssl->session.get()); + const size_t hash_len = EVP_MD_size(digest); + // We only offer one PSK, so the binders are a u16 and u8 length + // prefix, followed by the binder. The caller is assumed to have constructed + // |msg| with placeholder binders. + const size_t binders_len = 3 + hash_len; + uint8_t verify_data[EVP_MAX_MD_SIZE]; + size_t verify_data_len; + if (!tls13_psk_binder(verify_data, &verify_data_len, ssl->session.get(), + transcript, msg, binders_len) || + verify_data_len != hash_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + auto msg_binder = msg.last(verify_data_len); + OPENSSL_memcpy(msg_binder.data(), verify_data, verify_data_len); + if (out_binder_len != nullptr) { + *out_binder_len = verify_data_len; + } + return true; +} + +bool tls13_verify_psk_binder(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session, const SSLMessage &msg, + CBS *binders) { + uint8_t verify_data[EVP_MAX_MD_SIZE]; + size_t verify_data_len; + CBS binder; + // The binders are computed over |msg| with |binders| and its u16 length + // prefix removed. The caller is assumed to have parsed |msg|, extracted + // |binders|, and verified the PSK extension is last. + if (!tls13_psk_binder(verify_data, &verify_data_len, session, hs->transcript, + msg.raw, 2 + CBS_len(binders)) || + // We only consider the first PSK, so compare against the first binder. + !CBS_get_u8_length_prefixed(binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + bool binder_ok = + CBS_len(&binder) == verify_data_len && + CRYPTO_memcmp(CBS_data(&binder), verify_data, verify_data_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + binder_ok = true; +#endif + if (!binder_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return false; + } + + return true; +} + +size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl) { + static_assert(ECH_CONFIRMATION_SIGNAL_LEN < SSL3_RANDOM_SIZE, + "the confirmation signal is a suffix of the random"); + const size_t header_len = + SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH; + return header_len + 2 /* version */ + SSL3_RANDOM_SIZE - + ECH_CONFIRMATION_SIGNAL_LEN; +} + +bool ssl_ech_accept_confirmation(const SSL_HANDSHAKE *hs, Span out, + Span client_random, + const SSLTranscript &transcript, bool is_hrr, + Span msg, size_t offset) { + // See draft-ietf-tls-esni-13, sections 7.2 and 7.2.1. + static const uint8_t kZeros[EVP_MAX_MD_SIZE] = {0}; + + // We hash |msg|, with bytes from |offset| zeroed. + if (msg.size() < offset + ECH_CONFIRMATION_SIGNAL_LEN) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + auto before_zeros = msg.subspan(0, offset); + auto after_zeros = msg.subspan(offset + ECH_CONFIRMATION_SIGNAL_LEN); + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + ScopedEVP_MD_CTX ctx; + if (!transcript.CopyToHashContext(ctx.get(), transcript.Digest()) || + !EVP_DigestUpdate(ctx.get(), before_zeros.data(), before_zeros.size()) || + !EVP_DigestUpdate(ctx.get(), kZeros, ECH_CONFIRMATION_SIGNAL_LEN) || + !EVP_DigestUpdate(ctx.get(), after_zeros.data(), after_zeros.size()) || + !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) { + return false; + } + + uint8_t secret[EVP_MAX_MD_SIZE]; + size_t secret_len; + if (!HKDF_extract(secret, &secret_len, transcript.Digest(), + client_random.data(), client_random.size(), kZeros, + transcript.DigestLen())) { + return false; + } + + assert(out.size() == ECH_CONFIRMATION_SIGNAL_LEN); + return hkdf_expand_label(out, transcript.Digest(), + MakeConstSpan(secret, secret_len), + is_hrr ? label_to_span("hrr ech accept confirmation") + : label_to_span("ech accept confirmation"), + MakeConstSpan(context, context_len)); +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_server.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_server.cc new file mode 100644 index 00000000..f0c3e41c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls13_server.cc @@ -0,0 +1,1337 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +// Allow a minute of ticket age skew in either direction. This covers +// transmission delays in ClientHello and NewSessionTicket, as well as +// drift between client and server clock rate since the ticket was issued. +// See RFC 8446, section 8.3. +static const int32_t kMaxTicketAgeSkewSeconds = 60; + +static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + const uint16_t group_id = hs->new_session->group_id; + + bool found_key_share; + Span peer_key; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &peer_key, + &alert, client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + if (!found_key_share) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return false; + } + + Array secret; + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + if (hints && !hs->hints_requested && hints->key_share_group_id == group_id && + !hints->key_share_secret.empty()) { + // Copy DH secret from hints. + if (!hs->ecdh_public_key.CopyFrom(hints->key_share_public_key) || + !secret.CopyFrom(hints->key_share_secret)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + } else { + ScopedCBB public_key; + UniquePtr key_share = SSLKeyShare::Create(group_id); + if (!key_share || // + !CBB_init(public_key.get(), 32) || + !key_share->Accept(public_key.get(), &secret, &alert, peer_key) || + !CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + if (hints && hs->hints_requested) { + hints->key_share_group_id = group_id; + if (!hints->key_share_public_key.CopyFrom(hs->ecdh_public_key) || + !hints->key_share_secret.CopyFrom(secret)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return false; + } + } + } + + return tls13_advance_key_schedule(hs, secret); +} + +static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->ssl->version) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +static const SSL_CIPHER *choose_tls13_cipher( + const SSL *ssl, const SSL_CLIENT_HELLO *client_hello, uint16_t group_id) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + const uint16_t version = ssl_protocol_version(ssl); + + return ssl_choose_tls13_cipher(cipher_suites, version, group_id); +} + +static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) { + SSL *const ssl = hs->ssl; + if (// If the client doesn't accept resumption with PSK_DHE_KE, don't send a + // session ticket. + !hs->accept_psk_mode || + // We only implement stateless resumption in TLS 1.3, so skip sending + // tickets if disabled. + (SSL_get_options(ssl) & SSL_OP_NO_TICKET)) { + *out_sent_tickets = false; + return true; + } + + // TLS 1.3 recommends single-use tickets, so issue multiple tickets in case + // the client makes several connections before getting a renewal. + static const int kNumTickets = 2; + + // Rebase the session timestamp so that it is measured from ticket + // issuance. + ssl_session_rebase_time(ssl, hs->new_session.get()); + + for (int i = 0; i < kNumTickets; i++) { + UniquePtr session( + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH)); + if (!session) { + return false; + } + + if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) { + return false; + } + session->ticket_age_add_valid = true; + bool enable_early_data = + ssl->enable_early_data && + (!ssl->quic_method || !ssl->config->quic_early_data_context.empty()); + if (enable_early_data) { + // QUIC does not use the max_early_data_size parameter and always sets it + // to a fixed value. See RFC 9001, section 4.6.1. + session->ticket_max_early_data = + ssl->quic_method != nullptr ? 0xffffffff : kMaxEarlyDataAccepted; + } + + static_assert(kNumTickets < 256, "Too many tickets"); + uint8_t nonce[] = {static_cast(i)}; + + ScopedCBB cbb; + CBB body, nonce_cbb, ticket, extensions; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u32(&body, session->ticket_age_add) || + !CBB_add_u8_length_prefixed(&body, &nonce_cbb) || + !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !tls13_derive_session_psk(session.get(), nonce) || + !ssl_encrypt_ticket(hs, &ticket, session.get()) || + !CBB_add_u16_length_prefixed(&body, &extensions)) { + return false; + } + + if (enable_early_data) { + CBB early_data; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) || + !CBB_add_u16_length_prefixed(&extensions, &early_data) || + !CBB_add_u32(&early_data, session->ticket_max_early_data) || + !CBB_flush(&extensions)) { + return false; + } + } + + // Add a fake extension. See RFC 8701. + if (!CBB_add_u16(&extensions, + ssl_get_grease_value(hs, ssl_grease_ticket_extension)) || + !CBB_add_u16(&extensions, 0 /* empty */)) { + return false; + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return false; + } + } + + *out_sent_tickets = true; + return true; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + // At this point, most ClientHello extensions have already been processed by + // the common handshake logic. Resolve the remaining non-PSK parameters. + SSL *const ssl = hs->ssl; + SSLMessage msg; + SSL_CLIENT_HELLO client_hello; + if (!hs->GetClientHello(&msg, &client_hello)) { + return ssl_hs_error; + } + + if (ssl->quic_method != nullptr && client_hello.session_id_len > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_COMPATIBILITY_MODE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + OPENSSL_memcpy(hs->session_id, client_hello.session_id, + client_hello.session_id_len); + hs->session_id_len = client_hello.session_id_len; + + uint16_t group_id; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // Negotiate the cipher suite. + hs->new_cipher = choose_tls13_cipher(ssl, &client_hello, group_id); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The PRF hash is now known. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) { + return ssl_hs_error; + } + + hs->tls13_state = state13_select_session; + return ssl_hs_ok; +} + +static enum ssl_ticket_aead_result_t select_session( + SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr *out_session, + int32_t *out_ticket_age_skew, bool *out_offered_ticket, + const SSLMessage &msg, const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + *out_session = nullptr; + + CBS pre_shared_key; + *out_offered_ticket = ssl_client_hello_get_extension( + client_hello, &pre_shared_key, TLSEXT_TYPE_pre_shared_key); + if (!*out_offered_ticket) { + return ssl_ticket_aead_ignore_ticket; + } + + // Per RFC 8446, section 4.2.9, servers MUST abort the handshake if the client + // sends pre_shared_key without psk_key_exchange_modes. + CBS unused; + if (!ssl_client_hello_get_extension(client_hello, &unused, + TLSEXT_TYPE_psk_key_exchange_modes)) { + *out_alert = SSL_AD_MISSING_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + return ssl_ticket_aead_error; + } + + CBS ticket, binders; + uint32_t client_ticket_age; + if (!ssl_ext_pre_shared_key_parse_clienthello( + hs, &ticket, &binders, &client_ticket_age, out_alert, client_hello, + &pre_shared_key)) { + return ssl_ticket_aead_error; + } + + // If the peer did not offer psk_dhe, ignore the resumption. + if (!hs->accept_psk_mode) { + return ssl_ticket_aead_ignore_ticket; + } + + // TLS 1.3 session tickets are renewed separately as part of the + // NewSessionTicket. + bool unused_renew; + UniquePtr session; + enum ssl_ticket_aead_result_t ret = + ssl_process_ticket(hs, &session, &unused_renew, ticket, {}); + switch (ret) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_error: + *out_alert = SSL_AD_INTERNAL_ERROR; + return ret; + default: + return ret; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // Historically, some TLS 1.3 tickets were missing ticket_age_add. + !session->ticket_age_add_valid) { + return ssl_ticket_aead_ignore_ticket; + } + + // Recover the client ticket age and convert to seconds. + client_ticket_age -= session->ticket_age_add; + client_ticket_age /= 1000; + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Compute the server ticket age in seconds. + assert(now.tv_sec >= session->time); + uint64_t server_ticket_age = now.tv_sec - session->time; + + // To avoid overflowing |hs->ticket_age_skew|, we will not resume + // 68-year-old sessions. + if (server_ticket_age > INT32_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + + *out_ticket_age_skew = static_cast(client_ticket_age) - + static_cast(server_ticket_age); + + // Check the PSK binder. + if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) { + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_ticket_aead_error; + } + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +static bool quic_ticket_compatible(const SSL_SESSION *session, + const SSL_CONFIG *config) { + if (!session->is_quic) { + return true; + } + + if (session->quic_early_data_context.empty() || + config->quic_early_data_context.size() != + session->quic_early_data_context.size() || + CRYPTO_memcmp(config->quic_early_data_context.data(), + session->quic_early_data_context.data(), + session->quic_early_data_context.size()) != 0) { + return false; + } + return true; +} + +static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + SSL_CLIENT_HELLO client_hello; + if (!hs->GetClientHello(&msg, &client_hello)) { + return ssl_hs_error; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr session; + bool offered_ticket = false; + switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, + &offered_ticket, msg, &client_hello)) { + case ssl_ticket_aead_ignore_ticket: + assert(!session); + if (!ssl_get_new_session(hs)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + break; + + case ssl_ticket_aead_success: + // Carry over authentication information from the previous handshake into + // a fresh session. + hs->new_session = + SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY); + if (hs->new_session == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + hs->can_release_private_key = true; + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + break; + + case ssl_ticket_aead_error: + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + + case ssl_ticket_aead_retry: + hs->tls13_state = state13_select_session; + return ssl_hs_pending_ticket; + } + + // Negotiate ALPS now, after ALPN is negotiated and |hs->new_session| is + // initialized. + if (!ssl_negotiate_alps(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Record connection properties in the new session. + hs->new_session->cipher = hs->new_cipher; + if (!tls1_get_shared_group(hs, &hs->new_session->group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // Determine if we need HelloRetryRequest. + bool found_key_share; + if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, + /*out_key_share=*/nullptr, &alert, + &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Determine if we're negotiating 0-RTT. + if (!ssl->enable_early_data) { + ssl->s3->early_data_reason = ssl_early_data_disabled; + } else if (!offered_ticket) { + ssl->s3->early_data_reason = ssl_early_data_no_session_offered; + } else if (!session) { + ssl->s3->early_data_reason = ssl_early_data_session_not_resumed; + } else if (session->ticket_max_early_data == 0) { + ssl->s3->early_data_reason = ssl_early_data_unsupported_for_session; + } else if (!hs->early_data_offered) { + ssl->s3->early_data_reason = ssl_early_data_peer_declined; + } else if (hs->channel_id_negotiated) { + // Channel ID is incompatible with 0-RTT. + ssl->s3->early_data_reason = ssl_early_data_channel_id; + } else if (MakeConstSpan(ssl->s3->alpn_selected) != session->early_alpn) { + // The negotiated ALPN must match the one in the ticket. + ssl->s3->early_data_reason = ssl_early_data_alpn_mismatch; + } else if (hs->new_session->has_application_settings != + session->has_application_settings || + MakeConstSpan(hs->new_session->local_application_settings) != + session->local_application_settings) { + ssl->s3->early_data_reason = ssl_early_data_alps_mismatch; + } else if (ssl->s3->ticket_age_skew < -kMaxTicketAgeSkewSeconds || + kMaxTicketAgeSkewSeconds < ssl->s3->ticket_age_skew) { + ssl->s3->early_data_reason = ssl_early_data_ticket_age_skew; + } else if (!quic_ticket_compatible(session.get(), hs->config)) { + ssl->s3->early_data_reason = ssl_early_data_quic_parameter_mismatch; + } else if (!found_key_share) { + ssl->s3->early_data_reason = ssl_early_data_hello_retry_request; + } else { + // |ssl_session_is_resumable| forbids cross-cipher resumptions even if the + // PRF hashes match. + assert(hs->new_cipher == session->cipher); + + ssl->s3->early_data_reason = ssl_early_data_accepted; + ssl->s3->early_data_accepted = true; + } + + // Store the ALPN and ALPS values in the session for 0-RTT. Note the peer + // applications settings are not generally known until client + // EncryptedExtensions. + if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // The peer applications settings are usually received later, in + // EncryptedExtensions. But, in 0-RTT handshakes, we carry over the + // values from |session|. Do this now, before |session| is discarded. + if (ssl->s3->early_data_accepted && + hs->new_session->has_application_settings && + !hs->new_session->peer_application_settings.CopyFrom( + session->peer_application_settings)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Copy the QUIC early data context to the session. + if (ssl->enable_early_data && ssl->quic_method) { + if (!hs->new_session->quic_early_data_context.CopyFrom( + hs->config->quic_early_data_context)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t hash_len = EVP_MD_size( + ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher)); + + // Set up the key schedule and incorporate the PSK into the running secret. + if (!tls13_init_key_schedule( + hs, ssl->s3->session_reused + ? MakeConstSpan(hs->new_session->secret, + hs->new_session->secret_length) + : MakeConstSpan(kZeroes, hash_len)) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + if (!tls13_derive_early_secret(hs)) { + return ssl_hs_error; + } + } else if (hs->early_data_offered) { + ssl->s3->skip_early_data = true; + } + + if (!found_key_share) { + ssl->method->next_message(ssl); + if (!hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; + } + hs->tls13_state = state13_send_hello_retry_request; + return ssl_hs_ok; + } + + if (!resolve_ecdhe_secret(hs, &client_hello)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->ech_client_hello_buf.Reset(); + hs->tls13_state = state13_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->hints_requested) { + return ssl_hs_hints_ready; + } + + ScopedCBB cbb; + CBB body, session_id, extensions; + uint16_t group_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, ssl->version) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, group_id)) { + return ssl_hs_error; + } + if (hs->ech_is_inner) { + // Fill a placeholder for the ECH confirmation value. + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_encrypted_client_hello) || + !CBB_add_u16(&extensions, ECH_CONFIRMATION_SIGNAL_LEN) || + !CBB_add_zeros(&extensions, ECH_CONFIRMATION_SIGNAL_LEN)) { + return ssl_hs_error; + } + } + Array hrr; + if (!ssl->method->finish_message(ssl, cbb.get(), &hrr)) { + return ssl_hs_error; + } + if (hs->ech_is_inner) { + // Now that the message is encoded, fill in the whole value. + size_t offset = hrr.size() - ECH_CONFIRMATION_SIGNAL_LEN; + if (!ssl_ech_accept_confirmation( + hs, MakeSpan(hrr).last(ECH_CONFIRMATION_SIGNAL_LEN), + ssl->s3->client_random, hs->transcript, /*is_hrr=*/true, hrr, + offset)) { + return ssl_hs_error; + } + } + + if (!ssl->method->add_message(ssl, std::move(hrr)) || + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + ssl->s3->used_hello_retry_request = true; + hs->tls13_state = state13_read_second_client_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg.body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (ssl->s3->ech_status == ssl_ech_accepted) { + // If we previously accepted the ClientHelloInner, the second ClientHello + // must contain an outer encrypted_client_hello extension. + CBS ech_body; + if (!ssl_client_hello_get_extension(&client_hello, &ech_body, + TLSEXT_TYPE_encrypted_client_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return ssl_hs_error; + } + uint16_t kdf_id, aead_id; + uint8_t type, config_id; + CBS enc, payload; + if (!CBS_get_u8(&ech_body, &type) || // + type != ECH_CLIENT_OUTER || // + !CBS_get_u16(&ech_body, &kdf_id) || // + !CBS_get_u16(&ech_body, &aead_id) || + !CBS_get_u8(&ech_body, &config_id) || + !CBS_get_u16_length_prefixed(&ech_body, &enc) || + !CBS_get_u16_length_prefixed(&ech_body, &payload) || + CBS_len(&ech_body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (kdf_id != EVP_HPKE_KDF_id(EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get())) || + aead_id != + EVP_HPKE_AEAD_id(EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get())) || + config_id != hs->ech_config_id || CBS_len(&enc) > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Decrypt the payload with the HPKE context from the first ClientHello. + uint8_t alert = SSL_AD_DECODE_ERROR; + bool unused; + if (!ssl_client_hello_decrypt(hs, &alert, &unused, + &hs->ech_client_hello_buf, &client_hello, + payload)) { + // Decryption failure is fatal in the second ClientHello. + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Reparse |client_hello| from the buffer owned by |hs|. + if (!hs->GetClientHello(&msg, &client_hello)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // We perform all our negotiation based on the first ClientHello (for + // consistency with what |select_certificate_cb| observed), which is in the + // transcript, so we can ignore most of this second one. + // + // We do, however, check the second PSK binder. This covers the client key + // share, in case we ever send half-RTT data (we currently do not). It is also + // a tricky computation, so we enforce the peer handled it correctly. + if (ssl->s3->session_reused) { + CBS pre_shared_key; + if (!ssl_client_hello_get_extension(&client_hello, &pre_shared_key, + TLSEXT_TYPE_pre_shared_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INCONSISTENT_CLIENT_HELLO); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + CBS ticket, binders; + uint32_t client_ticket_age; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_pre_shared_key_parse_clienthello( + hs, &ticket, &binders, &client_ticket_age, &alert, &client_hello, + &pre_shared_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Note it is important that we do not obtain a new |SSL_SESSION| from + // |ticket|. We have already selected parameters based on the first + // ClientHello (in the transcript) and must not switch partway through. + if (!tls13_verify_psk_binder(hs, hs->new_session.get(), msg, &binders)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + } + + if (!resolve_ecdhe_secret(hs, &client_hello)) { + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // ClientHello should be the end of the flight. + if (ssl->method->has_unprocessed_handshake_data(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->ech_client_hello_buf.Reset(); + hs->tls13_state = state13_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + Span random(ssl->s3->server_random); + + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + if (hints && !hs->hints_requested && + hints->server_random.size() == random.size()) { + OPENSSL_memcpy(random.data(), hints->server_random.data(), random.size()); + } else { + RAND_bytes(random.data(), random.size()); + if (hints && hs->hints_requested && + !hints->server_random.CopyFrom(random)) { + return ssl_hs_error; + } + } + + Array server_hello; + ScopedCBB cbb; + CBB body, extensions, session_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !CBB_add_bytes(&body, ssl->s3->server_random, + sizeof(ssl->s3->server_random)) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) || + !CBB_add_u8(&body, 0) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) || + !ssl_ext_key_share_add_serverhello(hs, &extensions) || + !ssl_ext_supported_versions_add_serverhello(hs, &extensions) || + !ssl->method->finish_message(ssl, cbb.get(), &server_hello)) { + return ssl_hs_error; + } + + assert(ssl->s3->ech_status != ssl_ech_accepted || hs->ech_is_inner); + if (hs->ech_is_inner) { + // Fill in the ECH confirmation signal. + const size_t offset = ssl_ech_confirmation_signal_hello_offset(ssl); + Span random_suffix = random.last(ECH_CONFIRMATION_SIGNAL_LEN); + if (!ssl_ech_accept_confirmation(hs, random_suffix, ssl->s3->client_random, + hs->transcript, + /*is_hrr=*/false, server_hello, offset)) { + return ssl_hs_error; + } + + // Update |server_hello|. + Span server_hello_out = + MakeSpan(server_hello).subspan(offset, ECH_CONFIRMATION_SIGNAL_LEN); + OPENSSL_memcpy(server_hello_out.data(), random_suffix.data(), + ECH_CONFIRMATION_SIGNAL_LEN); + } + + if (!ssl->method->add_message(ssl, std::move(server_hello))) { + return ssl_hs_error; + } + + hs->ecdh_public_key.Reset(); // No longer needed. + if (!ssl->s3->used_hello_retry_request && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + // Derive and enable the handshake traffic secrets. + if (!tls13_derive_handshake_secrets(hs) || + !tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal, + hs->new_session.get(), + hs->server_handshake_secret())) { + return ssl_hs_error; + } + + // Send EncryptedExtensions. + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_ENCRYPTED_EXTENSIONS) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!ssl->s3->session_reused) { + // Determine whether to request a client certificate. + hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((hs->config->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + hs->channel_id_negotiated) { + hs->cert_request = false; + } + } + + // Send a CertificateRequest, if necessary. + if (hs->cert_request) { + CBB cert_request_extensions, sigalg_contents, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || + !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) || + !CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &sigalg_contents) || + !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(hs, &sigalgs_cbb)) { + return ssl_hs_error; + } + + if (ssl_has_client_CAs(hs->config)) { + CBB ca_contents; + if (!CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_certificate_authorities) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &ca_contents) || + !ssl_add_client_CA_list(hs, &ca_contents) || + !CBB_flush(&cert_request_extensions)) { + return ssl_hs_error; + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send the server Certificate message, if necessary. + if (!ssl->s3->session_reused) { + if (!ssl_has_certificate(hs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state13_send_server_certificate_verify; + return ssl_hs_ok; + } + + hs->tls13_state = state13_send_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) { + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state13_send_server_finished; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state13_send_server_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->hints_requested) { + return ssl_hs_hints_ready; + } + + hs->can_release_private_key = true; + if (!tls13_add_finished(hs) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule( + hs, MakeConstSpan(kZeroes, hs->transcript.DigestLen())) || + !tls13_derive_application_secrets(hs) || + !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal, + hs->new_session.get(), + hs->server_traffic_secret_0())) { + return ssl_hs_error; + } + + hs->tls13_state = state13_send_half_rtt_ticket; + return hs->handback ? ssl_hs_handback : ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_half_rtt_ticket(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->s3->early_data_accepted) { + // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on + // the wire sooner and also avoids triggering a write on |SSL_read| when + // processing the client Finished. This requires computing the client + // Finished early. See RFC 8446, section 4.6.1. + static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, + 0, 0}; + if (ssl->quic_method == nullptr && + !hs->transcript.Update(kEndOfEarlyData)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t finished_len; + if (!tls13_finished_mac(hs, hs->expected_client_finished().data(), + &finished_len, false /* client */)) { + return ssl_hs_error; + } + + if (finished_len != hs->expected_client_finished().size()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Feed the predicted Finished into the transcript. This allows us to derive + // the resumption secret early and send half-RTT tickets. + // + // TODO(davidben): This will need to be updated for DTLS 1.3. + assert(!SSL_is_dtls(hs->ssl)); + assert(hs->expected_client_finished().size() <= 0xff); + uint8_t header[4] = { + SSL3_MT_FINISHED, 0, 0, + static_cast(hs->expected_client_finished().size())}; + bool unused_sent_tickets; + if (!hs->transcript.Update(header) || + !hs->transcript.Update(hs->expected_client_finished()) || + !tls13_derive_resumption_secret(hs) || + !add_new_session_tickets(hs, &unused_sent_tickets)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state13_read_second_client_flight; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->s3->early_data_accepted) { + if (!tls13_set_traffic_key(ssl, ssl_encryption_early_data, evp_aead_open, + hs->new_session.get(), + hs->early_traffic_secret())) { + return ssl_hs_error; + } + hs->can_early_write = true; + hs->can_early_read = true; + hs->in_early_data = true; + } + + // QUIC doesn't use an EndOfEarlyData message (RFC 9001, section 8.3), so we + // switch to client_handshake_secret before the early return. + if (ssl->quic_method != nullptr) { + if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open, + hs->new_session.get(), + hs->client_handshake_secret())) { + return ssl_hs_error; + } + hs->tls13_state = state13_process_end_of_early_data; + return ssl->s3->early_data_accepted ? ssl_hs_early_return : ssl_hs_ok; + } + + hs->tls13_state = state13_process_end_of_early_data; + return ssl->s3->early_data_accepted ? ssl_hs_read_end_of_early_data + : ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // In protocols that use EndOfEarlyData, we must consume the extra message and + // switch to client_handshake_secret after the early return. + if (ssl->quic_method == nullptr) { + // If early data was not accepted, the EndOfEarlyData will be in the + // discarded early data. + if (hs->ssl->s3->early_data_accepted) { + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { + return ssl_hs_error; + } + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + ssl->method->next_message(ssl); + } + if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open, + hs->new_session.get(), + hs->client_handshake_secret())) { + return ssl_hs_error; + } + } + hs->tls13_state = state13_read_client_encrypted_extensions; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_encrypted_extensions( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // For now, only one extension uses client EncryptedExtensions. This function + // may be generalized if others use it in the future. + if (hs->new_session->has_application_settings && + !ssl->s3->early_data_accepted) { + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) { + return ssl_hs_error; + } + + CBS body = msg.body, extensions; + if (!CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + SSLExtension application_settings(TLSEXT_TYPE_application_settings); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, {&application_settings}, + /*ignore_unknown=*/false)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!application_settings.present) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return ssl_hs_error; + } + + // Note that, if 0-RTT was accepted, these values will already have been + // initialized earlier. + if (!hs->new_session->peer_application_settings.CopyFrom( + application_settings.data) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + } + + hs->tls13_state = state13_read_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!hs->cert_request) { + if (!ssl->s3->session_reused) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. (Only do + // this in full handshakes as resumptions should carry over the previous + // |verify_result|, though this is a no-op because servers do not + // implement the client's odd soft-fail mode.) + hs->new_session->verify_result = X509_V_OK; + } + + // Skip this state. + hs->tls13_state = state13_read_channel_id; + return ssl_hs_ok; + } + + const bool allow_anonymous = + (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !tls13_process_certificate(hs, msg, allow_anonymous) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state13_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) { + // Skip this state. + hs->tls13_state = state13_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state13_read_client_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state13_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!hs->channel_id_negotiated) { + hs->tls13_state = state13_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state13_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + // If early data was accepted, we've already computed the client Finished + // and derived the resumption secret. + !tls13_process_finished(hs, msg, ssl->s3->early_data_accepted) || + // evp_aead_seal keys have already been switched. + !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_open, + hs->new_session.get(), + hs->client_traffic_secret_0())) { + return ssl_hs_error; + } + + if (!ssl->s3->early_data_accepted) { + if (!ssl_hash_message(hs, msg) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + // We send post-handshake tickets as part of the handshake in 1-RTT. + hs->tls13_state = state13_send_new_session_ticket; + } else { + // We already sent half-RTT tickets. + hs->tls13_state = state13_done; + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) { + bool sent_tickets; + if (!add_new_session_tickets(hs, &sent_tickets)) { + return ssl_hs_error; + } + + hs->tls13_state = state13_done; + // In TLS 1.3, the NewSessionTicket isn't flushed until the server performs a + // write, to prevent a non-reading client from causing the server to hang in + // the case of a small server write buffer. Consumers which don't write data + // to the client will need to do a zero-byte write if they wish to flush the + // tickets. + if (hs->ssl->quic_method != nullptr && sent_tickets) { + return ssl_hs_flush; + } + return ssl_hs_ok; +} + +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state13_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum tls13_server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state13_select_parameters: + ret = do_select_parameters(hs); + break; + case state13_select_session: + ret = do_select_session(hs); + break; + case state13_send_hello_retry_request: + ret = do_send_hello_retry_request(hs); + break; + case state13_read_second_client_hello: + ret = do_read_second_client_hello(hs); + break; + case state13_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state13_send_server_certificate_verify: + ret = do_send_server_certificate_verify(hs); + break; + case state13_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state13_send_half_rtt_ticket: + ret = do_send_half_rtt_ticket(hs); + break; + case state13_read_second_client_flight: + ret = do_read_second_client_flight(hs); + break; + case state13_process_end_of_early_data: + ret = do_process_end_of_early_data(hs); + break; + case state13_read_client_encrypted_extensions: + ret = do_read_client_encrypted_extensions(hs); + break; + case state13_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state13_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state13_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state13_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state13_send_new_session_ticket: + ret = do_send_new_session_ticket(hs); + break; + case state13_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) { + enum tls13_server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state13_select_parameters: + return "TLS 1.3 server select_parameters"; + case state13_select_session: + return "TLS 1.3 server select_session"; + case state13_send_hello_retry_request: + return "TLS 1.3 server send_hello_retry_request"; + case state13_read_second_client_hello: + return "TLS 1.3 server read_second_client_hello"; + case state13_send_server_hello: + return "TLS 1.3 server send_server_hello"; + case state13_send_server_certificate_verify: + return "TLS 1.3 server send_server_certificate_verify"; + case state13_send_half_rtt_ticket: + return "TLS 1.3 server send_half_rtt_ticket"; + case state13_send_server_finished: + return "TLS 1.3 server send_server_finished"; + case state13_read_second_client_flight: + return "TLS 1.3 server read_second_client_flight"; + case state13_process_end_of_early_data: + return "TLS 1.3 server process_end_of_early_data"; + case state13_read_client_encrypted_extensions: + return "TLS 1.3 server read_client_encrypted_extensions"; + case state13_read_client_certificate: + return "TLS 1.3 server read_client_certificate"; + case state13_read_client_certificate_verify: + return "TLS 1.3 server read_client_certificate_verify"; + case state13_read_channel_id: + return "TLS 1.3 server read_channel_id"; + case state13_read_client_finished: + return "TLS 1.3 server read_client_finished"; + case state13_send_new_session_ticket: + return "TLS 1.3 server send_new_session_ticket"; + case state13_done: + return "TLS 1.3 server done"; + } + + return "TLS 1.3 server unknown"; +} + +BSSL_NAMESPACE_END diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_method.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_method.cc new file mode 100644 index 00000000..1fc1b304 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_method.cc @@ -0,0 +1,319 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include +#include + +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +BSSL_NAMESPACE_BEGIN + +static void tls_on_handshake_complete(SSL *ssl) { + // The handshake should have released its final message. + assert(!ssl->s3->has_message); + + // During the handshake, |hs_buf| is retained. Release if it there is no + // excess in it. There should not be any excess because the handshake logic + // rejects unprocessed data after each Finished message. Note this means we do + // not allow a TLS 1.2 HelloRequest to be packed into the same record as + // Finished. (Schannel also rejects this.) + assert(!ssl->s3->hs_buf || ssl->s3->hs_buf->length == 0); + if (ssl->s3->hs_buf && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +static bool tls_set_read_state(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic) { + // Cipher changes are forbidden if the current epoch has leftover data. + if (tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + if (ssl->quic_method != nullptr) { + if ((ssl->s3->hs == nullptr || !ssl->s3->hs->hints_requested) && + !ssl->quic_method->set_read_secret(ssl, level, aead_ctx->cipher(), + secret_for_quic.data(), + secret_for_quic.size())) { + return false; + } + + // QUIC only uses |ssl| for handshake messages, which never use early data + // keys, so we return without installing anything. This avoids needing to + // have two secrets active at once in 0-RTT. + if (level == ssl_encryption_early_data) { + return true; + } + } + + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + ssl->s3->aead_read_ctx = std::move(aead_ctx); + ssl->s3->read_level = level; + return true; +} + +static bool tls_set_write_state(SSL *ssl, ssl_encryption_level_t level, + UniquePtr aead_ctx, + Span secret_for_quic) { + if (!tls_flush_pending_hs_data(ssl)) { + return false; + } + + if (ssl->quic_method != nullptr) { + if ((ssl->s3->hs == nullptr || !ssl->s3->hs->hints_requested) && + !ssl->quic_method->set_write_secret(ssl, level, aead_ctx->cipher(), + secret_for_quic.data(), + secret_for_quic.size())) { + return false; + } + + // QUIC only uses |ssl| for handshake messages, which never use early data + // keys, so we return without installing anything. This avoids needing to + // have two secrets active at once in 0-RTT. + if (level == ssl_encryption_early_data) { + return true; + } + } + + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + ssl->s3->write_level = level; + return true; +} + +static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = { + false /* is_dtls */, + tls_new, + tls_free, + tls_get_message, + tls_next_message, + tls_has_unprocessed_handshake_data, + tls_open_handshake, + tls_open_change_cipher_spec, + tls_open_app_data, + tls_write_app_data, + tls_dispatch_alert, + tls_init_message, + tls_finish_message, + tls_add_message, + tls_add_change_cipher_spec, + tls_flush_flight, + tls_on_handshake_complete, + tls_set_read_state, + tls_set_write_state, +}; + +static bool ssl_noop_x509_check_client_CA_names( + STACK_OF(CRYPTO_BUFFER) *names) { + return true; +} + +static void ssl_noop_x509_clear(CERT *cert) {} +static void ssl_noop_x509_free(CERT *cert) {} +static void ssl_noop_x509_dup(CERT *new_cert, const CERT *cert) {} +static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {} +static void ssl_noop_x509_flush_cached_chain(CERT *cert) {} +static bool ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) { + return true; +} +static bool ssl_noop_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + return true; +} +static void ssl_noop_x509_session_clear(SSL_SESSION *session) {} +static bool ssl_noop_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL_HANDSHAKE *hs, + uint8_t *out_alert) { + return false; +} + +static void ssl_noop_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {} +static bool ssl_noop_x509_ssl_new(SSL_HANDSHAKE *hs) { return true; } +static void ssl_noop_x509_ssl_config_free(SSL_CONFIG *cfg) {} +static void ssl_noop_x509_ssl_flush_cached_client_CA(SSL_CONFIG *cfg) {} +static bool ssl_noop_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) { + return true; +} +static bool ssl_noop_x509_ssl_ctx_new(SSL_CTX *ctx) { return true; } +static void ssl_noop_x509_ssl_ctx_free(SSL_CTX *ctx) {} +static void ssl_noop_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {} + +const SSL_X509_METHOD ssl_noop_x509_method = { + ssl_noop_x509_check_client_CA_names, + ssl_noop_x509_clear, + ssl_noop_x509_free, + ssl_noop_x509_dup, + ssl_noop_x509_flush_cached_chain, + ssl_noop_x509_flush_cached_leaf, + ssl_noop_x509_session_cache_objects, + ssl_noop_x509_session_dup, + ssl_noop_x509_session_clear, + ssl_noop_x509_session_verify_cert_chain, + ssl_noop_x509_hs_flush_cached_ca_names, + ssl_noop_x509_ssl_new, + ssl_noop_x509_ssl_config_free, + ssl_noop_x509_ssl_flush_cached_client_CA, + ssl_noop_x509_ssl_auto_chain_if_needed, + ssl_noop_x509_ssl_ctx_new, + ssl_noop_x509_ssl_ctx_free, + ssl_noop_x509_ssl_ctx_flush_cached_client_CA, +}; + +BSSL_NAMESPACE_END + +using namespace bssl; + +const SSL_METHOD *TLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *SSLv23_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *TLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + TLS1_2_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *TLSv1_2_server_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_server_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_server_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *TLSv1_2_client_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_client_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_client_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *SSLv23_server_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *SSLv23_client_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *TLS_server_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_client_method(void) { + return TLS_method(); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_record.cc b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_record.cc new file mode 100644 index 00000000..5f52dd56 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/ssl/tls_record.cc @@ -0,0 +1,705 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +BSSL_NAMESPACE_BEGIN + +// kMaxEmptyRecords is the number of consecutive, empty records that will be +// processed. Without this limit an attacker could send empty records at a +// faster rate than we can process and cause record processing to loop +// forever. +static const uint8_t kMaxEmptyRecords = 32; + +// kMaxEarlyDataSkipped is the maximum number of rejected early data bytes that +// will be skipped. Without this limit an attacker could send records at a +// faster rate than we can process and cause trial decryption to loop forever. +// This value should be slightly above kMaxEarlyDataAccepted, which is measured +// in plaintext. +static const size_t kMaxEarlyDataSkipped = 16384; + +// kMaxWarningAlerts is the number of consecutive warning alerts that will be +// processed. +static const uint8_t kMaxWarningAlerts = 4; + +// ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher +// state needs record-splitting and zero otherwise. +static bool ssl_needs_record_splitting(const SSL *ssl) { +#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) + return !ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() < TLS1_1_VERSION && + (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && + SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher()); +#else + return false; +#endif +} + +bool ssl_record_sequence_update(uint8_t *seq, size_t seq_len) { + for (size_t i = seq_len - 1; i < seq_len; i--) { + ++seq[i]; + if (seq[i] != 0) { + return true; + } + } + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; +} + +size_t ssl_record_prefix_len(const SSL *ssl) { + size_t header_len; + if (SSL_is_dtls(ssl)) { + header_len = DTLS1_RT_HEADER_LENGTH; + } else { + header_len = SSL3_RT_HEADER_LENGTH; + } + + return header_len + ssl->s3->aead_read_ctx->ExplicitNonceLen(); +} + +size_t ssl_seal_align_prefix_len(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return DTLS1_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + + size_t ret = + SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + if (ssl_needs_record_splitting(ssl)) { + ret += SSL3_RT_HEADER_LENGTH; + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + } + return ret; +} + +static ssl_open_record_t skip_early_data(SSL *ssl, uint8_t *out_alert, + size_t consumed) { + ssl->s3->early_data_skipped += consumed; + if (ssl->s3->early_data_skipped < consumed) { + ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1; + } + + if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + return ssl_open_record_discard; +} + +ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + // If there is an unprocessed handshake message or we are already buffering + // too much, stop before decrypting another handshake record. + if (!tls_can_accept_handshake_data(ssl, out_alert)) { + return ssl_open_record_error; + } + + CBS cbs = CBS(in); + + // Decode the record header. + uint8_t type; + uint16_t version, ciphertext_len; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_get_u16(&cbs, &ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == SSL3_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return ssl_open_record_error; + } + + // Check the ciphertext length. + if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + // Extract the body. + CBS body; + if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len; + return ssl_open_record_partial; + } + + Span header = in.subspan(0, SSL3_RT_HEADER_LENGTH); + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header); + + *out_consumed = in.size() - CBS_len(&cbs); + + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION && + SSL_in_init(ssl) && + type == SSL3_RT_CHANGE_CIPHER_SPEC && + ciphertext_len == 1 && + CBS_data(&body)[0] == 1) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + // Skip early data received when expecting a second ClientHello if we rejected + // 0RTT. + if (ssl->s3->skip_early_data && + ssl->s3->aead_read_ctx->is_null_cipher() && + type == SSL3_RT_APPLICATION_DATA) { + return skip_early_data(ssl, out_alert, *out_consumed); + } + + // Decrypt the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, ssl->s3->read_sequence, header, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) { + ERR_clear_error(); + return skip_early_data(ssl, out_alert, *out_consumed); + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_BAD_RECORD_MAC; + return ssl_open_record_error; + } + + ssl->s3->skip_early_data = false; + + if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + // TLS 1.3 hides the record type inside the encrypted data. + bool has_padding = + !ssl->s3->aead_read_ctx->is_null_cipher() && + ssl->s3->aead_read_ctx->ProtocolVersion() >= TLS1_3_VERSION; + + // If there is padding, the plaintext limit includes the padding, but includes + // extra room for the inner content type. + size_t plaintext_limit = + has_padding ? SSL3_RT_MAX_PLAIN_LENGTH + 1 : SSL3_RT_MAX_PLAIN_LENGTH; + if (out->size() > plaintext_limit) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + if (has_padding) { + // The outer record type is always application_data. + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + do { + if (out->empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_open_record_error; + } + type = out->back(); + *out = out->subspan(0, out->size() - 1); + } while (type == 0); + } + + // Limit the number of consecutive empty records. + if (out->empty()) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + // Apart from the limit, empty records are returned up to the caller. This + // allows the caller to reject records of the wrong type. + } else { + ssl->s3->empty_record_count = 0; + } + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + // Handshake messages may not interleave with any other record type. + if (type != SSL3_RT_HANDSHAKE && + tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static bool do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, const uint8_t *in, + const size_t in_len) { + SSLAEADContext *aead = ssl->s3->aead_write_ctx.get(); + uint8_t *extra_in = NULL; + size_t extra_in_len = 0; + if (!aead->is_null_cipher() && + aead->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 hides the actual record type inside the encrypted data. + extra_in = &type; + extra_in_len = 1; + } + + size_t suffix_len, ciphertext_len; + if (!aead->SuffixLen(&suffix_len, in_len, extra_in_len) || + !aead->CiphertextLen(&ciphertext_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + + assert(in == out || !buffers_alias(in, in_len, out, in_len)); + assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl))); + assert(!buffers_alias(in, in_len, out_suffix, suffix_len)); + + if (extra_in_len) { + out_prefix[0] = SSL3_RT_APPLICATION_DATA; + } else { + out_prefix[0] = type; + } + + uint16_t record_version = aead->RecordVersion(); + + out_prefix[1] = record_version >> 8; + out_prefix[2] = record_version & 0xff; + out_prefix[3] = ciphertext_len >> 8; + out_prefix[4] = ciphertext_len & 0xff; + Span header = MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH); + + if (!aead->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, + out_prefix[0], record_version, ssl->s3->write_sequence, + header, in, in_len, extra_in, extra_in_len) || + !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header); + return true; +} + +static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type, + size_t in_len) { + size_t ret = SSL3_RT_HEADER_LENGTH; + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // In the case of record splitting, the 1-byte record (of the 1/n-1 split) + // will be placed in the prefix, as will four of the five bytes of the + // record header for the main record. The final byte will replace the first + // byte of the plaintext that was used in the small record. + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + ret += SSL3_RT_HEADER_LENGTH - 1; + } else { + ret += ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + return ret; +} + +static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len, + uint8_t type, size_t in_len) { + size_t extra_in_len = 0; + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 adds an extra byte for encrypted record type. + extra_in_len = 1; + } + // clang-format off + if (type == SSL3_RT_APPLICATION_DATA && + in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // With record splitting enabled, the first byte gets sealed into a separate + // record which is written into the prefix. + in_len -= 1; + } + // clang-format on + return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, extra_in_len); +} + +// tls_seal_scatter_record seals a new record of type |type| and body |in| and +// splits it between |out_prefix|, |out|, and |out_suffix|. Exactly +// |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len| +// bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It +// returns one on success and zero on error. If enabled, +// |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and +// may write two records concatenated. +static bool tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + const uint8_t *in, size_t in_len) { + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0); + const size_t prefix_len = SSL3_RT_HEADER_LENGTH; + + // Write the 1-byte fragment into |out_prefix|. + uint8_t *split_body = out_prefix + prefix_len; + uint8_t *split_suffix = split_body + 1; + + if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in, + 1)) { + return false; + } + + size_t split_record_suffix_len; + if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) { + assert(false); + return false; + } + const size_t split_record_len = prefix_len + 1 + split_record_suffix_len; + assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len( + ssl->s3->aead_write_ctx->cipher()) == + split_record_len); + + // Write the n-1-byte fragment. The header gets split between |out_prefix| + // (header[:-1]) and |out| (header[-1:]). + uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH]; + if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1, + in_len - 1)) { + return false; + } + assert(tls_seal_scatter_prefix_len(ssl, type, in_len) == + split_record_len + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix, + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1); + return true; + } + + return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len); +} + +bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out_len, uint8_t type, const uint8_t *in, + size_t in_len) { + if (buffers_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + + const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) { + return false; + } + if (in_len + prefix_len < in_len || + prefix_len + in_len + suffix_len < prefix_len + in_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (max_out_len < in_len + prefix_len + suffix_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + + uint8_t *prefix = out; + uint8_t *body = out + prefix_len; + uint8_t *suffix = body + in_len; + if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) { + return false; + } + + *out_len = prefix_len + in_len + suffix_len; + return true; +} + +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in) { + // Alerts records may not contain fragmented or multiple alerts. + if (in.size() != 2) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in); + + const uint8_t alert_level = in[0]; + const uint8_t alert_descr = in[1]; + + uint16_t alert = (alert_level << 8) | alert_descr; + ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert); + + if (alert_level == SSL3_AL_WARNING) { + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return ssl_open_record_close_notify; + } + + // Warning alerts do not exist in TLS 1.3, but RFC 8446 section 6.1 + // continues to define user_canceled as a signal to cancel the handshake, + // without specifying how to handle it. JDK11 misuses it to signal + // full-duplex connection close after the handshake. As a workaround, skip + // user_canceled as in TLS 1.2. This matches NSS and OpenSSL. + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION && + alert_descr != SSL_AD_USER_CANCELLED) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count++; + if (ssl->s3->warning_alert_count > kMaxWarningAlerts) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS); + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (alert_level == SSL3_AL_FATAL) { + OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); + ERR_add_error_dataf("SSL alert number %d", alert_descr); + *out_alert = 0; // No alert to send back to the peer. + return ssl_open_record_error; + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE); + return ssl_open_record_error; +} + +OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, uint8_t *out_alert, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + *out_alert = SSL_AD_INTERNAL_ERROR; + return OpenRecordResult::kError; + } + + Span plaintext; + uint8_t type = 0; + const ssl_open_record_t result = tls_open_record( + ssl, &type, &plaintext, out_record_len, out_alert, in); + + switch (result) { + case ssl_open_record_success: + if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return OpenRecordResult::kError; + } + *out = plaintext; + return OpenRecordResult::kOK; + case ssl_open_record_discard: + return OpenRecordResult::kDiscard; + case ssl_open_record_partial: + return OpenRecordResult::kIncompleteRecord; + case ssl_open_record_close_notify: + return OpenRecordResult::kAlertCloseNotify; + case ssl_open_record_error: + return OpenRecordResult::kError; + } + assert(false); + return OpenRecordResult::kError; +} + +size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) { + return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len); +} + +size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) { + assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA, + plaintext_len)) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD); + return suffix_len; +} + +bool SealRecord(SSL *ssl, const Span out_prefix, + const Span out, Span out_suffix, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) || + out.size() != in.size() || + out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(), + out_suffix.data(), SSL3_RT_APPLICATION_DATA, + in.data(), in.size()); +} + +BSSL_NAMESPACE_END + +using namespace bssl; + +size_t SSL_max_seal_overhead(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch); + } + + size_t ret = SSL3_RT_HEADER_LENGTH; + ret += ssl->s3->aead_write_ctx->MaxOverhead(); + // TLS 1.3 needs an extra byte for the encrypted record type. + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + ret += 1; + } + if (ssl_needs_record_splitting(ssl)) { + ret *= 2; + } + return ret; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_32.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_32.h new file mode 100644 index 00000000..cb83c606 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_32.h @@ -0,0 +1,1565 @@ +/* Autogenerated: 'src/ExtractionOCaml/unsaturated_solinas' --inline --static --use-value-barrier 25519 32 '(auto)' '2^255 - 19' carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes relax carry_scmul121666 */ +/* curve description: 25519 */ +/* machine_wordsize = 32 (from "32") */ +/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, relax, carry_scmul121666 */ +/* n = 10 (from "(auto)") */ +/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ +/* tight_bounds_multiplier = 1 (from "") */ +/* */ +/* Computed values: */ +/* carry_chain = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1] */ +/* eval z = z[0] + (z[1] << 26) + (z[2] << 51) + (z[3] << 77) + (z[4] << 102) + (z[5] << 128) + (z[6] << 153) + (z[7] << 179) + (z[8] << 204) + (z[9] << 230) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* balance = [0x7ffffda, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe] */ + +#include +typedef unsigned char fiat_25519_uint1; +typedef signed char fiat_25519_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_25519_FIAT_INLINE __inline__ +#else +# define FIAT_25519_FIAT_INLINE +#endif + +/* The type fiat_25519_loose_field_element is a field element with loose bounds. */ +/* Bounds: [[0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000]] */ +typedef uint32_t fiat_25519_loose_field_element[10]; + +/* The type fiat_25519_tight_field_element is a field element with tight bounds. */ +/* Bounds: [[0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000]] */ +typedef uint32_t fiat_25519_tight_field_element[10]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#if !defined(FIAT_25519_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint32_t fiat_25519_value_barrier_u32(uint32_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_25519_value_barrier_u32(x) (x) +#endif + + +/* + * The function fiat_25519_addcarryx_u26 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^26 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^26⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x3ffffff] + * arg3: [0x0 ~> 0x3ffffff] + * Output Bounds: + * out1: [0x0 ~> 0x3ffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint32_t x1; + uint32_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT32_C(0x3ffffff)); + x3 = (fiat_25519_uint1)(x1 >> 26); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_25519_subborrowx_u26 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^26 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^26⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x3ffffff] + * arg3: [0x0 ~> 0x3ffffff] + * Output Bounds: + * out1: [0x0 ~> 0x3ffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int32_t x1; + fiat_25519_int1 x2; + uint32_t x3; + x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 26); + x3 = (x1 & UINT32_C(0x3ffffff)); + *out1 = x3; + *out2 = (fiat_25519_uint1)(0x0 - x2); +} + +/* + * The function fiat_25519_addcarryx_u25 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^25 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^25⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x1ffffff] + * arg3: [0x0 ~> 0x1ffffff] + * Output Bounds: + * out1: [0x0 ~> 0x1ffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint32_t x1; + uint32_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT32_C(0x1ffffff)); + x3 = (fiat_25519_uint1)(x1 >> 25); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_25519_subborrowx_u25 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^25 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^25⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x1ffffff] + * arg3: [0x0 ~> 0x1ffffff] + * Output Bounds: + * out1: [0x0 ~> 0x1ffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int32_t x1; + fiat_25519_int1 x2; + uint32_t x3; + x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 25); + x3 = (x1 & UINT32_C(0x1ffffff)); + *out1 = x3; + *out2 = (fiat_25519_uint1)(0x0 - x2); +} + +/* + * The function fiat_25519_cmovznz_u32 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_cmovznz_u32(uint32_t* out1, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + fiat_25519_uint1 x1; + uint32_t x2; + uint32_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_25519_int1)(0x0 - x1) & UINT32_C(0xffffffff)); + x3 = ((fiat_25519_value_barrier_u32(x2) & arg3) | (fiat_25519_value_barrier_u32((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_25519_carry_mul multiplies two field elements and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_mul(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1, const fiat_25519_loose_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + uint64_t x74; + uint64_t x75; + uint64_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + uint64_t x93; + uint64_t x94; + uint64_t x95; + uint64_t x96; + uint64_t x97; + uint64_t x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint32_t x103; + uint64_t x104; + uint64_t x105; + uint64_t x106; + uint64_t x107; + uint64_t x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint32_t x115; + uint64_t x116; + uint64_t x117; + uint32_t x118; + uint64_t x119; + uint64_t x120; + uint32_t x121; + uint64_t x122; + uint64_t x123; + uint32_t x124; + uint64_t x125; + uint64_t x126; + uint32_t x127; + uint64_t x128; + uint64_t x129; + uint32_t x130; + uint64_t x131; + uint64_t x132; + uint32_t x133; + uint64_t x134; + uint64_t x135; + uint32_t x136; + uint64_t x137; + uint64_t x138; + uint32_t x139; + uint64_t x140; + uint64_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + fiat_25519_uint1 x145; + uint32_t x146; + uint32_t x147; + x1 = ((uint64_t)(arg1[9]) * ((arg2[9]) * UINT8_C(0x26))); + x2 = ((uint64_t)(arg1[9]) * ((arg2[8]) * UINT8_C(0x13))); + x3 = ((uint64_t)(arg1[9]) * ((arg2[7]) * UINT8_C(0x26))); + x4 = ((uint64_t)(arg1[9]) * ((arg2[6]) * UINT8_C(0x13))); + x5 = ((uint64_t)(arg1[9]) * ((arg2[5]) * UINT8_C(0x26))); + x6 = ((uint64_t)(arg1[9]) * ((arg2[4]) * UINT8_C(0x13))); + x7 = ((uint64_t)(arg1[9]) * ((arg2[3]) * UINT8_C(0x26))); + x8 = ((uint64_t)(arg1[9]) * ((arg2[2]) * UINT8_C(0x13))); + x9 = ((uint64_t)(arg1[9]) * ((arg2[1]) * UINT8_C(0x26))); + x10 = ((uint64_t)(arg1[8]) * ((arg2[9]) * UINT8_C(0x13))); + x11 = ((uint64_t)(arg1[8]) * ((arg2[8]) * UINT8_C(0x13))); + x12 = ((uint64_t)(arg1[8]) * ((arg2[7]) * UINT8_C(0x13))); + x13 = ((uint64_t)(arg1[8]) * ((arg2[6]) * UINT8_C(0x13))); + x14 = ((uint64_t)(arg1[8]) * ((arg2[5]) * UINT8_C(0x13))); + x15 = ((uint64_t)(arg1[8]) * ((arg2[4]) * UINT8_C(0x13))); + x16 = ((uint64_t)(arg1[8]) * ((arg2[3]) * UINT8_C(0x13))); + x17 = ((uint64_t)(arg1[8]) * ((arg2[2]) * UINT8_C(0x13))); + x18 = ((uint64_t)(arg1[7]) * ((arg2[9]) * UINT8_C(0x26))); + x19 = ((uint64_t)(arg1[7]) * ((arg2[8]) * UINT8_C(0x13))); + x20 = ((uint64_t)(arg1[7]) * ((arg2[7]) * UINT8_C(0x26))); + x21 = ((uint64_t)(arg1[7]) * ((arg2[6]) * UINT8_C(0x13))); + x22 = ((uint64_t)(arg1[7]) * ((arg2[5]) * UINT8_C(0x26))); + x23 = ((uint64_t)(arg1[7]) * ((arg2[4]) * UINT8_C(0x13))); + x24 = ((uint64_t)(arg1[7]) * ((arg2[3]) * UINT8_C(0x26))); + x25 = ((uint64_t)(arg1[6]) * ((arg2[9]) * UINT8_C(0x13))); + x26 = ((uint64_t)(arg1[6]) * ((arg2[8]) * UINT8_C(0x13))); + x27 = ((uint64_t)(arg1[6]) * ((arg2[7]) * UINT8_C(0x13))); + x28 = ((uint64_t)(arg1[6]) * ((arg2[6]) * UINT8_C(0x13))); + x29 = ((uint64_t)(arg1[6]) * ((arg2[5]) * UINT8_C(0x13))); + x30 = ((uint64_t)(arg1[6]) * ((arg2[4]) * UINT8_C(0x13))); + x31 = ((uint64_t)(arg1[5]) * ((arg2[9]) * UINT8_C(0x26))); + x32 = ((uint64_t)(arg1[5]) * ((arg2[8]) * UINT8_C(0x13))); + x33 = ((uint64_t)(arg1[5]) * ((arg2[7]) * UINT8_C(0x26))); + x34 = ((uint64_t)(arg1[5]) * ((arg2[6]) * UINT8_C(0x13))); + x35 = ((uint64_t)(arg1[5]) * ((arg2[5]) * UINT8_C(0x26))); + x36 = ((uint64_t)(arg1[4]) * ((arg2[9]) * UINT8_C(0x13))); + x37 = ((uint64_t)(arg1[4]) * ((arg2[8]) * UINT8_C(0x13))); + x38 = ((uint64_t)(arg1[4]) * ((arg2[7]) * UINT8_C(0x13))); + x39 = ((uint64_t)(arg1[4]) * ((arg2[6]) * UINT8_C(0x13))); + x40 = ((uint64_t)(arg1[3]) * ((arg2[9]) * UINT8_C(0x26))); + x41 = ((uint64_t)(arg1[3]) * ((arg2[8]) * UINT8_C(0x13))); + x42 = ((uint64_t)(arg1[3]) * ((arg2[7]) * UINT8_C(0x26))); + x43 = ((uint64_t)(arg1[2]) * ((arg2[9]) * UINT8_C(0x13))); + x44 = ((uint64_t)(arg1[2]) * ((arg2[8]) * UINT8_C(0x13))); + x45 = ((uint64_t)(arg1[1]) * ((arg2[9]) * UINT8_C(0x26))); + x46 = ((uint64_t)(arg1[9]) * (arg2[0])); + x47 = ((uint64_t)(arg1[8]) * (arg2[1])); + x48 = ((uint64_t)(arg1[8]) * (arg2[0])); + x49 = ((uint64_t)(arg1[7]) * (arg2[2])); + x50 = ((uint64_t)(arg1[7]) * ((arg2[1]) * 0x2)); + x51 = ((uint64_t)(arg1[7]) * (arg2[0])); + x52 = ((uint64_t)(arg1[6]) * (arg2[3])); + x53 = ((uint64_t)(arg1[6]) * (arg2[2])); + x54 = ((uint64_t)(arg1[6]) * (arg2[1])); + x55 = ((uint64_t)(arg1[6]) * (arg2[0])); + x56 = ((uint64_t)(arg1[5]) * (arg2[4])); + x57 = ((uint64_t)(arg1[5]) * ((arg2[3]) * 0x2)); + x58 = ((uint64_t)(arg1[5]) * (arg2[2])); + x59 = ((uint64_t)(arg1[5]) * ((arg2[1]) * 0x2)); + x60 = ((uint64_t)(arg1[5]) * (arg2[0])); + x61 = ((uint64_t)(arg1[4]) * (arg2[5])); + x62 = ((uint64_t)(arg1[4]) * (arg2[4])); + x63 = ((uint64_t)(arg1[4]) * (arg2[3])); + x64 = ((uint64_t)(arg1[4]) * (arg2[2])); + x65 = ((uint64_t)(arg1[4]) * (arg2[1])); + x66 = ((uint64_t)(arg1[4]) * (arg2[0])); + x67 = ((uint64_t)(arg1[3]) * (arg2[6])); + x68 = ((uint64_t)(arg1[3]) * ((arg2[5]) * 0x2)); + x69 = ((uint64_t)(arg1[3]) * (arg2[4])); + x70 = ((uint64_t)(arg1[3]) * ((arg2[3]) * 0x2)); + x71 = ((uint64_t)(arg1[3]) * (arg2[2])); + x72 = ((uint64_t)(arg1[3]) * ((arg2[1]) * 0x2)); + x73 = ((uint64_t)(arg1[3]) * (arg2[0])); + x74 = ((uint64_t)(arg1[2]) * (arg2[7])); + x75 = ((uint64_t)(arg1[2]) * (arg2[6])); + x76 = ((uint64_t)(arg1[2]) * (arg2[5])); + x77 = ((uint64_t)(arg1[2]) * (arg2[4])); + x78 = ((uint64_t)(arg1[2]) * (arg2[3])); + x79 = ((uint64_t)(arg1[2]) * (arg2[2])); + x80 = ((uint64_t)(arg1[2]) * (arg2[1])); + x81 = ((uint64_t)(arg1[2]) * (arg2[0])); + x82 = ((uint64_t)(arg1[1]) * (arg2[8])); + x83 = ((uint64_t)(arg1[1]) * ((arg2[7]) * 0x2)); + x84 = ((uint64_t)(arg1[1]) * (arg2[6])); + x85 = ((uint64_t)(arg1[1]) * ((arg2[5]) * 0x2)); + x86 = ((uint64_t)(arg1[1]) * (arg2[4])); + x87 = ((uint64_t)(arg1[1]) * ((arg2[3]) * 0x2)); + x88 = ((uint64_t)(arg1[1]) * (arg2[2])); + x89 = ((uint64_t)(arg1[1]) * ((arg2[1]) * 0x2)); + x90 = ((uint64_t)(arg1[1]) * (arg2[0])); + x91 = ((uint64_t)(arg1[0]) * (arg2[9])); + x92 = ((uint64_t)(arg1[0]) * (arg2[8])); + x93 = ((uint64_t)(arg1[0]) * (arg2[7])); + x94 = ((uint64_t)(arg1[0]) * (arg2[6])); + x95 = ((uint64_t)(arg1[0]) * (arg2[5])); + x96 = ((uint64_t)(arg1[0]) * (arg2[4])); + x97 = ((uint64_t)(arg1[0]) * (arg2[3])); + x98 = ((uint64_t)(arg1[0]) * (arg2[2])); + x99 = ((uint64_t)(arg1[0]) * (arg2[1])); + x100 = ((uint64_t)(arg1[0]) * (arg2[0])); + x101 = (x100 + (x45 + (x44 + (x42 + (x39 + (x35 + (x30 + (x24 + (x17 + x9))))))))); + x102 = (x101 >> 26); + x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); + x104 = (x91 + (x82 + (x74 + (x67 + (x61 + (x56 + (x52 + (x49 + (x47 + x46))))))))); + x105 = (x92 + (x83 + (x75 + (x68 + (x62 + (x57 + (x53 + (x50 + (x48 + x1))))))))); + x106 = (x93 + (x84 + (x76 + (x69 + (x63 + (x58 + (x54 + (x51 + (x10 + x2))))))))); + x107 = (x94 + (x85 + (x77 + (x70 + (x64 + (x59 + (x55 + (x18 + (x11 + x3))))))))); + x108 = (x95 + (x86 + (x78 + (x71 + (x65 + (x60 + (x25 + (x19 + (x12 + x4))))))))); + x109 = (x96 + (x87 + (x79 + (x72 + (x66 + (x31 + (x26 + (x20 + (x13 + x5))))))))); + x110 = (x97 + (x88 + (x80 + (x73 + (x36 + (x32 + (x27 + (x21 + (x14 + x6))))))))); + x111 = (x98 + (x89 + (x81 + (x40 + (x37 + (x33 + (x28 + (x22 + (x15 + x7))))))))); + x112 = (x99 + (x90 + (x43 + (x41 + (x38 + (x34 + (x29 + (x23 + (x16 + x8))))))))); + x113 = (x102 + x112); + x114 = (x113 >> 25); + x115 = (uint32_t)(x113 & UINT32_C(0x1ffffff)); + x116 = (x114 + x111); + x117 = (x116 >> 26); + x118 = (uint32_t)(x116 & UINT32_C(0x3ffffff)); + x119 = (x117 + x110); + x120 = (x119 >> 25); + x121 = (uint32_t)(x119 & UINT32_C(0x1ffffff)); + x122 = (x120 + x109); + x123 = (x122 >> 26); + x124 = (uint32_t)(x122 & UINT32_C(0x3ffffff)); + x125 = (x123 + x108); + x126 = (x125 >> 25); + x127 = (uint32_t)(x125 & UINT32_C(0x1ffffff)); + x128 = (x126 + x107); + x129 = (x128 >> 26); + x130 = (uint32_t)(x128 & UINT32_C(0x3ffffff)); + x131 = (x129 + x106); + x132 = (x131 >> 25); + x133 = (uint32_t)(x131 & UINT32_C(0x1ffffff)); + x134 = (x132 + x105); + x135 = (x134 >> 26); + x136 = (uint32_t)(x134 & UINT32_C(0x3ffffff)); + x137 = (x135 + x104); + x138 = (x137 >> 25); + x139 = (uint32_t)(x137 & UINT32_C(0x1ffffff)); + x140 = (x138 * UINT8_C(0x13)); + x141 = (x103 + x140); + x142 = (uint32_t)(x141 >> 26); + x143 = (uint32_t)(x141 & UINT32_C(0x3ffffff)); + x144 = (x142 + x115); + x145 = (fiat_25519_uint1)(x144 >> 25); + x146 = (x144 & UINT32_C(0x1ffffff)); + x147 = (x145 + x118); + out1[0] = x143; + out1[1] = x146; + out1[2] = x147; + out1[3] = x121; + out1[4] = x124; + out1[5] = x127; + out1[6] = x130; + out1[7] = x133; + out1[8] = x136; + out1[9] = x139; +} + +/* + * The function fiat_25519_carry_square squares a field element and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_square(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint64_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint64_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + uint64_t x74; + uint64_t x75; + uint32_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint32_t x88; + uint64_t x89; + uint64_t x90; + uint32_t x91; + uint64_t x92; + uint64_t x93; + uint32_t x94; + uint64_t x95; + uint64_t x96; + uint32_t x97; + uint64_t x98; + uint64_t x99; + uint32_t x100; + uint64_t x101; + uint64_t x102; + uint32_t x103; + uint64_t x104; + uint64_t x105; + uint32_t x106; + uint64_t x107; + uint64_t x108; + uint32_t x109; + uint64_t x110; + uint64_t x111; + uint32_t x112; + uint64_t x113; + uint64_t x114; + uint32_t x115; + uint32_t x116; + uint32_t x117; + fiat_25519_uint1 x118; + uint32_t x119; + uint32_t x120; + x1 = ((arg1[9]) * UINT8_C(0x13)); + x2 = (x1 * 0x2); + x3 = ((arg1[9]) * 0x2); + x4 = ((arg1[8]) * UINT8_C(0x13)); + x5 = ((uint64_t)x4 * 0x2); + x6 = ((arg1[8]) * 0x2); + x7 = ((arg1[7]) * UINT8_C(0x13)); + x8 = (x7 * 0x2); + x9 = ((arg1[7]) * 0x2); + x10 = ((arg1[6]) * UINT8_C(0x13)); + x11 = ((uint64_t)x10 * 0x2); + x12 = ((arg1[6]) * 0x2); + x13 = ((arg1[5]) * UINT8_C(0x13)); + x14 = ((arg1[5]) * 0x2); + x15 = ((arg1[4]) * 0x2); + x16 = ((arg1[3]) * 0x2); + x17 = ((arg1[2]) * 0x2); + x18 = ((arg1[1]) * 0x2); + x19 = ((uint64_t)(arg1[9]) * (x1 * 0x2)); + x20 = ((uint64_t)(arg1[8]) * x2); + x21 = ((uint64_t)(arg1[8]) * x4); + x22 = ((arg1[7]) * ((uint64_t)x2 * 0x2)); + x23 = ((arg1[7]) * x5); + x24 = ((uint64_t)(arg1[7]) * (x7 * 0x2)); + x25 = ((uint64_t)(arg1[6]) * x2); + x26 = ((arg1[6]) * x5); + x27 = ((uint64_t)(arg1[6]) * x8); + x28 = ((uint64_t)(arg1[6]) * x10); + x29 = ((arg1[5]) * ((uint64_t)x2 * 0x2)); + x30 = ((arg1[5]) * x5); + x31 = ((arg1[5]) * ((uint64_t)x8 * 0x2)); + x32 = ((arg1[5]) * x11); + x33 = ((uint64_t)(arg1[5]) * (x13 * 0x2)); + x34 = ((uint64_t)(arg1[4]) * x2); + x35 = ((arg1[4]) * x5); + x36 = ((uint64_t)(arg1[4]) * x8); + x37 = ((arg1[4]) * x11); + x38 = ((uint64_t)(arg1[4]) * x14); + x39 = ((uint64_t)(arg1[4]) * (arg1[4])); + x40 = ((arg1[3]) * ((uint64_t)x2 * 0x2)); + x41 = ((arg1[3]) * x5); + x42 = ((arg1[3]) * ((uint64_t)x8 * 0x2)); + x43 = ((uint64_t)(arg1[3]) * x12); + x44 = ((uint64_t)(arg1[3]) * (x14 * 0x2)); + x45 = ((uint64_t)(arg1[3]) * x15); + x46 = ((uint64_t)(arg1[3]) * ((arg1[3]) * 0x2)); + x47 = ((uint64_t)(arg1[2]) * x2); + x48 = ((arg1[2]) * x5); + x49 = ((uint64_t)(arg1[2]) * x9); + x50 = ((uint64_t)(arg1[2]) * x12); + x51 = ((uint64_t)(arg1[2]) * x14); + x52 = ((uint64_t)(arg1[2]) * x15); + x53 = ((uint64_t)(arg1[2]) * x16); + x54 = ((uint64_t)(arg1[2]) * (arg1[2])); + x55 = ((arg1[1]) * ((uint64_t)x2 * 0x2)); + x56 = ((uint64_t)(arg1[1]) * x6); + x57 = ((uint64_t)(arg1[1]) * (x9 * 0x2)); + x58 = ((uint64_t)(arg1[1]) * x12); + x59 = ((uint64_t)(arg1[1]) * (x14 * 0x2)); + x60 = ((uint64_t)(arg1[1]) * x15); + x61 = ((uint64_t)(arg1[1]) * (x16 * 0x2)); + x62 = ((uint64_t)(arg1[1]) * x17); + x63 = ((uint64_t)(arg1[1]) * ((arg1[1]) * 0x2)); + x64 = ((uint64_t)(arg1[0]) * x3); + x65 = ((uint64_t)(arg1[0]) * x6); + x66 = ((uint64_t)(arg1[0]) * x9); + x67 = ((uint64_t)(arg1[0]) * x12); + x68 = ((uint64_t)(arg1[0]) * x14); + x69 = ((uint64_t)(arg1[0]) * x15); + x70 = ((uint64_t)(arg1[0]) * x16); + x71 = ((uint64_t)(arg1[0]) * x17); + x72 = ((uint64_t)(arg1[0]) * x18); + x73 = ((uint64_t)(arg1[0]) * (arg1[0])); + x74 = (x73 + (x55 + (x48 + (x42 + (x37 + x33))))); + x75 = (x74 >> 26); + x76 = (uint32_t)(x74 & UINT32_C(0x3ffffff)); + x77 = (x64 + (x56 + (x49 + (x43 + x38)))); + x78 = (x65 + (x57 + (x50 + (x44 + (x39 + x19))))); + x79 = (x66 + (x58 + (x51 + (x45 + x20)))); + x80 = (x67 + (x59 + (x52 + (x46 + (x22 + x21))))); + x81 = (x68 + (x60 + (x53 + (x25 + x23)))); + x82 = (x69 + (x61 + (x54 + (x29 + (x26 + x24))))); + x83 = (x70 + (x62 + (x34 + (x30 + x27)))); + x84 = (x71 + (x63 + (x40 + (x35 + (x31 + x28))))); + x85 = (x72 + (x47 + (x41 + (x36 + x32)))); + x86 = (x75 + x85); + x87 = (x86 >> 25); + x88 = (uint32_t)(x86 & UINT32_C(0x1ffffff)); + x89 = (x87 + x84); + x90 = (x89 >> 26); + x91 = (uint32_t)(x89 & UINT32_C(0x3ffffff)); + x92 = (x90 + x83); + x93 = (x92 >> 25); + x94 = (uint32_t)(x92 & UINT32_C(0x1ffffff)); + x95 = (x93 + x82); + x96 = (x95 >> 26); + x97 = (uint32_t)(x95 & UINT32_C(0x3ffffff)); + x98 = (x96 + x81); + x99 = (x98 >> 25); + x100 = (uint32_t)(x98 & UINT32_C(0x1ffffff)); + x101 = (x99 + x80); + x102 = (x101 >> 26); + x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); + x104 = (x102 + x79); + x105 = (x104 >> 25); + x106 = (uint32_t)(x104 & UINT32_C(0x1ffffff)); + x107 = (x105 + x78); + x108 = (x107 >> 26); + x109 = (uint32_t)(x107 & UINT32_C(0x3ffffff)); + x110 = (x108 + x77); + x111 = (x110 >> 25); + x112 = (uint32_t)(x110 & UINT32_C(0x1ffffff)); + x113 = (x111 * UINT8_C(0x13)); + x114 = (x76 + x113); + x115 = (uint32_t)(x114 >> 26); + x116 = (uint32_t)(x114 & UINT32_C(0x3ffffff)); + x117 = (x115 + x88); + x118 = (fiat_25519_uint1)(x117 >> 25); + x119 = (x117 & UINT32_C(0x1ffffff)); + x120 = (x118 + x91); + out1[0] = x116; + out1[1] = x119; + out1[2] = x120; + out1[3] = x94; + out1[4] = x97; + out1[5] = x100; + out1[6] = x103; + out1[7] = x106; + out1[8] = x109; + out1[9] = x112; +} + +/* + * The function fiat_25519_carry reduces a field element. + * + * Postconditions: + * eval out1 mod m = eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + x1 = (arg1[0]); + x2 = ((x1 >> 26) + (arg1[1])); + x3 = ((x2 >> 25) + (arg1[2])); + x4 = ((x3 >> 26) + (arg1[3])); + x5 = ((x4 >> 25) + (arg1[4])); + x6 = ((x5 >> 26) + (arg1[5])); + x7 = ((x6 >> 25) + (arg1[6])); + x8 = ((x7 >> 26) + (arg1[7])); + x9 = ((x8 >> 25) + (arg1[8])); + x10 = ((x9 >> 26) + (arg1[9])); + x11 = ((x1 & UINT32_C(0x3ffffff)) + ((x10 >> 25) * UINT8_C(0x13))); + x12 = ((fiat_25519_uint1)(x11 >> 26) + (x2 & UINT32_C(0x1ffffff))); + x13 = (x11 & UINT32_C(0x3ffffff)); + x14 = (x12 & UINT32_C(0x1ffffff)); + x15 = ((fiat_25519_uint1)(x12 >> 25) + (x3 & UINT32_C(0x3ffffff))); + x16 = (x4 & UINT32_C(0x1ffffff)); + x17 = (x5 & UINT32_C(0x3ffffff)); + x18 = (x6 & UINT32_C(0x1ffffff)); + x19 = (x7 & UINT32_C(0x3ffffff)); + x20 = (x8 & UINT32_C(0x1ffffff)); + x21 = (x9 & UINT32_C(0x3ffffff)); + x22 = (x10 & UINT32_C(0x1ffffff)); + out1[0] = x13; + out1[1] = x14; + out1[2] = x15; + out1[3] = x16; + out1[4] = x17; + out1[5] = x18; + out1[6] = x19; + out1[7] = x20; + out1[8] = x21; + out1[9] = x22; +} + +/* + * The function fiat_25519_add adds two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 + eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_add(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = ((arg1[0]) + (arg2[0])); + x2 = ((arg1[1]) + (arg2[1])); + x3 = ((arg1[2]) + (arg2[2])); + x4 = ((arg1[3]) + (arg2[3])); + x5 = ((arg1[4]) + (arg2[4])); + x6 = ((arg1[5]) + (arg2[5])); + x7 = ((arg1[6]) + (arg2[6])); + x8 = ((arg1[7]) + (arg2[7])); + x9 = ((arg1[8]) + (arg2[8])); + x10 = ((arg1[9]) + (arg2[9])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; +} + +/* + * The function fiat_25519_sub subtracts two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 - eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_sub(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = ((UINT32_C(0x7ffffda) + (arg1[0])) - (arg2[0])); + x2 = ((UINT32_C(0x3fffffe) + (arg1[1])) - (arg2[1])); + x3 = ((UINT32_C(0x7fffffe) + (arg1[2])) - (arg2[2])); + x4 = ((UINT32_C(0x3fffffe) + (arg1[3])) - (arg2[3])); + x5 = ((UINT32_C(0x7fffffe) + (arg1[4])) - (arg2[4])); + x6 = ((UINT32_C(0x3fffffe) + (arg1[5])) - (arg2[5])); + x7 = ((UINT32_C(0x7fffffe) + (arg1[6])) - (arg2[6])); + x8 = ((UINT32_C(0x3fffffe) + (arg1[7])) - (arg2[7])); + x9 = ((UINT32_C(0x7fffffe) + (arg1[8])) - (arg2[8])); + x10 = ((UINT32_C(0x3fffffe) + (arg1[9])) - (arg2[9])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; +} + +/* + * The function fiat_25519_opp negates a field element. + * + * Postconditions: + * eval out1 mod m = -eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_opp(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = (UINT32_C(0x7ffffda) - (arg1[0])); + x2 = (UINT32_C(0x3fffffe) - (arg1[1])); + x3 = (UINT32_C(0x7fffffe) - (arg1[2])); + x4 = (UINT32_C(0x3fffffe) - (arg1[3])); + x5 = (UINT32_C(0x7fffffe) - (arg1[4])); + x6 = (UINT32_C(0x3fffffe) - (arg1[5])); + x7 = (UINT32_C(0x7fffffe) - (arg1[6])); + x8 = (UINT32_C(0x3fffffe) - (arg1[7])); + x9 = (UINT32_C(0x7fffffe) - (arg1[8])); + x10 = (UINT32_C(0x3fffffe) - (arg1[9])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; +} + +/* + * The function fiat_25519_selectznz is a multi-limb conditional select. + * + * Postconditions: + * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_selectznz(uint32_t out1[10], fiat_25519_uint1 arg1, const uint32_t arg2[10], const uint32_t arg3[10]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + fiat_25519_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_25519_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_25519_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_25519_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_25519_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); + fiat_25519_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); + fiat_25519_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); + fiat_25519_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); + fiat_25519_cmovznz_u32(&x9, arg1, (arg2[8]), (arg3[8])); + fiat_25519_cmovznz_u32(&x10, arg1, (arg2[9]), (arg3[9])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; +} + +/* + * The function fiat_25519_to_bytes serializes a field element to bytes in little-endian order. + * + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_to_bytes(uint8_t out1[32], const fiat_25519_tight_field_element arg1) { + uint32_t x1; + fiat_25519_uint1 x2; + uint32_t x3; + fiat_25519_uint1 x4; + uint32_t x5; + fiat_25519_uint1 x6; + uint32_t x7; + fiat_25519_uint1 x8; + uint32_t x9; + fiat_25519_uint1 x10; + uint32_t x11; + fiat_25519_uint1 x12; + uint32_t x13; + fiat_25519_uint1 x14; + uint32_t x15; + fiat_25519_uint1 x16; + uint32_t x17; + fiat_25519_uint1 x18; + uint32_t x19; + fiat_25519_uint1 x20; + uint32_t x21; + uint32_t x22; + fiat_25519_uint1 x23; + uint32_t x24; + fiat_25519_uint1 x25; + uint32_t x26; + fiat_25519_uint1 x27; + uint32_t x28; + fiat_25519_uint1 x29; + uint32_t x30; + fiat_25519_uint1 x31; + uint32_t x32; + fiat_25519_uint1 x33; + uint32_t x34; + fiat_25519_uint1 x35; + uint32_t x36; + fiat_25519_uint1 x37; + uint32_t x38; + fiat_25519_uint1 x39; + uint32_t x40; + fiat_25519_uint1 x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint8_t x50; + uint32_t x51; + uint8_t x52; + uint32_t x53; + uint8_t x54; + uint8_t x55; + uint32_t x56; + uint8_t x57; + uint32_t x58; + uint8_t x59; + uint32_t x60; + uint8_t x61; + uint8_t x62; + uint32_t x63; + uint8_t x64; + uint32_t x65; + uint8_t x66; + uint32_t x67; + uint8_t x68; + uint8_t x69; + uint32_t x70; + uint8_t x71; + uint32_t x72; + uint8_t x73; + uint32_t x74; + uint8_t x75; + uint8_t x76; + uint32_t x77; + uint8_t x78; + uint32_t x79; + uint8_t x80; + uint32_t x81; + uint8_t x82; + uint8_t x83; + uint8_t x84; + uint32_t x85; + uint8_t x86; + uint32_t x87; + uint8_t x88; + fiat_25519_uint1 x89; + uint32_t x90; + uint8_t x91; + uint32_t x92; + uint8_t x93; + uint32_t x94; + uint8_t x95; + uint8_t x96; + uint32_t x97; + uint8_t x98; + uint32_t x99; + uint8_t x100; + uint32_t x101; + uint8_t x102; + uint8_t x103; + uint32_t x104; + uint8_t x105; + uint32_t x106; + uint8_t x107; + uint32_t x108; + uint8_t x109; + uint8_t x110; + uint32_t x111; + uint8_t x112; + uint32_t x113; + uint8_t x114; + uint32_t x115; + uint8_t x116; + uint8_t x117; + fiat_25519_subborrowx_u26(&x1, &x2, 0x0, (arg1[0]), UINT32_C(0x3ffffed)); + fiat_25519_subborrowx_u25(&x3, &x4, x2, (arg1[1]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x5, &x6, x4, (arg1[2]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x7, &x8, x6, (arg1[3]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x9, &x10, x8, (arg1[4]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x11, &x12, x10, (arg1[5]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x13, &x14, x12, (arg1[6]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x15, &x16, x14, (arg1[7]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x17, &x18, x16, (arg1[8]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x19, &x20, x18, (arg1[9]), UINT32_C(0x1ffffff)); + fiat_25519_cmovznz_u32(&x21, x20, 0x0, UINT32_C(0xffffffff)); + fiat_25519_addcarryx_u26(&x22, &x23, 0x0, x1, (x21 & UINT32_C(0x3ffffed))); + fiat_25519_addcarryx_u25(&x24, &x25, x23, x3, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x26, &x27, x25, x5, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x28, &x29, x27, x7, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x30, &x31, x29, x9, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x32, &x33, x31, x11, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x34, &x35, x33, x13, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x36, &x37, x35, x15, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x38, &x39, x37, x17, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x40, &x41, x39, x19, (x21 & UINT32_C(0x1ffffff))); + x42 = (x40 << 6); + x43 = (x38 << 4); + x44 = (x36 << 3); + x45 = (x34 * (uint32_t)0x2); + x46 = (x30 << 6); + x47 = (x28 << 5); + x48 = (x26 << 3); + x49 = (x24 << 2); + x50 = (uint8_t)(x22 & UINT8_C(0xff)); + x51 = (x22 >> 8); + x52 = (uint8_t)(x51 & UINT8_C(0xff)); + x53 = (x51 >> 8); + x54 = (uint8_t)(x53 & UINT8_C(0xff)); + x55 = (uint8_t)(x53 >> 8); + x56 = (x49 + (uint32_t)x55); + x57 = (uint8_t)(x56 & UINT8_C(0xff)); + x58 = (x56 >> 8); + x59 = (uint8_t)(x58 & UINT8_C(0xff)); + x60 = (x58 >> 8); + x61 = (uint8_t)(x60 & UINT8_C(0xff)); + x62 = (uint8_t)(x60 >> 8); + x63 = (x48 + (uint32_t)x62); + x64 = (uint8_t)(x63 & UINT8_C(0xff)); + x65 = (x63 >> 8); + x66 = (uint8_t)(x65 & UINT8_C(0xff)); + x67 = (x65 >> 8); + x68 = (uint8_t)(x67 & UINT8_C(0xff)); + x69 = (uint8_t)(x67 >> 8); + x70 = (x47 + (uint32_t)x69); + x71 = (uint8_t)(x70 & UINT8_C(0xff)); + x72 = (x70 >> 8); + x73 = (uint8_t)(x72 & UINT8_C(0xff)); + x74 = (x72 >> 8); + x75 = (uint8_t)(x74 & UINT8_C(0xff)); + x76 = (uint8_t)(x74 >> 8); + x77 = (x46 + (uint32_t)x76); + x78 = (uint8_t)(x77 & UINT8_C(0xff)); + x79 = (x77 >> 8); + x80 = (uint8_t)(x79 & UINT8_C(0xff)); + x81 = (x79 >> 8); + x82 = (uint8_t)(x81 & UINT8_C(0xff)); + x83 = (uint8_t)(x81 >> 8); + x84 = (uint8_t)(x32 & UINT8_C(0xff)); + x85 = (x32 >> 8); + x86 = (uint8_t)(x85 & UINT8_C(0xff)); + x87 = (x85 >> 8); + x88 = (uint8_t)(x87 & UINT8_C(0xff)); + x89 = (fiat_25519_uint1)(x87 >> 8); + x90 = (x45 + (uint32_t)x89); + x91 = (uint8_t)(x90 & UINT8_C(0xff)); + x92 = (x90 >> 8); + x93 = (uint8_t)(x92 & UINT8_C(0xff)); + x94 = (x92 >> 8); + x95 = (uint8_t)(x94 & UINT8_C(0xff)); + x96 = (uint8_t)(x94 >> 8); + x97 = (x44 + (uint32_t)x96); + x98 = (uint8_t)(x97 & UINT8_C(0xff)); + x99 = (x97 >> 8); + x100 = (uint8_t)(x99 & UINT8_C(0xff)); + x101 = (x99 >> 8); + x102 = (uint8_t)(x101 & UINT8_C(0xff)); + x103 = (uint8_t)(x101 >> 8); + x104 = (x43 + (uint32_t)x103); + x105 = (uint8_t)(x104 & UINT8_C(0xff)); + x106 = (x104 >> 8); + x107 = (uint8_t)(x106 & UINT8_C(0xff)); + x108 = (x106 >> 8); + x109 = (uint8_t)(x108 & UINT8_C(0xff)); + x110 = (uint8_t)(x108 >> 8); + x111 = (x42 + (uint32_t)x110); + x112 = (uint8_t)(x111 & UINT8_C(0xff)); + x113 = (x111 >> 8); + x114 = (uint8_t)(x113 & UINT8_C(0xff)); + x115 = (x113 >> 8); + x116 = (uint8_t)(x115 & UINT8_C(0xff)); + x117 = (uint8_t)(x115 >> 8); + out1[0] = x50; + out1[1] = x52; + out1[2] = x54; + out1[3] = x57; + out1[4] = x59; + out1[5] = x61; + out1[6] = x64; + out1[7] = x66; + out1[8] = x68; + out1[9] = x71; + out1[10] = x73; + out1[11] = x75; + out1[12] = x78; + out1[13] = x80; + out1[14] = x82; + out1[15] = x83; + out1[16] = x84; + out1[17] = x86; + out1[18] = x88; + out1[19] = x91; + out1[20] = x93; + out1[21] = x95; + out1[22] = x98; + out1[23] = x100; + out1[24] = x102; + out1[25] = x105; + out1[26] = x107; + out1[27] = x109; + out1[28] = x112; + out1[29] = x114; + out1[30] = x116; + out1[31] = x117; +} + +/* + * The function fiat_25519_from_bytes deserializes a field element from bytes in little-endian order. + * + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_from_bytes(fiat_25519_tight_field_element out1, const uint8_t arg1[32]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint8_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint32_t x24; + uint32_t x25; + uint32_t x26; + uint32_t x27; + uint32_t x28; + uint32_t x29; + uint32_t x30; + uint32_t x31; + uint8_t x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint8_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint8_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint8_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + uint8_t x52; + uint32_t x53; + uint32_t x54; + uint32_t x55; + uint32_t x56; + uint32_t x57; + uint32_t x58; + uint32_t x59; + uint8_t x60; + uint32_t x61; + uint32_t x62; + uint32_t x63; + uint32_t x64; + uint8_t x65; + uint32_t x66; + uint32_t x67; + uint32_t x68; + uint32_t x69; + uint8_t x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint8_t x75; + uint32_t x76; + uint32_t x77; + uint32_t x78; + x1 = ((uint32_t)(arg1[31]) << 18); + x2 = ((uint32_t)(arg1[30]) << 10); + x3 = ((uint32_t)(arg1[29]) << 2); + x4 = ((uint32_t)(arg1[28]) << 20); + x5 = ((uint32_t)(arg1[27]) << 12); + x6 = ((uint32_t)(arg1[26]) << 4); + x7 = ((uint32_t)(arg1[25]) << 21); + x8 = ((uint32_t)(arg1[24]) << 13); + x9 = ((uint32_t)(arg1[23]) << 5); + x10 = ((uint32_t)(arg1[22]) << 23); + x11 = ((uint32_t)(arg1[21]) << 15); + x12 = ((uint32_t)(arg1[20]) << 7); + x13 = ((uint32_t)(arg1[19]) << 24); + x14 = ((uint32_t)(arg1[18]) << 16); + x15 = ((uint32_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint32_t)(arg1[15]) << 18); + x18 = ((uint32_t)(arg1[14]) << 10); + x19 = ((uint32_t)(arg1[13]) << 2); + x20 = ((uint32_t)(arg1[12]) << 19); + x21 = ((uint32_t)(arg1[11]) << 11); + x22 = ((uint32_t)(arg1[10]) << 3); + x23 = ((uint32_t)(arg1[9]) << 21); + x24 = ((uint32_t)(arg1[8]) << 13); + x25 = ((uint32_t)(arg1[7]) << 5); + x26 = ((uint32_t)(arg1[6]) << 22); + x27 = ((uint32_t)(arg1[5]) << 14); + x28 = ((uint32_t)(arg1[4]) << 6); + x29 = ((uint32_t)(arg1[3]) << 24); + x30 = ((uint32_t)(arg1[2]) << 16); + x31 = ((uint32_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint32_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x35 & UINT32_C(0x3ffffff)); + x37 = (uint8_t)(x35 >> 26); + x38 = (x28 + (uint32_t)x37); + x39 = (x27 + x38); + x40 = (x26 + x39); + x41 = (x40 & UINT32_C(0x1ffffff)); + x42 = (uint8_t)(x40 >> 25); + x43 = (x25 + (uint32_t)x42); + x44 = (x24 + x43); + x45 = (x23 + x44); + x46 = (x45 & UINT32_C(0x3ffffff)); + x47 = (uint8_t)(x45 >> 26); + x48 = (x22 + (uint32_t)x47); + x49 = (x21 + x48); + x50 = (x20 + x49); + x51 = (x50 & UINT32_C(0x1ffffff)); + x52 = (uint8_t)(x50 >> 25); + x53 = (x19 + (uint32_t)x52); + x54 = (x18 + x53); + x55 = (x17 + x54); + x56 = (x15 + (uint32_t)x16); + x57 = (x14 + x56); + x58 = (x13 + x57); + x59 = (x58 & UINT32_C(0x1ffffff)); + x60 = (uint8_t)(x58 >> 25); + x61 = (x12 + (uint32_t)x60); + x62 = (x11 + x61); + x63 = (x10 + x62); + x64 = (x63 & UINT32_C(0x3ffffff)); + x65 = (uint8_t)(x63 >> 26); + x66 = (x9 + (uint32_t)x65); + x67 = (x8 + x66); + x68 = (x7 + x67); + x69 = (x68 & UINT32_C(0x1ffffff)); + x70 = (uint8_t)(x68 >> 25); + x71 = (x6 + (uint32_t)x70); + x72 = (x5 + x71); + x73 = (x4 + x72); + x74 = (x73 & UINT32_C(0x3ffffff)); + x75 = (uint8_t)(x73 >> 26); + x76 = (x3 + (uint32_t)x75); + x77 = (x2 + x76); + x78 = (x1 + x77); + out1[0] = x36; + out1[1] = x41; + out1[2] = x46; + out1[3] = x51; + out1[4] = x55; + out1[5] = x59; + out1[6] = x64; + out1[7] = x69; + out1[8] = x74; + out1[9] = x78; +} + +/* + * The function fiat_25519_relax is the identity function converting from tight field elements to loose field elements. + * + * Postconditions: + * out1 = arg1 + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_relax(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = (arg1[0]); + x2 = (arg1[1]); + x3 = (arg1[2]); + x4 = (arg1[3]); + x5 = (arg1[4]); + x6 = (arg1[5]); + x7 = (arg1[6]); + x8 = (arg1[7]); + x9 = (arg1[8]); + x10 = (arg1[9]); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; +} + +/* + * The function fiat_25519_carry_scmul_121666 multiplies a field element by 121666 and reduces the result. + * + * Postconditions: + * eval out1 mod m = (121666 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_scmul_121666(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint32_t x11; + uint32_t x12; + uint64_t x13; + uint32_t x14; + uint32_t x15; + uint64_t x16; + uint32_t x17; + uint32_t x18; + uint64_t x19; + uint32_t x20; + uint32_t x21; + uint64_t x22; + uint32_t x23; + uint32_t x24; + uint64_t x25; + uint32_t x26; + uint32_t x27; + uint64_t x28; + uint32_t x29; + uint32_t x30; + uint64_t x31; + uint32_t x32; + uint32_t x33; + uint64_t x34; + uint32_t x35; + uint32_t x36; + uint64_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + fiat_25519_uint1 x42; + uint32_t x43; + uint32_t x44; + fiat_25519_uint1 x45; + uint32_t x46; + uint32_t x47; + x1 = ((uint64_t)UINT32_C(0x1db42) * (arg1[9])); + x2 = ((uint64_t)UINT32_C(0x1db42) * (arg1[8])); + x3 = ((uint64_t)UINT32_C(0x1db42) * (arg1[7])); + x4 = ((uint64_t)UINT32_C(0x1db42) * (arg1[6])); + x5 = ((uint64_t)UINT32_C(0x1db42) * (arg1[5])); + x6 = ((uint64_t)UINT32_C(0x1db42) * (arg1[4])); + x7 = ((uint64_t)UINT32_C(0x1db42) * (arg1[3])); + x8 = ((uint64_t)UINT32_C(0x1db42) * (arg1[2])); + x9 = ((uint64_t)UINT32_C(0x1db42) * (arg1[1])); + x10 = ((uint64_t)UINT32_C(0x1db42) * (arg1[0])); + x11 = (uint32_t)(x10 >> 26); + x12 = (uint32_t)(x10 & UINT32_C(0x3ffffff)); + x13 = (x11 + x9); + x14 = (uint32_t)(x13 >> 25); + x15 = (uint32_t)(x13 & UINT32_C(0x1ffffff)); + x16 = (x14 + x8); + x17 = (uint32_t)(x16 >> 26); + x18 = (uint32_t)(x16 & UINT32_C(0x3ffffff)); + x19 = (x17 + x7); + x20 = (uint32_t)(x19 >> 25); + x21 = (uint32_t)(x19 & UINT32_C(0x1ffffff)); + x22 = (x20 + x6); + x23 = (uint32_t)(x22 >> 26); + x24 = (uint32_t)(x22 & UINT32_C(0x3ffffff)); + x25 = (x23 + x5); + x26 = (uint32_t)(x25 >> 25); + x27 = (uint32_t)(x25 & UINT32_C(0x1ffffff)); + x28 = (x26 + x4); + x29 = (uint32_t)(x28 >> 26); + x30 = (uint32_t)(x28 & UINT32_C(0x3ffffff)); + x31 = (x29 + x3); + x32 = (uint32_t)(x31 >> 25); + x33 = (uint32_t)(x31 & UINT32_C(0x1ffffff)); + x34 = (x32 + x2); + x35 = (uint32_t)(x34 >> 26); + x36 = (uint32_t)(x34 & UINT32_C(0x3ffffff)); + x37 = (x35 + x1); + x38 = (uint32_t)(x37 >> 25); + x39 = (uint32_t)(x37 & UINT32_C(0x1ffffff)); + x40 = (x38 * UINT8_C(0x13)); + x41 = (x12 + x40); + x42 = (fiat_25519_uint1)(x41 >> 26); + x43 = (x41 & UINT32_C(0x3ffffff)); + x44 = (x42 + x15); + x45 = (fiat_25519_uint1)(x44 >> 25); + x46 = (x44 & UINT32_C(0x1ffffff)); + x47 = (x45 + x18); + out1[0] = x43; + out1[1] = x46; + out1[2] = x47; + out1[3] = x21; + out1[4] = x24; + out1[5] = x27; + out1[6] = x30; + out1[7] = x33; + out1[8] = x36; + out1[9] = x39; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_64.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_64.h new file mode 100644 index 00000000..faed049d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/curve25519_64.h @@ -0,0 +1,972 @@ +/* Autogenerated: 'src/ExtractionOCaml/unsaturated_solinas' --inline --static --use-value-barrier 25519 64 '(auto)' '2^255 - 19' carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes relax carry_scmul121666 */ +/* curve description: 25519 */ +/* machine_wordsize = 64 (from "64") */ +/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, relax, carry_scmul121666 */ +/* n = 5 (from "(auto)") */ +/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ +/* tight_bounds_multiplier = 1 (from "") */ +/* */ +/* Computed values: */ +/* carry_chain = [0, 1, 2, 3, 4, 0, 1] */ +/* eval z = z[0] + (z[1] << 51) + (z[2] << 102) + (z[3] << 153) + (z[4] << 204) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* balance = [0xfffffffffffda, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe] */ + +#include +typedef unsigned char fiat_25519_uint1; +typedef signed char fiat_25519_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_25519_FIAT_EXTENSION __extension__ +# define FIAT_25519_FIAT_INLINE __inline__ +#else +# define FIAT_25519_FIAT_EXTENSION +# define FIAT_25519_FIAT_INLINE +#endif + +FIAT_25519_FIAT_EXTENSION typedef signed __int128 fiat_25519_int128; +FIAT_25519_FIAT_EXTENSION typedef unsigned __int128 fiat_25519_uint128; + +/* The type fiat_25519_loose_field_element is a field element with loose bounds. */ +/* Bounds: [[0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000]] */ +typedef uint64_t fiat_25519_loose_field_element[5]; + +/* The type fiat_25519_tight_field_element is a field element with tight bounds. */ +/* Bounds: [[0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000]] */ +typedef uint64_t fiat_25519_tight_field_element[5]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#if !defined(FIAT_25519_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint64_t fiat_25519_value_barrier_u64(uint64_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_25519_value_barrier_u64(x) (x) +#endif + + +/* + * The function fiat_25519_addcarryx_u51 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^51 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^51⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x7ffffffffffff] + * arg3: [0x0 ~> 0x7ffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0x7ffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + uint64_t x1; + uint64_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT64_C(0x7ffffffffffff)); + x3 = (fiat_25519_uint1)(x1 >> 51); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_25519_subborrowx_u51 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^51 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^51⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x7ffffffffffff] + * arg3: [0x0 ~> 0x7ffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0x7ffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + int64_t x1; + fiat_25519_int1 x2; + uint64_t x3; + x1 = ((int64_t)(arg2 - (int64_t)arg1) - (int64_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 51); + x3 = (x1 & UINT64_C(0x7ffffffffffff)); + *out1 = x3; + *out2 = (fiat_25519_uint1)(0x0 - x2); +} + +/* + * The function fiat_25519_cmovznz_u64 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_cmovznz_u64(uint64_t* out1, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_25519_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_25519_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_25519_value_barrier_u64(x2) & arg3) | (fiat_25519_value_barrier_u64((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_25519_carry_mul multiplies two field elements and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_mul(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1, const fiat_25519_loose_field_element arg2) { + fiat_25519_uint128 x1; + fiat_25519_uint128 x2; + fiat_25519_uint128 x3; + fiat_25519_uint128 x4; + fiat_25519_uint128 x5; + fiat_25519_uint128 x6; + fiat_25519_uint128 x7; + fiat_25519_uint128 x8; + fiat_25519_uint128 x9; + fiat_25519_uint128 x10; + fiat_25519_uint128 x11; + fiat_25519_uint128 x12; + fiat_25519_uint128 x13; + fiat_25519_uint128 x14; + fiat_25519_uint128 x15; + fiat_25519_uint128 x16; + fiat_25519_uint128 x17; + fiat_25519_uint128 x18; + fiat_25519_uint128 x19; + fiat_25519_uint128 x20; + fiat_25519_uint128 x21; + fiat_25519_uint128 x22; + fiat_25519_uint128 x23; + fiat_25519_uint128 x24; + fiat_25519_uint128 x25; + fiat_25519_uint128 x26; + uint64_t x27; + uint64_t x28; + fiat_25519_uint128 x29; + fiat_25519_uint128 x30; + fiat_25519_uint128 x31; + fiat_25519_uint128 x32; + fiat_25519_uint128 x33; + uint64_t x34; + uint64_t x35; + fiat_25519_uint128 x36; + uint64_t x37; + uint64_t x38; + fiat_25519_uint128 x39; + uint64_t x40; + uint64_t x41; + fiat_25519_uint128 x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + fiat_25519_uint1 x50; + uint64_t x51; + uint64_t x52; + x1 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[4]) * UINT8_C(0x13))); + x2 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[3]) * UINT8_C(0x13))); + x3 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[2]) * UINT8_C(0x13))); + x4 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[1]) * UINT8_C(0x13))); + x5 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[4]) * UINT8_C(0x13))); + x6 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[3]) * UINT8_C(0x13))); + x7 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[2]) * UINT8_C(0x13))); + x8 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[4]) * UINT8_C(0x13))); + x9 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[3]) * UINT8_C(0x13))); + x10 = ((fiat_25519_uint128)(arg1[1]) * ((arg2[4]) * UINT8_C(0x13))); + x11 = ((fiat_25519_uint128)(arg1[4]) * (arg2[0])); + x12 = ((fiat_25519_uint128)(arg1[3]) * (arg2[1])); + x13 = ((fiat_25519_uint128)(arg1[3]) * (arg2[0])); + x14 = ((fiat_25519_uint128)(arg1[2]) * (arg2[2])); + x15 = ((fiat_25519_uint128)(arg1[2]) * (arg2[1])); + x16 = ((fiat_25519_uint128)(arg1[2]) * (arg2[0])); + x17 = ((fiat_25519_uint128)(arg1[1]) * (arg2[3])); + x18 = ((fiat_25519_uint128)(arg1[1]) * (arg2[2])); + x19 = ((fiat_25519_uint128)(arg1[1]) * (arg2[1])); + x20 = ((fiat_25519_uint128)(arg1[1]) * (arg2[0])); + x21 = ((fiat_25519_uint128)(arg1[0]) * (arg2[4])); + x22 = ((fiat_25519_uint128)(arg1[0]) * (arg2[3])); + x23 = ((fiat_25519_uint128)(arg1[0]) * (arg2[2])); + x24 = ((fiat_25519_uint128)(arg1[0]) * (arg2[1])); + x25 = ((fiat_25519_uint128)(arg1[0]) * (arg2[0])); + x26 = (x25 + (x10 + (x9 + (x7 + x4)))); + x27 = (uint64_t)(x26 >> 51); + x28 = (uint64_t)(x26 & UINT64_C(0x7ffffffffffff)); + x29 = (x21 + (x17 + (x14 + (x12 + x11)))); + x30 = (x22 + (x18 + (x15 + (x13 + x1)))); + x31 = (x23 + (x19 + (x16 + (x5 + x2)))); + x32 = (x24 + (x20 + (x8 + (x6 + x3)))); + x33 = (x27 + x32); + x34 = (uint64_t)(x33 >> 51); + x35 = (uint64_t)(x33 & UINT64_C(0x7ffffffffffff)); + x36 = (x34 + x31); + x37 = (uint64_t)(x36 >> 51); + x38 = (uint64_t)(x36 & UINT64_C(0x7ffffffffffff)); + x39 = (x37 + x30); + x40 = (uint64_t)(x39 >> 51); + x41 = (uint64_t)(x39 & UINT64_C(0x7ffffffffffff)); + x42 = (x40 + x29); + x43 = (uint64_t)(x42 >> 51); + x44 = (uint64_t)(x42 & UINT64_C(0x7ffffffffffff)); + x45 = (x43 * UINT8_C(0x13)); + x46 = (x28 + x45); + x47 = (x46 >> 51); + x48 = (x46 & UINT64_C(0x7ffffffffffff)); + x49 = (x47 + x35); + x50 = (fiat_25519_uint1)(x49 >> 51); + x51 = (x49 & UINT64_C(0x7ffffffffffff)); + x52 = (x50 + x38); + out1[0] = x48; + out1[1] = x51; + out1[2] = x52; + out1[3] = x41; + out1[4] = x44; +} + +/* + * The function fiat_25519_carry_square squares a field element and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_square(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + fiat_25519_uint128 x9; + fiat_25519_uint128 x10; + fiat_25519_uint128 x11; + fiat_25519_uint128 x12; + fiat_25519_uint128 x13; + fiat_25519_uint128 x14; + fiat_25519_uint128 x15; + fiat_25519_uint128 x16; + fiat_25519_uint128 x17; + fiat_25519_uint128 x18; + fiat_25519_uint128 x19; + fiat_25519_uint128 x20; + fiat_25519_uint128 x21; + fiat_25519_uint128 x22; + fiat_25519_uint128 x23; + fiat_25519_uint128 x24; + uint64_t x25; + uint64_t x26; + fiat_25519_uint128 x27; + fiat_25519_uint128 x28; + fiat_25519_uint128 x29; + fiat_25519_uint128 x30; + fiat_25519_uint128 x31; + uint64_t x32; + uint64_t x33; + fiat_25519_uint128 x34; + uint64_t x35; + uint64_t x36; + fiat_25519_uint128 x37; + uint64_t x38; + uint64_t x39; + fiat_25519_uint128 x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_25519_uint1 x48; + uint64_t x49; + uint64_t x50; + x1 = ((arg1[4]) * UINT8_C(0x13)); + x2 = (x1 * 0x2); + x3 = ((arg1[4]) * 0x2); + x4 = ((arg1[3]) * UINT8_C(0x13)); + x5 = (x4 * 0x2); + x6 = ((arg1[3]) * 0x2); + x7 = ((arg1[2]) * 0x2); + x8 = ((arg1[1]) * 0x2); + x9 = ((fiat_25519_uint128)(arg1[4]) * x1); + x10 = ((fiat_25519_uint128)(arg1[3]) * x2); + x11 = ((fiat_25519_uint128)(arg1[3]) * x4); + x12 = ((fiat_25519_uint128)(arg1[2]) * x2); + x13 = ((fiat_25519_uint128)(arg1[2]) * x5); + x14 = ((fiat_25519_uint128)(arg1[2]) * (arg1[2])); + x15 = ((fiat_25519_uint128)(arg1[1]) * x2); + x16 = ((fiat_25519_uint128)(arg1[1]) * x6); + x17 = ((fiat_25519_uint128)(arg1[1]) * x7); + x18 = ((fiat_25519_uint128)(arg1[1]) * (arg1[1])); + x19 = ((fiat_25519_uint128)(arg1[0]) * x3); + x20 = ((fiat_25519_uint128)(arg1[0]) * x6); + x21 = ((fiat_25519_uint128)(arg1[0]) * x7); + x22 = ((fiat_25519_uint128)(arg1[0]) * x8); + x23 = ((fiat_25519_uint128)(arg1[0]) * (arg1[0])); + x24 = (x23 + (x15 + x13)); + x25 = (uint64_t)(x24 >> 51); + x26 = (uint64_t)(x24 & UINT64_C(0x7ffffffffffff)); + x27 = (x19 + (x16 + x14)); + x28 = (x20 + (x17 + x9)); + x29 = (x21 + (x18 + x10)); + x30 = (x22 + (x12 + x11)); + x31 = (x25 + x30); + x32 = (uint64_t)(x31 >> 51); + x33 = (uint64_t)(x31 & UINT64_C(0x7ffffffffffff)); + x34 = (x32 + x29); + x35 = (uint64_t)(x34 >> 51); + x36 = (uint64_t)(x34 & UINT64_C(0x7ffffffffffff)); + x37 = (x35 + x28); + x38 = (uint64_t)(x37 >> 51); + x39 = (uint64_t)(x37 & UINT64_C(0x7ffffffffffff)); + x40 = (x38 + x27); + x41 = (uint64_t)(x40 >> 51); + x42 = (uint64_t)(x40 & UINT64_C(0x7ffffffffffff)); + x43 = (x41 * UINT8_C(0x13)); + x44 = (x26 + x43); + x45 = (x44 >> 51); + x46 = (x44 & UINT64_C(0x7ffffffffffff)); + x47 = (x45 + x33); + x48 = (fiat_25519_uint1)(x47 >> 51); + x49 = (x47 & UINT64_C(0x7ffffffffffff)); + x50 = (x48 + x36); + out1[0] = x46; + out1[1] = x49; + out1[2] = x50; + out1[3] = x39; + out1[4] = x42; +} + +/* + * The function fiat_25519_carry reduces a field element. + * + * Postconditions: + * eval out1 mod m = eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + x1 = (arg1[0]); + x2 = ((x1 >> 51) + (arg1[1])); + x3 = ((x2 >> 51) + (arg1[2])); + x4 = ((x3 >> 51) + (arg1[3])); + x5 = ((x4 >> 51) + (arg1[4])); + x6 = ((x1 & UINT64_C(0x7ffffffffffff)) + ((x5 >> 51) * UINT8_C(0x13))); + x7 = ((fiat_25519_uint1)(x6 >> 51) + (x2 & UINT64_C(0x7ffffffffffff))); + x8 = (x6 & UINT64_C(0x7ffffffffffff)); + x9 = (x7 & UINT64_C(0x7ffffffffffff)); + x10 = ((fiat_25519_uint1)(x7 >> 51) + (x3 & UINT64_C(0x7ffffffffffff))); + x11 = (x4 & UINT64_C(0x7ffffffffffff)); + x12 = (x5 & UINT64_C(0x7ffffffffffff)); + out1[0] = x8; + out1[1] = x9; + out1[2] = x10; + out1[3] = x11; + out1[4] = x12; +} + +/* + * The function fiat_25519_add adds two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 + eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_add(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((arg1[0]) + (arg2[0])); + x2 = ((arg1[1]) + (arg2[1])); + x3 = ((arg1[2]) + (arg2[2])); + x4 = ((arg1[3]) + (arg2[3])); + x5 = ((arg1[4]) + (arg2[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_sub subtracts two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 - eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_sub(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((UINT64_C(0xfffffffffffda) + (arg1[0])) - (arg2[0])); + x2 = ((UINT64_C(0xffffffffffffe) + (arg1[1])) - (arg2[1])); + x3 = ((UINT64_C(0xffffffffffffe) + (arg1[2])) - (arg2[2])); + x4 = ((UINT64_C(0xffffffffffffe) + (arg1[3])) - (arg2[3])); + x5 = ((UINT64_C(0xffffffffffffe) + (arg1[4])) - (arg2[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_opp negates a field element. + * + * Postconditions: + * eval out1 mod m = -eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_opp(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (UINT64_C(0xfffffffffffda) - (arg1[0])); + x2 = (UINT64_C(0xffffffffffffe) - (arg1[1])); + x3 = (UINT64_C(0xffffffffffffe) - (arg1[2])); + x4 = (UINT64_C(0xffffffffffffe) - (arg1[3])); + x5 = (UINT64_C(0xffffffffffffe) - (arg1[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_selectznz is a multi-limb conditional select. + * + * Postconditions: + * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_selectznz(uint64_t out1[5], fiat_25519_uint1 arg1, const uint64_t arg2[5], const uint64_t arg3[5]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + fiat_25519_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_25519_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_25519_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_25519_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_25519_cmovznz_u64(&x5, arg1, (arg2[4]), (arg3[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_to_bytes serializes a field element to bytes in little-endian order. + * + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_to_bytes(uint8_t out1[32], const fiat_25519_tight_field_element arg1) { + uint64_t x1; + fiat_25519_uint1 x2; + uint64_t x3; + fiat_25519_uint1 x4; + uint64_t x5; + fiat_25519_uint1 x6; + uint64_t x7; + fiat_25519_uint1 x8; + uint64_t x9; + fiat_25519_uint1 x10; + uint64_t x11; + uint64_t x12; + fiat_25519_uint1 x13; + uint64_t x14; + fiat_25519_uint1 x15; + uint64_t x16; + fiat_25519_uint1 x17; + uint64_t x18; + fiat_25519_uint1 x19; + uint64_t x20; + fiat_25519_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint8_t x26; + uint64_t x27; + uint8_t x28; + uint64_t x29; + uint8_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint8_t x34; + uint64_t x35; + uint8_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint64_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint8_t x50; + uint64_t x51; + uint8_t x52; + uint64_t x53; + uint8_t x54; + uint64_t x55; + uint8_t x56; + uint64_t x57; + uint8_t x58; + uint64_t x59; + uint8_t x60; + uint64_t x61; + uint8_t x62; + uint64_t x63; + uint8_t x64; + fiat_25519_uint1 x65; + uint64_t x66; + uint8_t x67; + uint64_t x68; + uint8_t x69; + uint64_t x70; + uint8_t x71; + uint64_t x72; + uint8_t x73; + uint64_t x74; + uint8_t x75; + uint64_t x76; + uint8_t x77; + uint8_t x78; + uint64_t x79; + uint8_t x80; + uint64_t x81; + uint8_t x82; + uint64_t x83; + uint8_t x84; + uint64_t x85; + uint8_t x86; + uint64_t x87; + uint8_t x88; + uint64_t x89; + uint8_t x90; + uint8_t x91; + fiat_25519_subborrowx_u51(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0x7ffffffffffed)); + fiat_25519_subborrowx_u51(&x3, &x4, x2, (arg1[1]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x5, &x6, x4, (arg1[2]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x7, &x8, x6, (arg1[3]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x9, &x10, x8, (arg1[4]), UINT64_C(0x7ffffffffffff)); + fiat_25519_cmovznz_u64(&x11, x10, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_25519_addcarryx_u51(&x12, &x13, 0x0, x1, (x11 & UINT64_C(0x7ffffffffffed))); + fiat_25519_addcarryx_u51(&x14, &x15, x13, x3, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x16, &x17, x15, x5, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x18, &x19, x17, x7, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x20, &x21, x19, x9, (x11 & UINT64_C(0x7ffffffffffff))); + x22 = (x20 << 4); + x23 = (x18 * (uint64_t)0x2); + x24 = (x16 << 6); + x25 = (x14 << 3); + x26 = (uint8_t)(x12 & UINT8_C(0xff)); + x27 = (x12 >> 8); + x28 = (uint8_t)(x27 & UINT8_C(0xff)); + x29 = (x27 >> 8); + x30 = (uint8_t)(x29 & UINT8_C(0xff)); + x31 = (x29 >> 8); + x32 = (uint8_t)(x31 & UINT8_C(0xff)); + x33 = (x31 >> 8); + x34 = (uint8_t)(x33 & UINT8_C(0xff)); + x35 = (x33 >> 8); + x36 = (uint8_t)(x35 & UINT8_C(0xff)); + x37 = (uint8_t)(x35 >> 8); + x38 = (x25 + (uint64_t)x37); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (x44 >> 8); + x47 = (uint8_t)(x46 & UINT8_C(0xff)); + x48 = (x46 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (uint8_t)(x48 >> 8); + x51 = (x24 + (uint64_t)x50); + x52 = (uint8_t)(x51 & UINT8_C(0xff)); + x53 = (x51 >> 8); + x54 = (uint8_t)(x53 & UINT8_C(0xff)); + x55 = (x53 >> 8); + x56 = (uint8_t)(x55 & UINT8_C(0xff)); + x57 = (x55 >> 8); + x58 = (uint8_t)(x57 & UINT8_C(0xff)); + x59 = (x57 >> 8); + x60 = (uint8_t)(x59 & UINT8_C(0xff)); + x61 = (x59 >> 8); + x62 = (uint8_t)(x61 & UINT8_C(0xff)); + x63 = (x61 >> 8); + x64 = (uint8_t)(x63 & UINT8_C(0xff)); + x65 = (fiat_25519_uint1)(x63 >> 8); + x66 = (x23 + (uint64_t)x65); + x67 = (uint8_t)(x66 & UINT8_C(0xff)); + x68 = (x66 >> 8); + x69 = (uint8_t)(x68 & UINT8_C(0xff)); + x70 = (x68 >> 8); + x71 = (uint8_t)(x70 & UINT8_C(0xff)); + x72 = (x70 >> 8); + x73 = (uint8_t)(x72 & UINT8_C(0xff)); + x74 = (x72 >> 8); + x75 = (uint8_t)(x74 & UINT8_C(0xff)); + x76 = (x74 >> 8); + x77 = (uint8_t)(x76 & UINT8_C(0xff)); + x78 = (uint8_t)(x76 >> 8); + x79 = (x22 + (uint64_t)x78); + x80 = (uint8_t)(x79 & UINT8_C(0xff)); + x81 = (x79 >> 8); + x82 = (uint8_t)(x81 & UINT8_C(0xff)); + x83 = (x81 >> 8); + x84 = (uint8_t)(x83 & UINT8_C(0xff)); + x85 = (x83 >> 8); + x86 = (uint8_t)(x85 & UINT8_C(0xff)); + x87 = (x85 >> 8); + x88 = (uint8_t)(x87 & UINT8_C(0xff)); + x89 = (x87 >> 8); + x90 = (uint8_t)(x89 & UINT8_C(0xff)); + x91 = (uint8_t)(x89 >> 8); + out1[0] = x26; + out1[1] = x28; + out1[2] = x30; + out1[3] = x32; + out1[4] = x34; + out1[5] = x36; + out1[6] = x39; + out1[7] = x41; + out1[8] = x43; + out1[9] = x45; + out1[10] = x47; + out1[11] = x49; + out1[12] = x52; + out1[13] = x54; + out1[14] = x56; + out1[15] = x58; + out1[16] = x60; + out1[17] = x62; + out1[18] = x64; + out1[19] = x67; + out1[20] = x69; + out1[21] = x71; + out1[22] = x73; + out1[23] = x75; + out1[24] = x77; + out1[25] = x80; + out1[26] = x82; + out1[27] = x84; + out1[28] = x86; + out1[29] = x88; + out1[30] = x90; + out1[31] = x91; +} + +/* + * The function fiat_25519_from_bytes deserializes a field element from bytes in little-endian order. + * + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_from_bytes(fiat_25519_tight_field_element out1, const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint8_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint8_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint8_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + x1 = ((uint64_t)(arg1[31]) << 44); + x2 = ((uint64_t)(arg1[30]) << 36); + x3 = ((uint64_t)(arg1[29]) << 28); + x4 = ((uint64_t)(arg1[28]) << 20); + x5 = ((uint64_t)(arg1[27]) << 12); + x6 = ((uint64_t)(arg1[26]) << 4); + x7 = ((uint64_t)(arg1[25]) << 47); + x8 = ((uint64_t)(arg1[24]) << 39); + x9 = ((uint64_t)(arg1[23]) << 31); + x10 = ((uint64_t)(arg1[22]) << 23); + x11 = ((uint64_t)(arg1[21]) << 15); + x12 = ((uint64_t)(arg1[20]) << 7); + x13 = ((uint64_t)(arg1[19]) << 50); + x14 = ((uint64_t)(arg1[18]) << 42); + x15 = ((uint64_t)(arg1[17]) << 34); + x16 = ((uint64_t)(arg1[16]) << 26); + x17 = ((uint64_t)(arg1[15]) << 18); + x18 = ((uint64_t)(arg1[14]) << 10); + x19 = ((uint64_t)(arg1[13]) << 2); + x20 = ((uint64_t)(arg1[12]) << 45); + x21 = ((uint64_t)(arg1[11]) << 37); + x22 = ((uint64_t)(arg1[10]) << 29); + x23 = ((uint64_t)(arg1[9]) << 21); + x24 = ((uint64_t)(arg1[8]) << 13); + x25 = ((uint64_t)(arg1[7]) << 5); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x38 & UINT64_C(0x7ffffffffffff)); + x40 = (uint8_t)(x38 >> 51); + x41 = (x25 + (uint64_t)x40); + x42 = (x24 + x41); + x43 = (x23 + x42); + x44 = (x22 + x43); + x45 = (x21 + x44); + x46 = (x20 + x45); + x47 = (x46 & UINT64_C(0x7ffffffffffff)); + x48 = (uint8_t)(x46 >> 51); + x49 = (x19 + (uint64_t)x48); + x50 = (x18 + x49); + x51 = (x17 + x50); + x52 = (x16 + x51); + x53 = (x15 + x52); + x54 = (x14 + x53); + x55 = (x13 + x54); + x56 = (x55 & UINT64_C(0x7ffffffffffff)); + x57 = (uint8_t)(x55 >> 51); + x58 = (x12 + (uint64_t)x57); + x59 = (x11 + x58); + x60 = (x10 + x59); + x61 = (x9 + x60); + x62 = (x8 + x61); + x63 = (x7 + x62); + x64 = (x63 & UINT64_C(0x7ffffffffffff)); + x65 = (uint8_t)(x63 >> 51); + x66 = (x6 + (uint64_t)x65); + x67 = (x5 + x66); + x68 = (x4 + x67); + x69 = (x3 + x68); + x70 = (x2 + x69); + x71 = (x1 + x70); + out1[0] = x39; + out1[1] = x47; + out1[2] = x56; + out1[3] = x64; + out1[4] = x71; +} + +/* + * The function fiat_25519_relax is the identity function converting from tight field elements to loose field elements. + * + * Postconditions: + * out1 = arg1 + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_relax(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (arg1[0]); + x2 = (arg1[1]); + x3 = (arg1[2]); + x4 = (arg1[3]); + x5 = (arg1[4]); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_carry_scmul_121666 multiplies a field element by 121666 and reduces the result. + * + * Postconditions: + * eval out1 mod m = (121666 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_scmul_121666(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + fiat_25519_uint128 x1; + fiat_25519_uint128 x2; + fiat_25519_uint128 x3; + fiat_25519_uint128 x4; + fiat_25519_uint128 x5; + uint64_t x6; + uint64_t x7; + fiat_25519_uint128 x8; + uint64_t x9; + uint64_t x10; + fiat_25519_uint128 x11; + uint64_t x12; + uint64_t x13; + fiat_25519_uint128 x14; + uint64_t x15; + uint64_t x16; + fiat_25519_uint128 x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + fiat_25519_uint1 x22; + uint64_t x23; + uint64_t x24; + fiat_25519_uint1 x25; + uint64_t x26; + uint64_t x27; + x1 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[4])); + x2 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[3])); + x3 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[2])); + x4 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[1])); + x5 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[0])); + x6 = (uint64_t)(x5 >> 51); + x7 = (uint64_t)(x5 & UINT64_C(0x7ffffffffffff)); + x8 = (x6 + x4); + x9 = (uint64_t)(x8 >> 51); + x10 = (uint64_t)(x8 & UINT64_C(0x7ffffffffffff)); + x11 = (x9 + x3); + x12 = (uint64_t)(x11 >> 51); + x13 = (uint64_t)(x11 & UINT64_C(0x7ffffffffffff)); + x14 = (x12 + x2); + x15 = (uint64_t)(x14 >> 51); + x16 = (uint64_t)(x14 & UINT64_C(0x7ffffffffffff)); + x17 = (x15 + x1); + x18 = (uint64_t)(x17 >> 51); + x19 = (uint64_t)(x17 & UINT64_C(0x7ffffffffffff)); + x20 = (x18 * UINT8_C(0x13)); + x21 = (x7 + x20); + x22 = (fiat_25519_uint1)(x21 >> 51); + x23 = (x21 & UINT64_C(0x7ffffffffffff)); + x24 = (x22 + x10); + x25 = (fiat_25519_uint1)(x24 >> 51); + x26 = (x24 & UINT64_C(0x7ffffffffffff)); + x27 = (x25 + x13); + out1[0] = x23; + out1[1] = x26; + out1[2] = x27; + out1[3] = x16; + out1[4] = x19; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_32.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_32.h new file mode 100644 index 00000000..3812d8ce --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_32.h @@ -0,0 +1,4760 @@ +/* Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --inline --static --use-value-barrier p256 32 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp */ +/* curve description: p256 */ +/* machine_wordsize = 32 (from "32") */ +/* requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp */ +/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ +/* */ +/* NOTE: In addition to the bounds specified above each function, all */ +/* functions synthesized for this Montgomery arithmetic require the */ +/* input to be strictly less than the prime modulus (m), and also */ +/* require the input to be in the unique saturated representation. */ +/* All functions also ensure that these two properties are true of */ +/* return values. */ +/* */ +/* Computed values: */ +/* eval z = z[0] + (z[1] << 32) + (z[2] << 64) + (z[3] << 96) + (z[4] << 128) + (z[5] << 160) + (z[6] << 192) + (z[7] << 224) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* twos_complement_eval z = let x1 := z[0] + (z[1] << 32) + (z[2] << 64) + (z[3] << 96) + (z[4] << 128) + (z[5] << 160) + (z[6] << 192) + (z[7] << 224) in */ +/* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ + +#include +typedef unsigned char fiat_p256_uint1; +typedef signed char fiat_p256_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_P256_FIAT_INLINE __inline__ +#else +# define FIAT_P256_FIAT_INLINE +#endif + +/* The type fiat_p256_montgomery_domain_field_element is a field element in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ +typedef uint32_t fiat_p256_montgomery_domain_field_element[8]; + +/* The type fiat_p256_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ +typedef uint32_t fiat_p256_non_montgomery_domain_field_element[8]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#if !defined(FIAT_P256_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint32_t fiat_p256_value_barrier_u32(uint32_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_p256_value_barrier_u32(x) (x) +#endif + + +/* + * The function fiat_p256_addcarryx_u32 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^32 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^32⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_addcarryx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint64_t x1; + uint32_t x2; + fiat_p256_uint1 x3; + x1 = ((arg1 + (uint64_t)arg2) + arg3); + x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + x3 = (fiat_p256_uint1)(x1 >> 32); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_p256_subborrowx_u32 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^32 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^32⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_subborrowx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int64_t x1; + fiat_p256_int1 x2; + uint32_t x3; + x1 = ((arg2 - (int64_t)arg1) - arg3); + x2 = (fiat_p256_int1)(x1 >> 32); + x3 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + *out1 = x3; + *out2 = (fiat_p256_uint1)(0x0 - x2); +} + +/* + * The function fiat_p256_mulx_u32 is a multiplication, returning the full double-width result. + * + * Postconditions: + * out1 = (arg1 * arg2) mod 2^32 + * out2 = ⌊arg1 * arg2 / 2^32⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffff] + * arg2: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0xffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mulx_u32(uint32_t* out1, uint32_t* out2, uint32_t arg1, uint32_t arg2) { + uint64_t x1; + uint32_t x2; + uint32_t x3; + x1 = ((uint64_t)arg1 * arg2); + x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + x3 = (uint32_t)(x1 >> 32); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_p256_cmovznz_u32 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u32(uint32_t* out1, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + fiat_p256_uint1 x1; + uint32_t x2; + uint32_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_p256_int1)(0x0 - x1) & UINT32_C(0xffffffff)); + x3 = ((fiat_p256_value_barrier_u32(x2) & arg3) | (fiat_p256_value_barrier_u32((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_p256_mul multiplies two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint32_t x24; + uint32_t x25; + fiat_p256_uint1 x26; + uint32_t x27; + fiat_p256_uint1 x28; + uint32_t x29; + fiat_p256_uint1 x30; + uint32_t x31; + fiat_p256_uint1 x32; + uint32_t x33; + fiat_p256_uint1 x34; + uint32_t x35; + fiat_p256_uint1 x36; + uint32_t x37; + fiat_p256_uint1 x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + fiat_p256_uint1 x49; + uint32_t x50; + fiat_p256_uint1 x51; + uint32_t x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + fiat_p256_uint1 x64; + uint32_t x65; + fiat_p256_uint1 x66; + uint32_t x67; + fiat_p256_uint1 x68; + uint32_t x69; + fiat_p256_uint1 x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint32_t x75; + uint32_t x76; + uint32_t x77; + uint32_t x78; + uint32_t x79; + uint32_t x80; + uint32_t x81; + uint32_t x82; + uint32_t x83; + uint32_t x84; + uint32_t x85; + uint32_t x86; + uint32_t x87; + fiat_p256_uint1 x88; + uint32_t x89; + fiat_p256_uint1 x90; + uint32_t x91; + fiat_p256_uint1 x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + uint32_t x102; + fiat_p256_uint1 x103; + uint32_t x104; + fiat_p256_uint1 x105; + uint32_t x106; + fiat_p256_uint1 x107; + uint32_t x108; + fiat_p256_uint1 x109; + uint32_t x110; + fiat_p256_uint1 x111; + uint32_t x112; + fiat_p256_uint1 x113; + uint32_t x114; + fiat_p256_uint1 x115; + uint32_t x116; + fiat_p256_uint1 x117; + uint32_t x118; + fiat_p256_uint1 x119; + uint32_t x120; + uint32_t x121; + uint32_t x122; + uint32_t x123; + uint32_t x124; + uint32_t x125; + uint32_t x126; + uint32_t x127; + uint32_t x128; + fiat_p256_uint1 x129; + uint32_t x130; + fiat_p256_uint1 x131; + uint32_t x132; + uint32_t x133; + fiat_p256_uint1 x134; + uint32_t x135; + fiat_p256_uint1 x136; + uint32_t x137; + fiat_p256_uint1 x138; + uint32_t x139; + fiat_p256_uint1 x140; + uint32_t x141; + fiat_p256_uint1 x142; + uint32_t x143; + fiat_p256_uint1 x144; + uint32_t x145; + fiat_p256_uint1 x146; + uint32_t x147; + fiat_p256_uint1 x148; + uint32_t x149; + fiat_p256_uint1 x150; + uint32_t x151; + uint32_t x152; + uint32_t x153; + uint32_t x154; + uint32_t x155; + uint32_t x156; + uint32_t x157; + uint32_t x158; + uint32_t x159; + uint32_t x160; + uint32_t x161; + uint32_t x162; + uint32_t x163; + uint32_t x164; + uint32_t x165; + uint32_t x166; + uint32_t x167; + uint32_t x168; + fiat_p256_uint1 x169; + uint32_t x170; + fiat_p256_uint1 x171; + uint32_t x172; + fiat_p256_uint1 x173; + uint32_t x174; + fiat_p256_uint1 x175; + uint32_t x176; + fiat_p256_uint1 x177; + uint32_t x178; + fiat_p256_uint1 x179; + uint32_t x180; + fiat_p256_uint1 x181; + uint32_t x182; + uint32_t x183; + fiat_p256_uint1 x184; + uint32_t x185; + fiat_p256_uint1 x186; + uint32_t x187; + fiat_p256_uint1 x188; + uint32_t x189; + fiat_p256_uint1 x190; + uint32_t x191; + fiat_p256_uint1 x192; + uint32_t x193; + fiat_p256_uint1 x194; + uint32_t x195; + fiat_p256_uint1 x196; + uint32_t x197; + fiat_p256_uint1 x198; + uint32_t x199; + fiat_p256_uint1 x200; + uint32_t x201; + uint32_t x202; + uint32_t x203; + uint32_t x204; + uint32_t x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + fiat_p256_uint1 x210; + uint32_t x211; + fiat_p256_uint1 x212; + uint32_t x213; + uint32_t x214; + fiat_p256_uint1 x215; + uint32_t x216; + fiat_p256_uint1 x217; + uint32_t x218; + fiat_p256_uint1 x219; + uint32_t x220; + fiat_p256_uint1 x221; + uint32_t x222; + fiat_p256_uint1 x223; + uint32_t x224; + fiat_p256_uint1 x225; + uint32_t x226; + fiat_p256_uint1 x227; + uint32_t x228; + fiat_p256_uint1 x229; + uint32_t x230; + fiat_p256_uint1 x231; + uint32_t x232; + uint32_t x233; + uint32_t x234; + uint32_t x235; + uint32_t x236; + uint32_t x237; + uint32_t x238; + uint32_t x239; + uint32_t x240; + uint32_t x241; + uint32_t x242; + uint32_t x243; + uint32_t x244; + uint32_t x245; + uint32_t x246; + uint32_t x247; + uint32_t x248; + uint32_t x249; + fiat_p256_uint1 x250; + uint32_t x251; + fiat_p256_uint1 x252; + uint32_t x253; + fiat_p256_uint1 x254; + uint32_t x255; + fiat_p256_uint1 x256; + uint32_t x257; + fiat_p256_uint1 x258; + uint32_t x259; + fiat_p256_uint1 x260; + uint32_t x261; + fiat_p256_uint1 x262; + uint32_t x263; + uint32_t x264; + fiat_p256_uint1 x265; + uint32_t x266; + fiat_p256_uint1 x267; + uint32_t x268; + fiat_p256_uint1 x269; + uint32_t x270; + fiat_p256_uint1 x271; + uint32_t x272; + fiat_p256_uint1 x273; + uint32_t x274; + fiat_p256_uint1 x275; + uint32_t x276; + fiat_p256_uint1 x277; + uint32_t x278; + fiat_p256_uint1 x279; + uint32_t x280; + fiat_p256_uint1 x281; + uint32_t x282; + uint32_t x283; + uint32_t x284; + uint32_t x285; + uint32_t x286; + uint32_t x287; + uint32_t x288; + uint32_t x289; + uint32_t x290; + fiat_p256_uint1 x291; + uint32_t x292; + fiat_p256_uint1 x293; + uint32_t x294; + uint32_t x295; + fiat_p256_uint1 x296; + uint32_t x297; + fiat_p256_uint1 x298; + uint32_t x299; + fiat_p256_uint1 x300; + uint32_t x301; + fiat_p256_uint1 x302; + uint32_t x303; + fiat_p256_uint1 x304; + uint32_t x305; + fiat_p256_uint1 x306; + uint32_t x307; + fiat_p256_uint1 x308; + uint32_t x309; + fiat_p256_uint1 x310; + uint32_t x311; + fiat_p256_uint1 x312; + uint32_t x313; + uint32_t x314; + uint32_t x315; + uint32_t x316; + uint32_t x317; + uint32_t x318; + uint32_t x319; + uint32_t x320; + uint32_t x321; + uint32_t x322; + uint32_t x323; + uint32_t x324; + uint32_t x325; + uint32_t x326; + uint32_t x327; + uint32_t x328; + uint32_t x329; + uint32_t x330; + fiat_p256_uint1 x331; + uint32_t x332; + fiat_p256_uint1 x333; + uint32_t x334; + fiat_p256_uint1 x335; + uint32_t x336; + fiat_p256_uint1 x337; + uint32_t x338; + fiat_p256_uint1 x339; + uint32_t x340; + fiat_p256_uint1 x341; + uint32_t x342; + fiat_p256_uint1 x343; + uint32_t x344; + uint32_t x345; + fiat_p256_uint1 x346; + uint32_t x347; + fiat_p256_uint1 x348; + uint32_t x349; + fiat_p256_uint1 x350; + uint32_t x351; + fiat_p256_uint1 x352; + uint32_t x353; + fiat_p256_uint1 x354; + uint32_t x355; + fiat_p256_uint1 x356; + uint32_t x357; + fiat_p256_uint1 x358; + uint32_t x359; + fiat_p256_uint1 x360; + uint32_t x361; + fiat_p256_uint1 x362; + uint32_t x363; + uint32_t x364; + uint32_t x365; + uint32_t x366; + uint32_t x367; + uint32_t x368; + uint32_t x369; + uint32_t x370; + uint32_t x371; + fiat_p256_uint1 x372; + uint32_t x373; + fiat_p256_uint1 x374; + uint32_t x375; + uint32_t x376; + fiat_p256_uint1 x377; + uint32_t x378; + fiat_p256_uint1 x379; + uint32_t x380; + fiat_p256_uint1 x381; + uint32_t x382; + fiat_p256_uint1 x383; + uint32_t x384; + fiat_p256_uint1 x385; + uint32_t x386; + fiat_p256_uint1 x387; + uint32_t x388; + fiat_p256_uint1 x389; + uint32_t x390; + fiat_p256_uint1 x391; + uint32_t x392; + fiat_p256_uint1 x393; + uint32_t x394; + uint32_t x395; + uint32_t x396; + uint32_t x397; + uint32_t x398; + uint32_t x399; + uint32_t x400; + uint32_t x401; + uint32_t x402; + uint32_t x403; + uint32_t x404; + uint32_t x405; + uint32_t x406; + uint32_t x407; + uint32_t x408; + uint32_t x409; + uint32_t x410; + uint32_t x411; + fiat_p256_uint1 x412; + uint32_t x413; + fiat_p256_uint1 x414; + uint32_t x415; + fiat_p256_uint1 x416; + uint32_t x417; + fiat_p256_uint1 x418; + uint32_t x419; + fiat_p256_uint1 x420; + uint32_t x421; + fiat_p256_uint1 x422; + uint32_t x423; + fiat_p256_uint1 x424; + uint32_t x425; + uint32_t x426; + fiat_p256_uint1 x427; + uint32_t x428; + fiat_p256_uint1 x429; + uint32_t x430; + fiat_p256_uint1 x431; + uint32_t x432; + fiat_p256_uint1 x433; + uint32_t x434; + fiat_p256_uint1 x435; + uint32_t x436; + fiat_p256_uint1 x437; + uint32_t x438; + fiat_p256_uint1 x439; + uint32_t x440; + fiat_p256_uint1 x441; + uint32_t x442; + fiat_p256_uint1 x443; + uint32_t x444; + uint32_t x445; + uint32_t x446; + uint32_t x447; + uint32_t x448; + uint32_t x449; + uint32_t x450; + uint32_t x451; + uint32_t x452; + fiat_p256_uint1 x453; + uint32_t x454; + fiat_p256_uint1 x455; + uint32_t x456; + uint32_t x457; + fiat_p256_uint1 x458; + uint32_t x459; + fiat_p256_uint1 x460; + uint32_t x461; + fiat_p256_uint1 x462; + uint32_t x463; + fiat_p256_uint1 x464; + uint32_t x465; + fiat_p256_uint1 x466; + uint32_t x467; + fiat_p256_uint1 x468; + uint32_t x469; + fiat_p256_uint1 x470; + uint32_t x471; + fiat_p256_uint1 x472; + uint32_t x473; + fiat_p256_uint1 x474; + uint32_t x475; + uint32_t x476; + uint32_t x477; + uint32_t x478; + uint32_t x479; + uint32_t x480; + uint32_t x481; + uint32_t x482; + uint32_t x483; + uint32_t x484; + uint32_t x485; + uint32_t x486; + uint32_t x487; + uint32_t x488; + uint32_t x489; + uint32_t x490; + uint32_t x491; + uint32_t x492; + fiat_p256_uint1 x493; + uint32_t x494; + fiat_p256_uint1 x495; + uint32_t x496; + fiat_p256_uint1 x497; + uint32_t x498; + fiat_p256_uint1 x499; + uint32_t x500; + fiat_p256_uint1 x501; + uint32_t x502; + fiat_p256_uint1 x503; + uint32_t x504; + fiat_p256_uint1 x505; + uint32_t x506; + uint32_t x507; + fiat_p256_uint1 x508; + uint32_t x509; + fiat_p256_uint1 x510; + uint32_t x511; + fiat_p256_uint1 x512; + uint32_t x513; + fiat_p256_uint1 x514; + uint32_t x515; + fiat_p256_uint1 x516; + uint32_t x517; + fiat_p256_uint1 x518; + uint32_t x519; + fiat_p256_uint1 x520; + uint32_t x521; + fiat_p256_uint1 x522; + uint32_t x523; + fiat_p256_uint1 x524; + uint32_t x525; + uint32_t x526; + uint32_t x527; + uint32_t x528; + uint32_t x529; + uint32_t x530; + uint32_t x531; + uint32_t x532; + uint32_t x533; + fiat_p256_uint1 x534; + uint32_t x535; + fiat_p256_uint1 x536; + uint32_t x537; + uint32_t x538; + fiat_p256_uint1 x539; + uint32_t x540; + fiat_p256_uint1 x541; + uint32_t x542; + fiat_p256_uint1 x543; + uint32_t x544; + fiat_p256_uint1 x545; + uint32_t x546; + fiat_p256_uint1 x547; + uint32_t x548; + fiat_p256_uint1 x549; + uint32_t x550; + fiat_p256_uint1 x551; + uint32_t x552; + fiat_p256_uint1 x553; + uint32_t x554; + fiat_p256_uint1 x555; + uint32_t x556; + uint32_t x557; + uint32_t x558; + uint32_t x559; + uint32_t x560; + uint32_t x561; + uint32_t x562; + uint32_t x563; + uint32_t x564; + uint32_t x565; + uint32_t x566; + uint32_t x567; + uint32_t x568; + uint32_t x569; + uint32_t x570; + uint32_t x571; + uint32_t x572; + uint32_t x573; + fiat_p256_uint1 x574; + uint32_t x575; + fiat_p256_uint1 x576; + uint32_t x577; + fiat_p256_uint1 x578; + uint32_t x579; + fiat_p256_uint1 x580; + uint32_t x581; + fiat_p256_uint1 x582; + uint32_t x583; + fiat_p256_uint1 x584; + uint32_t x585; + fiat_p256_uint1 x586; + uint32_t x587; + uint32_t x588; + fiat_p256_uint1 x589; + uint32_t x590; + fiat_p256_uint1 x591; + uint32_t x592; + fiat_p256_uint1 x593; + uint32_t x594; + fiat_p256_uint1 x595; + uint32_t x596; + fiat_p256_uint1 x597; + uint32_t x598; + fiat_p256_uint1 x599; + uint32_t x600; + fiat_p256_uint1 x601; + uint32_t x602; + fiat_p256_uint1 x603; + uint32_t x604; + fiat_p256_uint1 x605; + uint32_t x606; + uint32_t x607; + uint32_t x608; + uint32_t x609; + uint32_t x610; + uint32_t x611; + uint32_t x612; + uint32_t x613; + uint32_t x614; + fiat_p256_uint1 x615; + uint32_t x616; + fiat_p256_uint1 x617; + uint32_t x618; + uint32_t x619; + fiat_p256_uint1 x620; + uint32_t x621; + fiat_p256_uint1 x622; + uint32_t x623; + fiat_p256_uint1 x624; + uint32_t x625; + fiat_p256_uint1 x626; + uint32_t x627; + fiat_p256_uint1 x628; + uint32_t x629; + fiat_p256_uint1 x630; + uint32_t x631; + fiat_p256_uint1 x632; + uint32_t x633; + fiat_p256_uint1 x634; + uint32_t x635; + fiat_p256_uint1 x636; + uint32_t x637; + uint32_t x638; + fiat_p256_uint1 x639; + uint32_t x640; + fiat_p256_uint1 x641; + uint32_t x642; + fiat_p256_uint1 x643; + uint32_t x644; + fiat_p256_uint1 x645; + uint32_t x646; + fiat_p256_uint1 x647; + uint32_t x648; + fiat_p256_uint1 x649; + uint32_t x650; + fiat_p256_uint1 x651; + uint32_t x652; + fiat_p256_uint1 x653; + uint32_t x654; + fiat_p256_uint1 x655; + uint32_t x656; + uint32_t x657; + uint32_t x658; + uint32_t x659; + uint32_t x660; + uint32_t x661; + uint32_t x662; + uint32_t x663; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, (arg2[7])); + fiat_p256_mulx_u32(&x11, &x12, x8, (arg2[6])); + fiat_p256_mulx_u32(&x13, &x14, x8, (arg2[5])); + fiat_p256_mulx_u32(&x15, &x16, x8, (arg2[4])); + fiat_p256_mulx_u32(&x17, &x18, x8, (arg2[3])); + fiat_p256_mulx_u32(&x19, &x20, x8, (arg2[2])); + fiat_p256_mulx_u32(&x21, &x22, x8, (arg2[1])); + fiat_p256_mulx_u32(&x23, &x24, x8, (arg2[0])); + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); + fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); + fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); + fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); + x39 = (x38 + x10); + fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); + x52 = (x51 + x43); + fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); + fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); + fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); + fiat_p256_mulx_u32(&x71, &x72, x1, (arg2[7])); + fiat_p256_mulx_u32(&x73, &x74, x1, (arg2[6])); + fiat_p256_mulx_u32(&x75, &x76, x1, (arg2[5])); + fiat_p256_mulx_u32(&x77, &x78, x1, (arg2[4])); + fiat_p256_mulx_u32(&x79, &x80, x1, (arg2[3])); + fiat_p256_mulx_u32(&x81, &x82, x1, (arg2[2])); + fiat_p256_mulx_u32(&x83, &x84, x1, (arg2[1])); + fiat_p256_mulx_u32(&x85, &x86, x1, (arg2[0])); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); + x101 = (x100 + x72); + fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); + fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); + fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); + fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); + fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); + fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); + x132 = (x131 + x123); + fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); + fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); + fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); + fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); + fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); + fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); + fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); + fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); + x151 = ((uint32_t)x150 + x119); + fiat_p256_mulx_u32(&x152, &x153, x2, (arg2[7])); + fiat_p256_mulx_u32(&x154, &x155, x2, (arg2[6])); + fiat_p256_mulx_u32(&x156, &x157, x2, (arg2[5])); + fiat_p256_mulx_u32(&x158, &x159, x2, (arg2[4])); + fiat_p256_mulx_u32(&x160, &x161, x2, (arg2[3])); + fiat_p256_mulx_u32(&x162, &x163, x2, (arg2[2])); + fiat_p256_mulx_u32(&x164, &x165, x2, (arg2[1])); + fiat_p256_mulx_u32(&x166, &x167, x2, (arg2[0])); + fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); + x182 = (x181 + x153); + fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); + fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); + fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); + fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); + x213 = (x212 + x204); + fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); + fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); + fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); + x232 = ((uint32_t)x231 + x200); + fiat_p256_mulx_u32(&x233, &x234, x3, (arg2[7])); + fiat_p256_mulx_u32(&x235, &x236, x3, (arg2[6])); + fiat_p256_mulx_u32(&x237, &x238, x3, (arg2[5])); + fiat_p256_mulx_u32(&x239, &x240, x3, (arg2[4])); + fiat_p256_mulx_u32(&x241, &x242, x3, (arg2[3])); + fiat_p256_mulx_u32(&x243, &x244, x3, (arg2[2])); + fiat_p256_mulx_u32(&x245, &x246, x3, (arg2[1])); + fiat_p256_mulx_u32(&x247, &x248, x3, (arg2[0])); + fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); + fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); + fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); + x263 = (x262 + x234); + fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); + fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); + fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); + fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); + fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); + x294 = (x293 + x285); + fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); + fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); + x313 = ((uint32_t)x312 + x281); + fiat_p256_mulx_u32(&x314, &x315, x4, (arg2[7])); + fiat_p256_mulx_u32(&x316, &x317, x4, (arg2[6])); + fiat_p256_mulx_u32(&x318, &x319, x4, (arg2[5])); + fiat_p256_mulx_u32(&x320, &x321, x4, (arg2[4])); + fiat_p256_mulx_u32(&x322, &x323, x4, (arg2[3])); + fiat_p256_mulx_u32(&x324, &x325, x4, (arg2[2])); + fiat_p256_mulx_u32(&x326, &x327, x4, (arg2[1])); + fiat_p256_mulx_u32(&x328, &x329, x4, (arg2[0])); + fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); + fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); + fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); + fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); + fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); + fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); + fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); + x344 = (x343 + x315); + fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); + fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); + fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); + fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); + fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); + fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); + fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); + fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); + x375 = (x374 + x366); + fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); + fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); + fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); + fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); + fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); + fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); + fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); + fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); + fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); + x394 = ((uint32_t)x393 + x362); + fiat_p256_mulx_u32(&x395, &x396, x5, (arg2[7])); + fiat_p256_mulx_u32(&x397, &x398, x5, (arg2[6])); + fiat_p256_mulx_u32(&x399, &x400, x5, (arg2[5])); + fiat_p256_mulx_u32(&x401, &x402, x5, (arg2[4])); + fiat_p256_mulx_u32(&x403, &x404, x5, (arg2[3])); + fiat_p256_mulx_u32(&x405, &x406, x5, (arg2[2])); + fiat_p256_mulx_u32(&x407, &x408, x5, (arg2[1])); + fiat_p256_mulx_u32(&x409, &x410, x5, (arg2[0])); + fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); + fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); + fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); + fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); + fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); + fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); + fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); + x425 = (x424 + x396); + fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); + fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); + fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); + fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); + fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); + fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); + fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); + fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); + fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); + fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); + fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); + x456 = (x455 + x447); + fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); + fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); + fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); + fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); + x475 = ((uint32_t)x474 + x443); + fiat_p256_mulx_u32(&x476, &x477, x6, (arg2[7])); + fiat_p256_mulx_u32(&x478, &x479, x6, (arg2[6])); + fiat_p256_mulx_u32(&x480, &x481, x6, (arg2[5])); + fiat_p256_mulx_u32(&x482, &x483, x6, (arg2[4])); + fiat_p256_mulx_u32(&x484, &x485, x6, (arg2[3])); + fiat_p256_mulx_u32(&x486, &x487, x6, (arg2[2])); + fiat_p256_mulx_u32(&x488, &x489, x6, (arg2[1])); + fiat_p256_mulx_u32(&x490, &x491, x6, (arg2[0])); + fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); + fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); + fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); + fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); + fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); + fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); + fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); + x506 = (x505 + x477); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); + fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); + fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); + x537 = (x536 + x528); + fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); + fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); + fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); + fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); + fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); + fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); + fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); + fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); + fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); + x556 = ((uint32_t)x555 + x524); + fiat_p256_mulx_u32(&x557, &x558, x7, (arg2[7])); + fiat_p256_mulx_u32(&x559, &x560, x7, (arg2[6])); + fiat_p256_mulx_u32(&x561, &x562, x7, (arg2[5])); + fiat_p256_mulx_u32(&x563, &x564, x7, (arg2[4])); + fiat_p256_mulx_u32(&x565, &x566, x7, (arg2[3])); + fiat_p256_mulx_u32(&x567, &x568, x7, (arg2[2])); + fiat_p256_mulx_u32(&x569, &x570, x7, (arg2[1])); + fiat_p256_mulx_u32(&x571, &x572, x7, (arg2[0])); + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); + fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); + fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); + fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); + fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); + fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); + fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); + x587 = (x586 + x558); + fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); + fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); + fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); + fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); + fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); + fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); + fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); + fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); + fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); + fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); + fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); + x618 = (x617 + x609); + fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); + fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); + fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); + fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); + fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); + fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); + fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); + fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); + fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); + x637 = ((uint32_t)x636 + x605); + fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); + fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); + fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); + fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); + fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); + fiat_p256_cmovznz_u32(&x656, x655, x638, x621); + fiat_p256_cmovznz_u32(&x657, x655, x640, x623); + fiat_p256_cmovznz_u32(&x658, x655, x642, x625); + fiat_p256_cmovznz_u32(&x659, x655, x644, x627); + fiat_p256_cmovznz_u32(&x660, x655, x646, x629); + fiat_p256_cmovznz_u32(&x661, x655, x648, x631); + fiat_p256_cmovznz_u32(&x662, x655, x650, x633); + fiat_p256_cmovznz_u32(&x663, x655, x652, x635); + out1[0] = x656; + out1[1] = x657; + out1[2] = x658; + out1[3] = x659; + out1[4] = x660; + out1[5] = x661; + out1[6] = x662; + out1[7] = x663; +} + +/* + * The function fiat_p256_square squares a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint32_t x24; + uint32_t x25; + fiat_p256_uint1 x26; + uint32_t x27; + fiat_p256_uint1 x28; + uint32_t x29; + fiat_p256_uint1 x30; + uint32_t x31; + fiat_p256_uint1 x32; + uint32_t x33; + fiat_p256_uint1 x34; + uint32_t x35; + fiat_p256_uint1 x36; + uint32_t x37; + fiat_p256_uint1 x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + fiat_p256_uint1 x49; + uint32_t x50; + fiat_p256_uint1 x51; + uint32_t x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + fiat_p256_uint1 x64; + uint32_t x65; + fiat_p256_uint1 x66; + uint32_t x67; + fiat_p256_uint1 x68; + uint32_t x69; + fiat_p256_uint1 x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint32_t x75; + uint32_t x76; + uint32_t x77; + uint32_t x78; + uint32_t x79; + uint32_t x80; + uint32_t x81; + uint32_t x82; + uint32_t x83; + uint32_t x84; + uint32_t x85; + uint32_t x86; + uint32_t x87; + fiat_p256_uint1 x88; + uint32_t x89; + fiat_p256_uint1 x90; + uint32_t x91; + fiat_p256_uint1 x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + uint32_t x102; + fiat_p256_uint1 x103; + uint32_t x104; + fiat_p256_uint1 x105; + uint32_t x106; + fiat_p256_uint1 x107; + uint32_t x108; + fiat_p256_uint1 x109; + uint32_t x110; + fiat_p256_uint1 x111; + uint32_t x112; + fiat_p256_uint1 x113; + uint32_t x114; + fiat_p256_uint1 x115; + uint32_t x116; + fiat_p256_uint1 x117; + uint32_t x118; + fiat_p256_uint1 x119; + uint32_t x120; + uint32_t x121; + uint32_t x122; + uint32_t x123; + uint32_t x124; + uint32_t x125; + uint32_t x126; + uint32_t x127; + uint32_t x128; + fiat_p256_uint1 x129; + uint32_t x130; + fiat_p256_uint1 x131; + uint32_t x132; + uint32_t x133; + fiat_p256_uint1 x134; + uint32_t x135; + fiat_p256_uint1 x136; + uint32_t x137; + fiat_p256_uint1 x138; + uint32_t x139; + fiat_p256_uint1 x140; + uint32_t x141; + fiat_p256_uint1 x142; + uint32_t x143; + fiat_p256_uint1 x144; + uint32_t x145; + fiat_p256_uint1 x146; + uint32_t x147; + fiat_p256_uint1 x148; + uint32_t x149; + fiat_p256_uint1 x150; + uint32_t x151; + uint32_t x152; + uint32_t x153; + uint32_t x154; + uint32_t x155; + uint32_t x156; + uint32_t x157; + uint32_t x158; + uint32_t x159; + uint32_t x160; + uint32_t x161; + uint32_t x162; + uint32_t x163; + uint32_t x164; + uint32_t x165; + uint32_t x166; + uint32_t x167; + uint32_t x168; + fiat_p256_uint1 x169; + uint32_t x170; + fiat_p256_uint1 x171; + uint32_t x172; + fiat_p256_uint1 x173; + uint32_t x174; + fiat_p256_uint1 x175; + uint32_t x176; + fiat_p256_uint1 x177; + uint32_t x178; + fiat_p256_uint1 x179; + uint32_t x180; + fiat_p256_uint1 x181; + uint32_t x182; + uint32_t x183; + fiat_p256_uint1 x184; + uint32_t x185; + fiat_p256_uint1 x186; + uint32_t x187; + fiat_p256_uint1 x188; + uint32_t x189; + fiat_p256_uint1 x190; + uint32_t x191; + fiat_p256_uint1 x192; + uint32_t x193; + fiat_p256_uint1 x194; + uint32_t x195; + fiat_p256_uint1 x196; + uint32_t x197; + fiat_p256_uint1 x198; + uint32_t x199; + fiat_p256_uint1 x200; + uint32_t x201; + uint32_t x202; + uint32_t x203; + uint32_t x204; + uint32_t x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + fiat_p256_uint1 x210; + uint32_t x211; + fiat_p256_uint1 x212; + uint32_t x213; + uint32_t x214; + fiat_p256_uint1 x215; + uint32_t x216; + fiat_p256_uint1 x217; + uint32_t x218; + fiat_p256_uint1 x219; + uint32_t x220; + fiat_p256_uint1 x221; + uint32_t x222; + fiat_p256_uint1 x223; + uint32_t x224; + fiat_p256_uint1 x225; + uint32_t x226; + fiat_p256_uint1 x227; + uint32_t x228; + fiat_p256_uint1 x229; + uint32_t x230; + fiat_p256_uint1 x231; + uint32_t x232; + uint32_t x233; + uint32_t x234; + uint32_t x235; + uint32_t x236; + uint32_t x237; + uint32_t x238; + uint32_t x239; + uint32_t x240; + uint32_t x241; + uint32_t x242; + uint32_t x243; + uint32_t x244; + uint32_t x245; + uint32_t x246; + uint32_t x247; + uint32_t x248; + uint32_t x249; + fiat_p256_uint1 x250; + uint32_t x251; + fiat_p256_uint1 x252; + uint32_t x253; + fiat_p256_uint1 x254; + uint32_t x255; + fiat_p256_uint1 x256; + uint32_t x257; + fiat_p256_uint1 x258; + uint32_t x259; + fiat_p256_uint1 x260; + uint32_t x261; + fiat_p256_uint1 x262; + uint32_t x263; + uint32_t x264; + fiat_p256_uint1 x265; + uint32_t x266; + fiat_p256_uint1 x267; + uint32_t x268; + fiat_p256_uint1 x269; + uint32_t x270; + fiat_p256_uint1 x271; + uint32_t x272; + fiat_p256_uint1 x273; + uint32_t x274; + fiat_p256_uint1 x275; + uint32_t x276; + fiat_p256_uint1 x277; + uint32_t x278; + fiat_p256_uint1 x279; + uint32_t x280; + fiat_p256_uint1 x281; + uint32_t x282; + uint32_t x283; + uint32_t x284; + uint32_t x285; + uint32_t x286; + uint32_t x287; + uint32_t x288; + uint32_t x289; + uint32_t x290; + fiat_p256_uint1 x291; + uint32_t x292; + fiat_p256_uint1 x293; + uint32_t x294; + uint32_t x295; + fiat_p256_uint1 x296; + uint32_t x297; + fiat_p256_uint1 x298; + uint32_t x299; + fiat_p256_uint1 x300; + uint32_t x301; + fiat_p256_uint1 x302; + uint32_t x303; + fiat_p256_uint1 x304; + uint32_t x305; + fiat_p256_uint1 x306; + uint32_t x307; + fiat_p256_uint1 x308; + uint32_t x309; + fiat_p256_uint1 x310; + uint32_t x311; + fiat_p256_uint1 x312; + uint32_t x313; + uint32_t x314; + uint32_t x315; + uint32_t x316; + uint32_t x317; + uint32_t x318; + uint32_t x319; + uint32_t x320; + uint32_t x321; + uint32_t x322; + uint32_t x323; + uint32_t x324; + uint32_t x325; + uint32_t x326; + uint32_t x327; + uint32_t x328; + uint32_t x329; + uint32_t x330; + fiat_p256_uint1 x331; + uint32_t x332; + fiat_p256_uint1 x333; + uint32_t x334; + fiat_p256_uint1 x335; + uint32_t x336; + fiat_p256_uint1 x337; + uint32_t x338; + fiat_p256_uint1 x339; + uint32_t x340; + fiat_p256_uint1 x341; + uint32_t x342; + fiat_p256_uint1 x343; + uint32_t x344; + uint32_t x345; + fiat_p256_uint1 x346; + uint32_t x347; + fiat_p256_uint1 x348; + uint32_t x349; + fiat_p256_uint1 x350; + uint32_t x351; + fiat_p256_uint1 x352; + uint32_t x353; + fiat_p256_uint1 x354; + uint32_t x355; + fiat_p256_uint1 x356; + uint32_t x357; + fiat_p256_uint1 x358; + uint32_t x359; + fiat_p256_uint1 x360; + uint32_t x361; + fiat_p256_uint1 x362; + uint32_t x363; + uint32_t x364; + uint32_t x365; + uint32_t x366; + uint32_t x367; + uint32_t x368; + uint32_t x369; + uint32_t x370; + uint32_t x371; + fiat_p256_uint1 x372; + uint32_t x373; + fiat_p256_uint1 x374; + uint32_t x375; + uint32_t x376; + fiat_p256_uint1 x377; + uint32_t x378; + fiat_p256_uint1 x379; + uint32_t x380; + fiat_p256_uint1 x381; + uint32_t x382; + fiat_p256_uint1 x383; + uint32_t x384; + fiat_p256_uint1 x385; + uint32_t x386; + fiat_p256_uint1 x387; + uint32_t x388; + fiat_p256_uint1 x389; + uint32_t x390; + fiat_p256_uint1 x391; + uint32_t x392; + fiat_p256_uint1 x393; + uint32_t x394; + uint32_t x395; + uint32_t x396; + uint32_t x397; + uint32_t x398; + uint32_t x399; + uint32_t x400; + uint32_t x401; + uint32_t x402; + uint32_t x403; + uint32_t x404; + uint32_t x405; + uint32_t x406; + uint32_t x407; + uint32_t x408; + uint32_t x409; + uint32_t x410; + uint32_t x411; + fiat_p256_uint1 x412; + uint32_t x413; + fiat_p256_uint1 x414; + uint32_t x415; + fiat_p256_uint1 x416; + uint32_t x417; + fiat_p256_uint1 x418; + uint32_t x419; + fiat_p256_uint1 x420; + uint32_t x421; + fiat_p256_uint1 x422; + uint32_t x423; + fiat_p256_uint1 x424; + uint32_t x425; + uint32_t x426; + fiat_p256_uint1 x427; + uint32_t x428; + fiat_p256_uint1 x429; + uint32_t x430; + fiat_p256_uint1 x431; + uint32_t x432; + fiat_p256_uint1 x433; + uint32_t x434; + fiat_p256_uint1 x435; + uint32_t x436; + fiat_p256_uint1 x437; + uint32_t x438; + fiat_p256_uint1 x439; + uint32_t x440; + fiat_p256_uint1 x441; + uint32_t x442; + fiat_p256_uint1 x443; + uint32_t x444; + uint32_t x445; + uint32_t x446; + uint32_t x447; + uint32_t x448; + uint32_t x449; + uint32_t x450; + uint32_t x451; + uint32_t x452; + fiat_p256_uint1 x453; + uint32_t x454; + fiat_p256_uint1 x455; + uint32_t x456; + uint32_t x457; + fiat_p256_uint1 x458; + uint32_t x459; + fiat_p256_uint1 x460; + uint32_t x461; + fiat_p256_uint1 x462; + uint32_t x463; + fiat_p256_uint1 x464; + uint32_t x465; + fiat_p256_uint1 x466; + uint32_t x467; + fiat_p256_uint1 x468; + uint32_t x469; + fiat_p256_uint1 x470; + uint32_t x471; + fiat_p256_uint1 x472; + uint32_t x473; + fiat_p256_uint1 x474; + uint32_t x475; + uint32_t x476; + uint32_t x477; + uint32_t x478; + uint32_t x479; + uint32_t x480; + uint32_t x481; + uint32_t x482; + uint32_t x483; + uint32_t x484; + uint32_t x485; + uint32_t x486; + uint32_t x487; + uint32_t x488; + uint32_t x489; + uint32_t x490; + uint32_t x491; + uint32_t x492; + fiat_p256_uint1 x493; + uint32_t x494; + fiat_p256_uint1 x495; + uint32_t x496; + fiat_p256_uint1 x497; + uint32_t x498; + fiat_p256_uint1 x499; + uint32_t x500; + fiat_p256_uint1 x501; + uint32_t x502; + fiat_p256_uint1 x503; + uint32_t x504; + fiat_p256_uint1 x505; + uint32_t x506; + uint32_t x507; + fiat_p256_uint1 x508; + uint32_t x509; + fiat_p256_uint1 x510; + uint32_t x511; + fiat_p256_uint1 x512; + uint32_t x513; + fiat_p256_uint1 x514; + uint32_t x515; + fiat_p256_uint1 x516; + uint32_t x517; + fiat_p256_uint1 x518; + uint32_t x519; + fiat_p256_uint1 x520; + uint32_t x521; + fiat_p256_uint1 x522; + uint32_t x523; + fiat_p256_uint1 x524; + uint32_t x525; + uint32_t x526; + uint32_t x527; + uint32_t x528; + uint32_t x529; + uint32_t x530; + uint32_t x531; + uint32_t x532; + uint32_t x533; + fiat_p256_uint1 x534; + uint32_t x535; + fiat_p256_uint1 x536; + uint32_t x537; + uint32_t x538; + fiat_p256_uint1 x539; + uint32_t x540; + fiat_p256_uint1 x541; + uint32_t x542; + fiat_p256_uint1 x543; + uint32_t x544; + fiat_p256_uint1 x545; + uint32_t x546; + fiat_p256_uint1 x547; + uint32_t x548; + fiat_p256_uint1 x549; + uint32_t x550; + fiat_p256_uint1 x551; + uint32_t x552; + fiat_p256_uint1 x553; + uint32_t x554; + fiat_p256_uint1 x555; + uint32_t x556; + uint32_t x557; + uint32_t x558; + uint32_t x559; + uint32_t x560; + uint32_t x561; + uint32_t x562; + uint32_t x563; + uint32_t x564; + uint32_t x565; + uint32_t x566; + uint32_t x567; + uint32_t x568; + uint32_t x569; + uint32_t x570; + uint32_t x571; + uint32_t x572; + uint32_t x573; + fiat_p256_uint1 x574; + uint32_t x575; + fiat_p256_uint1 x576; + uint32_t x577; + fiat_p256_uint1 x578; + uint32_t x579; + fiat_p256_uint1 x580; + uint32_t x581; + fiat_p256_uint1 x582; + uint32_t x583; + fiat_p256_uint1 x584; + uint32_t x585; + fiat_p256_uint1 x586; + uint32_t x587; + uint32_t x588; + fiat_p256_uint1 x589; + uint32_t x590; + fiat_p256_uint1 x591; + uint32_t x592; + fiat_p256_uint1 x593; + uint32_t x594; + fiat_p256_uint1 x595; + uint32_t x596; + fiat_p256_uint1 x597; + uint32_t x598; + fiat_p256_uint1 x599; + uint32_t x600; + fiat_p256_uint1 x601; + uint32_t x602; + fiat_p256_uint1 x603; + uint32_t x604; + fiat_p256_uint1 x605; + uint32_t x606; + uint32_t x607; + uint32_t x608; + uint32_t x609; + uint32_t x610; + uint32_t x611; + uint32_t x612; + uint32_t x613; + uint32_t x614; + fiat_p256_uint1 x615; + uint32_t x616; + fiat_p256_uint1 x617; + uint32_t x618; + uint32_t x619; + fiat_p256_uint1 x620; + uint32_t x621; + fiat_p256_uint1 x622; + uint32_t x623; + fiat_p256_uint1 x624; + uint32_t x625; + fiat_p256_uint1 x626; + uint32_t x627; + fiat_p256_uint1 x628; + uint32_t x629; + fiat_p256_uint1 x630; + uint32_t x631; + fiat_p256_uint1 x632; + uint32_t x633; + fiat_p256_uint1 x634; + uint32_t x635; + fiat_p256_uint1 x636; + uint32_t x637; + uint32_t x638; + fiat_p256_uint1 x639; + uint32_t x640; + fiat_p256_uint1 x641; + uint32_t x642; + fiat_p256_uint1 x643; + uint32_t x644; + fiat_p256_uint1 x645; + uint32_t x646; + fiat_p256_uint1 x647; + uint32_t x648; + fiat_p256_uint1 x649; + uint32_t x650; + fiat_p256_uint1 x651; + uint32_t x652; + fiat_p256_uint1 x653; + uint32_t x654; + fiat_p256_uint1 x655; + uint32_t x656; + uint32_t x657; + uint32_t x658; + uint32_t x659; + uint32_t x660; + uint32_t x661; + uint32_t x662; + uint32_t x663; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, (arg1[7])); + fiat_p256_mulx_u32(&x11, &x12, x8, (arg1[6])); + fiat_p256_mulx_u32(&x13, &x14, x8, (arg1[5])); + fiat_p256_mulx_u32(&x15, &x16, x8, (arg1[4])); + fiat_p256_mulx_u32(&x17, &x18, x8, (arg1[3])); + fiat_p256_mulx_u32(&x19, &x20, x8, (arg1[2])); + fiat_p256_mulx_u32(&x21, &x22, x8, (arg1[1])); + fiat_p256_mulx_u32(&x23, &x24, x8, (arg1[0])); + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); + fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); + fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); + fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); + x39 = (x38 + x10); + fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); + x52 = (x51 + x43); + fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); + fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); + fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); + fiat_p256_mulx_u32(&x71, &x72, x1, (arg1[7])); + fiat_p256_mulx_u32(&x73, &x74, x1, (arg1[6])); + fiat_p256_mulx_u32(&x75, &x76, x1, (arg1[5])); + fiat_p256_mulx_u32(&x77, &x78, x1, (arg1[4])); + fiat_p256_mulx_u32(&x79, &x80, x1, (arg1[3])); + fiat_p256_mulx_u32(&x81, &x82, x1, (arg1[2])); + fiat_p256_mulx_u32(&x83, &x84, x1, (arg1[1])); + fiat_p256_mulx_u32(&x85, &x86, x1, (arg1[0])); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); + x101 = (x100 + x72); + fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); + fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); + fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); + fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); + fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); + fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); + x132 = (x131 + x123); + fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); + fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); + fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); + fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); + fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); + fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); + fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); + fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); + x151 = ((uint32_t)x150 + x119); + fiat_p256_mulx_u32(&x152, &x153, x2, (arg1[7])); + fiat_p256_mulx_u32(&x154, &x155, x2, (arg1[6])); + fiat_p256_mulx_u32(&x156, &x157, x2, (arg1[5])); + fiat_p256_mulx_u32(&x158, &x159, x2, (arg1[4])); + fiat_p256_mulx_u32(&x160, &x161, x2, (arg1[3])); + fiat_p256_mulx_u32(&x162, &x163, x2, (arg1[2])); + fiat_p256_mulx_u32(&x164, &x165, x2, (arg1[1])); + fiat_p256_mulx_u32(&x166, &x167, x2, (arg1[0])); + fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); + x182 = (x181 + x153); + fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); + fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); + fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); + fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); + x213 = (x212 + x204); + fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); + fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); + fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); + x232 = ((uint32_t)x231 + x200); + fiat_p256_mulx_u32(&x233, &x234, x3, (arg1[7])); + fiat_p256_mulx_u32(&x235, &x236, x3, (arg1[6])); + fiat_p256_mulx_u32(&x237, &x238, x3, (arg1[5])); + fiat_p256_mulx_u32(&x239, &x240, x3, (arg1[4])); + fiat_p256_mulx_u32(&x241, &x242, x3, (arg1[3])); + fiat_p256_mulx_u32(&x243, &x244, x3, (arg1[2])); + fiat_p256_mulx_u32(&x245, &x246, x3, (arg1[1])); + fiat_p256_mulx_u32(&x247, &x248, x3, (arg1[0])); + fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); + fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); + fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); + x263 = (x262 + x234); + fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); + fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); + fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); + fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); + fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); + x294 = (x293 + x285); + fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); + fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); + x313 = ((uint32_t)x312 + x281); + fiat_p256_mulx_u32(&x314, &x315, x4, (arg1[7])); + fiat_p256_mulx_u32(&x316, &x317, x4, (arg1[6])); + fiat_p256_mulx_u32(&x318, &x319, x4, (arg1[5])); + fiat_p256_mulx_u32(&x320, &x321, x4, (arg1[4])); + fiat_p256_mulx_u32(&x322, &x323, x4, (arg1[3])); + fiat_p256_mulx_u32(&x324, &x325, x4, (arg1[2])); + fiat_p256_mulx_u32(&x326, &x327, x4, (arg1[1])); + fiat_p256_mulx_u32(&x328, &x329, x4, (arg1[0])); + fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); + fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); + fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); + fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); + fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); + fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); + fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); + x344 = (x343 + x315); + fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); + fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); + fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); + fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); + fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); + fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); + fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); + fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); + x375 = (x374 + x366); + fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); + fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); + fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); + fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); + fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); + fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); + fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); + fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); + fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); + x394 = ((uint32_t)x393 + x362); + fiat_p256_mulx_u32(&x395, &x396, x5, (arg1[7])); + fiat_p256_mulx_u32(&x397, &x398, x5, (arg1[6])); + fiat_p256_mulx_u32(&x399, &x400, x5, (arg1[5])); + fiat_p256_mulx_u32(&x401, &x402, x5, (arg1[4])); + fiat_p256_mulx_u32(&x403, &x404, x5, (arg1[3])); + fiat_p256_mulx_u32(&x405, &x406, x5, (arg1[2])); + fiat_p256_mulx_u32(&x407, &x408, x5, (arg1[1])); + fiat_p256_mulx_u32(&x409, &x410, x5, (arg1[0])); + fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); + fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); + fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); + fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); + fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); + fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); + fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); + x425 = (x424 + x396); + fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); + fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); + fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); + fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); + fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); + fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); + fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); + fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); + fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); + fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); + fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); + x456 = (x455 + x447); + fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); + fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); + fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); + fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); + x475 = ((uint32_t)x474 + x443); + fiat_p256_mulx_u32(&x476, &x477, x6, (arg1[7])); + fiat_p256_mulx_u32(&x478, &x479, x6, (arg1[6])); + fiat_p256_mulx_u32(&x480, &x481, x6, (arg1[5])); + fiat_p256_mulx_u32(&x482, &x483, x6, (arg1[4])); + fiat_p256_mulx_u32(&x484, &x485, x6, (arg1[3])); + fiat_p256_mulx_u32(&x486, &x487, x6, (arg1[2])); + fiat_p256_mulx_u32(&x488, &x489, x6, (arg1[1])); + fiat_p256_mulx_u32(&x490, &x491, x6, (arg1[0])); + fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); + fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); + fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); + fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); + fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); + fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); + fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); + x506 = (x505 + x477); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); + fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); + fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); + x537 = (x536 + x528); + fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); + fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); + fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); + fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); + fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); + fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); + fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); + fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); + fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); + x556 = ((uint32_t)x555 + x524); + fiat_p256_mulx_u32(&x557, &x558, x7, (arg1[7])); + fiat_p256_mulx_u32(&x559, &x560, x7, (arg1[6])); + fiat_p256_mulx_u32(&x561, &x562, x7, (arg1[5])); + fiat_p256_mulx_u32(&x563, &x564, x7, (arg1[4])); + fiat_p256_mulx_u32(&x565, &x566, x7, (arg1[3])); + fiat_p256_mulx_u32(&x567, &x568, x7, (arg1[2])); + fiat_p256_mulx_u32(&x569, &x570, x7, (arg1[1])); + fiat_p256_mulx_u32(&x571, &x572, x7, (arg1[0])); + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); + fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); + fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); + fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); + fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); + fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); + fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); + x587 = (x586 + x558); + fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); + fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); + fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); + fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); + fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); + fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); + fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); + fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); + fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); + fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); + fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); + x618 = (x617 + x609); + fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); + fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); + fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); + fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); + fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); + fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); + fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); + fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); + fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); + x637 = ((uint32_t)x636 + x605); + fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); + fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); + fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); + fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); + fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); + fiat_p256_cmovznz_u32(&x656, x655, x638, x621); + fiat_p256_cmovznz_u32(&x657, x655, x640, x623); + fiat_p256_cmovznz_u32(&x658, x655, x642, x625); + fiat_p256_cmovznz_u32(&x659, x655, x644, x627); + fiat_p256_cmovznz_u32(&x660, x655, x646, x629); + fiat_p256_cmovznz_u32(&x661, x655, x648, x631); + fiat_p256_cmovznz_u32(&x662, x655, x650, x633); + fiat_p256_cmovznz_u32(&x663, x655, x652, x635); + out1[0] = x656; + out1[1] = x657; + out1[2] = x658; + out1[3] = x659; + out1[4] = x660; + out1[5] = x661; + out1[6] = x662; + out1[7] = x663; +} + +/* + * The function fiat_p256_add adds two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint32_t x1; + fiat_p256_uint1 x2; + uint32_t x3; + fiat_p256_uint1 x4; + uint32_t x5; + fiat_p256_uint1 x6; + uint32_t x7; + fiat_p256_uint1 x8; + uint32_t x9; + fiat_p256_uint1 x10; + uint32_t x11; + fiat_p256_uint1 x12; + uint32_t x13; + fiat_p256_uint1 x14; + uint32_t x15; + fiat_p256_uint1 x16; + uint32_t x17; + fiat_p256_uint1 x18; + uint32_t x19; + fiat_p256_uint1 x20; + uint32_t x21; + fiat_p256_uint1 x22; + uint32_t x23; + fiat_p256_uint1 x24; + uint32_t x25; + fiat_p256_uint1 x26; + uint32_t x27; + fiat_p256_uint1 x28; + uint32_t x29; + fiat_p256_uint1 x30; + uint32_t x31; + fiat_p256_uint1 x32; + uint32_t x33; + fiat_p256_uint1 x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_addcarryx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_addcarryx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_addcarryx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_addcarryx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); + fiat_p256_addcarryx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); + fiat_p256_addcarryx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); + fiat_p256_addcarryx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); + fiat_p256_subborrowx_u32(&x17, &x18, 0x0, x1, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x19, &x20, x18, x3, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x21, &x22, x20, x5, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x23, &x24, x22, x7, 0x0); + fiat_p256_subborrowx_u32(&x25, &x26, x24, x9, 0x0); + fiat_p256_subborrowx_u32(&x27, &x28, x26, x11, 0x0); + fiat_p256_subborrowx_u32(&x29, &x30, x28, x13, 0x1); + fiat_p256_subborrowx_u32(&x31, &x32, x30, x15, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x33, &x34, x32, x16, 0x0); + fiat_p256_cmovznz_u32(&x35, x34, x17, x1); + fiat_p256_cmovznz_u32(&x36, x34, x19, x3); + fiat_p256_cmovznz_u32(&x37, x34, x21, x5); + fiat_p256_cmovznz_u32(&x38, x34, x23, x7); + fiat_p256_cmovznz_u32(&x39, x34, x25, x9); + fiat_p256_cmovznz_u32(&x40, x34, x27, x11); + fiat_p256_cmovznz_u32(&x41, x34, x29, x13); + fiat_p256_cmovznz_u32(&x42, x34, x31, x15); + out1[0] = x35; + out1[1] = x36; + out1[2] = x37; + out1[3] = x38; + out1[4] = x39; + out1[5] = x40; + out1[6] = x41; + out1[7] = x42; +} + +/* + * The function fiat_p256_sub subtracts two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint32_t x1; + fiat_p256_uint1 x2; + uint32_t x3; + fiat_p256_uint1 x4; + uint32_t x5; + fiat_p256_uint1 x6; + uint32_t x7; + fiat_p256_uint1 x8; + uint32_t x9; + fiat_p256_uint1 x10; + uint32_t x11; + fiat_p256_uint1 x12; + uint32_t x13; + fiat_p256_uint1 x14; + uint32_t x15; + fiat_p256_uint1 x16; + uint32_t x17; + uint32_t x18; + fiat_p256_uint1 x19; + uint32_t x20; + fiat_p256_uint1 x21; + uint32_t x22; + fiat_p256_uint1 x23; + uint32_t x24; + fiat_p256_uint1 x25; + uint32_t x26; + fiat_p256_uint1 x27; + uint32_t x28; + fiat_p256_uint1 x29; + uint32_t x30; + fiat_p256_uint1 x31; + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_subborrowx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_subborrowx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_subborrowx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_subborrowx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); + fiat_p256_subborrowx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); + fiat_p256_subborrowx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); + fiat_p256_subborrowx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, x17); + fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, x17); + fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, x17); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); + fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); + fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); + fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, x17); + out1[0] = x18; + out1[1] = x20; + out1[2] = x22; + out1[3] = x24; + out1[4] = x26; + out1[5] = x28; + out1[6] = x30; + out1[7] = x32; +} + +/* + * The function fiat_p256_opp negates a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_opp(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint32_t x1; + fiat_p256_uint1 x2; + uint32_t x3; + fiat_p256_uint1 x4; + uint32_t x5; + fiat_p256_uint1 x6; + uint32_t x7; + fiat_p256_uint1 x8; + uint32_t x9; + fiat_p256_uint1 x10; + uint32_t x11; + fiat_p256_uint1 x12; + uint32_t x13; + fiat_p256_uint1 x14; + uint32_t x15; + fiat_p256_uint1 x16; + uint32_t x17; + uint32_t x18; + fiat_p256_uint1 x19; + uint32_t x20; + fiat_p256_uint1 x21; + uint32_t x22; + fiat_p256_uint1 x23; + uint32_t x24; + fiat_p256_uint1 x25; + uint32_t x26; + fiat_p256_uint1 x27; + uint32_t x28; + fiat_p256_uint1 x29; + uint32_t x30; + fiat_p256_uint1 x31; + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, 0x0, (arg1[0])); + fiat_p256_subborrowx_u32(&x3, &x4, x2, 0x0, (arg1[1])); + fiat_p256_subborrowx_u32(&x5, &x6, x4, 0x0, (arg1[2])); + fiat_p256_subborrowx_u32(&x7, &x8, x6, 0x0, (arg1[3])); + fiat_p256_subborrowx_u32(&x9, &x10, x8, 0x0, (arg1[4])); + fiat_p256_subborrowx_u32(&x11, &x12, x10, 0x0, (arg1[5])); + fiat_p256_subborrowx_u32(&x13, &x14, x12, 0x0, (arg1[6])); + fiat_p256_subborrowx_u32(&x15, &x16, x14, 0x0, (arg1[7])); + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, x17); + fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, x17); + fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, x17); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); + fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); + fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); + fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, x17); + out1[0] = x18; + out1[1] = x20; + out1[2] = x22; + out1[3] = x24; + out1[4] = x26; + out1[5] = x28; + out1[6] = x30; + out1[7] = x32; +} + +/* + * The function fiat_p256_from_montgomery translates a field element out of the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval out1 mod m = (eval arg1 * ((2^32)⁻¹ mod m)^8) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_montgomery(fiat_p256_non_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + fiat_p256_uint1 x11; + uint32_t x12; + fiat_p256_uint1 x13; + uint32_t x14; + fiat_p256_uint1 x15; + uint32_t x16; + fiat_p256_uint1 x17; + uint32_t x18; + fiat_p256_uint1 x19; + uint32_t x20; + fiat_p256_uint1 x21; + uint32_t x22; + fiat_p256_uint1 x23; + uint32_t x24; + fiat_p256_uint1 x25; + uint32_t x26; + fiat_p256_uint1 x27; + uint32_t x28; + uint32_t x29; + uint32_t x30; + uint32_t x31; + uint32_t x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + fiat_p256_uint1 x37; + uint32_t x38; + fiat_p256_uint1 x39; + uint32_t x40; + fiat_p256_uint1 x41; + uint32_t x42; + fiat_p256_uint1 x43; + uint32_t x44; + fiat_p256_uint1 x45; + uint32_t x46; + fiat_p256_uint1 x47; + uint32_t x48; + fiat_p256_uint1 x49; + uint32_t x50; + fiat_p256_uint1 x51; + uint32_t x52; + fiat_p256_uint1 x53; + uint32_t x54; + fiat_p256_uint1 x55; + uint32_t x56; + fiat_p256_uint1 x57; + uint32_t x58; + uint32_t x59; + uint32_t x60; + uint32_t x61; + uint32_t x62; + uint32_t x63; + uint32_t x64; + uint32_t x65; + uint32_t x66; + fiat_p256_uint1 x67; + uint32_t x68; + fiat_p256_uint1 x69; + uint32_t x70; + fiat_p256_uint1 x71; + uint32_t x72; + fiat_p256_uint1 x73; + uint32_t x74; + fiat_p256_uint1 x75; + uint32_t x76; + fiat_p256_uint1 x77; + uint32_t x78; + fiat_p256_uint1 x79; + uint32_t x80; + fiat_p256_uint1 x81; + uint32_t x82; + fiat_p256_uint1 x83; + uint32_t x84; + fiat_p256_uint1 x85; + uint32_t x86; + fiat_p256_uint1 x87; + uint32_t x88; + fiat_p256_uint1 x89; + uint32_t x90; + fiat_p256_uint1 x91; + uint32_t x92; + fiat_p256_uint1 x93; + uint32_t x94; + fiat_p256_uint1 x95; + uint32_t x96; + fiat_p256_uint1 x97; + uint32_t x98; + fiat_p256_uint1 x99; + uint32_t x100; + fiat_p256_uint1 x101; + uint32_t x102; + uint32_t x103; + uint32_t x104; + uint32_t x105; + uint32_t x106; + uint32_t x107; + uint32_t x108; + uint32_t x109; + uint32_t x110; + fiat_p256_uint1 x111; + uint32_t x112; + fiat_p256_uint1 x113; + uint32_t x114; + fiat_p256_uint1 x115; + uint32_t x116; + fiat_p256_uint1 x117; + uint32_t x118; + fiat_p256_uint1 x119; + uint32_t x120; + fiat_p256_uint1 x121; + uint32_t x122; + fiat_p256_uint1 x123; + uint32_t x124; + fiat_p256_uint1 x125; + uint32_t x126; + fiat_p256_uint1 x127; + uint32_t x128; + fiat_p256_uint1 x129; + uint32_t x130; + fiat_p256_uint1 x131; + uint32_t x132; + fiat_p256_uint1 x133; + uint32_t x134; + fiat_p256_uint1 x135; + uint32_t x136; + fiat_p256_uint1 x137; + uint32_t x138; + fiat_p256_uint1 x139; + uint32_t x140; + fiat_p256_uint1 x141; + uint32_t x142; + fiat_p256_uint1 x143; + uint32_t x144; + fiat_p256_uint1 x145; + uint32_t x146; + fiat_p256_uint1 x147; + uint32_t x148; + uint32_t x149; + uint32_t x150; + uint32_t x151; + uint32_t x152; + uint32_t x153; + uint32_t x154; + uint32_t x155; + uint32_t x156; + fiat_p256_uint1 x157; + uint32_t x158; + fiat_p256_uint1 x159; + uint32_t x160; + fiat_p256_uint1 x161; + uint32_t x162; + fiat_p256_uint1 x163; + uint32_t x164; + fiat_p256_uint1 x165; + uint32_t x166; + fiat_p256_uint1 x167; + uint32_t x168; + fiat_p256_uint1 x169; + uint32_t x170; + fiat_p256_uint1 x171; + uint32_t x172; + fiat_p256_uint1 x173; + uint32_t x174; + fiat_p256_uint1 x175; + uint32_t x176; + fiat_p256_uint1 x177; + uint32_t x178; + fiat_p256_uint1 x179; + uint32_t x180; + fiat_p256_uint1 x181; + uint32_t x182; + fiat_p256_uint1 x183; + uint32_t x184; + fiat_p256_uint1 x185; + uint32_t x186; + fiat_p256_uint1 x187; + uint32_t x188; + fiat_p256_uint1 x189; + uint32_t x190; + fiat_p256_uint1 x191; + uint32_t x192; + fiat_p256_uint1 x193; + uint32_t x194; + uint32_t x195; + uint32_t x196; + uint32_t x197; + uint32_t x198; + uint32_t x199; + uint32_t x200; + uint32_t x201; + uint32_t x202; + fiat_p256_uint1 x203; + uint32_t x204; + fiat_p256_uint1 x205; + uint32_t x206; + fiat_p256_uint1 x207; + uint32_t x208; + fiat_p256_uint1 x209; + uint32_t x210; + fiat_p256_uint1 x211; + uint32_t x212; + fiat_p256_uint1 x213; + uint32_t x214; + fiat_p256_uint1 x215; + uint32_t x216; + fiat_p256_uint1 x217; + uint32_t x218; + fiat_p256_uint1 x219; + uint32_t x220; + fiat_p256_uint1 x221; + uint32_t x222; + fiat_p256_uint1 x223; + uint32_t x224; + fiat_p256_uint1 x225; + uint32_t x226; + fiat_p256_uint1 x227; + uint32_t x228; + fiat_p256_uint1 x229; + uint32_t x230; + fiat_p256_uint1 x231; + uint32_t x232; + fiat_p256_uint1 x233; + uint32_t x234; + fiat_p256_uint1 x235; + uint32_t x236; + fiat_p256_uint1 x237; + uint32_t x238; + fiat_p256_uint1 x239; + uint32_t x240; + uint32_t x241; + uint32_t x242; + uint32_t x243; + uint32_t x244; + uint32_t x245; + uint32_t x246; + uint32_t x247; + uint32_t x248; + fiat_p256_uint1 x249; + uint32_t x250; + fiat_p256_uint1 x251; + uint32_t x252; + fiat_p256_uint1 x253; + uint32_t x254; + fiat_p256_uint1 x255; + uint32_t x256; + fiat_p256_uint1 x257; + uint32_t x258; + fiat_p256_uint1 x259; + uint32_t x260; + fiat_p256_uint1 x261; + uint32_t x262; + fiat_p256_uint1 x263; + uint32_t x264; + fiat_p256_uint1 x265; + uint32_t x266; + fiat_p256_uint1 x267; + uint32_t x268; + fiat_p256_uint1 x269; + uint32_t x270; + fiat_p256_uint1 x271; + uint32_t x272; + fiat_p256_uint1 x273; + uint32_t x274; + fiat_p256_uint1 x275; + uint32_t x276; + fiat_p256_uint1 x277; + uint32_t x278; + fiat_p256_uint1 x279; + uint32_t x280; + fiat_p256_uint1 x281; + uint32_t x282; + fiat_p256_uint1 x283; + uint32_t x284; + fiat_p256_uint1 x285; + uint32_t x286; + uint32_t x287; + uint32_t x288; + uint32_t x289; + uint32_t x290; + uint32_t x291; + uint32_t x292; + uint32_t x293; + uint32_t x294; + fiat_p256_uint1 x295; + uint32_t x296; + fiat_p256_uint1 x297; + uint32_t x298; + fiat_p256_uint1 x299; + uint32_t x300; + fiat_p256_uint1 x301; + uint32_t x302; + fiat_p256_uint1 x303; + uint32_t x304; + fiat_p256_uint1 x305; + uint32_t x306; + fiat_p256_uint1 x307; + uint32_t x308; + fiat_p256_uint1 x309; + uint32_t x310; + fiat_p256_uint1 x311; + uint32_t x312; + fiat_p256_uint1 x313; + uint32_t x314; + fiat_p256_uint1 x315; + uint32_t x316; + fiat_p256_uint1 x317; + uint32_t x318; + fiat_p256_uint1 x319; + uint32_t x320; + fiat_p256_uint1 x321; + uint32_t x322; + fiat_p256_uint1 x323; + uint32_t x324; + fiat_p256_uint1 x325; + uint32_t x326; + fiat_p256_uint1 x327; + uint32_t x328; + fiat_p256_uint1 x329; + uint32_t x330; + fiat_p256_uint1 x331; + uint32_t x332; + fiat_p256_uint1 x333; + uint32_t x334; + uint32_t x335; + uint32_t x336; + uint32_t x337; + uint32_t x338; + uint32_t x339; + uint32_t x340; + uint32_t x341; + x1 = (arg1[0]); + fiat_p256_mulx_u32(&x2, &x3, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x4, &x5, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x6, &x7, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x8, &x9, x1, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x10, &x11, 0x0, x9, x6); + fiat_p256_addcarryx_u32(&x12, &x13, x11, x7, x4); + fiat_p256_addcarryx_u32(&x14, &x15, 0x0, x1, x8); + fiat_p256_addcarryx_u32(&x16, &x17, x15, 0x0, x10); + fiat_p256_addcarryx_u32(&x18, &x19, x17, 0x0, x12); + fiat_p256_addcarryx_u32(&x20, &x21, x19, 0x0, (x13 + x5)); + fiat_p256_addcarryx_u32(&x22, &x23, 0x0, x16, (arg1[1])); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x18, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x20, 0x0); + fiat_p256_mulx_u32(&x28, &x29, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x30, &x31, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x32, &x33, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x34, &x35, x22, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x36, &x37, 0x0, x35, x32); + fiat_p256_addcarryx_u32(&x38, &x39, x37, x33, x30); + fiat_p256_addcarryx_u32(&x40, &x41, 0x0, x22, x34); + fiat_p256_addcarryx_u32(&x42, &x43, x41, x24, x36); + fiat_p256_addcarryx_u32(&x44, &x45, x43, x26, x38); + fiat_p256_addcarryx_u32(&x46, &x47, x45, ((uint32_t)x27 + x21), (x39 + x31)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x2, x22); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x3, x28); + fiat_p256_addcarryx_u32(&x52, &x53, 0x0, x42, (arg1[2])); + fiat_p256_addcarryx_u32(&x54, &x55, x53, x44, 0x0); + fiat_p256_addcarryx_u32(&x56, &x57, x55, x46, 0x0); + fiat_p256_mulx_u32(&x58, &x59, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x60, &x61, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x62, &x63, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x64, &x65, x52, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x66, &x67, 0x0, x65, x62); + fiat_p256_addcarryx_u32(&x68, &x69, x67, x63, x60); + fiat_p256_addcarryx_u32(&x70, &x71, 0x0, x52, x64); + fiat_p256_addcarryx_u32(&x72, &x73, x71, x54, x66); + fiat_p256_addcarryx_u32(&x74, &x75, x73, x56, x68); + fiat_p256_addcarryx_u32(&x76, &x77, x75, ((uint32_t)x57 + x47), (x69 + x61)); + fiat_p256_addcarryx_u32(&x78, &x79, x77, x1, 0x0); + fiat_p256_addcarryx_u32(&x80, &x81, x79, x48, 0x0); + fiat_p256_addcarryx_u32(&x82, &x83, x81, x50, x52); + fiat_p256_addcarryx_u32(&x84, &x85, x83, (x51 + x29), x58); + fiat_p256_addcarryx_u32(&x86, &x87, 0x0, x72, (arg1[3])); + fiat_p256_addcarryx_u32(&x88, &x89, x87, x74, 0x0); + fiat_p256_addcarryx_u32(&x90, &x91, x89, x76, 0x0); + fiat_p256_addcarryx_u32(&x92, &x93, x91, x78, 0x0); + fiat_p256_addcarryx_u32(&x94, &x95, x93, x80, 0x0); + fiat_p256_addcarryx_u32(&x96, &x97, x95, x82, 0x0); + fiat_p256_addcarryx_u32(&x98, &x99, x97, x84, 0x0); + fiat_p256_addcarryx_u32(&x100, &x101, x99, (x85 + x59), 0x0); + fiat_p256_mulx_u32(&x102, &x103, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x104, &x105, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x106, &x107, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x108, &x109, x86, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x109, x106); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x107, x104); + fiat_p256_addcarryx_u32(&x114, &x115, 0x0, x86, x108); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x88, x110); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x90, x112); + fiat_p256_addcarryx_u32(&x120, &x121, x119, x92, (x113 + x105)); + fiat_p256_addcarryx_u32(&x122, &x123, x121, x94, 0x0); + fiat_p256_addcarryx_u32(&x124, &x125, x123, x96, 0x0); + fiat_p256_addcarryx_u32(&x126, &x127, x125, x98, x86); + fiat_p256_addcarryx_u32(&x128, &x129, x127, x100, x102); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x101, x103); + fiat_p256_addcarryx_u32(&x132, &x133, 0x0, x116, (arg1[4])); + fiat_p256_addcarryx_u32(&x134, &x135, x133, x118, 0x0); + fiat_p256_addcarryx_u32(&x136, &x137, x135, x120, 0x0); + fiat_p256_addcarryx_u32(&x138, &x139, x137, x122, 0x0); + fiat_p256_addcarryx_u32(&x140, &x141, x139, x124, 0x0); + fiat_p256_addcarryx_u32(&x142, &x143, x141, x126, 0x0); + fiat_p256_addcarryx_u32(&x144, &x145, x143, x128, 0x0); + fiat_p256_addcarryx_u32(&x146, &x147, x145, x130, 0x0); + fiat_p256_mulx_u32(&x148, &x149, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x150, &x151, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x152, &x153, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x154, &x155, x132, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x156, &x157, 0x0, x155, x152); + fiat_p256_addcarryx_u32(&x158, &x159, x157, x153, x150); + fiat_p256_addcarryx_u32(&x160, &x161, 0x0, x132, x154); + fiat_p256_addcarryx_u32(&x162, &x163, x161, x134, x156); + fiat_p256_addcarryx_u32(&x164, &x165, x163, x136, x158); + fiat_p256_addcarryx_u32(&x166, &x167, x165, x138, (x159 + x151)); + fiat_p256_addcarryx_u32(&x168, &x169, x167, x140, 0x0); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x142, 0x0); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x144, x132); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x146, x148); + fiat_p256_addcarryx_u32(&x176, &x177, x175, ((uint32_t)x147 + x131), x149); + fiat_p256_addcarryx_u32(&x178, &x179, 0x0, x162, (arg1[5])); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x164, 0x0); + fiat_p256_addcarryx_u32(&x182, &x183, x181, x166, 0x0); + fiat_p256_addcarryx_u32(&x184, &x185, x183, x168, 0x0); + fiat_p256_addcarryx_u32(&x186, &x187, x185, x170, 0x0); + fiat_p256_addcarryx_u32(&x188, &x189, x187, x172, 0x0); + fiat_p256_addcarryx_u32(&x190, &x191, x189, x174, 0x0); + fiat_p256_addcarryx_u32(&x192, &x193, x191, x176, 0x0); + fiat_p256_mulx_u32(&x194, &x195, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x196, &x197, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x198, &x199, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x200, &x201, x178, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x202, &x203, 0x0, x201, x198); + fiat_p256_addcarryx_u32(&x204, &x205, x203, x199, x196); + fiat_p256_addcarryx_u32(&x206, &x207, 0x0, x178, x200); + fiat_p256_addcarryx_u32(&x208, &x209, x207, x180, x202); + fiat_p256_addcarryx_u32(&x210, &x211, x209, x182, x204); + fiat_p256_addcarryx_u32(&x212, &x213, x211, x184, (x205 + x197)); + fiat_p256_addcarryx_u32(&x214, &x215, x213, x186, 0x0); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x188, 0x0); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x190, x178); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x192, x194); + fiat_p256_addcarryx_u32(&x222, &x223, x221, ((uint32_t)x193 + x177), x195); + fiat_p256_addcarryx_u32(&x224, &x225, 0x0, x208, (arg1[6])); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x210, 0x0); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x212, 0x0); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x214, 0x0); + fiat_p256_addcarryx_u32(&x232, &x233, x231, x216, 0x0); + fiat_p256_addcarryx_u32(&x234, &x235, x233, x218, 0x0); + fiat_p256_addcarryx_u32(&x236, &x237, x235, x220, 0x0); + fiat_p256_addcarryx_u32(&x238, &x239, x237, x222, 0x0); + fiat_p256_mulx_u32(&x240, &x241, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x242, &x243, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x244, &x245, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x246, &x247, x224, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x248, &x249, 0x0, x247, x244); + fiat_p256_addcarryx_u32(&x250, &x251, x249, x245, x242); + fiat_p256_addcarryx_u32(&x252, &x253, 0x0, x224, x246); + fiat_p256_addcarryx_u32(&x254, &x255, x253, x226, x248); + fiat_p256_addcarryx_u32(&x256, &x257, x255, x228, x250); + fiat_p256_addcarryx_u32(&x258, &x259, x257, x230, (x251 + x243)); + fiat_p256_addcarryx_u32(&x260, &x261, x259, x232, 0x0); + fiat_p256_addcarryx_u32(&x262, &x263, x261, x234, 0x0); + fiat_p256_addcarryx_u32(&x264, &x265, x263, x236, x224); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x238, x240); + fiat_p256_addcarryx_u32(&x268, &x269, x267, ((uint32_t)x239 + x223), x241); + fiat_p256_addcarryx_u32(&x270, &x271, 0x0, x254, (arg1[7])); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x256, 0x0); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x258, 0x0); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x260, 0x0); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x262, 0x0); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x264, 0x0); + fiat_p256_addcarryx_u32(&x282, &x283, x281, x266, 0x0); + fiat_p256_addcarryx_u32(&x284, &x285, x283, x268, 0x0); + fiat_p256_mulx_u32(&x286, &x287, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x290, &x291, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x292, &x293, x270, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x294, &x295, 0x0, x293, x290); + fiat_p256_addcarryx_u32(&x296, &x297, x295, x291, x288); + fiat_p256_addcarryx_u32(&x298, &x299, 0x0, x270, x292); + fiat_p256_addcarryx_u32(&x300, &x301, x299, x272, x294); + fiat_p256_addcarryx_u32(&x302, &x303, x301, x274, x296); + fiat_p256_addcarryx_u32(&x304, &x305, x303, x276, (x297 + x289)); + fiat_p256_addcarryx_u32(&x306, &x307, x305, x278, 0x0); + fiat_p256_addcarryx_u32(&x308, &x309, x307, x280, 0x0); + fiat_p256_addcarryx_u32(&x310, &x311, x309, x282, x270); + fiat_p256_addcarryx_u32(&x312, &x313, x311, x284, x286); + fiat_p256_addcarryx_u32(&x314, &x315, x313, ((uint32_t)x285 + x269), x287); + fiat_p256_subborrowx_u32(&x316, &x317, 0x0, x300, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x318, &x319, x317, x302, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x320, &x321, x319, x304, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x322, &x323, x321, x306, 0x0); + fiat_p256_subborrowx_u32(&x324, &x325, x323, x308, 0x0); + fiat_p256_subborrowx_u32(&x326, &x327, x325, x310, 0x0); + fiat_p256_subborrowx_u32(&x328, &x329, x327, x312, 0x1); + fiat_p256_subborrowx_u32(&x330, &x331, x329, x314, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x332, &x333, x331, x315, 0x0); + fiat_p256_cmovznz_u32(&x334, x333, x316, x300); + fiat_p256_cmovznz_u32(&x335, x333, x318, x302); + fiat_p256_cmovznz_u32(&x336, x333, x320, x304); + fiat_p256_cmovznz_u32(&x337, x333, x322, x306); + fiat_p256_cmovznz_u32(&x338, x333, x324, x308); + fiat_p256_cmovznz_u32(&x339, x333, x326, x310); + fiat_p256_cmovznz_u32(&x340, x333, x328, x312); + fiat_p256_cmovznz_u32(&x341, x333, x330, x314); + out1[0] = x334; + out1[1] = x335; + out1[2] = x336; + out1[3] = x337; + out1[4] = x338; + out1[5] = x339; + out1[6] = x340; + out1[7] = x341; +} + +/* + * The function fiat_p256_to_montgomery translates a field element into the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = eval arg1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_montgomery(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_non_montgomery_domain_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + fiat_p256_uint1 x24; + uint32_t x25; + fiat_p256_uint1 x26; + uint32_t x27; + fiat_p256_uint1 x28; + uint32_t x29; + fiat_p256_uint1 x30; + uint32_t x31; + fiat_p256_uint1 x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + fiat_p256_uint1 x42; + uint32_t x43; + fiat_p256_uint1 x44; + uint32_t x45; + fiat_p256_uint1 x46; + uint32_t x47; + fiat_p256_uint1 x48; + uint32_t x49; + fiat_p256_uint1 x50; + uint32_t x51; + fiat_p256_uint1 x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + uint32_t x64; + uint32_t x65; + uint32_t x66; + uint32_t x67; + uint32_t x68; + uint32_t x69; + uint32_t x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint32_t x75; + uint32_t x76; + uint32_t x77; + fiat_p256_uint1 x78; + uint32_t x79; + fiat_p256_uint1 x80; + uint32_t x81; + fiat_p256_uint1 x82; + uint32_t x83; + fiat_p256_uint1 x84; + uint32_t x85; + fiat_p256_uint1 x86; + uint32_t x87; + fiat_p256_uint1 x88; + uint32_t x89; + fiat_p256_uint1 x90; + uint32_t x91; + fiat_p256_uint1 x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + fiat_p256_uint1 x102; + uint32_t x103; + uint32_t x104; + uint32_t x105; + uint32_t x106; + uint32_t x107; + uint32_t x108; + uint32_t x109; + uint32_t x110; + uint32_t x111; + fiat_p256_uint1 x112; + uint32_t x113; + fiat_p256_uint1 x114; + uint32_t x115; + fiat_p256_uint1 x116; + uint32_t x117; + fiat_p256_uint1 x118; + uint32_t x119; + fiat_p256_uint1 x120; + uint32_t x121; + fiat_p256_uint1 x122; + uint32_t x123; + fiat_p256_uint1 x124; + uint32_t x125; + fiat_p256_uint1 x126; + uint32_t x127; + fiat_p256_uint1 x128; + uint32_t x129; + fiat_p256_uint1 x130; + uint32_t x131; + fiat_p256_uint1 x132; + uint32_t x133; + uint32_t x134; + uint32_t x135; + uint32_t x136; + uint32_t x137; + uint32_t x138; + uint32_t x139; + uint32_t x140; + uint32_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + uint32_t x145; + uint32_t x146; + uint32_t x147; + fiat_p256_uint1 x148; + uint32_t x149; + fiat_p256_uint1 x150; + uint32_t x151; + fiat_p256_uint1 x152; + uint32_t x153; + fiat_p256_uint1 x154; + uint32_t x155; + fiat_p256_uint1 x156; + uint32_t x157; + fiat_p256_uint1 x158; + uint32_t x159; + fiat_p256_uint1 x160; + uint32_t x161; + fiat_p256_uint1 x162; + uint32_t x163; + fiat_p256_uint1 x164; + uint32_t x165; + fiat_p256_uint1 x166; + uint32_t x167; + fiat_p256_uint1 x168; + uint32_t x169; + fiat_p256_uint1 x170; + uint32_t x171; + fiat_p256_uint1 x172; + uint32_t x173; + uint32_t x174; + uint32_t x175; + uint32_t x176; + uint32_t x177; + uint32_t x178; + uint32_t x179; + uint32_t x180; + uint32_t x181; + fiat_p256_uint1 x182; + uint32_t x183; + fiat_p256_uint1 x184; + uint32_t x185; + fiat_p256_uint1 x186; + uint32_t x187; + fiat_p256_uint1 x188; + uint32_t x189; + fiat_p256_uint1 x190; + uint32_t x191; + fiat_p256_uint1 x192; + uint32_t x193; + fiat_p256_uint1 x194; + uint32_t x195; + fiat_p256_uint1 x196; + uint32_t x197; + fiat_p256_uint1 x198; + uint32_t x199; + fiat_p256_uint1 x200; + uint32_t x201; + fiat_p256_uint1 x202; + uint32_t x203; + uint32_t x204; + uint32_t x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + uint32_t x210; + uint32_t x211; + uint32_t x212; + uint32_t x213; + uint32_t x214; + uint32_t x215; + uint32_t x216; + uint32_t x217; + fiat_p256_uint1 x218; + uint32_t x219; + fiat_p256_uint1 x220; + uint32_t x221; + fiat_p256_uint1 x222; + uint32_t x223; + fiat_p256_uint1 x224; + uint32_t x225; + fiat_p256_uint1 x226; + uint32_t x227; + fiat_p256_uint1 x228; + uint32_t x229; + fiat_p256_uint1 x230; + uint32_t x231; + fiat_p256_uint1 x232; + uint32_t x233; + fiat_p256_uint1 x234; + uint32_t x235; + fiat_p256_uint1 x236; + uint32_t x237; + fiat_p256_uint1 x238; + uint32_t x239; + fiat_p256_uint1 x240; + uint32_t x241; + fiat_p256_uint1 x242; + uint32_t x243; + uint32_t x244; + uint32_t x245; + uint32_t x246; + uint32_t x247; + uint32_t x248; + uint32_t x249; + uint32_t x250; + uint32_t x251; + fiat_p256_uint1 x252; + uint32_t x253; + fiat_p256_uint1 x254; + uint32_t x255; + fiat_p256_uint1 x256; + uint32_t x257; + fiat_p256_uint1 x258; + uint32_t x259; + fiat_p256_uint1 x260; + uint32_t x261; + fiat_p256_uint1 x262; + uint32_t x263; + fiat_p256_uint1 x264; + uint32_t x265; + fiat_p256_uint1 x266; + uint32_t x267; + fiat_p256_uint1 x268; + uint32_t x269; + fiat_p256_uint1 x270; + uint32_t x271; + fiat_p256_uint1 x272; + uint32_t x273; + uint32_t x274; + uint32_t x275; + uint32_t x276; + uint32_t x277; + uint32_t x278; + uint32_t x279; + uint32_t x280; + uint32_t x281; + uint32_t x282; + uint32_t x283; + uint32_t x284; + uint32_t x285; + uint32_t x286; + uint32_t x287; + fiat_p256_uint1 x288; + uint32_t x289; + fiat_p256_uint1 x290; + uint32_t x291; + fiat_p256_uint1 x292; + uint32_t x293; + fiat_p256_uint1 x294; + uint32_t x295; + fiat_p256_uint1 x296; + uint32_t x297; + fiat_p256_uint1 x298; + uint32_t x299; + fiat_p256_uint1 x300; + uint32_t x301; + fiat_p256_uint1 x302; + uint32_t x303; + fiat_p256_uint1 x304; + uint32_t x305; + fiat_p256_uint1 x306; + uint32_t x307; + fiat_p256_uint1 x308; + uint32_t x309; + fiat_p256_uint1 x310; + uint32_t x311; + fiat_p256_uint1 x312; + uint32_t x313; + uint32_t x314; + uint32_t x315; + uint32_t x316; + uint32_t x317; + uint32_t x318; + uint32_t x319; + uint32_t x320; + uint32_t x321; + fiat_p256_uint1 x322; + uint32_t x323; + fiat_p256_uint1 x324; + uint32_t x325; + fiat_p256_uint1 x326; + uint32_t x327; + fiat_p256_uint1 x328; + uint32_t x329; + fiat_p256_uint1 x330; + uint32_t x331; + fiat_p256_uint1 x332; + uint32_t x333; + fiat_p256_uint1 x334; + uint32_t x335; + fiat_p256_uint1 x336; + uint32_t x337; + fiat_p256_uint1 x338; + uint32_t x339; + fiat_p256_uint1 x340; + uint32_t x341; + fiat_p256_uint1 x342; + uint32_t x343; + uint32_t x344; + uint32_t x345; + uint32_t x346; + uint32_t x347; + uint32_t x348; + uint32_t x349; + uint32_t x350; + uint32_t x351; + uint32_t x352; + uint32_t x353; + uint32_t x354; + uint32_t x355; + uint32_t x356; + uint32_t x357; + fiat_p256_uint1 x358; + uint32_t x359; + fiat_p256_uint1 x360; + uint32_t x361; + fiat_p256_uint1 x362; + uint32_t x363; + fiat_p256_uint1 x364; + uint32_t x365; + fiat_p256_uint1 x366; + uint32_t x367; + fiat_p256_uint1 x368; + uint32_t x369; + fiat_p256_uint1 x370; + uint32_t x371; + fiat_p256_uint1 x372; + uint32_t x373; + fiat_p256_uint1 x374; + uint32_t x375; + fiat_p256_uint1 x376; + uint32_t x377; + fiat_p256_uint1 x378; + uint32_t x379; + fiat_p256_uint1 x380; + uint32_t x381; + fiat_p256_uint1 x382; + uint32_t x383; + uint32_t x384; + uint32_t x385; + uint32_t x386; + uint32_t x387; + uint32_t x388; + uint32_t x389; + uint32_t x390; + uint32_t x391; + fiat_p256_uint1 x392; + uint32_t x393; + fiat_p256_uint1 x394; + uint32_t x395; + fiat_p256_uint1 x396; + uint32_t x397; + fiat_p256_uint1 x398; + uint32_t x399; + fiat_p256_uint1 x400; + uint32_t x401; + fiat_p256_uint1 x402; + uint32_t x403; + fiat_p256_uint1 x404; + uint32_t x405; + fiat_p256_uint1 x406; + uint32_t x407; + fiat_p256_uint1 x408; + uint32_t x409; + fiat_p256_uint1 x410; + uint32_t x411; + fiat_p256_uint1 x412; + uint32_t x413; + uint32_t x414; + uint32_t x415; + uint32_t x416; + uint32_t x417; + uint32_t x418; + uint32_t x419; + uint32_t x420; + uint32_t x421; + uint32_t x422; + uint32_t x423; + uint32_t x424; + uint32_t x425; + uint32_t x426; + uint32_t x427; + fiat_p256_uint1 x428; + uint32_t x429; + fiat_p256_uint1 x430; + uint32_t x431; + fiat_p256_uint1 x432; + uint32_t x433; + fiat_p256_uint1 x434; + uint32_t x435; + fiat_p256_uint1 x436; + uint32_t x437; + fiat_p256_uint1 x438; + uint32_t x439; + fiat_p256_uint1 x440; + uint32_t x441; + fiat_p256_uint1 x442; + uint32_t x443; + fiat_p256_uint1 x444; + uint32_t x445; + fiat_p256_uint1 x446; + uint32_t x447; + fiat_p256_uint1 x448; + uint32_t x449; + fiat_p256_uint1 x450; + uint32_t x451; + fiat_p256_uint1 x452; + uint32_t x453; + uint32_t x454; + uint32_t x455; + uint32_t x456; + uint32_t x457; + uint32_t x458; + uint32_t x459; + uint32_t x460; + uint32_t x461; + fiat_p256_uint1 x462; + uint32_t x463; + fiat_p256_uint1 x464; + uint32_t x465; + fiat_p256_uint1 x466; + uint32_t x467; + fiat_p256_uint1 x468; + uint32_t x469; + fiat_p256_uint1 x470; + uint32_t x471; + fiat_p256_uint1 x472; + uint32_t x473; + fiat_p256_uint1 x474; + uint32_t x475; + fiat_p256_uint1 x476; + uint32_t x477; + fiat_p256_uint1 x478; + uint32_t x479; + fiat_p256_uint1 x480; + uint32_t x481; + fiat_p256_uint1 x482; + uint32_t x483; + uint32_t x484; + uint32_t x485; + uint32_t x486; + uint32_t x487; + uint32_t x488; + uint32_t x489; + uint32_t x490; + uint32_t x491; + uint32_t x492; + uint32_t x493; + uint32_t x494; + uint32_t x495; + uint32_t x496; + uint32_t x497; + fiat_p256_uint1 x498; + uint32_t x499; + fiat_p256_uint1 x500; + uint32_t x501; + fiat_p256_uint1 x502; + uint32_t x503; + fiat_p256_uint1 x504; + uint32_t x505; + fiat_p256_uint1 x506; + uint32_t x507; + fiat_p256_uint1 x508; + uint32_t x509; + fiat_p256_uint1 x510; + uint32_t x511; + fiat_p256_uint1 x512; + uint32_t x513; + fiat_p256_uint1 x514; + uint32_t x515; + fiat_p256_uint1 x516; + uint32_t x517; + fiat_p256_uint1 x518; + uint32_t x519; + fiat_p256_uint1 x520; + uint32_t x521; + fiat_p256_uint1 x522; + uint32_t x523; + uint32_t x524; + uint32_t x525; + uint32_t x526; + uint32_t x527; + uint32_t x528; + uint32_t x529; + uint32_t x530; + uint32_t x531; + fiat_p256_uint1 x532; + uint32_t x533; + fiat_p256_uint1 x534; + uint32_t x535; + fiat_p256_uint1 x536; + uint32_t x537; + fiat_p256_uint1 x538; + uint32_t x539; + fiat_p256_uint1 x540; + uint32_t x541; + fiat_p256_uint1 x542; + uint32_t x543; + fiat_p256_uint1 x544; + uint32_t x545; + fiat_p256_uint1 x546; + uint32_t x547; + fiat_p256_uint1 x548; + uint32_t x549; + fiat_p256_uint1 x550; + uint32_t x551; + fiat_p256_uint1 x552; + uint32_t x553; + fiat_p256_uint1 x554; + uint32_t x555; + fiat_p256_uint1 x556; + uint32_t x557; + fiat_p256_uint1 x558; + uint32_t x559; + fiat_p256_uint1 x560; + uint32_t x561; + fiat_p256_uint1 x562; + uint32_t x563; + fiat_p256_uint1 x564; + uint32_t x565; + fiat_p256_uint1 x566; + uint32_t x567; + fiat_p256_uint1 x568; + uint32_t x569; + fiat_p256_uint1 x570; + uint32_t x571; + uint32_t x572; + uint32_t x573; + uint32_t x574; + uint32_t x575; + uint32_t x576; + uint32_t x577; + uint32_t x578; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, 0x4); + fiat_p256_mulx_u32(&x11, &x12, x8, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x13, &x14, x8, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x15, &x16, x8, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x17, &x18, x8, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x19, &x20, x8, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x21, &x22, x8, 0x3); + fiat_p256_addcarryx_u32(&x23, &x24, 0x0, x20, x17); + fiat_p256_addcarryx_u32(&x25, &x26, x24, x18, x15); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x16, x13); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x14, x11); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x12, x9); + fiat_p256_mulx_u32(&x33, &x34, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x35, &x36, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x37, &x38, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x39, &x40, x21, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x41, &x42, 0x0, x40, x37); + fiat_p256_addcarryx_u32(&x43, &x44, x42, x38, x35); + fiat_p256_addcarryx_u32(&x45, &x46, 0x0, x21, x39); + fiat_p256_addcarryx_u32(&x47, &x48, x46, x22, x41); + fiat_p256_addcarryx_u32(&x49, &x50, x48, x19, x43); + fiat_p256_addcarryx_u32(&x51, &x52, x50, x23, (x44 + x36)); + fiat_p256_addcarryx_u32(&x53, &x54, x52, x25, 0x0); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x27, 0x0); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x29, x21); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x31, x33); + fiat_p256_addcarryx_u32(&x61, &x62, x60, (x32 + x10), x34); + fiat_p256_mulx_u32(&x63, &x64, x1, 0x4); + fiat_p256_mulx_u32(&x65, &x66, x1, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x67, &x68, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x69, &x70, x1, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x71, &x72, x1, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x73, &x74, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x75, &x76, x1, 0x3); + fiat_p256_addcarryx_u32(&x77, &x78, 0x0, x74, x71); + fiat_p256_addcarryx_u32(&x79, &x80, x78, x72, x69); + fiat_p256_addcarryx_u32(&x81, &x82, x80, x70, x67); + fiat_p256_addcarryx_u32(&x83, &x84, x82, x68, x65); + fiat_p256_addcarryx_u32(&x85, &x86, x84, x66, x63); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x47, x75); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x49, x76); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x51, x73); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x53, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x55, x79); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x57, x81); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x59, x83); + fiat_p256_addcarryx_u32(&x101, &x102, x100, x61, x85); + fiat_p256_mulx_u32(&x103, &x104, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x105, &x106, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x107, &x108, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x109, &x110, x87, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x111, &x112, 0x0, x110, x107); + fiat_p256_addcarryx_u32(&x113, &x114, x112, x108, x105); + fiat_p256_addcarryx_u32(&x115, &x116, 0x0, x87, x109); + fiat_p256_addcarryx_u32(&x117, &x118, x116, x89, x111); + fiat_p256_addcarryx_u32(&x119, &x120, x118, x91, x113); + fiat_p256_addcarryx_u32(&x121, &x122, x120, x93, (x114 + x106)); + fiat_p256_addcarryx_u32(&x123, &x124, x122, x95, 0x0); + fiat_p256_addcarryx_u32(&x125, &x126, x124, x97, 0x0); + fiat_p256_addcarryx_u32(&x127, &x128, x126, x99, x87); + fiat_p256_addcarryx_u32(&x129, &x130, x128, x101, x103); + fiat_p256_addcarryx_u32(&x131, &x132, x130, (((uint32_t)x102 + x62) + (x86 + x64)), x104); + fiat_p256_mulx_u32(&x133, &x134, x2, 0x4); + fiat_p256_mulx_u32(&x135, &x136, x2, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x137, &x138, x2, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x139, &x140, x2, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x141, &x142, x2, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x143, &x144, x2, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x145, &x146, x2, 0x3); + fiat_p256_addcarryx_u32(&x147, &x148, 0x0, x144, x141); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x142, x139); + fiat_p256_addcarryx_u32(&x151, &x152, x150, x140, x137); + fiat_p256_addcarryx_u32(&x153, &x154, x152, x138, x135); + fiat_p256_addcarryx_u32(&x155, &x156, x154, x136, x133); + fiat_p256_addcarryx_u32(&x157, &x158, 0x0, x117, x145); + fiat_p256_addcarryx_u32(&x159, &x160, x158, x119, x146); + fiat_p256_addcarryx_u32(&x161, &x162, x160, x121, x143); + fiat_p256_addcarryx_u32(&x163, &x164, x162, x123, x147); + fiat_p256_addcarryx_u32(&x165, &x166, x164, x125, x149); + fiat_p256_addcarryx_u32(&x167, &x168, x166, x127, x151); + fiat_p256_addcarryx_u32(&x169, &x170, x168, x129, x153); + fiat_p256_addcarryx_u32(&x171, &x172, x170, x131, x155); + fiat_p256_mulx_u32(&x173, &x174, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x175, &x176, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x177, &x178, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x179, &x180, x157, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x181, &x182, 0x0, x180, x177); + fiat_p256_addcarryx_u32(&x183, &x184, x182, x178, x175); + fiat_p256_addcarryx_u32(&x185, &x186, 0x0, x157, x179); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x159, x181); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x161, x183); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x163, (x184 + x176)); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x165, 0x0); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x167, 0x0); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x169, x157); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x171, x173); + fiat_p256_addcarryx_u32(&x201, &x202, x200, (((uint32_t)x172 + x132) + (x156 + x134)), x174); + fiat_p256_mulx_u32(&x203, &x204, x3, 0x4); + fiat_p256_mulx_u32(&x205, &x206, x3, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x207, &x208, x3, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x209, &x210, x3, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x211, &x212, x3, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x213, &x214, x3, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x215, &x216, x3, 0x3); + fiat_p256_addcarryx_u32(&x217, &x218, 0x0, x214, x211); + fiat_p256_addcarryx_u32(&x219, &x220, x218, x212, x209); + fiat_p256_addcarryx_u32(&x221, &x222, x220, x210, x207); + fiat_p256_addcarryx_u32(&x223, &x224, x222, x208, x205); + fiat_p256_addcarryx_u32(&x225, &x226, x224, x206, x203); + fiat_p256_addcarryx_u32(&x227, &x228, 0x0, x187, x215); + fiat_p256_addcarryx_u32(&x229, &x230, x228, x189, x216); + fiat_p256_addcarryx_u32(&x231, &x232, x230, x191, x213); + fiat_p256_addcarryx_u32(&x233, &x234, x232, x193, x217); + fiat_p256_addcarryx_u32(&x235, &x236, x234, x195, x219); + fiat_p256_addcarryx_u32(&x237, &x238, x236, x197, x221); + fiat_p256_addcarryx_u32(&x239, &x240, x238, x199, x223); + fiat_p256_addcarryx_u32(&x241, &x242, x240, x201, x225); + fiat_p256_mulx_u32(&x243, &x244, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x245, &x246, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x247, &x248, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x249, &x250, x227, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x251, &x252, 0x0, x250, x247); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x248, x245); + fiat_p256_addcarryx_u32(&x255, &x256, 0x0, x227, x249); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x229, x251); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x231, x253); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x233, (x254 + x246)); + fiat_p256_addcarryx_u32(&x263, &x264, x262, x235, 0x0); + fiat_p256_addcarryx_u32(&x265, &x266, x264, x237, 0x0); + fiat_p256_addcarryx_u32(&x267, &x268, x266, x239, x227); + fiat_p256_addcarryx_u32(&x269, &x270, x268, x241, x243); + fiat_p256_addcarryx_u32(&x271, &x272, x270, (((uint32_t)x242 + x202) + (x226 + x204)), x244); + fiat_p256_mulx_u32(&x273, &x274, x4, 0x4); + fiat_p256_mulx_u32(&x275, &x276, x4, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x277, &x278, x4, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x279, &x280, x4, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x281, &x282, x4, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x283, &x284, x4, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x285, &x286, x4, 0x3); + fiat_p256_addcarryx_u32(&x287, &x288, 0x0, x284, x281); + fiat_p256_addcarryx_u32(&x289, &x290, x288, x282, x279); + fiat_p256_addcarryx_u32(&x291, &x292, x290, x280, x277); + fiat_p256_addcarryx_u32(&x293, &x294, x292, x278, x275); + fiat_p256_addcarryx_u32(&x295, &x296, x294, x276, x273); + fiat_p256_addcarryx_u32(&x297, &x298, 0x0, x257, x285); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x259, x286); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x261, x283); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x263, x287); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x265, x289); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x267, x291); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x269, x293); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x271, x295); + fiat_p256_mulx_u32(&x313, &x314, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x315, &x316, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x317, &x318, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x319, &x320, x297, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x321, &x322, 0x0, x320, x317); + fiat_p256_addcarryx_u32(&x323, &x324, x322, x318, x315); + fiat_p256_addcarryx_u32(&x325, &x326, 0x0, x297, x319); + fiat_p256_addcarryx_u32(&x327, &x328, x326, x299, x321); + fiat_p256_addcarryx_u32(&x329, &x330, x328, x301, x323); + fiat_p256_addcarryx_u32(&x331, &x332, x330, x303, (x324 + x316)); + fiat_p256_addcarryx_u32(&x333, &x334, x332, x305, 0x0); + fiat_p256_addcarryx_u32(&x335, &x336, x334, x307, 0x0); + fiat_p256_addcarryx_u32(&x337, &x338, x336, x309, x297); + fiat_p256_addcarryx_u32(&x339, &x340, x338, x311, x313); + fiat_p256_addcarryx_u32(&x341, &x342, x340, (((uint32_t)x312 + x272) + (x296 + x274)), x314); + fiat_p256_mulx_u32(&x343, &x344, x5, 0x4); + fiat_p256_mulx_u32(&x345, &x346, x5, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x347, &x348, x5, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x349, &x350, x5, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x351, &x352, x5, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x353, &x354, x5, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x355, &x356, x5, 0x3); + fiat_p256_addcarryx_u32(&x357, &x358, 0x0, x354, x351); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x352, x349); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x350, x347); + fiat_p256_addcarryx_u32(&x363, &x364, x362, x348, x345); + fiat_p256_addcarryx_u32(&x365, &x366, x364, x346, x343); + fiat_p256_addcarryx_u32(&x367, &x368, 0x0, x327, x355); + fiat_p256_addcarryx_u32(&x369, &x370, x368, x329, x356); + fiat_p256_addcarryx_u32(&x371, &x372, x370, x331, x353); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x333, x357); + fiat_p256_addcarryx_u32(&x375, &x376, x374, x335, x359); + fiat_p256_addcarryx_u32(&x377, &x378, x376, x337, x361); + fiat_p256_addcarryx_u32(&x379, &x380, x378, x339, x363); + fiat_p256_addcarryx_u32(&x381, &x382, x380, x341, x365); + fiat_p256_mulx_u32(&x383, &x384, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x385, &x386, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x387, &x388, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x389, &x390, x367, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x391, &x392, 0x0, x390, x387); + fiat_p256_addcarryx_u32(&x393, &x394, x392, x388, x385); + fiat_p256_addcarryx_u32(&x395, &x396, 0x0, x367, x389); + fiat_p256_addcarryx_u32(&x397, &x398, x396, x369, x391); + fiat_p256_addcarryx_u32(&x399, &x400, x398, x371, x393); + fiat_p256_addcarryx_u32(&x401, &x402, x400, x373, (x394 + x386)); + fiat_p256_addcarryx_u32(&x403, &x404, x402, x375, 0x0); + fiat_p256_addcarryx_u32(&x405, &x406, x404, x377, 0x0); + fiat_p256_addcarryx_u32(&x407, &x408, x406, x379, x367); + fiat_p256_addcarryx_u32(&x409, &x410, x408, x381, x383); + fiat_p256_addcarryx_u32(&x411, &x412, x410, (((uint32_t)x382 + x342) + (x366 + x344)), x384); + fiat_p256_mulx_u32(&x413, &x414, x6, 0x4); + fiat_p256_mulx_u32(&x415, &x416, x6, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x417, &x418, x6, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x419, &x420, x6, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x421, &x422, x6, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x423, &x424, x6, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x425, &x426, x6, 0x3); + fiat_p256_addcarryx_u32(&x427, &x428, 0x0, x424, x421); + fiat_p256_addcarryx_u32(&x429, &x430, x428, x422, x419); + fiat_p256_addcarryx_u32(&x431, &x432, x430, x420, x417); + fiat_p256_addcarryx_u32(&x433, &x434, x432, x418, x415); + fiat_p256_addcarryx_u32(&x435, &x436, x434, x416, x413); + fiat_p256_addcarryx_u32(&x437, &x438, 0x0, x397, x425); + fiat_p256_addcarryx_u32(&x439, &x440, x438, x399, x426); + fiat_p256_addcarryx_u32(&x441, &x442, x440, x401, x423); + fiat_p256_addcarryx_u32(&x443, &x444, x442, x403, x427); + fiat_p256_addcarryx_u32(&x445, &x446, x444, x405, x429); + fiat_p256_addcarryx_u32(&x447, &x448, x446, x407, x431); + fiat_p256_addcarryx_u32(&x449, &x450, x448, x409, x433); + fiat_p256_addcarryx_u32(&x451, &x452, x450, x411, x435); + fiat_p256_mulx_u32(&x453, &x454, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x455, &x456, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x457, &x458, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x459, &x460, x437, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x461, &x462, 0x0, x460, x457); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x458, x455); + fiat_p256_addcarryx_u32(&x465, &x466, 0x0, x437, x459); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x439, x461); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x441, x463); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x443, (x464 + x456)); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x445, 0x0); + fiat_p256_addcarryx_u32(&x475, &x476, x474, x447, 0x0); + fiat_p256_addcarryx_u32(&x477, &x478, x476, x449, x437); + fiat_p256_addcarryx_u32(&x479, &x480, x478, x451, x453); + fiat_p256_addcarryx_u32(&x481, &x482, x480, (((uint32_t)x452 + x412) + (x436 + x414)), x454); + fiat_p256_mulx_u32(&x483, &x484, x7, 0x4); + fiat_p256_mulx_u32(&x485, &x486, x7, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x487, &x488, x7, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x489, &x490, x7, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x491, &x492, x7, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x493, &x494, x7, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x495, &x496, x7, 0x3); + fiat_p256_addcarryx_u32(&x497, &x498, 0x0, x494, x491); + fiat_p256_addcarryx_u32(&x499, &x500, x498, x492, x489); + fiat_p256_addcarryx_u32(&x501, &x502, x500, x490, x487); + fiat_p256_addcarryx_u32(&x503, &x504, x502, x488, x485); + fiat_p256_addcarryx_u32(&x505, &x506, x504, x486, x483); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x467, x495); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x469, x496); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x471, x493); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x473, x497); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x475, x499); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x477, x501); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x479, x503); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x481, x505); + fiat_p256_mulx_u32(&x523, &x524, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x531, &x532, 0x0, x530, x527); + fiat_p256_addcarryx_u32(&x533, &x534, x532, x528, x525); + fiat_p256_addcarryx_u32(&x535, &x536, 0x0, x507, x529); + fiat_p256_addcarryx_u32(&x537, &x538, x536, x509, x531); + fiat_p256_addcarryx_u32(&x539, &x540, x538, x511, x533); + fiat_p256_addcarryx_u32(&x541, &x542, x540, x513, (x534 + x526)); + fiat_p256_addcarryx_u32(&x543, &x544, x542, x515, 0x0); + fiat_p256_addcarryx_u32(&x545, &x546, x544, x517, 0x0); + fiat_p256_addcarryx_u32(&x547, &x548, x546, x519, x507); + fiat_p256_addcarryx_u32(&x549, &x550, x548, x521, x523); + fiat_p256_addcarryx_u32(&x551, &x552, x550, (((uint32_t)x522 + x482) + (x506 + x484)), x524); + fiat_p256_subborrowx_u32(&x553, &x554, 0x0, x537, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x555, &x556, x554, x539, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x557, &x558, x556, x541, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x559, &x560, x558, x543, 0x0); + fiat_p256_subborrowx_u32(&x561, &x562, x560, x545, 0x0); + fiat_p256_subborrowx_u32(&x563, &x564, x562, x547, 0x0); + fiat_p256_subborrowx_u32(&x565, &x566, x564, x549, 0x1); + fiat_p256_subborrowx_u32(&x567, &x568, x566, x551, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x569, &x570, x568, x552, 0x0); + fiat_p256_cmovznz_u32(&x571, x570, x553, x537); + fiat_p256_cmovznz_u32(&x572, x570, x555, x539); + fiat_p256_cmovznz_u32(&x573, x570, x557, x541); + fiat_p256_cmovznz_u32(&x574, x570, x559, x543); + fiat_p256_cmovznz_u32(&x575, x570, x561, x545); + fiat_p256_cmovznz_u32(&x576, x570, x563, x547); + fiat_p256_cmovznz_u32(&x577, x570, x565, x549); + fiat_p256_cmovznz_u32(&x578, x570, x567, x551); + out1[0] = x571; + out1[1] = x572; + out1[2] = x573; + out1[3] = x574; + out1[4] = x575; + out1[5] = x576; + out1[6] = x577; + out1[7] = x578; +} + +/* + * The function fiat_p256_nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_nonzero(uint32_t* out1, const uint32_t arg1[8]) { + uint32_t x1; + x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | ((arg1[5]) | ((arg1[6]) | (arg1[7])))))))); + *out1 = x1; +} + +/* + * The function fiat_p256_selectznz is a multi-limb conditional select. + * + * Postconditions: + * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const uint32_t arg2[8], const uint32_t arg3[8]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + fiat_p256_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); + fiat_p256_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); + fiat_p256_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); + fiat_p256_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; +} + +/* + * The function fiat_p256_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_bytes(uint8_t out1[32], const uint32_t arg1[8]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint8_t x9; + uint32_t x10; + uint8_t x11; + uint32_t x12; + uint8_t x13; + uint8_t x14; + uint8_t x15; + uint32_t x16; + uint8_t x17; + uint32_t x18; + uint8_t x19; + uint8_t x20; + uint8_t x21; + uint32_t x22; + uint8_t x23; + uint32_t x24; + uint8_t x25; + uint8_t x26; + uint8_t x27; + uint32_t x28; + uint8_t x29; + uint32_t x30; + uint8_t x31; + uint8_t x32; + uint8_t x33; + uint32_t x34; + uint8_t x35; + uint32_t x36; + uint8_t x37; + uint8_t x38; + uint8_t x39; + uint32_t x40; + uint8_t x41; + uint32_t x42; + uint8_t x43; + uint8_t x44; + uint8_t x45; + uint32_t x46; + uint8_t x47; + uint32_t x48; + uint8_t x49; + uint8_t x50; + uint8_t x51; + uint32_t x52; + uint8_t x53; + uint32_t x54; + uint8_t x55; + uint8_t x56; + x1 = (arg1[7]); + x2 = (arg1[6]); + x3 = (arg1[5]); + x4 = (arg1[4]); + x5 = (arg1[3]); + x6 = (arg1[2]); + x7 = (arg1[1]); + x8 = (arg1[0]); + x9 = (uint8_t)(x8 & UINT8_C(0xff)); + x10 = (x8 >> 8); + x11 = (uint8_t)(x10 & UINT8_C(0xff)); + x12 = (x10 >> 8); + x13 = (uint8_t)(x12 & UINT8_C(0xff)); + x14 = (uint8_t)(x12 >> 8); + x15 = (uint8_t)(x7 & UINT8_C(0xff)); + x16 = (x7 >> 8); + x17 = (uint8_t)(x16 & UINT8_C(0xff)); + x18 = (x16 >> 8); + x19 = (uint8_t)(x18 & UINT8_C(0xff)); + x20 = (uint8_t)(x18 >> 8); + x21 = (uint8_t)(x6 & UINT8_C(0xff)); + x22 = (x6 >> 8); + x23 = (uint8_t)(x22 & UINT8_C(0xff)); + x24 = (x22 >> 8); + x25 = (uint8_t)(x24 & UINT8_C(0xff)); + x26 = (uint8_t)(x24 >> 8); + x27 = (uint8_t)(x5 & UINT8_C(0xff)); + x28 = (x5 >> 8); + x29 = (uint8_t)(x28 & UINT8_C(0xff)); + x30 = (x28 >> 8); + x31 = (uint8_t)(x30 & UINT8_C(0xff)); + x32 = (uint8_t)(x30 >> 8); + x33 = (uint8_t)(x4 & UINT8_C(0xff)); + x34 = (x4 >> 8); + x35 = (uint8_t)(x34 & UINT8_C(0xff)); + x36 = (x34 >> 8); + x37 = (uint8_t)(x36 & UINT8_C(0xff)); + x38 = (uint8_t)(x36 >> 8); + x39 = (uint8_t)(x3 & UINT8_C(0xff)); + x40 = (x3 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (uint8_t)(x42 >> 8); + x45 = (uint8_t)(x2 & UINT8_C(0xff)); + x46 = (x2 >> 8); + x47 = (uint8_t)(x46 & UINT8_C(0xff)); + x48 = (x46 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (uint8_t)(x48 >> 8); + x51 = (uint8_t)(x1 & UINT8_C(0xff)); + x52 = (x1 >> 8); + x53 = (uint8_t)(x52 & UINT8_C(0xff)); + x54 = (x52 >> 8); + x55 = (uint8_t)(x54 & UINT8_C(0xff)); + x56 = (uint8_t)(x54 >> 8); + out1[0] = x9; + out1[1] = x11; + out1[2] = x13; + out1[3] = x14; + out1[4] = x15; + out1[5] = x17; + out1[6] = x19; + out1[7] = x20; + out1[8] = x21; + out1[9] = x23; + out1[10] = x25; + out1[11] = x26; + out1[12] = x27; + out1[13] = x29; + out1[14] = x31; + out1[15] = x32; + out1[16] = x33; + out1[17] = x35; + out1[18] = x37; + out1[19] = x38; + out1[20] = x39; + out1[21] = x41; + out1[22] = x43; + out1[23] = x44; + out1[24] = x45; + out1[25] = x47; + out1[26] = x49; + out1[27] = x50; + out1[28] = x51; + out1[29] = x53; + out1[30] = x55; + out1[31] = x56; +} + +/* + * The function fiat_p256_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. + * + * Preconditions: + * 0 ≤ bytes_eval arg1 < m + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * 0 ≤ eval out1 < m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_bytes(uint32_t out1[8], const uint8_t arg1[32]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint8_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint8_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint8_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint8_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint8_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint8_t x24; + uint32_t x25; + uint32_t x26; + uint32_t x27; + uint8_t x28; + uint32_t x29; + uint32_t x30; + uint32_t x31; + uint8_t x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + uint32_t x52; + uint32_t x53; + uint32_t x54; + uint32_t x55; + uint32_t x56; + x1 = ((uint32_t)(arg1[31]) << 24); + x2 = ((uint32_t)(arg1[30]) << 16); + x3 = ((uint32_t)(arg1[29]) << 8); + x4 = (arg1[28]); + x5 = ((uint32_t)(arg1[27]) << 24); + x6 = ((uint32_t)(arg1[26]) << 16); + x7 = ((uint32_t)(arg1[25]) << 8); + x8 = (arg1[24]); + x9 = ((uint32_t)(arg1[23]) << 24); + x10 = ((uint32_t)(arg1[22]) << 16); + x11 = ((uint32_t)(arg1[21]) << 8); + x12 = (arg1[20]); + x13 = ((uint32_t)(arg1[19]) << 24); + x14 = ((uint32_t)(arg1[18]) << 16); + x15 = ((uint32_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint32_t)(arg1[15]) << 24); + x18 = ((uint32_t)(arg1[14]) << 16); + x19 = ((uint32_t)(arg1[13]) << 8); + x20 = (arg1[12]); + x21 = ((uint32_t)(arg1[11]) << 24); + x22 = ((uint32_t)(arg1[10]) << 16); + x23 = ((uint32_t)(arg1[9]) << 8); + x24 = (arg1[8]); + x25 = ((uint32_t)(arg1[7]) << 24); + x26 = ((uint32_t)(arg1[6]) << 16); + x27 = ((uint32_t)(arg1[5]) << 8); + x28 = (arg1[4]); + x29 = ((uint32_t)(arg1[3]) << 24); + x30 = ((uint32_t)(arg1[2]) << 16); + x31 = ((uint32_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint32_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x27 + (uint32_t)x28); + x37 = (x26 + x36); + x38 = (x25 + x37); + x39 = (x23 + (uint32_t)x24); + x40 = (x22 + x39); + x41 = (x21 + x40); + x42 = (x19 + (uint32_t)x20); + x43 = (x18 + x42); + x44 = (x17 + x43); + x45 = (x15 + (uint32_t)x16); + x46 = (x14 + x45); + x47 = (x13 + x46); + x48 = (x11 + (uint32_t)x12); + x49 = (x10 + x48); + x50 = (x9 + x49); + x51 = (x7 + (uint32_t)x8); + x52 = (x6 + x51); + x53 = (x5 + x52); + x54 = (x3 + (uint32_t)x4); + x55 = (x2 + x54); + x56 = (x1 + x55); + out1[0] = x35; + out1[1] = x38; + out1[2] = x41; + out1[3] = x44; + out1[4] = x47; + out1[5] = x50; + out1[6] = x53; + out1[7] = x56; +} + +/* + * The function fiat_p256_set_one returns the field element one in the Montgomery domain. + * + * Postconditions: + * eval (from_montgomery out1) mod m = 1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_set_one(fiat_p256_montgomery_domain_field_element out1) { + out1[0] = 0x1; + out1[1] = 0x0; + out1[2] = 0x0; + out1[3] = UINT32_C(0xffffffff); + out1[4] = UINT32_C(0xffffffff); + out1[5] = UINT32_C(0xffffffff); + out1[6] = UINT32_C(0xfffffffe); + out1[7] = 0x0; +} + +/* + * The function fiat_p256_msat returns the saturated representation of the prime modulus. + * + * Postconditions: + * twos_complement_eval out1 = m + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_msat(uint32_t out1[9]) { + out1[0] = UINT32_C(0xffffffff); + out1[1] = UINT32_C(0xffffffff); + out1[2] = UINT32_C(0xffffffff); + out1[3] = 0x0; + out1[4] = 0x0; + out1[5] = 0x0; + out1[6] = 0x1; + out1[7] = UINT32_C(0xffffffff); + out1[8] = 0x0; +} + +/* + * The function fiat_p256_divstep computes a divstep. + * + * Preconditions: + * 0 ≤ eval arg4 < m + * 0 ≤ eval arg5 < m + * Postconditions: + * out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) + * twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) + * twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) + * eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) + * eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) + * 0 ≤ eval out5 < m + * 0 ≤ eval out5 < m + * 0 ≤ eval out2 < m + * 0 ≤ eval out3 < m + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffff] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg4: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg5: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out4: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out5: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep(uint32_t* out1, uint32_t out2[9], uint32_t out3[9], uint32_t out4[8], uint32_t out5[8], uint32_t arg1, const uint32_t arg2[9], const uint32_t arg3[9], const uint32_t arg4[8], const uint32_t arg5[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_uint1 x3; + uint32_t x4; + fiat_p256_uint1 x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + fiat_p256_uint1 x17; + uint32_t x18; + fiat_p256_uint1 x19; + uint32_t x20; + fiat_p256_uint1 x21; + uint32_t x22; + fiat_p256_uint1 x23; + uint32_t x24; + fiat_p256_uint1 x25; + uint32_t x26; + fiat_p256_uint1 x27; + uint32_t x28; + fiat_p256_uint1 x29; + uint32_t x30; + fiat_p256_uint1 x31; + uint32_t x32; + fiat_p256_uint1 x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + fiat_p256_uint1 x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + fiat_p256_uint1 x64; + uint32_t x65; + fiat_p256_uint1 x66; + uint32_t x67; + fiat_p256_uint1 x68; + uint32_t x69; + fiat_p256_uint1 x70; + uint32_t x71; + fiat_p256_uint1 x72; + uint32_t x73; + fiat_p256_uint1 x74; + uint32_t x75; + fiat_p256_uint1 x76; + uint32_t x77; + fiat_p256_uint1 x78; + uint32_t x79; + fiat_p256_uint1 x80; + uint32_t x81; + fiat_p256_uint1 x82; + uint32_t x83; + fiat_p256_uint1 x84; + uint32_t x85; + uint32_t x86; + uint32_t x87; + uint32_t x88; + uint32_t x89; + uint32_t x90; + uint32_t x91; + uint32_t x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + fiat_p256_uint1 x102; + uint32_t x103; + fiat_p256_uint1 x104; + uint32_t x105; + fiat_p256_uint1 x106; + uint32_t x107; + fiat_p256_uint1 x108; + uint32_t x109; + uint32_t x110; + fiat_p256_uint1 x111; + uint32_t x112; + fiat_p256_uint1 x113; + uint32_t x114; + fiat_p256_uint1 x115; + uint32_t x116; + fiat_p256_uint1 x117; + uint32_t x118; + fiat_p256_uint1 x119; + uint32_t x120; + fiat_p256_uint1 x121; + uint32_t x122; + fiat_p256_uint1 x123; + uint32_t x124; + fiat_p256_uint1 x125; + uint32_t x126; + uint32_t x127; + uint32_t x128; + uint32_t x129; + uint32_t x130; + uint32_t x131; + uint32_t x132; + uint32_t x133; + fiat_p256_uint1 x134; + uint32_t x135; + uint32_t x136; + uint32_t x137; + uint32_t x138; + uint32_t x139; + uint32_t x140; + uint32_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + fiat_p256_uint1 x145; + uint32_t x146; + fiat_p256_uint1 x147; + uint32_t x148; + fiat_p256_uint1 x149; + uint32_t x150; + fiat_p256_uint1 x151; + uint32_t x152; + fiat_p256_uint1 x153; + uint32_t x154; + fiat_p256_uint1 x155; + uint32_t x156; + fiat_p256_uint1 x157; + uint32_t x158; + fiat_p256_uint1 x159; + uint32_t x160; + fiat_p256_uint1 x161; + uint32_t x162; + uint32_t x163; + uint32_t x164; + uint32_t x165; + uint32_t x166; + uint32_t x167; + uint32_t x168; + uint32_t x169; + uint32_t x170; + fiat_p256_uint1 x171; + uint32_t x172; + fiat_p256_uint1 x173; + uint32_t x174; + fiat_p256_uint1 x175; + uint32_t x176; + fiat_p256_uint1 x177; + uint32_t x178; + fiat_p256_uint1 x179; + uint32_t x180; + fiat_p256_uint1 x181; + uint32_t x182; + fiat_p256_uint1 x183; + uint32_t x184; + fiat_p256_uint1 x185; + uint32_t x186; + fiat_p256_uint1 x187; + uint32_t x188; + fiat_p256_uint1 x189; + uint32_t x190; + fiat_p256_uint1 x191; + uint32_t x192; + fiat_p256_uint1 x193; + uint32_t x194; + fiat_p256_uint1 x195; + uint32_t x196; + fiat_p256_uint1 x197; + uint32_t x198; + fiat_p256_uint1 x199; + uint32_t x200; + fiat_p256_uint1 x201; + uint32_t x202; + fiat_p256_uint1 x203; + uint32_t x204; + fiat_p256_uint1 x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + uint32_t x210; + uint32_t x211; + uint32_t x212; + uint32_t x213; + uint32_t x214; + uint32_t x215; + uint32_t x216; + uint32_t x217; + uint32_t x218; + uint32_t x219; + uint32_t x220; + uint32_t x221; + uint32_t x222; + uint32_t x223; + uint32_t x224; + uint32_t x225; + uint32_t x226; + uint32_t x227; + uint32_t x228; + uint32_t x229; + uint32_t x230; + fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (~arg1), 0x1); + x3 = (fiat_p256_uint1)((fiat_p256_uint1)(x1 >> 31) & (fiat_p256_uint1)((arg3[0]) & 0x1)); + fiat_p256_addcarryx_u32(&x4, &x5, 0x0, (~arg1), 0x1); + fiat_p256_cmovznz_u32(&x6, x3, arg1, x4); + fiat_p256_cmovznz_u32(&x7, x3, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u32(&x8, x3, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u32(&x9, x3, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u32(&x10, x3, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u32(&x11, x3, (arg2[4]), (arg3[4])); + fiat_p256_cmovznz_u32(&x12, x3, (arg2[5]), (arg3[5])); + fiat_p256_cmovznz_u32(&x13, x3, (arg2[6]), (arg3[6])); + fiat_p256_cmovznz_u32(&x14, x3, (arg2[7]), (arg3[7])); + fiat_p256_cmovznz_u32(&x15, x3, (arg2[8]), (arg3[8])); + fiat_p256_addcarryx_u32(&x16, &x17, 0x0, 0x1, (~(arg2[0]))); + fiat_p256_addcarryx_u32(&x18, &x19, x17, 0x0, (~(arg2[1]))); + fiat_p256_addcarryx_u32(&x20, &x21, x19, 0x0, (~(arg2[2]))); + fiat_p256_addcarryx_u32(&x22, &x23, x21, 0x0, (~(arg2[3]))); + fiat_p256_addcarryx_u32(&x24, &x25, x23, 0x0, (~(arg2[4]))); + fiat_p256_addcarryx_u32(&x26, &x27, x25, 0x0, (~(arg2[5]))); + fiat_p256_addcarryx_u32(&x28, &x29, x27, 0x0, (~(arg2[6]))); + fiat_p256_addcarryx_u32(&x30, &x31, x29, 0x0, (~(arg2[7]))); + fiat_p256_addcarryx_u32(&x32, &x33, x31, 0x0, (~(arg2[8]))); + fiat_p256_cmovznz_u32(&x34, x3, (arg3[0]), x16); + fiat_p256_cmovznz_u32(&x35, x3, (arg3[1]), x18); + fiat_p256_cmovznz_u32(&x36, x3, (arg3[2]), x20); + fiat_p256_cmovznz_u32(&x37, x3, (arg3[3]), x22); + fiat_p256_cmovznz_u32(&x38, x3, (arg3[4]), x24); + fiat_p256_cmovznz_u32(&x39, x3, (arg3[5]), x26); + fiat_p256_cmovznz_u32(&x40, x3, (arg3[6]), x28); + fiat_p256_cmovznz_u32(&x41, x3, (arg3[7]), x30); + fiat_p256_cmovznz_u32(&x42, x3, (arg3[8]), x32); + fiat_p256_cmovznz_u32(&x43, x3, (arg4[0]), (arg5[0])); + fiat_p256_cmovznz_u32(&x44, x3, (arg4[1]), (arg5[1])); + fiat_p256_cmovznz_u32(&x45, x3, (arg4[2]), (arg5[2])); + fiat_p256_cmovznz_u32(&x46, x3, (arg4[3]), (arg5[3])); + fiat_p256_cmovznz_u32(&x47, x3, (arg4[4]), (arg5[4])); + fiat_p256_cmovznz_u32(&x48, x3, (arg4[5]), (arg5[5])); + fiat_p256_cmovznz_u32(&x49, x3, (arg4[6]), (arg5[6])); + fiat_p256_cmovznz_u32(&x50, x3, (arg4[7]), (arg5[7])); + fiat_p256_addcarryx_u32(&x51, &x52, 0x0, x43, x43); + fiat_p256_addcarryx_u32(&x53, &x54, x52, x44, x44); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x45, x45); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x46, x46); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x47, x47); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x48, x48); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x49, x49); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x50, x50); + fiat_p256_subborrowx_u32(&x67, &x68, 0x0, x51, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x69, &x70, x68, x53, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x71, &x72, x70, x55, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x73, &x74, x72, x57, 0x0); + fiat_p256_subborrowx_u32(&x75, &x76, x74, x59, 0x0); + fiat_p256_subborrowx_u32(&x77, &x78, x76, x61, 0x0); + fiat_p256_subborrowx_u32(&x79, &x80, x78, x63, 0x1); + fiat_p256_subborrowx_u32(&x81, &x82, x80, x65, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x83, &x84, x82, x66, 0x0); + x85 = (arg4[7]); + x86 = (arg4[6]); + x87 = (arg4[5]); + x88 = (arg4[4]); + x89 = (arg4[3]); + x90 = (arg4[2]); + x91 = (arg4[1]); + x92 = (arg4[0]); + fiat_p256_subborrowx_u32(&x93, &x94, 0x0, 0x0, x92); + fiat_p256_subborrowx_u32(&x95, &x96, x94, 0x0, x91); + fiat_p256_subborrowx_u32(&x97, &x98, x96, 0x0, x90); + fiat_p256_subborrowx_u32(&x99, &x100, x98, 0x0, x89); + fiat_p256_subborrowx_u32(&x101, &x102, x100, 0x0, x88); + fiat_p256_subborrowx_u32(&x103, &x104, x102, 0x0, x87); + fiat_p256_subborrowx_u32(&x105, &x106, x104, 0x0, x86); + fiat_p256_subborrowx_u32(&x107, &x108, x106, 0x0, x85); + fiat_p256_cmovznz_u32(&x109, x108, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x93, x109); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x95, x109); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x97, x109); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x99, 0x0); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x101, 0x0); + fiat_p256_addcarryx_u32(&x120, &x121, x119, x103, 0x0); + fiat_p256_addcarryx_u32(&x122, &x123, x121, x105, (fiat_p256_uint1)(x109 & 0x1)); + fiat_p256_addcarryx_u32(&x124, &x125, x123, x107, x109); + fiat_p256_cmovznz_u32(&x126, x3, (arg5[0]), x110); + fiat_p256_cmovznz_u32(&x127, x3, (arg5[1]), x112); + fiat_p256_cmovznz_u32(&x128, x3, (arg5[2]), x114); + fiat_p256_cmovznz_u32(&x129, x3, (arg5[3]), x116); + fiat_p256_cmovznz_u32(&x130, x3, (arg5[4]), x118); + fiat_p256_cmovznz_u32(&x131, x3, (arg5[5]), x120); + fiat_p256_cmovznz_u32(&x132, x3, (arg5[6]), x122); + fiat_p256_cmovznz_u32(&x133, x3, (arg5[7]), x124); + x134 = (fiat_p256_uint1)(x34 & 0x1); + fiat_p256_cmovznz_u32(&x135, x134, 0x0, x7); + fiat_p256_cmovznz_u32(&x136, x134, 0x0, x8); + fiat_p256_cmovznz_u32(&x137, x134, 0x0, x9); + fiat_p256_cmovznz_u32(&x138, x134, 0x0, x10); + fiat_p256_cmovznz_u32(&x139, x134, 0x0, x11); + fiat_p256_cmovznz_u32(&x140, x134, 0x0, x12); + fiat_p256_cmovznz_u32(&x141, x134, 0x0, x13); + fiat_p256_cmovznz_u32(&x142, x134, 0x0, x14); + fiat_p256_cmovznz_u32(&x143, x134, 0x0, x15); + fiat_p256_addcarryx_u32(&x144, &x145, 0x0, x34, x135); + fiat_p256_addcarryx_u32(&x146, &x147, x145, x35, x136); + fiat_p256_addcarryx_u32(&x148, &x149, x147, x36, x137); + fiat_p256_addcarryx_u32(&x150, &x151, x149, x37, x138); + fiat_p256_addcarryx_u32(&x152, &x153, x151, x38, x139); + fiat_p256_addcarryx_u32(&x154, &x155, x153, x39, x140); + fiat_p256_addcarryx_u32(&x156, &x157, x155, x40, x141); + fiat_p256_addcarryx_u32(&x158, &x159, x157, x41, x142); + fiat_p256_addcarryx_u32(&x160, &x161, x159, x42, x143); + fiat_p256_cmovznz_u32(&x162, x134, 0x0, x43); + fiat_p256_cmovznz_u32(&x163, x134, 0x0, x44); + fiat_p256_cmovznz_u32(&x164, x134, 0x0, x45); + fiat_p256_cmovznz_u32(&x165, x134, 0x0, x46); + fiat_p256_cmovznz_u32(&x166, x134, 0x0, x47); + fiat_p256_cmovznz_u32(&x167, x134, 0x0, x48); + fiat_p256_cmovznz_u32(&x168, x134, 0x0, x49); + fiat_p256_cmovznz_u32(&x169, x134, 0x0, x50); + fiat_p256_addcarryx_u32(&x170, &x171, 0x0, x126, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x127, x163); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x128, x164); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x129, x165); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x130, x166); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x131, x167); + fiat_p256_addcarryx_u32(&x182, &x183, x181, x132, x168); + fiat_p256_addcarryx_u32(&x184, &x185, x183, x133, x169); + fiat_p256_subborrowx_u32(&x186, &x187, 0x0, x170, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x188, &x189, x187, x172, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x190, &x191, x189, x174, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x192, &x193, x191, x176, 0x0); + fiat_p256_subborrowx_u32(&x194, &x195, x193, x178, 0x0); + fiat_p256_subborrowx_u32(&x196, &x197, x195, x180, 0x0); + fiat_p256_subborrowx_u32(&x198, &x199, x197, x182, 0x1); + fiat_p256_subborrowx_u32(&x200, &x201, x199, x184, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x202, &x203, x201, x185, 0x0); + fiat_p256_addcarryx_u32(&x204, &x205, 0x0, x6, 0x1); + x206 = ((x144 >> 1) | ((x146 << 31) & UINT32_C(0xffffffff))); + x207 = ((x146 >> 1) | ((x148 << 31) & UINT32_C(0xffffffff))); + x208 = ((x148 >> 1) | ((x150 << 31) & UINT32_C(0xffffffff))); + x209 = ((x150 >> 1) | ((x152 << 31) & UINT32_C(0xffffffff))); + x210 = ((x152 >> 1) | ((x154 << 31) & UINT32_C(0xffffffff))); + x211 = ((x154 >> 1) | ((x156 << 31) & UINT32_C(0xffffffff))); + x212 = ((x156 >> 1) | ((x158 << 31) & UINT32_C(0xffffffff))); + x213 = ((x158 >> 1) | ((x160 << 31) & UINT32_C(0xffffffff))); + x214 = ((x160 & UINT32_C(0x80000000)) | (x160 >> 1)); + fiat_p256_cmovznz_u32(&x215, x84, x67, x51); + fiat_p256_cmovznz_u32(&x216, x84, x69, x53); + fiat_p256_cmovznz_u32(&x217, x84, x71, x55); + fiat_p256_cmovznz_u32(&x218, x84, x73, x57); + fiat_p256_cmovznz_u32(&x219, x84, x75, x59); + fiat_p256_cmovznz_u32(&x220, x84, x77, x61); + fiat_p256_cmovznz_u32(&x221, x84, x79, x63); + fiat_p256_cmovznz_u32(&x222, x84, x81, x65); + fiat_p256_cmovznz_u32(&x223, x203, x186, x170); + fiat_p256_cmovznz_u32(&x224, x203, x188, x172); + fiat_p256_cmovznz_u32(&x225, x203, x190, x174); + fiat_p256_cmovznz_u32(&x226, x203, x192, x176); + fiat_p256_cmovznz_u32(&x227, x203, x194, x178); + fiat_p256_cmovznz_u32(&x228, x203, x196, x180); + fiat_p256_cmovznz_u32(&x229, x203, x198, x182); + fiat_p256_cmovznz_u32(&x230, x203, x200, x184); + *out1 = x204; + out2[0] = x7; + out2[1] = x8; + out2[2] = x9; + out2[3] = x10; + out2[4] = x11; + out2[5] = x12; + out2[6] = x13; + out2[7] = x14; + out2[8] = x15; + out3[0] = x206; + out3[1] = x207; + out3[2] = x208; + out3[3] = x209; + out3[4] = x210; + out3[5] = x211; + out3[6] = x212; + out3[7] = x213; + out3[8] = x214; + out4[0] = x215; + out4[1] = x216; + out4[2] = x217; + out4[3] = x218; + out4[4] = x219; + out4[5] = x220; + out4[6] = x221; + out4[7] = x222; + out5[0] = x223; + out5[1] = x224; + out5[2] = x225; + out5[3] = x226; + out5[4] = x227; + out5[5] = x228; + out5[6] = x229; + out5[7] = x230; +} + +/* + * The function fiat_p256_divstep_precomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). + * + * Postconditions: + * eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep_precomp(uint32_t out1[8]) { + out1[0] = UINT32_C(0xb8000000); + out1[1] = UINT32_C(0x67ffffff); + out1[2] = UINT32_C(0x38000000); + out1[3] = UINT32_C(0xc0000000); + out1[4] = UINT32_C(0x7fffffff); + out1[5] = UINT32_C(0xd8000000); + out1[6] = UINT32_C(0xffffffff); + out1[7] = UINT32_C(0x2fffffff); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_64.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_64.h new file mode 100644 index 00000000..c7726384 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSL/Sources/CNIOBoringSSL/third_party/fiat/p256_64.h @@ -0,0 +1,2011 @@ +/* Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --inline --static --use-value-barrier p256 64 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp */ +/* curve description: p256 */ +/* machine_wordsize = 64 (from "64") */ +/* requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp */ +/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ +/* */ +/* NOTE: In addition to the bounds specified above each function, all */ +/* functions synthesized for this Montgomery arithmetic require the */ +/* input to be strictly less than the prime modulus (m), and also */ +/* require the input to be in the unique saturated representation. */ +/* All functions also ensure that these two properties are true of */ +/* return values. */ +/* */ +/* Computed values: */ +/* eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in */ +/* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ + +#include +typedef unsigned char fiat_p256_uint1; +typedef signed char fiat_p256_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_P256_FIAT_EXTENSION __extension__ +# define FIAT_P256_FIAT_INLINE __inline__ +#else +# define FIAT_P256_FIAT_EXTENSION +# define FIAT_P256_FIAT_INLINE +#endif + +FIAT_P256_FIAT_EXTENSION typedef signed __int128 fiat_p256_int128; +FIAT_P256_FIAT_EXTENSION typedef unsigned __int128 fiat_p256_uint128; + +/* The type fiat_p256_montgomery_domain_field_element is a field element in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_montgomery_domain_field_element[4]; + +/* The type fiat_p256_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_non_montgomery_domain_field_element[4]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#if !defined(FIAT_P256_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint64_t fiat_p256_value_barrier_u64(uint64_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_p256_value_barrier_u64(x) (x) +#endif + + +/* + * The function fiat_p256_addcarryx_u64 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^64 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint128 x1; + uint64_t x2; + fiat_p256_uint1 x3; + x1 = ((arg1 + (fiat_p256_uint128)arg2) + arg3); + x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + x3 = (fiat_p256_uint1)(x1 >> 64); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_p256_subborrowx_u64 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^64 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_int128 x1; + fiat_p256_int1 x2; + uint64_t x3; + x1 = ((arg2 - (fiat_p256_int128)arg1) - arg3); + x2 = (fiat_p256_int1)(x1 >> 64); + x3 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + *out1 = x3; + *out2 = (fiat_p256_uint1)(0x0 - x2); +} + +/* + * The function fiat_p256_mulx_u64 is a multiplication, returning the full double-width result. + * + * Postconditions: + * out1 = (arg1 * arg2) mod 2^64 + * out2 = ⌊arg1 * arg2 / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { + fiat_p256_uint128 x1; + uint64_t x2; + uint64_t x3; + x1 = ((fiat_p256_uint128)arg1 * arg2); + x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + x3 = (uint64_t)(x1 >> 64); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_p256_cmovznz_u64 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_p256_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_p256_value_barrier_u64(x2) & arg3) | (fiat_p256_value_barrier_u64((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_p256_mul multiplies two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + fiat_p256_uint1 x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + fiat_p256_uint1 x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + uint64_t x99; + fiat_p256_uint1 x100; + uint64_t x101; + fiat_p256_uint1 x102; + uint64_t x103; + fiat_p256_uint1 x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + fiat_p256_uint1 x119; + uint64_t x120; + fiat_p256_uint1 x121; + uint64_t x122; + fiat_p256_uint1 x123; + uint64_t x124; + fiat_p256_uint1 x125; + uint64_t x126; + fiat_p256_uint1 x127; + uint64_t x128; + uint64_t x129; + uint64_t x130; + uint64_t x131; + uint64_t x132; + uint64_t x133; + uint64_t x134; + uint64_t x135; + uint64_t x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + fiat_p256_uint1 x140; + uint64_t x141; + fiat_p256_uint1 x142; + uint64_t x143; + uint64_t x144; + fiat_p256_uint1 x145; + uint64_t x146; + fiat_p256_uint1 x147; + uint64_t x148; + fiat_p256_uint1 x149; + uint64_t x150; + fiat_p256_uint1 x151; + uint64_t x152; + fiat_p256_uint1 x153; + uint64_t x154; + uint64_t x155; + uint64_t x156; + uint64_t x157; + uint64_t x158; + uint64_t x159; + uint64_t x160; + fiat_p256_uint1 x161; + uint64_t x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + fiat_p256_uint1 x168; + uint64_t x169; + fiat_p256_uint1 x170; + uint64_t x171; + fiat_p256_uint1 x172; + uint64_t x173; + uint64_t x174; + fiat_p256_uint1 x175; + uint64_t x176; + fiat_p256_uint1 x177; + uint64_t x178; + fiat_p256_uint1 x179; + uint64_t x180; + fiat_p256_uint1 x181; + uint64_t x182; + fiat_p256_uint1 x183; + uint64_t x184; + uint64_t x185; + uint64_t x186; + uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg2[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg2[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg2[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg2[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg2[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg2[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg2[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg2[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg2[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg2[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg2[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg2[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg2[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg2[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg2[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg2[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); + fiat_p256_cmovznz_u64(&x187, x183, x180, x171); + out1[0] = x184; + out1[1] = x185; + out1[2] = x186; + out1[3] = x187; +} + +/* + * The function fiat_p256_square squares a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + fiat_p256_uint1 x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + fiat_p256_uint1 x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + uint64_t x99; + fiat_p256_uint1 x100; + uint64_t x101; + fiat_p256_uint1 x102; + uint64_t x103; + fiat_p256_uint1 x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + fiat_p256_uint1 x119; + uint64_t x120; + fiat_p256_uint1 x121; + uint64_t x122; + fiat_p256_uint1 x123; + uint64_t x124; + fiat_p256_uint1 x125; + uint64_t x126; + fiat_p256_uint1 x127; + uint64_t x128; + uint64_t x129; + uint64_t x130; + uint64_t x131; + uint64_t x132; + uint64_t x133; + uint64_t x134; + uint64_t x135; + uint64_t x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + fiat_p256_uint1 x140; + uint64_t x141; + fiat_p256_uint1 x142; + uint64_t x143; + uint64_t x144; + fiat_p256_uint1 x145; + uint64_t x146; + fiat_p256_uint1 x147; + uint64_t x148; + fiat_p256_uint1 x149; + uint64_t x150; + fiat_p256_uint1 x151; + uint64_t x152; + fiat_p256_uint1 x153; + uint64_t x154; + uint64_t x155; + uint64_t x156; + uint64_t x157; + uint64_t x158; + uint64_t x159; + uint64_t x160; + fiat_p256_uint1 x161; + uint64_t x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + fiat_p256_uint1 x168; + uint64_t x169; + fiat_p256_uint1 x170; + uint64_t x171; + fiat_p256_uint1 x172; + uint64_t x173; + uint64_t x174; + fiat_p256_uint1 x175; + uint64_t x176; + fiat_p256_uint1 x177; + uint64_t x178; + fiat_p256_uint1 x179; + uint64_t x180; + fiat_p256_uint1 x181; + uint64_t x182; + fiat_p256_uint1 x183; + uint64_t x184; + uint64_t x185; + uint64_t x186; + uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg1[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg1[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg1[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg1[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg1[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg1[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg1[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg1[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg1[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg1[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg1[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg1[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg1[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg1[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg1[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg1[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); + fiat_p256_cmovznz_u64(&x187, x183, x180, x171); + out1[0] = x184; + out1[1] = x185; + out1[2] = x186; + out1[3] = x187; +} + +/* + * The function fiat_p256_add adds two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + fiat_p256_uint1 x10; + uint64_t x11; + fiat_p256_uint1 x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); + fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); + fiat_p256_cmovznz_u64(&x19, x18, x9, x1); + fiat_p256_cmovznz_u64(&x20, x18, x11, x3); + fiat_p256_cmovznz_u64(&x21, x18, x13, x5); + fiat_p256_cmovznz_u64(&x22, x18, x15, x7); + out1[0] = x19; + out1[1] = x20; + out1[2] = x21; + out1[3] = x22; +} + +/* + * The function fiat_p256_sub subtracts two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); + fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * The function fiat_p256_opp negates a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_opp(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, 0x0, (arg1[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, 0x0, (arg1[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, 0x0, (arg1[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, 0x0, (arg1[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); + fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * The function fiat_p256_from_montgomery translates a field element out of the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_montgomery(fiat_p256_non_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + fiat_p256_uint1 x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + fiat_p256_uint1 x23; + uint64_t x24; + fiat_p256_uint1 x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + fiat_p256_uint1 x29; + uint64_t x30; + fiat_p256_uint1 x31; + uint64_t x32; + fiat_p256_uint1 x33; + uint64_t x34; + fiat_p256_uint1 x35; + uint64_t x36; + fiat_p256_uint1 x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + fiat_p256_uint1 x45; + uint64_t x46; + fiat_p256_uint1 x47; + uint64_t x48; + fiat_p256_uint1 x49; + uint64_t x50; + fiat_p256_uint1 x51; + uint64_t x52; + fiat_p256_uint1 x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + fiat_p256_uint1 x67; + uint64_t x68; + fiat_p256_uint1 x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + fiat_p256_uint1 x73; + uint64_t x74; + fiat_p256_uint1 x75; + uint64_t x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + fiat_p256_uint1 x84; + uint64_t x85; + fiat_p256_uint1 x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + x1 = (arg1[0]); + fiat_p256_mulx_u64(&x2, &x3, x1, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x4, &x5, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x6, &x7, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x8, &x9, 0x0, x7, x4); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x6); + fiat_p256_addcarryx_u64(&x12, &x13, x11, 0x0, x8); + fiat_p256_addcarryx_u64(&x14, &x15, 0x0, x12, (arg1[1])); + fiat_p256_mulx_u64(&x16, &x17, x14, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x18, &x19, x14, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x20, &x21, x14, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x22, &x23, 0x0, x21, x18); + fiat_p256_addcarryx_u64(&x24, &x25, 0x0, x14, x20); + fiat_p256_addcarryx_u64(&x26, &x27, x25, (x15 + (x13 + (x9 + x5))), x22); + fiat_p256_addcarryx_u64(&x28, &x29, x27, x2, (x23 + x19)); + fiat_p256_addcarryx_u64(&x30, &x31, x29, x3, x16); + fiat_p256_addcarryx_u64(&x32, &x33, 0x0, x26, (arg1[2])); + fiat_p256_addcarryx_u64(&x34, &x35, x33, x28, 0x0); + fiat_p256_addcarryx_u64(&x36, &x37, x35, x30, 0x0); + fiat_p256_mulx_u64(&x38, &x39, x32, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x40, &x41, x32, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x42, &x43, x32, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x44, &x45, 0x0, x43, x40); + fiat_p256_addcarryx_u64(&x46, &x47, 0x0, x32, x42); + fiat_p256_addcarryx_u64(&x48, &x49, x47, x34, x44); + fiat_p256_addcarryx_u64(&x50, &x51, x49, x36, (x45 + x41)); + fiat_p256_addcarryx_u64(&x52, &x53, x51, (x37 + (x31 + x17)), x38); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x48, (arg1[3])); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x50, 0x0); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x52, 0x0); + fiat_p256_mulx_u64(&x60, &x61, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x62, &x63, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x66, &x67, 0x0, x65, x62); + fiat_p256_addcarryx_u64(&x68, &x69, 0x0, x54, x64); + fiat_p256_addcarryx_u64(&x70, &x71, x69, x56, x66); + fiat_p256_addcarryx_u64(&x72, &x73, x71, x58, (x67 + x63)); + fiat_p256_addcarryx_u64(&x74, &x75, x73, (x59 + (x53 + x39)), x60); + x76 = (x75 + x61); + fiat_p256_subborrowx_u64(&x77, &x78, 0x0, x70, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x79, &x80, x78, x72, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x81, &x82, x80, x74, 0x0); + fiat_p256_subborrowx_u64(&x83, &x84, x82, x76, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x85, &x86, x84, 0x0, 0x0); + fiat_p256_cmovznz_u64(&x87, x86, x77, x70); + fiat_p256_cmovznz_u64(&x88, x86, x79, x72); + fiat_p256_cmovznz_u64(&x89, x86, x81, x74); + fiat_p256_cmovznz_u64(&x90, x86, x83, x76); + out1[0] = x87; + out1[1] = x88; + out1[2] = x89; + out1[3] = x90; +} + +/* + * The function fiat_p256_to_montgomery translates a field element into the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = eval arg1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_montgomery(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_non_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + fiat_p256_uint1 x26; + uint64_t x27; + fiat_p256_uint1 x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + fiat_p256_uint1 x66; + uint64_t x67; + fiat_p256_uint1 x68; + uint64_t x69; + fiat_p256_uint1 x70; + uint64_t x71; + fiat_p256_uint1 x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + fiat_p256_uint1 x86; + uint64_t x87; + fiat_p256_uint1 x88; + uint64_t x89; + fiat_p256_uint1 x90; + uint64_t x91; + fiat_p256_uint1 x92; + uint64_t x93; + fiat_p256_uint1 x94; + uint64_t x95; + fiat_p256_uint1 x96; + uint64_t x97; + fiat_p256_uint1 x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint64_t x103; + uint64_t x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + fiat_p256_uint1 x110; + uint64_t x111; + fiat_p256_uint1 x112; + uint64_t x113; + fiat_p256_uint1 x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + fiat_p256_uint1 x126; + uint64_t x127; + fiat_p256_uint1 x128; + uint64_t x129; + fiat_p256_uint1 x130; + uint64_t x131; + fiat_p256_uint1 x132; + uint64_t x133; + fiat_p256_uint1 x134; + uint64_t x135; + fiat_p256_uint1 x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + uint64_t x140; + uint64_t x141; + uint64_t x142; + uint64_t x143; + uint64_t x144; + uint64_t x145; + fiat_p256_uint1 x146; + uint64_t x147; + fiat_p256_uint1 x148; + uint64_t x149; + fiat_p256_uint1 x150; + uint64_t x151; + fiat_p256_uint1 x152; + uint64_t x153; + fiat_p256_uint1 x154; + uint64_t x155; + fiat_p256_uint1 x156; + uint64_t x157; + fiat_p256_uint1 x158; + uint64_t x159; + fiat_p256_uint1 x160; + uint64_t x161; + fiat_p256_uint1 x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + uint64_t x168; + uint64_t x169; + uint64_t x170; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x7, &x8, x4, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x9, &x10, x4, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x11, &x12, x4, 0x3); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + fiat_p256_mulx_u64(&x19, &x20, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x21, &x22, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x23, &x24, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u64(&x27, &x28, 0x0, x11, x23); + fiat_p256_addcarryx_u64(&x29, &x30, x28, x13, x25); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x15, (x26 + x22)); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x17, x19); + fiat_p256_addcarryx_u64(&x35, &x36, x34, (x18 + x6), x20); + fiat_p256_mulx_u64(&x37, &x38, x1, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x39, &x40, x1, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x41, &x42, x1, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x43, &x44, x1, 0x3); + fiat_p256_addcarryx_u64(&x45, &x46, 0x0, x44, x41); + fiat_p256_addcarryx_u64(&x47, &x48, x46, x42, x39); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x40, x37); + fiat_p256_addcarryx_u64(&x51, &x52, 0x0, x29, x43); + fiat_p256_addcarryx_u64(&x53, &x54, x52, x31, x45); + fiat_p256_addcarryx_u64(&x55, &x56, x54, x33, x47); + fiat_p256_addcarryx_u64(&x57, &x58, x56, x35, x49); + fiat_p256_mulx_u64(&x59, &x60, x51, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x61, &x62, x51, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x63, &x64, x51, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x65, &x66, 0x0, x64, x61); + fiat_p256_addcarryx_u64(&x67, &x68, 0x0, x51, x63); + fiat_p256_addcarryx_u64(&x69, &x70, x68, x53, x65); + fiat_p256_addcarryx_u64(&x71, &x72, x70, x55, (x66 + x62)); + fiat_p256_addcarryx_u64(&x73, &x74, x72, x57, x59); + fiat_p256_addcarryx_u64(&x75, &x76, x74, (((uint64_t)x58 + x36) + (x50 + x38)), x60); + fiat_p256_mulx_u64(&x77, &x78, x2, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x79, &x80, x2, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x81, &x82, x2, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x83, &x84, x2, 0x3); + fiat_p256_addcarryx_u64(&x85, &x86, 0x0, x84, x81); + fiat_p256_addcarryx_u64(&x87, &x88, x86, x82, x79); + fiat_p256_addcarryx_u64(&x89, &x90, x88, x80, x77); + fiat_p256_addcarryx_u64(&x91, &x92, 0x0, x69, x83); + fiat_p256_addcarryx_u64(&x93, &x94, x92, x71, x85); + fiat_p256_addcarryx_u64(&x95, &x96, x94, x73, x87); + fiat_p256_addcarryx_u64(&x97, &x98, x96, x75, x89); + fiat_p256_mulx_u64(&x99, &x100, x91, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x101, &x102, x91, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x103, &x104, x91, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x105, &x106, 0x0, x104, x101); + fiat_p256_addcarryx_u64(&x107, &x108, 0x0, x91, x103); + fiat_p256_addcarryx_u64(&x109, &x110, x108, x93, x105); + fiat_p256_addcarryx_u64(&x111, &x112, x110, x95, (x106 + x102)); + fiat_p256_addcarryx_u64(&x113, &x114, x112, x97, x99); + fiat_p256_addcarryx_u64(&x115, &x116, x114, (((uint64_t)x98 + x76) + (x90 + x78)), x100); + fiat_p256_mulx_u64(&x117, &x118, x3, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x119, &x120, x3, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x121, &x122, x3, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x123, &x124, x3, 0x3); + fiat_p256_addcarryx_u64(&x125, &x126, 0x0, x124, x121); + fiat_p256_addcarryx_u64(&x127, &x128, x126, x122, x119); + fiat_p256_addcarryx_u64(&x129, &x130, x128, x120, x117); + fiat_p256_addcarryx_u64(&x131, &x132, 0x0, x109, x123); + fiat_p256_addcarryx_u64(&x133, &x134, x132, x111, x125); + fiat_p256_addcarryx_u64(&x135, &x136, x134, x113, x127); + fiat_p256_addcarryx_u64(&x137, &x138, x136, x115, x129); + fiat_p256_mulx_u64(&x139, &x140, x131, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x141, &x142, x131, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x143, &x144, x131, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x145, &x146, 0x0, x144, x141); + fiat_p256_addcarryx_u64(&x147, &x148, 0x0, x131, x143); + fiat_p256_addcarryx_u64(&x149, &x150, x148, x133, x145); + fiat_p256_addcarryx_u64(&x151, &x152, x150, x135, (x146 + x142)); + fiat_p256_addcarryx_u64(&x153, &x154, x152, x137, x139); + fiat_p256_addcarryx_u64(&x155, &x156, x154, (((uint64_t)x138 + x116) + (x130 + x118)), x140); + fiat_p256_subborrowx_u64(&x157, &x158, 0x0, x149, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x159, &x160, x158, x151, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x161, &x162, x160, x153, 0x0); + fiat_p256_subborrowx_u64(&x163, &x164, x162, x155, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x165, &x166, x164, x156, 0x0); + fiat_p256_cmovznz_u64(&x167, x166, x157, x149); + fiat_p256_cmovznz_u64(&x168, x166, x159, x151); + fiat_p256_cmovznz_u64(&x169, x166, x161, x153); + fiat_p256_cmovznz_u64(&x170, x166, x163, x155); + out1[0] = x167; + out1[1] = x168; + out1[2] = x169; + out1[3] = x170; +} + +/* + * The function fiat_p256_nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { + uint64_t x1; + x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); + *out1 = x1; +} + +/* + * The function fiat_p256_selectznz is a multi-limb conditional select. + * + * Postconditions: + * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + fiat_p256_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; +} + +/* + * The function fiat_p256_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint8_t x5; + uint64_t x6; + uint8_t x7; + uint64_t x8; + uint8_t x9; + uint64_t x10; + uint8_t x11; + uint64_t x12; + uint8_t x13; + uint64_t x14; + uint8_t x15; + uint64_t x16; + uint8_t x17; + uint8_t x18; + uint8_t x19; + uint64_t x20; + uint8_t x21; + uint64_t x22; + uint8_t x23; + uint64_t x24; + uint8_t x25; + uint64_t x26; + uint8_t x27; + uint64_t x28; + uint8_t x29; + uint64_t x30; + uint8_t x31; + uint8_t x32; + uint8_t x33; + uint64_t x34; + uint8_t x35; + uint64_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint8_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint64_t x50; + uint8_t x51; + uint64_t x52; + uint8_t x53; + uint64_t x54; + uint8_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint8_t x59; + uint8_t x60; + x1 = (arg1[3]); + x2 = (arg1[2]); + x3 = (arg1[1]); + x4 = (arg1[0]); + x5 = (uint8_t)(x4 & UINT8_C(0xff)); + x6 = (x4 >> 8); + x7 = (uint8_t)(x6 & UINT8_C(0xff)); + x8 = (x6 >> 8); + x9 = (uint8_t)(x8 & UINT8_C(0xff)); + x10 = (x8 >> 8); + x11 = (uint8_t)(x10 & UINT8_C(0xff)); + x12 = (x10 >> 8); + x13 = (uint8_t)(x12 & UINT8_C(0xff)); + x14 = (x12 >> 8); + x15 = (uint8_t)(x14 & UINT8_C(0xff)); + x16 = (x14 >> 8); + x17 = (uint8_t)(x16 & UINT8_C(0xff)); + x18 = (uint8_t)(x16 >> 8); + x19 = (uint8_t)(x3 & UINT8_C(0xff)); + x20 = (x3 >> 8); + x21 = (uint8_t)(x20 & UINT8_C(0xff)); + x22 = (x20 >> 8); + x23 = (uint8_t)(x22 & UINT8_C(0xff)); + x24 = (x22 >> 8); + x25 = (uint8_t)(x24 & UINT8_C(0xff)); + x26 = (x24 >> 8); + x27 = (uint8_t)(x26 & UINT8_C(0xff)); + x28 = (x26 >> 8); + x29 = (uint8_t)(x28 & UINT8_C(0xff)); + x30 = (x28 >> 8); + x31 = (uint8_t)(x30 & UINT8_C(0xff)); + x32 = (uint8_t)(x30 >> 8); + x33 = (uint8_t)(x2 & UINT8_C(0xff)); + x34 = (x2 >> 8); + x35 = (uint8_t)(x34 & UINT8_C(0xff)); + x36 = (x34 >> 8); + x37 = (uint8_t)(x36 & UINT8_C(0xff)); + x38 = (x36 >> 8); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (uint8_t)(x44 >> 8); + x47 = (uint8_t)(x1 & UINT8_C(0xff)); + x48 = (x1 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (x48 >> 8); + x51 = (uint8_t)(x50 & UINT8_C(0xff)); + x52 = (x50 >> 8); + x53 = (uint8_t)(x52 & UINT8_C(0xff)); + x54 = (x52 >> 8); + x55 = (uint8_t)(x54 & UINT8_C(0xff)); + x56 = (x54 >> 8); + x57 = (uint8_t)(x56 & UINT8_C(0xff)); + x58 = (x56 >> 8); + x59 = (uint8_t)(x58 & UINT8_C(0xff)); + x60 = (uint8_t)(x58 >> 8); + out1[0] = x5; + out1[1] = x7; + out1[2] = x9; + out1[3] = x11; + out1[4] = x13; + out1[5] = x15; + out1[6] = x17; + out1[7] = x18; + out1[8] = x19; + out1[9] = x21; + out1[10] = x23; + out1[11] = x25; + out1[12] = x27; + out1[13] = x29; + out1[14] = x31; + out1[15] = x32; + out1[16] = x33; + out1[17] = x35; + out1[18] = x37; + out1[19] = x39; + out1[20] = x41; + out1[21] = x43; + out1[22] = x45; + out1[23] = x46; + out1[24] = x47; + out1[25] = x49; + out1[26] = x51; + out1[27] = x53; + out1[28] = x55; + out1[29] = x57; + out1[30] = x59; + out1[31] = x60; +} + +/* + * The function fiat_p256_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. + * + * Preconditions: + * 0 ≤ bytes_eval arg1 < m + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * 0 ≤ eval out1 < m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_bytes(uint64_t out1[4], const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint8_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint8_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint8_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + x1 = ((uint64_t)(arg1[31]) << 56); + x2 = ((uint64_t)(arg1[30]) << 48); + x3 = ((uint64_t)(arg1[29]) << 40); + x4 = ((uint64_t)(arg1[28]) << 32); + x5 = ((uint64_t)(arg1[27]) << 24); + x6 = ((uint64_t)(arg1[26]) << 16); + x7 = ((uint64_t)(arg1[25]) << 8); + x8 = (arg1[24]); + x9 = ((uint64_t)(arg1[23]) << 56); + x10 = ((uint64_t)(arg1[22]) << 48); + x11 = ((uint64_t)(arg1[21]) << 40); + x12 = ((uint64_t)(arg1[20]) << 32); + x13 = ((uint64_t)(arg1[19]) << 24); + x14 = ((uint64_t)(arg1[18]) << 16); + x15 = ((uint64_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint64_t)(arg1[15]) << 56); + x18 = ((uint64_t)(arg1[14]) << 48); + x19 = ((uint64_t)(arg1[13]) << 40); + x20 = ((uint64_t)(arg1[12]) << 32); + x21 = ((uint64_t)(arg1[11]) << 24); + x22 = ((uint64_t)(arg1[10]) << 16); + x23 = ((uint64_t)(arg1[9]) << 8); + x24 = (arg1[8]); + x25 = ((uint64_t)(arg1[7]) << 56); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x25 + x38); + x40 = (x23 + (uint64_t)x24); + x41 = (x22 + x40); + x42 = (x21 + x41); + x43 = (x20 + x42); + x44 = (x19 + x43); + x45 = (x18 + x44); + x46 = (x17 + x45); + x47 = (x15 + (uint64_t)x16); + x48 = (x14 + x47); + x49 = (x13 + x48); + x50 = (x12 + x49); + x51 = (x11 + x50); + x52 = (x10 + x51); + x53 = (x9 + x52); + x54 = (x7 + (uint64_t)x8); + x55 = (x6 + x54); + x56 = (x5 + x55); + x57 = (x4 + x56); + x58 = (x3 + x57); + x59 = (x2 + x58); + x60 = (x1 + x59); + out1[0] = x39; + out1[1] = x46; + out1[2] = x53; + out1[3] = x60; +} + +/* + * The function fiat_p256_set_one returns the field element one in the Montgomery domain. + * + * Postconditions: + * eval (from_montgomery out1) mod m = 1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_set_one(fiat_p256_montgomery_domain_field_element out1) { + out1[0] = 0x1; + out1[1] = UINT64_C(0xffffffff00000000); + out1[2] = UINT64_C(0xffffffffffffffff); + out1[3] = UINT32_C(0xfffffffe); +} + +/* + * The function fiat_p256_msat returns the saturated representation of the prime modulus. + * + * Postconditions: + * twos_complement_eval out1 = m + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_msat(uint64_t out1[5]) { + out1[0] = UINT64_C(0xffffffffffffffff); + out1[1] = UINT32_C(0xffffffff); + out1[2] = 0x0; + out1[3] = UINT64_C(0xffffffff00000001); + out1[4] = 0x0; +} + +/* + * The function fiat_p256_divstep computes a divstep. + * + * Preconditions: + * 0 ≤ eval arg4 < m + * 0 ≤ eval arg5 < m + * Postconditions: + * out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) + * twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) + * twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) + * eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) + * eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) + * 0 ≤ eval out5 < m + * 0 ≤ eval out5 < m + * 0 ≤ eval out2 < m + * 0 ≤ eval out3 < m + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep(uint64_t* out1, uint64_t out2[5], uint64_t out3[5], uint64_t out4[4], uint64_t out5[4], uint64_t arg1, const uint64_t arg2[5], const uint64_t arg3[5], const uint64_t arg4[4], const uint64_t arg5[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_uint1 x3; + uint64_t x4; + fiat_p256_uint1 x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + uint64_t x18; + fiat_p256_uint1 x19; + uint64_t x20; + fiat_p256_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + fiat_p256_uint1 x40; + uint64_t x41; + fiat_p256_uint1 x42; + uint64_t x43; + fiat_p256_uint1 x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + fiat_p256_uint1 x60; + uint64_t x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + fiat_p256_uint1 x65; + uint64_t x66; + fiat_p256_uint1 x67; + uint64_t x68; + fiat_p256_uint1 x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + uint64_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + fiat_p256_uint1 x81; + uint64_t x82; + fiat_p256_uint1 x83; + uint64_t x84; + fiat_p256_uint1 x85; + uint64_t x86; + fiat_p256_uint1 x87; + uint64_t x88; + fiat_p256_uint1 x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + uint64_t x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + fiat_p256_uint1 x99; + uint64_t x100; + fiat_p256_uint1 x101; + uint64_t x102; + fiat_p256_uint1 x103; + uint64_t x104; + fiat_p256_uint1 x105; + uint64_t x106; + fiat_p256_uint1 x107; + uint64_t x108; + fiat_p256_uint1 x109; + uint64_t x110; + fiat_p256_uint1 x111; + uint64_t x112; + fiat_p256_uint1 x113; + uint64_t x114; + uint64_t x115; + uint64_t x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + uint64_t x126; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (~arg1), 0x1); + x3 = (fiat_p256_uint1)((fiat_p256_uint1)(x1 >> 63) & (fiat_p256_uint1)((arg3[0]) & 0x1)); + fiat_p256_addcarryx_u64(&x4, &x5, 0x0, (~arg1), 0x1); + fiat_p256_cmovznz_u64(&x6, x3, arg1, x4); + fiat_p256_cmovznz_u64(&x7, x3, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x8, x3, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x9, x3, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u64(&x10, x3, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u64(&x11, x3, (arg2[4]), (arg3[4])); + fiat_p256_addcarryx_u64(&x12, &x13, 0x0, 0x1, (~(arg2[0]))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, (~(arg2[1]))); + fiat_p256_addcarryx_u64(&x16, &x17, x15, 0x0, (~(arg2[2]))); + fiat_p256_addcarryx_u64(&x18, &x19, x17, 0x0, (~(arg2[3]))); + fiat_p256_addcarryx_u64(&x20, &x21, x19, 0x0, (~(arg2[4]))); + fiat_p256_cmovznz_u64(&x22, x3, (arg3[0]), x12); + fiat_p256_cmovznz_u64(&x23, x3, (arg3[1]), x14); + fiat_p256_cmovznz_u64(&x24, x3, (arg3[2]), x16); + fiat_p256_cmovznz_u64(&x25, x3, (arg3[3]), x18); + fiat_p256_cmovznz_u64(&x26, x3, (arg3[4]), x20); + fiat_p256_cmovznz_u64(&x27, x3, (arg4[0]), (arg5[0])); + fiat_p256_cmovznz_u64(&x28, x3, (arg4[1]), (arg5[1])); + fiat_p256_cmovznz_u64(&x29, x3, (arg4[2]), (arg5[2])); + fiat_p256_cmovznz_u64(&x30, x3, (arg4[3]), (arg5[3])); + fiat_p256_addcarryx_u64(&x31, &x32, 0x0, x27, x27); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x28, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x29, x29); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x30, x30); + fiat_p256_subborrowx_u64(&x39, &x40, 0x0, x31, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x41, &x42, x40, x33, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x43, &x44, x42, x35, 0x0); + fiat_p256_subborrowx_u64(&x45, &x46, x44, x37, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x47, &x48, x46, x38, 0x0); + x49 = (arg4[3]); + x50 = (arg4[2]); + x51 = (arg4[1]); + x52 = (arg4[0]); + fiat_p256_subborrowx_u64(&x53, &x54, 0x0, 0x0, x52); + fiat_p256_subborrowx_u64(&x55, &x56, x54, 0x0, x51); + fiat_p256_subborrowx_u64(&x57, &x58, x56, 0x0, x50); + fiat_p256_subborrowx_u64(&x59, &x60, x58, 0x0, x49); + fiat_p256_cmovznz_u64(&x61, x60, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x62, &x63, 0x0, x53, x61); + fiat_p256_addcarryx_u64(&x64, &x65, x63, x55, (x61 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x66, &x67, x65, x57, 0x0); + fiat_p256_addcarryx_u64(&x68, &x69, x67, x59, (x61 & UINT64_C(0xffffffff00000001))); + fiat_p256_cmovznz_u64(&x70, x3, (arg5[0]), x62); + fiat_p256_cmovznz_u64(&x71, x3, (arg5[1]), x64); + fiat_p256_cmovznz_u64(&x72, x3, (arg5[2]), x66); + fiat_p256_cmovznz_u64(&x73, x3, (arg5[3]), x68); + x74 = (fiat_p256_uint1)(x22 & 0x1); + fiat_p256_cmovznz_u64(&x75, x74, 0x0, x7); + fiat_p256_cmovznz_u64(&x76, x74, 0x0, x8); + fiat_p256_cmovznz_u64(&x77, x74, 0x0, x9); + fiat_p256_cmovznz_u64(&x78, x74, 0x0, x10); + fiat_p256_cmovznz_u64(&x79, x74, 0x0, x11); + fiat_p256_addcarryx_u64(&x80, &x81, 0x0, x22, x75); + fiat_p256_addcarryx_u64(&x82, &x83, x81, x23, x76); + fiat_p256_addcarryx_u64(&x84, &x85, x83, x24, x77); + fiat_p256_addcarryx_u64(&x86, &x87, x85, x25, x78); + fiat_p256_addcarryx_u64(&x88, &x89, x87, x26, x79); + fiat_p256_cmovznz_u64(&x90, x74, 0x0, x27); + fiat_p256_cmovznz_u64(&x91, x74, 0x0, x28); + fiat_p256_cmovznz_u64(&x92, x74, 0x0, x29); + fiat_p256_cmovznz_u64(&x93, x74, 0x0, x30); + fiat_p256_addcarryx_u64(&x94, &x95, 0x0, x70, x90); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x71, x91); + fiat_p256_addcarryx_u64(&x98, &x99, x97, x72, x92); + fiat_p256_addcarryx_u64(&x100, &x101, x99, x73, x93); + fiat_p256_subborrowx_u64(&x102, &x103, 0x0, x94, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x104, &x105, x103, x96, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x106, &x107, x105, x98, 0x0); + fiat_p256_subborrowx_u64(&x108, &x109, x107, x100, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x110, &x111, x109, x101, 0x0); + fiat_p256_addcarryx_u64(&x112, &x113, 0x0, x6, 0x1); + x114 = ((x80 >> 1) | ((x82 << 63) & UINT64_C(0xffffffffffffffff))); + x115 = ((x82 >> 1) | ((x84 << 63) & UINT64_C(0xffffffffffffffff))); + x116 = ((x84 >> 1) | ((x86 << 63) & UINT64_C(0xffffffffffffffff))); + x117 = ((x86 >> 1) | ((x88 << 63) & UINT64_C(0xffffffffffffffff))); + x118 = ((x88 & UINT64_C(0x8000000000000000)) | (x88 >> 1)); + fiat_p256_cmovznz_u64(&x119, x48, x39, x31); + fiat_p256_cmovznz_u64(&x120, x48, x41, x33); + fiat_p256_cmovznz_u64(&x121, x48, x43, x35); + fiat_p256_cmovznz_u64(&x122, x48, x45, x37); + fiat_p256_cmovznz_u64(&x123, x111, x102, x94); + fiat_p256_cmovznz_u64(&x124, x111, x104, x96); + fiat_p256_cmovznz_u64(&x125, x111, x106, x98); + fiat_p256_cmovznz_u64(&x126, x111, x108, x100); + *out1 = x112; + out2[0] = x7; + out2[1] = x8; + out2[2] = x9; + out2[3] = x10; + out2[4] = x11; + out3[0] = x114; + out3[1] = x115; + out3[2] = x116; + out3[3] = x117; + out3[4] = x118; + out4[0] = x119; + out4[1] = x120; + out4[2] = x121; + out4[3] = x122; + out5[0] = x123; + out5[1] = x124; + out5[2] = x125; + out5[3] = x126; +} + +/* + * The function fiat_p256_divstep_precomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). + * + * Postconditions: + * eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep_precomp(uint64_t out1[4]) { + out1[0] = UINT64_C(0x67ffffffb8000000); + out1[1] = UINT64_C(0xc000000038000000); + out1[2] = UINT64_C(0xd80000007fffffff); + out1[3] = UINT64_C(0x2fffffffffffffff); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/README.md new file mode 100644 index 00000000..9a91146f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/README.md @@ -0,0 +1,53 @@ +# SwiftNIO SSL + +SwiftNIO SSL is a Swift package that contains an implementation of TLS based on BoringSSL. This package allows users of [SwiftNIO](https://github.com/apple/swift-nio) to write protocol clients and servers that use TLS to secure data in flight. + +The name is inspired primarily by the names of the library this package uses (BoringSSL), and not because we don't know the name of the protocol. We know the protocol is TLS! + +To get started, check out the [API docs](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html). + +## Using SwiftNIO SSL + +SwiftNIO SSL provides two `ChannelHandler`s to use to secure a data stream: the `NIOSSLClientHandler` and the `NIOSSLServerHandler`. Each of these can be added to a `Channel` to secure the communications on that channel. + +Additionally, we provide a number of low-level primitives for configuring your TLS connections. These will be shown below. + +To secure a server connection, you will need a X.509 certificate chain in a file (either PEM or DER, but PEM is far easier), and the associated private key for the leaf certificate. These objects can then be wrapped up in a `TLSConfiguration` object that is used to initialize the `ChannelHandler`. + +For example: + +```swift +let configuration = TLSConfiguration.makeServerConfiguration( + certificateChain: try NIOSSLCertificate.fromPEMFile("cert.pem").map { .certificate($0) }, + privateKey: .file("key.pem") +) +let sslContext = try NIOSSLContext(configuration: configuration) + +let server = ServerBootstrap(group: group) + .childChannelInitializer { channel in + // important: The handler must be initialized _inside_ the `childChannelInitializer` + let handler = try NIOSSLServerHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` + +For clients, it is a bit simpler as there is no need to have a certificate chain or private key (though clients *may* have these things). Setup for clients may be done like this: + +```swift +let configuration = TLSConfiguration.makeClientConfiguration() +let sslContext = try NIOSSLContext(configuration: configuration) + +let client = ClientBootstrap(group: group) + .channelInitializer { channel in + // important: The handler must be initialized _inside_ the `channelInitializer` + let handler = try NIOSSLClientHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` +Note that SwiftNIO SSL currently requires Swift 5.4 and above. Release 2.13.x and prior support Swift 5.0 and 5.1, Release 2.18.x and prior supports Swift 5.2 and 5.3. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/include/CNIOBoringSSLShims.h b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/include/CNIOBoringSSLShims.h new file mode 100644 index 00000000..f2de7f93 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/include/CNIOBoringSSLShims.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifndef C_NIO_BORINGSSL_SHIMS_H +#define C_NIO_BORINGSSL_SHIMS_H + +// This is for instances when `swift package generate-xcodeproj` is used as CNIOBoringSSL +// is treated as a framework and requires the framework's name as a prefix. +#if __has_include() +#include +#else +#include "CNIOBoringSSL.h" +#endif + +GENERAL_NAME *CNIOBoringSSLShims_sk_GENERAL_NAME_value(const STACK_OF(GENERAL_NAME) *sk, size_t i); +size_t CNIOBoringSSLShims_sk_GENERAL_NAME_num(const STACK_OF(GENERAL_NAME) *sk); + +void *CNIOBoringSSLShims_SSL_CTX_get_app_data(const SSL_CTX *ctx); +int CNIOBoringSSLShims_SSL_CTX_set_app_data(SSL_CTX *ctx, void *data); + +int CNIOBoringSSLShims_ERR_GET_LIB(uint32_t err); +int CNIOBoringSSLShims_ERR_GET_REASON(uint32_t err); + +#endif // C_NIO_BORINGSSL_SHIMS_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/shims.c b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/shims.c new file mode 100644 index 00000000..d88fea53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOBoringSSLShims/Sources/CNIOBoringSSLShims/shims.c @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +// Unfortunately, even in our brave BoringSSL world, we have "functions" that are +// macros too complex for the clang importer. This file handles them. +#include "CNIOBoringSSLShims.h" + +GENERAL_NAME *CNIOBoringSSLShims_sk_GENERAL_NAME_value(const STACK_OF(GENERAL_NAME) *sk, size_t i) { + return sk_GENERAL_NAME_value(sk, i); +} + +size_t CNIOBoringSSLShims_sk_GENERAL_NAME_num(const STACK_OF(GENERAL_NAME) *sk) { + return sk_GENERAL_NAME_num(sk); +} + +void *CNIOBoringSSLShims_SSL_CTX_get_app_data(const SSL_CTX *ctx) { + return SSL_CTX_get_app_data(ctx); +} + +int CNIOBoringSSLShims_SSL_CTX_set_app_data(SSL_CTX *ctx, void *data) { + return SSL_CTX_set_app_data(ctx, data); +} + +int CNIOBoringSSLShims_ERR_GET_LIB(uint32_t err) { + return ERR_GET_LIB(err); +} + +int CNIOBoringSSLShims_ERR_GET_REASON(uint32_t err) { + return ERR_GET_REASON(err); +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIODarwin/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIODarwin/README.md b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/include/CNIODarwin.h b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/include/CNIODarwin.h new file mode 100644 index 00000000..0c26520e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/include/CNIODarwin.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifndef C_NIO_DARWIN_H +#define C_NIO_DARWIN_H + +#ifdef __APPLE__ +#include +#include + +// Darwin platforms do not have a sendmmsg implementation available to them. This C module +// provides a shim that implements sendmmsg on top of sendmsg. It also provides a shim for +// recvmmsg, but does not actually implement that shim, instantly throwing errors if called. +// +// On Linux sendmmsg will error immediately in many cases if it knows any of the messages +// cannot be sent. This is not something we can easily achieve from userspace on Darwin, +// so instead if we encounter an error on any message but the first we will return "short". + +typedef struct { + struct msghdr msg_hdr; + unsigned int msg_len; +} CNIODarwin_mmsghdr; + +extern const int CNIODarwin_IPTOS_ECN_NOTECT; +extern const int CNIODarwin_IPTOS_ECN_MASK; +extern const int CNIODarwin_IPTOS_ECN_ECT0; +extern const int CNIODarwin_IPTOS_ECN_ECT1; +extern const int CNIODarwin_IPTOS_ECN_CE; +extern const int CNIODarwin_IPV6_RECVPKTINFO; +extern const int CNIODarwin_IPV6_PKTINFO; + +int CNIODarwin_sendmmsg(int sockfd, CNIODarwin_mmsghdr *msgvec, unsigned int vlen, int flags); +int CNIODarwin_recvmmsg(int sockfd, CNIODarwin_mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); + +// cmsghdr handling +struct cmsghdr *CNIODarwin_CMSG_FIRSTHDR(const struct msghdr *); +struct cmsghdr *CNIODarwin_CMSG_NXTHDR(const struct msghdr *, const struct cmsghdr *); +const void *CNIODarwin_CMSG_DATA(const struct cmsghdr *); +void *CNIODarwin_CMSG_DATA_MUTABLE(struct cmsghdr *); +size_t CNIODarwin_CMSG_LEN(size_t); +size_t CNIODarwin_CMSG_SPACE(size_t); + +#endif // __APPLE__ +#endif // C_NIO_DARWIN_H diff --git a/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/shim.c b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/shim.c new file mode 100644 index 00000000..90f9af49 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIODarwin/Sources/CNIODarwin/shim.c @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#include +#include +#include + +int CNIODarwin_sendmmsg(int sockfd, CNIODarwin_mmsghdr *msgvec, unsigned int vlen, int flags) { + // Some quick error checking. If vlen can't fit into int, we bail. + if ((vlen > INT_MAX) || (msgvec == NULL)) { + errno = EINVAL; + return -1; + } + + for (unsigned int i = 0; i < vlen; i++) { + ssize_t sendAmount = sendmsg(sockfd, &(msgvec[i].msg_hdr), flags); + if (sendAmount < 0 && i == 0) { + // Error on the first send, return the error. + return -1; + } + + if (sendAmount < 0) { + // Error on a later send, return short. + return i; + } + + // Send succeeded, save off the bytes written. + msgvec[i].msg_len = (unsigned int)sendAmount; + } + + // If we dropped out, we sent everything. + return vlen; +} + +int CNIODarwin_recvmmsg(int sockfd, CNIODarwin_mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) { + errx(EX_SOFTWARE, "recvmmsg shim not implemented on Darwin platforms\n"); +} + +struct cmsghdr *CNIODarwin_CMSG_FIRSTHDR(const struct msghdr *mhdr) { + assert(mhdr != NULL); + return CMSG_FIRSTHDR(mhdr); +} + +struct cmsghdr *CNIODarwin_CMSG_NXTHDR(const struct msghdr *mhdr, const struct cmsghdr *cmsg) { + assert(mhdr != NULL); + assert(cmsg != NULL); // Not required by Darwin but Linux needs this so we should match. + return CMSG_NXTHDR(mhdr, cmsg); +} + +const void *CNIODarwin_CMSG_DATA(const struct cmsghdr *cmsg) { + assert(cmsg != NULL); + return CMSG_DATA(cmsg); +} + +void *CNIODarwin_CMSG_DATA_MUTABLE(struct cmsghdr *cmsg) { + assert(cmsg != NULL); + return CMSG_DATA(cmsg); +} + +size_t CNIODarwin_CMSG_LEN(size_t payloadSizeBytes) { + return CMSG_LEN(payloadSizeBytes); +} + +size_t CNIODarwin_CMSG_SPACE(size_t payloadSizeBytes) { + return CMSG_SPACE(payloadSizeBytes); +} + +const int CNIODarwin_IPTOS_ECN_NOTECT = IPTOS_ECN_NOTECT; +const int CNIODarwin_IPTOS_ECN_MASK = IPTOS_ECN_MASK; +const int CNIODarwin_IPTOS_ECN_ECT0 = IPTOS_ECN_ECT0; +const int CNIODarwin_IPTOS_ECN_ECT1 = IPTOS_ECN_ECT1; +const int CNIODarwin_IPTOS_ECN_CE = IPTOS_ECN_CE; +const int CNIODarwin_IPV6_RECVPKTINFO = IPV6_RECVPKTINFO; +const int CNIODarwin_IPV6_PKTINFO = IPV6_PKTINFO; + +#endif // __APPLE__ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/c_nio_http_parser.c b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/c_nio_http_parser.c new file mode 100644 index 00000000..89877f68 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/c_nio_http_parser.c @@ -0,0 +1,2578 @@ +/* Additional changes for SwiftNIO: + - prefixed all symbols by 'c_nio_' +*/ +/* Copyright Joyent, Inc. and other Node contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "include/c_nio_http_parser.h" +#include +#include +#include +#include +#include + +static uint32_t max_header_size = HTTP_MAX_HEADER_SIZE; + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef BIT_AT +# define BIT_AT(a, i) \ + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) +#endif + +#ifndef ELEM_AT +# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) +#endif + +#define SET_ERRNO(e) \ +do { \ + parser->nread = nread; \ + parser->http_errno = (e); \ +} while(0) + +#define CURRENT_STATE() p_state +#define UPDATE_STATE(V) p_state = (enum state) (V); +#define RETURN(V) \ +do { \ + parser->nread = nread; \ + parser->state = CURRENT_STATE(); \ + return (V); \ +} while (0); +#define REEXECUTE() \ + goto reexecute; \ + + +#ifdef __GNUC__ +# define LIKELY(X) __builtin_expect(!!(X), 1) +# define UNLIKELY(X) __builtin_expect(!!(X), 0) +#else +# define LIKELY(X) (X) +# define UNLIKELY(X) (X) +#endif + + +/* Run the notify callback FOR, returning ER if it fails */ +#define CALLBACK_NOTIFY_(FOR, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ +} while (0) + +/* Run the notify callback FOR and consume the current byte */ +#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) + +/* Run the notify callback FOR and don't consume the current byte */ +#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) + +/* Run data callback FOR with LEN bytes, returning ER if it fails */ +#define CALLBACK_DATA_(FOR, LEN, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != \ + settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ +} while (0) + +/* Run the data callback FOR and consume the current byte */ +#define CALLBACK_DATA(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + +/* Run the data callback FOR and don't consume the current byte */ +#define CALLBACK_DATA_NOADVANCE(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + +/* Set the mark FOR; non-destructive if mark is already set */ +#define MARK(FOR) \ +do { \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ +} while (0) + +/* Don't allow the total size of the HTTP headers (including the status + * line) to exceed max_header_size. This check is here to protect + * embedders against denial-of-service attacks where the attacker feeds + * us a never-ending header that the embedder keeps buffering. + * + * This check is arguably the responsibility of embedders but we're doing + * it on the embedder's behalf because most won't bother and this way we + * make the web a little safer. max_header_size is still far bigger + * than any reasonable request or response so this should never affect + * day-to-day operation. + */ +#define COUNT_HEADER_SIZE(V) \ +do { \ + nread += (uint32_t)(V); \ + if (UNLIKELY(nread > max_header_size)) { \ + SET_ERRNO(HPE_HEADER_OVERFLOW); \ + goto error; \ + } \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { +#define XX(num, name, string) #string, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + ' ', '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +#if HTTP_PARSER_STRICT +# define T(v) 0 +#else +# define T(v) v +#endif + + +static const uint8_t normal_url_char[32] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; + +#undef T + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_http_major + , s_res_http_dot + , s_res_http_minor + , s_res_http_end + , s_res_first_status_code + , s_res_status_code + , s_res_status_start + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_http_I + , s_req_http_IC + , s_req_http_major + , s_req_http_dot + , s_req_http_minor + , s_req_http_end + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_discard_ws + , s_header_value_discard_ws_almost_done + , s_header_value_discard_lws + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; + + +#define PARSING_HEADER(state) (state <= s_headers_done) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_content_length_num + , h_content_length_ws + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_token_start + , h_matching_transfer_encoding_chunked + , h_matching_transfer_encoding_token + + , h_matching_connection_token_start + , h_matching_connection_keep_alive + , h_matching_connection_close + , h_matching_connection_upgrade + , h_matching_connection_token + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + , h_connection_upgrade + }; + +enum http_host_state + { + s_http_host_dead = 1 + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone + , s_http_host_port_start + , s_http_host_port +}; + +/* Macros for character classes; depends on strict-mode */ +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') +#define IS_NUM(c) ((c) >= '0' && (c) <= '9') +#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) +#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') +#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') + +#define STRICT_TOKEN(c) ((c == ' ') ? 0 : tokens[(unsigned char)c]) + +#if HTTP_PARSER_STRICT +#define TOKEN(c) STRICT_TOKEN(c) +#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) +#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') +#else +#define TOKEN(c) tokens[(unsigned char)c] +#define IS_URL_CHAR(c) \ + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) +#define IS_HOST_CHAR(c) \ + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') +#endif + +/** + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + **/ +#define IS_HEADER_CHAR(ch) \ + (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) + +#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) \ +do { \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ +} while (0) +# define NEW_MESSAGE() (c_nio_http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +/* Map errno values to strings for human-readable output */ +#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, +static struct { + const char *name; + const char *description; +} http_strerror_tab[] = { + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) +}; +#undef HTTP_STRERROR_GEN + +int c_nio_http_message_needs_eof(const http_parser *parser); + +/* Our URL parser. + * + * This is designed to be shared by c_nio_http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in c_nio_http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ +static enum state +parse_url_char(enum state s, const char ch) +{ + if (ch == ' ' || ch == '\r' || ch == '\n') { + return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* fall through */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; +} + +size_t c_nio_http_parser_execute (http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + const char *status_mark = 0; + enum state p_state = (enum state) parser->state; + const unsigned int lenient = parser->lenient_http_headers; + const unsigned int allow_chunked_length = parser->allow_chunked_length; + + uint32_t nread = parser->nread; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { + switch (CURRENT_STATE()) { + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; + } + } + + + if (CURRENT_STATE() == s_header_field) + header_field_mark = data; + if (CURRENT_STATE() == s_header_value) + header_value_mark = data; + switch (CURRENT_STATE()) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + case s_res_status: + status_mark = data; + break; + default: + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(CURRENT_STATE())) + COUNT_HEADER_SIZE(1); + +reexecute: + switch (CURRENT_STATE()) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (LIKELY(ch == CR || ch == LF)) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->uses_transfer_encoding = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + UPDATE_STATE(s_res_or_resp_H); + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + UPDATE_STATE(s_start_req); + REEXECUTE(); + } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + UPDATE_STATE(s_res_HT); + } else { + if (UNLIKELY(ch != 'E')) { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + UPDATE_STATE(s_req_method); + } + break; + + case s_start_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->uses_transfer_encoding = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + UPDATE_STATE(s_res_H); + } else { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HT); + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HTT); + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_res_HTTP); + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_res_http_major); + break; + + case s_res_http_major: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_res_http_dot); + break; + + case s_res_http_dot: + { + if (UNLIKELY(ch != '.')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_res_http_minor); + break; + } + + case s_res_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_res_http_end); + break; + + case s_res_http_end: + { + if (UNLIKELY(ch != ' ')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_res_first_status_code); + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + UPDATE_STATE(s_res_status_code); + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + UPDATE_STATE(s_res_status_start); + break; + case CR: + case LF: + UPDATE_STATE(s_res_status_start); + REEXECUTE(); + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (UNLIKELY(parser->status_code > 999)) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status_start: + { + MARK(status); + UPDATE_STATE(s_res_status); + parser->index = 0; + + if (ch == CR || ch == LF) + REEXECUTE(); + + break; + } + + case s_res_status: + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + CALLBACK_DATA(status); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA(status); + break; + } + + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_field_start); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->uses_transfer_encoding = 0; + parser->content_length = ULLONG_MAX; + + if (UNLIKELY(!IS_ALPHA(ch))) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'A': parser->method = HTTP_ACL; break; + case 'B': parser->method = HTTP_BIND; break; + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH, SOURCE */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + UPDATE_STATE(s_req_method); + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (UNLIKELY(ch == '\0')) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + UPDATE_STATE(s_req_spaces_before_url); + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if ((ch >= 'A' && ch <= 'Z') || ch == '-') { + + switch (parser->method << 16 | parser->index << 8 | ch) { +#define XX(meth, pos, ch, new_meth) \ + case (HTTP_##meth << 16 | pos << 8 | ch): \ + parser->method = HTTP_##new_meth; break; + + XX(POST, 1, 'U', PUT) + XX(POST, 1, 'A', PATCH) + XX(POST, 1, 'R', PROPFIND) + XX(PUT, 2, 'R', PURGE) + XX(CONNECT, 1, 'H', CHECKOUT) + XX(CONNECT, 2, 'P', COPY) + XX(MKCOL, 1, 'O', MOVE) + XX(MKCOL, 1, 'E', MERGE) + XX(MKCOL, 1, '-', MSEARCH) + XX(MKCOL, 2, 'A', MKACTIVITY) + XX(MKCOL, 3, 'A', MKCALENDAR) + XX(SUBSCRIBE, 1, 'E', SEARCH) + XX(SUBSCRIBE, 1, 'O', SOURCE) + XX(REPORT, 2, 'B', REBIND) + XX(PROPFIND, 4, 'P', PROPPATCH) + XX(LOCK, 1, 'I', LINK) + XX(UNLOCK, 2, 'S', UNSUBSCRIBE) + XX(UNLOCK, 2, 'B', UNBIND) + XX(UNLOCK, 3, 'I', UNLINK) +#undef XX + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + UPDATE_STATE(s_req_server_start); + } + + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + UPDATE_STATE(s_req_http_start); + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + UPDATE_STATE((ch == CR) ? + s_req_line_almost_done : + s_header_field_start); + CALLBACK_DATA(url); + break; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case ' ': + break; + case 'H': + UPDATE_STATE(s_req_http_H); + break; + case 'I': + if (parser->method == HTTP_SOURCE) { + UPDATE_STATE(s_req_http_I); + break; + } + /* fall through */ + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HT); + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HTT); + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_req_http_HTTP); + break; + + case s_req_http_I: + STRICT_CHECK(ch != 'C'); + UPDATE_STATE(s_req_http_IC); + break; + + case s_req_http_IC: + STRICT_CHECK(ch != 'E'); + UPDATE_STATE(s_req_http_HTTP); /* Treat "ICE" as "HTTP". */ + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_req_http_major); + break; + + case s_req_http_major: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_req_http_dot); + break; + + case s_req_http_dot: + { + if (UNLIKELY(ch != '.')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_req_http_minor); + break; + } + + case s_req_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_req_http_end); + break; + + case s_req_http_end: + { + if (ch == CR) { + UPDATE_STATE(s_req_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_field_start); + break; + } + + case s_header_field_start: + { + if (ch == CR) { + UPDATE_STATE(s_headers_almost_done); + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + UPDATE_STATE(s_headers_almost_done); + REEXECUTE(); + } + + c = TOKEN(ch); + + if (UNLIKELY(!c)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + UPDATE_STATE(s_header_field); + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + const char* start = p; + for (; p != data + len; p++) { + ch = *p; + c = TOKEN(ch); + + if (!c) + break; + + switch (parser->header_state) { + case h_general: { + size_t left = data + len - p; + const char* pe = p + MIN(left, max_header_size); + while (p+1 < pe && TOKEN(p[1])) { + p++; + } + break; + } + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + parser->uses_transfer_encoding = 1; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + } + + if (p == data + len) { + --p; + COUNT_HEADER_SIZE(p - start); + break; + } + + COUNT_HEADER_SIZE(p - start); + + if (ch == ':') { + UPDATE_STATE(s_header_value_discard_ws); + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_discard_ws: + if (ch == ' ' || ch == '\t') break; + + if (ch == CR) { + UPDATE_STATE(s_header_value_discard_ws_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + /* fall through */ + + case s_header_value_start: + { + MARK(header_value); + + UPDATE_STATE(s_header_value); + parser->index = 0; + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_matching_transfer_encoding_token; + } + break; + + /* Multi-value `Transfer-Encoding` header */ + case h_matching_transfer_encoding_token_start: + break; + + case h_content_length: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + if (parser->flags & F_CONTENTLENGTH) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + parser->flags |= F_CONTENTLENGTH; + parser->content_length = ch - '0'; + parser->header_state = h_content_length_num; + break; + + /* when obsolete line folding is encountered for content length + * continue to the s_header_value state */ + case h_content_length_ws: + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else if (c == 'u') { + parser->header_state = h_matching_connection_upgrade; + } else { + parser->header_state = h_matching_connection_token; + } + break; + + /* Multi-value `Connection` header */ + case h_matching_connection_token_start: + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + const char* start = p; + enum header_states h_state = (enum header_states) parser->header_state; + for (; p != data + len; p++) { + ch = *p; + if (ch == CR) { + UPDATE_STATE(s_header_almost_done); + parser->header_state = h_state; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_almost_done); + COUNT_HEADER_SIZE(p - start); + parser->header_state = h_state; + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + c = LOWER(ch); + + switch (h_state) { + case h_general: + { + size_t left = data + len - p; + const char* pe = p + MIN(left, max_header_size); + + for (; p != pe; p++) { + ch = *p; + if (ch == CR || ch == LF) { + --p; + break; + } + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + } + if (p == data + len) + --p; + break; + } + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + if (ch == ' ') break; + h_state = h_content_length_num; + /* fall through */ + + case h_content_length_num: + { + uint64_t t; + + if (ch == ' ') { + h_state = h_content_length_ws; + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + parser->content_length = t; + break; + } + + case h_content_length_ws: + if (ch == ' ') break; + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_token_start: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + h_state = h_matching_transfer_encoding_chunked; + } else if (STRICT_TOKEN(c)) { + /* TODO(indutny): similar code below does this, but why? + * At the very least it seems to be inconsistent given that + * h_matching_transfer_encoding_token does not check for + * `STRICT_TOKEN` + */ + h_state = h_matching_transfer_encoding_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; + + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + h_state = h_matching_transfer_encoding_token; + } else if (parser->index == sizeof(CHUNKED)-2) { + h_state = h_transfer_encoding_chunked; + } + break; + + case h_matching_transfer_encoding_token: + if (ch == ',') { + h_state = h_matching_transfer_encoding_token_start; + parser->index = 0; + } + break; + + case h_matching_connection_token_start: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + h_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + h_state = h_matching_connection_close; + } else if (c == 'u') { + h_state = h_matching_connection_upgrade; + } else if (STRICT_TOKEN(c)) { + h_state = h_matching_connection_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + h_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(CLOSE)-2) { + h_state = h_connection_close; + } + break; + + /* looking for 'Connection: upgrade' */ + case h_matching_connection_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE) - 1 || + c != UPGRADE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(UPGRADE)-2) { + h_state = h_connection_upgrade; + } + break; + + case h_matching_connection_token: + if (ch == ',') { + h_state = h_matching_connection_token_start; + parser->index = 0; + } + break; + + case h_transfer_encoding_chunked: + if (ch != ' ') h_state = h_matching_transfer_encoding_token; + break; + + case h_connection_keep_alive: + case h_connection_close: + case h_connection_upgrade: + if (ch == ',') { + if (h_state == h_connection_keep_alive) { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } else if (h_state == h_connection_close) { + parser->flags |= F_CONNECTION_CLOSE; + } else if (h_state == h_connection_upgrade) { + parser->flags |= F_CONNECTION_UPGRADE; + } + h_state = h_matching_connection_token_start; + parser->index = 0; + } else if (ch != ' ') { + h_state = h_matching_connection_token; + } + break; + + default: + UPDATE_STATE(s_header_value); + h_state = h_general; + break; + } + } + parser->header_state = h_state; + + if (p == data + len) + --p; + + COUNT_HEADER_SIZE(p - start); + break; + } + + case s_header_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_value_lws); + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') { + if (parser->header_state == h_content_length_num) { + /* treat obsolete line folding as space */ + parser->header_state = h_content_length_ws; + } + UPDATE_STATE(s_header_value_start); + REEXECUTE(); + } + + /* finished the header */ + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + default: + break; + } + + UPDATE_STATE(s_header_field_start); + REEXECUTE(); + } + + case s_header_value_discard_ws_almost_done: + { + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + case s_header_value_discard_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_discard_ws); + break; + } else { + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_content_length: + /* do not allow empty content length */ + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + break; + default: + break; + } + + /* header value was empty */ + MARK(header_value); + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + UPDATE_STATE(s_message_done); + CALLBACK_NOTIFY_NOADVANCE(chunk_complete); + REEXECUTE(); + } + + /* Cannot use transfer-encoding and a content-length header together + per the HTTP specification. (RFC 7230 Section 3.3.3) */ + if ((parser->uses_transfer_encoding == 1) && + (parser->flags & F_CONTENTLENGTH)) { + /* Allow it for lenient parsing as long as `Transfer-Encoding` is + * not `chunked` or allow_length_with_encoding is set + */ + if (parser->flags & F_CHUNKED) { + if (!allow_chunked_length) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + } else if (!lenient) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + } + + UPDATE_STATE(s_headers_done); + + /* Set this here so that on_headers_complete() callbacks can see it */ + if ((parser->flags & F_UPGRADE) && + (parser->flags & F_CONNECTION_UPGRADE)) { + /* For responses, "Upgrade: foo" and "Connection: upgrade" are + * mandatory only when it is a 101 Switching Protocols response, + * otherwise it is purely informational, to announce support. + */ + parser->upgrade = + (parser->type == HTTP_REQUEST || parser->status_code == 101); + } else { + parser->upgrade = (parser->method == HTTP_CONNECT); + } + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 2: + parser->upgrade = 1; + + /* fall through */ + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + RETURN(p - data); /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + RETURN(p - data); + } + + REEXECUTE(); + } + + case s_headers_done: + { + int hasBody; + STRICT_CHECK(ch != LF); + + parser->nread = 0; + nread = 0; + + hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + RETURN((p - data) + 1); + } + + if (parser->flags & F_SKIPBODY) { + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header, + * prepare for a chunk */ + UPDATE_STATE(s_chunk_size_start); + } else if (parser->uses_transfer_encoding == 1) { + if (parser->type == HTTP_REQUEST && !lenient) { + /* RFC 7230 3.3.3 */ + + /* If a Transfer-Encoding header field + * is present in a request and the chunked transfer coding is not + * the final encoding, the message body length cannot be determined + * reliably; the server MUST respond with the 400 (Bad Request) + * status code and then close the connection. + */ + SET_ERRNO(HPE_INVALID_TRANSFER_ENCODING); + RETURN(p - data); /* Error */ + } else { + /* RFC 7230 3.3.3 */ + + /* If a Transfer-Encoding header field is present in a response and + * the chunked transfer coding is not the final encoding, the + * message body length is determined by reading the connection until + * it is closed by the server. + */ + UPDATE_STATE(s_body_identity_eof); + } + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + UPDATE_STATE(s_body_identity); + } else { + if (!c_nio_http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + UPDATE_STATE(s_body_identity_eof); + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_message_done); + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + REEXECUTE(); + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } + break; + + case s_chunk_size_start: + { + assert(nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (UNLIKELY(unhex_val == -1)) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + UPDATE_STATE(s_chunk_size); + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + UPDATE_STATE(s_chunk_parameters); + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + UPDATE_STATE(s_header_field_start); + } else { + UPDATE_STATE(s_chunk_data); + } + CALLBACK_NOTIFY(chunk_header); + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_chunk_data_almost_done); + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + UPDATE_STATE(s_chunk_data_done); + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + nread = 0; + UPDATE_STATE(s_chunk_size_start); + CALLBACK_NOTIFY(chunk_complete); + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; + } + } + + /* Run callbacks for any marks that we have leftover after we ran out of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0) + + (status_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + CALLBACK_DATA_NOADVANCE(status); + + RETURN(len); + +error: + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + RETURN(p - data); +} + + +/* Does the parser need to see an EOF to find the end of the message? */ +int +c_nio_http_message_needs_eof (const http_parser *parser) +{ + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + /* RFC 7230 3.3.3, see `s_headers_almost_done` */ + if ((parser->uses_transfer_encoding == 1) && + (parser->flags & F_CHUNKED) == 0) { + return 1; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; +} + + +int +c_nio_http_should_keep_alive (const http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !c_nio_http_message_needs_eof(parser); +} + + +const char * +c_nio_http_method_str (enum http_method m) +{ + return ELEM_AT(method_strings, m, ""); +} + +const char * +c_nio_http_status_str (enum http_status s) +{ + switch (s) { +#define XX(num, name, string) case HTTP_STATUS_##name: return #string; + HTTP_STATUS_MAP(XX) +#undef XX + default: return ""; + } +} + +void +c_nio_http_parser_init (http_parser *parser, enum http_parser_type t) +{ + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; +} + +void +c_nio_http_parser_settings_init(http_parser_settings *settings) +{ + memset(settings, 0, sizeof(*settings)); +} + +const char * +c_nio_http_errno_name(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].name; +} + +const char * +c_nio_http_errno_description(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].description; +} + +static enum http_host_state +http_parse_host_char(enum http_host_state s, const char ch) { + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* fall through */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* fall through */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* fall through */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; +} + +static int +http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + assert(u->field_set & (1 << UF_HOST)); + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; + } + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = (uint16_t)(p - buf); + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = (uint16_t)(p - buf); + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = (uint16_t)(p - buf); + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = (uint16_t)(p - buf); + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; + } + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; +} + +void +c_nio_http_parser_url_init(struct http_parser_url *u) { + memset(u, 0, sizeof(*u)); +} + +int +c_nio_http_parser_parse_url(const char *buf, size_t buflen, int is_connect, + struct http_parser_url *u) +{ + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + if (buflen == 0) { + return 1; + } + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* fall through */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); + return 1; + } + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; + } + + u->field_data[uf].off = (uint16_t)(p - buf); + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & (1 << UF_SCHEMA)) && + (u->field_set & (1 << UF_HOST)) == 0) { + return 1; + } + + if (u->field_set & (1 << UF_HOST)) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + uint16_t off; + uint16_t len; + const char* p; + const char* end; + unsigned long v; + + off = u->field_data[UF_PORT].off; + len = u->field_data[UF_PORT].len; + end = buf + off + len; + + /* NOTE: The characters are already validated and are in the [0-9] range */ + assert((size_t) (off + len) <= buflen && "Port number overflow"); + v = 0; + for (p = buf + off; p < end; p++) { + v *= 10; + v += *p - '0'; + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + } + + u->port = (uint16_t) v; + } + + return 0; +} + +void +c_nio_http_parser_pause(http_parser *parser, int paused) { + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + uint32_t nread = parser->nread; /* used by the SET_ERRNO macro */ + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } +} + +int +c_nio_http_body_is_final(const struct http_parser *parser) { + return parser->state == s_message_done; +} + +unsigned long +c_nio_http_parser_version(void) { + return HTTP_PARSER_VERSION_MAJOR * 0x10000 | + HTTP_PARSER_VERSION_MINOR * 0x00100 | + HTTP_PARSER_VERSION_PATCH * 0x00001; +} + +void +c_nio_http_parser_set_max_header_size(uint32_t size) { + max_header_size = size; +} diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/CNIOHTTPParser.h b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/CNIOHTTPParser.h new file mode 100644 index 00000000..1d25103d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/CNIOHTTPParser.h @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// adaptions for http_parser to make it more straightforward to use from Swift + +#ifndef C_NIO_HTTP_PARSER_SWIFT +#define C_NIO_HTTP_PARSER_SWIFT + +#include "c_nio_http_parser.h" + +static inline size_t c_nio_http_parser_execute_swift(http_parser *parser, + const http_parser_settings *settings, + const void *data, + size_t len) { + return c_nio_http_parser_execute(parser, settings, (const char *)data, len); +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/c_nio_http_parser.h b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/c_nio_http_parser.h new file mode 100644 index 00000000..cab2f536 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOHTTPParser/Sources/CNIOHTTPParser/include/c_nio_http_parser.h @@ -0,0 +1,452 @@ +/* Additional changes for SwiftNIO: + - prefixed all symbols by 'c_nio_' +*/ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef http_parser_h +#define http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + +/* Also update SONAME in the Makefile whenever you change these. */ +#define HTTP_PARSER_VERSION_MAJOR 2 +#define HTTP_PARSER_VERSION_MINOR 9 +#define HTTP_PARSER_VERSION_PATCH 4 + +#include +#if defined(_WIN32) && !defined(__MINGW32__) && \ + (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#include +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#elif (defined(__sun) || defined(__sun__)) && defined(__SunOS_5_9) +#include +#else +#include +#endif + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef HTTP_PARSER_STRICT +# define HTTP_PARSER_STRICT 1 +#endif + +/* Maximium header size allowed. If the macro is not defined + * before including this header then the default is used. To + * change the maximum header size, define the macro in the build + * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove + * the effective limit on the size of the header, define the macro + * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) + */ +#ifndef HTTP_MAX_HEADER_SIZE +# define HTTP_MAX_HEADER_SIZE (80*1024) +#endif + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * Returning `2` from on_headers_complete will tell parser that it should not + * expect neither a body nor any futher responses on this connection. This is + * useful for handling responses to a CONNECT request which may not contain + * `Upgrade` or `Connection: upgrade` headers. + * + * http_data_cb does not return data chunks. It will be called arbitrarily + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Status Codes */ +#define HTTP_STATUS_MAP(XX) \ + XX(100, CONTINUE, Continue) \ + XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ + XX(102, PROCESSING, Processing) \ + XX(200, OK, OK) \ + XX(201, CREATED, Created) \ + XX(202, ACCEPTED, Accepted) \ + XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ + XX(204, NO_CONTENT, No Content) \ + XX(205, RESET_CONTENT, Reset Content) \ + XX(206, PARTIAL_CONTENT, Partial Content) \ + XX(207, MULTI_STATUS, Multi-Status) \ + XX(208, ALREADY_REPORTED, Already Reported) \ + XX(226, IM_USED, IM Used) \ + XX(300, MULTIPLE_CHOICES, Multiple Choices) \ + XX(301, MOVED_PERMANENTLY, Moved Permanently) \ + XX(302, FOUND, Found) \ + XX(303, SEE_OTHER, See Other) \ + XX(304, NOT_MODIFIED, Not Modified) \ + XX(305, USE_PROXY, Use Proxy) \ + XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \ + XX(308, PERMANENT_REDIRECT, Permanent Redirect) \ + XX(400, BAD_REQUEST, Bad Request) \ + XX(401, UNAUTHORIZED, Unauthorized) \ + XX(402, PAYMENT_REQUIRED, Payment Required) \ + XX(403, FORBIDDEN, Forbidden) \ + XX(404, NOT_FOUND, Not Found) \ + XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \ + XX(406, NOT_ACCEPTABLE, Not Acceptable) \ + XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \ + XX(408, REQUEST_TIMEOUT, Request Timeout) \ + XX(409, CONFLICT, Conflict) \ + XX(410, GONE, Gone) \ + XX(411, LENGTH_REQUIRED, Length Required) \ + XX(412, PRECONDITION_FAILED, Precondition Failed) \ + XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \ + XX(414, URI_TOO_LONG, URI Too Long) \ + XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \ + XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \ + XX(417, EXPECTATION_FAILED, Expectation Failed) \ + XX(421, MISDIRECTED_REQUEST, Misdirected Request) \ + XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \ + XX(423, LOCKED, Locked) \ + XX(424, FAILED_DEPENDENCY, Failed Dependency) \ + XX(426, UPGRADE_REQUIRED, Upgrade Required) \ + XX(428, PRECONDITION_REQUIRED, Precondition Required) \ + XX(429, TOO_MANY_REQUESTS, Too Many Requests) \ + XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \ + XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \ + XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \ + XX(501, NOT_IMPLEMENTED, Not Implemented) \ + XX(502, BAD_GATEWAY, Bad Gateway) \ + XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \ + XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \ + XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \ + XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \ + XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ + XX(508, LOOP_DETECTED, Loop Detected) \ + XX(510, NOT_EXTENDED, Not Extended) \ + XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ + +enum http_status + { +#define XX(num, name, string) HTTP_STATUS_##name = num, + HTTP_STATUS_MAP(XX) +#undef XX + }; + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* WebDAV */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + /* subversion */ \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + /* upnp */ \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + /* CalDAV */ \ + XX(30, MKCALENDAR, MKCALENDAR) \ + /* RFC-2068, section 19.6.1.2 */ \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + /* icecast */ \ + XX(33, SOURCE, SOURCE) \ + +enum http_method + { +#define XX(num, name, string) HTTP_##name = num, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_CONNECTION_UPGRADE = 1 << 3 + , F_TRAILING = 1 << 4 + , F_UPGRADE = 1 << 5 + , F_SKIPBODY = 1 << 6 + , F_CONTENTLENGTH = 1 << 7 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ +#define HTTP_ERRNO_MAP(XX) \ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + XX(CB_status, "the on_status callback failed") \ + XX(CB_chunk_header, "the on_chunk_header callback failed") \ + XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(UNEXPECTED_CONTENT_LENGTH, \ + "unexpected content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") \ + XX(INVALID_TRANSFER_ENCODING, \ + "request has invalid transfer-encoding") \ + + +/* Define HPE_* values for each errno value above */ +#define HTTP_ERRNO_GEN(n, s) HPE_##n, +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; +#undef HTTP_ERRNO_GEN + + +/* Get an http_errno value from an http_parser */ +#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) + + +struct http_parser { + /** PRIVATE **/ + unsigned int type : 2; /* enum http_parser_type */ + unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ + unsigned int state : 7; /* enum state from http_parser.c */ + unsigned int header_state : 7; /* enum header_state from http_parser.c */ + unsigned int index : 5; /* index into current matcher */ + unsigned int uses_transfer_encoding : 1; /* Transfer-Encoding header is present */ + unsigned int allow_chunked_length : 1; /* Allow headers with both + * `Content-Length` and + * `Transfer-Encoding: chunked` set */ + unsigned int lenient_http_headers : 1; + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body. `(uint64_t) -1` (all bits one) + * if no Content-Length header. + */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned int status_code : 16; /* responses only */ + unsigned int method : 8; /* requests only */ + unsigned int http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when c_nio_http_parser_execute() returns in addition to + * error checking. + */ + unsigned int upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_data_cb on_status; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + */ + http_cb on_chunk_header; + http_cb on_chunk_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for c_nio_http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +/* Returns the library version. Bits 16-23 contain the major version number, + * bits 8-15 the minor version number and bits 0-7 the patch level. + * Usage example: + * + * unsigned long version = c_nio_http_parser_version(); + * unsigned major = (version >> 16) & 255; + * unsigned minor = (version >> 8) & 255; + * unsigned patch = version & 255; + * printf("http_parser v%u.%u.%u\n", major, minor, patch); + */ +unsigned long c_nio_http_parser_version(void); + +void c_nio_http_parser_init(http_parser *parser, enum http_parser_type type); + + +/* Initialize http_parser_settings members to 0 + */ +void c_nio_http_parser_settings_init(http_parser_settings *settings); + + +/* Executes the parser. Returns number of parsed bytes. Sets + * `parser->http_errno` on error. */ +size_t c_nio_http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If c_nio_http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int c_nio_http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *c_nio_http_method_str(enum http_method m); + +/* Returns a string version of the HTTP status code. */ +const char *c_nio_http_status_str(enum http_status s); + +/* Return a string name of the given error */ +const char *c_nio_http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *c_nio_http_errno_description(enum http_errno err); + +/* Initialize all http_parser_url members to 0 */ +void c_nio_http_parser_url_init(struct http_parser_url *u); + +/* Parse a URL; return nonzero on failure */ +int c_nio_http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void c_nio_http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int c_nio_http_body_is_final(const http_parser *parser); + +/* Change the maximum header size provided at compile time. */ +void c_nio_http_parser_set_max_header_size(uint32_t size); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/CNIOLinux.h b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/CNIOLinux.h new file mode 100644 index 00000000..79b7f03f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/CNIOLinux.h @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifndef C_NIO_LINUX_H +#define C_NIO_LINUX_H + +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "liburing_nio.h" + +// Some explanation is required here. +// +// Due to SR-6772, we cannot get Swift code to directly see any of the mmsg structures or +// functions. However, we *can* get C code built by SwiftPM to see them. For this reason we +// elect to provide a selection of shims to enable Swift code to use recv_mmsg and send_mmsg. +// Mostly this is fine, but to minimise the overhead we want the Swift code to be able to +// create the msgvec directly without requiring further memory fussiness in our C shim. +// That requires us to also construct a C structure that has the same layout as struct mmsghdr. +// +// Conveniently glibc has pretty strict ABI stability rules, and this structure is part of the +// glibc ABI, so we can just reproduce the structure definition here and feel confident that it +// will be sufficient. +// +// If SR-6772 ever gets resolved we can remove this shim. +// +// https://bugs.swift.org/browse/SR-6772 + +typedef struct { + struct msghdr msg_hdr; + unsigned int msg_len; +} CNIOLinux_mmsghdr; + +typedef struct { + struct in6_addr ipi6_addr; + unsigned int ipi6_ifindex; +} CNIOLinux_in6_pktinfo; + +int CNIOLinux_sendmmsg(int sockfd, CNIOLinux_mmsghdr *msgvec, unsigned int vlen, int flags); +int CNIOLinux_recvmmsg(int sockfd, CNIOLinux_mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); + +int CNIOLinux_pthread_setname_np(pthread_t thread, const char *name); +int CNIOLinux_pthread_getname_np(pthread_t thread, char *name, size_t len); + +// Non-standard socket stuff. +int CNIOLinux_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags); + +// Thread affinity stuff. +int CNIOLinux_pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset); +int CNIOLinux_pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset); +void CNIOLinux_CPU_SET(int cpu, cpu_set_t *set); +void CNIOLinux_CPU_ZERO(cpu_set_t *set); +int CNIOLinux_CPU_ISSET(int cpu, cpu_set_t *set); +int CNIOLinux_CPU_SETSIZE(); + +// cmsghdr handling +struct cmsghdr *CNIOLinux_CMSG_FIRSTHDR(const struct msghdr *); +struct cmsghdr *CNIOLinux_CMSG_NXTHDR(struct msghdr *, struct cmsghdr *); +const void *CNIOLinux_CMSG_DATA(const struct cmsghdr *); +void *CNIOLinux_CMSG_DATA_MUTABLE(struct cmsghdr *); +size_t CNIOLinux_CMSG_LEN(size_t); +size_t CNIOLinux_CMSG_SPACE(size_t); + +// awkward time_T pain +extern const int CNIOLinux_SO_TIMESTAMP; +extern const int CNIOLinux_SO_RCVTIMEO; +#endif +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/liburing_nio.h b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/liburing_nio.h new file mode 100644 index 00000000..761852c4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/include/liburing_nio.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#ifndef LIBURING_NIO_H +#define LIBURING_NIO_H + +#ifdef __linux__ + +#ifdef SWIFTNIO_USE_IO_URING + +#if __has_include() +#include +#else +#error "SWIFTNIO_USE_IO_URING specified but liburing.h not available. You need to install https://github.com/axboe/liburing." +#endif + +// OR in the IOSQE_IO_LINK flag, couldn't access the define from Swift +void CNIOLinux_io_uring_set_link_flag(struct io_uring_sqe *sqe); + +// No way I managed to get this even when defining _GNU_SOURCE properly. Argh. +unsigned int CNIOLinux_POLLRDHUP(); + +#endif + +#endif /* __linux__ */ + +#endif /* LIBURING_NIO_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/liburing_shims.c b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/liburing_shims.c new file mode 100644 index 00000000..e66656ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/liburing_shims.c @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// Support functions for liburing + +// Check if this is needed, copied from shim.c to avoid possible problems due to: +// Xcode's Archive builds with Xcode's Package support struggle with empty .c files +// (https://bugs.swift.org/browse/SR-12939). +void CNIOLinux_i_do_nothing_just_working_around_a_darwin_toolchain_bug2(void) {} + +#ifdef __linux__ + +#ifdef SWIFTNIO_USE_IO_URING + +#define _GNU_SOURCE +#include +#include +#include + +void CNIOLinux_io_uring_set_link_flag(struct io_uring_sqe *sqe) +{ + sqe->flags |= IOSQE_IO_LINK; + return; +} + +unsigned int CNIOLinux_POLLRDHUP() +{ + return POLLRDHUP; +} + +#endif + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/shim.c b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/shim.c new file mode 100644 index 00000000..6de6f981 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOLinux/Sources/CNIOLinux/shim.c @@ -0,0 +1,152 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// Xcode's Archive builds with Xcode's Package support struggle with empty .c files +// (https://bugs.swift.org/browse/SR-12939). +void CNIOLinux_i_do_nothing_just_working_around_a_darwin_toolchain_bug(void) {} + +#ifdef __linux__ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +_Static_assert(sizeof(CNIOLinux_mmsghdr) == sizeof(struct mmsghdr), + "sizes of CNIOLinux_mmsghdr and struct mmsghdr differ"); + +_Static_assert(sizeof(CNIOLinux_in6_pktinfo) == sizeof(struct in6_pktinfo), + "sizes of CNIOLinux_in6_pktinfo and struct in6_pktinfo differ"); + +int CNIOLinux_sendmmsg(int sockfd, CNIOLinux_mmsghdr *msgvec, unsigned int vlen, int flags) { + // This is technically undefined behaviour, but it's basically fine because these types are the same size, and we + // don't think the compiler is inclined to blow anything up here. + return sendmmsg(sockfd, (struct mmsghdr *)msgvec, vlen, flags); +} + +int CNIOLinux_recvmmsg(int sockfd, CNIOLinux_mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) { + // This is technically undefined behaviour, but it's basically fine because these types are the same size, and we + // don't think the compiler is inclined to blow anything up here. + return recvmmsg(sockfd, (struct mmsghdr *)msgvec, vlen, flags, timeout); +} + +int CNIOLinux_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { + return accept4(sockfd, addr, addrlen, flags); +} + +int CNIOLinux_pthread_setname_np(pthread_t thread, const char *name) { + return pthread_setname_np(thread, name); +} + +int CNIOLinux_pthread_getname_np(pthread_t thread, char *name, size_t len) { +#ifdef __ANDROID__ + // https://android.googlesource.com/platform/bionic/+/master/libc/bionic/pthread_setname_np.cpp#51 + if (thread == pthread_self()) { + return TEMP_FAILURE_RETRY(prctl(PR_GET_NAME, name)) == -1 ? -1 : 0; + } + + char comm_name[64]; + snprintf(comm_name, sizeof(comm_name), "/proc/self/task/%d/comm", pthread_gettid_np(thread)); + int fd = TEMP_FAILURE_RETRY(open(comm_name, O_CLOEXEC | O_RDONLY)); + + if (fd == -1) return -1; + + ssize_t n = TEMP_FAILURE_RETRY(read(fd, name, len)); + close(fd); + if (n == -1) return -1; + + // The kernel adds a trailing '\n' to the /proc file, + // so this is actually the normal case for short names. + if (n > 0 && name[n - 1] == '\n') { + name[n - 1] = '\0'; + return 0; + } + + if (n >= 0 && len <= SSIZE_MAX && n == (ssize_t)len) return 1; + + name[n] = '\0'; + return 0; +#else + return pthread_getname_np(thread, name, len); +#endif +} + +int CNIOLinux_pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset) { +#ifdef __ANDROID__ + return sched_setaffinity(pthread_gettid_np(thread), cpusetsize, cpuset); +#else + return pthread_setaffinity_np(thread, cpusetsize, cpuset); +#endif +} + +int CNIOLinux_pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset) { +#ifdef __ANDROID__ + return sched_getaffinity(pthread_gettid_np(thread), cpusetsize, cpuset); +#else + return pthread_getaffinity_np(thread, cpusetsize, cpuset); +#endif +} + +void CNIOLinux_CPU_SET(int cpu, cpu_set_t *set) { + CPU_SET(cpu, set); +} + +void CNIOLinux_CPU_ZERO(cpu_set_t *set) { + CPU_ZERO(set); +} + +int CNIOLinux_CPU_ISSET(int cpu, cpu_set_t *set) { + return CPU_ISSET(cpu, set); +} + +int CNIOLinux_CPU_SETSIZE() { + return CPU_SETSIZE; +} + +struct cmsghdr *CNIOLinux_CMSG_FIRSTHDR(const struct msghdr *mhdr) { + assert(mhdr != NULL); + return CMSG_FIRSTHDR(mhdr); +} + +struct cmsghdr *CNIOLinux_CMSG_NXTHDR(struct msghdr *mhdr, struct cmsghdr *cmsg) { + assert(mhdr != NULL); + assert(cmsg != NULL); + return CMSG_NXTHDR(mhdr, cmsg); +} + +const void *CNIOLinux_CMSG_DATA(const struct cmsghdr *cmsg) { + assert(cmsg != NULL); + return CMSG_DATA(cmsg); +} + +void *CNIOLinux_CMSG_DATA_MUTABLE(struct cmsghdr *cmsg) { + assert(cmsg != NULL); + return CMSG_DATA(cmsg); +} + +size_t CNIOLinux_CMSG_LEN(size_t payloadSizeBytes) { + return CMSG_LEN(payloadSizeBytes); +} + +size_t CNIOLinux_CMSG_SPACE(size_t payloadSizeBytes) { + return CMSG_SPACE(payloadSizeBytes); +} + +const int CNIOLinux_SO_TIMESTAMP = SO_TIMESTAMP; +const int CNIOLinux_SO_RCVTIMEO = SO_RCVTIMEO; +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOWindows/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOWindows/README.md b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/WSAStartup.c b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/WSAStartup.c new file mode 100644 index 00000000..876edb30 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/WSAStartup.c @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if defined(_WIN32) + +#include + +#include + +#pragma section(".CRT$XCU", read) + +static void __cdecl +NIOWSAStartup(void) { + WSADATA wsa; + WORD wVersionRequested = MAKEWORD(2, 2); + if (!WSAStartup(wVersionRequested, &wsa)) { + _exit(EXIT_FAILURE); + } +} + +__declspec(allocate(".CRT$XCU")) +static void (*pNIOWSAStartup)(void) = &NIOWSAStartup; + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/include/CNIOWindows.h b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/include/CNIOWindows.h new file mode 100644 index 00000000..3978b6de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/include/CNIOWindows.h @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#ifndef C_NIO_WINDOWS_H +#define C_NIO_WINDOWS_H + +#if defined(_WIN32) + +#include +#include +#include + +#define NIO(name) CNIOWindows_ ## name + +// This is a DDK type which is not available in the WinSDK as it is not part of +// the shared, usermode (um), or ucrt portions of the code. We must replicate +// this datastructure manually from the MSDN references or the DDK. +// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_reparse_data_buffer +typedef struct NIO(_REPARSE_DATA_BUFFER) { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparsaeBuffer; + } DUMMYUNIONNAME; +} NIO(REPARSE_DATA_BUFFER), *NIO(PREPARSE_DATA_BUFFER); + +typedef struct { + WSAMSG msg_hdr; + unsigned int msg_len; +} NIO(mmsghdr); + +static inline __attribute__((__always_inline__)) int +NIO(getsockopt)(SOCKET s, int level, int optname, void *optval, int *optlen) { + return getsockopt(s, level, optname, optval, optlen); +} + +static inline __attribute__((__always_inline__)) int +NIO(recv)(SOCKET s, void *buf, int len, int flags) { + return recv(s, buf, len, flags); +} + +static inline __attribute__((__always_inline__)) int +NIO(recvfrom)(SOCKET s, void *buf, int len, int flags, SOCKADDR *from, + int *fromlen) { + return recvfrom(s, buf, len, flags, from, fromlen); +} + +static inline __attribute__((__always_inline__)) int +NIO(send)(SOCKET s, const void *buf, int len, int flags) { + return send(s, buf, len, flags); +} + +static inline __attribute__((__always_inline__)) int +NIO(setsockopt)(SOCKET s, int level, int optname, const void *optval, + int optlen) { + return setsockopt(s, level, optname, optval, optlen); +} + +static inline __attribute__((__always_inline__)) int +NIO(sendto)(SOCKET s, const void *buf, int len, int flags, const SOCKADDR *to, + int tolen) { + return sendto(s, buf, len, flags, to, tolen); +} + +int NIO(sendmmsg)(SOCKET s, NIO(mmsghdr) *msgvec, unsigned int vlen, int flags); + +int NIO(recvmmsg)(SOCKET s, NIO(mmsghdr) *msgvec, unsigned int vlen, int flags, + struct timespec *timeout); + + +const void *NIO(CMSG_DATA)(const WSACMSGHDR *); +void *NIO(CMSG_DATA_MUTABLE)(LPWSACMSGHDR); + +WSACMSGHDR *NIO(CMSG_FIRSTHDR)(const WSAMSG *); +WSACMSGHDR *NIO(CMSG_NXTHDR)(const WSAMSG *, LPWSACMSGHDR); + +size_t NIO(CMSG_LEN)(size_t); +size_t NIO(CMSG_SPACE)(size_t); + +#undef NIO + +#endif + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/shim.c b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/shim.c new file mode 100644 index 00000000..b3c85240 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CNIOWindows/Sources/CNIOWindows/shim.c @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if defined(_WIN32) + +#include "CNIOWindows.h" + +#include + +int CNIOWindows_sendmmsg(SOCKET s, CNIOWindows_mmsghdr *msgvec, unsigned int vlen, + int flags) { + assert(!"sendmmsg not implemented"); + abort(); +} + +int CNIOWindows_recvmmsg(SOCKET s, CNIOWindows_mmsghdr *msgvec, + unsigned int vlen, int flags, + struct timespec *timeout) { + assert(!"recvmmsg not implemented"); + abort(); +} + +const void *CNIOWindows_CMSG_DATA(const WSACMSGHDR *pcmsg) { + return WSA_CMSG_DATA(pcmsg); +} + +void *CNIOWindows_CMSG_DATA_MUTABLE(LPWSACMSGHDR pcmsg) { + return WSA_CMSG_DATA(pcmsg); +} + +WSACMSGHDR *CNIOWindows_CMSG_FIRSTHDR(const WSAMSG *msg) { + return WSA_CMSG_FIRSTHDR(msg); +} + +WSACMSGHDR *CNIOWindows_CMSG_NXTHDR(const WSAMSG *msg, LPWSACMSGHDR cmsg) { + return WSA_CMSG_NXTHDR(msg, cmsg); +} + +size_t CNIOWindows_CMSG_LEN(size_t length) { + return WSA_CMSG_LEN(length); +} + +size_t CNIOWindows_CMSG_SPACE(size_t length) { + return WSA_CMSG_SPACE(length); +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/LICENSE b/one-and-half-nibble/MobileApp/Pods/Cadence/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/README.md b/one-and-half-nibble/MobileApp/Pods/Cadence/README.md new file mode 100644 index 00000000..dd99adc4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/README.md @@ -0,0 +1,594 @@ +![Flow Swift SDK](./images/logo.jpg) + + + + + +The Flow Swift SDK provides Swift developers to build decentralized apps on Apple devices that interact with the Flow blockchain. + +# Getting Started + +## Installation + +### CocoaPods + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '13.0' +use_frameworks! + +target 'ExampleApp' do + pod 'FlowSDK', '~> 0.5.0' +end +``` + +### Swift Package Manager + +- File > Swift Packages > Add Package Dependency +- Add `https://github.com/portto/flow-swift-sdk.git` +- Select "Up to Next Major" with "0.5.0" + +# Usage + +Before sending out any transactions, please install [flow-cli](https://docs.onflow.org/flow-cli/install/) and [start emulator](https://docs.onflow.org/flow-cli/start-emulator/) first. + +Check out [Flow Access API Specification](https://docs.onflow.org/access-api/) for all apis. + +## Generating Key + +Flow blockchain uses ECDSA with SHA2-256 or SHA3-256 to grant access to control user accounts. + +Create a random private key for P256 and secp256k1 curve: +```swift +import FlowSDK + +let privateKey1 = try PrivateKey(signatureAlgorithm: .ecdsaP256) +let privateKey2 = try PrivateKey(signatureAlgorithm: .ecdsaSecp256k1) +``` + +A private key has an accompanying public key: +```swift +let publicKey = privateKey.publicKey +``` + +## Creating an Account + +You must start emulator to send this transaction. Once you have a key pair, you can create a new account using: +```swift +import FlowSDK +import BigInt + +// Generate a new private key +let privateKey = try PrivateKey(signatureAlgorithm: .ecdsaSecp256k1) + +// Get the public key +let publicKey = privateKey.publicKey + +// Get flow grpc client +let client = Client(network: .emulator) + +// Define creating account script +let script = """ +import Crypto + +transaction(publicKey: PublicKey, hashAlgorithm: HashAlgorithm, weight: UFix64) { + prepare(signer: AuthAccount) { + let account = AuthAccount(payer: signer) + + // add a key to the account + account.keys.add(publicKey: publicKey, hashAlgorithm: hashAlgorithm, weight: weight) + } +} +""" + +// Get service account info +let (payerAccount, payerAccountKey, payerSigner) = try await serviceAccount(client: client) + +// Get latest reference block id +let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id + +// Define creating account transaction +var transaction = try Transaction( + script: script.data(using: .utf8)!, + arguments: [ + publicKey.cadenceArugment, + HashAlgorithm.sha3_256.cadenceArugment, + .ufix64(1000) + ], + referenceBlockId: referenceBlockId!, + gasLimit: 100, + proposalKey: .init( + address: payerAccount.address, + keyIndex: payerAccountKey.index, + sequenceNumber: payerAccountKey.sequenceNumber), + payer: payerAccount.address, + authorizers: [payerAccount.address]) + +// Sign transaction +try transaction.signEnvelope( + address: payerAccount.address, + keyIndex: payerAccountKey.index, + signer: payerSigner) + +// Send out transaction +let txId = try await client.sendTransaction(transaction: transaction) + +// Get transaction result +var result: TransactionResult? +while result?.status != .sealed { + result = try await client.getTransactionResult(id: txId) + sleep(3) +} +debugPrint(result) + +private func serviceAccount(client: Client) async throws -> (account: Account, accountKey: AccountKey, signer: InMemorySigner) { + let serviceAddress = Address(hexString: "f8d6e0586b0a20c7") + let serviceAccount = try await client.getAccountAtLatestBlock(address: serviceAddress)! + let servicePrivateKey = try PrivateKey( + data: Data(hex: "7aac2988c5c3df3325d8cd679563cc974271f9505245da53e887fa3cc36c064f"), + signatureAlgorithm: .ecdsaP256) + let servicePublicKey = servicePrivateKey.publicKey + let serviceAccountKeyIndex = serviceAccount.keys.firstIndex(where: { $0.publicKey == servicePublicKey })! + let serviceAccountKey = serviceAccount.keys[serviceAccountKeyIndex] + let signer = InMemorySigner(privateKey: servicePrivateKey, hashAlgorithm: .sha3_256) + return (account: serviceAccount, accountKey: serviceAccountKey, signer: signer) +} +``` + +## Signing a Transaction + +Below is a simple transaction of printing "Hello World!" +```swift +import FlowSDK + +let myAddress: Address +let myAccountKey: AccountKey +let myPrivateKey: PrivateKey + +// Get flow grpc client +let client = Client(network: .emulator) + +// Get latest reference block id +let referenceBlockId = try await client.getLatestBlock(isSealed: true)!.id + +var transaction = Transaction( + script: "transaction { execute { log(\"Hello, World!\") } }".data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: myAddress, + keyIndex: myAccountKey.index, + sequenceNumber: myAccountKey.sequenceNumber), + payer: myAddress) +``` + +Transaction signing is done through the Signer protocol. The simplest (and least secure) implementation of Signer is InMemorySigner. +```swift +// create a signer from your private key and configured hash algorithm +let mySigner = InMemorySigner(privateKey: myPrivateKey, hashAlgorithm: myAccountKey.hashAlgorithm) + +try transaction.signEnvelope( + address: myAddress, + keyIndex: myAccountKey.index, + signer: mySigner) +``` + +Flow introduces new concepts that allow for more flexibility when creating and signing transactions. Before trying the examples below, we recommend that you read through the [transaction signature documentation](https://github.com/onflow/flow/blob/master/docs/content/concepts/accounts-and-keys.md#signing-a-transaction). + +### [Single party, single signature](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#single-party-single-signature) + +- Proposer, payer and authorizer are the same account (`0x01`). +- Only the envelope must be signed. +- Proposal key must have full signing weight. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +let key1 = account1.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account1.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signEnvelope(address: account1.address, keyIndex: key1.index, signer: key1Signer) +``` + +### [Single party, multiple signatures](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#single-party-multiple-signatures) + +- Proposer, payer and authorizer are the same account (`0x01`). +- Only the envelope must be signed. +- Each key has weight 500, so two signatures are required. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 500 | +| `0x01` | 2 | 500 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +let key1 = account1.keys[0] +let key2 = account1.keys[1] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key2Signer: Signer = getSignerForKey2() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account1.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signEnvelope(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 1 signs the envelope with key 2 +try transaction.signEnvelope(address: account1.address, keyIndex: key2.index, signer: key2Signer) +``` + +### [Multiple parties](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | +| `0x02` | 3 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key3 = account2.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key3Signer: Signer = getSignerForKey3() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 2 signs the envelope with key 3 +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) +``` + +### [Multiple parties, two authorizers](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. +- Account `0x02` is also an authorizer to show how to include two AuthAccounts into an transaction + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | +| `0x02` | 3 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key3 = account2.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key3Signer: Signer = getSignerForKey3() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer1: AuthAccount, signer2: AuthAccount) { + log(signer.address) + log(signer2.address) + } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address, account2.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 2 signs the envelope with key 3 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) +``` + +### [Multiple parties, multiple signatures](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties-multiple-signatures) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. +- Both accounts must sign twice (once with each of their keys). + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 500 | +| `0x01` | 2 | 500 | +| `0x02` | 3 | 500 | +| `0x02` | 4 | 500 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key2 = account1.keys[1] +let key3 = account2.keys[0] +let key4 = account2.keys[1] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key2Signer: Signer = getSignerForKey2() +let key3Signer: Signer = getSignerForKey3() +let key4Signer: Signer = getSignerForKey4() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 1 signs the payload with key 2 +try transaction.signPayload(address: account1.address, keyIndex: key2.index, signer: key2Signer) + +// account 2 signs the envelope with key 3 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) + +// account 2 signs the envelope with key 4 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key4.index, signer: key4Signer) +``` + +## Sending a Transaction + +You can submit a transaction to the network using the Access API client. +```swift +import FlowSDK + +let client = Client(host: "localhost", port: 3569) +// or +// let client = Client(network: .emulator) + +try await client.sendTransaction(transaction: transaction) +``` + +## Querying Transaction Results +After you have submitted a transaction, you can query its status by transaction ID: +```swift +let result = try await client.getTransactionResult(id: txId) +``` + +`result.status` will be one of the following values: +- unknown +- pending +- finalized +- executed +- sealed +- expired + +Check out [the documentation](https://docs.onflow.org/fcl/reference/api/#transaction-statuses) for more details. + +## Executing a Script +You can use the `executeScriptAtLatestBlock` method to execute a read-only script against the latest sealed execution state. + +Here is a simple script with a single return value: +```cadence +pub fun main(): UInt64 { + return 1 as UInt64 +} +``` + +Run script and decode as Swift type: +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let script = """ +pub fun main(): UInt64 { + return 1 as UInt64 +} +""" + +let cadenceValue: Cadence.Value = try await client.executeScriptAtLatestBlock(script: script.data(using: .utf8)!) +let value: UInt64 = try cadenceValue.toSwiftValue() +``` + +## Querying Blocks + +You can use the `getLatestBlock` method to fetch the latest block with sealed boolean flag: + +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let isSealed: Bool = true +let block = try await client.getLatestBlock(isSealed: isSealed) +``` + +Block contains BlockHeader and BlockPayload. BlockHeader contains the following fields: +- id: the ID (hash) of the block +- parentId: the ID of the previous block. +- height: the height of the block. +- timestamp: the block timestamp. + +BlockPayload contains the folowing fields: +- collectionGuarantees: an attestation signed by the nodes that have guaranteed a collection. +- seals: the attestation by verification nodes that the transactions in a previously executed block have been verified. + +## Querying Events + +You can use the `getEventsForHeightRange` method to query events. + +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let events: [BlockEvents] = try await client.getEventsForHeightRange( + eventType: "flow.AccountCreated", + startHeight: 10, + endHeight: 15) +``` + +### Event Type + +An event type contains the following fields: + +The event type to filter by. Event types are namespaced by the account and contract in which they are declared. + +For example, a `Transfer` event that was defined in the `Token` contract deployed at account `0x55555555555555555555` will have a type of `A.0x55555555555555555555.Token.Transfer`. + +Read the [language documentation](https://docs.onflow.org/cadence/language/events/) for more information on how to define and emit events in Cadence. + +### Querying Accounts + +You can use getAccountAtLatestBlock to query the state of an account. + +```swift +let client = Client(network: .testnet) + +let address = Address(hexString: "0xcb2d04fc89307107") +let account = try await client.getAccountAtLatestBlock(address: address) +``` + +An `Account` contains the following fields: +- address: the account address. +- balance: the account balance. +- keys: a list of the public keys associated with this account. +- contracts: the contract code deployed at this account. + +# Examples + +Check out [example](./example/) that how to use the SDK to interact wit Flow blockchain. + +# Development + +This repo was inspired from [flow-go-sdk](https://github.com/onflow/flow-go-sdk) and make it more Swifty. + +## Generate protobuf swift files + +``` +make install +make generate-protobuf +``` + +# License + +Flow Swift SDK is available under the Apache 2.0 license. Same with [gRPC-Swift](https://github.com/grpc/grpc-swift). diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Address.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Address.swift new file mode 100644 index 00000000..938d921c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Address.swift @@ -0,0 +1,93 @@ +// +// Address.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// [n,k,d]-Linear code parameters +/// The linear code used in the account addressing is a [64,45,7] +/// It generates a [64,45]-code, which is the space of Flow account addresses. +/// +/// n is the size of the code words in bits, +/// which is also the size of the account addresses in bits. +private let linearCodeN = 64 + +public struct Address: Equatable, Hashable { + + /// the size of an account address in bytes. + public static let length = (linearCodeN + 7) >> 3 + + public static let emptyAddress = Address(data: Data()) + + public let data: Data + + public var bytes: [UInt8] { + data.bytes + } + + public var hexString: String { + data.toHexString() + } + + public var hexStringWithPrefix: String { + var result = "0x" + if data.count < Self.length { + let zeroPadding = Data(repeating: 0, count: Self.length - data.count) + result += zeroPadding.toHexString() + } + result += data.toHexString() + return result + } + + /// If b is larger than 8, b will be cropped from the left. + /// If b is smaller than 8, b will be appended by zeroes at the front. + public init(data: Data) { + self.data = data.normalized + } + + public init(hexString: String) { + self.init(data: Data(hex: hexString.fixedHexString)) + } +} + +// MARK: - Codable +extension Address: Codable { + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode(description) + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + data = try container.decodeHexString().normalized + } +} + +// MARK: - CustomStringConvertible + +extension Address: CustomStringConvertible { + + public var description: String { + "0x" + hexString + } +} + +// MARK: - Data + +private extension Data { + + var normalized: Data { + switch count { + case 0..(decodableType: T.Type = T.self) throws -> T { + try value.toSwiftValue(decodableType: decodableType) + } + + public func toSwiftValue(decodableType: Optional.Type = Optional.self) throws -> T? { + try value.toSwiftValue(decodableType: decodableType) + } +} + +// MARK: - Static Function + +extension Argument { + + public static func decode(data: Data) throws -> Self { + let decoder = JSONDecoder() + decoder.userInfo[.decodingResults] = FTypeDecodingResults() + return try decoder.decode(Self.self, from: data) + } +} + +// MARK: - Convenience + +extension Argument { + + public static var void: Argument { + Argument(.void) + } + + public static func optional(_ value: Argument?) -> Argument { + Argument(.optional(value)) + } + + public static func bool(_ value: Bool) -> Argument { + Argument(.bool(value)) + } + + public static func string(_ value: String) -> Argument { + Argument(.string(value)) + } + + public static func address(_ value: Address) -> Argument { + Argument(.address(value)) + } + + public static func int(_ value: BigInt) -> Argument { + Argument(.int(value)) + } + + public static func uint(_ value: BigUInt) -> Argument { + Argument(.uint(value)) + } + + public static func int8(_ value: Int8) -> Argument { + Argument(.int8(value)) + } + + public static func uint8(_ value: UInt8) -> Argument { + Argument(.uint8(value)) + } + + public static func int16(_ value: Int16) -> Argument { + Argument(.int16(value)) + } + + public static func uint16(_ value: UInt16) -> Argument { + Argument(.uint16(value)) + } + + public static func int32(_ value: Int32) -> Argument { + Argument(.int32(value)) + } + + public static func uint32(_ value: UInt32) -> Argument { + Argument(.uint32(value)) + } + + public static func int64(_ value: Int64) -> Argument { + Argument(.int64(value)) + } + + public static func uint64(_ value: UInt64) -> Argument { + Argument(.uint64(value)) + } + + public static func int128(_ value: BigInt) -> Argument { + Argument(.int128(value)) + } + + public static func uint128(_ value: BigUInt) -> Argument { + Argument(.uint128(value)) + } + + public static func int256(_ value: BigInt) -> Argument { + Argument(.int256(value)) + } + + public static func uint256(_ value: BigUInt) -> Argument { + Argument(.uint256(value)) + } + + public static func word8(_ value: UInt8) -> Argument { + Argument(.word8(value)) + } + + public static func word16(_ value: UInt16) -> Argument { + Argument(.word16(value)) + } + + public static func word32(_ value: UInt32) -> Argument { + Argument(.word32(value)) + } + + public static func word64(_ value: UInt64) -> Argument { + Argument(.word64(value)) + } + + public static func fix64(_ value: Decimal) -> Argument { + Argument(.fix64(value)) + } + + public static func ufix64(_ value: Decimal) -> Argument { + Argument(.ufix64(value)) + } + + public static func array(_ value: [Argument]) -> Argument { + Argument(.array(value)) + } + + public static func array(_ value: Argument...) -> Argument { + Argument(.array(value)) + } + + public static func dictionary(_ value: [Dictionary]) -> Argument { + Argument(.dictionary(value)) + } + + public static func dictionary(_ value: Dictionary...) -> Argument { + Argument(.dictionary(value)) + } + + public static func `struct`(_ value: CompositeStruct) -> Argument { + Argument(.struct(value)) + } + + public static func `struct`(id: String, fields: [Composite.Field]) -> Argument { + Argument(.struct(.init(id: id, fields: fields))) + } + + public static func resource(_ value: CompositeStruct) -> Argument { + Argument(.resource(value)) + } + + public static func resource(id: String, fields: [Composite.Field]) -> Argument { + Argument(.resource(.init(id: id, fields: fields))) + } + + public static func event(_ value: CompositeStruct) -> Argument { + Argument(.event(value)) + } + + public static func event(id: String, fields: [Composite.Field]) -> Argument { + Argument(.event(.init(id: id, fields: fields))) + } + + public static func contract(_ value: CompositeStruct) -> Argument { + Argument(.contract(value)) + } + + public static func contract(id: String, fields: [Composite.Field]) -> Argument { + Argument(.contract(.init(id: id, fields: fields))) + } + + public static func `enum`(_ value: CompositeStruct) -> Argument { + Argument(.enum(value)) + } + + public static func `enum`(id: String, fields: [Composite.Field]) -> Argument { + Argument(.enum(.init(id: id, fields: fields))) + } + + public static func path(_ value: Path) -> Argument { + Argument(.path(value)) + } + + public static func path(domain: Path.Domain, identifier: String) -> Argument { + Argument(.path(Path(domain: domain, identifier: identifier))) + } + + public static func type(_ value: StaticTypeValue) -> Argument { + Argument(.type(value)) + } + + public static func type(staticType: FType) -> Argument { + Argument(.type(.init(staticType: staticType))) + } + + public static func capability(_ value: Capability) -> Argument { + Argument(.capability(value)) + } + + public static func capability(path: String, address: Address, borrowType: FType) -> Argument { + Argument(.capability(Capability(path: path, address: address, borrowType: borrowType))) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/CompositeType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/CompositeType.swift new file mode 100644 index 00000000..3c9d9036 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/CompositeType.swift @@ -0,0 +1,60 @@ +// +// CompositeType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public class CompositeType: Codable { + public let type: String + public let typeId: String + public var initializers: [InitializerType] + public var fields: [FieldType] + + public init( + type: String, + typeId: String, + initializers: [InitializerType], + fields: [FieldType] + ) { + self.type = type + self.typeId = typeId + self.initializers = initializers + self.fields = fields + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case type + case typeId = "typeID" + case initializers + case fields + } + + required public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.type = try container.decode(String.self, forKey: .type) + self.typeId = try container.decode(String.self, forKey: .typeId) + self.initializers = [] // must call decodePossibleRepeatedProperties later + self.fields = [] // must call decodePossibleRepeatedProperties later + } + + public func decodeFieldTypes(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + initializers = try container.decode([InitializerType].self, forKey: .initializers) + fields = try container.decode([FieldType].self, forKey: .fields) + } +} + +// MARK: - Equatable + +extension CompositeType: Equatable { + + public static func == (lhs: CompositeType, rhs: CompositeType) -> Bool { + lhs.type == rhs.type && + lhs.typeId == rhs.typeId + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/EnumType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/EnumType.swift new file mode 100644 index 00000000..767342ef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/EnumType.swift @@ -0,0 +1,62 @@ +// +// EnumType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public class EnumType: Codable { + + public var type: FType + public let typeId: String + public var initializers: [InitializerType] + public var fields: [FieldType] + + public init( + type: FType, + typeId: String, + initializers: [InitializerType] = [], + fields: [FieldType] + ) { + self.type = type + self.typeId = typeId + self.initializers = initializers + self.fields = fields + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case type + case typeId = "typeID" + case initializers + case fields + } + + required public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.type = .bool // must call decodePossibleRepeatedProperties later + self.typeId = try container.decode(String.self, forKey: .typeId) + self.initializers = [] // must call decodePossibleRepeatedProperties later + self.fields = [] // must call decodePossibleRepeatedProperties later + } + + public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + initializers = try container.decode([InitializerType].self, forKey: .initializers) + fields = try container.decode([FieldType].self, forKey: .fields) + } +} + +// MARK: - Equatable + +extension EnumType: Equatable { + + public static func == (lhs: EnumType, rhs: EnumType) -> Bool { + lhs.type == rhs.type && + lhs.typeId == rhs.typeId + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FieldType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FieldType.swift new file mode 100644 index 00000000..96a0d70f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FieldType.swift @@ -0,0 +1,18 @@ +// +// FieldType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct FieldType: Equatable, Codable { + public let id: String + public let type: FType + + public init(id: String, type: FType) { + self.id = id + self.type = type + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FunctionType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FunctionType.swift new file mode 100644 index 00000000..97857117 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/FunctionType.swift @@ -0,0 +1,56 @@ +// +// FunctionType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public class FunctionType: Codable { + public let typeId: String + public var parameters: [ParameterType] + public var `return`: FType + + public init( + typeId: String, + parameters: [ParameterType] = [], + return: FType = .void + ) { + self.typeId = typeId + self.parameters = parameters + self.return = `return` + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case typeId = "typeID" + case parameters + case `return` + } + + required public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.typeId = try container.decode(String.self, forKey: .typeId) + self.parameters = [] // must call decodePossibleRepeatedProperties later + self.return = .bool // must call decodePossibleRepeatedProperties later + } + + public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + parameters = try container.decode([ParameterType].self, forKey: .parameters) + `return` = try container.decodeFType(userInfo: decoder.userInfo, forKey: .return) + } +} + +// MARK: - Equatable + +extension FunctionType: Equatable { + + public static func == (lhs: FunctionType, rhs: FunctionType) -> Bool { + lhs.typeId == rhs.typeId && + lhs.parameters == rhs.parameters && + lhs.return == rhs.return + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/InitializerType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/InitializerType.swift new file mode 100644 index 00000000..2efc4732 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/InitializerType.swift @@ -0,0 +1,10 @@ +// +// InitializerType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public typealias InitializerType = [ParameterType] diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ParameterType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ParameterType.swift new file mode 100644 index 00000000..619092e1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ParameterType.swift @@ -0,0 +1,24 @@ +// +// ParameterType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct ParameterType: Equatable, Codable { + public let label: String + public let id: String + public let type: FType + + public init( + label: String, + id: String, + type: FType + ) { + self.label = label + self.id = id + self.type = type + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ReferenceType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ReferenceType.swift new file mode 100644 index 00000000..72c697fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/ReferenceType.swift @@ -0,0 +1,18 @@ +// +// ReferenceType.swift +// +// Created by Scott on 2022/6/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct ReferenceType: Equatable, Codable { + public let authorized: Bool + public let type: FType + + public init(authorized: Bool, type: FType) { + self.authorized = authorized + self.type = type + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/RestrictionType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/RestrictionType.swift new file mode 100644 index 00000000..4b2f08e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/CType/RestrictionType.swift @@ -0,0 +1,55 @@ +// +// RestrictionType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public class RestrictionType: Codable { + public let typeId: String + public var type: FType + public var restrictions: [FType] + + public init( + typeId: String, + type: FType, + restrictions: [FType] + ) { + self.typeId = typeId + self.type = type + self.restrictions = restrictions + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case typeId = "typeID" + case type + case restrictions + } + + required public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.typeId = try container.decode(String.self, forKey: .typeId) + self.type = .bool // must call decodePossibleRepeatedProperties later + self.restrictions = [] // must call decodePossibleRepeatedProperties later + } + + public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + restrictions = try container.decode([FType].self, forKey: .restrictions) + } +} + +// MARK: - Equatable + +extension RestrictionType: Equatable { + + public static func == (lhs: RestrictionType, rhs: RestrictionType) -> Bool { + lhs.typeId == rhs.typeId && + lhs.type == rhs.type + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Capability.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Capability.swift new file mode 100644 index 00000000..297208a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Capability.swift @@ -0,0 +1,26 @@ +// +// Capability.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// https://docs.onflow.org/cadence/json-cadence-spec/#capability +public struct Capability: Codable, Equatable { + + public let path: String + public let address: Address + public let borrowType: FType + + public init( + path: String, + address: Address, + borrowType: FType + ) { + self.path = path + self.address = address + self.borrowType = borrowType + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Composite.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Composite.swift new file mode 100644 index 00000000..017494b0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Composite.swift @@ -0,0 +1,40 @@ +// +// Composite.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// https://docs.onflow.org/cadence/json-cadence-spec/#composites-struct-resource-event-contract-enum +public struct Composite: Codable, Equatable { + + public let id: String + public let fields: [Field] + + public init(id: String, fields: [Field]) { + self.id = id + self.fields = fields + } +} + +public typealias CompositeStruct = Composite +public typealias CompositeResource = Composite +public typealias CompositeEvent = Composite +public typealias CompositeContract = Composite +public typealias CompositeEnum = Composite + +// MARK: - Field +extension Composite { + + public struct Field: Codable, Equatable { + public let name: String + public let value: Argument + + public init(name: String, value: Argument) { + self.name = name + self.value = value + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Dictionary.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Dictionary.swift new file mode 100644 index 00000000..314dda00 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Dictionary.swift @@ -0,0 +1,20 @@ +// +// Dictionary.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// https://docs.onflow.org/cadence/json-cadence-spec/#dictionary +public struct Dictionary: Codable, Equatable { + + public let key: Argument + public let value: Argument + + public init(key: Argument, value: Argument) { + self.key = key + self.value = value + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/CodingUserInfoKeyExtension.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/CodingUserInfoKeyExtension.swift new file mode 100644 index 00000000..ff2594da --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/CodingUserInfoKeyExtension.swift @@ -0,0 +1,12 @@ +// +// File.swift +// +// Created by Scott on 2022/6/28. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +extension CodingUserInfoKey { + static let decodingResults = CodingUserInfoKey(rawValue: "decodingResults")! +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/KeyedDecodingContainerProtocolExtension.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/KeyedDecodingContainerProtocolExtension.swift new file mode 100644 index 00000000..188fc892 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/KeyedDecodingContainerProtocolExtension.swift @@ -0,0 +1,99 @@ +// +// KeyedDecodingContainerProtocolExtension.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt + +// MARK: - BigInt, BigUInt + +extension KeyedDecodingContainerProtocol { + + func decodeBigIntFromString(forKey key: Self.Key) throws -> BigInt { + let string = try decode(String.self, forKey: key) + guard let bigInt = BigInt(string) else { + throw DecodingError.dataCorruptedError( + forKey: key, + in: self, + debugDescription: "Expected BigInt string") + } + return bigInt + } + + func decodeBigUIntFromString(forKey key: Self.Key) throws -> BigUInt { + let string = try decode(String.self, forKey: key) + guard let bigUInt = BigUInt(string) else { + throw DecodingError.dataCorruptedError( + forKey: key, + in: self, + debugDescription: "Expected BigUInt string") + } + return bigUInt + } + +} + +// MARK: - Decimal + +extension KeyedDecodingContainerProtocol { + + func decodeDecimalFromString(forKey key: Self.Key) throws -> Decimal { + let string = try decode(String.self, forKey: key) + guard let decimal = Decimal(string: string) else { + throw DecodingError.dataCorruptedError( + forKey: key, + in: self, + debugDescription: "Expected Decimal string") + } + return decimal + } +} + +// MARK: - String Integer + +extension KeyedDecodingContainerProtocol { + + func decodeStringInteger( + _ type: IntegerType.Type, + forKey key: Self.Key + ) throws -> IntegerType { + let text = try decode(String.self, forKey: key) + guard let value = IntegerType(text) else { + throw DecodingError.dataCorruptedError( + forKey: key, + in: self, + debugDescription: "Expected \(IntegerType.self) string") + } + return value + } +} + +// MARK: FType + +extension KeyedDecodingContainerProtocol { + + func decodeFType( + userInfo: [CodingUserInfoKey: Any], + forKey key: Self.Key + ) throws -> FType { + if let typeId = try? decode(String.self, forKey: key) { + if let results = userInfo[.decodingResults] as? FTypeDecodingResults, + let type = results.value[typeId] { + return type + } else { + throw DecodingError.dataCorruptedError( + forKey: key, + in: self, + debugDescription: "TypeID(\(typeId)) Not found") + } + } else { + let type = try decode(FType.self, forKey: key) + return type + } + } + +} + diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/SingleValueDecodingContainerExtension.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/SingleValueDecodingContainerExtension.swift new file mode 100644 index 00000000..bf91d7d6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/SingleValueDecodingContainerExtension.swift @@ -0,0 +1,19 @@ +// +// SingleValueDecodingContainerExtension.swift +// +// Created by Scott on 2022/5/19. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import CryptoSwift + +extension SingleValueDecodingContainer { + + func decodeHexString() throws -> Data { + let hexString = try decode(String.self) + let data = Data(hex: hexString.fixedHexString) + return data + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/StringExtension.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/StringExtension.swift new file mode 100644 index 00000000..ec9fecee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Extensions/StringExtension.swift @@ -0,0 +1,57 @@ +// +// StringExtension.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +extension String { + + var fixedHexString: String { + if count % 2 == 1 { + return "0" + self + } else { + return self + } + } + + var quoteString: String { + var result = "" + result += "\"" + + unicodeScalars.forEach { char in + switch char { + case "\0": + result += #"\0"# + case "\n": + result += #"\n"# + case "\r": + result += #"\r"# + case "\t": + result += #"\t"# + case "\\": + result += #"\\"# + case "\"": + result += #"\""# + default: + if 0x20 <= char.value && char.value <= 0x7E { + // ASCII printable from space through DEL-1. + result += String(char) + } else { + let finalChar: Unicode.Scalar + if char.value > 1114111 { + finalChar = Unicode.Scalar(65533 as UInt32) ?? char + } else { + finalChar = char + } + result += finalChar.description + } + } + } + result += "\"" + return result + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FType.swift new file mode 100644 index 00000000..cf4fc568 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FType.swift @@ -0,0 +1,489 @@ +// +// FType.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum FType: Equatable { + case `any` + case anyStruct + case anyResource + case type + case void + case never + case bool + case string + case character + case bytes + case address + case number + case signedNumber + case integer + case signedInteger + case fixedPoint + case signedFixedPoint + case int + case int8 + case int16 + case int32 + case int64 + case int128 + case int256 + case uint + case uint8 + case uint16 + case uint32 + case uint64 + case uint128 + case uint256 + case word8 + case word16 + case word32 + case word64 + case fix64 + case ufix64 + case path + case capabilityPath + case storagePath + case publicPath + case privatePath + case authAccount + case publicAccount + case authAccountKeys + case publicAccountKeys + case authAccountContracts + case publicAccountContracts + case deployedContract + case accountKey + case block + indirect case optional(FType) + indirect case variableSizedArray(elementType: FType) + indirect case constantSizedArray(elementType: FType, size: Int) + indirect case dictionary(keyType: FType, elementType: FType) + indirect case `struct`(CompositeType) + indirect case resource(CompositeType) + indirect case event(CompositeType) + indirect case contract(CompositeType) + indirect case structInterface(CompositeType) + indirect case resourceInterface(CompositeType) + indirect case contractInterface(CompositeType) + indirect case function(FunctionType) + indirect case reference(ReferenceType) + indirect case restriction(RestrictionType) + indirect case capability(borrowType: FType) + indirect case `enum`(EnumType) + + public var kind: FTypeKind { + switch self { + case .any: + return .any + case .anyStruct: + return .anyStruct + case .anyResource: + return .anyResource + case .type: + return .type + case .void: + return .void + case .never: + return .never + case .bool: + return .bool + case .string: + return .string + case .character: + return .character + case .bytes: + return .bytes + case .address: + return .address + case .number: + return .number + case .signedNumber: + return .signedNumber + case .integer: + return .integer + case .signedInteger: + return .signedInteger + case .fixedPoint: + return .fixedPoint + case .signedFixedPoint: + return .signedFixedPoint + case .int: + return .int + case .int8: + return .int8 + case .int16: + return .int16 + case .int32: + return .int32 + case .int64: + return .int64 + case .int128: + return .int128 + case .int256: + return .int256 + case .uint: + return .uint + case .uint8: + return .uint8 + case .uint16: + return .uint16 + case .uint32: + return .uint32 + case .uint64: + return .uint64 + case .uint128: + return .uint128 + case .uint256: + return .uint256 + case .word8: + return .word8 + case .word16: + return .word16 + case .word32: + return .word32 + case .word64: + return .word64 + case .fix64: + return .fix64 + case .ufix64: + return .ufix64 + case .path: + return .path + case .capabilityPath: + return .capabilityPath + case .storagePath: + return .storagePath + case .publicPath: + return .publicPath + case .privatePath: + return .privatePath + case .authAccount: + return .authAccount + case .publicAccount: + return .publicAccount + case .authAccountKeys: + return .authAccountKeys + case .publicAccountKeys: + return .publicAccountKeys + case .authAccountContracts: + return .authAccountContracts + case .publicAccountContracts: + return .publicAccountContracts + case .deployedContract: + return .deployedContract + case .accountKey: + return .accountKey + case .block: + return .block + case .optional: + return .optional + case .variableSizedArray: + return .variableSizedArray + case .constantSizedArray: + return .constantSizedArray + case .dictionary: + return .dictionary + case .struct: + return .struct + case .resource: + return .resource + case .event: + return .event + case .contract: + return .contract + case .structInterface: + return .structInterface + case .resourceInterface: + return .resourceInterface + case .contractInterface: + return .contractInterface + case .function: + return .function + case .reference: + return .reference + case .restriction: + return .restriction + case .capability: + return .capability + case .enum: + return .enum + } + } + + public var id: String { + switch self { + case .any, .anyStruct, .anyResource, + .type, .void, .never, + .bool, .string, .character, .bytes, .address, + .number, .signedNumber, .integer, .signedInteger, + .fixedPoint, .signedFixedPoint, + .int, .int8, .int16, .int32, .int64, .int128, .int256, + .uint, .uint8, .uint16, .uint32, .uint64, .uint128, .uint256, + .word8, .word16, .word32, .word64, + .fix64, .ufix64, + .path, .capabilityPath, .storagePath, .publicPath, .privatePath, + .authAccount, .publicAccount, .authAccountKeys, .publicAccountKeys, + .authAccountContracts, .publicAccountContracts, .deployedContract, + .accountKey, .block: + return kind.rawValue + case let .optional(type): + return "\(type.kind.rawValue)?" + case let .variableSizedArray(elementType): + return "[\(elementType.kind.rawValue)]" + case let .constantSizedArray(elementType, size): + return "[\(elementType.kind.rawValue);\(size)]" + case let .dictionary(keyType, elementType): + return "{\(keyType.kind.rawValue):\(elementType.kind.rawValue)}" + case let .struct(compositeType): + return compositeType.typeId + case let .resource(compositeType): + return compositeType.typeId + case let .event(compositeType): + return compositeType.typeId + case let .contract(compositeType): + return compositeType.typeId + case let .structInterface(compositeType): + return compositeType.typeId + case let .resourceInterface(compositeType): + return compositeType.typeId + case let .contractInterface(compositeType): + return compositeType.typeId + case let .function(functionType): + return functionType.typeId + case let .reference(referenceType): + var id = "&\(referenceType.type.id)" + if referenceType.authorized { + id = "auth" + id + } + return id + case let .restriction(restrictionType): + return restrictionType.typeId + case let .capability(borrowType): + return "\(kind.rawValue)<\(borrowType.id)>" + case let .enum(enumType): + return enumType.typeId + } + } +} + +// MARK: - Codable + +extension FType: Codable { + + enum CodingKeys: CodingKey { + case kind + case type + } + + enum ConstantSizedArrayCodingKeys: CodingKey { + case type + case size + } + + enum DictionaryCodingKeys: CodingKey { + case key + case value + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(kind, forKey: .kind) + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let kind = try container.decode(FTypeKind.self, forKey: .kind) + switch kind { + case .any: + self = .any + case .anyStruct: + self = .anyStruct + case .anyResource: + self = .anyResource + case .type: + self = .type + case .void: + self = .void + case .never: + self = .never + case .bool: + self = .bool + case .string: + self = .string + case .character: + self = .character + case .bytes: + self = .bytes + case .address: + self = .address + case .number: + self = .number + case .signedNumber: + self = .signedNumber + case .integer: + self = .integer + case .signedInteger: + self = .signedInteger + case .fixedPoint: + self = .fixedPoint + case .signedFixedPoint: + self = .signedFixedPoint + case .int: + self = .int + case .int8: + self = .int8 + case .int16: + self = .int16 + case .int32: + self = .int32 + case .int64: + self = .int64 + case .int128: + self = .int128 + case .int256: + self = .int256 + case .uint: + self = .uint + case .uint8: + self = .uint8 + case .uint16: + self = .uint16 + case .uint32: + self = .uint32 + case .uint64: + self = .uint64 + case .uint128: + self = .uint128 + case .uint256: + self = .uint256 + case .word8: + self = .word8 + case .word16: + self = .word16 + case .word32: + self = .word32 + case .word64: + self = .word64 + case .fix64: + self = .fix64 + case .ufix64: + self = .ufix64 + case .path: + self = .path + case .capabilityPath: + self = .capabilityPath + case .storagePath: + self = .storagePath + case .publicPath: + self = .publicPath + case .privatePath: + self = .privatePath + case .authAccount: + self = .authAccount + case .publicAccount: + self = .publicAccount + case .authAccountKeys: + self = .authAccountKeys + case .publicAccountKeys: + self = .publicAccountKeys + case .authAccountContracts: + self = .authAccountContracts + case .publicAccountContracts: + self = .publicAccountContracts + case .deployedContract: + self = .deployedContract + case .accountKey: + self = .accountKey + case .block: + self = .block + case .optional: + let type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + self = .optional(type) + case .variableSizedArray: + let element = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + self = .variableSizedArray(elementType: element) + case .constantSizedArray: + let container = try decoder.container(keyedBy: ConstantSizedArrayCodingKeys.self) + let element = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + let size = try container.decode(Int.self, forKey: .size) + self = .constantSizedArray(elementType: element, size: size) + case .dictionary: + let container = try decoder.container(keyedBy: DictionaryCodingKeys.self) + let key = try container.decodeFType(userInfo: decoder.userInfo, forKey: .key) + let element = try container.decodeFType(userInfo: decoder.userInfo, forKey: .value) + self = .dictionary(keyType: key, elementType: element) + case .struct: + let compositeType = try CompositeType(from: decoder) + self = .struct(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .resource: + let compositeType = try CompositeType(from: decoder) + self = .resource(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .event: + let compositeType = try CompositeType(from: decoder) + self = .event(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .contract: + let compositeType = try CompositeType(from: decoder) + self = .contract(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .structInterface: + let compositeType = try CompositeType(from: decoder) + self = .structInterface(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .resourceInterface: + let compositeType = try CompositeType(from: decoder) + self = .resourceInterface(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .contractInterface: + let compositeType = try CompositeType(from: decoder) + self = .contractInterface(compositeType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: compositeType.typeId) + try compositeType.decodeFieldTypes(from: decoder) + case .function: + let functionType = try FunctionType(from: decoder) + self = .function(functionType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: functionType.typeId) + try functionType.decodePossibleRepeatedProperties(from: decoder) + case .reference: + self = .reference(try ReferenceType(from: decoder)) + case .restriction: + let restrictionType = try RestrictionType(from: decoder) + self = .restriction(restrictionType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: restrictionType.typeId) + try restrictionType.decodePossibleRepeatedProperties(from: decoder) + case .capability: + let type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) + self = .capability(borrowType: type) + case .enum: + let enumType = try EnumType(from: decoder) + self = .enum(enumType) + decoder.addTypeToDecodingResultsIfPossible(type: self, typeId: enumType.typeId) + try enumType.decodePossibleRepeatedProperties(from: decoder) + } + } + +} + +// MARK: - Decoder + +private extension Decoder { + + func addTypeToDecodingResultsIfPossible(type: FType, typeId: String) { + if let results = userInfo[.decodingResults] as? FTypeDecodingResults { + results.value = [typeId: type] + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeDecodingResults.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeDecodingResults.swift new file mode 100644 index 00000000..3f758636 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeDecodingResults.swift @@ -0,0 +1,12 @@ +// +// FTypeDecodingResults.swift +// +// Created by Scott on 2022/6/28. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +class FTypeDecodingResults { + public var value: [String: FType] = [:] +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeKind.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeKind.swift new file mode 100644 index 00000000..3959bf58 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/FTypeKind.swift @@ -0,0 +1,78 @@ +// +// FTypeKind.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum FTypeKind: String, Equatable, Codable { + case `any` = "Any" + case anyStruct = "AnyStruct" + case anyResource = "AnyResource" + case type = "Type" + case void = "Void" + case never = "Never" + case bool = "Bool" + case string = "String" + case character = "Character" + case bytes = "Bytes" + case address = "Address" + case number = "Number" + case signedNumber = "SignedNumber" + case integer = "Integer" + case signedInteger = "SignedInteger" + case fixedPoint = "FixedPoint" + case signedFixedPoint = "SignedFixedPoint" + case int = "Int" + case int8 = "Int8" + case int16 = "Int16" + case int32 = "Int32" + case int64 = "Int64" + case int128 = "Int128" + case int256 = "Int256" + case uint = "UInt" + case uint8 = "UInt8" + case uint16 = "UInt16" + case uint32 = "UInt32" + case uint64 = "UInt64" + case uint128 = "UInt128" + case uint256 = "UInt256" + case word8 = "Word8" + case word16 = "Word16" + case word32 = "Word32" + case word64 = "Word64" + case fix64 = "Fix64" + case ufix64 = "UFix64" + case path = "Path" + case capabilityPath = "CapabilityPath" + case storagePath = "StoragePath" + case publicPath = "PublicPath" + case privatePath = "PrivatePath" + case authAccount = "AuthAccount" + case publicAccount = "PublicAccount" + case authAccountKeys = "AuthAccount.Keys" + case publicAccountKeys = "PublicAccount.Keys" + case authAccountContracts = "AuthAccount.Contracts" + case publicAccountContracts = "PublicAccount.Contracts" + case deployedContract = "DeployedContract" + case accountKey = "AccountKey" + case block = "Block" + case `optional` = "Optional" + case variableSizedArray = "VariableSizedArray" + case constantSizedArray = "ConstantSizedArray" + case dictionary = "Dictionary" + case `struct` = "Struct" + case resource = "Resource" + case event = "Event" + case contract = "Contract" + case structInterface = "StructInterface" + case resourceInterface = "ResourceInterface" + case contractInterface = "ContractInterface" + case function = "Function" + case reference = "Reference" + case restriction = "Restriction" + case capability = "Capability" + case `enum` = "Enum" +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Format.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Format.swift new file mode 100644 index 00000000..2cbf1caf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Format.swift @@ -0,0 +1,140 @@ +// +// Format.swift +// +// Created by Scott on 2022/6/29. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt + +enum Format { + case void + case `nil` + case string(String) + case address(Address) + case bool(Bool) + case bigInt(BigInt) + case bigUInt(BigUInt) + case int8(Int8) + case uint8(UInt8) + case int16(Int16) + case uint16(UInt16) + case int32(Int32) + case uint32(UInt32) + case int64(Int64) + case uint64(UInt64) + case int(Int) + case uint(UInt) + case decimal(Decimal) + case array([String]) + case dictionary([(key: String, value: String)]) + case composite( + typeId: String, + fields: [(name: String, value: String)]) + case path( + domain: String, + identifier: String) + case type(FType) + case capability( + borrowType: FType, + address: Address, + path: String) +} + +// MARK: - CustomStringConvertible + +extension Format: CustomStringConvertible { + + var description: String { + switch self { + case .void: + return "()" + case .nil: + return "nil" + case let .string(string): + return string.quoteString + case let .address(address): + return address.description + case let .bool(bool): + return bool ? "true" : "false" + case let .bigInt(bigInt): + return bigInt.description + case let .bigUInt(bigUInt): + return bigUInt.description + case let .int8(int8): + return String(int8) + case let .uint8(uint8): + return String(uint8) + case let .int16(int16): + return String(int16) + case let .uint16(uint16): + return String(uint16) + case let .int32(int32): + return String(int32) + case let .uint32(uint32): + return String(uint32) + case let .int64(int64): + return String(int64) + case let .uint64(uint64): + return String(uint64) + case let .int(int): + return String(int) + case let .uint(uint): + return String(uint) + case let .decimal(decimal): + let elements = decimal.description.split(separator: ".") + switch elements.count { + case 1: + return "\(elements[0]).00000000" + case 2: + let paddingZero = String(repeating: "0", count: 8 - elements[1].count) + return "\(elements[0]).\(elements[1])\(paddingZero)" + default: + return decimal.description + } + case let .array(array): + var result = "[" + for (index, string) in array.enumerated() { + if index > 0 { + result += ", " + } + result += string + } + result += "]" + return result + case let .dictionary(pairs): + var result = "{" + for (index, pair) in pairs.enumerated() { + if index > 0 { + result += ", " + } + result += "\(pair.key): \(pair.value)" + } + result += "}" + return result + case let .composite(typeId, fields): + var result = "\(typeId)(" + for (index, pair) in fields.enumerated() { + if index > 0 { + result += ", " + } + result += "\(pair.name): \(pair.value)" + } + result += ")" + return result + case let .path(domain, identifier): + return "/\(domain)/\(identifier)" + case let .type(type): + if type.id == "" { + return "Type()" + } else { + return "Type<\(type.id)>()" + } + case let .capability(borrowType, address, path): + let typeArgument = borrowType.id.isEmpty ? "" : "<\(borrowType.id)>" + return "Capability\(typeArgument)(address: \(address.hexStringWithPrefix), path: \(path))" + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Path.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Path.swift new file mode 100644 index 00000000..7f4857be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Path.swift @@ -0,0 +1,31 @@ +// +// Path.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// https://docs.onflow.org/cadence/json-cadence-spec/#path +public struct Path: Codable, Equatable { + + public let domain: Domain + public let identifier: String + + public init(domain: Domain, identifier: String) { + self.domain = domain + self.identifier = identifier + } +} + +// MARK: - Domain + +extension Path { + + public enum Domain: String, Codable { + case storage + case `private` + case `public` + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/StaticTypeValue.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/StaticTypeValue.swift new file mode 100644 index 00000000..1836392d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/StaticTypeValue.swift @@ -0,0 +1,17 @@ +// +// StaticTypeValue.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// https://docs.onflow.org/cadence/json-cadence-spec/#type-value +public struct StaticTypeValue: Codable, Equatable { + public let staticType: FType + + public init(staticType: FType) { + self.staticType = staticType + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Value.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Value.swift new file mode 100644 index 00000000..3dd91563 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/Value.swift @@ -0,0 +1,528 @@ +// +// Value.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt +import Combine + +public enum Value: Equatable { + case void + indirect case optional(Argument?) + case bool(Bool) + case string(String) + case address(Address) + case int(BigInt) + case uint(BigUInt) + case int8(Int8) + case uint8(UInt8) + case int16(Int16) + case uint16(UInt16) + case int32(Int32) + case uint32(UInt32) + case int64(Int64) + case uint64(UInt64) + case int128(BigInt) + case uint128(BigUInt) + case int256(BigInt) + case uint256(BigUInt) + case word8(UInt8) + case word16(UInt16) + case word32(UInt32) + case word64(UInt64) + case fix64(Decimal) + case ufix64(Decimal) + indirect case array([Argument]) + indirect case dictionary([Dictionary]) + indirect case `struct`(CompositeStruct) + indirect case resource(CompositeResource) + indirect case event(CompositeEvent) + indirect case contract(CompositeContract) + indirect case `enum`(CompositeEnum) + case path(Path) + case type(StaticTypeValue) + case capability(Capability) + + public var type: ValueType { + switch self { + case .void: return .void + case .optional: return .optional + case .bool: return .bool + case .string: return .string + case .address: return .address + case .int: return .int + case .uint: return .uint + case .int8: return .int8 + case .uint8: return .uint8 + case .int16: return .int16 + case .uint16: return .uint16 + case .int32: return .int32 + case .uint32: return .uint32 + case .int64: return .int64 + case .uint64: return .uint64 + case .int128: return .int128 + case .uint128: return .uint128 + case .int256: return .int256 + case .uint256: return .uint256 + case .word8: return .word8 + case .word16: return .word16 + case .word32: return .word32 + case .word64: return .word64 + case .fix64: return .fix64 + case .ufix64: return .ufix64 + case .array: return .array + case .dictionary: return .dictionary + case .struct: return .struct + case .resource: return .resource + case .event: return .event + case .contract: return .contract + case .enum: return .enum + case .path: return .path + case .type: return .type + case .capability: return .capability + } + } +} + +// MARK: - Encodable + +extension Value: Encodable { + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .void: + break + case let .optional(value): + try container.encode(value) + case let .bool(bool): + try container.encode(bool) + case let .string(string): + try container.encode(string) + case let .address(address): + try container.encode(address) + case let .int(int): + try container.encode(String(int)) + case let .uint(uint): + try container.encode(String(uint)) + case let .int8(int8): + try container.encode(String(int8)) + case let .uint8(uint8): + try container.encode(String(uint8)) + case let .int16(int16): + try container.encode(String(int16)) + case let .uint16(uint16): + try container.encode(String(uint16)) + case let .int32(int32): + try container.encode(String(int32)) + case let .uint32(uint32): + try container.encode(String(uint32)) + case let .int64(int64): + try container.encode(String(int64)) + case let .uint64(uint64): + try container.encode(String(uint64)) + case let .int128(int128): + try container.encode(int128.description) + case let .uint128(uint128): + try container.encode(uint128.description) + case let .int256(int256): + try container.encode(int256.description) + case let .uint256(uint256): + try container.encode(uint256.description) + case let .word8(word8): + try container.encode(String(word8)) + case let .word16(word16): + try container.encode(String(word16)) + case let .word32(word32): + try container.encode(String(word32)) + case let .word64(word64): + try container.encode(String(word64)) + case let .fix64(fix64): + try container.encode(fix64.description.addingZeroDecimalIfNeeded) + case let .ufix64(ufix64): + try container.encode(ufix64.description.addingZeroDecimalIfNeeded) + case let .array(array): + try container.encode(array) + case let .dictionary(dictionary): + try container.encode(dictionary) + case let .struct(`struct`): + try container.encode(`struct`) + case let .resource(resource): + try container.encode(resource) + case let .event(event): + try container.encode(event) + case let .contract(contract): + try container.encode(contract) + case let .enum(`enum`): + try container.encode(`enum`) + case let .path(path): + try container.encode(path) + case let .type(type): + try container.encode(type) + case let .capability(capability): + try container.encode(capability) + } + } + +} + +// MARK: - To Swift Value + +extension Value { + + public enum ValueDecodingError: Swift.Error { + case mismatchType + case invalidDictionaryKey + case inconsistentDictionaryKeyType + } + + private struct CompositeEnumWrapper: Decodable { + let rawValue: T + } + + public func toSwiftValue(decodableType: T.Type = T.self) throws -> T { + if let value = try toSwiftValue(decodableType: Optional.self) { + return value + } else { + throw ValueDecodingError.mismatchType + } + } + + public func toSwiftValue(decodableType: Optional.Type = Optional.self) throws -> T? { + guard let rawValue = try toSwiftRawValue() else { + return nil + } + + if let value = rawValue as? T { + return value + } + + guard JSONSerialization.isValidJSONObject(rawValue) else { + throw ValueDecodingError.mismatchType + } + + let data = try JSONSerialization.data( + withJSONObject: rawValue, + options: [.fragmentsAllowed]) + + switch self { + case .enum: + return try JSONDecoder().decode(CompositeEnumWrapper.self, from: data).rawValue + default: + return try JSONDecoder().decode(T.self, from: data) + } + } + + private func toSwiftRawValue() throws -> Any? { + switch self { + case .void: + return nil + case let .optional(value): + return try value?.value.toSwiftRawValue() + case let .bool(bool): + return bool + case let .string(string): + return string + case let .address(address): + return address + case let .int(bigInt): + return bigInt + case let .uint(bigUInt): + return bigUInt + case let .int8(int8): + return int8 + case let .uint8(uint8): + return uint8 + case let .int16(int16): + return int16 + case let .uint16(uint16): + return uint16 + case let .int32(int32): + return int32 + case let .uint32(uint32): + return uint32 + case let .int64(int64): + return int64 + case let .uint64(uint64): + return uint64 + case let .int128(bigInt): + return bigInt + case let .uint128(bigUInt): + return bigUInt + case let .int256(bigInt): + return bigInt + case let .uint256(bigUInt): + return bigUInt + case let .word8(uint8): + return uint8 + case let .word16(uint16): + return uint16 + case let .word32(uint32): + return uint32 + case let .word64(uint64): + return uint64 + case let .fix64(decimal): + return decimal + case let .ufix64(decimal): + return decimal + case let .array(array): + return try array.map { try $0.value.toSwiftRawValue() } + case let .dictionary(dictionary): + guard let firstElement = dictionary.first else { + return [:] + } + switch firstElement.key.type { + case .void: + throw ValueDecodingError.invalidDictionaryKey + case .optional: + throw ValueDecodingError.invalidDictionaryKey + case .bool: + return try makeSwiftDictionary(dictionary, type: Bool.self) + case .string: + return try makeSwiftDictionary(dictionary, type: String.self) + case .address: + return try makeSwiftDictionary(dictionary, type: Address.self) + case .int: + return try makeSwiftDictionary(dictionary, type: BigInt.self) + case .uint: + return try makeSwiftDictionary(dictionary, type: BigUInt.self) + case .int8: + return try makeSwiftDictionary(dictionary, type: Int8.self) + case .uint8: + return try makeSwiftDictionary(dictionary, type: UInt8.self) + case .int16: + return try makeSwiftDictionary(dictionary, type: Int16.self) + case .uint16: + return try makeSwiftDictionary(dictionary, type: UInt16.self) + case .int32: + return try makeSwiftDictionary(dictionary, type: Int32.self) + case .uint32: + return try makeSwiftDictionary(dictionary, type: UInt32.self) + case .int64: + return try makeSwiftDictionary(dictionary, type: Int64.self) + case .uint64: + return try makeSwiftDictionary(dictionary, type: UInt64.self) + case .int128: + return try makeSwiftDictionary(dictionary, type: BigInt.self) + case .uint128: + return try makeSwiftDictionary(dictionary, type: BigUInt.self) + case .int256: + return try makeSwiftDictionary(dictionary, type: BigInt.self) + case .uint256: + return try makeSwiftDictionary(dictionary, type: BigUInt.self) + case .word8: + return try makeSwiftDictionary(dictionary, type: Int8.self) + case .word16: + return try makeSwiftDictionary(dictionary, type: Int16.self) + case .word32: + return try makeSwiftDictionary(dictionary, type: Int32.self) + case .word64: + return try makeSwiftDictionary(dictionary, type: Int64.self) + case .fix64: + return try makeSwiftDictionary(dictionary, type: Decimal.self) + case .ufix64: + return try makeSwiftDictionary(dictionary, type: Decimal.self) + case .array, + .dictionary, + .struct, + .resource, + .event, + .contract, + .enum, + .path, + .type, + .capability: + throw ValueDecodingError.invalidDictionaryKey + } + case let .struct(compositeStruct): + return try convertCompositeToDictionary(compositeStruct) + case let .resource(compositeResource): + return try convertCompositeToDictionary(compositeResource) + case let .event(compositeEvent): + return try convertCompositeToDictionary(compositeEvent) + case let .contract(compositeContract): + return try convertCompositeToDictionary(compositeContract) + case let .enum(compositeEnum): + return try convertCompositeToDictionary(compositeEnum) + case let .path(path): + return path + case let .type(staticTypeValue): + return staticTypeValue.staticType + case let .capability(capability): + return capability + } + } + + private func makeSwiftDictionary( + _ dictionary: [Cadence.Dictionary], + type: KeyType.Type = KeyType.self + ) throws -> [KeyType: Any] { + var result: [KeyType: Any] = [:] + try dictionary.forEach { + guard let key = try $0.key.value.toSwiftRawValue() as? KeyType else { + throw ValueDecodingError.inconsistentDictionaryKeyType + } + let value = try $0.value.value.toSwiftRawValue() + result[key] = value + } + return result + } + + private func convertCompositeToDictionary(_ composite: Composite) throws -> [String: Any?] { + var result: [String: Any] = [:] + try composite.fields.forEach { + let value = try $0.value.value.toSwiftRawValue() + if let bigInt = value as? BigInt { + result[$0.name] = bigInt.description + } else if let bigUInt = value as? BigUInt { + result[$0.name] = bigUInt.description + } else if let decimal = value as? Decimal { + result[$0.name] = decimal.description + } else if let encodable = value as? Encodable { + let value = try encodable.encoded(with: JSONEncoder()) + result[$0.name] = try JSONSerialization.jsonObject( + with: value, + options: [.fragmentsAllowed]) + } else { + result[$0.name] = value + } + } + return result + } + +} + +private extension Encodable { + + func encoded(with encoder: Encoder) throws -> Data where Encoder.Output == Data { + try encoder.encode(self) + } +} + +// MARK: - CustomStringConvertible + +extension Value: CustomStringConvertible { + + public var description: String { + switch self { + case .void: + return Format.void.description + case let .optional(value): + if let value = value { + return value.value.description + } else { + return Format.nil.description + } + case let .bool(bool): + return Format.bool(bool).description + case let .string(string): + return Format.string(string).description + case let .address(address): + return Format.address(address).description + case let .int(bigInt): + return Format.bigInt(bigInt).description + case let .uint(bigUInt): + return Format.bigUInt(bigUInt).description + case let .int8(int8): + return Format.int8(int8).description + case let .uint8(uint8): + return Format.uint8(uint8).description + case let .int16(int16): + return Format.int16(int16).description + case let .uint16(uint16): + return Format.uint16(uint16).description + case let .int32(int32): + return Format.int32(int32).description + case let .uint32(uint32): + return Format.uint32(uint32).description + case let .int64(int64): + return Format.int64(int64).description + case let .uint64(uint64): + return Format.uint64(uint64).description + case let .int128(bigInt): + return Format.bigInt(bigInt).description + case let .uint128(bigUInt): + return Format.bigUInt(bigUInt).description + case let .int256(bigInt): + return Format.bigInt(bigInt).description + case let .uint256(bigUInt): + return Format.bigUInt(bigUInt).description + case let .word8(uint8): + return Format.uint8(uint8).description + case let .word16(uint16): + return Format.uint16(uint16).description + case let .word32(uint32): + return Format.uint32(uint32).description + case let .word64(uint64): + return Format.uint64(uint64).description + case let .fix64(decimal): + return Format.decimal(decimal).description + case let .ufix64(decimal): + return Format.decimal(decimal).description + case let .array(array): + return Format.array(array.map { $0.value.description }).description + case let .dictionary(array): + let pairs = array.map { (key: $0.key.value.description, value: $0.value.value.description) } + return Format.dictionary(pairs).description + case let .struct(compositeStruct): + let pairs = compositeStruct.fields.map { (name: $0.name, value: $0.value.value.description) } + return Format.composite( + typeId: compositeStruct.id, + fields: pairs + ).description + case let .resource(compositeResource): + let pairs = compositeResource.fields.map { (name: $0.name, value: $0.value.value.description) } + return Format.composite( + typeId: compositeResource.id, + fields: pairs + ).description + case let .event(compositeEvent): + let pairs = compositeEvent.fields.map { (name: $0.name, value: $0.value.value.description) } + return Format.composite( + typeId: compositeEvent.id, + fields: pairs + ).description + case let .contract(compositeContract): + let pairs = compositeContract.fields.map { (name: $0.name, value: $0.value.value.description) } + return Format.composite( + typeId: compositeContract.id, + fields: pairs + ).description + case let .enum(compositeEnum): + let pairs = compositeEnum.fields.map { (name: $0.name, value: $0.value.value.description) } + return Format.composite( + typeId: compositeEnum.id, + fields: pairs + ).description + case let .path(path): + return Format.path( + domain: path.domain.rawValue, + identifier: path.identifier + ).description + case let .type(staticTypeValue): + return Format.type(staticTypeValue.staticType).description + case let .capability(capability): + return Format.capability( + borrowType: capability.borrowType, + address: capability.address, + path: capability.path + ).description + } + } +} + +// MARK: - String + +private extension String { + + var addingZeroDecimalIfNeeded: String { + var result = description + if result.contains(".") == false { + result += ".0" + } + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/ValueType.swift b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/ValueType.swift new file mode 100644 index 00000000..9cf82790 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Cadence/Sources/Cadence/ValueType.swift @@ -0,0 +1,46 @@ +// +// ValueType.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum ValueType: String, Equatable, Codable { + case void = "Void" + case optional = "Optional" + case bool = "Bool" + case string = "String" + case address = "Address" + case int = "Int" + case uint = "UInt" + case int8 = "Int8" + case uint8 = "UInt8" + case int16 = "Int16" + case uint16 = "UInt16" + case int32 = "Int32" + case uint32 = "UInt32" + case int64 = "Int64" + case uint64 = "UInt64" + case int128 = "Int128" + case uint128 = "UInt128" + case int256 = "Int256" + case uint256 = "UInt256" + case word8 = "Word8" + case word16 = "Word16" + case word32 = "Word32" + case word64 = "Word64" + case fix64 = "Fix64" + case ufix64 = "UFix64" + case array = "Array" + case dictionary = "Dictionary" + case `struct` = "Struct" + case resource = "Resource" + case event = "Event" + case contract = "Contract" + case `enum` = "Enum" + case path = "Path" + case type = "Type" + case capability = "Capability" +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/LICENSE b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/LICENSE new file mode 100644 index 00000000..e52af7df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/LICENSE @@ -0,0 +1,11 @@ +Copyright (C) 2014-2017 Marcin Krzyżanowski +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/README.md b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/README.md new file mode 100644 index 00000000..e24b8a19 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/README.md @@ -0,0 +1,578 @@ +[![Platform](https://img.shields.io/badge/Platforms-iOS%20%7C%20Android%20%7CmacOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20Linux-4E4E4E.svg?colorA=28a745)](#installation) + +[![Swift support](https://img.shields.io/badge/Swift-3.1%20%7C%203.2%20%7C%204.0%20%7C%204.1%20%7C%204.2%20%7C%205.0-lightgrey.svg?colorA=28a745&colorB=4E4E4E)](#swift-versions-support) +[![Swift Package Manager compatible](https://img.shields.io/badge/SPM-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https://github.com/apple/swift-package-manager) +[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/CryptoSwift.svg?style=flat&label=CocoaPods&colorA=28a745&&colorB=4E4E4E)](https://cocoapods.org/pods/CryptoSwift) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https://github.com/Carthage/Carthage) + +# CryptoSwift + +Crypto related functions and helpers for [Swift](https://swift.org) implemented in Swift. ([#PureSwift](https://twitter.com/hashtag/pureswift)) + +**Note**: The `main` branch follows the latest currently released **version of Swift**. If you need an earlier version for an older version of Swift, you can specify its version in your `Podfile` or use the code on the branch for that version. Older branches are unsupported. Check [versions](#swift-versions-support) for details. + +--- + +[Requirements](#requirements) | [Features](#features) | [Contribution](#contribution) | [Installation](#installation) | [Swift versions](#swift-versions-support) | [How-to](#how-to) | [Author](#author) | [License](#license) | [Changelog](#changelog) + +## Sponsorship + +It takes some time to keep it all for your convenience, so maybe spare $1, so I can keep working on that. There are more than 8000 clones daily. If I'd get $1/month from each company that uses my work here, I'd say we're even. Hurry up, find the [Sponsorship](https://github.com/users/krzyzanowskim/sponsorship) button, and fulfill your duty. + +CryptoSwift isn't backed by any big company and is developer in my spare time that I also use to as a freelancer. + +[![Twitter](https://img.shields.io/badge/Twitter-@krzyzanowskim-blue.svg?style=flat)](http://twitter.com/krzyzanowskim) + +## Requirements +Good mood + +## Features + +- Easy to use +- Convenient extensions for String and Data +- Support for incremental updates (stream, ...) +- iOS, Android, macOS, AppleTV, watchOS, Linux support + +#### Hash (Digest) + [MD5](http://tools.ietf.org/html/rfc1321) +| [SHA1](http://tools.ietf.org/html/rfc3174) +| [SHA2-224](http://tools.ietf.org/html/rfc6234) +| [SHA2-256](http://tools.ietf.org/html/rfc6234) +| [SHA2-384](http://tools.ietf.org/html/rfc6234) +| [SHA2-512](http://tools.ietf.org/html/rfc6234) +| [SHA3](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) + +#### Cyclic Redundancy Check (CRC) + [CRC32](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) +| [CRC32C](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) +| [CRC16](http://en.wikipedia.org/wiki/Cyclic_redundancy_check) + +#### Cipher + [AES-128, AES-192, AES-256](http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf) +| [ChaCha20](http://cr.yp.to/chacha/chacha-20080128.pdf) +| [Rabbit](https://tools.ietf.org/html/rfc4503) +| [Blowfish](https://www.schneier.com/academic/blowfish/) + +#### Message authenticators + [Poly1305](http://cr.yp.to/mac/poly1305-20050329.pdf) +| [HMAC (MD5, SHA1, SHA256)](https://www.ietf.org/rfc/rfc2104.txt) +| [CMAC](https://tools.ietf.org/html/rfc4493) +| [CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) + +#### Cipher mode of operation +- Electronic codebook ([ECB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29)) +- Cipher-block chaining ([CBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29)) +- Propagating Cipher Block Chaining ([PCBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Propagating_Cipher_Block_Chaining_.28PCBC.29)) +- Cipher feedback ([CFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29)) +- Output Feedback ([OFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_.28OFB.29)) +- Counter Mode ([CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29)) +- Galois/Counter Mode ([GCM](https://csrc.nist.gov/publications/detail/sp/800-38d/final)) +- Counter with Cipher Block Chaining-Message Authentication Code ([CCM](https://csrc.nist.gov/publications/detail/sp/800-38c/final)) +- OCB Authenticated-Encryption Algorithm ([OCB](https://tools.ietf.org/html/rfc7253)) + +#### Password-Based Key Derivation Function +- [PBKDF1](http://tools.ietf.org/html/rfc2898#section-5.1) (Password-Based Key Derivation Function 1) +- [PBKDF2](http://tools.ietf.org/html/rfc2898#section-5.2) (Password-Based Key Derivation Function 2) +- [HKDF](https://tools.ietf.org/html/rfc5869) (HMAC-based Extract-and-Expand Key Derivation Function) +- [Scrypt](https://tools.ietf.org/html/rfc7914) (The scrypt Password-Based Key Derivation Function) + +#### Data padding + PKCS#5 +| [PKCS#7](http://tools.ietf.org/html/rfc5652#section-6.3) +| [Zero padding](https://en.wikipedia.org/wiki/Padding_(cryptography)#Zero_padding) +| [ISO78164](http://www.embedx.com/pdfs/ISO_STD_7816/info_isoiec7816-4%7Bed21.0%7Den.pdf) +| [ISO10126](https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO_10126) +| No padding + +#### Authenticated Encryption with Associated Data (AEAD) +- [AEAD\_CHACHA20\_POLY1305](https://tools.ietf.org/html/rfc7539#section-2.8) + +## Why +[Why?](https://github.com/krzyzanowskim/CryptoSwift/issues/5) [Because I can](https://github.com/krzyzanowskim/CryptoSwift/issues/5#issuecomment-53379391). + +## How do I get involved? + +You want to help, great! Go ahead and fork our repo, make your changes and send us a pull request. + +## Contribution + +Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to help with CryptoSwift. + +- If you found a bug, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues). +- If you have a feature request, [open an issue](https://github.com/krzyzanowskim/CryptoSwift/issues). + +## Installation + +### Hardened Runtime (macOS) and Xcode + +Binary CryptoSwift.xcframework (Used by Swift Package Manager package integration) won't load properly in your app if the app uses **Sign to Run Locally** Signing Certificate with Hardened Runtime enabled. It is possible to setup Xcode like this. To solve the problem you have two options: +- Use proper Signing Certificate, eg. *Development* <- this is the proper action +- Use `Disable Library Validation` aka `com.apple.security.cs.disable-library-validation` entitlement + +#### Xcode Project + +To install CryptoSwift, add it as a submodule to your project (on the top level project directory): + + git submodule add https://github.com/krzyzanowskim/CryptoSwift.git + +It is recommended to enable [Whole-Module Optimization](https://swift.org/blog/whole-module-optimizations/) to gain better performance. Non-optimized build results in significantly worse performance. + +#### Swift Package Manager + +You can use [Swift Package Manager](https://swift.org/package-manager/) and specify dependency in `Package.swift` by adding this: + +```swift +.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.5.1")) +``` + +See: [Package.swift - manual](http://blog.krzyzanowskim.com/2016/08/09/package-swift-manual/) + +Notice: Swift Package Manager uses debug configuration for debug Xcode build, that may result in significant (up to x10000) worse performance. Performance characteristic is different in Release build. To overcome this prolem, consider embed `CryptoSwift.xcframework` described below. + +#### CocoaPods + +You can use [CocoaPods](https://cocoapods.org/pods/CryptoSwift). + +```ruby +pod 'CryptoSwift', '~> 1.4.1' +``` + +Bear in mind that CocoaPods will build CryptoSwift without [Whole-Module Optimization](https://swift.org/blog/whole-module-optimizations/) that may impact performance. You can change it manually after installation, or use [cocoapods-wholemodule](https://github.com/jedlewison/cocoapods-wholemodule) plugin. + +#### Carthage + +You can use [Carthage](https://github.com/Carthage/Carthage). +Specify in Cartfile: + +```ruby +github "krzyzanowskim/CryptoSwift" +``` + +Run `carthage` to build the framework and drag the built CryptoSwift.framework into your Xcode project. Follow [build instructions](https://github.com/Carthage/Carthage#getting-started). [Common issues](https://github.com/krzyzanowskim/CryptoSwift/issues/492#issuecomment-330822874). + +#### XCFramework + +XCFrameworks require Xcode 11 or later and they can be integrated similarly to how we’re used to integrating the `.framework` format. +Please use script [scripts/build-framework.sh](scripts/build-framework.sh) to generate binary `CryptoSwift.xcframework` archive that you can use as a dependency in Xcode. + +CryptoSwift.xcframework is a Release (Optimized) binary that offer best available Swift code performance. + +Screen Shot 2020-10-27 at 00 06 32 + +#### Embedded Framework + +Embedded frameworks require a minimum deployment target of iOS 9 or macOS Sierra (10.12). Drag the `CryptoSwift.xcodeproj` file into your Xcode project, and add appropriate framework as a dependency to your target. Now select your App and choose the General tab for the app target. Find *Embedded Binaries* and press "+", then select `CryptoSwift.framework` (iOS, macOS, watchOS or tvOS) + +![](https://cloud.githubusercontent.com/assets/758033/10834511/25a26852-7e9a-11e5-8c01-6cc8f1838459.png) + +Sometimes "embedded framework" option is not available. In that case, you have to add new build phase for the target. + +![](https://cloud.githubusercontent.com/assets/758033/18415615/d5edabb0-77f8-11e6-8c94-f41d9fc2b8cb.png) + +##### iOS, macOS, watchOS, tvOS + +In the project, you'll find [single scheme](https://mxcl.dev/PromiseKit/news/2016/08/Multiplatform-Single-Scheme-Xcode-Projects/) for all platforms: +- CryptoSwift + +#### Swift versions support + +- Swift 1.2: branch [swift12](https://github.com/krzyzanowskim/CryptoSwift/tree/swift12) version <= 0.0.13 +- Swift 2.1: branch [swift21](https://github.com/krzyzanowskim/CryptoSwift/tree/swift21) version <= 0.2.3 +- Swift 2.2, 2.3: branch [swift2](https://github.com/krzyzanowskim/CryptoSwift/tree/swift2) version <= 0.5.2 +- Swift 3.1, branch [swift3](https://github.com/krzyzanowskim/CryptoSwift/tree/swift3) version <= 0.6.9 +- Swift 3.2, branch [swift32](https://github.com/krzyzanowskim/CryptoSwift/tree/swift32) version = 0.7.0 +- Swift 4.0, branch [swift4](https://github.com/krzyzanowskim/CryptoSwift/tree/swift4) version <= 0.12.0 +- Swift 4.2, branch [swift42](https://github.com/krzyzanowskim/CryptoSwift/tree/swift42) version <= 0.15.0 +- Swift 5.0, branch [swift5](https://github.com/krzyzanowskim/CryptoSwift/tree/swift5) version <= 1.2.0 +- Swift 5.1, branch [swift5](https://github.com/krzyzanowskim/CryptoSwift/tree/swift51) version <= 1.3.3 +- Swift 5.3 and newer, branch [main](https://github.com/krzyzanowskim/CryptoSwift/tree/main) + +## How-to + +* [Basics (data types, conversion, ...)](#basics) +* [Digest (MD5, SHA...)](#calculate-digest) +* [Message authenticators (HMAC, CMAC...)](#message-authenticators-1) +* [Password-Based Key Derivation Function (PBKDF2, ...)](#password-based-key-derivation-functions) +* [HMAC-based Key Derivation Function (HKDF)](#hmac-based-key-derivation-function) +* [Data Padding](#data-padding) +* [ChaCha20](#chacha20) +* [Rabbit](#rabbit) +* [Blowfish](#blowfish) +* [AES - Advanced Encryption Standard](#aes) +* [AES-GCM](#aes-gcm) +* [Authenticated Encryption with Associated Data (AEAD)](#aead) + +##### Basics + +```swift +import CryptoSwift +``` + +CryptoSwift uses array of bytes aka `Array` as a base type for all operations. Every data may be converted to a stream of bytes. You will find convenience functions that accept `String` or `Data`, and it will be internally converted to the array of bytes. + +##### Data types conversion + +For your convenience, **CryptoSwift** provides two functions to easily convert an array of bytes to `Data` or `Data` to an array of bytes: + +Data from bytes: + +```swift +let data = Data( [0x01, 0x02, 0x03]) +``` + +`Data` to `Array` + +```swift +let bytes = data.bytes // [1,2,3] +``` + +[Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) encoding: + +```swift +let bytes = Array(hex: "0x010203") // [1,2,3] +let hex = bytes.toHexString() // "010203" +``` + +Build bytes out of `String` +```swift +let bytes: Array = "cipherkey".bytes // Array("cipherkey".utf8) +``` + +Also... check out helpers that work with **Base64** encoded data: +```swift +"aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64ToString(cipher) +"aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64(cipher) +bytes.toBase64() +``` + +##### Calculate Digest + +Hashing a data or array of bytes (aka `Array`) +```swift +/* Hash struct usage */ +let bytes: Array = [0x01, 0x02, 0x03] +let digest = input.md5() +let digest = Digest.md5(bytes) +``` + +```swift +let data = Data([0x01, 0x02, 0x03]) + +let hash = data.md5() +let hash = data.sha1() +let hash = data.sha224() +let hash = data.sha256() +let hash = data.sha384() +let hash = data.sha512() +``` +```swift +do { + var digest = MD5() + let partial1 = try digest.update(withBytes: [0x31, 0x32]) + let partial2 = try digest.update(withBytes: [0x33]) + let result = try digest.finish() +} catch { } +``` + +Hashing a String and printing result + +```swift +let hash = "123".md5() // "123".bytes.md5() +``` + +##### Calculate CRC + +```swift +bytes.crc16() +data.crc16() + +bytes.crc32() +data.crc32() +``` + +##### Message authenticators + +```swift +// Calculate Message Authentication Code (MAC) for message +let key: Array = [1,2,3,4,5,6,7,8,9,10,...] + +try Poly1305(key: key).authenticate(bytes) +try HMAC(key: key, variant: .sha256).authenticate(bytes) +try CMAC(key: key).authenticate(bytes) +``` + +##### Password-Based Key Derivation Functions + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) + +let key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, keyLength: 32, variant: .sha256).calculate() +``` + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) +// Scrypt implementation does not implement work parallelization, so `p` parameter will +// increase the work time even in multicore systems +let key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate() +``` + +##### HMAC-based Key Derivation Function + +```swift +let password: Array = Array("s33krit".utf8) +let salt: Array = Array("nacllcan".utf8) + +let key = try HKDF(password: password, salt: salt, variant: .sha256).calculate() +``` + + +##### Data Padding + +Some content-encryption algorithms assume the input length is a multiple of `k` octets, where `k` is greater than one. For such algorithms, the input shall be padded. + +```swift +Padding.pkcs7.add(to: bytes, blockSize: AES.blockSize) +``` + +#### Working with Ciphers +##### ChaCha20 + +```swift +let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) +let decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted) +``` + +##### Rabbit + +```swift +let encrypted = try Rabbit(key: key, iv: iv).encrypt(message) +let decrypted = try Rabbit(key: key, iv: iv).decrypt(encrypted) +``` +##### Blowfish + +```swift +let encrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(message) +let decrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) +``` + +##### AES + +Notice regarding padding: *Manual padding of data is optional, and CryptoSwift is using PKCS7 padding by default. If you need to manually disable/enable padding, you can do this by setting parameter for __AES__ class* + +Variant of AES encryption (AES-128, AES-192, AES-256) depends on given key length: + +- AES-128 = 16 bytes +- AES-192 = 24 bytes +- AES-256 = 32 bytes + +AES-256 example + +```swift +let encryptedBytes = try AES(key: [1,2,3,...,32], blockMode: CBC(iv: [1,2,3,...,16]), padding: .pkcs7) +``` + +Full example: + +```swift +let password: [UInt8] = Array("s33krit".utf8) +let salt: [UInt8] = Array("nacllcan".utf8) + +/* Generate a key from a `password`. Optional if you already have a key */ +let key = try PKCS5.PBKDF2( + password: password, + salt: salt, + iterations: 4096, + keyLength: 32, /* AES-256 */ + variant: .sha256 +).calculate() + +/* Generate random IV value. IV is public value. Either need to generate, or get it from elsewhere */ +let iv = AES.randomIV(AES.blockSize) + +/* AES cryptor instance */ +let aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) + +/* Encrypt Data */ +let inputData = Data() +let encryptedBytes = try aes.encrypt(inputData.bytes) +let encryptedData = Data(encryptedBytes) + +/* Decrypt Data */ +let decryptedBytes = try aes.decrypt(encryptedData.bytes) +let decryptedData = Data(decryptedBytes) +``` + +###### All at once +```swift +do { + let aes = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap") // aes128 + let ciphertext = try aes.encrypt(Array("Nullam quis risus eget urna mollis ornare vel eu leo.".utf8)) +} catch { } +``` + +###### Incremental updates + +Incremental operations use instance of Cryptor and encrypt/decrypt one part at a time, this way you can save on memory for large files. + +```swift +do { + var encryptor = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap").makeEncryptor() + + var ciphertext = Array() + // aggregate partial results + ciphertext += try encryptor.update(withBytes: Array("Nullam quis risus ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("eget urna mollis ".utf8)) + ciphertext += try encryptor.update(withBytes: Array("ornare vel eu leo.".utf8)) + // finish at the end + ciphertext += try encryptor.finish() + + print(ciphertext.toHexString()) +} catch { + print(error) +} +``` + +###### AES Advanced usage +```swift +let input: Array = [0,1,2,3,4,5,6,7,8,9] + +let key: Array = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] +let iv: Array = // Random bytes of `AES.blockSize` length + +do { + let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input) + let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) +} catch { + print(error) +} +``` + +AES without data padding + +```swift +let input: Array = [0,1,2,3,4,5,6,7,8,9] +let encrypted: Array = try! AES(key: Array("secret0key000000".utf8), blockMode: CBC(iv: Array("0123456789012345".utf8)), padding: .noPadding).encrypt(input) +``` + +Using convenience extensions + +```swift +let plain = Data([0x01, 0x02, 0x03]) +let encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv)) +let decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv)) +``` + +##### AES-GCM + +The result of Galois/Counter Mode (GCM) encryption is ciphertext and **authentication tag**, that is later used to decryption. + +encryption + +```swift +do { + // In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. + let gcm = GCM(iv: iv, mode: .combined) + let aes = try AES(key: key, blockMode: gcm, padding: .noPadding) + let encrypted = try aes.encrypt(plaintext) + let tag = gcm.authenticationTag +} catch { + // failed +} +``` + +decryption + +```swift +do { + // In combined mode, the authentication tag is appended to the encrypted message. This is usually what you want. + let gcm = GCM(iv: iv, mode: .combined) + let aes = try AES(key: key, blockMode: gcm, padding: .noPadding) + return try aes.decrypt(encrypted) +} catch { + // failed +} +``` + +**Note**: GCM instance is not intended to be reused. So you can't use the same `GCM` instance from encoding to also perform decoding. + +##### AES-CCM + +The result of Counter with Cipher Block Chaining-Message Authentication Code encryption is ciphertext and **authentication tag**, that is later used to decryption. + +```swift +do { + // The authentication tag is appended to the encrypted message. + let tagLength = 8 + let ccm = CCM(iv: iv, tagLength: tagLength, messageLength: ciphertext.count - tagLength, additionalAuthenticatedData: data) + let aes = try AES(key: key, blockMode: ccm, padding: .noPadding) + return try aes.decrypt(encrypted) +} catch { + // failed +} +``` + +Check documentation or CCM specification for valid parameters for CCM. + +##### AEAD + +```swift +let encrypt = try AEADChaCha20Poly1305.encrypt(plaintext, key: key, iv: nonce, authenticationHeader: header) +let decrypt = try AEADChaCha20Poly1305.decrypt(ciphertext, key: key, iv: nonce, authenticationHeader: header, authenticationTag: tagArr: tag) +``` + +##### RSA + +RSA initialization from parameters + +```swift +let input: Array = [0,1,2,3,4,5,6,7,8,9] + +let n: Array = // RSA modulus +let e: Array = // RSA public exponent +let d: Array = // RSA private exponent + +let rsa = RSA(n: n, e: e, d: d) + +do { + let encrypted = try rsa.encrypt(input) + let decrypted = try rsa.decrypt(encrypted) +} catch { + print(error) +} +``` + +RSA key generation + +```swift +let rsa = RSA(keySize: 2048) // This generates a modulus, public exponent and private exponent with the given size +``` + +## Author + +CryptoSwift is owned and maintained by [Marcin Krzyżanowski](http://www.krzyzanowskim.com) + +You can follow me on Twitter at [@krzyzanowskim](http://twitter.com/krzyzanowskim) for project updates and releases. + +# Cryptography Notice + +This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information. + +## License + +Copyright (C) 2014-2021 Marcin Krzyżanowski +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, **an acknowledgment in the product documentation is required**. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + +## Changelog + +See [CHANGELOG](./CHANGELOG) file. diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift new file mode 100644 index 00000000..3b45ab44 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEAD.swift @@ -0,0 +1,40 @@ +// +// AEAD.swift +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// +// + +// https://www.iana.org/assignments/aead-parameters/aead-parameters.xhtml + +/// Authenticated Encryption with Associated Data (AEAD) +public protocol AEAD { + static var kLen: Int { get } // key length + static var ivRange: Range { get } // nonce length +} + +extension AEAD { + static func calculateAuthenticationTag(authenticator: Authenticator, cipherText: Array, authenticationHeader: Array) throws -> Array { + let headerPadding = ((16 - (authenticationHeader.count & 0xf)) & 0xf) + let cipherPadding = ((16 - (cipherText.count & 0xf)) & 0xf) + + var mac = authenticationHeader + mac += Array(repeating: 0, count: headerPadding) + mac += cipherText + mac += Array(repeating: 0, count: cipherPadding) + mac += UInt64(bigEndian: UInt64(authenticationHeader.count)).bytes() + mac += UInt64(bigEndian: UInt64(cipherText.count)).bytes() + + return try authenticator.authenticate(mac) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift new file mode 100644 index 00000000..b4c9aeb0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift @@ -0,0 +1,59 @@ +// +// ChaCha20Poly1305.swift +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// +// +// https://tools.ietf.org/html/rfc7539#section-2.8.1 + +/// AEAD_CHACHA20_POLY1305 +public final class AEADChaCha20Poly1305: AEAD { + public static let kLen = 32 // key length + public static var ivRange = Range(12...12) + + /// Authenticated encryption + public static func encrypt(_ plainText: Array, key: Array, iv: Array, authenticationHeader: Array) throws -> (cipherText: Array, authenticationTag: Array) { + let cipher = try ChaCha20(key: key, iv: iv) + + var polykey = Array(repeating: 0, count: kLen) + var toEncrypt = polykey + polykey = try cipher.encrypt(polykey) + toEncrypt += polykey + toEncrypt += plainText + + let fullCipherText = try cipher.encrypt(toEncrypt) + let cipherText = Array(fullCipherText.dropFirst(64)) + + let tag = try calculateAuthenticationTag(authenticator: Poly1305(key: polykey), cipherText: cipherText, authenticationHeader: authenticationHeader) + return (cipherText, tag) + } + + /// Authenticated decryption + public static func decrypt(_ cipherText: Array, key: Array, iv: Array, authenticationHeader: Array, authenticationTag: Array) throws -> (plainText: Array, success: Bool) { + let chacha = try ChaCha20(key: key, iv: iv) + + let polykey = try chacha.encrypt(Array(repeating: 0, count: self.kLen)) + let mac = try calculateAuthenticationTag(authenticator: Poly1305(key: polykey), cipherText: cipherText, authenticationHeader: authenticationHeader) + guard mac == authenticationTag else { + return (cipherText, false) + } + + var toDecrypt = Array(reserveCapacity: cipherText.count + 64) + toDecrypt += polykey + toDecrypt += polykey + toDecrypt += cipherText + let fullPlainText = try chacha.decrypt(toDecrypt) + let plainText = Array(fullPlainText.dropFirst(64)) + return (plainText, true) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift new file mode 100644 index 00000000..f84c92bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.Cryptors.swift @@ -0,0 +1,39 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// MARK: Cryptors + +extension AES: Cryptors { + @inlinable + public func makeEncryptor() throws -> Cryptor & Updatable { + let blockSize = blockMode.customBlockSize ?? AES.blockSize + let worker = try blockMode.worker(blockSize: blockSize, cipherOperation: encrypt, encryptionOperation: encrypt) + if worker is StreamModeWorker { + return try StreamEncryptor(blockSize: blockSize, padding: padding, worker) + } + return try BlockEncryptor(blockSize: blockSize, padding: padding, worker) + } + + @inlinable + public func makeDecryptor() throws -> Cryptor & Updatable { + let blockSize = blockMode.customBlockSize ?? AES.blockSize + let cipherOperation: CipherOperationOnBlock = blockMode.options.contains(.useEncryptToDecrypt) == true ? encrypt : decrypt + let worker = try blockMode.worker(blockSize: blockSize, cipherOperation: cipherOperation, encryptionOperation: encrypt) + if worker is StreamModeWorker { + return try StreamDecryptor(blockSize: blockSize, padding: padding, worker) + } + return try BlockDecryptor(blockSize: blockSize, padding: padding, worker) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.swift new file mode 100644 index 00000000..211bda6d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/AES.swift @@ -0,0 +1,556 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Implementation of Gladman algorithm http://www.gladman.me.uk/AES +// + +/// The Advanced Encryption Standard (AES) +public final class AES: BlockCipher { + public enum Error: Swift.Error { + /// Invalid key + case invalidKeySize + /// Data padding is required + case dataPaddingRequired + /// Invalid Data + case invalidData + } + + public enum Variant: Int { + case aes128 = 1, aes192, aes256 + + var Nk: Int { // Nk words + [4, 6, 8][self.rawValue - 1] + } + + var Nb: Int { // Nb words + 4 + } + + var Nr: Int { // Nr + self.Nk + 6 + } + } + + @usableFromInline + internal let variantNr: Int + + @usableFromInline + internal let variantNb: Int + + @usableFromInline + internal let variantNk: Int + + public static let blockSize: Int = 16 // 128 /8 + public let keySize: Int + + /// AES Variant + public let variant: Variant + + // Parameters + let key: Key + + @usableFromInline + let blockMode: BlockMode + + @usableFromInline + let padding: Padding + + // + @usableFromInline + internal lazy var expandedKey: Array> = self.expandKey(self.key, variant: self.variant) + + @usableFromInline + internal lazy var expandedKeyInv: Array> = self.expandKeyInv(self.key, variant: self.variant) + + private lazy var sBoxes: (sBox: Array, invSBox: Array) = self.calculateSBox() + private lazy var sBox: Array = self.sBoxes.sBox + private lazy var sBoxInv: Array = self.sBoxes.invSBox + + // Parameters for Linear Congruence Generators + private static let Rcon: Array = [ + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, + 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, + 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, + 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, + 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, + 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d + ] + + @usableFromInline static let T0: Array = [0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c] + @usableFromInline static let T0_INV: Array = [0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0] + @usableFromInline static let T1: Array = [0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x0, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a] + @usableFromInline static let T1_INV: Array = [0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042] + @usableFromInline static let T2: Array = [0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16] + @usableFromInline static let T2_INV: Array = [0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257] + @usableFromInline static let T3: Array = [0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616] + @usableFromInline static let T3_INV: Array = [0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8] + @usableFromInline static let U1: Array = [0x0, 0xb0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a, 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a, 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca, 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba, 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1, 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, 0xfe75793, 0x4ea5e9d, 0x19fd458f, 0x12f04c81, 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411, 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61, 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987, 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7, 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967, 0x1ed5ae3d, 0x15d8a733, 0x8cfbc21, 0x3c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117, 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c, 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c, 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x728ebb2, 0xc25e2bc, 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc, 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b, 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b, 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b, 0x1f6234d1, 0x146f3ddf, 0x97826cd, 0x2752fc3, 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb, 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0, 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0, 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, 0x10856342, 0x1b886a4c, 0x69f715e, 0xd927850, 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020, 0x1b79aec, 0xaba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6, 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6, 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526, 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56, 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d, 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, 0xe50cd7f, 0x55dc471, 0x184adf63, 0x1347d66d, 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd, 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d] + @usableFromInline static let U2: Array = [0x0, 0xd090e0b, 0x1a121c16, 0x171b121d, 0x3424382c, 0x392d3627, 0x2e36243a, 0x233f2a31, 0x68487058, 0x65417e53, 0x725a6c4e, 0x7f536245, 0x5c6c4874, 0x5165467f, 0x467e5462, 0x4b775a69, 0xd090e0b0, 0xdd99eebb, 0xca82fca6, 0xc78bf2ad, 0xe4b4d89c, 0xe9bdd697, 0xfea6c48a, 0xf3afca81, 0xb8d890e8, 0xb5d19ee3, 0xa2ca8cfe, 0xafc382f5, 0x8cfca8c4, 0x81f5a6cf, 0x96eeb4d2, 0x9be7bad9, 0xbb3bdb7b, 0xb632d570, 0xa129c76d, 0xac20c966, 0x8f1fe357, 0x8216ed5c, 0x950dff41, 0x9804f14a, 0xd373ab23, 0xde7aa528, 0xc961b735, 0xc468b93e, 0xe757930f, 0xea5e9d04, 0xfd458f19, 0xf04c8112, 0x6bab3bcb, 0x66a235c0, 0x71b927dd, 0x7cb029d6, 0x5f8f03e7, 0x52860dec, 0x459d1ff1, 0x489411fa, 0x3e34b93, 0xeea4598, 0x19f15785, 0x14f8598e, 0x37c773bf, 0x3ace7db4, 0x2dd56fa9, 0x20dc61a2, 0x6d76adf6, 0x607fa3fd, 0x7764b1e0, 0x7a6dbfeb, 0x595295da, 0x545b9bd1, 0x434089cc, 0x4e4987c7, 0x53eddae, 0x837d3a5, 0x1f2cc1b8, 0x1225cfb3, 0x311ae582, 0x3c13eb89, 0x2b08f994, 0x2601f79f, 0xbde64d46, 0xb0ef434d, 0xa7f45150, 0xaafd5f5b, 0x89c2756a, 0x84cb7b61, 0x93d0697c, 0x9ed96777, 0xd5ae3d1e, 0xd8a73315, 0xcfbc2108, 0xc2b52f03, 0xe18a0532, 0xec830b39, 0xfb981924, 0xf691172f, 0xd64d768d, 0xdb447886, 0xcc5f6a9b, 0xc1566490, 0xe2694ea1, 0xef6040aa, 0xf87b52b7, 0xf5725cbc, 0xbe0506d5, 0xb30c08de, 0xa4171ac3, 0xa91e14c8, 0x8a213ef9, 0x872830f2, 0x903322ef, 0x9d3a2ce4, 0x6dd963d, 0xbd49836, 0x1ccf8a2b, 0x11c68420, 0x32f9ae11, 0x3ff0a01a, 0x28ebb207, 0x25e2bc0c, 0x6e95e665, 0x639ce86e, 0x7487fa73, 0x798ef478, 0x5ab1de49, 0x57b8d042, 0x40a3c25f, 0x4daacc54, 0xdaec41f7, 0xd7e54ffc, 0xc0fe5de1, 0xcdf753ea, 0xeec879db, 0xe3c177d0, 0xf4da65cd, 0xf9d36bc6, 0xb2a431af, 0xbfad3fa4, 0xa8b62db9, 0xa5bf23b2, 0x86800983, 0x8b890788, 0x9c921595, 0x919b1b9e, 0xa7ca147, 0x775af4c, 0x106ebd51, 0x1d67b35a, 0x3e58996b, 0x33519760, 0x244a857d, 0x29438b76, 0x6234d11f, 0x6f3ddf14, 0x7826cd09, 0x752fc302, 0x5610e933, 0x5b19e738, 0x4c02f525, 0x410bfb2e, 0x61d79a8c, 0x6cde9487, 0x7bc5869a, 0x76cc8891, 0x55f3a2a0, 0x58faacab, 0x4fe1beb6, 0x42e8b0bd, 0x99fead4, 0x496e4df, 0x138df6c2, 0x1e84f8c9, 0x3dbbd2f8, 0x30b2dcf3, 0x27a9ceee, 0x2aa0c0e5, 0xb1477a3c, 0xbc4e7437, 0xab55662a, 0xa65c6821, 0x85634210, 0x886a4c1b, 0x9f715e06, 0x9278500d, 0xd90f0a64, 0xd406046f, 0xc31d1672, 0xce141879, 0xed2b3248, 0xe0223c43, 0xf7392e5e, 0xfa302055, 0xb79aec01, 0xba93e20a, 0xad88f017, 0xa081fe1c, 0x83bed42d, 0x8eb7da26, 0x99acc83b, 0x94a5c630, 0xdfd29c59, 0xd2db9252, 0xc5c0804f, 0xc8c98e44, 0xebf6a475, 0xe6ffaa7e, 0xf1e4b863, 0xfcedb668, 0x670a0cb1, 0x6a0302ba, 0x7d1810a7, 0x70111eac, 0x532e349d, 0x5e273a96, 0x493c288b, 0x44352680, 0xf427ce9, 0x24b72e2, 0x155060ff, 0x18596ef4, 0x3b6644c5, 0x366f4ace, 0x217458d3, 0x2c7d56d8, 0xca1377a, 0x1a83971, 0x16b32b6c, 0x1bba2567, 0x38850f56, 0x358c015d, 0x22971340, 0x2f9e1d4b, 0x64e94722, 0x69e04929, 0x7efb5b34, 0x73f2553f, 0x50cd7f0e, 0x5dc47105, 0x4adf6318, 0x47d66d13, 0xdc31d7ca, 0xd138d9c1, 0xc623cbdc, 0xcb2ac5d7, 0xe815efe6, 0xe51ce1ed, 0xf207f3f0, 0xff0efdfb, 0xb479a792, 0xb970a999, 0xae6bbb84, 0xa362b58f, 0x805d9fbe, 0x8d5491b5, 0x9a4f83a8, 0x97468da3] + @usableFromInline static let U3: Array = [0x0, 0x90e0b0d, 0x121c161a, 0x1b121d17, 0x24382c34, 0x2d362739, 0x36243a2e, 0x3f2a3123, 0x48705868, 0x417e5365, 0x5a6c4e72, 0x5362457f, 0x6c48745c, 0x65467f51, 0x7e546246, 0x775a694b, 0x90e0b0d0, 0x99eebbdd, 0x82fca6ca, 0x8bf2adc7, 0xb4d89ce4, 0xbdd697e9, 0xa6c48afe, 0xafca81f3, 0xd890e8b8, 0xd19ee3b5, 0xca8cfea2, 0xc382f5af, 0xfca8c48c, 0xf5a6cf81, 0xeeb4d296, 0xe7bad99b, 0x3bdb7bbb, 0x32d570b6, 0x29c76da1, 0x20c966ac, 0x1fe3578f, 0x16ed5c82, 0xdff4195, 0x4f14a98, 0x73ab23d3, 0x7aa528de, 0x61b735c9, 0x68b93ec4, 0x57930fe7, 0x5e9d04ea, 0x458f19fd, 0x4c8112f0, 0xab3bcb6b, 0xa235c066, 0xb927dd71, 0xb029d67c, 0x8f03e75f, 0x860dec52, 0x9d1ff145, 0x9411fa48, 0xe34b9303, 0xea45980e, 0xf1578519, 0xf8598e14, 0xc773bf37, 0xce7db43a, 0xd56fa92d, 0xdc61a220, 0x76adf66d, 0x7fa3fd60, 0x64b1e077, 0x6dbfeb7a, 0x5295da59, 0x5b9bd154, 0x4089cc43, 0x4987c74e, 0x3eddae05, 0x37d3a508, 0x2cc1b81f, 0x25cfb312, 0x1ae58231, 0x13eb893c, 0x8f9942b, 0x1f79f26, 0xe64d46bd, 0xef434db0, 0xf45150a7, 0xfd5f5baa, 0xc2756a89, 0xcb7b6184, 0xd0697c93, 0xd967779e, 0xae3d1ed5, 0xa73315d8, 0xbc2108cf, 0xb52f03c2, 0x8a0532e1, 0x830b39ec, 0x981924fb, 0x91172ff6, 0x4d768dd6, 0x447886db, 0x5f6a9bcc, 0x566490c1, 0x694ea1e2, 0x6040aaef, 0x7b52b7f8, 0x725cbcf5, 0x506d5be, 0xc08deb3, 0x171ac3a4, 0x1e14c8a9, 0x213ef98a, 0x2830f287, 0x3322ef90, 0x3a2ce49d, 0xdd963d06, 0xd498360b, 0xcf8a2b1c, 0xc6842011, 0xf9ae1132, 0xf0a01a3f, 0xebb20728, 0xe2bc0c25, 0x95e6656e, 0x9ce86e63, 0x87fa7374, 0x8ef47879, 0xb1de495a, 0xb8d04257, 0xa3c25f40, 0xaacc544d, 0xec41f7da, 0xe54ffcd7, 0xfe5de1c0, 0xf753eacd, 0xc879dbee, 0xc177d0e3, 0xda65cdf4, 0xd36bc6f9, 0xa431afb2, 0xad3fa4bf, 0xb62db9a8, 0xbf23b2a5, 0x80098386, 0x8907888b, 0x9215959c, 0x9b1b9e91, 0x7ca1470a, 0x75af4c07, 0x6ebd5110, 0x67b35a1d, 0x58996b3e, 0x51976033, 0x4a857d24, 0x438b7629, 0x34d11f62, 0x3ddf146f, 0x26cd0978, 0x2fc30275, 0x10e93356, 0x19e7385b, 0x2f5254c, 0xbfb2e41, 0xd79a8c61, 0xde94876c, 0xc5869a7b, 0xcc889176, 0xf3a2a055, 0xfaacab58, 0xe1beb64f, 0xe8b0bd42, 0x9fead409, 0x96e4df04, 0x8df6c213, 0x84f8c91e, 0xbbd2f83d, 0xb2dcf330, 0xa9ceee27, 0xa0c0e52a, 0x477a3cb1, 0x4e7437bc, 0x55662aab, 0x5c6821a6, 0x63421085, 0x6a4c1b88, 0x715e069f, 0x78500d92, 0xf0a64d9, 0x6046fd4, 0x1d1672c3, 0x141879ce, 0x2b3248ed, 0x223c43e0, 0x392e5ef7, 0x302055fa, 0x9aec01b7, 0x93e20aba, 0x88f017ad, 0x81fe1ca0, 0xbed42d83, 0xb7da268e, 0xacc83b99, 0xa5c63094, 0xd29c59df, 0xdb9252d2, 0xc0804fc5, 0xc98e44c8, 0xf6a475eb, 0xffaa7ee6, 0xe4b863f1, 0xedb668fc, 0xa0cb167, 0x302ba6a, 0x1810a77d, 0x111eac70, 0x2e349d53, 0x273a965e, 0x3c288b49, 0x35268044, 0x427ce90f, 0x4b72e202, 0x5060ff15, 0x596ef418, 0x6644c53b, 0x6f4ace36, 0x7458d321, 0x7d56d82c, 0xa1377a0c, 0xa8397101, 0xb32b6c16, 0xba25671b, 0x850f5638, 0x8c015d35, 0x97134022, 0x9e1d4b2f, 0xe9472264, 0xe0492969, 0xfb5b347e, 0xf2553f73, 0xcd7f0e50, 0xc471055d, 0xdf63184a, 0xd66d1347, 0x31d7cadc, 0x38d9c1d1, 0x23cbdcc6, 0x2ac5d7cb, 0x15efe6e8, 0x1ce1ede5, 0x7f3f0f2, 0xefdfbff, 0x79a792b4, 0x70a999b9, 0x6bbb84ae, 0x62b58fa3, 0x5d9fbe80, 0x5491b58d, 0x4f83a89a, 0x468da397] + @usableFromInline static let U4: Array = [0x0, 0xe0b0d09, 0x1c161a12, 0x121d171b, 0x382c3424, 0x3627392d, 0x243a2e36, 0x2a31233f, 0x70586848, 0x7e536541, 0x6c4e725a, 0x62457f53, 0x48745c6c, 0x467f5165, 0x5462467e, 0x5a694b77, 0xe0b0d090, 0xeebbdd99, 0xfca6ca82, 0xf2adc78b, 0xd89ce4b4, 0xd697e9bd, 0xc48afea6, 0xca81f3af, 0x90e8b8d8, 0x9ee3b5d1, 0x8cfea2ca, 0x82f5afc3, 0xa8c48cfc, 0xa6cf81f5, 0xb4d296ee, 0xbad99be7, 0xdb7bbb3b, 0xd570b632, 0xc76da129, 0xc966ac20, 0xe3578f1f, 0xed5c8216, 0xff41950d, 0xf14a9804, 0xab23d373, 0xa528de7a, 0xb735c961, 0xb93ec468, 0x930fe757, 0x9d04ea5e, 0x8f19fd45, 0x8112f04c, 0x3bcb6bab, 0x35c066a2, 0x27dd71b9, 0x29d67cb0, 0x3e75f8f, 0xdec5286, 0x1ff1459d, 0x11fa4894, 0x4b9303e3, 0x45980eea, 0x578519f1, 0x598e14f8, 0x73bf37c7, 0x7db43ace, 0x6fa92dd5, 0x61a220dc, 0xadf66d76, 0xa3fd607f, 0xb1e07764, 0xbfeb7a6d, 0x95da5952, 0x9bd1545b, 0x89cc4340, 0x87c74e49, 0xddae053e, 0xd3a50837, 0xc1b81f2c, 0xcfb31225, 0xe582311a, 0xeb893c13, 0xf9942b08, 0xf79f2601, 0x4d46bde6, 0x434db0ef, 0x5150a7f4, 0x5f5baafd, 0x756a89c2, 0x7b6184cb, 0x697c93d0, 0x67779ed9, 0x3d1ed5ae, 0x3315d8a7, 0x2108cfbc, 0x2f03c2b5, 0x532e18a, 0xb39ec83, 0x1924fb98, 0x172ff691, 0x768dd64d, 0x7886db44, 0x6a9bcc5f, 0x6490c156, 0x4ea1e269, 0x40aaef60, 0x52b7f87b, 0x5cbcf572, 0x6d5be05, 0x8deb30c, 0x1ac3a417, 0x14c8a91e, 0x3ef98a21, 0x30f28728, 0x22ef9033, 0x2ce49d3a, 0x963d06dd, 0x98360bd4, 0x8a2b1ccf, 0x842011c6, 0xae1132f9, 0xa01a3ff0, 0xb20728eb, 0xbc0c25e2, 0xe6656e95, 0xe86e639c, 0xfa737487, 0xf478798e, 0xde495ab1, 0xd04257b8, 0xc25f40a3, 0xcc544daa, 0x41f7daec, 0x4ffcd7e5, 0x5de1c0fe, 0x53eacdf7, 0x79dbeec8, 0x77d0e3c1, 0x65cdf4da, 0x6bc6f9d3, 0x31afb2a4, 0x3fa4bfad, 0x2db9a8b6, 0x23b2a5bf, 0x9838680, 0x7888b89, 0x15959c92, 0x1b9e919b, 0xa1470a7c, 0xaf4c0775, 0xbd51106e, 0xb35a1d67, 0x996b3e58, 0x97603351, 0x857d244a, 0x8b762943, 0xd11f6234, 0xdf146f3d, 0xcd097826, 0xc302752f, 0xe9335610, 0xe7385b19, 0xf5254c02, 0xfb2e410b, 0x9a8c61d7, 0x94876cde, 0x869a7bc5, 0x889176cc, 0xa2a055f3, 0xacab58fa, 0xbeb64fe1, 0xb0bd42e8, 0xead4099f, 0xe4df0496, 0xf6c2138d, 0xf8c91e84, 0xd2f83dbb, 0xdcf330b2, 0xceee27a9, 0xc0e52aa0, 0x7a3cb147, 0x7437bc4e, 0x662aab55, 0x6821a65c, 0x42108563, 0x4c1b886a, 0x5e069f71, 0x500d9278, 0xa64d90f, 0x46fd406, 0x1672c31d, 0x1879ce14, 0x3248ed2b, 0x3c43e022, 0x2e5ef739, 0x2055fa30, 0xec01b79a, 0xe20aba93, 0xf017ad88, 0xfe1ca081, 0xd42d83be, 0xda268eb7, 0xc83b99ac, 0xc63094a5, 0x9c59dfd2, 0x9252d2db, 0x804fc5c0, 0x8e44c8c9, 0xa475ebf6, 0xaa7ee6ff, 0xb863f1e4, 0xb668fced, 0xcb1670a, 0x2ba6a03, 0x10a77d18, 0x1eac7011, 0x349d532e, 0x3a965e27, 0x288b493c, 0x26804435, 0x7ce90f42, 0x72e2024b, 0x60ff1550, 0x6ef41859, 0x44c53b66, 0x4ace366f, 0x58d32174, 0x56d82c7d, 0x377a0ca1, 0x397101a8, 0x2b6c16b3, 0x25671bba, 0xf563885, 0x15d358c, 0x13402297, 0x1d4b2f9e, 0x472264e9, 0x492969e0, 0x5b347efb, 0x553f73f2, 0x7f0e50cd, 0x71055dc4, 0x63184adf, 0x6d1347d6, 0xd7cadc31, 0xd9c1d138, 0xcbdcc623, 0xc5d7cb2a, 0xefe6e815, 0xe1ede51c, 0xf3f0f207, 0xfdfbff0e, 0xa792b479, 0xa999b970, 0xbb84ae6b, 0xb58fa362, 0x9fbe805d, 0x91b58d54, 0x83a89a4f, 0x8da39746] + + /// Initialize AES with variant calculated out of key length: + /// - 16 bytes (AES-128) + /// - 24 bytes (AES-192) + /// - 32 bytes (AES-256) + /// + /// - parameter key: Key. Length of the key decides on AES variant. + /// - parameter iv: Initialization Vector (Optional for some blockMode values) + /// - parameter blockMode: Cipher mode of operation + /// - parameter padding: Padding method. .pkcs7, .noPadding, .zeroPadding, ... + /// + /// - throws: AES.Error + /// + /// - returns: Instance + public init(key: Array, blockMode: BlockMode, padding: Padding = .pkcs7) throws { + self.key = Key(bytes: key) + self.blockMode = blockMode + self.padding = padding + self.keySize = self.key.count + + // Validate key size + switch self.keySize * 8 { + case 128: + self.variant = .aes128 + case 192: + self.variant = .aes192 + case 256: + self.variant = .aes256 + default: + throw Error.invalidKeySize + } + + self.variantNb = self.variant.Nb + self.variantNk = self.variant.Nk + self.variantNr = self.variant.Nr + } + + @inlinable + internal func encrypt(block: ArraySlice) -> Array? { + if self.blockMode.options.contains(.paddingRequired) && block.count != AES.blockSize { + return Array(block) + } + + let rounds = self.variantNr + let rk = self.expandedKey + + let b00 = UInt32(block[block.startIndex.advanced(by: 0)]) + let b01 = UInt32(block[block.startIndex.advanced(by: 1)]) << 8 + let b02 = UInt32(block[block.startIndex.advanced(by: 2)]) << 16 + let b03 = UInt32(block[block.startIndex.advanced(by: 3)]) << 24 + var b0 = b00 | b01 | b02 | b03 + + let b10 = UInt32(block[block.startIndex.advanced(by: 4)]) + let b11 = UInt32(block[block.startIndex.advanced(by: 5)]) << 8 + let b12 = UInt32(block[block.startIndex.advanced(by: 6)]) << 16 + let b13 = UInt32(block[block.startIndex.advanced(by: 7)]) << 24 + var b1 = b10 | b11 | b12 | b13 + + let b20 = UInt32(block[block.startIndex.advanced(by: 8)]) + let b21 = UInt32(block[block.startIndex.advanced(by: 9)]) << 8 + let b22 = UInt32(block[block.startIndex.advanced(by: 10)]) << 16 + let b23 = UInt32(block[block.startIndex.advanced(by: 11)]) << 24 + var b2 = b20 | b21 | b22 | b23 + + let b30 = UInt32(block[block.startIndex.advanced(by: 12)]) + let b31 = UInt32(block[block.startIndex.advanced(by: 13)]) << 8 + let b32 = UInt32(block[block.startIndex.advanced(by: 14)]) << 16 + let b33 = UInt32(block[block.startIndex.advanced(by: 15)]) << 24 + var b3 = b30 | b31 | b32 | b33 + + let tLength = 4 + let t = UnsafeMutablePointer.allocate(capacity: tLength) + t.initialize(repeating: 0, count: tLength) + defer { + t.deinitialize(count: tLength) + t.deallocate() + } + + for r in 0..> 8) & 0xff)] + let lb02 = AES.T2[Int((t[2] >> 16) & 0xff)] + let lb03 = AES.T3[Int(t[3] >> 24)] + b0 = lb00 ^ lb01 ^ lb02 ^ lb03 + + let lb10 = AES.T0[Int(t[1] & 0xff)] + let lb11 = AES.T1[Int((t[2] >> 8) & 0xff)] + let lb12 = AES.T2[Int((t[3] >> 16) & 0xff)] + let lb13 = AES.T3[Int(t[0] >> 24)] + b1 = lb10 ^ lb11 ^ lb12 ^ lb13 + + let lb20 = AES.T0[Int(t[2] & 0xff)] + let lb21 = AES.T1[Int((t[3] >> 8) & 0xff)] + let lb22 = AES.T2[Int((t[0] >> 16) & 0xff)] + let lb23 = AES.T3[Int(t[1] >> 24)] + b2 = lb20 ^ lb21 ^ lb22 ^ lb23 + + let lb30 = AES.T0[Int(t[3] & 0xff)] + let lb31 = AES.T1[Int((t[0] >> 8) & 0xff)] + let lb32 = AES.T2[Int((t[1] >> 16) & 0xff)] + let lb33 = AES.T3[Int(t[2] >> 24)] + b3 = lb30 ^ lb31 ^ lb32 ^ lb33 + } + + // last round + let r = rounds - 1 + + t[0] = b0 ^ rk[r][0] + t[1] = b1 ^ rk[r][1] + t[2] = b2 ^ rk[r][2] + t[3] = b3 ^ rk[r][3] + + // rounds + b0 = F1(t[0], t[1], t[2], t[3]) ^ rk[rounds][0] + b1 = F1(t[1], t[2], t[3], t[0]) ^ rk[rounds][1] + b2 = F1(t[2], t[3], t[0], t[1]) ^ rk[rounds][2] + b3 = F1(t[3], t[0], t[1], t[2]) ^ rk[rounds][3] + + let encrypted: Array = [ + UInt8(b0 & 0xff), UInt8((b0 >> 8) & 0xff), UInt8((b0 >> 16) & 0xff), UInt8((b0 >> 24) & 0xff), + UInt8(b1 & 0xff), UInt8((b1 >> 8) & 0xff), UInt8((b1 >> 16) & 0xff), UInt8((b1 >> 24) & 0xff), + UInt8(b2 & 0xff), UInt8((b2 >> 8) & 0xff), UInt8((b2 >> 16) & 0xff), UInt8((b2 >> 24) & 0xff), + UInt8(b3 & 0xff), UInt8((b3 >> 8) & 0xff), UInt8((b3 >> 16) & 0xff), UInt8((b3 >> 24) & 0xff) + ] + return encrypted + } + + @usableFromInline + internal func decrypt(block: ArraySlice) -> Array? { + if self.blockMode.options.contains(.paddingRequired) && block.count != AES.blockSize { + return Array(block) + } + + let rounds = self.variantNr + let rk = self.expandedKeyInv + + // Save miliseconds by not using `block.toUInt32Array()` + let b00 = UInt32(block[block.startIndex.advanced(by: 0)]) + let b01 = UInt32(block[block.startIndex.advanced(by: 1)]) << 8 + let b02 = UInt32(block[block.startIndex.advanced(by: 2)]) << 16 + let b03 = UInt32(block[block.startIndex.advanced(by: 3)]) << 24 + var b0 = b00 | b01 | b02 | b03 + + let b10 = UInt32(block[block.startIndex.advanced(by: 4)]) + let b11 = UInt32(block[block.startIndex.advanced(by: 5)]) << 8 + let b12 = UInt32(block[block.startIndex.advanced(by: 6)]) << 16 + let b13 = UInt32(block[block.startIndex.advanced(by: 7)]) << 24 + var b1 = b10 | b11 | b12 | b13 + + let b20 = UInt32(block[block.startIndex.advanced(by: 8)]) + let b21 = UInt32(block[block.startIndex.advanced(by: 9)]) << 8 + let b22 = UInt32(block[block.startIndex.advanced(by: 10)]) << 16 + let b23 = UInt32(block[block.startIndex.advanced(by: 11)]) << 24 + var b2 = b20 | b21 | b22 | b23 + + let b30 = UInt32(block[block.startIndex.advanced(by: 12)]) + let b31 = UInt32(block[block.startIndex.advanced(by: 13)]) << 8 + let b32 = UInt32(block[block.startIndex.advanced(by: 14)]) << 16 + let b33 = UInt32(block[block.startIndex.advanced(by: 15)]) << 24 + var b3 = b30 | b31 | b32 | b33 + + let tLength = 4 + let t = UnsafeMutablePointer.allocate(capacity: tLength) + t.initialize(repeating: 0, count: tLength) + defer { + t.deinitialize(count: tLength) + t.deallocate() + } + + for r in (2...rounds).reversed() { + t[0] = b0 ^ rk[r][0] + t[1] = b1 ^ rk[r][1] + t[2] = b2 ^ rk[r][2] + t[3] = b3 ^ rk[r][3] + + let b00 = AES.T0_INV[Int(t[0] & 0xff)] + let b01 = AES.T1_INV[Int((t[3] >> 8) & 0xff)] + let b02 = AES.T2_INV[Int((t[2] >> 16) & 0xff)] + let b03 = AES.T3_INV[Int(t[1] >> 24)] + b0 = b00 ^ b01 ^ b02 ^ b03 + + let b10 = AES.T0_INV[Int(t[1] & 0xff)] + let b11 = AES.T1_INV[Int((t[0] >> 8) & 0xff)] + let b12 = AES.T2_INV[Int((t[3] >> 16) & 0xff)] + let b13 = AES.T3_INV[Int(t[2] >> 24)] + b1 = b10 ^ b11 ^ b12 ^ b13 + + let b20 = AES.T0_INV[Int(t[2] & 0xff)] + let b21 = AES.T1_INV[Int((t[1] >> 8) & 0xff)] + let b22 = AES.T2_INV[Int((t[0] >> 16) & 0xff)] + let b23 = AES.T3_INV[Int(t[3] >> 24)] + b2 = b20 ^ b21 ^ b22 ^ b23 + + let b30 = AES.T0_INV[Int(t[3] & 0xff)] + let b31 = AES.T1_INV[Int((t[2] >> 8) & 0xff)] + let b32 = AES.T2_INV[Int((t[1] >> 16) & 0xff)] + let b33 = AES.T3_INV[Int(t[0] >> 24)] + b3 = b30 ^ b31 ^ b32 ^ b33 + } + + // last round + t[0] = b0 ^ rk[1][0] + t[1] = b1 ^ rk[1][1] + t[2] = b2 ^ rk[1][2] + t[3] = b3 ^ rk[1][3] + + // rounds + + let lb00 = self.sBoxInv[Int(B0(t[0]))] + let lb01 = (sBoxInv[Int(B1(t[3]))] << 8) + let lb02 = (sBoxInv[Int(B2(t[2]))] << 16) + let lb03 = (sBoxInv[Int(B3(t[1]))] << 24) + b0 = lb00 | lb01 | lb02 | lb03 ^ rk[0][0] + + let lb10 = self.sBoxInv[Int(B0(t[1]))] + let lb11 = (sBoxInv[Int(B1(t[0]))] << 8) + let lb12 = (sBoxInv[Int(B2(t[3]))] << 16) + let lb13 = (sBoxInv[Int(B3(t[2]))] << 24) + b1 = lb10 | lb11 | lb12 | lb13 ^ rk[0][1] + + let lb20 = self.sBoxInv[Int(B0(t[2]))] + let lb21 = (sBoxInv[Int(B1(t[1]))] << 8) + let lb22 = (sBoxInv[Int(B2(t[0]))] << 16) + let lb23 = (sBoxInv[Int(B3(t[3]))] << 24) + b2 = lb20 | lb21 | lb22 | lb23 ^ rk[0][2] + + let lb30 = self.sBoxInv[Int(B0(t[3]))] + let lb31 = (sBoxInv[Int(B1(t[2]))] << 8) + let lb32 = (sBoxInv[Int(B2(t[1]))] << 16) + let lb33 = (sBoxInv[Int(B3(t[0]))] << 24) + b3 = lb30 | lb31 | lb32 | lb33 ^ rk[0][3] + + let result: Array = [ + UInt8(b0 & 0xff), UInt8((b0 >> 8) & 0xff), UInt8((b0 >> 16) & 0xff), UInt8((b0 >> 24) & 0xff), + UInt8(b1 & 0xff), UInt8((b1 >> 8) & 0xff), UInt8((b1 >> 16) & 0xff), UInt8((b1 >> 24) & 0xff), + UInt8(b2 & 0xff), UInt8((b2 >> 8) & 0xff), UInt8((b2 >> 16) & 0xff), UInt8((b2 >> 24) & 0xff), + UInt8(b3 & 0xff), UInt8((b3 >> 8) & 0xff), UInt8((b3 >> 16) & 0xff), UInt8((b3 >> 24) & 0xff) + ] + return result + } +} + +extension AES { + private func expandKeyInv(_ key: Key, variant: Variant) -> Array> { + let rounds = self.variantNr + var rk2: Array> = self.expandKey(key, variant: variant) + + for r in 1.. Array> { + func convertExpandedKey(_ expanded: Array) -> Array> { + expanded.batched(by: 4).map({ UInt32(bytes: $0.reversed()) }).batched(by: 4).map { Array($0) } + } + + /* + * Function used in the Key Expansion routine that takes a four-byte + * input word and applies an S-box to each of the four bytes to + * produce an output word. + */ + func subWord(_ word: Array) -> Array { + precondition(word.count == 4) + + var result = word + for i in 0..<4 { + result[i] = UInt8(self.sBox[Int(word[i])]) + } + return result + } + + @inline(__always) + func subWordInPlace(_ word: inout Array) { + precondition(word.count == 4) + word[0] = UInt8(self.sBox[Int(word[0])]) + word[1] = UInt8(self.sBox[Int(word[1])]) + word[2] = UInt8(self.sBox[Int(word[2])]) + word[3] = UInt8(self.sBox[Int(word[3])]) + } + + let wLength = self.variantNb * (self.variantNr + 1) * 4 + let w = UnsafeMutablePointer.allocate(capacity: wLength) + w.initialize(repeating: 0, count: wLength) + defer { + w.deinitialize(count: wLength) + w.deallocate() + } + + for i in 0.. + + for i in self.variantNk..(repeating: 0, count: 4) + + for wordIdx in 0..<4 { + tmp[wordIdx] = w[4 * (i - 1) + wordIdx] + } + if (i % self.variantNk) == 0 { + tmp = subWord(rotateLeft(UInt32(bytes: tmp), by: 8).bytes(totalBytes: 4)) + tmp[0] = tmp.first! ^ AES.Rcon[i / variantNk] + } else if self.variantNk > 6 && (i % self.variantNk) == 4 { + subWordInPlace(&tmp) + } + + // xor array of bytes + for wordIdx in 0..<4 { + w[4 * i + wordIdx] = w[4 * (i - variantNk) + wordIdx] ^ tmp[wordIdx] + } + } + return convertExpandedKey(Array(UnsafeBufferPointer(start: w, count: wLength))) + } + + @inline(__always) + private func B0(_ x: UInt32) -> UInt32 { + x & 0xff + } + + @inline(__always) + private func B1(_ x: UInt32) -> UInt32 { + (x >> 8) & 0xff + } + + @inline(__always) + private func B2(_ x: UInt32) -> UInt32 { + (x >> 16) & 0xff + } + + @inline(__always) + private func B3(_ x: UInt32) -> UInt32 { + (x >> 24) & 0xff + } + + @inline(__always) @usableFromInline + internal func F1(_ x0: UInt32, _ x1: UInt32, _ x2: UInt32, _ x3: UInt32) -> UInt32 { + var result: UInt32 = 0 + result |= UInt32(self.B1(AES.T0[Int(x0 & 255)])) + result |= UInt32(self.B1(AES.T0[Int((x1 >> 8) & 255)])) << 8 + result |= UInt32(self.B1(AES.T0[Int((x2 >> 16) & 255)])) << 16 + result |= UInt32(self.B1(AES.T0[Int(x3 >> 24)])) << 24 + return result + } + + private func calculateSBox() -> (sBox: Array, invSBox: Array) { + let sboxLength = 256 + let sbox = UnsafeMutablePointer.allocate(capacity: sboxLength) + let invsbox = UnsafeMutablePointer.allocate(capacity: sboxLength) + sbox.initialize(repeating: 0, count: sboxLength) + invsbox.initialize(repeating: 0, count: sboxLength) + defer { + sbox.deinitialize(count: sboxLength) + sbox.deallocate() + invsbox.deinitialize(count: sboxLength) + invsbox.deallocate() + } + + sbox[0] = 0x63 + + var p: UInt8 = 1, q: UInt8 = 1 + + repeat { + p = p ^ (UInt8(truncatingIfNeeded: Int(p) << 1) ^ ((p & 0x80) == 0x80 ? 0x1b : 0)) + q ^= q << 1 + q ^= q << 2 + q ^= q << 4 + q ^= (q & 0x80) == 0x80 ? 0x09 : 0 + + let s = 0x63 ^ q ^ rotateLeft(q, by: 1) ^ rotateLeft(q, by: 2) ^ rotateLeft(q, by: 3) ^ rotateLeft(q, by: 4) + + sbox[Int(p)] = UInt32(s) + invsbox[Int(s)] = UInt32(p) + } while p != 1 + + return (sBox: Array(UnsafeBufferPointer(start: sbox, count: sboxLength)), invSBox: Array(UnsafeBufferPointer(start: invsbox, count: sboxLength))) + } +} + +// MARK: Cipher + +extension AES: Cipher { + @inlinable + public func encrypt(_ bytes: ArraySlice) throws -> Array { + let blockSize = self.blockMode.customBlockSize ?? AES.blockSize + let chunks = bytes.batched(by: blockSize) + + var oneTimeCryptor = try makeEncryptor() + var out = Array(reserveCapacity: bytes.count) + for chunk in chunks { + out += try oneTimeCryptor.update(withBytes: chunk, isLast: false) + } + // Padding may be added at the very end + out += try oneTimeCryptor.finish() + + if self.blockMode.options.contains(.paddingRequired) && (out.count % AES.blockSize != 0) { + throw Error.dataPaddingRequired + } + + return out + } + + @inlinable + public func decrypt(_ bytes: ArraySlice) throws -> Array { + if self.blockMode.options.contains(.paddingRequired) && (bytes.count % AES.blockSize != 0) { + throw Error.dataPaddingRequired + } + + var oneTimeCryptor = try makeDecryptor() + let chunks = bytes.batched(by: AES.blockSize) + if chunks.isEmpty { + throw Error.invalidData + } + + var out = Array(reserveCapacity: bytes.count) + + var lastIdx = chunks.startIndex + chunks.indices.formIndex(&lastIdx, offsetBy: chunks.count - 1) + + // To properly remove padding, `isLast` has to be known when called with the last chunk of ciphertext + // Last chunk of ciphertext may contains padded data so next call to update(..) won't be able to remove it + for idx in chunks.indices { + out += try oneTimeCryptor.update(withBytes: chunks[idx], isLast: idx == lastIdx) + } + return out + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift new file mode 100644 index 00000000..48abed52 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Array+Extension.swift @@ -0,0 +1,155 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +extension Array { + @inlinable + init(reserveCapacity: Int) { + self = Array() + self.reserveCapacity(reserveCapacity) + } + + @inlinable + var slice: ArraySlice { + self[self.startIndex ..< self.endIndex] + } + + @inlinable + subscript (safe index: Index) -> Element? { + return indices.contains(index) ? self[index] : nil + } +} + +extension Array where Element == UInt8 { + public init(hex: String) { + self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount) + var buffer: UInt8? + var skip = hex.hasPrefix("0x") ? 2 : 0 + for char in hex.unicodeScalars.lazy { + guard skip == 0 else { + skip -= 1 + continue + } + guard char.value >= 48 && char.value <= 102 else { + removeAll() + return + } + let v: UInt8 + let c: UInt8 = UInt8(char.value) + switch c { + case let c where c <= 57: + v = c - 48 + case let c where c >= 65 && c <= 70: + v = c - 55 + case let c where c >= 97: + v = c - 87 + default: + removeAll() + return + } + if let b = buffer { + append(b << 4 | v) + buffer = nil + } else { + buffer = v + } + } + if let b = buffer { + append(b) + } + } + + public func toHexString() -> String { + `lazy`.reduce(into: "") { + var s = String($1, radix: 16) + if s.count == 1 { + s = "0" + s + } + $0 += s + } + } +} + +extension Array where Element == UInt8 { + /// split in chunks with given chunk size + @available(*, deprecated) + public func chunks(size chunksize: Int) -> Array> { + var words = Array>() + words.reserveCapacity(count / chunksize) + for idx in stride(from: chunksize, through: count, by: chunksize) { + words.append(Array(self[idx - chunksize ..< idx])) // slow for large table + } + let remainder = suffix(count % chunksize) + if !remainder.isEmpty { + words.append(Array(remainder)) + } + return words + } + + public func md5() -> [Element] { + Digest.md5(self) + } + + public func sha1() -> [Element] { + Digest.sha1(self) + } + + public func sha224() -> [Element] { + Digest.sha224(self) + } + + public func sha256() -> [Element] { + Digest.sha256(self) + } + + public func sha384() -> [Element] { + Digest.sha384(self) + } + + public func sha512() -> [Element] { + Digest.sha512(self) + } + + public func sha2(_ variant: SHA2.Variant) -> [Element] { + Digest.sha2(self, variant: variant) + } + + public func sha3(_ variant: SHA3.Variant) -> [Element] { + Digest.sha3(self, variant: variant) + } + + public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + Checksum.crc32(self, seed: seed, reflect: reflect) + } + + public func crc32c(seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + Checksum.crc32c(self, seed: seed, reflect: reflect) + } + + public func crc16(seed: UInt16? = nil) -> UInt16 { + Checksum.crc16(self, seed: seed) + } + + public func encrypt(cipher: Cipher) throws -> [Element] { + try cipher.encrypt(self.slice) + } + + public func decrypt(cipher: Cipher) throws -> [Element] { + try cipher.decrypt(self.slice) + } + + public func authenticate(with authenticator: A) throws -> [Element] { + try authenticator.authenticate(self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Authenticator.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Authenticator.swift new file mode 100644 index 00000000..fd0ad4bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Authenticator.swift @@ -0,0 +1,20 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// Message authentication code. +public protocol Authenticator { + /// Calculate Message Authentication Code (MAC) for message. + func authenticate(_ bytes: Array) throws -> Array +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift new file mode 100644 index 00000000..8d55d0a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BatchedCollection.swift @@ -0,0 +1,81 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@usableFromInline +struct BatchedCollectionIndex { + let range: Range +} + +extension BatchedCollectionIndex: Comparable { + @usableFromInline + static func == (lhs: BatchedCollectionIndex, rhs: BatchedCollectionIndex) -> Bool { + lhs.range.lowerBound == rhs.range.lowerBound + } + + @usableFromInline + static func < (lhs: BatchedCollectionIndex, rhs: BatchedCollectionIndex) -> Bool { + lhs.range.lowerBound < rhs.range.lowerBound + } +} + +protocol BatchedCollectionType: Collection { + associatedtype Base: Collection +} + +@usableFromInline +struct BatchedCollection: Collection { + let base: Base + let size: Int + + @usableFromInline + init(base: Base, size: Int) { + self.base = base + self.size = size + } + + @usableFromInline + typealias Index = BatchedCollectionIndex + + private func nextBreak(after idx: Base.Index) -> Base.Index { + self.base.index(idx, offsetBy: self.size, limitedBy: self.base.endIndex) ?? self.base.endIndex + } + + @usableFromInline + var startIndex: Index { + Index(range: self.base.startIndex.. Index { + Index(range: idx.range.upperBound.. Base.SubSequence { + self.base[idx.range] + } +} + +extension Collection { + @inlinable + func batched(by size: Int) -> BatchedCollection { + BatchedCollection(base: self, size: size) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Bit.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Bit.swift new file mode 100644 index 00000000..f1ec5b79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Bit.swift @@ -0,0 +1,26 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public enum Bit: Int { + case zero + case one +} + +extension Bit { + @inlinable + func inverted() -> Bit { + self == .zero ? .one : .zero + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift new file mode 100644 index 00000000..f7911780 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockCipher.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +protocol BlockCipher: Cipher { + static var blockSize: Int { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift new file mode 100644 index 00000000..935cdfa3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockDecryptor.swift @@ -0,0 +1,98 @@ +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public class BlockDecryptor: Cryptor, Updatable { + @usableFromInline + let blockSize: Int + + @usableFromInline + let padding: Padding + + @usableFromInline + var worker: CipherModeWorker + + @usableFromInline + var accumulated = Array() + + @usableFromInline + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + @inlinable + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + // If a worker (eg GCM) can combine ciphertext + tag + // we need to remove tag from the ciphertext. + if !isLast && self.accumulated.count < self.blockSize + self.worker.additionalBufferSize { + return [] + } + + let accumulatedWithoutSuffix: Array + if self.worker.additionalBufferSize > 0 { + // FIXME: how slow is that? + accumulatedWithoutSuffix = Array(self.accumulated.prefix(self.accumulated.count - self.worker.additionalBufferSize)) + } else { + accumulatedWithoutSuffix = self.accumulated + } + + var processedBytesCount = 0 + var plaintext = Array(reserveCapacity: accumulatedWithoutSuffix.count) + // Processing in a block-size manner. It's good for block modes, but bad for stream modes. + for var chunk in accumulatedWithoutSuffix.batched(by: self.blockSize) { + if isLast || (accumulatedWithoutSuffix.count - processedBytesCount) >= blockSize { + let isLastChunk = processedBytesCount + chunk.count == accumulatedWithoutSuffix.count + + if isLast, isLastChunk, var finalizingWorker = worker as? FinalizingDecryptModeWorker { + chunk = try finalizingWorker.willDecryptLast(bytes: chunk + accumulated.suffix(worker.additionalBufferSize)) // tag size + } + + if !chunk.isEmpty { + plaintext += worker.decrypt(block: chunk) + } + + if isLast, isLastChunk, var finalizingWorker = worker as? FinalizingDecryptModeWorker { + plaintext = Array(try finalizingWorker.didDecryptLast(bytes: plaintext.slice)) + } + + processedBytesCount += chunk.count + } + } + accumulated.removeFirst(processedBytesCount) // super-slow + + if isLast { + if accumulatedWithoutSuffix.isEmpty, var finalizingWorker = worker as? FinalizingDecryptModeWorker { + try finalizingWorker.willDecryptLast(bytes: self.accumulated.suffix(self.worker.additionalBufferSize)) + plaintext = Array(try finalizingWorker.didDecryptLast(bytes: plaintext.slice)) + } + plaintext = self.padding.remove(from: plaintext, blockSize: self.blockSize) + } + + return plaintext + } + + public func seek(to position: Int) throws { + guard var worker = self.worker as? SeekableModeWorker else { + fatalError("Not supported") + } + + try worker.seek(to: position) + self.worker = worker + + accumulated = [] + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift new file mode 100644 index 00000000..0ab1ed61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockEncryptor.swift @@ -0,0 +1,62 @@ +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@usableFromInline +final class BlockEncryptor: Cryptor, Updatable { + private let blockSize: Int + private var worker: CipherModeWorker + private let padding: Padding + // Accumulated bytes. Not all processed bytes. + private var accumulated = Array(reserveCapacity: 16) + + private var lastBlockRemainder = 0 + + @usableFromInline + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + self.accumulated += bytes + + if isLast { + self.accumulated = self.padding.add(to: self.accumulated, blockSize: self.blockSize) + } + + var encrypted = Array(reserveCapacity: accumulated.count) + for chunk in self.accumulated.batched(by: self.blockSize) { + if isLast || chunk.count == self.blockSize { + encrypted += self.worker.encrypt(block: chunk) + } + } + + // Stream encrypts all, so it removes all elements + self.accumulated.removeFirst(encrypted.count) + + if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true { + encrypted = Array(try finalizingWorker.finalize(encrypt: encrypted.slice)) + } + + return encrypted + } + + @usableFromInline + func seek(to: Int) throws { + fatalError("Not supported") + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift new file mode 100644 index 00000000..ff410d7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockMode.swift @@ -0,0 +1,26 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public typealias CipherOperationOnBlock = (_ block: ArraySlice) -> Array? + +public protocol BlockMode { + var options: BlockModeOption { get } + //TODO: doesn't have to be public + @inlinable func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker + + var customBlockSize: Int? { get } +} + +typealias StreamMode = BlockMode diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift new file mode 100644 index 00000000..a21dd895 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/BlockModeOptions.swift @@ -0,0 +1,34 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public struct BlockModeOption: OptionSet { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + @usableFromInline + static let none = BlockModeOption(rawValue: 1 << 0) + + @usableFromInline + static let initializationVectorRequired = BlockModeOption(rawValue: 1 << 1) + + @usableFromInline + static let paddingRequired = BlockModeOption(rawValue: 1 << 2) + + @usableFromInline + static let useEncryptToDecrypt = BlockModeOption(rawValue: 1 << 3) +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift new file mode 100644 index 00000000..ca5d6462 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CBC.swift @@ -0,0 +1,76 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Cipher-block chaining (CBC) +// + +public struct CBC: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .paddingRequired] + + private let iv: Array + + public let customBlockSize: Int? = nil + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return CBCModeWorker(blockSize: blockSize, iv: self.iv.slice, cipherOperation: cipherOperation) + } +} + +struct CBCModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + var blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + @inlinable + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(xor(prev ?? iv, plaintext)) else { + return Array(plaintext) + } + self.prev = ciphertext.slice + return ciphertext + } + + @inlinable + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let plaintext = cipherOperation(ciphertext) else { + return Array(ciphertext) + } + let result: Array = xor(prev ?? self.iv, plaintext) + self.prev = ciphertext + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift new file mode 100644 index 00000000..a42cbbfa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CCM.swift @@ -0,0 +1,365 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// CCM mode combines the well known CBC-MAC with the well known counter mode of encryption. +// https://tools.ietf.org/html/rfc3610 +// https://csrc.nist.gov/publications/detail/sp/800-38c/final + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +/// Counter with Cipher Block Chaining-Message Authentication Code +public struct CCM: StreamMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + case invalidParameter + case fail + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let nonce: Array + private let additionalAuthenticatedData: Array? + private let tagLength: Int + private let messageLength: Int // total message length. need to know in advance + public let customBlockSize: Int? = nil + + // `authenticationTag` nil for encryption, known tag for decryption + /// For encryption, the value is set at the end of the encryption. + /// For decryption, this is a known Tag to validate against. + public var authenticationTag: Array? + + /// Initialize CCM + /// + /// - Parameters: + /// - iv: Initialization vector. Nonce. Valid length between 7 and 13 bytes. + /// - tagLength: Authentication tag length, in bytes. Value of {4, 6, 8, 10, 12, 14, 16}. + /// - messageLength: Plaintext message length (excluding tag if attached). Length have to be provided in advance. + /// - additionalAuthenticatedData: Additional authenticated data. + public init(iv: Array, tagLength: Int, messageLength: Int, additionalAuthenticatedData: Array? = nil) { + self.nonce = iv + self.tagLength = tagLength + self.additionalAuthenticatedData = additionalAuthenticatedData + self.messageLength = messageLength // - tagLength + } + + /// Initialize CCM + /// + /// - Parameters: + /// - iv: Initialization vector. Nonce. Valid length between 7 and 13 bytes. + /// - tagLength: Authentication tag length, in bytes. Value of {4, 6, 8, 10, 12, 14, 16}. + /// - messageLength: Plaintext message length (excluding tag if attached). Length have to be provided in advance. + /// - authenticationTag: Authentication Tag value if not concatenated to ciphertext. + /// - additionalAuthenticatedData: Additional authenticated data. + public init(iv: Array, tagLength: Int, messageLength: Int, authenticationTag: Array, additionalAuthenticatedData: Array? = nil) { + self.init(iv: iv, tagLength: tagLength, messageLength: messageLength, additionalAuthenticatedData: additionalAuthenticatedData) + self.authenticationTag = authenticationTag + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.nonce.isEmpty { + throw Error.invalidInitializationVector + } + + return CCMModeWorker(blockSize: blockSize, nonce: self.nonce.slice, messageLength: self.messageLength, additionalAuthenticatedData: self.additionalAuthenticatedData, tagLength: self.tagLength, cipherOperation: cipherOperation) + } +} + +class CCMModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker { + typealias Counter = Int + var counter = 0 + + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + private let tagLength: Int + private let messageLength: Int // total message length. need to know in advance + private let q: UInt8 + + let additionalBufferSize: Int + private var keystreamPosIdx = 0 + private let nonce: Array + private var last_y: ArraySlice = [] + private var keystream: Array = [] + // Known Tag used to validate during decryption + private var expectedTag: Array? + + public enum Error: Swift.Error { + case invalidParameter + } + + init(blockSize: Int, nonce: ArraySlice, messageLength: Int, additionalAuthenticatedData: [UInt8]?, expectedTag: Array? = nil, tagLength: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = 16 // CCM is defined for 128 block size + self.tagLength = tagLength + self.additionalBufferSize = tagLength + self.messageLength = messageLength + self.expectedTag = expectedTag + self.cipherOperation = cipherOperation + self.nonce = Array(nonce) + self.q = UInt8(15 - nonce.count) // n = 15-q + + let hasAssociatedData = additionalAuthenticatedData != nil && !additionalAuthenticatedData!.isEmpty + self.processControlInformation(nonce: self.nonce, tagLength: tagLength, hasAssociatedData: hasAssociatedData) + + if let aad = additionalAuthenticatedData, hasAssociatedData { + self.process(aad: aad) + } + } + + // For the very first time setup new IV (aka y0) from the block0 + private func processControlInformation(nonce: [UInt8], tagLength: Int, hasAssociatedData: Bool) { + let block0 = try! format(nonce: nonce, Q: UInt32(self.messageLength), q: self.q, t: UInt8(tagLength), hasAssociatedData: hasAssociatedData).slice + let y0 = self.cipherOperation(block0)!.slice + self.last_y = y0 + } + + private func process(aad: [UInt8]) { + let encodedAAD = format(aad: aad) + + for block_i in encodedAAD.batched(by: 16) { + let y_i = self.cipherOperation(xor(block_i, self.last_y))!.slice + self.last_y = y_i + } + } + + private func S(i: Int) throws -> [UInt8] { + let ctr = try format(counter: i, nonce: nonce, q: q) + return self.cipherOperation(ctr.slice)! + } + + @inlinable + func seek(to position: Int) throws { + self.counter = position + self.keystream = try self.S(i: position) + let offset = position % self.blockSize + self.keystreamPosIdx = offset + } + + func encrypt(block plaintext: ArraySlice) -> Array { + var result = Array(reserveCapacity: plaintext.count) + + var processed = 0 + while processed < plaintext.count { + // Need a full block here to update keystream and do CBC + if self.keystream.isEmpty || self.keystreamPosIdx == self.blockSize { + // y[i], where i is the counter. Can encrypt 1 block at a time + self.counter += 1 + guard let S = try? S(i: counter) else { return Array(plaintext) } + let plaintextP = addPadding(Array(plaintext), blockSize: blockSize) + guard let y = cipherOperation(xor(last_y, plaintextP)) else { return Array(plaintext) } + self.last_y = y.slice + + self.keystream = S + self.keystreamPosIdx = 0 + } + + let xored: Array = xor(plaintext[plaintext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) + keystreamPosIdx += xored.count + processed += xored.count + result += xored + } + return result + } + + @inlinable + func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice { + // concatenate T at the end + guard let S0 = try? S(i: 0) else { return ciphertext } + + let computedTag = xor(last_y.prefix(self.tagLength), S0) as ArraySlice + return ciphertext + computedTag + } + + // Decryption is stream + // CBC is block + private var accumulatedPlaintext: [UInt8] = [] + + func decrypt(block ciphertext: ArraySlice) -> Array { + var output = Array(reserveCapacity: ciphertext.count) + + do { + var currentCounter = self.counter + var processed = 0 + while processed < ciphertext.count { + // Need a full block here to update keystream and do CBC + // New keystream for a new block + if self.keystream.isEmpty || self.keystreamPosIdx == self.blockSize { + currentCounter += 1 + guard let S = try? S(i: currentCounter) else { return Array(ciphertext) } + self.keystream = S + self.keystreamPosIdx = 0 + } + + let xored: Array = xor(ciphertext[ciphertext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) // plaintext + keystreamPosIdx += xored.count + processed += xored.count + output += xored + self.counter = currentCounter + } + } + + // Accumulate plaintext for the MAC calculations at the end. + // It would be good to process it together though, here. + self.accumulatedPlaintext += output + + // Shouldn't return plaintext until validate tag. + // With incremental update, can't validate tag until all block are processed. + return output + } + + @inlinable + func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice { + // concatenate T at the end + let computedTag = Array(last_y.prefix(self.tagLength)) + guard let expectedTag = self.expectedTag, expectedTag == computedTag else { + throw CCM.Error.fail + } + + return plaintext + } + + @discardableResult + func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice { + // get tag of additionalBufferSize size + // `ciphertext` contains at least additionalBufferSize bytes + // overwrite expectedTag property used later for verification + guard let S0 = try? S(i: 0) else { return ciphertext } + self.expectedTag = xor(ciphertext.suffix(self.tagLength), S0) as [UInt8] + return ciphertext[ciphertext.startIndex..) throws -> ArraySlice { + + // Calculate Tag, from the last CBC block, for accumulated plaintext. + var processed = 0 + for block in self.accumulatedPlaintext.batched(by: self.blockSize) { + let blockP = addPadding(Array(block), blockSize: blockSize) + guard let y = cipherOperation(xor(last_y, blockP)) else { return plaintext } + self.last_y = y.slice + processed += block.count + } + self.accumulatedPlaintext.removeFirst(processed) + return plaintext + } +} + +// Q - octet length of P +// q - octet length of Q. Maximum length (in octets) of payload. An element of {2,3,4,5,6,7,8} +// t - octet length of T (MAC length). An element of {4,6,8,10,12,14,16} +private func format(nonce N: [UInt8], Q: UInt32, q: UInt8, t: UInt8, hasAssociatedData: Bool) throws -> [UInt8] { + var flags0: UInt8 = 0 + + if hasAssociatedData { + // 7 bit + flags0 |= (1 << 6) + } + + // 6,5,4 bit is t in 3 bits + flags0 |= (((t - 2) / 2) & 0x07) << 3 + + // 3,2,1 bit is q in 3 bits + flags0 |= ((q - 1) & 0x07) << 0 + + var block0: [UInt8] = Array(repeating: 0, count: 16) + block0[0] = flags0 + + // N in 1...(15-q) octets, n = 15-q + // n is an element of {7,8,9,10,11,12,13} + let n = 15 - Int(q) + guard (n + Int(q)) == 15 else { + // n+q == 15 + throw CCMModeWorker.Error.invalidParameter + } + block0[1...n] = N[0...(n - 1)] + + // Q in (16-q)...15 octets + block0[(16 - Int(q))...15] = Q.bytes(totalBytes: Int(q)).slice + + return block0 +} + +/// Formatting of the Counter Blocks. Ctr[i] +/// The counter generation function. +/// Q - octet length of P +/// q - octet length of Q. Maximum length (in octets) of payload. An element of {2,3,4,5,6,7,8} +private func format(counter i: Int, nonce N: [UInt8], q: UInt8) throws -> [UInt8] { + var flags0: UInt8 = 0 + + // bit 8,7 is Reserved + // bit 4,5,6 shall be set to 0 + // 3,2,1 bit is q in 3 bits + flags0 |= ((q - 1) & 0x07) << 0 + + var block = Array(repeating: 0, count: 16) // block[0] + block[0] = flags0 + + // N in 1...(15-q) octets, n = 15-q + // n is an element of {7,8,9,10,11,12,13} + let n = 15 - Int(q) + guard (n + Int(q)) == 15 else { + // n+q == 15 + throw CCMModeWorker.Error.invalidParameter + } + block[1...n] = N[0...(n - 1)] + + // [i]8q in (16-q)...15 octets + block[(16 - Int(q))...15] = i.bytes(totalBytes: Int(q)).slice + + return block +} + +/// Resulting can be partitioned into 16-octet blocks +private func format(aad: [UInt8]) -> [UInt8] { + let a = aad.count + + switch Double(a) { + case 0..<65280: // 2^16-2^8 + // [a]16 + return addPadding(a.bytes(totalBytes: 2) + aad, blockSize: 16) + case 65280..<4_294_967_296: // 2^32 + // [a]32 + return addPadding([0xFF, 0xFE] + a.bytes(totalBytes: 4) + aad, blockSize: 16) + case 4_294_967_296.., blockSize: Int) -> Array { + if bytes.isEmpty { + return Array(repeating: 0, count: blockSize) + } + + let remainder = bytes.count % blockSize + if remainder == 0 { + return bytes + } + + let paddingCount = blockSize - remainder + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift new file mode 100644 index 00000000..95e91add --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CFB.swift @@ -0,0 +1,102 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Cipher feedback (CFB) +// + +public struct CFB: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public enum SegmentSize: Int { + case cfb8 = 1 // Encrypt byte per byte + case cfb128 = 16 // Encrypt 16 bytes per 16 bytes (default) + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + private let segmentSize: SegmentSize + public let customBlockSize: Int? + + public init(iv: Array, segmentSize: SegmentSize = .cfb128) { + self.iv = iv + self.segmentSize = segmentSize + self.customBlockSize = segmentSize.rawValue + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if !(self.iv.count == blockSize || (segmentSize == .cfb8 && self.iv.count == AES.blockSize)) { + throw Error.invalidInitializationVector + } + + return CFBModeWorker(blockSize: blockSize, iv: self.iv.slice, segmentSize: segmentSize, cipherOperation: cipherOperation) + } +} + +struct CFBModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private let segmentSize: CFB.SegmentSize + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, segmentSize: CFB.SegmentSize, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.segmentSize = segmentSize + self.cipherOperation = cipherOperation + } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + switch segmentSize { + case .cfb128: + guard let ciphertext = cipherOperation(prev ?? iv) else { + return Array(plaintext) + } + self.prev = xor(plaintext, ciphertext.slice) + return Array(self.prev ?? []) + case .cfb8: + guard let ciphertext = cipherOperation(prev ?? iv) else { + return Array(plaintext) + } + let result = [Array(plaintext)[0] ^ Array(ciphertext)[0]] + self.prev = Array((prev ?? iv).dropFirst()) + [result[0]] + return result + } + } + + @inlinable + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + switch segmentSize { + case .cfb128: + guard let plaintext = cipherOperation(prev ?? iv) else { + return Array(ciphertext) + } + let result: Array = xor(plaintext, ciphertext) + prev = ciphertext + return result + case .cfb8: + guard let plaintext = cipherOperation(prev ?? iv) else { + return Array(ciphertext) + } + self.prev = Array((prev ?? iv).dropFirst()) + [Array(ciphertext)[0]] + return [Array(ciphertext)[0] ^ Array(plaintext)[0]] + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift new file mode 100644 index 00000000..f0074ae4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/CTR.swift @@ -0,0 +1,138 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Counter (CTR) + +public struct CTR: StreamMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + private let counter: Int + public let customBlockSize: Int? = nil + + public init(iv: Array, counter: Int = 0) { + self.iv = iv + self.counter = counter + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return CTRModeWorker(blockSize: blockSize, iv: self.iv.slice, counter: self.counter, cipherOperation: cipherOperation) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct CTRModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker { + typealias Counter = CTRCounter + + final class CTRCounter { + private let constPrefix: Array + private var value: UInt64 + //TODO: make it an updatable value, computing is too slow + var bytes: Array { + self.constPrefix + self.value.bytes() + } + + @inlinable + init(_ initialValue: Array) { + let halfIndex = initialValue.startIndex.advanced(by: initialValue.count / 2) + self.constPrefix = Array(initialValue[initialValue.startIndex.., startAt index: Int) { + self.init(buildCounterValue(nonce, counter: UInt64(index))) + } + + static func += (lhs: CTRCounter, rhs: Int) { + lhs.value += UInt64(rhs) + } + } + + let cipherOperation: CipherOperationOnBlock + let additionalBufferSize: Int = 0 + let iv: Array + var counter: CTRCounter + + private let blockSize: Int + + // The same keystream is used for the block length plaintext + // As new data is added, keystream suffix is used to xor operation. + private var keystream: Array + private var keystreamPosIdx = 0 + + init(blockSize: Int, iv: ArraySlice, counter: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.cipherOperation = cipherOperation + self.blockSize = blockSize + self.iv = Array(iv) + + // the first keystream is calculated from the nonce = initial value of counter + self.counter = CTRCounter(nonce: Array(iv), startAt: counter) + self.keystream = Array(cipherOperation(self.counter.bytes.slice)!) + } + + @inlinable + mutating func seek(to position: Int) throws { + let offset = position % self.blockSize + self.counter = CTRCounter(nonce: self.iv, startAt: position / self.blockSize) + self.keystream = Array(self.cipherOperation(self.counter.bytes.slice)!) + self.keystreamPosIdx = offset + } + + // plaintext is at most blockSize long + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + var result = Array(reserveCapacity: plaintext.count) + + var processed = 0 + while processed < plaintext.count { + // Update keystream + if self.keystreamPosIdx == self.blockSize { + self.counter += 1 + self.keystream = Array(self.cipherOperation(self.counter.bytes.slice)!) + self.keystreamPosIdx = 0 + } + + let xored: Array = xor(plaintext[plaintext.startIndex.advanced(by: processed)...], keystream[keystreamPosIdx...]) + keystreamPosIdx += xored.count + processed += xored.count + result += xored + } + + return result + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + self.encrypt(block: ciphertext) + } +} + +private func buildCounterValue(_ iv: Array, counter: UInt64) -> Array { + let noncePartLen = iv.count / 2 + let noncePrefix = iv[iv.startIndex.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public protocol CipherModeWorker { + var cipherOperation: CipherOperationOnBlock { get } + + // Additional space needed when incrementally process data + // eg. for GCM combined mode + var additionalBufferSize: Int { get } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array + + @inlinable + mutating func decrypt(block ciphertext: ArraySlice) -> Array +} + +/// Block workers use `BlockEncryptor` +public protocol BlockModeWorker: CipherModeWorker { + var blockSize: Int { get } +} + +public protocol CounterModeWorker: CipherModeWorker { + associatedtype Counter + var counter: Counter { get set } +} + +public protocol SeekableModeWorker: CipherModeWorker { + mutating func seek(to position: Int) throws +} + +/// Stream workers use `StreamEncryptor` +public protocol StreamModeWorker: CipherModeWorker { +} + +public protocol FinalizingEncryptModeWorker: CipherModeWorker { + // Any final calculations, eg. calculate tag + // Called after the last block is encrypted + mutating func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice +} + +public protocol FinalizingDecryptModeWorker: CipherModeWorker { + // Called before decryption, hence input is ciphertext. + // ciphertext is either a last block, or a tag (for stream workers) + @discardableResult + mutating func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice + // Called after decryption, hence input is ciphertext + mutating func didDecryptLast(bytes plaintext: ArraySlice) throws -> ArraySlice + // Any final calculations, eg. calculate tag + // Called after the last block is encrypted + mutating func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift new file mode 100644 index 00000000..4e8f9ba0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/ECB.swift @@ -0,0 +1,53 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Electronic codebook (ECB) +// + +public struct ECB: BlockMode { + public let options: BlockModeOption = .paddingRequired + public let customBlockSize: Int? = nil + + public init() { + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + ECBModeWorker(blockSize: blockSize, cipherOperation: cipherOperation) + } +} + +struct ECBModeWorker: BlockModeWorker { + typealias Element = Array + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + + init(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.cipherOperation = cipherOperation + } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(plaintext) else { + return Array(plaintext) + } + return ciphertext + } + + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + self.encrypt(block: ciphertext) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift new file mode 100644 index 00000000..2aaeb342 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/GCM.swift @@ -0,0 +1,374 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Galois/Counter Mode (GCM) +// https://csrc.nist.gov/publications/detail/sp/800-38d/final +// ref: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.694.695&rep=rep1&type=pdf +// + +public final class GCM: BlockMode { + public enum Mode { + /// In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. + case combined + /// Some applications may need to store the authentication tag and the encrypted message at different locations. + case detached + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + /// Special symbol FAIL that indicates that the inputs are not authentic. + case fail + } + + private let iv: Array + private let additionalAuthenticatedData: Array? + private let mode: Mode + public let customBlockSize: Int? = nil + + /// Length of authentication tag, in bytes. + /// For encryption, the value is given as init parameter. + /// For decryption, the length of given authentication tag is used. + private let tagLength: Int + + // `authenticationTag` nil for encryption, known tag for decryption + /// For encryption, the value is set at the end of the encryption. + /// For decryption, this is a known Tag to validate against. + public var authenticationTag: Array? + + // encrypt + /// Possible tag lengths: 4,8,12,13,14,15,16 + public init(iv: Array, additionalAuthenticatedData: Array? = nil, tagLength: Int = 16, mode: Mode = .detached) { + self.iv = iv + self.additionalAuthenticatedData = additionalAuthenticatedData + self.mode = mode + self.tagLength = tagLength + } + + // decrypt + public convenience init(iv: Array, authenticationTag: Array, additionalAuthenticatedData: Array? = nil, mode: Mode = .detached) { + self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) + self.authenticationTag = authenticationTag + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.iv.isEmpty { + throw Error.invalidInitializationVector + } + + let worker = GCMModeWorker(iv: iv.slice, aad: self.additionalAuthenticatedData?.slice, expectedTag: self.authenticationTag, tagLength: self.tagLength, mode: self.mode, cipherOperation: cipherOperation) + worker.didCalculateTag = { [weak self] tag in + self?.authenticationTag = tag + } + return worker + } +} + +// MARK: - Worker + +final class GCMModeWorker: BlockModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker { + let cipherOperation: CipherOperationOnBlock + + // Callback called when authenticationTag is ready + var didCalculateTag: ((Array) -> Void)? + + private let tagLength: Int + // GCM nonce is 96-bits by default. It's the most effective length for the IV + private static let nonceSize = 12 + + // GCM is designed for 128-bit ciphers like AES (but not really for Blowfish). 64-bit mode is not implemented. + let blockSize = 16 // 128 bit + let additionalBufferSize: Int + private let iv: ArraySlice + private let mode: GCM.Mode + private var counter: UInt128 + private let eky0: UInt128 // move to GF? + private let h: UInt128 + + // Additional authenticated data + private let aad: ArraySlice? + // Known Tag used to validate during decryption + private var expectedTag: Array? + + // Note: need new worker to reset instance + // Use empty aad if not specified. AAD is optional. + private lazy var gf: GF = { + if let aad = aad { + return GF(aad: Array(aad), h: h, blockSize: blockSize) + } + return GF(aad: [UInt8](), h: h, blockSize: blockSize) + }() + + init(iv: ArraySlice, aad: ArraySlice? = nil, expectedTag: Array? = nil, tagLength: Int, mode: GCM.Mode, cipherOperation: @escaping CipherOperationOnBlock) { + self.cipherOperation = cipherOperation + self.iv = iv + self.mode = mode + self.aad = aad + self.expectedTag = expectedTag + self.tagLength = tagLength + self.h = UInt128(cipherOperation(Array(repeating: 0, count: self.blockSize).slice)!) // empty block + + if mode == .combined { + self.additionalBufferSize = tagLength + } else { + self.additionalBufferSize = 0 + } + + // Assume nonce is 12 bytes long, otherwise initial counter would be calulated from GHASH + // counter = GF.ghash(aad: [UInt8](), ciphertext: nonce) + if iv.count == GCMModeWorker.nonceSize { + self.counter = makeCounter(nonce: Array(self.iv)) + } else { + self.counter = GF.ghash(h: self.h, aad: [UInt8](), ciphertext: Array(iv), blockSize: self.blockSize) + } + + // Set constants + self.eky0 = UInt128(cipherOperation(self.counter.bytes.slice)!) + } + + func encrypt(block plaintext: ArraySlice) -> Array { + self.counter = incrementCounter(self.counter) + + guard let ekyN = cipherOperation(counter.bytes.slice) else { + return Array(plaintext) + } + + // plaintext block ^ ek1 + let ciphertext = xor(plaintext, ekyN) as Array + + // update ghash incrementally + gf.ghashUpdate(block: ciphertext) + + return Array(ciphertext) + } + + @inlinable + func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice { + // Calculate MAC tag. + let ghash = self.gf.ghashFinish() + let tag = Array((ghash ^ self.eky0).bytes.prefix(self.tagLength)) + + // Notify handler + self.didCalculateTag?(tag) + + switch self.mode { + case .combined: + return (ciphertext + tag).slice + case .detached: + return ciphertext + } + } + + @inlinable + func decrypt(block ciphertext: ArraySlice) -> Array { + self.counter = incrementCounter(self.counter) + + // update ghash incrementally + self.gf.ghashUpdate(block: Array(ciphertext)) + + guard let ekN = cipherOperation(counter.bytes.slice) else { + return Array(ciphertext) + } + + // ciphertext block ^ ek1 + let plaintext = xor(ciphertext, ekN) as Array + return plaintext + } + + // The authenticated decryption operation has five inputs: K, IV , C, A, and T. It has only a single + // output, either the plaintext value P or a special symbol FAIL that indicates that the inputs are not + // authentic. + @discardableResult + func willDecryptLast(bytes ciphertext: ArraySlice) throws -> ArraySlice { + // Validate tag + switch self.mode { + case .combined: + // overwrite expectedTag property used later for verification + self.expectedTag = Array(ciphertext.suffix(self.tagLength)) + return ciphertext[ciphertext.startIndex..) throws -> ArraySlice { + // Calculate MAC tag. + let ghash = self.gf.ghashFinish() + let computedTag = Array((ghash ^ self.eky0).bytes.prefix(self.tagLength)) + + // Validate tag + guard let expectedTag = self.expectedTag, computedTag == expectedTag else { + throw GCM.Error.fail + } + + return plaintext + } + + func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice { + // do nothing + plaintext + } +} + +// MARK: - Local utils + +private func makeCounter(nonce: Array) -> UInt128 { + UInt128(nonce + [0, 0, 0, 1]) +} + +// Successive counter values are generated using the function incr(), which treats the rightmost 32 +// bits of its argument as a nonnegative integer with the least significant bit on the right +private func incrementCounter(_ counter: UInt128) -> UInt128 { + let b = counter.i.b + 1 + let a = (b == 0 ? counter.i.a + 1 : counter.i.a) + return UInt128((a, b)) +} + +// If data is not a multiple of block size bytes long then the remainder is zero padded +// Note: It's similar to ZeroPadding, but it's not the same. +private func addPadding(_ bytes: Array, blockSize: Int) -> Array { + if bytes.isEmpty { + return Array(repeating: 0, count: blockSize) + } + + let remainder = bytes.count % blockSize + if remainder == 0 { + return bytes + } + + let paddingCount = blockSize - remainder + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes +} + +// MARK: - GF + +/// The Field GF(2^128) +private final class GF { + static let r = UInt128(a: 0xE100000000000000, b: 0) + + let blockSize: Int + let h: UInt128 + + // AAD won't change + let aadLength: Int + + // Updated for every consumed block + var ciphertextLength: Int + + // Start with 0 + var x: UInt128 + + init(aad: [UInt8], h: UInt128, blockSize: Int) { + self.blockSize = blockSize + self.aadLength = aad.count + self.ciphertextLength = 0 + self.h = h + self.x = 0 + + // Calculate for AAD at the begining + self.x = GF.calculateX(aad: aad, x: self.x, h: h, blockSize: blockSize) + } + + @discardableResult + func ghashUpdate(block ciphertextBlock: Array) -> UInt128 { + self.ciphertextLength += ciphertextBlock.count + self.x = GF.calculateX(block: addPadding(ciphertextBlock, blockSize: self.blockSize), x: self.x, h: self.h, blockSize: self.blockSize) + return self.x + } + + func ghashFinish() -> UInt128 { + // len(A) || len(C) + let len = UInt128(a: UInt64(aadLength * 8), b: UInt64(ciphertextLength * 8)) + x = GF.multiply(self.x ^ len, self.h) + return self.x + } + + // GHASH. One-time calculation + static func ghash(x startx: UInt128 = 0, h: UInt128, aad: Array, ciphertext: Array, blockSize: Int) -> UInt128 { + var x = self.calculateX(aad: aad, x: startx, h: h, blockSize: blockSize) + x = self.calculateX(ciphertext: ciphertext, x: x, h: h, blockSize: blockSize) + + // len(aad) || len(ciphertext) + let len = UInt128(a: UInt64(aad.count * 8), b: UInt64(ciphertext.count * 8)) + x = self.multiply(x ^ len, h) + + return x + } + + // Calculate Ciphertext part, for all blocks + // Not used with incremental calculation. + private static func calculateX(ciphertext: [UInt8], x startx: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let pciphertext = addPadding(ciphertext, blockSize: blockSize) + let blocksCount = pciphertext.count / blockSize + + var x = startx + for i in 0.., x: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let k = x ^ UInt128(ciphertextBlock) + return self.multiply(k, h) + } + + // Calculate AAD part, for all blocks + private static func calculateX(aad: [UInt8], x startx: UInt128, h: UInt128, blockSize: Int) -> UInt128 { + let paad = addPadding(aad, blockSize: blockSize) + let blocksCount = paad.count / blockSize + + var x = startx + for i in 0.. UInt128 { + var z: UInt128 = 0 + var v = x + var k = UInt128(a: 1 << 63, b: 0) + + for _ in 0..<128 { + if y & k == k { + z = z ^ v + } + + if v & 1 != 1 { + v = v >> 1 + } else { + v = (v >> 1) ^ self.r + } + + k = k >> 1 + } + + return z + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/OCB.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/OCB.swift new file mode 100644 index 00000000..4741793c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/OCB.swift @@ -0,0 +1,398 @@ +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// The OCB Authenticated-Encryption Algorithm +// https://tools.ietf.org/html/rfc7253 +// + +public final class OCB: BlockMode { + + public enum Mode { + /// In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. + case combined + /// Some applications may need to store the authentication tag and the encrypted message at different locations. + case detached + } + + public let options: BlockModeOption = [.initializationVectorRequired] + + public enum Error: Swift.Error { + case invalidNonce + case fail + } + + private let N: Array + private let additionalAuthenticatedData: Array? + private let mode: Mode + public let customBlockSize: Int? = nil + + /// Length of authentication tag, in bytes. + /// For encryption, the value is given as init parameter. + /// For decryption, the length of given authentication tag is used. + private let tagLength: Int + + // `authenticationTag` nil for encryption, known tag for decryption + /// For encryption, the value is set at the end of the encryption. + /// For decryption, this is a known Tag to validate against. + public var authenticationTag: Array? + + // encrypt + public init(nonce N: Array, additionalAuthenticatedData: Array? = nil, tagLength: Int = 16, mode: Mode = .detached) { + self.N = N + self.additionalAuthenticatedData = additionalAuthenticatedData + self.mode = mode + self.tagLength = tagLength + } + + // decrypt + @inlinable + public convenience init(nonce N: Array, authenticationTag: Array, additionalAuthenticatedData: Array? = nil, mode: Mode = .detached) { + self.init(nonce: N, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) + self.authenticationTag = authenticationTag + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.N.isEmpty || self.N.count > 15 { + throw Error.invalidNonce + } + + let worker = OCBModeWorker(N: N.slice, aad: self.additionalAuthenticatedData?.slice, expectedTag: self.authenticationTag, tagLength: self.tagLength, mode: self.mode, cipherOperation: cipherOperation, encryptionOperation: encryptionOperation) + worker.didCalculateTag = { [weak self] tag in + self?.authenticationTag = tag + } + return worker + } +} + +// MARK: - Worker + +final class OCBModeWorker: BlockModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker { + + let cipherOperation: CipherOperationOnBlock + var hashOperation: CipherOperationOnBlock! + + // Callback called when authenticationTag is ready + var didCalculateTag: ((Array) -> Void)? + + private let tagLength: Int + + let blockSize = 16 // 128 bit + var additionalBufferSize: Int + private let mode: OCB.Mode + + // Additional authenticated data + private let aad: ArraySlice? + // Known Tag used to validate during decryption + private var expectedTag: Array? + + /* + * KEY-DEPENDENT + */ + // NOTE: elements are lazily calculated + private var l = [Array]() + private var lAsterisk: Array + private var lDollar: Array + + /* + * PER-ENCRYPTION/DECRYPTION + */ + private var mainBlockCount: UInt64 + private var offsetMain: Array + private var checksum: Array + + init(N: ArraySlice, aad: ArraySlice? = nil, expectedTag: Array? = nil, tagLength: Int, mode: OCB.Mode, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) { + + self.cipherOperation = cipherOperation + self.hashOperation = encryptionOperation + self.mode = mode + self.aad = aad + self.expectedTag = expectedTag + self.tagLength = tagLength + + if mode == .combined { + self.additionalBufferSize = tagLength + } else { + self.additionalBufferSize = 0 + } + + /* + * KEY-DEPENDENT INITIALIZATION + */ + + let zeros = Array(repeating: 0, count: self.blockSize) + self.lAsterisk = self.hashOperation(zeros.slice)! /// L_* = ENCIPHER(K, zeros(128)) + self.lDollar = double(self.lAsterisk) /// L_$ = double(L_*) + self.l.append(double(self.lDollar)) /// L_0 = double(L_$) + + /* + * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALIZATION + */ + + /// Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N + var nonce = Array(repeating: 0, count: blockSize) + nonce[(nonce.count - N.count)...] = N + nonce[0] = UInt8(tagLength) << 4 + nonce[blockSize - 1 - N.count] |= 1 + + /// bottom = str2num(Nonce[123..128]) + let bottom = nonce[15] & 0x3F + + /// Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) + nonce[15] &= 0xC0 + let Ktop = self.hashOperation(nonce.slice)! + + /// Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) + let Stretch = Ktop + xor(Ktop[0..<8], Ktop[1..<9]) + + /// Offset_0 = Stretch[1+bottom..128+bottom] + var offsetMAIN_0 = Array(repeating: 0, count: blockSize) + let bits = bottom % 8 + let bytes = Int(bottom / 8) + if bits == 0 { + offsetMAIN_0[0..> (8 - bits))) + } + } + + self.mainBlockCount = 0 + self.offsetMain = Array(offsetMAIN_0.slice) + self.checksum = Array(repeating: 0, count: self.blockSize) /// Checksum_0 = zeros(128) + } + + /// L_i = double(L_{i-1}) for every integer i > 0 + func getLSub(_ n: Int) -> Array { + while n >= self.l.count { + self.l.append(double(self.l.last!)) + } + return self.l[n] + } + + func computeTag() -> Array { + + let sum = self.hashAAD() + + /// Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) + return xor(self.hashOperation(xor(xor(self.checksum, self.offsetMain).slice, self.lDollar))!, sum) + } + + func hashAAD() -> Array { + var sum = Array(repeating: 0, count: blockSize) + + guard let aad = self.aad else { + return sum + } + + var offset = Array(repeating: 0, count: blockSize) + var blockCount: UInt64 = 1 + for aadBlock in aad.batched(by: self.blockSize) { + + if aadBlock.count == self.blockSize { + + /// Offset_i = Offset_{i-1} xor L_{ntz(i)} + offset = xor(offset, self.getLSub(ntz(blockCount))) + + /// Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) + sum = xor(sum, self.hashOperation(xor(aadBlock, offset))!) + } else { + if !aadBlock.isEmpty { + + /// Offset_* = Offset_m xor L_* + offset = xor(offset, self.lAsterisk) + + /// CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* + let cipherInput: Array = xor(extend(aadBlock, size: blockSize), offset) + + /// Sum = Sum_m xor ENCIPHER(K, CipherInput) + sum = xor(sum, self.hashOperation(cipherInput.slice)!) + } + } + blockCount += 1 + } + + return sum + } + + func encrypt(block plaintext: ArraySlice) -> Array { + + if plaintext.count == self.blockSize { + return self.processBlock(block: plaintext, forEncryption: true) + } else { + return self.processFinalBlock(block: plaintext, forEncryption: true) + } + } + + func finalize(encrypt ciphertext: ArraySlice) throws -> ArraySlice { + + let tag = self.computeTag() + + self.didCalculateTag?(tag) + + switch self.mode { + case .combined: + return ciphertext + tag + case .detached: + return ciphertext + } + } + + func decrypt(block ciphertext: ArraySlice) -> Array { + + if ciphertext.count == self.blockSize { + return self.processBlock(block: ciphertext, forEncryption: false) + } else { + return self.processFinalBlock(block: ciphertext, forEncryption: false) + } + } + + func finalize(decrypt plaintext: ArraySlice) throws -> ArraySlice { + // do nothing + plaintext + } + + private func processBlock(block: ArraySlice, forEncryption: Bool) -> Array { + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks + */ + + self.mainBlockCount += 1 + + /// Offset_i = Offset_{i-1} xor L_{ntz(i)} + self.offsetMain = xor(self.offsetMain, self.getLSub(ntz(self.mainBlockCount))) + + /// C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) + /// P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) + var mainBlock = Array(block) + mainBlock = xor(mainBlock, offsetMain) + mainBlock = self.cipherOperation(mainBlock.slice)! + mainBlock = xor(mainBlock, self.offsetMain) + + /// Checksum_i = Checksum_{i-1} xor P_i + if forEncryption { + self.checksum = xor(self.checksum, block) + } else { + self.checksum = xor(self.checksum, mainBlock) + } + + return mainBlock + } + + private func processFinalBlock(block: ArraySlice, forEncryption: Bool) -> Array { + + let out: Array + + if block.isEmpty { + /// C_* = + /// P_* = + out = [] + + } else { + + /// Offset_* = Offset_m xor L_* + self.offsetMain = xor(self.offsetMain, self.lAsterisk) + + /// Pad = ENCIPHER(K, Offset_*) + let Pad = self.hashOperation(self.offsetMain.slice)! + + /// C_* = P_* xor Pad[1..bitlen(P_*)] + /// P_* = C_* xor Pad[1..bitlen(C_*)] + out = xor(block, Pad[0..) throws -> ArraySlice { + // Validate tag + switch self.mode { + case .combined: + // overwrite expectedTag property used later for verification + self.expectedTag = Array(ciphertext.suffix(self.tagLength)) + return ciphertext[ciphertext.startIndex..) throws -> ArraySlice { + // Calculate MAC tag. + let computedTag = self.computeTag() + + // Validate tag + guard let expectedTag = self.expectedTag, computedTag == expectedTag else { + throw OCB.Error.fail + } + + return plaintext + } +} + +// MARK: - Local utils + +private func ntz(_ x: UInt64) -> Int { + if x == 0 { + return 64 + } + + var xv = x + var n = 0 + while (xv & 1) == 0 { + n += 1 + xv = xv >> 1 + } + return n +} + +private func double(_ block: Array) -> Array { + var ( carry, result) = shiftLeft(block) + + /* + * NOTE: This construction is an attempt at a constant-time implementation. + */ + result[15] ^= (0x87 >> ((1 - carry) << 3)) + + return result +} + +private func shiftLeft(_ block: Array) -> (UInt8, Array) { + var output = Array(repeating: 0, count: block.count) + + var bit: UInt8 = 0 + + for i in 0..> 7) & 1 + } + return (bit, output) +} + +private func extend(_ block: ArraySlice, size: Int) -> Array { + var output = Array(repeating: 0, count: size) + output[0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Output Feedback (OFB) +// + +public struct OFB: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .useEncryptToDecrypt] + private let iv: Array + public let customBlockSize: Int? = nil + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return OFBModeWorker(blockSize: blockSize, iv: self.iv.slice, cipherOperation: cipherOperation) + } +} + +struct OFBModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + let blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(prev ?? iv) else { + return Array(plaintext) + } + self.prev = ciphertext.slice + return xor(plaintext, ciphertext) + } + + @inlinable + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let decrypted = cipherOperation(prev ?? iv) else { + return Array(ciphertext) + } + let plaintext: Array = xor(decrypted, ciphertext) + prev = decrypted.slice + return plaintext + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift new file mode 100644 index 00000000..eafd8bea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/BlockMode/PCBC.swift @@ -0,0 +1,74 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Propagating Cipher Block Chaining (PCBC) +// + +public struct PCBC: BlockMode { + public enum Error: Swift.Error { + /// Invalid IV + case invalidInitializationVector + } + + public let options: BlockModeOption = [.initializationVectorRequired, .paddingRequired] + private let iv: Array + public let customBlockSize: Int? = nil + + public init(iv: Array) { + self.iv = iv + } + + public func worker(blockSize: Int, cipherOperation: @escaping CipherOperationOnBlock, encryptionOperation: @escaping CipherOperationOnBlock) throws -> CipherModeWorker { + if self.iv.count != blockSize { + throw Error.invalidInitializationVector + } + + return PCBCModeWorker(blockSize: blockSize, iv: self.iv.slice, cipherOperation: cipherOperation) + } +} + +struct PCBCModeWorker: BlockModeWorker { + let cipherOperation: CipherOperationOnBlock + var blockSize: Int + let additionalBufferSize: Int = 0 + private let iv: ArraySlice + private var prev: ArraySlice? + + @inlinable + init(blockSize: Int, iv: ArraySlice, cipherOperation: @escaping CipherOperationOnBlock) { + self.blockSize = blockSize + self.iv = iv + self.cipherOperation = cipherOperation + } + + @inlinable + mutating func encrypt(block plaintext: ArraySlice) -> Array { + guard let ciphertext = cipherOperation(xor(prev ?? iv, plaintext)) else { + return Array(plaintext) + } + self.prev = xor(plaintext, ciphertext.slice) + return ciphertext + } + + @inlinable + mutating func decrypt(block ciphertext: ArraySlice) -> Array { + guard let plaintext = cipherOperation(ciphertext) else { + return Array(ciphertext) + } + let result: Array = xor(prev ?? self.iv, plaintext) + self.prev = xor(result, ciphertext) + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Blowfish.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Blowfish.swift new file mode 100644 index 00000000..8876fca2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Blowfish.swift @@ -0,0 +1,537 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// https://en.wikipedia.org/wiki/Blowfish_(cipher) +// Based on Paul Kocher implementation +// + +public final class Blowfish { + public enum Error: Swift.Error { + /// Data padding is required + case dataPaddingRequired + /// Invalid key or IV + case invalidKeyOrInitializationVector + /// Invalid IV + case invalidInitializationVector + /// Invalid block mode + case invalidBlockMode + } + + public static let blockSize: Int = 8 // 64 bit + public let keySize: Int + + private let blockMode: BlockMode + private let padding: Padding + private var decryptWorker: CipherModeWorker! + private var encryptWorker: CipherModeWorker! + + private let N = 16 // rounds + private var P: Array + private var S: Array> + private let origP: Array = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, + 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, + 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, + 0xb5470917, 0x9216d5d9, 0x8979fb1b + ] + + private let origS: Array> = [ + [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ], + [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ], + [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ], + [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ] + ] + + public init(key: Array, blockMode: BlockMode = CBC(iv: Array(repeating: 0, count: Blowfish.blockSize)), padding: Padding) throws { + precondition(key.count >= 5 && key.count <= 56) + + self.blockMode = blockMode + self.padding = padding + self.keySize = key.count + + self.S = self.origS + self.P = self.origP + + self.expandKey(key: key) + try self.setupBlockModeWorkers() + } + + private func setupBlockModeWorkers() throws { + self.encryptWorker = try self.blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: self.encrypt, encryptionOperation: self.encrypt) + + if self.blockMode.options.contains(.useEncryptToDecrypt) { + self.decryptWorker = try self.blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: self.encrypt, encryptionOperation: self.encrypt) + } else { + self.decryptWorker = try self.blockMode.worker(blockSize: Blowfish.blockSize, cipherOperation: self.decrypt, encryptionOperation: self.encrypt) + } + } + + private func reset() { + self.S = self.origS + self.P = self.origP + // todo expand key + } + + private func expandKey(key: Array) { + var j = 0 + for i in 0..<(self.N + 2) { + var data: UInt32 = 0x0 + for _ in 0..<4 { + data = (data << 8) | UInt32(key[j]) + j += 1 + if j >= key.count { + j = 0 + } + } + self.P[i] ^= data + } + + var datal: UInt32 = 0 + var datar: UInt32 = 0 + + for i in stride(from: 0, to: self.N + 2, by: 2) { + self.encryptBlowfishBlock(l: &datal, r: &datar) + self.P[i] = datal + self.P[i + 1] = datar + } + + for i in 0..<4 { + for j in stride(from: 0, to: 256, by: 2) { + self.encryptBlowfishBlock(l: &datal, r: &datar) + self.S[i][j] = datal + self.S[i][j + 1] = datar + } + } + } + + fileprivate func encrypt(block: ArraySlice) -> Array? { + var result = Array() + + var l = UInt32(bytes: block[block.startIndex..> 24) & 0xff), + UInt8((l >> 16) & 0xff) + ] + result += [ + UInt8((l >> 8) & 0xff), + UInt8((l >> 0) & 0xff) + ] + result += [ + UInt8((r >> 24) & 0xff), + UInt8((r >> 16) & 0xff) + ] + result += [ + UInt8((r >> 8) & 0xff), + UInt8((r >> 0) & 0xff) + ] + + return result + } + + fileprivate func decrypt(block: ArraySlice) -> Array? { + var result = Array() + + var l = UInt32(bytes: block[block.startIndex..> 24) & 0xff), + UInt8((l >> 16) & 0xff) + ] + result += [ + UInt8((l >> 8) & 0xff), + UInt8((l >> 0) & 0xff) + ] + result += [ + UInt8((r >> 24) & 0xff), + UInt8((r >> 16) & 0xff) + ] + result += [ + UInt8((r >> 8) & 0xff), + UInt8((r >> 0) & 0xff) + ] + return result + } + + /// Encrypts the 8-byte padded buffer + /// + /// - Parameters: + /// - l: left half + /// - r: right half + private func encryptBlowfishBlock(l: inout UInt32, r: inout UInt32) { + var Xl = l + var Xr = r + + for i in 0.. UInt32 { + let f1 = self.S[0][Int(x >> 24) & 0xff] + let f2 = self.S[1][Int(x >> 16) & 0xff] + let f3 = self.S[2][Int(x >> 8) & 0xff] + let f4 = self.S[3][Int(x & 0xff)] + return ((f1 &+ f2) ^ f3) &+ f4 + } +} + +extension Blowfish: Cipher { + /// Encrypt the 8-byte padded buffer, block by block. Note that for amounts of data larger than a block, it is not safe to just call encrypt() on successive blocks. + /// + /// - Parameter bytes: Plaintext data + /// - Returns: Encrypted data + public func encrypt(_ bytes: C) throws -> Array where C.Element == UInt8, C.Index == Int { + let bytes = self.padding.add(to: Array(bytes), blockSize: Blowfish.blockSize) // FIXME: Array(bytes) copies + + var out = Array() + out.reserveCapacity(bytes.count) + + for chunk in bytes.batched(by: Blowfish.blockSize) { + out += self.encryptWorker.encrypt(block: chunk) + } + + if self.blockMode.options.contains(.paddingRequired) && (out.count % Blowfish.blockSize != 0) { + throw Error.dataPaddingRequired + } + + return out + } + + /// Decrypt the 8-byte padded buffer + /// + /// - Parameter bytes: Ciphertext data + /// - Returns: Plaintext data + public func decrypt(_ bytes: C) throws -> Array where C.Element == UInt8, C.Index == Int { + if self.blockMode.options.contains(.paddingRequired) && (bytes.count % Blowfish.blockSize != 0) { + throw Error.dataPaddingRequired + } + + var out = Array() + out.reserveCapacity(bytes.count) + + for chunk in Array(bytes).batched(by: Blowfish.blockSize) { + out += self.decryptWorker.decrypt(block: chunk) // FIXME: copying here is innefective + } + + out = self.padding.remove(from: out, blockSize: Blowfish.blockSize) + + return out + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift new file mode 100644 index 00000000..941e4d1f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CBCMAC.swift @@ -0,0 +1,30 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public final class CBCMAC: CMAC { + public override func authenticate(_ bytes: Array) throws -> Array { + var inBytes = bytes + bitPadding(to: &inBytes, blockSize: CMAC.BlockSize) + let blocks = inBytes.batched(by: CMAC.BlockSize) + + var lastBlockEncryptionResult: [UInt8] = CBCMAC.Zero + try blocks.forEach { block in + let aes = try AES(key: Array(key), blockMode: CBC(iv: lastBlockEncryptionResult), padding: .noPadding) + lastBlockEncryptionResult = try aes.encrypt(block) + } + + return lastBlockEncryptionResult + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CMAC.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CMAC.swift new file mode 100644 index 00000000..f0e691cd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CMAC.swift @@ -0,0 +1,106 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public class CMAC: Authenticator { + public enum Error: Swift.Error { + case wrongKeyLength + } + + internal let key: SecureBytes + + internal static let BlockSize: Int = 16 + internal static let Zero: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + private static let Rb: Array = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87] + + public init(key: Array) throws { + self.key = SecureBytes(bytes: key) + } + + // MARK: Authenticator + + // AES-CMAC + public func authenticate(_ bytes: Array) throws -> Array { + let cipher = try AES(key: Array(key), blockMode: CBC(iv: CMAC.Zero), padding: .noPadding) + return try self.authenticate(bytes, cipher: cipher) + } + + // CMAC using a Cipher + public func authenticate(_ bytes: Array, cipher: Cipher) throws -> Array { + let l = try cipher.encrypt(CMAC.Zero) + var subKey1 = self.leftShiftOneBit(l) + if (l[0] & 0x80) != 0 { + subKey1 = xor(CMAC.Rb, subKey1) + } + var subKey2 = self.leftShiftOneBit(subKey1) + if (subKey1[0] & 0x80) != 0 { + subKey2 = xor(CMAC.Rb, subKey2) + } + + let lastBlockComplete: Bool + let blockCount = (bytes.count + CMAC.BlockSize - 1) / CMAC.BlockSize + if blockCount == 0 { + lastBlockComplete = false + } else { + lastBlockComplete = bytes.count % CMAC.BlockSize == 0 + } + var paddedBytes = bytes + if !lastBlockComplete { + bitPadding(to: &paddedBytes, blockSize: CMAC.BlockSize) + } + + var blocks = Array(paddedBytes.batched(by: CMAC.BlockSize)) + var lastBlock = blocks.popLast()! + if lastBlockComplete { + lastBlock = xor(lastBlock, subKey1) + } else { + lastBlock = xor(lastBlock, subKey2) + } + + var x = Array(repeating: 0x00, count: CMAC.BlockSize) + var y = Array(repeating: 0x00, count: CMAC.BlockSize) + for block in blocks { + y = xor(block, x) + x = try cipher.encrypt(y) + } + // the difference between CMAC and CBC-MAC is that CMAC xors the final block with a secret value + y = self.process(lastBlock: lastBlock, with: x) + return try cipher.encrypt(y) + } + + func process(lastBlock: ArraySlice, with x: [UInt8]) -> [UInt8] { + xor(lastBlock, x) + } + + // MARK: Helper methods + + /** + Performs left shift by one bit to the bit string aquired after concatenating al bytes in the byte array + - parameters: + - bytes: byte array + - returns: bit shifted bit string split again in array of bytes + */ + private func leftShiftOneBit(_ bytes: Array) -> Array { + var shifted = Array(repeating: 0x00, count: bytes.count) + let last = bytes.count - 1 + for index in 0..= 0) + var carry = word + var i = shift + while carry > 0 { + let (d, c) = self[i].addingReportingOverflow(carry) + self[i] = d + carry = (c ? 1 : 0) + i += 1 + } + } + + /// Add the digit `d` to this integer and return the result. + /// `d` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, shift)) + internal func addingWord(_ word: Word, shiftedBy shift: Int = 0) -> CS.BigUInt { + var r = self + r.addWord(word, shiftedBy: shift) + return r + } + + /// Add `b` to this integer in place. + /// `b` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, b.count + shift)) + internal mutating func add(_ b: CS.BigUInt, shiftedBy shift: Int = 0) { + precondition(shift >= 0) + var carry = false + var bi = 0 + let bc = b.count + while bi < bc || carry { + let ai = shift + bi + let (d, c) = self[ai].addingReportingOverflow(b[bi]) + if carry { + let (d2, c2) = d.addingReportingOverflow(1) + self[ai] = d2 + carry = c || c2 + } + else { + self[ai] = d + carry = c + } + bi += 1 + } + } + + /// Add `b` to this integer and return the result. + /// `b` is shifted `shift` words to the left before being added. + /// + /// - Complexity: O(max(count, b.count + shift)) + internal func adding(_ b: CS.BigUInt, shiftedBy shift: Int = 0) -> CS.BigUInt { + var r = self + r.add(b, shiftedBy: shift) + return r + } + + /// Increment this integer by one. If `shift` is non-zero, it selects + /// the word that is to be incremented. + /// + /// - Complexity: O(count + shift) + internal mutating func increment(shiftedBy shift: Int = 0) { + self.addWord(1, shiftedBy: shift) + } + + /// Add `a` and `b` together and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func +(a: CS.BigUInt, b: CS.BigUInt) -> CS.BigUInt { + return a.adding(b) + } + + /// Add `a` and `b` together, and store the sum in `a`. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func +=(a: inout CS.BigUInt, b: CS.BigUInt) { + a.add(b, shiftedBy: 0) + } +} + +extension CS.BigInt { + /// Add `a` to `b` and return the result. + public static func +(a: CS.BigInt, b: CS.BigInt) -> CS.BigInt { + switch (a.sign, b.sign) { + case (.plus, .plus): + return CS.BigInt(sign: .plus, magnitude: a.magnitude + b.magnitude) + case (.minus, .minus): + return CS.BigInt(sign: .minus, magnitude: a.magnitude + b.magnitude) + case (.plus, .minus): + if a.magnitude >= b.magnitude { + return CS.BigInt(sign: .plus, magnitude: a.magnitude - b.magnitude) + } + else { + return CS.BigInt(sign: .minus, magnitude: b.magnitude - a.magnitude) + } + case (.minus, .plus): + if b.magnitude >= a.magnitude { + return CS.BigInt(sign: .plus, magnitude: b.magnitude - a.magnitude) + } + else { + return CS.BigInt(sign: .minus, magnitude: a.magnitude - b.magnitude) + } + } + } + + /// Add `b` to `a` in place. + public static func +=(a: inout CS.BigInt, b: CS.BigInt) { + a = a + b + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigInt.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigInt.swift new file mode 100644 index 00000000..5c748db5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigInt.swift @@ -0,0 +1,78 @@ +// +// CS.BigInt.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2015-12-27. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: CS.BigInt + +extension CS { + + /// An arbitary precision signed integer type, also known as a "big integer". + /// + /// Operations on big integers never overflow, but they might take a long time to execute. + /// The amount of memory (and address space) available is the only constraint to the magnitude of these numbers. + /// + /// This particular big integer type uses base-2^64 digits to represent integers. + /// + /// `BigInt` is essentially a tiny wrapper that extends `BigUInt` with a sign bit and provides signed integer + /// operations. Both the underlying absolute value and the negative/positive flag are available as read-write + /// properties. + /// + /// Not all algorithms of `BigUInt` are available for `BigInt` values; for example, there is no square root or + /// primality test for signed integers. When you need to call one of these, just extract the absolute value: + /// + /// ```Swift + /// CS.BigInt(255).abs.isPrime() // Returns false + /// ``` + /// + public struct BigInt: SignedInteger { + public enum Sign { + case plus + case minus + } + + public typealias Magnitude = BigUInt + + /// The type representing a digit in `BigInt`'s underlying number system. + public typealias Word = BigUInt.Word + + public static var isSigned: Bool { + return true + } + + /// The absolute value of this integer. + public var magnitude: BigUInt + + /// True iff the value of this integer is negative. + public var sign: Sign + + /// Initializes a new big integer with the provided absolute number and sign flag. + public init(sign: Sign, magnitude: BigUInt) { + self.sign = (magnitude.isZero ? .plus : sign) + self.magnitude = magnitude + } + + /// Return true iff this integer is zero. + /// + /// - Complexity: O(1) + public var isZero: Bool { + return magnitude.isZero + } + + /// Returns `-1` if this value is negative and `1` if it’s positive; otherwise, `0`. + /// + /// - Returns: The sign of this number, expressed as an integer of the same type. + public func signum() -> CS.BigInt { + switch sign { + case .plus: + return isZero ? 0 : 1 + case .minus: + return -1 + } + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigUInt.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigUInt.swift new file mode 100644 index 00000000..3461bf9c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/BigUInt.swift @@ -0,0 +1,389 @@ +// +// BigUInt.swift +// BigInt +// +// Created by Károly Lőrentey on 2015-12-26. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS { + + /// An arbitary precision unsigned integer type, also known as a "big integer". + /// + /// Operations on big integers never overflow, but they may take a long time to execute. + /// The amount of memory (and address space) available is the only constraint to the magnitude of these numbers. + /// + /// This particular big integer type uses base-2^64 digits to represent integers; you can think of it as a wrapper + /// around `Array`. (In fact, `BigUInt` only uses an array if there are more than two digits.) + public struct BigUInt: UnsignedInteger { + /// The type representing a digit in `BigUInt`'s underlying number system. + public typealias Word = UInt + + /// The storage variants of a `BigUInt`. + enum Kind { + /// Value consists of the two specified words (low and high). Either or both words may be zero. + case inline(Word, Word) + /// Words are stored in a slice of the storage array. + case slice(from: Int, to: Int) + /// Words are stored in the storage array. + case array + } + + internal fileprivate (set) var kind: Kind // Internal for testing only + internal fileprivate (set) var storage: [Word] // Internal for testing only; stored separately to prevent COW copies + + /// Initializes a new BigUInt with value 0. + public init() { + self.kind = .inline(0, 0) + self.storage = [] + } + + internal init(word: Word) { + self.kind = .inline(word, 0) + self.storage = [] + } + + internal init(low: Word, high: Word) { + self.kind = .inline(low, high) + self.storage = [] + } + + /// Initializes a new BigUInt with the specified digits. The digits are ordered from least to most significant. + public init(words: [Word]) { + self.kind = .array + self.storage = words + normalize() + } + + internal init(words: [Word], from startIndex: Int, to endIndex: Int) { + self.kind = .slice(from: startIndex, to: endIndex) + self.storage = words + normalize() + } + } + +} + +extension CS.BigUInt { + public static var isSigned: Bool { + return false + } + + /// Return true iff this integer is zero. + /// + /// - Complexity: O(1) + var isZero: Bool { + switch kind { + case .inline(0, 0): return true + case .array: return storage.isEmpty + default: + return false + } + } + + /// Returns `1` if this value is, positive; otherwise, `0`. + /// + /// - Returns: The sign of this number, expressed as an integer of the same type. + public func signum() -> CS.BigUInt { + return isZero ? 0 : 1 + } +} + +extension CS.BigUInt { + mutating func ensureArray() { + switch kind { + case let .inline(w0, w1): + kind = .array + storage = w1 != 0 ? [w0, w1] + : w0 != 0 ? [w0] + : [] + case let .slice(from: start, to: end): + kind = .array + storage = Array(storage[start ..< end]) + case .array: + break + } + } + + var capacity: Int { + guard case .array = kind else { return 0 } + return storage.capacity + } + + mutating func reserveCapacity(_ minimumCapacity: Int) { + switch kind { + case let .inline(w0, w1): + kind = .array + storage.reserveCapacity(minimumCapacity) + if w1 != 0 { + storage.append(w0) + storage.append(w1) + } + else if w0 != 0 { + storage.append(w0) + } + case let .slice(from: start, to: end): + kind = .array + var words: [Word] = [] + words.reserveCapacity(Swift.max(end - start, minimumCapacity)) + words.append(contentsOf: storage[start ..< end]) + storage = words + case .array: + storage.reserveCapacity(minimumCapacity) + } + } + + /// Gets rid of leading zero digits in the digit array and converts slices into inline digits when possible. + internal mutating func normalize() { + switch kind { + case .slice(from: let start, to: var end): + assert(start >= 0 && end <= storage.count && start <= end) + while start < end, storage[end - 1] == 0 { + end -= 1 + } + switch end - start { + case 0: + kind = .inline(0, 0) + storage = [] + case 1: + kind = .inline(storage[start], 0) + storage = [] + case 2: + kind = .inline(storage[start], storage[start + 1]) + storage = [] + case storage.count: + assert(start == 0) + kind = .array + default: + kind = .slice(from: start, to: end) + } + case .array where storage.last == 0: + while storage.last == 0 { + storage.removeLast() + } + default: + break + } + } + + /// Set this integer to 0 without releasing allocated storage capacity (if any). + mutating func clear() { + self.load(0) + } + + /// Set this integer to `value` by copying its digits without releasing allocated storage capacity (if any). + mutating func load(_ value: CS.BigUInt) { + switch kind { + case .inline, .slice: + self = value + case .array: + self.storage.removeAll(keepingCapacity: true) + self.storage.append(contentsOf: value.words) + } + } +} + +extension CS.BigUInt { + //MARK: Collection-like members + + /// The number of digits in this integer, excluding leading zero digits. + var count: Int { + switch kind { + case let .inline(w0, w1): + return w1 != 0 ? 2 + : w0 != 0 ? 1 + : 0 + case let .slice(from: start, to: end): + return end - start + case .array: + return storage.count + } + } + + /// Get or set a digit at a given index. + /// + /// - Note: Unlike a normal collection, it is OK for the index to be greater than or equal to `endIndex`. + /// The subscripting getter returns zero for indexes beyond the most significant digit. + /// Setting these extended digits automatically appends new elements to the underlying digit array. + /// - Requires: index >= 0 + /// - Complexity: The getter is O(1). The setter is O(1) if the conditions below are true; otherwise it's O(count). + /// - The integer's storage is not shared with another integer + /// - The integer wasn't created as a slice of another integer + /// - `index < count` + subscript(_ index: Int) -> Word { + get { + precondition(index >= 0) + switch (kind, index) { + case (.inline(let w0, _), 0): return w0 + case (.inline(_, let w1), 1): return w1 + case (.slice(from: let start, to: let end), _) where index < end - start: + return storage[start + index] + case (.array, _) where index < storage.count: + return storage[index] + default: + return 0 + } + } + set(word) { + precondition(index >= 0) + switch (kind, index) { + case let (.inline(_, w1), 0): + kind = .inline(word, w1) + case let (.inline(w0, _), 1): + kind = .inline(w0, word) + case let (.slice(from: start, to: end), _) where index < end - start: + replace(at: index, with: word) + case (.array, _) where index < storage.count: + replace(at: index, with: word) + default: + extend(at: index, with: word) + } + } + } + + private mutating func replace(at index: Int, with word: Word) { + ensureArray() + precondition(index < storage.count) + storage[index] = word + if word == 0, index == storage.count - 1 { + normalize() + } + } + + private mutating func extend(at index: Int, with word: Word) { + guard word != 0 else { return } + reserveCapacity(index + 1) + precondition(index >= storage.count) + storage.append(contentsOf: repeatElement(0, count: index - storage.count)) + storage.append(word) + } + + /// Returns an integer built from the digits of this integer in the given range. + internal func extract(_ bounds: Range) -> CS.BigUInt { + switch kind { + case let .inline(w0, w1): + let bounds = bounds.clamped(to: 0 ..< 2) + if bounds == 0 ..< 2 { + return CS.BigUInt(low: w0, high: w1) + } + else if bounds == 0 ..< 1 { + return CS.BigUInt(word: w0) + } + else if bounds == 1 ..< 2 { + return CS.BigUInt(word: w1) + } + else { + return CS.BigUInt() + } + case let .slice(from: start, to: end): + let s = Swift.min(end, start + Swift.max(bounds.lowerBound, 0)) + let e = Swift.max(s, (bounds.upperBound > end - start ? end : start + bounds.upperBound)) + return CS.BigUInt(words: storage, from: s, to: e) + case .array: + let b = bounds.clamped(to: storage.startIndex ..< storage.endIndex) + return CS.BigUInt(words: storage, from: b.lowerBound, to: b.upperBound) + } + } + + internal func extract(_ bounds: Bounds) -> CS.BigUInt where Bounds.Bound == Int { + return self.extract(bounds.relative(to: 0 ..< Int.max)) + } +} + +extension CS.BigUInt { + internal mutating func shiftRight(byWords amount: Int) { + assert(amount >= 0) + guard amount > 0 else { return } + switch kind { + case let .inline(_, w1) where amount == 1: + kind = .inline(w1, 0) + case .inline(_, _): + kind = .inline(0, 0) + case let .slice(from: start, to: end): + let s = start + amount + if s >= end { + kind = .inline(0, 0) + } + else { + kind = .slice(from: s, to: end) + normalize() + } + case .array: + if amount >= storage.count { + storage.removeAll(keepingCapacity: true) + } + else { + storage.removeFirst(amount) + } + } + } + + internal mutating func shiftLeft(byWords amount: Int) { + assert(amount >= 0) + guard amount > 0 else { return } + guard !isZero else { return } + switch kind { + case let .inline(w0, 0) where amount == 1: + kind = .inline(0, w0) + case let .inline(w0, w1): + let c = (w1 == 0 ? 1 : 2) + storage.reserveCapacity(amount + c) + storage.append(contentsOf: repeatElement(0, count: amount)) + storage.append(w0) + if w1 != 0 { + storage.append(w1) + } + kind = .array + case let .slice(from: start, to: end): + var words: [Word] = [] + words.reserveCapacity(amount + count) + words.append(contentsOf: repeatElement(0, count: amount)) + words.append(contentsOf: storage[start ..< end]) + storage = words + kind = .array + case .array: + storage.insert(contentsOf: repeatElement(0, count: amount), at: 0) + } + } +} + +extension CS.BigUInt { + //MARK: Low and High + + /// Split this integer into a high-order and a low-order part. + /// + /// - Requires: count > 1 + /// - Returns: `(low, high)` such that + /// - `self == low.add(high, shiftedBy: middleIndex)` + /// - `high.width <= floor(width / 2)` + /// - `low.width <= ceil(width / 2)` + /// - Complexity: Typically O(1), but O(count) in the worst case, because high-order zero digits need to be removed after the split. + internal var split: (high: CS.BigUInt, low: CS.BigUInt) { + precondition(count > 1) + let mid = middleIndex + return (self.extract(mid...), self.extract(.. 1 + internal var low: CS.BigUInt { + return self.extract(0 ..< middleIndex) + } + + /// The high-order half of this CS.BigUInt. + /// + /// - Returns: `self[middleIndex ..< count]` + /// - Requires: count > 1 + internal var high: CS.BigUInt { + return self.extract(middleIndex ..< count) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Bitwise Ops.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Bitwise Ops.swift new file mode 100644 index 00000000..10099081 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Bitwise Ops.swift @@ -0,0 +1,121 @@ +// +// Bitwise Ops.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Bitwise Operations + +extension CS.BigUInt { + /// Return the ones' complement of `a`. + /// + /// - Complexity: O(a.count) + public static prefix func ~(a: CS.BigUInt) -> CS.BigUInt { + return CS.BigUInt(words: a.words.map { ~$0 }) + } + + /// Calculate the bitwise OR of `a` and `b`, and store the result in `a`. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func |= (a: inout CS.BigUInt, b: CS.BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] |= b[i] + } + } + + /// Calculate the bitwise AND of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func &= (a: inout CS.BigUInt, b: CS.BigUInt) { + for i in 0 ..< Swift.max(a.count, b.count) { + a[i] &= b[i] + } + } + + /// Calculate the bitwise XOR of `a` and `b` and return the result. + /// + /// - Complexity: O(max(a.count, b.count)) + public static func ^= (a: inout CS.BigUInt, b: CS.BigUInt) { + a.reserveCapacity(b.count) + for i in 0 ..< b.count { + a[i] ^= b[i] + } + } +} + +extension CS.BigInt { + public static prefix func ~(x: CS.BigInt) -> CS.BigInt { + switch x.sign { + case .plus: + return CS.BigInt(sign: .minus, magnitude: x.magnitude + 1) + case .minus: + return CS.BigInt(sign: .plus, magnitude: x.magnitude - 1) + } + } + + public static func &(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] & right[i]) + } + if lhs.sign == .minus && rhs.sign == .minus { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func |(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] | right[i]) + } + if lhs.sign == .minus || rhs.sign == .minus { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func ^(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt { + let left = lhs.words + let right = rhs.words + // Note we aren't using left.count/right.count here; we account for the sign bit separately later. + let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count) + var words: [UInt] = [] + words.reserveCapacity(count) + for i in 0 ..< count { + words.append(left[i] ^ right[i]) + } + if (lhs.sign == .minus) != (rhs.sign == .minus) { + words.twosComplement() + return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + + public static func &=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs & rhs + } + + public static func |=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs | rhs + } + + public static func ^=(lhs: inout CS.BigInt, rhs: CS.BigInt) { + lhs = lhs ^ rhs + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/CS.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/CS.swift new file mode 100644 index 00000000..cec128e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/CS.swift @@ -0,0 +1,24 @@ +// CryptoSwift +// +// Copyright (C) 2014-2022 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// To avoid name conflict with BigInt library, I choose to rename +// BigInt -> BigInteger +// BigUInt -> BigUInteger + +public typealias BigInteger = CS.BigInt +public typealias BigUInteger = CS.BigUInt + +public enum CS { + // namespace +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Codable.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Codable.swift new file mode 100644 index 00000000..067c19e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Codable.swift @@ -0,0 +1,157 @@ +// +// Codable.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-8-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS { + + // Little-endian to big-endian + struct Units: RandomAccessCollection + where Words.Element: FixedWidthInteger, Words.Index == Int { + typealias Word = Words.Element + let words: Words + init(of type: Unit.Type, _ words: Words) { + precondition(Word.bitWidth % Unit.bitWidth == 0 || Unit.bitWidth % Word.bitWidth == 0) + self.words = words + } + var count: Int { return (words.count * Word.bitWidth + Unit.bitWidth - 1) / Unit.bitWidth } + var startIndex: Int { return 0 } + var endIndex: Int { return count } + subscript(_ index: Int) -> Unit { + let index = count - 1 - index + if Unit.bitWidth == Word.bitWidth { + return Unit(words[index]) + } + else if Unit.bitWidth > Word.bitWidth { + let c = Unit.bitWidth / Word.bitWidth + var unit: Unit = 0 + var j = 0 + for i in (c * index) ..< Swift.min(c * (index + 1), words.endIndex) { + unit |= Unit(words[i]) << j + j += Word.bitWidth + } + return unit + } + // Unit.bitWidth < Word.bitWidth + let c = Word.bitWidth / Unit.bitWidth + let i = index / c + let j = index % c + return Unit(truncatingIfNeeded: words[i] >> (j * Unit.bitWidth)) + } + } +} + +extension Array where Element: FixedWidthInteger { + // Big-endian to little-endian + init(count: Int?, generator: () throws -> Unit?) rethrows { + typealias Word = Element + precondition(Word.bitWidth % Unit.bitWidth == 0 || Unit.bitWidth % Word.bitWidth == 0) + self = [] + if Unit.bitWidth == Word.bitWidth { + if let count = count { + self.reserveCapacity(count) + } + while let unit = try generator() { + self.append(Word(unit)) + } + } + else if Unit.bitWidth > Word.bitWidth { + let wordsPerUnit = Unit.bitWidth / Word.bitWidth + if let count = count { + self.reserveCapacity(count * wordsPerUnit) + } + while let unit = try generator() { + var shift = Unit.bitWidth - Word.bitWidth + while shift >= 0 { + self.append(Word(truncatingIfNeeded: unit >> shift)) + shift -= Word.bitWidth + } + } + } + else { + let unitsPerWord = Word.bitWidth / Unit.bitWidth + if let count = count { + self.reserveCapacity((count + unitsPerWord - 1) / unitsPerWord) + } + var word: Word = 0 + var c = 0 + while let unit = try generator() { + word <<= Unit.bitWidth + word |= Word(unit) + c += Unit.bitWidth + if c == Word.bitWidth { + self.append(word) + word = 0 + c = 0 + } + } + if c > 0 { + self.append(word << c) + var shifted: Word = 0 + for i in self.indices { + let word = self[i] + self[i] = shifted | (word >> c) + shifted = word << (Word.bitWidth - c) + } + } + } + self.reverse() + } +} + +extension CS.BigInt: Codable { + public init(from decoder: Decoder) throws { + var container = try decoder.unkeyedContainer() + + // Decode sign + let sign: CS.BigInt.Sign + switch try container.decode(String.self) { + case "+": + sign = .plus + case "-": + sign = .minus + default: + throw DecodingError.dataCorrupted(.init(codingPath: container.codingPath, + debugDescription: "Invalid big integer sign")) + } + + // Decode magnitude + let words = try [UInt](count: container.count?.advanced(by: -1)) { () -> UInt64? in + guard !container.isAtEnd else { return nil } + return try container.decode(UInt64.self) + } + let magnitude = CS.BigUInt(words: words) + + self.init(sign: sign, magnitude: magnitude) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.unkeyedContainer() + try container.encode(sign == .plus ? "+" : "-") + let units = CS.Units(of: UInt64.self, self.magnitude.words) + if units.isEmpty { + try container.encode(0 as UInt64) + } + else { + try container.encode(contentsOf: units) + } + } +} + +extension CS.BigUInt: Codable { + public init(from decoder: Decoder) throws { + let value = try CS.BigInt(from: decoder) + guard value.sign == .plus else { + throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, + debugDescription: "BigUInt cannot hold a negative value")) + } + self = value.magnitude + } + + public func encode(to encoder: Encoder) throws { + try CS.BigInt(sign: .plus, magnitude: self).encode(to: encoder) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Comparable.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Comparable.swift new file mode 100644 index 00000000..86b79ea4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Comparable.swift @@ -0,0 +1,63 @@ +// +// Comparable.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +import Foundation + +extension CS.BigUInt: Comparable { + //MARK: Comparison + + /// Compare `a` to `b` and return an `NSComparisonResult` indicating their order. + /// + /// - Complexity: O(count) + public static func compare(_ a: CS.BigUInt, _ b: CS.BigUInt) -> ComparisonResult { + if a.count != b.count { return a.count > b.count ? .orderedDescending : .orderedAscending } + for i in (0 ..< a.count).reversed() { + let ad = a[i] + let bd = b[i] + if ad != bd { return ad > bd ? .orderedDescending : .orderedAscending } + } + return .orderedSame + } + + /// Return true iff `a` is equal to `b`. + /// + /// - Complexity: O(count) + public static func ==(a: CS.BigUInt, b: CS.BigUInt) -> Bool { + return CS.BigUInt.compare(a, b) == .orderedSame + } + + /// Return true iff `a` is less than `b`. + /// + /// - Complexity: O(count) + public static func <(a: CS.BigUInt, b: CS.BigUInt) -> Bool { + return CS.BigUInt.compare(a, b) == .orderedAscending + } +} + +extension CS.BigInt { + /// Return true iff `a` is equal to `b`. + public static func ==(a: CS.BigInt, b: CS.BigInt) -> Bool { + return a.sign == b.sign && a.magnitude == b.magnitude + } + + /// Return true iff `a` is less than `b`. + public static func <(a: CS.BigInt, b: CS.BigInt) -> Bool { + switch (a.sign, b.sign) { + case (.plus, .plus): + return a.magnitude < b.magnitude + case (.plus, .minus): + return false + case (.minus, .plus): + return true + case (.minus, .minus): + return a.magnitude > b.magnitude + } + } +} + + diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Data Conversion.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Data Conversion.swift new file mode 100644 index 00000000..5ae34e32 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Data Conversion.swift @@ -0,0 +1,179 @@ +// +// Data Conversion.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +import Foundation + +extension CS.BigUInt { + //MARK: NSData Conversion + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + + var word: Word = 0 + for byte in buffer { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + assert(c == 0 && word == 0 && index == -1) + } + + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order. + public init(_ data: Data) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = data.count + guard length > 0 else { return } + let bytesPerDigit = Word.bitWidth / 8 + var index = length / bytesPerDigit + var c = bytesPerDigit - length % bytesPerDigit + if c == bytesPerDigit { + c = 0 + index -= 1 + } + let word: Word = data.withUnsafeBytes { buffPtr in + var word: Word = 0 + let p = buffPtr.bindMemory(to: UInt8.self) + for byte in p { + word <<= 8 + word += Word(byte) + c += 1 + if c == bytesPerDigit { + self[index] = word + index -= 1 + c = 0 + word = 0 + } + } + return word + } + assert(c == 0 && word == 0 && index == -1) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order. + public func serialize() -> Data { + // This assumes Digit is binary. + precondition(Word.bitWidth % 8 == 0) + + let byteCount = (self.bitWidth + 7) / 8 + + guard byteCount > 0 else { return Data() } + + var data = Data(count: byteCount) + data.withUnsafeMutableBytes { buffPtr in + let p = buffPtr.bindMemory(to: UInt8.self) + var i = byteCount - 1 + for var word in self.words { + for _ in 0 ..< Word.bitWidth / 8 { + p[i] = UInt8(word & 0xFF) + word >>= 8 + if i == 0 { + assert(word == 0) + break + } + i -= 1 + } + } + } + return data + } +} + +extension CS.BigInt { + + /// Initialize a BigInt from bytes accessed from an UnsafeRawBufferPointer, + /// where the first byte indicates sign (0 for positive, 1 for negative) + public init(_ buffer: UnsafeRawBufferPointer) { + // This assumes Word is binary. + precondition(Word.bitWidth % 8 == 0) + + self.init() + + let length = buffer.count + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard length > 1, let firstByte = buffer.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + self.magnitude = CS.BigUInt(UnsafeRawBufferPointer(rebasing: buffer.dropFirst(1))) + } + + /// Initializes an integer from the bits stored inside a piece of `Data`. + /// The data is assumed to be in network (big-endian) byte order with a first + /// byte to represent the sign (0 for positive, 1 for negative) + public init(_ data: Data) { + // This assumes Word is binary. + // This is the same assumption made when initializing CS.BigUInt from Data + precondition(Word.bitWidth % 8 == 0) + + self.init() + + // Serialized data for a BigInt should contain at least 2 bytes: one representing + // the sign, and another for the non-zero magnitude. Zero is represented by an + // empty Data struct, and negative zero is not supported. + guard data.count > 1, let firstByte = data.first else { return } + + // The first byte gives the sign + // This byte is compared to a bitmask to allow additional functionality to be added + // to this byte in the future. + self.sign = firstByte & 0b1 == 0 ? .plus : .minus + + // The remaining bytes are read and stored as the magnitude + self.magnitude = CS.BigUInt(data.dropFirst(1)) + } + + /// Return a `Data` value that contains the base-256 representation of this integer, in network (big-endian) byte order and a prepended byte to indicate the sign (0 for positive, 1 for negative) + public func serialize() -> Data { + // Create a data object for the magnitude portion of the BigInt + let magnitudeData = self.magnitude.serialize() + + // Similar to CS.BigUInt, a value of 0 should return an initialized, empty Data struct + guard magnitudeData.count > 0 else { return magnitudeData } + + // Create a new Data struct for the signed BigInt value + var data = Data(capacity: magnitudeData.count + 1) + + // The first byte should be 0 for a positive value, or 1 for a negative value + // i.e., the sign bit is the LSB + data.append(self.sign == .plus ? 0 : 1) + + data.append(magnitudeData) + return data + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Division.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Division.swift new file mode 100644 index 00000000..404e3312 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Division.swift @@ -0,0 +1,375 @@ +// +// Division.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Full-width multiplication and division + +// TODO: Return to `where Magnitude == Self` when SR-13491 is resolved +extension FixedWidthInteger { + private var halfShift: Self { + return Self(Self.bitWidth / 2) + + } + private var high: Self { + return self &>> halfShift + } + + private var low: Self { + let mask: Self = 1 &<< halfShift - 1 + return self & mask + } + + private var upshifted: Self { + return self &<< halfShift + } + + private var split: (high: Self, low: Self) { + return (self.high, self.low) + } + + private init(_ value: (high: Self, low: Self)) { + self = value.high.upshifted + value.low + } + + /// Divide the double-width integer `dividend` by `self` and return the quotient and remainder. + /// + /// - Requires: `dividend.high < self`, so that the result will fit in a single digit. + /// - Complexity: O(1) with 2 divisions, 6 multiplications and ~12 or so additions/subtractions. + internal func fastDividingFullWidth(_ dividend: (high: Self, low: Self.Magnitude)) -> (quotient: Self, remainder: Self) { + // Division is complicated; doing it with single-digit operations is maddeningly complicated. + // This is a Swift adaptation for "divlu2" in Hacker's Delight, + // which is in turn a C adaptation of Knuth's Algorithm D (TAOCP vol 2, 4.3.1). + precondition(dividend.high < self) + + // This replaces the implementation in stdlib, which is much slower. + // FIXME: Speed up stdlib. It should use full-width idiv on Intel processors, and + // fall back to a reasonably fast algorithm elsewhere. + + // The trick here is that we're actually implementing a 4/2 long division using half-words, + // with the long division loop unrolled into two 3/2 half-word divisions. + // Luckily, 3/2 half-word division can be approximated by a single full-word division operation + // that, when the divisor is normalized, differs from the correct result by at most 2. + + /// Find the half-word quotient in `u / vn`, which must be normalized. + /// `u` contains three half-words in the two halves of `u.high` and the lower half of + /// `u.low`. (The weird distribution makes for a slightly better fit with the input.) + /// `vn` contains the normalized divisor, consisting of two half-words. + /// + /// - Requires: u.high < vn && u.low.high == 0 && vn.leadingZeroBitCount == 0 + func quotient(dividing u: (high: Self, low: Self), by vn: Self) -> Self { + let (vn1, vn0) = vn.split + // Get approximate quotient. + let (q, r) = u.high.quotientAndRemainder(dividingBy: vn1) + let p = q * vn0 + // q is often already correct, but sometimes the approximation overshoots by at most 2. + // The code that follows checks for this while being careful to only perform single-digit operations. + if q.high == 0 && p <= r.upshifted + u.low { return q } + let r2 = r + vn1 + if r2.high != 0 { return q - 1 } + if (q - 1).high == 0 && p - vn0 <= r2.upshifted + u.low { return q - 1 } + //assert((r + 2 * vn1).high != 0 || p - 2 * vn0 <= (r + 2 * vn1).upshifted + u.low) + return q - 2 + } + /// Divide 3 half-digits by 2 half-digits to get a half-digit quotient and a full-digit remainder. + /// + /// - Requires: u.high < v && u.low.high == 0 && vn.width = width(Digit) + func quotientAndRemainder(dividing u: (high: Self, low: Self), by v: Self) -> (quotient: Self, remainder: Self) { + let q = quotient(dividing: u, by: v) + // Note that `uh.low` masks off a couple of bits, and `q * v` and the + // subtraction are likely to overflow. Despite this, the end result (remainder) will + // still be correct and it will fit inside a single (full) Digit. + let r = Self(u) &- q &* v + assert(r < v) + return (q, r) + } + + // Normalize the dividend and the divisor (self) such that the divisor has no leading zeroes. + let z = Self(self.leadingZeroBitCount) + let w = Self(Self.bitWidth) - z + let vn = self << z + + let un32 = (z == 0 ? dividend.high : (dividend.high &<< z) | ((dividend.low as! Self) &>> w)) // No bits are lost + let un10 = dividend.low &<< z + let (un1, un0) = un10.split + + // Divide `(un32,un10)` by `vn`, splitting the full 4/2 division into two 3/2 ones. + let (q1, un21) = quotientAndRemainder(dividing: (un32, (un1 as! Self)), by: vn) + let (q0, rn) = quotientAndRemainder(dividing: (un21, (un0 as! Self)), by: vn) + + // Undo normalization of the remainder and combine the two halves of the quotient. + let mod = rn >> z + let div = Self((q1, q0)) + return (div, mod) + } + + /// Return the quotient of the 3/2-word division `x/y` as a single word. + /// + /// - Requires: (x.0, x.1) <= y && y.0.high != 0 + /// - Returns: The exact value when it fits in a single word, otherwise `Self`. + static func approximateQuotient(dividing x: (Self, Self, Self), by y: (Self, Self)) -> Self { + // Start with q = (x.0, x.1) / y.0, (or Word.max on overflow) + var q: Self + var r: Self + if x.0 == y.0 { + q = Self.max + let (s, o) = x.0.addingReportingOverflow(x.1) + if o { return q } + r = s + } + else { + (q, r) = y.0.fastDividingFullWidth((x.0, (x.1 as! Magnitude))) + } + // Now refine q by considering x.2 and y.1. + // Note that since y is normalized, q * y - x is between 0 and 2. + let (ph, pl) = q.multipliedFullWidth(by: y.1) + if ph < r || (ph == r && pl <= x.2) { return q } + + let (r1, ro) = r.addingReportingOverflow(y.0) + if ro { return q - 1 } + + let (pl1, so) = pl.subtractingReportingOverflow((y.1 as! Magnitude)) + let ph1 = (so ? ph - 1 : ph) + + if ph1 < r1 || (ph1 == r1 && pl1 <= x.2) { return q - 1 } + return q - 2 + } +} + +extension CS.BigUInt { + //MARK: Division + + /// Divide this integer by the word `y`, leaving the quotient in its place and returning the remainder. + /// + /// - Requires: y > 0 + /// - Complexity: O(count) + internal mutating func divide(byWord y: Word) -> Word { + precondition(y > 0) + if y == 1 { return 0 } + + var remainder: Word = 0 + for i in (0 ..< count).reversed() { + let u = self[i] + (self[i], remainder) = y.fastDividingFullWidth((remainder, u)) + } + return remainder + } + + /// Divide this integer by the word `y` and return the resulting quotient and remainder. + /// + /// - Requires: y > 0 + /// - Returns: (quotient, remainder) where quotient = floor(x/y), remainder = x - quotient * y + /// - Complexity: O(x.count) + internal func quotientAndRemainder(dividingByWord y: Word) -> (quotient: CS.BigUInt, remainder: Word) { + var div = self + let mod = div.divide(byWord: y) + return (div, mod) + } + + /// Divide `x` by `y`, putting the quotient in `x` and the remainder in `y`. + /// Reusing integers like this reduces the number of allocations during the calculation. + static func divide(_ x: inout CS.BigUInt, by y: inout CS.BigUInt) { + // This is a Swift adaptation of "divmnu" from Hacker's Delight, which is in + // turn a C adaptation of Knuth's Algorithm D (TAOCP vol 2, 4.3.1). + + precondition(!y.isZero) + + // First, let's take care of the easy cases. + if x < y { + (x, y) = (0, x) + return + } + if y.count == 1 { + // The single-word case reduces to a simpler loop. + y = CS.BigUInt(x.divide(byWord: y[0])) + return + } + + // In the hard cases, we will perform the long division algorithm we learned in school. + // It works by successively calculating the single-word quotient of the top y.count + 1 + // words of x divided by y, replacing the top of x with the remainder, and repeating + // the process one word lower. + // + // The tricky part is that the algorithm needs to be able to do n+1/n word divisions, + // but we only have a primitive for dividing two words by a single + // word. (Remember that this step is also tricky when we do it on paper!) + // + // The solution is that the long division can be approximated by a single full division + // using just the most significant words. We can then use multiplications and + // subtractions to refine the approximation until we get the correct quotient word. + // + // We could do this by doing a simple 2/1 full division, but Knuth goes one step further, + // and implements a 3/2 division. This results in an exact approximation in the + // vast majority of cases, eliminating an extra subtraction over big integers. + // + // The function `approximateQuotient` above implements Knuth's 3/2 division algorithm. + // It requires that the divisor's most significant word is larger than + // Word.max / 2. This ensures that the approximation has tiny error bounds, + // which is what makes this entire approach viable. + // To satisfy this requirement, we will normalize the division by multiplying + // both the divisor and the dividend by the same (small) factor. + let z = y.leadingZeroBitCount + y <<= z + x <<= z // We'll calculate the remainder in the normalized dividend. + var quotient = CS.BigUInt() + assert(y.leadingZeroBitCount == 0) + + // We're ready to start the long division! + let dc = y.count + let d1 = y[dc - 1] + let d0 = y[dc - 2] + var product: CS.BigUInt = 0 + for j in (dc ... x.count).reversed() { + // Approximate dividing the top dc+1 words of `remainder` using the topmost 3/2 words. + let r2 = x[j] + let r1 = x[j - 1] + let r0 = x[j - 2] + let q = Word.approximateQuotient(dividing: (r2, r1, r0), by: (d1, d0)) + + // Multiply the entire divisor with `q` and subtract the result from remainder. + // Normalization ensures the 3/2 quotient will either be exact for the full division, or + // it may overshoot by at most 1, in which case the product will be greater + // than the remainder. + product.load(y) + product.multiply(byWord: q) + if product <= x.extract(j - dc ..< j + 1) { + x.subtract(product, shiftedBy: j - dc) + quotient[j - dc] = q + } + else { + // This case is extremely rare -- it has a probability of 1/2^(Word.bitWidth - 1). + x.add(y, shiftedBy: j - dc) + x.subtract(product, shiftedBy: j - dc) + quotient[j - dc] = q - 1 + } + } + // The remainder's normalization needs to be undone, but otherwise we're done. + x >>= z + y = x + x = quotient + } + + /// Divide `x` by `y`, putting the remainder in `x`. + mutating func formRemainder(dividingBy y: CS.BigUInt, normalizedBy shift: Int) { + precondition(!y.isZero) + assert(y.leadingZeroBitCount == 0) + if y.count == 1 { + let remainder = self.divide(byWord: y[0] >> shift) + self.load(CS.BigUInt(remainder)) + return + } + self <<= shift + if self >= y { + let dc = y.count + let d1 = y[dc - 1] + let d0 = y[dc - 2] + var product: CS.BigUInt = 0 + for j in (dc ... self.count).reversed() { + let r2 = self[j] + let r1 = self[j - 1] + let r0 = self[j - 2] + let q = Word.approximateQuotient(dividing: (r2, r1, r0), by: (d1, d0)) + product.load(y) + product.multiply(byWord: q) + if product <= self.extract(j - dc ..< j + 1) { + self.subtract(product, shiftedBy: j - dc) + } + else { + self.add(y, shiftedBy: j - dc) + self.subtract(product, shiftedBy: j - dc) + } + } + } + self >>= shift + } + + + /// Divide this integer by `y` and return the resulting quotient and remainder. + /// + /// - Requires: `y > 0` + /// - Returns: `(quotient, remainder)` where `quotient = floor(self/y)`, `remainder = self - quotient * y` + /// - Complexity: O(count^2) + public func quotientAndRemainder(dividingBy y: CS.BigUInt) -> (quotient: CS.BigUInt, remainder: CS.BigUInt) { + var x = self + var y = y + CS.BigUInt.divide(&x, by: &y) + return (x, y) + } + + /// Divide `x` by `y` and return the quotient. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func /(x: CS.BigUInt, y: CS.BigUInt) -> CS.BigUInt { + return x.quotientAndRemainder(dividingBy: y).quotient + } + + /// Divide `x` by `y` and return the remainder. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func %(x: CS.BigUInt, y: CS.BigUInt) -> CS.BigUInt { + var x = x + let shift = y.leadingZeroBitCount + x.formRemainder(dividingBy: y << shift, normalizedBy: shift) + return x + } + + /// Divide `x` by `y` and store the quotient in `x`. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func /=(x: inout CS.BigUInt, y: CS.BigUInt) { + var y = y + CS.BigUInt.divide(&x, by: &y) + } + + /// Divide `x` by `y` and store the remainder in `x`. + /// + /// - Note: Use `divided(by:)` if you also need the remainder. + public static func %=(x: inout CS.BigUInt, y: CS.BigUInt) { + let shift = y.leadingZeroBitCount + x.formRemainder(dividingBy: y << shift, normalizedBy: shift) + } +} + +extension CS.BigInt { + /// Divide this integer by `y` and return the resulting quotient and remainder. + /// + /// - Requires: `y > 0` + /// - Returns: `(quotient, remainder)` where `quotient = floor(self/y)`, `remainder = self - quotient * y` + /// - Complexity: O(count^2) + public func quotientAndRemainder(dividingBy y: CS.BigInt) -> (quotient: CS.BigInt, remainder: CS.BigInt) { + var a = self.magnitude + var b = y.magnitude + CS.BigUInt.divide(&a, by: &b) + return ( CS.BigInt(sign: self.sign == y.sign ? .plus : .minus, magnitude: a), + CS.BigInt(sign: self.sign, magnitude: b)) + } + + /// Divide `a` by `b` and return the quotient. Traps if `b` is zero. + public static func /(a: CS.BigInt, b: CS.BigInt) -> CS.BigInt { + return CS.BigInt(sign: a.sign == b.sign ? .plus : .minus, magnitude: a.magnitude / b.magnitude) + } + + /// Divide `a` by `b` and return the remainder. The result has the same sign as `a`. + public static func %(a: CS.BigInt, b: CS.BigInt) -> CS.BigInt { + return CS.BigInt(sign: a.sign, magnitude: a.magnitude % b.magnitude) + } + + /// Return the result of `a` mod `b`. The result is always a nonnegative integer that is less than the absolute value of `b`. + public func modulus(_ mod: CS.BigInt) -> CS.BigInt { + let remainder = self.magnitude % mod.magnitude + return CS.BigInt( + self.sign == .minus && !remainder.isZero + ? mod.magnitude - remainder + : remainder) + } +} + +extension CS.BigInt { + /// Divide `a` by `b` storing the quotient in `a`. + public static func /=(a: inout CS.BigInt, b: CS.BigInt) { a = a / b } + /// Divide `a` by `b` storing the remainder in `a`. + public static func %=(a: inout CS.BigInt, b: CS.BigInt) { a = a % b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Exponentiation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Exponentiation.swift new file mode 100644 index 00000000..14aa714c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Exponentiation.swift @@ -0,0 +1,119 @@ +// +// Exponentiation.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + //MARK: Exponentiation + + /// Returns this integer raised to the power `exponent`. + /// + /// This function calculates the result by [successively squaring the base while halving the exponent][expsqr]. + /// + /// [expsqr]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// - Note: This function can be unreasonably expensive for large exponents, which is why `exponent` is + /// a simple integer value. If you want to calculate big exponents, you'll probably need to use + /// the modulo arithmetic variant. + /// - Returns: 1 if `exponent == 0`, otherwise `self` raised to `exponent`. (This implies that `0.power(0) == 1`.) + /// - SeeAlso: `BigUInt.power(_:, modulus:)` + /// - Complexity: O((exponent * self.count)^log2(3)) or somesuch. The result may require a large amount of memory, too. + public func power(_ exponent: Int) -> CS.BigUInt { + if exponent == 0 { return 1 } + if exponent == 1 { return self } + if exponent < 0 { + precondition(!self.isZero) + return self == 1 ? 1 : 0 + } + if self <= 1 { return self } + var result = CS.BigUInt(1) + var b = self + var e = exponent + while e > 0 { + if e & 1 == 1 { + result *= b + } + e >>= 1 + b *= b + } + return result + } + + /// Returns the remainder of this integer raised to the power `exponent` in modulo arithmetic under `modulus`. + /// + /// Uses the [right-to-left binary method][rtlb]. + /// + /// [rtlb]: https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method + /// + /// - Complexity: O(exponent.count * modulus.count^log2(3)) or somesuch + public func power(_ exponent: CS.BigUInt, modulus: CS.BigUInt) -> CS.BigUInt { + precondition(!modulus.isZero) + if modulus == (1 as CS.BigUInt) { return 0 } + let shift = modulus.leadingZeroBitCount + let normalizedModulus = modulus << shift + var result = CS.BigUInt(1) + var b = self + b.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + for var e in exponent.words { + for _ in 0 ..< Word.bitWidth { + if e & 1 == 1 { + result *= b + result.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + } + e >>= 1 + b *= b + b.formRemainder(dividingBy: normalizedModulus, normalizedBy: shift) + } + } + return result + } +} + +extension CS.BigInt { + /// Returns this integer raised to the power `exponent`. + /// + /// This function calculates the result by [successively squaring the base while halving the exponent][expsqr]. + /// + /// [expsqr]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// - Note: This function can be unreasonably expensive for large exponents, which is why `exponent` is + /// a simple integer value. If you want to calculate big exponents, you'll probably need to use + /// the modulo arithmetic variant. + /// - Returns: 1 if `exponent == 0`, otherwise `self` raised to `exponent`. (This implies that `0.power(0) == 1`.) + /// - SeeAlso: `BigUInt.power(_:, modulus:)` + /// - Complexity: O((exponent * self.count)^log2(3)) or somesuch. The result may require a large amount of memory, too. + public func power(_ exponent: Int) -> CS.BigInt { + return CS.BigInt(sign: self.sign == .minus && exponent & 1 != 0 ? .minus : .plus, + magnitude: self.magnitude.power(exponent)) + } + + /// Returns the remainder of this integer raised to the power `exponent` in modulo arithmetic under `modulus`. + /// + /// Uses the [right-to-left binary method][rtlb]. + /// + /// [rtlb]: https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method + /// + /// - Complexity: O(exponent.count * modulus.count^log2(3)) or somesuch + public func power(_ exponent: CS.BigInt, modulus: CS.BigInt) -> CS.BigInt { + precondition(!modulus.isZero) + if modulus.magnitude == 1 { return 0 } + if exponent.isZero { return 1 } + if exponent == 1 { return self.modulus(modulus) } + if exponent < 0 { + precondition(!self.isZero) + guard magnitude == 1 else { return 0 } + guard sign == .minus else { return 1 } + guard exponent.magnitude[0] & 1 != 0 else { return 1 } + return CS.BigInt(modulus.magnitude - 1) + } + let power = self.magnitude.power(exponent.magnitude, + modulus: modulus.magnitude) + if self.sign == .plus || exponent.magnitude[0] & 1 == 0 || power.isZero { + return CS.BigInt(power) + } + return CS.BigInt(modulus.magnitude - power) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Floating Point Conversion.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Floating Point Conversion.swift new file mode 100644 index 00000000..524f9ef4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Floating Point Conversion.swift @@ -0,0 +1,73 @@ +// +// Floating Point Conversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + public init?(exactly source: T) { + guard source.isFinite else { return nil } + guard !source.isZero else { self = 0; return } + guard source.sign == .plus else { return nil } + let value = source.rounded(.towardZero) + guard value == source else { return nil } + assert(value.floatingPointClass == .positiveNormal) + assert(value.exponent >= 0) + let significand = value.significandBitPattern + self = (CS.BigUInt(1) << value.exponent) + CS.BigUInt(significand) >> (T.significandBitCount - Int(value.exponent)) + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension CS.BigInt { + public init?(exactly source: T) { + switch source.sign{ + case .plus: + guard let magnitude = CS.BigUInt(exactly: source) else { return nil } + self = CS.BigInt(sign: .plus, magnitude: magnitude) + case .minus: + guard let magnitude = CS.BigUInt(exactly: -source) else { return nil } + self = CS.BigInt(sign: .minus, magnitude: magnitude) + } + } + + public init(_ source: T) { + self.init(exactly: source.rounded(.towardZero))! + } +} + +extension BinaryFloatingPoint where RawExponent: FixedWidthInteger, RawSignificand: FixedWidthInteger { + public init(_ value: CS.BigInt) { + guard !value.isZero else { self = 0; return } + let v = value.magnitude + let bitWidth = v.bitWidth + var exponent = bitWidth - 1 + let shift = bitWidth - Self.significandBitCount - 1 + var significand = value.magnitude >> (shift - 1) + if significand[0] & 3 == 3 { // Handle rounding + significand >>= 1 + significand += 1 + if significand.trailingZeroBitCount >= Self.significandBitCount { + exponent += 1 + } + } + else { + significand >>= 1 + } + let bias = 1 << (Self.exponentBitCount - 1) - 1 + guard exponent <= bias else { self = Self.infinity; return } + significand &= 1 << Self.significandBitCount - 1 + self = Self.init(sign: value.sign == .plus ? .plus : .minus, + exponentBitPattern: RawExponent(bias + exponent), + significandBitPattern: RawSignificand(significand)) + } + + public init(_ value: CS.BigUInt) { + self.init(CS.BigInt(sign: .plus, magnitude: value)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/GCD.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/GCD.swift new file mode 100644 index 00000000..50f56f79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/GCD.swift @@ -0,0 +1,80 @@ +// +// GCD.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + //MARK: Greatest Common Divisor + + /// Returns the greatest common divisor of `self` and `b`. + /// + /// - Complexity: O(count^2) where count = max(self.count, b.count) + public func greatestCommonDivisor(with b: CS.BigUInt) -> CS.BigUInt { + // This is Stein's algorithm: https://en.wikipedia.org/wiki/Binary_GCD_algorithm + if self.isZero { return b } + if b.isZero { return self } + + let az = self.trailingZeroBitCount + let bz = b.trailingZeroBitCount + let twos = Swift.min(az, bz) + + var (x, y) = (self >> az, b >> bz) + if x < y { swap(&x, &y) } + + while !x.isZero { + x >>= x.trailingZeroBitCount + if x < y { swap(&x, &y) } + x -= y + } + return y << twos + } + + /// Returns the [multiplicative inverse of this integer in modulo `modulus` arithmetic][inverse], + /// or `nil` if there is no such number. + /// + /// [inverse]: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers + /// + /// - Returns: If `gcd(self, modulus) == 1`, the value returned is an integer `a < modulus` such that `(a * self) % modulus == 1`. If `self` and `modulus` aren't coprime, the return value is `nil`. + /// - Requires: modulus > 1 + /// - Complexity: O(count^3) + public func inverse(_ modulus: CS.BigUInt) -> CS.BigUInt? { + precondition(modulus > 1) + var t1 = CS.BigInt(0) + var t2 = CS.BigInt(1) + var r1 = modulus + var r2 = self + while !r2.isZero { + let quotient = r1 / r2 + (t1, t2) = (t2, t1 - CS.BigInt(quotient) * t2) + (r1, r2) = (r2, r1 - quotient * r2) + } + if r1 > 1 { return nil } + if t1.sign == .minus { return modulus - t1.magnitude } + return t1.magnitude + } +} + +extension CS.BigInt { + /// Returns the greatest common divisor of `a` and `b`. + /// + /// - Complexity: O(count^2) where count = max(a.count, b.count) + public func greatestCommonDivisor(with b: CS.BigInt) -> CS.BigInt { + return CS.BigInt(self.magnitude.greatestCommonDivisor(with: b.magnitude)) + } + + /// Returns the [multiplicative inverse of this integer in modulo `modulus` arithmetic][inverse], + /// or `nil` if there is no such number. + /// + /// [inverse]: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers + /// + /// - Returns: If `gcd(self, modulus) == 1`, the value returned is an integer `a < modulus` such that `(a * self) % modulus == 1`. If `self` and `modulus` aren't coprime, the return value is `nil`. + /// - Requires: modulus.magnitude > 1 + /// - Complexity: O(count^3) + public func inverse(_ modulus: CS.BigInt) -> CS.BigInt? { + guard let inv = self.magnitude.inverse(modulus.magnitude) else { return nil } + return CS.BigInt(self.sign == .plus || inv.isZero ? inv : modulus.magnitude - inv) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Hashable.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Hashable.swift new file mode 100644 index 00000000..5ae01bfe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Hashable.swift @@ -0,0 +1,26 @@ +// +// Hashable.swift +// BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt: Hashable { + //MARK: Hashing + + /// Append this `BigUInt` to the specified hasher. + public func hash(into hasher: inout Hasher) { + for word in self.words { + hasher.combine(word) + } + } +} + +extension CS.BigInt: Hashable { + /// Append this `BigInt` to the specified hasher. + public func hash(into hasher: inout Hasher) { + hasher.combine(sign) + hasher.combine(magnitude) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Integer Conversion.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Integer Conversion.swift new file mode 100644 index 00000000..ab77f266 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Integer Conversion.swift @@ -0,0 +1,89 @@ +// +// Integer Conversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + public init?(exactly source: T) { + guard source >= (0 as T) else { return nil } + if source.bitWidth <= 2 * Word.bitWidth { + var it = source.words.makeIterator() + self.init(low: it.next() ?? 0, high: it.next() ?? 0) + precondition(it.next() == nil, "Length of BinaryInteger.words is greater than its bitWidth") + } + else { + self.init(words: source.words) + } + } + + public init(_ source: T) { + precondition(source >= (0 as T), "BigUInt cannot represent negative values") + self.init(exactly: source)! + } + + public init(truncatingIfNeeded source: T) { + self.init(words: source.words) + } + + public init(clamping source: T) { + if source <= (0 as T) { + self.init() + } + else { + self.init(words: source.words) + } + } +} + +extension CS.BigInt { + public init() { + self.init(sign: .plus, magnitude: 0) + } + + /// Initializes a new signed big integer with the same value as the specified unsigned big integer. + public init(_ integer: CS.BigUInt) { + self.magnitude = integer + self.sign = .plus + } + + public init(_ source: T) where T : BinaryInteger { + if source >= (0 as T) { + self.init(sign: .plus, magnitude: CS.BigUInt(source)) + } + else { + var words = Array(source.words) + words.twosComplement() + self.init(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + } + + public init?(exactly source: T) where T : BinaryInteger { + self.init(source) + } + + public init(clamping source: T) where T : BinaryInteger { + self.init(source) + } + + public init(truncatingIfNeeded source: T) where T : BinaryInteger { + self.init(source) + } +} + +extension CS.BigUInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: UInt64) { + self.init(value) + } +} + +extension CS.BigInt: ExpressibleByIntegerLiteral { + /// Initialize a new big integer from an integer literal. + public init(integerLiteral value: Int64) { + self.init(value) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Multiplication.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Multiplication.swift new file mode 100644 index 00000000..bb8bf7d5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Multiplication.swift @@ -0,0 +1,165 @@ +// +// Multiplication.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + + //MARK: Multiplication + + /// Multiply this big integer by a single word, and store the result in place of the original big integer. + /// + /// - Complexity: O(count) + public mutating func multiply(byWord y: Word) { + guard y != 0 else { self = 0; return } + guard y != 1 else { return } + var carry: Word = 0 + let c = self.count + for i in 0 ..< c { + let (h, l) = self[i].multipliedFullWidth(by: y) + let (low, o) = l.addingReportingOverflow(carry) + self[i] = low + carry = (o ? h + 1 : h) + } + self[c] = carry + } + + /// Multiply this big integer by a single Word, and return the result. + /// + /// - Complexity: O(count) + public func multiplied(byWord y: Word) -> CS.BigUInt { + var r = self + r.multiply(byWord: y) + return r + } + + /// Multiply `x` by `y`, and add the result to this integer, optionally shifted `shift` words to the left. + /// + /// - Note: This is the fused multiply/shift/add operation; it is more efficient than doing the components + /// individually. (The fused operation doesn't need to allocate space for temporary big integers.) + /// - Returns: `self` is set to `self + (x * y) << (shift * 2^Word.bitWidth)` + /// - Complexity: O(count) + public mutating func multiplyAndAdd(_ x: CS.BigUInt, _ y: Word, shiftedBy shift: Int = 0) { + precondition(shift >= 0) + guard y != 0 && x.count > 0 else { return } + guard y != 1 else { self.add(x, shiftedBy: shift); return } + var mulCarry: Word = 0 + var addCarry = false + let xc = x.count + var xi = 0 + while xi < xc || addCarry || mulCarry > 0 { + let (h, l) = x[xi].multipliedFullWidth(by: y) + let (low, o) = l.addingReportingOverflow(mulCarry) + mulCarry = (o ? h + 1 : h) + + let ai = shift + xi + let (sum1, so1) = self[ai].addingReportingOverflow(low) + if addCarry { + let (sum2, so2) = sum1.addingReportingOverflow(1) + self[ai] = sum2 + addCarry = so1 || so2 + } + else { + self[ai] = sum1 + addCarry = so1 + } + xi += 1 + } + } + + /// Multiply this integer by `y` and return the result. + /// + /// - Note: This uses the naive O(n^2) multiplication algorithm unless both arguments have more than + /// `BigUInt.directMultiplicationLimit` words. + /// - Complexity: O(n^log2(3)) + public func multiplied(by y: CS.BigUInt) -> CS.BigUInt { + // This method is mostly defined for symmetry with the rest of the arithmetic operations. + return self * y + } + + /// Multiplication switches to an asymptotically better recursive algorithm when arguments have more words than this limit. + public static var directMultiplicationLimit: Int = 1024 + + /// Multiply `a` by `b` and return the result. + /// + /// - Note: This uses the naive O(n^2) multiplication algorithm unless both arguments have more than + /// `BigUInt.directMultiplicationLimit` words. + /// - Complexity: O(n^log2(3)) + public static func *(x: CS.BigUInt, y: CS.BigUInt) -> CS.BigUInt { + let xc = x.count + let yc = y.count + if xc == 0 { return CS.BigUInt() } + if yc == 0 { return CS.BigUInt() } + if yc == 1 { return x.multiplied(byWord: y[0]) } + if xc == 1 { return y.multiplied(byWord: x[0]) } + + if Swift.min(xc, yc) <= CS.BigUInt.directMultiplicationLimit { + // Long multiplication. + let left = (xc < yc ? y : x) + let right = (xc < yc ? x : y) + var result = CS.BigUInt() + for i in (0 ..< right.count).reversed() { + result.multiplyAndAdd(left, right[i], shiftedBy: i) + } + return result + } + + if yc < xc { + let (xh, xl) = x.split + var r = xl * y + r.add(xh * y, shiftedBy: x.middleIndex) + return r + } + else if xc < yc { + let (yh, yl) = y.split + var r = yl * x + r.add(yh * x, shiftedBy: y.middleIndex) + return r + } + + let shift = x.middleIndex + + // Karatsuba multiplication: + // x * y = * = (ignoring carry) + let (a, b) = x.split + let (c, d) = y.split + + let high = a * c + let low = b * d + let xp = a >= b + let yp = c >= d + let xm = (xp ? a - b : b - a) + let ym = (yp ? c - d : d - c) + let m = xm * ym + + var r = low + r.add(high, shiftedBy: 2 * shift) + r.add(low, shiftedBy: shift) + r.add(high, shiftedBy: shift) + if xp == yp { + r.subtract(m, shiftedBy: shift) + } + else { + r.add(m, shiftedBy: shift) + } + return r + } + + /// Multiply `a` by `b` and store the result in `a`. + public static func *=(a: inout CS.BigUInt, b: CS.BigUInt) { + a = a * b + } +} + +extension CS.BigInt { + /// Multiply `a` with `b` and return the result. + public static func *(a: CS.BigInt, b: CS.BigInt) -> CS.BigInt { + return CS.BigInt(sign: a.sign == b.sign ? .plus : .minus, magnitude: a.magnitude * b.magnitude) + } + + /// Multiply `a` with `b` in place. + public static func *=(a: inout CS.BigInt, b: CS.BigInt) { a = a * b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Prime Test.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Prime Test.swift new file mode 100644 index 00000000..e9fdffa4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Prime Test.swift @@ -0,0 +1,153 @@ +// +// Prime Test.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +/// The first several [prime numbers][primes]. +/// +/// [primes]: https://oeis.org/A000040 +let primes: [CS.BigUInt.Word] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] + +/// The ith element in this sequence is the smallest composite number that passes the strong probable prime test +/// for all of the first (i+1) primes. +/// +/// This is sequence [A014233](http://oeis.org/A014233) on the [Online Encyclopaedia of Integer Sequences](http://oeis.org). +let pseudoPrimes: [CS.BigUInt] = [ + /* 2 */ 2_047, + /* 3 */ 1_373_653, + /* 5 */ 25_326_001, + /* 7 */ 3_215_031_751, + /* 11 */ 2_152_302_898_747, + /* 13 */ 3_474_749_660_383, + /* 17 */ 341_550_071_728_321, + /* 19 */ 341_550_071_728_321, + /* 23 */ 3_825_123_056_546_413_051, + /* 29 */ 3_825_123_056_546_413_051, + /* 31 */ 3_825_123_056_546_413_051, + /* 37 */ "318665857834031151167461", + /* 41 */ "3317044064679887385961981", +] + +extension CS.BigUInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: CS.BigUInt) -> Bool { + precondition(base > (1 as CS.BigUInt)) + precondition(self > (0 as CS.BigUInt)) + let dec = self - 1 + + let r = dec.trailingZeroBitCount + let d = dec >> r + + var test = base.power(d, modulus: self) + if test == 1 || test == dec { return true } + + if r > 0 { + let shift = self.leadingZeroBitCount + let normalized = self << shift + for _ in 1 ..< r { + test *= test + test.formRemainder(dividingBy: normalized, normalizedBy: shift) + if test == 1 { + return false + } + if test == dec { return true } + } + } + return false + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if count <= 1 && self[0] < 2 { return false } + if count == 1 && self[0] < 4 { return true } + + // Even numbers above 2 aren't prime. + if self[0] & 1 == 0 { return false } + + // Quickly check for small primes. + for i in 1 ..< primes.count { + let p = primes[i] + if self.count == 1 && self[0] == p { + return true + } + if self.quotientAndRemainder(dividingByWord: p).remainder == 0 { + return false + } + } + + /// Give an exact answer when we can. + if self < pseudoPrimes.last! { + for i in 0 ..< pseudoPrimes.count { + guard isStrongProbablePrime(CS.BigUInt(primes[i])) else { + break + } + if self < pseudoPrimes[i] { + // `self` is below the lowest pseudoprime corresponding to the prime bases we tested. It's a prime! + return true + } + } + return false + } + + /// Otherwise do as many rounds of random SPPT as required. + for _ in 0 ..< rounds { + let random = CS.BigUInt.randomInteger(lessThan: self - 2) + 2 + guard isStrongProbablePrime(random) else { + return false + } + } + + // Well, it smells primey to me. + return true + } +} + +extension CS.BigInt { + //MARK: Primality Testing + + /// Returns true iff this integer passes the [strong probable prime test][sppt] for the specified base. + /// + /// [sppt]: https://en.wikipedia.org/wiki/Probable_prime + public func isStrongProbablePrime(_ base: CS.BigInt) -> Bool { + precondition(base.sign == .plus) + if self.sign == .minus { return false } + return self.magnitude.isStrongProbablePrime(base.magnitude) + } + + /// Returns true if this integer is probably prime. Returns false if this integer is definitely not prime. + /// + /// This function performs a probabilistic [Miller-Rabin Primality Test][mrpt], consisting of `rounds` iterations, + /// each calculating the strong probable prime test for a random base. The number of rounds is 10 by default, + /// but you may specify your own choice. + /// + /// To speed things up, the function checks if `self` is divisible by the first few prime numbers before + /// diving into (slower) Miller-Rabin testing. + /// + /// Also, when `self` is less than 82 bits wide, `isPrime` does a deterministic test that is guaranteed to + /// return a correct result. + /// + /// [mrpt]: https://en.wikipedia.org/wiki/Miller–Rabin_primality_test + public func isPrime(rounds: Int = 10) -> Bool { + if self.sign == .minus { return false } + return self.magnitude.isPrime(rounds: rounds) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Random.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Random.swift new file mode 100644 index 00000000..33e5802f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Random.swift @@ -0,0 +1,101 @@ +// +// Random.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-04. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + /// Create a big unsigned integer consisting of `width` uniformly distributed random bits. + /// + /// - Parameter width: The maximum number of one bits in the result. + /// - Parameter generator: The source of randomness. + /// - Returns: A big unsigned integer less than `1 << width`. + public static func randomInteger(withMaximumWidth width: Int, using generator: inout RNG) -> CS.BigUInt { + var result = CS.BigUInt.zero + var bitsLeft = width + var i = 0 + let wordsNeeded = (width + Word.bitWidth - 1) / Word.bitWidth + if wordsNeeded > 2 { + result.reserveCapacity(wordsNeeded) + } + while bitsLeft >= Word.bitWidth { + result[i] = generator.next() + i += 1 + bitsLeft -= Word.bitWidth + } + if bitsLeft > 0 { + let mask: Word = (1 << bitsLeft) - 1 + result[i] = (generator.next() as Word) & mask + } + return result + } + + /// Create a big unsigned integer consisting of `width` uniformly distributed random bits. + /// + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Parameter width: The maximum number of one bits in the result. + /// - Returns: A big unsigned integer less than `1 << width`. + public static func randomInteger(withMaximumWidth width: Int) -> CS.BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(withMaximumWidth: width, using: &rng) + } + + /// Create a big unsigned integer consisting of `width-1` uniformly distributed random bits followed by a one bit. + /// + /// - Note: If `width` is zero, the result is zero. + /// + /// - Parameter width: The number of bits required to represent the answer. + /// - Parameter generator: The source of randomness. + /// - Returns: A random big unsigned integer whose width is `width`. + public static func randomInteger(withExactWidth width: Int, using generator: inout RNG) -> CS.BigUInt { + // width == 0 -> return 0 because there is no room for a one bit. + // width == 1 -> return 1 because there is no room for any random bits. + guard width > 1 else { return CS.BigUInt(width) } + var result = randomInteger(withMaximumWidth: width - 1, using: &generator) + result[(width - 1) / Word.bitWidth] |= 1 << Word((width - 1) % Word.bitWidth) + return result + } + + /// Create a big unsigned integer consisting of `width-1` uniformly distributed random bits followed by a one bit. + /// + /// - Note: If `width` is zero, the result is zero. + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Returns: A random big unsigned integer whose width is `width`. + public static func randomInteger(withExactWidth width: Int) -> CS.BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(withExactWidth: width, using: &rng) + } + + /// Create a uniformly distributed random unsigned integer that's less than the specified limit. + /// + /// - Precondition: `limit > 0`. + /// + /// - Parameter limit: The upper bound on the result. + /// - Parameter generator: The source of randomness. + /// - Returns: A random big unsigned integer that is less than `limit`. + public static func randomInteger(lessThan limit: CS.BigUInt, using generator: inout RNG) -> CS.BigUInt { + precondition(limit > 0, "\(#function): 0 is not a valid limit") + let width = limit.bitWidth + var random = randomInteger(withMaximumWidth: width, using: &generator) + while random >= limit { + random = randomInteger(withMaximumWidth: width, using: &generator) + } + return random + } + + /// Create a uniformly distributed random unsigned integer that's less than the specified limit. + /// + /// - Precondition: `limit > 0`. + /// - Note: I use a `SystemRandomGeneratorGenerator` as the source of randomness. + /// + /// - Parameter limit: The upper bound on the result. + /// - Returns: A random big unsigned integer that is less than `limit`. + public static func randomInteger(lessThan limit: CS.BigUInt) -> CS.BigUInt { + var rng = SystemRandomNumberGenerator() + return randomInteger(lessThan: limit, using: &rng) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Shifts.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Shifts.swift new file mode 100644 index 00000000..9960bf6f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Shifts.swift @@ -0,0 +1,211 @@ +// +// Shifts.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + + //MARK: Shift Operators + + internal func shiftedLeft(by amount: Word) -> CS.BigUInt { + guard amount > 0 else { return self } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let up = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let down = Word(Word.bitWidth) - up + + var result = CS.BigUInt() + if up > 0 { + var i = 0 + var lowbits: Word = 0 + while i < self.count || lowbits > 0 { + let word = self[i] + result[i + ext] = word << up | lowbits + lowbits = word >> down + i += 1 + } + } + else { + for i in 0 ..< self.count { + result[i + ext] = self[i] + } + } + return result + } + + internal mutating func shiftLeft(by amount: Word) { + guard amount > 0 else { return } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let up = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let down = Word(Word.bitWidth) - up + + if up > 0 { + var i = 0 + var lowbits: Word = 0 + while i < self.count || lowbits > 0 { + let word = self[i] + self[i] = word << up | lowbits + lowbits = word >> down + i += 1 + } + } + if ext > 0 && self.count > 0 { + self.shiftLeft(byWords: ext) + } + } + + internal func shiftedRight(by amount: Word) -> CS.BigUInt { + guard amount > 0 else { return self } + guard amount < self.bitWidth else { return 0 } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let down = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let up = Word(Word.bitWidth) - down + + var result = CS.BigUInt() + if down > 0 { + var highbits: Word = 0 + for i in (ext ..< self.count).reversed() { + let word = self[i] + result[i - ext] = highbits | word >> down + highbits = word << up + } + } + else { + for i in (ext ..< self.count).reversed() { + result[i - ext] = self[i] + } + } + return result + } + + internal mutating func shiftRight(by amount: Word) { + guard amount > 0 else { return } + guard amount < self.bitWidth else { self.clear(); return } + + let ext = Int(amount / Word(Word.bitWidth)) // External shift amount (new words) + let down = Word(amount % Word(Word.bitWidth)) // Internal shift amount (subword shift) + let up = Word(Word.bitWidth) - down + + if ext > 0 { + self.shiftRight(byWords: ext) + } + if down > 0 { + var i = self.count - 1 + var highbits: Word = 0 + while i >= 0 { + let word = self[i] + self[i] = highbits | word >> down + highbits = word << up + i -= 1 + } + } + } + + public static func >>=(lhs: inout CS.BigUInt, rhs: Other) { + if rhs < (0 as Other) { + lhs <<= (0 - rhs) + } + else if rhs >= lhs.bitWidth { + lhs.clear() + } + else { + lhs.shiftRight(by: UInt(rhs)) + } + } + + public static func <<=(lhs: inout CS.BigUInt, rhs: Other) { + if rhs < (0 as Other) { + lhs >>= (0 - rhs) + return + } + lhs.shiftLeft(by: Word(exactly: rhs)!) + } + + public static func >>(lhs: CS.BigUInt, rhs: Other) -> CS.BigUInt { + if rhs < (0 as Other) { + return lhs << (0 - rhs) + } + if rhs > Word.max { + return 0 + } + return lhs.shiftedRight(by: UInt(rhs)) + } + + public static func <<(lhs: CS.BigUInt, rhs: Other) -> CS.BigUInt { + if rhs < (0 as Other) { + return lhs >> (0 - rhs) + } + return lhs.shiftedLeft(by: Word(exactly: rhs)!) + } +} + +extension CS.BigInt { + func shiftedLeft(by amount: Word) -> CS.BigInt { + return CS.BigInt(sign: self.sign, magnitude: self.magnitude.shiftedLeft(by: amount)) + } + + mutating func shiftLeft(by amount: Word) { + self.magnitude.shiftLeft(by: amount) + } + + func shiftedRight(by amount: Word) -> CS.BigInt { + let m = self.magnitude.shiftedRight(by: amount) + return CS.BigInt(sign: self.sign, magnitude: self.sign == .minus && m.isZero ? 1 : m) + } + + mutating func shiftRight(by amount: Word) { + magnitude.shiftRight(by: amount) + if sign == .minus, magnitude.isZero { + magnitude.load(1) + } + } + + public static func &<<(left: CS.BigInt, right: CS.BigInt) -> CS.BigInt { + return left.shiftedLeft(by: right.words[0]) + } + + public static func &<<=(left: inout CS.BigInt, right: CS.BigInt) { + left.shiftLeft(by: right.words[0]) + } + + public static func &>>(left: CS.BigInt, right: CS.BigInt) -> CS.BigInt { + return left.shiftedRight(by: right.words[0]) + } + + public static func &>>=(left: inout CS.BigInt, right: CS.BigInt) { + left.shiftRight(by: right.words[0]) + } + + public static func <<(lhs: CS.BigInt, rhs: Other) -> CS.BigInt { + guard rhs >= (0 as Other) else { return lhs >> (0 - rhs) } + return lhs.shiftedLeft(by: Word(rhs)) + } + + public static func <<=(lhs: inout CS.BigInt, rhs: Other) { + if rhs < (0 as Other) { + lhs >>= (0 - rhs) + } + else { + lhs.shiftLeft(by: Word(rhs)) + } + } + + public static func >>(lhs: CS.BigInt, rhs: Other) -> CS.BigInt { + guard rhs >= (0 as Other) else { return lhs << (0 - rhs) } + return lhs.shiftedRight(by: Word(rhs)) + } + + public static func >>=(lhs: inout CS.BigInt, rhs: Other) { + if rhs < (0 as Other) { + lhs <<= (0 - rhs) + } + else { + lhs.shiftRight(by: Word(rhs)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Square Root.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Square Root.swift new file mode 100644 index 00000000..ab6df657 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Square Root.swift @@ -0,0 +1,41 @@ +// +// Square Root.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +//MARK: Square Root + +extension CS.BigUInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> CS.BigUInt { + // This implementation uses Newton's method. + guard !self.isZero else { return CS.BigUInt() } + var x = CS.BigUInt(1) << ((self.bitWidth + 1) / 2) + var y: CS.BigUInt = 0 + while true { + y.load(self) + y /= x + y += x + y >>= 1 + if x == y || x == y - 1 { break } + x = y + } + return x + } +} + +extension CS.BigInt { + /// Returns the integer square root of a big integer; i.e., the largest integer whose square isn't greater than `value`. + /// + /// - Requires: self >= 0 + /// - Returns: floor(sqrt(self)) + public func squareRoot() -> CS.BigInt { + precondition(self.sign == .plus) + return CS.BigInt(sign: .plus, magnitude: self.magnitude.squareRoot()) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Strideable.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Strideable.swift new file mode 100644 index 00000000..ffba780e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Strideable.swift @@ -0,0 +1,38 @@ +// +// Strideable.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt: Strideable { + /// A type that can represent the distance between two values ofa `BigUInt`. + public typealias Stride = CS.BigInt + + /// Adds `n` to `self` and returns the result. Traps if the result would be less than zero. + public func advanced(by n: CS.BigInt) -> CS.BigUInt { + return n.sign == .minus ? self - n.magnitude : self + n.magnitude + } + + /// Returns the (potentially negative) difference between `self` and `other` as a `BigInt`. Never traps. + public func distance(to other: CS.BigUInt) -> CS.BigInt { + return CS.BigInt(other) - CS.BigInt(self) + } +} + +extension CS.BigInt: Strideable { + public typealias Stride = CS.BigInt + + /// Returns `self + n`. + public func advanced(by n: Stride) -> CS.BigInt { + return self + n + } + + /// Returns `other - self`. + public func distance(to other: CS.BigInt) -> Stride { + return other - self + } +} + + diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/String Conversion.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/String Conversion.swift new file mode 100644 index 00000000..9707bbb7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/String Conversion.swift @@ -0,0 +1,236 @@ +// +// String Conversion.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + + //MARK: String Conversion + + /// Calculates the number of numerals in a given radix that fit inside a single `Word`. + /// + /// - Returns: (chars, power) where `chars` is highest that satisfy `radix^chars <= 2^Word.bitWidth`. `power` is zero + /// if radix is a power of two; otherwise `power == radix^chars`. + fileprivate static func charsPerWord(forRadix radix: Int) -> (chars: Int, power: Word) { + var power: Word = 1 + var overflow = false + var count = 0 + while !overflow { + let (p, o) = power.multipliedReportingOverflow(by: Word(radix)) + overflow = o + if !o || p == 0 { + count += 1 + power = p + } + } + return (count, power) + } + + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string consisting of characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + precondition(radix > 1) + let (charsPerWord, power) = CS.BigUInt.charsPerWord(forRadix: radix) + + var words: [Word] = [] + var end = text.endIndex + var start = end + var count = 0 + while start != text.startIndex { + start = text.index(before: start) + count += 1 + if count == charsPerWord { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + end = start + count = 0 + } + } + if start != end { + guard let d = Word.init(text[start ..< end], radix: radix) else { return nil } + words.append(d) + } + + if power == 0 { + self.init(words: words) + } + else { + self.init() + for d in words.reversed() { + self.multiply(byWord: power) + self.addWord(d) + } + } + } +} + +extension CS.BigInt { + /// Initialize a big integer from an ASCII representation in a given radix. Numerals above `9` are represented by + /// letters from the English alphabet. + /// + /// - Requires: `radix > 1 && radix < 36` + /// - Parameter `text`: A string optionally starting with "-" or "+" followed by characters corresponding to numerals in the given radix. (0-9, a-z, A-Z) + /// - Parameter `radix`: The base of the number system to use, or 10 if unspecified. + /// - Returns: The integer represented by `text`, or nil if `text` contains a character that does not represent a numeral in `radix`. + public init?(_ text: S, radix: Int = 10) { + var magnitude: CS.BigUInt? + var sign: Sign = .plus + if text.first == "-" { + sign = .minus + let text = text.dropFirst() + magnitude = CS.BigUInt(text, radix: radix) + } + else if text.first == "+" { + let text = text.dropFirst() + magnitude = CS.BigUInt(text, radix: radix) + } + else { + magnitude = CS.BigUInt(text, radix: radix) + } + guard let m = magnitude else { return nil } + self.magnitude = m + self.sign = sign + } +} + +extension String { + /// Initialize a new string with the base-10 representation of an unsigned big integer. + /// + /// - Complexity: O(v.count^2) + public init(_ v: CS.BigUInt) { self.init(v, radix: 10, uppercase: false) } + + /// Initialize a new string representing an unsigned big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ v: CS.BigUInt, radix: Int, uppercase: Bool = false) { + precondition(radix > 1) + let (charsPerWord, power) = CS.BigUInt.charsPerWord(forRadix: radix) + + guard !v.isZero else { self = "0"; return } + + var parts: [String] + if power == 0 { + parts = v.words.map { String($0, radix: radix, uppercase: uppercase) } + } + else { + parts = [] + var rest = v + while !rest.isZero { + let mod = rest.divide(byWord: power) + parts.append(String(mod, radix: radix, uppercase: uppercase)) + } + } + assert(!parts.isEmpty) + + self = "" + var first = true + for part in parts.reversed() { + let zeroes = charsPerWord - part.count + assert(zeroes >= 0) + if !first && zeroes > 0 { + // Insert leading zeroes for mid-Words + self += String(repeating: "0", count: zeroes) + } + first = false + self += part + } + } + + /// Initialize a new string representing a signed big integer in the given radix (base). + /// + /// Numerals greater than 9 are represented as letters from the English alphabet, + /// starting with `a` if `uppercase` is false or `A` otherwise. + /// + /// - Requires: radix > 1 && radix <= 36 + /// - Complexity: O(count) when radix is a power of two; otherwise O(count^2). + public init(_ value: CS.BigInt, radix: Int = 10, uppercase: Bool = false) { + self = String(value.magnitude, radix: radix, uppercase: uppercase) + if value.sign == .minus { + self = "-" + self + } + } +} + +extension CS.BigUInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = CS.BigUInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = CS.BigUInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = CS.BigUInt(value, radix: 10)! + } +} + +extension CS.BigInt: ExpressibleByStringLiteral { + /// Initialize a new big integer from a Unicode scalar. + /// The scalar must represent a decimal digit. + public init(unicodeScalarLiteral value: UnicodeScalar) { + self = CS.BigInt(String(value), radix: 10)! + } + + /// Initialize a new big integer from an extended grapheme cluster. + /// The cluster must consist of a decimal digit. + public init(extendedGraphemeClusterLiteral value: String) { + self = CS.BigInt(value, radix: 10)! + } + + /// Initialize a new big integer from a decimal number represented by a string literal of arbitrary length. + /// The string must contain only decimal digits. + public init(stringLiteral value: StringLiteralType) { + self = CS.BigInt(value, radix: 10)! + } +} + +extension CS.BigUInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension CS.BigInt: CustomStringConvertible { + /// Return the decimal representation of this integer. + public var description: String { + return String(self, radix: 10) + } +} + +extension CS.BigUInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.bitWidth) bits)" + } +} + +extension CS.BigInt: CustomPlaygroundDisplayConvertible { + + /// Return the playground quick look representation of this integer. + public var playgroundDescription: Any { + let text = String(self) + return text + " (\(self.magnitude.bitWidth) bits)" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Subtraction.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Subtraction.swift new file mode 100644 index 00000000..8baeed95 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Subtraction.swift @@ -0,0 +1,169 @@ +// +// Subtraction.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2016-01-03. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension CS.BigUInt { + //MARK: Subtraction + + /// Subtract `word` from this integer in place, returning a flag indicating if the operation + /// caused an arithmetic overflow. `word` is shifted `shift` words to the left before being subtracted. + /// + /// - Note: If the result indicates an overflow, then `self` becomes the two's complement of the absolute difference. + /// - Complexity: O(count) + internal mutating func subtractWordReportingOverflow(_ word: Word, shiftedBy shift: Int = 0) -> Bool { + precondition(shift >= 0) + var carry: Word = word + var i = shift + let count = self.count + while carry > 0 && i < count { + let (d, c) = self[i].subtractingReportingOverflow(carry) + self[i] = d + carry = (c ? 1 : 0) + i += 1 + } + return carry > 0 + } + + /// Subtract `word` from this integer, returning the difference and a flag that is true if the operation + /// caused an arithmetic overflow. `word` is shifted `shift` words to the left before being subtracted. + /// + /// - Note: If `overflow` is true, then the returned value is the two's complement of the absolute difference. + /// - Complexity: O(count) + internal func subtractingWordReportingOverflow(_ word: Word, shiftedBy shift: Int = 0) -> (partialValue: CS.BigUInt, overflow: Bool) { + var result = self + let overflow = result.subtractWordReportingOverflow(word, shiftedBy: shift) + return (result, overflow) + } + + /// Subtract a digit `d` from this integer in place. + /// `d` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= d * 2^shift + /// - Complexity: O(count) + internal mutating func subtractWord(_ word: Word, shiftedBy shift: Int = 0) { + let overflow = subtractWordReportingOverflow(word, shiftedBy: shift) + precondition(!overflow) + } + + /// Subtract a digit `d` from this integer and return the result. + /// `d` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= d * 2^shift + /// - Complexity: O(count) + internal func subtractingWord(_ word: Word, shiftedBy shift: Int = 0) -> CS.BigUInt { + var result = self + result.subtractWord(word, shiftedBy: shift) + return result + } + + /// Subtract `other` from this integer in place, and return a flag indicating if the operation caused an + /// arithmetic overflow. `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Note: If the result indicates an overflow, then `self` becomes the twos' complement of the absolute difference. + /// - Complexity: O(count) + public mutating func subtractReportingOverflow(_ b: CS.BigUInt, shiftedBy shift: Int = 0) -> Bool { + precondition(shift >= 0) + var carry = false + var bi = 0 + let bc = b.count + let count = self.count + while bi < bc || (shift + bi < count && carry) { + let ai = shift + bi + let (d, c) = self[ai].subtractingReportingOverflow(b[bi]) + if carry { + let (d2, c2) = d.subtractingReportingOverflow(1) + self[ai] = d2 + carry = c || c2 + } + else { + self[ai] = d + carry = c + } + bi += 1 + } + return carry + } + + /// Subtract `other` from this integer, returning the difference and a flag indicating arithmetic overflow. + /// `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Note: If `overflow` is true, then the result value is the twos' complement of the absolute value of the difference. + /// - Complexity: O(count) + public func subtractingReportingOverflow(_ other: CS.BigUInt, shiftedBy shift: Int) -> (partialValue: CS.BigUInt, overflow: Bool) { + var result = self + let overflow = result.subtractReportingOverflow(other, shiftedBy: shift) + return (result, overflow) + } + + /// Subtracts `other` from `self`, returning the result and a flag indicating arithmetic overflow. + /// + /// - Note: When the operation overflows, then `partialValue` is the twos' complement of the absolute value of the difference. + /// - Complexity: O(count) + public func subtractingReportingOverflow(_ other: CS.BigUInt) -> (partialValue: CS.BigUInt, overflow: Bool) { + return self.subtractingReportingOverflow(other, shiftedBy: 0) + } + + /// Subtract `other` from this integer in place. + /// `other` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= other * 2^shift + /// - Complexity: O(count) + public mutating func subtract(_ other: CS.BigUInt, shiftedBy shift: Int = 0) { + let overflow = subtractReportingOverflow(other, shiftedBy: shift) + precondition(!overflow) + } + + /// Subtract `b` from this integer, and return the difference. + /// `b` is shifted `shift` digits to the left before being subtracted. + /// + /// - Requires: self >= b * 2^shift + /// - Complexity: O(count) + public func subtracting(_ other: CS.BigUInt, shiftedBy shift: Int = 0) -> CS.BigUInt { + var result = self + result.subtract(other, shiftedBy: shift) + return result + } + + /// Decrement this integer by one. + /// + /// - Requires: !isZero + /// - Complexity: O(count) + public mutating func decrement(shiftedBy shift: Int = 0) { + self.subtract(1, shiftedBy: shift) + } + + /// Subtract `b` from `a` and return the result. + /// + /// - Requires: a >= b + /// - Complexity: O(a.count) + public static func -(a: CS.BigUInt, b: CS.BigUInt) -> CS.BigUInt { + return a.subtracting(b) + } + + /// Subtract `b` from `a` and store the result in `a`. + /// + /// - Requires: a >= b + /// - Complexity: O(a.count) + public static func -=(a: inout CS.BigUInt, b: CS.BigUInt) { + a.subtract(b) + } +} + +extension CS.BigInt { + public mutating func negate() { + guard !magnitude.isZero else { return } + self.sign = self.sign == .plus ? .minus : .plus + } + + /// Subtract `b` from `a` and return the result. + public static func -(a: CS.BigInt, b: CS.BigInt) -> CS.BigInt { + return a + -b + } + + /// Subtract `b` from `a` in place. + public static func -=(a: inout CS.BigInt, b: CS.BigInt) { a = a - b } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Words and Bits.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Words and Bits.swift new file mode 100644 index 00000000..95a99e15 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CS_BigInt/Words and Bits.swift @@ -0,0 +1,202 @@ +// +// Words and Bits.swift +// CS.BigInt +// +// Created by Károly Lőrentey on 2017-08-11. +// Copyright © 2016-2017 Károly Lőrentey. +// + +extension Array where Element == UInt { + mutating func twosComplement() { + var increment = true + for i in 0 ..< self.count { + if increment { + (self[i], increment) = (~self[i]).addingReportingOverflow(1) + } + else { + self[i] = ~self[i] + } + } + } +} + +extension CS.BigUInt { + public subscript(bitAt index: Int) -> Bool { + get { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + return self[i] & (1 << j) != 0 + } + set { + precondition(index >= 0) + let (i, j) = index.quotientAndRemainder(dividingBy: Word.bitWidth) + if newValue { + self[i] |= 1 << j + } + else { + self[i] &= ~(1 << j) + } + } + } +} + +extension CS.BigUInt { + /// The minimum number of bits required to represent this integer in binary. + /// + /// - Returns: floor(log2(2 * self + 1)) + /// - Complexity: O(1) + public var bitWidth: Int { + guard count > 0 else { return 0 } + return count * Word.bitWidth - self[count - 1].leadingZeroBitCount + } + + /// The number of leading zero bits in the binary representation of this integer in base `2^(Word.bitWidth)`. + /// This is useful when you need to normalize a `BigUInt` such that the top bit of its most significant word is 1. + /// + /// - Note: 0 is considered to have zero leading zero bits. + /// - Returns: A value in `0...(Word.bitWidth - 1)`. + /// - SeeAlso: width + /// - Complexity: O(1) + public var leadingZeroBitCount: Int { + guard count > 0 else { return 0 } + return self[count - 1].leadingZeroBitCount + } + + /// The number of trailing zero bits in the binary representation of this integer. + /// + /// - Note: 0 is considered to have zero trailing zero bits. + /// - Returns: A value in `0...width`. + /// - Complexity: O(count) + public var trailingZeroBitCount: Int { + guard count > 0 else { return 0 } + let i = self.words.firstIndex { $0 != 0 }! + return i * Word.bitWidth + self[i].trailingZeroBitCount + } +} + +extension CS.BigInt { + public var bitWidth: Int { + guard !magnitude.isZero else { return 0 } + return magnitude.bitWidth + 1 + } + + public var trailingZeroBitCount: Int { + // Amazingly, this works fine for negative numbers + return magnitude.trailingZeroBitCount + } +} + +extension CS.BigUInt { + public struct Words: RandomAccessCollection { + private let value: CS.BigUInt + + fileprivate init(_ value: CS.BigUInt) { self.value = value } + + public var startIndex: Int { return 0 } + public var endIndex: Int { return value.count } + + public subscript(_ index: Int) -> Word { + return value[index] + } + } + + public var words: Words { return Words(self) } + + public init(words: Words) where Words.Element == Word { + let uc = words.underestimatedCount + if uc > 2 { + self.init(words: Array(words)) + } + else { + var it = words.makeIterator() + guard let w0 = it.next() else { + self.init() + return + } + guard let w1 = it.next() else { + self.init(word: w0) + return + } + if let w2 = it.next() { + var words: [UInt] = [] + words.reserveCapacity(Swift.max(3, uc)) + words.append(w0) + words.append(w1) + words.append(w2) + while let word = it.next() { + words.append(word) + } + self.init(words: words) + } + else { + self.init(low: w0, high: w1) + } + } + } +} + +extension CS.BigInt { + public struct Words: RandomAccessCollection { + public typealias Indices = CountableRange + + private let value: CS.BigInt + private let decrementLimit: Int + + fileprivate init(_ value: CS.BigInt) { + self.value = value + switch value.sign { + case .plus: + self.decrementLimit = 0 + case .minus: + assert(!value.magnitude.isZero) + self.decrementLimit = value.magnitude.words.firstIndex(where: { $0 != 0 })! + } + } + + public var count: Int { + switch value.sign { + case .plus: + if let high = value.magnitude.words.last, high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + case .minus: + let high = value.magnitude.words.last! + if high >> (Word.bitWidth - 1) != 0 { + return value.magnitude.count + 1 + } + return value.magnitude.count + } + } + + public var indices: Indices { return 0 ..< count } + public var startIndex: Int { return 0 } + public var endIndex: Int { return count } + + public subscript(_ index: Int) -> UInt { + // Note that indices above `endIndex` are accepted. + if value.sign == .plus { + return value.magnitude[index] + } + if index <= decrementLimit { + return ~(value.magnitude[index] &- 1) + } + return ~value.magnitude[index] + } + } + + public var words: Words { + return Words(self) + } + + public init(words: S) where S.Element == Word { + var words = Array(words) + if (words.last ?? 0) >> (Word.bitWidth - 1) == 0 { + self.init(sign: .plus, magnitude: CS.BigUInt(words: words)) + } + else { + words.twosComplement() + self.init(sign: .minus, magnitude: CS.BigUInt(words: words)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift new file mode 100644 index 00000000..f9ba5e45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ChaCha20.swift @@ -0,0 +1,347 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// https://tools.ietf.org/html/rfc7539 +// + +public final class ChaCha20: BlockCipher { + public enum Error: Swift.Error { + case invalidKeyOrInitializationVector + case notSupported + } + + public static let blockSize = 64 // 512 / 8 + public let keySize: Int + + fileprivate let key: Key + fileprivate var counter: Array + + public init(key: Array, iv nonce: Array) throws { + precondition(nonce.count == 12 || nonce.count == 8) + + if key.count != 32 { + throw Error.invalidKeyOrInitializationVector + } + + self.key = Key(bytes: key) + self.keySize = self.key.count + + if nonce.count == 8 { + self.counter = [0, 0, 0, 0, 0, 0, 0, 0] + nonce + } else { + self.counter = [0, 0, 0, 0] + nonce + } + + assert(self.counter.count == 16) + } + + /// https://tools.ietf.org/html/rfc7539#section-2.3. + fileprivate func core(block: inout Array, counter: Array, key: Array) { + precondition(block.count == ChaCha20.blockSize) + precondition(counter.count == 16) + precondition(key.count == 32) + + let j0: UInt32 = 0x61707865 + let j1: UInt32 = 0x3320646e // 0x3620646e sigma/tau + let j2: UInt32 = 0x79622d32 + let j3: UInt32 = 0x6b206574 + let j4: UInt32 = UInt32(bytes: key[0..<4]).bigEndian + let j5: UInt32 = UInt32(bytes: key[4..<8]).bigEndian + let j6: UInt32 = UInt32(bytes: key[8..<12]).bigEndian + let j7: UInt32 = UInt32(bytes: key[12..<16]).bigEndian + let j8: UInt32 = UInt32(bytes: key[16..<20]).bigEndian + let j9: UInt32 = UInt32(bytes: key[20..<24]).bigEndian + let j10: UInt32 = UInt32(bytes: key[24..<28]).bigEndian + let j11: UInt32 = UInt32(bytes: key[28..<32]).bigEndian + let j12: UInt32 = UInt32(bytes: counter[0..<4]).bigEndian + let j13: UInt32 = UInt32(bytes: counter[4..<8]).bigEndian + let j14: UInt32 = UInt32(bytes: counter[8..<12]).bigEndian + let j15: UInt32 = UInt32(bytes: counter[12..<16]).bigEndian + + var (x0, x1, x2, x3, x4, x5, x6, x7) = (j0, j1, j2, j3, j4, j5, j6, j7) + var (x8, x9, x10, x11, x12, x13, x14, x15) = (j8, j9, j10, j11, j12, j13, j14, j15) + + for _ in 0..<10 { // 20 rounds + x0 = x0 &+ x4 + x12 ^= x0 + x12 = (x12 << 16) | (x12 >> 16) + x8 = x8 &+ x12 + x4 ^= x8 + x4 = (x4 << 12) | (x4 >> 20) + x0 = x0 &+ x4 + x12 ^= x0 + x12 = (x12 << 8) | (x12 >> 24) + x8 = x8 &+ x12 + x4 ^= x8 + x4 = (x4 << 7) | (x4 >> 25) + x1 = x1 &+ x5 + x13 ^= x1 + x13 = (x13 << 16) | (x13 >> 16) + x9 = x9 &+ x13 + x5 ^= x9 + x5 = (x5 << 12) | (x5 >> 20) + x1 = x1 &+ x5 + x13 ^= x1 + x13 = (x13 << 8) | (x13 >> 24) + x9 = x9 &+ x13 + x5 ^= x9 + x5 = (x5 << 7) | (x5 >> 25) + x2 = x2 &+ x6 + x14 ^= x2 + x14 = (x14 << 16) | (x14 >> 16) + x10 = x10 &+ x14 + x6 ^= x10 + x6 = (x6 << 12) | (x6 >> 20) + x2 = x2 &+ x6 + x14 ^= x2 + x14 = (x14 << 8) | (x14 >> 24) + x10 = x10 &+ x14 + x6 ^= x10 + x6 = (x6 << 7) | (x6 >> 25) + x3 = x3 &+ x7 + x15 ^= x3 + x15 = (x15 << 16) | (x15 >> 16) + x11 = x11 &+ x15 + x7 ^= x11 + x7 = (x7 << 12) | (x7 >> 20) + x3 = x3 &+ x7 + x15 ^= x3 + x15 = (x15 << 8) | (x15 >> 24) + x11 = x11 &+ x15 + x7 ^= x11 + x7 = (x7 << 7) | (x7 >> 25) + x0 = x0 &+ x5 + x15 ^= x0 + x15 = (x15 << 16) | (x15 >> 16) + x10 = x10 &+ x15 + x5 ^= x10 + x5 = (x5 << 12) | (x5 >> 20) + x0 = x0 &+ x5 + x15 ^= x0 + x15 = (x15 << 8) | (x15 >> 24) + x10 = x10 &+ x15 + x5 ^= x10 + x5 = (x5 << 7) | (x5 >> 25) + x1 = x1 &+ x6 + x12 ^= x1 + x12 = (x12 << 16) | (x12 >> 16) + x11 = x11 &+ x12 + x6 ^= x11 + x6 = (x6 << 12) | (x6 >> 20) + x1 = x1 &+ x6 + x12 ^= x1 + x12 = (x12 << 8) | (x12 >> 24) + x11 = x11 &+ x12 + x6 ^= x11 + x6 = (x6 << 7) | (x6 >> 25) + x2 = x2 &+ x7 + x13 ^= x2 + x13 = (x13 << 16) | (x13 >> 16) + x8 = x8 &+ x13 + x7 ^= x8 + x7 = (x7 << 12) | (x7 >> 20) + x2 = x2 &+ x7 + x13 ^= x2 + x13 = (x13 << 8) | (x13 >> 24) + x8 = x8 &+ x13 + x7 ^= x8 + x7 = (x7 << 7) | (x7 >> 25) + x3 = x3 &+ x4 + x14 ^= x3 + x14 = (x14 << 16) | (x14 >> 16) + x9 = x9 &+ x14 + x4 ^= x9 + x4 = (x4 << 12) | (x4 >> 20) + x3 = x3 &+ x4 + x14 ^= x3 + x14 = (x14 << 8) | (x14 >> 24) + x9 = x9 &+ x14 + x4 ^= x9 + x4 = (x4 << 7) | (x4 >> 25) + } + + x0 = x0 &+ j0 + x1 = x1 &+ j1 + x2 = x2 &+ j2 + x3 = x3 &+ j3 + x4 = x4 &+ j4 + x5 = x5 &+ j5 + x6 = x6 &+ j6 + x7 = x7 &+ j7 + x8 = x8 &+ j8 + x9 = x9 &+ j9 + x10 = x10 &+ j10 + x11 = x11 &+ j11 + x12 = x12 &+ j12 + x13 = x13 &+ j13 + x14 = x14 &+ j14 + x15 = x15 &+ j15 + + block.replaceSubrange(0..<4, with: x0.bigEndian.bytes()) + block.replaceSubrange(4..<8, with: x1.bigEndian.bytes()) + block.replaceSubrange(8..<12, with: x2.bigEndian.bytes()) + block.replaceSubrange(12..<16, with: x3.bigEndian.bytes()) + block.replaceSubrange(16..<20, with: x4.bigEndian.bytes()) + block.replaceSubrange(20..<24, with: x5.bigEndian.bytes()) + block.replaceSubrange(24..<28, with: x6.bigEndian.bytes()) + block.replaceSubrange(28..<32, with: x7.bigEndian.bytes()) + block.replaceSubrange(32..<36, with: x8.bigEndian.bytes()) + block.replaceSubrange(36..<40, with: x9.bigEndian.bytes()) + block.replaceSubrange(40..<44, with: x10.bigEndian.bytes()) + block.replaceSubrange(44..<48, with: x11.bigEndian.bytes()) + block.replaceSubrange(48..<52, with: x12.bigEndian.bytes()) + block.replaceSubrange(52..<56, with: x13.bigEndian.bytes()) + block.replaceSubrange(56..<60, with: x14.bigEndian.bytes()) + block.replaceSubrange(60..<64, with: x15.bigEndian.bytes()) + } + + // XORKeyStream + func process(bytes: ArraySlice, counter: inout Array, key: Array) -> Array { + precondition(counter.count == 16) + precondition(key.count == 32) + + var block = Array(repeating: 0, count: ChaCha20.blockSize) + var bytesSlice = bytes + var out = Array(reserveCapacity: bytesSlice.count) + + while bytesSlice.count >= ChaCha20.blockSize { + self.core(block: &block, counter: counter, key: key) + for (i, x) in block.enumerated() { + out.append(bytesSlice[bytesSlice.startIndex + i] ^ x) + } + var u: UInt32 = 1 + for i in 0..<4 { + u += UInt32(counter[i]) + counter[i] = UInt8(u & 0xff) + u >>= 8 + } + bytesSlice = bytesSlice[bytesSlice.startIndex + ChaCha20.blockSize..) throws -> Array { + self.process(bytes: bytes, counter: &self.counter, key: Array(self.key)) + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + try self.encrypt(bytes) + } +} + +// MARK: Encryptor + +extension ChaCha20 { + public struct ChaChaEncryptor: Cryptor, Updatable { + private var accumulated = Array() + private let chacha: ChaCha20 + + init(chacha: ChaCha20) { + self.chacha = chacha + } + + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + var encrypted = Array() + encrypted.reserveCapacity(self.accumulated.count) + for chunk in self.accumulated.batched(by: ChaCha20.blockSize) { + if isLast || self.accumulated.count >= ChaCha20.blockSize { + encrypted += try self.chacha.encrypt(chunk) + self.accumulated.removeFirst(chunk.count) // TODO: improve performance + } + } + return encrypted + } + + public func seek(to: Int) throws { + throw Error.notSupported + } + } +} + +// MARK: Decryptor + +extension ChaCha20 { + public struct ChaChaDecryptor: Cryptor, Updatable { + private var accumulated = Array() + + private var offset: Int = 0 + private var offsetToRemove: Int = 0 + private let chacha: ChaCha20 + + init(chacha: ChaCha20) { + self.chacha = chacha + } + + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = true) throws -> Array { + // prepend "offset" number of bytes at the beginning + if self.offset > 0 { + self.accumulated += Array(repeating: 0, count: self.offset) + bytes + self.offsetToRemove = self.offset + self.offset = 0 + } else { + self.accumulated += bytes + } + + var plaintext = Array() + plaintext.reserveCapacity(self.accumulated.count) + for chunk in self.accumulated.batched(by: ChaCha20.blockSize) { + if isLast || self.accumulated.count >= ChaCha20.blockSize { + plaintext += try self.chacha.decrypt(chunk) + + // remove "offset" from the beginning of first chunk + if self.offsetToRemove > 0 { + plaintext.removeFirst(self.offsetToRemove) // TODO: improve performance + self.offsetToRemove = 0 + } + + self.accumulated.removeFirst(chunk.count) + } + } + + return plaintext + } + + public func seek(to: Int) throws { + throw Error.notSupported + } + } +} + +// MARK: Cryptors + +extension ChaCha20: Cryptors { + //TODO: Use BlockEncryptor/BlockDecryptor + + public func makeEncryptor() -> Cryptor & Updatable { + ChaCha20.ChaChaEncryptor(chacha: self) + } + + public func makeDecryptor() -> Cryptor & Updatable { + ChaCha20.ChaChaDecryptor(chacha: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Checksum.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Checksum.swift new file mode 100644 index 00000000..26ec1288 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Checksum.swift @@ -0,0 +1,208 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// CRC - cyclic redundancy check code. +public final class Checksum { + + @usableFromInline + static let table32: Array = [ + 0x0000_0000, 0x7707_3096, 0xEE0E_612C, 0x9909_51BA, 0x076D_C419, 0x706A_F48F, 0xE963_A535, 0x9E64_95A3, + 0x0EDB_8832, 0x79DC_B8A4, 0xE0D5_E91E, 0x97D2_D988, 0x09B6_4C2B, 0x7EB1_7CBD, 0xE7B8_2D07, 0x90BF_1D91, + 0x1DB7_1064, 0x6AB0_20F2, 0xF3B9_7148, 0x84BE_41DE, 0x1ADA_D47D, 0x6DDD_E4EB, 0xF4D4_B551, 0x83D3_85C7, + 0x136C_9856, 0x646B_A8C0, 0xFD62_F97A, 0x8A65_C9EC, 0x1401_5C4F, 0x6306_6CD9, 0xFA0F_3D63, 0x8D08_0DF5, + 0x3B6E_20C8, 0x4C69_105E, 0xD560_41E4, 0xA267_7172, 0x3C03_E4D1, 0x4B04_D447, 0xD20D_85FD, 0xA50A_B56B, + 0x35B5_A8FA, 0x42B2_986C, 0xDBBB_C9D6, 0xACBC_F940, 0x32D8_6CE3, 0x45DF_5C75, 0xDCD6_0DCF, 0xABD1_3D59, + 0x26D9_30AC, 0x51DE_003A, 0xC8D7_5180, 0xBFD0_6116, 0x21B4_F4B5, 0x56B3_C423, 0xCFBA_9599, 0xB8BD_A50F, + 0x2802_B89E, 0x5F05_8808, 0xC60C_D9B2, 0xB10B_E924, 0x2F6F_7C87, 0x5868_4C11, 0xC161_1DAB, 0xB666_2D3D, + 0x76DC_4190, 0x01DB_7106, 0x98D2_20BC, 0xEFD5_102A, 0x71B1_8589, 0x06B6_B51F, 0x9FBF_E4A5, 0xE8B8_D433, + 0x7807_C9A2, 0x0F00_F934, 0x9609_A88E, 0xE10E_9818, 0x7F6A_0DBB, 0x086D_3D2D, 0x9164_6C97, 0xE663_5C01, + 0x6B6B_51F4, 0x1C6C_6162, 0x8565_30D8, 0xF262_004E, 0x6C06_95ED, 0x1B01_A57B, 0x8208_F4C1, 0xF50F_C457, + 0x65B0_D9C6, 0x12B7_E950, 0x8BBE_B8EA, 0xFCB9_887C, 0x62DD_1DDF, 0x15DA_2D49, 0x8CD3_7CF3, 0xFBD4_4C65, + 0x4DB2_6158, 0x3AB5_51CE, 0xA3BC_0074, 0xD4BB_30E2, 0x4ADF_A541, 0x3DD8_95D7, 0xA4D1_C46D, 0xD3D6_F4FB, + 0x4369_E96A, 0x346E_D9FC, 0xAD67_8846, 0xDA60_B8D0, 0x4404_2D73, 0x3303_1DE5, 0xAA0A_4C5F, 0xDD0D_7CC9, + 0x5005_713C, 0x2702_41AA, 0xBE0B_1010, 0xC90C_2086, 0x5768_B525, 0x206F_85B3, 0xB966_D409, 0xCE61_E49F, + 0x5EDE_F90E, 0x29D9_C998, 0xB0D0_9822, 0xC7D7_A8B4, 0x59B3_3D17, 0x2EB4_0D81, 0xB7BD_5C3B, 0xC0BA_6CAD, + 0xEDB8_8320, 0x9ABF_B3B6, 0x03B6_E20C, 0x74B1_D29A, 0xEAD5_4739, 0x9DD2_77AF, 0x04DB_2615, 0x73DC_1683, + 0xE363_0B12, 0x9464_3B84, 0x0D6D_6A3E, 0x7A6A_5AA8, 0xE40E_CF0B, 0x9309_FF9D, 0x0A00_AE27, 0x7D07_9EB1, + 0xF00F_9344, 0x8708_A3D2, 0x1E01_F268, 0x6906_C2FE, 0xF762_575D, 0x8065_67CB, 0x196C_3671, 0x6E6B_06E7, + 0xFED4_1B76, 0x89D3_2BE0, 0x10DA_7A5A, 0x67DD_4ACC, 0xF9B9_DF6F, 0x8EBE_EFF9, 0x17B7_BE43, 0x60B0_8ED5, + 0xD6D6_A3E8, 0xA1D1_937E, 0x38D8_C2C4, 0x4FDF_F252, 0xD1BB_67F1, 0xA6BC_5767, 0x3FB5_06DD, 0x48B2_364B, + 0xD80D_2BDA, 0xAF0A_1B4C, 0x3603_4AF6, 0x4104_7A60, 0xDF60_EFC3, 0xA867_DF55, 0x316E_8EEF, 0x4669_BE79, + 0xCB61_B38C, 0xBC66_831A, 0x256F_D2A0, 0x5268_E236, 0xCC0C_7795, 0xBB0B_4703, 0x2202_16B9, 0x5505_262F, + 0xC5BA_3BBE, 0xB2BD_0B28, 0x2BB4_5A92, 0x5CB3_6A04, 0xC2D7_FFA7, 0xB5D0_CF31, 0x2CD9_9E8B, 0x5BDE_AE1D, + 0x9B64_C2B0, 0xEC63_F226, 0x756A_A39C, 0x026D_930A, 0x9C09_06A9, 0xEB0E_363F, 0x7207_6785, 0x0500_5713, + 0x95BF_4A82, 0xE2B8_7A14, 0x7BB1_2BAE, 0x0CB6_1B38, 0x92D2_8E9B, 0xE5D5_BE0D, 0x7CDC_EFB7, 0x0BDB_DF21, + 0x86D3_D2D4, 0xF1D4_E242, 0x68DD_B3F8, 0x1FDA_836E, 0x81BE_16CD, 0xF6B9_265B, 0x6FB0_77E1, 0x18B7_4777, + 0x8808_5AE6, 0xFF0F_6A70, 0x6606_3BCA, 0x1101_0B5C, 0x8F65_9EFF, 0xF862_AE69, 0x616B_FFD3, 0x166C_CF45, + 0xA00A_E278, 0xD70D_D2EE, 0x4E04_8354, 0x3903_B3C2, 0xA767_2661, 0xD060_16F7, 0x4969_474D, 0x3E6E_77DB, + 0xAED1_6A4A, 0xD9D6_5ADC, 0x40DF_0B66, 0x37D8_3BF0, 0xA9BC_AE53, 0xDEBB_9EC5, 0x47B2_CF7F, 0x30B5_FFE9, + 0xBDBD_F21C, 0xCABA_C28A, 0x53B3_9330, 0x24B4_A3A6, 0xBAD0_3605, 0xCDD7_0693, 0x54DE_5729, 0x23D9_67BF, + 0xB366_7A2E, 0xC461_4AB8, 0x5D68_1B02, 0x2A6F_2B94, 0xB40B_BE37, 0xC30C_8EA1, 0x5A05_DF1B, 0x2D02_EF8D + ] + + @usableFromInline + static let table32c: Array = [ + 0x0000_0000, 0xF26B_8303, 0xE13B_70F7, 0x1350_F3F4, 0xC79A_971F, 0x35F1_141C, 0x26A1_E7E8, 0xD4CA_64EB, + 0x8AD9_58CF, 0x78B2_DBCC, 0x6BE2_2838, 0x9989_AB3B, 0x4D43_CFD0, 0xBF28_4CD3, 0xAC78_BF27, 0x5E13_3C24, + 0x105E_C76F, 0xE235_446C, 0xF165_B798, 0x030E_349B, 0xD7C4_5070, 0x25AF_D373, 0x36FF_2087, 0xC494_A384, + 0x9A87_9FA0, 0x68EC_1CA3, 0x7BBC_EF57, 0x89D7_6C54, 0x5D1D_08BF, 0xAF76_8BBC, 0xBC26_7848, 0x4E4D_FB4B, + 0x20BD_8EDE, 0xD2D6_0DDD, 0xC186_FE29, 0x33ED_7D2A, 0xE727_19C1, 0x154C_9AC2, 0x061C_6936, 0xF477_EA35, + 0xAA64_D611, 0x580F_5512, 0x4B5F_A6E6, 0xB934_25E5, 0x6DFE_410E, 0x9F95_C20D, 0x8CC5_31F9, 0x7EAE_B2FA, + 0x30E3_49B1, 0xC288_CAB2, 0xD1D8_3946, 0x23B3_BA45, 0xF779_DEAE, 0x0512_5DAD, 0x1642_AE59, 0xE429_2D5A, + 0xBA3A_117E, 0x4851_927D, 0x5B01_6189, 0xA96A_E28A, 0x7DA0_8661, 0x8FCB_0562, 0x9C9B_F696, 0x6EF0_7595, + 0x417B_1DBC, 0xB310_9EBF, 0xA040_6D4B, 0x522B_EE48, 0x86E1_8AA3, 0x748A_09A0, 0x67DA_FA54, 0x95B1_7957, + 0xCBA2_4573, 0x39C9_C670, 0x2A99_3584, 0xD8F2_B687, 0x0C38_D26C, 0xFE53_516F, 0xED03_A29B, 0x1F68_2198, + 0x5125_DAD3, 0xA34E_59D0, 0xB01E_AA24, 0x4275_2927, 0x96BF_4DCC, 0x64D4_CECF, 0x7784_3D3B, 0x85EF_BE38, + 0xDBFC_821C, 0x2997_011F, 0x3AC7_F2EB, 0xC8AC_71E8, 0x1C66_1503, 0xEE0D_9600, 0xFD5D_65F4, 0x0F36_E6F7, + 0x61C6_9362, 0x93AD_1061, 0x80FD_E395, 0x7296_6096, 0xA65C_047D, 0x5437_877E, 0x4767_748A, 0xB50C_F789, + 0xEB1F_CBAD, 0x1974_48AE, 0x0A24_BB5A, 0xF84F_3859, 0x2C85_5CB2, 0xDEEE_DFB1, 0xCDBE_2C45, 0x3FD5_AF46, + 0x7198_540D, 0x83F3_D70E, 0x90A3_24FA, 0x62C8_A7F9, 0xB602_C312, 0x4469_4011, 0x5739_B3E5, 0xA552_30E6, + 0xFB41_0CC2, 0x092A_8FC1, 0x1A7A_7C35, 0xE811_FF36, 0x3CDB_9BDD, 0xCEB0_18DE, 0xDDE0_EB2A, 0x2F8B_6829, + 0x82F6_3B78, 0x709D_B87B, 0x63CD_4B8F, 0x91A6_C88C, 0x456C_AC67, 0xB707_2F64, 0xA457_DC90, 0x563C_5F93, + 0x082F_63B7, 0xFA44_E0B4, 0xE914_1340, 0x1B7F_9043, 0xCFB5_F4A8, 0x3DDE_77AB, 0x2E8E_845F, 0xDCE5_075C, + 0x92A8_FC17, 0x60C3_7F14, 0x7393_8CE0, 0x81F8_0FE3, 0x5532_6B08, 0xA759_E80B, 0xB409_1BFF, 0x4662_98FC, + 0x1871_A4D8, 0xEA1A_27DB, 0xF94A_D42F, 0x0B21_572C, 0xDFEB_33C7, 0x2D80_B0C4, 0x3ED0_4330, 0xCCBB_C033, + 0xA24B_B5A6, 0x5020_36A5, 0x4370_C551, 0xB11B_4652, 0x65D1_22B9, 0x97BA_A1BA, 0x84EA_524E, 0x7681_D14D, + 0x2892_ED69, 0xDAF9_6E6A, 0xC9A9_9D9E, 0x3BC2_1E9D, 0xEF08_7A76, 0x1D63_F975, 0x0E33_0A81, 0xFC58_8982, + 0xB215_72C9, 0x407E_F1CA, 0x532E_023E, 0xA145_813D, 0x758F_E5D6, 0x87E4_66D5, 0x94B4_9521, 0x66DF_1622, + 0x38CC_2A06, 0xCAA7_A905, 0xD9F7_5AF1, 0x2B9C_D9F2, 0xFF56_BD19, 0x0D3D_3E1A, 0x1E6D_CDEE, 0xEC06_4EED, + 0xC38D_26C4, 0x31E6_A5C7, 0x22B6_5633, 0xD0DD_D530, 0x0417_B1DB, 0xF67C_32D8, 0xE52C_C12C, 0x1747_422F, + 0x4954_7E0B, 0xBB3F_FD08, 0xA86F_0EFC, 0x5A04_8DFF, 0x8ECE_E914, 0x7CA5_6A17, 0x6FF5_99E3, 0x9D9E_1AE0, + 0xD3D3_E1AB, 0x21B8_62A8, 0x32E8_915C, 0xC083_125F, 0x1449_76B4, 0xE622_F5B7, 0xF572_0643, 0x0719_8540, + 0x590A_B964, 0xAB61_3A67, 0xB831_C993, 0x4A5A_4A90, 0x9E90_2E7B, 0x6CFB_AD78, 0x7FAB_5E8C, 0x8DC0_DD8F, + 0xE330_A81A, 0x115B_2B19, 0x020B_D8ED, 0xF060_5BEE, 0x24AA_3F05, 0xD6C1_BC06, 0xC591_4FF2, 0x37FA_CCF1, + 0x69E9_F0D5, 0x9B82_73D6, 0x88D2_8022, 0x7AB9_0321, 0xAE73_67CA, 0x5C18_E4C9, 0x4F48_173D, 0xBD23_943E, + 0xF36E_6F75, 0x0105_EC76, 0x1255_1F82, 0xE03E_9C81, 0x34F4_F86A, 0xC69F_7B69, 0xD5CF_889D, 0x27A4_0B9E, + 0x79B7_37BA, 0x8BDC_B4B9, 0x988C_474D, 0x6AE7_C44E, 0xBE2D_A0A5, 0x4C46_23A6, 0x5F16_D052, 0xAD7D_5351 + ] + + @usableFromInline + static let table16: Array = [ + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 + ] + + @usableFromInline + init() { + // + } + + /// Polynomial: 0xEDB88320 (Reversed) - IEEE + @inlinable + func crc32(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + var crc: UInt32 = seed != nil ? seed! : 0xFFFF_FFFF + for chunk in message.batched(by: 256) { + for b in chunk { + let idx = Int((crc ^ UInt32(reflect ? b : reversed(b))) & 0xFF) + crc = (crc >> 8) ^ Checksum.table32[idx] + } + } + return (reflect ? crc : reversed(crc)) ^ 0xFFFF_FFFF + } + + /// Polynomial: 0x82F63B78 (Reversed) - Castagnoli + @inlinable + func crc32c(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + var crc: UInt32 = seed != nil ? seed! : 0xFFFF_FFFF + for chunk in message.batched(by: 256) { + for b in chunk { + let idx = Int((crc ^ UInt32(reflect ? b : reversed(b))) & 0xFF) + crc = (crc >> 8) ^ Checksum.table32c[idx] + } + } + return (reflect ? crc : reversed(crc)) ^ 0xFFFF_FFFF + } + + /// Polynomial: 0xA001 (Reversed) - IBM + @inlinable + func crc16(_ message: Array, seed: UInt16? = nil) -> UInt16 { + var crc: UInt16 = seed != nil ? seed! : 0x0000 + for chunk in message.batched(by: 256) { + for b in chunk { + crc = (crc >> 8) ^ Checksum.table16[Int((crc ^ UInt16(b)) & 0xFF)] + } + } + return crc + } +} + +// MARK: Public interface + +public extension Checksum { + /// Calculate CRC32. + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// - parameter reflect: is reflect (default true) + /// + /// - returns: Calculated code + @inlinable + static func crc32(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + Checksum().crc32(message, seed: seed, reflect: reflect) + } + + /// Calculate CRC32C + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// - parameter reflect: is reflect (default true) + /// + /// - returns: Calculated code + @inlinable + static func crc32c(_ message: Array, seed: UInt32? = nil, reflect: Bool = true) -> UInt32 { + Checksum().crc32c(message, seed: seed, reflect: reflect) + } + + /// Calculate CRC16 + /// + /// - parameter message: Message + /// - parameter seed: Seed value (Optional) + /// + /// - returns: Calculated code + @inlinable + static func crc16(_ message: Array, seed: UInt16? = nil) -> UInt16 { + Checksum().crc16(message, seed: seed) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cipher.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cipher.swift new file mode 100644 index 00000000..d7e669ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cipher.swift @@ -0,0 +1,47 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public enum CipherError: Error { + case encrypt + case decrypt +} + +public protocol Cipher: AnyObject { + var keySize: Int { get } + + /// Encrypt given bytes at once + /// + /// - parameter bytes: Plaintext data + /// - returns: Encrypted data + func encrypt(_ bytes: ArraySlice) throws -> Array + func encrypt(_ bytes: Array) throws -> Array + + /// Decrypt given bytes at once + /// + /// - parameter bytes: Ciphertext data + /// - returns: Plaintext data + func decrypt(_ bytes: ArraySlice) throws -> Array + func decrypt(_ bytes: Array) throws -> Array +} + +extension Cipher { + public func encrypt(_ bytes: Array) throws -> Array { + try self.encrypt(bytes.slice) + } + + public func decrypt(_ bytes: Array) throws -> Array { + try self.decrypt(bytes.slice) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift new file mode 100644 index 00000000..a1b7d92d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Collection+Extension.swift @@ -0,0 +1,61 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// +extension Collection where Self.Element == UInt8, Self.Index == Int { + // Big endian order + @inlinable + func toUInt32Array() -> Array { + guard !isEmpty else { + return [] + } + + let c = strideCount(from: startIndex, to: endIndex, by: 4) + return Array(unsafeUninitializedCapacity: c) { buf, count in + var counter = 0 + for idx in stride(from: startIndex, to: endIndex, by: 4) { + let val = UInt32(bytes: self, fromIndex: idx).bigEndian + buf[counter] = val + counter += 1 + } + count = counter + assert(counter == c) + } + } + + // Big endian order + @inlinable + func toUInt64Array() -> Array { + guard !isEmpty else { + return [] + } + + let c = strideCount(from: startIndex, to: endIndex, by: 8) + return Array(unsafeUninitializedCapacity: c) { buf, count in + var counter = 0 + for idx in stride(from: startIndex, to: endIndex, by: 8) { + let val = UInt64(bytes: self, fromIndex: idx).bigEndian + buf[counter] = val + counter += 1 + } + count = counter + assert(counter == c) + } + } +} + +@usableFromInline +func strideCount(from: Int, to: Int, by: Int) -> Int { + let count = to - from + return count / by + (count % by > 0 ? 1 : 0) +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CompactMap.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CompactMap.swift new file mode 100644 index 00000000..34a1a439 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/CompactMap.swift @@ -0,0 +1,25 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if swift(>=4.1) +// TODO: remove this file when Xcode 9.2 is no longer used +#else + extension Sequence { + @inlinable + public func compactMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { + try flatMap(transform) + } + } +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptor.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptor.swift new file mode 100644 index 00000000..25fd135c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptor.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// Cryptor (Encryptor or Decryptor) +public protocol Cryptor { + /// Seek to position in file, if block mode allows random access. + /// + /// - parameter to: new value of counter + mutating func seek(to: Int) throws +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptors.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptors.swift new file mode 100644 index 00000000..2c22dde9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Cryptors.swift @@ -0,0 +1,44 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +/// Worker cryptor/decryptor of `Updatable` types +public protocol Cryptors: AnyObject { + + /// Cryptor suitable for encryption + func makeEncryptor() throws -> Cryptor & Updatable + + /// Cryptor suitable for decryption + func makeDecryptor() throws -> Cryptor & Updatable + + /// Generate array of random bytes. Helper function. + static func randomIV(_ blockSize: Int) -> Array +} + +extension Cryptors { + /// Generate array of random values. + /// Convenience helper that uses `Swift.RandomNumberGenerator`. + /// - Parameter count: Length of array + public static func randomIV(_ count: Int) -> Array { + (0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@available(*, renamed: "Digest") +public typealias Hash = Digest + +/// Hash functions to calculate Digest. +public struct Digest { + /// Calculate MD5 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func md5(_ bytes: Array) -> Array { + MD5().calculate(for: bytes) + } + + /// Calculate SHA1 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha1(_ bytes: Array) -> Array { + SHA1().calculate(for: bytes) + } + + /// Calculate SHA2-224 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha224(_ bytes: Array) -> Array { + self.sha2(bytes, variant: .sha224) + } + + /// Calculate SHA2-256 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha256(_ bytes: Array) -> Array { + self.sha2(bytes, variant: .sha256) + } + + /// Calculate SHA2-384 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha384(_ bytes: Array) -> Array { + self.sha2(bytes, variant: .sha384) + } + + /// Calculate SHA2-512 Digest + /// - parameter bytes: input message + /// - returns: Digest bytes + public static func sha512(_ bytes: Array) -> Array { + self.sha2(bytes, variant: .sha512) + } + + /// Calculate SHA2 Digest + /// - parameter bytes: input message + /// - parameter variant: SHA-2 variant + /// - returns: Digest bytes + public static func sha2(_ bytes: Array, variant: SHA2.Variant) -> Array { + SHA2(variant: variant).calculate(for: bytes) + } + + /// Calculate SHA3 Digest + /// - parameter bytes: input message + /// - parameter variant: SHA-3 variant + /// - returns: Digest bytes + public static func sha3(_ bytes: Array, variant: SHA3.Variant) -> Array { + SHA3(variant: variant).calculate(for: bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/DigestType.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/DigestType.swift new file mode 100644 index 00000000..c99f081f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/DigestType.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +internal protocol DigestType { + func calculate(for bytes: Array) -> Array +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift new file mode 100644 index 00000000..3c6055c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/AES+Foundation.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension AES { + /// Initialize with CBC block mode. + /// + /// - Parameters: + /// - key: Key as a String. + /// - iv: IV as a String. + /// - padding: Padding + /// - Throws: Error + /// + /// The input is a String, that is treat as sequence of bytes made directly out of String. + /// If input is Base64 encoded data (which is a String technically) it is not decoded automatically for you. + public convenience init(key: String, iv: String, padding: Padding = .pkcs7) throws { + try self.init(key: key.bytes, blockMode: CBC(iv: iv.bytes), padding: padding) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift new file mode 100644 index 00000000..64f7f116 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Array+Foundation.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +public extension Array where Element == UInt8 { + func toBase64() -> String { + Data(self).base64EncodedString() + } + + init(base64: String) { + self.init() + + guard let decodedData = Data(base64Encoded: base64) else { + return + } + + append(contentsOf: decodedData.bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift new file mode 100644 index 00000000..57c1eea7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift @@ -0,0 +1,23 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension Blowfish { + /// Initialize with CBC block mode. + public convenience init(key: String, iv: String, padding: Padding = .pkcs7) throws { + try self.init(key: key.bytes, blockMode: CBC(iv: iv.bytes), padding: padding) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift new file mode 100644 index 00000000..347f4588 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension ChaCha20 { + public convenience init(key: String, iv: String) throws { + try self.init(key: key.bytes, iv: iv.bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift new file mode 100644 index 00000000..3a9e2c95 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Data+Extension.swift @@ -0,0 +1,92 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension Data { + /// Two octet checksum as defined in RFC-4880. Sum of all octets, mod 65536 + public func checksum() -> UInt16 { + let s = self.withUnsafeBytes { buf in + return buf.lazy.map(UInt32.init).reduce(UInt32(0), +) + } + return UInt16(s % 65535) + } + + public func md5() -> Data { + Data( Digest.md5(bytes)) + } + + public func sha1() -> Data { + Data( Digest.sha1(bytes)) + } + + public func sha224() -> Data { + Data( Digest.sha224(bytes)) + } + + public func sha256() -> Data { + Data( Digest.sha256(bytes)) + } + + public func sha384() -> Data { + Data( Digest.sha384(bytes)) + } + + public func sha512() -> Data { + Data( Digest.sha512(bytes)) + } + + public func sha3(_ variant: SHA3.Variant) -> Data { + Data( Digest.sha3(bytes, variant: variant)) + } + + public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> Data { + Data( Checksum.crc32(bytes, seed: seed, reflect: reflect).bytes()) + } + + public func crc32c(seed: UInt32? = nil, reflect: Bool = true) -> Data { + Data( Checksum.crc32c(bytes, seed: seed, reflect: reflect).bytes()) + } + + public func crc16(seed: UInt16? = nil) -> Data { + Data( Checksum.crc16(bytes, seed: seed).bytes()) + } + + public func encrypt(cipher: Cipher) throws -> Data { + Data( try cipher.encrypt(bytes.slice)) + } + + public func decrypt(cipher: Cipher) throws -> Data { + Data( try cipher.decrypt(bytes.slice)) + } + + public func authenticate(with authenticator: Authenticator) throws -> Data { + Data( try authenticator.authenticate(bytes)) + } +} + +extension Data { + public init(hex: String) { + self.init(Array(hex: hex)) + } + + public var bytes: Array { + Array(self) + } + + public func toHexString() -> String { + self.bytes.toHexString() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift new file mode 100644 index 00000000..99b7b627 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/HMAC+Foundation.swift @@ -0,0 +1,22 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension HMAC { + public convenience init(key: String, variant: HMAC.Variant = .md5) throws { + self.init(key: key.bytes, variant: variant) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift new file mode 100644 index 00000000..d3543b2f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift @@ -0,0 +1,26 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension Rabbit { + public convenience init(key: String) throws { + try self.init(key: key.bytes) + } + + public convenience init(key: String, iv: String) throws { + try self.init(key: key.bytes, iv: iv.bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift new file mode 100644 index 00000000..89a84649 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/String+FoundationExtension.swift @@ -0,0 +1,41 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +extension String { + /// Return Base64 back to String + public func decryptBase64ToString(cipher: Cipher) throws -> String { + guard let decodedData = Data(base64Encoded: self, options: []) else { + throw CipherError.decrypt + } + + let decrypted = try decodedData.decrypt(cipher: cipher) + + if let decryptedString = String(data: decrypted, encoding: String.Encoding.utf8) { + return decryptedString + } + + throw CipherError.decrypt + } + + public func decryptBase64(cipher: Cipher) throws -> Array { + guard let decodedData = Data(base64Encoded: self, options: []) else { + throw CipherError.decrypt + } + + return try decodedData.decrypt(cipher: cipher).bytes + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift new file mode 100644 index 00000000..f146cf76 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Foundation/Utils+Foundation.swift @@ -0,0 +1,27 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +func perf(_ text: String, closure: () -> Void) { + let measurementStart = Date() + + closure() + + let measurementStop = Date() + let executionTime = measurementStop.timeIntervalSince(measurementStart) + + print("\(text) \(executionTime)") +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Generics.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Generics.swift new file mode 100644 index 00000000..dfd90bbe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Generics.swift @@ -0,0 +1,43 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// Array of bytes. Caution: don't use directly because generic is slow. +/// +/// - parameter value: integer value +/// - parameter length: length of output array. By default size of value type +/// +/// - returns: Array of bytes +@_specialize(where T == Int) +@_specialize(where T == UInt) +@_specialize(where T == UInt8) +@_specialize(where T == UInt16) +@_specialize(where T == UInt32) +@_specialize(where T == UInt64) +@inlinable +func arrayOfBytes(value: T, length totalBytes: Int = MemoryLayout.size) -> Array { + let valuePointer = UnsafeMutablePointer.allocate(capacity: 1) + valuePointer.pointee = value + + let bytesPointer = UnsafeMutablePointer(OpaquePointer(valuePointer)) + var bytes = Array(repeating: 0, count: totalBytes) + for j in 0...size, totalBytes) { + bytes[totalBytes - 1 - j] = (bytesPointer + j).pointee + } + + valuePointer.deinitialize(count: 1) + valuePointer.deallocate() + + return bytes +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HKDF.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HKDF.swift new file mode 100644 index 00000000..5f48c0a6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HKDF.swift @@ -0,0 +1,86 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// https://www.ietf.org/rfc/rfc5869.txt +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +/// A key derivation function. +/// +/// HKDF - HMAC-based Extract-and-Expand Key Derivation Function. +public struct HKDF { + public enum Error: Swift.Error { + case invalidInput + case derivedKeyTooLong + } + + private let numBlocks: Int // l + private let dkLen: Int + private let info: Array + private let prk: Array + private let variant: HMAC.Variant + + /// - parameters: + /// - variant: hash variant + /// - salt: optional salt (if not provided, it is set to a sequence of variant.digestLength zeros) + /// - info: optional context and application specific information + /// - keyLength: intended length of derived key + public init(password: Array, salt: Array? = nil, info: Array? = nil, keyLength: Int? = nil /* dkLen */, variant: HMAC.Variant = .sha2(.sha256)) throws { + guard !password.isEmpty else { + throw Error.invalidInput + } + + let dkLen = keyLength ?? variant.digestLength + let keyLengthFinal = Double(dkLen) + let hLen = Double(variant.digestLength) + let numBlocks = Int(ceil(keyLengthFinal / hLen)) // l = ceil(keyLength / hLen) + guard numBlocks <= 255 else { + throw Error.derivedKeyTooLong + } + + /// HKDF-Extract(salt, password) -> PRK + /// - PRK - a pseudo-random key; it is used by calculate() + self.prk = try HMAC(key: salt ?? [], variant: variant).authenticate(password) + self.info = info ?? [] + self.variant = variant + self.dkLen = dkLen + self.numBlocks = numBlocks + } + + public func calculate() throws -> Array { + let hmac = HMAC(key: prk, variant: variant) + var ret = Array() + ret.reserveCapacity(self.numBlocks * self.variant.digestLength) + var value = Array() + for i in 1...self.numBlocks { + value.append(contentsOf: self.info) + value.append(UInt8(i)) + + let bytes = try hmac.authenticate(value) + ret.append(contentsOf: bytes) + + /// update value to use it as input for next iteration + value = bytes + } + return Array(ret.prefix(self.dkLen)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HMAC.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HMAC.swift new file mode 100644 index 00000000..d8641313 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/HMAC.swift @@ -0,0 +1,124 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public final class HMAC: Authenticator { + public enum Error: Swift.Error { + case authenticateError + case invalidInput + } + + public enum Variant { + case md5 + case sha1 + case sha2(SHA2.Variant) + case sha3(SHA3.Variant) + + @available(*, deprecated, message: "Use sha2(variant) instead.") + case sha256, sha384, sha512 + + var digestLength: Int { + switch self { + case .sha1: + return SHA1.digestLength + case .sha256: + return SHA2.Variant.sha256.digestLength + case .sha384: + return SHA2.Variant.sha384.digestLength + case .sha512: + return SHA2.Variant.sha512.digestLength + case .sha2(let variant): + return variant.digestLength + case .sha3(let variant): + return variant.digestLength + case .md5: + return MD5.digestLength + } + } + + func calculateHash(_ bytes: Array) -> Array { + switch self { + case .sha1: + return Digest.sha1(bytes) + case .sha256: + return Digest.sha256(bytes) + case .sha384: + return Digest.sha384(bytes) + case .sha512: + return Digest.sha512(bytes) + case .sha2(let variant): + return Digest.sha2(bytes, variant: variant) + case .sha3(let variant): + return Digest.sha3(bytes, variant: variant) + case .md5: + return Digest.md5(bytes) + } + } + + func blockSize() -> Int { + switch self { + case .md5: + return MD5.blockSize + case .sha1: + return SHA1.blockSize + case .sha256: + return SHA2.Variant.sha256.blockSize + case .sha384: + return SHA2.Variant.sha384.blockSize + case .sha512: + return SHA2.Variant.sha512.blockSize + case .sha2(let variant): + return variant.blockSize + case .sha3(let variant): + return variant.blockSize + } + } + } + + var key: Array + let variant: Variant + + public init(key: Array, variant: HMAC.Variant = .md5) { + self.variant = variant + self.key = key + + if key.count > variant.blockSize() { + let hash = variant.calculateHash(key) + self.key = hash + } + + if key.count < variant.blockSize() { + self.key = ZeroPadding().add(to: key, blockSize: variant.blockSize()) + } + } + + // MARK: Authenticator + + public func authenticate(_ bytes: Array) throws -> Array { + var opad = Array(repeating: 0x5c, count: variant.blockSize()) + for idx in self.key.indices { + opad[idx] = self.key[idx] ^ opad[idx] + } + var ipad = Array(repeating: 0x36, count: variant.blockSize()) + for idx in self.key.indices { + ipad[idx] = self.key[idx] ^ ipad[idx] + } + + let ipadAndMessageHash = self.variant.calculateHash(ipad + bytes) + let result = self.variant.calculateHash(opad + ipadAndMessageHash) + + // return Array(result[0..<10]) // 80 bits + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ISO10126Padding.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ISO10126Padding.swift new file mode 100644 index 00000000..8aebd114 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ISO10126Padding.swift @@ -0,0 +1,56 @@ +// +// CryptoSwift +// +// Copyright (C) Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +/// Padding with random bytes, ending with the number of added bytes. +/// Read the [Wikipedia](https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO_10126) +/// and [Crypto-IT](http://www.crypto-it.net/eng/theory/padding.html) articles for more info. +struct ISO10126Padding: PaddingProtocol { + init() { + } + + @inlinable + func add(to bytes: Array, blockSize: Int) -> Array { + let padding = UInt8(blockSize - (bytes.count % blockSize)) + var withPadding = bytes + if padding > 0 { + withPadding += (0..<(padding - 1)).map { _ in UInt8.random(in: 0...255) } + [padding] + } + return withPadding + } + + @inlinable + func remove(from bytes: Array, blockSize: Int?) -> Array { + guard !bytes.isEmpty, let lastByte = bytes.last else { + return bytes + } + + assert(!bytes.isEmpty, "Need bytes to remove padding") + + let padding = Int(lastByte) // last byte + let finalLength = bytes.count - padding + + if finalLength < 0 { + return bytes + } + + if padding >= 1 { + return Array(bytes[0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +// First byte is 0x80, rest is zero padding +// http://www.crypto-it.net/eng/theory/padding.html +// http://www.embedx.com/pdfs/ISO_STD_7816/info_isoiec7816-4%7Bed21.0%7Den.pdf +struct ISO78164Padding: PaddingProtocol { + init() { + } + + @inlinable + func add(to bytes: Array, blockSize: Int) -> Array { + var padded = Array(bytes) + padded.append(0x80) + + while (padded.count % blockSize) != 0 { + padded.append(0x00) + } + return padded + } + + @inlinable + func remove(from bytes: Array, blockSize _: Int?) -> Array { + if let idx = bytes.lastIndex(of: 0x80) { + return Array(bytes[.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +extension FixedWidthInteger { + @inlinable + func bytes(totalBytes: Int = MemoryLayout.size) -> Array { + arrayOfBytes(value: self.littleEndian, length: totalBytes) + // TODO: adjust bytes order + // var value = self.littleEndian + // return withUnsafeBytes(of: &value, Array.init).reversed() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/MD5.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/MD5.swift new file mode 100644 index 00000000..bd7925f1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/MD5.swift @@ -0,0 +1,161 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public final class MD5: DigestType { + static let blockSize: Int = 64 + static let digestLength: Int = 16 // 128 / 8 + fileprivate static let hashInitialValue: Array = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476] + + fileprivate var accumulated = Array() + fileprivate var processedBytesTotalCount: Int = 0 + fileprivate var accumulatedHash: Array = MD5.hashInitialValue + + /** specifies the per-round shift amounts */ + private let s: Array = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + ] + + /** binary integer part of the sines of integers (Radians) */ + private let k: Array = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + ] + + public init() { + } + + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + fatalError() + } + } + + // mutating currentHash in place is way faster than returning new result + fileprivate func process(block chunk: ArraySlice, currentHash: inout Array) { + assert(chunk.count == 16 * 4) + + // Initialize hash value for this chunk: + var A: UInt32 = currentHash[0] + var B: UInt32 = currentHash[1] + var C: UInt32 = currentHash[2] + var D: UInt32 = currentHash[3] + + var dTemp: UInt32 = 0 + + // Main loop + for j in 0.., isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + self.accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: 64 / 8) // A 64-bit representation of b + + // Step 1. Append padding + bitPadding(to: &self.accumulated, blockSize: MD5.blockSize, allowance: 64 / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + self.accumulated += lengthBytes.reversed() + } + + var processedBytes = 0 + for chunk in self.accumulated.batched(by: MD5.blockSize) { + if isLast || (self.accumulated.count - processedBytes) >= MD5.blockSize { + self.process(block: chunk, currentHash: &self.accumulatedHash) + processedBytes += chunk.count + } + } + self.accumulated.removeFirst(processedBytes) + self.processedBytesTotalCount += processedBytes + + // output current hash + var result = Array() + result.reserveCapacity(MD5.digestLength) + + for hElement in self.accumulatedHash { + let hLE = hElement.littleEndian + result += Array(arrayLiteral: UInt8(hLE & 0xff), UInt8((hLE >> 8) & 0xff), UInt8((hLE >> 16) & 0xff), UInt8((hLE >> 24) & 0xff)) + } + + // reset hash value for instance + if isLast { + self.accumulatedHash = MD5.hashInitialValue + } + + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/NoPadding.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/NoPadding.swift new file mode 100644 index 00000000..9c75f6f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/NoPadding.swift @@ -0,0 +1,27 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +struct NoPadding: PaddingProtocol { + init() { + } + + func add(to data: Array, blockSize _: Int) -> Array { + data + } + + func remove(from data: Array, blockSize _: Int?) -> Array { + data + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Operators.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Operators.swift new file mode 100644 index 00000000..cee442d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Operators.swift @@ -0,0 +1,32 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/* + Bit shifting with overflow protection using overflow operator "&". + Approach is consistent with standard overflow operators &+, &-, &*, &/ + and introduce new overflow operators for shifting: &<<, &>> + + Note: Works with unsigned integers values only + + Usage + + var i = 1 // init + var j = i &<< 2 //shift left + j &<<= 2 //shift left and assign + + @see: https://medium.com/@krzyzanowskim/swiftly-shift-bits-and-protect-yourself-be33016ce071 + + This fuctonality is now implemented as part of Swift 3, SE-0104 https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md + */ diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift new file mode 100644 index 00000000..b7e8e70b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PBKDF1.swift @@ -0,0 +1,97 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public extension PKCS5 { + /// A key derivation function. + /// + /// PBKDF1 is recommended only for compatibility with existing + /// applications since the keys it produces may not be large enough for + /// some applications. + struct PBKDF1 { + public enum Error: Swift.Error { + case invalidInput + case derivedKeyTooLong + } + + public enum Variant { + case md5, sha1 + + @usableFromInline + var size: Int { + switch self { + case .md5: + return MD5.digestLength + case .sha1: + return SHA1.digestLength + } + } + + @usableFromInline + func calculateHash(_ bytes: Array) -> Array { + switch self { + case .sha1: + return Digest.sha1(bytes) + case .md5: + return Digest.md5(bytes) + } + } + } + + @usableFromInline + let iterations: Int // c + + @usableFromInline + let variant: Variant + + @usableFromInline + let keyLength: Int + + @usableFromInline + let t1: Array + + /// - parameters: + /// - salt: salt, an eight-bytes + /// - variant: hash variant + /// - iterations: iteration count, a positive integer + /// - keyLength: intended length of derived key + public init(password: Array, salt: Array, variant: Variant = .sha1, iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */ ) throws { + precondition(iterations > 0) + precondition(salt.count == 8) + + let keyLength = keyLength ?? variant.size + + if keyLength > variant.size { + throw Error.derivedKeyTooLong + } + + let t1 = variant.calculateHash(password + salt) + + self.iterations = iterations + self.variant = variant + self.keyLength = keyLength + self.t1 = t1 + } + + /// Apply the underlying hash function Hash for c iterations + @inlinable + public func calculate() -> Array { + var t = self.t1 + for _ in 2...self.iterations { + t = self.variant.calculateHash(t) + } + return Array(t[0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// https://www.ietf.org/rfc/rfc2898.txt +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +public extension PKCS5 { + /// A key derivation function. + /// + /// PBKDF2 - Password-Based Key Derivation Function 2. Key stretching technique. + /// DK = PBKDF2(PRF, Password, Salt, c, dkLen) + struct PBKDF2 { + public enum Error: Swift.Error { + case invalidInput + case derivedKeyTooLong + } + + private let salt: Array // S + fileprivate let iterations: Int // c + private let numBlocks: Int // l + private let dkLen: Int + fileprivate let prf: HMAC + + /// - parameters: + /// - salt: salt + /// - variant: hash variant + /// - iterations: iteration count, a positive integer + /// - keyLength: intended length of derived key + /// - variant: MAC variant. Defaults to SHA256 + public init(password: Array, salt: Array, iterations: Int = 4096 /* c */, keyLength: Int? = nil /* dkLen */, variant: HMAC.Variant = .sha2(.sha256)) throws { + precondition(iterations > 0) + + let prf = HMAC(key: password, variant: variant) + + guard iterations > 0 && !salt.isEmpty else { + throw Error.invalidInput + } + + self.dkLen = keyLength ?? variant.digestLength + let keyLengthFinal = Double(dkLen) + let hLen = Double(prf.variant.digestLength) + if keyLengthFinal > (pow(2, 32) - 1) * hLen { + throw Error.derivedKeyTooLong + } + + self.salt = salt + self.iterations = iterations + self.prf = prf + + self.numBlocks = Int(ceil(Double(keyLengthFinal) / hLen)) // l = ceil(keyLength / hLen) + } + + public func calculate() throws -> Array { + var ret = Array() + ret.reserveCapacity(self.numBlocks * self.prf.variant.digestLength) + for i in 1...self.numBlocks { + // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter + if let value = try calculateBlock(self.salt, blockNum: i) { + ret.append(contentsOf: value) + } + } + return Array(ret.prefix(self.dkLen)) + } + } +} + +private extension PKCS5.PBKDF2 { + func ARR(_ i: Int) -> Array { + var inti = Array(repeating: 0, count: 4) + inti[0] = UInt8((i >> 24) & 0xff) + inti[1] = UInt8((i >> 16) & 0xff) + inti[2] = UInt8((i >> 8) & 0xff) + inti[3] = UInt8(i & 0xff) + return inti + } + + // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c + // U_1 = PRF (P, S || INT (i)) + func calculateBlock(_ salt: Array, blockNum: Int) throws -> Array? { + guard let u1 = try? prf.authenticate(salt + ARR(blockNum)) else { // blockNum.bytes() is slower + return nil + } + + var u = u1 + var ret = u + if iterations > 1 { + // U_2 = PRF (P, U_1) , + // U_c = PRF (P, U_{c-1}) . + for _ in 2...iterations { + u = try prf.authenticate(u) + for x in 0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// PKCS is a group of public-key cryptography standards devised +// and published by RSA Security Inc, starting in the early 1990s. +// + +public enum PKCS5 { + typealias Padding = PKCS7Padding +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift new file mode 100644 index 00000000..2831c371 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7.swift @@ -0,0 +1,18 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public enum PKCS7 { + typealias Padding = PKCS7Padding +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift new file mode 100644 index 00000000..cb97917a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/PKCS/PKCS7Padding.swift @@ -0,0 +1,62 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// PKCS is a group of public-key cryptography standards devised +// and published by RSA Security Inc, starting in the early 1990s. +// + +struct PKCS7Padding: PaddingProtocol { + enum Error: Swift.Error { + case invalidPaddingValue + } + + init() { + } + + @inlinable + func add(to bytes: Array, blockSize: Int) -> Array { + let padding = UInt8(blockSize - (bytes.count % blockSize)) + var withPadding = bytes + if padding == 0 { + // If the original data is a multiple of N bytes, then an extra block of bytes with value N is added. + withPadding += Array(repeating: UInt8(blockSize), count: Int(blockSize)) + } else { + // The value of each added byte is the number of bytes that are added + withPadding += Array(repeating: padding, count: Int(padding)) + } + return withPadding + } + + @inlinable + func remove(from bytes: Array, blockSize _: Int?) -> Array { + guard !bytes.isEmpty, let lastByte = bytes.last else { + return bytes + } + + assert(!bytes.isEmpty, "Need bytes to remove padding") + + let padding = Int(lastByte) // last byte + let finalLength = bytes.count - padding + + if finalLength < 0 { + return bytes + } + + if padding >= 1 { + return Array(bytes[0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public protocol PaddingProtocol { + func add(to: Array, blockSize: Int) -> Array + func remove(from: Array, blockSize: Int?) -> Array +} + +public enum Padding: PaddingProtocol { + case noPadding, zeroPadding, pkcs7, pkcs5, iso78164, iso10126 + + public func add(to: Array, blockSize: Int) -> Array { + switch self { + case .noPadding: + return to // NoPadding().add(to: to, blockSize: blockSize) + case .zeroPadding: + return ZeroPadding().add(to: to, blockSize: blockSize) + case .pkcs7: + return PKCS7.Padding().add(to: to, blockSize: blockSize) + case .pkcs5: + return PKCS5.Padding().add(to: to, blockSize: blockSize) + case .iso78164: + return ISO78164Padding().add(to: to, blockSize: blockSize) + case .iso10126: + return ISO10126Padding().add(to: to, blockSize: blockSize) + } + } + + public func remove(from: Array, blockSize: Int?) -> Array { + switch self { + case .noPadding: + return from //NoPadding().remove(from: from, blockSize: blockSize) + case .zeroPadding: + return ZeroPadding().remove(from: from, blockSize: blockSize) + case .pkcs7: + return PKCS7.Padding().remove(from: from, blockSize: blockSize) + case .pkcs5: + return PKCS5.Padding().remove(from: from, blockSize: blockSize) + case .iso78164: + return ISO78164Padding().remove(from: from, blockSize: blockSize) + case .iso10126: + return ISO10126Padding().remove(from: from, blockSize: blockSize) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Poly1305.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Poly1305.swift new file mode 100644 index 00000000..3e8f7a3d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Poly1305.swift @@ -0,0 +1,165 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-4 +// nacl/crypto_onetimeauth/poly1305/ref/auth.c +// +/// Poly1305 takes a 32-byte, one-time key and a message and produces a 16-byte tag that authenticates the +/// message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message. + +public final class Poly1305: Authenticator { + public enum Error: Swift.Error { + case authenticateError + } + + public static let blockSize: Int = 16 + + private let key: SecureBytes + + /// - parameter key: 32-byte key + public init(key: Array) { + self.key = SecureBytes(bytes: key) + } + + private func squeeze(h: inout Array) { + assert(h.count == 17) + var u: UInt32 = 0 + for j in 0..<16 { + u = u &+ h[j] + h[j] = u & 255 + u = u >> 8 + } + + u = u &+ h[16] + h[16] = u & 3 + u = 5 * (u >> 2) + + for j in 0..<16 { + u = u &+ h[j] + h[j] = u & 255 + u = u >> 8 + } + + u = u &+ h[16] + h[16] = u + } + + private func add(h: inout Array, c: Array) { + assert(h.count == 17 && c.count == 17) + + var u: UInt32 = 0 + for j in 0..<17 { + u = u &+ (h[j] &+ c[j]) + h[j] = u & 255 + u = u >> 8 + } + } + + private func mulmod(h: inout Array, r: Array) { + var hr = Array(repeating: 0, count: 17) + var u: UInt32 = 0 + for i in 0..<17 { + u = 0 + for j in 0...i { + u = u &+ (h[j] * r[i &- j]) + } + for j in (i + 1)..<17 { + u = u &+ (320 * h[j] * r[i &+ 17 &- j]) + } + hr[i] = u + } + h = hr + self.squeeze(h: &h) + } + + private func freeze(h: inout Array) { + let horig = h + self.add(h: &h, c: [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]) + let negative = UInt32(bitPattern: -Int32(h[16] >> 7)) + for j in 0..<17 { + h[j] ^= negative & (horig[j] ^ h[j]) + } + } + + /// the key is partitioned into two parts, called "r" and "s" + fileprivate func onetimeauth(message input: Array, key k: Array) -> Array { + // clamp + var r = Array(repeating: 0, count: 17) + var h = Array(repeating: 0, count: 17) + var c = Array(repeating: 0, count: 17) + + r[0] = UInt32(k[0]) + r[1] = UInt32(k[1]) + r[2] = UInt32(k[2]) + r[3] = UInt32(k[3] & 15) + r[4] = UInt32(k[4] & 252) + r[5] = UInt32(k[5]) + r[6] = UInt32(k[6]) + r[7] = UInt32(k[7] & 15) + r[8] = UInt32(k[8] & 252) + r[9] = UInt32(k[9]) + r[10] = UInt32(k[10]) + r[11] = UInt32(k[11] & 15) + r[12] = UInt32(k[12] & 252) + r[13] = UInt32(k[13]) + r[14] = UInt32(k[14]) + r[15] = UInt32(k[15] & 15) + r[16] = 0 + + var inlen = input.count + var inpos = 0 + while inlen > 0 { + for j in 0..) throws -> Array { + self.onetimeauth(message: bytes, key: Array(self.key)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/RSA.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/RSA.swift new file mode 100644 index 00000000..f411fa6d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/RSA.swift @@ -0,0 +1,131 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// Foundation is required for `Data` to be found +import Foundation + +// Note: The `BigUInt` struct was copied from: +// https://github.com/attaswift/BigInt +// It allows fast calculation for RSA big numbers + +public final class RSA { + + public enum Error: Swift.Error { + /// No private key specified + case noPrivateKey + } + + /// RSA Modulus + public let n: BigUInteger + + /// RSA Public Exponent + public let e: BigUInteger + + /// RSA Private Exponent + public let d: BigUInteger? + + /// The size of the modulus, in bits + public let keySize: Int + + /// Initialize with RSA parameters + /// - Parameters: + /// - n: The RSA Modulus + /// - e: The RSA Public Exponent + /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known) + public init(n: BigUInteger, e: BigUInteger, d: BigUInteger? = nil) { + self.n = n + self.e = e + self.d = d + + self.keySize = n.bitWidth + } + + /// Initialize with RSA parameters + /// - Parameters: + /// - n: The RSA Modulus + /// - e: The RSA Public Exponent + /// - d: The RSA Private Exponent (or nil if unknown, e.g. if only public key is known) + public convenience init(n: Array, e: Array, d: Array? = nil) { + if let d = d { + self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e)), d: BigUInteger(Data(d))) + } else { + self.init(n: BigUInteger(Data(n)), e: BigUInteger(Data(e))) + } + } + + /// Initialize with a generated key pair + /// - Parameter keySize: The size of the modulus + public convenience init(keySize: Int) { + // Generate prime numbers + let p = BigUInteger.generatePrime(keySize / 2) + let q = BigUInteger.generatePrime(keySize / 2) + + // Calculate modulus + let n = p * q + + // Calculate public and private exponent + let e: BigUInteger = 65537 + let phi = (p - 1) * (q - 1) + let d = e.inverse(phi) + + // Initialize + self.init(n: n, e: e, d: d) + } + + // TODO: Add initializer from PEM (ASN.1 with DER header) (See #892) + + // TODO: Add export to PEM (ASN.1 with DER header) (See #892) + +} + +// MARK: Cipher + +extension RSA: Cipher { + + @inlinable + public func encrypt(_ bytes: ArraySlice) throws -> Array { + // Calculate encrypted data + return BigUInteger(Data(bytes)).power(e, modulus: n).serialize().bytes + } + + @inlinable + public func decrypt(_ bytes: ArraySlice) throws -> Array { + // Check for Private Exponent presence + guard let d = d else { + throw RSA.Error.noPrivateKey + } + + // Calculate decrypted data + return BigUInteger(Data(bytes)).power(d, modulus: n).serialize().bytes + } + +} + +// MARK: CS.BigUInt extension + +extension BigUInteger { + + public static func generatePrime(_ width: Int) -> BigUInteger { + // Note: Need to find a better way to generate prime numbers + while true { + var random = BigUInteger.randomInteger(withExactWidth: width) + random |= BigUInteger(1) + if random.isPrime() { + return random + } + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Rabbit.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Rabbit.swift new file mode 100644 index 00000000..ad0303cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Rabbit.swift @@ -0,0 +1,221 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public final class Rabbit: BlockCipher { + public enum Error: Swift.Error { + case invalidKeyOrInitializationVector + } + + /// Size of IV in bytes + public static let ivSize = 64 / 8 + + /// Size of key in bytes + public static let keySize = 128 / 8 + + /// Size of block in bytes + public static let blockSize = 128 / 8 + + public var keySize: Int { + self.key.count + } + + /// Key + private let key: Key + + /// IV (optional) + private let iv: Array? + + /// State variables + private var x = Array(repeating: 0, count: 8) + + /// Counter variables + private var c = Array(repeating: 0, count: 8) + + /// Counter carry + private var p7: UInt32 = 0 + + /// 'a' constants + private var a: Array = [ + 0x4d34d34d, + 0xd34d34d3, + 0x34d34d34, + 0x4d34d34d, + 0xd34d34d3, + 0x34d34d34, + 0x4d34d34d, + 0xd34d34d3 + ] + + // MARK: - Initializers + + public convenience init(key: Array) throws { + try self.init(key: key, iv: nil) + } + + public init(key: Array, iv: Array?) throws { + self.key = Key(bytes: key) + self.iv = iv + + guard key.count == Rabbit.keySize && (iv == nil || iv!.count == Rabbit.ivSize) else { + throw Error.invalidKeyOrInitializationVector + } + } + + // MARK: - + + fileprivate func setup() { + self.p7 = 0 + + // Key divided into 8 subkeys + let k = Array(unsafeUninitializedCapacity: 8) { buf, count in + for j in 0..<8 { + buf[j] = UInt32(self.key[Rabbit.blockSize - (2 * j + 1)]) | (UInt32(self.key[Rabbit.blockSize - (2 * j + 2)]) << 8) + } + count = 8 + } + + // Initialize state and counter variables from subkeys + for j in 0..<8 { + if j % 2 == 0 { + self.x[j] = (k[(j + 1) % 8] << 16) | k[j] + self.c[j] = (k[(j + 4) % 8] << 16) | k[(j + 5) % 8] + } else { + self.x[j] = (k[(j + 5) % 8] << 16) | k[(j + 4) % 8] + self.c[j] = (k[j] << 16) | k[(j + 1) % 8] + } + } + + // Iterate system four times + self.nextState() + self.nextState() + self.nextState() + self.nextState() + + // Reinitialize counter variables + for j in 0..<8 { + self.c[j] = self.c[j] ^ self.x[(j + 4) % 8] + } + + if let iv = iv { + self.setupIV(iv) + } + } + + private func setupIV(_ iv: Array) { + // 63...56 55...48 47...40 39...32 31...24 23...16 15...8 7...0 IV bits + // 0 1 2 3 4 5 6 7 IV bytes in array + let iv0 = UInt32(bytes: [iv[4], iv[5], iv[6], iv[7]]) + let iv1 = UInt32(bytes: [iv[0], iv[1], iv[4], iv[5]]) + let iv2 = UInt32(bytes: [iv[0], iv[1], iv[2], iv[3]]) + let iv3 = UInt32(bytes: [iv[2], iv[3], iv[6], iv[7]]) + + // Modify the counter state as function of the IV + c[0] = self.c[0] ^ iv0 + self.c[1] = self.c[1] ^ iv1 + self.c[2] = self.c[2] ^ iv2 + self.c[3] = self.c[3] ^ iv3 + self.c[4] = self.c[4] ^ iv0 + self.c[5] = self.c[5] ^ iv1 + self.c[6] = self.c[6] ^ iv2 + self.c[7] = self.c[7] ^ iv3 + + // Iterate system four times + self.nextState() + self.nextState() + self.nextState() + self.nextState() + } + + private func nextState() { + // Before an iteration the counters are incremented + var carry = self.p7 + for j in 0..<8 { + let prev = self.c[j] + self.c[j] = prev &+ self.a[j] &+ carry + carry = prev > self.c[j] ? 1 : 0 // detect overflow + } + self.p7 = carry // save last carry bit + + // Iteration of the system + self.x = Array(unsafeUninitializedCapacity: 8) { newX, count in + newX[0] = self.g(0) &+ rotateLeft(self.g(7), by: 16) &+ rotateLeft(self.g(6), by: 16) + newX[1] = self.g(1) &+ rotateLeft(self.g(0), by: 8) &+ self.g(7) + newX[2] = self.g(2) &+ rotateLeft(self.g(1), by: 16) &+ rotateLeft(self.g(0), by: 16) + newX[3] = self.g(3) &+ rotateLeft(self.g(2), by: 8) &+ self.g(1) + newX[4] = self.g(4) &+ rotateLeft(self.g(3), by: 16) &+ rotateLeft(self.g(2), by: 16) + newX[5] = self.g(5) &+ rotateLeft(self.g(4), by: 8) &+ self.g(3) + newX[6] = self.g(6) &+ rotateLeft(self.g(5), by: 16) &+ rotateLeft(self.g(4), by: 16) + newX[7] = self.g(7) &+ rotateLeft(self.g(6), by: 8) &+ self.g(5) + count = 8 + } + } + + private func g(_ j: Int) -> UInt32 { + let sum = self.x[j] &+ self.c[j] + let square = UInt64(sum) * UInt64(sum) + return UInt32(truncatingIfNeeded: square ^ (square >> 32)) + } + + fileprivate func nextOutput() -> Array { + self.nextState() + + var output16 = Array(repeating: 0, count: Rabbit.blockSize / 2) + output16[7] = UInt16(truncatingIfNeeded: self.x[0]) ^ UInt16(truncatingIfNeeded: self.x[5] >> 16) + output16[6] = UInt16(truncatingIfNeeded: self.x[0] >> 16) ^ UInt16(truncatingIfNeeded: self.x[3]) + output16[5] = UInt16(truncatingIfNeeded: self.x[2]) ^ UInt16(truncatingIfNeeded: self.x[7] >> 16) + output16[4] = UInt16(truncatingIfNeeded: self.x[2] >> 16) ^ UInt16(truncatingIfNeeded: self.x[5]) + output16[3] = UInt16(truncatingIfNeeded: self.x[4]) ^ UInt16(truncatingIfNeeded: self.x[1] >> 16) + output16[2] = UInt16(truncatingIfNeeded: self.x[4] >> 16) ^ UInt16(truncatingIfNeeded: self.x[7]) + output16[1] = UInt16(truncatingIfNeeded: self.x[6]) ^ UInt16(truncatingIfNeeded: self.x[3] >> 16) + output16[0] = UInt16(truncatingIfNeeded: self.x[6] >> 16) ^ UInt16(truncatingIfNeeded: self.x[1]) + + var output8 = Array(repeating: 0, count: Rabbit.blockSize) + for j in 0..> 8) + output8[j * 2 + 1] = UInt8(truncatingIfNeeded: output16[j]) + } + return output8 + } +} + +// MARK: Cipher + +extension Rabbit: Cipher { + public func encrypt(_ bytes: ArraySlice) throws -> Array { + self.setup() + + return Array(unsafeUninitializedCapacity: bytes.count) { result, count in + var output = self.nextOutput() + var byteIdx = 0 + var outputIdx = 0 + while byteIdx < bytes.count { + if outputIdx == Rabbit.blockSize { + output = self.nextOutput() + outputIdx = 0 + } + + result[byteIdx] = bytes[byteIdx] ^ output[outputIdx] + + byteIdx += 1 + outputIdx += 1 + } + count = bytes.count + } + } + + public func decrypt(_ bytes: ArraySlice) throws -> Array { + try self.encrypt(bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA1.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA1.swift new file mode 100644 index 00000000..59cabefc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA1.swift @@ -0,0 +1,158 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +public final class SHA1: DigestType { + + @usableFromInline + static let digestLength: Int = 20 // 160 / 8 + + @usableFromInline + static let blockSize: Int = 64 + + @usableFromInline + static let hashInitialValue: ContiguousArray = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] + + @usableFromInline + var accumulated = Array() + + @usableFromInline + var processedBytesTotalCount: Int = 0 + + @usableFromInline + var accumulatedHash: ContiguousArray = SHA1.hashInitialValue + + public init() { + } + + @inlinable + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + @usableFromInline + func process(block chunk: ArraySlice, currentHash hh: inout ContiguousArray) { + // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15, big-endian + // Extend the sixteen 32-bit words into eighty 32-bit words: + let M = UnsafeMutablePointer.allocate(capacity: 80) + M.initialize(repeating: 0, count: 80) + defer { + M.deinitialize(count: 80) + M.deallocate() + } + + for x in 0..<80 { + switch x { + case 0...15: + let start = chunk.startIndex.advanced(by: x * 4) // * MemoryLayout.size + M[x] = UInt32(bytes: chunk, fromIndex: start) + default: + M[x] = rotateLeft(M[x - 3] ^ M[x - 8] ^ M[x - 14] ^ M[x - 16], by: 1) + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + + // Main loop + for j in 0...79 { + var f: UInt32 = 0 + var k: UInt32 = 0 + + switch j { + case 0...19: + f = (B & C) | ((~B) & D) + k = 0x5a827999 + case 20...39: + f = B ^ C ^ D + k = 0x6ed9eba1 + case 40...59: + f = (B & C) | (B & D) | (C & D) + k = 0x8f1bbcdc + case 60...79: + f = B ^ C ^ D + k = 0xca62c1d6 + default: + break + } + + let temp = rotateLeft(A, by: 5) &+ f &+ E &+ M[j] &+ k + E = D + D = C + C = rotateLeft(B, by: 30) + B = A + A = temp + } + + hh[0] = hh[0] &+ A + hh[1] = hh[1] &+ B + hh[2] = hh[2] &+ C + hh[3] = hh[3] &+ D + hh[4] = hh[4] &+ E + } +} + +extension SHA1: Updatable { + @discardableResult @inlinable + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + self.accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: 64 / 8) // A 64-bit representation of b + + // Step 1. Append padding + bitPadding(to: &self.accumulated, blockSize: SHA1.blockSize, allowance: 64 / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + self.accumulated += lengthBytes + } + + var processedBytes = 0 + for chunk in self.accumulated.batched(by: SHA1.blockSize) { + if isLast || (self.accumulated.count - processedBytes) >= SHA1.blockSize { + self.process(block: chunk, currentHash: &self.accumulatedHash) + processedBytes += chunk.count + } + } + self.accumulated.removeFirst(processedBytes) + self.processedBytesTotalCount += processedBytes + + // output current hash + var result = Array(repeating: 0, count: SHA1.digestLength) + var pos = 0 + for idx in 0..> 24) & 0xff) + result[pos + 1] = UInt8((h >> 16) & 0xff) + result[pos + 2] = UInt8((h >> 8) & 0xff) + result[pos + 3] = UInt8(h & 0xff) + pos += 4 + } + + // reset hash value for instance + if isLast { + self.accumulatedHash = SHA1.hashInitialValue + } + + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA2.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA2.swift new file mode 100644 index 00000000..e5f84de9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA2.swift @@ -0,0 +1,368 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// TODO: generic for process32/64 (UInt32/UInt64) +// + +public final class SHA2: DigestType { + @usableFromInline + let variant: Variant + + @usableFromInline + let size: Int + + @usableFromInline + let blockSize: Int + + @usableFromInline + let digestLength: Int + + private let k: Array + + @usableFromInline + var accumulated = Array() + + @usableFromInline + var processedBytesTotalCount: Int = 0 + + @usableFromInline + var accumulatedHash32 = Array() + + @usableFromInline + var accumulatedHash64 = Array() + + @frozen + public enum Variant: RawRepresentable { + case sha224, sha256, sha384, sha512 + + public var digestLength: Int { + self.rawValue / 8 + } + + public var blockSize: Int { + switch self { + case .sha224, .sha256: + return 64 + case .sha384, .sha512: + return 128 + } + } + + public typealias RawValue = Int + public var rawValue: RawValue { + switch self { + case .sha224: + return 224 + case .sha256: + return 256 + case .sha384: + return 384 + case .sha512: + return 512 + } + } + + public init?(rawValue: RawValue) { + switch rawValue { + case 224: + self = .sha224 + case 256: + self = .sha256 + case 384: + self = .sha384 + case 512: + self = .sha512 + default: + return nil + } + } + + @usableFromInline + var h: Array { + switch self { + case .sha224: + return [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] + case .sha256: + return [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19] + case .sha384: + return [0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4] + case .sha512: + return [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179] + } + } + + @usableFromInline + var finalLength: Int { + switch self { + case .sha224: + return 7 + case .sha384: + return 6 + default: + return Int.max + } + } + } + + public init(variant: SHA2.Variant) { + self.variant = variant + switch self.variant { + case .sha224, .sha256: + self.accumulatedHash32 = variant.h.map { UInt32($0) } // FIXME: UInt64 for process64 + self.blockSize = variant.blockSize + self.size = variant.rawValue + self.digestLength = variant.digestLength + self.k = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ] + case .sha384, .sha512: + self.accumulatedHash64 = variant.h + self.blockSize = variant.blockSize + self.size = variant.rawValue + self.digestLength = variant.digestLength + self.k = [ + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, + 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, + 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab, + 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, + 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, + 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, + 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c, + 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6, + 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 + ] + } + } + + @inlinable + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + @usableFromInline + func process64(block chunk: ArraySlice, currentHash hh: inout Array) { + // break chunk into sixteen 64-bit words M[j], 0 ≤ j ≤ 15, big-endian + // Extend the sixteen 64-bit words into eighty 64-bit words: + let M = UnsafeMutablePointer.allocate(capacity: self.k.count) + M.initialize(repeating: 0, count: self.k.count) + defer { + M.deinitialize(count: self.k.count) + M.deallocate() + } + for x in 0...size + M[x] = UInt64(bytes: chunk, fromIndex: start) + default: + let s0 = rotateRight(M[x - 15], by: 1) ^ rotateRight(M[x - 15], by: 8) ^ (M[x - 15] >> 7) + let s1 = rotateRight(M[x - 2], by: 19) ^ rotateRight(M[x - 2], by: 61) ^ (M[x - 2] >> 6) + M[x] = M[x - 16] &+ s0 &+ M[x - 7] &+ s1 + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + var F = hh[5] + var G = hh[6] + var H = hh[7] + + // Main loop + for j in 0.., currentHash hh: inout Array) { + // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15, big-endian + // Extend the sixteen 32-bit words into sixty-four 32-bit words: + let M = UnsafeMutablePointer.allocate(capacity: self.k.count) + M.initialize(repeating: 0, count: self.k.count) + defer { + M.deinitialize(count: self.k.count) + M.deallocate() + } + + for x in 0...size + M[x] = UInt32(bytes: chunk, fromIndex: start) + default: + let s0 = rotateRight(M[x - 15], by: 7) ^ rotateRight(M[x - 15], by: 18) ^ (M[x - 15] >> 3) + let s1 = rotateRight(M[x - 2], by: 17) ^ rotateRight(M[x - 2], by: 19) ^ (M[x - 2] >> 10) + M[x] = M[x - 16] &+ s0 &+ M[x - 7] &+ s1 + } + } + + var A = hh[0] + var B = hh[1] + var C = hh[2] + var D = hh[3] + var E = hh[4] + var F = hh[5] + var G = hh[6] + var H = hh[7] + + // Main loop + for j in 0.., isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + if isLast { + let lengthInBits = (processedBytesTotalCount + self.accumulated.count) * 8 + let lengthBytes = lengthInBits.bytes(totalBytes: self.blockSize / 8) // A 64-bit/128-bit representation of b. blockSize fit by accident. + + // Step 1. Append padding + bitPadding(to: &self.accumulated, blockSize: self.blockSize, allowance: self.blockSize / 8) + + // Step 2. Append Length a 64-bit representation of lengthInBits + self.accumulated += lengthBytes + } + + var processedBytes = 0 + for chunk in self.accumulated.batched(by: self.blockSize) { + if isLast || (self.accumulated.count - processedBytes) >= self.blockSize { + switch self.variant { + case .sha224, .sha256: + self.process32(block: chunk, currentHash: &self.accumulatedHash32) + case .sha384, .sha512: + self.process64(block: chunk, currentHash: &self.accumulatedHash64) + } + processedBytes += chunk.count + } + } + self.accumulated.removeFirst(processedBytes) + self.processedBytesTotalCount += processedBytes + + // output current hash + var result = Array(repeating: 0, count: variant.digestLength) + switch self.variant { + case .sha224, .sha256: + var pos = 0 + for idx in 0..> 24) & 0xff) + result[pos + 1] = UInt8((h >> 16) & 0xff) + result[pos + 2] = UInt8((h >> 8) & 0xff) + result[pos + 3] = UInt8(h & 0xff) + pos += 4 + } + case .sha384, .sha512: + var pos = 0 + for idx in 0..> 56) & 0xff) + result[pos + 1] = UInt8((h >> 48) & 0xff) + result[pos + 2] = UInt8((h >> 40) & 0xff) + result[pos + 3] = UInt8((h >> 32) & 0xff) + result[pos + 4] = UInt8((h >> 24) & 0xff) + result[pos + 5] = UInt8((h >> 16) & 0xff) + result[pos + 6] = UInt8((h >> 8) & 0xff) + result[pos + 7] = UInt8(h & 0xff) + pos += 8 + } + } + + // reset hash value for instance + if isLast { + switch self.variant { + case .sha224, .sha256: + self.accumulatedHash32 = self.variant.h.lazy.map { UInt32($0) } // FIXME: UInt64 for process64 + case .sha384, .sha512: + self.accumulatedHash64 = self.variant.h + } + } + + return result + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA3.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA3.swift new file mode 100644 index 00000000..dc57504e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SHA3.swift @@ -0,0 +1,299 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +// http://keccak.noekeon.org/specs_summary.html +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +public final class SHA3: DigestType { + let round_constants: Array = [ + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, + 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, + 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, + 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, + 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 + ] + + public let blockSize: Int + public let digestLength: Int + public let markByte: UInt8 + + @usableFromInline + var accumulated = Array() + + + @usableFromInline + var accumulatedHash: Array + + public enum Variant { + case sha224, sha256, sha384, sha512, keccak224, keccak256, keccak384, keccak512 + + var digestLength: Int { + 100 - (self.blockSize / 2) + } + + var blockSize: Int { + (1600 - self.outputLength * 2) / 8 + } + + var markByte: UInt8 { + switch self { + case .sha224, .sha256, .sha384, .sha512: + return 0x06 // 0x1F for SHAKE + case .keccak224, .keccak256, .keccak384, .keccak512: + return 0x01 + } + } + + public var outputLength: Int { + switch self { + case .sha224, .keccak224: + return 224 + case .sha256, .keccak256: + return 256 + case .sha384, .keccak384: + return 384 + case .sha512, .keccak512: + return 512 + } + } + } + + public init(variant: SHA3.Variant) { + self.blockSize = variant.blockSize + self.digestLength = variant.digestLength + self.markByte = variant.markByte + self.accumulatedHash = Array(repeating: 0, count: self.digestLength) + } + + @inlinable + public func calculate(for bytes: Array) -> Array { + do { + return try update(withBytes: bytes.slice, isLast: true) + } catch { + return [] + } + } + + /// 1. For all pairs (x,z) such that 0≤x<5 and 0≤z) { + let c = UnsafeMutablePointer.allocate(capacity: 5) + c.initialize(repeating: 0, count: 5) + defer { + c.deinitialize(count: 5) + c.deallocate() + } + let d = UnsafeMutablePointer.allocate(capacity: 5) + d.initialize(repeating: 0, count: 5) + defer { + d.deinitialize(count: 5) + d.deallocate() + } + + for i in 0..<5 { + c[i] = a[i] ^ a[i &+ 5] ^ a[i &+ 10] ^ a[i &+ 15] ^ a[i &+ 20] + } + + d[0] = rotateLeft(c[1], by: 1) ^ c[4] + d[1] = rotateLeft(c[2], by: 1) ^ c[0] + d[2] = rotateLeft(c[3], by: 1) ^ c[1] + d[3] = rotateLeft(c[4], by: 1) ^ c[2] + d[4] = rotateLeft(c[0], by: 1) ^ c[3] + + for i in 0..<5 { + a[i] ^= d[i] + a[i &+ 5] ^= d[i] + a[i &+ 10] ^= d[i] + a[i &+ 15] ^= d[i] + a[i &+ 20] ^= d[i] + } + } + + /// A′[x, y, z]=A[(x &+ 3y) mod 5, x, z] + private func π(_ a: inout Array) { + let a1 = a[1] + a[1] = a[6] + a[6] = a[9] + a[9] = a[22] + a[22] = a[14] + a[14] = a[20] + a[20] = a[2] + a[2] = a[12] + a[12] = a[13] + a[13] = a[19] + a[19] = a[23] + a[23] = a[15] + a[15] = a[4] + a[4] = a[24] + a[24] = a[21] + a[21] = a[8] + a[8] = a[16] + a[16] = a[5] + a[5] = a[3] + a[3] = a[18] + a[18] = a[17] + a[17] = a[11] + a[11] = a[7] + a[7] = a[10] + a[10] = a1 + } + + /// For all triples (x, y, z) such that 0≤x<5, 0≤y<5, and 0≤z) { + for i in stride(from: 0, to: 25, by: 5) { + let a0 = a[0 &+ i] + let a1 = a[1 &+ i] + a[0 &+ i] ^= ~a1 & a[2 &+ i] + a[1 &+ i] ^= ~a[2 &+ i] & a[3 &+ i] + a[2 &+ i] ^= ~a[3 &+ i] & a[4 &+ i] + a[3 &+ i] ^= ~a[4 &+ i] & a0 + a[4 &+ i] ^= ~a0 & a1 + } + } + + private func ι(_ a: inout Array, round: Int) { + a[0] ^= self.round_constants[round] + } + + @usableFromInline + func process(block chunk: ArraySlice, currentHash hh: inout Array) { + // expand + hh[0] ^= chunk[0].littleEndian + hh[1] ^= chunk[1].littleEndian + hh[2] ^= chunk[2].littleEndian + hh[3] ^= chunk[3].littleEndian + hh[4] ^= chunk[4].littleEndian + hh[5] ^= chunk[5].littleEndian + hh[6] ^= chunk[6].littleEndian + hh[7] ^= chunk[7].littleEndian + hh[8] ^= chunk[8].littleEndian + if self.blockSize > 72 { // 72 / 8, sha-512 + hh[9] ^= chunk[9].littleEndian + hh[10] ^= chunk[10].littleEndian + hh[11] ^= chunk[11].littleEndian + hh[12] ^= chunk[12].littleEndian + if self.blockSize > 104 { // 104 / 8, sha-384 + hh[13] ^= chunk[13].littleEndian + hh[14] ^= chunk[14].littleEndian + hh[15] ^= chunk[15].littleEndian + hh[16] ^= chunk[16].littleEndian + if self.blockSize > 136 { // 136 / 8, sha-256 + hh[17] ^= chunk[17].littleEndian + // FULL_SHA3_FAMILY_SUPPORT + if self.blockSize > 144 { // 144 / 8, sha-224 + hh[18] ^= chunk[18].littleEndian + hh[19] ^= chunk[19].littleEndian + hh[20] ^= chunk[20].littleEndian + hh[21] ^= chunk[21].littleEndian + hh[22] ^= chunk[22].littleEndian + hh[23] ^= chunk[23].littleEndian + hh[24] ^= chunk[24].littleEndian + } + } + } + } + + // Keccak-f + for round in 0..<24 { + self.θ(&hh) + + hh[1] = rotateLeft(hh[1], by: 1) + hh[2] = rotateLeft(hh[2], by: 62) + hh[3] = rotateLeft(hh[3], by: 28) + hh[4] = rotateLeft(hh[4], by: 27) + hh[5] = rotateLeft(hh[5], by: 36) + hh[6] = rotateLeft(hh[6], by: 44) + hh[7] = rotateLeft(hh[7], by: 6) + hh[8] = rotateLeft(hh[8], by: 55) + hh[9] = rotateLeft(hh[9], by: 20) + hh[10] = rotateLeft(hh[10], by: 3) + hh[11] = rotateLeft(hh[11], by: 10) + hh[12] = rotateLeft(hh[12], by: 43) + hh[13] = rotateLeft(hh[13], by: 25) + hh[14] = rotateLeft(hh[14], by: 39) + hh[15] = rotateLeft(hh[15], by: 41) + hh[16] = rotateLeft(hh[16], by: 45) + hh[17] = rotateLeft(hh[17], by: 15) + hh[18] = rotateLeft(hh[18], by: 21) + hh[19] = rotateLeft(hh[19], by: 8) + hh[20] = rotateLeft(hh[20], by: 18) + hh[21] = rotateLeft(hh[21], by: 2) + hh[22] = rotateLeft(hh[22], by: 61) + hh[23] = rotateLeft(hh[23], by: 56) + hh[24] = rotateLeft(hh[24], by: 14) + + self.π(&hh) + self.χ(&hh) + self.ι(&hh, round: round) + } + } +} + +extension SHA3: Updatable { + + @inlinable + public func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + self.accumulated += bytes + + if isLast { + // Add padding + let markByteIndex = self.accumulated.count + + // We need to always pad the input. Even if the input is a multiple of blockSize. + let r = self.blockSize * 8 + let q = (r / 8) - (accumulated.count % (r / 8)) + self.accumulated += Array(repeating: 0, count: q) + + self.accumulated[markByteIndex] |= self.markByte + self.accumulated[self.accumulated.count - 1] |= 0x80 + } + + var processedBytes = 0 + for chunk in self.accumulated.batched(by: self.blockSize) { + if isLast || (self.accumulated.count - processedBytes) >= self.blockSize { + self.process(block: chunk.toUInt64Array().slice, currentHash: &self.accumulatedHash) + processedBytes += chunk.count + } + } + self.accumulated.removeFirst(processedBytes) + + // TODO: verify performance, reduce vs for..in + let result = self.accumulatedHash.reduce(into: Array()) { (result, value) in + result += value.bigEndian.bytes() + } + + // reset hash value for instance + if isLast { + self.accumulatedHash = Array(repeating: 0, count: self.digestLength) + } + + return Array(result[0.. +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +// +// https://tools.ietf.org/html/rfc7914 +// + +/// Implementation of the scrypt key derivation function. +public final class Scrypt { + enum Error: Swift.Error { + case nIsTooLarge + case rIsTooLarge + case nMustBeAPowerOf2GreaterThan1 + case invalidInput + } + + /// Configuration parameters. + private let salt: SecureBytes + private let password: SecureBytes + private let blocksize: Int // 128 * r + private let salsaBlock = UnsafeMutableRawPointer.allocate(byteCount: 64, alignment: 64) + private let dkLen: Int + private let N: Int + private let r: Int + private let p: Int + + /// - parameters: + /// - password: password + /// - salt: salt + /// - dkLen: output length + /// - N: determines extra memory used + /// - r: determines a block size + /// - p: determines parallelicity degree + public init(password: Array, salt: Array, dkLen: Int, N: Int, r: Int, p: Int) throws { + precondition(dkLen > 0) + precondition(N > 0) + precondition(r > 0) + precondition(p > 0) + + guard !(N < 2 || (N & (N - 1)) != 0) else { throw Error.nMustBeAPowerOf2GreaterThan1 } + + guard N <= .max / 128 / r else { throw Error.nIsTooLarge } + guard r <= .max / 128 / p else { throw Error.rIsTooLarge } + + guard !salt.isEmpty else { + throw Error.invalidInput + } + + self.blocksize = 128 * r + self.N = N + self.r = r + self.p = p + self.password = SecureBytes(bytes: password) + self.salt = SecureBytes(bytes: salt) + self.dkLen = dkLen + } + + /// Runs the key derivation function with a specific password. + public func calculate() throws -> [UInt8] { + // Allocate memory (as bytes for now) for further use in mixing steps + let B = UnsafeMutableRawPointer.allocate(byteCount: 128 * self.r * self.p, alignment: 64) + let XY = UnsafeMutableRawPointer.allocate(byteCount: 256 * self.r + 64, alignment: 64) + let V = UnsafeMutableRawPointer.allocate(byteCount: 128 * self.r * self.N, alignment: 64) + + // Deallocate memory when done + defer { + B.deallocate() + XY.deallocate() + V.deallocate() + } + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + // Expand the initial key + let barray = try PKCS5.PBKDF2(password: Array(self.password), salt: Array(self.salt), iterations: 1, keyLength: self.p * 128 * self.r, variant: .sha2(.sha256)).calculate() + barray.withUnsafeBytes { p in + B.copyMemory(from: p.baseAddress!, byteCount: barray.count) + } + + /* 2: for i = 0 to p - 1 do */ + // do the mixing + for i in 0 ..< self.p { + /* 3: B_i <-- MF(B_i, N) */ + smix(B + i * 128 * self.r, V.assumingMemoryBound(to: UInt32.self), XY.assumingMemoryBound(to: UInt32.self)) + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + let pointer = B.assumingMemoryBound(to: UInt8.self) + let bufferPointer = UnsafeBufferPointer(start: pointer, count: p * 128 * self.r) + let block = [UInt8](bufferPointer) + return try PKCS5.PBKDF2(password: Array(self.password), salt: block, iterations: 1, keyLength: self.dkLen, variant: .sha2(.sha256)).calculate() + } +} + +private extension Scrypt { + /// Computes `B = SMix_r(B, N)`. + /// + /// The input `block` must be `128*r` bytes in length; the temporary storage `v` must be `128*r*n` bytes in length; + /// the temporary storage `xy` must be `256*r + 64` bytes in length. The arrays `block`, `v`, and `xy` must be + /// aligned to a multiple of 64 bytes. + @inline(__always) func smix(_ block: UnsafeMutableRawPointer, _ v: UnsafeMutablePointer, _ xy: UnsafeMutablePointer) { + let X = xy + let Y = xy + 32 * self.r + let Z = xy + 64 * self.r + + /* 1: X <-- B */ + let typedBlock = block.assumingMemoryBound(to: UInt32.self) + X.assign(from: typedBlock, count: 32 * self.r) + + /* 2: for i = 0 to N - 1 do */ + for i in stride(from: 0, to: self.N, by: 2) { + /* 3: V_i <-- X */ + UnsafeMutableRawPointer(v + i * (32 * self.r)).copyMemory(from: X, byteCount: 128 * self.r) + + /* 4: X <-- H(X) */ + self.blockMixSalsa8(X, Y, Z) + + /* 3: V_i <-- X */ + UnsafeMutableRawPointer(v + (i + 1) * (32 * self.r)).copyMemory(from: Y, byteCount: 128 * self.r) + + /* 4: X <-- H(X) */ + self.blockMixSalsa8(Y, X, Z) + } + + /* 6: for i = 0 to N - 1 do */ + for _ in stride(from: 0, to: self.N, by: 2) { + /* + 7: j <-- Integerify (X) mod N + where Integerify (B[0] ... B[2 * r - 1]) is defined + as the result of interpreting B[2 * r - 1] as a little-endian integer. + */ + var j = Int(integerify(X) & UInt64(self.N - 1)) + + /* 8: X <-- H(X \xor V_j) */ + self.blockXor(X, v + j * 32 * self.r, 128 * self.r) + self.blockMixSalsa8(X, Y, Z) + + /* 7: j <-- Integerify(X) mod N */ + j = Int(self.integerify(Y) & UInt64(self.N - 1)) + + /* 8: X <-- H(X \xor V_j) */ + self.blockXor(Y, v + j * 32 * self.r, 128 * self.r) + self.blockMixSalsa8(Y, X, Z) + } + + /* 10: B' <-- X */ + for k in 0 ..< 32 * self.r { + UnsafeMutableRawPointer(block + 4 * k).storeBytes(of: X[k], as: UInt32.self) + } + } + + /// Returns the result of parsing `B_{2r-1}` as a little-endian integer. + @inline(__always) func integerify(_ block: UnsafeRawPointer) -> UInt64 { + let bi = block + (2 * self.r - 1) * 64 + return bi.load(as: UInt64.self).littleEndian + } + + /// Compute `bout = BlockMix_{salsa20/8, r}(bin)`. + /// + /// The input `bin` must be `128*r` bytes in length; the output `bout` must also be the same size. The temporary + /// space `x` must be 64 bytes. + @inline(__always) func blockMixSalsa8(_ bin: UnsafePointer, _ bout: UnsafeMutablePointer, _ x: UnsafeMutablePointer) { + /* 1: X <-- B_{2r - 1} */ + UnsafeMutableRawPointer(x).copyMemory(from: bin + (2 * self.r - 1) * 16, byteCount: 64) + + /* 2: for i = 0 to 2r - 1 do */ + for i in stride(from: 0, to: 2 * self.r, by: 2) { + /* 3: X <-- H(X \xor B_i) */ + self.blockXor(x, bin + i * 16, 64) + self.salsa20_8_typed(x) + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + UnsafeMutableRawPointer(bout + i * 8).copyMemory(from: x, byteCount: 64) + + /* 3: X <-- H(X \xor B_i) */ + self.blockXor(x, bin + i * 16 + 16, 64) + self.salsa20_8_typed(x) + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + UnsafeMutableRawPointer(bout + i * 8 + self.r * 16).copyMemory(from: x, byteCount: 64) + } + } + + @inline(__always) func salsa20_8_typed(_ block: UnsafeMutablePointer) { + self.salsaBlock.copyMemory(from: UnsafeRawPointer(block), byteCount: 64) + let salsaBlockTyped = self.salsaBlock.assumingMemoryBound(to: UInt32.self) + + for _ in stride(from: 0, to: 8, by: 2) { + salsaBlockTyped[4] ^= rotateLeft(salsaBlockTyped[0] &+ salsaBlockTyped[12], by: 7) + salsaBlockTyped[8] ^= rotateLeft(salsaBlockTyped[4] &+ salsaBlockTyped[0], by: 9) + salsaBlockTyped[12] ^= rotateLeft(salsaBlockTyped[8] &+ salsaBlockTyped[4], by: 13) + salsaBlockTyped[0] ^= rotateLeft(salsaBlockTyped[12] &+ salsaBlockTyped[8], by: 18) + + salsaBlockTyped[9] ^= rotateLeft(salsaBlockTyped[5] &+ salsaBlockTyped[1], by: 7) + salsaBlockTyped[13] ^= rotateLeft(salsaBlockTyped[9] &+ salsaBlockTyped[5], by: 9) + salsaBlockTyped[1] ^= rotateLeft(salsaBlockTyped[13] &+ salsaBlockTyped[9], by: 13) + salsaBlockTyped[5] ^= rotateLeft(salsaBlockTyped[1] &+ salsaBlockTyped[13], by: 18) + + salsaBlockTyped[14] ^= rotateLeft(salsaBlockTyped[10] &+ salsaBlockTyped[6], by: 7) + salsaBlockTyped[2] ^= rotateLeft(salsaBlockTyped[14] &+ salsaBlockTyped[10], by: 9) + salsaBlockTyped[6] ^= rotateLeft(salsaBlockTyped[2] &+ salsaBlockTyped[14], by: 13) + salsaBlockTyped[10] ^= rotateLeft(salsaBlockTyped[6] &+ salsaBlockTyped[2], by: 18) + + salsaBlockTyped[3] ^= rotateLeft(salsaBlockTyped[15] &+ salsaBlockTyped[11], by: 7) + salsaBlockTyped[7] ^= rotateLeft(salsaBlockTyped[3] &+ salsaBlockTyped[15], by: 9) + salsaBlockTyped[11] ^= rotateLeft(salsaBlockTyped[7] &+ salsaBlockTyped[3], by: 13) + salsaBlockTyped[15] ^= rotateLeft(salsaBlockTyped[11] &+ salsaBlockTyped[7], by: 18) + + salsaBlockTyped[1] ^= rotateLeft(salsaBlockTyped[0] &+ salsaBlockTyped[3], by: 7) + salsaBlockTyped[2] ^= rotateLeft(salsaBlockTyped[1] &+ salsaBlockTyped[0], by: 9) + salsaBlockTyped[3] ^= rotateLeft(salsaBlockTyped[2] &+ salsaBlockTyped[1], by: 13) + salsaBlockTyped[0] ^= rotateLeft(salsaBlockTyped[3] &+ salsaBlockTyped[2], by: 18) + + salsaBlockTyped[6] ^= rotateLeft(salsaBlockTyped[5] &+ salsaBlockTyped[4], by: 7) + salsaBlockTyped[7] ^= rotateLeft(salsaBlockTyped[6] &+ salsaBlockTyped[5], by: 9) + salsaBlockTyped[4] ^= rotateLeft(salsaBlockTyped[7] &+ salsaBlockTyped[6], by: 13) + salsaBlockTyped[5] ^= rotateLeft(salsaBlockTyped[4] &+ salsaBlockTyped[7], by: 18) + + salsaBlockTyped[11] ^= rotateLeft(salsaBlockTyped[10] &+ salsaBlockTyped[9], by: 7) + salsaBlockTyped[8] ^= rotateLeft(salsaBlockTyped[11] &+ salsaBlockTyped[10], by: 9) + salsaBlockTyped[9] ^= rotateLeft(salsaBlockTyped[8] &+ salsaBlockTyped[11], by: 13) + salsaBlockTyped[10] ^= rotateLeft(salsaBlockTyped[9] &+ salsaBlockTyped[8], by: 18) + + salsaBlockTyped[12] ^= rotateLeft(salsaBlockTyped[15] &+ salsaBlockTyped[14], by: 7) + salsaBlockTyped[13] ^= rotateLeft(salsaBlockTyped[12] &+ salsaBlockTyped[15], by: 9) + salsaBlockTyped[14] ^= rotateLeft(salsaBlockTyped[13] &+ salsaBlockTyped[12], by: 13) + salsaBlockTyped[15] ^= rotateLeft(salsaBlockTyped[14] &+ salsaBlockTyped[13], by: 18) + } + for i in 0 ..< 16 { + block[i] = block[i] &+ salsaBlockTyped[i] + } + } + + @inline(__always) func blockXor(_ dest: UnsafeMutableRawPointer, _ src: UnsafeRawPointer, _ len: Int) { + let D = dest.assumingMemoryBound(to: UInt64.self) + let S = src.assumingMemoryBound(to: UInt64.self) + let L = len / MemoryLayout.size + + for i in 0 ..< L { + D[i] ^= S[i] + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift new file mode 100644 index 00000000..9d80fca8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/SecureBytes.swift @@ -0,0 +1,87 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(WinSDK) +import WinSDK +#endif + +typealias Key = SecureBytes + +/// Keeps bytes in memory. Because this is class, bytes are not copied +/// and memory area is locked as long as referenced, then unlocked on deinit +final class SecureBytes { + private let bytes: Array + let count: Int + + init(bytes: Array) { + self.bytes = bytes + self.count = bytes.count + self.bytes.withUnsafeBufferPointer { (pointer) -> Void in + #if os(Windows) + VirtualLock(UnsafeMutableRawPointer(mutating: pointer.baseAddress), SIZE_T(pointer.count)) + #else + mlock(pointer.baseAddress, pointer.count) + #endif + } + } + + deinit { + self.bytes.withUnsafeBufferPointer { (pointer) -> Void in + #if os(Windows) + VirtualUnlock(UnsafeMutableRawPointer(mutating: pointer.baseAddress), SIZE_T(pointer.count)) + #else + munlock(pointer.baseAddress, pointer.count) + #endif + } + } +} + +extension SecureBytes: Collection { + typealias Index = Int + + var endIndex: Int { + self.bytes.endIndex + } + + var startIndex: Int { + self.bytes.startIndex + } + + subscript(position: Index) -> UInt8 { + self.bytes[position] + } + + subscript(bounds: Range) -> ArraySlice { + self.bytes[bounds] + } + + func formIndex(after i: inout Int) { + self.bytes.formIndex(after: &i) + } + + func index(after i: Int) -> Int { + self.bytes.index(after: i) + } +} + +extension SecureBytes: ExpressibleByArrayLiteral { + public convenience init(arrayLiteral elements: UInt8...) { + self.init(bytes: elements) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift new file mode 100644 index 00000000..88802b56 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamDecryptor.swift @@ -0,0 +1,92 @@ +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@usableFromInline +final class StreamDecryptor: Cryptor, Updatable { + + @usableFromInline + internal let blockSize: Int + + @usableFromInline + internal var worker: CipherModeWorker + + @usableFromInline + internal let padding: Padding + + @usableFromInline + internal var accumulated = Array() + + @usableFromInline + internal var lastBlockRemainder = 0 + + @usableFromInline + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + + @inlinable + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + self.accumulated += bytes + + let toProcess = self.accumulated.prefix(max(self.accumulated.count - self.worker.additionalBufferSize, 0)) + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + // will truncate suffix if needed + try finalizingWorker.willDecryptLast(bytes: self.accumulated.slice) + } + + var processedBytesCount = 0 + var plaintext = Array(reserveCapacity: bytes.count + self.worker.additionalBufferSize) + for chunk in toProcess.batched(by: self.blockSize) { + plaintext += self.worker.decrypt(block: chunk) + processedBytesCount += chunk.count + } + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + plaintext = Array(try finalizingWorker.didDecryptLast(bytes: plaintext.slice)) + } + + // omit unecessary calculation if not needed + if self.padding != .noPadding { + self.lastBlockRemainder = plaintext.count.quotientAndRemainder(dividingBy: self.blockSize).remainder + } + + if isLast { + // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't. + plaintext = self.padding.remove(from: plaintext, blockSize: self.blockSize - self.lastBlockRemainder) + } + + self.accumulated.removeFirst(processedBytesCount) // super-slow + + if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true { + plaintext = Array(try finalizingWorker.finalize(decrypt: plaintext.slice)) + } + + return plaintext + } + + @inlinable + public func seek(to position: Int) throws { + guard var worker = self.worker as? SeekableModeWorker else { + fatalError("Not supported") + } + + try worker.seek(to: position) + self.worker = worker + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift new file mode 100644 index 00000000..10ce7b1a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/StreamEncryptor.swift @@ -0,0 +1,68 @@ +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@usableFromInline +final class StreamEncryptor: Cryptor, Updatable { + + @usableFromInline + internal let blockSize: Int + + @usableFromInline + internal var worker: CipherModeWorker + + @usableFromInline + internal let padding: Padding + + @usableFromInline + internal var lastBlockRemainder = 0 + + @usableFromInline + init(blockSize: Int, padding: Padding, _ worker: CipherModeWorker) throws { + self.blockSize = blockSize + self.padding = padding + self.worker = worker + } + + // MARK: Updatable + + @inlinable + public func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array { + var accumulated = Array(bytes) + if isLast { + // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't. + accumulated = self.padding.add(to: accumulated, blockSize: self.blockSize - self.lastBlockRemainder) + } + + var encrypted = Array(reserveCapacity: bytes.count) + for chunk in accumulated.batched(by: self.blockSize) { + encrypted += self.worker.encrypt(block: chunk) + } + + // omit unecessary calculation if not needed + if self.padding != .noPadding { + self.lastBlockRemainder = encrypted.count.quotientAndRemainder(dividingBy: self.blockSize).remainder + } + + if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true { + encrypted = Array(try finalizingWorker.finalize(encrypt: encrypted.slice)) + } + + return encrypted + } + + @usableFromInline + func seek(to: Int) throws { + fatalError("Not supported") + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/String+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/String+Extension.swift new file mode 100644 index 00000000..dc979ce3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/String+Extension.swift @@ -0,0 +1,96 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/** String extension */ +extension String { + + @inlinable + public var bytes: Array { + data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8) + } + + @inlinable + public func md5() -> String { + self.bytes.md5().toHexString() + } + + @inlinable + public func sha1() -> String { + self.bytes.sha1().toHexString() + } + + @inlinable + public func sha224() -> String { + self.bytes.sha224().toHexString() + } + + @inlinable + public func sha256() -> String { + self.bytes.sha256().toHexString() + } + + @inlinable + public func sha384() -> String { + self.bytes.sha384().toHexString() + } + + @inlinable + public func sha512() -> String { + self.bytes.sha512().toHexString() + } + + @inlinable + public func sha3(_ variant: SHA3.Variant) -> String { + self.bytes.sha3(variant).toHexString() + } + + @inlinable + public func crc32(seed: UInt32? = nil, reflect: Bool = true) -> String { + self.bytes.crc32(seed: seed, reflect: reflect).bytes().toHexString() + } + + @inlinable + public func crc32c(seed: UInt32? = nil, reflect: Bool = true) -> String { + self.bytes.crc32c(seed: seed, reflect: reflect).bytes().toHexString() + } + + @inlinable + public func crc16(seed: UInt16? = nil) -> String { + self.bytes.crc16(seed: seed).bytes().toHexString() + } + + /// - parameter cipher: Instance of `Cipher` + /// - returns: hex string of bytes + @inlinable + public func encrypt(cipher: Cipher) throws -> String { + try self.bytes.encrypt(cipher: cipher).toHexString() + } + + /// - parameter cipher: Instance of `Cipher` + /// - returns: base64 encoded string of encrypted bytes + @inlinable + public func encryptToBase64(cipher: Cipher) throws -> String { + try self.bytes.encrypt(cipher: cipher).toBase64() + } + + // decrypt() does not make sense for String + + /// - parameter authenticator: Instance of `Authenticator` + /// - returns: hex string of string + @inlinable + public func authenticate(with authenticator: A) throws -> String { + try self.bytes.authenticate(with: authenticator).toHexString() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt128.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt128.swift new file mode 100644 index 00000000..abc24933 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt128.swift @@ -0,0 +1,90 @@ +// +// UInt128.swift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +import Foundation + +struct UInt128: Equatable, ExpressibleByIntegerLiteral { + let i: (a: UInt64, b: UInt64) + + typealias IntegerLiteralType = UInt64 + + init(integerLiteral value: IntegerLiteralType) { + self = UInt128(value) + } + + init(_ raw: Array) { + self = raw.prefix(MemoryLayout.stride).withUnsafeBytes({ (rawBufferPointer) -> UInt128 in + let arr = rawBufferPointer.bindMemory(to: UInt64.self) + return UInt128((arr[0].bigEndian, arr[1].bigEndian)) + }) + } + + init(_ raw: ArraySlice) { + self.init(Array(raw)) + } + + init(_ i: (a: UInt64, b: UInt64)) { + self.i = i + } + + init(a: UInt64, b: UInt64) { + self.init((a, b)) + } + + init(_ b: UInt64) { + self.init((0, b)) + } + + // Bytes + var bytes: Array { + var at = self.i.a.bigEndian + var bt = self.i.b.bigEndian + + let ar = Data(bytes: &at, count: MemoryLayout.size(ofValue: at)) + let br = Data(bytes: &bt, count: MemoryLayout.size(ofValue: bt)) + + var result = Data() + result.append(ar) + result.append(br) + return result.bytes + } + + static func ^ (n1: UInt128, n2: UInt128) -> UInt128 { + UInt128((n1.i.a ^ n2.i.a, n1.i.b ^ n2.i.b)) + } + + static func & (n1: UInt128, n2: UInt128) -> UInt128 { + UInt128((n1.i.a & n2.i.a, n1.i.b & n2.i.b)) + } + + static func >> (value: UInt128, by: Int) -> UInt128 { + var result = value + for _ in 0..> 1 + let b = result.i.b >> 1 + ((result.i.a & 1) << 63) + result = UInt128((a, b)) + } + return result + } + + // Equatable. + static func == (lhs: UInt128, rhs: UInt128) -> Bool { + lhs.i == rhs.i + } + + static func != (lhs: UInt128, rhs: UInt128) -> Bool { + !(lhs == rhs) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift new file mode 100644 index 00000000..777bd980 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift @@ -0,0 +1,37 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/** array of bytes */ +extension UInt16 { + @_specialize(where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt16(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(where T == ArraySlice) + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt16(bytes[index.advanced(by: 0)]) << 8 : 0 + let val1 = count > 1 ? UInt16(bytes[index.advanced(by: 1)]) : 0 + + self = val0 | val1 + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift new file mode 100644 index 00000000..91558692 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift @@ -0,0 +1,51 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +protocol _UInt32Type {} +extension UInt32: _UInt32Type {} + +/** array of bytes */ +extension UInt32 { + @_specialize(where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt32(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(where T == ArraySlice) + @inlinable + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt32(bytes[index.advanced(by: 0)]) << 24 : 0 + let val1 = count > 1 ? UInt32(bytes[index.advanced(by: 1)]) << 16 : 0 + let val2 = count > 2 ? UInt32(bytes[index.advanced(by: 2)]) << 8 : 0 + let val3 = count > 3 ? UInt32(bytes[index.advanced(by: 3)]) : 0 + + self = val0 | val1 | val2 | val3 + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift new file mode 100644 index 00000000..224f7173 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift @@ -0,0 +1,44 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/** array of bytes */ +extension UInt64 { + @_specialize(where T == ArraySlice) + init(bytes: T) where T.Element == UInt8, T.Index == Int { + self = UInt64(bytes: bytes, fromIndex: bytes.startIndex) + } + + @_specialize(where T == ArraySlice) + @inlinable + init(bytes: T, fromIndex index: T.Index) where T.Element == UInt8, T.Index == Int { + if bytes.isEmpty { + self = 0 + return + } + + let count = bytes.count + + let val0 = count > 0 ? UInt64(bytes[index.advanced(by: 0)]) << 56 : 0 + let val1 = count > 1 ? UInt64(bytes[index.advanced(by: 1)]) << 48 : 0 + let val2 = count > 2 ? UInt64(bytes[index.advanced(by: 2)]) << 40 : 0 + let val3 = count > 3 ? UInt64(bytes[index.advanced(by: 3)]) << 32 : 0 + let val4 = count > 4 ? UInt64(bytes[index.advanced(by: 4)]) << 24 : 0 + let val5 = count > 5 ? UInt64(bytes[index.advanced(by: 5)]) << 16 : 0 + let val6 = count > 6 ? UInt64(bytes[index.advanced(by: 6)]) << 8 : 0 + let val7 = count > 7 ? UInt64(bytes[index.advanced(by: 7)]) : 0 + + self = val0 | val1 | val2 | val3 | val4 | val5 | val6 | val7 + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift new file mode 100644 index 00000000..906a9ded --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/UInt8+Extension.swift @@ -0,0 +1,74 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(ucrt) +import ucrt +#endif + +public protocol _UInt8Type {} +extension UInt8: _UInt8Type {} + +/** casting */ +extension UInt8 { + /** cast because UInt8() because std initializer crash if value is > byte */ + static func with(value: UInt64) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } + + static func with(value: UInt32) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } + + static func with(value: UInt16) -> UInt8 { + let tmp = value & 0xff + return UInt8(tmp) + } +} + +/** Bits */ +extension UInt8 { + /** array of bits */ + public func bits() -> [Bit] { + let totalBitsCount = MemoryLayout.size * 8 + + var bitsArray = [Bit](repeating: Bit.zero, count: totalBitsCount) + + for j in 0.. String { + var s = String() + let arr: [Bit] = self.bits() + for idx in arr.indices { + s += (arr[idx] == Bit.one ? "1" : "0") + if idx.advanced(by: 1) % 8 == 0 { s += " " } + } + return s + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Updatable.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Updatable.swift new file mode 100644 index 00000000..22031ad6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Updatable.swift @@ -0,0 +1,107 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// A type that supports incremental updates. For example Digest or Cipher may be updatable +/// and calculate result incerementally. +public protocol Updatable { + /// Update given bytes in chunks. + /// + /// - parameter bytes: Bytes to process. + /// - parameter isLast: Indicate if given chunk is the last one. No more updates after this call. + /// - returns: Processed partial result data or empty array. + mutating func update(withBytes bytes: ArraySlice, isLast: Bool) throws -> Array + + /// Update given bytes in chunks. + /// + /// - Parameters: + /// - bytes: Bytes to process. + /// - isLast: Indicate if given chunk is the last one. No more updates after this call. + /// - output: Resulting bytes callback. + /// - Returns: Processed partial result data or empty array. + mutating func update(withBytes bytes: ArraySlice, isLast: Bool, output: (_ bytes: Array) -> Void) throws +} + +extension Updatable { + @inlinable + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false, output: (_ bytes: Array) -> Void) throws { + let processed = try update(withBytes: bytes, isLast: isLast) + if !processed.isEmpty { + output(processed) + } + } + + @inlinable + public mutating func update(withBytes bytes: ArraySlice, isLast: Bool = false) throws -> Array { + try self.update(withBytes: bytes, isLast: isLast) + } + + @inlinable + public mutating func update(withBytes bytes: Array, isLast: Bool = false) throws -> Array { + try self.update(withBytes: bytes.slice, isLast: isLast) + } + + @inlinable + public mutating func update(withBytes bytes: Array, isLast: Bool = false, output: (_ bytes: Array) -> Void) throws { + try self.update(withBytes: bytes.slice, isLast: isLast, output: output) + } + + /// Finish updates. This may apply padding. + /// - parameter bytes: Bytes to process + /// - returns: Processed data. + @inlinable + public mutating func finish(withBytes bytes: ArraySlice) throws -> Array { + try self.update(withBytes: bytes, isLast: true) + } + + @inlinable + public mutating func finish(withBytes bytes: Array) throws -> Array { + try self.finish(withBytes: bytes.slice) + } + + /// Finish updates. May add padding. + /// + /// - Returns: Processed data + /// - Throws: Error + @inlinable + public mutating func finish() throws -> Array { + try self.update(withBytes: [], isLast: true) + } + + /// Finish updates. This may apply padding. + /// - parameter bytes: Bytes to process + /// - parameter output: Resulting data + /// - returns: Processed data. + @inlinable + public mutating func finish(withBytes bytes: ArraySlice, output: (_ bytes: Array) -> Void) throws { + let processed = try update(withBytes: bytes, isLast: true) + if !processed.isEmpty { + output(processed) + } + } + + @inlinable + public mutating func finish(withBytes bytes: Array, output: (_ bytes: Array) -> Void) throws { + try self.finish(withBytes: bytes.slice, output: output) + } + + /// Finish updates. May add padding. + /// + /// - Parameter output: Processed data + /// - Throws: Error + @inlinable + public mutating func finish(output: (Array) -> Void) throws { + try self.finish(withBytes: [], output: output) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Utils.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Utils.swift new file mode 100644 index 00000000..7afca0b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/Utils.swift @@ -0,0 +1,117 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +@inlinable +func rotateLeft(_ value: UInt8, by: UInt8) -> UInt8 { + ((value << by) & 0xff) | (value >> (8 - by)) +} + +@inlinable +func rotateLeft(_ value: UInt16, by: UInt16) -> UInt16 { + ((value << by) & 0xffff) | (value >> (16 - by)) +} + +@inlinable +func rotateLeft(_ value: UInt32, by: UInt32) -> UInt32 { + ((value << by) & 0xffffffff) | (value >> (32 - by)) +} + +@inlinable +func rotateLeft(_ value: UInt64, by: UInt64) -> UInt64 { + (value << by) | (value >> (64 - by)) +} + +@inlinable +func rotateRight(_ value: UInt16, by: UInt16) -> UInt16 { + (value >> by) | (value << (16 - by)) +} + +@inlinable +func rotateRight(_ value: UInt32, by: UInt32) -> UInt32 { + (value >> by) | (value << (32 - by)) +} + +@inlinable +func rotateRight(_ value: UInt64, by: UInt64) -> UInt64 { + ((value >> by) | (value << (64 - by))) +} + +@inlinable +func reversed(_ uint8: UInt8) -> UInt8 { + var v = uint8 + v = (v & 0xf0) >> 4 | (v & 0x0f) << 4 + v = (v & 0xcc) >> 2 | (v & 0x33) << 2 + v = (v & 0xaa) >> 1 | (v & 0x55) << 1 + return v +} + +@inlinable +func reversed(_ uint32: UInt32) -> UInt32 { + var v = uint32 + v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1) + v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2) + v = ((v >> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4) + v = ((v >> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8) + v = ((v >> 16) & 0xffff) | ((v & 0xffff) << 16) + return v +} + +@inlinable +func xor(_ left: T, _ right: V) -> ArraySlice where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, V.Element == UInt8, V.Index == Int { + return xor(left, right).slice +} + +@inlinable +func xor(_ left: T, _ right: V) -> Array where T: RandomAccessCollection, V: RandomAccessCollection, T.Element == UInt8, T.Index == Int, V.Element == UInt8, V.Index == Int { + let length = Swift.min(left.count, right.count) + + let buf = UnsafeMutablePointer.allocate(capacity: length) + buf.initialize(repeating: 0, count: length) + defer { + buf.deinitialize(count: length) + buf.deallocate() + } + + // xor + for i in 0.., blockSize: Int, allowance: Int = 0) { + let msgLength = data.count + // Step 1. Append Padding Bits + // append one bit (UInt8 with one bit) to message + data.append(0x80) + + // Step 2. append "0" bit until message length in bits ≡ 448 (mod 512) + let max = blockSize - allowance // 448, 986 + if msgLength % blockSize < max { // 448 + data += Array(repeating: 0, count: max - 1 - (msgLength % blockSize)) + } else { + data += Array(repeating: 0, count: blockSize + max - 1 - (msgLength % blockSize)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift new file mode 100644 index 00000000..b1b67dd4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/CryptoSwift/Sources/CryptoSwift/ZeroPadding.swift @@ -0,0 +1,40 @@ +// +// CryptoSwift +// +// Copyright (C) 2014-2021 Marcin Krzyżanowski +// This software is provided 'as-is', without any express or implied warranty. +// +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: +// +// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +// - This notice may not be removed or altered from any source or binary distribution. +// + +/// All the bytes that are required to be padded are padded with zero. +/// Zero padding may not be reversible if the original file ends with one or more zero bytes. +struct ZeroPadding: PaddingProtocol { + init() { + } + + @inlinable + func add(to bytes: Array, blockSize: Int) -> Array { + let paddingCount = blockSize - (bytes.count % blockSize) + if paddingCount > 0 { + return bytes + Array(repeating: 0, count: paddingCount) + } + return bytes + } + + @inlinable + func remove(from bytes: Array, blockSize _: Int?) -> Array { + for (idx, value) in bytes.reversed().enumerated() { + if value != 0 { + return Array(bytes[0.. CGRect { + let x = origin.x / s.width + let y = origin.y / s.height + let width = size.width / s.width + let height = size.height / s.height + return CGRect(x: x, y: y, width: width, height: height) + } +} + +class BlurLayer: CALayer { + private static let blurRadiusKey = "blurRadius" + private static let blurLayoutKey = "blurLayout" + @NSManaged var blurRadius: CGFloat + @NSManaged private var blurLayout: CGFloat + + private var fromBlurRadius: CGFloat? + var presentationRadius: CGFloat { + if let radius = fromBlurRadius { + if let layer = presentation() { + return layer.blurRadius + } else { + return radius + } + } else { + return blurRadius + } + } + + override class func needsDisplay(forKey key: String) -> Bool { + if key == blurRadiusKey || key == blurLayoutKey { + return true + } + return super.needsDisplay(forKey: key) + } + + open override func action(forKey event: String) -> CAAction? { + if event == BlurLayer.blurRadiusKey { + fromBlurRadius = nil + + if let action = super.action(forKey: "opacity") as? CABasicAnimation { + fromBlurRadius = (presentation() ?? self).blurRadius + + action.keyPath = event + action.fromValue = fromBlurRadius + return action + } + } + + if event == BlurLayer.blurLayoutKey, let action = super.action(forKey: "opacity") as? CABasicAnimation { + action.keyPath = event + action.fromValue = 0 + action.toValue = 1 + return action + } + + return super.action(forKey: event) + } +} + +extension BlurLayer { + func draw(_ image: UIImage, fixes isFixes: Bool, baseLayer: CALayer?) { + contents = image.cgImage + contentsScale = image.scale + + if isFixes, let blurLayer = presentation() { + contentsRect = blurLayer.convert(blurLayer.bounds, to: baseLayer).rectangle(image.size) + } + } + + func refresh() { + fromBlurRadius = nil + } + + func animate() { + UIView.performWithoutAnimation { + blurLayout = 0 + } + blurLayout = 1 + } + + func render(in context: CGContext, for layer: CALayer) { + let layers = hideOverlappingLayers(layer.sublayers) + layer.render(in: context) + layers.forEach { + $0.isHidden = false + } + } + + private func hideOverlappingLayers(_ layers: [CALayer]?) -> [CALayer] { + var hiddenLayers: [CALayer] = [] + guard let layers = layers else { + return hiddenLayers + } + + for layer in layers.reversed() { + if isHang(to: layer) { + return hiddenLayers + hideOverlappingLayers(layer.sublayers) + } + if layer.isHidden == false { + layer.isHidden = true + hiddenLayers.append(layer) + } + if layer == self { + return hiddenLayers + } + } + return hiddenLayers + } + + private func isHang(to target: CALayer) -> Bool { + var layer = superlayer + while layer != nil { + if layer == target { + return true + } + layer = layer?.superlayer + } + return false + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGContext+CGImage.swift b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGContext+CGImage.swift new file mode 100644 index 00000000..84808b28 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGContext+CGImage.swift @@ -0,0 +1,33 @@ +// +// CGContext+CGImage.swift +// DynamicBlurView +// +// Created by Kyohei Ito on 2017/08/17. +// Copyright © 2017年 kyohei_ito. All rights reserved. +// + +import UIKit + +extension CGContext { + static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? { + UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale) + guard let context = UIGraphicsGetCurrentContext() else { + return nil + } + + context.translateBy(x: -rect.origin.x, y: -rect.origin.y) + context.interpolationQuality = quality.interpolationQuality + + return context + } + + func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? { + if let color = blendColor { + setFillColor(color.cgColor) + setBlendMode(blendMode) + fill(CGRect(origin: .zero, size: size)) + } + + return makeImage() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGImage+Accelerate.swift b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGImage+Accelerate.swift new file mode 100644 index 00000000..7931e31a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/CGImage+Accelerate.swift @@ -0,0 +1,66 @@ +// +// CGImage+Accelerate.swift +// DynamicBlurView +// +// Created by Kyohei Ito on 2017/08/17. +// Copyright © 2017年 kyohei_ito. All rights reserved. +// + +import Accelerate +import UIKit + +extension CGImage { + var area: Int { + return width * height + } + + private var size: CGSize { + return CGSize(width: width, height: height) + } + + private var bytes: Int { + return bytesPerRow * height + } + + private func imageBuffer(from data: UnsafeMutableRawPointer!) -> vImage_Buffer { + return vImage_Buffer(data: data, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: bytesPerRow) + } + + func blurred(with boxSize: UInt32, iterations: Int, blendColor: UIColor?, blendMode: CGBlendMode) -> CGImage? { + guard let providerData = dataProvider?.data else { + return nil + } + + let inData = malloc(bytes) + var inBuffer = imageBuffer(from: inData) + + let outData = malloc(bytes) + var outBuffer = imageBuffer(from: outData) + + let tempSize = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend + kvImageGetTempBufferSize)) + let tempData = malloc(tempSize) + + defer { + free(inData) + free(outData) + free(tempData) + } + + let source = CFDataGetBytePtr(providerData) + memcpy(inBuffer.data, source, bytes) + + for _ in 0.. + +//! Project version number for DynamicBlurView. +FOUNDATION_EXPORT double DynamicBlurViewVersionNumber; + +//! Project version string for DynamicBlurView. +FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.swift b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.swift new file mode 100644 index 00000000..5b9fbb84 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/DynamicBlurView.swift @@ -0,0 +1,195 @@ +// +// DynamicBlurView.swift +// DynamicBlurView +// +// Created by Kyohei Ito on 2015/04/08. +// Copyright (c) 2015年 kyohei_ito. All rights reserved. +// + +import UIKit + +open class DynamicBlurView: UIView { + open override class var layerClass : AnyClass { + return BlurLayer.self + } + + private var staticImage: UIImage? + private var displayLink: CADisplayLink? + private var blurLayer: BlurLayer { + return layer as! BlurLayer + } + private let mainQueue = DispatchQueue.main + private let globalQueue: DispatchQueue = { + if #available (iOS 8.0, *) { + return .global(qos: .userInteractive) + } else { + return .global(priority: .high) + } + }() + private var renderingTarget: UIView? { + if isDeepRendering { + return window + } else { + return superview + } + } + + /// When true, it captures displays image and blur it asynchronously. Try to set true if needs more performance. + /// Asynchronous drawing is possibly crash when needs to process on main thread that drawing with animation for example. + open var drawsAsynchronously: Bool = false + /// Radius of blur. + open var blurRadius: CGFloat { + set { blurLayer.blurRadius = newValue } + get { return blurLayer.blurRadius } + } + /// Default is none. + open var trackingMode: TrackingMode = .none { + didSet { + if trackingMode != oldValue { + linkForDisplay() + } + } + } + /// Blend color. + open var blendColor: UIColor? + /// Blend mode. + open var blendMode: CGBlendMode = .plusLighter + /// Default is 3. + open var iterations: Int = 3 + /// If the view want to render beyond the layer, should be true. + open var isDeepRendering: Bool = false + /// When none of tracking mode, it can change the radius of blur with the ratio. Should set from 0 to 1. + open var blurRatio: CGFloat = 1 { + didSet { + if let image = staticImage, oldValue != blurRatio { + draw(image, blurRadius: blurRadius, fixes: false, baseLayer: renderingTarget?.layer) + } + } + } + /// Quality of captured image. + open var quality: CaptureQuality = .medium + + public override init(frame: CGRect) { + super.init(frame: frame) + isUserInteractionEnabled = false + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + isUserInteractionEnabled = false + } + + open override func didMoveToWindow() { + super.didMoveToWindow() + + if let view = renderingTarget, window != nil && trackingMode == .none { + staticImage = snapshotImage(for: view.layer, conversion: !isDeepRendering) + } + } + + open override func didMoveToSuperview() { + super.didMoveToSuperview() + + if superview == nil { + displayLink?.invalidate() + displayLink = nil + } else { + linkForDisplay() + } + } + + private func async(on queue: DispatchQueue, actions: @escaping () -> Void) { + if drawsAsynchronously { + queue.async(execute: actions) + } else { + actions() + } + } + + private func sync(on queue: DispatchQueue, actions: () -> Void) { + if drawsAsynchronously { + queue.sync(execute: actions) + } else { + actions() + } + } + + private func draw(_ image: UIImage, blurRadius radius: CGFloat, fixes isFixes: Bool, baseLayer: CALayer?) { + async(on: globalQueue) { [weak self] in + if let me = self, let blurredImage = image.blurred(radius: radius, iterations: me.iterations, ratio: me.blurRatio, blendColor: me.blendColor, blendMode: me.blendMode) { + me.sync(on: me.mainQueue) { + me.blurLayer.draw(blurredImage, fixes: isFixes, baseLayer: baseLayer) + } + } + } + } + + private func blurLayerRect(to layer: CALayer, conversion: Bool) -> CGRect { + if conversion { + let presentationLayer = blurLayer.presentation() ?? blurLayer + return presentationLayer.convert(presentationLayer.bounds, to: layer) + } else { + return layer.bounds + } + } + + private func snapshotImage(for layer: CALayer, conversion: Bool) -> UIImage? { + let rect = blurLayerRect(to: layer, conversion: conversion) + guard let context = CGContext.imageContext(with: quality, rect: rect, opaque: isOpaque) else { + return nil + } + + blurLayer.render(in: context, for: layer) + + defer { + UIGraphicsEndImageContext() + } + + return UIGraphicsGetImageFromCurrentImageContext() + } +} + +extension DynamicBlurView { + open override func display(_ layer: CALayer) { + let blurRadius = blurLayer.presentationRadius + let isFixes = isDeepRendering && staticImage != nil + if let view = renderingTarget, let image = staticImage ?? snapshotImage(for: view.layer, conversion: !isFixes) { + draw(image, blurRadius: blurRadius, fixes: isFixes, baseLayer: view.layer) + } + } +} + +extension DynamicBlurView { + private func linkForDisplay() { + displayLink?.invalidate() + displayLink = UIScreen.main.displayLink(withTarget: self, selector: #selector(DynamicBlurView.displayDidRefresh(_:))) + displayLink?.add(to: .main, forMode: RunLoop.Mode(rawValue: trackingMode.description)) + } + + @objc private func displayDidRefresh(_ displayLink: CADisplayLink) { + display(layer) + } +} + +extension DynamicBlurView { + /// Remove cache of blur image then get it again. + open func refresh() { + blurLayer.refresh() + staticImage = nil + blurRatio = 1 + display(layer) + } + + /// Remove cache of blur image. + open func remove() { + blurLayer.refresh() + staticImage = nil + blurRatio = 1 + layer.contents = nil + } + + /// Should use when needs to change layout with animation when is set none of tracking mode. + public func animate() { + blurLayer.animate() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/TrackingMode.swift b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/TrackingMode.swift new file mode 100644 index 00000000..a61a78da --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/TrackingMode.swift @@ -0,0 +1,27 @@ +// +// TrackingMode.swift +// DynamicBlurView +// +// Created by Kyohei Ito on 2017/08/17. +// Copyright © 2017年 kyohei_ito. All rights reserved. +// + +import UIKit + +public enum TrackingMode: CustomStringConvertible { + case tracking + case common + case none + + public var description: String { + switch self { + case .tracking: + return RunLoop.Mode.tracking.rawValue + case .common: + return RunLoop.Mode.common.rawValue + case .none: + return "" + } + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/UIImage+Blur.swift b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/UIImage+Blur.swift new file mode 100644 index 00000000..324aa911 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/DynamicBlurView/Sources/DynamicBlurView/UIImage+Blur.swift @@ -0,0 +1,30 @@ +// +// UIImage+Blur.swift +// DynamicBlurView +// +// Created by Kyohei Ito on 2017/08/11. +// Copyright © 2017年 kyohei_ito. All rights reserved. +// + +import UIKit + +public extension UIImage { + func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? { + guard let cgImage = cgImage else { + return nil + } + + if cgImage.area <= 0 || radius <= 0 { + return self + } + + var boxSize = UInt32(radius * scale * ratio) + if boxSize % 2 == 0 { + boxSize += 1 + } + + return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map { + UIImage(cgImage: $0, scale: scale, orientation: imageOrientation) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/LICENSE b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/LICENSE new file mode 100644 index 00000000..02de8f49 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/README.md b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/README.md new file mode 100644 index 00000000..3f2cf1ef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/README.md @@ -0,0 +1,299 @@ + +![FCL Swift](./docs-asset/FCL-Swift.jpg) + + + + +## What is FCL? + +The Flow Client Library (FCL) is used to interact with user wallets and the Flow blockchain. When using FCL for authentication, dApps are able to support all FCL-compatible wallets on Flow and their users without any custom integrations or changes needed to the dApp code. + +For more description, please refer to [fcl.js](https://github.com/onflow/fcl-js) + +This repo is inspired by [fcl-js](https://github.com/onflow/fcl-js) and [fcl-swift](https://github.com/Outblock/fcl-swift) + +--- +## Getting Started + +### Requirements +- Swift version >= 5.6 +- iOS version >= 13 + +## Installation + +### CocoaPods + +FCL-SDK is available through [CocoaPods](https://cocoapods.org). You can include specific subspec to install, simply add the following line to your Podfile: + +```ruby +pod 'FCL-SDK', '~> 0.3.3' +``` + +### Swift Package Manager + + +```swift +.package(url: "https://github.com/portto/fcl-swift.git", .upToNextMinor(from: "0.3.3")) +``` + +Here's an example PackageDescription: + +```swift +// swift-tools-version: 5.6 +import PackageDescription + +let package = Package( + name: "MyPackage", + products: [ + .library( + name: "MyPackage", + targets: ["MyPackage"] + ), + ], + dependencies: [ + .package(url: "https://github.com/portto/fcl-swift.git", .upToNextMinor(from: "0.3.3")) + ], + targets: [ + .target( + name: "MyPackage", + dependencies: [ + .product(name: "FCL_SDK", package: "fcl-swift"), + ] + ) + ] +) +``` + +### Platform + +We only support iOS platform now. Please switch your XCode build target to iOS device. + + +### Importing + +```swift +import FCL_SDK +``` +--- +## FCL for dApps +### Configuration + +Initialize `WalletProvider` instance e.g. `BloctoWalletProvider`, `DapperWalletProvider`. And simply specify `network` and put those wallet providers into config option `supportedWalletProviders` then you are good to go. + +```swift +import FCL_SDK + +do { + let bloctoWalletProvider = try BloctoWalletProvider( + bloctoAppIdentifier: bloctoSDKAppId, + window: nil, + network: .testnet + ) + fcl.config + .put(.network(.testnet)) + .put(.supportedWalletProviders( + [ + bloctoWalletProvider, + ] + )) +} catch { + // handle error +} + +Task { + try await fcl.login() +} +``` + +> **Note**: bloctoSDKAppId can be found in [Blocto Developer Dashboard](https://developers.blocto.app/), for detail instruction please refer to [Blocto Docs](https://docs.blocto.app/blocto-sdk/register-app-id) + +### User Signatures + +Cryptographic signatures are a key part of the blockchain. They are used to prove ownership of an address without exposing its private key. While primarily used for signing transactions, cryptographic signatures can also be used to sign arbitrary messages. + +FCL has a feature that let you send arbitrary data to a configured wallet/service where the user may approve signing it with their private keys. + +We can retrieve user signatures only after user had logged in, otherwise error will be thrown. + +```swift +Task { + do { + let signatures: [FCLCompositeSignature] = try await fcl.signUserMessage(message: "message you want user to sign.") + } catch { + // handle error + } +} +``` + +The message could be signed by several private key of the same wallet address. Those signatures will be valid all together as long as their corresponding key weight sum up at least 1000. +For more info about multiple signatures, please refer to [Flow docs](https://developers.flow.com/learn/concepts/accounts-and-keys#single-party-multiple-signatures) + + +### Blockchain Interactions +- *Query the chain*: Send arbitrary Cadence scripts to the chain and receive back decoded values +```swift +import FCL_SDK + +let script = """ +import ValueDapp from \(valueDappContract) + +pub fun main(): UFix64 { + return ValueDapp.value +} +""" + +Task { + let argument = try await fcl.query(script: script) + label.text = argument.value.description +} +``` +- *Mutate the chain*: Send arbitrary transactions with specify authorizer to perform state changes on chain. +```swift +import FCL_SDK + +Task { @MainActor in + guard let userWalletAddress = fcl.currentUser?.address else { + // handle error + return + } + + let scriptString = """ + import ValueDapp from 0x5a8143da8058740c + + transaction(value: UFix64) { + prepare(authorizer: AuthAccount) { + ValueDapp.setValue(value) + } + } + """ + + let argument = Cadence.Argument(.ufix64(10)) + + let txHsh = try await fcl.mutate( + cadence: scriptString, + arguments: [argument], + limit: 100, + authorizers: [userWalletAddress] + ) +} +``` + +[Learn more about on-chain interactions >](https://docs.onflow.org/fcl/reference/api/#on-chain-interactions) + +--- +## Prove ownership +To prove ownership of a wallet address, there are two approaches. +- Account proof: in the beginning of authentication, there are `accountProofData` you can provide for user to sign and return generated signatures along with account address. + +`fcl.authanticate` is also called behide `fcl.login()` with accountProofData set to nil. + +```swift +let accountProofData = FCLAccountProofData( + appId: "Here you can specify your app name.", + nonce: "75f8587e5bd5f9dcc9909d0dae1f0ac5814458b2ae129620502cb936fde7120a" // minimum 32-byte random nonce as a hex string. +) +let address = try await fcl.authanticate(accountProofData: accountProofData) +``` + +- [User signature](#User-Signatures): provide specific message for user to sign and generate one or more signatures. + +### Verifying User Signatures + +What makes message signatures more interesting is that we can use Flow blockchain to verify the signatures. Cadence has a built-in function called verify that will verify a signature against a Flow account given the account address. + +FCL includes a utility function, verifyUserSignatures, for verifying one or more signatures against an account's public key on the Flow blockchain. + +You can use both in tandem to prove a user is in control of a private key or keys. This enables cryptographically-secure login flow using a message-signing-based authentication mechanism with a user’s public address as their identifier. + +To verify above ownership, there are two utility functions define accordingly in [AppUtilities](https://github.com/portto/fcl-swift/blob/main/Sources/FCL-SDK/AppUtilities/AppUtilities.swift). + +--- +## Utilities +- Get account details from any Flow address +```swift +let account: Account? = try await fcl.flowAPIClient.getAccountAtLatestBlock(address: address) +``` +- Get the latest block +```swift +let block: Block? = try await fcl.flowAPIClient.getLatestBlock(isSealed: true) +``` +- Transaction status polling +```swift +let result = try await fcl.getTransactionStatus(transactionId: txHash) +``` + +[Learn more about utilities >](https://docs.onflow.org/fcl/reference/api/#pre-built-interactions) + +--- +## FCL for Wallet Providers +Wallet providers on Flow have the flexibility to build their user interactions and UI through a variety of ways: +- Native app intercommunication via Universal links or custom schemes. +- Back channel communication via HTTP polling with webpage button approving. + +FCL is agnostic to the communication channel and be configured to create both custodial and non-custodial wallets. This enables users to interact with wallet providers both native app install or not. + +Native app should be considered first to provide better user experience if installed, otherwise fallback to back channel communication. + +The communication channels involve responding to a set of pre-defined FCL messages to deliver the requested information to the dApp. Implementing a FCL compatible wallet on Flow is as simple as filling in the responses with the appropriate data when FCL requests them. + + +### Current Wallet Providers +- [Blocto](https://blocto.portto.io/en/) (fully supported) [Docs](https://docs.blocto.app/blocto-sdk/ios-sdk/flow) +- [Dapper Wallet](https://www.meetdapper.com/) (support only authn for now) + +### Wallet Selection +- dApps can display and support all FCL compatible wallets who conform to `WalletProvider`. +- Users don't need to sign up for new wallets - they can carry over their existing one to any dApps that use FCL for authentication and authorization. +- Wallet selection panel will be shown automatically when `login()` is being called only if there are more than one wallet provider in `supportedWalletProviders`. + + +```swift +import FCL_SDK + +do { + let bloctoWalletProvider = try BloctoWalletProvider( + bloctoAppIdentifier: bloctoSDKAppId, + window: nil, + network: .testnet + ) + let dapperWalletProvider = DapperWalletProvider.default + fcl.config + .put(.network(.testnet)) + .put(.supportedWalletProviders( + [ + bloctoWalletProvider, + dapperWalletProvider, + ] + )) +} catch { + // handle error +} + +Task { + try await fcl.login() +} +``` + +### Building your own wallet provider + +- Declare a wallet provider type and conform the protocol [WalletProvider](./Sources/FCL-SDK/WalletProvider/WalletProvider.swift). +- If building a wallet involve back channel communication, read the [wallet guide](https://github.com/onflow/fcl-js/blob/master/packages/fcl/src/wallet-provider-spec/draft-v3.md) first to build the concept of the implementation and use method from `WalletProvider` to fulfill your business logic. + +Every walllet provider can use below property from `WalletProvider` to customize icon, title and description. Those info will be shown [here](#wallet-selection). +``` +var providerInfo: ProviderInfo { get } +``` + +--- + +## Next Steps + +Learn Flow's smart contract language to build any script or transactions: [Cadence](https://docs.onflow.org/cadence/). + +Explore all of Flow [docs and tools](https://docs.onflow.org). + +--- + +## Support + +Notice a problem or want to request a feature? [Add an issue](https://github.com/portto/fcl-swift/issues) or [Make a pull request](https://github.com/portto/fcl-swift/compare). diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/AppUtilities/AppUtilities.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/AppUtilities/AppUtilities.swift new file mode 100644 index 00000000..82c01c9d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/AppUtilities/AppUtilities.swift @@ -0,0 +1,141 @@ +// +// AppUtilities.swift +// +// +// Created by Andrew Wang on 2022/7/11. +// + +import Foundation +import Cadence +import BigInt +import FlowSDK + +public enum AppUtilities { + + public static func verifyAccountProof( + appIdentifier: String, + accountProofData: AccountProofVerifiable, + fclCryptoContract: Address? + ) async throws -> Bool { + let verifyMessage = WalletUtilities.encodeAccountProof( + address: accountProofData.address, + nonce: accountProofData.nonce, + appIdentifier: appIdentifier, + includeDomainTag: false + ) + + var indices: [Cadence.Argument] = [] + var siganature: [Cadence.Argument] = [] + for signature in accountProofData.signatures { + indices.append(.int(BigInt(signature.keyId))) + siganature.append(.string(signature.signature)) + } + + let arguments: [Cadence.Argument] = [ + .address(accountProofData.address), + .string(verifyMessage), + .array(indices), + .array(siganature), + ] + + let verifyScript = try getVerifySignaturesScript( + isAccountProof: true, + fclCryptoContract: fclCryptoContract + ) + let result = try await fcl.query( + script: verifyScript, + arguments: arguments + ) + guard case let .bool(valid) = result.value else { + throw FCLError.unexpectedResult + } + return valid + } + + public static func verifyUserSignatures( + message: String, + signatures: [CompositeSignatureVerifiable], + fclCryptoContract: Address? + ) async throws -> Bool { + + guard let address = signatures.first?.address else { + throw FCLError.compositeSignatureInvalid + } + + var indices: [Cadence.Argument] = [] + var siganature: [Cadence.Argument] = [] + for signature in signatures { + indices.append(.int(BigInt(signature.keyId))) + siganature.append(.string(signature.signature)) + } + + let arguments: [Cadence.Argument] = [ + .address(Address(hexString: address)), + .string(message), + .array(indices), + .array(siganature), + ] + + let verifyScript = try getVerifySignaturesScript( + isAccountProof: false, + fclCryptoContract: fclCryptoContract + ) + let result = try await fcl.query( + script: verifyScript, + arguments: arguments + ) + guard case let .bool(valid) = result.value else { + throw FCLError.unexpectedResult + } + return valid + } + + static func accountProofContractAddress( + network: Network + ) throws -> Address { + switch network { + case .mainnet: + return Address(hexString: "0xb4b82a1c9d21d284") + case .testnet: + return Address(hexString: "0x74daa6f9c7ef24b1") + case .canarynet, + .sandboxnet, + .emulator: + throw FCLError.currentNetworkNotSupported + } + } + + static func getVerifySignaturesScript( + isAccountProof: Bool, + fclCryptoContract: Address? + ) throws -> String { + let contractAddress: Address + if let fclCryptoContract = fclCryptoContract { + contractAddress = fclCryptoContract + } else { + contractAddress = try accountProofContractAddress(network: fcl.config.network) + } + + let verifyFunction = isAccountProof + ? "verifyAccountProofSignatures" + : "verifyUserSignatures" + + return """ + import FCLCrypto from \(contractAddress.hexStringWithPrefix) + + pub fun main( + address: Address, + message: String, + keyIndices: [Int], + signatures: [String] + ): Bool { + return FCLCrypto.\(verifyFunction)( + address: address, + message: message, + keyIndices: keyIndices, + signatures: signatures) + } + """ + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AddressReplacement.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AddressReplacement.swift new file mode 100644 index 00000000..f56f4617 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AddressReplacement.swift @@ -0,0 +1,27 @@ +// +// AddressReplacement.swift +// FCL +// +// Created by Andrew Wang on 2022/6/29. +// + +import Foundation +import Cadence + +struct AddressReplacement: Hashable { + + let placeholder: String + let replacement: Address + + public init( + placeholder: String, + replacement: Address + ) { + self.placeholder = placeholder + self.replacement = replacement + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(placeholder) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AppDetail.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AppDetail.swift new file mode 100644 index 00000000..57ac375b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/AppDetail.swift @@ -0,0 +1,44 @@ +// +// AppDetail.swift +// FCL +// +// Created by Andrew Wang on 2022/6/29. +// + +import Foundation +import SwiftyJSON + +public struct AppDetail: Encodable { + + let title: String + let icon: URL? + var custom: [String: Encodable] = [:] + + enum CodingKeys: String, CodingKey { + case title + case icon + } + + public init( + title: String, + icon: URL?, + custom: [String: Encodable] = [:] + ) { + self.title = title + self.icon = icon + self.custom = custom + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(title, forKey: .title) + try container.encode(icon, forKey: .icon) + var dynamicContainer = encoder.container(keyedBy: DynamicKey.self) + for (key, value) in custom { + if let codingKey = DynamicKey(stringValue: key) { + try dynamicContainer.encode(value, forKey: codingKey) + } + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/Config.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/Config.swift new file mode 100644 index 00000000..65f0aaf4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Config/Config.swift @@ -0,0 +1,108 @@ +// +// Config.swift +// +// +// Created by Andrew Wang on 2022/6/24. +// + +import Foundation +import FlowSDK +import Cadence + +public enum WalletSelection { + case authn(URL) + case discoveryWallets([WalletProvider]) +} + +public enum Scope: String, Encodable { + case email + case name +} + +public class Config { + + var network: Network = .testnet + + var appDetail: AppDetail? + + var walletProviderCandidates: [WalletProvider] = [] + + var selectedWalletProvider: WalletProvider? + + var addressReplacements: Set = [] + + var computeLimit: UInt64 = defaultComputeLimit + + /// To switch on and off for logging message + var logging: Bool = true + + var openIdScopes: [Scope] = [] + + public enum Option { + @available(*, unavailable, renamed: "network", message: "Use network instead.") + case env(String) + case network(Network) + + case appDetail(AppDetail) + + @available(*, unavailable, renamed: "wallets", message: "Use supportedWalletProviders instead.") + case challengeHandshake + // Wallet Discovery mechanism + case supportedWalletProviders([WalletProvider]) + + case replace(placeHolder: String, with: Address) + + case computeLimit(UInt64) + + case logging(Bool) + + // User info + /* TODO: implementation + case challengeScope "challenge.scope" + case openId([Scope]) + */ + } + + @discardableResult + public func put(_ option: Option) throws -> Self { + switch option { + case let .network(network): + self.network = network + try walletProviderCandidates.forEach { + try $0.updateNetwork(network) + } + case .env: + break + case let .appDetail(appDetail): + self.appDetail = appDetail + case .challengeHandshake: + break + case let .supportedWalletProviders(walletProviders): + walletProviderCandidates = walletProviders + if walletProviders.count == 1, + let firstProvider = walletProviders.first { + selectedWalletProvider = firstProvider + } + try walletProviderCandidates.forEach { + try $0.updateNetwork(network) + } + case let .replace(placeholder, replacement): + let addressReplacement = AddressReplacement(placeholder: placeholder, replacement: replacement) + addressReplacements.insert(addressReplacement) + case let .computeLimit(limit): + computeLimit = limit + case let .logging(enable): + logging = enable + /* TODO: implementation + case let .openId(scopes): + openIdScopes = scopes + */ + } + return self + } + + public func reset() { + selectedWalletProvider = nil + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Constants.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Constants.swift new file mode 100644 index 00000000..6d85ed26 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Constants.swift @@ -0,0 +1,12 @@ +// +// Constants.swift +// +// +// Created by Andrew Wang on 2022/6/29. +// + +import Foundation + +enum Constants { + static let fclVersion = "1.0.0" +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/CadenceArgumentExtension.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/CadenceArgumentExtension.swift new file mode 100644 index 00000000..7c946fe4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/CadenceArgumentExtension.swift @@ -0,0 +1,41 @@ +// +// CadenceArgumentExtension.swift +// FCL +// +// Created by Andrew Wang on 2022/7/27. +// + +import Foundation +import Cadence + +extension Cadence.Argument { + + func toFCLArgument() -> Argument { + func randomString(length: Int) -> String { + let letters = "abcdefghijklmnopqrstuvwxyz0123456789" + return String((0 ..< length).map { _ in letters.randomElement()! }) + } + + return Argument( + kind: "ARGUMENT", + tempId: randomString(length: 10), + value: value, + asArgument: self, + xform: Xform(label: type.rawValue) + ) + } + +} + +extension Array where Element == Cadence.Argument { + + func toFCLArguments() -> [(String, Argument)] { + var list = [(String, Argument)]() + forEach { arg in + let fclArg = arg.toFCLArgument() + list.append((fclArg.tempId, fclArg)) + } + return list + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/Extensions.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/Extensions.swift new file mode 100644 index 00000000..07a47cb5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/Extensions.swift @@ -0,0 +1,96 @@ +// +// Extensions.swift +// FCL +// +// Created by Andrew Wang on 2022/7/27. +// + +import Foundation + +extension Array where Element: Hashable { + func uniqued() -> [Element] { + var seen = Set() + return filter { seen.insert($0).inserted } + } +} + +extension String { + + public var hexDecodedData: Data { + // Convert to a CString and make sure it has an even number of characters (terminating 0 is included, so we + // check for uneven!) + guard let cString = cString(using: .ascii), (cString.count % 2) == 1 else { + return Data() + } + + var result = Data(capacity: (cString.count - 1) / 2) + for i in stride(from: 0, to: cString.count - 1, by: 2) { + guard let l = hexCharToByte(cString[i]), + let r = hexCharToByte(cString[i + 1]) else { + return Data() + } + var value: UInt8 = (l << 4) | r + result.append(&value, count: MemoryLayout.size(ofValue: value)) + } + return result + } + + func sansPrefix() -> String { + if hasPrefix("0x") || hasPrefix("Fx") { + return String(dropFirst(2)) + } + return self + } + + private func hexCharToByte(_ c: CChar) -> UInt8? { + if c >= 48 && c <= 57 { // 0 - 9 + return UInt8(c - 48) + } + if c >= 97 && c <= 102 { // a - f + return UInt8(10) + UInt8(c - 97) + } + if c >= 65 && c <= 70 { // A - F + return UInt8(10) + UInt8(c - 65) + } + return nil + } + +} + +extension URLRequest { + + func toReadable() -> String { + var result = httpMethod ?? "" + result.append("\n\n") + let urlString = url?.absoluteString ?? "" + + result.append(urlString) + result.append("\n\n") + do { + if let header = allHTTPHeaderFields { + let headerData = try JSONSerialization.data(withJSONObject: header, options: .prettyPrinted) + result.append(String(data: headerData, encoding: .utf8) ?? "") + result.append("\n\n") + } + if let body = httpBody { + let object = try JSONSerialization.jsonObject(with: body, options: .fragmentsAllowed) + let bodyData = try JSONSerialization.data(withJSONObject: object, options: .prettyPrinted) + result.append(String(data: bodyData, encoding: .utf8) ?? "") + result.append("\n\n") + } + } catch { + debugPrint(error) + } + return result + } + +} + +extension Data { + + func prettyData() throws -> Data { + let object = try JSONSerialization.jsonObject(with: self, options: .fragmentsAllowed) + return try JSONSerialization.data(withJSONObject: object, options: .prettyPrinted) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/TaskExtension.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/TaskExtension.swift new file mode 100644 index 00000000..54c84244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Extensions/TaskExtension.swift @@ -0,0 +1,18 @@ +// +// TaskExtension.swift +// +// +// Created by Andrew Wang on 2022/7/6. +// + +import Foundation + +extension Task where Success == Never, Failure == Never { + + public + static func sleep(seconds: Double) async throws { + let duration = UInt64(seconds * 1_000_000_000) + try await Task.sleep(nanoseconds: duration) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCL.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCL.swift new file mode 100644 index 00000000..63652886 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCL.swift @@ -0,0 +1,493 @@ +// +// FCL.swift +// +// +// Created by Andrew Wang on 2022/6/24. +// + +import Foundation +import FlowSDK +import Cadence +import AuthenticationServices +import GRPC + +public let fcl: FCL = FCL() + +func log( + message: String +) { + guard fcl.config.logging else { return } + print("🚀 FCL: " + message) +} + +public class FCL: NSObject { + + public let config = Config() + public var delegate: FCLDelegate? + + var flowAPIClient: Client { + get async throws { + let task = Task(priority: .utility) { + Client(network: config.network) + } + return await task.value + } + } + + private var webAuthSession: ASWebAuthenticationSession? + private let requestSession = URLSession(configuration: .default) + + public var currentUser: User? + + override init() { + super.init() + } + + public func config( + provider: WalletProvider + ) {} + + public func login() async throws -> Address { + try await authanticate(accountProofData: nil) + } + + public func logout() { + unauthenticate() + } + + public func relogin() async throws -> Address { + logout() + return try await login() + } + + // Authn + public func authanticate(accountProofData: FCLAccountProofData?) async throws -> Address { + do { + let walletProvider: WalletProvider + if let provider = config.selectedWalletProvider { + walletProvider = provider + } else { + if config.walletProviderCandidates.isEmpty == false { + walletProvider = try await selectionProvider() + fcl.config.selectedWalletProvider = walletProvider + } else { + throw FCLError.walletProviderNotSpecified + } + } + try await walletProvider.authn(accountProofData: accountProofData) + guard let user = currentUser else { + throw FCLError.userNotFound + } + return user.address + } catch { + fcl.config.reset() + throw error + } + } + + public func unauthenticate() { + currentUser = nil + config.reset() + } + + public func reauthenticate(accountProofData: FCLAccountProofData?) async throws -> Address { + unauthenticate() + return try await authanticate(accountProofData: accountProofData) + } + + // User signature + public func signUserMessage(message: String) async throws -> [FCLCompositeSignature] { + guard let walletProvider = config.selectedWalletProvider else { + throw FCLError.walletProviderNotSpecified + } + return try await walletProvider.getUserSignature(message) + } + + // MARK: - Routing + + public func continueForLinks(_ userActivity: NSUserActivity) { + config.selectedWalletProvider?.continueForLinks(userActivity) + } + + public func application(open url: URL) { + config.selectedWalletProvider?.application(open: url) + } + + // MARK: Internal + + func serviceOfType(type: ServiceType) throws -> Service? { + guard let currentUser = currentUser else { + throw FCLError.userNotFound + } + return currentUser.services.first(where: { $0.type == type }) + } + + func openWithWebAuthenticationSession(_ service: Service) throws { + let request = try service.getURLRequest() + + guard let url = request.url else { + throw FCLError.urlNotFound + } + + log(message: "About to open ASWebAuthenticationSession with \(url.absoluteString)") + + let session = ASWebAuthenticationSession( + url: url, + callbackURLScheme: nil, + completionHandler: { [weak self] _, _ in + self?.webAuthSession?.cancel() + self?.webAuthSession = nil + } + ) + + session.presentationContextProvider = self + + webAuthSession = session + + let startsSuccessfully = session.start() + if startsSuccessfully == false { + throw FCLError.authenticateFailed + } + } + + func polling(service: Service, data: Data? = nil) async throws -> AuthResponse { + let request = try service.getURLRequest(body: data) + guard let type = service.type else { + throw FCLError.serviceTypeNotFound + } + return try await pollingRequest(request, type: type) + } + + func pollingRequest(_ request: URLRequest, type: ServiceType) async throws -> AuthResponse { + let authnResponse: AuthResponse = try await requestSession.dataAuthnResponse(for: request) + switch authnResponse.status { + case .pending: + switch type { + case .authn, + .userSignature: + guard let localView = authnResponse.local, + let backChannel = authnResponse.updates else { + throw FCLError.serviceError + } + let openBrowserTask = Task { @MainActor in + try openWithWebAuthenticationSession(localView) + } + _ = try await openBrowserTask.result.get() + try await Task.sleep(seconds: 1) + return try await polling(service: backChannel) + case .authz: + // blocto non custodial respond with updates. + guard let localView = authnResponse.local, + let backChannel = authnResponse.authorizationUpdates ?? authnResponse.updates else { + throw FCLError.serviceError + } + let openBrowserTask = Task { @MainActor in + try openWithWebAuthenticationSession(localView) + } + _ = try await openBrowserTask.result.get() + try await Task.sleep(seconds: 1) + let backChannelRequest = try backChannel.getURLRequest() + return try await pollingRequest(backChannelRequest, type: .backChannel) + case .backChannel: + if webAuthSession == nil { + throw FCLError.userCanceled + } + try await Task.sleep(seconds: 1) + return try await pollingRequest(request, type: type) + case .localView, + .preAuthz, + .openId, + .accountProof, + .authnRefresh: + throw FCLError.serviceError + } + case .approved, .declined: + Task { @MainActor in + webAuthSession?.cancel() + webAuthSession = nil + } + return authnResponse + } + } + + func buildUser(authn: AuthResponse) throws -> User { + guard let address: String = authn.data?.address else { + throw FCLError.authenticateFailed + } + return User( + address: Address(hexString: address), + accountProof: nil, + loggedIn: true, + expiresAt: 0, + services: authn.data?.services ?? [] + ) + } + + func getKeyWindow() -> UIWindow? { + UIApplication.shared.connectedScenes + .filter { $0.activationState == .foregroundActive } + .compactMap { $0 as? UIWindowScene } + .first?.windows + .filter(\.isKeyWindow).first + } + + @MainActor + private func selectionProvider() async throws -> WalletProvider { + guard let keyWindow = getKeyWindow() else { + throw FCLError.walletProviderInitFailed + } + return try await withCheckedThrowingContinuation { continuation in + let selectionViewController = WalletProviderSelectionViewController(providers: fcl.config.walletProviderCandidates) + selectionViewController.presentationController?.delegate = selectionViewController + selectionViewController.onSelect = { [weak selectionViewController] provider in + selectionViewController?.dismiss(animated: true) + continuation.resume(returning: provider) + } + selectionViewController.onCancel = { [weak selectionViewController] in + selectionViewController?.dismiss(animated: true) + continuation.resume(throwing: FCLError.userCanceled) + } + guard let topViewController = topViewController(from: keyWindow) else { + continuation.resume(throwing: FCLError.walletProviderInitFailed) + return + } + topViewController.present(selectionViewController, animated: true) + } + } + + private func topViewController(from window: UIWindow) -> UIViewController? { + var topController: UIViewController? = window.rootViewController + while let presentedViewController = window.rootViewController?.presentedViewController { + topController = presentedViewController + } + return topController + } + +} + +// MARK: ASWebAuthenticationPresentationContextProviding + +extension FCL: ASWebAuthenticationPresentationContextProviding { + + public func presentationAnchor(for _: ASWebAuthenticationSession) -> ASPresentationAnchor { + delegate?.webAuthenticationContextProvider() ?? ASPresentationAnchor() + } + +} + +// MARK: - Transaction Build + +extension FCL { + + func send(_ builds: [TransactionBuild]) async throws -> Identifier { + let ix = prepare(ix: Interaction(), builder: builds) + + let resolvers: [Resolver] = [ + CadenceResolver(), + AccountsResolver(), + RefBlockResolver(), + SequenceNumberResolver(), + SignatureResolver(), + ] + + let interaction = try await pipe(ix: ix, resolvers: resolvers) + return try await sendIX(ix: interaction) + } + + func send(@FCL.TransactionBuilder builder: () -> [TransactionBuild]) async throws -> Identifier { + try await send(builder()) + } + + func prepare(ix: Interaction, builder: [TransactionBuild]) -> Interaction { + var newIX = ix + + builder.forEach { build in + switch build { + case let .transaction(script): + newIX.tag = .transaction + newIX.message.cadence = script + case let .arguments(args): + let fclArgs = args.toFCLArguments() // .compactMap { Flow.Argument(value: $0) }.toFCLArguments() + newIX.message.arguments = Array(fclArgs.map(\.0)) + newIX.arguments = fclArgs.reduce(into: [:]) { $0[$1.0] = $1.1 } + case let .computeLimit(gasLimit): + newIX.message.computeLimit = gasLimit + } + } + + newIX = setComputeLimitIfNeeded(ix: newIX, builder: builder) + + newIX.status = .ok + + return newIX + } + + private func setComputeLimitIfNeeded(ix: Interaction, builder: [TransactionBuild]) -> Interaction { + var newIX = ix + let computeLimitCase = builder.first(where: { + if case .computeLimit = $0 { + return true + } else { + return false + } + }) + + if computeLimitCase == nil { + newIX.message.computeLimit = fcl.config.computeLimit + } + return newIX + } + +} + +public extension FCL { + + enum TransactionBuild { + case transaction(script: String) + case arguments([Cadence.Argument]) + case computeLimit(UInt64) + + // TODO: support custom proposer and authorizer + /* + case proposer(Transaction.ProposalKey) + case payer([TransactionFeePayer]) + case authorizers([]) + */ + } + + @resultBuilder + enum TransactionBuilder { + public static func buildBlock() -> [TransactionBuild] { [] } + + public static func buildArray(_ components: [[TransactionBuild]]) -> [TransactionBuild] { + components.flatMap { $0 } + } + + public static func buildBlock(_ components: TransactionBuild...) -> [TransactionBuild] { + components + } + } + +} + +extension FCL { + + /// Query the Flow Blockchain + /// - Parameters: + /// - script: Cadence Script used to query Flow. + /// - arguments: Arguments passed to cadence script. + /// - Returns: Cadence response Value from Flow Blockchain contract. + public func query( + script: String, + arguments: [Cadence.Argument] = [] + ) async throws -> Cadence.Argument { + let items = fcl.config.addressReplacements + + let newScript = items.reduce(script) { result, replacement in + result.replacingOccurrences(of: replacement.placeholder, with: replacement.replacement.hexStringWithPrefix) + } + return try await fcl.flowAPIClient + .executeScriptAtLatestBlock( + script: Data(newScript.utf8), + arguments: arguments + ) + } + + /// As the current user Mutate the Flow Blockchain + /// - Parameters: + /// - cadence: Cadence Transaction used to mutate Flow + /// - arguments: Arguments passed to cadence transaction + /// - limit: Compute Limit (gas limit) for transaction + /// - Returns: Transaction id + public func mutate( + cadence: String, + arguments: [Cadence.Argument] = [], + limit: UInt64 = 1000, + authorizers: [Cadence.Address] + ) async throws -> Identifier { + // not check accessNode.api here cause we already define it in Network's endpoint. + guard let walletProvider = fcl.config.selectedWalletProvider else { + throw FCLError.walletProviderNotSpecified + } + + let items = fcl.config.addressReplacements + let newCadence = items.reduce(cadence) { result, replacement in + result.replacingOccurrences(of: replacement.placeholder, with: replacement.replacement.hexStringWithPrefix) + } + + // TODO: support additional authorizers. + return try await walletProvider.mutate( + cadence: newCadence, + arguments: arguments, + limit: limit, + authorizers: authorizers + ) + } + + func pipe(ix: Interaction, resolvers: [Resolver]) async throws -> Interaction { + var newInteraction = ix + for resolver in resolvers { + newInteraction = try await resolver.resolve(ix: newInteraction) + } + return newInteraction + } + + func sendIX(ix: Interaction) async throws -> Identifier { + let tx = try await ix.toFlowTransaction() + return try await fcl.flowAPIClient.sendTransaction(transaction: tx) + } + +} + +public extension FCL { + + func getEventsForHeightRange( + eventType: String, + startHeight: UInt64, + endHeight: UInt64, + options: CallOptions? = nil + ) async throws -> [BlockEvents] { + try await flowAPIClient + .getEventsForHeightRange(eventType: eventType, startHeight: startHeight, endHeight: endHeight, options: options) + } + + func getEventsForBlockIDs( + eventType: String, + blockIds: [Identifier], + options: CallOptions? = nil + ) async throws -> [BlockEvents] { + try await flowAPIClient + .getEventsForBlockIDs(eventType: eventType, blockIds: blockIds, options: options) + } + + func getAccount(address: String) async throws -> FlowSDK.Account? { + try await flowAPIClient + .getAccountAtLatestBlock(address: Cadence.Address(hexString: address)) + } + + func getBlock(blockId: String) async throws -> FlowSDK.Block? { + try await flowAPIClient + .getBlockByID(blockId: Identifier(hexString: blockId)) + } + + func getLastestBlock(sealed: Bool = true) async throws -> FlowSDK.Block? { + try await flowAPIClient + .getLatestBlock(isSealed: sealed) + } + + func getBlockHeader(blockId: String) async throws -> FlowSDK.BlockHeader? { + try await flowAPIClient + .getBlockHeaderById(blockId: Identifier(hexString: blockId)) + } + + func getTransactionStatus(transactionId: String) async throws -> FlowSDK.TransactionResult { + try await flowAPIClient + .getTransactionResult(id: Identifier(hexString: transactionId)) + } + + func getTransaction(transactionId: String) async throws -> FlowSDK.Transaction? { + try await flowAPIClient + .getTransaction(id: Identifier(hexString: transactionId)) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLDelegate.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLDelegate.swift new file mode 100644 index 00000000..edb2a64f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLDelegate.swift @@ -0,0 +1,13 @@ +// +// FCLDelegate.swift +// +// +// Created by Andrew Wang on 2022/7/6. +// + +import Foundation +import AuthenticationServices + +public protocol FCLDelegate { + func webAuthenticationContextProvider() -> ASPresentationAnchor? +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLError.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLError.swift new file mode 100644 index 00000000..f6b98dc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/FCLError.swift @@ -0,0 +1,45 @@ +// +// FCLError.swift +// +// +// Created by Andrew Wang on 2022/6/29. +// + +import Foundation + +public enum FCLError: Swift.Error { + case `internal` + case parameterEncodingFailed + case authenticateFailed + case walletProviderNotSpecified + case walletProviderInitFailed + case responseUnexpected + case authnFailed(message: String) + case currentNetworkNotSupported + case unexpectedResult + case serviceError + case invalidRequest + case compositeSignatureInvalid + case invaildProposer + case fetchAccountFailure + case missingPayer + case unauthenticated + case encodeFailed + case userCanceled + case serviceNotImplemented + case unsupported + + case userNotFound + case presentableNotFound + case urlNotFound + case serviceNotFound + case resolverNotFound + case accountNotFound + case preAuthzNotFound + case scriptNotFound + case valueNotFound + case authDataNotFound + case latestBlockNotFound + case keyNotFound + case serviceTypeNotFound +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AccountProofData.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AccountProofData.swift new file mode 100644 index 00000000..29cf56b0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AccountProofData.swift @@ -0,0 +1,45 @@ +// +// File.swift +// +// +// Created by Andrew Wang on 2022/7/11. +// + +import Foundation +import Cadence + +public struct FCLAccountProofData { + /// A human-readable string e.g. "Blocto", "NBA Top Shot" + public let appId: String + /// minimum 32-byte random nonce + public let nonce: String + + public init(appId: String, nonce: String) { + self.appId = appId + self.nonce = nonce + } + +} + +public protocol AccountProofVerifiable { + var address: Address { get } + var nonce: String { get } + var signatures: [CompositeSignatureVerifiable] { get } +} + +public struct AccountProofSignatureData: AccountProofVerifiable { + + public let address: Address + public let nonce: String + public let signatures: [CompositeSignatureVerifiable] + + public init( + address: Address, + nonce: String, + signatures: [FCLCompositeSignature] + ) { + self.address = address + self.nonce = nonce + self.signatures = signatures + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AuthData.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AuthData.swift new file mode 100644 index 00000000..428d8e62 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/AuthData.swift @@ -0,0 +1,63 @@ +// +// AuthData.swift +// FCL +// +// Created by Andrew Wang on 2022/7/6. +// + +import Foundation + +public struct AuthData: Decodable { + let fclType: String? + let fclVersion: String? + let address: String? // exist in dapper wallet authn response, blocto api/flow/payer + let services: [Service]? + let keyId: Int? // exist in user signature + let signature: String? // exist in blocto api/flow/payer + + // pre-authz response (blocto only) + let proposer: Service? + let payer: [Service]? + let authorization: [Service]? + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address = "addr" + case services + case keyId + case signature + case proposer + case payer + case authorization + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.fclType = try container.decodeIfPresent(String.self, forKey: .fclType) + self.fclVersion = try container.decodeIfPresent(String.self, forKey: .fclVersion) + self.address = try container.decodeIfPresent(String.self, forKey: .address) + self.services = try container.decodeIfPresent([Service].self, forKey: .services) + self.keyId = try container.decodeIfPresent(Int.self, forKey: .keyId) + self.signature = try container.decodeIfPresent(String.self, forKey: .signature) + self.proposer = try container.decodeIfPresent(Service.self, forKey: .proposer) + self.payer = try container.decodeIfPresent([Service].self, forKey: .payer) ?? [] + self.authorization = try container.decodeIfPresent([Service].self, forKey: .authorization) ?? [] + } + + init( + proposer: Service?, + payer: [Service]?, + authorization: [Service]? + ) { + self.fclType = nil + self.fclVersion = nil + self.address = nil + self.services = nil + self.keyId = nil + self.signature = nil + self.proposer = proposer + self.payer = payer + self.authorization = authorization + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ClientInfo.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ClientInfo.swift new file mode 100644 index 00000000..ecf4ae98 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ClientInfo.swift @@ -0,0 +1,29 @@ +// +// ClientInfo.swift +// FCL +// +// Created by Andrew Wang on 2022/7/30. +// + +import Foundation + +struct ClientInfo: Encodable { + + let fclVersion: String = Constants.fclVersion + let fclLibrary: String = "https://github.com/portto/fcl-swift" + let hostname: String? = nil + + enum CodingKeys: String, CodingKey { + case fclVersion + case fclLibrary + case hostname + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fclVersion, forKey: .fclVersion) + try container.encode(fclLibrary, forKey: .fclLibrary) + try container.encode(hostname, forKey: .hostname) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/DynamicKey.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/DynamicKey.swift new file mode 100644 index 00000000..a73a21f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/DynamicKey.swift @@ -0,0 +1,22 @@ +// +// DynamicKey.swift +// FCL-SDK +// +// Created by Andrew Wang on 2023/2/23. +// + +import Foundation + +struct DynamicKey: CodingKey { + var stringValue: String + var intValue: Int? + + init?(stringValue: String) { + self.stringValue = stringValue + } + + init?(intValue: Int) { + fatalError("init(intValue:) has not been implemented") + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/FCLCompositeSignature.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/FCLCompositeSignature.swift new file mode 100644 index 00000000..28452b60 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/FCLCompositeSignature.swift @@ -0,0 +1,45 @@ +// +// FCLCompositeSignature.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +public protocol CompositeSignatureVerifiable { + var address: String { get } + var keyId: Int { get } + var signature: String { get } +} + +public struct FCLCompositeSignature: CompositeSignatureVerifiable, Decodable { + + public let fclType: String + public let fclVersion: String + public let address: String + public let keyId: Int + // hex string + public let signature: String + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address = "addr" + case keyId + case signature + } + + public init( + address: String, + keyId: Int, + signature: String + ) { + self.fclType = Pragma.compositeSignature.fclType + self.fclVersion = Pragma.compositeSignature.fclVersion + self.address = address + self.keyId = keyId + self.signature = signature + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Interaction.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Interaction.swift new file mode 100644 index 00000000..38fc07c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Interaction.swift @@ -0,0 +1,232 @@ +// +// Interaction.swift +// FCL +// +// Created by Andrew Wang on 2022/7/25. +// + +import Foundation +import FlowSDK +import Cadence +import BigInt + +struct Interaction: Encodable { + var tag: Tag = .unknown + var assigns = [String: String]() + var status: Status = .ok + var reason: String? + var accounts = [String: SignableUser]() + var params = [String: String]() + var arguments = [String: Argument]() + var message = Message() + var proposer: String? + var authorizations = [String]() + var payer: String? + var events = Events() + var transaction = Id() + var block = Block() + var account = Account() + var collection = Id() + + enum Status: String, CaseIterable, Codable { + case ok = "OK" + case bad = "BAD" + } + + enum Tag: String, CaseIterable, Codable { + case unknown = "UNKNOWN" + case script = "SCRIPT" + case transaction = "TRANSACTION" + case getTransactionStatus = "GET_TRANSACTION_STATUS" + case getAccount = "GET_ACCOUNT" + case getEvents = "GET_EVENTS" + case getLatestBlock = "GET_LATEST_BLOCK" + case ping = "PING" + case getTransaction = "GET_TRANSACTION" + case getBlockById = "GET_BLOCK_BY_ID" + case getBlockByHeight = "GET_BLOCK_BY_HEIGHT" + case getBlock = "GET_BLOCK" + case getBlockHeader = "GET_BLOCK_HEADER" + case getCollection = "GET_COLLECTION" + } + + @discardableResult + mutating func setTag(_ tag: Tag) -> Self { + self.tag = tag + return self + } + + var findInsideSigners: [String] { + // Inside Signers Are: (authorizers + proposer) - payer + var inside = Set(authorizations) + if let proposer = proposer { + inside.insert(proposer) + } + if let payer = payer { + inside.remove(payer) + } + return Array(inside) + } + + var findOutsideSigners: [String] { + // Outside Signers Are: (payer) + guard let payer = payer else { + return [] + } + let outside = Set([payer]) + return Array(outside) + } + + func createProposalKey() -> ProposalKey { + guard let proposer = proposer, + let account = accounts[proposer], + let sequenceNum = account.sequenceNum else { + return ProposalKey() + } + + return ProposalKey( + address: account.address.hexString, + keyId: Int(account.keyId), + sequenceNum: Int(sequenceNum) + ) + } + + func createFlowProposalKey() async throws -> Transaction.ProposalKey { + guard let proposer = proposer, + var account = accounts[proposer], + let sequenceNumber = account.sequenceNum else { + throw FCLError.invaildProposer + } + + let address = account.address + let keyId = account.keyId + + if let sequenceNum = account.sequenceNum { + let key = Transaction.ProposalKey( + address: address, + keyIndex: Int(keyId), + sequenceNumber: UInt64(sequenceNum) + ) + return key + } else { + let remoteAccount = try await fcl.flowAPIClient.getAccountAtLatestBlock(address: address) + guard let remoteAccount = remoteAccount else { + throw FCLError.accountNotFound + } + account.sequenceNum = remoteAccount.keys[Int(keyId)].sequenceNumber + let key = Transaction.ProposalKey( + address: address, + keyIndex: Int(keyId), + sequenceNumber: sequenceNumber + ) + return key + } + } + + func buildPreSignable(role: Role) -> PreSignable { + PreSignable( + roles: role, + cadence: message.cadence ?? "", + args: message.arguments.compactMap { tempId in arguments[tempId]?.asArgument }, + interaction: self + ) + } + + func toFlowTransaction() async throws -> Transaction { + let proposalKey = try await createFlowProposalKey() + + guard let payerAccount = payer, + let payerAddress = accounts[payerAccount]?.address else { + throw FCLError.missingPayer + } + + var tx = try Transaction( + script: Data((message.cadence ?? "").utf8), + arguments: message.arguments.compactMap { tempId in arguments[tempId]?.asArgument }, + referenceBlockId: Identifier(hexString: message.refBlock ?? ""), + gasLimit: message.computeLimit, + proposalKey: proposalKey, + payer: payerAddress, + authorizers: authorizations + .compactMap { cid in accounts[cid]?.address } + .uniqued() + ) + + let insideSigners = findInsideSigners + insideSigners.forEach { address in + if let account = accounts[address], + let signature = account.signature { + tx.addPayloadSignature( + address: account.address, + keyIndex: Int(account.keyId), + signature: signature.hexDecodedData + ) + } + } + + let outsideSigners = findOutsideSigners + outsideSigners.forEach { address in + if let account = accounts[address], + let signature = account.signature { + tx.addEnvelopeSignature( + address: account.address, + keyIndex: Int(account.keyId), + signature: signature.hexDecodedData + ) + } + } + return tx + } +} + +struct Argument: Encodable { + var kind: String + var tempId: String + var value: Cadence.Value + var asArgument: Cadence.Argument + var xform: Xform +} + +struct Xform: Codable { + var label: String +} + +struct Id: Encodable { + var id: String? +} + +let defaultComputeLimit: UInt64 = 100 + +struct Message: Encodable { + var cadence: String? + var refBlock: String? + var computeLimit: UInt64 = defaultComputeLimit + var proposer: String? + var payer: String? + var authorizations: [String] = [] + var params: [String] = [] + var arguments: [String] = [] +} + +struct Events: Encodable { + var eventType: String? + var start: String? + var end: String? + var blockIds: [String] = [] +} + +struct Block: Encodable { + var id: String? + var height: Int64? + var isSealed: Bool? +} + +struct Account: Encodable { + var addr: String? +} + +struct ProposalKey: Encodable { + var address: String? + var keyId: Int? + var sequenceNum: Int? +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Pragma.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Pragma.swift new file mode 100644 index 00000000..4277c98a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Pragma.swift @@ -0,0 +1,25 @@ +// +// Pragma.swift +// +// +// Created by Andrew Wang on 2022/7/14. +// + +import Foundation + +struct Pragma { + + static let user = Pragma(fclType: "USER", fclVersion: Constants.fclVersion) + static let provider = Pragma(fclType: "Provider", fclVersion: Constants.fclVersion) + static let service = Pragma(fclType: "Service", fclVersion: Constants.fclVersion) + static let identity = Pragma(fclType: "Identity", fclVersion: Constants.fclVersion) + static let pollingResponse = Pragma(fclType: "PollingResponse", fclVersion: Constants.fclVersion) + static let compositeSignature = Pragma(fclType: "CompositeSignature", fclVersion: Constants.fclVersion) + static let openId = Pragma(fclType: "OpenId", fclVersion: Constants.fclVersion) + static let preSignable = Pragma(fclType: "PreSignable", fclVersion: "1.0.1") + static let signable = Pragma(fclType: "Signable", fclVersion: "1.0.1") + + let fclType: String + let fclVersion: String + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/PreSignable.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/PreSignable.swift new file mode 100644 index 00000000..853cc13d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/PreSignable.swift @@ -0,0 +1,76 @@ +// +// PreSignable.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation +import Cadence + +public struct PreSignable: Encodable { + let fclType: String = Pragma.preSignable.fclType + let fclVersion: String = Pragma.preSignable.fclVersion + let roles: Role + let cadence: String + var args: [Cadence.Argument] = [] + let data = [String: String]() + var interaction = Interaction() + + var voucher: Voucher { + let insideSigners: [Singature] = interaction.findInsideSigners.compactMap { id in + guard let account = interaction.accounts[id] else { return nil } + return Singature( + address: account.address.hexString, + keyId: account.keyId, + sig: account.signature + ) + } + + let outsideSigners: [Singature] = interaction.findOutsideSigners.compactMap { id in + guard let account = interaction.accounts[id] else { return nil } + return Singature( + address: account.address.hexString, + keyId: account.keyId, + sig: account.signature + ) + } + + return Voucher( + cadence: interaction.message.cadence, + refBlock: interaction.message.refBlock, + computeLimit: interaction.message.computeLimit, + arguments: interaction.message.arguments.compactMap { tempId in + interaction.arguments[tempId]?.asArgument + }, + proposalKey: interaction.createProposalKey(), + payer: interaction.payer, + authorizers: interaction.authorizations + .compactMap { cid in interaction.accounts[cid]?.address.hexString } + .uniqued(), + payloadSigs: insideSigners, + envelopeSigs: outsideSigners + ) + } + + enum CodingKeys: String, CodingKey { + case fType = "f_type" + case fVsn = "f_vsn" + case roles + case cadence + case args + case interaction + case voucher + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fclType, forKey: .fType) + try container.encode(fclVersion, forKey: .fVsn) + try container.encode(roles, forKey: .roles) + try container.encode(cadence, forKey: .cadence) + try container.encode(args, forKey: .args) + try container.encode(interaction, forKey: .interaction) + try container.encode(voucher, forKey: .voucher) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ProviderInfo.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ProviderInfo.swift new file mode 100644 index 00000000..df4b35af --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ProviderInfo.swift @@ -0,0 +1,14 @@ +// +// ProviderInfo.swift +// +// +// Created by Andrew Wang on 2022/7/5. +// + +import Foundation + +public struct ProviderInfo { + let title: String + let desc: String? + let icon: URL? +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ResponseStatus.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ResponseStatus.swift new file mode 100644 index 00000000..bd75281d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/ResponseStatus.swift @@ -0,0 +1,14 @@ +// +// ResponseStatus.swift +// +// +// Created by Andrew Wang on 2022/7/1. +// + +import Foundation + +enum ResponseStatus: String, Decodable { + case pending = "PENDING" + case approved = "APPROVED" + case declined = "DECLINED" +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Role.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Role.swift new file mode 100644 index 00000000..25c31fe3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Role.swift @@ -0,0 +1,21 @@ +// +// Role.swift +// FCL-SDK +// +// Created by Andrew Wang on 2022/8/16. +// + +import Foundation + +struct Role: Encodable { + var proposer: Bool = false + var authorizer: Bool = false + var payer: Bool = false + var param: Bool? + + mutating func merge(role: Role) { + proposer = proposer || role.proposer + authorizer = authorizer || role.authorizer + payer = payer || role.payer + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/RoleType.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/RoleType.swift new file mode 100644 index 00000000..4e81202a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/RoleType.swift @@ -0,0 +1,14 @@ +// +// RoleType.swift +// FCL-SDK +// +// Created by Andrew Wang on 2022/8/16. +// + +import Foundation + +enum RoleType: String { + case proposer = "PROPOSER" + case payer = "PAYER" + case authorizer = "AUTHORIZER" +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Signable.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Signable.swift new file mode 100644 index 00000000..d59982f6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Signable.swift @@ -0,0 +1,89 @@ +// +// Signable.swift +// FCL +// +// Created by Andrew Wang on 2022/7/30. +// + +import Foundation +import Cadence + +struct Signable: Encodable { + + let fclType: String = Pragma.signable.fclType + let fclVersion: String = Pragma.signable.fclVersion + let data = [String: String]() + let message: String + let keyId: UInt32 + let address: Cadence.Address + let roles: Role + let cadence: String? + let args: [Cadence.Argument] + let interaction: Interaction + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address = "addr" + case roles + case data + case message + case keyId + case cadence + case args + case interaction + case voucher + } + + var voucher: Voucher { + let insideSigners: [Singature] = interaction.findInsideSigners.compactMap { id in + guard let account = interaction.accounts[id] else { return nil } + return Singature( + address: account.address.hexString, + keyId: account.keyId, + sig: account.signature + ) + } + + let outsideSigners: [Singature] = interaction.findOutsideSigners.compactMap { id in + guard let account = interaction.accounts[id] else { return nil } + return Singature( + address: account.address.hexString, + keyId: account.keyId, + sig: account.signature + ) + } + + return Voucher( + cadence: interaction.message.cadence, + refBlock: interaction.message.refBlock, + computeLimit: interaction.message.computeLimit, + arguments: interaction.message.arguments.compactMap { tempId in + interaction.arguments[tempId]?.asArgument + }, + proposalKey: interaction.createProposalKey(), + payer: interaction.accounts[interaction.payer ?? ""]?.address.hexString, + authorizers: interaction.authorizations + .compactMap { cid in interaction.accounts[cid]?.address.hexString } + .uniqued(), + payloadSigs: insideSigners, + envelopeSigs: outsideSigners + ) + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fclType, forKey: .fclType) + try container.encode(fclVersion, forKey: .fclVersion) + try container.encode(data, forKey: .data) + try container.encode(message, forKey: .message) + try container.encode(keyId, forKey: .keyId) + try container.encode(roles, forKey: .roles) + try container.encode(cadence, forKey: .cadence) + try container.encode(address.hexString, forKey: .address) + try container.encode(args, forKey: .args) + try container.encode(interaction, forKey: .interaction) + try container.encode(voucher, forKey: .voucher) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/SignableUser.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/SignableUser.swift new file mode 100644 index 00000000..58a5aba4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/SignableUser.swift @@ -0,0 +1,45 @@ +// +// SignableUser.swift +// FCL-SDK +// +// Created by Andrew Wang on 2022/8/16. +// + +import Foundation +import Cadence + +struct SignableUser: Encodable { + var address: Cadence.Address + var keyId: UInt32 + var role: Role + + // Assigned in SignatureResolver + var signature: String? + // Assigned in SequenceNumberResolver + var sequenceNum: UInt64? + + var tempId: String { + address.hexString + "-" + String(keyId) + } + + var signingFunction: (Data) async throws -> AuthResponse + + enum CodingKeys: String, CodingKey { + case address = "addr" + case keyId + case role + case signature + case sequenceNum + case tempId + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(address.hexString, forKey: .address) + try container.encode(keyId, forKey: .keyId) + try container.encode(role, forKey: .role) + try container.encode(signature, forKey: .signature) + try container.encode(sequenceNum, forKey: .sequenceNum) + try container.encode(tempId, forKey: .tempId) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Singature.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Singature.swift new file mode 100644 index 00000000..4d5b077b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Singature.swift @@ -0,0 +1,14 @@ +// +// Singature.swift +// FCL-SDK +// +// Created by Andrew Wang on 2022/8/16. +// + +import Foundation + +struct Singature: Encodable { + let address: String + let keyId: UInt32 + let sig: String? +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/TransactionFeePayer.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/TransactionFeePayer.swift new file mode 100644 index 00000000..825ef16c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/TransactionFeePayer.swift @@ -0,0 +1,26 @@ +// +// TransactionFeePayer.swift +// FCL +// +// Created by Andrew Wang on 2022/7/29. +// + +import Foundation +import Cadence + +/// The key that specifies the fee payer address with key for a transaction. +public struct TransactionFeePayer: Equatable { + + public let address: Address + public let keyIndex: Int + + public var tempId: String { + address.hexString + "-" + String(keyIndex) + } + + public init(address: Address, keyIndex: Int) { + self.address = address + self.keyIndex = keyIndex + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Voucher.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Voucher.swift new file mode 100644 index 00000000..f8511451 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Models/Voucher.swift @@ -0,0 +1,21 @@ +// +// Voucher.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation +import Cadence + +struct Voucher: Encodable { + let cadence: String? + let refBlock: String? + let computeLimit: UInt64 + let arguments: [Cadence.Argument] + let proposalKey: ProposalKey + var payer: String? + let authorizers: [String]? + let payloadSigs: [Singature]? + let envelopeSigs: [Singature]? +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/PollingResponse.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/PollingResponse.swift new file mode 100644 index 00000000..446ebbf0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/PollingResponse.swift @@ -0,0 +1,88 @@ +// +// PollingResponse.swift +// +// +// Created by Andrew Wang on 2022/7/1. +// + +import Foundation + +/// Used for authn, authz and pre-authz +struct AuthResponse: Decodable { + let fclType: String? + let fclVersion: String? + let status: ResponseStatus + var updates: Service? // authn + var local: Service? // authn, authz + var data: AuthData? + let reason: String? + let compositeSignature: AuthData? // authz + let authorizationUpdates: Service? // authz + let userSignatures: [FCLCompositeSignature] + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case status + case updates + case local + case data + case reason + case compositeSignature + case authorizationUpdates + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + fclType = try? container.decode(String.self, forKey: .fclType) + fclVersion = try? container.decode(String.self, forKey: .fclVersion) + status = try container.decode(ResponseStatus.self, forKey: .status) + updates = try? container.decode(Service.self, forKey: .updates) + do { + local = try container.decode(Service.self, forKey: .local) + } catch { + let locals = try? container.decode([Service].self, forKey: .local) + local = locals?.first + } + data = try? container.decode(AuthData.self, forKey: .data) + userSignatures = (try? container.decode([FCLCompositeSignature].self, forKey: .data)) ?? [] + reason = try? container.decode(String.self, forKey: .reason) + compositeSignature = try? container.decode(AuthData.self, forKey: .compositeSignature) + authorizationUpdates = try? container.decode(Service.self, forKey: .authorizationUpdates) + } +} + +/// Used for post pre-authz response +struct PollingWrappedResponse: Decodable { + let fclType: String? + let fclVersion: String? + let status: ResponseStatus + let data: Model? + let reason: String? + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case status + case data + case reason + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.fclType = try? container.decode(String.self, forKey: .fclType) + self.fclVersion = try? container.decode(String.self, forKey: .fclVersion) + self.status = try container.decode(ResponseStatus.self, forKey: .status) + switch status { + case .pending: + self.reason = nil + self.data = nil + case .approved: + self.reason = nil + self.data = try container.decode(Model.self, forKey: .data) + case .declined: + self.reason = try? container.decode(String.self, forKey: .reason) + self.data = nil + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/URLSessionExtension.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/URLSessionExtension.swift new file mode 100644 index 00000000..cad9f61f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Network/URLSessionExtension.swift @@ -0,0 +1,35 @@ +// +// URLSessionExtension.swift +// +// +// Created by Andrew Wang on 2022/7/6. +// + +import UIKit + +extension URLSession { + + static let decoder = JSONDecoder() + + func dataAuthnResponse(for request: URLRequest) async throws -> AuthResponse { + log(message: request.toReadable()) + let data = try await data(for: request) + log(message: String(data: try data.prettyData(), encoding: .utf8) ?? "") + return try Self.decoder.decode(AuthResponse.self, from: data) + } + + private func data(for request: URLRequest) async throws -> Data { + try await withCheckedThrowingContinuation { continuation in + dataTask(with: request) { data, _, error in + if let error = error { + continuation.resume(with: .failure(error)) + } else if let data = data { + continuation.resume(with: .success(data)) + } else { + continuation.resume(with: .failure(FCLError.responseUnexpected)) + } + }.resume() + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/AccountsResolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/AccountsResolver.swift new file mode 100644 index 00000000..a6736dfa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/AccountsResolver.swift @@ -0,0 +1,101 @@ +// +// AccountsResolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation +import FlowSDK +import Cadence + +final class AccountsResolver: Resolver { + + func resolve(ix: Interaction) async throws -> Interaction { + if ix.tag == .transaction { + return try await collectAccounts(ix: ix, accounts: Array(ix.accounts.values)) + } + + return try await withCheckedThrowingContinuation { continuation in + continuation.resume(with: .success(ix)) + } + } + + func collectAccounts(ix: Interaction, accounts: [SignableUser]) async throws -> Interaction { + guard let currentUser = fcl.currentUser, + currentUser.loggedIn else { + throw FCLError.unauthenticated + } + + guard let walletProvider = fcl.config.selectedWalletProvider else { + throw FCLError.walletProviderNotSpecified + } + + let preSignable = ix.buildPreSignable(role: Role()) + let authData = try await walletProvider.preAuthz(preSignable: preSignable) + + let signableUsers = buildSignableUsers(authData: authData) + var accounts = [String: SignableUser]() + + var newIX = ix + newIX.authorizations.removeAll() + signableUsers.forEach { user in + let tempId = user.tempId + + if accounts.keys.contains(tempId) { + accounts[tempId]?.role.merge(role: user.role) + } + accounts[tempId] = user + + if user.role.proposer { + newIX.proposer = tempId + } + + if user.role.payer { + newIX.payer = tempId + } + + if user.role.authorizer { + newIX.authorizations.append(tempId) + } + } + newIX.accounts = accounts + return newIX + } + + func buildSignableUsers(authData: AuthData) -> [SignableUser] { + var axs = [(role: RoleType, service: Service)]() + if let proposer = authData.proposer { + axs.append((RoleType.proposer, proposer)) + } + for az in authData.payer ?? [] { + axs.append((RoleType.payer, az)) + } + for az in authData.authorization ?? [] { + axs.append((RoleType.authorizer, az)) + } + + return axs.compactMap { role, service in + + guard let address = service.identity?.address, + let keyId = service.identity?.keyId else { + return nil + } + + return SignableUser( + address: Cadence.Address(hexString: address), + keyId: keyId, + role: Role( + proposer: role == .proposer, + authorizer: role == .authorizer, + payer: role == .payer, + param: nil + ) + ) { data in + let request = try service.getURLRequest(body: data) + return try await fcl.pollingRequest(request, type: .authz) + } + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/CadenceResolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/CadenceResolver.swift new file mode 100644 index 00000000..fecb0fec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/CadenceResolver.swift @@ -0,0 +1,29 @@ +// +// CadenceResolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation + +final class CadenceResolver: Resolver { + + func resolve(ix: Interaction) async throws -> Interaction { + guard let cadenceSript = ix.message.cadence else { + throw FCLError.scriptNotFound + } + if ix.tag == .transaction || ix.tag == .script { + var newIx = ix + newIx.message.cadence = fcl.config.addressReplacements.reduce(cadenceSript) { result, replacement in + result.replacingOccurrences( + of: replacement.placeholder, + with: replacement.replacement.hexStringWithPrefix + ) + } + return newIx + } + return ix + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/RefBlockResolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/RefBlockResolver.swift new file mode 100644 index 00000000..e04dd73f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/RefBlockResolver.swift @@ -0,0 +1,20 @@ +// +// RefBlockResolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation +import FlowSDK + +final class RefBlockResolver: Resolver { + + func resolve(ix: Interaction) async throws -> Interaction { + let block = try await fcl.flowAPIClient.getLatestBlock(isSealed: true) + var newIX = ix + newIX.message.refBlock = block?.blockHeader.id.hexString + return newIX + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/Resolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/Resolver.swift new file mode 100644 index 00000000..d7be4fc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/Resolver.swift @@ -0,0 +1,12 @@ +// +// Resolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation + +protocol Resolver { + func resolve(ix: Interaction) async throws -> Interaction +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SequenceNumberResolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SequenceNumberResolver.swift new file mode 100644 index 00000000..2f022868 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SequenceNumberResolver.swift @@ -0,0 +1,32 @@ +// +// SequenceNumberResolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Cadence +import Foundation + +final class SequenceNumberResolver: Resolver { + + func resolve(ix: Interaction) async throws -> Interaction { + guard let proposer = ix.proposer, + let account = ix.accounts[proposer] else { + throw FCLError.internal + } + + if account.sequenceNum == nil { + let remoteAccount = try await fcl.flowAPIClient.getAccountAtLatestBlock(address: account.address) + guard let remoteAccount = remoteAccount else { + throw FCLError.accountNotFound + } + var newIX = ix + newIX.accounts[proposer]?.sequenceNum = remoteAccount.keys[Int(account.keyId)].sequenceNumber + return newIX + } else { + return ix + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SignatureResolver.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SignatureResolver.swift new file mode 100644 index 00000000..aa7a633f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Resolve/SignatureResolver.swift @@ -0,0 +1,147 @@ +// +// SignatureResolver.swift +// FCL +// +// Created by Andrew Wang on 2022/7/26. +// + +import Foundation +import FlowSDK + +final class SignatureResolver: Resolver { + + func resolve(ix interaction: Interaction) async throws -> Interaction { + var ix = interaction + + guard ix.tag == .transaction else { + throw FCLError.internal + } + + let insideSigners = interaction.findInsideSigners + + let tx = try await ix.toFlowTransaction() + + let payloadSignatureMap = try await withThrowingTaskGroup( + of: (id: String, signature: String).self, + returning: [String: String].self, + body: { taskGroup in + + let insidePayload = tx.encodedPayload.toHexString() + + let interaction = ix + for address in insideSigners { + taskGroup.addTask { + try await self.fetchSignature( + ix: interaction, + payload: insidePayload, + id: address + ) + } + } + + var returning: [String: String] = [:] + for try await result in taskGroup { + returning[result.id] = result.signature + } + return returning + } + ) + + payloadSignatureMap.forEach { id, signature in + ix.accounts[id]?.signature = signature + } + + let outsideSigners = ix.findOutsideSigners + let envelopeSignatureMap = try await withThrowingTaskGroup( + of: (id: String, signature: String).self, + returning: [String: String].self, + body: { taskGroup in + + let envelopeMessage = encodeEnvelopeMessage( + transaction: tx, + ix: ix, + insideSigners: insideSigners + ) + + let interaction = ix + for address in outsideSigners { + taskGroup.addTask { + try await self.fetchSignature( + ix: interaction, + payload: envelopeMessage, + id: address + ) + } + } + var returning: [String: String] = [:] + for try await result in taskGroup { + returning[result.id] = result.signature + } + return returning + } + + ) + envelopeSignatureMap.forEach { id, signature in + ix.accounts[id]?.signature = signature + } + return ix + } + + func fetchSignature( + ix: Interaction, + payload: String, + id: String + ) async throws -> (id: String, signature: String) { + guard let account = ix.accounts[id], + let signable = buildSignable( + ix: ix, + payload: payload, + account: account + ), + let data = try? JSONEncoder().encode(signable) else { + throw FCLError.internal + } + + let response = try await account.signingFunction(data) + return (id: id, signature: (response.data?.signature ?? response.compositeSignature?.signature) ?? "") + } + + func encodeEnvelopeMessage( + transaction: Transaction, + ix: Interaction, + insideSigners: [String] + ) -> String { + var tx = transaction + insideSigners.forEach { address in + if let account = ix.accounts[address], + let signature = account.signature { + tx.addPayloadSignature( + address: account.address, + keyIndex: Int(account.keyId), + signature: signature.hexDecodedData + ) + } + } + + return tx.encodedEnvelope.toHexString() + } + + func buildSignable( + ix: Interaction, + payload: String, + account: SignableUser + ) -> Signable? { + Signable( + message: payload, + keyId: account.keyId, + address: account.address, + roles: account.role, + cadence: ix.message.cadence, + args: ix.message.arguments.compactMap { tempId in + ix.arguments[tempId]?.asArgument + }, + interaction: ix + ) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/Service.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/Service.swift new file mode 100644 index 00000000..02f1deb5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/Service.swift @@ -0,0 +1,159 @@ +// +// Service.swift +// FCL +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation +import SwiftyJSON +import UIKit + +public struct Service: Decodable { + let fclType: String? + let fclVersion: String? + let type: ServiceType? + let method: ServiceMethod? + let endpoint: URL? + let uid: String? + let id: String? + let identity: ServiceIdentity? + let provider: ServiceProvider? + let params: [String: String] + let data: ServiceDataType + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case type + case method + case endpoint + case uid + case id + case identity + case provider + case params + case data + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.fclType = try? container.decode(String.self, forKey: .fclType) + self.fclVersion = try? container.decode(String.self, forKey: .fclVersion) + self.type = try? container.decode(ServiceType.self, forKey: .type) + self.method = try? container.decode(ServiceMethod.self, forKey: .method) + self.endpoint = try? container.decode(URL.self, forKey: .endpoint) + self.uid = try? container.decode(String.self, forKey: .uid) + self.id = try? container.decode(String.self, forKey: .id) + self.identity = try? container.decode(ServiceIdentity.self, forKey: .identity) + self.provider = try? container.decode(ServiceProvider.self, forKey: .provider) + self.params = (try? container.decode([String: String].self, forKey: .params)) ?? [:] + switch type { + case .openId: + if let openId = try? container.decode(JSON.self, forKey: .data) { + self.data = .openId(openId) + } else { + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "open id data structure not exist." + ) + ) + } + case .accountProof: + if let accountProof = try? container.decode(ServiceAccountProof.self, forKey: .data) { + self.data = .accountProof(accountProof) + } else { + self.data = .notExist + } + case .authn, + .localView, + .authz, + .preAuthz, + .backChannel, + .userSignature, + .authnRefresh: + if let json = try? container.decode(JSON.self, forKey: .data) { + self.data = .json(json) + } else { + self.data = .notExist + } + case .none: + self.data = .notExist + } + } +} + +extension Service { + + func getURLRequest(body: Data? = nil) throws -> URLRequest { + switch type { + case .authn: + throw FCLError.serviceNotImplemented + case .localView, + .preAuthz, + .userSignature, + .backChannel, + .authz, + .none: + guard let endpoint = endpoint else { + throw FCLError.serviceError + } + guard let requestURL = buildURL(url: endpoint, params: params) else { + throw FCLError.invalidRequest + } + let object = try body?.toDictionary() ?? [:] + return try RequstBuilder.buildURLRequest(url: requestURL, method: method, body: object) + case .openId: + throw FCLError.serviceNotImplemented + case .accountProof: + throw FCLError.serviceNotImplemented + case .authnRefresh: + throw FCLError.serviceNotImplemented + } + } + + private func buildURL(url: URL, params: [String: String] = [:]) -> URL? { + guard var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { + return nil + } + + var queryItems: [URLQueryItem] = [] + + for (name, value) in params { + queryItems.append( + URLQueryItem(name: name, value: value) + ) + } + + urlComponents.queryItems = queryItems + return urlComponents.url + } + +} + +extension Encodable { + /// Converting object to postable dictionary + func toDictionary(_ encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] { + let data = try encoder.encode(self) + let object = try JSONSerialization.jsonObject(with: data) + guard let json = object as? [String: Any] else { + let context = DecodingError.Context(codingPath: [], debugDescription: "Deserialized object is not a dictionary") + throw DecodingError.typeMismatch(type(of: object), context) + } + return json + } +} + +extension Data { + + func toDictionary() throws -> [String: Any] { + let object = try JSONSerialization.jsonObject(with: self) + guard let json = object as? [String: Any] else { + let context = DecodingError.Context(codingPath: [], debugDescription: "Deserialized data is not a dictionary") + throw DecodingError.typeMismatch(type(of: object), context) + } + return json + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceAccountProof.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceAccountProof.swift new file mode 100644 index 00000000..b91b0341 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceAccountProof.swift @@ -0,0 +1,26 @@ +// +// ServiceAccountProof.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +public struct ServiceAccountProof: Decodable { + + let fclType: String + let fclVersion: String + let address: String + let nonce: String + let signatures: [FCLCompositeSignature] + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address + case nonce + case signatures + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceDataType.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceDataType.swift new file mode 100644 index 00000000..7f0ef4cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceDataType.swift @@ -0,0 +1,59 @@ +// +// ServiceDataType.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation +import SwiftyJSON + +// https://github.com/onflow/fcl-js/blob/master/packages/fcl/src/current-user/normalize/open-id.js +/* +{ + "f_type": "Service", + "f_vsn": "1.0.0", + "type": "open-id", + "uid": "uniqueDedupeKey", + "method: "data", + "data": { + "profile": { + "name": "Bob", + "family_name": "Builder", + "given_name": "Robert", + "middle_name": "the", + "nickname": "Bob the Builder", + "perferred_username": "bob", + "profile": "https://www.bobthebuilder.com/", + "picture": "https://avatars.onflow.org/avatar/bob", + "gender": "...", + "birthday": "2001-01-18", + "zoneinfo": "America/Vancouver", + "locale": "en-us", + "updated_at": "1614970797388" + }, + "email": { + "email": "bob@bob.bob", + "email_verified": true + }, + "address": { + "address": "One Apple Park Way, Cupertino, CA 95014, USA" + }, + "phone": { + "phone_number": "+1 (xxx) yyy-zzzz", + "phone_number_verified": true + }, + "social": { + "twitter": "@_qvvg", + "twitter_verified": true + }, + } +} +*/ + +public enum ServiceDataType { + case openId(JSON) + case accountProof(ServiceAccountProof) + case json(JSON) + case notExist +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceIdentity.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceIdentity.swift new file mode 100644 index 00000000..95810363 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceIdentity.swift @@ -0,0 +1,22 @@ +// +// ServiceIdentity.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +struct ServiceIdentity: Decodable { + public let fclType: String? // proposer, payer, authorization in PreAuthzResponse do not have this key. + public let fclVersion: String? // proposer, payer, authorization in PreAuthzResponse do not have this key. + public let address: String + let keyId: UInt32 + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address + case keyId + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceMethod.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceMethod.swift new file mode 100644 index 00000000..1e1e712e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceMethod.swift @@ -0,0 +1,28 @@ +// +// ServiceMethod.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +public enum ServiceMethod: String, Decodable { + case httpPost = "HTTP/POST" + case httpGet = "HTTP/GET" + case iframe = "VIEW/IFRAME" + case iframeRPC = "IFRAME/RPC" + case browserIframe = "BROWSER/IFRAME" + case data = "DATA" + + var httpMethod: String? { + switch self { + case .httpGet: + return "GET" + case .httpPost: + return "POST" + default: + return nil + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceProvider.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceProvider.swift new file mode 100644 index 00000000..bac657be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceProvider.swift @@ -0,0 +1,31 @@ +// +// ServiceProvider.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +struct ServiceProvider: Decodable { + public let fclType: String + public let fclVersion: String + public let address: String? + public let name: String? + public let iconString: String? + + public var iconURL: URL? { + if let iconString = iconString { + return URL(string: iconString) + } + return nil + } + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address + case name + case iconString = "icon" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceType.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceType.swift new file mode 100644 index 00000000..694335fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/Service/ServiceType.swift @@ -0,0 +1,22 @@ +// +// ServiceType.swift +// +// +// Created by Andrew Wang on 2022/6/30. +// + +import Foundation + +public enum ServiceType: String, Decodable { + case authn + case authz + case preAuthz = "pre-authz" + case userSignature = "user-signature" + case backChannel = "back-channel-rpc" + case openId = "open-id" + case accountProof = "account-proof" + case authnRefresh = "authn-refresh" + case localView = "local-view" +} + +extension ServiceType: Equatable {} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/User.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/User.swift new file mode 100644 index 00000000..0fc299b6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/User/User.swift @@ -0,0 +1,85 @@ +// +// File.swift +// +// +// Created by Andrew Wang on 2022/6/29. +// + +import Foundation +import Cadence + +public struct User: Decodable { + + public var fclType: String = Pragma.user.fclType + public var fclVersion: String = Pragma.user.fclVersion + public let address: Address + public var loggedIn: Bool = false + public let expiresAt: TimeInterval + private var accountProofData: AccountProofSignatureData? + public let services: [Service] + + public var accountProof: AccountProofSignatureData? { + if let proof = accountProofData { + return proof.signatures.isEmpty ? nil : proof + } else { + do { + let accountProofService = try fcl.serviceOfType(type: .accountProof) + if case let .accountProof(serviceAccountProof) = accountProofService?.data { + return AccountProofSignatureData( + address: address, + nonce: serviceAccountProof.nonce, + signatures: serviceAccountProof.signatures) + } + return nil + } catch { + return nil + } + } + } + + var expiresAtDate: Date { + Date(timeIntervalSince1970: expiresAt) + } + + enum CodingKeys: String, CodingKey { + case fclType = "f_type" + case fclVersion = "f_vsn" + case address = "addr" + case loggedIn + case expiresAt + case services + } + + public init( + fclType: String, + fclVersion: String, + address: Address, + accountProof: AccountProofSignatureData?, + loggedIn: Bool = false, + expiresAt: TimeInterval, + services: [Service] + ) { + self.fclType = fclType + self.fclVersion = fclVersion + self.address = address + self.accountProofData = accountProof + self.loggedIn = loggedIn + self.expiresAt = expiresAt + self.services = services + } + + public init( + address: Address, + accountProof: AccountProofSignatureData?, + loggedIn: Bool = false, + expiresAt: TimeInterval, + services: [Service] + ) { + self.address = address + self.accountProofData = accountProof + self.loggedIn = loggedIn + self.expiresAt = expiresAt + self.services = services + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Utilities/RequestBuilder.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Utilities/RequestBuilder.swift new file mode 100644 index 00000000..a2216ab5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/Utilities/RequestBuilder.swift @@ -0,0 +1,46 @@ +// +// RequestBuilder.swift +// FCL +// +// Created by Andrew Wang on 2022/8/12. +// + +import Foundation + +enum RequstBuilder { + + static func buildURLRequest( + url: URL, + method: ServiceMethod?, + body: [String: Any] = [:] + ) throws -> URLRequest { + var urlRequest = URLRequest(url: url) + urlRequest.httpMethod = method?.httpMethod + + guard let selectedWalletProvider = fcl.config.selectedWalletProvider else { + throw FCLError.walletProviderNotSpecified + } + + var newRequest = selectedWalletProvider.modifyRequest(urlRequest) + + if newRequest.httpMethod == ServiceMethod.httpPost.httpMethod { + var object = body + if let appDetail = fcl.config.appDetail { + let appDetailDic = try appDetail.toDictionary() + object = object.merging(appDetailDic, uniquingKeysWith: { $1 }) + } + if fcl.config.openIdScopes.isEmpty == false { + let openIdScopesDic = try fcl.config.openIdScopes.toDictionary() + object = object.merging(openIdScopesDic, uniquingKeysWith: { $1 }) + } + let clientInfoDic = try ClientInfo().toDictionary() + object = object.merging(clientInfoDic, uniquingKeysWith: { $1 }) + let body = try? JSONSerialization.data(withJSONObject: object) + newRequest.httpBody = body + newRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") + newRequest.addValue("application/json", forHTTPHeaderField: "Accept") + } + return newRequest + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/BloctoWalletProvider.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/BloctoWalletProvider.swift new file mode 100644 index 00000000..f26fefd9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/BloctoWalletProvider.swift @@ -0,0 +1,344 @@ +// +// BloctoWalletProvider.swift +// +// +// Created by Andrew Wang on 2022/7/5. +// + +import Foundation +import UIKit +import FlowSDK +import BloctoSDK +import SwiftyJSON +import Cadence + +public final class BloctoWalletProvider: WalletProvider { + + var bloctoFlowSDK: BloctoFlowSDK + public let providerInfo: ProviderInfo = ProviderInfo( + title: "Blocto", + desc: "Entrance to blockchain world.", + icon: URL(string: "https://ipfs.blocto.app/ipfs/QmTmQQBz5KfVUcHW83S3kxqh29vSQ3cH7pcsc6cngYsG5U") + ) + private(set) var network: Network + private(set) var environment: BloctoEnvironment + + private let bloctoAppIdentifier: String + + private var bloctoAppScheme: String { + switch environment { + case .prod: + return "blocto://" + case .dev: + return "blocto-dev://" + } + } + + private var bloctoApiBaseURLString: String { + switch environment { + case .prod: + return "https://api.blocto.app" + case .dev: + return "https://api-dev.blocto.app" + } + } + + private var webAuthnURL: URL? { + switch environment { + case .prod: + return URL(string: "https://flow-wallet.blocto.app/api/flow/authn") + case .dev: + return URL(string: "https://flow-wallet-testnet.blocto.app/api/flow/authn") + } + } + + /// Initial wallet provider + /// - Parameters: + /// - bloctoAppIdentifier: identifier from app registered in blocto developer dashboard. + /// testnet dashboard: https://developers-staging.blocto.app/ + /// mainnet dashboard: https://developers.blocto.app/ + /// - window: used for presenting webView if no Blocto app installed. If pass nil then we will get the top ViewContoller from keyWindow. + /// - network: indicate flow network to use. + /// - logging: Enabling log message, default is true. + public init( + bloctoAppIdentifier: String, + window: UIWindow?, + network: Network, + logging: Bool = true + ) throws { + self.bloctoAppIdentifier = bloctoAppIdentifier + let getWindow = { () throws -> UIWindow in + guard let window = window ?? fcl.getKeyWindow() else { + throw FCLError.walletProviderInitFailed + } + return window + } + self.network = network + if let environment = Self.getBloctoEnvironment(by: network) { + self.environment = environment + } else { + throw FCLError.currentNetworkNotSupported + } + BloctoSDK.shared.initialize( + with: bloctoAppIdentifier, + getWindow: getWindow, + logging: logging, + environment: environment + ) + self.bloctoFlowSDK = BloctoSDK.shared.flow + } + + /// Get called when config network changed + /// - Parameter network: Flow network + public func updateNetwork(_ network: Network) throws { + self.network = network + if let environment = Self.getBloctoEnvironment(by: network) { + self.environment = environment + } else { + throw FCLError.currentNetworkNotSupported + } + BloctoSDK.shared.updateEnvironment(environment) + } + + /// Ask user to authanticate and get flow address along with account proof if provide accountProofData + /// - Parameter accountProofData: AccountProofData used for proving a user controls an on-chain account, optional. + public func authn(accountProofData: FCLAccountProofData?) async throws { + if let bloctoAppSchemeURL = URL(string: bloctoAppScheme), + await UIApplication.shared.canOpenURL(bloctoAppSchemeURL) { + // blocto app installed + try await setupUserByBloctoSDK(accountProofData) + } else { + // blocto app not install + guard let authnURL = webAuthnURL else { + throw FCLError.urlNotFound + } + var data: [String: String] = [:] + if let accountProofData = accountProofData { + data["accountProofIdentifier"] = accountProofData.appId + data["accountProofNonce"] = accountProofData.nonce + } + + let authnRequest = try RequstBuilder.buildURLRequest( + url: authnURL, + method: .httpPost, + body: data + ) + let authResponse = try await fcl.pollingRequest(authnRequest, type: .authn) + fcl.currentUser = try fcl.buildUser(authn: authResponse) + } + } + + public func getUserSignature(_ message: String) async throws -> [FCLCompositeSignature] { + guard let user = fcl.currentUser else { throw FCLError.userNotFound } + if let bloctoAppSchemeURL = URL(string: bloctoAppScheme), + await UIApplication.shared.canOpenURL(bloctoAppSchemeURL) { + // blocto app installed + return try await withCheckedThrowingContinuation { continuation in + bloctoFlowSDK.signMessage( + from: user.address.hexStringWithPrefix, + message: message + ) { result in + switch result { + case let .success(flowCompositeSignatures): + continuation.resume(returning: flowCompositeSignatures.map { + FCLCompositeSignature( + address: $0.address, + keyId: $0.keyId, + signature: $0.signature + ) + }) + case let .failure(error): + continuation.resume(throwing: error) + } + } + } + } else { + // blocto app not install + guard let userSignatureService = try fcl.serviceOfType(type: .userSignature) else { + throw FCLError.serviceNotFound + } + + let encoder = JSONEncoder() + let encodeData = try encoder.encode(["message": Data(message.utf8).toHexString()]) + let response = try await fcl.polling( + service: userSignatureService, + data: encodeData + ) + return response.userSignatures + } + } + + public func mutate( + cadence: String, + arguments: [Cadence.Argument], + limit: UInt64, + authorizers: [Cadence.Address] + ) async throws -> Identifier { + if let bloctoAppSchemeURL = URL(string: bloctoAppScheme), + await UIApplication.shared.canOpenURL(bloctoAppSchemeURL) { + + guard let userAddress = fcl.currentUser?.address else { + throw FCLError.userNotFound + } + guard let account = try await fcl.flowAPIClient.getAccountAtLatestBlock(address: userAddress) else { + throw FCLError.accountNotFound + } + guard let block = try await fcl.flowAPIClient.getLatestBlock(isSealed: true) else { + throw FCLError.latestBlockNotFound + } + + guard let cosignerKey = account.keys + .first(where: { $0.weight == 999 && $0.revoked == false }) else { + throw FCLError.keyNotFound + } + + let proposalKey = Transaction.ProposalKey( + address: userAddress, + keyIndex: cosignerKey.index, + sequenceNumber: cosignerKey.sequenceNumber + ) + + let feePayer = try await bloctoFlowSDK.getFeePayerAddress() + + let transaction = try FlowSDK.Transaction( + script: Data(cadence.utf8), + arguments: arguments, + referenceBlockId: block.blockHeader.id, + gasLimit: limit, + proposalKey: proposalKey, + payer: feePayer, + authorizers: authorizers + ) + return try await withCheckedThrowingContinuation { [weak self] continuation in + guard let self = self else { + continuation.resume(throwing: FCLError.internal) + return + } + Task { @MainActor in + self.bloctoFlowSDK.sendTransaction( + from: userAddress, + transaction: transaction + ) { result in + switch result { + case let .success(txId): + continuation.resume(returning: Identifier(hexString: txId)) + case let .failure(error): + continuation.resume(throwing: error) + } + } + } + } + } else { + return try await fcl.send([ + .transaction(script: cadence), + .computeLimit(limit), + .arguments(arguments), + ]) + } + } + + /// Retrive preSignable info for Flow transaction + /// - Parameter preSignable: Pre-defined type. + /// - Returns: Data includes proposer, payer, authorization. + /// Only used if Blocto native app not install. + public func preAuthz(preSignable: PreSignable?) async throws -> AuthData { + guard fcl.currentUser != nil else { throw FCLError.userNotFound } + // blocto app not install + guard let service = try fcl.serviceOfType(type: .preAuthz) else { + throw FCLError.preAuthzNotFound + } + + var data: Data? + if let preSignable = preSignable { + data = try JSONEncoder().encode(preSignable) + } + + // for blocto pre-authz it will response approved directly once request. + let authResponse = try await fcl.polling(service: service, data: data) + guard let authData = authResponse.data else { + throw FCLError.authDataNotFound + } + return authData + } + + public func modifyRequest(_ request: URLRequest) -> URLRequest { + var newRequest = request + newRequest.addValue(bloctoAppIdentifier, forHTTPHeaderField: "Blocto-Application-Identifier") + return newRequest + } + + /// Entry of Universal Links + /// - Parameter userActivity: the same userActivity from UIApplicationDelegate + public func continueForLinks(_ userActivity: NSUserActivity) { + BloctoSDK.shared.continue(userActivity) + } + + /// Entry of custom scheme + /// - Parameters: + /// - url: custom scheme URL + public func application(open url: URL) { + BloctoSDK.shared.application(open: url) + } + + // MARK: - Private + + private func setupUserByBloctoSDK(_ accountProofData: FCLAccountProofData?) async throws { + let (address, accountProof): (String, AccountProofSignatureData?) = try await withCheckedThrowingContinuation { continuation in + var bloctoAccountProofData: FlowAccountProofData? + if let accountProofData = accountProofData { + bloctoAccountProofData = FlowAccountProofData( + appId: accountProofData.appId, + nonce: accountProofData.nonce + ) + } + bloctoFlowSDK.authanticate(accountProofData: bloctoAccountProofData) { result in + switch result { + case let .success((address, accountProof)): + if let fclAccountProofData = accountProofData { + let fclAccountProofSignatures = accountProof.map { + FCLCompositeSignature( + address: $0.address, + keyId: $0.keyId, + signature: $0.signature + ) + } + let accountProofSignatureData = AccountProofSignatureData( + address: Address(hexString: address), + nonce: fclAccountProofData.nonce, + signatures: fclAccountProofSignatures + ) + continuation.resume(returning: (address, accountProofSignatureData)) + } else { + continuation.resume(returning: (address, nil)) + } + case let .failure(error): + continuation.resume(throwing: FCLError.authnFailed(message: String(describing: error))) + } + } + } + + fcl.currentUser = User( + address: Address(hexString: address), + accountProof: accountProof, + loggedIn: true, + expiresAt: 0, + services: [] + ) + } + + private static func getBloctoEnvironment(by network: Network) -> BloctoEnvironment? { + switch network { + case .mainnet: + return .prod + case .testnet: + return .dev + case .canarynet: + return nil + case .sandboxnet: + return nil + case .emulator: + return nil + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/DapperWalletProvider.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/DapperWalletProvider.swift new file mode 100644 index 00000000..ba5c0ac4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/DapperWalletProvider.swift @@ -0,0 +1,107 @@ +// +// DapperWalletProvider.swift +// +// +// Created by Andrew Wang on 2022/7/5. +// + +import Foundation +import FlowSDK +import Cadence + +public final class DapperWalletProvider: WalletProvider { + + public static let `default`: DapperWalletProvider = { + let info = ProviderInfo( + title: "Dapper Wallet", + desc: nil, + icon: URL(string: "https://ipfs.blocto.app/ipfs/Qmb81oGbB9qxUct7udtHsAqiJkRf4ey2bxuDhdg1ojFDfr") + ) + return DapperWalletProvider(providerInfo: info) + }() + + public var providerInfo: ProviderInfo + var user: User? + + // mainnet only for now + private var accessNodeApiString: String { + switch fcl.config.network { + case .testnet, + .canarynet, + .sandboxnet, + .emulator: + return "" + case .mainnet: + return "https://dapper-http-post.vercel.app/api/authn" + } + } + + init(providerInfo: ProviderInfo) { + self.providerInfo = providerInfo + } + + public func updateNetwork(_ network: Network) {} + + public func authn(accountProofData: FCLAccountProofData?) async throws { + let session = URLSession(configuration: .default) + let urlComponent = URLComponents(string: accessNodeApiString) + guard let requestURL = urlComponent?.url else { + throw FCLError.urlNotFound + } + var request = URLRequest(url: requestURL) + request.httpMethod = "POST" + + let pollingResponse = try await session.dataAuthnResponse(for: request) + + guard let localService = pollingResponse.local else { + throw FCLError.authenticateFailed + } + + guard let updatesService = pollingResponse.updates else { + throw FCLError.authenticateFailed + } + + if accountProofData != nil { + log(message: "Dapper not support native account proof for now.") + } + + let openBrowserTask = Task { @MainActor in + try fcl.openWithWebAuthenticationSession(localService) + let authnResponse = try await fcl.polling(service: updatesService) + fcl.currentUser = try fcl.buildUser(authn: authnResponse) + } + _ = try await openBrowserTask.result.get() + } + + public func getUserSignature(_ message: String) async throws -> [FCLCompositeSignature] { + throw FCLError.unsupported + } + + public func mutate( + cadence: String, + arguments: [Cadence.Argument], + limit: UInt64, + authorizers: [Cadence.Address] + ) async throws -> Identifier { + throw FCLError.unsupported + } + + public func preAuthz(preSignable: PreSignable?) async throws -> AuthData { + throw FCLError.unsupported + } + + public func modifyRequest(_ request: URLRequest) -> URLRequest { + /// Workaround + if fcl.config.selectedWalletProvider is DapperWalletProvider, + let url = request.url, + url.absoluteString.contains("https://dapper-http-post.vercel.app/api/authn-poll") { + /// Though POST https://dapper-http-post.vercel.app/api/authn?l6n=https://foo.com response back-channel-rpc using method HTTP/POST + /// Requesting using GET will only be accepted by dapper wallet. + var newRequest = request + newRequest.httpMethod = ServiceMethod.httpGet.httpMethod + return newRequest + } + return request + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/WalletProvider.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/WalletProvider.swift new file mode 100644 index 00000000..c6750039 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProvider/WalletProvider.swift @@ -0,0 +1,82 @@ +// +// WalletProvider.swift +// +// +// Created by Andrew Wang on 2022/7/5. +// + +import Foundation +import FlowSDK +import Cadence + +public protocol WalletProvider { + + /// Info to describe wallet provider + var providerInfo: ProviderInfo { get } + + /// Method called by user changing network of Flow blockchain. + /// - Parameter network: Flow network + func updateNetwork(_ network: Network) throws + + /// Authentication of Flow blockchain account address. if valid account proof data provided, + /// - Parameter accountProofData: Pre-defined struct used to sign for account proot. + func authn(accountProofData: FCLAccountProofData?) async throws + + /// To retrive user signatures of specific input message. + /// - Parameter message: A human readable string e.g. "message to be sign" + /// - Returns: Pre-defined signature array. + func getUserSignature(_ message: String) async throws -> [FCLCompositeSignature] + + /// Modify Flow blockchain state with transaction compositions. + /// - Parameters: + /// - cadence: Transaction script of Flow transaction. + /// - arguments: Arguments of Flow transaction. + /// - limit: Gas limit (compute limit) of Flow transaction. + /// - authorizers: Addresses of accounts data being modify by current transaction. + /// - Returns: Transaction identifier (tx hash). + func mutate( + cadence: String, + arguments: [Cadence.Argument], + limit: UInt64, + authorizers: [Cadence.Address] + ) async throws -> Identifier + + /// Retrive preSignable info for Flow transaction. + /// - Parameter preSignable: Pre-defined type. + /// - Returns: Data includes proposer, payer, authorization. + /// Only be used if wallet provider implement web send transaction. + func preAuthz(preSignable: PreSignable?) async throws -> AuthData + + /// Method to modify url request before sending. Default implementation will not modify request. + /// - Parameter request: URLRequest about to send. + /// - Returns: URLRequest that has been modified. + func modifyRequest(_ request: URLRequest) -> URLRequest + + /// Entry of Universal Links + /// - Parameter userActivity: the same userActivity from UIApplicationDelegate + /// Only be used if wallet provider involve other native app authentication. + func continueForLinks(_ userActivity: NSUserActivity) + + /// Entry of custom scheme + /// - Parameters: + /// - url: custom scheme URL + /// Only be used if wallet provider involve other native app authentication. + func application(open url: URL) + + // TODO: implementation + /* + func openId() async throws -> JSON {} + */ +} + +extension WalletProvider { + + func modifyRequest(_ request: URLRequest) -> URLRequest { + request + } + + public func continueForLinks(_ userActivity: NSUserActivity) {} + + public func application(open url: URL) {} + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProviderSelectionViewController.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProviderSelectionViewController.swift new file mode 100644 index 00000000..6ec36bfc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletProviderSelectionViewController.swift @@ -0,0 +1,191 @@ +// +// WalletProviderSelectionViewController.swift +// FCL-SDK +// +// Created by Andrew Wang on 2022/8/24. +// + +import Foundation +import UIKit + +final class WalletProviderSelectionViewController: UIViewController { + + var onSelect: ((WalletProvider) -> Void)? + var onCancel: (() -> Void)? + + private let providers: [WalletProvider] + + private lazy var containerView: UIView = { + let view = UIView() + view.backgroundColor = .white + view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(titleLabel) + titleLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true + titleLabel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true + titleLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true + view.addSubview(stackView) + stackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20).isActive = true + stackView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true + stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true + stackView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true + return view + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.text = "Select a wallet" + label.font = .systemFont(ofSize: 24) + label.textColor = .black + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var cancelButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.setBackgroundImage(nil, for: .normal) + button.addTarget(self, action: #selector(self.onCancel(sender:)), for: .touchUpInside) + return button + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView() + stackView.axis = .vertical + stackView.distribution = .equalSpacing + stackView.alignment = .fill + stackView.spacing = 12 + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + init(providers: [WalletProvider]) { + self.providers = providers + super.init(nibName: nil, bundle: nil) + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + view.addSubview(cancelButton) + cancelButton.topAnchor.constraint(equalTo: view.topAnchor).isActive = true + cancelButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + cancelButton.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + cancelButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + + cancelButton.addSubview(containerView) + containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true + containerView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 50).isActive = true + containerView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -50).isActive = true + + for (index, provider) in providers.enumerated() { + let button = createProviderSelectionButton(from: provider.providerInfo, index: index) + button.addTarget(self, action: #selector(onClicked(sender:)), for: .touchUpInside) + stackView.addArrangedSubview(button) + } + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + containerView.layer.cornerRadius = 10 + containerView.clipsToBounds = true + } + + private func createProviderSelectionButton(from info: ProviderInfo, index: Int) -> UIButton { + let iconImage = UIImageView() + if let iconURL = info.icon { + let request = URLRequest(url: iconURL) + URLSession(configuration: .default) + .dataTask(with: request) { data, _, error in + if let error = error { + log(message: String(describing: error)) + return + } + guard let data = data else { + log(message: "Icon image data not found.") + return + } + + DispatchQueue.main.async { + iconImage.image = UIImage(data: data) + } + }.resume() + } + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.heightAnchor.constraint(equalToConstant: 65).isActive = true + button.tag = index + button.layer.cornerRadius = 10 + button.layer.borderWidth = 1 + button.layer.borderColor = UIColor(red: 225 / 255, green: 225 / 255, blue: 225 / 255, alpha: 1).cgColor + button.clipsToBounds = true + let titleLabel = UILabel() + titleLabel.font = .systemFont(ofSize: 16) + titleLabel.textColor = .black + titleLabel.text = info.title + + button.addSubview(iconImage) + + let container = UIStackView() + container.isUserInteractionEnabled = false + container.axis = .vertical + container.alignment = .leading + container.distribution = .equalSpacing + button.addSubview(container) + + container.addArrangedSubview(titleLabel) + + if let desc = info.desc { + let descLabel = UILabel() + descLabel.font = .systemFont(ofSize: 12) + descLabel.textColor = .gray + descLabel.text = desc + container.addArrangedSubview(descLabel) + } + + iconImage.translatesAutoresizingMaskIntoConstraints = false + iconImage.topAnchor.constraint(equalTo: button.topAnchor, constant: 12).isActive = true + iconImage.leftAnchor.constraint(equalTo: button.leftAnchor, constant: 12).isActive = true + iconImage.bottomAnchor.constraint(equalTo: button.bottomAnchor, constant: -12).isActive = true + iconImage.widthAnchor.constraint(equalTo: iconImage.heightAnchor).isActive = true + + container.translatesAutoresizingMaskIntoConstraints = false + container.topAnchor.constraint(equalTo: button.topAnchor, constant: 12).isActive = true + container.leftAnchor.constraint(equalTo: iconImage.rightAnchor, constant: 12).isActive = true + container.rightAnchor.constraint(equalTo: button.rightAnchor, constant: -12).isActive = true + container.bottomAnchor.constraint(equalTo: button.bottomAnchor, constant: -12).isActive = true + return button + } + + @objc + private func onClicked(sender: UIButton) { + cancelButton.isUserInteractionEnabled = false + let index = sender.tag + onSelect?(providers[index]) + onSelect = nil + onCancel = nil + } + + @objc + private func onCancel(sender: UIButton) { + cancelButton.isUserInteractionEnabled = false + onCancel?() + onCancel = nil + onSelect = nil + } +} + +// MARK: UIAdaptivePresentationControllerDelegate + +extension WalletProviderSelectionViewController: UIAdaptivePresentationControllerDelegate { + + func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { + false + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletUtilities/WalletUtilities.swift b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletUtilities/WalletUtilities.swift new file mode 100644 index 00000000..293ab8ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FCL-SDK/Sources/FCL-SDK/WalletUtilities/WalletUtilities.swift @@ -0,0 +1,32 @@ +// +// WalletUtilities.swift +// +// +// Created by Andrew Wang on 2022/7/11. +// + +import Foundation +import FlowSDK +import Cadence + +public enum WalletUtilities { + + public static func encodeAccountProof( + address: Address, + nonce: String, + appIdentifier: String, + includeDomainTag: Bool + ) -> String { + let accountProofData: RLPEncodable = [ + appIdentifier, + Data(hex: String(address.hexString)), + Data(hex: nonce), + ] + if includeDomainTag { + return (DomainTag.accountProof.rightPaddedData + accountProofData.rlpData).toHexString() + } else { + return accountProofData.rlpData.toHexString() + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/LICENSE b/one-and-half-nibble/MobileApp/Pods/FlowSDK/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/README.md b/one-and-half-nibble/MobileApp/Pods/FlowSDK/README.md new file mode 100644 index 00000000..dd99adc4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/README.md @@ -0,0 +1,594 @@ +![Flow Swift SDK](./images/logo.jpg) + + + + + +The Flow Swift SDK provides Swift developers to build decentralized apps on Apple devices that interact with the Flow blockchain. + +# Getting Started + +## Installation + +### CocoaPods + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '13.0' +use_frameworks! + +target 'ExampleApp' do + pod 'FlowSDK', '~> 0.5.0' +end +``` + +### Swift Package Manager + +- File > Swift Packages > Add Package Dependency +- Add `https://github.com/portto/flow-swift-sdk.git` +- Select "Up to Next Major" with "0.5.0" + +# Usage + +Before sending out any transactions, please install [flow-cli](https://docs.onflow.org/flow-cli/install/) and [start emulator](https://docs.onflow.org/flow-cli/start-emulator/) first. + +Check out [Flow Access API Specification](https://docs.onflow.org/access-api/) for all apis. + +## Generating Key + +Flow blockchain uses ECDSA with SHA2-256 or SHA3-256 to grant access to control user accounts. + +Create a random private key for P256 and secp256k1 curve: +```swift +import FlowSDK + +let privateKey1 = try PrivateKey(signatureAlgorithm: .ecdsaP256) +let privateKey2 = try PrivateKey(signatureAlgorithm: .ecdsaSecp256k1) +``` + +A private key has an accompanying public key: +```swift +let publicKey = privateKey.publicKey +``` + +## Creating an Account + +You must start emulator to send this transaction. Once you have a key pair, you can create a new account using: +```swift +import FlowSDK +import BigInt + +// Generate a new private key +let privateKey = try PrivateKey(signatureAlgorithm: .ecdsaSecp256k1) + +// Get the public key +let publicKey = privateKey.publicKey + +// Get flow grpc client +let client = Client(network: .emulator) + +// Define creating account script +let script = """ +import Crypto + +transaction(publicKey: PublicKey, hashAlgorithm: HashAlgorithm, weight: UFix64) { + prepare(signer: AuthAccount) { + let account = AuthAccount(payer: signer) + + // add a key to the account + account.keys.add(publicKey: publicKey, hashAlgorithm: hashAlgorithm, weight: weight) + } +} +""" + +// Get service account info +let (payerAccount, payerAccountKey, payerSigner) = try await serviceAccount(client: client) + +// Get latest reference block id +let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id + +// Define creating account transaction +var transaction = try Transaction( + script: script.data(using: .utf8)!, + arguments: [ + publicKey.cadenceArugment, + HashAlgorithm.sha3_256.cadenceArugment, + .ufix64(1000) + ], + referenceBlockId: referenceBlockId!, + gasLimit: 100, + proposalKey: .init( + address: payerAccount.address, + keyIndex: payerAccountKey.index, + sequenceNumber: payerAccountKey.sequenceNumber), + payer: payerAccount.address, + authorizers: [payerAccount.address]) + +// Sign transaction +try transaction.signEnvelope( + address: payerAccount.address, + keyIndex: payerAccountKey.index, + signer: payerSigner) + +// Send out transaction +let txId = try await client.sendTransaction(transaction: transaction) + +// Get transaction result +var result: TransactionResult? +while result?.status != .sealed { + result = try await client.getTransactionResult(id: txId) + sleep(3) +} +debugPrint(result) + +private func serviceAccount(client: Client) async throws -> (account: Account, accountKey: AccountKey, signer: InMemorySigner) { + let serviceAddress = Address(hexString: "f8d6e0586b0a20c7") + let serviceAccount = try await client.getAccountAtLatestBlock(address: serviceAddress)! + let servicePrivateKey = try PrivateKey( + data: Data(hex: "7aac2988c5c3df3325d8cd679563cc974271f9505245da53e887fa3cc36c064f"), + signatureAlgorithm: .ecdsaP256) + let servicePublicKey = servicePrivateKey.publicKey + let serviceAccountKeyIndex = serviceAccount.keys.firstIndex(where: { $0.publicKey == servicePublicKey })! + let serviceAccountKey = serviceAccount.keys[serviceAccountKeyIndex] + let signer = InMemorySigner(privateKey: servicePrivateKey, hashAlgorithm: .sha3_256) + return (account: serviceAccount, accountKey: serviceAccountKey, signer: signer) +} +``` + +## Signing a Transaction + +Below is a simple transaction of printing "Hello World!" +```swift +import FlowSDK + +let myAddress: Address +let myAccountKey: AccountKey +let myPrivateKey: PrivateKey + +// Get flow grpc client +let client = Client(network: .emulator) + +// Get latest reference block id +let referenceBlockId = try await client.getLatestBlock(isSealed: true)!.id + +var transaction = Transaction( + script: "transaction { execute { log(\"Hello, World!\") } }".data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: myAddress, + keyIndex: myAccountKey.index, + sequenceNumber: myAccountKey.sequenceNumber), + payer: myAddress) +``` + +Transaction signing is done through the Signer protocol. The simplest (and least secure) implementation of Signer is InMemorySigner. +```swift +// create a signer from your private key and configured hash algorithm +let mySigner = InMemorySigner(privateKey: myPrivateKey, hashAlgorithm: myAccountKey.hashAlgorithm) + +try transaction.signEnvelope( + address: myAddress, + keyIndex: myAccountKey.index, + signer: mySigner) +``` + +Flow introduces new concepts that allow for more flexibility when creating and signing transactions. Before trying the examples below, we recommend that you read through the [transaction signature documentation](https://github.com/onflow/flow/blob/master/docs/content/concepts/accounts-and-keys.md#signing-a-transaction). + +### [Single party, single signature](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#single-party-single-signature) + +- Proposer, payer and authorizer are the same account (`0x01`). +- Only the envelope must be signed. +- Proposal key must have full signing weight. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +let key1 = account1.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account1.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signEnvelope(address: account1.address, keyIndex: key1.index, signer: key1Signer) +``` + +### [Single party, multiple signatures](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#single-party-multiple-signatures) + +- Proposer, payer and authorizer are the same account (`0x01`). +- Only the envelope must be signed. +- Each key has weight 500, so two signatures are required. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 500 | +| `0x01` | 2 | 500 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +let key1 = account1.keys[0] +let key2 = account1.keys[1] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key2Signer: Signer = getSignerForKey2() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account1.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signEnvelope(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 1 signs the envelope with key 2 +try transaction.signEnvelope(address: account1.address, keyIndex: key2.index, signer: key2Signer) +``` + +### [Multiple parties](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | +| `0x02` | 3 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key3 = account2.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key3Signer: Signer = getSignerForKey3() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 2 signs the envelope with key 3 +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) +``` + +### [Multiple parties, two authorizers](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. +- Account `0x02` is also an authorizer to show how to include two AuthAccounts into an transaction + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 1000 | +| `0x02` | 3 | 1000 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key3 = account2.keys[0] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key3Signer: Signer = getSignerForKey3() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer1: AuthAccount, signer2: AuthAccount) { + log(signer.address) + log(signer2.address) + } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address, account2.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 2 signs the envelope with key 3 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) +``` + +### [Multiple parties, multiple signatures](https://github.com/onflow/flow/blob/master/docs/accounts-and-keys.md#multiple-parties-multiple-signatures) + +- Proposer and authorizer are the same account (`0x01`). +- Payer is a separate account (`0x02`). +- Account `0x01` signs the payload. +- Account `0x02` signs the envelope. + - Account `0x02` must sign last since it is the payer. +- Both accounts must sign twice (once with each of their keys). + +| Account | Key ID | Weight | +|-----------|--------|--------| +| `0x01` | 1 | 500 | +| `0x01` | 2 | 500 | +| `0x02` | 3 | 500 | +| `0x02` | 4 | 500 | + +```swift +let client = Client(network: .emulator) + +guard let referenceBlockId = try await client.getLatestBlock(isSealed: true)?.id else { + return +} + +guard let account1 = try await client.getAccountAtLatestBlock(address: Address(hexString: "01")) else { + return +} +guard let account2 = try await client.getAccountAtLatestBlock(address: Address(hexString: "02")) else { + return +} +let key1 = account1.keys[0] +let key2 = account1.keys[1] +let key3 = account2.keys[0] +let key4 = account2.keys[1] + +// create signer from securely-stored private key +let key1Signer: Signer = getSignerForKey1() +let key2Signer: Signer = getSignerForKey2() +let key3Signer: Signer = getSignerForKey3() +let key4Signer: Signer = getSignerForKey4() + +var transaction = Transaction( + script: """ + transaction { + prepare(signer: AuthAccount) { log(signer.address) } + } + """.data(using: .utf8)!, + referenceBlockId: referenceBlockId, + gasLimit: 100, + proposalKey: .init( + address: account1.address, + keyIndex: key1.index, + sequenceNumber: key1.sequenceNumber), + payer: account2.address, + authorizers: [account1.address]) + +// account 1 signs the envelope with key 1 +try transaction.signPayload(address: account1.address, keyIndex: key1.index, signer: key1Signer) + +// account 1 signs the payload with key 2 +try transaction.signPayload(address: account1.address, keyIndex: key2.index, signer: key2Signer) + +// account 2 signs the envelope with key 3 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key3.index, signer: key3Signer) + +// account 2 signs the envelope with key 4 +// note: payer always signs last +try transaction.signEnvelope(address: account2.address, keyIndex: key4.index, signer: key4Signer) +``` + +## Sending a Transaction + +You can submit a transaction to the network using the Access API client. +```swift +import FlowSDK + +let client = Client(host: "localhost", port: 3569) +// or +// let client = Client(network: .emulator) + +try await client.sendTransaction(transaction: transaction) +``` + +## Querying Transaction Results +After you have submitted a transaction, you can query its status by transaction ID: +```swift +let result = try await client.getTransactionResult(id: txId) +``` + +`result.status` will be one of the following values: +- unknown +- pending +- finalized +- executed +- sealed +- expired + +Check out [the documentation](https://docs.onflow.org/fcl/reference/api/#transaction-statuses) for more details. + +## Executing a Script +You can use the `executeScriptAtLatestBlock` method to execute a read-only script against the latest sealed execution state. + +Here is a simple script with a single return value: +```cadence +pub fun main(): UInt64 { + return 1 as UInt64 +} +``` + +Run script and decode as Swift type: +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let script = """ +pub fun main(): UInt64 { + return 1 as UInt64 +} +""" + +let cadenceValue: Cadence.Value = try await client.executeScriptAtLatestBlock(script: script.data(using: .utf8)!) +let value: UInt64 = try cadenceValue.toSwiftValue() +``` + +## Querying Blocks + +You can use the `getLatestBlock` method to fetch the latest block with sealed boolean flag: + +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let isSealed: Bool = true +let block = try await client.getLatestBlock(isSealed: isSealed) +``` + +Block contains BlockHeader and BlockPayload. BlockHeader contains the following fields: +- id: the ID (hash) of the block +- parentId: the ID of the previous block. +- height: the height of the block. +- timestamp: the block timestamp. + +BlockPayload contains the folowing fields: +- collectionGuarantees: an attestation signed by the nodes that have guaranteed a collection. +- seals: the attestation by verification nodes that the transactions in a previously executed block have been verified. + +## Querying Events + +You can use the `getEventsForHeightRange` method to query events. + +```swift +import FlowSDK + +let client = Client(network: .testnet) + +let events: [BlockEvents] = try await client.getEventsForHeightRange( + eventType: "flow.AccountCreated", + startHeight: 10, + endHeight: 15) +``` + +### Event Type + +An event type contains the following fields: + +The event type to filter by. Event types are namespaced by the account and contract in which they are declared. + +For example, a `Transfer` event that was defined in the `Token` contract deployed at account `0x55555555555555555555` will have a type of `A.0x55555555555555555555.Token.Transfer`. + +Read the [language documentation](https://docs.onflow.org/cadence/language/events/) for more information on how to define and emit events in Cadence. + +### Querying Accounts + +You can use getAccountAtLatestBlock to query the state of an account. + +```swift +let client = Client(network: .testnet) + +let address = Address(hexString: "0xcb2d04fc89307107") +let account = try await client.getAccountAtLatestBlock(address: address) +``` + +An `Account` contains the following fields: +- address: the account address. +- balance: the account balance. +- keys: a list of the public keys associated with this account. +- contracts: the contract code deployed at this account. + +# Examples + +Check out [example](./example/) that how to use the SDK to interact wit Flow blockchain. + +# Development + +This repo was inspired from [flow-go-sdk](https://github.com/onflow/flow-go-sdk) and make it more Swifty. + +## Generate protobuf swift files + +``` +make install +make generate-protobuf +``` + +# License + +Flow Swift SDK is available under the Apache 2.0 license. Same with [gRPC-Swift](https://github.com/grpc/grpc-swift). diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Client.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Client.swift new file mode 100644 index 00000000..45aebb36 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Client.swift @@ -0,0 +1,359 @@ +// +// Client.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence +import NIO +import GRPC + +/// A gRPC Client for the Flow Access API. +final public class Client { + + private let eventLoopGroup: EventLoopGroup + private let accessAPIClient: Flow_Access_AccessAPIAsyncClientProtocol + + public convenience init(host: String, port: Int) { + let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) + let channel = ClientConnection( + configuration: .default( + target: .host(host, port: port), + eventLoopGroup: eventLoopGroup)) + self.init( + eventLoopGroup: eventLoopGroup, + accessAPIClient: Flow_Access_AccessAPIAsyncClient(channel: channel)) + } + + public convenience init(network: Network) { + let endpoint = network.endpoint + self.init(host: endpoint.host, port: endpoint.port) + } + + init(eventLoopGroup: EventLoopGroup, + accessAPIClient: Flow_Access_AccessAPIAsyncClientProtocol) { + self.eventLoopGroup = eventLoopGroup + self.accessAPIClient = accessAPIClient + } + + /// Close stops the client connection to the access node. + public func close(_ callback: ((Error?) -> Void)? = nil) { + eventLoopGroup.shutdownGracefully { [weak self] error in + if let error = error { + callback?(error) + } + self?.accessAPIClient.channel.close() + .whenComplete{ result in + switch result { + case .success: + break + case let .failure(error): + callback?(error) + } + } + } + } + + /// Check if the access node is alive and healthy. + public func ping(options: CallOptions? = nil) async throws { + let request = Flow_Access_PingRequest() + _ = try await accessAPIClient.ping(request, callOptions: options) + } + + /// Gets a block header by ID. + public func getLatestBlockHeader( + isSealed: Bool, + options: CallOptions? = nil + ) async throws -> BlockHeader? { + let request = Flow_Access_GetLatestBlockHeaderRequest.with { + $0.isSealed = false + } + let response = try await accessAPIClient.getLatestBlockHeader(request, callOptions: options) + return response.hasBlock ? BlockHeader(response.block) : nil + } + + /// Gets a block header by ID. + public func getBlockHeaderById( + blockId: Identifier, + options: CallOptions? = nil + ) async throws -> BlockHeader? { + let request = Flow_Access_GetBlockHeaderByIDRequest.with { + $0.id = blockId.data + } + let response = try await accessAPIClient.getBlockHeaderByID(request, callOptions: options) + return response.hasBlock ? BlockHeader(response.block) : nil + } + + /// Gets a block header by height. + public func getBlockHeaderByHeight( + height: UInt64, + options: CallOptions? = nil + ) async throws -> BlockHeader? { + let request = Flow_Access_GetBlockHeaderByHeightRequest.with { + $0.height = height + } + let response = try await accessAPIClient.getBlockHeaderByHeight(request, callOptions: options) + return response.hasBlock ? BlockHeader(response.block) : nil + } + + /// Gets the full payload of the latest sealed or unsealed block. + public func getLatestBlock( + isSealed: Bool, + options: CallOptions? = nil + ) async throws -> Block? { + let request = Flow_Access_GetLatestBlockRequest.with { + $0.isSealed = isSealed + } + let response = try await accessAPIClient.getLatestBlock(request, callOptions: options) + return response.hasBlock ? Block(response.block) : nil + } + + /// Gets a full block by ID. + public func getBlockByID( + blockId: Identifier, + options: CallOptions? = nil + ) async throws -> Block? { + let request = Flow_Access_GetBlockByIDRequest.with { + $0.id = blockId.data + } + let response = try await accessAPIClient.getBlockByID(request, callOptions: options) + return response.hasBlock ? Block(response.block) : nil + } + + /// Gets a full block by height. + public func getBlockByHeight( + height: UInt64, + options: CallOptions? = nil + ) async throws -> Block? { + let request = Flow_Access_GetBlockByHeightRequest.with { + $0.height = height + } + let response = try await accessAPIClient.getBlockByHeight(request, callOptions: options) + return response.hasBlock ? Block(response.block) : nil + } + + /// Gets a collection by ID. + public func getCollection( + collectionId: Identifier, + options: CallOptions? = nil + ) async throws -> Collection? { + let request = Flow_Access_GetCollectionByIDRequest.with { + $0.id = collectionId.data + } + let response = try await accessAPIClient.getCollectionByID(request, callOptions: options) + return response.hasCollection ? Collection(response.collection) : nil + } + + /// Submits a transaction to the network. + public func sendTransaction( + transaction: Transaction, + options: CallOptions? = nil + ) async throws -> Identifier { + let request = Flow_Access_SendTransactionRequest.with { + $0.transaction = convertTransaction(transaction) + } + let response = try await accessAPIClient.sendTransaction(request, callOptions: options) + return Identifier(data: response.id) + } + + /// Gets a transaction by ID. + public func getTransaction( + id: Identifier, + options: CallOptions? = nil + ) async throws -> Transaction? { + let request = Flow_Access_GetTransactionRequest.with { + $0.id = id.data + } + let response = try await accessAPIClient.getTransaction(request, callOptions: options) + return response.hasTransaction ? Transaction(response.transaction) : nil + } + + /// Gets the result of a transaction. + public func getTransactionResult( + id: Identifier, + options: CallOptions? = nil + ) async throws -> TransactionResult { + let request = Flow_Access_GetTransactionRequest.with { + $0.id = id.data + } + let response = try await accessAPIClient.getTransactionResult(request, callOptions: options) + return try TransactionResult(response) + } + + /// Gets an account by address at the latest sealed block. + public func getAccountAtLatestBlock( + address: Address, + options: CallOptions? = nil + ) async throws -> Account? { + let request = Flow_Access_GetAccountAtLatestBlockRequest.with { + $0.address = address.data + } + let response = try await accessAPIClient.getAccountAtLatestBlock(request, callOptions: options) + return response.hasAccount ? try Account(response.account) : nil + } + + /// Gets an account by address at the given block height + public func getAccountAtBlockHeight( + address: Address, + blockHeight: UInt64, + options: CallOptions? = nil + ) async throws -> Account? { + let request = Flow_Access_GetAccountAtBlockHeightRequest.with { + $0.address = address.data + $0.blockHeight = blockHeight + } + let response = try await accessAPIClient.getAccountAtBlockHeight(request, callOptions: options) + return response.hasAccount ? try Account(response.account) : nil + } + + /// Executes a read-only Cadence script against the latest sealed execution state. + public func executeScriptAtLatestBlock( + script: Data, + arguments: [Cadence.Argument] = [], + options: CallOptions? = nil + ) async throws -> Cadence.Argument { + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + let request = try Flow_Access_ExecuteScriptAtLatestBlockRequest.with { + $0.script = script + $0.arguments = try arguments.map { try encoder.encode($0) } + } + let response = try await accessAPIClient.executeScriptAtLatestBlock(request, callOptions: options) + return try Cadence.Argument.decode(data: response.value) + } + + /// Executes a ready-only Cadence script against the execution state at the block with the given ID. + public func executeScriptAtBlockID( + blockId: Identifier, + script: Data, + arguments: [Cadence.Argument], + options: CallOptions? = nil + ) async throws -> Cadence.Argument { + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + let request = try Flow_Access_ExecuteScriptAtBlockIDRequest.with { + $0.blockID = blockId.data + $0.script = script + $0.arguments = try arguments.map { try encoder.encode($0) } + } + let response = try await accessAPIClient.executeScriptAtBlockID(request, callOptions: options) + return try Cadence.Argument.decode(data: response.value) + } + + /// Executes a ready-only Cadence script against the execution state at the given block height. + public func executeScriptAtBlockHeight( + height: UInt64, + script: Data, + arguments: [Cadence.Argument], + options: CallOptions? = nil + ) async throws -> Cadence.Argument { + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + let request = try Flow_Access_ExecuteScriptAtBlockHeightRequest.with { + $0.blockHeight = height + $0.script = script + $0.arguments = try arguments.map { try encoder.encode($0) } + } + let response = try await accessAPIClient.executeScriptAtBlockHeight(request, callOptions: options) + return try Cadence.Argument.decode(data: response.value) + } + + /// Retrieves events for all sealed blocks between the start and end block heights (inclusive) with the given type. + public func getEventsForHeightRange( + eventType: String, + startHeight: UInt64, + endHeight: UInt64, + options: CallOptions? = nil + ) async throws -> [BlockEvents] { + let request = Flow_Access_GetEventsForHeightRangeRequest.with { + $0.type = eventType + $0.startHeight = startHeight + $0.endHeight = endHeight + } + let response = try await accessAPIClient.getEventsForHeightRange(request, callOptions: options) + return try response.results.map { try BlockEvents($0) } + } + + /// Retrieves events with the given type from the specified block IDs. + public func getEventsForBlockIDs( + eventType: String, + blockIds: [Identifier], + options: CallOptions? = nil + ) async throws -> [BlockEvents] { + let request = Flow_Access_GetEventsForBlockIDsRequest.with { + $0.type = eventType + $0.blockIds = blockIds.map { $0.data } + } + let response = try await accessAPIClient.getEventsForBlockIDs(request, callOptions: options) + return try response.results.map { try BlockEvents($0) } + } + + /// Retrieves the Flow network details + public func getNetworkParameters( + options: CallOptions? = nil + ) async throws -> String { + let request = Flow_Access_GetNetworkParametersRequest() + + let response = try await accessAPIClient.getNetworkParameters(request, callOptions: options) + return response.chainID + } + + /// Retrieves the latest snapshot of the protocol state in serialized form. This is used to generate a root snapshot file + /// used by Flow nodes to bootstrap their local protocol state database. + public func getLatestProtocolStateSnapshot( + options: CallOptions? = nil + ) async throws -> Data { + let request = Flow_Access_GetLatestProtocolStateSnapshotRequest() + let response = try await accessAPIClient.getLatestProtocolStateSnapshot(request, callOptions: options) + return response.serializedSnapshot + } + + /// Gets the execution results at the block ID. + public func getExecutionResultForBlockID( + blockId: Identifier, + options: CallOptions? = nil + ) async throws -> ExecutionResult? { + let request = Flow_Access_GetExecutionResultForBlockIDRequest.with { + $0.blockID = blockId.data + } + let response = try await accessAPIClient.getExecutionResultForBlockID(request, callOptions: options) + return response.hasExecutionResult ? ExecutionResult(response.executionResult) : nil + } + +} + +extension Client { + + private func convertTransaction(_ transaction: Transaction) -> Flow_Entities_Transaction { + Flow_Entities_Transaction.with { + $0.script = transaction.script + $0.arguments = transaction.arguments + $0.referenceBlockID = transaction.referenceBlockId.data + $0.gasLimit = transaction.gasLimit + $0.proposalKey = .with { + $0.address = transaction.proposalKey.address.data + $0.keyID = UInt32(transaction.proposalKey.keyIndex) + $0.sequenceNumber = transaction.proposalKey.sequenceNumber + } + $0.payer = transaction.payer.data + $0.authorizers = transaction.authorizers.map { $0.data } + $0.payloadSignatures = transaction.payloadSignatures.map { payloadSignature in + .with { + $0.address = payloadSignature.address.data + $0.keyID = UInt32(payloadSignature.keyIndex) + $0.signature = payloadSignature.signature + } + } + $0.envelopeSignatures = transaction.envelopeSignatures.map { envelopeSignature in + .with { + $0.address = envelopeSignature.address.data + $0.keyID = UInt32(envelopeSignature.keyIndex) + $0.signature = envelopeSignature.signature + } + } + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/HashAlgorithm.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/HashAlgorithm.swift new file mode 100644 index 00000000..8aa29c5f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/HashAlgorithm.swift @@ -0,0 +1,30 @@ +// +// HashAlgorithm.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum HashAlgorithm: UInt32, RawRepresentable { + /// SHA2_256 is SHA-2 with a 256-bit digest (also referred to as SHA256). + case sha2_256 = 1 + + /// SHA3_256 is SHA-3 with a 256-bit digest. + case sha3_256 = 3 +} + +extension HashAlgorithm { + + func getDigest(message: Data) -> SHA256Digest { + let digest: SHA256Digest + switch self { + case .sha2_256: + digest = SHA256Digest(data: message.sha256())! + case .sha3_256: + digest = SHA256Digest(data: message.sha3(.sha256))! + } + return digest + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/InMemorySigner.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/InMemorySigner.swift new file mode 100644 index 00000000..410876ea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/InMemorySigner.swift @@ -0,0 +1,28 @@ +// +// InMemorySigner.swift +// +// Created by Scott on 2022/6/6. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct InMemorySigner: Signer { + + public let privateKey: PrivateKey + + public let hashAlgorithm: HashAlgorithm + + public init(privateKey: PrivateKey, hashAlgorithm: HashAlgorithm) { + self.privateKey = privateKey + self.hashAlgorithm = hashAlgorithm + } + + public var publicKey: PublicKey { + privateKey.publicKey + } + + public func sign(message: Data) throws -> Data { + try privateKey.sign(message: message, hashAlgorithm: hashAlgorithm) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PrivateKey.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PrivateKey.swift new file mode 100644 index 00000000..161631f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PrivateKey.swift @@ -0,0 +1,124 @@ +// +// PrivateKey.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import CryptoKit +import CryptoSwift +import secp256k1Swift + +public struct PrivateKey { + + public let data: Data + + public let algorithm: SignatureAlgorithm + + public let publicKey: PublicKey + + private let implementation: Implementation + + public var size: Int { + data.count + } + + public var hexString: String { + data.toHexString() + } + + public init(signatureAlgorithm: SignatureAlgorithm) throws { + self.algorithm = signatureAlgorithm + + switch signatureAlgorithm { + case .ecdsaP256: + let key = P256.Signing.PrivateKey(compactRepresentable: false) + self.data = key.rawRepresentation + self.publicKey = try PublicKey(data: key.publicKey.rawRepresentation, signatureAlgorithm: .ecdsaP256) + self.implementation = .ecdsaP256(key) + case .ecdsaSecp256k1: + let key = try secp256k1.Signing.PrivateKey(format: .uncompressed) + self.data = key.rawRepresentation + let rawPublicKey = key.publicKey.rawRepresentation + self.publicKey = try PublicKey(data: rawPublicKey.dropFirst(), signatureAlgorithm: .ecdsaSecp256k1) + self.implementation = .ecdsaSecp256k1(key) + } + } + + public init(data: Data, signatureAlgorithm: SignatureAlgorithm) throws { + self.data = data + self.algorithm = signatureAlgorithm + + switch signatureAlgorithm { + case .ecdsaP256: + let key = try P256.Signing.PrivateKey(rawRepresentation: data) + self.publicKey = try PublicKey(data: key.publicKey.rawRepresentation, signatureAlgorithm: .ecdsaP256) + self.implementation = .ecdsaP256(key) + case .ecdsaSecp256k1: + let key = try secp256k1.Signing.PrivateKey(rawRepresentation: data, format: .uncompressed) + let rawPublicKey = key.publicKey.rawRepresentation + self.publicKey = try PublicKey(data: rawPublicKey.dropFirst(), signatureAlgorithm: .ecdsaSecp256k1) + self.implementation = .ecdsaSecp256k1(key) + } + } + + /// Generates a signature. + /// - Parameter data: The data to sign. + /// - Parameter hashAlgorithm: The hash algorithm. + /// - Returns: The ECDSA Signature. + /// - Throws: If there is a failure producing the signature. + public func sign(message: Data, hashAlgorithm: HashAlgorithm) throws -> Data { + switch implementation { + case let .ecdsaP256(key): + let digest = hashAlgorithm.getDigest(message: message) + return try key.signature(for: digest).rawRepresentation + case let .ecdsaSecp256k1(key): + let digest = hashAlgorithm.getDigest(message: message) + return try key.ecdsa.signature(for: digest).compactRepresentation + } + } +} + +// MARK: - Equatable, Hashable + +extension PrivateKey: Equatable, Hashable { + + public static func == (lhs: PrivateKey, rhs: PrivateKey) -> Bool { + lhs.hashValue == rhs.hashValue + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(data) + hasher.combine(algorithm) + } + +} + +// MARK: - Error + +extension PrivateKey { + + public enum Error: Swift.Error { + case insufficientSeedLength + } +} + +// MARK: - CustomStringConvertible + +extension PrivateKey: CustomStringConvertible { + + public var description: String { + hexString + } +} + +// MARK: - Implementation + +extension PrivateKey { + + private enum Implementation { + case ecdsaP256(P256.Signing.PrivateKey) + case ecdsaSecp256k1(secp256k1.Signing.PrivateKey) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PublicKey.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PublicKey.swift new file mode 100644 index 00000000..2b84db90 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/PublicKey.swift @@ -0,0 +1,115 @@ +// +// PublicKey.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import CryptoKit +import CryptoSwift +import secp256k1Swift + +public struct PublicKey { + + public let data: Data + + public let algorithm: SignatureAlgorithm + + public var size: Int { + data.count + } + + public var hexString: String { + data.toHexString() + } + + private let implementation: Implementation + + public init(data: Data, signatureAlgorithm: SignatureAlgorithm) throws { + self.algorithm = signatureAlgorithm + + switch signatureAlgorithm { + case .ecdsaP256: + self.data = data + self.implementation = .ecdsaP256(try P256.Signing.PublicKey(rawRepresentation: data)) + case .ecdsaSecp256k1: + let rawData: Data + switch data.count { + case secp256k1.Format.compressed.length, secp256k1.Format.compressed.length - 1: + throw Error.unsupportedCompressFormat + case secp256k1.Format.uncompressed.length: + rawData = data + self.data = data.dropFirst() + case secp256k1.Format.uncompressed.length - 1: + self.data = data + rawData = Data([0x04]) + data + default: + throw Error.incorrectKeySize + } + + let key = try secp256k1.Signing.PublicKey( + rawRepresentation: [UInt8](rawData), + format: .uncompressed) + self.implementation = .ecdsaSecp256k1(key) + } + } + + public func verify(signature: Data, message: Data, hashAlgorithm: HashAlgorithm) throws -> Bool { + switch implementation { + case let .ecdsaP256(key): + let digest = hashAlgorithm.getDigest(message: message) + let ecdsaSignature = try P256.Signing.ECDSASignature(rawRepresentation: signature) + return key.isValidSignature(ecdsaSignature, for: digest) + case let .ecdsaSecp256k1(key): + let digest = hashAlgorithm.getDigest(message: message) + let ecdsaSignature = try secp256k1.Signing.ECDSASignature(compactRepresentation: signature) + return key.ecdsa.isValidSignature(ecdsaSignature, for: digest) + } + } + +} + +// MARK: - Equatable, Hashable + +extension PublicKey: Equatable, Hashable { + + public static func == (lhs: PublicKey, rhs: PublicKey) -> Bool { + lhs.hashValue == rhs.hashValue + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(data) + hasher.combine(algorithm) + } + +} + +// MARK: - Error + +extension PublicKey { + + enum Error: Swift.Error { + case unsupportedCompressFormat + case incorrectKeySize + } +} + +// MARK: - CustomStringConvertible + +extension PublicKey: CustomStringConvertible { + + public var description: String { + hexString + } +} + +// MARK: - Implementation + +extension PublicKey { + + private enum Implementation { + case ecdsaP256(P256.Signing.PublicKey) + case ecdsaSecp256k1(secp256k1.Signing.PublicKey) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SHA256Digest.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SHA256Digest.swift new file mode 100644 index 00000000..3d11f392 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SHA256Digest.swift @@ -0,0 +1,100 @@ +// +// SHA256Digest.swift +// +// Created by Scott on 2022/6/6. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import CryptoKit +import secp256k1Swift + +public struct SHA256Digest: CryptoKit.Digest, secp256k1Swift.Digest { + + let bytes: (UInt64, UInt64, UInt64, UInt64) + + init?(data: Data) { + self.init(bytes: [UInt8](data)) + } + + init?(bytes: [UInt8]) { + let some = bytes.withUnsafeBytes { bufferPointer in + return Self(bufferPointer: bufferPointer) + } + + if some != nil { + self = some! + } else { + return nil + } + } + + init?(bufferPointer: UnsafeRawBufferPointer) { + guard bufferPointer.count == 32 else { + return nil + } + + var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0)) + withUnsafeMutableBytes(of: &bytes) { targetPtr in + targetPtr.copyMemory(from: bufferPointer) + } + self.bytes = bytes + } + + public static var byteCount: Int { + return 32 + } + + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } + + // MARK: - CustomStringConvertible + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + array.appendByte(bytes.1) + array.appendByte(bytes.2) + array.appendByte(bytes.3) + return array.prefix(upTo: SHA256Digest.byteCount) + } + + public var description: String { + return "\("SHA256") digest: \(toArray())" + } + + // MARK: - Equatable + + public static func == (lhs: SHA256Digest, rhs: SHA256Digest) -> Bool { + lhs.hashValue == rhs.hashValue + } + + // MARK: - Hashable + + public func hash(into hasher: inout Hasher) { + withUnsafeBytes { hasher.combine(bytes: $0) } + } + + // MARK: - Sequence + + public func makeIterator() -> Array.Iterator { + withUnsafeBytes { + Array($0).makeIterator() + } + } + +} + +extension MutableDataProtocol { + + mutating func appendByte(_ byte: UInt64) { + withUnsafePointer( + to: byte.littleEndian, + { append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) }) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SignatureAlgorithm.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SignatureAlgorithm.swift new file mode 100644 index 00000000..c4978d79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/SignatureAlgorithm.swift @@ -0,0 +1,13 @@ +// +// SignatureAlgorithm.swift +// +// Created by Scott on 2022/6/5. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum SignatureAlgorithm: UInt32, RawRepresentable { + case ecdsaP256 = 2 + case ecdsaSecp256k1 = 3 +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/Signer.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/Signer.swift new file mode 100644 index 00000000..6ff24c52 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Crypto/Signer.swift @@ -0,0 +1,18 @@ +// +// Signer.swift +// +// Created by Scott on 2022/6/5. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public protocol Signer { + + /// PublicKey returns the verification public key corresponding to the signer + var publicKey: PublicKey { get } + + /// Signs the given message with this signer. + /// - Returns: signature + func sign(message: Data) throws -> Data +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/HashAlgorithm+Cadence.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/HashAlgorithm+Cadence.swift new file mode 100644 index 00000000..92fbceeb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/HashAlgorithm+Cadence.swift @@ -0,0 +1,34 @@ +// +// HashAlgorithm.swift +// +// Created by Scott on 2022/7/24. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +public extension HashAlgorithm { + + var cadenceArugment: Cadence.Argument { + .enum( + id: "HashAlgorithm", + fields: [ + .init( + name: "rawValue", + value: .uint8(cadenceRawValue) + ) + ] + ) + } + + var cadenceRawValue: UInt8 { + switch self { + case .sha2_256: + return 1 + case .sha3_256: + return 3 + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/PublickKey+Cadence.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/PublickKey+Cadence.swift new file mode 100644 index 00000000..c846ae51 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/PublickKey+Cadence.swift @@ -0,0 +1,35 @@ +// +// PublicKey.swift +// +// Created by Scott on 2022/7/24. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +public extension PublicKey { + + var cadenceArugment: Cadence.Argument { + .struct( + id: "PublicKey", + fields: [ + .init( + name: "publicKey", + value: .array(data.map { .uint8($0) }) + ), + .init( + name: "signatureAlgorithm", + value: .enum( + id: "SignatureAlgorithm", + fields: [ + .init( + name: "rawValue", + value: .uint8(algorithm.cadenceRawValue)) + ] + ) + ), + ] + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/SignatureAlgorithm+Cadence.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/SignatureAlgorithm+Cadence.swift new file mode 100644 index 00000000..6bad64dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Extensions/SignatureAlgorithm+Cadence.swift @@ -0,0 +1,20 @@ +// +// SignatureAlgorithm+Cadence.swift +// +// Created by Scott on 2022/7/12. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public extension SignatureAlgorithm { + + var cadenceRawValue: UInt8 { + switch self { + case .ecdsaP256: + return 1 + case .ecdsaSecp256k1: + return 2 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Account.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Account.swift new file mode 100644 index 00000000..ffeac6d4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Account.swift @@ -0,0 +1,106 @@ +// +// Account.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +/// An account on the Flow network. +public struct Account: Equatable { + + public let address: Address + + public let balance: UInt64 + + public let code: Data + + public let keys: [AccountKey] + + public let contracts: [String: Data] + + public init( + address: Address, + balance: UInt64, + code: Data, + keys: [AccountKey], + contracts: [String: Data] + ) { + self.address = address + self.balance = balance + self.code = code + self.keys = keys + self.contracts = contracts + } + + init(_ value: Flow_Entities_Account) throws { + self.address = Address(data: value.address) + self.balance = value.balance + self.code = value.code + self.keys = try value.keys.map { try AccountKey($0) } + self.contracts = value.contracts + } +} + +/// A public key associated with an account. +public struct AccountKey: Equatable { + + /// The total key weight required to authorize access to an account. + public static let weightThreshold = 1000 + + public let index: Int + + public let publicKey: PublicKey + + public let signatureAlgorithm: SignatureAlgorithm + + public let hashAlgorithm: HashAlgorithm + + public let weight: Int + + public let sequenceNumber: UInt64 + + public let revoked: Bool + + public init( + index: Int, + publicKey: PublicKey, + signatureAlgorithm: SignatureAlgorithm, + hashAlgorithm: HashAlgorithm, + weight: Int, + sequenceNumber: UInt64, + revoked: Bool = false + ) { + self.index = index + self.publicKey = publicKey + self.signatureAlgorithm = signatureAlgorithm + self.hashAlgorithm = hashAlgorithm + self.weight = weight + self.sequenceNumber = sequenceNumber + self.revoked = revoked + } + + init(_ value: Flow_Entities_AccountKey) throws { + self.index = Int(value.index) + guard let signatureAlgorithm = SignatureAlgorithm(rawValue: value.signAlgo) else { + throw Error.unsupportedSignatureAlgorithm + } + self.signatureAlgorithm = signatureAlgorithm + guard let hashAlgorithm = HashAlgorithm(rawValue: value.hashAlgo) else { + throw Error.unsupportedHashAlgorithm + } + self.hashAlgorithm = hashAlgorithm + self.publicKey = try PublicKey(data: value.publicKey, signatureAlgorithm: signatureAlgorithm) + self.weight = Int(value.weight) + self.sequenceNumber = UInt64(value.sequenceNumber) + self.revoked = value.revoked + } + + public enum Error: Swift.Error { + case unsupportedSignatureAlgorithm + case unsupportedHashAlgorithm + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Block.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Block.swift new file mode 100644 index 00000000..9db4855c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Block.swift @@ -0,0 +1,94 @@ +// +// Block.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// Block is a set of state mutations applied to the Flow blockchain. +public struct Block: Equatable { + + public let blockHeader: BlockHeader + + public let blockPayload: BlockPayload + + public var id: Identifier { + blockHeader.id + } + + public init(blockHeader: BlockHeader, blockPayload: BlockPayload) { + self.blockHeader = blockHeader + self.blockPayload = blockPayload + } + + init(_ value: Flow_Entities_Block) { + self.blockHeader = BlockHeader( + id: Identifier(data: value.id), + parentId: Identifier(data: value.parentID), + height: value.height, + timestamp: value.hasTimestamp ? value.timestamp.date : nil) + self.blockPayload = BlockPayload( + collectionGuarantees: value.collectionGuarantees.map { + CollectionGuarantee(collectionId: Identifier(data: $0.collectionID)) + }, + seals: value.blockSeals.map { + BlockSeal( + blockID: Identifier(data: $0.blockID), + executionReceiptID: Identifier(data: $0.executionReceiptID)) + }) + } +} + +/// BlockHeader is a summary of a full block. +public struct BlockHeader: Equatable { + + public let id: Identifier + + public let parentId: Identifier + + public let height: UInt64 + + public let timestamp: Date? + + public init( + id: Identifier, + parentId: Identifier, + height: UInt64, + timestamp: Date? + ) { + self.id = id + self.parentId = parentId + self.height = height + self.timestamp = timestamp + } + + init(_ value: Flow_Entities_BlockHeader) { + self.id = Identifier(data: value.id) + self.parentId = Identifier(data: value.parentID) + self.height = value.height + self.timestamp = value.hasTimestamp ? value.timestamp.date : nil + } + +} + +/// BlockPayload is the full contents of a block. +/// +/// A payload contains the collection guarantees and seals for a block. +public struct BlockPayload: Equatable { + public let collectionGuarantees: [CollectionGuarantee] + public let seals: [BlockSeal] +} + +/// BlockSeal is the attestation by verification nodes that the transactions in a previously +/// executed block have been verified. +public struct BlockSeal: Equatable { + + /// The ID of the block this Seal refers to (which will be of lower height than this block) + public let blockID: Identifier + + /// The ID of the execution receipt generated by the Verifier nodes; the work of verifying a + /// block produces the same receipt among all verifying nodes + public let executionReceiptID: Identifier +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/BlockEvents.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/BlockEvents.swift new file mode 100644 index 00000000..319280d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/BlockEvents.swift @@ -0,0 +1,39 @@ +// +// BlockEvents.swift +// +// Created by Scott on 2022/6/1. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// The events that occurred in a specific block. +public struct BlockEvents: Equatable { + + public let blockId: Identifier + + public let height: UInt64 + + public let blockDate: Date + + public let events: [Event] + + public init( + blockId: Identifier, + height: UInt64, + blockDate: Date, + events: [Event] + ) { + self.blockId = blockId + self.height = height + self.blockDate = blockDate + self.events = events + } + + init(_ value: Flow_Access_EventsResponse.Result) throws { + self.blockId = Identifier(data: value.blockID) + self.height = value.blockHeight + self.blockDate = value.blockTimestamp.date + self.events = try value.events.map { try Event($0) } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Collection.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Collection.swift new file mode 100644 index 00000000..5c7b39e1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Collection.swift @@ -0,0 +1,28 @@ +// +// Collection.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +/// A Collection is a list of transactions bundled together for inclusion in a block. +public struct Collection: Equatable { + + public let transactionIds: [Identifier] + + public init(transactionIds: [Identifier]) { + self.transactionIds = transactionIds + } + + init(_ value: Flow_Entities_Collection) { + self.transactionIds = value.transactionIds.map { Identifier(data: $0) } + } +} + +/// A CollectionGuarantee is an attestation signed by the nodes that have guaranteed a collection. +public struct CollectionGuarantee: Equatable { + + public let collectionId: Identifier +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/DomainTag.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/DomainTag.swift new file mode 100644 index 00000000..0f509495 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/DomainTag.swift @@ -0,0 +1,31 @@ +// +// DomainTag.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +private let domainTagLength = 32 + +/// A domain tag is encoded as UTF-8 bytes, right padded to a total length of 32 bytes. +public enum DomainTag: String { + + /// The prefix of all signed transaction payloads. + case transaction = "FLOW-V0.0-transaction" + + /// The prefix of all signed user space payloads. + case user = "FLOW-V0.0-user" + + /// The prefix of all signed accountProof message. + case accountProof = "FCL-ACCOUNT-PROOF-V0.0" + + public var rightPaddedData: Data { + var data = rawValue.data(using: .utf8) ?? Data() + while data.count < domainTagLength { + data.append(0) + } + return data + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Event.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Event.swift new file mode 100644 index 00000000..95929d2b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Event.swift @@ -0,0 +1,67 @@ +// +// Event.swift +// +// Created by Scott on 2022/5/20. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +public struct Event: Equatable { + /// The qualified event type. + public let type: String + + /// The ID of the transaction this event was emitted from. + public let transactionId: Identifier + + /// The index of the transaction this event was emitted from, within its containing block. + public let transactionIndex: Int + + /// The index of the event within the transaction it was emitted from. + public let eventIndex: Int + + /// Value contains the event data. + public let value: Cadence.CompositeEvent + + /// Bytes representing event data. + public let payload: Data + + public init( + type: String, + transactionId: Identifier, + transactionIndex: Int, + eventIndex: Int, + value: Cadence.CompositeEvent, + payload: Data + ) { + self.type = type + self.transactionId = transactionId + self.transactionIndex = transactionIndex + self.eventIndex = eventIndex + self.value = value + self.payload = payload + } + + init(_ value: Flow_Entities_Event) throws { + self.type = value.type + self.transactionId = Identifier(data: value.transactionID) + self.transactionIndex = Int(value.transactionIndex) + self.eventIndex = Int(value.eventIndex) + self.payload = value.payload + + if case let .event(event) = try Cadence.Argument.decode(data: value.payload).value { + self.value = event + } else { + throw Error.notEventArgument + } + } +} + +// MARK: - Error +extension Event { + + public enum Error: Swift.Error { + case notEventArgument + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/ExecutionResult.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/ExecutionResult.swift new file mode 100644 index 00000000..18b0e989 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/ExecutionResult.swift @@ -0,0 +1,114 @@ +// +// ExecutionResult.swift +// +// Created by Scott on 2022/6/1. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct ExecutionResult: Equatable { + + public let previousResultId: Identifier + + public let blockId: Identifier + + public let chunks: [Chunk] + + public let serviceEvents: [ServiceEvent] + + public init( + previousResultId: Identifier, + blockId: Identifier, + chunks: [Chunk], + serviceEvents: [ServiceEvent] + ) { + self.previousResultId = previousResultId + self.blockId = blockId + self.chunks = chunks + self.serviceEvents = serviceEvents + } + + init(_ value: Flow_Entities_ExecutionResult) { + self.previousResultId = Identifier(data: value.previousResultID) + self.blockId = Identifier(data: value.blockID) + self.chunks = value.chunks.map { Chunk($0) } + self.serviceEvents = value.serviceEvents.map { ServiceEvent($0) } + } +} + +public typealias StateCommitment = Identifier + +public struct Chunk: Equatable { + + public let collectionIndex: UInt + + /// start state when starting executing this chunk + public let startState: StateCommitment + + /// Hash of events generated by executing results + public let eventCollection: Data + + /// Block id of the execution result this chunk belongs to + public let blockId: Identifier + + /// total amount of computation used by running all txs in this chunk + public let totalComputationUsed: UInt64 + + /// number of transactions inside the collection + public let numberOfTransactions: UInt32 + + /// chunk index inside the ER (starts from zero) + public let index: UInt64 + + /// endState inferred from next chunk or from the ER + public let endState: StateCommitment + + public init( + collectionIndex: UInt, + startState: StateCommitment, + eventCollection: Data, + blockId: Identifier, + totalComputationUsed: UInt64, + numberOfTransactions: UInt32, + index: UInt64, + endState: StateCommitment + ) { + self.collectionIndex = collectionIndex + self.startState = startState + self.eventCollection = eventCollection + self.blockId = blockId + self.totalComputationUsed = totalComputationUsed + self.numberOfTransactions = numberOfTransactions + self.index = index + self.endState = endState + } + + init(_ value: Flow_Entities_Chunk) { + self.collectionIndex = UInt(value.collectionIndex) + self.startState = StateCommitment(data: value.startState) + self.eventCollection = value.eventCollection + self.blockId = Identifier(data: value.blockID) + self.totalComputationUsed = value.totalComputationUsed + self.numberOfTransactions = value.numberOfTransactions + self.index = value.index + self.endState = StateCommitment(data: value.endState) + } +} + +public struct ServiceEvent: Equatable { + + public let type: String + + public let payload: Data + + public init(type: String, payload: Data) { + self.type = type + self.payload = payload + } + + init(_ value: Flow_Entities_ServiceEvent) { + self.type = value.type + self.payload = value.payload + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Identifier.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Identifier.swift new file mode 100644 index 00000000..97bff39f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Identifier.swift @@ -0,0 +1,44 @@ +// +// Identifier.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import CryptoSwift + +public struct Identifier: Equatable { + + public static let empty = Identifier(data: Data(repeating: 0, count: 32)) + + public let data: Data + + public var hexString: String { + data.toHexString() + } + + public init(data: Data) { + self.data = data + } + + public init(hexString: String) { + self.init(data: Data(hex: hexString)) + } +} + +// MARK: - CustomStringConvertible +extension Identifier: CustomStringConvertible { + + public var description: String { + hexString + } +} + +// MARK: - ExpressibleByStringLiteral +extension Identifier: ExpressibleByStringLiteral { + + public init(stringLiteral value: String) { + self.init(hexString: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Transaction.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Transaction.swift new file mode 100644 index 00000000..c5caef6f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/Transaction.swift @@ -0,0 +1,472 @@ +// +// Transaction.swift +// +// Created by Scott on 2022/5/18. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence +import CryptoSwift + +/// A full transaction object containing a payload and signatures. +public struct Transaction: Equatable { + + /// The UTF-8 encoded Cadence source code that defines the execution logic for this transaction. + public var script: Data + + /// A list of Cadence values passed into this transaction. + /// Each argument is encoded as JSON-CDC bytes. + public private(set) var arguments: [Data] + + /// A reference to the block used to calculate the expiry of this transaction. + /// + /// A transaction is considered expired if it is submitted to Flow after refBlock + N, where N + /// is a constant defined by the network. + /// + /// For example, if a transaction references a block with height of X and the network limit is 10, + /// a block with height X+10 is the last block that is allowed to include this transaction. + public var referenceBlockId: Identifier + + /// The maximum number of computational units that can be used to execute this transaction. + public var gasLimit: UInt64 + + /// ProposalKey is the account key used to propose this transaction. + /// + /// A proposal key references a specific key on an account, along with an up-to-date + /// sequence number for that key. This sequence number is used to prevent replay attacks. + /// + /// Find more information about sequence numbers here: https://docs.onflow.org/concepts/transaction-signing/#sequence-numbers + public private(set) var proposalKey: ProposalKey + + /// The account that pays the fee for this transaction. + /// + /// Find more information about the payer role here: https://docs.onflow.org/concepts/transaction-signing/#signer-roles + public private(set) var payer: Address + + /// A list of the accounts that are authorizing this transaction to + /// mutate to their on-chain account state. + /// + /// Find more information about the authorizer role here: https://docs.onflow.org/concepts/transaction-signing/#signer-roles + public var authorizers: [Address] + + /// A list of signatures generated by the proposer and authorizer roles. + /// + /// A payload signature is generated over the inner portion of the transaction (TransactionDomainTag + payload). + /// + /// You can find more information about transaction signatures here: https://docs.onflow.org/concepts/transaction-signing/#anatomy-of-a-transaction + public private(set) var payloadSignatures: [Signature] + + /// A list of signatures generated by the payer role. + /// + /// An envelope signature is generated over the outer portion of the transaction (TransactionDomainTag + payload + payloadSignatures). + /// + /// Find more information about transaction signatures here: https://docs.onflow.org/concepts/transaction-signing/#anatomy-of-a-transaction + public private(set) var envelopeSignatures: [Signature] + + /// The canonical SHA3-256 hash of this transaction. + public var id: Identifier { + let message = encode() + let hash = message.sha3(.sha256) + return Identifier(data: hash) + } + + public init( + script: Data, + referenceBlockId: Identifier, + gasLimit: UInt64 = 9999, + proposalKey: ProposalKey, + payer: Address, + authorizers: [Address] = [], + payloadSignatures: [Signature] = [], + envelopeSignatures: [Signature] = [] + ) { + self.script = script + self.arguments = [] + self.referenceBlockId = referenceBlockId + self.gasLimit = gasLimit + self.proposalKey = proposalKey + self.payer = payer + self.authorizers = authorizers + self.payloadSignatures = payloadSignatures + self.envelopeSignatures = envelopeSignatures + } + + public init( + script: Data, + arguments: [Cadence.Argument], + referenceBlockId: Identifier, + gasLimit: UInt64 = 9999, + proposalKey: ProposalKey, + payer: Address, + authorizers: [Address] = [], + payloadSignatures: [Signature] = [], + envelopeSignatures: [Signature] = [] + ) throws { + self.init( + script: script, + referenceBlockId: referenceBlockId, + gasLimit: gasLimit, + proposalKey: proposalKey, + payer: payer, + authorizers: authorizers, + payloadSignatures: payloadSignatures, + envelopeSignatures: envelopeSignatures) + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + self.arguments = try arguments.map { try encoder.encode($0) } + } + + init(_ value: Flow_Entities_Transaction) { + self.script = value.script + self.arguments = value.arguments + self.referenceBlockId = Identifier(data: value.referenceBlockID) + self.gasLimit = value.gasLimit + self.proposalKey = ProposalKey(value.proposalKey) + self.payer = Address(data: value.payer) + self.authorizers = value.authorizers.map { Address(data: $0) } + self.payloadSignatures = [] + self.envelopeSignatures = [] + value.payloadSignatures.forEach { + addPayloadSignature( + address: Address(data: $0.address), + keyIndex: Int($0.keyID), + signature: $0.signature) + } + value.envelopeSignatures.forEach { + addEnvelopeSignature( + address: Address(data: $0.address), + keyIndex: Int($0.keyID), + signature: $0.signature) + } + } + + public func getArugment(at index: Int) throws -> Cadence.Argument { + return try JSONDecoder().decode(Cadence.Argument.self, from: arguments[index]) + } + + /// Adds a Cadence argument to this transaction. + public mutating func addArgument(_ argument: Cadence.Argument) throws { + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + let data = try encoder.encode(argument) + arguments.append(data) + } + + /// Adds Cadence arguments to this transaction. + public mutating func addArguments(_ arguments: [Cadence.Argument]) throws { + let encoder = JSONEncoder() + encoder.outputFormatting = .withoutEscapingSlashes + let argumentDatas = try arguments.map { try encoder.encode($0) } + self.arguments.append(contentsOf: argumentDatas) + } + + /// Adds a raw JSON-CDC encoded argument to this transaction. + public mutating func addRawArgument(_ argument: Data) { + self.arguments.append(argument) + } + + /// Adds raw JSON-CDC encoded arguments to this transaction. + public mutating func addRawArguments(_ arguments: [Data]) { + self.arguments = arguments + } + + /// Sets the proposal key and sequence number for this transaction. + /// + /// The first two arguments specify the account key to be used, and the last argument is the sequence + /// number being declared. + public mutating func setProposalKey(address: Address, keyIndex: Int, sequenceNumber: UInt64) { + proposalKey = ProposalKey( + address: address, + keyIndex: keyIndex, + sequenceNumber: sequenceNumber) + refreshSignerIndex() + } + + /// Sets the payer account for this transaction. + public mutating func setPayer(address: Address) { + payer = address + refreshSignerIndex() + } + + /// Adds an authorizer account to this transaction. + public mutating func addAuthorizer(address: Address) { + self.authorizers.append(address) + refreshSignerIndex() + } + +} + +// MARK: - Signer +extension Transaction { + + /// signerList returns a list of unique accounts required to sign this transaction. + /// + /// The list is returned in the following order: + /// 1. PROPOSER + /// 2. PAYER + /// 2. AUTHORIZERS (in insertion order) + /// + /// The only exception to the above ordering is for deduplication; if the same account + /// is used in multiple signing roles, only the first occurrence is included in the list. + private var signerList: [Address] { + var signers: [Address] = [] + var seen = Set
() + + if proposalKey.address != .emptyAddress, + seen.contains(proposalKey.address) == false { + signers.append(proposalKey.address) + seen.insert(proposalKey.address) + } + if payer != .emptyAddress, + seen.contains(payer) == false { + signers.append(payer) + seen.insert(payer) + } + authorizers.forEach { + if seen.contains($0) == false { + signers.append($0) + seen.insert($0) + } + } + return signers + } + + private var signerMap: [Address: Int] { + var signers: [Address: Int] = [:] + for (index, signer) in signerList.enumerated() { + signers[signer] = index + } + return signers + } + + private mutating func refreshSignerIndex() { + let signerMap = self.signerMap + for (index, signature) in payloadSignatures.enumerated() { + if let signerIndex = signerMap[signature.address] { + payloadSignatures[index].signerIndex = signerIndex + } else { + payloadSignatures[index].signerIndex = -1 + } + } + for (index, signature) in envelopeSignatures.enumerated() { + if let signerIndex = signerMap[signature.address] { + envelopeSignatures[index].signerIndex = signerIndex + } else { + envelopeSignatures[index].signerIndex = -1 + } + } + } +} + +// MARK: - Payload, Envelope +extension Transaction { + + /// Signs the transaction payload (TransactionDomainTag + payload) with the specified account key. + /// + /// The resulting signature is combined with the account address and key index before + /// being added to the transaction. + /// + /// This function returns an error if the signature cannot be generated. + public mutating func signPayload( + address: Address, + keyIndex: Int, + signer: Signer + ) throws { + let signature = try signer.sign(message: encodedPayload) + addPayloadSignature( + address: address, + keyIndex: keyIndex, + signature: signature) + } + + /// Signs the full transaction (TransactionDomainTag + payload + payload signatures) with the specified account key. + /// + /// The resulting signature is combined with the account address and key index before + /// being added to the transaction. + /// + /// This function returns an error if the signature cannot be generated. + public mutating func signEnvelope( + address: Address, + keyIndex: Int, + signer: Signer + ) throws { + let signature = try signer.sign(message: encodedEnvelope) + addEnvelopeSignature( + address: address, + keyIndex: keyIndex, + signature: signature) + } + + /// Adds a payload signature to the transaction for the given address and key index. + public mutating func addPayloadSignature(address: Address, keyIndex: Int, signature: Data) { + let signature = createSignature( + address: address, + keyIndex: keyIndex, + signature: signature) + payloadSignatures.append(signature) + payloadSignatures.sort(by: transactionAreInIncreasingOrder) + refreshSignerIndex() + } + + /// Adds an envelope signature to the transaction for the given address and key index. + public mutating func addEnvelopeSignature(address: Address, keyIndex: Int, signature: Data) { + let signature = createSignature( + address: address, + keyIndex: keyIndex, + signature: signature) + envelopeSignatures.append(signature) + envelopeSignatures.sort(by: transactionAreInIncreasingOrder) + refreshSignerIndex() + } + + private func transactionAreInIncreasingOrder( + left: Signature, + right: Signature + ) -> Bool { + if left.signerIndex == right.signerIndex { + return left.keyIndex < right.keyIndex + } else { + return left.signerIndex < right.signerIndex + } + } + + private func createSignature( + address: Address, + keyIndex: Int, + signature: Data + ) -> Signature { + let signerIndex = signerMap[address] ?? -1 + return Signature( + address: address, + signerIndex: signerIndex, + keyIndex: keyIndex, + signature: signature) + } + + public var payloadMessage: Data { + payloadRLPList.rlpData + } + + public var encodedPayload: Data { + DomainTag.transaction.rightPaddedData + payloadMessage + } + + public var payloadRLPList: RLPEncoableArray { + [ + script, + RLPEncoableArray(arguments), + referenceBlockId.data, + gasLimit, + proposalKey.address.data, + UInt(proposalKey.keyIndex), + proposalKey.sequenceNumber, + payer.data, + RLPEncoableArray(authorizers.map { $0.data }) + ] + } + + /// The signable message for the transaction envelope. + /// + /// This message is only signed by the payer account. + public var envelopeMessage: Data { + envelopeRLPList.rlpData + } + + public var encodedEnvelope: Data { + DomainTag.transaction.rightPaddedData + envelopeMessage + } + + private var envelopeRLPList: RLPEncoableArray { + [ + payloadRLPList, + RLPEncoableArray(payloadSignatures.map { $0.rlpList }) + ] + } +} + +// MARK: - RLPDecodable + +extension Transaction: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + let items = try rlpItem.getListItems() + + let payloadRLPListItemCount = 9 + let payloadRLPListItems: [RLPItem] + let hasSignature: Bool + switch items.count { + case 3: + hasSignature = true + payloadRLPListItems = try items[0].getListItems() + case payloadRLPListItemCount: + hasSignature = false + payloadRLPListItems = items + default: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + + // payload + guard payloadRLPListItems.count == payloadRLPListItemCount else { + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + self.script = try Data(rlpItem: payloadRLPListItems[0]) + self.arguments = try payloadRLPListItems[1].getListItems() + .map { try Data(rlpItem: $0) } + self.referenceBlockId = Identifier(data: try Data(rlpItem: payloadRLPListItems[2])) + self.gasLimit = try UInt64(rlpItem: payloadRLPListItems[3]) + self.proposalKey = ProposalKey( + address: Address(data: try Data(rlpItem: payloadRLPListItems[4])), + keyIndex: Int(try UInt(rlpItem: payloadRLPListItems[5])), + sequenceNumber: try UInt64(rlpItem: payloadRLPListItems[6])) + self.payer = Address(data: try Data(rlpItem: payloadRLPListItems[7])) + self.authorizers = try payloadRLPListItems[8].getListItems() + .map { Address(data: try Data(rlpItem: $0)) } + + if hasSignature { + // payloadSignatures & envelopeSignatures + self.payloadSignatures = try items[1].getListItems() + .map { try Transaction.Signature(rlpItem: $0) } + self.envelopeSignatures = try items[2].getListItems() + .map { try Transaction.Signature(rlpItem: $0) } + + for (index, payloadSignature) in payloadSignatures.enumerated() { + guard payloadSignature.signerIndex < signerList.count else { + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + payloadSignatures[index].address = signerList[payloadSignature.signerIndex] + } + for (index, envelopeSignature) in envelopeSignatures.enumerated() { + guard envelopeSignature.signerIndex < signerList.count else { + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + envelopeSignatures[index].address = signerList[envelopeSignature.signerIndex] + } + } else { + self.payloadSignatures = [] + self.envelopeSignatures = [] + } + } +} + +// MARK: - Encode, Decode + +extension Transaction { + + /// Encode serializes the full transaction data including the payload and all signatures. + public func encode() -> Data { + RLPEncoableArray([ + payloadRLPList, + RLPEncoableArray(payloadSignatures.map { $0.rlpList }), + RLPEncoableArray(envelopeSignatures.map { $0.rlpList }) + ]).rlpData + } + + /// Decode serializeds the full transaction data including the payload and all signatures. + public init(rlpData: Data) throws { + let decoder = RLPDecoder() + let items = try decoder.decodeRLPData(rlpData) + try self.init(rlpItem: items) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionProposalKey.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionProposalKey.swift new file mode 100644 index 00000000..4725a67e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionProposalKey.swift @@ -0,0 +1,32 @@ +// +// TransactionProposalKey.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +extension Transaction { + + /// The key that specifies the proposal key and sequence number for a transaction. + public struct ProposalKey: Equatable { + public let address: Address + public let keyIndex: Int + public let sequenceNumber: UInt64 + + public init(address: Address, keyIndex: Int, sequenceNumber: UInt64) { + self.address = address + self.keyIndex = keyIndex + self.sequenceNumber = sequenceNumber + } + + init(_ value: Flow_Entities_Transaction.ProposalKey) { + self.address = Address(data: value.address) + self.keyIndex = Int(value.keyID) + self.sequenceNumber = value.sequenceNumber + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionResult.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionResult.swift new file mode 100644 index 00000000..e678f91a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionResult.swift @@ -0,0 +1,44 @@ +// +// TransactionResult.swift +// +// Created by Scott on 2022/5/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public struct TransactionResult: Equatable { + public let status: TransactionStatus? + public let errorMessage: String? + public let events: [Event] + public let blockId: Identifier + + public init( + status: TransactionStatus?, + errorMessage: String?, + events: [Event], + blockId: Identifier + ) { + self.status = status + self.errorMessage = errorMessage + self.events = events + self.blockId = blockId + } + + init(_ value: Flow_Access_TransactionResultResponse) throws { + let errorMessage: String? + if value.statusCode != 0 { + errorMessage = value.errorMessage == "" ? "transaction execution failed" : value.errorMessage + } else { + errorMessage = nil + } + self.status = value.status + self.errorMessage = errorMessage + self.events = try value.events.map { try Event($0) } + self.blockId = Identifier(data: value.blockID) + } +} + +// MARK: - TransactionStatus + +public typealias TransactionStatus = Flow_Entities_TransactionStatus diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionSignature.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionSignature.swift new file mode 100644 index 00000000..e643c766 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Models/TransactionSignature.swift @@ -0,0 +1,58 @@ +// +// TransactionSignature.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import Cadence + +extension Transaction { + + /// A signature associated with a specific account key. + public struct Signature: Equatable { + public var address: Address + public var signerIndex: Int + public let keyIndex: Int + public let signature: Data + + public init( + address: Address, + signerIndex: Int, + keyIndex: Int, + signature: Data + ) { + self.address = address + self.signerIndex = signerIndex + self.keyIndex = keyIndex + self.signature = signature + } + } +} + +extension Transaction.Signature: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + let items = try rlpItem.getListItems() + guard items.count == 3 else { + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + + self.address = Address.emptyAddress + self.signerIndex = Int(try UInt(rlpItem: items[0])) + self.keyIndex = Int(try UInt(rlpItem: items[1])) + self.signature = try Data(rlpItem: items[2]) + } +} + +extension Transaction.Signature: RLPEncodableList { + + public var rlpList: RLPEncoableArray { + [ + UInt(signerIndex), + UInt(keyIndex), + signature + ] + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Network.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Network.swift new file mode 100644 index 00000000..4534f2ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Network.swift @@ -0,0 +1,47 @@ +// +// Network.swift +// +// Created by Scott on 2022/6/21. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum Network: String { + case mainnet + case testnet + case canarynet + case sandboxnet + case emulator + + var endpoint: Endpoint { + switch self { + case .mainnet: + return Endpoint(host: "access.mainnet.nodes.onflow.org", port: 9000) + case .testnet: + return Endpoint(host: "access.devnet.nodes.onflow.org", port: 9000) + case .canarynet: + return Endpoint(host: "access.canary.nodes.onflow.org", port: 9000) + case .sandboxnet: + return Endpoint(host: "access.sandboxnet.nodes.onflow.org", port: 9000) + case .emulator: + return Endpoint(host: "127.0.0.1", port: 3569) + } + } +} + +// MARK: - Endpoint + +extension Network { + + public struct Endpoint { + + public let host: String + public let port: Int + + public init(host: String, port: Int) { + self.host = host + self.port = port + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.grpc.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.grpc.swift new file mode 100644 index 00000000..74135ec6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.grpc.swift @@ -0,0 +1,1723 @@ +// +// DO NOT EDIT. +// +// Generated by the protocol buffer compiler. +// Source: flow/access/access.proto +// + +// +// Copyright 2018, gRPC Authors 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +import GRPC +import NIO +import NIOConcurrencyHelpers +import SwiftProtobuf + + +/// AccessAPI is the public-facing API provided by access nodes. +/// +/// Usage: instantiate `Flow_Access_AccessAPIClient`, then call methods of this protocol to make API calls. +public protocol Flow_Access_AccessAPIClientProtocol: GRPCClient { + var serviceName: String { get } + var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? { get } + + func ping( + _ request: Flow_Access_PingRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getLatestBlockHeader( + _ request: Flow_Access_GetLatestBlockHeaderRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getBlockHeaderByID( + _ request: Flow_Access_GetBlockHeaderByIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getBlockHeaderByHeight( + _ request: Flow_Access_GetBlockHeaderByHeightRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getLatestBlock( + _ request: Flow_Access_GetLatestBlockRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getBlockByID( + _ request: Flow_Access_GetBlockByIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getBlockByHeight( + _ request: Flow_Access_GetBlockByHeightRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getCollectionByID( + _ request: Flow_Access_GetCollectionByIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func sendTransaction( + _ request: Flow_Access_SendTransactionRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransaction( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResult( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResultByIndex( + _ request: Flow_Access_GetTransactionByIndexRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResultsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getAccount( + _ request: Flow_Access_GetAccountRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getAccountAtLatestBlock( + _ request: Flow_Access_GetAccountAtLatestBlockRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getAccountAtBlockHeight( + _ request: Flow_Access_GetAccountAtBlockHeightRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func executeScriptAtLatestBlock( + _ request: Flow_Access_ExecuteScriptAtLatestBlockRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func executeScriptAtBlockID( + _ request: Flow_Access_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func executeScriptAtBlockHeight( + _ request: Flow_Access_ExecuteScriptAtBlockHeightRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getEventsForHeightRange( + _ request: Flow_Access_GetEventsForHeightRangeRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getEventsForBlockIDs( + _ request: Flow_Access_GetEventsForBlockIDsRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getNetworkParameters( + _ request: Flow_Access_GetNetworkParametersRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getLatestProtocolStateSnapshot( + _ request: Flow_Access_GetLatestProtocolStateSnapshotRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getExecutionResultForBlockID( + _ request: Flow_Access_GetExecutionResultForBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall +} + +extension Flow_Access_AccessAPIClientProtocol { + public var serviceName: String { + return "flow.access.AccessAPI" + } + + /// Ping is used to check if the access node is alive and healthy. + /// + /// - Parameters: + /// - request: Request to send to Ping. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func ping( + _ request: Flow_Access_PingRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + /// GetLatestBlockHeader gets the latest sealed or unsealed block header. + /// + /// - Parameters: + /// - request: Request to send to GetLatestBlockHeader. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getLatestBlockHeader( + _ request: Flow_Access_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + /// GetBlockHeaderByID gets a block header by ID. + /// + /// - Parameters: + /// - request: Request to send to GetBlockHeaderByID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getBlockHeaderByID( + _ request: Flow_Access_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } + + /// GetBlockHeaderByHeight gets a block header by height. + /// + /// - Parameters: + /// - request: Request to send to GetBlockHeaderByHeight. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getBlockHeaderByHeight( + _ request: Flow_Access_GetBlockHeaderByHeightRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByHeightInterceptors() ?? [] + ) + } + + /// GetLatestBlock gets the full payload of the latest sealed or unsealed + /// block. + /// + /// - Parameters: + /// - request: Request to send to GetLatestBlock. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getLatestBlock( + _ request: Flow_Access_GetLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? [] + ) + } + + /// GetBlockByID gets a full block by ID. + /// + /// - Parameters: + /// - request: Request to send to GetBlockByID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getBlockByID( + _ request: Flow_Access_GetBlockByIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByIDInterceptors() ?? [] + ) + } + + /// GetBlockByHeight gets a full block by height. + /// + /// - Parameters: + /// - request: Request to send to GetBlockByHeight. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getBlockByHeight( + _ request: Flow_Access_GetBlockByHeightRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByHeightInterceptors() ?? [] + ) + } + + /// GetCollectionByID gets a collection by ID. + /// + /// - Parameters: + /// - request: Request to send to GetCollectionByID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getCollectionByID( + _ request: Flow_Access_GetCollectionByIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getCollectionByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetCollectionByIDInterceptors() ?? [] + ) + } + + /// SendTransaction submits a transaction to the network. + /// + /// - Parameters: + /// - request: Request to send to SendTransaction. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func sendTransaction( + _ request: Flow_Access_SendTransactionRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.sendTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? [] + ) + } + + /// GetTransaction gets a transaction by ID. + /// + /// - Parameters: + /// - request: Request to send to GetTransaction. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransaction( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? [] + ) + } + + /// GetTransactionResult gets the result of a transaction. + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResult. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResult( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + /// GetTransactionResultByIndex gets the result of a transaction at a specified + /// block and index + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResultByIndex. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResultByIndex( + _ request: Flow_Access_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + /// GetTransactionResultsByBlockID gets all the transaction results for a + /// specified block + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResultsByBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResultsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + /// GetTransactionsByBlockID gets all the transactions for a specified block + /// + /// - Parameters: + /// - request: Request to send to GetTransactionsByBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionsByBlockIDInterceptors() ?? [] + ) + } + + /// GetAccount is an alias for GetAccountAtLatestBlock. + /// + /// Warning: this function is deprecated. It behaves identically to + /// GetAccountAtLatestBlock and will be removed in a future version. + /// + /// - Parameters: + /// - request: Request to send to GetAccount. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getAccount( + _ request: Flow_Access_GetAccountRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccount.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountInterceptors() ?? [] + ) + } + + /// GetAccountAtLatestBlock gets an account by address from the latest sealed + /// execution state. + /// + /// - Parameters: + /// - request: Request to send to GetAccountAtLatestBlock. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getAccountAtLatestBlock( + _ request: Flow_Access_GetAccountAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtLatestBlockInterceptors() ?? [] + ) + } + + /// GetAccountAtBlockHeight gets an account by address at the given block + /// height + /// + /// - Parameters: + /// - request: Request to send to GetAccountAtBlockHeight. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getAccountAtBlockHeight( + _ request: Flow_Access_GetAccountAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockHeightInterceptors() ?? [] + ) + } + + /// ExecuteScriptAtLatestBlock executes a read-only Cadence script against the + /// latest sealed execution state. + /// + /// - Parameters: + /// - request: Request to send to ExecuteScriptAtLatestBlock. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func executeScriptAtLatestBlock( + _ request: Flow_Access_ExecuteScriptAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtLatestBlockInterceptors() ?? [] + ) + } + + /// ExecuteScriptAtBlockID executes a ready-only Cadence script against the + /// execution state at the block with the given ID. + /// + /// - Parameters: + /// - request: Request to send to ExecuteScriptAtBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func executeScriptAtBlockID( + _ request: Flow_Access_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + /// ExecuteScriptAtBlockHeight executes a ready-only Cadence script against the + /// execution state at the given block height. + /// + /// - Parameters: + /// - request: Request to send to ExecuteScriptAtBlockHeight. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func executeScriptAtBlockHeight( + _ request: Flow_Access_ExecuteScriptAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockHeightInterceptors() ?? [] + ) + } + + /// GetEventsForHeightRange retrieves events emitted within the specified block + /// range. + /// + /// - Parameters: + /// - request: Request to send to GetEventsForHeightRange. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getEventsForHeightRange( + _ request: Flow_Access_GetEventsForHeightRangeRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForHeightRange.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForHeightRangeInterceptors() ?? [] + ) + } + + /// GetEventsForBlockIDs retrieves events for the specified block IDs and event + /// type. + /// + /// - Parameters: + /// - request: Request to send to GetEventsForBlockIDs. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getEventsForBlockIDs( + _ request: Flow_Access_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + /// GetNetworkParameters retrieves the Flow network details + /// + /// - Parameters: + /// - request: Request to send to GetNetworkParameters. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getNetworkParameters( + _ request: Flow_Access_GetNetworkParametersRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getNetworkParameters.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetNetworkParametersInterceptors() ?? [] + ) + } + + /// GetLatestProtocolStateSnapshot retrieves the latest sealed protocol state + /// snapshot. Used by Flow nodes joining the network to bootstrap a + /// space-efficient local state. + /// + /// - Parameters: + /// - request: Request to send to GetLatestProtocolStateSnapshot. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getLatestProtocolStateSnapshot( + _ request: Flow_Access_GetLatestProtocolStateSnapshotRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestProtocolStateSnapshot.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestProtocolStateSnapshotInterceptors() ?? [] + ) + } + + /// GetExecutionResultForBlockID returns Execution Result for a given block. + /// At present, Access Node might not have execution results for every block + /// and as usual, until sealed, this data can change + /// + /// - Parameters: + /// - request: Request to send to GetExecutionResultForBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getExecutionResultForBlockID( + _ request: Flow_Access_GetExecutionResultForBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getExecutionResultForBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetExecutionResultForBlockIDInterceptors() ?? [] + ) + } +} + +#if compiler(>=5.6) +@available(*, deprecated) +extension Flow_Access_AccessAPIClient: @unchecked Sendable {} +#endif // compiler(>=5.6) + +@available(*, deprecated, renamed: "Flow_Access_AccessAPINIOClient") +public final class Flow_Access_AccessAPIClient: Flow_Access_AccessAPIClientProtocol { + private let lock = Lock() + private var _defaultCallOptions: CallOptions + private var _interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? + public let channel: GRPCChannel + public var defaultCallOptions: CallOptions { + get { self.lock.withLock { return self._defaultCallOptions } } + set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } + } + public var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? { + get { self.lock.withLock { return self._interceptors } } + set { self.lock.withLockVoid { self._interceptors = newValue } } + } + + /// Creates a client for the flow.access.AccessAPI service. + /// + /// - Parameters: + /// - channel: `GRPCChannel` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self._defaultCallOptions = defaultCallOptions + self._interceptors = interceptors + } +} + +public struct Flow_Access_AccessAPINIOClient: Flow_Access_AccessAPIClientProtocol { + public var channel: GRPCChannel + public var defaultCallOptions: CallOptions + public var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? + + /// Creates a client for the flow.access.AccessAPI service. + /// + /// - Parameters: + /// - channel: `GRPCChannel` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors + } +} + +#if compiler(>=5.6) +/// AccessAPI is the public-facing API provided by access nodes. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public protocol Flow_Access_AccessAPIAsyncClientProtocol: GRPCClient { + static var serviceDescriptor: GRPCServiceDescriptor { get } + var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? { get } + + func makePingCall( + _ request: Flow_Access_PingRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetLatestBlockHeaderCall( + _ request: Flow_Access_GetLatestBlockHeaderRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetBlockHeaderByIDCall( + _ request: Flow_Access_GetBlockHeaderByIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetBlockHeaderByHeightCall( + _ request: Flow_Access_GetBlockHeaderByHeightRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetLatestBlockCall( + _ request: Flow_Access_GetLatestBlockRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetBlockByIDCall( + _ request: Flow_Access_GetBlockByIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetBlockByHeightCall( + _ request: Flow_Access_GetBlockByHeightRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetCollectionByIDCall( + _ request: Flow_Access_GetCollectionByIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeSendTransactionCall( + _ request: Flow_Access_SendTransactionRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionCall( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultCall( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultByIndexCall( + _ request: Flow_Access_GetTransactionByIndexRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultsByBlockIDCall( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionsByBlockIDCall( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetAccountCall( + _ request: Flow_Access_GetAccountRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetAccountAtLatestBlockCall( + _ request: Flow_Access_GetAccountAtLatestBlockRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetAccountAtBlockHeightCall( + _ request: Flow_Access_GetAccountAtBlockHeightRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeExecuteScriptAtLatestBlockCall( + _ request: Flow_Access_ExecuteScriptAtLatestBlockRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeExecuteScriptAtBlockIDCall( + _ request: Flow_Access_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeExecuteScriptAtBlockHeightCall( + _ request: Flow_Access_ExecuteScriptAtBlockHeightRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetEventsForHeightRangeCall( + _ request: Flow_Access_GetEventsForHeightRangeRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetEventsForBlockIdsCall( + _ request: Flow_Access_GetEventsForBlockIDsRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetNetworkParametersCall( + _ request: Flow_Access_GetNetworkParametersRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetLatestProtocolStateSnapshotCall( + _ request: Flow_Access_GetLatestProtocolStateSnapshotRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetExecutionResultForBlockIDCall( + _ request: Flow_Access_GetExecutionResultForBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Flow_Access_AccessAPIAsyncClientProtocol { + public static var serviceDescriptor: GRPCServiceDescriptor { + return Flow_Access_AccessAPIClientMetadata.serviceDescriptor + } + + public var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? { + return nil + } + + public func makePingCall( + _ request: Flow_Access_PingRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + public func makeGetLatestBlockHeaderCall( + _ request: Flow_Access_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + public func makeGetBlockHeaderByIDCall( + _ request: Flow_Access_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } + + public func makeGetBlockHeaderByHeightCall( + _ request: Flow_Access_GetBlockHeaderByHeightRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByHeightInterceptors() ?? [] + ) + } + + public func makeGetLatestBlockCall( + _ request: Flow_Access_GetLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? [] + ) + } + + public func makeGetBlockByIDCall( + _ request: Flow_Access_GetBlockByIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByIDInterceptors() ?? [] + ) + } + + public func makeGetBlockByHeightCall( + _ request: Flow_Access_GetBlockByHeightRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByHeightInterceptors() ?? [] + ) + } + + public func makeGetCollectionByIDCall( + _ request: Flow_Access_GetCollectionByIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getCollectionByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetCollectionByIDInterceptors() ?? [] + ) + } + + public func makeSendTransactionCall( + _ request: Flow_Access_SendTransactionRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.sendTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? [] + ) + } + + public func makeGetTransactionCall( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultCall( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultByIndexCall( + _ request: Flow_Access_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultsByBlockIDCall( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + public func makeGetTransactionsByBlockIDCall( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionsByBlockIDInterceptors() ?? [] + ) + } + + public func makeGetAccountCall( + _ request: Flow_Access_GetAccountRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccount.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountInterceptors() ?? [] + ) + } + + public func makeGetAccountAtLatestBlockCall( + _ request: Flow_Access_GetAccountAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtLatestBlockInterceptors() ?? [] + ) + } + + public func makeGetAccountAtBlockHeightCall( + _ request: Flow_Access_GetAccountAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockHeightInterceptors() ?? [] + ) + } + + public func makeExecuteScriptAtLatestBlockCall( + _ request: Flow_Access_ExecuteScriptAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtLatestBlockInterceptors() ?? [] + ) + } + + public func makeExecuteScriptAtBlockIDCall( + _ request: Flow_Access_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + public func makeExecuteScriptAtBlockHeightCall( + _ request: Flow_Access_ExecuteScriptAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockHeightInterceptors() ?? [] + ) + } + + public func makeGetEventsForHeightRangeCall( + _ request: Flow_Access_GetEventsForHeightRangeRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForHeightRange.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForHeightRangeInterceptors() ?? [] + ) + } + + public func makeGetEventsForBlockIdsCall( + _ request: Flow_Access_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + public func makeGetNetworkParametersCall( + _ request: Flow_Access_GetNetworkParametersRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getNetworkParameters.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetNetworkParametersInterceptors() ?? [] + ) + } + + public func makeGetLatestProtocolStateSnapshotCall( + _ request: Flow_Access_GetLatestProtocolStateSnapshotRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestProtocolStateSnapshot.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestProtocolStateSnapshotInterceptors() ?? [] + ) + } + + public func makeGetExecutionResultForBlockIDCall( + _ request: Flow_Access_GetExecutionResultForBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getExecutionResultForBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetExecutionResultForBlockIDInterceptors() ?? [] + ) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Flow_Access_AccessAPIAsyncClientProtocol { + public func ping( + _ request: Flow_Access_PingRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_PingResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + public func getLatestBlockHeader( + _ request: Flow_Access_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockHeaderResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + public func getBlockHeaderByID( + _ request: Flow_Access_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockHeaderResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } + + public func getBlockHeaderByHeight( + _ request: Flow_Access_GetBlockHeaderByHeightRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockHeaderResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByHeightInterceptors() ?? [] + ) + } + + public func getLatestBlock( + _ request: Flow_Access_GetLatestBlockRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? [] + ) + } + + public func getBlockByID( + _ request: Flow_Access_GetBlockByIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByIDInterceptors() ?? [] + ) + } + + public func getBlockByHeight( + _ request: Flow_Access_GetBlockByHeightRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_BlockResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getBlockByHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockByHeightInterceptors() ?? [] + ) + } + + public func getCollectionByID( + _ request: Flow_Access_GetCollectionByIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_CollectionResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getCollectionByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetCollectionByIDInterceptors() ?? [] + ) + } + + public func sendTransaction( + _ request: Flow_Access_SendTransactionRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_SendTransactionResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.sendTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? [] + ) + } + + public func getTransaction( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_TransactionResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransaction.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? [] + ) + } + + public func getTransactionResult( + _ request: Flow_Access_GetTransactionRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_TransactionResultResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + public func getTransactionResultByIndex( + _ request: Flow_Access_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_TransactionResultResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + public func getTransactionResultsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_TransactionResultsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + public func getTransactionsByBlockID( + _ request: Flow_Access_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_TransactionsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getTransactionsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionsByBlockIDInterceptors() ?? [] + ) + } + + public func getAccount( + _ request: Flow_Access_GetAccountRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_GetAccountResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccount.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountInterceptors() ?? [] + ) + } + + public func getAccountAtLatestBlock( + _ request: Flow_Access_GetAccountAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_AccountResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtLatestBlockInterceptors() ?? [] + ) + } + + public func getAccountAtBlockHeight( + _ request: Flow_Access_GetAccountAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_AccountResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockHeightInterceptors() ?? [] + ) + } + + public func executeScriptAtLatestBlock( + _ request: Flow_Access_ExecuteScriptAtLatestBlockRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_ExecuteScriptResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtLatestBlock.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtLatestBlockInterceptors() ?? [] + ) + } + + public func executeScriptAtBlockID( + _ request: Flow_Access_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_ExecuteScriptResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + public func executeScriptAtBlockHeight( + _ request: Flow_Access_ExecuteScriptAtBlockHeightRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_ExecuteScriptResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockHeight.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockHeightInterceptors() ?? [] + ) + } + + public func getEventsForHeightRange( + _ request: Flow_Access_GetEventsForHeightRangeRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_EventsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForHeightRange.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForHeightRangeInterceptors() ?? [] + ) + } + + public func getEventsForBlockIDs( + _ request: Flow_Access_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_EventsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + public func getNetworkParameters( + _ request: Flow_Access_GetNetworkParametersRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_GetNetworkParametersResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getNetworkParameters.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetNetworkParametersInterceptors() ?? [] + ) + } + + public func getLatestProtocolStateSnapshot( + _ request: Flow_Access_GetLatestProtocolStateSnapshotRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_ProtocolStateSnapshotResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getLatestProtocolStateSnapshot.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestProtocolStateSnapshotInterceptors() ?? [] + ) + } + + public func getExecutionResultForBlockID( + _ request: Flow_Access_GetExecutionResultForBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Access_ExecutionResultForBlockIDResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Access_AccessAPIClientMetadata.Methods.getExecutionResultForBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetExecutionResultForBlockIDInterceptors() ?? [] + ) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct Flow_Access_AccessAPIAsyncClient: Flow_Access_AccessAPIAsyncClientProtocol { + public var channel: GRPCChannel + public var defaultCallOptions: CallOptions + public var interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? + + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Access_AccessAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors + } +} + +#endif // compiler(>=5.6) + +public protocol Flow_Access_AccessAPIClientInterceptorFactoryProtocol: GRPCSendable { + + /// - Returns: Interceptors to use when invoking 'ping'. + func makePingInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getLatestBlockHeader'. + func makeGetLatestBlockHeaderInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getBlockHeaderByID'. + func makeGetBlockHeaderByIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getBlockHeaderByHeight'. + func makeGetBlockHeaderByHeightInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getLatestBlock'. + func makeGetLatestBlockInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getBlockByID'. + func makeGetBlockByIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getBlockByHeight'. + func makeGetBlockByHeightInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getCollectionByID'. + func makeGetCollectionByIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'sendTransaction'. + func makeSendTransactionInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransaction'. + func makeGetTransactionInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResult'. + func makeGetTransactionResultInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResultByIndex'. + func makeGetTransactionResultByIndexInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResultsByBlockID'. + func makeGetTransactionResultsByBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionsByBlockID'. + func makeGetTransactionsByBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getAccount'. + func makeGetAccountInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getAccountAtLatestBlock'. + func makeGetAccountAtLatestBlockInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getAccountAtBlockHeight'. + func makeGetAccountAtBlockHeightInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'executeScriptAtLatestBlock'. + func makeExecuteScriptAtLatestBlockInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'executeScriptAtBlockID'. + func makeExecuteScriptAtBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'executeScriptAtBlockHeight'. + func makeExecuteScriptAtBlockHeightInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getEventsForHeightRange'. + func makeGetEventsForHeightRangeInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getEventsForBlockIDs'. + func makeGetEventsForBlockIDsInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getNetworkParameters'. + func makeGetNetworkParametersInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getLatestProtocolStateSnapshot'. + func makeGetLatestProtocolStateSnapshotInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getExecutionResultForBlockID'. + func makeGetExecutionResultForBlockIDInterceptors() -> [ClientInterceptor] +} + +public enum Flow_Access_AccessAPIClientMetadata { + public static let serviceDescriptor = GRPCServiceDescriptor( + name: "AccessAPI", + fullName: "flow.access.AccessAPI", + methods: [ + Flow_Access_AccessAPIClientMetadata.Methods.ping, + Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlockHeader, + Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByID, + Flow_Access_AccessAPIClientMetadata.Methods.getBlockHeaderByHeight, + Flow_Access_AccessAPIClientMetadata.Methods.getLatestBlock, + Flow_Access_AccessAPIClientMetadata.Methods.getBlockByID, + Flow_Access_AccessAPIClientMetadata.Methods.getBlockByHeight, + Flow_Access_AccessAPIClientMetadata.Methods.getCollectionByID, + Flow_Access_AccessAPIClientMetadata.Methods.sendTransaction, + Flow_Access_AccessAPIClientMetadata.Methods.getTransaction, + Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResult, + Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultByIndex, + Flow_Access_AccessAPIClientMetadata.Methods.getTransactionResultsByBlockID, + Flow_Access_AccessAPIClientMetadata.Methods.getTransactionsByBlockID, + Flow_Access_AccessAPIClientMetadata.Methods.getAccount, + Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtLatestBlock, + Flow_Access_AccessAPIClientMetadata.Methods.getAccountAtBlockHeight, + Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtLatestBlock, + Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockID, + Flow_Access_AccessAPIClientMetadata.Methods.executeScriptAtBlockHeight, + Flow_Access_AccessAPIClientMetadata.Methods.getEventsForHeightRange, + Flow_Access_AccessAPIClientMetadata.Methods.getEventsForBlockIDs, + Flow_Access_AccessAPIClientMetadata.Methods.getNetworkParameters, + Flow_Access_AccessAPIClientMetadata.Methods.getLatestProtocolStateSnapshot, + Flow_Access_AccessAPIClientMetadata.Methods.getExecutionResultForBlockID, + ] + ) + + public enum Methods { + public static let ping = GRPCMethodDescriptor( + name: "Ping", + path: "/flow.access.AccessAPI/Ping", + type: GRPCCallType.unary + ) + + public static let getLatestBlockHeader = GRPCMethodDescriptor( + name: "GetLatestBlockHeader", + path: "/flow.access.AccessAPI/GetLatestBlockHeader", + type: GRPCCallType.unary + ) + + public static let getBlockHeaderByID = GRPCMethodDescriptor( + name: "GetBlockHeaderByID", + path: "/flow.access.AccessAPI/GetBlockHeaderByID", + type: GRPCCallType.unary + ) + + public static let getBlockHeaderByHeight = GRPCMethodDescriptor( + name: "GetBlockHeaderByHeight", + path: "/flow.access.AccessAPI/GetBlockHeaderByHeight", + type: GRPCCallType.unary + ) + + public static let getLatestBlock = GRPCMethodDescriptor( + name: "GetLatestBlock", + path: "/flow.access.AccessAPI/GetLatestBlock", + type: GRPCCallType.unary + ) + + public static let getBlockByID = GRPCMethodDescriptor( + name: "GetBlockByID", + path: "/flow.access.AccessAPI/GetBlockByID", + type: GRPCCallType.unary + ) + + public static let getBlockByHeight = GRPCMethodDescriptor( + name: "GetBlockByHeight", + path: "/flow.access.AccessAPI/GetBlockByHeight", + type: GRPCCallType.unary + ) + + public static let getCollectionByID = GRPCMethodDescriptor( + name: "GetCollectionByID", + path: "/flow.access.AccessAPI/GetCollectionByID", + type: GRPCCallType.unary + ) + + public static let sendTransaction = GRPCMethodDescriptor( + name: "SendTransaction", + path: "/flow.access.AccessAPI/SendTransaction", + type: GRPCCallType.unary + ) + + public static let getTransaction = GRPCMethodDescriptor( + name: "GetTransaction", + path: "/flow.access.AccessAPI/GetTransaction", + type: GRPCCallType.unary + ) + + public static let getTransactionResult = GRPCMethodDescriptor( + name: "GetTransactionResult", + path: "/flow.access.AccessAPI/GetTransactionResult", + type: GRPCCallType.unary + ) + + public static let getTransactionResultByIndex = GRPCMethodDescriptor( + name: "GetTransactionResultByIndex", + path: "/flow.access.AccessAPI/GetTransactionResultByIndex", + type: GRPCCallType.unary + ) + + public static let getTransactionResultsByBlockID = GRPCMethodDescriptor( + name: "GetTransactionResultsByBlockID", + path: "/flow.access.AccessAPI/GetTransactionResultsByBlockID", + type: GRPCCallType.unary + ) + + public static let getTransactionsByBlockID = GRPCMethodDescriptor( + name: "GetTransactionsByBlockID", + path: "/flow.access.AccessAPI/GetTransactionsByBlockID", + type: GRPCCallType.unary + ) + + public static let getAccount = GRPCMethodDescriptor( + name: "GetAccount", + path: "/flow.access.AccessAPI/GetAccount", + type: GRPCCallType.unary + ) + + public static let getAccountAtLatestBlock = GRPCMethodDescriptor( + name: "GetAccountAtLatestBlock", + path: "/flow.access.AccessAPI/GetAccountAtLatestBlock", + type: GRPCCallType.unary + ) + + public static let getAccountAtBlockHeight = GRPCMethodDescriptor( + name: "GetAccountAtBlockHeight", + path: "/flow.access.AccessAPI/GetAccountAtBlockHeight", + type: GRPCCallType.unary + ) + + public static let executeScriptAtLatestBlock = GRPCMethodDescriptor( + name: "ExecuteScriptAtLatestBlock", + path: "/flow.access.AccessAPI/ExecuteScriptAtLatestBlock", + type: GRPCCallType.unary + ) + + public static let executeScriptAtBlockID = GRPCMethodDescriptor( + name: "ExecuteScriptAtBlockID", + path: "/flow.access.AccessAPI/ExecuteScriptAtBlockID", + type: GRPCCallType.unary + ) + + public static let executeScriptAtBlockHeight = GRPCMethodDescriptor( + name: "ExecuteScriptAtBlockHeight", + path: "/flow.access.AccessAPI/ExecuteScriptAtBlockHeight", + type: GRPCCallType.unary + ) + + public static let getEventsForHeightRange = GRPCMethodDescriptor( + name: "GetEventsForHeightRange", + path: "/flow.access.AccessAPI/GetEventsForHeightRange", + type: GRPCCallType.unary + ) + + public static let getEventsForBlockIDs = GRPCMethodDescriptor( + name: "GetEventsForBlockIDs", + path: "/flow.access.AccessAPI/GetEventsForBlockIDs", + type: GRPCCallType.unary + ) + + public static let getNetworkParameters = GRPCMethodDescriptor( + name: "GetNetworkParameters", + path: "/flow.access.AccessAPI/GetNetworkParameters", + type: GRPCCallType.unary + ) + + public static let getLatestProtocolStateSnapshot = GRPCMethodDescriptor( + name: "GetLatestProtocolStateSnapshot", + path: "/flow.access.AccessAPI/GetLatestProtocolStateSnapshot", + type: GRPCCallType.unary + ) + + public static let getExecutionResultForBlockID = GRPCMethodDescriptor( + name: "GetExecutionResultForBlockID", + path: "/flow.access.AccessAPI/GetExecutionResultForBlockID", + type: GRPCCallType.unary + ) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.pb.swift new file mode 100644 index 00000000..f781f16f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/access/access.pb.swift @@ -0,0 +1,2061 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/access/access.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Access_PingRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_PingResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetLatestBlockHeaderRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var isSealed: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetBlockHeaderByIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetBlockHeaderByHeightRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var height: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_BlockHeaderResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var block: Flow_Entities_BlockHeader { + get {return _block ?? Flow_Entities_BlockHeader()} + set {_block = newValue} + } + /// Returns true if `block` has been explicitly set. + public var hasBlock: Bool {return self._block != nil} + /// Clears the value of `block`. Subsequent reads from it will return its default value. + public mutating func clearBlock() {self._block = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _block: Flow_Entities_BlockHeader? = nil +} + +public struct Flow_Access_GetLatestBlockRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var isSealed: Bool = false + + public var fullBlockResponse: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetBlockByIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var fullBlockResponse: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetBlockByHeightRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var height: UInt64 = 0 + + public var fullBlockResponse: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_BlockResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var block: Flow_Entities_Block { + get {return _block ?? Flow_Entities_Block()} + set {_block = newValue} + } + /// Returns true if `block` has been explicitly set. + public var hasBlock: Bool {return self._block != nil} + /// Clears the value of `block`. Subsequent reads from it will return its default value. + public mutating func clearBlock() {self._block = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _block: Flow_Entities_Block? = nil +} + +public struct Flow_Access_GetCollectionByIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_CollectionResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var collection: Flow_Entities_Collection { + get {return _collection ?? Flow_Entities_Collection()} + set {_collection = newValue} + } + /// Returns true if `collection` has been explicitly set. + public var hasCollection: Bool {return self._collection != nil} + /// Clears the value of `collection`. Subsequent reads from it will return its default value. + public mutating func clearCollection() {self._collection = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _collection: Flow_Entities_Collection? = nil +} + +public struct Flow_Access_SendTransactionRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var transaction: Flow_Entities_Transaction { + get {return _transaction ?? Flow_Entities_Transaction()} + set {_transaction = newValue} + } + /// Returns true if `transaction` has been explicitly set. + public var hasTransaction: Bool {return self._transaction != nil} + /// Clears the value of `transaction`. Subsequent reads from it will return its default value. + public mutating func clearTransaction() {self._transaction = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _transaction: Flow_Entities_Transaction? = nil +} + +public struct Flow_Access_SendTransactionResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetTransactionRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetTransactionByIndexRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var index: UInt32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetTransactionsByBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_TransactionResultsResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var transactionResults: [Flow_Access_TransactionResultResponse] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_TransactionsResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var transactions: [Flow_Entities_Transaction] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_TransactionResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var transaction: Flow_Entities_Transaction { + get {return _transaction ?? Flow_Entities_Transaction()} + set {_transaction = newValue} + } + /// Returns true if `transaction` has been explicitly set. + public var hasTransaction: Bool {return self._transaction != nil} + /// Clears the value of `transaction`. Subsequent reads from it will return its default value. + public mutating func clearTransaction() {self._transaction = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _transaction: Flow_Entities_Transaction? = nil +} + +public struct Flow_Access_TransactionResultResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var status: Flow_Entities_TransactionStatus = .unknown + + public var statusCode: UInt32 = 0 + + public var errorMessage: String = String() + + public var events: [Flow_Entities_Event] = [] + + public var blockID: Data = Data() + + public var transactionID: Data = Data() + + public var collectionID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetAccountRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetAccountResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var account: Flow_Entities_Account { + get {return _account ?? Flow_Entities_Account()} + set {_account = newValue} + } + /// Returns true if `account` has been explicitly set. + public var hasAccount: Bool {return self._account != nil} + /// Clears the value of `account`. Subsequent reads from it will return its default value. + public mutating func clearAccount() {self._account = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _account: Flow_Entities_Account? = nil +} + +public struct Flow_Access_GetAccountAtLatestBlockRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_AccountResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var account: Flow_Entities_Account { + get {return _account ?? Flow_Entities_Account()} + set {_account = newValue} + } + /// Returns true if `account` has been explicitly set. + public var hasAccount: Bool {return self._account != nil} + /// Clears the value of `account`. Subsequent reads from it will return its default value. + public mutating func clearAccount() {self._account = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _account: Flow_Entities_Account? = nil +} + +public struct Flow_Access_GetAccountAtBlockHeightRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var blockHeight: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ExecuteScriptAtLatestBlockRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var script: Data = Data() + + public var arguments: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ExecuteScriptAtBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var script: Data = Data() + + public var arguments: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ExecuteScriptAtBlockHeightRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockHeight: UInt64 = 0 + + public var script: Data = Data() + + public var arguments: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ExecuteScriptResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var value: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetEventsForHeightRangeRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var type: String = String() + + public var startHeight: UInt64 = 0 + + public var endHeight: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetEventsForBlockIDsRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var type: String = String() + + public var blockIds: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_EventsResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var results: [Flow_Access_EventsResponse.Result] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct Result { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var blockHeight: UInt64 = 0 + + public var events: [Flow_Entities_Event] = [] + + public var blockTimestamp: SwiftProtobuf.Google_Protobuf_Timestamp { + get {return _blockTimestamp ?? SwiftProtobuf.Google_Protobuf_Timestamp()} + set {_blockTimestamp = newValue} + } + /// Returns true if `blockTimestamp` has been explicitly set. + public var hasBlockTimestamp: Bool {return self._blockTimestamp != nil} + /// Clears the value of `blockTimestamp`. Subsequent reads from it will return its default value. + public mutating func clearBlockTimestamp() {self._blockTimestamp = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _blockTimestamp: SwiftProtobuf.Google_Protobuf_Timestamp? = nil + } + + public init() {} +} + +public struct Flow_Access_GetNetworkParametersRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetNetworkParametersResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var chainID: String = String() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetLatestProtocolStateSnapshotRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ProtocolStateSnapshotResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var serializedSnapshot: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_GetExecutionResultForBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Access_ExecutionResultForBlockIDResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var executionResult: Flow_Entities_ExecutionResult { + get {return _executionResult ?? Flow_Entities_ExecutionResult()} + set {_executionResult = newValue} + } + /// Returns true if `executionResult` has been explicitly set. + public var hasExecutionResult: Bool {return self._executionResult != nil} + /// Clears the value of `executionResult`. Subsequent reads from it will return its default value. + public mutating func clearExecutionResult() {self._executionResult = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _executionResult: Flow_Entities_ExecutionResult? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Access_PingRequest: @unchecked Sendable {} +extension Flow_Access_PingResponse: @unchecked Sendable {} +extension Flow_Access_GetLatestBlockHeaderRequest: @unchecked Sendable {} +extension Flow_Access_GetBlockHeaderByIDRequest: @unchecked Sendable {} +extension Flow_Access_GetBlockHeaderByHeightRequest: @unchecked Sendable {} +extension Flow_Access_BlockHeaderResponse: @unchecked Sendable {} +extension Flow_Access_GetLatestBlockRequest: @unchecked Sendable {} +extension Flow_Access_GetBlockByIDRequest: @unchecked Sendable {} +extension Flow_Access_GetBlockByHeightRequest: @unchecked Sendable {} +extension Flow_Access_BlockResponse: @unchecked Sendable {} +extension Flow_Access_GetCollectionByIDRequest: @unchecked Sendable {} +extension Flow_Access_CollectionResponse: @unchecked Sendable {} +extension Flow_Access_SendTransactionRequest: @unchecked Sendable {} +extension Flow_Access_SendTransactionResponse: @unchecked Sendable {} +extension Flow_Access_GetTransactionRequest: @unchecked Sendable {} +extension Flow_Access_GetTransactionByIndexRequest: @unchecked Sendable {} +extension Flow_Access_GetTransactionsByBlockIDRequest: @unchecked Sendable {} +extension Flow_Access_TransactionResultsResponse: @unchecked Sendable {} +extension Flow_Access_TransactionsResponse: @unchecked Sendable {} +extension Flow_Access_TransactionResponse: @unchecked Sendable {} +extension Flow_Access_TransactionResultResponse: @unchecked Sendable {} +extension Flow_Access_GetAccountRequest: @unchecked Sendable {} +extension Flow_Access_GetAccountResponse: @unchecked Sendable {} +extension Flow_Access_GetAccountAtLatestBlockRequest: @unchecked Sendable {} +extension Flow_Access_AccountResponse: @unchecked Sendable {} +extension Flow_Access_GetAccountAtBlockHeightRequest: @unchecked Sendable {} +extension Flow_Access_ExecuteScriptAtLatestBlockRequest: @unchecked Sendable {} +extension Flow_Access_ExecuteScriptAtBlockIDRequest: @unchecked Sendable {} +extension Flow_Access_ExecuteScriptAtBlockHeightRequest: @unchecked Sendable {} +extension Flow_Access_ExecuteScriptResponse: @unchecked Sendable {} +extension Flow_Access_GetEventsForHeightRangeRequest: @unchecked Sendable {} +extension Flow_Access_GetEventsForBlockIDsRequest: @unchecked Sendable {} +extension Flow_Access_EventsResponse: @unchecked Sendable {} +extension Flow_Access_EventsResponse.Result: @unchecked Sendable {} +extension Flow_Access_GetNetworkParametersRequest: @unchecked Sendable {} +extension Flow_Access_GetNetworkParametersResponse: @unchecked Sendable {} +extension Flow_Access_GetLatestProtocolStateSnapshotRequest: @unchecked Sendable {} +extension Flow_Access_ProtocolStateSnapshotResponse: @unchecked Sendable {} +extension Flow_Access_GetExecutionResultForBlockIDRequest: @unchecked Sendable {} +extension Flow_Access_ExecutionResultForBlockIDResponse: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.access" + +extension Flow_Access_PingRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".PingRequest" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_PingRequest, rhs: Flow_Access_PingRequest) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_PingResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".PingResponse" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_PingResponse, rhs: Flow_Access_PingResponse) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetLatestBlockHeaderRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetLatestBlockHeaderRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "is_sealed"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.isSealed) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.isSealed != false { + try visitor.visitSingularBoolField(value: self.isSealed, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetLatestBlockHeaderRequest, rhs: Flow_Access_GetLatestBlockHeaderRequest) -> Bool { + if lhs.isSealed != rhs.isSealed {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetBlockHeaderByIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetBlockHeaderByIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetBlockHeaderByIDRequest, rhs: Flow_Access_GetBlockHeaderByIDRequest) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetBlockHeaderByHeightRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetBlockHeaderByHeightRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "height"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.height) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.height != 0 { + try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetBlockHeaderByHeightRequest, rhs: Flow_Access_GetBlockHeaderByHeightRequest) -> Bool { + if lhs.height != rhs.height {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_BlockHeaderResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BlockHeaderResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "block"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._block) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._block { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_BlockHeaderResponse, rhs: Flow_Access_BlockHeaderResponse) -> Bool { + if lhs._block != rhs._block {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetLatestBlockRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetLatestBlockRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "is_sealed"), + 2: .standard(proto: "full_block_response"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.isSealed) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.fullBlockResponse) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.isSealed != false { + try visitor.visitSingularBoolField(value: self.isSealed, fieldNumber: 1) + } + if self.fullBlockResponse != false { + try visitor.visitSingularBoolField(value: self.fullBlockResponse, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetLatestBlockRequest, rhs: Flow_Access_GetLatestBlockRequest) -> Bool { + if lhs.isSealed != rhs.isSealed {return false} + if lhs.fullBlockResponse != rhs.fullBlockResponse {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetBlockByIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetBlockByIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .standard(proto: "full_block_response"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.fullBlockResponse) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + if self.fullBlockResponse != false { + try visitor.visitSingularBoolField(value: self.fullBlockResponse, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetBlockByIDRequest, rhs: Flow_Access_GetBlockByIDRequest) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.fullBlockResponse != rhs.fullBlockResponse {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetBlockByHeightRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetBlockByHeightRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "height"), + 2: .standard(proto: "full_block_response"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.height) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.fullBlockResponse) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.height != 0 { + try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 1) + } + if self.fullBlockResponse != false { + try visitor.visitSingularBoolField(value: self.fullBlockResponse, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetBlockByHeightRequest, rhs: Flow_Access_GetBlockByHeightRequest) -> Bool { + if lhs.height != rhs.height {return false} + if lhs.fullBlockResponse != rhs.fullBlockResponse {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_BlockResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BlockResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "block"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._block) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._block { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_BlockResponse, rhs: Flow_Access_BlockResponse) -> Bool { + if lhs._block != rhs._block {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetCollectionByIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetCollectionByIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetCollectionByIDRequest, rhs: Flow_Access_GetCollectionByIDRequest) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_CollectionResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".CollectionResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "collection"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._collection) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._collection { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_CollectionResponse, rhs: Flow_Access_CollectionResponse) -> Bool { + if lhs._collection != rhs._collection {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_SendTransactionRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SendTransactionRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "transaction"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._transaction) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._transaction { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_SendTransactionRequest, rhs: Flow_Access_SendTransactionRequest) -> Bool { + if lhs._transaction != rhs._transaction {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_SendTransactionResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SendTransactionResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_SendTransactionResponse, rhs: Flow_Access_SendTransactionResponse) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetTransactionRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetTransactionRequest, rhs: Flow_Access_GetTransactionRequest) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetTransactionByIndexRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionByIndexRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .same(proto: "index"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.index) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if self.index != 0 { + try visitor.visitSingularUInt32Field(value: self.index, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetTransactionByIndexRequest, rhs: Flow_Access_GetTransactionByIndexRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.index != rhs.index {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetTransactionsByBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionsByBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetTransactionsByBlockIDRequest, rhs: Flow_Access_GetTransactionsByBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_TransactionResultsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".TransactionResultsResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "transaction_results"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.transactionResults) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.transactionResults.isEmpty { + try visitor.visitRepeatedMessageField(value: self.transactionResults, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_TransactionResultsResponse, rhs: Flow_Access_TransactionResultsResponse) -> Bool { + if lhs.transactionResults != rhs.transactionResults {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_TransactionsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".TransactionsResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "transactions"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.transactions) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.transactions.isEmpty { + try visitor.visitRepeatedMessageField(value: self.transactions, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_TransactionsResponse, rhs: Flow_Access_TransactionsResponse) -> Bool { + if lhs.transactions != rhs.transactions {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_TransactionResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".TransactionResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "transaction"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._transaction) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._transaction { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_TransactionResponse, rhs: Flow_Access_TransactionResponse) -> Bool { + if lhs._transaction != rhs._transaction {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_TransactionResultResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".TransactionResultResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "status"), + 2: .standard(proto: "status_code"), + 3: .standard(proto: "error_message"), + 4: .same(proto: "events"), + 5: .standard(proto: "block_id"), + 6: .standard(proto: "transaction_id"), + 7: .standard(proto: "collection_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.status) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.statusCode) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.events) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.transactionID) }() + case 7: try { try decoder.decodeSingularBytesField(value: &self.collectionID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.status != .unknown { + try visitor.visitSingularEnumField(value: self.status, fieldNumber: 1) + } + if self.statusCode != 0 { + try visitor.visitSingularUInt32Field(value: self.statusCode, fieldNumber: 2) + } + if !self.errorMessage.isEmpty { + try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 3) + } + if !self.events.isEmpty { + try visitor.visitRepeatedMessageField(value: self.events, fieldNumber: 4) + } + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 5) + } + if !self.transactionID.isEmpty { + try visitor.visitSingularBytesField(value: self.transactionID, fieldNumber: 6) + } + if !self.collectionID.isEmpty { + try visitor.visitSingularBytesField(value: self.collectionID, fieldNumber: 7) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_TransactionResultResponse, rhs: Flow_Access_TransactionResultResponse) -> Bool { + if lhs.status != rhs.status {return false} + if lhs.statusCode != rhs.statusCode {return false} + if lhs.errorMessage != rhs.errorMessage {return false} + if lhs.events != rhs.events {return false} + if lhs.blockID != rhs.blockID {return false} + if lhs.transactionID != rhs.transactionID {return false} + if lhs.collectionID != rhs.collectionID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetAccountRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetAccountRequest, rhs: Flow_Access_GetAccountRequest) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetAccountResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "account"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._account) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._account { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetAccountResponse, rhs: Flow_Access_GetAccountResponse) -> Bool { + if lhs._account != rhs._account {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetAccountAtLatestBlockRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountAtLatestBlockRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetAccountAtLatestBlockRequest, rhs: Flow_Access_GetAccountAtLatestBlockRequest) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_AccountResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".AccountResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "account"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._account) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._account { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_AccountResponse, rhs: Flow_Access_AccountResponse) -> Bool { + if lhs._account != rhs._account {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetAccountAtBlockHeightRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountAtBlockHeightRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + 2: .standard(proto: "block_height"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.blockHeight) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + if self.blockHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.blockHeight, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetAccountAtBlockHeightRequest, rhs: Flow_Access_GetAccountAtBlockHeightRequest) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.blockHeight != rhs.blockHeight {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ExecuteScriptAtLatestBlockRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptAtLatestBlockRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "script"), + 2: .same(proto: "arguments"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.script) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.arguments) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.script.isEmpty { + try visitor.visitSingularBytesField(value: self.script, fieldNumber: 1) + } + if !self.arguments.isEmpty { + try visitor.visitRepeatedBytesField(value: self.arguments, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ExecuteScriptAtLatestBlockRequest, rhs: Flow_Access_ExecuteScriptAtLatestBlockRequest) -> Bool { + if lhs.script != rhs.script {return false} + if lhs.arguments != rhs.arguments {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ExecuteScriptAtBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptAtBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .same(proto: "script"), + 3: .same(proto: "arguments"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.script) }() + case 3: try { try decoder.decodeRepeatedBytesField(value: &self.arguments) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.script.isEmpty { + try visitor.visitSingularBytesField(value: self.script, fieldNumber: 2) + } + if !self.arguments.isEmpty { + try visitor.visitRepeatedBytesField(value: self.arguments, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ExecuteScriptAtBlockIDRequest, rhs: Flow_Access_ExecuteScriptAtBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.script != rhs.script {return false} + if lhs.arguments != rhs.arguments {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ExecuteScriptAtBlockHeightRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptAtBlockHeightRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_height"), + 2: .same(proto: "script"), + 3: .same(proto: "arguments"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.blockHeight) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.script) }() + case 3: try { try decoder.decodeRepeatedBytesField(value: &self.arguments) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.blockHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.blockHeight, fieldNumber: 1) + } + if !self.script.isEmpty { + try visitor.visitSingularBytesField(value: self.script, fieldNumber: 2) + } + if !self.arguments.isEmpty { + try visitor.visitRepeatedBytesField(value: self.arguments, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ExecuteScriptAtBlockHeightRequest, rhs: Flow_Access_ExecuteScriptAtBlockHeightRequest) -> Bool { + if lhs.blockHeight != rhs.blockHeight {return false} + if lhs.script != rhs.script {return false} + if lhs.arguments != rhs.arguments {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ExecuteScriptResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.value.isEmpty { + try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ExecuteScriptResponse, rhs: Flow_Access_ExecuteScriptResponse) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetEventsForHeightRangeRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetEventsForHeightRangeRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "start_height"), + 3: .standard(proto: "end_height"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.startHeight) }() + case 3: try { try decoder.decodeSingularUInt64Field(value: &self.endHeight) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.type.isEmpty { + try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) + } + if self.startHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.startHeight, fieldNumber: 2) + } + if self.endHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.endHeight, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetEventsForHeightRangeRequest, rhs: Flow_Access_GetEventsForHeightRangeRequest) -> Bool { + if lhs.type != rhs.type {return false} + if lhs.startHeight != rhs.startHeight {return false} + if lhs.endHeight != rhs.endHeight {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetEventsForBlockIDsRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetEventsForBlockIDsRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "block_ids"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.blockIds) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.type.isEmpty { + try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) + } + if !self.blockIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.blockIds, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetEventsForBlockIDsRequest, rhs: Flow_Access_GetEventsForBlockIDsRequest) -> Bool { + if lhs.type != rhs.type {return false} + if lhs.blockIds != rhs.blockIds {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_EventsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EventsResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "results"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.results) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.results.isEmpty { + try visitor.visitRepeatedMessageField(value: self.results, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_EventsResponse, rhs: Flow_Access_EventsResponse) -> Bool { + if lhs.results != rhs.results {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_EventsResponse.Result: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Flow_Access_EventsResponse.protoMessageName + ".Result" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .standard(proto: "block_height"), + 3: .same(proto: "events"), + 4: .standard(proto: "block_timestamp"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.blockHeight) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.events) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._blockTimestamp) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if self.blockHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.blockHeight, fieldNumber: 2) + } + if !self.events.isEmpty { + try visitor.visitRepeatedMessageField(value: self.events, fieldNumber: 3) + } + try { if let v = self._blockTimestamp { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_EventsResponse.Result, rhs: Flow_Access_EventsResponse.Result) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.blockHeight != rhs.blockHeight {return false} + if lhs.events != rhs.events {return false} + if lhs._blockTimestamp != rhs._blockTimestamp {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetNetworkParametersRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetNetworkParametersRequest" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetNetworkParametersRequest, rhs: Flow_Access_GetNetworkParametersRequest) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetNetworkParametersResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetNetworkParametersResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "chain_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.chainID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.chainID.isEmpty { + try visitor.visitSingularStringField(value: self.chainID, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetNetworkParametersResponse, rhs: Flow_Access_GetNetworkParametersResponse) -> Bool { + if lhs.chainID != rhs.chainID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetLatestProtocolStateSnapshotRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetLatestProtocolStateSnapshotRequest" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetLatestProtocolStateSnapshotRequest, rhs: Flow_Access_GetLatestProtocolStateSnapshotRequest) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ProtocolStateSnapshotResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ProtocolStateSnapshotResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "serializedSnapshot"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.serializedSnapshot) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.serializedSnapshot.isEmpty { + try visitor.visitSingularBytesField(value: self.serializedSnapshot, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ProtocolStateSnapshotResponse, rhs: Flow_Access_ProtocolStateSnapshotResponse) -> Bool { + if lhs.serializedSnapshot != rhs.serializedSnapshot {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_GetExecutionResultForBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetExecutionResultForBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_GetExecutionResultForBlockIDRequest, rhs: Flow_Access_GetExecutionResultForBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Access_ExecutionResultForBlockIDResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecutionResultForBlockIDResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "execution_result"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._executionResult) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._executionResult { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Access_ExecutionResultForBlockIDResponse, rhs: Flow_Access_ExecutionResultForBlockIDResponse) -> Bool { + if lhs._executionResult != rhs._executionResult {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/account.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/account.pb.swift new file mode 100644 index 00000000..80ca42dc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/account.pb.swift @@ -0,0 +1,198 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/account.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_Account { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var balance: UInt64 = 0 + + public var code: Data = Data() + + public var keys: [Flow_Entities_AccountKey] = [] + + public var contracts: Dictionary = [:] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_AccountKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var index: UInt32 = 0 + + public var publicKey: Data = Data() + + public var signAlgo: UInt32 = 0 + + public var hashAlgo: UInt32 = 0 + + public var weight: UInt32 = 0 + + public var sequenceNumber: UInt32 = 0 + + public var revoked: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_Account: @unchecked Sendable {} +extension Flow_Entities_AccountKey: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_Account: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Account" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + 2: .same(proto: "balance"), + 3: .same(proto: "code"), + 4: .same(proto: "keys"), + 5: .same(proto: "contracts"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.balance) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.code) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.keys) }() + case 5: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: &self.contracts) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + if self.balance != 0 { + try visitor.visitSingularUInt64Field(value: self.balance, fieldNumber: 2) + } + if !self.code.isEmpty { + try visitor.visitSingularBytesField(value: self.code, fieldNumber: 3) + } + if !self.keys.isEmpty { + try visitor.visitRepeatedMessageField(value: self.keys, fieldNumber: 4) + } + if !self.contracts.isEmpty { + try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: self.contracts, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Account, rhs: Flow_Entities_Account) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.balance != rhs.balance {return false} + if lhs.code != rhs.code {return false} + if lhs.keys != rhs.keys {return false} + if lhs.contracts != rhs.contracts {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_AccountKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".AccountKey" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "index"), + 2: .standard(proto: "public_key"), + 3: .standard(proto: "sign_algo"), + 4: .standard(proto: "hash_algo"), + 5: .same(proto: "weight"), + 6: .standard(proto: "sequence_number"), + 7: .same(proto: "revoked"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.index) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.publicKey) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.signAlgo) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.hashAlgo) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.weight) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.sequenceNumber) }() + case 7: try { try decoder.decodeSingularBoolField(value: &self.revoked) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.index != 0 { + try visitor.visitSingularUInt32Field(value: self.index, fieldNumber: 1) + } + if !self.publicKey.isEmpty { + try visitor.visitSingularBytesField(value: self.publicKey, fieldNumber: 2) + } + if self.signAlgo != 0 { + try visitor.visitSingularUInt32Field(value: self.signAlgo, fieldNumber: 3) + } + if self.hashAlgo != 0 { + try visitor.visitSingularUInt32Field(value: self.hashAlgo, fieldNumber: 4) + } + if self.weight != 0 { + try visitor.visitSingularUInt32Field(value: self.weight, fieldNumber: 5) + } + if self.sequenceNumber != 0 { + try visitor.visitSingularUInt32Field(value: self.sequenceNumber, fieldNumber: 6) + } + if self.revoked != false { + try visitor.visitSingularBoolField(value: self.revoked, fieldNumber: 7) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_AccountKey, rhs: Flow_Entities_AccountKey) -> Bool { + if lhs.index != rhs.index {return false} + if lhs.publicKey != rhs.publicKey {return false} + if lhs.signAlgo != rhs.signAlgo {return false} + if lhs.hashAlgo != rhs.hashAlgo {return false} + if lhs.weight != rhs.weight {return false} + if lhs.sequenceNumber != rhs.sequenceNumber {return false} + if lhs.revoked != rhs.revoked {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block.pb.swift new file mode 100644 index 00000000..d84f335d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block.pb.swift @@ -0,0 +1,239 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/block.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_Block { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data { + get {return _storage._id} + set {_uniqueStorage()._id = newValue} + } + + public var parentID: Data { + get {return _storage._parentID} + set {_uniqueStorage()._parentID = newValue} + } + + public var height: UInt64 { + get {return _storage._height} + set {_uniqueStorage()._height = newValue} + } + + public var timestamp: SwiftProtobuf.Google_Protobuf_Timestamp { + get {return _storage._timestamp ?? SwiftProtobuf.Google_Protobuf_Timestamp()} + set {_uniqueStorage()._timestamp = newValue} + } + /// Returns true if `timestamp` has been explicitly set. + public var hasTimestamp: Bool {return _storage._timestamp != nil} + /// Clears the value of `timestamp`. Subsequent reads from it will return its default value. + public mutating func clearTimestamp() {_uniqueStorage()._timestamp = nil} + + public var collectionGuarantees: [Flow_Entities_CollectionGuarantee] { + get {return _storage._collectionGuarantees} + set {_uniqueStorage()._collectionGuarantees = newValue} + } + + public var blockSeals: [Flow_Entities_BlockSeal] { + get {return _storage._blockSeals} + set {_uniqueStorage()._blockSeals = newValue} + } + + public var signatures: [Data] { + get {return _storage._signatures} + set {_uniqueStorage()._signatures = newValue} + } + + public var executionReceiptMetaList: [Flow_Entities_ExecutionReceiptMeta] { + get {return _storage._executionReceiptMetaList} + set {_uniqueStorage()._executionReceiptMetaList = newValue} + } + + public var executionResultList: [Flow_Entities_ExecutionResult] { + get {return _storage._executionResultList} + set {_uniqueStorage()._executionResultList = newValue} + } + + public var blockHeader: Flow_Entities_BlockHeader { + get {return _storage._blockHeader ?? Flow_Entities_BlockHeader()} + set {_uniqueStorage()._blockHeader = newValue} + } + /// Returns true if `blockHeader` has been explicitly set. + public var hasBlockHeader: Bool {return _storage._blockHeader != nil} + /// Clears the value of `blockHeader`. Subsequent reads from it will return its default value. + public mutating func clearBlockHeader() {_uniqueStorage()._blockHeader = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_Block: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_Block: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Block" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .standard(proto: "parent_id"), + 3: .same(proto: "height"), + 4: .same(proto: "timestamp"), + 5: .standard(proto: "collection_guarantees"), + 6: .standard(proto: "block_seals"), + 7: .same(proto: "signatures"), + 8: .standard(proto: "execution_receipt_metaList"), + 9: .standard(proto: "execution_result_list"), + 10: .standard(proto: "block_header"), + ] + + fileprivate class _StorageClass { + var _id: Data = Data() + var _parentID: Data = Data() + var _height: UInt64 = 0 + var _timestamp: SwiftProtobuf.Google_Protobuf_Timestamp? = nil + var _collectionGuarantees: [Flow_Entities_CollectionGuarantee] = [] + var _blockSeals: [Flow_Entities_BlockSeal] = [] + var _signatures: [Data] = [] + var _executionReceiptMetaList: [Flow_Entities_ExecutionReceiptMeta] = [] + var _executionResultList: [Flow_Entities_ExecutionResult] = [] + var _blockHeader: Flow_Entities_BlockHeader? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _id = source._id + _parentID = source._parentID + _height = source._height + _timestamp = source._timestamp + _collectionGuarantees = source._collectionGuarantees + _blockSeals = source._blockSeals + _signatures = source._signatures + _executionReceiptMetaList = source._executionReceiptMetaList + _executionResultList = source._executionResultList + _blockHeader = source._blockHeader + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &_storage._id) }() + case 2: try { try decoder.decodeSingularBytesField(value: &_storage._parentID) }() + case 3: try { try decoder.decodeSingularUInt64Field(value: &_storage._height) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._timestamp) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &_storage._collectionGuarantees) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &_storage._blockSeals) }() + case 7: try { try decoder.decodeRepeatedBytesField(value: &_storage._signatures) }() + case 8: try { try decoder.decodeRepeatedMessageField(value: &_storage._executionReceiptMetaList) }() + case 9: try { try decoder.decodeRepeatedMessageField(value: &_storage._executionResultList) }() + case 10: try { try decoder.decodeSingularMessageField(value: &_storage._blockHeader) }() + default: break + } + } + } + } + + public func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !_storage._id.isEmpty { + try visitor.visitSingularBytesField(value: _storage._id, fieldNumber: 1) + } + if !_storage._parentID.isEmpty { + try visitor.visitSingularBytesField(value: _storage._parentID, fieldNumber: 2) + } + if _storage._height != 0 { + try visitor.visitSingularUInt64Field(value: _storage._height, fieldNumber: 3) + } + try { if let v = _storage._timestamp { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + if !_storage._collectionGuarantees.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._collectionGuarantees, fieldNumber: 5) + } + if !_storage._blockSeals.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._blockSeals, fieldNumber: 6) + } + if !_storage._signatures.isEmpty { + try visitor.visitRepeatedBytesField(value: _storage._signatures, fieldNumber: 7) + } + if !_storage._executionReceiptMetaList.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._executionReceiptMetaList, fieldNumber: 8) + } + if !_storage._executionResultList.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._executionResultList, fieldNumber: 9) + } + try { if let v = _storage._blockHeader { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Block, rhs: Flow_Entities_Block) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._id != rhs_storage._id {return false} + if _storage._parentID != rhs_storage._parentID {return false} + if _storage._height != rhs_storage._height {return false} + if _storage._timestamp != rhs_storage._timestamp {return false} + if _storage._collectionGuarantees != rhs_storage._collectionGuarantees {return false} + if _storage._blockSeals != rhs_storage._blockSeals {return false} + if _storage._signatures != rhs_storage._signatures {return false} + if _storage._executionReceiptMetaList != rhs_storage._executionReceiptMetaList {return false} + if _storage._executionResultList != rhs_storage._executionResultList {return false} + if _storage._blockHeader != rhs_storage._blockHeader {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_header.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_header.pb.swift new file mode 100644 index 00000000..713046e2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_header.pb.swift @@ -0,0 +1,175 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/block_header.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_BlockHeader { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var parentID: Data = Data() + + public var height: UInt64 = 0 + + public var timestamp: SwiftProtobuf.Google_Protobuf_Timestamp { + get {return _timestamp ?? SwiftProtobuf.Google_Protobuf_Timestamp()} + set {_timestamp = newValue} + } + /// Returns true if `timestamp` has been explicitly set. + public var hasTimestamp: Bool {return self._timestamp != nil} + /// Clears the value of `timestamp`. Subsequent reads from it will return its default value. + public mutating func clearTimestamp() {self._timestamp = nil} + + public var payloadHash: Data = Data() + + public var view: UInt64 = 0 + + /// deprecated!! value will be empty. replaced by parent_vote_indices + public var parentVoterIds: [Data] = [] + + public var parentVoterSigData: Data = Data() + + public var proposerID: Data = Data() + + public var proposerSigData: Data = Data() + + public var chainID: String = String() + + public var parentVoterIndices: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _timestamp: SwiftProtobuf.Google_Protobuf_Timestamp? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_BlockHeader: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_BlockHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BlockHeader" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .standard(proto: "parent_id"), + 3: .same(proto: "height"), + 4: .same(proto: "timestamp"), + 5: .standard(proto: "payload_hash"), + 6: .same(proto: "view"), + 7: .standard(proto: "parent_voter_ids"), + 8: .standard(proto: "parent_voter_sig_data"), + 9: .standard(proto: "proposer_id"), + 10: .standard(proto: "proposer_sig_data"), + 11: .standard(proto: "chain_id"), + 12: .standard(proto: "parent_voter_indices"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.parentID) }() + case 3: try { try decoder.decodeSingularUInt64Field(value: &self.height) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._timestamp) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.payloadHash) }() + case 6: try { try decoder.decodeSingularUInt64Field(value: &self.view) }() + case 7: try { try decoder.decodeRepeatedBytesField(value: &self.parentVoterIds) }() + case 8: try { try decoder.decodeSingularBytesField(value: &self.parentVoterSigData) }() + case 9: try { try decoder.decodeSingularBytesField(value: &self.proposerID) }() + case 10: try { try decoder.decodeSingularBytesField(value: &self.proposerSigData) }() + case 11: try { try decoder.decodeSingularStringField(value: &self.chainID) }() + case 12: try { try decoder.decodeSingularBytesField(value: &self.parentVoterIndices) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + if !self.parentID.isEmpty { + try visitor.visitSingularBytesField(value: self.parentID, fieldNumber: 2) + } + if self.height != 0 { + try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 3) + } + try { if let v = self._timestamp { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + if !self.payloadHash.isEmpty { + try visitor.visitSingularBytesField(value: self.payloadHash, fieldNumber: 5) + } + if self.view != 0 { + try visitor.visitSingularUInt64Field(value: self.view, fieldNumber: 6) + } + if !self.parentVoterIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.parentVoterIds, fieldNumber: 7) + } + if !self.parentVoterSigData.isEmpty { + try visitor.visitSingularBytesField(value: self.parentVoterSigData, fieldNumber: 8) + } + if !self.proposerID.isEmpty { + try visitor.visitSingularBytesField(value: self.proposerID, fieldNumber: 9) + } + if !self.proposerSigData.isEmpty { + try visitor.visitSingularBytesField(value: self.proposerSigData, fieldNumber: 10) + } + if !self.chainID.isEmpty { + try visitor.visitSingularStringField(value: self.chainID, fieldNumber: 11) + } + if !self.parentVoterIndices.isEmpty { + try visitor.visitSingularBytesField(value: self.parentVoterIndices, fieldNumber: 12) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_BlockHeader, rhs: Flow_Entities_BlockHeader) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.parentID != rhs.parentID {return false} + if lhs.height != rhs.height {return false} + if lhs._timestamp != rhs._timestamp {return false} + if lhs.payloadHash != rhs.payloadHash {return false} + if lhs.view != rhs.view {return false} + if lhs.parentVoterIds != rhs.parentVoterIds {return false} + if lhs.parentVoterSigData != rhs.parentVoterSigData {return false} + if lhs.proposerID != rhs.proposerID {return false} + if lhs.proposerSigData != rhs.proposerSigData {return false} + if lhs.chainID != rhs.chainID {return false} + if lhs.parentVoterIndices != rhs.parentVoterIndices {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_seal.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_seal.pb.swift new file mode 100644 index 00000000..f8c8189c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/block_seal.pb.swift @@ -0,0 +1,174 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/block_seal.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_BlockSeal { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var executionReceiptID: Data = Data() + + public var executionReceiptSignatures: [Data] = [] + + public var resultApprovalSignatures: [Data] = [] + + public var finalState: Data = Data() + + public var resultID: Data = Data() + + public var aggregatedApprovalSigs: [Flow_Entities_AggregatedSignature] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_AggregatedSignature { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var verifierSignatures: [Data] = [] + + public var signerIds: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_BlockSeal: @unchecked Sendable {} +extension Flow_Entities_AggregatedSignature: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_BlockSeal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BlockSeal" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .standard(proto: "execution_receipt_id"), + 3: .standard(proto: "execution_receipt_signatures"), + 4: .standard(proto: "result_approval_signatures"), + 5: .standard(proto: "final_state"), + 6: .standard(proto: "result_id"), + 7: .standard(proto: "aggregated_approval_sigs"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.executionReceiptID) }() + case 3: try { try decoder.decodeRepeatedBytesField(value: &self.executionReceiptSignatures) }() + case 4: try { try decoder.decodeRepeatedBytesField(value: &self.resultApprovalSignatures) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.finalState) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.resultID) }() + case 7: try { try decoder.decodeRepeatedMessageField(value: &self.aggregatedApprovalSigs) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.executionReceiptID.isEmpty { + try visitor.visitSingularBytesField(value: self.executionReceiptID, fieldNumber: 2) + } + if !self.executionReceiptSignatures.isEmpty { + try visitor.visitRepeatedBytesField(value: self.executionReceiptSignatures, fieldNumber: 3) + } + if !self.resultApprovalSignatures.isEmpty { + try visitor.visitRepeatedBytesField(value: self.resultApprovalSignatures, fieldNumber: 4) + } + if !self.finalState.isEmpty { + try visitor.visitSingularBytesField(value: self.finalState, fieldNumber: 5) + } + if !self.resultID.isEmpty { + try visitor.visitSingularBytesField(value: self.resultID, fieldNumber: 6) + } + if !self.aggregatedApprovalSigs.isEmpty { + try visitor.visitRepeatedMessageField(value: self.aggregatedApprovalSigs, fieldNumber: 7) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_BlockSeal, rhs: Flow_Entities_BlockSeal) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.executionReceiptID != rhs.executionReceiptID {return false} + if lhs.executionReceiptSignatures != rhs.executionReceiptSignatures {return false} + if lhs.resultApprovalSignatures != rhs.resultApprovalSignatures {return false} + if lhs.finalState != rhs.finalState {return false} + if lhs.resultID != rhs.resultID {return false} + if lhs.aggregatedApprovalSigs != rhs.aggregatedApprovalSigs {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_AggregatedSignature: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".AggregatedSignature" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "verifier_signatures"), + 2: .standard(proto: "signer_ids"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedBytesField(value: &self.verifierSignatures) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.signerIds) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.verifierSignatures.isEmpty { + try visitor.visitRepeatedBytesField(value: self.verifierSignatures, fieldNumber: 1) + } + if !self.signerIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.signerIds, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_AggregatedSignature, rhs: Flow_Entities_AggregatedSignature) -> Bool { + if lhs.verifierSignatures != rhs.verifierSignatures {return false} + if lhs.signerIds != rhs.signerIds {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/collection.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/collection.pb.swift new file mode 100644 index 00000000..d18b6650 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/collection.pb.swift @@ -0,0 +1,167 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/collection.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_Collection { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var transactionIds: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_CollectionGuarantee { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var collectionID: Data = Data() + + public var signatures: [Data] = [] + + public var referenceBlockID: Data = Data() + + public var signature: Data = Data() + + /// deprecated!! value will be empty. replaced by signer_indices + public var signerIds: [Data] = [] + + public var signerIndices: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_Collection: @unchecked Sendable {} +extension Flow_Entities_CollectionGuarantee: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_Collection: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Collection" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .standard(proto: "transaction_ids"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.transactionIds) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + if !self.transactionIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.transactionIds, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Collection, rhs: Flow_Entities_Collection) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.transactionIds != rhs.transactionIds {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_CollectionGuarantee: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".CollectionGuarantee" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "collection_id"), + 2: .same(proto: "signatures"), + 3: .standard(proto: "reference_block_id"), + 4: .same(proto: "signature"), + 5: .standard(proto: "signer_ids"), + 6: .standard(proto: "signer_indices"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.collectionID) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.signatures) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.referenceBlockID) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.signature) }() + case 5: try { try decoder.decodeRepeatedBytesField(value: &self.signerIds) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.signerIndices) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.collectionID.isEmpty { + try visitor.visitSingularBytesField(value: self.collectionID, fieldNumber: 1) + } + if !self.signatures.isEmpty { + try visitor.visitRepeatedBytesField(value: self.signatures, fieldNumber: 2) + } + if !self.referenceBlockID.isEmpty { + try visitor.visitSingularBytesField(value: self.referenceBlockID, fieldNumber: 3) + } + if !self.signature.isEmpty { + try visitor.visitSingularBytesField(value: self.signature, fieldNumber: 4) + } + if !self.signerIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.signerIds, fieldNumber: 5) + } + if !self.signerIndices.isEmpty { + try visitor.visitSingularBytesField(value: self.signerIndices, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_CollectionGuarantee, rhs: Flow_Entities_CollectionGuarantee) -> Bool { + if lhs.collectionID != rhs.collectionID {return false} + if lhs.signatures != rhs.signatures {return false} + if lhs.referenceBlockID != rhs.referenceBlockID {return false} + if lhs.signature != rhs.signature {return false} + if lhs.signerIds != rhs.signerIds {return false} + if lhs.signerIndices != rhs.signerIndices {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/event.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/event.pb.swift new file mode 100644 index 00000000..21898111 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/event.pb.swift @@ -0,0 +1,105 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/event.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_Event { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var type: String = String() + + public var transactionID: Data = Data() + + public var transactionIndex: UInt32 = 0 + + public var eventIndex: UInt32 = 0 + + public var payload: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_Event: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_Event: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Event" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "transaction_id"), + 3: .standard(proto: "transaction_index"), + 4: .standard(proto: "event_index"), + 5: .same(proto: "payload"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.transactionID) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.transactionIndex) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.eventIndex) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.payload) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.type.isEmpty { + try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) + } + if !self.transactionID.isEmpty { + try visitor.visitSingularBytesField(value: self.transactionID, fieldNumber: 2) + } + if self.transactionIndex != 0 { + try visitor.visitSingularUInt32Field(value: self.transactionIndex, fieldNumber: 3) + } + if self.eventIndex != 0 { + try visitor.visitSingularUInt32Field(value: self.eventIndex, fieldNumber: 4) + } + if !self.payload.isEmpty { + try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Event, rhs: Flow_Entities_Event) -> Bool { + if lhs.type != rhs.type {return false} + if lhs.transactionID != rhs.transactionID {return false} + if lhs.transactionIndex != rhs.transactionIndex {return false} + if lhs.eventIndex != rhs.eventIndex {return false} + if lhs.payload != rhs.payload {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/execution_result.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/execution_result.pb.swift new file mode 100644 index 00000000..cfc83114 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/execution_result.pb.swift @@ -0,0 +1,343 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/execution_result.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Entities_ExecutionResult { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var previousResultID: Data = Data() + + public var blockID: Data = Data() + + public var chunks: [Flow_Entities_Chunk] = [] + + public var serviceEvents: [Flow_Entities_ServiceEvent] = [] + + public var executionDataID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_Chunk { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var collectionIndex: UInt32 = 0 + + /// state when starting executing this chunk + public var startState: Data = Data() + + /// Events generated by executing results + public var eventCollection: Data = Data() + + /// Block id of the execution result this chunk belongs to + public var blockID: Data = Data() + + /// total amount of computation used by running all txs in this chunk + public var totalComputationUsed: UInt64 = 0 + + /// number of transactions inside the collection + public var numberOfTransactions: UInt32 = 0 + + /// chunk index inside the ER (starts from zero) + public var index: UInt64 = 0 + + /// EndState inferred from next chunk or from the ER + public var endState: Data = Data() + + public var executionDataID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_ServiceEvent { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var type: String = String() + + public var payload: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Entities_ExecutionReceiptMeta { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var executorID: Data = Data() + + public var resultID: Data = Data() + + public var spocks: [Data] = [] + + public var executorSignature: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_ExecutionResult: @unchecked Sendable {} +extension Flow_Entities_Chunk: @unchecked Sendable {} +extension Flow_Entities_ServiceEvent: @unchecked Sendable {} +extension Flow_Entities_ExecutionReceiptMeta: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_ExecutionResult: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecutionResult" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "previous_result_id"), + 2: .standard(proto: "block_id"), + 3: .same(proto: "chunks"), + 4: .standard(proto: "service_events"), + 5: .standard(proto: "execution_data_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.previousResultID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.chunks) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.serviceEvents) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.executionDataID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.previousResultID.isEmpty { + try visitor.visitSingularBytesField(value: self.previousResultID, fieldNumber: 1) + } + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 2) + } + if !self.chunks.isEmpty { + try visitor.visitRepeatedMessageField(value: self.chunks, fieldNumber: 3) + } + if !self.serviceEvents.isEmpty { + try visitor.visitRepeatedMessageField(value: self.serviceEvents, fieldNumber: 4) + } + if !self.executionDataID.isEmpty { + try visitor.visitSingularBytesField(value: self.executionDataID, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_ExecutionResult, rhs: Flow_Entities_ExecutionResult) -> Bool { + if lhs.previousResultID != rhs.previousResultID {return false} + if lhs.blockID != rhs.blockID {return false} + if lhs.chunks != rhs.chunks {return false} + if lhs.serviceEvents != rhs.serviceEvents {return false} + if lhs.executionDataID != rhs.executionDataID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_Chunk: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Chunk" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "CollectionIndex"), + 2: .standard(proto: "start_state"), + 3: .standard(proto: "event_collection"), + 4: .standard(proto: "block_id"), + 5: .standard(proto: "total_computation_used"), + 6: .standard(proto: "number_of_transactions"), + 7: .same(proto: "index"), + 8: .standard(proto: "end_state"), + 9: .standard(proto: "execution_data_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.collectionIndex) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.startState) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.eventCollection) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 5: try { try decoder.decodeSingularUInt64Field(value: &self.totalComputationUsed) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.numberOfTransactions) }() + case 7: try { try decoder.decodeSingularUInt64Field(value: &self.index) }() + case 8: try { try decoder.decodeSingularBytesField(value: &self.endState) }() + case 9: try { try decoder.decodeSingularBytesField(value: &self.executionDataID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.collectionIndex != 0 { + try visitor.visitSingularUInt32Field(value: self.collectionIndex, fieldNumber: 1) + } + if !self.startState.isEmpty { + try visitor.visitSingularBytesField(value: self.startState, fieldNumber: 2) + } + if !self.eventCollection.isEmpty { + try visitor.visitSingularBytesField(value: self.eventCollection, fieldNumber: 3) + } + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 4) + } + if self.totalComputationUsed != 0 { + try visitor.visitSingularUInt64Field(value: self.totalComputationUsed, fieldNumber: 5) + } + if self.numberOfTransactions != 0 { + try visitor.visitSingularUInt32Field(value: self.numberOfTransactions, fieldNumber: 6) + } + if self.index != 0 { + try visitor.visitSingularUInt64Field(value: self.index, fieldNumber: 7) + } + if !self.endState.isEmpty { + try visitor.visitSingularBytesField(value: self.endState, fieldNumber: 8) + } + if !self.executionDataID.isEmpty { + try visitor.visitSingularBytesField(value: self.executionDataID, fieldNumber: 9) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Chunk, rhs: Flow_Entities_Chunk) -> Bool { + if lhs.collectionIndex != rhs.collectionIndex {return false} + if lhs.startState != rhs.startState {return false} + if lhs.eventCollection != rhs.eventCollection {return false} + if lhs.blockID != rhs.blockID {return false} + if lhs.totalComputationUsed != rhs.totalComputationUsed {return false} + if lhs.numberOfTransactions != rhs.numberOfTransactions {return false} + if lhs.index != rhs.index {return false} + if lhs.endState != rhs.endState {return false} + if lhs.executionDataID != rhs.executionDataID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_ServiceEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ServiceEvent" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .same(proto: "payload"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.payload) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.type.isEmpty { + try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) + } + if !self.payload.isEmpty { + try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_ServiceEvent, rhs: Flow_Entities_ServiceEvent) -> Bool { + if lhs.type != rhs.type {return false} + if lhs.payload != rhs.payload {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_ExecutionReceiptMeta: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecutionReceiptMeta" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "executor_id"), + 2: .standard(proto: "result_id"), + 3: .same(proto: "spocks"), + 4: .standard(proto: "executor_signature"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.executorID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.resultID) }() + case 3: try { try decoder.decodeRepeatedBytesField(value: &self.spocks) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.executorSignature) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.executorID.isEmpty { + try visitor.visitSingularBytesField(value: self.executorID, fieldNumber: 1) + } + if !self.resultID.isEmpty { + try visitor.visitSingularBytesField(value: self.resultID, fieldNumber: 2) + } + if !self.spocks.isEmpty { + try visitor.visitRepeatedBytesField(value: self.spocks, fieldNumber: 3) + } + if !self.executorSignature.isEmpty { + try visitor.visitSingularBytesField(value: self.executorSignature, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_ExecutionReceiptMeta, rhs: Flow_Entities_ExecutionReceiptMeta) -> Bool { + if lhs.executorID != rhs.executorID {return false} + if lhs.resultID != rhs.resultID {return false} + if lhs.spocks != rhs.spocks {return false} + if lhs.executorSignature != rhs.executorSignature {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/transaction.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/transaction.pb.swift new file mode 100644 index 00000000..6bf521f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/entities/transaction.pb.swift @@ -0,0 +1,340 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/entities/transaction.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public enum Flow_Entities_TransactionStatus: SwiftProtobuf.Enum { + public typealias RawValue = Int + case unknown // = 0 + case pending // = 1 + case finalized // = 2 + case executed // = 3 + case sealed // = 4 + case expired // = 5 + case UNRECOGNIZED(Int) + + public init() { + self = .unknown + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .pending + case 2: self = .finalized + case 3: self = .executed + case 4: self = .sealed + case 5: self = .expired + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .unknown: return 0 + case .pending: return 1 + case .finalized: return 2 + case .executed: return 3 + case .sealed: return 4 + case .expired: return 5 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Flow_Entities_TransactionStatus: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static var allCases: [Flow_Entities_TransactionStatus] = [ + .unknown, + .pending, + .finalized, + .executed, + .sealed, + .expired, + ] +} + +#endif // swift(>=4.2) + +public struct Flow_Entities_Transaction { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var script: Data = Data() + + public var arguments: [Data] = [] + + public var referenceBlockID: Data = Data() + + public var gasLimit: UInt64 = 0 + + public var proposalKey: Flow_Entities_Transaction.ProposalKey { + get {return _proposalKey ?? Flow_Entities_Transaction.ProposalKey()} + set {_proposalKey = newValue} + } + /// Returns true if `proposalKey` has been explicitly set. + public var hasProposalKey: Bool {return self._proposalKey != nil} + /// Clears the value of `proposalKey`. Subsequent reads from it will return its default value. + public mutating func clearProposalKey() {self._proposalKey = nil} + + public var payer: Data = Data() + + public var authorizers: [Data] = [] + + public var payloadSignatures: [Flow_Entities_Transaction.Signature] = [] + + public var envelopeSignatures: [Flow_Entities_Transaction.Signature] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct ProposalKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var keyID: UInt32 = 0 + + public var sequenceNumber: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + } + + public struct Signature { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var address: Data = Data() + + public var keyID: UInt32 = 0 + + public var signature: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + } + + public init() {} + + fileprivate var _proposalKey: Flow_Entities_Transaction.ProposalKey? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Entities_TransactionStatus: @unchecked Sendable {} +extension Flow_Entities_Transaction: @unchecked Sendable {} +extension Flow_Entities_Transaction.ProposalKey: @unchecked Sendable {} +extension Flow_Entities_Transaction.Signature: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.entities" + +extension Flow_Entities_TransactionStatus: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "PENDING"), + 2: .same(proto: "FINALIZED"), + 3: .same(proto: "EXECUTED"), + 4: .same(proto: "SEALED"), + 5: .same(proto: "EXPIRED"), + ] +} + +extension Flow_Entities_Transaction: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Transaction" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "script"), + 2: .same(proto: "arguments"), + 3: .standard(proto: "reference_block_id"), + 4: .standard(proto: "gas_limit"), + 5: .standard(proto: "proposal_key"), + 6: .same(proto: "payer"), + 7: .same(proto: "authorizers"), + 8: .standard(proto: "payload_signatures"), + 9: .standard(proto: "envelope_signatures"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.script) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.arguments) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.referenceBlockID) }() + case 4: try { try decoder.decodeSingularUInt64Field(value: &self.gasLimit) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._proposalKey) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self.payer) }() + case 7: try { try decoder.decodeRepeatedBytesField(value: &self.authorizers) }() + case 8: try { try decoder.decodeRepeatedMessageField(value: &self.payloadSignatures) }() + case 9: try { try decoder.decodeRepeatedMessageField(value: &self.envelopeSignatures) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.script.isEmpty { + try visitor.visitSingularBytesField(value: self.script, fieldNumber: 1) + } + if !self.arguments.isEmpty { + try visitor.visitRepeatedBytesField(value: self.arguments, fieldNumber: 2) + } + if !self.referenceBlockID.isEmpty { + try visitor.visitSingularBytesField(value: self.referenceBlockID, fieldNumber: 3) + } + if self.gasLimit != 0 { + try visitor.visitSingularUInt64Field(value: self.gasLimit, fieldNumber: 4) + } + try { if let v = self._proposalKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + if !self.payer.isEmpty { + try visitor.visitSingularBytesField(value: self.payer, fieldNumber: 6) + } + if !self.authorizers.isEmpty { + try visitor.visitRepeatedBytesField(value: self.authorizers, fieldNumber: 7) + } + if !self.payloadSignatures.isEmpty { + try visitor.visitRepeatedMessageField(value: self.payloadSignatures, fieldNumber: 8) + } + if !self.envelopeSignatures.isEmpty { + try visitor.visitRepeatedMessageField(value: self.envelopeSignatures, fieldNumber: 9) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Transaction, rhs: Flow_Entities_Transaction) -> Bool { + if lhs.script != rhs.script {return false} + if lhs.arguments != rhs.arguments {return false} + if lhs.referenceBlockID != rhs.referenceBlockID {return false} + if lhs.gasLimit != rhs.gasLimit {return false} + if lhs._proposalKey != rhs._proposalKey {return false} + if lhs.payer != rhs.payer {return false} + if lhs.authorizers != rhs.authorizers {return false} + if lhs.payloadSignatures != rhs.payloadSignatures {return false} + if lhs.envelopeSignatures != rhs.envelopeSignatures {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_Transaction.ProposalKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Flow_Entities_Transaction.protoMessageName + ".ProposalKey" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + 2: .standard(proto: "key_id"), + 3: .standard(proto: "sequence_number"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.keyID) }() + case 3: try { try decoder.decodeSingularUInt64Field(value: &self.sequenceNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + if self.keyID != 0 { + try visitor.visitSingularUInt32Field(value: self.keyID, fieldNumber: 2) + } + if self.sequenceNumber != 0 { + try visitor.visitSingularUInt64Field(value: self.sequenceNumber, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Transaction.ProposalKey, rhs: Flow_Entities_Transaction.ProposalKey) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.keyID != rhs.keyID {return false} + if lhs.sequenceNumber != rhs.sequenceNumber {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Entities_Transaction.Signature: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Flow_Entities_Transaction.protoMessageName + ".Signature" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "address"), + 2: .standard(proto: "key_id"), + 3: .same(proto: "signature"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.keyID) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.signature) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) + } + if self.keyID != 0 { + try visitor.visitSingularUInt32Field(value: self.keyID, fieldNumber: 2) + } + if !self.signature.isEmpty { + try visitor.visitSingularBytesField(value: self.signature, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Entities_Transaction.Signature, rhs: Flow_Entities_Transaction.Signature) -> Bool { + if lhs.address != rhs.address {return false} + if lhs.keyID != rhs.keyID {return false} + if lhs.signature != rhs.signature {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.grpc.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.grpc.swift new file mode 100644 index 00000000..06f38c85 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.grpc.swift @@ -0,0 +1,780 @@ +// +// DO NOT EDIT. +// +// Generated by the protocol buffer compiler. +// Source: flow/execution/execution.proto +// + +// +// Copyright 2018, gRPC Authors 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +import GRPC +import NIO +import NIOConcurrencyHelpers +import SwiftProtobuf + + +/// ExecutionAPI is the API provided by the execution nodes. +/// +/// Usage: instantiate `Flow_Execution_ExecutionAPIClient`, then call methods of this protocol to make API calls. +public protocol Flow_Execution_ExecutionAPIClientProtocol: GRPCClient { + var serviceName: String { get } + var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? { get } + + func ping( + _ request: Flow_Execution_PingRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getAccountAtBlockID( + _ request: Flow_Execution_GetAccountAtBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func executeScriptAtBlockID( + _ request: Flow_Execution_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getEventsForBlockIDs( + _ request: Flow_Execution_GetEventsForBlockIDsRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResult( + _ request: Flow_Execution_GetTransactionResultRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResultByIndex( + _ request: Flow_Execution_GetTransactionByIndexRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getTransactionResultsByBlockID( + _ request: Flow_Execution_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getRegisterAtBlockID( + _ request: Flow_Execution_GetRegisterAtBlockIDRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getLatestBlockHeader( + _ request: Flow_Execution_GetLatestBlockHeaderRequest, + callOptions: CallOptions? + ) -> UnaryCall + + func getBlockHeaderByID( + _ request: Flow_Execution_GetBlockHeaderByIDRequest, + callOptions: CallOptions? + ) -> UnaryCall +} + +extension Flow_Execution_ExecutionAPIClientProtocol { + public var serviceName: String { + return "flow.execution.ExecutionAPI" + } + + /// Ping is used to check if the access node is alive and healthy. + /// + /// - Parameters: + /// - request: Request to send to Ping. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func ping( + _ request: Flow_Execution_PingRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + /// GetAccountAtBlockID gets an account by address at the given block ID + /// + /// - Parameters: + /// - request: Request to send to GetAccountAtBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getAccountAtBlockID( + _ request: Flow_Execution_GetAccountAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getAccountAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockIDInterceptors() ?? [] + ) + } + + /// ExecuteScriptAtBlockID executes a ready-only Cadence script against the + /// execution state at the block with the given ID. + /// + /// - Parameters: + /// - request: Request to send to ExecuteScriptAtBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func executeScriptAtBlockID( + _ request: Flow_Execution_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + /// GetEventsForBlockIDs retrieves events for all the specified block IDs that + /// have the given type + /// + /// - Parameters: + /// - request: Request to send to GetEventsForBlockIDs. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getEventsForBlockIDs( + _ request: Flow_Execution_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + /// GetTransactionResult gets the result of a transaction. + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResult. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResult( + _ request: Flow_Execution_GetTransactionResultRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + /// GetTransactionResultByIndex gets the result of a transaction at the index . + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResultByIndex. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResultByIndex( + _ request: Flow_Execution_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + /// GetTransactionResultByIndex gets the results of all transactions in the + /// block ordered by transaction index + /// + /// - Parameters: + /// - request: Request to send to GetTransactionResultsByBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getTransactionResultsByBlockID( + _ request: Flow_Execution_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + /// GetRegisterAtBlockID collects a register at the block with the given ID (if + /// available). + /// + /// - Parameters: + /// - request: Request to send to GetRegisterAtBlockID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getRegisterAtBlockID( + _ request: Flow_Execution_GetRegisterAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getRegisterAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetRegisterAtBlockIDInterceptors() ?? [] + ) + } + + /// GetLatestBlockHeader gets the latest sealed or unsealed block header. + /// + /// - Parameters: + /// - request: Request to send to GetLatestBlockHeader. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getLatestBlockHeader( + _ request: Flow_Execution_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + /// GetBlockHeaderByID gets a block header by ID. + /// + /// - Parameters: + /// - request: Request to send to GetBlockHeaderByID. + /// - callOptions: Call options. + /// - Returns: A `UnaryCall` with futures for the metadata, status and response. + public func getBlockHeaderByID( + _ request: Flow_Execution_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) -> UnaryCall { + return self.makeUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } +} + +#if compiler(>=5.6) +@available(*, deprecated) +extension Flow_Execution_ExecutionAPIClient: @unchecked Sendable {} +#endif // compiler(>=5.6) + +@available(*, deprecated, renamed: "Flow_Execution_ExecutionAPINIOClient") +public final class Flow_Execution_ExecutionAPIClient: Flow_Execution_ExecutionAPIClientProtocol { + private let lock = Lock() + private var _defaultCallOptions: CallOptions + private var _interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? + public let channel: GRPCChannel + public var defaultCallOptions: CallOptions { + get { self.lock.withLock { return self._defaultCallOptions } } + set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } + } + public var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? { + get { self.lock.withLock { return self._interceptors } } + set { self.lock.withLockVoid { self._interceptors = newValue } } + } + + /// Creates a client for the flow.execution.ExecutionAPI service. + /// + /// - Parameters: + /// - channel: `GRPCChannel` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self._defaultCallOptions = defaultCallOptions + self._interceptors = interceptors + } +} + +public struct Flow_Execution_ExecutionAPINIOClient: Flow_Execution_ExecutionAPIClientProtocol { + public var channel: GRPCChannel + public var defaultCallOptions: CallOptions + public var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? + + /// Creates a client for the flow.execution.ExecutionAPI service. + /// + /// - Parameters: + /// - channel: `GRPCChannel` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + /// - interceptors: A factory providing interceptors for each RPC. + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors + } +} + +#if compiler(>=5.6) +/// ExecutionAPI is the API provided by the execution nodes. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public protocol Flow_Execution_ExecutionAPIAsyncClientProtocol: GRPCClient { + static var serviceDescriptor: GRPCServiceDescriptor { get } + var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? { get } + + func makePingCall( + _ request: Flow_Execution_PingRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetAccountAtBlockIDCall( + _ request: Flow_Execution_GetAccountAtBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeExecuteScriptAtBlockIDCall( + _ request: Flow_Execution_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetEventsForBlockIdsCall( + _ request: Flow_Execution_GetEventsForBlockIDsRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultCall( + _ request: Flow_Execution_GetTransactionResultRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultByIndexCall( + _ request: Flow_Execution_GetTransactionByIndexRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetTransactionResultsByBlockIDCall( + _ request: Flow_Execution_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetRegisterAtBlockIDCall( + _ request: Flow_Execution_GetRegisterAtBlockIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetLatestBlockHeaderCall( + _ request: Flow_Execution_GetLatestBlockHeaderRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall + + func makeGetBlockHeaderByIDCall( + _ request: Flow_Execution_GetBlockHeaderByIDRequest, + callOptions: CallOptions? + ) -> GRPCAsyncUnaryCall +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Flow_Execution_ExecutionAPIAsyncClientProtocol { + public static var serviceDescriptor: GRPCServiceDescriptor { + return Flow_Execution_ExecutionAPIClientMetadata.serviceDescriptor + } + + public var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? { + return nil + } + + public func makePingCall( + _ request: Flow_Execution_PingRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + public func makeGetAccountAtBlockIDCall( + _ request: Flow_Execution_GetAccountAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getAccountAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockIDInterceptors() ?? [] + ) + } + + public func makeExecuteScriptAtBlockIDCall( + _ request: Flow_Execution_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + public func makeGetEventsForBlockIdsCall( + _ request: Flow_Execution_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultCall( + _ request: Flow_Execution_GetTransactionResultRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultByIndexCall( + _ request: Flow_Execution_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + public func makeGetTransactionResultsByBlockIDCall( + _ request: Flow_Execution_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + public func makeGetRegisterAtBlockIDCall( + _ request: Flow_Execution_GetRegisterAtBlockIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getRegisterAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetRegisterAtBlockIDInterceptors() ?? [] + ) + } + + public func makeGetLatestBlockHeaderCall( + _ request: Flow_Execution_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + public func makeGetBlockHeaderByIDCall( + _ request: Flow_Execution_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) -> GRPCAsyncUnaryCall { + return self.makeAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Flow_Execution_ExecutionAPIAsyncClientProtocol { + public func ping( + _ request: Flow_Execution_PingRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_PingResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.ping.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makePingInterceptors() ?? [] + ) + } + + public func getAccountAtBlockID( + _ request: Flow_Execution_GetAccountAtBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetAccountAtBlockIDResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getAccountAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetAccountAtBlockIDInterceptors() ?? [] + ) + } + + public func executeScriptAtBlockID( + _ request: Flow_Execution_ExecuteScriptAtBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_ExecuteScriptAtBlockIDResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.executeScriptAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeExecuteScriptAtBlockIDInterceptors() ?? [] + ) + } + + public func getEventsForBlockIDs( + _ request: Flow_Execution_GetEventsForBlockIDsRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetEventsForBlockIDsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getEventsForBlockIDs.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetEventsForBlockIDsInterceptors() ?? [] + ) + } + + public func getTransactionResult( + _ request: Flow_Execution_GetTransactionResultRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetTransactionResultResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResult.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultInterceptors() ?? [] + ) + } + + public func getTransactionResultByIndex( + _ request: Flow_Execution_GetTransactionByIndexRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetTransactionResultResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultByIndex.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultByIndexInterceptors() ?? [] + ) + } + + public func getTransactionResultsByBlockID( + _ request: Flow_Execution_GetTransactionsByBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetTransactionResultsResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultsByBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetTransactionResultsByBlockIDInterceptors() ?? [] + ) + } + + public func getRegisterAtBlockID( + _ request: Flow_Execution_GetRegisterAtBlockIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_GetRegisterAtBlockIDResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getRegisterAtBlockID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetRegisterAtBlockIDInterceptors() ?? [] + ) + } + + public func getLatestBlockHeader( + _ request: Flow_Execution_GetLatestBlockHeaderRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_BlockHeaderResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getLatestBlockHeader.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetLatestBlockHeaderInterceptors() ?? [] + ) + } + + public func getBlockHeaderByID( + _ request: Flow_Execution_GetBlockHeaderByIDRequest, + callOptions: CallOptions? = nil + ) async throws -> Flow_Execution_BlockHeaderResponse { + return try await self.performAsyncUnaryCall( + path: Flow_Execution_ExecutionAPIClientMetadata.Methods.getBlockHeaderByID.path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: self.interceptors?.makeGetBlockHeaderByIDInterceptors() ?? [] + ) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct Flow_Execution_ExecutionAPIAsyncClient: Flow_Execution_ExecutionAPIAsyncClientProtocol { + public var channel: GRPCChannel + public var defaultCallOptions: CallOptions + public var interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? + + public init( + channel: GRPCChannel, + defaultCallOptions: CallOptions = CallOptions(), + interceptors: Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol? = nil + ) { + self.channel = channel + self.defaultCallOptions = defaultCallOptions + self.interceptors = interceptors + } +} + +#endif // compiler(>=5.6) + +public protocol Flow_Execution_ExecutionAPIClientInterceptorFactoryProtocol: GRPCSendable { + + /// - Returns: Interceptors to use when invoking 'ping'. + func makePingInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getAccountAtBlockID'. + func makeGetAccountAtBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'executeScriptAtBlockID'. + func makeExecuteScriptAtBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getEventsForBlockIDs'. + func makeGetEventsForBlockIDsInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResult'. + func makeGetTransactionResultInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResultByIndex'. + func makeGetTransactionResultByIndexInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getTransactionResultsByBlockID'. + func makeGetTransactionResultsByBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getRegisterAtBlockID'. + func makeGetRegisterAtBlockIDInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getLatestBlockHeader'. + func makeGetLatestBlockHeaderInterceptors() -> [ClientInterceptor] + + /// - Returns: Interceptors to use when invoking 'getBlockHeaderByID'. + func makeGetBlockHeaderByIDInterceptors() -> [ClientInterceptor] +} + +public enum Flow_Execution_ExecutionAPIClientMetadata { + public static let serviceDescriptor = GRPCServiceDescriptor( + name: "ExecutionAPI", + fullName: "flow.execution.ExecutionAPI", + methods: [ + Flow_Execution_ExecutionAPIClientMetadata.Methods.ping, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getAccountAtBlockID, + Flow_Execution_ExecutionAPIClientMetadata.Methods.executeScriptAtBlockID, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getEventsForBlockIDs, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResult, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultByIndex, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getTransactionResultsByBlockID, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getRegisterAtBlockID, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getLatestBlockHeader, + Flow_Execution_ExecutionAPIClientMetadata.Methods.getBlockHeaderByID, + ] + ) + + public enum Methods { + public static let ping = GRPCMethodDescriptor( + name: "Ping", + path: "/flow.execution.ExecutionAPI/Ping", + type: GRPCCallType.unary + ) + + public static let getAccountAtBlockID = GRPCMethodDescriptor( + name: "GetAccountAtBlockID", + path: "/flow.execution.ExecutionAPI/GetAccountAtBlockID", + type: GRPCCallType.unary + ) + + public static let executeScriptAtBlockID = GRPCMethodDescriptor( + name: "ExecuteScriptAtBlockID", + path: "/flow.execution.ExecutionAPI/ExecuteScriptAtBlockID", + type: GRPCCallType.unary + ) + + public static let getEventsForBlockIDs = GRPCMethodDescriptor( + name: "GetEventsForBlockIDs", + path: "/flow.execution.ExecutionAPI/GetEventsForBlockIDs", + type: GRPCCallType.unary + ) + + public static let getTransactionResult = GRPCMethodDescriptor( + name: "GetTransactionResult", + path: "/flow.execution.ExecutionAPI/GetTransactionResult", + type: GRPCCallType.unary + ) + + public static let getTransactionResultByIndex = GRPCMethodDescriptor( + name: "GetTransactionResultByIndex", + path: "/flow.execution.ExecutionAPI/GetTransactionResultByIndex", + type: GRPCCallType.unary + ) + + public static let getTransactionResultsByBlockID = GRPCMethodDescriptor( + name: "GetTransactionResultsByBlockID", + path: "/flow.execution.ExecutionAPI/GetTransactionResultsByBlockID", + type: GRPCCallType.unary + ) + + public static let getRegisterAtBlockID = GRPCMethodDescriptor( + name: "GetRegisterAtBlockID", + path: "/flow.execution.ExecutionAPI/GetRegisterAtBlockID", + type: GRPCCallType.unary + ) + + public static let getLatestBlockHeader = GRPCMethodDescriptor( + name: "GetLatestBlockHeader", + path: "/flow.execution.ExecutionAPI/GetLatestBlockHeader", + type: GRPCCallType.unary + ) + + public static let getBlockHeaderByID = GRPCMethodDescriptor( + name: "GetBlockHeaderByID", + path: "/flow.execution.ExecutionAPI/GetBlockHeaderByID", + type: GRPCCallType.unary + ) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.pb.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.pb.swift new file mode 100644 index 00000000..0f381d94 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.pb.swift @@ -0,0 +1,983 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: flow/execution/execution.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +public struct Flow_Execution_PingRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_PingResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetAccountAtBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var address: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetAccountAtBlockIDResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var account: Flow_Entities_Account { + get {return _account ?? Flow_Entities_Account()} + set {_account = newValue} + } + /// Returns true if `account` has been explicitly set. + public var hasAccount: Bool {return self._account != nil} + /// Clears the value of `account`. Subsequent reads from it will return its default value. + public mutating func clearAccount() {self._account = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _account: Flow_Entities_Account? = nil +} + +public struct Flow_Execution_ExecuteScriptAtBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var script: Data = Data() + + public var arguments: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_ExecuteScriptAtBlockIDResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var value: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetEventsForBlockIDsResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var results: [Flow_Execution_GetEventsForBlockIDsResponse.Result] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct Result { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var blockHeight: UInt64 = 0 + + public var events: [Flow_Entities_Event] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + } + + public init() {} +} + +public struct Flow_Execution_GetEventsForBlockIDsRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var type: String = String() + + public var blockIds: [Data] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetTransactionResultRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var transactionID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetTransactionByIndexRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var index: UInt32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetTransactionResultResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var statusCode: UInt32 = 0 + + public var errorMessage: String = String() + + public var events: [Flow_Entities_Event] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetTransactionsByBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetTransactionResultsResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var transactionResults: [Flow_Execution_GetTransactionResultResponse] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetRegisterAtBlockIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var blockID: Data = Data() + + public var registerOwner: Data = Data() + + public var registerController: Data = Data() + + public var registerKey: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetRegisterAtBlockIDResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var value: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetLatestBlockHeaderRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var isSealed: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_GetBlockHeaderByIDRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var id: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +public struct Flow_Execution_BlockHeaderResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var block: Flow_Entities_BlockHeader { + get {return _block ?? Flow_Entities_BlockHeader()} + set {_block = newValue} + } + /// Returns true if `block` has been explicitly set. + public var hasBlock: Bool {return self._block != nil} + /// Clears the value of `block`. Subsequent reads from it will return its default value. + public mutating func clearBlock() {self._block = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _block: Flow_Entities_BlockHeader? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Flow_Execution_PingRequest: @unchecked Sendable {} +extension Flow_Execution_PingResponse: @unchecked Sendable {} +extension Flow_Execution_GetAccountAtBlockIDRequest: @unchecked Sendable {} +extension Flow_Execution_GetAccountAtBlockIDResponse: @unchecked Sendable {} +extension Flow_Execution_ExecuteScriptAtBlockIDRequest: @unchecked Sendable {} +extension Flow_Execution_ExecuteScriptAtBlockIDResponse: @unchecked Sendable {} +extension Flow_Execution_GetEventsForBlockIDsResponse: @unchecked Sendable {} +extension Flow_Execution_GetEventsForBlockIDsResponse.Result: @unchecked Sendable {} +extension Flow_Execution_GetEventsForBlockIDsRequest: @unchecked Sendable {} +extension Flow_Execution_GetTransactionResultRequest: @unchecked Sendable {} +extension Flow_Execution_GetTransactionByIndexRequest: @unchecked Sendable {} +extension Flow_Execution_GetTransactionResultResponse: @unchecked Sendable {} +extension Flow_Execution_GetTransactionsByBlockIDRequest: @unchecked Sendable {} +extension Flow_Execution_GetTransactionResultsResponse: @unchecked Sendable {} +extension Flow_Execution_GetRegisterAtBlockIDRequest: @unchecked Sendable {} +extension Flow_Execution_GetRegisterAtBlockIDResponse: @unchecked Sendable {} +extension Flow_Execution_GetLatestBlockHeaderRequest: @unchecked Sendable {} +extension Flow_Execution_GetBlockHeaderByIDRequest: @unchecked Sendable {} +extension Flow_Execution_BlockHeaderResponse: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "flow.execution" + +extension Flow_Execution_PingRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".PingRequest" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_PingRequest, rhs: Flow_Execution_PingRequest) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_PingResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".PingResponse" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_PingResponse, rhs: Flow_Execution_PingResponse) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetAccountAtBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountAtBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .same(proto: "address"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.address) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.address.isEmpty { + try visitor.visitSingularBytesField(value: self.address, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetAccountAtBlockIDRequest, rhs: Flow_Execution_GetAccountAtBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.address != rhs.address {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetAccountAtBlockIDResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetAccountAtBlockIDResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "account"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._account) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._account { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetAccountAtBlockIDResponse, rhs: Flow_Execution_GetAccountAtBlockIDResponse) -> Bool { + if lhs._account != rhs._account {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_ExecuteScriptAtBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptAtBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .same(proto: "script"), + 3: .same(proto: "arguments"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.script) }() + case 3: try { try decoder.decodeRepeatedBytesField(value: &self.arguments) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.script.isEmpty { + try visitor.visitSingularBytesField(value: self.script, fieldNumber: 2) + } + if !self.arguments.isEmpty { + try visitor.visitRepeatedBytesField(value: self.arguments, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_ExecuteScriptAtBlockIDRequest, rhs: Flow_Execution_ExecuteScriptAtBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.script != rhs.script {return false} + if lhs.arguments != rhs.arguments {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_ExecuteScriptAtBlockIDResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExecuteScriptAtBlockIDResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.value.isEmpty { + try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_ExecuteScriptAtBlockIDResponse, rhs: Flow_Execution_ExecuteScriptAtBlockIDResponse) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetEventsForBlockIDsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetEventsForBlockIDsResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "results"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.results) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.results.isEmpty { + try visitor.visitRepeatedMessageField(value: self.results, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetEventsForBlockIDsResponse, rhs: Flow_Execution_GetEventsForBlockIDsResponse) -> Bool { + if lhs.results != rhs.results {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetEventsForBlockIDsResponse.Result: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Flow_Execution_GetEventsForBlockIDsResponse.protoMessageName + ".Result" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .standard(proto: "block_height"), + 3: .same(proto: "events"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularUInt64Field(value: &self.blockHeight) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.events) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if self.blockHeight != 0 { + try visitor.visitSingularUInt64Field(value: self.blockHeight, fieldNumber: 2) + } + if !self.events.isEmpty { + try visitor.visitRepeatedMessageField(value: self.events, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetEventsForBlockIDsResponse.Result, rhs: Flow_Execution_GetEventsForBlockIDsResponse.Result) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.blockHeight != rhs.blockHeight {return false} + if lhs.events != rhs.events {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetEventsForBlockIDsRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetEventsForBlockIDsRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "block_ids"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() + case 2: try { try decoder.decodeRepeatedBytesField(value: &self.blockIds) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.type.isEmpty { + try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) + } + if !self.blockIds.isEmpty { + try visitor.visitRepeatedBytesField(value: self.blockIds, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetEventsForBlockIDsRequest, rhs: Flow_Execution_GetEventsForBlockIDsRequest) -> Bool { + if lhs.type != rhs.type {return false} + if lhs.blockIds != rhs.blockIds {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetTransactionResultRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionResultRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .standard(proto: "transaction_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.transactionID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.transactionID.isEmpty { + try visitor.visitSingularBytesField(value: self.transactionID, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetTransactionResultRequest, rhs: Flow_Execution_GetTransactionResultRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.transactionID != rhs.transactionID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetTransactionByIndexRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionByIndexRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .same(proto: "index"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.index) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if self.index != 0 { + try visitor.visitSingularUInt32Field(value: self.index, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetTransactionByIndexRequest, rhs: Flow_Execution_GetTransactionByIndexRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.index != rhs.index {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetTransactionResultResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionResultResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "status_code"), + 2: .standard(proto: "error_message"), + 3: .same(proto: "events"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.statusCode) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.events) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.statusCode != 0 { + try visitor.visitSingularUInt32Field(value: self.statusCode, fieldNumber: 1) + } + if !self.errorMessage.isEmpty { + try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) + } + if !self.events.isEmpty { + try visitor.visitRepeatedMessageField(value: self.events, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetTransactionResultResponse, rhs: Flow_Execution_GetTransactionResultResponse) -> Bool { + if lhs.statusCode != rhs.statusCode {return false} + if lhs.errorMessage != rhs.errorMessage {return false} + if lhs.events != rhs.events {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetTransactionsByBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionsByBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetTransactionsByBlockIDRequest, rhs: Flow_Execution_GetTransactionsByBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetTransactionResultsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetTransactionResultsResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "transaction_results"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.transactionResults) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.transactionResults.isEmpty { + try visitor.visitRepeatedMessageField(value: self.transactionResults, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetTransactionResultsResponse, rhs: Flow_Execution_GetTransactionResultsResponse) -> Bool { + if lhs.transactionResults != rhs.transactionResults {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetRegisterAtBlockIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetRegisterAtBlockIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "block_id"), + 2: .standard(proto: "register_owner"), + 3: .standard(proto: "register_controller"), + 4: .standard(proto: "register_key"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.registerOwner) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.registerController) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.registerKey) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.blockID.isEmpty { + try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) + } + if !self.registerOwner.isEmpty { + try visitor.visitSingularBytesField(value: self.registerOwner, fieldNumber: 2) + } + if !self.registerController.isEmpty { + try visitor.visitSingularBytesField(value: self.registerController, fieldNumber: 3) + } + if !self.registerKey.isEmpty { + try visitor.visitSingularBytesField(value: self.registerKey, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetRegisterAtBlockIDRequest, rhs: Flow_Execution_GetRegisterAtBlockIDRequest) -> Bool { + if lhs.blockID != rhs.blockID {return false} + if lhs.registerOwner != rhs.registerOwner {return false} + if lhs.registerController != rhs.registerController {return false} + if lhs.registerKey != rhs.registerKey {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetRegisterAtBlockIDResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetRegisterAtBlockIDResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.value.isEmpty { + try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetRegisterAtBlockIDResponse, rhs: Flow_Execution_GetRegisterAtBlockIDResponse) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetLatestBlockHeaderRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetLatestBlockHeaderRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "is_sealed"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.isSealed) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.isSealed != false { + try visitor.visitSingularBoolField(value: self.isSealed, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetLatestBlockHeaderRequest, rhs: Flow_Execution_GetLatestBlockHeaderRequest) -> Bool { + if lhs.isSealed != rhs.isSealed {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_GetBlockHeaderByIDRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GetBlockHeaderByIDRequest" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.id.isEmpty { + try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_GetBlockHeaderByIDRequest, rhs: Flow_Execution_GetBlockHeaderByIDRequest) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Flow_Execution_BlockHeaderResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BlockHeaderResponse" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "block"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._block) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._block { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Flow_Execution_BlockHeaderResponse, rhs: Flow_Execution_BlockHeaderResponse) -> Bool { + if lhs._block != rhs._block {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodable.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodable.swift new file mode 100644 index 00000000..89e50fea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodable.swift @@ -0,0 +1,114 @@ +// +// RLPDecodable.swift +// +// Created by Scott on 2022/8/5. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt + +public protocol RLPDecodable { + init(rlpItem: RLPItem) throws +} + +// MARK: - Data + +extension Data: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + switch rlpItem { + case .empty: + self = Data() + case let .data(data): + self = data + case .list: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + } + +} + +// MARK: - Unsigned Integer + +extension UInt: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + self = UInt(try BigUInt(rlpItem: rlpItem)) + } +} + +extension UInt8: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + self = UInt8(try BigUInt(rlpItem: rlpItem)) + } +} + +extension UInt16: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + self = UInt16(try BigUInt(rlpItem: rlpItem)) + } +} + +extension UInt32: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + self = UInt32(try BigUInt(rlpItem: rlpItem)) + } +} + +extension UInt64: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + self = UInt64(try BigUInt(rlpItem: rlpItem)) + } +} + +extension BigUInt: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + switch rlpItem { + case .empty, .list: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + case let .data(data): + self = BigUInt(data) + } + } +} + +// MARK: - String + +extension String: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + switch rlpItem { + case .empty, .list: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + case let .data(data): + self = String(data: data, encoding: .utf8) ?? "" + } + } +} + +// MARK: - Bool + +extension Bool: RLPDecodable { + + public init(rlpItem: RLPItem) throws { + switch rlpItem { + case .empty, .list: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + case let .data(data): + switch data.count { + case 0: + self = false + case 1: + self = (data[0] == 1) + default: + throw RLPDecodingError.invalidType(rlpItem, type: Self.self) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecoder.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecoder.swift new file mode 100644 index 00000000..f5b441b9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecoder.swift @@ -0,0 +1,125 @@ +// +// RLPDecoder.swift +// +// Created by Scott on 2022/8/6. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt + +final public class RLPDecoder { + + public init() { } + + public func decodeRLPData(_ data: Data) throws -> RLPItem { + try decodeRLPData(data, isList: false) + } + + private func decodeRLPData(_ data: Data, isList: Bool) throws -> RLPItem { + if data.count == 0 { + if isList { + return .list([]) + } else { + return .empty + } + } + + var finalItems = [RLPItem]() + var currentData = Data(data) + while currentData.count != 0 { + let (offset, dataLength, type) = try decodeLength(currentData) + switch type { + case .empty: + break + case .data: + let slice = try slice( + data: currentData, + offset: offset, + length: dataLength) + let data = Data(slice) + finalItems.append(.data(data)) + case .list: + let slice = try slice( + data: currentData, + offset: offset, + length: dataLength) + let list = try decodeRLPData(Data(slice), isList: true) + finalItems.append(list) + } + currentData = sliceRest( + data: currentData, + start: offset + dataLength) + } + if isList { + return RLPItem.list(finalItems) + } else { + guard finalItems.count == 1 else { + throw RLPDecodingError.invalidFormat + } + return finalItems[0] + } + } + + private func decodeLength(_ input: Data) throws -> (offset: BigUInt, length: BigUInt, type: RLPItemType) { + let length = BigUInt(input.count) + if (length == BigUInt(0)) { + return (0, 0, .empty) + } + let prefixByte = input[0] + if prefixByte <= 0x7f { + return (0, 1, .data) + } else if prefixByte <= 0xb7 && length > BigUInt(prefixByte - 0x80) { + let dataLength = BigUInt(prefixByte - 0x80) + return (1, dataLength, .data) + } else if try prefixByte <= 0xbf && length > BigUInt(prefixByte - 0xb7) && length > BigUInt(prefixByte - 0xb7) + toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xb7))) { + let lengthOfLength = BigUInt(prefixByte - 0xb7) + let dataLength = try toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xb7))) + return (1 + lengthOfLength, dataLength, .data) + } else if prefixByte <= 0xf7 && length > BigUInt(prefixByte - 0xc0) { + let listLen = BigUInt(prefixByte - 0xc0) + return (1, listLen, .list) + } else if try prefixByte <= 0xff && length > BigUInt(prefixByte - 0xf7) && length > BigUInt(prefixByte - 0xf7) + toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xf7))) { + let lengthOfListLength = BigUInt(prefixByte - 0xf7) + let listLength = try toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xf7))) + return (1 + lengthOfListLength, listLength, .list) + } else { + throw RLPDecodingError.invalidFormat + } + } + + private func slice(data: Data, offset: BigUInt, length: BigUInt) throws -> Data { + if BigUInt(data.count) < offset + length { + throw RLPDecodingError.invalidFormat + } + let slice = data[UInt64(offset) ..< UInt64(offset + length)] + return Data(slice) + } + + private func sliceRest(data: Data, start: BigUInt) -> Data { + if BigUInt(data.count) < start { + return Data() + } else { + let slice = data[UInt64(start) ..< UInt64(data.count)] + return Data(slice) + } + } + + private func toBigUInt(_ data: Data) throws -> BigUInt { + if data.count == 0 { + throw RLPDecodingError.invalidFormat + } else if data.count == 1 { + return BigUInt.init(data) + } else { + let slice = data[0 ..< data.count - 1] + return try BigUInt(data[data.count-1]) + toBigUInt(slice)*256 + } + } + +} + +private enum RLPItemType { + case empty + case data + case list +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodingError.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodingError.swift new file mode 100644 index 00000000..14ac94f9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPDecodingError.swift @@ -0,0 +1,14 @@ +// +// RLPDecodingError.swift +// +// Created by Scott on 2022/8/6. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum RLPDecodingError: Swift.Error { + case invalidFormat + case invalidType(RLPItem, type: Any.Type) + case notListType +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodable.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodable.swift new file mode 100644 index 00000000..7819a2a6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodable.swift @@ -0,0 +1,134 @@ +// +// RLPEncodable.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation +import BigInt + +public protocol RLPEncodable { + var rlpData: Data { get } +} + +extension RLPEncodable { + + fileprivate func encodeLength(_ length: UInt64, offset: UInt8) -> Data { + if length < 56 { + return Data([UInt8(length) + offset]) + } else { + let binaryData = length.bigEndianBinaryData + return Data([UInt8(binaryData.count) + offset + 55]) + binaryData + } + } +} + +// MARK: - RLPEncoableArray + +public typealias RLPEncoableArray = [RLPEncodable] + +extension RLPEncoableArray: RLPEncodable { + + public var rlpData: Data { + get { + var output = Data() + for value in self { + output += value.rlpData + } + return encodeLength(UInt64(output.count), offset: 0xc0) + output + } + } +} + +// MARK: - Data + +extension Data: RLPEncodable { + + public var rlpData: Data { + if count == 1 && self[0] <= 0x7f { + return self + } else { + var output = encodeLength(UInt64(count), offset: 0x80) + output.append(self) + return output + } + } +} + +// MARK: - Unsigned Integer + +extension UInt: RLPEncodable { + + public var rlpData: Data { + BigUInt(self).rlpData + } +} + +extension UInt8: RLPEncodable { + + public var rlpData: Data { + BigUInt(self).rlpData + } +} + +extension UInt16: RLPEncodable { + + public var rlpData: Data { + BigUInt(self).rlpData + } +} + +extension UInt32: RLPEncodable { + + public var rlpData: Data { + BigUInt(self).rlpData + } +} + +extension UInt64: RLPEncodable { + + public var rlpData: Data { + BigUInt(self).rlpData + } +} + +extension BigUInt: RLPEncodable { + + public var rlpData: Data { + serialize().rlpData + } +} + +// MARK: - String + +extension String: RLPEncodable { + + public var rlpData: Data { + (data(using: .utf8) ?? Data()).rlpData + } +} + +// MARK: - Bool + +extension Bool: RLPEncodable { + + public var rlpData: Data { + ((self ? 1 : 0) as UInt).rlpData + } +} + +// MARK: - Private + +private extension UInt64 { + + var bigEndianBinaryData: Data { + var value = self + let bytes: [UInt8] = withUnsafeBytes(of: &value) { Array($0) }.reversed() + if let index = bytes.firstIndex(where: { $0 != 0x0 }) { + return Data(bytes[index...]) + } else { + return Data([0]) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodableList.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodableList.swift new file mode 100644 index 00000000..539c5481 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPEncodableList.swift @@ -0,0 +1,12 @@ +// +// File.swift +// +// Created by Scott on 2022/5/22. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public protocol RLPEncodableList { + var rlpList: RLPEncoableArray { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPItem.swift b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPItem.swift new file mode 100644 index 00000000..325e4002 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/FlowSDK/Sources/FlowSDK/RLP/RLPItem.swift @@ -0,0 +1,23 @@ +// +// RLPItem.swift +// +// Created by Scott on 2022/8/6. +// Copyright © 2022 portto. All rights reserved. +// + +import Foundation + +public enum RLPItem: Equatable { + case empty + case data(Data) + indirect case list([RLPItem]) + + public func getListItems() throws -> [RLPItem] { + switch self { + case .empty, .data: + throw RLPDecodingError.notListType + case let .list(items): + return items + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Logging/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/Logging/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Logging/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/Logging/README.md b/one-and-half-nibble/MobileApp/Pods/Logging/README.md new file mode 100644 index 00000000..e6db511e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Logging/README.md @@ -0,0 +1,276 @@ +# SwiftLog + +A Logging API package for Swift. Version `1.0.0` requires Swift 5.0 but there is a version `0.x.y` series available for Swift 4 to ease your transition towards Swift 5. If you intend to use or support SwiftLog for Swift 4, please check the [paragraph](#help-i-need-swift-4) at the end of the document. + +First things first: This is the beginning of a community-driven open-source project actively seeking contributions, be it code, documentation, or ideas. Apart from contributing to `SwiftLog` itself, there's another huge gap at the moment: `SwiftLog` is an _API package_ which tries to establish a common API the ecosystem can use. To make logging really work for real-world workloads, we need `SwiftLog`-compatible _logging backends_ which then either persist the log messages in files, render them in nicer colors on the terminal, or send them over to Splunk or ELK. + +What `SwiftLog` provides today can be found in the [API docs][api-docs]. + +## Getting started + +If you have a server-side Swift application, or maybe a cross-platform (for example Linux & macOS) app/library, and you would like to log, we think targeting this logging API package is a great idea. Below you'll find all you need to know to get started. + +#### Adding the dependency + +`SwiftLog` is designed for Swift 5, the `1.0.0` release requires Swift 5 (however we will soon tag a `0.x` version that will work with Swift 4 for the transition period). To depend on the logging API package, you need to declare your dependency in your `Package.swift`: + +```swift +.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"), +``` + +and to your application/library target, add `"Logging"` to your `dependencies`, e.g. like this: + +```swift +.target(name: "BestExampleApp", dependencies: ["Logging"]), +``` + +#### Let's log + +```swift +// 1) let's import the logging API package +import Logging + +// 2) we need to create a logger, the label works similarly to a DispatchQueue label +let logger = Logger(label: "com.example.BestExampleApp.main") + +// 3) we're now ready to use it +logger.info("Hello World!") +``` + +#### Output + +``` +2019-03-13T15:46:38+0000 info: Hello World! +``` + +#### Default `Logger` behavior + +`SwiftLog` provides for very basic console logging out-of-the-box by way of `StreamLogHandler`. It is possible to switch the default output to `stderr` like so: +```swift +LoggingSystem.bootstrap(StreamLogHandler.standardError) +``` + +`StreamLogHandler` is primarily a convenience only and does not provide any substantial customization. Library maintainers who aim to build their own logging backends for integration and consumption should implement the `LogHandler` protocol directly as laid out in [the "On the implementation of a logging backend" section](#on-the-implementation-of-a-logging-backend-a-loghandler). + +For further information, please check the [API documentation][api-docs]. + + +#### Selecting a logging backend implementation (applications only) + +As the API has just launched, not many implementations exist yet. If you are interested in implementing one see the "Implementation considerations" section below explaining how to do so. List of existing SwiftLog API compatible libraries: + +| Repository | Handler Description| +| ----------- | ----------- | +| [IBM-Swift/HeliumLogger](https://github.com/IBM-Swift/HeliumLogger) |a logging backend widely used in the Kitura ecosystem | +| [ianpartridge/swift-log-**syslog**](https://github.com/ianpartridge/swift-log-syslog) | a [syslog](https://en.wikipedia.org/wiki/Syslog) backend| +| [Adorkable/swift-log-**format-and-pipe**](https://github.com/Adorkable/swift-log-format-and-pipe) | a backend that allows customization of the output format and the resulting destination | +| [chrisaljoudi/swift-log-**oslog**](https://github.com/chrisaljoudi/swift-log-oslog) | an OSLog [Unified Logging](https://developer.apple.com/documentation/os/logging) backend for use on Apple platforms. **Important Note:** we recommend using os_log directly as decribed [here](https://developer.apple.com/documentation/os/logging). Using os_log through swift-log using this backend will be less efficient and will also prevent specifying the privacy of the message. The backend always uses `%{public}@` as the format string and eagerly converts all string interpolations to strings. This has two drawbacks: 1. the static components of the string interpolation would be eagerly copied by the unified logging system, which will result in loss of performance. 2. It makes all messages public, which changes the default privacy policy of os_log, and doesn't allow specifying fine-grained privacy of sections of the message. In a separate on-going work, Swift APIs for os_log are being improved and made to align closely with swift-log APIs. References: [Unifying Logging Levels](https://forums.swift.org/t/custom-string-interpolation-and-compile-time-interpretation-applied-to-logging/18799), [Making os_log accept string interpolations using compile-time interpretation](https://forums.swift.org/t/logging-levels-for-swifts-server-side-logging-apis-and-new-os-log-apis/20365). | +| [Brainfinance/StackdriverLogging](https://github.com/Brainfinance/StackdriverLogging) | a structured JSON logging backend for use on Google Cloud Platform with the [Stackdriver logging agent](https://cloud.google.com/logging/docs/agent) | +| [vapor/console-kit](https://github.com/vapor/console-kit/) | print log messages to a terminal with stylized ([ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code)) output | +| [neallester/swift-log-testing](https://github.com/neallester/swift-log-testing) | provides access to log messages for use in assertions (within test targets) | +| [wlisac/swift-log-slack](https://github.com/wlisac/swift-log-slack) | a logging backend that sends critical log messages to Slack | +| [NSHipster/swift-log-github-actions](https://github.com/NSHipster/swift-log-github-actions) | a logging backend that translates logging messages into [workflow commands for GitHub Actions](https://help.github.com/en/actions/reference/workflow-commands-for-github-actions). | +| [stevapple/swift-log-telegram](https://github.com/stevapple/swift-log-telegram) | a logging backend that sends log messages to any Telegram chat (Inspired by and forked from [wlisac/swift-log-slack](https://github.com/wlisac/swift-log-slack)) | +| [jagreenwood/swift-log-datadog](https://github.com/jagreenwood/swift-log-datadog) | a logging backend which sends log messages to the [Datadog](https://www.datadoghq.com/log-management/) log management service | +| Your library? | [Get in touch!](https://forums.swift.org/c/server) | + +## What is an API package? + +Glad you asked. We believe that for the Swift on Server ecosystem, it's crucial to have a logging API that can be adopted by anybody so a multitude of libraries from different parties can all log to a shared destination. More concretely this means that we believe all the log messages from all libraries end up in the same file, database, Elastic Stack/Splunk instance, or whatever you may choose. + +In the real-world however, there are so many opinions over how exactly a logging system should behave, what a log message should be formatted like, and where/how it should be persisted. We think it's not feasible to wait for one logging package to support everything that a specific deployment needs whilst still being easy enough to use and remain performant. That's why we decided to cut the problem in half: + +1. a logging API +2. a logging backend implementation + +This package only provides the logging API itself and therefore `SwiftLog` is a 'logging API package'. `SwiftLog` (using `LoggingSystem.bootstrap`) can be configured to choose any compatible logging backend implementation. This way packages can adopt the API and the _application_ can choose any compatible logging backend implementation without requiring any changes from any of the libraries. + +Just for completeness sake: This API package does actually include an overly simplistic and non-configurable logging backend implementation which simply writes all log messages to `stdout`. The reason to include this overly simplistic logging backend implementation is to improve the first-time usage experience. Let's assume you start a project and try out `SwiftLog` for the first time, it's just a whole lot better to see something you logged appear on `stdout` in a simplistic format rather than nothing happening at all. For any real-world application, we advise configuring another logging backend implementation that logs in the style you like. + +## The core concepts + +### Loggers + +`Logger`s are used to emit log messages and therefore the most important type in `SwiftLog`, so their use should be as simple as possible. Most commonly, they are used to emit log messages in a certain log level. For example: + +```swift +// logging an informational message +logger.info("Hello World!") + +// ouch, something went wrong +logger.error("Houston, we have a problem: \(problem)") +``` + +### Log levels + +The following log levels are supported: + + - `trace` + - `debug` + - `info` + - `notice` + - `warning` + - `error` + - `critical` + +The log level of a given logger can be changed, but the change will only affect the specific logger you changed it on. You could say the `Logger` is a _value type_ regarding the log level. + + +### Logging metadata + +Logging metadata is metadata that can be attached to loggers to add information that is crucial when debugging a problem. In servers, the usual example is attaching a request UUID to a logger that will then be present on all log messages logged with that logger. Example: + +```swift +var logger = logger +logger[metadataKey: "request-uuid"] = "\(UUID())" +logger.info("hello world") +``` + +will print + +``` +2019-03-13T18:30:02+0000 info: request-uuid=F8633013-3DD8-481C-9256-B296E43443ED hello world +``` + +with the default logging backend implementation that ships with `SwiftLog`. Needless to say, the format is fully defined by the logging backend you choose. + +## On the implementation of a logging backend (a `LogHandler`) + +Note: If you don't want to implement a custom logging backend, everything in this section is probably not very relevant, so please feel free to skip. + +To become a compatible logging backend that all `SwiftLog` consumers can use, you need to do two things: 1) Implement a type (usually a `struct`) that implements `LogHandler`, a protocol provided by `SwiftLog` and 2) instruct `SwiftLog` to use your logging backend implementation. + +A `LogHandler` or logging backend implementation is anything that conforms to the following protocol + +```swift +public protocol LogHandler { + func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?, file: String, function: String, line: UInt) + + subscript(metadataKey _: String) -> Logger.Metadata.Value? { get set } + + var metadata: Logger.Metadata { get set } + + var logLevel: Logger.Level { get set } +} +``` + +Instructing `SwiftLog` to use your logging backend as the one the whole application (including all libraries) should use is very simple: + + LoggingSystem.bootstrap(MyLogHandler.init) + +### Implementation considerations + +`LogHandler`s control most parts of the logging system: + +#### Under control of a `LogHandler` + +##### Configuration + +`LogHandler`s control the two crucial pieces of `Logger` configuration, namely: + +- log level (`logger.logLevel` property) +- logging metadata (`logger[metadataKey:]` and `logger.metadata`) + +For the system to work, however, it is important that `LogHandler` treat the configuration as _value types_. This means that `LogHandler`s should be `struct`s and a change in log level or logging metadata should only affect the very `LogHandler` it was changed on. + +However, in special cases, it is acceptable that a `LogHandler` provides some global log level override that may affect all `LogHandler`s created. + +##### Emitting +- emitting the log message itself + +### Not under control of `LogHandler`s + +`LogHandler`s do not control if a message should be logged or not. `Logger` will only invoke the `log` function of a `LogHandler` if `Logger` determines that a log message should be emitted given the configured log level. + +## Source vs Label + +A `Logger` carries an (immutable) `label` and each log message carries a `source` parameter (since SwiftLog 1.3.0). The `Logger`'s label +identifies the creator of the `Logger`. If you are using structured logging by preserving metadata across multiple modules, the `Logger`'s +`label` is not a good way to identify where a log message originated from as it identifies the creator of a `Logger` which is often passed +around between libraries to preserve metadata and the like. + +If you want to filter all log messages originating from a certain subsystem, filter by `source` which defaults to the module that is emitting the +log message. + +## SwiftLog for Swift 4 + + +First of, SwiftLog 1.0.x and SwiftLog 0.0.x are mostly compatible so don't be afraid. In fact, SwiftLog 0.0.0 is the same source code as SwiftLog 1.0.0 with a few changes made to make it Swift 4 compatible. + +### How can I use SwiftLog 0 library or application? + +If you have a application or a library that needs to be compatible with both Swift 4 and 5, then we recommend using the following in your `Package.swift`: + +```swift +.package(url: "https://github.com/apple/swift-log.git", Version("0.0.0") ..< Version("2.0.0")), +``` + +This will instruct SwiftPM to allow any SwiftLog 0 and any SwiftLog 1 version. This is an unusual form because usually packages don't support multiple major versions of a package. Because SwiftLog 0 and 1 are mostly compatible however, this should not be a real issue and will enable everybody to get the best. If compiled with a Swift 4 compiler, this will be a SwiftLog 0 version but if compiled with a Swift 5 compiler everybody will get the best experience and performance delivered by SwiftLog 1. + +In most cases, there is only one thing you need to remember: Always use _string literals_ and _string interpolations_ in the log methods and don't rely on the fact that SwiftLog 0 also allows `String`. + +Good: + +```swift +logger.info("hello world") +``` + +Bad: + +```swift +let message = "hello world" +logger.info(message) +``` + +If you have a `String` that you received from elsewhere, please use + +```swift +logger.info("\(stringIAlreadyHave)") +``` + +For more details, have a look in the next section. + + +### What are the differences between SwiftLog 1 and 0? + +- SwiftLog 0 does not use `@inlinable`. +- Apart from accepting `Logger.Message` for the message, SwiftLog 0 has a `String` overload. +- In SwiftLog 0, `Logger.Message` is not `ExpressibleByStringLiteral` or `ExpressibleByStringInterpolation`. +- In SwiftLog 0, `Logger.MetadataValue` is not `ExpressibleByStringLiteral` or `ExpressibleByStringInterpolation`. + +#### Why these differences? + +##### @inlinable + +Swift 4.0 & 4.1 don't support `@inlinable`, so SwiftLog 0 can't use them. + +##### Logger.Message +Because all Swift 4 versions don't have a (non-deprecated) mechanism for a type to be `ExpressibleByStringInterpolation` we couldn't make `Logger.Message` expressible by string literals. Unfortunately, the most basic form of our logging API is `logger.info("Hello \(world)")`. For this to work however, `"Hello \(world)"` needs to be accepted and because we can't make `Logger.Message` `ExpressibleByStringInterpolation` we added an overload for all the logging methods to also accept `String`. In most cases, you won't even notice that with SwiftLog 0 you're creating a `String` (which is then transformed to a `Logger.Message`) and with SwiftLog 1 you're creating a `Logger.Message` directly. That is because both `String` and `Logger.Message` will accept all forms of string literals and string interpolations. +Unfortunately, there is code that will make this seemingly small difference visible. If you write + +```swift +let message = "Hello world" +logger.info(message) +``` + +then this will only work in SwiftLog 0 and not in SwiftLog 1. Why? Because SwiftLog 1 will want a `Logger.Message` but `let message = "Hello world"` will make `message` to be of type `String` and in SwiftLog 1, the logging methods don't accept `String`s. + +So if you intend to be compatible with SwiftLog 0 and 1 at the same time, please make sure to always use a _string literal_ or a _string interpolation_ inside of the logging methods. + +In the case that you already have a `String` handy that you want to log, don't worry at all, just use + +```swift +let message = "Hello world" +logger.info("\(message)") +``` + +and again, you will be okay with SwiftLog 0 and 1. + +## Design + +This logging API was designed with the contributors to the Swift on Server community and approved by the [SSWG (Swift Server Work Group)](https://swift.org/server/) to the 'sandbox level' of the SSWG's [incubation process](https://github.com/swift-server/sswg/blob/master/process/incubation.md). + +- [pitch](https://forums.swift.org/t/logging/16027), [discussion](https://forums.swift.org/t/discussion-server-logging-api/18834), [feedback](https://forums.swift.org/t/feedback-server-logging-api-with-revisions/19375) +- [log levels](https://forums.swift.org/t/logging-levels-for-swifts-server-side-logging-apis-and-new-os-log-apis/20365) + +[api-docs]: https://apple.github.io/swift-log/docs/current/Logging/Structs/Logger.html diff --git a/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Locks.swift b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Locks.swift new file mode 100644 index 00000000..5c4d32d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Locks.swift @@ -0,0 +1,257 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Logging API open source project +// +// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift Logging API project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Windows) +import WinSDK +#else +import Glibc +#endif + +/// A threading lock based on `libpthread` instead of `libdispatch`. +/// +/// This object provides a lock on top of a single `pthread_mutex_t`. This kind +/// of lock is safe to use with `libpthread`-based threading models, such as the +/// one used by NIO. On Windows, the lock is based on the substantially similar +/// `SRWLOCK` type. +internal final class Lock { + #if os(Windows) + fileprivate let mutex: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) + #else + fileprivate let mutex: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) + #endif + + /// Create a new lock. + public init() { + #if os(Windows) + InitializeSRWLock(self.mutex) + #else + var attr = pthread_mutexattr_t() + pthread_mutexattr_init(&attr) + pthread_mutexattr_settype(&attr, .init(PTHREAD_MUTEX_ERRORCHECK)) + + let err = pthread_mutex_init(self.mutex, &attr) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") + #endif + } + + deinit { + #if os(Windows) + // SRWLOCK does not need to be free'd + #else + let err = pthread_mutex_destroy(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") + #endif + self.mutex.deallocate() + } + + /// Acquire the lock. + /// + /// Whenever possible, consider using `withLock` instead of this method and + /// `unlock`, to simplify lock handling. + public func lock() { + #if os(Windows) + AcquireSRWLockExclusive(self.mutex) + #else + let err = pthread_mutex_lock(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") + #endif + } + + /// Release the lock. + /// + /// Whenever possible, consider using `withLock` instead of this method and + /// `lock`, to simplify lock handling. + public func unlock() { + #if os(Windows) + ReleaseSRWLockExclusive(self.mutex) + #else + let err = pthread_mutex_unlock(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") + #endif + } +} + +extension Lock { + /// Acquire the lock for the duration of the given block. + /// + /// This convenience method should be preferred to `lock` and `unlock` in + /// most situations, as it ensures that the lock will be released regardless + /// of how `body` exits. + /// + /// - Parameter body: The block to execute while holding the lock. + /// - Returns: The value returned by the block. + @inlinable + internal func withLock(_ body: () throws -> T) rethrows -> T { + self.lock() + defer { + self.unlock() + } + return try body() + } + + // specialise Void return (for performance) + @inlinable + internal func withLockVoid(_ body: () throws -> Void) rethrows { + try self.withLock(body) + } +} + +/// A reader/writer threading lock based on `libpthread` instead of `libdispatch`. +/// +/// This object provides a lock on top of a single `pthread_rwlock_t`. This kind +/// of lock is safe to use with `libpthread`-based threading models, such as the +/// one used by NIO. On Windows, the lock is based on the substantially similar +/// `SRWLOCK` type. +internal final class ReadWriteLock { + #if os(Windows) + fileprivate let rwlock: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) + fileprivate var shared: Bool = true + #else + fileprivate let rwlock: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) + #endif + + /// Create a new lock. + public init() { + #if os(Windows) + InitializeSRWLock(self.rwlock) + #else + let err = pthread_rwlock_init(self.rwlock, nil) + precondition(err == 0, "\(#function) failed in pthread_rwlock with error \(err)") + #endif + } + + deinit { + #if os(Windows) + // SRWLOCK does not need to be free'd + #else + let err = pthread_rwlock_destroy(self.rwlock) + precondition(err == 0, "\(#function) failed in pthread_rwlock with error \(err)") + #endif + self.rwlock.deallocate() + } + + /// Acquire a reader lock. + /// + /// Whenever possible, consider using `withReaderLock` instead of this + /// method and `unlock`, to simplify lock handling. + public func lockRead() { + #if os(Windows) + AcquireSRWLockShared(self.rwlock) + self.shared = true + #else + let err = pthread_rwlock_rdlock(self.rwlock) + precondition(err == 0, "\(#function) failed in pthread_rwlock with error \(err)") + #endif + } + + /// Acquire a writer lock. + /// + /// Whenever possible, consider using `withWriterLock` instead of this + /// method and `unlock`, to simplify lock handling. + public func lockWrite() { + #if os(Windows) + AcquireSRWLockExclusive(self.rwlock) + self.shared = false + #else + let err = pthread_rwlock_wrlock(self.rwlock) + precondition(err == 0, "\(#function) failed in pthread_rwlock with error \(err)") + #endif + } + + /// Release the lock. + /// + /// Whenever possible, consider using `withReaderLock` and `withWriterLock` + /// instead of this method and `lockRead` and `lockWrite`, to simplify lock + /// handling. + public func unlock() { + #if os(Windows) + if self.shared { + ReleaseSRWLockShared(self.rwlock) + } else { + ReleaseSRWLockExclusive(self.rwlock) + } + #else + let err = pthread_rwlock_unlock(self.rwlock) + precondition(err == 0, "\(#function) failed in pthread_rwlock with error \(err)") + #endif + } +} + +extension ReadWriteLock { + /// Acquire the reader lock for the duration of the given block. + /// + /// This convenience method should be preferred to `lockRead` and `unlock` + /// in most situations, as it ensures that the lock will be released + /// regardless of how `body` exits. + /// + /// - Parameter body: The block to execute while holding the reader lock. + /// - Returns: The value returned by the block. + @inlinable + internal func withReaderLock(_ body: () throws -> T) rethrows -> T { + self.lockRead() + defer { + self.unlock() + } + return try body() + } + + /// Acquire the writer lock for the duration of the given block. + /// + /// This convenience method should be preferred to `lockWrite` and `unlock` + /// in most situations, as it ensures that the lock will be released + /// regardless of how `body` exits. + /// + /// - Parameter body: The block to execute while holding the writer lock. + /// - Returns: The value returned by the block. + @inlinable + internal func withWriterLock(_ body: () throws -> T) rethrows -> T { + self.lockWrite() + defer { + self.unlock() + } + return try body() + } + + // specialise Void return (for performance) + @inlinable + internal func withReaderLockVoid(_ body: () throws -> Void) rethrows { + try self.withReaderLock(body) + } + + // specialise Void return (for performance) + @inlinable + internal func withWriterLockVoid(_ body: () throws -> Void) rethrows { + try self.withWriterLock(body) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/LogHandler.swift b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/LogHandler.swift new file mode 100644 index 00000000..6b52b120 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/LogHandler.swift @@ -0,0 +1,188 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Logging API open source project +// +// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift Logging API project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A `LogHandler` is an implementation of a logging backend. +/// +/// This type is an implementation detail and should not normally be used, unless implementing your own logging backend. +/// To use the SwiftLog API, please refer to the documentation of `Logger`. +/// +/// # Implementation requirements +/// +/// To implement your own `LogHandler` you should respect a few requirements that are necessary so applications work +/// as expected regardless of the selected `LogHandler` implementation. +/// +/// - The `LogHandler` must be a `struct`. +/// - The metadata and `logLevel` properties must be implemented so that setting them on a `Logger` does not affect +/// other `Logger`s. +/// +/// ### Treat log level & metadata as values +/// +/// When developing your `LogHandler`, please make sure the following test works. +/// +/// ```swift +/// LoggingSystem.bootstrap(MyLogHandler.init) // your LogHandler might have a different bootstrapping step +/// var logger1 = Logger(label: "first logger") +/// logger1.logLevel = .debug +/// logger1[metadataKey: "only-on"] = "first" +/// +/// var logger2 = logger1 +/// logger2.logLevel = .error // this must not override `logger1`'s log level +/// logger2[metadataKey: "only-on"] = "second" // this must not override `logger1`'s metadata +/// +/// XCTAssertEqual(.debug, logger1.logLevel) +/// XCTAssertEqual(.error, logger2.logLevel) +/// XCTAssertEqual("first", logger1[metadataKey: "only-on"]) +/// XCTAssertEqual("second", logger2[metadataKey: "only-on"]) +/// ``` +/// +/// ### Special cases +/// +/// In certain special cases, the log level behaving like a value on `Logger` might not be what you want. For example, +/// you might want to set the log level across _all_ `Logger`s to `.debug` when say a signal (eg. `SIGUSR1`) is received +/// to be able to debug special failures in production. This special case is acceptable but we urge you to create a +/// solution specific to your `LogHandler` implementation to achieve that. Please find an example implementation of this +/// behavior below, on reception of the signal you would call +/// `LogHandlerWithGlobalLogLevelOverride.overrideGlobalLogLevel = .debug`, for example. +/// +/// ```swift +/// import class Foundation.NSLock +/// +/// public struct LogHandlerWithGlobalLogLevelOverride: LogHandler { +/// // the static properties hold the globally overridden log level (if overridden) +/// private static let overrideLock = NSLock() +/// private static var overrideLogLevel: Logger.Level? = nil +/// +/// // this holds the log level if not overridden +/// private var _logLevel: Logger.Level = .info +/// +/// // metadata storage +/// public var metadata: Logger.Metadata = [:] +/// +/// public init(label: String) { +/// // [...] +/// } +/// +/// public var logLevel: Logger.Level { +/// // when we get asked for the log level, we check if it was globally overridden or not +/// get { +/// LogHandlerWithGlobalLogLevelOverride.overrideLock.lock() +/// defer { LogHandlerWithGlobalLogLevelOverride.overrideLock.unlock() } +/// return LogHandlerWithGlobalLogLevelOverride.overrideLogLevel ?? self._logLevel +/// } +/// // we set the log level whenever we're asked (note: this might not have an effect if globally +/// // overridden) +/// set { +/// self._logLevel = newValue +/// } +/// } +/// +/// public func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?, +/// source: String, file: String, function: String, line: UInt) { +/// // [...] +/// } +/// +/// public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? { +/// get { +/// return self.metadata[metadataKey] +/// } +/// set(newValue) { +/// self.metadata[metadataKey] = newValue +/// } +/// } +/// +/// // this is the function to globally override the log level, it is not part of the `LogHandler` protocol +/// public static func overrideGlobalLogLevel(_ logLevel: Logger.Level) { +/// LogHandlerWithGlobalLogLevelOverride.overrideLock.lock() +/// defer { LogHandlerWithGlobalLogLevelOverride.overrideLock.unlock() } +/// LogHandlerWithGlobalLogLevelOverride.overrideLogLevel = logLevel +/// } +/// } +/// ``` +/// +/// Please note that the above `LogHandler` will still pass the 'log level is a value' test above it iff the global log +/// level has not been overridden. And most importantly it passes the requirement listed above: A change to the log +/// level on one `Logger` should not affect the log level of another `Logger` variable. +public protocol LogHandler { + /// This method is called when a `LogHandler` must emit a log message. There is no need for the `LogHandler` to + /// check if the `level` is above or below the configured `logLevel` as `Logger` already performed this check and + /// determined that a message should be logged. + /// + /// - parameters: + /// - level: The log level the message was logged at. + /// - message: The message to log. To obtain a `String` representation call `message.description`. + /// - metadata: The metadata associated to this log message. + /// - source: The source where the log message originated, for example the logging module. + /// - file: The file the log message was emitted from. + /// - function: The function the log line was emitted from. + /// - line: The line the log message was emitted from. + func log(level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt) + + /// SwiftLog 1.0 compatibility method. Please do _not_ implement, implement + /// `log(level:message:metadata:source:file:function:line:)` instead. + @available(*, deprecated, renamed: "log(level:message:metadata:source:file:function:line:)") + func log(level: Logging.Logger.Level, message: Logging.Logger.Message, metadata: Logging.Logger.Metadata?, file: String, function: String, line: UInt) + + /// Add, remove, or change the logging metadata. + /// + /// - note: `LogHandler`s must treat logging metadata as a value type. This means that the change in metadata must + /// only affect this very `LogHandler`. + /// + /// - parameters: + /// - metadataKey: The key for the metadata item + subscript(metadataKey _: String) -> Logger.Metadata.Value? { get set } + + /// Get or set the entire metadata storage as a dictionary. + /// + /// - note: `LogHandler`s must treat logging metadata as a value type. This means that the change in metadata must + /// only affect this very `LogHandler`. + var metadata: Logger.Metadata { get set } + + /// Get or set the configured log level. + /// + /// - note: `LogHandler`s must treat the log level as a value type. This means that the change in metadata must + /// only affect this very `LogHandler`. It is acceptable to provide some form of global log level override + /// that means a change in log level on a particular `LogHandler` might not be reflected in any + /// `LogHandler`. + var logLevel: Logger.Level { get set } +} + +extension LogHandler { + @available(*, deprecated, message: "You should implement this method instead of using the default implementation") + public func log(level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt) { + self.log(level: level, message: message, metadata: metadata, file: file, function: function, line: line) + } + + @available(*, deprecated, renamed: "log(level:message:metadata:source:file:function:line:)") + public func log(level: Logging.Logger.Level, message: Logging.Logger.Message, metadata: Logging.Logger.Metadata?, file: String, function: String, line: UInt) { + self.log(level: level, + message: message, + metadata: metadata, + source: Logger.currentModule(filePath: file), + file: file, + function: function, + line: line) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Logging.swift b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Logging.swift new file mode 100644 index 00000000..434eb927 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Logging/Sources/Logging/Logging.swift @@ -0,0 +1,826 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Logging API open source project +// +// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift Logging API project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Windows) +import MSVCRT +#else +import Glibc +#endif + +/// A `Logger` is the central type in `SwiftLog`. Its central function is to emit log messages using one of the methods +/// corresponding to a log level. +/// +/// `Logger`s are value types with respect to the `logLevel` and the `metadata` (as well as the immutable `label` +/// and the selected `LogHandler`). Therefore, `Logger`s are suitable to be passed around between libraries if you want +/// to preserve metadata across libraries. +/// +/// The most basic usage of a `Logger` is +/// +/// logger.info("Hello World!") +/// +public struct Logger { + @usableFromInline + var handler: LogHandler + + /// An identifier of the creator of this `Logger`. + public let label: String + + internal init(label: String, _ handler: LogHandler) { + self.label = label + self.handler = handler + } +} + +extension Logger { + /// Log a message passing the log level as a parameter. + /// + /// If the `logLevel` passed to this method is more severe than the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - level: The log level to log `message` at. For the available log levels, see `Logger.Level`. + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func log(level: Logger.Level, + _ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + if self.logLevel <= level { + self.handler.log(level: level, + message: message(), + metadata: metadata(), + source: source() ?? Logger.currentModule(filePath: (file)), + file: file, function: function, line: line) + } + } + + /// Add, change, or remove a logging metadata item. + /// + /// - note: Logging metadata behaves as a value that means a change to the logging metadata will only affect the + /// very `Logger` it was changed on. + @inlinable + public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? { + get { + return self.handler[metadataKey: metadataKey] + } + set { + self.handler[metadataKey: metadataKey] = newValue + } + } + + /// Get or set the log level configured for this `Logger`. + /// + /// - note: `Logger`s treat `logLevel` as a value. This means that a change in `logLevel` will only affect this + /// very `Logger`. It it acceptable for logging backends to have some form of global log level override + /// that affects multiple or even all loggers. This means a change in `logLevel` to one `Logger` might in + /// certain cases have no effect. + @inlinable + public var logLevel: Logger.Level { + get { + return self.handler.logLevel + } + set { + self.handler.logLevel = newValue + } + } +} + +extension Logger { + /// Log a message passing with the `Logger.Level.trace` log level. + /// + /// If `.trace` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func trace(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .trace, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.debug` log level. + /// + /// If `.debug` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func debug(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .debug, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.info` log level. + /// + /// If `.info` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func info(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .info, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.notice` log level. + /// + /// If `.notice` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func notice(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .notice, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.warning` log level. + /// + /// If `.warning` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func warning(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .warning, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.error` log level. + /// + /// If `.error` is at least as severe as the `Logger`'s `logLevel`, it will be logged, + /// otherwise nothing will happen. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func error(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .error, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } + + /// Log a message passing with the `Logger.Level.critical` log level. + /// + /// `.critical` messages will always be logged. + /// + /// - parameters: + /// - message: The message to be logged. `message` can be used with any string interpolation literal. + /// - metadata: One-off metadata to attach to this log message. + /// - source: The source this log messages originates to. Currently, it defaults to the folder containing the + /// file that is emitting the log message, which usually is the module. + /// - file: The file this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#file`). + /// - function: The function this log message originates from (there's usually no need to pass it explicitly as + /// it defaults to `#function`). + /// - line: The line this log message originates from (there's usually no need to pass it explicitly as it + /// defaults to `#line`). + @inlinable + public func critical(_ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + source: @autoclosure () -> String? = nil, + file: String = #file, function: String = #function, line: UInt = #line) { + self.log(level: .critical, message(), metadata: metadata(), source: source(), file: file, function: function, line: line) + } +} + +/// The `LoggingSystem` is a global facility where the default logging backend implementation (`LogHandler`) can be +/// configured. `LoggingSystem` is set up just once in a given program to set up the desired logging backend +/// implementation. +public enum LoggingSystem { + fileprivate static let lock = ReadWriteLock() + fileprivate static var factory: (String) -> LogHandler = StreamLogHandler.standardOutput + fileprivate static var initialized = false + + /// `bootstrap` is a one-time configuration function which globally selects the desired logging backend + /// implementation. `bootstrap` can be called at maximum once in any given program, calling it more than once will + /// lead to undefined behavior, most likely a crash. + /// + /// - parameters: + /// - factory: A closure that given a `Logger` identifier, produces an instance of the `LogHandler`. + public static func bootstrap(_ factory: @escaping (String) -> LogHandler) { + self.lock.withWriterLock { + precondition(!self.initialized, "logging system can only be initialized once per process.") + self.factory = factory + self.initialized = true + } + } + + // for our testing we want to allow multiple bootstraping + internal static func bootstrapInternal(_ factory: @escaping (String) -> LogHandler) { + self.lock.withWriterLock { + self.factory = factory + } + } +} + +extension Logger { + /// `Metadata` is a typealias for `[String: Logger.MetadataValue]` the type of the metadata storage. + public typealias Metadata = [String: MetadataValue] + + /// A logging metadata value. `Logger.MetadataValue` is string, array, and dictionary literal convertible. + /// + /// `MetadataValue` provides convenient conformances to `ExpressibleByStringInterpolation`, + /// `ExpressibleByStringLiteral`, `ExpressibleByArrayLiteral`, and `ExpressibleByDictionaryLiteral` which means + /// that when constructing `MetadataValue`s you should default to using Swift's usual literals. + /// + /// Examples: + /// - prefer `logger.info("user logged in", metadata: ["user-id": "\(user.id)"])` over + /// `..., metadata: ["user-id": .string(user.id.description)])` + /// - prefer `logger.info("user selected colors", metadata: ["colors": ["\(user.topColor)", "\(user.secondColor)"]])` + /// over `..., metadata: ["colors": .array([.string("\(user.topColor)"), .string("\(user.secondColor)")])` + /// - prefer `logger.info("nested info", metadata: ["nested": ["fave-numbers": ["\(1)", "\(2)", "\(3)"], "foo": "bar"]])` + /// over `..., metadata: ["nested": .dictionary(["fave-numbers": ...])])` + public enum MetadataValue { + /// A metadata value which is a `String`. + /// + /// Because `MetadataValue` implements `ExpressibleByStringInterpolation`, and `ExpressibleByStringLiteral`, + /// you don't need to type `.string(someType.description)` you can use the string interpolation `"\(someType)"`. + case string(String) + + /// A metadata value which is some `CustomStringConvertible`. + case stringConvertible(CustomStringConvertible) + + /// A metadata value which is a dictionary from `String` to `Logger.MetadataValue`. + /// + /// Because `MetadataValue` implements `ExpressibleByDictionaryLiteral`, you don't need to type + /// `.dictionary(["foo": .string("bar \(buz)")])`, you can just use the more natural `["foo": "bar \(buz)"]`. + case dictionary(Metadata) + + /// A metadata value which is an array of `Logger.MetadataValue`s. + /// + /// Because `MetadataValue` implements `ExpressibleByArrayLiteral`, you don't need to type + /// `.array([.string("foo"), .string("bar \(buz)")])`, you can just use the more natural `["foo", "bar \(buz)"]`. + case array([Metadata.Value]) + } + + /// The log level. + /// + /// Log levels are ordered by their severity, with `.trace` being the least severe and + /// `.critical` being the most severe. + public enum Level: String, Codable, CaseIterable { + /// Appropriate for messages that contain information normally of use only when + /// tracing the execution of a program. + case trace + + /// Appropriate for messages that contain information normally of use only when + /// debugging a program. + case debug + + /// Appropriate for informational messages. + case info + + /// Appropriate for conditions that are not error conditions, but that may require + /// special handling. + case notice + + /// Appropriate for messages that are not error conditions, but more severe than + /// `.notice`. + case warning + + /// Appropriate for error conditions. + case error + + /// Appropriate for critical error conditions that usually require immediate + /// attention. + /// + /// When a `critical` message is logged, the logging backend (`LogHandler`) is free to perform + /// more heavy-weight operations to capture system state (such as capturing stack traces) to facilitate + /// debugging. + case critical + } + + /// Construct a `Logger` given a `label` identifying the creator of the `Logger`. + /// + /// The `label` should identify the creator of the `Logger`. This can be an application, a sub-system, or even + /// a datatype. + /// + /// - parameters: + /// - label: An identifier for the creator of a `Logger`. + public init(label: String) { + self = LoggingSystem.lock.withReaderLock { Logger(label: label, LoggingSystem.factory(label)) } + } + + /// Construct a `Logger` given a `label` identifying the creator of the `Logger` or a non-standard `LogHandler`. + /// + /// The `label` should identify the creator of the `Logger`. This can be an application, a sub-system, or even + /// a datatype. + /// + /// This initializer provides an escape hatch in case the global default logging backend implementation (set up + /// using `LoggingSystem.bootstrap` is not appropriate for this particular logger. + /// + /// - parameters: + /// - label: An identifier for the creator of a `Logger`. + /// - factory: A closure creating non-standard `LogHandler`s. + public init(label: String, factory: (String) -> LogHandler) { + self = Logger(label: label, factory(label)) + } +} + +extension Logger.Level { + internal var naturalIntegralValue: Int { + switch self { + case .trace: + return 0 + case .debug: + return 1 + case .info: + return 2 + case .notice: + return 3 + case .warning: + return 4 + case .error: + return 5 + case .critical: + return 6 + } + } +} + +extension Logger.Level: Comparable { + public static func < (lhs: Logger.Level, rhs: Logger.Level) -> Bool { + return lhs.naturalIntegralValue < rhs.naturalIntegralValue + } +} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9687 +// Then we could write it as follows and it would work under Swift 5 and not only 4 as it does currently: +// extension Logger.Metadata.Value: Equatable { +extension Logger.MetadataValue: Equatable { + public static func == (lhs: Logger.Metadata.Value, rhs: Logger.Metadata.Value) -> Bool { + switch (lhs, rhs) { + case (.string(let lhs), .string(let rhs)): + return lhs == rhs + case (.stringConvertible(let lhs), .stringConvertible(let rhs)): + return lhs.description == rhs.description + case (.array(let lhs), .array(let rhs)): + return lhs == rhs + case (.dictionary(let lhs), .dictionary(let rhs)): + return lhs == rhs + default: + return false + } + } +} + +extension Logger { + /// `Logger.Message` represents a log message's text. It is usually created using string literals. + /// + /// Example creating a `Logger.Message`: + /// + /// let world: String = "world" + /// let myLogMessage: Logger.Message = "Hello \(world)" + /// + /// Most commonly, `Logger.Message`s appear simply as the parameter to a logging method such as: + /// + /// logger.info("Hello \(world)") + /// + public struct Message: ExpressibleByStringLiteral, Equatable, CustomStringConvertible, ExpressibleByStringInterpolation { + public typealias StringLiteralType = String + + private var value: String + + public init(stringLiteral value: String) { + self.value = value + } + + public var description: String { + return self.value + } + } +} + +/// A pseudo-`LogHandler` that can be used to send messages to multiple other `LogHandler`s. +/// +/// ### Effective Logger.Level +/// +/// When first initialized the multiplex log handlers' log level is automatically set to the minimum of all the +/// passed in log handlers. This ensures that each of the handlers will be able to log at their appropriate level +/// any log events they might be interested in. +/// +/// Example: +/// If log handler `A` is logging at `.debug` level, and log handler `B` is logging at `.info` level, the constructed +/// `MultiplexLogHandler([A, B])`'s effective log level will be set to `.debug`, meaning that debug messages will be +/// handled by this handler, while only logged by the underlying `A` log handler (since `B`'s log level is `.info` +/// and thus it would not actually log that log message). +/// +/// If the log level is _set_ on a `Logger` backed by an `MultiplexLogHandler` the log level will apply to *all* +/// underlying log handlers, allowing a logger to still select at what level it wants to log regardless of if the underlying +/// handler is a multiplex or a normal one. If for some reason one might want to not allow changing a log level of a specific +/// handler passed into the multiplex log handler, this is possible by wrapping it in a handler which ignores any log level changes. +/// +/// ### Effective Logger.Metadata +/// +/// Since a `MultiplexLogHandler` is a combination of multiple log handlers, the handling of metadata can be non-obvious. +/// For example, the underlying log handlers may have metadata of their own set before they are used to initialize the multiplex log handler. +/// +/// The multiplex log handler acts purely as proxy and does not make any changes to underlying handler metadata other than +/// proxying writes that users made on a `Logger` instance backed by this handler. +/// +/// Setting metadata is always proxied through to _all_ underlying handlers, meaning that if a modification like +/// `logger[metadataKey: "x"] = "y"` is made, all underlying log handlers that this multiplex handler was initiated with +/// will observe this change. +/// +/// Reading metadata from the multiplex log handler MAY need to pick one of conflicting values if the underlying log handlers +/// were already initiated with some metadata before passing them into the multiplex handler. The multiplex handler uses +/// the order in which the handlers were passed in during its initialization as a priority indicator - the first handler's +/// values are more important than the next handlers values, etc. +/// +/// Example: +/// If the multiplex log handler was initiated with two handlers like this: `MultiplexLogHandler([handler1, handler2])`. +/// The handlers each have some already set metadata: `handler1` has metadata values for keys `one` and `all`, and `handler2` +/// has values for keys `two` and `all`. +/// +/// A query through the multiplex log handler the key `one` naturally returns `handler1`'s value, and a query for `two` +/// naturally returns `handler2`'s value. Querying for the key `all` will return `handler1`'s value, as that handler was indicated +/// "more important" than the second handler. The same rule applies when querying for the `metadata` property of the +/// multiplex log handler - it constructs `Metadata` uniquing values. +public struct MultiplexLogHandler: LogHandler { + private var handlers: [LogHandler] + private var effectiveLogLevel: Logger.Level + + /// Create a `MultiplexLogHandler`. + /// + /// - parameters: + /// - handlers: An array of `LogHandler`s, each of which will receive the log messages sent to this `Logger`. + /// The array must not be empty. + public init(_ handlers: [LogHandler]) { + assert(!handlers.isEmpty, "MultiplexLogHandler.handlers MUST NOT be empty") + self.handlers = handlers + self.effectiveLogLevel = handlers.map { $0.logLevel }.min() ?? .trace + } + + public var logLevel: Logger.Level { + get { + return self.effectiveLogLevel + } + set { + self.mutatingForEachHandler { $0.logLevel = newValue } + self.effectiveLogLevel = newValue + } + } + + public func log(level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt) { + for handler in self.handlers where handler.logLevel <= level { + handler.log(level: level, message: message, metadata: metadata, source: source, file: file, function: function, line: line) + } + } + + public var metadata: Logger.Metadata { + get { + var effectiveMetadata: Logger.Metadata = [:] + // as a rough estimate we assume that the underlying handlers have a similar metadata count, + // and we use the first one's current count to estimate how big of a dictionary we need to allocate: + effectiveMetadata.reserveCapacity(self.handlers.first!.metadata.count) // !-safe, we always have at least one handler + return self.handlers.reduce(into: effectiveMetadata) { effectiveMetadata, handler in + effectiveMetadata.merge(handler.metadata, uniquingKeysWith: { l, _ in l }) + } + } + set { + self.mutatingForEachHandler { $0.metadata = newValue } + } + } + + public subscript(metadataKey metadataKey: Logger.Metadata.Key) -> Logger.Metadata.Value? { + get { + for handler in self.handlers { + if let value = handler[metadataKey: metadataKey] { + return value + } + } + return nil + } + set { + self.mutatingForEachHandler { $0[metadataKey: metadataKey] = newValue } + } + } + + private mutating func mutatingForEachHandler(_ mutator: (inout LogHandler) -> Void) { + for index in self.handlers.indices { + mutator(&self.handlers[index]) + } + } +} + +/// A wrapper to facilitate `print`-ing to stderr and stdio that +/// ensures access to the underlying `FILE` is locked to prevent +/// cross-thread interleaving of output. +internal struct StdioOutputStream: TextOutputStream { + internal let file: UnsafeMutablePointer + internal let flushMode: FlushMode + + internal func write(_ string: String) { + string.withCString { ptr in + #if os(Windows) + _lock_file(self.file) + #else + flockfile(self.file) + #endif + defer { + #if os(Windows) + _unlock_file(self.file) + #else + funlockfile(self.file) + #endif + } + _ = fputs(ptr, self.file) + if case .always = self.flushMode { + self.flush() + } + } + } + + /// Flush the underlying stream. + /// This has no effect when using the `.always` flush mode, which is the default + internal func flush() { + _ = fflush(self.file) + } + + internal static let stderr = StdioOutputStream(file: systemStderr, flushMode: .always) + internal static let stdout = StdioOutputStream(file: systemStdout, flushMode: .always) + + /// Defines the flushing strategy for the underlying stream. + internal enum FlushMode { + case undefined + case always + } +} + +// Prevent name clashes +#if os(macOS) || os(tvOS) || os(iOS) || os(watchOS) +let systemStderr = Darwin.stderr +let systemStdout = Darwin.stdout +#elseif os(Windows) +let systemStderr = MSVCRT.stderr +let systemStdout = MSVCRT.stdout +#else +let systemStderr = Glibc.stderr! +let systemStdout = Glibc.stdout! +#endif + +/// `StreamLogHandler` is a simple implementation of `LogHandler` for directing +/// `Logger` output to either `stderr` or `stdout` via the factory methods. +public struct StreamLogHandler: LogHandler { + /// Factory that makes a `StreamLogHandler` to directs its output to `stdout` + public static func standardOutput(label: String) -> StreamLogHandler { + return StreamLogHandler(label: label, stream: StdioOutputStream.stdout) + } + + /// Factory that makes a `StreamLogHandler` to directs its output to `stderr` + public static func standardError(label: String) -> StreamLogHandler { + return StreamLogHandler(label: label, stream: StdioOutputStream.stderr) + } + + private let stream: TextOutputStream + private let label: String + + public var logLevel: Logger.Level = .info + + private var prettyMetadata: String? + public var metadata = Logger.Metadata() { + didSet { + self.prettyMetadata = self.prettify(self.metadata) + } + } + + public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? { + get { + return self.metadata[metadataKey] + } + set { + self.metadata[metadataKey] = newValue + } + } + + // internal for testing only + internal init(label: String, stream: TextOutputStream) { + self.label = label + self.stream = stream + } + + public func log(level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt) { + let prettyMetadata = metadata?.isEmpty ?? true + ? self.prettyMetadata + : self.prettify(self.metadata.merging(metadata!, uniquingKeysWith: { _, new in new })) + + var stream = self.stream + stream.write("\(self.timestamp()) \(level) \(self.label) :\(prettyMetadata.map { " \($0)" } ?? "") \(message)\n") + } + + private func prettify(_ metadata: Logger.Metadata) -> String? { + return !metadata.isEmpty ? metadata.map { "\($0)=\($1)" }.joined(separator: " ") : nil + } + + private func timestamp() -> String { + var buffer = [Int8](repeating: 0, count: 255) + var timestamp = time(nil) + let localTime = localtime(×tamp) + strftime(&buffer, buffer.count, "%Y-%m-%dT%H:%M:%S%z", localTime) + return buffer.withUnsafeBufferPointer { + $0.withMemoryRebound(to: CChar.self) { + String(cString: $0.baseAddress!) + } + } + } +} + +/// No operation LogHandler, used when no logging is required +public struct SwiftLogNoOpLogHandler: LogHandler { + public init() {} + + @inlinable public func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?, file: String, function: String, line: UInt) {} + + @inlinable public subscript(metadataKey _: String) -> Logger.Metadata.Value? { + get { + return nil + } + set {} + } + + @inlinable public var metadata: Logger.Metadata { + get { + return [:] + } + set {} + } + + @inlinable public var logLevel: Logger.Level { + get { + return .critical + } + set {} + } +} + +extension Logger { + @inlinable + internal static func currentModule(filePath: String = #file) -> String { + let utf8All = filePath.utf8 + return filePath.utf8.lastIndex(of: UInt8(ascii: "/")).flatMap { lastSlash -> Substring? in + utf8All[.. Substring in + filePath[utf8All.index(after: secondLastSlash) ..< lastSlash] + } + }.map { + String($0) + } ?? "n/a" + } +} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9686 +extension Logger.MetadataValue: ExpressibleByStringLiteral { + public typealias StringLiteralType = String + + public init(stringLiteral value: String) { + self = .string(value) + } +} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9686 +extension Logger.MetadataValue: CustomStringConvertible { + public var description: String { + switch self { + case .dictionary(let dict): + return dict.mapValues { $0.description }.description + case .array(let list): + return list.map { $0.description }.description + case .string(let str): + return str + case .stringConvertible(let repr): + return repr.description + } + } +} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9687 +extension Logger.MetadataValue: ExpressibleByStringInterpolation {} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9686 +extension Logger.MetadataValue: ExpressibleByDictionaryLiteral { + public typealias Key = String + public typealias Value = Logger.Metadata.Value + + public init(dictionaryLiteral elements: (String, Logger.Metadata.Value)...) { + self = .dictionary(.init(uniqueKeysWithValues: elements)) + } +} + +// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for +// https://bugs.swift.org/browse/SR-9686 +extension Logger.MetadataValue: ExpressibleByArrayLiteral { + public typealias ArrayLiteralElement = Logger.Metadata.Value + + public init(arrayLiteral elements: Logger.Metadata.Value...) { + self = .array(elements) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Manifest.lock b/one-and-half-nibble/MobileApp/Pods/Manifest.lock new file mode 100644 index 00000000..3629c2df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Manifest.lock @@ -0,0 +1,279 @@ +PODS: + - _NIODataStructures (2.40.0) + - BigInt (5.2.0) + - BloctoSDK/Core (0.5.0) + - BloctoSDK/Flow (0.5.0): + - BloctoSDK/Core (~> 0.5.0) + - FlowSDK (~> 0.5.0) + - Cadence (0.5.0): + - BigInt (~> 5.2.0) + - CryptoSwift (~> 1.5.1) + - CGRPCZlibp (1.8.2) + - CNIOAtomics (2.40.0) + - CNIOBoringSSL (2.19.0) + - CNIOBoringSSLShims (2.19.0): + - CNIOBoringSSL (= 2.19.0) + - CNIODarwin (2.40.0) + - CNIOHTTPParser (2.40.0) + - CNIOLinux (2.40.0) + - CNIOWindows (2.40.0) + - CryptoSwift (1.5.1) + - DynamicBlurView (4.1.0) + - FCL-SDK (0.3.3): + - BloctoSDK/Flow (~> 0.5.0) + - SwiftyJSON + - FlowSDK (0.5.0): + - FlowSDK/FlowSDK (= 0.5.0) + - FlowSDK/FlowSDK (0.5.0): + - BigInt (~> 5.2.0) + - Cadence (~> 0.5.0) + - CryptoSwift (~> 1.5.1) + - gRPC-Swiftp (~> 1.8.2) + - secp256k1Swift (~> 0.7.4) + - gRPC-Swiftp (1.8.2): + - CGRPCZlibp (= 1.8.2) + - Logging (< 2.0.0, >= 1.4.0) + - SwiftNIO (< 3.0.0, >= 2.32.0) + - SwiftNIOExtras (< 2.0.0, >= 1.4.0) + - SwiftNIOHTTP2 (< 2.0.0, >= 1.18.2) + - SwiftNIOSSL (< 3.0.0, >= 2.14.0) + - SwiftNIOTransportServices (< 2.0.0, >= 1.11.1) + - SwiftProtobuf (< 2.0.0, >= 1.9.0) + - Logging (1.4.0) + - MercariQRScanner (1.9.0) + - PopupDialog (1.1.1): + - DynamicBlurView (~> 4.0) + - SDWebImage (5.12.5): + - SDWebImage/Core (= 5.12.5) + - SDWebImage/Core (5.12.5) + - secp256k1Swift (0.7.4): + - secp256k1Wrapper (~> 0.0.5) + - secp256k1Wrapper (0.0.5) + - SVProgressHUD (2.2.5) + - SwiftNIO (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOConcurrencyHelpers (2.40.0): + - CNIOAtomics (= 2.40.0) + - SwiftNIOCore (2.40.0): + - CNIOAtomics (= 2.40.0) + - CNIOLinux (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOEmbedded (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIOLinux (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOExtras (1.11.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOFoundationCompat (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOHPACK (1.22.0): + - _NIODataStructures (< 3, >= 2.35.0) + - CNIOAtomics (< 3, >= 2.35.0) + - CNIODarwin (< 3, >= 2.35.0) + - CNIOHTTPParser (< 3, >= 2.35.0) + - CNIOLinux (< 3, >= 2.35.0) + - CNIOWindows (< 3, >= 2.35.0) + - SwiftNIO (< 3, >= 2.35.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) + - SwiftNIOCore (< 3, >= 2.35.0) + - SwiftNIOEmbedded (< 3, >= 2.35.0) + - SwiftNIOHTTP1 (< 3, >= 2.35.0) + - SwiftNIOPosix (< 3, >= 2.35.0) + - SwiftNIOHTTP1 (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOHTTPParser (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOHTTP2 (1.22.0): + - _NIODataStructures (< 3, >= 2.35.0) + - CNIOAtomics (< 3, >= 2.35.0) + - CNIODarwin (< 3, >= 2.35.0) + - CNIOHTTPParser (< 3, >= 2.35.0) + - CNIOLinux (< 3, >= 2.35.0) + - CNIOWindows (< 3, >= 2.35.0) + - SwiftNIO (< 3, >= 2.35.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) + - SwiftNIOCore (< 3, >= 2.35.0) + - SwiftNIOEmbedded (< 3, >= 2.35.0) + - SwiftNIOHPACK (= 1.22.0) + - SwiftNIOHTTP1 (< 3, >= 2.35.0) + - SwiftNIOPosix (< 3, >= 2.35.0) + - SwiftNIOTLS (< 3, >= 2.35.0) + - SwiftNIOPosix (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOSSL (2.19.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIOBoringSSL (= 2.19.0) + - CNIOBoringSSLShims (= 2.19.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOTLS (< 3, >= 2.32.0) + - SwiftNIOTLS (2.40.0): + - _NIODataStructures (= 2.40.0) + - CNIOAtomics (= 2.40.0) + - CNIODarwin (= 2.40.0) + - CNIOLinux (= 2.40.0) + - CNIOWindows (= 2.40.0) + - SwiftNIO (= 2.40.0) + - SwiftNIOConcurrencyHelpers (= 2.40.0) + - SwiftNIOCore (= 2.40.0) + - SwiftNIOEmbedded (= 2.40.0) + - SwiftNIOPosix (= 2.40.0) + - SwiftNIOTransportServices (1.12.0): + - _NIODataStructures (< 3, >= 2.32.0) + - CNIOAtomics (< 3, >= 2.32.0) + - CNIODarwin (< 3, >= 2.32.0) + - CNIOLinux (< 3, >= 2.32.0) + - CNIOWindows (< 3, >= 2.32.0) + - SwiftNIO (< 3, >= 2.32.0) + - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) + - SwiftNIOCore (< 3, >= 2.32.0) + - SwiftNIOEmbedded (< 3, >= 2.32.0) + - SwiftNIOFoundationCompat (< 3, >= 2.32.0) + - SwiftNIOPosix (< 3, >= 2.32.0) + - SwiftNIOTLS (< 3, >= 2.32.0) + - SwiftProtobuf (1.20.3) + - SwiftyJSON (5.0.1) + +DEPENDENCIES: + - DynamicBlurView + - FCL-SDK (~> 0.3.3) + - MercariQRScanner + - PopupDialog (~> 1.1) + - SDWebImage (~> 5.0) + - SVProgressHUD + +SPEC REPOS: + trunk: + - _NIODataStructures + - BigInt + - BloctoSDK + - Cadence + - CGRPCZlibp + - CNIOAtomics + - CNIOBoringSSL + - CNIOBoringSSLShims + - CNIODarwin + - CNIOHTTPParser + - CNIOLinux + - CNIOWindows + - CryptoSwift + - DynamicBlurView + - FCL-SDK + - FlowSDK + - gRPC-Swiftp + - Logging + - MercariQRScanner + - PopupDialog + - SDWebImage + - secp256k1Swift + - secp256k1Wrapper + - SVProgressHUD + - SwiftNIO + - SwiftNIOConcurrencyHelpers + - SwiftNIOCore + - SwiftNIOEmbedded + - SwiftNIOExtras + - SwiftNIOFoundationCompat + - SwiftNIOHPACK + - SwiftNIOHTTP1 + - SwiftNIOHTTP2 + - SwiftNIOPosix + - SwiftNIOSSL + - SwiftNIOTLS + - SwiftNIOTransportServices + - SwiftProtobuf + - SwiftyJSON + +SPEC CHECKSUMS: + _NIODataStructures: 3d45d8e70a1d17a15b1dc59d102c63dbc0525ffd + BigInt: f668a80089607f521586bbe29513d708491ef2f7 + BloctoSDK: ee7b4dfe3fe249fb27254d42d6cdb3de4b268544 + Cadence: f354a678487ab17716acd61ddbb637130e9642b8 + CGRPCZlibp: 2f3e1e7a6d6cb481d4d1a26d3ec09aefacf09cbb + CNIOAtomics: 8edf08644e5e6fa0f021c239be9e8beb1cd9ef18 + CNIOBoringSSL: 2c9c96c2e95f15e83fb8d26b9738d939cc39ae33 + CNIOBoringSSLShims: c5c9346e7bbd1040f4f8793a35441dda7487539a + CNIODarwin: 93850990d29f2626b05306c6c9309f9be0d74c2f + CNIOHTTPParser: 8ce395236fa1d09ac3b4f4bcfba79b849b2ac684 + CNIOLinux: 62e3505f50de558c393dc2f273dde71dcce518da + CNIOWindows: 3047f2d8165848a3936a0a755fee27c6b5ee479b + CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 + DynamicBlurView: 58e18fae80bb614e34681a4486870e7d257b62e8 + FCL-SDK: 43fff0a39d8cf2981dee0f640482ea18fd9e4f05 + FlowSDK: 08c8b36cdc7b1c0d7017504592e8d13042e71bd0 + gRPC-Swiftp: 1f5a05ce5b544bff3dce93223e72829daac26113 + Logging: beeb016c9c80cf77042d62e83495816847ef108b + MercariQRScanner: e5aea873969af59b09b4cc411fc1c5b6293dba44 + PopupDialog: 720c92befd8bc23c13442254945213db5612f149 + SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e + secp256k1Swift: ea49d2b06724444a03cf7938a2d3fc7acc4c0f08 + secp256k1Wrapper: 0378417cd06d51187bbc9e178ec318e7902e2120 + SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 + SwiftNIO: 829958aab300642625091f82fc2f49cb7cf4ef24 + SwiftNIOConcurrencyHelpers: 697370136789b1074e4535eaae75cbd7f900370e + SwiftNIOCore: 473fdfe746534d7aa25766916459eeaf6f92ef49 + SwiftNIOEmbedded: ffcb5147db67d9686c8366b7f8427b36132f2c8a + SwiftNIOExtras: 481f74d6bf0b0ef699905ed66439cb019c4975c9 + SwiftNIOFoundationCompat: b9cdbea4806e4a12e9f66d9696fa3b98c4c3232b + SwiftNIOHPACK: e7d3ff5bd671528adfb11cd4e0c84ddfdc3c4453 + SwiftNIOHTTP1: ef56706550a1dc135ea69d65215b9941e643c23b + SwiftNIOHTTP2: cc81d7a6ba70d2ddc5376f471904b27ef5d2b7b8 + SwiftNIOPosix: b49af4bdbecaadfadd5c93dfe28594d6722b75e4 + SwiftNIOSSL: d153c5a6fc5b2301b0519b4c4d037a9414212da6 + SwiftNIOTLS: 598af547490133e9aac52aed0c23c4a90c31dcfc + SwiftNIOTransportServices: 0b2b407819d82eb63af558c5396e33c945759503 + SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 + SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e + +PODFILE CHECKSUM: 2ee197391bce94760f2e151ebb997bc78b137bd2 + +COCOAPODS: 1.11.2 diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/LICENSE b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/LICENSE new file mode 100644 index 00000000..771f65be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Mercari, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Bundle+Module.swift b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Bundle+Module.swift new file mode 100644 index 00000000..eb6f2653 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Bundle+Module.swift @@ -0,0 +1,16 @@ +// +// Bundle+Module.swift +// QRScanner +// +// Created by woxtu on 2020/11/22. +// + +import Foundation + +#if !SWIFT_PACKAGE +extension Bundle { + static var module: Bundle = { + return Bundle(for: QRScannerView.self) + }() +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/Contents.json b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/Contents.json b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/Contents.json new file mode 100644 index 00000000..a7b581c2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "scan_qr_focus.pdf", + "resizing" : { + "mode" : "9-part", + "center" : { + "mode" : "tile", + "width" : 1, + "height" : 1 + }, + "cap-insets" : { + "bottom" : 58, + "top" : 58, + "right" : 58, + "left" : 58 + } + } + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/scan_qr_focus.pdf b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/scan_qr_focus.pdf new file mode 100644 index 00000000..a63fbabd Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/Images.xcassets/scan_qr_focus.imageset/scan_qr_focus.pdf differ diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerError.swift b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerError.swift new file mode 100644 index 00000000..dcf91632 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerError.swift @@ -0,0 +1,24 @@ +// +// QRScannerError.swift +// QRScanner +// +// Created by wbi on 2019/10/16. +// Copyright © 2019 Mercari, Inc. All rights reserved. +// + +import Foundation +import AVFoundation + +public enum QRScannerError: Error { + case unauthorized(AVAuthorizationStatus) + case deviceFailure(DeviceError) + case readFailure + case unknown + + public enum DeviceError { + case videoUnavailable + case inputInvalid + case metadataOutputFailure + case videoDataOutputFailure + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerView.swift b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerView.swift new file mode 100644 index 00000000..098dce40 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/QRScanner/QRScannerView.swift @@ -0,0 +1,420 @@ +// +// QRScannerView.swift +// QRScanner +// +// Created by wbi on 2019/10/16. +// Copyright © 2019 Mercari, Inc. All rights reserved. +// + +import UIKit +import AVFoundation + +// MARK: - QRScannerViewDelegate +public protocol QRScannerViewDelegate: AnyObject { + // Required + func qrScannerView(_ qrScannerView: QRScannerView, didFailure error: QRScannerError) + func qrScannerView(_ qrScannerView: QRScannerView, didSuccess code: String) + // Optional + func qrScannerView(_ qrScannerView: QRScannerView, didChangeTorchActive isOn: Bool) +} + +public extension QRScannerViewDelegate { + func qrScannerView(_ qrScannerView: QRScannerView, didChangeTorchActive isOn: Bool) {} +} + +// MARK: - QRScannerView +@IBDesignable +public class QRScannerView: UIView { + + // MARK: - Input + public struct Input { + let focusImage: UIImage? + let focusImagePadding: CGFloat? + let animationDuration: Double? + let isBlurEffectEnabled: Bool? + + public static var `default`: Input { + return .init(focusImage: nil, focusImagePadding: nil, animationDuration: nil, isBlurEffectEnabled: nil) + } + + public init(focusImage: UIImage? = nil, focusImagePadding: CGFloat? = nil, animationDuration: Double? = nil, isBlurEffectEnabled: Bool? = nil) { + self.focusImage = focusImage + self.focusImagePadding = focusImagePadding + self.animationDuration = animationDuration + self.isBlurEffectEnabled = isBlurEffectEnabled + } + } + + // MARK: - Public Properties + @IBInspectable + public var focusImage: UIImage? + + @IBInspectable + public var focusImagePadding: CGFloat = 8.0 + + @IBInspectable + public var animationDuration: Double = 0.5 + + @IBInspectable + public var isBlurEffectEnabled: Bool = false + + // MARK: - Public + + public func configure(delegate: QRScannerViewDelegate, input: Input = .default) { + self.delegate = delegate + if let focusImage = input.focusImage { + self.focusImage = focusImage + } + if let focusImagePadding = input.focusImagePadding { + self.focusImagePadding = focusImagePadding + } + if let animationDuration = input.animationDuration { + self.animationDuration = animationDuration + } + if let isBlurEffectEnabled = input.isBlurEffectEnabled { + self.isBlurEffectEnabled = isBlurEffectEnabled + } + + configureSession() + addPreviewLayer() + setupBlurEffectView() + setupImageViews() + } + + public func startRunning() { + guard isAuthorized() else { return } + guard !session.isRunning else { return } + videoDataOutputEnable = false + metadataOutputEnable = true + metadataQueue.async { [weak self] in + self?.session.startRunning() + } + } + + public func stopRunning() { + guard session.isRunning else { return } + videoDataQueue.async { [weak self] in + self?.session.stopRunning() + } + metadataOutputEnable = false + videoDataOutputEnable = false + } + + public func rescan() { + guard isAuthorized() else { return } + if isBlurEffectEnabled { + blurEffectView.isHidden = true + } + focusImageView.removeFromSuperview() + qrCodeImageView.removeFromSuperview() + setupImageViews() + qrCodeImage = nil + videoDataOutputEnable = false + metadataOutputEnable = true + } + + public func setTorchActive(isOn: Bool) { + assert(Thread.isMainThread) + + guard let videoDevice = AVCaptureDevice.default(for: .video), + videoDevice.hasTorch, videoDevice.isTorchAvailable, + (metadataOutputEnable || videoDataOutputEnable) else { + return + } + try? videoDevice.lockForConfiguration() + videoDevice.torchMode = isOn ? .on : .off + videoDevice.unlockForConfiguration() + } + + deinit { + setTorchActive(isOn: false) + focusImageView.removeFromSuperview() + qrCodeImageView.removeFromSuperview() + session.inputs.forEach { session.removeInput($0) } + session.outputs.forEach { session.removeOutput($0) } + removePreviewLayer() + torchActiveObservation = nil + } + + // MARK: - Private + + private weak var delegate: QRScannerViewDelegate? + private let metadataQueue = DispatchQueue(label: "metadata.session.qrreader.queue") + private let videoDataQueue = DispatchQueue(label: "videoData.session.qrreader.queue") + private let session = AVCaptureSession() + private var previewLayer: AVCaptureVideoPreviewLayer? + private var focusImageView = UIImageView() + private var qrCodeImageView = UIImageView() + private var metadataOutput = AVCaptureMetadataOutput() + private var videoDataOutput = AVCaptureVideoDataOutput() + private var metadataOutputEnable = false + private var videoDataOutputEnable = false + private var torchActiveObservation: NSKeyValueObservation? + private var qrCodeImage: UIImage? + private lazy var blurEffectView: UIVisualEffectView = { + let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light)) + blurEffectView.frame = self.bounds + blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + return blurEffectView + }() + + private enum AuthorizationStatus { + case authorized, notDetermined, restrictedOrDenied + } + + private func isAuthorized() -> Bool { + return authorizationStatus() == .authorized + } + + private func authorizationStatus() -> AuthorizationStatus { + switch AVCaptureDevice.authorizationStatus(for: .video) { + case .authorized: + return .authorized + case .notDetermined: + failure(.unauthorized(.notDetermined)) + return .notDetermined + case .denied: + failure(.unauthorized(.denied)) + return .restrictedOrDenied + case .restricted: + failure(.unauthorized(.restricted)) + return .restrictedOrDenied + @unknown default: + return .restrictedOrDenied + } + } + + private func configureSession() { + // check device initialize + guard let videoDevice = AVCaptureDevice.default(for: .video) else { + failure(.deviceFailure(.videoUnavailable)) + return + } + + // check input + guard let videoInput = try? AVCaptureDeviceInput(device: videoDevice), session.canAddInput(videoInput) else { + failure(.deviceFailure(.inputInvalid)) + return + } + + // check metadata output + guard session.canAddOutput(metadataOutput) else { + failure(.deviceFailure(.metadataOutputFailure)) + return + } + + // check videoData output + guard session.canAddOutput(videoDataOutput) else { + failure(.deviceFailure(.videoDataOutputFailure)) + return + } + + // commit session + session.beginConfiguration() + session.addInput(videoInput) + metadataOutput.setMetadataObjectsDelegate(self, queue: metadataQueue) + session.addOutput(metadataOutput) + metadataOutput.metadataObjectTypes = [.qr] + + videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA] + videoDataOutput.setSampleBufferDelegate(self, queue: videoDataQueue) + session.addOutput(videoDataOutput) + + session.commitConfiguration() + + // torch observation + if videoDevice.hasTorch { + torchActiveObservation = videoDevice.observe(\.isTorchActive, options: .new) { [weak self] _, change in + self?.didChangeTorchActive(isOn: change.newValue ?? false) + } + } + + // start running + if authorizationStatus() == .notDetermined { + videoDataOutputEnable = false + metadataOutputEnable = true + metadataQueue.async { [weak self] in + self?.session.startRunning() + } + } + } + + private func setupBlurEffectView() { + guard isBlurEffectEnabled else { return } + blurEffectView.isHidden = true + addSubview(blurEffectView) + } + + private func setupImageViews() { + let width = self.bounds.width * 0.618 + let x = self.bounds.width * 0.191 + let y = self.bounds.height * 0.191 + focusImageView = UIImageView(frame: CGRect(x: x, y: y, width: width, height: width)) + focusImageView.image = focusImage ?? UIImage(named: "scan_qr_focus", in: .module, compatibleWith: nil) + addSubview(focusImageView) + + qrCodeImageView = UIImageView() + qrCodeImageView.contentMode = .scaleAspectFill + addSubview(qrCodeImageView) + } + + private func addPreviewLayer() { + let previewLayer = AVCaptureVideoPreviewLayer(session: session) + previewLayer.videoGravity = .resizeAspectFill + previewLayer.frame = self.bounds + layer.addSublayer(previewLayer) + + self.previewLayer = previewLayer + } + + private func removePreviewLayer() { + previewLayer?.removeFromSuperlayer() + } + + private func moveImageViews(qrCode: String, corners: [CGPoint]) { + assert(Thread.isMainThread) + + let path = UIBezierPath() + path.move(to: corners[0]) + corners[1.. maxSide ? side : maxSide + } + maxSide += focusImagePadding * 2 + + UIView.animate(withDuration: animationDuration, animations: { [weak self] in + guard let strongSelf = self else { return } + strongSelf.focusImageView.frame = path.bounds + let center = strongSelf.focusImageView.center + strongSelf.focusImageView.frame.size = CGSize(width: maxSide, height: maxSide) + strongSelf.focusImageView.center = center + strongSelf.focusImageView.transform = CGAffineTransform.identity.rotated(by: degrees) + + strongSelf.qrCodeImageView.frame = path.bounds + strongSelf.qrCodeImageView.center = center + }, completion: { [weak self] _ in + guard let strongSelf = self else { return } + strongSelf.qrCodeImageView.image = strongSelf.qrCodeImage + if strongSelf.isBlurEffectEnabled { + strongSelf.blurEffectView.isHidden = false + } + strongSelf.success(qrCode) + }) + } + + private func failure(_ error: QRScannerError) { + delegate?.qrScannerView(self, didFailure: error) + } + + private func success(_ code: String) { + delegate?.qrScannerView(self, didSuccess: code) + } + + private func didChangeTorchActive(isOn: Bool) { + delegate?.qrScannerView(self, didChangeTorchActive: isOn) + } +} + +// MARK: - AVCaptureMetadataOutputObjectsDelegate + +extension QRScannerView: AVCaptureMetadataOutputObjectsDelegate { + public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { + guard metadataOutputEnable else { return } + if let metadataObject = metadataObjects.first { + guard let readableObject = previewLayer?.transformedMetadataObject(for: metadataObject) as? AVMetadataMachineReadableCodeObject, metadataObject.type == .qr else { return } + guard let stringValue = readableObject.stringValue else { return } + metadataOutputEnable = false + videoDataOutputEnable = true + + DispatchQueue.main.async { [weak self] in + guard let strongSelf = self else { return } + strongSelf.setTorchActive(isOn: false) + strongSelf.moveImageViews(qrCode: stringValue, corners: readableObject.corners) + } + } + } +} + +// MARK: - AVCaptureVideoDataOutputSampleBufferDelegate + +extension QRScannerView: AVCaptureVideoDataOutputSampleBufferDelegate { + public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { + connection.videoOrientation = .portrait + guard videoDataOutputEnable else { return } + guard let qrCodeImage = getImageFromSampleBuffer(sampleBuffer: sampleBuffer) else { return } + + self.qrCodeImage = qrCodeImage + videoDataOutputEnable = false + } + + private func getImageFromSampleBuffer(sampleBuffer: CMSampleBuffer) -> UIImage? { + let scale = UIScreen.main.scale + guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil } + CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly) + let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer) + let width = CVPixelBufferGetWidth(pixelBuffer) + let height = CVPixelBufferGetHeight(pixelBuffer) + let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer) + let colorSpace = CGColorSpaceCreateDeviceRGB() + let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue) + guard let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else { return nil } + guard let cgImage = context.makeImage() else { return nil } + + let sampleBuffer = UIImage(cgImage: cgImage, scale: scale, orientation: .up) + CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly) + + return readQRCode(sampleBuffer) + } + + private func readQRCode(_ image: UIImage) -> UIImage? { + guard let ciImage = CIImage(image: image) else { return nil } + let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]) + guard let features = detector?.features(in: ciImage) else { return nil } + guard let feature = features.first as? CIQRCodeFeature else { return nil } + + let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -ciImage.extent.size.height) + let path = UIBezierPath() + path.move(to: feature.topLeft.applying(transform)) + path.addLine(to: feature.topRight.applying(transform)) + path.addLine(to: feature.bottomRight.applying(transform)) + path.addLine(to: feature.bottomLeft.applying(transform)) + path.close() + return image.crop(path) + } +} + +private extension UIImage { + func crop(_ path: UIBezierPath) -> UIImage? { + let rect = CGRect(origin: CGPoint(), size: CGSize(width: size.width * scale, height: size.height * scale)) + UIGraphicsBeginImageContextWithOptions(rect.size, false, scale) + + UIColor.clear.setFill() + UIRectFill(rect) + path.addClip() + draw(in: rect) + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + guard let croppedImage = image?.cgImage?.cropping(to: CGRect(x: path.bounds.origin.x * scale, y: path.bounds.origin.y * scale, width: path.bounds.size.width * scale, height: path.bounds.size.height * scale)) else { return nil } + return UIImage(cgImage: croppedImage, scale: scale, orientation: imageOrientation) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/README.md b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/README.md new file mode 100644 index 00000000..b2eddf66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/MercariQRScanner/README.md @@ -0,0 +1,192 @@ +# QRScanner +A simple QR Code scanner framework for iOS. Provides a similar scan effect to ios13+. Written in Swift. + +* [日本語のブログ](https://tech.mercari.com/entry/2019/12/12/094129) + +|iOS 13.0+| Use QRScanner in iOS 10.0+| +|-|-| +||| + +"QR Code" is a registered trademark of DENSO WAVE INCORPORATED + +## Feature +- Similar to iOS 13.0+ design +- Simple usage Sample +- Support from iOS 10.0+ + +## Development Requirements +- iOS 10.0+ +- Swift: 5.4.2 +- Xcode Version: 13.0 + +## Installation +CocoaPods is the recommended method of installing QRScanner. + +### The Pod Way + +- Simply add the following line to your Podfile +```ruby + platform :ios, '10.0' + pod 'MercariQRScanner' +``` + +- Run command +``` + pod install +``` +- Write Import statement on your source file +```swift + import MercariQRScanner +``` + +### The Carthage Way + +- Move your project dir and create Cartfile +``` +> touch Cartfile +``` +- add the following line to Cartfile +``` +github "mercari/QRScanner" +``` +- Create framework +``` +> carthage update --platform iOS +``` + +- In Xcode, move to "General > Build Phase > Linked Frameworks and Libraries" +- Add the framework to your project +- Add a new run script and put the following code +``` +/usr/local/bin/carthage copy-frameworks +``` +- Click "+" at Input file and Add the framework path +``` +$(SRCROOT)/Carthage/Build/iOS/QRScanner.framework +``` ++ Write Import statement on your source file +```swift +import QRScanner +``` + +## Usage + +See [QRScannerSample](https://github.com/mercari/QRScanner/tree/master/QRScannerSample) + +### Add `Privacy - Camera Usage Description` to Info.plist file + + + +### The Basis Of Usage + +```swift +import QRScanner +// If use the Pod way, please import MercariQRScanner + +final class ViewController: UIViewController { + override func viewDidLoad() { + super.viewDidLoad() + + let qrScannerView = QRScannerView(frame: view.bounds) + view.addSubview(qrScannerView) + qrScannerView.configure(delegate: self) + qrScannerView.startRunning() + } +} + +extension ViewController: QRScannerViewDelegate { + func qrScannerView(_ qrScannerView: QRScannerView, didFailure error: QRScannerError) { + print(error) + } + + func qrScannerView(_ qrScannerView: QRScannerView, didSuccess code: String) { + print(code) + } +} +``` + +### Customization + +#### Source Code Way + +```swift +override func viewDidLoad() { + super.viewDidLoad() + + let qrScannerView = QRScannerView(frame: view.bounds) + + // Customize focusImage, focusImagePadding, animationDuration + qrScannerView.focusImage = UIImage(named: "scan_qr_focus") + qrScannerView.focusImagePadding = 8.0 + qrScannerView.animationDuration = 0.5 + + qrScannerView.configure(delegate: self) + view.addSubview(qrScannerView) + qrScannerView.startRunning() +} +``` + +#### Interface Builder Way + +|Setup Custom Class|Customize| +|-|-| +||| + +### Add FlashButton + +[FlashButtonSample](https://github.com/mercari/QRScanner/blob/master/QRScannerSample/QRScannerSample/FlashButton.swift) + +```swift +final class ViewController: UIViewController { + + ... + + @IBOutlet var flashButton: FlashButton! + + @IBAction func tapFlashButton(_ sender: UIButton) { + qrScannerView.setTorchActive(isOn: !sender.isSelected) + } +} + +extension ViewController: QRScannerViewDelegate { + + ... + + func qrScannerView(_ qrScannerView: QRScannerView, didChangeTorchActive isOn: Bool) { + flashButton.isSelected = isOn + } +} +``` + +### Add Blur Effect + +#### Source Code Way + +```swift + qrScannerView.configure(delegate: self, input: .init(isBlurEffectEnabled: true)) +``` + +#### Interface Builder Way + +|Customize| +|-| +|| + +## Committers + +* Hitsu ([@hitsubunnu](https://github.com/hitsubunnu)) +* Sonny ([@tedbrosby](https://github.com/tedbrosby)) +* Daichiro ([@daichiro](https://github.com/daichiro)) + +## Contribution + +Please read the CLA carefully before submitting your contribution to Mercari. +Under any circumstances, by submitting your contribution, you are deemed to accept and agree to be bound by the terms and conditions of the CLA. + +https://www.mercari.com/cla/ + +## License + +Copyright 2019 Mercari, Inc. + +Licensed under the MIT License. diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/project.pbxproj b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 00000000..2f99bf18 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,16728 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 00304FEED98F36BA2B4E6138E2901DBF /* AsyncWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EE3F46D7411B71D83FAAD008A2E82D5 /* AsyncWriter.swift */; }; + 003CD5283BC9087FEF973075302763DD /* Role.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6A8AA637C75BC871D1086059116087 /* Role.swift */; }; + 007F57C0030B0CA201A359FD816A3CE1 /* SDImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E4FBE2249766692D9DCD326AD210E0 /* SDImageFrame.m */; }; + 00925F03DED82E0317508AFC81FAE9E2 /* CNIOHTTPParser-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A3B24D4DB3060A69D9A18858B51BD36 /* CNIOHTTPParser-dummy.m */; }; + 00A70E59F0BDDD533B3BE0D5329ADC57 /* v3_pmaps.c in Sources */ = {isa = PBXBuildFile; fileRef = CDA93E44ACEA49D047A8B0DFCED8CFEB /* v3_pmaps.c */; }; + 00C22009B3BEB45AE5A45805DEDCC316 /* Words and Bits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86255070A3CCAF2DCDB9ECE5391A5F6A /* Words and Bits.swift */; }; + 00C59A57D810B34C978A10E9AF859B59 /* CNIOBoringSSL_nid.h in Headers */ = {isa = PBXBuildFile; fileRef = AA22FB13720A6412E5E086ED932D06D8 /* CNIOBoringSSL_nid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 01066162D71B72A3740B57DF11239E18 /* ReceivingRstStreamState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DE16D46D4E1C5A7996BCCFF955DE5F /* ReceivingRstStreamState.swift */; }; + 0111A299C84506713936964EA9964A81 /* ServerHandlerStateMachine+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08DF434C8C2F95CD2F212947799075BA /* ServerHandlerStateMachine+Actions.swift */; }; + 014D64642F0747A1F91169F1EA385F55 /* timestamp.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA57072C8406D072532BC8C000A532B1 /* timestamp.pb.swift */; }; + 014E6A106AA72977A9B23E50F1040CCD /* sha512-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 0E725B039DDE85D72BAF12B4A4CFB2F3 /* sha512-586.linux.x86.S */; }; + 018689E8C966BB153C0315D1BB756FEC /* pem_xaux.c in Sources */ = {isa = PBXBuildFile; fileRef = D6397A1E765ACDAE82BB631C5DCBB30F /* pem_xaux.c */; }; + 0194017B139DB8873A9ADFF6B144FC5A /* blinding.c in Sources */ = {isa = PBXBuildFile; fileRef = 7974CE5CD2CD502F04009B9D88D533C7 /* blinding.c */; }; + 01B74DCA125ECE14E3A51EFEB874D672 /* prime.c in Sources */ = {isa = PBXBuildFile; fileRef = FDC3DE34332A925ED7AF74B4A48270C8 /* prime.c */; }; + 01CFAEF83800A868D12203969713532D /* BloctoSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = F02D804318B912DB80C817AC1499A081 /* BloctoSDK.swift */; }; + 0277BF84EAE1AF2C8A1EC9DD21E623F5 /* WireFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0721EF9A72F01319DB08771946208C /* WireFormat.swift */; }; + 0297DE6077A06ECB90B5018547573403 /* TransactionSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91DA5E04F67C81D9A610BFDE1B7E6A81 /* TransactionSignature.swift */; }; + 029CDC517DECF5D8316C2D20AD9058E0 /* ssl_session.cc in Sources */ = {isa = PBXBuildFile; fileRef = B676A8CC6D7A55B9F2330EFF0F439AE6 /* ssl_session.cc */; }; + 02A34F86694B6E68BE8417E55FA53F30 /* NonBlockingFileIO.swift in Sources */ = {isa = PBXBuildFile; fileRef = F372FE0BD8E79C0C954CD7368DD56E4B /* NonBlockingFileIO.swift */; }; + 0300545CAC1E40D94149E4A311BE5F3F /* ecdh.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A8344CF6C33D499F30836C9EBCE1F20 /* ecdh.c */; }; + 030A3E51B9E56CD6146F186166ED4FFC /* GRPCStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69DE0F1E76B17106976985E62F2E7132 /* GRPCStatus.swift */; }; + 0311D5903A8C13AE6158796BC69AD994 /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 100736BBAE33F97D2D4BA48AF254EC25 /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0327B97220F858FE9F756549296DBDD3 /* UnaryResponseCallContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC4AE025180D60650876592B1B3B7C0 /* UnaryResponseCallContext.swift */; }; + 034ECEA0E580CDD41D6B5934B1EE6714 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4750AA11686A2E12D6E8A31809AA2D2 /* Error.swift */; }; + 035327CF4C657115EE5A64D2A6408C90 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 035E1DAAB190ECE75BBC3C2C01A2C7F5 /* ServerCallContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 206D595DA6D868D7DB345D772286138A /* ServerCallContext.swift */; }; + 0394719E7095CB053C04F4B407452073 /* field_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 31DA3AB6DBAC8E44A9983629C3A978AA /* field_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0395305AF97DA05D29CFE7B9A4A17B4D /* a_i2d_fp.c in Sources */ = {isa = PBXBuildFile; fileRef = D448E72582B6BAAF2BBA7D9FA5189644 /* a_i2d_fp.c */; }; + 03B6705143E65EC1723C9A10FE9FEEE8 /* CallDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11603B9D360BC58772C329CF91BEC74 /* CallDetails.swift */; }; + 03D441DB166EF3C3438A7B49CBE8B02F /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D236FDEF838701B1E66DFFA97F02D4E /* Data+Extensions.swift */; }; + 04190E7039B3265AD22AE6CB4789EAD6 /* NIOTSChannelOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF99873D68B73F324125054CD5617835 /* NIOTSChannelOptions.swift */; }; + 04471B662ED2959F6D46382162B6001C /* ex_data.c in Sources */ = {isa = PBXBuildFile; fileRef = FF2320961936E59CBDAB2EBF11A7B62A /* ex_data.c */; }; + 04692774557F353CAD0317AE56854CDC /* digests.c in Sources */ = {isa = PBXBuildFile; fileRef = BBAC339BE80C1C4E2E9507BC75AA64C7 /* digests.c */; }; + 0469464887CD5DF06E189FAB225F2D24 /* TransactionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F8A9FFAD9DD5E2DCC1B6D55F8B31A4 /* TransactionResult.swift */; }; + 046FBC08EC8BAFFAB07821A38567E912 /* cipher_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = 580E2EBBFE458EC3F736133677BAFD9E /* cipher_extra.c */; }; + 0503B9C4E26816ADE8FF091792BF5CF3 /* Stopwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFF32C7F2CEA1A995EFBFA1B389B1C /* Stopwatch.swift */; }; + 05102BD9E7BCB80DC7B64A34D0E7850B /* SDWebImageCacheSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DFA6D41A16145F4392BBA40705024CF /* SDWebImageCacheSerializer.m */; }; + 05399C35827DEE4DD35A9DD254645202 /* PopupDialog-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 302CF87E639FCD36334254EC25AE99C0 /* PopupDialog-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 05D76FA82DD3C37B76FFC1689CEF9981 /* SDWebImageDownloaderDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 330EB56430E880E789BE7DFB1E461C89 /* SDWebImageDownloaderDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 05D96EEA3633D34242E9FC7D523CF2BE /* MessageEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FEBC0C81CE82A09BDEA8BE8310B2E26 /* MessageEncoding.swift */; }; + 05DEFF4F666F29206344595D025DAE7E /* secp256k1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D20EC911C9371E4FFA011F5DD1D64A1 /* secp256k1.swift */; }; + 05EECD90A450385DF1A7E41D85AC6AA4 /* MarkedCircularBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1535AA5F7C7E64787C97A332A65291 /* MarkedCircularBuffer.swift */; }; + 05F2AE75BFE10AC23A1F3F251F86522B /* fips.c in Sources */ = {isa = PBXBuildFile; fileRef = CAF3612E50BAAE6C2D6EC831E700F9FF /* fips.c */; }; + 05FD6418BFC3AE594DFB95895A1F19D1 /* tls_cbc.c in Sources */ = {isa = PBXBuildFile; fileRef = EA2A0AF3A809B6D227FAF4440D16DA91 /* tls_cbc.c */; }; + 061F08E035EF8433CE03F9D596BAD2EB /* dh.c in Sources */ = {isa = PBXBuildFile; fileRef = 0480F69F7241973DEDB98B22253663AC /* dh.c */; }; + 06671B662E667EAF88B20FCDFE2FE470 /* Voucher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962796D624989567A469AD221C8F317C /* Voucher.swift */; }; + 066C1275C946EF3694CF437FAA0B846E /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE18D266883CE29CF57E950BD8D8EE4C /* UInt128.swift */; }; + 067A89333F31F0163B435AB2DE985AEE /* Message+TextFormatAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54947049A58743A0C0042261F0E344B4 /* Message+TextFormatAdditions.swift */; }; + 06C85607640345D6A2C1CD13C2D514E1 /* p256-nistz.h in Headers */ = {isa = PBXBuildFile; fileRef = AFB519F2A9DF09C595E0186FDD032F11 /* p256-nistz.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 06CA44ED2A1053488482695266BAB93C /* LineBasedFrameDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488502B49EA245C5DF9A028AEA0D53B9 /* LineBasedFrameDecoder.swift */; }; + 06D80670E698BEE870B774E42917971D /* HTTP2PipelineHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D27B54D304A4F4AFCE4E3D33461AF5 /* HTTP2PipelineHelpers.swift */; }; + 0749EE058FE13B1F5B867BB03750B182 /* QRScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46260190555EDA809052AAFE11384B6A /* QRScannerView.swift */; }; + 07A41F67B40B3C6C6C3DB862F1F633F8 /* SDWebImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 72F0CF78FE96B9FA56CB5EAED86E907E /* SDWebImageManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 07B239EA1B4D958AEA1EEB420A76EB74 /* NIOTSEventLoopGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF0443455AE135021E6621A85C3D07 /* NIOTSEventLoopGroup.swift */; }; + 07BE74CA6DD87E9C114CC07B87A25692 /* rdrand-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C571B78A8486423E82B83B20305F2 /* rdrand-x86_64.mac.x86_64.S */; }; + 088AC8FD840686DBA147906488874B97 /* QueryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA59255F85D49A61ECB56ADD71721B9 /* QueryItem.swift */; }; + 08A18E6BD351CD781F9B2ADF46D06489 /* CNIOWindows.h in Headers */ = {isa = PBXBuildFile; fileRef = 94C03FF593B078886C1EE15A3B66FDF9 /* CNIOWindows.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 08A2249E3B535AC87503E0C8AD5EA581 /* sha512-armv4.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 79C25710B55D85F3562DDF354FA4D589 /* sha512-armv4.linux.arm.S */; }; + 08B9F65055E30C44AC9BBFAA2EE60AAB /* ghashv8-armx64.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 3ED5C868056584A2804EBA59AC1F8DB5 /* ghashv8-armx64.ios.aarch64.S */; }; + 08C84826FDC140A6A0AE9E7A3D6E61D2 /* CNIOBoringSSL_base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 62EC0F8FA6CDAD507979070A6DDC9CA9 /* CNIOBoringSSL_base64.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 08DD40693867A231B7A4E72C1BEB2BBF /* LinuxCABundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E895D3C198F54C3672CFF97EC77D18E4 /* LinuxCABundle.swift */; }; + 08F2001DC9F97027A943FB9CB3E90C5A /* CNIOBoringSSL_bn.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FF09A62EB2C949481BE3164B7FD35AE /* CNIOBoringSSL_bn.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0907B00794FCDF0A327BB1F58BA6ABC9 /* NIOHTTPClientUpgradeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6824E58803648F18F7ED3C2F1AACB45 /* NIOHTTPClientUpgradeHandler.swift */; }; + 092350853F2356C1D0C80789E14ACD3D /* InterceptorContextList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E6121ABD5731EAD67AF31B2156D245 /* InterceptorContextList.swift */; }; + 093150C571E73CAEF7AE687055B5EAC3 /* DoubleParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F497C9CF344483D772A5E2788BBF4BB1 /* DoubleParser.swift */; }; + 097F302ACF6C4556451C8555F57EF9DD /* mem.c in Sources */ = {isa = PBXBuildFile; fileRef = D5B4F82B8EEFF961A5F7EC682B610977 /* mem.c */; }; + 0A11D1FE33D116D3EBACF8D8CE07C7FB /* CNIOBoringSSL_evp.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B68FE07B21CC522B358D579282D30E /* CNIOBoringSSL_evp.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0A1E9D524309EC4E97C5631075641265 /* handshake_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 933FDBA513463FAC642AF22F11B680FC /* handshake_client.cc */; }; + 0A733A02A2F7047FC928576907A8E855 /* any.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CCC7587DA96C8EEF14833B955B0338 /* any.pb.swift */; }; + 0AAD61818F040DD52199FE3D1F6887E4 /* a_mbstr.c in Sources */ = {isa = PBXBuildFile; fileRef = 3750323885EC02B225F7E44D305723D4 /* a_mbstr.c */; }; + 0AF0B58C7A9F95CF47D0BB6FB75F6FF2 /* ghashv8-armx64.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 0624CB03F399E0666C965D9203090649 /* ghashv8-armx64.linux.aarch64.S */; }; + 0B09E5BF60E1F7034257A75BB42B1992 /* shim.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F281A4AA01935FE92D665AE9536B1 /* shim.c */; }; + 0B3AECF339BD39C50E6CDEE4BDC1BD6D /* ServerInterceptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D0CE134117056C9057B4DAFC24094EE /* ServerInterceptors.swift */; }; + 0B4E22B49079B4F4FA584C02310CC9EA /* BaseSocketChannel+SocketOptionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D030D5F8B3618F444E710AF1876E44 /* BaseSocketChannel+SocketOptionProvider.swift */; }; + 0BB2AD0D4B310F116340828E1E7E2B9B /* x_x509a.c in Sources */ = {isa = PBXBuildFile; fileRef = 52A707EE42FC57DC14D5F7A673496EFF /* x_x509a.c */; }; + 0BF9362C02368CBE135D13C89EC81632 /* shift.c in Sources */ = {isa = PBXBuildFile; fileRef = FC26EDDD6735D27600FA0D17B85868CB /* shift.c */; }; + 0BFA90EFCD3407716FFC60D140325188 /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D9C4B53AD56E6599FB7C338C7BD65F8 /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0C070928EEECA1314011AEEE3C11F813 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 28A8B8911F41C0B29674DD930FA0C2E8 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C453F0CBBFD3329A488F0EF6DFDD488 /* PoolManagerStateMachine+PerPoolState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17F7618D35EB1C624B284E6674556704 /* PoolManagerStateMachine+PerPoolState.swift */; }; + 0C51A757DDC20B436F410BFF1263CAD6 /* CNIOBoringSSL_type_check.h in Headers */ = {isa = PBXBuildFile; fileRef = F1474C32BD49331333311B100CE80555 /* CNIOBoringSSL_type_check.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0C76BA74E22A5CFD8207C10026401D80 /* SDAnimatedImagePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 71BFE46CDEE212C2D554D40D5FF5E7F6 /* SDAnimatedImagePlayer.m */; }; + 0C82E543EF035DB9C066DC60C5D3B612 /* InboundWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 875643C3A2B0BB94A8A34FB1C7FCA178 /* InboundWindowManager.swift */; }; + 0CC8665704F6A8B01419FE6216253EE5 /* a_d2i_fp.c in Sources */ = {isa = PBXBuildFile; fileRef = 85BCB5DB1810B32E458CFF66D5D5B0B1 /* a_d2i_fp.c */; }; + 0CE9A2762524F23D61F497FD9A621F08 /* GRPCStatusMessageMarshaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B97E78A3E74437B8A21A71DCF55F9849 /* GRPCStatusMessageMarshaller.swift */; }; + 0CF5F5807C5CD694BC8A5C774175F223 /* URLOpening.swift in Sources */ = {isa = PBXBuildFile; fileRef = 746F91594C1C6B55A7F67979D2257F75 /* URLOpening.swift */; }; + 0D0AF4DF934B7BE39EC6E287B003BBA6 /* SDMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DCDD34AB556F1F49D46C07F5D1439A3 /* SDMemoryCache.m */; }; + 0D2B3D451D64A5A0AE5CE51E975D7494 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 806FE446300C5A6F475BE596A8C09F8E /* SDImageCache.m */; }; + 0D3D74E87637764C70C18C2DA1BD29EE /* UnknownStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B04B2811394A6178E69DA925AC1C9B /* UnknownStorage.swift */; }; + 0D60294A7BB35B73E960580B064D3CA9 /* CNIOHTTPParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EEF1A795EC83D9C06CA29B76F0DCA23 /* CNIOHTTPParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0D78165F93D407AEA77E1DDA94C8C59C /* CNIOBoringSSL_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5139FFF6FF1ED7F082529C640B4062 /* CNIOBoringSSL_buf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0DA1F39FF87097B001CA65CFF4063698 /* evp.c in Sources */ = {isa = PBXBuildFile; fileRef = F6B770EF99C3415FE53DCA48B48F61E1 /* evp.c */; }; + 0DC201DB13FFBABC695B3D93C4A4C9CA /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634AC0A70874A63C45F2B35E58DB4BDC /* Channel.swift */; }; + 0DD6B5B1DF81A4CF957BA08365244124 /* GCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = E136AD5881B92E5F3FE8944DD75F0AB2 /* GCM.swift */; }; + 0DEECB4887F8ED8A8304156D1C440639 /* SDWebImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C63AF0C7583CF8E8E56FA5E6C476BC3F /* SDWebImage-dummy.m */; }; + 0DFA9A7F143EEC14262713FDA3C0D379 /* vpaes-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = EC4117C89342DC6DB6591EEE2778D12A /* vpaes-armv8.ios.aarch64.S */; }; + 0E08DD80DD1102D9AA553B648A2F22C6 /* p_rsa_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = CCA5BEBB9543CB4D3616D04BAE558155 /* p_rsa_asn1.c */; }; + 0E297F64DD9BC7C8FE04C1EC2DA878A1 /* DH.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CA5BCBA60A0D0F4C9BB59488542BFB6 /* DH.swift */; }; + 0E498B0426DC585532962A1D1F0F9C13 /* ServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69F18166D6FA989A07C1BF2EDE3CD089 /* ServiceType.swift */; }; + 0E96C98EB2D7F8E410F48E943F490EA6 /* ConnectivityState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C637AFE0F17CD6E5434C0F35F7A9AB49 /* ConnectivityState.swift */; }; + 0E984D6070F467D3EA99D4F466A6B55A /* Ref.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC6F0F2EF3F899754774C80358CFB92 /* Ref.swift */; }; + 0EA40F31474C855AA31F2243B616CB2D /* _NIODataStructures-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 439C7DAD9370D19499787E98149B6764 /* _NIODataStructures-dummy.m */; }; + 0EFCF636B9B5A32F7267C1A7030C694F /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A26A6109C860BF91A1D978645558CC2 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F22961374191F222242FC1F430FDB35 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCD6C11BF1A8D3DE74A721E78D0D3E /* Operators.swift */; }; + 0F31EC3D670E860E870C1E9F0AFB8870 /* p_ed25519_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = F3DD926E581AA883A2946241C603809A /* p_ed25519_asn1.c */; }; + 0F4322740A001E3D7BFD2C333BCF907D /* SDImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D3750C70FE753271823ACC07BA2AF57 /* SDImageCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0F780014CD531EA8866B5D36EC30BA63 /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211122AEEB526BA62B5F07B93EE9D19E /* DigestType.swift */; }; + 0FC7A9F8C69F1C0912FA4D1ABF53F919 /* time_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 6B0606176305FD0DDFCA2EFCE02CBE4C /* time_support.c */; }; + 0FE49E3D3126E4B6FE4368B964522B90 /* WebCORSHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD63A32D56755A4FA3D94486B21B69A0 /* WebCORSHandler.swift */; }; + 0FFA0C960F26666918569059FB8E92BC /* SDImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D40E5DCB25DDB72596D326CE4ED62102 /* SDImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1021F6D66CA4651E16E3D045BBA68EFA /* secp256k1Wrapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FF3C424009C0D93BF5CE0E36B2C00792 /* secp256k1Wrapper-dummy.m */; }; + 106C2369F8AD4D75E89177FF097F5F33 /* Google_Protobuf_Struct+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40E3A228B04F1C4382F68906F3F17B0D /* Google_Protobuf_Struct+Extensions.swift */; }; + 10D2F03A26A5904844445590664908BC /* NIOTSListenerChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A4B92D3375D3A69A261B2924123569 /* NIOTSListenerChannel.swift */; }; + 10D52373AC94CCF8D89E7C8D9B176206 /* ClientCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6F5E6ABD294A9AC1D6C2C7B56EEF23 /* ClientCall.swift */; }; + 10E9E4249C8C22A571EBFECF3C0676CC /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = A6AF4990B009B43367303C0DCA03D676 /* UIImageView+WebCache.m */; }; + 10EE7669F20D37F8576CB7B68DD21D1A /* x86_64-mont.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1074E48131DD1AE2A57E6DB16C89FEDB /* x86_64-mont.mac.x86_64.S */; }; + 10FA40334A22E567295DE81B8AE79415 /* DecompressionLimit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D58A6E75C6E7F360A35D31ED3E1962 /* DecompressionLimit.swift */; }; + 11281D1803D4FF95259EA1860F54E518 /* sha1-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 9749E5B1C62EFA9B15CB3B561D4A3F43 /* sha1-586.linux.x86.S */; }; + 1132612F1CBE48D6AFFFE14FF52DAB5E /* a_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 99B7B5C6C7132BC4AE13670C71B1D319 /* a_int.c */; }; + 11CE36975066F85CE305DAE06309A544 /* GRPCAsyncRequestStreamWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A7ECDE3312ABF35B64E9CE0D610FA1 /* GRPCAsyncRequestStreamWriter.swift */; }; + 11E79385CD0DA86166E63D21E7E078E9 /* SDImageIOAnimatedCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AA7887399F147D38C74BE47F5DCC78E /* SDImageIOAnimatedCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 11F5FAC519308BE1E08776FF82736BD2 /* UnsafeBufferPointer+Shims.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843DC486B3962999E5D2EB6FD72C1F70 /* UnsafeBufferPointer+Shims.swift */; }; + 11F7B3AD8780B2A65994FDF2C9E9F28A /* EdDSA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E542CFBA98D0309857132E3BBABDB1 /* EdDSA.swift */; }; + 12464BB4762BAEB0E983C174976CFCC4 /* AuthData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 489556374B814C855DDA8F691A042350 /* AuthData.swift */; }; + 124F4DB8BA6D77FC4F6AACAD9594AD01 /* e_aesccm.c in Sources */ = {isa = PBXBuildFile; fileRef = B3AC106B742111DE087FA7B87A523B68 /* e_aesccm.c */; }; + 127B1F9A311B5FA87E6FE241915DB1DC /* co-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 073163420BED79D3F0D457FBB780682B /* co-586.linux.x86.S */; }; + 12849636E47ABE1B6709389B8714C81B /* Square Root.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE5BA2C7268A4F3816EA97002DA5E406 /* Square Root.swift */; }; + 128F1E85FFEF8B9C512A70C4723F4EF6 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6987D26A615917E6A7DB77F32FD14EC2 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 12C6D94FCB6D192C318198975AF8FB14 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 12F29F012AC7EA642A061CEFAC3A1A49 /* CNIOBoringSSL_e_os2.h in Headers */ = {isa = PBXBuildFile; fileRef = 242C756CAA8E25AB53D50F4EB9DE1C91 /* CNIOBoringSSL_e_os2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 12F91E01435FE08933A65A1DE95EC3D0 /* PrivateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9C6551A4C7E622106E3008ACCFC4A2 /* PrivateKey.swift */; }; + 1327F3B8D187244BF4E16BBD4173AF0B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 135FDA9E9BE1E6052092179EDBACCA91 /* field_10x26.h in Headers */ = {isa = PBXBuildFile; fileRef = 9ECEA2B23797D093DC1226DA47AB8BBA /* field_10x26.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 138C53F998E2DC58D18BDD0A1010EC1D /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31DCA335F3F32407235D0E111DFD0222 /* Config.swift */; }; + 138DFC533930F784B55D9BB8AACC0E06 /* SDImageCacheDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A0D5CC485EB2D72002AADA744B9B7DF /* SDImageCacheDefine.m */; }; + 13C33A2031B817F6877197B61C39E796 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE9230B1CD0D146600F41FD1C33A2A1 /* AES+Foundation.swift */; }; + 13C7B272C6E5F6A6CC5058AEFF912315 /* NIOAtomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B6B33E8DD205D584F0FFBE94EF68B3 /* NIOAtomic.swift */; }; + 13D2EC002DF5B19A2E953F954BF2B98E /* Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ABA6E8006B92B26C68AB3678AD43EC /* Serialization.swift */; }; + 143CAE0E207112691002259E1FA9E152 /* fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CF8D342496F49AFD2C13EF26F105ADE /* fd.c */; }; + 148E30B721817B243804E273ECD62757 /* bench.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E390FCD5668D1ADFB9CCBEEADDA960 /* bench.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 14BA4B3502ADE782A26DF00A8683924C /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4A308418216D636E99E558FCF77305E /* SecureBytes.swift */; }; + 14EAC53C775EA6A2C046651995690AC1 /* HPACKHeaders+Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF7AA6EBA1CE1E2A25802226115F77 /* HPACKHeaders+Validation.swift */; }; + 14F304B39D45A85652C5479204FA7675 /* CNIOBoringSSL_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D925DD409F2D414D1714BB5A5CA7B35 /* CNIOBoringSSL_buffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1531AF560743A1A162C7A9F151976FE9 /* v3_alt.c in Sources */ = {isa = PBXBuildFile; fileRef = B1D31E813551E4238174131DCA97F395 /* v3_alt.c */; }; + 1566A4870F5204DB95F44BDD25EF21CE /* SwiftNIOHTTP1-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FEABACF790432B16D0E392CB8416450 /* SwiftNIOHTTP1-dummy.m */; }; + 15C4C6B65F9A787FF4BC153F84FA6D38 /* AuthenticationSessioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3325BF8B476B063FCC992863946D8CB7 /* AuthenticationSessioning.swift */; }; + 15C778B2B8D8A223E3D3F37A70852494 /* scalar_low.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FEF39B78A6E02C765B4C708648B7A1 /* scalar_low.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 16439BB5FCBEE1827F379305A18611AB /* RLPDecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70B5A4EC9A2152DEE80BCF8F5BADA95 /* RLPDecodingError.swift */; }; + 1647BDFD386D433CBE0A46F1133299EA /* GRPCSendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0732CFBADE6259ACDF883CC16830835 /* GRPCSendable.swift */; }; + 16492EE99023DA47E1E67E5350DD99E4 /* x_pubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 305C829DCF6FBC7616A2B7DA53E928C4 /* x_pubkey.c */; }; + 164DEB7B33A09DD8663942511488AD16 /* SDImageGIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 6EE26EF8BE3D6A621D350BED9AA4AA2B /* SDImageGIFCoder.m */; }; + 168AB5EA0EBEB75D0434B55D0B97AD47 /* SDImageIOAnimatedCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F034E1F8CB2245253C9C794A0405E /* SDImageIOAnimatedCoderInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 169CC102186A230162AD42AF6E5EAECC /* print.c in Sources */ = {isa = PBXBuildFile; fileRef = 926E439F468CB0725B600E917A8FD131 /* print.c */; }; + 16B5435D378ADD56E7EB9B5FC50AEA44 /* HeaderTables.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F2E4DBBAAC82896230FA9EEF346638 /* HeaderTables.swift */; }; + 16BCDC468B7D329356800F7FE29281AB /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D517C93BB421BDDBD08A3281DFF9A4E /* SHA3.swift */; }; + 16CBEFA7C019A9551338BFDD1A43BFCB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 1777459577F63D908A836EF87F81B5FC /* main_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = AE7382BF76136F84B7A70C79D72F7E1A /* main_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 178672167BEBFDCC7789B6A50D766009 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 17C20D68963C252E9991CD7361723892 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BF8FE387A24324DB3636F112BFEA0ED /* Codable.swift */; }; + 18303B692A81A7D708973A6B9CBA75D8 /* SDAsyncBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E1182AF5CAA2AD260B7CCA3ADAEF7 /* SDAsyncBlockOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1887EFFAB070FC03886C6814B7973F02 /* ProviderInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90749C992E1BDD56FB2E5288EC80B36C /* ProviderInfo.swift */; }; + 18A8611ADD250CF40765F939E6DFD74B /* UnaryCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6EBFDC467B069F2BB9F8A08DF9115F /* UnaryCall.swift */; }; + 18EED5DCAFE2B676CEA9BA017107475D /* ZigZag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 887D9ECBC6B7F324CA3652F963F26571 /* ZigZag.swift */; }; + 194580FD51324B7C68D531C1B92E3E6A /* Division.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A2CC40A74FE6E4ECA8426FD1F6E64C /* Division.swift */; }; + 1978230AE0580B192FBF3589822A8207 /* GRPCChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF3AED7324AF2D4D94E0FFBAAF68EA96 /* GRPCChannel.swift */; }; + 19E55A20F0FB0B8B2630CB7961051EA9 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F21E8BB641EB344580DF444761E4D1D /* ChaCha20.swift */; }; + 1A37C655C603D137C76749E5787AAFD9 /* ServerInterceptorStateMachine+Intercepting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D15B530C1C0371C492AD75F922A6708 /* ServerInterceptorStateMachine+Intercepting.swift */; }; + 1AA9D67490B0BFF463915C09EED3D18C /* FileHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D2CC12E6E6166F2F0A662EDE733AE0 /* FileHandle.swift */; }; + 1AD82970D2B7334CBC8C42BF4C794143 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 1AE145736057FCBBD443FEC33A59A031 /* URLSessionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B010A061172855A37BE93C13FBDAD2 /* URLSessionProtocol.swift */; }; + 1B04A7272BEEDB0ABAF2DB20B0753366 /* x509_d2.c in Sources */ = {isa = PBXBuildFile; fileRef = 05C69BB038C2BE1ADA4A8E7DFE61589F /* x509_d2.c */; }; + 1B1FA30DC4EDFAC16D3B7685D30D90BD /* curve25519_32.h in Headers */ = {isa = PBXBuildFile; fileRef = 0744CD624F8529BFDA6DD9FE8C4A0D3F /* curve25519_32.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1B311E005DC1E098D108A7E529F71DD7 /* p_x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = F030EBCD1BB9F6809ACD10D556B7B1A0 /* p_x25519.c */; }; + 1B5271914E05BA88A006D8F0E1FD01AF /* x509name.c in Sources */ = {isa = PBXBuildFile; fileRef = 28CB8C467C147A30A990880025432449 /* x509name.c */; }; + 1B7D7FAEBFE29E80BA244AC626A3FED7 /* AddressReplacement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94DB78A6514187DF8BD31B5992CFDB04 /* AddressReplacement.swift */; }; + 1B8B77D013186603AB1A541336BE1ABA /* Service.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3772C1098F014CC7D14A0E944D584142 /* Service.swift */; }; + 1BB5ACC5E8E0CCB3F92E2677C3E4FB77 /* TextFormatScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF40917DF5A60C569C3D716E8DF3C25 /* TextFormatScanner.swift */; }; + 1BCD91BE33AFBF6AD203C19B62B1A96F /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E8885964394043CF304049308BC001F /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1BCDAB3C011B6B584B7BAF5B8787A2D0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 1C0188522AE8F90E65BBF12A4A57E5F0 /* ServerHandlerStateMachine+Finished.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F86C258B6E7E7D3579567A28EB94E0 /* ServerHandlerStateMachine+Finished.swift */; }; + 1C02A39D593EFE131B22846E6396F7D0 /* StreamLender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567FD469C35653B294CC5F47C54BAE32 /* StreamLender.swift */; }; + 1C2AE1E769BC1E5BA7062E4FB71DC6F8 /* PresentationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A4019C4EFFC2C909028FCF61F52C50 /* PresentationManager.swift */; }; + 1C2E294E64DD6F42A4E308ED052922DA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 1D199B3D7405201C26BC49047210A4A2 /* sign.c in Sources */ = {isa = PBXBuildFile; fileRef = 3327CF7D3195E556C6BC5D38CD50DC54 /* sign.c */; }; + 1D31F4126492EC4A1F6309A5F3BE07EA /* modinv64_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = CA44D2212E0CBD1D2922B7C5B191F102 /* modinv64_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1D325CFE11FE13A075C835E922BE1017 /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A36B1EE7A2D9315FC135DC6ADC49CF8 /* SVRadialGradientLayer.m */; }; + 1D95638B24CD46FD3DE23CC05EC50DBD /* GRPCServerPipelineConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEBA82D151D457B8D21E60FEE8FD924 /* GRPCServerPipelineConfigurator.swift */; }; + 1D95F578A3D2278DB2F9FBF41CA57A34 /* t_req.c in Sources */ = {isa = PBXBuildFile; fileRef = E36639476C222AC1321AE96AD9D9F3C1 /* t_req.c */; }; + 1D98188786C6EB48E6C3C3C1A4566BD7 /* precomputed_ecmult_gen.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E4AF999BF1254DD47727C2AEB7CBE48 /* precomputed_ecmult_gen.c */; settings = {COMPILER_FLAGS = "-DENABLE_MODULE_ECDH -DENABLE_MODULE_EXTRAKEYS -DENABLE_MODULE_RECOVERY -DENABLE_MODULE_SCHNORRSIG -DECMULT_GEN_PREC_BITS=4 -DECMULT_WINDOW_SIZE=15"; }; }; + 1DE947B834ED9E7DB45C0C490B12B4F5 /* e_chacha20poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = 14819172B31D4560BBD90390AB099AA1 /* e_chacha20poly1305.c */; }; + 1DED1CCBDC985A2E5624B2AC121DF103 /* e_aesgcmsiv.c in Sources */ = {isa = PBXBuildFile; fileRef = 0AF76A158E58D3DF43D7424F076AAD88 /* e_aesgcmsiv.c */; }; + 1E6152AE31D8E87B9CA6BD9D39F6280D /* CBCMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6E92656D4BBA6B5D21A6CF282B7FBB /* CBCMAC.swift */; }; + 1E82A1290E730894E41F451AFFEC26E5 /* Google_Protobuf_Timestamp+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26BBF10E864BCDD9CB2BE2284E3C9035 /* Google_Protobuf_Timestamp+Extensions.swift */; }; + 1EA0EFAFC0CA82353E71A262DCD55CAD /* secp256k1.h in Headers */ = {isa = PBXBuildFile; fileRef = 68E783BE195DDBA1CB7656608D41E62B /* secp256k1.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1ED8CEF109BCE64D0CCDA312F21B65A2 /* Cryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B03BD8B7CDD44609147E2976B328A423 /* Cryptor.swift */; }; + 1EFDB44E84AD03172B673AA3F428E752 /* PublicKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DD29ACB4CAE8D176D00306632D91B8 /* PublicKey.swift */; }; + 1F2E1C81716EE2989CF74352602BA7C0 /* ssl_x509.cc in Sources */ = {isa = PBXBuildFile; fileRef = C392709A348F71D9BA1F421199AAA4FC /* ssl_x509.cc */; }; + 1F4A13FD6675FCFCD9C19DF350348899 /* SVProgressAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C81418EABA8EB915144461E60CACE9 /* SVProgressAnimatedView.m */; }; + 1F7E97D272599397F5A938FE90AAA50F /* GRPCServiceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 554A30FAAA98F5650C4DFD0A9A48D30F /* GRPCServiceDescription.swift */; }; + 1F967DEE665A796AD5E0F4131F8052BB /* ByteBuffer-core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD6EEDAB47DBB048F944F50271E9FE0 /* ByteBuffer-core.swift */; }; + 1FD18AE4000607EBFDDF44FBA911DBE6 /* lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36F8D48D07C091BB1DACB071869B385C /* lock.swift */; }; + 1FEF626C094C06E18E9C332F1CB209FC /* x_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 318E86C627046ABDA00262E294538BE6 /* x_info.c */; }; + 1FFCBF421B34F1FDF2DF4104A8B3D499 /* TimeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1988AD6E34C0FF5849A9D31E644F9C42 /* TimeUtils.swift */; }; + 1FFD3A5D025903D1D457CABAF4F8E8BB /* SelectableEventLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5308041E257F28BE08E78CA91D4F0F9D /* SelectableEventLoop.swift */; }; + 20004B99F5050F59E747AB8DFAD7E891 /* SDWebImageDownloaderOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 966B4887F9DD9CD0ACCE62DE15BB14E3 /* SDWebImageDownloaderOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 20068761C9269D078753ABAB5517457B /* JSONEncodingVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D383BE6F056AC34E290D9985C98F462 /* JSONEncodingVisitor.swift */; }; + 200988C51A16062694059EB7B9E86BE0 /* cpu_aarch64_apple.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FC4BA2407401C3D72C0698DD1AEEBE5 /* cpu_aarch64_apple.c */; }; + 2020BDF490BB448003F12065D8662658 /* StreamEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADEDF5DB5CACF65B1F5326FC7DE2542 /* StreamEncryptor.swift */; }; + 2066A39A9CFCC4A4AD22AD2E7EE8C781 /* extensions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 576E84427AEC0E7BD5C7523E06B64FB3 /* extensions.cc */; }; + 208B3E1D3EA0585B0AFBE7D0EBBE34E7 /* GRPCAsyncBidirectionalStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF1B4381BEA551E1BEC8BD8A0F45A2E /* GRPCAsyncBidirectionalStreamingCall.swift */; }; + 20B983FEC35608CBE7036C4B743D44EB /* PollingResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AF0FDC004753EBA45EFC05DEFDD26D /* PollingResponse.swift */; }; + 211881A545C6CDEA8F31F068506F424B /* tls13_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 21294BEA1B79ECCF54117971DCFAD4E3 /* tls13_server.cc */; }; + 213E350CBE45392D78D022FD67262278 /* _MessageContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE64E9D19A886C817DDBE83563847C8 /* _MessageContext.swift */; }; + 2146154EA67C9C7C9AA6E27A09907E52 /* StreamMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A87F6880630FB4135090D5EB831F1 /* StreamMap.swift */; }; + 216BCA5B4152F43341A639C4539AD209 /* InitializerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26E310C45322A4ED4AA8FDA6189BB58 /* InitializerType.swift */; }; + 2174577CF2427A10DA8EABCFE645184D /* stack.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A4F06961A91338037FDCD870FD3A52E /* stack.c */; }; + 219AF511E706D6051A3D797DCBB638E6 /* x509_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = E19198AD322B90004297C469FEA5DB6C /* x509_cmp.c */; }; + 21D05279AA20EE7A1707A76C11BBCC00 /* NSBezierPath+SDRoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = C1F09B4955E96B2CEA5C0ABB75765747 /* NSBezierPath+SDRoundedCorners.m */; }; + 21DCD6FAE0686F2BB8E6F29189259C9B /* t_crl.c in Sources */ = {isa = PBXBuildFile; fileRef = EEC7776718F9A0615E07E697E101BD00 /* t_crl.c */; }; + 21E4953C3C05B96B90C4813EA94851B5 /* sha512-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = CA752654586A87C3CF5A48628F2A0C70 /* sha512-x86_64.linux.x86_64.S */; }; + 21F0615E77BA18091AE7AEF63C0E344F /* ec.c in Sources */ = {isa = PBXBuildFile; fileRef = 1997AA70B5C9CF99899BAAE9C39F3687 /* ec.c */; }; + 220A5DF00449033884685ECFC8FC9F1E /* api.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = B99B18B8997A3B27982F4A265CE6B365 /* api.pb.swift */; }; + 2299A0C9729AD55F9716F23E6F69B3E6 /* UnaryServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE16B6E629E3869F9CC21C3710AEE4C2 /* UnaryServerHandler.swift */; }; + 22B0E64E15D819C861158B0905546FDD /* RLPEncodableList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E667AE513A07C5DA03178515082AB7ED /* RLPEncodableList.swift */; }; + 22D452F8A3E250D161C8F72E524D669F /* FCLCompositeSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B95149890F9EB8667E582B99117736A /* FCLCompositeSignature.swift */; }; + 231991D416A8C399788EDE74D7D6E153 /* ecmult_compute_table_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 56707F1F35E9FA8B9C5BC03F1F30820D /* ecmult_compute_table_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 231A6374BFDF710A48C2427EF40466D2 /* ghash-neon-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 09EA10F3BD9588C5F0626E1E2EB3058F /* ghash-neon-armv8.linux.aarch64.S */; }; + 2325FCFA2B1B805C609CDB7C9F746E17 /* sha1-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 7EF2A44E9190048723B5408D239C2DC8 /* sha1-x86_64.mac.x86_64.S */; }; + 2366665EF870073B6400837985BD8160 /* x509cset.c in Sources */ = {isa = PBXBuildFile; fileRef = 14ECEB7E2BDA7B586F03DE2D62E88580 /* x509cset.c */; }; + 2387BA6A9FA73DE59088828AA79AE2A3 /* e_aesctrhmac.c in Sources */ = {isa = PBXBuildFile; fileRef = B9F05E2FE7977D3C097CFCCD3D8F4C2C /* e_aesctrhmac.c */; }; + 238B47BFDCAA664594A50749A699CA94 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C303112F60D6260807EFC5BEC533C0F8 /* Codable.swift */; }; + 23D3EADC91FC0602C3C8464C01DDDB9D /* RequestBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7F6195F500500561F1C0E2469545EF /* RequestBuilder.swift */; }; + 23F2376F3985F98AC41CA3AB975484B7 /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E08C20860569C87EE2F3AA6F06E5146 /* UInt16+Extension.swift */; }; + 240BAF5F91B3A549CACDB9F950E06566 /* x_name.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E41CB40FFD567899DF0C9440841F298 /* x_name.c */; }; + 2414DBF6E5DAB682E13615C4F4EBBA08 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 31077F40DE76448B09C8C93E0DFE3AF3 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2420475023B2D20EF1E4761A29661EEB /* ThreadPosix.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DBE2A6527A0E5F9B151446A402E14F /* ThreadPosix.swift */; }; + 2422BD14FC8BF0EC43C0EB38C8AAA01C /* tasn_enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 885E717B30A17DFBD9D63B98379E6883 /* tasn_enc.c */; }; + 24539AA69483BAC22DF4B6A4E661D1BD /* JSONDecodingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DEF390E21590188D7A27E6EEBCE0616 /* JSONDecodingOptions.swift */; }; + 24A7246A37DE34DB49544C489D45B8E2 /* CNIOBoringSSL_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6584B64DEE85ED6A8185CB5C7BE2B5DC /* CNIOBoringSSL_cipher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 24B3E393946D47A88703047590F066E7 /* PopupDialog+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D34821E2734FD3FD949F1EA95A2C744 /* PopupDialog+Keyboard.swift */; }; + 24DA814C2F7EA7C4187E2BF0B6466E9A /* SDAnimatedImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = C0A7DD2887C9012BC347BEA8C0AE059E /* SDAnimatedImageRep.m */; }; + 24DDD7C28150C3900FB75B7247CBBB78 /* aesv8-armx32.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = ED381E7A1561E7D710199DF83CA03990 /* aesv8-armx32.ios.arm.S */; }; + 24EA9BF8A7E10BDCB2B55716B7706A3F /* Bitwise Ops.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDBD5749F3FA2EEF750A1389E486D52C /* Bitwise Ops.swift */; }; + 252437788350C64E967C083D2ED6062E /* x_exten.c in Sources */ = {isa = PBXBuildFile; fileRef = 61B777F35BCB94CB5F2FBDAAD92939D1 /* x_exten.c */; }; + 2536B9BD4C2A9A1582333039FE5262D2 /* HashVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F03137B9A7361A477771450D163E9E8 /* HashVisitor.swift */; }; + 2555E359F9B41AEB322F1D047446FD2E /* rsaz-avx2.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = F1B3C4AB602AE6C7E11DC959C4F5F4D9 /* rsaz-avx2.linux.x86_64.S */; }; + 259D069DA9EE8D65896D9A58703D7103 /* buf.c in Sources */ = {isa = PBXBuildFile; fileRef = AFC2B42DF489B79BF57DDBF4A56453EC /* buf.c */; }; + 25D8592E215821E151A76E4FA989A921 /* refcount_lock.c in Sources */ = {isa = PBXBuildFile; fileRef = BA44DD3AAA85A97EA796D27E695437BC /* refcount_lock.c */; }; + 25EB52D099A4E7AB47C440FA84516CA1 /* x509_vpm.c in Sources */ = {isa = PBXBuildFile; fileRef = 1C420B1758416686759479BC0808D903 /* x509_vpm.c */; }; + 25FA9486E8A8B7EF48BF4ACFF210E3F2 /* CNIOBoringSSL_cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 225C2F0EB965A60AA6428E027F9D6370 /* CNIOBoringSSL_cpu.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2649BD966C3B00E41347178E9A833920 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1834AB61EE4BDDCD2DA92719083CB0F5 /* Blowfish.swift */; }; + 26821B9A27A4405B95DDD64E73056F6F /* ecmult_compute_table.h in Headers */ = {isa = PBXBuildFile; fileRef = E99EA8807815163F01066C02261ADCC1 /* ecmult_compute_table.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26944BFD4B8B8F631C0037619FC289F2 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DDFBE971A9F36C3D422E7C892F6053A /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 269B387FBBE2EAA2FE9B1CFF3AA09B3E /* rsaz_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = 36D26F5E67278BD31B9999C31CB37CBE /* rsaz_exp.c */; }; + 26A459DAC73FC2DCD5D7B0F12044F5FE /* ConnectionStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82AAF7249C7A243276F99629C91B7201 /* ConnectionStateMachine.swift */; }; + 26B20EFDC551B51912CFF2A6490C822D /* HPACKDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABFC0B6B87D0498049F2399765759D2 /* HPACKDecoder.swift */; }; + 26BF15D648EFA59FCA18AE285AC5B2A1 /* UIImage+MemoryCacheCost.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FCF71CC854BB6C918AB124655B2CAA7 /* UIImage+MemoryCacheCost.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 27181A4A309FC58C0AD2204EEA2FBFF2 /* CaptureQuality.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92C39073C666F3B2A344FFEE6B8910B /* CaptureQuality.swift */; }; + 2740B5448830CEFB0D1297AD69348418 /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9C8C0D310CF5B79226BE303CE6DE71 /* Decoder.swift */; }; + 275F99E74511043432C892810081DCAF /* SDDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CAD39B8875D55AA8E4426663E5F29E63 /* SDDiskCache.m */; }; + 278F5B2C01E923AA0C691D79BD0F321F /* UIImage+MultiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = A3380E0461C012878D8D0A4F5D15812C /* UIImage+MultiFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 27A24F80CF96015C16322EF7F645455B /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F75E00AC1E123368612D1953C7A472B /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 27C93A01F5FBF44A9613BBCBD3F53DED /* RemotelyQuiescingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FCD784F66C4172968D69584606D85C /* RemotelyQuiescingState.swift */; }; + 27E62EB5E6BEA87C00B242C2C8F22833 /* sha256-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 0B8022ED770EECA6AD08D59D3C644A1E /* sha256-x86_64.linux.x86_64.S */; }; + 27E961A836DAAD6BF73D755C4F5C6AA9 /* CNIOBoringSSL_safestack.h in Headers */ = {isa = PBXBuildFile; fileRef = C0113A9C794494094661D69DAAEC3214 /* CNIOBoringSSL_safestack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 282D3255D6943F4493975DA44B8CB6EC /* block_header.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B845CFDE312262625CAA4A7C843065 /* block_header.pb.swift */; }; + 28532908E40E423052AA43B0000028BF /* UIImage+Metadata.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D48BA151B8DF7918DA4CB33BF04F76 /* UIImage+Metadata.m */; }; + 285B49E1351B811C8532F9CD10E8DA90 /* blake2.c in Sources */ = {isa = PBXBuildFile; fileRef = FB14291E43ACFF921F360FB93AF38517 /* blake2.c */; }; + 288C4A9BE0B5B805FDED2A667D70CAB2 /* scrypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CA968D37E649A137FED235C6F605C65 /* scrypt.c */; }; + 289BB4383D8D0E6BAC66A02DABA987C9 /* GRPCIdleHandlerStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 186F7FBFBC9EC8B701D8D23534B49107 /* GRPCIdleHandlerStateMachine.swift */; }; + 28CAC0777930D9A1AF954AD2AFEEBAB5 /* v3_cpols.c in Sources */ = {isa = PBXBuildFile; fileRef = D10BB7A9B0FD68ED82C64D21CAC3AF2B /* v3_cpols.c */; }; + 28D1A14F79B2621274E486A2B7590AE2 /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248D34408517F523A350B44AC1E40FFF /* NoPadding.swift */; }; + 28EE052960A57B1B99593F28560B5E02 /* ThreadWindows.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C23B35B737F8A5A2A53DF67D203584 /* ThreadWindows.swift */; }; + 28F974FBE5AC1D2A4FA83F5BEDB1A1E9 /* dsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 11355BF143D6A8167F1CF508A51F64EE /* dsa.c */; }; + 290FDBE7D9B49AD40EDF8ECCC88D11F5 /* sha256-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 9F057B73B6702566A18F973839B10FF7 /* sha256-armv8.linux.aarch64.S */; }; + 2925AD48C2EAA347D02CD1C81F2BF2F5 /* ssl_transcript.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2CE94AE477E46E05AD8CD7994C9018A4 /* ssl_transcript.cc */; }; + 29491528E885FD6860457159F0DFB1FF /* HPACKEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129734FDDAF80E355B66A2397411314E /* HPACKEncoder.swift */; }; + 296B3EB544FC567348D2DDD5E4A204FB /* HTTPServerUpgradeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633C8C447C3FB1D4948A5BC065F355D6 /* HTTPServerUpgradeHandler.swift */; }; + 296F137821441F0CFAC52D800B8C2E93 /* ReferenceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1AB638EAD1EF8DD5285B803ED81B7 /* ReferenceType.swift */; }; + 297C35DCB9740DB54850B2923B9C237F /* Method.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536B9688B9200C123C4AC48652D36DAC /* Method.swift */; }; + 2980F984F7D2F691456888ECDB4A4120 /* MayReceiveFrames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F58491C6DD6CE92E44F104904186AC /* MayReceiveFrames.swift */; }; + 29B3FF0CF6EA57C77BF5A5A719D3BFCB /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A69601E2C917D2C7F86620B14F5F6987 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 29D4AEADB1E6B2C2FADA9CAF5016CEEB /* ghash-ssse3-x86.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 13FCD06B6CB42DC1D49F888089EC1304 /* ghash-ssse3-x86.linux.x86.S */; }; + 29DB79786DCDF3D889D273E0FA343F03 /* StreamingResponseCallContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B7A9E311EEA55E7535DFFA305302F6 /* StreamingResponseCallContext.swift */; }; + 29EFCE0029DAD34685F685DDC1584B19 /* PopupDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CCD93EFB03582F1106146024982D6B3 /* PopupDialog.swift */; }; + 2A2CB45901D951125ED082797A2E753E /* TLSConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CC3284E14BCF196DF7F1FC8A8C14B0 /* TLSConfiguration.swift */; }; + 2A58E784F4CBFDB27CB892BF47772782 /* ecdh_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = 557E8F163489D4D5A76F3540372DF512 /* ecdh_extra.c */; }; + 2A5977387319C6D0D9004D924B3D6CC2 /* a_utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 125FE81450FCFDEECAB6FA98B546AB16 /* a_utf8.c */; }; + 2A668DBCA505D299293EE6672ABA753F /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A762F23B1113D8E24B6AE1977D53DCB /* PKCS5.swift */; }; + 2AE24649677F27909C566071BC24AD2C /* PoolManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C8C7BB879B9DC1A63010ED47A05068 /* PoolManager.swift */; }; + 2B0D6D3F5CC10D03FE038F6BD58A71E7 /* CNIOBoringSSL_trust_token.h in Headers */ = {isa = PBXBuildFile; fileRef = BE0EFC3EFC30E0946EC8EAFAEB7C6A23 /* CNIOBoringSSL_trust_token.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2B20316F776E14186C91F489FB6B98C7 /* IntegerTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBAD15A414C98019A77F53D9F0847B11 /* IntegerTypes.swift */; }; + 2B453504C4F5C3239BDF25866828B590 /* rsaz_exp.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D2D3C66784C69FFD174E32B064616C2 /* rsaz_exp.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B7C943E62B9E04DB1053FA1408B6F51 /* CNIOBoringSSL_poly1305.h in Headers */ = {isa = PBXBuildFile; fileRef = C7B12679B3AE20F22998634963EDEB40 /* CNIOBoringSSL_poly1305.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2BC5609552C6B8061F1409B996F44C31 /* v3_pcia.c in Sources */ = {isa = PBXBuildFile; fileRef = 536271B47921F5A15BD15A2481CEC19A /* v3_pcia.c */; }; + 2BCBE089BB0218A079AAEEE73EBDF84C /* SwiftProtobuf-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C469D31D68B05F5C787C4195A2FB4C9 /* SwiftProtobuf-dummy.m */; }; + 2C620C5D7AEC13C573DB767902CD7A03 /* TLSVerificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB07308B36D8F85B7F9D40B31BCDA3B1 /* TLSVerificationHandler.swift */; }; + 2C68099EAFBBBD04A6415AB789EA0F0A /* SignatureAlgorithm+Cadence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAEC86F60F8795EC88E6D54463B62AC /* SignatureAlgorithm+Cadence.swift */; }; + 2C717084B1D688C8FB7194BBA8EBD028 /* PendingWritesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39863663084ED88A78F3ACB07CF63C20 /* PendingWritesManager.swift */; }; + 2C762E5C654B718C19CC98FEB27C2DA4 /* SDFileAttributeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B7017881DF5963322E5F9BFB3FF8855 /* SDFileAttributeHelper.m */; }; + 2CC93CDE16A4E4CCE784EC8EE7A9363A /* RestrictionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09430125F9E5748C67B35E97EFF1E0C3 /* RestrictionType.swift */; }; + 2CD787C99352C8E90F9EDC014DFE8262 /* TrackingMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249FA949B321C359DDB7A787CBB8E4CD /* TrackingMode.swift */; }; + 2CDE49667B9B52C8E4E197AC72644548 /* ReceivingHeadersState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21EF5C431176A45CB3F8F2CDC1035DA /* ReceivingHeadersState.swift */; }; + 2CEA645D742EF2C864D1078945C4C9B3 /* fips_shared_support.c in Sources */ = {isa = PBXBuildFile; fileRef = CAD15AC7A223C4AB51E56BA97FE8D30B /* fips_shared_support.c */; }; + 2D1D24C88A23F82164E0DB607DC8BE2A /* SendingWindowUpdateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAD2E654193717BE99B9064DD4811B7 /* SendingWindowUpdateState.swift */; }; + 2D20C12406A999419249E1E307F69829 /* SequenceNumberResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 715097A0A8AA6288109B6A38590962C6 /* SequenceNumberResolver.swift */; }; + 2D2A975AC241C8648DA36B497D271526 /* e_rc2.c in Sources */ = {isa = PBXBuildFile; fileRef = FED43552635768BCC4C78BEE32DCA1A5 /* e_rc2.c */; }; + 2D55CC779DD6D3FD8B1420C7D650F2F4 /* c_nio_http_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BF92DA07FF2BFCD193217F90EDA6DF0 /* c_nio_http_parser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2D7E7D5F025A1006C0D373B5884B6E52 /* SDWebImageDownloaderResponseModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 59DEF33DF5D0533B2F230F950425D679 /* SDWebImageDownloaderResponseModifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2DAF67AC29A7DB0A656B356746BB4D81 /* x509_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A09CDE39737C3CDDB81BF9732C91CFC /* x509_set.c */; }; + 2E01037F1DBA7627B825769DA9FCC401 /* GRPCClientChannelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D0589E851EBFC66CE9F5E2306DCD04B /* GRPCClientChannelHandler.swift */; }; + 2E2017820A49E43FD89404C41DDD646C /* SafeCompare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B295C96E65F578984871707C9373DB8 /* SafeCompare.swift */; }; + 2E225159666F9600A6472D4C9E8A1BC1 /* ReceivingWindowUpdateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A64C1697F6315EE294F1C985C6E2FABB /* ReceivingWindowUpdateState.swift */; }; + 2E676A8652B8B33723849761B554B088 /* PreSignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E57E9F69648C28BE44DD5F17DF1F549 /* PreSignable.swift */; }; + 2E6FC2E96E3E66DA213A746B85E1D191 /* CNIOBoringSSL_asn1.h in Headers */ = {isa = PBXBuildFile; fileRef = 66077917DB54CBB0DFB565612EE929C2 /* CNIOBoringSSL_asn1.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E77466B99CF36A7A6B7F51E30EBA1D1 /* pkcs8.c in Sources */ = {isa = PBXBuildFile; fileRef = FADD4E85533236D815BDBC5585464254 /* pkcs8.c */; }; + 2E873556BA959B32C3A09E123454A225 /* simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C64905FA3EA211221F9F9969540494D8 /* simple.c */; }; + 2E91E0AC4DAEB74AEE8F59074951D30C /* x_sig.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D488D9F0EBC85B9EE41D929CABD0A2E /* x_sig.c */; }; + 2F85FF5597762E2E3C6961C6DD690A60 /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = E6DC64D0790FCBD808F1189978E45306 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2F9453DDA53C6BCD2DCFFB168BA689CC /* SwiftNIOTransportServices-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7672BDB3320CC16155E590B26AB14394 /* SwiftNIOTransportServices-dummy.m */; }; + 2FC36894797171AE85A2E5697783C285 /* ApplicationProtocolNegotiationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AB3AF641421C7780DA0A681572666A /* ApplicationProtocolNegotiationHandler.swift */; }; + 2FCCBF31C63046E3838B248B451D2263 /* asn_pack.c in Sources */ = {isa = PBXBuildFile; fileRef = 2E4DB6419D123356E98E2E5554EB8DCB /* asn_pack.c */; }; + 3015C91C523C5133A639F57DE0425100 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A7769ABF2BDCDA505650A03B5AED87 /* SDImageAssetManager.m */; }; + 3039CFE7D17F3DF82B08B2A827AFE446 /* ValueType.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD0215600AEB19164756FA72475BCB2F /* ValueType.swift */; }; + 307D23D086096B219F62664F1B7E4944 /* v3_conf.c in Sources */ = {isa = PBXBuildFile; fileRef = ECDEFD005DD0018E26210FF8F6A95B5C /* v3_conf.c */; }; + 30893A8858D646E8EA11BC475EFFC95B /* a_digest.c in Sources */ = {isa = PBXBuildFile; fileRef = BEC3EBB70A4B1534B7BE14CD450659AF /* a_digest.c */; }; + 30E47B499E8FA95AB447A28923A9C666 /* ProtobufAPIVersionCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9D25B6386B64C23DE7B0BF846749F80 /* ProtobufAPIVersionCheck.swift */; }; + 3110384B69E79E8FBAF8427D5F3392C0 /* main_impl4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2257ABEBE7B0BE768733AA198201002D /* main_impl4.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 31BA8F67687A3DCA9163EA36D46B2062 /* AsyncAwaitSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = C661B04F55355271A9F8DCD687D303AE /* AsyncAwaitSupport.swift */; }; + 31BCDEFDC31BA73696819B52FB7E8B44 /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25196B26AD9D6CDDD91A54874EFD4A1D /* PKCS7Padding.swift */; }; + 31C7D807BAB08D0590E2F09A272E24CD /* SocketAddresses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AAAE61AA716A70C5261F8FA6A98E4C9 /* SocketAddresses.swift */; }; + 31D5B73EB3DF7B6970F181DEF0CDD9AD /* ControlMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E525E05D489CE1A833F84421241958B /* ControlMessage.swift */; }; + 31F38550A862FED98573915EDE3C9BFB /* SwiftNIOTransportServices-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B69F35BDFA7E3985C0BF5A43101532E /* SwiftNIOTransportServices-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 31F60D97F4140D2AF8211F1949778527 /* v3_genn.c in Sources */ = {isa = PBXBuildFile; fileRef = 8EF5CCE3CAE796C01BC8099306428ED4 /* v3_genn.c */; }; + 32177ED52870A5948D85E9EC66A1B73A /* CNIOBoringSSL_hrss.h in Headers */ = {isa = PBXBuildFile; fileRef = DEBF4C708C9182A6158AD07729A04D54 /* CNIOBoringSSL_hrss.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3249450A5B8B712B7515FFFB15B342C2 /* CNIOBoringSSL_des.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F3996E2ECA8D02EBEDE108CE6C07DA /* CNIOBoringSSL_des.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 329398D9FDCC749115DAFCDFBD89BF4E /* ctr.c in Sources */ = {isa = PBXBuildFile; fileRef = 85C28454D1170371B9D8A0DF53331720 /* ctr.c */; }; + 32AE2F6E08E5E9A303A2FD9205386F4E /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8C0E874C7752604C945A86C83156ECB /* Client.swift */; }; + 32F801AEE6075762594F689998CBFA77 /* dtls_method.cc in Sources */ = {isa = PBXBuildFile; fileRef = 50A09330521F5E469A86D09B6C683AE0 /* dtls_method.cc */; }; + 33383BFF8CF2F04FAA1C97438A407AAB /* ConvenienceOptionSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4AE6EBD52125EB64187C198B9998052 /* ConvenienceOptionSupport.swift */; }; + 334B3DC37D7F45A1B3AB0B120ADD8C90 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3447ACB6AF004264B23BE6BF79FE179E /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 336BA7F271A33087B951BA4C6C6B2C6F /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BEC1870D5E8752AFBADC18D9E910946 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 336E671A32DBBE0DF1750CAC02EF0E91 /* DapperWalletProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0866B41EB6AEDC557B09BE6BED4DD85 /* DapperWalletProvider.swift */; }; + 337EB308AF27E38233BE5BBA64822443 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 3383D1489A786E3DF95F56AC27F6D805 /* curve25519_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D2A8E0EA07BE8699C688044205A447C /* curve25519_64.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3392445932E97CE330EBD08732B22E65 /* simple_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 434EE467ACF31ADF9B7EB3AE050852FB /* simple_mul.c */; }; + 33A70DD42AA65918B521426786DD817F /* tls_record.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B5F437EC689DD66B48C952477347467 /* tls_record.cc */; }; + 33AB8FFB5F57EBE4E10F14914D000CE2 /* ServerErrorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB2A9752DA2D470C520B44CA619076B /* ServerErrorDelegate.swift */; }; + 33C0E2EFD1C8046A2020D25FD1F1611F /* SDImageAWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DEF889114EFDCE691DAEE2F56411B5AB /* SDImageAWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33FE5DA9B7C3359A372C8FE50DAB3F89 /* v3_pci.c in Sources */ = {isa = PBXBuildFile; fileRef = 1D45A7157713AE7017F1EF3AF4930E2B /* v3_pci.c */; }; + 341368BF38E97ACFAF3F0866C1BB77D1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 343B53EB998CC5B609B8DE84BAD882E0 /* SDWebImageIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = C070BF6E38EB220139D06F9C127FFDF5 /* SDWebImageIndicator.m */; }; + 34B5DC4D539F2BB627BA9DB30FD5197E /* ClientConnection+NWTLS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A884FF8ED4F6B364A965586227FF7E39 /* ClientConnection+NWTLS.swift */; }; + 34BF78E8CA1CB64B419902E4D16EB3A3 /* Shifts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B611E01AE9F71F3596A643A7D2A421C0 /* Shifts.swift */; }; + 34C942CECDD821753DC991C863A649A8 /* ssl_lib.cc in Sources */ = {isa = PBXBuildFile; fileRef = BBDE3E6CCC2C2E47E05E483B33552AD8 /* ssl_lib.cc */; }; + 34D0B67BCA0134CA6B02C42A18F50EC3 /* p224-64.c in Sources */ = {isa = PBXBuildFile; fileRef = 34BDDD8B06A6C8AED5EB5D30FA9F2A88 /* p224-64.c */; }; + 34EFF2685CB6B544507AAECEB83323F4 /* CircularBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22988D09847FF0EFBB7BF71B1818201F /* CircularBuffer.swift */; }; + 3622AFF43F23CBD87FDE9257B991ADED /* ClientInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F65183B06EC810B56AE796D97035222 /* ClientInfo.swift */; }; + 3634E84D125C95C379D76A2B1ECFB625 /* CNIOWindows-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6767891787016D4050CDB4C413106873 /* CNIOWindows-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 363CBFF46709F7C4175D1678769B39F2 /* v3_ia5.c in Sources */ = {isa = PBXBuildFile; fileRef = 201E492F116A89CDAA466CBA8D40CF6F /* v3_ia5.c */; }; + 364F8DC5ADE96CE3CA2B30F84BDD2D9C /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB8B787D84DC3ED9227B3184A1A4369 /* Digest.swift */; }; + 36A0033DC9DE66FCEA295EA3FAB69FAD /* Asymmetric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76AC28F9452BACDFEB2FFE9583CF3F28 /* Asymmetric.swift */; }; + 36B1FE4CCE0CB5BE55D4DABBA48D7D5B /* TextFormatDecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F47BA8B5549C0C4A9F35A0BF8EE2CD /* TextFormatDecodingError.swift */; }; + 36B22E86B2BFF233749B736F3F2AA409 /* p5_pbev2.c in Sources */ = {isa = PBXBuildFile; fileRef = E77F790CCA4B1B8F1B6CD5B3C98BF486 /* p5_pbev2.c */; }; + 36C4B71AD593AAC1EC123CAC393A8A42 /* SwiftNIOPosix-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B325D7050B338C70831E7F3117794BE /* SwiftNIOPosix-dummy.m */; }; + 36E57B5E5628F49E6815083DCAE8B968 /* Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6538FD01C920493BE564E5F79BB1EDC3 /* Thread.swift */; }; + 36E821F5D3A12F0C6041663DCF2673D5 /* DynamicBlurView.h in Headers */ = {isa = PBXBuildFile; fileRef = 73B680A7975CF68CC70271B1876AC25C /* DynamicBlurView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 36EBFC3E076F4D62B303ACC0704F7AEC /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE715B9C7DA79D3E184910C877DFD198 /* String+FoundationExtension.swift */; }; + 36F35669F3AFF65477B2366FC09A1B3F /* SDWebImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1793B1A8D6B29682805F8E809D394CFD /* SDWebImageOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 370E327857C0A7598490ABD014DA3C56 /* PCAPRingBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FF6032FB91E924B08894D202423B16 /* PCAPRingBuffer.swift */; }; + 3797AF5CB4E2FDA7B4972B3BDF95C612 /* SSLCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF71BC3254D90CE69B3FD2C1D702DE0A /* SSLCertificate.swift */; }; + 37E3C820BC838123661E1391BEAF8092 /* UIImageView+HighlightedWebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 04A53EE37AA8CA3AB2F52ABF0D84FD4E /* UIImageView+HighlightedWebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 381D42ECF079E81454D3418F6DCC3B0B /* String Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6834A81C3A0BC11254126CF44CF45C6B /* String Conversion.swift */; }; + 382F693474A72AE3B04DEE1872A92A6B /* Server.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2683A364FE598567755584430E34AEA8 /* Server.swift */; }; + 385F07B7AF065FB0145F084A0C160256 /* CallbackMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09788728497C89B1D08DEAB7DB2D2D86 /* CallbackMethod.swift */; }; + 38C17D5F6F02C2300FA28DA364B08555 /* RLPDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E02FC64457E1330FD2D59B8A42CDDB9 /* RLPDecoder.swift */; }; + 38CF7D5EE6C28780FE3F9C1E63CFF3D4 /* SDAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A62A9516C784312B6E9DCF811BEFA843 /* SDAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 38D4225ADD3AD2E23B7F980267500E0B /* wnaf.c in Sources */ = {isa = PBXBuildFile; fileRef = 26D493BEBDA50C996FF6E836192AD09F /* wnaf.c */; }; + 38FB2392290B383258674CAA64EA6989 /* ResponseStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DA9089BD259A8CD372B4BACC27F344 /* ResponseStatus.swift */; }; + 391E8EF30D9F2981FBFC133B891FE4E7 /* c_nio_http_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C497C2FB894DD3EF2130F73BD38D1F6 /* c_nio_http_parser.c */; }; + 3937C65ECB0CD2E2AEC99C27CFE98DFD /* GRPCClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6DE86A887712395D34AC74951E2B7F2 /* GRPCClient.swift */; }; + 393F4CAB20C2F98ACE213B5622227A10 /* x_spki.c in Sources */ = {isa = PBXBuildFile; fileRef = 5E7EA222E0C14D26E93668B34B40EC24 /* x_spki.c */; }; + 3995CC3DF22F08AE84EA213DFE49064A /* CNIOBoringSSL_hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B43C57C58784FCEFA2CBDEF283F75B0 /* CNIOBoringSSL_hmac.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 39B08B0FE49C78AB4BCC889D37916B52 /* pbkdf.c in Sources */ = {isa = PBXBuildFile; fileRef = E66028A9BC516368D326E1467AD827B9 /* pbkdf.c */; }; + 39BC4EC07ACADD3B81E1775BEE6FA3A0 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5775235143C439271C4EDF08E25E941 /* Authenticator.swift */; }; + 39CFF7DEB8EE9CEA4BE583563FC68ABB /* KeyedDecodingContainerProtocolExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41139673B91A0801D89A7AD0239C82B4 /* KeyedDecodingContainerProtocolExtension.swift */; }; + 3A1B7837444E712B61F81BFC7214069C /* Google_Protobuf_Duration+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752DD0693488AAC12528A410CF1B462B /* Google_Protobuf_Duration+Extensions.swift */; }; + 3A442DD3A0079E4599068BB0B7C2B604 /* e_tls.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BB4947856BAB2BD924157D3AA2E861C /* e_tls.c */; }; + 3A5832B520FA616148B778C9D27378E5 /* shim.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6BBD134CE96FF5620A937811221B57 /* shim.c */; settings = {COMPILER_FLAGS = "-D__APPLE_USE_RFC_3542=1"; }; }; + 3A5C01C51285F5FFD051261823BDAC3D /* p_ec.c in Sources */ = {isa = PBXBuildFile; fileRef = AB71FD00DEB3A0ED199A7CF3CE0181B8 /* p_ec.c */; }; + 3A8D49922B5DB2E5D54D7F90439231BC /* v3_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = E0EA82A4A84FD9D37485CCA3798E48A6 /* v3_lib.c */; }; + 3AC3AD7FD0C399B65CD6C018C51816C1 /* passive.c in Sources */ = {isa = PBXBuildFile; fileRef = A69F7967829F2BA523BFAF89710C4A00 /* passive.c */; }; + 3ACC20EC1AC96897FA23F83EE511B57B /* FlowSDK-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A9428F804A61917EC818A13B40631A27 /* FlowSDK-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B72C235C1AB8944333C2322F08B6B46 /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 190F33C8800487DE7FD3FC3D767E1502 /* SDWebImageTransition.m */; }; + 3B7D76DD8B20D98506855AAF6C1DB657 /* source_context.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = D587939838E633D7D3BB2F5EDEDE5011 /* source_context.pb.swift */; }; + 3BB15EE818B40E814B6F57F41801D205 /* ec_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 52FEBD0FB983B544EE473E3B708AF839 /* ec_key.c */; }; + 3BC7792865FAD916A4DB8E7695A2768A /* StreamDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D2F093BEE044995B014C077990A57 /* StreamDecryptor.swift */; }; + 3BCAE39D65BCD9FFACB96156CA7B084E /* Capability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A6622BC3A5738284B4FFB7EE3E49AC7 /* Capability.swift */; }; + 3BD2AC8EBB74AF8A5DD2F707812AA060 /* ByteBuffer-conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D80CD66E9C87158F6F5D67AFFED62EB /* ByteBuffer-conversions.swift */; }; + 3BEEEADFF04E2FE7CB8ED7A1BB5E2844 /* LinuxCPUSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AA2C31CB795D4CEC50EE6FA24AF4C1 /* LinuxCPUSet.swift */; }; + 3BF2D5C59B1CED39EB16613E4BEE1AFF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 3C0A8F7F9A1899CAE1E39801A1760C46 /* hpke.c in Sources */ = {isa = PBXBuildFile; fileRef = D3801A363FE17786D7DBE4F3571FC3BB /* hpke.c */; }; + 3C10368702A8DBB98538F33EC98EA47A /* NIOCloseOnErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E03FB9C4D7EBB4B177BAE64292C69AD1 /* NIOCloseOnErrorHandler.swift */; }; + 3C3652259AE69A20693C18577D7158FA /* AnyMessageStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E4924462479AAFB08B5F728BD40684B /* AnyMessageStorage.swift */; }; + 3C609EFC2B1EA792944BB30029F260E1 /* CGRPCZlibp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B323BAC1EC365CD5A5AFC329449DF3C /* CGRPCZlibp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3C646DD6A481FDBACA0F87F5F6FC03DD /* p256-x86_64-asm.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7A5A13941436B4785B45BEF1D9012 /* p256-x86_64-asm.linux.x86_64.S */; }; + 3C74F74B2437F0528188E8CF2C2FDFA3 /* ghash-x86.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 86BCE77648001A9860BA9ED1C6D5CBAA /* ghash-x86.linux.x86.S */; }; + 3C9DD8BF2BC29C594EF7DDDC1AC20A39 /* ReceivingGoAwayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73E7B58CCC3FDF610ED5E5F29121CEA1 /* ReceivingGoAwayState.swift */; }; + 3D1485C04688DD005632FF34A33B48AC /* AEAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDF35E8639017787D175323CA359D07A /* AEAD.swift */; }; + 3D428FEC4A3AD3F5BC720208D9FA3C2A /* md5-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = ADF1451E76D53D6923B25ECAB4EFEC04 /* md5-x86_64.linux.x86_64.S */; }; + 3D610323517B99A5074AF910E46F4681 /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526ED2C5D0CAED69CCE1C91E3640C6F6 /* CFB.swift */; }; + 3D6829553392CA8D26534EC5F5852844 /* AppDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228777DAC0CFA7ABAE01250071E1780F /* AppDetail.swift */; }; + 3D7151FB0FF951AA015EE3644BDC078A /* CMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B2A679D31DCD596EEC5BA8D7AC26C4 /* CMAC.swift */; }; + 3D842812B067B5DBC33A9CA7CE5211DD /* URLSessionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0604EF3225428B5D345DFD1D40604F3E /* URLSessionExtension.swift */; }; + 3DCA61FB5C526EC9D1E71B89C21FE248 /* CNIOAtomics-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AD1C392EAEF15BD0F92D2E6BD8131F /* CNIOAtomics-dummy.m */; }; + 3DFAA395226CA356B2BC563D68059218 /* URLComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = E747B0DAB33E037A6FC0E59DD4BB8C6F /* URLComponents.swift */; }; + 3E049E682EACE80B60B2F8D2B7F5F420 /* vpaes-armv7.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 540D85AAA885F961771C8AE709B2E3BD /* vpaes-armv7.ios.arm.S */; }; + 3E145E30FB5E9184B578974DAA1F3CAA /* asn1_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DFD26BAFD93E2F23DC053E3D8373D71 /* asn1_compat.c */; }; + 3E36CADE9AB4FB5CA346B548082D5983 /* armv4-mont.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 2B7D55E7D073D38B90AE5EFDF895B883 /* armv4-mont.ios.arm.S */; }; + 3E412DFDCB98BAD9E439CDBD68D953E0 /* p256_beeu-armv8-asm.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 2D19761A0B447DA579F73045D0EC0405 /* p256_beeu-armv8-asm.ios.aarch64.S */; }; + 3E42701B449F5BCC28EA93B1F896E113 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6FFAA21FABF954FA624913576251BF /* Logging.swift */; }; + 3E866A1B98C4B497DC6B912C2C82F761 /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC8441953E0511E075A55C9CC42E27E7 /* Rabbit.swift */; }; + 3E8D88F434DABBC551E828DFDAD424AF /* HTTP2StreamChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445336EC05FB156B35CD30D78AB56F7E /* HTTP2StreamChannel.swift */; }; + 3F014C9233DA4A9519754870B00CB6C4 /* p_ec_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 26468D5F27DE15516B01E0C24D8DC020 /* p_ec_asn1.c */; }; + 3F373E5D3E6B46D37E6AFECF483DC201 /* Codable+ByteBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EB52F4DE857E6CA5BC27C60BFAA047 /* Codable+ByteBuffer.swift */; }; + 3F5505CDB9E9AFE4C7C53E9AE4BDBE5D /* execution_result.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39945BEE0BA25547BEE869FDD63873F /* execution_result.pb.swift */; }; + 3F567CE353442AE137B71B258409F5DA /* SDImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137DDEABB44E61FEC937F8735AB2BFCA /* SDImageLoadersManager.m */; }; + 3F5909D48C8883BB1EDCF3A5696954E1 /* x509_txt.c in Sources */ = {isa = PBXBuildFile; fileRef = 0671DFB179723F36496A64FE5B5B2A25 /* x509_txt.c */; }; + 3F5A9C6722CF24A67082F4FDA44A3A07 /* rsaz-avx2.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 5183C8B06B2FB512F8EBB2BA65E84D34 /* rsaz-avx2.mac.x86_64.S */; }; + 3FA64CC0150CC8785A449CD2BA0AE4A9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 3FB12D1C256B8D1BAE15BF19E4163EB5 /* x509_v3.c in Sources */ = {isa = PBXBuildFile; fileRef = 3952A7D0C8AA53FC69555B71FFEC8EA3 /* x509_v3.c */; }; + 3FD12183C97BF61139CCA374B72313FA /* Subtraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 369A8C22EFAF607261525365CF510608 /* Subtraction.swift */; }; + 3FFBD47D4264F4B38EEC93627453A434 /* EventLoopFuture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A26731C91E6BD1C0ADEFC3D162CB1B6 /* EventLoopFuture.swift */; }; + 40224FA586F705009FE476F24D0B9EE5 /* scalar_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B9F59DEEB501854CB292BA30EED9FE1 /* scalar_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 40325640A5E0EAEBF4D95BEBC09ED112 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D344F7DF3C892D34365A5382075A06D /* UIKit.framework */; }; + 4075297FF5A21C84EF513521FD7B34EF /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0105C5BDCC968D3CB601B11FF63E74E4 /* SDWeakProxy.m */; }; + 409D336A5E9481A89FFDC487C0567F72 /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0CEBD079B76F4703EE2CE856E59BC3 /* Collection+Extension.swift */; }; + 40A09F5E948345A60B856BB7C3BB5FE3 /* Subtraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A903B307C82702D8099A1F1C7C0697C /* Subtraction.swift */; }; + 40AC97C5D29738700D1542040EC3B7C8 /* CallOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527DFFBB1677EE7C10B5FE3397F4B0F6 /* CallOptions.swift */; }; + 412EE262DCED176A73591124DBDBA97C /* UIImage+MemoryCacheCost.m in Sources */ = {isa = PBXBuildFile; fileRef = B30C1C5FE90BD3E1CDC3E1AC3FE3A35C /* UIImage+MemoryCacheCost.m */; }; + 41563D7A88B2B5AB455F7369556CE6A5 /* PassthroughMessageSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205E11C37E7B176455E96ACA338D3486 /* PassthroughMessageSource.swift */; }; + 4162FD4DC81264250152C090A05E5C70 /* secp256k1_preallocated.h in Headers */ = {isa = PBXBuildFile; fileRef = F7828C89FC15A295868A8D6D48408479 /* secp256k1_preallocated.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 419470CFF238F966CABFA15C324BEB42 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 41BBAE8C840AA595366BB22FE072C75D /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DE5AF97508CDFCD16CB50A4D988423 /* Constants.swift */; }; + 41F053EEF2AF2A9D9175FD2213C2E62B /* CNIOBoringSSL_objects.h in Headers */ = {isa = PBXBuildFile; fileRef = EE79390AA30BC15E638A709665466A6C /* CNIOBoringSSL_objects.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 41F230F2A6E6E050DC90A01861EE3B6B /* bsaes-armv7.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = A9E372A470782C3F8A90B18E5E01C195 /* bsaes-armv7.linux.arm.S */; }; + 42029FEF26CB14EEE3360353CAB69949 /* CNIOBoringSSL_boringssl_prefix_symbols.h in Headers */ = {isa = PBXBuildFile; fileRef = 75B0E53F3B6357D83B76559AB25E0DAD /* CNIOBoringSSL_boringssl_prefix_symbols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 420D28F3B8C7A6B5AC500FDF88B57872 /* StreamStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0E49E0085C99A522336D97C0D644E2 /* StreamStateMachine.swift */; }; + 42258B3EBC9E21CE161CFD7DFD3BBE8D /* Locks.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E4C0FA477431EB8B424B3E86E6E278 /* Locks.swift */; }; + 4270711461FD0522F4914290FF43BB92 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ACBD31AC425A93986D8DA5597F7FE80 /* User.swift */; }; + 42822E48A1441AD8E0011D37C1625B36 /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 34E313835ACC1C3A633A38FC5DA81F44 /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 428B7476BB9653288BB42A936041D612 /* HTTP2Frame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CE207153EF5353D725D8EA028555A5B /* HTTP2Frame.swift */; }; + 429E5CC928985357D07058FDEE8069FA /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E84BD2EE14B54889FE7A9DC744FB2076 /* UIView+WebCacheOperation.m */; }; + 42BB279BAACDE5F42F5E467429B295CB /* ServerBuilder+NIOSSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4166CCB7B030C71C569CC9571ED054E0 /* ServerBuilder+NIOSSL.swift */; }; + 42C29C0C622839691B91E97AFB68CFDD /* HTTP2UserEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9059977DCEFF09B9DF959B8130F23A18 /* HTTP2UserEvents.swift */; }; + 43076FC6D9C62A893FBADB9A1160923F /* CNIOBoringSSL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 2139CE03849530684122BD8D1590DAD4 /* CNIOBoringSSL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43C2C33EB588312825F3FFBD4F80B794 /* SendingHeadersState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5863D402126A6AF32F4B895202656681 /* SendingHeadersState.swift */; }; + 43C87FB3800A6BD28B5490A4F392188F /* HTTP2SettingsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF6E3A06093B1FBF24D0CDFA55E48E4B /* HTTP2SettingsState.swift */; }; + 43D89640DA44BC448AF1169EE744892C /* urandom.c in Sources */ = {isa = PBXBuildFile; fileRef = 9975BCDF9C13EAC1086E49406AF9586E /* urandom.c */; }; + 441F9A62730F73CB2E2C58A5DDE1F3C8 /* CNIOBoringSSL_ex_data.h in Headers */ = {isa = PBXBuildFile; fileRef = F30262F08BA5B002A9DA4FA0B09FC1F7 /* CNIOBoringSSL_ex_data.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 444D3731A419203D89C6A46FB93445CC /* x_val.c in Sources */ = {isa = PBXBuildFile; fileRef = A0D220C80433E4283F2163A55CA822A3 /* x_val.c */; }; + 449C1B624DEEC2565D0B8C809C0103A7 /* CNIOBoringSSL_engine.h in Headers */ = {isa = PBXBuildFile; fileRef = E90DB3DF75F4249C5839DBB7B1F6B048 /* CNIOBoringSSL_engine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 44BA1B9824BE5B3DDCA771F5BEB2FFEB /* scalar.h in Headers */ = {isa = PBXBuildFile; fileRef = 7513FDB345A1F65E3221C98807F698A9 /* scalar.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 44F8FD88A3F44F423EC14E77188B3C96 /* algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = 672C34D301D2789BD465129E931DF530 /* algorithm.c */; }; + 45923B7EC01C7C652B67FE34763304D7 /* div_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = 70AC45CB71401C49657416805D8D6801 /* div_extra.c */; }; + 45A4A1908ED5AD2720326A3C4E1B9E04 /* secp256k1_schnorrsig.h in Headers */ = {isa = PBXBuildFile; fileRef = 40AEBB2D920B40CB9140D666883A8F17 /* secp256k1_schnorrsig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45B6DF681B09BF997E84A2EFC6536A5B /* TaskExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7DCC5C12AD7E2C8657631AC471C25B /* TaskExtension.swift */; }; + 4618F63D9BC63C5DAE31EF33DFE988DD /* SwiftNIOSSL-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C08AA9786D7C02B53B65E79786224F2A /* SwiftNIOSSL-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 461CBD4619115C3F588833050A10D13B /* SelectableChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 203A85ED452B8D5A2E6607D17154B355 /* SelectableChannel.swift */; }; + 4623448C58E0E271F0DF5F4CC6CAFD0D /* SDImageCachesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B5844B0F5BCD183C6F24728D9D2D55 /* SDImageCachesManager.m */; }; + 46387A06696852FFD7DC028A937E9F17 /* Heap.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3ADD3A261C519861223F27639A1EB81 /* Heap.swift */; }; + 4645A03CFB6DDC053B5886AE7FA1D750 /* CNIOBoringSSL_x509_vfy.h in Headers */ = {isa = PBXBuildFile; fileRef = EAD70090C51A8155E88EE4B15A8090B0 /* CNIOBoringSSL_x509_vfy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 468B2977ECE39B9FA89CD0C9F8BF945B /* group.h in Headers */ = {isa = PBXBuildFile; fileRef = 3435A3B12A63A7FCB7B93A5B38A01B4B /* group.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 474163E6CF20CA1AC3698759F2B6D51B /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = E30A11CD3BEC671E6C5B6D2BC47A094C /* NSButton+WebCache.m */; }; + 474EE6CAD4486F21F08B52EB7557F443 /* tasn_fre.c in Sources */ = {isa = PBXBuildFile; fileRef = ABF3045DB54F2F18DE8E2856CF02D59B /* tasn_fre.c */; }; + 47CD1C6665C95709A1F74625C46615B8 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82006C1BC2CD48F726128D0C958B3ACB /* Int+Extension.swift */; }; + 47DD92D5DB6339143D1C2D6F90F2FE4C /* FlowAccountProofData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0C50F65C6376FDAC08630DD26C4B513 /* FlowAccountProofData.swift */; }; + 47F0503848BFA54967C68EEE6FAA95FA /* collection.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3714076099ED9A889D91939B3943B37D /* collection.pb.swift */; }; + 4807FD6E6AAB401A5971FE2A9925B598 /* ClientInterceptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7797BD7095643FBB0149737059E66DD /* ClientInterceptors.swift */; }; + 4817F4C6195F7000116E4A850A701C17 /* t_x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 2353F9CFA0E9F592D40639086374E728 /* t_x509.c */; }; + 4828389ED5801DF33D36DDAF0D60AB19 /* p256_32.h in Headers */ = {isa = PBXBuildFile; fileRef = E9EFF4C4B9DF5E0341500D3BDD455CE8 /* p256_32.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 482A850322C280BCE092BC0F5C8405BA /* CNIOLinux-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EAA8959B66C811A04B4320E8DA8D7628 /* CNIOLinux-dummy.m */; }; + 485A98918677B2F9846DD8FA43F3ADF4 /* DynamicHeaderTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F335D34944F3E6119B5E507E77BDEC /* DynamicHeaderTable.swift */; }; + 4867A79B1558BAEF4BD4C3D5EC042A8C /* t1_enc.cc in Sources */ = {isa = PBXBuildFile; fileRef = DAA737D85B90547148EA523BDB9C67F8 /* t1_enc.cc */; }; + 48920AFFC7C0E2FEA632DAA2BD63287D /* SDWebImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BBC73AB7289510464AFB5EFF44C43FAD /* SDWebImage-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 48A8A612910DD25151B7DB44BB66D3FA /* pcy_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C4F50D1510E1DDB79006E5CC71F205C4 /* pcy_cache.c */; }; + 48C73436D25ED04DE06C887714312F3E /* MultiplexerAbstractChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2FE0034D8005E82F47B9AB3C43969B /* MultiplexerAbstractChannel.swift */; }; + 48ED5F872612BDDD09B72C499200B8DE /* HasRemoteSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE70679AC03E0FC6318978897996424 /* HasRemoteSettings.swift */; }; + 492185AB514512EF8E6A30B311641523 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B136E798B4E73E57A5A5FCC779C6FF2D /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4928E2AD23275D08BB262C3546D0E086 /* WalletUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C8FA7659DAD9BA5584AACB46E8140C /* WalletUtilities.swift */; }; + 4941BBDC75993BC4EA64F2D71C4434E8 /* HTTPTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EEB202953F639113C26DB38D5381833 /* HTTPTypes.swift */; }; + 495D1E4BC683C5D93F1837C5D2CB66E5 /* ecmult.h in Headers */ = {isa = PBXBuildFile; fileRef = A1125F1577E36499C027A5A9272733CD /* ecmult.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4968417FBF31E5D093DA26F044D4744B /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6180C78B00D01DE7E8304F0223D7EC39 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 49784491DF6681E08E3AEE84E98A3C42 /* curve25519_tables.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A245C7712673F309BB6780D129E133 /* curve25519_tables.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4979CE34D784A50E49B5B5BECE0A5AB5 /* ConnectionManagerID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08D128A5B7DECFFA30FE718DD3540B3E /* ConnectionManagerID.swift */; }; + 498AB54D6531F0B57EAAD113AA0CF0F9 /* SDAsyncBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 306A34EEB7DC87E36AFC5C3247F4E4AE /* SDAsyncBlockOperation.m */; }; + 49D5D7867AFA4533EF8193A80185AC8A /* chacha-armv4.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 8317596C69D387B4AA90D6E8E6EF1BF3 /* chacha-armv4.linux.arm.S */; }; + 49E0EED639D3861CBB10D9BA3E7C5451 /* Interfaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC5763D6A87662250C6ADCCEE75095A /* Interfaces.swift */; }; + 49F97D8BA4E81A5E0EF866A293392AF2 /* SDWebImageDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 699ED647324E1C44560B50FED10A26F6 /* SDWebImageDefine.m */; }; + 4A21B8CD44BDC8E66C6014B607CF44C1 /* Prime Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = D561F1333FD64F4F25B777E77E28522F /* Prime Test.swift */; }; + 4A27F890C33243C4548A25318264B375 /* UIImage+ForceDecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F757CFB8F52CE330E5561E43BAAACF8 /* UIImage+ForceDecode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4A2CBEDEF036B20A7C990A2730D64C3C /* MessageEncodingHeaderValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98CFC661373BA9730BCC13E2E1F61B8E /* MessageEncodingHeaderValidator.swift */; }; + 4A2E859236B917B1EC38CB3337EFBF08 /* ServerHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F266418CB8BCC7A3BA24AD0C5A06BAF0 /* ServerHandlerProtocol.swift */; }; + 4A787352B4D5C3D906F51A18246FC565 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1477C5AA1AAA188540A3BFC4FA21B928 /* Signer.swift */; }; + 4A98BF03DBEA2BDEAD0B3ECCC3975F0D /* p256-armv8-asm.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = A69622B5F3DF7E322BD0DB1E53CE75FF /* p256-armv8-asm.ios.aarch64.S */; }; + 4A9CD656B01029C96194280307260759 /* StreamChannelList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98D59B2FC57B2209A63E822B13AA4C3 /* StreamChannelList.swift */; }; + 4A9F7B7755F8A2EE66EAF13A15749B96 /* CNIOBoringSSL_is_boringssl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C9AF29710BD67F5A4A26E24F9B09020 /* CNIOBoringSSL_is_boringssl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B085F1FDFD4ED3ED0F46B992AF7E0BB /* PopupDialogDefaultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF8E38A6C86993609FD23CD53FD060C /* PopupDialogDefaultViewController.swift */; }; + 4B0CFBD848C6E74B26D2728487E9DE32 /* ec_montgomery.c in Sources */ = {isa = PBXBuildFile; fileRef = 3B1D90298B7591466F5ECEA71DE9F898 /* ec_montgomery.c */; }; + 4B364FF25C5306DFADA83D2D76AC09FC /* CNIOAtomics.h in Headers */ = {isa = PBXBuildFile; fileRef = C424F70C6667E36112AD91D1FF8F46DC /* CNIOAtomics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B455767CB398A52EC2EB47E43CC04F9 /* URLSessionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40C9DD71B957910488093D4D1003D53F /* URLSessionExtension.swift */; }; + 4BBABCB240B62249A6070DF509A7DFBB /* cbb.c in Sources */ = {isa = PBXBuildFile; fileRef = 3E34D3D39BF3DC05FEBA1760D451BD70 /* cbb.c */; }; + 4CA0EFA43FDB50F927904E64D5AF57DB /* x509_ext.c in Sources */ = {isa = PBXBuildFile; fileRef = D2711FB3F56616A310BA4635C98D5817 /* x509_ext.c */; }; + 4CB3DC21B4147A401390ECBB934404B1 /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23DDBB141AC1C1CBD70DB81078C885CF /* SecureBytes.swift */; }; + 4CEF5A22ADCE5D9EB050845407BFA422 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6F36B910678D8E547D0C654844171A /* DataExtensions.swift */; }; + 4D3608C860CF3B95CF1FF4FBD88C8702 /* c-atomics.c in Sources */ = {isa = PBXBuildFile; fileRef = E6DB6B7AD7E5EAA5EA9B3C212BBC84D2 /* c-atomics.c */; }; + 4D39754498EB7DD1C3CAFEE31A9D918B /* ecmult_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = D8A3BC28D5AFF50B3CF081A56F0AD709 /* ecmult_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4D57503805406F4CC28676B457ADD8D1 /* NIOTSBootstraps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB0B628CE279EFD3E1BB98516E402AC /* NIOTSBootstraps.swift */; }; + 4D756B1039718931B1EB6E3F93334FF9 /* self_check.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D5FE45BB35F7C5F6BEA5A13BB220B /* self_check.c */; }; + 4D7599267DAE9AE608BF7491DAC8B5F5 /* HuffmanTables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 275805B9428E3EAEBAAC2086BF1F4720 /* HuffmanTables.swift */; }; + 4D8E40DA9C634BF4711D776563937111 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DF2B71AC6C25CA17AE97DDD49CD7E3 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4DC032894868226AE220360BADB2C237 /* SVProgressHUD-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DFBAC8F5B391B91A2CF90C493B6F1E41 /* SVProgressHUD-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4E1BF46BB4A52452D22D37E79A7E60D2 /* rc4.c in Sources */ = {isa = PBXBuildFile; fileRef = F6801817E0996DB2058C8F032BBEF622 /* rc4.c */; }; + 4E5F8F25AE9C665A1B68F7DBBA87940F /* ssl_file.cc in Sources */ = {isa = PBXBuildFile; fileRef = 50D5CED640DEE11BBAA33C46AB1A9DD7 /* ssl_file.cc */; }; + 4E6BDAC26F53B9D533928A1C4AB0C2C5 /* CNIOBoringSSL_pem.h in Headers */ = {isa = PBXBuildFile; fileRef = C260B43A2350E61901AD4EAE6A63EC2C /* CNIOBoringSSL_pem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4E886EAD99747CBEA13F5B83A07E10DB /* GRPCTimeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD67DE4C7F0D195290FB9B1CD3FA05F /* GRPCTimeout.swift */; }; + 4EB3F1296EE4B577E02B8651CB3B64E3 /* a_verify.c in Sources */ = {isa = PBXBuildFile; fileRef = 1F3D03A413A633F04396541E48627005 /* a_verify.c */; }; + 4F5982101CB9FB68613E826F137B5E95 /* SDAssociatedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B89A2EA9C362A77FBCA5E4BDF5E4F69 /* SDAssociatedObject.m */; }; + 4FB353F2B2E7D7AE0811D7C538DA2B36 /* SDAnimatedImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = C19C39C799D0670D4B7753B7373C54A2 /* SDAnimatedImageRep.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4FB462800158909068B7A27D83E802F0 /* Zeroization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2333C8CE8E8B8A2E2CEE465FDE578227 /* Zeroization.swift */; }; + 4FB7368C14F3EB36D7DF25D267A6FB8A /* SSLConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DCF94245EE14B9D234181E1B22FD7C2 /* SSLConnection.swift */; }; + 4FE85020FA9539B37E30602C5096EE60 /* asn1_gen.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C149DBAE7FF996B43634962F24F3C27 /* asn1_gen.c */; }; + 4FF5A864D3607F7061817866CC8022CA /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736863024538C0336937C1263FBC4B9 /* Dictionary.swift */; }; + 4FF8138ED7EC99F88EA1434B8138C7F2 /* RefBlockResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F922BA79034FCBFFDEF5221E779C3BBD /* RefBlockResolver.swift */; }; + 4FFB10F8CB368E03F334BCE0D2A311E9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 50A1348C46C8AED836CF761E02F27A4C /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6E01B5DAF6B4CA74B4852A157A8805 /* Blowfish+Foundation.swift */; }; + 50CB192CA68D75DE5F793D0BC87F166C /* pmbtoken.c in Sources */ = {isa = PBXBuildFile; fileRef = 6763E9CF3A1C3076164F2C922B83431C /* pmbtoken.c */; }; + 50F2A5DBC1D6D5425029C9B6B3CC71FE /* AuthenticateMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D1A0FA4B06F24C3206B6E8ECC38062E /* AuthenticateMethod.swift */; }; + 511B8BDB8C401CD5A276530D7BD67258 /* HTTP2ToHTTP1Codec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FC57450151C39D180A7DE70D0C807AF /* HTTP2ToHTTP1Codec.swift */; }; + 5151ED5BAA1A285E87EC4D504E38CCDC /* type.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1CFB827F779CBE90AC1D2BBEFAF94EA /* type.pb.swift */; }; + 5154CF227555E61F584EFB393DC39E33 /* digest_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = 8F01808D47405EE897EAA5274B62488C /* digest_extra.c */; }; + 51869257D458739CE3A3D020FCDC6C58 /* ecmult_gen_compute_table_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 288D1967128600890475281F1DE4AF11 /* ecmult_gen_compute_table_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 519B33DCAE0FB73CC313A2C2AD434449 /* SDImageCoderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD2222DD9CD658D62F87B34C0342A0B /* SDImageCoderHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 519D50F11F4EE3378085EE282D0894FC /* aesv8-armx32.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = C47B78C19988CCCD0806027F63B5CAEE /* aesv8-armx32.linux.arm.S */; }; + 51A720B6500C8729D426923A3A3D173B /* SignFlowMessageMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 542C6DB9D65205F8DE75FE1C5ED21018 /* SignFlowMessageMethod.swift */; }; + 51F4E301047801A09A37B8A049F66427 /* ext_dat.h in Headers */ = {isa = PBXBuildFile; fileRef = F2F8FE0DA2B701325F9AE8CD81D9ECC0 /* ext_dat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 51F891EA712D8F14CF1DD77BF20B62A9 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BF0600E7181F289680078246C28D8D7 /* ImageIO.framework */; }; + 521401BF1E6FA6B3BD67B4E8D286D68E /* ber.c in Sources */ = {isa = PBXBuildFile; fileRef = 24F21E455C17C94138FF860D25DF2215 /* ber.c */; }; + 522F14B172BBFF77FE8C11781E046839 /* CNIOBoringSSL_rsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD4898DA7882FF64EA7BBF472DD0FEC /* CNIOBoringSSL_rsa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 523861A018452CE8BB166B59A7872BDA /* SDImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = CF1F5D93B023F71A05A4ED03AE04E4D7 /* SDImageFrame.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 52393A042FB7C220709E5817F08479A5 /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C684847AD03E2C92EE6DC36358B8005 /* printf.c */; }; + 5254EA375DC1CA76FE44095887749177 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 169D6C71568363DA1999B117D896AC68 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5269E0AF4A9F6CBC34F5D7B8C45AC27F /* chacha20_poly1305_x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 09E8238E00364F2B31B6E0428BB5C690 /* chacha20_poly1305_x86_64.mac.x86_64.S */; }; + 526E5E8A0138F67AE41A49DE2D02D737 /* tls13_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7F9AA16751603F0ED1D7D6241CBE2549 /* tls13_client.cc */; }; + 528FC3273A41C006C06DF1ED9702070B /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4261559F8853764054D0325731A6DDA0 /* ZeroPadding.swift */; }; + 52BCC3B2F8AE7F59556925DEC603C634 /* SVIndefiniteAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F2A68C667C54E3B7561491056754A87 /* SVIndefiniteAnimatedView.m */; }; + 52D559F996AE40546BC6B29632614E63 /* cpu_ppc64le.c in Sources */ = {isa = PBXBuildFile; fileRef = BCD389D31F30FBD3A0E3D7DDB3273254 /* cpu_ppc64le.c */; }; + 52E4D58F0CF4344DAC0637B9B5B75BCC /* pkcs8_x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 6A4BFD29442A54F99DEFEAD99DCE208F /* pkcs8_x509.c */; }; + 536E9C0D3855A6AF7CADCB9FBAFC613D /* SDImageIOCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F64C7779258BC4F72C9B5527B4AD9A /* SDImageIOCoder.m */; }; + 537B0195EF2A345A27DC0043F5053482 /* FlowSDK-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ED5164774FF7BFEC7AED2C9C68CF8D2 /* FlowSDK-dummy.m */; }; + 53BECA6AA55F80D63F104475EE6524CA /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DDD8BD3738991F903CBD2F231644C87 /* QuartzCore.framework */; }; + 53C40EF2BAC7F4EF8A334476A545C398 /* JSONRPCFraming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F5C098A9215008584059ED9E540D4 /* JSONRPCFraming.swift */; }; + 53CAF4D42094B8A0AA0FE2AA5BC818DF /* StaticHeaderTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BBF3EED4F75438552D9EB9017EFA8B /* StaticHeaderTable.swift */; }; + 540CC89836D830624883860F4AD3EAB0 /* Floating Point Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2E804978DC1D481FCB239A99226BB /* Floating Point Conversion.swift */; }; + 5432647F174FD713AD006C79866D2F50 /* dsa_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 0B3959585FF35CABC0E8BD2E19A0EA98 /* dsa_asn1.c */; }; + 5436A3AEA6342F0D82D945BFC89189AA /* SocketOptionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B329999DE3EE0D8E00FA0D425AEFC3 /* SocketOptionProvider.swift */; }; + 54855934F4CB99C4C12123DE349A1D5F /* poly1305_arm_asm.S in Sources */ = {isa = PBXBuildFile; fileRef = 871F2A38AE8AC9376E3561F36772742C /* poly1305_arm_asm.S */; }; + 548A1EF62DCFDC73212C81132753BC4C /* BlockEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECE7EF9FF98C339A92B8CAF8E2EE2080 /* BlockEvents.swift */; }; + 54F1F5EEDD0CED79BADEFAB5998DFE16 /* SignatureResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ECD758173A4365C3AF953E56F0B3C80 /* SignatureResolver.swift */; }; + 54FA85CE73D53DDDCC531C226A12686F /* BinaryEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08936EC14856D906A7C6AB50A157FA60 /* BinaryEncoder.swift */; }; + 5526D75473578EAC2B1EA77E29B899D8 /* ServerInterceptorPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1095271DD12AFF9F7DA342ED0452BF3D /* ServerInterceptorPipeline.swift */; }; + 5566250BAD657877EA12FE06021FDEE4 /* ByteBufferBIO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B6893083FF0DBAB17C2B696B72CAB6 /* ByteBufferBIO.swift */; }; + 557F49253B5D3A0F60392265287B3CAC /* CNIOBoringSSL_asn1_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A126BD214790EE4C1CA42E4A387311E /* CNIOBoringSSL_asn1_mac.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 558879C27D5562A3F4048F33FF75F9AC /* GRPCChannel+AsyncAwaitSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = B495EFFA32E7E62E2FD0AB0F689098A6 /* GRPCChannel+AsyncAwaitSupport.swift */; }; + 55A7E844E2375D632EC293FFD4026998 /* CNIOBoringSSL_pool.h in Headers */ = {isa = PBXBuildFile; fileRef = F1D3285305DE04F9777C0854D000D062 /* CNIOBoringSSL_pool.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 55D3C00883F2CA52FE8F11468E97CB50 /* Division.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96EF442F0D881078905BD87375142326 /* Division.swift */; }; + 55F866048AAF4BBFDBE746557B41620C /* BlockEncryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5F94CB3C154047CF825DEAEB6199D19 /* BlockEncryptor.swift */; }; + 56244090576E9D57C3CF597292EFCE2F /* IndexedHeaderTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E358977EBFBB1B19A411BAEA76FA770A /* IndexedHeaderTable.swift */; }; + 566329068166F7AC2F01D0E9794B67A2 /* x509rset.c in Sources */ = {isa = PBXBuildFile; fileRef = B6C53E0C38272AE6FA2E8E5C35C9046A /* x509rset.c */; }; + 567AFBE7D3BA44F61600619310EC5428 /* NIOThreadPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BAAE75DEA3771B8E9934450CF53138 /* NIOThreadPool.swift */; }; + 567B00754C874C109A355462560C2B67 /* chacha-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = F854D5B6B19CCABE0F70B1C6422DDCD3 /* chacha-x86_64.mac.x86_64.S */; }; + 5743C484AED63266D4D78E4A4C74DDCF /* x86_64-gcc.c in Sources */ = {isa = PBXBuildFile; fileRef = BBF794238B05307E3AE72845744E0D06 /* x86_64-gcc.c */; }; + 5752D404DFD7D35214D328F5954B2F5C /* engine.c in Sources */ = {isa = PBXBuildFile; fileRef = A8D66AA126C6C94A62B4E3B3EC35645F /* engine.c */; }; + 578AD332DA729456829E38A9F50AE454 /* BSDSocketAPIPosix.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF9AC5693C5E7E568C3EB0077AB198A8 /* BSDSocketAPIPosix.swift */; }; + 57CE164539CF32C51BBEFA21F1882B06 /* ExtensionMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76407BD8DC1F3FEEB7055E348E01C2E1 /* ExtensionMap.swift */; }; + 57E1C476BA5F8DD1ED740FE8DBC05D8A /* SDAnimatedImagePlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = A5B1D4B342D8E17E058E8805C0793856 /* SDAnimatedImagePlayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 57E3D9C77D4BF46D20B4623A77756EF0 /* StreamState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74DE4695C579F6E61573FA510FB21B08 /* StreamState.swift */; }; + 5801E6D9947415534B4CFA8BE07B3EAF /* BloctoSDKCompatible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 864D6FBF48B8E33BA48229F0FD5D8D21 /* BloctoSDKCompatible.swift */; }; + 58228B08AEC1167F0FC1465776665F9A /* ssl_stat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7A847BA2B6D042C77880F1099B20995E /* ssl_stat.cc */; }; + 585384668E02C5616D34FE90841E416A /* siphash.c in Sources */ = {isa = PBXBuildFile; fileRef = BB2B48DE63C63DFDCB60CF127640A4DA /* siphash.c */; }; + 5864DCC2F17C09A9092B478ACA788C57 /* ByteBuffer-views.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D2F5F9D2EBCABD0650C3DD9B6F124B /* ByteBuffer-views.swift */; }; + 58755350E5AC41820A0DA740D7586134 /* NIOSSLClientHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15847CFE3042952A3D46C83B0DD8A25F /* NIOSSLClientHandler.swift */; }; + 58AD1F9789AD2EF060E774EC081BDD75 /* aesv8-armx64.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 7BC31F011248F16CE3E77E3F25508401 /* aesv8-armx64.ios.aarch64.S */; }; + 58C653C980692BFEF073B7DC904A3544 /* EnumType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F6E98384A8607B14786C60260DA7E7 /* EnumType.swift */; }; + 58FAE3A59FBE896EBBDACB0808067CA5 /* SDDeviceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EDB2F023E8D4B7137FED7F6A435C3787 /* SDDeviceHelper.m */; }; + 590B3598D1229E14176826E4582E2AC1 /* AccountsResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FDB16E285BA44509CA04F4CA63E699 /* AccountsResolver.swift */; }; + 591C624074BF9F241A5F1B5D9A562865 /* ecmult_const_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DB89C0E4A195E152E33D752C7ACFC25 /* ecmult_const_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 598831EFD3048806C3FA3AD56ACDF54D /* ServerStreamingServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E25C008B16D40841525DCD017034D7 /* ServerStreamingServerHandler.swift */; }; + 59927BD986ECD57C54DAE6FA61A67DE4 /* CNIOBoringSSL_base.h in Headers */ = {isa = PBXBuildFile; fileRef = CF33312D7AC69B54F5B685FE2F46D2E6 /* CNIOBoringSSL_base.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 59B4C57BD8E265F38A6FD43D66D36184 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B1418F069305E2B7F2CA9ED5AA56C3 /* BundleExtension.swift */; }; + 59C1D83E821E6E9A977038D530FAAFBD /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 831C0F957479585F1A8681350E2F1960 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 59C374DEBCDD66228552DDEACF5A3D42 /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2C1A9AB12ADED76780A6D05E37119 /* Bit.swift */; }; + 59E68E35F43099496FFF47D0A675E7B6 /* event.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AC2EC3666BF3283F5E15A69EB7D3B5 /* event.pb.swift */; }; + 5A24F1977DDF7783E072A05DD63976F5 /* UIViewController+Visibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA162300774D9EC15AE362843239196 /* UIViewController+Visibility.swift */; }; + 5A28263760C842A7FBDEC80D177BDE2A /* Embedded.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A47A564F560312A0F9EE315068D3F09 /* Embedded.swift */; }; + 5A3E5B854E8188DDF4E958BBC9198600 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 5ACC86B4D6F34E04125A0D77F340BB3B /* x509_req.c in Sources */ = {isa = PBXBuildFile; fileRef = 99DB7853515659BF0940D0DB249CF962 /* x509_req.c */; }; + 5B1AF207A52B7481DA036541E7A4BE8B /* BlockDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D83CEE77E716014FB275733BCA3AC0 /* BlockDecryptor.swift */; }; + 5B3271A67137276C4B2CD554BAB9F4DA /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 8020F5D5CC03C195103D0A77D1AB1062 /* UIImage+MultiFormat.m */; }; + 5B381340C3C8973E28F7A52B552C661D /* CNIOBoringSSL_aead.h in Headers */ = {isa = PBXBuildFile; fileRef = 6116A87F1DC0388E72BF1318376A9A8D /* CNIOBoringSSL_aead.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5B47C9724578CB56CC6F1674AC585807 /* main_impl2.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B0554ECD8C9BCA36CB6736F494816F1 /* main_impl2.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5B4A9D9A0F84E0C13B7C112AB24F0F28 /* convert.c in Sources */ = {isa = PBXBuildFile; fileRef = EEFFA244AF2F7CB9F637B306CE1884AA /* convert.c */; }; + 5B581E49E611950BDF0E77F3CACF5A6D /* CompositeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CA88BB7B03385B102806F68F723F32 /* CompositeType.swift */; }; + 5B69919844A3BD774BAABB186D6A524F /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 75EE6C6825E074E05328C99223303166 /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5B98F58EB26DD61ACB7FE670AF9DDB64 /* FunctionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C93C63BAF9ABDE8D9F8A517D0B3E81 /* FunctionType.swift */; }; + 5BBE7719912593F1DEFF8E763EAD4ED6 /* SDImageCacheDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 277FEA5A1CCAD8C95A06EA8BD6BA4EFC /* SDImageCacheDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5BFC5248FBB5CA1D66A13019B42A0320 /* SSLPublicKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A95A53CE558FD0A98C3CC52BF080A1F /* SSLPublicKey.swift */; }; + 5C02F2E4DEB3835B3E55301FA83178C9 /* scalar_8x32_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 07424D645F2E9ACEEF471C2D45E734F9 /* scalar_8x32_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5C3E4CC39E3E51B53B6A01E2D5120F23 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 81AECAE46BD788C0FA0E5735F9D8C082 /* Images.xcassets */; }; + 5C54A4A3171049D05DD20D4F98CC133F /* Pragma.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AA449DC627A563D0622878274D245C /* Pragma.swift */; }; + 5C6C7057DFCDA946716D77D0BB391973 /* CNIOBoringSSL_bytestring.h in Headers */ = {isa = PBXBuildFile; fileRef = B659A48694C1451AC56E4764DE043F7A /* CNIOBoringSSL_bytestring.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C9A67CF785AC29AF1D3DD1D83C48462 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 573642D12978379632CF4F8FADF0BB41 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5CE971EFB830145250E66CACC6EF6B9F /* div.c in Sources */ = {isa = PBXBuildFile; fileRef = 8DDE2415D2CEFD7CE529F9EB805AE1B1 /* div.c */; }; + 5D10DE91A793CDB9660A43C1BF0313B3 /* execution.grpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2610510E35410963A2FB651DA639BA4C /* execution.grpc.swift */; }; + 5D1978794F6B1DDDFFF1EADFF75E72A4 /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006D290CE0E3AA073250AE2695602D44 /* IO.swift */; }; + 5D2A6D9E8022EA39F8D102FEE7426452 /* sha256-armv4.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 02D9B7644BF54ECC5C459FE5F0A4D8A0 /* sha256-armv4.linux.arm.S */; }; + 5D896C5F7B9287C84768CFC751B0C9F6 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8051E24E27FD90DF9CEC414E6B98F822 /* StringExtensions.swift */; }; + 5D973CD77F0F65F6CB752712B7674CDD /* Message+AnyAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693C7FDB3C518480EA1B432ED4461DF3 /* Message+AnyAdditions.swift */; }; + 5E05762975DDE5AF60856D7B2E83AA3B /* e_aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 64117CF438B850CA195E0F38D6F76C7F /* e_aes.c */; }; + 5E2E5766780F9E5C0D6B21CFCA40F4A4 /* GRPCAsyncServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99A84BF3728DC28D573570492FF1F6CB /* GRPCAsyncServerHandler.swift */; }; + 5E5A0CB52A65D92341CDA1AF56F138FE /* TLSEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABCC4970C4B371898F3166186E6F9B0E /* TLSEvents.swift */; }; + 5E6D8AC3B49F7D24358244E84DE04905 /* FlowMethodContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606F713E4CA5C57D75EDFA2ABEDBCA02 /* FlowMethodContentType.swift */; }; + 5EA63EE694223E347D3CB483F21C256C /* SocketProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41C43FAEA6332A1BE439A46C4F647CF0 /* SocketProtocols.swift */; }; + 5F119FF6E0035958CF98758B41801163 /* chacha-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 288CF90C4C2212F995F62D27D54D0073 /* chacha-x86_64.linux.x86_64.S */; }; + 5F2868E310528CCFB325CCBE126FA25B /* CNIOBoringSSL_evp_errors.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F2D9F2F28DC75871F1432985EEE953 /* CNIOBoringSSL_evp_errors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5F42403E65F979D69536C6413E959845 /* HashAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0EEBF7DAFFF2F7679DDA958B59770C /* HashAlgorithm.swift */; }; + 5F49C3C9A3733CD50642E0B57D405D44 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 014B4C27D85ADC3C511DAA45E701648D /* SDWebImageError.m */; }; + 5F4DFD9C2AAC52263A18763910088A77 /* pkcs7.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F9DCE64FEE0B4BE586CFAEB2F055774 /* pkcs7.c */; }; + 5F52CDA0F30AF57DE98CD95FA200A1AC /* NameMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0457317A2F98C0FAA8F58581A3B86 /* NameMap.swift */; }; + 5F7DDD0B418E98BC86553F8F34689CAC /* BinaryEncodingVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFEA6712F888607A1730D40B710E1D2B /* BinaryEncodingVisitor.swift */; }; + 5F8BBE3B833E4414E4FEC4F278BC20B3 /* QRScannerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5458105415C4E6D283CD649D22A132E7 /* QRScannerError.swift */; }; + 5FA575431BE6BD8ABE69A690BA4943AB /* LengthFieldBasedFrameDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660DC8D7B5079C83E6BF3CE126E828E2 /* LengthFieldBasedFrameDecoder.swift */; }; + 5FB06B78116762C93A87321002E2CD4B /* CNIOBoringSSL_curve25519.h in Headers */ = {isa = PBXBuildFile; fileRef = 701971BD8BCEF2402A37510E0BEE5103 /* CNIOBoringSSL_curve25519.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5FB701AAB2C475A80FBA13979F08B5B9 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96FB297C04A70F53F4B0206297549C27 /* Account.swift */; }; + 6032C795642C2EF4FE1D580FAB9DD4AB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 60543A3F48C7EE855FBFAC85E1506798 /* v3_utl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4FCEF474895FD1E1FEDC2B4A58A77FBA /* v3_utl.c */; }; + 60738B205D5C0788DE7B2E9C00207F56 /* RoleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3533A6CD08AF5725024A2238FD3F722B /* RoleType.swift */; }; + 6076364F0EB6528E1A89701575CAD8ED /* CNIOBoringSSL_opensslconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 2643C0596BCC8A98798192904EE5725E /* CNIOBoringSSL_opensslconf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 60AC910D52240D2F812E608BDAFBAA35 /* p256-armv8-asm.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 4548E0B0E2ED9F2EEF03049DE28D7C48 /* p256-armv8-asm.linux.aarch64.S */; }; + 60C03AFBB5A899CA40DBEBFE0267E1C1 /* CNIOBoringSSL_blowfish.h in Headers */ = {isa = PBXBuildFile; fileRef = 74AAFDC7CD7AFD70EF9B0540E439156D /* CNIOBoringSSL_blowfish.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 613E78E03E1E9B4C495283F08DA2C360 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B12017F089338B3E2DAE84CCF35DA50 /* UInt32+Extension.swift */; }; + 61620557240AB79D29D36EFAEF3536EF /* Codec.swift in Sources */ = {isa = PBXBuildFile; fileRef = E753CB8B7DA12B68CE4372634BD6037C /* Codec.swift */; }; + 61802DEB44AA7C04FA69284DF12CB514 /* ServiceAccountProof.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E02D00A3F9AD848D15406BF6A7A49B /* ServiceAccountProof.swift */; }; + 61C81E5D6706E0184347C7237B25F71C /* shim.c in Sources */ = {isa = PBXBuildFile; fileRef = FDFDAD50B9C60762A8D0B9C0536B97BD /* shim.c */; }; + 61CD5A24511DC980EFF397CF57AC50F5 /* SDInternalMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 2521D5239AD26895494922C727BB1151 /* SDInternalMacros.m */; }; + 61D475469B0DD6D8652EBD93E1345B7B /* ServiceIdentity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841D60008F5F770B313C006A8DFA67A7 /* ServiceIdentity.swift */; }; + 61D922EE85D8CE18443233D34D07ABBA /* socket_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = 8908B111120DA1E80ADDAE3AA27324C3 /* socket_helper.c */; }; + 622D4C39D9B07E268931459D70F8B43C /* handshake.cc in Sources */ = {isa = PBXBuildFile; fileRef = BE221C402A207197DC2799CBC4A0FF4F /* handshake.cc */; }; + 628FACAC8ED43F663F9D52984EA90BB9 /* GRPCPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67845E98E019276FA82E0785DDDA884C /* GRPCPayload.swift */; }; + 62A22A4C10675F9B65C7677CFD6C4676 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D36A06D692CD1593D7474074E83834 /* SDWebImagePrefetcher.m */; }; + 62B7FC1AB67641CA77E7C088EA4E1999 /* PooledChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65403732FF94C6E473686DD943B25626 /* PooledChannel.swift */; }; + 62C96961DEEA2FA4F262498F3D1B33BF /* PlatformSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 904BAB653CB9F1076FB673F402C78DAC /* PlatformSupport.swift */; }; + 62D02A250BFFC41A9CA41D71141D61F6 /* GRPCAsyncServerCallContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85FBB12A3222F572D172DB14751E94E /* GRPCAsyncServerCallContext.swift */; }; + 62D436F7476CADC46700E7F03469FCD7 /* Pods-fanex-fanexUITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EF348493FE6F399B33F6E4E0764E51 /* Pods-fanex-fanexUITests-dummy.m */; }; + 62DF4079529380369B2BB7386F22CF2F /* ClientTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB5AC65D86ECBEDFAD2CF7EF32DD974 /* ClientTransport.swift */; }; + 6373D7EBE71A274FA0B3E7C2AF9B18C9 /* pem_all.c in Sources */ = {isa = PBXBuildFile; fileRef = 926ADA1DC1706FBE131060E6C9790423 /* pem_all.c */; }; + 637661C78D6216FBDEC893AFF8AC2681 /* CNIOBoringSSL_mem.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BFF208CBA978EE49028C2CCBFFA9C1 /* CNIOBoringSSL_mem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 63A2B0DDF3407A20B8CA4AC4A59670F2 /* WSAStartup.c in Sources */ = {isa = PBXBuildFile; fileRef = 4F572B6F10A59CA774F9046854C9871D /* WSAStartup.c */; }; + 643AFEA4C7B86B04EFF5F942E6261224 /* CS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F5C53B14919489C35D8B006C24AEA4D /* CS.swift */; }; + 646F4915348FA769874FCF303A424AC5 /* cipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 7735873715F8E46AB2C372215EFEAEBA /* cipher.c */; }; + 6497E8C8D82E52ADDFABF0085356E6BF /* ByteBuffer-multi-int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5632E69283B9EC57F1BD922821CC8E35 /* ByteBuffer-multi-int.swift */; }; + 64A0464897D1C080467F35FE3389FDC0 /* ByteBuffer-foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61CDA0D8685E7D3CD7FE1286FFFEC4F /* ByteBuffer-foundation.swift */; }; + 64B43D4566523233D5EE198768F03492 /* QuiescingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B1DE3821898D0F8784CB1671EBF4AB1 /* QuiescingHelper.swift */; }; + 64B960D6E9E9C92C1DFFBAA5484644F2 /* UniversalBootstrapSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14C057D940A62DB7A534003E557095F2 /* UniversalBootstrapSupport.swift */; }; + 64CDB33E49BDBE16653C88756E26B8CB /* SDImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C9B64804E5A4ED733B833205C732EB /* SDImageCoder.m */; }; + 64E41914871F2A181FBFDEC999BDF86F /* GRPCChannelBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 729B1F8B32184B8DEB21E9CC93C3D27F /* GRPCChannelBuilder.swift */; }; + 6541F9F3AE7BFF4B80B53E90A2423F9E /* Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 688BEA52472D776443869462E1284ACB /* Hashable.swift */; }; + 657ADF9EE9934FFFF22CD148ED853F0D /* Composite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29FA795821AE0DC47490E02DE1710064 /* Composite.swift */; }; + 658E2827D037D0B0A2853EA7F7C4EA87 /* OutboundFlowControlBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EEFEF54C907113F6F86F4F48E57796D /* OutboundFlowControlBuffer.swift */; }; + 65A14A6524E0A8F1ABAAADBBAE0CC693 /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = AA9914C500C20DDCE0CFE379E7AEB345 /* aes.c */; }; + 65A29E177745762A8D9ABE06754C3AC1 /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EC63F48F6D767F3F3A0BF21AD9DB9B /* CompactMap.swift */; }; + 65A8FEA804F5B01C5A627024F472299E /* UIView+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2615582796F402C01E58DF1352B78ED9 /* UIView+Animations.swift */; }; + 65B8C304291077DAC3CC504A7FE41FD9 /* shims.c in Sources */ = {isa = PBXBuildFile; fileRef = 47DD2CA25279CAE9CE134398B7EFA22C /* shims.c */; }; + 65C4978314C56793A0D562632C9CE9CC /* chacha-x86.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 9B531A3455683AA7F96B0A480AA4F19F /* chacha-x86.linux.x86.S */; }; + 65E5CF094A4EF1FD8B0A9F11B2854FF2 /* GRPCAsyncResponseStreamWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C2F9D3B024AAF5570BB6D9D31F2CE81 /* GRPCAsyncResponseStreamWriter.swift */; }; + 66B0448EA8AECB87C3ECF93E36576D87 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC3BE4C1AD289339E860C9A67A5FCE5 /* PKCS7.swift */; }; + 66CD34BF7A48482B9CCC4F786B4E825B /* DispatchQueue+WithFuture.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8A6BA1B7B49FA8AAD4FD76EB06F865E /* DispatchQueue+WithFuture.swift */; }; + 66D24476F40B0EE147E89D6A6A878A18 /* CNIOBoringSSL_ssl.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A210AFF28F0967DF1250DA5D6F30295 /* CNIOBoringSSL_ssl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66D84E2A8E11B5A129331D777D1598BE /* des.c in Sources */ = {isa = PBXBuildFile; fileRef = BBEF31902CE95C276B59B842C4B48F38 /* des.c */; }; + 6722DCA670229327597ADC3D81BB492B /* BigInt-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F20911E8F738725F1098D11A744D10 /* BigInt-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 67448894860AED1A1CF02861676FB103 /* CNIOBoringSSL_ssl3.h in Headers */ = {isa = PBXBuildFile; fileRef = 76D0C0B97E84363163E311367A65FD86 /* CNIOBoringSSL_ssl3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 67481BFD0E0E3FBEE77814B7995D1067 /* x509_obj.c in Sources */ = {isa = PBXBuildFile; fileRef = A718B5CE6BA2C99D08C87F557C7B2B5C /* x509_obj.c */; }; + 67A7C4A010994278ECA06D32770C5A12 /* key_wrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 167F7BD23ECC1417C82557643373AF11 /* key_wrap.c */; }; + 67A7F6B8AD4FBE5B8502087EAE0CFA28 /* Scrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87369BB0769E23EF24803F44A0F226F /* Scrypt.swift */; }; + 67B0CAAD8E88B9A2357C41E73EA2EB48 /* SDWebImageCacheKeyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB8935FD0D4655DDDEC773B7B4915CE /* SDWebImageCacheKeyFilter.m */; }; + 67B3DCBA30FDEDA18E0D4E3B2C16C911 /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 482746E8A1E48F9CA975F617D909F368 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 67B45FFF17232DBFBCBE36BFA67BFC29 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 258C74AC14ED4729DFBD81F79BC024E5 /* HKDF.swift */; }; + 6835A73143DA54E752A2B1B9C7DFCF6B /* PresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6014095D840DACF4EF8FF2531E2E542 /* PresentationController.swift */; }; + 687F29546854F86FD82EC6F30B00AC8B /* Google_Protobuf_ListValue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFEAB067865545587BA1DD5088599E0D /* Google_Protobuf_ListValue+Extensions.swift */; }; + 68920084478A15324A2C7E4B78661ACA /* ConnectionManagerChannelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183EBD613645D681F4B465B7D841374E /* ConnectionManagerChannelProvider.swift */; }; + 68F1948803997D4EAB1C83133763BE08 /* CNIOBoringSSL_ecdsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EBBCBD31CFEA671C4DC08DA393EF1BA /* CNIOBoringSSL_ecdsa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6917678919D98CAE2E6EFAFA82A6C2A2 /* cmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 90E4167A20621BF7147FD29098C445C3 /* cmac.c */; }; + 69537FE1409498730C7BDEE75AC9CE28 /* Pods-fanex-fanexUITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 42C67CC7CB131AB7939B3A81F842DF44 /* Pods-fanex-fanexUITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6953C194CA2FDBE1AB357C5B04477FF0 /* BloctoEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10CFF73497998A64521A8977F6B9C268 /* BloctoEnvironment.swift */; }; + 69A186B2DA541D39C102E28AF01AAF68 /* OCB.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8D469CE10346D8B8D052DA3DAEE9EFD /* OCB.swift */; }; + 69E7229D084E4C32BD9D1111570E3B16 /* ResponsePartContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCAB0E52009B591A221259DB8DBCBAD /* ResponsePartContainer.swift */; }; + 69E87248F1AD8B478E3DC2C7EE62B715 /* CNIOBoringSSL_siphash.h in Headers */ = {isa = PBXBuildFile; fileRef = 19E9154058D129015C37FB0D1CFADA46 /* CNIOBoringSSL_siphash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69EA3F34D3F0E947DA259171A0CD1CE3 /* StateMachineResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BF8E20702878FA358112FB44B023028 /* StateMachineResult.swift */; }; + 69EFCEB36A220606180FDD81F3F314F9 /* sha512-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 9822C50FBD93EA3721F13BD2B0A8B553 /* sha512-armv8.ios.aarch64.S */; }; + 6A40DF1C404BBD84266915AD920DE108 /* JSONEncodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F25954EBE6DCA38CB6072D0C2538EF9C /* JSONEncodingError.swift */; }; + 6A479035AD915D35AF67A5E168F8A98C /* CNIOBoringSSLShims-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 919A1F050EB6C3A6737D3554B23721D2 /* CNIOBoringSSLShims-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6A6D768A74F8BFBABED2364907A2DF0C /* BigUInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 469DDA25BECAEAB7FC53F911528989DD /* BigUInt.swift */; }; + 6A75628664126A13B3357EA0F6475A99 /* rsa_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 239876020140DECD9541EF5A9B12F7B6 /* rsa_asn1.c */; }; + 6A9204974B6B064E5798ED763F5ABFF1 /* cbc.c in Sources */ = {isa = PBXBuildFile; fileRef = FFDC3033E57BC05599C5A99C4F1DD735 /* cbc.c */; }; + 6A950124DFAB3658C9C496596D95C4DD /* liburing_nio.h in Headers */ = {isa = PBXBuildFile; fileRef = EADFD74CB52F0ABEA2C40E3903C69CEB /* liburing_nio.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6AC7F87B410F5DF58D68D04F570D93C4 /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1BEA579A59439676E2AA53871A081BA /* Block.swift */; }; + 6AFFF39083764ED7B6783AD4364FBC30 /* CNIOBoringSSL_asn1t.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D8974AE36F98BE418E182C13540358C /* CNIOBoringSSL_asn1t.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6B5E2B5C200CD813C14261C73288075C /* SwiftyJSON-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D60BEB2C0F3EAB59348E0C1D13463871 /* SwiftyJSON-dummy.m */; }; + 6B856A2A524B09A99E7E81574A061FDD /* MulticastChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043AE59D361B71B5E48ECC54B7625B1A /* MulticastChannel.swift */; }; + 6B85A0F50B486198B6508EE519F4119D /* SwiftNIO-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A38B7CA9A787A9EB473D611E8A8F23C8 /* SwiftNIO-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6BE718F60B8AC6015559D89E4B4EF322 /* SwiftNIOSSL-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD35F75EC94D2373D47C9CC59435702 /* SwiftNIOSSL-dummy.m */; }; + 6C148C90EDC036C4160D5A80FAAFF1B1 /* err_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 009C115F9C8F1EBC270B2714D9C76DCE /* err_data.c */; }; + 6C3F1FCABE4B67F89FA6816BBF706326 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 251AE8F2B12EC0B82DE04BDCA51B97EA /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6C435BB27EAB8F4B8EEB841DF30FA01F /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 688410218F9477BF03CC02672B5D29E3 /* StringExtension.swift */; }; + 6C6B35C6E4A5EC4C0D001DF311C5BA59 /* x_attrib.c in Sources */ = {isa = PBXBuildFile; fileRef = 7F1BA82BD02D495DD5171719767560FE /* x_attrib.c */; }; + 6C93ABDF963DDA7C78AADD9F22CD5CB1 /* NSBezierPath+SDRoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C640988E3E214D1F511AD59B5086A3 /* NSBezierPath+SDRoundedCorners.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CDC7602E4FC35165BEBAAB8D20DEA6C /* SingleValueDecodingContainerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0ED1ECFBE441E1197964BD40E28F12 /* SingleValueDecodingContainerExtension.swift */; }; + 6D09754C1E727AB5A25828F276F8CB58 /* ConnectionPool+PerConnectionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 980C4FDA16712B01699898BC0D207423 /* ConnectionPool+PerConnectionState.swift */; }; + 6D1E33469FB8FBE812956B0076A7B28F /* SVRadialGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 75403BA0717E47809896A2101A23F3F2 /* SVRadialGradientLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D219D21CA5B7A3E4714F35C92A22332 /* HTTP2FrameParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21CB70AC2EA6F4EB47A967F465F212BF /* HTTP2FrameParser.swift */; }; + 6D315B3E273D3557B8321C25270D4399 /* trust_token.c in Sources */ = {isa = PBXBuildFile; fileRef = A3786BF0BD05B585EE84F25EED9031FA /* trust_token.c */; }; + 6D6AF4306636FDE7A760177C49B272DB /* ByteBuffer-int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567DAE15E7F0276F6621B62348EBBFD5 /* ByteBuffer-int.swift */; }; + 6D9B484F5CAFE7618800F617B7CCB251 /* Message+JSONArrayAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F6D7D0E5BCC5EAEFF300B35435A85 /* Message+JSONArrayAdditions.swift */; }; + 6DA8B06D829E22F50025A899894EDB90 /* HTTP2FlowControlWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 380BE38C5A780567380E7CBDD33D7E9A /* HTTP2FlowControlWindow.swift */; }; + 6DDB62C833FF89AE8452990561387B2E /* ServerInterceptorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = F06E3F0F68E87986C37B89E07CB61626 /* ServerInterceptorStateMachine.swift */; }; + 6EA8F20EB99AD5C1BE905406F2951673 /* FieldTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = CADC67C899E5C65F088281C441A35555 /* FieldTag.swift */; }; + 6EB2C4B594B05A3A764B23442E4B5E09 /* modinv64.h in Headers */ = {isa = PBXBuildFile; fileRef = 807F99CF0921EFD7AAF68E2FFACE71BB /* modinv64.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6EC717982CD95A70F4F49D51E0459438 /* SwiftNIOFoundationCompat-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D15728B7F7BDD59F3421E167B782156 /* SwiftNIOFoundationCompat-dummy.m */; }; + 6EF3029DB9EEC014CB1DCBEE0B1B1BA9 /* jacobi.c in Sources */ = {isa = PBXBuildFile; fileRef = 113398F397A4A27D8E9FFEE9D0AE4AC3 /* jacobi.c */; }; + 6F036122F16E5FBC921C3C593B4C3D58 /* CNIOBoringSSL_cast.h in Headers */ = {isa = PBXBuildFile; fileRef = A69EBE0C9607A625092F94878F438ACB /* CNIOBoringSSL_cast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6F179152D94A49F7A28626BE73A1B8BF /* NIOFilterEmptyWritesHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C793CAD5D4C08E9EC559EB44F6F4AB39 /* NIOFilterEmptyWritesHandler.swift */; }; + 6F196F59B8B71F355DCF7451CDFC33DD /* HTTPDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF6F34E0C0955CF1A878FF94E52AFE0 /* HTTPDecoder.swift */; }; + 6F2F1E12BD5D187DB9255732FD24BB8E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 6F3A8A7781B3B803292C8B904538D45F /* HTTP2ToRawGRPCStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97962E42C217EF60D24440D061F34DE /* HTTP2ToRawGRPCStateMachine.swift */; }; + 6F4B172730B7293C1D988FBE34B45E20 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 672487A4A912ADC41F78EDCDA947B52C /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6F5A9E4BF5C6100234CBEE4AF697B8EA /* sha512.c in Sources */ = {isa = PBXBuildFile; fileRef = 9711B7C6751DB7169E30AC2344DEFFBD /* sha512.c */; }; + 6F816C06926556C18A038ACFA0E2B6A6 /* SelectiveVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E42A345459393C420965B5E32F38D3 /* SelectiveVisitor.swift */; }; + 6FB6FD26A9C75AEFB3BD7FF6E52910C6 /* gRPC-Swiftp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B9A298482E75869E1ED00F8077386B3 /* gRPC-Swiftp-dummy.m */; }; + 6FBD3CC7CC1566D7EEE33A1A513AEDE0 /* CNIOBoringSSLShims.h in Headers */ = {isa = PBXBuildFile; fileRef = FE25F61CB7A64F0BDD6A737277034E91 /* CNIOBoringSSLShims.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6FC650859642FECFE05B108117CD5E04 /* utility.h in Headers */ = {isa = PBXBuildFile; fileRef = F93F9A99AE614D69C0F64C977EB127AE /* utility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6FCB9936F3CED366B0F61F27D1CF57CE /* HTTP2ChannelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BAA52FF2A5C1EBA66F5466604F5601 /* HTTP2ChannelHandler.swift */; }; + 6FD394C7F605CB68DAC815DFFB65552F /* testrand_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 77FCB4602CFB8CFE7B1942923867936A /* testrand_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6FF4C47BC28EA09CF1EE35124D42C890 /* CNIOBoringSSL_srtp.h in Headers */ = {isa = PBXBuildFile; fileRef = C270E8AAEC0C71BAB6FECCB12F46B555 /* CNIOBoringSSL_srtp.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7018B5FF9DD5D93B9A728AF6ACDFE2FC /* SelectorGeneric.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACC4D4A7F4A5D8085AC922873268066C /* SelectorGeneric.swift */; }; + 705ACB6C225D1E6B5F594ED1CC53FA22 /* evp_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 38BA9B5FEB9C039329AE2A15D4D42739 /* evp_asn1.c */; }; + 7090F68043DADD044880B9A4DDB571E7 /* BigInt-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 00BB1D33B406DC76DDD4359DA00B8353 /* BigInt-dummy.m */; }; + 70A9442BAA644D89EBACFA20F5C038D7 /* StringUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C489C72417D9363D5C7D75F9A1786E7 /* StringUtils.swift */; }; + 70AD166AB8AE0891F544A819A74ED95E /* aesni-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = E3115F95805159489F6A96D13A4B6B0F /* aesni-x86_64.linux.x86_64.S */; }; + 70B19CD939C0082AD128D6463E73F3E0 /* pool.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C1D5CAB4128265FE20FCEEBB65A1CA9 /* pool.c */; }; + 70D4769F68D38AE475B80AC65508BA86 /* pkcs7_x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CA8A516E5D26CFC3E0BBE41525B3EC1 /* pkcs7_x509.c */; }; + 712A08906486C430CA5E724471995301 /* DynamicBlurView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 63647EC3A1665A41F433DFD09501F254 /* DynamicBlurView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 71B96E3F1B30FBFED16852B84B89781B /* CNIOBoringSSL_hpke.h in Headers */ = {isa = PBXBuildFile; fileRef = 89335E424E816A8DC01CC0ACDD434A43 /* CNIOBoringSSL_hpke.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 71E9350415664018344326E82F76017D /* struct.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F7A9500A6630A2CA8CA115E055B0062 /* struct.pb.swift */; }; + 72203F70B7769F4CF61A67039D9C974D /* a_type.c in Sources */ = {isa = PBXBuildFile; fileRef = 866B08232B96F5B9DA341EC4C127988E /* a_type.c */; }; + 723E1B6BBAE628C58E990D408A90C129 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4527FDF828AF69BDCF723726E37DE46E /* PriorityQueue.swift */; }; + 7241A8BAE8411A4E7DCE5B1759F1C89E /* GRPCIdleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C982DE04B6EBE96FCA55C8F5E6BA4D3 /* GRPCIdleHandler.swift */; }; + 72784E2069423F893C44C1F05EBEDCBA /* transaction.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C19014ED3BF4FE7F33FD701C930DB9 /* transaction.pb.swift */; }; + 7285377A3D573AD10BA6ADBD4F88B87F /* rsa_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 2E922A1CEE4EAFE9C8F97BD271F6A11F /* rsa_impl.c */; }; + 72A2E1CB3A9C7EAB39968D502638481E /* NIOExtrasError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50620683857F7039ED3A222630547C53 /* NIOExtrasError.swift */; }; + 72AF36CCEFB67D3E56E57DFCC7FDED1C /* HashAlgorithm+Cadence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6659279DE10A5C642FEBD858FDB74F /* HashAlgorithm+Cadence.swift */; }; + 72DBF2E878F4DDD2283BEA3C1D87CFA3 /* ecmult_gen_compute_table.h in Headers */ = {isa = PBXBuildFile; fileRef = 88A52EE3F3AFDBB44C3592AD31A41FBD /* ecmult_gen_compute_table.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 73467864F7509005F7F7E2C0A24F824A /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC58E07BCA5C6D8154968ED29DC0EF8D /* Array+Foundation.swift */; }; + 7346D424959BC2E7D1384AF6C76FCAAE /* Addition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D850324603466D1F86860D5F3BBC78 /* Addition.swift */; }; + 734B4EC7674E9C9F6758ECD07FE3C180 /* a_bitstr.c in Sources */ = {isa = PBXBuildFile; fileRef = 2C71484685488673050E878779E16406 /* a_bitstr.c */; }; + 735D6864E8D81ADD0811DF8EFACB4BAB /* BinaryDecodingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E02396B0223EA2822BDAF9522B514F3 /* BinaryDecodingOptions.swift */; }; + 73D9823E4035DA1316DDDA9B68A78A68 /* CNIOBoringSSL_crypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 924F1FC918F274DC38CBFFDA178B3404 /* CNIOBoringSSL_crypto.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73DBA4269C02A006834B8CE9FA6349FE /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04815858CB98C03EA5F95A2A932CBA5 /* Errors.swift */; }; + 73E1178AD16F91C80A718FB778F3534A /* Strideable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FEE4D1BBD78901D1C2429FA30F1EE0 /* Strideable.swift */; }; + 73F2DE8B48DC2F7C87529AB3901B9E94 /* UIImage+Metadata.h in Headers */ = {isa = PBXBuildFile; fileRef = E994D5025236EFF6DADE574DAF5538F2 /* UIImage+Metadata.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 740B0F616D146B2AAA987EAD3D744ABE /* vpaes-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 26B2FAE9195C1B10FB8289451911B381 /* vpaes-x86_64.mac.x86_64.S */; }; + 74249B06A875FEC41D2307774ECF3915 /* precomputed_ecmult_gen.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D7B8E5E7945F60A19C07B8006CB4BEB /* precomputed_ecmult_gen.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7447A1EB3C57C08F765C8BC8C5C88FC8 /* ClientInterceptorContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = C37A5585E6C895F76C51215421BCF806 /* ClientInterceptorContext.swift */; }; + 74B8B8E110BC9746E90542A42DCF5175 /* CNIOBoringSSL_ecdh.h in Headers */ = {isa = PBXBuildFile; fileRef = D1AADC027009B9AD670FAB50C640B26E /* CNIOBoringSSL_ecdh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 75114F16237DD8B62054DA37AA290821 /* t_x509a.c in Sources */ = {isa = PBXBuildFile; fileRef = 868290F8DF10946C2B695AE2C93A45AA /* t_x509a.c */; }; + 7541E0891E941376565E648C3706C284 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = D78E079D6EED20A6C6105DF41E1D00B7 /* rand.c */; }; + 75468FA6F8EA0A51CD41F8C7DEEF1A4B /* generic.c in Sources */ = {isa = PBXBuildFile; fileRef = 1D7FDD58731DDEA2F0F27C7ED1964F45 /* generic.c */; }; + 75730F51DF804038A43327AA9514B161 /* DebugOutboundEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15FA039D9BDF798A1C7C94118249DBCE /* DebugOutboundEventsHandler.swift */; }; + 7584F718277C9061AC2E52CAA09FBEAA /* CNIOBoringSSL_ec.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AAFC99C5990321A2051AC7826DCE3C6 /* CNIOBoringSSL_ec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 763FE225D3C6A3DB727CCDC349F146B7 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 670C456D4FCFEF9092396FF161CA4A3E /* Updatable.swift */; }; + 766844130D16F11F565407F8F40EEA25 /* ecdsa_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 31B37A38F26CFA3F17CD9667A71A9768 /* ecdsa_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7678DCEDA9BBF65DC15D9E666E87608F /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A30EB5C0B404B831478DE052634CFE /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7684A27F1255449E069F25A2460A1051 /* Bootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B73542505E6AC61B95C80C000C7B18 /* Bootstrap.swift */; }; + 769C022C8F15B72D06A16BE4668EDD00 /* FTypeDecodingResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D7A0D11CA207225D3E47CB684B339A /* FTypeDecodingResults.swift */; }; + 76C03C89B7BB0D57BAF09CE4C7B4C64C /* ChannelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 712C37FF555DF1B9B58D9576DF3FB848 /* ChannelHandler.swift */; }; + 76D24833C231AE4F6466AD4698D79771 /* Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 334BFB5B2E3B497E2F56969B867E12E4 /* Format.swift */; }; + 76E07381A4547147B0BA17BC718F3742 /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBCF711E54A49A7662966284B6C692B /* Version.swift */; }; + 76EB4E7E1EFE7CAF58C31A1AF94B32ED /* sha256-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 7C5265CC769A2FD94944FE072A165B82 /* sha256-x86_64.mac.x86_64.S */; }; + 774A41D26A7C10451680557504D7A53F /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E968AB08461932A981DEA0A9A3D749D /* BatchedCollection.swift */; }; + 77651F160816E699EC490DD9D3F9BE02 /* Shifts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 322DEC6D54542BD146B90AE8B0641CB2 /* Shifts.swift */; }; + 77D207655D8C32EF73E93060E7A10446 /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F6B3F237075144484066C543B8A2AA /* BlockModeOptions.swift */; }; + 77D5C61D0768726297CCF2021E90A72A /* p256_beeu-x86_64-asm.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 09A50810385D7DEBCBAB856DE8A1E29C /* p256_beeu-x86_64-asm.mac.x86_64.S */; }; + 77F4CE4F8D2670B1377B055907A0E585 /* vpaes-x86.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 9FB260E0E9462A69EC446102C7E8886E /* vpaes-x86.linux.x86.S */; }; + 77FFE2CBD5EF02249C01167EAE986A25 /* d1_both.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB8849B3D92320B1D9361B58B46BC9E8 /* d1_both.cc */; }; + 781DD3B836810CCF3F03CB5FFE5D4355 /* CodingUserInfoKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF051C40E0CFD9F649039315312B2DE7 /* CodingUserInfoKeyExtension.swift */; }; + 783B384FD754B788E0D9B28E44B5850F /* NIOTSConnectionBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB14934FB57CF022B95128B26B5145D0 /* NIOTSConnectionBootstrap.swift */; }; + 78598BD37A8B3B79879E22CB36D95BEC /* BlurLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A944D2C2A11F7534F950A9B6078ADAE /* BlurLayer.swift */; }; + 788148D1C9E6AA37BDD8031228B5D072 /* dh_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = CF6A36C389477C0B91CF6F4154DE17C9 /* dh_asn1.c */; }; + 789067D8C8C95DC1657FA055E62354F2 /* GCD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D90504E9042649F39D595CAF524C4A1 /* GCD.swift */; }; + 78A427AD4E2362A4B6C8A9E7A5949E52 /* StreamChannelFlowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B8527DE7A43676401D74299221BC85 /* StreamChannelFlowController.swift */; }; + 78AE96580BD551EB905F72C21AB81E97 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BDB386DC2393B9E00111C6BDCC355BD /* SDImageCachesManagerOperation.m */; }; + 78CF56076ED4F5CD8A9E06408FF38638 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 78E0841EBEDB9D23315EF9C4AD0622BE /* e_rc4.c in Sources */ = {isa = PBXBuildFile; fileRef = ADBA815F54C9D0EBF6960A6A7CBB4C5A /* e_rc4.c */; }; + 78E455067CFA419CEDEBAF632DDFB41D /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C76D5CDB172A27B9B99CB6F16784B942 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 78E46D7931B72355B5FB6A02E69020FD /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01AEEA96113AD6E0F2E3656217271781 /* PBKDF1.swift */; }; + 7958EC35F3C362EE1349FECF7C3DC434 /* Pods-fanex-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1860DAB7ABED7C618762837FA928958D /* Pods-fanex-dummy.m */; }; + 795DEEBC169E6837FAB76CBD2E89A08C /* TCPOptions+SocketChannelOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 717D08C83B52D264B00E632B40CEC117 /* TCPOptions+SocketChannelOption.swift */; }; + 797DAD55DB988B23DA44636F61B6C43A /* SwiftNIOExtras-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B28CE17861BCF5E0A2ABD21781EAB3 /* SwiftNIOExtras-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 798FA71F8CAE44D05016FFF767100375 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 799453F1531D0D9FEA91CCA42EB5A3FF /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DA1D186ACB7B19ECADBCFD4F0BBA144 /* Random.swift */; }; + 79C2E45FA742C6ED63BF449B77B8DB44 /* TypeAssistedChannelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D1C122D30DFE497EE9723B76290229 /* TypeAssistedChannelHandler.swift */; }; + 79CFD854BAA8075B908D7634B02FC6C8 /* ISO78164Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1B7684B4B29822AD4BAFE4218D7CD1 /* ISO78164Padding.swift */; }; + 79E610505AF9B4FC580B00FF762AB70E /* SimpleExtensionMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9AA60793268CDFDA0C0D0CF98F240AF /* SimpleExtensionMap.swift */; }; + 7A29BBC943E38ED7E2041A1910C9C46B /* SwiftNIOEmbedded-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E7AFF69AFE0501AE9FEEC943B53D2C4 /* SwiftNIOEmbedded-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7A424FED21A399FE2610DCB710A4A3FB /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DA374C9FE3135CF0B453A8C5F2DB723 /* SDWebImageOptionsProcessor.m */; }; + 7A4487E9A50688C36A2B754451C60F03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 7A7114736B9A1E24DEFB43290E7ED0F4 /* CNIOBoringSSL-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 019179E7EBA346AA3B2A3C0DA52BD554 /* CNIOBoringSSL-dummy.m */; }; + 7A8325565E872462166C2858CBE78D28 /* a_time.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A64A81ABFFD55BDD512C9EE827EB405 /* a_time.c */; }; + 7A99C203EF8D0D2120DCC6FF459EF820 /* CNIODarwin.h in Headers */ = {isa = PBXBuildFile; fileRef = C01D03DBF1929B2E2EDAFE1D84B937BE /* CNIODarwin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7AB97A46D97437AF1E1C0F9FBBBDA0D8 /* WalletProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 281D8BD48C1BED7DE797404CDF26B27E /* WalletProvider.swift */; }; + 7AECE95B2E2283F846DC931CD8DF8ACA /* empty.c in Sources */ = {isa = PBXBuildFile; fileRef = D33E3CFEC8B6CF1099E266DBB405837C /* empty.c */; }; + 7B355F0E3E660FC2C7561EFA25231CCC /* ExtensibleMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31815169F689A8CA600353549CAECB02 /* ExtensibleMessage.swift */; }; + 7B386053FC82368502E8411EF6AF9B98 /* pem_pk8.c in Sources */ = {isa = PBXBuildFile; fileRef = 56D8359142F5F79A1F73766AFD5D69E8 /* pem_pk8.c */; }; + 7B54990D5103BBD20358E34FBBBACDCC /* CNIOBoringSSL_hkdf.h in Headers */ = {isa = PBXBuildFile; fileRef = 20D2544B93F0B3FCD20F549C25D6CF6F /* CNIOBoringSSL_hkdf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B85051BC13267C48BBA96BE23976269 /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608F623D3B08BA42C8FEC503EB0A3202 /* Checksum.swift */; }; + 7B924E02C258C9BDE0E3A54B7768F878 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA2685CC2F3E2263B3EA330DFF9E4B0 /* Utilities.swift */; }; + 7BE557A1E55B8AD33467E54D28DC6932 /* testrand.h in Headers */ = {isa = PBXBuildFile; fileRef = 66E55B569C5EE21BB5AB9F6E5D66EB77 /* testrand.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7C197D219FA3C1EF21038175317B4CA0 /* UIImageView+Calculations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 994D43AD3904B05EB0ED69E59CD860AE /* UIImageView+Calculations.swift */; }; + 7C2D7AA423F824E10814FA8944F4BBC1 /* aesni-gcm-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 2744B37C8ED8E5438A8F126831F29C6F /* aesni-gcm-x86_64.linux.x86_64.S */; }; + 7C3107BE6BA61DBBB9AF9ACF7B74DAAD /* Call+AsyncRequestStreamWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 256418E2881B6DAA7F14910D02B5180E /* Call+AsyncRequestStreamWriter.swift */; }; + 7C530F8FAE658F95E15FBCD2CBA5EEAE /* PoolManagerStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = C617C7314F44C614860C8B4B8CE78CFE /* PoolManagerStateMachine.swift */; }; + 7C54E1A2F6000A4F5813E969FC21A7D1 /* a_object.c in Sources */ = {isa = PBXBuildFile; fileRef = DBBB69673F9AB022794371244DF6B647 /* a_object.c */; }; + 7C589253D3B0E83C2102556792F9C818 /* x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 1077464057841BEBFE3889CA5E03ADFE /* x509.c */; }; + 7C650767C20B9F60821B50E278E52A13 /* aesni-x86.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 16D1A09E96EB6E967038D24C69E5B2C0 /* aesni-x86.linux.x86.S */; }; + 7CB758EEFCC854A88FE9B50A79046D5B /* encrypted_client_hello.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4FA19DB464A583F8787040A400E72AF0 /* encrypted_client_hello.cc */; }; + 7CD2DE56E6CFC834C1CF672A21B71836 /* FlowCompositeSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = F911CC7F62394A9AB0B666A7D3101E2D /* FlowCompositeSignature.swift */; }; + 7CED3AD85AB0E657AA82C8B40BF87637 /* RLPItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC5572EABD4F6E36821E4ABD2AD4B09C /* RLPItem.swift */; }; + 7CF4FBBC3E9D8CD785EEAC13274CD66A /* CNIOBoringSSL_sha.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7BD51E66B34C82517DC0D59C7B8BB3 /* CNIOBoringSSL_sha.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7CF8F5D09D2A1C1B0CD67A010F2E3CCA /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB19D0C3B111ABDA93C9E962F460016 /* Event.swift */; }; + 7D2B8A81C9C8DEA2581AB7AA2779DB65 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 14DC03D634FF492642E6371B31F1264A /* md5.c */; }; + 7D89B4B7D472B822D9309AF38498AD1C /* chacha.c in Sources */ = {isa = PBXBuildFile; fileRef = 36595D90A92316F603C71CB5F01F7C1E /* chacha.c */; }; + 7D9E8F8A5D02148FCC2DBD6319BCC3D1 /* SDWebImageDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = C5620042BB874899D92901F7626042D3 /* SDWebImageDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7DEA03372CDB3CEDC57066D6EF00A463 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = D88B4F5806EF70D37AF0578452D42980 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7DEC1F9B1F85EACD3BFA4F07610D0E51 /* d1_lib.cc in Sources */ = {isa = PBXBuildFile; fileRef = 57AE728B2D53D0CB3F47000F93780F51 /* d1_lib.cc */; }; + 7E2ED852A96880CDBF1B52969CA0D3B6 /* String Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E1897D1BAEEDBE602D40F24F560BF2 /* String Conversion.swift */; }; + 7E6862A73246BB1A0E7BCEBAF50FFBE1 /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5BD54E549BB42CDA46C2291134E1AD /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7E741B3269431A5DF6F48D618BE5D41E /* sha256-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 809845627483AAE66290A0A5CAAB924F /* sha256-armv8.ios.aarch64.S */; }; + 7E7BA3355640C118DE950658C2272AC2 /* TextFormatDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4091261A509088CF57731B9198952C95 /* TextFormatDecoder.swift */; }; + 7E95F9BA0431B5C6933EEF7030E032EB /* QuiescingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 739B55A60450347DDC51BAB2ECA7970A /* QuiescingState.swift */; }; + 7E99F1A8DAFB235473CEE29B80B6C988 /* ssl_cert.cc in Sources */ = {isa = PBXBuildFile; fileRef = FDD6D466796CC73FB667BFD0CFF68102 /* ssl_cert.cc */; }; + 7EA11D8CEDC5B8E130108C1BB0E40D9F /* add.c in Sources */ = {isa = PBXBuildFile; fileRef = FD23B53B0A47C0B9314C9B5EBCE50F98 /* add.c */; }; + 7EA8ED4B5FADECCC485FC0A5CF904B8E /* GetaddrinfoResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 000D9C2A853E3E3FD34A1155D5819056 /* GetaddrinfoResolver.swift */; }; + 7EACACEBF875C6E4991C1E2D1EE5E93C /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42A115EF9B5E2AD5EEB58AAEA68FFD8D /* Collection.swift */; }; + 7ECA836470E0DE7C5C60FBF251F6BE30 /* SwiftNIOHTTP1-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D75FB5F17B7BEEC09796E3465E8F7D14 /* SwiftNIOHTTP1-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7EFA051C29E0B78307713526C58E9758 /* hash_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F43C7A8E64E38B5952F584AD678185F5 /* hash_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7F5A32FAA652A02D9F78B42D894737D3 /* access.grpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1590218E00A6F2E93D7E8640D81887C /* access.grpc.swift */; }; + 7F82AA1B00DC5EC3D1DF3E1E9BAF2AC0 /* IntegerCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE87F53AE675706680F530C168F294E6 /* IntegerCoding.swift */; }; + 7F8893187E4DA4EFC75D75C98F1C3145 /* CNIOBoringSSLShims-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8A53D6F6D367FC034837B1DD62A240 /* CNIOBoringSSLShims-dummy.m */; }; + 7FA448714DD89FE8A240BE8E50FDB770 /* sha512-armv4.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 0A98F39503CB658134EC3722FEC271DC /* sha512-armv4.ios.arm.S */; }; + 7FC5A0E43ACF497E444040DD504BC652 /* PendingDatagramWritesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F05A1BDA04C07B42D1D50DF121E7DEF /* PendingDatagramWritesManager.swift */; }; + 7FE990D0E641867E134EE9E3F1BFA70D /* AppUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = EACC63230D4C4319D211F27750098F39 /* AppUtilities.swift */; }; + 7FF5BA014629589DBC1DBC5C34BE8E6E /* CNIOBoringSSL_opensslv.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D37BB9E32BA0A1B7CACF7479569D296 /* CNIOBoringSSL_opensslv.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 805CF770886A9CFBF3CE0046D0F9BC12 /* NIOAny.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673FA8BD54C5D615B1D6EB9067EF13E8 /* NIOAny.swift */; }; + 807539BDCAFED59F1F17455D4C87F0D4 /* ExtensionFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE315AD2E58CBC0BE5D4A94EEF3E8B51 /* ExtensionFields.swift */; }; + 809A09224ABB6A00BEF6B72EFAB30B4E /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 96EE5B32A454B7CC397B5C934856843C /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 80D4A72C26C2EF865F9DCA400D2F1E70 /* SDImageGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = B9C19433ED23297D0104677C4BBD09CA /* SDImageGraphics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 80D55B72E6FF9FBD9015A33F59D16B16 /* DynamicKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51684645291C96C48EFBEB63CE861D2A /* DynamicKey.swift */; }; + 80EA4546B55DBBA6081ACFDE29EA0A5B /* CNIOBoringSSL_conf.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A438CD9BFBD6DBA35E833922EC43468 /* CNIOBoringSSL_conf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 818BA65A1DFB65A6AD46B7AD72ED6F3B /* SystemCallHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 674C78CA48A7FE09DFCE8F6C367C6AD9 /* SystemCallHelpers.swift */; }; + 81D455617E941A643E61BED3FE1E1EDB /* p256-nistz-table.h in Headers */ = {isa = PBXBuildFile; fileRef = 63113E7737284DD30A6259682D4CEA67 /* p256-nistz-table.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 81DEE0975FD2488D5C61D099F17DC3FA /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A44A41336C1C73744B65F997ACD14C /* BigInt.swift */; }; + 821B52A10812A9D270BDB32088E99A7D /* CNIOBoringSSL_ec_key.h in Headers */ = {isa = PBXBuildFile; fileRef = 4073C7B6E2C3A068A9662C2499E43876 /* CNIOBoringSSL_ec_key.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8230F8BAFAA7FA0FD826FB6E1FAD7704 /* PopupDialog-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AEA9286C59806AD1E11E2FD5B9F90733 /* PopupDialog-dummy.m */; }; + 825C5A3D82A91C028A3FD640AE8850CE /* random.c in Sources */ = {isa = PBXBuildFile; fileRef = 63B54017CE0B0CA0650D0731FB5F9950 /* random.c */; }; + 826A2744ADC1B1435EC7E63F3C2C7FB9 /* pcy_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 68729B16F225DACE71B8D33EB9ACB558 /* pcy_lib.c */; }; + 827D304687FE0124457833531D64B786 /* ECDSA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193F9FE54D002CC3099E78F220DFD569 /* ECDSA.swift */; }; + 828A7FD40F2CFA0ECEEEC3E075765AAE /* x_algor.c in Sources */ = {isa = PBXBuildFile; fileRef = 940CC6D29A4972AD85F8265F8E5AF468 /* x_algor.c */; }; + 82A2B9AD57B62BD2C0BC5DBEC3594CB8 /* ghash-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 48D89B5DB7277D2575CCD411BCBF2911 /* ghash-x86_64.linux.x86_64.S */; }; + 82A8B0C2ABF0AA8E658B222DAA4D3B2F /* modinv32_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4817559D2BD0D488311A04F0D16CB83A /* modinv32_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 82CD5A1334946C967ED05143D4DACA43 /* DebugInboundEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6D316C011289D6114027CEB8E9C2D9 /* DebugInboundEventsHandler.swift */; }; + 82D33BE6D49328C2F4AEC86DEDED4F00 /* CNIOBoringSSL_obj_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 54DCBB006E801E2E59D8295DE6FBD486 /* CNIOBoringSSL_obj_mac.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 82DA01D0ECDFFC1F612ACEB43FF6A3AF /* PointerHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1969EB0465C0CAEFE0141F3491D7F5F /* PointerHelpers.swift */; }; + 82F81D59F9EE230609BB512B5670628A /* DomainTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE71D92B1BAC8A1856C21B6C893EEED /* DomainTag.swift */; }; + 832690B4037075196CBA2F7A2548C2D5 /* BSDSocketAPICommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBCC7B0E2FB5F7C376254FBFC8169C43 /* BSDSocketAPICommon.swift */; }; + 8330C9043C7E9AFD44AA4A2C17F99DEC /* p256_beeu-x86_64-asm.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 95006D59F8C11B65CE508C1BE5751A46 /* p256_beeu-x86_64-asm.linux.x86_64.S */; }; + 835FD939BEC789E4EEFE096225D251EA /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09297DFBBB10B6771E1F84A3F19325D7 /* Utils+Foundation.swift */; }; + 8376D3D00D90F1304232A1CA08EBB7EA /* LengthPrefixedMessageReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F64FC89200F8D0706E8CCAFD14914470 /* LengthPrefixedMessageReader.swift */; }; + 83B22A6C4E15D459E62089A9993B237A /* bn_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = C0811470D725E0E13094B269A7653FB7 /* bn_asn1.c */; }; + 83F49E49512DA20AED17D6F3C48DE63A /* x86_64-mont.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 33A32575EDCB047F39900C2B6D2BAA59 /* x86_64-mont.linux.x86_64.S */; }; + 840F36EB08048B43E9FCBD62B6E627E4 /* JSONDecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067FE95B3B4DC5361B13366DC2BE3ED3 /* JSONDecodingError.swift */; }; + 8433F353F3016EFF0316F48188D6B651 /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = FA00B28287E667761380128BB484F4CC /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 8448DFB10F52D1872284FAF948754AEB /* IdentityVerification.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB72FA10C1BE9E862B724ECBB814D72F /* IdentityVerification.swift */; }; + 84687F01FA16CAA2D442BBCC2DAAEE59 /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3284F8D7D061DCA29D88332125072289 /* OFB.swift */; }; + 84894DB19B389E92CBF1FCD01CCA7134 /* NIOLengthFieldBitLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581D60585908DAA6033C9E21C8ADF092 /* NIOLengthFieldBitLength.swift */; }; + 84A09F650CB6D87CF142E2008A388E54 /* FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445AF8E94A7BC212A4B000327B75D3BB /* FileDescriptor.swift */; }; + 84ABBD503E6029819C724166A1DD5132 /* secp256k1_ecdh.h in Headers */ = {isa = PBXBuildFile; fileRef = 689ED28F1F4352CF81582818D9F4EB64 /* secp256k1_ecdh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 84AF32ED596E20AEBC370B505CF33164 /* PrettyBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E6BF9922345EBD760CFF08640E08E9E /* PrettyBytes.swift */; }; + 84B624227D73D3746CEFD48E49D74635 /* SDAssociatedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B029DA3494978B4D55C326350A0C3B /* SDAssociatedObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 85078DEC8913D55AFFB15E9D6026CACB /* digestsign.c in Sources */ = {isa = PBXBuildFile; fileRef = FC9D40188C134BF4D0132BAE23A32251 /* digestsign.c */; }; + 851B74D2962016A0B93A58BA47E04178 /* ServerInterceptorStateMachine+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6A478D5EAD917E7F36CF45CEC70B84 /* ServerInterceptorStateMachine+Actions.swift */; }; + 854D7A4A2872566E4D06870518053225 /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = FABD24490DD4ED00306CA54635E45EF9 /* SDImageAPNGCoder.m */; }; + 8551BB6CE0B1441553CF33E6F1866AD0 /* SSLContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03896A4C5D1CA97D2AC38836D9DADA67 /* SSLContext.swift */; }; + 85593576AAEB9671294E2C539DE2C70C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 85B4F3C13C829CA99A2EA551F5B26F6F /* montgomery.c in Sources */ = {isa = PBXBuildFile; fileRef = A495CC0169B4DE51BC42C5C9FD5C2B14 /* montgomery.c */; }; + 85BF38CBE77FB5836F6D550F56B0F820 /* UniversalBootstrapSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22D1A79C4C0AB646702F14CD7CB5F31C /* UniversalBootstrapSupport.swift */; }; + 85FD951409D33B630016856A83757325 /* scalar_4x64_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 20923CBF0D3E28FE03BFD939A5269687 /* scalar_4x64_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8607CDDF3A485A361B6F0296B95B675E /* duration.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE9F6900C3BE0B0D876EEF118FA2339 /* duration.pb.swift */; }; + 86301403B7C3EE7CD7A74549DB13AD0B /* e_null.c in Sources */ = {isa = PBXBuildFile; fileRef = CDDC0B8D791C8C49E6F9070D46D7CF5F /* e_null.c */; }; + 8652E0F5FC00B619A38182E3D6342167 /* DatagramVectorReadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9E6E4E43E58A87D73434E991B0450D /* DatagramVectorReadManager.swift */; }; + 8690C6953643F2B0B3E34ED2E78B283E /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E78B33A1DFF123DF62FA02FE632939A /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 86910B420D68F278708D70119B7344E5 /* PopupDialogDefaultButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = E32E9F648A6FD4A830BA69B40C9C0428 /* PopupDialogDefaultButtons.swift */; }; + 86CB7870DEFF50D055C11996E955BB91 /* HTTPEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47BAB972B9DA6714049FE8E07EF08C1C /* HTTPEncoder.swift */; }; + 86D8584BE5FAFD616E4547BAD669DACD /* ghash-armv4.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 3FE009698F0B833B3B56D8E247C0E2D1 /* ghash-armv4.ios.arm.S */; }; + 86DEF87E4F8198D710456B66C73C76AA /* Exponentiation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B7819128C40A9899F97FAAA36D894B3 /* Exponentiation.swift */; }; + 86FA8044E01AFBB6E2770623D4973B09 /* gRPC-Swiftp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EF12325E188F77C0C95B571E77124B73 /* gRPC-Swiftp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 87494EA46B7AC2E2D07BBE20C8FBB0B8 /* CNIOHTTPParser-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 96D40FDB9D0E9C588AB0A7978B159390 /* CNIOHTTPParser-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 875A71D248448B0DFDE1BD15BCC9E333 /* BinaryDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125EACBDC5ACC520A733CADA059F44FC /* BinaryDecoder.swift */; }; + 875B44B5225C468C1798E3E323AE42C7 /* field_5x52_int128_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5160EE97B79C9809A0F792E3F645C72 /* field_5x52_int128_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 876E1E985D645D400B413F4EF4C071A7 /* CNIOLinux.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B3CA316383F8802A59A51825155C724 /* CNIOLinux.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8781DFC727A787C8AC36CDD6559155B1 /* secp256k1Swift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BD4134865699B139E54951E256C6F701 /* secp256k1Swift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 87C0A26D2A061AA99F6EC5EEEDA6CCC3 /* SwiftNIOEmbedded-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F634A8F909B2004C538D3794F0DDF70 /* SwiftNIOEmbedded-dummy.m */; }; + 87DFFC20C5BC8A4C4B6F7022E45DDAC9 /* bio_ssl.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB0A8C2CB3C8DBC1632687EA5BA09D5F /* bio_ssl.cc */; }; + 87F430052E25221DA3B1D9BEC805BEE6 /* ISO10126Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3DE7FDD0ADABD706D2739EEB88BA64 /* ISO10126Padding.swift */; }; + 87F9C4B7F650D9277B81B82A202A5443 /* MaySendFrames.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD7548A6F50F4CBB0D8776BF446DBD28 /* MaySendFrames.swift */; }; + 8808BCBD14114C8E254A61332ED4DC12 /* HTTPServerProtocolErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA49B891F4BD7B9F847A85FAE26BE8CD /* HTTPServerProtocolErrorHandler.swift */; }; + 8821E3636BB86560FC2F2D2CFF545F16 /* SDImageCodersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8B91EEF6FE8FD80692353167860554 /* SDImageCodersManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 88605D5BB9FF67780FE9099265F4B97E /* bn-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 48F5B0EAFC68E15D99BB48CE96AC36B3 /* bn-586.linux.x86.S */; }; + 888BEE4C3B238AC407C59D2194939AB9 /* SDImageCacheConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A08D0D28E808A53F9752502B7AB6BFE /* SDImageCacheConfig.m */; }; + 889B05E4CE86D14A10E9C9DAC2B3E7B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 88BDF69E0C64309C5A931EEDD0C4193E /* asn1_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA75EA43D5FC6726DC39A45537FD5D3 /* asn1_lib.c */; }; + 8932E535236B3F5DE82316190B433EE1 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7143903518B45B3B4368F186D9483490 /* Extensions.swift */; }; + 89345519765AE40FE56C04A805E034A8 /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7569FE549DE97DD2355EAD434DEA81D5 /* UInt64+Extension.swift */; }; + 896F827AC8B227E67D53F9282F0489B2 /* EventLoopFuture+WithEventLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17130905A7954A110258063CF2BB0C33 /* EventLoopFuture+WithEventLoop.swift */; }; + 897FA00B23D248BF04111BBA6ADC2FF3 /* RLPEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CC2A12C07D5515B9B8E785234834B4 /* RLPEncodable.swift */; }; + 89B5B1919789E937E0E81B78DCC600D8 /* curve25519.c in Sources */ = {isa = PBXBuildFile; fileRef = A01EEE5EB6F8BB3C30D2412EF6E4A8DB /* curve25519.c */; }; + 89B75DA0552BB2AD4F5E890D83268D5F /* RequestAccountMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC5826C4720FA1B7B3778827DF4517F /* RequestAccountMethod.swift */; }; + 89DF2D9C5EFB02A72EC0CE2138B77F35 /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 808D08A0CB972D95262C50B2C8460F77 /* SVProgressHUD.m */; }; + 8A3B5CBFC8D8D6661597CFFF81583013 /* pcy_tree.c in Sources */ = {isa = PBXBuildFile; fileRef = 54B8FDBB46F84E79D561233DE2CB2ECA /* pcy_tree.c */; }; + 8A4FEFA934312DD959EFF528213E2038 /* p256_64.h in Headers */ = {isa = PBXBuildFile; fileRef = AD1003EB741271BB093E74D64F323A92 /* p256_64.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8A95BCA66D82FEFECCA5746DC9685C96 /* charmap.h in Headers */ = {isa = PBXBuildFile; fileRef = DD080D9D0066EA88ABC10B14F8920C64 /* charmap.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8AC112E917271A0E7669BF49FE7D8D50 /* Error+NIOSSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB32F7AB6A7CC1CF10B4632146512E4 /* Error+NIOSSL.swift */; }; + 8AD812A36A3F45945EBE15FE7B305554 /* v3_pcons.c in Sources */ = {isa = PBXBuildFile; fileRef = 345E070647C98D8EDC77638552258C8B /* v3_pcons.c */; }; + 8BD89CD3ED492B3A09C9B215CBB7EBD4 /* ExecutionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE41B596CC64683D3C1C0FE068823186 /* ExecutionResult.swift */; }; + 8C1AA1579F53FB71B287AB0F5BAC261A /* ssl_buffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 22AC771C467207A9BA0A54A03227D294 /* ssl_buffer.cc */; }; + 8C44B8EF7029311A92F7408622AC1EBC /* CNIODarwin-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B13ECBBEA21F99BFECD0DD09E5C0B7A0 /* CNIODarwin-dummy.m */; }; + 8C5D0B2A7B52DF68D03820244993E91B /* SDImageTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = D6C65F229611613EDA6CA861ABF58094 /* SDImageTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8C83032E203400397B9E92830C845D56 /* CNIOBoringSSL_blake2.h in Headers */ = {isa = PBXBuildFile; fileRef = 769E69568A316FDF6B3797D285755BB7 /* CNIOBoringSSL_blake2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8C9D609988FE2993BB116B4B00FAC57B /* SDWebImagePrefetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EDF120F9CFEA86931D71F1931D9F75B /* SDWebImagePrefetcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8CC279199EF39D7DA793BDA1FFF22FF2 /* NIOSSLHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD40323B10E8239FC8F186C9065EE598 /* NIOSSLHandler.swift */; }; + 8CC79D41E5B378932CF413CEC13CC3EC /* AccountProofData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D15A50EE5BB4D434CB93F59A65B2E1 /* AccountProofData.swift */; }; + 8CD34755FC451BCBEA1DAC9F5306636E /* ClientTransportFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2E8E0EC3E3D0DA30CC01C980215515 /* ClientTransportFactory.swift */; }; + 8CD580B0B5647801B16A259E0A7AD6EC /* CNIOBoringSSL_pkcs12.h in Headers */ = {isa = PBXBuildFile; fileRef = 24FAD07EDFD4F7446B7B3087913B744A /* CNIOBoringSSL_pkcs12.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8D14245A9C211C6000E4693D8F61B92C /* Data Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49B2A8C3F35F5883ECABDFBA56D961C1 /* Data Conversion.swift */; }; + 8D716860B7C9D57D691CA3FBE34F7543 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019CEF31B4677F922E3374D77EF6DAA2 /* Resolver.swift */; }; + 8D73A7A52CAC162A201751447F3E822C /* Pods-fanexTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 592ECFA0202DC3D72A69C99AF5F1693C /* Pods-fanexTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8D837DE5AF2AC58CB2D2532150E26E0B /* ServerErrorProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082C345E6CF5971948D1443C3E5061BC /* ServerErrorProcessor.swift */; }; + 8D935610884B8CE93FA6D1540411BCB9 /* basic-config.h in Headers */ = {isa = PBXBuildFile; fileRef = D87C163D2F9A6289B1C80E3AB8459790 /* basic-config.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8D9D5713E6FC1E021FFF5238A6026EB6 /* ClientInterceptorPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A5A5841BE08BD8E11D0963F7CB3D5C /* ClientInterceptorPipeline.swift */; }; + 8DC8B00F61A16E0E82E73044F488C796 /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = E1FB3A89265A69F9801F85E9DB90A200 /* base64.c */; }; + 8DDDC3F18CD83DAD95CFCDE316A0E06E /* Varint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A36BE9C53E671A694FC4006041B0247 /* Varint.swift */; }; + 8DF27CEE8FBD94A82CF6EED2C5917A92 /* Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B1390D47F4087E0018F33553778E55 /* Address.swift */; }; + 8E1A4C31C11C323D4250DC77A6452505 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 8E53AABA01D8C15F66C41BA352405064 /* ProtoNameProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3A057EDD5E7D5E097B894F2E59B37 /* ProtoNameProviding.swift */; }; + 8E639D361F0B893AB4CA53013E5D0117 /* rsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 99397EBD2713FC0B5C926E662DB36B29 /* rsa.c */; }; + 8EA31FCDA00CA16218D2AE03CB6CC4D4 /* utility.c in Sources */ = {isa = PBXBuildFile; fileRef = 8B01738680478070311F7465DBD996A2 /* utility.c */; settings = {COMPILER_FLAGS = "-DENABLE_MODULE_ECDH -DENABLE_MODULE_EXTRAKEYS -DENABLE_MODULE_RECOVERY -DENABLE_MODULE_SCHNORRSIG -DECMULT_GEN_PREC_BITS=4 -DECMULT_WINDOW_SIZE=15"; }; }; + 8EA9B4893651C1EFF8E787FB4B1895D8 /* a_utctm.c in Sources */ = {isa = PBXBuildFile; fileRef = D05CAAFC9A2E05CC9475D01611990AE4 /* a_utctm.c */; }; + 8EB44CF3B5E5165ECB407883346138F9 /* EventLoopFuture+RecoverFromUncleanShutdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7429C5A9FAE59CCDDAC3E7D669C079CF /* EventLoopFuture+RecoverFromUncleanShutdown.swift */; }; + 8EB713CDA5720AC9AC3CAC0D516E5F65 /* fork_detect.c in Sources */ = {isa = PBXBuildFile; fileRef = 225201E51C43DA7D188B2242FC65C191 /* fork_detect.c */; }; + 8EBC581D15C60F56D9B741B35111EA28 /* thread_win.c in Sources */ = {isa = PBXBuildFile; fileRef = F4101AADDF0EA95C8416FE6C5C9F8FB4 /* thread_win.c */; }; + 8ED98FC7E7FF6796ED2C55C02477DDF4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 8F29CAB46A3AF7609A396CE22671F423 /* PassthroughMessageSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = C77A761ED7EE5B3F9934E8867532CD9F /* PassthroughMessageSequence.swift */; }; + 8F5BF5ADFD3D622FF01DD8201CF54CCA /* md5-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CED859490C1400D8301C7B7C47AF813 /* md5-586.linux.x86.S */; }; + 8F5CABA6FF150B55235821E71ED7984E /* URLEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73BC5E3CCCB8A71118830BB74E782545 /* URLEncoding.swift */; }; + 8F88549F032EFFEA9C281860520CC879 /* SDWebImageIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 12CB7F9B92A615FA3F5971FA7CA71496 /* SDWebImageIndicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8FCFBD2B16B6D35BAA395B750BA68F2B /* rand_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = 3296571AEE74017B771EDAE08C437F61 /* rand_extra.c */; }; + 901C0CE07B2CA5EDBE95ABC547108F97 /* SSLErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E8AF0B8E6E62DE4FF3C86D748245E23 /* SSLErrors.swift */; }; + 903A1D086098A9BFCDB5161DBF555BBA /* SSLInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1826E26775407F17457CCFAFF94835F3 /* SSLInit.swift */; }; + 903F3D85C4E26C6C3810EF8465B800EE /* CNIOBoringSSL_span.h in Headers */ = {isa = PBXBuildFile; fileRef = 42F7F1A1DBBFB7640DC700B5B0F5E3A1 /* CNIOBoringSSL_span.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9046ACF4E9A631179B2F7ACD5457AC60 /* precomputed_ecmult.h in Headers */ = {isa = PBXBuildFile; fileRef = A9DCA49E1FFA9607497E9C6B8239270D /* precomputed_ecmult.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 909CBA577868D6E976AC82340B50343E /* SDImageCachesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B4ED69E4AF1E48667B2065876C749F /* SDImageCachesManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 90A1368C902FA3997565580BD550A1D0 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447A6EDADED82970E5400D1C1CF0BDE /* Array+Extension.swift */; }; + 90C6B9797D5C6844B2A0EADE1E6F937B /* SwiftNIOHTTP2-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D4D8755F63B123A5B3596B36D1B55D1E /* SwiftNIOHTTP2-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 90C7B8A60C2516B9BDEBC60A2A605362 /* Message+BinaryAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82CC6E59C710C9A479CED04F6EE1953 /* Message+BinaryAdditions.swift */; }; + 90E1B9CA712F3E3D19C34AE551582040 /* x509_vfy.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E793BBA0C633FEEDBABABF92969F7DB /* x509_vfy.c */; }; + 90EDCF951A14E6E89A0D43337925BAD1 /* LocallyQuiescingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D14D9882811FC95C4A52156FF3A0722 /* LocallyQuiescingState.swift */; }; + 910586F1659C1ABF0DCFF5D35EEF84E0 /* WatermarkedFlowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED8CCA0FCBBC5D24D493B41CECEC3C34 /* WatermarkedFlowController.swift */; }; + 91503E1A26EB13111FC795578B02BF22 /* scalar_4x64.h in Headers */ = {isa = PBXBuildFile; fileRef = 476278A16583C8538AFE1DEB99804DC7 /* scalar_4x64.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9172F06D07C6AD5856C0928547998FF1 /* scratch_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 681CE7F242DD1F94F884B8952827D0C4 /* scratch_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9180F29ED52CBC946F07529ADB8378A9 /* WritePCAPHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B576AAD6BDC64DD3BBAC385FD520D7 /* WritePCAPHandler.swift */; }; + 918162E4377088ADD539EA01D60D6F32 /* ghash-ssse3-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 3F42E68F8F1B4036B1AE89EDF9CFA7D3 /* ghash-ssse3-x86_64.mac.x86_64.S */; }; + 91A199FF2A2BB3FE5767716C4232DBB5 /* HTTPServerPipelineHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CBC1E059014B56C25224FCC43A92433 /* HTTPServerPipelineHandler.swift */; }; + 91A1AD329755A01C1DF443F8ACA0DB08 /* p256_beeu-armv8-asm.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = C9CC46CB241619CF2FF6976F65331C22 /* p256_beeu-armv8-asm.linux.aarch64.S */; }; + 91CC0ADF6F7F594543D54E0C786D3B98 /* ServiceMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF02BEB41B3324A7EDE9B47B64D29E11 /* ServiceMethod.swift */; }; + 91F7CEC4CB4C130E2EC2651A91307FDD /* secp256k1Swift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EC5CEA3C1A1008F4A6EF70E7F50D1F4 /* secp256k1Swift-dummy.m */; }; + 9217F5236FE1F764DA37607E4F58A4D8 /* md32_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D0DC076BBAB2EA49B318C0AEBB39F4F /* md32_common.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 92310C4D2834697ED20400E7948B5874 /* ServerHandlerStateMachine+Idle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430DDB59333EC7767251863BFC41F5A /* ServerHandlerStateMachine+Idle.swift */; }; + 9242B61F4DDBC32696F866FA11DD81FF /* GRPCClient+AsyncAwaitSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79498A14802AEB00C50159F45431EBB /* GRPCClient+AsyncAwaitSupport.swift */; }; + 925281ECDAB627C72EFC8299EEA8D79E /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D462F248FEBAB1C92771B296C65AAB45 /* Utilities.swift */; }; + 928C18FEBBA63ECCBA0D2B050E53A30A /* access.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B348362474913E38AF17055678DF7C7 /* access.pb.swift */; }; + 92BCA5ACF42CEECB51875ECBB000E300 /* GRPCLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDD27EA6B00152FF0E718F7E4E0B5BC /* GRPCLogger.swift */; }; + 92BE3FAEA06EA097008DF150FFD6AB3D /* Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64003FC3B36480A559C1E01B4E5180DE /* Linux.swift */; }; + 931613395255E0FA0A1749FD25C5D429 /* EventLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4895F0708E8EB50CD4A750A9511AE34F /* EventLoop.swift */; }; + 931D7961922B8F01F60747E66927918C /* Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF179EF5BF07E33B49915C790AA9463 /* Interaction.swift */; }; + 9360ADE473BF98DAE696E99119797280 /* HasLocalSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A65A9AAE2CB4259669C7F1CD52FC22 /* HasLocalSettings.swift */; }; + 9370582F8435D8057A4B9D0C1EF87700 /* atomics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C95B55237F43C6DD123B5CA48961ADCA /* atomics.swift */; }; + 93850E9620D3F3941A574C341895E235 /* BloctoSDK-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2534CA8D3B74A01222E7A77A1A6B124F /* BloctoSDK-dummy.m */; }; + 938D2992915D6FE7A9DC59E172111584 /* Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578517D7D69BDBEBDD8E47022CCBC81 /* Linux.swift */; }; + 9422C6187DDB4ADEF16B99F65C6EB16C /* GRPCStatusAndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448C675002E3DCA228896933562EE2AA /* GRPCStatusAndMetadata.swift */; }; + 943B0A1B436BAF4D419574466EF70FB3 /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 383EA49322B94216634E72962ED27F13 /* SVProgressHUD.bundle */; }; + 945377AB6F66065876391D8469014C65 /* TextFormatDecodingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C09A6BC46D6AA43601F4B44F4AAF2CA7 /* TextFormatDecodingOptions.swift */; }; + 9466136BC831A90F33B72499E2ACF0EB /* sha1-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = D61158F986302E12E922F356AC6A7673 /* sha1-x86_64.linux.x86_64.S */; }; + 946F3DB3BCCFC40E9FFF92709521771F /* FCL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97EDFC1B66D01A1233C83AA13E6C3E34 /* FCL.swift */; }; + 94939BA9762C72B225D04F935C667F8A /* tls13_both.cc in Sources */ = {isa = PBXBuildFile; fileRef = 31F4ED7CF3CE87BEDBC1F99CB0874EE6 /* tls13_both.cc */; }; + 954F404A6D712201D9F78F1893B7E794 /* GRPCAsyncResponseStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A65A501924E6053568C1E8BAC3675B /* GRPCAsyncResponseStream.swift */; }; + 9559BC0A5F6062AE2B71AA45F4AFE8A0 /* ChannelOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36483716E2DF6E768945736F78E8A549 /* ChannelOption.swift */; }; + 955D0935513D1F162D501287B0325623 /* ExtensionFieldValueSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B9BFDE2AB7150122CE94F7D3061F88 /* ExtensionFieldValueSet.swift */; }; + 9602632D44D14CAD9C199F579C7FF561 /* ssl_key_share.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7EEDE01AE2D834A270754AC5ACCD6FDD /* ssl_key_share.cc */; }; + 96066E08B1D29D3170E3A211F1E35F1D /* by_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 47589CEE455848A67549A64D69A4B25B /* by_dir.c */; }; + 963811DD817F9A25665CB366882D00FA /* DebugOnly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2847E7D26F025BB1D57C079905EB843B /* DebugOnly.swift */; }; + 96479C9C76FDC513C03ADD58168F6911 /* SDImageIOAnimatedCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = B8096BA9AEAAB47DDD31DAA0036E2CED /* SDImageIOAnimatedCoder.m */; }; + 964AFDEC56EE52534D7199AD73F1C264 /* chacha-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 90ED2F344C5847CA95D7B80B73E146A1 /* chacha-armv8.linux.aarch64.S */; }; + 96614FB7F1EE44190975CF9D3775561B /* ByteCollectionUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9263A27F2368160D48F5D8D39811F5C6 /* ByteCollectionUtils.swift */; }; + 967576A5F308F9A5D22642DFE25F6D73 /* LengthPrefixedMessageWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1845575A98867066BC733AD1C8202CA5 /* LengthPrefixedMessageWriter.swift */; }; + 96AAE61037686D0D11BFABF87E3EDF99 /* HTTP2StreamMultiplexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0DD1041FF36196DF02DE517716A5AE6 /* HTTP2StreamMultiplexer.swift */; }; + 973A1CD9F60908C9D6A024ADE16ADFB5 /* chacha-armv4.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = DCC668BBD24EEF42DBAC20B915CC8D69 /* chacha-armv4.ios.arm.S */; }; + 9777D65ECAA2B800674F79BDD7034A2D /* PosixPort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 777E76DC30F79C40830F0990980A4072 /* PosixPort.swift */; }; + 97A740267D6B0AD72622EB9D862651B4 /* CipherModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72638FCE3746FD4EE7CE54980A2EB158 /* CipherModeWorker.swift */; }; + 97DFA419584FFB1AA70710DC03CCBC88 /* CadenceArgumentExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 716AB6CD880F7D751DACE82887F42C91 /* CadenceArgumentExtension.swift */; }; + 97E73E13FA016FA00E2F31EE0CF0B4D7 /* PipePair.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8505E620F80DAB19865C77F7204E3DE2 /* PipePair.swift */; }; + 980DEB38F9BD91AFA6B47F51D64E2166 /* SwiftNIO-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FB7774CFEFF2CA175477B9CF9FE9E3DA /* SwiftNIO-dummy.m */; }; + 9830A6203AA060D2147558809319CA8D /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4944D92039A49A17EC34979D0F9648 /* ConnectionManager.swift */; }; + 984CC8A94475153D5054D052291168C2 /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53589CFAB32460C48156336CE5EE883F /* Poly1305.swift */; }; + 98C6517114A26AF9E637604AC4D58BEE /* Digests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25583F9C089332D336990AD128E4EEE9 /* Digests.swift */; }; + 9917CEAD8CE1CEB7FEC031255AED8FA8 /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CC4FBE5CACD2CAB0301E49D7AC65B92 /* SDWebImageError.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 991D00F3C0F86EBDBBCA96D379C12DF2 /* ssl_cipher.cc in Sources */ = {isa = PBXBuildFile; fileRef = ADF6487B52236A319DE826891AC0CC05 /* ssl_cipher.cc */; }; + 991FEE429484419A2B1CE17341C32C87 /* CNIOBoringSSL_x509.h in Headers */ = {isa = PBXBuildFile; fileRef = CAB5BE488205DAD5ECF3325DBEB0CB80 /* CNIOBoringSSL_x509.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 994327308CC7ECE7850C804FA0EA5F21 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8077F7252FAFDBE8DF3D1A8A44F808EF /* NSImage+Compatibility.m */; }; + 9970473854F7AD56D1BBFF69BC342332 /* HTTPPipelineSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F05446E7403E52098CDA564AC7A9C6 /* HTTPPipelineSetup.swift */; }; + 99709E1C4991C49EE5601FF9461B2969 /* SDImageHEICCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = E201F149034E7DE2B52308F670E942D8 /* SDImageHEICCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9978300F278FBB2909212961DEADCAC2 /* _GRPCClientCodecHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F69D217FB1BED38F59C70AF29DF895 /* _GRPCClientCodecHandler.swift */; }; + 997919169678152515DD1FA4B5E9231C /* StateManagedChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43ABA1E2D7A98863CDB143A0D955ABF /* StateManagedChannel.swift */; }; + 99A91CCDCD7E7195569A50F0AF71DACD /* ecdsa_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C88AF3E809F3C89DCD2B84B6726E1CF /* ecdsa_asn1.c */; }; + 99E31072D780FBEDAB586BA141451234 /* Google_Protobuf_Any+Registry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B96C39808611942C367F684DEAA2D3 /* Google_Protobuf_Any+Registry.swift */; }; + 9A118EFBC45C01036600EB8D94A69F97 /* ClientInterceptorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCF6A65EC27B88428B3A0CF63413317F /* ClientInterceptorProtocol.swift */; }; + 9A1BB524FAE632DB09FE770BE8DC8F0F /* LoggingServerErrorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80BC07600C31821C48FCBAE486DF89E /* LoggingServerErrorDelegate.swift */; }; + 9A42D6F18A35749F78972DCF68E54E0F /* p_x25519_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 183018A2F8E465C8814BA55F7DD78965 /* p_x25519_asn1.c */; }; + 9A649C40075F0E7A01D3A39B47E34E12 /* ghash-armv4.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 276ABCC94009D60FD2C18128F2B2586B /* ghash-armv4.linux.arm.S */; }; + 9A6FE052F88D8CD593A1DAD117E0821F /* x86_64-mont5.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 2A1BE9ABAC549D7D0A183959CFA54396 /* x86_64-mont5.mac.x86_64.S */; }; + 9A7FD0E844EC414A2B246CB0A010BDC2 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1109E4D9498CA2A28B97BFFC963ADD83 /* Utility.swift */; }; + 9A84B985B88342B6CDA921D4C2F3ABA3 /* HPACKHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DA1DE656AFDE4C64EFF20746AF3D0B /* HPACKHeader.swift */; }; + 9A930E3136F8C7A0EF07AB176345845A /* ghashv8-armx32.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 1698B48A7FBCCD81FBEAF7B8D95C5CCD /* ghashv8-armx32.linux.arm.S */; }; + 9ADEE811DB62E02DB875EFF9DA83E1AC /* HTTP2Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D4B490F34F7351B400CE5225B4A047 /* HTTP2Settings.swift */; }; + 9B1477CFA378038EE96F941438F75D81 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 9B941E4C325F231E0FF215B9943B1BF3 /* HasFlowControlWindows.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467CCA25199920B058849FD6C2C321CE /* HasFlowControlWindows.swift */; }; + 9B99B4CE0D78F2E353153F4EC9920E12 /* voprf.c in Sources */ = {isa = PBXBuildFile; fileRef = FC515B3B56B84E2210FA56992DB9705E /* voprf.c */; }; + 9BACDF144D3D89AB3A9FB4A4B7E47410 /* CNIOBoringSSL_stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 85023AE87EBFED1E887AA6F3F7ABA2C1 /* CNIOBoringSSL_stack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9BBC00D55C136D204D9E6135D396B088 /* MultiThreadedEventLoopGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56C4BFD62C8CCE18637535CF0A76FF2 /* MultiThreadedEventLoopGroup.swift */; }; + 9C06DF25247F6FF83E23E0FD066CB5C4 /* ServerChannelErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B937F84CA0F4DE0A31A65B671E08821 /* ServerChannelErrorHandler.swift */; }; + 9C096C865369C21D252A0F4F90BE21D9 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 82862FE35B12CF563FC156B6110476B1 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9C8A66CCD5209B42FEE81B7198F1F9DD /* ServerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9767344EF78CB1C9C72E3387E88AC09 /* ServerBuilder.swift */; }; + 9CDEA353E845FE3EBA3889F6DC0251AF /* FCL-SDK-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF665EB75E6C7CA2AC7151F867A8615 /* FCL-SDK-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9CE03904E73697E6764B07D01FBDD54C /* IOData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE2E6E1CA325F9BF2A6343630420EFB /* IOData.swift */; }; + 9CEB5B454088D6BCC3A11C759A76161A /* SDAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 852805F03CD9FE9D25A0C3D4B3E7D4D5 /* SDAnimatedImage.m */; }; + 9D041316DA723CA8912BC9DA2530C257 /* fork_detect.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DD497DF7646EFCA903C73201E6D5128 /* fork_detect.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9D0FA12B3199079CFDDC9BC7C8130715 /* ReceivingDataState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB3E6CA4148FDD0A85530EEE85C17BC /* ReceivingDataState.swift */; }; + 9D0FF4962DEFF82F2E48F48CB2A7FE9B /* ecdsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C1ABD90C5C3F8E73ED1658CA23F8A4 /* ecdsa.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9D3380488D2648776C64EC2AA8F75955 /* pcy_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 391A2DAE73D4062B17F9DC9B32E75C7F /* pcy_map.c */; }; + 9D3C5746BEC51A55660EDEE3348389FB /* UIWindowExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6471F8CAE3AF3E5255A97AE4A70BB0 /* UIWindowExtension.swift */; }; + 9D7EBB3A7377C116526B8A511F8CE245 /* SDDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = CA8520A7740E149F0C6D18630A0F5E32 /* SDDisplayLink.m */; }; + 9DA75302CE8D7699963D0B4DEAA0097B /* obj_dat.h in Headers */ = {isa = PBXBuildFile; fileRef = 130724651ABE653E5C388F378A1A011F /* obj_dat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9DD5C68AEBD2F6E0C8BC97F1B11136A9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + 9E1432E859BD6E901D050E711CDEE881 /* BaseStreamSocketChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C7F2C73FC7C012E942EED296C5EFE2 /* BaseStreamSocketChannel.swift */; }; + 9E2CD9AB65E5C3E69C155F6F7338D6B5 /* OutboundFrameBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 070EB0072D9FA1881763CA6EA3B48CA2 /* OutboundFrameBuffer.swift */; }; + 9E537E197FCD26894A560695CA14818E /* sha1-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1910BB24C12FB9701C167D4835C46CF2 /* sha1-armv8.ios.aarch64.S */; }; + 9EB0C08316385535F0818C9101D9997B /* CNIOBoringSSL_md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F0595717F923571F063D4697772B8DD /* CNIOBoringSSL_md5.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9EBE0316C43C221F2566D14B66821B87 /* secp256k1.c in Sources */ = {isa = PBXBuildFile; fileRef = BAD1E7D62CBA874732C8DBB7B121F54F /* secp256k1.c */; settings = {COMPILER_FLAGS = "-DENABLE_MODULE_ECDH -DENABLE_MODULE_EXTRAKEYS -DENABLE_MODULE_RECOVERY -DENABLE_MODULE_SCHNORRSIG -DECMULT_GEN_PREC_BITS=4 -DECMULT_WINDOW_SIZE=15"; }; }; + 9F10A0E482367468FD7AA526A7826FE4 /* GRPCError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5B1BFB9F383FB335DAA5730B9A73A16 /* GRPCError.swift */; }; + 9F77F70AAEAD5899CD4281C3D239248B /* FlowMethodType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1575DC7DE34542CAA9140F3C83A38F9C /* FlowMethodType.swift */; }; + 9F8F9A5E33E0EE4F74F7F440FAAB173E /* p256_table.h in Headers */ = {isa = PBXBuildFile; fileRef = 126ECBF84E8EC272A797E71ED28D0785 /* p256_table.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9FA73BFE060AFF50C64519A75A5574D2 /* tasn_new.c in Sources */ = {isa = PBXBuildFile; fileRef = 77FC267086AFB9870729CA2F56F19755 /* tasn_new.c */; }; + 9FD7FF60559CFFCA9FD7FB732173F870 /* FCL-SDK-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3341C39DD9BC0B467383DAB3D96B4E65 /* FCL-SDK-dummy.m */; }; + 9FD9956DD18BC154D2BAEB6A0C8C382C /* FType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E0708E7CD171E1FC77EDE99034EC939 /* FType.swift */; }; + 9FDCC681879CC99EAABDE61586111607 /* String+unsafeUninitializedCapacity.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6D54E77894F35CA1EC1245BB57F3B0 /* String+unsafeUninitializedCapacity.swift */; }; + 9FFC483844B163BC1FEEFDE3CB235460 /* SelectorEpoll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606ED2AF7D78BF7428003D150AEA1570 /* SelectorEpoll.swift */; }; + 9FFFED044A7A91DD9B4BBAC0FB8EEC76 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B52153335ED8460B4D76170794B791A /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A0057ACF8EE5EE1267DCD9399D4B585F /* refcount_c11.c in Sources */ = {isa = PBXBuildFile; fileRef = 80D071A6E31239AA1A56D6F34AAF2BFD /* refcount_c11.c */; }; + A00A0348C076445AD56219C5D8CAB513 /* Exports.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F50EBBC228643BBF9686C9B450DB58 /* Exports.swift */; }; + A00ACDABBB125650F881E13AAC80EE4B /* x509_lu.c in Sources */ = {isa = PBXBuildFile; fileRef = 93E4422CDED7F1D4227B7E5D322F43C1 /* x509_lu.c */; }; + A01636DB38B55AB3720A0053D5D49385 /* a_bool.c in Sources */ = {isa = PBXBuildFile; fileRef = 201003D040C6423595A3EC0B593CCEE5 /* a_bool.c */; }; + A01F905BA277D75B6EBDE576C63BBFE6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + A075C0125E388D7C795E166A3A069EF6 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BD1F34CFE7497BBD6197A9FF7E8FC7DA /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A083AAC3481062E5DE223D480757A83B /* UIButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = BF39F093DBD84740D41A94119F30C0B6 /* UIButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A13BC77BD45A2B0F32400EF94A7F928D /* hkdf.c in Sources */ = {isa = PBXBuildFile; fileRef = 27EBE9375FCD8E338CF2D516B8869EAE /* hkdf.c */; }; + A16B12794B4DFC3E76EEB6457F626795 /* RequestResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9352F8CAFC6537ACBAAB22D0AE728CCE /* RequestResponseHandler.swift */; }; + A17CA57E6FF0E55EC45BB7F5F83237CE /* bio.c in Sources */ = {isa = PBXBuildFile; fileRef = 31808CF1897D8D379D800951311CF3FF /* bio.c */; }; + A18C9C5C94A51AF113FD6094ACD67D05 /* aead.c in Sources */ = {isa = PBXBuildFile; fileRef = EF06B86D5C779FC349D2DC6B37349507 /* aead.c */; }; + A1EF6E033E2D73A89B6E26D1F5A5498B /* ssl_asn1.cc in Sources */ = {isa = PBXBuildFile; fileRef = F3073BCC2A47AC56DF49294324E56648 /* ssl_asn1.cc */; }; + A1FF1B8B82A494D7D29DEC80C8D710A9 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81073BD7A32C72DE43989D7A7C1EF95 /* Padding.swift */; }; + A21BBC955341A72B51526E645C6C84D4 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F09E3B56130C3D3396435B94FDB806 /* Logger.swift */; }; + A21E13377597DDD36D32828911EB7AF0 /* ServerHandlerStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7439633EDD2E01ED03402DB1D02A0D /* ServerHandlerStateMachine.swift */; }; + A233010267CDD35546791488F54A0225 /* GRPCTLSConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8EE5C7973CA3CFEE5FD57A854A7E18B /* GRPCTLSConfiguration.swift */; }; + A24B4B60656BA387B9979BD877A23983 /* SDDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = FA03486F566E13730B52AFCA100827EE /* SDDisplayLink.h */; settings = {ATTRIBUTES = (Private, ); }; }; + A28021EC2FA52704C25635AC73D1EDD8 /* ChannelPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE40AFE7EFA92E72357747043244CE2 /* ChannelPipeline.swift */; }; + A28B0C7CAB1DB0E4430B488575D2EB0B /* modinv32.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C5D5F0E96517B6A2FD7F1E6CC11A961 /* modinv32.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A2AD719965974E7B15C6FE309C96AF86 /* QueryDecoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2E4F913CC7AD04D77905B6175B9E551 /* QueryDecoding.swift */; }; + A2BA17FF4D685C9DBA81F6DBC60B940C /* x509_trs.c in Sources */ = {isa = PBXBuildFile; fileRef = 58564B21CC6075F988564B3467107203 /* x509_trs.c */; }; + A2CE92DE43AB450DE1AAA129BFBADCBE /* SDGraphicsImageRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 95894A8F7B6DAE981F5165BE4F2EE40A /* SDGraphicsImageRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A2DF717D326BD940EA7210F0A90516C9 /* Strideable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DE3B81F7066E320CAC2CF2B74F561 /* Strideable.swift */; }; + A2E1B133255638FBB5F55C4CCCF77267 /* ResponseContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F8FBB2076A193DA0C2D6BF5BED3E049 /* ResponseContainers.swift */; }; + A2FA9BF500E5A97AEB0882F62552B00C /* vpaes-armv7.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = BA415EF77A72691888985A75DD694708 /* vpaes-armv7.linux.arm.S */; }; + A2FCD5718C96A293D359142D57FABC2E /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4487E443015FCF86B7D2288B4B132613 /* ChaCha20+Foundation.swift */; }; + A3137D709E339687763D9AFF5FE1616F /* LinuxUring.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3E2E750872CF97E0A6E77587D690DA2 /* LinuxUring.swift */; }; + A3BFF0CDB72BC173BEA1C8ADDBDB0D1D /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = EE25658DF6ED641DE4B9C84EE85F4AAD /* UIView+WebCache.m */; }; + A3C8B16A87DA9D76BF77BCEB0AB498ED /* field_5x52_asm_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B7C580C98CD15D9B5D5099A582F50F /* field_5x52_asm_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A3CD0A59293810E0DAE3DACFDA19721E /* v3_ncons.c in Sources */ = {isa = PBXBuildFile; fileRef = 1C745E1C3AB4D48E7AAE3A7CB7C661AB /* v3_ncons.c */; }; + A3D8C3EFDD38B6A725C235D08C05F4DA /* Bundle+Module.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D751421E4FEBFA7A96941313C1592A /* Bundle+Module.swift */; }; + A3E665BAE12599243AE3B669EE8EBCC8 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1758411E8067285A2146A45045AA7B /* SHA1.swift */; }; + A40AB16CC34439B2580523C759EFBFE4 /* LogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5537285A56608EC950F942013E870F2 /* LogHandler.swift */; }; + A40BF33478C497D5D4C1B2A835BE3D3C /* sha512-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = FBD5B642CFF084A609C00F03399C12CE /* sha512-armv8.linux.aarch64.S */; }; + A42FB500D8E7E9706590E6ECF80A3F2F /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 42C55DECF218CAD487EE2130755E8D2D /* util.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A4460B2EA066EBC46283E99805444310 /* BinaryDelimited.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ED79131FD4799CE802D4FCB1A45A27D /* BinaryDelimited.swift */; }; + A49766AA6A5500618B4200B22531AB4A /* pem_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 8DEA8C2291C63E540ADE27DF18E653C4 /* pem_lib.c */; }; + A49822680868EADD918002A03FDB316E /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6337AAB3E193E899F6BAA540A282 /* err.c */; }; + A4A382C0552AEA0E3E61A52FEA004ADF /* ServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E03EC85D380BC085366FA157E17D9B /* ServiceProvider.swift */; }; + A4E9C0DA3D34D2E1F620D97CF180C9AF /* felem.c in Sources */ = {isa = PBXBuildFile; fileRef = 82BDEA9DBA5FF9733B6B9B3BAB638B79 /* felem.c */; }; + A527902D8FFE632759BB39C077636C17 /* cpu_aarch64_linux.c in Sources */ = {isa = PBXBuildFile; fileRef = 3624E55B7B6A72C190EF3AFF2F736950 /* cpu_aarch64_linux.c */; }; + A535EC97D3F3FF5CA9D3968D27F85803 /* Schnorr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 015510173B8F8742C76C82E9583217AB /* Schnorr.swift */; }; + A58E08C2BE122504E1A73341C560DB00 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + A5F1958ECF3EFC3FB453ACEE40840BCF /* InteractiveTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE21EAEDADC5882C334469A44553854 /* InteractiveTransition.swift */; }; + A6078F2E15C7AEE2E69AAACEAF4A2E16 /* RNG_boring.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0742B711AB7B5FF0D93C43D48B5D760 /* RNG_boring.swift */; }; + A6624C7C8092B9B4BB0FE7B551279C8B /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1073FF82D7B94967CD02A0F194F4DA56 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A66EA069CD81F972736548BA4DE4E1CA /* ReadWriteStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9504D4A1C7E0AA4D1702B0383635B87 /* ReadWriteStates.swift */; }; + A68ACC24048B3C426D38421731E4CD0D /* RLPDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71ABE852F923874D69D84A7984A91B85 /* RLPDecodable.swift */; }; + A695EDFB21102F67B4C6529A87A94929 /* CNIOBoringSSL_dtls1.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AF365C7AB26489C06FCFE902F8A964E /* CNIOBoringSSL_dtls1.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A732554841675F7604445175F2DE09A7 /* MathUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474EC5560C6B9561B3B042241C5711F7 /* MathUtils.swift */; }; + A7422ED90013F6BC9FAA34AE7838C04C /* scalar_8x32.h in Headers */ = {isa = PBXBuildFile; fileRef = 494D5E014AD83FD2360542A6642709E3 /* scalar_8x32.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A7B20E66948F7AB9FAD6B822A0907AE4 /* WriteCapturingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECDD0AF7AD61EEDFE08E3FA3A87EC4D /* WriteCapturingHandler.swift */; }; + A7C03AB52CB4FC6A80B8746A4AF6A342 /* s3_both.cc in Sources */ = {isa = PBXBuildFile; fileRef = ADCA520ECD233B494FD505EBE481F731 /* s3_both.cc */; }; + A7DC8EA2A5607E09F167AEADBD0645EE /* SendingPushPromiseState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FDC10C92DFE9FA6A8021029EE54A1E /* SendingPushPromiseState.swift */; }; + A7EAE08B437791F211D42F68D2A4CBAC /* CNIOBoringSSL_obj.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F8615D099F6945070841273BA82F9DA /* CNIOBoringSSL_obj.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A81F5E7AC6A31EA09FB5B0CD5ECBA22E /* Exponentiation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501D740D00D470DD9CA9FE7C785F5EA5 /* Exponentiation.swift */; }; + A8436E9E56A2C6BAD1A959CD14123E7E /* block.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AA17A649FAE8060A699174BFD83D0C3 /* block.pb.swift */; }; + A888ACD36DC8E310636E797F7791F6B6 /* PopupDialogOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F45C4839DB209C95B4EFAECE05A4A33E /* PopupDialogOverlayView.swift */; }; + A8A29192006F6D9AC7670F3388BD3E15 /* BinaryDecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F227685ECEAB7343AD33F83D2C1A38 /* BinaryDecodingError.swift */; }; + A8FB47C71F7057936055737189584B39 /* CNIODarwin-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E71DDD9AEF01CB88D7D69EC16C54A094 /* CNIODarwin-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A90C432845167D1E63B82FFF07E57244 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70E4456A5BE8F2A335A5797D1098BD55 /* Value.swift */; }; + A9107234AE0F0D455E32C3B534266B85 /* CNIOBoringSSL_pkcs7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6164625CCEC1B1A4714B2CAE4C9E60C8 /* CNIOBoringSSL_pkcs7.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A91B62F5DF8EDEBE2821D2AFBFF25306 /* deterministic.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A6B5A15604556F5E309DBB8A743209B /* deterministic.c */; }; + A9252C247626E6F799ECEFD2030A4617 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + A9280CD3EA6149283C4BBB508CC7E261 /* sha1-armv4-large.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = C4C69845B2B0DB9185C23E3B1BBBB22E /* sha1-armv4-large.ios.arm.S */; }; + A95A8D3A20122AA075B523B7BCCF6C26 /* FTypeKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DAE52D6C3B2FC9C548C6B1D2539123A /* FTypeKind.swift */; }; + A96ACE11F57CBE08CC0E5D09FF847644 /* ctrdrbg.c in Sources */ = {isa = PBXBuildFile; fileRef = 8A0B2BF8BB6F85B0D453ED8C0B12FC40 /* ctrdrbg.c */; }; + A972F08843D4B1003BA8469D736F5FBD /* Server+NIOSSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC169C7AA03EA4BB6D8B3E3015E4C8A /* Server+NIOSSL.swift */; }; + A9A87DA629538D239C4B7401EB56AEB5 /* SDImageTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 54906576365FC97D0EB18ED670E894F9 /* SDImageTransformer.m */; }; + A9ED333C9D5490ED6E875E3947CB4CFA /* ServerInterceptorContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E0B6181CAC16C08E1B995F751D98DEF /* ServerInterceptorContext.swift */; }; + AA14752B985943EBA724A69DF73AF9BE /* v3_int.c in Sources */ = {isa = PBXBuildFile; fileRef = ED387E83E449F79ECE1D3527813215E3 /* v3_int.c */; }; + AA16C3F0B3D3178D62016E5FBB5E4A22 /* v3_extku.c in Sources */ = {isa = PBXBuildFile; fileRef = 4866F4D0DEA7C704FFE87F04B0E49967 /* v3_extku.c */; }; + AA1C125E770AE299227ECFF33C5F1B94 /* FixedLengthFrameDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E05C5D12EF55A7458060ADF19DA4B30 /* FixedLengthFrameDecoder.swift */; }; + AA1C68A34DFE6909AD17E03D4D02804E /* pcy_node.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B10E2920D0B16D49380B9A007D044A8 /* pcy_node.c */; }; + AA3AE0DF5E35D3E0D2CAE7972D69373E /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 93284C051CD0D2398503282372E442D9 /* SDAnimatedImageView+WebCache.m */; }; + AA66D62E105BBC2AA92FF7D188F468DF /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 31E0781A7DC6D1FDC2E73FE1098577E2 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AAB1DAD7EE0ADC803800D8AB46D927B9 /* LazyEventLoopPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3DE27288C920D21A42D6701815B7EF7 /* LazyEventLoopPromise.swift */; }; + AAC07F3FA5AF37257CA114ED88ADFFF3 /* SwiftProtobuf-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C7B1D3A5BDDEF2311211C6CA5BF0AF3D /* SwiftProtobuf-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AAD011FB4574B6E2B871A4B4DE866F03 /* kdf.c in Sources */ = {isa = PBXBuildFile; fileRef = 5028C4DCE5B10736EA096F4B9353E47B /* kdf.c */; }; + AB04DE035BEE708294D6F4AD6BEA9885 /* RecvByteBufferAllocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD38889D7644ED72769E8B659531B54 /* RecvByteBufferAllocator.swift */; }; + AB362E1D1899A06B9A83F6B6D74BEF5D /* ghash-ssse3-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = A3446BB29394B0DCC0BCF77E214CF218 /* ghash-ssse3-x86_64.linux.x86_64.S */; }; + AB4CA0AFA9EC77EC975EA03C914DD0F5 /* ecmult_gen_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A97EB307AB2A06BDBEE9950E524D56 /* ecmult_gen_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AB66E4C0C00A3E127E9D3326F14F65AD /* HTTP2FrameEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF2F71AF6DDAF0DB59F19D7CE5D44651 /* HTTP2FrameEncoder.swift */; }; + AB746F2E2A6E7B18964CF833F37A76EE /* v3_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 6081F7CA47E05CCAB868E82D6A8D6A3E /* v3_info.c */; }; + AB783D5B6EA24609BA0B9099ADA68E8D /* SwiftNIOExtras-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CAA35DA1D30329F0BCD279A4029063A3 /* SwiftNIOExtras-dummy.m */; }; + ABA5315129C1DCFCAD315B9973B732C1 /* tls13_enc.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF8DDEA73D7A9A0D0BB5BE9F00FE3CA8 /* tls13_enc.cc */; }; + ABB53A30025655067FC1A3ACC2F688C7 /* p_rsa.c in Sources */ = {isa = PBXBuildFile; fileRef = D800D3A45C73A256CA1CA8ECE8173369 /* p_rsa.c */; }; + ABB81BFFC4D7D91965AFE61F512BF09E /* a_strnid.c in Sources */ = {isa = PBXBuildFile; fileRef = 764EEE0418CD889331FABF1FA4208DAE /* a_strnid.c */; }; + ABCFCC4C4A69BF42F3E65FAF2A29DC75 /* ConnectionPool+Waiter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4747431DC93868AA2BE766A668E675B6 /* ConnectionPool+Waiter.swift */; }; + ABEAA41C35A6CD25C93E622FB129C379 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = D57C247374F68157B55FF81C04D58B22 /* SDImageLoader.m */; }; + AC7DE6FE7FDBBEA23A376869515ED036 /* block_seal.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D33AA2633CE5706C3EE91FBDCC3D29 /* block_seal.pb.swift */; }; + ACA0F212F4B81B2C29FF2A2BC56ACD34 /* StreamEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C155581852CB3AEEEE25F846462DAE0F /* StreamEvent.swift */; }; + ACD85778F812D36BC98C73685D3BB63C /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92F1410EB55386BE15D50D734605E346 /* Argument.swift */; }; + ACDCD1E99F1B233F37D6A6AE598F1013 /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F13848373B9F209766DB133A0176976D /* CBC.swift */; }; + ACE606619281328C18BE78506D37587D /* spake25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BC863125BAAAA379F9D46B9B09FA011 /* spake25519.c */; }; + ACF1D580603432F23AE87E1DB8BFED8B /* ssl_aead_ctx.cc in Sources */ = {isa = PBXBuildFile; fileRef = 150528A791ECFD7B40965F1B68C64876 /* ssl_aead_ctx.cc */; }; + AD0CFDA140E346502935BA58225E6EF3 /* SDWebImageDownloaderRequestModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FED0FFA4EB5C277938AE6448CC17382 /* SDWebImageDownloaderRequestModifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AD2F68F52B04607489BCFBEE3FBE0BF6 /* BSDSocketAPIWindows.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15EEA51CFF44E7DD7562A964143DF44A /* BSDSocketAPIWindows.swift */; }; + AD801317EBECC0C2ECE1FB7D29D8F63A /* ConnectionKeepalive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABF0F0C625CF2ABE592F32D09A9B9CD /* ConnectionKeepalive.swift */; }; + ADC47F1C5A8C8EF36F50DE82CEC057F5 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = B76FE45529FA7930D3992ADBA1E05047 /* Network.swift */; }; + AE009249C47986771A5D877A59B9C181 /* CNIOWindows-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C495DA1DE6588F5E5C267D67D0B3A67 /* CNIOWindows-dummy.m */; }; + AE09121C81E1F81F5671B10FAC50EAA2 /* SwiftNIOConcurrencyHelpers-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 066CA9FB8FF27BE3124222A30B4AF4F8 /* SwiftNIOConcurrencyHelpers-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AE14F20041D68EBA67F122B43E1D264F /* SubjectAlternativeName.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3792872F4F7E79DED08D802E38E942B /* SubjectAlternativeName.swift */; }; + AE4311E2B54BCD38E418D673F19E8E5A /* ClientErrorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2209F2B910446F43708EF208A89D3AE6 /* ClientErrorDelegate.swift */; }; + AE77CDAC417882E6017BADF780316526 /* SHA256Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7B48DD881BF8AE6BDC689EB96936503 /* SHA256Digest.swift */; }; + AE89C60F9CD4D6E1400DD304CE2A2B9E /* UIColor+SDHexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F72B636107B54802B4D852AE2F69935 /* UIColor+SDHexString.m */; }; + AF30386438AFE8B05D07AAF32AE4029E /* c-nioatomics.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E44DA338686E612A83487C6B0C5BFEB /* c-nioatomics.c */; }; + AF3463130EC3D84AF97EDF84BBA66DBA /* CNIOBoringSSL.h in Headers */ = {isa = PBXBuildFile; fileRef = DE9AD1D139042C4717863CEAEC80465E /* CNIOBoringSSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF42E7AC19979D422B1ED9FED09D93B1 /* scalar.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F7DDBE2182C2EEA7EE5F9F7EFA52A6 /* scalar.c */; }; + AFA808AD0B8AF05DAB714D485099D878 /* Call.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA0FE597DC1F3C6A5BCA04F2DA989A4 /* Call.swift */; }; + AFB2363051A846EEADDF248D61F698C7 /* InMemorySigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDE3529B4144EF636975040E170E6470 /* InMemorySigner.swift */; }; + AFE04C9F3EB37DE0F6DA19F6817907DA /* BinaryEncodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D076AF38527FFEC91314404B4572AF02 /* BinaryEncodingError.swift */; }; + B03D4343E9D6CA937BEA99244A0AB1E6 /* ConnectionBackoff.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6FC7C6947FF36F684A3994FFE7F76DE /* ConnectionBackoff.swift */; }; + B04279CC3476C6D75EDE63B360B89DEC /* SDWebImageTransitionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C76DC87990DC417BEEEA3A5BD223B758 /* SDWebImageTransitionInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + B08632DAF109AEC509A3390757380A6D /* p256-x86_64-asm.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 75CA24FC216CB0ED577D2C21D9993B55 /* p256-x86_64-asm.mac.x86_64.S */; }; + B0C202C52318CC3232B8B6997F6BC616 /* windows.c in Sources */ = {isa = PBXBuildFile; fileRef = F8DC87EB0A7B8E748FD15F55C32E2256 /* windows.c */; }; + B0CFC8A882453B026D543DD3E8D8672E /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E64BD1FC6EAC0B1F102580C6E0D46BA /* Utils.swift */; }; + B0DEC1B63B3731DF4D49CE1157DC2A9E /* vpaes-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 807BABDB923D2AA2EDE6E2C9564118CD /* vpaes-armv8.linux.aarch64.S */; }; + B0FE087E0B18253FF946D32C70AFC21E /* CustomJSONCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC28474AB6F09E4815ADBE0B747B4C5 /* CustomJSONCodable.swift */; }; + B11A25A0F5D114CF44470C84D29DB853 /* ChannelHandlers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C827709A684A15363ECD8BA2B8F989F8 /* ChannelHandlers.swift */; }; + B1249F9A182915B23188BB117C96C627 /* GRPCAsyncUnaryCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8BAD0DF4E234C3431802E561A851D6 /* GRPCAsyncUnaryCall.swift */; }; + B128DE666CCA7CF6B0F09411D8209A92 /* SDWebImageCacheKeyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 715987A64B4A51CE1A1DC6A99BD674C1 /* SDWebImageCacheKeyFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B176B65678CE2CABE44D8C4309345C29 /* empty.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8AFD4A17DAF112099B42485F0F640F /* empty.pb.swift */; }; + B1950D5C96D92C81E7F436920077982A /* PopupDialogContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C79F27D75309CFD6B32E480A9C7A0AA /* PopupDialogContainerView.swift */; }; + B2264B5C3C3B0BC8671968E961F1BF02 /* p_ed25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B343970A1011A392AEA4D1F350C12D6 /* p_ed25519.c */; }; + B22F40A0E0838D29531FA0CDD88340A7 /* Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 198BD051E2B3CA3FC8E558A4803C65F6 /* Internal.swift */; }; + B247E23747DCFDECABA4475BD5C178D1 /* pcy_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 547798325CC1938A46B860161C33CB10 /* pcy_data.c */; }; + B26B94D74111CD5B59D48AB1E91141D8 /* v3_bcons.c in Sources */ = {isa = PBXBuildFile; fileRef = A3DFBFE8EDBE45EFA4304736E38C2792 /* v3_bcons.c */; }; + B287B47DACB981153E561026E38103FC /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F1E99C30A6589FEA05F5C1AFAFE119DD /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B2E403326D98D74B8F834D9B8411B058 /* fuchsia.c in Sources */ = {isa = PBXBuildFile; fileRef = 3B40B7E604BEB81EC871771768F61B00 /* fuchsia.c */; }; + B2E7CE9F90EA1EE141B3E1B069BBB672 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B86D1B76693FF2E7EB9A86C20BFAE1D /* Socket.swift */; }; + B3324EA2D5A61BFF8096863ABF5E14A7 /* CGImage+Accelerate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDB1BE639E6732DC1AA91B4160FC16A /* CGImage+Accelerate.swift */; }; + B381279C5D0A624F6C4DC88B82103394 /* cpu_arm_linux.c in Sources */ = {isa = PBXBuildFile; fileRef = 35A60E87A46C4A1C69DADD9B8B770A1F /* cpu_arm_linux.c */; }; + B3A0A5ECD1000BE87C76B29BD5461E28 /* CNIOBoringSSL_rc4.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D111CC23C86E6B89A4722CEDBB8FB26 /* CNIOBoringSSL_rc4.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B3A26162D7E624677A1187B6CEC89FF6 /* NIOTSErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32FE80B761FCC33AFB00DEE944FAF1F9 /* NIOTSErrors.swift */; }; + B3B0ABFD856BD653AD6B02E0A3D9868F /* PointerHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215056034A9C8EA82C4CC47FCD5CC9A6 /* PointerHelpers.swift */; }; + B3BE0D29DC167F2F394F7D3E34644F13 /* GRPCAsyncRequestStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27A0096D0F1AF00682CD50F6A4A08285 /* GRPCAsyncRequestStream.swift */; }; + B3D27A1C48FECD7C99188919A8DA288B /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1DD2C2EFC8604B688328D8CA7803D30 /* Comparable.swift */; }; + B41B0AFF039DE2739E9F782FF7755C89 /* digest.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB8BB999DEE6A0B9F8D50422812E258 /* digest.c */; }; + B420CE9CA1710BA4AC944CE59B4B4BF4 /* sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 23A6E2F9965A1F5B3DEF4780054926B2 /* sqrt.c */; }; + B497C92DC53B438DD27AB3DD79242637 /* BidirectionalStreamingServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7333AB5B013C75729FD116AC76867A4 /* BidirectionalStreamingServerHandler.swift */; }; + B4F4F64C189CD5FA3DE41E955B38FCA1 /* handshake_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 49538024CCF200F26D85AF212732E499 /* handshake_server.cc */; }; + B50064B1842CB43A87F7BB049EDCA78B /* SwiftNIOFoundationCompat-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 193F09AEBB44F16749D93F05FEDC1E59 /* SwiftNIOFoundationCompat-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B50986EE01C27FE64BFE67230DA3AA3D /* Google_Protobuf_Wrappers+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B115167F4570AF95A5C342C0CB230C /* Google_Protobuf_Wrappers+Extensions.swift */; }; + B509EDB7A6E94BBBBEE39B062C02A37E /* GRPCKeepaliveHandlers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3095F84099BAC79F6F6C210A93F1540 /* GRPCKeepaliveHandlers.swift */; }; + B531065FFCCBB26DC592750AD36072CC /* scratch.h in Headers */ = {isa = PBXBuildFile; fileRef = F8ED91581CA32AE9891FBC75E9198829 /* scratch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B55076FBAEC4E2C7A4F59A909BD04436 /* JSONRPCFraming+ContentLengthHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE889AEBF1F0F3D6CC3BC99186CBD41E /* JSONRPCFraming+ContentLengthHeader.swift */; }; + B5783BE56D88997CF017C75B95B454F7 /* SwiftNIOHTTP2-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D458F5EEF5F6D974F7A4B1C7B3B905FE /* SwiftNIOHTTP2-dummy.m */; }; + B58F2FC64967DFD9BF01AF85664E90BC /* obj.c in Sources */ = {isa = PBXBuildFile; fileRef = F84197669E7FAFA2A6430305A4B74647 /* obj.c */; }; + B58FBDD4A8D7B7ADC8863413094D4A3B /* i2d_pr.c in Sources */ = {isa = PBXBuildFile; fileRef = 0686F287BA1CB4499AAACB0B42046194 /* i2d_pr.c */; }; + B5A1D2506138A3312BBA4444388B840D /* thread_none.c in Sources */ = {isa = PBXBuildFile; fileRef = E7F100F1D0CF11736A4A00AE46E8435B /* thread_none.c */; }; + B5B662BD5AECB16F053AABA331CE462C /* a_gentm.c in Sources */ = {isa = PBXBuildFile; fileRef = 47B239F6E85774E499B22605B3CDB384 /* a_gentm.c */; }; + B5BF1D01D17BCEFAC594BD0AA2FEA001 /* v3_akey.c in Sources */ = {isa = PBXBuildFile; fileRef = F9244E289417969DA18D388116361D90 /* v3_akey.c */; }; + B5F97901641027AD01C6BDDF0F93A37F /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0925800F0F3DA00319FE641B576C727 /* UInt8+Extension.swift */; }; + B603F1FCB8AA2E158DB796D8D83559EA /* JSONEncodingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07204D813C49972B4CF09D3F10D926A6 /* JSONEncodingOptions.swift */; }; + B70113762D0008B21195B8BFD64DAF15 /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98C0F7953BE8F0580FC9DD009C52546 /* Cryptors.swift */; }; + B7091199F7AC91AC3616E80016CE96E0 /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F03CB0E6217D65140886F475B1AA61A /* Digest.swift */; }; + B720378C74F3FB6E7F8C27ECBD9CB0C3 /* RequestBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA597A99CDB1A93C02D695E01E790C6 /* RequestBuilder.swift */; }; + B722E31FFDC5872960240360EC552FF2 /* x_crl.c in Sources */ = {isa = PBXBuildFile; fileRef = 766CA41AA03E28649D02A18EE8F205E5 /* x_crl.c */; }; + B74E2B3FF06C36CA30F399CA55F2ACE6 /* SendingRstStreamState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81FAAC53CF7CB572F1A0713851F727B5 /* SendingRstStreamState.swift */; }; + B74FE5CCBF1C5720ABEF276A73A1676D /* CNIOLinux-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B87A50A9B5D40943EDCE15F73F41D23A /* CNIOLinux-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B7569E77F21DB44F3FB454A1838580E2 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 965C295B24640A3C38DFFA48A87550C3 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B8227C8AFCB69A1C642A9173CF871D2F /* forkunsafe.c in Sources */ = {isa = PBXBuildFile; fileRef = 947D727E23A36EA2E057AA2043E55414 /* forkunsafe.c */; }; + B8231AB7A1921DF1171E8436FCEAD26A /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBE1AB9F1660D3300D0A277E7A595F0 /* HMAC+Foundation.swift */; }; + B830185E1C7ED31627FA1B8775888EBF /* TransitionAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E9A160FE84EE321E41281FB995E30C2 /* TransitionAnimations.swift */; }; + B832FC757137322A12712A3C4BFF509C /* oct.c in Sources */ = {isa = PBXBuildFile; fileRef = 6ED3A5996E262D0EF0535AC7C4137969 /* oct.c */; }; + B88C351562CE8FA4255EA9023213BE4E /* SDGraphicsImageRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = E81B478A234CDAB017868988B1FDA209 /* SDGraphicsImageRenderer.m */; }; + B8E546A8E7D00B7C43323546BD0D4045 /* DynamicBlurView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8E7AF066F0911188C195EF539855E4 /* DynamicBlurView-dummy.m */; }; + B908EF2F4DD8AFF1520A554C5457885B /* cbs.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6AE05284A13FEEC2B201DA0DF6196D /* cbs.c */; }; + B90AA99B9252253631CE5F103E1A8FFD /* HTTP2StreamID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F63BA50A6FCCC7315BE388EE36A1A01 /* HTTP2StreamID.swift */; }; + B91DE28186CBFD37620730ED7E3B3361 /* asn1_par.c in Sources */ = {isa = PBXBuildFile; fileRef = D81F70F67EBAF255F9AB9DE70BB28A19 /* asn1_par.c */; }; + B9358AEFA08C2A82020460337AE934D5 /* CancellationError+GRPCStatusTransformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F016C3BECF713FE493125FCC61F487 /* CancellationError+GRPCStatusTransformable.swift */; }; + B96BCDA4AF618BF171AA502CC84FCD8F /* Data Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA91C8A665F57B9A91C735498340D88 /* Data Conversion.swift */; }; + B97B1A6B52C898386522F3A2E255B792 /* conf_def.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DF2315104F0841E7D1F426ECF1DF5BA /* conf_def.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B987BB03FB34EDB2F13027E000DD1C8E /* liburing_shims.c in Sources */ = {isa = PBXBuildFile; fileRef = 98F5C5815636CC2CDB148C52AC2D5275 /* liburing_shims.c */; }; + B9BD8B8855D4A37EF85675FB83C8DA78 /* cpu_aarch64_fuchsia.c in Sources */ = {isa = PBXBuildFile; fileRef = D7C73208AD27DA45312A80946D6185E9 /* cpu_aarch64_fuchsia.c */; }; + BA0D388D2D149F70E82F3A059DAA481A /* ProtobufMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 268BA908D38F7A6EAB4AB545DEE155A1 /* ProtobufMap.swift */; }; + BA149B567209375CB8310871618C5D50 /* CNIOBoringSSL_chacha.h in Headers */ = {isa = PBXBuildFile; fileRef = 72DD492310DBB3DC25CF83043BD87850 /* CNIOBoringSSL_chacha.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BA1D0752A4EFE5057AA96B56B34D5063 /* delocate.h in Headers */ = {isa = PBXBuildFile; fileRef = A8AC96E184F6A709EA24AD89B6A214CC /* delocate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA354A3C3E0FEDF3D5B0556BE7E9A55F /* obj_xref.c in Sources */ = {isa = PBXBuildFile; fileRef = A2B6F66717F15163B79818319D00A6E0 /* obj_xref.c */; }; + BA5BADC02C792DC56412C1E88E2C933B /* rdrand-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 9F44F5EF9CCF2E1F401C612C898A6846 /* rdrand-x86_64.linux.x86_64.S */; }; + BAAE8BAEBE55A4662CD14F0AD6FFA1B2 /* FakeChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96BA613367923BBFF2F2DBD0354DAF1 /* FakeChannel.swift */; }; + BAC0CB1E4BAA509CE3C089F5B05CEB4F /* ConnectionStreamsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8ABAFE8C989A5EC3349EB1395B6C86 /* ConnectionStreamsState.swift */; }; + BAED169CF9230E5C3F0AC939B8B6FB7E /* x25519-asm-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 2F6F9372C9AE6F2B9A7BE59E5A636A92 /* x25519-asm-arm.S */; }; + BB35EAC57CE1C9F84889A8728874D311 /* NIOTSListenerBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98CA796CC028075D66589D2DD00FD17 /* NIOTSListenerBootstrap.swift */; }; + BB506D44EC0BB9223EE79F583252AE80 /* CompressionAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E6A03147D0A9EC2FDEB805FDBB269D /* CompressionAlgorithm.swift */; }; + BB68AACB02D968CDB668AAB5C10CA4BF /* armv8-mont.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 83D2B264237083DDB90A3A3B5618FCA5 /* armv8-mont.ios.aarch64.S */; }; + BBC8DDB19BF1C2F7730EE3D70F6898F8 /* rsa_print.c in Sources */ = {isa = PBXBuildFile; fileRef = 383D394039DA0D40F1AC14793FDBFB62 /* rsa_print.c */; }; + BC128C004F898A480D5BD3D3A06D71D7 /* eckey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F218B3EC4501CDBF5A97164AEFEFB25 /* eckey.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BC5441D127E656443122BBF1944E04CC /* bn.c in Sources */ = {isa = PBXBuildFile; fileRef = 30B9ECDEF200F0B0B7B43576A64F2D47 /* bn.c */; }; + BC8B0C073D8858F51464F9253173FD49 /* CNIOBoringSSL_ripemd.h in Headers */ = {isa = PBXBuildFile; fileRef = 8DA7813BCD0DDF69755DD1838DBD2583 /* CNIOBoringSSL_ripemd.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BC900F4AB545CCD918B220411187D08E /* PipeChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682582E511D4CFCB4AC801EC5E6C7A42 /* PipeChannel.swift */; }; + BCABD8D30EB03A91A2A446AF0CD7F6C6 /* Logging-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = ADB47706A4A069D6173C880CA9EEC239 /* Logging-dummy.m */; }; + BCB2A79CBE1B95E0F7E225A15603B608 /* assumptions.h in Headers */ = {isa = PBXBuildFile; fileRef = D36C79BBBBA3A45553902A70E34CFBC1 /* assumptions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BCB7B61DB37BA3EDB8CBBF258DC66446 /* UIImage+ExtendedCacheData.m in Sources */ = {isa = PBXBuildFile; fileRef = 676876EDFF467DBF93ABF12E82EDD8AD /* UIImage+ExtendedCacheData.m */; }; + BD074722CD72470954ADB5B1198E01C5 /* NSData+ImageContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 201EE10DB004216D5209886FB7443829 /* NSData+ImageContentType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BD1A7F825CBFFAFD5548ED4FB435BE29 /* Tweak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51896288820E9AA5F8A6FAC96A977C74 /* Tweak.swift */; }; + BD7909110122EA2883543699E65D6237 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8424D5BFC4301B7A3E986E42A11F4571 /* MD5.swift */; }; + BD89EF7B99AA3E4C79E3501FA539208A /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC25E5C0E44AD4B8FE7567924453006D /* System.swift */; }; + BDAEE0AE18AAE13FFC15096AA8E4B659 /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2C162FF68AE73704F1D0370CBB8E821 /* IO.swift */; }; + BE1ADAB398269B1A67B190CFA10CF328 /* CNIOBoringSSL_aes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DF64CD5C8E782FFABAFC4FF7AAF64C5 /* CNIOBoringSSL_aes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BE4B2817A0465897840B7D3AE572E6CE /* UnsafeRawPointer+Shims.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2B535D0CA6C53122205C5A6CDE8EFC0 /* UnsafeRawPointer+Shims.swift */; }; + BE649A29E5FB32C54FDAE55994804F6D /* SDWebImageOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = A263437A804DE2A19CE442E5E628CE9D /* SDWebImageOperation.m */; }; + BE687A95786CFAB7E099F2F55E020294 /* FCLError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A1048B1348EB81E26D98A91883630AD /* FCLError.swift */; }; + BE8BA963210EB262B1520E9E522CB212 /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 2CCCCBFDF06E3D222AD3E72FFE4BD813 /* connect.c */; }; + BEA309F837B5371FBD3753241079D60B /* CNIOBoringSSL_dh.h in Headers */ = {isa = PBXBuildFile; fileRef = 22D5900AE5CF42D49A30529330F50352 /* CNIOBoringSSL_dh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BEEC4501CE6C7501A0DE1868E350FE99 /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9396DDDD1A58F1D7F4FFD73D7B3E6B9 /* PCBC.swift */; }; + BF2EC78C3ECBEEBF388F34D3791445AE /* SwiftNIOConcurrencyHelpers-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4222400A280D18AAD5AD7F866EFF9A6C /* SwiftNIOConcurrencyHelpers-dummy.m */; }; + BF6B694AA2B8D3B64A9F4ABB24BBA8BD /* MercariQRScanner-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE986B653115BDA8E79A7E164F44CFA /* MercariQRScanner-dummy.m */; }; + BF7991AF3BAFFFB3A3BD44A70A0A798A /* GRPCServerRequestRoutingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B043DDB45818671A86CC424B821B2D /* GRPCServerRequestRoutingHandler.swift */; }; + BF813D6A70BF38AD42D0D53F59806E6D /* wrappers.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F5FF3D59B1851F9A4C9823F57AC5981 /* wrappers.pb.swift */; }; + BF8B28D4A5F95D42B8BD313EFCEBE949 /* Logging-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 024DE6CD691DEF3BBDAE8A50B8D56DF0 /* Logging-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BF9A6E2CB8F67686C4B7E04538664919 /* UIImage+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = CF3424F9089EEA88A0156E122EE2E7DD /* UIImage+Transform.m */; }; + BFA1E1EBC7BB2E23BFCFD8D554705CAD /* by_file.c in Sources */ = {isa = PBXBuildFile; fileRef = E3E05A06E1D1AEDA186039A82B0C3048 /* by_file.c */; }; + BFA351FBA9AC889942F0304B372AD1DF /* ClientStreamingServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD1453B26707E3BBFCC6A2E2380775C7 /* ClientStreamingServerHandler.swift */; }; + BFACABBEE75963CB9A2F46AC34367195 /* TransactionProposalKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0CB49F4D5C20983310803D707A2EAF9 /* TransactionProposalKey.swift */; }; + BFD0839D147B1701518C1F48C299CB35 /* FieldTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 202EAE2488A3312FC2F0C7CA280CF2A1 /* FieldTypes.swift */; }; + BFE809D08A0710648C7A6BD6E1D492FB /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = A230DA09837C434CE63C8CEC8CB6FB07 /* hash.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFF97881904F1970C96A0B3D13DEA33F /* SwiftNIOHPACK-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A18A2EEDDFBCBE87D6F005B10DB418F5 /* SwiftNIOHPACK-dummy.m */; }; + C009A108BCA10592B4D3A3496F431498 /* rsa_pss.c in Sources */ = {isa = PBXBuildFile; fileRef = 36BCE89A2F094A56A37CE24E51E8478E /* rsa_pss.c */; }; + C021850F6405E4421315CCABC6D164F6 /* ServiceDataType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699A3089D1F3A798E655A7A25AAEF23E /* ServiceDataType.swift */; }; + C02EB9B65A254C5450BFE7FD06E78727 /* ServerHandlerStateMachine+Draining.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBF98C528EC0C5C2B7685286984AAD90 /* ServerHandlerStateMachine+Draining.swift */; }; + C03E4D92BFFDB72F250853C5D099BC04 /* cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = E668AFE040CFD1CAC7A6D5CA192E1586 /* cmp.c */; }; + C0CBB75BAE53A402F4E93D6E15D16FB6 /* JSONDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C57DB877D0B18BE81B5991497EFB83D3 /* JSONDecoder.swift */; }; + C0D2BFCF10F21ED7122493210B5638F2 /* BaseSocketChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41A865E94909DA53300849ECE5936E1 /* BaseSocketChannel.swift */; }; + C0E2645172F1D32948A46B6336B1D6CE /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C0A6F2A5DDB51F0F498518600BB7E21 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C10273C7D9B2212C16FB9D8EDF8C4939 /* PopupDialogDefaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58374516B6E39546FBBB6E9BCC08E48 /* PopupDialogDefaultView.swift */; }; + C13A7DF7136FD0687DC4D803AB6382A8 /* CCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 484B18FCC75A69141F249D9018FC6E79 /* CCM.swift */; }; + C1514EB1781043AFE7AE81B3730B49BA /* v3_bitst.c in Sources */ = {isa = PBXBuildFile; fileRef = 5F492BAA38208825BA9D871CE8E97BFC /* v3_bitst.c */; }; + C15B3F89E6F83DC9CCB14903FC5D80C5 /* SVProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 891F6C38DB160984768F7ACF77C04993 /* SVProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C1CCD14D7F52BAE64BCCF96CAF9A1A8B /* HTTP2PingData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F421E9463495ED8B3A343284F5A95ECB /* HTTP2PingData.swift */; }; + C1FBDC8160EA3EAA854EF57D9883DEA0 /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EBBC38E8B4526897E288AC3935AAA62 /* Data+Extension.swift */; }; + C201A9E63BBA5D8B51FA064382ED969B /* MethodName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA5524014361D68DC8908D92BA5CB195 /* MethodName.swift */; }; + C227932EAD480FF974148FED7B41B66B /* AnyUnpackError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D02C1E0AE5E91CDC76A4FBFEDF72DF8 /* AnyUnpackError.swift */; }; + C2378DC0D6CC3598C0DB121D0686544D /* precomputed_ecmult.c in Sources */ = {isa = PBXBuildFile; fileRef = 32A8A8AEB4DC5E8D8F8540AE22FA44F6 /* precomputed_ecmult.c */; settings = {COMPILER_FLAGS = "-DENABLE_MODULE_ECDH -DENABLE_MODULE_EXTRAKEYS -DENABLE_MODULE_RECOVERY -DENABLE_MODULE_SCHNORRSIG -DECMULT_GEN_PREC_BITS=4 -DECMULT_WINDOW_SIZE=15"; }; }; + C27BD8C6B4E713A8E7B7B76B80E45823 /* SDWebImageDownloaderRequestModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = ACBF6340035E1DD58EA9E0188DD22824 /* SDWebImageDownloaderRequestModifier.m */; }; + C27C43D1F2D365DE70BAFCB41FECB107 /* main_impl3.h in Headers */ = {isa = PBXBuildFile; fileRef = 7175926837E08AC3D16D3F34A114B9A0 /* main_impl3.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C2D82385F4FDB67F6613CBBE8E2BD850 /* SDMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2693B01988B6DE451619238CDDD1BC02 /* SDMemoryCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C2DF6E0594E6D50A8304433BA8015BAD /* a_print.c in Sources */ = {isa = PBXBuildFile; fileRef = 9AF08C7D22A2CD6829F32301D191B54A /* a_print.c */; }; + C30CB0C72BC6AAFC60C7F55706353F24 /* cpu_arm_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = 32DF3DB2C8D58227D79CBCAD10A7CC06 /* cpu_arm_linux.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C338246650DC5F473FAD560883706248 /* ghash-neon-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 81B21E3A326D5E9975392E40E1B3C9D7 /* ghash-neon-armv8.ios.aarch64.S */; }; + C3570531D80D2D9ACDABBDC4D9635265 /* aesni-gcm-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = BD7145615C4722938094415282B4CC4B /* aesni-gcm-x86_64.mac.x86_64.S */; }; + C3C84ECFBFF2546938B4149639598DCF /* CNIOBoringSSL_tls1.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B030C622B398C956EE39FAAA7A68289 /* CNIOBoringSSL_tls1.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C3DEE99279FC4719801242BD2F629FC9 /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = BBEEB47144B65631102F7AFC833EB4DC /* socket.c */; }; + C42A6C89C3FBE7C77A2797827B51B65F /* SNIHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D1C37175511A3E8DE33E96132632A6B /* SNIHandler.swift */; }; + C4762BD85B320B9EBE199F7CDFBCED12 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B24040089D9C5D78D870471EDDA24BEA /* UIImageView+HighlightedWebCache.m */; }; + C4A78B8FC2DC76FBCF43D9D53BF90767 /* SDImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C000342FB0B9668D6C2C263D0D3897D4 /* SDImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C4CD271FF070F78D8BF54618838E7FAB /* TransactionFeePayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64CC2B8BD5A968C8ECE43D8CCE8B0112 /* TransactionFeePayer.swift */; }; + C4DA7CF646C65783D9A7A79DD5F0F24E /* tasn_typ.c in Sources */ = {isa = PBXBuildFile; fileRef = 08C897EDF2921AAEFC00DE41E4E472F1 /* tasn_typ.c */; }; + C50CE66819CF8D303172E3184A877FD1 /* GRPCAsyncServerStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF13C39A51927AE32AFC954ED9417057 /* GRPCAsyncServerStreamingCall.swift */; }; + C5405630762B9EBFEF7C48D595C9BA13 /* EventLoopFuture+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5BBB57A935727EEF21A5AF26FE7A1E /* EventLoopFuture+Deprecated.swift */; }; + C54F0EAE413A390A7724FB77B2DF7C17 /* derive_key.c in Sources */ = {isa = PBXBuildFile; fileRef = F61BF97A058E4380C2240049EF36E9E6 /* derive_key.c */; }; + C55A2D001850D3F407D968CFF1C545E2 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D4A33464B8025591F17F626782668E /* UIButton+WebCache.m */; }; + C57BCD825F6491DC5DCA9FBF9D239B8A /* padding.c in Sources */ = {isa = PBXBuildFile; fileRef = E27145F5259634BD1971D2919DCF19EE /* padding.c */; }; + C5D4FD6E526D4804CB9BBC71A034EEF8 /* sha1-armv4-large.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 3FC68B1806253222E7DEC3A03FA57876 /* sha1-armv4-large.linux.arm.S */; }; + C61E2AF98307341D5AA172CDFDAA94F2 /* cfb.c in Sources */ = {isa = PBXBuildFile; fileRef = 968977F2912D1CEA6A50A6AEBE7039B9 /* cfb.c */; }; + C65E405C8A8CA760FD31087C7B53A41C /* CNIOBoringSSL_rand.h in Headers */ = {isa = PBXBuildFile; fileRef = 381018DE63E6716965F88F348EFBA40B /* CNIOBoringSSL_rand.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C6A6BC0CCBA4E6B2CD5222E3A1DA0530 /* a_octet.c in Sources */ = {isa = PBXBuildFile; fileRef = F92FBFA8D72DAC4D564472BB97707870 /* a_octet.c */; }; + C6A7CB5C6E0F50E578E6F446ABF503DB /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 261522E8FA2A52D990467B27DF2A76DB /* PBKDF2.swift */; }; + C6C448D2D192186FA58E02CFAC79FC0B /* CNIOBoringSSL_err.h in Headers */ = {isa = PBXBuildFile; fileRef = 553CF428A3057584E0E91F727869C3B9 /* CNIOBoringSSL_err.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C6E38181CD7752A6B54CFE2972BD695C /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE18259BFD9CE81EBAE94B05B4902E80 /* BlockMode.swift */; }; + C716D1D1B19476E661F8A9C2F01F2D1F /* JSONScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61329CB4B0AFAB6D6A0714878415F6E3 /* JSONScanner.swift */; }; + C7743E4568465EC45D0C91259D639200 /* SwiftyJSON-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = FDDD2D73E4D2EECF3B63527CD28F21CF /* SwiftyJSON-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C7E8A80BE6BE5452380D8CA71F278B8A /* SDImageGIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = BAC97623A3FE90868CDB8E3A6963E85A /* SDImageGIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C81C295AD40E8C4267DA5A82701DB73D /* ConcurrentStreamBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21651EE6A057DD7D2ADD0FBCE37B206E /* ConcurrentStreamBuffer.swift */; }; + C8471B00E86DD75DC0245CDE589FD1B1 /* montgomery_inv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BD11E4F78AC8858E805F4B175704574 /* montgomery_inv.c */; }; + C84A551AE92BEC69BAD42BF9EA9B3861 /* Blockchain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56553376B99AF7775384AC1BA59FEB9 /* Blockchain.swift */; }; + C8DE48466E0FB1A680E386533D4565D6 /* ec_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 603DB6327F928979DB143EDB3B2E94FC /* ec_asn1.c */; }; + C8E452B697F515C8E92880290551DDD8 /* InboundEventBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE42292A4FD16EE1A12341490A57D2C /* InboundEventBuffer.swift */; }; + C943D9B8DC4F913A671DB05F6B87CA1A /* pem_oth.c in Sources */ = {isa = PBXBuildFile; fileRef = C43B966FB585F6DD13A697D96166E616 /* pem_oth.c */; }; + C954E2D071119B440BAC0DAF015E28C8 /* QueryName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F05FEE62851E94A769372DC3CD3E8335 /* QueryName.swift */; }; + C990A390F1BCE9973A3688EABFCE69C5 /* SwiftNIOCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CCBEED9840A524A1F782D870BA02CFE /* SwiftNIOCore-dummy.m */; }; + C9CDDC9606B4064A0C2F375F7B96E0FF /* gcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2FD0458620342EF1241D8233FE11526E /* gcd.c */; }; + C9E4E81122FB77A6DF9E881B669F1AEE /* v3_ocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = AD97C485447932CFD80DAB09622E758C /* v3_ocsp.c */; }; + CA16CFA4484506D2C0D1BD2EF539960C /* ContentLengthVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B7003D2F4E5985B21868B438D9AD55 /* ContentLengthVerifier.swift */; }; + CA59BD4AD06D1BB7CB263A2E7E3CCC7B /* polyval.c in Sources */ = {isa = PBXBuildFile; fileRef = E8263A32885981CDD291AF8C313E0131 /* polyval.c */; }; + CA631C7462B02F1518D850BE655EFA45 /* GRPCChannelPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23E55556354D48D4FD7988BAC017D751 /* GRPCChannelPool.swift */; }; + CAD9303799AFE797D36BABF4BCF117E7 /* handoff.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1449BA3246ACAD59795CF756778E324E /* handoff.cc */; }; + CADEF3031D0EA9FD1988ECD451452A7D /* NIOHTTPObjectAggregator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67656E3C8BABFA1F2CC575CA2F9BA96 /* NIOHTTPObjectAggregator.swift */; }; + CAE7E576E76FC8A5CBFA243957D375CD /* d1_pkt.cc in Sources */ = {isa = PBXBuildFile; fileRef = C004D6E82E62266875A85C4DD9BFC4D1 /* d1_pkt.cc */; }; + CAEC75A8C619CF4229CF00D8ECC8E04E /* scalar_low_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 75640331ACC3A5E4B6CBA6DA62F539A1 /* scalar_low_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CAF5FF5A5ACE199F8DCA016F70EC94F4 /* CadenceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3621A9CDBCA3A77391C8DAAEE9B91FE4 /* CadenceResolver.swift */; }; + CB060A42FC429C12A22523A000868A6F /* GRPCAsyncClientStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFAE696FD8F13F560F24B8FA0116127B /* GRPCAsyncClientStreamingCall.swift */; }; + CB4D0153A0528F79BD6C847A9CD1953C /* execution.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB2A7A0E6EB30C6DFB50B3042E6EEE4 /* execution.pb.swift */; }; + CB55A2875AFA9C9BD41B19F1A4130B7C /* secp256k1_recovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 796848D95E9BA10B25A83BC6FAC6279D /* secp256k1_recovery.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CB6CA55E19F6E08B7CC05B1CD9F08AA7 /* MercariQRScanner-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DC6A748C2861B919099BAC626E9198D /* MercariQRScanner-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CB890B97BC4C6D4004BFF98A965F67F0 /* name_print.c in Sources */ = {isa = PBXBuildFile; fileRef = E25DB3244B2111EE09A01E72382F5CE3 /* name_print.c */; }; + CBC2CC340CD4CFCD60F9A30BC9E0955C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + CBDF03BED681B866C9CBC8E081651AFC /* BidirectionalStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87EE4554627E69785104159E7BA5F42 /* BidirectionalStreamingCall.swift */; }; + CC0097F80618AE7D909918D35A984ACB /* CNIOBoringSSL_cmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 235F85F616FBD4AFE863F4520D597CBE /* CNIOBoringSSL_cmac.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CD39817695A4DA222FF2C21FCE11A1DA /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 8156F58C8053D3FB9A6408CC8A13CDE1 /* file.c */; }; + CD42A502DBC1A533C80C7AE552A22F73 /* ObjectIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E1CC848E4930BB28B8B18131408127 /* ObjectIdentifier.swift */; }; + CD59912FBB10DB79E8252E0523019E0C /* secp256k1_extrakeys.h in Headers */ = {isa = PBXBuildFile; fileRef = F20791D229474FF6C088B7939C535825 /* secp256k1_extrakeys.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CE0C4C6147B74217171C6225159A0A50 /* hrss.c in Sources */ = {isa = PBXBuildFile; fileRef = 8F941B1AE0DE9669799EA5DB9604311D /* hrss.c */; }; + CE1A174322BF9F6998B6FD18C9ED362D /* ServerInterceptorStateMachine+Finished.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57C4375ED9A8C93CC09EE54BB969BC0 /* ServerInterceptorStateMachine+Finished.swift */; }; + CE3D6F2CD88E230621989B156610545C /* URLComponentsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1655554B8A6F6D0EC8890EEA2359462 /* URLComponentsExtensions.swift */; }; + CE4A5C96EAA37622F7E4D70C813FC221 /* CGRPCZlibp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A10F5D694C319F02E04D2C36464713C3 /* CGRPCZlibp-dummy.m */; }; + CE6053F20DD10A68A6F4D0E70784846F /* MessageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D920EEF436E21BBA439A27EB4D74DF39 /* MessageExtension.swift */; }; + CED332E4EE14635BF55493A9713E660D /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E9240AA999E52750C2D2F8E00F79E0B /* Rabbit+Foundation.swift */; }; + CEDF770B414C9A0CD5A520E1EB5E2B0B /* bsaes-armv7.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = BDEF01BE14B5AAA8285D70D93F0A5C6F /* bsaes-armv7.ios.arm.S */; }; + CEF2C8EBA49AA56A23A7BE0886949BA2 /* TextFormatEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B0D5A311F2E48AB02CD7CD89C77C14 /* TextFormatEncoder.swift */; }; + CF3800F8457C260F3A7927C32AD3881A /* ClientStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6839D1D519D3E405E6EDD9FBB2B5ED /* ClientStreamingCall.swift */; }; + CF5629FF0DFA9C0A78566093B28B5FAA /* params.c in Sources */ = {isa = PBXBuildFile; fileRef = 99C414B31E8A4D979898A38141A74B97 /* params.c */; }; + CF94AD566889FEEA32BB5E9076B1CF57 /* lhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 598247BC22A408C1AC2B3DB8892F821A /* lhash.c */; }; + CF9DCD561FEB5404D65B09EA77C1D688 /* v3_enum.c in Sources */ = {isa = PBXBuildFile; fileRef = B5FEBD4F255A8CA1957B51619B8FE6AD /* v3_enum.c */; }; + CFD207FB543B08C520B4EC4F6737097B /* Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = B087EA2FA49AD39D579628C77C4DF597 /* Path.swift */; }; + D01241AE09316D6EC4E98F684F515169 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 389A98E60BBEAB30A4712D63BE032A95 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D068C248672F2F8C73B19F82AE28A146 /* getrandom_fillin.h in Headers */ = {isa = PBXBuildFile; fileRef = E82FDE9D9EB4589FABB9CC02B87186AF /* getrandom_fillin.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D076B4E3F7CFEFDA13F9C8CA5C5C7C20 /* SwiftNIOTLS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A56A69DF36F5FA88C2DD9305B3D0C31 /* SwiftNIOTLS-dummy.m */; }; + D07F3C00344184A13BDD96CBC9EB5FB0 /* JSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC12B4AAB7E6AE3C249440811136A9B /* JSONEncoder.swift */; }; + D0B11036AEB4E11E3B1ECA363C58947B /* sha256-armv4.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 9E786D76B785BDCE148B66B3149FCA4D /* sha256-armv4.ios.arm.S */; }; + D0BFDACD74C58900345A29629E2E3B7D /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44437A9E7D313DF745E40B02473AE4CF /* String+Extension.swift */; }; + D0D2E9D1C53C43F8E38BD0808AF49EA1 /* ghashv8-armx32.ios.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = ABCDF59FB62F7013BA9A97B7F0EAD7E4 /* ghashv8-armx32.ios.arm.S */; }; + D1691005C5FF403516FCA539B0E8038E /* Multiplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9291ACAD1464AAA4A7957FAAFB7D197B /* Multiplication.swift */; }; + D181DB77994B119DA8E201BC4BE275FF /* secp256k1Wrapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A05782676F8CA2756C2C8E8A859BCB5 /* secp256k1Wrapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D19D08375F25913FF490193FBAA8614A /* LengthFieldPrepender.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE01B6CAAE26C2D87F755136F85C0EC3 /* LengthFieldPrepender.swift */; }; + D1A79DA0A4CAEDCEB4D59B79D4DEBD5B /* KeyedDecodingContainerProtocolExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0012700C73B952EE683DE5A28FD938A /* KeyedDecodingContainerProtocolExtension.swift */; }; + D1BBC12B87C64762B76D92297EFF659A /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BF593AB41A0AF0DEFBF863C4A465B86 /* CTR.swift */; }; + D1C2AA1139364C475172E188804E7BDF /* Floating Point Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B1FF1FFA5E7337517ABF817BC382321 /* Floating Point Conversion.swift */; }; + D1E33B121B8325A062BEEE4CA67CF77F /* poly1305.c in Sources */ = {isa = PBXBuildFile; fileRef = A3B296B9B264741B05D9FCA4EA296817 /* poly1305.c */; }; + D1F415CA1F34784DB7F02CCE24FDFD89 /* x_req.c in Sources */ = {isa = PBXBuildFile; fileRef = 8F347992C8E1B36C3F9FA4486BF8A1EA /* x_req.c */; }; + D1FCB300B05FF5B07E657659C562E5BC /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE17D22B26A6B724BC41BC503CCE139F /* Transaction.swift */; }; + D22B8317C08105B8A39DD1D05C262B0C /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680E3D81317929F61038DF8CE7A8290C /* AES.Cryptors.swift */; }; + D26627EAF46CB6E53DCBCF96B6797E5B /* x509spki.c in Sources */ = {isa = PBXBuildFile; fileRef = 6A85E08DFECD52E6D6CD9D01D71CEC16 /* x509spki.c */; }; + D26D909937F2AB2279973335583C0718 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9992AD91E5BD44D3B71483530B7FB33A /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D2765EBF4CFFAC92693C0427C04EBF51 /* ssl_privkey.cc in Sources */ = {isa = PBXBuildFile; fileRef = 626D6A6FBA3C4456357F4F9D36C475F7 /* ssl_privkey.cc */; }; + D28123212117C581CE08AADC49E61955 /* poly_rq_mul.S in Sources */ = {isa = PBXBuildFile; fileRef = 25E3E2C3D37FF81B175B64914C4DC51A /* poly_rq_mul.S */; }; + D2B49C219707EBE35482D258A5B960A9 /* CGRPCZlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DE1360C6D2F87387AAD2D043161B451 /* CGRPCZlib.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2C0EAD724728C5289C0D55B30F49B90 /* tasn_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = EE376EECC27E33D291AAD2610B267511 /* tasn_dec.c */; }; + D2C52270976D1BF8AEEDBF3D59D15EF1 /* CNIOBoringSSL_arm_arch.h in Headers */ = {isa = PBXBuildFile; fileRef = 066BA4BE605B6CE1001F8E954A29FA45 /* CNIOBoringSSL_arm_arch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CF6154C4F799BA6DCB03922C9278FF /* Google_Protobuf_Value+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C79850F447C2F84490990DD4AD8A54D3 /* Google_Protobuf_Value+Extensions.swift */; }; + D2EAAF790440AF298F4D91FD14A3B52C /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA903E3889EF8277F0D62AF77621B8F /* Message.swift */; }; + D35ECA1C6DDCDB82AE5BB7DE6BAEBA64 /* QueryEscape.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B586BCFD71CE4BCE197B2B172AE998 /* QueryEscape.swift */; }; + D3AAA0D0680BDD8506ADD0B6655868C2 /* NSNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70843714C0D9E382FCE8599C7E843D95 /* NSNumber.swift */; }; + D3EF7DCB4CE16AB91A467871353CD3EC /* BytesUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14CC3CB213ACC83D237A5886CA26B14 /* BytesUtil.swift */; }; + D45DD7CA09A8CF82B8287AB1581494F0 /* ServerStreamingCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5B2D264C8C540509FF1E9DF0014B42 /* ServerStreamingCall.swift */; }; + D4882F6EA281285B41A8397CAECA14C3 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A13056BABF3222698DC5A80B5463130 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D51906689701B3B3C93BF5DDE805A0F3 /* p256.c in Sources */ = {isa = PBXBuildFile; fileRef = 53392B8EDA78E9CBEDC1226D85F9EF59 /* p256.c */; }; + D5239ADD0689C3ADA13B2BD820BF7BAC /* BloctoSDK-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 030D13FA49F1EC5A5369417569B3F42C /* BloctoSDK-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D53A753DFC77FE7C3E879E91811001FC /* SHA256.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2E5F8322D7FD72559B6E7011F4E4922 /* SHA256.swift */; }; + D54C9D56EF5F66831AFD008E8B435E51 /* HPACKErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A13E071B674DC17F15A4DEB4243ECB1 /* HPACKErrors.swift */; }; + D556C63635E7A83C7A9B04FB104F7339 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DFF907064B630709019AC49B093B5D5 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D563294D5FDD5F0788E409D6C9EEE296 /* Cadence-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FA191A1A6EA690A2394B507BC8A1151 /* Cadence-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D56F5E0E1A036C494A3B19CD7BE10866 /* GRPCWebToHTTP2ServerCodec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBE3972F653181A13752675E7A877F2A /* GRPCWebToHTTP2ServerCodec.swift */; }; + D5C931A7EE31E76793DB60F0BAE03706 /* s3_pkt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5579F459567A501C9ABAD77F662B04E3 /* s3_pkt.cc */; }; + D5D3B649FA004615F19F0ADCD5E958D1 /* SingleStepByteToMessageDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B71DB02A1F498F92F0D682A10F39B7CA /* SingleStepByteToMessageDecoder.swift */; }; + D5D7BDA3AA7F9F267A93814DDD81A880 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + D5ED75505B2886AA29E4A1EBA912653E /* pem_x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 79C3BB6A22C6C64728AE5A3A9800B74C /* pem_x509.c */; }; + D61B2EFCA57203938C38DBD96538415B /* CNIOBoringSSL_pkcs8.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAD05B47CB8D574AC08834631342C19 /* CNIOBoringSSL_pkcs8.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D64CEC1A63908BD756A80F3D92578230 /* CNIOAtomics-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 649702361E788AB9B1259095141BB33B /* CNIOAtomics-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D6599C63A8E9C8C7FB6E79987391F7A0 /* Google_Protobuf_FieldMask+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA9BF98A613A23FD0E1127D868665C8 /* Google_Protobuf_FieldMask+Extensions.swift */; }; + D659BF981D133BC6B6965F20B3615967 /* ec_derive.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99AF05FFC3A4C4404BB9C4D287D3BC /* ec_derive.c */; }; + D6634BF4B9D8938A861D81E5047079BF /* account.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D79B0FD81FD36CF6C4267556FBAC5C /* account.pb.swift */; }; + D68F08F717E95BABFB43AE705D943426 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 7868B0CDEB78DBFB971E767F254140D3 /* SDWebImageDownloader.m */; }; + D692521557700730B1EE4ABD2EBBDC16 /* cpp_magic.h in Headers */ = {isa = PBXBuildFile; fileRef = 25C0642A6B82FB59C0FFF8C9A592B792 /* cpp_magic.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D6BF0D382E2E68028AAF3CA080E941E8 /* Addition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8F959C010C8EE0A0547CF67FEA904B /* Addition.swift */; }; + D6C758E9A1EF4B06CDF96D39D4EE31A5 /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44F9093DBD2DD7FB5CC1B73033D02658 /* BlockCipher.swift */; }; + D6F57F85DEA67C9E358001DF97436C96 /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = E2289E7AE246F961F1A92D56F8B531B7 /* sha256.c */; }; + D720A60BC531A3ADC5EC2FDA68D40763 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + D727998958FC27FA7696ADF1D974B6D0 /* SwiftNIOTLS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E9BCA3A2D8C63873EE05B43FA2DD72A /* SwiftNIOTLS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D7414D81DFEAEE19FAB7DF0AFB4DD161 /* BaseSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95229EF545043EA7BCF2D678483CC45 /* BaseSocket.swift */; }; + D747E6D1A1FBC22717171EDC089D5A4A /* AsyncAwaitSupport+OldXcodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81B64ADFE4BDE44F8BB718A1F9322757 /* AsyncAwaitSupport+OldXcodes.swift */; }; + D769D4D06E7DFD5B38BE20BC66561200 /* ConnectionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1C77232231A56100C2C126C3D2BA3F /* ConnectionPool.swift */; }; + D7BA04ADFE3104907F100E9370184A65 /* UIImage+ExtendedCacheData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BE2D8F9A463FC1F21117131272AD9D4 /* UIImage+ExtendedCacheData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D7D077F0FA5CAC32ACB65372453C701F /* SDImageAWebPCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F3E90EFBADCAF15D47861BF06C9C66F /* SDImageAWebPCoder.m */; }; + D81334DB8948DAC08260FA3D7D3DE705 /* p_dsa_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 63A1C84C64764931184EA5A3B829CB71 /* p_dsa_asn1.c */; }; + D847E99BFD8C95B9A7C7619D0C871778 /* unicode.c in Sources */ = {isa = PBXBuildFile; fileRef = A3F40CFB0549042E755E3C6338B0A11C /* unicode.c */; }; + D84A17A4FC02A3A2F22E8FA6C2CCE64E /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 441A7B437D3E27161D566330AD6CA312 /* ECB.swift */; }; + D88076DA0593D2835645CA5A92FFA37C /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 825EFFDDE9B3D5F42B64850D210D839E /* SDAnimatedImageView.m */; }; + D8E031F864BE34AB0D73002CE05E9742 /* SecurityFrameworkCertificateVerification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A29A5BEB2B946BEE2C128683E4D9BBB /* SecurityFrameworkCertificateVerification.swift */; }; + D94577585EE54E79F4F9584B50B1684A /* AddressedEnvelope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DBD255DD3EFE8B8F18EC77884784289 /* AddressedEnvelope.swift */; }; + D9601285D494DBADD1870DE4F407037B /* TextFormatEncodingVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14752CF2FF865DF39649F33F07C77C7 /* TextFormatEncodingVisitor.swift */; }; + D975B260AB44081399BCB612916CE675 /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C90756B2FB9DEC6D7311D5881FF7FAC /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D9ED50F4E709BD9139B7BB1EB987E716 /* CNIOBoringSSL_digest.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9A66F407FAFEF96BA9346ED325C854 /* CNIOBoringSSL_digest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DA1719C5308D83A4CD7819F1C6032539 /* poly1305_vec.c in Sources */ = {isa = PBXBuildFile; fileRef = DABFF317E1626B524FACA62C0C149889 /* poly1305_vec.c */; }; + DA46C610786FEC6A0B86A749120F1316 /* ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 137BE3AC11783E57A07C5477D5948A98 /* ctx.c */; }; + DA6471627554399FEDB451E8FFE42ED1 /* HappyEyeballs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60DA5A9E77C90FD5E3A6BECEBA97BABF /* HappyEyeballs.swift */; }; + DA668BADDD228A5D2764B41BF820A3D0 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AEBF46834A19EE43F1812948101E19D /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DA6EDABF74C3C6E9F9997B698195D6A2 /* Prime Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8634EBFFCCDD9B284853088DD982AB91 /* Prime Test.swift */; }; + DA7A97CC9E1A7548858FCA7B4D7C1629 /* PopupDialogButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E3DF7A1DE405E528197F98001D7A73 /* PopupDialogButton.swift */; }; + DA7D579CB9A6B1A72AE972758201ED2D /* SSLPKCS12Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D7CBC2B76E29B6042FF02D05EB4EF33 /* SSLPKCS12Bundle.swift */; }; + DA9899E48206C31AAEF6113E43256C30 /* Identifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A1FEA4E83370409F5570F73F0B9838 /* Identifier.swift */; }; + DAC33BB50B13BD204EE6FB6FF0F70743 /* ChannelInvoker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7646B3AFC5E6A30618DD8AF57E8D8B04 /* ChannelInvoker.swift */; }; + DAE1D6B30C3EBE1E5E91599A18B29E8D /* Zlib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2924B309ECDB9B85124C35459153AC54 /* Zlib.swift */; }; + DAEA293A91F3E49D3F2B0A1155FD5302 /* mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 095487687BC21CBD523027ABA0812340 /* mul.c */; }; + DAF8A77BF7CFE74D7C9586D51DE81434 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + DB61822BEA875B413C858E1166590C9F /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A9527754C739FD142F18EBFDCB50B9 /* SDWebImageDownloaderOperation.m */; }; + DB6449B04301AA8589453CCF85E23EA6 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 86CDA9D7F74123ECD5926436D656E42E /* util.c */; }; + DB68D9AFA817850ED9EBBE7F3F378AF5 /* SDImageCodersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D86098F5C60B52847DA9D83AC3F267C /* SDImageCodersManager.m */; }; + DB6E76EB84F509A527E48E4A0FB98FA7 /* GRPCClientStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = F13CE72E4DE115E0CB8A9510566B58B6 /* GRPCClientStateMachine.swift */; }; + DB6F6903C0371975D73C65B8A6B31956 /* CNIOBoringSSL_lhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CB4E7BB0CF0584BAD6F97344F04BCD9 /* CNIOBoringSSL_lhash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DB8E1659FB468E5F18878493EF3C69A3 /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439E97A1D3AC6989C07A674A4DF0344C /* Version.swift */; }; + DBAA133B55305E85224A1B3CFD5D6D0D /* _NIODataStructures-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B56C4BF02503F348797EF44D132B4F5D /* _NIODataStructures-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DBBAC864AD405BED53782364E0F0D5F3 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = FD32A762666BDBE51E1BFF3DFE7526C2 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DBD4BFBC053F0FE4522C6C96AD6E6813 /* exponentiation.c in Sources */ = {isa = PBXBuildFile; fileRef = D306E5CF93DA0C35925B406052C351C2 /* exponentiation.c */; }; + DBF4B4D6EE8593C2D5AE41DA9A160D33 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + DC3593C40C4B7A8FFC62DE36FF21C783 /* pem_pkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F7503BE3EC95DDA2F8E1ED90CF7CF71 /* pem_pkey.c */; }; + DC581B8511549CEA215A0EF40CEE4157 /* ControlFrameBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5626242BB7146F77738520DFAE216A5A /* ControlFrameBuffer.swift */; }; + DC8BCD4B3A292E7A4482B1A17A262620 /* ServerHandlerStateMachine+Handling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EA8C52B80490B71F1A647CD6800483C /* ServerHandlerStateMachine+Handling.swift */; }; + DC9B0741A999A3812C9958CBD17E5D30 /* RSA.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA9F0E3CEC147A6DE206E5B03934731 /* RSA.swift */; }; + DCECA9BC622223C915D47B526558A28C /* dtls_record.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7002D4F1EB05B8F8EEF19D1CBDA2833A /* dtls_record.cc */; }; + DD358916DB501726FE37FEDC7ACB9729 /* chacha-armv8.ios.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = A813103232F50456F6CFFDBD38743C19 /* chacha-armv8.ios.aarch64.S */; }; + DD63864BA12CADFC78FBBF1F3CA61120 /* aesni-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1808CB586541F56505012C7222909DEC /* aesni-x86_64.mac.x86_64.S */; }; + DD997A01C8E0B39974B40004F87B26C8 /* mode_wrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = AD1A3DE715CE103B04510EBCCB7557F5 /* mode_wrappers.c */; }; + DDA8E54FFAA6DFF7E15F15A52AB7C662 /* Hashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A9AE26BA8C9E100E1A049D203896B4 /* Hashable.swift */; }; + DDAE076023646EC3A7717A39373C14E7 /* CNIOBoringSSL_md4.h in Headers */ = {isa = PBXBuildFile; fileRef = 792D40C0B5291DFDEDB11F6CE0649DB9 /* CNIOBoringSSL_md4.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DDBAC3B83A7251293580CE204CB2B7E4 /* Cadence-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 307067ECFCDF628D0BFA3A54498C23B8 /* Cadence-dummy.m */; }; + DDBCF39FC0DE63E0CC584A179B9A99F8 /* TextFormatEncodingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DEDCE51540072C4379CBA95F93B4CFD /* TextFormatEncodingOptions.swift */; }; + DDD928B3278BCFF21AA132CECAAD5F65 /* v3_purp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8A6FE2D88F187D54B3237983D3AE0408 /* v3_purp.c */; }; + DE0BA471FB4FC10C0B25BDE4F22F5B76 /* SDWebImageDownloaderDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = DA29D1A3E827E2DEAE7B710196D264C9 /* SDWebImageDownloaderDecryptor.m */; }; + DE241BC1AF468AD74758AFBA2D7D0485 /* v3_akeya.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D62241984225CE5EAC16D48BC371AB8 /* v3_akeya.c */; }; + DE9547469793D715D9380C071EDEA124 /* BSDSocketAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55323FF6763FDF0FD55A710B19CA1549 /* BSDSocketAPI.swift */; }; + DEA1C15ADF5B7F4AEF8379FA1BCF6A44 /* UIImage+Blur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B2F307985AC8DE763A234C8EACE96F /* UIImage+Blur.swift */; }; + DECA57AF64C5C257919649ECBB75F0B9 /* SDWebImageCacheSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = F9452C8340B87C5D87F7E13392F0D052 /* SDWebImageCacheSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DEE74CD0E78DE0DB4056A8A3244B6ED1 /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = EE93CD03907EE0EDBC912DB01B347EB8 /* UIImage+GIF.m */; }; + DF0FA751B12587DEF6AB8115D1CAD804 /* s3_lib.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD318DB1E63E9531C89B293D34186B07 /* s3_lib.cc */; }; + DF10F64FCDA06951F00273C0884C3EE0 /* Singature.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6E1F74F4BFA0885B4863B6C052B4F3 /* Singature.swift */; }; + DF153650063F4CD806469DFC8B9047AE /* eckey_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E2F291C8EAA7B8A3F81A388D7280711 /* eckey_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DF45F7F2696065FAC74D56742C3F1AD8 /* md5-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = FB05FC2852DC3B82A137AFE1FD584A3E /* md5-x86_64.mac.x86_64.S */; }; + DF527586940E1AE495029DDC2E60E665 /* x509_att.c in Sources */ = {isa = PBXBuildFile; fileRef = 978ED63145A5D349DC34780FDD0A8CC6 /* x509_att.c */; }; + DF955E134FCC89A7F2347CD7F00EC5EF /* FileRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64F7DA6E0B11E2AB6D1CFBF2BB4CBC8 /* FileRegion.swift */; }; + DFA9FF35A4AB8FB30CA7149018CE76F1 /* Words and Bits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08A595AD5E52D398253F765D3646FEA3 /* Words and Bits.swift */; }; + DFB452F78F1FA4D3B38152EAD3D49D2A /* selftest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B504D41BF6D241A3F017DB3191ECC91 /* selftest.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DFDB176EA2652EBC56E5F74ACB88047B /* field_5x52.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CFE5772B62649A74A68BF90457734A3 /* field_5x52.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E03B9580B8220AD064E1E96000C23624 /* StaticTypeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2F560F2FE25185B92D32A7AC9F0BE4 /* StaticTypeValue.swift */; }; + E074A63D41FB511B4A4EB2B18C8E823B /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C91FA15C4D33D1B7E9559142748045 /* Resolver.swift */; }; + E0885BDF48915F32BE60CE8CE80C4CFC /* SwiftNIOHPACK-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 561797F07D64EEC2278F2C20D284ABC4 /* SwiftNIOHPACK-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E147CEBD99B43CFD13C60BB6E2514DFF /* _EmbeddedThroughput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297DA80F9A4242565798518F67BD9061 /* _EmbeddedThroughput.swift */; }; + E17DDA2A7D35CCEA2F859C72AFE9F2AE /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3272BF10A705DA3798C673B76D5148 /* sha1.c */; }; + E1CAAE3F0D4C2C50998BA10BE616AC02 /* DynamicBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 404E03500F2035FA7045242A74AF80F4 /* DynamicBlurView.swift */; }; + E24C390EE50EC6E285E377002E0B7353 /* sha512-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 05BA590DAC219FB7EAC94ED634E0FB8F /* sha512-x86_64.mac.x86_64.S */; }; + E27E10710700E3BD84F597B8D007EEEE /* HTTP2ToRawGRPCServerCodec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D059656D450DB7462D191A177599D6A2 /* HTTP2ToRawGRPCServerCodec.swift */; }; + E2958FD405C58EC77AAF489BD273FBDB /* armv8-mont.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = FA9B6B81A974AFAC9F65AF34375287F3 /* armv8-mont.linux.aarch64.S */; }; + E29D45250296F63650E57BA46A9E46A6 /* HTTP2ErrorCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 629A52E1E4CA932DAE68FF73DCA52081 /* HTTP2ErrorCode.swift */; }; + E2D221DA97594520F8B583E948E1F9C7 /* x86_64-mont5.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 200DC709F6BF532949BC63AE3410B612 /* x86_64-mont5.linux.x86_64.S */; }; + E33A7CDF3107CD3426ADD0D906100CD4 /* SDImageHEICCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F4BE6BBA53BCAFE0232A7F15B66BAC /* SDImageHEICCoder.m */; }; + E343A4361B61CEFF8C4FAB89A16A6851 /* Pods-fanex-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 381DA48DFA835D5C2909A03D9471E54A /* Pods-fanex-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E378BCF0B877D69B68804CB10B12B846 /* x_all.c in Sources */ = {isa = PBXBuildFile; fileRef = 3079F5D1DE8B050D9D823C7D18855C53 /* x_all.c */; }; + E3AC342DC87C6BAA7EF8F79C2FE9B455 /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = 3090844C262BD61943DE6CB9833BDAD4 /* thread.c */; }; + E3CA4C3F4DBCD626BFF8E94107EF729F /* bytes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4FA167D30D3F8F8FEC7D9F31A0DA35DD /* bytes.c */; }; + E3EC582C886EFE91B791B99B413E44F3 /* ByteBuffer-lengthPrefix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81CA65DAA499F4180D7F20A100FDA6EE /* ByteBuffer-lengthPrefix.swift */; }; + E402D73132C9322E7C2D02FE319312A2 /* armv4-mont.linux.arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 843C50DA31F8E3B21D234B2AE095DBB5 /* armv4-mont.linux.arm.S */; }; + E41184C85FB11969BEED1C1255CF96F1 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576AC85311DDBD08D126184FB7191BED /* Generics.swift */; }; + E449941AA9B755CEEDF66999C58D98B0 /* EventLoop+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B92469E0E33F66124F5C1D3EB3EC364 /* EventLoop+Deprecated.swift */; }; + E48C92167F6F0221B63E379D48376496 /* NIOTSNetworkEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C96D53D709CAA0EC53D442695E95B4AD /* NIOTSNetworkEvents.swift */; }; + E4A7207A022D9584CD9B7D29381C8454 /* GCD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A8D955348F8FF566612970196459D9B /* GCD.swift */; }; + E4AF87F8012F919F00E2E8698A1A3C33 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = EBC11F927EF369180412CF967C1C71A1 /* SDWebImageCompat.m */; }; + E4B0992E34A04B158C11A94DAC794278 /* CNIOBoringSSL-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 154D8E8D0F6B17F4D864A80C3C2543A1 /* CNIOBoringSSL-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E4C06CFB3944C30B9E6443AA0F8332C1 /* a_strex.c in Sources */ = {isa = PBXBuildFile; fileRef = 6EF2B22C03C28FE00CDFD8407D2FBB55 /* a_strex.c */; }; + E4C13C7E6E3FB95A9694F4DDBCBCED30 /* Enum.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E3511C4C20DBFBB77226B38065CDE9 /* Enum.swift */; }; + E4F76B17938B5DCA6D1853AE27018713 /* BloctoWalletProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E360AA62048C3919BBFD38F63BB1508D /* BloctoWalletProvider.swift */; }; + E515780850EBAD40342EBF2997BFC2D2 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 914529946EF5601AA93F8EE079CF3C9B /* SDWebImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E556832E0C191FCFABB9E97C87D243EF /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 40358CCD7FAD3DBA05B893A63923B67B /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; + E5C6051933677CDF392BF6356271A92E /* SDImageIOCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 5208FE10C0E0EC040DE60A94FED96266 /* SDImageIOCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E5DB387A5D9CF98DC2A3D53D813E7681 /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08951CD09B134E4455D285B4E199637 /* SwiftyJSON.swift */; }; + E60BBB0218ABDD03C08F66CD9973A5DF /* sha256-586.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = E5870E9EFBACE59A56028B0E330D8339 /* sha256-586.linux.x86.S */; }; + E677C65A67EE379C522DE165EA429C89 /* vpaes-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 012D295FB484D69B3CA2BD10A7F20B4C /* vpaes-x86_64.linux.x86_64.S */; }; + E6DBD6C5D945067C315EEA87244D872C /* FlowSignatureType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86732BEBFBCA696599CF87443ACD0FE /* FlowSignatureType.swift */; }; + E6E77C21BEB0D12F83C95039A71A4401 /* field.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CA1003700742FCF9A856FE54DABB5BD /* field.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E70EBA16751054574A227A6432CCE4B0 /* SVIndefiniteAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A6186673700ED88DEB1E9C017272782 /* SVIndefiniteAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E721A722DE94103D703212DF73FFF2F2 /* MessageParts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2E5F552BE3FC33AF702D83A2839354 /* MessageParts.swift */; }; + E77834DCFE86B4649DDAEBC511B1F495 /* SendAndReceiveGoawayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EED3777D51C8B8889CB915AEA5071C4 /* SendAndReceiveGoawayState.swift */; }; + E7A8DC86F7559373DBC9CBCEDC38CBD5 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9024AD82FD71C379F75FC57CA503D370 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E7B5FE73B705ACD5475CB1A003AF1C48 /* CGContext+CGImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80C859888912E5732D63118F83ABA0F /* CGContext+CGImage.swift */; }; + E7FA1E1CD066D0335A95376C73E3F8ED /* SDImageCacheConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 68D1CC3A9F718D0F87F05426AC681B0A /* SDImageCacheConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E83EB1766BA2756C9C5C3F918BC9F60D /* cpu_aarch64_win.c in Sources */ = {isa = PBXBuildFile; fileRef = 139A78790D675E8D7658D8A8A2384794 /* cpu_aarch64_win.c */; }; + E85B446B6BE0049275FCCDC69B9654F0 /* gcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 6882A01C332B342BCEAFA7A90B78BB4E /* gcm.c */; }; + E86D3491661EFC3BD9FE7655FF0D4357 /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44102141F3911EB572FE3710794EC10D /* BigInt.swift */; }; + E875CE58DD62C146D1AA337206CC9845 /* URLQueryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C922CF29D12C9731A042B778664EEBF1 /* URLQueryItem.swift */; }; + E89B05BF6B14EC0E1DC66254DD39F079 /* IntegerBitPacking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C406C06F57CEF98C098EB1834266766A /* IntegerBitPacking.swift */; }; + E8A3924DF45674B1A7C49A31245BFC7F /* SocketChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3174AB3987026757E7D96EF2202B2CAB /* SocketChannel.swift */; }; + E8C629BF8835F12558DB40C81ABC3B68 /* DelegatingErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2E0761EDC7027047AA1C390EB7873F5 /* DelegatingErrorHandler.swift */; }; + E8CE28499C17965A931605D4F47AAEBF /* NSImage+Compatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = E294B949999A1A5079F9FEBD6B774F68 /* NSImage+Compatibility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E8D2CE0F5988394E8B16DF4E2802339F /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AE57BE0D5EE76EFBABB44E2EA7B7A7 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E8D519B63C2077979F799769F9A35072 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0513510E718E5809FBE277362E08257D /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; + E8E7C3E3A7852157F2A34F3488B19186 /* BigUInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB2156CD55FD16E3A95B4AC96E16738 /* BigUInt.swift */; }; + E96F3501EF2AC42C682BD16B73831AD5 /* NIOTSEventLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185AA3C3932111DAAA91315C83FF1256 /* NIOTSEventLoop.swift */; }; + E999BF52BC1A0DB561E4F948E4C63AAF /* NIOTSConnectionChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14651E9E01AE716B20D51B8CA012A3F9 /* NIOTSConnectionChannel.swift */; }; + E9B42EFC6940A6552B2744DFDC85822B /* GRPCContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A78B9E397FC3A26081AF8D0468C9A30A /* GRPCContentType.swift */; }; + E9BDD9FC4F5E7A0F8C5020BF1CC7D10E /* BinaryEncodingSizeVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76CD9C4BBC20D5D9CFA35EF21D2A28E2 /* BinaryEncodingSizeVisitor.swift */; }; + E9CF46857D61D2A8AF4C3722C27C61C6 /* SDImageCoderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = B1B2FF5011F1F0B315552B06B8F31887 /* SDImageCoderHelper.m */; }; + E9FEC8C859AD5D65B9902141E1FF401B /* aes128gcmsiv-x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 35467501D3CA6E0233E29B1E9F1F0BEB /* aes128gcmsiv-x86_64.linux.x86_64.S */; }; + EA1A875D165EE690AD246CF9C6F3617A /* p256-nistz.c in Sources */ = {isa = PBXBuildFile; fileRef = 993A1317DC22F99DF8A87D2BEF94AEA3 /* p256-nistz.c */; }; + EA5CBA722DBF91291CC6D0DE5228C7A7 /* PublickKey+Cadence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431FB716FA31D9BC5168E6D7645EAB0C /* PublickKey+Cadence.swift */; }; + EA803E256823ADA868E6A119D9D229B1 /* Message+JSONAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20AF747D8CB7AF6E01E1F7B58F040B26 /* Message+JSONAdditions.swift */; }; + EB03395DC45589EF6BC76A76C7375F0F /* ECDH.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5F179B7546D92B3E3DD6C93F2C0164 /* ECDH.swift */; }; + EB1AA9AAEF921D90FF3FABA3A734BA83 /* DeadChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84650E9EF8B829CC71F475A58EF9FA97 /* DeadChannel.swift */; }; + EB50AB7E66D9203D629090DDE2F4D209 /* _FakeResponseStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD0A2854CC856EABE27D02B8B2A196D7 /* _FakeResponseStream.swift */; }; + EB5F55D277062C3DA392ACD464EF4CAA /* v3_prn.c in Sources */ = {isa = PBXBuildFile; fileRef = 5C046B5BB46DDFF18ADD409B49436BD1 /* v3_prn.c */; }; + EB6552B2B6F12838F0A9B125CBA09B31 /* a_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = 68CEBDA6647D2970C777AF684FD248ED /* a_sign.c */; }; + EB80442999C84C1038422C0EDA69B6C7 /* md4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7A9EC9573C7A3E60032641DD2C1C4795 /* md4.c */; }; + EBBF5E2E2068B7C1A8C3BA7E2E5A7DDE /* gcd_extra.c in Sources */ = {isa = PBXBuildFile; fileRef = AD399753F135626CB1495DD19609C932 /* gcd_extra.c */; }; + EBD6019AD15D1E3DE7D54A018E977DA9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + EC0D35F2428314AFAE49DB8177C8AC1C /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E434DE23A18B5F3AE72EEB4CDE12D61 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EC2E56E563DF0286FC9BBA18AAE3E203 /* Visitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FD6706181F20F0BB844323B4501CCBB /* Visitor.swift */; }; + EC2F337218FE40AA913E2578BB50DCDC /* x_pkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 6CC717C5651767D375F458FC34B8A566 /* x_pkey.c */; }; + EC3D9E3E5CA1A27A875F58D876E2EF70 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + EC9211C49E43C38212BB791C35605245 /* TransitionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64554F810325123E1D8A563813465BA2 /* TransitionAnimator.swift */; }; + EC95784DCA76E26345C1E5090C1B1850 /* Bitwise Ops.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C35921FB08EA0C514E6E13007AC5066 /* Bitwise Ops.swift */; }; + ECA67E92E03378D0E6A42C72F6067970 /* ghash-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = E40AE1987BFAD661223EDD5BCD64E438 /* ghash-x86_64.mac.x86_64.S */; }; + ECC00A0AF7CE2DC24219FA4F944B7F89 /* SendingDataState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F920BC94FE761A03B0EEB62522F35C9C /* SendingDataState.swift */; }; + ED23CD1CED44EE98522F6A6522F8872D /* ByteBuffer-aux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD06CC435D05FAF9356A9E55E340DAF /* ByteBuffer-aux.swift */; }; + ED5CB63C5B433E39D4638E7F69BBECE7 /* CNIOBoringSSL_x509v3.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5B1F22506D5F481C955B8329C18EEB /* CNIOBoringSSL_x509v3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ED6049663DBF4B471880F7DC46212E27 /* v3_skey.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C37C919BAC5CC9F4315FC8E80AE0BAA /* v3_skey.c */; }; + ED7CB46FE083BBF78F85985512CBCAEF /* gcm_nohw.c in Sources */ = {isa = PBXBuildFile; fileRef = B0E148C89286FC10D58812BF0310AC2E /* gcm_nohw.c */; }; + EDA02AB3723123319E6A02113F7C0F6E /* SSLPrivateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 369C48AD3362D32C75B73925F8EF8B43 /* SSLPrivateKey.swift */; }; + EDB9B74B32A165CB0FFFB8E48D626D4F /* Google_Protobuf_NullValue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991BC180A5163AA7D7212862738DAD7E /* Google_Protobuf_NullValue+Extensions.swift */; }; + EDE4C554BFC9A36D7C39A1745DDB5EA9 /* IntegerBitPacking.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB49AEFC8709DEE496D85E1E049F85D /* IntegerBitPacking.swift */; }; + EDF63361BC1F79E71FB598AC9971148C /* SwiftNIOCore-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B4B7EBE7A82D97D5576D1E05A39B6B5 /* SwiftNIOCore-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE061A69D6FEA3002D1409F9123784E0 /* BloctoFlowSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = B08C0844D183BD82AD0C9ED81AA99268 /* BloctoFlowSDK.swift */; }; + EE5A45DC805358351A9B5C97C4541DEC /* descriptor.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = E651C6A6A5C2103B3BFB4694639A6744 /* descriptor.pb.swift */; }; + EE6E9CCABA4265C11D11F4A7AB7E97AE /* aes128gcmsiv-x86_64.mac.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = F20B9FF634D7126C0E37A3AFF9CD0B2C /* aes128gcmsiv-x86_64.mac.x86_64.S */; }; + EE71A81B20826C203428976F420177DD /* ServerSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF67958A7B889FD32EE31BC5BD7153C2 /* ServerSocket.swift */; }; + EE8A7D3D1CC460B7209D2E36A76AD4D4 /* x86-mont.linux.x86.S in Sources */ = {isa = PBXBuildFile; fileRef = B58B678C9D1B0BF85162F3EE8B1619F0 /* x86-mont.linux.x86.S */; }; + EF02CAD1A27CDB6A369CF41D120EBE9C /* ecmult_const.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BECF935580ED15BE7BBED8A011B189E /* ecmult_const.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EF15DE530D074CBC2EE055EF5E915F7C /* DOSHeuristics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E3A1FEA70906514D5833E0C24B272A8 /* DOSHeuristics.swift */; }; + EF1C79757D7C7A5BCCE5C67B0D33D8A7 /* sha1-altivec.c in Sources */ = {isa = PBXBuildFile; fileRef = 156F768DC24E72ABF7AFFB0B384D10C8 /* sha1-altivec.c */; }; + EF3E28CB5B5B3E834B9409BE1CB36B7B /* d1_srtp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7DE6A0217C1A0B0D81EBB20DEAFE8713 /* d1_srtp.cc */; }; + EF715BDEF2FCDA364B172720D1FF9829 /* JSONSerialization+ByteBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E1B86F03FEB77983C03E9095597B3C2 /* JSONSerialization+ByteBuffer.swift */; }; + EF767776B19C0D880488CE95FFF2D1F5 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421CA9C32CA2524466A67A1548654BBE /* Cipher.swift */; }; + EFB6C0A49787457FEE34CAA9C221FB17 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9748CE6DBD4F6B5C7299576A07341672 /* Accelerate.framework */; }; + EFF06BCAAD35C22AEA7845996EBD11E1 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F3EA21AB0B510C02841B9B09476F9E2 /* SHA2.swift */; }; + F04832E00C01F64280C200F9FA94AA2F /* SSLCallbacks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DBEE5E02B05AA31F5C64FE602B3A266 /* SSLCallbacks.swift */; }; + F05A43E63E90BCA0E8B09AE36CDBC816 /* HTTP2Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E9CEFF47F7C6B77BF71C3804FAC888 /* HTTP2Stream.swift */; }; + F077E74D9855D0D7FCF570F8E8ED4A1E /* SDFileAttributeHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2544EF6EC105AB5E2D3F989DA6D4AC /* SDFileAttributeHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + F0B228EA8A6211C8B6CEF100AD165047 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD554B1F5155CCEC522FD091E3B42B44 /* UserInfo.swift */; }; + F0CA93246FD5CEB9AC2224751F3BFE33 /* conf.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D8AC108A683453F882A65E63ACBC007 /* conf.c */; }; + F0E28CEF30861F3589A4A662CEA76D80 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 06CB876E7538CECF6296183C9239A40C /* SDImageGraphics.m */; }; + F13CDD9E25BB411286D4BF7A76986DD9 /* FieldType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05AF864C3E9FEE08D516DE2E350E390 /* FieldType.swift */; }; + F14BC3459CEAED3AD9737F5162FF4689 /* CryptoSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A3F68D52609F06530707E690E292C7 /* CryptoSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F161112B04B9AC7D276D9F588BA6E313 /* SDDeviceHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 885445AB8E8BF1B1A00D746A027C9D1D /* SDDeviceHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + F1796E85F14F1B07352AF9A86DB70F2B /* poly1305_arm.c in Sources */ = {isa = PBXBuildFile; fileRef = D2F7A62C86D43CBFBE760EC3E47BBAE1 /* poly1305_arm.c */; }; + F19088E1B32529B025BA2654FA289785 /* ClientConnection+NIOSSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218871546F42F6E20E483CAD41CCE258 /* ClientConnection+NIOSSL.swift */; }; + F20DD14AD88DFD6E88AF21664360D3E0 /* CNIOBoringSSL_ossl_typ.h in Headers */ = {isa = PBXBuildFile; fileRef = BC235DDB7681F367A590FA00C20F5A24 /* CNIOBoringSSL_ossl_typ.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F255F5742D91ACF953300EC019A5C569 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6BEF0D076B6676CEA35ED8F8DCD6C48 /* AES.swift */; }; + F25AE87DFABA108A482A099407418A3D /* ecmult_gen.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AB5E959B806B6D0CF955CF738AC44A6 /* ecmult_gen.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F25DD8DF9EDC42E03EE1A85BE89FAF29 /* SignatureAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55D91D9519BCE3F60C8F6510F17EB0B /* SignatureAlgorithm.swift */; }; + F272EAF414553A81C7C54EA35F06B339 /* IntegerTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0D077A97DCF15297B0CCBD600A6CFF /* IntegerTypes.swift */; }; + F2A471453076AD07758F14B12BA5373E /* group_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = EC0B3F23D2F2899609E05188B8AB2972 /* group_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F2E080D591DA83169CBB120644B2C8FB /* field_mask.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DA367665CC9BC1C69B04890D3494B39 /* field_mask.pb.swift */; }; + F319BA905F2230077F909C723CFF0F7E /* tls_method.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0F614077E368A14C70311405F7FE69D0 /* tls_method.cc */; }; + F33B49D79748B138362B4FB84408FC1A /* field_10x26_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E0AC26AB92B81B956F7247841234F11 /* field_10x26_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F38D12F5EE7BF7EE8686B0363A1DD433 /* chacha20_poly1305_x86_64.linux.x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = E804F479A0C73C7E15BF90C02CE451DB /* chacha20_poly1305_x86_64.linux.x86_64.S */; }; + F3F0878161819EE96DAAB97A955681B3 /* ssl_versions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6BFF036C07C43EDDC9044F5A484038AB /* ssl_versions.cc */; }; + F41028D4E0E43E885ED9ADDFABBE1ED3 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 764CE82F2813B002821F53D9441AE86F /* Comparable.swift */; }; + F41F82E9D51C50FD12B0785DE02DE71A /* thread_pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = 8FB4B7760175730C39FC1F260C5439B4 /* thread_pthread.c */; }; + F463DEB020D5C466D4613947AE4BE16F /* SDAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 76BCDE90DDBD2974D226B0DC728E0AAD /* SDAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4811CFAC05932CE436CC2C32BAD91E6 /* UIColor+SDHexString.h in Headers */ = {isa = PBXBuildFile; fileRef = D74C19340A61F25F7DE3AFCD405BB334 /* UIColor+SDHexString.h */; settings = {ATTRIBUTES = (Private, ); }; }; + F485AD8EB9C160D3E4253726C2F93909 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 93AEA077B5B2D1CE26978A40A245BF92 /* hmac.c */; }; + F48D813DBD324DDC9B06FC203A38568D /* CNIOBoringSSL_bio.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D38132414C08347AD7B4BB2AC16B6D2 /* CNIOBoringSSL_bio.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F497CD01EF6568475FD363A248D78A4B /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 85E19BBBB9A6ED0D665B3E9C5DC3484F /* UIImage+ForceDecode.m */; }; + F4B10C796BDD8DB6C781BF31B4C71D83 /* FCLDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 936C01B367E6C83629C332BC641FE4EF /* FCLDelegate.swift */; }; + F4E9619C0FB0B826F231BD0F73BD2C87 /* aes_nohw.c in Sources */ = {isa = PBXBuildFile; fileRef = DE9515A45FBBC6DCD53031F946838D95 /* aes_nohw.c */; }; + F4E97401322A30BBB4BAEFB5D96A6E8E /* e_des.c in Sources */ = {isa = PBXBuildFile; fileRef = 275BABD7D495C8038B7954184A3542E8 /* e_des.c */; }; + F4ED72DAE062C7DD4AF21AE5EF4E5892 /* HTTP2ConnectionStateChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 766A92521248B4D7CD1345D794D01673 /* HTTP2ConnectionStateChange.swift */; }; + F52DC6DD05D02987E451BDD8658809AD /* v3_crld.c in Sources */ = {isa = PBXBuildFile; fileRef = C03F3F214061CD431CD8FE1BCB83D015 /* v3_crld.c */; }; + F5371A396E8882980DD3BA8F9979583D /* AEADChaCha20Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1A1E10AFB8B8835880E65401C2DD9 /* AEADChaCha20Poly1305.swift */; }; + F54EB5C3506F5A9E1947441BE850B2A6 /* pair.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABFF64DD17238FD146150F9D6C09010 /* pair.c */; }; + F5979CF6BA6E3FB5FC30F8611868E4B3 /* Pods-fanexTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FD72A695D77BD4F392D0EBE936B2EB51 /* Pods-fanexTests-dummy.m */; }; + F5BC1AC29184091891661463D97A0EF0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + F5CDDAD3CC8FB214E48E5105DB07A039 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE4127318ACB65C0E8D0BEE1BF74A804 /* Signature.swift */; }; + F5EDCE3262CA40B80D30F10E05F7227A /* SendFlowTransactionMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3568EAA3220005786354D1B8DCCA50 /* SendFlowTransactionMethod.swift */; }; + F5F0562EFC8A4222EB84980F223E6C15 /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B019302E2A4FC7DB5D8D6C49AB207B4 /* Random.swift */; }; + F61E5D02AAC4F81630437B1CB05FD5BE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + F6283C44CF6A82AB1DC097C4E5A149F5 /* FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E810951424A6E5BC0AF196C7E0520B1 /* FileDescriptor.swift */; }; + F643188BD47ADBDC31EF551594C50284 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD08109835C6A45C609EC05D36F56513 /* HMAC.swift */; }; + F64FF06ED0A31B75355386672A568CC5 /* SwiftNIOPosix-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CFE74D605415B4D1AA55DA6DFB704085 /* SwiftNIOPosix-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F67378DA034C55276DE7FE8033D5A644 /* cpu_arm.c in Sources */ = {isa = PBXBuildFile; fileRef = F98FEB534446DF2637FA145FD087C2E3 /* cpu_arm.c */; }; + F695D5DB77B445476619C25ECBA5DAAF /* check.c in Sources */ = {isa = PBXBuildFile; fileRef = A5E983DC62177D36493A0A1614E01CD4 /* check.c */; }; + F6CD3F5A60CAD8157A3289A434A81FD0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + F7243933EAA2401DC6901A124685CC11 /* CryptoSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E383DA3A0800A46C0734C2D4460F19 /* CryptoSwift-dummy.m */; }; + F7289F163C285103D6CCAB39447153CA /* SDWebImageDownloaderConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = D2026207177E77CCFCF8DC1F5B32429B /* SDWebImageDownloaderConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F77280E74EB91678AA294E66DD6070E2 /* SVProgressAnimatedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCEFA31AF70F373E509ED8E34154C05 /* SVProgressAnimatedView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F7857CD0D3B1FB5C718447F140DFB54A /* HuffmanCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56ECAFB119E54C34869DCE1A260D278F /* HuffmanCoding.swift */; }; + F7C80AF1F3CBB02D63D52CA677C17BB7 /* Signable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9B529C7D801576754E91D4503778443 /* Signable.swift */; }; + F81C75E02116969FBAB72B27EA9087F4 /* crypto.c in Sources */ = {isa = PBXBuildFile; fileRef = 06A8DC591EE9F5CEEC5C7D12DC2FF72A /* crypto.c */; }; + F81E16CDC41BE1CB2C103F910F5FFC70 /* Square Root.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9CA9FCDB3FE02945409F2162324A36 /* Square Root.swift */; }; + F825380DCC6CC82AB040E8FA985DAA3C /* ConnectionManager+Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5655ACB7792921A9D8656260482B6D /* ConnectionManager+Delegates.swift */; }; + F82A064DB011FD573481889639DA4AEE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + F85A22BE2DB8AF01608769785E8EF38A /* JSONMapEncodingVisitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 742882FE522A7CABFA19008D890AFF0F /* JSONMapEncodingVisitor.swift */; }; + F8DF325D968A7599FC260EC29086D890 /* SendingGoawayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48BD2CBE13261ED5F8C62054F938FBA0 /* SendingGoawayState.swift */; }; + F8F76CBCF6687AF4CCC81B2AFA104D05 /* evp_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 8064FD2B8EED372A919120A0AF91965E /* evp_ctx.c */; }; + F910D09581632891360B34FD0306E5FC /* SelectorKqueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF33EE50785750CD3E0018658BA90C2 /* SelectorKqueue.swift */; }; + F91E4C7F2AA392410D84A4D4FA201368 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + F93B819F0B0BB771FEFB3F0F84753133 /* CustomPrivateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D41C1A5A3343C40316A5339C52B6BBF /* CustomPrivateKey.swift */; }; + F95103DB3CDE985249C0B9E4CD464BA0 /* Integer Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCD2D8AA00FB066742BC2E855446832E /* Integer Conversion.swift */; }; + F952C2CC4645B301C4713EF243482A76 /* f_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 5EA5D5F30C38E89044BB740F26EE88DD /* f_int.c */; }; + F96058593FD3C9B8C55EDE66F17DE65E /* a_dup.c in Sources */ = {isa = PBXBuildFile; fileRef = 279DAF7322354512CDCD4BC5968C006E /* a_dup.c */; }; + F9B1FEE3A1FF29834BF8C7B9D24F3E38 /* Array+BoundsCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581957A460F05E4ACD7377112F415EEA /* Array+BoundsCheck.swift */; }; + FA2025E60FE222FA7D64F132E489DB3F /* ClientConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92206D944CFA8537AE3137C4C34F8351 /* ClientConnection.swift */; }; + FA321678D47162AFCE8D6D2717AF6482 /* Multiplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3155CD0AC33851B9A052F1421C6EF29C /* Multiplication.swift */; }; + FA6681F61CE9E2B71D507604A3CF7793 /* Google_Protobuf_Any+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B19ACA6BA4F4AFDFECA7E476DF3D949 /* Google_Protobuf_Any+Extensions.swift */; }; + FA778E0BE842D3266A5A67148F90468D /* aesv8-armx64.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = 970DE3CF94367649A0C1037F78DE8966 /* aesv8-armx64.linux.aarch64.S */; }; + FAC2251A8AAD90FBCB3EAF21B87D4F11 /* ReceivingPushPromiseState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF24D3F43BB89FBBE0F38FA3E5A66E5B /* ReceivingPushPromiseState.swift */; }; + FB02596D198EB66B6CDDD00F64ECF3EB /* x_x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 699AA7624510F132CCCA43004E29AF3F /* x_x509.c */; }; + FB04F98E7B54951A8854AA185087E096 /* SelectorUring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DBCEA097C38D41A4D4C7202B5074C77 /* SelectorUring.swift */; }; + FB30E0EC31F7BF815E935CD587DA5FB4 /* sha1-armv8.linux.aarch64.S in Sources */ = {isa = PBXBuildFile; fileRef = B973EA967343AFC1DF901B6918C7E1D3 /* sha1-armv8.linux.aarch64.S */; }; + FB359FC2B8375E01A8A8F84D3C50EE82 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = F37ABF268AD3432B45CED98A326932FB /* SDWebImageDownloaderResponseModifier.m */; }; + FB3AE837C059BFB7650B276B8F8CD451 /* bio_mem.c in Sources */ = {isa = PBXBuildFile; fileRef = 2208A35CDBBA7DCCEFF1FA3ECE745F07 /* bio_mem.c */; }; + FB56162BEA8AF3084D83EC769AF6BF82 /* x509_def.c in Sources */ = {isa = PBXBuildFile; fileRef = 6EB81601FBCD4A2EB2215AD7D3F98D37 /* x509_def.c */; }; + FB75C35AE50C5817BF46DE52DF48AE2F /* cpu_intel.c in Sources */ = {isa = PBXBuildFile; fileRef = C6DEF9947D494076C7D9D1324FD01167 /* cpu_intel.c */; }; + FBE59E78C51AE59228120999ACA53EC1 /* SocketAddress+NWEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0A22926820729A8784C92EA32D61569 /* SocketAddress+NWEndpoint.swift */; }; + FBF9F0B0B8CBB6211734394125177E84 /* tasn_utl.c in Sources */ = {isa = PBXBuildFile; fileRef = 92E357F294D6449E154AA957032191D4 /* tasn_utl.c */; }; + FC0BC091D9946965008A4FC8897C232A /* SignableUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B7A63C9E772AE749842EEEA4C93B6F5 /* SignableUser.swift */; }; + FC4C5AB4C2B9A776CB456F0947196200 /* NIOSSLServerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25E39B2ADC446C5FB878AB317A9A2F6D /* NIOSSLServerHandler.swift */; }; + FC4DF8D2F505E1B461CCB047D4C40AE2 /* ClientConnectionConfiguration+NIOSSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F7204919891D132080FB4623165DD5F /* ClientConnectionConfiguration+NIOSSL.swift */; }; + FCE2D34E84F3C89B8E4E03BFEFE3E646 /* Selectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3E3562250BD9DC2DCEC39BD3E40552 /* Selectable.swift */; }; + FCFB679BABFBF4E0E9FC812BD91B7DFB /* GRPCHeaderName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6004A2299268FB7700C904D7E47177B4 /* GRPCHeaderName.swift */; }; + FD034688B0EB9413321FD92EBC9D5C93 /* CNIOBoringSSL_boringssl_prefix_symbols_asm.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B75CA13DC587252CA4275F80B0A9B7 /* CNIOBoringSSL_boringssl_prefix_symbols_asm.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FD41B07598328C439A9E751673F93FB3 /* WalletProviderSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A339F6C2B3057C4FEB959D08FD97D501 /* WalletProviderSelectionViewController.swift */; }; + FD7710A5A649E95199C4D357E3B37070 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 42421A125481E8BC392AE93887636702 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FDA6C3D301D4905F17CD7C3191DAC50A /* HTTP2Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C2F8ACCB538BD6193D9C52D140644F /* HTTP2Error.swift */; }; + FDBBA7A2C479E21F8CE7A8B523B4AAF8 /* hexdump.c in Sources */ = {isa = PBXBuildFile; fileRef = A2C5C802B3FDA538AA688E471C10BA99 /* hexdump.c */; }; + FDD4676911B72FAA3507E707DDA44AB2 /* CNIOBoringSSL_dsa.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C2A0DFE4E35AC9512309D40178C611 /* CNIOBoringSSL_dsa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FDD69F9D6A002DF8F252ABE0E067BE29 /* ecdsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 86B849448B31D6D97CC059662046AB48 /* ecdsa.c */; }; + FE0189D2FE038AD82C4CCF5A801A50A3 /* SDDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FD9A8BDDC22690193E3A35513F8F21E /* SDDiskCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE045CC1A836EE919908F461FAB4D88D /* f_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C54FE2987488C6C135F609E75D9D5E5 /* f_string.c */; }; + FE05A1BF611E69C94BC7A9EADBE10B2F /* SDWebImageDownloaderConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B0C4554A14955AF5120F1DA97B1C66 /* SDWebImageDownloaderConfig.m */; }; + FE2DB3C76A33538019AC9F0E4C34B80A /* ParameterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF47AA3DA3B8EB010E9C9249B488EAC4 /* ParameterType.swift */; }; + FE451E52E11EC735B9B8803F94027594 /* TimeLimit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AFD068065187C51C67D79026959C01D /* TimeLimit.swift */; }; + FE4845B6FDD260059CDF9E26965CA31B /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5826C42634F78CBC9152291B92BE2D /* SDWebImageManager.m */; }; + FED0EC9EACFA0F0C5DEBC0FD7289F225 /* Integer Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70EDEE52BD5BEC13259E3639B8BA99A /* Integer Conversion.swift */; }; + FED292AF8AD5924263FC0A8D0B8AF26D /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D780F6DECFC48AFCAC7177C09D88CAA /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FEE735CEDD647C3E76C437CEBF95CFA7 /* pem_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 388E956EBF9BD27203EBEEEE800C4D24 /* pem_info.c */; }; + FF0A5DBCC4A8FF9B7A1BD8AC530D601E /* hash_to_curve.c in Sources */ = {isa = PBXBuildFile; fileRef = 76C4BC78E99BBCA69E17333115A63EE1 /* hash_to_curve.c */; }; + FF2852BDC874384F2E64A65E277D44F4 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = E5262DE15AC178F44123A11F52286966 /* internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FF378778F3B30B260D277BDAFE77EFE8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */; }; + FF66F3E7374A9398D5B08AA23273BC0E /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = D6834988BB87EBBA075596656CA2100C /* NSData+ImageContentType.m */; }; + FF82B869A9DEC533A4ABE96F83E5A90C /* ofb.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C9A1B083389A9099DA073CE542C2329 /* ofb.c */; }; + FFCE149A55EA0CB0909049C3AF92A082 /* field_5x52_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BE3FABFFCEF31E8FB55DE029BD0F0B /* field_5x52_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FFD43D91BF1FA4ADF714D56E7A10B2A8 /* SVProgressHUD-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E1116D42B41D6F34C7E3FE87161B217F /* SVProgressHUD-dummy.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 007E2C622AE440DBAA72215A3BC7216A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A5F702E0DA383BC1479572581615A916; + remoteInfo = SwiftProtobuf; + }; + 011FCF9545362173F0FBE27D15FDA00F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 016B36A757D510003C1FF2677152A957 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 01E8A316DE3D4D7D805B8D3BB407EED1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 032AD0EC02560D9D7B4399A8D005A5DE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 03C84521A9A390440B5FEA070034D7DB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 041E036BCFC30882D8EAB232D4BF231B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09DD83B7D075842A3A5105AD410BD38A; + remoteInfo = BigInt; + }; + 05E2EB24011DED185E76CAF73FB7187A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 060D532169A167D451CBEA885F664164 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 063AE03CF52FD4089CCA881D8069C526 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 07BF6A63FB50A073CE1CD9341FBDC653 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 085ADAFE3D4497B14E4E66AB6E8BF713 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 17112F66EE5BDC5584A51CF4FCE7631A; + remoteInfo = SwiftNIOHTTP2; + }; + 0ABC08C42E9CD5AEE7F38BA4A27E723C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 814D3CA630EB31504C9C25A1AE6B75B7; + remoteInfo = secp256k1Swift; + }; + 0C1F1BB9B17126E7101A54AEEAF4A0B1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 0D37A0500B5AC313193B8F6BA1DE79CA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 0DF445E46C0F343D535374EBA80D12D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 0E5C20DE1096DDD01912F83CEA7257C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 61DB9F97C45B368C17F830199512E361; + remoteInfo = SwiftNIOExtras; + }; + 0EB35E76647B981007A74F763038058D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D6DC8585F20CBE789F7D3D4F645980E; + remoteInfo = SwiftNIOTransportServices; + }; + 0FF205AB8D8A599D83FA92934D1E276C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6E71929B582F8CD57B3DC1FD6560F047; + remoteInfo = PopupDialog; + }; + 1115DE116B293761C48C4DD97C7B1E1A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 113AA8BBE0A13E9CC6BFB6F7DF17380C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 59007493BE8F52FEEC69F0F9330AA6C0; + remoteInfo = CNIOHTTPParser; + }; + 13C80CBE0F563D34465D31B2349AFFB7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56C793C77970EA2F3692F44FFEFD9360; + remoteInfo = SwiftNIOHTTP1; + }; + 146147665BF147A234F24A13AE2800BC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 150595293A93FB2D283EA1466C123621 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 1561371AD8F22F67C5360697A1C7C20A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CE9E4A87F29CA10BA13A4B9B6FCCD386; + remoteInfo = Cadence; + }; + 166AC9F8687964D156096204D85FF88C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 16706E4FAB9B83FC505D57767BD0D1EC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 179820060F76F48D063EEC8ADA94D0BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 186FEA6AB4D1B52F85B5EBB3405320E0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 1CA2324B6D77615A2E946E94F1EA649F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2ABF3F8EC6CE525E1E02C51D72C64E94; + remoteInfo = Logging; + }; + 1D4BF5981FD9B49F3F1BD59ADF246E63 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2ABF3F8EC6CE525E1E02C51D72C64E94; + remoteInfo = Logging; + }; + 1DF019299CA434C64BAA7F7ABD4156C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 1EC76625A150AF6659E66157A04DB6D9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5A8A5B4451A77B0A6D36B131E2974E23; + remoteInfo = BloctoSDK; + }; + 1F3DAC5DEA2109107383A49EE149DDB9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 21FEF6FA7764BCF0C73A76DD5E8E8700 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1C8D67D8B72D6BA42CCEDB648537A340; + remoteInfo = SVProgressHUD; + }; + 22695A8AE408F69BE2B83B587BDFE795 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 814D3CA630EB31504C9C25A1AE6B75B7; + remoteInfo = secp256k1Swift; + }; + 236E60C5BA1B88E2D5957A292A09A10B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 2509575E1DEAB6AEE8DF714B23F8F3AD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 17112F66EE5BDC5584A51CF4FCE7631A; + remoteInfo = SwiftNIOHTTP2; + }; + 2521065BFAED9868C6354FFC483ABE6C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 263C505EDA0C83A41F82635C57CD6564 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 2640BB9E1C26CC9B981EAB6779ABAA54 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 26821F82ECAB576923B07947E8B2AAE1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CE9E4A87F29CA10BA13A4B9B6FCCD386; + remoteInfo = Cadence; + }; + 288CB4D61A66EDB921CDCC9D85EA8C1E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 814D3CA630EB31504C9C25A1AE6B75B7; + remoteInfo = secp256k1Swift; + }; + 29756E76526D338DDC89FF0E99828D70 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 2A275ED137F21C7EA192634F03985446 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 2A5514C534984ED14F98EDA40FEBE4FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 2B5B555A20BA12AC80F7EAB92FE9BA4E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 2C8ADE5F6348A98677CD308906BC49F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E0A1D7BDF9C722E6E4B4B1E012D20E51; + remoteInfo = SwiftNIOTLS; + }; + 2CBA22C034E6B1C1276895BB554FA976 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2ABF3F8EC6CE525E1E02C51D72C64E94; + remoteInfo = Logging; + }; + 2F65C9D254D345582D1CA26215A9EF64 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 30C846D3C3BD2898035960FCCCB31A61 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 31401FDD32168A417476E33592D92FFC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 320A70E3D80981A9E4E5454B7B7D7CEF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 32A757E08C231B3C57A49F2658384DB4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09DD83B7D075842A3A5105AD410BD38A; + remoteInfo = BigInt; + }; + 32CC88FDE27D57C6F78D16D8EC361579 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 341514C5489E78BADDD2029CAFE28406 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 72EA11C51422080CE0CAEC35AC0EE02D; + remoteInfo = secp256k1Wrapper; + }; + 343A616783C2ABF0950C2492FAE2B7D8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 359A80515EFDA29DBD050956CAD216CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF4D556EB90FFD6388321BDFD45BDDB3; + remoteInfo = SwiftNIOSSL; + }; + 36407F1DA4AC005C2FBA349D8C0BE391 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 36471A42BAD1E0F83090D6B679884A35 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 3698DDDA359A8167FDF5106B36B81A27 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56C793C77970EA2F3692F44FFEFD9360; + remoteInfo = SwiftNIOHTTP1; + }; + 37250669E7938A4BA2D5392353C75417 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7D914FA2F03C860D5133BA2DB87C594A; + remoteInfo = DynamicBlurView; + }; + 38D31EAB0513D90E61C29FAD29BDA30E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F52E6DA0104A4F8C767EF42CAE3D09F4; + remoteInfo = MercariQRScanner; + }; + 39626834F4ABA8A5763DBE0D8BDF1F2B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D118A6A04828FD3CDA8640CD2B6796D2; + remoteInfo = SwiftyJSON; + }; + 39B9E7790728BE450AFB2655675DFE59 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 3A38E91E97412EF882B4B5C46D722124 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 3A4522680D2949492B9E844E32C7DF88 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 3C5272FED129B87287C2C31848EF9D83 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 834F3DE9EFC7B90102D63A51F6A9AF51; + remoteInfo = SwiftNIOFoundationCompat; + }; + 3E9E583206CE24BA87D4DF69FD34A227 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 65C8D0D3B04F444B821EB675E4D821DA; + remoteInfo = CNIOBoringSSLShims; + }; + 400938569EC22CF0264EA228555F5C18 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 851EADC4C9B098805B57AB058076FF60; + remoteInfo = "gRPC-Swiftp"; + }; + 42C4686E33E8239E5CF5D8A45DED0F25 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 72EA11C51422080CE0CAEC35AC0EE02D; + remoteInfo = secp256k1Wrapper; + }; + 4410D3443B9F65A10FF461AD09E78210 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 61DB9F97C45B368C17F830199512E361; + remoteInfo = SwiftNIOExtras; + }; + 4496E0639926295FD5936C9F86FC2D2F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 454CDA7172449E4C4DD703ED0C7F6069 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D94F5C545887C8BC575883E745A3DF; + remoteInfo = CNIOBoringSSL; + }; + 459834457F831D18A418B6EE8FE2CB5B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E0A1D7BDF9C722E6E4B4B1E012D20E51; + remoteInfo = SwiftNIOTLS; + }; + 461FAABF37F0331E4D4817912711A708 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 54382245E5C9DB4A3CFB906FD97A35BB; + remoteInfo = CGRPCZlibp; + }; + 46C8F4A16410C25E72369CD68DBAC10F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 474CB4272BC96F5C8D4C011FC2CBB4CE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 477E53130651B3909A182675B4C4FCAE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 4787086F9EAC3A1599AD7984A0CE6CEA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E0A1D7BDF9C722E6E4B4B1E012D20E51; + remoteInfo = SwiftNIOTLS; + }; + 489812E11F21AA4D734684968B50FC51 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D5D61C34B6B0F36656A57CF77C297BA6; + remoteInfo = "Pods-fanex"; + }; + 48DF44B1FF4BA87119DE8E0B025BDDA8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 4BE0634985444EB31423906950EB2B07 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 4F98B8334A017F71137B1151ED9614C6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 561DB9653F62FEF27FACB5AE49E2EC7E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D6DC8585F20CBE789F7D3D4F645980E; + remoteInfo = SwiftNIOTransportServices; + }; + 567428280E76013316E58E798DD673D6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 834F3DE9EFC7B90102D63A51F6A9AF51; + remoteInfo = SwiftNIOFoundationCompat; + }; + 598DF02B7F63F92B8D3AE53987C3EA9D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 85E705C55EE1E21751DAF1510D4F983E; + remoteInfo = "FCL-SDK"; + }; + 59EC701FAC3B88727031AB0FDCD4E39F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 5AB8B3C5C3FBDE2D6475BFD2D41C0A2B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 5C8D41E369967A0CAF3464324FD155E2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 5D19632B5016C9DB206EE8C5A0251A46 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 446DA03EDE44E6615A2A146E3D90AA3D; + remoteInfo = FlowSDK; + }; + 5D706C9E78C870C6B75A06ACC66C6460 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 99313990C1D76A6D1D017868B6975CC8; + remoteInfo = CryptoSwift; + }; + 5E667CECEA2BAAACDD6F4777FB337151 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 608DD3935EFCF53434BE7677B6D12514 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + 612A8EB388C5C59728D21E714BC0B0D0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7D914FA2F03C860D5133BA2DB87C594A; + remoteInfo = DynamicBlurView; + }; + 62B4BED0BEA634F9AF755194CE21319F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 6325AAE95A73366E78EFE686A9FE2E22 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 64F7E28614025CC638DFAAABC030AA3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1C8D67D8B72D6BA42CCEDB648537A340; + remoteInfo = SVProgressHUD; + }; + 67420F30499074783FC59C820F1F9DD2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 69BC47F9871E54C8D9B54001848F2E3A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 6D2149B338570BEE8192BB1DEBA540EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 85E705C55EE1E21751DAF1510D4F983E; + remoteInfo = "FCL-SDK"; + }; + 6D63A243211BC9A0679F952887020D61 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 6D9958164AEFF9DE5180A6BAEC533FA5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 6F096D160F0FF315B45E64F5C3CEB0DF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 6FB8A3277A47394257400C39103EE2FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 71886DD1D10B704945D4AF329EA0354F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 71D605E165020EA96DFA324B65D8EF87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 720031B6A08B4106F7F89EE671AB17CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 72F7D63905F7B9FD11391B2AD0587DFF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 744A0FD25358AC3F85726588CC53BFCF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6E71929B582F8CD57B3DC1FD6560F047; + remoteInfo = PopupDialog; + }; + 745BD01F7202E46E3A389374712646EC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + 7A1422DA53F2C9AAB83526FF3B48D9E9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + 7C372F9FE6B97CB3877A3B6390A857E8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 7D176593519D8732AF619B9F6022B558 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 7DF0D2688104EAA8BE606EA2F746C0A2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 81B37D09C5F4F8C02E435C7920D719EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 99313990C1D76A6D1D017868B6975CC8; + remoteInfo = CryptoSwift; + }; + 8251E5FB0C03ED523D4EBA886C92CBDC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + 82936E53E97920F437B6791032F52747 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 83934CCE1EDEEB92855858388EA00529 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56C793C77970EA2F3692F44FFEFD9360; + remoteInfo = SwiftNIOHTTP1; + }; + 8572B29F638AEFD74C158EDE6570A6ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F71DD9985215E142F625AD23A9121477; + remoteInfo = SwiftNIOHPACK; + }; + 8976B05569E2A8F510B55C6BBE8FD179 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 17112F66EE5BDC5584A51CF4FCE7631A; + remoteInfo = SwiftNIOHTTP2; + }; + 89F5EA84604067AC37A943E275E5BFFD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + 8A044C1E99A8260CAD6C6968013A1FA1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 59007493BE8F52FEEC69F0F9330AA6C0; + remoteInfo = CNIOHTTPParser; + }; + 8A67AAFB1201BF513252E61B60D97B19 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 8B12164E223B7EF0BDA57157FA071117 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 446DA03EDE44E6615A2A146E3D90AA3D; + remoteInfo = FlowSDK; + }; + 90636EEA2DE2AD94DDF681285ADDAC62 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D118A6A04828FD3CDA8640CD2B6796D2; + remoteInfo = SwiftyJSON; + }; + 913F2557E49A59D1DA1C947F3AAF1D50 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + 926103AA6EE13F1BFF5B4D090941122A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E0A1D7BDF9C722E6E4B4B1E012D20E51; + remoteInfo = SwiftNIOTLS; + }; + 9284D82866A643F412BA470CE71F9DC0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 834F3DE9EFC7B90102D63A51F6A9AF51; + remoteInfo = SwiftNIOFoundationCompat; + }; + 97A1CE3537297B2C6228270754F2BB12 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + 98CBA552B690C24228BB719478264946 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + 9A1ED3674DC1D2A9C27EAD6EB793FAC5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 9B5BAB5D91B7D73F529D8F2EE56B1FE3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + 9CA09BAA47DFC260B05F0FBDE7C4DD12 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 851EADC4C9B098805B57AB058076FF60; + remoteInfo = "gRPC-Swiftp"; + }; + 9CE74CB9083EC2EDD2C39CB92A743B95 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + 9D523B64DA99BD016DB79C6675FEDF59 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 59007493BE8F52FEEC69F0F9330AA6C0; + remoteInfo = CNIOHTTPParser; + }; + 9E0332FA582B4CC0B88B2071ADABFA3D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF4D556EB90FFD6388321BDFD45BDDB3; + remoteInfo = SwiftNIOSSL; + }; + 9EA1DCAA28525470DE468DCB2DA6D6A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56C793C77970EA2F3692F44FFEFD9360; + remoteInfo = SwiftNIOHTTP1; + }; + 9F25906B9B7A431FF1E878AC47D58463 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; + remoteInfo = SDWebImage; + }; + A068280261EB172A7C160505F4BE5E1A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F71DD9985215E142F625AD23A9121477; + remoteInfo = SwiftNIOHPACK; + }; + A3F7F837E3861CF47CD3E07FFFCE9928 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F71DD9985215E142F625AD23A9121477; + remoteInfo = SwiftNIOHPACK; + }; + A507FC181960BD26EF143FB76515F8E0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + A892774CBA503C27274DD3A934809C69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + A9B521AC1FE3E4FD80F0A1BAC2C38B45 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + ABDEDD5288A8D4B8B2A73AE3A4ACA387 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + AC323AB2D83D96B7A83E1A72C24EB835 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + ACAA08D268FCCC3A032638503C6B6323 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 446DA03EDE44E6615A2A146E3D90AA3D; + remoteInfo = FlowSDK; + }; + AE4788BA882A138FEC36F0591DF8AB76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + AF86CA6C6B4EEA71024D9B73CF95F7E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + B00340090F9EB12B85C89D463ABCD6E0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + B07A3799A069CF3100BCF7D61C8F5161 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + B14BDBE2A863612EC7E960B0530FAFD9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E0A1D7BDF9C722E6E4B4B1E012D20E51; + remoteInfo = SwiftNIOTLS; + }; + B34C14187AF7A63905EA0FF0EE609DB3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + B43293B3D6210ECD720AF479AA680A1A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 65C8D0D3B04F444B821EB675E4D821DA; + remoteInfo = CNIOBoringSSLShims; + }; + B65D7796D78DA1252A779595C98E0D07 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D94F5C545887C8BC575883E745A3DF; + remoteInfo = CNIOBoringSSL; + }; + B9C07ED05B4DEA8EA7227C6AFA0B298D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + BBEC2851149C6DC5B8FB4C160813E4E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + BC1A0A0B3AFED043AC112F357551069B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + BCE4A899DD76943CB4C18FD423A7FBC4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 72EA11C51422080CE0CAEC35AC0EE02D; + remoteInfo = secp256k1Wrapper; + }; + BEC0FA37A5E4CDA00551CB63F192C89F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + BFD520B864050F77C59E22B0E5BE3355 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + C057AD48EE614BDEBCDDF0A5C654FC0D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5A8A5B4451A77B0A6D36B131E2974E23; + remoteInfo = BloctoSDK; + }; + C0E2677EA5DA9E47707A3D85539D7D70 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CE9E4A87F29CA10BA13A4B9B6FCCD386; + remoteInfo = Cadence; + }; + C1693564C05C979A690CF92B218A38AA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 99313990C1D76A6D1D017868B6975CC8; + remoteInfo = CryptoSwift; + }; + C22CD13FEFC3A77C90DD26AC3708F2AA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 65C8D0D3B04F444B821EB675E4D821DA; + remoteInfo = CNIOBoringSSLShims; + }; + C2A8E3041CF0FB7D444AE71EE4934914 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 56A44E6B610D174593F40C5AD73224C4; + remoteInfo = CNIODarwin; + }; + C3119BAA6D1E87F62886E433B64703C9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + C4F3F99F1C7B42AFD03BCFBDBC6FF325 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + C6CA2332035A1B248840C9F30429C5B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + C6DDD11BFFE61C6BB1B21C9076E9453F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D94F5C545887C8BC575883E745A3DF; + remoteInfo = CNIOBoringSSL; + }; + C7B86302CC89BA2BD33F605BA2D19897 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + CA147885AA6336ED6147B9A72989B51C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + CB0C57F8A952E7615EDC1BA0BDA1BB60 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + CD229B86035C3093C9BDD1FDF8F79029 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + CFBE8C5F53D76F6229EC8E7B95BD4382 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + CFC45823198678BB6D6298D2D2C5DCDD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + D197677195BF55C212342DC98A1A5393 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + D24278AA8EBCC775AE29ECEE478BA235 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A5F702E0DA383BC1479572581615A916; + remoteInfo = SwiftProtobuf; + }; + D4705674247BEB907A5564A1895E08F8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + D4C0F307E7D8BD2C6B68A15135F5BDE3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09DD83B7D075842A3A5105AD410BD38A; + remoteInfo = BigInt; + }; + D645A2E3C9263D89B8A80F6E023E2BFB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + D6730A1A00AC749D4571513E234DE057 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + D72299E1B6908A755D54CB9FA200BCDE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + D79CDA0100D06E9A7C575C4C3D0290F5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 61DB9F97C45B368C17F830199512E361; + remoteInfo = SwiftNIOExtras; + }; + D971CFBAC387680E35EF1DE462A0C2DE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + DC9F331C33A5AA3ED7041D822576A892 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + DDC4B8191ACBEB54241AE7D92A9B0E41 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + DEC721464308D5861BE903A655B3B838 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + DF58493A604E051BE8E58492795839D4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09DD83B7D075842A3A5105AD410BD38A; + remoteInfo = BigInt; + }; + E181E9F63B04335A967CD540BC03F982 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D118A6A04828FD3CDA8640CD2B6796D2; + remoteInfo = SwiftyJSON; + }; + E47E05DE0D87639D83EADFE7EBFA3325 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A66DC2DC19095E11E5D3A679802D4; + remoteInfo = CNIOWindows; + }; + E582EC05CFA7ABB456657147779A415B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + E59038072916A52065F0536132BB59EF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 851EADC4C9B098805B57AB058076FF60; + remoteInfo = "gRPC-Swiftp"; + }; + E62582A92773F0D64A955AD2684CF9F5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D736A00DEDBE6AC34D5D1D32FD54046C; + remoteInfo = SwiftNIOPosix; + }; + E6B7DAB080EE245BA479A5E112486C37 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F818C63E0C8BC4199AC207AD36B89F0; + remoteInfo = SwiftNIOEmbedded; + }; + E726A64E631B923B2AEFFFE04A463346 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5E62229F86AA9810C2A7E6CF628B8486; + remoteInfo = SwiftNIO; + }; + EAD7286AFA0AF9C618C2957525784EFE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D6DC8585F20CBE789F7D3D4F645980E; + remoteInfo = SwiftNIOTransportServices; + }; + EB201969191599A59538AF32D6EB882A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F52E6DA0104A4F8C767EF42CAE3D09F4; + remoteInfo = MercariQRScanner; + }; + EB58221F3CD6A75B6F41BEA08DFFAB5C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 54382245E5C9DB4A3CFB906FD97A35BB; + remoteInfo = CGRPCZlibp; + }; + ED1B203A406398F17142F07FBF0793E3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF4D556EB90FFD6388321BDFD45BDDB3; + remoteInfo = SwiftNIOSSL; + }; + F0BD72A30A4162150B585B359E1B479B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 54382245E5C9DB4A3CFB906FD97A35BB; + remoteInfo = CGRPCZlibp; + }; + F0EE73BDDC076288873EC28787EFE8E2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7D914FA2F03C860D5133BA2DB87C594A; + remoteInfo = DynamicBlurView; + }; + F12D50DD742774B3C33E7E9582A58872 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E31BF93EB20B6245622D5A44E45F9BCA; + remoteInfo = CNIOAtomics; + }; + F1ADDFAFBD1BFFB92296406D0A25ECE8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5A8A5B4451A77B0A6D36B131E2974E23; + remoteInfo = BloctoSDK; + }; + F3352E2AB5DB41BEA6C15865C47DB699 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 99313990C1D76A6D1D017868B6975CC8; + remoteInfo = CryptoSwift; + }; + F3DC40A044D9C4C5ADA27AD1AA3346FF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34E23B39AFBC87A7678CDCA494DE5CDC; + remoteInfo = CNIOLinux; + }; + F4B783D816412CCC6DE9E69636FEA64E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D94F5C545887C8BC575883E745A3DF; + remoteInfo = CNIOBoringSSL; + }; + F75D262DCDAB8D705DBD93A4CB86FC4D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + F95C0132BC329B0ADD7C3D709A1C0E3D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A5F702E0DA383BC1479572581615A916; + remoteInfo = SwiftProtobuf; + }; + FA0C0459529775D533F0D601AFDE7A67 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A284FBC915D2D556B046FA0A96871C2F; + remoteInfo = SwiftNIOCore; + }; + FA1F72D908594FC64B32474EF09D746B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; + remoteInfo = SDWebImage; + }; + FD9A7E8499607C6A040E40308E7A3BD6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + FE760A803168F081CA76547159693FA7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 595729A6BA7621B06DBF24D66650D595; + remoteInfo = _NIODataStructures; + }; + FECFB85B4E98093FF67F5590C09F53A2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 59007493BE8F52FEEC69F0F9330AA6C0; + remoteInfo = CNIOHTTPParser; + }; + FEF2D44EEE9CB02013372B0F411F451A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; + FF0B12F5D8F0BC78FB6FBAF73AE49BD0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 59007493BE8F52FEEC69F0F9330AA6C0; + remoteInfo = CNIOHTTPParser; + }; + FFC66300C63CF8DF0A3C94B5CDC1C4A0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 773FB76F4A2F42092713B9025F188877; + remoteInfo = SwiftNIOConcurrencyHelpers; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 000D9C2A853E3E3FD34A1155D5819056 /* GetaddrinfoResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GetaddrinfoResolver.swift; path = Sources/NIOPosix/GetaddrinfoResolver.swift; sourceTree = ""; }; + 006D290CE0E3AA073250AE2695602D44 /* IO.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IO.swift; path = Sources/NIOCore/IO.swift; sourceTree = ""; }; + 009C115F9C8F1EBC270B2714D9C76DCE /* err_data.c */ = {isa = PBXFileReference; includeInIndex = 1; name = err_data.c; path = Sources/CNIOBoringSSL/crypto/err/err_data.c; sourceTree = ""; }; + 00B029DA3494978B4D55C326350A0C3B /* SDAssociatedObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAssociatedObject.h; path = SDWebImage/Private/SDAssociatedObject.h; sourceTree = ""; }; + 00B2F307985AC8DE763A234C8EACE96F /* UIImage+Blur.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImage+Blur.swift"; path = "Sources/DynamicBlurView/UIImage+Blur.swift"; sourceTree = ""; }; + 00BB1D33B406DC76DDD4359DA00B8353 /* BigInt-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "BigInt-dummy.m"; sourceTree = ""; }; + 00E8B69FA8F1B21329BA5D82E2893816 /* SwiftNIOConcurrencyHelpers.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOConcurrencyHelpers.debug.xcconfig; sourceTree = ""; }; + 0105C5BDCC968D3CB601B11FF63E74E4 /* SDWeakProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWeakProxy.m; path = SDWebImage/Private/SDWeakProxy.m; sourceTree = ""; }; + 012D295FB484D69B3CA2BD10A7F20B4C /* vpaes-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 0143F5E4F7DFC8834E9678910D8B8DBD /* SwiftNIOEmbedded-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOEmbedded-prefix.pch"; sourceTree = ""; }; + 014B4C27D85ADC3C511DAA45E701648D /* SDWebImageError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageError.m; path = SDWebImage/Core/SDWebImageError.m; sourceTree = ""; }; + 015510173B8F8742C76C82E9583217AB /* Schnorr.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Schnorr.swift; path = Sources/secp256k1Swift/Schnorr.swift; sourceTree = ""; }; + 019179E7EBA346AA3B2A3C0DA52BD554 /* CNIOBoringSSL-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOBoringSSL-dummy.m"; sourceTree = ""; }; + 019CEF31B4677F922E3374D77EF6DAA2 /* Resolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resolver.swift; path = "Sources/FCL-SDK/Resolve/Resolver.swift"; sourceTree = ""; }; + 01AEEA96113AD6E0F2E3656217271781 /* PBKDF1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF1.swift; path = Sources/CryptoSwift/PKCS/PBKDF1.swift; sourceTree = ""; }; + 01B66A124FC2BBB446F619F5F98F4ADA /* CNIODarwin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIODarwin.debug.xcconfig; sourceTree = ""; }; + 01E04E7584BFCB8E60E48FF5F3D89EFA /* Pods-fanexTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanexTests-Info.plist"; sourceTree = ""; }; + 024DE6CD691DEF3BBDAE8A50B8D56DF0 /* Logging-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Logging-umbrella.h"; sourceTree = ""; }; + 02645BB34CFF0DE639E95842490D9F30 /* CGRPCZlibp */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CGRPCZlibp; path = CGRPCZlib.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 02D9B7644BF54ECC5C459FE5F0A4D8A0 /* sha256-armv4.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-armv4.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.linux.arm.S"; sourceTree = ""; }; + 02E542CFBA98D0309857132E3BBABDB1 /* EdDSA.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EdDSA.swift; path = Sources/secp256k1Swift/EdDSA.swift; sourceTree = ""; }; + 030D13FA49F1EC5A5369417569B3F42C /* BloctoSDK-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BloctoSDK-umbrella.h"; sourceTree = ""; }; + 03896A4C5D1CA97D2AC38836D9DADA67 /* SSLContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLContext.swift; path = Sources/NIOSSL/SSLContext.swift; sourceTree = ""; }; + 03A9527754C739FD142F18EBFDCB50B9 /* SDWebImageDownloaderOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderOperation.m; path = SDWebImage/Core/SDWebImageDownloaderOperation.m; sourceTree = ""; }; + 03EF348493FE6F399B33F6E4E0764E51 /* Pods-fanex-fanexUITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-fanex-fanexUITests-dummy.m"; sourceTree = ""; }; + 043AE59D361B71B5E48ECC54B7625B1A /* MulticastChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MulticastChannel.swift; path = Sources/NIOCore/MulticastChannel.swift; sourceTree = ""; }; + 047FFFBE4CC1CEA41C4164578F58ACF8 /* CryptoSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CryptoSwift.modulemap; sourceTree = ""; }; + 0480F69F7241973DEDB98B22253663AC /* dh.c */ = {isa = PBXFileReference; includeInIndex = 1; name = dh.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/dh/dh.c; sourceTree = ""; }; + 04A53EE37AA8CA3AB2F52ABF0D84FD4E /* UIImageView+HighlightedWebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+HighlightedWebCache.h"; path = "SDWebImage/Core/UIImageView+HighlightedWebCache.h"; sourceTree = ""; }; + 04D2CC12E6E6166F2F0A662EDE733AE0 /* FileHandle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FileHandle.swift; path = Sources/NIOCore/FileHandle.swift; sourceTree = ""; }; + 04DE5AF97508CDFCD16CB50A4D988423 /* Constants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = "Sources/FCL-SDK/Constants.swift"; sourceTree = ""; }; + 04F09E3B56130C3D3396435B94FDB806 /* Logger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.swift; path = Sources/GRPC/Logger.swift; sourceTree = ""; }; + 04F5E9B44FFBBC5F19BE21D313A782EA /* CNIOAtomics-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOAtomics-Info.plist"; sourceTree = ""; }; + 0513510E718E5809FBE277362E08257D /* SDImageCachesManagerOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManagerOperation.h; path = SDWebImage/Private/SDImageCachesManagerOperation.h; sourceTree = ""; }; + 05BA590DAC219FB7EAC94ED634E0FB8F /* sha512-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 05C69BB038C2BE1ADA4A8E7DFE61589F /* x509_d2.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_d2.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_d2.c; sourceTree = ""; }; + 05F1AB638EAD1EF8DD5285B803ED81B7 /* ReferenceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReferenceType.swift; path = Sources/Cadence/CType/ReferenceType.swift; sourceTree = ""; }; + 0604EF3225428B5D345DFD1D40604F3E /* URLSessionExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLSessionExtension.swift; path = "Sources/FCL-SDK/Network/URLSessionExtension.swift"; sourceTree = ""; }; + 0624CB03F399E0666C965D9203090649 /* ghashv8-armx64.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghashv8-armx64.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.linux.aarch64.S"; sourceTree = ""; }; + 066BA4BE605B6CE1001F8E954A29FA45 /* CNIOBoringSSL_arm_arch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_arm_arch.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_arm_arch.h; sourceTree = ""; }; + 066CA9FB8FF27BE3124222A30B4AF4F8 /* SwiftNIOConcurrencyHelpers-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOConcurrencyHelpers-umbrella.h"; sourceTree = ""; }; + 0671DFB179723F36496A64FE5B5B2A25 /* x509_txt.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_txt.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_txt.c; sourceTree = ""; }; + 067FE95B3B4DC5361B13366DC2BE3ED3 /* JSONDecodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONDecodingError.swift; path = Sources/SwiftProtobuf/JSONDecodingError.swift; sourceTree = ""; }; + 0686F287BA1CB4499AAACB0B42046194 /* i2d_pr.c */ = {isa = PBXFileReference; includeInIndex = 1; name = i2d_pr.c; path = Sources/CNIOBoringSSL/crypto/x509/i2d_pr.c; sourceTree = ""; }; + 06A8DC591EE9F5CEEC5C7D12DC2FF72A /* crypto.c */ = {isa = PBXFileReference; includeInIndex = 1; name = crypto.c; path = Sources/CNIOBoringSSL/crypto/crypto.c; sourceTree = ""; }; + 06CB876E7538CECF6296183C9239A40C /* SDImageGraphics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGraphics.m; path = SDWebImage/Core/SDImageGraphics.m; sourceTree = ""; }; + 070EB0072D9FA1881763CA6EA3B48CA2 /* OutboundFrameBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OutboundFrameBuffer.swift; path = "Sources/NIOHTTP2/Frame Buffers/OutboundFrameBuffer.swift"; sourceTree = ""; }; + 07204D813C49972B4CF09D3F10D926A6 /* JSONEncodingOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONEncodingOptions.swift; path = Sources/SwiftProtobuf/JSONEncodingOptions.swift; sourceTree = ""; }; + 073163420BED79D3F0D457FBB780682B /* co-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "co-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/co-586.linux.x86.S"; sourceTree = ""; }; + 07424D645F2E9ACEEF471C2D45E734F9 /* scalar_8x32_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_8x32_impl.h; path = src/scalar_8x32_impl.h; sourceTree = ""; }; + 0744CD624F8529BFDA6DD9FE8C4A0D3F /* curve25519_32.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = curve25519_32.h; path = Sources/CNIOBoringSSL/third_party/fiat/curve25519_32.h; sourceTree = ""; }; + 075CFC2142202D06EF31BDC7AF046762 /* DynamicBlurView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "DynamicBlurView-Info.plist"; sourceTree = ""; }; + 076E1182AF5CAA2AD260B7CCA3ADAEF7 /* SDAsyncBlockOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAsyncBlockOperation.h; path = SDWebImage/Private/SDAsyncBlockOperation.h; sourceTree = ""; }; + 07DEEECEF437CFC809687467C7ED76E0 /* secp256k1Swift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = secp256k1Swift; path = secp256k1Swift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 07DFCEDD1083EC13218433CEA010C5DE /* SwiftNIOHTTP2-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOHTTP2-Info.plist"; sourceTree = ""; }; + 082C345E6CF5971948D1443C3E5061BC /* ServerErrorProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerErrorProcessor.swift; path = Sources/GRPC/ServerErrorProcessor.swift; sourceTree = ""; }; + 08323451668CE99A067392F0BB0D9036 /* SwiftNIOExtras.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOExtras.modulemap; sourceTree = ""; }; + 083FAF36C95CE4B92F4A465353ECE4C6 /* PopupDialog.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PopupDialog.modulemap; sourceTree = ""; }; + 08936EC14856D906A7C6AB50A157FA60 /* BinaryEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryEncoder.swift; path = Sources/SwiftProtobuf/BinaryEncoder.swift; sourceTree = ""; }; + 08A595AD5E52D398253F765D3646FEA3 /* Words and Bits.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Words and Bits.swift"; path = "Sources/CryptoSwift/CS_BigInt/Words and Bits.swift"; sourceTree = ""; }; + 08C897EDF2921AAEFC00DE41E4E472F1 /* tasn_typ.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_typ.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_typ.c; sourceTree = ""; }; + 08D128A5B7DECFFA30FE718DD3540B3E /* ConnectionManagerID.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionManagerID.swift; path = Sources/GRPC/ConnectionPool/ConnectionManagerID.swift; sourceTree = ""; }; + 08DF2B71AC6C25CA17AE97DDD49CD7E3 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/internal.h; sourceTree = ""; }; + 08DF434C8C2F95CD2F212947799075BA /* ServerHandlerStateMachine+Actions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerHandlerStateMachine+Actions.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Actions.swift"; sourceTree = ""; }; + 08F20911E8F738725F1098D11A744D10 /* BigInt-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BigInt-umbrella.h"; sourceTree = ""; }; + 08F3996E2ECA8D02EBEDE108CE6C07DA /* CNIOBoringSSL_des.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_des.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_des.h; sourceTree = ""; }; + 09297DFBBB10B6771E1F84A3F19325D7 /* Utils+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Utils+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Utils+Foundation.swift"; sourceTree = ""; }; + 09430125F9E5748C67B35E97EFF1E0C3 /* RestrictionType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RestrictionType.swift; path = Sources/Cadence/CType/RestrictionType.swift; sourceTree = ""; }; + 095487687BC21CBD523027ABA0812340 /* mul.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mul.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/mul.c; sourceTree = ""; }; + 0969899AE73EC6CB5D3EE43F1AEFF8E7 /* CNIOLinux-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOLinux-prefix.pch"; sourceTree = ""; }; + 09788728497C89B1D08DEAB7DB2D2D86 /* CallbackMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallbackMethod.swift; path = Sources/Core/Models/CallbackMethod.swift; sourceTree = ""; }; + 097C04FF78D4121F703E70B171360395 /* CNIOWindows.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOWindows.modulemap; sourceTree = ""; }; + 09A50810385D7DEBCBAB856DE8A1E29C /* p256_beeu-x86_64-asm.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256_beeu-x86_64-asm.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.mac.x86_64.S"; sourceTree = ""; }; + 09D751421E4FEBFA7A96941313C1592A /* Bundle+Module.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bundle+Module.swift"; path = "QRScanner/Bundle+Module.swift"; sourceTree = ""; }; + 09E8238E00364F2B31B6E0428BB5C690 /* chacha20_poly1305_x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = chacha20_poly1305_x86_64.mac.x86_64.S; path = Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.mac.x86_64.S; sourceTree = ""; }; + 09EA10F3BD9588C5F0626E1E2EB3058F /* ghash-neon-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-neon-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.linux.aarch64.S"; sourceTree = ""; }; + 0A05782676F8CA2756C2C8E8A859BCB5 /* secp256k1Wrapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "secp256k1Wrapper-umbrella.h"; sourceTree = ""; }; + 0A0D5CC485EB2D72002AADA744B9B7DF /* SDImageCacheDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheDefine.m; path = SDWebImage/Core/SDImageCacheDefine.m; sourceTree = ""; }; + 0A1048B1348EB81E26D98A91883630AD /* FCLError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FCLError.swift; path = "Sources/FCL-SDK/FCLError.swift"; sourceTree = ""; }; + 0A4C652F98037553C4AA0E5E81811923 /* CNIODarwin.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIODarwin.modulemap; sourceTree = ""; }; + 0A8ABAFE8C989A5EC3349EB1395B6C86 /* ConnectionStreamsState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionStreamsState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStreamsState.swift; sourceTree = ""; }; + 0A95A53CE558FD0A98C3CC52BF080A1F /* SSLPublicKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLPublicKey.swift; path = Sources/NIOSSL/SSLPublicKey.swift; sourceTree = ""; }; + 0A98F39503CB658134EC3722FEC271DC /* sha512-armv4.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-armv4.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.ios.arm.S"; sourceTree = ""; }; + 0AAD2E654193717BE99B9064DD4811B7 /* SendingWindowUpdateState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingWindowUpdateState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingWindowUpdateState.swift; sourceTree = ""; }; + 0ABF0F0C625CF2ABE592F32D09A9B9CD /* ConnectionKeepalive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionKeepalive.swift; path = Sources/GRPC/ConnectionKeepalive.swift; sourceTree = ""; }; + 0AD6EEDAB47DBB048F944F50271E9FE0 /* ByteBuffer-core.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-core.swift"; path = "Sources/NIOCore/ByteBuffer-core.swift"; sourceTree = ""; }; + 0ADEDF5DB5CACF65B1F5326FC7DE2542 /* StreamEncryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamEncryptor.swift; path = Sources/CryptoSwift/StreamEncryptor.swift; sourceTree = ""; }; + 0AEBF46834A19EE43F1812948101E19D /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/hrss/internal.h; sourceTree = ""; }; + 0AF40917DF5A60C569C3D716E8DF3C25 /* TextFormatScanner.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatScanner.swift; path = Sources/SwiftProtobuf/TextFormatScanner.swift; sourceTree = ""; }; + 0AF76A158E58D3DF43D7424F076AAD88 /* e_aesgcmsiv.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_aesgcmsiv.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesgcmsiv.c; sourceTree = ""; }; + 0B3959585FF35CABC0E8BD2E19A0EA98 /* dsa_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = dsa_asn1.c; path = Sources/CNIOBoringSSL/crypto/dsa/dsa_asn1.c; sourceTree = ""; }; + 0B7819128C40A9899F97FAAA36D894B3 /* Exponentiation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Exponentiation.swift; path = Sources/CryptoSwift/CS_BigInt/Exponentiation.swift; sourceTree = ""; }; + 0B8022ED770EECA6AD08D59D3C644A1E /* sha256-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 0C2F281A4AA01935FE92D665AE9536B1 /* shim.c */ = {isa = PBXFileReference; includeInIndex = 1; name = shim.c; path = Sources/CNIOWindows/shim.c; sourceTree = ""; }; + 0C35921FB08EA0C514E6E13007AC5066 /* Bitwise Ops.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bitwise Ops.swift"; path = "Sources/Bitwise Ops.swift"; sourceTree = ""; }; + 0C469D31D68B05F5C787C4195A2FB4C9 /* SwiftProtobuf-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftProtobuf-dummy.m"; sourceTree = ""; }; + 0C88AF3E809F3C89DCD2B84B6726E1CF /* ecdsa_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ecdsa_asn1.c; path = Sources/CNIOBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c; sourceTree = ""; }; + 0C8B91EEF6FE8FD80692353167860554 /* SDImageCodersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCodersManager.h; path = SDWebImage/Core/SDImageCodersManager.h; sourceTree = ""; }; + 0CF8D342496F49AFD2C13EF26F105ADE /* fd.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fd.c; path = Sources/CNIOBoringSSL/crypto/bio/fd.c; sourceTree = ""; }; + 0D0CE134117056C9057B4DAFC24094EE /* ServerInterceptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerInterceptors.swift; path = Sources/GRPC/Interceptor/ServerInterceptors.swift; sourceTree = ""; }; + 0D15728B7F7BDD59F3421E167B782156 /* SwiftNIOFoundationCompat-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOFoundationCompat-dummy.m"; sourceTree = ""; }; + 0D383BE6F056AC34E290D9985C98F462 /* JSONEncodingVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONEncodingVisitor.swift; path = Sources/SwiftProtobuf/JSONEncodingVisitor.swift; sourceTree = ""; }; + 0D43A46ECC17F3BAA29A7A78DD21389C /* SVProgressHUD.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SVProgressHUD.modulemap; sourceTree = ""; }; + 0DA9ADEDD11ED9847050BA2534A8F7F6 /* Pods-fanex-fanexUITests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-fanex-fanexUITests-frameworks.sh"; sourceTree = ""; }; + 0E41CB40FFD567899DF0C9440841F298 /* x_name.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_name.c; path = Sources/CNIOBoringSSL/crypto/x509/x_name.c; sourceTree = ""; }; + 0E44DA338686E612A83487C6B0C5BFEB /* c-nioatomics.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "c-nioatomics.c"; path = "Sources/CNIOAtomics/src/c-nioatomics.c"; sourceTree = ""; }; + 0E4AF999BF1254DD47727C2AEB7CBE48 /* precomputed_ecmult_gen.c */ = {isa = PBXFileReference; includeInIndex = 1; name = precomputed_ecmult_gen.c; path = src/precomputed_ecmult_gen.c; sourceTree = ""; }; + 0E725B039DDE85D72BAF12B4A4CFB2F3 /* sha512-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-586.linux.x86.S"; sourceTree = ""; }; + 0E793BBA0C633FEEDBABABF92969F7DB /* x509_vfy.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_vfy.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_vfy.c; sourceTree = ""; }; + 0EA2685CC2F3E2263B3EA330DFF9E4B0 /* Utilities.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utilities.swift; path = Sources/NIOPosix/Utilities.swift; sourceTree = ""; }; + 0EC4AE025180D60650876592B1B3B7C0 /* UnaryResponseCallContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnaryResponseCallContext.swift; path = Sources/GRPC/ServerCallContexts/UnaryResponseCallContext.swift; sourceTree = ""; }; + 0ED5164774FF7BFEC7AED2C9C68CF8D2 /* FlowSDK-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FlowSDK-dummy.m"; sourceTree = ""; }; + 0EEB202953F639113C26DB38D5381833 /* HTTPTypes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPTypes.swift; path = Sources/NIOHTTP1/HTTPTypes.swift; sourceTree = ""; }; + 0F218B3EC4501CDBF5A97164AEFEFB25 /* eckey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = eckey.h; path = src/eckey.h; sourceTree = ""; }; + 0F21A408FF9FDD6A3FFEDE112A1BFA31 /* CryptoSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.release.xcconfig; sourceTree = ""; }; + 0F5BBB57A935727EEF21A5AF26FE7A1E /* EventLoopFuture+Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "EventLoopFuture+Deprecated.swift"; path = "Sources/NIOCore/EventLoopFuture+Deprecated.swift"; sourceTree = ""; }; + 0F614077E368A14C70311405F7FE69D0 /* tls_method.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls_method.cc; path = Sources/CNIOBoringSSL/ssl/tls_method.cc; sourceTree = ""; }; + 0F7204919891D132080FB4623165DD5F /* ClientConnectionConfiguration+NIOSSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ClientConnectionConfiguration+NIOSSL.swift"; path = "Sources/GRPC/ClientConnectionConfiguration+NIOSSL.swift"; sourceTree = ""; }; + 0F7A9500A6630A2CA8CA115E055B0062 /* struct.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = struct.pb.swift; path = Sources/SwiftProtobuf/struct.pb.swift; sourceTree = ""; }; + 0F8181A38BFEE82303D4BD20E1B79BA7 /* SwiftNIOSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOSSL.release.xcconfig; sourceTree = ""; }; + 0F8FBB2076A193DA0C2D6BF5BED3E049 /* ResponseContainers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseContainers.swift; path = Sources/GRPC/ClientCalls/ResponseContainers.swift; sourceTree = ""; }; + 0FB95F4D973D09EAB0AB4179AC1E066D /* SwiftNIOTLS.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOTLS.modulemap; sourceTree = ""; }; + 0FC4BA2407401C3D72C0698DD1AEEBE5 /* cpu_aarch64_apple.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_aarch64_apple.c; path = Sources/CNIOBoringSSL/crypto/cpu_aarch64_apple.c; sourceTree = ""; }; + 100736BBAE33F97D2D4BA48AF254EC25 /* SDWebImageTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransition.h; path = SDWebImage/Core/SDWebImageTransition.h; sourceTree = ""; }; + 1019854EC76E5A35372C2247872FBB45 /* SwiftNIOFoundationCompat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOFoundationCompat.release.xcconfig; sourceTree = ""; }; + 1073FF82D7B94967CD02A0F194F4DA56 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/digest/internal.h; sourceTree = ""; }; + 1074E48131DD1AE2A57E6DB16C89FEDB /* x86_64-mont.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86_64-mont.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.mac.x86_64.S"; sourceTree = ""; }; + 1077464057841BEBFE3889CA5E03ADFE /* x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509.c; path = Sources/CNIOBoringSSL/crypto/x509/x509.c; sourceTree = ""; }; + 1095271DD12AFF9F7DA342ED0452BF3D /* ServerInterceptorPipeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerInterceptorPipeline.swift; path = Sources/GRPC/Interceptor/ServerInterceptorPipeline.swift; sourceTree = ""; }; + 10B329999DE3EE0D8E00FA0D425AEFC3 /* SocketOptionProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SocketOptionProvider.swift; path = Sources/NIOCore/SocketOptionProvider.swift; sourceTree = ""; }; + 10CFF73497998A64521A8977F6B9C268 /* BloctoEnvironment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BloctoEnvironment.swift; path = Sources/Core/BloctoEnvironment.swift; sourceTree = ""; }; + 1109E4D9498CA2A28B97BFFC963ADD83 /* Utility.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utility.swift; path = Sources/secp256k1Swift/Utility.swift; sourceTree = ""; }; + 113398F397A4A27D8E9FFEE9D0AE4AC3 /* jacobi.c */ = {isa = PBXFileReference; includeInIndex = 1; name = jacobi.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/jacobi.c; sourceTree = ""; }; + 11355BF143D6A8167F1CF508A51F64EE /* dsa.c */ = {isa = PBXFileReference; includeInIndex = 1; name = dsa.c; path = Sources/CNIOBoringSSL/crypto/dsa/dsa.c; sourceTree = ""; }; + 124D5FE45BB35F7C5F6BEA5A13BB220B /* self_check.c */ = {isa = PBXFileReference; includeInIndex = 1; name = self_check.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/self_check.c; sourceTree = ""; }; + 125EACBDC5ACC520A733CADA059F44FC /* BinaryDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDecoder.swift; path = Sources/SwiftProtobuf/BinaryDecoder.swift; sourceTree = ""; }; + 125FE81450FCFDEECAB6FA98B546AB16 /* a_utf8.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_utf8.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_utf8.c; sourceTree = ""; }; + 126ECBF84E8EC272A797E71ED28D0785 /* p256_table.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = p256_table.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256_table.h; sourceTree = ""; }; + 129734FDDAF80E355B66A2397411314E /* HPACKEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HPACKEncoder.swift; path = Sources/NIOHPACK/HPACKEncoder.swift; sourceTree = ""; }; + 12CB7F9B92A615FA3F5971FA7CA71496 /* SDWebImageIndicator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageIndicator.h; path = SDWebImage/Core/SDWebImageIndicator.h; sourceTree = ""; }; + 130724651ABE653E5C388F378A1A011F /* obj_dat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = obj_dat.h; path = Sources/CNIOBoringSSL/crypto/obj/obj_dat.h; sourceTree = ""; }; + 134C82C2AF26C1F6D1FA6484A52A0FF4 /* SwiftNIOHTTP1 */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOHTTP1; path = NIOHTTP1.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 137BE3AC11783E57A07C5477D5948A98 /* ctx.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ctx.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/ctx.c; sourceTree = ""; }; + 137DDEABB44E61FEC937F8735AB2BFCA /* SDImageLoadersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoadersManager.m; path = SDWebImage/Core/SDImageLoadersManager.m; sourceTree = ""; }; + 139A78790D675E8D7658D8A8A2384794 /* cpu_aarch64_win.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_aarch64_win.c; path = Sources/CNIOBoringSSL/crypto/cpu_aarch64_win.c; sourceTree = ""; }; + 13CCC7587DA96C8EEF14833B955B0338 /* any.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = any.pb.swift; path = Sources/SwiftProtobuf/any.pb.swift; sourceTree = ""; }; + 13DDEA3EA920AEB24582257476D29CA3 /* SwiftNIOPosix-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOPosix-prefix.pch"; sourceTree = ""; }; + 13FCD06B6CB42DC1D49F888089EC1304 /* ghash-ssse3-x86.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-ssse3-x86.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86.linux.x86.S"; sourceTree = ""; }; + 1447A6EDADED82970E5400D1C1CF0BDE /* Array+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Extension.swift"; path = "Sources/CryptoSwift/Array+Extension.swift"; sourceTree = ""; }; + 1449BA3246ACAD59795CF756778E324E /* handoff.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = handoff.cc; path = Sources/CNIOBoringSSL/ssl/handoff.cc; sourceTree = ""; }; + 14651E9E01AE716B20D51B8CA012A3F9 /* NIOTSConnectionChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSConnectionChannel.swift; path = Sources/NIOTransportServices/NIOTSConnectionChannel.swift; sourceTree = ""; }; + 1477C5AA1AAA188540A3BFC4FA21B928 /* Signer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signer.swift; path = Sources/FlowSDK/Crypto/Signer.swift; sourceTree = ""; }; + 14819172B31D4560BBD90390AB099AA1 /* e_chacha20poly1305.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_chacha20poly1305.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c; sourceTree = ""; }; + 14932620AFF7A9C7891AE057709873BD /* gRPC-Swiftp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "gRPC-Swiftp-Info.plist"; sourceTree = ""; }; + 14C057D940A62DB7A534003E557095F2 /* UniversalBootstrapSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UniversalBootstrapSupport.swift; path = Sources/NIOSSL/UniversalBootstrapSupport.swift; sourceTree = ""; }; + 14DC03D634FF492642E6371B31F1264A /* md5.c */ = {isa = PBXFileReference; includeInIndex = 1; name = md5.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/md5/md5.c; sourceTree = ""; }; + 14ECEB7E2BDA7B586F03DE2D62E88580 /* x509cset.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509cset.c; path = Sources/CNIOBoringSSL/crypto/x509/x509cset.c; sourceTree = ""; }; + 150528A791ECFD7B40965F1B68C64876 /* ssl_aead_ctx.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_aead_ctx.cc; path = Sources/CNIOBoringSSL/ssl/ssl_aead_ctx.cc; sourceTree = ""; }; + 154D8E8D0F6B17F4D864A80C3C2543A1 /* CNIOBoringSSL-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOBoringSSL-umbrella.h"; sourceTree = ""; }; + 156F768DC24E72ABF7AFFB0B384D10C8 /* sha1-altivec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-altivec.c"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1-altivec.c"; sourceTree = ""; }; + 1575DC7DE34542CAA9140F3C83A38F9C /* FlowMethodType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlowMethodType.swift; path = Sources/Flow/Models/FlowMethodType.swift; sourceTree = ""; }; + 15847CFE3042952A3D46C83B0DD8A25F /* NIOSSLClientHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOSSLClientHandler.swift; path = Sources/NIOSSL/NIOSSLClientHandler.swift; sourceTree = ""; }; + 15D850324603466D1F86860D5F3BBC78 /* Addition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Addition.swift; path = Sources/CryptoSwift/CS_BigInt/Addition.swift; sourceTree = ""; }; + 15EEA51CFF44E7DD7562A964143DF44A /* BSDSocketAPIWindows.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BSDSocketAPIWindows.swift; path = Sources/NIOPosix/BSDSocketAPIWindows.swift; sourceTree = ""; }; + 15FA039D9BDF798A1C7C94118249DBCE /* DebugOutboundEventsHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DebugOutboundEventsHandler.swift; path = Sources/NIOExtras/DebugOutboundEventsHandler.swift; sourceTree = ""; }; + 167F7BD23ECC1417C82557643373AF11 /* key_wrap.c */ = {isa = PBXFileReference; includeInIndex = 1; name = key_wrap.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/aes/key_wrap.c; sourceTree = ""; }; + 1698B48A7FBCCD81FBEAF7B8D95C5CCD /* ghashv8-armx32.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghashv8-armx32.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.linux.arm.S"; sourceTree = ""; }; + 169D6C71568363DA1999B117D896AC68 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/internal.h; sourceTree = ""; }; + 16D1A09E96EB6E967038D24C69E5B2C0 /* aesni-x86.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesni-x86.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86.linux.x86.S"; sourceTree = ""; }; + 17130905A7954A110258063CF2BB0C33 /* EventLoopFuture+WithEventLoop.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "EventLoopFuture+WithEventLoop.swift"; path = "Sources/NIOCore/EventLoopFuture+WithEventLoop.swift"; sourceTree = ""; }; + 1793B1A8D6B29682805F8E809D394CFD /* SDWebImageOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOperation.h; path = SDWebImage/Core/SDWebImageOperation.h; sourceTree = ""; }; + 17A4019C4EFFC2C909028FCF61F52C50 /* PresentationManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PresentationManager.swift; path = PopupDialog/Classes/PresentationManager.swift; sourceTree = ""; }; + 17F7618D35EB1C624B284E6674556704 /* PoolManagerStateMachine+PerPoolState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PoolManagerStateMachine+PerPoolState.swift"; path = "Sources/GRPC/ConnectionPool/PoolManagerStateMachine+PerPoolState.swift"; sourceTree = ""; }; + 18078BAA5B8CD8C4BCE1F204781688A7 /* BloctoSDK */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = BloctoSDK; path = BloctoSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1808CB586541F56505012C7222909DEC /* aesni-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesni-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 1826E26775407F17457CCFAFF94835F3 /* SSLInit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLInit.swift; path = Sources/NIOSSL/SSLInit.swift; sourceTree = ""; }; + 183018A2F8E465C8814BA55F7DD78965 /* p_x25519_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_x25519_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/p_x25519_asn1.c; sourceTree = ""; }; + 1834AB61EE4BDDCD2DA92719083CB0F5 /* Blowfish.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Blowfish.swift; path = Sources/CryptoSwift/Blowfish.swift; sourceTree = ""; }; + 183EBD613645D681F4B465B7D841374E /* ConnectionManagerChannelProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionManagerChannelProvider.swift; path = Sources/GRPC/ConnectionManagerChannelProvider.swift; sourceTree = ""; }; + 1845575A98867066BC733AD1C8202CA5 /* LengthPrefixedMessageWriter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LengthPrefixedMessageWriter.swift; path = Sources/GRPC/LengthPrefixedMessageWriter.swift; sourceTree = ""; }; + 185AA3C3932111DAAA91315C83FF1256 /* NIOTSEventLoop.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSEventLoop.swift; path = Sources/NIOTransportServices/NIOTSEventLoop.swift; sourceTree = ""; }; + 1860DAB7ABED7C618762837FA928958D /* Pods-fanex-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-fanex-dummy.m"; sourceTree = ""; }; + 186F7FBFBC9EC8B701D8D23534B49107 /* GRPCIdleHandlerStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCIdleHandlerStateMachine.swift; path = Sources/GRPC/GRPCIdleHandlerStateMachine.swift; sourceTree = ""; }; + 18AD1C392EAEF15BD0F92D2E6BD8131F /* CNIOAtomics-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOAtomics-dummy.m"; sourceTree = ""; }; + 18B04B2811394A6178E69DA925AC1C9B /* UnknownStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnknownStorage.swift; path = Sources/SwiftProtobuf/UnknownStorage.swift; sourceTree = ""; }; + 190AC20F29333DC43C461DC412B766FD /* secp256k1Wrapper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = secp256k1Wrapper.debug.xcconfig; sourceTree = ""; }; + 190F33C8800487DE7FD3FC3D767E1502 /* SDWebImageTransition.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageTransition.m; path = SDWebImage/Core/SDWebImageTransition.m; sourceTree = ""; }; + 1910BB24C12FB9701C167D4835C46CF2 /* sha1-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.ios.aarch64.S"; sourceTree = ""; }; + 1936F11FC65709C16D7A78196D0740B1 /* SwiftNIOHPACK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHPACK.debug.xcconfig; sourceTree = ""; }; + 193F09AEBB44F16749D93F05FEDC1E59 /* SwiftNIOFoundationCompat-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOFoundationCompat-umbrella.h"; sourceTree = ""; }; + 193F9FE54D002CC3099E78F220DFD569 /* ECDSA.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ECDSA.swift; path = Sources/secp256k1Swift/ECDSA.swift; sourceTree = ""; }; + 1988AD6E34C0FF5849A9D31E644F9C42 /* TimeUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimeUtils.swift; path = Sources/SwiftProtobuf/TimeUtils.swift; sourceTree = ""; }; + 198BD051E2B3CA3FC8E558A4803C65F6 /* Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Internal.swift; path = Sources/SwiftProtobuf/Internal.swift; sourceTree = ""; }; + 1997AA70B5C9CF99899BAAE9C39F3687 /* ec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ec.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec.c; sourceTree = ""; }; + 19AB3AF641421C7780DA0A681572666A /* ApplicationProtocolNegotiationHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ApplicationProtocolNegotiationHandler.swift; path = Sources/NIOTLS/ApplicationProtocolNegotiationHandler.swift; sourceTree = ""; }; + 19E9154058D129015C37FB0D1CFADA46 /* CNIOBoringSSL_siphash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_siphash.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_siphash.h; sourceTree = ""; }; + 1A64A81ABFFD55BDD512C9EE827EB405 /* a_time.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_time.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_time.c; sourceTree = ""; }; + 1AA59255F85D49A61ECB56ADD71721B9 /* QueryItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QueryItem.swift; path = Sources/Core/Models/QueryItem.swift; sourceTree = ""; }; + 1AB0B628CE279EFD3E1BB98516E402AC /* NIOTSBootstraps.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSBootstraps.swift; path = Sources/NIOTransportServices/NIOTSBootstraps.swift; sourceTree = ""; }; + 1ABFC0B6B87D0498049F2399765759D2 /* HPACKDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HPACKDecoder.swift; path = Sources/NIOHPACK/HPACKDecoder.swift; sourceTree = ""; }; + 1ADC740F2C27B4194C6F202343AACA33 /* _NIODataStructures-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "_NIODataStructures-prefix.pch"; sourceTree = ""; }; + 1B019302E2A4FC7DB5D8D6C49AB207B4 /* Random.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Random.swift; path = Sources/Random.swift; sourceTree = ""; }; + 1B10E2920D0B16D49380B9A007D044A8 /* pcy_node.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_node.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_node.c; sourceTree = ""; }; + 1B1DE3821898D0F8784CB1671EBF4AB1 /* QuiescingHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuiescingHelper.swift; path = Sources/NIOExtras/QuiescingHelper.swift; sourceTree = ""; }; + 1B5826C42634F78CBC9152291B92BE2D /* SDWebImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageManager.m; path = SDWebImage/Core/SDWebImageManager.m; sourceTree = ""; }; + 1B85BE54C7D8BB813DE51F56C1CBEC85 /* Pods-fanex-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanex-Info.plist"; sourceTree = ""; }; + 1B9F59DEEB501854CB292BA30EED9FE1 /* scalar_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_impl.h; path = src/scalar_impl.h; sourceTree = ""; }; + 1BB4947856BAB2BD924157D3AA2E861C /* e_tls.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_tls.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_tls.c; sourceTree = ""; }; + 1BD11E4F78AC8858E805F4B175704574 /* montgomery_inv.c */ = {isa = PBXFileReference; includeInIndex = 1; name = montgomery_inv.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery_inv.c; sourceTree = ""; }; + 1C2F9D3B024AAF5570BB6D9D31F2CE81 /* GRPCAsyncResponseStreamWriter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncResponseStreamWriter.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStreamWriter.swift; sourceTree = ""; }; + 1C420B1758416686759479BC0808D903 /* x509_vpm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_vpm.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_vpm.c; sourceTree = ""; }; + 1C5B1F22506D5F481C955B8329C18EEB /* CNIOBoringSSL_x509v3.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_x509v3.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509v3.h; sourceTree = ""; }; + 1C745E1C3AB4D48E7AAE3A7CB7C661AB /* v3_ncons.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_ncons.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_ncons.c; sourceTree = ""; }; + 1C79F27D75309CFD6B32E480A9C7A0AA /* PopupDialogContainerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogContainerView.swift; path = PopupDialog/Classes/PopupDialogContainerView.swift; sourceTree = ""; }; + 1CA5BCBA60A0D0F4C9BB59488542BFB6 /* DH.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DH.swift; path = Sources/secp256k1Swift/DH.swift; sourceTree = ""; }; + 1CBC1E059014B56C25224FCC43A92433 /* HTTPServerPipelineHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPServerPipelineHandler.swift; path = Sources/NIOHTTP1/HTTPServerPipelineHandler.swift; sourceTree = ""; }; + 1CD67DE4C7F0D195290FB9B1CD3FA05F /* GRPCTimeout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCTimeout.swift; path = Sources/GRPC/GRPCTimeout.swift; sourceTree = ""; }; + 1D45A7157713AE7017F1EF3AF4930E2B /* v3_pci.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_pci.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_pci.c; sourceTree = ""; }; + 1D7FDD58731DDEA2F0F27C7ED1964F45 /* generic.c */ = {isa = PBXFileReference; includeInIndex = 1; name = generic.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/generic.c; sourceTree = ""; }; + 1DA1D186ACB7B19ECADBCFD4F0BBA144 /* Random.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Random.swift; path = Sources/CryptoSwift/CS_BigInt/Random.swift; sourceTree = ""; }; + 1DBEE5E02B05AA31F5C64FE602B3A266 /* SSLCallbacks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLCallbacks.swift; path = Sources/NIOSSL/SSLCallbacks.swift; sourceTree = ""; }; + 1DCF94245EE14B9D234181E1B22FD7C2 /* SSLConnection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLConnection.swift; path = Sources/NIOSSL/SSLConnection.swift; sourceTree = ""; }; + 1DDF0443455AE135021E6621A85C3D07 /* NIOTSEventLoopGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSEventLoopGroup.swift; path = Sources/NIOTransportServices/NIOTSEventLoopGroup.swift; sourceTree = ""; }; + 1DEF390E21590188D7A27E6EEBCE0616 /* JSONDecodingOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONDecodingOptions.swift; path = Sources/SwiftProtobuf/JSONDecodingOptions.swift; sourceTree = ""; }; + 1DFA6D41A16145F4392BBA40705024CF /* SDWebImageCacheSerializer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheSerializer.m; path = SDWebImage/Core/SDWebImageCacheSerializer.m; sourceTree = ""; }; + 1DFD26BAFD93E2F23DC053E3D8373D71 /* asn1_compat.c */ = {isa = PBXFileReference; includeInIndex = 1; name = asn1_compat.c; path = Sources/CNIOBoringSSL/crypto/bytestring/asn1_compat.c; sourceTree = ""; }; + 1E02FC64457E1330FD2D59B8A42CDDB9 /* RLPDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPDecoder.swift; path = Sources/FlowSDK/RLP/RLPDecoder.swift; sourceTree = ""; }; + 1E6BF9922345EBD760CFF08640E08E9E /* PrettyBytes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PrettyBytes.swift; path = Sources/secp256k1Swift/PrettyBytes.swift; sourceTree = ""; }; + 1E6ECA6B0A9A8C4E6A7CA9C4FB436793 /* SwiftNIOPosix.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOPosix.debug.xcconfig; sourceTree = ""; }; + 1E810951424A6E5BC0AF196C7E0520B1 /* FileDescriptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FileDescriptor.swift; path = Sources/NIOCore/FileDescriptor.swift; sourceTree = ""; }; + 1E8AF0B8E6E62DE4FF3C86D748245E23 /* SSLErrors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLErrors.swift; path = Sources/NIOSSL/SSLErrors.swift; sourceTree = ""; }; + 1E9CA9FCDB3FE02945409F2162324A36 /* Square Root.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Square Root.swift"; path = "Sources/Square Root.swift"; sourceTree = ""; }; + 1EBE1AB9F1660D3300D0A277E7A595F0 /* HMAC+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "HMAC+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/HMAC+Foundation.swift"; sourceTree = ""; }; + 1F03137B9A7361A477771450D163E9E8 /* HashVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HashVisitor.swift; path = Sources/SwiftProtobuf/HashVisitor.swift; sourceTree = ""; }; + 1F2E8E0EC3E3D0DA30CC01C980215515 /* ClientTransportFactory.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientTransportFactory.swift; path = Sources/GRPC/Interceptor/ClientTransportFactory.swift; sourceTree = ""; }; + 1F3D03A413A633F04396541E48627005 /* a_verify.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_verify.c; path = Sources/CNIOBoringSSL/crypto/x509/a_verify.c; sourceTree = ""; }; + 1F3E90EFBADCAF15D47861BF06C9C66F /* SDImageAWebPCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAWebPCoder.m; path = SDWebImage/Core/SDImageAWebPCoder.m; sourceTree = ""; }; + 1F3EA21AB0B510C02841B9B09476F9E2 /* SHA2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA2.swift; path = Sources/CryptoSwift/SHA2.swift; sourceTree = ""; }; + 1F5FF3D59B1851F9A4C9823F57AC5981 /* wrappers.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = wrappers.pb.swift; path = Sources/SwiftProtobuf/wrappers.pb.swift; sourceTree = ""; }; + 1F757CFB8F52CE330E5561E43BAAACF8 /* UIImage+ForceDecode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ForceDecode.h"; path = "SDWebImage/Core/UIImage+ForceDecode.h"; sourceTree = ""; }; + 1F75E00AC1E123368612D1953C7A472B /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/dsa/internal.h; sourceTree = ""; }; + 1F8E7AF066F0911188C195EF539855E4 /* DynamicBlurView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DynamicBlurView-dummy.m"; sourceTree = ""; }; + 1FE986B653115BDA8E79A7E164F44CFA /* MercariQRScanner-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MercariQRScanner-dummy.m"; sourceTree = ""; }; + 1FED0FFA4EB5C277938AE6448CC17382 /* SDWebImageDownloaderRequestModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderRequestModifier.h; path = SDWebImage/Core/SDWebImageDownloaderRequestModifier.h; sourceTree = ""; }; + 200DC709F6BF532949BC63AE3410B612 /* x86_64-mont5.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86_64-mont5.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.linux.x86_64.S"; sourceTree = ""; }; + 201003D040C6423595A3EC0B593CCEE5 /* a_bool.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_bool.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_bool.c; sourceTree = ""; }; + 201E492F116A89CDAA466CBA8D40CF6F /* v3_ia5.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_ia5.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_ia5.c; sourceTree = ""; }; + 201EE10DB004216D5209886FB7443829 /* NSData+ImageContentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+ImageContentType.h"; path = "SDWebImage/Core/NSData+ImageContentType.h"; sourceTree = ""; }; + 202EAE2488A3312FC2F0C7CA280CF2A1 /* FieldTypes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FieldTypes.swift; path = Sources/SwiftProtobuf/FieldTypes.swift; sourceTree = ""; }; + 203A85ED452B8D5A2E6607D17154B355 /* SelectableChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectableChannel.swift; path = Sources/NIOPosix/SelectableChannel.swift; sourceTree = ""; }; + 205E11C37E7B176455E96ACA338D3486 /* PassthroughMessageSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughMessageSource.swift; path = Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSource.swift; sourceTree = ""; }; + 206D595DA6D868D7DB345D772286138A /* ServerCallContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerCallContext.swift; path = Sources/GRPC/ServerCallContexts/ServerCallContext.swift; sourceTree = ""; }; + 20923CBF0D3E28FE03BFD939A5269687 /* scalar_4x64_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_4x64_impl.h; path = src/scalar_4x64_impl.h; sourceTree = ""; }; + 20AF747D8CB7AF6E01E1F7B58F040B26 /* Message+JSONAdditions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Message+JSONAdditions.swift"; path = "Sources/SwiftProtobuf/Message+JSONAdditions.swift"; sourceTree = ""; }; + 20D2544B93F0B3FCD20F549C25D6CF6F /* CNIOBoringSSL_hkdf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_hkdf.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_hkdf.h; sourceTree = ""; }; + 211122AEEB526BA62B5F07B93EE9D19E /* DigestType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DigestType.swift; path = Sources/CryptoSwift/DigestType.swift; sourceTree = ""; }; + 21294BEA1B79ECCF54117971DCFAD4E3 /* tls13_server.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls13_server.cc; path = Sources/CNIOBoringSSL/ssl/tls13_server.cc; sourceTree = ""; }; + 2139CE03849530684122BD8D1590DAD4 /* CNIOBoringSSL_thread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_thread.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_thread.h; sourceTree = ""; }; + 215056034A9C8EA82C4CC47FCD5CC9A6 /* PointerHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PointerHelpers.swift; path = Sources/NIOCore/PointerHelpers.swift; sourceTree = ""; }; + 215F034E1F8CB2245253C9C794A0405E /* SDImageIOAnimatedCoderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOAnimatedCoderInternal.h; path = SDWebImage/Private/SDImageIOAnimatedCoderInternal.h; sourceTree = ""; }; + 21651EE6A057DD7D2ADD0FBCE37B206E /* ConcurrentStreamBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentStreamBuffer.swift; path = "Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift"; sourceTree = ""; }; + 218871546F42F6E20E483CAD41CCE258 /* ClientConnection+NIOSSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ClientConnection+NIOSSL.swift"; path = "Sources/GRPC/GRPCChannel/ClientConnection+NIOSSL.swift"; sourceTree = ""; }; + 21CB70AC2EA6F4EB47A967F465F212BF /* HTTP2FrameParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2FrameParser.swift; path = Sources/NIOHTTP2/HTTP2FrameParser.swift; sourceTree = ""; }; + 2208A35CDBBA7DCCEFF1FA3ECE745F07 /* bio_mem.c */ = {isa = PBXFileReference; includeInIndex = 1; name = bio_mem.c; path = Sources/CNIOBoringSSL/crypto/bio/bio_mem.c; sourceTree = ""; }; + 2209F2B910446F43708EF208A89D3AE6 /* ClientErrorDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientErrorDelegate.swift; path = Sources/GRPC/ClientErrorDelegate.swift; sourceTree = ""; }; + 225201E51C43DA7D188B2242FC65C191 /* fork_detect.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fork_detect.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.c; sourceTree = ""; }; + 2257ABEBE7B0BE768733AA198201002D /* main_impl4.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = main_impl4.h; path = src/modules/schnorrsig/main_impl4.h; sourceTree = ""; }; + 225C2F0EB965A60AA6428E027F9D6370 /* CNIOBoringSSL_cpu.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_cpu.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_cpu.h; sourceTree = ""; }; + 228777DAC0CFA7ABAE01250071E1780F /* AppDetail.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AppDetail.swift; path = "Sources/FCL-SDK/Config/AppDetail.swift"; sourceTree = ""; }; + 22988D09847FF0EFBB7BF71B1818201F /* CircularBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CircularBuffer.swift; path = Sources/NIOCore/CircularBuffer.swift; sourceTree = ""; }; + 22AC771C467207A9BA0A54A03227D294 /* ssl_buffer.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_buffer.cc; path = Sources/CNIOBoringSSL/ssl/ssl_buffer.cc; sourceTree = ""; }; + 22D1A79C4C0AB646702F14CD7CB5F31C /* UniversalBootstrapSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UniversalBootstrapSupport.swift; path = Sources/NIOCore/UniversalBootstrapSupport.swift; sourceTree = ""; }; + 22D5900AE5CF42D49A30529330F50352 /* CNIOBoringSSL_dh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_dh.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_dh.h; sourceTree = ""; }; + 22DE16D46D4E1C5A7996BCCFF955DE5F /* ReceivingRstStreamState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingRstStreamState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingRstStreamState.swift; sourceTree = ""; }; + 2333C8CE8E8B8A2E2CEE465FDE578227 /* Zeroization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zeroization.swift; path = Sources/secp256k1Swift/Zeroization.swift; sourceTree = ""; }; + 2353F9CFA0E9F592D40639086374E728 /* t_x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = t_x509.c; path = Sources/CNIOBoringSSL/crypto/x509/t_x509.c; sourceTree = ""; }; + 235F85F616FBD4AFE863F4520D597CBE /* CNIOBoringSSL_cmac.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_cmac.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_cmac.h; sourceTree = ""; }; + 239876020140DECD9541EF5A9B12F7B6 /* rsa_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsa_asn1.c; path = Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_asn1.c; sourceTree = ""; }; + 23A6E2F9965A1F5B3DEF4780054926B2 /* sqrt.c */ = {isa = PBXFileReference; includeInIndex = 1; name = sqrt.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/sqrt.c; sourceTree = ""; }; + 23DDBB141AC1C1CBD70DB81078C885CF /* SecureBytes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecureBytes.swift; path = "Sources/swift-crypto/Sources/Crypto/Util/SecureBytes.swift"; sourceTree = ""; }; + 23E55556354D48D4FD7988BAC017D751 /* GRPCChannelPool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCChannelPool.swift; path = Sources/GRPC/ConnectionPool/GRPCChannelPool.swift; sourceTree = ""; }; + 242C756CAA8E25AB53D50F4EB9DE1C91 /* CNIOBoringSSL_e_os2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_e_os2.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_e_os2.h; sourceTree = ""; }; + 248D34408517F523A350B44AC1E40FFF /* NoPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NoPadding.swift; path = Sources/CryptoSwift/NoPadding.swift; sourceTree = ""; }; + 249FA949B321C359DDB7A787CBB8E4CD /* TrackingMode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TrackingMode.swift; path = Sources/DynamicBlurView/TrackingMode.swift; sourceTree = ""; }; + 24A2CC40A74FE6E4ECA8426FD1F6E64C /* Division.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Division.swift; path = Sources/CryptoSwift/CS_BigInt/Division.swift; sourceTree = ""; }; + 24B7003D2F4E5985B21868B438D9AD55 /* ContentLengthVerifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContentLengthVerifier.swift; path = Sources/NIOHTTP2/ContentLengthVerifier.swift; sourceTree = ""; }; + 24C23B35B737F8A5A2A53DF67D203584 /* ThreadWindows.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadWindows.swift; path = Sources/NIOPosix/ThreadWindows.swift; sourceTree = ""; }; + 24CF3B0ED5000E1B181CBA28A128F837 /* MercariQRScanner-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MercariQRScanner-Info.plist"; sourceTree = ""; }; + 24F21E455C17C94138FF860D25DF2215 /* ber.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ber.c; path = Sources/CNIOBoringSSL/crypto/bytestring/ber.c; sourceTree = ""; }; + 24FAD07EDFD4F7446B7B3087913B744A /* CNIOBoringSSL_pkcs12.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_pkcs12.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs12.h; sourceTree = ""; }; + 25196B26AD9D6CDDD91A54874EFD4A1D /* PKCS7Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7Padding.swift; path = Sources/CryptoSwift/PKCS/PKCS7Padding.swift; sourceTree = ""; }; + 251AE8F2B12EC0B82DE04BDCA51B97EA /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/bytestring/internal.h; sourceTree = ""; }; + 2521D5239AD26895494922C727BB1151 /* SDInternalMacros.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDInternalMacros.m; path = SDWebImage/Private/SDInternalMacros.m; sourceTree = ""; }; + 252869E03C30E4DB9A6AE754D99A1D20 /* SwiftNIOFoundationCompat-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOFoundationCompat-Info.plist"; sourceTree = ""; }; + 2534CA8D3B74A01222E7A77A1A6B124F /* BloctoSDK-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "BloctoSDK-dummy.m"; sourceTree = ""; }; + 25583F9C089332D336990AD128E4EEE9 /* Digests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Digests.swift; path = Sources/secp256k1Swift/Digests.swift; sourceTree = ""; }; + 256418E2881B6DAA7F14910D02B5180E /* Call+AsyncRequestStreamWriter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Call+AsyncRequestStreamWriter.swift"; path = "Sources/GRPC/AsyncAwaitSupport/Call+AsyncRequestStreamWriter.swift"; sourceTree = ""; }; + 258C74AC14ED4729DFBD81F79BC024E5 /* HKDF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HKDF.swift; path = Sources/CryptoSwift/HKDF.swift; sourceTree = ""; }; + 25C0642A6B82FB59C0FFF8C9A592B792 /* cpp_magic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = cpp_magic.h; path = Sources/CNIOAtomics/src/cpp_magic.h; sourceTree = ""; }; + 25E39B2ADC446C5FB878AB317A9A2F6D /* NIOSSLServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOSSLServerHandler.swift; path = Sources/NIOSSL/NIOSSLServerHandler.swift; sourceTree = ""; }; + 25E3E2C3D37FF81B175B64914C4DC51A /* poly_rq_mul.S */ = {isa = PBXFileReference; includeInIndex = 1; name = poly_rq_mul.S; path = Sources/CNIOBoringSSL/crypto/hrss/asm/poly_rq_mul.S; sourceTree = ""; }; + 2610510E35410963A2FB651DA639BA4C /* execution.grpc.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = execution.grpc.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.grpc.swift; sourceTree = ""; }; + 261522E8FA2A52D990467B27DF2A76DB /* PBKDF2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF2.swift; path = Sources/CryptoSwift/PKCS/PBKDF2.swift; sourceTree = ""; }; + 2615582796F402C01E58DF1352B78ED9 /* UIView+Animations.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Animations.swift"; path = "PopupDialog/Classes/UIView+Animations.swift"; sourceTree = ""; }; + 2643C0596BCC8A98798192904EE5725E /* CNIOBoringSSL_opensslconf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_opensslconf.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslconf.h; sourceTree = ""; }; + 26468D5F27DE15516B01E0C24D8DC020 /* p_ec_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_ec_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/p_ec_asn1.c; sourceTree = ""; }; + 267062B3614E6E43C1A754BDDEBFDCBA /* CNIOHTTPParser.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOHTTPParser.debug.xcconfig; sourceTree = ""; }; + 2683A364FE598567755584430E34AEA8 /* Server.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Server.swift; path = Sources/GRPC/Server.swift; sourceTree = ""; }; + 268BA908D38F7A6EAB4AB545DEE155A1 /* ProtobufMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ProtobufMap.swift; path = Sources/SwiftProtobuf/ProtobufMap.swift; sourceTree = ""; }; + 2693B01988B6DE451619238CDDD1BC02 /* SDMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDMemoryCache.h; path = SDWebImage/Core/SDMemoryCache.h; sourceTree = ""; }; + 26B2FAE9195C1B10FB8289451911B381 /* vpaes-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 26BBF10E864BCDD9CB2BE2284E3C9035 /* Google_Protobuf_Timestamp+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Timestamp+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift"; sourceTree = ""; }; + 26C3A057EDD5E7D5E097B894F2E59B37 /* ProtoNameProviding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ProtoNameProviding.swift; path = Sources/SwiftProtobuf/ProtoNameProviding.swift; sourceTree = ""; }; + 26D493BEBDA50C996FF6E836192AD09F /* wnaf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = wnaf.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/wnaf.c; sourceTree = ""; }; + 26E0457317A2F98C0FAA8F58581A3B86 /* NameMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NameMap.swift; path = Sources/SwiftProtobuf/NameMap.swift; sourceTree = ""; }; + 2744B37C8ED8E5438A8F126831F29C6F /* aesni-gcm-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesni-gcm-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 275805B9428E3EAEBAAC2086BF1F4720 /* HuffmanTables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HuffmanTables.swift; path = Sources/NIOHPACK/HuffmanTables.swift; sourceTree = ""; }; + 275BABD7D495C8038B7954184A3542E8 /* e_des.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_des.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_des.c; sourceTree = ""; }; + 276ABCC94009D60FD2C18128F2B2586B /* ghash-armv4.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-armv4.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.linux.arm.S"; sourceTree = ""; }; + 277FEA5A1CCAD8C95A06EA8BD6BA4EFC /* SDImageCacheDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheDefine.h; path = SDWebImage/Core/SDImageCacheDefine.h; sourceTree = ""; }; + 279DAF7322354512CDCD4BC5968C006E /* a_dup.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_dup.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_dup.c; sourceTree = ""; }; + 27A0096D0F1AF00682CD50F6A4A08285 /* GRPCAsyncRequestStream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncRequestStream.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStream.swift; sourceTree = ""; }; + 27EBE9375FCD8E338CF2D516B8869EAE /* hkdf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hkdf.c; path = Sources/CNIOBoringSSL/crypto/hkdf/hkdf.c; sourceTree = ""; }; + 281C99726698FD07704A83C0E4CA33FB /* Logging-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Logging-prefix.pch"; sourceTree = ""; }; + 281D8BD48C1BED7DE797404CDF26B27E /* WalletProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WalletProvider.swift; path = "Sources/FCL-SDK/WalletProvider/WalletProvider.swift"; sourceTree = ""; }; + 2847E7D26F025BB1D57C079905EB843B /* DebugOnly.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DebugOnly.swift; path = Sources/GRPC/DebugOnly.swift; sourceTree = ""; }; + 288CF90C4C2212F995F62D27D54D0073 /* chacha-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 288D1967128600890475281F1DE4AF11 /* ecmult_gen_compute_table_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_gen_compute_table_impl.h; path = src/ecmult_gen_compute_table_impl.h; sourceTree = ""; }; + 28A8B8911F41C0B29674DD930FA0C2E8 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/ec_extra/internal.h; sourceTree = ""; }; + 28CB8C467C147A30A990880025432449 /* x509name.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509name.c; path = Sources/CNIOBoringSSL/crypto/x509/x509name.c; sourceTree = ""; }; + 2924B309ECDB9B85124C35459153AC54 /* Zlib.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zlib.swift; path = Sources/GRPC/Compression/Zlib.swift; sourceTree = ""; }; + 297DA80F9A4242565798518F67BD9061 /* _EmbeddedThroughput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _EmbeddedThroughput.swift; path = Sources/GRPC/_EmbeddedThroughput.swift; sourceTree = ""; }; + 29D2F5F9D2EBCABD0650C3DD9B6F124B /* ByteBuffer-views.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-views.swift"; path = "Sources/NIOCore/ByteBuffer-views.swift"; sourceTree = ""; }; + 29D83CEE77E716014FB275733BCA3AC0 /* BlockDecryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockDecryptor.swift; path = Sources/CryptoSwift/BlockDecryptor.swift; sourceTree = ""; }; + 29F05446E7403E52098CDA564AC7A9C6 /* HTTPPipelineSetup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPPipelineSetup.swift; path = Sources/NIOHTTP1/HTTPPipelineSetup.swift; sourceTree = ""; }; + 29FA795821AE0DC47490E02DE1710064 /* Composite.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Composite.swift; path = Sources/Cadence/Composite.swift; sourceTree = ""; }; + 2A0369DFFB5C299E59FA6CCCDCDB053E /* Pods-fanex-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanex-acknowledgements.plist"; sourceTree = ""; }; + 2A1BE9ABAC549D7D0A183959CFA54396 /* x86_64-mont5.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86_64-mont5.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont5.mac.x86_64.S"; sourceTree = ""; }; + 2A2FE0034D8005E82F47B9AB3C43969B /* MultiplexerAbstractChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultiplexerAbstractChannel.swift; path = Sources/NIOHTTP2/MultiplexerAbstractChannel.swift; sourceTree = ""; }; + 2A36B1EE7A2D9315FC135DC6ADC49CF8 /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVRadialGradientLayer.m; path = SVProgressHUD/SVRadialGradientLayer.m; sourceTree = ""; }; + 2A4CC298CC8CF90A2A7FAFA7D74BD1CF /* SwiftNIOHTTP2 */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOHTTP2; path = NIOHTTP2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2A6B5A15604556F5E309DBB8A743209B /* deterministic.c */ = {isa = PBXFileReference; includeInIndex = 1; name = deterministic.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/deterministic.c; sourceTree = ""; }; + 2A6DE3B81F7066E320CAC2CF2B74F561 /* Strideable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Strideable.swift; path = Sources/CryptoSwift/CS_BigInt/Strideable.swift; sourceTree = ""; }; + 2A8D955348F8FF566612970196459D9B /* GCD.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GCD.swift; path = Sources/GCD.swift; sourceTree = ""; }; + 2AB7DAA6F97DF10E00BD54DAB7CFD793 /* DynamicBlurView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DynamicBlurView.debug.xcconfig; sourceTree = ""; }; + 2B348362474913E38AF17055678DF7C7 /* access.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = access.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/access/access.pb.swift; sourceTree = ""; }; + 2B52153335ED8460B4D76170794B791A /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/x509v3/internal.h; sourceTree = ""; }; + 2B6F5E6ABD294A9AC1D6C2C7B56EEF23 /* ClientCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientCall.swift; path = Sources/GRPC/ClientCalls/ClientCall.swift; sourceTree = ""; }; + 2B7D55E7D073D38B90AE5EFDF895B883 /* armv4-mont.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "armv4-mont.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.ios.arm.S"; sourceTree = ""; }; + 2BB1B6E58F42F0A1C956FB24D13586B3 /* SwiftNIOSSL-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOSSL-Info.plist"; sourceTree = ""; }; + 2C2E5F552BE3FC33AF702D83A2839354 /* MessageParts.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageParts.swift; path = Sources/GRPC/Interceptor/MessageParts.swift; sourceTree = ""; }; + 2C3C2254EB57228190A1B6A024B26C52 /* DynamicBlurView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DynamicBlurView.release.xcconfig; sourceTree = ""; }; + 2C489C72417D9363D5C7D75F9A1786E7 /* StringUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StringUtils.swift; path = Sources/SwiftProtobuf/StringUtils.swift; sourceTree = ""; }; + 2C5C0BC3D6A52DA6F561E59A77FD1C48 /* Pods-fanex.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanex.debug.xcconfig"; sourceTree = ""; }; + 2C71484685488673050E878779E16406 /* a_bitstr.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_bitstr.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_bitstr.c; sourceTree = ""; }; + 2CCCCBFDF06E3D222AD3E72FFE4BD813 /* connect.c */ = {isa = PBXFileReference; includeInIndex = 1; name = connect.c; path = Sources/CNIOBoringSSL/crypto/bio/connect.c; sourceTree = ""; }; + 2CE94AE477E46E05AD8CD7994C9018A4 /* ssl_transcript.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_transcript.cc; path = Sources/CNIOBoringSSL/ssl/ssl_transcript.cc; sourceTree = ""; }; + 2D0DC076BBAB2EA49B318C0AEBB39F4F /* md32_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = md32_common.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/digest/md32_common.h; sourceTree = ""; }; + 2D19761A0B447DA579F73045D0EC0405 /* p256_beeu-armv8-asm.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256_beeu-armv8-asm.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.ios.aarch64.S"; sourceTree = ""; }; + 2D2544EF6EC105AB5E2D3F989DA6D4AC /* SDFileAttributeHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDFileAttributeHelper.h; path = SDWebImage/Private/SDFileAttributeHelper.h; sourceTree = ""; }; + 2D488D9F0EBC85B9EE41D929CABD0A2E /* x_sig.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_sig.c; path = Sources/CNIOBoringSSL/crypto/x509/x_sig.c; sourceTree = ""; }; + 2D517C93BB421BDDBD08A3281DFF9A4E /* SHA3.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA3.swift; path = Sources/CryptoSwift/SHA3.swift; sourceTree = ""; }; + 2D9C4B53AD56E6599FB7C338C7BD65F8 /* UIImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+WebCache.h"; path = "SDWebImage/Core/UIImageView+WebCache.h"; sourceTree = ""; }; + 2DE2E6E1CA325F9BF2A6343630420EFB /* IOData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IOData.swift; path = Sources/NIOCore/IOData.swift; sourceTree = ""; }; + 2E4DB6419D123356E98E2E5554EB8DCB /* asn_pack.c */ = {isa = PBXFileReference; includeInIndex = 1; name = asn_pack.c; path = Sources/CNIOBoringSSL/crypto/asn1/asn_pack.c; sourceTree = ""; }; + 2E64BD1FC6EAC0B1F102580C6E0D46BA /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = Sources/CryptoSwift/Utils.swift; sourceTree = ""; }; + 2E8885964394043CF304049308BC001F /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/conf/internal.h; sourceTree = ""; }; + 2E922A1CEE4EAFE9C8F97BD271F6A11F /* rsa_impl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsa_impl.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c; sourceTree = ""; }; + 2EC5CEA3C1A1008F4A6EF70E7F50D1F4 /* secp256k1Swift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "secp256k1Swift-dummy.m"; sourceTree = ""; }; + 2EE2751E013EF458FC67C5EBFFC5039C /* SwiftNIOSSL-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOSSL-prefix.pch"; sourceTree = ""; }; + 2F2A68C667C54E3B7561491056754A87 /* SVIndefiniteAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVIndefiniteAnimatedView.m; path = SVProgressHUD/SVIndefiniteAnimatedView.m; sourceTree = ""; }; + 2F5C53B14919489C35D8B006C24AEA4D /* CS.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CS.swift; path = Sources/CryptoSwift/CS_BigInt/CS.swift; sourceTree = ""; }; + 2F634A8F909B2004C538D3794F0DDF70 /* SwiftNIOEmbedded-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOEmbedded-dummy.m"; sourceTree = ""; }; + 2F63BA50A6FCCC7315BE388EE36A1A01 /* HTTP2StreamID.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2StreamID.swift; path = Sources/NIOHTTP2/HTTP2StreamID.swift; sourceTree = ""; }; + 2F6F9372C9AE6F2B9A7BE59E5A636A92 /* x25519-asm-arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x25519-asm-arm.S"; path = "Sources/CNIOBoringSSL/crypto/curve25519/asm/x25519-asm-arm.S"; sourceTree = ""; }; + 2FB81A1A9FA63E45CEA511A33CB9BD46 /* CNIOWindows.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOWindows.release.xcconfig; sourceTree = ""; }; + 2FD0458620342EF1241D8233FE11526E /* gcd.c */ = {isa = PBXFileReference; includeInIndex = 1; name = gcd.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd.c; sourceTree = ""; }; + 300BB2CB97DD4DA36846810A394A85E5 /* Pods-fanex */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-fanex"; path = Pods_fanex.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 302CF87E639FCD36334254EC25AE99C0 /* PopupDialog-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PopupDialog-umbrella.h"; sourceTree = ""; }; + 30340B262F1F7E20B838FE3271BD6903 /* Pods-fanexTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanexTests.release.xcconfig"; sourceTree = ""; }; + 3053B7EE86607A6432D4A5A3957AEACB /* CNIOWindows-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOWindows-Info.plist"; sourceTree = ""; }; + 305C829DCF6FBC7616A2B7DA53E928C4 /* x_pubkey.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_pubkey.c; path = Sources/CNIOBoringSSL/crypto/x509/x_pubkey.c; sourceTree = ""; }; + 306A34EEB7DC87E36AFC5C3247F4E4AE /* SDAsyncBlockOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAsyncBlockOperation.m; path = SDWebImage/Private/SDAsyncBlockOperation.m; sourceTree = ""; }; + 307067ECFCDF628D0BFA3A54498C23B8 /* Cadence-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Cadence-dummy.m"; sourceTree = ""; }; + 3079F5D1DE8B050D9D823C7D18855C53 /* x_all.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_all.c; path = Sources/CNIOBoringSSL/crypto/x509/x_all.c; sourceTree = ""; }; + 3090844C262BD61943DE6CB9833BDAD4 /* thread.c */ = {isa = PBXFileReference; includeInIndex = 1; name = thread.c; path = Sources/CNIOBoringSSL/crypto/thread.c; sourceTree = ""; }; + 30B1390D47F4087E0018F33553778E55 /* Address.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Address.swift; path = Sources/Cadence/Address.swift; sourceTree = ""; }; + 30B5844B0F5BCD183C6F24728D9D2D55 /* SDImageCachesManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManager.m; path = SDWebImage/Core/SDImageCachesManager.m; sourceTree = ""; }; + 30B9ECDEF200F0B0B7B43576A64F2D47 /* bn.c */ = {isa = PBXFileReference; includeInIndex = 1; name = bn.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bn.c; sourceTree = ""; }; + 30F8A9FFAD9DD5E2DCC1B6D55F8B31A4 /* TransactionResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransactionResult.swift; path = Sources/FlowSDK/Models/TransactionResult.swift; sourceTree = ""; }; + 31077F40DE76448B09C8C93E0DFE3AF3 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/internal.h; sourceTree = ""; }; + 3155CD0AC33851B9A052F1421C6EF29C /* Multiplication.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Multiplication.swift; path = Sources/CryptoSwift/CS_BigInt/Multiplication.swift; sourceTree = ""; }; + 3174AB3987026757E7D96EF2202B2CAB /* SocketChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SocketChannel.swift; path = Sources/NIOPosix/SocketChannel.swift; sourceTree = ""; }; + 31808CF1897D8D379D800951311CF3FF /* bio.c */ = {isa = PBXFileReference; includeInIndex = 1; name = bio.c; path = Sources/CNIOBoringSSL/crypto/bio/bio.c; sourceTree = ""; }; + 31815169F689A8CA600353549CAECB02 /* ExtensibleMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensibleMessage.swift; path = Sources/SwiftProtobuf/ExtensibleMessage.swift; sourceTree = ""; }; + 318E86C627046ABDA00262E294538BE6 /* x_info.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_info.c; path = Sources/CNIOBoringSSL/crypto/x509/x_info.c; sourceTree = ""; }; + 31A555D03ED5093AD41ACDF92A85B86C /* SwiftNIOTLS-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOTLS-Info.plist"; sourceTree = ""; }; + 31B37A38F26CFA3F17CD9667A71A9768 /* ecdsa_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecdsa_impl.h; path = src/ecdsa_impl.h; sourceTree = ""; }; + 31B47C603FED805DF8C2BB1365745900 /* _NIODataStructures.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = _NIODataStructures.release.xcconfig; sourceTree = ""; }; + 31DA3AB6DBAC8E44A9983629C3A978AA /* field_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_impl.h; path = src/field_impl.h; sourceTree = ""; }; + 31DCA335F3F32407235D0E111DFD0222 /* Config.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Config.swift; path = "Sources/FCL-SDK/Config/Config.swift"; sourceTree = ""; }; + 31E02D00A3F9AD848D15406BF6A7A49B /* ServiceAccountProof.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceAccountProof.swift; path = "Sources/FCL-SDK/User/Service/ServiceAccountProof.swift"; sourceTree = ""; }; + 31E0781A7DC6D1FDC2E73FE1098577E2 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/bio/internal.h; sourceTree = ""; }; + 31F4ED7CF3CE87BEDBC1F99CB0874EE6 /* tls13_both.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls13_both.cc; path = Sources/CNIOBoringSSL/ssl/tls13_both.cc; sourceTree = ""; }; + 322DEC6D54542BD146B90AE8B0641CB2 /* Shifts.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Shifts.swift; path = Sources/Shifts.swift; sourceTree = ""; }; + 3284F8D7D061DCA29D88332125072289 /* OFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OFB.swift; path = Sources/CryptoSwift/BlockMode/OFB.swift; sourceTree = ""; }; + 3296571AEE74017B771EDAE08C437F61 /* rand_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rand_extra.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/rand_extra.c; sourceTree = ""; }; + 32A8A8AEB4DC5E8D8F8540AE22FA44F6 /* precomputed_ecmult.c */ = {isa = PBXFileReference; includeInIndex = 1; name = precomputed_ecmult.c; path = src/precomputed_ecmult.c; sourceTree = ""; }; + 32DA1DE656AFDE4C64EFF20746AF3D0B /* HPACKHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HPACKHeader.swift; path = Sources/NIOHPACK/HPACKHeader.swift; sourceTree = ""; }; + 32DF3DB2C8D58227D79CBCAD10A7CC06 /* cpu_arm_linux.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = cpu_arm_linux.h; path = Sources/CNIOBoringSSL/crypto/cpu_arm_linux.h; sourceTree = ""; }; + 32FE80B761FCC33AFB00DEE944FAF1F9 /* NIOTSErrors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSErrors.swift; path = Sources/NIOTransportServices/NIOTSErrors.swift; sourceTree = ""; }; + 330EB56430E880E789BE7DFB1E461C89 /* SDWebImageDownloaderDecryptor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderDecryptor.h; path = SDWebImage/Core/SDWebImageDownloaderDecryptor.h; sourceTree = ""; }; + 3325BF8B476B063FCC992863946D8CB7 /* AuthenticationSessioning.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationSessioning.swift; path = Sources/Core/Protocols/AuthenticationSessioning.swift; sourceTree = ""; }; + 3327CF7D3195E556C6BC5D38CD50DC54 /* sign.c */ = {isa = PBXFileReference; includeInIndex = 1; name = sign.c; path = Sources/CNIOBoringSSL/crypto/evp/sign.c; sourceTree = ""; }; + 3341C39DD9BC0B467383DAB3D96B4E65 /* FCL-SDK-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FCL-SDK-dummy.m"; sourceTree = ""; }; + 334BFB5B2E3B497E2F56969B867E12E4 /* Format.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Format.swift; path = Sources/Cadence/Format.swift; sourceTree = ""; }; + 33A32575EDCB047F39900C2B6D2BAA59 /* x86_64-mont.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86_64-mont.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/x86_64-mont.linux.x86_64.S"; sourceTree = ""; }; + 33FFC143B0BC2F9DFBBEF1EA71EFEB36 /* SwiftNIOHTTP1.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHTTP1.debug.xcconfig; sourceTree = ""; }; + 3430DDB59333EC7767251863BFC41F5A /* ServerHandlerStateMachine+Idle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerHandlerStateMachine+Idle.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Idle.swift"; sourceTree = ""; }; + 3435A3B12A63A7FCB7B93A5B38A01B4B /* group.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = group.h; path = src/group.h; sourceTree = ""; }; + 3447ACB6AF004264B23BE6BF79FE179E /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/internal.h; sourceTree = ""; }; + 345E070647C98D8EDC77638552258C8B /* v3_pcons.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_pcons.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_pcons.c; sourceTree = ""; }; + 34B73542505E6AC61B95C80C000C7B18 /* Bootstrap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bootstrap.swift; path = Sources/NIOPosix/Bootstrap.swift; sourceTree = ""; }; + 34BDDD8B06A6C8AED5EB5D30FA9F2A88 /* p224-64.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "p224-64.c"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p224-64.c"; sourceTree = ""; }; + 34E313835ACC1C3A633A38FC5DA81F44 /* SDAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "SDAnimatedImageView+WebCache.h"; path = "SDWebImage/Core/SDAnimatedImageView+WebCache.h"; sourceTree = ""; }; + 34E4FBE2249766692D9DCD326AD210E0 /* SDImageFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageFrame.m; path = SDWebImage/Core/SDImageFrame.m; sourceTree = ""; }; + 34F6B3F237075144484066C543B8A2AA /* BlockModeOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = ""; }; + 34FB964502259D0FF233CE71CFDD2A71 /* PopupDialog */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PopupDialog; path = PopupDialog.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 351E7CAAA37F849FD7F76A7FB91F6F53 /* SwiftNIOHPACK-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOHPACK-Info.plist"; sourceTree = ""; }; + 3533A6CD08AF5725024A2238FD3F722B /* RoleType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RoleType.swift; path = "Sources/FCL-SDK/Models/RoleType.swift"; sourceTree = ""; }; + 35467501D3CA6E0233E29B1E9F1F0BEB /* aes128gcmsiv-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aes128gcmsiv-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 35A60E87A46C4A1C69DADD9B8B770A1F /* cpu_arm_linux.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_arm_linux.c; path = Sources/CNIOBoringSSL/crypto/cpu_arm_linux.c; sourceTree = ""; }; + 361B9C96B65816E47F1647BE9FDA0EC7 /* SwiftNIOFoundationCompat-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOFoundationCompat-prefix.pch"; sourceTree = ""; }; + 3621A9CDBCA3A77391C8DAAEE9B91FE4 /* CadenceResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CadenceResolver.swift; path = "Sources/FCL-SDK/Resolve/CadenceResolver.swift"; sourceTree = ""; }; + 3624E55B7B6A72C190EF3AFF2F736950 /* cpu_aarch64_linux.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_aarch64_linux.c; path = Sources/CNIOBoringSSL/crypto/cpu_aarch64_linux.c; sourceTree = ""; }; + 36483716E2DF6E768945736F78E8A549 /* ChannelOption.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChannelOption.swift; path = Sources/NIOCore/ChannelOption.swift; sourceTree = ""; }; + 36595D90A92316F603C71CB5F01F7C1E /* chacha.c */ = {isa = PBXFileReference; includeInIndex = 1; name = chacha.c; path = Sources/CNIOBoringSSL/crypto/chacha/chacha.c; sourceTree = ""; }; + 367CC54EBAD387B037592BA9CDFFC0FE /* FCL-SDK */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "FCL-SDK"; path = FCL_SDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 369A8C22EFAF607261525365CF510608 /* Subtraction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Subtraction.swift; path = Sources/CryptoSwift/CS_BigInt/Subtraction.swift; sourceTree = ""; }; + 369C48AD3362D32C75B73925F8EF8B43 /* SSLPrivateKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLPrivateKey.swift; path = Sources/NIOSSL/SSLPrivateKey.swift; sourceTree = ""; }; + 36BCE89A2F094A56A37CE24E51E8478E /* rsa_pss.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsa_pss.c; path = Sources/CNIOBoringSSL/crypto/x509/rsa_pss.c; sourceTree = ""; }; + 36D26F5E67278BD31B9999C31CB37CBE /* rsaz_exp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsaz_exp.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.c; sourceTree = ""; }; + 36F8D48D07C091BB1DACB071869B385C /* lock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = lock.swift; path = Sources/NIOConcurrencyHelpers/lock.swift; sourceTree = ""; }; + 3714076099ED9A889D91939B3943B37D /* collection.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = collection.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/collection.pb.swift; sourceTree = ""; }; + 3750323885EC02B225F7E44D305723D4 /* a_mbstr.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_mbstr.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_mbstr.c; sourceTree = ""; }; + 3772C1098F014CC7D14A0E944D584142 /* Service.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Service.swift; path = "Sources/FCL-SDK/User/Service/Service.swift"; sourceTree = ""; }; + 37F335D34944F3E6119B5E507E77BDEC /* DynamicHeaderTable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DynamicHeaderTable.swift; path = Sources/NIOHPACK/DynamicHeaderTable.swift; sourceTree = ""; }; + 380BE38C5A780567380E7CBDD33D7E9A /* HTTP2FlowControlWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2FlowControlWindow.swift; path = Sources/NIOHTTP2/HTTP2FlowControlWindow.swift; sourceTree = ""; }; + 381018DE63E6716965F88F348EFBA40B /* CNIOBoringSSL_rand.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_rand.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_rand.h; sourceTree = ""; }; + 381DA48DFA835D5C2909A03D9471E54A /* Pods-fanex-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-fanex-umbrella.h"; sourceTree = ""; }; + 383D394039DA0D40F1AC14793FDBFB62 /* rsa_print.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsa_print.c; path = Sources/CNIOBoringSSL/crypto/rsa_extra/rsa_print.c; sourceTree = ""; }; + 383EA49322B94216634E72962ED27F13 /* SVProgressHUD.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = SVProgressHUD.bundle; path = SVProgressHUD/SVProgressHUD.bundle; sourceTree = ""; }; + 388E956EBF9BD27203EBEEEE800C4D24 /* pem_info.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_info.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_info.c; sourceTree = ""; }; + 389A98E60BBEAB30A4712D63BE032A95 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/internal.h; sourceTree = ""; }; + 38B7C580C98CD15D9B5D5099A582F50F /* field_5x52_asm_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_5x52_asm_impl.h; path = src/field_5x52_asm_impl.h; sourceTree = ""; }; + 38BA9B5FEB9C039329AE2A15D4D42739 /* evp_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = evp_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/evp_asn1.c; sourceTree = ""; }; + 38D7A0D11CA207225D3E47CB684B339A /* FTypeDecodingResults.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FTypeDecodingResults.swift; path = Sources/Cadence/FTypeDecodingResults.swift; sourceTree = ""; }; + 391A2DAE73D4062B17F9DC9B32E75C7F /* pcy_map.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_map.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_map.c; sourceTree = ""; }; + 393B0F7F47A7F366DDF0A7E3405BBBAE /* CNIOWindows.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOWindows.debug.xcconfig; sourceTree = ""; }; + 3952A7D0C8AA53FC69555B71FFEC8EA3 /* x509_v3.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_v3.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_v3.c; sourceTree = ""; }; + 39863663084ED88A78F3ACB07CF63C20 /* PendingWritesManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PendingWritesManager.swift; path = Sources/NIOPosix/PendingWritesManager.swift; sourceTree = ""; }; + 398B10F826963DF33B9F0BBBD7B1E5C8 /* SwiftNIOHPACK-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHPACK-prefix.pch"; sourceTree = ""; }; + 39E42A345459393C420965B5E32F38D3 /* SelectiveVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectiveVisitor.swift; path = Sources/SwiftProtobuf/SelectiveVisitor.swift; sourceTree = ""; }; + 3A0D077A97DCF15297B0CCBD600A6CFF /* IntegerTypes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerTypes.swift; path = Sources/NIOPosix/IntegerTypes.swift; sourceTree = ""; }; + 3A13056BABF3222698DC5A80B5463130 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/aes/internal.h; sourceTree = ""; }; + 3A29A5BEB2B946BEE2C128683E4D9BBB /* SecurityFrameworkCertificateVerification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecurityFrameworkCertificateVerification.swift; path = Sources/NIOSSL/SecurityFrameworkCertificateVerification.swift; sourceTree = ""; }; + 3A47A564F560312A0F9EE315068D3F09 /* Embedded.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Embedded.swift; path = Sources/NIOEmbedded/Embedded.swift; sourceTree = ""; }; + 3A6622BC3A5738284B4FFB7EE3E49AC7 /* Capability.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Capability.swift; path = Sources/Cadence/Capability.swift; sourceTree = ""; }; + 3B0554ECD8C9BCA36CB6736F494816F1 /* main_impl2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = main_impl2.h; path = src/modules/extrakeys/main_impl2.h; sourceTree = ""; }; + 3B12017F089338B3E2DAE84CCF35DA50 /* UInt32+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt32+Extension.swift"; path = "Sources/CryptoSwift/UInt32+Extension.swift"; sourceTree = ""; }; + 3B1D90298B7591466F5ECEA71DE9F898 /* ec_montgomery.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ec_montgomery.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_montgomery.c; sourceTree = ""; }; + 3B1FF1FFA5E7337517ABF817BC382321 /* Floating Point Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Floating Point Conversion.swift"; path = "Sources/CryptoSwift/CS_BigInt/Floating Point Conversion.swift"; sourceTree = ""; }; + 3B3CA316383F8802A59A51825155C724 /* CNIOLinux.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOLinux.h; path = Sources/CNIOLinux/include/CNIOLinux.h; sourceTree = ""; }; + 3B3DE7FDD0ADABD706D2739EEB88BA64 /* ISO10126Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISO10126Padding.swift; path = Sources/CryptoSwift/ISO10126Padding.swift; sourceTree = ""; }; + 3B40B7E604BEB81EC871771768F61B00 /* fuchsia.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fuchsia.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/fuchsia.c; sourceTree = ""; }; + 3B675E4619748AE52DB48AE541E34C1A /* gRPC-Swiftp */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "gRPC-Swiftp"; path = GRPC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B7017881DF5963322E5F9BFB3FF8855 /* SDFileAttributeHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDFileAttributeHelper.m; path = SDWebImage/Private/SDFileAttributeHelper.m; sourceTree = ""; }; + 3B95149890F9EB8667E582B99117736A /* FCLCompositeSignature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FCLCompositeSignature.swift; path = "Sources/FCL-SDK/Models/FCLCompositeSignature.swift"; sourceTree = ""; }; + 3BB8B787D84DC3ED9227B3184A1A4369 /* Digest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Digest.swift; path = Sources/CryptoSwift/Digest.swift; sourceTree = ""; }; + 3BE2D8F9A463FC1F21117131272AD9D4 /* UIImage+ExtendedCacheData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ExtendedCacheData.h"; path = "SDWebImage/Core/UIImage+ExtendedCacheData.h"; sourceTree = ""; }; + 3BECF935580ED15BE7BBED8A011B189E /* ecmult_const.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_const.h; path = src/ecmult_const.h; sourceTree = ""; }; + 3C0A6F2A5DDB51F0F498518600BB7E21 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/poly1305/internal.h; sourceTree = ""; }; + 3C54FE2987488C6C135F609E75D9D5E5 /* f_string.c */ = {isa = PBXFileReference; includeInIndex = 1; name = f_string.c; path = Sources/CNIOBoringSSL/crypto/asn1/f_string.c; sourceTree = ""; }; + 3C5D5F0E96517B6A2FD7F1E6CC11A961 /* modinv32.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = modinv32.h; path = src/modinv32.h; sourceTree = ""; }; + 3C684847AD03E2C92EE6DC36358B8005 /* printf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = printf.c; path = Sources/CNIOBoringSSL/crypto/bio/printf.c; sourceTree = ""; }; + 3C90756B2FB9DEC6D7311D5881FF7FAC /* UIView+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCache.h"; path = "SDWebImage/Core/UIView+WebCache.h"; sourceTree = ""; }; + 3C9AF29710BD67F5A4A26E24F9B09020 /* CNIOBoringSSL_is_boringssl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_is_boringssl.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_is_boringssl.h; sourceTree = ""; }; + 3CC3BE4C1AD289339E860C9A67A5FCE5 /* PKCS7.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7.swift; path = Sources/CryptoSwift/PKCS/PKCS7.swift; sourceTree = ""; }; + 3D111CC23C86E6B89A4722CEDBB8FB26 /* CNIOBoringSSL_rc4.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_rc4.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_rc4.h; sourceTree = ""; }; + 3D236FDEF838701B1E66DFFA97F02D4E /* Data+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data+Extensions.swift"; path = "Sources/SwiftProtobuf/Data+Extensions.swift"; sourceTree = ""; }; + 3D2A8E0EA07BE8699C688044205A447C /* curve25519_64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = curve25519_64.h; path = Sources/CNIOBoringSSL/third_party/fiat/curve25519_64.h; sourceTree = ""; }; + 3D37BB9E32BA0A1B7CACF7479569D296 /* CNIOBoringSSL_opensslv.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_opensslv.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_opensslv.h; sourceTree = ""; }; + 3D8BAD0DF4E234C3431802E561A851D6 /* GRPCAsyncUnaryCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncUnaryCall.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncUnaryCall.swift; sourceTree = ""; }; + 3D9A44DCA7C25E6D914D065F57872D37 /* Logging.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Logging.modulemap; sourceTree = ""; }; + 3DC6A748C2861B919099BAC626E9198D /* MercariQRScanner-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MercariQRScanner-umbrella.h"; sourceTree = ""; }; + 3DE1360C6D2F87387AAD2D043161B451 /* CGRPCZlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CGRPCZlib.h; path = Sources/CGRPCZlib/include/CGRPCZlib.h; sourceTree = ""; }; + 3E0708E7CD171E1FC77EDE99034EC939 /* FType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FType.swift; path = Sources/Cadence/FType.swift; sourceTree = ""; }; + 3E0AC26AB92B81B956F7247841234F11 /* field_10x26_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_10x26_impl.h; path = src/field_10x26_impl.h; sourceTree = ""; }; + 3E34D3D39BF3DC05FEBA1760D451BD70 /* cbb.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cbb.c; path = Sources/CNIOBoringSSL/crypto/bytestring/cbb.c; sourceTree = ""; }; + 3E434DE23A18B5F3AE72EEB4CDE12D61 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/x509/internal.h; sourceTree = ""; }; + 3E7AFF69AFE0501AE9FEEC943B53D2C4 /* SwiftNIOEmbedded-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOEmbedded-umbrella.h"; sourceTree = ""; }; + 3E879CE367BE41AC0CAF08EDB2BBE007 /* Pods-fanex-fanexUITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-fanex-fanexUITests.modulemap"; sourceTree = ""; }; + 3ED5C868056584A2804EBA59AC1F8DB5 /* ghashv8-armx64.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghashv8-armx64.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx64.ios.aarch64.S"; sourceTree = ""; }; + 3EEFEF54C907113F6F86F4F48E57796D /* OutboundFlowControlBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OutboundFlowControlBuffer.swift; path = "Sources/NIOHTTP2/Frame Buffers/OutboundFlowControlBuffer.swift"; sourceTree = ""; }; + 3F42E68F8F1B4036B1AE89EDF9CFA7D3 /* ghash-ssse3-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-ssse3-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 3F8615D099F6945070841273BA82F9DA /* CNIOBoringSSL_obj.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_obj.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj.h; sourceTree = ""; }; + 3F9DCE64FEE0B4BE586CFAEB2F055774 /* pkcs7.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pkcs7.c; path = Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7.c; sourceTree = ""; }; + 3FB8BB999DEE6A0B9F8D50422812E258 /* digest.c */ = {isa = PBXFileReference; includeInIndex = 1; name = digest.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digest.c; sourceTree = ""; }; + 3FC68B1806253222E7DEC3A03FA57876 /* sha1-armv4-large.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-armv4-large.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.linux.arm.S"; sourceTree = ""; }; + 3FE009698F0B833B3B56D8E247C0E2D1 /* ghash-armv4.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-armv4.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-armv4.ios.arm.S"; sourceTree = ""; }; + 40358CCD7FAD3DBA05B893A63923B67B /* SDmetamacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDmetamacros.h; path = SDWebImage/Private/SDmetamacros.h; sourceTree = ""; }; + 404E03500F2035FA7045242A74AF80F4 /* DynamicBlurView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DynamicBlurView.swift; path = Sources/DynamicBlurView/DynamicBlurView.swift; sourceTree = ""; }; + 4073C7B6E2C3A068A9662C2499E43876 /* CNIOBoringSSL_ec_key.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ec_key.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec_key.h; sourceTree = ""; }; + 407CF315C2FCBAFEE027AB69D7D6746A /* FCL-SDK-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FCL-SDK-Info.plist"; sourceTree = ""; }; + 4091261A509088CF57731B9198952C95 /* TextFormatDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatDecoder.swift; path = Sources/SwiftProtobuf/TextFormatDecoder.swift; sourceTree = ""; }; + 40AEBB2D920B40CB9140D666883A8F17 /* secp256k1_schnorrsig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1_schnorrsig.h; path = include/secp256k1_schnorrsig.h; sourceTree = ""; }; + 40C2A0DFE4E35AC9512309D40178C611 /* CNIOBoringSSL_dsa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_dsa.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_dsa.h; sourceTree = ""; }; + 40C9DD71B957910488093D4D1003D53F /* URLSessionExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLSessionExtension.swift; path = Sources/Flow/Extensions/URLSessionExtension.swift; sourceTree = ""; }; + 40E3A228B04F1C4382F68906F3F17B0D /* Google_Protobuf_Struct+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Struct+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift"; sourceTree = ""; }; + 41139673B91A0801D89A7AD0239C82B4 /* KeyedDecodingContainerProtocolExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyedDecodingContainerProtocolExtension.swift; path = Sources/Core/Extensions/KeyedDecodingContainerProtocolExtension.swift; sourceTree = ""; }; + 4166CCB7B030C71C569CC9571ED054E0 /* ServerBuilder+NIOSSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerBuilder+NIOSSL.swift"; path = "Sources/GRPC/ServerBuilder+NIOSSL.swift"; sourceTree = ""; }; + 41C43FAEA6332A1BE439A46C4F647CF0 /* SocketProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SocketProtocols.swift; path = Sources/NIOPosix/SocketProtocols.swift; sourceTree = ""; }; + 421CA9C32CA2524466A67A1548654BBE /* Cipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = ""; }; + 4222400A280D18AAD5AD7F866EFF9A6C /* SwiftNIOConcurrencyHelpers-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOConcurrencyHelpers-dummy.m"; sourceTree = ""; }; + 42421A125481E8BC392AE93887636702 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/evp/internal.h; sourceTree = ""; }; + 425EC4E071C3E87CFBDBC0FCD714DC46 /* Pods-fanex-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-fanex-frameworks.sh"; sourceTree = ""; }; + 42607D9DB5A42F8245A1AB7CA432CAF2 /* CNIOBoringSSLShims.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOBoringSSLShims.modulemap; sourceTree = ""; }; + 4261559F8853764054D0325731A6DDA0 /* ZeroPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZeroPadding.swift; path = Sources/CryptoSwift/ZeroPadding.swift; sourceTree = ""; }; + 42A115EF9B5E2AD5EEB58AAEA68FFD8D /* Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Collection.swift; path = Sources/FlowSDK/Models/Collection.swift; sourceTree = ""; }; + 42C55DECF218CAD487EE2130755E8D2D /* util.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = util.h; path = src/util.h; sourceTree = ""; }; + 42C67CC7CB131AB7939B3A81F842DF44 /* Pods-fanex-fanexUITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-fanex-fanexUITests-umbrella.h"; sourceTree = ""; }; + 42E23A3C1C5D8CE37484B124E180BAA0 /* SwiftNIOTransportServices */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOTransportServices; path = NIOTransportServices.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 42F7F1A1DBBFB7640DC700B5B0F5E3A1 /* CNIOBoringSSL_span.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_span.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_span.h; sourceTree = ""; }; + 431FB716FA31D9BC5168E6D7645EAB0C /* PublickKey+Cadence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PublickKey+Cadence.swift"; path = "Sources/FlowSDK/Extensions/PublickKey+Cadence.swift"; sourceTree = ""; }; + 434EE467ACF31ADF9B7EB3AE050852FB /* simple_mul.c */ = {isa = PBXFileReference; includeInIndex = 1; name = simple_mul.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple_mul.c; sourceTree = ""; }; + 439C7DAD9370D19499787E98149B6764 /* _NIODataStructures-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "_NIODataStructures-dummy.m"; sourceTree = ""; }; + 439E97A1D3AC6989C07A674A4DF0344C /* Version.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Version.swift; path = Sources/GRPC/Version.swift; sourceTree = ""; }; + 43B010A061172855A37BE93C13FBDAD2 /* URLSessionProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLSessionProtocol.swift; path = Sources/Core/Protocols/URLSessionProtocol.swift; sourceTree = ""; }; + 43BCA78D557ACEB23EEA495EE0402530 /* SwiftNIOTLS */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOTLS; path = NIOTLS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 43C1ABD90C5C3F8E73ED1658CA23F8A4 /* ecdsa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecdsa.h; path = src/ecdsa.h; sourceTree = ""; }; + 43F69D217FB1BED38F59C70AF29DF895 /* _GRPCClientCodecHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _GRPCClientCodecHandler.swift; path = Sources/GRPC/_GRPCClientCodecHandler.swift; sourceTree = ""; }; + 44102141F3911EB572FE3710794EC10D /* BigInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BigInt.swift; path = Sources/CryptoSwift/CS_BigInt/BigInt.swift; sourceTree = ""; }; + 441A7B437D3E27161D566330AD6CA312 /* ECB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = ""; }; + 441FBD47A4C4F314DAA4E4D04E248A4B /* FCL-SDK-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FCL-SDK-prefix.pch"; sourceTree = ""; }; + 44437A9E7D313DF745E40B02473AE4CF /* String+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Extension.swift"; path = "Sources/CryptoSwift/String+Extension.swift"; sourceTree = ""; }; + 445336EC05FB156B35CD30D78AB56F7E /* HTTP2StreamChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2StreamChannel.swift; path = Sources/NIOHTTP2/HTTP2StreamChannel.swift; sourceTree = ""; }; + 445AF8E94A7BC212A4B000327B75D3BB /* FileDescriptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FileDescriptor.swift; path = Sources/NIOPosix/FileDescriptor.swift; sourceTree = ""; }; + 448192BAB37A6C7C19B4F9130C555DAE /* SwiftNIOCore-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOCore-prefix.pch"; sourceTree = ""; }; + 4487E443015FCF86B7D2288B4B132613 /* ChaCha20+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ChaCha20+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift"; sourceTree = ""; }; + 448C675002E3DCA228896933562EE2AA /* GRPCStatusAndMetadata.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCStatusAndMetadata.swift; path = Sources/GRPC/GRPCStatusAndMetadata.swift; sourceTree = ""; }; + 4498FC5440F2F336E68966637D8DEFE7 /* SDWebImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SDWebImage.modulemap; sourceTree = ""; }; + 44F9093DBD2DD7FB5CC1B73033D02658 /* BlockCipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockCipher.swift; path = Sources/CryptoSwift/BlockCipher.swift; sourceTree = ""; }; + 4527FDF828AF69BDCF723726E37DE46E /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Sources/_NIODataStructures/PriorityQueue.swift; sourceTree = ""; }; + 4548E0B0E2ED9F2EEF03049DE28D7C48 /* p256-armv8-asm.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256-armv8-asm.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S"; sourceTree = ""; }; + 45B6B33E8DD205D584F0FFBE94EF68B3 /* NIOAtomic.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOAtomic.swift; path = Sources/NIOConcurrencyHelpers/NIOAtomic.swift; sourceTree = ""; }; + 45D030D5F8B3618F444E710AF1876E44 /* BaseSocketChannel+SocketOptionProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "BaseSocketChannel+SocketOptionProvider.swift"; path = "Sources/NIOPosix/BaseSocketChannel+SocketOptionProvider.swift"; sourceTree = ""; }; + 46260190555EDA809052AAFE11384B6A /* QRScannerView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QRScannerView.swift; path = QRScanner/QRScannerView.swift; sourceTree = ""; }; + 467CCA25199920B058849FD6C2C321CE /* HasFlowControlWindows.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HasFlowControlWindows.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/HasFlowControlWindows.swift; sourceTree = ""; }; + 469DDA25BECAEAB7FC53F911528989DD /* BigUInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BigUInt.swift; path = Sources/BigUInt.swift; sourceTree = ""; }; + 470F5C098A9215008584059ED9E540D4 /* JSONRPCFraming.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONRPCFraming.swift; path = Sources/NIOExtras/JSONRPCFraming.swift; sourceTree = ""; }; + 4747431DC93868AA2BE766A668E675B6 /* ConnectionPool+Waiter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConnectionPool+Waiter.swift"; path = "Sources/GRPC/ConnectionPool/ConnectionPool+Waiter.swift"; sourceTree = ""; }; + 474EC5560C6B9561B3B042241C5711F7 /* MathUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MathUtils.swift; path = Sources/SwiftProtobuf/MathUtils.swift; sourceTree = ""; }; + 47589CEE455848A67549A64D69A4B25B /* by_dir.c */ = {isa = PBXFileReference; includeInIndex = 1; name = by_dir.c; path = Sources/CNIOBoringSSL/crypto/x509/by_dir.c; sourceTree = ""; }; + 476278A16583C8538AFE1DEB99804DC7 /* scalar_4x64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_4x64.h; path = src/scalar_4x64.h; sourceTree = ""; }; + 47AA2C31CB795D4CEC50EE6FA24AF4C1 /* LinuxCPUSet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinuxCPUSet.swift; path = Sources/NIOPosix/LinuxCPUSet.swift; sourceTree = ""; }; + 47AE5EF4EEF683F76336F5E2F095E501 /* PopupDialog.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PopupDialog.release.xcconfig; sourceTree = ""; }; + 47B239F6E85774E499B22605B3CDB384 /* a_gentm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_gentm.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_gentm.c; sourceTree = ""; }; + 47BAB972B9DA6714049FE8E07EF08C1C /* HTTPEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPEncoder.swift; path = Sources/NIOHTTP1/HTTPEncoder.swift; sourceTree = ""; }; + 47DD2CA25279CAE9CE134398B7EFA22C /* shims.c */ = {isa = PBXFileReference; includeInIndex = 1; name = shims.c; path = Sources/CNIOBoringSSLShims/shims.c; sourceTree = ""; }; + 47FEF39B78A6E02C765B4C708648B7A1 /* scalar_low.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_low.h; path = src/scalar_low.h; sourceTree = ""; }; + 4817559D2BD0D488311A04F0D16CB83A /* modinv32_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = modinv32_impl.h; path = src/modinv32_impl.h; sourceTree = ""; }; + 482746E8A1E48F9CA975F617D909F368 /* SDImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoader.h; path = SDWebImage/Core/SDImageLoader.h; sourceTree = ""; }; + 4829FCB00ADE43B6064E63565DEE1F5E /* SwiftNIOConcurrencyHelpers.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOConcurrencyHelpers.release.xcconfig; sourceTree = ""; }; + 484B18FCC75A69141F249D9018FC6E79 /* CCM.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CCM.swift; path = Sources/CryptoSwift/BlockMode/CCM.swift; sourceTree = ""; }; + 4866F4D0DEA7C704FFE87F04B0E49967 /* v3_extku.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_extku.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_extku.c; sourceTree = ""; }; + 488502B49EA245C5DF9A028AEA0D53B9 /* LineBasedFrameDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LineBasedFrameDecoder.swift; path = Sources/NIOExtras/LineBasedFrameDecoder.swift; sourceTree = ""; }; + 489556374B814C855DDA8F691A042350 /* AuthData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthData.swift; path = "Sources/FCL-SDK/Models/AuthData.swift"; sourceTree = ""; }; + 4895F0708E8EB50CD4A750A9511AE34F /* EventLoop.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventLoop.swift; path = Sources/NIOCore/EventLoop.swift; sourceTree = ""; }; + 48A974135B072A4B43A724AF83ACD734 /* Pods-fanex-fanexUITests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanex-fanexUITests-Info.plist"; sourceTree = ""; }; + 48BD2CBE13261ED5F8C62054F938FBA0 /* SendingGoawayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingGoawayState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingGoawayState.swift; sourceTree = ""; }; + 48D89B5DB7277D2575CCD411BCBF2911 /* ghash-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 48F5B0EAFC68E15D99BB48CE96AC36B3 /* bn-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "bn-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/bn-586.linux.x86.S"; sourceTree = ""; }; + 490CD9C4E3DE9C27BFBC75726FB70169 /* CNIOBoringSSL-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOBoringSSL-Info.plist"; sourceTree = ""; }; + 494D5E014AD83FD2360542A6642709E3 /* scalar_8x32.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_8x32.h; path = src/scalar_8x32.h; sourceTree = ""; }; + 49538024CCF200F26D85AF212732E499 /* handshake_server.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = handshake_server.cc; path = Sources/CNIOBoringSSL/ssl/handshake_server.cc; sourceTree = ""; }; + 498BAEFEA926989AF4B263B8ED9C52AC /* SwiftNIOEmbedded.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOEmbedded.release.xcconfig; sourceTree = ""; }; + 49A97EB307AB2A06BDBEE9950E524D56 /* ecmult_gen_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_gen_impl.h; path = src/ecmult_gen_impl.h; sourceTree = ""; }; + 49B2A8C3F35F5883ECABDFBA56D961C1 /* Data Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data Conversion.swift"; path = "Sources/CryptoSwift/CS_BigInt/Data Conversion.swift"; sourceTree = ""; }; + 49D4A33464B8025591F17F626782668E /* UIButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIButton+WebCache.m"; path = "SDWebImage/Core/UIButton+WebCache.m"; sourceTree = ""; }; + 4A13E071B674DC17F15A4DEB4243ECB1 /* HPACKErrors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HPACKErrors.swift; path = Sources/NIOHPACK/HPACKErrors.swift; sourceTree = ""; }; + 4A1D16EDB0405CEE4C837F184DC39013 /* CNIOWindows */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOWindows; path = CNIOWindows.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4A26A6109C860BF91A1D978645558CC2 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/asn1/internal.h; sourceTree = ""; }; + 4A4223B40ACB8BC2DD87DDE651C4ADF0 /* SwiftNIOEmbedded-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOEmbedded-Info.plist"; sourceTree = ""; }; + 4A53D04E30BEBD984D583E8B0882AB4E /* CNIOBoringSSLShims-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOBoringSSLShims-Info.plist"; sourceTree = ""; }; + 4A56A69DF36F5FA88C2DD9305B3D0C31 /* SwiftNIOTLS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOTLS-dummy.m"; sourceTree = ""; }; + 4AFD068065187C51C67D79026959C01D /* TimeLimit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TimeLimit.swift; path = Sources/GRPC/TimeLimit.swift; sourceTree = ""; }; + 4B2D28E09E850EBAACFFC4677BFF6724 /* Pods-fanex-fanexUITests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-fanex-fanexUITests"; path = Pods_fanex_fanexUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BA75EA43D5FC6726DC39A45537FD5D3 /* asn1_lib.c */ = {isa = PBXFileReference; includeInIndex = 1; name = asn1_lib.c; path = Sources/CNIOBoringSSL/crypto/asn1/asn1_lib.c; sourceTree = ""; }; + 4BA7A5A13941436B4785B45BEF1D9012 /* p256-x86_64-asm.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256-x86_64-asm.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.linux.x86_64.S"; sourceTree = ""; }; + 4BC863125BAAAA379F9D46B9B09FA011 /* spake25519.c */ = {isa = PBXFileReference; includeInIndex = 1; name = spake25519.c; path = Sources/CNIOBoringSSL/crypto/curve25519/spake25519.c; sourceTree = ""; }; + 4C3F73AE7C39FA0571F1FC3BD4B748E1 /* SwiftNIOTransportServices.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOTransportServices.modulemap; sourceTree = ""; }; + 4C9C8C0D310CF5B79226BE303CE6DE71 /* Decoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Decoder.swift; path = Sources/SwiftProtobuf/Decoder.swift; sourceTree = ""; }; + 4CA162300774D9EC15AE362843239196 /* UIViewController+Visibility.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIViewController+Visibility.swift"; path = "PopupDialog/Classes/UIViewController+Visibility.swift"; sourceTree = ""; }; + 4CE71D92B1BAC8A1856C21B6C893EEED /* DomainTag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DomainTag.swift; path = Sources/FlowSDK/Models/DomainTag.swift; sourceTree = ""; }; + 4CECE1D3F082EE1C5AF7E5E93BAEDF74 /* CNIODarwin */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIODarwin; path = CNIODarwin.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CED859490C1400D8301C7B7C47AF813 /* md5-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "md5-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/md5-586.linux.x86.S"; sourceTree = ""; }; + 4CF33EE50785750CD3E0018658BA90C2 /* SelectorKqueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectorKqueue.swift; path = Sources/NIOPosix/SelectorKqueue.swift; sourceTree = ""; }; + 4D0589E851EBFC66CE9F5E2306DCD04B /* GRPCClientChannelHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCClientChannelHandler.swift; path = Sources/GRPC/GRPCClientChannelHandler.swift; sourceTree = ""; }; + 4D15B530C1C0371C492AD75F922A6708 /* ServerInterceptorStateMachine+Intercepting.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerInterceptorStateMachine+Intercepting.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Intercepting.swift"; sourceTree = ""; }; + 4D67F34D63E7BD7AF2FC9BB501EE6A7B /* SwiftNIOHTTP2.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHTTP2.release.xcconfig; sourceTree = ""; }; + 4D86098F5C60B52847DA9D83AC3F267C /* SDImageCodersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCodersManager.m; path = SDWebImage/Core/SDImageCodersManager.m; sourceTree = ""; }; + 4DDFBE971A9F36C3D422E7C892F6053A /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/lhash/internal.h; sourceTree = ""; }; + 4DEDCE51540072C4379CBA95F93B4CFD /* TextFormatEncodingOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatEncodingOptions.swift; path = Sources/SwiftProtobuf/TextFormatEncodingOptions.swift; sourceTree = ""; }; + 4E178514B54CC8064E94365ECF2BC5A0 /* CNIOBoringSSLShims.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOBoringSSLShims.debug.xcconfig; sourceTree = ""; }; + 4E1EB225DA4EBE4FEC26F11AD725CE18 /* SwiftyJSON.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftyJSON.modulemap; sourceTree = ""; }; + 4E525E05D489CE1A833F84421241958B /* ControlMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlMessage.swift; path = Sources/NIOPosix/ControlMessage.swift; sourceTree = ""; }; + 4F1891472D5631F287DFBCEDA49E9244 /* SwiftNIO.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIO.modulemap; sourceTree = ""; }; + 4F572B6F10A59CA774F9046854C9871D /* WSAStartup.c */ = {isa = PBXFileReference; includeInIndex = 1; name = WSAStartup.c; path = Sources/CNIOWindows/WSAStartup.c; sourceTree = ""; }; + 4FA167D30D3F8F8FEC7D9F31A0DA35DD /* bytes.c */ = {isa = PBXFileReference; includeInIndex = 1; name = bytes.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/bytes.c; sourceTree = ""; }; + 4FA191A1A6EA690A2394B507BC8A1151 /* Cadence-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Cadence-umbrella.h"; sourceTree = ""; }; + 4FA19DB464A583F8787040A400E72AF0 /* encrypted_client_hello.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = encrypted_client_hello.cc; path = Sources/CNIOBoringSSL/ssl/encrypted_client_hello.cc; sourceTree = ""; }; + 4FCAB0E52009B591A221259DB8DBCBAD /* ResponsePartContainer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponsePartContainer.swift; path = Sources/GRPC/ClientCalls/ResponsePartContainer.swift; sourceTree = ""; }; + 4FCEF474895FD1E1FEDC2B4A58A77FBA /* v3_utl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_utl.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_utl.c; sourceTree = ""; }; + 4FCF71CC854BB6C918AB124655B2CAA7 /* UIImage+MemoryCacheCost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MemoryCacheCost.h"; path = "SDWebImage/Core/UIImage+MemoryCacheCost.h"; sourceTree = ""; }; + 4FD4898DA7882FF64EA7BBF472DD0FEC /* CNIOBoringSSL_rsa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_rsa.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_rsa.h; sourceTree = ""; }; + 4FE70679AC03E0FC6318978897996424 /* HasRemoteSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HasRemoteSettings.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/HasRemoteSettings.swift; sourceTree = ""; }; + 501D740D00D470DD9CA9FE7C785F5EA5 /* Exponentiation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Exponentiation.swift; path = Sources/Exponentiation.swift; sourceTree = ""; }; + 5028C4DCE5B10736EA096F4B9353E47B /* kdf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = kdf.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/tls/kdf.c; sourceTree = ""; }; + 50620683857F7039ED3A222630547C53 /* NIOExtrasError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOExtrasError.swift; path = Sources/NIOExtras/NIOExtrasError.swift; sourceTree = ""; }; + 50A09330521F5E469A86D09B6C683AE0 /* dtls_method.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = dtls_method.cc; path = Sources/CNIOBoringSSL/ssl/dtls_method.cc; sourceTree = ""; }; + 50B2A679D31DCD596EEC5BA8D7AC26C4 /* CMAC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CMAC.swift; path = Sources/CryptoSwift/CMAC.swift; sourceTree = ""; }; + 50D5CED640DEE11BBAA33C46AB1A9DD7 /* ssl_file.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_file.cc; path = Sources/CNIOBoringSSL/ssl/ssl_file.cc; sourceTree = ""; }; + 515C37611AA1CAFD8AD95C60181AC7CC /* SwiftNIOConcurrencyHelpers-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOConcurrencyHelpers-prefix.pch"; sourceTree = ""; }; + 51684645291C96C48EFBEB63CE861D2A /* DynamicKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DynamicKey.swift; path = "Sources/FCL-SDK/Models/DynamicKey.swift"; sourceTree = ""; }; + 5183C8B06B2FB512F8EBB2BA65E84D34 /* rsaz-avx2.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "rsaz-avx2.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.mac.x86_64.S"; sourceTree = ""; }; + 51896288820E9AA5F8A6FAC96A977C74 /* Tweak.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Tweak.swift; path = Sources/secp256k1Swift/Tweak.swift; sourceTree = ""; }; + 51A9AE26BA8C9E100E1A049D203896B4 /* Hashable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Hashable.swift; path = Sources/Hashable.swift; sourceTree = ""; }; + 51B6893083FF0DBAB17C2B696B72CAB6 /* ByteBufferBIO.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ByteBufferBIO.swift; path = Sources/NIOSSL/ByteBufferBIO.swift; sourceTree = ""; }; + 51CA1BF1AEEC3CC946C5EA99D7A1F59B /* SwiftNIOTransportServices.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOTransportServices.release.xcconfig; sourceTree = ""; }; + 5208FE10C0E0EC040DE60A94FED96266 /* SDImageIOCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOCoder.h; path = SDWebImage/Core/SDImageIOCoder.h; sourceTree = ""; }; + 526ED2C5D0CAED69CCE1C91E3640C6F6 /* CFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CFB.swift; path = Sources/CryptoSwift/BlockMode/CFB.swift; sourceTree = ""; }; + 527DFFBB1677EE7C10B5FE3397F4B0F6 /* CallOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallOptions.swift; path = Sources/GRPC/CallOptions.swift; sourceTree = ""; }; + 52A707EE42FC57DC14D5F7A673496EFF /* x_x509a.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_x509a.c; path = Sources/CNIOBoringSSL/crypto/x509/x_x509a.c; sourceTree = ""; }; + 52A70AE9E6190A82C587A37FE9D8EB4B /* gRPC-Swiftp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "gRPC-Swiftp.debug.xcconfig"; sourceTree = ""; }; + 52DA9089BD259A8CD372B4BACC27F344 /* ResponseStatus.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseStatus.swift; path = "Sources/FCL-SDK/Models/ResponseStatus.swift"; sourceTree = ""; }; + 52FEBD0FB983B544EE473E3B708AF839 /* ec_key.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ec_key.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/ec_key.c; sourceTree = ""; }; + 5308041E257F28BE08E78CA91D4F0F9D /* SelectableEventLoop.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectableEventLoop.swift; path = Sources/NIOPosix/SelectableEventLoop.swift; sourceTree = ""; }; + 53392B8EDA78E9CBEDC1226D85F9EF59 /* p256.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p256.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256.c; sourceTree = ""; }; + 53589CFAB32460C48156336CE5EE883F /* Poly1305.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Poly1305.swift; path = Sources/CryptoSwift/Poly1305.swift; sourceTree = ""; }; + 536271B47921F5A15BD15A2481CEC19A /* v3_pcia.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_pcia.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_pcia.c; sourceTree = ""; }; + 536B9688B9200C123C4AC48652D36DAC /* Method.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Method.swift; path = Sources/Core/Models/Method.swift; sourceTree = ""; }; + 53CA88BB7B03385B102806F68F723F32 /* CompositeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompositeType.swift; path = Sources/Cadence/CType/CompositeType.swift; sourceTree = ""; }; + 53FF6032FB91E924B08894D202423B16 /* PCAPRingBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PCAPRingBuffer.swift; path = Sources/NIOExtras/PCAPRingBuffer.swift; sourceTree = ""; }; + 540D85AAA885F961771C8AE709B2E3BD /* vpaes-armv7.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-armv7.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.ios.arm.S"; sourceTree = ""; }; + 542C6DB9D65205F8DE75FE1C5ED21018 /* SignFlowMessageMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SignFlowMessageMethod.swift; path = Sources/Flow/Methods/SignFlowMessageMethod.swift; sourceTree = ""; }; + 5458105415C4E6D283CD649D22A132E7 /* QRScannerError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QRScannerError.swift; path = QRScanner/QRScannerError.swift; sourceTree = ""; }; + 547798325CC1938A46B860161C33CB10 /* pcy_data.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_data.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_data.c; sourceTree = ""; }; + 54906576365FC97D0EB18ED670E894F9 /* SDImageTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageTransformer.m; path = SDWebImage/Core/SDImageTransformer.m; sourceTree = ""; }; + 54947049A58743A0C0042261F0E344B4 /* Message+TextFormatAdditions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Message+TextFormatAdditions.swift"; path = "Sources/SwiftProtobuf/Message+TextFormatAdditions.swift"; sourceTree = ""; }; + 54B576AAD6BDC64DD3BBAC385FD520D7 /* WritePCAPHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WritePCAPHandler.swift; path = Sources/NIOExtras/WritePCAPHandler.swift; sourceTree = ""; }; + 54B8FDBB46F84E79D561233DE2CB2ECA /* pcy_tree.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_tree.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_tree.c; sourceTree = ""; }; + 54DBDC1C254BCB0849C37FB96F917A5E /* _NIODataStructures-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "_NIODataStructures-Info.plist"; sourceTree = ""; }; + 54DCBB006E801E2E59D8295DE6FBD486 /* CNIOBoringSSL_obj_mac.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_obj_mac.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_obj_mac.h; sourceTree = ""; }; + 54EB52F4DE857E6CA5BC27C60BFAA047 /* Codable+ByteBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Codable+ByteBuffer.swift"; path = "Sources/NIOFoundationCompat/Codable+ByteBuffer.swift"; sourceTree = ""; }; + 55323FF6763FDF0FD55A710B19CA1549 /* BSDSocketAPI.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BSDSocketAPI.swift; path = Sources/NIOCore/BSDSocketAPI.swift; sourceTree = ""; }; + 553CF428A3057584E0E91F727869C3B9 /* CNIOBoringSSL_err.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_err.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_err.h; sourceTree = ""; }; + 554A30FAAA98F5650C4DFD0A9A48D30F /* GRPCServiceDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCServiceDescription.swift; path = Sources/GRPC/GRPCServiceDescription.swift; sourceTree = ""; }; + 5579F459567A501C9ABAD77F662B04E3 /* s3_pkt.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = s3_pkt.cc; path = Sources/CNIOBoringSSL/ssl/s3_pkt.cc; sourceTree = ""; }; + 557E8F163489D4D5A76F3540372DF512 /* ecdh_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ecdh_extra.c; path = Sources/CNIOBoringSSL/crypto/ecdh_extra/ecdh_extra.c; sourceTree = ""; }; + 55A65A9AAE2CB4259669C7F1CD52FC22 /* HasLocalSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HasLocalSettings.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/HasLocalSettings.swift; sourceTree = ""; }; + 561797F07D64EEC2278F2C20D284ABC4 /* SwiftNIOHPACK-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHPACK-umbrella.h"; sourceTree = ""; }; + 5626242BB7146F77738520DFAE216A5A /* ControlFrameBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlFrameBuffer.swift; path = "Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift"; sourceTree = ""; }; + 5632E69283B9EC57F1BD922821CC8E35 /* ByteBuffer-multi-int.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-multi-int.swift"; path = "Sources/NIOCore/ByteBuffer-multi-int.swift"; sourceTree = ""; }; + 56707F1F35E9FA8B9C5BC03F1F30820D /* ecmult_compute_table_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_compute_table_impl.h; path = src/ecmult_compute_table_impl.h; sourceTree = ""; }; + 567DAE15E7F0276F6621B62348EBBFD5 /* ByteBuffer-int.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-int.swift"; path = "Sources/NIOCore/ByteBuffer-int.swift"; sourceTree = ""; }; + 567FD469C35653B294CC5F47C54BAE32 /* StreamLender.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamLender.swift; path = Sources/GRPC/ConnectionPool/StreamLender.swift; sourceTree = ""; }; + 56D8359142F5F79A1F73766AFD5D69E8 /* pem_pk8.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_pk8.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_pk8.c; sourceTree = ""; }; + 56EC97BCE868A9664BDC8893A3962076 /* CNIODarwin-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIODarwin-prefix.pch"; sourceTree = ""; }; + 56ECAFB119E54C34869DCE1A260D278F /* HuffmanCoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HuffmanCoding.swift; path = Sources/NIOHPACK/HuffmanCoding.swift; sourceTree = ""; }; + 573642D12978379632CF4F8FADF0BB41 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/dh/internal.h; sourceTree = ""; }; + 576AC85311DDBD08D126184FB7191BED /* Generics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generics.swift; path = Sources/CryptoSwift/Generics.swift; sourceTree = ""; }; + 576E84427AEC0E7BD5C7523E06B64FB3 /* extensions.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = extensions.cc; path = Sources/CNIOBoringSSL/ssl/extensions.cc; sourceTree = ""; }; + 579FF490F79F59658DAF13F0E591B4E8 /* CNIOLinux.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOLinux.debug.xcconfig; sourceTree = ""; }; + 57A1FEA4E83370409F5570F73F0B9838 /* Identifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identifier.swift; path = Sources/FlowSDK/Models/Identifier.swift; sourceTree = ""; }; + 57AE728B2D53D0CB3F47000F93780F51 /* d1_lib.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = d1_lib.cc; path = Sources/CNIOBoringSSL/ssl/d1_lib.cc; sourceTree = ""; }; + 57E3DF7A1DE405E528197F98001D7A73 /* PopupDialogButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogButton.swift; path = PopupDialog/Classes/PopupDialogButton.swift; sourceTree = ""; }; + 57EDA73702499167446611B4D790CFAE /* FCL-SDK.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "FCL-SDK.modulemap"; sourceTree = ""; }; + 57F372EEBB66DB5339D666EE9378C337 /* SwiftNIOTLS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOTLS.debug.xcconfig; sourceTree = ""; }; + 580E2EBBFE458EC3F736133677BAFD9E /* cipher_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cipher_extra.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/cipher_extra.c; sourceTree = ""; }; + 581957A460F05E4ACD7377112F415EEA /* Array+BoundsCheck.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+BoundsCheck.swift"; path = "Sources/GRPC/Array+BoundsCheck.swift"; sourceTree = ""; }; + 581D60585908DAA6033C9E21C8ADF092 /* NIOLengthFieldBitLength.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOLengthFieldBitLength.swift; path = Sources/NIOExtras/NIOLengthFieldBitLength.swift; sourceTree = ""; }; + 58564B21CC6075F988564B3467107203 /* x509_trs.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_trs.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_trs.c; sourceTree = ""; }; + 5863D402126A6AF32F4B895202656681 /* SendingHeadersState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingHeadersState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingHeadersState.swift; sourceTree = ""; }; + 589D2F093BEE044995B014C077990A57 /* StreamDecryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamDecryptor.swift; path = Sources/CryptoSwift/StreamDecryptor.swift; sourceTree = ""; }; + 58E1897D1BAEEDBE602D40F24F560BF2 /* String Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String Conversion.swift"; path = "Sources/CryptoSwift/CS_BigInt/String Conversion.swift"; sourceTree = ""; }; + 592ECFA0202DC3D72A69C99AF5F1693C /* Pods-fanexTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-fanexTests-umbrella.h"; sourceTree = ""; }; + 596EDC10FB2C816516BF38E8A47E49E0 /* BloctoSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BloctoSDK.release.xcconfig; sourceTree = ""; }; + 597A8C58E74C74F58474999B4A26F7E2 /* BigInt.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = BigInt.modulemap; sourceTree = ""; }; + 598247BC22A408C1AC2B3DB8892F821A /* lhash.c */ = {isa = PBXFileReference; includeInIndex = 1; name = lhash.c; path = Sources/CNIOBoringSSL/crypto/lhash/lhash.c; sourceTree = ""; }; + 59DEF33DF5D0533B2F230F950425D679 /* SDWebImageDownloaderResponseModifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderResponseModifier.h; path = SDWebImage/Core/SDWebImageDownloaderResponseModifier.h; sourceTree = ""; }; + 5A08D0D28E808A53F9752502B7AB6BFE /* SDImageCacheConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCacheConfig.m; path = SDWebImage/Core/SDImageCacheConfig.m; sourceTree = ""; }; + 5A09CDE39737C3CDDB81BF9732C91CFC /* x509_set.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_set.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_set.c; sourceTree = ""; }; + 5A26731C91E6BD1C0ADEFC3D162CB1B6 /* EventLoopFuture.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventLoopFuture.swift; path = Sources/NIOCore/EventLoopFuture.swift; sourceTree = ""; }; + 5A36BE9C53E671A694FC4006041B0247 /* Varint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Varint.swift; path = Sources/SwiftProtobuf/Varint.swift; sourceTree = ""; }; + 5A4F06961A91338037FDCD870FD3A52E /* stack.c */ = {isa = PBXFileReference; includeInIndex = 1; name = stack.c; path = Sources/CNIOBoringSSL/crypto/stack/stack.c; sourceTree = ""; }; + 5A8344CF6C33D499F30836C9EBCE1F20 /* ecdh.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ecdh.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ecdh/ecdh.c; sourceTree = ""; }; + 5A903B307C82702D8099A1F1C7C0697C /* Subtraction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Subtraction.swift; path = Sources/Subtraction.swift; sourceTree = ""; }; + 5AAAE61AA716A70C5261F8FA6A98E4C9 /* SocketAddresses.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SocketAddresses.swift; path = Sources/NIOCore/SocketAddresses.swift; sourceTree = ""; }; + 5AAFC99C5990321A2051AC7826DCE3C6 /* CNIOBoringSSL_ec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ec.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ec.h; sourceTree = ""; }; + 5ABFF64DD17238FD146150F9D6C09010 /* pair.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pair.c; path = Sources/CNIOBoringSSL/crypto/bio/pair.c; sourceTree = ""; }; + 5ACBD31AC425A93986D8DA5597F7FE80 /* User.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = User.swift; path = "Sources/FCL-SDK/User/User.swift"; sourceTree = ""; }; + 5B030C622B398C956EE39FAAA7A68289 /* CNIOBoringSSL_tls1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_tls1.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_tls1.h; sourceTree = ""; }; + 5B19ACA6BA4F4AFDFECA7E476DF3D949 /* Google_Protobuf_Any+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Any+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift"; sourceTree = ""; }; + 5B323BAC1EC365CD5A5AFC329449DF3C /* CGRPCZlibp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CGRPCZlibp-umbrella.h"; sourceTree = ""; }; + 5B69F35BDFA7E3985C0BF5A43101532E /* SwiftNIOTransportServices-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOTransportServices-umbrella.h"; sourceTree = ""; }; + 5B7F6D7D0E5BCC5EAEFF300B35435A85 /* Message+JSONArrayAdditions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Message+JSONArrayAdditions.swift"; path = "Sources/SwiftProtobuf/Message+JSONArrayAdditions.swift"; sourceTree = ""; }; + 5B9A298482E75869E1ED00F8077386B3 /* gRPC-Swiftp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "gRPC-Swiftp-dummy.m"; sourceTree = ""; }; + 5BA597A99CDB1A93C02D695E01E790C6 /* RequestBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestBuilder.swift; path = "Sources/FCL-SDK/Utilities/RequestBuilder.swift"; sourceTree = ""; }; + 5BBCF711E54A49A7662966284B6C692B /* Version.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Version.swift; path = Sources/SwiftProtobuf/Version.swift; sourceTree = ""; }; + 5BD06CC435D05FAF9356A9E55E340DAF /* ByteBuffer-aux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-aux.swift"; path = "Sources/NIOCore/ByteBuffer-aux.swift"; sourceTree = ""; }; + 5BE9BF7F0B0096EDA17340602CCF5AE9 /* CGRPCZlibp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CGRPCZlibp.debug.xcconfig; sourceTree = ""; }; + 5BEC1870D5E8752AFBADC18D9E910946 /* SDImageAssetManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAssetManager.h; path = SDWebImage/Private/SDImageAssetManager.h; sourceTree = ""; }; + 5BF0600E7181F289680078246C28D8D7 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; }; + 5BF593AB41A0AF0DEFBF863C4A465B86 /* CTR.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CTR.swift; path = Sources/CryptoSwift/BlockMode/CTR.swift; sourceTree = ""; }; + 5BF8E20702878FA358112FB44B023028 /* StateMachineResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StateMachineResult.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/StateMachineResult.swift; sourceTree = ""; }; + 5BF8FE387A24324DB3636F112BFEA0ED /* Codable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Codable.swift; path = Sources/Codable.swift; sourceTree = ""; }; + 5BF92DA07FF2BFCD193217F90EDA6DF0 /* c_nio_http_parser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = c_nio_http_parser.h; path = Sources/CNIOHTTPParser/include/c_nio_http_parser.h; sourceTree = ""; }; + 5C046B5BB46DDFF18ADD409B49436BD1 /* v3_prn.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_prn.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_prn.c; sourceTree = ""; }; + 5C2F560F2FE25185B92D32A7AC9F0BE4 /* StaticTypeValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StaticTypeValue.swift; path = Sources/Cadence/StaticTypeValue.swift; sourceTree = ""; }; + 5C5DEEA37AFD93D55687831DE94BEE7E /* secp256k1Swift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "secp256k1Swift-prefix.pch"; sourceTree = ""; }; + 5C6FFAA21FABF954FA624913576251BF /* Logging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logging.swift; path = Sources/Logging/Logging.swift; sourceTree = ""; }; + 5CA1003700742FCF9A856FE54DABB5BD /* field.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field.h; path = src/field.h; sourceTree = ""; }; + 5CA8A516E5D26CFC3E0BBE41525B3EC1 /* pkcs7_x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pkcs7_x509.c; path = Sources/CNIOBoringSSL/crypto/pkcs7/pkcs7_x509.c; sourceTree = ""; }; + 5CA9BF98A613A23FD0E1127D868665C8 /* Google_Protobuf_FieldMask+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_FieldMask+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift"; sourceTree = ""; }; + 5CC4FBE5CACD2CAB0301E49D7AC65B92 /* SDWebImageError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageError.h; path = SDWebImage/Core/SDWebImageError.h; sourceTree = ""; }; + 5D1C37175511A3E8DE33E96132632A6B /* SNIHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SNIHandler.swift; path = Sources/NIOTLS/SNIHandler.swift; sourceTree = ""; }; + 5D34821E2734FD3FD949F1EA95A2C744 /* PopupDialog+Keyboard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PopupDialog+Keyboard.swift"; path = "PopupDialog/Classes/PopupDialog+Keyboard.swift"; sourceTree = ""; }; + 5D62241984225CE5EAC16D48BC371AB8 /* v3_akeya.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_akeya.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_akeya.c; sourceTree = ""; }; + 5DA367665CC9BC1C69B04890D3494B39 /* field_mask.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = field_mask.pb.swift; path = Sources/SwiftProtobuf/field_mask.pb.swift; sourceTree = ""; }; + 5E05C5D12EF55A7458060ADF19DA4B30 /* FixedLengthFrameDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FixedLengthFrameDecoder.swift; path = Sources/NIOExtras/FixedLengthFrameDecoder.swift; sourceTree = ""; }; + 5E0721EF9A72F01319DB08771946208C /* WireFormat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WireFormat.swift; path = Sources/SwiftProtobuf/WireFormat.swift; sourceTree = ""; }; + 5E08C20860569C87EE2F3AA6F06E5146 /* UInt16+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt16+Extension.swift"; path = "Sources/CryptoSwift/UInt16+Extension.swift"; sourceTree = ""; }; + 5E1B86F03FEB77983C03E9095597B3C2 /* JSONSerialization+ByteBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "JSONSerialization+ByteBuffer.swift"; path = "Sources/NIOFoundationCompat/JSONSerialization+ByteBuffer.swift"; sourceTree = ""; }; + 5E7EA222E0C14D26E93668B34B40EC24 /* x_spki.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_spki.c; path = Sources/CNIOBoringSSL/crypto/x509/x_spki.c; sourceTree = ""; }; + 5E982D315A4CB75E8F15068B30779C7C /* SwiftNIO */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIO; path = NIO.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E9A160FE84EE321E41281FB995E30C2 /* TransitionAnimations.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransitionAnimations.swift; path = PopupDialog/Classes/TransitionAnimations.swift; sourceTree = ""; }; + 5EA5D5F30C38E89044BB740F26EE88DD /* f_int.c */ = {isa = PBXFileReference; includeInIndex = 1; name = f_int.c; path = Sources/CNIOBoringSSL/crypto/asn1/f_int.c; sourceTree = ""; }; + 5EA8C52B80490B71F1A647CD6800483C /* ServerHandlerStateMachine+Handling.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerHandlerStateMachine+Handling.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Handling.swift"; sourceTree = ""; }; + 5EBBC38E8B4526897E288AC3935AAA62 /* Data+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data+Extension.swift"; path = "Sources/CryptoSwift/Foundation/Data+Extension.swift"; sourceTree = ""; }; + 5EBBCBD31CFEA671C4DC08DA393EF1BA /* CNIOBoringSSL_ecdsa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ecdsa.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdsa.h; sourceTree = ""; }; + 5EE9230B1CD0D146600F41FD1C33A2A1 /* AES+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "AES+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/AES+Foundation.swift"; sourceTree = ""; }; + 5EEF1A795EC83D9C06CA29B76F0DCA23 /* CNIOHTTPParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOHTTPParser.h; path = Sources/CNIOHTTPParser/include/CNIOHTTPParser.h; sourceTree = ""; }; + 5F0595717F923571F063D4697772B8DD /* CNIOBoringSSL_md5.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_md5.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_md5.h; sourceTree = ""; }; + 5F492BAA38208825BA9D871CE8E97BFC /* v3_bitst.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_bitst.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_bitst.c; sourceTree = ""; }; + 5FC12B4AAB7E6AE3C249440811136A9B /* JSONEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONEncoder.swift; path = Sources/SwiftProtobuf/JSONEncoder.swift; sourceTree = ""; }; + 5FCEFA31AF70F373E509ED8E34154C05 /* SVProgressAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressAnimatedView.h; path = SVProgressHUD/SVProgressAnimatedView.h; sourceTree = ""; }; + 6004A2299268FB7700C904D7E47177B4 /* GRPCHeaderName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCHeaderName.swift; path = Sources/GRPC/GRPCHeaderName.swift; sourceTree = ""; }; + 603DB6327F928979DB143EDB3B2E94FC /* ec_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ec_asn1.c; path = Sources/CNIOBoringSSL/crypto/ec_extra/ec_asn1.c; sourceTree = ""; }; + 603EC9C5ECD9FEB15F1FD72336FDB40B /* CNIODarwin-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIODarwin-Info.plist"; sourceTree = ""; }; + 606ED2AF7D78BF7428003D150AEA1570 /* SelectorEpoll.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectorEpoll.swift; path = Sources/NIOPosix/SelectorEpoll.swift; sourceTree = ""; }; + 606F713E4CA5C57D75EDFA2ABEDBCA02 /* FlowMethodContentType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlowMethodContentType.swift; path = Sources/Flow/Models/FlowMethodContentType.swift; sourceTree = ""; }; + 6081F7CA47E05CCAB868E82D6A8D6A3E /* v3_info.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_info.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_info.c; sourceTree = ""; }; + 608F623D3B08BA42C8FEC503EB0A3202 /* Checksum.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Checksum.swift; path = Sources/CryptoSwift/Checksum.swift; sourceTree = ""; }; + 60B1418F069305E2B7F2CA9ED5AA56C3 /* BundleExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BundleExtension.swift; path = Sources/Core/Extensions/BundleExtension.swift; sourceTree = ""; }; + 60DA5A9E77C90FD5E3A6BECEBA97BABF /* HappyEyeballs.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HappyEyeballs.swift; path = Sources/NIOPosix/HappyEyeballs.swift; sourceTree = ""; }; + 6116A87F1DC0388E72BF1318376A9A8D /* CNIOBoringSSL_aead.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_aead.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_aead.h; sourceTree = ""; }; + 61329CB4B0AFAB6D6A0714878415F6E3 /* JSONScanner.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONScanner.swift; path = Sources/SwiftProtobuf/JSONScanner.swift; sourceTree = ""; }; + 6164625CCEC1B1A4714B2CAE4C9E60C8 /* CNIOBoringSSL_pkcs7.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_pkcs7.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs7.h; sourceTree = ""; }; + 6180C78B00D01DE7E8304F0223D7EC39 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/pkcs8/internal.h; sourceTree = ""; }; + 61B3DA25CFEB729C2DB261ACD2CCE46F /* Pods-fanex-fanexUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanex-fanexUITests.release.xcconfig"; sourceTree = ""; }; + 61B777F35BCB94CB5F2FBDAAD92939D1 /* x_exten.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_exten.c; path = Sources/CNIOBoringSSL/crypto/x509/x_exten.c; sourceTree = ""; }; + 61C2F8ACCB538BD6193D9C52D140644F /* HTTP2Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2Error.swift; path = Sources/NIOHTTP2/HTTP2Error.swift; sourceTree = ""; }; + 61D33AA2633CE5706C3EE91FBDCC3D29 /* block_seal.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = block_seal.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/block_seal.pb.swift; sourceTree = ""; }; + 626D6A6FBA3C4456357F4F9D36C475F7 /* ssl_privkey.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_privkey.cc; path = Sources/CNIOBoringSSL/ssl/ssl_privkey.cc; sourceTree = ""; }; + 627FAE45BAEC0F2C05EAB84C44C02CD9 /* CNIOHTTPParser-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOHTTPParser-prefix.pch"; sourceTree = ""; }; + 629A52E1E4CA932DAE68FF73DCA52081 /* HTTP2ErrorCode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ErrorCode.swift; path = Sources/NIOHTTP2/HTTP2ErrorCode.swift; sourceTree = ""; }; + 62EC0F8FA6CDAD507979070A6DDC9CA9 /* CNIOBoringSSL_base64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_base64.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_base64.h; sourceTree = ""; }; + 63113E7737284DD30A6259682D4CEA67 /* p256-nistz-table.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "p256-nistz-table.h"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz-table.h"; sourceTree = ""; }; + 633C8C447C3FB1D4948A5BC065F355D6 /* HTTPServerUpgradeHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPServerUpgradeHandler.swift; path = Sources/NIOHTTP1/HTTPServerUpgradeHandler.swift; sourceTree = ""; }; + 634AC0A70874A63C45F2B35E58DB4BDC /* Channel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Channel.swift; path = Sources/NIOCore/Channel.swift; sourceTree = ""; }; + 63647EC3A1665A41F433DFD09501F254 /* DynamicBlurView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DynamicBlurView-umbrella.h"; sourceTree = ""; }; + 63A1C84C64764931184EA5A3B829CB71 /* p_dsa_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_dsa_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/p_dsa_asn1.c; sourceTree = ""; }; + 63B54017CE0B0CA0650D0731FB5F9950 /* random.c */ = {isa = PBXFileReference; includeInIndex = 1; name = random.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/random.c; sourceTree = ""; }; + 63F64C7779258BC4F72C9B5527B4AD9A /* SDImageIOCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOCoder.m; path = SDWebImage/Core/SDImageIOCoder.m; sourceTree = ""; }; + 64003FC3B36480A559C1E01B4E5180DE /* Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Linux.swift; path = Sources/NIOCore/Linux.swift; sourceTree = ""; }; + 64117CF438B850CA195E0F38D6F76C7F /* e_aes.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_aes.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/e_aes.c; sourceTree = ""; }; + 6454772CDFC04EFE6E1F5AD38FE7E3DD /* secp256k1Wrapper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = secp256k1Wrapper.release.xcconfig; sourceTree = ""; }; + 64554F810325123E1D8A563813465BA2 /* TransitionAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransitionAnimator.swift; path = PopupDialog/Classes/TransitionAnimator.swift; sourceTree = ""; }; + 649702361E788AB9B1259095141BB33B /* CNIOAtomics-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOAtomics-umbrella.h"; sourceTree = ""; }; + 64CC2B8BD5A968C8ECE43D8CCE8B0112 /* TransactionFeePayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransactionFeePayer.swift; path = "Sources/FCL-SDK/Models/TransactionFeePayer.swift"; sourceTree = ""; }; + 64E10E4FD6E48A59E6866C41F1A27D40 /* SwiftNIOPosix-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOPosix-Info.plist"; sourceTree = ""; }; + 6538FD01C920493BE564E5F79BB1EDC3 /* Thread.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Thread.swift; path = Sources/NIOPosix/Thread.swift; sourceTree = ""; }; + 65403732FF94C6E473686DD943B25626 /* PooledChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PooledChannel.swift; path = Sources/GRPC/ConnectionPool/PooledChannel.swift; sourceTree = ""; }; + 6578517D7D69BDBEBDD8E47022CCBC81 /* Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Linux.swift; path = Sources/NIOPosix/Linux.swift; sourceTree = ""; }; + 6584B64DEE85ED6A8185CB5C7BE2B5DC /* CNIOBoringSSL_cipher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_cipher.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_cipher.h; sourceTree = ""; }; + 65ABA6E8006B92B26C68AB3678AD43EC /* Serialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Serialization.swift; path = Sources/GRPC/Serialization.swift; sourceTree = ""; }; + 66077917DB54CBB0DFB565612EE929C2 /* CNIOBoringSSL_asn1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_asn1.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1.h; sourceTree = ""; }; + 660DC8D7B5079C83E6BF3CE126E828E2 /* LengthFieldBasedFrameDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LengthFieldBasedFrameDecoder.swift; path = Sources/NIOExtras/LengthFieldBasedFrameDecoder.swift; sourceTree = ""; }; + 66B1F6A1B8718BCBF93B8CF2335563EC /* Pods-fanex-fanexUITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanex-fanexUITests-acknowledgements.plist"; sourceTree = ""; }; + 66C930E2F1869C8A260040906EDE19CF /* BigInt-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "BigInt-Info.plist"; sourceTree = ""; }; + 66E55B569C5EE21BB5AB9F6E5D66EB77 /* testrand.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = testrand.h; path = src/testrand.h; sourceTree = ""; }; + 66FDC10C92DFE9FA6A8021029EE54A1E /* SendingPushPromiseState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingPushPromiseState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingPushPromiseState.swift; sourceTree = ""; }; + 670C456D4FCFEF9092396FF161CA4A3E /* Updatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Updatable.swift; path = Sources/CryptoSwift/Updatable.swift; sourceTree = ""; }; + 672487A4A912ADC41F78EDCDA947B52C /* SDWebImageOptionsProcessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageOptionsProcessor.h; path = SDWebImage/Core/SDWebImageOptionsProcessor.h; sourceTree = ""; }; + 672C34D301D2789BD465129E931DF530 /* algorithm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = algorithm.c; path = Sources/CNIOBoringSSL/crypto/x509/algorithm.c; sourceTree = ""; }; + 673CA60B9FF9D56D5AEAFAD4E2D7B368 /* SwiftNIOConcurrencyHelpers */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOConcurrencyHelpers; path = NIOConcurrencyHelpers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 673FA8BD54C5D615B1D6EB9067EF13E8 /* NIOAny.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOAny.swift; path = Sources/NIOCore/NIOAny.swift; sourceTree = ""; }; + 674C78CA48A7FE09DFCE8F6C367C6AD9 /* SystemCallHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SystemCallHelpers.swift; path = Sources/NIOCore/SystemCallHelpers.swift; sourceTree = ""; }; + 6763E9CF3A1C3076164F2C922B83431C /* pmbtoken.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pmbtoken.c; path = Sources/CNIOBoringSSL/crypto/trust_token/pmbtoken.c; sourceTree = ""; }; + 6767891787016D4050CDB4C413106873 /* CNIOWindows-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOWindows-umbrella.h"; sourceTree = ""; }; + 676876EDFF467DBF93ABF12E82EDD8AD /* UIImage+ExtendedCacheData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ExtendedCacheData.m"; path = "SDWebImage/Core/UIImage+ExtendedCacheData.m"; sourceTree = ""; }; + 67845E98E019276FA82E0785DDDA884C /* GRPCPayload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCPayload.swift; path = Sources/GRPC/GRPCPayload.swift; sourceTree = ""; }; + 680E3D81317929F61038DF8CE7A8290C /* AES.Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.Cryptors.swift; path = Sources/CryptoSwift/AES.Cryptors.swift; sourceTree = ""; }; + 681CE7F242DD1F94F884B8952827D0C4 /* scratch_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scratch_impl.h; path = src/scratch_impl.h; sourceTree = ""; }; + 682582E511D4CFCB4AC801EC5E6C7A42 /* PipeChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PipeChannel.swift; path = Sources/NIOPosix/PipeChannel.swift; sourceTree = ""; }; + 6834A81C3A0BC11254126CF44CF45C6B /* String Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String Conversion.swift"; path = "Sources/String Conversion.swift"; sourceTree = ""; }; + 683C3A9077D7AFBD12A2AB115EED400A /* gRPC-Swiftp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "gRPC-Swiftp.release.xcconfig"; sourceTree = ""; }; + 68729B16F225DACE71B8D33EB9ACB558 /* pcy_lib.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_lib.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_lib.c; sourceTree = ""; }; + 6882A01C332B342BCEAFA7A90B78BB4E /* gcm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = gcm.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm.c; sourceTree = ""; }; + 688410218F9477BF03CC02672B5D29E3 /* StringExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StringExtension.swift; path = Sources/Cadence/Extensions/StringExtension.swift; sourceTree = ""; }; + 688BEA52472D776443869462E1284ACB /* Hashable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Hashable.swift; path = Sources/CryptoSwift/CS_BigInt/Hashable.swift; sourceTree = ""; }; + 689ED28F1F4352CF81582818D9F4EB64 /* secp256k1_ecdh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1_ecdh.h; path = include/secp256k1_ecdh.h; sourceTree = ""; }; + 68CEBDA6647D2970C777AF684FD248ED /* a_sign.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_sign.c; path = Sources/CNIOBoringSSL/crypto/x509/a_sign.c; sourceTree = ""; }; + 68D1CC3A9F718D0F87F05426AC681B0A /* SDImageCacheConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCacheConfig.h; path = SDWebImage/Core/SDImageCacheConfig.h; sourceTree = ""; }; + 68E783BE195DDBA1CB7656608D41E62B /* secp256k1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1.h; path = include/secp256k1.h; sourceTree = ""; }; + 693C7FDB3C518480EA1B432ED4461DF3 /* Message+AnyAdditions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Message+AnyAdditions.swift"; path = "Sources/SwiftProtobuf/Message+AnyAdditions.swift"; sourceTree = ""; }; + 6987D26A615917E6A7DB77F32FD14EC2 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/trust_token/internal.h; sourceTree = ""; }; + 699361D574BEBE539C51757D679B1819 /* SwiftNIOPosix.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOPosix.release.xcconfig; sourceTree = ""; }; + 699A3089D1F3A798E655A7A25AAEF23E /* ServiceDataType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceDataType.swift; path = "Sources/FCL-SDK/User/Service/ServiceDataType.swift"; sourceTree = ""; }; + 699AA7624510F132CCCA43004E29AF3F /* x_x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_x509.c; path = Sources/CNIOBoringSSL/crypto/x509/x_x509.c; sourceTree = ""; }; + 699ED647324E1C44560B50FED10A26F6 /* SDWebImageDefine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDefine.m; path = SDWebImage/Core/SDWebImageDefine.m; sourceTree = ""; }; + 69A3F68D52609F06530707E690E292C7 /* CryptoSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-umbrella.h"; sourceTree = ""; }; + 69DE0F1E76B17106976985E62F2E7132 /* GRPCStatus.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCStatus.swift; path = Sources/GRPC/GRPCStatus.swift; sourceTree = ""; }; + 69ED75F0B2316A6688A81A6A1728E93A /* PopupDialog-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PopupDialog-Info.plist"; sourceTree = ""; }; + 69F18166D6FA989A07C1BF2EDE3CD089 /* ServiceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceType.swift; path = "Sources/FCL-SDK/User/Service/ServiceType.swift"; sourceTree = ""; }; + 6A210AFF28F0967DF1250DA5D6F30295 /* CNIOBoringSSL_ssl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ssl.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl.h; sourceTree = ""; }; + 6A4BFD29442A54F99DEFEAD99DCE208F /* pkcs8_x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pkcs8_x509.c; path = Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8_x509.c; sourceTree = ""; }; + 6A6186673700ED88DEB1E9C017272782 /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVIndefiniteAnimatedView.h; path = SVProgressHUD/SVIndefiniteAnimatedView.h; sourceTree = ""; }; + 6A85E08DFECD52E6D6CD9D01D71CEC16 /* x509spki.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509spki.c; path = Sources/CNIOBoringSSL/crypto/x509/x509spki.c; sourceTree = ""; }; + 6AB54BC674F9B26B020C03ABD8B8A0C8 /* FlowSDK-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FlowSDK-Info.plist"; sourceTree = ""; }; + 6AB5AC65D86ECBEDFAD2CF7EF32DD974 /* ClientTransport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientTransport.swift; path = Sources/GRPC/Interceptor/ClientTransport.swift; sourceTree = ""; }; + 6B0606176305FD0DDFCA2EFCE02CBE4C /* time_support.c */ = {isa = PBXFileReference; includeInIndex = 1; name = time_support.c; path = Sources/CNIOBoringSSL/crypto/asn1/time_support.c; sourceTree = ""; }; + 6B295C96E65F578984871707C9373DB8 /* SafeCompare.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SafeCompare.swift; path = Sources/secp256k1Swift/SafeCompare.swift; sourceTree = ""; }; + 6B4B7EBE7A82D97D5576D1E05A39B6B5 /* SwiftNIOCore-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOCore-umbrella.h"; sourceTree = ""; }; + 6B92469E0E33F66124F5C1D3EB3EC364 /* EventLoop+Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "EventLoop+Deprecated.swift"; path = "Sources/NIOCore/EventLoop+Deprecated.swift"; sourceTree = ""; }; + 6BFF036C07C43EDDC9044F5A484038AB /* ssl_versions.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_versions.cc; path = Sources/CNIOBoringSSL/ssl/ssl_versions.cc; sourceTree = ""; }; + 6C149DBAE7FF996B43634962F24F3C27 /* asn1_gen.c */ = {isa = PBXFileReference; includeInIndex = 1; name = asn1_gen.c; path = Sources/CNIOBoringSSL/crypto/x509/asn1_gen.c; sourceTree = ""; }; + 6C1D5CAB4128265FE20FCEEBB65A1CA9 /* pool.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pool.c; path = Sources/CNIOBoringSSL/crypto/pool/pool.c; sourceTree = ""; }; + 6C79792E9AEF2232DE54E9A4C4C4C2F2 /* BloctoSDK-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BloctoSDK-prefix.pch"; sourceTree = ""; }; + 6C982DE04B6EBE96FCA55C8F5E6BA4D3 /* GRPCIdleHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCIdleHandler.swift; path = Sources/GRPC/GRPCIdleHandler.swift; sourceTree = ""; }; + 6CB4E7BB0CF0584BAD6F97344F04BCD9 /* CNIOBoringSSL_lhash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_lhash.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_lhash.h; sourceTree = ""; }; + 6CC717C5651767D375F458FC34B8A566 /* x_pkey.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_pkey.c; path = Sources/CNIOBoringSSL/crypto/x509/x_pkey.c; sourceTree = ""; }; + 6CCD93EFB03582F1106146024982D6B3 /* PopupDialog.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialog.swift; path = PopupDialog/Classes/PopupDialog.swift; sourceTree = ""; }; + 6D040D1A67C3DBE3C11EB6FBC61B8141 /* SwiftNIOFoundationCompat */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOFoundationCompat; path = NIOFoundationCompat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D14D9882811FC95C4A52156FF3A0722 /* LocallyQuiescingState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LocallyQuiescingState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/LocallyQuiescingState.swift; sourceTree = ""; }; + 6D1A0FA4B06F24C3206B6E8ECC38062E /* AuthenticateMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticateMethod.swift; path = Sources/Flow/Methods/AuthenticateMethod.swift; sourceTree = ""; }; + 6D34289681192F83F7D7E501404DA0C7 /* gRPC-Swiftp-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "gRPC-Swiftp-prefix.pch"; sourceTree = ""; }; + 6D3750C70FE753271823ACC07BA2AF57 /* SDImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCache.h; path = SDWebImage/Core/SDImageCache.h; sourceTree = ""; }; + 6D38132414C08347AD7B4BB2AC16B6D2 /* CNIOBoringSSL_bio.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_bio.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_bio.h; sourceTree = ""; }; + 6DAFF32C7F2CEA1A995EFBFA1B389B1C /* Stopwatch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Stopwatch.swift; path = Sources/GRPC/Stopwatch.swift; sourceTree = ""; }; + 6DB89C0E4A195E152E33D752C7ACFC25 /* ecmult_const_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_const_impl.h; path = src/ecmult_const_impl.h; sourceTree = ""; }; + 6DBCEA097C38D41A4D4C7202B5074C77 /* SelectorUring.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectorUring.swift; path = Sources/NIOPosix/SelectorUring.swift; sourceTree = ""; }; + 6DBD255DD3EFE8B8F18EC77884784289 /* AddressedEnvelope.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AddressedEnvelope.swift; path = Sources/NIOCore/AddressedEnvelope.swift; sourceTree = ""; }; + 6DBEB0B449511C620D93E016D0AD9C3F /* Logging-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Logging-Info.plist"; sourceTree = ""; }; + 6DCDD34AB556F1F49D46C07F5D1439A3 /* SDMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDMemoryCache.m; path = SDWebImage/Core/SDMemoryCache.m; sourceTree = ""; }; + 6DD8DDCB1D614AFA22177C03F50B1D59 /* FlowSDK.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FlowSDK.modulemap; sourceTree = ""; }; + 6DF2315104F0841E7D1F426ECF1DF5BA /* conf_def.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = conf_def.h; path = Sources/CNIOBoringSSL/crypto/conf/conf_def.h; sourceTree = ""; }; + 6DFF907064B630709019AC49B093B5D5 /* UIImage+Transform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Transform.h"; path = "SDWebImage/Core/UIImage+Transform.h"; sourceTree = ""; }; + 6E9A9BB5C857744B10FE5E40FD860C03 /* Pods-fanex-fanexUITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-fanex-fanexUITests-acknowledgements.markdown"; sourceTree = ""; }; + 6EB81601FBCD4A2EB2215AD7D3F98D37 /* x509_def.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_def.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_def.c; sourceTree = ""; }; + 6ED3A5996E262D0EF0535AC7C4137969 /* oct.c */ = {isa = PBXFileReference; includeInIndex = 1; name = oct.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/oct.c; sourceTree = ""; }; + 6EDF120F9CFEA86931D71F1931D9F75B /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImagePrefetcher.h; path = SDWebImage/Core/SDWebImagePrefetcher.h; sourceTree = ""; }; + 6EE26EF8BE3D6A621D350BED9AA4AA2B /* SDImageGIFCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageGIFCoder.m; path = SDWebImage/Core/SDImageGIFCoder.m; sourceTree = ""; }; + 6EF2B22C03C28FE00CDFD8407D2FBB55 /* a_strex.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_strex.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_strex.c; sourceTree = ""; }; + 6F1C5C1A1C8F9473CEF780C63705F78A /* CNIOLinux */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOLinux; path = CNIOLinux.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6F2D32CEAA9F7B0E401A841702D9AC14 /* SwiftNIOHTTP1.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOHTTP1.modulemap; sourceTree = ""; }; + 6F7503BE3EC95DDA2F8E1ED90CF7CF71 /* pem_pkey.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_pkey.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_pkey.c; sourceTree = ""; }; + 6FA0BD9869B88FF73FABA4D6D57124D4 /* CGRPCZlibp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CGRPCZlibp.modulemap; sourceTree = ""; }; + 6FAB5953B2D05E975AA748D0B4F5373E /* FCL-SDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "FCL-SDK.debug.xcconfig"; sourceTree = ""; }; + 6FD9A8BDDC22690193E3A35513F8F21E /* SDDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDiskCache.h; path = SDWebImage/Core/SDDiskCache.h; sourceTree = ""; }; + 6FE64E9D19A886C817DDBE83563847C8 /* _MessageContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _MessageContext.swift; path = Sources/GRPC/_MessageContext.swift; sourceTree = ""; }; + 6FEABACF790432B16D0E392CB8416450 /* SwiftNIOHTTP1-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOHTTP1-dummy.m"; sourceTree = ""; }; + 6FEBC0C81CE82A09BDEA8BE8310B2E26 /* MessageEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageEncoding.swift; path = Sources/GRPC/Compression/MessageEncoding.swift; sourceTree = ""; }; + 7002D4F1EB05B8F8EEF19D1CBDA2833A /* dtls_record.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = dtls_record.cc; path = Sources/CNIOBoringSSL/ssl/dtls_record.cc; sourceTree = ""; }; + 701971BD8BCEF2402A37510E0BEE5103 /* CNIOBoringSSL_curve25519.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_curve25519.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_curve25519.h; sourceTree = ""; }; + 70843714C0D9E382FCE8599C7E843D95 /* NSNumber.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NSNumber.swift; path = Sources/Core/Extensions/NSNumber.swift; sourceTree = ""; }; + 70AC45CB71401C49657416805D8D6801 /* div_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = div_extra.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div_extra.c; sourceTree = ""; }; + 70C85FC51E089DF1B652EDBE5CD782B1 /* PopupDialog-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PopupDialog-prefix.pch"; sourceTree = ""; }; + 70E4456A5BE8F2A335A5797D1098BD55 /* Value.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Value.swift; path = Sources/Cadence/Value.swift; sourceTree = ""; }; + 712C37FF555DF1B9B58D9576DF3FB848 /* ChannelHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChannelHandler.swift; path = Sources/NIOCore/ChannelHandler.swift; sourceTree = ""; }; + 7143903518B45B3B4368F186D9483490 /* Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = "Sources/FCL-SDK/Extensions/Extensions.swift"; sourceTree = ""; }; + 715097A0A8AA6288109B6A38590962C6 /* SequenceNumberResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SequenceNumberResolver.swift; path = "Sources/FCL-SDK/Resolve/SequenceNumberResolver.swift"; sourceTree = ""; }; + 715987A64B4A51CE1A1DC6A99BD674C1 /* SDWebImageCacheKeyFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheKeyFilter.h; path = SDWebImage/Core/SDWebImageCacheKeyFilter.h; sourceTree = ""; }; + 716AB6CD880F7D751DACE82887F42C91 /* CadenceArgumentExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CadenceArgumentExtension.swift; path = "Sources/FCL-SDK/Extensions/CadenceArgumentExtension.swift"; sourceTree = ""; }; + 7175926837E08AC3D16D3F34A114B9A0 /* main_impl3.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = main_impl3.h; path = src/modules/recovery/main_impl3.h; sourceTree = ""; }; + 717D08C83B52D264B00E632B40CEC117 /* TCPOptions+SocketChannelOption.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "TCPOptions+SocketChannelOption.swift"; path = "Sources/NIOTransportServices/TCPOptions+SocketChannelOption.swift"; sourceTree = ""; }; + 718103D734BC6C94385D871392384612 /* SwiftNIOExtras.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOExtras.release.xcconfig; sourceTree = ""; }; + 71ABE852F923874D69D84A7984A91B85 /* RLPDecodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPDecodable.swift; path = Sources/FlowSDK/RLP/RLPDecodable.swift; sourceTree = ""; }; + 71BFE46CDEE212C2D554D40D5FF5E7F6 /* SDAnimatedImagePlayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImagePlayer.m; path = SDWebImage/Core/SDAnimatedImagePlayer.m; sourceTree = ""; }; + 723F81442DCD35573C56B73B133F718F /* SwiftProtobuf-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftProtobuf-Info.plist"; sourceTree = ""; }; + 72638FCE3746FD4EE7CE54980A2EB158 /* CipherModeWorker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CipherModeWorker.swift; path = Sources/CryptoSwift/BlockMode/CipherModeWorker.swift; sourceTree = ""; }; + 729B1F8B32184B8DEB21E9CC93C3D27F /* GRPCChannelBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCChannelBuilder.swift; path = Sources/GRPC/GRPCChannel/GRPCChannelBuilder.swift; sourceTree = ""; }; + 72D964BAB663A157827B42E3EFC3AD13 /* secp256k1Swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = secp256k1Swift.debug.xcconfig; sourceTree = ""; }; + 72DD492310DBB3DC25CF83043BD87850 /* CNIOBoringSSL_chacha.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_chacha.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_chacha.h; sourceTree = ""; }; + 72F0CF78FE96B9FA56CB5EAED86E907E /* SDWebImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageManager.h; path = SDWebImage/Core/SDWebImageManager.h; sourceTree = ""; }; + 732FCE54A0B757B577A79BA1BE4259F6 /* SwiftNIOTransportServices-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOTransportServices-prefix.pch"; sourceTree = ""; }; + 73328AB6E67FF4855DF7327B64265B4E /* SwiftNIOSSL */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOSSL; path = NIOSSL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 73643EEA08A3187BF338758D45B69065 /* Pods-fanexTests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-fanexTests"; path = Pods_fanexTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 739B55A60450347DDC51BAB2ECA7970A /* QuiescingState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuiescingState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/QuiescingState.swift; sourceTree = ""; }; + 73B680A7975CF68CC70271B1876AC25C /* DynamicBlurView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = DynamicBlurView.h; path = Sources/DynamicBlurView/DynamicBlurView.h; sourceTree = ""; }; + 73BC5E3CCCB8A71118830BB74E782545 /* URLEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncoding.swift; path = Sources/Core/Utilities/URLEncoding.swift; sourceTree = ""; }; + 73D79B0FD81FD36CF6C4267556FBAC5C /* account.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = account.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/account.pb.swift; sourceTree = ""; }; + 73E7B58CCC3FDF610ED5E5F29121CEA1 /* ReceivingGoAwayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingGoAwayState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingGoAwayState.swift; sourceTree = ""; }; + 73FEE4D1BBD78901D1C2429FA30F1EE0 /* Strideable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Strideable.swift; path = Sources/Strideable.swift; sourceTree = ""; }; + 7411E610AE039B5E4637766CB6288303 /* SwiftNIOTransportServices-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOTransportServices-Info.plist"; sourceTree = ""; }; + 742882FE522A7CABFA19008D890AFF0F /* JSONMapEncodingVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONMapEncodingVisitor.swift; path = Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift; sourceTree = ""; }; + 7429C5A9FAE59CCDDAC3E7D669C079CF /* EventLoopFuture+RecoverFromUncleanShutdown.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "EventLoopFuture+RecoverFromUncleanShutdown.swift"; path = "Sources/GRPC/EventLoopFuture+RecoverFromUncleanShutdown.swift"; sourceTree = ""; }; + 746F91594C1C6B55A7F67979D2257F75 /* URLOpening.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLOpening.swift; path = Sources/Core/Protocols/URLOpening.swift; sourceTree = ""; }; + 74AAFDC7CD7AFD70EF9B0540E439156D /* CNIOBoringSSL_blowfish.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_blowfish.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_blowfish.h; sourceTree = ""; }; + 74DE4695C579F6E61573FA510FB21B08 /* StreamState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamState.swift; path = Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/StreamState.swift; sourceTree = ""; }; + 7513FDB345A1F65E3221C98807F698A9 /* scalar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar.h; path = src/scalar.h; sourceTree = ""; }; + 752DD0693488AAC12528A410CF1B462B /* Google_Protobuf_Duration+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Duration+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift"; sourceTree = ""; }; + 75403BA0717E47809896A2101A23F3F2 /* SVRadialGradientLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVRadialGradientLayer.h; path = SVProgressHUD/SVRadialGradientLayer.h; sourceTree = ""; }; + 75640331ACC3A5E4B6CBA6DA62F539A1 /* scalar_low_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scalar_low_impl.h; path = src/scalar_low_impl.h; sourceTree = ""; }; + 7569FE549DE97DD2355EAD434DEA81D5 /* UInt64+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt64+Extension.swift"; path = "Sources/CryptoSwift/UInt64+Extension.swift"; sourceTree = ""; }; + 75B0E53F3B6357D83B76559AB25E0DAD /* CNIOBoringSSL_boringssl_prefix_symbols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_boringssl_prefix_symbols.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols.h; sourceTree = ""; }; + 75CA24FC216CB0ED577D2C21D9993B55 /* p256-x86_64-asm.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256-x86_64-asm.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256-x86_64-asm.mac.x86_64.S"; sourceTree = ""; }; + 75EE6C6825E074E05328C99223303166 /* SDWebImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloader.h; path = SDWebImage/Core/SDWebImageDownloader.h; sourceTree = ""; }; + 76407BD8DC1F3FEEB7055E348E01C2E1 /* ExtensionMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionMap.swift; path = Sources/SwiftProtobuf/ExtensionMap.swift; sourceTree = ""; }; + 7646B3AFC5E6A30618DD8AF57E8D8B04 /* ChannelInvoker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChannelInvoker.swift; path = Sources/NIOCore/ChannelInvoker.swift; sourceTree = ""; }; + 764CE82F2813B002821F53D9441AE86F /* Comparable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Comparable.swift; path = Sources/Comparable.swift; sourceTree = ""; }; + 764EEE0418CD889331FABF1FA4208DAE /* a_strnid.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_strnid.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_strnid.c; sourceTree = ""; }; + 766A92521248B4D7CD1345D794D01673 /* HTTP2ConnectionStateChange.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ConnectionStateChange.swift; path = Sources/NIOHTTP2/HTTP2ConnectionStateChange.swift; sourceTree = ""; }; + 766CA41AA03E28649D02A18EE8F205E5 /* x_crl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_crl.c; path = Sources/CNIOBoringSSL/crypto/x509/x_crl.c; sourceTree = ""; }; + 7672BDB3320CC16155E590B26AB14394 /* SwiftNIOTransportServices-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOTransportServices-dummy.m"; sourceTree = ""; }; + 769E69568A316FDF6B3797D285755BB7 /* CNIOBoringSSL_blake2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_blake2.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_blake2.h; sourceTree = ""; }; + 76AC28F9452BACDFEB2FFE9583CF3F28 /* Asymmetric.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Asymmetric.swift; path = Sources/secp256k1Swift/Asymmetric.swift; sourceTree = ""; }; + 76BCDE90DDBD2974D226B0DC728E0AAD /* SDAnimatedImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageView.h; path = SDWebImage/Core/SDAnimatedImageView.h; sourceTree = ""; }; + 76C4BC78E99BBCA69E17333115A63EE1 /* hash_to_curve.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hash_to_curve.c; path = Sources/CNIOBoringSSL/crypto/ec_extra/hash_to_curve.c; sourceTree = ""; }; + 76CD9C4BBC20D5D9CFA35EF21D2A28E2 /* BinaryEncodingSizeVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryEncodingSizeVisitor.swift; path = Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift; sourceTree = ""; }; + 76D0C0B97E84363163E311367A65FD86 /* CNIOBoringSSL_ssl3.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ssl3.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ssl3.h; sourceTree = ""; }; + 76EFDA04C75D0547F58E8333515A45AB /* SwiftNIO.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIO.debug.xcconfig; sourceTree = ""; }; + 7735873715F8E46AB2C372215EFEAEBA /* cipher.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cipher.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/cipher.c; sourceTree = ""; }; + 777E76DC30F79C40830F0990980A4072 /* PosixPort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PosixPort.swift; path = Sources/NIOSSL/PosixPort.swift; sourceTree = ""; }; + 77D4B490F34F7351B400CE5225B4A047 /* HTTP2Settings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2Settings.swift; path = Sources/NIOHTTP2/HTTP2Settings.swift; sourceTree = ""; }; + 77FC267086AFB9870729CA2F56F19755 /* tasn_new.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_new.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_new.c; sourceTree = ""; }; + 77FCB4602CFB8CFE7B1942923867936A /* testrand_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = testrand_impl.h; path = src/testrand_impl.h; sourceTree = ""; }; + 782B3DD0F29FE497BDD4D415DA7CC737 /* _NIODataStructures.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = _NIODataStructures.modulemap; sourceTree = ""; }; + 78431EA97C0C20246C4833012B325706 /* SwiftNIO-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIO-prefix.pch"; sourceTree = ""; }; + 7868B0CDEB78DBFB971E767F254140D3 /* SDWebImageDownloader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloader.m; path = SDWebImage/Core/SDWebImageDownloader.m; sourceTree = ""; }; + 792D40C0B5291DFDEDB11F6CE0649DB9 /* CNIOBoringSSL_md4.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_md4.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_md4.h; sourceTree = ""; }; + 796848D95E9BA10B25A83BC6FAC6279D /* secp256k1_recovery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1_recovery.h; path = include/secp256k1_recovery.h; sourceTree = ""; }; + 7974CE5CD2CD502F04009B9D88D533C7 /* blinding.c */ = {isa = PBXFileReference; includeInIndex = 1; name = blinding.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/blinding.c; sourceTree = ""; }; + 79B75CA13DC587252CA4275F80B0A9B7 /* CNIOBoringSSL_boringssl_prefix_symbols_asm.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_boringssl_prefix_symbols_asm.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_boringssl_prefix_symbols_asm.h; sourceTree = ""; }; + 79BBF3EED4F75438552D9EB9017EFA8B /* StaticHeaderTable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StaticHeaderTable.swift; path = Sources/NIOHPACK/StaticHeaderTable.swift; sourceTree = ""; }; + 79C1EF32BD6685FE569A9EF68CA59A78 /* SwiftNIOHPACK.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOHPACK.modulemap; sourceTree = ""; }; + 79C25710B55D85F3562DDF354FA4D589 /* sha512-armv4.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-armv4.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv4.linux.arm.S"; sourceTree = ""; }; + 79C3BB6A22C6C64728AE5A3A9800B74C /* pem_x509.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_x509.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_x509.c; sourceTree = ""; }; + 7A0CEBD079B76F4703EE2CE856E59BC3 /* Collection+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Collection+Extension.swift"; path = "Sources/CryptoSwift/Collection+Extension.swift"; sourceTree = ""; }; + 7A1535AA5F7C7E64787C97A332A65291 /* MarkedCircularBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MarkedCircularBuffer.swift; path = Sources/NIOCore/MarkedCircularBuffer.swift; sourceTree = ""; }; + 7A2BA49B19A14C63DCA70C388DA85953 /* BigInt.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BigInt.debug.xcconfig; sourceTree = ""; }; + 7A6F43EDA3AAEB0A7636E47D1BEA18A8 /* SwiftNIOFoundationCompat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOFoundationCompat.debug.xcconfig; sourceTree = ""; }; + 7A762F23B1113D8E24B6AE1977D53DCB /* PKCS5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS5.swift; path = Sources/CryptoSwift/PKCS/PKCS5.swift; sourceTree = ""; }; + 7A847BA2B6D042C77880F1099B20995E /* ssl_stat.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_stat.cc; path = Sources/CNIOBoringSSL/ssl/ssl_stat.cc; sourceTree = ""; }; + 7A9EC9573C7A3E60032641DD2C1C4795 /* md4.c */ = {isa = PBXFileReference; includeInIndex = 1; name = md4.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/md4/md4.c; sourceTree = ""; }; + 7AB5E959B806B6D0CF955CF738AC44A6 /* ecmult_gen.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_gen.h; path = src/ecmult_gen.h; sourceTree = ""; }; + 7AC5763D6A87662250C6ADCCEE75095A /* Interfaces.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Interfaces.swift; path = Sources/NIOCore/Interfaces.swift; sourceTree = ""; }; + 7AE40AFE7EFA92E72357747043244CE2 /* ChannelPipeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChannelPipeline.swift; path = Sources/NIOCore/ChannelPipeline.swift; sourceTree = ""; }; + 7AEBA82D151D457B8D21E60FEE8FD924 /* GRPCServerPipelineConfigurator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCServerPipelineConfigurator.swift; path = Sources/GRPC/GRPCServerPipelineConfigurator.swift; sourceTree = ""; }; + 7B325D7050B338C70831E7F3117794BE /* SwiftNIOPosix-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOPosix-dummy.m"; sourceTree = ""; }; + 7B343970A1011A392AEA4D1F350C12D6 /* p_ed25519.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_ed25519.c; path = Sources/CNIOBoringSSL/crypto/evp/p_ed25519.c; sourceTree = ""; }; + 7B6A8AA637C75BC871D1086059116087 /* Role.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Role.swift; path = "Sources/FCL-SDK/Models/Role.swift"; sourceTree = ""; }; + 7B7C5FBF0BB02E454854FD9C1656EAF1 /* SwiftyJSON-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-prefix.pch"; sourceTree = ""; }; + 7B86D1B76693FF2E7EB9A86C20BFAE1D /* Socket.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Socket.swift; path = Sources/NIOPosix/Socket.swift; sourceTree = ""; }; + 7BC31F011248F16CE3E77E3F25508401 /* aesv8-armx64.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesv8-armx64.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.ios.aarch64.S"; sourceTree = ""; }; + 7BDD27EA6B00152FF0E718F7E4E0B5BC /* GRPCLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCLogger.swift; path = Sources/GRPC/GRPCLogger.swift; sourceTree = ""; }; + 7BF3F10E7C390DBE08FD2668947709C4 /* SwiftNIOHTTP1-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHTTP1-prefix.pch"; sourceTree = ""; }; + 7C495DA1DE6588F5E5C267D67D0B3A67 /* CNIOWindows-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOWindows-dummy.m"; sourceTree = ""; }; + 7C5265CC769A2FD94944FE072A165B82 /* sha256-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 7CCBEED9840A524A1F782D870BA02CFE /* SwiftNIOCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOCore-dummy.m"; sourceTree = ""; }; + 7CE207153EF5353D725D8EA028555A5B /* HTTP2Frame.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2Frame.swift; path = Sources/NIOHTTP2/HTTP2Frame.swift; sourceTree = ""; }; + 7CE6CB7FA5DCAE1E7306FC4950B6E6B2 /* SwiftNIOEmbedded.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOEmbedded.modulemap; sourceTree = ""; }; + 7D09D70EE4A5398949BD23971F06909A /* CNIODarwin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIODarwin.release.xcconfig; sourceTree = ""; }; + 7D2D3C66784C69FFD174E32B064616C2 /* rsaz_exp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = rsaz_exp.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/rsaz_exp.h; sourceTree = ""; }; + 7D41C1A5A3343C40316A5339C52B6BBF /* CustomPrivateKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CustomPrivateKey.swift; path = Sources/NIOSSL/CustomPrivateKey.swift; sourceTree = ""; }; + 7D780F6DECFC48AFCAC7177C09D88CAA /* SDWebImageCompat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCompat.h; path = SDWebImage/Core/SDWebImageCompat.h; sourceTree = ""; }; + 7D7B8E5E7945F60A19C07B8006CB4BEB /* precomputed_ecmult_gen.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = precomputed_ecmult_gen.h; path = src/precomputed_ecmult_gen.h; sourceTree = ""; }; + 7D90504E9042649F39D595CAF524C4A1 /* GCD.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GCD.swift; path = Sources/CryptoSwift/CS_BigInt/GCD.swift; sourceTree = ""; }; + 7DB2A9752DA2D470C520B44CA619076B /* ServerErrorDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerErrorDelegate.swift; path = Sources/GRPC/ServerErrorDelegate.swift; sourceTree = ""; }; + 7DE6A0217C1A0B0D81EBB20DEAFE8713 /* d1_srtp.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = d1_srtp.cc; path = Sources/CNIOBoringSSL/ssl/d1_srtp.cc; sourceTree = ""; }; + 7E0B6181CAC16C08E1B995F751D98DEF /* ServerInterceptorContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerInterceptorContext.swift; path = Sources/GRPC/Interceptor/ServerInterceptorContext.swift; sourceTree = ""; }; + 7E3A1FEA70906514D5833E0C24B272A8 /* DOSHeuristics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DOSHeuristics.swift; path = Sources/NIOHTTP2/DOSHeuristics.swift; sourceTree = ""; }; + 7E4924462479AAFB08B5F728BD40684B /* AnyMessageStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyMessageStorage.swift; path = Sources/SwiftProtobuf/AnyMessageStorage.swift; sourceTree = ""; }; + 7E57E9F69648C28BE44DD5F17DF1F549 /* PreSignable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PreSignable.swift; path = "Sources/FCL-SDK/Models/PreSignable.swift"; sourceTree = ""; }; + 7E78B33A1DFF123DF62FA02FE632939A /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/internal.h; sourceTree = ""; }; + 7E968AB08461932A981DEA0A9A3D749D /* BatchedCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BatchedCollection.swift; path = Sources/CryptoSwift/BatchedCollection.swift; sourceTree = ""; }; + 7ECDD0AF7AD61EEDFE08E3FA3A87EC4D /* WriteCapturingHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WriteCapturingHandler.swift; path = Sources/GRPC/WriteCapturingHandler.swift; sourceTree = ""; }; + 7ED79131FD4799CE802D4FCB1A45A27D /* BinaryDelimited.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDelimited.swift; path = Sources/SwiftProtobuf/BinaryDelimited.swift; sourceTree = ""; }; + 7EE3F46D7411B71D83FAAD008A2E82D5 /* AsyncWriter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncWriter.swift; path = Sources/GRPC/AsyncAwaitSupport/AsyncWriter.swift; sourceTree = ""; }; + 7EED3777D51C8B8889CB915AEA5071C4 /* SendAndReceiveGoawayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendAndReceiveGoawayState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/SendAndReceiveGoawayState.swift; sourceTree = ""; }; + 7EEDE01AE2D834A270754AC5ACCD6FDD /* ssl_key_share.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_key_share.cc; path = Sources/CNIOBoringSSL/ssl/ssl_key_share.cc; sourceTree = ""; }; + 7EF2A44E9190048723B5408D239C2DC8 /* sha1-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 7F1BA82BD02D495DD5171719767560FE /* x_attrib.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_attrib.c; path = Sources/CNIOBoringSSL/crypto/x509/x_attrib.c; sourceTree = ""; }; + 7F507707B2353A74A5C1204E3238AB67 /* SwiftNIOSSL.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOSSL.modulemap; sourceTree = ""; }; + 7F87CEEB29D415F63D329BB8210E9DCA /* SwiftNIOHTTP1-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOHTTP1-Info.plist"; sourceTree = ""; }; + 7F9AA16751603F0ED1D7D6241CBE2549 /* tls13_client.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls13_client.cc; path = Sources/CNIOBoringSSL/ssl/tls13_client.cc; sourceTree = ""; }; + 7FA903E3889EF8277F0D62AF77621B8F /* Message.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Message.swift; path = Sources/SwiftProtobuf/Message.swift; sourceTree = ""; }; + 7FB3E6CA4148FDD0A85530EEE85C17BC /* ReceivingDataState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingDataState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingDataState.swift; sourceTree = ""; }; + 7FC57450151C39D180A7DE70D0C807AF /* HTTP2ToHTTP1Codec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ToHTTP1Codec.swift; path = Sources/NIOHTTP2/HTTP2ToHTTP1Codec.swift; sourceTree = ""; }; + 8020F5D5CC03C195103D0A77D1AB1062 /* UIImage+MultiFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MultiFormat.m"; path = "SDWebImage/Core/UIImage+MultiFormat.m"; sourceTree = ""; }; + 8051E24E27FD90DF9CEC414E6B98F822 /* StringExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StringExtensions.swift; path = Sources/Core/Extensions/StringExtensions.swift; sourceTree = ""; }; + 8064FD2B8EED372A919120A0AF91965E /* evp_ctx.c */ = {isa = PBXFileReference; includeInIndex = 1; name = evp_ctx.c; path = Sources/CNIOBoringSSL/crypto/evp/evp_ctx.c; sourceTree = ""; }; + 806FE446300C5A6F475BE596A8C09F8E /* SDImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCache.m; path = SDWebImage/Core/SDImageCache.m; sourceTree = ""; }; + 8077F7252FAFDBE8DF3D1A8A44F808EF /* NSImage+Compatibility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSImage+Compatibility.m"; path = "SDWebImage/Core/NSImage+Compatibility.m"; sourceTree = ""; }; + 807BABDB923D2AA2EDE6E2C9564118CD /* vpaes-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.linux.aarch64.S"; sourceTree = ""; }; + 807F6B14251EAA3A22A075AF6781C6C5 /* SDWebImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-prefix.pch"; sourceTree = ""; }; + 807F99CF0921EFD7AAF68E2FFACE71BB /* modinv64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = modinv64.h; path = src/modinv64.h; sourceTree = ""; }; + 808D08A0CB972D95262C50B2C8460F77 /* SVProgressHUD.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressHUD.m; path = SVProgressHUD/SVProgressHUD.m; sourceTree = ""; }; + 809579937BFB7F3B4CC2F399DFC66341 /* CryptoSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-prefix.pch"; sourceTree = ""; }; + 809845627483AAE66290A0A5CAAB924F /* sha256-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.ios.aarch64.S"; sourceTree = ""; }; + 80D071A6E31239AA1A56D6F34AAF2BFD /* refcount_c11.c */ = {isa = PBXFileReference; includeInIndex = 1; name = refcount_c11.c; path = Sources/CNIOBoringSSL/crypto/refcount_c11.c; sourceTree = ""; }; + 8156F58C8053D3FB9A6408CC8A13CDE1 /* file.c */ = {isa = PBXFileReference; includeInIndex = 1; name = file.c; path = Sources/CNIOBoringSSL/crypto/bio/file.c; sourceTree = ""; }; + 8199A0F10EDCAB412B8E7161C713BC66 /* SwiftNIOFoundationCompat.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOFoundationCompat.modulemap; sourceTree = ""; }; + 81AC88440747A0FCA422BCA626C9A038 /* SwiftNIOExtras */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOExtras; path = NIOExtras.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 81AECAE46BD788C0FA0E5735F9D8C082 /* Images.xcassets */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = QRScanner/Images.xcassets; sourceTree = ""; }; + 81B21E3A326D5E9975392E40E1B3C9D7 /* ghash-neon-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-neon-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-neon-armv8.ios.aarch64.S"; sourceTree = ""; }; + 81B64ADFE4BDE44F8BB718A1F9322757 /* AsyncAwaitSupport+OldXcodes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "AsyncAwaitSupport+OldXcodes.swift"; path = "Sources/NIOCore/AsyncAwaitSupport+OldXcodes.swift"; sourceTree = ""; }; + 81CA65DAA499F4180D7F20A100FDA6EE /* ByteBuffer-lengthPrefix.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-lengthPrefix.swift"; path = "Sources/NIOCore/ByteBuffer-lengthPrefix.swift"; sourceTree = ""; }; + 81FAAC53CF7CB572F1A0713851F727B5 /* SendingRstStreamState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingRstStreamState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingRstStreamState.swift; sourceTree = ""; }; + 82006C1BC2CD48F726128D0C958B3ACB /* Int+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Int+Extension.swift"; path = "Sources/CryptoSwift/Int+Extension.swift"; sourceTree = ""; }; + 825EFFDDE9B3D5F42B64850D210D839E /* SDAnimatedImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageView.m; path = SDWebImage/Core/SDAnimatedImageView.m; sourceTree = ""; }; + 82862FE35B12CF563FC156B6110476B1 /* SDWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWeakProxy.h; path = SDWebImage/Private/SDWeakProxy.h; sourceTree = ""; }; + 82AAF7249C7A243276F99629C91B7201 /* ConnectionStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionStateMachine.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStateMachine.swift; sourceTree = ""; }; + 82BDEA9DBA5FF9733B6B9B3BAB638B79 /* felem.c */ = {isa = PBXFileReference; includeInIndex = 1; name = felem.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/felem.c; sourceTree = ""; }; + 82FBE5CE279EE64E6AC1A3D977D9C3E7 /* SwiftProtobuf.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftProtobuf.release.xcconfig; sourceTree = ""; }; + 8317596C69D387B4AA90D6E8E6EF1BF3 /* chacha-armv4.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-armv4.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.linux.arm.S"; sourceTree = ""; }; + 831C0F957479585F1A8681350E2F1960 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/ssl/internal.h; sourceTree = ""; }; + 8342CEB64D4BEBCE210DF23AAF9855D6 /* SwiftProtobuf.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftProtobuf.debug.xcconfig; sourceTree = ""; }; + 83A30EB5C0B404B831478DE052634CFE /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/pkcs7/internal.h; sourceTree = ""; }; + 83BFF208CBA978EE49028C2CCBFFA9C1 /* CNIOBoringSSL_mem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_mem.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_mem.h; sourceTree = ""; }; + 83D2B264237083DDB90A3A3B5618FCA5 /* armv8-mont.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "armv8-mont.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.ios.aarch64.S"; sourceTree = ""; }; + 83F58491C6DD6CE92E44F104904186AC /* MayReceiveFrames.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MayReceiveFrames.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/MayReceiveFrames.swift; sourceTree = ""; }; + 841D60008F5F770B313C006A8DFA67A7 /* ServiceIdentity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceIdentity.swift; path = "Sources/FCL-SDK/User/Service/ServiceIdentity.swift"; sourceTree = ""; }; + 8424D5BFC4301B7A3E986E42A11F4571 /* MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MD5.swift; path = Sources/CryptoSwift/MD5.swift; sourceTree = ""; }; + 8436BC15451DA6766C259541522EB812 /* _NIODataStructures */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = _NIODataStructures; path = _NIODataStructures.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 843C50DA31F8E3B21D234B2AE095DBB5 /* armv4-mont.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "armv4-mont.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/armv4-mont.linux.arm.S"; sourceTree = ""; }; + 843DC486B3962999E5D2EB6FD72C1F70 /* UnsafeBufferPointer+Shims.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UnsafeBufferPointer+Shims.swift"; path = "Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift"; sourceTree = ""; }; + 84650E9EF8B829CC71F475A58EF9FA97 /* DeadChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DeadChannel.swift; path = Sources/NIOCore/DeadChannel.swift; sourceTree = ""; }; + 8489F90B00219E2F816445944BEF3D01 /* Logging.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Logging.debug.xcconfig; sourceTree = ""; }; + 84B8527DE7A43676401D74299221BC85 /* StreamChannelFlowController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamChannelFlowController.swift; path = Sources/NIOHTTP2/StreamChannelFlowController.swift; sourceTree = ""; }; + 84D167E6FCBE27D8E5E6BC4A30A076EC /* CNIOBoringSSL.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOBoringSSL.modulemap; sourceTree = ""; }; + 84DD29ACB4CAE8D176D00306632D91B8 /* PublicKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublicKey.swift; path = Sources/FlowSDK/Crypto/PublicKey.swift; sourceTree = ""; }; + 84E383DA3A0800A46C0734C2D4460F19 /* CryptoSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CryptoSwift-dummy.m"; sourceTree = ""; }; + 85023AE87EBFED1E887AA6F3F7ABA2C1 /* CNIOBoringSSL_stack.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_stack.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_stack.h; sourceTree = ""; }; + 8505E620F80DAB19865C77F7204E3DE2 /* PipePair.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PipePair.swift; path = Sources/NIOPosix/PipePair.swift; sourceTree = ""; }; + 852805F03CD9FE9D25A0C3D4B3E7D4D5 /* SDAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImage.m; path = SDWebImage/Core/SDAnimatedImage.m; sourceTree = ""; }; + 8535333F12E206F0A29CED9A0F935BF7 /* CGRPCZlibp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CGRPCZlibp.release.xcconfig; sourceTree = ""; }; + 859AB0A0806DCFFB6C5C85C999B23FC7 /* SVProgressHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.release.xcconfig; sourceTree = ""; }; + 85AA449DC627A563D0622878274D245C /* Pragma.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Pragma.swift; path = "Sources/FCL-SDK/Models/Pragma.swift"; sourceTree = ""; }; + 85BCB5DB1810B32E458CFF66D5D5B0B1 /* a_d2i_fp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_d2i_fp.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_d2i_fp.c; sourceTree = ""; }; + 85C28454D1170371B9D8A0DF53331720 /* ctr.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ctr.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ctr.c; sourceTree = ""; }; + 85E19BBBB9A6ED0D665B3E9C5DC3484F /* UIImage+ForceDecode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ForceDecode.m"; path = "SDWebImage/Core/UIImage+ForceDecode.m"; sourceTree = ""; }; + 85F47BA8B5549C0C4A9F35A0BF8EE2CD /* TextFormatDecodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatDecodingError.swift; path = Sources/SwiftProtobuf/TextFormatDecodingError.swift; sourceTree = ""; }; + 86255070A3CCAF2DCDB9ECE5391A5F6A /* Words and Bits.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Words and Bits.swift"; path = "Sources/Words and Bits.swift"; sourceTree = ""; }; + 8634EBFFCCDD9B284853088DD982AB91 /* Prime Test.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Prime Test.swift"; path = "Sources/Prime Test.swift"; sourceTree = ""; }; + 864D6FBF48B8E33BA48229F0FD5D8D21 /* BloctoSDKCompatible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BloctoSDKCompatible.swift; path = Sources/Core/Extensions/BloctoSDKCompatible.swift; sourceTree = ""; }; + 866B08232B96F5B9DA341EC4C127988E /* a_type.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_type.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_type.c; sourceTree = ""; }; + 868290F8DF10946C2B695AE2C93A45AA /* t_x509a.c */ = {isa = PBXFileReference; includeInIndex = 1; name = t_x509a.c; path = Sources/CNIOBoringSSL/crypto/x509/t_x509a.c; sourceTree = ""; }; + 86B0C15C4D16323D6FF84C1FA5384A89 /* SwiftNIOCore.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOCore.release.xcconfig; sourceTree = ""; }; + 86B849448B31D6D97CC059662046AB48 /* ecdsa.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ecdsa.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c; sourceTree = ""; }; + 86BCE77648001A9860BA9ED1C6D5CBAA /* ghash-x86.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-x86.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86.linux.x86.S"; sourceTree = ""; }; + 86BE3FABFFCEF31E8FB55DE029BD0F0B /* field_5x52_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_5x52_impl.h; path = src/field_5x52_impl.h; sourceTree = ""; }; + 86C4A2D817E6CFFF31BF75161625FD5D /* DynamicBlurView */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = DynamicBlurView; path = DynamicBlurView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 86CDA9D7F74123ECD5926436D656E42E /* util.c */ = {isa = PBXFileReference; includeInIndex = 1; name = util.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/util.c; sourceTree = ""; }; + 871F2A38AE8AC9376E3561F36772742C /* poly1305_arm_asm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = poly1305_arm_asm.S; path = Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm_asm.S; sourceTree = ""; }; + 875643C3A2B0BB94A8A34FB1C7FCA178 /* InboundWindowManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InboundWindowManager.swift; path = Sources/NIOHTTP2/InboundWindowManager.swift; sourceTree = ""; }; + 879A80E98782881CC1A23C471B4FE210 /* Cadence.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Cadence.modulemap; sourceTree = ""; }; + 8827950DD3810708BE7B6452799C3145 /* DynamicBlurView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DynamicBlurView-prefix.pch"; sourceTree = ""; }; + 885445AB8E8BF1B1A00D746A027C9D1D /* SDDeviceHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDeviceHelper.h; path = SDWebImage/Private/SDDeviceHelper.h; sourceTree = ""; }; + 885E717B30A17DFBD9D63B98379E6883 /* tasn_enc.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_enc.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_enc.c; sourceTree = ""; }; + 887D9ECBC6B7F324CA3652F963F26571 /* ZigZag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZigZag.swift; path = Sources/SwiftProtobuf/ZigZag.swift; sourceTree = ""; }; + 88A52EE3F3AFDBB44C3592AD31A41FBD /* ecmult_gen_compute_table.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_gen_compute_table.h; path = src/ecmult_gen_compute_table.h; sourceTree = ""; }; + 88DCEFFCCAE19562AD1B892026A9330A /* SwiftNIOCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOCore.debug.xcconfig; sourceTree = ""; }; + 8908B111120DA1E80ADDAE3AA27324C3 /* socket_helper.c */ = {isa = PBXFileReference; includeInIndex = 1; name = socket_helper.c; path = Sources/CNIOBoringSSL/crypto/bio/socket_helper.c; sourceTree = ""; }; + 891F6C38DB160984768F7ACF77C04993 /* SVProgressHUD.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SVProgressHUD.h; path = SVProgressHUD/SVProgressHUD.h; sourceTree = ""; }; + 89335E424E816A8DC01CC0ACDD434A43 /* CNIOBoringSSL_hpke.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_hpke.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_hpke.h; sourceTree = ""; }; + 8A0B2BF8BB6F85B0D453ED8C0B12FC40 /* ctrdrbg.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ctrdrbg.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/ctrdrbg.c; sourceTree = ""; }; + 8A126BD214790EE4C1CA42E4A387311E /* CNIOBoringSSL_asn1_mac.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_asn1_mac.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1_mac.h; sourceTree = ""; }; + 8A208216618E2EB447F2F85B8B31B0F4 /* Cadence-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Cadence-prefix.pch"; sourceTree = ""; }; + 8A3B24D4DB3060A69D9A18858B51BD36 /* CNIOHTTPParser-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOHTTPParser-dummy.m"; sourceTree = ""; }; + 8A438CD9BFBD6DBA35E833922EC43468 /* CNIOBoringSSL_conf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_conf.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_conf.h; sourceTree = ""; }; + 8A6887895625D9DECAAEBF5A690134F7 /* SwiftNIOHPACK */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOHPACK; path = NIOHPACK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8A6FE2D88F187D54B3237983D3AE0408 /* v3_purp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_purp.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_purp.c; sourceTree = ""; }; + 8A7DABB47C717F3A0AE17A086BF808B5 /* SwiftNIOSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOSSL.debug.xcconfig; sourceTree = ""; }; + 8AA17A649FAE8060A699174BFD83D0C3 /* block.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = block.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/block.pb.swift; sourceTree = ""; }; + 8AA7887399F147D38C74BE47F5DCC78E /* SDImageIOAnimatedCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageIOAnimatedCoder.h; path = SDWebImage/Core/SDImageIOAnimatedCoder.h; sourceTree = ""; }; + 8AF365C7AB26489C06FCFE902F8A964E /* CNIOBoringSSL_dtls1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_dtls1.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_dtls1.h; sourceTree = ""; }; + 8AFCD6C11BF1A8D3DE74A721E78D0D3E /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Sources/CryptoSwift/Operators.swift; sourceTree = ""; }; + 8B01738680478070311F7465DBD996A2 /* utility.c */ = {isa = PBXFileReference; includeInIndex = 1; name = utility.c; path = src/utility.c; sourceTree = ""; }; + 8B504D41BF6D241A3F017DB3191ECC91 /* selftest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = selftest.h; path = src/selftest.h; sourceTree = ""; }; + 8B7A63C9E772AE749842EEEA4C93B6F5 /* SignableUser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SignableUser.swift; path = "Sources/FCL-SDK/Models/SignableUser.swift"; sourceTree = ""; }; + 8B89A2EA9C362A77FBCA5E4BDF5E4F69 /* SDAssociatedObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAssociatedObject.m; path = SDWebImage/Private/SDAssociatedObject.m; sourceTree = ""; }; + 8B937F84CA0F4DE0A31A65B671E08821 /* ServerChannelErrorHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerChannelErrorHandler.swift; path = Sources/GRPC/ServerChannelErrorHandler.swift; sourceTree = ""; }; + 8BDB386DC2393B9E00111C6BDCC355BD /* SDImageCachesManagerOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCachesManagerOperation.m; path = SDWebImage/Private/SDImageCachesManagerOperation.m; sourceTree = ""; }; + 8C37C919BAC5CC9F4315FC8E80AE0BAA /* v3_skey.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_skey.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_skey.c; sourceTree = ""; }; + 8C497C2FB894DD3EF2130F73BD38D1F6 /* c_nio_http_parser.c */ = {isa = PBXFileReference; includeInIndex = 1; name = c_nio_http_parser.c; path = Sources/CNIOHTTPParser/c_nio_http_parser.c; sourceTree = ""; }; + 8C9A1B083389A9099DA073CE542C2329 /* ofb.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ofb.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/ofb.c; sourceTree = ""; }; + 8CA968D37E649A137FED235C6F605C65 /* scrypt.c */ = {isa = PBXFileReference; includeInIndex = 1; name = scrypt.c; path = Sources/CNIOBoringSSL/crypto/evp/scrypt.c; sourceTree = ""; }; + 8CFE5772B62649A74A68BF90457734A3 /* field_5x52.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_5x52.h; path = src/field_5x52.h; sourceTree = ""; }; + 8D02C1E0AE5E91CDC76A4FBFEDF72DF8 /* AnyUnpackError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyUnpackError.swift; path = Sources/SwiftProtobuf/AnyUnpackError.swift; sourceTree = ""; }; + 8D20EC911C9371E4FFA011F5DD1D64A1 /* secp256k1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = secp256k1.swift; path = Sources/secp256k1Swift/secp256k1.swift; sourceTree = ""; }; + 8D344F7DF3C892D34365A5382075A06D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 8D7CBC2B76E29B6042FF02D05EB4EF33 /* SSLPKCS12Bundle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLPKCS12Bundle.swift; path = Sources/NIOSSL/SSLPKCS12Bundle.swift; sourceTree = ""; }; + 8D8974AE36F98BE418E182C13540358C /* CNIOBoringSSL_asn1t.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_asn1t.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_asn1t.h; sourceTree = ""; }; + 8DA7813BCD0DDF69755DD1838DBD2583 /* CNIOBoringSSL_ripemd.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ripemd.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ripemd.h; sourceTree = ""; }; + 8DAE52D6C3B2FC9C548C6B1D2539123A /* FTypeKind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FTypeKind.swift; path = Sources/Cadence/FTypeKind.swift; sourceTree = ""; }; + 8DC169C7AA03EA4BB6D8B3E3015E4C8A /* Server+NIOSSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Server+NIOSSL.swift"; path = "Sources/GRPC/Server+NIOSSL.swift"; sourceTree = ""; }; + 8DD02F2712EDB42025E6D5142E561917 /* CNIOBoringSSL-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOBoringSSL-prefix.pch"; sourceTree = ""; }; + 8DDD8BD3738991F903CBD2F231644C87 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; + 8DDE2415D2CEFD7CE529F9EB805AE1B1 /* div.c */ = {isa = PBXFileReference; includeInIndex = 1; name = div.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/div.c; sourceTree = ""; }; + 8DEA8C2291C63E540ADE27DF18E653C4 /* pem_lib.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_lib.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_lib.c; sourceTree = ""; }; + 8E02396B0223EA2822BDAF9522B514F3 /* BinaryDecodingOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDecodingOptions.swift; path = Sources/SwiftProtobuf/BinaryDecodingOptions.swift; sourceTree = ""; }; + 8E9240AA999E52750C2D2F8E00F79E0B /* Rabbit+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Rabbit+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift"; sourceTree = ""; }; + 8E9BCA3A2D8C63873EE05B43FA2DD72A /* SwiftNIOTLS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOTLS-umbrella.h"; sourceTree = ""; }; + 8ECD758173A4365C3AF953E56F0B3C80 /* SignatureResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SignatureResolver.swift; path = "Sources/FCL-SDK/Resolve/SignatureResolver.swift"; sourceTree = ""; }; + 8EF5CCE3CAE796C01BC8099306428ED4 /* v3_genn.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_genn.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_genn.c; sourceTree = ""; }; + 8F01808D47405EE897EAA5274B62488C /* digest_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = digest_extra.c; path = Sources/CNIOBoringSSL/crypto/digest_extra/digest_extra.c; sourceTree = ""; }; + 8F21E8BB641EB344580DF444761E4D1D /* ChaCha20.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChaCha20.swift; path = Sources/CryptoSwift/ChaCha20.swift; sourceTree = ""; }; + 8F347992C8E1B36C3F9FA4486BF8A1EA /* x_req.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_req.c; path = Sources/CNIOBoringSSL/crypto/x509/x_req.c; sourceTree = ""; }; + 8F65183B06EC810B56AE796D97035222 /* ClientInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientInfo.swift; path = "Sources/FCL-SDK/Models/ClientInfo.swift"; sourceTree = ""; }; + 8F72B636107B54802B4D852AE2F69935 /* UIColor+SDHexString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIColor+SDHexString.m"; path = "SDWebImage/Private/UIColor+SDHexString.m"; sourceTree = ""; }; + 8F90EF6E29C41EA643A08282FCEAEA2A /* MercariQRScanner-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MercariQRScanner-prefix.pch"; sourceTree = ""; }; + 8F941B1AE0DE9669799EA5DB9604311D /* hrss.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hrss.c; path = Sources/CNIOBoringSSL/crypto/hrss/hrss.c; sourceTree = ""; }; + 8FB4B7760175730C39FC1F260C5439B4 /* thread_pthread.c */ = {isa = PBXFileReference; includeInIndex = 1; name = thread_pthread.c; path = Sources/CNIOBoringSSL/crypto/thread_pthread.c; sourceTree = ""; }; + 8FB8935FD0D4655DDDEC773B7B4915CE /* SDWebImageCacheKeyFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCacheKeyFilter.m; path = SDWebImage/Core/SDWebImageCacheKeyFilter.m; sourceTree = ""; }; + 8FC5826C4720FA1B7B3778827DF4517F /* RequestAccountMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestAccountMethod.swift; path = Sources/Core/Methods/RequestAccountMethod.swift; sourceTree = ""; }; + 8FD6706181F20F0BB844323B4501CCBB /* Visitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Visitor.swift; path = Sources/SwiftProtobuf/Visitor.swift; sourceTree = ""; }; + 8FE9F6900C3BE0B0D876EEF118FA2339 /* duration.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = duration.pb.swift; path = Sources/SwiftProtobuf/duration.pb.swift; sourceTree = ""; }; + 8FF09A62EB2C949481BE3164B7FD35AE /* CNIOBoringSSL_bn.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_bn.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_bn.h; sourceTree = ""; }; + 9024AD82FD71C379F75FC57CA503D370 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/chacha/internal.h; sourceTree = ""; }; + 904BAB653CB9F1076FB673F402C78DAC /* PlatformSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PlatformSupport.swift; path = Sources/GRPC/PlatformSupport.swift; sourceTree = ""; }; + 9059977DCEFF09B9DF959B8130F23A18 /* HTTP2UserEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2UserEvents.swift; path = Sources/NIOHTTP2/HTTP2UserEvents.swift; sourceTree = ""; }; + 90749C992E1BDD56FB2E5288EC80B36C /* ProviderInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ProviderInfo.swift; path = "Sources/FCL-SDK/Models/ProviderInfo.swift"; sourceTree = ""; }; + 90E4167A20621BF7147FD29098C445C3 /* cmac.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cmac.c; path = Sources/CNIOBoringSSL/crypto/cmac/cmac.c; sourceTree = ""; }; + 90ED2F344C5847CA95D7B80B73E146A1 /* chacha-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.linux.aarch64.S"; sourceTree = ""; }; + 914529946EF5601AA93F8EE079CF3C9B /* SDWebImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImage.h; path = WebImage/SDWebImage.h; sourceTree = ""; }; + 915361CF4F5BEB9ECA5F7A89DAE63096 /* MercariQRScanner */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MercariQRScanner; path = MercariQRScanner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 918ECE4B52BECD386CF80B33C8BE5A8D /* SwiftyJSON.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.debug.xcconfig; sourceTree = ""; }; + 919A1F050EB6C3A6737D3554B23721D2 /* CNIOBoringSSLShims-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOBoringSSLShims-umbrella.h"; sourceTree = ""; }; + 91B96C39808611942C367F684DEAA2D3 /* Google_Protobuf_Any+Registry.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Any+Registry.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift"; sourceTree = ""; }; + 91BB24BA472AF523E913108C9AA301F2 /* BigInt */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = BigInt; path = BigInt.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 91DA5E04F67C81D9A610BFDE1B7E6A81 /* TransactionSignature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransactionSignature.swift; path = Sources/FlowSDK/Models/TransactionSignature.swift; sourceTree = ""; }; + 921A5CE0D626D2D9F73F2B2C37C57DD3 /* MercariQRScanner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MercariQRScanner.release.xcconfig; sourceTree = ""; }; + 92206D944CFA8537AE3137C4C34F8351 /* ClientConnection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientConnection.swift; path = Sources/GRPC/ClientConnection.swift; sourceTree = ""; }; + 924F1FC918F274DC38CBFFDA178B3404 /* CNIOBoringSSL_crypto.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_crypto.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_crypto.h; sourceTree = ""; }; + 92604BA8B45D91FC57F71A4527FCCEF3 /* BloctoSDK-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "BloctoSDK-Info.plist"; sourceTree = ""; }; + 9263A27F2368160D48F5D8D39811F5C6 /* ByteCollectionUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ByteCollectionUtils.swift; path = Sources/NIOHTTP1/ByteCollectionUtils.swift; sourceTree = ""; }; + 926ADA1DC1706FBE131060E6C9790423 /* pem_all.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_all.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_all.c; sourceTree = ""; }; + 926E439F468CB0725B600E917A8FD131 /* print.c */ = {isa = PBXFileReference; includeInIndex = 1; name = print.c; path = Sources/CNIOBoringSSL/crypto/evp/print.c; sourceTree = ""; }; + 9291ACAD1464AAA4A7957FAAFB7D197B /* Multiplication.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Multiplication.swift; path = Sources/Multiplication.swift; sourceTree = ""; }; + 92E357F294D6449E154AA957032191D4 /* tasn_utl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_utl.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_utl.c; sourceTree = ""; }; + 92F1410EB55386BE15D50D734605E346 /* Argument.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Argument.swift; path = Sources/Cadence/Argument.swift; sourceTree = ""; }; + 93284C051CD0D2398503282372E442D9 /* SDAnimatedImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "SDAnimatedImageView+WebCache.m"; path = "SDWebImage/Core/SDAnimatedImageView+WebCache.m"; sourceTree = ""; }; + 932928A2279109486F3A16C66E4D61F8 /* Cadence */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Cadence; path = Cadence.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 933FDBA513463FAC642AF22F11B680FC /* handshake_client.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = handshake_client.cc; path = Sources/CNIOBoringSSL/ssl/handshake_client.cc; sourceTree = ""; }; + 9352F8CAFC6537ACBAAB22D0AE728CCE /* RequestResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestResponseHandler.swift; path = Sources/NIOExtras/RequestResponseHandler.swift; sourceTree = ""; }; + 9353F679479027B35261BCF58CD26951 /* CNIOBoringSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOBoringSSL.debug.xcconfig; sourceTree = ""; }; + 936C01B367E6C83629C332BC641FE4EF /* FCLDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FCLDelegate.swift; path = "Sources/FCL-SDK/FCLDelegate.swift"; sourceTree = ""; }; + 93AEA077B5B2D1CE26978A40A245BF92 /* hmac.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hmac.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/hmac/hmac.c; sourceTree = ""; }; + 93E4422CDED7F1D4227B7E5D322F43C1 /* x509_lu.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_lu.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_lu.c; sourceTree = ""; }; + 93F0AD3ADAD0EFBF6747866F9AD34681 /* MercariQRScanner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MercariQRScanner.debug.xcconfig; sourceTree = ""; }; + 940CC6D29A4972AD85F8265F8E5AF468 /* x_algor.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_algor.c; path = Sources/CNIOBoringSSL/crypto/x509/x_algor.c; sourceTree = ""; }; + 943D347E61A2E181A4FA2CA894307B6E /* SwiftProtobuf */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftProtobuf; path = SwiftProtobuf.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 947D727E23A36EA2E057AA2043E55414 /* forkunsafe.c */ = {isa = PBXFileReference; includeInIndex = 1; name = forkunsafe.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/forkunsafe.c; sourceTree = ""; }; + 94C03FF593B078886C1EE15A3B66FDF9 /* CNIOWindows.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOWindows.h; path = Sources/CNIOWindows/include/CNIOWindows.h; sourceTree = ""; }; + 94C91FA15C4D33D1B7E9559142748045 /* Resolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resolver.swift; path = Sources/NIOPosix/Resolver.swift; sourceTree = ""; }; + 94DB78A6514187DF8BD31B5992CFDB04 /* AddressReplacement.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AddressReplacement.swift; path = "Sources/FCL-SDK/Config/AddressReplacement.swift"; sourceTree = ""; }; + 94F227685ECEAB7343AD33F83D2C1A38 /* BinaryDecodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDecodingError.swift; path = Sources/SwiftProtobuf/BinaryDecodingError.swift; sourceTree = ""; }; + 95006D59F8C11B65CE508C1BE5751A46 /* p256_beeu-x86_64-asm.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256_beeu-x86_64-asm.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-x86_64-asm.linux.x86_64.S"; sourceTree = ""; }; + 95894A8F7B6DAE981F5165BE4F2EE40A /* SDGraphicsImageRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDGraphicsImageRenderer.h; path = SDWebImage/Core/SDGraphicsImageRenderer.h; sourceTree = ""; }; + 962796D624989567A469AD221C8F317C /* Voucher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Voucher.swift; path = "Sources/FCL-SDK/Models/Voucher.swift"; sourceTree = ""; }; + 965C295B24640A3C38DFFA48A87550C3 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/md5/internal.h; sourceTree = ""; }; + 966B4887F9DD9CD0ACCE62DE15BB14E3 /* SDWebImageDownloaderOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderOperation.h; path = SDWebImage/Core/SDWebImageDownloaderOperation.h; sourceTree = ""; }; + 968977F2912D1CEA6A50A6AEBE7039B9 /* cfb.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cfb.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cfb.c; sourceTree = ""; }; + 96B043DDB45818671A86CC424B821B2D /* GRPCServerRequestRoutingHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCServerRequestRoutingHandler.swift; path = Sources/GRPC/GRPCServerRequestRoutingHandler.swift; sourceTree = ""; }; + 96D40FDB9D0E9C588AB0A7978B159390 /* CNIOHTTPParser-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOHTTPParser-umbrella.h"; sourceTree = ""; }; + 96EE5B32A454B7CC397B5C934856843C /* SDImageAPNGCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAPNGCoder.h; path = SDWebImage/Core/SDImageAPNGCoder.h; sourceTree = ""; }; + 96EF442F0D881078905BD87375142326 /* Division.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Division.swift; path = Sources/Division.swift; sourceTree = ""; }; + 96FB297C04A70F53F4B0206297549C27 /* Account.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Account.swift; path = Sources/FlowSDK/Models/Account.swift; sourceTree = ""; }; + 970DE3CF94367649A0C1037F78DE8966 /* aesv8-armx64.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesv8-armx64.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx64.linux.aarch64.S"; sourceTree = ""; }; + 9711B7C6751DB7169E30AC2344DEFFBD /* sha512.c */ = {isa = PBXFileReference; includeInIndex = 1; name = sha512.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha512.c; sourceTree = ""; }; + 97360CE18256061D39011474972E0C90 /* CGRPCZlibp-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CGRPCZlibp-prefix.pch"; sourceTree = ""; }; + 9748CE6DBD4F6B5C7299576A07341672 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; }; + 9749E5B1C62EFA9B15CB3B561D4A3F43 /* sha1-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-586.linux.x86.S"; sourceTree = ""; }; + 978ED63145A5D349DC34780FDD0A8CC6 /* x509_att.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_att.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_att.c; sourceTree = ""; }; + 97EDFC1B66D01A1233C83AA13E6C3E34 /* FCL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FCL.swift; path = "Sources/FCL-SDK/FCL.swift"; sourceTree = ""; }; + 980C4FDA16712B01699898BC0D207423 /* ConnectionPool+PerConnectionState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConnectionPool+PerConnectionState.swift"; path = "Sources/GRPC/ConnectionPool/ConnectionPool+PerConnectionState.swift"; sourceTree = ""; }; + 9822C50FBD93EA3721F13BD2B0A8B553 /* sha512-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.ios.aarch64.S"; sourceTree = ""; }; + 98CFC661373BA9730BCC13E2E1F61B8E /* MessageEncodingHeaderValidator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageEncodingHeaderValidator.swift; path = Sources/GRPC/MessageEncodingHeaderValidator.swift; sourceTree = ""; }; + 98F5C5815636CC2CDB148C52AC2D5275 /* liburing_shims.c */ = {isa = PBXFileReference; includeInIndex = 1; name = liburing_shims.c; path = Sources/CNIOLinux/liburing_shims.c; sourceTree = ""; }; + 9910BBE166BD1E89E9E12DC90492F787 /* FlowSDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlowSDK.debug.xcconfig; sourceTree = ""; }; + 991BC180A5163AA7D7212862738DAD7E /* Google_Protobuf_NullValue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_NullValue+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift"; sourceTree = ""; }; + 99397EBD2713FC0B5C926E662DB36B29 /* rsa.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rsa.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/rsa.c; sourceTree = ""; }; + 993A1317DC22F99DF8A87D2BEF94AEA3 /* p256-nistz.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256-nistz.c"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.c"; sourceTree = ""; }; + 994D43AD3904B05EB0ED69E59CD860AE /* UIImageView+Calculations.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImageView+Calculations.swift"; path = "PopupDialog/Classes/UIImageView+Calculations.swift"; sourceTree = ""; }; + 9975BCDF9C13EAC1086E49406AF9586E /* urandom.c */ = {isa = PBXFileReference; includeInIndex = 1; name = urandom.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/urandom.c; sourceTree = ""; }; + 9992AD91E5BD44D3B71483530B7FB33A /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/des/internal.h; sourceTree = ""; }; + 99A84BF3728DC28D573570492FF1F6CB /* GRPCAsyncServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncServerHandler.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerHandler.swift; sourceTree = ""; }; + 99B7B5C6C7132BC4AE13670C71B1D319 /* a_int.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_int.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_int.c; sourceTree = ""; }; + 99C414B31E8A4D979898A38141A74B97 /* params.c */ = {isa = PBXFileReference; includeInIndex = 1; name = params.c; path = Sources/CNIOBoringSSL/crypto/dh_extra/params.c; sourceTree = ""; }; + 99DB7853515659BF0940D0DB249CF962 /* x509_req.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_req.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_req.c; sourceTree = ""; }; + 9A6AE05284A13FEEC2B201DA0DF6196D /* cbs.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cbs.c; path = Sources/CNIOBoringSSL/crypto/bytestring/cbs.c; sourceTree = ""; }; + 9A944D2C2A11F7534F950A9B6078ADAE /* BlurLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlurLayer.swift; path = Sources/DynamicBlurView/BlurLayer.swift; sourceTree = ""; }; + 9AB506C3FBAED9D5626B76F835294F30 /* CNIOBoringSSLShims-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOBoringSSLShims-prefix.pch"; sourceTree = ""; }; + 9AD2222DD9CD658D62F87B34C0342A0B /* SDImageCoderHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoderHelper.h; path = SDWebImage/Core/SDImageCoderHelper.h; sourceTree = ""; }; + 9AF08C7D22A2CD6829F32301D191B54A /* a_print.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_print.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_print.c; sourceTree = ""; }; + 9AFBF96323889F7EAF96656004366771 /* CNIOBoringSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOBoringSSL.release.xcconfig; sourceTree = ""; }; + 9B43C57C58784FCEFA2CBDEF283F75B0 /* CNIOBoringSSL_hmac.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_hmac.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_hmac.h; sourceTree = ""; }; + 9B5139FFF6FF1ED7F082529C640B4062 /* CNIOBoringSSL_buf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_buf.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_buf.h; sourceTree = ""; }; + 9B531A3455683AA7F96B0A480AA4F19F /* chacha-x86.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-x86.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-x86.linux.x86.S"; sourceTree = ""; }; + 9B5F437EC689DD66B48C952477347467 /* tls_record.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls_record.cc; path = Sources/CNIOBoringSSL/ssl/tls_record.cc; sourceTree = ""; }; + 9B8A53D6F6D367FC034837B1DD62A240 /* CNIOBoringSSLShims-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOBoringSSLShims-dummy.m"; sourceTree = ""; }; + 9B99006B4C7A31D6028CB7A585C1C322 /* CNIOAtomics-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOAtomics-prefix.pch"; sourceTree = ""; }; + 9C6471F8CAE3AF3E5255A97AE4A70BB0 /* UIWindowExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UIWindowExtension.swift; path = Sources/Core/Extensions/UIWindowExtension.swift; sourceTree = ""; }; + 9C8AFD4A17DAF112099B42485F0F640F /* empty.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = empty.pb.swift; path = Sources/SwiftProtobuf/empty.pb.swift; sourceTree = ""; }; + 9CF1A1E10AFB8B8835880E65401C2DD9 /* AEADChaCha20Poly1305.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AEADChaCha20Poly1305.swift; path = Sources/CryptoSwift/AEAD/AEADChaCha20Poly1305.swift; sourceTree = ""; }; + 9CF3A537CCBB4F47740B588DBC13AF75 /* FlowSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlowSDK.release.xcconfig; sourceTree = ""; }; + 9D0ED1ECFBE441E1197964BD40E28F12 /* SingleValueDecodingContainerExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleValueDecodingContainerExtension.swift; path = Sources/Cadence/Extensions/SingleValueDecodingContainerExtension.swift; sourceTree = ""; }; + 9D231FBD70C9601052E3C08B6E0B3C1A /* secp256k1Swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = secp256k1Swift.release.xcconfig; sourceTree = ""; }; + 9D7E805F18D220B2496E7ED497D891F6 /* BloctoSDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BloctoSDK.debug.xcconfig; sourceTree = ""; }; + 9D80CD66E9C87158F6F5D67AFFED62EB /* ByteBuffer-conversions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-conversions.swift"; path = "Sources/NIOCore/ByteBuffer-conversions.swift"; sourceTree = ""; }; + 9D8AC108A683453F882A65E63ACBC007 /* conf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = conf.c; path = Sources/CNIOBoringSSL/crypto/conf/conf.c; sourceTree = ""; }; + 9D925DD409F2D414D1714BB5A5CA7B35 /* CNIOBoringSSL_buffer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_buffer.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_buffer.h; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9DA374C9FE3135CF0B453A8C5F2DB723 /* SDWebImageOptionsProcessor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageOptionsProcessor.m; path = SDWebImage/Core/SDWebImageOptionsProcessor.m; sourceTree = ""; }; + 9DD497DF7646EFCA903C73201E6D5128 /* fork_detect.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = fork_detect.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/fork_detect.h; sourceTree = ""; }; + 9DF64CD5C8E782FFABAFC4FF7AAF64C5 /* CNIOBoringSSL_aes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_aes.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_aes.h; sourceTree = ""; }; + 9DF6F34E0C0955CF1A878FF94E52AFE0 /* HTTPDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPDecoder.swift; path = Sources/NIOHTTP1/HTTPDecoder.swift; sourceTree = ""; }; + 9E2F291C8EAA7B8A3F81A388D7280711 /* eckey_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = eckey_impl.h; path = src/eckey_impl.h; sourceTree = ""; }; + 9E6C571B78A8486423E82B83B20305F2 /* rdrand-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "rdrand-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.mac.x86_64.S"; sourceTree = ""; }; + 9E786D76B785BDCE148B66B3149FCA4D /* sha256-armv4.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-armv4.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv4.ios.arm.S"; sourceTree = ""; }; + 9ECEA2B23797D093DC1226DA47AB8BBA /* field_10x26.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_10x26.h; path = src/field_10x26.h; sourceTree = ""; }; + 9F03CB0E6217D65140886F475B1AA61A /* Digest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Digest.swift; path = "Sources/swift-crypto/Sources/Crypto/Digests/Digest.swift"; sourceTree = ""; }; + 9F057B73B6702566A18F973839B10FF7 /* sha256-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-armv8.linux.aarch64.S"; sourceTree = ""; }; + 9F05A1BDA04C07B42D1D50DF121E7DEF /* PendingDatagramWritesManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PendingDatagramWritesManager.swift; path = Sources/NIOPosix/PendingDatagramWritesManager.swift; sourceTree = ""; }; + 9F399A7791A91BD8ADEC576869E71837 /* SwiftNIOConcurrencyHelpers.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOConcurrencyHelpers.modulemap; sourceTree = ""; }; + 9F44F5EF9CCF2E1F401C612C898A6846 /* rdrand-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "rdrand-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/rdrand-x86_64.linux.x86_64.S"; sourceTree = ""; }; + 9F6EBFDC467B069F2BB9F8A08DF9115F /* UnaryCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnaryCall.swift; path = Sources/GRPC/ClientCalls/UnaryCall.swift; sourceTree = ""; }; + 9F9E6E4E43E58A87D73434E991B0450D /* DatagramVectorReadManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DatagramVectorReadManager.swift; path = Sources/NIOPosix/DatagramVectorReadManager.swift; sourceTree = ""; }; + 9FB260E0E9462A69EC446102C7E8886E /* vpaes-x86.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-x86.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-x86.linux.x86.S"; sourceTree = ""; }; + 9FC28474AB6F09E4815ADBE0B747B4C5 /* CustomJSONCodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CustomJSONCodable.swift; path = Sources/SwiftProtobuf/CustomJSONCodable.swift; sourceTree = ""; }; + 9FDB1BE639E6732DC1AA91B4160FC16A /* CGImage+Accelerate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CGImage+Accelerate.swift"; path = "Sources/DynamicBlurView/CGImage+Accelerate.swift"; sourceTree = ""; }; + A0012700C73B952EE683DE5A28FD938A /* KeyedDecodingContainerProtocolExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyedDecodingContainerProtocolExtension.swift; path = Sources/Cadence/Extensions/KeyedDecodingContainerProtocolExtension.swift; sourceTree = ""; }; + A00E16AE69A03C3643B9534FCF13263C /* SwiftNIOCore */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOCore; path = NIOCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A01EEE5EB6F8BB3C30D2412EF6E4A8DB /* curve25519.c */ = {isa = PBXFileReference; includeInIndex = 1; name = curve25519.c; path = Sources/CNIOBoringSSL/crypto/curve25519/curve25519.c; sourceTree = ""; }; + A08951CD09B134E4455D285B4E199637 /* SwiftyJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftyJSON.swift; path = Source/SwiftyJSON/SwiftyJSON.swift; sourceTree = ""; }; + A0C50F65C6376FDAC08630DD26C4B513 /* FlowAccountProofData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlowAccountProofData.swift; path = Sources/Flow/Models/FlowAccountProofData.swift; sourceTree = ""; }; + A0D220C80433E4283F2163A55CA822A3 /* x_val.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x_val.c; path = Sources/CNIOBoringSSL/crypto/x509/x_val.c; sourceTree = ""; }; + A0D58A6E75C6E7F360A35D31ED3E1962 /* DecompressionLimit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DecompressionLimit.swift; path = Sources/GRPC/Compression/DecompressionLimit.swift; sourceTree = ""; }; + A10F5D694C319F02E04D2C36464713C3 /* CGRPCZlibp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CGRPCZlibp-dummy.m"; sourceTree = ""; }; + A1125F1577E36499C027A5A9272733CD /* ecmult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult.h; path = src/ecmult.h; sourceTree = ""; }; + A1590218E00A6F2E93D7E8640D81887C /* access.grpc.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = access.grpc.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/access/access.grpc.swift; sourceTree = ""; }; + A18A2EEDDFBCBE87D6F005B10DB418F5 /* SwiftNIOHPACK-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOHPACK-dummy.m"; sourceTree = ""; }; + A1969EB0465C0CAEFE0141F3491D7F5F /* PointerHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PointerHelpers.swift; path = Sources/NIOPosix/PointerHelpers.swift; sourceTree = ""; }; + A1BEA579A59439676E2AA53871A081BA /* Block.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Block.swift; path = Sources/FlowSDK/Models/Block.swift; sourceTree = ""; }; + A1C640988E3E214D1F511AD59B5086A3 /* NSBezierPath+SDRoundedCorners.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSBezierPath+SDRoundedCorners.h"; path = "SDWebImage/Private/NSBezierPath+SDRoundedCorners.h"; sourceTree = ""; }; + A230DA09837C434CE63C8CEC8CB6FB07 /* hash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = hash.h; path = src/hash.h; sourceTree = ""; }; + A263437A804DE2A19CE442E5E628CE9D /* SDWebImageOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageOperation.m; path = SDWebImage/Core/SDWebImageOperation.m; sourceTree = ""; }; + A2B6F66717F15163B79818319D00A6E0 /* obj_xref.c */ = {isa = PBXFileReference; includeInIndex = 1; name = obj_xref.c; path = Sources/CNIOBoringSSL/crypto/obj/obj_xref.c; sourceTree = ""; }; + A2C5C802B3FDA538AA688E471C10BA99 /* hexdump.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hexdump.c; path = Sources/CNIOBoringSSL/crypto/bio/hexdump.c; sourceTree = ""; }; + A2E0761EDC7027047AA1C390EB7873F5 /* DelegatingErrorHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegatingErrorHandler.swift; path = Sources/GRPC/DelegatingErrorHandler.swift; sourceTree = ""; }; + A2E4F913CC7AD04D77905B6175B9E551 /* QueryDecoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QueryDecoding.swift; path = Sources/Core/Utilities/QueryDecoding.swift; sourceTree = ""; }; + A3380E0461C012878D8D0A4F5D15812C /* UIImage+MultiFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+MultiFormat.h"; path = "SDWebImage/Core/UIImage+MultiFormat.h"; sourceTree = ""; }; + A339F6C2B3057C4FEB959D08FD97D501 /* WalletProviderSelectionViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WalletProviderSelectionViewController.swift; path = "Sources/FCL-SDK/WalletProviderSelectionViewController.swift"; sourceTree = ""; }; + A3446BB29394B0DCC0BCF77E214CF218 /* ghash-ssse3-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-ssse3-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-ssse3-x86_64.linux.x86_64.S"; sourceTree = ""; }; + A3786BF0BD05B585EE84F25EED9031FA /* trust_token.c */ = {isa = PBXFileReference; includeInIndex = 1; name = trust_token.c; path = Sources/CNIOBoringSSL/crypto/trust_token/trust_token.c; sourceTree = ""; }; + A3792872F4F7E79DED08D802E38E942B /* SubjectAlternativeName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubjectAlternativeName.swift; path = Sources/NIOSSL/SubjectAlternativeName.swift; sourceTree = ""; }; + A38B7CA9A787A9EB473D611E8A8F23C8 /* SwiftNIO-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIO-umbrella.h"; sourceTree = ""; }; + A3B296B9B264741B05D9FCA4EA296817 /* poly1305.c */ = {isa = PBXFileReference; includeInIndex = 1; name = poly1305.c; path = Sources/CNIOBoringSSL/crypto/poly1305/poly1305.c; sourceTree = ""; }; + A3DFBFE8EDBE45EFA4304736E38C2792 /* v3_bcons.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_bcons.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_bcons.c; sourceTree = ""; }; + A3F40CFB0549042E755E3C6338B0A11C /* unicode.c */ = {isa = PBXFileReference; includeInIndex = 1; name = unicode.c; path = Sources/CNIOBoringSSL/crypto/bytestring/unicode.c; sourceTree = ""; }; + A495CC0169B4DE51BC42C5C9FD5C2B14 /* montgomery.c */ = {isa = PBXFileReference; includeInIndex = 1; name = montgomery.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/montgomery.c; sourceTree = ""; }; + A4AE6EBD52125EB64187C198B9998052 /* ConvenienceOptionSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConvenienceOptionSupport.swift; path = Sources/NIOCore/ConvenienceOptionSupport.swift; sourceTree = ""; }; + A4FBA4C5DC60851E041F493279C7BD17 /* CNIOHTTPParser.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOHTTPParser.release.xcconfig; sourceTree = ""; }; + A5537285A56608EC950F942013E870F2 /* LogHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LogHandler.swift; path = Sources/Logging/LogHandler.swift; sourceTree = ""; }; + A58374516B6E39546FBBB6E9BCC08E48 /* PopupDialogDefaultView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogDefaultView.swift; path = PopupDialog/Classes/PopupDialogDefaultView.swift; sourceTree = ""; }; + A5A2E804978DC1D481FCB239A99226BB /* Floating Point Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Floating Point Conversion.swift"; path = "Sources/Floating Point Conversion.swift"; sourceTree = ""; }; + A5AE57BE0D5EE76EFBABB44E2EA7B7A7 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/sha/internal.h; sourceTree = ""; }; + A5B1D4B342D8E17E058E8805C0793856 /* SDAnimatedImagePlayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImagePlayer.h; path = SDWebImage/Core/SDAnimatedImagePlayer.h; sourceTree = ""; }; + A5E983DC62177D36493A0A1614E01CD4 /* check.c */ = {isa = PBXFileReference; includeInIndex = 1; name = check.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/dh/check.c; sourceTree = ""; }; + A5F495CBF3D6A182B34EFB8EA2AFFA9A /* CNIOHTTPParser.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOHTTPParser.modulemap; sourceTree = ""; }; + A5F94CB3C154047CF825DEAEB6199D19 /* BlockEncryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockEncryptor.swift; path = Sources/CryptoSwift/BlockEncryptor.swift; sourceTree = ""; }; + A62A9516C784312B6E9DCF811BEFA843 /* SDAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImage.h; path = SDWebImage/Core/SDAnimatedImage.h; sourceTree = ""; }; + A64C1697F6315EE294F1C985C6E2FABB /* ReceivingWindowUpdateState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingWindowUpdateState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingWindowUpdateState.swift; sourceTree = ""; }; + A64E8EADE71F27E0A92CA03FB8C639E8 /* SwiftyJSON-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftyJSON-Info.plist"; sourceTree = ""; }; + A6513E0A6CB60623515716E73996F0F5 /* Logging */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Logging; path = Logging.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A6824E58803648F18F7ED3C2F1AACB45 /* NIOHTTPClientUpgradeHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOHTTPClientUpgradeHandler.swift; path = Sources/NIOHTTP1/NIOHTTPClientUpgradeHandler.swift; sourceTree = ""; }; + A69601E2C917D2C7F86620B14F5F6987 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/err/internal.h; sourceTree = ""; }; + A69622B5F3DF7E322BD0DB1E53CE75FF /* p256-armv8-asm.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256-armv8-asm.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S"; sourceTree = ""; }; + A69EBE0C9607A625092F94878F438ACB /* CNIOBoringSSL_cast.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_cast.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_cast.h; sourceTree = ""; }; + A69F7967829F2BA523BFAF89710C4A00 /* passive.c */ = {isa = PBXFileReference; includeInIndex = 1; name = passive.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/passive.c; sourceTree = ""; }; + A6AF4990B009B43367303C0DCA03D676 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+WebCache.m"; path = "SDWebImage/Core/UIImageView+WebCache.m"; sourceTree = ""; }; + A6E3511C4C20DBFBB77226B38065CDE9 /* Enum.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Enum.swift; path = Sources/SwiftProtobuf/Enum.swift; sourceTree = ""; }; + A718B5CE6BA2C99D08C87F557C7B2B5C /* x509_obj.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_obj.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_obj.c; sourceTree = ""; }; + A7797BD7095643FBB0149737059E66DD /* ClientInterceptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientInterceptors.swift; path = Sources/GRPC/Interceptor/ClientInterceptors.swift; sourceTree = ""; }; + A78B9E397FC3A26081AF8D0468C9A30A /* GRPCContentType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCContentType.swift; path = Sources/GRPC/GRPCContentType.swift; sourceTree = ""; }; + A7D48BA151B8DF7918DA4CB33BF04F76 /* UIImage+Metadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Metadata.m"; path = "SDWebImage/Core/UIImage+Metadata.m"; sourceTree = ""; }; + A80BC07600C31821C48FCBAE486DF89E /* LoggingServerErrorDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LoggingServerErrorDelegate.swift; path = Sources/GRPC/LoggingServerErrorDelegate.swift; sourceTree = ""; }; + A80C859888912E5732D63118F83ABA0F /* CGContext+CGImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CGContext+CGImage.swift"; path = "Sources/DynamicBlurView/CGContext+CGImage.swift"; sourceTree = ""; }; + A813103232F50456F6CFFDBD38743C19 /* chacha-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-armv8.ios.aarch64.S"; sourceTree = ""; }; + A86732BEBFBCA696599CF87443ACD0FE /* FlowSignatureType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlowSignatureType.swift; path = Sources/Flow/Models/FlowSignatureType.swift; sourceTree = ""; }; + A884FF8ED4F6B364A965586227FF7E39 /* ClientConnection+NWTLS.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ClientConnection+NWTLS.swift"; path = "Sources/GRPC/GRPCChannel/ClientConnection+NWTLS.swift"; sourceTree = ""; }; + A8865C07F40DEAC93D7F3F0AC0C36067 /* SwiftNIOExtras-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOExtras-Info.plist"; sourceTree = ""; }; + A8A6BA1B7B49FA8AAD4FD76EB06F865E /* DispatchQueue+WithFuture.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+WithFuture.swift"; path = "Sources/NIOCore/DispatchQueue+WithFuture.swift"; sourceTree = ""; }; + A8AC96E184F6A709EA24AD89B6A214CC /* delocate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = delocate.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/delocate.h; sourceTree = ""; }; + A8B4ED69E4AF1E48667B2065876C749F /* SDImageCachesManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCachesManager.h; path = SDWebImage/Core/SDImageCachesManager.h; sourceTree = ""; }; + A8C9B64804E5A4ED733B833205C732EB /* SDImageCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoder.m; path = SDWebImage/Core/SDImageCoder.m; sourceTree = ""; }; + A8D66AA126C6C94A62B4E3B3EC35645F /* engine.c */ = {isa = PBXFileReference; includeInIndex = 1; name = engine.c; path = Sources/CNIOBoringSSL/crypto/engine/engine.c; sourceTree = ""; }; + A8EEAE9099ADA7E88C6493D08089A3D4 /* SwiftNIOTLS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOTLS-prefix.pch"; sourceTree = ""; }; + A9396DDDD1A58F1D7F4FFD73D7B3E6B9 /* PCBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PCBC.swift; path = Sources/CryptoSwift/BlockMode/PCBC.swift; sourceTree = ""; }; + A9428F804A61917EC818A13B40631A27 /* FlowSDK-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlowSDK-umbrella.h"; sourceTree = ""; }; + A9AA60793268CDFDA0C0D0CF98F240AF /* SimpleExtensionMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SimpleExtensionMap.swift; path = Sources/SwiftProtobuf/SimpleExtensionMap.swift; sourceTree = ""; }; + A9CC3284E14BCF196DF7F1FC8A8C14B0 /* TLSConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TLSConfiguration.swift; path = Sources/NIOSSL/TLSConfiguration.swift; sourceTree = ""; }; + A9DCA49E1FFA9607497E9C6B8239270D /* precomputed_ecmult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = precomputed_ecmult.h; path = src/precomputed_ecmult.h; sourceTree = ""; }; + A9E372A470782C3F8A90B18E5E01C195 /* bsaes-armv7.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "bsaes-armv7.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.linux.arm.S"; sourceTree = ""; }; + A9E4C0FA477431EB8B424B3E86E6E278 /* Locks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Locks.swift; path = Sources/Logging/Locks.swift; sourceTree = ""; }; + A9F2E4DBBAAC82896230FA9EEF346638 /* HeaderTables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeaderTables.swift; path = Sources/NIOHPACK/HeaderTables.swift; sourceTree = ""; }; + AA22FB13720A6412E5E086ED932D06D8 /* CNIOBoringSSL_nid.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_nid.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_nid.h; sourceTree = ""; }; + AA57072C8406D072532BC8C000A532B1 /* timestamp.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = timestamp.pb.swift; path = Sources/SwiftProtobuf/timestamp.pb.swift; sourceTree = ""; }; + AA9914C500C20DDCE0CFE379E7AEB345 /* aes.c */ = {isa = PBXFileReference; includeInIndex = 1; name = aes.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes.c; sourceTree = ""; }; + AAB2156CD55FD16E3A95B4AC96E16738 /* BigUInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BigUInt.swift; path = Sources/CryptoSwift/CS_BigInt/BigUInt.swift; sourceTree = ""; }; + AB6A478D5EAD917E7F36CF45CEC70B84 /* ServerInterceptorStateMachine+Actions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerInterceptorStateMachine+Actions.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Actions.swift"; sourceTree = ""; }; + AB6E1F74F4BFA0885B4863B6C052B4F3 /* Singature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Singature.swift; path = "Sources/FCL-SDK/Models/Singature.swift"; sourceTree = ""; }; + AB71FD00DEB3A0ED199A7CF3CE0181B8 /* p_ec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_ec.c; path = Sources/CNIOBoringSSL/crypto/evp/p_ec.c; sourceTree = ""; }; + AB8849B3D92320B1D9361B58B46BC9E8 /* d1_both.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = d1_both.cc; path = Sources/CNIOBoringSSL/ssl/d1_both.cc; sourceTree = ""; }; + ABB9E9402F24F870985BDAADA6EF464D /* secp256k1Wrapper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "secp256k1Wrapper-Info.plist"; sourceTree = ""; }; + ABCC4970C4B371898F3166186E6F9B0E /* TLSEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TLSEvents.swift; path = Sources/NIOTLS/TLSEvents.swift; sourceTree = ""; }; + ABCDF59FB62F7013BA9A97B7F0EAD7E4 /* ghashv8-armx32.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghashv8-armx32.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghashv8-armx32.ios.arm.S"; sourceTree = ""; }; + ABF3045DB54F2F18DE8E2856CF02D59B /* tasn_fre.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_fre.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_fre.c; sourceTree = ""; }; + AC3568EAA3220005786354D1B8DCCA50 /* SendFlowTransactionMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendFlowTransactionMethod.swift; path = Sources/Flow/Methods/SendFlowTransactionMethod.swift; sourceTree = ""; }; + ACBF6340035E1DD58EA9E0188DD22824 /* SDWebImageDownloaderRequestModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderRequestModifier.m; path = SDWebImage/Core/SDWebImageDownloaderRequestModifier.m; sourceTree = ""; }; + ACC40784851EB756A9CB882A545B72DD /* Cadence-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Cadence-Info.plist"; sourceTree = ""; }; + ACC4D4A7F4A5D8085AC922873268066C /* SelectorGeneric.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SelectorGeneric.swift; path = Sources/NIOPosix/SelectorGeneric.swift; sourceTree = ""; }; + AD1003EB741271BB093E74D64F323A92 /* p256_64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = p256_64.h; path = Sources/CNIOBoringSSL/third_party/fiat/p256_64.h; sourceTree = ""; }; + AD1453B26707E3BBFCC6A2E2380775C7 /* ClientStreamingServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientStreamingServerHandler.swift; path = Sources/GRPC/CallHandlers/ClientStreamingServerHandler.swift; sourceTree = ""; }; + AD1A3DE715CE103B04510EBCCB7557F5 /* mode_wrappers.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mode_wrappers.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/aes/mode_wrappers.c; sourceTree = ""; }; + AD399753F135626CB1495DD19609C932 /* gcd_extra.c */ = {isa = PBXFileReference; includeInIndex = 1; name = gcd_extra.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/gcd_extra.c; sourceTree = ""; }; + AD97C485447932CFD80DAB09622E758C /* v3_ocsp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_ocsp.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_ocsp.c; sourceTree = ""; }; + ADB47706A4A069D6173C880CA9EEC239 /* Logging-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Logging-dummy.m"; sourceTree = ""; }; + ADBA815F54C9D0EBF6960A6A7CBB4C5A /* e_rc4.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_rc4.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc4.c; sourceTree = ""; }; + ADCA520ECD233B494FD505EBE481F731 /* s3_both.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = s3_both.cc; path = Sources/CNIOBoringSSL/ssl/s3_both.cc; sourceTree = ""; }; + ADF1451E76D53D6923B25ECAB4EFEC04 /* md5-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "md5-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.linux.x86_64.S"; sourceTree = ""; }; + ADF6487B52236A319DE826891AC0CC05 /* ssl_cipher.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_cipher.cc; path = Sources/CNIOBoringSSL/ssl/ssl_cipher.cc; sourceTree = ""; }; + AE3210440188F385CA13711590591E66 /* SwiftNIOHTTP2.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOHTTP2.modulemap; sourceTree = ""; }; + AE3E45F8F49AC7440A4DFBF42F1526E8 /* FCL-SDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "FCL-SDK.release.xcconfig"; sourceTree = ""; }; + AE7382BF76136F84B7A70C79D72F7E1A /* main_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = main_impl.h; path = src/modules/ecdh/main_impl.h; sourceTree = ""; }; + AE87F53AE675706680F530C168F294E6 /* IntegerCoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerCoding.swift; path = Sources/NIOHPACK/IntegerCoding.swift; sourceTree = ""; }; + AEA9286C59806AD1E11E2FD5B9F90733 /* PopupDialog-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PopupDialog-dummy.m"; sourceTree = ""; }; + AEAD05B47CB8D574AC08834631342C19 /* CNIOBoringSSL_pkcs8.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_pkcs8.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_pkcs8.h; sourceTree = ""; }; + AF2F71AF6DDAF0DB59F19D7CE5D44651 /* HTTP2FrameEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2FrameEncoder.swift; path = Sources/NIOHTTP2/HTTP2FrameEncoder.swift; sourceTree = ""; }; + AF8DDEA73D7A9A0D0BB5BE9F00FE3CA8 /* tls13_enc.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = tls13_enc.cc; path = Sources/CNIOBoringSSL/ssl/tls13_enc.cc; sourceTree = ""; }; + AF99873D68B73F324125054CD5617835 /* NIOTSChannelOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSChannelOptions.swift; path = Sources/NIOTransportServices/NIOTSChannelOptions.swift; sourceTree = ""; }; + AFAE696FD8F13F560F24B8FA0116127B /* GRPCAsyncClientStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncClientStreamingCall.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncClientStreamingCall.swift; sourceTree = ""; }; + AFB49AEFC8709DEE496D85E1E049F85D /* IntegerBitPacking.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerBitPacking.swift; path = Sources/NIOCore/IntegerBitPacking.swift; sourceTree = ""; }; + AFB519F2A9DF09C595E0186FDD032F11 /* p256-nistz.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "p256-nistz.h"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ec/p256-nistz.h"; sourceTree = ""; }; + AFC2B42DF489B79BF57DDBF4A56453EC /* buf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = buf.c; path = Sources/CNIOBoringSSL/crypto/buf/buf.c; sourceTree = ""; }; + B00141CED0B13A8AB80467697980865F /* SwiftNIOHTTP2.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHTTP2.debug.xcconfig; sourceTree = ""; }; + B03BD8B7CDD44609147E2976B328A423 /* Cryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cryptor.swift; path = Sources/CryptoSwift/Cryptor.swift; sourceTree = ""; }; + B0732CFBADE6259ACDF883CC16830835 /* GRPCSendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCSendable.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCSendable.swift; sourceTree = ""; }; + B07B933388A168E64FC702F045725314 /* SwiftNIOCore.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOCore.modulemap; sourceTree = ""; }; + B087EA2FA49AD39D579628C77C4DF597 /* Path.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Path.swift; path = Sources/Cadence/Path.swift; sourceTree = ""; }; + B08C0844D183BD82AD0C9ED81AA99268 /* BloctoFlowSDK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BloctoFlowSDK.swift; path = Sources/Flow/BloctoFlowSDK.swift; sourceTree = ""; }; + B0A22926820729A8784C92EA32D61569 /* SocketAddress+NWEndpoint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SocketAddress+NWEndpoint.swift"; path = "Sources/NIOTransportServices/SocketAddress+NWEndpoint.swift"; sourceTree = ""; }; + B0B214D775196BA7CA8E17E53048A493 /* SDWebImage */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SDWebImage; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B0E148C89286FC10D58812BF0310AC2E /* gcm_nohw.c */ = {isa = PBXFileReference; includeInIndex = 1; name = gcm_nohw.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/gcm_nohw.c; sourceTree = ""; }; + B136E798B4E73E57A5A5FCC779C6FF2D /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/internal.h; sourceTree = ""; }; + B13ECBBEA21F99BFECD0DD09E5C0B7A0 /* CNIODarwin-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIODarwin-dummy.m"; sourceTree = ""; }; + B14752CF2FF865DF39649F33F07C77C7 /* TextFormatEncodingVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatEncodingVisitor.swift; path = Sources/SwiftProtobuf/TextFormatEncodingVisitor.swift; sourceTree = ""; }; + B1B2FF5011F1F0B315552B06B8F31887 /* SDImageCoderHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageCoderHelper.m; path = SDWebImage/Core/SDImageCoderHelper.m; sourceTree = ""; }; + B1D31E813551E4238174131DCA97F395 /* v3_alt.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_alt.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_alt.c; sourceTree = ""; }; + B1DBE2A6527A0E5F9B151446A402E14F /* ThreadPosix.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadPosix.swift; path = Sources/NIOPosix/ThreadPosix.swift; sourceTree = ""; }; + B1E390FCD5668D1ADFB9CCBEEADDA960 /* bench.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = bench.h; path = src/bench.h; sourceTree = ""; }; + B24040089D9C5D78D870471EDDA24BEA /* UIImageView+HighlightedWebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+HighlightedWebCache.m"; path = "SDWebImage/Core/UIImageView+HighlightedWebCache.m"; sourceTree = ""; }; + B26E310C45322A4ED4AA8FDA6189BB58 /* InitializerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InitializerType.swift; path = Sources/Cadence/CType/InitializerType.swift; sourceTree = ""; }; + B30C1C5FE90BD3E1CDC3E1AC3FE3A35C /* UIImage+MemoryCacheCost.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+MemoryCacheCost.m"; path = "SDWebImage/Core/UIImage+MemoryCacheCost.m"; sourceTree = ""; }; + B3895C65A6C586BC934F80C6B7ABD6D8 /* FlowSDK-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlowSDK-prefix.pch"; sourceTree = ""; }; + B39357A8BA62A1DE32E48810C6BE4632 /* SDWebImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.release.xcconfig; sourceTree = ""; }; + B39945BEE0BA25547BEE869FDD63873F /* execution_result.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = execution_result.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/execution_result.pb.swift; sourceTree = ""; }; + B3AC106B742111DE087FA7B87A523B68 /* e_aesccm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_aesccm.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesccm.c; sourceTree = ""; }; + B3DE27288C920D21A42D6701815B7EF7 /* LazyEventLoopPromise.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LazyEventLoopPromise.swift; path = Sources/GRPC/ClientCalls/LazyEventLoopPromise.swift; sourceTree = ""; }; + B3E9CEFF47F7C6B77BF71C3804FAC888 /* HTTP2Stream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2Stream.swift; path = Sources/NIOHTTP2/HTTP2Stream.swift; sourceTree = ""; }; + B43ABA1E2D7A98863CDB143A0D955ABF /* StateManagedChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StateManagedChannel.swift; path = Sources/NIOTransportServices/StateManagedChannel.swift; sourceTree = ""; }; + B495EFFA32E7E62E2FD0AB0F689098A6 /* GRPCChannel+AsyncAwaitSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "GRPCChannel+AsyncAwaitSupport.swift"; path = "Sources/GRPC/AsyncAwaitSupport/GRPCChannel+AsyncAwaitSupport.swift"; sourceTree = ""; }; + B4A308418216D636E99E558FCF77305E /* SecureBytes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecureBytes.swift; path = Sources/CryptoSwift/SecureBytes.swift; sourceTree = ""; }; + B4B9BFDE2AB7150122CE94F7D3061F88 /* ExtensionFieldValueSet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionFieldValueSet.swift; path = Sources/SwiftProtobuf/ExtensionFieldValueSet.swift; sourceTree = ""; }; + B55D91D9519BCE3F60C8F6510F17EB0B /* SignatureAlgorithm.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SignatureAlgorithm.swift; path = Sources/FlowSDK/Crypto/SignatureAlgorithm.swift; sourceTree = ""; }; + B56553376B99AF7775384AC1BA59FEB9 /* Blockchain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Blockchain.swift; path = Sources/Core/Models/Blockchain.swift; sourceTree = ""; }; + B56C4BF02503F348797EF44D132B4F5D /* _NIODataStructures-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "_NIODataStructures-umbrella.h"; sourceTree = ""; }; + B56C4BFD62C8CCE18637535CF0A76FF2 /* MultiThreadedEventLoopGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultiThreadedEventLoopGroup.swift; path = Sources/NIOPosix/MultiThreadedEventLoopGroup.swift; sourceTree = ""; }; + B57C4375ED9A8C93CC09EE54BB969BC0 /* ServerInterceptorStateMachine+Finished.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerInterceptorStateMachine+Finished.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Finished.swift"; sourceTree = ""; }; + B58B678C9D1B0BF85162F3EE8B1619F0 /* x86-mont.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86-mont.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/x86-mont.linux.x86.S"; sourceTree = ""; }; + B5A245C7712673F309BB6780D129E133 /* curve25519_tables.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = curve25519_tables.h; path = Sources/CNIOBoringSSL/crypto/curve25519/curve25519_tables.h; sourceTree = ""; }; + B5A65A501924E6053568C1E8BAC3675B /* GRPCAsyncResponseStream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncResponseStream.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStream.swift; sourceTree = ""; }; + B5F2C1A9AB12ADED76780A6D05E37119 /* Bit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bit.swift; path = Sources/CryptoSwift/Bit.swift; sourceTree = ""; }; + B5FEBD4F255A8CA1957B51619B8FE6AD /* v3_enum.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_enum.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_enum.c; sourceTree = ""; }; + B6014095D840DACF4EF8FF2531E2E542 /* PresentationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PresentationController.swift; path = PopupDialog/Classes/PresentationController.swift; sourceTree = ""; }; + B611E01AE9F71F3596A643A7D2A421C0 /* Shifts.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Shifts.swift; path = Sources/CryptoSwift/CS_BigInt/Shifts.swift; sourceTree = ""; }; + B61CDA0D8685E7D3CD7FE1286FFFEC4F /* ByteBuffer-foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ByteBuffer-foundation.swift"; path = "Sources/NIOFoundationCompat/ByteBuffer-foundation.swift"; sourceTree = ""; }; + B64F7DA6E0B11E2AB6D1CFBF2BB4CBC8 /* FileRegion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FileRegion.swift; path = Sources/NIOCore/FileRegion.swift; sourceTree = ""; }; + B659A48694C1451AC56E4764DE043F7A /* CNIOBoringSSL_bytestring.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_bytestring.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_bytestring.h; sourceTree = ""; }; + B676A8CC6D7A55B9F2330EFF0F439AE6 /* ssl_session.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_session.cc; path = Sources/CNIOBoringSSL/ssl/ssl_session.cc; sourceTree = ""; }; + B6B28CE17861BCF5E0A2ABD21781EAB3 /* SwiftNIOExtras-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOExtras-umbrella.h"; sourceTree = ""; }; + B6C53E0C38272AE6FA2E8E5C35C9046A /* x509rset.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509rset.c; path = Sources/CNIOBoringSSL/crypto/x509/x509rset.c; sourceTree = ""; }; + B6FB4210C8AC0D95761859E27284052F /* Pods-fanex-fanexUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanex-fanexUITests.debug.xcconfig"; sourceTree = ""; }; + B70B5A4EC9A2152DEE80BCF8F5BADA95 /* RLPDecodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPDecodingError.swift; path = Sources/FlowSDK/RLP/RLPDecodingError.swift; sourceTree = ""; }; + B71DB02A1F498F92F0D682A10F39B7CA /* SingleStepByteToMessageDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleStepByteToMessageDecoder.swift; path = Sources/NIOCore/SingleStepByteToMessageDecoder.swift; sourceTree = ""; }; + B76FE45529FA7930D3992ADBA1E05047 /* Network.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Network.swift; path = Sources/FlowSDK/Network.swift; sourceTree = ""; }; + B7F86C258B6E7E7D3579567A28EB94E0 /* ServerHandlerStateMachine+Finished.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerHandlerStateMachine+Finished.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Finished.swift"; sourceTree = ""; }; + B8096BA9AEAAB47DDD31DAA0036E2CED /* SDImageIOAnimatedCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageIOAnimatedCoder.m; path = SDWebImage/Core/SDImageIOAnimatedCoder.m; sourceTree = ""; }; + B82CC6E59C710C9A479CED04F6EE1953 /* Message+BinaryAdditions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Message+BinaryAdditions.swift"; path = "Sources/SwiftProtobuf/Message+BinaryAdditions.swift"; sourceTree = ""; }; + B87A50A9B5D40943EDCE15F73F41D23A /* CNIOLinux-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOLinux-umbrella.h"; sourceTree = ""; }; + B87EE4554627E69785104159E7BA5F42 /* BidirectionalStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BidirectionalStreamingCall.swift; path = Sources/GRPC/ClientCalls/BidirectionalStreamingCall.swift; sourceTree = ""; }; + B8AA754EBAFF03CB7D0D93E72C524C95 /* SwiftNIO-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIO-Info.plist"; sourceTree = ""; }; + B8C7F2C73FC7C012E942EED296C5EFE2 /* BaseStreamSocketChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseStreamSocketChannel.swift; path = Sources/NIOPosix/BaseStreamSocketChannel.swift; sourceTree = ""; }; + B8F6E98384A8607B14786C60260DA7E7 /* EnumType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumType.swift; path = Sources/Cadence/CType/EnumType.swift; sourceTree = ""; }; + B92046FCE952E070444772F0017A14D5 /* CNIOBoringSSLShims.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOBoringSSLShims.release.xcconfig; sourceTree = ""; }; + B973EA967343AFC1DF901B6918C7E1D3 /* sha1-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv8.linux.aarch64.S"; sourceTree = ""; }; + B9777D2A1685333BBF468EFCD3584A40 /* _NIODataStructures.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = _NIODataStructures.debug.xcconfig; sourceTree = ""; }; + B97E78A3E74437B8A21A71DCF55F9849 /* GRPCStatusMessageMarshaller.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCStatusMessageMarshaller.swift; path = Sources/GRPC/GRPCStatusMessageMarshaller.swift; sourceTree = ""; }; + B98D59B2FC57B2209A63E822B13AA4C3 /* StreamChannelList.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamChannelList.swift; path = Sources/NIOHTTP2/StreamChannelList.swift; sourceTree = ""; }; + B99B18B8997A3B27982F4A265CE6B365 /* api.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = api.pb.swift; path = Sources/SwiftProtobuf/api.pb.swift; sourceTree = ""; }; + B9C19433ED23297D0104677C4BBD09CA /* SDImageGraphics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGraphics.h; path = SDWebImage/Core/SDImageGraphics.h; sourceTree = ""; }; + B9F05E2FE7977D3C097CFCCD3D8F4C2C /* e_aesctrhmac.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_aesctrhmac.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_aesctrhmac.c; sourceTree = ""; }; + BA36C95CC11BBA679562231CDB7DC1A5 /* secp256k1Wrapper */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = secp256k1Wrapper; path = secp256k1Wrapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BA415EF77A72691888985A75DD694708 /* vpaes-armv7.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-armv7.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv7.linux.arm.S"; sourceTree = ""; }; + BA44DD3AAA85A97EA796D27E695437BC /* refcount_lock.c */ = {isa = PBXFileReference; includeInIndex = 1; name = refcount_lock.c; path = Sources/CNIOBoringSSL/crypto/refcount_lock.c; sourceTree = ""; }; + BAC97623A3FE90868CDB8E3A6963E85A /* SDImageGIFCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageGIFCoder.h; path = SDWebImage/Core/SDImageGIFCoder.h; sourceTree = ""; }; + BAD1E7D62CBA874732C8DBB7B121F54F /* secp256k1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = secp256k1.c; path = src/secp256k1.c; sourceTree = ""; }; + BB0A8C2CB3C8DBC1632687EA5BA09D5F /* bio_ssl.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = bio_ssl.cc; path = Sources/CNIOBoringSSL/ssl/bio_ssl.cc; sourceTree = ""; }; + BB14934FB57CF022B95128B26B5145D0 /* NIOTSConnectionBootstrap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSConnectionBootstrap.swift; path = Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift; sourceTree = ""; }; + BB1B7684B4B29822AD4BAFE4218D7CD1 /* ISO78164Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISO78164Padding.swift; path = Sources/CryptoSwift/ISO78164Padding.swift; sourceTree = ""; }; + BB2964841926D0B8548E45C82B3BFD5F /* CryptoSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.debug.xcconfig; sourceTree = ""; }; + BB2B48DE63C63DFDCB60CF127640A4DA /* siphash.c */ = {isa = PBXFileReference; includeInIndex = 1; name = siphash.c; path = Sources/CNIOBoringSSL/crypto/siphash/siphash.c; sourceTree = ""; }; + BB3A87F6880630FB4135090D5EB831F1 /* StreamMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamMap.swift; path = Sources/NIOHTTP2/StreamMap.swift; sourceTree = ""; }; + BB6F36B910678D8E547D0C654844171A /* DataExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataExtensions.swift; path = Sources/Core/Extensions/DataExtensions.swift; sourceTree = ""; }; + BB7439633EDD2E01ED03402DB1D02A0D /* ServerHandlerStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerHandlerStateMachine.swift; path = Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine.swift; sourceTree = ""; }; + BBAC339BE80C1C4E2E9507BC75AA64C7 /* digests.c */ = {isa = PBXFileReference; includeInIndex = 1; name = digests.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/digest/digests.c; sourceTree = ""; }; + BBBC89616D0756CD768F9406643F7DC0 /* CNIOBoringSSL */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOBoringSSL; path = CNIOBoringSSL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BBC73AB7289510464AFB5EFF44C43FAD /* SDWebImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SDWebImage-umbrella.h"; sourceTree = ""; }; + BBDE3E6CCC2C2E47E05E483B33552AD8 /* ssl_lib.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_lib.cc; path = Sources/CNIOBoringSSL/ssl/ssl_lib.cc; sourceTree = ""; }; + BBE42292A4FD16EE1A12341490A57D2C /* InboundEventBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InboundEventBuffer.swift; path = Sources/NIOHTTP2/InboundEventBuffer.swift; sourceTree = ""; }; + BBEEB47144B65631102F7AFC833EB4DC /* socket.c */ = {isa = PBXFileReference; includeInIndex = 1; name = socket.c; path = Sources/CNIOBoringSSL/crypto/bio/socket.c; sourceTree = ""; }; + BBEF31902CE95C276B59B842C4B48F38 /* des.c */ = {isa = PBXFileReference; includeInIndex = 1; name = des.c; path = Sources/CNIOBoringSSL/crypto/des/des.c; sourceTree = ""; }; + BBF794238B05307E3AE72845744E0D06 /* x86_64-gcc.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "x86_64-gcc.c"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/bn/asm/x86_64-gcc.c"; sourceTree = ""; }; + BBF98C528EC0C5C2B7685286984AAD90 /* ServerHandlerStateMachine+Draining.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ServerHandlerStateMachine+Draining.swift"; path = "Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Draining.swift"; sourceTree = ""; }; + BC235DDB7681F367A590FA00C20F5A24 /* CNIOBoringSSL_ossl_typ.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ossl_typ.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ossl_typ.h; sourceTree = ""; }; + BC5572EABD4F6E36821E4ABD2AD4B09C /* RLPItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPItem.swift; path = Sources/FlowSDK/RLP/RLPItem.swift; sourceTree = ""; }; + BC6D316C011289D6114027CEB8E9C2D9 /* DebugInboundEventsHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DebugInboundEventsHandler.swift; path = Sources/NIOExtras/DebugInboundEventsHandler.swift; sourceTree = ""; }; + BC8441953E0511E075A55C9CC42E27E7 /* Rabbit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rabbit.swift; path = Sources/CryptoSwift/Rabbit.swift; sourceTree = ""; }; + BCD389D31F30FBD3A0E3D7DDB3273254 /* cpu_ppc64le.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_ppc64le.c; path = Sources/CNIOBoringSSL/crypto/cpu_ppc64le.c; sourceTree = ""; }; + BCE21EAEDADC5882C334469A44553854 /* InteractiveTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InteractiveTransition.swift; path = PopupDialog/Classes/InteractiveTransition.swift; sourceTree = ""; }; + BCF6A65EC27B88428B3A0CF63413317F /* ClientInterceptorProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientInterceptorProtocol.swift; path = Sources/GRPC/Interceptor/ClientInterceptorProtocol.swift; sourceTree = ""; }; + BD0215600AEB19164756FA72475BCB2F /* ValueType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ValueType.swift; path = Sources/Cadence/ValueType.swift; sourceTree = ""; }; + BD08109835C6A45C609EC05D36F56513 /* HMAC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HMAC.swift; path = Sources/CryptoSwift/HMAC.swift; sourceTree = ""; }; + BD1F34CFE7497BBD6197A9FF7E8FC7DA /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/tls/internal.h; sourceTree = ""; }; + BD2218A808C034905587CE858F8C8D80 /* CNIOLinux-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOLinux-Info.plist"; sourceTree = ""; }; + BD4134865699B139E54951E256C6F701 /* secp256k1Swift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "secp256k1Swift-umbrella.h"; sourceTree = ""; }; + BD7145615C4722938094415282B4CC4B /* aesni-gcm-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesni-gcm-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-gcm-x86_64.mac.x86_64.S"; sourceTree = ""; }; + BD7548A6F50F4CBB0D8776BF446DBD28 /* MaySendFrames.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MaySendFrames.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/MaySendFrames.swift; sourceTree = ""; }; + BDE3529B4144EF636975040E170E6470 /* InMemorySigner.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InMemorySigner.swift; path = Sources/FlowSDK/Crypto/InMemorySigner.swift; sourceTree = ""; }; + BDEF01BE14B5AAA8285D70D93F0A5C6F /* bsaes-armv7.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "bsaes-armv7.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/bsaes-armv7.ios.arm.S"; sourceTree = ""; }; + BDF35E8639017787D175323CA359D07A /* AEAD.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AEAD.swift; path = Sources/CryptoSwift/AEAD/AEAD.swift; sourceTree = ""; }; + BE01B6CAAE26C2D87F755136F85C0EC3 /* LengthFieldPrepender.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LengthFieldPrepender.swift; path = Sources/NIOExtras/LengthFieldPrepender.swift; sourceTree = ""; }; + BE0EFC3EFC30E0946EC8EAFAEB7C6A23 /* CNIOBoringSSL_trust_token.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_trust_token.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_trust_token.h; sourceTree = ""; }; + BE17D22B26A6B724BC41BC503CCE139F /* Transaction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Transaction.swift; path = Sources/FlowSDK/Models/Transaction.swift; sourceTree = ""; }; + BE221C402A207197DC2799CBC4A0FF4F /* handshake.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = handshake.cc; path = Sources/CNIOBoringSSL/ssl/handshake.cc; sourceTree = ""; }; + BE315AD2E58CBC0BE5D4A94EEF3E8B51 /* ExtensionFields.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExtensionFields.swift; path = Sources/SwiftProtobuf/ExtensionFields.swift; sourceTree = ""; }; + BE5BA2C7268A4F3816EA97002DA5E406 /* Square Root.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Square Root.swift"; path = "Sources/CryptoSwift/CS_BigInt/Square Root.swift"; sourceTree = ""; }; + BE889AEBF1F0F3D6CC3BC99186CBD41E /* JSONRPCFraming+ContentLengthHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "JSONRPCFraming+ContentLengthHeader.swift"; path = "Sources/NIOExtras/JSONRPCFraming+ContentLengthHeader.swift"; sourceTree = ""; }; + BEC3EBB70A4B1534B7BE14CD450659AF /* a_digest.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_digest.c; path = Sources/CNIOBoringSSL/crypto/x509/a_digest.c; sourceTree = ""; }; + BEE655195A6F5B88BD1FD92449766B2D /* CNIOWindows-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIOWindows-prefix.pch"; sourceTree = ""; }; + BF24D3F43BB89FBBE0F38FA3E5A66E5B /* ReceivingPushPromiseState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingPushPromiseState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingPushPromiseState.swift; sourceTree = ""; }; + BF39F093DBD84740D41A94119F30C0B6 /* UIButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIButton+WebCache.h"; path = "SDWebImage/Core/UIButton+WebCache.h"; sourceTree = ""; }; + BFEA6712F888607A1730D40B710E1D2B /* BinaryEncodingVisitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryEncodingVisitor.swift; path = Sources/SwiftProtobuf/BinaryEncodingVisitor.swift; sourceTree = ""; }; + C000342FB0B9668D6C2C263D0D3897D4 /* SDImageLoadersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageLoadersManager.h; path = SDWebImage/Core/SDImageLoadersManager.h; sourceTree = ""; }; + C004D6E82E62266875A85C4DD9BFC4D1 /* d1_pkt.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = d1_pkt.cc; path = Sources/CNIOBoringSSL/ssl/d1_pkt.cc; sourceTree = ""; }; + C0113A9C794494094661D69DAAEC3214 /* CNIOBoringSSL_safestack.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_safestack.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_safestack.h; sourceTree = ""; }; + C01D03DBF1929B2E2EDAFE1D84B937BE /* CNIODarwin.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIODarwin.h; path = Sources/CNIODarwin/include/CNIODarwin.h; sourceTree = ""; }; + C03F3F214061CD431CD8FE1BCB83D015 /* v3_crld.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_crld.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_crld.c; sourceTree = ""; }; + C04815858CB98C03EA5F95A2A932CBA5 /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = Sources/secp256k1Swift/Errors.swift; sourceTree = ""; }; + C070BF6E38EB220139D06F9C127FFDF5 /* SDWebImageIndicator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageIndicator.m; path = SDWebImage/Core/SDWebImageIndicator.m; sourceTree = ""; }; + C0811470D725E0E13094B269A7653FB7 /* bn_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = bn_asn1.c; path = Sources/CNIOBoringSSL/crypto/bn_extra/bn_asn1.c; sourceTree = ""; }; + C08AA9786D7C02B53B65E79786224F2A /* SwiftNIOSSL-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOSSL-umbrella.h"; sourceTree = ""; }; + C09A6BC46D6AA43601F4B44F4AAF2CA7 /* TextFormatDecodingOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatDecodingOptions.swift; path = Sources/SwiftProtobuf/TextFormatDecodingOptions.swift; sourceTree = ""; }; + C0A4B92D3375D3A69A261B2924123569 /* NIOTSListenerChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSListenerChannel.swift; path = Sources/NIOTransportServices/NIOTSListenerChannel.swift; sourceTree = ""; }; + C0A7DD2887C9012BC347BEA8C0AE059E /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageRep.m; path = SDWebImage/Core/SDAnimatedImageRep.m; sourceTree = ""; }; + C0B0D5A311F2E48AB02CD7CD89C77C14 /* TextFormatEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextFormatEncoder.swift; path = Sources/SwiftProtobuf/TextFormatEncoder.swift; sourceTree = ""; }; + C0C8FA7659DAD9BA5584AACB46E8140C /* WalletUtilities.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WalletUtilities.swift; path = "Sources/FCL-SDK/WalletUtilities/WalletUtilities.swift"; sourceTree = ""; }; + C11603B9D360BC58772C329CF91BEC74 /* CallDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CallDetails.swift; path = Sources/GRPC/ClientCalls/CallDetails.swift; sourceTree = ""; }; + C14CC3CB213ACC83D237A5886CA26B14 /* BytesUtil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BytesUtil.swift; path = "Sources/swift-crypto/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift"; sourceTree = ""; }; + C155581852CB3AEEEE25F846462DAE0F /* StreamEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamEvent.swift; path = Sources/GRPC/StreamEvent.swift; sourceTree = ""; }; + C19C39C799D0670D4B7753B7373C54A2 /* SDAnimatedImageRep.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDAnimatedImageRep.h; path = SDWebImage/Core/SDAnimatedImageRep.h; sourceTree = ""; }; + C1A5A5841BE08BD8E11D0963F7CB3D5C /* ClientInterceptorPipeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientInterceptorPipeline.swift; path = Sources/GRPC/Interceptor/ClientInterceptorPipeline.swift; sourceTree = ""; }; + C1CFB827F779CBE90AC1D2BBEFAF94EA /* type.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = type.pb.swift; path = Sources/SwiftProtobuf/type.pb.swift; sourceTree = ""; }; + C1F09B4955E96B2CEA5C0ABB75765747 /* NSBezierPath+SDRoundedCorners.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSBezierPath+SDRoundedCorners.m"; path = "SDWebImage/Private/NSBezierPath+SDRoundedCorners.m"; sourceTree = ""; }; + C2158C32C48DE5625C49C2199495659E /* DynamicBlurView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = DynamicBlurView.modulemap; sourceTree = ""; }; + C260B43A2350E61901AD4EAE6A63EC2C /* CNIOBoringSSL_pem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_pem.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_pem.h; sourceTree = ""; }; + C270E8AAEC0C71BAB6FECCB12F46B555 /* CNIOBoringSSL_srtp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_srtp.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_srtp.h; sourceTree = ""; }; + C2E03EC85D380BC085366FA157E17D9B /* ServiceProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceProvider.swift; path = "Sources/FCL-SDK/User/Service/ServiceProvider.swift"; sourceTree = ""; }; + C2E5F8322D7FD72559B6E7011F4E4922 /* SHA256.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA256.swift; path = Sources/secp256k1Swift/SHA256.swift; sourceTree = ""; }; + C303112F60D6260807EFC5BEC533C0F8 /* Codable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Codable.swift; path = Sources/CryptoSwift/CS_BigInt/Codable.swift; sourceTree = ""; }; + C37A5585E6C895F76C51215421BCF806 /* ClientInterceptorContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientInterceptorContext.swift; path = Sources/GRPC/Interceptor/ClientInterceptorContext.swift; sourceTree = ""; }; + C392709A348F71D9BA1F421199AAA4FC /* ssl_x509.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_x509.cc; path = Sources/CNIOBoringSSL/ssl/ssl_x509.cc; sourceTree = ""; }; + C3E6121ABD5731EAD67AF31B2156D245 /* InterceptorContextList.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InterceptorContextList.swift; path = Sources/GRPC/InterceptorContextList.swift; sourceTree = ""; }; + C406C06F57CEF98C098EB1834266766A /* IntegerBitPacking.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerBitPacking.swift; path = Sources/NIOPosix/IntegerBitPacking.swift; sourceTree = ""; }; + C424F70C6667E36112AD91D1FF8F46DC /* CNIOAtomics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOAtomics.h; path = Sources/CNIOAtomics/include/CNIOAtomics.h; sourceTree = ""; }; + C43B966FB585F6DD13A697D96166E616 /* pem_oth.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_oth.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_oth.c; sourceTree = ""; }; + C47B78C19988CCCD0806027F63B5CAEE /* aesv8-armx32.linux.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesv8-armx32.linux.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.linux.arm.S"; sourceTree = ""; }; + C4C69845B2B0DB9185C23E3B1BBBB22E /* sha1-armv4-large.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-armv4-large.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-armv4-large.ios.arm.S"; sourceTree = ""; }; + C4CB6337AAB3E193E899F6BAA540A282 /* err.c */ = {isa = PBXFileReference; includeInIndex = 1; name = err.c; path = Sources/CNIOBoringSSL/crypto/err/err.c; sourceTree = ""; }; + C4F50D1510E1DDB79006E5CC71F205C4 /* pcy_cache.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pcy_cache.c; path = Sources/CNIOBoringSSL/crypto/x509v3/pcy_cache.c; sourceTree = ""; }; + C5620042BB874899D92901F7626042D3 /* SDWebImageDefine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDefine.h; path = SDWebImage/Core/SDWebImageDefine.h; sourceTree = ""; }; + C565118E16A7BADE8EA751B3E1EC17F0 /* BigInt-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BigInt-prefix.pch"; sourceTree = ""; }; + C57DB877D0B18BE81B5991497EFB83D3 /* JSONDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONDecoder.swift; path = Sources/SwiftProtobuf/JSONDecoder.swift; sourceTree = ""; }; + C5B51E986151943001F9FB91147A71C4 /* BigInt.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BigInt.release.xcconfig; sourceTree = ""; }; + C5FCD784F66C4172968D69584606D85C /* RemotelyQuiescingState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemotelyQuiescingState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/RemotelyQuiescingState.swift; sourceTree = ""; }; + C617C7314F44C614860C8B4B8CE78CFE /* PoolManagerStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PoolManagerStateMachine.swift; path = Sources/GRPC/ConnectionPool/PoolManagerStateMachine.swift; sourceTree = ""; }; + C637AFE0F17CD6E5434C0F35F7A9AB49 /* ConnectivityState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectivityState.swift; path = Sources/GRPC/ConnectivityState.swift; sourceTree = ""; }; + C63AF0C7583CF8E8E56FA5E6C476BC3F /* SDWebImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SDWebImage-dummy.m"; sourceTree = ""; }; + C64905FA3EA211221F9F9969540494D8 /* simple.c */ = {isa = PBXFileReference; includeInIndex = 1; name = simple.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/simple.c; sourceTree = ""; }; + C661B04F55355271A9F8DCD687D303AE /* AsyncAwaitSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncAwaitSupport.swift; path = Sources/NIOCore/AsyncAwaitSupport.swift; sourceTree = ""; }; + C6B115167F4570AF95A5C342C0CB230C /* Google_Protobuf_Wrappers+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Wrappers+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift"; sourceTree = ""; }; + C6BEF0D076B6676CEA35ED8F8DCD6C48 /* AES.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.swift; path = Sources/CryptoSwift/AES.swift; sourceTree = ""; }; + C6DE86A887712395D34AC74951E2B7F2 /* GRPCClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCClient.swift; path = Sources/GRPC/GRPCClient.swift; sourceTree = ""; }; + C6DEF9947D494076C7D9D1324FD01167 /* cpu_intel.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_intel.c; path = Sources/CNIOBoringSSL/crypto/cpu_intel.c; sourceTree = ""; }; + C76D5CDB172A27B9B99CB6F16784B942 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/pool/internal.h; sourceTree = ""; }; + C76DC87990DC417BEEEA3A5BD223B758 /* SDWebImageTransitionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransitionInternal.h; path = SDWebImage/Private/SDWebImageTransitionInternal.h; sourceTree = ""; }; + C77A761ED7EE5B3F9934E8867532CD9F /* PassthroughMessageSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughMessageSequence.swift; path = Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSequence.swift; sourceTree = ""; }; + C793CAD5D4C08E9EC559EB44F6F4AB39 /* NIOFilterEmptyWritesHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOFilterEmptyWritesHandler.swift; path = Sources/NIOTransportServices/NIOFilterEmptyWritesHandler.swift; sourceTree = ""; }; + C79850F447C2F84490990DD4AD8A54D3 /* Google_Protobuf_Value+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_Value+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift"; sourceTree = ""; }; + C7B12679B3AE20F22998634963EDEB40 /* CNIOBoringSSL_poly1305.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_poly1305.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_poly1305.h; sourceTree = ""; }; + C7B1D3A5BDDEF2311211C6CA5BF0AF3D /* SwiftProtobuf-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftProtobuf-umbrella.h"; sourceTree = ""; }; + C7DF0B2E8D690EEF78B6B95A929E0960 /* Cadence.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Cadence.debug.xcconfig; sourceTree = ""; }; + C7E25C008B16D40841525DCD017034D7 /* ServerStreamingServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerStreamingServerHandler.swift; path = Sources/GRPC/CallHandlers/ServerStreamingServerHandler.swift; sourceTree = ""; }; + C81073BD7A32C72DE43989D7A7C1EF95 /* Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Padding.swift; path = Sources/CryptoSwift/Padding.swift; sourceTree = ""; }; + C827709A684A15363ECD8BA2B8F989F8 /* ChannelHandlers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChannelHandlers.swift; path = Sources/NIOCore/ChannelHandlers.swift; sourceTree = ""; }; + C8A44A41336C1C73744B65F997ACD14C /* BigInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BigInt.swift; path = Sources/BigInt.swift; sourceTree = ""; }; + C922CF29D12C9731A042B778664EEBF1 /* URLQueryItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLQueryItem.swift; path = Sources/Core/Extensions/URLQueryItem.swift; sourceTree = ""; }; + C92C39073C666F3B2A344FFEE6B8910B /* CaptureQuality.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CaptureQuality.swift; path = Sources/DynamicBlurView/CaptureQuality.swift; sourceTree = ""; }; + C95B55237F43C6DD123B5CA48961ADCA /* atomics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = atomics.swift; path = Sources/NIOConcurrencyHelpers/atomics.swift; sourceTree = ""; }; + C96D53D709CAA0EC53D442695E95B4AD /* NIOTSNetworkEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSNetworkEvents.swift; path = Sources/NIOTransportServices/NIOTSNetworkEvents.swift; sourceTree = ""; }; + C9B845CFDE312262625CAA4A7C843065 /* block_header.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = block_header.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/block_header.pb.swift; sourceTree = ""; }; + C9CC46CB241619CF2FF6976F65331C22 /* p256_beeu-armv8-asm.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "p256_beeu-armv8-asm.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/p256_beeu-armv8-asm.linux.aarch64.S"; sourceTree = ""; }; + C9D15A50EE5BB4D434CB93F59A65B2E1 /* AccountProofData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccountProofData.swift; path = "Sources/FCL-SDK/Models/AccountProofData.swift"; sourceTree = ""; }; + C9D32C7F5134420F2C61C17F759579EB /* CryptoSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CryptoSwift-Info.plist"; sourceTree = ""; }; + C9F50EBBC228643BBF9686C9B450DB58 /* Exports.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Exports.swift; path = Sources/NIO/Exports.swift; sourceTree = ""; }; + CA44D2212E0CBD1D2922B7C5B191F102 /* modinv64_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = modinv64_impl.h; path = src/modinv64_impl.h; sourceTree = ""; }; + CA5524014361D68DC8908D92BA5CB195 /* MethodName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MethodName.swift; path = Sources/Core/Models/MethodName.swift; sourceTree = ""; }; + CA752654586A87C3CF5A48628F2A0C70 /* sha512-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-x86_64.linux.x86_64.S"; sourceTree = ""; }; + CA7E10854BA00094355406B7844497F9 /* Pods-fanexTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-fanexTests-acknowledgements.plist"; sourceTree = ""; }; + CA8520A7740E149F0C6D18630A0F5E32 /* SDDisplayLink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDisplayLink.m; path = SDWebImage/Private/SDDisplayLink.m; sourceTree = ""; }; + CA98D9A63854A14E1B8B03D491F17D2A /* SwiftNIOHTTP1.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHTTP1.release.xcconfig; sourceTree = ""; }; + CAA35DA1D30329F0BCD279A4029063A3 /* SwiftNIOExtras-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOExtras-dummy.m"; sourceTree = ""; }; + CAA91C8A665F57B9A91C735498340D88 /* Data Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data Conversion.swift"; path = "Sources/Data Conversion.swift"; sourceTree = ""; }; + CAB5BE488205DAD5ECF3325DBEB0CB80 /* CNIOBoringSSL_x509.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_x509.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509.h; sourceTree = ""; }; + CAD15AC7A223C4AB51E56BA97FE8D30B /* fips_shared_support.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fips_shared_support.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/fips_shared_support.c; sourceTree = ""; }; + CAD39B8875D55AA8E4426663E5F29E63 /* SDDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDiskCache.m; path = SDWebImage/Core/SDDiskCache.m; sourceTree = ""; }; + CADC67C899E5C65F088281C441A35555 /* FieldTag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FieldTag.swift; path = Sources/SwiftProtobuf/FieldTag.swift; sourceTree = ""; }; + CAF3612E50BAAE6C2D6EC831E700F9FF /* fips.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fips.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/self_check/fips.c; sourceTree = ""; }; + CB72FA10C1BE9E862B724ECBB814D72F /* IdentityVerification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IdentityVerification.swift; path = Sources/NIOSSL/IdentityVerification.swift; sourceTree = ""; }; + CBA473ED92C1037C118477A4972B8318 /* SwiftNIOExtras.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOExtras.debug.xcconfig; sourceTree = ""; }; + CCA5BEBB9543CB4D3616D04BAE558155 /* p_rsa_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_rsa_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/p_rsa_asn1.c; sourceTree = ""; }; + CD0A2854CC856EABE27D02B8B2A196D7 /* _FakeResponseStream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _FakeResponseStream.swift; path = Sources/GRPC/_FakeResponseStream.swift; sourceTree = ""; }; + CD1C77232231A56100C2C126C3D2BA3F /* ConnectionPool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionPool.swift; path = Sources/GRPC/ConnectionPool/ConnectionPool.swift; sourceTree = ""; }; + CD3E3562250BD9DC2DCEC39BD3E40552 /* Selectable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Selectable.swift; path = Sources/NIOPosix/Selectable.swift; sourceTree = ""; }; + CD40323B10E8239FC8F186C9065EE598 /* NIOSSLHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOSSLHandler.swift; path = Sources/NIOSSL/NIOSSLHandler.swift; sourceTree = ""; }; + CD554B1F5155CCEC522FD091E3B42B44 /* UserInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UserInfo.swift; path = Sources/GRPC/UserInfo.swift; sourceTree = ""; }; + CD63A32D56755A4FA3D94486B21B69A0 /* WebCORSHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WebCORSHandler.swift; path = Sources/GRPC/WebCORSHandler.swift; sourceTree = ""; }; + CD6E01B5DAF6B4CA74B4852A157A8805 /* Blowfish+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Blowfish+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift"; sourceTree = ""; }; + CDA93E44ACEA49D047A8B0DFCED8CFEB /* v3_pmaps.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_pmaps.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_pmaps.c; sourceTree = ""; }; + CDDC0B8D791C8C49E6F9070D46D7CF5F /* e_null.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_null.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_null.c; sourceTree = ""; }; + CE5BD54E549BB42CDA46C2291134E1AD /* NSButton+WebCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/Core/NSButton+WebCache.h"; sourceTree = ""; }; + CE6E92656D4BBA6B5D21A6CF282B7FBB /* CBCMAC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CBCMAC.swift; path = Sources/CryptoSwift/CBCMAC.swift; sourceTree = ""; }; + CE7BD51E66B34C82517DC0D59C7B8BB3 /* CNIOBoringSSL_sha.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_sha.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_sha.h; sourceTree = ""; }; + CEB19D0C3B111ABDA93C9E962F460016 /* Event.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Event.swift; path = Sources/FlowSDK/Models/Event.swift; sourceTree = ""; }; + CEF1B4381BEA551E1BEC8BD8A0F45A2E /* GRPCAsyncBidirectionalStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncBidirectionalStreamingCall.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncBidirectionalStreamingCall.swift; sourceTree = ""; }; + CF1F5D93B023F71A05A4ED03AE04E4D7 /* SDImageFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageFrame.h; path = SDWebImage/Core/SDImageFrame.h; sourceTree = ""; }; + CF33312D7AC69B54F5B685FE2F46D2E6 /* CNIOBoringSSL_base.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_base.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_base.h; sourceTree = ""; }; + CF3424F9089EEA88A0156E122EE2E7DD /* UIImage+Transform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Transform.m"; path = "SDWebImage/Core/UIImage+Transform.m"; sourceTree = ""; }; + CF47AA3DA3B8EB010E9C9249B488EAC4 /* ParameterType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterType.swift; path = Sources/Cadence/CType/ParameterType.swift; sourceTree = ""; }; + CF6A36C389477C0B91CF6F4154DE17C9 /* dh_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = dh_asn1.c; path = Sources/CNIOBoringSSL/crypto/dh_extra/dh_asn1.c; sourceTree = ""; }; + CFE74D605415B4D1AA55DA6DFB704085 /* SwiftNIOPosix-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOPosix-umbrella.h"; sourceTree = ""; }; + D059656D450DB7462D191A177599D6A2 /* HTTP2ToRawGRPCServerCodec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ToRawGRPCServerCodec.swift; path = Sources/GRPC/HTTP2ToRawGRPCServerCodec.swift; sourceTree = ""; }; + D05CAAFC9A2E05CC9475D01611990AE4 /* a_utctm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_utctm.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_utctm.c; sourceTree = ""; }; + D0742B711AB7B5FF0D93C43D48B5D760 /* RNG_boring.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RNG_boring.swift; path = "Sources/swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift"; sourceTree = ""; }; + D076AF38527FFEC91314404B4572AF02 /* BinaryEncodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryEncodingError.swift; path = Sources/SwiftProtobuf/BinaryEncodingError.swift; sourceTree = ""; }; + D0866B41EB6AEDC557B09BE6BED4DD85 /* DapperWalletProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DapperWalletProvider.swift; path = "Sources/FCL-SDK/WalletProvider/DapperWalletProvider.swift"; sourceTree = ""; }; + D10BB7A9B0FD68ED82C64D21CAC3AF2B /* v3_cpols.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_cpols.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_cpols.c; sourceTree = ""; }; + D138731AC283B1675098D887342027D8 /* CNIOBoringSSLShims */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOBoringSSLShims; path = CNIOBoringSSLShims.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D1888F7EA84E495DF29AAC7AD4BBD33A /* CNIOHTTPParser-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CNIOHTTPParser-Info.plist"; sourceTree = ""; }; + D1AADC027009B9AD670FAB50C640B26E /* CNIOBoringSSL_ecdh.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ecdh.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ecdh.h; sourceTree = ""; }; + D1B586BCFD71CE4BCE197B2B172AE998 /* QueryEscape.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QueryEscape.swift; path = Sources/Core/Models/QueryEscape.swift; sourceTree = ""; }; + D1CC2A12C07D5515B9B8E785234834B4 /* RLPEncodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPEncodable.swift; path = Sources/FlowSDK/RLP/RLPEncodable.swift; sourceTree = ""; }; + D1DD2C2EFC8604B688328D8CA7803D30 /* Comparable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Comparable.swift; path = Sources/CryptoSwift/CS_BigInt/Comparable.swift; sourceTree = ""; }; + D2026207177E77CCFCF8DC1F5B32429B /* SDWebImageDownloaderConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderConfig.h; path = SDWebImage/Core/SDWebImageDownloaderConfig.h; sourceTree = ""; }; + D21EF5C431176A45CB3F8F2CDC1035DA /* ReceivingHeadersState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReceivingHeadersState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingHeadersState.swift; sourceTree = ""; }; + D262F10A23088344883964E1418BE853 /* Pods-fanexTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-fanexTests.modulemap"; sourceTree = ""; }; + D2711FB3F56616A310BA4635C98D5817 /* x509_ext.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_ext.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_ext.c; sourceTree = ""; }; + D2C162FF68AE73704F1D0370CBB8E821 /* IO.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IO.swift; path = Sources/NIOPosix/IO.swift; sourceTree = ""; }; + D2F7A62C86D43CBFBE760EC3E47BBAE1 /* poly1305_arm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = poly1305_arm.c; path = Sources/CNIOBoringSSL/crypto/poly1305/poly1305_arm.c; sourceTree = ""; }; + D306E5CF93DA0C35925B406052C351C2 /* exponentiation.c */ = {isa = PBXFileReference; includeInIndex = 1; name = exponentiation.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/exponentiation.c; sourceTree = ""; }; + D3095F84099BAC79F6F6C210A93F1540 /* GRPCKeepaliveHandlers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCKeepaliveHandlers.swift; path = Sources/GRPC/GRPCKeepaliveHandlers.swift; sourceTree = ""; }; + D33E3CFEC8B6CF1099E266DBB405837C /* empty.c */ = {isa = PBXFileReference; includeInIndex = 1; name = empty.c; path = Sources/CGRPCZlib/empty.c; sourceTree = ""; }; + D346C93079C3308B4DA5A3C16624F7A7 /* secp256k1Swift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = secp256k1Swift.modulemap; sourceTree = ""; }; + D36C79BBBBA3A45553902A70E34CFBC1 /* assumptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = assumptions.h; path = src/assumptions.h; sourceTree = ""; }; + D3801A363FE17786D7DBE4F3571FC3BB /* hpke.c */ = {isa = PBXFileReference; includeInIndex = 1; name = hpke.c; path = Sources/CNIOBoringSSL/crypto/hpke/hpke.c; sourceTree = ""; }; + D3ADD3A261C519861223F27639A1EB81 /* Heap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Heap.swift; path = Sources/_NIODataStructures/Heap.swift; sourceTree = ""; }; + D3E2E750872CF97E0A6E77587D690DA2 /* LinuxUring.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinuxUring.swift; path = Sources/NIOPosix/LinuxUring.swift; sourceTree = ""; }; + D40E5DCB25DDB72596D326CE4ED62102 /* SDImageCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageCoder.h; path = SDWebImage/Core/SDImageCoder.h; sourceTree = ""; }; + D418CCC7A6AC0FB56934549E60249E06 /* CNIOLinux.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOLinux.release.xcconfig; sourceTree = ""; }; + D448E72582B6BAAF2BBA7D9FA5189644 /* a_i2d_fp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_i2d_fp.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_i2d_fp.c; sourceTree = ""; }; + D458F5EEF5F6D974F7A4B1C7B3B905FE /* SwiftNIOHTTP2-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOHTTP2-dummy.m"; sourceTree = ""; }; + D462F248FEBAB1C92771B296C65AAB45 /* Utilities.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utilities.swift; path = Sources/NIOCore/Utilities.swift; sourceTree = ""; }; + D4D8755F63B123A5B3596B36D1B55D1E /* SwiftNIOHTTP2-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHTTP2-umbrella.h"; sourceTree = ""; }; + D561F1333FD64F4F25B777E77E28522F /* Prime Test.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Prime Test.swift"; path = "Sources/CryptoSwift/CS_BigInt/Prime Test.swift"; sourceTree = ""; }; + D57C247374F68157B55FF81C04D58B22 /* SDImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageLoader.m; path = SDWebImage/Core/SDImageLoader.m; sourceTree = ""; }; + D587939838E633D7D3BB2F5EDEDE5011 /* source_context.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = source_context.pb.swift; path = Sources/SwiftProtobuf/source_context.pb.swift; sourceTree = ""; }; + D5B4F82B8EEFF961A5F7EC682B610977 /* mem.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mem.c; path = Sources/CNIOBoringSSL/crypto/mem.c; sourceTree = ""; }; + D5E6A03147D0A9EC2FDEB805FDBB269D /* CompressionAlgorithm.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompressionAlgorithm.swift; path = Sources/GRPC/Compression/CompressionAlgorithm.swift; sourceTree = ""; }; + D5EEEF9636E2C27602F4A72507BF2C05 /* SwiftNIOCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOCore-Info.plist"; sourceTree = ""; }; + D60BEB2C0F3EAB59348E0C1D13463871 /* SwiftyJSON-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftyJSON-dummy.m"; sourceTree = ""; }; + D61158F986302E12E922F356AC6A7673 /* sha1-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha1-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha1-x86_64.linux.x86_64.S"; sourceTree = ""; }; + D6397A1E765ACDAE82BB631C5DCBB30F /* pem_xaux.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pem_xaux.c; path = Sources/CNIOBoringSSL/crypto/pem/pem_xaux.c; sourceTree = ""; }; + D67656E3C8BABFA1F2CC575CA2F9BA96 /* NIOHTTPObjectAggregator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOHTTPObjectAggregator.swift; path = Sources/NIOHTTP1/NIOHTTPObjectAggregator.swift; sourceTree = ""; }; + D6834988BB87EBBA075596656CA2100C /* NSData+ImageContentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+ImageContentType.m"; path = "SDWebImage/Core/NSData+ImageContentType.m"; sourceTree = ""; }; + D69780E46CD39C58EABFCD14326E92C5 /* CNIOAtomics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOAtomics.release.xcconfig; sourceTree = ""; }; + D6BAAE75DEA3771B8E9934450CF53138 /* NIOThreadPool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOThreadPool.swift; path = Sources/NIOPosix/NIOThreadPool.swift; sourceTree = ""; }; + D6C65F229611613EDA6CA861ABF58094 /* SDImageTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageTransformer.h; path = SDWebImage/Core/SDImageTransformer.h; sourceTree = ""; }; + D70EDEE52BD5BEC13259E3639B8BA99A /* Integer Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Integer Conversion.swift"; path = "Sources/CryptoSwift/CS_BigInt/Integer Conversion.swift"; sourceTree = ""; }; + D736863024538C0336937C1263FBC4B9 /* Dictionary.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Dictionary.swift; path = Sources/Cadence/Dictionary.swift; sourceTree = ""; }; + D74C19340A61F25F7DE3AFCD405BB334 /* UIColor+SDHexString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIColor+SDHexString.h"; path = "SDWebImage/Private/UIColor+SDHexString.h"; sourceTree = ""; }; + D75FB5F17B7BEEC09796E3465E8F7D14 /* SwiftNIOHTTP1-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHTTP1-umbrella.h"; sourceTree = ""; }; + D78E079D6EED20A6C6105DF41E1D00B7 /* rand.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rand.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/rand.c; sourceTree = ""; }; + D7AC2EC3666BF3283F5E15A69EB7D3B5 /* event.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = event.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/event.pb.swift; sourceTree = ""; }; + D7C19014ED3BF4FE7F33FD701C930DB9 /* transaction.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = transaction.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/entities/transaction.pb.swift; sourceTree = ""; }; + D7C73208AD27DA45312A80946D6185E9 /* cpu_aarch64_fuchsia.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_aarch64_fuchsia.c; path = Sources/CNIOBoringSSL/crypto/cpu_aarch64_fuchsia.c; sourceTree = ""; }; + D800D3A45C73A256CA1CA8ECE8173369 /* p_rsa.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_rsa.c; path = Sources/CNIOBoringSSL/crypto/evp/p_rsa.c; sourceTree = ""; }; + D81F70F67EBAF255F9AB9DE70BB28A19 /* asn1_par.c */ = {isa = PBXFileReference; includeInIndex = 1; name = asn1_par.c; path = Sources/CNIOBoringSSL/crypto/asn1/asn1_par.c; sourceTree = ""; }; + D85994E4069B3EC81A279B775780797A /* SwiftNIOPosix */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOPosix; path = NIOPosix.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D87C163D2F9A6289B1C80E3AB8459790 /* basic-config.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "basic-config.h"; path = "src/basic-config.h"; sourceTree = ""; }; + D88B4F5806EF70D37AF0578452D42980 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/internal.h; sourceTree = ""; }; + D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + D8A3BC28D5AFF50B3CF081A56F0AD709 /* ecmult_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_impl.h; path = src/ecmult_impl.h; sourceTree = ""; }; + D8B68FE07B21CC522B358D579282D30E /* CNIOBoringSSL_evp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_evp.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp.h; sourceTree = ""; }; + D8EE5C7973CA3CFEE5FD57A854A7E18B /* GRPCTLSConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCTLSConfiguration.swift; path = Sources/GRPC/GRPCTLSConfiguration.swift; sourceTree = ""; }; + D8FDB16E285BA44509CA04F4CA63E699 /* AccountsResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccountsResolver.swift; path = "Sources/FCL-SDK/Resolve/AccountsResolver.swift"; sourceTree = ""; }; + D908361B8625862D2C49A79C1B9BEA16 /* SDWebImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SDWebImage.debug.xcconfig; sourceTree = ""; }; + D91FC01385D3680BAE48C7A1E23CB088 /* CNIOAtomics */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOAtomics; path = CNIOAtomics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D920EEF436E21BBA439A27EB4D74DF39 /* MessageExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageExtension.swift; path = Sources/SwiftProtobuf/MessageExtension.swift; sourceTree = ""; }; + D9A4DA078108B9FD83435DED90E5D8F1 /* SVProgressHUD-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-prefix.pch"; sourceTree = ""; }; + D9AF0FDC004753EBA45EFC05DEFDD26D /* PollingResponse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PollingResponse.swift; path = "Sources/FCL-SDK/Network/PollingResponse.swift"; sourceTree = ""; }; + D9B529C7D801576754E91D4503778443 /* Signable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signable.swift; path = "Sources/FCL-SDK/Models/Signable.swift"; sourceTree = ""; }; + D9D25B6386B64C23DE7B0BF846749F80 /* ProtobufAPIVersionCheck.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ProtobufAPIVersionCheck.swift; path = Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift; sourceTree = ""; }; + DA0E49E0085C99A522336D97C0D644E2 /* StreamStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamStateMachine.swift; path = Sources/NIOHTTP2/StreamStateMachine.swift; sourceTree = ""; }; + DA29D1A3E827E2DEAE7B710196D264C9 /* SDWebImageDownloaderDecryptor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderDecryptor.m; path = SDWebImage/Core/SDWebImageDownloaderDecryptor.m; sourceTree = ""; }; + DA5B2D264C8C540509FF1E9DF0014B42 /* ServerStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerStreamingCall.swift; path = Sources/GRPC/ClientCalls/ServerStreamingCall.swift; sourceTree = ""; }; + DA5F1FF9DF20765A233511DC436191CE /* SwiftNIOHTTP2-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOHTTP2-prefix.pch"; sourceTree = ""; }; + DA6839D1D519D3E405E6EDD9FBB2B5ED /* ClientStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ClientStreamingCall.swift; path = Sources/GRPC/ClientCalls/ClientStreamingCall.swift; sourceTree = ""; }; + DA6BBD134CE96FF5620A937811221B57 /* shim.c */ = {isa = PBXFileReference; includeInIndex = 1; name = shim.c; path = Sources/CNIODarwin/shim.c; sourceTree = ""; }; + DA9C6551A4C7E622106E3008ACCFC4A2 /* PrivateKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PrivateKey.swift; path = Sources/FlowSDK/Crypto/PrivateKey.swift; sourceTree = ""; }; + DAA737D85B90547148EA523BDB9C67F8 /* t1_enc.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = t1_enc.cc; path = Sources/CNIOBoringSSL/ssl/t1_enc.cc; sourceTree = ""; }; + DAB2A7A0E6EB30C6DFB50B3042E6EEE4 /* execution.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = execution.pb.swift; path = Sources/FlowSDK/Protobuf/Generated/flow/execution/execution.pb.swift; sourceTree = ""; }; + DABFF317E1626B524FACA62C0C149889 /* poly1305_vec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = poly1305_vec.c; path = Sources/CNIOBoringSSL/crypto/poly1305/poly1305_vec.c; sourceTree = ""; }; + DB07308B36D8F85B7F9D40B31BCDA3B1 /* TLSVerificationHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TLSVerificationHandler.swift; path = Sources/GRPC/TLSVerificationHandler.swift; sourceTree = ""; }; + DB3C51FC2CE11F6E1FC4DB0C1059C64F /* Pods-fanexTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanexTests.debug.xcconfig"; sourceTree = ""; }; + DB4B1D84D0BF51670648EFB8394A7113 /* SDWebImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SDWebImage-Info.plist"; sourceTree = ""; }; + DBBB69673F9AB022794371244DF6B647 /* a_object.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_object.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_object.c; sourceTree = ""; }; + DBBF7AA6EBA1CE1E2A25802226115F77 /* HPACKHeaders+Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "HPACKHeaders+Validation.swift"; path = "Sources/NIOHTTP2/HPACKHeaders+Validation.swift"; sourceTree = ""; }; + DBD38889D7644ED72769E8B659531B54 /* RecvByteBufferAllocator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecvByteBufferAllocator.swift; path = Sources/NIOCore/RecvByteBufferAllocator.swift; sourceTree = ""; }; + DBE34A1D672AD2579D3BB755C51A5C5B /* Logging.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Logging.release.xcconfig; sourceTree = ""; }; + DC1758411E8067285A2146A45045AA7B /* SHA1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA1.swift; path = Sources/CryptoSwift/SHA1.swift; sourceTree = ""; }; + DC24001B0B936C4BAD8F8EACF07E466C /* SwiftNIO.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIO.release.xcconfig; sourceTree = ""; }; + DC639B3693A5684D7058BF67CD67A76B /* SwiftNIOHPACK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOHPACK.release.xcconfig; sourceTree = ""; }; + DC8CE43DCE073AC353F2133251430DDB /* SVProgressHUD-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SVProgressHUD-Info.plist"; sourceTree = ""; }; + DCA0FE597DC1F3C6A5BCA04F2DA989A4 /* Call.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Call.swift; path = Sources/GRPC/ClientCalls/Call.swift; sourceTree = ""; }; + DCAEC86F60F8795EC88E6D54463B62AC /* SignatureAlgorithm+Cadence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SignatureAlgorithm+Cadence.swift"; path = "Sources/FlowSDK/Extensions/SignatureAlgorithm+Cadence.swift"; sourceTree = ""; }; + DCB1DC8F307D2C326B774E8B2DBCD44C /* CNIOLinux.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOLinux.modulemap; sourceTree = ""; }; + DCC668BBD24EEF42DBAC20B915CC8D69 /* chacha-armv4.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-armv4.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-armv4.ios.arm.S"; sourceTree = ""; }; + DCD2D8AA00FB066742BC2E855446832E /* Integer Conversion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Integer Conversion.swift"; path = "Sources/Integer Conversion.swift"; sourceTree = ""; }; + DCD6665F6C8BAD060595A501C0346F1A /* SwiftNIOTransportServices.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOTransportServices.debug.xcconfig; sourceTree = ""; }; + DCF665EB75E6C7CA2AC7151F867A8615 /* FCL-SDK-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FCL-SDK-umbrella.h"; sourceTree = ""; }; + DD080D9D0066EA88ABC10B14F8920C64 /* charmap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = charmap.h; path = Sources/CNIOBoringSSL/crypto/asn1/charmap.h; sourceTree = ""; }; + DD8F959C010C8EE0A0547CF67FEA904B /* Addition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Addition.swift; path = Sources/Addition.swift; sourceTree = ""; }; + DDB32F7AB6A7CC1CF10B4632146512E4 /* Error+NIOSSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Error+NIOSSL.swift"; path = "Sources/GRPC/Error+NIOSSL.swift"; sourceTree = ""; }; + DDC6F0F2EF3F899754774C80358CFB92 /* Ref.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Ref.swift; path = Sources/GRPC/Ref.swift; sourceTree = ""; }; + DE18259BFD9CE81EBAE94B05B4902E80 /* BlockMode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockMode.swift; path = Sources/CryptoSwift/BlockMode/BlockMode.swift; sourceTree = ""; }; + DE18D266883CE29CF57E950BD8D8EE4C /* UInt128.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UInt128.swift; path = Sources/CryptoSwift/UInt128.swift; sourceTree = ""; }; + DE9515A45FBBC6DCD53031F946838D95 /* aes_nohw.c */ = {isa = PBXFileReference; includeInIndex = 1; name = aes_nohw.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/aes/aes_nohw.c; sourceTree = ""; }; + DE9AD1D139042C4717863CEAEC80465E /* CNIOBoringSSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL.h; sourceTree = ""; }; + DEBF4C708C9182A6158AD07729A04D54 /* CNIOBoringSSL_hrss.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_hrss.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_hrss.h; sourceTree = ""; }; + DEF889114EFDCE691DAEE2F56411B5AB /* SDImageAWebPCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageAWebPCoder.h; path = SDWebImage/Core/SDImageAWebPCoder.h; sourceTree = ""; }; + DEF8E38A6C86993609FD23CD53FD060C /* PopupDialogDefaultViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogDefaultViewController.swift; path = PopupDialog/Classes/PopupDialogDefaultViewController.swift; sourceTree = ""; }; + DF460495858DBE915D5FF2B7EB92E23B /* SwiftNIOConcurrencyHelpers-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftNIOConcurrencyHelpers-Info.plist"; sourceTree = ""; }; + DF71BC3254D90CE69B3FD2C1D702DE0A /* SSLCertificate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SSLCertificate.swift; path = Sources/NIOSSL/SSLCertificate.swift; sourceTree = ""; }; + DF8564E76204B0DB31B6EE565193A0BC /* Pods-fanex-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-fanex-acknowledgements.markdown"; sourceTree = ""; }; + DF9AC5693C5E7E568C3EB0077AB198A8 /* BSDSocketAPIPosix.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BSDSocketAPIPosix.swift; path = Sources/NIOPosix/BSDSocketAPIPosix.swift; sourceTree = ""; }; + DFA9F0E3CEC147A6DE206E5B03934731 /* RSA.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RSA.swift; path = Sources/CryptoSwift/RSA.swift; sourceTree = ""; }; + DFBAC8F5B391B91A2CF90C493B6F1E41 /* SVProgressHUD-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-umbrella.h"; sourceTree = ""; }; + E0104C16951B11FB6DED96D556CF2028 /* MercariQRScanner.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MercariQRScanner.modulemap; sourceTree = ""; }; + E03FB9C4D7EBB4B177BAE64292C69AD1 /* NIOCloseOnErrorHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOCloseOnErrorHandler.swift; path = Sources/NIOCore/NIOCloseOnErrorHandler.swift; sourceTree = ""; }; + E05AF864C3E9FEE08D516DE2E350E390 /* FieldType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FieldType.swift; path = Sources/Cadence/CType/FieldType.swift; sourceTree = ""; }; + E0925800F0F3DA00319FE641B576C727 /* UInt8+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt8+Extension.swift"; path = "Sources/CryptoSwift/UInt8+Extension.swift"; sourceTree = ""; }; + E0CB49F4D5C20983310803D707A2EAF9 /* TransactionProposalKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransactionProposalKey.swift; path = Sources/FlowSDK/Models/TransactionProposalKey.swift; sourceTree = ""; }; + E0EA82A4A84FD9D37485CCA3798E48A6 /* v3_lib.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_lib.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_lib.c; sourceTree = ""; }; + E1116D42B41D6F34C7E3FE87161B217F /* SVProgressHUD-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SVProgressHUD-dummy.m"; sourceTree = ""; }; + E136AD5881B92E5F3FE8944DD75F0AB2 /* GCM.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GCM.swift; path = Sources/CryptoSwift/BlockMode/GCM.swift; sourceTree = ""; }; + E1655554B8A6F6D0EC8890EEA2359462 /* URLComponentsExtensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLComponentsExtensions.swift; path = Sources/Flow/Extensions/URLComponentsExtensions.swift; sourceTree = ""; }; + E18AB3400B57A79FD5CE7E88BE4FBF63 /* Cadence.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Cadence.release.xcconfig; sourceTree = ""; }; + E19198AD322B90004297C469FEA5DB6C /* x509_cmp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = x509_cmp.c; path = Sources/CNIOBoringSSL/crypto/x509/x509_cmp.c; sourceTree = ""; }; + E1A7ECDE3312ABF35B64E9CE0D610FA1 /* GRPCAsyncRequestStreamWriter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncRequestStreamWriter.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStreamWriter.swift; sourceTree = ""; }; + E1C8C7BB879B9DC1A63010ED47A05068 /* PoolManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PoolManager.swift; path = Sources/GRPC/ConnectionPool/PoolManager.swift; sourceTree = ""; }; + E1F2D9F2F28DC75871F1432985EEE953 /* CNIOBoringSSL_evp_errors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_evp_errors.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_evp_errors.h; sourceTree = ""; }; + E1FB3A89265A69F9801F85E9DB90A200 /* base64.c */ = {isa = PBXFileReference; includeInIndex = 1; name = base64.c; path = Sources/CNIOBoringSSL/crypto/base64/base64.c; sourceTree = ""; }; + E201F149034E7DE2B52308F670E942D8 /* SDImageHEICCoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDImageHEICCoder.h; path = SDWebImage/Core/SDImageHEICCoder.h; sourceTree = ""; }; + E2289E7AE246F961F1A92D56F8B531B7 /* sha256.c */ = {isa = PBXFileReference; includeInIndex = 1; name = sha256.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha256.c; sourceTree = ""; }; + E23C076BA70925415F490FEDB215DA92 /* SwiftyJSON */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftyJSON; path = SwiftyJSON.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E25DB3244B2111EE09A01E72382F5CE3 /* name_print.c */ = {isa = PBXFileReference; includeInIndex = 1; name = name_print.c; path = Sources/CNIOBoringSSL/crypto/x509/name_print.c; sourceTree = ""; }; + E27145F5259634BD1971D2919DCF19EE /* padding.c */ = {isa = PBXFileReference; includeInIndex = 1; name = padding.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rsa/padding.c; sourceTree = ""; }; + E294B949999A1A5079F9FEBD6B774F68 /* NSImage+Compatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSImage+Compatibility.h"; path = "SDWebImage/Core/NSImage+Compatibility.h"; sourceTree = ""; }; + E30A11CD3BEC671E6C5B6D2BC47A094C /* NSButton+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/Core/NSButton+WebCache.m"; sourceTree = ""; }; + E3115F95805159489F6A96D13A4B6B0F /* aesni-x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesni-x86_64.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesni-x86_64.linux.x86_64.S"; sourceTree = ""; }; + E32E9F648A6FD4A830BA69B40C9C0428 /* PopupDialogDefaultButtons.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogDefaultButtons.swift; path = PopupDialog/Classes/PopupDialogDefaultButtons.swift; sourceTree = ""; }; + E358977EBFBB1B19A411BAEA76FA770A /* IndexedHeaderTable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IndexedHeaderTable.swift; path = Sources/NIOHPACK/IndexedHeaderTable.swift; sourceTree = ""; }; + E360AA62048C3919BBFD38F63BB1508D /* BloctoWalletProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BloctoWalletProvider.swift; path = "Sources/FCL-SDK/WalletProvider/BloctoWalletProvider.swift"; sourceTree = ""; }; + E36639476C222AC1321AE96AD9D9F3C1 /* t_req.c */ = {isa = PBXFileReference; includeInIndex = 1; name = t_req.c; path = Sources/CNIOBoringSSL/crypto/x509/t_req.c; sourceTree = ""; }; + E3E05A06E1D1AEDA186039A82B0C3048 /* by_file.c */ = {isa = PBXFileReference; includeInIndex = 1; name = by_file.c; path = Sources/CNIOBoringSSL/crypto/x509/by_file.c; sourceTree = ""; }; + E40AE1987BFAD661223EDD5BCD64E438 /* ghash-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "ghash-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/ghash-x86_64.mac.x86_64.S"; sourceTree = ""; }; + E4B7A9E311EEA55E7535DFFA305302F6 /* StreamingResponseCallContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StreamingResponseCallContext.swift; path = Sources/GRPC/ServerCallContexts/StreamingResponseCallContext.swift; sourceTree = ""; }; + E4D3DAA4823B69DE8B68DFAF03DF054B /* SwiftNIOPosix.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftNIOPosix.modulemap; sourceTree = ""; }; + E4D7AF2FFDCED01CDA1D9A7C7E877132 /* SwiftNIOEmbedded.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOEmbedded.debug.xcconfig; sourceTree = ""; }; + E5160EE97B79C9809A0F792E3F645C72 /* field_5x52_int128_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = field_5x52_int128_impl.h; path = src/field_5x52_int128_impl.h; sourceTree = ""; }; + E5262DE15AC178F44123A11F52286966 /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/curve25519/internal.h; sourceTree = ""; }; + E5775235143C439271C4EDF08E25E941 /* Authenticator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Authenticator.swift; path = Sources/CryptoSwift/Authenticator.swift; sourceTree = ""; }; + E5870E9EFBACE59A56028B0E330D8339 /* sha256-586.linux.x86.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha256-586.linux.x86.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha256-586.linux.x86.S"; sourceTree = ""; }; + E5B1BFB9F383FB335DAA5730B9A73A16 /* GRPCError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCError.swift; path = Sources/GRPC/GRPCError.swift; sourceTree = ""; }; + E651C6A6A5C2103B3BFB4694639A6744 /* descriptor.pb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = descriptor.pb.swift; path = Sources/SwiftProtobuf/descriptor.pb.swift; sourceTree = ""; }; + E65A74CFF2E48DB5BDC56CB0068A6CA1 /* SwiftProtobuf.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftProtobuf.modulemap; sourceTree = ""; }; + E66028A9BC516368D326E1467AD827B9 /* pbkdf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pbkdf.c; path = Sources/CNIOBoringSSL/crypto/evp/pbkdf.c; sourceTree = ""; }; + E667AE513A07C5DA03178515082AB7ED /* RLPEncodableList.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RLPEncodableList.swift; path = Sources/FlowSDK/RLP/RLPEncodableList.swift; sourceTree = ""; }; + E668AFE040CFD1CAC7A6D5CA192E1586 /* cmp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cmp.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/cmp.c; sourceTree = ""; }; + E6DB6B7AD7E5EAA5EA9B3C212BBC84D2 /* c-atomics.c */ = {isa = PBXFileReference; includeInIndex = 1; name = "c-atomics.c"; path = "Sources/CNIOAtomics/src/c-atomics.c"; sourceTree = ""; }; + E6DC64D0790FCBD808F1189978E45306 /* UIView+WebCacheOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCacheOperation.h"; path = "SDWebImage/Core/UIView+WebCacheOperation.h"; sourceTree = ""; }; + E6FB1813DCECD368FD0CB74060E96349 /* BloctoSDK.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = BloctoSDK.modulemap; sourceTree = ""; }; + E6FC7C6947FF36F684A3994FFE7F76DE /* ConnectionBackoff.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionBackoff.swift; path = Sources/GRPC/ConnectionBackoff.swift; sourceTree = ""; }; + E71DDD9AEF01CB88D7D69EC16C54A094 /* CNIODarwin-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CNIODarwin-umbrella.h"; sourceTree = ""; }; + E747B0DAB33E037A6FC0E59DD4BB8C6F /* URLComponents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLComponents.swift; path = Sources/Core/Extensions/URLComponents.swift; sourceTree = ""; }; + E753CB8B7DA12B68CE4372634BD6037C /* Codec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Codec.swift; path = Sources/NIOCore/Codec.swift; sourceTree = ""; }; + E77B986346C2874BB28EAD34DE8FEF70 /* SwiftNIOExtras-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftNIOExtras-prefix.pch"; sourceTree = ""; }; + E77F790CCA4B1B8F1B6CD5B3C98BF486 /* p5_pbev2.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p5_pbev2.c; path = Sources/CNIOBoringSSL/crypto/pkcs8/p5_pbev2.c; sourceTree = ""; }; + E7B48DD881BF8AE6BDC689EB96936503 /* SHA256Digest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA256Digest.swift; path = Sources/FlowSDK/Crypto/SHA256Digest.swift; sourceTree = ""; }; + E7C89F722798F571C28B19243305FA4C /* secp256k1Swift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "secp256k1Swift-Info.plist"; sourceTree = ""; }; + E7F100F1D0CF11736A4A00AE46E8435B /* thread_none.c */ = {isa = PBXFileReference; includeInIndex = 1; name = thread_none.c; path = Sources/CNIOBoringSSL/crypto/thread_none.c; sourceTree = ""; }; + E7F4BE6BBA53BCAFE0232A7F15B66BAC /* SDImageHEICCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageHEICCoder.m; path = SDWebImage/Core/SDImageHEICCoder.m; sourceTree = ""; }; + E804F479A0C73C7E15BF90C02CE451DB /* chacha20_poly1305_x86_64.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = chacha20_poly1305_x86_64.linux.x86_64.S; path = Sources/CNIOBoringSSL/crypto/cipher_extra/chacha20_poly1305_x86_64.linux.x86_64.S; sourceTree = ""; }; + E81B478A234CDAB017868988B1FDA209 /* SDGraphicsImageRenderer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDGraphicsImageRenderer.m; path = SDWebImage/Core/SDGraphicsImageRenderer.m; sourceTree = ""; }; + E8263A32885981CDD291AF8C313E0131 /* polyval.c */ = {isa = PBXFileReference; includeInIndex = 1; name = polyval.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/polyval.c; sourceTree = ""; }; + E82FDE9D9EB4589FABB9CC02B87186AF /* getrandom_fillin.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = getrandom_fillin.h; path = Sources/CNIOBoringSSL/crypto/fipsmodule/rand/getrandom_fillin.h; sourceTree = ""; }; + E83089C79437628622D534CAA83363B4 /* SwiftNIOEmbedded */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftNIOEmbedded; path = NIOEmbedded.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E8457AC368411E1953DDF7BE182DA599 /* CNIOHTTPParser */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CNIOHTTPParser; path = CNIOHTTPParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E84BD2EE14B54889FE7A9DC744FB2076 /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCacheOperation.m"; path = "SDWebImage/Core/UIView+WebCacheOperation.m"; sourceTree = ""; }; + E87369BB0769E23EF24803F44A0F226F /* Scrypt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Scrypt.swift; path = Sources/CryptoSwift/Scrypt.swift; sourceTree = ""; }; + E895D3C198F54C3672CFF97EC77D18E4 /* LinuxCABundle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinuxCABundle.swift; path = Sources/NIOSSL/LinuxCABundle.swift; sourceTree = ""; }; + E8C0E874C7752604C945A86C83156ECB /* Client.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Client.swift; path = Sources/FlowSDK/Client.swift; sourceTree = ""; }; + E90DB3DF75F4249C5839DBB7B1F6B048 /* CNIOBoringSSL_engine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_engine.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_engine.h; sourceTree = ""; }; + E9504D4A1C7E0AA4D1702B0383635B87 /* ReadWriteStates.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReadWriteStates.swift; path = Sources/GRPC/ReadWriteStates.swift; sourceTree = ""; }; + E9767344EF78CB1C9C72E3387E88AC09 /* ServerBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerBuilder.swift; path = Sources/GRPC/ServerBuilder.swift; sourceTree = ""; }; + E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SVProgressHUD; path = SVProgressHUD.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E98C0F7953BE8F0580FC9DD009C52546 /* Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cryptors.swift; path = Sources/CryptoSwift/Cryptors.swift; sourceTree = ""; }; + E98CA796CC028075D66589D2DD00FD17 /* NIOTSListenerBootstrap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NIOTSListenerBootstrap.swift; path = Sources/NIOTransportServices/NIOTSListenerBootstrap.swift; sourceTree = ""; }; + E994D5025236EFF6DADE574DAF5538F2 /* UIImage+Metadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Metadata.h"; path = "SDWebImage/Core/UIImage+Metadata.h"; sourceTree = ""; }; + E99EA8807815163F01066C02261ADCC1 /* ecmult_compute_table.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ecmult_compute_table.h; path = src/ecmult_compute_table.h; sourceTree = ""; }; + E9D36A06D692CD1593D7474074E83834 /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImagePrefetcher.m; path = SDWebImage/Core/SDWebImagePrefetcher.m; sourceTree = ""; }; + E9EFF4C4B9DF5E0341500D3BDD455CE8 /* p256_32.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = p256_32.h; path = Sources/CNIOBoringSSL/third_party/fiat/p256_32.h; sourceTree = ""; }; + EA2A0AF3A809B6D227FAF4440D16DA91 /* tls_cbc.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tls_cbc.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/tls_cbc.c; sourceTree = ""; }; + EA49B891F4BD7B9F847A85FAE26BE8CD /* HTTPServerProtocolErrorHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPServerProtocolErrorHandler.swift; path = Sources/NIOHTTP1/HTTPServerProtocolErrorHandler.swift; sourceTree = ""; }; + EA7DCC5C12AD7E2C8657631AC471C25B /* TaskExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TaskExtension.swift; path = "Sources/FCL-SDK/Extensions/TaskExtension.swift"; sourceTree = ""; }; + EAA8959B66C811A04B4320E8DA8D7628 /* CNIOLinux-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CNIOLinux-dummy.m"; sourceTree = ""; }; + EACC63230D4C4319D211F27750098F39 /* AppUtilities.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AppUtilities.swift; path = "Sources/FCL-SDK/AppUtilities/AppUtilities.swift"; sourceTree = ""; }; + EAD70090C51A8155E88EE4B15A8090B0 /* CNIOBoringSSL_x509_vfy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_x509_vfy.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_x509_vfy.h; sourceTree = ""; }; + EADFD74CB52F0ABEA2C40E3903C69CEB /* liburing_nio.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = liburing_nio.h; path = Sources/CNIOLinux/include/liburing_nio.h; sourceTree = ""; }; + EAF179EF5BF07E33B49915C790AA9463 /* Interaction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Interaction.swift; path = "Sources/FCL-SDK/Models/Interaction.swift"; sourceTree = ""; }; + EB7F6195F500500561F1C0E2469545EF /* RequestBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestBuilder.swift; path = Sources/Core/Utilities/RequestBuilder.swift; sourceTree = ""; }; + EBC11F927EF369180412CF967C1C71A1 /* SDWebImageCompat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageCompat.m; path = SDWebImage/Core/SDWebImageCompat.m; sourceTree = ""; }; + EC0B3F23D2F2899609E05188B8AB2972 /* group_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = group_impl.h; path = src/group_impl.h; sourceTree = ""; }; + EC25E5C0E44AD4B8FE7567924453006D /* System.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = System.swift; path = Sources/NIOPosix/System.swift; sourceTree = ""; }; + EC4117C89342DC6DB6591EEE2778D12A /* vpaes-armv8.ios.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "vpaes-armv8.ios.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/vpaes-armv8.ios.aarch64.S"; sourceTree = ""; }; + EC4E7E433CE6A32FC3D02BF10F8A9E08 /* Pods-fanex.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-fanex.release.xcconfig"; sourceTree = ""; }; + EC58E07BCA5C6D8154968ED29DC0EF8D /* Array+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Array+Foundation.swift"; sourceTree = ""; }; + EC6D54E77894F35CA1EC1245BB57F3B0 /* String+unsafeUninitializedCapacity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+unsafeUninitializedCapacity.swift"; path = "Sources/NIOSSL/String+unsafeUninitializedCapacity.swift"; sourceTree = ""; }; + ECDEFD005DD0018E26210FF8F6A95B5C /* v3_conf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_conf.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_conf.c; sourceTree = ""; }; + ECE7EF9FF98C339A92B8CAF8E2EE2080 /* BlockEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockEvents.swift; path = Sources/FlowSDK/Models/BlockEvents.swift; sourceTree = ""; }; + ED381E7A1561E7D710199DF83CA03990 /* aesv8-armx32.ios.arm.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aesv8-armx32.ios.arm.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/aesv8-armx32.ios.arm.S"; sourceTree = ""; }; + ED387E83E449F79ECE1D3527813215E3 /* v3_int.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_int.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_int.c; sourceTree = ""; }; + ED8CCA0FCBBC5D24D493B41CECEC3C34 /* WatermarkedFlowController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WatermarkedFlowController.swift; path = Sources/NIOHTTP2/WatermarkedFlowController.swift; sourceTree = ""; }; + EDB2896CA76E4083FD655A1249E1241F /* CNIOAtomics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CNIOAtomics.debug.xcconfig; sourceTree = ""; }; + EDB2F023E8D4B7137FED7F6A435C3787 /* SDDeviceHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDDeviceHelper.m; path = SDWebImage/Private/SDDeviceHelper.m; sourceTree = ""; }; + EE25658DF6ED641DE4B9C84EE85F4AAD /* UIView+WebCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCache.m"; path = "SDWebImage/Core/UIView+WebCache.m"; sourceTree = ""; }; + EE376EECC27E33D291AAD2610B267511 /* tasn_dec.c */ = {isa = PBXFileReference; includeInIndex = 1; name = tasn_dec.c; path = Sources/CNIOBoringSSL/crypto/asn1/tasn_dec.c; sourceTree = ""; }; + EE715B9C7DA79D3E184910C877DFD198 /* String+FoundationExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+FoundationExtension.swift"; path = "Sources/CryptoSwift/Foundation/String+FoundationExtension.swift"; sourceTree = ""; }; + EE79390AA30BC15E638A709665466A6C /* CNIOBoringSSL_objects.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_objects.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_objects.h; sourceTree = ""; }; + EE93CD03907EE0EDBC912DB01B347EB8 /* UIImage+GIF.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+GIF.m"; path = "SDWebImage/Core/UIImage+GIF.m"; sourceTree = ""; }; + EE9A66F407FAFEF96BA9346ED325C854 /* CNIOBoringSSL_digest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_digest.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_digest.h; sourceTree = ""; }; + EEC7776718F9A0615E07E697E101BD00 /* t_crl.c */ = {isa = PBXFileReference; includeInIndex = 1; name = t_crl.c; path = Sources/CNIOBoringSSL/crypto/x509/t_crl.c; sourceTree = ""; }; + EEFFA244AF2F7CB9F637B306CE1884AA /* convert.c */ = {isa = PBXFileReference; includeInIndex = 1; name = convert.c; path = Sources/CNIOBoringSSL/crypto/bn_extra/convert.c; sourceTree = ""; }; + EF051C40E0CFD9F649039315312B2DE7 /* CodingUserInfoKeyExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CodingUserInfoKeyExtension.swift; path = Sources/Cadence/Extensions/CodingUserInfoKeyExtension.swift; sourceTree = ""; }; + EF06B86D5C779FC349D2DC6B37349507 /* aead.c */ = {isa = PBXFileReference; includeInIndex = 1; name = aead.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/cipher/aead.c; sourceTree = ""; }; + EF12325E188F77C0C95B571E77124B73 /* gRPC-Swiftp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "gRPC-Swiftp-umbrella.h"; sourceTree = ""; }; + EF13C39A51927AE32AFC954ED9417057 /* GRPCAsyncServerStreamingCall.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncServerStreamingCall.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerStreamingCall.swift; sourceTree = ""; }; + EF3AED7324AF2D4D94E0FFBAAF68EA96 /* GRPCChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCChannel.swift; path = Sources/GRPC/GRPCChannel/GRPCChannel.swift; sourceTree = ""; }; + EF5094047F1DE14436CA3AB5298C4593 /* PopupDialog.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PopupDialog.debug.xcconfig; sourceTree = ""; }; + EF67958A7B889FD32EE31BC5BD7153C2 /* ServerSocket.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerSocket.swift; path = Sources/NIOPosix/ServerSocket.swift; sourceTree = ""; }; + EF6E3A06093B1FBF24D0CDFA55E48E4B /* HTTP2SettingsState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2SettingsState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/HTTP2SettingsState.swift; sourceTree = ""; }; + EFEAB067865545587BA1DD5088599E0D /* Google_Protobuf_ListValue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Google_Protobuf_ListValue+Extensions.swift"; path = "Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift"; sourceTree = ""; }; + F0112394FA0D1C88F67FF17014ADD4AE /* Pods-fanex.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-fanex.modulemap"; sourceTree = ""; }; + F02D804318B912DB80C817AC1499A081 /* BloctoSDK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BloctoSDK.swift; path = Sources/Core/BloctoSDK.swift; sourceTree = ""; }; + F030EBCD1BB9F6809ACD10D556B7B1A0 /* p_x25519.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_x25519.c; path = Sources/CNIOBoringSSL/crypto/evp/p_x25519.c; sourceTree = ""; }; + F05FEE62851E94A769372DC3CD3E8335 /* QueryName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QueryName.swift; path = Sources/Core/Models/QueryName.swift; sourceTree = ""; }; + F06E3F0F68E87986C37B89E07CB61626 /* ServerInterceptorStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerInterceptorStateMachine.swift; path = Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine.swift; sourceTree = ""; }; + F0B0C4554A14955AF5120F1DA97B1C66 /* SDWebImageDownloaderConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderConfig.m; path = SDWebImage/Core/SDWebImageDownloaderConfig.m; sourceTree = ""; }; + F0DD1041FF36196DF02DE517716A5AE6 /* HTTP2StreamMultiplexer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2StreamMultiplexer.swift; path = Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift; sourceTree = ""; }; + F13848373B9F209766DB133A0176976D /* CBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CBC.swift; path = Sources/CryptoSwift/BlockMode/CBC.swift; sourceTree = ""; }; + F13CE72E4DE115E0CB8A9510566B58B6 /* GRPCClientStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCClientStateMachine.swift; path = Sources/GRPC/GRPCClientStateMachine.swift; sourceTree = ""; }; + F1474C32BD49331333311B100CE80555 /* CNIOBoringSSL_type_check.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_type_check.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_type_check.h; sourceTree = ""; }; + F1B3C4AB602AE6C7E11DC959C4F5F4D9 /* rsaz-avx2.linux.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "rsaz-avx2.linux.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/rsaz-avx2.linux.x86_64.S"; sourceTree = ""; }; + F1D3285305DE04F9777C0854D000D062 /* CNIOBoringSSL_pool.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_pool.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_pool.h; sourceTree = ""; }; + F1E99C30A6589FEA05F5C1AFAFE119DD /* internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Sources/CNIOBoringSSL/crypto/cipher_extra/internal.h; sourceTree = ""; }; + F20791D229474FF6C088B7939C535825 /* secp256k1_extrakeys.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1_extrakeys.h; path = include/secp256k1_extrakeys.h; sourceTree = ""; }; + F20B9FF634D7126C0E37A3AFF9CD0B2C /* aes128gcmsiv-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "aes128gcmsiv-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/cipher_extra/aes128gcmsiv-x86_64.mac.x86_64.S"; sourceTree = ""; }; + F252AC6CCD5977D44BA5C00A411DE274 /* CGRPCZlibp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "CGRPCZlibp-Info.plist"; sourceTree = ""; }; + F25954EBE6DCA38CB6072D0C2538EF9C /* JSONEncodingError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = JSONEncodingError.swift; path = Sources/SwiftProtobuf/JSONEncodingError.swift; sourceTree = ""; }; + F266418CB8BCC7A3BA24AD0C5A06BAF0 /* ServerHandlerProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerHandlerProtocol.swift; path = Sources/GRPC/CallHandlers/ServerHandlerProtocol.swift; sourceTree = ""; }; + F2B535D0CA6C53122205C5A6CDE8EFC0 /* UnsafeRawPointer+Shims.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UnsafeRawPointer+Shims.swift"; path = "Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift"; sourceTree = ""; }; + F2D1C122D30DFE497EE9723B76290229 /* TypeAssistedChannelHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TypeAssistedChannelHandler.swift; path = Sources/NIOCore/TypeAssistedChannelHandler.swift; sourceTree = ""; }; + F2F8FE0DA2B701325F9AE8CD81D9ECC0 /* ext_dat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ext_dat.h; path = Sources/CNIOBoringSSL/crypto/x509v3/ext_dat.h; sourceTree = ""; }; + F30262F08BA5B002A9DA4FA0B09FC1F7 /* CNIOBoringSSL_ex_data.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSL_ex_data.h; path = Sources/CNIOBoringSSL/include/CNIOBoringSSL_ex_data.h; sourceTree = ""; }; + F3073BCC2A47AC56DF49294324E56648 /* ssl_asn1.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_asn1.cc; path = Sources/CNIOBoringSSL/ssl/ssl_asn1.cc; sourceTree = ""; }; + F372FE0BD8E79C0C954CD7368DD56E4B /* NonBlockingFileIO.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NonBlockingFileIO.swift; path = Sources/NIOPosix/NonBlockingFileIO.swift; sourceTree = ""; }; + F37ABF268AD3432B45CED98A326932FB /* SDWebImageDownloaderResponseModifier.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderResponseModifier.m; path = SDWebImage/Core/SDWebImageDownloaderResponseModifier.m; sourceTree = ""; }; + F3DD926E581AA883A2946241C603809A /* p_ed25519_asn1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = p_ed25519_asn1.c; path = Sources/CNIOBoringSSL/crypto/evp/p_ed25519_asn1.c; sourceTree = ""; }; + F3E1CC848E4930BB28B8B18131408127 /* ObjectIdentifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObjectIdentifier.swift; path = Sources/NIOSSL/ObjectIdentifier.swift; sourceTree = ""; }; + F3F016C3BECF713FE493125FCC61F487 /* CancellationError+GRPCStatusTransformable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CancellationError+GRPCStatusTransformable.swift"; path = "Sources/GRPC/AsyncAwaitSupport/CancellationError+GRPCStatusTransformable.swift"; sourceTree = ""; }; + F3F7DDBE2182C2EEA7EE5F9F7EFA52A6 /* scalar.c */ = {isa = PBXFileReference; includeInIndex = 1; name = scalar.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/ec/scalar.c; sourceTree = ""; }; + F4101AADDF0EA95C8416FE6C5C9F8FB4 /* thread_win.c */ = {isa = PBXFileReference; includeInIndex = 1; name = thread_win.c; path = Sources/CNIOBoringSSL/crypto/thread_win.c; sourceTree = ""; }; + F41A865E94909DA53300849ECE5936E1 /* BaseSocketChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseSocketChannel.swift; path = Sources/NIOPosix/BaseSocketChannel.swift; sourceTree = ""; }; + F421E9463495ED8B3A343284F5A95ECB /* HTTP2PingData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2PingData.swift; path = Sources/NIOHTTP2/HTTP2PingData.swift; sourceTree = ""; }; + F43C7A8E64E38B5952F584AD678185F5 /* hash_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = hash_impl.h; path = src/hash_impl.h; sourceTree = ""; }; + F45C4839DB209C95B4EFAECE05A4A33E /* PopupDialogOverlayView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PopupDialogOverlayView.swift; path = PopupDialog/Classes/PopupDialogOverlayView.swift; sourceTree = ""; }; + F4750AA11686A2E12D6E8A31809AA2D2 /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = Sources/Core/Models/Error.swift; sourceTree = ""; }; + F497C9CF344483D772A5E2788BBF4BB1 /* DoubleParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DoubleParser.swift; path = Sources/SwiftProtobuf/DoubleParser.swift; sourceTree = ""; }; + F4FDD8C3A61E6625D29D34C8E4A8A9C9 /* CNIOAtomics.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CNIOAtomics.modulemap; sourceTree = ""; }; + F5BAA52FF2A5C1EBA66F5466604F5601 /* HTTP2ChannelHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ChannelHandler.swift; path = Sources/NIOHTTP2/HTTP2ChannelHandler.swift; sourceTree = ""; }; + F5D27B54D304A4F4AFCE4E3D33461AF5 /* HTTP2PipelineHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2PipelineHelpers.swift; path = Sources/NIOHTTP2/HTTP2PipelineHelpers.swift; sourceTree = ""; }; + F61BF97A058E4380C2240049EF36E9E6 /* derive_key.c */ = {isa = PBXFileReference; includeInIndex = 1; name = derive_key.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/derive_key.c; sourceTree = ""; }; + F64FC89200F8D0706E8CCAFD14914470 /* LengthPrefixedMessageReader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LengthPrefixedMessageReader.swift; path = Sources/GRPC/LengthPrefixedMessageReader.swift; sourceTree = ""; }; + F6801817E0996DB2058C8F032BBEF622 /* rc4.c */ = {isa = PBXFileReference; includeInIndex = 1; name = rc4.c; path = Sources/CNIOBoringSSL/crypto/rc4/rc4.c; sourceTree = ""; }; + F6B770EF99C3415FE53DCA48B48F61E1 /* evp.c */ = {isa = PBXFileReference; includeInIndex = 1; name = evp.c; path = Sources/CNIOBoringSSL/crypto/evp/evp.c; sourceTree = ""; }; + F72016BFA9188CA7F0C1612DB95E4A4B /* secp256k1Wrapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = secp256k1Wrapper.modulemap; sourceTree = ""; }; + F7333AB5B013C75729FD116AC76867A4 /* BidirectionalStreamingServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BidirectionalStreamingServerHandler.swift; path = Sources/GRPC/CallHandlers/BidirectionalStreamingServerHandler.swift; sourceTree = ""; }; + F7828C89FC15A295868A8D6D48408479 /* secp256k1_preallocated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = secp256k1_preallocated.h; path = include/secp256k1_preallocated.h; sourceTree = ""; }; + F79498A14802AEB00C50159F45431EBB /* GRPCClient+AsyncAwaitSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "GRPCClient+AsyncAwaitSupport.swift"; path = "Sources/GRPC/AsyncAwaitSupport/GRPCClient+AsyncAwaitSupport.swift"; sourceTree = ""; }; + F7A52911CA1238E07A642DC258ADB327 /* secp256k1Wrapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "secp256k1Wrapper-prefix.pch"; sourceTree = ""; }; + F7A91F4686FC34066E9F1F3B610CAEBF /* SVProgressHUD.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SVProgressHUD.debug.xcconfig; sourceTree = ""; }; + F7C81418EABA8EB915144461E60CACE9 /* SVProgressAnimatedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SVProgressAnimatedView.m; path = SVProgressHUD/SVProgressAnimatedView.m; sourceTree = ""; }; + F7EC63F48F6D767F3F3A0BF21AD9DB9B /* CompactMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompactMap.swift; path = Sources/CryptoSwift/CompactMap.swift; sourceTree = ""; }; + F81274EDB681F11E7CB05F7DCA2BB33C /* CryptoSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CryptoSwift; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F8269385F226C6592D280DB0D6625E88 /* Pods-fanexTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-fanexTests-acknowledgements.markdown"; sourceTree = ""; }; + F836D4A8C76F56D6DD73F426915AB52A /* SwiftNIOTLS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftNIOTLS.release.xcconfig; sourceTree = ""; }; + F84197669E7FAFA2A6430305A4B74647 /* obj.c */ = {isa = PBXFileReference; includeInIndex = 1; name = obj.c; path = Sources/CNIOBoringSSL/crypto/obj/obj.c; sourceTree = ""; }; + F854D5B6B19CCABE0F70B1C6422DDCD3 /* chacha-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "chacha-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/chacha/chacha-x86_64.mac.x86_64.S"; sourceTree = ""; }; + F85FBB12A3222F572D172DB14751E94E /* GRPCAsyncServerCallContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCAsyncServerCallContext.swift; path = Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerCallContext.swift; sourceTree = ""; }; + F8D469CE10346D8B8D052DA3DAEE9EFD /* OCB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OCB.swift; path = Sources/CryptoSwift/BlockMode/OCB.swift; sourceTree = ""; }; + F8DC87EB0A7B8E748FD15F55C32E2256 /* windows.c */ = {isa = PBXFileReference; includeInIndex = 1; name = windows.c; path = Sources/CNIOBoringSSL/crypto/rand_extra/windows.c; sourceTree = ""; }; + F8ED91581CA32AE9891FBC75E9198829 /* scratch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = scratch.h; path = src/scratch.h; sourceTree = ""; }; + F911CC7F62394A9AB0B666A7D3101E2D /* FlowCompositeSignature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlowCompositeSignature.swift; path = Sources/Flow/Models/FlowCompositeSignature.swift; sourceTree = ""; }; + F920BC94FE761A03B0EEB62522F35C9C /* SendingDataState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SendingDataState.swift; path = Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingDataState.swift; sourceTree = ""; }; + F922BA79034FCBFFDEF5221E779C3BBD /* RefBlockResolver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RefBlockResolver.swift; path = "Sources/FCL-SDK/Resolve/RefBlockResolver.swift"; sourceTree = ""; }; + F9244E289417969DA18D388116361D90 /* v3_akey.c */ = {isa = PBXFileReference; includeInIndex = 1; name = v3_akey.c; path = Sources/CNIOBoringSSL/crypto/x509v3/v3_akey.c; sourceTree = ""; }; + F92FBFA8D72DAC4D564472BB97707870 /* a_octet.c */ = {isa = PBXFileReference; includeInIndex = 1; name = a_octet.c; path = Sources/CNIOBoringSSL/crypto/asn1/a_octet.c; sourceTree = ""; }; + F93F9A99AE614D69C0F64C977EB127AE /* utility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = utility.h; path = include/utility.h; sourceTree = ""; }; + F9452C8340B87C5D87F7E13392F0D052 /* SDWebImageCacheSerializer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDWebImageCacheSerializer.h; path = SDWebImage/Core/SDWebImageCacheSerializer.h; sourceTree = ""; }; + F95229EF545043EA7BCF2D678483CC45 /* BaseSocket.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseSocket.swift; path = Sources/NIOPosix/BaseSocket.swift; sourceTree = ""; }; + F96BA613367923BBFF2F2DBD0354DAF1 /* FakeChannel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FakeChannel.swift; path = Sources/GRPC/FakeChannel.swift; sourceTree = ""; }; + F97962E42C217EF60D24440D061F34DE /* HTTP2ToRawGRPCStateMachine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTP2ToRawGRPCStateMachine.swift; path = Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift; sourceTree = ""; }; + F97E1D4476C75DA1152015FA92F5E874 /* gRPC-Swiftp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "gRPC-Swiftp.modulemap"; sourceTree = ""; }; + F98FEB534446DF2637FA145FD087C2E3 /* cpu_arm.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cpu_arm.c; path = Sources/CNIOBoringSSL/crypto/cpu_arm.c; sourceTree = ""; }; + F9A7769ABF2BDCDA505650A03B5AED87 /* SDImageAssetManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAssetManager.m; path = SDWebImage/Private/SDImageAssetManager.m; sourceTree = ""; }; + F9C93C63BAF9ABDE8D9F8A517D0B3E81 /* FunctionType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FunctionType.swift; path = Sources/Cadence/CType/FunctionType.swift; sourceTree = ""; }; + FA00B28287E667761380128BB484F4CC /* SDInternalMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDInternalMacros.h; path = SDWebImage/Private/SDInternalMacros.h; sourceTree = ""; }; + FA03486F566E13730B52AFCA100827EE /* SDDisplayLink.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SDDisplayLink.h; path = SDWebImage/Private/SDDisplayLink.h; sourceTree = ""; }; + FA0FF3EF9504A14378958B379D648B19 /* FlowSDK */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FlowSDK; path = FlowSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FA6659279DE10A5C642FEBD858FDB74F /* HashAlgorithm+Cadence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "HashAlgorithm+Cadence.swift"; path = "Sources/FlowSDK/Extensions/HashAlgorithm+Cadence.swift"; sourceTree = ""; }; + FA9B6B81A974AFAC9F65AF34375287F3 /* armv8-mont.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "armv8-mont.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/armv8-mont.linux.aarch64.S"; sourceTree = ""; }; + FABD24490DD4ED00306CA54635E45EF9 /* SDImageAPNGCoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SDImageAPNGCoder.m; path = SDWebImage/Core/SDImageAPNGCoder.m; sourceTree = ""; }; + FAD35F75EC94D2373D47C9CC59435702 /* SwiftNIOSSL-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIOSSL-dummy.m"; sourceTree = ""; }; + FADD4E85533236D815BDBC5585464254 /* pkcs8.c */ = {isa = PBXFileReference; includeInIndex = 1; name = pkcs8.c; path = Sources/CNIOBoringSSL/crypto/pkcs8/pkcs8.c; sourceTree = ""; }; + FB05FC2852DC3B82A137AFE1FD584A3E /* md5-x86_64.mac.x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "md5-x86_64.mac.x86_64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/md5-x86_64.mac.x86_64.S"; sourceTree = ""; }; + FB14291E43ACFF921F360FB93AF38517 /* blake2.c */ = {isa = PBXFileReference; includeInIndex = 1; name = blake2.c; path = Sources/CNIOBoringSSL/crypto/blake2/blake2.c; sourceTree = ""; }; + FB5655ACB7792921A9D8656260482B6D /* ConnectionManager+Delegates.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConnectionManager+Delegates.swift"; path = "Sources/GRPC/ConnectionManager+Delegates.swift"; sourceTree = ""; }; + FB7774CFEFF2CA175477B9CF9FE9E3DA /* SwiftNIO-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftNIO-dummy.m"; sourceTree = ""; }; + FBAD15A414C98019A77F53D9F0847B11 /* IntegerTypes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerTypes.swift; path = Sources/NIOCore/IntegerTypes.swift; sourceTree = ""; }; + FBCC7B0E2FB5F7C376254FBFC8169C43 /* BSDSocketAPICommon.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BSDSocketAPICommon.swift; path = Sources/NIOPosix/BSDSocketAPICommon.swift; sourceTree = ""; }; + FBD5B642CFF084A609C00F03399C12CE /* sha512-armv8.linux.aarch64.S */ = {isa = PBXFileReference; includeInIndex = 1; name = "sha512-armv8.linux.aarch64.S"; path = "Sources/CNIOBoringSSL/crypto/fipsmodule/sha512-armv8.linux.aarch64.S"; sourceTree = ""; }; + FBE3972F653181A13752675E7A877F2A /* GRPCWebToHTTP2ServerCodec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GRPCWebToHTTP2ServerCodec.swift; path = Sources/GRPC/GRPCWebToHTTP2ServerCodec.swift; sourceTree = ""; }; + FC260EC4C9B23C137D0191AC2936FC5F /* SwiftProtobuf-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftProtobuf-prefix.pch"; sourceTree = ""; }; + FC26EDDD6735D27600FA0D17B85868CB /* shift.c */ = {isa = PBXFileReference; includeInIndex = 1; name = shift.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/shift.c; sourceTree = ""; }; + FC515B3B56B84E2210FA56992DB9705E /* voprf.c */ = {isa = PBXFileReference; includeInIndex = 1; name = voprf.c; path = Sources/CNIOBoringSSL/crypto/trust_token/voprf.c; sourceTree = ""; }; + FC9D40188C134BF4D0132BAE23A32251 /* digestsign.c */ = {isa = PBXFileReference; includeInIndex = 1; name = digestsign.c; path = Sources/CNIOBoringSSL/crypto/evp/digestsign.c; sourceTree = ""; }; + FCCD4381FC5AE473243D1B1AAEBE4615 /* SwiftyJSON.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.release.xcconfig; sourceTree = ""; }; + FD23B53B0A47C0B9314C9B5EBCE50F98 /* add.c */ = {isa = PBXFileReference; includeInIndex = 1; name = add.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/add.c; sourceTree = ""; }; + FD318DB1E63E9531C89B293D34186B07 /* s3_lib.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = s3_lib.cc; path = Sources/CNIOBoringSSL/ssl/s3_lib.cc; sourceTree = ""; }; + FD3272BF10A705DA3798C673B76D5148 /* sha1.c */ = {isa = PBXFileReference; includeInIndex = 1; name = sha1.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/sha/sha1.c; sourceTree = ""; }; + FD32A762666BDBE51E1BFF3DFE7526C2 /* UIImage+GIF.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+GIF.h"; path = "SDWebImage/Core/UIImage+GIF.h"; sourceTree = ""; }; + FD4944D92039A49A17EC34979D0F9648 /* ConnectionManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionManager.swift; path = Sources/GRPC/ConnectionManager.swift; sourceTree = ""; }; + FD72A695D77BD4F392D0EBE936B2EB51 /* Pods-fanexTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-fanexTests-dummy.m"; sourceTree = ""; }; + FD99AF05FFC3A4C4404BB9C4D287D3BC /* ec_derive.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ec_derive.c; path = Sources/CNIOBoringSSL/crypto/ec_extra/ec_derive.c; sourceTree = ""; }; + FDBD5749F3FA2EEF750A1389E486D52C /* Bitwise Ops.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bitwise Ops.swift"; path = "Sources/CryptoSwift/CS_BigInt/Bitwise Ops.swift"; sourceTree = ""; }; + FDC3DE34332A925ED7AF74B4A48270C8 /* prime.c */ = {isa = PBXFileReference; includeInIndex = 1; name = prime.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/bn/prime.c; sourceTree = ""; }; + FDD6D466796CC73FB667BFD0CFF68102 /* ssl_cert.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = ssl_cert.cc; path = Sources/CNIOBoringSSL/ssl/ssl_cert.cc; sourceTree = ""; }; + FDDD2D73E4D2EECF3B63527CD28F21CF /* SwiftyJSON-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-umbrella.h"; sourceTree = ""; }; + FDFDAD50B9C60762A8D0B9C0536B97BD /* shim.c */ = {isa = PBXFileReference; includeInIndex = 1; name = shim.c; path = Sources/CNIOLinux/shim.c; sourceTree = ""; }; + FE0EEBF7DAFFF2F7679DDA958B59770C /* HashAlgorithm.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HashAlgorithm.swift; path = Sources/FlowSDK/Crypto/HashAlgorithm.swift; sourceTree = ""; }; + FE16B6E629E3869F9CC21C3710AEE4C2 /* UnaryServerHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnaryServerHandler.swift; path = Sources/GRPC/CallHandlers/UnaryServerHandler.swift; sourceTree = ""; }; + FE25F61CB7A64F0BDD6A737277034E91 /* CNIOBoringSSLShims.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CNIOBoringSSLShims.h; path = Sources/CNIOBoringSSLShims/include/CNIOBoringSSLShims.h; sourceTree = ""; }; + FE4127318ACB65C0E8D0BEE1BF74A804 /* Signature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signature.swift; path = "Sources/swift-crypto/Sources/Crypto/Signatures/Signature.swift"; sourceTree = ""; }; + FE41B596CC64683D3C1C0FE068823186 /* ExecutionResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExecutionResult.swift; path = Sources/FlowSDK/Models/ExecutionResult.swift; sourceTree = ""; }; + FED43552635768BCC4C78BEE32DCA1A5 /* e_rc2.c */ = {isa = PBXFileReference; includeInIndex = 1; name = e_rc2.c; path = Sources/CNIOBoringSSL/crypto/cipher_extra/e_rc2.c; sourceTree = ""; }; + FF02BEB41B3324A7EDE9B47B64D29E11 /* ServiceMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceMethod.swift; path = "Sources/FCL-SDK/User/Service/ServiceMethod.swift"; sourceTree = ""; }; + FF2320961936E59CBDAB2EBF11A7B62A /* ex_data.c */ = {isa = PBXFileReference; includeInIndex = 1; name = ex_data.c; path = Sources/CNIOBoringSSL/crypto/ex_data.c; sourceTree = ""; }; + FF3C424009C0D93BF5CE0E36B2C00792 /* secp256k1Wrapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "secp256k1Wrapper-dummy.m"; sourceTree = ""; }; + FF5F179B7546D92B3E3DD6C93F2C0164 /* ECDH.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ECDH.swift; path = Sources/secp256k1Swift/ECDH.swift; sourceTree = ""; }; + FFDC3033E57BC05599C5A99C4F1DD735 /* cbc.c */ = {isa = PBXFileReference; includeInIndex = 1; name = cbc.c; path = Sources/CNIOBoringSSL/crypto/fipsmodule/modes/cbc.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 073CA4512703A07BDC442F4FD27A9E22 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1AD82970D2B7334CBC8C42BF4C794143 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0946B4E873FB949D224E88B60E4FF80F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 178672167BEBFDCC7789B6A50D766009 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0F7A1490E2F76ABB8A5DF1D057276C16 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 78CF56076ED4F5CD8A9E06408FF38638 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0F86543F55314FBBF35C1594CC0A8E84 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6032C795642C2EF4FE1D580FAB9DD4AB /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 11379356021538EC61B49D0E27E3FEE9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CBC2CC340CD4CFCD60F9A30BC9E0955C /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 178F22DBE49565BEBFE6AFB867DD4F37 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 419470CFF238F966CABFA15C324BEB42 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1901CEF914F1C89526CC7B4B5A34B640 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A58E08C2BE122504E1A73341C560DB00 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1D5D6473CB29A09AB0E6A90F39C96C59 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3BF2D5C59B1CED39EB16613E4BEE1AFF /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 215C40FEC0DC42A170CEB2E87F7A25F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F82A064DB011FD573481889639DA4AEE /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24A6F86BA2803C14A9F67847915AA75C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3FA64CC0150CC8785A449CD2BA0AE4A9 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2BDE80FC9CC2D9C431FA8D6072EA251B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1C2E294E64DD6F42A4E308ED052922DA /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2E4080B5667EA5F40655DC585E459595 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EC3D9E3E5CA1A27A875F58D876E2EF70 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3473C50E39D59A32F55704D7C6273327 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1327F3B8D187244BF4E16BBD4173AF0B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 390F21EFEDF9FC3E399CC8CE8937F47D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4FFB10F8CB368E03F334BCE0D2A311E9 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3BAB6E77DD1FBC909964C39643F21244 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1BCDAB3C011B6B584B7BAF5B8787A2D0 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 43844D13DA6F3C2ED9E726566123C95E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D720A60BC531A3ADC5EC2FDA68D40763 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 45B80BBEA22F6A6BF03C644DF50F8554 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F91E4C7F2AA392410D84A4D4FA201368 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 514B9E896711AE5537D281C13B6B0006 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8ED98FC7E7FF6796ED2C55C02477DDF4 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5A1969DD96E266CCC8111344B0D442C4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A4487E9A50688C36A2B754451C60F03 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5BE3C5EFF74402BA5397C8D27800D20B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EFB6C0A49787457FEE34CAA9C221FB17 /* Accelerate.framework in Frameworks */, + 341368BF38E97ACFAF3F0866C1BB77D1 /* Foundation.framework in Frameworks */, + 40325640A5E0EAEBF4D95BEBC09ED112 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FC030FC787D52EA132C88F9D20DD8A5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A9252C247626E6F799ECEFD2030A4617 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6B0B3CF7F2918518C073EBF75E188E1B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 889B05E4CE86D14A10E9C9DAC2B3E7B7 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7441BBBDBDCFBFCBDAB0F7775006F626 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A01F905BA277D75B6EBDE576C63BBFE6 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 765078170972CBD9E41B13D3C3979878 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 16CBEFA7C019A9551338BFDD1A43BFCB /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 824EA4E007FC2D3DB34A248D1C3C2BB1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DAF8A77BF7CFE74D7C9586D51DE81434 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 835A33FE7E2A55D3B766195C72E8C42D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9B1477CFA378038EE96F941438F75D81 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 85AB6077A53F66F59AC1A7700E37DF8B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 12C6D94FCB6D192C318198975AF8FB14 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 89627D7C265FE6982EB6CA811534A889 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D5D7BDA3AA7F9F267A93814DDD81A880 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 906AAB1325A370AFE920A1629E1C3563 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F5BC1AC29184091891661463D97A0EF0 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9F9332661014D80C00B6057EFF424E30 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 337EB308AF27E38233BE5BBA64822443 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B37AFD44EC7D46A5FBCB40FBAE3363CF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FF378778F3B30B260D277BDAFE77EFE8 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C46E597B7C52B4A38582CB8B9E6187DB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 035327CF4C657115EE5A64D2A6408C90 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CC750A63195DFF5FDAA9CCAD5E3BB26B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8E1A4C31C11C323D4250DC77A6452505 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D144877115364218CA9245F54AF958AF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EBD6019AD15D1E3DE7D54A018E977DA9 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D85857194C8750BC9CC1799F7E65BA08 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F61E5D02AAC4F81630437B1CB05FD5BE /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA76E43865D6C2D14F5422C200700BEB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6F2F1E12BD5D187DB9255732FD24BB8E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB5DF2EA7D8E53A74519F53BFFD43AE3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F6CD3F5A60CAD8157A3289A434A81FD0 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E389FF082B036E756B0679583C1BE62E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 798FA71F8CAE44D05016FFF767100375 /* Foundation.framework in Frameworks */, + 53BECA6AA55F80D63F104475EE6524CA /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE2D4D0DCA16BD182E75192E712C77EB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9DD5C68AEBD2F6E0C8BC97F1B11136A9 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE86003DCE4F23984637FC53FD4FE685 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DBF4B4D6EE8593C2D5AE41DA9A160D33 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F9DF974592A7823164CD2C4206C3882F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 85593576AAEB9671294E2C539DE2C70C /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FB6A1E8A43CF1D3ADFB49BA355F0DEA1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5A3E5B854E8188DDF4E958BBC9198600 /* Foundation.framework in Frameworks */, + 51F891EA712D8F14CF1DD77BF20B62A9 /* ImageIO.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 00056531FCF5A77CBC33540D3F0BD8DB /* SwiftNIO */ = { + isa = PBXGroup; + children = ( + C9F50EBBC228643BBF9686C9B450DB58 /* Exports.swift */, + 0B695AA1C5011E633B93A4900CA1C5CF /* Support Files */, + ); + name = SwiftNIO; + path = SwiftNIO; + sourceTree = ""; + }; + 0008426395B7E4AA04FAC96D42D40D8D /* Support Files */ = { + isa = PBXGroup; + children = ( + 0A4C652F98037553C4AA0E5E81811923 /* CNIODarwin.modulemap */, + B13ECBBEA21F99BFECD0DD09E5C0B7A0 /* CNIODarwin-dummy.m */, + 603EC9C5ECD9FEB15F1FD72336FDB40B /* CNIODarwin-Info.plist */, + 56EC97BCE868A9664BDC8893A3962076 /* CNIODarwin-prefix.pch */, + E71DDD9AEF01CB88D7D69EC16C54A094 /* CNIODarwin-umbrella.h */, + 01B66A124FC2BBB446F619F5F98F4ADA /* CNIODarwin.debug.xcconfig */, + 7D09D70EE4A5398949BD23971F06909A /* CNIODarwin.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIODarwin"; + sourceTree = ""; + }; + 043C39176A2DC155069954627219A9F1 /* Support Files */ = { + isa = PBXGroup; + children = ( + 3D9A44DCA7C25E6D914D065F57872D37 /* Logging.modulemap */, + ADB47706A4A069D6173C880CA9EEC239 /* Logging-dummy.m */, + 6DBEB0B449511C620D93E016D0AD9C3F /* Logging-Info.plist */, + 281C99726698FD07704A83C0E4CA33FB /* Logging-prefix.pch */, + 024DE6CD691DEF3BBDAE8A50B8D56DF0 /* Logging-umbrella.h */, + 8489F90B00219E2F816445944BEF3D01 /* Logging.debug.xcconfig */, + DBE34A1D672AD2579D3BB755C51A5C5B /* Logging.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Logging"; + sourceTree = ""; + }; + 0B695AA1C5011E633B93A4900CA1C5CF /* Support Files */ = { + isa = PBXGroup; + children = ( + 4F1891472D5631F287DFBCEDA49E9244 /* SwiftNIO.modulemap */, + FB7774CFEFF2CA175477B9CF9FE9E3DA /* SwiftNIO-dummy.m */, + B8AA754EBAFF03CB7D0D93E72C524C95 /* SwiftNIO-Info.plist */, + 78431EA97C0C20246C4833012B325706 /* SwiftNIO-prefix.pch */, + A38B7CA9A787A9EB473D611E8A8F23C8 /* SwiftNIO-umbrella.h */, + 76EFDA04C75D0547F58E8333515A45AB /* SwiftNIO.debug.xcconfig */, + DC24001B0B936C4BAD8F8EACF07E466C /* SwiftNIO.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIO"; + sourceTree = ""; + }; + 0E276015E92A039D80211D4EEFAE2C89 /* _NIODataStructures */ = { + isa = PBXGroup; + children = ( + D3ADD3A261C519861223F27639A1EB81 /* Heap.swift */, + 4527FDF828AF69BDCF723726E37DE46E /* PriorityQueue.swift */, + 39EA2ED607F4044D24B973EC84BBCFAB /* Support Files */, + ); + name = _NIODataStructures; + path = _NIODataStructures; + sourceTree = ""; + }; + 0E76BE7B2B28B632D16B7D37215CBF8F /* SwiftNIOCore */ = { + isa = PBXGroup; + children = ( + 6DBD255DD3EFE8B8F18EC77884784289 /* AddressedEnvelope.swift */, + C661B04F55355271A9F8DCD687D303AE /* AsyncAwaitSupport.swift */, + 81B64ADFE4BDE44F8BB718A1F9322757 /* AsyncAwaitSupport+OldXcodes.swift */, + 55323FF6763FDF0FD55A710B19CA1549 /* BSDSocketAPI.swift */, + 5BD06CC435D05FAF9356A9E55E340DAF /* ByteBuffer-aux.swift */, + 9D80CD66E9C87158F6F5D67AFFED62EB /* ByteBuffer-conversions.swift */, + 0AD6EEDAB47DBB048F944F50271E9FE0 /* ByteBuffer-core.swift */, + 567DAE15E7F0276F6621B62348EBBFD5 /* ByteBuffer-int.swift */, + 81CA65DAA499F4180D7F20A100FDA6EE /* ByteBuffer-lengthPrefix.swift */, + 5632E69283B9EC57F1BD922821CC8E35 /* ByteBuffer-multi-int.swift */, + 29D2F5F9D2EBCABD0650C3DD9B6F124B /* ByteBuffer-views.swift */, + 634AC0A70874A63C45F2B35E58DB4BDC /* Channel.swift */, + 712C37FF555DF1B9B58D9576DF3FB848 /* ChannelHandler.swift */, + C827709A684A15363ECD8BA2B8F989F8 /* ChannelHandlers.swift */, + 7646B3AFC5E6A30618DD8AF57E8D8B04 /* ChannelInvoker.swift */, + 36483716E2DF6E768945736F78E8A549 /* ChannelOption.swift */, + 7AE40AFE7EFA92E72357747043244CE2 /* ChannelPipeline.swift */, + 22988D09847FF0EFBB7BF71B1818201F /* CircularBuffer.swift */, + E753CB8B7DA12B68CE4372634BD6037C /* Codec.swift */, + A4AE6EBD52125EB64187C198B9998052 /* ConvenienceOptionSupport.swift */, + 84650E9EF8B829CC71F475A58EF9FA97 /* DeadChannel.swift */, + A8A6BA1B7B49FA8AAD4FD76EB06F865E /* DispatchQueue+WithFuture.swift */, + 4895F0708E8EB50CD4A750A9511AE34F /* EventLoop.swift */, + 6B92469E0E33F66124F5C1D3EB3EC364 /* EventLoop+Deprecated.swift */, + 5A26731C91E6BD1C0ADEFC3D162CB1B6 /* EventLoopFuture.swift */, + 0F5BBB57A935727EEF21A5AF26FE7A1E /* EventLoopFuture+Deprecated.swift */, + 17130905A7954A110258063CF2BB0C33 /* EventLoopFuture+WithEventLoop.swift */, + 1E810951424A6E5BC0AF196C7E0520B1 /* FileDescriptor.swift */, + 04D2CC12E6E6166F2F0A662EDE733AE0 /* FileHandle.swift */, + B64F7DA6E0B11E2AB6D1CFBF2BB4CBC8 /* FileRegion.swift */, + AFB49AEFC8709DEE496D85E1E049F85D /* IntegerBitPacking.swift */, + FBAD15A414C98019A77F53D9F0847B11 /* IntegerTypes.swift */, + 7AC5763D6A87662250C6ADCCEE75095A /* Interfaces.swift */, + 006D290CE0E3AA073250AE2695602D44 /* IO.swift */, + 2DE2E6E1CA325F9BF2A6343630420EFB /* IOData.swift */, + 64003FC3B36480A559C1E01B4E5180DE /* Linux.swift */, + 7A1535AA5F7C7E64787C97A332A65291 /* MarkedCircularBuffer.swift */, + 043AE59D361B71B5E48ECC54B7625B1A /* MulticastChannel.swift */, + 673FA8BD54C5D615B1D6EB9067EF13E8 /* NIOAny.swift */, + E03FB9C4D7EBB4B177BAE64292C69AD1 /* NIOCloseOnErrorHandler.swift */, + 215056034A9C8EA82C4CC47FCD5CC9A6 /* PointerHelpers.swift */, + DBD38889D7644ED72769E8B659531B54 /* RecvByteBufferAllocator.swift */, + B71DB02A1F498F92F0D682A10F39B7CA /* SingleStepByteToMessageDecoder.swift */, + 5AAAE61AA716A70C5261F8FA6A98E4C9 /* SocketAddresses.swift */, + 10B329999DE3EE0D8E00FA0D425AEFC3 /* SocketOptionProvider.swift */, + 674C78CA48A7FE09DFCE8F6C367C6AD9 /* SystemCallHelpers.swift */, + F2D1C122D30DFE497EE9723B76290229 /* TypeAssistedChannelHandler.swift */, + 22D1A79C4C0AB646702F14CD7CB5F31C /* UniversalBootstrapSupport.swift */, + D462F248FEBAB1C92771B296C65AAB45 /* Utilities.swift */, + 731F27313F119E78BB6042A85B922F27 /* Support Files */, + ); + name = SwiftNIOCore; + path = SwiftNIOCore; + sourceTree = ""; + }; + 14DC9AB0E6D91B6C756922A4CE0BCCA8 /* FlowSDK */ = { + isa = PBXGroup; + children = ( + A1590218E00A6F2E93D7E8640D81887C /* access.grpc.swift */, + 2B348362474913E38AF17055678DF7C7 /* access.pb.swift */, + 96FB297C04A70F53F4B0206297549C27 /* Account.swift */, + 73D79B0FD81FD36CF6C4267556FBAC5C /* account.pb.swift */, + A1BEA579A59439676E2AA53871A081BA /* Block.swift */, + 8AA17A649FAE8060A699174BFD83D0C3 /* block.pb.swift */, + C9B845CFDE312262625CAA4A7C843065 /* block_header.pb.swift */, + 61D33AA2633CE5706C3EE91FBDCC3D29 /* block_seal.pb.swift */, + ECE7EF9FF98C339A92B8CAF8E2EE2080 /* BlockEvents.swift */, + E8C0E874C7752604C945A86C83156ECB /* Client.swift */, + 42A115EF9B5E2AD5EEB58AAEA68FFD8D /* Collection.swift */, + 3714076099ED9A889D91939B3943B37D /* collection.pb.swift */, + 4CE71D92B1BAC8A1856C21B6C893EEED /* DomainTag.swift */, + CEB19D0C3B111ABDA93C9E962F460016 /* Event.swift */, + D7AC2EC3666BF3283F5E15A69EB7D3B5 /* event.pb.swift */, + 2610510E35410963A2FB651DA639BA4C /* execution.grpc.swift */, + DAB2A7A0E6EB30C6DFB50B3042E6EEE4 /* execution.pb.swift */, + B39945BEE0BA25547BEE869FDD63873F /* execution_result.pb.swift */, + FE41B596CC64683D3C1C0FE068823186 /* ExecutionResult.swift */, + FE0EEBF7DAFFF2F7679DDA958B59770C /* HashAlgorithm.swift */, + FA6659279DE10A5C642FEBD858FDB74F /* HashAlgorithm+Cadence.swift */, + 57A1FEA4E83370409F5570F73F0B9838 /* Identifier.swift */, + BDE3529B4144EF636975040E170E6470 /* InMemorySigner.swift */, + B76FE45529FA7930D3992ADBA1E05047 /* Network.swift */, + DA9C6551A4C7E622106E3008ACCFC4A2 /* PrivateKey.swift */, + 84DD29ACB4CAE8D176D00306632D91B8 /* PublicKey.swift */, + 431FB716FA31D9BC5168E6D7645EAB0C /* PublickKey+Cadence.swift */, + 71ABE852F923874D69D84A7984A91B85 /* RLPDecodable.swift */, + 1E02FC64457E1330FD2D59B8A42CDDB9 /* RLPDecoder.swift */, + B70B5A4EC9A2152DEE80BCF8F5BADA95 /* RLPDecodingError.swift */, + D1CC2A12C07D5515B9B8E785234834B4 /* RLPEncodable.swift */, + E667AE513A07C5DA03178515082AB7ED /* RLPEncodableList.swift */, + BC5572EABD4F6E36821E4ABD2AD4B09C /* RLPItem.swift */, + E7B48DD881BF8AE6BDC689EB96936503 /* SHA256Digest.swift */, + B55D91D9519BCE3F60C8F6510F17EB0B /* SignatureAlgorithm.swift */, + DCAEC86F60F8795EC88E6D54463B62AC /* SignatureAlgorithm+Cadence.swift */, + 1477C5AA1AAA188540A3BFC4FA21B928 /* Signer.swift */, + BE17D22B26A6B724BC41BC503CCE139F /* Transaction.swift */, + D7C19014ED3BF4FE7F33FD701C930DB9 /* transaction.pb.swift */, + E0CB49F4D5C20983310803D707A2EAF9 /* TransactionProposalKey.swift */, + 30F8A9FFAD9DD5E2DCC1B6D55F8B31A4 /* TransactionResult.swift */, + 91DA5E04F67C81D9A610BFDE1B7E6A81 /* TransactionSignature.swift */, + ); + name = FlowSDK; + sourceTree = ""; + }; + 192F89A6E9764A181E0372C191523A73 /* Support Files */ = { + isa = PBXGroup; + children = ( + 84D167E6FCBE27D8E5E6BC4A30A076EC /* CNIOBoringSSL.modulemap */, + 019179E7EBA346AA3B2A3C0DA52BD554 /* CNIOBoringSSL-dummy.m */, + 490CD9C4E3DE9C27BFBC75726FB70169 /* CNIOBoringSSL-Info.plist */, + 8DD02F2712EDB42025E6D5142E561917 /* CNIOBoringSSL-prefix.pch */, + 154D8E8D0F6B17F4D864A80C3C2543A1 /* CNIOBoringSSL-umbrella.h */, + 9353F679479027B35261BCF58CD26951 /* CNIOBoringSSL.debug.xcconfig */, + 9AFBF96323889F7EAF96656004366771 /* CNIOBoringSSL.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOBoringSSL"; + sourceTree = ""; + }; + 1A228F1BFDBCA358CAAF0ABD27597E5C /* secp256k1Wrapper */ = { + isa = PBXGroup; + children = ( + D36C79BBBBA3A45553902A70E34CFBC1 /* assumptions.h */, + D87C163D2F9A6289B1C80E3AB8459790 /* basic-config.h */, + B1E390FCD5668D1ADFB9CCBEEADDA960 /* bench.h */, + 43C1ABD90C5C3F8E73ED1658CA23F8A4 /* ecdsa.h */, + 31B37A38F26CFA3F17CD9667A71A9768 /* ecdsa_impl.h */, + 0F218B3EC4501CDBF5A97164AEFEFB25 /* eckey.h */, + 9E2F291C8EAA7B8A3F81A388D7280711 /* eckey_impl.h */, + A1125F1577E36499C027A5A9272733CD /* ecmult.h */, + E99EA8807815163F01066C02261ADCC1 /* ecmult_compute_table.h */, + 56707F1F35E9FA8B9C5BC03F1F30820D /* ecmult_compute_table_impl.h */, + 3BECF935580ED15BE7BBED8A011B189E /* ecmult_const.h */, + 6DB89C0E4A195E152E33D752C7ACFC25 /* ecmult_const_impl.h */, + 7AB5E959B806B6D0CF955CF738AC44A6 /* ecmult_gen.h */, + 88A52EE3F3AFDBB44C3592AD31A41FBD /* ecmult_gen_compute_table.h */, + 288D1967128600890475281F1DE4AF11 /* ecmult_gen_compute_table_impl.h */, + 49A97EB307AB2A06BDBEE9950E524D56 /* ecmult_gen_impl.h */, + D8A3BC28D5AFF50B3CF081A56F0AD709 /* ecmult_impl.h */, + 5CA1003700742FCF9A856FE54DABB5BD /* field.h */, + 9ECEA2B23797D093DC1226DA47AB8BBA /* field_10x26.h */, + 3E0AC26AB92B81B956F7247841234F11 /* field_10x26_impl.h */, + 8CFE5772B62649A74A68BF90457734A3 /* field_5x52.h */, + 38B7C580C98CD15D9B5D5099A582F50F /* field_5x52_asm_impl.h */, + 86BE3FABFFCEF31E8FB55DE029BD0F0B /* field_5x52_impl.h */, + E5160EE97B79C9809A0F792E3F645C72 /* field_5x52_int128_impl.h */, + 31DA3AB6DBAC8E44A9983629C3A978AA /* field_impl.h */, + 3435A3B12A63A7FCB7B93A5B38A01B4B /* group.h */, + EC0B3F23D2F2899609E05188B8AB2972 /* group_impl.h */, + A230DA09837C434CE63C8CEC8CB6FB07 /* hash.h */, + F43C7A8E64E38B5952F584AD678185F5 /* hash_impl.h */, + AE7382BF76136F84B7A70C79D72F7E1A /* main_impl.h */, + 3B0554ECD8C9BCA36CB6736F494816F1 /* main_impl2.h */, + 7175926837E08AC3D16D3F34A114B9A0 /* main_impl3.h */, + 2257ABEBE7B0BE768733AA198201002D /* main_impl4.h */, + 3C5D5F0E96517B6A2FD7F1E6CC11A961 /* modinv32.h */, + 4817559D2BD0D488311A04F0D16CB83A /* modinv32_impl.h */, + 807F99CF0921EFD7AAF68E2FFACE71BB /* modinv64.h */, + CA44D2212E0CBD1D2922B7C5B191F102 /* modinv64_impl.h */, + 32A8A8AEB4DC5E8D8F8540AE22FA44F6 /* precomputed_ecmult.c */, + A9DCA49E1FFA9607497E9C6B8239270D /* precomputed_ecmult.h */, + 0E4AF999BF1254DD47727C2AEB7CBE48 /* precomputed_ecmult_gen.c */, + 7D7B8E5E7945F60A19C07B8006CB4BEB /* precomputed_ecmult_gen.h */, + 7513FDB345A1F65E3221C98807F698A9 /* scalar.h */, + 476278A16583C8538AFE1DEB99804DC7 /* scalar_4x64.h */, + 20923CBF0D3E28FE03BFD939A5269687 /* scalar_4x64_impl.h */, + 494D5E014AD83FD2360542A6642709E3 /* scalar_8x32.h */, + 07424D645F2E9ACEEF471C2D45E734F9 /* scalar_8x32_impl.h */, + 1B9F59DEEB501854CB292BA30EED9FE1 /* scalar_impl.h */, + 47FEF39B78A6E02C765B4C708648B7A1 /* scalar_low.h */, + 75640331ACC3A5E4B6CBA6DA62F539A1 /* scalar_low_impl.h */, + F8ED91581CA32AE9891FBC75E9198829 /* scratch.h */, + 681CE7F242DD1F94F884B8952827D0C4 /* scratch_impl.h */, + BAD1E7D62CBA874732C8DBB7B121F54F /* secp256k1.c */, + 68E783BE195DDBA1CB7656608D41E62B /* secp256k1.h */, + 689ED28F1F4352CF81582818D9F4EB64 /* secp256k1_ecdh.h */, + F20791D229474FF6C088B7939C535825 /* secp256k1_extrakeys.h */, + F7828C89FC15A295868A8D6D48408479 /* secp256k1_preallocated.h */, + 796848D95E9BA10B25A83BC6FAC6279D /* secp256k1_recovery.h */, + 40AEBB2D920B40CB9140D666883A8F17 /* secp256k1_schnorrsig.h */, + 8B504D41BF6D241A3F017DB3191ECC91 /* selftest.h */, + 66E55B569C5EE21BB5AB9F6E5D66EB77 /* testrand.h */, + 77FCB4602CFB8CFE7B1942923867936A /* testrand_impl.h */, + 42C55DECF218CAD487EE2130755E8D2D /* util.h */, + 8B01738680478070311F7465DBD996A2 /* utility.c */, + F93F9A99AE614D69C0F64C977EB127AE /* utility.h */, + 9F767438567EC93BD7E8A4F7FE312FD0 /* Support Files */, + ); + name = secp256k1Wrapper; + path = secp256k1Wrapper; + sourceTree = ""; + }; + 1F92BB4F1ECD057E9E622F5BDBB2EEF9 /* BloctoSDK */ = { + isa = PBXGroup; + children = ( + 733DE0C352BAE50A5C3FA5ABFE35813C /* Core */, + E28761A96500BEFAFD13006937037172 /* Flow */, + AD963F49BB57316ED108CF46A11CD0EF /* Support Files */, + ); + name = BloctoSDK; + path = BloctoSDK; + sourceTree = ""; + }; + 1FF58983CA01319C76E76B3D9B8E1B06 /* Support Files */ = { + isa = PBXGroup; + children = ( + 7F507707B2353A74A5C1204E3238AB67 /* SwiftNIOSSL.modulemap */, + FAD35F75EC94D2373D47C9CC59435702 /* SwiftNIOSSL-dummy.m */, + 2BB1B6E58F42F0A1C956FB24D13586B3 /* SwiftNIOSSL-Info.plist */, + 2EE2751E013EF458FC67C5EBFFC5039C /* SwiftNIOSSL-prefix.pch */, + C08AA9786D7C02B53B65E79786224F2A /* SwiftNIOSSL-umbrella.h */, + 8A7DABB47C717F3A0AE17A086BF808B5 /* SwiftNIOSSL.debug.xcconfig */, + 0F8181A38BFEE82303D4BD20E1B79BA7 /* SwiftNIOSSL.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOSSL"; + sourceTree = ""; + }; + 261AE1C049581FD90AAC18D1AAD586D2 /* Support Files */ = { + isa = PBXGroup; + children = ( + C2158C32C48DE5625C49C2199495659E /* DynamicBlurView.modulemap */, + 1F8E7AF066F0911188C195EF539855E4 /* DynamicBlurView-dummy.m */, + 075CFC2142202D06EF31BDC7AF046762 /* DynamicBlurView-Info.plist */, + 8827950DD3810708BE7B6452799C3145 /* DynamicBlurView-prefix.pch */, + 63647EC3A1665A41F433DFD09501F254 /* DynamicBlurView-umbrella.h */, + 2AB7DAA6F97DF10E00BD54DAB7CFD793 /* DynamicBlurView.debug.xcconfig */, + 2C3C2254EB57228190A1B6A024B26C52 /* DynamicBlurView.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/DynamicBlurView"; + sourceTree = ""; + }; + 2AE30BF349948286FA0B2E9F19D1B9F8 /* SwiftNIOFoundationCompat */ = { + isa = PBXGroup; + children = ( + B61CDA0D8685E7D3CD7FE1286FFFEC4F /* ByteBuffer-foundation.swift */, + 54EB52F4DE857E6CA5BC27C60BFAA047 /* Codable+ByteBuffer.swift */, + 5E1B86F03FEB77983C03E9095597B3C2 /* JSONSerialization+ByteBuffer.swift */, + A72CA0F77539A80028A207CEB469A88F /* Support Files */, + ); + name = SwiftNIOFoundationCompat; + path = SwiftNIOFoundationCompat; + sourceTree = ""; + }; + 32BC918F52C57E8AEE25B197D0AACB84 /* Cadence */ = { + isa = PBXGroup; + children = ( + 30B1390D47F4087E0018F33553778E55 /* Address.swift */, + 92F1410EB55386BE15D50D734605E346 /* Argument.swift */, + 3A6622BC3A5738284B4FFB7EE3E49AC7 /* Capability.swift */, + EF051C40E0CFD9F649039315312B2DE7 /* CodingUserInfoKeyExtension.swift */, + 29FA795821AE0DC47490E02DE1710064 /* Composite.swift */, + 53CA88BB7B03385B102806F68F723F32 /* CompositeType.swift */, + D736863024538C0336937C1263FBC4B9 /* Dictionary.swift */, + B8F6E98384A8607B14786C60260DA7E7 /* EnumType.swift */, + E05AF864C3E9FEE08D516DE2E350E390 /* FieldType.swift */, + 334BFB5B2E3B497E2F56969B867E12E4 /* Format.swift */, + 3E0708E7CD171E1FC77EDE99034EC939 /* FType.swift */, + 38D7A0D11CA207225D3E47CB684B339A /* FTypeDecodingResults.swift */, + 8DAE52D6C3B2FC9C548C6B1D2539123A /* FTypeKind.swift */, + F9C93C63BAF9ABDE8D9F8A517D0B3E81 /* FunctionType.swift */, + B26E310C45322A4ED4AA8FDA6189BB58 /* InitializerType.swift */, + A0012700C73B952EE683DE5A28FD938A /* KeyedDecodingContainerProtocolExtension.swift */, + CF47AA3DA3B8EB010E9C9249B488EAC4 /* ParameterType.swift */, + B087EA2FA49AD39D579628C77C4DF597 /* Path.swift */, + 05F1AB638EAD1EF8DD5285B803ED81B7 /* ReferenceType.swift */, + 09430125F9E5748C67B35E97EFF1E0C3 /* RestrictionType.swift */, + 9D0ED1ECFBE441E1197964BD40E28F12 /* SingleValueDecodingContainerExtension.swift */, + 5C2F560F2FE25185B92D32A7AC9F0BE4 /* StaticTypeValue.swift */, + 688410218F9477BF03CC02672B5D29E3 /* StringExtension.swift */, + 70E4456A5BE8F2A335A5797D1098BD55 /* Value.swift */, + BD0215600AEB19164756FA72475BCB2F /* ValueType.swift */, + C77203FE37D09C7FBEB6D2A11E1905B0 /* Support Files */, + ); + name = Cadence; + path = Cadence; + sourceTree = ""; + }; + 334050140C289D450828503C56C59FDA /* SwiftNIOHTTP2 */ = { + isa = PBXGroup; + children = ( + 21651EE6A057DD7D2ADD0FBCE37B206E /* ConcurrentStreamBuffer.swift */, + 82AAF7249C7A243276F99629C91B7201 /* ConnectionStateMachine.swift */, + 0A8ABAFE8C989A5EC3349EB1395B6C86 /* ConnectionStreamsState.swift */, + 24B7003D2F4E5985B21868B438D9AD55 /* ContentLengthVerifier.swift */, + 5626242BB7146F77738520DFAE216A5A /* ControlFrameBuffer.swift */, + 7E3A1FEA70906514D5833E0C24B272A8 /* DOSHeuristics.swift */, + 467CCA25199920B058849FD6C2C321CE /* HasFlowControlWindows.swift */, + 55A65A9AAE2CB4259669C7F1CD52FC22 /* HasLocalSettings.swift */, + 4FE70679AC03E0FC6318978897996424 /* HasRemoteSettings.swift */, + DBBF7AA6EBA1CE1E2A25802226115F77 /* HPACKHeaders+Validation.swift */, + F5BAA52FF2A5C1EBA66F5466604F5601 /* HTTP2ChannelHandler.swift */, + 766A92521248B4D7CD1345D794D01673 /* HTTP2ConnectionStateChange.swift */, + 61C2F8ACCB538BD6193D9C52D140644F /* HTTP2Error.swift */, + 629A52E1E4CA932DAE68FF73DCA52081 /* HTTP2ErrorCode.swift */, + 380BE38C5A780567380E7CBDD33D7E9A /* HTTP2FlowControlWindow.swift */, + 7CE207153EF5353D725D8EA028555A5B /* HTTP2Frame.swift */, + AF2F71AF6DDAF0DB59F19D7CE5D44651 /* HTTP2FrameEncoder.swift */, + 21CB70AC2EA6F4EB47A967F465F212BF /* HTTP2FrameParser.swift */, + F421E9463495ED8B3A343284F5A95ECB /* HTTP2PingData.swift */, + F5D27B54D304A4F4AFCE4E3D33461AF5 /* HTTP2PipelineHelpers.swift */, + 77D4B490F34F7351B400CE5225B4A047 /* HTTP2Settings.swift */, + EF6E3A06093B1FBF24D0CDFA55E48E4B /* HTTP2SettingsState.swift */, + B3E9CEFF47F7C6B77BF71C3804FAC888 /* HTTP2Stream.swift */, + 445336EC05FB156B35CD30D78AB56F7E /* HTTP2StreamChannel.swift */, + 2F63BA50A6FCCC7315BE388EE36A1A01 /* HTTP2StreamID.swift */, + F0DD1041FF36196DF02DE517716A5AE6 /* HTTP2StreamMultiplexer.swift */, + 7FC57450151C39D180A7DE70D0C807AF /* HTTP2ToHTTP1Codec.swift */, + 9059977DCEFF09B9DF959B8130F23A18 /* HTTP2UserEvents.swift */, + BBE42292A4FD16EE1A12341490A57D2C /* InboundEventBuffer.swift */, + 875643C3A2B0BB94A8A34FB1C7FCA178 /* InboundWindowManager.swift */, + 6D14D9882811FC95C4A52156FF3A0722 /* LocallyQuiescingState.swift */, + 83F58491C6DD6CE92E44F104904186AC /* MayReceiveFrames.swift */, + BD7548A6F50F4CBB0D8776BF446DBD28 /* MaySendFrames.swift */, + 2A2FE0034D8005E82F47B9AB3C43969B /* MultiplexerAbstractChannel.swift */, + 3EEFEF54C907113F6F86F4F48E57796D /* OutboundFlowControlBuffer.swift */, + 070EB0072D9FA1881763CA6EA3B48CA2 /* OutboundFrameBuffer.swift */, + 739B55A60450347DDC51BAB2ECA7970A /* QuiescingState.swift */, + 7FB3E6CA4148FDD0A85530EEE85C17BC /* ReceivingDataState.swift */, + 73E7B58CCC3FDF610ED5E5F29121CEA1 /* ReceivingGoAwayState.swift */, + D21EF5C431176A45CB3F8F2CDC1035DA /* ReceivingHeadersState.swift */, + BF24D3F43BB89FBBE0F38FA3E5A66E5B /* ReceivingPushPromiseState.swift */, + 22DE16D46D4E1C5A7996BCCFF955DE5F /* ReceivingRstStreamState.swift */, + A64C1697F6315EE294F1C985C6E2FABB /* ReceivingWindowUpdateState.swift */, + C5FCD784F66C4172968D69584606D85C /* RemotelyQuiescingState.swift */, + 7EED3777D51C8B8889CB915AEA5071C4 /* SendAndReceiveGoawayState.swift */, + F920BC94FE761A03B0EEB62522F35C9C /* SendingDataState.swift */, + 48BD2CBE13261ED5F8C62054F938FBA0 /* SendingGoawayState.swift */, + 5863D402126A6AF32F4B895202656681 /* SendingHeadersState.swift */, + 66FDC10C92DFE9FA6A8021029EE54A1E /* SendingPushPromiseState.swift */, + 81FAAC53CF7CB572F1A0713851F727B5 /* SendingRstStreamState.swift */, + 0AAD2E654193717BE99B9064DD4811B7 /* SendingWindowUpdateState.swift */, + 5BF8E20702878FA358112FB44B023028 /* StateMachineResult.swift */, + 84B8527DE7A43676401D74299221BC85 /* StreamChannelFlowController.swift */, + B98D59B2FC57B2209A63E822B13AA4C3 /* StreamChannelList.swift */, + BB3A87F6880630FB4135090D5EB831F1 /* StreamMap.swift */, + DA0E49E0085C99A522336D97C0D644E2 /* StreamStateMachine.swift */, + ED8CCA0FCBBC5D24D493B41CECEC3C34 /* WatermarkedFlowController.swift */, + EF4BD545F15D1F86A777BD488A300D7F /* Support Files */, + ); + name = SwiftNIOHTTP2; + path = SwiftNIOHTTP2; + sourceTree = ""; + }; + 39EA2ED607F4044D24B973EC84BBCFAB /* Support Files */ = { + isa = PBXGroup; + children = ( + 782B3DD0F29FE497BDD4D415DA7CC737 /* _NIODataStructures.modulemap */, + 439C7DAD9370D19499787E98149B6764 /* _NIODataStructures-dummy.m */, + 54DBDC1C254BCB0849C37FB96F917A5E /* _NIODataStructures-Info.plist */, + 1ADC740F2C27B4194C6F202343AACA33 /* _NIODataStructures-prefix.pch */, + B56C4BF02503F348797EF44D132B4F5D /* _NIODataStructures-umbrella.h */, + B9777D2A1685333BBF468EFCD3584A40 /* _NIODataStructures.debug.xcconfig */, + 31B47C603FED805DF8C2BB1365745900 /* _NIODataStructures.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/_NIODataStructures"; + sourceTree = ""; + }; + 3AE0D09268AEC73772F4CB0DD6DCB51D /* Support Files */ = { + isa = PBXGroup; + children = ( + 6DD8DDCB1D614AFA22177C03F50B1D59 /* FlowSDK.modulemap */, + 0ED5164774FF7BFEC7AED2C9C68CF8D2 /* FlowSDK-dummy.m */, + 6AB54BC674F9B26B020C03ABD8B8A0C8 /* FlowSDK-Info.plist */, + B3895C65A6C586BC934F80C6B7ABD6D8 /* FlowSDK-prefix.pch */, + A9428F804A61917EC818A13B40631A27 /* FlowSDK-umbrella.h */, + 9910BBE166BD1E89E9E12DC90492F787 /* FlowSDK.debug.xcconfig */, + 9CF3A537CCBB4F47740B588DBC13AF75 /* FlowSDK.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FlowSDK"; + sourceTree = ""; + }; + 3E8E40A746E8091D523998722B77CF71 /* Support Files */ = { + isa = PBXGroup; + children = ( + 097C04FF78D4121F703E70B171360395 /* CNIOWindows.modulemap */, + 7C495DA1DE6588F5E5C267D67D0B3A67 /* CNIOWindows-dummy.m */, + 3053B7EE86607A6432D4A5A3957AEACB /* CNIOWindows-Info.plist */, + BEE655195A6F5B88BD1FD92449766B2D /* CNIOWindows-prefix.pch */, + 6767891787016D4050CDB4C413106873 /* CNIOWindows-umbrella.h */, + 393B0F7F47A7F366DDF0A7E3405BBBAE /* CNIOWindows.debug.xcconfig */, + 2FB81A1A9FA63E45CEA511A33CB9BD46 /* CNIOWindows.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOWindows"; + sourceTree = ""; + }; + 46953F65FE1337D5B8C9BDC571A977E2 /* Support Files */ = { + isa = PBXGroup; + children = ( + 6F2D32CEAA9F7B0E401A841702D9AC14 /* SwiftNIOHTTP1.modulemap */, + 6FEABACF790432B16D0E392CB8416450 /* SwiftNIOHTTP1-dummy.m */, + 7F87CEEB29D415F63D329BB8210E9DCA /* SwiftNIOHTTP1-Info.plist */, + 7BF3F10E7C390DBE08FD2668947709C4 /* SwiftNIOHTTP1-prefix.pch */, + D75FB5F17B7BEEC09796E3465E8F7D14 /* SwiftNIOHTTP1-umbrella.h */, + 33FFC143B0BC2F9DFBBEF1EA71EFEB36 /* SwiftNIOHTTP1.debug.xcconfig */, + CA98D9A63854A14E1B8B03D491F17D2A /* SwiftNIOHTTP1.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOHTTP1"; + sourceTree = ""; + }; + 4C5DAA4770FE8E8828409EC542E979C9 /* SwiftNIOEmbedded */ = { + isa = PBXGroup; + children = ( + 3A47A564F560312A0F9EE315068D3F09 /* Embedded.swift */, + DE686C6C2CE5D14978412AB57C947D68 /* Support Files */, + ); + name = SwiftNIOEmbedded; + path = SwiftNIOEmbedded; + sourceTree = ""; + }; + 4FBEE5232960A692ED1328F711D886CD /* CNIOWindows */ = { + isa = PBXGroup; + children = ( + 94C03FF593B078886C1EE15A3B66FDF9 /* CNIOWindows.h */, + 0C2F281A4AA01935FE92D665AE9536B1 /* shim.c */, + 4F572B6F10A59CA774F9046854C9871D /* WSAStartup.c */, + 3E8E40A746E8091D523998722B77CF71 /* Support Files */, + ); + name = CNIOWindows; + path = CNIOWindows; + sourceTree = ""; + }; + 50ADBD6944B07B4766E45A0713F4D39A /* SwiftNIOTLS */ = { + isa = PBXGroup; + children = ( + 19AB3AF641421C7780DA0A681572666A /* ApplicationProtocolNegotiationHandler.swift */, + 5D1C37175511A3E8DE33E96132632A6B /* SNIHandler.swift */, + ABCC4970C4B371898F3166186E6F9B0E /* TLSEvents.swift */, + 6AA9B362BF0B2A1F51D46487A96FEC2E /* Support Files */, + ); + name = SwiftNIOTLS; + path = SwiftNIOTLS; + sourceTree = ""; + }; + 53F3BB931298DC8E9F97B0B70B0108EE /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 5A82624DFA22366377873EA7259BA2D9 /* Pods-fanex */, + F9B4E2361B9BB53E0D6148CFE8392C84 /* Pods-fanex-fanexUITests */, + 9F600CD8447956B6DFCF8A034E35CB87 /* Pods-fanexTests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 5A25C0DFFABE8F54E3C2B357CA9AF56A /* Support Files */ = { + isa = PBXGroup; + children = ( + 57EDA73702499167446611B4D790CFAE /* FCL-SDK.modulemap */, + 3341C39DD9BC0B467383DAB3D96B4E65 /* FCL-SDK-dummy.m */, + 407CF315C2FCBAFEE027AB69D7D6746A /* FCL-SDK-Info.plist */, + 441FBD47A4C4F314DAA4E4D04E248A4B /* FCL-SDK-prefix.pch */, + DCF665EB75E6C7CA2AC7151F867A8615 /* FCL-SDK-umbrella.h */, + 6FAB5953B2D05E975AA748D0B4F5373E /* FCL-SDK.debug.xcconfig */, + AE3E45F8F49AC7440A4DFBF42F1526E8 /* FCL-SDK.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FCL-SDK"; + sourceTree = ""; + }; + 5A82624DFA22366377873EA7259BA2D9 /* Pods-fanex */ = { + isa = PBXGroup; + children = ( + F0112394FA0D1C88F67FF17014ADD4AE /* Pods-fanex.modulemap */, + DF8564E76204B0DB31B6EE565193A0BC /* Pods-fanex-acknowledgements.markdown */, + 2A0369DFFB5C299E59FA6CCCDCDB053E /* Pods-fanex-acknowledgements.plist */, + 1860DAB7ABED7C618762837FA928958D /* Pods-fanex-dummy.m */, + 425EC4E071C3E87CFBDBC0FCD714DC46 /* Pods-fanex-frameworks.sh */, + 1B85BE54C7D8BB813DE51F56C1CBEC85 /* Pods-fanex-Info.plist */, + 381DA48DFA835D5C2909A03D9471E54A /* Pods-fanex-umbrella.h */, + 2C5C0BC3D6A52DA6F561E59A77FD1C48 /* Pods-fanex.debug.xcconfig */, + EC4E7E433CE6A32FC3D02BF10F8A9E08 /* Pods-fanex.release.xcconfig */, + ); + name = "Pods-fanex"; + path = "Target Support Files/Pods-fanex"; + sourceTree = ""; + }; + 5E1500413F1F27B7F13F718736D3FE0E /* CGRPCZlibp */ = { + isa = PBXGroup; + children = ( + 3DE1360C6D2F87387AAD2D043161B451 /* CGRPCZlib.h */, + D33E3CFEC8B6CF1099E266DBB405837C /* empty.c */, + E53F6DF31563223FE37AAEB6D52C3C54 /* Support Files */, + ); + name = CGRPCZlibp; + path = CGRPCZlibp; + sourceTree = ""; + }; + 5FC35C24BE8E72B8BD7B0244E4291F7D /* Core */ = { + isa = PBXGroup; + children = ( + A1C640988E3E214D1F511AD59B5086A3 /* NSBezierPath+SDRoundedCorners.h */, + C1F09B4955E96B2CEA5C0ABB75765747 /* NSBezierPath+SDRoundedCorners.m */, + CE5BD54E549BB42CDA46C2291134E1AD /* NSButton+WebCache.h */, + E30A11CD3BEC671E6C5B6D2BC47A094C /* NSButton+WebCache.m */, + 201EE10DB004216D5209886FB7443829 /* NSData+ImageContentType.h */, + D6834988BB87EBBA075596656CA2100C /* NSData+ImageContentType.m */, + E294B949999A1A5079F9FEBD6B774F68 /* NSImage+Compatibility.h */, + 8077F7252FAFDBE8DF3D1A8A44F808EF /* NSImage+Compatibility.m */, + A62A9516C784312B6E9DCF811BEFA843 /* SDAnimatedImage.h */, + 852805F03CD9FE9D25A0C3D4B3E7D4D5 /* SDAnimatedImage.m */, + A5B1D4B342D8E17E058E8805C0793856 /* SDAnimatedImagePlayer.h */, + 71BFE46CDEE212C2D554D40D5FF5E7F6 /* SDAnimatedImagePlayer.m */, + C19C39C799D0670D4B7753B7373C54A2 /* SDAnimatedImageRep.h */, + C0A7DD2887C9012BC347BEA8C0AE059E /* SDAnimatedImageRep.m */, + 76BCDE90DDBD2974D226B0DC728E0AAD /* SDAnimatedImageView.h */, + 825EFFDDE9B3D5F42B64850D210D839E /* SDAnimatedImageView.m */, + 34E313835ACC1C3A633A38FC5DA81F44 /* SDAnimatedImageView+WebCache.h */, + 93284C051CD0D2398503282372E442D9 /* SDAnimatedImageView+WebCache.m */, + 00B029DA3494978B4D55C326350A0C3B /* SDAssociatedObject.h */, + 8B89A2EA9C362A77FBCA5E4BDF5E4F69 /* SDAssociatedObject.m */, + 076E1182AF5CAA2AD260B7CCA3ADAEF7 /* SDAsyncBlockOperation.h */, + 306A34EEB7DC87E36AFC5C3247F4E4AE /* SDAsyncBlockOperation.m */, + 885445AB8E8BF1B1A00D746A027C9D1D /* SDDeviceHelper.h */, + EDB2F023E8D4B7137FED7F6A435C3787 /* SDDeviceHelper.m */, + 6FD9A8BDDC22690193E3A35513F8F21E /* SDDiskCache.h */, + CAD39B8875D55AA8E4426663E5F29E63 /* SDDiskCache.m */, + FA03486F566E13730B52AFCA100827EE /* SDDisplayLink.h */, + CA8520A7740E149F0C6D18630A0F5E32 /* SDDisplayLink.m */, + 2D2544EF6EC105AB5E2D3F989DA6D4AC /* SDFileAttributeHelper.h */, + 3B7017881DF5963322E5F9BFB3FF8855 /* SDFileAttributeHelper.m */, + 95894A8F7B6DAE981F5165BE4F2EE40A /* SDGraphicsImageRenderer.h */, + E81B478A234CDAB017868988B1FDA209 /* SDGraphicsImageRenderer.m */, + 96EE5B32A454B7CC397B5C934856843C /* SDImageAPNGCoder.h */, + FABD24490DD4ED00306CA54635E45EF9 /* SDImageAPNGCoder.m */, + 5BEC1870D5E8752AFBADC18D9E910946 /* SDImageAssetManager.h */, + F9A7769ABF2BDCDA505650A03B5AED87 /* SDImageAssetManager.m */, + DEF889114EFDCE691DAEE2F56411B5AB /* SDImageAWebPCoder.h */, + 1F3E90EFBADCAF15D47861BF06C9C66F /* SDImageAWebPCoder.m */, + 6D3750C70FE753271823ACC07BA2AF57 /* SDImageCache.h */, + 806FE446300C5A6F475BE596A8C09F8E /* SDImageCache.m */, + 68D1CC3A9F718D0F87F05426AC681B0A /* SDImageCacheConfig.h */, + 5A08D0D28E808A53F9752502B7AB6BFE /* SDImageCacheConfig.m */, + 277FEA5A1CCAD8C95A06EA8BD6BA4EFC /* SDImageCacheDefine.h */, + 0A0D5CC485EB2D72002AADA744B9B7DF /* SDImageCacheDefine.m */, + A8B4ED69E4AF1E48667B2065876C749F /* SDImageCachesManager.h */, + 30B5844B0F5BCD183C6F24728D9D2D55 /* SDImageCachesManager.m */, + 0513510E718E5809FBE277362E08257D /* SDImageCachesManagerOperation.h */, + 8BDB386DC2393B9E00111C6BDCC355BD /* SDImageCachesManagerOperation.m */, + D40E5DCB25DDB72596D326CE4ED62102 /* SDImageCoder.h */, + A8C9B64804E5A4ED733B833205C732EB /* SDImageCoder.m */, + 9AD2222DD9CD658D62F87B34C0342A0B /* SDImageCoderHelper.h */, + B1B2FF5011F1F0B315552B06B8F31887 /* SDImageCoderHelper.m */, + 0C8B91EEF6FE8FD80692353167860554 /* SDImageCodersManager.h */, + 4D86098F5C60B52847DA9D83AC3F267C /* SDImageCodersManager.m */, + CF1F5D93B023F71A05A4ED03AE04E4D7 /* SDImageFrame.h */, + 34E4FBE2249766692D9DCD326AD210E0 /* SDImageFrame.m */, + BAC97623A3FE90868CDB8E3A6963E85A /* SDImageGIFCoder.h */, + 6EE26EF8BE3D6A621D350BED9AA4AA2B /* SDImageGIFCoder.m */, + B9C19433ED23297D0104677C4BBD09CA /* SDImageGraphics.h */, + 06CB876E7538CECF6296183C9239A40C /* SDImageGraphics.m */, + E201F149034E7DE2B52308F670E942D8 /* SDImageHEICCoder.h */, + E7F4BE6BBA53BCAFE0232A7F15B66BAC /* SDImageHEICCoder.m */, + 8AA7887399F147D38C74BE47F5DCC78E /* SDImageIOAnimatedCoder.h */, + B8096BA9AEAAB47DDD31DAA0036E2CED /* SDImageIOAnimatedCoder.m */, + 215F034E1F8CB2245253C9C794A0405E /* SDImageIOAnimatedCoderInternal.h */, + 5208FE10C0E0EC040DE60A94FED96266 /* SDImageIOCoder.h */, + 63F64C7779258BC4F72C9B5527B4AD9A /* SDImageIOCoder.m */, + 482746E8A1E48F9CA975F617D909F368 /* SDImageLoader.h */, + D57C247374F68157B55FF81C04D58B22 /* SDImageLoader.m */, + C000342FB0B9668D6C2C263D0D3897D4 /* SDImageLoadersManager.h */, + 137DDEABB44E61FEC937F8735AB2BFCA /* SDImageLoadersManager.m */, + D6C65F229611613EDA6CA861ABF58094 /* SDImageTransformer.h */, + 54906576365FC97D0EB18ED670E894F9 /* SDImageTransformer.m */, + FA00B28287E667761380128BB484F4CC /* SDInternalMacros.h */, + 2521D5239AD26895494922C727BB1151 /* SDInternalMacros.m */, + 2693B01988B6DE451619238CDDD1BC02 /* SDMemoryCache.h */, + 6DCDD34AB556F1F49D46C07F5D1439A3 /* SDMemoryCache.m */, + 40358CCD7FAD3DBA05B893A63923B67B /* SDmetamacros.h */, + 82862FE35B12CF563FC156B6110476B1 /* SDWeakProxy.h */, + 0105C5BDCC968D3CB601B11FF63E74E4 /* SDWeakProxy.m */, + 914529946EF5601AA93F8EE079CF3C9B /* SDWebImage.h */, + 715987A64B4A51CE1A1DC6A99BD674C1 /* SDWebImageCacheKeyFilter.h */, + 8FB8935FD0D4655DDDEC773B7B4915CE /* SDWebImageCacheKeyFilter.m */, + F9452C8340B87C5D87F7E13392F0D052 /* SDWebImageCacheSerializer.h */, + 1DFA6D41A16145F4392BBA40705024CF /* SDWebImageCacheSerializer.m */, + 7D780F6DECFC48AFCAC7177C09D88CAA /* SDWebImageCompat.h */, + EBC11F927EF369180412CF967C1C71A1 /* SDWebImageCompat.m */, + C5620042BB874899D92901F7626042D3 /* SDWebImageDefine.h */, + 699ED647324E1C44560B50FED10A26F6 /* SDWebImageDefine.m */, + 75EE6C6825E074E05328C99223303166 /* SDWebImageDownloader.h */, + 7868B0CDEB78DBFB971E767F254140D3 /* SDWebImageDownloader.m */, + D2026207177E77CCFCF8DC1F5B32429B /* SDWebImageDownloaderConfig.h */, + F0B0C4554A14955AF5120F1DA97B1C66 /* SDWebImageDownloaderConfig.m */, + 330EB56430E880E789BE7DFB1E461C89 /* SDWebImageDownloaderDecryptor.h */, + DA29D1A3E827E2DEAE7B710196D264C9 /* SDWebImageDownloaderDecryptor.m */, + 966B4887F9DD9CD0ACCE62DE15BB14E3 /* SDWebImageDownloaderOperation.h */, + 03A9527754C739FD142F18EBFDCB50B9 /* SDWebImageDownloaderOperation.m */, + 1FED0FFA4EB5C277938AE6448CC17382 /* SDWebImageDownloaderRequestModifier.h */, + ACBF6340035E1DD58EA9E0188DD22824 /* SDWebImageDownloaderRequestModifier.m */, + 59DEF33DF5D0533B2F230F950425D679 /* SDWebImageDownloaderResponseModifier.h */, + F37ABF268AD3432B45CED98A326932FB /* SDWebImageDownloaderResponseModifier.m */, + 5CC4FBE5CACD2CAB0301E49D7AC65B92 /* SDWebImageError.h */, + 014B4C27D85ADC3C511DAA45E701648D /* SDWebImageError.m */, + 12CB7F9B92A615FA3F5971FA7CA71496 /* SDWebImageIndicator.h */, + C070BF6E38EB220139D06F9C127FFDF5 /* SDWebImageIndicator.m */, + 72F0CF78FE96B9FA56CB5EAED86E907E /* SDWebImageManager.h */, + 1B5826C42634F78CBC9152291B92BE2D /* SDWebImageManager.m */, + 1793B1A8D6B29682805F8E809D394CFD /* SDWebImageOperation.h */, + A263437A804DE2A19CE442E5E628CE9D /* SDWebImageOperation.m */, + 672487A4A912ADC41F78EDCDA947B52C /* SDWebImageOptionsProcessor.h */, + 9DA374C9FE3135CF0B453A8C5F2DB723 /* SDWebImageOptionsProcessor.m */, + 6EDF120F9CFEA86931D71F1931D9F75B /* SDWebImagePrefetcher.h */, + E9D36A06D692CD1593D7474074E83834 /* SDWebImagePrefetcher.m */, + 100736BBAE33F97D2D4BA48AF254EC25 /* SDWebImageTransition.h */, + 190F33C8800487DE7FD3FC3D767E1502 /* SDWebImageTransition.m */, + C76DC87990DC417BEEEA3A5BD223B758 /* SDWebImageTransitionInternal.h */, + BF39F093DBD84740D41A94119F30C0B6 /* UIButton+WebCache.h */, + 49D4A33464B8025591F17F626782668E /* UIButton+WebCache.m */, + D74C19340A61F25F7DE3AFCD405BB334 /* UIColor+SDHexString.h */, + 8F72B636107B54802B4D852AE2F69935 /* UIColor+SDHexString.m */, + 3BE2D8F9A463FC1F21117131272AD9D4 /* UIImage+ExtendedCacheData.h */, + 676876EDFF467DBF93ABF12E82EDD8AD /* UIImage+ExtendedCacheData.m */, + 1F757CFB8F52CE330E5561E43BAAACF8 /* UIImage+ForceDecode.h */, + 85E19BBBB9A6ED0D665B3E9C5DC3484F /* UIImage+ForceDecode.m */, + FD32A762666BDBE51E1BFF3DFE7526C2 /* UIImage+GIF.h */, + EE93CD03907EE0EDBC912DB01B347EB8 /* UIImage+GIF.m */, + 4FCF71CC854BB6C918AB124655B2CAA7 /* UIImage+MemoryCacheCost.h */, + B30C1C5FE90BD3E1CDC3E1AC3FE3A35C /* UIImage+MemoryCacheCost.m */, + E994D5025236EFF6DADE574DAF5538F2 /* UIImage+Metadata.h */, + A7D48BA151B8DF7918DA4CB33BF04F76 /* UIImage+Metadata.m */, + A3380E0461C012878D8D0A4F5D15812C /* UIImage+MultiFormat.h */, + 8020F5D5CC03C195103D0A77D1AB1062 /* UIImage+MultiFormat.m */, + 6DFF907064B630709019AC49B093B5D5 /* UIImage+Transform.h */, + CF3424F9089EEA88A0156E122EE2E7DD /* UIImage+Transform.m */, + 04A53EE37AA8CA3AB2F52ABF0D84FD4E /* UIImageView+HighlightedWebCache.h */, + B24040089D9C5D78D870471EDDA24BEA /* UIImageView+HighlightedWebCache.m */, + 2D9C4B53AD56E6599FB7C338C7BD65F8 /* UIImageView+WebCache.h */, + A6AF4990B009B43367303C0DCA03D676 /* UIImageView+WebCache.m */, + 3C90756B2FB9DEC6D7311D5881FF7FAC /* UIView+WebCache.h */, + EE25658DF6ED641DE4B9C84EE85F4AAD /* UIView+WebCache.m */, + E6DC64D0790FCBD808F1189978E45306 /* UIView+WebCacheOperation.h */, + E84BD2EE14B54889FE7A9DC744FB2076 /* UIView+WebCacheOperation.m */, + ); + name = Core; + sourceTree = ""; + }; + 6099323DAFC41ECF667CBC9EE3FF41A3 /* CNIOLinux */ = { + isa = PBXGroup; + children = ( + 3B3CA316383F8802A59A51825155C724 /* CNIOLinux.h */, + EADFD74CB52F0ABEA2C40E3903C69CEB /* liburing_nio.h */, + 98F5C5815636CC2CDB148C52AC2D5275 /* liburing_shims.c */, + FDFDAD50B9C60762A8D0B9C0536B97BD /* shim.c */, + B2F55BEA0FF4E19C651E207267333875 /* Support Files */, + ); + name = CNIOLinux; + path = CNIOLinux; + sourceTree = ""; + }; + 623BD32DBEA05BDAFA31B8C03F986C7A /* MercariQRScanner */ = { + isa = PBXGroup; + children = ( + 09D751421E4FEBFA7A96941313C1592A /* Bundle+Module.swift */, + 5458105415C4E6D283CD649D22A132E7 /* QRScannerError.swift */, + 46260190555EDA809052AAFE11384B6A /* QRScannerView.swift */, + D236DC3A0D112174E2AFFD6B864B9999 /* Resources */, + 9EE0148311241785F7CDDD395B9B93FF /* Support Files */, + ); + name = MercariQRScanner; + path = MercariQRScanner; + sourceTree = ""; + }; + 62E7C7B7DCF1E8DB5B701574AA33F0B1 /* Support Files */ = { + isa = PBXGroup; + children = ( + D346C93079C3308B4DA5A3C16624F7A7 /* secp256k1Swift.modulemap */, + 2EC5CEA3C1A1008F4A6EF70E7F50D1F4 /* secp256k1Swift-dummy.m */, + E7C89F722798F571C28B19243305FA4C /* secp256k1Swift-Info.plist */, + 5C5DEEA37AFD93D55687831DE94BEE7E /* secp256k1Swift-prefix.pch */, + BD4134865699B139E54951E256C6F701 /* secp256k1Swift-umbrella.h */, + 72D964BAB663A157827B42E3EFC3AD13 /* secp256k1Swift.debug.xcconfig */, + 9D231FBD70C9601052E3C08B6E0B3C1A /* secp256k1Swift.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/secp256k1Swift"; + sourceTree = ""; + }; + 6490C6ABE6139ED25D198E8F2258485A /* Pods */ = { + isa = PBXGroup; + children = ( + 0E276015E92A039D80211D4EEFAE2C89 /* _NIODataStructures */, + 6E9963B5C1D4AFEC263970CABB9BD9D7 /* BigInt */, + 1F92BB4F1ECD057E9E622F5BDBB2EEF9 /* BloctoSDK */, + 32BC918F52C57E8AEE25B197D0AACB84 /* Cadence */, + 5E1500413F1F27B7F13F718736D3FE0E /* CGRPCZlibp */, + FBA17EA439DCFE2E0055CF4667B9E53F /* CNIOAtomics */, + F701A73CC09C701BAF6B8B96A0DCEFFE /* CNIOBoringSSL */, + E9272705AC011384D4D8DD6F7D1E2137 /* CNIOBoringSSLShims */, + 9DE67E2002634E1462C6E74B8A0FB1D8 /* CNIODarwin */, + B398FD654BE5726F22E85741671A6C50 /* CNIOHTTPParser */, + 6099323DAFC41ECF667CBC9EE3FF41A3 /* CNIOLinux */, + 4FBEE5232960A692ED1328F711D886CD /* CNIOWindows */, + B51CC7400A6B54BDC5A89E21F2BBF4C2 /* CryptoSwift */, + 7417379B3316A65A63A666D569166816 /* DynamicBlurView */, + 6F9566D3BA513113021398E9D593424A /* FCL-SDK */, + 8FC35D7B3D7494BEFC17D28DD4E14565 /* FlowSDK */, + BA2510FD001FA5C7559D0AFA0DA1C0BB /* gRPC-Swiftp */, + 8F632B53AA9AA3D2B004073EFB1DA2DF /* Logging */, + 623BD32DBEA05BDAFA31B8C03F986C7A /* MercariQRScanner */, + D3FE54D19C9D6F4DBFC711E12DB2F422 /* PopupDialog */, + B49CEC7A0E32F729463F5E8428DC5DCC /* SDWebImage */, + FAC1B3789C6E72323185C535CB300E21 /* secp256k1Swift */, + 1A228F1BFDBCA358CAAF0ABD27597E5C /* secp256k1Wrapper */, + AE73A24E241186A6430059CB56A4AFD2 /* SVProgressHUD */, + 00056531FCF5A77CBC33540D3F0BD8DB /* SwiftNIO */, + EA37E1093FFE4E3F3B6C11F73B339277 /* SwiftNIOConcurrencyHelpers */, + 0E76BE7B2B28B632D16B7D37215CBF8F /* SwiftNIOCore */, + 4C5DAA4770FE8E8828409EC542E979C9 /* SwiftNIOEmbedded */, + B874146282380C3E8550EDF35068D156 /* SwiftNIOExtras */, + 2AE30BF349948286FA0B2E9F19D1B9F8 /* SwiftNIOFoundationCompat */, + 931CBBEC12B854FE38AF2BAA60195FAB /* SwiftNIOHPACK */, + C66666999DB991FEF3D3E2D0D14C5F66 /* SwiftNIOHTTP1 */, + 334050140C289D450828503C56C59FDA /* SwiftNIOHTTP2 */, + 658E2DCFE26B9AC0577E2595C7B60815 /* SwiftNIOPosix */, + 9B84720681052963FE3BE6F1135C368E /* SwiftNIOSSL */, + 50ADBD6944B07B4766E45A0713F4D39A /* SwiftNIOTLS */, + 8A77DA7709835928956C7B7601760753 /* SwiftNIOTransportServices */, + 8C0928B4E7DF846769F4B798ABE8B4A4 /* SwiftProtobuf */, + E25F1E1356D41D04F0BF6064DEA3B628 /* SwiftyJSON */, + ); + name = Pods; + sourceTree = ""; + }; + 658E2DCFE26B9AC0577E2595C7B60815 /* SwiftNIOPosix */ = { + isa = PBXGroup; + children = ( + F95229EF545043EA7BCF2D678483CC45 /* BaseSocket.swift */, + F41A865E94909DA53300849ECE5936E1 /* BaseSocketChannel.swift */, + 45D030D5F8B3618F444E710AF1876E44 /* BaseSocketChannel+SocketOptionProvider.swift */, + B8C7F2C73FC7C012E942EED296C5EFE2 /* BaseStreamSocketChannel.swift */, + 34B73542505E6AC61B95C80C000C7B18 /* Bootstrap.swift */, + FBCC7B0E2FB5F7C376254FBFC8169C43 /* BSDSocketAPICommon.swift */, + DF9AC5693C5E7E568C3EB0077AB198A8 /* BSDSocketAPIPosix.swift */, + 15EEA51CFF44E7DD7562A964143DF44A /* BSDSocketAPIWindows.swift */, + 4E525E05D489CE1A833F84421241958B /* ControlMessage.swift */, + 9F9E6E4E43E58A87D73434E991B0450D /* DatagramVectorReadManager.swift */, + 445AF8E94A7BC212A4B000327B75D3BB /* FileDescriptor.swift */, + 000D9C2A853E3E3FD34A1155D5819056 /* GetaddrinfoResolver.swift */, + 60DA5A9E77C90FD5E3A6BECEBA97BABF /* HappyEyeballs.swift */, + C406C06F57CEF98C098EB1834266766A /* IntegerBitPacking.swift */, + 3A0D077A97DCF15297B0CCBD600A6CFF /* IntegerTypes.swift */, + D2C162FF68AE73704F1D0370CBB8E821 /* IO.swift */, + 6578517D7D69BDBEBDD8E47022CCBC81 /* Linux.swift */, + 47AA2C31CB795D4CEC50EE6FA24AF4C1 /* LinuxCPUSet.swift */, + D3E2E750872CF97E0A6E77587D690DA2 /* LinuxUring.swift */, + B56C4BFD62C8CCE18637535CF0A76FF2 /* MultiThreadedEventLoopGroup.swift */, + D6BAAE75DEA3771B8E9934450CF53138 /* NIOThreadPool.swift */, + F372FE0BD8E79C0C954CD7368DD56E4B /* NonBlockingFileIO.swift */, + 9F05A1BDA04C07B42D1D50DF121E7DEF /* PendingDatagramWritesManager.swift */, + 39863663084ED88A78F3ACB07CF63C20 /* PendingWritesManager.swift */, + 682582E511D4CFCB4AC801EC5E6C7A42 /* PipeChannel.swift */, + 8505E620F80DAB19865C77F7204E3DE2 /* PipePair.swift */, + A1969EB0465C0CAEFE0141F3491D7F5F /* PointerHelpers.swift */, + 94C91FA15C4D33D1B7E9559142748045 /* Resolver.swift */, + CD3E3562250BD9DC2DCEC39BD3E40552 /* Selectable.swift */, + 203A85ED452B8D5A2E6607D17154B355 /* SelectableChannel.swift */, + 5308041E257F28BE08E78CA91D4F0F9D /* SelectableEventLoop.swift */, + 606ED2AF7D78BF7428003D150AEA1570 /* SelectorEpoll.swift */, + ACC4D4A7F4A5D8085AC922873268066C /* SelectorGeneric.swift */, + 4CF33EE50785750CD3E0018658BA90C2 /* SelectorKqueue.swift */, + 6DBCEA097C38D41A4D4C7202B5074C77 /* SelectorUring.swift */, + EF67958A7B889FD32EE31BC5BD7153C2 /* ServerSocket.swift */, + 7B86D1B76693FF2E7EB9A86C20BFAE1D /* Socket.swift */, + 3174AB3987026757E7D96EF2202B2CAB /* SocketChannel.swift */, + 41C43FAEA6332A1BE439A46C4F647CF0 /* SocketProtocols.swift */, + EC25E5C0E44AD4B8FE7567924453006D /* System.swift */, + 6538FD01C920493BE564E5F79BB1EDC3 /* Thread.swift */, + B1DBE2A6527A0E5F9B151446A402E14F /* ThreadPosix.swift */, + 24C23B35B737F8A5A2A53DF67D203584 /* ThreadWindows.swift */, + 0EA2685CC2F3E2263B3EA330DFF9E4B0 /* Utilities.swift */, + AFD830614260B2B20381200FA060E08D /* Support Files */, + ); + name = SwiftNIOPosix; + path = SwiftNIOPosix; + sourceTree = ""; + }; + 6AA9B362BF0B2A1F51D46487A96FEC2E /* Support Files */ = { + isa = PBXGroup; + children = ( + 0FB95F4D973D09EAB0AB4179AC1E066D /* SwiftNIOTLS.modulemap */, + 4A56A69DF36F5FA88C2DD9305B3D0C31 /* SwiftNIOTLS-dummy.m */, + 31A555D03ED5093AD41ACDF92A85B86C /* SwiftNIOTLS-Info.plist */, + A8EEAE9099ADA7E88C6493D08089A3D4 /* SwiftNIOTLS-prefix.pch */, + 8E9BCA3A2D8C63873EE05B43FA2DD72A /* SwiftNIOTLS-umbrella.h */, + 57F372EEBB66DB5339D666EE9378C337 /* SwiftNIOTLS.debug.xcconfig */, + F836D4A8C76F56D6DD73F426915AB52A /* SwiftNIOTLS.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOTLS"; + sourceTree = ""; + }; + 6C44CE62F7E26F1723A176A941F00E54 /* Support Files */ = { + isa = PBXGroup; + children = ( + A5F495CBF3D6A182B34EFB8EA2AFFA9A /* CNIOHTTPParser.modulemap */, + 8A3B24D4DB3060A69D9A18858B51BD36 /* CNIOHTTPParser-dummy.m */, + D1888F7EA84E495DF29AAC7AD4BBD33A /* CNIOHTTPParser-Info.plist */, + 627FAE45BAEC0F2C05EAB84C44C02CD9 /* CNIOHTTPParser-prefix.pch */, + 96D40FDB9D0E9C588AB0A7978B159390 /* CNIOHTTPParser-umbrella.h */, + 267062B3614E6E43C1A754BDDEBFDCBA /* CNIOHTTPParser.debug.xcconfig */, + A4FBA4C5DC60851E041F493279C7BD17 /* CNIOHTTPParser.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOHTTPParser"; + sourceTree = ""; + }; + 6E9963B5C1D4AFEC263970CABB9BD9D7 /* BigInt */ = { + isa = PBXGroup; + children = ( + DD8F959C010C8EE0A0547CF67FEA904B /* Addition.swift */, + C8A44A41336C1C73744B65F997ACD14C /* BigInt.swift */, + 469DDA25BECAEAB7FC53F911528989DD /* BigUInt.swift */, + 0C35921FB08EA0C514E6E13007AC5066 /* Bitwise Ops.swift */, + 5BF8FE387A24324DB3636F112BFEA0ED /* Codable.swift */, + 764CE82F2813B002821F53D9441AE86F /* Comparable.swift */, + CAA91C8A665F57B9A91C735498340D88 /* Data Conversion.swift */, + 96EF442F0D881078905BD87375142326 /* Division.swift */, + 501D740D00D470DD9CA9FE7C785F5EA5 /* Exponentiation.swift */, + A5A2E804978DC1D481FCB239A99226BB /* Floating Point Conversion.swift */, + 2A8D955348F8FF566612970196459D9B /* GCD.swift */, + 51A9AE26BA8C9E100E1A049D203896B4 /* Hashable.swift */, + DCD2D8AA00FB066742BC2E855446832E /* Integer Conversion.swift */, + 9291ACAD1464AAA4A7957FAAFB7D197B /* Multiplication.swift */, + 8634EBFFCCDD9B284853088DD982AB91 /* Prime Test.swift */, + 1B019302E2A4FC7DB5D8D6C49AB207B4 /* Random.swift */, + 322DEC6D54542BD146B90AE8B0641CB2 /* Shifts.swift */, + 1E9CA9FCDB3FE02945409F2162324A36 /* Square Root.swift */, + 73FEE4D1BBD78901D1C2429FA30F1EE0 /* Strideable.swift */, + 6834A81C3A0BC11254126CF44CF45C6B /* String Conversion.swift */, + 5A903B307C82702D8099A1F1C7C0697C /* Subtraction.swift */, + 86255070A3CCAF2DCDB9ECE5391A5F6A /* Words and Bits.swift */, + 834AFDE967CCA700979CBA5D4EEB2D8F /* Support Files */, + ); + name = BigInt; + path = BigInt; + sourceTree = ""; + }; + 6F9566D3BA513113021398E9D593424A /* FCL-SDK */ = { + isa = PBXGroup; + children = ( + C9D15A50EE5BB4D434CB93F59A65B2E1 /* AccountProofData.swift */, + D8FDB16E285BA44509CA04F4CA63E699 /* AccountsResolver.swift */, + 94DB78A6514187DF8BD31B5992CFDB04 /* AddressReplacement.swift */, + 228777DAC0CFA7ABAE01250071E1780F /* AppDetail.swift */, + EACC63230D4C4319D211F27750098F39 /* AppUtilities.swift */, + 489556374B814C855DDA8F691A042350 /* AuthData.swift */, + E360AA62048C3919BBFD38F63BB1508D /* BloctoWalletProvider.swift */, + 716AB6CD880F7D751DACE82887F42C91 /* CadenceArgumentExtension.swift */, + 3621A9CDBCA3A77391C8DAAEE9B91FE4 /* CadenceResolver.swift */, + 8F65183B06EC810B56AE796D97035222 /* ClientInfo.swift */, + 31DCA335F3F32407235D0E111DFD0222 /* Config.swift */, + 04DE5AF97508CDFCD16CB50A4D988423 /* Constants.swift */, + D0866B41EB6AEDC557B09BE6BED4DD85 /* DapperWalletProvider.swift */, + 51684645291C96C48EFBEB63CE861D2A /* DynamicKey.swift */, + 7143903518B45B3B4368F186D9483490 /* Extensions.swift */, + 97EDFC1B66D01A1233C83AA13E6C3E34 /* FCL.swift */, + 3B95149890F9EB8667E582B99117736A /* FCLCompositeSignature.swift */, + 936C01B367E6C83629C332BC641FE4EF /* FCLDelegate.swift */, + 0A1048B1348EB81E26D98A91883630AD /* FCLError.swift */, + EAF179EF5BF07E33B49915C790AA9463 /* Interaction.swift */, + D9AF0FDC004753EBA45EFC05DEFDD26D /* PollingResponse.swift */, + 85AA449DC627A563D0622878274D245C /* Pragma.swift */, + 7E57E9F69648C28BE44DD5F17DF1F549 /* PreSignable.swift */, + 90749C992E1BDD56FB2E5288EC80B36C /* ProviderInfo.swift */, + F922BA79034FCBFFDEF5221E779C3BBD /* RefBlockResolver.swift */, + 5BA597A99CDB1A93C02D695E01E790C6 /* RequestBuilder.swift */, + 019CEF31B4677F922E3374D77EF6DAA2 /* Resolver.swift */, + 52DA9089BD259A8CD372B4BACC27F344 /* ResponseStatus.swift */, + 7B6A8AA637C75BC871D1086059116087 /* Role.swift */, + 3533A6CD08AF5725024A2238FD3F722B /* RoleType.swift */, + 715097A0A8AA6288109B6A38590962C6 /* SequenceNumberResolver.swift */, + 3772C1098F014CC7D14A0E944D584142 /* Service.swift */, + 31E02D00A3F9AD848D15406BF6A7A49B /* ServiceAccountProof.swift */, + 699A3089D1F3A798E655A7A25AAEF23E /* ServiceDataType.swift */, + 841D60008F5F770B313C006A8DFA67A7 /* ServiceIdentity.swift */, + FF02BEB41B3324A7EDE9B47B64D29E11 /* ServiceMethod.swift */, + C2E03EC85D380BC085366FA157E17D9B /* ServiceProvider.swift */, + 69F18166D6FA989A07C1BF2EDE3CD089 /* ServiceType.swift */, + D9B529C7D801576754E91D4503778443 /* Signable.swift */, + 8B7A63C9E772AE749842EEEA4C93B6F5 /* SignableUser.swift */, + 8ECD758173A4365C3AF953E56F0B3C80 /* SignatureResolver.swift */, + AB6E1F74F4BFA0885B4863B6C052B4F3 /* Singature.swift */, + EA7DCC5C12AD7E2C8657631AC471C25B /* TaskExtension.swift */, + 64CC2B8BD5A968C8ECE43D8CCE8B0112 /* TransactionFeePayer.swift */, + 0604EF3225428B5D345DFD1D40604F3E /* URLSessionExtension.swift */, + 5ACBD31AC425A93986D8DA5597F7FE80 /* User.swift */, + 962796D624989567A469AD221C8F317C /* Voucher.swift */, + 281D8BD48C1BED7DE797404CDF26B27E /* WalletProvider.swift */, + A339F6C2B3057C4FEB959D08FD97D501 /* WalletProviderSelectionViewController.swift */, + C0C8FA7659DAD9BA5584AACB46E8140C /* WalletUtilities.swift */, + 5A25C0DFFABE8F54E3C2B357CA9AF56A /* Support Files */, + ); + name = "FCL-SDK"; + path = "FCL-SDK"; + sourceTree = ""; + }; + 70F95CA9979A9026044723228252BE4A /* Support Files */ = { + isa = PBXGroup; + children = ( + 42607D9DB5A42F8245A1AB7CA432CAF2 /* CNIOBoringSSLShims.modulemap */, + 9B8A53D6F6D367FC034837B1DD62A240 /* CNIOBoringSSLShims-dummy.m */, + 4A53D04E30BEBD984D583E8B0882AB4E /* CNIOBoringSSLShims-Info.plist */, + 9AB506C3FBAED9D5626B76F835294F30 /* CNIOBoringSSLShims-prefix.pch */, + 919A1F050EB6C3A6737D3554B23721D2 /* CNIOBoringSSLShims-umbrella.h */, + 4E178514B54CC8064E94365ECF2BC5A0 /* CNIOBoringSSLShims.debug.xcconfig */, + B92046FCE952E070444772F0017A14D5 /* CNIOBoringSSLShims.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOBoringSSLShims"; + sourceTree = ""; + }; + 731F27313F119E78BB6042A85B922F27 /* Support Files */ = { + isa = PBXGroup; + children = ( + B07B933388A168E64FC702F045725314 /* SwiftNIOCore.modulemap */, + 7CCBEED9840A524A1F782D870BA02CFE /* SwiftNIOCore-dummy.m */, + D5EEEF9636E2C27602F4A72507BF2C05 /* SwiftNIOCore-Info.plist */, + 448192BAB37A6C7C19B4F9130C555DAE /* SwiftNIOCore-prefix.pch */, + 6B4B7EBE7A82D97D5576D1E05A39B6B5 /* SwiftNIOCore-umbrella.h */, + 88DCEFFCCAE19562AD1B892026A9330A /* SwiftNIOCore.debug.xcconfig */, + 86B0C15C4D16323D6FF84C1FA5384A89 /* SwiftNIOCore.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOCore"; + sourceTree = ""; + }; + 733DE0C352BAE50A5C3FA5ABFE35813C /* Core */ = { + isa = PBXGroup; + children = ( + 3325BF8B476B063FCC992863946D8CB7 /* AuthenticationSessioning.swift */, + B56553376B99AF7775384AC1BA59FEB9 /* Blockchain.swift */, + 10CFF73497998A64521A8977F6B9C268 /* BloctoEnvironment.swift */, + F02D804318B912DB80C817AC1499A081 /* BloctoSDK.swift */, + 864D6FBF48B8E33BA48229F0FD5D8D21 /* BloctoSDKCompatible.swift */, + 60B1418F069305E2B7F2CA9ED5AA56C3 /* BundleExtension.swift */, + 09788728497C89B1D08DEAB7DB2D2D86 /* CallbackMethod.swift */, + BB6F36B910678D8E547D0C654844171A /* DataExtensions.swift */, + F4750AA11686A2E12D6E8A31809AA2D2 /* Error.swift */, + 41139673B91A0801D89A7AD0239C82B4 /* KeyedDecodingContainerProtocolExtension.swift */, + 536B9688B9200C123C4AC48652D36DAC /* Method.swift */, + CA5524014361D68DC8908D92BA5CB195 /* MethodName.swift */, + 70843714C0D9E382FCE8599C7E843D95 /* NSNumber.swift */, + A2E4F913CC7AD04D77905B6175B9E551 /* QueryDecoding.swift */, + D1B586BCFD71CE4BCE197B2B172AE998 /* QueryEscape.swift */, + 1AA59255F85D49A61ECB56ADD71721B9 /* QueryItem.swift */, + F05FEE62851E94A769372DC3CD3E8335 /* QueryName.swift */, + 8FC5826C4720FA1B7B3778827DF4517F /* RequestAccountMethod.swift */, + EB7F6195F500500561F1C0E2469545EF /* RequestBuilder.swift */, + 8051E24E27FD90DF9CEC414E6B98F822 /* StringExtensions.swift */, + 9C6471F8CAE3AF3E5255A97AE4A70BB0 /* UIWindowExtension.swift */, + E747B0DAB33E037A6FC0E59DD4BB8C6F /* URLComponents.swift */, + 73BC5E3CCCB8A71118830BB74E782545 /* URLEncoding.swift */, + 746F91594C1C6B55A7F67979D2257F75 /* URLOpening.swift */, + C922CF29D12C9731A042B778664EEBF1 /* URLQueryItem.swift */, + 43B010A061172855A37BE93C13FBDAD2 /* URLSessionProtocol.swift */, + ); + name = Core; + sourceTree = ""; + }; + 7417379B3316A65A63A666D569166816 /* DynamicBlurView */ = { + isa = PBXGroup; + children = ( + 9A944D2C2A11F7534F950A9B6078ADAE /* BlurLayer.swift */, + C92C39073C666F3B2A344FFEE6B8910B /* CaptureQuality.swift */, + A80C859888912E5732D63118F83ABA0F /* CGContext+CGImage.swift */, + 9FDB1BE639E6732DC1AA91B4160FC16A /* CGImage+Accelerate.swift */, + 73B680A7975CF68CC70271B1876AC25C /* DynamicBlurView.h */, + 404E03500F2035FA7045242A74AF80F4 /* DynamicBlurView.swift */, + 249FA949B321C359DDB7A787CBB8E4CD /* TrackingMode.swift */, + 00B2F307985AC8DE763A234C8EACE96F /* UIImage+Blur.swift */, + 261AE1C049581FD90AAC18D1AAD586D2 /* Support Files */, + ); + name = DynamicBlurView; + path = DynamicBlurView; + sourceTree = ""; + }; + 7C4877609CB3950F9FD03378237D4AB7 /* iOS */ = { + isa = PBXGroup; + children = ( + 9748CE6DBD4F6B5C7299576A07341672 /* Accelerate.framework */, + D891661FC3D0A8B7296AF0E14CA4A2E1 /* Foundation.framework */, + 5BF0600E7181F289680078246C28D8D7 /* ImageIO.framework */, + 8DDD8BD3738991F903CBD2F231644C87 /* QuartzCore.framework */, + 8D344F7DF3C892D34365A5382075A06D /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 834AFDE967CCA700979CBA5D4EEB2D8F /* Support Files */ = { + isa = PBXGroup; + children = ( + 597A8C58E74C74F58474999B4A26F7E2 /* BigInt.modulemap */, + 00BB1D33B406DC76DDD4359DA00B8353 /* BigInt-dummy.m */, + 66C930E2F1869C8A260040906EDE19CF /* BigInt-Info.plist */, + C565118E16A7BADE8EA751B3E1EC17F0 /* BigInt-prefix.pch */, + 08F20911E8F738725F1098D11A744D10 /* BigInt-umbrella.h */, + 7A2BA49B19A14C63DCA70C388DA85953 /* BigInt.debug.xcconfig */, + C5B51E986151943001F9FB91147A71C4 /* BigInt.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/BigInt"; + sourceTree = ""; + }; + 8A77DA7709835928956C7B7601760753 /* SwiftNIOTransportServices */ = { + isa = PBXGroup; + children = ( + C793CAD5D4C08E9EC559EB44F6F4AB39 /* NIOFilterEmptyWritesHandler.swift */, + 1AB0B628CE279EFD3E1BB98516E402AC /* NIOTSBootstraps.swift */, + AF99873D68B73F324125054CD5617835 /* NIOTSChannelOptions.swift */, + BB14934FB57CF022B95128B26B5145D0 /* NIOTSConnectionBootstrap.swift */, + 14651E9E01AE716B20D51B8CA012A3F9 /* NIOTSConnectionChannel.swift */, + 32FE80B761FCC33AFB00DEE944FAF1F9 /* NIOTSErrors.swift */, + 185AA3C3932111DAAA91315C83FF1256 /* NIOTSEventLoop.swift */, + 1DDF0443455AE135021E6621A85C3D07 /* NIOTSEventLoopGroup.swift */, + E98CA796CC028075D66589D2DD00FD17 /* NIOTSListenerBootstrap.swift */, + C0A4B92D3375D3A69A261B2924123569 /* NIOTSListenerChannel.swift */, + C96D53D709CAA0EC53D442695E95B4AD /* NIOTSNetworkEvents.swift */, + B0A22926820729A8784C92EA32D61569 /* SocketAddress+NWEndpoint.swift */, + B43ABA1E2D7A98863CDB143A0D955ABF /* StateManagedChannel.swift */, + 717D08C83B52D264B00E632B40CEC117 /* TCPOptions+SocketChannelOption.swift */, + BA83443BEBA1602162FBAAA640229728 /* Support Files */, + ); + name = SwiftNIOTransportServices; + path = SwiftNIOTransportServices; + sourceTree = ""; + }; + 8C0928B4E7DF846769F4B798ABE8B4A4 /* SwiftProtobuf */ = { + isa = PBXGroup; + children = ( + 13CCC7587DA96C8EEF14833B955B0338 /* any.pb.swift */, + 7E4924462479AAFB08B5F728BD40684B /* AnyMessageStorage.swift */, + 8D02C1E0AE5E91CDC76A4FBFEDF72DF8 /* AnyUnpackError.swift */, + B99B18B8997A3B27982F4A265CE6B365 /* api.pb.swift */, + 125EACBDC5ACC520A733CADA059F44FC /* BinaryDecoder.swift */, + 94F227685ECEAB7343AD33F83D2C1A38 /* BinaryDecodingError.swift */, + 8E02396B0223EA2822BDAF9522B514F3 /* BinaryDecodingOptions.swift */, + 7ED79131FD4799CE802D4FCB1A45A27D /* BinaryDelimited.swift */, + 08936EC14856D906A7C6AB50A157FA60 /* BinaryEncoder.swift */, + D076AF38527FFEC91314404B4572AF02 /* BinaryEncodingError.swift */, + 76CD9C4BBC20D5D9CFA35EF21D2A28E2 /* BinaryEncodingSizeVisitor.swift */, + BFEA6712F888607A1730D40B710E1D2B /* BinaryEncodingVisitor.swift */, + 9FC28474AB6F09E4815ADBE0B747B4C5 /* CustomJSONCodable.swift */, + 3D236FDEF838701B1E66DFFA97F02D4E /* Data+Extensions.swift */, + 4C9C8C0D310CF5B79226BE303CE6DE71 /* Decoder.swift */, + E651C6A6A5C2103B3BFB4694639A6744 /* descriptor.pb.swift */, + F497C9CF344483D772A5E2788BBF4BB1 /* DoubleParser.swift */, + 8FE9F6900C3BE0B0D876EEF118FA2339 /* duration.pb.swift */, + 9C8AFD4A17DAF112099B42485F0F640F /* empty.pb.swift */, + A6E3511C4C20DBFBB77226B38065CDE9 /* Enum.swift */, + 31815169F689A8CA600353549CAECB02 /* ExtensibleMessage.swift */, + BE315AD2E58CBC0BE5D4A94EEF3E8B51 /* ExtensionFields.swift */, + B4B9BFDE2AB7150122CE94F7D3061F88 /* ExtensionFieldValueSet.swift */, + 76407BD8DC1F3FEEB7055E348E01C2E1 /* ExtensionMap.swift */, + 5DA367665CC9BC1C69B04890D3494B39 /* field_mask.pb.swift */, + CADC67C899E5C65F088281C441A35555 /* FieldTag.swift */, + 202EAE2488A3312FC2F0C7CA280CF2A1 /* FieldTypes.swift */, + 5B19ACA6BA4F4AFDFECA7E476DF3D949 /* Google_Protobuf_Any+Extensions.swift */, + 91B96C39808611942C367F684DEAA2D3 /* Google_Protobuf_Any+Registry.swift */, + 752DD0693488AAC12528A410CF1B462B /* Google_Protobuf_Duration+Extensions.swift */, + 5CA9BF98A613A23FD0E1127D868665C8 /* Google_Protobuf_FieldMask+Extensions.swift */, + EFEAB067865545587BA1DD5088599E0D /* Google_Protobuf_ListValue+Extensions.swift */, + 991BC180A5163AA7D7212862738DAD7E /* Google_Protobuf_NullValue+Extensions.swift */, + 40E3A228B04F1C4382F68906F3F17B0D /* Google_Protobuf_Struct+Extensions.swift */, + 26BBF10E864BCDD9CB2BE2284E3C9035 /* Google_Protobuf_Timestamp+Extensions.swift */, + C79850F447C2F84490990DD4AD8A54D3 /* Google_Protobuf_Value+Extensions.swift */, + C6B115167F4570AF95A5C342C0CB230C /* Google_Protobuf_Wrappers+Extensions.swift */, + 1F03137B9A7361A477771450D163E9E8 /* HashVisitor.swift */, + 198BD051E2B3CA3FC8E558A4803C65F6 /* Internal.swift */, + C57DB877D0B18BE81B5991497EFB83D3 /* JSONDecoder.swift */, + 067FE95B3B4DC5361B13366DC2BE3ED3 /* JSONDecodingError.swift */, + 1DEF390E21590188D7A27E6EEBCE0616 /* JSONDecodingOptions.swift */, + 5FC12B4AAB7E6AE3C249440811136A9B /* JSONEncoder.swift */, + F25954EBE6DCA38CB6072D0C2538EF9C /* JSONEncodingError.swift */, + 07204D813C49972B4CF09D3F10D926A6 /* JSONEncodingOptions.swift */, + 0D383BE6F056AC34E290D9985C98F462 /* JSONEncodingVisitor.swift */, + 742882FE522A7CABFA19008D890AFF0F /* JSONMapEncodingVisitor.swift */, + 61329CB4B0AFAB6D6A0714878415F6E3 /* JSONScanner.swift */, + 474EC5560C6B9561B3B042241C5711F7 /* MathUtils.swift */, + 7FA903E3889EF8277F0D62AF77621B8F /* Message.swift */, + 693C7FDB3C518480EA1B432ED4461DF3 /* Message+AnyAdditions.swift */, + B82CC6E59C710C9A479CED04F6EE1953 /* Message+BinaryAdditions.swift */, + 20AF747D8CB7AF6E01E1F7B58F040B26 /* Message+JSONAdditions.swift */, + 5B7F6D7D0E5BCC5EAEFF300B35435A85 /* Message+JSONArrayAdditions.swift */, + 54947049A58743A0C0042261F0E344B4 /* Message+TextFormatAdditions.swift */, + D920EEF436E21BBA439A27EB4D74DF39 /* MessageExtension.swift */, + 26E0457317A2F98C0FAA8F58581A3B86 /* NameMap.swift */, + D9D25B6386B64C23DE7B0BF846749F80 /* ProtobufAPIVersionCheck.swift */, + 268BA908D38F7A6EAB4AB545DEE155A1 /* ProtobufMap.swift */, + 26C3A057EDD5E7D5E097B894F2E59B37 /* ProtoNameProviding.swift */, + 39E42A345459393C420965B5E32F38D3 /* SelectiveVisitor.swift */, + A9AA60793268CDFDA0C0D0CF98F240AF /* SimpleExtensionMap.swift */, + D587939838E633D7D3BB2F5EDEDE5011 /* source_context.pb.swift */, + 2C489C72417D9363D5C7D75F9A1786E7 /* StringUtils.swift */, + 0F7A9500A6630A2CA8CA115E055B0062 /* struct.pb.swift */, + 4091261A509088CF57731B9198952C95 /* TextFormatDecoder.swift */, + 85F47BA8B5549C0C4A9F35A0BF8EE2CD /* TextFormatDecodingError.swift */, + C09A6BC46D6AA43601F4B44F4AAF2CA7 /* TextFormatDecodingOptions.swift */, + C0B0D5A311F2E48AB02CD7CD89C77C14 /* TextFormatEncoder.swift */, + 4DEDCE51540072C4379CBA95F93B4CFD /* TextFormatEncodingOptions.swift */, + B14752CF2FF865DF39649F33F07C77C7 /* TextFormatEncodingVisitor.swift */, + 0AF40917DF5A60C569C3D716E8DF3C25 /* TextFormatScanner.swift */, + AA57072C8406D072532BC8C000A532B1 /* timestamp.pb.swift */, + 1988AD6E34C0FF5849A9D31E644F9C42 /* TimeUtils.swift */, + C1CFB827F779CBE90AC1D2BBEFAF94EA /* type.pb.swift */, + 18B04B2811394A6178E69DA925AC1C9B /* UnknownStorage.swift */, + 843DC486B3962999E5D2EB6FD72C1F70 /* UnsafeBufferPointer+Shims.swift */, + F2B535D0CA6C53122205C5A6CDE8EFC0 /* UnsafeRawPointer+Shims.swift */, + 5A36BE9C53E671A694FC4006041B0247 /* Varint.swift */, + 5BBCF711E54A49A7662966284B6C692B /* Version.swift */, + 8FD6706181F20F0BB844323B4501CCBB /* Visitor.swift */, + 5E0721EF9A72F01319DB08771946208C /* WireFormat.swift */, + 1F5FF3D59B1851F9A4C9823F57AC5981 /* wrappers.pb.swift */, + 887D9ECBC6B7F324CA3652F963F26571 /* ZigZag.swift */, + E653251FB0AE2A6C2A59F0A9670630C8 /* Support Files */, + ); + name = SwiftProtobuf; + path = SwiftProtobuf; + sourceTree = ""; + }; + 8F632B53AA9AA3D2B004073EFB1DA2DF /* Logging */ = { + isa = PBXGroup; + children = ( + A9E4C0FA477431EB8B424B3E86E6E278 /* Locks.swift */, + 5C6FFAA21FABF954FA624913576251BF /* Logging.swift */, + A5537285A56608EC950F942013E870F2 /* LogHandler.swift */, + 043C39176A2DC155069954627219A9F1 /* Support Files */, + ); + name = Logging; + path = Logging; + sourceTree = ""; + }; + 8FC35D7B3D7494BEFC17D28DD4E14565 /* FlowSDK */ = { + isa = PBXGroup; + children = ( + 14DC9AB0E6D91B6C756922A4CE0BCCA8 /* FlowSDK */, + 3AE0D09268AEC73772F4CB0DD6DCB51D /* Support Files */, + ); + name = FlowSDK; + path = FlowSDK; + sourceTree = ""; + }; + 931CBBEC12B854FE38AF2BAA60195FAB /* SwiftNIOHPACK */ = { + isa = PBXGroup; + children = ( + 37F335D34944F3E6119B5E507E77BDEC /* DynamicHeaderTable.swift */, + A9F2E4DBBAAC82896230FA9EEF346638 /* HeaderTables.swift */, + 1ABFC0B6B87D0498049F2399765759D2 /* HPACKDecoder.swift */, + 129734FDDAF80E355B66A2397411314E /* HPACKEncoder.swift */, + 4A13E071B674DC17F15A4DEB4243ECB1 /* HPACKErrors.swift */, + 32DA1DE656AFDE4C64EFF20746AF3D0B /* HPACKHeader.swift */, + 56ECAFB119E54C34869DCE1A260D278F /* HuffmanCoding.swift */, + 275805B9428E3EAEBAAC2086BF1F4720 /* HuffmanTables.swift */, + E358977EBFBB1B19A411BAEA76FA770A /* IndexedHeaderTable.swift */, + AE87F53AE675706680F530C168F294E6 /* IntegerCoding.swift */, + 79BBF3EED4F75438552D9EB9017EFA8B /* StaticHeaderTable.swift */, + BFF4C3D5510BBAF0DEA233E9115B2C0F /* Support Files */, + ); + name = SwiftNIOHPACK; + path = SwiftNIOHPACK; + sourceTree = ""; + }; + 99EA7076DFA537F058D7AE3CD99CD8DF /* Support Files */ = { + isa = PBXGroup; + children = ( + 4E1EB225DA4EBE4FEC26F11AD725CE18 /* SwiftyJSON.modulemap */, + D60BEB2C0F3EAB59348E0C1D13463871 /* SwiftyJSON-dummy.m */, + A64E8EADE71F27E0A92CA03FB8C639E8 /* SwiftyJSON-Info.plist */, + 7B7C5FBF0BB02E454854FD9C1656EAF1 /* SwiftyJSON-prefix.pch */, + FDDD2D73E4D2EECF3B63527CD28F21CF /* SwiftyJSON-umbrella.h */, + 918ECE4B52BECD386CF80B33C8BE5A8D /* SwiftyJSON.debug.xcconfig */, + FCCD4381FC5AE473243D1B1AAEBE4615 /* SwiftyJSON.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftyJSON"; + sourceTree = ""; + }; + 9A6209F039876CDC07FAF33840AEE7DA /* Support Files */ = { + isa = PBXGroup; + children = ( + F4FDD8C3A61E6625D29D34C8E4A8A9C9 /* CNIOAtomics.modulemap */, + 18AD1C392EAEF15BD0F92D2E6BD8131F /* CNIOAtomics-dummy.m */, + 04F5E9B44FFBBC5F19BE21D313A782EA /* CNIOAtomics-Info.plist */, + 9B99006B4C7A31D6028CB7A585C1C322 /* CNIOAtomics-prefix.pch */, + 649702361E788AB9B1259095141BB33B /* CNIOAtomics-umbrella.h */, + EDB2896CA76E4083FD655A1249E1241F /* CNIOAtomics.debug.xcconfig */, + D69780E46CD39C58EABFCD14326E92C5 /* CNIOAtomics.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOAtomics"; + sourceTree = ""; + }; + 9B84720681052963FE3BE6F1135C368E /* SwiftNIOSSL */ = { + isa = PBXGroup; + children = ( + 51B6893083FF0DBAB17C2B696B72CAB6 /* ByteBufferBIO.swift */, + 7D41C1A5A3343C40316A5339C52B6BBF /* CustomPrivateKey.swift */, + CB72FA10C1BE9E862B724ECBB814D72F /* IdentityVerification.swift */, + E895D3C198F54C3672CFF97EC77D18E4 /* LinuxCABundle.swift */, + 15847CFE3042952A3D46C83B0DD8A25F /* NIOSSLClientHandler.swift */, + CD40323B10E8239FC8F186C9065EE598 /* NIOSSLHandler.swift */, + 25E39B2ADC446C5FB878AB317A9A2F6D /* NIOSSLServerHandler.swift */, + F3E1CC848E4930BB28B8B18131408127 /* ObjectIdentifier.swift */, + 777E76DC30F79C40830F0990980A4072 /* PosixPort.swift */, + 3A29A5BEB2B946BEE2C128683E4D9BBB /* SecurityFrameworkCertificateVerification.swift */, + 1DBEE5E02B05AA31F5C64FE602B3A266 /* SSLCallbacks.swift */, + DF71BC3254D90CE69B3FD2C1D702DE0A /* SSLCertificate.swift */, + 1DCF94245EE14B9D234181E1B22FD7C2 /* SSLConnection.swift */, + 03896A4C5D1CA97D2AC38836D9DADA67 /* SSLContext.swift */, + 1E8AF0B8E6E62DE4FF3C86D748245E23 /* SSLErrors.swift */, + 1826E26775407F17457CCFAFF94835F3 /* SSLInit.swift */, + 8D7CBC2B76E29B6042FF02D05EB4EF33 /* SSLPKCS12Bundle.swift */, + 369C48AD3362D32C75B73925F8EF8B43 /* SSLPrivateKey.swift */, + 0A95A53CE558FD0A98C3CC52BF080A1F /* SSLPublicKey.swift */, + EC6D54E77894F35CA1EC1245BB57F3B0 /* String+unsafeUninitializedCapacity.swift */, + A3792872F4F7E79DED08D802E38E942B /* SubjectAlternativeName.swift */, + A9CC3284E14BCF196DF7F1FC8A8C14B0 /* TLSConfiguration.swift */, + 14C057D940A62DB7A534003E557095F2 /* UniversalBootstrapSupport.swift */, + 1FF58983CA01319C76E76B3D9B8E1B06 /* Support Files */, + ); + name = SwiftNIOSSL; + path = SwiftNIOSSL; + sourceTree = ""; + }; + 9DE67E2002634E1462C6E74B8A0FB1D8 /* CNIODarwin */ = { + isa = PBXGroup; + children = ( + C01D03DBF1929B2E2EDAFE1D84B937BE /* CNIODarwin.h */, + DA6BBD134CE96FF5620A937811221B57 /* shim.c */, + 0008426395B7E4AA04FAC96D42D40D8D /* Support Files */, + ); + name = CNIODarwin; + path = CNIODarwin; + sourceTree = ""; + }; + 9EE0148311241785F7CDDD395B9B93FF /* Support Files */ = { + isa = PBXGroup; + children = ( + E0104C16951B11FB6DED96D556CF2028 /* MercariQRScanner.modulemap */, + 1FE986B653115BDA8E79A7E164F44CFA /* MercariQRScanner-dummy.m */, + 24CF3B0ED5000E1B181CBA28A128F837 /* MercariQRScanner-Info.plist */, + 8F90EF6E29C41EA643A08282FCEAEA2A /* MercariQRScanner-prefix.pch */, + 3DC6A748C2861B919099BAC626E9198D /* MercariQRScanner-umbrella.h */, + 93F0AD3ADAD0EFBF6747866F9AD34681 /* MercariQRScanner.debug.xcconfig */, + 921A5CE0D626D2D9F73F2B2C37C57DD3 /* MercariQRScanner.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/MercariQRScanner"; + sourceTree = ""; + }; + 9F600CD8447956B6DFCF8A034E35CB87 /* Pods-fanexTests */ = { + isa = PBXGroup; + children = ( + D262F10A23088344883964E1418BE853 /* Pods-fanexTests.modulemap */, + F8269385F226C6592D280DB0D6625E88 /* Pods-fanexTests-acknowledgements.markdown */, + CA7E10854BA00094355406B7844497F9 /* Pods-fanexTests-acknowledgements.plist */, + FD72A695D77BD4F392D0EBE936B2EB51 /* Pods-fanexTests-dummy.m */, + 01E04E7584BFCB8E60E48FF5F3D89EFA /* Pods-fanexTests-Info.plist */, + 592ECFA0202DC3D72A69C99AF5F1693C /* Pods-fanexTests-umbrella.h */, + DB3C51FC2CE11F6E1FC4DB0C1059C64F /* Pods-fanexTests.debug.xcconfig */, + 30340B262F1F7E20B838FE3271BD6903 /* Pods-fanexTests.release.xcconfig */, + ); + name = "Pods-fanexTests"; + path = "Target Support Files/Pods-fanexTests"; + sourceTree = ""; + }; + 9F767438567EC93BD7E8A4F7FE312FD0 /* Support Files */ = { + isa = PBXGroup; + children = ( + F72016BFA9188CA7F0C1612DB95E4A4B /* secp256k1Wrapper.modulemap */, + FF3C424009C0D93BF5CE0E36B2C00792 /* secp256k1Wrapper-dummy.m */, + ABB9E9402F24F870985BDAADA6EF464D /* secp256k1Wrapper-Info.plist */, + F7A52911CA1238E07A642DC258ADB327 /* secp256k1Wrapper-prefix.pch */, + 0A05782676F8CA2756C2C8E8A859BCB5 /* secp256k1Wrapper-umbrella.h */, + 190AC20F29333DC43C461DC412B766FD /* secp256k1Wrapper.debug.xcconfig */, + 6454772CDFC04EFE6E1F5AD38FE7E3DD /* secp256k1Wrapper.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/secp256k1Wrapper"; + sourceTree = ""; + }; + A72CA0F77539A80028A207CEB469A88F /* Support Files */ = { + isa = PBXGroup; + children = ( + 8199A0F10EDCAB412B8E7161C713BC66 /* SwiftNIOFoundationCompat.modulemap */, + 0D15728B7F7BDD59F3421E167B782156 /* SwiftNIOFoundationCompat-dummy.m */, + 252869E03C30E4DB9A6AE754D99A1D20 /* SwiftNIOFoundationCompat-Info.plist */, + 361B9C96B65816E47F1647BE9FDA0EC7 /* SwiftNIOFoundationCompat-prefix.pch */, + 193F09AEBB44F16749D93F05FEDC1E59 /* SwiftNIOFoundationCompat-umbrella.h */, + 7A6F43EDA3AAEB0A7636E47D1BEA18A8 /* SwiftNIOFoundationCompat.debug.xcconfig */, + 1019854EC76E5A35372C2247872FBB45 /* SwiftNIOFoundationCompat.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOFoundationCompat"; + sourceTree = ""; + }; + AD963F49BB57316ED108CF46A11CD0EF /* Support Files */ = { + isa = PBXGroup; + children = ( + E6FB1813DCECD368FD0CB74060E96349 /* BloctoSDK.modulemap */, + 2534CA8D3B74A01222E7A77A1A6B124F /* BloctoSDK-dummy.m */, + 92604BA8B45D91FC57F71A4527FCCEF3 /* BloctoSDK-Info.plist */, + 6C79792E9AEF2232DE54E9A4C4C4C2F2 /* BloctoSDK-prefix.pch */, + 030D13FA49F1EC5A5369417569B3F42C /* BloctoSDK-umbrella.h */, + 9D7E805F18D220B2496E7ED497D891F6 /* BloctoSDK.debug.xcconfig */, + 596EDC10FB2C816516BF38E8A47E49E0 /* BloctoSDK.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/BloctoSDK"; + sourceTree = ""; + }; + AE73A24E241186A6430059CB56A4AFD2 /* SVProgressHUD */ = { + isa = PBXGroup; + children = ( + 6A6186673700ED88DEB1E9C017272782 /* SVIndefiniteAnimatedView.h */, + 2F2A68C667C54E3B7561491056754A87 /* SVIndefiniteAnimatedView.m */, + 5FCEFA31AF70F373E509ED8E34154C05 /* SVProgressAnimatedView.h */, + F7C81418EABA8EB915144461E60CACE9 /* SVProgressAnimatedView.m */, + 891F6C38DB160984768F7ACF77C04993 /* SVProgressHUD.h */, + 808D08A0CB972D95262C50B2C8460F77 /* SVProgressHUD.m */, + 75403BA0717E47809896A2101A23F3F2 /* SVRadialGradientLayer.h */, + 2A36B1EE7A2D9315FC135DC6ADC49CF8 /* SVRadialGradientLayer.m */, + E71FFBDA6DF53D3031EE367F40C3B925 /* Resources */, + B33E958C3EFFC73447D1D8DF8BDCA315 /* Support Files */, + ); + name = SVProgressHUD; + path = SVProgressHUD; + sourceTree = ""; + }; + AFD830614260B2B20381200FA060E08D /* Support Files */ = { + isa = PBXGroup; + children = ( + E4D3DAA4823B69DE8B68DFAF03DF054B /* SwiftNIOPosix.modulemap */, + 7B325D7050B338C70831E7F3117794BE /* SwiftNIOPosix-dummy.m */, + 64E10E4FD6E48A59E6866C41F1A27D40 /* SwiftNIOPosix-Info.plist */, + 13DDEA3EA920AEB24582257476D29CA3 /* SwiftNIOPosix-prefix.pch */, + CFE74D605415B4D1AA55DA6DFB704085 /* SwiftNIOPosix-umbrella.h */, + 1E6ECA6B0A9A8C4E6A7CA9C4FB436793 /* SwiftNIOPosix.debug.xcconfig */, + 699361D574BEBE539C51757D679B1819 /* SwiftNIOPosix.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOPosix"; + sourceTree = ""; + }; + B2F55BEA0FF4E19C651E207267333875 /* Support Files */ = { + isa = PBXGroup; + children = ( + DCB1DC8F307D2C326B774E8B2DBCD44C /* CNIOLinux.modulemap */, + EAA8959B66C811A04B4320E8DA8D7628 /* CNIOLinux-dummy.m */, + BD2218A808C034905587CE858F8C8D80 /* CNIOLinux-Info.plist */, + 0969899AE73EC6CB5D3EE43F1AEFF8E7 /* CNIOLinux-prefix.pch */, + B87A50A9B5D40943EDCE15F73F41D23A /* CNIOLinux-umbrella.h */, + 579FF490F79F59658DAF13F0E591B4E8 /* CNIOLinux.debug.xcconfig */, + D418CCC7A6AC0FB56934549E60249E06 /* CNIOLinux.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CNIOLinux"; + sourceTree = ""; + }; + B33E958C3EFFC73447D1D8DF8BDCA315 /* Support Files */ = { + isa = PBXGroup; + children = ( + 0D43A46ECC17F3BAA29A7A78DD21389C /* SVProgressHUD.modulemap */, + E1116D42B41D6F34C7E3FE87161B217F /* SVProgressHUD-dummy.m */, + DC8CE43DCE073AC353F2133251430DDB /* SVProgressHUD-Info.plist */, + D9A4DA078108B9FD83435DED90E5D8F1 /* SVProgressHUD-prefix.pch */, + DFBAC8F5B391B91A2CF90C493B6F1E41 /* SVProgressHUD-umbrella.h */, + F7A91F4686FC34066E9F1F3B610CAEBF /* SVProgressHUD.debug.xcconfig */, + 859AB0A0806DCFFB6C5C85C999B23FC7 /* SVProgressHUD.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SVProgressHUD"; + sourceTree = ""; + }; + B398FD654BE5726F22E85741671A6C50 /* CNIOHTTPParser */ = { + isa = PBXGroup; + children = ( + 8C497C2FB894DD3EF2130F73BD38D1F6 /* c_nio_http_parser.c */, + 5BF92DA07FF2BFCD193217F90EDA6DF0 /* c_nio_http_parser.h */, + 5EEF1A795EC83D9C06CA29B76F0DCA23 /* CNIOHTTPParser.h */, + 6C44CE62F7E26F1723A176A941F00E54 /* Support Files */, + ); + name = CNIOHTTPParser; + path = CNIOHTTPParser; + sourceTree = ""; + }; + B49CEC7A0E32F729463F5E8428DC5DCC /* SDWebImage */ = { + isa = PBXGroup; + children = ( + 5FC35C24BE8E72B8BD7B0244E4291F7D /* Core */, + BCD6C242F2EEBD57859E8C1DD13D44A7 /* Support Files */, + ); + name = SDWebImage; + path = SDWebImage; + sourceTree = ""; + }; + B51CC7400A6B54BDC5A89E21F2BBF4C2 /* CryptoSwift */ = { + isa = PBXGroup; + children = ( + 15D850324603466D1F86860D5F3BBC78 /* Addition.swift */, + BDF35E8639017787D175323CA359D07A /* AEAD.swift */, + 9CF1A1E10AFB8B8835880E65401C2DD9 /* AEADChaCha20Poly1305.swift */, + C6BEF0D076B6676CEA35ED8F8DCD6C48 /* AES.swift */, + 5EE9230B1CD0D146600F41FD1C33A2A1 /* AES+Foundation.swift */, + 680E3D81317929F61038DF8CE7A8290C /* AES.Cryptors.swift */, + 1447A6EDADED82970E5400D1C1CF0BDE /* Array+Extension.swift */, + EC58E07BCA5C6D8154968ED29DC0EF8D /* Array+Foundation.swift */, + E5775235143C439271C4EDF08E25E941 /* Authenticator.swift */, + 7E968AB08461932A981DEA0A9A3D749D /* BatchedCollection.swift */, + 44102141F3911EB572FE3710794EC10D /* BigInt.swift */, + AAB2156CD55FD16E3A95B4AC96E16738 /* BigUInt.swift */, + B5F2C1A9AB12ADED76780A6D05E37119 /* Bit.swift */, + FDBD5749F3FA2EEF750A1389E486D52C /* Bitwise Ops.swift */, + 44F9093DBD2DD7FB5CC1B73033D02658 /* BlockCipher.swift */, + 29D83CEE77E716014FB275733BCA3AC0 /* BlockDecryptor.swift */, + A5F94CB3C154047CF825DEAEB6199D19 /* BlockEncryptor.swift */, + DE18259BFD9CE81EBAE94B05B4902E80 /* BlockMode.swift */, + 34F6B3F237075144484066C543B8A2AA /* BlockModeOptions.swift */, + 1834AB61EE4BDDCD2DA92719083CB0F5 /* Blowfish.swift */, + CD6E01B5DAF6B4CA74B4852A157A8805 /* Blowfish+Foundation.swift */, + F13848373B9F209766DB133A0176976D /* CBC.swift */, + CE6E92656D4BBA6B5D21A6CF282B7FBB /* CBCMAC.swift */, + 484B18FCC75A69141F249D9018FC6E79 /* CCM.swift */, + 526ED2C5D0CAED69CCE1C91E3640C6F6 /* CFB.swift */, + 8F21E8BB641EB344580DF444761E4D1D /* ChaCha20.swift */, + 4487E443015FCF86B7D2288B4B132613 /* ChaCha20+Foundation.swift */, + 608F623D3B08BA42C8FEC503EB0A3202 /* Checksum.swift */, + 421CA9C32CA2524466A67A1548654BBE /* Cipher.swift */, + 72638FCE3746FD4EE7CE54980A2EB158 /* CipherModeWorker.swift */, + 50B2A679D31DCD596EEC5BA8D7AC26C4 /* CMAC.swift */, + C303112F60D6260807EFC5BEC533C0F8 /* Codable.swift */, + 7A0CEBD079B76F4703EE2CE856E59BC3 /* Collection+Extension.swift */, + F7EC63F48F6D767F3F3A0BF21AD9DB9B /* CompactMap.swift */, + D1DD2C2EFC8604B688328D8CA7803D30 /* Comparable.swift */, + B03BD8B7CDD44609147E2976B328A423 /* Cryptor.swift */, + E98C0F7953BE8F0580FC9DD009C52546 /* Cryptors.swift */, + 2F5C53B14919489C35D8B006C24AEA4D /* CS.swift */, + 5BF593AB41A0AF0DEFBF863C4A465B86 /* CTR.swift */, + 49B2A8C3F35F5883ECABDFBA56D961C1 /* Data Conversion.swift */, + 5EBBC38E8B4526897E288AC3935AAA62 /* Data+Extension.swift */, + 3BB8B787D84DC3ED9227B3184A1A4369 /* Digest.swift */, + 211122AEEB526BA62B5F07B93EE9D19E /* DigestType.swift */, + 24A2CC40A74FE6E4ECA8426FD1F6E64C /* Division.swift */, + 441A7B437D3E27161D566330AD6CA312 /* ECB.swift */, + 0B7819128C40A9899F97FAAA36D894B3 /* Exponentiation.swift */, + 3B1FF1FFA5E7337517ABF817BC382321 /* Floating Point Conversion.swift */, + 7D90504E9042649F39D595CAF524C4A1 /* GCD.swift */, + E136AD5881B92E5F3FE8944DD75F0AB2 /* GCM.swift */, + 576AC85311DDBD08D126184FB7191BED /* Generics.swift */, + 688BEA52472D776443869462E1284ACB /* Hashable.swift */, + 258C74AC14ED4729DFBD81F79BC024E5 /* HKDF.swift */, + BD08109835C6A45C609EC05D36F56513 /* HMAC.swift */, + 1EBE1AB9F1660D3300D0A277E7A595F0 /* HMAC+Foundation.swift */, + 82006C1BC2CD48F726128D0C958B3ACB /* Int+Extension.swift */, + D70EDEE52BD5BEC13259E3639B8BA99A /* Integer Conversion.swift */, + 3B3DE7FDD0ADABD706D2739EEB88BA64 /* ISO10126Padding.swift */, + BB1B7684B4B29822AD4BAFE4218D7CD1 /* ISO78164Padding.swift */, + 8424D5BFC4301B7A3E986E42A11F4571 /* MD5.swift */, + 3155CD0AC33851B9A052F1421C6EF29C /* Multiplication.swift */, + 248D34408517F523A350B44AC1E40FFF /* NoPadding.swift */, + F8D469CE10346D8B8D052DA3DAEE9EFD /* OCB.swift */, + 3284F8D7D061DCA29D88332125072289 /* OFB.swift */, + 8AFCD6C11BF1A8D3DE74A721E78D0D3E /* Operators.swift */, + C81073BD7A32C72DE43989D7A7C1EF95 /* Padding.swift */, + 01AEEA96113AD6E0F2E3656217271781 /* PBKDF1.swift */, + 261522E8FA2A52D990467B27DF2A76DB /* PBKDF2.swift */, + A9396DDDD1A58F1D7F4FFD73D7B3E6B9 /* PCBC.swift */, + 7A762F23B1113D8E24B6AE1977D53DCB /* PKCS5.swift */, + 3CC3BE4C1AD289339E860C9A67A5FCE5 /* PKCS7.swift */, + 25196B26AD9D6CDDD91A54874EFD4A1D /* PKCS7Padding.swift */, + 53589CFAB32460C48156336CE5EE883F /* Poly1305.swift */, + D561F1333FD64F4F25B777E77E28522F /* Prime Test.swift */, + BC8441953E0511E075A55C9CC42E27E7 /* Rabbit.swift */, + 8E9240AA999E52750C2D2F8E00F79E0B /* Rabbit+Foundation.swift */, + 1DA1D186ACB7B19ECADBCFD4F0BBA144 /* Random.swift */, + DFA9F0E3CEC147A6DE206E5B03934731 /* RSA.swift */, + E87369BB0769E23EF24803F44A0F226F /* Scrypt.swift */, + B4A308418216D636E99E558FCF77305E /* SecureBytes.swift */, + DC1758411E8067285A2146A45045AA7B /* SHA1.swift */, + 1F3EA21AB0B510C02841B9B09476F9E2 /* SHA2.swift */, + 2D517C93BB421BDDBD08A3281DFF9A4E /* SHA3.swift */, + B611E01AE9F71F3596A643A7D2A421C0 /* Shifts.swift */, + BE5BA2C7268A4F3816EA97002DA5E406 /* Square Root.swift */, + 589D2F093BEE044995B014C077990A57 /* StreamDecryptor.swift */, + 0ADEDF5DB5CACF65B1F5326FC7DE2542 /* StreamEncryptor.swift */, + 2A6DE3B81F7066E320CAC2CF2B74F561 /* Strideable.swift */, + 58E1897D1BAEEDBE602D40F24F560BF2 /* String Conversion.swift */, + 44437A9E7D313DF745E40B02473AE4CF /* String+Extension.swift */, + EE715B9C7DA79D3E184910C877DFD198 /* String+FoundationExtension.swift */, + 369A8C22EFAF607261525365CF510608 /* Subtraction.swift */, + DE18D266883CE29CF57E950BD8D8EE4C /* UInt128.swift */, + 5E08C20860569C87EE2F3AA6F06E5146 /* UInt16+Extension.swift */, + 3B12017F089338B3E2DAE84CCF35DA50 /* UInt32+Extension.swift */, + 7569FE549DE97DD2355EAD434DEA81D5 /* UInt64+Extension.swift */, + E0925800F0F3DA00319FE641B576C727 /* UInt8+Extension.swift */, + 670C456D4FCFEF9092396FF161CA4A3E /* Updatable.swift */, + 2E64BD1FC6EAC0B1F102580C6E0D46BA /* Utils.swift */, + 09297DFBBB10B6771E1F84A3F19325D7 /* Utils+Foundation.swift */, + 08A595AD5E52D398253F765D3646FEA3 /* Words and Bits.swift */, + 4261559F8853764054D0325731A6DDA0 /* ZeroPadding.swift */, + DF475AB9437D316570D4841957A5DBE2 /* Support Files */, + ); + name = CryptoSwift; + path = CryptoSwift; + sourceTree = ""; + }; + B6F33207DA79F22B7A816D25522CADEA /* Support Files */ = { + isa = PBXGroup; + children = ( + F97E1D4476C75DA1152015FA92F5E874 /* gRPC-Swiftp.modulemap */, + 5B9A298482E75869E1ED00F8077386B3 /* gRPC-Swiftp-dummy.m */, + 14932620AFF7A9C7891AE057709873BD /* gRPC-Swiftp-Info.plist */, + 6D34289681192F83F7D7E501404DA0C7 /* gRPC-Swiftp-prefix.pch */, + EF12325E188F77C0C95B571E77124B73 /* gRPC-Swiftp-umbrella.h */, + 52A70AE9E6190A82C587A37FE9D8EB4B /* gRPC-Swiftp.debug.xcconfig */, + 683C3A9077D7AFBD12A2AB115EED400A /* gRPC-Swiftp.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/gRPC-Swiftp"; + sourceTree = ""; + }; + B874146282380C3E8550EDF35068D156 /* SwiftNIOExtras */ = { + isa = PBXGroup; + children = ( + BC6D316C011289D6114027CEB8E9C2D9 /* DebugInboundEventsHandler.swift */, + 15FA039D9BDF798A1C7C94118249DBCE /* DebugOutboundEventsHandler.swift */, + 5E05C5D12EF55A7458060ADF19DA4B30 /* FixedLengthFrameDecoder.swift */, + 470F5C098A9215008584059ED9E540D4 /* JSONRPCFraming.swift */, + BE889AEBF1F0F3D6CC3BC99186CBD41E /* JSONRPCFraming+ContentLengthHeader.swift */, + 660DC8D7B5079C83E6BF3CE126E828E2 /* LengthFieldBasedFrameDecoder.swift */, + BE01B6CAAE26C2D87F755136F85C0EC3 /* LengthFieldPrepender.swift */, + 488502B49EA245C5DF9A028AEA0D53B9 /* LineBasedFrameDecoder.swift */, + 50620683857F7039ED3A222630547C53 /* NIOExtrasError.swift */, + 581D60585908DAA6033C9E21C8ADF092 /* NIOLengthFieldBitLength.swift */, + 53FF6032FB91E924B08894D202423B16 /* PCAPRingBuffer.swift */, + 1B1DE3821898D0F8784CB1671EBF4AB1 /* QuiescingHelper.swift */, + 9352F8CAFC6537ACBAAB22D0AE728CCE /* RequestResponseHandler.swift */, + 54B576AAD6BDC64DD3BBAC385FD520D7 /* WritePCAPHandler.swift */, + FCAF07A0ACB6728EF0A953CAC6442696 /* Support Files */, + ); + name = SwiftNIOExtras; + path = SwiftNIOExtras; + sourceTree = ""; + }; + B94D7768568A9992200DB461E8CF687F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7C4877609CB3950F9FD03378237D4AB7 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + BA2510FD001FA5C7559D0AFA0DA1C0BB /* gRPC-Swiftp */ = { + isa = PBXGroup; + children = ( + 297DA80F9A4242565798518F67BD9061 /* _EmbeddedThroughput.swift */, + CD0A2854CC856EABE27D02B8B2A196D7 /* _FakeResponseStream.swift */, + 43F69D217FB1BED38F59C70AF29DF895 /* _GRPCClientCodecHandler.swift */, + 6FE64E9D19A886C817DDBE83563847C8 /* _MessageContext.swift */, + 581957A460F05E4ACD7377112F415EEA /* Array+BoundsCheck.swift */, + 7EE3F46D7411B71D83FAAD008A2E82D5 /* AsyncWriter.swift */, + B87EE4554627E69785104159E7BA5F42 /* BidirectionalStreamingCall.swift */, + F7333AB5B013C75729FD116AC76867A4 /* BidirectionalStreamingServerHandler.swift */, + DCA0FE597DC1F3C6A5BCA04F2DA989A4 /* Call.swift */, + 256418E2881B6DAA7F14910D02B5180E /* Call+AsyncRequestStreamWriter.swift */, + C11603B9D360BC58772C329CF91BEC74 /* CallDetails.swift */, + 527DFFBB1677EE7C10B5FE3397F4B0F6 /* CallOptions.swift */, + F3F016C3BECF713FE493125FCC61F487 /* CancellationError+GRPCStatusTransformable.swift */, + 2B6F5E6ABD294A9AC1D6C2C7B56EEF23 /* ClientCall.swift */, + 92206D944CFA8537AE3137C4C34F8351 /* ClientConnection.swift */, + 218871546F42F6E20E483CAD41CCE258 /* ClientConnection+NIOSSL.swift */, + A884FF8ED4F6B364A965586227FF7E39 /* ClientConnection+NWTLS.swift */, + 0F7204919891D132080FB4623165DD5F /* ClientConnectionConfiguration+NIOSSL.swift */, + 2209F2B910446F43708EF208A89D3AE6 /* ClientErrorDelegate.swift */, + C37A5585E6C895F76C51215421BCF806 /* ClientInterceptorContext.swift */, + C1A5A5841BE08BD8E11D0963F7CB3D5C /* ClientInterceptorPipeline.swift */, + BCF6A65EC27B88428B3A0CF63413317F /* ClientInterceptorProtocol.swift */, + A7797BD7095643FBB0149737059E66DD /* ClientInterceptors.swift */, + DA6839D1D519D3E405E6EDD9FBB2B5ED /* ClientStreamingCall.swift */, + AD1453B26707E3BBFCC6A2E2380775C7 /* ClientStreamingServerHandler.swift */, + 6AB5AC65D86ECBEDFAD2CF7EF32DD974 /* ClientTransport.swift */, + 1F2E8E0EC3E3D0DA30CC01C980215515 /* ClientTransportFactory.swift */, + D5E6A03147D0A9EC2FDEB805FDBB269D /* CompressionAlgorithm.swift */, + E6FC7C6947FF36F684A3994FFE7F76DE /* ConnectionBackoff.swift */, + 0ABF0F0C625CF2ABE592F32D09A9B9CD /* ConnectionKeepalive.swift */, + FD4944D92039A49A17EC34979D0F9648 /* ConnectionManager.swift */, + FB5655ACB7792921A9D8656260482B6D /* ConnectionManager+Delegates.swift */, + 183EBD613645D681F4B465B7D841374E /* ConnectionManagerChannelProvider.swift */, + 08D128A5B7DECFFA30FE718DD3540B3E /* ConnectionManagerID.swift */, + CD1C77232231A56100C2C126C3D2BA3F /* ConnectionPool.swift */, + 980C4FDA16712B01699898BC0D207423 /* ConnectionPool+PerConnectionState.swift */, + 4747431DC93868AA2BE766A668E675B6 /* ConnectionPool+Waiter.swift */, + C637AFE0F17CD6E5434C0F35F7A9AB49 /* ConnectivityState.swift */, + 2847E7D26F025BB1D57C079905EB843B /* DebugOnly.swift */, + A0D58A6E75C6E7F360A35D31ED3E1962 /* DecompressionLimit.swift */, + A2E0761EDC7027047AA1C390EB7873F5 /* DelegatingErrorHandler.swift */, + DDB32F7AB6A7CC1CF10B4632146512E4 /* Error+NIOSSL.swift */, + 7429C5A9FAE59CCDDAC3E7D669C079CF /* EventLoopFuture+RecoverFromUncleanShutdown.swift */, + F96BA613367923BBFF2F2DBD0354DAF1 /* FakeChannel.swift */, + CEF1B4381BEA551E1BEC8BD8A0F45A2E /* GRPCAsyncBidirectionalStreamingCall.swift */, + AFAE696FD8F13F560F24B8FA0116127B /* GRPCAsyncClientStreamingCall.swift */, + 27A0096D0F1AF00682CD50F6A4A08285 /* GRPCAsyncRequestStream.swift */, + E1A7ECDE3312ABF35B64E9CE0D610FA1 /* GRPCAsyncRequestStreamWriter.swift */, + B5A65A501924E6053568C1E8BAC3675B /* GRPCAsyncResponseStream.swift */, + 1C2F9D3B024AAF5570BB6D9D31F2CE81 /* GRPCAsyncResponseStreamWriter.swift */, + F85FBB12A3222F572D172DB14751E94E /* GRPCAsyncServerCallContext.swift */, + 99A84BF3728DC28D573570492FF1F6CB /* GRPCAsyncServerHandler.swift */, + EF13C39A51927AE32AFC954ED9417057 /* GRPCAsyncServerStreamingCall.swift */, + 3D8BAD0DF4E234C3431802E561A851D6 /* GRPCAsyncUnaryCall.swift */, + EF3AED7324AF2D4D94E0FFBAAF68EA96 /* GRPCChannel.swift */, + B495EFFA32E7E62E2FD0AB0F689098A6 /* GRPCChannel+AsyncAwaitSupport.swift */, + 729B1F8B32184B8DEB21E9CC93C3D27F /* GRPCChannelBuilder.swift */, + 23E55556354D48D4FD7988BAC017D751 /* GRPCChannelPool.swift */, + C6DE86A887712395D34AC74951E2B7F2 /* GRPCClient.swift */, + F79498A14802AEB00C50159F45431EBB /* GRPCClient+AsyncAwaitSupport.swift */, + 4D0589E851EBFC66CE9F5E2306DCD04B /* GRPCClientChannelHandler.swift */, + F13CE72E4DE115E0CB8A9510566B58B6 /* GRPCClientStateMachine.swift */, + A78B9E397FC3A26081AF8D0468C9A30A /* GRPCContentType.swift */, + E5B1BFB9F383FB335DAA5730B9A73A16 /* GRPCError.swift */, + 6004A2299268FB7700C904D7E47177B4 /* GRPCHeaderName.swift */, + 6C982DE04B6EBE96FCA55C8F5E6BA4D3 /* GRPCIdleHandler.swift */, + 186F7FBFBC9EC8B701D8D23534B49107 /* GRPCIdleHandlerStateMachine.swift */, + D3095F84099BAC79F6F6C210A93F1540 /* GRPCKeepaliveHandlers.swift */, + 7BDD27EA6B00152FF0E718F7E4E0B5BC /* GRPCLogger.swift */, + 67845E98E019276FA82E0785DDDA884C /* GRPCPayload.swift */, + B0732CFBADE6259ACDF883CC16830835 /* GRPCSendable.swift */, + 7AEBA82D151D457B8D21E60FEE8FD924 /* GRPCServerPipelineConfigurator.swift */, + 96B043DDB45818671A86CC424B821B2D /* GRPCServerRequestRoutingHandler.swift */, + 554A30FAAA98F5650C4DFD0A9A48D30F /* GRPCServiceDescription.swift */, + 69DE0F1E76B17106976985E62F2E7132 /* GRPCStatus.swift */, + 448C675002E3DCA228896933562EE2AA /* GRPCStatusAndMetadata.swift */, + B97E78A3E74437B8A21A71DCF55F9849 /* GRPCStatusMessageMarshaller.swift */, + 1CD67DE4C7F0D195290FB9B1CD3FA05F /* GRPCTimeout.swift */, + D8EE5C7973CA3CFEE5FD57A854A7E18B /* GRPCTLSConfiguration.swift */, + FBE3972F653181A13752675E7A877F2A /* GRPCWebToHTTP2ServerCodec.swift */, + D059656D450DB7462D191A177599D6A2 /* HTTP2ToRawGRPCServerCodec.swift */, + F97962E42C217EF60D24440D061F34DE /* HTTP2ToRawGRPCStateMachine.swift */, + C3E6121ABD5731EAD67AF31B2156D245 /* InterceptorContextList.swift */, + B3DE27288C920D21A42D6701815B7EF7 /* LazyEventLoopPromise.swift */, + F64FC89200F8D0706E8CCAFD14914470 /* LengthPrefixedMessageReader.swift */, + 1845575A98867066BC733AD1C8202CA5 /* LengthPrefixedMessageWriter.swift */, + 04F09E3B56130C3D3396435B94FDB806 /* Logger.swift */, + A80BC07600C31821C48FCBAE486DF89E /* LoggingServerErrorDelegate.swift */, + 6FEBC0C81CE82A09BDEA8BE8310B2E26 /* MessageEncoding.swift */, + 98CFC661373BA9730BCC13E2E1F61B8E /* MessageEncodingHeaderValidator.swift */, + 2C2E5F552BE3FC33AF702D83A2839354 /* MessageParts.swift */, + C77A761ED7EE5B3F9934E8867532CD9F /* PassthroughMessageSequence.swift */, + 205E11C37E7B176455E96ACA338D3486 /* PassthroughMessageSource.swift */, + 904BAB653CB9F1076FB673F402C78DAC /* PlatformSupport.swift */, + 65403732FF94C6E473686DD943B25626 /* PooledChannel.swift */, + E1C8C7BB879B9DC1A63010ED47A05068 /* PoolManager.swift */, + C617C7314F44C614860C8B4B8CE78CFE /* PoolManagerStateMachine.swift */, + 17F7618D35EB1C624B284E6674556704 /* PoolManagerStateMachine+PerPoolState.swift */, + E9504D4A1C7E0AA4D1702B0383635B87 /* ReadWriteStates.swift */, + DDC6F0F2EF3F899754774C80358CFB92 /* Ref.swift */, + 0F8FBB2076A193DA0C2D6BF5BED3E049 /* ResponseContainers.swift */, + 4FCAB0E52009B591A221259DB8DBCBAD /* ResponsePartContainer.swift */, + 65ABA6E8006B92B26C68AB3678AD43EC /* Serialization.swift */, + 2683A364FE598567755584430E34AEA8 /* Server.swift */, + 8DC169C7AA03EA4BB6D8B3E3015E4C8A /* Server+NIOSSL.swift */, + E9767344EF78CB1C9C72E3387E88AC09 /* ServerBuilder.swift */, + 4166CCB7B030C71C569CC9571ED054E0 /* ServerBuilder+NIOSSL.swift */, + 206D595DA6D868D7DB345D772286138A /* ServerCallContext.swift */, + 8B937F84CA0F4DE0A31A65B671E08821 /* ServerChannelErrorHandler.swift */, + 7DB2A9752DA2D470C520B44CA619076B /* ServerErrorDelegate.swift */, + 082C345E6CF5971948D1443C3E5061BC /* ServerErrorProcessor.swift */, + F266418CB8BCC7A3BA24AD0C5A06BAF0 /* ServerHandlerProtocol.swift */, + BB7439633EDD2E01ED03402DB1D02A0D /* ServerHandlerStateMachine.swift */, + 08DF434C8C2F95CD2F212947799075BA /* ServerHandlerStateMachine+Actions.swift */, + BBF98C528EC0C5C2B7685286984AAD90 /* ServerHandlerStateMachine+Draining.swift */, + B7F86C258B6E7E7D3579567A28EB94E0 /* ServerHandlerStateMachine+Finished.swift */, + 5EA8C52B80490B71F1A647CD6800483C /* ServerHandlerStateMachine+Handling.swift */, + 3430DDB59333EC7767251863BFC41F5A /* ServerHandlerStateMachine+Idle.swift */, + 7E0B6181CAC16C08E1B995F751D98DEF /* ServerInterceptorContext.swift */, + 1095271DD12AFF9F7DA342ED0452BF3D /* ServerInterceptorPipeline.swift */, + 0D0CE134117056C9057B4DAFC24094EE /* ServerInterceptors.swift */, + F06E3F0F68E87986C37B89E07CB61626 /* ServerInterceptorStateMachine.swift */, + AB6A478D5EAD917E7F36CF45CEC70B84 /* ServerInterceptorStateMachine+Actions.swift */, + B57C4375ED9A8C93CC09EE54BB969BC0 /* ServerInterceptorStateMachine+Finished.swift */, + 4D15B530C1C0371C492AD75F922A6708 /* ServerInterceptorStateMachine+Intercepting.swift */, + DA5B2D264C8C540509FF1E9DF0014B42 /* ServerStreamingCall.swift */, + C7E25C008B16D40841525DCD017034D7 /* ServerStreamingServerHandler.swift */, + 6DAFF32C7F2CEA1A995EFBFA1B389B1C /* Stopwatch.swift */, + C155581852CB3AEEEE25F846462DAE0F /* StreamEvent.swift */, + E4B7A9E311EEA55E7535DFFA305302F6 /* StreamingResponseCallContext.swift */, + 567FD469C35653B294CC5F47C54BAE32 /* StreamLender.swift */, + 74DE4695C579F6E61573FA510FB21B08 /* StreamState.swift */, + 4AFD068065187C51C67D79026959C01D /* TimeLimit.swift */, + DB07308B36D8F85B7F9D40B31BCDA3B1 /* TLSVerificationHandler.swift */, + 9F6EBFDC467B069F2BB9F8A08DF9115F /* UnaryCall.swift */, + 0EC4AE025180D60650876592B1B3B7C0 /* UnaryResponseCallContext.swift */, + FE16B6E629E3869F9CC21C3710AEE4C2 /* UnaryServerHandler.swift */, + CD554B1F5155CCEC522FD091E3B42B44 /* UserInfo.swift */, + 439E97A1D3AC6989C07A674A4DF0344C /* Version.swift */, + CD63A32D56755A4FA3D94486B21B69A0 /* WebCORSHandler.swift */, + 7ECDD0AF7AD61EEDFE08E3FA3A87EC4D /* WriteCapturingHandler.swift */, + 2924B309ECDB9B85124C35459153AC54 /* Zlib.swift */, + B6F33207DA79F22B7A816D25522CADEA /* Support Files */, + ); + name = "gRPC-Swiftp"; + path = "gRPC-Swiftp"; + sourceTree = ""; + }; + BA83443BEBA1602162FBAAA640229728 /* Support Files */ = { + isa = PBXGroup; + children = ( + 4C3F73AE7C39FA0571F1FC3BD4B748E1 /* SwiftNIOTransportServices.modulemap */, + 7672BDB3320CC16155E590B26AB14394 /* SwiftNIOTransportServices-dummy.m */, + 7411E610AE039B5E4637766CB6288303 /* SwiftNIOTransportServices-Info.plist */, + 732FCE54A0B757B577A79BA1BE4259F6 /* SwiftNIOTransportServices-prefix.pch */, + 5B69F35BDFA7E3985C0BF5A43101532E /* SwiftNIOTransportServices-umbrella.h */, + DCD6665F6C8BAD060595A501C0346F1A /* SwiftNIOTransportServices.debug.xcconfig */, + 51CA1BF1AEEC3CC946C5EA99D7A1F59B /* SwiftNIOTransportServices.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOTransportServices"; + sourceTree = ""; + }; + BC0CF0BF5E7DEB81FE1A2F797FE2F4D8 /* Products */ = { + isa = PBXGroup; + children = ( + 8436BC15451DA6766C259541522EB812 /* _NIODataStructures */, + 91BB24BA472AF523E913108C9AA301F2 /* BigInt */, + 18078BAA5B8CD8C4BCE1F204781688A7 /* BloctoSDK */, + 932928A2279109486F3A16C66E4D61F8 /* Cadence */, + 02645BB34CFF0DE639E95842490D9F30 /* CGRPCZlibp */, + D91FC01385D3680BAE48C7A1E23CB088 /* CNIOAtomics */, + BBBC89616D0756CD768F9406643F7DC0 /* CNIOBoringSSL */, + D138731AC283B1675098D887342027D8 /* CNIOBoringSSLShims */, + 4CECE1D3F082EE1C5AF7E5E93BAEDF74 /* CNIODarwin */, + E8457AC368411E1953DDF7BE182DA599 /* CNIOHTTPParser */, + 6F1C5C1A1C8F9473CEF780C63705F78A /* CNIOLinux */, + 4A1D16EDB0405CEE4C837F184DC39013 /* CNIOWindows */, + F81274EDB681F11E7CB05F7DCA2BB33C /* CryptoSwift */, + 86C4A2D817E6CFFF31BF75161625FD5D /* DynamicBlurView */, + 367CC54EBAD387B037592BA9CDFFC0FE /* FCL-SDK */, + FA0FF3EF9504A14378958B379D648B19 /* FlowSDK */, + 3B675E4619748AE52DB48AE541E34C1A /* gRPC-Swiftp */, + A6513E0A6CB60623515716E73996F0F5 /* Logging */, + 915361CF4F5BEB9ECA5F7A89DAE63096 /* MercariQRScanner */, + 300BB2CB97DD4DA36846810A394A85E5 /* Pods-fanex */, + 4B2D28E09E850EBAACFFC4677BFF6724 /* Pods-fanex-fanexUITests */, + 73643EEA08A3187BF338758D45B69065 /* Pods-fanexTests */, + 34FB964502259D0FF233CE71CFDD2A71 /* PopupDialog */, + B0B214D775196BA7CA8E17E53048A493 /* SDWebImage */, + 07DEEECEF437CFC809687467C7ED76E0 /* secp256k1Swift */, + BA36C95CC11BBA679562231CDB7DC1A5 /* secp256k1Wrapper */, + E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */, + 5E982D315A4CB75E8F15068B30779C7C /* SwiftNIO */, + 673CA60B9FF9D56D5AEAFAD4E2D7B368 /* SwiftNIOConcurrencyHelpers */, + A00E16AE69A03C3643B9534FCF13263C /* SwiftNIOCore */, + E83089C79437628622D534CAA83363B4 /* SwiftNIOEmbedded */, + 81AC88440747A0FCA422BCA626C9A038 /* SwiftNIOExtras */, + 6D040D1A67C3DBE3C11EB6FBC61B8141 /* SwiftNIOFoundationCompat */, + 8A6887895625D9DECAAEBF5A690134F7 /* SwiftNIOHPACK */, + 134C82C2AF26C1F6D1FA6484A52A0FF4 /* SwiftNIOHTTP1 */, + 2A4CC298CC8CF90A2A7FAFA7D74BD1CF /* SwiftNIOHTTP2 */, + D85994E4069B3EC81A279B775780797A /* SwiftNIOPosix */, + 73328AB6E67FF4855DF7327B64265B4E /* SwiftNIOSSL */, + 43BCA78D557ACEB23EEA495EE0402530 /* SwiftNIOTLS */, + 42E23A3C1C5D8CE37484B124E180BAA0 /* SwiftNIOTransportServices */, + 943D347E61A2E181A4FA2CA894307B6E /* SwiftProtobuf */, + E23C076BA70925415F490FEDB215DA92 /* SwiftyJSON */, + ); + name = Products; + sourceTree = ""; + }; + BCD6C242F2EEBD57859E8C1DD13D44A7 /* Support Files */ = { + isa = PBXGroup; + children = ( + 4498FC5440F2F336E68966637D8DEFE7 /* SDWebImage.modulemap */, + C63AF0C7583CF8E8E56FA5E6C476BC3F /* SDWebImage-dummy.m */, + DB4B1D84D0BF51670648EFB8394A7113 /* SDWebImage-Info.plist */, + 807F6B14251EAA3A22A075AF6781C6C5 /* SDWebImage-prefix.pch */, + BBC73AB7289510464AFB5EFF44C43FAD /* SDWebImage-umbrella.h */, + D908361B8625862D2C49A79C1B9BEA16 /* SDWebImage.debug.xcconfig */, + B39357A8BA62A1DE32E48810C6BE4632 /* SDWebImage.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SDWebImage"; + sourceTree = ""; + }; + BFF4C3D5510BBAF0DEA233E9115B2C0F /* Support Files */ = { + isa = PBXGroup; + children = ( + 79C1EF32BD6685FE569A9EF68CA59A78 /* SwiftNIOHPACK.modulemap */, + A18A2EEDDFBCBE87D6F005B10DB418F5 /* SwiftNIOHPACK-dummy.m */, + 351E7CAAA37F849FD7F76A7FB91F6F53 /* SwiftNIOHPACK-Info.plist */, + 398B10F826963DF33B9F0BBBD7B1E5C8 /* SwiftNIOHPACK-prefix.pch */, + 561797F07D64EEC2278F2C20D284ABC4 /* SwiftNIOHPACK-umbrella.h */, + 1936F11FC65709C16D7A78196D0740B1 /* SwiftNIOHPACK.debug.xcconfig */, + DC639B3693A5684D7058BF67CD67A76B /* SwiftNIOHPACK.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOHPACK"; + sourceTree = ""; + }; + C66666999DB991FEF3D3E2D0D14C5F66 /* SwiftNIOHTTP1 */ = { + isa = PBXGroup; + children = ( + 9263A27F2368160D48F5D8D39811F5C6 /* ByteCollectionUtils.swift */, + 9DF6F34E0C0955CF1A878FF94E52AFE0 /* HTTPDecoder.swift */, + 47BAB972B9DA6714049FE8E07EF08C1C /* HTTPEncoder.swift */, + 29F05446E7403E52098CDA564AC7A9C6 /* HTTPPipelineSetup.swift */, + 1CBC1E059014B56C25224FCC43A92433 /* HTTPServerPipelineHandler.swift */, + EA49B891F4BD7B9F847A85FAE26BE8CD /* HTTPServerProtocolErrorHandler.swift */, + 633C8C447C3FB1D4948A5BC065F355D6 /* HTTPServerUpgradeHandler.swift */, + 0EEB202953F639113C26DB38D5381833 /* HTTPTypes.swift */, + A6824E58803648F18F7ED3C2F1AACB45 /* NIOHTTPClientUpgradeHandler.swift */, + D67656E3C8BABFA1F2CC575CA2F9BA96 /* NIOHTTPObjectAggregator.swift */, + 46953F65FE1337D5B8C9BDC571A977E2 /* Support Files */, + ); + name = SwiftNIOHTTP1; + path = SwiftNIOHTTP1; + sourceTree = ""; + }; + C77203FE37D09C7FBEB6D2A11E1905B0 /* Support Files */ = { + isa = PBXGroup; + children = ( + 879A80E98782881CC1A23C471B4FE210 /* Cadence.modulemap */, + 307067ECFCDF628D0BFA3A54498C23B8 /* Cadence-dummy.m */, + ACC40784851EB756A9CB882A545B72DD /* Cadence-Info.plist */, + 8A208216618E2EB447F2F85B8B31B0F4 /* Cadence-prefix.pch */, + 4FA191A1A6EA690A2394B507BC8A1151 /* Cadence-umbrella.h */, + C7DF0B2E8D690EEF78B6B95A929E0960 /* Cadence.debug.xcconfig */, + E18AB3400B57A79FD5CE7E88BE4FBF63 /* Cadence.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Cadence"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + B94D7768568A9992200DB461E8CF687F /* Frameworks */, + 6490C6ABE6139ED25D198E8F2258485A /* Pods */, + BC0CF0BF5E7DEB81FE1A2F797FE2F4D8 /* Products */, + 53F3BB931298DC8E9F97B0B70B0108EE /* Targets Support Files */, + ); + sourceTree = ""; + }; + D236DC3A0D112174E2AFFD6B864B9999 /* Resources */ = { + isa = PBXGroup; + children = ( + 81AECAE46BD788C0FA0E5735F9D8C082 /* Images.xcassets */, + ); + name = Resources; + sourceTree = ""; + }; + D3FE54D19C9D6F4DBFC711E12DB2F422 /* PopupDialog */ = { + isa = PBXGroup; + children = ( + BCE21EAEDADC5882C334469A44553854 /* InteractiveTransition.swift */, + 6CCD93EFB03582F1106146024982D6B3 /* PopupDialog.swift */, + 5D34821E2734FD3FD949F1EA95A2C744 /* PopupDialog+Keyboard.swift */, + 57E3DF7A1DE405E528197F98001D7A73 /* PopupDialogButton.swift */, + 1C79F27D75309CFD6B32E480A9C7A0AA /* PopupDialogContainerView.swift */, + E32E9F648A6FD4A830BA69B40C9C0428 /* PopupDialogDefaultButtons.swift */, + A58374516B6E39546FBBB6E9BCC08E48 /* PopupDialogDefaultView.swift */, + DEF8E38A6C86993609FD23CD53FD060C /* PopupDialogDefaultViewController.swift */, + F45C4839DB209C95B4EFAECE05A4A33E /* PopupDialogOverlayView.swift */, + B6014095D840DACF4EF8FF2531E2E542 /* PresentationController.swift */, + 17A4019C4EFFC2C909028FCF61F52C50 /* PresentationManager.swift */, + 5E9A160FE84EE321E41281FB995E30C2 /* TransitionAnimations.swift */, + 64554F810325123E1D8A563813465BA2 /* TransitionAnimator.swift */, + 994D43AD3904B05EB0ED69E59CD860AE /* UIImageView+Calculations.swift */, + 2615582796F402C01E58DF1352B78ED9 /* UIView+Animations.swift */, + 4CA162300774D9EC15AE362843239196 /* UIViewController+Visibility.swift */, + DEF1D792C4DA66CE572BE33B03C25094 /* Support Files */, + ); + name = PopupDialog; + path = PopupDialog; + sourceTree = ""; + }; + DE686C6C2CE5D14978412AB57C947D68 /* Support Files */ = { + isa = PBXGroup; + children = ( + 7CE6CB7FA5DCAE1E7306FC4950B6E6B2 /* SwiftNIOEmbedded.modulemap */, + 2F634A8F909B2004C538D3794F0DDF70 /* SwiftNIOEmbedded-dummy.m */, + 4A4223B40ACB8BC2DD87DDE651C4ADF0 /* SwiftNIOEmbedded-Info.plist */, + 0143F5E4F7DFC8834E9678910D8B8DBD /* SwiftNIOEmbedded-prefix.pch */, + 3E7AFF69AFE0501AE9FEEC943B53D2C4 /* SwiftNIOEmbedded-umbrella.h */, + E4D7AF2FFDCED01CDA1D9A7C7E877132 /* SwiftNIOEmbedded.debug.xcconfig */, + 498BAEFEA926989AF4B263B8ED9C52AC /* SwiftNIOEmbedded.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOEmbedded"; + sourceTree = ""; + }; + DEF1D792C4DA66CE572BE33B03C25094 /* Support Files */ = { + isa = PBXGroup; + children = ( + 083FAF36C95CE4B92F4A465353ECE4C6 /* PopupDialog.modulemap */, + AEA9286C59806AD1E11E2FD5B9F90733 /* PopupDialog-dummy.m */, + 69ED75F0B2316A6688A81A6A1728E93A /* PopupDialog-Info.plist */, + 70C85FC51E089DF1B652EDBE5CD782B1 /* PopupDialog-prefix.pch */, + 302CF87E639FCD36334254EC25AE99C0 /* PopupDialog-umbrella.h */, + EF5094047F1DE14436CA3AB5298C4593 /* PopupDialog.debug.xcconfig */, + 47AE5EF4EEF683F76336F5E2F095E501 /* PopupDialog.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/PopupDialog"; + sourceTree = ""; + }; + DF475AB9437D316570D4841957A5DBE2 /* Support Files */ = { + isa = PBXGroup; + children = ( + 047FFFBE4CC1CEA41C4164578F58ACF8 /* CryptoSwift.modulemap */, + 84E383DA3A0800A46C0734C2D4460F19 /* CryptoSwift-dummy.m */, + C9D32C7F5134420F2C61C17F759579EB /* CryptoSwift-Info.plist */, + 809579937BFB7F3B4CC2F399DFC66341 /* CryptoSwift-prefix.pch */, + 69A3F68D52609F06530707E690E292C7 /* CryptoSwift-umbrella.h */, + BB2964841926D0B8548E45C82B3BFD5F /* CryptoSwift.debug.xcconfig */, + 0F21A408FF9FDD6A3FFEDE112A1BFA31 /* CryptoSwift.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CryptoSwift"; + sourceTree = ""; + }; + E25F1E1356D41D04F0BF6064DEA3B628 /* SwiftyJSON */ = { + isa = PBXGroup; + children = ( + A08951CD09B134E4455D285B4E199637 /* SwiftyJSON.swift */, + 99EA7076DFA537F058D7AE3CD99CD8DF /* Support Files */, + ); + name = SwiftyJSON; + path = SwiftyJSON; + sourceTree = ""; + }; + E28761A96500BEFAFD13006937037172 /* Flow */ = { + isa = PBXGroup; + children = ( + 6D1A0FA4B06F24C3206B6E8ECC38062E /* AuthenticateMethod.swift */, + B08C0844D183BD82AD0C9ED81AA99268 /* BloctoFlowSDK.swift */, + A0C50F65C6376FDAC08630DD26C4B513 /* FlowAccountProofData.swift */, + F911CC7F62394A9AB0B666A7D3101E2D /* FlowCompositeSignature.swift */, + 606F713E4CA5C57D75EDFA2ABEDBCA02 /* FlowMethodContentType.swift */, + 1575DC7DE34542CAA9140F3C83A38F9C /* FlowMethodType.swift */, + A86732BEBFBCA696599CF87443ACD0FE /* FlowSignatureType.swift */, + AC3568EAA3220005786354D1B8DCCA50 /* SendFlowTransactionMethod.swift */, + 542C6DB9D65205F8DE75FE1C5ED21018 /* SignFlowMessageMethod.swift */, + E1655554B8A6F6D0EC8890EEA2359462 /* URLComponentsExtensions.swift */, + 40C9DD71B957910488093D4D1003D53F /* URLSessionExtension.swift */, + ); + name = Flow; + sourceTree = ""; + }; + E53F6DF31563223FE37AAEB6D52C3C54 /* Support Files */ = { + isa = PBXGroup; + children = ( + 6FA0BD9869B88FF73FABA4D6D57124D4 /* CGRPCZlibp.modulemap */, + A10F5D694C319F02E04D2C36464713C3 /* CGRPCZlibp-dummy.m */, + F252AC6CCD5977D44BA5C00A411DE274 /* CGRPCZlibp-Info.plist */, + 97360CE18256061D39011474972E0C90 /* CGRPCZlibp-prefix.pch */, + 5B323BAC1EC365CD5A5AFC329449DF3C /* CGRPCZlibp-umbrella.h */, + 5BE9BF7F0B0096EDA17340602CCF5AE9 /* CGRPCZlibp.debug.xcconfig */, + 8535333F12E206F0A29CED9A0F935BF7 /* CGRPCZlibp.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/CGRPCZlibp"; + sourceTree = ""; + }; + E653251FB0AE2A6C2A59F0A9670630C8 /* Support Files */ = { + isa = PBXGroup; + children = ( + E65A74CFF2E48DB5BDC56CB0068A6CA1 /* SwiftProtobuf.modulemap */, + 0C469D31D68B05F5C787C4195A2FB4C9 /* SwiftProtobuf-dummy.m */, + 723F81442DCD35573C56B73B133F718F /* SwiftProtobuf-Info.plist */, + FC260EC4C9B23C137D0191AC2936FC5F /* SwiftProtobuf-prefix.pch */, + C7B1D3A5BDDEF2311211C6CA5BF0AF3D /* SwiftProtobuf-umbrella.h */, + 8342CEB64D4BEBCE210DF23AAF9855D6 /* SwiftProtobuf.debug.xcconfig */, + 82FBE5CE279EE64E6AC1A3D977D9C3E7 /* SwiftProtobuf.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftProtobuf"; + sourceTree = ""; + }; + E71FFBDA6DF53D3031EE367F40C3B925 /* Resources */ = { + isa = PBXGroup; + children = ( + 383EA49322B94216634E72962ED27F13 /* SVProgressHUD.bundle */, + ); + name = Resources; + sourceTree = ""; + }; + E9272705AC011384D4D8DD6F7D1E2137 /* CNIOBoringSSLShims */ = { + isa = PBXGroup; + children = ( + FE25F61CB7A64F0BDD6A737277034E91 /* CNIOBoringSSLShims.h */, + 47DD2CA25279CAE9CE134398B7EFA22C /* shims.c */, + 70F95CA9979A9026044723228252BE4A /* Support Files */, + ); + name = CNIOBoringSSLShims; + path = CNIOBoringSSLShims; + sourceTree = ""; + }; + E963D50EB119129735A1E79DD351FFFF /* Support Files */ = { + isa = PBXGroup; + children = ( + 9F399A7791A91BD8ADEC576869E71837 /* SwiftNIOConcurrencyHelpers.modulemap */, + 4222400A280D18AAD5AD7F866EFF9A6C /* SwiftNIOConcurrencyHelpers-dummy.m */, + DF460495858DBE915D5FF2B7EB92E23B /* SwiftNIOConcurrencyHelpers-Info.plist */, + 515C37611AA1CAFD8AD95C60181AC7CC /* SwiftNIOConcurrencyHelpers-prefix.pch */, + 066CA9FB8FF27BE3124222A30B4AF4F8 /* SwiftNIOConcurrencyHelpers-umbrella.h */, + 00E8B69FA8F1B21329BA5D82E2893816 /* SwiftNIOConcurrencyHelpers.debug.xcconfig */, + 4829FCB00ADE43B6064E63565DEE1F5E /* SwiftNIOConcurrencyHelpers.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOConcurrencyHelpers"; + sourceTree = ""; + }; + EA37E1093FFE4E3F3B6C11F73B339277 /* SwiftNIOConcurrencyHelpers */ = { + isa = PBXGroup; + children = ( + C95B55237F43C6DD123B5CA48961ADCA /* atomics.swift */, + 36F8D48D07C091BB1DACB071869B385C /* lock.swift */, + 45B6B33E8DD205D584F0FFBE94EF68B3 /* NIOAtomic.swift */, + E963D50EB119129735A1E79DD351FFFF /* Support Files */, + ); + name = SwiftNIOConcurrencyHelpers; + path = SwiftNIOConcurrencyHelpers; + sourceTree = ""; + }; + EF4BD545F15D1F86A777BD488A300D7F /* Support Files */ = { + isa = PBXGroup; + children = ( + AE3210440188F385CA13711590591E66 /* SwiftNIOHTTP2.modulemap */, + D458F5EEF5F6D974F7A4B1C7B3B905FE /* SwiftNIOHTTP2-dummy.m */, + 07DFCEDD1083EC13218433CEA010C5DE /* SwiftNIOHTTP2-Info.plist */, + DA5F1FF9DF20765A233511DC436191CE /* SwiftNIOHTTP2-prefix.pch */, + D4D8755F63B123A5B3596B36D1B55D1E /* SwiftNIOHTTP2-umbrella.h */, + B00141CED0B13A8AB80467697980865F /* SwiftNIOHTTP2.debug.xcconfig */, + 4D67F34D63E7BD7AF2FC9BB501EE6A7B /* SwiftNIOHTTP2.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOHTTP2"; + sourceTree = ""; + }; + F701A73CC09C701BAF6B8B96A0DCEFFE /* CNIOBoringSSL */ = { + isa = PBXGroup; + children = ( + 2C71484685488673050E878779E16406 /* a_bitstr.c */, + 201003D040C6423595A3EC0B593CCEE5 /* a_bool.c */, + 85BCB5DB1810B32E458CFF66D5D5B0B1 /* a_d2i_fp.c */, + BEC3EBB70A4B1534B7BE14CD450659AF /* a_digest.c */, + 279DAF7322354512CDCD4BC5968C006E /* a_dup.c */, + 47B239F6E85774E499B22605B3CDB384 /* a_gentm.c */, + D448E72582B6BAAF2BBA7D9FA5189644 /* a_i2d_fp.c */, + 99B7B5C6C7132BC4AE13670C71B1D319 /* a_int.c */, + 3750323885EC02B225F7E44D305723D4 /* a_mbstr.c */, + DBBB69673F9AB022794371244DF6B647 /* a_object.c */, + F92FBFA8D72DAC4D564472BB97707870 /* a_octet.c */, + 9AF08C7D22A2CD6829F32301D191B54A /* a_print.c */, + 68CEBDA6647D2970C777AF684FD248ED /* a_sign.c */, + 6EF2B22C03C28FE00CDFD8407D2FBB55 /* a_strex.c */, + 764EEE0418CD889331FABF1FA4208DAE /* a_strnid.c */, + 1A64A81ABFFD55BDD512C9EE827EB405 /* a_time.c */, + 866B08232B96F5B9DA341EC4C127988E /* a_type.c */, + D05CAAFC9A2E05CC9475D01611990AE4 /* a_utctm.c */, + 125FE81450FCFDEECAB6FA98B546AB16 /* a_utf8.c */, + 1F3D03A413A633F04396541E48627005 /* a_verify.c */, + FD23B53B0A47C0B9314C9B5EBCE50F98 /* add.c */, + EF06B86D5C779FC349D2DC6B37349507 /* aead.c */, + AA9914C500C20DDCE0CFE379E7AEB345 /* aes.c */, + 35467501D3CA6E0233E29B1E9F1F0BEB /* aes128gcmsiv-x86_64.linux.x86_64.S */, + F20B9FF634D7126C0E37A3AFF9CD0B2C /* aes128gcmsiv-x86_64.mac.x86_64.S */, + DE9515A45FBBC6DCD53031F946838D95 /* aes_nohw.c */, + 2744B37C8ED8E5438A8F126831F29C6F /* aesni-gcm-x86_64.linux.x86_64.S */, + BD7145615C4722938094415282B4CC4B /* aesni-gcm-x86_64.mac.x86_64.S */, + 16D1A09E96EB6E967038D24C69E5B2C0 /* aesni-x86.linux.x86.S */, + E3115F95805159489F6A96D13A4B6B0F /* aesni-x86_64.linux.x86_64.S */, + 1808CB586541F56505012C7222909DEC /* aesni-x86_64.mac.x86_64.S */, + ED381E7A1561E7D710199DF83CA03990 /* aesv8-armx32.ios.arm.S */, + C47B78C19988CCCD0806027F63B5CAEE /* aesv8-armx32.linux.arm.S */, + 7BC31F011248F16CE3E77E3F25508401 /* aesv8-armx64.ios.aarch64.S */, + 970DE3CF94367649A0C1037F78DE8966 /* aesv8-armx64.linux.aarch64.S */, + 672C34D301D2789BD465129E931DF530 /* algorithm.c */, + 2B7D55E7D073D38B90AE5EFDF895B883 /* armv4-mont.ios.arm.S */, + 843C50DA31F8E3B21D234B2AE095DBB5 /* armv4-mont.linux.arm.S */, + 83D2B264237083DDB90A3A3B5618FCA5 /* armv8-mont.ios.aarch64.S */, + FA9B6B81A974AFAC9F65AF34375287F3 /* armv8-mont.linux.aarch64.S */, + 1DFD26BAFD93E2F23DC053E3D8373D71 /* asn1_compat.c */, + 6C149DBAE7FF996B43634962F24F3C27 /* asn1_gen.c */, + 4BA75EA43D5FC6726DC39A45537FD5D3 /* asn1_lib.c */, + D81F70F67EBAF255F9AB9DE70BB28A19 /* asn1_par.c */, + 2E4DB6419D123356E98E2E5554EB8DCB /* asn_pack.c */, + E1FB3A89265A69F9801F85E9DB90A200 /* base64.c */, + 24F21E455C17C94138FF860D25DF2215 /* ber.c */, + 31808CF1897D8D379D800951311CF3FF /* bio.c */, + 2208A35CDBBA7DCCEFF1FA3ECE745F07 /* bio_mem.c */, + BB0A8C2CB3C8DBC1632687EA5BA09D5F /* bio_ssl.cc */, + FB14291E43ACFF921F360FB93AF38517 /* blake2.c */, + 7974CE5CD2CD502F04009B9D88D533C7 /* blinding.c */, + 30B9ECDEF200F0B0B7B43576A64F2D47 /* bn.c */, + 48F5B0EAFC68E15D99BB48CE96AC36B3 /* bn-586.linux.x86.S */, + C0811470D725E0E13094B269A7653FB7 /* bn_asn1.c */, + BDEF01BE14B5AAA8285D70D93F0A5C6F /* bsaes-armv7.ios.arm.S */, + A9E372A470782C3F8A90B18E5E01C195 /* bsaes-armv7.linux.arm.S */, + AFC2B42DF489B79BF57DDBF4A56453EC /* buf.c */, + 47589CEE455848A67549A64D69A4B25B /* by_dir.c */, + E3E05A06E1D1AEDA186039A82B0C3048 /* by_file.c */, + 4FA167D30D3F8F8FEC7D9F31A0DA35DD /* bytes.c */, + 3E34D3D39BF3DC05FEBA1760D451BD70 /* cbb.c */, + FFDC3033E57BC05599C5A99C4F1DD735 /* cbc.c */, + 9A6AE05284A13FEEC2B201DA0DF6196D /* cbs.c */, + 968977F2912D1CEA6A50A6AEBE7039B9 /* cfb.c */, + 36595D90A92316F603C71CB5F01F7C1E /* chacha.c */, + DCC668BBD24EEF42DBAC20B915CC8D69 /* chacha-armv4.ios.arm.S */, + 8317596C69D387B4AA90D6E8E6EF1BF3 /* chacha-armv4.linux.arm.S */, + A813103232F50456F6CFFDBD38743C19 /* chacha-armv8.ios.aarch64.S */, + 90ED2F344C5847CA95D7B80B73E146A1 /* chacha-armv8.linux.aarch64.S */, + 9B531A3455683AA7F96B0A480AA4F19F /* chacha-x86.linux.x86.S */, + 288CF90C4C2212F995F62D27D54D0073 /* chacha-x86_64.linux.x86_64.S */, + F854D5B6B19CCABE0F70B1C6422DDCD3 /* chacha-x86_64.mac.x86_64.S */, + E804F479A0C73C7E15BF90C02CE451DB /* chacha20_poly1305_x86_64.linux.x86_64.S */, + 09E8238E00364F2B31B6E0428BB5C690 /* chacha20_poly1305_x86_64.mac.x86_64.S */, + DD080D9D0066EA88ABC10B14F8920C64 /* charmap.h */, + A5E983DC62177D36493A0A1614E01CD4 /* check.c */, + 7735873715F8E46AB2C372215EFEAEBA /* cipher.c */, + 580E2EBBFE458EC3F736133677BAFD9E /* cipher_extra.c */, + 90E4167A20621BF7147FD29098C445C3 /* cmac.c */, + E668AFE040CFD1CAC7A6D5CA192E1586 /* cmp.c */, + DE9AD1D139042C4717863CEAEC80465E /* CNIOBoringSSL.h */, + 6116A87F1DC0388E72BF1318376A9A8D /* CNIOBoringSSL_aead.h */, + 9DF64CD5C8E782FFABAFC4FF7AAF64C5 /* CNIOBoringSSL_aes.h */, + 066BA4BE605B6CE1001F8E954A29FA45 /* CNIOBoringSSL_arm_arch.h */, + 66077917DB54CBB0DFB565612EE929C2 /* CNIOBoringSSL_asn1.h */, + 8A126BD214790EE4C1CA42E4A387311E /* CNIOBoringSSL_asn1_mac.h */, + 8D8974AE36F98BE418E182C13540358C /* CNIOBoringSSL_asn1t.h */, + CF33312D7AC69B54F5B685FE2F46D2E6 /* CNIOBoringSSL_base.h */, + 62EC0F8FA6CDAD507979070A6DDC9CA9 /* CNIOBoringSSL_base64.h */, + 6D38132414C08347AD7B4BB2AC16B6D2 /* CNIOBoringSSL_bio.h */, + 769E69568A316FDF6B3797D285755BB7 /* CNIOBoringSSL_blake2.h */, + 74AAFDC7CD7AFD70EF9B0540E439156D /* CNIOBoringSSL_blowfish.h */, + 8FF09A62EB2C949481BE3164B7FD35AE /* CNIOBoringSSL_bn.h */, + 75B0E53F3B6357D83B76559AB25E0DAD /* CNIOBoringSSL_boringssl_prefix_symbols.h */, + 79B75CA13DC587252CA4275F80B0A9B7 /* CNIOBoringSSL_boringssl_prefix_symbols_asm.h */, + 9B5139FFF6FF1ED7F082529C640B4062 /* CNIOBoringSSL_buf.h */, + 9D925DD409F2D414D1714BB5A5CA7B35 /* CNIOBoringSSL_buffer.h */, + B659A48694C1451AC56E4764DE043F7A /* CNIOBoringSSL_bytestring.h */, + A69EBE0C9607A625092F94878F438ACB /* CNIOBoringSSL_cast.h */, + 72DD492310DBB3DC25CF83043BD87850 /* CNIOBoringSSL_chacha.h */, + 6584B64DEE85ED6A8185CB5C7BE2B5DC /* CNIOBoringSSL_cipher.h */, + 235F85F616FBD4AFE863F4520D597CBE /* CNIOBoringSSL_cmac.h */, + 8A438CD9BFBD6DBA35E833922EC43468 /* CNIOBoringSSL_conf.h */, + 225C2F0EB965A60AA6428E027F9D6370 /* CNIOBoringSSL_cpu.h */, + 924F1FC918F274DC38CBFFDA178B3404 /* CNIOBoringSSL_crypto.h */, + 701971BD8BCEF2402A37510E0BEE5103 /* CNIOBoringSSL_curve25519.h */, + 08F3996E2ECA8D02EBEDE108CE6C07DA /* CNIOBoringSSL_des.h */, + 22D5900AE5CF42D49A30529330F50352 /* CNIOBoringSSL_dh.h */, + EE9A66F407FAFEF96BA9346ED325C854 /* CNIOBoringSSL_digest.h */, + 40C2A0DFE4E35AC9512309D40178C611 /* CNIOBoringSSL_dsa.h */, + 8AF365C7AB26489C06FCFE902F8A964E /* CNIOBoringSSL_dtls1.h */, + 242C756CAA8E25AB53D50F4EB9DE1C91 /* CNIOBoringSSL_e_os2.h */, + 5AAFC99C5990321A2051AC7826DCE3C6 /* CNIOBoringSSL_ec.h */, + 4073C7B6E2C3A068A9662C2499E43876 /* CNIOBoringSSL_ec_key.h */, + D1AADC027009B9AD670FAB50C640B26E /* CNIOBoringSSL_ecdh.h */, + 5EBBCBD31CFEA671C4DC08DA393EF1BA /* CNIOBoringSSL_ecdsa.h */, + E90DB3DF75F4249C5839DBB7B1F6B048 /* CNIOBoringSSL_engine.h */, + 553CF428A3057584E0E91F727869C3B9 /* CNIOBoringSSL_err.h */, + D8B68FE07B21CC522B358D579282D30E /* CNIOBoringSSL_evp.h */, + E1F2D9F2F28DC75871F1432985EEE953 /* CNIOBoringSSL_evp_errors.h */, + F30262F08BA5B002A9DA4FA0B09FC1F7 /* CNIOBoringSSL_ex_data.h */, + 20D2544B93F0B3FCD20F549C25D6CF6F /* CNIOBoringSSL_hkdf.h */, + 9B43C57C58784FCEFA2CBDEF283F75B0 /* CNIOBoringSSL_hmac.h */, + 89335E424E816A8DC01CC0ACDD434A43 /* CNIOBoringSSL_hpke.h */, + DEBF4C708C9182A6158AD07729A04D54 /* CNIOBoringSSL_hrss.h */, + 3C9AF29710BD67F5A4A26E24F9B09020 /* CNIOBoringSSL_is_boringssl.h */, + 6CB4E7BB0CF0584BAD6F97344F04BCD9 /* CNIOBoringSSL_lhash.h */, + 792D40C0B5291DFDEDB11F6CE0649DB9 /* CNIOBoringSSL_md4.h */, + 5F0595717F923571F063D4697772B8DD /* CNIOBoringSSL_md5.h */, + 83BFF208CBA978EE49028C2CCBFFA9C1 /* CNIOBoringSSL_mem.h */, + AA22FB13720A6412E5E086ED932D06D8 /* CNIOBoringSSL_nid.h */, + 3F8615D099F6945070841273BA82F9DA /* CNIOBoringSSL_obj.h */, + 54DCBB006E801E2E59D8295DE6FBD486 /* CNIOBoringSSL_obj_mac.h */, + EE79390AA30BC15E638A709665466A6C /* CNIOBoringSSL_objects.h */, + 2643C0596BCC8A98798192904EE5725E /* CNIOBoringSSL_opensslconf.h */, + 3D37BB9E32BA0A1B7CACF7479569D296 /* CNIOBoringSSL_opensslv.h */, + BC235DDB7681F367A590FA00C20F5A24 /* CNIOBoringSSL_ossl_typ.h */, + C260B43A2350E61901AD4EAE6A63EC2C /* CNIOBoringSSL_pem.h */, + 24FAD07EDFD4F7446B7B3087913B744A /* CNIOBoringSSL_pkcs12.h */, + 6164625CCEC1B1A4714B2CAE4C9E60C8 /* CNIOBoringSSL_pkcs7.h */, + AEAD05B47CB8D574AC08834631342C19 /* CNIOBoringSSL_pkcs8.h */, + C7B12679B3AE20F22998634963EDEB40 /* CNIOBoringSSL_poly1305.h */, + F1D3285305DE04F9777C0854D000D062 /* CNIOBoringSSL_pool.h */, + 381018DE63E6716965F88F348EFBA40B /* CNIOBoringSSL_rand.h */, + 3D111CC23C86E6B89A4722CEDBB8FB26 /* CNIOBoringSSL_rc4.h */, + 8DA7813BCD0DDF69755DD1838DBD2583 /* CNIOBoringSSL_ripemd.h */, + 4FD4898DA7882FF64EA7BBF472DD0FEC /* CNIOBoringSSL_rsa.h */, + C0113A9C794494094661D69DAAEC3214 /* CNIOBoringSSL_safestack.h */, + CE7BD51E66B34C82517DC0D59C7B8BB3 /* CNIOBoringSSL_sha.h */, + 19E9154058D129015C37FB0D1CFADA46 /* CNIOBoringSSL_siphash.h */, + 42F7F1A1DBBFB7640DC700B5B0F5E3A1 /* CNIOBoringSSL_span.h */, + C270E8AAEC0C71BAB6FECCB12F46B555 /* CNIOBoringSSL_srtp.h */, + 6A210AFF28F0967DF1250DA5D6F30295 /* CNIOBoringSSL_ssl.h */, + 76D0C0B97E84363163E311367A65FD86 /* CNIOBoringSSL_ssl3.h */, + 85023AE87EBFED1E887AA6F3F7ABA2C1 /* CNIOBoringSSL_stack.h */, + 2139CE03849530684122BD8D1590DAD4 /* CNIOBoringSSL_thread.h */, + 5B030C622B398C956EE39FAAA7A68289 /* CNIOBoringSSL_tls1.h */, + BE0EFC3EFC30E0946EC8EAFAEB7C6A23 /* CNIOBoringSSL_trust_token.h */, + F1474C32BD49331333311B100CE80555 /* CNIOBoringSSL_type_check.h */, + CAB5BE488205DAD5ECF3325DBEB0CB80 /* CNIOBoringSSL_x509.h */, + EAD70090C51A8155E88EE4B15A8090B0 /* CNIOBoringSSL_x509_vfy.h */, + 1C5B1F22506D5F481C955B8329C18EEB /* CNIOBoringSSL_x509v3.h */, + 073163420BED79D3F0D457FBB780682B /* co-586.linux.x86.S */, + 9D8AC108A683453F882A65E63ACBC007 /* conf.c */, + 6DF2315104F0841E7D1F426ECF1DF5BA /* conf_def.h */, + 2CCCCBFDF06E3D222AD3E72FFE4BD813 /* connect.c */, + EEFFA244AF2F7CB9F637B306CE1884AA /* convert.c */, + 0FC4BA2407401C3D72C0698DD1AEEBE5 /* cpu_aarch64_apple.c */, + D7C73208AD27DA45312A80946D6185E9 /* cpu_aarch64_fuchsia.c */, + 3624E55B7B6A72C190EF3AFF2F736950 /* cpu_aarch64_linux.c */, + 139A78790D675E8D7658D8A8A2384794 /* cpu_aarch64_win.c */, + F98FEB534446DF2637FA145FD087C2E3 /* cpu_arm.c */, + 35A60E87A46C4A1C69DADD9B8B770A1F /* cpu_arm_linux.c */, + 32DF3DB2C8D58227D79CBCAD10A7CC06 /* cpu_arm_linux.h */, + C6DEF9947D494076C7D9D1324FD01167 /* cpu_intel.c */, + BCD389D31F30FBD3A0E3D7DDB3273254 /* cpu_ppc64le.c */, + 06A8DC591EE9F5CEEC5C7D12DC2FF72A /* crypto.c */, + 85C28454D1170371B9D8A0DF53331720 /* ctr.c */, + 8A0B2BF8BB6F85B0D453ED8C0B12FC40 /* ctrdrbg.c */, + 137BE3AC11783E57A07C5477D5948A98 /* ctx.c */, + A01EEE5EB6F8BB3C30D2412EF6E4A8DB /* curve25519.c */, + 0744CD624F8529BFDA6DD9FE8C4A0D3F /* curve25519_32.h */, + 3D2A8E0EA07BE8699C688044205A447C /* curve25519_64.h */, + B5A245C7712673F309BB6780D129E133 /* curve25519_tables.h */, + AB8849B3D92320B1D9361B58B46BC9E8 /* d1_both.cc */, + 57AE728B2D53D0CB3F47000F93780F51 /* d1_lib.cc */, + C004D6E82E62266875A85C4DD9BFC4D1 /* d1_pkt.cc */, + 7DE6A0217C1A0B0D81EBB20DEAFE8713 /* d1_srtp.cc */, + A8AC96E184F6A709EA24AD89B6A214CC /* delocate.h */, + F61BF97A058E4380C2240049EF36E9E6 /* derive_key.c */, + BBEF31902CE95C276B59B842C4B48F38 /* des.c */, + 2A6B5A15604556F5E309DBB8A743209B /* deterministic.c */, + 0480F69F7241973DEDB98B22253663AC /* dh.c */, + CF6A36C389477C0B91CF6F4154DE17C9 /* dh_asn1.c */, + 3FB8BB999DEE6A0B9F8D50422812E258 /* digest.c */, + 8F01808D47405EE897EAA5274B62488C /* digest_extra.c */, + BBAC339BE80C1C4E2E9507BC75AA64C7 /* digests.c */, + FC9D40188C134BF4D0132BAE23A32251 /* digestsign.c */, + 8DDE2415D2CEFD7CE529F9EB805AE1B1 /* div.c */, + 70AC45CB71401C49657416805D8D6801 /* div_extra.c */, + 11355BF143D6A8167F1CF508A51F64EE /* dsa.c */, + 0B3959585FF35CABC0E8BD2E19A0EA98 /* dsa_asn1.c */, + 50A09330521F5E469A86D09B6C683AE0 /* dtls_method.cc */, + 7002D4F1EB05B8F8EEF19D1CBDA2833A /* dtls_record.cc */, + 64117CF438B850CA195E0F38D6F76C7F /* e_aes.c */, + B3AC106B742111DE087FA7B87A523B68 /* e_aesccm.c */, + B9F05E2FE7977D3C097CFCCD3D8F4C2C /* e_aesctrhmac.c */, + 0AF76A158E58D3DF43D7424F076AAD88 /* e_aesgcmsiv.c */, + 14819172B31D4560BBD90390AB099AA1 /* e_chacha20poly1305.c */, + 275BABD7D495C8038B7954184A3542E8 /* e_des.c */, + CDDC0B8D791C8C49E6F9070D46D7CF5F /* e_null.c */, + FED43552635768BCC4C78BEE32DCA1A5 /* e_rc2.c */, + ADBA815F54C9D0EBF6960A6A7CBB4C5A /* e_rc4.c */, + 1BB4947856BAB2BD924157D3AA2E861C /* e_tls.c */, + 1997AA70B5C9CF99899BAAE9C39F3687 /* ec.c */, + 603DB6327F928979DB143EDB3B2E94FC /* ec_asn1.c */, + FD99AF05FFC3A4C4404BB9C4D287D3BC /* ec_derive.c */, + 52FEBD0FB983B544EE473E3B708AF839 /* ec_key.c */, + 3B1D90298B7591466F5ECEA71DE9F898 /* ec_montgomery.c */, + 5A8344CF6C33D499F30836C9EBCE1F20 /* ecdh.c */, + 557E8F163489D4D5A76F3540372DF512 /* ecdh_extra.c */, + 86B849448B31D6D97CC059662046AB48 /* ecdsa.c */, + 0C88AF3E809F3C89DCD2B84B6726E1CF /* ecdsa_asn1.c */, + 4FA19DB464A583F8787040A400E72AF0 /* encrypted_client_hello.cc */, + A8D66AA126C6C94A62B4E3B3EC35645F /* engine.c */, + C4CB6337AAB3E193E899F6BAA540A282 /* err.c */, + 009C115F9C8F1EBC270B2714D9C76DCE /* err_data.c */, + F6B770EF99C3415FE53DCA48B48F61E1 /* evp.c */, + 38BA9B5FEB9C039329AE2A15D4D42739 /* evp_asn1.c */, + 8064FD2B8EED372A919120A0AF91965E /* evp_ctx.c */, + FF2320961936E59CBDAB2EBF11A7B62A /* ex_data.c */, + D306E5CF93DA0C35925B406052C351C2 /* exponentiation.c */, + F2F8FE0DA2B701325F9AE8CD81D9ECC0 /* ext_dat.h */, + 576E84427AEC0E7BD5C7523E06B64FB3 /* extensions.cc */, + 5EA5D5F30C38E89044BB740F26EE88DD /* f_int.c */, + 3C54FE2987488C6C135F609E75D9D5E5 /* f_string.c */, + 0CF8D342496F49AFD2C13EF26F105ADE /* fd.c */, + 82BDEA9DBA5FF9733B6B9B3BAB638B79 /* felem.c */, + 8156F58C8053D3FB9A6408CC8A13CDE1 /* file.c */, + CAF3612E50BAAE6C2D6EC831E700F9FF /* fips.c */, + CAD15AC7A223C4AB51E56BA97FE8D30B /* fips_shared_support.c */, + 225201E51C43DA7D188B2242FC65C191 /* fork_detect.c */, + 9DD497DF7646EFCA903C73201E6D5128 /* fork_detect.h */, + 947D727E23A36EA2E057AA2043E55414 /* forkunsafe.c */, + 3B40B7E604BEB81EC871771768F61B00 /* fuchsia.c */, + 2FD0458620342EF1241D8233FE11526E /* gcd.c */, + AD399753F135626CB1495DD19609C932 /* gcd_extra.c */, + 6882A01C332B342BCEAFA7A90B78BB4E /* gcm.c */, + B0E148C89286FC10D58812BF0310AC2E /* gcm_nohw.c */, + 1D7FDD58731DDEA2F0F27C7ED1964F45 /* generic.c */, + E82FDE9D9EB4589FABB9CC02B87186AF /* getrandom_fillin.h */, + 3FE009698F0B833B3B56D8E247C0E2D1 /* ghash-armv4.ios.arm.S */, + 276ABCC94009D60FD2C18128F2B2586B /* ghash-armv4.linux.arm.S */, + 81B21E3A326D5E9975392E40E1B3C9D7 /* ghash-neon-armv8.ios.aarch64.S */, + 09EA10F3BD9588C5F0626E1E2EB3058F /* ghash-neon-armv8.linux.aarch64.S */, + 13FCD06B6CB42DC1D49F888089EC1304 /* ghash-ssse3-x86.linux.x86.S */, + A3446BB29394B0DCC0BCF77E214CF218 /* ghash-ssse3-x86_64.linux.x86_64.S */, + 3F42E68F8F1B4036B1AE89EDF9CFA7D3 /* ghash-ssse3-x86_64.mac.x86_64.S */, + 86BCE77648001A9860BA9ED1C6D5CBAA /* ghash-x86.linux.x86.S */, + 48D89B5DB7277D2575CCD411BCBF2911 /* ghash-x86_64.linux.x86_64.S */, + E40AE1987BFAD661223EDD5BCD64E438 /* ghash-x86_64.mac.x86_64.S */, + ABCDF59FB62F7013BA9A97B7F0EAD7E4 /* ghashv8-armx32.ios.arm.S */, + 1698B48A7FBCCD81FBEAF7B8D95C5CCD /* ghashv8-armx32.linux.arm.S */, + 3ED5C868056584A2804EBA59AC1F8DB5 /* ghashv8-armx64.ios.aarch64.S */, + 0624CB03F399E0666C965D9203090649 /* ghashv8-armx64.linux.aarch64.S */, + 1449BA3246ACAD59795CF756778E324E /* handoff.cc */, + BE221C402A207197DC2799CBC4A0FF4F /* handshake.cc */, + 933FDBA513463FAC642AF22F11B680FC /* handshake_client.cc */, + 49538024CCF200F26D85AF212732E499 /* handshake_server.cc */, + 76C4BC78E99BBCA69E17333115A63EE1 /* hash_to_curve.c */, + A2C5C802B3FDA538AA688E471C10BA99 /* hexdump.c */, + 27EBE9375FCD8E338CF2D516B8869EAE /* hkdf.c */, + 93AEA077B5B2D1CE26978A40A245BF92 /* hmac.c */, + D3801A363FE17786D7DBE4F3571FC3BB /* hpke.c */, + 8F941B1AE0DE9669799EA5DB9604311D /* hrss.c */, + 0686F287BA1CB4499AAACB0B42046194 /* i2d_pr.c */, + 4A26A6109C860BF91A1D978645558CC2 /* internal.h */, + 31E0781A7DC6D1FDC2E73FE1098577E2 /* internal.h */, + 251AE8F2B12EC0B82DE04BDCA51B97EA /* internal.h */, + 9024AD82FD71C379F75FC57CA503D370 /* internal.h */, + F1E99C30A6589FEA05F5C1AFAFE119DD /* internal.h */, + 2E8885964394043CF304049308BC001F /* internal.h */, + E5262DE15AC178F44123A11F52286966 /* internal.h */, + 9992AD91E5BD44D3B71483530B7FB33A /* internal.h */, + 1F75E00AC1E123368612D1953C7A472B /* internal.h */, + 28A8B8911F41C0B29674DD930FA0C2E8 /* internal.h */, + A69601E2C917D2C7F86620B14F5F6987 /* internal.h */, + 42421A125481E8BC392AE93887636702 /* internal.h */, + 3A13056BABF3222698DC5A80B5463130 /* internal.h */, + 389A98E60BBEAB30A4712D63BE032A95 /* internal.h */, + 169D6C71568363DA1999B117D896AC68 /* internal.h */, + 573642D12978379632CF4F8FADF0BB41 /* internal.h */, + 1073FF82D7B94967CD02A0F194F4DA56 /* internal.h */, + 08DF2B71AC6C25CA17AE97DDD49CD7E3 /* internal.h */, + 3447ACB6AF004264B23BE6BF79FE179E /* internal.h */, + 965C295B24640A3C38DFFA48A87550C3 /* internal.h */, + 7E78B33A1DFF123DF62FA02FE632939A /* internal.h */, + B136E798B4E73E57A5A5FCC779C6FF2D /* internal.h */, + D88B4F5806EF70D37AF0578452D42980 /* internal.h */, + A5AE57BE0D5EE76EFBABB44E2EA7B7A7 /* internal.h */, + BD1F34CFE7497BBD6197A9FF7E8FC7DA /* internal.h */, + 0AEBF46834A19EE43F1812948101E19D /* internal.h */, + 31077F40DE76448B09C8C93E0DFE3AF3 /* internal.h */, + 4DDFBE971A9F36C3D422E7C892F6053A /* internal.h */, + 83A30EB5C0B404B831478DE052634CFE /* internal.h */, + 6180C78B00D01DE7E8304F0223D7EC39 /* internal.h */, + 3C0A6F2A5DDB51F0F498518600BB7E21 /* internal.h */, + C76D5CDB172A27B9B99CB6F16784B942 /* internal.h */, + 6987D26A615917E6A7DB77F32FD14EC2 /* internal.h */, + 3E434DE23A18B5F3AE72EEB4CDE12D61 /* internal.h */, + 2B52153335ED8460B4D76170794B791A /* internal.h */, + 831C0F957479585F1A8681350E2F1960 /* internal.h */, + 113398F397A4A27D8E9FFEE9D0AE4AC3 /* jacobi.c */, + 5028C4DCE5B10736EA096F4B9353E47B /* kdf.c */, + 167F7BD23ECC1417C82557643373AF11 /* key_wrap.c */, + 598247BC22A408C1AC2B3DB8892F821A /* lhash.c */, + 2D0DC076BBAB2EA49B318C0AEBB39F4F /* md32_common.h */, + 7A9EC9573C7A3E60032641DD2C1C4795 /* md4.c */, + 14DC03D634FF492642E6371B31F1264A /* md5.c */, + 4CED859490C1400D8301C7B7C47AF813 /* md5-586.linux.x86.S */, + ADF1451E76D53D6923B25ECAB4EFEC04 /* md5-x86_64.linux.x86_64.S */, + FB05FC2852DC3B82A137AFE1FD584A3E /* md5-x86_64.mac.x86_64.S */, + D5B4F82B8EEFF961A5F7EC682B610977 /* mem.c */, + AD1A3DE715CE103B04510EBCCB7557F5 /* mode_wrappers.c */, + A495CC0169B4DE51BC42C5C9FD5C2B14 /* montgomery.c */, + 1BD11E4F78AC8858E805F4B175704574 /* montgomery_inv.c */, + 095487687BC21CBD523027ABA0812340 /* mul.c */, + E25DB3244B2111EE09A01E72382F5CE3 /* name_print.c */, + F84197669E7FAFA2A6430305A4B74647 /* obj.c */, + 130724651ABE653E5C388F378A1A011F /* obj_dat.h */, + A2B6F66717F15163B79818319D00A6E0 /* obj_xref.c */, + 6ED3A5996E262D0EF0535AC7C4137969 /* oct.c */, + 8C9A1B083389A9099DA073CE542C2329 /* ofb.c */, + 34BDDD8B06A6C8AED5EB5D30FA9F2A88 /* p224-64.c */, + 53392B8EDA78E9CBEDC1226D85F9EF59 /* p256.c */, + A69622B5F3DF7E322BD0DB1E53CE75FF /* p256-armv8-asm.ios.aarch64.S */, + 4548E0B0E2ED9F2EEF03049DE28D7C48 /* p256-armv8-asm.linux.aarch64.S */, + 993A1317DC22F99DF8A87D2BEF94AEA3 /* p256-nistz.c */, + AFB519F2A9DF09C595E0186FDD032F11 /* p256-nistz.h */, + 63113E7737284DD30A6259682D4CEA67 /* p256-nistz-table.h */, + 4BA7A5A13941436B4785B45BEF1D9012 /* p256-x86_64-asm.linux.x86_64.S */, + 75CA24FC216CB0ED577D2C21D9993B55 /* p256-x86_64-asm.mac.x86_64.S */, + E9EFF4C4B9DF5E0341500D3BDD455CE8 /* p256_32.h */, + AD1003EB741271BB093E74D64F323A92 /* p256_64.h */, + 2D19761A0B447DA579F73045D0EC0405 /* p256_beeu-armv8-asm.ios.aarch64.S */, + C9CC46CB241619CF2FF6976F65331C22 /* p256_beeu-armv8-asm.linux.aarch64.S */, + 95006D59F8C11B65CE508C1BE5751A46 /* p256_beeu-x86_64-asm.linux.x86_64.S */, + 09A50810385D7DEBCBAB856DE8A1E29C /* p256_beeu-x86_64-asm.mac.x86_64.S */, + 126ECBF84E8EC272A797E71ED28D0785 /* p256_table.h */, + E77F790CCA4B1B8F1B6CD5B3C98BF486 /* p5_pbev2.c */, + 63A1C84C64764931184EA5A3B829CB71 /* p_dsa_asn1.c */, + AB71FD00DEB3A0ED199A7CF3CE0181B8 /* p_ec.c */, + 26468D5F27DE15516B01E0C24D8DC020 /* p_ec_asn1.c */, + 7B343970A1011A392AEA4D1F350C12D6 /* p_ed25519.c */, + F3DD926E581AA883A2946241C603809A /* p_ed25519_asn1.c */, + D800D3A45C73A256CA1CA8ECE8173369 /* p_rsa.c */, + CCA5BEBB9543CB4D3616D04BAE558155 /* p_rsa_asn1.c */, + F030EBCD1BB9F6809ACD10D556B7B1A0 /* p_x25519.c */, + 183018A2F8E465C8814BA55F7DD78965 /* p_x25519_asn1.c */, + E27145F5259634BD1971D2919DCF19EE /* padding.c */, + 5ABFF64DD17238FD146150F9D6C09010 /* pair.c */, + 99C414B31E8A4D979898A38141A74B97 /* params.c */, + A69F7967829F2BA523BFAF89710C4A00 /* passive.c */, + E66028A9BC516368D326E1467AD827B9 /* pbkdf.c */, + C4F50D1510E1DDB79006E5CC71F205C4 /* pcy_cache.c */, + 547798325CC1938A46B860161C33CB10 /* pcy_data.c */, + 68729B16F225DACE71B8D33EB9ACB558 /* pcy_lib.c */, + 391A2DAE73D4062B17F9DC9B32E75C7F /* pcy_map.c */, + 1B10E2920D0B16D49380B9A007D044A8 /* pcy_node.c */, + 54B8FDBB46F84E79D561233DE2CB2ECA /* pcy_tree.c */, + 926ADA1DC1706FBE131060E6C9790423 /* pem_all.c */, + 388E956EBF9BD27203EBEEEE800C4D24 /* pem_info.c */, + 8DEA8C2291C63E540ADE27DF18E653C4 /* pem_lib.c */, + C43B966FB585F6DD13A697D96166E616 /* pem_oth.c */, + 56D8359142F5F79A1F73766AFD5D69E8 /* pem_pk8.c */, + 6F7503BE3EC95DDA2F8E1ED90CF7CF71 /* pem_pkey.c */, + 79C3BB6A22C6C64728AE5A3A9800B74C /* pem_x509.c */, + D6397A1E765ACDAE82BB631C5DCBB30F /* pem_xaux.c */, + 3F9DCE64FEE0B4BE586CFAEB2F055774 /* pkcs7.c */, + 5CA8A516E5D26CFC3E0BBE41525B3EC1 /* pkcs7_x509.c */, + FADD4E85533236D815BDBC5585464254 /* pkcs8.c */, + 6A4BFD29442A54F99DEFEAD99DCE208F /* pkcs8_x509.c */, + 6763E9CF3A1C3076164F2C922B83431C /* pmbtoken.c */, + A3B296B9B264741B05D9FCA4EA296817 /* poly1305.c */, + D2F7A62C86D43CBFBE760EC3E47BBAE1 /* poly1305_arm.c */, + 871F2A38AE8AC9376E3561F36772742C /* poly1305_arm_asm.S */, + DABFF317E1626B524FACA62C0C149889 /* poly1305_vec.c */, + 25E3E2C3D37FF81B175B64914C4DC51A /* poly_rq_mul.S */, + E8263A32885981CDD291AF8C313E0131 /* polyval.c */, + 6C1D5CAB4128265FE20FCEEBB65A1CA9 /* pool.c */, + FDC3DE34332A925ED7AF74B4A48270C8 /* prime.c */, + 926E439F468CB0725B600E917A8FD131 /* print.c */, + 3C684847AD03E2C92EE6DC36358B8005 /* printf.c */, + D78E079D6EED20A6C6105DF41E1D00B7 /* rand.c */, + 3296571AEE74017B771EDAE08C437F61 /* rand_extra.c */, + 63B54017CE0B0CA0650D0731FB5F9950 /* random.c */, + F6801817E0996DB2058C8F032BBEF622 /* rc4.c */, + 9F44F5EF9CCF2E1F401C612C898A6846 /* rdrand-x86_64.linux.x86_64.S */, + 9E6C571B78A8486423E82B83B20305F2 /* rdrand-x86_64.mac.x86_64.S */, + 80D071A6E31239AA1A56D6F34AAF2BFD /* refcount_c11.c */, + BA44DD3AAA85A97EA796D27E695437BC /* refcount_lock.c */, + 99397EBD2713FC0B5C926E662DB36B29 /* rsa.c */, + 239876020140DECD9541EF5A9B12F7B6 /* rsa_asn1.c */, + 2E922A1CEE4EAFE9C8F97BD271F6A11F /* rsa_impl.c */, + 383D394039DA0D40F1AC14793FDBFB62 /* rsa_print.c */, + 36BCE89A2F094A56A37CE24E51E8478E /* rsa_pss.c */, + F1B3C4AB602AE6C7E11DC959C4F5F4D9 /* rsaz-avx2.linux.x86_64.S */, + 5183C8B06B2FB512F8EBB2BA65E84D34 /* rsaz-avx2.mac.x86_64.S */, + 36D26F5E67278BD31B9999C31CB37CBE /* rsaz_exp.c */, + 7D2D3C66784C69FFD174E32B064616C2 /* rsaz_exp.h */, + ADCA520ECD233B494FD505EBE481F731 /* s3_both.cc */, + FD318DB1E63E9531C89B293D34186B07 /* s3_lib.cc */, + 5579F459567A501C9ABAD77F662B04E3 /* s3_pkt.cc */, + F3F7DDBE2182C2EEA7EE5F9F7EFA52A6 /* scalar.c */, + 8CA968D37E649A137FED235C6F605C65 /* scrypt.c */, + 124D5FE45BB35F7C5F6BEA5A13BB220B /* self_check.c */, + FD3272BF10A705DA3798C673B76D5148 /* sha1.c */, + 9749E5B1C62EFA9B15CB3B561D4A3F43 /* sha1-586.linux.x86.S */, + 156F768DC24E72ABF7AFFB0B384D10C8 /* sha1-altivec.c */, + C4C69845B2B0DB9185C23E3B1BBBB22E /* sha1-armv4-large.ios.arm.S */, + 3FC68B1806253222E7DEC3A03FA57876 /* sha1-armv4-large.linux.arm.S */, + 1910BB24C12FB9701C167D4835C46CF2 /* sha1-armv8.ios.aarch64.S */, + B973EA967343AFC1DF901B6918C7E1D3 /* sha1-armv8.linux.aarch64.S */, + D61158F986302E12E922F356AC6A7673 /* sha1-x86_64.linux.x86_64.S */, + 7EF2A44E9190048723B5408D239C2DC8 /* sha1-x86_64.mac.x86_64.S */, + E2289E7AE246F961F1A92D56F8B531B7 /* sha256.c */, + E5870E9EFBACE59A56028B0E330D8339 /* sha256-586.linux.x86.S */, + 9E786D76B785BDCE148B66B3149FCA4D /* sha256-armv4.ios.arm.S */, + 02D9B7644BF54ECC5C459FE5F0A4D8A0 /* sha256-armv4.linux.arm.S */, + 809845627483AAE66290A0A5CAAB924F /* sha256-armv8.ios.aarch64.S */, + 9F057B73B6702566A18F973839B10FF7 /* sha256-armv8.linux.aarch64.S */, + 0B8022ED770EECA6AD08D59D3C644A1E /* sha256-x86_64.linux.x86_64.S */, + 7C5265CC769A2FD94944FE072A165B82 /* sha256-x86_64.mac.x86_64.S */, + 9711B7C6751DB7169E30AC2344DEFFBD /* sha512.c */, + 0E725B039DDE85D72BAF12B4A4CFB2F3 /* sha512-586.linux.x86.S */, + 0A98F39503CB658134EC3722FEC271DC /* sha512-armv4.ios.arm.S */, + 79C25710B55D85F3562DDF354FA4D589 /* sha512-armv4.linux.arm.S */, + 9822C50FBD93EA3721F13BD2B0A8B553 /* sha512-armv8.ios.aarch64.S */, + FBD5B642CFF084A609C00F03399C12CE /* sha512-armv8.linux.aarch64.S */, + CA752654586A87C3CF5A48628F2A0C70 /* sha512-x86_64.linux.x86_64.S */, + 05BA590DAC219FB7EAC94ED634E0FB8F /* sha512-x86_64.mac.x86_64.S */, + FC26EDDD6735D27600FA0D17B85868CB /* shift.c */, + 3327CF7D3195E556C6BC5D38CD50DC54 /* sign.c */, + C64905FA3EA211221F9F9969540494D8 /* simple.c */, + 434EE467ACF31ADF9B7EB3AE050852FB /* simple_mul.c */, + BB2B48DE63C63DFDCB60CF127640A4DA /* siphash.c */, + BBEEB47144B65631102F7AFC833EB4DC /* socket.c */, + 8908B111120DA1E80ADDAE3AA27324C3 /* socket_helper.c */, + 4BC863125BAAAA379F9D46B9B09FA011 /* spake25519.c */, + 23A6E2F9965A1F5B3DEF4780054926B2 /* sqrt.c */, + 150528A791ECFD7B40965F1B68C64876 /* ssl_aead_ctx.cc */, + F3073BCC2A47AC56DF49294324E56648 /* ssl_asn1.cc */, + 22AC771C467207A9BA0A54A03227D294 /* ssl_buffer.cc */, + FDD6D466796CC73FB667BFD0CFF68102 /* ssl_cert.cc */, + ADF6487B52236A319DE826891AC0CC05 /* ssl_cipher.cc */, + 50D5CED640DEE11BBAA33C46AB1A9DD7 /* ssl_file.cc */, + 7EEDE01AE2D834A270754AC5ACCD6FDD /* ssl_key_share.cc */, + BBDE3E6CCC2C2E47E05E483B33552AD8 /* ssl_lib.cc */, + 626D6A6FBA3C4456357F4F9D36C475F7 /* ssl_privkey.cc */, + B676A8CC6D7A55B9F2330EFF0F439AE6 /* ssl_session.cc */, + 7A847BA2B6D042C77880F1099B20995E /* ssl_stat.cc */, + 2CE94AE477E46E05AD8CD7994C9018A4 /* ssl_transcript.cc */, + 6BFF036C07C43EDDC9044F5A484038AB /* ssl_versions.cc */, + C392709A348F71D9BA1F421199AAA4FC /* ssl_x509.cc */, + 5A4F06961A91338037FDCD870FD3A52E /* stack.c */, + DAA737D85B90547148EA523BDB9C67F8 /* t1_enc.cc */, + EEC7776718F9A0615E07E697E101BD00 /* t_crl.c */, + E36639476C222AC1321AE96AD9D9F3C1 /* t_req.c */, + 2353F9CFA0E9F592D40639086374E728 /* t_x509.c */, + 868290F8DF10946C2B695AE2C93A45AA /* t_x509a.c */, + EE376EECC27E33D291AAD2610B267511 /* tasn_dec.c */, + 885E717B30A17DFBD9D63B98379E6883 /* tasn_enc.c */, + ABF3045DB54F2F18DE8E2856CF02D59B /* tasn_fre.c */, + 77FC267086AFB9870729CA2F56F19755 /* tasn_new.c */, + 08C897EDF2921AAEFC00DE41E4E472F1 /* tasn_typ.c */, + 92E357F294D6449E154AA957032191D4 /* tasn_utl.c */, + 3090844C262BD61943DE6CB9833BDAD4 /* thread.c */, + E7F100F1D0CF11736A4A00AE46E8435B /* thread_none.c */, + 8FB4B7760175730C39FC1F260C5439B4 /* thread_pthread.c */, + F4101AADDF0EA95C8416FE6C5C9F8FB4 /* thread_win.c */, + 6B0606176305FD0DDFCA2EFCE02CBE4C /* time_support.c */, + 31F4ED7CF3CE87BEDBC1F99CB0874EE6 /* tls13_both.cc */, + 7F9AA16751603F0ED1D7D6241CBE2549 /* tls13_client.cc */, + AF8DDEA73D7A9A0D0BB5BE9F00FE3CA8 /* tls13_enc.cc */, + 21294BEA1B79ECCF54117971DCFAD4E3 /* tls13_server.cc */, + EA2A0AF3A809B6D227FAF4440D16DA91 /* tls_cbc.c */, + 0F614077E368A14C70311405F7FE69D0 /* tls_method.cc */, + 9B5F437EC689DD66B48C952477347467 /* tls_record.cc */, + A3786BF0BD05B585EE84F25EED9031FA /* trust_token.c */, + A3F40CFB0549042E755E3C6338B0A11C /* unicode.c */, + 9975BCDF9C13EAC1086E49406AF9586E /* urandom.c */, + 86CDA9D7F74123ECD5926436D656E42E /* util.c */, + F9244E289417969DA18D388116361D90 /* v3_akey.c */, + 5D62241984225CE5EAC16D48BC371AB8 /* v3_akeya.c */, + B1D31E813551E4238174131DCA97F395 /* v3_alt.c */, + A3DFBFE8EDBE45EFA4304736E38C2792 /* v3_bcons.c */, + 5F492BAA38208825BA9D871CE8E97BFC /* v3_bitst.c */, + ECDEFD005DD0018E26210FF8F6A95B5C /* v3_conf.c */, + D10BB7A9B0FD68ED82C64D21CAC3AF2B /* v3_cpols.c */, + C03F3F214061CD431CD8FE1BCB83D015 /* v3_crld.c */, + B5FEBD4F255A8CA1957B51619B8FE6AD /* v3_enum.c */, + 4866F4D0DEA7C704FFE87F04B0E49967 /* v3_extku.c */, + 8EF5CCE3CAE796C01BC8099306428ED4 /* v3_genn.c */, + 201E492F116A89CDAA466CBA8D40CF6F /* v3_ia5.c */, + 6081F7CA47E05CCAB868E82D6A8D6A3E /* v3_info.c */, + ED387E83E449F79ECE1D3527813215E3 /* v3_int.c */, + E0EA82A4A84FD9D37485CCA3798E48A6 /* v3_lib.c */, + 1C745E1C3AB4D48E7AAE3A7CB7C661AB /* v3_ncons.c */, + AD97C485447932CFD80DAB09622E758C /* v3_ocsp.c */, + 1D45A7157713AE7017F1EF3AF4930E2B /* v3_pci.c */, + 536271B47921F5A15BD15A2481CEC19A /* v3_pcia.c */, + 345E070647C98D8EDC77638552258C8B /* v3_pcons.c */, + CDA93E44ACEA49D047A8B0DFCED8CFEB /* v3_pmaps.c */, + 5C046B5BB46DDFF18ADD409B49436BD1 /* v3_prn.c */, + 8A6FE2D88F187D54B3237983D3AE0408 /* v3_purp.c */, + 8C37C919BAC5CC9F4315FC8E80AE0BAA /* v3_skey.c */, + 4FCEF474895FD1E1FEDC2B4A58A77FBA /* v3_utl.c */, + FC515B3B56B84E2210FA56992DB9705E /* voprf.c */, + 540D85AAA885F961771C8AE709B2E3BD /* vpaes-armv7.ios.arm.S */, + BA415EF77A72691888985A75DD694708 /* vpaes-armv7.linux.arm.S */, + EC4117C89342DC6DB6591EEE2778D12A /* vpaes-armv8.ios.aarch64.S */, + 807BABDB923D2AA2EDE6E2C9564118CD /* vpaes-armv8.linux.aarch64.S */, + 9FB260E0E9462A69EC446102C7E8886E /* vpaes-x86.linux.x86.S */, + 012D295FB484D69B3CA2BD10A7F20B4C /* vpaes-x86_64.linux.x86_64.S */, + 26B2FAE9195C1B10FB8289451911B381 /* vpaes-x86_64.mac.x86_64.S */, + F8DC87EB0A7B8E748FD15F55C32E2256 /* windows.c */, + 26D493BEBDA50C996FF6E836192AD09F /* wnaf.c */, + 2F6F9372C9AE6F2B9A7BE59E5A636A92 /* x25519-asm-arm.S */, + 1077464057841BEBFE3889CA5E03ADFE /* x509.c */, + 978ED63145A5D349DC34780FDD0A8CC6 /* x509_att.c */, + E19198AD322B90004297C469FEA5DB6C /* x509_cmp.c */, + 05C69BB038C2BE1ADA4A8E7DFE61589F /* x509_d2.c */, + 6EB81601FBCD4A2EB2215AD7D3F98D37 /* x509_def.c */, + D2711FB3F56616A310BA4635C98D5817 /* x509_ext.c */, + 93E4422CDED7F1D4227B7E5D322F43C1 /* x509_lu.c */, + A718B5CE6BA2C99D08C87F557C7B2B5C /* x509_obj.c */, + 99DB7853515659BF0940D0DB249CF962 /* x509_req.c */, + 5A09CDE39737C3CDDB81BF9732C91CFC /* x509_set.c */, + 58564B21CC6075F988564B3467107203 /* x509_trs.c */, + 0671DFB179723F36496A64FE5B5B2A25 /* x509_txt.c */, + 3952A7D0C8AA53FC69555B71FFEC8EA3 /* x509_v3.c */, + 0E793BBA0C633FEEDBABABF92969F7DB /* x509_vfy.c */, + 1C420B1758416686759479BC0808D903 /* x509_vpm.c */, + 14ECEB7E2BDA7B586F03DE2D62E88580 /* x509cset.c */, + 28CB8C467C147A30A990880025432449 /* x509name.c */, + B6C53E0C38272AE6FA2E8E5C35C9046A /* x509rset.c */, + 6A85E08DFECD52E6D6CD9D01D71CEC16 /* x509spki.c */, + B58B678C9D1B0BF85162F3EE8B1619F0 /* x86-mont.linux.x86.S */, + BBF794238B05307E3AE72845744E0D06 /* x86_64-gcc.c */, + 33A32575EDCB047F39900C2B6D2BAA59 /* x86_64-mont.linux.x86_64.S */, + 1074E48131DD1AE2A57E6DB16C89FEDB /* x86_64-mont.mac.x86_64.S */, + 200DC709F6BF532949BC63AE3410B612 /* x86_64-mont5.linux.x86_64.S */, + 2A1BE9ABAC549D7D0A183959CFA54396 /* x86_64-mont5.mac.x86_64.S */, + 940CC6D29A4972AD85F8265F8E5AF468 /* x_algor.c */, + 3079F5D1DE8B050D9D823C7D18855C53 /* x_all.c */, + 7F1BA82BD02D495DD5171719767560FE /* x_attrib.c */, + 766CA41AA03E28649D02A18EE8F205E5 /* x_crl.c */, + 61B777F35BCB94CB5F2FBDAAD92939D1 /* x_exten.c */, + 318E86C627046ABDA00262E294538BE6 /* x_info.c */, + 0E41CB40FFD567899DF0C9440841F298 /* x_name.c */, + 6CC717C5651767D375F458FC34B8A566 /* x_pkey.c */, + 305C829DCF6FBC7616A2B7DA53E928C4 /* x_pubkey.c */, + 8F347992C8E1B36C3F9FA4486BF8A1EA /* x_req.c */, + 2D488D9F0EBC85B9EE41D929CABD0A2E /* x_sig.c */, + 5E7EA222E0C14D26E93668B34B40EC24 /* x_spki.c */, + A0D220C80433E4283F2163A55CA822A3 /* x_val.c */, + 699AA7624510F132CCCA43004E29AF3F /* x_x509.c */, + 52A707EE42FC57DC14D5F7A673496EFF /* x_x509a.c */, + 192F89A6E9764A181E0372C191523A73 /* Support Files */, + ); + name = CNIOBoringSSL; + path = CNIOBoringSSL; + sourceTree = ""; + }; + F9B4E2361B9BB53E0D6148CFE8392C84 /* Pods-fanex-fanexUITests */ = { + isa = PBXGroup; + children = ( + 3E879CE367BE41AC0CAF08EDB2BBE007 /* Pods-fanex-fanexUITests.modulemap */, + 6E9A9BB5C857744B10FE5E40FD860C03 /* Pods-fanex-fanexUITests-acknowledgements.markdown */, + 66B1F6A1B8718BCBF93B8CF2335563EC /* Pods-fanex-fanexUITests-acknowledgements.plist */, + 03EF348493FE6F399B33F6E4E0764E51 /* Pods-fanex-fanexUITests-dummy.m */, + 0DA9ADEDD11ED9847050BA2534A8F7F6 /* Pods-fanex-fanexUITests-frameworks.sh */, + 48A974135B072A4B43A724AF83ACD734 /* Pods-fanex-fanexUITests-Info.plist */, + 42C67CC7CB131AB7939B3A81F842DF44 /* Pods-fanex-fanexUITests-umbrella.h */, + B6FB4210C8AC0D95761859E27284052F /* Pods-fanex-fanexUITests.debug.xcconfig */, + 61B3DA25CFEB729C2DB261ACD2CCE46F /* Pods-fanex-fanexUITests.release.xcconfig */, + ); + name = "Pods-fanex-fanexUITests"; + path = "Target Support Files/Pods-fanex-fanexUITests"; + sourceTree = ""; + }; + FAC1B3789C6E72323185C535CB300E21 /* secp256k1Swift */ = { + isa = PBXGroup; + children = ( + 76AC28F9452BACDFEB2FFE9583CF3F28 /* Asymmetric.swift */, + C14CC3CB213ACC83D237A5886CA26B14 /* BytesUtil.swift */, + 1CA5BCBA60A0D0F4C9BB59488542BFB6 /* DH.swift */, + 9F03CB0E6217D65140886F475B1AA61A /* Digest.swift */, + 25583F9C089332D336990AD128E4EEE9 /* Digests.swift */, + FF5F179B7546D92B3E3DD6C93F2C0164 /* ECDH.swift */, + 193F9FE54D002CC3099E78F220DFD569 /* ECDSA.swift */, + 02E542CFBA98D0309857132E3BBABDB1 /* EdDSA.swift */, + C04815858CB98C03EA5F95A2A932CBA5 /* Errors.swift */, + 1E6BF9922345EBD760CFF08640E08E9E /* PrettyBytes.swift */, + D0742B711AB7B5FF0D93C43D48B5D760 /* RNG_boring.swift */, + 6B295C96E65F578984871707C9373DB8 /* SafeCompare.swift */, + 015510173B8F8742C76C82E9583217AB /* Schnorr.swift */, + 8D20EC911C9371E4FFA011F5DD1D64A1 /* secp256k1.swift */, + 23DDBB141AC1C1CBD70DB81078C885CF /* SecureBytes.swift */, + C2E5F8322D7FD72559B6E7011F4E4922 /* SHA256.swift */, + FE4127318ACB65C0E8D0BEE1BF74A804 /* Signature.swift */, + 51896288820E9AA5F8A6FAC96A977C74 /* Tweak.swift */, + 1109E4D9498CA2A28B97BFFC963ADD83 /* Utility.swift */, + 2333C8CE8E8B8A2E2CEE465FDE578227 /* Zeroization.swift */, + 62E7C7B7DCF1E8DB5B701574AA33F0B1 /* Support Files */, + ); + name = secp256k1Swift; + path = secp256k1Swift; + sourceTree = ""; + }; + FBA17EA439DCFE2E0055CF4667B9E53F /* CNIOAtomics */ = { + isa = PBXGroup; + children = ( + E6DB6B7AD7E5EAA5EA9B3C212BBC84D2 /* c-atomics.c */, + 0E44DA338686E612A83487C6B0C5BFEB /* c-nioatomics.c */, + C424F70C6667E36112AD91D1FF8F46DC /* CNIOAtomics.h */, + 25C0642A6B82FB59C0FFF8C9A592B792 /* cpp_magic.h */, + 9A6209F039876CDC07FAF33840AEE7DA /* Support Files */, + ); + name = CNIOAtomics; + path = CNIOAtomics; + sourceTree = ""; + }; + FCAF07A0ACB6728EF0A953CAC6442696 /* Support Files */ = { + isa = PBXGroup; + children = ( + 08323451668CE99A067392F0BB0D9036 /* SwiftNIOExtras.modulemap */, + CAA35DA1D30329F0BCD279A4029063A3 /* SwiftNIOExtras-dummy.m */, + A8865C07F40DEAC93D7F3F0AC0C36067 /* SwiftNIOExtras-Info.plist */, + E77B986346C2874BB28EAD34DE8FEF70 /* SwiftNIOExtras-prefix.pch */, + B6B28CE17861BCF5E0A2ABD21781EAB3 /* SwiftNIOExtras-umbrella.h */, + CBA473ED92C1037C118477A4972B8318 /* SwiftNIOExtras.debug.xcconfig */, + 718103D734BC6C94385D871392384612 /* SwiftNIOExtras.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/SwiftNIOExtras"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 0657D3EE8B3E28F4FF1914D8C9642B26 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 90C6B9797D5C6844B2A0EADE1E6F937B /* SwiftNIOHTTP2-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0A939273C9DB710B376AED03E58F85BE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B85A0F50B486198B6508EE519F4119D /* SwiftNIO-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0B4C0E03790A440BD928D0575BBAFA6C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AE09121C81E1F81F5671B10FAC50EAA2 /* SwiftNIOConcurrencyHelpers-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 104737A7F2F8176AF07A40A019B4DC37 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C93ABDF963DDA7C78AADD9F22CD5CB1 /* NSBezierPath+SDRoundedCorners.h in Headers */, + 7E6862A73246BB1A0E7BCEBAF50FFBE1 /* NSButton+WebCache.h in Headers */, + BD074722CD72470954ADB5B1198E01C5 /* NSData+ImageContentType.h in Headers */, + E8CE28499C17965A931605D4F47AAEBF /* NSImage+Compatibility.h in Headers */, + 38CF7D5EE6C28780FE3F9C1E63CFF3D4 /* SDAnimatedImage.h in Headers */, + 57E1C476BA5F8DD1ED740FE8DBC05D8A /* SDAnimatedImagePlayer.h in Headers */, + 4FB353F2B2E7D7AE0811D7C538DA2B36 /* SDAnimatedImageRep.h in Headers */, + F463DEB020D5C466D4613947AE4BE16F /* SDAnimatedImageView.h in Headers */, + 42822E48A1441AD8E0011D37C1625B36 /* SDAnimatedImageView+WebCache.h in Headers */, + 84B624227D73D3746CEFD48E49D74635 /* SDAssociatedObject.h in Headers */, + 18303B692A81A7D708973A6B9CBA75D8 /* SDAsyncBlockOperation.h in Headers */, + F161112B04B9AC7D276D9F588BA6E313 /* SDDeviceHelper.h in Headers */, + FE0189D2FE038AD82C4CCF5A801A50A3 /* SDDiskCache.h in Headers */, + A24B4B60656BA387B9979BD877A23983 /* SDDisplayLink.h in Headers */, + F077E74D9855D0D7FCF570F8E8ED4A1E /* SDFileAttributeHelper.h in Headers */, + A2CE92DE43AB450DE1AAA129BFBADCBE /* SDGraphicsImageRenderer.h in Headers */, + 809A09224ABB6A00BEF6B72EFAB30B4E /* SDImageAPNGCoder.h in Headers */, + 336BA7F271A33087B951BA4C6C6B2C6F /* SDImageAssetManager.h in Headers */, + 33C0E2EFD1C8046A2020D25FD1F1611F /* SDImageAWebPCoder.h in Headers */, + 0F4322740A001E3D7BFD2C333BCF907D /* SDImageCache.h in Headers */, + E7FA1E1CD066D0335A95376C73E3F8ED /* SDImageCacheConfig.h in Headers */, + 5BBE7719912593F1DEFF8E763EAD4ED6 /* SDImageCacheDefine.h in Headers */, + 909CBA577868D6E976AC82340B50343E /* SDImageCachesManager.h in Headers */, + E8D519B63C2077979F799769F9A35072 /* SDImageCachesManagerOperation.h in Headers */, + 0FFA0C960F26666918569059FB8E92BC /* SDImageCoder.h in Headers */, + 519B33DCAE0FB73CC313A2C2AD434449 /* SDImageCoderHelper.h in Headers */, + 8821E3636BB86560FC2F2D2CFF545F16 /* SDImageCodersManager.h in Headers */, + 523861A018452CE8BB166B59A7872BDA /* SDImageFrame.h in Headers */, + C7E8A80BE6BE5452380D8CA71F278B8A /* SDImageGIFCoder.h in Headers */, + 80D4A72C26C2EF865F9DCA400D2F1E70 /* SDImageGraphics.h in Headers */, + 99709E1C4991C49EE5601FF9461B2969 /* SDImageHEICCoder.h in Headers */, + 11E79385CD0DA86166E63D21E7E078E9 /* SDImageIOAnimatedCoder.h in Headers */, + 168AB5EA0EBEB75D0434B55D0B97AD47 /* SDImageIOAnimatedCoderInternal.h in Headers */, + E5C6051933677CDF392BF6356271A92E /* SDImageIOCoder.h in Headers */, + 67B3DCBA30FDEDA18E0D4E3B2C16C911 /* SDImageLoader.h in Headers */, + C4A78B8FC2DC76FBCF43D9D53BF90767 /* SDImageLoadersManager.h in Headers */, + 8C5D0B2A7B52DF68D03820244993E91B /* SDImageTransformer.h in Headers */, + 8433F353F3016EFF0316F48188D6B651 /* SDInternalMacros.h in Headers */, + C2D82385F4FDB67F6613CBBE8E2BD850 /* SDMemoryCache.h in Headers */, + E556832E0C191FCFABB9E97C87D243EF /* SDmetamacros.h in Headers */, + 9C096C865369C21D252A0F4F90BE21D9 /* SDWeakProxy.h in Headers */, + E515780850EBAD40342EBF2997BFC2D2 /* SDWebImage.h in Headers */, + 48920AFFC7C0E2FEA632DAA2BD63287D /* SDWebImage-umbrella.h in Headers */, + B128DE666CCA7CF6B0F09411D8209A92 /* SDWebImageCacheKeyFilter.h in Headers */, + DECA57AF64C5C257919649ECBB75F0B9 /* SDWebImageCacheSerializer.h in Headers */, + FED292AF8AD5924263FC0A8D0B8AF26D /* SDWebImageCompat.h in Headers */, + 7D9E8F8A5D02148FCC2DBD6319BCC3D1 /* SDWebImageDefine.h in Headers */, + 5B69919844A3BD774BAABB186D6A524F /* SDWebImageDownloader.h in Headers */, + F7289F163C285103D6CCAB39447153CA /* SDWebImageDownloaderConfig.h in Headers */, + 05D76FA82DD3C37B76FFC1689CEF9981 /* SDWebImageDownloaderDecryptor.h in Headers */, + 20004B99F5050F59E747AB8DFAD7E891 /* SDWebImageDownloaderOperation.h in Headers */, + AD0CFDA140E346502935BA58225E6EF3 /* SDWebImageDownloaderRequestModifier.h in Headers */, + 2D7E7D5F025A1006C0D373B5884B6E52 /* SDWebImageDownloaderResponseModifier.h in Headers */, + 9917CEAD8CE1CEB7FEC031255AED8FA8 /* SDWebImageError.h in Headers */, + 8F88549F032EFFEA9C281860520CC879 /* SDWebImageIndicator.h in Headers */, + 07A41F67B40B3C6C6C3DB862F1F633F8 /* SDWebImageManager.h in Headers */, + 36F35669F3AFF65477B2366FC09A1B3F /* SDWebImageOperation.h in Headers */, + 6F4B172730B7293C1D988FBE34B45E20 /* SDWebImageOptionsProcessor.h in Headers */, + 8C9D609988FE2993BB116B4B00FAC57B /* SDWebImagePrefetcher.h in Headers */, + 0311D5903A8C13AE6158796BC69AD994 /* SDWebImageTransition.h in Headers */, + B04279CC3476C6D75EDE63B360B89DEC /* SDWebImageTransitionInternal.h in Headers */, + A083AAC3481062E5DE223D480757A83B /* UIButton+WebCache.h in Headers */, + F4811CFAC05932CE436CC2C32BAD91E6 /* UIColor+SDHexString.h in Headers */, + D7BA04ADFE3104907F100E9370184A65 /* UIImage+ExtendedCacheData.h in Headers */, + 4A27F890C33243C4548A25318264B375 /* UIImage+ForceDecode.h in Headers */, + DBBAC864AD405BED53782364E0F0D5F3 /* UIImage+GIF.h in Headers */, + 26BF15D648EFA59FCA18AE285AC5B2A1 /* UIImage+MemoryCacheCost.h in Headers */, + 73F2DE8B48DC2F7C87529AB3901B9E94 /* UIImage+Metadata.h in Headers */, + 278F5B2C01E923AA0C691D79BD0F321F /* UIImage+MultiFormat.h in Headers */, + D556C63635E7A83C7A9B04FB104F7339 /* UIImage+Transform.h in Headers */, + 37E3C820BC838123661E1391BEAF8092 /* UIImageView+HighlightedWebCache.h in Headers */, + 0BFA90EFCD3407716FFC60D140325188 /* UIImageView+WebCache.h in Headers */, + D975B260AB44081399BCB612916CE675 /* UIView+WebCache.h in Headers */, + 2F85FF5597762E2E3C6961C6DD690A60 /* UIView+WebCacheOperation.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1EC222004258899747E7AB830FD40472 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 86FA8044E01AFBB6E2770623D4973B09 /* gRPC-Swiftp-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 25C44E0DEC2C2822EA04D185843913A6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E343A4361B61CEFF8C4FAB89A16A6851 /* Pods-fanex-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2EABE42D33095CF85CB6B75207A50AAD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D2B49C219707EBE35482D258A5B960A9 /* CGRPCZlib.h in Headers */, + 3C609EFC2B1EA792944BB30029F260E1 /* CGRPCZlibp-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 32DA596662685778F05D01D89B471955 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6722DCA670229327597ADC3D81BB492B /* BigInt-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C91E77CC6E7137DBCFF1079C6712DBF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 797DAD55DB988B23DA44636F61B6C43A /* SwiftNIOExtras-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CFC8E0F71337197A8B9A06FBBEAC387 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8A95BCA66D82FEFECCA5746DC9685C96 /* charmap.h in Headers */, + AF3463130EC3D84AF97EDF84BBA66DBA /* CNIOBoringSSL.h in Headers */, + E4B0992E34A04B158C11A94DAC794278 /* CNIOBoringSSL-umbrella.h in Headers */, + 5B381340C3C8973E28F7A52B552C661D /* CNIOBoringSSL_aead.h in Headers */, + BE1ADAB398269B1A67B190CFA10CF328 /* CNIOBoringSSL_aes.h in Headers */, + D2C52270976D1BF8AEEDBF3D59D15EF1 /* CNIOBoringSSL_arm_arch.h in Headers */, + 2E6FC2E96E3E66DA213A746B85E1D191 /* CNIOBoringSSL_asn1.h in Headers */, + 557F49253B5D3A0F60392265287B3CAC /* CNIOBoringSSL_asn1_mac.h in Headers */, + 6AFFF39083764ED7B6783AD4364FBC30 /* CNIOBoringSSL_asn1t.h in Headers */, + 59927BD986ECD57C54DAE6FA61A67DE4 /* CNIOBoringSSL_base.h in Headers */, + 08C84826FDC140A6A0AE9E7A3D6E61D2 /* CNIOBoringSSL_base64.h in Headers */, + F48D813DBD324DDC9B06FC203A38568D /* CNIOBoringSSL_bio.h in Headers */, + 8C83032E203400397B9E92830C845D56 /* CNIOBoringSSL_blake2.h in Headers */, + 60C03AFBB5A899CA40DBEBFE0267E1C1 /* CNIOBoringSSL_blowfish.h in Headers */, + 08F2001DC9F97027A943FB9CB3E90C5A /* CNIOBoringSSL_bn.h in Headers */, + 42029FEF26CB14EEE3360353CAB69949 /* CNIOBoringSSL_boringssl_prefix_symbols.h in Headers */, + FD034688B0EB9413321FD92EBC9D5C93 /* CNIOBoringSSL_boringssl_prefix_symbols_asm.h in Headers */, + 0D78165F93D407AEA77E1DDA94C8C59C /* CNIOBoringSSL_buf.h in Headers */, + 14F304B39D45A85652C5479204FA7675 /* CNIOBoringSSL_buffer.h in Headers */, + 5C6C7057DFCDA946716D77D0BB391973 /* CNIOBoringSSL_bytestring.h in Headers */, + 6F036122F16E5FBC921C3C593B4C3D58 /* CNIOBoringSSL_cast.h in Headers */, + BA149B567209375CB8310871618C5D50 /* CNIOBoringSSL_chacha.h in Headers */, + 24A7246A37DE34DB49544C489D45B8E2 /* CNIOBoringSSL_cipher.h in Headers */, + CC0097F80618AE7D909918D35A984ACB /* CNIOBoringSSL_cmac.h in Headers */, + 80EA4546B55DBBA6081ACFDE29EA0A5B /* CNIOBoringSSL_conf.h in Headers */, + 25FA9486E8A8B7EF48BF4ACFF210E3F2 /* CNIOBoringSSL_cpu.h in Headers */, + 73D9823E4035DA1316DDDA9B68A78A68 /* CNIOBoringSSL_crypto.h in Headers */, + 5FB06B78116762C93A87321002E2CD4B /* CNIOBoringSSL_curve25519.h in Headers */, + 3249450A5B8B712B7515FFFB15B342C2 /* CNIOBoringSSL_des.h in Headers */, + BEA309F837B5371FBD3753241079D60B /* CNIOBoringSSL_dh.h in Headers */, + D9ED50F4E709BD9139B7BB1EB987E716 /* CNIOBoringSSL_digest.h in Headers */, + FDD4676911B72FAA3507E707DDA44AB2 /* CNIOBoringSSL_dsa.h in Headers */, + A695EDFB21102F67B4C6529A87A94929 /* CNIOBoringSSL_dtls1.h in Headers */, + 12F29F012AC7EA642A061CEFAC3A1A49 /* CNIOBoringSSL_e_os2.h in Headers */, + 7584F718277C9061AC2E52CAA09FBEAA /* CNIOBoringSSL_ec.h in Headers */, + 821B52A10812A9D270BDB32088E99A7D /* CNIOBoringSSL_ec_key.h in Headers */, + 74B8B8E110BC9746E90542A42DCF5175 /* CNIOBoringSSL_ecdh.h in Headers */, + 68F1948803997D4EAB1C83133763BE08 /* CNIOBoringSSL_ecdsa.h in Headers */, + 449C1B624DEEC2565D0B8C809C0103A7 /* CNIOBoringSSL_engine.h in Headers */, + C6C448D2D192186FA58E02CFAC79FC0B /* CNIOBoringSSL_err.h in Headers */, + 0A11D1FE33D116D3EBACF8D8CE07C7FB /* CNIOBoringSSL_evp.h in Headers */, + 5F2868E310528CCFB325CCBE126FA25B /* CNIOBoringSSL_evp_errors.h in Headers */, + 441F9A62730F73CB2E2C58A5DDE1F3C8 /* CNIOBoringSSL_ex_data.h in Headers */, + 7B54990D5103BBD20358E34FBBBACDCC /* CNIOBoringSSL_hkdf.h in Headers */, + 3995CC3DF22F08AE84EA213DFE49064A /* CNIOBoringSSL_hmac.h in Headers */, + 71B96E3F1B30FBFED16852B84B89781B /* CNIOBoringSSL_hpke.h in Headers */, + 32177ED52870A5948D85E9EC66A1B73A /* CNIOBoringSSL_hrss.h in Headers */, + 4A9F7B7755F8A2EE66EAF13A15749B96 /* CNIOBoringSSL_is_boringssl.h in Headers */, + DB6F6903C0371975D73C65B8A6B31956 /* CNIOBoringSSL_lhash.h in Headers */, + DDAE076023646EC3A7717A39373C14E7 /* CNIOBoringSSL_md4.h in Headers */, + 9EB0C08316385535F0818C9101D9997B /* CNIOBoringSSL_md5.h in Headers */, + 637661C78D6216FBDEC893AFF8AC2681 /* CNIOBoringSSL_mem.h in Headers */, + 00C59A57D810B34C978A10E9AF859B59 /* CNIOBoringSSL_nid.h in Headers */, + A7EAE08B437791F211D42F68D2A4CBAC /* CNIOBoringSSL_obj.h in Headers */, + 82D33BE6D49328C2F4AEC86DEDED4F00 /* CNIOBoringSSL_obj_mac.h in Headers */, + 41F053EEF2AF2A9D9175FD2213C2E62B /* CNIOBoringSSL_objects.h in Headers */, + 6076364F0EB6528E1A89701575CAD8ED /* CNIOBoringSSL_opensslconf.h in Headers */, + 7FF5BA014629589DBC1DBC5C34BE8E6E /* CNIOBoringSSL_opensslv.h in Headers */, + F20DD14AD88DFD6E88AF21664360D3E0 /* CNIOBoringSSL_ossl_typ.h in Headers */, + 4E6BDAC26F53B9D533928A1C4AB0C2C5 /* CNIOBoringSSL_pem.h in Headers */, + 8CD580B0B5647801B16A259E0A7AD6EC /* CNIOBoringSSL_pkcs12.h in Headers */, + A9107234AE0F0D455E32C3B534266B85 /* CNIOBoringSSL_pkcs7.h in Headers */, + D61B2EFCA57203938C38DBD96538415B /* CNIOBoringSSL_pkcs8.h in Headers */, + 2B7C943E62B9E04DB1053FA1408B6F51 /* CNIOBoringSSL_poly1305.h in Headers */, + 55A7E844E2375D632EC293FFD4026998 /* CNIOBoringSSL_pool.h in Headers */, + C65E405C8A8CA760FD31087C7B53A41C /* CNIOBoringSSL_rand.h in Headers */, + B3A0A5ECD1000BE87C76B29BD5461E28 /* CNIOBoringSSL_rc4.h in Headers */, + BC8B0C073D8858F51464F9253173FD49 /* CNIOBoringSSL_ripemd.h in Headers */, + 522F14B172BBFF77FE8C11781E046839 /* CNIOBoringSSL_rsa.h in Headers */, + 27E961A836DAAD6BF73D755C4F5C6AA9 /* CNIOBoringSSL_safestack.h in Headers */, + 7CF4FBBC3E9D8CD785EEAC13274CD66A /* CNIOBoringSSL_sha.h in Headers */, + 69E87248F1AD8B478E3DC2C7EE62B715 /* CNIOBoringSSL_siphash.h in Headers */, + 903F3D85C4E26C6C3810EF8465B800EE /* CNIOBoringSSL_span.h in Headers */, + 6FF4C47BC28EA09CF1EE35124D42C890 /* CNIOBoringSSL_srtp.h in Headers */, + 66D24476F40B0EE147E89D6A6A878A18 /* CNIOBoringSSL_ssl.h in Headers */, + 67448894860AED1A1CF02861676FB103 /* CNIOBoringSSL_ssl3.h in Headers */, + 9BACDF144D3D89AB3A9FB4A4B7E47410 /* CNIOBoringSSL_stack.h in Headers */, + 43076FC6D9C62A893FBADB9A1160923F /* CNIOBoringSSL_thread.h in Headers */, + C3C84ECFBFF2546938B4149639598DCF /* CNIOBoringSSL_tls1.h in Headers */, + 2B0D6D3F5CC10D03FE038F6BD58A71E7 /* CNIOBoringSSL_trust_token.h in Headers */, + 0C51A757DDC20B436F410BFF1263CAD6 /* CNIOBoringSSL_type_check.h in Headers */, + 991FEE429484419A2B1CE17341C32C87 /* CNIOBoringSSL_x509.h in Headers */, + 4645A03CFB6DDC053B5886AE7FA1D750 /* CNIOBoringSSL_x509_vfy.h in Headers */, + ED5CB63C5B433E39D4638E7F69BBECE7 /* CNIOBoringSSL_x509v3.h in Headers */, + B97B1A6B52C898386522F3A2E255B792 /* conf_def.h in Headers */, + C30CB0C72BC6AAFC60C7F55706353F24 /* cpu_arm_linux.h in Headers */, + 1B1FA30DC4EDFAC16D3B7685D30D90BD /* curve25519_32.h in Headers */, + 3383D1489A786E3DF95F56AC27F6D805 /* curve25519_64.h in Headers */, + 49784491DF6681E08E3AEE84E98A3C42 /* curve25519_tables.h in Headers */, + BA1D0752A4EFE5057AA96B56B34D5063 /* delocate.h in Headers */, + 51F4E301047801A09A37B8A049F66427 /* ext_dat.h in Headers */, + 9D041316DA723CA8912BC9DA2530C257 /* fork_detect.h in Headers */, + D068C248672F2F8C73B19F82AE28A146 /* getrandom_fillin.h in Headers */, + 0EFCF636B9B5A32F7267C1A7030C694F /* internal.h in Headers */, + AA66D62E105BBC2AA92FF7D188F468DF /* internal.h in Headers */, + 6C3F1FCABE4B67F89FA6816BBF706326 /* internal.h in Headers */, + E7A8DC86F7559373DBC9CBCEDC38CBD5 /* internal.h in Headers */, + B287B47DACB981153E561026E38103FC /* internal.h in Headers */, + 1BCD91BE33AFBF6AD203C19B62B1A96F /* internal.h in Headers */, + FF2852BDC874384F2E64A65E277D44F4 /* internal.h in Headers */, + D26D909937F2AB2279973335583C0718 /* internal.h in Headers */, + 27A24F80CF96015C16322EF7F645455B /* internal.h in Headers */, + 0C070928EEECA1314011AEEE3C11F813 /* internal.h in Headers */, + 29B3FF0CF6EA57C77BF5A5A719D3BFCB /* internal.h in Headers */, + FD7710A5A649E95199C4D357E3B37070 /* internal.h in Headers */, + D4882F6EA281285B41A8397CAECA14C3 /* internal.h in Headers */, + D01241AE09316D6EC4E98F684F515169 /* internal.h in Headers */, + 5254EA375DC1CA76FE44095887749177 /* internal.h in Headers */, + 5C9A67CF785AC29AF1D3DD1D83C48462 /* internal.h in Headers */, + A6624C7C8092B9B4BB0FE7B551279C8B /* internal.h in Headers */, + 4D8E40DA9C634BF4711D776563937111 /* internal.h in Headers */, + 334B3DC37D7F45A1B3AB0B120ADD8C90 /* internal.h in Headers */, + B7569E77F21DB44F3FB454A1838580E2 /* internal.h in Headers */, + 8690C6953643F2B0B3E34ED2E78B283E /* internal.h in Headers */, + 492185AB514512EF8E6A30B311641523 /* internal.h in Headers */, + 7DEA03372CDB3CEDC57066D6EF00A463 /* internal.h in Headers */, + E8D2CE0F5988394E8B16DF4E2802339F /* internal.h in Headers */, + A075C0125E388D7C795E166A3A069EF6 /* internal.h in Headers */, + DA668BADDD228A5D2764B41BF820A3D0 /* internal.h in Headers */, + 2414DBF6E5DAB682E13615C4F4EBBA08 /* internal.h in Headers */, + 26944BFD4B8B8F631C0037619FC289F2 /* internal.h in Headers */, + 7678DCEDA9BBF65DC15D9E666E87608F /* internal.h in Headers */, + 4968417FBF31E5D093DA26F044D4744B /* internal.h in Headers */, + C0E2645172F1D32948A46B6336B1D6CE /* internal.h in Headers */, + 78E455067CFA419CEDEBAF632DDFB41D /* internal.h in Headers */, + 128F1E85FFEF8B9C512A70C4723F4EF6 /* internal.h in Headers */, + EC0D35F2428314AFAE49DB8177C8AC1C /* internal.h in Headers */, + 9FFFED044A7A91DD9B4BBAC0FB8EEC76 /* internal.h in Headers */, + 59C1D83E821E6E9A977038D530FAAFBD /* internal.h in Headers */, + 9217F5236FE1F764DA37607E4F58A4D8 /* md32_common.h in Headers */, + 9DA75302CE8D7699963D0B4DEAA0097B /* obj_dat.h in Headers */, + 06C85607640345D6A2C1CD13C2D514E1 /* p256-nistz.h in Headers */, + 81D455617E941A643E61BED3FE1E1EDB /* p256-nistz-table.h in Headers */, + 4828389ED5801DF33D36DDAF0D60AB19 /* p256_32.h in Headers */, + 8A4FEFA934312DD959EFF528213E2038 /* p256_64.h in Headers */, + 9F8F9A5E33E0EE4F74F7F440FAAB173E /* p256_table.h in Headers */, + 2B453504C4F5C3239BDF25866828B590 /* rsaz_exp.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5304391AFFCDEADB21125EF200891209 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D73A7A52CAC162A201751447F3E822C /* Pods-fanexTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 548121DC45083FA8CE8348896AB8505F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B50064B1842CB43A87F7BB049EDCA78B /* SwiftNIOFoundationCompat-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 54AC2112AE609980B728B098CF1A59F2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D727998958FC27FA7696ADF1D974B6D0 /* SwiftNIOTLS-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 567FF1B1737DFC4A3D5479AF64E8CE95 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 05399C35827DEE4DD35A9DD254645202 /* PopupDialog-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 57BD09A4FAE5E08FBE2413C484057E3E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + CB6CA55E19F6E08B7CC05B1CD9F08AA7 /* MercariQRScanner-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 647F4A5B55939130044C57EA69BBCBE0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A29BBC943E38ED7E2041A1910C9C46B /* SwiftNIOEmbedded-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6579E4D44EE47874D1B721366CAF2E88 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 69537FE1409498730C7BDEE75AC9CE28 /* Pods-fanex-fanexUITests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6B5CA505D540DE77F08E0BCD22C6C298 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 36E821F5D3A12F0C6041663DCF2673D5 /* DynamicBlurView.h in Headers */, + 712A08906486C430CA5E724471995301 /* DynamicBlurView-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6DE9E7B34EB24769860A549107B4F04C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E70EBA16751054574A227A6432CCE4B0 /* SVIndefiniteAnimatedView.h in Headers */, + F77280E74EB91678AA294E66DD6070E2 /* SVProgressAnimatedView.h in Headers */, + C15B3F89E6F83DC9CCB14903FC5D80C5 /* SVProgressHUD.h in Headers */, + 4DC032894868226AE220360BADB2C237 /* SVProgressHUD-umbrella.h in Headers */, + 6D1E33469FB8FBE812956B0076A7B28F /* SVRadialGradientLayer.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7184D5C3E0722A0393279BA159CCEB30 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + BF8B28D4A5F95D42B8BD313EFCEBE949 /* Logging-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 726B821BBA2AFC8A5304843B3AB656EA /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4618F63D9BC63C5DAE31EF33DFE988DD /* SwiftNIOSSL-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 76E8D8FA76F15A833B540AC7ED5268F5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 876E1E985D645D400B413F4EF4C071A7 /* CNIOLinux.h in Headers */, + B74FE5CCBF1C5720ABEF276A73A1676D /* CNIOLinux-umbrella.h in Headers */, + 6A950124DFAB3658C9C496596D95C4DD /* liburing_nio.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7A6C55F401C6AA83EED669315A759971 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 31F38550A862FED98573915EDE3C9BFB /* SwiftNIOTransportServices-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7AF1E32BBB6D2774C2053D5744D7E26C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F64FF06ED0A31B75355386672A568CC5 /* SwiftNIOPosix-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8CFCD9F45393EB65D64639C8416EEE02 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C7743E4568465EC45D0C91259D639200 /* SwiftyJSON-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D12D2F5065986586EEE62B0B109F73B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D55CC779DD6D3FD8B1420C7D650F2F4 /* c_nio_http_parser.h in Headers */, + 0D60294A7BB35B73E960580B064D3CA9 /* CNIOHTTPParser.h in Headers */, + 87494EA46B7AC2E2D07BBE20C8FBB0B8 /* CNIOHTTPParser-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F3531B92B347FB9AD7320D181575EF9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3ACC20EC1AC96897FA23F83EE511B57B /* FlowSDK-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 914BD6E00B0507939BEC76343A95E1E1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7ECA836470E0DE7C5C60FBF251F6BE30 /* SwiftNIOHTTP1-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 93D18E60087C4E8C7AC2236546CFB0E5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EDF63361BC1F79E71FB598AC9971148C /* SwiftNIOCore-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A8D5F226095625BBB44A067762403DBE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F14BC3459CEAED3AD9737F5162FF4689 /* CryptoSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A8E5F25334979EDD882BC874088C1058 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D563294D5FDD5F0788E409D6C9EEE296 /* Cadence-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4CCCF2B236B02DF6E6CF29A9427350A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E0885BDF48915F32BE60CE8CE80C4CFC /* SwiftNIOHPACK-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF51A05B417C8596A4572063D7877BB7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A99C203EF8D0D2120DCC6FF459EF820 /* CNIODarwin.h in Headers */, + A8FB47C71F7057936055737189584B39 /* CNIODarwin-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C3454DAC762B6D9DE0375C878617E5CD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9CDEA353E845FE3EBA3889F6DC0251AF /* FCL-SDK-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DDEF6D661DE2192A55B4BD8278A1459F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6FBD3CC7CC1566D7EEE33A1A513AEDE0 /* CNIOBoringSSLShims.h in Headers */, + 6A479035AD915D35AF67A5E168F8A98C /* CNIOBoringSSLShims-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DF5B42B151D824997DF999E972EEA21C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DBAA133B55305E85224A1B3CFD5D6D0D /* _NIODataStructures-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2CF88F6B7447599892B3729279BD620 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AAC07F3FA5AF37257CA114ED88ADFFF3 /* SwiftProtobuf-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7DAD0F842380BB51C10F7D12CD58694 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + BCB2A79CBE1B95E0F7E225A15603B608 /* assumptions.h in Headers */, + 8D935610884B8CE93FA6D1540411BCB9 /* basic-config.h in Headers */, + 148E30B721817B243804E273ECD62757 /* bench.h in Headers */, + 9D0FF4962DEFF82F2E48F48CB2A7FE9B /* ecdsa.h in Headers */, + 766844130D16F11F565407F8F40EEA25 /* ecdsa_impl.h in Headers */, + BC128C004F898A480D5BD3D3A06D71D7 /* eckey.h in Headers */, + DF153650063F4CD806469DFC8B9047AE /* eckey_impl.h in Headers */, + 495D1E4BC683C5D93F1837C5D2CB66E5 /* ecmult.h in Headers */, + 26821B9A27A4405B95DDD64E73056F6F /* ecmult_compute_table.h in Headers */, + 231991D416A8C399788EDE74D7D6E153 /* ecmult_compute_table_impl.h in Headers */, + EF02CAD1A27CDB6A369CF41D120EBE9C /* ecmult_const.h in Headers */, + 591C624074BF9F241A5F1B5D9A562865 /* ecmult_const_impl.h in Headers */, + F25AE87DFABA108A482A099407418A3D /* ecmult_gen.h in Headers */, + 72DBF2E878F4DDD2283BEA3C1D87CFA3 /* ecmult_gen_compute_table.h in Headers */, + 51869257D458739CE3A3D020FCDC6C58 /* ecmult_gen_compute_table_impl.h in Headers */, + AB4CA0AFA9EC77EC975EA03C914DD0F5 /* ecmult_gen_impl.h in Headers */, + 4D39754498EB7DD1C3CAFEE31A9D918B /* ecmult_impl.h in Headers */, + E6E77C21BEB0D12F83C95039A71A4401 /* field.h in Headers */, + 135FDA9E9BE1E6052092179EDBACCA91 /* field_10x26.h in Headers */, + F33B49D79748B138362B4FB84408FC1A /* field_10x26_impl.h in Headers */, + DFDB176EA2652EBC56E5F74ACB88047B /* field_5x52.h in Headers */, + A3C8B16A87DA9D76BF77BCEB0AB498ED /* field_5x52_asm_impl.h in Headers */, + FFCE149A55EA0CB0909049C3AF92A082 /* field_5x52_impl.h in Headers */, + 875B44B5225C468C1798E3E323AE42C7 /* field_5x52_int128_impl.h in Headers */, + 0394719E7095CB053C04F4B407452073 /* field_impl.h in Headers */, + 468B2977ECE39B9FA89CD0C9F8BF945B /* group.h in Headers */, + F2A471453076AD07758F14B12BA5373E /* group_impl.h in Headers */, + BFE809D08A0710648C7A6BD6E1D492FB /* hash.h in Headers */, + 7EFA051C29E0B78307713526C58E9758 /* hash_impl.h in Headers */, + 1777459577F63D908A836EF87F81B5FC /* main_impl.h in Headers */, + 5B47C9724578CB56CC6F1674AC585807 /* main_impl2.h in Headers */, + C27C43D1F2D365DE70BAFCB41FECB107 /* main_impl3.h in Headers */, + 3110384B69E79E8FBAF8427D5F3392C0 /* main_impl4.h in Headers */, + A28B0C7CAB1DB0E4430B488575D2EB0B /* modinv32.h in Headers */, + 82A8B0C2ABF0AA8E658B222DAA4D3B2F /* modinv32_impl.h in Headers */, + 6EB2C4B594B05A3A764B23442E4B5E09 /* modinv64.h in Headers */, + 1D31F4126492EC4A1F6309A5F3BE07EA /* modinv64_impl.h in Headers */, + 9046ACF4E9A631179B2F7ACD5457AC60 /* precomputed_ecmult.h in Headers */, + 74249B06A875FEC41D2307774ECF3915 /* precomputed_ecmult_gen.h in Headers */, + 44BA1B9824BE5B3DDCA771F5BEB2FFEB /* scalar.h in Headers */, + 91503E1A26EB13111FC795578B02BF22 /* scalar_4x64.h in Headers */, + 85FD951409D33B630016856A83757325 /* scalar_4x64_impl.h in Headers */, + A7422ED90013F6BC9FAA34AE7838C04C /* scalar_8x32.h in Headers */, + 5C02F2E4DEB3835B3E55301FA83178C9 /* scalar_8x32_impl.h in Headers */, + 40224FA586F705009FE476F24D0B9EE5 /* scalar_impl.h in Headers */, + 15C778B2B8D8A223E3D3F37A70852494 /* scalar_low.h in Headers */, + CAEC75A8C619CF4229CF00D8ECC8E04E /* scalar_low_impl.h in Headers */, + B531065FFCCBB26DC592750AD36072CC /* scratch.h in Headers */, + 9172F06D07C6AD5856C0928547998FF1 /* scratch_impl.h in Headers */, + 1EA0EFAFC0CA82353E71A262DCD55CAD /* secp256k1.h in Headers */, + 84ABBD503E6029819C724166A1DD5132 /* secp256k1_ecdh.h in Headers */, + CD59912FBB10DB79E8252E0523019E0C /* secp256k1_extrakeys.h in Headers */, + 4162FD4DC81264250152C090A05E5C70 /* secp256k1_preallocated.h in Headers */, + CB55A2875AFA9C9BD41B19F1A4130B7C /* secp256k1_recovery.h in Headers */, + 45A4A1908ED5AD2720326A3C4E1B9E04 /* secp256k1_schnorrsig.h in Headers */, + D181DB77994B119DA8E201BC4BE275FF /* secp256k1Wrapper-umbrella.h in Headers */, + DFB452F78F1FA4D3B38152EAD3D49D2A /* selftest.h in Headers */, + 7BE557A1E55B8AD33467E54D28DC6932 /* testrand.h in Headers */, + 6FD394C7F605CB68DAC815DFFB65552F /* testrand_impl.h in Headers */, + A42FB500D8E7E9706590E6ECF80A3F2F /* util.h in Headers */, + 6FC650859642FECFE05B108117CD5E04 /* utility.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EA7B249205F62439D7245B12B8BF8257 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8781DFC727A787C8AC36CDD6559155B1 /* secp256k1Swift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EED349C326E8FA19559595BEDFF304DC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B364FF25C5306DFADA83D2D76AC09FC /* CNIOAtomics.h in Headers */, + D64CEC1A63908BD756A80F3D92578230 /* CNIOAtomics-umbrella.h in Headers */, + D692521557700730B1EE4ABD2EBBDC16 /* cpp_magic.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F9B00D5396183BF7247CC4B6B332A8E9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D5239ADD0689C3ADA13B2BD820BF7BAC /* BloctoSDK-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FD6E0C12247BE00D83910344CC107B0A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 08A18E6BD351CD781F9B2ADF46D06489 /* CNIOWindows.h in Headers */, + 3634E84D125C95C379D76A2B1ECFB625 /* CNIOWindows-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 09DD83B7D075842A3A5105AD410BD38A /* BigInt */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C696C8CA41BB855C8D3F30C1B2DEF51 /* Build configuration list for PBXNativeTarget "BigInt" */; + buildPhases = ( + 32DA596662685778F05D01D89B471955 /* Headers */, + 3B4BFA6C78E7E27765466DEF2EBB6DA9 /* Sources */, + 11379356021538EC61B49D0E27E3FEE9 /* Frameworks */, + C776F6A64A073BE88CD07D9069E3346C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BigInt; + productName = BigInt; + productReference = 91BB24BA472AF523E913108C9AA301F2 /* BigInt */; + productType = "com.apple.product-type.framework"; + }; + 17112F66EE5BDC5584A51CF4FCE7631A /* SwiftNIOHTTP2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1FC39448079F9761DB0444346A203FE5 /* Build configuration list for PBXNativeTarget "SwiftNIOHTTP2" */; + buildPhases = ( + 0657D3EE8B3E28F4FF1914D8C9642B26 /* Headers */, + 151155F162A28F148E23675E0ECAC893 /* Sources */, + EE86003DCE4F23984637FC53FD4FE685 /* Frameworks */, + 6DA3BD93360B186FED278BB17BC74EE7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3F6EB28B7F01BED3D7BE0A2DBEA97518 /* PBXTargetDependency */, + AC14E65EBC84BFE96CAF318D7F6D7140 /* PBXTargetDependency */, + F51CC1A9E946409D9F5AA893ADB55856 /* PBXTargetDependency */, + DC3CC555A97861B90EEECA1FA9C141F2 /* PBXTargetDependency */, + 7A567600474F7FEC4911AB0703628753 /* PBXTargetDependency */, + 4A073398C91DE14D95AB5073ECDD9164 /* PBXTargetDependency */, + 3508159F99D633C18438C8D07C579330 /* PBXTargetDependency */, + 73313742ED6C81DB6A3109D783504DAE /* PBXTargetDependency */, + 4FD2218FD88C7E56F38AF69E73231F36 /* PBXTargetDependency */, + 8114A10AE43DA12050137E641FCC6798 /* PBXTargetDependency */, + 466B36C87C2A5E03EFAC7C60FCE0D0EA /* PBXTargetDependency */, + AAD487CB22BBC1DE6909F1D8B7CE3B29 /* PBXTargetDependency */, + A64CE1926FADFA96D134425A09E605B6 /* PBXTargetDependency */, + B7A1C7E647CB051B858C49EED5CE7D9C /* PBXTargetDependency */, + ); + name = SwiftNIOHTTP2; + productName = NIOHTTP2; + productReference = 2A4CC298CC8CF90A2A7FAFA7D74BD1CF /* SwiftNIOHTTP2 */; + productType = "com.apple.product-type.framework"; + }; + 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */ = { + isa = PBXNativeTarget; + buildConfigurationList = 807FEF9D9629A72728B6B83F5CA12C85 /* Build configuration list for PBXNativeTarget "SVProgressHUD" */; + buildPhases = ( + 6DE9E7B34EB24769860A549107B4F04C /* Headers */, + 108B36464ADE4902E2E2C83461767402 /* Sources */, + E389FF082B036E756B0679583C1BE62E /* Frameworks */, + A4CCC3CC21F770E272C54B18DDDE6DA3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SVProgressHUD; + productName = SVProgressHUD; + productReference = E97D43C46A45EE515A4DA3AF94398441 /* SVProgressHUD */; + productType = "com.apple.product-type.framework"; + }; + 2ABF3F8EC6CE525E1E02C51D72C64E94 /* Logging */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8FE90004A4B3612A71B8C66E991D6603 /* Build configuration list for PBXNativeTarget "Logging" */; + buildPhases = ( + 7184D5C3E0722A0393279BA159CCEB30 /* Headers */, + 15B97154D9AA488D4AEE934158A07C36 /* Sources */, + 85AB6077A53F66F59AC1A7700E37DF8B /* Frameworks */, + 1215F98F9CA34918D373E396EB049C19 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Logging; + productName = Logging; + productReference = A6513E0A6CB60623515716E73996F0F5 /* Logging */; + productType = "com.apple.product-type.framework"; + }; + 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */ = { + isa = PBXNativeTarget; + buildConfigurationList = A8923C9E1170C9B5C2F047CF927406C1 /* Build configuration list for PBXNativeTarget "CNIOLinux" */; + buildPhases = ( + 76E8D8FA76F15A833B540AC7ED5268F5 /* Headers */, + 4C69BAFCE046797C7D34FC1320D044B6 /* Sources */, + 3BAB6E77DD1FBC909964C39643F21244 /* Frameworks */, + 0338E9DD361AAB2CBBABFB2A5B172C90 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIOLinux; + productName = CNIOLinux; + productReference = 6F1C5C1A1C8F9473CEF780C63705F78A /* CNIOLinux */; + productType = "com.apple.product-type.framework"; + }; + 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */ = { + isa = PBXNativeTarget; + buildConfigurationList = BABD4A24CFCBE5B6FE4680AA062FCF04 /* Build configuration list for PBXNativeTarget "SDWebImage" */; + buildPhases = ( + 104737A7F2F8176AF07A40A019B4DC37 /* Headers */, + 4B6FB7A17469A2800E7231A1444746CB /* Sources */, + FB6A1E8A43CF1D3ADFB49BA355F0DEA1 /* Frameworks */, + DC20DB2B5A8B3C34EAC16992C6449775 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SDWebImage; + productName = SDWebImage; + productReference = B0B214D775196BA7CA8E17E53048A493 /* SDWebImage */; + productType = "com.apple.product-type.framework"; + }; + 446DA03EDE44E6615A2A146E3D90AA3D /* FlowSDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1452BA34CFC4CA921B1198A423E64C25 /* Build configuration list for PBXNativeTarget "FlowSDK" */; + buildPhases = ( + 8F3531B92B347FB9AD7320D181575EF9 /* Headers */, + 1CF8E521FBDE56FECE372CE0BBD8774C /* Sources */, + 824EA4E007FC2D3DB34A248D1C3C2BB1 /* Frameworks */, + 367BEF65DEAFC0F28EEC92148C61CEE3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B8D262E43E5DDF596527B2711F0AD27E /* PBXTargetDependency */, + 1CAA8EB937A8612FA23212C62C91CBBD /* PBXTargetDependency */, + F072DF03B9C6FAE58435F079917AE029 /* PBXTargetDependency */, + 61A94C70864366E841DA3DDFC7588C5C /* PBXTargetDependency */, + 046FDBE7F90B7109E462B91DED822C01 /* PBXTargetDependency */, + ); + name = FlowSDK; + productName = FlowSDK; + productReference = FA0FF3EF9504A14378958B379D648B19 /* FlowSDK */; + productType = "com.apple.product-type.framework"; + }; + 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */ = { + isa = PBXNativeTarget; + buildConfigurationList = 807DFD17F79151217EC31070EA5AFB1E /* Build configuration list for PBXNativeTarget "CNIOWindows" */; + buildPhases = ( + FD6E0C12247BE00D83910344CC107B0A /* Headers */, + B5E8E62813ACBE0DFD725BAA9A851314 /* Sources */, + 6B0B3CF7F2918518C073EBF75E188E1B /* Frameworks */, + 33CC6F8230BD0C52CB7C2B47107AFB7B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIOWindows; + productName = CNIOWindows; + productReference = 4A1D16EDB0405CEE4C837F184DC39013 /* CNIOWindows */; + productType = "com.apple.product-type.framework"; + }; + 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */ = { + isa = PBXNativeTarget; + buildConfigurationList = 37472EAC69133C913656A0F98C117288 /* Build configuration list for PBXNativeTarget "SwiftNIOEmbedded" */; + buildPhases = ( + 647F4A5B55939130044C57EA69BBCBE0 /* Headers */, + 259B59946D781041F752DF4B5FAA61FF /* Sources */, + F9DF974592A7823164CD2C4206C3882F /* Frameworks */, + CFFED6A91FA4B92FB6187DDE0164E82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A3AF27998DCDA1FDF3673B1B30703DF3 /* PBXTargetDependency */, + 8D65FEFB21149E75A7B947B214879160 /* PBXTargetDependency */, + CEB64638BD0F5DAE1345E99A97989CEA /* PBXTargetDependency */, + 98CE072D38EEECC3FA49A812685F1185 /* PBXTargetDependency */, + F04DBF9C4953529CC89A70892EF8C540 /* PBXTargetDependency */, + ); + name = SwiftNIOEmbedded; + productName = NIOEmbedded; + productReference = E83089C79437628622D534CAA83363B4 /* SwiftNIOEmbedded */; + productType = "com.apple.product-type.framework"; + }; + 54382245E5C9DB4A3CFB906FD97A35BB /* CGRPCZlibp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 31E25A7DA65A994902661DBC87F4480F /* Build configuration list for PBXNativeTarget "CGRPCZlibp" */; + buildPhases = ( + 2EABE42D33095CF85CB6B75207A50AAD /* Headers */, + 81051028DE7225687C9FFF763AD47D0C /* Sources */, + 2BDE80FC9CC2D9C431FA8D6072EA251B /* Frameworks */, + E3E8460D533945543EDDC478E4D27172 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CGRPCZlibp; + productName = CGRPCZlib; + productReference = 02645BB34CFF0DE639E95842490D9F30 /* CGRPCZlibp */; + productType = "com.apple.product-type.framework"; + }; + 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */ = { + isa = PBXNativeTarget; + buildConfigurationList = 407CE045BD56FAE98E8079A18EF820D0 /* Build configuration list for PBXNativeTarget "CNIODarwin" */; + buildPhases = ( + BF51A05B417C8596A4572063D7877BB7 /* Headers */, + 35848B0FBDD5C461811D1FC7B126BA24 /* Sources */, + 43844D13DA6F3C2ED9E726566123C95E /* Frameworks */, + D9A6F2D0672BA3144D598D16F1D0E163 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIODarwin; + productName = CNIODarwin; + productReference = 4CECE1D3F082EE1C5AF7E5E93BAEDF74 /* CNIODarwin */; + productType = "com.apple.product-type.framework"; + }; + 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */ = { + isa = PBXNativeTarget; + buildConfigurationList = CCF70CA0E20CF6114DFD888616FF765F /* Build configuration list for PBXNativeTarget "SwiftNIOHTTP1" */; + buildPhases = ( + 914BD6E00B0507939BEC76343A95E1E1 /* Headers */, + 45A0E663EC6B027315DD54C45AFF0A59 /* Sources */, + C46E597B7C52B4A38582CB8B9E6187DB /* Frameworks */, + BA03F669FEDCACCE81DCC230B2B1B410 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 6FD8E056E8FD62A4293B191B1B851639 /* PBXTargetDependency */, + 47D79CB3533EAED27ED9830DDFB7D2C5 /* PBXTargetDependency */, + 8A0DED7E83D4EA888429A21E188C08BC /* PBXTargetDependency */, + DE6FD95BBC491CD5510B7C4461D9BE8F /* PBXTargetDependency */, + C8B462F7CB458FF2E33BBFC5F43E7A7F /* PBXTargetDependency */, + 92A9D0154923980F26EF819867844A6C /* PBXTargetDependency */, + 585319BDE94DE971B3AA54C7472891E4 /* PBXTargetDependency */, + A72856C329D82FA33CD7177666E3494C /* PBXTargetDependency */, + 991DF2BF2B57BA9400358F380D7A75B8 /* PBXTargetDependency */, + 546A27887AE6ADC9F74D29F811C93B1F /* PBXTargetDependency */, + C91AF97FCD234CD79E5554F0860DB61F /* PBXTargetDependency */, + ); + name = SwiftNIOHTTP1; + productName = NIOHTTP1; + productReference = 134C82C2AF26C1F6D1FA6484A52A0FF4 /* SwiftNIOHTTP1 */; + productType = "com.apple.product-type.framework"; + }; + 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */ = { + isa = PBXNativeTarget; + buildConfigurationList = A7E7E1351DE9BC036A87A76C3C1F0F70 /* Build configuration list for PBXNativeTarget "CNIOHTTPParser" */; + buildPhases = ( + 8D12D2F5065986586EEE62B0B109F73B /* Headers */, + C32A6C523F3D6A954321B65A0C2F674D /* Sources */, + B37AFD44EC7D46A5FBCB40FBAE3363CF /* Frameworks */, + B760DFD74FB77DF3673692A3E0DD16B4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIOHTTPParser; + productName = CNIOHTTPParser; + productReference = E8457AC368411E1953DDF7BE182DA599 /* CNIOHTTPParser */; + productType = "com.apple.product-type.framework"; + }; + 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5126FD23D53D384B5F17BAFE760FB0F3 /* Build configuration list for PBXNativeTarget "_NIODataStructures" */; + buildPhases = ( + DF5B42B151D824997DF999E972EEA21C /* Headers */, + 91F1CC240271391A20B61758DE5851A4 /* Sources */, + 0F86543F55314FBBF35C1594CC0A8E84 /* Frameworks */, + 52FAFDA542AF2211AB2D8C7A5B3103CA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = _NIODataStructures; + productName = _NIODataStructures; + productReference = 8436BC15451DA6766C259541522EB812 /* _NIODataStructures */; + productType = "com.apple.product-type.framework"; + }; + 5A8A5B4451A77B0A6D36B131E2974E23 /* BloctoSDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32280DB872FAE69E008C7718ABB4F4C1 /* Build configuration list for PBXNativeTarget "BloctoSDK" */; + buildPhases = ( + F9B00D5396183BF7247CC4B6B332A8E9 /* Headers */, + 41DAF87DCCD998148F6C97B967DC3379 /* Sources */, + 215C40FEC0DC42A170CEB2E87F7A25F3 /* Frameworks */, + 070AF9FEDFD26E4F06F0D64B0E7BA11F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 860E7990858BFDA09A6451DA04AA5AA8 /* PBXTargetDependency */, + ); + name = BloctoSDK; + productName = BloctoSDK; + productReference = 18078BAA5B8CD8C4BCE1F204781688A7 /* BloctoSDK */; + productType = "com.apple.product-type.framework"; + }; + 5D6DC8585F20CBE789F7D3D4F645980E /* SwiftNIOTransportServices */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4CADF0DFAF02C257E2E00F97AA90E5BB /* Build configuration list for PBXNativeTarget "SwiftNIOTransportServices" */; + buildPhases = ( + 7A6C55F401C6AA83EED669315A759971 /* Headers */, + F500A4FE439CDEF4CF437B62E56ECD87 /* Sources */, + 835A33FE7E2A55D3B766195C72E8C42D /* Frameworks */, + 307D90E0345C74D96191AFCB4A3D1895 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 10E6BD943581D6734145D8EDAE2FA3CB /* PBXTargetDependency */, + D8A72CC27F5E46E79FFFD086FB50A7AD /* PBXTargetDependency */, + B5F7FE8285AB2D9E614ECA0F7F98B20C /* PBXTargetDependency */, + 61A8F93412921E5C3409F73385C623F8 /* PBXTargetDependency */, + FCFE71F9C51285C2ACCCA9CE64F3E999 /* PBXTargetDependency */, + 28A6EAED54DDB1B79A96C90C2A4FBC06 /* PBXTargetDependency */, + 8025DBD1B95AD96E533CEB706EEDB94D /* PBXTargetDependency */, + 2E34FE252928549C71FE69756456A800 /* PBXTargetDependency */, + 5318487F4F34AA2330A8094D11DB8D4A /* PBXTargetDependency */, + DDD8B9FC2A7277A8409375191688E7F4 /* PBXTargetDependency */, + C9111B4CB0F67417A59CB70499D6D27A /* PBXTargetDependency */, + 2DDB5D0FF22B16370AB44E310D509B29 /* PBXTargetDependency */, + ); + name = SwiftNIOTransportServices; + productName = NIOTransportServices; + productReference = 42E23A3C1C5D8CE37484B124E180BAA0 /* SwiftNIOTransportServices */; + productType = "com.apple.product-type.framework"; + }; + 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1C7184C9DC5F57266D25F1FB10ADF8C /* Build configuration list for PBXNativeTarget "SwiftNIO" */; + buildPhases = ( + 0A939273C9DB710B376AED03E58F85BE /* Headers */, + 5606D26B127296E9294E5C79B674B1BC /* Sources */, + 0946B4E873FB949D224E88B60E4FF80F /* Frameworks */, + 83A366519E8D30332C528C6E6A79B94A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + AFCA0B3EB08F8ABFA79215034D047B20 /* PBXTargetDependency */, + 08DFBAB7A2D1F8291FDC3EDC582621F4 /* PBXTargetDependency */, + 06B9823BAC46C9307028CF42C5D94FD3 /* PBXTargetDependency */, + 182165BFC33EAED7BFFB1393A3D91A32 /* PBXTargetDependency */, + FA95F16822D4A002E51EF5CA923DE364 /* PBXTargetDependency */, + 3E792FF89C3F369FDE71E23E97C2CB98 /* PBXTargetDependency */, + F3C5A8620AC1007E0621E4331D7195C2 /* PBXTargetDependency */, + 06E598FC4D34E504398BAC10C836FE85 /* PBXTargetDependency */, + F7B352EE3558C84D71ADBE90EFB43F78 /* PBXTargetDependency */, + ); + name = SwiftNIO; + productName = NIO; + productReference = 5E982D315A4CB75E8F15068B30779C7C /* SwiftNIO */; + productType = "com.apple.product-type.framework"; + }; + 61DB9F97C45B368C17F830199512E361 /* SwiftNIOExtras */ = { + isa = PBXNativeTarget; + buildConfigurationList = 74DA03C0685F5BC3A109932481F343B0 /* Build configuration list for PBXNativeTarget "SwiftNIOExtras" */; + buildPhases = ( + 4C91E77CC6E7137DBCFF1079C6712DBF /* Headers */, + F708DC1F73B45E572336E29D47BC8B67 /* Sources */, + 3473C50E39D59A32F55704D7C6273327 /* Frameworks */, + 2D826701DC52F7F32C09BC5792C51583 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F61F6EFD14909F2DF984C6532BC8B066 /* PBXTargetDependency */, + 72DC94BB5FE75FFF290FC13D6E3938A7 /* PBXTargetDependency */, + F7C8CF2B511BCBD63EDD5E04F38AFDD7 /* PBXTargetDependency */, + 1B7CE3198E1D89B9062D9454D22F0F6A /* PBXTargetDependency */, + 69713A8FD6655A8ECDB4247C61CA843B /* PBXTargetDependency */, + 119763A794B9463DD24A674A2967E366 /* PBXTargetDependency */, + CC0890DC7A56B04BF3C2FD43E0197BD3 /* PBXTargetDependency */, + 3B11C2F9C6D616FDD78D75EBB8C81B19 /* PBXTargetDependency */, + 6DA8991D847DEF37EB8A0DC372908CCC /* PBXTargetDependency */, + 6665E88CB89C7727C16695F329D4E2BF /* PBXTargetDependency */, + ); + name = SwiftNIOExtras; + productName = NIOExtras; + productReference = 81AC88440747A0FCA422BCA626C9A038 /* SwiftNIOExtras */; + productType = "com.apple.product-type.framework"; + }; + 65C8D0D3B04F444B821EB675E4D821DA /* CNIOBoringSSLShims */ = { + isa = PBXNativeTarget; + buildConfigurationList = C78AC542AF3C6690B1042AB421DBF608 /* Build configuration list for PBXNativeTarget "CNIOBoringSSLShims" */; + buildPhases = ( + DDEF6D661DE2192A55B4BD8278A1459F /* Headers */, + 94E4F7E090D14C6262F408A9945399C8 /* Sources */, + D144877115364218CA9245F54AF958AF /* Frameworks */, + 0507FE74ACE8CDB247F13AE3E9319521 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4D5DC35EC264A91C48C49DC51E3C60EB /* PBXTargetDependency */, + ); + name = CNIOBoringSSLShims; + productName = CNIOBoringSSLShims; + productReference = D138731AC283B1675098D887342027D8 /* CNIOBoringSSLShims */; + productType = "com.apple.product-type.framework"; + }; + 6E71929B582F8CD57B3DC1FD6560F047 /* PopupDialog */ = { + isa = PBXNativeTarget; + buildConfigurationList = 82DD89191CBB71A80BEEB00F63C291EC /* Build configuration list for PBXNativeTarget "PopupDialog" */; + buildPhases = ( + 567FF1B1737DFC4A3D5479AF64E8CE95 /* Headers */, + 6553DE6C4DE4146E1DBC591BB1845973 /* Sources */, + 514B9E896711AE5537D281C13B6B0006 /* Frameworks */, + 8EF36C13F9DCA47A3C211E62052FD3E5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9B5BE5013EB9FDF6193D67452B6CEC43 /* PBXTargetDependency */, + ); + name = PopupDialog; + productName = PopupDialog; + productReference = 34FB964502259D0FF233CE71CFDD2A71 /* PopupDialog */; + productType = "com.apple.product-type.framework"; + }; + 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */ = { + isa = PBXNativeTarget; + buildConfigurationList = 73C4F8ECE74823C72A0B7DF4A6A676F7 /* Build configuration list for PBXNativeTarget "CNIOBoringSSL" */; + buildPhases = ( + 4CFC8E0F71337197A8B9A06FBBEAC387 /* Headers */, + 545CF28F6289A5FA10F79049C0C5DC66 /* Sources */, + 0F7A1490E2F76ABB8A5DF1D057276C16 /* Frameworks */, + 7D7423D688F7C285F8E9302C851988AD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIOBoringSSL; + productName = CNIOBoringSSL; + productReference = BBBC89616D0756CD768F9406643F7DC0 /* CNIOBoringSSL */; + productType = "com.apple.product-type.framework"; + }; + 72EA11C51422080CE0CAEC35AC0EE02D /* secp256k1Wrapper */ = { + isa = PBXNativeTarget; + buildConfigurationList = BCF90AA723661B881DB460C7B37264F7 /* Build configuration list for PBXNativeTarget "secp256k1Wrapper" */; + buildPhases = ( + E7DAD0F842380BB51C10F7D12CD58694 /* Headers */, + 62C4533F24B3C97E049294153C6009BD /* Sources */, + CC750A63195DFF5FDAA9CCAD5E3BB26B /* Frameworks */, + 9F1B2014C24C15FA0BC03E2820FDCBED /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = secp256k1Wrapper; + productName = secp256k1Wrapper; + productReference = BA36C95CC11BBA679562231CDB7DC1A5 /* secp256k1Wrapper */; + productType = "com.apple.product-type.framework"; + }; + 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1BBB16EB7069406B761A88626AED702D /* Build configuration list for PBXNativeTarget "SwiftNIOConcurrencyHelpers" */; + buildPhases = ( + 0B4C0E03790A440BD928D0575BBAFA6C /* Headers */, + 61D5CB2A810C7FC352C0CF15BEF8EE8E /* Sources */, + EE2D4D0DCA16BD182E75192E712C77EB /* Frameworks */, + FD6493EA8A343A984F088C42DC5F3626 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 600B835B23FA6C600C45FFCC1DAE599F /* PBXTargetDependency */, + ); + name = SwiftNIOConcurrencyHelpers; + productName = NIOConcurrencyHelpers; + productReference = 673CA60B9FF9D56D5AEAFAD4E2D7B368 /* SwiftNIOConcurrencyHelpers */; + productType = "com.apple.product-type.framework"; + }; + 7D914FA2F03C860D5133BA2DB87C594A /* DynamicBlurView */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0760232251EA461456909CD65D1D22AF /* Build configuration list for PBXNativeTarget "DynamicBlurView" */; + buildPhases = ( + 6B5CA505D540DE77F08E0BCD22C6C298 /* Headers */, + 99E49451CD45EE51C32A150E172D36C7 /* Sources */, + 5BE3C5EFF74402BA5397C8D27800D20B /* Frameworks */, + 2CE73D7DDF0FF3CCDCC44918DFB3178D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DynamicBlurView; + productName = DynamicBlurView; + productReference = 86C4A2D817E6CFFF31BF75161625FD5D /* DynamicBlurView */; + productType = "com.apple.product-type.framework"; + }; + 814D3CA630EB31504C9C25A1AE6B75B7 /* secp256k1Swift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2B3CB99B88A081A0697B5463DB259194 /* Build configuration list for PBXNativeTarget "secp256k1Swift" */; + buildPhases = ( + EA7B249205F62439D7245B12B8BF8257 /* Headers */, + 912FA7F2A6306DE0091563D8D3CD43C1 /* Sources */, + 178F22DBE49565BEBFE6AFB867DD4F37 /* Frameworks */, + 871B7691D94A52179CDA363CC1EDE7F9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DC65CE716235E7252B2E280D6E47C53F /* PBXTargetDependency */, + ); + name = secp256k1Swift; + productName = secp256k1Swift; + productReference = 07DEEECEF437CFC809687467C7ED76E0 /* secp256k1Swift */; + productType = "com.apple.product-type.framework"; + }; + 834F3DE9EFC7B90102D63A51F6A9AF51 /* SwiftNIOFoundationCompat */ = { + isa = PBXNativeTarget; + buildConfigurationList = B11C7159FE09498456D8BBCB9B1ADF49 /* Build configuration list for PBXNativeTarget "SwiftNIOFoundationCompat" */; + buildPhases = ( + 548121DC45083FA8CE8348896AB8505F /* Headers */, + B9E3EDD72D5BBD61999CA90AB528007E /* Sources */, + 45B80BBEA22F6A6BF03C644DF50F8554 /* Frameworks */, + E3E502A761056A4E01EBECBD5C4537D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4C36BA04A342CAE8B71AE8B5B5F2B052 /* PBXTargetDependency */, + BD0A680BC1E66234B6C275D93F9EDAA4 /* PBXTargetDependency */, + CBBA2AEE2C702CE05968AC68E5C03616 /* PBXTargetDependency */, + D29F12E57E824F881C1024F0816A2166 /* PBXTargetDependency */, + 704D000B7BF4CFF13A8CA335877479F6 /* PBXTargetDependency */, + 078888E1021FBDAD5A98EC52A37C1840 /* PBXTargetDependency */, + 54EC16322C9803015F846B01CEAE69AB /* PBXTargetDependency */, + CAB8E461C9D5FEB6DBDB2047A31837DD /* PBXTargetDependency */, + 7295DF9B4CCCD6C2AF470FA9994A968B /* PBXTargetDependency */, + 6124CD8E872D0BDAE242360EC893C761 /* PBXTargetDependency */, + ); + name = SwiftNIOFoundationCompat; + productName = NIOFoundationCompat; + productReference = 6D040D1A67C3DBE3C11EB6FBC61B8141 /* SwiftNIOFoundationCompat */; + productType = "com.apple.product-type.framework"; + }; + 851EADC4C9B098805B57AB058076FF60 /* gRPC-Swiftp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B505826D4438A766AC48260B25112AF /* Build configuration list for PBXNativeTarget "gRPC-Swiftp" */; + buildPhases = ( + 1EC222004258899747E7AB830FD40472 /* Headers */, + FBF55E39820DAC82F4E4E5A3ECB8C8E9 /* Sources */, + D85857194C8750BC9CC1799F7E65BA08 /* Frameworks */, + ECC9B27BD5FCE667E76A03E3B07E0280 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 90E73C724F8C103C52034DE49546CF27 /* PBXTargetDependency */, + FC70C7F5DC2E1A5F05DDE298C930F34B /* PBXTargetDependency */, + 5D739DDF26E9E0AA52742A61A2E4A80D /* PBXTargetDependency */, + 1427A616844C28E535D8CFD98FC2FA4A /* PBXTargetDependency */, + 4A76DE25D040F234D7B1A635A2CCA9A7 /* PBXTargetDependency */, + CFCA66E63B1B676FF6786C67FD8749FF /* PBXTargetDependency */, + 4F533D4F2332CF3960D0C83F5B229947 /* PBXTargetDependency */, + 246BDE28579EBF1384598444EB0C15CC /* PBXTargetDependency */, + ); + name = "gRPC-Swiftp"; + productName = GRPC; + productReference = 3B675E4619748AE52DB48AE541E34C1A /* gRPC-Swiftp */; + productType = "com.apple.product-type.framework"; + }; + 85E705C55EE1E21751DAF1510D4F983E /* FCL-SDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0E6DD91A9FCBD60BBBCAD3B56E8C6951 /* Build configuration list for PBXNativeTarget "FCL-SDK" */; + buildPhases = ( + C3454DAC762B6D9DE0375C878617E5CD /* Headers */, + 998DB4FDC72027717F8C1B061B233CD2 /* Sources */, + 1901CEF914F1C89526CC7B4B5A34B640 /* Frameworks */, + 9414A87AE2478C75FE21233B20EC3147 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DCFE8CF7BE8F259112DE214524DC7F21 /* PBXTargetDependency */, + C56A63459E764858C0E55ADA24E52983 /* PBXTargetDependency */, + ); + name = "FCL-SDK"; + productName = FCL_SDK; + productReference = 367CC54EBAD387B037592BA9CDFFC0FE /* FCL-SDK */; + productType = "com.apple.product-type.framework"; + }; + 89CBF82371E354F25396C12B34804198 /* Pods-fanexTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = ACF1A1DAD01BB2C6CC83080EDC52EA51 /* Build configuration list for PBXNativeTarget "Pods-fanexTests" */; + buildPhases = ( + 5304391AFFCDEADB21125EF200891209 /* Headers */, + C6AE0677323C0AA412FEF367A2118C03 /* Sources */, + 9F9332661014D80C00B6057EFF424E30 /* Frameworks */, + 158BA0892D9B6A3EC714D1C8CBED0D52 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 62FEF478BD2A0B784D1FB1163597E0E5 /* PBXTargetDependency */, + ); + name = "Pods-fanexTests"; + productName = Pods_fanexTests; + productReference = 73643EEA08A3187BF338758D45B69065 /* Pods-fanexTests */; + productType = "com.apple.product-type.framework"; + }; + 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = C8C755AE412B45E17E1142C83244A1EF /* Build configuration list for PBXNativeTarget "CryptoSwift" */; + buildPhases = ( + A8D5F226095625BBB44A067762403DBE /* Headers */, + 8922821CAE0A2EDD720B2EDAAC480969 /* Sources */, + 906AAB1325A370AFE920A1629E1C3563 /* Frameworks */, + 16A693CA697EF54F56C556045E2D4967 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CryptoSwift; + productName = CryptoSwift; + productReference = F81274EDB681F11E7CB05F7DCA2BB33C /* CryptoSwift */; + productType = "com.apple.product-type.framework"; + }; + A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2352C424B358B93E5FB0F821F16CE8B0 /* Build configuration list for PBXNativeTarget "SwiftNIOCore" */; + buildPhases = ( + 93D18E60087C4E8C7AC2236546CFB0E5 /* Headers */, + C82B5A6646D3768C42F8CDCCFCBF18E4 /* Sources */, + 765078170972CBD9E41B13D3C3979878 /* Frameworks */, + A677226498674906E330DBEF901EA4DA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + EBF9BD97E5227424FEAA3FF0A3341BC0 /* PBXTargetDependency */, + 5733BDB0F5749B55BDBBB0C82637FBF8 /* PBXTargetDependency */, + FCB5643F9A725C86AFCCC462F2EE0BC7 /* PBXTargetDependency */, + ); + name = SwiftNIOCore; + productName = NIOCore; + productReference = A00E16AE69A03C3643B9534FCF13263C /* SwiftNIOCore */; + productType = "com.apple.product-type.framework"; + }; + A5F702E0DA383BC1479572581615A916 /* SwiftProtobuf */ = { + isa = PBXNativeTarget; + buildConfigurationList = B507F2DAF6B61D93CF6A883715853372 /* Build configuration list for PBXNativeTarget "SwiftProtobuf" */; + buildPhases = ( + E2CF88F6B7447599892B3729279BD620 /* Headers */, + B8431C4117C2D2C4C9AFCF7419A22C5F /* Sources */, + DB5DF2EA7D8E53A74519F53BFFD43AE3 /* Frameworks */, + 49CE861589712671BFB674E155FA745E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftProtobuf; + productName = SwiftProtobuf; + productReference = 943D347E61A2E181A4FA2CA894307B6E /* SwiftProtobuf */; + productType = "com.apple.product-type.framework"; + }; + C9BE6B81CE17330F64D48B2DD71C2228 /* Pods-fanex-fanexUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5D5C5591972CB4318463485CD8219013 /* Build configuration list for PBXNativeTarget "Pods-fanex-fanexUITests" */; + buildPhases = ( + 6579E4D44EE47874D1B721366CAF2E88 /* Headers */, + 5FB3BAB210986BFE10D62EC1678E2364 /* Sources */, + 1D5D6473CB29A09AB0E6A90F39C96C59 /* Frameworks */, + 0B758D55EE35DFDFC194448ED5F934D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 038C7A501E306882F7896E00DE87C09A /* PBXTargetDependency */, + 603F818186D87D5DBBED2F809DE081C7 /* PBXTargetDependency */, + 70E9AF8AA19DEFA1311BC8AACFEACDBD /* PBXTargetDependency */, + C22EF9E1392B8E370AB3AF135FC4C5D4 /* PBXTargetDependency */, + 6EC112BBED520555C7D68F82B6ABD2F9 /* PBXTargetDependency */, + 2C416606605ED7ECFD414485A32A22BB /* PBXTargetDependency */, + 308025E0D6B0EC45F1900E3E8C6B1DBF /* PBXTargetDependency */, + 34BDD9822AF2141C6BB435625A73BA4D /* PBXTargetDependency */, + 0228D2C2A2501C05BDA6FB0A1BAF6348 /* PBXTargetDependency */, + 224BE7E52FFC7F40E296462A6D1C84E2 /* PBXTargetDependency */, + 7C4E2D7DA3FA3D0A71DA0F076ADBC8B7 /* PBXTargetDependency */, + 78661ED6DD469638173ED9B30DC3B7C5 /* PBXTargetDependency */, + A6C3C9F24084105F7A1BA3337CDC059E /* PBXTargetDependency */, + A39188E7BEE00FE6FC585B1CCEC5D18D /* PBXTargetDependency */, + B913BA400073ACBC2AF0704B75C056D0 /* PBXTargetDependency */, + 8A816C625035C3E0DD6373B415EC15BC /* PBXTargetDependency */, + 3A0C249E87FBE56CF6FB0EBC8E1F7F3F /* PBXTargetDependency */, + A032D968F2BCF6A51269B97E963832ED /* PBXTargetDependency */, + E94E5D66DFDB66856DE20896C4384AA6 /* PBXTargetDependency */, + 550732659089AE9960375A7D1C66ADD1 /* PBXTargetDependency */, + F3A0B33927300988EC32CD81C40AA5E2 /* PBXTargetDependency */, + 0A324B3E2BB7648094044F017A8EE0A0 /* PBXTargetDependency */, + 3303EAB3B9E615FC912071B7A553B942 /* PBXTargetDependency */, + 65F6100DC8F6CC635E57CEE43C5BB19F /* PBXTargetDependency */, + 044AA22809D937EFE8E18B9152746312 /* PBXTargetDependency */, + E909D5C6FE06848C52A74792B5843859 /* PBXTargetDependency */, + D671EB1EDD4CBD089C9722EF737F1339 /* PBXTargetDependency */, + 724615429F82EBD938FF3D5E7BF7F895 /* PBXTargetDependency */, + 798D84E6FBC0F6DE7942CD6AA0F031CC /* PBXTargetDependency */, + 04774F6BC7D28563253FB17FACE90C06 /* PBXTargetDependency */, + E3B77BB1DABFE06AB99BB07220ADFE97 /* PBXTargetDependency */, + 966C16AA0B951E5E0402723BB04A1E4D /* PBXTargetDependency */, + 55D38AD4D69DE99D53DAA79DF581E16B /* PBXTargetDependency */, + 6E6D337AF318CF564021D632E6D6F8CF /* PBXTargetDependency */, + A66A3238A9B0114A0DABB625F7AB5A1D /* PBXTargetDependency */, + BB5E0C8415BD8B93376F0D9CDBF94E40 /* PBXTargetDependency */, + A162E01E813844A1312DD9BFBFD548E6 /* PBXTargetDependency */, + D605040DFE4385A3991A3D6363964E1E /* PBXTargetDependency */, + F58EE7C0FB65D347A65EA94EDEDE52A3 /* PBXTargetDependency */, + ); + name = "Pods-fanex-fanexUITests"; + productName = Pods_fanex_fanexUITests; + productReference = 4B2D28E09E850EBAACFFC4677BFF6724 /* Pods-fanex-fanexUITests */; + productType = "com.apple.product-type.framework"; + }; + CE9E4A87F29CA10BA13A4B9B6FCCD386 /* Cadence */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5B99BE48F5F355257AD701BE6BF287A7 /* Build configuration list for PBXNativeTarget "Cadence" */; + buildPhases = ( + A8E5F25334979EDD882BC874088C1058 /* Headers */, + AA141FA25DB9F2A41BB5F46E542E5F15 /* Sources */, + 5FC030FC787D52EA132C88F9D20DD8A5 /* Frameworks */, + 5D33E15104CCB37D50CF887C078EF959 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + AEEC4AB2C38D4C1E37B40D3850C57F06 /* PBXTargetDependency */, + DBE9728CF19A17AF67A1F2F5066D4D74 /* PBXTargetDependency */, + ); + name = Cadence; + productName = Cadence; + productReference = 932928A2279109486F3A16C66E4D61F8 /* Cadence */; + productType = "com.apple.product-type.framework"; + }; + CF4D556EB90FFD6388321BDFD45BDDB3 /* SwiftNIOSSL */ = { + isa = PBXNativeTarget; + buildConfigurationList = D82A5F20379D6AA8B5AF202CFA5838FB /* Build configuration list for PBXNativeTarget "SwiftNIOSSL" */; + buildPhases = ( + 726B821BBA2AFC8A5304843B3AB656EA /* Headers */, + E794A2A742D84C7B857A385367BF237E /* Sources */, + 7441BBBDBDCFBFCBDAB0F7775006F626 /* Frameworks */, + 29B6E751E8813BE9B5349BB45DFEAF83 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B1202BE92A2625D324C496123F495618 /* PBXTargetDependency */, + 06CCE66A4CBF9A6FA3E20005E0C0A8AE /* PBXTargetDependency */, + 7D33427A3B4F9D9DD2E6F9395412E051 /* PBXTargetDependency */, + CAA36A3AC4BBCBF93DF5B06215913A0E /* PBXTargetDependency */, + E98BDFD3504E01A52147C32AA671E6FB /* PBXTargetDependency */, + DABA83732B97B34235811C8B7EF81B45 /* PBXTargetDependency */, + DC4912249288527538E558A0954E3E2F /* PBXTargetDependency */, + EB5CAA67CEF578E527BEA4EB9023D830 /* PBXTargetDependency */, + 10D348AC8F287D5614D83CD504205A88 /* PBXTargetDependency */, + 484C6F6D564D2791C6219ED01119375D /* PBXTargetDependency */, + 27199B8000EE5126C01162FB8E7705F4 /* PBXTargetDependency */, + 25411863FC966F97FFABB07BC6DB5B5C /* PBXTargetDependency */, + 4A25CD31AEE04D37F9B962232F7239F1 /* PBXTargetDependency */, + ); + name = SwiftNIOSSL; + productName = NIOSSL; + productReference = 73328AB6E67FF4855DF7327B64265B4E /* SwiftNIOSSL */; + productType = "com.apple.product-type.framework"; + }; + D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6FE7248D024BB1299E4CA37218234399 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */; + buildPhases = ( + 8CFCD9F45393EB65D64639C8416EEE02 /* Headers */, + 7150198F4B0FA51AC42974C30D24194B /* Sources */, + 390F21EFEDF9FC3E399CC8CE8937F47D /* Frameworks */, + 7D9C0BED4A08FEEBF3FC71FFEB8A14E9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftyJSON; + productName = SwiftyJSON; + productReference = E23C076BA70925415F490FEDB215DA92 /* SwiftyJSON */; + productType = "com.apple.product-type.framework"; + }; + D5D61C34B6B0F36656A57CF77C297BA6 /* Pods-fanex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2ABB7819979A3490D43740C6DD180657 /* Build configuration list for PBXNativeTarget "Pods-fanex" */; + buildPhases = ( + 25C44E0DEC2C2822EA04D185843913A6 /* Headers */, + B3CC4389BFAAC554AF4E77263B4970EE /* Sources */, + DA76E43865D6C2D14F5422C200700BEB /* Frameworks */, + B14F03FC73DFAD90AA3C00F1636DD619 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 13C317CD96A879F250EDB9C9B1EBA9A5 /* PBXTargetDependency */, + 9308049DB96F3DC42DD01E73F8DA84D2 /* PBXTargetDependency */, + E3477E2D10FEF686A2E7986E4E4ADD8D /* PBXTargetDependency */, + A8B2A174D397F044FDE5A4A32BC5AF96 /* PBXTargetDependency */, + 30FADCA34C3972AED11A3862AB22A8F5 /* PBXTargetDependency */, + CBB445264E41843BA56CE87E2E71C5AE /* PBXTargetDependency */, + B1C7203378A1142EB72E8A915F385963 /* PBXTargetDependency */, + 48C889037C290D6D74646196C9E5D916 /* PBXTargetDependency */, + AB9FEE502C57590DE648F110619F08BE /* PBXTargetDependency */, + 1CDF6C7D36C2712346A713E21E1D9688 /* PBXTargetDependency */, + 09A630B50C50046DAB2CC4A44DDA614A /* PBXTargetDependency */, + 3127A864E36969E73BDE1F66D93AB93E /* PBXTargetDependency */, + ACCEFFBA5EEFEE70DCC9BD89D80CDFC9 /* PBXTargetDependency */, + D10F7AD94F358AB3AAAB0623DF802760 /* PBXTargetDependency */, + 9B2A7F11E04BEF1541D71F817BE169AA /* PBXTargetDependency */, + D345E6B0CB9233B38F385DB238946B3E /* PBXTargetDependency */, + 79762CE44253D21CEB614CA9EE210F3D /* PBXTargetDependency */, + 80541813E5980BD572277A3246DEE61A /* PBXTargetDependency */, + 94653D726981294EFDD10F4430CDED65 /* PBXTargetDependency */, + 3BA9F2AEA8739971CEE8A9A3AAD6B9D3 /* PBXTargetDependency */, + 30F0D309975272280F791551247C90E9 /* PBXTargetDependency */, + C216B4BC492ED158651C113A9DCC8B01 /* PBXTargetDependency */, + 1F5F59406C48B5B70BA5E8C7B53582F0 /* PBXTargetDependency */, + 9AAA94E5D40BE342986977145985905B /* PBXTargetDependency */, + 399F4FEB41957355CC088ED1C386C00F /* PBXTargetDependency */, + 00DA780A54D0828CD6955B253F04AF4D /* PBXTargetDependency */, + 1DD55CB8D3ED13C199F01876D85E4565 /* PBXTargetDependency */, + ACB73AE2848112169BF3FF17A45AF5F6 /* PBXTargetDependency */, + 128F2DED5661F0E0E9437165AE51D3FC /* PBXTargetDependency */, + 51B457AECBA3CFF8548C722E434237F3 /* PBXTargetDependency */, + 88C96393C60357B8577097AAC9724A70 /* PBXTargetDependency */, + 6FF7A2301E0B50784445E8CF8545B688 /* PBXTargetDependency */, + AB7425AF0C567364FCF6389B1D19F02E /* PBXTargetDependency */, + 5B96494B5A94BBF7ED38D942AED3D63D /* PBXTargetDependency */, + 5188BDA4C9DBAD07227E6329122134DD /* PBXTargetDependency */, + 01E9343BA9310799B63E59391389F4B2 /* PBXTargetDependency */, + 54F6D47245B2D4F04860A43CA04E5C9F /* PBXTargetDependency */, + ED382F7DF066794D52B3FB4455F590EF /* PBXTargetDependency */, + D9CAA4F01AD4B2EE275CEE120D6CF516 /* PBXTargetDependency */, + ); + name = "Pods-fanex"; + productName = Pods_fanex; + productReference = 300BB2CB97DD4DA36846810A394A85E5 /* Pods-fanex */; + productType = "com.apple.product-type.framework"; + }; + D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1415ECE334DCCA6DC980A43E5E4366B1 /* Build configuration list for PBXNativeTarget "SwiftNIOPosix" */; + buildPhases = ( + 7AF1E32BBB6D2774C2053D5744D7E26C /* Headers */, + BA44F608FC3EE94F867DCD49CC2694A9 /* Sources */, + 5A1969DD96E266CCC8111344B0D442C4 /* Frameworks */, + 5427F8AE4243F5B235E63AF96FA3EF97 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5A6F64245EBFDFF3540C5313CF201135 /* PBXTargetDependency */, + 6CB5E1BF7326C5811194FC0E6D5149D0 /* PBXTargetDependency */, + A059A24DED83656C90DB6A5F9989FE41 /* PBXTargetDependency */, + CB75C39D8B78800678841CE314110A4D /* PBXTargetDependency */, + 65902DBD13E5BC6AD631595F19B0A4CA /* PBXTargetDependency */, + 43ED3B641A97B27FA67DD99C47C86D77 /* PBXTargetDependency */, + 8AF9202713D94710C483ED2F461F861D /* PBXTargetDependency */, + ); + name = SwiftNIOPosix; + productName = NIOPosix; + productReference = D85994E4069B3EC81A279B775780797A /* SwiftNIOPosix */; + productType = "com.apple.product-type.framework"; + }; + E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0C14859D34B9027BBFBC968C1A2F3216 /* Build configuration list for PBXNativeTarget "SwiftNIOTLS" */; + buildPhases = ( + 54AC2112AE609980B728B098CF1A59F2 /* Headers */, + EC3B919A3B77D2428A5E7C63BF8FC6FB /* Sources */, + 073CA4512703A07BDC442F4FD27A9E22 /* Frameworks */, + BAA725A275B45D05BF80F65BA6D559C0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 99D973172F12E139B18283156ED79561 /* PBXTargetDependency */, + B94EE68281D3CDE248AAA0E96F032769 /* PBXTargetDependency */, + 5CA46EE889330FEDA5ADD04EA412BD20 /* PBXTargetDependency */, + F18ABC90D47A4142A44E348B0E892557 /* PBXTargetDependency */, + F57A1816028025AD92046F2C3C2032CF /* PBXTargetDependency */, + 9989B427686884AF149B7EF37256D53D /* PBXTargetDependency */, + C2D8F9E8938EB5182F06B24FDE1112AF /* PBXTargetDependency */, + 20188C8764A764A447A36FCCCAB999FE /* PBXTargetDependency */, + 2349BAC88578FF1FAAC2DDA69C6D3351 /* PBXTargetDependency */, + FCFFFB83B6BA6BF482E6709CB20A0463 /* PBXTargetDependency */, + ); + name = SwiftNIOTLS; + productName = NIOTLS; + productReference = 43BCA78D557ACEB23EEA495EE0402530 /* SwiftNIOTLS */; + productType = "com.apple.product-type.framework"; + }; + E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */ = { + isa = PBXNativeTarget; + buildConfigurationList = B39D77ADCBA580D59305992054625C4F /* Build configuration list for PBXNativeTarget "CNIOAtomics" */; + buildPhases = ( + EED349C326E8FA19559595BEDFF304DC /* Headers */, + 51F6B8026FB04C8C612A40D56DCFEC78 /* Sources */, + 2E4080B5667EA5F40655DC585E459595 /* Frameworks */, + 5BF83F88432907689E101F222BD87499 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CNIOAtomics; + productName = CNIOAtomics; + productReference = D91FC01385D3680BAE48C7A1E23CB088 /* CNIOAtomics */; + productType = "com.apple.product-type.framework"; + }; + F52E6DA0104A4F8C767EF42CAE3D09F4 /* MercariQRScanner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7DB8D3C965A40C5A7E49FD2AFDD1087B /* Build configuration list for PBXNativeTarget "MercariQRScanner" */; + buildPhases = ( + 57BD09A4FAE5E08FBE2413C484057E3E /* Headers */, + D289E0F76A764BA9C83ACE956D6A27A0 /* Sources */, + 24A6F86BA2803C14A9F67847915AA75C /* Frameworks */, + B502629C5C3C8ACAB881BDB1CB86A009 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MercariQRScanner; + productName = MercariQRScanner; + productReference = 915361CF4F5BEB9ECA5F7A89DAE63096 /* MercariQRScanner */; + productType = "com.apple.product-type.framework"; + }; + F71DD9985215E142F625AD23A9121477 /* SwiftNIOHPACK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 263E4F18F2482D2B79CEEBE3572473EC /* Build configuration list for PBXNativeTarget "SwiftNIOHPACK" */; + buildPhases = ( + B4CCCF2B236B02DF6E6CF29A9427350A /* Headers */, + 3424B8E0B4C6FF840DAF84BA7B8EAE12 /* Sources */, + 89627D7C265FE6982EB6CA811534A889 /* Frameworks */, + 7DFAFA60B27522AE37BF45BD145E1084 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 21A37639297A8B0A4066292E5A50C545 /* PBXTargetDependency */, + 7033F7A064718ED5A9A1A42FD13DDA93 /* PBXTargetDependency */, + 22A19E247DC81B9AD464DEA07EA4F4ED /* PBXTargetDependency */, + 7157BE1E049E3DA30432821C2ED2940E /* PBXTargetDependency */, + 5B54C3963B31A7E92AFE75C7AB9D92D2 /* PBXTargetDependency */, + BA28A5E5F7C33022537A111229359CDA /* PBXTargetDependency */, + 4D4586E5C01E7C85D2EE7FA575F10FF5 /* PBXTargetDependency */, + 2C5FFFE3153FC0AA03ED2275E3F372CA /* PBXTargetDependency */, + 1AF27CB171A41D0F2E56014AAC1F8D4F /* PBXTargetDependency */, + BF17B205263C38CA4570DF5DD44376F8 /* PBXTargetDependency */, + 07B57AB0246092FC3892BDAC6DFBDEC4 /* PBXTargetDependency */, + 4F14857032D0393F64CB489FDA2703FE /* PBXTargetDependency */, + ); + name = SwiftNIOHPACK; + productName = NIOHPACK; + productReference = 8A6887895625D9DECAAEBF5A690134F7 /* SwiftNIOHPACK */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1300; + LastUpgradeCheck = 1300; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = BC0CF0BF5E7DEB81FE1A2F797FE2F4D8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */, + 09DD83B7D075842A3A5105AD410BD38A /* BigInt */, + 5A8A5B4451A77B0A6D36B131E2974E23 /* BloctoSDK */, + CE9E4A87F29CA10BA13A4B9B6FCCD386 /* Cadence */, + 54382245E5C9DB4A3CFB906FD97A35BB /* CGRPCZlibp */, + E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */, + 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */, + 65C8D0D3B04F444B821EB675E4D821DA /* CNIOBoringSSLShims */, + 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */, + 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */, + 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */, + 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */, + 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */, + 7D914FA2F03C860D5133BA2DB87C594A /* DynamicBlurView */, + 85E705C55EE1E21751DAF1510D4F983E /* FCL-SDK */, + 446DA03EDE44E6615A2A146E3D90AA3D /* FlowSDK */, + 851EADC4C9B098805B57AB058076FF60 /* gRPC-Swiftp */, + 2ABF3F8EC6CE525E1E02C51D72C64E94 /* Logging */, + F52E6DA0104A4F8C767EF42CAE3D09F4 /* MercariQRScanner */, + D5D61C34B6B0F36656A57CF77C297BA6 /* Pods-fanex */, + C9BE6B81CE17330F64D48B2DD71C2228 /* Pods-fanex-fanexUITests */, + 89CBF82371E354F25396C12B34804198 /* Pods-fanexTests */, + 6E71929B582F8CD57B3DC1FD6560F047 /* PopupDialog */, + 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */, + 814D3CA630EB31504C9C25A1AE6B75B7 /* secp256k1Swift */, + 72EA11C51422080CE0CAEC35AC0EE02D /* secp256k1Wrapper */, + 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */, + 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */, + 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */, + A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */, + 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */, + 61DB9F97C45B368C17F830199512E361 /* SwiftNIOExtras */, + 834F3DE9EFC7B90102D63A51F6A9AF51 /* SwiftNIOFoundationCompat */, + F71DD9985215E142F625AD23A9121477 /* SwiftNIOHPACK */, + 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */, + 17112F66EE5BDC5584A51CF4FCE7631A /* SwiftNIOHTTP2 */, + D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */, + CF4D556EB90FFD6388321BDFD45BDDB3 /* SwiftNIOSSL */, + E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */, + 5D6DC8585F20CBE789F7D3D4F645980E /* SwiftNIOTransportServices */, + A5F702E0DA383BC1479572581615A916 /* SwiftProtobuf */, + D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0338E9DD361AAB2CBBABFB2A5B172C90 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0507FE74ACE8CDB247F13AE3E9319521 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 070AF9FEDFD26E4F06F0D64B0E7BA11F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0B758D55EE35DFDFC194448ED5F934D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1215F98F9CA34918D373E396EB049C19 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 158BA0892D9B6A3EC714D1C8CBED0D52 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 16A693CA697EF54F56C556045E2D4967 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 29B6E751E8813BE9B5349BB45DFEAF83 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2CE73D7DDF0FF3CCDCC44918DFB3178D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D826701DC52F7F32C09BC5792C51583 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 307D90E0345C74D96191AFCB4A3D1895 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC6F8230BD0C52CB7C2B47107AFB7B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 367BEF65DEAFC0F28EEC92148C61CEE3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 49CE861589712671BFB674E155FA745E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 52FAFDA542AF2211AB2D8C7A5B3103CA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5427F8AE4243F5B235E63AF96FA3EF97 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5BF83F88432907689E101F222BD87499 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5D33E15104CCB37D50CF887C078EF959 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6DA3BD93360B186FED278BB17BC74EE7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7D7423D688F7C285F8E9302C851988AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7D9C0BED4A08FEEBF3FC71FFEB8A14E9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7DFAFA60B27522AE37BF45BD145E1084 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 83A366519E8D30332C528C6E6A79B94A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 871B7691D94A52179CDA363CC1EDE7F9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8EF36C13F9DCA47A3C211E62052FD3E5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9414A87AE2478C75FE21233B20EC3147 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9F1B2014C24C15FA0BC03E2820FDCBED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A4CCC3CC21F770E272C54B18DDDE6DA3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 943B0A1B436BAF4D419574466EF70FB3 /* SVProgressHUD.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A677226498674906E330DBEF901EA4DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B14F03FC73DFAD90AA3C00F1636DD619 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B502629C5C3C8ACAB881BDB1CB86A009 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C3E4CC39E3E51B53B6A01E2D5120F23 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B760DFD74FB77DF3673692A3E0DD16B4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BA03F669FEDCACCE81DCC230B2B1B410 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BAA725A275B45D05BF80F65BA6D559C0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C776F6A64A073BE88CD07D9069E3346C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFFED6A91FA4B92FB6187DDE0164E82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D9A6F2D0672BA3144D598D16F1D0E163 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC20DB2B5A8B3C34EAC16992C6449775 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E3E502A761056A4E01EBECBD5C4537D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E3E8460D533945543EDDC478E4D27172 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ECC9B27BD5FCE667E76A03E3B07E0280 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FD6493EA8A343A984F088C42DC5F3626 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 108B36464ADE4902E2E2C83461767402 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52BCC3B2F8AE7F59556925DEC603C634 /* SVIndefiniteAnimatedView.m in Sources */, + 1F4A13FD6675FCFCD9C19DF350348899 /* SVProgressAnimatedView.m in Sources */, + 89DF2D9C5EFB02A72EC0CE2138B77F35 /* SVProgressHUD.m in Sources */, + FFD43D91BF1FA4ADF714D56E7A10B2A8 /* SVProgressHUD-dummy.m in Sources */, + 1D325CFE11FE13A075C835E922BE1017 /* SVRadialGradientLayer.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 151155F162A28F148E23675E0ECAC893 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C81C295AD40E8C4267DA5A82701DB73D /* ConcurrentStreamBuffer.swift in Sources */, + 26A459DAC73FC2DCD5D7B0F12044F5FE /* ConnectionStateMachine.swift in Sources */, + BAC0CB1E4BAA509CE3C089F5B05CEB4F /* ConnectionStreamsState.swift in Sources */, + CA16CFA4484506D2C0D1BD2EF539960C /* ContentLengthVerifier.swift in Sources */, + DC581B8511549CEA215A0EF40CEE4157 /* ControlFrameBuffer.swift in Sources */, + EF15DE530D074CBC2EE055EF5E915F7C /* DOSHeuristics.swift in Sources */, + 9B941E4C325F231E0FF215B9943B1BF3 /* HasFlowControlWindows.swift in Sources */, + 9360ADE473BF98DAE696E99119797280 /* HasLocalSettings.swift in Sources */, + 48ED5F872612BDDD09B72C499200B8DE /* HasRemoteSettings.swift in Sources */, + 14EAC53C775EA6A2C046651995690AC1 /* HPACKHeaders+Validation.swift in Sources */, + 6FCB9936F3CED366B0F61F27D1CF57CE /* HTTP2ChannelHandler.swift in Sources */, + F4ED72DAE062C7DD4AF21AE5EF4E5892 /* HTTP2ConnectionStateChange.swift in Sources */, + FDA6C3D301D4905F17CD7C3191DAC50A /* HTTP2Error.swift in Sources */, + E29D45250296F63650E57BA46A9E46A6 /* HTTP2ErrorCode.swift in Sources */, + 6DA8B06D829E22F50025A899894EDB90 /* HTTP2FlowControlWindow.swift in Sources */, + 428B7476BB9653288BB42A936041D612 /* HTTP2Frame.swift in Sources */, + AB66E4C0C00A3E127E9D3326F14F65AD /* HTTP2FrameEncoder.swift in Sources */, + 6D219D21CA5B7A3E4714F35C92A22332 /* HTTP2FrameParser.swift in Sources */, + C1CCD14D7F52BAE64BCCF96CAF9A1A8B /* HTTP2PingData.swift in Sources */, + 06D80670E698BEE870B774E42917971D /* HTTP2PipelineHelpers.swift in Sources */, + 9ADEE811DB62E02DB875EFF9DA83E1AC /* HTTP2Settings.swift in Sources */, + 43C87FB3800A6BD28B5490A4F392188F /* HTTP2SettingsState.swift in Sources */, + F05A43E63E90BCA0E8B09AE36CDBC816 /* HTTP2Stream.swift in Sources */, + 3E8D88F434DABBC551E828DFDAD424AF /* HTTP2StreamChannel.swift in Sources */, + B90AA99B9252253631CE5F103E1A8FFD /* HTTP2StreamID.swift in Sources */, + 96AAE61037686D0D11BFABF87E3EDF99 /* HTTP2StreamMultiplexer.swift in Sources */, + 511B8BDB8C401CD5A276530D7BD67258 /* HTTP2ToHTTP1Codec.swift in Sources */, + 42C29C0C622839691B91E97AFB68CFDD /* HTTP2UserEvents.swift in Sources */, + C8E452B697F515C8E92880290551DDD8 /* InboundEventBuffer.swift in Sources */, + 0C82E543EF035DB9C066DC60C5D3B612 /* InboundWindowManager.swift in Sources */, + 90EDCF951A14E6E89A0D43337925BAD1 /* LocallyQuiescingState.swift in Sources */, + 2980F984F7D2F691456888ECDB4A4120 /* MayReceiveFrames.swift in Sources */, + 87F9C4B7F650D9277B81B82A202A5443 /* MaySendFrames.swift in Sources */, + 48C73436D25ED04DE06C887714312F3E /* MultiplexerAbstractChannel.swift in Sources */, + 658E2827D037D0B0A2853EA7F7C4EA87 /* OutboundFlowControlBuffer.swift in Sources */, + 9E2CD9AB65E5C3E69C155F6F7338D6B5 /* OutboundFrameBuffer.swift in Sources */, + 7E95F9BA0431B5C6933EEF7030E032EB /* QuiescingState.swift in Sources */, + 9D0FA12B3199079CFDDC9BC7C8130715 /* ReceivingDataState.swift in Sources */, + 3C9DD8BF2BC29C594EF7DDDC1AC20A39 /* ReceivingGoAwayState.swift in Sources */, + 2CDE49667B9B52C8E4E197AC72644548 /* ReceivingHeadersState.swift in Sources */, + FAC2251A8AAD90FBCB3EAF21B87D4F11 /* ReceivingPushPromiseState.swift in Sources */, + 01066162D71B72A3740B57DF11239E18 /* ReceivingRstStreamState.swift in Sources */, + 2E225159666F9600A6472D4C9E8A1BC1 /* ReceivingWindowUpdateState.swift in Sources */, + 27C93A01F5FBF44A9613BBCBD3F53DED /* RemotelyQuiescingState.swift in Sources */, + E77834DCFE86B4649DDAEBC511B1F495 /* SendAndReceiveGoawayState.swift in Sources */, + ECC00A0AF7CE2DC24219FA4F944B7F89 /* SendingDataState.swift in Sources */, + F8DF325D968A7599FC260EC29086D890 /* SendingGoawayState.swift in Sources */, + 43C2C33EB588312825F3FFBD4F80B794 /* SendingHeadersState.swift in Sources */, + A7DC8EA2A5607E09F167AEADBD0645EE /* SendingPushPromiseState.swift in Sources */, + B74E2B3FF06C36CA30F399CA55F2ACE6 /* SendingRstStreamState.swift in Sources */, + 2D1D24C88A23F82164E0DB607DC8BE2A /* SendingWindowUpdateState.swift in Sources */, + 69EA3F34D3F0E947DA259171A0CD1CE3 /* StateMachineResult.swift in Sources */, + 78A427AD4E2362A4B6C8A9E7A5949E52 /* StreamChannelFlowController.swift in Sources */, + 4A9CD656B01029C96194280307260759 /* StreamChannelList.swift in Sources */, + 2146154EA67C9C7C9AA6E27A09907E52 /* StreamMap.swift in Sources */, + 420D28F3B8C7A6B5AC500FDF88B57872 /* StreamStateMachine.swift in Sources */, + B5783BE56D88997CF017C75B95B454F7 /* SwiftNIOHTTP2-dummy.m in Sources */, + 910586F1659C1ABF0DCFF5D35EEF84E0 /* WatermarkedFlowController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15B97154D9AA488D4AEE934158A07C36 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 42258B3EBC9E21CE161CFD7DFD3BBE8D /* Locks.swift in Sources */, + 3E42701B449F5BCC28EA93B1F896E113 /* Logging.swift in Sources */, + BCABD8D30EB03A91A2A446AF0CD7F6C6 /* Logging-dummy.m in Sources */, + A40AB16CC34439B2580523C759EFBFE4 /* LogHandler.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1CF8E521FBDE56FECE372CE0BBD8774C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7F5A32FAA652A02D9F78B42D894737D3 /* access.grpc.swift in Sources */, + 928C18FEBBA63ECCBA0D2B050E53A30A /* access.pb.swift in Sources */, + 5FB701AAB2C475A80FBA13979F08B5B9 /* Account.swift in Sources */, + D6634BF4B9D8938A861D81E5047079BF /* account.pb.swift in Sources */, + 6AC7F87B410F5DF58D68D04F570D93C4 /* Block.swift in Sources */, + A8436E9E56A2C6BAD1A959CD14123E7E /* block.pb.swift in Sources */, + 282D3255D6943F4493975DA44B8CB6EC /* block_header.pb.swift in Sources */, + AC7DE6FE7FDBBEA23A376869515ED036 /* block_seal.pb.swift in Sources */, + 548A1EF62DCFDC73212C81132753BC4C /* BlockEvents.swift in Sources */, + 32AE2F6E08E5E9A303A2FD9205386F4E /* Client.swift in Sources */, + 7EACACEBF875C6E4991C1E2D1EE5E93C /* Collection.swift in Sources */, + 47F0503848BFA54967C68EEE6FAA95FA /* collection.pb.swift in Sources */, + 82F81D59F9EE230609BB512B5670628A /* DomainTag.swift in Sources */, + 7CF8F5D09D2A1C1B0CD67A010F2E3CCA /* Event.swift in Sources */, + 59E68E35F43099496FFF47D0A675E7B6 /* event.pb.swift in Sources */, + 5D10DE91A793CDB9660A43C1BF0313B3 /* execution.grpc.swift in Sources */, + CB4D0153A0528F79BD6C847A9CD1953C /* execution.pb.swift in Sources */, + 3F5505CDB9E9AFE4C7C53E9AE4BDBE5D /* execution_result.pb.swift in Sources */, + 8BD89CD3ED492B3A09C9B215CBB7EBD4 /* ExecutionResult.swift in Sources */, + 537B0195EF2A345A27DC0043F5053482 /* FlowSDK-dummy.m in Sources */, + 5F42403E65F979D69536C6413E959845 /* HashAlgorithm.swift in Sources */, + 72AF36CCEFB67D3E56E57DFCC7FDED1C /* HashAlgorithm+Cadence.swift in Sources */, + DA9899E48206C31AAEF6113E43256C30 /* Identifier.swift in Sources */, + AFB2363051A846EEADDF248D61F698C7 /* InMemorySigner.swift in Sources */, + ADC47F1C5A8C8EF36F50DE82CEC057F5 /* Network.swift in Sources */, + 12F91E01435FE08933A65A1DE95EC3D0 /* PrivateKey.swift in Sources */, + 1EFDB44E84AD03172B673AA3F428E752 /* PublicKey.swift in Sources */, + EA5CBA722DBF91291CC6D0DE5228C7A7 /* PublickKey+Cadence.swift in Sources */, + A68ACC24048B3C426D38421731E4CD0D /* RLPDecodable.swift in Sources */, + 38C17D5F6F02C2300FA28DA364B08555 /* RLPDecoder.swift in Sources */, + 16439BB5FCBEE1827F379305A18611AB /* RLPDecodingError.swift in Sources */, + 897FA00B23D248BF04111BBA6ADC2FF3 /* RLPEncodable.swift in Sources */, + 22B0E64E15D819C861158B0905546FDD /* RLPEncodableList.swift in Sources */, + 7CED3AD85AB0E657AA82C8B40BF87637 /* RLPItem.swift in Sources */, + AE77CDAC417882E6017BADF780316526 /* SHA256Digest.swift in Sources */, + F25DD8DF9EDC42E03EE1A85BE89FAF29 /* SignatureAlgorithm.swift in Sources */, + 2C68099EAFBBBD04A6415AB789EA0F0A /* SignatureAlgorithm+Cadence.swift in Sources */, + 4A787352B4D5C3D906F51A18246FC565 /* Signer.swift in Sources */, + D1FCB300B05FF5B07E657659C562E5BC /* Transaction.swift in Sources */, + 72784E2069423F893C44C1F05EBEDCBA /* transaction.pb.swift in Sources */, + BFACABBEE75963CB9A2F46AC34367195 /* TransactionProposalKey.swift in Sources */, + 0469464887CD5DF06E189FAB225F2D24 /* TransactionResult.swift in Sources */, + 0297DE6077A06ECB90B5018547573403 /* TransactionSignature.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 259B59946D781041F752DF4B5FAA61FF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5A28263760C842A7FBDEC80D177BDE2A /* Embedded.swift in Sources */, + 87C0A26D2A061AA99F6EC5EEEDA6CCC3 /* SwiftNIOEmbedded-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3424B8E0B4C6FF840DAF84BA7B8EAE12 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 485A98918677B2F9846DD8FA43F3ADF4 /* DynamicHeaderTable.swift in Sources */, + 16B5435D378ADD56E7EB9B5FC50AEA44 /* HeaderTables.swift in Sources */, + 26B20EFDC551B51912CFF2A6490C822D /* HPACKDecoder.swift in Sources */, + 29491528E885FD6860457159F0DFB1FF /* HPACKEncoder.swift in Sources */, + D54C9D56EF5F66831AFD008E8B435E51 /* HPACKErrors.swift in Sources */, + 9A84B985B88342B6CDA921D4C2F3ABA3 /* HPACKHeader.swift in Sources */, + F7857CD0D3B1FB5C718447F140DFB54A /* HuffmanCoding.swift in Sources */, + 4D7599267DAE9AE608BF7491DAC8B5F5 /* HuffmanTables.swift in Sources */, + 56244090576E9D57C3CF597292EFCE2F /* IndexedHeaderTable.swift in Sources */, + 7F82AA1B00DC5EC3D1DF3E1E9BAF2AC0 /* IntegerCoding.swift in Sources */, + 53CAF4D42094B8A0AA0FE2AA5BC818DF /* StaticHeaderTable.swift in Sources */, + BFF97881904F1970C96A0B3D13DEA33F /* SwiftNIOHPACK-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 35848B0FBDD5C461811D1FC7B126BA24 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C44B8EF7029311A92F7408622AC1EBC /* CNIODarwin-dummy.m in Sources */, + 3A5832B520FA616148B778C9D27378E5 /* shim.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3B4BFA6C78E7E27765466DEF2EBB6DA9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D6BF0D382E2E68028AAF3CA080E941E8 /* Addition.swift in Sources */, + 81DEE0975FD2488D5C61D099F17DC3FA /* BigInt.swift in Sources */, + 7090F68043DADD044880B9A4DDB571E7 /* BigInt-dummy.m in Sources */, + 6A6D768A74F8BFBABED2364907A2DF0C /* BigUInt.swift in Sources */, + EC95784DCA76E26345C1E5090C1B1850 /* Bitwise Ops.swift in Sources */, + 17C20D68963C252E9991CD7361723892 /* Codable.swift in Sources */, + F41028D4E0E43E885ED9ADDFABBE1ED3 /* Comparable.swift in Sources */, + B96BCDA4AF618BF171AA502CC84FCD8F /* Data Conversion.swift in Sources */, + 55D3C00883F2CA52FE8F11468E97CB50 /* Division.swift in Sources */, + A81F5E7AC6A31EA09FB5B0CD5ECBA22E /* Exponentiation.swift in Sources */, + 540CC89836D830624883860F4AD3EAB0 /* Floating Point Conversion.swift in Sources */, + E4A7207A022D9584CD9B7D29381C8454 /* GCD.swift in Sources */, + DDA8E54FFAA6DFF7E15F15A52AB7C662 /* Hashable.swift in Sources */, + F95103DB3CDE985249C0B9E4CD464BA0 /* Integer Conversion.swift in Sources */, + D1691005C5FF403516FCA539B0E8038E /* Multiplication.swift in Sources */, + DA6EDABF74C3C6E9F9997B698195D6A2 /* Prime Test.swift in Sources */, + F5F0562EFC8A4222EB84980F223E6C15 /* Random.swift in Sources */, + 77651F160816E699EC490DD9D3F9BE02 /* Shifts.swift in Sources */, + F81E16CDC41BE1CB2C103F910F5FFC70 /* Square Root.swift in Sources */, + 73E1178AD16F91C80A718FB778F3534A /* Strideable.swift in Sources */, + 381D42ECF079E81454D3418F6DCC3B0B /* String Conversion.swift in Sources */, + 40A09F5E948345A60B856BB7C3BB5FE3 /* Subtraction.swift in Sources */, + 00C22009B3BEB45AE5A45805DEDCC316 /* Words and Bits.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 41DAF87DCCD998148F6C97B967DC3379 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 50F2A5DBC1D6D5425029C9B6B3CC71FE /* AuthenticateMethod.swift in Sources */, + 15C4C6B65F9A787FF4BC153F84FA6D38 /* AuthenticationSessioning.swift in Sources */, + C84A551AE92BEC69BAD42BF9EA9B3861 /* Blockchain.swift in Sources */, + 6953C194CA2FDBE1AB357C5B04477FF0 /* BloctoEnvironment.swift in Sources */, + EE061A69D6FEA3002D1409F9123784E0 /* BloctoFlowSDK.swift in Sources */, + 01CFAEF83800A868D12203969713532D /* BloctoSDK.swift in Sources */, + 93850E9620D3F3941A574C341895E235 /* BloctoSDK-dummy.m in Sources */, + 5801E6D9947415534B4CFA8BE07B3EAF /* BloctoSDKCompatible.swift in Sources */, + 59B4C57BD8E265F38A6FD43D66D36184 /* BundleExtension.swift in Sources */, + 385F07B7AF065FB0145F084A0C160256 /* CallbackMethod.swift in Sources */, + 4CEF5A22ADCE5D9EB050845407BFA422 /* DataExtensions.swift in Sources */, + 034ECEA0E580CDD41D6B5934B1EE6714 /* Error.swift in Sources */, + 47DD92D5DB6339143D1C2D6F90F2FE4C /* FlowAccountProofData.swift in Sources */, + 7CD2DE56E6CFC834C1CF672A21B71836 /* FlowCompositeSignature.swift in Sources */, + 5E6D8AC3B49F7D24358244E84DE04905 /* FlowMethodContentType.swift in Sources */, + 9F77F70AAEAD5899CD4281C3D239248B /* FlowMethodType.swift in Sources */, + E6DBD6C5D945067C315EEA87244D872C /* FlowSignatureType.swift in Sources */, + 39CFF7DEB8EE9CEA4BE583563FC68ABB /* KeyedDecodingContainerProtocolExtension.swift in Sources */, + 297C35DCB9740DB54850B2923B9C237F /* Method.swift in Sources */, + C201A9E63BBA5D8B51FA064382ED969B /* MethodName.swift in Sources */, + D3AAA0D0680BDD8506ADD0B6655868C2 /* NSNumber.swift in Sources */, + A2AD719965974E7B15C6FE309C96AF86 /* QueryDecoding.swift in Sources */, + D35ECA1C6DDCDB82AE5BB7DE6BAEBA64 /* QueryEscape.swift in Sources */, + 088AC8FD840686DBA147906488874B97 /* QueryItem.swift in Sources */, + C954E2D071119B440BAC0DAF015E28C8 /* QueryName.swift in Sources */, + 89B75DA0552BB2AD4F5E890D83268D5F /* RequestAccountMethod.swift in Sources */, + 23D3EADC91FC0602C3C8464C01DDDB9D /* RequestBuilder.swift in Sources */, + F5EDCE3262CA40B80D30F10E05F7227A /* SendFlowTransactionMethod.swift in Sources */, + 51A720B6500C8729D426923A3A3D173B /* SignFlowMessageMethod.swift in Sources */, + 5D896C5F7B9287C84768CFC751B0C9F6 /* StringExtensions.swift in Sources */, + 9D3C5746BEC51A55660EDEE3348389FB /* UIWindowExtension.swift in Sources */, + 3DFAA395226CA356B2BC563D68059218 /* URLComponents.swift in Sources */, + CE3D6F2CD88E230621989B156610545C /* URLComponentsExtensions.swift in Sources */, + 8F5CABA6FF150B55235821E71ED7984E /* URLEncoding.swift in Sources */, + 0CF5F5807C5CD694BC8A5C774175F223 /* URLOpening.swift in Sources */, + E875CE58DD62C146D1AA337206CC9845 /* URLQueryItem.swift in Sources */, + 4B455767CB398A52EC2EB47E43CC04F9 /* URLSessionExtension.swift in Sources */, + 1AE145736057FCBBD443FEC33A59A031 /* URLSessionProtocol.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 45A0E663EC6B027315DD54C45AFF0A59 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96614FB7F1EE44190975CF9D3775561B /* ByteCollectionUtils.swift in Sources */, + 6F196F59B8B71F355DCF7451CDFC33DD /* HTTPDecoder.swift in Sources */, + 86CB7870DEFF50D055C11996E955BB91 /* HTTPEncoder.swift in Sources */, + 9970473854F7AD56D1BBFF69BC342332 /* HTTPPipelineSetup.swift in Sources */, + 91A199FF2A2BB3FE5767716C4232DBB5 /* HTTPServerPipelineHandler.swift in Sources */, + 8808BCBD14114C8E254A61332ED4DC12 /* HTTPServerProtocolErrorHandler.swift in Sources */, + 296B3EB544FC567348D2DDD5E4A204FB /* HTTPServerUpgradeHandler.swift in Sources */, + 4941BBDC75993BC4EA64F2D71C4434E8 /* HTTPTypes.swift in Sources */, + 0907B00794FCDF0A327BB1F58BA6ABC9 /* NIOHTTPClientUpgradeHandler.swift in Sources */, + CADEF3031D0EA9FD1988ECD451452A7D /* NIOHTTPObjectAggregator.swift in Sources */, + 1566A4870F5204DB95F44BDD25EF21CE /* SwiftNIOHTTP1-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B6FB7A17469A2800E7231A1444746CB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 21D05279AA20EE7A1707A76C11BBCC00 /* NSBezierPath+SDRoundedCorners.m in Sources */, + 474163E6CF20CA1AC3698759F2B6D51B /* NSButton+WebCache.m in Sources */, + FF66F3E7374A9398D5B08AA23273BC0E /* NSData+ImageContentType.m in Sources */, + 994327308CC7ECE7850C804FA0EA5F21 /* NSImage+Compatibility.m in Sources */, + 9CEB5B454088D6BCC3A11C759A76161A /* SDAnimatedImage.m in Sources */, + 0C76BA74E22A5CFD8207C10026401D80 /* SDAnimatedImagePlayer.m in Sources */, + 24DA814C2F7EA7C4187E2BF0B6466E9A /* SDAnimatedImageRep.m in Sources */, + D88076DA0593D2835645CA5A92FFA37C /* SDAnimatedImageView.m in Sources */, + AA3AE0DF5E35D3E0D2CAE7972D69373E /* SDAnimatedImageView+WebCache.m in Sources */, + 4F5982101CB9FB68613E826F137B5E95 /* SDAssociatedObject.m in Sources */, + 498AB54D6531F0B57EAAD113AA0CF0F9 /* SDAsyncBlockOperation.m in Sources */, + 58FAE3A59FBE896EBBDACB0808067CA5 /* SDDeviceHelper.m in Sources */, + 275F99E74511043432C892810081DCAF /* SDDiskCache.m in Sources */, + 9D7EBB3A7377C116526B8A511F8CE245 /* SDDisplayLink.m in Sources */, + 2C762E5C654B718C19CC98FEB27C2DA4 /* SDFileAttributeHelper.m in Sources */, + B88C351562CE8FA4255EA9023213BE4E /* SDGraphicsImageRenderer.m in Sources */, + 854D7A4A2872566E4D06870518053225 /* SDImageAPNGCoder.m in Sources */, + 3015C91C523C5133A639F57DE0425100 /* SDImageAssetManager.m in Sources */, + D7D077F0FA5CAC32ACB65372453C701F /* SDImageAWebPCoder.m in Sources */, + 0D2B3D451D64A5A0AE5CE51E975D7494 /* SDImageCache.m in Sources */, + 888BEE4C3B238AC407C59D2194939AB9 /* SDImageCacheConfig.m in Sources */, + 138DFC533930F784B55D9BB8AACC0E06 /* SDImageCacheDefine.m in Sources */, + 4623448C58E0E271F0DF5F4CC6CAFD0D /* SDImageCachesManager.m in Sources */, + 78AE96580BD551EB905F72C21AB81E97 /* SDImageCachesManagerOperation.m in Sources */, + 64CDB33E49BDBE16653C88756E26B8CB /* SDImageCoder.m in Sources */, + E9CF46857D61D2A8AF4C3722C27C61C6 /* SDImageCoderHelper.m in Sources */, + DB68D9AFA817850ED9EBBE7F3F378AF5 /* SDImageCodersManager.m in Sources */, + 007F57C0030B0CA201A359FD816A3CE1 /* SDImageFrame.m in Sources */, + 164DEB7B33A09DD8663942511488AD16 /* SDImageGIFCoder.m in Sources */, + F0E28CEF30861F3589A4A662CEA76D80 /* SDImageGraphics.m in Sources */, + E33A7CDF3107CD3426ADD0D906100CD4 /* SDImageHEICCoder.m in Sources */, + 96479C9C76FDC513C03ADD58168F6911 /* SDImageIOAnimatedCoder.m in Sources */, + 536E9C0D3855A6AF7CADCB9FBAFC613D /* SDImageIOCoder.m in Sources */, + ABEAA41C35A6CD25C93E622FB129C379 /* SDImageLoader.m in Sources */, + 3F567CE353442AE137B71B258409F5DA /* SDImageLoadersManager.m in Sources */, + A9A87DA629538D239C4B7401EB56AEB5 /* SDImageTransformer.m in Sources */, + 61CD5A24511DC980EFF397CF57AC50F5 /* SDInternalMacros.m in Sources */, + 0D0AF4DF934B7BE39EC6E287B003BBA6 /* SDMemoryCache.m in Sources */, + 4075297FF5A21C84EF513521FD7B34EF /* SDWeakProxy.m in Sources */, + 0DEECB4887F8ED8A8304156D1C440639 /* SDWebImage-dummy.m in Sources */, + 67B0CAAD8E88B9A2357C41E73EA2EB48 /* SDWebImageCacheKeyFilter.m in Sources */, + 05102BD9E7BCB80DC7B64A34D0E7850B /* SDWebImageCacheSerializer.m in Sources */, + E4AF87F8012F919F00E2E8698A1A3C33 /* SDWebImageCompat.m in Sources */, + 49F97D8BA4E81A5E0EF866A293392AF2 /* SDWebImageDefine.m in Sources */, + D68F08F717E95BABFB43AE705D943426 /* SDWebImageDownloader.m in Sources */, + FE05A1BF611E69C94BC7A9EADBE10B2F /* SDWebImageDownloaderConfig.m in Sources */, + DE0BA471FB4FC10C0B25BDE4F22F5B76 /* SDWebImageDownloaderDecryptor.m in Sources */, + DB61822BEA875B413C858E1166590C9F /* SDWebImageDownloaderOperation.m in Sources */, + C27BD8C6B4E713A8E7B7B76B80E45823 /* SDWebImageDownloaderRequestModifier.m in Sources */, + FB359FC2B8375E01A8A8F84D3C50EE82 /* SDWebImageDownloaderResponseModifier.m in Sources */, + 5F49C3C9A3733CD50642E0B57D405D44 /* SDWebImageError.m in Sources */, + 343B53EB998CC5B609B8DE84BAD882E0 /* SDWebImageIndicator.m in Sources */, + FE4845B6FDD260059CDF9E26965CA31B /* SDWebImageManager.m in Sources */, + BE649A29E5FB32C54FDAE55994804F6D /* SDWebImageOperation.m in Sources */, + 7A424FED21A399FE2610DCB710A4A3FB /* SDWebImageOptionsProcessor.m in Sources */, + 62A22A4C10675F9B65C7677CFD6C4676 /* SDWebImagePrefetcher.m in Sources */, + 3B72C235C1AB8944333C2322F08B6B46 /* SDWebImageTransition.m in Sources */, + C55A2D001850D3F407D968CFF1C545E2 /* UIButton+WebCache.m in Sources */, + AE89C60F9CD4D6E1400DD304CE2A2B9E /* UIColor+SDHexString.m in Sources */, + BCB7B61DB37BA3EDB8CBBF258DC66446 /* UIImage+ExtendedCacheData.m in Sources */, + F497CD01EF6568475FD363A248D78A4B /* UIImage+ForceDecode.m in Sources */, + DEE74CD0E78DE0DB4056A8A3244B6ED1 /* UIImage+GIF.m in Sources */, + 412EE262DCED176A73591124DBDBA97C /* UIImage+MemoryCacheCost.m in Sources */, + 28532908E40E423052AA43B0000028BF /* UIImage+Metadata.m in Sources */, + 5B3271A67137276C4B2CD554BAB9F4DA /* UIImage+MultiFormat.m in Sources */, + BF9A6E2CB8F67686C4B7E04538664919 /* UIImage+Transform.m in Sources */, + C4762BD85B320B9EBE199F7CDFBCED12 /* UIImageView+HighlightedWebCache.m in Sources */, + 10E9E4249C8C22A571EBFECF3C0676CC /* UIImageView+WebCache.m in Sources */, + A3BFF0CDB72BC173BEA1C8ADDBDB0D1D /* UIView+WebCache.m in Sources */, + 429E5CC928985357D07058FDEE8069FA /* UIView+WebCacheOperation.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C69BAFCE046797C7D34FC1320D044B6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 482A850322C280BCE092BC0F5C8405BA /* CNIOLinux-dummy.m in Sources */, + B987BB03FB34EDB2F13027E000DD1C8E /* liburing_shims.c in Sources */, + 61C81E5D6706E0184347C7237B25F71C /* shim.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51F6B8026FB04C8C612A40D56DCFEC78 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D3608C860CF3B95CF1FF4FBD88C8702 /* c-atomics.c in Sources */, + AF30386438AFE8B05D07AAF32AE4029E /* c-nioatomics.c in Sources */, + 3DCA61FB5C526EC9D1E71B89C21FE248 /* CNIOAtomics-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 545CF28F6289A5FA10F79049C0C5DC66 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 734B4EC7674E9C9F6758ECD07FE3C180 /* a_bitstr.c in Sources */, + A01636DB38B55AB3720A0053D5D49385 /* a_bool.c in Sources */, + 0CC8665704F6A8B01419FE6216253EE5 /* a_d2i_fp.c in Sources */, + 30893A8858D646E8EA11BC475EFFC95B /* a_digest.c in Sources */, + F96058593FD3C9B8C55EDE66F17DE65E /* a_dup.c in Sources */, + B5B662BD5AECB16F053AABA331CE462C /* a_gentm.c in Sources */, + 0395305AF97DA05D29CFE7B9A4A17B4D /* a_i2d_fp.c in Sources */, + 1132612F1CBE48D6AFFFE14FF52DAB5E /* a_int.c in Sources */, + 0AAD61818F040DD52199FE3D1F6887E4 /* a_mbstr.c in Sources */, + 7C54E1A2F6000A4F5813E969FC21A7D1 /* a_object.c in Sources */, + C6A6BC0CCBA4E6B2CD5222E3A1DA0530 /* a_octet.c in Sources */, + C2DF6E0594E6D50A8304433BA8015BAD /* a_print.c in Sources */, + EB6552B2B6F12838F0A9B125CBA09B31 /* a_sign.c in Sources */, + E4C06CFB3944C30B9E6443AA0F8332C1 /* a_strex.c in Sources */, + ABB81BFFC4D7D91965AFE61F512BF09E /* a_strnid.c in Sources */, + 7A8325565E872462166C2858CBE78D28 /* a_time.c in Sources */, + 72203F70B7769F4CF61A67039D9C974D /* a_type.c in Sources */, + 8EA9B4893651C1EFF8E787FB4B1895D8 /* a_utctm.c in Sources */, + 2A5977387319C6D0D9004D924B3D6CC2 /* a_utf8.c in Sources */, + 4EB3F1296EE4B577E02B8651CB3B64E3 /* a_verify.c in Sources */, + 7EA11D8CEDC5B8E130108C1BB0E40D9F /* add.c in Sources */, + A18C9C5C94A51AF113FD6094ACD67D05 /* aead.c in Sources */, + 65A14A6524E0A8F1ABAAADBBAE0CC693 /* aes.c in Sources */, + E9FEC8C859AD5D65B9902141E1FF401B /* aes128gcmsiv-x86_64.linux.x86_64.S in Sources */, + EE6E9CCABA4265C11D11F4A7AB7E97AE /* aes128gcmsiv-x86_64.mac.x86_64.S in Sources */, + F4E9619C0FB0B826F231BD0F73BD2C87 /* aes_nohw.c in Sources */, + 7C2D7AA423F824E10814FA8944F4BBC1 /* aesni-gcm-x86_64.linux.x86_64.S in Sources */, + C3570531D80D2D9ACDABBDC4D9635265 /* aesni-gcm-x86_64.mac.x86_64.S in Sources */, + 7C650767C20B9F60821B50E278E52A13 /* aesni-x86.linux.x86.S in Sources */, + 70AD166AB8AE0891F544A819A74ED95E /* aesni-x86_64.linux.x86_64.S in Sources */, + DD63864BA12CADFC78FBBF1F3CA61120 /* aesni-x86_64.mac.x86_64.S in Sources */, + 24DDD7C28150C3900FB75B7247CBBB78 /* aesv8-armx32.ios.arm.S in Sources */, + 519D50F11F4EE3378085EE282D0894FC /* aesv8-armx32.linux.arm.S in Sources */, + 58AD1F9789AD2EF060E774EC081BDD75 /* aesv8-armx64.ios.aarch64.S in Sources */, + FA778E0BE842D3266A5A67148F90468D /* aesv8-armx64.linux.aarch64.S in Sources */, + 44F8FD88A3F44F423EC14E77188B3C96 /* algorithm.c in Sources */, + 3E36CADE9AB4FB5CA346B548082D5983 /* armv4-mont.ios.arm.S in Sources */, + E402D73132C9322E7C2D02FE319312A2 /* armv4-mont.linux.arm.S in Sources */, + BB68AACB02D968CDB668AAB5C10CA4BF /* armv8-mont.ios.aarch64.S in Sources */, + E2958FD405C58EC77AAF489BD273FBDB /* armv8-mont.linux.aarch64.S in Sources */, + 3E145E30FB5E9184B578974DAA1F3CAA /* asn1_compat.c in Sources */, + 4FE85020FA9539B37E30602C5096EE60 /* asn1_gen.c in Sources */, + 88BDF69E0C64309C5A931EEDD0C4193E /* asn1_lib.c in Sources */, + B91DE28186CBFD37620730ED7E3B3361 /* asn1_par.c in Sources */, + 2FCCBF31C63046E3838B248B451D2263 /* asn_pack.c in Sources */, + 8DC8B00F61A16E0E82E73044F488C796 /* base64.c in Sources */, + 521401BF1E6FA6B3BD67B4E8D286D68E /* ber.c in Sources */, + A17CA57E6FF0E55EC45BB7F5F83237CE /* bio.c in Sources */, + FB3AE837C059BFB7650B276B8F8CD451 /* bio_mem.c in Sources */, + 87DFFC20C5BC8A4C4B6F7022E45DDAC9 /* bio_ssl.cc in Sources */, + 285B49E1351B811C8532F9CD10E8DA90 /* blake2.c in Sources */, + 0194017B139DB8873A9ADFF6B144FC5A /* blinding.c in Sources */, + BC5441D127E656443122BBF1944E04CC /* bn.c in Sources */, + 88605D5BB9FF67780FE9099265F4B97E /* bn-586.linux.x86.S in Sources */, + 83B22A6C4E15D459E62089A9993B237A /* bn_asn1.c in Sources */, + CEDF770B414C9A0CD5A520E1EB5E2B0B /* bsaes-armv7.ios.arm.S in Sources */, + 41F230F2A6E6E050DC90A01861EE3B6B /* bsaes-armv7.linux.arm.S in Sources */, + 259D069DA9EE8D65896D9A58703D7103 /* buf.c in Sources */, + 96066E08B1D29D3170E3A211F1E35F1D /* by_dir.c in Sources */, + BFA1E1EBC7BB2E23BFCFD8D554705CAD /* by_file.c in Sources */, + E3CA4C3F4DBCD626BFF8E94107EF729F /* bytes.c in Sources */, + 4BBABCB240B62249A6070DF509A7DFBB /* cbb.c in Sources */, + 6A9204974B6B064E5798ED763F5ABFF1 /* cbc.c in Sources */, + B908EF2F4DD8AFF1520A554C5457885B /* cbs.c in Sources */, + C61E2AF98307341D5AA172CDFDAA94F2 /* cfb.c in Sources */, + 7D89B4B7D472B822D9309AF38498AD1C /* chacha.c in Sources */, + 973A1CD9F60908C9D6A024ADE16ADFB5 /* chacha-armv4.ios.arm.S in Sources */, + 49D5D7867AFA4533EF8193A80185AC8A /* chacha-armv4.linux.arm.S in Sources */, + DD358916DB501726FE37FEDC7ACB9729 /* chacha-armv8.ios.aarch64.S in Sources */, + 964AFDEC56EE52534D7199AD73F1C264 /* chacha-armv8.linux.aarch64.S in Sources */, + 65C4978314C56793A0D562632C9CE9CC /* chacha-x86.linux.x86.S in Sources */, + 5F119FF6E0035958CF98758B41801163 /* chacha-x86_64.linux.x86_64.S in Sources */, + 567B00754C874C109A355462560C2B67 /* chacha-x86_64.mac.x86_64.S in Sources */, + F38D12F5EE7BF7EE8686B0363A1DD433 /* chacha20_poly1305_x86_64.linux.x86_64.S in Sources */, + 5269E0AF4A9F6CBC34F5D7B8C45AC27F /* chacha20_poly1305_x86_64.mac.x86_64.S in Sources */, + F695D5DB77B445476619C25ECBA5DAAF /* check.c in Sources */, + 646F4915348FA769874FCF303A424AC5 /* cipher.c in Sources */, + 046FBC08EC8BAFFAB07821A38567E912 /* cipher_extra.c in Sources */, + 6917678919D98CAE2E6EFAFA82A6C2A2 /* cmac.c in Sources */, + C03E4D92BFFDB72F250853C5D099BC04 /* cmp.c in Sources */, + 7A7114736B9A1E24DEFB43290E7ED0F4 /* CNIOBoringSSL-dummy.m in Sources */, + 127B1F9A311B5FA87E6FE241915DB1DC /* co-586.linux.x86.S in Sources */, + F0CA93246FD5CEB9AC2224751F3BFE33 /* conf.c in Sources */, + BE8BA963210EB262B1520E9E522CB212 /* connect.c in Sources */, + 5B4A9D9A0F84E0C13B7C112AB24F0F28 /* convert.c in Sources */, + 200988C51A16062694059EB7B9E86BE0 /* cpu_aarch64_apple.c in Sources */, + B9BD8B8855D4A37EF85675FB83C8DA78 /* cpu_aarch64_fuchsia.c in Sources */, + A527902D8FFE632759BB39C077636C17 /* cpu_aarch64_linux.c in Sources */, + E83EB1766BA2756C9C5C3F918BC9F60D /* cpu_aarch64_win.c in Sources */, + F67378DA034C55276DE7FE8033D5A644 /* cpu_arm.c in Sources */, + B381279C5D0A624F6C4DC88B82103394 /* cpu_arm_linux.c in Sources */, + FB75C35AE50C5817BF46DE52DF48AE2F /* cpu_intel.c in Sources */, + 52D559F996AE40546BC6B29632614E63 /* cpu_ppc64le.c in Sources */, + F81C75E02116969FBAB72B27EA9087F4 /* crypto.c in Sources */, + 329398D9FDCC749115DAFCDFBD89BF4E /* ctr.c in Sources */, + A96ACE11F57CBE08CC0E5D09FF847644 /* ctrdrbg.c in Sources */, + DA46C610786FEC6A0B86A749120F1316 /* ctx.c in Sources */, + 89B5B1919789E937E0E81B78DCC600D8 /* curve25519.c in Sources */, + 77FFE2CBD5EF02249C01167EAE986A25 /* d1_both.cc in Sources */, + 7DEC1F9B1F85EACD3BFA4F07610D0E51 /* d1_lib.cc in Sources */, + CAE7E576E76FC8A5CBFA243957D375CD /* d1_pkt.cc in Sources */, + EF3E28CB5B5B3E834B9409BE1CB36B7B /* d1_srtp.cc in Sources */, + C54F0EAE413A390A7724FB77B2DF7C17 /* derive_key.c in Sources */, + 66D84E2A8E11B5A129331D777D1598BE /* des.c in Sources */, + A91B62F5DF8EDEBE2821D2AFBFF25306 /* deterministic.c in Sources */, + 061F08E035EF8433CE03F9D596BAD2EB /* dh.c in Sources */, + 788148D1C9E6AA37BDD8031228B5D072 /* dh_asn1.c in Sources */, + B41B0AFF039DE2739E9F782FF7755C89 /* digest.c in Sources */, + 5154CF227555E61F584EFB393DC39E33 /* digest_extra.c in Sources */, + 04692774557F353CAD0317AE56854CDC /* digests.c in Sources */, + 85078DEC8913D55AFFB15E9D6026CACB /* digestsign.c in Sources */, + 5CE971EFB830145250E66CACC6EF6B9F /* div.c in Sources */, + 45923B7EC01C7C652B67FE34763304D7 /* div_extra.c in Sources */, + 28F974FBE5AC1D2A4FA83F5BEDB1A1E9 /* dsa.c in Sources */, + 5432647F174FD713AD006C79866D2F50 /* dsa_asn1.c in Sources */, + 32F801AEE6075762594F689998CBFA77 /* dtls_method.cc in Sources */, + DCECA9BC622223C915D47B526558A28C /* dtls_record.cc in Sources */, + 5E05762975DDE5AF60856D7B2E83AA3B /* e_aes.c in Sources */, + 124F4DB8BA6D77FC4F6AACAD9594AD01 /* e_aesccm.c in Sources */, + 2387BA6A9FA73DE59088828AA79AE2A3 /* e_aesctrhmac.c in Sources */, + 1DED1CCBDC985A2E5624B2AC121DF103 /* e_aesgcmsiv.c in Sources */, + 1DE947B834ED9E7DB45C0C490B12B4F5 /* e_chacha20poly1305.c in Sources */, + F4E97401322A30BBB4BAEFB5D96A6E8E /* e_des.c in Sources */, + 86301403B7C3EE7CD7A74549DB13AD0B /* e_null.c in Sources */, + 2D2A975AC241C8648DA36B497D271526 /* e_rc2.c in Sources */, + 78E0841EBEDB9D23315EF9C4AD0622BE /* e_rc4.c in Sources */, + 3A442DD3A0079E4599068BB0B7C2B604 /* e_tls.c in Sources */, + 21F0615E77BA18091AE7AEF63C0E344F /* ec.c in Sources */, + C8DE48466E0FB1A680E386533D4565D6 /* ec_asn1.c in Sources */, + D659BF981D133BC6B6965F20B3615967 /* ec_derive.c in Sources */, + 3BB15EE818B40E814B6F57F41801D205 /* ec_key.c in Sources */, + 4B0CFBD848C6E74B26D2728487E9DE32 /* ec_montgomery.c in Sources */, + 0300545CAC1E40D94149E4A311BE5F3F /* ecdh.c in Sources */, + 2A58E784F4CBFDB27CB892BF47772782 /* ecdh_extra.c in Sources */, + FDD69F9D6A002DF8F252ABE0E067BE29 /* ecdsa.c in Sources */, + 99A91CCDCD7E7195569A50F0AF71DACD /* ecdsa_asn1.c in Sources */, + 7CB758EEFCC854A88FE9B50A79046D5B /* encrypted_client_hello.cc in Sources */, + 5752D404DFD7D35214D328F5954B2F5C /* engine.c in Sources */, + A49822680868EADD918002A03FDB316E /* err.c in Sources */, + 6C148C90EDC036C4160D5A80FAAFF1B1 /* err_data.c in Sources */, + 0DA1F39FF87097B001CA65CFF4063698 /* evp.c in Sources */, + 705ACB6C225D1E6B5F594ED1CC53FA22 /* evp_asn1.c in Sources */, + F8F76CBCF6687AF4CCC81B2AFA104D05 /* evp_ctx.c in Sources */, + 04471B662ED2959F6D46382162B6001C /* ex_data.c in Sources */, + DBD4BFBC053F0FE4522C6C96AD6E6813 /* exponentiation.c in Sources */, + 2066A39A9CFCC4A4AD22AD2E7EE8C781 /* extensions.cc in Sources */, + F952C2CC4645B301C4713EF243482A76 /* f_int.c in Sources */, + FE045CC1A836EE919908F461FAB4D88D /* f_string.c in Sources */, + 143CAE0E207112691002259E1FA9E152 /* fd.c in Sources */, + A4E9C0DA3D34D2E1F620D97CF180C9AF /* felem.c in Sources */, + CD39817695A4DA222FF2C21FCE11A1DA /* file.c in Sources */, + 05F2AE75BFE10AC23A1F3F251F86522B /* fips.c in Sources */, + 2CEA645D742EF2C864D1078945C4C9B3 /* fips_shared_support.c in Sources */, + 8EB713CDA5720AC9AC3CAC0D516E5F65 /* fork_detect.c in Sources */, + B8227C8AFCB69A1C642A9173CF871D2F /* forkunsafe.c in Sources */, + B2E403326D98D74B8F834D9B8411B058 /* fuchsia.c in Sources */, + C9CDDC9606B4064A0C2F375F7B96E0FF /* gcd.c in Sources */, + EBBF5E2E2068B7C1A8C3BA7E2E5A7DDE /* gcd_extra.c in Sources */, + E85B446B6BE0049275FCCDC69B9654F0 /* gcm.c in Sources */, + ED7CB46FE083BBF78F85985512CBCAEF /* gcm_nohw.c in Sources */, + 75468FA6F8EA0A51CD41F8C7DEEF1A4B /* generic.c in Sources */, + 86D8584BE5FAFD616E4547BAD669DACD /* ghash-armv4.ios.arm.S in Sources */, + 9A649C40075F0E7A01D3A39B47E34E12 /* ghash-armv4.linux.arm.S in Sources */, + C338246650DC5F473FAD560883706248 /* ghash-neon-armv8.ios.aarch64.S in Sources */, + 231A6374BFDF710A48C2427EF40466D2 /* ghash-neon-armv8.linux.aarch64.S in Sources */, + 29D4AEADB1E6B2C2FADA9CAF5016CEEB /* ghash-ssse3-x86.linux.x86.S in Sources */, + AB362E1D1899A06B9A83F6B6D74BEF5D /* ghash-ssse3-x86_64.linux.x86_64.S in Sources */, + 918162E4377088ADD539EA01D60D6F32 /* ghash-ssse3-x86_64.mac.x86_64.S in Sources */, + 3C74F74B2437F0528188E8CF2C2FDFA3 /* ghash-x86.linux.x86.S in Sources */, + 82A2B9AD57B62BD2C0BC5DBEC3594CB8 /* ghash-x86_64.linux.x86_64.S in Sources */, + ECA67E92E03378D0E6A42C72F6067970 /* ghash-x86_64.mac.x86_64.S in Sources */, + D0D2E9D1C53C43F8E38BD0808AF49EA1 /* ghashv8-armx32.ios.arm.S in Sources */, + 9A930E3136F8C7A0EF07AB176345845A /* ghashv8-armx32.linux.arm.S in Sources */, + 08B9F65055E30C44AC9BBFAA2EE60AAB /* ghashv8-armx64.ios.aarch64.S in Sources */, + 0AF0B58C7A9F95CF47D0BB6FB75F6FF2 /* ghashv8-armx64.linux.aarch64.S in Sources */, + CAD9303799AFE797D36BABF4BCF117E7 /* handoff.cc in Sources */, + 622D4C39D9B07E268931459D70F8B43C /* handshake.cc in Sources */, + 0A1E9D524309EC4E97C5631075641265 /* handshake_client.cc in Sources */, + B4F4F64C189CD5FA3DE41E955B38FCA1 /* handshake_server.cc in Sources */, + FF0A5DBCC4A8FF9B7A1BD8AC530D601E /* hash_to_curve.c in Sources */, + FDBBA7A2C479E21F8CE7A8B523B4AAF8 /* hexdump.c in Sources */, + A13BC77BD45A2B0F32400EF94A7F928D /* hkdf.c in Sources */, + F485AD8EB9C160D3E4253726C2F93909 /* hmac.c in Sources */, + 3C0A8F7F9A1899CAE1E39801A1760C46 /* hpke.c in Sources */, + CE0C4C6147B74217171C6225159A0A50 /* hrss.c in Sources */, + B58FBDD4A8D7B7ADC8863413094D4A3B /* i2d_pr.c in Sources */, + 6EF3029DB9EEC014CB1DCBEE0B1B1BA9 /* jacobi.c in Sources */, + AAD011FB4574B6E2B871A4B4DE866F03 /* kdf.c in Sources */, + 67A7C4A010994278ECA06D32770C5A12 /* key_wrap.c in Sources */, + CF94AD566889FEEA32BB5E9076B1CF57 /* lhash.c in Sources */, + EB80442999C84C1038422C0EDA69B6C7 /* md4.c in Sources */, + 7D2B8A81C9C8DEA2581AB7AA2779DB65 /* md5.c in Sources */, + 8F5BF5ADFD3D622FF01DD8201CF54CCA /* md5-586.linux.x86.S in Sources */, + 3D428FEC4A3AD3F5BC720208D9FA3C2A /* md5-x86_64.linux.x86_64.S in Sources */, + DF45F7F2696065FAC74D56742C3F1AD8 /* md5-x86_64.mac.x86_64.S in Sources */, + 097F302ACF6C4556451C8555F57EF9DD /* mem.c in Sources */, + DD997A01C8E0B39974B40004F87B26C8 /* mode_wrappers.c in Sources */, + 85B4F3C13C829CA99A2EA551F5B26F6F /* montgomery.c in Sources */, + C8471B00E86DD75DC0245CDE589FD1B1 /* montgomery_inv.c in Sources */, + DAEA293A91F3E49D3F2B0A1155FD5302 /* mul.c in Sources */, + CB890B97BC4C6D4004BFF98A965F67F0 /* name_print.c in Sources */, + B58F2FC64967DFD9BF01AF85664E90BC /* obj.c in Sources */, + BA354A3C3E0FEDF3D5B0556BE7E9A55F /* obj_xref.c in Sources */, + B832FC757137322A12712A3C4BFF509C /* oct.c in Sources */, + FF82B869A9DEC533A4ABE96F83E5A90C /* ofb.c in Sources */, + 34D0B67BCA0134CA6B02C42A18F50EC3 /* p224-64.c in Sources */, + D51906689701B3B3C93BF5DDE805A0F3 /* p256.c in Sources */, + 4A98BF03DBEA2BDEAD0B3ECCC3975F0D /* p256-armv8-asm.ios.aarch64.S in Sources */, + 60AC910D52240D2F812E608BDAFBAA35 /* p256-armv8-asm.linux.aarch64.S in Sources */, + EA1A875D165EE690AD246CF9C6F3617A /* p256-nistz.c in Sources */, + 3C646DD6A481FDBACA0F87F5F6FC03DD /* p256-x86_64-asm.linux.x86_64.S in Sources */, + B08632DAF109AEC509A3390757380A6D /* p256-x86_64-asm.mac.x86_64.S in Sources */, + 3E412DFDCB98BAD9E439CDBD68D953E0 /* p256_beeu-armv8-asm.ios.aarch64.S in Sources */, + 91A1AD329755A01C1DF443F8ACA0DB08 /* p256_beeu-armv8-asm.linux.aarch64.S in Sources */, + 8330C9043C7E9AFD44AA4A2C17F99DEC /* p256_beeu-x86_64-asm.linux.x86_64.S in Sources */, + 77D5C61D0768726297CCF2021E90A72A /* p256_beeu-x86_64-asm.mac.x86_64.S in Sources */, + 36B22E86B2BFF233749B736F3F2AA409 /* p5_pbev2.c in Sources */, + D81334DB8948DAC08260FA3D7D3DE705 /* p_dsa_asn1.c in Sources */, + 3A5C01C51285F5FFD051261823BDAC3D /* p_ec.c in Sources */, + 3F014C9233DA4A9519754870B00CB6C4 /* p_ec_asn1.c in Sources */, + B2264B5C3C3B0BC8671968E961F1BF02 /* p_ed25519.c in Sources */, + 0F31EC3D670E860E870C1E9F0AFB8870 /* p_ed25519_asn1.c in Sources */, + ABB53A30025655067FC1A3ACC2F688C7 /* p_rsa.c in Sources */, + 0E08DD80DD1102D9AA553B648A2F22C6 /* p_rsa_asn1.c in Sources */, + 1B311E005DC1E098D108A7E529F71DD7 /* p_x25519.c in Sources */, + 9A42D6F18A35749F78972DCF68E54E0F /* p_x25519_asn1.c in Sources */, + C57BCD825F6491DC5DCA9FBF9D239B8A /* padding.c in Sources */, + F54EB5C3506F5A9E1947441BE850B2A6 /* pair.c in Sources */, + CF5629FF0DFA9C0A78566093B28B5FAA /* params.c in Sources */, + 3AC3AD7FD0C399B65CD6C018C51816C1 /* passive.c in Sources */, + 39B08B0FE49C78AB4BCC889D37916B52 /* pbkdf.c in Sources */, + 48A8A612910DD25151B7DB44BB66D3FA /* pcy_cache.c in Sources */, + B247E23747DCFDECABA4475BD5C178D1 /* pcy_data.c in Sources */, + 826A2744ADC1B1435EC7E63F3C2C7FB9 /* pcy_lib.c in Sources */, + 9D3380488D2648776C64EC2AA8F75955 /* pcy_map.c in Sources */, + AA1C68A34DFE6909AD17E03D4D02804E /* pcy_node.c in Sources */, + 8A3B5CBFC8D8D6661597CFFF81583013 /* pcy_tree.c in Sources */, + 6373D7EBE71A274FA0B3E7C2AF9B18C9 /* pem_all.c in Sources */, + FEE735CEDD647C3E76C437CEBF95CFA7 /* pem_info.c in Sources */, + A49766AA6A5500618B4200B22531AB4A /* pem_lib.c in Sources */, + C943D9B8DC4F913A671DB05F6B87CA1A /* pem_oth.c in Sources */, + 7B386053FC82368502E8411EF6AF9B98 /* pem_pk8.c in Sources */, + DC3593C40C4B7A8FFC62DE36FF21C783 /* pem_pkey.c in Sources */, + D5ED75505B2886AA29E4A1EBA912653E /* pem_x509.c in Sources */, + 018689E8C966BB153C0315D1BB756FEC /* pem_xaux.c in Sources */, + 5F4DFD9C2AAC52263A18763910088A77 /* pkcs7.c in Sources */, + 70D4769F68D38AE475B80AC65508BA86 /* pkcs7_x509.c in Sources */, + 2E77466B99CF36A7A6B7F51E30EBA1D1 /* pkcs8.c in Sources */, + 52E4D58F0CF4344DAC0637B9B5B75BCC /* pkcs8_x509.c in Sources */, + 50CB192CA68D75DE5F793D0BC87F166C /* pmbtoken.c in Sources */, + D1E33B121B8325A062BEEE4CA67CF77F /* poly1305.c in Sources */, + F1796E85F14F1B07352AF9A86DB70F2B /* poly1305_arm.c in Sources */, + 54855934F4CB99C4C12123DE349A1D5F /* poly1305_arm_asm.S in Sources */, + DA1719C5308D83A4CD7819F1C6032539 /* poly1305_vec.c in Sources */, + D28123212117C581CE08AADC49E61955 /* poly_rq_mul.S in Sources */, + CA59BD4AD06D1BB7CB263A2E7E3CCC7B /* polyval.c in Sources */, + 70B19CD939C0082AD128D6463E73F3E0 /* pool.c in Sources */, + 01B74DCA125ECE14E3A51EFEB874D672 /* prime.c in Sources */, + 169CC102186A230162AD42AF6E5EAECC /* print.c in Sources */, + 52393A042FB7C220709E5817F08479A5 /* printf.c in Sources */, + 7541E0891E941376565E648C3706C284 /* rand.c in Sources */, + 8FCFBD2B16B6D35BAA395B750BA68F2B /* rand_extra.c in Sources */, + 825C5A3D82A91C028A3FD640AE8850CE /* random.c in Sources */, + 4E1BF46BB4A52452D22D37E79A7E60D2 /* rc4.c in Sources */, + BA5BADC02C792DC56412C1E88E2C933B /* rdrand-x86_64.linux.x86_64.S in Sources */, + 07BE74CA6DD87E9C114CC07B87A25692 /* rdrand-x86_64.mac.x86_64.S in Sources */, + A0057ACF8EE5EE1267DCD9399D4B585F /* refcount_c11.c in Sources */, + 25D8592E215821E151A76E4FA989A921 /* refcount_lock.c in Sources */, + 8E639D361F0B893AB4CA53013E5D0117 /* rsa.c in Sources */, + 6A75628664126A13B3357EA0F6475A99 /* rsa_asn1.c in Sources */, + 7285377A3D573AD10BA6ADBD4F88B87F /* rsa_impl.c in Sources */, + BBC8DDB19BF1C2F7730EE3D70F6898F8 /* rsa_print.c in Sources */, + C009A108BCA10592B4D3A3496F431498 /* rsa_pss.c in Sources */, + 2555E359F9B41AEB322F1D047446FD2E /* rsaz-avx2.linux.x86_64.S in Sources */, + 3F5A9C6722CF24A67082F4FDA44A3A07 /* rsaz-avx2.mac.x86_64.S in Sources */, + 269B387FBBE2EAA2FE9B1CFF3AA09B3E /* rsaz_exp.c in Sources */, + A7C03AB52CB4FC6A80B8746A4AF6A342 /* s3_both.cc in Sources */, + DF0FA751B12587DEF6AB8115D1CAD804 /* s3_lib.cc in Sources */, + D5C931A7EE31E76793DB60F0BAE03706 /* s3_pkt.cc in Sources */, + AF42E7AC19979D422B1ED9FED09D93B1 /* scalar.c in Sources */, + 288C4A9BE0B5B805FDED2A667D70CAB2 /* scrypt.c in Sources */, + 4D756B1039718931B1EB6E3F93334FF9 /* self_check.c in Sources */, + E17DDA2A7D35CCEA2F859C72AFE9F2AE /* sha1.c in Sources */, + 11281D1803D4FF95259EA1860F54E518 /* sha1-586.linux.x86.S in Sources */, + EF1C79757D7C7A5BCCE5C67B0D33D8A7 /* sha1-altivec.c in Sources */, + A9280CD3EA6149283C4BBB508CC7E261 /* sha1-armv4-large.ios.arm.S in Sources */, + C5D4FD6E526D4804CB9BBC71A034EEF8 /* sha1-armv4-large.linux.arm.S in Sources */, + 9E537E197FCD26894A560695CA14818E /* sha1-armv8.ios.aarch64.S in Sources */, + FB30E0EC31F7BF815E935CD587DA5FB4 /* sha1-armv8.linux.aarch64.S in Sources */, + 9466136BC831A90F33B72499E2ACF0EB /* sha1-x86_64.linux.x86_64.S in Sources */, + 2325FCFA2B1B805C609CDB7C9F746E17 /* sha1-x86_64.mac.x86_64.S in Sources */, + D6F57F85DEA67C9E358001DF97436C96 /* sha256.c in Sources */, + E60BBB0218ABDD03C08F66CD9973A5DF /* sha256-586.linux.x86.S in Sources */, + D0B11036AEB4E11E3B1ECA363C58947B /* sha256-armv4.ios.arm.S in Sources */, + 5D2A6D9E8022EA39F8D102FEE7426452 /* sha256-armv4.linux.arm.S in Sources */, + 7E741B3269431A5DF6F48D618BE5D41E /* sha256-armv8.ios.aarch64.S in Sources */, + 290FDBE7D9B49AD40EDF8ECCC88D11F5 /* sha256-armv8.linux.aarch64.S in Sources */, + 27E62EB5E6BEA87C00B242C2C8F22833 /* sha256-x86_64.linux.x86_64.S in Sources */, + 76EB4E7E1EFE7CAF58C31A1AF94B32ED /* sha256-x86_64.mac.x86_64.S in Sources */, + 6F5A9E4BF5C6100234CBEE4AF697B8EA /* sha512.c in Sources */, + 014E6A106AA72977A9B23E50F1040CCD /* sha512-586.linux.x86.S in Sources */, + 7FA448714DD89FE8A240BE8E50FDB770 /* sha512-armv4.ios.arm.S in Sources */, + 08A2249E3B535AC87503E0C8AD5EA581 /* sha512-armv4.linux.arm.S in Sources */, + 69EFCEB36A220606180FDD81F3F314F9 /* sha512-armv8.ios.aarch64.S in Sources */, + A40BF33478C497D5D4C1B2A835BE3D3C /* sha512-armv8.linux.aarch64.S in Sources */, + 21E4953C3C05B96B90C4813EA94851B5 /* sha512-x86_64.linux.x86_64.S in Sources */, + E24C390EE50EC6E285E377002E0B7353 /* sha512-x86_64.mac.x86_64.S in Sources */, + 0BF9362C02368CBE135D13C89EC81632 /* shift.c in Sources */, + 1D199B3D7405201C26BC49047210A4A2 /* sign.c in Sources */, + 2E873556BA959B32C3A09E123454A225 /* simple.c in Sources */, + 3392445932E97CE330EBD08732B22E65 /* simple_mul.c in Sources */, + 585384668E02C5616D34FE90841E416A /* siphash.c in Sources */, + C3DEE99279FC4719801242BD2F629FC9 /* socket.c in Sources */, + 61D922EE85D8CE18443233D34D07ABBA /* socket_helper.c in Sources */, + ACE606619281328C18BE78506D37587D /* spake25519.c in Sources */, + B420CE9CA1710BA4AC944CE59B4B4BF4 /* sqrt.c in Sources */, + ACF1D580603432F23AE87E1DB8BFED8B /* ssl_aead_ctx.cc in Sources */, + A1EF6E033E2D73A89B6E26D1F5A5498B /* ssl_asn1.cc in Sources */, + 8C1AA1579F53FB71B287AB0F5BAC261A /* ssl_buffer.cc in Sources */, + 7E99F1A8DAFB235473CEE29B80B6C988 /* ssl_cert.cc in Sources */, + 991D00F3C0F86EBDBBCA96D379C12DF2 /* ssl_cipher.cc in Sources */, + 4E5F8F25AE9C665A1B68F7DBBA87940F /* ssl_file.cc in Sources */, + 9602632D44D14CAD9C199F579C7FF561 /* ssl_key_share.cc in Sources */, + 34C942CECDD821753DC991C863A649A8 /* ssl_lib.cc in Sources */, + D2765EBF4CFFAC92693C0427C04EBF51 /* ssl_privkey.cc in Sources */, + 029CDC517DECF5D8316C2D20AD9058E0 /* ssl_session.cc in Sources */, + 58228B08AEC1167F0FC1465776665F9A /* ssl_stat.cc in Sources */, + 2925AD48C2EAA347D02CD1C81F2BF2F5 /* ssl_transcript.cc in Sources */, + F3F0878161819EE96DAAB97A955681B3 /* ssl_versions.cc in Sources */, + 1F2E1C81716EE2989CF74352602BA7C0 /* ssl_x509.cc in Sources */, + 2174577CF2427A10DA8EABCFE645184D /* stack.c in Sources */, + 4867A79B1558BAEF4BD4C3D5EC042A8C /* t1_enc.cc in Sources */, + 21DCD6FAE0686F2BB8E6F29189259C9B /* t_crl.c in Sources */, + 1D95F578A3D2278DB2F9FBF41CA57A34 /* t_req.c in Sources */, + 4817F4C6195F7000116E4A850A701C17 /* t_x509.c in Sources */, + 75114F16237DD8B62054DA37AA290821 /* t_x509a.c in Sources */, + D2C0EAD724728C5289C0D55B30F49B90 /* tasn_dec.c in Sources */, + 2422BD14FC8BF0EC43C0EB38C8AAA01C /* tasn_enc.c in Sources */, + 474EE6CAD4486F21F08B52EB7557F443 /* tasn_fre.c in Sources */, + 9FA73BFE060AFF50C64519A75A5574D2 /* tasn_new.c in Sources */, + C4DA7CF646C65783D9A7A79DD5F0F24E /* tasn_typ.c in Sources */, + FBF9F0B0B8CBB6211734394125177E84 /* tasn_utl.c in Sources */, + E3AC342DC87C6BAA7EF8F79C2FE9B455 /* thread.c in Sources */, + B5A1D2506138A3312BBA4444388B840D /* thread_none.c in Sources */, + F41F82E9D51C50FD12B0785DE02DE71A /* thread_pthread.c in Sources */, + 8EBC581D15C60F56D9B741B35111EA28 /* thread_win.c in Sources */, + 0FC7A9F8C69F1C0912FA4D1ABF53F919 /* time_support.c in Sources */, + 94939BA9762C72B225D04F935C667F8A /* tls13_both.cc in Sources */, + 526E5E8A0138F67AE41A49DE2D02D737 /* tls13_client.cc in Sources */, + ABA5315129C1DCFCAD315B9973B732C1 /* tls13_enc.cc in Sources */, + 211881A545C6CDEA8F31F068506F424B /* tls13_server.cc in Sources */, + 05FD6418BFC3AE594DFB95895A1F19D1 /* tls_cbc.c in Sources */, + F319BA905F2230077F909C723CFF0F7E /* tls_method.cc in Sources */, + 33A70DD42AA65918B521426786DD817F /* tls_record.cc in Sources */, + 6D315B3E273D3557B8321C25270D4399 /* trust_token.c in Sources */, + D847E99BFD8C95B9A7C7619D0C871778 /* unicode.c in Sources */, + 43D89640DA44BC448AF1169EE744892C /* urandom.c in Sources */, + DB6449B04301AA8589453CCF85E23EA6 /* util.c in Sources */, + B5BF1D01D17BCEFAC594BD0AA2FEA001 /* v3_akey.c in Sources */, + DE241BC1AF468AD74758AFBA2D7D0485 /* v3_akeya.c in Sources */, + 1531AF560743A1A162C7A9F151976FE9 /* v3_alt.c in Sources */, + B26B94D74111CD5B59D48AB1E91141D8 /* v3_bcons.c in Sources */, + C1514EB1781043AFE7AE81B3730B49BA /* v3_bitst.c in Sources */, + 307D23D086096B219F62664F1B7E4944 /* v3_conf.c in Sources */, + 28CAC0777930D9A1AF954AD2AFEEBAB5 /* v3_cpols.c in Sources */, + F52DC6DD05D02987E451BDD8658809AD /* v3_crld.c in Sources */, + CF9DCD561FEB5404D65B09EA77C1D688 /* v3_enum.c in Sources */, + AA16C3F0B3D3178D62016E5FBB5E4A22 /* v3_extku.c in Sources */, + 31F60D97F4140D2AF8211F1949778527 /* v3_genn.c in Sources */, + 363CBFF46709F7C4175D1678769B39F2 /* v3_ia5.c in Sources */, + AB746F2E2A6E7B18964CF833F37A76EE /* v3_info.c in Sources */, + AA14752B985943EBA724A69DF73AF9BE /* v3_int.c in Sources */, + 3A8D49922B5DB2E5D54D7F90439231BC /* v3_lib.c in Sources */, + A3CD0A59293810E0DAE3DACFDA19721E /* v3_ncons.c in Sources */, + C9E4E81122FB77A6DF9E881B669F1AEE /* v3_ocsp.c in Sources */, + 33FE5DA9B7C3359A372C8FE50DAB3F89 /* v3_pci.c in Sources */, + 2BC5609552C6B8061F1409B996F44C31 /* v3_pcia.c in Sources */, + 8AD812A36A3F45945EBE15FE7B305554 /* v3_pcons.c in Sources */, + 00A70E59F0BDDD533B3BE0D5329ADC57 /* v3_pmaps.c in Sources */, + EB5F55D277062C3DA392ACD464EF4CAA /* v3_prn.c in Sources */, + DDD928B3278BCFF21AA132CECAAD5F65 /* v3_purp.c in Sources */, + ED6049663DBF4B471880F7DC46212E27 /* v3_skey.c in Sources */, + 60543A3F48C7EE855FBFAC85E1506798 /* v3_utl.c in Sources */, + 9B99B4CE0D78F2E353153F4EC9920E12 /* voprf.c in Sources */, + 3E049E682EACE80B60B2F8D2B7F5F420 /* vpaes-armv7.ios.arm.S in Sources */, + A2FA9BF500E5A97AEB0882F62552B00C /* vpaes-armv7.linux.arm.S in Sources */, + 0DFA9A7F143EEC14262713FDA3C0D379 /* vpaes-armv8.ios.aarch64.S in Sources */, + B0DEC1B63B3731DF4D49CE1157DC2A9E /* vpaes-armv8.linux.aarch64.S in Sources */, + 77F4CE4F8D2670B1377B055907A0E585 /* vpaes-x86.linux.x86.S in Sources */, + E677C65A67EE379C522DE165EA429C89 /* vpaes-x86_64.linux.x86_64.S in Sources */, + 740B0F616D146B2AAA987EAD3D744ABE /* vpaes-x86_64.mac.x86_64.S in Sources */, + B0C202C52318CC3232B8B6997F6BC616 /* windows.c in Sources */, + 38D4225ADD3AD2E23B7F980267500E0B /* wnaf.c in Sources */, + BAED169CF9230E5C3F0AC939B8B6FB7E /* x25519-asm-arm.S in Sources */, + 7C589253D3B0E83C2102556792F9C818 /* x509.c in Sources */, + DF527586940E1AE495029DDC2E60E665 /* x509_att.c in Sources */, + 219AF511E706D6051A3D797DCBB638E6 /* x509_cmp.c in Sources */, + 1B04A7272BEEDB0ABAF2DB20B0753366 /* x509_d2.c in Sources */, + FB56162BEA8AF3084D83EC769AF6BF82 /* x509_def.c in Sources */, + 4CA0EFA43FDB50F927904E64D5AF57DB /* x509_ext.c in Sources */, + A00ACDABBB125650F881E13AAC80EE4B /* x509_lu.c in Sources */, + 67481BFD0E0E3FBEE77814B7995D1067 /* x509_obj.c in Sources */, + 5ACC86B4D6F34E04125A0D77F340BB3B /* x509_req.c in Sources */, + 2DAF67AC29A7DB0A656B356746BB4D81 /* x509_set.c in Sources */, + A2BA17FF4D685C9DBA81F6DBC60B940C /* x509_trs.c in Sources */, + 3F5909D48C8883BB1EDCF3A5696954E1 /* x509_txt.c in Sources */, + 3FB12D1C256B8D1BAE15BF19E4163EB5 /* x509_v3.c in Sources */, + 90E1B9CA712F3E3D19C34AE551582040 /* x509_vfy.c in Sources */, + 25EB52D099A4E7AB47C440FA84516CA1 /* x509_vpm.c in Sources */, + 2366665EF870073B6400837985BD8160 /* x509cset.c in Sources */, + 1B5271914E05BA88A006D8F0E1FD01AF /* x509name.c in Sources */, + 566329068166F7AC2F01D0E9794B67A2 /* x509rset.c in Sources */, + D26627EAF46CB6E53DCBCF96B6797E5B /* x509spki.c in Sources */, + EE8A7D3D1CC460B7209D2E36A76AD4D4 /* x86-mont.linux.x86.S in Sources */, + 5743C484AED63266D4D78E4A4C74DDCF /* x86_64-gcc.c in Sources */, + 83F49E49512DA20AED17D6F3C48DE63A /* x86_64-mont.linux.x86_64.S in Sources */, + 10EE7669F20D37F8576CB7B68DD21D1A /* x86_64-mont.mac.x86_64.S in Sources */, + E2D221DA97594520F8B583E948E1F9C7 /* x86_64-mont5.linux.x86_64.S in Sources */, + 9A6FE052F88D8CD593A1DAD117E0821F /* x86_64-mont5.mac.x86_64.S in Sources */, + 828A7FD40F2CFA0ECEEEC3E075765AAE /* x_algor.c in Sources */, + E378BCF0B877D69B68804CB10B12B846 /* x_all.c in Sources */, + 6C6B35C6E4A5EC4C0D001DF311C5BA59 /* x_attrib.c in Sources */, + B722E31FFDC5872960240360EC552FF2 /* x_crl.c in Sources */, + 252437788350C64E967C083D2ED6062E /* x_exten.c in Sources */, + 1FEF626C094C06E18E9C332F1CB209FC /* x_info.c in Sources */, + 240BAF5F91B3A549CACDB9F950E06566 /* x_name.c in Sources */, + EC2F337218FE40AA913E2578BB50DCDC /* x_pkey.c in Sources */, + 16492EE99023DA47E1E67E5350DD99E4 /* x_pubkey.c in Sources */, + D1F415CA1F34784DB7F02CCE24FDFD89 /* x_req.c in Sources */, + 2E91E0AC4DAEB74AEE8F59074951D30C /* x_sig.c in Sources */, + 393F4CAB20C2F98ACE213B5622227A10 /* x_spki.c in Sources */, + 444D3731A419203D89C6A46FB93445CC /* x_val.c in Sources */, + FB02596D198EB66B6CDDD00F64ECF3EB /* x_x509.c in Sources */, + 0BB2AD0D4B310F116340828E1E7E2B9B /* x_x509a.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5606D26B127296E9294E5C79B674B1BC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A00A0348C076445AD56219C5D8CAB513 /* Exports.swift in Sources */, + 980DEB38F9BD91AFA6B47F51D64E2166 /* SwiftNIO-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FB3BAB210986BFE10D62EC1678E2364 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 62D436F7476CADC46700E7F03469FCD7 /* Pods-fanex-fanexUITests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 61D5CB2A810C7FC352C0CF15BEF8EE8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9370582F8435D8057A4B9D0C1EF87700 /* atomics.swift in Sources */, + 1FD18AE4000607EBFDDF44FBA911DBE6 /* lock.swift in Sources */, + 13C7B272C6E5F6A6CC5058AEFF912315 /* NIOAtomic.swift in Sources */, + BF2EC78C3ECBEEBF388F34D3791445AE /* SwiftNIOConcurrencyHelpers-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 62C4533F24B3C97E049294153C6009BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C2378DC0D6CC3598C0DB121D0686544D /* precomputed_ecmult.c in Sources */, + 1D98188786C6EB48E6C3C3C1A4566BD7 /* precomputed_ecmult_gen.c in Sources */, + 9EBE0316C43C221F2566D14B66821B87 /* secp256k1.c in Sources */, + 1021F6D66CA4651E16E3D045BBA68EFA /* secp256k1Wrapper-dummy.m in Sources */, + 8EA31FCDA00CA16218D2AE03CB6CC4D4 /* utility.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6553DE6C4DE4146E1DBC591BB1845973 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A5F1958ECF3EFC3FB453ACEE40840BCF /* InteractiveTransition.swift in Sources */, + 29EFCE0029DAD34685F685DDC1584B19 /* PopupDialog.swift in Sources */, + 24B3E393946D47A88703047590F066E7 /* PopupDialog+Keyboard.swift in Sources */, + 8230F8BAFAA7FA0FD826FB6E1FAD7704 /* PopupDialog-dummy.m in Sources */, + DA7A97CC9E1A7548858FCA7B4D7C1629 /* PopupDialogButton.swift in Sources */, + B1950D5C96D92C81E7F436920077982A /* PopupDialogContainerView.swift in Sources */, + 86910B420D68F278708D70119B7344E5 /* PopupDialogDefaultButtons.swift in Sources */, + C10273C7D9B2212C16FB9D8EDF8C4939 /* PopupDialogDefaultView.swift in Sources */, + 4B085F1FDFD4ED3ED0F46B992AF7E0BB /* PopupDialogDefaultViewController.swift in Sources */, + A888ACD36DC8E310636E797F7791F6B6 /* PopupDialogOverlayView.swift in Sources */, + 6835A73143DA54E752A2B1B9C7DFCF6B /* PresentationController.swift in Sources */, + 1C2AE1E769BC1E5BA7062E4FB71DC6F8 /* PresentationManager.swift in Sources */, + B830185E1C7ED31627FA1B8775888EBF /* TransitionAnimations.swift in Sources */, + EC9211C49E43C38212BB791C35605245 /* TransitionAnimator.swift in Sources */, + 7C197D219FA3C1EF21038175317B4CA0 /* UIImageView+Calculations.swift in Sources */, + 65A8FEA804F5B01C5A627024F472299E /* UIView+Animations.swift in Sources */, + 5A24F1977DDF7783E072A05DD63976F5 /* UIViewController+Visibility.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7150198F4B0FA51AC42974C30D24194B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E5DB387A5D9CF98DC2A3D53D813E7681 /* SwiftyJSON.swift in Sources */, + 6B5E2B5C200CD813C14261C73288075C /* SwiftyJSON-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 81051028DE7225687C9FFF763AD47D0C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CE4A5C96EAA37622F7E4D70C813FC221 /* CGRPCZlibp-dummy.m in Sources */, + 7AECE95B2E2283F846DC931CD8DF8ACA /* empty.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8922821CAE0A2EDD720B2EDAAC480969 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7346D424959BC2E7D1384AF6C76FCAAE /* Addition.swift in Sources */, + 3D1485C04688DD005632FF34A33B48AC /* AEAD.swift in Sources */, + F5371A396E8882980DD3BA8F9979583D /* AEADChaCha20Poly1305.swift in Sources */, + F255F5742D91ACF953300EC019A5C569 /* AES.swift in Sources */, + 13C33A2031B817F6877197B61C39E796 /* AES+Foundation.swift in Sources */, + D22B8317C08105B8A39DD1D05C262B0C /* AES.Cryptors.swift in Sources */, + 90A1368C902FA3997565580BD550A1D0 /* Array+Extension.swift in Sources */, + 73467864F7509005F7F7E2C0A24F824A /* Array+Foundation.swift in Sources */, + 39BC4EC07ACADD3B81E1775BEE6FA3A0 /* Authenticator.swift in Sources */, + 774A41D26A7C10451680557504D7A53F /* BatchedCollection.swift in Sources */, + E86D3491661EFC3BD9FE7655FF0D4357 /* BigInt.swift in Sources */, + E8E7C3E3A7852157F2A34F3488B19186 /* BigUInt.swift in Sources */, + 59C374DEBCDD66228552DDEACF5A3D42 /* Bit.swift in Sources */, + 24EA9BF8A7E10BDCB2B55716B7706A3F /* Bitwise Ops.swift in Sources */, + D6C758E9A1EF4B06CDF96D39D4EE31A5 /* BlockCipher.swift in Sources */, + 5B1AF207A52B7481DA036541E7A4BE8B /* BlockDecryptor.swift in Sources */, + 55F866048AAF4BBFDBE746557B41620C /* BlockEncryptor.swift in Sources */, + C6E38181CD7752A6B54CFE2972BD695C /* BlockMode.swift in Sources */, + 77D207655D8C32EF73E93060E7A10446 /* BlockModeOptions.swift in Sources */, + 2649BD966C3B00E41347178E9A833920 /* Blowfish.swift in Sources */, + 50A1348C46C8AED836CF761E02F27A4C /* Blowfish+Foundation.swift in Sources */, + ACDCD1E99F1B233F37D6A6AE598F1013 /* CBC.swift in Sources */, + 1E6152AE31D8E87B9CA6BD9D39F6280D /* CBCMAC.swift in Sources */, + C13A7DF7136FD0687DC4D803AB6382A8 /* CCM.swift in Sources */, + 3D610323517B99A5074AF910E46F4681 /* CFB.swift in Sources */, + 19E55A20F0FB0B8B2630CB7961051EA9 /* ChaCha20.swift in Sources */, + A2FCD5718C96A293D359142D57FABC2E /* ChaCha20+Foundation.swift in Sources */, + 7B85051BC13267C48BBA96BE23976269 /* Checksum.swift in Sources */, + EF767776B19C0D880488CE95FFF2D1F5 /* Cipher.swift in Sources */, + 97A740267D6B0AD72622EB9D862651B4 /* CipherModeWorker.swift in Sources */, + 3D7151FB0FF951AA015EE3644BDC078A /* CMAC.swift in Sources */, + 238B47BFDCAA664594A50749A699CA94 /* Codable.swift in Sources */, + 409D336A5E9481A89FFDC487C0567F72 /* Collection+Extension.swift in Sources */, + 65A29E177745762A8D9ABE06754C3AC1 /* CompactMap.swift in Sources */, + B3D27A1C48FECD7C99188919A8DA288B /* Comparable.swift in Sources */, + 1ED8CEF109BCE64D0CCDA312F21B65A2 /* Cryptor.swift in Sources */, + B70113762D0008B21195B8BFD64DAF15 /* Cryptors.swift in Sources */, + F7243933EAA2401DC6901A124685CC11 /* CryptoSwift-dummy.m in Sources */, + 643AFEA4C7B86B04EFF5F942E6261224 /* CS.swift in Sources */, + D1BBC12B87C64762B76D92297EFF659A /* CTR.swift in Sources */, + 8D14245A9C211C6000E4693D8F61B92C /* Data Conversion.swift in Sources */, + C1FBDC8160EA3EAA854EF57D9883DEA0 /* Data+Extension.swift in Sources */, + 364F8DC5ADE96CE3CA2B30F84BDD2D9C /* Digest.swift in Sources */, + 0F780014CD531EA8866B5D36EC30BA63 /* DigestType.swift in Sources */, + 194580FD51324B7C68D531C1B92E3E6A /* Division.swift in Sources */, + D84A17A4FC02A3A2F22E8FA6C2CCE64E /* ECB.swift in Sources */, + 86DEF87E4F8198D710456B66C73C76AA /* Exponentiation.swift in Sources */, + D1C2AA1139364C475172E188804E7BDF /* Floating Point Conversion.swift in Sources */, + 789067D8C8C95DC1657FA055E62354F2 /* GCD.swift in Sources */, + 0DD6B5B1DF81A4CF957BA08365244124 /* GCM.swift in Sources */, + E41184C85FB11969BEED1C1255CF96F1 /* Generics.swift in Sources */, + 6541F9F3AE7BFF4B80B53E90A2423F9E /* Hashable.swift in Sources */, + 67B45FFF17232DBFBCBE36BFA67BFC29 /* HKDF.swift in Sources */, + F643188BD47ADBDC31EF551594C50284 /* HMAC.swift in Sources */, + B8231AB7A1921DF1171E8436FCEAD26A /* HMAC+Foundation.swift in Sources */, + 47CD1C6665C95709A1F74625C46615B8 /* Int+Extension.swift in Sources */, + FED0EC9EACFA0F0C5DEBC0FD7289F225 /* Integer Conversion.swift in Sources */, + 87F430052E25221DA3B1D9BEC805BEE6 /* ISO10126Padding.swift in Sources */, + 79CFD854BAA8075B908D7634B02FC6C8 /* ISO78164Padding.swift in Sources */, + BD7909110122EA2883543699E65D6237 /* MD5.swift in Sources */, + FA321678D47162AFCE8D6D2717AF6482 /* Multiplication.swift in Sources */, + 28D1A14F79B2621274E486A2B7590AE2 /* NoPadding.swift in Sources */, + 69A186B2DA541D39C102E28AF01AAF68 /* OCB.swift in Sources */, + 84687F01FA16CAA2D442BBCC2DAAEE59 /* OFB.swift in Sources */, + 0F22961374191F222242FC1F430FDB35 /* Operators.swift in Sources */, + A1FF1B8B82A494D7D29DEC80C8D710A9 /* Padding.swift in Sources */, + 78E46D7931B72355B5FB6A02E69020FD /* PBKDF1.swift in Sources */, + C6A7CB5C6E0F50E578E6F446ABF503DB /* PBKDF2.swift in Sources */, + BEEC4501CE6C7501A0DE1868E350FE99 /* PCBC.swift in Sources */, + 2A668DBCA505D299293EE6672ABA753F /* PKCS5.swift in Sources */, + 66B0448EA8AECB87C3ECF93E36576D87 /* PKCS7.swift in Sources */, + 31BCDEFDC31BA73696819B52FB7E8B44 /* PKCS7Padding.swift in Sources */, + 984CC8A94475153D5054D052291168C2 /* Poly1305.swift in Sources */, + 4A21B8CD44BDC8E66C6014B607CF44C1 /* Prime Test.swift in Sources */, + 3E866A1B98C4B497DC6B912C2C82F761 /* Rabbit.swift in Sources */, + CED332E4EE14635BF55493A9713E660D /* Rabbit+Foundation.swift in Sources */, + 799453F1531D0D9FEA91CCA42EB5A3FF /* Random.swift in Sources */, + DC9B0741A999A3812C9958CBD17E5D30 /* RSA.swift in Sources */, + 67A7F6B8AD4FBE5B8502087EAE0CFA28 /* Scrypt.swift in Sources */, + 14BA4B3502ADE782A26DF00A8683924C /* SecureBytes.swift in Sources */, + A3E665BAE12599243AE3B669EE8EBCC8 /* SHA1.swift in Sources */, + EFF06BCAAD35C22AEA7845996EBD11E1 /* SHA2.swift in Sources */, + 16BCDC468B7D329356800F7FE29281AB /* SHA3.swift in Sources */, + 34BF78E8CA1CB64B419902E4D16EB3A3 /* Shifts.swift in Sources */, + 12849636E47ABE1B6709389B8714C81B /* Square Root.swift in Sources */, + 3BC7792865FAD916A4DB8E7695A2768A /* StreamDecryptor.swift in Sources */, + 2020BDF490BB448003F12065D8662658 /* StreamEncryptor.swift in Sources */, + A2DF717D326BD940EA7210F0A90516C9 /* Strideable.swift in Sources */, + 7E2ED852A96880CDBF1B52969CA0D3B6 /* String Conversion.swift in Sources */, + D0BFDACD74C58900345A29629E2E3B7D /* String+Extension.swift in Sources */, + 36EBFC3E076F4D62B303ACC0704F7AEC /* String+FoundationExtension.swift in Sources */, + 3FD12183C97BF61139CCA374B72313FA /* Subtraction.swift in Sources */, + 066C1275C946EF3694CF437FAA0B846E /* UInt128.swift in Sources */, + 23F2376F3985F98AC41CA3AB975484B7 /* UInt16+Extension.swift in Sources */, + 613E78E03E1E9B4C495283F08DA2C360 /* UInt32+Extension.swift in Sources */, + 89345519765AE40FE56C04A805E034A8 /* UInt64+Extension.swift in Sources */, + B5F97901641027AD01C6BDDF0F93A37F /* UInt8+Extension.swift in Sources */, + 763FE225D3C6A3DB727CCDC349F146B7 /* Updatable.swift in Sources */, + B0CFC8A882453B026D543DD3E8D8672E /* Utils.swift in Sources */, + 835FD939BEC789E4EEFE096225D251EA /* Utils+Foundation.swift in Sources */, + DFA9FF35A4AB8FB30CA7149018CE76F1 /* Words and Bits.swift in Sources */, + 528FC3273A41C006C06DF1ED9702070B /* ZeroPadding.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 912FA7F2A6306DE0091563D8D3CD43C1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 36A0033DC9DE66FCEA295EA3FAB69FAD /* Asymmetric.swift in Sources */, + D3EF7DCB4CE16AB91A467871353CD3EC /* BytesUtil.swift in Sources */, + 0E297F64DD9BC7C8FE04C1EC2DA878A1 /* DH.swift in Sources */, + B7091199F7AC91AC3616E80016CE96E0 /* Digest.swift in Sources */, + 98C6517114A26AF9E637604AC4D58BEE /* Digests.swift in Sources */, + EB03395DC45589EF6BC76A76C7375F0F /* ECDH.swift in Sources */, + 827D304687FE0124457833531D64B786 /* ECDSA.swift in Sources */, + 11F7B3AD8780B2A65994FDF2C9E9F28A /* EdDSA.swift in Sources */, + 73DBA4269C02A006834B8CE9FA6349FE /* Errors.swift in Sources */, + 84AF32ED596E20AEBC370B505CF33164 /* PrettyBytes.swift in Sources */, + A6078F2E15C7AEE2E69AAACEAF4A2E16 /* RNG_boring.swift in Sources */, + 2E2017820A49E43FD89404C41DDD646C /* SafeCompare.swift in Sources */, + A535EC97D3F3FF5CA9D3968D27F85803 /* Schnorr.swift in Sources */, + 05DEFF4F666F29206344595D025DAE7E /* secp256k1.swift in Sources */, + 91F7CEC4CB4C130E2EC2651A91307FDD /* secp256k1Swift-dummy.m in Sources */, + 4CB3DC21B4147A401390ECBB934404B1 /* SecureBytes.swift in Sources */, + D53A753DFC77FE7C3E879E91811001FC /* SHA256.swift in Sources */, + F5CDDAD3CC8FB214E48E5105DB07A039 /* Signature.swift in Sources */, + BD1A7F825CBFFAFD5548ED4FB435BE29 /* Tweak.swift in Sources */, + 9A7FD0E844EC414A2B246CB0A010BDC2 /* Utility.swift in Sources */, + 4FB462800158909068B7A27D83E802F0 /* Zeroization.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 91F1CC240271391A20B61758DE5851A4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0EA40F31474C855AA31F2243B616CB2D /* _NIODataStructures-dummy.m in Sources */, + 46387A06696852FFD7DC028A937E9F17 /* Heap.swift in Sources */, + 723E1B6BBAE628C58E990D408A90C129 /* PriorityQueue.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 94E4F7E090D14C6262F408A9945399C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7F8893187E4DA4EFC75D75C98F1C3145 /* CNIOBoringSSLShims-dummy.m in Sources */, + 65B8C304291077DAC3CC504A7FE41FD9 /* shims.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 998DB4FDC72027717F8C1B061B233CD2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8CC79D41E5B378932CF413CEC13CC3EC /* AccountProofData.swift in Sources */, + 590B3598D1229E14176826E4582E2AC1 /* AccountsResolver.swift in Sources */, + 1B7D7FAEBFE29E80BA244AC626A3FED7 /* AddressReplacement.swift in Sources */, + 3D6829553392CA8D26534EC5F5852844 /* AppDetail.swift in Sources */, + 7FE990D0E641867E134EE9E3F1BFA70D /* AppUtilities.swift in Sources */, + 12464BB4762BAEB0E983C174976CFCC4 /* AuthData.swift in Sources */, + E4F76B17938B5DCA6D1853AE27018713 /* BloctoWalletProvider.swift in Sources */, + 97DFA419584FFB1AA70710DC03CCBC88 /* CadenceArgumentExtension.swift in Sources */, + CAF5FF5A5ACE199F8DCA016F70EC94F4 /* CadenceResolver.swift in Sources */, + 3622AFF43F23CBD87FDE9257B991ADED /* ClientInfo.swift in Sources */, + 138C53F998E2DC58D18BDD0A1010EC1D /* Config.swift in Sources */, + 41BBAE8C840AA595366BB22FE072C75D /* Constants.swift in Sources */, + 336E671A32DBBE0DF1750CAC02EF0E91 /* DapperWalletProvider.swift in Sources */, + 80D55B72E6FF9FBD9015A33F59D16B16 /* DynamicKey.swift in Sources */, + 8932E535236B3F5DE82316190B433EE1 /* Extensions.swift in Sources */, + 946F3DB3BCCFC40E9FFF92709521771F /* FCL.swift in Sources */, + 9FD7FF60559CFFCA9FD7FB732173F870 /* FCL-SDK-dummy.m in Sources */, + 22D452F8A3E250D161C8F72E524D669F /* FCLCompositeSignature.swift in Sources */, + F4B10C796BDD8DB6C781BF31B4C71D83 /* FCLDelegate.swift in Sources */, + BE687A95786CFAB7E099F2F55E020294 /* FCLError.swift in Sources */, + 931D7961922B8F01F60747E66927918C /* Interaction.swift in Sources */, + 20B983FEC35608CBE7036C4B743D44EB /* PollingResponse.swift in Sources */, + 5C54A4A3171049D05DD20D4F98CC133F /* Pragma.swift in Sources */, + 2E676A8652B8B33723849761B554B088 /* PreSignable.swift in Sources */, + 1887EFFAB070FC03886C6814B7973F02 /* ProviderInfo.swift in Sources */, + 4FF8138ED7EC99F88EA1434B8138C7F2 /* RefBlockResolver.swift in Sources */, + B720378C74F3FB6E7F8C27ECBD9CB0C3 /* RequestBuilder.swift in Sources */, + 8D716860B7C9D57D691CA3FBE34F7543 /* Resolver.swift in Sources */, + 38FB2392290B383258674CAA64EA6989 /* ResponseStatus.swift in Sources */, + 003CD5283BC9087FEF973075302763DD /* Role.swift in Sources */, + 60738B205D5C0788DE7B2E9C00207F56 /* RoleType.swift in Sources */, + 2D20C12406A999419249E1E307F69829 /* SequenceNumberResolver.swift in Sources */, + 1B8B77D013186603AB1A541336BE1ABA /* Service.swift in Sources */, + 61802DEB44AA7C04FA69284DF12CB514 /* ServiceAccountProof.swift in Sources */, + C021850F6405E4421315CCABC6D164F6 /* ServiceDataType.swift in Sources */, + 61D475469B0DD6D8652EBD93E1345B7B /* ServiceIdentity.swift in Sources */, + 91CC0ADF6F7F594543D54E0C786D3B98 /* ServiceMethod.swift in Sources */, + A4A382C0552AEA0E3E61A52FEA004ADF /* ServiceProvider.swift in Sources */, + 0E498B0426DC585532962A1D1F0F9C13 /* ServiceType.swift in Sources */, + F7C80AF1F3CBB02D63D52CA677C17BB7 /* Signable.swift in Sources */, + FC0BC091D9946965008A4FC8897C232A /* SignableUser.swift in Sources */, + 54F1F5EEDD0CED79BADEFAB5998DFE16 /* SignatureResolver.swift in Sources */, + DF10F64FCDA06951F00273C0884C3EE0 /* Singature.swift in Sources */, + 45B6DF681B09BF997E84A2EFC6536A5B /* TaskExtension.swift in Sources */, + C4CD271FF070F78D8BF54618838E7FAB /* TransactionFeePayer.swift in Sources */, + 3D842812B067B5DBC33A9CA7CE5211DD /* URLSessionExtension.swift in Sources */, + 4270711461FD0522F4914290FF43BB92 /* User.swift in Sources */, + 06671B662E667EAF88B20FCDFE2FE470 /* Voucher.swift in Sources */, + 7AB97A46D97437AF1E1C0F9FBBBDA0D8 /* WalletProvider.swift in Sources */, + FD41B07598328C439A9E751673F93FB3 /* WalletProviderSelectionViewController.swift in Sources */, + 4928E2AD23275D08BB262C3546D0E086 /* WalletUtilities.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 99E49451CD45EE51C32A150E172D36C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 78598BD37A8B3B79879E22CB36D95BEC /* BlurLayer.swift in Sources */, + 27181A4A309FC58C0AD2204EEA2FBFF2 /* CaptureQuality.swift in Sources */, + E7B5FE73B705ACD5475CB1A003AF1C48 /* CGContext+CGImage.swift in Sources */, + B3324EA2D5A61BFF8096863ABF5E14A7 /* CGImage+Accelerate.swift in Sources */, + E1CAAE3F0D4C2C50998BA10BE616AC02 /* DynamicBlurView.swift in Sources */, + B8E546A8E7D00B7C43323546BD0D4045 /* DynamicBlurView-dummy.m in Sources */, + 2CD787C99352C8E90F9EDC014DFE8262 /* TrackingMode.swift in Sources */, + DEA1C15ADF5B7F4AEF8379FA1BCF6A44 /* UIImage+Blur.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AA141FA25DB9F2A41BB5F46E542E5F15 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DF27CEE8FBD94A82CF6EED2C5917A92 /* Address.swift in Sources */, + ACD85778F812D36BC98C73685D3BB63C /* Argument.swift in Sources */, + DDBAC3B83A7251293580CE204CB2B7E4 /* Cadence-dummy.m in Sources */, + 3BCAE39D65BCD9FFACB96156CA7B084E /* Capability.swift in Sources */, + 781DD3B836810CCF3F03CB5FFE5D4355 /* CodingUserInfoKeyExtension.swift in Sources */, + 657ADF9EE9934FFFF22CD148ED853F0D /* Composite.swift in Sources */, + 5B581E49E611950BDF0E77F3CACF5A6D /* CompositeType.swift in Sources */, + 4FF5A864D3607F7061817866CC8022CA /* Dictionary.swift in Sources */, + 58C653C980692BFEF073B7DC904A3544 /* EnumType.swift in Sources */, + F13CDD9E25BB411286D4BF7A76986DD9 /* FieldType.swift in Sources */, + 76D24833C231AE4F6466AD4698D79771 /* Format.swift in Sources */, + 9FD9956DD18BC154D2BAEB6A0C8C382C /* FType.swift in Sources */, + 769C022C8F15B72D06A16BE4668EDD00 /* FTypeDecodingResults.swift in Sources */, + A95A8D3A20122AA075B523B7BCCF6C26 /* FTypeKind.swift in Sources */, + 5B98F58EB26DD61ACB7FE670AF9DDB64 /* FunctionType.swift in Sources */, + 216BCA5B4152F43341A639C4539AD209 /* InitializerType.swift in Sources */, + D1A79DA0A4CAEDCEB4D59B79D4DEBD5B /* KeyedDecodingContainerProtocolExtension.swift in Sources */, + FE2DB3C76A33538019AC9F0E4C34B80A /* ParameterType.swift in Sources */, + CFD207FB543B08C520B4EC4F6737097B /* Path.swift in Sources */, + 296F137821441F0CFAC52D800B8C2E93 /* ReferenceType.swift in Sources */, + 2CC93CDE16A4E4CCE784EC8EE7A9363A /* RestrictionType.swift in Sources */, + 6CDC7602E4FC35165BEBAAB8D20DEA6C /* SingleValueDecodingContainerExtension.swift in Sources */, + E03B9580B8220AD064E1E96000C23624 /* StaticTypeValue.swift in Sources */, + 6C435BB27EAB8F4B8EEB841DF30FA01F /* StringExtension.swift in Sources */, + A90C432845167D1E63B82FFF07E57244 /* Value.swift in Sources */, + 3039CFE7D17F3DF82B08B2A827AFE446 /* ValueType.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B3CC4389BFAAC554AF4E77263B4970EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7958EC35F3C362EE1349FECF7C3DC434 /* Pods-fanex-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B5E8E62813ACBE0DFD725BAA9A851314 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AE009249C47986771A5D877A59B9C181 /* CNIOWindows-dummy.m in Sources */, + 0B09E5BF60E1F7034257A75BB42B1992 /* shim.c in Sources */, + 63A2B0DDF3407A20B8CA4AC4A59670F2 /* WSAStartup.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8431C4117C2D2C4C9AFCF7419A22C5F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A733A02A2F7047FC928576907A8E855 /* any.pb.swift in Sources */, + 3C3652259AE69A20693C18577D7158FA /* AnyMessageStorage.swift in Sources */, + C227932EAD480FF974148FED7B41B66B /* AnyUnpackError.swift in Sources */, + 220A5DF00449033884685ECFC8FC9F1E /* api.pb.swift in Sources */, + 875A71D248448B0DFDE1BD15BCC9E333 /* BinaryDecoder.swift in Sources */, + A8A29192006F6D9AC7670F3388BD3E15 /* BinaryDecodingError.swift in Sources */, + 735D6864E8D81ADD0811DF8EFACB4BAB /* BinaryDecodingOptions.swift in Sources */, + A4460B2EA066EBC46283E99805444310 /* BinaryDelimited.swift in Sources */, + 54FA85CE73D53DDDCC531C226A12686F /* BinaryEncoder.swift in Sources */, + AFE04C9F3EB37DE0F6DA19F6817907DA /* BinaryEncodingError.swift in Sources */, + E9BDD9FC4F5E7A0F8C5020BF1CC7D10E /* BinaryEncodingSizeVisitor.swift in Sources */, + 5F7DDD0B418E98BC86553F8F34689CAC /* BinaryEncodingVisitor.swift in Sources */, + B0FE087E0B18253FF946D32C70AFC21E /* CustomJSONCodable.swift in Sources */, + 03D441DB166EF3C3438A7B49CBE8B02F /* Data+Extensions.swift in Sources */, + 2740B5448830CEFB0D1297AD69348418 /* Decoder.swift in Sources */, + EE5A45DC805358351A9B5C97C4541DEC /* descriptor.pb.swift in Sources */, + 093150C571E73CAEF7AE687055B5EAC3 /* DoubleParser.swift in Sources */, + 8607CDDF3A485A361B6F0296B95B675E /* duration.pb.swift in Sources */, + B176B65678CE2CABE44D8C4309345C29 /* empty.pb.swift in Sources */, + E4C13C7E6E3FB95A9694F4DDBCBCED30 /* Enum.swift in Sources */, + 7B355F0E3E660FC2C7561EFA25231CCC /* ExtensibleMessage.swift in Sources */, + 807539BDCAFED59F1F17455D4C87F0D4 /* ExtensionFields.swift in Sources */, + 955D0935513D1F162D501287B0325623 /* ExtensionFieldValueSet.swift in Sources */, + 57CE164539CF32C51BBEFA21F1882B06 /* ExtensionMap.swift in Sources */, + F2E080D591DA83169CBB120644B2C8FB /* field_mask.pb.swift in Sources */, + 6EA8F20EB99AD5C1BE905406F2951673 /* FieldTag.swift in Sources */, + BFD0839D147B1701518C1F48C299CB35 /* FieldTypes.swift in Sources */, + FA6681F61CE9E2B71D507604A3CF7793 /* Google_Protobuf_Any+Extensions.swift in Sources */, + 99E31072D780FBEDAB586BA141451234 /* Google_Protobuf_Any+Registry.swift in Sources */, + 3A1B7837444E712B61F81BFC7214069C /* Google_Protobuf_Duration+Extensions.swift in Sources */, + D6599C63A8E9C8C7FB6E79987391F7A0 /* Google_Protobuf_FieldMask+Extensions.swift in Sources */, + 687F29546854F86FD82EC6F30B00AC8B /* Google_Protobuf_ListValue+Extensions.swift in Sources */, + EDB9B74B32A165CB0FFFB8E48D626D4F /* Google_Protobuf_NullValue+Extensions.swift in Sources */, + 106C2369F8AD4D75E89177FF097F5F33 /* Google_Protobuf_Struct+Extensions.swift in Sources */, + 1E82A1290E730894E41F451AFFEC26E5 /* Google_Protobuf_Timestamp+Extensions.swift in Sources */, + D2CF6154C4F799BA6DCB03922C9278FF /* Google_Protobuf_Value+Extensions.swift in Sources */, + B50986EE01C27FE64BFE67230DA3AA3D /* Google_Protobuf_Wrappers+Extensions.swift in Sources */, + 2536B9BD4C2A9A1582333039FE5262D2 /* HashVisitor.swift in Sources */, + B22F40A0E0838D29531FA0CDD88340A7 /* Internal.swift in Sources */, + C0CBB75BAE53A402F4E93D6E15D16FB6 /* JSONDecoder.swift in Sources */, + 840F36EB08048B43E9FCBD62B6E627E4 /* JSONDecodingError.swift in Sources */, + 24539AA69483BAC22DF4B6A4E661D1BD /* JSONDecodingOptions.swift in Sources */, + D07F3C00344184A13BDD96CBC9EB5FB0 /* JSONEncoder.swift in Sources */, + 6A40DF1C404BBD84266915AD920DE108 /* JSONEncodingError.swift in Sources */, + B603F1FCB8AA2E158DB796D8D83559EA /* JSONEncodingOptions.swift in Sources */, + 20068761C9269D078753ABAB5517457B /* JSONEncodingVisitor.swift in Sources */, + F85A22BE2DB8AF01608769785E8EF38A /* JSONMapEncodingVisitor.swift in Sources */, + C716D1D1B19476E661F8A9C2F01F2D1F /* JSONScanner.swift in Sources */, + A732554841675F7604445175F2DE09A7 /* MathUtils.swift in Sources */, + D2EAAF790440AF298F4D91FD14A3B52C /* Message.swift in Sources */, + 5D973CD77F0F65F6CB752712B7674CDD /* Message+AnyAdditions.swift in Sources */, + 90C7B8A60C2516B9BDEBC60A2A605362 /* Message+BinaryAdditions.swift in Sources */, + EA803E256823ADA868E6A119D9D229B1 /* Message+JSONAdditions.swift in Sources */, + 6D9B484F5CAFE7618800F617B7CCB251 /* Message+JSONArrayAdditions.swift in Sources */, + 067A89333F31F0163B435AB2DE985AEE /* Message+TextFormatAdditions.swift in Sources */, + CE6053F20DD10A68A6F4D0E70784846F /* MessageExtension.swift in Sources */, + 5F52CDA0F30AF57DE98CD95FA200A1AC /* NameMap.swift in Sources */, + 30E47B499E8FA95AB447A28923A9C666 /* ProtobufAPIVersionCheck.swift in Sources */, + BA0D388D2D149F70E82F3A059DAA481A /* ProtobufMap.swift in Sources */, + 8E53AABA01D8C15F66C41BA352405064 /* ProtoNameProviding.swift in Sources */, + 6F816C06926556C18A038ACFA0E2B6A6 /* SelectiveVisitor.swift in Sources */, + 79E610505AF9B4FC580B00FF762AB70E /* SimpleExtensionMap.swift in Sources */, + 3B7D76DD8B20D98506855AAF6C1DB657 /* source_context.pb.swift in Sources */, + 70A9442BAA644D89EBACFA20F5C038D7 /* StringUtils.swift in Sources */, + 71E9350415664018344326E82F76017D /* struct.pb.swift in Sources */, + 2BCBE089BB0218A079AAEEE73EBDF84C /* SwiftProtobuf-dummy.m in Sources */, + 7E7BA3355640C118DE950658C2272AC2 /* TextFormatDecoder.swift in Sources */, + 36B1FE4CCE0CB5BE55D4DABBA48D7D5B /* TextFormatDecodingError.swift in Sources */, + 945377AB6F66065876391D8469014C65 /* TextFormatDecodingOptions.swift in Sources */, + CEF2C8EBA49AA56A23A7BE0886949BA2 /* TextFormatEncoder.swift in Sources */, + DDBCF39FC0DE63E0CC584A179B9A99F8 /* TextFormatEncodingOptions.swift in Sources */, + D9601285D494DBADD1870DE4F407037B /* TextFormatEncodingVisitor.swift in Sources */, + 1BB5ACC5E8E0CCB3F92E2677C3E4FB77 /* TextFormatScanner.swift in Sources */, + 014D64642F0747A1F91169F1EA385F55 /* timestamp.pb.swift in Sources */, + 1FFCBF421B34F1FDF2DF4104A8B3D499 /* TimeUtils.swift in Sources */, + 5151ED5BAA1A285E87EC4D504E38CCDC /* type.pb.swift in Sources */, + 0D3D74E87637764C70C18C2DA1BD29EE /* UnknownStorage.swift in Sources */, + 11F5FAC519308BE1E08776FF82736BD2 /* UnsafeBufferPointer+Shims.swift in Sources */, + BE4B2817A0465897840B7D3AE572E6CE /* UnsafeRawPointer+Shims.swift in Sources */, + 8DDDC3F18CD83DAD95CFCDE316A0E06E /* Varint.swift in Sources */, + 76E07381A4547147B0BA17BC718F3742 /* Version.swift in Sources */, + EC2E56E563DF0286FC9BBA18AAE3E203 /* Visitor.swift in Sources */, + 0277BF84EAE1AF2C8A1EC9DD21E623F5 /* WireFormat.swift in Sources */, + BF813D6A70BF38AD42D0D53F59806E6D /* wrappers.pb.swift in Sources */, + 18EED5DCAFE2B676CEA9BA017107475D /* ZigZag.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B9E3EDD72D5BBD61999CA90AB528007E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64A0464897D1C080467F35FE3389FDC0 /* ByteBuffer-foundation.swift in Sources */, + 3F373E5D3E6B46D37E6AFECF483DC201 /* Codable+ByteBuffer.swift in Sources */, + EF715BDEF2FCDA364B172720D1FF9829 /* JSONSerialization+ByteBuffer.swift in Sources */, + 6EC717982CD95A70F4F49D51E0459438 /* SwiftNIOFoundationCompat-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BA44F608FC3EE94F867DCD49CC2694A9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D7414D81DFEAEE19FAB7DF0AFB4DD161 /* BaseSocket.swift in Sources */, + C0D2BFCF10F21ED7122493210B5638F2 /* BaseSocketChannel.swift in Sources */, + 0B4E22B49079B4F4FA584C02310CC9EA /* BaseSocketChannel+SocketOptionProvider.swift in Sources */, + 9E1432E859BD6E901D050E711CDEE881 /* BaseStreamSocketChannel.swift in Sources */, + 7684A27F1255449E069F25A2460A1051 /* Bootstrap.swift in Sources */, + 832690B4037075196CBA2F7A2548C2D5 /* BSDSocketAPICommon.swift in Sources */, + 578AD332DA729456829E38A9F50AE454 /* BSDSocketAPIPosix.swift in Sources */, + AD2F68F52B04607489BCFBEE3FBE0BF6 /* BSDSocketAPIWindows.swift in Sources */, + 31D5B73EB3DF7B6970F181DEF0CDD9AD /* ControlMessage.swift in Sources */, + 8652E0F5FC00B619A38182E3D6342167 /* DatagramVectorReadManager.swift in Sources */, + 84A09F650CB6D87CF142E2008A388E54 /* FileDescriptor.swift in Sources */, + 7EA8ED4B5FADECCC485FC0A5CF904B8E /* GetaddrinfoResolver.swift in Sources */, + DA6471627554399FEDB451E8FFE42ED1 /* HappyEyeballs.swift in Sources */, + E89B05BF6B14EC0E1DC66254DD39F079 /* IntegerBitPacking.swift in Sources */, + F272EAF414553A81C7C54EA35F06B339 /* IntegerTypes.swift in Sources */, + BDAEE0AE18AAE13FFC15096AA8E4B659 /* IO.swift in Sources */, + 938D2992915D6FE7A9DC59E172111584 /* Linux.swift in Sources */, + 3BEEEADFF04E2FE7CB8ED7A1BB5E2844 /* LinuxCPUSet.swift in Sources */, + A3137D709E339687763D9AFF5FE1616F /* LinuxUring.swift in Sources */, + 9BBC00D55C136D204D9E6135D396B088 /* MultiThreadedEventLoopGroup.swift in Sources */, + 567AFBE7D3BA44F61600619310EC5428 /* NIOThreadPool.swift in Sources */, + 02A34F86694B6E68BE8417E55FA53F30 /* NonBlockingFileIO.swift in Sources */, + 7FC5A0E43ACF497E444040DD504BC652 /* PendingDatagramWritesManager.swift in Sources */, + 2C717084B1D688C8FB7194BBA8EBD028 /* PendingWritesManager.swift in Sources */, + BC900F4AB545CCD918B220411187D08E /* PipeChannel.swift in Sources */, + 97E73E13FA016FA00E2F31EE0CF0B4D7 /* PipePair.swift in Sources */, + 82DA01D0ECDFFC1F612ACEB43FF6A3AF /* PointerHelpers.swift in Sources */, + E074A63D41FB511B4A4EB2B18C8E823B /* Resolver.swift in Sources */, + FCE2D34E84F3C89B8E4E03BFEFE3E646 /* Selectable.swift in Sources */, + 461CBD4619115C3F588833050A10D13B /* SelectableChannel.swift in Sources */, + 1FFD3A5D025903D1D457CABAF4F8E8BB /* SelectableEventLoop.swift in Sources */, + 9FFC483844B163BC1FEEFDE3CB235460 /* SelectorEpoll.swift in Sources */, + 7018B5FF9DD5D93B9A728AF6ACDFE2FC /* SelectorGeneric.swift in Sources */, + F910D09581632891360B34FD0306E5FC /* SelectorKqueue.swift in Sources */, + FB04F98E7B54951A8854AA185087E096 /* SelectorUring.swift in Sources */, + EE71A81B20826C203428976F420177DD /* ServerSocket.swift in Sources */, + B2E7CE9F90EA1EE141B3E1B069BBB672 /* Socket.swift in Sources */, + E8A3924DF45674B1A7C49A31245BFC7F /* SocketChannel.swift in Sources */, + 5EA63EE694223E347D3CB483F21C256C /* SocketProtocols.swift in Sources */, + 36C4B71AD593AAC1EC123CAC393A8A42 /* SwiftNIOPosix-dummy.m in Sources */, + BD89EF7B99AA3E4C79E3501FA539208A /* System.swift in Sources */, + 36E57B5E5628F49E6815083DCAE8B968 /* Thread.swift in Sources */, + 2420475023B2D20EF1E4761A29661EEB /* ThreadPosix.swift in Sources */, + 28EE052960A57B1B99593F28560B5E02 /* ThreadWindows.swift in Sources */, + 7B924E02C258C9BDE0E3A54B7768F878 /* Utilities.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C32A6C523F3D6A954321B65A0C2F674D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 391E8EF30D9F2981FBFC133B891FE4E7 /* c_nio_http_parser.c in Sources */, + 00925F03DED82E0317508AFC81FAE9E2 /* CNIOHTTPParser-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C6AE0677323C0AA412FEF367A2118C03 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F5979CF6BA6E3FB5FC30F8611868E4B3 /* Pods-fanexTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C82B5A6646D3768C42F8CDCCFCBF18E4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D94577585EE54E79F4F9584B50B1684A /* AddressedEnvelope.swift in Sources */, + 31BA8F67687A3DCA9163EA36D46B2062 /* AsyncAwaitSupport.swift in Sources */, + D747E6D1A1FBC22717171EDC089D5A4A /* AsyncAwaitSupport+OldXcodes.swift in Sources */, + DE9547469793D715D9380C071EDEA124 /* BSDSocketAPI.swift in Sources */, + ED23CD1CED44EE98522F6A6522F8872D /* ByteBuffer-aux.swift in Sources */, + 3BD2AC8EBB74AF8A5DD2F707812AA060 /* ByteBuffer-conversions.swift in Sources */, + 1F967DEE665A796AD5E0F4131F8052BB /* ByteBuffer-core.swift in Sources */, + 6D6AF4306636FDE7A760177C49B272DB /* ByteBuffer-int.swift in Sources */, + E3EC582C886EFE91B791B99B413E44F3 /* ByteBuffer-lengthPrefix.swift in Sources */, + 6497E8C8D82E52ADDFABF0085356E6BF /* ByteBuffer-multi-int.swift in Sources */, + 5864DCC2F17C09A9092B478ACA788C57 /* ByteBuffer-views.swift in Sources */, + 0DC201DB13FFBABC695B3D93C4A4C9CA /* Channel.swift in Sources */, + 76C03C89B7BB0D57BAF09CE4C7B4C64C /* ChannelHandler.swift in Sources */, + B11A25A0F5D114CF44470C84D29DB853 /* ChannelHandlers.swift in Sources */, + DAC33BB50B13BD204EE6FB6FF0F70743 /* ChannelInvoker.swift in Sources */, + 9559BC0A5F6062AE2B71AA45F4AFE8A0 /* ChannelOption.swift in Sources */, + A28021EC2FA52704C25635AC73D1EDD8 /* ChannelPipeline.swift in Sources */, + 34EFF2685CB6B544507AAECEB83323F4 /* CircularBuffer.swift in Sources */, + 61620557240AB79D29D36EFAEF3536EF /* Codec.swift in Sources */, + 33383BFF8CF2F04FAA1C97438A407AAB /* ConvenienceOptionSupport.swift in Sources */, + EB1AA9AAEF921D90FF3FABA3A734BA83 /* DeadChannel.swift in Sources */, + 66CD34BF7A48482B9CCC4F786B4E825B /* DispatchQueue+WithFuture.swift in Sources */, + 931613395255E0FA0A1749FD25C5D429 /* EventLoop.swift in Sources */, + E449941AA9B755CEEDF66999C58D98B0 /* EventLoop+Deprecated.swift in Sources */, + 3FFBD47D4264F4B38EEC93627453A434 /* EventLoopFuture.swift in Sources */, + C5405630762B9EBFEF7C48D595C9BA13 /* EventLoopFuture+Deprecated.swift in Sources */, + 896F827AC8B227E67D53F9282F0489B2 /* EventLoopFuture+WithEventLoop.swift in Sources */, + F6283C44CF6A82AB1DC097C4E5A149F5 /* FileDescriptor.swift in Sources */, + 1AA9D67490B0BFF463915C09EED3D18C /* FileHandle.swift in Sources */, + DF955E134FCC89A7F2347CD7F00EC5EF /* FileRegion.swift in Sources */, + EDE4C554BFC9A36D7C39A1745DDB5EA9 /* IntegerBitPacking.swift in Sources */, + 2B20316F776E14186C91F489FB6B98C7 /* IntegerTypes.swift in Sources */, + 49E0EED639D3861CBB10D9BA3E7C5451 /* Interfaces.swift in Sources */, + 5D1978794F6B1DDDFFF1EADFF75E72A4 /* IO.swift in Sources */, + 9CE03904E73697E6764B07D01FBDD54C /* IOData.swift in Sources */, + 92BE3FAEA06EA097008DF150FFD6AB3D /* Linux.swift in Sources */, + 05EECD90A450385DF1A7E41D85AC6AA4 /* MarkedCircularBuffer.swift in Sources */, + 6B856A2A524B09A99E7E81574A061FDD /* MulticastChannel.swift in Sources */, + 805CF770886A9CFBF3CE0046D0F9BC12 /* NIOAny.swift in Sources */, + 3C10368702A8DBB98538F33EC98EA47A /* NIOCloseOnErrorHandler.swift in Sources */, + B3B0ABFD856BD653AD6B02E0A3D9868F /* PointerHelpers.swift in Sources */, + AB04DE035BEE708294D6F4AD6BEA9885 /* RecvByteBufferAllocator.swift in Sources */, + D5D3B649FA004615F19F0ADCD5E958D1 /* SingleStepByteToMessageDecoder.swift in Sources */, + 31C7D807BAB08D0590E2F09A272E24CD /* SocketAddresses.swift in Sources */, + 5436A3AEA6342F0D82D945BFC89189AA /* SocketOptionProvider.swift in Sources */, + C990A390F1BCE9973A3688EABFCE69C5 /* SwiftNIOCore-dummy.m in Sources */, + 818BA65A1DFB65A6AD46B7AD72ED6F3B /* SystemCallHelpers.swift in Sources */, + 79C2E45FA742C6ED63BF449B77B8DB44 /* TypeAssistedChannelHandler.swift in Sources */, + 85BF38CBE77FB5836F6D550F56B0F820 /* UniversalBootstrapSupport.swift in Sources */, + 925281ECDAB627C72EFC8299EEA8D79E /* Utilities.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D289E0F76A764BA9C83ACE956D6A27A0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A3D8C3EFDD38B6A725C235D08C05F4DA /* Bundle+Module.swift in Sources */, + BF6B694AA2B8D3B64A9F4ABB24BBA8BD /* MercariQRScanner-dummy.m in Sources */, + 5F8BBE3B833E4414E4FEC4F278BC20B3 /* QRScannerError.swift in Sources */, + 0749EE058FE13B1F5B867BB03750B182 /* QRScannerView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E794A2A742D84C7B857A385367BF237E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5566250BAD657877EA12FE06021FDEE4 /* ByteBufferBIO.swift in Sources */, + F93B819F0B0BB771FEFB3F0F84753133 /* CustomPrivateKey.swift in Sources */, + 8448DFB10F52D1872284FAF948754AEB /* IdentityVerification.swift in Sources */, + 08DD40693867A231B7A4E72C1BEB2BBF /* LinuxCABundle.swift in Sources */, + 58755350E5AC41820A0DA740D7586134 /* NIOSSLClientHandler.swift in Sources */, + 8CC279199EF39D7DA793BDA1FFF22FF2 /* NIOSSLHandler.swift in Sources */, + FC4C5AB4C2B9A776CB456F0947196200 /* NIOSSLServerHandler.swift in Sources */, + CD42A502DBC1A533C80C7AE552A22F73 /* ObjectIdentifier.swift in Sources */, + 9777D65ECAA2B800674F79BDD7034A2D /* PosixPort.swift in Sources */, + D8E031F864BE34AB0D73002CE05E9742 /* SecurityFrameworkCertificateVerification.swift in Sources */, + F04832E00C01F64280C200F9FA94AA2F /* SSLCallbacks.swift in Sources */, + 3797AF5CB4E2FDA7B4972B3BDF95C612 /* SSLCertificate.swift in Sources */, + 4FB7368C14F3EB36D7DF25D267A6FB8A /* SSLConnection.swift in Sources */, + 8551BB6CE0B1441553CF33E6F1866AD0 /* SSLContext.swift in Sources */, + 901C0CE07B2CA5EDBE95ABC547108F97 /* SSLErrors.swift in Sources */, + 903A1D086098A9BFCDB5161DBF555BBA /* SSLInit.swift in Sources */, + DA7D579CB9A6B1A72AE972758201ED2D /* SSLPKCS12Bundle.swift in Sources */, + EDA02AB3723123319E6A02113F7C0F6E /* SSLPrivateKey.swift in Sources */, + 5BFC5248FBB5CA1D66A13019B42A0320 /* SSLPublicKey.swift in Sources */, + 9FDCC681879CC99EAABDE61586111607 /* String+unsafeUninitializedCapacity.swift in Sources */, + AE14F20041D68EBA67F122B43E1D264F /* SubjectAlternativeName.swift in Sources */, + 6BE718F60B8AC6015559D89E4B4EF322 /* SwiftNIOSSL-dummy.m in Sources */, + 2A2CB45901D951125ED082797A2E753E /* TLSConfiguration.swift in Sources */, + 64B960D6E9E9C92C1DFFBAA5484644F2 /* UniversalBootstrapSupport.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC3B919A3B77D2428A5E7C63BF8FC6FB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2FC36894797171AE85A2E5697783C285 /* ApplicationProtocolNegotiationHandler.swift in Sources */, + C42A6C89C3FBE7C77A2797827B51B65F /* SNIHandler.swift in Sources */, + D076B4E3F7CFEFDA13F9C8CA5C5C7C20 /* SwiftNIOTLS-dummy.m in Sources */, + 5E5A0CB52A65D92341CDA1AF56F138FE /* TLSEvents.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F500A4FE439CDEF4CF437B62E56ECD87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6F179152D94A49F7A28626BE73A1B8BF /* NIOFilterEmptyWritesHandler.swift in Sources */, + 4D57503805406F4CC28676B457ADD8D1 /* NIOTSBootstraps.swift in Sources */, + 04190E7039B3265AD22AE6CB4789EAD6 /* NIOTSChannelOptions.swift in Sources */, + 783B384FD754B788E0D9B28E44B5850F /* NIOTSConnectionBootstrap.swift in Sources */, + E999BF52BC1A0DB561E4F948E4C63AAF /* NIOTSConnectionChannel.swift in Sources */, + B3A26162D7E624677A1187B6CEC89FF6 /* NIOTSErrors.swift in Sources */, + E96F3501EF2AC42C682BD16B73831AD5 /* NIOTSEventLoop.swift in Sources */, + 07B239EA1B4D958AEA1EEB420A76EB74 /* NIOTSEventLoopGroup.swift in Sources */, + BB35EAC57CE1C9F84889A8728874D311 /* NIOTSListenerBootstrap.swift in Sources */, + 10D2F03A26A5904844445590664908BC /* NIOTSListenerChannel.swift in Sources */, + E48C92167F6F0221B63E379D48376496 /* NIOTSNetworkEvents.swift in Sources */, + FBE59E78C51AE59228120999ACA53EC1 /* SocketAddress+NWEndpoint.swift in Sources */, + 997919169678152515DD1FA4B5E9231C /* StateManagedChannel.swift in Sources */, + 2F9453DDA53C6BCD2DCFFB168BA689CC /* SwiftNIOTransportServices-dummy.m in Sources */, + 795DEEBC169E6837FAB76CBD2E89A08C /* TCPOptions+SocketChannelOption.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F708DC1F73B45E572336E29D47BC8B67 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 82CD5A1334946C967ED05143D4DACA43 /* DebugInboundEventsHandler.swift in Sources */, + 75730F51DF804038A43327AA9514B161 /* DebugOutboundEventsHandler.swift in Sources */, + AA1C125E770AE299227ECFF33C5F1B94 /* FixedLengthFrameDecoder.swift in Sources */, + 53C40EF2BAC7F4EF8A334476A545C398 /* JSONRPCFraming.swift in Sources */, + B55076FBAEC4E2C7A4F59A909BD04436 /* JSONRPCFraming+ContentLengthHeader.swift in Sources */, + 5FA575431BE6BD8ABE69A690BA4943AB /* LengthFieldBasedFrameDecoder.swift in Sources */, + D19D08375F25913FF490193FBAA8614A /* LengthFieldPrepender.swift in Sources */, + 06CA44ED2A1053488482695266BAB93C /* LineBasedFrameDecoder.swift in Sources */, + 72A2E1CB3A9C7EAB39968D502638481E /* NIOExtrasError.swift in Sources */, + 84894DB19B389E92CBF1FCD01CCA7134 /* NIOLengthFieldBitLength.swift in Sources */, + 370E327857C0A7598490ABD014DA3C56 /* PCAPRingBuffer.swift in Sources */, + 64B43D4566523233D5EE198768F03492 /* QuiescingHelper.swift in Sources */, + A16B12794B4DFC3E76EEB6457F626795 /* RequestResponseHandler.swift in Sources */, + AB783D5B6EA24609BA0B9099ADA68E8D /* SwiftNIOExtras-dummy.m in Sources */, + 9180F29ED52CBC946F07529ADB8378A9 /* WritePCAPHandler.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FBF55E39820DAC82F4E4E5A3ECB8C8E9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E147CEBD99B43CFD13C60BB6E2514DFF /* _EmbeddedThroughput.swift in Sources */, + EB50AB7E66D9203D629090DDE2F4D209 /* _FakeResponseStream.swift in Sources */, + 9978300F278FBB2909212961DEADCAC2 /* _GRPCClientCodecHandler.swift in Sources */, + 213E350CBE45392D78D022FD67262278 /* _MessageContext.swift in Sources */, + F9B1FEE3A1FF29834BF8C7B9D24F3E38 /* Array+BoundsCheck.swift in Sources */, + 00304FEED98F36BA2B4E6138E2901DBF /* AsyncWriter.swift in Sources */, + CBDF03BED681B866C9CBC8E081651AFC /* BidirectionalStreamingCall.swift in Sources */, + B497C92DC53B438DD27AB3DD79242637 /* BidirectionalStreamingServerHandler.swift in Sources */, + AFA808AD0B8AF05DAB714D485099D878 /* Call.swift in Sources */, + 7C3107BE6BA61DBBB9AF9ACF7B74DAAD /* Call+AsyncRequestStreamWriter.swift in Sources */, + 03B6705143E65EC1723C9A10FE9FEEE8 /* CallDetails.swift in Sources */, + 40AC97C5D29738700D1542040EC3B7C8 /* CallOptions.swift in Sources */, + B9358AEFA08C2A82020460337AE934D5 /* CancellationError+GRPCStatusTransformable.swift in Sources */, + 10D52373AC94CCF8D89E7C8D9B176206 /* ClientCall.swift in Sources */, + FA2025E60FE222FA7D64F132E489DB3F /* ClientConnection.swift in Sources */, + F19088E1B32529B025BA2654FA289785 /* ClientConnection+NIOSSL.swift in Sources */, + 34B5DC4D539F2BB627BA9DB30FD5197E /* ClientConnection+NWTLS.swift in Sources */, + FC4DF8D2F505E1B461CCB047D4C40AE2 /* ClientConnectionConfiguration+NIOSSL.swift in Sources */, + AE4311E2B54BCD38E418D673F19E8E5A /* ClientErrorDelegate.swift in Sources */, + 7447A1EB3C57C08F765C8BC8C5C88FC8 /* ClientInterceptorContext.swift in Sources */, + 8D9D5713E6FC1E021FFF5238A6026EB6 /* ClientInterceptorPipeline.swift in Sources */, + 9A118EFBC45C01036600EB8D94A69F97 /* ClientInterceptorProtocol.swift in Sources */, + 4807FD6E6AAB401A5971FE2A9925B598 /* ClientInterceptors.swift in Sources */, + CF3800F8457C260F3A7927C32AD3881A /* ClientStreamingCall.swift in Sources */, + BFA351FBA9AC889942F0304B372AD1DF /* ClientStreamingServerHandler.swift in Sources */, + 62DF4079529380369B2BB7386F22CF2F /* ClientTransport.swift in Sources */, + 8CD34755FC451BCBEA1DAC9F5306636E /* ClientTransportFactory.swift in Sources */, + BB506D44EC0BB9223EE79F583252AE80 /* CompressionAlgorithm.swift in Sources */, + B03D4343E9D6CA937BEA99244A0AB1E6 /* ConnectionBackoff.swift in Sources */, + AD801317EBECC0C2ECE1FB7D29D8F63A /* ConnectionKeepalive.swift in Sources */, + 9830A6203AA060D2147558809319CA8D /* ConnectionManager.swift in Sources */, + F825380DCC6CC82AB040E8FA985DAA3C /* ConnectionManager+Delegates.swift in Sources */, + 68920084478A15324A2C7E4B78661ACA /* ConnectionManagerChannelProvider.swift in Sources */, + 4979CE34D784A50E49B5B5BECE0A5AB5 /* ConnectionManagerID.swift in Sources */, + D769D4D06E7DFD5B38BE20BC66561200 /* ConnectionPool.swift in Sources */, + 6D09754C1E727AB5A25828F276F8CB58 /* ConnectionPool+PerConnectionState.swift in Sources */, + ABCFCC4C4A69BF42F3E65FAF2A29DC75 /* ConnectionPool+Waiter.swift in Sources */, + 0E96C98EB2D7F8E410F48E943F490EA6 /* ConnectivityState.swift in Sources */, + 963811DD817F9A25665CB366882D00FA /* DebugOnly.swift in Sources */, + 10FA40334A22E567295DE81B8AE79415 /* DecompressionLimit.swift in Sources */, + E8C629BF8835F12558DB40C81ABC3B68 /* DelegatingErrorHandler.swift in Sources */, + 8AC112E917271A0E7669BF49FE7D8D50 /* Error+NIOSSL.swift in Sources */, + 8EB44CF3B5E5165ECB407883346138F9 /* EventLoopFuture+RecoverFromUncleanShutdown.swift in Sources */, + BAAE8BAEBE55A4662CD14F0AD6FFA1B2 /* FakeChannel.swift in Sources */, + 6FB6FD26A9C75AEFB3BD7FF6E52910C6 /* gRPC-Swiftp-dummy.m in Sources */, + 208B3E1D3EA0585B0AFBE7D0EBBE34E7 /* GRPCAsyncBidirectionalStreamingCall.swift in Sources */, + CB060A42FC429C12A22523A000868A6F /* GRPCAsyncClientStreamingCall.swift in Sources */, + B3BE0D29DC167F2F394F7D3E34644F13 /* GRPCAsyncRequestStream.swift in Sources */, + 11CE36975066F85CE305DAE06309A544 /* GRPCAsyncRequestStreamWriter.swift in Sources */, + 954F404A6D712201D9F78F1893B7E794 /* GRPCAsyncResponseStream.swift in Sources */, + 65E5CF094A4EF1FD8B0A9F11B2854FF2 /* GRPCAsyncResponseStreamWriter.swift in Sources */, + 62D02A250BFFC41A9CA41D71141D61F6 /* GRPCAsyncServerCallContext.swift in Sources */, + 5E2E5766780F9E5C0D6B21CFCA40F4A4 /* GRPCAsyncServerHandler.swift in Sources */, + C50CE66819CF8D303172E3184A877FD1 /* GRPCAsyncServerStreamingCall.swift in Sources */, + B1249F9A182915B23188BB117C96C627 /* GRPCAsyncUnaryCall.swift in Sources */, + 1978230AE0580B192FBF3589822A8207 /* GRPCChannel.swift in Sources */, + 558879C27D5562A3F4048F33FF75F9AC /* GRPCChannel+AsyncAwaitSupport.swift in Sources */, + 64E41914871F2A181FBFDEC999BDF86F /* GRPCChannelBuilder.swift in Sources */, + CA631C7462B02F1518D850BE655EFA45 /* GRPCChannelPool.swift in Sources */, + 3937C65ECB0CD2E2AEC99C27CFE98DFD /* GRPCClient.swift in Sources */, + 9242B61F4DDBC32696F866FA11DD81FF /* GRPCClient+AsyncAwaitSupport.swift in Sources */, + 2E01037F1DBA7627B825769DA9FCC401 /* GRPCClientChannelHandler.swift in Sources */, + DB6E76EB84F509A527E48E4A0FB98FA7 /* GRPCClientStateMachine.swift in Sources */, + E9B42EFC6940A6552B2744DFDC85822B /* GRPCContentType.swift in Sources */, + 9F10A0E482367468FD7AA526A7826FE4 /* GRPCError.swift in Sources */, + FCFB679BABFBF4E0E9FC812BD91B7DFB /* GRPCHeaderName.swift in Sources */, + 7241A8BAE8411A4E7DCE5B1759F1C89E /* GRPCIdleHandler.swift in Sources */, + 289BB4383D8D0E6BAC66A02DABA987C9 /* GRPCIdleHandlerStateMachine.swift in Sources */, + B509EDB7A6E94BBBBEE39B062C02A37E /* GRPCKeepaliveHandlers.swift in Sources */, + 92BCA5ACF42CEECB51875ECBB000E300 /* GRPCLogger.swift in Sources */, + 628FACAC8ED43F663F9D52984EA90BB9 /* GRPCPayload.swift in Sources */, + 1647BDFD386D433CBE0A46F1133299EA /* GRPCSendable.swift in Sources */, + 1D95638B24CD46FD3DE23CC05EC50DBD /* GRPCServerPipelineConfigurator.swift in Sources */, + BF7991AF3BAFFFB3A3BD44A70A0A798A /* GRPCServerRequestRoutingHandler.swift in Sources */, + 1F7E97D272599397F5A938FE90AAA50F /* GRPCServiceDescription.swift in Sources */, + 030A3E51B9E56CD6146F186166ED4FFC /* GRPCStatus.swift in Sources */, + 9422C6187DDB4ADEF16B99F65C6EB16C /* GRPCStatusAndMetadata.swift in Sources */, + 0CE9A2762524F23D61F497FD9A621F08 /* GRPCStatusMessageMarshaller.swift in Sources */, + 4E886EAD99747CBEA13F5B83A07E10DB /* GRPCTimeout.swift in Sources */, + A233010267CDD35546791488F54A0225 /* GRPCTLSConfiguration.swift in Sources */, + D56F5E0E1A036C494A3B19CD7BE10866 /* GRPCWebToHTTP2ServerCodec.swift in Sources */, + E27E10710700E3BD84F597B8D007EEEE /* HTTP2ToRawGRPCServerCodec.swift in Sources */, + 6F3A8A7781B3B803292C8B904538D45F /* HTTP2ToRawGRPCStateMachine.swift in Sources */, + 092350853F2356C1D0C80789E14ACD3D /* InterceptorContextList.swift in Sources */, + AAB1DAD7EE0ADC803800D8AB46D927B9 /* LazyEventLoopPromise.swift in Sources */, + 8376D3D00D90F1304232A1CA08EBB7EA /* LengthPrefixedMessageReader.swift in Sources */, + 967576A5F308F9A5D22642DFE25F6D73 /* LengthPrefixedMessageWriter.swift in Sources */, + A21BBC955341A72B51526E645C6C84D4 /* Logger.swift in Sources */, + 9A1BB524FAE632DB09FE770BE8DC8F0F /* LoggingServerErrorDelegate.swift in Sources */, + 05D96EEA3633D34242E9FC7D523CF2BE /* MessageEncoding.swift in Sources */, + 4A2CBEDEF036B20A7C990A2730D64C3C /* MessageEncodingHeaderValidator.swift in Sources */, + E721A722DE94103D703212DF73FFF2F2 /* MessageParts.swift in Sources */, + 8F29CAB46A3AF7609A396CE22671F423 /* PassthroughMessageSequence.swift in Sources */, + 41563D7A88B2B5AB455F7369556CE6A5 /* PassthroughMessageSource.swift in Sources */, + 62C96961DEEA2FA4F262498F3D1B33BF /* PlatformSupport.swift in Sources */, + 62B7FC1AB67641CA77E7C088EA4E1999 /* PooledChannel.swift in Sources */, + 2AE24649677F27909C566071BC24AD2C /* PoolManager.swift in Sources */, + 7C530F8FAE658F95E15FBCD2CBA5EEAE /* PoolManagerStateMachine.swift in Sources */, + 0C453F0CBBFD3329A488F0EF6DFDD488 /* PoolManagerStateMachine+PerPoolState.swift in Sources */, + A66EA069CD81F972736548BA4DE4E1CA /* ReadWriteStates.swift in Sources */, + 0E984D6070F467D3EA99D4F466A6B55A /* Ref.swift in Sources */, + A2E1B133255638FBB5F55C4CCCF77267 /* ResponseContainers.swift in Sources */, + 69E7229D084E4C32BD9D1111570E3B16 /* ResponsePartContainer.swift in Sources */, + 13D2EC002DF5B19A2E953F954BF2B98E /* Serialization.swift in Sources */, + 382F693474A72AE3B04DEE1872A92A6B /* Server.swift in Sources */, + A972F08843D4B1003BA8469D736F5FBD /* Server+NIOSSL.swift in Sources */, + 9C8A66CCD5209B42FEE81B7198F1F9DD /* ServerBuilder.swift in Sources */, + 42BB279BAACDE5F42F5E467429B295CB /* ServerBuilder+NIOSSL.swift in Sources */, + 035E1DAAB190ECE75BBC3C2C01A2C7F5 /* ServerCallContext.swift in Sources */, + 9C06DF25247F6FF83E23E0FD066CB5C4 /* ServerChannelErrorHandler.swift in Sources */, + 33AB8FFB5F57EBE4E10F14914D000CE2 /* ServerErrorDelegate.swift in Sources */, + 8D837DE5AF2AC58CB2D2532150E26E0B /* ServerErrorProcessor.swift in Sources */, + 4A2E859236B917B1EC38CB3337EFBF08 /* ServerHandlerProtocol.swift in Sources */, + A21E13377597DDD36D32828911EB7AF0 /* ServerHandlerStateMachine.swift in Sources */, + 0111A299C84506713936964EA9964A81 /* ServerHandlerStateMachine+Actions.swift in Sources */, + C02EB9B65A254C5450BFE7FD06E78727 /* ServerHandlerStateMachine+Draining.swift in Sources */, + 1C0188522AE8F90E65BBF12A4A57E5F0 /* ServerHandlerStateMachine+Finished.swift in Sources */, + DC8BCD4B3A292E7A4482B1A17A262620 /* ServerHandlerStateMachine+Handling.swift in Sources */, + 92310C4D2834697ED20400E7948B5874 /* ServerHandlerStateMachine+Idle.swift in Sources */, + A9ED333C9D5490ED6E875E3947CB4CFA /* ServerInterceptorContext.swift in Sources */, + 5526D75473578EAC2B1EA77E29B899D8 /* ServerInterceptorPipeline.swift in Sources */, + 0B3AECF339BD39C50E6CDEE4BDC1BD6D /* ServerInterceptors.swift in Sources */, + 6DDB62C833FF89AE8452990561387B2E /* ServerInterceptorStateMachine.swift in Sources */, + 851B74D2962016A0B93A58BA47E04178 /* ServerInterceptorStateMachine+Actions.swift in Sources */, + CE1A174322BF9F6998B6FD18C9ED362D /* ServerInterceptorStateMachine+Finished.swift in Sources */, + 1A37C655C603D137C76749E5787AAFD9 /* ServerInterceptorStateMachine+Intercepting.swift in Sources */, + D45DD7CA09A8CF82B8287AB1581494F0 /* ServerStreamingCall.swift in Sources */, + 598831EFD3048806C3FA3AD56ACDF54D /* ServerStreamingServerHandler.swift in Sources */, + 0503B9C4E26816ADE8FF091792BF5CF3 /* Stopwatch.swift in Sources */, + ACA0F212F4B81B2C29FF2A2BC56ACD34 /* StreamEvent.swift in Sources */, + 29DB79786DCDF3D889D273E0FA343F03 /* StreamingResponseCallContext.swift in Sources */, + 1C02A39D593EFE131B22846E6396F7D0 /* StreamLender.swift in Sources */, + 57E3D9C77D4BF46D20B4623A77756EF0 /* StreamState.swift in Sources */, + FE451E52E11EC735B9B8803F94027594 /* TimeLimit.swift in Sources */, + 2C620C5D7AEC13C573DB767902CD7A03 /* TLSVerificationHandler.swift in Sources */, + 18A8611ADD250CF40765F939E6DFD74B /* UnaryCall.swift in Sources */, + 0327B97220F858FE9F756549296DBDD3 /* UnaryResponseCallContext.swift in Sources */, + 2299A0C9729AD55F9716F23E6F69B3E6 /* UnaryServerHandler.swift in Sources */, + F0B228EA8A6211C8B6CEF100AD165047 /* UserInfo.swift in Sources */, + DB8E1659FB468E5F18878493EF3C69A3 /* Version.swift in Sources */, + 0FE49E3D3126E4B6FE4368B964522B90 /* WebCORSHandler.swift in Sources */, + A7B20E66948F7AB9FAD6B822A0907AE4 /* WriteCapturingHandler.swift in Sources */, + DAE1D6B30C3EBE1E5E91599A18B29E8D /* Zlib.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 00DA780A54D0828CD6955B253F04AF4D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOFoundationCompat; + target = 834F3DE9EFC7B90102D63A51F6A9AF51 /* SwiftNIOFoundationCompat */; + targetProxy = 567428280E76013316E58E798DD673D6 /* PBXContainerItemProxy */; + }; + 01E9343BA9310799B63E59391389F4B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 166AC9F8687964D156096204D85FF88C /* PBXContainerItemProxy */; + }; + 0228D2C2A2501C05BDA6FB0A1BAF6348 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 97A1CE3537297B2C6228270754F2BB12 /* PBXContainerItemProxy */; + }; + 038C7A501E306882F7896E00DE87C09A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BigInt; + target = 09DD83B7D075842A3A5105AD410BD38A /* BigInt */; + targetProxy = D4C0F307E7D8BD2C6B68A15135F5BDE3 /* PBXContainerItemProxy */; + }; + 044AA22809D937EFE8E18B9152746312 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOExtras; + target = 61DB9F97C45B368C17F830199512E361 /* SwiftNIOExtras */; + targetProxy = 4410D3443B9F65A10FF461AD09E78210 /* PBXContainerItemProxy */; + }; + 046FDBE7F90B7109E462B91DED822C01 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Swift; + target = 814D3CA630EB31504C9C25A1AE6B75B7 /* secp256k1Swift */; + targetProxy = 0ABC08C42E9CD5AEE7F38BA4A27E723C /* PBXContainerItemProxy */; + }; + 04774F6BC7D28563253FB17FACE90C06 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 7A1422DA53F2C9AAB83526FF3B48D9E9 /* PBXContainerItemProxy */; + }; + 06B9823BAC46C9307028CF42C5D94FD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 2A5514C534984ED14F98EDA40FEBE4FD /* PBXContainerItemProxy */; + }; + 06CCE66A4CBF9A6FA3E20005E0C0A8AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSL; + target = 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */; + targetProxy = B65D7796D78DA1252A779595C98E0D07 /* PBXContainerItemProxy */; + }; + 06E598FC4D34E504398BAC10C836FE85 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 5C8D41E369967A0CAF3464324FD155E2 /* PBXContainerItemProxy */; + }; + 078888E1021FBDAD5A98EC52A37C1840 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = FEF2D44EEE9CB02013372B0F411F451A /* PBXContainerItemProxy */; + }; + 07B57AB0246092FC3892BDAC6DFBDEC4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 2521065BFAED9868C6354FFC483ABE6C /* PBXContainerItemProxy */; + }; + 08DFBAB7A2D1F8291FDC3EDC582621F4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = BBEC2851149C6DC5B8FB4C160813E4E4 /* PBXContainerItemProxy */; + }; + 09A630B50C50046DAB2CC4A44DDA614A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Cadence; + target = CE9E4A87F29CA10BA13A4B9B6FCCD386 /* Cadence */; + targetProxy = 1561371AD8F22F67C5360697A1C7C20A /* PBXContainerItemProxy */; + }; + 0A324B3E2BB7648094044F017A8EE0A0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 2F65C9D254D345582D1CA26215A9EF64 /* PBXContainerItemProxy */; + }; + 10D348AC8F287D5614D83CD504205A88 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = AC323AB2D83D96B7A83E1A72C24EB835 /* PBXContainerItemProxy */; + }; + 10E6BD943581D6734145D8EDAE2FA3CB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 8A67AAFB1201BF513252E61B60D97B19 /* PBXContainerItemProxy */; + }; + 119763A794B9463DD24A674A2967E366 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = AE4788BA882A138FEC36F0591DF8AB76 /* PBXContainerItemProxy */; + }; + 128F2DED5661F0E0E9437165AE51D3FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP2; + target = 17112F66EE5BDC5584A51CF4FCE7631A /* SwiftNIOHTTP2 */; + targetProxy = 2509575E1DEAB6AEE8DF714B23F8F3AD /* PBXContainerItemProxy */; + }; + 13C317CD96A879F250EDB9C9B1EBA9A5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BigInt; + target = 09DD83B7D075842A3A5105AD410BD38A /* BigInt */; + targetProxy = DF58493A604E051BE8E58492795839D4 /* PBXContainerItemProxy */; + }; + 1427A616844C28E535D8CFD98FC2FA4A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOExtras; + target = 61DB9F97C45B368C17F830199512E361 /* SwiftNIOExtras */; + targetProxy = D79CDA0100D06E9A7C575C4C3D0290F5 /* PBXContainerItemProxy */; + }; + 182165BFC33EAED7BFFB1393A3D91A32 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = B07A3799A069CF3100BCF7D61C8F5161 /* PBXContainerItemProxy */; + }; + 1AF27CB171A41D0F2E56014AAC1F8D4F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 89F5EA84604067AC37A943E275E5BFFD /* PBXContainerItemProxy */; + }; + 1B7CE3198E1D89B9062D9454D22F0F6A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 30C846D3C3BD2898035960FCCCB31A61 /* PBXContainerItemProxy */; + }; + 1CAA8EB937A8612FA23212C62C91CBBD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Cadence; + target = CE9E4A87F29CA10BA13A4B9B6FCCD386 /* Cadence */; + targetProxy = 26821F82ECAB576923B07947E8B2AAE1 /* PBXContainerItemProxy */; + }; + 1CDF6C7D36C2712346A713E21E1D9688 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = E47E05DE0D87639D83EADFE7EBFA3325 /* PBXContainerItemProxy */; + }; + 1DD55CB8D3ED13C199F01876D85E4565 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHPACK; + target = F71DD9985215E142F625AD23A9121477 /* SwiftNIOHPACK */; + targetProxy = A068280261EB172A7C160505F4BE5E1A /* PBXContainerItemProxy */; + }; + 1F5F59406C48B5B70BA5E8C7B53582F0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = ABDEDD5288A8D4B8B2A73AE3A4ACA387 /* PBXContainerItemProxy */; + }; + 20188C8764A764A447A36FCCCAB999FE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 4BE0634985444EB31423906950EB2B07 /* PBXContainerItemProxy */; + }; + 21A37639297A8B0A4066292E5A50C545 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = A507FC181960BD26EF143FB76515F8E0 /* PBXContainerItemProxy */; + }; + 224BE7E52FFC7F40E296462A6D1C84E2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = B9C07ED05B4DEA8EA7227C6AFA0B298D /* PBXContainerItemProxy */; + }; + 22A19E247DC81B9AD464DEA07EA4F4ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOHTTPParser; + target = 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */; + targetProxy = FECFB85B4E98093FF67F5590C09F53A2 /* PBXContainerItemProxy */; + }; + 2349BAC88578FF1FAAC2DDA69C6D3351 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = B00340090F9EB12B85C89D463ABCD6E0 /* PBXContainerItemProxy */; + }; + 246BDE28579EBF1384598444EB0C15CC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftProtobuf; + target = A5F702E0DA383BC1479572581615A916 /* SwiftProtobuf */; + targetProxy = F95C0132BC329B0ADD7C3D709A1C0E3D /* PBXContainerItemProxy */; + }; + 25411863FC966F97FFABB07BC6DB5B5C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTLS; + target = E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */; + targetProxy = 4787086F9EAC3A1599AD7984A0CE6CEA /* PBXContainerItemProxy */; + }; + 27199B8000EE5126C01162FB8E7705F4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 011FCF9545362173F0FBE27D15FDA00F /* PBXContainerItemProxy */; + }; + 28A6EAED54DDB1B79A96C90C2A4FBC06 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 0DF445E46C0F343D535374EBA80D12D1 /* PBXContainerItemProxy */; + }; + 2C416606605ED7ECFD414485A32A22BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSLShims; + target = 65C8D0D3B04F444B821EB675E4D821DA /* CNIOBoringSSLShims */; + targetProxy = B43293B3D6210ECD720AF479AA680A1A /* PBXContainerItemProxy */; + }; + 2C5FFFE3153FC0AA03ED2275E3F372CA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 32CC88FDE27D57C6F78D16D8EC361579 /* PBXContainerItemProxy */; + }; + 2DDB5D0FF22B16370AB44E310D509B29 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = F75D262DCDAB8D705DBD93A4CB86FC4D /* PBXContainerItemProxy */; + }; + 2E34FE252928549C71FE69756456A800 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = E6B7DAB080EE245BA479A5E112486C37 /* PBXContainerItemProxy */; + }; + 308025E0D6B0EC45F1900E3E8C6B1DBF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 59EC701FAC3B88727031AB0FDCD4E39F /* PBXContainerItemProxy */; + }; + 30F0D309975272280F791551247C90E9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 72F7D63905F7B9FD11391B2AD0587DFF /* PBXContainerItemProxy */; + }; + 30FADCA34C3972AED11A3862AB22A8F5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSL; + target = 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */; + targetProxy = C6DDD11BFFE61C6BB1B21C9076E9453F /* PBXContainerItemProxy */; + }; + 3127A864E36969E73BDE1F66D93AB93E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CryptoSwift; + target = 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */; + targetProxy = F3352E2AB5DB41BEA6C15865C47DB699 /* PBXContainerItemProxy */; + }; + 3303EAB3B9E615FC912071B7A553B942 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 913F2557E49A59D1DA1C947F3AAF1D50 /* PBXContainerItemProxy */; + }; + 34BDD9822AF2141C6BB435625A73BA4D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOHTTPParser; + target = 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */; + targetProxy = 113AA8BBE0A13E9CC6BFB6F7DF17380C /* PBXContainerItemProxy */; + }; + 3508159F99D633C18438C8D07C579330 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 07BF6A63FB50A073CE1CD9341FBDC653 /* PBXContainerItemProxy */; + }; + 399F4FEB41957355CC088ED1C386C00F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOExtras; + target = 61DB9F97C45B368C17F830199512E361 /* SwiftNIOExtras */; + targetProxy = 0E5C20DE1096DDD01912F83CEA7257C3 /* PBXContainerItemProxy */; + }; + 3A0C249E87FBE56CF6FB0EBC8E1F7F3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MercariQRScanner; + target = F52E6DA0104A4F8C767EF42CAE3D09F4 /* MercariQRScanner */; + targetProxy = 38D31EAB0513D90E61C29FAD29BDA30E /* PBXContainerItemProxy */; + }; + 3B11C2F9C6D616FDD78D75EBB8C81B19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 6D63A243211BC9A0679F952887020D61 /* PBXContainerItemProxy */; + }; + 3BA9F2AEA8739971CEE8A9A3AAD6B9D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SVProgressHUD; + target = 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */; + targetProxy = 21FEF6FA7764BCF0C73A76DD5E8E8700 /* PBXContainerItemProxy */; + }; + 3E792FF89C3F369FDE71E23E97C2CB98 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 186FEA6AB4D1B52F85B5EBB3405320E0 /* PBXContainerItemProxy */; + }; + 3F6EB28B7F01BED3D7BE0A2DBEA97518 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 98CBA552B690C24228BB719478264946 /* PBXContainerItemProxy */; + }; + 43ED3B641A97B27FA67DD99C47C86D77 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = FA0C0459529775D533F0D601AFDE7A67 /* PBXContainerItemProxy */; + }; + 466B36C87C2A5E03EFAC7C60FCE0D0EA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP1; + target = 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */; + targetProxy = 3698DDDA359A8167FDF5106B36B81A27 /* PBXContainerItemProxy */; + }; + 47D79CB3533EAED27ED9830DDFB7D2C5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 9A1ED3674DC1D2A9C27EAD6EB793FAC5 /* PBXContainerItemProxy */; + }; + 484C6F6D564D2791C6219ED01119375D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 36407F1DA4AC005C2FBA349D8C0BE391 /* PBXContainerItemProxy */; + }; + 48C889037C290D6D74646196C9E5D916 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOHTTPParser; + target = 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */; + targetProxy = 9D523B64DA99BD016DB79C6675FEDF59 /* PBXContainerItemProxy */; + }; + 4A073398C91DE14D95AB5073ECDD9164 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 71886DD1D10B704945D4AF329EA0354F /* PBXContainerItemProxy */; + }; + 4A25CD31AEE04D37F9B962232F7239F1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = BC1A0A0B3AFED043AC112F357551069B /* PBXContainerItemProxy */; + }; + 4A76DE25D040F234D7B1A635A2CCA9A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP2; + target = 17112F66EE5BDC5584A51CF4FCE7631A /* SwiftNIOHTTP2 */; + targetProxy = 085ADAFE3D4497B14E4E66AB6E8BF713 /* PBXContainerItemProxy */; + }; + 4C36BA04A342CAE8B71AE8B5B5F2B052 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = CB0C57F8A952E7615EDC1BA0BDA1BB60 /* PBXContainerItemProxy */; + }; + 4D4586E5C01E7C85D2EE7FA575F10FF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 608DD3935EFCF53434BE7677B6D12514 /* PBXContainerItemProxy */; + }; + 4D5DC35EC264A91C48C49DC51E3C60EB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSL; + target = 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */; + targetProxy = 454CDA7172449E4C4DD703ED0C7F6069 /* PBXContainerItemProxy */; + }; + 4F14857032D0393F64CB489FDA2703FE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 62B4BED0BEA634F9AF755194CE21319F /* PBXContainerItemProxy */; + }; + 4F533D4F2332CF3960D0C83F5B229947 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTransportServices; + target = 5D6DC8585F20CBE789F7D3D4F645980E /* SwiftNIOTransportServices */; + targetProxy = 0EB35E76647B981007A74F763038058D /* PBXContainerItemProxy */; + }; + 4FD2218FD88C7E56F38AF69E73231F36 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = C7B86302CC89BA2BD33F605BA2D19897 /* PBXContainerItemProxy */; + }; + 5188BDA4C9DBAD07227E6329122134DD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftyJSON; + target = D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */; + targetProxy = 90636EEA2DE2AD94DDF681285ADDAC62 /* PBXContainerItemProxy */; + }; + 51B457AECBA3CFF8548C722E434237F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = D6730A1A00AC749D4571513E234DE057 /* PBXContainerItemProxy */; + }; + 5318487F4F34AA2330A8094D11DB8D4A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOFoundationCompat; + target = 834F3DE9EFC7B90102D63A51F6A9AF51 /* SwiftNIOFoundationCompat */; + targetProxy = 9284D82866A643F412BA470CE71F9DC0 /* PBXContainerItemProxy */; + }; + 546A27887AE6ADC9F74D29F811C93B1F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = E62582A92773F0D64A955AD2684CF9F5 /* PBXContainerItemProxy */; + }; + 54EC16322C9803015F846B01CEAE69AB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 150595293A93FB2D283EA1466C123621 /* PBXContainerItemProxy */; + }; + 54F6D47245B2D4F04860A43CA04E5C9F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "gRPC-Swiftp"; + target = 851EADC4C9B098805B57AB058076FF60 /* gRPC-Swiftp */; + targetProxy = 9CA09BAA47DFC260B05F0FBDE7C4DD12 /* PBXContainerItemProxy */; + }; + 550732659089AE9960375A7D1C66ADD1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SVProgressHUD; + target = 1C8D67D8B72D6BA42CCEDB648537A340 /* SVProgressHUD */; + targetProxy = 64F7E28614025CC638DFAAABC030AA3F /* PBXContainerItemProxy */; + }; + 55D38AD4D69DE99D53DAA79DF581E16B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTransportServices; + target = 5D6DC8585F20CBE789F7D3D4F645980E /* SwiftNIOTransportServices */; + targetProxy = 561DB9653F62FEF27FACB5AE49E2EC7E /* PBXContainerItemProxy */; + }; + 5733BDB0F5749B55BDBBB0C82637FBF8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 46C8F4A16410C25E72369CD68DBAC10F /* PBXContainerItemProxy */; + }; + 585319BDE94DE971B3AA54C7472891E4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = E582EC05CFA7ABB456657147779A415B /* PBXContainerItemProxy */; + }; + 5A6F64245EBFDFF3540C5313CF201135 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = BFD520B864050F77C59E22B0E5BE3355 /* PBXContainerItemProxy */; + }; + 5B54C3963B31A7E92AFE75C7AB9D92D2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 48DF44B1FF4BA87119DE8E0B025BDDA8 /* PBXContainerItemProxy */; + }; + 5B96494B5A94BBF7ED38D942AED3D63D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftProtobuf; + target = A5F702E0DA383BC1479572581615A916 /* SwiftProtobuf */; + targetProxy = 007E2C622AE440DBAA72215A3BC7216A /* PBXContainerItemProxy */; + }; + 5CA46EE889330FEDA5ADD04EA412BD20 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 67420F30499074783FC59C820F1F9DD2 /* PBXContainerItemProxy */; + }; + 5D739DDF26E9E0AA52742A61A2E4A80D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 2B5B555A20BA12AC80F7EAB92FE9BA4E /* PBXContainerItemProxy */; + }; + 600B835B23FA6C600C45FFCC1DAE599F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = CFBE8C5F53D76F6229EC8E7B95BD4382 /* PBXContainerItemProxy */; + }; + 603F818186D87D5DBBED2F809DE081C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BloctoSDK; + target = 5A8A5B4451A77B0A6D36B131E2974E23 /* BloctoSDK */; + targetProxy = 1EC76625A150AF6659E66157A04DB6D9 /* PBXContainerItemProxy */; + }; + 6124CD8E872D0BDAE242360EC893C761 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 2A275ED137F21C7EA192634F03985446 /* PBXContainerItemProxy */; + }; + 61A8F93412921E5C3409F73385C623F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 745BD01F7202E46E3A389374712646EC /* PBXContainerItemProxy */; + }; + 61A94C70864366E841DA3DDFC7588C5C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "gRPC-Swiftp"; + target = 851EADC4C9B098805B57AB058076FF60 /* gRPC-Swiftp */; + targetProxy = E59038072916A52065F0536132BB59EF /* PBXContainerItemProxy */; + }; + 62FEF478BD2A0B784D1FB1163597E0E5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-fanex"; + target = D5D61C34B6B0F36656A57CF77C297BA6 /* Pods-fanex */; + targetProxy = 489812E11F21AA4D734684968B50FC51 /* PBXContainerItemProxy */; + }; + 65902DBD13E5BC6AD631595F19B0A4CA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 16706E4FAB9B83FC505D57767BD0D1EC /* PBXContainerItemProxy */; + }; + 65F6100DC8F6CC635E57CEE43C5BB19F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 063AE03CF52FD4089CCA881D8069C526 /* PBXContainerItemProxy */; + }; + 6665E88CB89C7727C16695F329D4E2BF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 6D9958164AEFF9DE5180A6BAEC533FA5 /* PBXContainerItemProxy */; + }; + 69713A8FD6655A8ECDB4247C61CA843B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 1115DE116B293761C48C4DD97C7B1E1A /* PBXContainerItemProxy */; + }; + 6CB5E1BF7326C5811194FC0E6D5149D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = AF86CA6C6B4EEA71024D9B73CF95F7E4 /* PBXContainerItemProxy */; + }; + 6DA8991D847DEF37EB8A0DC372908CCC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 31401FDD32168A417476E33592D92FFC /* PBXContainerItemProxy */; + }; + 6E6D337AF318CF564021D632E6D6F8CF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftProtobuf; + target = A5F702E0DA383BC1479572581615A916 /* SwiftProtobuf */; + targetProxy = D24278AA8EBCC775AE29ECEE478BA235 /* PBXContainerItemProxy */; + }; + 6EC112BBED520555C7D68F82B6ABD2F9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSL; + target = 71D94F5C545887C8BC575883E745A3DF /* CNIOBoringSSL */; + targetProxy = F4B783D816412CCC6DE9E69636FEA64E /* PBXContainerItemProxy */; + }; + 6FD8E056E8FD62A4293B191B1B851639 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 179820060F76F48D063EEC8ADA94D0BD /* PBXContainerItemProxy */; + }; + 6FF7A2301E0B50784445E8CF8545B688 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTLS; + target = E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */; + targetProxy = 2C8ADE5F6348A98677CD308906BC49F1 /* PBXContainerItemProxy */; + }; + 7033F7A064718ED5A9A1A42FD13DDA93 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 720031B6A08B4106F7F89EE671AB17CC /* PBXContainerItemProxy */; + }; + 704D000B7BF4CFF13A8CA335877479F6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 8251E5FB0C03ED523D4EBA886C92CBDC /* PBXContainerItemProxy */; + }; + 70E9AF8AA19DEFA1311BC8AACFEACDBD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CGRPCZlibp; + target = 54382245E5C9DB4A3CFB906FD97A35BB /* CGRPCZlibp */; + targetProxy = F0BD72A30A4162150B585B359E1B479B /* PBXContainerItemProxy */; + }; + 7157BE1E049E3DA30432821C2ED2940E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 1F3DAC5DEA2109107383A49EE149DDB9 /* PBXContainerItemProxy */; + }; + 724615429F82EBD938FF3D5E7BF7F895 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP1; + target = 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */; + targetProxy = 83934CCE1EDEEB92855858388EA00529 /* PBXContainerItemProxy */; + }; + 7295DF9B4CCCD6C2AF470FA9994A968B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 1DF019299CA434C64BAA7F7ABD4156C4 /* PBXContainerItemProxy */; + }; + 72DC94BB5FE75FFF290FC13D6E3938A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 39B9E7790728BE450AFB2655675DFE59 /* PBXContainerItemProxy */; + }; + 73313742ED6C81DB6A3109D783504DAE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = D4705674247BEB907A5564A1895E08F8 /* PBXContainerItemProxy */; + }; + 78661ED6DD469638173ED9B30DC3B7C5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CryptoSwift; + target = 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */; + targetProxy = C1693564C05C979A690CF92B218A38AA /* PBXContainerItemProxy */; + }; + 79762CE44253D21CEB614CA9EE210F3D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MercariQRScanner; + target = F52E6DA0104A4F8C767EF42CAE3D09F4 /* MercariQRScanner */; + targetProxy = EB201969191599A59538AF32D6EB882A /* PBXContainerItemProxy */; + }; + 798D84E6FBC0F6DE7942CD6AA0F031CC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP2; + target = 17112F66EE5BDC5584A51CF4FCE7631A /* SwiftNIOHTTP2 */; + targetProxy = 8976B05569E2A8F510B55C6BBE8FD179 /* PBXContainerItemProxy */; + }; + 7A567600474F7FEC4911AB0703628753 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = DDC4B8191ACBEB54241AE7D92A9B0E41 /* PBXContainerItemProxy */; + }; + 7C4E2D7DA3FA3D0A71DA0F076ADBC8B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Cadence; + target = CE9E4A87F29CA10BA13A4B9B6FCCD386 /* Cadence */; + targetProxy = C0E2677EA5DA9E47707A3D85539D7D70 /* PBXContainerItemProxy */; + }; + 7D33427A3B4F9D9DD2E6F9395412E051 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSLShims; + target = 65C8D0D3B04F444B821EB675E4D821DA /* CNIOBoringSSLShims */; + targetProxy = 3E9E583206CE24BA87D4DF69FD34A227 /* PBXContainerItemProxy */; + }; + 8025DBD1B95AD96E533CEB706EEDB94D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 3A38E91E97412EF882B4B5C46D722124 /* PBXContainerItemProxy */; + }; + 80541813E5980BD572277A3246DEE61A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PopupDialog; + target = 6E71929B582F8CD57B3DC1FD6560F047 /* PopupDialog */; + targetProxy = 744A0FD25358AC3F85726588CC53BFCF /* PBXContainerItemProxy */; + }; + 8114A10AE43DA12050137E641FCC6798 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHPACK; + target = F71DD9985215E142F625AD23A9121477 /* SwiftNIOHPACK */; + targetProxy = A3F7F837E3861CF47CD3E07FFFCE9928 /* PBXContainerItemProxy */; + }; + 860E7990858BFDA09A6451DA04AA5AA8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FlowSDK; + target = 446DA03EDE44E6615A2A146E3D90AA3D /* FlowSDK */; + targetProxy = ACAA08D268FCCC3A032638503C6B6323 /* PBXContainerItemProxy */; + }; + 88C96393C60357B8577097AAC9724A70 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOSSL; + target = CF4D556EB90FFD6388321BDFD45BDDB3 /* SwiftNIOSSL */; + targetProxy = ED1B203A406398F17142F07FBF0793E3 /* PBXContainerItemProxy */; + }; + 8A0DED7E83D4EA888429A21E188C08BC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOHTTPParser; + target = 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */; + targetProxy = 8A044C1E99A8260CAD6C6968013A1FA1 /* PBXContainerItemProxy */; + }; + 8A816C625035C3E0DD6373B415EC15BC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Logging; + target = 2ABF3F8EC6CE525E1E02C51D72C64E94 /* Logging */; + targetProxy = 1D4BF5981FD9B49F3F1BD59ADF246E63 /* PBXContainerItemProxy */; + }; + 8AF9202713D94710C483ED2F461F861D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = C6CA2332035A1B248840C9F30429C5B8 /* PBXContainerItemProxy */; + }; + 8D65FEFB21149E75A7B947B214879160 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 0C1F1BB9B17126E7101A54AEEAF4A0B1 /* PBXContainerItemProxy */; + }; + 90E73C724F8C103C52034DE49546CF27 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CGRPCZlibp; + target = 54382245E5C9DB4A3CFB906FD97A35BB /* CGRPCZlibp */; + targetProxy = 461FAABF37F0331E4D4817912711A708 /* PBXContainerItemProxy */; + }; + 92A9D0154923980F26EF819867844A6C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = E726A64E631B923B2AEFFFE04A463346 /* PBXContainerItemProxy */; + }; + 9308049DB96F3DC42DD01E73F8DA84D2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BloctoSDK; + target = 5A8A5B4451A77B0A6D36B131E2974E23 /* BloctoSDK */; + targetProxy = F1ADDFAFBD1BFFB92296406D0A25ECE8 /* PBXContainerItemProxy */; + }; + 94653D726981294EFDD10F4430CDED65 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SDWebImage; + target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; + targetProxy = 9F25906B9B7A431FF1E878AC47D58463 /* PBXContainerItemProxy */; + }; + 966C16AA0B951E5E0402723BB04A1E4D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTLS; + target = E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */; + targetProxy = 926103AA6EE13F1BFF5B4D090941122A /* PBXContainerItemProxy */; + }; + 98CE072D38EEECC3FA49A812685F1185 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = DC9F331C33A5AA3ED7041D822576A892 /* PBXContainerItemProxy */; + }; + 991DF2BF2B57BA9400358F380D7A75B8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 474CB4272BC96F5C8D4C011FC2CBB4CE /* PBXContainerItemProxy */; + }; + 9989B427686884AF149B7EF37256D53D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 236E60C5BA1B88E2D5957A292A09A10B /* PBXContainerItemProxy */; + }; + 99D973172F12E139B18283156ED79561 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 7D176593519D8732AF619B9F6022B558 /* PBXContainerItemProxy */; + }; + 9AAA94E5D40BE342986977145985905B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = 36471A42BAD1E0F83090D6B679884A35 /* PBXContainerItemProxy */; + }; + 9B2A7F11E04BEF1541D71F817BE169AA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FlowSDK; + target = 446DA03EDE44E6615A2A146E3D90AA3D /* FlowSDK */; + targetProxy = 8B12164E223B7EF0BDA57157FA071117 /* PBXContainerItemProxy */; + }; + 9B5BE5013EB9FDF6193D67452B6CEC43 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = DynamicBlurView; + target = 7D914FA2F03C860D5133BA2DB87C594A /* DynamicBlurView */; + targetProxy = 612A8EB388C5C59728D21E714BC0B0D0 /* PBXContainerItemProxy */; + }; + A032D968F2BCF6A51269B97E963832ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PopupDialog; + target = 6E71929B582F8CD57B3DC1FD6560F047 /* PopupDialog */; + targetProxy = 0FF205AB8D8A599D83FA92934D1E276C /* PBXContainerItemProxy */; + }; + A059A24DED83656C90DB6A5F9989FE41 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = F3DC40A044D9C4C5ADA27AD1AA3346FF /* PBXContainerItemProxy */; + }; + A162E01E813844A1312DD9BFBFD548E6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "gRPC-Swiftp"; + target = 851EADC4C9B098805B57AB058076FF60 /* gRPC-Swiftp */; + targetProxy = 400938569EC22CF0264EA228555F5C18 /* PBXContainerItemProxy */; + }; + A39188E7BEE00FE6FC585B1CCEC5D18D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FCL-SDK"; + target = 85E705C55EE1E21751DAF1510D4F983E /* FCL-SDK */; + targetProxy = 598DF02B7F63F92B8D3AE53987C3EA9D /* PBXContainerItemProxy */; + }; + A3AF27998DCDA1FDF3673B1B30703DF3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 7C372F9FE6B97CB3877A3B6390A857E8 /* PBXContainerItemProxy */; + }; + A64CE1926FADFA96D134425A09E605B6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTLS; + target = E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */; + targetProxy = B14BDBE2A863612EC7E960B0530FAFD9 /* PBXContainerItemProxy */; + }; + A66A3238A9B0114A0DABB625F7AB5A1D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftyJSON; + target = D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */; + targetProxy = 39626834F4ABA8A5763DBE0D8BDF1F2B /* PBXContainerItemProxy */; + }; + A6C3C9F24084105F7A1BA3337CDC059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = DynamicBlurView; + target = 7D914FA2F03C860D5133BA2DB87C594A /* DynamicBlurView */; + targetProxy = F0EE73BDDC076288873EC28787EFE8E2 /* PBXContainerItemProxy */; + }; + A72856C329D82FA33CD7177666E3494C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 7DF0D2688104EAA8BE606EA2F746C0A2 /* PBXContainerItemProxy */; + }; + A8B2A174D397F044FDE5A4A32BC5AF96 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 4496E0639926295FD5936C9F86FC2D2F /* PBXContainerItemProxy */; + }; + AAD487CB22BBC1DE6909F1D8B7CE3B29 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 29756E76526D338DDC89FF0E99828D70 /* PBXContainerItemProxy */; + }; + AB7425AF0C567364FCF6389B1D19F02E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTransportServices; + target = 5D6DC8585F20CBE789F7D3D4F645980E /* SwiftNIOTransportServices */; + targetProxy = EAD7286AFA0AF9C618C2957525784EFE /* PBXContainerItemProxy */; + }; + AB9FEE502C57590DE648F110619F08BE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = DEC721464308D5861BE903A655B3B838 /* PBXContainerItemProxy */; + }; + AC14E65EBC84BFE96CAF318D7F6D7140 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = C2A8E3041CF0FB7D444AE71EE4934914 /* PBXContainerItemProxy */; + }; + ACB73AE2848112169BF3FF17A45AF5F6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP1; + target = 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */; + targetProxy = 9EA1DCAA28525470DE468DCB2DA6D6A8 /* PBXContainerItemProxy */; + }; + ACCEFFBA5EEFEE70DCC9BD89D80CDFC9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = DynamicBlurView; + target = 7D914FA2F03C860D5133BA2DB87C594A /* DynamicBlurView */; + targetProxy = 37250669E7938A4BA2D5392353C75417 /* PBXContainerItemProxy */; + }; + AEEC4AB2C38D4C1E37B40D3850C57F06 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BigInt; + target = 09DD83B7D075842A3A5105AD410BD38A /* BigInt */; + targetProxy = 32A757E08C231B3C57A49F2658384DB4 /* PBXContainerItemProxy */; + }; + AFCA0B3EB08F8ABFA79215034D047B20 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = F12D50DD742774B3C33E7E9582A58872 /* PBXContainerItemProxy */; + }; + B1202BE92A2625D324C496123F495618 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 6F096D160F0FF315B45E64F5C3CEB0DF /* PBXContainerItemProxy */; + }; + B1C7203378A1142EB72E8A915F385963 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 03C84521A9A390440B5FEA070034D7DB /* PBXContainerItemProxy */; + }; + B5F7FE8285AB2D9E614ECA0F7F98B20C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = CD229B86035C3093C9BDD1FDF8F79029 /* PBXContainerItemProxy */; + }; + B7A1C7E647CB051B858C49EED5CE7D9C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 71D605E165020EA96DFA324B65D8EF87 /* PBXContainerItemProxy */; + }; + B8D262E43E5DDF596527B2711F0AD27E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BigInt; + target = 09DD83B7D075842A3A5105AD410BD38A /* BigInt */; + targetProxy = 041E036BCFC30882D8EAB232D4BF231B /* PBXContainerItemProxy */; + }; + B913BA400073ACBC2AF0704B75C056D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FlowSDK; + target = 446DA03EDE44E6615A2A146E3D90AA3D /* FlowSDK */; + targetProxy = 5D19632B5016C9DB206EE8C5A0251A46 /* PBXContainerItemProxy */; + }; + B94EE68281D3CDE248AAA0E96F032769 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 320A70E3D80981A9E4E5454B7B7D7CEF /* PBXContainerItemProxy */; + }; + BA28A5E5F7C33022537A111229359CDA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = BEC0FA37A5E4CDA00551CB63F192C89F /* PBXContainerItemProxy */; + }; + BB5E0C8415BD8B93376F0D9CDBF94E40 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 9CE74CB9083EC2EDD2C39CB92A743B95 /* PBXContainerItemProxy */; + }; + BD0A680BC1E66234B6C275D93F9EDAA4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 146147665BF147A234F24A13AE2800BC /* PBXContainerItemProxy */; + }; + BF17B205263C38CA4570DF5DD44376F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHTTP1; + target = 56C793C77970EA2F3692F44FFEFD9360 /* SwiftNIOHTTP1 */; + targetProxy = 13C80CBE0F563D34465D31B2349AFFB7 /* PBXContainerItemProxy */; + }; + C216B4BC492ED158651C113A9DCC8B01 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 01E8A316DE3D4D7D805B8D3BB407EED1 /* PBXContainerItemProxy */; + }; + C22EF9E1392B8E370AB3AF135FC4C5D4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = A892774CBA503C27274DD3A934809C69 /* PBXContainerItemProxy */; + }; + C2D8F9E8938EB5182F06B24FDE1112AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 6325AAE95A73366E78EFE686A9FE2E22 /* PBXContainerItemProxy */; + }; + C56A63459E764858C0E55ADA24E52983 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftyJSON; + target = D118A6A04828FD3CDA8640CD2B6796D2 /* SwiftyJSON */; + targetProxy = E181E9F63B04335A967CD540BC03F982 /* PBXContainerItemProxy */; + }; + C8B462F7CB458FF2E33BBFC5F43E7A7F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 5AB8B3C5C3FBDE2D6475BFD2D41C0A2B /* PBXContainerItemProxy */; + }; + C9111B4CB0F67417A59CB70499D6D27A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOTLS; + target = E0A1D7BDF9C722E6E4B4B1E012D20E51 /* SwiftNIOTLS */; + targetProxy = 459834457F831D18A418B6EE8FE2CB5B /* PBXContainerItemProxy */; + }; + C91AF97FCD234CD79E5554F0860DB61F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 5E667CECEA2BAAACDD6F4777FB337151 /* PBXContainerItemProxy */; + }; + CAA36A3AC4BBCBF93DF5B06215913A0E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 060D532169A167D451CBEA885F664164 /* PBXContainerItemProxy */; + }; + CAB8E461C9D5FEB6DBDB2047A31837DD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = A9B521AC1FE3E4FD80F0A1BAC2C38B45 /* PBXContainerItemProxy */; + }; + CB75C39D8B78800678841CE314110A4D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 4F98B8334A017F71137B1151ED9614C6 /* PBXContainerItemProxy */; + }; + CBB445264E41843BA56CE87E2E71C5AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOBoringSSLShims; + target = 65C8D0D3B04F444B821EB675E4D821DA /* CNIOBoringSSLShims */; + targetProxy = C22CD13FEFC3A77C90DD26AC3708F2AA /* PBXContainerItemProxy */; + }; + CBBA2AEE2C702CE05968AC68E5C03616 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 343A616783C2ABF0950C2492FAE2B7D8 /* PBXContainerItemProxy */; + }; + CC0890DC7A56B04BF3C2FD43E0197BD3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOCore; + target = A284FBC915D2D556B046FA0A96871C2F /* SwiftNIOCore */; + targetProxy = 05E2EB24011DED185E76CAF73FB7187A /* PBXContainerItemProxy */; + }; + CEB64638BD0F5DAE1345E99A97989CEA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 3A4522680D2949492B9E844E32C7DF88 /* PBXContainerItemProxy */; + }; + CFCA66E63B1B676FF6786C67FD8749FF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOSSL; + target = CF4D556EB90FFD6388321BDFD45BDDB3 /* SwiftNIOSSL */; + targetProxy = 359A80515EFDA29DBD050956CAD216CC /* PBXContainerItemProxy */; + }; + D10F7AD94F358AB3AAAB0623DF802760 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FCL-SDK"; + target = 85E705C55EE1E21751DAF1510D4F983E /* FCL-SDK */; + targetProxy = 6D2149B338570BEE8192BB1DEBA540EA /* PBXContainerItemProxy */; + }; + D29F12E57E824F881C1024F0816A2166 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = 69BC47F9871E54C8D9B54001848F2E3A /* PBXContainerItemProxy */; + }; + D345E6B0CB9233B38F385DB238946B3E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Logging; + target = 2ABF3F8EC6CE525E1E02C51D72C64E94 /* Logging */; + targetProxy = 1CA2324B6D77615A2E946E94F1EA649F /* PBXContainerItemProxy */; + }; + D605040DFE4385A3991A3D6363964E1E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Swift; + target = 814D3CA630EB31504C9C25A1AE6B75B7 /* secp256k1Swift */; + targetProxy = 22695A8AE408F69BE2B83B587BDFE795 /* PBXContainerItemProxy */; + }; + D671EB1EDD4CBD089C9722EF737F1339 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOHPACK; + target = F71DD9985215E142F625AD23A9121477 /* SwiftNIOHPACK */; + targetProxy = 8572B29F638AEFD74C158EDE6570A6ED /* PBXContainerItemProxy */; + }; + D8A72CC27F5E46E79FFFD086FB50A7AD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIODarwin; + target = 56A44E6B610D174593F40C5AD73224C4 /* CNIODarwin */; + targetProxy = 9B5BAB5D91B7D73F529D8F2EE56B1FE3 /* PBXContainerItemProxy */; + }; + D9CAA4F01AD4B2EE275CEE120D6CF516 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Wrapper; + target = 72EA11C51422080CE0CAEC35AC0EE02D /* secp256k1Wrapper */; + targetProxy = 42C4686E33E8239E5CF5D8A45DED0F25 /* PBXContainerItemProxy */; + }; + DABA83732B97B34235811C8B7EF81B45 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = D645A2E3C9263D89B8A80F6E023E2BFB /* PBXContainerItemProxy */; + }; + DBE9728CF19A17AF67A1F2F5066D4D74 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CryptoSwift; + target = 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */; + targetProxy = 81B37D09C5F4F8C02E435C7920D719EE /* PBXContainerItemProxy */; + }; + DC3CC555A97861B90EEECA1FA9C141F2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 0D37A0500B5AC313193B8F6BA1DE79CA /* PBXContainerItemProxy */; + }; + DC4912249288527538E558A0954E3E2F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = 6FB8A3277A47394257400C39103EE2FD /* PBXContainerItemProxy */; + }; + DC65CE716235E7252B2E280D6E47C53F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Wrapper; + target = 72EA11C51422080CE0CAEC35AC0EE02D /* secp256k1Wrapper */; + targetProxy = 341514C5489E78BADDD2029CAFE28406 /* PBXContainerItemProxy */; + }; + DCFE8CF7BE8F259112DE214524DC7F21 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = BloctoSDK; + target = 5A8A5B4451A77B0A6D36B131E2974E23 /* BloctoSDK */; + targetProxy = C057AD48EE614BDEBCDDF0A5C654FC0D /* PBXContainerItemProxy */; + }; + DDD8B9FC2A7277A8409375191688E7F4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOPosix; + target = D736A00DEDBE6AC34D5D1D32FD54046C /* SwiftNIOPosix */; + targetProxy = 2640BB9E1C26CC9B981EAB6779ABAA54 /* PBXContainerItemProxy */; + }; + DE6FD95BBC491CD5510B7C4461D9BE8F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 016B36A757D510003C1FF2677152A957 /* PBXContainerItemProxy */; + }; + E3477E2D10FEF686A2E7986E4E4ADD8D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CGRPCZlibp; + target = 54382245E5C9DB4A3CFB906FD97A35BB /* CGRPCZlibp */; + targetProxy = EB58221F3CD6A75B6F41BEA08DFFAB5C /* PBXContainerItemProxy */; + }; + E3B77BB1DABFE06AB99BB07220ADFE97 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOSSL; + target = CF4D556EB90FFD6388321BDFD45BDDB3 /* SwiftNIOSSL */; + targetProxy = 9E0332FA582B4CC0B88B2071ADABFA3D /* PBXContainerItemProxy */; + }; + E909D5C6FE06848C52A74792B5843859 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOFoundationCompat; + target = 834F3DE9EFC7B90102D63A51F6A9AF51 /* SwiftNIOFoundationCompat */; + targetProxy = 3C5272FED129B87287C2C31848EF9D83 /* PBXContainerItemProxy */; + }; + E94E5D66DFDB66856DE20896C4384AA6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SDWebImage; + target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; + targetProxy = FA1F72D908594FC64B32474EF09D746B /* PBXContainerItemProxy */; + }; + E98BDFD3504E01A52147C32AA671E6FB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = D72299E1B6908A755D54CB9FA200BCDE /* PBXContainerItemProxy */; + }; + EB5CAA67CEF578E527BEA4EB9023D830 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = 263C505EDA0C83A41F82635C57CD6564 /* PBXContainerItemProxy */; + }; + EBF9BD97E5227424FEAA3FF0A3341BC0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = 477E53130651B3909A182675B4C4FCAE /* PBXContainerItemProxy */; + }; + ED382F7DF066794D52B3FB4455F590EF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Swift; + target = 814D3CA630EB31504C9C25A1AE6B75B7 /* secp256k1Swift */; + targetProxy = 288CB4D61A66EDB921CDCC9D85EA8C1E /* PBXContainerItemProxy */; + }; + F04DBF9C4953529CC89A70892EF8C540 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = 032AD0EC02560D9D7B4399A8D005A5DE /* PBXContainerItemProxy */; + }; + F072DF03B9C6FAE58435F079917AE029 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CryptoSwift; + target = 99313990C1D76A6D1D017868B6975CC8 /* CryptoSwift */; + targetProxy = 5D706C9E78C870C6B75A06ACC66C6460 /* PBXContainerItemProxy */; + }; + F18ABC90D47A4142A44E348B0E892557 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOWindows; + target = 4A0A66DC2DC19095E11E5D3A679802D4 /* CNIOWindows */; + targetProxy = C4F3F99F1C7B42AFD03BCFBDBC6FF325 /* PBXContainerItemProxy */; + }; + F3A0B33927300988EC32CD81C40AA5E2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = CA147885AA6336ED6147B9A72989B51C /* PBXContainerItemProxy */; + }; + F3C5A8620AC1007E0621E4331D7195C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOEmbedded; + target = 4F818C63E0C8BC4199AC207AD36B89F0 /* SwiftNIOEmbedded */; + targetProxy = C3119BAA6D1E87F62886E433B64703C9 /* PBXContainerItemProxy */; + }; + F51CC1A9E946409D9F5AA893ADB55856 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOHTTPParser; + target = 59007493BE8F52FEEC69F0F9330AA6C0 /* CNIOHTTPParser */; + targetProxy = FF0B12F5D8F0BC78FB6FBAF73AE49BD0 /* PBXContainerItemProxy */; + }; + F57A1816028025AD92046F2C3C2032CF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = CFC45823198678BB6D6298D2D2C5DCDD /* PBXContainerItemProxy */; + }; + F58EE7C0FB65D347A65EA94EDEDE52A3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = secp256k1Wrapper; + target = 72EA11C51422080CE0CAEC35AC0EE02D /* secp256k1Wrapper */; + targetProxy = BCE4A899DD76943CB4C18FD423A7FBC4 /* PBXContainerItemProxy */; + }; + F61F6EFD14909F2DF984C6532BC8B066 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOAtomics; + target = E31BF93EB20B6245622D5A44E45F9BCA /* CNIOAtomics */; + targetProxy = D971CFBAC387680E35EF1DE462A0C2DE /* PBXContainerItemProxy */; + }; + F7B352EE3558C84D71ADBE90EFB43F78 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = FE760A803168F081CA76547159693FA7 /* PBXContainerItemProxy */; + }; + F7C8CF2B511BCBD63EDD5E04F38AFDD7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CNIOLinux; + target = 34E23B39AFBC87A7678CDCA494DE5CDC /* CNIOLinux */; + targetProxy = 82936E53E97920F437B6791032F52747 /* PBXContainerItemProxy */; + }; + FA95F16822D4A002E51EF5CA923DE364 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = D197677195BF55C212342DC98A1A5393 /* PBXContainerItemProxy */; + }; + FC70C7F5DC2E1A5F05DDE298C930F34B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Logging; + target = 2ABF3F8EC6CE525E1E02C51D72C64E94 /* Logging */; + targetProxy = 2CBA22C034E6B1C1276895BB554FA976 /* PBXContainerItemProxy */; + }; + FCB5643F9A725C86AFCCC462F2EE0BC7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIOConcurrencyHelpers; + target = 773FB76F4A2F42092713B9025F188877 /* SwiftNIOConcurrencyHelpers */; + targetProxy = FFC66300C63CF8DF0A3C94B5CDC1C4A0 /* PBXContainerItemProxy */; + }; + FCFE71F9C51285C2ACCCA9CE64F3E999 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwiftNIO; + target = 5E62229F86AA9810C2A7E6CF628B8486 /* SwiftNIO */; + targetProxy = B34C14187AF7A63905EA0FF0EE609DB3 /* PBXContainerItemProxy */; + }; + FCFFFB83B6BA6BF482E6709CB20A0463 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = _NIODataStructures; + target = 595729A6BA7621B06DBF24D66650D595 /* _NIODataStructures */; + targetProxy = FD9A7E8499607C6A040E40308E7A3BD6 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 00403A510F1318D67AA55C1B4DCB17FB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B39357A8BA62A1DE32E48810C6BE4632 /* SDWebImage.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SDWebImage/SDWebImage-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SDWebImage/SDWebImage.modulemap"; + PRODUCT_MODULE_NAME = SDWebImage; + PRODUCT_NAME = SDWebImage; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 0141C08964D6EF6A681ABADB6CDC5B24 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D09D70EE4A5398949BD23971F06909A /* CNIODarwin.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIODarwin/CNIODarwin-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIODarwin/CNIODarwin-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIODarwin/CNIODarwin.modulemap"; + PRODUCT_MODULE_NAME = CNIODarwin; + PRODUCT_NAME = CNIODarwin; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 06D50E25E4870F768E2EEDA4D18EF56D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2C5C0BC3D6A52DA6F561E59A77FD1C48 /* Pods-fanex.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanex/Pods-fanex-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanex/Pods-fanex.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 0963386D626CE94B9B152180B456800E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 699361D574BEBE539C51757D679B1819 /* SwiftNIOPosix.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix.modulemap"; + PRODUCT_MODULE_NAME = NIOPosix; + PRODUCT_NAME = NIOPosix; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 0A7EAF9ACB62F707EAF104F1A8A69C89 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 82FBE5CE279EE64E6AC1A3D977D9C3E7 /* SwiftProtobuf.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftProtobuf/SwiftProtobuf-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftProtobuf/SwiftProtobuf-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftProtobuf/SwiftProtobuf.modulemap"; + PRODUCT_MODULE_NAME = SwiftProtobuf; + PRODUCT_NAME = SwiftProtobuf; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 17741A66CF50768C9065C10A423F2410 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B6FB4210C8AC0D95761859E27284052F /* Pods-fanex-fanexUITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 18AA1555D513716317D672706BDA367B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 498BAEFEA926989AF4B263B8ED9C52AC /* SwiftNIOEmbedded.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.modulemap"; + PRODUCT_MODULE_NAME = NIOEmbedded; + PRODUCT_NAME = NIOEmbedded; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 1DE6BDD0281C9C89B4FE0815E016E157 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9353F679479027B35261BCF58CD26951 /* CNIOBoringSSL.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL.modulemap"; + PRODUCT_MODULE_NAME = CNIOBoringSSL; + PRODUCT_NAME = CNIOBoringSSL; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 1E58A1C7465C2E275E30526CA2A3F809 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC24001B0B936C4BAD8F8EACF07E466C /* SwiftNIO.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIO/SwiftNIO-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIO/SwiftNIO-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIO/SwiftNIO.modulemap"; + PRODUCT_MODULE_NAME = NIO; + PRODUCT_NAME = NIO; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 208418814F0A637F43445B719CDB49CA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 88DCEFFCCAE19562AD1B892026A9330A /* SwiftNIOCore.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOCore/SwiftNIOCore-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOCore/SwiftNIOCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOCore/SwiftNIOCore.modulemap"; + PRODUCT_MODULE_NAME = NIOCore; + PRODUCT_NAME = NIOCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 23A065DAAC01EF849F8D213C687108D1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0F21A408FF9FDD6A3FFEDE112A1BFA31 /* CryptoSwift.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CryptoSwift/CryptoSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; + PRODUCT_MODULE_NAME = CryptoSwift; + PRODUCT_NAME = CryptoSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 278F96E0D6F022FB40BD828F51E94D99 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C5B51E986151943001F9FB91147A71C4 /* BigInt.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BigInt/BigInt-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BigInt/BigInt-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BigInt/BigInt.modulemap"; + PRODUCT_MODULE_NAME = BigInt; + PRODUCT_NAME = BigInt; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 283F09B04CC184663D5AFA32BDC40F27 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B9777D2A1685333BBF468EFCD3584A40 /* _NIODataStructures.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/_NIODataStructures/_NIODataStructures-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/_NIODataStructures/_NIODataStructures-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/_NIODataStructures/_NIODataStructures.modulemap"; + PRODUCT_MODULE_NAME = _NIODataStructures; + PRODUCT_NAME = _NIODataStructures; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 2E8F3E08B1541BCA5E3F61A243DC01E1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 718103D734BC6C94385D871392384612 /* SwiftNIOExtras.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras.modulemap"; + PRODUCT_MODULE_NAME = NIOExtras; + PRODUCT_NAME = NIOExtras; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 353310E7DF2D6B146F0049A1DD78A655 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 93F0AD3ADAD0EFBF6747866F9AD34681 /* MercariQRScanner.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/MercariQRScanner/MercariQRScanner-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MercariQRScanner/MercariQRScanner-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/MercariQRScanner/MercariQRScanner.modulemap"; + PRODUCT_MODULE_NAME = MercariQRScanner; + PRODUCT_NAME = MercariQRScanner; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 36BEE28EB88FFBF746AE841E186D88C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 01B66A124FC2BBB446F619F5F98F4ADA /* CNIODarwin.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIODarwin/CNIODarwin-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIODarwin/CNIODarwin-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIODarwin/CNIODarwin.modulemap"; + PRODUCT_MODULE_NAME = CNIODarwin; + PRODUCT_NAME = CNIODarwin; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 37D3BD489457A5821EE829F76E51CEE6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D231FBD70C9601052E3C08B6E0B3C1A /* secp256k1Swift.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/secp256k1Swift/secp256k1Swift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/secp256k1Swift/secp256k1Swift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/secp256k1Swift/secp256k1Swift.modulemap"; + PRODUCT_MODULE_NAME = secp256k1Swift; + PRODUCT_NAME = secp256k1Swift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 38145DCEDCCA6064D4D51FFB31426DAB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC639B3693A5684D7058BF67CD67A76B /* SwiftNIOHPACK.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.modulemap"; + PRODUCT_MODULE_NAME = NIOHPACK; + PRODUCT_NAME = NIOHPACK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 38E0496CC72AA7AAE4E3DA7240373E7C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61B3DA25CFEB729C2DB261ACD2CCE46F /* Pods-fanex-fanexUITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 3A9EA29ED6921878E3F25F2AEACA9FB3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F7A91F4686FC34066E9F1F3B610CAEBF /* SVProgressHUD.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD.modulemap"; + PRODUCT_MODULE_NAME = SVProgressHUD; + PRODUCT_NAME = SVProgressHUD; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 412FA0FD5BBA6978D265EB8D99F12733 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A4FBA4C5DC60851E041F493279C7BD17 /* CNIOHTTPParser.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser.modulemap"; + PRODUCT_MODULE_NAME = CNIOHTTPParser; + PRODUCT_NAME = CNIOHTTPParser; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 44796597F470CB17B9F821EC079DE9A0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6454772CDFC04EFE6E1F5AD38FE7E3DD /* secp256k1Wrapper.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper.modulemap"; + PRODUCT_MODULE_NAME = secp256k1Wrapper; + PRODUCT_NAME = secp256k1Wrapper; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 49D4436E52E74C578B1DCD5C8C0D5886 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F836D4A8C76F56D6DD73F426915AB52A /* SwiftNIOTLS.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS.modulemap"; + PRODUCT_MODULE_NAME = NIOTLS; + PRODUCT_NAME = NIOTLS; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 4C7D64A95AE2D855F99C155925F8B815 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 31B47C603FED805DF8C2BB1365745900 /* _NIODataStructures.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/_NIODataStructures/_NIODataStructures-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/_NIODataStructures/_NIODataStructures-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/_NIODataStructures/_NIODataStructures.modulemap"; + PRODUCT_MODULE_NAME = _NIODataStructures; + PRODUCT_NAME = _NIODataStructures; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 51373257C3854AAE8974A60438841FBC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 86B0C15C4D16323D6FF84C1FA5384A89 /* SwiftNIOCore.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOCore/SwiftNIOCore-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOCore/SwiftNIOCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOCore/SwiftNIOCore.modulemap"; + PRODUCT_MODULE_NAME = NIOCore; + PRODUCT_NAME = NIOCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 5BA0D5C6D3F2E0D33B266175114ECCFB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0F8181A38BFEE82303D4BD20E1B79BA7 /* SwiftNIOSSL.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL.modulemap"; + PRODUCT_MODULE_NAME = NIOSSL; + PRODUCT_NAME = NIOSSL; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 5C830163E1AF489C517AA9D09559EA03 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9910BBE166BD1E89E9E12DC90492F787 /* FlowSDK.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FlowSDK/FlowSDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FlowSDK/FlowSDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FlowSDK/FlowSDK.modulemap"; + PRODUCT_MODULE_NAME = FlowSDK; + PRODUCT_NAME = FlowSDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 5CC1CFD2C6348A5A2DA0CDDB3BCA28EA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EDB2896CA76E4083FD655A1249E1241F /* CNIOAtomics.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOAtomics/CNIOAtomics-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOAtomics/CNIOAtomics-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOAtomics/CNIOAtomics.modulemap"; + PRODUCT_MODULE_NAME = CNIOAtomics; + PRODUCT_NAME = CNIOAtomics; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 5D4648FE8AFD75BD1FF76D801756267D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2FB81A1A9FA63E45CEA511A33CB9BD46 /* CNIOWindows.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOWindows/CNIOWindows-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOWindows/CNIOWindows-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOWindows/CNIOWindows.modulemap"; + PRODUCT_MODULE_NAME = CNIOWindows; + PRODUCT_NAME = CNIOWindows; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 5DB54D57B79B1BCF3039AEF22640BE4F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CBA473ED92C1037C118477A4972B8318 /* SwiftNIOExtras.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOExtras/SwiftNIOExtras.modulemap"; + PRODUCT_MODULE_NAME = NIOExtras; + PRODUCT_NAME = NIOExtras; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 5E4F2D52ED8393790447A3FB75E12A49 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9CF3A537CCBB4F47740B588DBC13AF75 /* FlowSDK.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FlowSDK/FlowSDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FlowSDK/FlowSDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FlowSDK/FlowSDK.modulemap"; + PRODUCT_MODULE_NAME = FlowSDK; + PRODUCT_NAME = FlowSDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 603A2191613B685C63C1EACB6B3569FE /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FCCD4381FC5AE473243D1B1AAEBE4615 /* SwiftyJSON.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON.modulemap"; + PRODUCT_MODULE_NAME = SwiftyJSON; + PRODUCT_NAME = SwiftyJSON; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 66D06AB80438770AF480CD6D3AFFBB7A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 596EDC10FB2C816516BF38E8A47E49E0 /* BloctoSDK.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BloctoSDK/BloctoSDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BloctoSDK/BloctoSDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BloctoSDK/BloctoSDK.modulemap"; + PRODUCT_MODULE_NAME = BloctoSDK; + PRODUCT_NAME = BloctoSDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 6ACAF1F65D3B6DF2F6A0ABC33A01429A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8489F90B00219E2F816445944BEF3D01 /* Logging.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Logging/Logging-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Logging/Logging-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/Logging/Logging.modulemap"; + PRODUCT_MODULE_NAME = Logging; + PRODUCT_NAME = Logging; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 6B83C383149761C9860E05FAD8179F6C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 72D964BAB663A157827B42E3EFC3AD13 /* secp256k1Swift.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/secp256k1Swift/secp256k1Swift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/secp256k1Swift/secp256k1Swift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/secp256k1Swift/secp256k1Swift.modulemap"; + PRODUCT_MODULE_NAME = secp256k1Swift; + PRODUCT_NAME = secp256k1Swift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 6D42E26F7FE6080E3B36D82A996D9D2F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1936F11FC65709C16D7A78196D0740B1 /* SwiftNIOHPACK.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.modulemap"; + PRODUCT_MODULE_NAME = NIOHPACK; + PRODUCT_NAME = NIOHPACK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 73CB271215122436B87B6FC72B98E0AB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51CA1BF1AEEC3CC946C5EA99D7A1F59B /* SwiftNIOTransportServices.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.modulemap"; + PRODUCT_MODULE_NAME = NIOTransportServices; + PRODUCT_NAME = NIOTransportServices; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 73D1C6D0BBD3258AC61403FF5B76CBA5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CA98D9A63854A14E1B8B03D491F17D2A /* SwiftNIOHTTP1.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.modulemap"; + PRODUCT_MODULE_NAME = NIOHTTP1; + PRODUCT_NAME = NIOHTTP1; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 76329E040871B244628D94B19AACF818 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B92046FCE952E070444772F0017A14D5 /* CNIOBoringSSLShims.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.modulemap"; + PRODUCT_MODULE_NAME = CNIOBoringSSLShims; + PRODUCT_NAME = CNIOBoringSSLShims; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 76C854152E00A6365199C771353658B1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EC4E7E433CE6A32FC3D02BF10F8A9E08 /* Pods-fanex.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanex/Pods-fanex-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanex/Pods-fanex.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 78D5511EA17419A5928B82B2542A80EF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A2BA49B19A14C63DCA70C388DA85953 /* BigInt.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BigInt/BigInt-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BigInt/BigInt-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BigInt/BigInt.modulemap"; + PRODUCT_MODULE_NAME = BigInt; + PRODUCT_NAME = BigInt; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7B1A79BC8B80742A8BDFB9DD8F3557AE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF5094047F1DE14436CA3AB5298C4593 /* PopupDialog.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/PopupDialog/PopupDialog-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PopupDialog/PopupDialog-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/PopupDialog/PopupDialog.modulemap"; + PRODUCT_MODULE_NAME = PopupDialog; + PRODUCT_NAME = PopupDialog; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 80BF26E029EDBCA8B9ED99FD66FE6570 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D418CCC7A6AC0FB56934549E60249E06 /* CNIOLinux.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOLinux/CNIOLinux-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOLinux/CNIOLinux-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOLinux/CNIOLinux.modulemap"; + PRODUCT_MODULE_NAME = CNIOLinux; + PRODUCT_NAME = CNIOLinux; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 83D9F02D261A9F60DC096FD43FBC1535 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 00E8B69FA8F1B21329BA5D82E2893816 /* SwiftNIOConcurrencyHelpers.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.modulemap"; + PRODUCT_MODULE_NAME = NIOConcurrencyHelpers; + PRODUCT_NAME = NIOConcurrencyHelpers; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 858FCDD258FE91ECD2B4FCD67A5ABD94 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9AFBF96323889F7EAF96656004366771 /* CNIOBoringSSL.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOBoringSSL/CNIOBoringSSL.modulemap"; + PRODUCT_MODULE_NAME = CNIOBoringSSL; + PRODUCT_NAME = CNIOBoringSSL; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 8A8619D62F7F018A9869A87A3D446E41 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BB2964841926D0B8548E45C82B3BFD5F /* CryptoSwift.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CryptoSwift/CryptoSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; + PRODUCT_MODULE_NAME = CryptoSwift; + PRODUCT_NAME = CryptoSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 8C5B930A5815DE3E9B460240C1589282 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AE3E45F8F49AC7440A4DFBF42F1526E8 /* FCL-SDK.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FCL-SDK/FCL-SDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FCL-SDK/FCL-SDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FCL-SDK/FCL-SDK.modulemap"; + PRODUCT_MODULE_NAME = FCL_SDK; + PRODUCT_NAME = FCL_SDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 8CF166AD0D199156050CFF3CCFA4B096 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D7E805F18D220B2496E7ED497D891F6 /* BloctoSDK.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/BloctoSDK/BloctoSDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/BloctoSDK/BloctoSDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/BloctoSDK/BloctoSDK.modulemap"; + PRODUCT_MODULE_NAME = BloctoSDK; + PRODUCT_NAME = BloctoSDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 90746FA1825A88DF3F651CA76746E7D8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 190AC20F29333DC43C461DC412B766FD /* secp256k1Wrapper.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/secp256k1Wrapper/secp256k1Wrapper.modulemap"; + PRODUCT_MODULE_NAME = secp256k1Wrapper; + PRODUCT_NAME = secp256k1Wrapper; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 940B7992A81976FBA7CDAE6BA3EBA9C0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 30340B262F1F7E20B838FE3271BD6903 /* Pods-fanexTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanexTests/Pods-fanexTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanexTests/Pods-fanexTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 9553C89E183877A5CB2F3C6801BEC129 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + 95C50435EB7279CD7AA8D41693A970B8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33FFC143B0BC2F9DFBBEF1EA71EFEB36 /* SwiftNIOHTTP1.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.modulemap"; + PRODUCT_MODULE_NAME = NIOHTTP1; + PRODUCT_NAME = NIOHTTP1; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 96AE8C4EAEECA76D2E9708713DBCFF61 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D69780E46CD39C58EABFCD14326E92C5 /* CNIOAtomics.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOAtomics/CNIOAtomics-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOAtomics/CNIOAtomics-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOAtomics/CNIOAtomics.modulemap"; + PRODUCT_MODULE_NAME = CNIOAtomics; + PRODUCT_NAME = CNIOAtomics; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A0B7FFCDFDF397C9C1A3DEADB7B929B5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1E6ECA6B0A9A8C4E6A7CA9C4FB436793 /* SwiftNIOPosix.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOPosix/SwiftNIOPosix.modulemap"; + PRODUCT_MODULE_NAME = NIOPosix; + PRODUCT_NAME = NIOPosix; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A26214DB7B007440EAF44F5BF970BE43 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 683C3A9077D7AFBD12A2AB115EED400A /* gRPC-Swiftp.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp.modulemap"; + PRODUCT_MODULE_NAME = GRPC; + PRODUCT_NAME = GRPC; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A2E9E6FF6F65A6F29CDDC5CC195C4A1D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2AB7DAA6F97DF10E00BD54DAB7CFD793 /* DynamicBlurView.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/DynamicBlurView/DynamicBlurView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/DynamicBlurView/DynamicBlurView-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/DynamicBlurView/DynamicBlurView.modulemap"; + PRODUCT_MODULE_NAME = DynamicBlurView; + PRODUCT_NAME = DynamicBlurView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A3DF9A64FD79319F234F474A01466479 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 76EFDA04C75D0547F58E8333515A45AB /* SwiftNIO.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIO/SwiftNIO-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIO/SwiftNIO-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIO/SwiftNIO.modulemap"; + PRODUCT_MODULE_NAME = NIO; + PRODUCT_NAME = NIO; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A4F18433251783CB80FA629ED49E6536 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 47AE5EF4EEF683F76336F5E2F095E501 /* PopupDialog.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/PopupDialog/PopupDialog-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PopupDialog/PopupDialog-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/PopupDialog/PopupDialog.modulemap"; + PRODUCT_MODULE_NAME = PopupDialog; + PRODUCT_NAME = PopupDialog; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A72DEAC6C4423DB1E77BC10688A2A052 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 579FF490F79F59658DAF13F0E591B4E8 /* CNIOLinux.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOLinux/CNIOLinux-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOLinux/CNIOLinux-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOLinux/CNIOLinux.modulemap"; + PRODUCT_MODULE_NAME = CNIOLinux; + PRODUCT_NAME = CNIOLinux; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A83B800574B5AD9FAB71C0DB8A850330 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2C3C2254EB57228190A1B6A024B26C52 /* DynamicBlurView.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/DynamicBlurView/DynamicBlurView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/DynamicBlurView/DynamicBlurView-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/DynamicBlurView/DynamicBlurView.modulemap"; + PRODUCT_MODULE_NAME = DynamicBlurView; + PRODUCT_NAME = DynamicBlurView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A91DD08C0BC41AF3FF4CE28F320757C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DB3C51FC2CE11F6E1FC4DB0C1059C64F /* Pods-fanexTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-fanexTests/Pods-fanexTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-fanexTests/Pods-fanexTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + AF62F7FFCEE966BFF3B68E54A31661D4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 57F372EEBB66DB5339D666EE9378C337 /* SwiftNIOTLS.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOTLS/SwiftNIOTLS.modulemap"; + PRODUCT_MODULE_NAME = NIOTLS; + PRODUCT_NAME = NIOTLS; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B0A83E2B33F87D1C7856C6DF93404465 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D908361B8625862D2C49A79C1B9BEA16 /* SDWebImage.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SDWebImage/SDWebImage-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SDWebImage/SDWebImage-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SDWebImage/SDWebImage.modulemap"; + PRODUCT_MODULE_NAME = SDWebImage; + PRODUCT_NAME = SDWebImage; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B6173608430D4B98118606F6E51D9F3F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4D67F34D63E7BD7AF2FC9BB501EE6A7B /* SwiftNIOHTTP2.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.modulemap"; + PRODUCT_MODULE_NAME = NIOHTTP2; + PRODUCT_NAME = NIOHTTP2; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + B8E109FB676D76C218D89A215C33FDCC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4829FCB00ADE43B6064E63565DEE1F5E /* SwiftNIOConcurrencyHelpers.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.modulemap"; + PRODUCT_MODULE_NAME = NIOConcurrencyHelpers; + PRODUCT_NAME = NIOConcurrencyHelpers; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BCA58EDF4243BC38511C70ADE94F4467 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E18AB3400B57A79FD5CE7E88BE4FBF63 /* Cadence.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Cadence/Cadence-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Cadence/Cadence-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/Cadence/Cadence.modulemap"; + PRODUCT_MODULE_NAME = Cadence; + PRODUCT_NAME = Cadence; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BFEA8CB36F2DD0D53ADC31769F8F1454 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4E178514B54CC8064E94365ECF2BC5A0 /* CNIOBoringSSLShims.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.modulemap"; + PRODUCT_MODULE_NAME = CNIOBoringSSLShims; + PRODUCT_NAME = CNIOBoringSSLShims; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C4C301E661FAEA6949577E8D06E9D5BD /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 918ECE4B52BECD386CF80B33C8BE5A8D /* SwiftyJSON.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON.modulemap"; + PRODUCT_MODULE_NAME = SwiftyJSON; + PRODUCT_NAME = SwiftyJSON; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C730C48A0A6F5C89DDDFCD2D09313F24 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 921A5CE0D626D2D9F73F2B2C37C57DD3 /* MercariQRScanner.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/MercariQRScanner/MercariQRScanner-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MercariQRScanner/MercariQRScanner-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/MercariQRScanner/MercariQRScanner.modulemap"; + PRODUCT_MODULE_NAME = MercariQRScanner; + PRODUCT_NAME = MercariQRScanner; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + CB128CFAC29569136BD8DBEC447C9D73 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8A7DABB47C717F3A0AE17A086BF808B5 /* SwiftNIOSSL.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOSSL/SwiftNIOSSL.modulemap"; + PRODUCT_MODULE_NAME = NIOSSL; + PRODUCT_NAME = NIOSSL; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D31BD7ECE08CF980D2B9B077070CE6CA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8342CEB64D4BEBCE210DF23AAF9855D6 /* SwiftProtobuf.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftProtobuf/SwiftProtobuf-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftProtobuf/SwiftProtobuf-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftProtobuf/SwiftProtobuf.modulemap"; + PRODUCT_MODULE_NAME = SwiftProtobuf; + PRODUCT_NAME = SwiftProtobuf; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D54D161C3B80D50DE7DCBBCBBE5EEBD9 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1019854EC76E5A35372C2247872FBB45 /* SwiftNIOFoundationCompat.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.modulemap"; + PRODUCT_MODULE_NAME = NIOFoundationCompat; + PRODUCT_NAME = NIOFoundationCompat; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D67A6CFF1FCD57C7AD23332663A2ECA2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 267062B3614E6E43C1A754BDDEBFDCBA /* CNIOHTTPParser.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOHTTPParser/CNIOHTTPParser.modulemap"; + PRODUCT_MODULE_NAME = CNIOHTTPParser; + PRODUCT_NAME = CNIOHTTPParser; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DC67D1B730925B7B5D2650E59CEA5FDB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 393B0F7F47A7F366DDF0A7E3405BBBAE /* CNIOWindows.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CNIOWindows/CNIOWindows-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CNIOWindows/CNIOWindows-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CNIOWindows/CNIOWindows.modulemap"; + PRODUCT_MODULE_NAME = CNIOWindows; + PRODUCT_NAME = CNIOWindows; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E0DD49BEC81BECFAA529C257BEA5EFCB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DBE34A1D672AD2579D3BB755C51A5C5B /* Logging.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Logging/Logging-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Logging/Logging-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/Logging/Logging.modulemap"; + PRODUCT_MODULE_NAME = Logging; + PRODUCT_NAME = Logging; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + E11CE118D7CC1A62E5E2E00184AD18D1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8535333F12E206F0A29CED9A0F935BF7 /* CGRPCZlibp.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CGRPCZlibp/CGRPCZlibp-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CGRPCZlibp/CGRPCZlibp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CGRPCZlibp/CGRPCZlibp.modulemap"; + PRODUCT_MODULE_NAME = CGRPCZlib; + PRODUCT_NAME = CGRPCZlib; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + E769347CB8B4C73503B58936115E6682 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C7DF0B2E8D690EEF78B6B95A929E0960 /* Cadence.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Cadence/Cadence-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Cadence/Cadence-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/Cadence/Cadence.modulemap"; + PRODUCT_MODULE_NAME = Cadence; + PRODUCT_NAME = Cadence; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E7C4E72588BA38523B53DEC049091E02 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 859AB0A0806DCFFB6C5C85C999B23FC7 /* SVProgressHUD.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SVProgressHUD/SVProgressHUD.modulemap"; + PRODUCT_MODULE_NAME = SVProgressHUD; + PRODUCT_NAME = SVProgressHUD; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + EA4363E1B1474848ADA35D0A93D8F3C3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B00141CED0B13A8AB80467697980865F /* SwiftNIOHTTP2.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.modulemap"; + PRODUCT_MODULE_NAME = NIOHTTP2; + PRODUCT_NAME = NIOHTTP2; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + ED164453391CD6C06A59A786D8BCB276 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCD6665F6C8BAD060595A501C0346F1A /* SwiftNIOTransportServices.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.modulemap"; + PRODUCT_MODULE_NAME = NIOTransportServices; + PRODUCT_NAME = NIOTransportServices; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F22D6A80948C8A3D87509CD0DCEF39B3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 52A70AE9E6190A82C587A37FE9D8EB4B /* gRPC-Swiftp.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/gRPC-Swiftp/gRPC-Swiftp.modulemap"; + PRODUCT_MODULE_NAME = GRPC; + PRODUCT_NAME = GRPC; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F36F075ACF21E7133820DF031E3D2E0E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6FAB5953B2D05E975AA748D0B4F5373E /* FCL-SDK.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FCL-SDK/FCL-SDK-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FCL-SDK/FCL-SDK-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FCL-SDK/FCL-SDK.modulemap"; + PRODUCT_MODULE_NAME = FCL_SDK; + PRODUCT_NAME = FCL_SDK; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F7E3F3F8812A2CD5A9260D10254B9C0C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A6F43EDA3AAEB0A7636E47D1BEA18A8 /* SwiftNIOFoundationCompat.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.modulemap"; + PRODUCT_MODULE_NAME = NIOFoundationCompat; + PRODUCT_NAME = NIOFoundationCompat; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + FBC8341FEB65EF829838C4F8360C94E4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5BE9BF7F0B0096EDA17340602CCF5AE9 /* CGRPCZlibp.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CGRPCZlibp/CGRPCZlibp-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CGRPCZlibp/CGRPCZlibp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/CGRPCZlibp/CGRPCZlibp.modulemap"; + PRODUCT_MODULE_NAME = CGRPCZlib; + PRODUCT_NAME = CGRPCZlib; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + FFC162428B39D3F85B74D21C3A714913 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E4D7AF2FFDCED01CDA1D9A7C7E877132 /* SwiftNIOEmbedded.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.modulemap"; + PRODUCT_MODULE_NAME = NIOEmbedded; + PRODUCT_NAME = NIOEmbedded; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.4; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0760232251EA461456909CD65D1D22AF /* Build configuration list for PBXNativeTarget "DynamicBlurView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A2E9E6FF6F65A6F29CDDC5CC195C4A1D /* Debug */, + A83B800574B5AD9FAB71C0DB8A850330 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0C14859D34B9027BBFBC968C1A2F3216 /* Build configuration list for PBXNativeTarget "SwiftNIOTLS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AF62F7FFCEE966BFF3B68E54A31661D4 /* Debug */, + 49D4436E52E74C578B1DCD5C8C0D5886 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0E6DD91A9FCBD60BBBCAD3B56E8C6951 /* Build configuration list for PBXNativeTarget "FCL-SDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F36F075ACF21E7133820DF031E3D2E0E /* Debug */, + 8C5B930A5815DE3E9B460240C1589282 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1415ECE334DCCA6DC980A43E5E4366B1 /* Build configuration list for PBXNativeTarget "SwiftNIOPosix" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A0B7FFCDFDF397C9C1A3DEADB7B929B5 /* Debug */, + 0963386D626CE94B9B152180B456800E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1452BA34CFC4CA921B1198A423E64C25 /* Build configuration list for PBXNativeTarget "FlowSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5C830163E1AF489C517AA9D09559EA03 /* Debug */, + 5E4F2D52ED8393790447A3FB75E12A49 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1BBB16EB7069406B761A88626AED702D /* Build configuration list for PBXNativeTarget "SwiftNIOConcurrencyHelpers" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 83D9F02D261A9F60DC096FD43FBC1535 /* Debug */, + B8E109FB676D76C218D89A215C33FDCC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1FC39448079F9761DB0444346A203FE5 /* Build configuration list for PBXNativeTarget "SwiftNIOHTTP2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EA4363E1B1474848ADA35D0A93D8F3C3 /* Debug */, + B6173608430D4B98118606F6E51D9F3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2352C424B358B93E5FB0F821F16CE8B0 /* Build configuration list for PBXNativeTarget "SwiftNIOCore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 208418814F0A637F43445B719CDB49CA /* Debug */, + 51373257C3854AAE8974A60438841FBC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 263E4F18F2482D2B79CEEBE3572473EC /* Build configuration list for PBXNativeTarget "SwiftNIOHPACK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D42E26F7FE6080E3B36D82A996D9D2F /* Debug */, + 38145DCEDCCA6064D4D51FFB31426DAB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2ABB7819979A3490D43740C6DD180657 /* Build configuration list for PBXNativeTarget "Pods-fanex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 06D50E25E4870F768E2EEDA4D18EF56D /* Debug */, + 76C854152E00A6365199C771353658B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2B3CB99B88A081A0697B5463DB259194 /* Build configuration list for PBXNativeTarget "secp256k1Swift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6B83C383149761C9860E05FAD8179F6C /* Debug */, + 37D3BD489457A5821EE829F76E51CEE6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 31E25A7DA65A994902661DBC87F4480F /* Build configuration list for PBXNativeTarget "CGRPCZlibp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FBC8341FEB65EF829838C4F8360C94E4 /* Debug */, + E11CE118D7CC1A62E5E2E00184AD18D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32280DB872FAE69E008C7718ABB4F4C1 /* Build configuration list for PBXNativeTarget "BloctoSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8CF166AD0D199156050CFF3CCFA4B096 /* Debug */, + 66D06AB80438770AF480CD6D3AFFBB7A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 37472EAC69133C913656A0F98C117288 /* Build configuration list for PBXNativeTarget "SwiftNIOEmbedded" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FFC162428B39D3F85B74D21C3A714913 /* Debug */, + 18AA1555D513716317D672706BDA367B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 407CE045BD56FAE98E8079A18EF820D0 /* Build configuration list for PBXNativeTarget "CNIODarwin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 36BEE28EB88FFBF746AE841E186D88C7 /* Debug */, + 0141C08964D6EF6A681ABADB6CDC5B24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */, + 9553C89E183877A5CB2F3C6801BEC129 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4CADF0DFAF02C257E2E00F97AA90E5BB /* Build configuration list for PBXNativeTarget "SwiftNIOTransportServices" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ED164453391CD6C06A59A786D8BCB276 /* Debug */, + 73CB271215122436B87B6FC72B98E0AB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5126FD23D53D384B5F17BAFE760FB0F3 /* Build configuration list for PBXNativeTarget "_NIODataStructures" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 283F09B04CC184663D5AFA32BDC40F27 /* Debug */, + 4C7D64A95AE2D855F99C155925F8B815 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5B99BE48F5F355257AD701BE6BF287A7 /* Build configuration list for PBXNativeTarget "Cadence" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E769347CB8B4C73503B58936115E6682 /* Debug */, + BCA58EDF4243BC38511C70ADE94F4467 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5D5C5591972CB4318463485CD8219013 /* Build configuration list for PBXNativeTarget "Pods-fanex-fanexUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 17741A66CF50768C9065C10A423F2410 /* Debug */, + 38E0496CC72AA7AAE4E3DA7240373E7C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6C696C8CA41BB855C8D3F30C1B2DEF51 /* Build configuration list for PBXNativeTarget "BigInt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 78D5511EA17419A5928B82B2542A80EF /* Debug */, + 278F96E0D6F022FB40BD828F51E94D99 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6FE7248D024BB1299E4CA37218234399 /* Build configuration list for PBXNativeTarget "SwiftyJSON" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C4C301E661FAEA6949577E8D06E9D5BD /* Debug */, + 603A2191613B685C63C1EACB6B3569FE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 73C4F8ECE74823C72A0B7DF4A6A676F7 /* Build configuration list for PBXNativeTarget "CNIOBoringSSL" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DE6BDD0281C9C89B4FE0815E016E157 /* Debug */, + 858FCDD258FE91ECD2B4FCD67A5ABD94 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 74DA03C0685F5BC3A109932481F343B0 /* Build configuration list for PBXNativeTarget "SwiftNIOExtras" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5DB54D57B79B1BCF3039AEF22640BE4F /* Debug */, + 2E8F3E08B1541BCA5E3F61A243DC01E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7B505826D4438A766AC48260B25112AF /* Build configuration list for PBXNativeTarget "gRPC-Swiftp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F22D6A80948C8A3D87509CD0DCEF39B3 /* Debug */, + A26214DB7B007440EAF44F5BF970BE43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7DB8D3C965A40C5A7E49FD2AFDD1087B /* Build configuration list for PBXNativeTarget "MercariQRScanner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 353310E7DF2D6B146F0049A1DD78A655 /* Debug */, + C730C48A0A6F5C89DDDFCD2D09313F24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 807DFD17F79151217EC31070EA5AFB1E /* Build configuration list for PBXNativeTarget "CNIOWindows" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC67D1B730925B7B5D2650E59CEA5FDB /* Debug */, + 5D4648FE8AFD75BD1FF76D801756267D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 807FEF9D9629A72728B6B83F5CA12C85 /* Build configuration list for PBXNativeTarget "SVProgressHUD" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3A9EA29ED6921878E3F25F2AEACA9FB3 /* Debug */, + E7C4E72588BA38523B53DEC049091E02 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 82DD89191CBB71A80BEEB00F63C291EC /* Build configuration list for PBXNativeTarget "PopupDialog" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B1A79BC8B80742A8BDFB9DD8F3557AE /* Debug */, + A4F18433251783CB80FA629ED49E6536 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8FE90004A4B3612A71B8C66E991D6603 /* Build configuration list for PBXNativeTarget "Logging" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6ACAF1F65D3B6DF2F6A0ABC33A01429A /* Debug */, + E0DD49BEC81BECFAA529C257BEA5EFCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7E7E1351DE9BC036A87A76C3C1F0F70 /* Build configuration list for PBXNativeTarget "CNIOHTTPParser" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D67A6CFF1FCD57C7AD23332663A2ECA2 /* Debug */, + 412FA0FD5BBA6978D265EB8D99F12733 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A8923C9E1170C9B5C2F047CF927406C1 /* Build configuration list for PBXNativeTarget "CNIOLinux" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A72DEAC6C4423DB1E77BC10688A2A052 /* Debug */, + 80BF26E029EDBCA8B9ED99FD66FE6570 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ACF1A1DAD01BB2C6CC83080EDC52EA51 /* Build configuration list for PBXNativeTarget "Pods-fanexTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A91DD08C0BC41AF3FF4CE28F320757C7 /* Debug */, + 940B7992A81976FBA7CDAE6BA3EBA9C0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B11C7159FE09498456D8BBCB9B1ADF49 /* Build configuration list for PBXNativeTarget "SwiftNIOFoundationCompat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F7E3F3F8812A2CD5A9260D10254B9C0C /* Debug */, + D54D161C3B80D50DE7DCBBCBBE5EEBD9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B39D77ADCBA580D59305992054625C4F /* Build configuration list for PBXNativeTarget "CNIOAtomics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5CC1CFD2C6348A5A2DA0CDDB3BCA28EA /* Debug */, + 96AE8C4EAEECA76D2E9708713DBCFF61 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B507F2DAF6B61D93CF6A883715853372 /* Build configuration list for PBXNativeTarget "SwiftProtobuf" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D31BD7ECE08CF980D2B9B077070CE6CA /* Debug */, + 0A7EAF9ACB62F707EAF104F1A8A69C89 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BABD4A24CFCBE5B6FE4680AA062FCF04 /* Build configuration list for PBXNativeTarget "SDWebImage" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B0A83E2B33F87D1C7856C6DF93404465 /* Debug */, + 00403A510F1318D67AA55C1B4DCB17FB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BCF90AA723661B881DB460C7B37264F7 /* Build configuration list for PBXNativeTarget "secp256k1Wrapper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 90746FA1825A88DF3F651CA76746E7D8 /* Debug */, + 44796597F470CB17B9F821EC079DE9A0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C78AC542AF3C6690B1042AB421DBF608 /* Build configuration list for PBXNativeTarget "CNIOBoringSSLShims" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BFEA8CB36F2DD0D53ADC31769F8F1454 /* Debug */, + 76329E040871B244628D94B19AACF818 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C8C755AE412B45E17E1142C83244A1EF /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8A8619D62F7F018A9869A87A3D446E41 /* Debug */, + 23A065DAAC01EF849F8D213C687108D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CCF70CA0E20CF6114DFD888616FF765F /* Build configuration list for PBXNativeTarget "SwiftNIOHTTP1" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 95C50435EB7279CD7AA8D41693A970B8 /* Debug */, + 73D1C6D0BBD3258AC61403FF5B76CBA5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D82A5F20379D6AA8B5AF202CFA5838FB /* Build configuration list for PBXNativeTarget "SwiftNIOSSL" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CB128CFAC29569136BD8DBEC447C9D73 /* Debug */, + 5BA0D5C6D3F2E0D33B266175114ECCFB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1C7184C9DC5F57266D25F1FB10ADF8C /* Build configuration list for PBXNativeTarget "SwiftNIO" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A3DF9A64FD79319F234F474A01466479 /* Debug */, + 1E58A1C7465C2E275E30526CA2A3F809 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BigInt.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BigInt.xcscheme new file mode 100644 index 00000000..c273e024 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BigInt.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BloctoSDK.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BloctoSDK.xcscheme new file mode 100644 index 00000000..9a3a8eb3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/BloctoSDK.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CGRPCZlibp.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CGRPCZlibp.xcscheme new file mode 100644 index 00000000..5c4f01c3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CGRPCZlibp.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOAtomics.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOAtomics.xcscheme new file mode 100644 index 00000000..37cdda9c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOAtomics.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSL.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSL.xcscheme new file mode 100644 index 00000000..bb147e72 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSL.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSLShims.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSLShims.xcscheme new file mode 100644 index 00000000..aca4dd9a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOBoringSSLShims.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIODarwin.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIODarwin.xcscheme new file mode 100644 index 00000000..b9b79deb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIODarwin.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOHTTPParser.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOHTTPParser.xcscheme new file mode 100644 index 00000000..ad94e06e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOHTTPParser.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOLinux.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOLinux.xcscheme new file mode 100644 index 00000000..77fb13a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOLinux.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOWindows.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOWindows.xcscheme new file mode 100644 index 00000000..c5bd8578 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CNIOWindows.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Cadence.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Cadence.xcscheme new file mode 100644 index 00000000..e0224403 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Cadence.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CryptoSwift.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CryptoSwift.xcscheme new file mode 100644 index 00000000..453e76b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/CryptoSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/DynamicBlurView.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/DynamicBlurView.xcscheme new file mode 100644 index 00000000..d31d780d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/DynamicBlurView.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FCL-SDK.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FCL-SDK.xcscheme new file mode 100644 index 00000000..7cf61f0a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FCL-SDK.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FlowSDK.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FlowSDK.xcscheme new file mode 100644 index 00000000..66c6c6fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/FlowSDK.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Logging.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Logging.xcscheme new file mode 100644 index 00000000..afbe390b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Logging.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/MercariQRScanner.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/MercariQRScanner.xcscheme new file mode 100644 index 00000000..d91812e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/MercariQRScanner.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex-fanexUITests.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex-fanexUITests.xcscheme new file mode 100644 index 00000000..c598e6a1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex-fanexUITests.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex.xcscheme new file mode 100644 index 00000000..8f1fb861 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanex.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanexTests.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanexTests.xcscheme new file mode 100644 index 00000000..b7cd8e29 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/Pods-fanexTests.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/PopupDialog.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/PopupDialog.xcscheme new file mode 100644 index 00000000..da1aebe1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/PopupDialog.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SDWebImage.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SDWebImage.xcscheme new file mode 100644 index 00000000..37ef74c5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SDWebImage.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SVProgressHUD.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SVProgressHUD.xcscheme new file mode 100644 index 00000000..04fe60ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SVProgressHUD.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIO.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIO.xcscheme new file mode 100644 index 00000000..0c7d06b0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIO.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOConcurrencyHelpers.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOConcurrencyHelpers.xcscheme new file mode 100644 index 00000000..efb9c3ee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOConcurrencyHelpers.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOCore.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOCore.xcscheme new file mode 100644 index 00000000..377fc8ba --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOCore.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOEmbedded.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOEmbedded.xcscheme new file mode 100644 index 00000000..238161a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOEmbedded.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOExtras.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOExtras.xcscheme new file mode 100644 index 00000000..766b6a4c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOExtras.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOFoundationCompat.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOFoundationCompat.xcscheme new file mode 100644 index 00000000..078581f6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOFoundationCompat.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHPACK.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHPACK.xcscheme new file mode 100644 index 00000000..a9e1c81c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHPACK.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP1.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP1.xcscheme new file mode 100644 index 00000000..738395f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP1.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP2.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP2.xcscheme new file mode 100644 index 00000000..c4cd4427 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOHTTP2.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOPosix.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOPosix.xcscheme new file mode 100644 index 00000000..ab45d729 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOPosix.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOSSL.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOSSL.xcscheme new file mode 100644 index 00000000..0dd40b41 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOSSL.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTLS.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTLS.xcscheme new file mode 100644 index 00000000..2eb863c4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTLS.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTransportServices.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTransportServices.xcscheme new file mode 100644 index 00000000..a55016fa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftNIOTransportServices.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftProtobuf.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftProtobuf.xcscheme new file mode 100644 index 00000000..73f74767 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftProtobuf.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftyJSON.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftyJSON.xcscheme new file mode 100644 index 00000000..6cbb0561 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/SwiftyJSON.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/_NIODataStructures.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/_NIODataStructures.xcscheme new file mode 100644 index 00000000..28c17721 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/_NIODataStructures.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/gRPC-Swiftp.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/gRPC-Swiftp.xcscheme new file mode 100644 index 00000000..8158bb19 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/gRPC-Swiftp.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Swift.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Swift.xcscheme new file mode 100644 index 00000000..37ad2dd0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Swift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Wrapper.xcscheme b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Wrapper.xcscheme new file mode 100644 index 00000000..7eaf37c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/secp256k1Wrapper.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..37204f62 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Pods.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,305 @@ + + + + + SchemeUserState + + BigInt.xcscheme + + isShown + + orderHint + 54 + + BloctoSDK.xcscheme + + isShown + + orderHint + 55 + + CGRPCZlibp.xcscheme + + isShown + + orderHint + 57 + + CNIOAtomics.xcscheme + + isShown + + orderHint + 58 + + CNIOBoringSSL.xcscheme + + isShown + + orderHint + 59 + + CNIOBoringSSLShims.xcscheme + + isShown + + orderHint + 60 + + CNIODarwin.xcscheme + + isShown + + orderHint + 61 + + CNIOHTTPParser.xcscheme + + isShown + + orderHint + 62 + + CNIOLinux.xcscheme + + isShown + + orderHint + 63 + + CNIOWindows.xcscheme + + isShown + + orderHint + 64 + + Cadence.xcscheme + + isShown + + orderHint + 56 + + CryptoSwift.xcscheme + + isShown + + orderHint + 65 + + DynamicBlurView.xcscheme + + isShown + + orderHint + 66 + + FCL-SDK.xcscheme + + isShown + + orderHint + 67 + + FlowSDK.xcscheme + + isShown + + orderHint + 68 + + Logging.xcscheme + + isShown + + orderHint + 70 + + MercariQRScanner.xcscheme + + isShown + + orderHint + 71 + + Pods-fanex-fanexUITests.xcscheme + + isShown + + orderHint + 73 + + Pods-fanex.xcscheme + + isShown + + orderHint + 72 + + Pods-fanexTests.xcscheme + + isShown + + orderHint + 74 + + PopupDialog.xcscheme + + isShown + + orderHint + 75 + + SDWebImage.xcscheme + + isShown + + orderHint + 76 + + SVProgressHUD.xcscheme + + isShown + + orderHint + 79 + + SwiftNIO.xcscheme + + isShown + + orderHint + 80 + + SwiftNIOConcurrencyHelpers.xcscheme + + isShown + + orderHint + 81 + + SwiftNIOCore.xcscheme + + isShown + + orderHint + 82 + + SwiftNIOEmbedded.xcscheme + + isShown + + orderHint + 83 + + SwiftNIOExtras.xcscheme + + isShown + + orderHint + 84 + + SwiftNIOFoundationCompat.xcscheme + + isShown + + orderHint + 85 + + SwiftNIOHPACK.xcscheme + + isShown + + orderHint + 86 + + SwiftNIOHTTP1.xcscheme + + isShown + + orderHint + 87 + + SwiftNIOHTTP2.xcscheme + + isShown + + orderHint + 88 + + SwiftNIOPosix.xcscheme + + isShown + + orderHint + 89 + + SwiftNIOSSL.xcscheme + + isShown + + orderHint + 90 + + SwiftNIOTLS.xcscheme + + isShown + + orderHint + 91 + + SwiftNIOTransportServices.xcscheme + + isShown + + orderHint + 92 + + SwiftProtobuf.xcscheme + + isShown + + orderHint + 93 + + SwiftyJSON.xcscheme + + isShown + + orderHint + 94 + + _NIODataStructures.xcscheme + + isShown + + orderHint + 53 + + gRPC-Swiftp.xcscheme + + isShown + + orderHint + 69 + + secp256k1Swift.xcscheme + + isShown + + orderHint + 77 + + secp256k1Wrapper.xcscheme + + isShown + + orderHint + 78 + + + SuppressBuildableAutocreation + + + diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/LICENSE b/one-and-half-nibble/MobileApp/Pods/PopupDialog/LICENSE new file mode 100644 index 00000000..6431917c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +Author - Martin Wildfeuer (http://www.mwfire.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/InteractiveTransition.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/InteractiveTransition.swift new file mode 100644 index 00000000..0f9f2f43 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/InteractiveTransition.swift @@ -0,0 +1,86 @@ +// +// PopupDialogInteractiveTransition.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +// Handles interactive transition triggered via pan gesture recognizer on dialog +final internal class InteractiveTransition: UIPercentDrivenInteractiveTransition { + + // If the interactive transition was started + var hasStarted = false + + // If the interactive transition + var shouldFinish = false + + // The view controller containing the views + // with attached gesture recognizers + weak var viewController: UIViewController? + + @objc func handlePan(_ sender: UIPanGestureRecognizer) { + + guard let vc = viewController else { return } + + guard let progress = calculateProgress(sender: sender) else { return } + + switch sender.state { + case .began: + hasStarted = true + vc.dismiss(animated: true, completion: nil) + case .changed: + shouldFinish = progress > 0.3 + update(progress) + case .cancelled: + hasStarted = false + cancel() + case .ended: + hasStarted = false + completionSpeed = 0.55 + shouldFinish ? finish() : cancel() + default: + break + } + } +} + +internal extension InteractiveTransition { + + /*! + Translates the pan gesture recognizer position to the progress percentage + - parameter sender: A UIPanGestureRecognizer + - returns: Progress + */ + func calculateProgress(sender: UIPanGestureRecognizer) -> CGFloat? { + guard let vc = viewController else { return nil } + + // http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/ + let translation = sender.translation(in: vc.view) + let verticalMovement = translation.y / vc.view.bounds.height + let downwardMovement = fmaxf(Float(verticalMovement), 0.0) + let downwardMovementPercent = fminf(downwardMovement, 1.0) + let progress = CGFloat(downwardMovementPercent) + + return progress + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog+Keyboard.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog+Keyboard.swift new file mode 100644 index 00000000..38ed6df8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog+Keyboard.swift @@ -0,0 +1,132 @@ +// +// PopupDialog+Keyboard.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// This extension is designed to handle dialog positioning +/// if a keyboard is displayed while the popup is on top +internal extension PopupDialog { + + // MARK: - Keyboard & orientation observers + + /*! Add obserservers for UIKeyboard notifications */ + func addObservers() { + NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), + name: UIDevice.orientationDidChangeNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(keyboardWillShow), + name: UIResponder.keyboardWillShowNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(keyboardWillHide), + name: UIResponder.keyboardWillHideNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(keyboardWillChangeFrame), + name: UIResponder.keyboardWillChangeFrameNotification, + object: nil) + } + + /*! Remove observers */ + func removeObservers() { + NotificationCenter.default.removeObserver(self, + name: UIDevice.orientationDidChangeNotification, + object: nil) + + NotificationCenter.default.removeObserver(self, + name: UIResponder.keyboardWillShowNotification, + object: nil) + + NotificationCenter.default.removeObserver(self, + name: UIResponder.keyboardWillHideNotification, + object: nil) + + NotificationCenter.default.removeObserver(self, + name: UIResponder.keyboardWillChangeFrameNotification, + object: nil) + } + + // MARK: - Actions + + /*! + Keyboard will show notification listener + - parameter notification: NSNotification + */ + @objc fileprivate func keyboardWillShow(_ notification: Notification) { + guard isTopAndVisible else { return } + keyboardShown = true + centerPopup() + } + + /*! + Keyboard will hide notification listener + - parameter notification: NSNotification + */ + @objc fileprivate func keyboardWillHide(_ notification: Notification) { + guard isTopAndVisible else { return } + keyboardShown = false + centerPopup() + } + + /*! + Keyboard will change frame notification listener + - parameter notification: NSNotification + */ + @objc fileprivate func keyboardWillChangeFrame(_ notification: Notification) { + guard let keyboardRect = (notification as NSNotification).userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { + return + } + keyboardHeight = keyboardRect.cgRectValue.height + } + + /*! + Listen to orientation changes + - parameter notification: NSNotification + */ + @objc fileprivate func orientationChanged(_ notification: Notification) { + if keyboardShown { centerPopup() } + } + + fileprivate func centerPopup() { + + // Make sure keyboard should reposition on keayboard notifications + guard keyboardShiftsView else { return } + + // Make sure a valid keyboard height is available + guard let keyboardHeight = keyboardHeight else { return } + + // Calculate new center of shadow background + let popupCenter = keyboardShown ? keyboardHeight / -2 : 0 + + // Reposition and animate + popupContainerView.centerYConstraint?.constant = popupCenter + popupContainerView.pv_layoutIfNeededAnimated() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog.swift new file mode 100644 index 00000000..69e7a006 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialog.swift @@ -0,0 +1,342 @@ +// +// PopupDialog.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// Creates a Popup dialog similar to UIAlertController +final public class PopupDialog: UIViewController { + + // MARK: Private / Internal + + /// First init flag + fileprivate var initialized = false + + /// StatusBar display related + fileprivate let hideStatusBar: Bool + fileprivate var statusBarShouldBeHidden: Bool = false + + /// Width for iPad displays + fileprivate let preferredWidth: CGFloat + + /// The completion handler + fileprivate var completion: (() -> Void)? + + /// The custom transition presentation manager + fileprivate var presentationManager: PresentationManager! + + /// Interactor class for pan gesture dismissal + fileprivate lazy var interactor = InteractiveTransition() + + /// Returns the controllers view + internal var popupContainerView: PopupDialogContainerView { + return view as! PopupDialogContainerView // swiftlint:disable:this force_cast + } + + /// The set of buttons + fileprivate var buttons = [PopupDialogButton]() + + /// Whether keyboard has shifted view + internal var keyboardShown = false + + /// Keyboard height + internal var keyboardHeight: CGFloat? + + // MARK: Public + + /// The content view of the popup dialog + public var viewController: UIViewController + + /// Whether or not to shift view for keyboard display + public var keyboardShiftsView = true + + // MARK: - Initializers + + /*! + Creates a standard popup dialog with title, message and image field + + - parameter title: The dialog title + - parameter message: The dialog message + - parameter image: The dialog image + - parameter buttonAlignment: The dialog button alignment + - parameter transitionStyle: The dialog transition style + - parameter preferredWidth: The preferred width for iPad screens + - parameter tapGestureDismissal: Indicates if dialog can be dismissed via tap gesture + - parameter panGestureDismissal: Indicates if dialog can be dismissed via pan gesture + - parameter hideStatusBar: Whether to hide the status bar on PopupDialog presentation + - parameter completion: Completion block invoked when dialog was dismissed + + - returns: Popup dialog default style + */ + @objc public convenience init( + title: String?, + message: String?, + image: UIImage? = nil, + buttonAlignment: NSLayoutConstraint.Axis = .vertical, + transitionStyle: PopupDialogTransitionStyle = .bounceUp, + preferredWidth: CGFloat = 340, + tapGestureDismissal: Bool = true, + panGestureDismissal: Bool = true, + hideStatusBar: Bool = false, + completion: (() -> Void)? = nil) { + + // Create and configure the standard popup dialog view + let viewController = PopupDialogDefaultViewController() + viewController.titleText = title + viewController.messageText = message + viewController.image = image + + // Call designated initializer + self.init(viewController: viewController, + buttonAlignment: buttonAlignment, + transitionStyle: transitionStyle, + preferredWidth: preferredWidth, + tapGestureDismissal: tapGestureDismissal, + panGestureDismissal: panGestureDismissal, + hideStatusBar: hideStatusBar, + completion: completion) + } + + /*! + Creates a popup dialog containing a custom view + + - parameter viewController: A custom view controller to be displayed + - parameter buttonAlignment: The dialog button alignment + - parameter transitionStyle: The dialog transition style + - parameter preferredWidth: The preferred width for iPad screens + - parameter tapGestureDismissal: Indicates if dialog can be dismissed via tap gesture + - parameter panGestureDismissal: Indicates if dialog can be dismissed via pan gesture + - parameter hideStatusBar: Whether to hide the status bar on PopupDialog presentation + - parameter completion: Completion block invoked when dialog was dismissed + + - returns: Popup dialog with a custom view controller + */ + @objc public init( + viewController: UIViewController, + buttonAlignment: NSLayoutConstraint.Axis = .vertical, + transitionStyle: PopupDialogTransitionStyle = .bounceUp, + preferredWidth: CGFloat = 340, + tapGestureDismissal: Bool = true, + panGestureDismissal: Bool = true, + hideStatusBar: Bool = false, + completion: (() -> Void)? = nil) { + + self.viewController = viewController + self.preferredWidth = preferredWidth + self.hideStatusBar = hideStatusBar + self.completion = completion + super.init(nibName: nil, bundle: nil) + + // Init the presentation manager + presentationManager = PresentationManager(transitionStyle: transitionStyle, interactor: interactor) + + // Assign the interactor view controller + interactor.viewController = self + + // Define presentation styles + transitioningDelegate = presentationManager + modalPresentationStyle = .custom + + // StatusBar setup + modalPresentationCapturesStatusBarAppearance = true + + // Add our custom view to the container + addChild(viewController) + popupContainerView.stackView.insertArrangedSubview(viewController.view, at: 0) + popupContainerView.buttonStackView.axis = buttonAlignment + viewController.didMove(toParent: self) + + // Allow for dialog dismissal on background tap + if tapGestureDismissal { + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap)) + tapRecognizer.cancelsTouchesInView = false + popupContainerView.addGestureRecognizer(tapRecognizer) + } + // Allow for dialog dismissal on dialog pan gesture + if panGestureDismissal { + let panRecognizer = UIPanGestureRecognizer(target: interactor, action: #selector(InteractiveTransition.handlePan)) + panRecognizer.cancelsTouchesInView = false + popupContainerView.stackView.addGestureRecognizer(panRecognizer) + } + } + + // Init with coder not implemented + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - View life cycle + + /// Replaces controller view with popup view + public override func loadView() { + view = PopupDialogContainerView(frame: UIScreen.main.bounds, preferredWidth: preferredWidth) + } + + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + addObservers() + + guard !initialized else { return } + appendButtons() + initialized = true + } + + public override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + statusBarShouldBeHidden = hideStatusBar + UIView.animate(withDuration: 0.15) { + self.setNeedsStatusBarAppearanceUpdate() + } + } + + public override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + removeObservers() + } + + deinit { + completion?() + completion = nil + } + + // MARK: - Dismissal related + + @objc fileprivate func handleTap(_ sender: UITapGestureRecognizer) { + + // Make sure it's not a tap on the dialog but the background + let point = sender.location(in: popupContainerView.stackView) + guard !popupContainerView.stackView.point(inside: point, with: nil) else { return } + dismiss() + } + + /*! + Dismisses the popup dialog + */ + @objc public func dismiss(_ completion: (() -> Void)? = nil) { + self.dismiss(animated: true) { + completion?() + } + } + + // MARK: - Button related + + /*! + Appends the buttons added to the popup dialog + to the placeholder stack view + */ + fileprivate func appendButtons() { + + // Add action to buttons + let stackView = popupContainerView.stackView + let buttonStackView = popupContainerView.buttonStackView + if buttons.isEmpty { + stackView.removeArrangedSubview(popupContainerView.buttonStackView) + } + + for (index, button) in buttons.enumerated() { + button.needsLeftSeparator = buttonStackView.axis == .horizontal && index > 0 + buttonStackView.addArrangedSubview(button) + button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) + } + } + + /*! + Adds a single PopupDialogButton to the Popup dialog + - parameter button: A PopupDialogButton instance + */ + @objc public func addButton(_ button: PopupDialogButton) { + buttons.append(button) + } + + /*! + Adds an array of PopupDialogButtons to the Popup dialog + - parameter buttons: A list of PopupDialogButton instances + */ + @objc public func addButtons(_ buttons: [PopupDialogButton]) { + self.buttons += buttons + } + + /// Calls the action closure of the button instance tapped + @objc fileprivate func buttonTapped(_ button: PopupDialogButton) { + if button.dismissOnTap { + dismiss({ button.buttonAction?() }) + } else { + button.buttonAction?() + } + } + + /*! + Simulates a button tap for the given index + Makes testing a breeze + - parameter index: The index of the button to tap + */ + public func tapButtonWithIndex(_ index: Int) { + let button = buttons[index] + button.buttonAction?() + } + + // MARK: - StatusBar display related + + public override var prefersStatusBarHidden: Bool { + return statusBarShouldBeHidden + } + + public override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { + return .slide + } +} + +// MARK: - View proxy values + +extension PopupDialog { + + /// The button alignment of the alert dialog + @objc public var buttonAlignment: NSLayoutConstraint.Axis { + get { + return popupContainerView.buttonStackView.axis + } + set { + popupContainerView.buttonStackView .axis = newValue + popupContainerView.pv_layoutIfNeededAnimated() + } + } + + /// The transition style + @objc public var transitionStyle: PopupDialogTransitionStyle { + get { return presentationManager.transitionStyle } + set { presentationManager.transitionStyle = newValue } + } +} + +// MARK: - Shake + +extension PopupDialog { + + /// Performs a shake animation on the dialog + @objc public func shake() { + popupContainerView.pv_shake() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogButton.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogButton.swift new file mode 100644 index 00000000..774213b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogButton.swift @@ -0,0 +1,166 @@ +// +// PopupDialogButton.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// Represents the default button for the popup dialog +open class PopupDialogButton: UIButton { + + public typealias PopupDialogButtonAction = () -> Void + + // MARK: Public + + /// The font and size of the button title + @objc open dynamic var titleFont: UIFont? { + get { return titleLabel?.font } + set { titleLabel?.font = newValue } + } + + /// The height of the button + @objc open dynamic var buttonHeight: Int + + /// The title color of the button + @objc open dynamic var titleColor: UIColor? { + get { return self.titleColor(for: UIControl.State()) } + set { setTitleColor(newValue, for: UIControl.State()) } + } + + /// The background color of the button + @objc open dynamic var buttonColor: UIColor? { + get { return backgroundColor } + set { backgroundColor = newValue } + } + + /// The separator color of this button + @objc open dynamic var separatorColor: UIColor? { + get { return separator.backgroundColor } + set { + separator.backgroundColor = newValue + leftSeparator.backgroundColor = newValue + } + } + + /// Default appearance of the button + open var defaultTitleFont = UIFont.systemFont(ofSize: 14) + open var defaultTitleColor = UIColor(red: 0.25, green: 0.53, blue: 0.91, alpha: 1) + open var defaultButtonColor = UIColor.clear + open var defaultSeparatorColor = UIColor(white: 0.9, alpha: 1) + + /// Whether button should dismiss popup when tapped + @objc open var dismissOnTap = true + + /// The action called when the button is tapped + open fileprivate(set) var buttonAction: PopupDialogButtonAction? + + // MARK: Private + + fileprivate lazy var separator: UIView = { + let line = UIView(frame: .zero) + line.translatesAutoresizingMaskIntoConstraints = false + return line + }() + + fileprivate lazy var leftSeparator: UIView = { + let line = UIView(frame: .zero) + line.translatesAutoresizingMaskIntoConstraints = false + line.alpha = 0 + return line + }() + + // MARK: Internal + + internal var needsLeftSeparator: Bool = false { + didSet { + leftSeparator.alpha = needsLeftSeparator ? 1.0 : 0.0 + } + } + + // MARK: Initializers + + /*! + Creates a button that can be added to the popup dialog + + - parameter title: The button title + - parameter dismisssOnTap: Whether a tap automatically dismisses the dialog + - parameter action: The action closure + + - returns: PopupDialogButton + */ + @objc public init(title: String, height: Int = 45, dismissOnTap: Bool = true, action: PopupDialogButtonAction?) { + + // Assign the button height + buttonHeight = height + + // Assign the button action + buttonAction = action + + super.init(frame: .zero) + + // Set the button title + setTitle(title, for: UIControl.State()) + + self.dismissOnTap = dismissOnTap + + // Setup the views + setupView() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: View setup + + open func setupView() { + + // Default appearance + setTitleColor(defaultTitleColor, for: UIControl.State()) + titleLabel?.font = defaultTitleFont + backgroundColor = defaultButtonColor + separator.backgroundColor = defaultSeparatorColor + leftSeparator.backgroundColor = defaultSeparatorColor + + // Add and layout views + addSubview(separator) + addSubview(leftSeparator) + + let views = ["separator": separator, "leftSeparator": leftSeparator, "button": self] + let metrics = ["buttonHeight": buttonHeight] + var constraints = [NSLayoutConstraint]() + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:[button(buttonHeight)]", options: [], metrics: metrics, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[separator]|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[separator(1)]", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[leftSeparator(1)]", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[leftSeparator]|", options: [], metrics: nil, views: views) + NSLayoutConstraint.activate(constraints) + } + + open override var isHighlighted: Bool { + didSet { + isHighlighted ? pv_fade(.out, 0.5) : pv_fade(.in, 1.0) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogContainerView.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogContainerView.swift new file mode 100644 index 00000000..4f36e6c0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogContainerView.swift @@ -0,0 +1,197 @@ +// +// PopupDialogContainerView.swift +// Pods +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// The main view of the popup dialog +final public class PopupDialogContainerView: UIView { + + // MARK: - Appearance + + /// The background color of the popup dialog + override public dynamic var backgroundColor: UIColor? { + get { return container.backgroundColor } + set { container.backgroundColor = newValue } + } + + /// The corner radius of the popup view + @objc public dynamic var cornerRadius: Float { + get { return Float(shadowContainer.layer.cornerRadius) } + set { + let radius = CGFloat(newValue) + shadowContainer.layer.cornerRadius = radius + container.layer.cornerRadius = radius + } + } + + // MARK: Shadow related + + /// Enable / disable shadow rendering of the container + @objc public dynamic var shadowEnabled: Bool { + get { return shadowContainer.layer.shadowRadius > 0 } + set { shadowContainer.layer.shadowRadius = newValue ? shadowRadius : 0 } + } + + /// Color of the container shadow + @objc public dynamic var shadowColor: UIColor? { + get { + guard let color = shadowContainer.layer.shadowColor else { + return nil + } + return UIColor(cgColor: color) + } + set { shadowContainer.layer.shadowColor = newValue?.cgColor } + } + + /// Radius of the container shadow + @objc public dynamic var shadowRadius: CGFloat { + get { return shadowContainer.layer.shadowRadius } + set { shadowContainer.layer.shadowRadius = newValue } + } + + /// Opacity of the the container shadow + @objc public dynamic var shadowOpacity: Float { + get { return shadowContainer.layer.shadowOpacity } + set { shadowContainer.layer.shadowOpacity = newValue } + } + + /// Offset of the the container shadow + @objc public dynamic var shadowOffset: CGSize { + get { return shadowContainer.layer.shadowOffset } + set { shadowContainer.layer.shadowOffset = newValue } + } + + /// Path of the the container shadow + @objc public dynamic var shadowPath: CGPath? { + get { return shadowContainer.layer.shadowPath} + set { shadowContainer.layer.shadowPath = newValue } + } + + // MARK: - Views + + /// The shadow container is the basic view of the PopupDialog + /// As it does not clip subviews, a shadow can be applied to it + internal lazy var shadowContainer: UIView = { + let shadowContainer = UIView(frame: .zero) + shadowContainer.translatesAutoresizingMaskIntoConstraints = false + shadowContainer.backgroundColor = UIColor.clear + shadowContainer.layer.shadowColor = UIColor.black.cgColor + shadowContainer.layer.shadowRadius = 5 + shadowContainer.layer.shadowOpacity = 0.4 + shadowContainer.layer.shadowOffset = CGSize(width: 0, height: 0) + shadowContainer.layer.cornerRadius = 4 + return shadowContainer + }() + + /// The container view is a child of shadowContainer and contains + /// all other views. It clips to bounds so cornerRadius can be set + internal lazy var container: UIView = { + let container = UIView(frame: .zero) + container.translatesAutoresizingMaskIntoConstraints = false + container.backgroundColor = UIColor.white + container.clipsToBounds = true + container.layer.cornerRadius = 4 + return container + }() + + // The container stack view for buttons + internal lazy var buttonStackView: UIStackView = { + let buttonStackView = UIStackView() + buttonStackView.translatesAutoresizingMaskIntoConstraints = false + buttonStackView.distribution = .fillEqually + buttonStackView.spacing = 0 + return buttonStackView + }() + + // The main stack view, containing all relevant views + internal lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.buttonStackView]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = 0 + return stackView + }() + + // The preferred width for iPads + fileprivate let preferredWidth: CGFloat + + // MARK: - Constraints + + /// The center constraint of the shadow container + internal var centerYConstraint: NSLayoutConstraint? + + // MARK: - Initializers + + internal init(frame: CGRect, preferredWidth: CGFloat) { + self.preferredWidth = preferredWidth + super.init(frame: frame) + setupViews() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - View setup + + internal func setupViews() { + + // Add views + addSubview(shadowContainer) + shadowContainer.addSubview(container) + container.addSubview(stackView) + + // Layout views + let views = ["shadowContainer": shadowContainer, "container": container, "stackView": stackView] + var constraints = [NSLayoutConstraint]() + + // Shadow container constraints + if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad { + let metrics = ["preferredWidth": preferredWidth] + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(>=40)-[shadowContainer(==preferredWidth@900)]-(>=40)-|", options: [], metrics: metrics, views: views) + } else { + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(>=10,==20@900)-[shadowContainer(<=340,>=300)]-(>=10,==20@900)-|", options: [], metrics: nil, views: views) + } + constraints += [NSLayoutConstraint(item: shadowContainer, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)] + centerYConstraint = NSLayoutConstraint(item: shadowContainer, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0) + + if let centerYConstraint = centerYConstraint { + constraints.append(centerYConstraint) + } + + // Container constraints + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[container]|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[container]|", options: [], metrics: nil, views: views) + + // Main stack view constraints + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[stackView]|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: [], metrics: nil, views: views) + + // Activate constraints + NSLayoutConstraint.activate(constraints) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultButtons.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultButtons.swift new file mode 100644 index 00000000..0bb130ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultButtons.swift @@ -0,0 +1,54 @@ +// +// PopupDialogDefaultButtons.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +// MARK: Default button + +/// Represents the default button for the popup dialog +public final class DefaultButton: PopupDialogButton {} + +// MARK: Cancel button + +/// Represents a cancel button for the popup dialog +public final class CancelButton: PopupDialogButton { + + override public func setupView() { + defaultTitleColor = UIColor.lightGray + super.setupView() + } +} + +// MARK: destructive button + +/// Represents a destructive button for the popup dialog +public final class DestructiveButton: PopupDialogButton { + + override public func setupView() { + defaultTitleColor = UIColor.red + super.setupView() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultView.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultView.swift new file mode 100644 index 00000000..7107222e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultView.swift @@ -0,0 +1,148 @@ +// +// PopupDialogView.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// The main view of the popup dialog +final public class PopupDialogDefaultView: UIView { + + // MARK: - Appearance + + /// The font and size of the title label + @objc public dynamic var titleFont: UIFont { + get { return titleLabel.font } + set { titleLabel.font = newValue } + } + + /// The color of the title label + @objc public dynamic var titleColor: UIColor? { + get { return titleLabel.textColor } + set { titleLabel.textColor = newValue } + } + + /// The text alignment of the title label + @objc public dynamic var titleTextAlignment: NSTextAlignment { + get { return titleLabel.textAlignment } + set { titleLabel.textAlignment = newValue } + } + + /// The font and size of the body label + @objc public dynamic var messageFont: UIFont { + get { return messageLabel.font } + set { messageLabel.font = newValue } + } + + /// The color of the message label + @objc public dynamic var messageColor: UIColor? { + get { return messageLabel.textColor } + set { messageLabel.textColor = newValue} + } + + /// The text alignment of the message label + @objc public dynamic var messageTextAlignment: NSTextAlignment { + get { return messageLabel.textAlignment } + set { messageLabel.textAlignment = newValue } + } + + // MARK: - Views + + /// The view that will contain the image, if set + internal lazy var imageView: UIImageView = { + let imageView = UIImageView(frame: .zero) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + return imageView + }() + + /// The title label of the dialog + internal lazy var titleLabel: UILabel = { + let titleLabel = UILabel(frame: .zero) + titleLabel.translatesAutoresizingMaskIntoConstraints = false + titleLabel.numberOfLines = 0 + titleLabel.textAlignment = .center + titleLabel.textColor = UIColor(white: 0.4, alpha: 1) + titleLabel.font = .boldSystemFont(ofSize: 14) + return titleLabel + }() + + /// The message label of the dialog + internal lazy var messageLabel: UILabel = { + let messageLabel = UILabel(frame: .zero) + messageLabel.translatesAutoresizingMaskIntoConstraints = false + messageLabel.numberOfLines = 0 + messageLabel.textAlignment = .center + messageLabel.textColor = UIColor(white: 0.6, alpha: 1) + messageLabel.font = .systemFont(ofSize: 14) + return messageLabel + }() + + /// The height constraint of the image view, 0 by default + internal var imageHeightConstraint: NSLayoutConstraint? + + // MARK: - Initializers + + internal override init(frame: CGRect) { + super.init(frame: frame) + setupViews() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - View setup + + internal func setupViews() { + + // Self setup + translatesAutoresizingMaskIntoConstraints = false + + // Add views + addSubview(imageView) + addSubview(titleLabel) + addSubview(messageLabel) + + // Layout views + let views = ["imageView": imageView, "titleLabel": titleLabel, "messageLabel": messageLabel] as [String: Any] + var constraints = [NSLayoutConstraint]() + + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[imageView]|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(==20@900)-[titleLabel]-(==20@900)-|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(==20@900)-[messageLabel]-(==20@900)-|", options: [], metrics: nil, views: views) + constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-(==30@900)-[titleLabel]-(==8@900)-[messageLabel]-(==30@900)-|", options: [], metrics: nil, views: views) + + // ImageView height constraint + imageHeightConstraint = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: imageView, attribute: .height, multiplier: 0, constant: 0) + + if let imageHeightConstraint = imageHeightConstraint { + constraints.append(imageHeightConstraint) + } + + // Activate constraints + NSLayoutConstraint.activate(constraints) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultViewController.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultViewController.swift new file mode 100644 index 00000000..cdda4111 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogDefaultViewController.swift @@ -0,0 +1,133 @@ +// +// PopupDialogDefaultViewController.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import UIKit + +final public class PopupDialogDefaultViewController: UIViewController { + + public var standardView: PopupDialogDefaultView { + return view as! PopupDialogDefaultView // swiftlint:disable:this force_cast + } + + override public func loadView() { + super.loadView() + view = PopupDialogDefaultView(frame: .zero) + } +} + +public extension PopupDialogDefaultViewController { + + // MARK: - Setter / Getter + + // MARK: Content + + /// The dialog image + var image: UIImage? { + get { return standardView.imageView.image } + set { + standardView.imageView.image = newValue + standardView.imageHeightConstraint?.constant = standardView.imageView.pv_heightForImageView() + } + } + + /// The title text of the dialog + var titleText: String? { + get { return standardView.titleLabel.text } + set { + standardView.titleLabel.text = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The message text of the dialog + var messageText: String? { + get { return standardView.messageLabel.text } + set { + standardView.messageLabel.text = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + // MARK: Appearance + + /// The font and size of the title label + @objc dynamic var titleFont: UIFont { + get { return standardView.titleFont } + set { + standardView.titleFont = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The color of the title label + @objc dynamic var titleColor: UIColor? { + get { return standardView.titleLabel.textColor } + set { + standardView.titleColor = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The text alignment of the title label + @objc dynamic var titleTextAlignment: NSTextAlignment { + get { return standardView.titleTextAlignment } + set { + standardView.titleTextAlignment = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The font and size of the body label + @objc dynamic var messageFont: UIFont { + get { return standardView.messageFont} + set { + standardView.messageFont = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The color of the message label + @objc dynamic var messageColor: UIColor? { + get { return standardView.messageColor } + set { + standardView.messageColor = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + /// The text alignment of the message label + @objc dynamic var messageTextAlignment: NSTextAlignment { + get { return standardView.messageTextAlignment } + set { + standardView.messageTextAlignment = newValue + standardView.pv_layoutIfNeededAnimated() + } + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + standardView.imageHeightConstraint?.constant = standardView.imageView.pv_heightForImageView() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogOverlayView.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogOverlayView.swift new file mode 100644 index 00000000..a1326c08 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PopupDialogOverlayView.swift @@ -0,0 +1,128 @@ +// +// PopupDialogOverlayView.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import DynamicBlurView + +/// The (blurred) overlay view below the popup dialog +final public class PopupDialogOverlayView: UIView { + + // MARK: - Appearance + + /// Turns the blur of the overlay view on or off + @objc public dynamic var blurEnabled: Bool { + get { return !blurView.isHidden } + set { blurView.isHidden = !newValue } + } + + /// The blur radius of the overlay view + @objc public dynamic var blurRadius: CGFloat { + get { return blurView.blurRadius } + set { blurView.blurRadius = newValue } + } + + /// Whether the blur view should allow for + /// live rendering of the background + @objc public dynamic var liveBlurEnabled: Bool { + get { return blurView.trackingMode == .common } + set { + if newValue { + blurView.trackingMode = .common + } else { + blurView.trackingMode = .none + } + } + } + + /// The background color of the overlay view + @objc public dynamic var color: UIColor? { + get { return overlay.backgroundColor } + set { overlay.backgroundColor = newValue } + } + + /// The opacity of the overlay view + @objc public dynamic var opacity: CGFloat { + get { return overlay.alpha } + set { overlay.alpha = newValue } + } + + // MARK: - Views + + internal lazy var blurView: DynamicBlurView = { + let blurView = DynamicBlurView(frame: .zero) + blurView.blurRadius = 8 + blurView.trackingMode = .none + blurView.isDeepRendering = true + blurView.tintColor = .clear + blurView.autoresizingMask = [.flexibleHeight, .flexibleWidth] + return blurView + }() + + internal lazy var overlay: UIView = { + let overlay = UIView(frame: .zero) + overlay.backgroundColor = .black + overlay.alpha = 0.7 + overlay.autoresizingMask = [.flexibleHeight, .flexibleWidth] + return overlay + }() + + // MARK: - Inititalizers + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - View setup + + fileprivate func setupView() { + + autoresizingMask = [.flexibleHeight, .flexibleWidth] + backgroundColor = .clear + alpha = 0 + + addSubview(blurView) + addSubview(overlay) + } + +} + +// MARK: - Deprecated + +extension PopupDialogOverlayView { + + /// Whether the blur view should allow for + /// dynamic rendering of the background + @available(*, deprecated, message: "liveBlur has been deprecated and will be removed with future versions of PopupDialog. Please use isLiveBlurEnabled instead.") + @objc public dynamic var liveBlur: Bool { + get { return liveBlurEnabled } + set { liveBlurEnabled = newValue } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationController.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationController.swift new file mode 100644 index 00000000..ccca56ab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationController.swift @@ -0,0 +1,61 @@ +// +// PopupDialogPresentationController.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +final internal class PresentationController: UIPresentationController { + + private lazy var overlay: PopupDialogOverlayView = { + return PopupDialogOverlayView(frame: .zero) + }() + + override func presentationTransitionWillBegin() { + + guard let containerView = containerView else { return } + + overlay.frame = containerView.bounds + containerView.insertSubview(overlay, at: 0) + + presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in + self?.overlay.alpha = 1.0 + }, completion: nil) + } + + override func dismissalTransitionWillBegin() { + presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in + self?.overlay.alpha = 0.0 + }, completion: nil) + } + + override func containerViewWillLayoutSubviews() { + + guard let presentedView = presentedView else { return } + + presentedView.frame = frameOfPresentedViewInContainerView + overlay.blurView.refresh() + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationManager.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationManager.swift new file mode 100644 index 00000000..fdc1072a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/PresentationManager.swift @@ -0,0 +1,86 @@ +// +// PopupDialogPresentationManager.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +final internal class PresentationManager: NSObject, UIViewControllerTransitioningDelegate { + + var transitionStyle: PopupDialogTransitionStyle + var interactor: InteractiveTransition + + init(transitionStyle: PopupDialogTransitionStyle, interactor: InteractiveTransition) { + self.transitionStyle = transitionStyle + self.interactor = interactor + super.init() + } + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + let presentationController = PresentationController(presentedViewController: presented, presenting: source) + return presentationController + } + + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + + var transition: TransitionAnimator + switch transitionStyle { + case .bounceUp: + transition = BounceUpTransition(direction: .in) + case .bounceDown: + transition = BounceDownTransition(direction: .in) + case .zoomIn: + transition = ZoomTransition(direction: .in) + case .fadeIn: + transition = FadeTransition(direction: .in) + } + + return transition + } + + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + + if interactor.hasStarted || interactor.shouldFinish { + return DismissInteractiveTransition() + } + + var transition: TransitionAnimator + switch transitionStyle { + case .bounceUp: + transition = BounceUpTransition(direction: .out) + case .bounceDown: + transition = BounceDownTransition(direction: .out) + case .zoomIn: + transition = ZoomTransition(direction: .out) + case .fadeIn: + transition = FadeTransition(direction: .out) + } + + return transition + } + + func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return interactor.hasStarted ? interactor : nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimations.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimations.swift new file mode 100644 index 00000000..e496b0c6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimations.swift @@ -0,0 +1,186 @@ +// +// PopupDialogTransitionAnimations.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/*! + Presentation transition styles for the popup dialog + + - BounceUp: Dialog bounces in from bottom and is dismissed to bottom + - BounceDown: Dialog bounces in from top and is dismissed to top + - ZoomIn: Dialog zooms in and is dismissed by zooming out + - FadeIn: Dialog fades in and is dismissed by fading out + */ +@objc public enum PopupDialogTransitionStyle: Int { + case bounceUp + case bounceDown + case zoomIn + case fadeIn +} + +/// Dialog bounces in from bottom and is dismissed to bottom +final internal class BounceUpTransition: TransitionAnimator { + + init(direction: AnimationDirection) { + super.init(inDuration: 0.22, outDuration: 0.2, direction: direction) + } + + override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + super.animateTransition(using: transitionContext) + + switch direction { + case .in: + to.view.bounds.origin = CGPoint(x: 0, y: -from.view.bounds.size.height) + UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: { [weak self] in + guard let self = self else { return } + self.to.view.bounds = self.from.view.bounds + }, completion: { _ in + transitionContext.completeTransition(true) + }) + case .out: + UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: { [weak self] in + guard let self = self else { return } + self.from.view.bounds.origin = CGPoint(x: 0, y: -self.from.view.bounds.size.height) + self.from.view.alpha = 0.0 + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + } +} + + +/// Dialog bounces in from top and is dismissed to top +final internal class BounceDownTransition: TransitionAnimator { + + init(direction: AnimationDirection) { + super.init(inDuration: 0.22, outDuration: 0.2, direction: direction) + } + + override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + super.animateTransition(using: transitionContext) + + switch direction { + case .in: + to.view.bounds.origin = CGPoint(x: 0, y: from.view.bounds.size.height) + UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: { [weak self] in + guard let self = self else { return } + self.to.view.bounds = self.from.view.bounds + }, completion: { _ in + transitionContext.completeTransition(true) + }) + case .out: + UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: { [weak self] in + guard let self = self else { return } + self.from.view.bounds.origin = CGPoint(x: 0, y: self.from.view.bounds.size.height) + self.from.view.alpha = 0.0 + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + } +} + +/// Dialog zooms in and is dismissed by zooming out +final internal class ZoomTransition: TransitionAnimator { + + init(direction: AnimationDirection) { + super.init(inDuration: 0.22, outDuration: 0.2, direction: direction) + } + + override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + super.animateTransition(using: transitionContext) + + switch direction { + case .in: + to.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) + UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: { [weak self] in + guard let self = self else { return } + self.to.view.transform = CGAffineTransform(scaleX: 1, y: 1) + }, completion: { _ in + transitionContext.completeTransition(true) + }) + case .out: + UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: { [weak self] in + guard let self = self else { return } + self.from.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) + self.from.view.alpha = 0.0 + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + } +} + +/// Dialog fades in and is dismissed by fading out +final internal class FadeTransition: TransitionAnimator { + + init(direction: AnimationDirection) { + super.init(inDuration: 0.22, outDuration: 0.2, direction: direction) + } + + override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + super.animateTransition(using: transitionContext) + + switch direction { + case .in: + to.view.alpha = 0 + UIView.animate(withDuration: 0.6, delay: 0.0, options: [.curveEaseOut], + animations: { [weak self] in + guard let self = self else { return } + self.to.view.alpha = 1 + }, completion: { _ in + transitionContext.completeTransition(true) + }) + case .out: + UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: { [weak self] in + guard let self = self else { return } + self.from.view.alpha = 0.0 + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + } +} + +/// Used for the always drop out animation with pan gesture dismissal +final internal class DismissInteractiveTransition: TransitionAnimator { + + init() { + super.init(inDuration: 0.22, outDuration: 0.32, direction: .out) + } + + override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + super.animateTransition(using: transitionContext) + UIView.animate(withDuration: outDuration, delay: 0.0, options: [.beginFromCurrentState], animations: { [weak self] in + guard let self = self else { return } + self.from.view.bounds.origin = CGPoint(x: 0, y: -self.from.view.bounds.size.height) + self.from.view.alpha = 0.0 + }, completion: { _ in + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimator.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimator.swift new file mode 100644 index 00000000..fd996fae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/TransitionAnimator.swift @@ -0,0 +1,68 @@ +// +// PopupDialogTransitionAnimator.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/// Base class for custom transition animations +internal class TransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning { + + var to: UIViewController! + var from: UIViewController! + let inDuration: TimeInterval + let outDuration: TimeInterval + let direction: AnimationDirection + + init(inDuration: TimeInterval, outDuration: TimeInterval, direction: AnimationDirection) { + self.inDuration = inDuration + self.outDuration = outDuration + self.direction = direction + super.init() + } + + internal func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return direction == .in ? inDuration : outDuration + } + + internal func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + switch direction { + case .in: + guard let to = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to), + let from = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) else { return } + + self.to = to + self.from = from + + let container = transitionContext.containerView + container.addSubview(to.view) + case .out: + guard let to = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to), + let from = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) else { return } + + self.to = to + self.from = from + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIImageView+Calculations.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIImageView+Calculations.swift new file mode 100755 index 00000000..2ad91213 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIImageView+Calculations.swift @@ -0,0 +1,44 @@ +// +// UIImageView+Calculations.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +internal extension UIImageView { + + /*! + Calculates the height of the the UIImageView has to + have so the image is displayed correctly + - returns: Height to set on the imageView + */ + func pv_heightForImageView() -> CGFloat { + guard let image = image, image.size.height > 0 else { + return 0.0 + } + let width = bounds.size.width + let ratio = image.size.height / image.size.width + return width * ratio + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIView+Animations.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIView+Animations.swift new file mode 100644 index 00000000..68adc290 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIView+Animations.swift @@ -0,0 +1,82 @@ +// +// UIView+Animations.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +/*! + The intended direction of the animation + - in: Animate in + - out: Animate out + */ +internal enum AnimationDirection { + case `in` // swiftlint:disable:this identifier_name + case out +} + +internal extension UIView { + + /// The key for the fade animation + var fadeKey: String { return "FadeAnimation" } + var shakeKey: String { return "ShakeAnimation" } + + func pv_fade(_ direction: AnimationDirection, _ value: Float, duration: CFTimeInterval = 0.08) { + layer.removeAnimation(forKey: fadeKey) + let animation = CABasicAnimation(keyPath: "opacity") + animation.duration = duration + animation.fromValue = layer.presentation()?.opacity + layer.opacity = value + animation.fillMode = CAMediaTimingFillMode.forwards + layer.add(animation, forKey: fadeKey) + } + + func pv_layoutIfNeededAnimated(duration: CFTimeInterval = 0.08) { + UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(), animations: { + self.layoutIfNeeded() + }, completion: nil) + } + + // As found at https://gist.github.com/mourad-brahim/cf0bfe9bec5f33a6ea66#file-uiview-animations-swift-L9 + // Slightly modified + func pv_shake() { + layer.removeAnimation(forKey: shakeKey) + let vals: [Double] = [-2, 2, -2, 2, 0] + + let translation = CAKeyframeAnimation(keyPath: "transform.translation.x") + translation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) + translation.values = vals + + let rotation = CAKeyframeAnimation(keyPath: "transform.rotation.z") + rotation.values = vals.map { (degrees: Double) in + let radians: Double = (Double.pi * degrees) / 180.0 + return radians + } + + let shakeGroup: CAAnimationGroup = CAAnimationGroup() + shakeGroup.animations = [translation, rotation] + shakeGroup.duration = 0.3 + self.layer.add(shakeGroup, forKey: shakeKey) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIViewController+Visibility.swift b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIViewController+Visibility.swift new file mode 100644 index 00000000..079b1ac2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/PopupDialog/Classes/UIViewController+Visibility.swift @@ -0,0 +1,52 @@ +// +// UIViewController+Visibility.swift +// +// Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +// Author - Martin Wildfeuer (http://www.mwfire.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +// http://stackoverflow.com/questions/2777438/how-to-tell-if-uiviewcontrollers-view-is-visible +internal extension UIViewController { + + var isTopAndVisible: Bool { + return isVisible && isTopViewController + } + + var isVisible: Bool { + if isViewLoaded { + return view.window != nil + } + return false + } + + var isTopViewController: Bool { + if self.navigationController != nil { + return self.navigationController?.visibleViewController === self + } else if self.tabBarController != nil { + return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil + } else { + return self.presentedViewController == nil && self.isVisible + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/PopupDialog/README.md b/one-and-half-nibble/MobileApp/Pods/PopupDialog/README.md new file mode 100644 index 00000000..c2302a47 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/PopupDialog/README.md @@ -0,0 +1,499 @@ + + +

 

+ +![Swift Version](https://img.shields.io/badge/Swift-5-orange.svg) +[![Version](https://img.shields.io/cocoapods/v/PopupDialog.svg?style=flat)](http://cocoapods.org/pods/PopupDialog) +[![License](https://img.shields.io/cocoapods/l/PopupDialog.svg?style=flat)](http://cocoapods.org/pods/PopupDialog) +[![Platform](https://img.shields.io/cocoapods/p/PopupDialog.svg?style=flat)](http://cocoapods.org/pods/PopupDialog) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Build Status Master](https://travis-ci.org/Orderella/PopupDialog.svg?branch=master)](https://travis-ci.org/Orderella/PopupDialog) +[![Build Status Development](https://travis-ci.org/Orderella/PopupDialog.svg?branch=development)](https://travis-ci.org/Orderella/PopupDialog) +[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com) + +

 

+ +# Introduction + +Popup Dialog is a simple, customizable popup dialog written in Swift. + + + + + + +## Features + +- [x] Easy to use API with hardly any boilerplate code +- [x] Convenient default view with image, title, message +- [x] Supports custom view controllers +- [x] Slick transition animations +- [x] Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc. +- [x] Can be dismissed via swipe and background tap +- [x] Objective-C compatible +- [x] Works on all screens and devices supporting iOS 10.0+ + +

 

+ +# Installation + +This version is Swift 5 compatible. For the Swift 4.2 version, please use [V1.0.0](https://github.com/Orderella/PopupDialog/releases/tag/1.0.0). + +## CocoaPods + +PopupDialog is available through [CocoaPods](http://cocoapods.org). Simply add the following to your Podfile: + +```ruby +use_frameworks! + +target '' +pod 'PopupDialog', '~> 1.1' +``` + +## Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of `0.17` is required. + +To install, simply add the following lines to your Cartfile: + +```ruby +github "Orderella/PopupDialog" ~> 1.1 +``` + +## Manually + +If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the [Classes](https://github.com/trungp/PopupDialog/tree/master/PopupDialog/Classes) +folder to your project. Moreover, you have to manually add the classes of [DynamicBlurView](https://github.com/KyoheiG3/DynamicBlurView/tree/master/DynamicBlurView) to your project. + + +

 

+ +# Example + +You can find this and more example projects in the repo. To run it, clone the repo, and run `pod install` from the Example directory first. + +```swift +import PopupDialog + +// Prepare the popup assets +let title = "THIS IS THE DIALOG TITLE" +let message = "This is the message section of the popup dialog default view" +let image = UIImage(named: "pexels-photo-103290") + +// Create the dialog +let popup = PopupDialog(title: title, message: message, image: image) + +// Create buttons +let buttonOne = CancelButton(title: "CANCEL") { + print("You canceled the car dialog.") +} + +// This button will not the dismiss the dialog +let buttonTwo = DefaultButton(title: "ADMIRE CAR", dismissOnTap: false) { + print("What a beauty!") +} + +let buttonThree = DefaultButton(title: "BUY CAR", height: 60) { + print("Ah, maybe next time :)") +} + +// Add buttons to dialog +// Alternatively, you can use popup.addButton(buttonOne) +// to add a single button +popup.addButtons([buttonOne, buttonTwo, buttonThree]) + +// Present dialog +self.present(popup, animated: true, completion: nil) +``` + +

 

+ +# Usage + +PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller. + +## Default Dialog + +```swift +public convenience init( + title: String?, + message: String?, + image: UIImage? = nil, + buttonAlignment: UILayoutConstraintAxis = .vertical, + transitionStyle: PopupDialogTransitionStyle = .bounceUp, + preferredWidth: CGFloat = 340, + tapGestureDismissal: Bool = true, + panGestureDismissal: Bool = true, + hideStatusBar: Bool = false, + completion: (() -> Void)? = nil) +``` + +The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and three). + +Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually. + +If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur. + +## Custom View Controller + +```swift +public init( + viewController: UIViewController, + buttonAlignment: UILayoutConstraintAxis = .vertical, + transitionStyle: PopupDialogTransitionStyle = .bounceUp, + preferredWidth: CGFloat = 340, + tapGestureDismissal: Bool = true, + panGestureDismissal: Bool = true, + hideStatusBar: Bool = false, + completion: (() -> Void)? = nil) +``` + +You can pass your own view controller to PopupDialog (see image two). It is accessible via the `viewController` property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues. + +Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via `dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?)`. + +## Button Alignment + +Buttons can be distributed either `.horizontal` or `.vertical`, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons. + +```swift +public enum UILayoutConstraintAxis : Int { + case horizontal + case vertical +} +``` + +## Transition Style + +You can set a transition animation style with `.bounceUp` being the default. The following transition styles are available + +```swift +public enum PopupDialogTransitionStyle: Int { + case bounceUp + case bounceDown + case zoomIn + case fadeIn +} +``` + +## Preferred Width + +PopupDialog will always try to have a max width of 340 . On iPhones with smaller screens, like iPhone 5 SE, width would be 320. +340 is also the standard width for iPads. By setting preferredWidth you can override the max width of 340 for iPads only. + +## Gesture Dismissal + +Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to `true`. You can prevent this behavior by setting either `tapGestureDismissal` or `panGestureDismissal` to `false` in the initializer. + +## Hide Status Bar + +PopupDialog can hide the status bar whenever it is displayed. Defaults to `false`. Make sure to add `UIViewControllerBasedStatusBarAppearance` to `Info.plist` and set it to `YES`. + +## Completion +This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal. + +

 

+ +# Default Dialog Properties + +If you are using the default dialog, you can change selected properties at runtime: + +```swift +// Create the dialog +let popup = PopupDialog(title: title, message: message, image: image) + +// Present dialog +self.present(popup, animated: true, completion: nil) + +// Get the default view controller and cast it +// Unfortunately, casting is necessary to support Objective-C +let vc = popup.viewController as! PopupDialogDefaultViewController + +// Set dialog properties +vc.image = UIImage(...) +vc.titleText = "..." +vc.messageText = "..." +vc.buttonAlignment = .horizontal +vc.transitionStyle = .bounceUp +``` + +

 

+ +# Styling PopupDialog + +Appearance is the preferred way of customizing the style of PopupDialog. +The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers". + +This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style. + +## Dialog Default View Appearance Settings + +If you are using the default popup view, the following appearance settings are available: + +```swift +let dialogAppearance = PopupDialogDefaultView.appearance() + +dialogAppearance.backgroundColor = .white +dialogAppearance.titleFont = .boldSystemFont(ofSize: 14) +dialogAppearance.titleColor = UIColor(white: 0.4, alpha: 1) +dialogAppearance.titleTextAlignment = .center +dialogAppearance.messageFont = .systemFont(ofSize: 14) +dialogAppearance.messageColor = UIColor(white: 0.6, alpha: 1) +dialogAppearance.messageTextAlignment = .center +``` + +## Dialog Container Appearance Settings + +The container view contains the PopupDialogDefaultView or your custom view controller. the following appearance settings are available: + +```swift +let containerAppearance = PopupDialogContainerView.appearance() + +containerAppearance.backgroundColor = UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00) +containerAppearance.cornerRadius = 2 +containerAppearance.shadowEnabled = true +containerAppearance.shadowColor = .black +containerAppearance.shadowOpacity = 0.6 +containerAppearance.shadowRadius = 20 +containerAppearance.shadowOffset = CGSize(width: 0, height: 8) +containerAppearance.shadowPath = CGPath(...) +``` + +## Overlay View Appearance Settings + +This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;) + +```swift +let overlayAppearance = PopupDialogOverlayView.appearance() + +overlayAppearance.color = .black +overlayAppearance.blurRadius = 20 +overlayAppearance.blurEnabled = true +overlayAppearance.liveBlurEnabled = false +overlayAppearance.opacity = 0.7 +``` + +#### Note +Setting `liveBlurEnabled` to true, that is enabling realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default. Choose wisely whether you need this feature or not ;) + +## Button Appearance Settings + +The standard button classes available are `DefaultButton`, `CancelButton` and `DestructiveButton`. All buttons feature the same appearance settings and can be styled seperately. + +```swift +var buttonAppearance = DefaultButton.appearance() + +// Default button +buttonAppearance.titleFont = .systemFont(ofSize: 14) +buttonAppearance.titleColor = UIColor(red: 0.25, green: 0.53, blue: 0.91, alpha: 1) +buttonAppearance.buttonColor = .clear +buttonAppearance.separatorColor = UIColor(white: 0.9, alpha: 1) + +// Below, only the differences are highlighted + +// Cancel button +CancelButton.appearance().titleColor = .lightGray + +// Destructive button +DestructiveButton.appearance().titleColor = .red +``` + +Moreover, you can create a custom button by subclassing `PopupDialogButton`. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble. + +```swift +public final class SolidBlueButton: PopupDialogButton { + + override public func setupView() { + defaultFont = .boldSystemFont(ofSize: 16) + defaultTitleColor = .white + defaultButtonColor = .blue + defaultSeparatorColor = .clear + super.setupView() + } +} + +``` + +These buttons can be customized with the appearance settings given above as well. + +

 

+ +## Dark mode example + +The following is an example of a *Dark Mode* theme. You can find this in the Example project `AppDelegate`, just uncomment it to apply the custom appearance. + +```swift +// Customize dialog appearance +let pv = PopupDialogDefaultView.appearance() +pv.titleFont = UIFont(name: "HelveticaNeue-Light", size: 16)! +pv.titleColor = .white +pv.messageFont = UIFont(name: "HelveticaNeue", size: 14)! +pv.messageColor = UIColor(white: 0.8, alpha: 1) + +// Customize the container view appearance +let pcv = PopupDialogContainerView.appearance() +pcv.backgroundColor = UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00) +pcv.cornerRadius = 2 +pcv.shadowEnabled = true +pcv.shadowColor = .black + +// Customize overlay appearance +let ov = PopupDialogOverlayView.appearance() +ov.blurEnabled = true +ov.blurRadius = 30 +ov.liveBlurEnabled = true +ov.opacity = 0.7 +ov.color = .black + +// Customize default button appearance +let db = DefaultButton.appearance() +db.titleFont = UIFont(name: "HelveticaNeue-Medium", size: 14)! +db.titleColor = .white +db.buttonColor = UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00) +db.separatorColor = UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00) + +// Customize cancel button appearance +let cb = CancelButton.appearance() +cb.titleFont = UIFont(name: "HelveticaNeue-Medium", size: 14)! +cb.titleColor = UIColor(white: 0.6, alpha: 1) +cb.buttonColor = UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00) +cb.separatorColor = UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00) + +``` + + + + +I can see that there is room for more customization options. I might add more of them over time. + +

 

+ +# Screen sizes and rotation + +Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points on iPhones. For iPads, you can set `preferredWidth` when initializing a new PopupDialog. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen. + +

 

+ +# Working with text fields + +If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting `keyboardShiftsView` to false on a PopupDialog. + +# Testing + +PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically: + +```swift +public func tapButtonWithIndex(_ index: Int) +``` + +Other than that, PopupDialog unit tests are included in the root folder. + +

 

+ +# Objective-C + +PopupDialog can be used in Objective-C projects as well. +Here is a basic example: + +```objective-c +PopupDialog *popup = [[PopupDialog alloc] initWithTitle: @"Title" + message: @"This is a message" + image: nil + buttonAlignment: UILayoutConstraintAxisVertical + transitionStyle: PopupDialogTransitionStyleBounceUp + preferredWidth: 380 + tapGestureDismissal: NO + panGestureDismissal: NO + hideStatusBar: NO + completion: nil]; + +DestructiveButton *delete = [[DestructiveButton alloc] initWithTitle: @"Delete" + height: 45 + dismissOnTap: YES + action: nil]; + +CancelButton *cancel = [[CancelButton alloc] initWithTitle: @"Cancel" + height: 45 + dismissOnTap: YES + action: nil]; + +DefaultButton *ok = [[DefaultButton alloc] initWithTitle: @"OK" + height: 45 + dismissOnTap: YES + action: nil]; + +[dialog addButtons:@[delete, cancel, ok]]; + +[self presentViewController:popup animated:YES completion:nil]; +``` + + +

 

+ + +# Bonus + +## Shake animation + +If you happen to use PopupDialog to validate text input, for example, you can call the handy `shake()` method on PopupDialog. + +

 

+ +# Requirements + +Minimum requirement is iOS 10.0. This dialog was written with Swift 5, for support of older versions please head over to releases. + +

 

+ +# Changelog +* **1.1.1** Updates dependencies to Swift 5 +* **1.1.0** Swift 5 support +* **1.0.0** Pinned Swift version to 4.2
Dropped iOS 9 support as of moving to ios-snapshot-test-case +* **0.9.2** Fixes crash when presenting dialog while app is inactive +* **0.9.1** Fixes Carthage support +* **0.9.0** Swift 4.2 support +* **0.8.1** Added shadow appearance properties +* **0.8.0** Separated tap and pan gesture dismissal +* **0.7.1** Fixes Objective-C compatability
Improved Carthage handling +* **0.7.0** Removed FXBlurView while switching to DynamicBlurView +* **0.6.2** Added preferredWidth option for iPads +* **0.6.1** Added shake animation
Introduced hideStatusBar option +* **0.6.0** Swift 4 support
Dropped iOS8 compatibility +* **0.5.4** Fixed bug where blur view would reveal hidden layer
Improved view controller lifecycle handling
Scroll views can now be used with gesture dismissal +* **0.5.3** Fixed memory leak with custom view controllers
Added UI automation & snapshot tests +* **0.5.2** Fixed image scaling for default view +* **0.5.1** Introduced custom button height parameter
Reintroduced iOS8 compatibility +* **0.5.0** Swift 3 compatibility / removed iOS8 +* **0.4.0** iOS 8 compatibility +* **0.3.3** Fixes buttons being added multiple times +* **0.3.2** Dialog repositioning when interacting with keyboard
Non dismissable buttons option
Additional completion handler when dialog is dismissed +* **0.3.1** Fixed Carthage issues +* **0.3.0** Objective-C compatibility +* **0.2.2** Turned off liveBlur by default to increase performance +* **0.2.1** Dismiss via background tap or swipe down transition +* **0.2.0** You can now pass custom view controllers to the dialog. This introduces breaking changes. +* **0.1.6** Defer button action until animation completes +* **0.1.5** Exposed dialog properties
(titleText, messageText, image, buttonAlignment, transitionStyle) +* **0.1.4** Pick transition animation style +* **0.1.3** Big screen support
Exposed basic shadow appearance +* **0.1.2** Exposed blur and overlay appearance +* **0.1.1** Added themeing example +* **0.1.0** Intitial version + +

 

+ +# Author + +Martin Wildfeuer, mwfire@mwfire.de +for Orderella Ltd., [orderella.co.uk](http://orderella.co.uk)
+You might also want to follow us on Twitter, [@theMWFire](https://twitter.com/theMWFire) | [@Orderella](https://twitter.com/orderella) + +# Thank you +Thanks to everyone who uses, enhances and improves this library, especially the contributors. +Moreover, thanks to KyoheiG3 for porting FXBlurView to [DynamicBlurView](https://github.com/KyoheiG3/DynamicBlurView). + +

 

+ +# License + +PopupDialog is available under the MIT license. See the LICENSE file for more info. diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/LICENSE b/one-and-half-nibble/MobileApp/Pods/SDWebImage/LICENSE new file mode 100644 index 00000000..2f5785d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/README.md b/one-and-half-nibble/MobileApp/Pods/SDWebImage/README.md new file mode 100644 index 00000000..06e28e3a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/README.md @@ -0,0 +1,352 @@ +

+ +

+ + +[![Build Status](http://img.shields.io/travis/SDWebImage/SDWebImage/master.svg?style=flat)](https://travis-ci.org/SDWebImage/SDWebImage) +[![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) +[![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) +[![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg)](https://github.com/SDWebImage/SDWebImage) +[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager/) +[![Mac Catalyst compatible](https://img.shields.io/badge/Catalyst-compatible-brightgreen.svg)](https://developer.apple.com/documentation/xcode/creating_a_mac_version_of_your_ipad_app/) +[![codecov](https://codecov.io/gh/SDWebImage/SDWebImage/branch/master/graph/badge.svg)](https://codecov.io/gh/SDWebImage/SDWebImage) + +This library provides an async image downloader with cache support. For convenience, we added categories for UI elements like `UIImageView`, `UIButton`, `MKAnnotationView`. + +## Features + +- [x] Categories for `UIImageView`, `UIButton`, `MKAnnotationView` adding web image and cache management +- [x] An asynchronous image downloader +- [x] An asynchronous memory + disk image caching with automatic cache expiration handling +- [x] A background image decompression to avoid frame rate drop +- [x] [Progressive image loading](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#progressive-animation) (including animated image, like GIF showing in Web browser) +- [x] [Thumbnail image decoding](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#thumbnail-decoding-550) to save CPU && Memory for large images +- [x] [Extendable image coder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420) to support massive image format, like WebP +- [x] [Full-stack solution for animated images](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) which keep a balance between CPU && Memory +- [x] [Customizable and composable transformations](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#transformer-50) can be applied to the images right after download +- [x] [Customizable and multiple caches system](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-cache-50) +- [x] [Customizable and multiple loaders system](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-loader-50) to expand the capabilities, like [Photos Library](https://github.com/SDWebImage/SDWebImagePhotosPlugin) +- [x] [Image loading indicators](https://github.com/SDWebImage/SDWebImage/wiki/How-to-use#use-view-indicator-50) +- [x] [Image loading transition animation](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#image-transition-430) +- [x] A guarantee that the same URL won't be downloaded several times +- [x] A guarantee that bogus URLs won't be retried again and again +- [x] A guarantee that main thread will never be blocked +- [x] Modern Objective-C and better Swift support +- [x] Performances! + +## Supported Image Formats + +- Image formats supported by Apple system (JPEG, PNG, TIFF, BMP, ...), including [GIF](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#gif-coder)/[APNG](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#apng-coder) animated image +- HEIC format from iOS 11/macOS 10.13, including animated HEIC from iOS 13/macOS 10.15 via [SDWebImageHEICCoder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#heic-coder). For lower firmware, use coder plugin [SDWebImageHEIFCoder](https://github.com/SDWebImage/SDWebImageHEIFCoder) +- WebP format from iOS 14/macOS 11.0 via [SDWebImageAWebPCoder](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#awebp-coder). For lower firmware, use coder plugin [SDWebImageWebPCoder](https://github.com/SDWebImage/SDWebImageWebPCoder) +- Support extendable coder plugins for new image formats like BPG, AVIF. And vector format like PDF, SVG. See all the list in [Image coder plugin List](https://github.com/SDWebImage/SDWebImage/wiki/Coder-Plugin-List) + +## Additional modules and Ecosystem + +In order to keep SDWebImage focused and limited to the core features, but also allow extensibility and custom behaviors, during the 5.0 refactoring we focused on modularizing the library. +As such, we have moved/built new modules to [SDWebImage org](https://github.com/SDWebImage). + +#### SwiftUI +[SwiftUI](https://developer.apple.com/xcode/swiftui/) is an innovative UI framework written in Swift to build user interfaces across all Apple platforms. + +We support SwiftUI by building a brand new framework called [SDWebImageSwiftUI](https://github.com/SDWebImage/SDWebImageSwiftUI), which is built on top of SDWebImage core functions (caching, loading and animation). + +The new framework introduce two View structs `WebImage` and `AnimatedImage` for SwiftUI world, `ImageIndicator` modifier for any View, `ImageManager` observable object for data source. Supports iOS 13+/macOS 10.15+/tvOS 13+/watchOS 6+ and Swift 5.1. Have a nice try and provide feedback! + +#### Coders for additional image formats +- [SDWebImageWebPCoder](https://github.com/SDWebImage/SDWebImageWebPCoder) - coder for WebP format. iOS 8+/macOS 10.10+. Based on [libwebp](https://chromium.googlesource.com/webm/libwebp) +- [SDWebImageHEIFCoder](https://github.com/SDWebImage/SDWebImageHEIFCoder) - coder for HEIF format, iOS 8+/macOS 10.10+ support. Based on [libheif](https://github.com/strukturag/libheif) +- [SDWebImageBPGCoder](https://github.com/SDWebImage/SDWebImageBPGCoder) - coder for BPG format. Based on [libbpg](https://github.com/mirrorer/libbpg) +- [SDWebImageFLIFCoder](https://github.com/SDWebImage/SDWebImageFLIFCoder) - coder for FLIF format. Based on [libflif](https://github.com/FLIF-hub/FLIF) +- [SDWebImageAVIFCoder](https://github.com/SDWebImage/SDWebImageAVIFCoder) - coder for AVIF (AV1-based) format. Based on [libavif](https://github.com/AOMediaCodec/libavif) +- [SDWebImagePDFCoder](https://github.com/SDWebImage/SDWebImagePDFCoder) - coder for PDF vector format. Using built-in frameworks +- [SDWebImageSVGCoder](https://github.com/SDWebImage/SDWebImageSVGCoder) - coder for SVG vector format. Using built-in frameworks +- [SDWebImageLottieCoder](https://github.com/SDWebImage/SDWebImageLottieCoder) - coder for Lottie animation format. Based on [rlottie](https://github.com/Samsung/rlottie) +- and more from community! + +#### Custom Caches +- [SDWebImageYYPlugin](https://github.com/SDWebImage/SDWebImageYYPlugin) - plugin to support caching images with [YYCache](https://github.com/ibireme/YYCache) +- [SDWebImagePINPlugin](https://github.com/SDWebImage/SDWebImagePINPlugin) - plugin to support caching images with [PINCache](https://github.com/pinterest/PINCache) + +#### Custom Loaders +- [SDWebImagePhotosPlugin](https://github.com/SDWebImage/SDWebImagePhotosPlugin) - plugin to support loading images from Photos (using `Photos.framework`) +- [SDWebImageLinkPlugin](https://github.com/SDWebImage/SDWebImageLinkPlugin) - plugin to support loading images from rich link url, as well as `LPLinkView` (using `LinkPresentation.framework`) + +#### Integration with 3rd party libraries +- [SDWebImageLottiePlugin](https://github.com/SDWebImage/SDWebImageLottiePlugin) - plugin to support [Lottie-iOS](https://github.com/airbnb/lottie-ios), vector animation rending with remote JSON files +- [SDWebImageSVGKitPlugin](https://github.com/SDWebImage/SDWebImageSVGKitPlugin) - plugin to support [SVGKit](https://github.com/SVGKit/SVGKit), SVG rendering using Core Animation, iOS 8+/macOS 10.10+ support +- [SDWebImageFLPlugin](https://github.com/SDWebImage/SDWebImageFLPlugin) - plugin to support [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) as the engine for animated GIFs +- [SDWebImageYYPlugin](https://github.com/SDWebImage/SDWebImageYYPlugin) - plugin to integrate [YYImage](https://github.com/ibireme/YYImage) & [YYCache](https://github.com/ibireme/YYCache) for image rendering & caching + +#### Community driven popular libraries +- [FirebaseUI](https://github.com/firebase/FirebaseUI-iOS) - Firebase Storage binding for query images, based on SDWebImage loader system +- [react-native-fast-image](https://github.com/DylanVann/react-native-fast-image) - React Native fast image component, based on SDWebImage Animated Image solution +- [flutter_image_compress](https://github.com/OpenFlutter/flutter_image_compress) - Flutter compresses image plugin, based on SDWebImage WebP coder plugin + +#### Make our lives easier +- [libwebp-Xcode](https://github.com/SDWebImage/libwebp-Xcode) - A wrapper for [libwebp](https://chromium.googlesource.com/webm/libwebp) + an Xcode project. +- [libheif-Xcode](https://github.com/SDWebImage/libheif-Xcode) - A wrapper for [libheif](https://github.com/strukturag/libheif) + an Xcode project. +- [libavif-Xcode](https://github.com/SDWebImage/libavif-Xcode) - A wrapper for [libavif](https://github.com/AOMediaCodec/libavif) + an Xcode project. +- and more third-party C/C++ image codec libraries with CocoaPods/Carthage/SwiftPM support. + +You can use those directly, or create similar components of your own, by using the customizable architecture of SDWebImage. + +## Requirements + +- iOS 9.0 or later +- tvOS 9.0 or later +- watchOS 2.0 or later +- macOS 10.11 or later (10.15 for Catalyst) +- Xcode 11.0 or later + +#### Backwards compatibility + +- For iOS 8, macOS 10.10 or Xcode < 11, use [any 5.x version up to 5.9.5](https://github.com/SDWebImage/SDWebImage/releases/tag/5.9.5) +- For iOS 7, macOS 10.9 or Xcode < 8, use [any 4.x version up to 4.4.6](https://github.com/SDWebImage/SDWebImage/releases/tag/4.4.6) +- For macOS 10.8, use [any 4.x version up to 4.3.0](https://github.com/SDWebImage/SDWebImage/releases/tag/4.3.0) +- For iOS 5 and 6, use [any 3.x version up to 3.7.6](https://github.com/SDWebImage/SDWebImage/releases/tag/3.7.6) +- For iOS < 5.0, please use the last [2.0 version](https://github.com/SDWebImage/SDWebImage/tree/2.0-compat). + +## Getting Started + +- Read this Readme doc +- Read the [How to use section](https://github.com/SDWebImage/SDWebImage#how-to-use) +- Read the [Latest Documentation](https://sdwebimage.github.io/) and [CocoaDocs for old version](http://cocoadocs.org/docsets/SDWebImage/) +- Try the example by downloading the project from Github or even easier using CocoaPods try `pod try SDWebImage` +- Read the [Installation Guide](https://github.com/SDWebImage/SDWebImage/wiki/Installation-Guide) +- Read the [SDWebImage 5.0 Migration Guide](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/SDWebImage-5.0-Migration-guide.md) to get an idea of the changes from 4.x to 5.x +- Read the [SDWebImage 4.0 Migration Guide](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/SDWebImage-4.0-Migration-guide.md) to get an idea of the changes from 3.x to 4.x +- Read the [Common Problems](https://github.com/SDWebImage/SDWebImage/wiki/Common-Problems) to find the solution for common problems +- Go to the [Wiki Page](https://github.com/SDWebImage/SDWebImage/wiki) for more information such as [Advanced Usage](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage) + +## Who Uses It +- Find out [who uses SDWebImage](https://github.com/SDWebImage/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list. + +## Communication + +- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage). (Tag 'sdwebimage') +- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage). +- If you **found a bug**, open an issue. +- If you **have a feature request**, open an issue. +- If you **need IRC channel**, use [Gitter](https://gitter.im/SDWebImage/community). + +## Contribution + +- If you **want to contribute**, read the [Contributing Guide](https://github.com/SDWebImage/SDWebImage/blob/master/.github/CONTRIBUTING.md) +- For **development contribution guide**, read the [How-To-Contribute](https://github.com/SDWebImage/SDWebImage/wiki/How-to-Contribute) +- For **understanding code architecture**, read the [Code Architecture Analysis](https://github.com/SDWebImage/SDWebImage/wiki/5.6-Code-Architecture-Analysis) + +## How To Use + +* Objective-C + +```objective-c +#import +... +[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; +``` + +* Swift + +```swift +import SDWebImage + +imageView.sd_setImage(with: URL(string: "http://www.domain.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png")) +``` + +- For details about how to use the library and clear examples, see [The detailed How to use](https://github.com/SDWebImage/SDWebImage/blob/master/Docs/HowToUse.md) + +## Animated Images (GIF) support + +In 5.0, we introduced a brand new mechanism for supporting animated images. This includes animated image loading, rendering, decoding, and also supports customizations (for advanced users). + +This animated image solution is available for `iOS`/`tvOS`/`macOS`. The `SDAnimatedImage` is subclass of `UIImage/NSImage`, and `SDAnimatedImageView` is subclass of `UIImageView/NSImageView`, to make them compatible with the common frameworks APIs. + +The `SDAnimatedImageView` supports the familiar image loading category methods, works like drop-in replacement for `UIImageView/NSImageView`. + +Don't have `UIView` (like `WatchKit` or `CALayer`)? you can still use `SDAnimatedPlayer` the player engine for advanced playback and rendering. + +See [Animated Image](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) for more detailed information. + +* Objective-C + +```objective-c +SDAnimatedImageView *imageView = [SDAnimatedImageView new]; +SDAnimatedImage *animatedImage = [SDAnimatedImage imageNamed:@"image.gif"]; +imageView.image = animatedImage; +``` + +* Swift + +```swift +let imageView = SDAnimatedImageView() +let animatedImage = SDAnimatedImage(named: "image.gif") +imageView.image = animatedImage +``` + +#### FLAnimatedImage integration has its own dedicated repo +In order to clean up things and make our core project do less things, we decided that the `FLAnimatedImage` integration does not belong here. From 5.0, this will still be available, but under a dedicated repo [SDWebImageFLPlugin](https://github.com/SDWebImage/SDWebImageFLPlugin). + +## Installation + +There are four ways to use SDWebImage in your project: +- using CocoaPods +- using Carthage +- using Swift Package Manager +- manual install (build frameworks or embed Xcode Project) + +### Installation with CocoaPods + +[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the [Get Started](http://cocoapods.org/#get_started) section for more details. + +#### Podfile +``` +platform :ios, '8.0' +pod 'SDWebImage', '~> 5.0' +``` + +##### Swift and static framework + +Swift project previously had to use `use_frameworks!` to make all Pods into dynamic framework to let CocoaPods work. + +However, starting with `CocoaPods 1.5.0+` (with `Xcode 9+`), which supports to build both Objective-C && Swift code into static framework. You can use modular headers to use SDWebImage as static framework, without the need of `use_frameworks!`: + +``` +platform :ios, '8.0' +# Uncomment the next line when you want all Pods as static framework +# use_modular_headers! +pod 'SDWebImage', :modular_headers => true +``` + +See more on [CocoaPods 1.5.0 — Swift Static Libraries](http://blog.cocoapods.org/CocoaPods-1.5.0/) + +If not, you still need to add `use_frameworks!` to use SDWebImage as dynamic framework: + +``` +platform :ios, '8.0' +use_frameworks! +pod 'SDWebImage' +``` + +#### Subspecs + +There are 2 subspecs available now: `Core` and `MapKit` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `MapKit`, you need to specify it). + +Podfile example: + +``` +pod 'SDWebImage/MapKit' +``` + +### Installation with Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods. + +To install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage) + +Carthage users can point to this repository and use whichever generated framework they'd like: SDWebImage, SDWebImageMapKit or both. + +Make the following entry in your Cartfile: `github "SDWebImage/SDWebImage"` +Then run `carthage update` +If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained [over at Carthage](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). + +> NOTE: At this time, Carthage does not provide a way to build only specific repository subcomponents (or equivalent of CocoaPods's subspecs). All components and their dependencies will be built with the above command. However, you don't need to copy frameworks you aren't using into your project. For instance, if you aren't using `SDWebImageMapKit`, feel free to delete that framework from the Carthage Build directory after `carthage update` completes. + +### Installation with Swift Package Manager (Xcode 11+) + +[Swift Package Manager](https://swift.org/package-manager/) (SwiftPM) is a tool for managing the distribution of Swift code as well as C-family dependency. From Xcode 11, SwiftPM got natively integrated with Xcode. + +SDWebImage support SwiftPM from version 5.1.0. To use SwiftPM, you should use Xcode 11 to open your project. Click `File` -> `Swift Packages` -> `Add Package Dependency`, enter [SDWebImage repo's URL](https://github.com/SDWebImage/SDWebImage.git). Or you can login Xcode with your GitHub account and just type `SDWebImage` to search. + +After select the package, you can choose the dependency type (tagged version, branch or commit). Then Xcode will setup all the stuff for you. + +If you're a framework author and use SDWebImage as a dependency, update your `Package.swift` file: + +```swift +let package = Package( + // 5.1.0 ..< 6.0.0 + dependencies: [ + .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.1.0") + ], + // ... +) +``` + +### Manual Installation Guide + +See more on [Manual install Guide](https://github.com/SDWebImage/SDWebImage/wiki/Installation-Guide#manual-installation-guide) + +### Import headers in your source files + +In the source files where you need to use the library, import the umbrella header file: + +```objective-c +#import +``` + +It's also recommend to use the module import syntax, available for CocoaPods(enable `modular_headers`)/Carthage/SwiftPM. + +```objecitivec +@import SDWebImage; +``` + +### Build Project + +At this point your workspace should build without error. If you are having problem, post to the Issue and the +community can help you solve it. + +## Data Collection Practices +As required by the [App privacy details on the App Store](https://developer.apple.com/app-store/app-privacy-details/), here's SDWebImage's list of [Data Collection Practices](https://sdwebimage.github.io/DataCollection/index.html). + +## Author +- [Olivier Poitrey](https://github.com/rs) + +## Collaborators +- [Konstantinos K.](https://github.com/mythodeia) +- [Bogdan Poplauschi](https://github.com/bpoplauschi) +- [Chester Liu](https://github.com/skyline75489) +- [DreamPiggy](https://github.com/dreampiggy) +- [Wu Zhong](https://github.com/zhongwuzw) + +## Credits + +Thank you to all the people who have already contributed to SDWebImage. + +[![Contributors](https://opencollective.com/SDWebImage/contributors.svg?width=890)](https://github.com/SDWebImage/SDWebImage/graphs/contributors) + +## Licenses + +All source code is licensed under the [MIT License](https://github.com/SDWebImage/SDWebImage/blob/master/LICENSE). + +## Architecture + +To learn about SDWebImage's architecture design for contribution, read [The Core of SDWebImage v5.6 Architecture](https://github.com/SDWebImage/SDWebImage/wiki/5.6-Code-Architecture-Analysis). Thanks @looseyi for the post and translation. + +#### High Level Diagram +

+ +

+ +#### Overall Class Diagram +

+ +

+ +#### Top Level API Diagram +

+ +

+ +#### Main Sequence Diagram +

+ +

+ +#### More detailed diagrams +- [Manager API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageManagerClassDiagram.png) +- [Coders API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageCodersClassDiagram.png) +- [Loader API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageLoaderClassDiagram.png) +- [Cache API Diagram](https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/Docs/Diagrams/SDWebImageCacheClassDiagram.png) + diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.h new file mode 100644 index 00000000..5b8035b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.h @@ -0,0 +1,340 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with NSButton. + */ +@interface NSButton (WebCache) + +#pragma mark - Image + +/** + * Get the current image URL. + */ +@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentImageURL; + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +#pragma mark - Alternate Image + +/** + * Get the current alternateImage URL. + */ +@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentAlternateImageURL; + +/** + * Set the button `alternateImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @see sd_setAlternateImageWithURL:placeholderImage:options: + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the button `alternateImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `alternateImage` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while alternateImage is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `alternateImage` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while alternateImage is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +#pragma mark - Cancel + +/** + * Cancel the current image download + */ +- (void)sd_cancelCurrentImageLoad; + +/** + * Cancel the current alternateImage download + */ +- (void)sd_cancelCurrentAlternateImageLoad; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.m new file mode 100644 index 00000000..300e5a36 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSButton+WebCache.m @@ -0,0 +1,172 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSButton+WebCache.h" + +#if SD_MAC + +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" +#import "UIView+WebCache.h" +#import "SDInternalMacros.h" + +static NSString * const SDAlternateImageOperationKey = @"NSButtonAlternateImageOperation"; + +@implementation NSButton (WebCache) + +#pragma mark - Image + +- (void)sd_setImageWithURL:(nullable NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + self.sd_currentImageURL = url; + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:context + setImageBlock:nil + progress:progressBlock + completed:^(NSImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +#pragma mark - Alternate Image + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url { + [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + self.sd_currentAlternateImageURL = url; + + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextSetImageOperationKey] = SDAlternateImageOperationKey; + @weakify(self); + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:mutableContext + setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + @strongify(self); + self.alternateImage = image; + } + progress:progressBlock + completed:^(NSImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +#pragma mark - Cancel + +- (void)sd_cancelCurrentImageLoad { + [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])]; +} + +- (void)sd_cancelCurrentAlternateImageLoad { + [self sd_cancelImageLoadOperationWithKey:SDAlternateImageOperationKey]; +} + +#pragma mar - Private + +- (NSURL *)sd_currentImageURL { + return objc_getAssociatedObject(self, @selector(sd_currentImageURL)); +} + +- (void)setSd_currentImageURL:(NSURL *)sd_currentImageURL { + objc_setAssociatedObject(self, @selector(sd_currentImageURL), sd_currentImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSURL *)sd_currentAlternateImageURL { + return objc_getAssociatedObject(self, @selector(sd_currentAlternateImageURL)); +} + +- (void)setSd_currentAlternateImageURL:(NSURL *)sd_currentAlternateImageURL { + objc_setAssociatedObject(self, @selector(sd_currentAlternateImageURL), sd_currentAlternateImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.h new file mode 100644 index 00000000..fb5ba60a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.h @@ -0,0 +1,61 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Fabrice Aneche + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/** + You can use switch case like normal enum. It's also recommended to add a default case. You should not assume anything about the raw value. + For custom coder plugin, it can also extern the enum for supported format. See `SDImageCoder` for more detailed information. + */ +typedef NSInteger SDImageFormat NS_TYPED_EXTENSIBLE_ENUM; +static const SDImageFormat SDImageFormatUndefined = -1; +static const SDImageFormat SDImageFormatJPEG = 0; +static const SDImageFormat SDImageFormatPNG = 1; +static const SDImageFormat SDImageFormatGIF = 2; +static const SDImageFormat SDImageFormatTIFF = 3; +static const SDImageFormat SDImageFormatWebP = 4; +static const SDImageFormat SDImageFormatHEIC = 5; +static const SDImageFormat SDImageFormatHEIF = 6; +static const SDImageFormat SDImageFormatPDF = 7; +static const SDImageFormat SDImageFormatSVG = 8; + +/** + NSData category about the image content type and UTI. + */ +@interface NSData (ImageContentType) + +/** + * Return image format + * + * @param data the input image data + * + * @return the image format as `SDImageFormat` (enum) + */ ++ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data; + +/** + * Convert SDImageFormat to UTType + * + * @param format Format as SDImageFormat + * @return The UTType as CFStringRef + * @note For unknown format, `kSDUTTypeImage` abstract type will return + */ ++ (nonnull CFStringRef)sd_UTTypeFromImageFormat:(SDImageFormat)format CF_RETURNS_NOT_RETAINED NS_SWIFT_NAME(sd_UTType(from:)); + +/** + * Convert UTType to SDImageFormat + * + * @param uttype The UTType as CFStringRef + * @return The Format as SDImageFormat + * @note For unknown type, `SDImageFormatUndefined` will return + */ ++ (SDImageFormat)sd_imageFormatFromUTType:(nonnull CFStringRef)uttype; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.m new file mode 100644 index 00000000..070dfdfc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSData+ImageContentType.m @@ -0,0 +1,153 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Fabrice Aneche + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSData+ImageContentType.h" +#if SD_MAC +#import +#else +#import +#endif +#import "SDImageIOAnimatedCoderInternal.h" + +#define kSVGTagEnd @"" + +@implementation NSData (ImageContentType) + ++ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data { + if (!data) { + return SDImageFormatUndefined; + } + + // File signatures table: http://www.garykessler.net/library/file_sigs.html + uint8_t c; + [data getBytes:&c length:1]; + switch (c) { + case 0xFF: + return SDImageFormatJPEG; + case 0x89: + return SDImageFormatPNG; + case 0x47: + return SDImageFormatGIF; + case 0x49: + case 0x4D: + return SDImageFormatTIFF; + case 0x52: { + if (data.length >= 12) { + //RIFF....WEBP + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; + if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { + return SDImageFormatWebP; + } + } + break; + } + case 0x00: { + if (data.length >= 12) { + //....ftypheic ....ftypheix ....ftyphevc ....ftyphevx + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; + if ([testString isEqualToString:@"ftypheic"] + || [testString isEqualToString:@"ftypheix"] + || [testString isEqualToString:@"ftyphevc"] + || [testString isEqualToString:@"ftyphevx"]) { + return SDImageFormatHEIC; + } + //....ftypmif1 ....ftypmsf1 + if ([testString isEqualToString:@"ftypmif1"] || [testString isEqualToString:@"ftypmsf1"]) { + return SDImageFormatHEIF; + } + } + break; + } + case 0x25: { + if (data.length >= 4) { + //%PDF + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(1, 3)] encoding:NSASCIIStringEncoding]; + if ([testString isEqualToString:@"PDF"]) { + return SDImageFormatPDF; + } + } + } + case 0x3C: { + // Check end with SVG tag + if ([data rangeOfData:[kSVGTagEnd dataUsingEncoding:NSUTF8StringEncoding] options:NSDataSearchBackwards range: NSMakeRange(data.length - MIN(100, data.length), MIN(100, data.length))].location != NSNotFound) { + return SDImageFormatSVG; + } + } + } + return SDImageFormatUndefined; +} + ++ (nonnull CFStringRef)sd_UTTypeFromImageFormat:(SDImageFormat)format { + CFStringRef UTType; + switch (format) { + case SDImageFormatJPEG: + UTType = kSDUTTypeJPEG; + break; + case SDImageFormatPNG: + UTType = kSDUTTypePNG; + break; + case SDImageFormatGIF: + UTType = kSDUTTypeGIF; + break; + case SDImageFormatTIFF: + UTType = kSDUTTypeTIFF; + break; + case SDImageFormatWebP: + UTType = kSDUTTypeWebP; + break; + case SDImageFormatHEIC: + UTType = kSDUTTypeHEIC; + break; + case SDImageFormatHEIF: + UTType = kSDUTTypeHEIF; + break; + case SDImageFormatPDF: + UTType = kSDUTTypePDF; + break; + case SDImageFormatSVG: + UTType = kSDUTTypeSVG; + break; + default: + // default is kUTTypeImage abstract type + UTType = kSDUTTypeImage; + break; + } + return UTType; +} + ++ (SDImageFormat)sd_imageFormatFromUTType:(CFStringRef)uttype { + if (!uttype) { + return SDImageFormatUndefined; + } + SDImageFormat imageFormat; + if (CFStringCompare(uttype, kSDUTTypeJPEG, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatJPEG; + } else if (CFStringCompare(uttype, kSDUTTypePNG, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatPNG; + } else if (CFStringCompare(uttype, kSDUTTypeGIF, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatGIF; + } else if (CFStringCompare(uttype, kSDUTTypeTIFF, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatTIFF; + } else if (CFStringCompare(uttype, kSDUTTypeWebP, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatWebP; + } else if (CFStringCompare(uttype, kSDUTTypeHEIC, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatHEIC; + } else if (CFStringCompare(uttype, kSDUTTypeHEIF, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatHEIF; + } else if (CFStringCompare(uttype, kSDUTTypePDF, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatPDF; + } else if (CFStringCompare(uttype, kSDUTTypeSVG, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatSVG; + } else { + imageFormat = SDImageFormatUndefined; + } + return imageFormat; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.h new file mode 100644 index 00000000..0a562cc4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.h @@ -0,0 +1,67 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +/** + This category is provided to easily write cross-platform(AppKit/UIKit) code. For common usage, see `UIImage+Metadata.h`. + */ +@interface NSImage (Compatibility) + +/** +The underlying Core Graphics image object. This will actually use `CGImageForProposedRect` with the image size. + */ +@property (nonatomic, readonly, nullable) CGImageRef CGImage; +/** + The underlying Core Image data. This will actually use `bestRepresentationForRect` with the image size to find the `NSCIImageRep`. + */ +@property (nonatomic, readonly, nullable) CIImage *CIImage; +/** + The scale factor of the image. This wil actually use `bestRepresentationForRect` with image size and pixel size to calculate the scale factor. If failed, use the default value 1.0. Should be greater than or equal to 1.0. + */ +@property (nonatomic, readonly) CGFloat scale; + +// These are convenience methods to make AppKit's `NSImage` match UIKit's `UIImage` behavior. The scale factor should be greater than or equal to 1.0. + +/** + Returns an image object with the scale factor and orientation. The representation is created from the Core Graphics image object. + @note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will actually create a `NSCGImageSnapshotRep` representation and always use `backingScaleFactor` as scale factor. So we should avoid it and use `NSBitmapImageRep` with `initWithCGImage:` instead. + @note The difference between this and UIKit's `UIImage` equivalent method is the way to process orientation. If the provided image orientation is not equal to Up orientation, this method will firstly rotate the CGImage to the correct orientation to work compatible with `NSImageView`. However, UIKit will not actually rotate CGImage and just store it as `imageOrientation` property. + + @param cgImage A Core Graphics image object + @param scale The image scale factor + @param orientation The orientation of the image data + @return The image object + */ +- (nonnull instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation; + +/** + Initializes and returns an image object with the specified Core Image object. The representation is `NSCIImageRep`. + + @param ciImage A Core Image image object + @param scale The image scale factor + @param orientation The orientation of the image data + @return The image object + */ +- (nonnull instancetype)initWithCIImage:(nonnull CIImage *)ciImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation; + +/** + Returns an image object with the scale factor. The representation is created from the image data. + @note The difference between these this and `initWithData:` is that `initWithData:` will always use `backingScaleFactor` as scale factor. + + @param data The image data + @param scale The image scale factor + @return The image object + */ +- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.m new file mode 100644 index 00000000..ce67151e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/NSImage+Compatibility.m @@ -0,0 +1,120 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSImage+Compatibility.h" + +#if SD_MAC + +#import "SDImageCoderHelper.h" + +@implementation NSImage (Compatibility) + +- (nullable CGImageRef)CGImage { + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:nil hints:nil]; + return cgImage; +} + +- (nullable CIImage *)CIImage { + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + if (![imageRep isKindOfClass:NSCIImageRep.class]) { + return nil; + } + return ((NSCIImageRep *)imageRep).CIImage; +} + +- (CGFloat)scale { + CGFloat scale = 1; + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + CGFloat width = imageRep.size.width; + CGFloat height = imageRep.size.height; + CGFloat pixelWidth = (CGFloat)imageRep.pixelsWide; + CGFloat pixelHeight = (CGFloat)imageRep.pixelsHigh; + if (width > 0 && height > 0) { + CGFloat widthScale = pixelWidth / width; + CGFloat heightScale = pixelHeight / height; + if (widthScale == heightScale && widthScale >= 1) { + // Protect because there may be `NSImageRepMatchesDevice` (0) + scale = widthScale; + } + } + + return scale; +} + +- (instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation { + NSBitmapImageRep *imageRep; + if (orientation != kCGImagePropertyOrientationUp) { + // AppKit design is different from UIKit. Where CGImage based image rep does not respect to any orientation. Only data based image rep which contains the EXIF metadata can automatically detect orientation. + // This should be nonnull, until the memory is exhausted cause `CGBitmapContextCreate` failed. + CGImageRef rotatedCGImage = [SDImageCoderHelper CGImageCreateDecoded:cgImage orientation:orientation]; + imageRep = [[NSBitmapImageRep alloc] initWithCGImage:rotatedCGImage]; + CGImageRelease(rotatedCGImage); + } else { + imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; + } + if (scale < 1) { + scale = 1; + } + CGFloat pixelWidth = imageRep.pixelsWide; + CGFloat pixelHeight = imageRep.pixelsHigh; + NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale); + self = [self initWithSize:size]; + if (self) { + imageRep.size = size; + [self addRepresentation:imageRep]; + } + return self; +} + +- (instancetype)initWithCIImage:(nonnull CIImage *)ciImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation { + NSCIImageRep *imageRep; + if (orientation != kCGImagePropertyOrientationUp) { + CIImage *rotatedCIImage = [ciImage imageByApplyingOrientation:orientation]; + imageRep = [[NSCIImageRep alloc] initWithCIImage:rotatedCIImage]; + } else { + imageRep = [[NSCIImageRep alloc] initWithCIImage:ciImage]; + } + if (scale < 1) { + scale = 1; + } + CGFloat pixelWidth = imageRep.pixelsWide; + CGFloat pixelHeight = imageRep.pixelsHigh; + NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale); + self = [self initWithSize:size]; + if (self) { + imageRep.size = size; + [self addRepresentation:imageRep]; + } + return self; +} + +- (instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale { + NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:data]; + if (!imageRep) { + return nil; + } + if (scale < 1) { + scale = 1; + } + CGFloat pixelWidth = imageRep.pixelsWide; + CGFloat pixelHeight = imageRep.pixelsHigh; + NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale); + self = [self initWithSize:size]; + if (self) { + imageRep.size = size; + [self addRepresentation:imageRep]; + } + return self; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.h new file mode 100644 index 00000000..2e208cdf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.h @@ -0,0 +1,114 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDImageCoder.h" + + +/** + This is the protocol for SDAnimatedImage class only but not for SDAnimatedImageCoder. If you want to provide a custom animated image class with full advanced function, you can conform to this instead of the base protocol. + */ +@protocol SDAnimatedImage + +@required +/** + Initializes and returns the image object with the specified data, scale factor and possible animation decoding options. + @note We use this to create animated image instance for normal animation decoding. + + @param data The data object containing the image data. + @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property. + @param options A dictionary containing any animation decoding options. + @return An initialized object + */ +- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale options:(nullable SDImageCoderOptions *)options; + +/** + Initializes the image with an animated coder. You can use the coder to decode the image frame later. + @note We use this with animated coder which conforms to `SDProgressiveImageCoder` for progressive animation decoding. + + @param animatedCoder An animated coder which conform `SDAnimatedImageCoder` protocol + @param scale The scale factor to assume when interpreting the image data. Applying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the `size` property. + @return An initialized object + */ +- (nullable instancetype)initWithAnimatedCoder:(nonnull id)animatedCoder scale:(CGFloat)scale; + +@optional +// These methods are used for optional advanced feature, like image frame preloading. +/** + Pre-load all animated image frame into memory. Then later frame image request can directly return the frame for index without decoding. + This method may be called on background thread. + + @note If one image instance is shared by lots of imageViews, the CPU performance for large animated image will drop down because the request frame index will be random (not in order) and the decoder should take extra effort to keep it re-entrant. You can use this to reduce CPU usage if need. Attention this will consume more memory usage. + */ +- (void)preloadAllFrames; + +/** + Unload all animated image frame from memory if are already pre-loaded. Then later frame image request need decoding. You can use this to free up the memory usage if need. + */ +- (void)unloadAllFrames; + +/** + Returns a Boolean value indicating whether all animated image frames are already pre-loaded into memory. + */ +@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded; + +/** + Return the animated image coder if the image is created with `initWithAnimatedCoder:scale:` method. + @note We use this with animated coder which conforms to `SDProgressiveImageCoder` for progressive animation decoding. + */ +@property (nonatomic, strong, readonly, nullable) id animatedCoder; + +@end + +/** + The image class which supports animating on `SDAnimatedImageView`. You can also use it on normal UIImageView/NSImageView. + */ +@interface SDAnimatedImage : UIImage + +// This class override these methods from UIImage(NSImage), and it supports NSSecureCoding. +// You should use these methods to create a new animated image. Use other methods just call super instead. +// Pay attention, when the animated image frame count <= 1, all the `SDAnimatedImageProvider` protocol methods will return nil or 0 value, you'd better check the frame count before usage and keep fallback. ++ (nullable instancetype)imageNamed:(nonnull NSString *)name; // Cache in memory, no Asset Catalog support +#if __has_include() ++ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection; // Cache in memory, no Asset Catalog support +#else ++ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle; // Cache in memory, no Asset Catalog support +#endif ++ (nullable instancetype)imageWithContentsOfFile:(nonnull NSString *)path; ++ (nullable instancetype)imageWithData:(nonnull NSData *)data; ++ (nullable instancetype)imageWithData:(nonnull NSData *)data scale:(CGFloat)scale; +- (nullable instancetype)initWithContentsOfFile:(nonnull NSString *)path; +- (nullable instancetype)initWithData:(nonnull NSData *)data; +- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale; + +/** + Current animated image format. + */ +@property (nonatomic, assign, readonly) SDImageFormat animatedImageFormat; + +/** + Current animated image data, you can use this to grab the compressed format data and create another animated image instance. + If this image instance is an animated image created by using animated image coder (which means using the API listed above or using `initWithAnimatedCoder:scale:`), this property is non-nil. + */ +@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData; + +/** + The scale factor of the image. + + @note For UIKit, this just call super instead. + @note For AppKit, `NSImage` can contains multiple image representations with different scales. However, this class does not do that from the design. We process the scale like UIKit. This will actually be calculated from image size and pixel size. + */ +@property (nonatomic, readonly) CGFloat scale; + +// By default, animated image frames are returned by decoding just in time without keeping into memory. But you can choose to preload them into memory as well, See the description in `SDAnimatedImage` protocol. +// After preloaded, there is no huge difference on performance between this and UIImage's `animatedImageWithImages:duration:`. But UIImage's animation have some issues such like blanking and pausing during segue when using in `UIImageView`. It's recommend to use only if need. +- (void)preloadAllFrames; +- (void)unloadAllFrames; +@property (nonatomic, assign, readonly, getter=isAllFramesLoaded) BOOL allFramesLoaded; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.m new file mode 100644 index 00000000..f98c4929 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImage.m @@ -0,0 +1,392 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAnimatedImage.h" +#import "NSImage+Compatibility.h" +#import "SDImageCoder.h" +#import "SDImageCodersManager.h" +#import "SDImageFrame.h" +#import "UIImage+MemoryCacheCost.h" +#import "UIImage+Metadata.h" +#import "UIImage+MultiFormat.h" +#import "SDImageCoderHelper.h" +#import "SDImageAssetManager.h" +#import "objc/runtime.h" + +static CGFloat SDImageScaleFromPath(NSString *string) { + if (string.length == 0 || [string hasSuffix:@"/"]) return 1; + NSString *name = string.stringByDeletingPathExtension; + __block CGFloat scale = 1; + + NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil]; + [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { + scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue; + }]; + + return scale; +} + +@interface SDAnimatedImage () + +@property (nonatomic, strong) id animatedCoder; +@property (nonatomic, assign, readwrite) SDImageFormat animatedImageFormat; +@property (atomic, copy) NSArray *loadedAnimatedImageFrames; // Mark as atomic to keep thread-safe +@property (nonatomic, assign, getter=isAllFramesLoaded) BOOL allFramesLoaded; + +@end + +@implementation SDAnimatedImage +@dynamic scale; // call super + +#pragma mark - UIImage override method ++ (instancetype)imageNamed:(NSString *)name { +#if __has_include() + return [self imageNamed:name inBundle:nil compatibleWithTraitCollection:nil]; +#else + return [self imageNamed:name inBundle:nil]; +#endif +} + +#if __has_include() ++ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection { + if (!traitCollection) { + traitCollection = UIScreen.mainScreen.traitCollection; + } + CGFloat scale = traitCollection.displayScale; + return [self imageNamed:name inBundle:bundle scale:scale]; +} +#else ++ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle { + return [self imageNamed:name inBundle:bundle scale:0]; +} +#endif + +// 0 scale means automatically check ++ (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle scale:(CGFloat)scale { + if (!name) { + return nil; + } + if (!bundle) { + bundle = [NSBundle mainBundle]; + } + SDImageAssetManager *assetManager = [SDImageAssetManager sharedAssetManager]; + SDAnimatedImage *image = (SDAnimatedImage *)[assetManager imageForName:name]; + if ([image isKindOfClass:[SDAnimatedImage class]]) { + return image; + } + NSString *path = [assetManager getPathForName:name bundle:bundle preferredScale:&scale]; + if (!path) { + return image; + } + NSData *data = [NSData dataWithContentsOfFile:path]; + if (!data) { + return image; + } + image = [[self alloc] initWithData:data scale:scale]; + if (image) { + [assetManager storeImage:image forName:name]; + } + + return image; +} + ++ (instancetype)imageWithContentsOfFile:(NSString *)path { + return [[self alloc] initWithContentsOfFile:path]; +} + ++ (instancetype)imageWithData:(NSData *)data { + return [[self alloc] initWithData:data]; +} + ++ (instancetype)imageWithData:(NSData *)data scale:(CGFloat)scale { + return [[self alloc] initWithData:data scale:scale]; +} + +- (instancetype)initWithContentsOfFile:(NSString *)path { + NSData *data = [NSData dataWithContentsOfFile:path]; + return [self initWithData:data scale:SDImageScaleFromPath(path)]; +} + +- (instancetype)initWithData:(NSData *)data { + return [self initWithData:data scale:1]; +} + +- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale { + return [self initWithData:data scale:scale options:nil]; +} + +- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale options:(SDImageCoderOptions *)options { + if (!data || data.length == 0) { + return nil; + } + data = [data copy]; // avoid mutable data + id animatedCoder = nil; + for (idcoder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) { + if ([coder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) { + if ([coder canDecodeFromData:data]) { + if (!options) { + options = @{SDImageCoderDecodeScaleFactor : @(scale)}; + } + animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:data options:options]; + break; + } + } + } + if (!animatedCoder) { + return nil; + } + return [self initWithAnimatedCoder:animatedCoder scale:scale]; +} + +- (instancetype)initWithAnimatedCoder:(id)animatedCoder scale:(CGFloat)scale { + if (!animatedCoder) { + return nil; + } + UIImage *image = [animatedCoder animatedImageFrameAtIndex:0]; + if (!image) { + return nil; + } +#if SD_MAC + self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:kCGImagePropertyOrientationUp]; +#else + self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:image.imageOrientation]; +#endif + if (self) { + // Only keep the animated coder if frame count > 1, save RAM usage for non-animated image format (APNG/WebP) + if (animatedCoder.animatedImageFrameCount > 1) { + _animatedCoder = animatedCoder; + } + NSData *data = [animatedCoder animatedImageData]; + SDImageFormat format = [NSData sd_imageFormatForImageData:data]; + _animatedImageFormat = format; + } + return self; +} + +#pragma mark - Preload +- (void)preloadAllFrames { + if (!_animatedCoder) { + return; + } + if (!self.isAllFramesLoaded) { + NSMutableArray *frames = [NSMutableArray arrayWithCapacity:self.animatedImageFrameCount]; + for (size_t i = 0; i < self.animatedImageFrameCount; i++) { + UIImage *image = [self animatedImageFrameAtIndex:i]; + NSTimeInterval duration = [self animatedImageDurationAtIndex:i]; + SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration]; // through the image should be nonnull, used as nullable for `animatedImageFrameAtIndex:` + [frames addObject:frame]; + } + self.loadedAnimatedImageFrames = frames; + self.allFramesLoaded = YES; + } +} + +- (void)unloadAllFrames { + if (!_animatedCoder) { + return; + } + if (self.isAllFramesLoaded) { + self.loadedAnimatedImageFrames = nil; + self.allFramesLoaded = NO; + } +} + +#pragma mark - NSSecureCoding +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + _animatedImageFormat = [aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(animatedImageFormat))]; + NSData *animatedImageData = [aDecoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(animatedImageData))]; + if (!animatedImageData) { + return self; + } + CGFloat scale = self.scale; + id animatedCoder = nil; + for (idcoder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) { + if ([coder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) { + if ([coder canDecodeFromData:animatedImageData]) { + animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:animatedImageData options:@{SDImageCoderDecodeScaleFactor : @(scale)}]; + break; + } + } + } + if (!animatedCoder) { + return self; + } + if (animatedCoder.animatedImageFrameCount > 1) { + _animatedCoder = animatedCoder; + } + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + [aCoder encodeInteger:self.animatedImageFormat forKey:NSStringFromSelector(@selector(animatedImageFormat))]; + NSData *animatedImageData = self.animatedImageData; + if (animatedImageData) { + [aCoder encodeObject:animatedImageData forKey:NSStringFromSelector(@selector(animatedImageData))]; + } +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +#pragma mark - SDAnimatedImageProvider + +- (NSData *)animatedImageData { + return [self.animatedCoder animatedImageData]; +} + +- (NSUInteger)animatedImageLoopCount { + return [self.animatedCoder animatedImageLoopCount]; +} + +- (NSUInteger)animatedImageFrameCount { + return [self.animatedCoder animatedImageFrameCount]; +} + +- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index { + if (index >= self.animatedImageFrameCount) { + return nil; + } + if (self.isAllFramesLoaded) { + SDImageFrame *frame = [self.loadedAnimatedImageFrames objectAtIndex:index]; + return frame.image; + } + return [self.animatedCoder animatedImageFrameAtIndex:index]; +} + +- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index { + if (index >= self.animatedImageFrameCount) { + return 0; + } + if (self.isAllFramesLoaded) { + SDImageFrame *frame = [self.loadedAnimatedImageFrames objectAtIndex:index]; + return frame.duration; + } + return [self.animatedCoder animatedImageDurationAtIndex:index]; +} + +@end + +@implementation SDAnimatedImage (MemoryCacheCost) + +- (NSUInteger)sd_memoryCost { + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_memoryCost)); + if (value != nil) { + return value.unsignedIntegerValue; + } + + CGImageRef imageRef = self.CGImage; + if (!imageRef) { + return 0; + } + NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef); + NSUInteger frameCount = 1; + if (self.isAllFramesLoaded) { + frameCount = self.animatedImageFrameCount; + } + frameCount = frameCount > 0 ? frameCount : 1; + NSUInteger cost = bytesPerFrame * frameCount; + return cost; +} + +@end + +@implementation SDAnimatedImage (Metadata) + +- (BOOL)sd_isAnimated { + return YES; +} + +- (NSUInteger)sd_imageLoopCount { + return self.animatedImageLoopCount; +} + +- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount { + return; +} + +- (NSUInteger)sd_imageFrameCount { + return self.animatedImageFrameCount; +} + +- (SDImageFormat)sd_imageFormat { + return self.animatedImageFormat; +} + +- (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat { + return; +} + +- (BOOL)sd_isVector { + return NO; +} + +@end + +@implementation SDAnimatedImage (MultiFormat) + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data { + return [self sd_imageWithData:data scale:1]; +} + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale { + return [self sd_imageWithData:data scale:scale firstFrameOnly:NO]; +} + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly { + if (!data) { + return nil; + } + return [[self alloc] initWithData:data scale:scale options:@{SDImageCoderDecodeFirstFrameOnly : @(firstFrameOnly)}]; +} + +- (nullable NSData *)sd_imageData { + NSData *imageData = self.animatedImageData; + if (imageData) { + return imageData; + } else { + return [self sd_imageDataAsFormat:self.animatedImageFormat]; + } +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat { + return [self sd_imageDataAsFormat:imageFormat compressionQuality:1]; +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality { + return [self sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:NO]; +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly { + if (firstFrameOnly) { + // First frame, use super implementation + return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly]; + } + NSUInteger frameCount = self.animatedImageFrameCount; + if (frameCount <= 1) { + // Static image, use super implementation + return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly]; + } + // Keep animated image encoding, loop each frame. + NSMutableArray *frames = [NSMutableArray arrayWithCapacity:frameCount]; + for (size_t i = 0; i < frameCount; i++) { + UIImage *image = [self animatedImageFrameAtIndex:i]; + NSTimeInterval duration = [self animatedImageDurationAtIndex:i]; + SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration]; + [frames addObject:frame]; + } + UIImage *animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames]; + NSData *imageData = [animatedImage sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly]; + return imageData; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.h new file mode 100644 index 00000000..e71e239c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.h @@ -0,0 +1,112 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" +#import "SDImageCoder.h" + +typedef NS_ENUM(NSUInteger, SDAnimatedImagePlaybackMode) { + /** + * From first to last frame and stop or next loop. + */ + SDAnimatedImagePlaybackModeNormal = 0, + /** + * From last frame to first frame and stop or next loop. + */ + SDAnimatedImagePlaybackModeReverse, + /** + * From first frame to last frame and reverse again, like reciprocating. + */ + SDAnimatedImagePlaybackModeBounce, + /** + * From last frame to first frame and reverse again, like reversed reciprocating. + */ + SDAnimatedImagePlaybackModeReversedBounce, +}; + +/// A player to control the playback of animated image, which can be used to drive Animated ImageView or any rendering usage, like CALayer/WatchKit/SwiftUI rendering. +@interface SDAnimatedImagePlayer : NSObject + +/// Current playing frame image. This value is KVO Compliance. +@property (nonatomic, readonly, nullable) UIImage *currentFrame; + +/// Current frame index, zero based. This value is KVO Compliance. +@property (nonatomic, readonly) NSUInteger currentFrameIndex; + +/// Current loop count since its latest animating. This value is KVO Compliance. +@property (nonatomic, readonly) NSUInteger currentLoopCount; + +/// Total frame count for animated image rendering. Defaults is animated image's frame count. +/// @note For progressive animation, you can update this value when your provider receive more frames. +@property (nonatomic, assign) NSUInteger totalFrameCount; + +/// Total loop count for animated image rendering. Default is animated image's loop count. +@property (nonatomic, assign) NSUInteger totalLoopCount; + +/// The animation playback rate. Default is 1.0 +/// `1.0` means the normal speed. +/// `0.0` means stopping the animation. +/// `0.0-1.0` means the slow speed. +/// `> 1.0` means the fast speed. +/// `< 0.0` is not supported currently and stop animation. (may support reverse playback in the future) +@property (nonatomic, assign) double playbackRate; + +/// Asynchronous setup animation playback mode. Default mode is SDAnimatedImagePlaybackModeNormal. +@property (nonatomic, assign) SDAnimatedImagePlaybackMode playbackMode; + +/// Provide a max buffer size by bytes. This is used to adjust frame buffer count and can be useful when the decoding cost is expensive (such as Animated WebP software decoding). Default is 0. +/// `0` means automatically adjust by calculating current memory usage. +/// `1` means without any buffer cache, each of frames will be decoded and then be freed after rendering. (Lowest Memory and Highest CPU) +/// `NSUIntegerMax` means cache all the buffer. (Lowest CPU and Highest Memory) +@property (nonatomic, assign) NSUInteger maxBufferSize; + +/// You can specify a runloop mode to let it rendering. +/// Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device +@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode; + +/// Create a player with animated image provider. If the provider's `animatedImageFrameCount` is less than 1, returns nil. +/// The provider can be any protocol implementation, like `SDAnimatedImage`, `SDImageGIFCoder`, etc. +/// @note This provider can represent mutable content, like progressive animated loading. But you need to update the frame count by yourself +/// @param provider The animated provider +- (nullable instancetype)initWithProvider:(nonnull id)provider; + +/// Create a player with animated image provider. If the provider's `animatedImageFrameCount` is less than 1, returns nil. +/// The provider can be any protocol implementation, like `SDAnimatedImage` or `SDImageGIFCoder`, etc. +/// @note This provider can represent mutable content, like progressive animated loading. But you need to update the frame count by yourself +/// @param provider The animated provider ++ (nullable instancetype)playerWithProvider:(nonnull id)provider; + +/// The handler block when current frame and index changed. +@property (nonatomic, copy, nullable) void (^animationFrameHandler)(NSUInteger index, UIImage * _Nonnull frame); + +/// The handler block when one loop count finished. +@property (nonatomic, copy, nullable) void (^animationLoopHandler)(NSUInteger loopCount); + +/// Return the status whether animation is playing. +@property (nonatomic, readonly) BOOL isPlaying; + +/// Start the animation. Or resume the previously paused animation. +- (void)startPlaying; + +/// Pause the animation. Keep the current frame index and loop count. +- (void)pausePlaying; + +/// Stop the animation. Reset the current frame index and loop count. +- (void)stopPlaying; + +/// Seek to the desired frame index and loop count. +/// @note This can be used for advanced control like progressive loading, or skipping specify frames. +/// @param index The frame index +/// @param loopCount The loop count +- (void)seekToFrameAtIndex:(NSUInteger)index loopCount:(NSUInteger)loopCount; + +/// Clear the frame cache buffer. The frame cache buffer size can be controlled by `maxBufferSize`. +/// By default, when stop or pause the animation, the frame buffer is still kept to ready for the next restart +- (void)clearFrameBuffer; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.m new file mode 100644 index 00000000..a03f78b1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImagePlayer.m @@ -0,0 +1,406 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDAnimatedImagePlayer.h" +#import "NSImage+Compatibility.h" +#import "SDDisplayLink.h" +#import "SDDeviceHelper.h" +#import "SDInternalMacros.h" + +@interface SDAnimatedImagePlayer () { + SD_LOCK_DECLARE(_lock); + NSRunLoopMode _runLoopMode; +} + +@property (nonatomic, strong, readwrite) UIImage *currentFrame; +@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex; +@property (nonatomic, assign, readwrite) NSUInteger currentLoopCount; +@property (nonatomic, strong) id animatedProvider; +@property (nonatomic, strong) NSMutableDictionary *frameBuffer; +@property (nonatomic, assign) NSTimeInterval currentTime; +@property (nonatomic, assign) BOOL bufferMiss; +@property (nonatomic, assign) BOOL needsDisplayWhenImageBecomesAvailable; +@property (nonatomic, assign) BOOL shouldReverse; +@property (nonatomic, assign) NSUInteger maxBufferCount; +@property (nonatomic, strong) NSOperationQueue *fetchQueue; +@property (nonatomic, strong) SDDisplayLink *displayLink; + +@end + +@implementation SDAnimatedImagePlayer + +- (instancetype)initWithProvider:(id)provider { + self = [super init]; + if (self) { + NSUInteger animatedImageFrameCount = provider.animatedImageFrameCount; + // Check the frame count + if (animatedImageFrameCount <= 1) { + return nil; + } + self.totalFrameCount = animatedImageFrameCount; + // Get the current frame and loop count. + self.totalLoopCount = provider.animatedImageLoopCount; + self.animatedProvider = provider; + self.playbackRate = 1.0; + SD_LOCK_INIT(_lock); +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + ++ (instancetype)playerWithProvider:(id)provider { + SDAnimatedImagePlayer *player = [[SDAnimatedImagePlayer alloc] initWithProvider:provider]; + return player; +} + +#pragma mark - Life Cycle + +- (void)dealloc { +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification { + [_fetchQueue cancelAllOperations]; + [_fetchQueue addOperationWithBlock:^{ + NSNumber *currentFrameIndex = @(self.currentFrameIndex); + SD_LOCK(self->_lock); + NSArray *keys = self.frameBuffer.allKeys; + // only keep the next frame for later rendering + for (NSNumber * key in keys) { + if (![key isEqualToNumber:currentFrameIndex]) { + [self.frameBuffer removeObjectForKey:key]; + } + } + SD_UNLOCK(self->_lock); + }]; +} + +#pragma mark - Private +- (NSOperationQueue *)fetchQueue { + if (!_fetchQueue) { + _fetchQueue = [[NSOperationQueue alloc] init]; + _fetchQueue.maxConcurrentOperationCount = 1; + } + return _fetchQueue; +} + +- (NSMutableDictionary *)frameBuffer { + if (!_frameBuffer) { + _frameBuffer = [NSMutableDictionary dictionary]; + } + return _frameBuffer; +} + +- (SDDisplayLink *)displayLink { + if (!_displayLink) { + _displayLink = [SDDisplayLink displayLinkWithTarget:self selector:@selector(displayDidRefresh:)]; + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.runLoopMode]; + [_displayLink stop]; + } + return _displayLink; +} + +- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode { + if ([_runLoopMode isEqual:runLoopMode]) { + return; + } + if (_displayLink) { + if (_runLoopMode) { + [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:_runLoopMode]; + } + if (runLoopMode.length > 0) { + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode]; + } + } + _runLoopMode = [runLoopMode copy]; +} + +- (NSRunLoopMode)runLoopMode { + if (!_runLoopMode) { + _runLoopMode = [[self class] defaultRunLoopMode]; + } + return _runLoopMode; +} + +#pragma mark - State Control + +- (void)setupCurrentFrame { + if (self.currentFrameIndex != 0) { + return; + } + if (self.playbackMode == SDAnimatedImagePlaybackModeReverse || + self.playbackMode == SDAnimatedImagePlaybackModeReversedBounce) { + self.currentFrameIndex = self.totalFrameCount - 1; + } + + if (!self.currentFrame && [self.animatedProvider isKindOfClass:[UIImage class]]) { + UIImage *image = (UIImage *)self.animatedProvider; + // Use the poster image if available + #if SD_MAC + UIImage *posterFrame = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp]; + #else + UIImage *posterFrame = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation]; + #endif + if (posterFrame) { + self.currentFrame = posterFrame; + SD_LOCK(self->_lock); + self.frameBuffer[@(self.currentFrameIndex)] = self.currentFrame; + SD_UNLOCK(self->_lock); + [self handleFrameChange]; + } + } + +} + +- (void)resetCurrentFrameStatus { + // These should not trigger KVO, user don't need to receive an `index == 0, image == nil` callback. + _currentFrame = nil; + _currentFrameIndex = 0; + _currentLoopCount = 0; + _currentTime = 0; + _bufferMiss = NO; + _needsDisplayWhenImageBecomesAvailable = NO; +} + +- (void)clearFrameBuffer { + SD_LOCK(_lock); + [_frameBuffer removeAllObjects]; + SD_UNLOCK(_lock); +} + +#pragma mark - Animation Control +- (void)startPlaying { + [self.displayLink start]; + // Setup frame + [self setupCurrentFrame]; + // Calculate max buffer size + [self calculateMaxBufferCount]; +} + +- (void)stopPlaying { + [_fetchQueue cancelAllOperations]; + // Using `_displayLink` here because when UIImageView dealloc, it may trigger `[self stopAnimating]`, we already release the display link in SDAnimatedImageView's dealloc method. + [_displayLink stop]; + // We need to reset the frame status, but not trigger any handle. This can ensure next time's playing status correct. + [self resetCurrentFrameStatus]; +} + +- (void)pausePlaying { + [_fetchQueue cancelAllOperations]; + [_displayLink stop]; +} + +- (BOOL)isPlaying { + return _displayLink.isRunning; +} + +- (void)seekToFrameAtIndex:(NSUInteger)index loopCount:(NSUInteger)loopCount { + if (index >= self.totalFrameCount) { + return; + } + self.currentFrameIndex = index; + self.currentLoopCount = loopCount; + self.currentFrame = [self.animatedProvider animatedImageFrameAtIndex:index]; + [self handleFrameChange]; +} + +#pragma mark - Core Render +- (void)displayDidRefresh:(SDDisplayLink *)displayLink { + // If for some reason a wild call makes it through when we shouldn't be animating, bail. + // Early return! + if (!self.isPlaying) { + return; + } + + NSUInteger totalFrameCount = self.totalFrameCount; + if (totalFrameCount <= 1) { + // Total frame count less than 1, wrong configuration and stop animating + [self stopPlaying]; + return; + } + + NSTimeInterval playbackRate = self.playbackRate; + if (playbackRate <= 0) { + // Does not support <= 0 play rate + [self stopPlaying]; + return; + } + + // Calculate refresh duration + NSTimeInterval duration = self.displayLink.duration; + + NSUInteger currentFrameIndex = self.currentFrameIndex; + NSUInteger nextFrameIndex = (currentFrameIndex + 1) % totalFrameCount; + + if (self.playbackMode == SDAnimatedImagePlaybackModeReverse) { + nextFrameIndex = currentFrameIndex == 0 ? (totalFrameCount - 1) : (currentFrameIndex - 1) % totalFrameCount; + + } else if (self.playbackMode == SDAnimatedImagePlaybackModeBounce || + self.playbackMode == SDAnimatedImagePlaybackModeReversedBounce) { + if (currentFrameIndex == 0) { + self.shouldReverse = false; + } else if (currentFrameIndex == totalFrameCount - 1) { + self.shouldReverse = true; + } + nextFrameIndex = self.shouldReverse ? (currentFrameIndex - 1) : (currentFrameIndex + 1); + nextFrameIndex %= totalFrameCount; + } + + + // Check if we need to display new frame firstly + BOOL bufferFull = NO; + if (self.needsDisplayWhenImageBecomesAvailable) { + UIImage *currentFrame; + SD_LOCK(_lock); + currentFrame = self.frameBuffer[@(currentFrameIndex)]; + SD_UNLOCK(_lock); + + // Update the current frame + if (currentFrame) { + SD_LOCK(_lock); + // Remove the frame buffer if need + if (self.frameBuffer.count > self.maxBufferCount) { + self.frameBuffer[@(currentFrameIndex)] = nil; + } + // Check whether we can stop fetch + if (self.frameBuffer.count == totalFrameCount) { + bufferFull = YES; + } + SD_UNLOCK(_lock); + + // Update the current frame immediately + self.currentFrame = currentFrame; + [self handleFrameChange]; + + self.bufferMiss = NO; + self.needsDisplayWhenImageBecomesAvailable = NO; + } + else { + self.bufferMiss = YES; + } + } + + // Check if we have the frame buffer + if (!self.bufferMiss) { + // Then check if timestamp is reached + self.currentTime += duration; + NSTimeInterval currentDuration = [self.animatedProvider animatedImageDurationAtIndex:currentFrameIndex]; + currentDuration = currentDuration / playbackRate; + if (self.currentTime < currentDuration) { + // Current frame timestamp not reached, return + return; + } + + // Otherwise, we should be ready to display next frame + self.needsDisplayWhenImageBecomesAvailable = YES; + self.currentFrameIndex = nextFrameIndex; + self.currentTime -= currentDuration; + NSTimeInterval nextDuration = [self.animatedProvider animatedImageDurationAtIndex:nextFrameIndex]; + nextDuration = nextDuration / playbackRate; + if (self.currentTime > nextDuration) { + // Do not skip frame + self.currentTime = nextDuration; + } + + // Update the loop count when last frame rendered + if (nextFrameIndex == 0) { + // Update the loop count + self.currentLoopCount++; + [self handleLoopChange]; + + // if reached the max loop count, stop animating, 0 means loop indefinitely + NSUInteger maxLoopCount = self.totalLoopCount; + if (maxLoopCount != 0 && (self.currentLoopCount >= maxLoopCount)) { + [self stopPlaying]; + return; + } + } + } + + // Since we support handler, check animating state again + if (!self.isPlaying) { + return; + } + + // Check if we should prefetch next frame or current frame + // When buffer miss, means the decode speed is slower than render speed, we fetch current miss frame + // Or, most cases, the decode speed is faster than render speed, we fetch next frame + NSUInteger fetchFrameIndex = self.bufferMiss? currentFrameIndex : nextFrameIndex; + UIImage *fetchFrame; + SD_LOCK(_lock); + fetchFrame = self.bufferMiss? nil : self.frameBuffer[@(nextFrameIndex)]; + SD_UNLOCK(_lock); + + if (!fetchFrame && !bufferFull && self.fetchQueue.operationCount == 0) { + // Prefetch next frame in background queue + id animatedProvider = self.animatedProvider; + @weakify(self); + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + @strongify(self); + if (!self) { + return; + } + UIImage *frame = [animatedProvider animatedImageFrameAtIndex:fetchFrameIndex]; + + BOOL isAnimating = self.displayLink.isRunning; + if (isAnimating) { + SD_LOCK(self->_lock); + self.frameBuffer[@(fetchFrameIndex)] = frame; + SD_UNLOCK(self->_lock); + } + }]; + [self.fetchQueue addOperation:operation]; + } +} + +- (void)handleFrameChange { + if (self.animationFrameHandler) { + self.animationFrameHandler(self.currentFrameIndex, self.currentFrame); + } +} + +- (void)handleLoopChange { + if (self.animationLoopHandler) { + self.animationLoopHandler(self.currentLoopCount); + } +} + +#pragma mark - Util +- (void)calculateMaxBufferCount { + NSUInteger bytes = CGImageGetBytesPerRow(self.currentFrame.CGImage) * CGImageGetHeight(self.currentFrame.CGImage); + if (bytes == 0) bytes = 1024; + + NSUInteger max = 0; + if (self.maxBufferSize > 0) { + max = self.maxBufferSize; + } else { + // Calculate based on current memory, these factors are by experience + NSUInteger total = [SDDeviceHelper totalMemory]; + NSUInteger free = [SDDeviceHelper freeMemory]; + max = MIN(total * 0.2, free * 0.6); + } + + NSUInteger maxBufferCount = (double)max / (double)bytes; + if (!maxBufferCount) { + // At least 1 frame + maxBufferCount = 1; + } + + self.maxBufferCount = maxBufferCount; +} + ++ (NSString *)defaultRunLoopMode { + // Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations. + return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.h new file mode 100644 index 00000000..be52f8cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.h @@ -0,0 +1,23 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +/** + A subclass of `NSBitmapImageRep` to fix that GIF duration issue because `NSBitmapImageRep` will reset `NSImageCurrentFrameDuration` by using `kCGImagePropertyGIFDelayTime` but not `kCGImagePropertyGIFUnclampedDelayTime`. + This also fix the GIF loop count issue, which will use the Netscape standard (See http://www6.uniovi.es/gifanim/gifabout.htm) to only place once when the `kCGImagePropertyGIFLoopCount` is nil. This is what modern browser's behavior. + Built in GIF coder use this instead of `NSBitmapImageRep` for better GIF rendering. If you do not want this, only enable `SDImageIOCoder`, which just call `NSImage` API and actually use `NSBitmapImageRep` for GIF image. + This also support APNG format using `SDImageAPNGCoder`. Which provide full alpha-channel support and the correct duration match the `kCGImagePropertyAPNGUnclampedDelayTime`. + */ +@interface SDAnimatedImageRep : NSBitmapImageRep + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.m new file mode 100644 index 00000000..2ef3a88b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageRep.m @@ -0,0 +1,133 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAnimatedImageRep.h" + +#if SD_MAC + +#import "SDImageIOAnimatedCoderInternal.h" +#import "SDImageGIFCoder.h" +#import "SDImageAPNGCoder.h" +#import "SDImageHEICCoder.h" +#import "SDImageAWebPCoder.h" + +@implementation SDAnimatedImageRep { + CGImageSourceRef _imageSource; +} + +- (void)dealloc { + if (_imageSource) { + CFRelease(_imageSource); + _imageSource = NULL; + } +} + +- (instancetype)copyWithZone:(NSZone *)zone { + SDAnimatedImageRep *imageRep = [super copyWithZone:zone]; + CFRetain(imageRep->_imageSource); + return imageRep; +} + +// `NSBitmapImageRep`'s `imageRepWithData:` is not designed initializer ++ (instancetype)imageRepWithData:(NSData *)data { + SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data]; + return imageRep; +} + +// We should override init method for `NSBitmapImageRep` to do initialize about animated image format +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +- (instancetype)initWithData:(NSData *)data { + self = [super initWithData:data]; + if (self) { + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL); + if (!imageSource) { + return self; + } + _imageSource = imageSource; + NSUInteger frameCount = CGImageSourceGetCount(imageSource); + if (frameCount <= 1) { + return self; + } + CFStringRef type = CGImageSourceGetType(imageSource); + if (!type) { + return self; + } + if (CFStringCompare(type, kSDUTTypeGIF, 0) == kCFCompareEqualTo) { + // GIF + // Fix the `NSBitmapImageRep` GIF loop count calculation issue + // Which will use 0 when there are no loop count information metadata in GIF data + NSUInteger loopCount = [SDImageGIFCoder imageLoopCountWithSource:imageSource]; + [self setProperty:NSImageLoopCount withValue:@(loopCount)]; + } else if (CFStringCompare(type, kSDUTTypePNG, 0) == kCFCompareEqualTo) { + // APNG + // Do initialize about frame count, current frame/duration and loop count + [self setProperty:NSImageFrameCount withValue:@(frameCount)]; + [self setProperty:NSImageCurrentFrame withValue:@(0)]; + NSUInteger loopCount = [SDImageAPNGCoder imageLoopCountWithSource:imageSource]; + [self setProperty:NSImageLoopCount withValue:@(loopCount)]; + } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) { + // HEIC + // Do initialize about frame count, current frame/duration and loop count + [self setProperty:NSImageFrameCount withValue:@(frameCount)]; + [self setProperty:NSImageCurrentFrame withValue:@(0)]; + NSUInteger loopCount = [SDImageHEICCoder imageLoopCountWithSource:imageSource]; + [self setProperty:NSImageLoopCount withValue:@(loopCount)]; + } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) { + // WebP + // Do initialize about frame count, current frame/duration and loop count + [self setProperty:NSImageFrameCount withValue:@(frameCount)]; + [self setProperty:NSImageCurrentFrame withValue:@(0)]; + NSUInteger loopCount = [SDImageAWebPCoder imageLoopCountWithSource:imageSource]; + [self setProperty:NSImageLoopCount withValue:@(loopCount)]; + } + } + return self; +} + +// `NSBitmapImageRep` will use `kCGImagePropertyGIFDelayTime` whenever you call `setProperty:withValue:` with `NSImageCurrentFrame` to change the current frame. We override it and use the actual `kCGImagePropertyGIFUnclampedDelayTime` if need. +- (void)setProperty:(NSBitmapImageRepPropertyKey)property withValue:(id)value { + [super setProperty:property withValue:value]; + if ([property isEqualToString:NSImageCurrentFrame]) { + // Access the image source + CGImageSourceRef imageSource = _imageSource; + if (!imageSource) { + return; + } + // Check format type + CFStringRef type = CGImageSourceGetType(imageSource); + if (!type) { + return; + } + NSUInteger index = [value unsignedIntegerValue]; + NSTimeInterval frameDuration = 0; + if (CFStringCompare(type, kSDUTTypeGIF, 0) == kCFCompareEqualTo) { + // GIF + frameDuration = [SDImageGIFCoder frameDurationAtIndex:index source:imageSource]; + } else if (CFStringCompare(type, kSDUTTypePNG, 0) == kCFCompareEqualTo) { + // APNG + frameDuration = [SDImageAPNGCoder frameDurationAtIndex:index source:imageSource]; + } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) { + // HEIC + frameDuration = [SDImageHEICCoder frameDurationAtIndex:index source:imageSource]; + } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) { + // WebP + frameDuration = [SDImageAWebPCoder frameDurationAtIndex:index source:imageSource]; + } + if (!frameDuration) { + return; + } + // Reset super frame duration with the actual frame duration + [super setProperty:NSImageCurrentFrameDuration withValue:@(frameDuration)]; + } +} +#pragma clang diagnostic pop + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.h new file mode 100644 index 00000000..af464764 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.h @@ -0,0 +1,168 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAnimatedImageView.h" + +#if SD_UIKIT || SD_MAC + +#import "SDWebImageManager.h" + +/** + Integrates SDWebImage async downloading and caching of remote images with SDAnimatedImageView. + */ +@interface SDAnimatedImageView (WebCache) + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.m new file mode 100644 index 00000000..beb56b2c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView+WebCache.m @@ -0,0 +1,79 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAnimatedImageView+WebCache.h" + +#if SD_UIKIT || SD_MAC + +#import "UIView+WebCache.h" +#import "SDAnimatedImage.h" + +@implementation SDAnimatedImageView (WebCache) + +- (void)sd_setImageWithURL:(nullable NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + Class animatedImageClass = [SDAnimatedImage class]; + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextAnimatedImageClass] = animatedImageClass; + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:mutableContext + setImageBlock:nil + progress:progressBlock + completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.h new file mode 100644 index 00000000..f5f541b1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.h @@ -0,0 +1,110 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_UIKIT || SD_MAC + +#import "SDAnimatedImage.h" +#import "SDAnimatedImagePlayer.h" + +/** + A drop-in replacement for UIImageView/NSImageView, you can use this for animated image rendering. + Call `setImage:` with `UIImage(NSImage)` which conforms to `SDAnimatedImage` protocol will start animated image rendering. Call with normal UIImage(NSImage) will back to normal UIImageView(NSImageView) rendering + For UIKit: use `-startAnimating`, `-stopAnimating` to control animating. `isAnimating` to check animation state. + For AppKit: use `-setAnimates:` to control animating, `animates` to check animation state. This view is layer-backed. + */ +@interface SDAnimatedImageView : UIImageView +/** + The internal animation player. + This property is only used for advanced usage, like inspecting/debugging animation status, control progressive loading, complicated animation frame index control, etc. + @warning Pay attention if you directly update the player's property like `totalFrameCount`, `totalLoopCount`, the same property on `SDAnimatedImageView` may not get synced. + */ +@property (nonatomic, strong, readonly, nullable) SDAnimatedImagePlayer *player; + +/** + Current display frame image. This value is KVO Compliance. + */ +@property (nonatomic, strong, readonly, nullable) UIImage *currentFrame; +/** + Current frame index, zero based. This value is KVO Compliance. + */ +@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex; +/** + Current loop count since its latest animating. This value is KVO Compliance. + */ +@property (nonatomic, assign, readonly) NSUInteger currentLoopCount; +/** + YES to choose `animationRepeatCount` property for animation loop count. No to use animated image's `animatedImageLoopCount` instead. + Default is NO. + */ +@property (nonatomic, assign) BOOL shouldCustomLoopCount; +/** + Total loop count for animated image rendering. Default is animated image's loop count. + If you need to set custom loop count, set `shouldCustomLoopCount` to YES and change this value. + This class override UIImageView's `animationRepeatCount` property on iOS, use this property as well. + */ +@property (nonatomic, assign) NSInteger animationRepeatCount; +/** + The animation playback rate. Default is 1.0. + `1.0` means the normal speed. + `0.0` means stopping the animation. + `0.0-1.0` means the slow speed. + `> 1.0` means the fast speed. + `< 0.0` is not supported currently and stop animation. (may support reverse playback in the future) + */ +@property (nonatomic, assign) double playbackRate; + +/// Asynchronous setup animation playback mode. Default mode is SDAnimatedImagePlaybackModeNormal. +@property (nonatomic, assign) SDAnimatedImagePlaybackMode playbackMode; + +/** + Provide a max buffer size by bytes. This is used to adjust frame buffer count and can be useful when the decoding cost is expensive (such as Animated WebP software decoding). Default is 0. + `0` means automatically adjust by calculating current memory usage. + `1` means without any buffer cache, each of frames will be decoded and then be freed after rendering. (Lowest Memory and Highest CPU) + `NSUIntegerMax` means cache all the buffer. (Lowest CPU and Highest Memory) + */ +@property (nonatomic, assign) NSUInteger maxBufferSize; +/** + Whehter or not to enable incremental image load for animated image. This is for the animated image which `sd_isIncremental` is YES (See `UIImage+Metadata.h`). If enable, animated image rendering will stop at the last frame available currently, and continue when another `setImage:` trigger, where the new animated image's `animatedImageData` should be updated from the previous one. If the `sd_isIncremental` is NO. The incremental image load stop. + @note If you are confused about this description, open Chrome browser to view some large GIF images with low network speed to see the animation behavior. + @note The best practice to use incremental load is using `initWithAnimatedCoder:scale:` in `SDAnimatedImage` with animated coder which conform to `SDProgressiveImageCoder` as well. Then call incremental update and incremental decode method to produce the image. + Default is YES. Set to NO to only render the static poster for incremental animated image. + */ +@property (nonatomic, assign) BOOL shouldIncrementalLoad; + +/** + Whether or not to clear the frame buffer cache when animation stopped. See `maxBufferSize` + This is useful when you want to limit the memory usage during frequently visibility changes (such as image view inside a list view, then push and pop) + Default is NO. + */ +@property (nonatomic, assign) BOOL clearBufferWhenStopped; + +/** + Whether or not to reset the current frame index when animation stopped. + For some of use case, you may want to reset the frame index to 0 when stop, but some other want to keep the current frame index. + Default is NO. + */ +@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped; + +/** + If the image which conforms to `SDAnimatedImage` protocol has more than one frame, set this value to `YES` will automatically + play/stop the animation when the view become visible/invisible. + Default is YES. + */ +@property (nonatomic, assign) BOOL autoPlayAnimatedImage; + +/** + You can specify a runloop mode to let it rendering. + Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device + @note This is useful for some cases, for example, always specify NSDefaultRunLoopMode, if you want to pause the animation when user scroll (for Mac user, drag the mouse or touchpad) + */ +@property (nonatomic, copy, nonnull) NSRunLoopMode runLoopMode; +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.m new file mode 100644 index 00000000..53d697f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDAnimatedImageView.m @@ -0,0 +1,536 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAnimatedImageView.h" + +#if SD_UIKIT || SD_MAC + +#import "UIImage+Metadata.h" +#import "NSImage+Compatibility.h" +#import "SDInternalMacros.h" +#import "objc/runtime.h" + +@interface UIImageView () +@end + +@interface SDAnimatedImageView () { + BOOL _initFinished; // Extra flag to mark the `commonInit` is called + NSRunLoopMode _runLoopMode; + NSUInteger _maxBufferSize; + double _playbackRate; + SDAnimatedImagePlaybackMode _playbackMode; +} + +@property (nonatomic, strong, readwrite) SDAnimatedImagePlayer *player; +@property (nonatomic, strong, readwrite) UIImage *currentFrame; +@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex; +@property (nonatomic, assign, readwrite) NSUInteger currentLoopCount; +@property (nonatomic, assign) BOOL shouldAnimate; +@property (nonatomic, assign) BOOL isProgressive; +@property (nonatomic) CALayer *imageViewLayer; // The actual rendering layer. + +@end + +@implementation SDAnimatedImageView +#if SD_UIKIT +@dynamic animationRepeatCount; // we re-use this property from `UIImageView` super class on iOS. +#endif + +#pragma mark - Initializers + +#if SD_MAC ++ (instancetype)imageViewWithImage:(NSImage *)image +{ + NSRect frame = NSMakeRect(0, 0, image.size.width, image.size.height); + SDAnimatedImageView *imageView = [[SDAnimatedImageView alloc] initWithFrame:frame]; + [imageView setImage:image]; + return imageView; +} +#else +// -initWithImage: isn't documented as a designated initializer of UIImageView, but it actually seems to be. +// Using -initWithImage: doesn't call any of the other designated initializers. +- (instancetype)initWithImage:(UIImage *)image +{ + self = [super initWithImage:image]; + if (self) { + [self commonInit]; + } + return self; +} + +// -initWithImage:highlightedImage: also isn't documented as a designated initializer of UIImageView, but it doesn't call any other designated initializers. +- (instancetype)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage +{ + self = [super initWithImage:image highlightedImage:highlightedImage]; + if (self) { + [self commonInit]; + } + return self; +} +#endif + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInit]; + } + return self; +} + +- (void)commonInit +{ + // Pay attention that UIKit's `initWithImage:` will trigger a `setImage:` during initialization before this `commonInit`. + // So the properties which rely on this order, should using lazy-evaluation or do extra check in `setImage:`. + self.autoPlayAnimatedImage = YES; + self.shouldCustomLoopCount = NO; + self.shouldIncrementalLoad = YES; + self.playbackRate = 1.0; +#if SD_MAC + self.wantsLayer = YES; +#endif + // Mark commonInit finished + _initFinished = YES; +} + +#pragma mark - Accessors +#pragma mark Public + +- (void)setImage:(UIImage *)image +{ + if (self.image == image) { + return; + } + + // Check Progressive rendering + [self updateIsProgressiveWithImage:image]; + + if (!self.isProgressive) { + // Stop animating + self.player = nil; + self.currentFrame = nil; + self.currentFrameIndex = 0; + self.currentLoopCount = 0; + } + + // We need call super method to keep function. This will impliedly call `setNeedsDisplay`. But we have no way to avoid this when using animated image. So we call `setNeedsDisplay` again at the end. + super.image = image; + if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) { + if (!self.player) { + id provider; + // Check progressive loading + if (self.isProgressive) { + provider = [self progressiveAnimatedCoderForImage:image]; + } else { + provider = (id)image; + } + // Create animated player + self.player = [SDAnimatedImagePlayer playerWithProvider:provider]; + } else { + // Update Frame Count + self.player.totalFrameCount = [(id)image animatedImageFrameCount]; + } + + if (!self.player) { + // animated player nil means the image format is not supported, or frame count <= 1 + return; + } + + // Custom Loop Count + if (self.shouldCustomLoopCount) { + self.player.totalLoopCount = self.animationRepeatCount; + } + + // RunLoop Mode + self.player.runLoopMode = self.runLoopMode; + + // Max Buffer Size + self.player.maxBufferSize = self.maxBufferSize; + + // Play Rate + self.player.playbackRate = self.playbackRate; + + // Play Mode + self.player.playbackMode = self.playbackMode; + + // Setup handler + @weakify(self); + self.player.animationFrameHandler = ^(NSUInteger index, UIImage * frame) { + @strongify(self); + self.currentFrameIndex = index; + self.currentFrame = frame; + [self.imageViewLayer setNeedsDisplay]; + }; + self.player.animationLoopHandler = ^(NSUInteger loopCount) { + @strongify(self); + // Progressive image reach the current last frame index. Keep the state and pause animating. Wait for later restart + if (self.isProgressive) { + NSUInteger lastFrameIndex = self.player.totalFrameCount - 1; + [self.player seekToFrameAtIndex:lastFrameIndex loopCount:0]; + [self.player pausePlaying]; + } else { + self.currentLoopCount = loopCount; + } + }; + + // Ensure disabled highlighting; it's not supported (see `-setHighlighted:`). + super.highlighted = NO; + + [self stopAnimating]; + [self checkPlay]; + + [self.imageViewLayer setNeedsDisplay]; + } +} + +#pragma mark - Configuration + +- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode +{ + _runLoopMode = [runLoopMode copy]; + self.player.runLoopMode = runLoopMode; +} + +- (NSRunLoopMode)runLoopMode +{ + if (!_runLoopMode) { + _runLoopMode = [[self class] defaultRunLoopMode]; + } + return _runLoopMode; +} + ++ (NSString *)defaultRunLoopMode { + // Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations. + return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode; +} + +- (void)setMaxBufferSize:(NSUInteger)maxBufferSize +{ + _maxBufferSize = maxBufferSize; + self.player.maxBufferSize = maxBufferSize; +} + +- (NSUInteger)maxBufferSize { + return _maxBufferSize; // Defaults to 0 +} + +- (void)setPlaybackRate:(double)playbackRate +{ + _playbackRate = playbackRate; + self.player.playbackRate = playbackRate; +} + +- (double)playbackRate +{ + if (!_initFinished) { + return 1.0; // Defaults to 1.0 + } + return _playbackRate; +} + +- (void)setPlaybackMode:(SDAnimatedImagePlaybackMode)playbackMode { + _playbackMode = playbackMode; + self.player.playbackMode = playbackMode; +} + +- (SDAnimatedImagePlaybackMode)playbackMode { + if (!_initFinished) { + return SDAnimatedImagePlaybackModeNormal; // Default mode is normal + } + return _playbackMode; +} + + +- (BOOL)shouldIncrementalLoad +{ + if (!_initFinished) { + return YES; // Defaults to YES + } + return _initFinished; +} + +#pragma mark - UIView Method Overrides +#pragma mark Observing View-Related Changes + +#if SD_MAC +- (void)viewDidMoveToSuperview +#else +- (void)didMoveToSuperview +#endif +{ +#if SD_MAC + [super viewDidMoveToSuperview]; +#else + [super didMoveToSuperview]; +#endif + + [self checkPlay]; +} + +#if SD_MAC +- (void)viewDidMoveToWindow +#else +- (void)didMoveToWindow +#endif +{ +#if SD_MAC + [super viewDidMoveToWindow]; +#else + [super didMoveToWindow]; +#endif + + [self checkPlay]; +} + +#if SD_MAC +- (void)setAlphaValue:(CGFloat)alphaValue +#else +- (void)setAlpha:(CGFloat)alpha +#endif +{ +#if SD_MAC + [super setAlphaValue:alphaValue]; +#else + [super setAlpha:alpha]; +#endif + + [self checkPlay]; +} + +- (void)setHidden:(BOOL)hidden +{ + [super setHidden:hidden]; + + [self checkPlay]; +} + +#pragma mark - UIImageView Method Overrides +#pragma mark Image Data + +- (void)setAnimationRepeatCount:(NSInteger)animationRepeatCount +{ +#if SD_UIKIT + [super setAnimationRepeatCount:animationRepeatCount]; +#else + _animationRepeatCount = animationRepeatCount; +#endif + + if (self.shouldCustomLoopCount) { + self.player.totalLoopCount = animationRepeatCount; + } +} + +- (void)startAnimating +{ + if (self.player) { + [self updateShouldAnimate]; + if (self.shouldAnimate) { + [self.player startPlaying]; + } + } else { +#if SD_UIKIT + [super startAnimating]; +#else + [super setAnimates:YES]; +#endif + } +} + +- (void)stopAnimating +{ + if (self.player) { + if (self.resetFrameIndexWhenStopped) { + [self.player stopPlaying]; + } else { + [self.player pausePlaying]; + } + if (self.clearBufferWhenStopped) { + [self.player clearFrameBuffer]; + } + } else { +#if SD_UIKIT + [super stopAnimating]; +#else + [super setAnimates:NO]; +#endif + } +} + +#if SD_UIKIT +- (BOOL)isAnimating +{ + if (self.player) { + return self.player.isPlaying; + } else { + return [super isAnimating]; + } +} +#endif + +#if SD_MAC +- (BOOL)animates +{ + if (self.player) { + return self.player.isPlaying; + } else { + return [super animates]; + } +} + +- (void)setAnimates:(BOOL)animates +{ + if (animates) { + [self startAnimating]; + } else { + [self stopAnimating]; + } +} +#endif + +#pragma mark Highlighted Image Unsupport + +- (void)setHighlighted:(BOOL)highlighted +{ + // Highlighted image is unsupported for animated images, but implementing it breaks the image view when embedded in a UICollectionViewCell. + if (!self.player) { + [super setHighlighted:highlighted]; + } +} + + +#pragma mark - Private Methods +#pragma mark Animation + +/// Check if it should be played +- (void)checkPlay +{ + // Only handle for SDAnimatedImage, leave UIAnimatedImage or animationImages for super implementation control + if (self.player && self.autoPlayAnimatedImage) { + [self updateShouldAnimate]; + if (self.shouldAnimate) { + [self startAnimating]; + } else { + [self stopAnimating]; + } + } +} + +// Don't repeatedly check our window & superview in `-displayDidRefresh:` for performance reasons. +// Just update our cached value whenever the animated image or visibility (window, superview, hidden, alpha) is changed. +- (void)updateShouldAnimate +{ +#if SD_MAC + BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alphaValue > 0.0; +#else + BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alpha > 0.0; +#endif + self.shouldAnimate = self.player && isVisible; +} + +// Update progressive status only after `setImage:` call. +- (void)updateIsProgressiveWithImage:(UIImage *)image +{ + self.isProgressive = NO; + if (!self.shouldIncrementalLoad) { + // Early return + return; + } + // We must use `image.class conformsToProtocol:` instead of `image conformsToProtocol:` here + // Because UIKit on macOS, using internal hard-coded override method, which returns NO + id currentAnimatedCoder = [self progressiveAnimatedCoderForImage:image]; + if (currentAnimatedCoder) { + UIImage *previousImage = self.image; + if (!previousImage) { + // If current animated coder supports progressive, and no previous image to check, start progressive loading + self.isProgressive = YES; + } else { + id previousAnimatedCoder = [self progressiveAnimatedCoderForImage:previousImage]; + if (previousAnimatedCoder == currentAnimatedCoder) { + // If current animated coder is the same as previous, start progressive loading + self.isProgressive = YES; + } + } + } +} + +// Check if image can represent a `Progressive Animated Image` during loading +- (id)progressiveAnimatedCoderForImage:(UIImage *)image +{ + if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)] && image.sd_isIncremental && [image respondsToSelector:@selector(animatedCoder)]) { + id animatedCoder = [(id)image animatedCoder]; + if ([animatedCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) { + return (id)animatedCoder; + } + } + return nil; +} + + +#pragma mark Providing the Layer's Content +#pragma mark - CALayerDelegate + +- (void)displayLayer:(CALayer *)layer +{ + UIImage *currentFrame = self.currentFrame; + if (currentFrame) { + layer.contentsScale = currentFrame.scale; + layer.contents = (__bridge id)currentFrame.CGImage; + } else { + // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering. + if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) { + [super displayLayer:layer]; + } + } +} + +#if SD_MAC +// NSImageView use a subview. We need this subview's layer for actual rendering. +// Why using this design may because of properties like `imageAlignment` and `imageScaling`, which it's not available for UIImageView.contentMode (it's impossible to align left and keep aspect ratio at the same time) +- (NSView *)imageView { + NSImageView *imageView = objc_getAssociatedObject(self, SD_SEL_SPI(imageView)); + if (!imageView) { + // macOS 10.14 + imageView = objc_getAssociatedObject(self, SD_SEL_SPI(imageSubview)); + } + return imageView; +} + +// on macOS, it's the imageView subview's layer (we use layer-hosting view to let CALayerDelegate works) +- (CALayer *)imageViewLayer { + NSView *imageView = self.imageView; + if (!imageView) { + return nil; + } + if (!_imageViewLayer) { + _imageViewLayer = [CALayer new]; + _imageViewLayer.delegate = self; + imageView.layer = _imageViewLayer; + imageView.wantsLayer = YES; + } + return _imageViewLayer; +} +#else +// on iOS, it's the imageView itself's layer +- (CALayer *)imageViewLayer { + return self.layer; +} + +#endif + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.h new file mode 100644 index 00000000..dc5e1fae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.h @@ -0,0 +1,145 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +@class SDImageCacheConfig; +/** + A protocol to allow custom disk cache used in SDImageCache. + */ +@protocol SDDiskCache + +// All of these method are called from the same global queue to avoid blocking on main queue and thread-safe problem. But it's also recommend to ensure thread-safe yourself using lock or other ways. +@required +/** + Create a new disk cache based on the specified path. You can check `maxDiskSize` and `maxDiskAge` used for disk cache. + + @param cachePath Full path of a directory in which the cache will write data. + Once initialized you should not read and write to this directory. + @param config The cache config to be used to create the cache. + + @return A new cache object, or nil if an error occurs. + */ +- (nullable instancetype)initWithCachePath:(nonnull NSString *)cachePath config:(nonnull SDImageCacheConfig *)config; + +/** + Returns a boolean value that indicates whether a given key is in cache. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the data. If nil, just return NO. + @return Whether the key is in cache. + */ +- (BOOL)containsDataForKey:(nonnull NSString *)key; + +/** + Returns the data associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the data. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable NSData *)dataForKey:(nonnull NSString *)key; + +/** + Sets the value of the specified key in the cache. + This method may blocks the calling thread until file write finished. + + @param data The data to be stored in the cache. + @param key The key with which to associate the value. If nil, this method has no effect. + */ +- (void)setData:(nullable NSData *)data forKey:(nonnull NSString *)key; + +/** + Returns the extended data associated with a given key. + This method may blocks the calling thread until file read finished. + + @param key A string identifying the data. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable NSData *)extendedDataForKey:(nonnull NSString *)key; + +/** + Set extended data with a given key. + + @discussion You can set any extended data to exist cache key. Without override the exist disk file data. + on UNIX, the common way for this is to use the Extended file attributes (xattr) + + @param extendedData The extended data (pass nil to remove). + @param key The key with which to associate the value. If nil, this method has no effect. +*/ +- (void)setExtendedData:(nullable NSData *)extendedData forKey:(nonnull NSString *)key; + +/** + Removes the value of the specified key in the cache. + This method may blocks the calling thread until file delete finished. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + */ +- (void)removeDataForKey:(nonnull NSString *)key; + +/** + Empties the cache. + This method may blocks the calling thread until file delete finished. + */ +- (void)removeAllData; + +/** + Removes the expired data from the cache. You can choose the data to remove base on `ageLimit`, `countLimit` and `sizeLimit` options. + */ +- (void)removeExpiredData; + +/** + The cache path for key + + @param key A string identifying the value + @return The cache path for key. Or nil if the key can not associate to a path + */ +- (nullable NSString *)cachePathForKey:(nonnull NSString *)key; + +/** + Returns the number of data in this cache. + This method may blocks the calling thread until file read finished. + + @return The total data count. + */ +- (NSUInteger)totalCount; + +/** + Returns the total size (in bytes) of data in this cache. + This method may blocks the calling thread until file read finished. + + @return The total data size in bytes. + */ +- (NSUInteger)totalSize; + +@end + +/** + The built-in disk cache. + */ +@interface SDDiskCache : NSObject +/** + Cache Config object - storing all kind of settings. + */ +@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config; + +- (nonnull instancetype)init NS_UNAVAILABLE; + +/** + Move the cache directory from old location to new location, the old location will be removed after finish. + If the old location does not exist, does nothing. + If the new location does not exist, only do a movement of directory. + If the new location does exist, will move and merge the files from old location. + If the new location does exist, but is not a directory, will remove it and do a movement of directory. + + @param srcPath old location of cache directory + @param dstPath new location of cache directory + */ +- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.m new file mode 100644 index 00000000..5f5d41a1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDDiskCache.m @@ -0,0 +1,326 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDDiskCache.h" +#import "SDImageCacheConfig.h" +#import "SDFileAttributeHelper.h" +#import + +static NSString * const SDDiskCacheExtendedAttributeName = @"com.hackemist.SDDiskCache"; + +@interface SDDiskCache () + +@property (nonatomic, copy) NSString *diskCachePath; +@property (nonatomic, strong, nonnull) NSFileManager *fileManager; + +@end + +@implementation SDDiskCache + +- (instancetype)init { + NSAssert(NO, @"Use `initWithCachePath:` with the disk cache path"); + return nil; +} + +#pragma mark - SDcachePathForKeyDiskCache Protocol +- (instancetype)initWithCachePath:(NSString *)cachePath config:(nonnull SDImageCacheConfig *)config { + if (self = [super init]) { + _diskCachePath = cachePath; + _config = config; + [self commonInit]; + } + return self; +} + +- (void)commonInit { + if (self.config.fileManager) { + self.fileManager = self.config.fileManager; + } else { + self.fileManager = [NSFileManager new]; + } +} + +- (BOOL)containsDataForKey:(NSString *)key { + NSParameterAssert(key); + NSString *filePath = [self cachePathForKey:key]; + BOOL exists = [self.fileManager fileExistsAtPath:filePath]; + + // fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name + // checking the key with and without the extension + if (!exists) { + exists = [self.fileManager fileExistsAtPath:filePath.stringByDeletingPathExtension]; + } + + return exists; +} + +- (NSData *)dataForKey:(NSString *)key { + NSParameterAssert(key); + NSString *filePath = [self cachePathForKey:key]; + NSData *data = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil]; + if (data) { + return data; + } + + // fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name + // checking the key with and without the extension + data = [NSData dataWithContentsOfFile:filePath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil]; + if (data) { + return data; + } + + return nil; +} + +- (void)setData:(NSData *)data forKey:(NSString *)key { + NSParameterAssert(data); + NSParameterAssert(key); + if (![self.fileManager fileExistsAtPath:self.diskCachePath]) { + [self.fileManager createDirectoryAtPath:self.diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + + // get cache Path for image key + NSString *cachePathForKey = [self cachePathForKey:key]; + // transform to NSURL + NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey]; + + [data writeToURL:fileURL options:self.config.diskCacheWritingOptions error:nil]; + + // disable iCloud backup + if (self.config.shouldDisableiCloud) { + // ignore iCloud backup resource value error + [fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil]; + } +} + +- (NSData *)extendedDataForKey:(NSString *)key { + NSParameterAssert(key); + + // get cache Path for image key + NSString *cachePathForKey = [self cachePathForKey:key]; + + NSData *extendedData = [SDFileAttributeHelper extendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil]; + + return extendedData; +} + +- (void)setExtendedData:(NSData *)extendedData forKey:(NSString *)key { + NSParameterAssert(key); + // get cache Path for image key + NSString *cachePathForKey = [self cachePathForKey:key]; + + if (!extendedData) { + // Remove + [SDFileAttributeHelper removeExtendedAttribute:SDDiskCacheExtendedAttributeName atPath:cachePathForKey traverseLink:NO error:nil]; + } else { + // Override + [SDFileAttributeHelper setExtendedAttribute:SDDiskCacheExtendedAttributeName value:extendedData atPath:cachePathForKey traverseLink:NO overwrite:YES error:nil]; + } +} + +- (void)removeDataForKey:(NSString *)key { + NSParameterAssert(key); + NSString *filePath = [self cachePathForKey:key]; + [self.fileManager removeItemAtPath:filePath error:nil]; +} + +- (void)removeAllData { + [self.fileManager removeItemAtPath:self.diskCachePath error:nil]; + [self.fileManager createDirectoryAtPath:self.diskCachePath + withIntermediateDirectories:YES + attributes:nil + error:NULL]; +} + +- (void)removeExpiredData { + NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; + + // Compute content date key to be used for tests + NSURLResourceKey cacheContentDateKey = NSURLContentModificationDateKey; + switch (self.config.diskCacheExpireType) { + case SDImageCacheConfigExpireTypeAccessDate: + cacheContentDateKey = NSURLContentAccessDateKey; + break; + case SDImageCacheConfigExpireTypeModificationDate: + cacheContentDateKey = NSURLContentModificationDateKey; + break; + case SDImageCacheConfigExpireTypeCreationDate: + cacheContentDateKey = NSURLCreationDateKey; + break; + case SDImageCacheConfigExpireTypeChangeDate: + cacheContentDateKey = NSURLAttributeModificationDateKey; + break; + default: + break; + } + + NSArray *resourceKeys = @[NSURLIsDirectoryKey, cacheContentDateKey, NSURLTotalFileAllocatedSizeKey]; + + // This enumerator prefetches useful properties for our cache files. + NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtURL:diskCacheURL + includingPropertiesForKeys:resourceKeys + options:NSDirectoryEnumerationSkipsHiddenFiles + errorHandler:NULL]; + + NSDate *expirationDate = (self.config.maxDiskAge < 0) ? nil: [NSDate dateWithTimeIntervalSinceNow:-self.config.maxDiskAge]; + NSMutableDictionary *> *cacheFiles = [NSMutableDictionary dictionary]; + NSUInteger currentCacheSize = 0; + + // Enumerate all of the files in the cache directory. This loop has two purposes: + // + // 1. Removing files that are older than the expiration date. + // 2. Storing file attributes for the size-based cleanup pass. + NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; + for (NSURL *fileURL in fileEnumerator) { + NSError *error; + NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:&error]; + + // Skip directories and errors. + if (error || !resourceValues || [resourceValues[NSURLIsDirectoryKey] boolValue]) { + continue; + } + + // Remove files that are older than the expiration date; + NSDate *modifiedDate = resourceValues[cacheContentDateKey]; + if (expirationDate && [[modifiedDate laterDate:expirationDate] isEqualToDate:expirationDate]) { + [urlsToDelete addObject:fileURL]; + continue; + } + + // Store a reference to this file and account for its total size. + NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; + currentCacheSize += totalAllocatedSize.unsignedIntegerValue; + cacheFiles[fileURL] = resourceValues; + } + + for (NSURL *fileURL in urlsToDelete) { + [self.fileManager removeItemAtURL:fileURL error:nil]; + } + + // If our remaining disk cache exceeds a configured maximum size, perform a second + // size-based cleanup pass. We delete the oldest files first. + NSUInteger maxDiskSize = self.config.maxDiskSize; + if (maxDiskSize > 0 && currentCacheSize > maxDiskSize) { + // Target half of our maximum cache size for this cleanup pass. + const NSUInteger desiredCacheSize = maxDiskSize / 2; + + // Sort the remaining cache files by their last modification time or last access time (oldest first). + NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent + usingComparator:^NSComparisonResult(id obj1, id obj2) { + return [obj1[cacheContentDateKey] compare:obj2[cacheContentDateKey]]; + }]; + + // Delete files until we fall below our desired cache size. + for (NSURL *fileURL in sortedFiles) { + if ([self.fileManager removeItemAtURL:fileURL error:nil]) { + NSDictionary *resourceValues = cacheFiles[fileURL]; + NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; + currentCacheSize -= totalAllocatedSize.unsignedIntegerValue; + + if (currentCacheSize < desiredCacheSize) { + break; + } + } + } + } +} + +- (nullable NSString *)cachePathForKey:(NSString *)key { + NSParameterAssert(key); + return [self cachePathForKey:key inPath:self.diskCachePath]; +} + +- (NSUInteger)totalSize { + NSUInteger size = 0; + NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtPath:self.diskCachePath]; + for (NSString *fileName in fileEnumerator) { + NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName]; + NSDictionary *attrs = [self.fileManager attributesOfItemAtPath:filePath error:nil]; + size += [attrs fileSize]; + } + return size; +} + +- (NSUInteger)totalCount { + NSUInteger count = 0; + NSDirectoryEnumerator *fileEnumerator = [self.fileManager enumeratorAtPath:self.diskCachePath]; + count = fileEnumerator.allObjects.count; + return count; +} + +#pragma mark - Cache paths + +- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path { + NSString *filename = SDDiskCacheFileNameForKey(key); + return [path stringByAppendingPathComponent:filename]; +} + +- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath { + NSParameterAssert(srcPath); + NSParameterAssert(dstPath); + // Check if old path is equal to new path + if ([srcPath isEqualToString:dstPath]) { + return; + } + BOOL isDirectory; + // Check if old path is directory + if (![self.fileManager fileExistsAtPath:srcPath isDirectory:&isDirectory] || !isDirectory) { + return; + } + // Check if new path is directory + if (![self.fileManager fileExistsAtPath:dstPath isDirectory:&isDirectory] || !isDirectory) { + if (!isDirectory) { + // New path is not directory, remove file + [self.fileManager removeItemAtPath:dstPath error:nil]; + } + NSString *dstParentPath = [dstPath stringByDeletingLastPathComponent]; + // Creates any non-existent parent directories as part of creating the directory in path + if (![self.fileManager fileExistsAtPath:dstParentPath]) { + [self.fileManager createDirectoryAtPath:dstParentPath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + // New directory does not exist, rename directory + [self.fileManager moveItemAtPath:srcPath toPath:dstPath error:nil]; + } else { + // New directory exist, merge the files + NSDirectoryEnumerator *dirEnumerator = [self.fileManager enumeratorAtPath:srcPath]; + NSString *file; + while ((file = [dirEnumerator nextObject])) { + [self.fileManager moveItemAtPath:[srcPath stringByAppendingPathComponent:file] toPath:[dstPath stringByAppendingPathComponent:file] error:nil]; + } + // Remove the old path + [self.fileManager removeItemAtPath:srcPath error:nil]; + } +} + +#pragma mark - Hash + +#define SD_MAX_FILE_EXTENSION_LENGTH (NAME_MAX - CC_MD5_DIGEST_LENGTH * 2 - 1) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +static inline NSString * _Nonnull SDDiskCacheFileNameForKey(NSString * _Nullable key) { + const char *str = key.UTF8String; + if (str == NULL) { + str = ""; + } + unsigned char r[CC_MD5_DIGEST_LENGTH]; + CC_MD5(str, (CC_LONG)strlen(str), r); + NSURL *keyURL = [NSURL URLWithString:key]; + NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension; + // File system has file name length limit, we need to check if ext is too long, we don't add it to the filename + if (ext.length > SD_MAX_FILE_EXTENSION_LENGTH) { + ext = nil; + } + NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@", + r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], + r[11], r[12], r[13], r[14], r[15], ext.length == 0 ? @"" : [NSString stringWithFormat:@".%@", ext]]; + return filename; +} +#pragma clang diagnostic pop + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.h new file mode 100644 index 00000000..900acd76 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.h @@ -0,0 +1,73 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDWebImageCompat.h" + +/** + These following class are provided to use `UIGraphicsImageRenderer` with polyfill, which allows write cross-platform(AppKit/UIKit) code and avoid runtime version check. + Compared to `UIGraphicsBeginImageContext`, `UIGraphicsImageRenderer` use dynamic bitmap from your draw code to generate CGContext, not always use ARGB8888, which is more performant on RAM usage. + Which means, if you draw CGImage/CIImage which contains grayscale only, the underlaying bitmap context use grayscale, it's managed by system and not a fixed type. (actually, the `kCGContextTypeAutomatic`) + For usage, See more in Apple's documentation: https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer + For UIKit on iOS/tvOS 10+, these method just use the same `UIGraphicsImageRenderer` API. + For others (macOS/watchOS or iOS/tvOS 10-), these method use the `SDImageGraphics.h` to implements the same behavior (but without dynamic bitmap support) +*/ + +typedef void (^SDGraphicsImageDrawingActions)(CGContextRef _Nonnull context); +typedef NS_ENUM(NSInteger, SDGraphicsImageRendererFormatRange) { + SDGraphicsImageRendererFormatRangeUnspecified = -1, + SDGraphicsImageRendererFormatRangeAutomatic = 0, + SDGraphicsImageRendererFormatRangeExtended, + SDGraphicsImageRendererFormatRangeStandard +}; + +/// A set of drawing attributes that represent the configuration of an image renderer context. +@interface SDGraphicsImageRendererFormat : NSObject + +/// The display scale of the image renderer context. +/// The default value is equal to the scale of the main screen. +@property (nonatomic) CGFloat scale; + +/// A Boolean value indicating whether the underlying Core Graphics context has an alpha channel. +/// The default value is NO. +@property (nonatomic) BOOL opaque; + +/// Specifying whether the bitmap context should use extended color. +/// For iOS 12+, the value is from system `preferredRange` property +/// For iOS 10-11, the value is from system `prefersExtendedRange` property +/// For iOS 9-, the value is `.standard` +@property (nonatomic) SDGraphicsImageRendererFormatRange preferredRange; + +/// Init the default format. See each properties's default value. +- (nonnull instancetype)init; + +/// Returns a new format best suited for the main screen’s current configuration. ++ (nonnull instancetype)preferredFormat; + +@end + +/// A graphics renderer for creating Core Graphics-backed images. +@interface SDGraphicsImageRenderer : NSObject + +/// Creates an image renderer for drawing images of a given size. +/// @param size The size of images output from the renderer, specified in points. +/// @return An initialized image renderer. +- (nonnull instancetype)initWithSize:(CGSize)size; + +/// Creates a new image renderer with a given size and format. +/// @param size The size of images output from the renderer, specified in points. +/// @param format A SDGraphicsImageRendererFormat object that encapsulates the format used to create the renderer context. +/// @return An initialized image renderer. +- (nonnull instancetype)initWithSize:(CGSize)size format:(nonnull SDGraphicsImageRendererFormat *)format; + +/// Creates an image by following a set of drawing instructions. +/// @param actions A SDGraphicsImageDrawingActions block that, when invoked by the renderer, executes a set of drawing instructions to create the output image. +/// @note You should not retain or use the context outside the block, it's non-escaping. +/// @return A UIImage object created by the supplied drawing actions. +- (nonnull UIImage *)imageWithActions:(nonnull NS_NOESCAPE SDGraphicsImageDrawingActions)actions; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.m new file mode 100644 index 00000000..03aef3a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDGraphicsImageRenderer.m @@ -0,0 +1,244 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDGraphicsImageRenderer.h" +#import "SDImageGraphics.h" + +@interface SDGraphicsImageRendererFormat () +#if SD_UIKIT +@property (nonatomic, strong) UIGraphicsImageRendererFormat *uiformat API_AVAILABLE(ios(10.0), tvos(10.0)); +#endif +@end + +@implementation SDGraphicsImageRendererFormat +@synthesize scale = _scale; +@synthesize opaque = _opaque; +@synthesize preferredRange = _preferredRange; + +#pragma mark - Property +- (CGFloat)scale { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + return self.uiformat.scale; + } else { + return _scale; + } +#else + return _scale; +#endif +} + +- (void)setScale:(CGFloat)scale { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + self.uiformat.scale = scale; + } else { + _scale = scale; + } +#else + _scale = scale; +#endif +} + +- (BOOL)opaque { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + return self.uiformat.opaque; + } else { + return _opaque; + } +#else + return _opaque; +#endif +} + +- (void)setOpaque:(BOOL)opaque { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + self.uiformat.opaque = opaque; + } else { + _opaque = opaque; + } +#else + _opaque = opaque; +#endif +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (SDGraphicsImageRendererFormatRange)preferredRange { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + if (@available(iOS 12.0, tvOS 12.0, *)) { + return (SDGraphicsImageRendererFormatRange)self.uiformat.preferredRange; + } else { + BOOL prefersExtendedRange = self.uiformat.prefersExtendedRange; + if (prefersExtendedRange) { + return SDGraphicsImageRendererFormatRangeExtended; + } else { + return SDGraphicsImageRendererFormatRangeStandard; + } + } + } else { + return _preferredRange; + } +#else + return _preferredRange; +#endif +} + +- (void)setPreferredRange:(SDGraphicsImageRendererFormatRange)preferredRange { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + if (@available(iOS 12.0, tvOS 12.0, *)) { + self.uiformat.preferredRange = (UIGraphicsImageRendererFormatRange)preferredRange; + } else { + switch (preferredRange) { + case SDGraphicsImageRendererFormatRangeExtended: + self.uiformat.prefersExtendedRange = YES; + break; + case SDGraphicsImageRendererFormatRangeStandard: + self.uiformat.prefersExtendedRange = NO; + default: + // Automatic means default + break; + } + } + } else { + _preferredRange = preferredRange; + } +#else + _preferredRange = preferredRange; +#endif +} +#pragma clang diagnostic pop + +- (instancetype)init { + self = [super init]; + if (self) { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.10, *)) { + UIGraphicsImageRendererFormat *uiformat = [[UIGraphicsImageRendererFormat alloc] init]; + self.uiformat = uiformat; + } else { +#endif +#if SD_WATCH + CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale; +#elif SD_UIKIT + CGFloat screenScale = [UIScreen mainScreen].scale; +#elif SD_MAC + CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor; +#endif + self.scale = screenScale; + self.opaque = NO; + self.preferredRange = SDGraphicsImageRendererFormatRangeStandard; +#if SD_UIKIT + } +#endif + } + return self; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +- (instancetype)initForMainScreen { + self = [super init]; + if (self) { +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.0, *)) { + UIGraphicsImageRendererFormat *uiformat; + // iOS 11.0.0 GM does have `preferredFormat`, but iOS 11 betas did not (argh!) + if ([UIGraphicsImageRenderer respondsToSelector:@selector(preferredFormat)]) { + uiformat = [UIGraphicsImageRendererFormat preferredFormat]; + } else { + uiformat = [UIGraphicsImageRendererFormat defaultFormat]; + } + self.uiformat = uiformat; + } else { +#endif +#if SD_WATCH + CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale; +#elif SD_UIKIT + CGFloat screenScale = [UIScreen mainScreen].scale; +#elif SD_MAC + CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor; +#endif + self.scale = screenScale; + self.opaque = NO; + self.preferredRange = SDGraphicsImageRendererFormatRangeStandard; +#if SD_UIKIT + } +#endif + } + return self; +} +#pragma clang diagnostic pop + ++ (instancetype)preferredFormat { + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] initForMainScreen]; + return format; +} + +@end + +@interface SDGraphicsImageRenderer () +@property (nonatomic, assign) CGSize size; +@property (nonatomic, strong) SDGraphicsImageRendererFormat *format; +#if SD_UIKIT +@property (nonatomic, strong) UIGraphicsImageRenderer *uirenderer API_AVAILABLE(ios(10.0), tvos(10.0)); +#endif +@end + +@implementation SDGraphicsImageRenderer + +- (instancetype)initWithSize:(CGSize)size { + return [self initWithSize:size format:SDGraphicsImageRendererFormat.preferredFormat]; +} + +- (instancetype)initWithSize:(CGSize)size format:(SDGraphicsImageRendererFormat *)format { + NSParameterAssert(format); + self = [super init]; + if (self) { + self.size = size; + self.format = format; +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.0, *)) { + UIGraphicsImageRendererFormat *uiformat = format.uiformat; + self.uirenderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:uiformat]; + } +#endif + } + return self; +} + +- (UIImage *)imageWithActions:(NS_NOESCAPE SDGraphicsImageDrawingActions)actions { + NSParameterAssert(actions); +#if SD_UIKIT + if (@available(iOS 10.0, tvOS 10.0, *)) { + UIGraphicsImageDrawingActions uiactions = ^(UIGraphicsImageRendererContext *rendererContext) { + if (actions) { + actions(rendererContext.CGContext); + } + }; + return [self.uirenderer imageWithActions:uiactions]; + } else { +#endif + SDGraphicsBeginImageContextWithOptions(self.size, self.format.opaque, self.format.scale); + CGContextRef context = SDGraphicsGetCurrentContext(); + if (actions) { + actions(context); + } + UIImage *image = SDGraphicsGetImageFromCurrentImageContext(); + SDGraphicsEndImageContext(); + return image; +#if SD_UIKIT + } +#endif +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.h new file mode 100644 index 00000000..f73742cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.h @@ -0,0 +1,19 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageIOAnimatedCoder.h" + +/** + Built in coder using ImageIO that supports APNG encoding/decoding + */ +@interface SDImageAPNGCoder : SDImageIOAnimatedCoder + +@property (nonatomic, class, readonly, nonnull) SDImageAPNGCoder *sharedCoder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.m new file mode 100644 index 00000000..b262bd3b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAPNGCoder.m @@ -0,0 +1,58 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageAPNGCoder.h" +#import "SDImageIOAnimatedCoderInternal.h" +#if SD_MAC +#import +#else +#import +#endif + +@implementation SDImageAPNGCoder + ++ (instancetype)sharedCoder { + static SDImageAPNGCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageAPNGCoder alloc] init]; + }); + return coder; +} + +#pragma mark - Subclass Override + ++ (SDImageFormat)imageFormat { + return SDImageFormatPNG; +} + ++ (NSString *)imageUTType { + return (__bridge NSString *)kSDUTTypePNG; +} + ++ (NSString *)dictionaryProperty { + return (__bridge NSString *)kCGImagePropertyPNGDictionary; +} + ++ (NSString *)unclampedDelayTimeProperty { + return (__bridge NSString *)kCGImagePropertyAPNGUnclampedDelayTime; +} + ++ (NSString *)delayTimeProperty { + return (__bridge NSString *)kCGImagePropertyAPNGDelayTime; +} + ++ (NSString *)loopCountProperty { + return (__bridge NSString *)kCGImagePropertyAPNGLoopCount; +} + ++ (NSUInteger)defaultLoopCount { + return 0; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.h new file mode 100644 index 00000000..4b585a99 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.h @@ -0,0 +1,23 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageIOAnimatedCoder.h" + +/** + This coder is used for Google WebP and Animated WebP(AWebP) image format. + Image/IO provide the WebP decoding support in iOS 14/macOS 11/tvOS 14/watchOS 7+. + @note Currently Image/IO seems does not supports WebP encoding, if you need WebP encoding, use the custom codec below. + @note If you need to support lower firmware version for WebP, you can have a try at https://github.com/SDWebImage/SDWebImageWebPCoder + */ +API_AVAILABLE(ios(14.0), tvos(14.0), macos(11.0), watchos(7.0)) +@interface SDImageAWebPCoder : SDImageIOAnimatedCoder + +@property (nonatomic, class, readonly, nonnull) SDImageAWebPCoder *sharedCoder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.m new file mode 100644 index 00000000..e58bc215 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageAWebPCoder.m @@ -0,0 +1,98 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDImageAWebPCoder.h" +#import "SDImageIOAnimatedCoderInternal.h" + +// These constants are available from iOS 14+ and Xcode 12. This raw value is used for toolchain and firmware compatibility +static NSString * kSDCGImagePropertyWebPDictionary = @"{WebP}"; +static NSString * kSDCGImagePropertyWebPLoopCount = @"LoopCount"; +static NSString * kSDCGImagePropertyWebPDelayTime = @"DelayTime"; +static NSString * kSDCGImagePropertyWebPUnclampedDelayTime = @"UnclampedDelayTime"; + +@implementation SDImageAWebPCoder + ++ (void)initialize { +#if __IPHONE_14_0 || __TVOS_14_0 || __MAC_11_0 || __WATCHOS_7_0 + // Xcode 12 + if (@available(iOS 14, tvOS 14, macOS 11, watchOS 7, *)) { + // Use SDK instead of raw value + kSDCGImagePropertyWebPDictionary = (__bridge NSString *)kCGImagePropertyWebPDictionary; + kSDCGImagePropertyWebPLoopCount = (__bridge NSString *)kCGImagePropertyWebPLoopCount; + kSDCGImagePropertyWebPDelayTime = (__bridge NSString *)kCGImagePropertyWebPDelayTime; + kSDCGImagePropertyWebPUnclampedDelayTime = (__bridge NSString *)kCGImagePropertyWebPUnclampedDelayTime; + } +#endif +} + ++ (instancetype)sharedCoder { + static SDImageAWebPCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageAWebPCoder alloc] init]; + }); + return coder; +} + +#pragma mark - SDImageCoder + +- (BOOL)canDecodeFromData:(nullable NSData *)data { + switch ([NSData sd_imageFormatForImageData:data]) { + case SDImageFormatWebP: + // Check WebP decoding compatibility + return [self.class canDecodeFromFormat:SDImageFormatWebP]; + default: + return NO; + } +} + +- (BOOL)canIncrementalDecodeFromData:(NSData *)data { + return [self canDecodeFromData:data]; +} + +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + switch (format) { + case SDImageFormatWebP: + // Check WebP encoding compatibility + return [self.class canEncodeToFormat:SDImageFormatWebP]; + default: + return NO; + } +} + +#pragma mark - Subclass Override + ++ (SDImageFormat)imageFormat { + return SDImageFormatWebP; +} + ++ (NSString *)imageUTType { + return (__bridge NSString *)kSDUTTypeWebP; +} + ++ (NSString *)dictionaryProperty { + return kSDCGImagePropertyWebPDictionary; +} + ++ (NSString *)unclampedDelayTimeProperty { + return kSDCGImagePropertyWebPUnclampedDelayTime; +} + ++ (NSString *)delayTimeProperty { + return kSDCGImagePropertyWebPDelayTime; +} + ++ (NSString *)loopCountProperty { + return kSDCGImagePropertyWebPLoopCount; +} + ++ (NSUInteger)defaultLoopCount { + return 0; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.h new file mode 100644 index 00000000..ad3afd53 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.h @@ -0,0 +1,422 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" +#import "SDImageCacheConfig.h" +#import "SDImageCacheDefine.h" +#import "SDMemoryCache.h" +#import "SDDiskCache.h" + +/// Image Cache Options +typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) { + /** + * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDImageCacheQueryMemoryDataSync` + */ + SDImageCacheQueryMemoryData = 1 << 0, + /** + * By default, when you only specify `SDImageCacheQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously. + */ + SDImageCacheQueryMemoryDataSync = 1 << 1, + /** + * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously. + @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page. + */ + SDImageCacheQueryDiskDataSync = 1 << 2, + /** + * By default, images are decoded respecting their original size. On iOS, this flag will scale down the + * images to a size compatible with the constrained memory of devices. + */ + SDImageCacheScaleDownLargeImages = 1 << 3, + /** + * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation. + * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image. + */ + SDImageCacheAvoidDecodeImage = 1 << 4, + /** + * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image. + */ + SDImageCacheDecodeFirstFrameOnly = 1 << 5, + /** + * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from disk cache + */ + SDImageCachePreloadAllFrames = 1 << 6, + /** + * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution. + * Using this option, can ensure we always produce image with your provided class. If failed, an error with code `SDWebImageErrorBadImageData` will be used. + * Note this options is not compatible with `SDImageCacheDecodeFirstFrameOnly`, which always produce a UIImage/NSImage. + */ + SDImageCacheMatchAnimatedImageClass = 1 << 7, +}; + +/** + * SDImageCache maintains a memory cache and a disk cache. Disk cache write operations are performed + * asynchronous so it doesn’t add unnecessary latency to the UI. + */ +@interface SDImageCache : NSObject + +#pragma mark - Properties + +/** + * Cache Config object - storing all kind of settings. + * The property is copy so change of current config will not accidentally affect other cache's config. + */ +@property (nonatomic, copy, nonnull, readonly) SDImageCacheConfig *config; + +/** + * The memory cache implementation object used for current image cache. + * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method. + * @note To customize this class, check `SDImageCacheConfig.memoryCacheClass` property. + */ +@property (nonatomic, strong, readonly, nonnull) id memoryCache; + +/** + * The disk cache implementation object used for current image cache. + * By default we use `SDMemoryCache` class, you can also use this to call your own implementation class method. + * @note To customize this class, check `SDImageCacheConfig.diskCacheClass` property. + * @warning When calling method about read/write in disk cache, be sure to either make your disk cache implementation IO-safe or using the same access queue to avoid issues. + */ +@property (nonatomic, strong, readonly, nonnull) id diskCache; + +/** + * The disk cache's root path + */ +@property (nonatomic, copy, nonnull, readonly) NSString *diskCachePath; + +/** + * The additional disk cache path to check if the query from disk cache not exist; + * The `key` param is the image cache key. The returned file path will be used to load the disk cache. If return nil, ignore it. + * Useful if you want to bundle pre-loaded images with your app + */ +@property (nonatomic, copy, nullable) SDImageCacheAdditionalCachePathBlock additionalCachePathBlock; + +#pragma mark - Singleton and initialization + +/** + * Returns global shared cache instance + */ +@property (nonatomic, class, readonly, nonnull) SDImageCache *sharedImageCache; + +/** + * Control the default disk cache directory. This will effect all the SDImageCache instance created after modification, even for shared image cache. + * This can be used to share the same disk cache with the App and App Extension (Today/Notification Widget) using `- [NSFileManager.containerURLForSecurityApplicationGroupIdentifier:]`. + * @note If you pass nil, the value will be reset to `~/Library/Caches/com.hackemist.SDImageCache`. + * @note We still preserve the `namespace` arg, which means, if you change this property into `/path/to/use`, the `SDImageCache.sharedImageCache.diskCachePath` should be `/path/to/use/default` because shared image cache use `default` as namespace. + * Defaults to nil. + */ +@property (nonatomic, class, readwrite, null_resettable) NSString *defaultDiskCacheDirectory; + +/** + * Init a new cache store with a specific namespace + * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/) + * + * @param ns The namespace to use for this cache store + */ +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns; + +/** + * Init a new cache store with a specific namespace and directory. + * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/) + * + * @param ns The namespace to use for this cache store + * @param directory Directory to cache disk images in + */ +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns + diskCacheDirectory:(nullable NSString *)directory; + +/** + * Init a new cache store with a specific namespace, directory and config. + * The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/) + * + * @param ns The namespace to use for this cache store + * @param directory Directory to cache disk images in + * @param config The cache config to be used to create the cache. You can provide custom memory cache or disk cache class in the cache config + */ +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns + diskCacheDirectory:(nullable NSString *)directory + config:(nullable SDImageCacheConfig *)config NS_DESIGNATED_INITIALIZER; + +#pragma mark - Cache paths + +/** + Get the cache path for a certain key + + @param key The unique image cache key + @return The cache path. You can check `lastPathComponent` to grab the file name. + */ +- (nullable NSString *)cachePathForKey:(nullable NSString *)key; + +#pragma mark - Store Ops + +/** + * Asynchronously store an image into memory and disk cache at the given key. + * + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL + * @param completionBlock A block executed after the operation is finished + */ +- (void)storeImage:(nullable UIImage *)image + forKey:(nullable NSString *)key + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +/** + * Asynchronously store an image into memory and disk cache at the given key. + * + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL + * @param toDisk Store the image to disk cache if YES. If NO, the completion block is called synchronously + * @param completionBlock A block executed after the operation is finished + * @note If no image data is provided and encode to disk, we will try to detect the image format (using either `sd_imageFormat` or `SDAnimatedImage` protocol method) and animation status, to choose the best matched format, including GIF, JPEG or PNG. + */ +- (void)storeImage:(nullable UIImage *)image + forKey:(nullable NSString *)key + toDisk:(BOOL)toDisk + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +/** + * Asynchronously store an image into memory and disk cache at the given key. + * + * @param image The image to store + * @param imageData The image data as returned by the server, this representation will be used for disk storage + * instead of converting the given image object into a storable/compressed image format in order + * to save quality and CPU + * @param key The unique image cache key, usually it's image absolute URL + * @param toDisk Store the image to disk cache if YES. If NO, the completion block is called synchronously + * @param completionBlock A block executed after the operation is finished + * @note If no image data is provided and encode to disk, we will try to detect the image format (using either `sd_imageFormat` or `SDAnimatedImage` protocol method) and animation status, to choose the best matched format, including GIF, JPEG or PNG. + */ +- (void)storeImage:(nullable UIImage *)image + imageData:(nullable NSData *)imageData + forKey:(nullable NSString *)key + toDisk:(BOOL)toDisk + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +/** + * Synchronously store image into memory cache at the given key. + * + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL + */ +- (void)storeImageToMemory:(nullable UIImage*)image + forKey:(nullable NSString *)key; + +/** + * Synchronously store image data into disk cache at the given key. + * + * @param imageData The image data to store + * @param key The unique image cache key, usually it's image absolute URL + */ +- (void)storeImageDataToDisk:(nullable NSData *)imageData + forKey:(nullable NSString *)key; + + +#pragma mark - Contains and Check Ops + +/** + * Asynchronously check if image exists in disk cache already (does not load the image) + * + * @param key the key describing the url + * @param completionBlock the block to be executed when the check is done. + * @note the completion block will be always executed on the main queue + */ +- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDImageCacheCheckCompletionBlock)completionBlock; + +/** + * Synchronously check if image data exists in disk cache already (does not load the image) + * + * @param key the key describing the url + */ +- (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key; + +#pragma mark - Query and Retrieve Ops + +/** + * Synchronously query the image data for the given key in disk cache. You can decode the image data to image after loaded. + * + * @param key The unique key used to store the wanted image + * @return The image data for the given key, or nil if not found. + */ +- (nullable NSData *)diskImageDataForKey:(nullable NSString *)key; + +/** + * Asynchronously query the image data for the given key in disk cache. You can decode the image data to image after loaded. + * + * @param key The unique key used to store the wanted image + * @param completionBlock the block to be executed when the query is done. + * @note the completion block will be always executed on the main queue + */ +- (void)diskImageDataQueryForKey:(nullable NSString *)key completion:(nullable SDImageCacheQueryDataCompletionBlock)completionBlock; + +/** + * Asynchronously queries the cache with operation and call the completion when done. + * + * @param key The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`. + * @param doneBlock The completion block. Will not get called if the operation is cancelled + * + * @return a NSOperation instance containing the cache op + */ +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDImageCacheQueryCompletionBlock)doneBlock; + +/** + * Asynchronously queries the cache with operation and call the completion when done. + * + * @param key The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`. + * @param options A mask to specify options to use for this cache query + * @param doneBlock The completion block. Will not get called if the operation is cancelled + * + * @return a NSOperation instance containing the cache op + */ +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDImageCacheQueryCompletionBlock)doneBlock; + +/** + * Asynchronously queries the cache with operation and call the completion when done. + * + * @param key The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`. + * @param options A mask to specify options to use for this cache query + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param doneBlock The completion block. Will not get called if the operation is cancelled + * + * @return a NSOperation instance containing the cache op + */ +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock; + +/** + * Asynchronously queries the cache with operation and call the completion when done. + * + * @param key The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`. + * @param options A mask to specify options to use for this cache query + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param queryCacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediately. + * @param doneBlock The completion block. Will not get called if the operation is cancelled + * + * @return a NSOperation instance containing the cache op + */ +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock; + +/** + * Synchronously query the memory cache. + * + * @param key The unique key used to store the image + * @return The image for the given key, or nil if not found. + */ +- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key; + +/** + * Synchronously query the disk cache. + * + * @param key The unique key used to store the image + * @return The image for the given key, or nil if not found. + */ +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key; + +/** + * Synchronously query the disk cache. With the options and context which may effect the image generation. (Such as transformer, animated image, thumbnail, etc) + * + * @param key The unique key used to store the image + * @param options A mask to specify options to use for this cache query + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @return The image for the given key, or nil if not found. + */ +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context; + +/** + * Synchronously query the cache (memory and or disk) after checking the memory cache. + * + * @param key The unique key used to store the image + * @return The image for the given key, or nil if not found. + */ +- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key; + +/** + * Synchronously query the cache (memory and or disk) after checking the memory cache. With the options and context which may effect the image generation. (Such as transformer, animated image, thumbnail, etc) + * + * @param key The unique key used to store the image + * @param options A mask to specify options to use for this cache query + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @return The image for the given key, or nil if not found. + */ +- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context; + +#pragma mark - Remove Ops + +/** + * Asynchronously remove the image from memory and disk cache + * + * @param key The unique image cache key + * @param completion A block that should be executed after the image has been removed (optional) + */ +- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion; + +/** + * Asynchronously remove the image from memory and optionally disk cache + * + * @param key The unique image cache key + * @param fromDisk Also remove cache entry from disk if YES. If NO, the completion block is called synchronously + * @param completion A block that should be executed after the image has been removed (optional) + */ +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion; + +/** + Synchronously remove the image from memory cache. + + @param key The unique image cache key + */ +- (void)removeImageFromMemoryForKey:(nullable NSString *)key; + +/** + Synchronously remove the image from disk cache. + + @param key The unique image cache key + */ +- (void)removeImageFromDiskForKey:(nullable NSString *)key; + +#pragma mark - Cache clean Ops + +/** + * Synchronously Clear all memory cached images + */ +- (void)clearMemory; + +/** + * Asynchronously clear all disk cached images. Non-blocking method - returns immediately. + * @param completion A block that should be executed after cache expiration completes (optional) + */ +- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion; + +/** + * Asynchronously remove all expired cached image from disk. Non-blocking method - returns immediately. + * @param completionBlock A block that should be executed after cache expiration completes (optional) + */ +- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock; + +#pragma mark - Cache Info + +/** + * Get the total bytes size of images in the disk cache + */ +- (NSUInteger)totalDiskSize; + +/** + * Get the number of images in the disk cache + */ +- (NSUInteger)totalDiskCount; + +/** + * Asynchronously calculate the disk cache's size. + */ +- (void)calculateSizeWithCompletionBlock:(nullable SDImageCacheCalculateSizeBlock)completionBlock; + +@end + +/** + * SDImageCache is the built-in image cache implementation for web image manager. It adopts `SDImageCache` protocol to provide the function for web image manager to use for image loading process. + */ +@interface SDImageCache (SDImageCache) + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.m new file mode 100644 index 00000000..635908b3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCache.m @@ -0,0 +1,944 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCache.h" +#import "NSImage+Compatibility.h" +#import "SDImageCodersManager.h" +#import "SDImageCoderHelper.h" +#import "SDAnimatedImage.h" +#import "UIImage+MemoryCacheCost.h" +#import "UIImage+Metadata.h" +#import "UIImage+ExtendedCacheData.h" + +static NSString * _defaultDiskCacheDirectory; + +@interface SDImageCache () + +#pragma mark - Properties +@property (nonatomic, strong, readwrite, nonnull) id memoryCache; +@property (nonatomic, strong, readwrite, nonnull) id diskCache; +@property (nonatomic, copy, readwrite, nonnull) SDImageCacheConfig *config; +@property (nonatomic, copy, readwrite, nonnull) NSString *diskCachePath; +@property (nonatomic, strong, nullable) dispatch_queue_t ioQueue; + +@end + + +@implementation SDImageCache + +#pragma mark - Singleton, init, dealloc + ++ (nonnull instancetype)sharedImageCache { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + ++ (NSString *)defaultDiskCacheDirectory { + if (!_defaultDiskCacheDirectory) { + _defaultDiskCacheDirectory = [[self userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"]; + } + return _defaultDiskCacheDirectory; +} + ++ (void)setDefaultDiskCacheDirectory:(NSString *)defaultDiskCacheDirectory { + _defaultDiskCacheDirectory = [defaultDiskCacheDirectory copy]; +} + +- (instancetype)init { + return [self initWithNamespace:@"default"]; +} + +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns { + return [self initWithNamespace:ns diskCacheDirectory:nil]; +} + +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns + diskCacheDirectory:(nullable NSString *)directory { + return [self initWithNamespace:ns diskCacheDirectory:directory config:SDImageCacheConfig.defaultCacheConfig]; +} + +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns + diskCacheDirectory:(nullable NSString *)directory + config:(nullable SDImageCacheConfig *)config { + if ((self = [super init])) { + NSAssert(ns, @"Cache namespace should not be nil"); + + // Create IO serial queue + _ioQueue = dispatch_queue_create("com.hackemist.SDImageCache", DISPATCH_QUEUE_SERIAL); + + if (!config) { + config = SDImageCacheConfig.defaultCacheConfig; + } + _config = [config copy]; + + // Init the memory cache + NSAssert([config.memoryCacheClass conformsToProtocol:@protocol(SDMemoryCache)], @"Custom memory cache class must conform to `SDMemoryCache` protocol"); + _memoryCache = [[config.memoryCacheClass alloc] initWithConfig:_config]; + + // Init the disk cache + if (!directory) { + // Use default disk cache directory + directory = [self.class defaultDiskCacheDirectory]; + } + _diskCachePath = [directory stringByAppendingPathComponent:ns]; + + NSAssert([config.diskCacheClass conformsToProtocol:@protocol(SDDiskCache)], @"Custom disk cache class must conform to `SDDiskCache` protocol"); + _diskCache = [[config.diskCacheClass alloc] initWithCachePath:_diskCachePath config:_config]; + + // Check and migrate disk cache directory if need + [self migrateDiskCacheDirectory]; + +#if SD_UIKIT + // Subscribe to app events + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillTerminate:) + name:UIApplicationWillTerminateNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationDidEnterBackground:) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; +#endif +#if SD_MAC + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillTerminate:) + name:NSApplicationWillTerminateNotification + object:nil]; +#endif + } + + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Cache paths + +- (nullable NSString *)cachePathForKey:(nullable NSString *)key { + if (!key) { + return nil; + } + return [self.diskCache cachePathForKey:key]; +} + ++ (nullable NSString *)userCacheDirectory { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + return paths.firstObject; +} + +- (void)migrateDiskCacheDirectory { + if ([self.diskCache isKindOfClass:[SDDiskCache class]]) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // ~/Library/Caches/com.hackemist.SDImageCache/default/ + NSString *newDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"] stringByAppendingPathComponent:@"default"]; + // ~/Library/Caches/default/com.hackemist.SDWebImageCache.default/ + NSString *oldDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"]; + dispatch_async(self.ioQueue, ^{ + [((SDDiskCache *)self.diskCache) moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath]; + }); + }); + } +} + +#pragma mark - Store Ops + +- (void)storeImage:(nullable UIImage *)image + forKey:(nullable NSString *)key + completion:(nullable SDWebImageNoParamsBlock)completionBlock { + [self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock]; +} + +- (void)storeImage:(nullable UIImage *)image + forKey:(nullable NSString *)key + toDisk:(BOOL)toDisk + completion:(nullable SDWebImageNoParamsBlock)completionBlock { + [self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock]; +} + +- (void)storeImage:(nullable UIImage *)image + imageData:(nullable NSData *)imageData + forKey:(nullable NSString *)key + toDisk:(BOOL)toDisk + completion:(nullable SDWebImageNoParamsBlock)completionBlock { + return [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:toDisk completion:completionBlock]; +} + +- (void)storeImage:(nullable UIImage *)image + imageData:(nullable NSData *)imageData + forKey:(nullable NSString *)key + toMemory:(BOOL)toMemory + toDisk:(BOOL)toDisk + completion:(nullable SDWebImageNoParamsBlock)completionBlock { + if (!image || !key) { + if (completionBlock) { + completionBlock(); + } + return; + } + // if memory cache is enabled + if (toMemory && self.config.shouldCacheImagesInMemory) { + NSUInteger cost = image.sd_memoryCost; + [self.memoryCache setObject:image forKey:key cost:cost]; + } + + if (!toDisk) { + if (completionBlock) { + completionBlock(); + } + return; + } + dispatch_async(self.ioQueue, ^{ + @autoreleasepool { + NSData *data = imageData; + if (!data && [image conformsToProtocol:@protocol(SDAnimatedImage)]) { + // If image is custom animated image class, prefer its original animated data + data = [((id)image) animatedImageData]; + } + if (!data && image) { + // Check image's associated image format, may return .undefined + SDImageFormat format = image.sd_imageFormat; + if (format == SDImageFormatUndefined) { + // If image is animated, use GIF (APNG may be better, but has bugs before macOS 10.14) + if (image.sd_isAnimated) { + format = SDImageFormatGIF; + } else { + // If we do not have any data to detect image format, check whether it contains alpha channel to use PNG or JPEG format + format = [SDImageCoderHelper CGImageContainsAlpha:image.CGImage] ? SDImageFormatPNG : SDImageFormatJPEG; + } + } + data = [[SDImageCodersManager sharedManager] encodedDataWithImage:image format:format options:nil]; + } + [self _storeImageDataToDisk:data forKey:key]; + [self _archivedDataWithImage:image forKey:key]; + } + + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(); + }); + } + }); +} + +- (void)_archivedDataWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return; + } + // Check extended data + id extendedObject = image.sd_extendedObject; + if (![extendedObject conformsToProtocol:@protocol(NSCoding)]) { + return; + } + NSData *extendedData; + if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) { + NSError *error; + extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject requiringSecureCoding:NO error:&error]; + if (error) { + NSLog(@"NSKeyedArchiver archive failed with error: %@", error); + } + } else { + @try { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject]; +#pragma clang diagnostic pop + } @catch (NSException *exception) { + NSLog(@"NSKeyedArchiver archive failed with exception: %@", exception); + } + } + if (extendedData) { + [self.diskCache setExtendedData:extendedData forKey:key]; + } +} + +- (void)storeImageToMemory:(UIImage *)image forKey:(NSString *)key { + if (!image || !key) { + return; + } + NSUInteger cost = image.sd_memoryCost; + [self.memoryCache setObject:image forKey:key cost:cost]; +} + +- (void)storeImageDataToDisk:(nullable NSData *)imageData + forKey:(nullable NSString *)key { + if (!imageData || !key) { + return; + } + + dispatch_sync(self.ioQueue, ^{ + [self _storeImageDataToDisk:imageData forKey:key]; + }); +} + +// Make sure to call from io queue by caller +- (void)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key { + if (!imageData || !key) { + return; + } + + [self.diskCache setData:imageData forKey:key]; +} + +#pragma mark - Query and Retrieve Ops + +- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDImageCacheCheckCompletionBlock)completionBlock { + dispatch_async(self.ioQueue, ^{ + BOOL exists = [self _diskImageDataExistsWithKey:key]; + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(exists); + }); + } + }); +} + +- (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key { + if (!key) { + return NO; + } + + __block BOOL exists = NO; + dispatch_sync(self.ioQueue, ^{ + exists = [self _diskImageDataExistsWithKey:key]; + }); + + return exists; +} + +// Make sure to call from io queue by caller +- (BOOL)_diskImageDataExistsWithKey:(nullable NSString *)key { + if (!key) { + return NO; + } + + return [self.diskCache containsDataForKey:key]; +} + +- (void)diskImageDataQueryForKey:(NSString *)key completion:(SDImageCacheQueryDataCompletionBlock)completionBlock { + dispatch_async(self.ioQueue, ^{ + NSData *imageData = [self diskImageDataBySearchingAllPathsForKey:key]; + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(imageData); + }); + } + }); +} + +- (nullable NSData *)diskImageDataForKey:(nullable NSString *)key { + if (!key) { + return nil; + } + __block NSData *imageData = nil; + dispatch_sync(self.ioQueue, ^{ + imageData = [self diskImageDataBySearchingAllPathsForKey:key]; + }); + + return imageData; +} + +- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key { + return [self.memoryCache objectForKey:key]; +} + +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key { + return [self imageFromDiskCacheForKey:key options:0 context:nil]; +} + +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context { + NSData *data = [self diskImageDataForKey:key]; + UIImage *diskImage = [self diskImageForKey:key data:data options:options context:context]; + + BOOL shouldCacheToMomery = YES; + if (context[SDWebImageContextStoreCacheType]) { + SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue]; + shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory); + } + if (diskImage && self.config.shouldCacheImagesInMemory && shouldCacheToMomery) { + NSUInteger cost = diskImage.sd_memoryCost; + [self.memoryCache setObject:diskImage forKey:key cost:cost]; + } + + return diskImage; +} + +- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key { + return [self imageFromCacheForKey:key options:0 context:nil]; +} + +- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context { + // First check the in-memory cache... + UIImage *image = [self imageFromMemoryCacheForKey:key]; + if (image) { + if (options & SDImageCacheDecodeFirstFrameOnly) { + // Ensure static image + Class animatedImageClass = image.class; + if (image.sd_isAnimated || ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)])) { +#if SD_MAC + image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp]; +#else + image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation]; +#endif + } + } else if (options & SDImageCacheMatchAnimatedImageClass) { + // Check image class matching + Class animatedImageClass = image.class; + Class desiredImageClass = context[SDWebImageContextAnimatedImageClass]; + if (desiredImageClass && ![animatedImageClass isSubclassOfClass:desiredImageClass]) { + image = nil; + } + } + } + + // Since we don't need to query imageData, return image if exist + if (image) { + return image; + } + + // Second check the disk cache... + image = [self imageFromDiskCacheForKey:key options:options context:context]; + return image; +} + +- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key { + if (!key) { + return nil; + } + + NSData *data = [self.diskCache dataForKey:key]; + if (data) { + return data; + } + + // Addtional cache path for custom pre-load cache + if (self.additionalCachePathBlock) { + NSString *filePath = self.additionalCachePathBlock(key); + if (filePath) { + data = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil]; + } + } + + return data; +} + +- (nullable UIImage *)diskImageForKey:(nullable NSString *)key { + NSData *data = [self diskImageDataForKey:key]; + return [self diskImageForKey:key data:data]; +} + +- (nullable UIImage *)diskImageForKey:(nullable NSString *)key data:(nullable NSData *)data { + return [self diskImageForKey:key data:data options:0 context:nil]; +} + +- (nullable UIImage *)diskImageForKey:(nullable NSString *)key data:(nullable NSData *)data options:(SDImageCacheOptions)options context:(SDWebImageContext *)context { + if (!data) { + return nil; + } + UIImage *image = SDImageCacheDecodeImageData(data, key, [[self class] imageOptionsFromCacheOptions:options], context); + [self _unarchiveObjectWithImage:image forKey:key]; + return image; +} + +- (void)_unarchiveObjectWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return; + } + // Check extended data + NSData *extendedData = [self.diskCache extendedDataForKey:key]; + if (!extendedData) { + return; + } + id extendedObject; + if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) { + NSError *error; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:extendedData error:&error]; + unarchiver.requiresSecureCoding = NO; + extendedObject = [unarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:&error]; + if (error) { + NSLog(@"NSKeyedUnarchiver unarchive failed with error: %@", error); + } + } else { + @try { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + extendedObject = [NSKeyedUnarchiver unarchiveObjectWithData:extendedData]; +#pragma clang diagnostic pop + } @catch (NSException *exception) { + NSLog(@"NSKeyedUnarchiver unarchive failed with exception: %@", exception); + } + } + image.sd_extendedObject = extendedObject; +} + +- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDImageCacheQueryCompletionBlock)doneBlock { + return [self queryCacheOperationForKey:key options:0 done:doneBlock]; +} + +- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key options:(SDImageCacheOptions)options done:(SDImageCacheQueryCompletionBlock)doneBlock { + return [self queryCacheOperationForKey:key options:options context:nil done:doneBlock]; +} + +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock { + return [self queryCacheOperationForKey:key options:options context:context cacheType:SDImageCacheTypeAll done:doneBlock]; +} + +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock { + if (!key) { + if (doneBlock) { + doneBlock(nil, nil, SDImageCacheTypeNone); + } + return nil; + } + // Invalid cache type + if (queryCacheType == SDImageCacheTypeNone) { + if (doneBlock) { + doneBlock(nil, nil, SDImageCacheTypeNone); + } + return nil; + } + + // First check the in-memory cache... + UIImage *image; + if (queryCacheType != SDImageCacheTypeDisk) { + image = [self imageFromMemoryCacheForKey:key]; + } + + if (image) { + if (options & SDImageCacheDecodeFirstFrameOnly) { + // Ensure static image + Class animatedImageClass = image.class; + if (image.sd_isAnimated || ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)])) { +#if SD_MAC + image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp]; +#else + image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation]; +#endif + } + } else if (options & SDImageCacheMatchAnimatedImageClass) { + // Check image class matching + Class animatedImageClass = image.class; + Class desiredImageClass = context[SDWebImageContextAnimatedImageClass]; + if (desiredImageClass && ![animatedImageClass isSubclassOfClass:desiredImageClass]) { + image = nil; + } + } + } + + BOOL shouldQueryMemoryOnly = (queryCacheType == SDImageCacheTypeMemory) || (image && !(options & SDImageCacheQueryMemoryData)); + if (shouldQueryMemoryOnly) { + if (doneBlock) { + doneBlock(image, nil, SDImageCacheTypeMemory); + } + return nil; + } + + // Second check the disk cache... + NSOperation *operation = [NSOperation new]; + // Check whether we need to synchronously query disk + // 1. in-memory cache hit & memoryDataSync + // 2. in-memory cache miss & diskDataSync + BOOL shouldQueryDiskSync = ((image && options & SDImageCacheQueryMemoryDataSync) || + (!image && options & SDImageCacheQueryDiskDataSync)); + NSData* (^queryDiskDataBlock)(void) = ^NSData* { + if (operation.isCancelled) { + return nil; + } + + return [self diskImageDataBySearchingAllPathsForKey:key]; + }; + + UIImage* (^queryDiskImageBlock)(NSData*) = ^UIImage*(NSData* diskData) { + if (operation.isCancelled) { + return nil; + } + + UIImage *diskImage; + if (image) { + // the image is from in-memory cache, but need image data + diskImage = image; + } else if (diskData) { + BOOL shouldCacheToMomery = YES; + if (context[SDWebImageContextStoreCacheType]) { + SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue]; + shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory); + } + // decode image data only if in-memory cache missed + diskImage = [self diskImageForKey:key data:diskData options:options context:context]; + if (shouldCacheToMomery && diskImage && self.config.shouldCacheImagesInMemory) { + NSUInteger cost = diskImage.sd_memoryCost; + [self.memoryCache setObject:diskImage forKey:key cost:cost]; + } + } + return diskImage; + }; + + // Query in ioQueue to keep IO-safe + if (shouldQueryDiskSync) { + __block NSData* diskData; + __block UIImage* diskImage; + dispatch_sync(self.ioQueue, ^{ + diskData = queryDiskDataBlock(); + diskImage = queryDiskImageBlock(diskData); + }); + if (doneBlock) { + doneBlock(diskImage, diskData, SDImageCacheTypeDisk); + } + } else { + dispatch_async(self.ioQueue, ^{ + NSData* diskData = queryDiskDataBlock(); + UIImage* diskImage = queryDiskImageBlock(diskData); + if (doneBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + doneBlock(diskImage, diskData, SDImageCacheTypeDisk); + }); + } + }); + } + + return operation; +} + +#pragma mark - Remove Ops + +- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion { + [self removeImageForKey:key fromDisk:YES withCompletion:completion]; +} + +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion { + [self removeImageForKey:key fromMemory:YES fromDisk:fromDisk withCompletion:completion]; +} + +- (void)removeImageForKey:(nullable NSString *)key fromMemory:(BOOL)fromMemory fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion { + if (key == nil) { + return; + } + + if (fromMemory && self.config.shouldCacheImagesInMemory) { + [self.memoryCache removeObjectForKey:key]; + } + + if (fromDisk) { + dispatch_async(self.ioQueue, ^{ + [self.diskCache removeDataForKey:key]; + + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(); + }); + } + }); + } else if (completion) { + completion(); + } +} + +- (void)removeImageFromMemoryForKey:(NSString *)key { + if (!key) { + return; + } + + [self.memoryCache removeObjectForKey:key]; +} + +- (void)removeImageFromDiskForKey:(NSString *)key { + if (!key) { + return; + } + dispatch_sync(self.ioQueue, ^{ + [self _removeImageFromDiskForKey:key]; + }); +} + +// Make sure to call from io queue by caller +- (void)_removeImageFromDiskForKey:(NSString *)key { + if (!key) { + return; + } + + [self.diskCache removeDataForKey:key]; +} + +#pragma mark - Cache clean Ops + +- (void)clearMemory { + [self.memoryCache removeAllObjects]; +} + +- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion { + dispatch_async(self.ioQueue, ^{ + [self.diskCache removeAllData]; + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(); + }); + } + }); +} + +- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock { + dispatch_async(self.ioQueue, ^{ + [self.diskCache removeExpiredData]; + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(); + }); + } + }); +} + +#pragma mark - UIApplicationWillTerminateNotification + +#if SD_UIKIT || SD_MAC +- (void)applicationWillTerminate:(NSNotification *)notification { + // On iOS/macOS, the async opeartion to remove exipred data will be terminated quickly + // Try using the sync operation to ensure we reomve the exipred data + if (!self.config.shouldRemoveExpiredDataWhenTerminate) { + return; + } + dispatch_sync(self.ioQueue, ^{ + [self.diskCache removeExpiredData]; + }); +} +#endif + +#pragma mark - UIApplicationDidEnterBackgroundNotification + +#if SD_UIKIT +- (void)applicationDidEnterBackground:(NSNotification *)notification { + if (!self.config.shouldRemoveExpiredDataWhenEnterBackground) { + return; + } + Class UIApplicationClass = NSClassFromString(@"UIApplication"); + if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) { + return; + } + UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)]; + __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ + // Clean up any unfinished task business by marking where you + // stopped or ending the task outright. + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; + + // Start the long-running task and return immediately. + [self deleteOldFilesWithCompletionBlock:^{ + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; +} +#endif + +#pragma mark - Cache Info + +- (NSUInteger)totalDiskSize { + __block NSUInteger size = 0; + dispatch_sync(self.ioQueue, ^{ + size = [self.diskCache totalSize]; + }); + return size; +} + +- (NSUInteger)totalDiskCount { + __block NSUInteger count = 0; + dispatch_sync(self.ioQueue, ^{ + count = [self.diskCache totalCount]; + }); + return count; +} + +- (void)calculateSizeWithCompletionBlock:(nullable SDImageCacheCalculateSizeBlock)completionBlock { + dispatch_async(self.ioQueue, ^{ + NSUInteger fileCount = [self.diskCache totalCount]; + NSUInteger totalSize = [self.diskCache totalSize]; + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(fileCount, totalSize); + }); + } + }); +} + +#pragma mark - Helper ++ (SDWebImageOptions)imageOptionsFromCacheOptions:(SDImageCacheOptions)cacheOptions { + SDWebImageOptions options = 0; + if (cacheOptions & SDImageCacheScaleDownLargeImages) options |= SDWebImageScaleDownLargeImages; + if (cacheOptions & SDImageCacheDecodeFirstFrameOnly) options |= SDWebImageDecodeFirstFrameOnly; + if (cacheOptions & SDImageCachePreloadAllFrames) options |= SDWebImagePreloadAllFrames; + if (cacheOptions & SDImageCacheAvoidDecodeImage) options |= SDWebImageAvoidDecodeImage; + if (cacheOptions & SDImageCacheMatchAnimatedImageClass) options |= SDWebImageMatchAnimatedImageClass; + + return options; +} + +@end + +@implementation SDImageCache (SDImageCache) + +#pragma mark - SDImageCache + +- (id)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock { + return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:completionBlock]; +} + +- (id)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock { + SDImageCacheOptions cacheOptions = 0; + if (options & SDWebImageQueryMemoryData) cacheOptions |= SDImageCacheQueryMemoryData; + if (options & SDWebImageQueryMemoryDataSync) cacheOptions |= SDImageCacheQueryMemoryDataSync; + if (options & SDWebImageQueryDiskDataSync) cacheOptions |= SDImageCacheQueryDiskDataSync; + if (options & SDWebImageScaleDownLargeImages) cacheOptions |= SDImageCacheScaleDownLargeImages; + if (options & SDWebImageAvoidDecodeImage) cacheOptions |= SDImageCacheAvoidDecodeImage; + if (options & SDWebImageDecodeFirstFrameOnly) cacheOptions |= SDImageCacheDecodeFirstFrameOnly; + if (options & SDWebImagePreloadAllFrames) cacheOptions |= SDImageCachePreloadAllFrames; + if (options & SDWebImageMatchAnimatedImageClass) cacheOptions |= SDImageCacheMatchAnimatedImageClass; + + return [self queryCacheOperationForKey:key options:cacheOptions context:context cacheType:cacheType done:completionBlock]; +} + +- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(nullable NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock { + switch (cacheType) { + case SDImageCacheTypeNone: { + [self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:NO completion:completionBlock]; + } + break; + case SDImageCacheTypeMemory: { + [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:NO completion:completionBlock]; + } + break; + case SDImageCacheTypeDisk: { + [self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:YES completion:completionBlock]; + } + break; + case SDImageCacheTypeAll: { + [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:YES completion:completionBlock]; + } + break; + default: { + if (completionBlock) { + completionBlock(); + } + } + break; + } +} + +- (void)removeImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock { + switch (cacheType) { + case SDImageCacheTypeNone: { + [self removeImageForKey:key fromMemory:NO fromDisk:NO withCompletion:completionBlock]; + } + break; + case SDImageCacheTypeMemory: { + [self removeImageForKey:key fromMemory:YES fromDisk:NO withCompletion:completionBlock]; + } + break; + case SDImageCacheTypeDisk: { + [self removeImageForKey:key fromMemory:NO fromDisk:YES withCompletion:completionBlock]; + } + break; + case SDImageCacheTypeAll: { + [self removeImageForKey:key fromMemory:YES fromDisk:YES withCompletion:completionBlock]; + } + break; + default: { + if (completionBlock) { + completionBlock(); + } + } + break; + } +} + +- (void)containsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDImageCacheContainsCompletionBlock)completionBlock { + switch (cacheType) { + case SDImageCacheTypeNone: { + if (completionBlock) { + completionBlock(SDImageCacheTypeNone); + } + } + break; + case SDImageCacheTypeMemory: { + BOOL isInMemoryCache = ([self imageFromMemoryCacheForKey:key] != nil); + if (completionBlock) { + completionBlock(isInMemoryCache ? SDImageCacheTypeMemory : SDImageCacheTypeNone); + } + } + break; + case SDImageCacheTypeDisk: { + [self diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) { + if (completionBlock) { + completionBlock(isInDiskCache ? SDImageCacheTypeDisk : SDImageCacheTypeNone); + } + }]; + } + break; + case SDImageCacheTypeAll: { + BOOL isInMemoryCache = ([self imageFromMemoryCacheForKey:key] != nil); + if (isInMemoryCache) { + if (completionBlock) { + completionBlock(SDImageCacheTypeMemory); + } + return; + } + [self diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) { + if (completionBlock) { + completionBlock(isInDiskCache ? SDImageCacheTypeDisk : SDImageCacheTypeNone); + } + }]; + } + break; + default: + if (completionBlock) { + completionBlock(SDImageCacheTypeNone); + } + break; + } +} + +- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock { + switch (cacheType) { + case SDImageCacheTypeNone: { + if (completionBlock) { + completionBlock(); + } + } + break; + case SDImageCacheTypeMemory: { + [self clearMemory]; + if (completionBlock) { + completionBlock(); + } + } + break; + case SDImageCacheTypeDisk: { + [self clearDiskOnCompletion:completionBlock]; + } + break; + case SDImageCacheTypeAll: { + [self clearMemory]; + [self clearDiskOnCompletion:completionBlock]; + } + break; + default: { + if (completionBlock) { + completionBlock(); + } + } + break; + } +} + +@end + diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.h new file mode 100644 index 00000000..468fa09e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.h @@ -0,0 +1,144 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/// Image Cache Expire Type +typedef NS_ENUM(NSUInteger, SDImageCacheConfigExpireType) { + /** + * When the image cache is accessed it will update this value + */ + SDImageCacheConfigExpireTypeAccessDate, + /** + * When the image cache is created or modified it will update this value (Default) + */ + SDImageCacheConfigExpireTypeModificationDate, + /** + * When the image cache is created it will update this value + */ + SDImageCacheConfigExpireTypeCreationDate, + /** + * When the image cache is created, modified, renamed, file attribute updated (like permission, xattr) it will update this value + */ + SDImageCacheConfigExpireTypeChangeDate, +}; + +/** + The class contains all the config for image cache + @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well. + */ +@interface SDImageCacheConfig : NSObject + +/** + Gets the default cache config used for shared instance or initialization when it does not provide any cache config. Such as `SDImageCache.sharedImageCache`. + @note You can modify the property on default cache config, which can be used for later created cache instance. The already created cache instance does not get affected. + */ +@property (nonatomic, class, readonly, nonnull) SDImageCacheConfig *defaultCacheConfig; + +/** + * Whether or not to disable iCloud backup + * Defaults to YES. + */ +@property (assign, nonatomic) BOOL shouldDisableiCloud; + +/** + * Whether or not to use memory cache + * @note When the memory cache is disabled, the weak memory cache will also be disabled. + * Defaults to YES. + */ +@property (assign, nonatomic) BOOL shouldCacheImagesInMemory; + +/* + * The option to control weak memory cache for images. When enable, `SDImageCache`'s memory cache will use a weak maptable to store the image at the same time when it stored to memory, and get removed at the same time. + * However when memory warning is triggered, since the weak maptable does not hold a strong reference to image instance, even when the memory cache itself is purged, some images which are held strongly by UIImageViews or other live instances can be recovered again, to avoid later re-query from disk cache or network. This may be helpful for the case, for example, when app enter background and memory is purged, cause cell flashing after re-enter foreground. + * When enabling this option, we will sync back the image from weak maptable to strong cache during next time top level `sd_setImage` function call. + * Defaults to NO (YES before 5.12.0 version). You can change this option dynamically. + */ +@property (assign, nonatomic) BOOL shouldUseWeakMemoryCache; + +/** + * Whether or not to remove the expired disk data when application entering the background. (Not works for macOS) + * Defaults to YES. + */ +@property (assign, nonatomic) BOOL shouldRemoveExpiredDataWhenEnterBackground; + +/** + * Whether or not to remove the expired disk data when application been terminated. This operation is processed in sync to ensure clean up. + * Defaults to YES. + */ +@property (assign, nonatomic) BOOL shouldRemoveExpiredDataWhenTerminate; + +/** + * The reading options while reading cache from disk. + * Defaults to 0. You can set this to `NSDataReadingMappedIfSafe` to improve performance. + */ +@property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions; + +/** + * The writing options while writing cache to disk. + * Defaults to `NSDataWritingAtomic`. You can set this to `NSDataWritingWithoutOverwriting` to prevent overwriting an existing file. + */ +@property (assign, nonatomic) NSDataWritingOptions diskCacheWritingOptions; + +/** + * The maximum length of time to keep an image in the disk cache, in seconds. + * Setting this to a negative value means no expiring. + * Setting this to zero means that all cached files would be removed when do expiration check. + * Defaults to 1 week. + */ +@property (assign, nonatomic) NSTimeInterval maxDiskAge; + +/** + * The maximum size of the disk cache, in bytes. + * Defaults to 0. Which means there is no cache size limit. + */ +@property (assign, nonatomic) NSUInteger maxDiskSize; + +/** + * The maximum "total cost" of the in-memory image cache. The cost function is the bytes size held in memory. + * @note The memory cost is bytes size in memory, but not simple pixels count. For common ARGB8888 image, one pixel is 4 bytes (32 bits). + * Defaults to 0. Which means there is no memory cost limit. + */ +@property (assign, nonatomic) NSUInteger maxMemoryCost; + +/** + * The maximum number of objects in-memory image cache should hold. + * Defaults to 0. Which means there is no memory count limit. + */ +@property (assign, nonatomic) NSUInteger maxMemoryCount; + +/* + * The attribute which the clear cache will be checked against when clearing the disk cache + * Default is Modified Date + */ +@property (assign, nonatomic) SDImageCacheConfigExpireType diskCacheExpireType; + +/** + * The custom file manager for disk cache. Pass nil to let disk cache choose the proper file manager. + * Defaults to nil. + * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect. + * @note Since `NSFileManager` does not support `NSCopying`. We just pass this by reference during copying. So it's not recommend to set this value on `defaultCacheConfig`. + */ +@property (strong, nonatomic, nullable) NSFileManager *fileManager; + +/** + * The custom memory cache class. Provided class instance must conform to `SDMemoryCache` protocol to allow usage. + * Defaults to built-in `SDMemoryCache` class. + * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect. + */ +@property (assign, nonatomic, nonnull) Class memoryCacheClass; + +/** + * The custom disk cache class. Provided class instance must conform to `SDDiskCache` protocol to allow usage. + * Defaults to built-in `SDDiskCache` class. + * @note This value does not support dynamic changes. Which means further modification on this value after cache initialized has no effect. + */ +@property (assign ,nonatomic, nonnull) Class diskCacheClass; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.m new file mode 100644 index 00000000..fc022859 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheConfig.m @@ -0,0 +1,65 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCacheConfig.h" +#import "SDMemoryCache.h" +#import "SDDiskCache.h" + +static SDImageCacheConfig *_defaultCacheConfig; +static const NSInteger kDefaultCacheMaxDiskAge = 60 * 60 * 24 * 7; // 1 week + +@implementation SDImageCacheConfig + ++ (SDImageCacheConfig *)defaultCacheConfig { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _defaultCacheConfig = [SDImageCacheConfig new]; + }); + return _defaultCacheConfig; +} + +- (instancetype)init { + if (self = [super init]) { + _shouldDisableiCloud = YES; + _shouldCacheImagesInMemory = YES; + _shouldUseWeakMemoryCache = NO; + _shouldRemoveExpiredDataWhenEnterBackground = YES; + _shouldRemoveExpiredDataWhenTerminate = YES; + _diskCacheReadingOptions = 0; + _diskCacheWritingOptions = NSDataWritingAtomic; + _maxDiskAge = kDefaultCacheMaxDiskAge; + _maxDiskSize = 0; + _diskCacheExpireType = SDImageCacheConfigExpireTypeModificationDate; + _memoryCacheClass = [SDMemoryCache class]; + _diskCacheClass = [SDDiskCache class]; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + SDImageCacheConfig *config = [[[self class] allocWithZone:zone] init]; + config.shouldDisableiCloud = self.shouldDisableiCloud; + config.shouldCacheImagesInMemory = self.shouldCacheImagesInMemory; + config.shouldUseWeakMemoryCache = self.shouldUseWeakMemoryCache; + config.shouldRemoveExpiredDataWhenEnterBackground = self.shouldRemoveExpiredDataWhenEnterBackground; + config.shouldRemoveExpiredDataWhenTerminate = self.shouldRemoveExpiredDataWhenTerminate; + config.diskCacheReadingOptions = self.diskCacheReadingOptions; + config.diskCacheWritingOptions = self.diskCacheWritingOptions; + config.maxDiskAge = self.maxDiskAge; + config.maxDiskSize = self.maxDiskSize; + config.maxMemoryCost = self.maxMemoryCost; + config.maxMemoryCount = self.maxMemoryCount; + config.diskCacheExpireType = self.diskCacheExpireType; + config.fileManager = self.fileManager; // NSFileManager does not conform to NSCopying, just pass the reference + config.memoryCacheClass = self.memoryCacheClass; + config.diskCacheClass = self.diskCacheClass; + + return config; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.h new file mode 100644 index 00000000..48f7b5ca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.h @@ -0,0 +1,143 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageOperation.h" +#import "SDWebImageDefine.h" + +/// Image Cache Type +typedef NS_ENUM(NSInteger, SDImageCacheType) { + /** + * For query and contains op in response, means the image isn't available in the image cache + * For op in request, this type is not available and take no effect. + */ + SDImageCacheTypeNone, + /** + * For query and contains op in response, means the image was obtained from the disk cache. + * For op in request, means process only disk cache. + */ + SDImageCacheTypeDisk, + /** + * For query and contains op in response, means the image was obtained from the memory cache. + * For op in request, means process only memory cache. + */ + SDImageCacheTypeMemory, + /** + * For query and contains op in response, this type is not available and take no effect. + * For op in request, means process both memory cache and disk cache. + */ + SDImageCacheTypeAll +}; + +typedef void(^SDImageCacheCheckCompletionBlock)(BOOL isInCache); +typedef void(^SDImageCacheQueryDataCompletionBlock)(NSData * _Nullable data); +typedef void(^SDImageCacheCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize); +typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString * _Nonnull key); +typedef void(^SDImageCacheQueryCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType); +typedef void(^SDImageCacheContainsCompletionBlock)(SDImageCacheType containsCacheType); + +/** + This is the built-in decoding process for image query from cache. + @note If you want to implement your custom loader with `queryImageForKey:options:context:completion:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. + + @param imageData The image data from the cache. Should not be nil + @param cacheKey The image cache key from the input. Should not be nil + @param options The options arg from the input + @param context The context arg from the input + @return The decoded image for current image data query from cache + */ +FOUNDATION_EXPORT UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context); + +/** + This is the image cache protocol to provide custom image cache for `SDWebImageManager`. + Though the best practice to custom image cache, is to write your own class which conform `SDMemoryCache` or `SDDiskCache` protocol for `SDImageCache` class (See more on `SDImageCacheConfig.memoryCacheClass & SDImageCacheConfig.diskCacheClass`). + However, if your own cache implementation contains more advanced feature beyond `SDImageCache` itself, you can consider to provide this instead. For example, you can even use a cache manager like `SDImageCachesManager` to register multiple caches. + */ +@protocol SDImageCache + +@required +/** + Query the cached image from image cache for given key. The operation can be used to cancel the query. + If image is cached in memory, completion is called synchronously, else asynchronously and depends on the options arg (See `SDWebImageQueryDiskSync`) + + @param key The image cache key + @param options A mask to specify options to use for this query + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @param completionBlock The completion block. Will not get called if the operation is cancelled + @return The operation for this query + */ +- (nullable id)queryImageForKey:(nullable NSString *)key + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock; + +/** + Query the cached image from image cache for given key. The operation can be used to cancel the query. + If image is cached in memory, completion is called synchronously, else asynchronously and depends on the options arg (See `SDWebImageQueryDiskSync`) + + @param key The image cache key + @param options A mask to specify options to use for this query + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @param cacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediately. + @param completionBlock The completion block. Will not get called if the operation is cancelled + @return The operation for this query + */ +- (nullable id)queryImageForKey:(nullable NSString *)key + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + cacheType:(SDImageCacheType)cacheType + completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock; + +/** + Store the image into image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously. + + @param image The image to store + @param imageData The image data to be used for disk storage + @param key The image cache key + @param cacheType The image store op cache type + @param completionBlock A block executed after the operation is finished + */ +- (void)storeImage:(nullable UIImage *)image + imageData:(nullable NSData *)imageData + forKey:(nullable NSString *)key + cacheType:(SDImageCacheType)cacheType + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +/** + Remove the image from image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously. + + @param key The image cache key + @param cacheType The image remove op cache type + @param completionBlock A block executed after the operation is finished + */ +- (void)removeImageForKey:(nullable NSString *)key + cacheType:(SDImageCacheType)cacheType + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +/** + Check if image cache contains the image for the given key (does not load the image). If image is cached in memory, completion is called synchronously, else asynchronously. + + @param key The image cache key + @param cacheType The image contains op cache type + @param completionBlock A block executed after the operation is finished. + */ +- (void)containsImageForKey:(nullable NSString *)key + cacheType:(SDImageCacheType)cacheType + completion:(nullable SDImageCacheContainsCompletionBlock)completionBlock; + +/** + Clear all the cached images for image cache. If cache type is memory only, completion is called synchronously, else asynchronously. + + @param cacheType The image clear op cache type + @param completionBlock A block executed after the operation is finished + */ +- (void)clearWithCacheType:(SDImageCacheType)cacheType + completion:(nullable SDWebImageNoParamsBlock)completionBlock; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.m new file mode 100644 index 00000000..19db161a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCacheDefine.m @@ -0,0 +1,85 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCacheDefine.h" +#import "SDImageCodersManager.h" +#import "SDImageCoderHelper.h" +#import "SDAnimatedImage.h" +#import "UIImage+Metadata.h" +#import "SDInternalMacros.h" + +UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context) { + UIImage *image; + BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly); + NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor]; + CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey); + NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio]; + NSValue *thumbnailSizeValue; + BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages); + if (shouldScaleDown) { + CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4; + CGFloat dimension = ceil(sqrt(thumbnailPixels)); + thumbnailSizeValue = @(CGSizeMake(dimension, dimension)); + } + if (context[SDWebImageContextImageThumbnailPixelSize]) { + thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize]; + } + + SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2]; + mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame); + mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale); + mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue; + mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue; + mutableCoderOptions[SDImageCoderWebImageContext] = context; + SDImageCoderOptions *coderOptions = [mutableCoderOptions copy]; + + // Grab the image coder + id imageCoder; + if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) { + imageCoder = context[SDWebImageContextImageCoder]; + } else { + imageCoder = [SDImageCodersManager sharedManager]; + } + + if (!decodeFirstFrame) { + Class animatedImageClass = context[SDWebImageContextAnimatedImageClass]; + // check whether we should use `SDAnimatedImage` + if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) { + image = [[animatedImageClass alloc] initWithData:imageData scale:scale options:coderOptions]; + if (image) { + // Preload frames if supported + if (options & SDWebImagePreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) { + [((id)image) preloadAllFrames]; + } + } else { + // Check image class matching + if (options & SDWebImageMatchAnimatedImageClass) { + return nil; + } + } + } + } + if (!image) { + image = [imageCoder decodedImageWithData:imageData options:coderOptions]; + } + if (image) { + BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage); + if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) { + // `SDAnimatedImage` do not decode + shouldDecode = NO; + } else if (image.sd_isAnimated) { + // animated image do not decode + shouldDecode = NO; + } + if (shouldDecode) { + image = [SDImageCoderHelper decodedImageWithImage:image]; + } + } + + return image; +} diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.h new file mode 100644 index 00000000..ad85db88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.h @@ -0,0 +1,81 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageCacheDefine.h" + +/// Policy for cache operation +typedef NS_ENUM(NSUInteger, SDImageCachesManagerOperationPolicy) { + SDImageCachesManagerOperationPolicySerial, // process all caches serially (from the highest priority to the lowest priority cache by order) + SDImageCachesManagerOperationPolicyConcurrent, // process all caches concurrently + SDImageCachesManagerOperationPolicyHighestOnly, // process the highest priority cache only + SDImageCachesManagerOperationPolicyLowestOnly // process the lowest priority cache only +}; + +/** + A caches manager to manage multiple caches. + */ +@interface SDImageCachesManager : NSObject + +/** + Returns the global shared caches manager instance. By default we will set [`SDImageCache.sharedImageCache`] into the caches array. + */ +@property (nonatomic, class, readonly, nonnull) SDImageCachesManager *sharedManager; + +// These are op policy for cache manager. + +/** + Operation policy for query op. + Defaults to `Serial`, means query all caches serially (one completion called then next begin) until one cache query success (`image` != nil). + */ +@property (nonatomic, assign) SDImageCachesManagerOperationPolicy queryOperationPolicy; + +/** + Operation policy for store op. + Defaults to `HighestOnly`, means store to the highest priority cache only. + */ +@property (nonatomic, assign) SDImageCachesManagerOperationPolicy storeOperationPolicy; + +/** + Operation policy for remove op. + Defaults to `Concurrent`, means remove all caches concurrently. + */ +@property (nonatomic, assign) SDImageCachesManagerOperationPolicy removeOperationPolicy; + +/** + Operation policy for contains op. + Defaults to `Serial`, means check all caches serially (one completion called then next begin) until one cache check success (`containsCacheType` != None). + */ +@property (nonatomic, assign) SDImageCachesManagerOperationPolicy containsOperationPolicy; + +/** + Operation policy for clear op. + Defaults to `Concurrent`, means clear all caches concurrently. + */ +@property (nonatomic, assign) SDImageCachesManagerOperationPolicy clearOperationPolicy; + +/** + All caches in caches manager. The caches array is a priority queue, which means the later added cache will have the highest priority + */ +@property (nonatomic, copy, nullable) NSArray> *caches; + +/** + Add a new cache to the end of caches array. Which has the highest priority. + + @param cache cache + */ +- (void)addCache:(nonnull id)cache; + +/** + Remove a cache in the caches array. + + @param cache cache + */ +- (void)removeCache:(nonnull id)cache; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.m new file mode 100644 index 00000000..5b8c0c36 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCachesManager.m @@ -0,0 +1,556 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCachesManager.h" +#import "SDImageCachesManagerOperation.h" +#import "SDImageCache.h" +#import "SDInternalMacros.h" + +@interface SDImageCachesManager () + +@property (nonatomic, strong, nonnull) NSMutableArray> *imageCaches; + +@end + +@implementation SDImageCachesManager { + SD_LOCK_DECLARE(_cachesLock); +} + ++ (SDImageCachesManager *)sharedManager { + static dispatch_once_t onceToken; + static SDImageCachesManager *manager; + dispatch_once(&onceToken, ^{ + manager = [[SDImageCachesManager alloc] init]; + }); + return manager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.queryOperationPolicy = SDImageCachesManagerOperationPolicySerial; + self.storeOperationPolicy = SDImageCachesManagerOperationPolicyHighestOnly; + self.removeOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent; + self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial; + self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent; + // initialize with default image caches + _imageCaches = [NSMutableArray arrayWithObject:[SDImageCache sharedImageCache]]; + SD_LOCK_INIT(_cachesLock); + } + return self; +} + +- (NSArray> *)caches { + SD_LOCK(_cachesLock); + NSArray> *caches = [_imageCaches copy]; + SD_UNLOCK(_cachesLock); + return caches; +} + +- (void)setCaches:(NSArray> *)caches { + SD_LOCK(_cachesLock); + [_imageCaches removeAllObjects]; + if (caches.count) { + [_imageCaches addObjectsFromArray:caches]; + } + SD_UNLOCK(_cachesLock); +} + +#pragma mark - Cache IO operations + +- (void)addCache:(id)cache { + if (![cache conformsToProtocol:@protocol(SDImageCache)]) { + return; + } + SD_LOCK(_cachesLock); + [_imageCaches addObject:cache]; + SD_UNLOCK(_cachesLock); +} + +- (void)removeCache:(id)cache { + if (![cache conformsToProtocol:@protocol(SDImageCache)]) { + return; + } + SD_LOCK(_cachesLock); + [_imageCaches removeObject:cache]; + SD_UNLOCK(_cachesLock); +} + +#pragma mark - SDImageCache + +- (id)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)completionBlock { + return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:completionBlock]; +} + +- (id)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock { + if (!key) { + return nil; + } + NSArray> *caches = self.caches; + NSUInteger count = caches.count; + if (count == 0) { + return nil; + } else if (count == 1) { + return [caches.firstObject queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock]; + } + switch (self.queryOperationPolicy) { + case SDImageCachesManagerOperationPolicyHighestOnly: { + id cache = caches.lastObject; + return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyLowestOnly: { + id cache = caches.firstObject; + return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyConcurrent: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self concurrentQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + return operation; + } + break; + case SDImageCachesManagerOperationPolicySerial: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self serialQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + return operation; + } + break; + default: + return nil; + break; + } +} + +- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock { + if (!key) { + return; + } + NSArray> *caches = self.caches; + NSUInteger count = caches.count; + if (count == 0) { + return; + } else if (count == 1) { + [caches.firstObject storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock]; + return; + } + switch (self.storeOperationPolicy) { + case SDImageCachesManagerOperationPolicyHighestOnly: { + id cache = caches.lastObject; + [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyLowestOnly: { + id cache = caches.firstObject; + [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyConcurrent: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self concurrentStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + } + break; + case SDImageCachesManagerOperationPolicySerial: { + [self serialStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator]; + } + break; + default: + break; + } +} + +- (void)removeImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock { + if (!key) { + return; + } + NSArray> *caches = self.caches; + NSUInteger count = caches.count; + if (count == 0) { + return; + } else if (count == 1) { + [caches.firstObject removeImageForKey:key cacheType:cacheType completion:completionBlock]; + return; + } + switch (self.removeOperationPolicy) { + case SDImageCachesManagerOperationPolicyHighestOnly: { + id cache = caches.lastObject; + [cache removeImageForKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyLowestOnly: { + id cache = caches.firstObject; + [cache removeImageForKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyConcurrent: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self concurrentRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + } + break; + case SDImageCachesManagerOperationPolicySerial: { + [self serialRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator]; + } + break; + default: + break; + } +} + +- (void)containsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock { + if (!key) { + return; + } + NSArray> *caches = self.caches; + NSUInteger count = caches.count; + if (count == 0) { + return; + } else if (count == 1) { + [caches.firstObject containsImageForKey:key cacheType:cacheType completion:completionBlock]; + return; + } + switch (self.clearOperationPolicy) { + case SDImageCachesManagerOperationPolicyHighestOnly: { + id cache = caches.lastObject; + [cache containsImageForKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyLowestOnly: { + id cache = caches.firstObject; + [cache containsImageForKey:key cacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyConcurrent: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self concurrentContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + } + break; + case SDImageCachesManagerOperationPolicySerial: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self serialContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + } + break; + default: + break; + } +} + +- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock { + NSArray> *caches = self.caches; + NSUInteger count = caches.count; + if (count == 0) { + return; + } else if (count == 1) { + [caches.firstObject clearWithCacheType:cacheType completion:completionBlock]; + return; + } + switch (self.clearOperationPolicy) { + case SDImageCachesManagerOperationPolicyHighestOnly: { + id cache = caches.lastObject; + [cache clearWithCacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyLowestOnly: { + id cache = caches.firstObject; + [cache clearWithCacheType:cacheType completion:completionBlock]; + } + break; + case SDImageCachesManagerOperationPolicyConcurrent: { + SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new]; + [operation beginWithTotalCount:caches.count]; + [self concurrentClearWithCacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation]; + } + break; + case SDImageCachesManagerOperationPolicySerial: { + [self serialClearWithCacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator]; + } + break; + default: + break; + } +} + +#pragma mark - Concurrent Operation + +- (void)concurrentQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + for (id cache in enumerator) { + [cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) { + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (image) { + // Success + [operation done]; + if (completionBlock) { + completionBlock(image, data, cacheType); + } + return; + } + if (operation.pendingCount == 0) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(nil, nil, SDImageCacheTypeNone); + } + } + }]; + } +} + +- (void)concurrentStoreImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + for (id cache in enumerator) { + [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:^{ + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (operation.pendingCount == 0) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(); + } + } + }]; + } +} + +- (void)concurrentRemoveImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + for (id cache in enumerator) { + [cache removeImageForKey:key cacheType:cacheType completion:^{ + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (operation.pendingCount == 0) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(); + } + } + }]; + } +} + +- (void)concurrentContainsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + for (id cache in enumerator) { + [cache containsImageForKey:key cacheType:cacheType completion:^(SDImageCacheType containsCacheType) { + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (containsCacheType != SDImageCacheTypeNone) { + // Success + [operation done]; + if (completionBlock) { + completionBlock(containsCacheType); + } + return; + } + if (operation.pendingCount == 0) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(SDImageCacheTypeNone); + } + } + }]; + } +} + +- (void)concurrentClearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + for (id cache in enumerator) { + [cache clearWithCacheType:cacheType completion:^{ + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (operation.pendingCount == 0) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(); + } + } + }]; + } +} + +#pragma mark - Serial Operation + +- (void)serialQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + id cache = enumerator.nextObject; + if (!cache) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(nil, nil, SDImageCacheTypeNone); + } + return; + } + @weakify(self); + [cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) { + @strongify(self); + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (image) { + // Success + [operation done]; + if (completionBlock) { + completionBlock(image, data, cacheType); + } + return; + } + // Next + [self serialQueryImageForKey:key options:options context:context cacheType:queryCacheType completion:completionBlock enumerator:enumerator operation:operation]; + }]; +} + +- (void)serialStoreImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator { + NSParameterAssert(enumerator); + id cache = enumerator.nextObject; + if (!cache) { + // Complete + if (completionBlock) { + completionBlock(); + } + return; + } + @weakify(self); + [cache storeImage:image imageData:imageData forKey:key cacheType:cacheType completion:^{ + @strongify(self); + // Next + [self serialStoreImage:image imageData:imageData forKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator]; + }]; +} + +- (void)serialRemoveImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator { + NSParameterAssert(enumerator); + id cache = enumerator.nextObject; + if (!cache) { + // Complete + if (completionBlock) { + completionBlock(); + } + return; + } + @weakify(self); + [cache removeImageForKey:key cacheType:cacheType completion:^{ + @strongify(self); + // Next + [self serialRemoveImageForKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator]; + }]; +} + +- (void)serialContainsImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheContainsCompletionBlock)completionBlock enumerator:(NSEnumerator> *)enumerator operation:(SDImageCachesManagerOperation *)operation { + NSParameterAssert(enumerator); + NSParameterAssert(operation); + id cache = enumerator.nextObject; + if (!cache) { + // Complete + [operation done]; + if (completionBlock) { + completionBlock(SDImageCacheTypeNone); + } + return; + } + @weakify(self); + [cache containsImageForKey:key cacheType:cacheType completion:^(SDImageCacheType containsCacheType) { + @strongify(self); + if (operation.isCancelled) { + // Cancelled + return; + } + if (operation.isFinished) { + // Finished + return; + } + [operation completeOne]; + if (containsCacheType != SDImageCacheTypeNone) { + // Success + [operation done]; + if (completionBlock) { + completionBlock(containsCacheType); + } + return; + } + // Next + [self serialContainsImageForKey:key cacheType:cacheType completion:completionBlock enumerator:enumerator operation:operation]; + }]; +} + +- (void)serialClearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock enumerator:(NSEnumerator> *)enumerator { + NSParameterAssert(enumerator); + id cache = enumerator.nextObject; + if (!cache) { + // Complete + if (completionBlock) { + completionBlock(); + } + return; + } + @weakify(self); + [cache clearWithCacheType:cacheType completion:^{ + @strongify(self); + // Next + [self serialClearWithCacheType:cacheType completion:completionBlock enumerator:enumerator]; + }]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.h new file mode 100644 index 00000000..53b52e5d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.h @@ -0,0 +1,266 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "NSData+ImageContentType.h" + +typedef NSString * SDImageCoderOption NS_STRING_ENUM; +typedef NSDictionary SDImageCoderOptions; +typedef NSMutableDictionary SDImageCoderMutableOptions; + +#pragma mark - Coder Options +// These options are for image decoding +/** + A Boolean value indicating whether to decode the first frame only for animated image during decoding. (NSNumber). If not provide, decode animated image if need. + @note works for `SDImageCoder`. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeFirstFrameOnly; + +/** + A CGFloat value which is greater than or equal to 1.0. This value specify the image scale factor for decoding. If not provide, use 1.0. (NSNumber) + @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeScaleFactor; + +/** + A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format). + Defaults to YES. + @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodePreserveAspectRatio; + +/** + A CGSize value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.preserveAspectRatio`) the value size. + Defaults to CGSizeZero, which means no thumbnail generation at all. + @note Supports for animated image as well. + @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both. + @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `SDAnimatedImageCoder`. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeThumbnailPixelSize; + + +// These options are for image encoding +/** + A Boolean value indicating whether to encode the first frame only for animated image during encoding. (NSNumber). If not provide, encode animated image if need. + @note works for `SDImageCoder`. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeFirstFrameOnly; +/** + A double value between 0.0-1.0 indicating the encode compression quality to produce the image data. 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. If not provide, use 1.0. (NSNumber) + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeCompressionQuality; + +/** + A UIColor(NSColor) value to used for non-alpha image encoding when the input image has alpha channel, the background color will be used to compose the alpha one. If not provide, use white color. + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeBackgroundColor; + +/** + A CGSize value indicating the max image resolution in pixels during encoding. For vector image, this also effect the output vector data information about width and height. The encoder will not generate the encoded image larger than this limit. Note it always use the aspect ratio of input image.. + Defaults to CGSizeZero, which means no max size limit at all. + @note Supports for animated image as well. + @note The output image's width is limited to pixel size's width, the output image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both. + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeMaxPixelSize; + +/** + A NSUInteger value specify the max output data bytes size after encoding. Some lossy format like JPEG/HEIF supports the hint for codec to automatically reduce the quality and match the file size you want. Note this option will override the `SDImageCoderEncodeCompressionQuality`, because now the quality is decided by the encoder. (NSNumber) + @note This is a hint, no guarantee for output size because of compression algorithm limit. And this options does not works for vector images. + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeMaxFileSize; + +/** + A Boolean value indicating the encoding format should contains a thumbnail image into the output data. Only some of image format (like JPEG/HEIF/AVIF) support this behavior. The embed thumbnail will be used during next time thumbnail decoding (provided `.thumbnailPixelSize`), which is faster than full image thumbnail decoding. (NSNumber) + Defaults to NO, which does not embed any thumbnail. + @note The thumbnail image's pixel size is not defined, the encoder can choose the proper pixel size which is suitable for encoding quality. + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeEmbedThumbnail; + +/** + A SDWebImageContext object which hold the original context options from top-level API. (SDWebImageContext) + This option is ignored for all built-in coders and take no effect. + But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data information only. + See `SDWebImageContext` for more detailed information. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderWebImageContext API_DEPRECATED("The coder component will be seperated from Core subspec in the future. Update your code to not rely on this context option.", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED)); + +#pragma mark - Coder +/** + This is the image coder protocol to provide custom image decoding/encoding. + These methods are all required to implement. + @note Pay attention that these methods are not called from main queue. + */ +@protocol SDImageCoder + +@required +#pragma mark - Decoding +/** + Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder. + + @param data The image data so we can look at it + @return YES if this coder can decode the data, NO otherwise + */ +- (BOOL)canDecodeFromData:(nullable NSData *)data; + +/** + Decode the image data to image. + @note This protocol may supports decode animated image frames. You can use `+[SDImageCoderHelper animatedImageWithFrames:]` to produce an animated image with frames. + + @param data The image data to be decoded + @param options A dictionary containing any decoding options. Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for image. Pass @{SDImageCoderDecodeFirstFrameOnly: @(YES)} to decode the first frame only. + @return The decoded image from data + */ +- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data + options:(nullable SDImageCoderOptions *)options; + +#pragma mark - Encoding + +/** + Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder. + For custom coder which introduce new image format, you'd better define a new `SDImageFormat` using like this. If you're creating public coder plugin for new image format, also update `https://github.com/rs/SDWebImage/wiki/Coder-Plugin-List` to avoid same value been defined twice. + * @code + static const SDImageFormat SDImageFormatHEIF = 10; + * @endcode + + @param format The image format + @return YES if this coder can encode the image, NO otherwise + */ +- (BOOL)canEncodeToFormat:(SDImageFormat)format NS_SWIFT_NAME(canEncode(to:)); + +/** + Encode the image to image data. + @note This protocol may supports encode animated image frames. You can use `+[SDImageCoderHelper framesFromAnimatedImage:]` to assemble an animated image with frames. + + @param image The image to be encoded + @param format The image format to encode, you should note `SDImageFormatUndefined` format is also possible + @param options A dictionary containing any encoding options. Pass @{SDImageCoderEncodeCompressionQuality: @(1)} to specify compression quality. + @return The encoded image data + */ +- (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image + format:(SDImageFormat)format + options:(nullable SDImageCoderOptions *)options; + +@end + +#pragma mark - Progressive Coder +/** + This is the image coder protocol to provide custom progressive image decoding. + These methods are all required to implement. + @note Pay attention that these methods are not called from main queue. + */ +@protocol SDProgressiveImageCoder + +@required +/** + Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder. + + @param data The image data so we can look at it + @return YES if this coder can decode the data, NO otherwise + */ +- (BOOL)canIncrementalDecodeFromData:(nullable NSData *)data; + +/** + Because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts + This init method should not return nil + + @param options A dictionary containing any progressive decoding options (instance-level). Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive animated image (each frames should use the same scale). + @return A new instance to do incremental decoding for the specify image format + */ +- (nonnull instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options; + +/** + Update the incremental decoding when new image data available + + @param data The image data has been downloaded so far + @param finished Whether the download has finished + */ +- (void)updateIncrementalData:(nullable NSData *)data finished:(BOOL)finished; + +/** + Incremental decode the current image data to image. + @note Due to the performance issue for progressive decoding and the integration for image view. This method may only return the first frame image even if the image data is animated image. If you want progressive animated image decoding, conform to `SDAnimatedImageCoder` protocol as well and use `animatedImageFrameAtIndex:` instead. + + @param options A dictionary containing any progressive decoding options. Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive image + @return The decoded image from current data + */ +- (nullable UIImage *)incrementalDecodedImageWithOptions:(nullable SDImageCoderOptions *)options; + +@end + +#pragma mark - Animated Image Provider +/** + This is the animated image protocol to provide the basic function for animated image rendering. It's adopted by `SDAnimatedImage` and `SDAnimatedImageCoder` + */ +@protocol SDAnimatedImageProvider + +@required +/** + The original animated image data for current image. If current image is not an animated format, return nil. + We may use this method to grab back the original image data if need, such as NSCoding or compare. + + @return The animated image data + */ +@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData; + +/** + Total animated frame count. + If the frame count is less than 1, then the methods below will be ignored. + + @return Total animated frame count. + */ +@property (nonatomic, assign, readonly) NSUInteger animatedImageFrameCount; +/** + Animation loop count, 0 means infinite looping. + + @return Animation loop count + */ +@property (nonatomic, assign, readonly) NSUInteger animatedImageLoopCount; +/** + Returns the frame image from a specified index. + @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's not recommend to store the images into array because it's memory consuming) + + @param index Frame index (zero based). + @return Frame's image + */ +- (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index; +/** + Returns the frames's duration from a specified index. + @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's recommend to store the durations into array because it's not memory-consuming) + + @param index Frame index (zero based). + @return Frame's duration + */ +- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index; + +@end + +#pragma mark - Animated Coder +/** + This is the animated image coder protocol for custom animated image class like `SDAnimatedImage`. Through it inherit from `SDImageCoder`. We currentlly only use the method `canDecodeFromData:` to detect the proper coder for specify animated image format. + */ +@protocol SDAnimatedImageCoder + +@required +/** + Because animated image coder should keep the original data, we will alloc a new instance with the same class for the specify animated image data + The init method should return nil if it can't decode the specify animated image data to produce any frame. + After the instance created, we may call methods in `SDAnimatedImageProvider` to produce animated image frame. + + @param data The animated image data to be decode + @param options A dictionary containing any animated decoding options (instance-level). Pass @{SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for animated image (each frames should use the same scale). + @return A new instance to do animated decoding for specify image data + */ +- (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.m new file mode 100644 index 00000000..0fda1983 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoder.m @@ -0,0 +1,23 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCoder.h" + +SDImageCoderOption const SDImageCoderDecodeFirstFrameOnly = @"decodeFirstFrameOnly"; +SDImageCoderOption const SDImageCoderDecodeScaleFactor = @"decodeScaleFactor"; +SDImageCoderOption const SDImageCoderDecodePreserveAspectRatio = @"decodePreserveAspectRatio"; +SDImageCoderOption const SDImageCoderDecodeThumbnailPixelSize = @"decodeThumbnailPixelSize"; + +SDImageCoderOption const SDImageCoderEncodeFirstFrameOnly = @"encodeFirstFrameOnly"; +SDImageCoderOption const SDImageCoderEncodeCompressionQuality = @"encodeCompressionQuality"; +SDImageCoderOption const SDImageCoderEncodeBackgroundColor = @"encodeBackgroundColor"; +SDImageCoderOption const SDImageCoderEncodeMaxPixelSize = @"encodeMaxPixelSize"; +SDImageCoderOption const SDImageCoderEncodeMaxFileSize = @"encodeMaxFileSize"; +SDImageCoderOption const SDImageCoderEncodeEmbedThumbnail = @"encodeEmbedThumbnail"; + +SDImageCoderOption const SDImageCoderWebImageContext = @"webImageContext"; diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.h new file mode 100644 index 00000000..77b9d779 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.h @@ -0,0 +1,127 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDImageFrame.h" + +/** + Provide some common helper methods for building the image decoder/encoder. + */ +@interface SDImageCoderHelper : NSObject + +/** + Return an animated image with frames array. + For UIKit, this will apply the patch and then create animated UIImage. The patch is because that `+[UIImage animatedImageWithImages:duration:]` just use the average of duration for each image. So it will not work if different frame has different duration. Therefore we repeat the specify frame for specify times to let it work. + For AppKit, NSImage does not support animates other than GIF. This will try to encode the frames to GIF format and then create an animated NSImage for rendering. Attention the animated image may loss some detail if the input frames contain full alpha channel because GIF only supports 1 bit alpha channel. (For 1 pixel, either transparent or not) + + @param frames The frames array. If no frames or frames is empty, return nil + @return A animated image for rendering on UIImageView(UIKit) or NSImageView(AppKit) + */ ++ (UIImage * _Nullable)animatedImageWithFrames:(NSArray * _Nullable)frames; + +/** + Return frames array from an animated image. + For UIKit, this will unapply the patch for the description above and then create frames array. This will also work for normal animated UIImage. + For AppKit, NSImage does not support animates other than GIF. This will try to decode the GIF imageRep and then create frames array. + + @param animatedImage A animated image. If it's not animated, return nil + @return The frames array + */ ++ (NSArray * _Nullable)framesFromAnimatedImage:(UIImage * _Nullable)animatedImage NS_SWIFT_NAME(frames(from:)); + +/** + Return the shared device-dependent RGB color space. This follows The Get Rule. + On iOS, it's created with deviceRGB (if available, use sRGB). + On macOS, it's from the screen colorspace (if failed, use deviceRGB) + Because it's shared, you should not retain or release this object. + + @return The device-dependent RGB color space + */ ++ (CGColorSpaceRef _Nonnull)colorSpaceGetDeviceRGB CF_RETURNS_NOT_RETAINED; + +/** + Check whether CGImage contains alpha channel. + + @param cgImage The CGImage + @return Return YES if CGImage contains alpha channel, otherwise return NO + */ ++ (BOOL)CGImageContainsAlpha:(_Nonnull CGImageRef)cgImage; + +/** + Create a decoded CGImage by the provided CGImage. This follows The Create Rule and you are response to call release after usage. + It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView. + @note This actually call `CGImageCreateDecoded:orientation:` with the Up orientation. + + @param cgImage The CGImage + @return A new created decoded image + */ ++ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage CF_RETURNS_RETAINED; + +/** + Create a decoded CGImage by the provided CGImage and orientation. This follows The Create Rule and you are response to call release after usage. + It will detect whether image contains alpha channel, then create a new bitmap context with the same size of image, and draw it. This can ensure that the image do not need extra decoding after been set to the imageView. + + @param cgImage The CGImage + @param orientation The EXIF image orientation. + @return A new created decoded image + */ ++ (CGImageRef _Nullable)CGImageCreateDecoded:(_Nonnull CGImageRef)cgImage orientation:(CGImagePropertyOrientation)orientation CF_RETURNS_RETAINED; + +/** + Create a scaled CGImage by the provided CGImage and size. This follows The Create Rule and you are response to call release after usage. + It will detect whether the image size matching the scale size, if not, stretch the image to the target size. + + @param cgImage The CGImage + @param size The scale size in pixel. + @return A new created scaled image + */ ++ (CGImageRef _Nullable)CGImageCreateScaled:(_Nonnull CGImageRef)cgImage size:(CGSize)size CF_RETURNS_RETAINED; + +/** + Return the decoded image by the provided image. This one unlike `CGImageCreateDecoded:`, will not decode the image which contains alpha channel or animated image + @param image The image to be decoded + @return The decoded image + */ ++ (UIImage * _Nullable)decodedImageWithImage:(UIImage * _Nullable)image; + +/** + Return the decoded and probably scaled down image by the provided image. If the image pixels bytes size large than the limit bytes, will try to scale down. Or just works as `decodedImageWithImage:`, never scale up. + @warning You should not pass too small bytes, the suggestion value should be larger than 1MB. Even we use Tile Decoding to avoid OOM, however, small bytes will consume much more CPU time because we need to iterate more times to draw each tile. + + @param image The image to be decoded and scaled down + @param bytes The limit bytes size. Provide 0 to use the build-in limit. + @return The decoded and probably scaled down image + */ ++ (UIImage * _Nullable)decodedAndScaledDownImageWithImage:(UIImage * _Nullable)image limitBytes:(NSUInteger)bytes; + +/** + Control the default limit bytes to scale down largest images. + This value must be larger than 4 Bytes (at least 1x1 pixel). Defaults to 60MB on iOS/tvOS, 90MB on macOS, 30MB on watchOS. + */ +@property (class, readwrite) NSUInteger defaultScaleDownLimitBytes; + +#if SD_UIKIT || SD_WATCH +/** + Convert an EXIF image orientation to an iOS one. + + @param exifOrientation EXIF orientation + @return iOS orientation + */ ++ (UIImageOrientation)imageOrientationFromEXIFOrientation:(CGImagePropertyOrientation)exifOrientation NS_SWIFT_NAME(imageOrientation(from:)); + +/** + Convert an iOS orientation to an EXIF image orientation. + + @param imageOrientation iOS orientation + @return EXIF orientation + */ ++ (CGImagePropertyOrientation)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation; +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.m new file mode 100644 index 00000000..1f641212 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCoderHelper.m @@ -0,0 +1,696 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCoderHelper.h" +#import "SDImageFrame.h" +#import "NSImage+Compatibility.h" +#import "NSData+ImageContentType.h" +#import "SDAnimatedImageRep.h" +#import "UIImage+ForceDecode.h" +#import "SDAssociatedObject.h" +#import "UIImage+Metadata.h" +#import "SDInternalMacros.h" +#import "SDGraphicsImageRenderer.h" +#import + +static inline size_t SDByteAlign(size_t size, size_t alignment) { + return ((size + (alignment - 1)) / alignment) * alignment; +} + +static const size_t kBytesPerPixel = 4; +static const size_t kBitsPerComponent = 8; + +static const CGFloat kBytesPerMB = 1024.0f * 1024.0f; +/* + * Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set + * Suggested value for iPad1 and iPhone 3GS: 60. + * Suggested value for iPad2 and iPhone 4: 120. + * Suggested value for iPhone 3G and iPod 2 and earlier devices: 30. + */ +#if SD_MAC +static CGFloat kDestImageLimitBytes = 90.f * kBytesPerMB; +#elif SD_UIKIT +static CGFloat kDestImageLimitBytes = 60.f * kBytesPerMB; +#elif SD_WATCH +static CGFloat kDestImageLimitBytes = 30.f * kBytesPerMB; +#endif + +static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to overlap the seems where tiles meet. + +@implementation SDImageCoderHelper + ++ (UIImage *)animatedImageWithFrames:(NSArray *)frames { + NSUInteger frameCount = frames.count; + if (frameCount == 0) { + return nil; + } + + UIImage *animatedImage; + +#if SD_UIKIT || SD_WATCH + NSUInteger durations[frameCount]; + for (size_t i = 0; i < frameCount; i++) { + durations[i] = frames[i].duration * 1000; + } + NSUInteger const gcd = gcdArray(frameCount, durations); + __block NSTimeInterval totalDuration = 0; + NSMutableArray *animatedImages = [NSMutableArray arrayWithCapacity:frameCount]; + [frames enumerateObjectsUsingBlock:^(SDImageFrame * _Nonnull frame, NSUInteger idx, BOOL * _Nonnull stop) { + UIImage *image = frame.image; + NSUInteger duration = frame.duration * 1000; + totalDuration += frame.duration; + NSUInteger repeatCount; + if (gcd) { + repeatCount = duration / gcd; + } else { + repeatCount = 1; + } + for (size_t i = 0; i < repeatCount; ++i) { + [animatedImages addObject:image]; + } + }]; + + animatedImage = [UIImage animatedImageWithImages:animatedImages duration:totalDuration]; + +#else + + NSMutableData *imageData = [NSMutableData data]; + CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:SDImageFormatGIF]; + // Create an image destination. GIF does not support EXIF image orientation + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL); + if (!imageDestination) { + // Handle failure. + return nil; + } + + for (size_t i = 0; i < frameCount; i++) { + @autoreleasepool { + SDImageFrame *frame = frames[i]; + NSTimeInterval frameDuration = frame.duration; + CGImageRef frameImageRef = frame.image.CGImage; + NSDictionary *frameProperties = @{(__bridge NSString *)kCGImagePropertyGIFDictionary : @{(__bridge NSString *)kCGImagePropertyGIFDelayTime : @(frameDuration)}}; + CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties); + } + } + // Finalize the destination. + if (CGImageDestinationFinalize(imageDestination) == NO) { + // Handle failure. + CFRelease(imageDestination); + return nil; + } + CFRelease(imageDestination); + CGFloat scale = MAX(frames.firstObject.image.scale, 1); + + SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:imageData]; + NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale); + imageRep.size = size; + animatedImage = [[NSImage alloc] initWithSize:size]; + [animatedImage addRepresentation:imageRep]; +#endif + + return animatedImage; +} + ++ (NSArray *)framesFromAnimatedImage:(UIImage *)animatedImage { + if (!animatedImage) { + return nil; + } + + NSMutableArray *frames = [NSMutableArray array]; + NSUInteger frameCount = 0; + +#if SD_UIKIT || SD_WATCH + NSArray *animatedImages = animatedImage.images; + frameCount = animatedImages.count; + if (frameCount == 0) { + return nil; + } + + NSTimeInterval avgDuration = animatedImage.duration / frameCount; + if (avgDuration == 0) { + avgDuration = 0.1; // if it's a animated image but no duration, set it to default 100ms (this do not have that 10ms limit like GIF or WebP to allow custom coder provide the limit) + } + + __block NSUInteger repeatCount = 1; + __block UIImage *previousImage = animatedImages.firstObject; + [animatedImages enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) { + // ignore first + if (idx == 0) { + return; + } + if ([image isEqual:previousImage]) { + repeatCount++; + } else { + SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount]; + [frames addObject:frame]; + repeatCount = 1; + } + previousImage = image; + }]; + // last one + SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount]; + [frames addObject:frame]; + +#else + + NSRect imageRect = NSMakeRect(0, 0, animatedImage.size.width, animatedImage.size.height); + NSImageRep *imageRep = [animatedImage bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (!bitmapImageRep) { + return nil; + } + frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue]; + if (frameCount == 0) { + return nil; + } + CGFloat scale = animatedImage.scale; + + for (size_t i = 0; i < frameCount; i++) { + @autoreleasepool { + // NSBitmapImageRep need to manually change frame. "Good taste" API + [bitmapImageRep setProperty:NSImageCurrentFrame withValue:@(i)]; + NSTimeInterval frameDuration = [[bitmapImageRep valueForProperty:NSImageCurrentFrameDuration] doubleValue]; + NSImage *frameImage = [[NSImage alloc] initWithCGImage:bitmapImageRep.CGImage scale:scale orientation:kCGImagePropertyOrientationUp]; + SDImageFrame *frame = [SDImageFrame frameWithImage:frameImage duration:frameDuration]; + [frames addObject:frame]; + } + } +#endif + + return frames; +} + ++ (CGColorSpaceRef)colorSpaceGetDeviceRGB { + static CGColorSpaceRef colorSpace; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + }); + return colorSpace; +} + ++ (BOOL)CGImageContainsAlpha:(CGImageRef)cgImage { + if (!cgImage) { + return NO; + } + CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(cgImage); + BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone || + alphaInfo == kCGImageAlphaNoneSkipFirst || + alphaInfo == kCGImageAlphaNoneSkipLast); + return hasAlpha; +} + ++ (CGImageRef)CGImageCreateDecoded:(CGImageRef)cgImage { + return [self CGImageCreateDecoded:cgImage orientation:kCGImagePropertyOrientationUp]; +} + ++ (CGImageRef)CGImageCreateDecoded:(CGImageRef)cgImage orientation:(CGImagePropertyOrientation)orientation { + if (!cgImage) { + return NULL; + } + size_t width = CGImageGetWidth(cgImage); + size_t height = CGImageGetHeight(cgImage); + if (width == 0 || height == 0) return NULL; + size_t newWidth; + size_t newHeight; + switch (orientation) { + case kCGImagePropertyOrientationLeft: + case kCGImagePropertyOrientationLeftMirrored: + case kCGImagePropertyOrientationRight: + case kCGImagePropertyOrientationRightMirrored: { + // These orientation should swap width & height + newWidth = height; + newHeight = width; + } + break; + default: { + newWidth = width; + newHeight = height; + } + break; + } + + BOOL hasAlpha = [self CGImageContainsAlpha:cgImage]; + // kCGImageAlphaNone is not supported in CGBitmapContextCreate. + // Check #3330 for more detail about why this bitmap is choosen. + CGBitmapInfo bitmapInfo; + if (hasAlpha) { + // iPhone GPU prefer to use BGRA8888, see: https://forums.raywenderlich.com/t/why-mtlpixelformat-bgra8unorm/53489 + // BGRA8888 + bitmapInfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; + } else { + // BGR888 previously works on iOS 8~iOS 14, however, iOS 15+ will result a black image. FB9958017 + // RGB888 + bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast; + } + CGContextRef context = CGBitmapContextCreate(NULL, newWidth, newHeight, 8, 0, [self colorSpaceGetDeviceRGB], bitmapInfo); + if (!context) { + return NULL; + } + + // Apply transform + CGAffineTransform transform = SDCGContextTransformFromOrientation(orientation, CGSizeMake(newWidth, newHeight)); + CGContextConcatCTM(context, transform); + CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage); // The rect is bounding box of CGImage, don't swap width & height + CGImageRef newImageRef = CGBitmapContextCreateImage(context); + CGContextRelease(context); + + return newImageRef; +} + ++ (CGImageRef)CGImageCreateScaled:(CGImageRef)cgImage size:(CGSize)size { + if (!cgImage) { + return NULL; + } + size_t width = CGImageGetWidth(cgImage); + size_t height = CGImageGetHeight(cgImage); + if (width == size.width && height == size.height) { + CGImageRetain(cgImage); + return cgImage; + } + + __block vImage_Buffer input_buffer = {}, output_buffer = {}; + @onExit { + if (input_buffer.data) free(input_buffer.data); + if (output_buffer.data) free(output_buffer.data); + }; + BOOL hasAlpha = [self CGImageContainsAlpha:cgImage]; + // kCGImageAlphaNone is not supported in CGBitmapContextCreate. + // Check #3330 for more detail about why this bitmap is choosen. + CGBitmapInfo bitmapInfo; + if (hasAlpha) { + // iPhone GPU prefer to use BGRA8888, see: https://forums.raywenderlich.com/t/why-mtlpixelformat-bgra8unorm/53489 + // BGRA8888 + bitmapInfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; + } else { + // BGR888 previously works on iOS 8~iOS 14, however, iOS 15+ will result a black image. FB9958017 + // RGB888 + bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast; + } + vImage_CGImageFormat format = (vImage_CGImageFormat) { + .bitsPerComponent = 8, + .bitsPerPixel = 32, + .colorSpace = NULL, + .bitmapInfo = bitmapInfo, + .version = 0, + .decode = NULL, + .renderingIntent = CGImageGetRenderingIntent(cgImage) + }; + + vImage_Error a_ret = vImageBuffer_InitWithCGImage(&input_buffer, &format, NULL, cgImage, kvImageNoFlags); + if (a_ret != kvImageNoError) return NULL; + output_buffer.width = MAX(size.width, 0); + output_buffer.height = MAX(size.height, 0); + output_buffer.rowBytes = SDByteAlign(output_buffer.width * 4, 64); + output_buffer.data = malloc(output_buffer.rowBytes * output_buffer.height); + if (!output_buffer.data) return NULL; + + vImage_Error ret = vImageScale_ARGB8888(&input_buffer, &output_buffer, NULL, kvImageHighQualityResampling); + if (ret != kvImageNoError) return NULL; + + CGImageRef outputImage = vImageCreateCGImageFromBuffer(&output_buffer, &format, NULL, NULL, kvImageNoFlags, &ret); + if (ret != kvImageNoError) { + CGImageRelease(outputImage); + return NULL; + } + + return outputImage; +} + ++ (UIImage *)decodedImageWithImage:(UIImage *)image { + if (![self shouldDecodeImage:image]) { + return image; + } + + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + return image; + } + BOOL hasAlpha = [self CGImageContainsAlpha:imageRef]; + // Prefer to use new Image Renderer to re-draw image, instead of low-level CGBitmapContext and CGContextDrawImage + // This can keep both OS compatible and don't fight with Apple's performance optimization + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.opaque = !hasAlpha; + format.scale = image.scale; + CGSize imageSize = image.size; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:imageSize format:format]; + UIImage *decodedImage = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)]; + }]; + SDImageCopyAssociatedObject(image, decodedImage); + decodedImage.sd_isDecoded = YES; + return decodedImage; +} + ++ (UIImage *)decodedAndScaledDownImageWithImage:(UIImage *)image limitBytes:(NSUInteger)bytes { + if (![self shouldDecodeImage:image]) { + return image; + } + + if (![self shouldScaleDownImage:image limitBytes:bytes]) { + return [self decodedImageWithImage:image]; + } + + CGFloat destTotalPixels; + CGFloat tileTotalPixels; + if (bytes == 0) { + bytes = kDestImageLimitBytes; + } + destTotalPixels = bytes / kBytesPerPixel; + tileTotalPixels = destTotalPixels / 3; + CGContextRef destContext = NULL; + + // autorelease the bitmap context and all vars to help system to free memory when there are memory warning. + // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory]; + @autoreleasepool { + CGImageRef sourceImageRef = image.CGImage; + + CGSize sourceResolution = CGSizeZero; + sourceResolution.width = CGImageGetWidth(sourceImageRef); + sourceResolution.height = CGImageGetHeight(sourceImageRef); + CGFloat sourceTotalPixels = sourceResolution.width * sourceResolution.height; + // Determine the scale ratio to apply to the input image + // that results in an output image of the defined size. + // see kDestImageSizeMB, and how it relates to destTotalPixels. + CGFloat imageScale = sqrt(destTotalPixels / sourceTotalPixels); + CGSize destResolution = CGSizeZero; + destResolution.width = MAX(1, (int)(sourceResolution.width * imageScale)); + destResolution.height = MAX(1, (int)(sourceResolution.height * imageScale)); + + // device color space + CGColorSpaceRef colorspaceRef = [self colorSpaceGetDeviceRGB]; + BOOL hasAlpha = [self CGImageContainsAlpha:sourceImageRef]; + + // kCGImageAlphaNone is not supported in CGBitmapContextCreate. + // Check #3330 for more detail about why this bitmap is choosen. + CGBitmapInfo bitmapInfo; + if (hasAlpha) { + // iPhone GPU prefer to use BGRA8888, see: https://forums.raywenderlich.com/t/why-mtlpixelformat-bgra8unorm/53489 + // BGRA8888 + bitmapInfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; + } else { + // BGR888 previously works on iOS 8~iOS 14, however, iOS 15+ will result a black image. FB9958017 + // RGB888 + bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast; + } + destContext = CGBitmapContextCreate(NULL, + destResolution.width, + destResolution.height, + kBitsPerComponent, + 0, + colorspaceRef, + bitmapInfo); + + if (destContext == NULL) { + return image; + } + CGContextSetInterpolationQuality(destContext, kCGInterpolationHigh); + + // Now define the size of the rectangle to be used for the + // incremental bits from the input image to the output image. + // we use a source tile width equal to the width of the source + // image due to the way that iOS retrieves image data from disk. + // iOS must decode an image from disk in full width 'bands', even + // if current graphics context is clipped to a subrect within that + // band. Therefore we fully utilize all of the pixel data that results + // from a decoding operation by anchoring our tile size to the full + // width of the input image. + CGRect sourceTile = CGRectZero; + sourceTile.size.width = sourceResolution.width; + // The source tile height is dynamic. Since we specified the size + // of the source tile in MB, see how many rows of pixels high it + // can be given the input image width. + sourceTile.size.height = MAX(1, (int)(tileTotalPixels / sourceTile.size.width)); + sourceTile.origin.x = 0.0f; + // The output tile is the same proportions as the input tile, but + // scaled to image scale. + CGRect destTile; + destTile.size.width = destResolution.width; + destTile.size.height = sourceTile.size.height * imageScale; + destTile.origin.x = 0.0f; + // The source seem overlap is proportionate to the destination seem overlap. + // this is the amount of pixels to overlap each tile as we assemble the output image. + float sourceSeemOverlap = (int)((kDestSeemOverlap/destResolution.height)*sourceResolution.height); + CGImageRef sourceTileImageRef; + // calculate the number of read/write operations required to assemble the + // output image. + int iterations = (int)( sourceResolution.height / sourceTile.size.height ); + // If tile height doesn't divide the image height evenly, add another iteration + // to account for the remaining pixels. + int remainder = (int)sourceResolution.height % (int)sourceTile.size.height; + if(remainder) { + iterations++; + } + // Add seem overlaps to the tiles, but save the original tile height for y coordinate calculations. + float sourceTileHeightMinusOverlap = sourceTile.size.height; + sourceTile.size.height += sourceSeemOverlap; + destTile.size.height += kDestSeemOverlap; + for( int y = 0; y < iterations; ++y ) { + @autoreleasepool { + sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap; + destTile.origin.y = destResolution.height - (( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + kDestSeemOverlap); + sourceTileImageRef = CGImageCreateWithImageInRect( sourceImageRef, sourceTile ); + if( y == iterations - 1 && remainder ) { + float dify = destTile.size.height; + destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale; + dify -= destTile.size.height; + destTile.origin.y = MIN(0, destTile.origin.y + dify); + } + CGContextDrawImage( destContext, destTile, sourceTileImageRef ); + CGImageRelease( sourceTileImageRef ); + } + } + + CGImageRef destImageRef = CGBitmapContextCreateImage(destContext); + CGContextRelease(destContext); + if (destImageRef == NULL) { + return image; + } +#if SD_MAC + UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:kCGImagePropertyOrientationUp]; +#else + UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:image.imageOrientation]; +#endif + CGImageRelease(destImageRef); + if (destImage == nil) { + return image; + } + SDImageCopyAssociatedObject(image, destImage); + destImage.sd_isDecoded = YES; + return destImage; + } +} + ++ (NSUInteger)defaultScaleDownLimitBytes { + return kDestImageLimitBytes; +} + ++ (void)setDefaultScaleDownLimitBytes:(NSUInteger)defaultScaleDownLimitBytes { + if (defaultScaleDownLimitBytes < kBytesPerPixel) { + return; + } + kDestImageLimitBytes = defaultScaleDownLimitBytes; +} + +#if SD_UIKIT || SD_WATCH +// Convert an EXIF image orientation to an iOS one. ++ (UIImageOrientation)imageOrientationFromEXIFOrientation:(CGImagePropertyOrientation)exifOrientation { + UIImageOrientation imageOrientation = UIImageOrientationUp; + switch (exifOrientation) { + case kCGImagePropertyOrientationUp: + imageOrientation = UIImageOrientationUp; + break; + case kCGImagePropertyOrientationDown: + imageOrientation = UIImageOrientationDown; + break; + case kCGImagePropertyOrientationLeft: + imageOrientation = UIImageOrientationLeft; + break; + case kCGImagePropertyOrientationRight: + imageOrientation = UIImageOrientationRight; + break; + case kCGImagePropertyOrientationUpMirrored: + imageOrientation = UIImageOrientationUpMirrored; + break; + case kCGImagePropertyOrientationDownMirrored: + imageOrientation = UIImageOrientationDownMirrored; + break; + case kCGImagePropertyOrientationLeftMirrored: + imageOrientation = UIImageOrientationLeftMirrored; + break; + case kCGImagePropertyOrientationRightMirrored: + imageOrientation = UIImageOrientationRightMirrored; + break; + default: + break; + } + return imageOrientation; +} + +// Convert an iOS orientation to an EXIF image orientation. ++ (CGImagePropertyOrientation)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation { + CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp; + switch (imageOrientation) { + case UIImageOrientationUp: + exifOrientation = kCGImagePropertyOrientationUp; + break; + case UIImageOrientationDown: + exifOrientation = kCGImagePropertyOrientationDown; + break; + case UIImageOrientationLeft: + exifOrientation = kCGImagePropertyOrientationLeft; + break; + case UIImageOrientationRight: + exifOrientation = kCGImagePropertyOrientationRight; + break; + case UIImageOrientationUpMirrored: + exifOrientation = kCGImagePropertyOrientationUpMirrored; + break; + case UIImageOrientationDownMirrored: + exifOrientation = kCGImagePropertyOrientationDownMirrored; + break; + case UIImageOrientationLeftMirrored: + exifOrientation = kCGImagePropertyOrientationLeftMirrored; + break; + case UIImageOrientationRightMirrored: + exifOrientation = kCGImagePropertyOrientationRightMirrored; + break; + default: + break; + } + return exifOrientation; +} +#endif + +#pragma mark - Helper Function ++ (BOOL)shouldDecodeImage:(nullable UIImage *)image { + // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error + if (image == nil) { + return NO; + } + // Avoid extra decode + if (image.sd_isDecoded) { + return NO; + } + // do not decode animated images + if (image.sd_isAnimated) { + return NO; + } + // do not decode vector images + if (image.sd_isVector) { + return NO; + } + + return YES; +} + ++ (BOOL)shouldScaleDownImage:(nonnull UIImage *)image limitBytes:(NSUInteger)bytes { + BOOL shouldScaleDown = YES; + + CGImageRef sourceImageRef = image.CGImage; + CGSize sourceResolution = CGSizeZero; + sourceResolution.width = CGImageGetWidth(sourceImageRef); + sourceResolution.height = CGImageGetHeight(sourceImageRef); + float sourceTotalPixels = sourceResolution.width * sourceResolution.height; + if (sourceTotalPixels <= 0) { + return NO; + } + CGFloat destTotalPixels; + if (bytes == 0) { + bytes = [self defaultScaleDownLimitBytes]; + } + bytes = MAX(bytes, kBytesPerPixel); + destTotalPixels = bytes / kBytesPerPixel; + float imageScale = destTotalPixels / sourceTotalPixels; + if (imageScale < 1) { + shouldScaleDown = YES; + } else { + shouldScaleDown = NO; + } + + return shouldScaleDown; +} + +static inline CGAffineTransform SDCGContextTransformFromOrientation(CGImagePropertyOrientation orientation, CGSize size) { + // Inspiration from @libfeihu + // We need to calculate the proper transformation to make the image upright. + // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. + CGAffineTransform transform = CGAffineTransformIdentity; + + switch (orientation) { + case kCGImagePropertyOrientationDown: + case kCGImagePropertyOrientationDownMirrored: + transform = CGAffineTransformTranslate(transform, size.width, size.height); + transform = CGAffineTransformRotate(transform, M_PI); + break; + + case kCGImagePropertyOrientationLeft: + case kCGImagePropertyOrientationLeftMirrored: + transform = CGAffineTransformTranslate(transform, size.width, 0); + transform = CGAffineTransformRotate(transform, M_PI_2); + break; + + case kCGImagePropertyOrientationRight: + case kCGImagePropertyOrientationRightMirrored: + transform = CGAffineTransformTranslate(transform, 0, size.height); + transform = CGAffineTransformRotate(transform, -M_PI_2); + break; + case kCGImagePropertyOrientationUp: + case kCGImagePropertyOrientationUpMirrored: + break; + } + + switch (orientation) { + case kCGImagePropertyOrientationUpMirrored: + case kCGImagePropertyOrientationDownMirrored: + transform = CGAffineTransformTranslate(transform, size.width, 0); + transform = CGAffineTransformScale(transform, -1, 1); + break; + + case kCGImagePropertyOrientationLeftMirrored: + case kCGImagePropertyOrientationRightMirrored: + transform = CGAffineTransformTranslate(transform, size.height, 0); + transform = CGAffineTransformScale(transform, -1, 1); + break; + case kCGImagePropertyOrientationUp: + case kCGImagePropertyOrientationDown: + case kCGImagePropertyOrientationLeft: + case kCGImagePropertyOrientationRight: + break; + } + + return transform; +} + +#if SD_UIKIT || SD_WATCH +static NSUInteger gcd(NSUInteger a, NSUInteger b) { + NSUInteger c; + while (a != 0) { + c = a; + a = b % a; + b = c; + } + return b; +} + +static NSUInteger gcdArray(size_t const count, NSUInteger const * const values) { + if (count == 0) { + return 0; + } + NSUInteger result = values[0]; + for (size_t i = 1; i < count; ++i) { + result = gcd(values[i], result); + } + return result; +} +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.h new file mode 100644 index 00000000..14b655da --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.h @@ -0,0 +1,58 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageCoder.h" + +/** + Global object holding the array of coders, so that we avoid passing them from object to object. + Uses a priority queue behind scenes, which means the latest added coders have the highest priority. + This is done so when encoding/decoding something, we go through the list and ask each coder if they can handle the current data. + That way, users can add their custom coders while preserving our existing prebuilt ones + + Note: the `coders` getter will return the coders in their reversed order + Example: + - by default we internally set coders = `IOCoder`, `GIFCoder`, `APNGCoder` + - calling `coders` will return `@[IOCoder, GIFCoder, APNGCoder]` + - call `[addCoder:[MyCrazyCoder new]]` + - calling `coders` now returns `@[IOCoder, GIFCoder, APNGCoder, MyCrazyCoder]` + + Coders + ------ + A coder must conform to the `SDImageCoder` protocol or even to `SDProgressiveImageCoder` if it supports progressive decoding + Conformance is important because that way, they will implement `canDecodeFromData` or `canEncodeToFormat` + Those methods are called on each coder in the array (using the priority order) until one of them returns YES. + That means that coder can decode that data / encode to that format + */ +@interface SDImageCodersManager : NSObject + +/** + Returns the global shared coders manager instance. + */ +@property (nonatomic, class, readonly, nonnull) SDImageCodersManager *sharedManager; + +/** + All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority + */ +@property (nonatomic, copy, nullable) NSArray> *coders; + +/** + Add a new coder to the end of coders array. Which has the highest priority. + + @param coder coder + */ +- (void)addCoder:(nonnull id)coder; + +/** + Remove a coder in the coders array. + + @param coder coder + */ +- (void)removeCoder:(nonnull id)coder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.m new file mode 100644 index 00000000..00653d1c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageCodersManager.m @@ -0,0 +1,130 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCodersManager.h" +#import "SDImageIOCoder.h" +#import "SDImageGIFCoder.h" +#import "SDImageAPNGCoder.h" +#import "SDImageHEICCoder.h" +#import "SDInternalMacros.h" + +@interface SDImageCodersManager () + +@property (nonatomic, strong, nonnull) NSMutableArray> *imageCoders; + +@end + +@implementation SDImageCodersManager { + SD_LOCK_DECLARE(_codersLock); +} + ++ (nonnull instancetype)sharedManager { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (instancetype)init { + if (self = [super init]) { + // initialize with default coders + _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]]; + SD_LOCK_INIT(_codersLock); + } + return self; +} + +- (NSArray> *)coders { + SD_LOCK(_codersLock); + NSArray> *coders = [_imageCoders copy]; + SD_UNLOCK(_codersLock); + return coders; +} + +- (void)setCoders:(NSArray> *)coders { + SD_LOCK(_codersLock); + [_imageCoders removeAllObjects]; + if (coders.count) { + [_imageCoders addObjectsFromArray:coders]; + } + SD_UNLOCK(_codersLock); +} + +#pragma mark - Coder IO operations + +- (void)addCoder:(nonnull id)coder { + if (![coder conformsToProtocol:@protocol(SDImageCoder)]) { + return; + } + SD_LOCK(_codersLock); + [_imageCoders addObject:coder]; + SD_UNLOCK(_codersLock); +} + +- (void)removeCoder:(nonnull id)coder { + if (![coder conformsToProtocol:@protocol(SDImageCoder)]) { + return; + } + SD_LOCK(_codersLock); + [_imageCoders removeObject:coder]; + SD_UNLOCK(_codersLock); +} + +#pragma mark - SDImageCoder +- (BOOL)canDecodeFromData:(NSData *)data { + NSArray> *coders = self.coders; + for (id coder in coders.reverseObjectEnumerator) { + if ([coder canDecodeFromData:data]) { + return YES; + } + } + return NO; +} + +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + NSArray> *coders = self.coders; + for (id coder in coders.reverseObjectEnumerator) { + if ([coder canEncodeToFormat:format]) { + return YES; + } + } + return NO; +} + +- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options { + if (!data) { + return nil; + } + UIImage *image; + NSArray> *coders = self.coders; + for (id coder in coders.reverseObjectEnumerator) { + if ([coder canDecodeFromData:data]) { + image = [coder decodedImageWithData:data options:options]; + break; + } + } + + return image; +} + +- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options { + if (!image) { + return nil; + } + NSArray> *coders = self.coders; + for (id coder in coders.reverseObjectEnumerator) { + if ([coder canEncodeToFormat:format]) { + return [coder encodedDataWithImage:image format:format options:options]; + } + } + return nil; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.h new file mode 100644 index 00000000..a93fd9c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.h @@ -0,0 +1,36 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/** + This class is used for creating animated images via `animatedImageWithFrames` in `SDImageCoderHelper`. + @note If you need to specify animated images loop count, use `sd_imageLoopCount` property in `UIImage+Metadata.h`. + */ +@interface SDImageFrame : NSObject + +/** + The image of current frame. You should not set an animated image. + */ +@property (nonatomic, strong, readonly, nonnull) UIImage *image; +/** + The duration of current frame to be displayed. The number is seconds but not milliseconds. You should not set this to zero. + */ +@property (nonatomic, readonly, assign) NSTimeInterval duration; + +/** + Create a frame instance with specify image and duration + + @param image current frame's image + @param duration current frame's duration + @return frame instance + */ ++ (instancetype _Nonnull)frameWithImage:(UIImage * _Nonnull)image duration:(NSTimeInterval)duration; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.m new file mode 100644 index 00000000..f035af54 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageFrame.m @@ -0,0 +1,28 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageFrame.h" + +@interface SDImageFrame () + +@property (nonatomic, strong, readwrite, nonnull) UIImage *image; +@property (nonatomic, readwrite, assign) NSTimeInterval duration; + +@end + +@implementation SDImageFrame + ++ (instancetype)frameWithImage:(UIImage *)image duration:(NSTimeInterval)duration { + SDImageFrame *frame = [[SDImageFrame alloc] init]; + frame.image = image; + frame.duration = duration; + + return frame; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.h new file mode 100644 index 00000000..5ef67acd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.h @@ -0,0 +1,22 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageIOAnimatedCoder.h" + +/** + Built in coder using ImageIO that supports animated GIF encoding/decoding + @note `SDImageIOCoder` supports GIF but only as static (will use the 1st frame). + @note Use `SDImageGIFCoder` for fully animated GIFs. For `UIImageView`, it will produce animated `UIImage`(`NSImage` on macOS) for rendering. For `SDAnimatedImageView`, it will use `SDAnimatedImage` for rendering. + @note The recommended approach for animated GIFs is using `SDAnimatedImage` with `SDAnimatedImageView`. It's more performant than `UIImageView` for GIF displaying(especially on memory usage) + */ +@interface SDImageGIFCoder : SDImageIOAnimatedCoder + +@property (nonatomic, class, readonly, nonnull) SDImageGIFCoder *sharedCoder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.m new file mode 100644 index 00000000..a1838b16 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGIFCoder.m @@ -0,0 +1,58 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageGIFCoder.h" +#import "SDImageIOAnimatedCoderInternal.h" +#if SD_MAC +#import +#else +#import +#endif + +@implementation SDImageGIFCoder + ++ (instancetype)sharedCoder { + static SDImageGIFCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageGIFCoder alloc] init]; + }); + return coder; +} + +#pragma mark - Subclass Override + ++ (SDImageFormat)imageFormat { + return SDImageFormatGIF; +} + ++ (NSString *)imageUTType { + return (__bridge NSString *)kSDUTTypeGIF; +} + ++ (NSString *)dictionaryProperty { + return (__bridge NSString *)kCGImagePropertyGIFDictionary; +} + ++ (NSString *)unclampedDelayTimeProperty { + return (__bridge NSString *)kCGImagePropertyGIFUnclampedDelayTime; +} + ++ (NSString *)delayTimeProperty { + return (__bridge NSString *)kCGImagePropertyGIFDelayTime; +} + ++ (NSString *)loopCountProperty { + return (__bridge NSString *)kCGImagePropertyGIFLoopCount; +} + ++ (NSUInteger)defaultLoopCount { + return 1; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.h new file mode 100644 index 00000000..131d6850 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.h @@ -0,0 +1,28 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import + +/** + These following graphics context method are provided to easily write cross-platform(AppKit/UIKit) code. + For UIKit, these methods just call the same method in `UIGraphics.h`. See the documentation for usage. + For AppKit, these methods use `NSGraphicsContext` to create image context and match the behavior like UIKit. + @note If you don't care bitmap format (ARGB8888) and just draw image, use `SDGraphicsImageRenderer` instead. It's more performant on RAM usage.` + */ + +/// Returns the current graphics context. +FOUNDATION_EXPORT CGContextRef __nullable SDGraphicsGetCurrentContext(void) CF_RETURNS_NOT_RETAINED; +/// Creates a bitmap-based graphics context and makes it the current context. +FOUNDATION_EXPORT void SDGraphicsBeginImageContext(CGSize size); +/// Creates a bitmap-based graphics context with the specified options. +FOUNDATION_EXPORT void SDGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); +/// Removes the current bitmap-based graphics context from the top of the stack. +FOUNDATION_EXPORT void SDGraphicsEndImageContext(void); +/// Returns an image based on the contents of the current bitmap-based graphics context. +FOUNDATION_EXPORT UIImage * __nullable SDGraphicsGetImageFromCurrentImageContext(void); diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.m new file mode 100644 index 00000000..f6f89279 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageGraphics.m @@ -0,0 +1,115 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageGraphics.h" +#import "NSImage+Compatibility.h" +#import "SDImageCoderHelper.h" +#import "objc/runtime.h" + +#if SD_MAC +static void *kNSGraphicsContextScaleFactorKey; + +static CGContextRef SDCGContextCreateBitmapContext(CGSize size, BOOL opaque, CGFloat scale) { + if (scale == 0) { + // Match `UIGraphicsBeginImageContextWithOptions`, reset to the scale factor of the device’s main screen if scale is 0. + scale = [NSScreen mainScreen].backingScaleFactor; + } + size_t width = ceil(size.width * scale); + size_t height = ceil(size.height * scale); + if (width < 1 || height < 1) return NULL; + + CGColorSpaceRef space = [SDImageCoderHelper colorSpaceGetDeviceRGB]; + // kCGImageAlphaNone is not supported in CGBitmapContextCreate. + // Check #3330 for more detail about why this bitmap is choosen. + CGBitmapInfo bitmapInfo; + if (!opaque) { + // iPhone GPU prefer to use BGRA8888, see: https://forums.raywenderlich.com/t/why-mtlpixelformat-bgra8unorm/53489 + // BGRA8888 + bitmapInfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; + } else { + // BGR888 previously works on iOS 8~iOS 14, however, iOS 15+ will result a black image. FB9958017 + // RGB888 + bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast; + } + CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, space, bitmapInfo); + if (!context) { + return NULL; + } + CGContextScaleCTM(context, scale, scale); + + return context; +} +#endif + +CGContextRef SDGraphicsGetCurrentContext(void) { +#if SD_UIKIT || SD_WATCH + return UIGraphicsGetCurrentContext(); +#else + return NSGraphicsContext.currentContext.CGContext; +#endif +} + +void SDGraphicsBeginImageContext(CGSize size) { +#if SD_UIKIT || SD_WATCH + UIGraphicsBeginImageContext(size); +#else + SDGraphicsBeginImageContextWithOptions(size, NO, 1.0); +#endif +} + +void SDGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) { +#if SD_UIKIT || SD_WATCH + UIGraphicsBeginImageContextWithOptions(size, opaque, scale); +#else + CGContextRef context = SDCGContextCreateBitmapContext(size, opaque, scale); + if (!context) { + return; + } + NSGraphicsContext *graphicsContext = [NSGraphicsContext graphicsContextWithCGContext:context flipped:NO]; + objc_setAssociatedObject(graphicsContext, &kNSGraphicsContextScaleFactorKey, @(scale), OBJC_ASSOCIATION_RETAIN); + CGContextRelease(context); + [NSGraphicsContext saveGraphicsState]; + NSGraphicsContext.currentContext = graphicsContext; +#endif +} + +void SDGraphicsEndImageContext(void) { +#if SD_UIKIT || SD_WATCH + UIGraphicsEndImageContext(); +#else + [NSGraphicsContext restoreGraphicsState]; +#endif +} + +UIImage * SDGraphicsGetImageFromCurrentImageContext(void) { +#if SD_UIKIT || SD_WATCH + return UIGraphicsGetImageFromCurrentImageContext(); +#else + NSGraphicsContext *context = NSGraphicsContext.currentContext; + CGContextRef contextRef = context.CGContext; + if (!contextRef) { + return nil; + } + CGImageRef imageRef = CGBitmapContextCreateImage(contextRef); + if (!imageRef) { + return nil; + } + CGFloat scale = 0; + NSNumber *scaleFactor = objc_getAssociatedObject(context, &kNSGraphicsContextScaleFactorKey); + if ([scaleFactor isKindOfClass:[NSNumber class]]) { + scale = scaleFactor.doubleValue; + } + if (!scale) { + // reset to the scale factor of the device’s main screen if scale is 0. + scale = [NSScreen mainScreen].backingScaleFactor; + } + NSImage *image = [[NSImage alloc] initWithCGImage:imageRef scale:scale orientation:kCGImagePropertyOrientationUp]; + CGImageRelease(imageRef); + return image; +#endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.h new file mode 100644 index 00000000..f7dd6612 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.h @@ -0,0 +1,25 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDImageIOAnimatedCoder.h" + +/** + This coder is used for HEIC (HEIF with HEVC container codec) image format. + Image/IO provide the static HEIC (.heic) support in iOS 11/macOS 10.13/tvOS 11/watchOS 4+. + Image/IO provide the animated HEIC (.heics) support in iOS 13/macOS 10.15/tvOS 13/watchOS 6+. + See https://nokiatech.github.io/heif/technical.html for the standard. + @note This coder is not in the default coder list for now, since HEIC animated image is really rare, and Apple's implementation still contains performance issues. You can enable if you need this. + @note If you need to support lower firmware version for HEIF, you can have a try at https://github.com/SDWebImage/SDWebImageHEIFCoder + */ +API_AVAILABLE(ios(13.0), tvos(13.0), macos(10.15), watchos(6.0)) +@interface SDImageHEICCoder : SDImageIOAnimatedCoder + +@property (nonatomic, class, readonly, nonnull) SDImageHEICCoder *sharedCoder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.m new file mode 100644 index 00000000..dd83aea1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageHEICCoder.m @@ -0,0 +1,101 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDImageHEICCoder.h" +#import "SDImageIOAnimatedCoderInternal.h" + +// These constants are available from iOS 13+ and Xcode 11. This raw value is used for toolchain and firmware compatibility +static NSString * kSDCGImagePropertyHEICSDictionary = @"{HEICS}"; +static NSString * kSDCGImagePropertyHEICSLoopCount = @"LoopCount"; +static NSString * kSDCGImagePropertyHEICSDelayTime = @"DelayTime"; +static NSString * kSDCGImagePropertyHEICSUnclampedDelayTime = @"UnclampedDelayTime"; + +@implementation SDImageHEICCoder + ++ (void)initialize { + if (@available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)) { + // Use SDK instead of raw value + kSDCGImagePropertyHEICSDictionary = (__bridge NSString *)kCGImagePropertyHEICSDictionary; + kSDCGImagePropertyHEICSLoopCount = (__bridge NSString *)kCGImagePropertyHEICSLoopCount; + kSDCGImagePropertyHEICSDelayTime = (__bridge NSString *)kCGImagePropertyHEICSDelayTime; + kSDCGImagePropertyHEICSUnclampedDelayTime = (__bridge NSString *)kCGImagePropertyHEICSUnclampedDelayTime; + } +} + ++ (instancetype)sharedCoder { + static SDImageHEICCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageHEICCoder alloc] init]; + }); + return coder; +} + +#pragma mark - SDImageCoder + +- (BOOL)canDecodeFromData:(nullable NSData *)data { + switch ([NSData sd_imageFormatForImageData:data]) { + case SDImageFormatHEIC: + // Check HEIC decoding compatibility + return [self.class canDecodeFromFormat:SDImageFormatHEIC]; + case SDImageFormatHEIF: + // Check HEIF decoding compatibility + return [self.class canDecodeFromFormat:SDImageFormatHEIF]; + default: + return NO; + } +} + +- (BOOL)canIncrementalDecodeFromData:(NSData *)data { + return [self canDecodeFromData:data]; +} + +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + switch (format) { + case SDImageFormatHEIC: + // Check HEIC encoding compatibility + return [self.class canEncodeToFormat:SDImageFormatHEIC]; + case SDImageFormatHEIF: + // Check HEIF encoding compatibility + return [self.class canEncodeToFormat:SDImageFormatHEIF]; + default: + return NO; + } +} + +#pragma mark - Subclass Override + ++ (SDImageFormat)imageFormat { + return SDImageFormatHEIC; +} + ++ (NSString *)imageUTType { + return (__bridge NSString *)kSDUTTypeHEIC; +} + ++ (NSString *)dictionaryProperty { + return kSDCGImagePropertyHEICSDictionary; +} + ++ (NSString *)unclampedDelayTimeProperty { + return kSDCGImagePropertyHEICSUnclampedDelayTime; +} + ++ (NSString *)delayTimeProperty { + return kSDCGImagePropertyHEICSDelayTime; +} + ++ (NSString *)loopCountProperty { + return kSDCGImagePropertyHEICSLoopCount; +} + ++ (NSUInteger)defaultLoopCount { + return 0; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.h new file mode 100644 index 00000000..a314c57a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.h @@ -0,0 +1,59 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import +#import "SDImageCoder.h" + +/** + This is the abstract class for all animated coder, which use the Image/IO API. You can not use this directly as real coders. A exception will be raised if you use this class. + All of the properties need the subclass to implement and works as expected. + For Image/IO, See Apple's documentation: https://developer.apple.com/documentation/imageio + */ +@interface SDImageIOAnimatedCoder : NSObject + +#pragma mark - Subclass Override +/** + The supported animated image format. Such as `SDImageFormatGIF`. + @note Subclass override. + */ +@property (class, readonly) SDImageFormat imageFormat; +/** + The supported image format UTI Type. Such as `kSDUTTypeGIF`. + This can be used for cases when we can not detect `SDImageFormat. Such as progressive decoding's hint format `kCGImageSourceTypeIdentifierHint`. + @note Subclass override. + */ +@property (class, readonly, nonnull) NSString *imageUTType; +/** + The image container property key used in Image/IO API. Such as `kCGImagePropertyGIFDictionary`. + @note Subclass override. + */ +@property (class, readonly, nonnull) NSString *dictionaryProperty; +/** + The image unclamped delay time property key used in Image/IO API. Such as `kCGImagePropertyGIFUnclampedDelayTime` + @note Subclass override. + */ +@property (class, readonly, nonnull) NSString *unclampedDelayTimeProperty; +/** + The image delay time property key used in Image/IO API. Such as `kCGImagePropertyGIFDelayTime`. + @note Subclass override. + */ +@property (class, readonly, nonnull) NSString *delayTimeProperty; +/** + The image loop count property key used in Image/IO API. Such as `kCGImagePropertyGIFLoopCount`. + @note Subclass override. + */ +@property (class, readonly, nonnull) NSString *loopCountProperty; +/** + The default loop count when there are no any loop count information inside image container metadata. + For example, for GIF format, the standard use 1 (play once). For APNG format, the standard use 0 (infinity loop). + @note Subclass override. + */ +@property (class, readonly) NSUInteger defaultLoopCount; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.m new file mode 100644 index 00000000..a7e08c19 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOAnimatedCoder.m @@ -0,0 +1,663 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDImageIOAnimatedCoder.h" +#import "NSImage+Compatibility.h" +#import "UIImage+Metadata.h" +#import "NSData+ImageContentType.h" +#import "SDImageCoderHelper.h" +#import "SDAnimatedImageRep.h" +#import "UIImage+ForceDecode.h" + +// Specify DPI for vector format in CGImageSource, like PDF +static NSString * kSDCGImageSourceRasterizationDPI = @"kCGImageSourceRasterizationDPI"; +// Specify File Size for lossy format encoding, like JPEG +static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize"; + +@interface SDImageIOCoderFrame : NSObject + +@property (nonatomic, assign) NSUInteger index; // Frame index (zero based) +@property (nonatomic, assign) NSTimeInterval duration; // Frame duration in seconds + +@end + +@implementation SDImageIOCoderFrame +@end + +@implementation SDImageIOAnimatedCoder { + size_t _width, _height; + CGImageSourceRef _imageSource; + NSData *_imageData; + CGFloat _scale; + NSUInteger _loopCount; + NSUInteger _frameCount; + NSArray *_frames; + BOOL _finished; + BOOL _preserveAspectRatio; + CGSize _thumbnailSize; +} + +- (void)dealloc +{ + if (_imageSource) { + CFRelease(_imageSource); + _imageSource = NULL; + } +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification +{ + if (_imageSource) { + for (size_t i = 0; i < _frameCount; i++) { + CGImageSourceRemoveCacheAtIndex(_imageSource, i); + } + } +} + +#pragma mark - Subclass Override + ++ (SDImageFormat)imageFormat { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSString *)imageUTType { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSString *)dictionaryProperty { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSString *)unclampedDelayTimeProperty { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSString *)delayTimeProperty { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSString *)loopCountProperty { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (NSUInteger)defaultLoopCount { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"For `SDImageIOAnimatedCoder` subclass, you must override %@ method", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + +#pragma mark - Utils + ++ (BOOL)canDecodeFromFormat:(SDImageFormat)format { + static dispatch_once_t onceToken; + static NSSet *imageUTTypeSet; + dispatch_once(&onceToken, ^{ + NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers(); + imageUTTypeSet = [NSSet setWithArray:imageUTTypes]; + }); + CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format]; + if ([imageUTTypeSet containsObject:(__bridge NSString *)(imageUTType)]) { + // Can decode from target format + return YES; + } + return NO; +} + ++ (BOOL)canEncodeToFormat:(SDImageFormat)format { + static dispatch_once_t onceToken; + static NSSet *imageUTTypeSet; + dispatch_once(&onceToken, ^{ + NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageDestinationCopyTypeIdentifiers(); + imageUTTypeSet = [NSSet setWithArray:imageUTTypes]; + }); + CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format]; + if ([imageUTTypeSet containsObject:(__bridge NSString *)(imageUTType)]) { + // Can encode to target format + return YES; + } + return NO; +} + ++ (NSUInteger)imageLoopCountWithSource:(CGImageSourceRef)source { + NSUInteger loopCount = self.defaultLoopCount; + NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, NULL); + NSDictionary *containerProperties = imageProperties[self.dictionaryProperty]; + if (containerProperties) { + NSNumber *containerLoopCount = containerProperties[self.loopCountProperty]; + if (containerLoopCount != nil) { + loopCount = containerLoopCount.unsignedIntegerValue; + } + } + return loopCount; +} + ++ (NSTimeInterval)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { + NSDictionary *options = @{ + (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES), + (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage + }; + NSTimeInterval frameDuration = 0.1; + CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)options); + if (!cfFrameProperties) { + return frameDuration; + } + NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; + NSDictionary *containerProperties = frameProperties[self.dictionaryProperty]; + + NSNumber *delayTimeUnclampedProp = containerProperties[self.unclampedDelayTimeProperty]; + if (delayTimeUnclampedProp != nil) { + frameDuration = [delayTimeUnclampedProp doubleValue]; + } else { + NSNumber *delayTimeProp = containerProperties[self.delayTimeProperty]; + if (delayTimeProp != nil) { + frameDuration = [delayTimeProp doubleValue]; + } + } + + // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. + // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify + // a duration of <= 10 ms. See and + // for more information. + + if (frameDuration < 0.011) { + frameDuration = 0.1; + } + + CFRelease(cfFrameProperties); + return frameDuration; +} + ++ (UIImage *)createFrameAtIndex:(NSUInteger)index source:(CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(NSDictionary *)options { + // Some options need to pass to `CGImageSourceCopyPropertiesAtIndex` before `CGImageSourceCreateImageAtIndex`, or ImageIO will ignore them because they parse once :) + // Parse the image properties + NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)options); + CGFloat pixelWidth = [properties[(__bridge NSString *)kCGImagePropertyPixelWidth] doubleValue]; + CGFloat pixelHeight = [properties[(__bridge NSString *)kCGImagePropertyPixelHeight] doubleValue]; + CGImagePropertyOrientation exifOrientation = (CGImagePropertyOrientation)[properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue]; + if (!exifOrientation) { + exifOrientation = kCGImagePropertyOrientationUp; + } + + CFStringRef uttype = CGImageSourceGetType(source); + // Check vector format + BOOL isVector = NO; + if ([NSData sd_imageFormatFromUTType:uttype] == SDImageFormatPDF) { + isVector = YES; + } + + NSMutableDictionary *decodingOptions; + if (options) { + decodingOptions = [NSMutableDictionary dictionaryWithDictionary:options]; + } else { + decodingOptions = [NSMutableDictionary dictionary]; + } + CGImageRef imageRef; + BOOL createFullImage = thumbnailSize.width == 0 || thumbnailSize.height == 0 || pixelWidth == 0 || pixelHeight == 0 || (pixelWidth <= thumbnailSize.width && pixelHeight <= thumbnailSize.height); + if (createFullImage) { + if (isVector) { + if (thumbnailSize.width == 0 || thumbnailSize.height == 0) { + // Provide the default pixel count for vector images, simply just use the screen size +#if SD_WATCH + thumbnailSize = WKInterfaceDevice.currentDevice.screenBounds.size; +#elif SD_UIKIT + thumbnailSize = UIScreen.mainScreen.bounds.size; +#elif SD_MAC + thumbnailSize = NSScreen.mainScreen.frame.size; +#endif + } + CGFloat maxPixelSize = MAX(thumbnailSize.width, thumbnailSize.height); + NSUInteger DPIPerPixel = 2; + NSUInteger rasterizationDPI = maxPixelSize * DPIPerPixel; + decodingOptions[kSDCGImageSourceRasterizationDPI] = @(rasterizationDPI); + } + imageRef = CGImageSourceCreateImageAtIndex(source, index, (__bridge CFDictionaryRef)[decodingOptions copy]); + } else { + decodingOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailWithTransform] = @(preserveAspectRatio); + CGFloat maxPixelSize; + if (preserveAspectRatio) { + CGFloat pixelRatio = pixelWidth / pixelHeight; + CGFloat thumbnailRatio = thumbnailSize.width / thumbnailSize.height; + if (pixelRatio > thumbnailRatio) { + maxPixelSize = thumbnailSize.width; + } else { + maxPixelSize = thumbnailSize.height; + } + } else { + maxPixelSize = MAX(thumbnailSize.width, thumbnailSize.height); + } + decodingOptions[(__bridge NSString *)kCGImageSourceThumbnailMaxPixelSize] = @(maxPixelSize); + decodingOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailFromImageAlways] = @(YES); + imageRef = CGImageSourceCreateThumbnailAtIndex(source, index, (__bridge CFDictionaryRef)[decodingOptions copy]); + } + if (!imageRef) { + return nil; + } + // Thumbnail image post-process + if (!createFullImage) { + if (preserveAspectRatio) { + // kCGImageSourceCreateThumbnailWithTransform will apply EXIF transform as well, we should not apply twice + exifOrientation = kCGImagePropertyOrientationUp; + } else { + // `CGImageSourceCreateThumbnailAtIndex` take only pixel dimension, if not `preserveAspectRatio`, we should manual scale to the target size + CGImageRef scaledImageRef = [SDImageCoderHelper CGImageCreateScaled:imageRef size:thumbnailSize]; + CGImageRelease(imageRef); + imageRef = scaledImageRef; + } + } + +#if SD_UIKIT || SD_WATCH + UIImageOrientation imageOrientation = [SDImageCoderHelper imageOrientationFromEXIFOrientation:exifOrientation]; + UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:exifOrientation]; +#endif + CGImageRelease(imageRef); + return image; +} + +#pragma mark - Decode +- (BOOL)canDecodeFromData:(nullable NSData *)data { + return ([NSData sd_imageFormatForImageData:data] == self.class.imageFormat); +} + +- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options { + if (!data) { + return nil; + } + CGFloat scale = 1; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { +#if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; +#else + thumbnailSize = thumbnailSizeValue.CGSizeValue; +#endif + } + + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + +#if SD_MAC + // If don't use thumbnail, prefers the built-in generation of frames (GIF/APNG) + // Which decode frames in time and reduce memory usage + if (thumbnailSize.width == 0 || thumbnailSize.height == 0) { + SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data]; + NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale); + imageRep.size = size; + NSImage *animatedImage = [[NSImage alloc] initWithSize:size]; + [animatedImage addRepresentation:imageRep]; + return animatedImage; + } +#endif + + CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); + if (!source) { + return nil; + } + size_t count = CGImageSourceGetCount(source); + UIImage *animatedImage; + + BOOL decodeFirstFrame = [options[SDImageCoderDecodeFirstFrameOnly] boolValue]; + if (decodeFirstFrame || count <= 1) { + animatedImage = [self.class createFrameAtIndex:0 source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil]; + } else { + NSMutableArray *frames = [NSMutableArray array]; + + for (size_t i = 0; i < count; i++) { + UIImage *image = [self.class createFrameAtIndex:i source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil]; + if (!image) { + continue; + } + + NSTimeInterval duration = [self.class frameDurationAtIndex:i source:source]; + + SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration]; + [frames addObject:frame]; + } + + NSUInteger loopCount = [self.class imageLoopCountWithSource:source]; + + animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames]; + animatedImage.sd_imageLoopCount = loopCount; + } + animatedImage.sd_imageFormat = self.class.imageFormat; + CFRelease(source); + + return animatedImage; +} + +#pragma mark - Progressive Decode + +- (BOOL)canIncrementalDecodeFromData:(NSData *)data { + return ([NSData sd_imageFormatForImageData:data] == self.class.imageFormat); +} + +- (instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options { + self = [super init]; + if (self) { + NSString *imageUTType = self.class.imageUTType; + _imageSource = CGImageSourceCreateIncremental((__bridge CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceTypeIdentifierHint : imageUTType}); + CGFloat scale = 1; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + _scale = scale; + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { + #if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; + #else + thumbnailSize = thumbnailSizeValue.CGSizeValue; + #endif + } + _thumbnailSize = thumbnailSize; + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + _preserveAspectRatio = preserveAspectRatio; +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished { + if (_finished) { + return; + } + _imageData = data; + _finished = finished; + + // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ + // Thanks to the author @Nyx0uf + + // Update the data source, we must pass ALL the data, not just the new bytes + CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)data, finished); + + if (_width + _height == 0) { + NSDictionary *options = @{ + (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES), + (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage + }; + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, (__bridge CFDictionaryRef)options); + if (properties) { + CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); + if (val) CFNumberGetValue(val, kCFNumberLongType, &_height); + val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); + if (val) CFNumberGetValue(val, kCFNumberLongType, &_width); + CFRelease(properties); + } + } + + // For animated image progressive decoding because the frame count and duration may be changed. + [self scanAndCheckFramesValidWithImageSource:_imageSource]; +} + +- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options { + UIImage *image; + + if (_width + _height > 0) { + // Create the image + CGFloat scale = _scale; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + image = [self.class createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:nil]; + if (image) { + image.sd_imageFormat = self.class.imageFormat; + } + } + + return image; +} + +#pragma mark - Encode +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + return (format == self.class.imageFormat); +} + +- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options { + if (!image) { + return nil; + } + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + // Earily return, supports CGImage only + return nil; + } + + if (format != self.class.imageFormat) { + return nil; + } + + NSMutableData *imageData = [NSMutableData data]; + CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format]; + NSArray *frames = [SDImageCoderHelper framesFromAnimatedImage:image]; + + // Create an image destination. Animated Image does not support EXIF image orientation TODO + // The `CGImageDestinationCreateWithData` will log a warning when count is 0, use 1 instead. + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frames.count ?: 1, NULL); + if (!imageDestination) { + // Handle failure. + return nil; + } + NSMutableDictionary *properties = [NSMutableDictionary dictionary]; + // Encoding Options + double compressionQuality = 1; + if (options[SDImageCoderEncodeCompressionQuality]) { + compressionQuality = [options[SDImageCoderEncodeCompressionQuality] doubleValue]; + } + properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = @(compressionQuality); + CGColorRef backgroundColor = [options[SDImageCoderEncodeBackgroundColor] CGColor]; + if (backgroundColor) { + properties[(__bridge NSString *)kCGImageDestinationBackgroundColor] = (__bridge id)(backgroundColor); + } + CGSize maxPixelSize = CGSizeZero; + NSValue *maxPixelSizeValue = options[SDImageCoderEncodeMaxPixelSize]; + if (maxPixelSizeValue != nil) { +#if SD_MAC + maxPixelSize = maxPixelSizeValue.sizeValue; +#else + maxPixelSize = maxPixelSizeValue.CGSizeValue; +#endif + } + CGFloat pixelWidth = (CGFloat)CGImageGetWidth(imageRef); + CGFloat pixelHeight = (CGFloat)CGImageGetHeight(imageRef); + CGFloat finalPixelSize = 0; + if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && pixelWidth > maxPixelSize.width && pixelHeight > maxPixelSize.height) { + CGFloat pixelRatio = pixelWidth / pixelHeight; + CGFloat maxPixelSizeRatio = maxPixelSize.width / maxPixelSize.height; + if (pixelRatio > maxPixelSizeRatio) { + finalPixelSize = maxPixelSize.width; + } else { + finalPixelSize = maxPixelSize.height; + } + properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize); + } + NSUInteger maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue]; + if (maxFileSize > 0) { + properties[kSDCGImageDestinationRequestedFileSize] = @(maxFileSize); + // Remove the quality if we have file size limit + properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = nil; + } + BOOL embedThumbnail = NO; + if (options[SDImageCoderEncodeEmbedThumbnail]) { + embedThumbnail = [options[SDImageCoderEncodeEmbedThumbnail] boolValue]; + } + properties[(__bridge NSString *)kCGImageDestinationEmbedThumbnail] = @(embedThumbnail); + + BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue]; + if (encodeFirstFrame || frames.count == 0) { + // for static single images + CGImageDestinationAddImage(imageDestination, imageRef, (__bridge CFDictionaryRef)properties); + } else { + // for animated images + NSUInteger loopCount = image.sd_imageLoopCount; + NSDictionary *containerProperties = @{ + self.class.dictionaryProperty: @{self.class.loopCountProperty : @(loopCount)} + }; + // container level properties (applies for `CGImageDestinationSetProperties`, not individual frames) + CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)containerProperties); + + for (size_t i = 0; i < frames.count; i++) { + SDImageFrame *frame = frames[i]; + NSTimeInterval frameDuration = frame.duration; + CGImageRef frameImageRef = frame.image.CGImage; + properties[self.class.dictionaryProperty] = @{self.class.delayTimeProperty : @(frameDuration)}; + CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)properties); + } + } + // Finalize the destination. + if (CGImageDestinationFinalize(imageDestination) == NO) { + // Handle failure. + imageData = nil; + } + + CFRelease(imageDestination); + + return [imageData copy]; +} + +#pragma mark - SDAnimatedImageCoder +- (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options { + if (!data) { + return nil; + } + self = [super init]; + if (self) { + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); + if (!imageSource) { + return nil; + } + BOOL framesValid = [self scanAndCheckFramesValidWithImageSource:imageSource]; + if (!framesValid) { + CFRelease(imageSource); + return nil; + } + CGFloat scale = 1; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + _scale = scale; + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { + #if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; + #else + thumbnailSize = thumbnailSizeValue.CGSizeValue; + #endif + } + _thumbnailSize = thumbnailSize; + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + _preserveAspectRatio = preserveAspectRatio; + _imageSource = imageSource; + _imageData = data; +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (BOOL)scanAndCheckFramesValidWithImageSource:(CGImageSourceRef)imageSource { + if (!imageSource) { + return NO; + } + NSUInteger frameCount = CGImageSourceGetCount(imageSource); + NSUInteger loopCount = [self.class imageLoopCountWithSource:imageSource]; + NSMutableArray *frames = [NSMutableArray array]; + + for (size_t i = 0; i < frameCount; i++) { + SDImageIOCoderFrame *frame = [[SDImageIOCoderFrame alloc] init]; + frame.index = i; + frame.duration = [self.class frameDurationAtIndex:i source:imageSource]; + [frames addObject:frame]; + } + + _frameCount = frameCount; + _loopCount = loopCount; + _frames = [frames copy]; + + return YES; +} + +- (NSData *)animatedImageData { + return _imageData; +} + +- (NSUInteger)animatedImageLoopCount { + return _loopCount; +} + +- (NSUInteger)animatedImageFrameCount { + return _frameCount; +} + +- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index { + if (index >= _frameCount) { + return 0; + } + return _frames[index].duration; +} + +- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index { + if (index >= _frameCount) { + return nil; + } + // Animated Image should not use the CGContext solution to force decode. Prefers to use Image/IO built in method, which is safer and memory friendly, see https://github.com/SDWebImage/SDWebImage/issues/2961 + NSDictionary *options = @{ + (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @(YES), + (__bridge NSString *)kCGImageSourceShouldCache : @(YES) // Always cache to reduce CPU usage + }; + UIImage *image = [self.class createFrameAtIndex:index source:_imageSource scale:_scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:options]; + if (!image) { + return nil; + } + image.sd_imageFormat = self.class.imageFormat; + image.sd_isDecoded = YES; + return image; +} + +@end + diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.h new file mode 100644 index 00000000..98682ed6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.h @@ -0,0 +1,30 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDImageCoder.h" + +/** + Built in coder that supports PNG, JPEG, TIFF, includes support for progressive decoding. + + GIF + Also supports static GIF (meaning will only handle the 1st frame). + For a full GIF support, we recommend `SDAnimatedImageView` to keep both CPU and memory balanced. + + HEIC + This coder also supports HEIC format because ImageIO supports it natively. But it depends on the system capabilities, so it won't work on all devices, see: https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf + Decode(Software): !Simulator && (iOS 11 || tvOS 11 || macOS 10.13) + Decode(Hardware): !Simulator && ((iOS 11 && A9Chip) || (macOS 10.13 && 6thGenerationIntelCPU)) + Encode(Software): macOS 10.13 + Encode(Hardware): !Simulator && ((iOS 11 && A10FusionChip) || (macOS 10.13 && 6thGenerationIntelCPU)) + */ +@interface SDImageIOCoder : NSObject + +@property (nonatomic, class, readonly, nonnull) SDImageIOCoder *sharedCoder; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.m new file mode 100644 index 00000000..8e1199f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageIOCoder.m @@ -0,0 +1,292 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageIOCoder.h" +#import "SDImageCoderHelper.h" +#import "NSImage+Compatibility.h" +#import +#import "UIImage+Metadata.h" +#import "SDImageIOAnimatedCoderInternal.h" + +// Specify File Size for lossy format encoding, like JPEG +static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize"; + +@implementation SDImageIOCoder { + size_t _width, _height; + CGImagePropertyOrientation _orientation; + CGImageSourceRef _imageSource; + CGFloat _scale; + BOOL _finished; + BOOL _preserveAspectRatio; + CGSize _thumbnailSize; +} + +- (void)dealloc { + if (_imageSource) { + CFRelease(_imageSource); + _imageSource = NULL; + } +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification +{ + if (_imageSource) { + CGImageSourceRemoveCacheAtIndex(_imageSource, 0); + } +} + ++ (instancetype)sharedCoder { + static SDImageIOCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageIOCoder alloc] init]; + }); + return coder; +} + +#pragma mark - Decode +- (BOOL)canDecodeFromData:(nullable NSData *)data { + return YES; +} + +- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options { + if (!data) { + return nil; + } + CGFloat scale = 1; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1) ; + } + + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { +#if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; +#else + thumbnailSize = thumbnailSizeValue.CGSizeValue; +#endif + } + + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + + CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); + if (!source) { + return nil; + } + + UIImage *image = [SDImageIOAnimatedCoder createFrameAtIndex:0 source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:nil]; + CFRelease(source); + if (!image) { + return nil; + } + + image.sd_imageFormat = [NSData sd_imageFormatForImageData:data]; + return image; +} + +#pragma mark - Progressive Decode + +- (BOOL)canIncrementalDecodeFromData:(NSData *)data { + return [self canDecodeFromData:data]; +} + +- (instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options { + self = [super init]; + if (self) { + _imageSource = CGImageSourceCreateIncremental(NULL); + CGFloat scale = 1; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + _scale = scale; + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { + #if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; + #else + thumbnailSize = thumbnailSizeValue.CGSizeValue; + #endif + } + _thumbnailSize = thumbnailSize; + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + _preserveAspectRatio = preserveAspectRatio; +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished { + if (_finished) { + return; + } + _finished = finished; + + // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ + // Thanks to the author @Nyx0uf + + // Update the data source, we must pass ALL the data, not just the new bytes + CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)data, finished); + + if (_width + _height == 0) { + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, NULL); + if (properties) { + NSInteger orientationValue = 1; + CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); + if (val) CFNumberGetValue(val, kCFNumberLongType, &_height); + val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); + if (val) CFNumberGetValue(val, kCFNumberLongType, &_width); + val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); + if (val) CFNumberGetValue(val, kCFNumberNSIntegerType, &orientationValue); + CFRelease(properties); + + // When we draw to Core Graphics, we lose orientation information, + // which means the image below born of initWithCGIImage will be + // oriented incorrectly sometimes. (Unlike the image born of initWithData + // in didCompleteWithError.) So save it here and pass it on later. + _orientation = (CGImagePropertyOrientation)orientationValue; + } + } +} + +- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options { + UIImage *image; + + if (_width + _height > 0) { + // Create the image + CGFloat scale = _scale; + NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor]; + if (scaleFactor != nil) { + scale = MAX([scaleFactor doubleValue], 1); + } + image = [SDImageIOAnimatedCoder createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize options:nil]; + if (image) { + CFStringRef uttype = CGImageSourceGetType(_imageSource); + image.sd_imageFormat = [NSData sd_imageFormatFromUTType:uttype]; + } + } + + return image; +} + +#pragma mark - Encode +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + return YES; +} + +- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options { + if (!image) { + return nil; + } + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + // Earily return, supports CGImage only + return nil; + } + + if (format == SDImageFormatUndefined) { + BOOL hasAlpha = [SDImageCoderHelper CGImageContainsAlpha:imageRef]; + if (hasAlpha) { + format = SDImageFormatPNG; + } else { + format = SDImageFormatJPEG; + } + } + + NSMutableData *imageData = [NSMutableData data]; + CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:format]; + + // Create an image destination. + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL); + if (!imageDestination) { + // Handle failure. + return nil; + } + + NSMutableDictionary *properties = [NSMutableDictionary dictionary]; +#if SD_UIKIT || SD_WATCH + CGImagePropertyOrientation exifOrientation = [SDImageCoderHelper exifOrientationFromImageOrientation:image.imageOrientation]; +#else + CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp; +#endif + properties[(__bridge NSString *)kCGImagePropertyOrientation] = @(exifOrientation); + // Encoding Options + double compressionQuality = 1; + if (options[SDImageCoderEncodeCompressionQuality]) { + compressionQuality = [options[SDImageCoderEncodeCompressionQuality] doubleValue]; + } + properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = @(compressionQuality); + CGColorRef backgroundColor = [options[SDImageCoderEncodeBackgroundColor] CGColor]; + if (backgroundColor) { + properties[(__bridge NSString *)kCGImageDestinationBackgroundColor] = (__bridge id)(backgroundColor); + } + CGSize maxPixelSize = CGSizeZero; + NSValue *maxPixelSizeValue = options[SDImageCoderEncodeMaxPixelSize]; + if (maxPixelSizeValue != nil) { +#if SD_MAC + maxPixelSize = maxPixelSizeValue.sizeValue; +#else + maxPixelSize = maxPixelSizeValue.CGSizeValue; +#endif + } + CGFloat pixelWidth = (CGFloat)CGImageGetWidth(imageRef); + CGFloat pixelHeight = (CGFloat)CGImageGetHeight(imageRef); + if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && pixelWidth > maxPixelSize.width && pixelHeight > maxPixelSize.height) { + CGFloat pixelRatio = pixelWidth / pixelHeight; + CGFloat maxPixelSizeRatio = maxPixelSize.width / maxPixelSize.height; + CGFloat finalPixelSize; + if (pixelRatio > maxPixelSizeRatio) { + finalPixelSize = maxPixelSize.width; + } else { + finalPixelSize = maxPixelSize.height; + } + properties[(__bridge NSString *)kCGImageDestinationImageMaxPixelSize] = @(finalPixelSize); + } + NSUInteger maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue]; + if (maxFileSize > 0) { + properties[kSDCGImageDestinationRequestedFileSize] = @(maxFileSize); + // Remove the quality if we have file size limit + properties[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] = nil; + } + BOOL embedThumbnail = NO; + if (options[SDImageCoderEncodeEmbedThumbnail]) { + embedThumbnail = [options[SDImageCoderEncodeEmbedThumbnail] boolValue]; + } + properties[(__bridge NSString *)kCGImageDestinationEmbedThumbnail] = @(embedThumbnail); + + // Add your image to the destination. + CGImageDestinationAddImage(imageDestination, imageRef, (__bridge CFDictionaryRef)properties); + + // Finalize the destination. + if (CGImageDestinationFinalize(imageDestination) == NO) { + // Handle failure. + imageData = nil; + } + + CFRelease(imageDestination); + + return [imageData copy]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.h new file mode 100644 index 00000000..addad836 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.h @@ -0,0 +1,146 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" +#import "SDWebImageOperation.h" +#import "SDImageCoder.h" + +typedef void(^SDImageLoaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL); +typedef void(^SDImageLoaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished); + +#pragma mark - Context Options + +/** + A `UIImage` instance from `SDWebImageManager` when you specify `SDWebImageRefreshCached` and image cache hit. + This can be a hint for image loader to load the image from network and refresh the image from remote location if needed. If the image from remote location does not change, you should call the completion with `SDWebImageErrorCacheNotModified` error. (UIImage) + @note If you don't implement `SDWebImageRefreshCached` support, you do not need to care about this context option. + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextLoaderCachedImage; + +#pragma mark - Helper method + +/** + This is the built-in decoding process for image download from network or local file. + @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. + + @param imageData The image data from the network. Should not be nil + @param imageURL The image URL from the input. Should not be nil + @param options The options arg from the input + @param context The context arg from the input + @return The decoded image for current image data load from the network + */ +FOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context); + +/** + This is the built-in decoding process for image progressive download from network. It's used when `SDWebImageProgressiveLoad` option is set. (It's not required when your loader does not support progressive image loading) + @note If you want to implement your custom loader with `requestImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image. + + @param imageData The image data from the network so far. Should not be nil + @param imageURL The image URL from the input. Should not be nil + @param finished Pass NO to specify the download process has not finished. Pass YES when all image data has finished. + @param operation The loader operation associated with current progressive download. Why to provide this is because progressive decoding need to store the partial decoded context for each operation to avoid conflict. You should provide the operation from `loadImageWithURL:` method return value. + @param options The options arg from the input + @param context The context arg from the input + @return The decoded progressive image for current image data load from the network + */ +FOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished, id _Nonnull operation, SDWebImageOptions options, SDWebImageContext * _Nullable context); + +/** + This function get the progressive decoder for current loading operation. If no progressive decoding is happended or decoder is not able to construct, return nil. + @return The progressive decoder associated with the loading operation. + */ +FOUNDATION_EXPORT id _Nullable SDImageLoaderGetProgressiveCoder(id _Nonnull operation); + +/** + This function set the progressive decoder for current loading operation. If no progressive decoding is happended, pass nil. + @param operation The loading operation to associate the progerssive decoder. + */ +FOUNDATION_EXPORT void SDImageLoaderSetProgressiveCoder(id _Nonnull operation, id _Nullable progressiveCoder); + +#pragma mark - SDImageLoader + +/** + This is the protocol to specify custom image load process. You can create your own class to conform this protocol and use as a image loader to load image from network or any available remote resources defined by yourself. + If you want to implement custom loader for image download from network or local file, you just need to concentrate on image data download only. After the download finish, call `SDImageLoaderDecodeImageData` or `SDImageLoaderDecodeProgressiveImageData` to use the built-in decoding process and produce image (Remember to call in the global queue). And finally callback the completion block. + If you directly get the image instance using some third-party SDKs, such as image directly from Photos framework. You can process the image data and image instance by yourself without that built-in decoding process. And finally callback the completion block. + @note It's your responsibility to load the image in the desired global queue(to avoid block main queue). We do not dispatch these method call in a global queue but just from the call queue (For `SDWebImageManager`, it typically call from the main queue). +*/ +@protocol SDImageLoader + +@required +/** + Whether current image loader supports to load the provide image URL. + This will be checked every time a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `requestImageWithURL:options:context:progress:completed:`. + + @param url The image URL to be loaded. + @return YES to continue download, NO to stop download. + */ +- (BOOL)canRequestImageForURL:(nullable NSURL *)url API_DEPRECATED("Use canRequestImageForURL:options:context: instead", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED)); + +@optional +/** + Whether current image loader supports to load the provide image URL, with associated options and context. + This will be checked every time a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `requestImageWithURL:options:context:progress:completed:`. + + @param url The image URL to be loaded. + @param options A mask to specify options to use for this request + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @return YES to continue download, NO to stop download. + */ +- (BOOL)canRequestImageForURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +@required +/** + Load the image and image data with the given URL and return the image data. You're responsible for producing the image instance. + + @param url The URL represent the image. Note this may not be a HTTP URL + @param options A mask to specify options to use for this request + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + @param completedBlock A block called when operation has been completed. + @return An operation which allow the user to cancel the current request. + */ +- (nullable id)requestImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDImageLoaderCompletedBlock)completedBlock; + + +/** + Whether the error from image loader should be marked indeed un-recoverable or not. + If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not. + + @param url The URL represent the image. Note this may not be a HTTP URL + @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error. + @return Whether to block this url or not. Return YES to mark this URL as failed. + */ +- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url + error:(nonnull NSError *)error API_DEPRECATED("Use shouldBlockFailedURLWithURL:error:options:context: instead", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED)); + +@optional +/** + Whether the error from image loader should be marked indeed un-recoverable or not, with associated options and context. + If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not. + + @param url The URL represent the image. Note this may not be a HTTP URL + @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error. + @param options A mask to specify options to use for this request + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @return Whether to block this url or not. Return YES to mark this URL as failed. + */ +- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url + error:(nonnull NSError *)error + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.m new file mode 100644 index 00000000..d6b95948 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoader.m @@ -0,0 +1,210 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageLoader.h" +#import "SDWebImageCacheKeyFilter.h" +#import "SDImageCodersManager.h" +#import "SDImageCoderHelper.h" +#import "SDAnimatedImage.h" +#import "UIImage+Metadata.h" +#import "SDInternalMacros.h" +#import "objc/runtime.h" + +SDWebImageContextOption const SDWebImageContextLoaderCachedImage = @"loaderCachedImage"; + +static void * SDImageLoaderProgressiveCoderKey = &SDImageLoaderProgressiveCoderKey; + +id SDImageLoaderGetProgressiveCoder(id operation) { + NSCParameterAssert(operation); + return objc_getAssociatedObject(operation, SDImageLoaderProgressiveCoderKey); +} + +void SDImageLoaderSetProgressiveCoder(id operation, id progressiveCoder) { + NSCParameterAssert(operation); + objc_setAssociatedObject(operation, SDImageLoaderProgressiveCoderKey, progressiveCoder, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context) { + NSCParameterAssert(imageData); + NSCParameterAssert(imageURL); + + UIImage *image; + id cacheKeyFilter = context[SDWebImageContextCacheKeyFilter]; + NSString *cacheKey; + if (cacheKeyFilter) { + cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL]; + } else { + cacheKey = imageURL.absoluteString; + } + BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly); + NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor]; + CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey); + NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio]; + NSValue *thumbnailSizeValue; + BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages); + if (shouldScaleDown) { + CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4; + CGFloat dimension = ceil(sqrt(thumbnailPixels)); + thumbnailSizeValue = @(CGSizeMake(dimension, dimension)); + } + if (context[SDWebImageContextImageThumbnailPixelSize]) { + thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize]; + } + + SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2]; + mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame); + mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale); + mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue; + mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue; + mutableCoderOptions[SDImageCoderWebImageContext] = context; + SDImageCoderOptions *coderOptions = [mutableCoderOptions copy]; + + // Grab the image coder + id imageCoder; + if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) { + imageCoder = context[SDWebImageContextImageCoder]; + } else { + imageCoder = [SDImageCodersManager sharedManager]; + } + + if (!decodeFirstFrame) { + // check whether we should use `SDAnimatedImage` + Class animatedImageClass = context[SDWebImageContextAnimatedImageClass]; + if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) { + image = [[animatedImageClass alloc] initWithData:imageData scale:scale options:coderOptions]; + if (image) { + // Preload frames if supported + if (options & SDWebImagePreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) { + [((id)image) preloadAllFrames]; + } + } else { + // Check image class matching + if (options & SDWebImageMatchAnimatedImageClass) { + return nil; + } + } + } + } + if (!image) { + image = [imageCoder decodedImageWithData:imageData options:coderOptions]; + } + if (image) { + BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage); + if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) { + // `SDAnimatedImage` do not decode + shouldDecode = NO; + } else if (image.sd_isAnimated) { + // animated image do not decode + shouldDecode = NO; + } + + if (shouldDecode) { + image = [SDImageCoderHelper decodedImageWithImage:image]; + } + } + + return image; +} + +UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished, id _Nonnull operation, SDWebImageOptions options, SDWebImageContext * _Nullable context) { + NSCParameterAssert(imageData); + NSCParameterAssert(imageURL); + NSCParameterAssert(operation); + + UIImage *image; + id cacheKeyFilter = context[SDWebImageContextCacheKeyFilter]; + NSString *cacheKey; + if (cacheKeyFilter) { + cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL]; + } else { + cacheKey = imageURL.absoluteString; + } + BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly); + NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor]; + CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey); + NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio]; + NSValue *thumbnailSizeValue; + BOOL shouldScaleDown = SD_OPTIONS_CONTAINS(options, SDWebImageScaleDownLargeImages); + if (shouldScaleDown) { + CGFloat thumbnailPixels = SDImageCoderHelper.defaultScaleDownLimitBytes / 4; + CGFloat dimension = ceil(sqrt(thumbnailPixels)); + thumbnailSizeValue = @(CGSizeMake(dimension, dimension)); + } + if (context[SDWebImageContextImageThumbnailPixelSize]) { + thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize]; + } + + SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:2]; + mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame); + mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale); + mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue; + mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue; + mutableCoderOptions[SDImageCoderWebImageContext] = context; + SDImageCoderOptions *coderOptions = [mutableCoderOptions copy]; + + // Grab the progressive image coder + id progressiveCoder = SDImageLoaderGetProgressiveCoder(operation); + if (!progressiveCoder) { + id imageCoder = context[SDWebImageContextImageCoder]; + // Check the progressive coder if provided + if ([imageCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) { + progressiveCoder = [[[imageCoder class] alloc] initIncrementalWithOptions:coderOptions]; + } else { + // We need to create a new instance for progressive decoding to avoid conflicts + for (id coder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) { + if ([coder conformsToProtocol:@protocol(SDProgressiveImageCoder)] && + [((id)coder) canIncrementalDecodeFromData:imageData]) { + progressiveCoder = [[[coder class] alloc] initIncrementalWithOptions:coderOptions]; + break; + } + } + } + SDImageLoaderSetProgressiveCoder(operation, progressiveCoder); + } + // If we can't find any progressive coder, disable progressive download + if (!progressiveCoder) { + return nil; + } + + [progressiveCoder updateIncrementalData:imageData finished:finished]; + if (!decodeFirstFrame) { + // check whether we should use `SDAnimatedImage` + Class animatedImageClass = context[SDWebImageContextAnimatedImageClass]; + if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [progressiveCoder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) { + image = [[animatedImageClass alloc] initWithAnimatedCoder:(id)progressiveCoder scale:scale]; + if (image) { + // Progressive decoding does not preload frames + } else { + // Check image class matching + if (options & SDWebImageMatchAnimatedImageClass) { + return nil; + } + } + } + } + if (!image) { + image = [progressiveCoder incrementalDecodedImageWithOptions:coderOptions]; + } + if (image) { + BOOL shouldDecode = !SD_OPTIONS_CONTAINS(options, SDWebImageAvoidDecodeImage); + if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) { + // `SDAnimatedImage` do not decode + shouldDecode = NO; + } else if (image.sd_isAnimated) { + // animated image do not decode + shouldDecode = NO; + } + if (shouldDecode) { + image = [SDImageCoderHelper decodedImageWithImage:image]; + } + // mark the image as progressive (completed one are not mark as progressive) + image.sd_isIncremental = !finished; + } + + return image; +} diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.h new file mode 100644 index 00000000..9886f459 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.h @@ -0,0 +1,40 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageLoader.h" + +/** + A loaders manager to manage multiple loaders + */ +@interface SDImageLoadersManager : NSObject + +/** + Returns the global shared loaders manager instance. By default we will set [`SDWebImageDownloader.sharedDownloader`] into the loaders array. + */ +@property (nonatomic, class, readonly, nonnull) SDImageLoadersManager *sharedManager; + +/** + All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority + */ +@property (nonatomic, copy, nullable) NSArray>* loaders; + +/** + Add a new image loader to the end of loaders array. Which has the highest priority. + + @param loader loader + */ +- (void)addLoader:(nonnull id)loader; + +/** + Remove an image loader in the loaders array. + + @param loader loader + */ +- (void)removeLoader:(nonnull id)loader; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.m new file mode 100644 index 00000000..ac86c29d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageLoadersManager.m @@ -0,0 +1,123 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageLoadersManager.h" +#import "SDWebImageDownloader.h" +#import "SDInternalMacros.h" + +@interface SDImageLoadersManager () + +@property (nonatomic, strong, nonnull) NSMutableArray> *imageLoaders; + +@end + +@implementation SDImageLoadersManager { + SD_LOCK_DECLARE(_loadersLock); +} + ++ (SDImageLoadersManager *)sharedManager { + static dispatch_once_t onceToken; + static SDImageLoadersManager *manager; + dispatch_once(&onceToken, ^{ + manager = [[SDImageLoadersManager alloc] init]; + }); + return manager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + // initialize with default image loaders + _imageLoaders = [NSMutableArray arrayWithObject:[SDWebImageDownloader sharedDownloader]]; + SD_LOCK_INIT(_loadersLock); + } + return self; +} + +- (NSArray> *)loaders { + SD_LOCK(_loadersLock); + NSArray>* loaders = [_imageLoaders copy]; + SD_UNLOCK(_loadersLock); + return loaders; +} + +- (void)setLoaders:(NSArray> *)loaders { + SD_LOCK(_loadersLock); + [_imageLoaders removeAllObjects]; + if (loaders.count) { + [_imageLoaders addObjectsFromArray:loaders]; + } + SD_UNLOCK(_loadersLock); +} + +#pragma mark - Loader Property + +- (void)addLoader:(id)loader { + if (![loader conformsToProtocol:@protocol(SDImageLoader)]) { + return; + } + SD_LOCK(_loadersLock); + [_imageLoaders addObject:loader]; + SD_UNLOCK(_loadersLock); +} + +- (void)removeLoader:(id)loader { + if (![loader conformsToProtocol:@protocol(SDImageLoader)]) { + return; + } + SD_LOCK(_loadersLock); + [_imageLoaders removeObject:loader]; + SD_UNLOCK(_loadersLock); +} + +#pragma mark - SDImageLoader + +- (BOOL)canRequestImageForURL:(nullable NSURL *)url { + return [self canRequestImageForURL:url options:0 context:nil]; +} + +- (BOOL)canRequestImageForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context { + NSArray> *loaders = self.loaders; + for (id loader in loaders.reverseObjectEnumerator) { + if ([loader respondsToSelector:@selector(canRequestImageForURL:options:context:)]) { + if ([loader canRequestImageForURL:url options:options context:context]) { + return YES; + } + } else { + if ([loader canRequestImageForURL:url]) { + return YES; + } + } + } + return NO; +} + +- (id)requestImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock { + if (!url) { + return nil; + } + NSArray> *loaders = self.loaders; + for (id loader in loaders.reverseObjectEnumerator) { + if ([loader canRequestImageForURL:url]) { + return [loader requestImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock]; + } + } + return nil; +} + +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + NSArray> *loaders = self.loaders; + for (id loader in loaders.reverseObjectEnumerator) { + if ([loader canRequestImageForURL:url]) { + return [loader shouldBlockFailedURLWithURL:url error:error]; + } + } + return NO; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.h new file mode 100644 index 00000000..3031bfe0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.h @@ -0,0 +1,241 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "UIImage+Transform.h" + +/** + Return the transformed cache key which applied with specify transformerKey. + + @param key The original cache key + @param transformerKey The transformer key from the transformer + @return The transformed cache key + */ +FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey); + +/** + Return the thumbnailed cache key which applied with specify thumbnailSize and preserveAspectRatio control. + @param key The original cache key + @param thumbnailPixelSize The thumbnail pixel size + @param preserveAspectRatio The preserve aspect ratio option + @return The thumbnailed cache key + @note If you have both transformer and thumbnail applied for image, call `SDThumbnailedKeyForKey` firstly and then with `SDTransformedKeyForKey`.` + */ +FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio); + +/** + A transformer protocol to transform the image load from cache or from download. + You can provide transformer to cache and manager (Through the `transformer` property or context option `SDWebImageContextImageTransformer`). + + @note The transform process is called from a global queue in order to not to block the main queue. + */ +@protocol SDImageTransformer + +@required +/** + For each transformer, it must contains its cache key to used to store the image cache or query from the cache. This key will be appened after the original cache key generated by URL or from user. + + @return The cache key to appended after the original cache key. Should not be nil. + */ +@property (nonatomic, copy, readonly, nonnull) NSString *transformerKey; + +/** + Transform the image to another image. + + @param image The image to be transformed + @param key The cache key associated to the image. This arg is a hint for image source, not always useful and should be nullable. In the future we will remove this arg. + @return The transformed image, or nil if transform failed + */ +- (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key API_DEPRECATED("The key arg will be removed in the future. Update your code and don't rely on that.", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED)); + +@end + +#pragma mark - Pipeline + +/** + Pipeline transformer. Which you can bind multiple transformers together to let the image to be transformed one by one in order and generate the final image. + @note Because transformers are lightweight, if you want to append or arrange transformers, create another pipeline transformer instead. This class is considered as immutable. + */ +@interface SDImagePipelineTransformer : NSObject + +/** + All transformers in pipeline + */ +@property (nonatomic, copy, readonly, nonnull) NSArray> *transformers; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithTransformers:(nonnull NSArray> *)transformers; + +@end + +// There are some built-in transformers based on the `UIImage+Transformer` category to provide the common image geometry, image blending and image effect process. Those transform are useful for static image only but you can create your own to support animated image as well. +// Because transformers are lightweight, these class are considered as immutable. +#pragma mark - Image Geometry + +/** + Image round corner transformer + */ +@interface SDImageRoundCornerTransformer: NSObject + +/** + The radius of each corner oval. Values larger than half the + rectangle's width or height are clamped appropriately to + half the width or height. + */ +@property (nonatomic, assign, readonly) CGFloat cornerRadius; + +/** + A bitmask value that identifies the corners that you want + rounded. You can use this parameter to round only a subset + of the corners of the rectangle. + */ +@property (nonatomic, assign, readonly) SDRectCorner corners; + +/** + The inset border line width. Values larger than half the rectangle's + width or height are clamped appropriately to half the width + or height. + */ +@property (nonatomic, assign, readonly) CGFloat borderWidth; + +/** + The border stroke color. nil means clear color. + */ +@property (nonatomic, strong, readonly, nullable) UIColor *borderColor; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor; + +@end + +/** + Image resizing transformer + */ +@interface SDImageResizingTransformer : NSObject + +/** + The new size to be resized, values should be positive. + */ +@property (nonatomic, assign, readonly) CGSize size; + +/** + The scale mode for image content. + */ +@property (nonatomic, assign, readonly) SDImageScaleMode scaleMode; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode; + +@end + +/** + Image cropping transformer + */ +@interface SDImageCroppingTransformer : NSObject + +/** + Image's inner rect. + */ +@property (nonatomic, assign, readonly) CGRect rect; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithRect:(CGRect)rect; + +@end + +/** + Image flipping transformer + */ +@interface SDImageFlippingTransformer : NSObject + +/** + YES to flip the image horizontally. ⇋ + */ +@property (nonatomic, assign, readonly) BOOL horizontal; + +/** + YES to flip the image vertically. ⥯ + */ +@property (nonatomic, assign, readonly) BOOL vertical; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical; + +@end + +/** + Image rotation transformer + */ +@interface SDImageRotationTransformer : NSObject + +/** + Rotated radians in counterclockwise.⟲ + */ +@property (nonatomic, assign, readonly) CGFloat angle; + +/** + YES: new image's size is extend to fit all content. + NO: image's size will not change, content may be clipped. + */ +@property (nonatomic, assign, readonly) BOOL fitSize; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize; + +@end + +#pragma mark - Image Blending + +/** + Image tint color transformer + */ +@interface SDImageTintTransformer : NSObject + +/** + The tint color. + */ +@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithColor:(nonnull UIColor *)tintColor; + +@end + +#pragma mark - Image Effect + +/** + Image blur effect transformer + */ +@interface SDImageBlurTransformer : NSObject + +/** + The radius of the blur in points, 0 means no blur effect. + */ +@property (nonatomic, assign, readonly) CGFloat blurRadius; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithRadius:(CGFloat)blurRadius; + +@end + +#if SD_UIKIT || SD_MAC +/** + Core Image filter transformer + */ +@interface SDImageFilterTransformer: NSObject + +/** + The CIFilter to be applied to the image. + */ +@property (nonatomic, strong, readonly, nonnull) CIFilter *filter; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)transformerWithFilter:(nonnull CIFilter *)filter; + +@end +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.m new file mode 100644 index 00000000..8e7a3e2a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDImageTransformer.m @@ -0,0 +1,331 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageTransformer.h" +#import "UIColor+SDHexString.h" +#if SD_UIKIT || SD_MAC +#import +#endif + +// Separator for different transformerKey, for example, `image.png` |> flip(YES,NO) |> rotate(pi/4,YES) => 'image-SDImageFlippingTransformer(1,0)-SDImageRotationTransformer(0.78539816339,1).png' +static NSString * const SDImageTransformerKeySeparator = @"-"; + +NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey) { + if (!key || !transformerKey) { + return nil; + } + // Find the file extension + NSURL *keyURL = [NSURL URLWithString:key]; + NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension; + if (ext.length > 0) { + // For non-file URL + if (keyURL && !keyURL.isFileURL) { + // keep anything except path (like URL query) + NSURLComponents *component = [NSURLComponents componentsWithURL:keyURL resolvingAgainstBaseURL:NO]; + component.path = [[[component.path.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext]; + return component.URL.absoluteString; + } else { + // file URL + return [[[key.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext]; + } + } else { + return [[key stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey]; + } +} + +NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio) { + NSString *thumbnailKey = [NSString stringWithFormat:@"Thumbnail({%f,%f},%d)", thumbnailPixelSize.width, thumbnailPixelSize.height, preserveAspectRatio]; + return SDTransformedKeyForKey(key, thumbnailKey); +} + +@interface SDImagePipelineTransformer () + +@property (nonatomic, copy, readwrite, nonnull) NSArray> *transformers; +@property (nonatomic, copy, readwrite) NSString *transformerKey; + +@end + +@implementation SDImagePipelineTransformer + ++ (instancetype)transformerWithTransformers:(NSArray> *)transformers { + SDImagePipelineTransformer *transformer = [SDImagePipelineTransformer new]; + transformer.transformers = transformers; + transformer.transformerKey = [[self class] cacheKeyForTransformers:transformers]; + + return transformer; +} + ++ (NSString *)cacheKeyForTransformers:(NSArray> *)transformers { + if (transformers.count == 0) { + return @""; + } + NSMutableArray *cacheKeys = [NSMutableArray arrayWithCapacity:transformers.count]; + [transformers enumerateObjectsUsingBlock:^(id _Nonnull transformer, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *cacheKey = transformer.transformerKey; + [cacheKeys addObject:cacheKey]; + }]; + + return [cacheKeys componentsJoinedByString:SDImageTransformerKeySeparator]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + UIImage *transformedImage = image; + for (id transformer in self.transformers) { + transformedImage = [transformer transformedImageWithImage:transformedImage forKey:key]; + } + return transformedImage; +} + +@end + +@interface SDImageRoundCornerTransformer () + +@property (nonatomic, assign) CGFloat cornerRadius; +@property (nonatomic, assign) SDRectCorner corners; +@property (nonatomic, assign) CGFloat borderWidth; +@property (nonatomic, strong, nullable) UIColor *borderColor; + +@end + +@implementation SDImageRoundCornerTransformer + ++ (instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor { + SDImageRoundCornerTransformer *transformer = [SDImageRoundCornerTransformer new]; + transformer.cornerRadius = cornerRadius; + transformer.corners = corners; + transformer.borderWidth = borderWidth; + transformer.borderColor = borderColor; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageRoundCornerTransformer(%f,%lu,%f,%@)", self.cornerRadius, (unsigned long)self.corners, self.borderWidth, self.borderColor.sd_hexString]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_roundedCornerImageWithRadius:self.cornerRadius corners:self.corners borderWidth:self.borderWidth borderColor:self.borderColor]; +} + +@end + +@interface SDImageResizingTransformer () + +@property (nonatomic, assign) CGSize size; +@property (nonatomic, assign) SDImageScaleMode scaleMode; + +@end + +@implementation SDImageResizingTransformer + ++ (instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode { + SDImageResizingTransformer *transformer = [SDImageResizingTransformer new]; + transformer.size = size; + transformer.scaleMode = scaleMode; + + return transformer; +} + +- (NSString *)transformerKey { + CGSize size = self.size; + return [NSString stringWithFormat:@"SDImageResizingTransformer({%f,%f},%lu)", size.width, size.height, (unsigned long)self.scaleMode]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_resizedImageWithSize:self.size scaleMode:self.scaleMode]; +} + +@end + +@interface SDImageCroppingTransformer () + +@property (nonatomic, assign) CGRect rect; + +@end + +@implementation SDImageCroppingTransformer + ++ (instancetype)transformerWithRect:(CGRect)rect { + SDImageCroppingTransformer *transformer = [SDImageCroppingTransformer new]; + transformer.rect = rect; + + return transformer; +} + +- (NSString *)transformerKey { + CGRect rect = self.rect; + return [NSString stringWithFormat:@"SDImageCroppingTransformer({%f,%f,%f,%f})", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_croppedImageWithRect:self.rect]; +} + +@end + +@interface SDImageFlippingTransformer () + +@property (nonatomic, assign) BOOL horizontal; +@property (nonatomic, assign) BOOL vertical; + +@end + +@implementation SDImageFlippingTransformer + ++ (instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical { + SDImageFlippingTransformer *transformer = [SDImageFlippingTransformer new]; + transformer.horizontal = horizontal; + transformer.vertical = vertical; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageFlippingTransformer(%d,%d)", self.horizontal, self.vertical]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_flippedImageWithHorizontal:self.horizontal vertical:self.vertical]; +} + +@end + +@interface SDImageRotationTransformer () + +@property (nonatomic, assign) CGFloat angle; +@property (nonatomic, assign) BOOL fitSize; + +@end + +@implementation SDImageRotationTransformer + ++ (instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize { + SDImageRotationTransformer *transformer = [SDImageRotationTransformer new]; + transformer.angle = angle; + transformer.fitSize = fitSize; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageRotationTransformer(%f,%d)", self.angle, self.fitSize]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_rotatedImageWithAngle:self.angle fitSize:self.fitSize]; +} + +@end + +#pragma mark - Image Blending + +@interface SDImageTintTransformer () + +@property (nonatomic, strong, nonnull) UIColor *tintColor; + +@end + +@implementation SDImageTintTransformer + ++ (instancetype)transformerWithColor:(UIColor *)tintColor { + SDImageTintTransformer *transformer = [SDImageTintTransformer new]; + transformer.tintColor = tintColor; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageTintTransformer(%@)", self.tintColor.sd_hexString]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_tintedImageWithColor:self.tintColor]; +} + +@end + +#pragma mark - Image Effect + +@interface SDImageBlurTransformer () + +@property (nonatomic, assign) CGFloat blurRadius; + +@end + +@implementation SDImageBlurTransformer + ++ (instancetype)transformerWithRadius:(CGFloat)blurRadius { + SDImageBlurTransformer *transformer = [SDImageBlurTransformer new]; + transformer.blurRadius = blurRadius; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageBlurTransformer(%f)", self.blurRadius]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_blurredImageWithRadius:self.blurRadius]; +} + +@end + +#if SD_UIKIT || SD_MAC +@interface SDImageFilterTransformer () + +@property (nonatomic, strong, nonnull) CIFilter *filter; + +@end + +@implementation SDImageFilterTransformer + ++ (instancetype)transformerWithFilter:(CIFilter *)filter { + SDImageFilterTransformer *transformer = [SDImageFilterTransformer new]; + transformer.filter = filter; + + return transformer; +} + +- (NSString *)transformerKey { + return [NSString stringWithFormat:@"SDImageFilterTransformer(%@)", self.filter.name]; +} + +- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key { + if (!image) { + return nil; + } + return [image sd_filteredImageWithFilter:self.filter]; +} + +@end +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.h new file mode 100644 index 00000000..43c39e84 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.h @@ -0,0 +1,78 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +@class SDImageCacheConfig; +/** + A protocol to allow custom memory cache used in SDImageCache. + */ +@protocol SDMemoryCache + +@required + +/** + Create a new memory cache instance with the specify cache config. You can check `maxMemoryCost` and `maxMemoryCount` used for memory cache. + + @param config The cache config to be used to create the cache. + @return The new memory cache instance. + */ +- (nonnull instancetype)initWithConfig:(nonnull SDImageCacheConfig *)config; + +/** + Returns the value associated with a given key. + + @param key An object identifying the value. If nil, just return nil. + @return The value associated with key, or nil if no value is associated with key. + */ +- (nullable id)objectForKey:(nonnull id)key; + +/** + Sets the value of the specified key in the cache (0 cost). + + @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`. + @param key The key with which to associate the value. If nil, this method has no effect. + @discussion Unlike an NSMutableDictionary object, a cache does not copy the key + objects that are put into it. + */ +- (void)setObject:(nullable id)object forKey:(nonnull id)key; + +/** + Sets the value of the specified key in the cache, and associates the key-value + pair with the specified cost. + + @param object The object to store in the cache. If nil, it calls `removeObjectForKey`. + @param key The key with which to associate the value. If nil, this method has no effect. + @param cost The cost with which to associate the key-value pair. + @discussion Unlike an NSMutableDictionary object, a cache does not copy the key + objects that are put into it. + */ +- (void)setObject:(nullable id)object forKey:(nonnull id)key cost:(NSUInteger)cost; + +/** + Removes the value of the specified key in the cache. + + @param key The key identifying the value to be removed. If nil, this method has no effect. + */ +- (void)removeObjectForKey:(nonnull id)key; + +/** + Empties the cache immediately. + */ +- (void)removeAllObjects; + +@end + +/** + A memory cache which auto purge the cache on memory warning and support weak cache. + */ +@interface SDMemoryCache : NSCache + +@property (nonatomic, strong, nonnull, readonly) SDImageCacheConfig *config; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.m new file mode 100644 index 00000000..7bcc3859 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDMemoryCache.m @@ -0,0 +1,158 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDMemoryCache.h" +#import "SDImageCacheConfig.h" +#import "UIImage+MemoryCacheCost.h" +#import "SDInternalMacros.h" + +static void * SDMemoryCacheContext = &SDMemoryCacheContext; + +@interface SDMemoryCache () { +#if SD_UIKIT + SD_LOCK_DECLARE(_weakCacheLock); // a lock to keep the access to `weakCache` thread-safe +#endif +} + +@property (nonatomic, strong, nullable) SDImageCacheConfig *config; +#if SD_UIKIT +@property (nonatomic, strong, nonnull) NSMapTable *weakCache; // strong-weak cache +#endif +@end + +@implementation SDMemoryCache + +- (void)dealloc { + [_config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCost)) context:SDMemoryCacheContext]; + [_config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCount)) context:SDMemoryCacheContext]; +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + self.delegate = nil; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _config = [[SDImageCacheConfig alloc] init]; + [self commonInit]; + } + return self; +} + +- (instancetype)initWithConfig:(SDImageCacheConfig *)config { + self = [super init]; + if (self) { + _config = config; + [self commonInit]; + } + return self; +} + +- (void)commonInit { + SDImageCacheConfig *config = self.config; + self.totalCostLimit = config.maxMemoryCost; + self.countLimit = config.maxMemoryCount; + + [config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCost)) options:0 context:SDMemoryCacheContext]; + [config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxMemoryCount)) options:0 context:SDMemoryCacheContext]; + +#if SD_UIKIT + self.weakCache = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0]; + SD_LOCK_INIT(_weakCacheLock); + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didReceiveMemoryWarning:) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; +#endif +} + +// Current this seems no use on macOS (macOS use virtual memory and do not clear cache when memory warning). So we only override on iOS/tvOS platform. +#if SD_UIKIT +- (void)didReceiveMemoryWarning:(NSNotification *)notification { + // Only remove cache, but keep weak cache + [super removeAllObjects]; +} + +// `setObject:forKey:` just call this with 0 cost. Override this is enough +- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g { + [super setObject:obj forKey:key cost:g]; + if (!self.config.shouldUseWeakMemoryCache) { + return; + } + if (key && obj) { + // Store weak cache + SD_LOCK(_weakCacheLock); + [self.weakCache setObject:obj forKey:key]; + SD_UNLOCK(_weakCacheLock); + } +} + +- (id)objectForKey:(id)key { + id obj = [super objectForKey:key]; + if (!self.config.shouldUseWeakMemoryCache) { + return obj; + } + if (key && !obj) { + // Check weak cache + SD_LOCK(_weakCacheLock); + obj = [self.weakCache objectForKey:key]; + SD_UNLOCK(_weakCacheLock); + if (obj) { + // Sync cache + NSUInteger cost = 0; + if ([obj isKindOfClass:[UIImage class]]) { + cost = [(UIImage *)obj sd_memoryCost]; + } + [super setObject:obj forKey:key cost:cost]; + } + } + return obj; +} + +- (void)removeObjectForKey:(id)key { + [super removeObjectForKey:key]; + if (!self.config.shouldUseWeakMemoryCache) { + return; + } + if (key) { + // Remove weak cache + SD_LOCK(_weakCacheLock); + [self.weakCache removeObjectForKey:key]; + SD_UNLOCK(_weakCacheLock); + } +} + +- (void)removeAllObjects { + [super removeAllObjects]; + if (!self.config.shouldUseWeakMemoryCache) { + return; + } + // Manually remove should also remove weak cache + SD_LOCK(_weakCacheLock); + [self.weakCache removeAllObjects]; + SD_UNLOCK(_weakCacheLock); +} +#endif + +#pragma mark - KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if (context == SDMemoryCacheContext) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxMemoryCost))]) { + self.totalCostLimit = self.config.maxMemoryCost; + } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxMemoryCount))]) { + self.countLimit = self.config.maxMemoryCount; + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.h new file mode 100644 index 00000000..4f54dd89 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.h @@ -0,0 +1,32 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +typedef NSString * _Nullable(^SDWebImageCacheKeyFilterBlock)(NSURL * _Nonnull url); + +/** + This is the protocol for cache key filter. + We can use a block to specify the cache key filter. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. + */ +@protocol SDWebImageCacheKeyFilter + +- (nullable NSString *)cacheKeyForURL:(nonnull NSURL *)url; + +@end + +/** + A cache key filter class with block. + */ +@interface SDWebImageCacheKeyFilter : NSObject + +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block; ++ (nonnull instancetype)cacheKeyFilterWithBlock:(nonnull SDWebImageCacheKeyFilterBlock)block; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.m new file mode 100644 index 00000000..b4ebb8b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheKeyFilter.m @@ -0,0 +1,39 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCacheKeyFilter.h" + +@interface SDWebImageCacheKeyFilter () + +@property (nonatomic, copy, nonnull) SDWebImageCacheKeyFilterBlock block; + +@end + +@implementation SDWebImageCacheKeyFilter + +- (instancetype)initWithBlock:(SDWebImageCacheKeyFilterBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)cacheKeyFilterWithBlock:(SDWebImageCacheKeyFilterBlock)block { + SDWebImageCacheKeyFilter *cacheKeyFilter = [[SDWebImageCacheKeyFilter alloc] initWithBlock:block]; + return cacheKeyFilter; +} + +- (NSString *)cacheKeyForURL:(NSURL *)url { + if (!self.block) { + return nil; + } + return self.block(url); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.h new file mode 100644 index 00000000..3c271b1f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.h @@ -0,0 +1,36 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +typedef NSData * _Nullable(^SDWebImageCacheSerializerBlock)(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL); + +/** + This is the protocol for cache serializer. + We can use a block to specify the cache serializer. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. + */ +@protocol SDWebImageCacheSerializer + +/// Provide the image data associated to the image and store to disk cache +/// @param image The loaded image +/// @param data The original loaded image data +/// @param imageURL The image URL +- (nullable NSData *)cacheDataWithImage:(nonnull UIImage *)image originalData:(nullable NSData *)data imageURL:(nullable NSURL *)imageURL; + +@end + +/** + A cache serializer class with block. + */ +@interface SDWebImageCacheSerializer : NSObject + +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageCacheSerializerBlock)block; ++ (nonnull instancetype)cacheSerializerWithBlock:(nonnull SDWebImageCacheSerializerBlock)block; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.m new file mode 100644 index 00000000..51528e68 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCacheSerializer.m @@ -0,0 +1,39 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCacheSerializer.h" + +@interface SDWebImageCacheSerializer () + +@property (nonatomic, copy, nonnull) SDWebImageCacheSerializerBlock block; + +@end + +@implementation SDWebImageCacheSerializer + +- (instancetype)initWithBlock:(SDWebImageCacheSerializerBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)cacheSerializerWithBlock:(SDWebImageCacheSerializerBlock)block { + SDWebImageCacheSerializer *cacheSerializer = [[SDWebImageCacheSerializer alloc] initWithBlock:block]; + return cacheSerializer; +} + +- (NSData *)cacheDataWithImage:(UIImage *)image originalData:(NSData *)data imageURL:(nullable NSURL *)imageURL { + if (!self.block) { + return nil; + } + return self.block(image, data, imageURL); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.h new file mode 100644 index 00000000..f47a248a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.h @@ -0,0 +1,95 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Jamie Pinkham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import + +#ifdef __OBJC_GC__ + #error SDWebImage does not support Objective-C Garbage Collection +#endif + +// Seems like TARGET_OS_MAC is always defined (on all platforms). +// To determine if we are running on macOS, use TARGET_OS_OSX in Xcode 8 +#if TARGET_OS_OSX + #define SD_MAC 1 +#else + #define SD_MAC 0 +#endif + +// iOS and tvOS are very similar, UIKit exists on both platforms +// Note: watchOS also has UIKit, but it's very limited +#if TARGET_OS_IOS || TARGET_OS_TV + #define SD_UIKIT 1 +#else + #define SD_UIKIT 0 +#endif + +#if TARGET_OS_IOS + #define SD_IOS 1 +#else + #define SD_IOS 0 +#endif + +#if TARGET_OS_TV + #define SD_TV 1 +#else + #define SD_TV 0 +#endif + +#if TARGET_OS_WATCH + #define SD_WATCH 1 +#else + #define SD_WATCH 0 +#endif + + +#if SD_MAC + #import + #ifndef UIImage + #define UIImage NSImage + #endif + #ifndef UIImageView + #define UIImageView NSImageView + #endif + #ifndef UIView + #define UIView NSView + #endif + #ifndef UIColor + #define UIColor NSColor + #endif +#else + #if SD_UIKIT + #import + #endif + #if SD_WATCH + #import + #ifndef UIView + #define UIView WKInterfaceObject + #endif + #ifndef UIImageView + #define UIImageView WKInterfaceImage + #endif + #endif +#endif + +#ifndef NS_ENUM +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#endif + +#ifndef NS_OPTIONS +#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#endif + +#ifndef dispatch_main_async_safe +#define dispatch_main_async_safe(block)\ + if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\ + block();\ + } else {\ + dispatch_async(dispatch_get_main_queue(), block);\ + } +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.m new file mode 100644 index 00000000..12974010 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageCompat.m @@ -0,0 +1,17 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if !__has_feature(objc_arc) + #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag +#endif + +#if !OS_OBJECT_USE_OBJC + #error SDWebImage need ARC for dispatch object +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.h new file mode 100644 index 00000000..83a2d186 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.h @@ -0,0 +1,324 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +typedef void(^SDWebImageNoParamsBlock)(void); +typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM; +typedef NSDictionary SDWebImageContext; +typedef NSMutableDictionary SDWebImageMutableContext; + +#pragma mark - Image scale + +/** + Return the image scale factor for the specify key, supports file name and url key. + This is the built-in way to check the scale factor when we have no context about it. Because scale factor is not stored in image data (It's typically from filename). + However, you can also provide custom scale factor as well, see `SDWebImageContextImageScaleFactor`. + + @param key The image cache key + @return The scale factor for image + */ +FOUNDATION_EXPORT CGFloat SDImageScaleFactorForKey(NSString * _Nullable key); + +/** + Scale the image with the scale factor for the specify key. If no need to scale, return the original image. + This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+Metadata.h`. + @note This is actually a convenience function, which firstly call `SDImageScaleFactorForKey` and then call `SDScaledImageForScaleFactor`, kept for backward compatibility. + + @param key The image cache key + @param image The image + @return The scaled image + */ +FOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image); + +/** + Scale the image with the scale factor. If no need to scale, return the original image. + This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+Metadata.h`. + + @param scale The image scale factor + @param image The image + @return The scaled image + */ +FOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image); + +#pragma mark - WebCache Options + +/// WebCache options +typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { + /** + * By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying. + * This flag disable this blacklisting. + */ + SDWebImageRetryFailed = 1 << 0, + + /** + * By default, image downloads are started during UI interactions, this flags disable this feature, + * leading to delayed download on UIScrollView deceleration for instance. + */ + SDWebImageLowPriority = 1 << 1, + + /** + * This flag enables progressive download, the image is displayed progressively during download as a browser would do. + * By default, the image is only displayed once completely downloaded. + */ + SDWebImageProgressiveLoad = 1 << 2, + + /** + * Even if the image is cached, respect the HTTP response cache control, and refresh the image from remote location if needed. + * The disk caching will be handled by NSURLCache instead of SDWebImage leading to slight performance degradation. + * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics. + * If a cached image is refreshed, the completion block is called once with the cached image and again with the final image. + * + * Use this flag only if you can't make your URLs static with embedded cache busting parameter. + */ + SDWebImageRefreshCached = 1 << 3, + + /** + * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for + * extra time in background to let the request finish. If the background task expires the operation will be cancelled. + */ + SDWebImageContinueInBackground = 1 << 4, + + /** + * Handles cookies stored in NSHTTPCookieStore by setting + * NSMutableURLRequest.HTTPShouldHandleCookies = YES; + */ + SDWebImageHandleCookies = 1 << 5, + + /** + * Enable to allow untrusted SSL certificates. + * Useful for testing purposes. Use with caution in production. + */ + SDWebImageAllowInvalidSSLCertificates = 1 << 6, + + /** + * By default, images are loaded in the order in which they were queued. This flag moves them to + * the front of the queue. + */ + SDWebImageHighPriority = 1 << 7, + + /** + * By default, placeholder images are loaded while the image is loading. This flag will delay the loading + * of the placeholder image until after the image has finished loading. + */ + SDWebImageDelayPlaceholder = 1 << 8, + + /** + * We usually don't apply transform on animated images as most transformers could not manage animated images. + * Use this flag to transform them anyway. + */ + SDWebImageTransformAnimatedImage = 1 << 9, + + /** + * By default, image is added to the imageView after download. But in some cases, we want to + * have the hand before setting the image (apply a filter or add it with cross-fade animation for instance) + * Use this flag if you want to manually set the image in the completion when success + */ + SDWebImageAvoidAutoSetImage = 1 << 10, + + /** + * By default, images are decoded respecting their original size. + * This flag will scale down the images to a size compatible with the constrained memory of devices. + * To control the limit memory bytes, check `SDImageCoderHelper.defaultScaleDownLimitBytes` (Defaults to 60MB on iOS) + * This will actually translate to use context option `.imageThumbnailPixelSize` from v5.5.0 (Defaults to (3966, 3966) on iOS). Previously does not. + * This flags effect the progressive and animated images as well from v5.5.0. Previously does not. + * @note If you need detail controls, it's better to use context option `imageThumbnailPixelSize` and `imagePreserveAspectRatio` instead. + */ + SDWebImageScaleDownLargeImages = 1 << 11, + + /** + * By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDWebImageQueryMemoryDataSync` + */ + SDWebImageQueryMemoryData = 1 << 12, + + /** + * By default, when you only specify `SDWebImageQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously. + * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing. + */ + SDWebImageQueryMemoryDataSync = 1 << 13, + + /** + * By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously. + * @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page. + * @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing. + */ + SDWebImageQueryDiskDataSync = 1 << 14, + + /** + * By default, when the cache missed, the image is load from the loader. This flag can prevent this to load from cache only. + */ + SDWebImageFromCacheOnly = 1 << 15, + + /** + * By default, we query the cache before the image is load from the loader. This flag can prevent this to load from loader only. + */ + SDWebImageFromLoaderOnly = 1 << 16, + + /** + * By default, when you use `SDWebImageTransition` to do some view transition after the image load finished, this transition is only applied for image when the callback from manager is asynchronous (from network, or disk cache query) + * This mask can force to apply view transition for any cases, like memory cache query, or sync disk cache query. + */ + SDWebImageForceTransition = 1 << 17, + + /** + * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation. + * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image. + */ + SDWebImageAvoidDecodeImage = 1 << 18, + + /** + * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image. + */ + SDWebImageDecodeFirstFrameOnly = 1 << 19, + + /** + * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. However, you can specify to preload all frames into memory to reduce CPU usage when the animated image is shared by lots of imageViews. + * This will actually trigger `preloadAllAnimatedImageFrames` in the background queue(Disk Cache & Download only). + */ + SDWebImagePreloadAllFrames = 1 << 20, + + /** + * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available to produce one exactlly matching your custom class as a fallback solution. + * Using this option, can ensure we always callback image with your provided class. If failed to produce one, a error with code `SDWebImageErrorBadImageData` will been used. + * Note this options is not compatible with `SDWebImageDecodeFirstFrameOnly`, which always produce a UIImage/NSImage. + */ + SDWebImageMatchAnimatedImageClass = 1 << 21, + + /** + * By default, when we load the image from network, the image will be written to the cache (memory and disk, controlled by your `storeCacheType` context option) + * This maybe an asynchronously operation and the final `SDInternalCompletionBlock` callback does not guarantee the disk cache written is finished and may cause logic error. (For example, you modify the disk data just in completion block, however, the disk cache is not ready) + * If you need to process with the disk cache in the completion block, you should use this option to ensure the disk cache already been written when callback. + * Note if you use this when using the custom cache serializer, or using the transformer, we will also wait until the output image data written is finished. + */ + SDWebImageWaitStoreCache = 1 << 22, + + /** + * We usually don't apply transform on vector images, because vector images supports dynamically changing to any size, rasterize to a fixed size will loss details. To modify vector images, you can process the vector data at runtime (such as modifying PDF tag / SVG element). + * Use this flag to transform them anyway. + */ + SDWebImageTransformVectorImage = 1 << 23 +}; + + +#pragma mark - Context Options + +/** + A String to be used as the operation key for view category to store the image load operation. This is used for view instance which supports different image loading process. If nil, will use the class name as operation key. (NSString *) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextSetImageOperationKey; + +/** + A SDWebImageManager instance to control the image download and cache process using in UIImageView+WebCache category and likes. If not provided, use the shared manager (SDWebImageManager *) + @deprecated Deprecated in the future. This context options can be replaced by other context option control like `.imageCache`, `.imageLoader`, `.imageTransformer` (See below), which already matches all the properties in SDWebImageManager. + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCustomManager API_DEPRECATED("Use individual context option like .imageCache, .imageLoader and .imageTransformer instead", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED)); + +/** + A id instance which conforms to `SDImageCache` protocol. It's used to override the image manager's cache during the image loading pipeline. + In other word, if you just want to specify a custom cache during image loading, you don't need to re-create a dummy SDWebImageManager instance with the cache. If not provided, use the image manager's cache (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageCache; + +/** + A id instance which conforms to `SDImageLoader` protocol. It's used to override the image manager's loader during the image loading pipeline. + In other word, if you just want to specify a custom loader during image loading, you don't need to re-create a dummy SDWebImageManager instance with the loader. If not provided, use the image manager's cache (id) +*/ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageLoader; + +/** + A id instance which conforms to `SDImageCoder` protocol. It's used to override the default image coder for image decoding(including progressive) and encoding during the image loading process. + If you use this context option, we will not always use `SDImageCodersManager.shared` to loop through all registered coders and find the suitable one. Instead, we will arbitrarily use the exact provided coder without extra checking (We may not call `canDecodeFromData:`). + @note This is only useful for cases which you can ensure the loading url matches your coder, or you find it's too hard to write a common coder which can used for generic usage. This will bind the loading url with the coder logic, which is not always a good design, but possible. (id) +*/ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageCoder; + +/** + A id instance which conforms `SDImageTransformer` protocol. It's used for image transform after the image load finished and store the transformed image to cache. If you provide one, it will ignore the `transformer` in manager and use provided one instead. If you pass NSNull, the transformer feature will be disabled. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageTransformer; + +/** + A CGFloat raw value which specify the image scale factor. The number should be greater than or equal to 1.0. If not provide or the number is invalid, we will use the cache key to specify the scale factor. (NSNumber) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageScaleFactor; + +/** + A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format). + Defaults to YES. (NSNumber) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImagePreserveAspectRatio; + +/** + A CGSize raw value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.imagePreserveAspectRatio`) the value size. + @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both. + Defaults to CGSizeZero, which means no thumbnail generation at all. (NSValue) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageThumbnailPixelSize; + +/** + A SDImageCacheType raw value which specify the source of cache to query. Specify `SDImageCacheTypeDisk` to query from disk cache only; `SDImageCacheTypeMemory` to query from memory only. And `SDImageCacheTypeAll` to query from both memory cache and disk cache. Specify `SDImageCacheTypeNone` is invalid and totally ignore the cache query. + If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextQueryCacheType; + +/** + A SDImageCacheType raw value which specify the store cache type when the image has just been downloaded and will be stored to the cache. Specify `SDImageCacheTypeNone` to disable cache storage; `SDImageCacheTypeDisk` to store in disk cache only; `SDImageCacheTypeMemory` to store in memory only. And `SDImageCacheTypeAll` to store in both memory cache and disk cache. + If you use image transformer feature, this actually apply for the transformed image, but not the original image itself. Use `SDWebImageContextOriginalStoreCacheType` if you want to control the original image's store cache type at the same time. + If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextStoreCacheType; + +/** + The same behavior like `SDWebImageContextQueryCacheType`, but control the query cache type for the original image when you use image transformer feature. This allows the detail control of cache query for these two images. For example, if you want to query the transformed image from both memory/disk cache, query the original image from disk cache only, use `[.queryCacheType : .all, .originalQueryCacheType : .disk]` + If not provide or the value is invalid, we will use `SDImageCacheTypeDisk`, which query the original full image data from disk cache after transformed image cache miss. This is suitable for most common cases to avoid re-downloading the full data for different transform variants. (NSNumber) + @note Which means, if you set this value to not be `.none`, we will query the original image from cache, then do transform with transformer, instead of actual downloading, which can save bandwidth usage. + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalQueryCacheType; + +/** + The same behavior like `SDWebImageContextStoreCacheType`, but control the store cache type for the original image when you use image transformer feature. This allows the detail control of cache storage for these two images. For example, if you want to store the transformed image into both memory/disk cache, store the original image into disk cache only, use `[.storeCacheType : .all, .originalStoreCacheType : .disk]` + If not provide or the value is invalid, we will use `SDImageCacheTypeDisk`, which store the original full image data into disk cache after storing the transformed image. This is suitable for most common cases to avoid re-downloading the full data for different transform variants. (NSNumber) + @note This only store the original image, if you want to use the original image without downloading in next query, specify `SDWebImageContextOriginalQueryCacheType` as well. + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalStoreCacheType; + +/** + A id instance which conforms to `SDImageCache` protocol. It's used to control the cache for original image when using the transformer. If you provide one, the original image (full size image) will query and write from that cache instance instead, the transformed image will query and write from the default `SDWebImageContextImageCache` instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalImageCache; + +/** + A Class object which the instance is a `UIImage/NSImage` subclass and adopt `SDAnimatedImage` protocol. We will call `initWithData:scale:options:` to create the instance (or `initWithAnimatedCoder:scale:` when using progressive download) . If the instance create failed, fallback to normal `UIImage/NSImage`. + This can be used to improve animated images rendering performance (especially memory usage on big animated images) with `SDAnimatedImageView` (Class). + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextAnimatedImageClass; + +/** + A id instance to modify the image download request. It's used for downloader to modify the original request from URL and options. If you provide one, it will ignore the `requestModifier` in downloader and use provided one instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadRequestModifier; + +/** + A id instance to modify the image download response. It's used for downloader to modify the original response from URL and options. If you provide one, it will ignore the `responseModifier` in downloader and use provided one instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadResponseModifier; + +/** + A id instance to decrypt the image download data. This can be used for image data decryption, such as Base64 encoded image. If you provide one, it will ignore the `decryptor` in downloader and use provided one instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextDownloadDecryptor; + +/** + A id instance to convert an URL into a cache key. It's used when manager need cache key to use image cache. If you provide one, it will ignore the `cacheKeyFilter` in manager and use provided one instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCacheKeyFilter; + +/** + A id instance to convert the decoded image, the source downloaded data, to the actual data. It's used for manager to store image to the disk cache. If you provide one, it will ignore the `cacheSerializer` in manager and use provided one instead. (id) + */ +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCacheSerializer; diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.m new file mode 100644 index 00000000..845730f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDefine.m @@ -0,0 +1,140 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDefine.h" +#import "UIImage+Metadata.h" +#import "NSImage+Compatibility.h" +#import "SDAssociatedObject.h" + +#pragma mark - Image scale + +static inline NSArray * _Nonnull SDImageScaleFactors() { + return @[@2, @3]; +} + +inline CGFloat SDImageScaleFactorForKey(NSString * _Nullable key) { + CGFloat scale = 1; + if (!key) { + return scale; + } + // Check if target OS support scale +#if SD_WATCH + if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) +#elif SD_UIKIT + if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) +#elif SD_MAC + if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]) +#endif + { + // a@2x.png -> 8 + if (key.length >= 8) { + // Fast check + BOOL isURL = [key hasPrefix:@"http://"] || [key hasPrefix:@"https://"]; + for (NSNumber *scaleFactor in SDImageScaleFactors()) { + // @2x. for file name and normal url + NSString *fileScale = [NSString stringWithFormat:@"@%@x.", scaleFactor]; + if ([key containsString:fileScale]) { + scale = scaleFactor.doubleValue; + return scale; + } + if (isURL) { + // %402x. for url encode + NSString *urlScale = [NSString stringWithFormat:@"%%40%@x.", scaleFactor]; + if ([key containsString:urlScale]) { + scale = scaleFactor.doubleValue; + return scale; + } + } + } + } + } + return scale; +} + +inline UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) { + if (!image) { + return nil; + } + CGFloat scale = SDImageScaleFactorForKey(key); + return SDScaledImageForScaleFactor(scale, image); +} + +inline UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image) { + if (!image) { + return nil; + } + if (scale <= 1) { + return image; + } + if (scale == image.scale) { + return image; + } + UIImage *scaledImage; + if (image.sd_isAnimated) { + UIImage *animatedImage; +#if SD_UIKIT || SD_WATCH + // `UIAnimatedImage` images share the same size and scale. + NSMutableArray *scaledImages = [NSMutableArray array]; + + for (UIImage *tempImage in image.images) { + UIImage *tempScaledImage = [[UIImage alloc] initWithCGImage:tempImage.CGImage scale:scale orientation:tempImage.imageOrientation]; + [scaledImages addObject:tempScaledImage]; + } + + animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration]; + animatedImage.sd_imageLoopCount = image.sd_imageLoopCount; +#else + // Animated GIF for `NSImage` need to grab `NSBitmapImageRep`; + NSRect imageRect = NSMakeRect(0, 0, image.size.width, image.size.height); + NSImageRep *imageRep = [image bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (bitmapImageRep) { + NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale); + animatedImage = [[NSImage alloc] initWithSize:size]; + bitmapImageRep.size = size; + [animatedImage addRepresentation:bitmapImageRep]; + } +#endif + scaledImage = animatedImage; + } else { +#if SD_UIKIT || SD_WATCH + scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; +#else + scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:kCGImagePropertyOrientationUp]; +#endif + } + SDImageCopyAssociatedObject(image, scaledImage); + + return scaledImage; +} + +#pragma mark - Context option + +SDWebImageContextOption const SDWebImageContextSetImageOperationKey = @"setImageOperationKey"; +SDWebImageContextOption const SDWebImageContextCustomManager = @"customManager"; +SDWebImageContextOption const SDWebImageContextImageCache = @"imageCache"; +SDWebImageContextOption const SDWebImageContextImageLoader = @"imageLoader"; +SDWebImageContextOption const SDWebImageContextImageCoder = @"imageCoder"; +SDWebImageContextOption const SDWebImageContextImageTransformer = @"imageTransformer"; +SDWebImageContextOption const SDWebImageContextImageScaleFactor = @"imageScaleFactor"; +SDWebImageContextOption const SDWebImageContextImagePreserveAspectRatio = @"imagePreserveAspectRatio"; +SDWebImageContextOption const SDWebImageContextImageThumbnailPixelSize = @"imageThumbnailPixelSize"; +SDWebImageContextOption const SDWebImageContextQueryCacheType = @"queryCacheType"; +SDWebImageContextOption const SDWebImageContextStoreCacheType = @"storeCacheType"; +SDWebImageContextOption const SDWebImageContextOriginalQueryCacheType = @"originalQueryCacheType"; +SDWebImageContextOption const SDWebImageContextOriginalStoreCacheType = @"originalStoreCacheType"; +SDWebImageContextOption const SDWebImageContextOriginalImageCache = @"originalImageCache"; +SDWebImageContextOption const SDWebImageContextAnimatedImageClass = @"animatedImageClass"; +SDWebImageContextOption const SDWebImageContextDownloadRequestModifier = @"downloadRequestModifier"; +SDWebImageContextOption const SDWebImageContextDownloadResponseModifier = @"downloadResponseModifier"; +SDWebImageContextOption const SDWebImageContextDownloadDecryptor = @"downloadDecryptor"; +SDWebImageContextOption const SDWebImageContextCacheKeyFilter = @"cacheKeyFilter"; +SDWebImageContextOption const SDWebImageContextCacheSerializer = @"cacheSerializer"; diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.h new file mode 100644 index 00000000..a2f50f46 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.h @@ -0,0 +1,314 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" +#import "SDWebImageOperation.h" +#import "SDWebImageDownloaderConfig.h" +#import "SDWebImageDownloaderRequestModifier.h" +#import "SDWebImageDownloaderResponseModifier.h" +#import "SDWebImageDownloaderDecryptor.h" +#import "SDImageLoader.h" + +/// Downloader options +typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) { + /** + * Put the download in the low queue priority and task priority. + */ + SDWebImageDownloaderLowPriority = 1 << 0, + + /** + * This flag enables progressive download, the image is displayed progressively during download as a browser would do. + */ + SDWebImageDownloaderProgressiveLoad = 1 << 1, + + /** + * By default, request prevent the use of NSURLCache. With this flag, NSURLCache + * is used with default policies. + */ + SDWebImageDownloaderUseNSURLCache = 1 << 2, + + /** + * Call completion block with nil image/imageData if the image was read from NSURLCache + * And the error code is `SDWebImageErrorCacheNotModified` + * This flag should be combined with `SDWebImageDownloaderUseNSURLCache`. + */ + SDWebImageDownloaderIgnoreCachedResponse = 1 << 3, + + /** + * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for + * extra time in background to let the request finish. If the background task expires the operation will be cancelled. + */ + SDWebImageDownloaderContinueInBackground = 1 << 4, + + /** + * Handles cookies stored in NSHTTPCookieStore by setting + * NSMutableURLRequest.HTTPShouldHandleCookies = YES; + */ + SDWebImageDownloaderHandleCookies = 1 << 5, + + /** + * Enable to allow untrusted SSL certificates. + * Useful for testing purposes. Use with caution in production. + */ + SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6, + + /** + * Put the download in the high queue priority and task priority. + */ + SDWebImageDownloaderHighPriority = 1 << 7, + + /** + * By default, images are decoded respecting their original size. On iOS, this flag will scale down the + * images to a size compatible with the constrained memory of devices. + * This flag take no effect if `SDWebImageDownloaderAvoidDecodeImage` is set. And it will be ignored if `SDWebImageDownloaderProgressiveLoad` is set. + */ + SDWebImageDownloaderScaleDownLargeImages = 1 << 8, + + /** + * By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation. + * However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image. + */ + SDWebImageDownloaderAvoidDecodeImage = 1 << 9, + + /** + * By default, we decode the animated image. This flag can force decode the first frame only and produce the static image. + */ + SDWebImageDownloaderDecodeFirstFrameOnly = 1 << 10, + + /** + * By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from network + */ + SDWebImageDownloaderPreloadAllFrames = 1 << 11, + + /** + * By default, when you use `SDWebImageContextAnimatedImageClass` context option (like using `SDAnimatedImageView` which designed to use `SDAnimatedImage`), we may still use `UIImage` when the memory cache hit, or image decoder is not available, to behave as a fallback solution. + * Using this option, can ensure we always produce image with your provided class. If failed, a error with code `SDWebImageErrorBadImageData` will been used. + * Note this options is not compatible with `SDWebImageDownloaderDecodeFirstFrameOnly`, which always produce a UIImage/NSImage. + */ + SDWebImageDownloaderMatchAnimatedImageClass = 1 << 12, +}; + +FOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadStartNotification; +FOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadReceiveResponseNotification; +FOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadStopNotification; +FOUNDATION_EXPORT NSNotificationName _Nonnull const SDWebImageDownloadFinishNotification; + +typedef SDImageLoaderProgressBlock SDWebImageDownloaderProgressBlock; +typedef SDImageLoaderCompletedBlock SDWebImageDownloaderCompletedBlock; + +/** + * A token associated with each download. Can be used to cancel a download + */ +@interface SDWebImageDownloadToken : NSObject + +/** + Cancel the current download. + */ +- (void)cancel; + +/** + The download's URL. + */ +@property (nonatomic, strong, nullable, readonly) NSURL *url; + +/** + The download's request. + */ +@property (nonatomic, strong, nullable, readonly) NSURLRequest *request; + +/** + The download's response. + */ +@property (nonatomic, strong, nullable, readonly) NSURLResponse *response; + +/** + The download's metrics. This will be nil if download operation does not support metrics. + */ +@property (nonatomic, strong, nullable, readonly) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +@end + + +/** + * Asynchronous downloader dedicated and optimized for image loading. + */ +@interface SDWebImageDownloader : NSObject + +/** + * Downloader Config object - storing all kind of settings. + * Most config properties support dynamic changes during download, except something like `sessionConfiguration`, see `SDWebImageDownloaderConfig` for more detail. + */ +@property (nonatomic, copy, readonly, nonnull) SDWebImageDownloaderConfig *config; + +/** + * Set the request modifier to modify the original download request before image load. + * This request modifier method will be called for each downloading image request. Return the original request means no modification. Return nil will cancel the download request. + * Defaults to nil, means does not modify the original download request. + * @note If you want to modify single request, consider using `SDWebImageContextDownloadRequestModifier` context option. + */ +@property (nonatomic, strong, nullable) id requestModifier; + +/** + * Set the response modifier to modify the original download response during image load. + * This response modifier method will be called for each downloading image response. Return the original response means no modification. Return nil will mark current download as cancelled. + * Defaults to nil, means does not modify the original download response. + * @note If you want to modify single response, consider using `SDWebImageContextDownloadResponseModifier` context option. + */ +@property (nonatomic, strong, nullable) id responseModifier; + +/** + * Set the decryptor to decrypt the original download data before image decoding. This can be used for encrypted image data, like Base64. + * This decryptor method will be called for each downloading image data. Return the original data means no modification. Return nil will mark this download failed. + * Defaults to nil, means does not modify the original download data. + * @note When using decryptor, progressive decoding will be disabled, to avoid data corrupt issue. + * @note If you want to decrypt single download data, consider using `SDWebImageContextDownloadDecryptor` context option. + */ +@property (nonatomic, strong, nullable) id decryptor; + +/** + * The configuration in use by the internal NSURLSession. If you want to provide a custom sessionConfiguration, use `SDWebImageDownloaderConfig.sessionConfiguration` and create a new downloader instance. + @note This is immutable according to NSURLSession's documentation. Mutating this object directly has no effect. + */ +@property (nonatomic, readonly, nonnull) NSURLSessionConfiguration *sessionConfiguration; + +/** + * Gets/Sets the download queue suspension state. + */ +@property (nonatomic, assign, getter=isSuspended) BOOL suspended; + +/** + * Shows the current amount of downloads that still need to be downloaded + */ +@property (nonatomic, assign, readonly) NSUInteger currentDownloadCount; + +/** + * Returns the global shared downloader instance. Which use the `SDWebImageDownloaderConfig.defaultDownloaderConfig` config. + */ +@property (nonatomic, class, readonly, nonnull) SDWebImageDownloader *sharedDownloader; + +/** + Creates an instance of a downloader with specified downloader config. + You can specify session configuration, timeout or operation class through downloader config. + + @param config The downloader config. If you specify nil, the `defaultDownloaderConfig` will be used. + @return new instance of downloader class + */ +- (nonnull instancetype)initWithConfig:(nullable SDWebImageDownloaderConfig *)config NS_DESIGNATED_INITIALIZER; + +/** + * Set a value for a HTTP header to be appended to each download HTTP request. + * + * @param value The value for the header field. Use `nil` value to remove the header field. + * @param field The name of the header field to set. + */ +- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field; + +/** + * Returns the value of the specified HTTP header field. + * + * @return The value associated with the header field field, or `nil` if there is no corresponding header field. + */ +- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field; + +/** + * Creates a SDWebImageDownloader async downloader instance with a given URL + * + * The delegate will be informed when the image is finish downloaded or an error has happen. + * + * @see SDWebImageDownloaderDelegate + * + * @param url The URL to the image to download + * @param completedBlock A block called once the download is completed. + * If the download succeeded, the image parameter is set, in case of error, + * error parameter is set with the error. The last parameter is always YES + * if SDWebImageDownloaderProgressiveDownload isn't use. With the + * SDWebImageDownloaderProgressiveDownload option, this block is called + * repeatedly with the partial image object and the finished argument set to NO + * before to be called a last time with the full image and finished argument + * set to YES. In case of error, the finished argument is always YES. + * + * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation + */ +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; + +/** + * Creates a SDWebImageDownloader async downloader instance with a given URL + * + * The delegate will be informed when the image is finish downloaded or an error has happen. + * + * @see SDWebImageDownloaderDelegate + * + * @param url The URL to the image to download + * @param options The options to be used for this download + * @param progressBlock A block called repeatedly while the image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called once the download is completed. + * If the download succeeded, the image parameter is set, in case of error, + * error parameter is set with the error. The last parameter is always YES + * if SDWebImageDownloaderProgressiveLoad isn't use. With the + * SDWebImageDownloaderProgressiveLoad option, this block is called + * repeatedly with the partial image object and the finished argument set to NO + * before to be called a last time with the full image and finished argument + * set to YES. In case of error, the finished argument is always YES. + * + * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation + */ +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url + options:(SDWebImageDownloaderOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; + +/** + * Creates a SDWebImageDownloader async downloader instance with a given URL + * + * The delegate will be informed when the image is finish downloaded or an error has happen. + * + * @see SDWebImageDownloaderDelegate + * + * @param url The URL to the image to download + * @param options The options to be used for this download + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called repeatedly while the image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called once the download is completed. + * + * @return A token (SDWebImageDownloadToken) that can be used to cancel this operation + */ +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; + +/** + * Cancels all download operations in the queue + */ +- (void)cancelAllDownloads; + +/** + * Invalidates the managed session, optionally canceling pending operations. + * @note If you use custom downloader instead of the shared downloader, you need call this method when you do not use it to avoid memory leak + * @param cancelPendingOperations Whether or not to cancel pending operations. + * @note Calling this method on the shared downloader has no effect. + */ +- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations; + +@end + + +/** + SDWebImageDownloader is the built-in image loader conform to `SDImageLoader`. Which provide the HTTP/HTTPS/FTP download, or local file URL using NSURLSession. + However, this downloader class itself also support customization for advanced users. You can specify `operationClass` in download config to custom download operation, See `SDWebImageDownloaderOperation`. + If you want to provide some image loader which beyond network or local file, consider to create your own custom class conform to `SDImageLoader`. + */ +@interface SDWebImageDownloader (SDImageLoader) + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.m new file mode 100644 index 00000000..cd6b7966 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloader.m @@ -0,0 +1,637 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloader.h" +#import "SDWebImageDownloaderConfig.h" +#import "SDWebImageDownloaderOperation.h" +#import "SDWebImageError.h" +#import "SDInternalMacros.h" + +NSNotificationName const SDWebImageDownloadStartNotification = @"SDWebImageDownloadStartNotification"; +NSNotificationName const SDWebImageDownloadReceiveResponseNotification = @"SDWebImageDownloadReceiveResponseNotification"; +NSNotificationName const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification"; +NSNotificationName const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinishNotification"; + +static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext; + +@interface SDWebImageDownloadToken () + +@property (nonatomic, strong, nullable, readwrite) NSURL *url; +@property (nonatomic, strong, nullable, readwrite) NSURLRequest *request; +@property (nonatomic, strong, nullable, readwrite) NSURLResponse *response; +@property (nonatomic, strong, nullable, readwrite) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); +@property (nonatomic, weak, nullable, readwrite) id downloadOperationCancelToken; +@property (nonatomic, weak, nullable) NSOperation *downloadOperation; +@property (nonatomic, assign, getter=isCancelled) BOOL cancelled; + +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +- (nonnull instancetype)initWithDownloadOperation:(nullable NSOperation *)downloadOperation; + +@end + +@interface SDWebImageDownloader () + +@property (strong, nonatomic, nonnull) NSOperationQueue *downloadQueue; +@property (strong, nonatomic, nonnull) NSMutableDictionary *> *URLOperations; +@property (strong, nonatomic, nullable) NSMutableDictionary *HTTPHeaders; + +// The session in which data tasks will run +@property (strong, nonatomic) NSURLSession *session; + +@end + +@implementation SDWebImageDownloader { + SD_LOCK_DECLARE(_HTTPHeadersLock); // A lock to keep the access to `HTTPHeaders` thread-safe + SD_LOCK_DECLARE(_operationsLock); // A lock to keep the access to `URLOperations` thread-safe +} + ++ (void)initialize { + // Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator ) + // To use it, just add #import "SDNetworkActivityIndicator.h" in addition to the SDWebImage import + if (NSClassFromString(@"SDNetworkActivityIndicator")) { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id activityIndicator = [NSClassFromString(@"SDNetworkActivityIndicator") performSelector:NSSelectorFromString(@"sharedActivityIndicator")]; +#pragma clang diagnostic pop + + // Remove observer in case it was previously added. + [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStartNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStopNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:activityIndicator + selector:NSSelectorFromString(@"startActivity") + name:SDWebImageDownloadStartNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:activityIndicator + selector:NSSelectorFromString(@"stopActivity") + name:SDWebImageDownloadStopNotification object:nil]; + } +} + ++ (nonnull instancetype)sharedDownloader { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (nonnull instancetype)init { + return [self initWithConfig:SDWebImageDownloaderConfig.defaultDownloaderConfig]; +} + +- (instancetype)initWithConfig:(SDWebImageDownloaderConfig *)config { + self = [super init]; + if (self) { + if (!config) { + config = SDWebImageDownloaderConfig.defaultDownloaderConfig; + } + _config = [config copy]; + [_config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) options:0 context:SDWebImageDownloaderContext]; + _downloadQueue = [NSOperationQueue new]; + _downloadQueue.maxConcurrentOperationCount = _config.maxConcurrentDownloads; + _downloadQueue.name = @"com.hackemist.SDWebImageDownloader"; + _URLOperations = [NSMutableDictionary new]; + NSMutableDictionary *headerDictionary = [NSMutableDictionary dictionary]; + NSString *userAgent = nil; +#if SD_UIKIT + // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 + userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]]; +#elif SD_WATCH + // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 + userAgent = [NSString stringWithFormat:@"%@/%@ (%@; watchOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[WKInterfaceDevice currentDevice] model], [[WKInterfaceDevice currentDevice] systemVersion], [[WKInterfaceDevice currentDevice] screenScale]]; +#elif SD_MAC + userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]; +#endif + if (userAgent) { + if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { + NSMutableString *mutableUserAgent = [userAgent mutableCopy]; + if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) { + userAgent = mutableUserAgent; + } + } + headerDictionary[@"User-Agent"] = userAgent; + } + headerDictionary[@"Accept"] = @"image/*,*/*;q=0.8"; + _HTTPHeaders = headerDictionary; + SD_LOCK_INIT(_HTTPHeadersLock); + SD_LOCK_INIT(_operationsLock); + NSURLSessionConfiguration *sessionConfiguration = _config.sessionConfiguration; + if (!sessionConfiguration) { + sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + } + /** + * Create the session for this task + * We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate + * method calls and completion handler calls. + */ + _session = [NSURLSession sessionWithConfiguration:sessionConfiguration + delegate:self + delegateQueue:nil]; + } + return self; +} + +- (void)dealloc { + [self.downloadQueue cancelAllOperations]; + [self.config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) context:SDWebImageDownloaderContext]; + + // Invalide the URLSession after all operations been cancelled + [self.session invalidateAndCancel]; + self.session = nil; +} + +- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations { + if (self == [SDWebImageDownloader sharedDownloader]) { + return; + } + if (cancelPendingOperations) { + [self.session invalidateAndCancel]; + } else { + [self.session finishTasksAndInvalidate]; + } +} + +- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field { + if (!field) { + return; + } + SD_LOCK(_HTTPHeadersLock); + [self.HTTPHeaders setValue:value forKey:field]; + SD_UNLOCK(_HTTPHeadersLock); +} + +- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field { + if (!field) { + return nil; + } + SD_LOCK(_HTTPHeadersLock); + NSString *value = [self.HTTPHeaders objectForKey:field]; + SD_UNLOCK(_HTTPHeadersLock); + return value; +} + +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url + completed:(SDWebImageDownloaderCompletedBlock)completedBlock { + return [self downloadImageWithURL:url options:0 progress:nil completed:completedBlock]; +} + +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock { + return [self downloadImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock { + // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. + if (url == nil) { + if (completedBlock) { + NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Image url is nil"}]; + completedBlock(nil, nil, error, YES); + } + return nil; + } + + SD_LOCK(_operationsLock); + id downloadOperationCancelToken; + NSOperation *operation = [self.URLOperations objectForKey:url]; + // There is a case that the operation may be marked as finished or cancelled, but not been removed from `self.URLOperations`. + if (!operation || operation.isFinished || operation.isCancelled) { + operation = [self createDownloaderOperationWithUrl:url options:options context:context]; + if (!operation) { + SD_UNLOCK(_operationsLock); + if (completedBlock) { + NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @"Downloader operation is nil"}]; + completedBlock(nil, nil, error, YES); + } + return nil; + } + @weakify(self); + operation.completionBlock = ^{ + @strongify(self); + if (!self) { + return; + } + SD_LOCK(self->_operationsLock); + [self.URLOperations removeObjectForKey:url]; + SD_UNLOCK(self->_operationsLock); + }; + self.URLOperations[url] = operation; + // Add the handlers before submitting to operation queue, avoid the race condition that operation finished before setting handlers. + downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock]; + // Add operation to operation queue only after all configuration done according to Apple's doc. + // `addOperation:` does not synchronously execute the `operation.completionBlock` so this will not cause deadlock. + [self.downloadQueue addOperation:operation]; + } else { + // When we reuse the download operation to attach more callbacks, there may be thread safe issue because the getter of callbacks may in another queue (decoding queue or delegate queue) + // So we lock the operation here, and in `SDWebImageDownloaderOperation`, we use `@synchonzied (self)`, to ensure the thread safe between these two classes. + @synchronized (operation) { + downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock]; + } + if (!operation.isExecuting) { + if (options & SDWebImageDownloaderHighPriority) { + operation.queuePriority = NSOperationQueuePriorityHigh; + } else if (options & SDWebImageDownloaderLowPriority) { + operation.queuePriority = NSOperationQueuePriorityLow; + } else { + operation.queuePriority = NSOperationQueuePriorityNormal; + } + } + } + SD_UNLOCK(_operationsLock); + + SDWebImageDownloadToken *token = [[SDWebImageDownloadToken alloc] initWithDownloadOperation:operation]; + token.url = url; + token.request = operation.request; + token.downloadOperationCancelToken = downloadOperationCancelToken; + + return token; +} + +- (nullable NSOperation *)createDownloaderOperationWithUrl:(nonnull NSURL *)url + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context { + NSTimeInterval timeoutInterval = self.config.downloadTimeout; + if (timeoutInterval == 0.0) { + timeoutInterval = 15.0; + } + + // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise + NSURLRequestCachePolicy cachePolicy = options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData; + NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:cachePolicy timeoutInterval:timeoutInterval]; + mutableRequest.HTTPShouldHandleCookies = SD_OPTIONS_CONTAINS(options, SDWebImageDownloaderHandleCookies); + mutableRequest.HTTPShouldUsePipelining = YES; + SD_LOCK(_HTTPHeadersLock); + mutableRequest.allHTTPHeaderFields = self.HTTPHeaders; + SD_UNLOCK(_HTTPHeadersLock); + + // Context Option + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + + // Request Modifier + id requestModifier; + if ([context valueForKey:SDWebImageContextDownloadRequestModifier]) { + requestModifier = [context valueForKey:SDWebImageContextDownloadRequestModifier]; + } else { + requestModifier = self.requestModifier; + } + + NSURLRequest *request; + if (requestModifier) { + NSURLRequest *modifiedRequest = [requestModifier modifiedRequestWithRequest:[mutableRequest copy]]; + // If modified request is nil, early return + if (!modifiedRequest) { + return nil; + } else { + request = [modifiedRequest copy]; + } + } else { + request = [mutableRequest copy]; + } + // Response Modifier + id responseModifier; + if ([context valueForKey:SDWebImageContextDownloadResponseModifier]) { + responseModifier = [context valueForKey:SDWebImageContextDownloadResponseModifier]; + } else { + responseModifier = self.responseModifier; + } + if (responseModifier) { + mutableContext[SDWebImageContextDownloadResponseModifier] = responseModifier; + } + // Decryptor + id decryptor; + if ([context valueForKey:SDWebImageContextDownloadDecryptor]) { + decryptor = [context valueForKey:SDWebImageContextDownloadDecryptor]; + } else { + decryptor = self.decryptor; + } + if (decryptor) { + mutableContext[SDWebImageContextDownloadDecryptor] = decryptor; + } + + context = [mutableContext copy]; + + // Operation Class + Class operationClass = self.config.operationClass; + if (operationClass && [operationClass isSubclassOfClass:[NSOperation class]] && [operationClass conformsToProtocol:@protocol(SDWebImageDownloaderOperation)]) { + // Custom operation class + } else { + operationClass = [SDWebImageDownloaderOperation class]; + } + NSOperation *operation = [[operationClass alloc] initWithRequest:request inSession:self.session options:options context:context]; + + if ([operation respondsToSelector:@selector(setCredential:)]) { + if (self.config.urlCredential) { + operation.credential = self.config.urlCredential; + } else if (self.config.username && self.config.password) { + operation.credential = [NSURLCredential credentialWithUser:self.config.username password:self.config.password persistence:NSURLCredentialPersistenceForSession]; + } + } + + if ([operation respondsToSelector:@selector(setMinimumProgressInterval:)]) { + operation.minimumProgressInterval = MIN(MAX(self.config.minimumProgressInterval, 0), 1); + } + + if ([operation respondsToSelector:@selector(setAcceptableStatusCodes:)]) { + operation.acceptableStatusCodes = self.config.acceptableStatusCodes; + } + + if ([operation respondsToSelector:@selector(setAcceptableContentTypes:)]) { + operation.acceptableContentTypes = self.config.acceptableContentTypes; + } + + if (options & SDWebImageDownloaderHighPriority) { + operation.queuePriority = NSOperationQueuePriorityHigh; + } else if (options & SDWebImageDownloaderLowPriority) { + operation.queuePriority = NSOperationQueuePriorityLow; + } + + if (self.config.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) { + // Emulate LIFO execution order by systematically, each previous adding operation can dependency the new operation + // This can gurantee the new operation to be execulated firstly, even if when some operations finished, meanwhile you appending new operations + // Just make last added operation dependents new operation can not solve this problem. See test case #test15DownloaderLIFOExecutionOrder + for (NSOperation *pendingOperation in self.downloadQueue.operations) { + [pendingOperation addDependency:operation]; + } + } + + return operation; +} + +- (void)cancelAllDownloads { + [self.downloadQueue cancelAllOperations]; +} + +#pragma mark - Properties + +- (BOOL)isSuspended { + return self.downloadQueue.isSuspended; +} + +- (void)setSuspended:(BOOL)suspended { + self.downloadQueue.suspended = suspended; +} + +- (NSUInteger)currentDownloadCount { + return self.downloadQueue.operationCount; +} + +- (NSURLSessionConfiguration *)sessionConfiguration { + return self.session.configuration; +} + +#pragma mark - KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if (context == SDWebImageDownloaderContext) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxConcurrentDownloads))]) { + self.downloadQueue.maxConcurrentOperationCount = self.config.maxConcurrentDownloads; + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark Helper methods + +- (NSOperation *)operationWithTask:(NSURLSessionTask *)task { + NSOperation *returnOperation = nil; + for (NSOperation *operation in self.downloadQueue.operations) { + if ([operation respondsToSelector:@selector(dataTask)]) { + // So we lock the operation here, and in `SDWebImageDownloaderOperation`, we use `@synchonzied (self)`, to ensure the thread safe between these two classes. + NSURLSessionTask *operationTask; + @synchronized (operation) { + operationTask = operation.dataTask; + } + if (operationTask.taskIdentifier == task.taskIdentifier) { + returnOperation = operation; + break; + } + } + } + return returnOperation; +} + +#pragma mark NSURLSessionDataDelegate + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask +didReceiveResponse:(NSURLResponse *)response + completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:dataTask]; + if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:didReceiveResponse:completionHandler:)]) { + [dataOperation URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler]; + } else { + if (completionHandler) { + completionHandler(NSURLSessionResponseAllow); + } + } +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:dataTask]; + if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:didReceiveData:)]) { + [dataOperation URLSession:session dataTask:dataTask didReceiveData:data]; + } +} + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + willCacheResponse:(NSCachedURLResponse *)proposedResponse + completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:dataTask]; + if ([dataOperation respondsToSelector:@selector(URLSession:dataTask:willCacheResponse:completionHandler:)]) { + [dataOperation URLSession:session dataTask:dataTask willCacheResponse:proposedResponse completionHandler:completionHandler]; + } else { + if (completionHandler) { + completionHandler(proposedResponse); + } + } +} + +#pragma mark NSURLSessionTaskDelegate + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:task]; + if ([dataOperation respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]) { + [dataOperation URLSession:session task:task didCompleteWithError:error]; + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:task]; + if ([dataOperation respondsToSelector:@selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)]) { + [dataOperation URLSession:session task:task willPerformHTTPRedirection:response newRequest:request completionHandler:completionHandler]; + } else { + if (completionHandler) { + completionHandler(request); + } + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:task]; + if ([dataOperation respondsToSelector:@selector(URLSession:task:didReceiveChallenge:completionHandler:)]) { + [dataOperation URLSession:session task:task didReceiveChallenge:challenge completionHandler:completionHandler]; + } else { + if (completionHandler) { + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + } + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { + + // Identify the operation that runs this task and pass it the delegate method + NSOperation *dataOperation = [self operationWithTask:task]; + if ([dataOperation respondsToSelector:@selector(URLSession:task:didFinishCollectingMetrics:)]) { + [dataOperation URLSession:session task:task didFinishCollectingMetrics:metrics]; + } +} + +@end + +@implementation SDWebImageDownloadToken + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:SDWebImageDownloadReceiveResponseNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:SDWebImageDownloadStopNotification object:nil]; +} + +- (instancetype)initWithDownloadOperation:(NSOperation *)downloadOperation { + self = [super init]; + if (self) { + _downloadOperation = downloadOperation; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidReceiveResponse:) name:SDWebImageDownloadReceiveResponseNotification object:downloadOperation]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidStop:) name:SDWebImageDownloadStopNotification object:downloadOperation]; + } + return self; +} + +- (void)downloadDidReceiveResponse:(NSNotification *)notification { + NSOperation *downloadOperation = notification.object; + if (downloadOperation && downloadOperation == self.downloadOperation) { + self.response = downloadOperation.response; + } +} + +- (void)downloadDidStop:(NSNotification *)notification { + NSOperation *downloadOperation = notification.object; + if (downloadOperation && downloadOperation == self.downloadOperation) { + if ([downloadOperation respondsToSelector:@selector(metrics)]) { + if (@available(iOS 10.0, tvOS 10.0, macOS 10.12, watchOS 3.0, *)) { + self.metrics = downloadOperation.metrics; + } + } + } +} + +- (void)cancel { + @synchronized (self) { + if (self.isCancelled) { + return; + } + self.cancelled = YES; + [self.downloadOperation cancel:self.downloadOperationCancelToken]; + self.downloadOperationCancelToken = nil; + } +} + +@end + +@implementation SDWebImageDownloader (SDImageLoader) + +- (BOOL)canRequestImageForURL:(NSURL *)url { + return [self canRequestImageForURL:url options:0 context:nil]; +} + +- (BOOL)canRequestImageForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context { + if (!url) { + return NO; + } + // Always pass YES to let URLSession or custom download operation to determine + return YES; +} + +- (id)requestImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock { + UIImage *cachedImage = context[SDWebImageContextLoaderCachedImage]; + + SDWebImageDownloaderOptions downloaderOptions = 0; + if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority; + if (options & SDWebImageProgressiveLoad) downloaderOptions |= SDWebImageDownloaderProgressiveLoad; + if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache; + if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground; + if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies; + if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates; + if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority; + if (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages; + if (options & SDWebImageAvoidDecodeImage) downloaderOptions |= SDWebImageDownloaderAvoidDecodeImage; + if (options & SDWebImageDecodeFirstFrameOnly) downloaderOptions |= SDWebImageDownloaderDecodeFirstFrameOnly; + if (options & SDWebImagePreloadAllFrames) downloaderOptions |= SDWebImageDownloaderPreloadAllFrames; + if (options & SDWebImageMatchAnimatedImageClass) downloaderOptions |= SDWebImageDownloaderMatchAnimatedImageClass; + + if (cachedImage && options & SDWebImageRefreshCached) { + // force progressive off if image already cached but forced refreshing + downloaderOptions &= ~SDWebImageDownloaderProgressiveLoad; + // ignore image read from NSURLCache if image if cached but force refreshing + downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; + } + + return [self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock]; +} + +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + return [self shouldBlockFailedURLWithURL:url error:error options:0 context:nil]; +} + +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error options:(SDWebImageOptions)options context:(SDWebImageContext *)context { + BOOL shouldBlockFailedURL; + // Filter the error domain and check error codes + if ([error.domain isEqualToString:SDWebImageErrorDomain]) { + shouldBlockFailedURL = ( error.code == SDWebImageErrorInvalidURL + || error.code == SDWebImageErrorBadImageData); + } else if ([error.domain isEqualToString:NSURLErrorDomain]) { + shouldBlockFailedURL = ( error.code != NSURLErrorNotConnectedToInternet + && error.code != NSURLErrorCancelled + && error.code != NSURLErrorTimedOut + && error.code != NSURLErrorInternationalRoamingOff + && error.code != NSURLErrorDataNotAllowed + && error.code != NSURLErrorCannotFindHost + && error.code != NSURLErrorCannotConnectToHost + && error.code != NSURLErrorNetworkConnectionLost); + } else { + shouldBlockFailedURL = NO; + } + return shouldBlockFailedURL; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.h new file mode 100644 index 00000000..9d5e67bf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.h @@ -0,0 +1,113 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/// Operation execution order +typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) { + /** + * Default value. All download operations will execute in queue style (first-in-first-out). + */ + SDWebImageDownloaderFIFOExecutionOrder, + + /** + * All download operations will execute in stack style (last-in-first-out). + */ + SDWebImageDownloaderLIFOExecutionOrder +}; + +/** + The class contains all the config for image downloader + @note This class conform to NSCopying, make sure to add the property in `copyWithZone:` as well. + */ +@interface SDWebImageDownloaderConfig : NSObject + +/** + Gets the default downloader config used for shared instance or initialization when it does not provide any downloader config. Such as `SDWebImageDownloader.sharedDownloader`. + @note You can modify the property on default downloader config, which can be used for later created downloader instance. The already created downloader instance does not get affected. + */ +@property (nonatomic, class, readonly, nonnull) SDWebImageDownloaderConfig *defaultDownloaderConfig; + +/** + * The maximum number of concurrent downloads. + * Defaults to 6. + */ +@property (nonatomic, assign) NSInteger maxConcurrentDownloads; + +/** + * The timeout value (in seconds) for each download operation. + * Defaults to 15.0. + */ +@property (nonatomic, assign) NSTimeInterval downloadTimeout; + +/** + * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected. + * The value should be 0.0-1.0. + * @note If you're using progressive decoding feature, this will also effect the image refresh rate. + * @note This value may enhance the performance if you don't want progress callback too frequently. + * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately. + */ +@property (nonatomic, assign) double minimumProgressInterval; + +/** + * The custom session configuration in use by NSURLSession. If you don't provide one, we will use `defaultSessionConfiguration` instead. + * Defatuls to nil. + * @note This property does not support dynamic changes, means it's immutable after the downloader instance initialized. + */ +@property (nonatomic, strong, nullable) NSURLSessionConfiguration *sessionConfiguration; + +/** + * Gets/Sets a subclass of `SDWebImageDownloaderOperation` as the default + * `NSOperation` to be used each time SDWebImage constructs a request + * operation to download an image. + * Defaults to nil. + * @note Passing `NSOperation` to set as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`. + */ +@property (nonatomic, assign, nullable) Class operationClass; + +/** + * Changes download operations execution order. + * Defaults to `SDWebImageDownloaderFIFOExecutionOrder`. + */ +@property (nonatomic, assign) SDWebImageDownloaderExecutionOrder executionOrder; + +/** + * Set the default URL credential to be set for request operations. + * Defaults to nil. + */ +@property (nonatomic, copy, nullable) NSURLCredential *urlCredential; + +/** + * Set username using for HTTP Basic authentication. + * Defaults to nil. + */ +@property (nonatomic, copy, nullable) NSString *username; + +/** + * Set password using for HTTP Basic authentication. + * Defaults to nil. + */ +@property (nonatomic, copy, nullable) NSString *password; + +/** + * Set the acceptable HTTP Response status code. The status code which beyond the range will mark the download operation failed. + * For example, if we config [200, 400) but server response is 503, the download will fail with error code `SDWebImageErrorInvalidDownloadStatusCode`. + * Defaults to [200,400). Nil means no validation at all. + */ +@property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes; + +/** + * Set the acceptable HTTP Response content type. The content type beyond the set will mark the download operation failed. + * For example, if we config ["image/png"] but server response is "application/json", the download will fail with error code `SDWebImageErrorInvalidDownloadContentType`. + * Normally you don't need this for image format detection because we use image's data file signature magic bytes: https://en.wikipedia.org/wiki/List_of_file_signatures + * Defaults to nil. Nil means no validation at all. + */ +@property (nonatomic, copy, nullable) NSSet *acceptableContentTypes; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.m new file mode 100644 index 00000000..6120bd8a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderConfig.m @@ -0,0 +1,52 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloaderConfig.h" + +static SDWebImageDownloaderConfig * _defaultDownloaderConfig; + +@implementation SDWebImageDownloaderConfig + ++ (SDWebImageDownloaderConfig *)defaultDownloaderConfig { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _defaultDownloaderConfig = [SDWebImageDownloaderConfig new]; + }); + return _defaultDownloaderConfig; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _maxConcurrentDownloads = 6; + _downloadTimeout = 15.0; + _executionOrder = SDWebImageDownloaderFIFOExecutionOrder; + _acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + SDWebImageDownloaderConfig *config = [[[self class] allocWithZone:zone] init]; + config.maxConcurrentDownloads = self.maxConcurrentDownloads; + config.downloadTimeout = self.downloadTimeout; + config.minimumProgressInterval = self.minimumProgressInterval; + config.sessionConfiguration = [self.sessionConfiguration copyWithZone:zone]; + config.operationClass = self.operationClass; + config.executionOrder = self.executionOrder; + config.urlCredential = self.urlCredential; + config.username = self.username; + config.password = self.password; + config.acceptableStatusCodes = self.acceptableStatusCodes; + config.acceptableContentTypes = self.acceptableContentTypes; + + return config; +} + + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.h new file mode 100644 index 00000000..0923f297 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.h @@ -0,0 +1,49 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" + +typedef NSData * _Nullable (^SDWebImageDownloaderDecryptorBlock)(NSData * _Nonnull data, NSURLResponse * _Nullable response); + +/** +This is the protocol for downloader decryptor. Which decrypt the original encrypted data before decoding. Note progressive decoding is not compatible for decryptor. +We can use a block to specify the downloader decryptor. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. +*/ +@protocol SDWebImageDownloaderDecryptor + +/// Decrypt the original download data and return a new data. You can use this to decrypt the data using your preferred algorithm. +/// @param data The original download data +/// @param response The URL response for data. If you modify the original URL response via response modifier, the modified version will be here. This arg is nullable. +/// @note If nil is returned, the image download will be marked as failed with error `SDWebImageErrorBadImageData` +- (nullable NSData *)decryptedDataWithData:(nonnull NSData *)data response:(nullable NSURLResponse *)response; + +@end + +/** +A downloader response modifier class with block. +*/ +@interface SDWebImageDownloaderDecryptor : NSObject + +/// Create the data decryptor with block +/// @param block A block to control decrypt logic +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderDecryptorBlock)block; + +/// Create the data decryptor with block +/// @param block A block to control decrypt logic ++ (nonnull instancetype)decryptorWithBlock:(nonnull SDWebImageDownloaderDecryptorBlock)block; + +@end + +/// Convenience way to create decryptor for common data encryption. +@interface SDWebImageDownloaderDecryptor (Conveniences) + +/// Base64 Encoded image data decryptor +@property (class, readonly, nonnull) SDWebImageDownloaderDecryptor *base64Decryptor; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.m new file mode 100644 index 00000000..a3b75b26 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderDecryptor.m @@ -0,0 +1,55 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDWebImageDownloaderDecryptor.h" + +@interface SDWebImageDownloaderDecryptor () + +@property (nonatomic, copy, nonnull) SDWebImageDownloaderDecryptorBlock block; + +@end + +@implementation SDWebImageDownloaderDecryptor + +- (instancetype)initWithBlock:(SDWebImageDownloaderDecryptorBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)decryptorWithBlock:(SDWebImageDownloaderDecryptorBlock)block { + SDWebImageDownloaderDecryptor *decryptor = [[SDWebImageDownloaderDecryptor alloc] initWithBlock:block]; + return decryptor; +} + +- (nullable NSData *)decryptedDataWithData:(nonnull NSData *)data response:(nullable NSURLResponse *)response { + if (!self.block) { + return nil; + } + return self.block(data, response); +} + +@end + +@implementation SDWebImageDownloaderDecryptor (Conveniences) + ++ (SDWebImageDownloaderDecryptor *)base64Decryptor { + static SDWebImageDownloaderDecryptor *decryptor; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + decryptor = [SDWebImageDownloaderDecryptor decryptorWithBlock:^NSData * _Nullable(NSData * _Nonnull data, NSURLResponse * _Nullable response) { + NSData *modifiedData = [[NSData alloc] initWithBase64EncodedData:data options:NSDataBase64DecodingIgnoreUnknownCharacters]; + return modifiedData; + }]; + }); + return decryptor; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.h new file mode 100644 index 00000000..1cd2a50d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.h @@ -0,0 +1,172 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageDownloader.h" +#import "SDWebImageOperation.h" + +/** + Describes a downloader operation. If one wants to use a custom downloader op, it needs to inherit from `NSOperation` and conform to this protocol + For the description about these methods, see `SDWebImageDownloaderOperation` + @note If your custom operation class does not use `NSURLSession` at all, do not implement the optional methods and session delegate methods. + */ +@protocol SDWebImageDownloaderOperation +@required +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request + inSession:(nullable NSURLSession *)session + options:(SDWebImageDownloaderOptions)options; + +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request + inSession:(nullable NSURLSession *)session + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context; + +- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; + +- (BOOL)cancel:(nullable id)token; + +@property (strong, nonatomic, readonly, nullable) NSURLRequest *request; +@property (strong, nonatomic, readonly, nullable) NSURLResponse *response; + +@optional +@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask; +@property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +// These operation-level config was inherited from downloader. See `SDWebImageDownloaderConfig` for documentation. +@property (strong, nonatomic, nullable) NSURLCredential *credential; +@property (assign, nonatomic) double minimumProgressInterval; +@property (copy, nonatomic, nullable) NSIndexSet *acceptableStatusCodes; +@property (copy, nonatomic, nullable) NSSet *acceptableContentTypes; + +@end + + +/** + The download operation class for SDWebImageDownloader. + */ +@interface SDWebImageDownloaderOperation : NSOperation + +/** + * The request used by the operation's task. + */ +@property (strong, nonatomic, readonly, nullable) NSURLRequest *request; + +/** + * The response returned by the operation's task. + */ +@property (strong, nonatomic, readonly, nullable) NSURLResponse *response; + +/** + * The operation's task + */ +@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask; + +/** + * The collected metrics from `-URLSession:task:didFinishCollectingMetrics:`. + * This can be used to collect the network metrics like download duration, DNS lookup duration, SSL handshake duration, etc. See Apple's documentation: https://developer.apple.com/documentation/foundation/urlsessiontaskmetrics + */ +@property (strong, nonatomic, readonly, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +/** + * The credential used for authentication challenges in `-URLSession:task:didReceiveChallenge:completionHandler:`. + * + * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. + */ +@property (strong, nonatomic, nullable) NSURLCredential *credential; + +/** + * The minimum interval about progress percent during network downloading. Which means the next progress callback and current progress callback's progress percent difference should be larger or equal to this value. However, the final finish download progress callback does not get effected. + * The value should be 0.0-1.0. + * @note If you're using progressive decoding feature, this will also effect the image refresh rate. + * @note This value may enhance the performance if you don't want progress callback too frequently. + * Defaults to 0, which means each time we receive the new data from URLSession, we callback the progressBlock immediately. + */ +@property (assign, nonatomic) double minimumProgressInterval; + +/** + * Set the acceptable HTTP Response status code. The status code which beyond the range will mark the download operation failed. + * For example, if we config [200, 400) but server response is 503, the download will fail with error code `SDWebImageErrorInvalidDownloadStatusCode`. + * Defaults to [200,400). Nil means no validation at all. + */ +@property (copy, nonatomic, nullable) NSIndexSet *acceptableStatusCodes; + +/** + * Set the acceptable HTTP Response content type. The content type beyond the set will mark the download operation failed. + * For example, if we config ["image/png"] but server response is "application/json", the download will fail with error code `SDWebImageErrorInvalidDownloadContentType`. + * Normally you don't need this for image format detection because we use image's data file signature magic bytes: https://en.wikipedia.org/wiki/List_of_file_signatures + * Defaults to nil. Nil means no validation at all. + */ +@property (copy, nonatomic, nullable) NSSet *acceptableContentTypes; + +/** + * The options for the receiver. + */ +@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; + +/** + * The context for the receiver. + */ +@property (copy, nonatomic, readonly, nullable) SDWebImageContext *context; + +/** + * Initializes a `SDWebImageDownloaderOperation` object + * + * @see SDWebImageDownloaderOperation + * + * @param request the URL request + * @param session the URL session in which this operation will run + * @param options downloader options + * + * @return the initialized instance + */ +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request + inSession:(nullable NSURLSession *)session + options:(SDWebImageDownloaderOptions)options; + +/** + * Initializes a `SDWebImageDownloaderOperation` object + * + * @see SDWebImageDownloaderOperation + * + * @param request the URL request + * @param session the URL session in which this operation will run + * @param options downloader options + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * + * @return the initialized instance + */ +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request + inSession:(nullable NSURLSession *)session + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context NS_DESIGNATED_INITIALIZER; + +/** + * Adds handlers for progress and completion. Returns a token that can be passed to -cancel: to cancel this set of + * callbacks. + * + * @param progressBlock the block executed when a new chunk of data arrives. + * @note the progress block is executed on a background queue + * @param completedBlock the block executed when the download is done. + * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue + * + * @return the token to use to cancel this set of handlers + */ +- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; + +/** + * Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled. + * + * @param token the token representing a set of callbacks to cancel + * + * @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise. + */ +- (BOOL)cancel:(nullable id)token; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.m new file mode 100644 index 00000000..6df03197 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderOperation.m @@ -0,0 +1,618 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloaderOperation.h" +#import "SDWebImageError.h" +#import "SDInternalMacros.h" +#import "SDWebImageDownloaderResponseModifier.h" +#import "SDWebImageDownloaderDecryptor.h" + +static NSString *const kProgressCallbackKey = @"progress"; +static NSString *const kCompletedCallbackKey = @"completed"; + +typedef NSMutableDictionary SDCallbacksDictionary; + +@interface SDWebImageDownloaderOperation () + +@property (strong, nonatomic, nonnull) NSMutableArray *callbackBlocks; + +@property (assign, nonatomic, readwrite) SDWebImageDownloaderOptions options; +@property (copy, nonatomic, readwrite, nullable) SDWebImageContext *context; + +@property (assign, nonatomic, getter = isExecuting) BOOL executing; +@property (assign, nonatomic, getter = isFinished) BOOL finished; +@property (strong, nonatomic, nullable) NSMutableData *imageData; +@property (copy, nonatomic, nullable) NSData *cachedData; // for `SDWebImageDownloaderIgnoreCachedResponse` +@property (assign, nonatomic) NSUInteger expectedSize; // may be 0 +@property (assign, nonatomic) NSUInteger receivedSize; +@property (strong, nonatomic, nullable, readwrite) NSURLResponse *response; +@property (strong, nonatomic, nullable) NSError *responseError; +@property (assign, nonatomic) double previousProgress; // previous progress percent + +@property (strong, nonatomic, nullable) id responseModifier; // modify original URLResponse +@property (strong, nonatomic, nullable) id decryptor; // decrypt image data + +// This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run +// the task associated with this operation +@property (weak, nonatomic, nullable) NSURLSession *unownedSession; +// This is set if we're using not using an injected NSURLSession. We're responsible of invalidating this one +@property (strong, nonatomic, nullable) NSURLSession *ownedSession; + +@property (strong, nonatomic, readwrite, nullable) NSURLSessionTask *dataTask; + +@property (strong, nonatomic, readwrite, nullable) NSURLSessionTaskMetrics *metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + +@property (strong, nonatomic, nonnull) NSOperationQueue *coderQueue; // the serial operation queue to do image decoding +#if SD_UIKIT +@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId; +#endif + +@end + +@implementation SDWebImageDownloaderOperation + +@synthesize executing = _executing; +@synthesize finished = _finished; + +- (nonnull instancetype)init { + return [self initWithRequest:nil inSession:nil options:0]; +} + +- (instancetype)initWithRequest:(NSURLRequest *)request inSession:(NSURLSession *)session options:(SDWebImageDownloaderOptions)options { + return [self initWithRequest:request inSession:session options:options context:nil]; +} + +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request + inSession:(nullable NSURLSession *)session + options:(SDWebImageDownloaderOptions)options + context:(nullable SDWebImageContext *)context { + if ((self = [super init])) { + _request = [request copy]; + _options = options; + _context = [context copy]; + _callbackBlocks = [NSMutableArray new]; + _responseModifier = context[SDWebImageContextDownloadResponseModifier]; + _decryptor = context[SDWebImageContextDownloadDecryptor]; + _executing = NO; + _finished = NO; + _expectedSize = 0; + _unownedSession = session; + _coderQueue = [NSOperationQueue new]; + _coderQueue.maxConcurrentOperationCount = 1; +#if SD_UIKIT + _backgroundTaskId = UIBackgroundTaskInvalid; +#endif + } + return self; +} + +- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock { + SDCallbacksDictionary *callbacks = [NSMutableDictionary new]; + if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy]; + if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy]; + @synchronized (self) { + [self.callbackBlocks addObject:callbacks]; + } + return callbacks; +} + +- (nullable NSArray *)callbacksForKey:(NSString *)key { + NSMutableArray *callbacks; + @synchronized (self) { + callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy]; + } + // We need to remove [NSNull null] because there might not always be a progress block for each callback + [callbacks removeObjectIdenticalTo:[NSNull null]]; + return [callbacks copy]; // strip mutability here +} + +- (BOOL)cancel:(nullable id)token { + if (!token) return NO; + + BOOL shouldCancel = NO; + @synchronized (self) { + NSMutableArray *tempCallbackBlocks = [self.callbackBlocks mutableCopy]; + [tempCallbackBlocks removeObjectIdenticalTo:token]; + if (tempCallbackBlocks.count == 0) { + shouldCancel = YES; + } + } + if (shouldCancel) { + // Cancel operation running and callback last token's completion block + [self cancel]; + } else { + // Only callback this token's completion block + @synchronized (self) { + [self.callbackBlocks removeObjectIdenticalTo:token]; + } + SDWebImageDownloaderCompletedBlock completedBlock = [token valueForKey:kCompletedCallbackKey]; + dispatch_main_async_safe(^{ + if (completedBlock) { + completedBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}], YES); + } + }); + } + return shouldCancel; +} + +- (void)start { + @synchronized (self) { + if (self.isCancelled) { + if (!self.isFinished) self.finished = YES; + // Operation cancelled by user before sending the request + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user before sending the request"}]]; + [self reset]; + return; + } + +#if SD_UIKIT + Class UIApplicationClass = NSClassFromString(@"UIApplication"); + BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)]; + if (hasApplication && [self shouldContinueWhenAppEntersBackground]) { + __weak typeof(self) wself = self; + UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)]; + self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{ + [wself cancel]; + }]; + } +#endif + NSURLSession *session = self.unownedSession; + if (!session) { + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + sessionConfig.timeoutIntervalForRequest = 15; + + /** + * Create the session for this task + * We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate + * method calls and completion handler calls. + */ + session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:nil]; + self.ownedSession = session; + } + + if (self.options & SDWebImageDownloaderIgnoreCachedResponse) { + // Grab the cached data for later check + NSURLCache *URLCache = session.configuration.URLCache; + if (!URLCache) { + URLCache = [NSURLCache sharedURLCache]; + } + NSCachedURLResponse *cachedResponse; + // NSURLCache's `cachedResponseForRequest:` is not thread-safe, see https://developer.apple.com/documentation/foundation/nsurlcache#2317483 + @synchronized (URLCache) { + cachedResponse = [URLCache cachedResponseForRequest:self.request]; + } + if (cachedResponse) { + self.cachedData = cachedResponse.data; + self.response = cachedResponse.response; + } + } + + if (!session.delegate) { + // Session been invalid and has no delegate at all + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @"Session delegate is nil and invalid"}]]; + [self reset]; + return; + } + + self.dataTask = [session dataTaskWithRequest:self.request]; + self.executing = YES; + } + + if (self.dataTask) { + if (self.options & SDWebImageDownloaderHighPriority) { + self.dataTask.priority = NSURLSessionTaskPriorityHigh; + self.coderQueue.qualityOfService = NSQualityOfServiceUserInteractive; + } else if (self.options & SDWebImageDownloaderLowPriority) { + self.dataTask.priority = NSURLSessionTaskPriorityLow; + self.coderQueue.qualityOfService = NSQualityOfServiceBackground; + } else { + self.dataTask.priority = NSURLSessionTaskPriorityDefault; + self.coderQueue.qualityOfService = NSQualityOfServiceDefault; + } + [self.dataTask resume]; + for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { + progressBlock(0, NSURLResponseUnknownLength, self.request.URL); + } + __block typeof(self) strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:strongSelf]; + }); + } else { + if (!self.isFinished) self.finished = YES; + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @"Task can't be initialized"}]]; + [self reset]; + } +} + +- (void)cancel { + @synchronized (self) { + [self cancelInternal]; + } +} + +- (void)cancelInternal { + if (self.isFinished) return; + [super cancel]; + + __block typeof(self) strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:strongSelf]; + }); + + if (self.dataTask) { + // Cancel the URLSession, `URLSession:task:didCompleteWithError:` delegate callback will be ignored + [self.dataTask cancel]; + self.dataTask = nil; + } + + // NSOperation disallow setFinished=YES **before** operation's start method been called + // We check for the initialized status, which is isExecuting == NO && isFinished = NO + // Ony update for non-intialized status, which is !(isExecuting == NO && isFinished = NO), or if (self.isExecuting || self.isFinished) {...} + if (self.isExecuting || self.isFinished) { + if (self.isExecuting) self.executing = NO; + if (!self.isFinished) self.finished = YES; + } + + // Operation cancelled by user during sending the request + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}]]; + + [self reset]; +} + +- (void)done { + self.finished = YES; + self.executing = NO; + [self reset]; +} + +- (void)reset { + @synchronized (self) { + [self.callbackBlocks removeAllObjects]; + self.dataTask = nil; + + if (self.ownedSession) { + [self.ownedSession invalidateAndCancel]; + self.ownedSession = nil; + } + +#if SD_UIKIT + if (self.backgroundTaskId != UIBackgroundTaskInvalid) { + // If backgroundTaskId != UIBackgroundTaskInvalid, sharedApplication is always exist + UIApplication * app = [UIApplication performSelector:@selector(sharedApplication)]; + [app endBackgroundTask:self.backgroundTaskId]; + self.backgroundTaskId = UIBackgroundTaskInvalid; + } +#endif + } +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _finished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _executing = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isConcurrent { + return YES; +} + +#pragma mark NSURLSessionDataDelegate + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask +didReceiveResponse:(NSURLResponse *)response + completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { + NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; + + // Check response modifier, if return nil, will marked as cancelled. + BOOL valid = YES; + if (self.responseModifier && response) { + response = [self.responseModifier modifiedResponseWithResponse:response]; + if (!response) { + valid = NO; + self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain + code:SDWebImageErrorInvalidDownloadResponse + userInfo:@{NSLocalizedDescriptionKey : @"Download marked as failed because response is nil"}]; + } + } + + NSInteger expected = (NSInteger)response.expectedContentLength; + expected = expected > 0 ? expected : 0; + self.expectedSize = expected; + self.response = response; + + // Check status code valid (defaults [200,400)) + NSInteger statusCode = [response isKindOfClass:NSHTTPURLResponse.class] ? ((NSHTTPURLResponse *)response).statusCode : 0; + BOOL statusCodeValid = YES; + if (valid && statusCode > 0 && self.acceptableStatusCodes) { + statusCodeValid = [self.acceptableStatusCodes containsIndex:statusCode]; + } + if (!statusCodeValid) { + valid = NO; + self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain + code:SDWebImageErrorInvalidDownloadStatusCode + userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Download marked as failed because of invalid response status code %ld", (long)statusCode], + SDWebImageErrorDownloadStatusCodeKey : @(statusCode), + SDWebImageErrorDownloadResponseKey : response}]; + } + // Check content type valid (defaults nil) + NSString *contentType = [response isKindOfClass:NSHTTPURLResponse.class] ? ((NSHTTPURLResponse *)response).MIMEType : nil; + BOOL contentTypeValid = YES; + if (valid && contentType.length > 0 && self.acceptableContentTypes) { + contentTypeValid = [self.acceptableContentTypes containsObject:contentType]; + } + if (!contentTypeValid) { + valid = NO; + self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain + code:SDWebImageErrorInvalidDownloadContentType + userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Download marked as failed because of invalid response content type %@", contentType], + SDWebImageErrorDownloadContentTypeKey : contentType, + SDWebImageErrorDownloadResponseKey : response}]; + } + //'304 Not Modified' is an exceptional one + //URLSession current behavior will return 200 status code when the server respond 304 and URLCache hit. But this is not a standard behavior and we just add a check + if (valid && statusCode == 304 && !self.cachedData) { + valid = NO; + self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain + code:SDWebImageErrorCacheNotModified + userInfo:@{NSLocalizedDescriptionKey: @"Download response status code is 304 not modified and ignored", + SDWebImageErrorDownloadResponseKey : response}]; + } + + if (valid) { + for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { + progressBlock(0, expected, self.request.URL); + } + } else { + // Status code invalid and marked as cancelled. Do not call `[self.dataTask cancel]` which may mass up URLSession life cycle + disposition = NSURLSessionResponseCancel; + } + __block typeof(self) strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadReceiveResponseNotification object:strongSelf]; + }); + + if (completionHandler) { + completionHandler(disposition); + } +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { + if (!self.imageData) { + self.imageData = [[NSMutableData alloc] initWithCapacity:self.expectedSize]; + } + [self.imageData appendData:data]; + + self.receivedSize = self.imageData.length; + if (self.expectedSize == 0) { + // Unknown expectedSize, immediately call progressBlock and return + for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { + progressBlock(self.receivedSize, self.expectedSize, self.request.URL); + } + return; + } + + // Get the finish status + BOOL finished = (self.receivedSize >= self.expectedSize); + // Get the current progress + double currentProgress = (double)self.receivedSize / (double)self.expectedSize; + double previousProgress = self.previousProgress; + double progressInterval = currentProgress - previousProgress; + // Check if we need callback progress + if (!finished && (progressInterval < self.minimumProgressInterval)) { + return; + } + self.previousProgress = currentProgress; + + // Using data decryptor will disable the progressive decoding, since there are no support for progressive decrypt + BOOL supportProgressive = (self.options & SDWebImageDownloaderProgressiveLoad) && !self.decryptor; + // Progressive decoding Only decode partial image, full image in `URLSession:task:didCompleteWithError:` + if (supportProgressive && !finished) { + // Get the image data + NSData *imageData = self.imageData; + + // keep maximum one progressive decode process during download + if (self.coderQueue.operationCount == 0) { + // NSOperation have autoreleasepool, don't need to create extra one + @weakify(self); + [self.coderQueue addOperationWithBlock:^{ + @strongify(self); + if (!self) { + return; + } + UIImage *image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, NO, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context); + if (image) { + // We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding. + + [self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO]; + } + }]; + } + } + + for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { + progressBlock(self.receivedSize, self.expectedSize, self.request.URL); + } +} + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + willCacheResponse:(NSCachedURLResponse *)proposedResponse + completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler { + + NSCachedURLResponse *cachedResponse = proposedResponse; + + if (!(self.options & SDWebImageDownloaderUseNSURLCache)) { + // Prevents caching of responses + cachedResponse = nil; + } + if (completionHandler) { + completionHandler(cachedResponse); + } +} + +#pragma mark NSURLSessionTaskDelegate + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + // If we already cancel the operation or anything mark the operation finished, don't callback twice + if (self.isFinished) return; + + @synchronized(self) { + self.dataTask = nil; + __block typeof(self) strongSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:strongSelf]; + if (!error) { + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:strongSelf]; + } + }); + } + + // make sure to call `[self done]` to mark operation as finished + if (error) { + // custom error instead of URLSession error + if (self.responseError) { + error = self.responseError; + } + [self callCompletionBlocksWithError:error]; + [self done]; + } else { + if ([self callbacksForKey:kCompletedCallbackKey].count > 0) { + NSData *imageData = self.imageData; + self.imageData = nil; + // data decryptor + if (imageData && self.decryptor) { + imageData = [self.decryptor decryptedDataWithData:imageData response:self.response]; + } + if (imageData) { + /** if you specified to only use cached data via `SDWebImageDownloaderIgnoreCachedResponse`, + * then we should check if the cached data is equal to image data + */ + if (self.options & SDWebImageDownloaderIgnoreCachedResponse && [self.cachedData isEqualToData:imageData]) { + self.responseError = [NSError errorWithDomain:SDWebImageErrorDomain + code:SDWebImageErrorCacheNotModified + userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image is not modified and ignored", + SDWebImageErrorDownloadResponseKey : self.response}]; + // call completion block with not modified error + [self callCompletionBlocksWithError:self.responseError]; + [self done]; + } else { + // decode the image in coder queue, cancel all previous decoding process + [self.coderQueue cancelAllOperations]; + @weakify(self); + [self.coderQueue addOperationWithBlock:^{ + @strongify(self); + if (!self) { + return; + } + // check if we already use progressive decoding, use that to produce faster decoding + id progressiveCoder = SDImageLoaderGetProgressiveCoder(self); + UIImage *image; + if (progressiveCoder) { + image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, YES, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context); + } else { + image = SDImageLoaderDecodeImageData(imageData, self.request.URL, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context); + } + CGSize imageSize = image.size; + if (imageSize.width == 0 || imageSize.height == 0) { + NSString *description = image == nil ? @"Downloaded image decode failed" : @"Downloaded image has 0 pixels"; + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : description}]]; + } else { + [self callCompletionBlocksWithImage:image imageData:imageData error:nil finished:YES]; + } + [self done]; + }]; + } + } else { + [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}]]; + [self done]; + } + } else { + [self done]; + } + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + + NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; + __block NSURLCredential *credential = nil; + + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates)) { + disposition = NSURLSessionAuthChallengePerformDefaultHandling; + } else { + credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + disposition = NSURLSessionAuthChallengeUseCredential; + } + } else { + if (challenge.previousFailureCount == 0) { + if (self.credential) { + credential = self.credential; + disposition = NSURLSessionAuthChallengeUseCredential; + } else { + // Web Server like Nginx can set `ssl_verify_client` to optional but not always on + // We'd better use default handling here + disposition = NSURLSessionAuthChallengePerformDefaultHandling; + } + } else { + disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; + } + } + + if (completionHandler) { + completionHandler(disposition, credential); + } +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) { + self.metrics = metrics; +} + +#pragma mark Helper methods ++ (SDWebImageOptions)imageOptionsFromDownloaderOptions:(SDWebImageDownloaderOptions)downloadOptions { + SDWebImageOptions options = 0; + if (downloadOptions & SDWebImageDownloaderScaleDownLargeImages) options |= SDWebImageScaleDownLargeImages; + if (downloadOptions & SDWebImageDownloaderDecodeFirstFrameOnly) options |= SDWebImageDecodeFirstFrameOnly; + if (downloadOptions & SDWebImageDownloaderPreloadAllFrames) options |= SDWebImagePreloadAllFrames; + if (downloadOptions & SDWebImageDownloaderAvoidDecodeImage) options |= SDWebImageAvoidDecodeImage; + if (downloadOptions & SDWebImageDownloaderMatchAnimatedImageClass) options |= SDWebImageMatchAnimatedImageClass; + + return options; +} + +- (BOOL)shouldContinueWhenAppEntersBackground { + return SD_OPTIONS_CONTAINS(self.options, SDWebImageDownloaderContinueInBackground); +} + +- (void)callCompletionBlocksWithError:(nullable NSError *)error { + [self callCompletionBlocksWithImage:nil imageData:nil error:error finished:YES]; +} + +- (void)callCompletionBlocksWithImage:(nullable UIImage *)image + imageData:(nullable NSData *)imageData + error:(nullable NSError *)error + finished:(BOOL)finished { + NSArray *completionBlocks = [self callbacksForKey:kCompletedCallbackKey]; + dispatch_main_async_safe(^{ + for (SDWebImageDownloaderCompletedBlock completedBlock in completionBlocks) { + completedBlock(image, imageData, error, finished); + } + }); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.h new file mode 100644 index 00000000..42c8a402 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.h @@ -0,0 +1,69 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +typedef NSURLRequest * _Nullable (^SDWebImageDownloaderRequestModifierBlock)(NSURLRequest * _Nonnull request); + +/** + This is the protocol for downloader request modifier. + We can use a block to specify the downloader request modifier. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. + */ +@protocol SDWebImageDownloaderRequestModifier + +/// Modify the original URL request and return a new one instead. You can modify the HTTP header, cachePolicy, etc for this URL. +/// @param request The original URL request for image loading +/// @note If return nil, the URL request will be cancelled. +- (nullable NSURLRequest *)modifiedRequestWithRequest:(nonnull NSURLRequest *)request; + +@end + +/** + A downloader request modifier class with block. + */ +@interface SDWebImageDownloaderRequestModifier : NSObject + +/// Create the request modifier with block +/// @param block A block to control modifier logic +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block; + +/// Create the request modifier with block +/// @param block A block to control modifier logic ++ (nonnull instancetype)requestModifierWithBlock:(nonnull SDWebImageDownloaderRequestModifierBlock)block; + +@end + +/** +A convenient request modifier to provide the HTTP request including HTTP Method, Headers and Body. +*/ +@interface SDWebImageDownloaderRequestModifier (Conveniences) + +/// Create the request modifier with HTTP Method. +/// @param method HTTP Method, nil means to GET. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithMethod:(nullable NSString *)method; + +/// Create the request modifier with HTTP Headers. +/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original request. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithHeaders:(nullable NSDictionary *)headers; + +/// Create the request modifier with HTTP Body. +/// @param body HTTP Body. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithBody:(nullable NSData *)body; + +/// Create the request modifier with HTTP Method, Headers and Body. +/// @param method HTTP Method, nil means to GET. +/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original request. +/// @param body HTTP Body. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithMethod:(nullable NSString *)method headers:(nullable NSDictionary *)headers body:(nullable NSData *)body; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.m new file mode 100644 index 00000000..c12c84f8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderRequestModifier.m @@ -0,0 +1,71 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloaderRequestModifier.h" + +@interface SDWebImageDownloaderRequestModifier () + +@property (nonatomic, copy, nonnull) SDWebImageDownloaderRequestModifierBlock block; + +@end + +@implementation SDWebImageDownloaderRequestModifier + +- (instancetype)initWithBlock:(SDWebImageDownloaderRequestModifierBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)requestModifierWithBlock:(SDWebImageDownloaderRequestModifierBlock)block { + SDWebImageDownloaderRequestModifier *requestModifier = [[SDWebImageDownloaderRequestModifier alloc] initWithBlock:block]; + return requestModifier; +} + +- (NSURLRequest *)modifiedRequestWithRequest:(NSURLRequest *)request { + if (!self.block) { + return nil; + } + return self.block(request); +} + +@end + +@implementation SDWebImageDownloaderRequestModifier (Conveniences) + +- (instancetype)initWithMethod:(NSString *)method { + return [self initWithMethod:method headers:nil body:nil]; +} + +- (instancetype)initWithHeaders:(NSDictionary *)headers { + return [self initWithMethod:nil headers:headers body:nil]; +} + +- (instancetype)initWithBody:(NSData *)body { + return [self initWithMethod:nil headers:nil body:body]; +} + +- (instancetype)initWithMethod:(NSString *)method headers:(NSDictionary *)headers body:(NSData *)body { + method = method ? [method copy] : @"GET"; + headers = [headers copy]; + body = [body copy]; + return [self initWithBlock:^NSURLRequest * _Nullable(NSURLRequest * _Nonnull request) { + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + mutableRequest.HTTPMethod = method; + mutableRequest.HTTPBody = body; + for (NSString *header in headers) { + NSString *value = headers[header]; + [mutableRequest setValue:value forHTTPHeaderField:header]; + } + return [mutableRequest copy]; + }]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.h new file mode 100644 index 00000000..63c1456e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.h @@ -0,0 +1,69 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +typedef NSURLResponse * _Nullable (^SDWebImageDownloaderResponseModifierBlock)(NSURLResponse * _Nonnull response); + +/** + This is the protocol for downloader response modifier. + We can use a block to specify the downloader response modifier. But Using protocol can make this extensible, and allow Swift user to use it easily instead of using `@convention(block)` to store a block into context options. + */ +@protocol SDWebImageDownloaderResponseModifier + +/// Modify the original URL response and return a new response. You can use this to check MIME-Type, mock server response, etc. +/// @param response The original URL response, note for HTTP request it's actually a `NSHTTPURLResponse` instance +/// @note If nil is returned, the image download will marked as cancelled with error `SDWebImageErrorInvalidDownloadResponse` +- (nullable NSURLResponse *)modifiedResponseWithResponse:(nonnull NSURLResponse *)response; + +@end + +/** + A downloader response modifier class with block. + */ +@interface SDWebImageDownloaderResponseModifier : NSObject + +/// Create the response modifier with block +/// @param block A block to control modifier logic +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageDownloaderResponseModifierBlock)block; + +/// Create the response modifier with block +/// @param block A block to control modifier logic ++ (nonnull instancetype)responseModifierWithBlock:(nonnull SDWebImageDownloaderResponseModifierBlock)block; + +@end + +/** +A convenient response modifier to provide the HTTP response including HTTP Status Code, Version and Headers. +*/ +@interface SDWebImageDownloaderResponseModifier (Conveniences) + +/// Create the response modifier with HTTP Status code. +/// @param statusCode HTTP Status Code. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithStatusCode:(NSInteger)statusCode; + +/// Create the response modifier with HTTP Version. Status code defaults to 200. +/// @param version HTTP Version, nil means "HTTP/1.1". +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithVersion:(nullable NSString *)version; + +/// Create the response modifier with HTTP Headers. Status code defaults to 200. +/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original response. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithHeaders:(nullable NSDictionary *)headers; + +/// Create the response modifier with HTTP Status Code, Version and Headers. +/// @param statusCode HTTP Status Code. +/// @param version HTTP Version, nil means "HTTP/1.1". +/// @param headers HTTP Headers. Case insensitive according to HTTP/1.1(HTTP/2) standard. The headers will override the same fields from original response. +/// @note This is for convenience, if you need code to control the logic, use block API instead. +- (nonnull instancetype)initWithStatusCode:(NSInteger)statusCode version:(nullable NSString *)version headers:(nullable NSDictionary *)headers; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.m new file mode 100644 index 00000000..6acf02a2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageDownloaderResponseModifier.m @@ -0,0 +1,73 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + + +#import "SDWebImageDownloaderResponseModifier.h" + +@interface SDWebImageDownloaderResponseModifier () + +@property (nonatomic, copy, nonnull) SDWebImageDownloaderResponseModifierBlock block; + +@end + +@implementation SDWebImageDownloaderResponseModifier + +- (instancetype)initWithBlock:(SDWebImageDownloaderResponseModifierBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)responseModifierWithBlock:(SDWebImageDownloaderResponseModifierBlock)block { + SDWebImageDownloaderResponseModifier *responseModifier = [[SDWebImageDownloaderResponseModifier alloc] initWithBlock:block]; + return responseModifier; +} + +- (nullable NSURLResponse *)modifiedResponseWithResponse:(nonnull NSURLResponse *)response { + if (!self.block) { + return nil; + } + return self.block(response); +} + +@end + +@implementation SDWebImageDownloaderResponseModifier (Conveniences) + +- (instancetype)initWithStatusCode:(NSInteger)statusCode { + return [self initWithStatusCode:statusCode version:nil headers:nil]; +} + +- (instancetype)initWithVersion:(NSString *)version { + return [self initWithStatusCode:200 version:version headers:nil]; +} + +- (instancetype)initWithHeaders:(NSDictionary *)headers { + return [self initWithStatusCode:200 version:nil headers:headers]; +} + +- (instancetype)initWithStatusCode:(NSInteger)statusCode version:(NSString *)version headers:(NSDictionary *)headers { + version = version ? [version copy] : @"HTTP/1.1"; + headers = [headers copy]; + return [self initWithBlock:^NSURLResponse * _Nullable(NSURLResponse * _Nonnull response) { + if (![response isKindOfClass:NSHTTPURLResponse.class]) { + return response; + } + NSMutableDictionary *mutableHeaders = [((NSHTTPURLResponse *)response).allHeaderFields mutableCopy]; + for (NSString *header in headers) { + NSString *value = headers[header]; + mutableHeaders[header] = value; + } + NSHTTPURLResponse *httpResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL statusCode:statusCode HTTPVersion:version headerFields:[mutableHeaders copy]]; + return httpResponse; + }]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.h new file mode 100644 index 00000000..bb91d0bd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.h @@ -0,0 +1,32 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Jamie Pinkham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +FOUNDATION_EXPORT NSErrorDomain const _Nonnull SDWebImageErrorDomain; + +/// The response instance for invalid download response (NSURLResponse *) +FOUNDATION_EXPORT NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadResponseKey; +/// The HTTP status code for invalid download response (NSNumber *) +FOUNDATION_EXPORT NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadStatusCodeKey; +/// The HTTP MIME content type for invalid download response (NSString *) +FOUNDATION_EXPORT NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadContentTypeKey; + +/// SDWebImage error domain and codes +typedef NS_ERROR_ENUM(SDWebImageErrorDomain, SDWebImageError) { + SDWebImageErrorInvalidURL = 1000, // The URL is invalid, such as nil URL or corrupted URL + SDWebImageErrorBadImageData = 1001, // The image data can not be decoded to image, or the image data is empty + SDWebImageErrorCacheNotModified = 1002, // The remote location specify that the cached image is not modified, such as the HTTP response 304 code. It's useful for `SDWebImageRefreshCached` + SDWebImageErrorBlackListed = 1003, // The URL is blacklisted because of unrecoverable failure marked by downloader (such as 404), you can use `.retryFailed` option to avoid this + SDWebImageErrorInvalidDownloadOperation = 2000, // The image download operation is invalid, such as nil operation or unexpected error occur when operation initialized + SDWebImageErrorInvalidDownloadStatusCode = 2001, // The image download response a invalid status code. You can check the status code in error's userInfo under `SDWebImageErrorDownloadStatusCodeKey` + SDWebImageErrorCancelled = 2002, // The image loading operation is cancelled before finished, during either async disk cache query, or waiting before actual network request. For actual network request error, check `NSURLErrorDomain` error domain and code. + SDWebImageErrorInvalidDownloadResponse = 2003, // When using response modifier, the modified download response is nil and marked as failed. + SDWebImageErrorInvalidDownloadContentType = 2004, // The image download response a invalid content type. You can check the MIME content type in error's userInfo under `SDWebImageErrorDownloadContentTypeKey` +}; diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.m new file mode 100644 index 00000000..bd0d17ad --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageError.m @@ -0,0 +1,16 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Jamie Pinkham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageError.h" + +NSErrorDomain const _Nonnull SDWebImageErrorDomain = @"SDWebImageErrorDomain"; + +NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadResponseKey = @"SDWebImageErrorDownloadResponseKey"; +NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadStatusCodeKey = @"SDWebImageErrorDownloadStatusCodeKey"; +NSErrorUserInfoKey const _Nonnull SDWebImageErrorDownloadContentTypeKey = @"SDWebImageErrorDownloadContentTypeKey"; diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.h new file mode 100644 index 00000000..e1165c12 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.h @@ -0,0 +1,115 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_UIKIT || SD_MAC + +/** + A protocol to custom the indicator during the image loading. + All of these methods are called from main queue. + */ +@protocol SDWebImageIndicator + +@required +/** + The view associate to the indicator. + + @return The indicator view + */ +@property (nonatomic, strong, readonly, nonnull) UIView *indicatorView; + +/** + Start the animating for indicator. + */ +- (void)startAnimatingIndicator; + +/** + Stop the animating for indicator. + */ +- (void)stopAnimatingIndicator; + +@optional +/** + Update the loading progress (0-1.0) for indicator. Optional + + @param progress The progress, value between 0 and 1.0 + */ +- (void)updateIndicatorProgress:(double)progress; + +@end + +#pragma mark - Activity Indicator + +/** + Activity indicator class. + for UIKit(macOS), it use a `UIActivityIndicatorView`. + for AppKit(macOS), it use a `NSProgressIndicator` with the spinning style. + */ +@interface SDWebImageActivityIndicator : NSObject + +#if SD_UIKIT +@property (nonatomic, strong, readonly, nonnull) UIActivityIndicatorView *indicatorView; +#else +@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView; +#endif + +@end + +/** + Convenience way to use activity indicator. + */ +@interface SDWebImageActivityIndicator (Conveniences) + +/// These indicator use the fixed color without dark mode support +/// gray-style activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *grayIndicator; +/// large gray-style activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *grayLargeIndicator; +/// white-style activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *whiteIndicator; +/// large white-style activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *whiteLargeIndicator; +/// These indicator use the system style, supports dark mode if available (iOS 13+/macOS 10.14+) +/// large activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *largeIndicator; +/// medium activity indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageActivityIndicator *mediumIndicator; + +@end + +#pragma mark - Progress Indicator + +/** + Progress indicator class. + for UIKit(macOS), it use a `UIProgressView`. + for AppKit(macOS), it use a `NSProgressIndicator` with the bar style. + */ +@interface SDWebImageProgressIndicator : NSObject + +#if SD_UIKIT +@property (nonatomic, strong, readonly, nonnull) UIProgressView *indicatorView; +#else +@property (nonatomic, strong, readonly, nonnull) NSProgressIndicator *indicatorView; +#endif + +@end + +/** + Convenience way to create progress indicator. Remember to specify the indicator width or use layout constraint if need. + */ +@interface SDWebImageProgressIndicator (Conveniences) + +/// default-style progress indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageProgressIndicator *defaultIndicator; +/// bar-style progress indicator +@property (nonatomic, class, nonnull, readonly) SDWebImageProgressIndicator *barIndicator API_UNAVAILABLE(macos, tvos); + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.m new file mode 100644 index 00000000..6d4a8ee3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageIndicator.m @@ -0,0 +1,274 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageIndicator.h" + +#if SD_UIKIT || SD_MAC + +#if SD_MAC +#import +#endif + +#pragma mark - Activity Indicator + +@interface SDWebImageActivityIndicator () + +#if SD_UIKIT +@property (nonatomic, strong, readwrite, nonnull) UIActivityIndicatorView *indicatorView; +#else +@property (nonatomic, strong, readwrite, nonnull) NSProgressIndicator *indicatorView; +#endif + +@end + +@implementation SDWebImageActivityIndicator + +- (instancetype)init { + self = [super init]; + if (self) { + [self commonInit]; + } + return self; +} + +#if SD_UIKIT +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)commonInit { + self.indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + self.indicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; +} +#pragma clang diagnostic pop +#endif + +#if SD_MAC +- (void)commonInit { + self.indicatorView = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect]; + self.indicatorView.style = NSProgressIndicatorStyleSpinning; + self.indicatorView.controlSize = NSControlSizeSmall; + [self.indicatorView sizeToFit]; + self.indicatorView.autoresizingMask = NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin; +} +#endif + +- (void)startAnimatingIndicator { +#if SD_UIKIT + [self.indicatorView startAnimating]; +#else + [self.indicatorView startAnimation:nil]; +#endif + self.indicatorView.hidden = NO; +} + +- (void)stopAnimatingIndicator { +#if SD_UIKIT + [self.indicatorView stopAnimating]; +#else + [self.indicatorView stopAnimation:nil]; +#endif + self.indicatorView.hidden = YES; +} + +@end + +@implementation SDWebImageActivityIndicator (Conveniences) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ++ (SDWebImageActivityIndicator *)grayIndicator { + SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new]; +#if SD_UIKIT +#if SD_IOS + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +#else + indicator.indicatorView.color = [UIColor colorWithWhite:0 alpha:0.45]; // Color from `UIActivityIndicatorViewStyleGray` +#endif +#else + indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support +#endif + return indicator; +} + ++ (SDWebImageActivityIndicator *)grayLargeIndicator { + SDWebImageActivityIndicator *indicator = SDWebImageActivityIndicator.grayIndicator; +#if SD_UIKIT + UIColor *grayColor = indicator.indicatorView.color; + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; + indicator.indicatorView.color = grayColor; +#else + indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support + indicator.indicatorView.controlSize = NSControlSizeRegular; +#endif + [indicator.indicatorView sizeToFit]; + return indicator; +} + ++ (SDWebImageActivityIndicator *)whiteIndicator { + SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new]; +#if SD_UIKIT + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite; +#else + indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support + CIFilter *lighten = [CIFilter filterWithName:@"CIColorControls"]; + [lighten setDefaults]; + [lighten setValue:@(1) forKey:kCIInputBrightnessKey]; + indicator.indicatorView.contentFilters = @[lighten]; +#endif + return indicator; +} + ++ (SDWebImageActivityIndicator *)whiteLargeIndicator { + SDWebImageActivityIndicator *indicator = SDWebImageActivityIndicator.whiteIndicator; +#if SD_UIKIT + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; +#else + indicator.indicatorView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; // Disable dark mode support + indicator.indicatorView.controlSize = NSControlSizeRegular; + [indicator.indicatorView sizeToFit]; +#endif + return indicator; +} + ++ (SDWebImageActivityIndicator *)largeIndicator { + SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new]; +#if SD_UIKIT + if (@available(iOS 13.0, tvOS 13.0, *)) { + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleLarge; + } else { + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; + } +#else + indicator.indicatorView.controlSize = NSControlSizeRegular; + [indicator.indicatorView sizeToFit]; +#endif + return indicator; +} + ++ (SDWebImageActivityIndicator *)mediumIndicator { + SDWebImageActivityIndicator *indicator = [SDWebImageActivityIndicator new]; +#if SD_UIKIT + if (@available(iOS 13.0, tvOS 13.0, *)) { + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; + } else { + indicator.indicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite; + } +#else + indicator.indicatorView.controlSize = NSControlSizeSmall; + [indicator.indicatorView sizeToFit]; +#endif + return indicator; +} +#pragma clang diagnostic pop + +@end + +#pragma mark - Progress Indicator + +@interface SDWebImageProgressIndicator () + +#if SD_UIKIT +@property (nonatomic, strong, readwrite, nonnull) UIProgressView *indicatorView; +#else +@property (nonatomic, strong, readwrite, nonnull) NSProgressIndicator *indicatorView; +#endif + +@end + +@implementation SDWebImageProgressIndicator + +- (instancetype)init { + self = [super init]; + if (self) { + [self commonInit]; + } + return self; +} + +#if SD_UIKIT +- (void)commonInit { + self.indicatorView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; + self.indicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; +} +#endif + +#if SD_MAC +- (void)commonInit { + self.indicatorView = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 160, 0)]; // Width from `UIProgressView` default width + self.indicatorView.style = NSProgressIndicatorStyleBar; + self.indicatorView.controlSize = NSControlSizeSmall; + [self.indicatorView sizeToFit]; + self.indicatorView.autoresizingMask = NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin; +} +#endif + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +- (void)startAnimatingIndicator { + self.indicatorView.hidden = NO; +#if SD_UIKIT + if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) { + // Ignore NSProgress + } else { + self.indicatorView.progress = 0; + } +#else + self.indicatorView.indeterminate = YES; + self.indicatorView.doubleValue = 0; + [self.indicatorView startAnimation:nil]; +#endif +} + +- (void)stopAnimatingIndicator { + self.indicatorView.hidden = YES; +#if SD_UIKIT + if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) { + // Ignore NSProgress + } else { + self.indicatorView.progress = 1; + } +#else + self.indicatorView.indeterminate = NO; + self.indicatorView.doubleValue = 100; + [self.indicatorView stopAnimation:nil]; +#endif +} + +- (void)updateIndicatorProgress:(double)progress { +#if SD_UIKIT + if ([self.indicatorView respondsToSelector:@selector(observedProgress)] && self.indicatorView.observedProgress) { + // Ignore NSProgress + } else { + [self.indicatorView setProgress:progress animated:YES]; + } +#else + self.indicatorView.indeterminate = progress > 0 ? NO : YES; + self.indicatorView.doubleValue = progress * 100; +#endif +} +#pragma clang diagnostic pop + +@end + +@implementation SDWebImageProgressIndicator (Conveniences) + ++ (SDWebImageProgressIndicator *)defaultIndicator { + SDWebImageProgressIndicator *indicator = [SDWebImageProgressIndicator new]; + return indicator; +} + +#if SD_IOS ++ (SDWebImageProgressIndicator *)barIndicator { + SDWebImageProgressIndicator *indicator = [SDWebImageProgressIndicator new]; + indicator.indicatorView.progressViewStyle = UIProgressViewStyleBar; + return indicator; +} +#endif + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.h new file mode 100644 index 00000000..ee90724e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.h @@ -0,0 +1,287 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageOperation.h" +#import "SDImageCacheDefine.h" +#import "SDImageLoader.h" +#import "SDImageTransformer.h" +#import "SDWebImageCacheKeyFilter.h" +#import "SDWebImageCacheSerializer.h" +#import "SDWebImageOptionsProcessor.h" + +typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL); + +typedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL); + +/** + A combined operation representing the cache and loader operation. You can use it to cancel the load process. + */ +@interface SDWebImageCombinedOperation : NSObject + +/** + Cancel the current operation, including cache and loader process + */ +- (void)cancel; + +/** + The cache operation from the image cache query + */ +@property (strong, nonatomic, nullable, readonly) id cacheOperation; + +/** + The loader operation from the image loader (such as download operation) + */ +@property (strong, nonatomic, nullable, readonly) id loaderOperation; + +@end + + +@class SDWebImageManager; + +/** + The manager delegate protocol. + */ +@protocol SDWebImageManagerDelegate + +@optional + +/** + * Controls which image should be downloaded when the image is not found in the cache. + * + * @param imageManager The current `SDWebImageManager` + * @param imageURL The url of the image to be downloaded + * + * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. + */ +- (BOOL)imageManager:(nonnull SDWebImageManager *)imageManager shouldDownloadImageForURL:(nonnull NSURL *)imageURL; + +/** + * Controls the complicated logic to mark as failed URLs when download error occur. + * If the delegate implement this method, we will not use the built-in way to mark URL as failed based on error code; + @param imageManager The current `SDWebImageManager` + @param imageURL The url of the image + @param error The download error for the url + @return Whether to block this url or not. Return YES to mark this URL as failed. + */ +- (BOOL)imageManager:(nonnull SDWebImageManager *)imageManager shouldBlockFailedURL:(nonnull NSURL *)imageURL withError:(nonnull NSError *)error; + +@end + +/** + * The SDWebImageManager is the class behind the UIImageView+WebCache category and likes. + * It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache). + * You can use this class directly to benefit from web image downloading with caching in another context than + * a UIView. + * + * Here is a simple example of how to use SDWebImageManager: + * + * @code + +SDWebImageManager *manager = [SDWebImageManager sharedManager]; +[manager loadImageWithURL:imageURL + options:0 + progress:nil + completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (image) { + // do something with image + } + }]; + + * @endcode + */ +@interface SDWebImageManager : NSObject + +/** + * The delegate for manager. Defaults to nil. + */ +@property (weak, nonatomic, nullable) id delegate; + +/** + * The image cache used by manager to query image cache. + */ +@property (strong, nonatomic, readonly, nonnull) id imageCache; + +/** + * The image loader used by manager to load image. + */ +@property (strong, nonatomic, readonly, nonnull) id imageLoader; + +/** + The image transformer for manager. It's used for image transform after the image load finished and store the transformed image to cache, see `SDImageTransformer`. + Defaults to nil, which means no transform is applied. + @note This will affect all the load requests for this manager if you provide. However, you can pass `SDWebImageContextImageTransformer` in context arg to explicitly use that transformer instead. + */ +@property (strong, nonatomic, nullable) id transformer; + +/** + * The cache filter is used to convert an URL into a cache key each time SDWebImageManager need cache key to use image cache. + * + * The following example sets a filter in the application delegate that will remove any query-string from the + * URL before to use it as a cache key: + * + * @code + SDWebImageManager.sharedManager.cacheKeyFilter =[SDWebImageCacheKeyFilter cacheKeyFilterWithBlock:^NSString * _Nullable(NSURL * _Nonnull url) { + url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; + return [url absoluteString]; + }]; + * @endcode + */ +@property (nonatomic, strong, nullable) id cacheKeyFilter; + +/** + * The cache serializer is used to convert the decoded image, the source downloaded data, to the actual data used for storing to the disk cache. If you return nil, means to generate the data from the image instance, see `SDImageCache`. + * For example, if you are using WebP images and facing the slow decoding time issue when later retrieving from disk cache again. You can try to encode the decoded image to JPEG/PNG format to disk cache instead of source downloaded data. + * @note The `image` arg is nonnull, but when you also provide an image transformer and the image is transformed, the `data` arg may be nil, take attention to this case. + * @note This method is called from a global queue in order to not to block the main thread. + * @code + SDWebImageManager.sharedManager.cacheSerializer = [SDWebImageCacheSerializer cacheSerializerWithBlock:^NSData * _Nullable(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL) { + SDImageFormat format = [NSData sd_imageFormatForImageData:data]; + switch (format) { + case SDImageFormatWebP: + return image.images ? data : nil; + default: + return data; + } +}]; + * @endcode + * The default value is nil. Means we just store the source downloaded data to disk cache. + */ +@property (nonatomic, strong, nullable) id cacheSerializer; + +/** + The options processor is used, to have a global control for all the image request options and context option for current manager. + @note If you use `transformer`, `cacheKeyFilter` or `cacheSerializer` property of manager, the input context option already apply those properties before passed. This options processor is a better replacement for those property in common usage. + For example, you can control the global options, based on the URL or original context option like the below code. + + @code + SDWebImageManager.sharedManager.optionsProcessor = [SDWebImageOptionsProcessor optionsProcessorWithBlock:^SDWebImageOptionsResult * _Nullable(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context) { + // Only do animation on `SDAnimatedImageView` + if (!context[SDWebImageContextAnimatedImageClass]) { + options |= SDWebImageDecodeFirstFrameOnly; + } + // Do not force decode for png url + if ([url.lastPathComponent isEqualToString:@"png"]) { + options |= SDWebImageAvoidDecodeImage; + } + // Always use screen scale factor + SDWebImageMutableContext *mutableContext = [NSDictionary dictionaryWithDictionary:context]; + mutableContext[SDWebImageContextImageScaleFactor] = @(UIScreen.mainScreen.scale); + context = [mutableContext copy]; + + return [[SDWebImageOptionsResult alloc] initWithOptions:options context:context]; + }]; + @endcode + */ +@property (nonatomic, strong, nullable) id optionsProcessor; + +/** + * Check one or more operations running + */ +@property (nonatomic, assign, readonly, getter=isRunning) BOOL running; + +/** + The default image cache when the manager which is created with no arguments. Such as shared manager or init. + Defaults to nil. Means using `SDImageCache.sharedImageCache` + */ +@property (nonatomic, class, nullable) id defaultImageCache; + +/** + The default image loader for manager which is created with no arguments. Such as shared manager or init. + Defaults to nil. Means using `SDWebImageDownloader.sharedDownloader` + */ +@property (nonatomic, class, nullable) id defaultImageLoader; + +/** + * Returns global shared manager instance. + */ +@property (nonatomic, class, readonly, nonnull) SDWebImageManager *sharedManager; + +/** + * Allows to specify instance of cache and image loader used with image manager. + * @return new instance of `SDWebImageManager` with specified cache and loader. + */ +- (nonnull instancetype)initWithCache:(nonnull id)cache loader:(nonnull id)loader NS_DESIGNATED_INITIALIZER; + +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @param url The URL to the image + * @param options A mask to specify options to use for this request + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. + * + * This parameter is required. + * + * This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter. + * In case of error the image parameter is nil and the third parameter may contain an NSError. + * + * The forth parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache + * or from the memory cache or from the network. + * + * The fifth parameter is set to NO when the SDWebImageProgressiveLoad option is used and the image is + * downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the + * block is called a last time with the full image and the last parameter set to YES. + * + * The last parameter is the original image URL + * + * @return Returns an instance of SDWebImageCombinedOperation, which you can cancel the loading process. + */ +- (nullable SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nonnull SDInternalCompletionBlock)completedBlock; + +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @param url The URL to the image + * @param options A mask to specify options to use for this request + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. + * + * @return Returns an instance of SDWebImageCombinedOperation, which you can cancel the loading process. + */ +- (nullable SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nonnull SDInternalCompletionBlock)completedBlock; + +/** + * Cancel all current operations + */ +- (void)cancelAll; + +/** + * Remove the specify URL from failed black list. + * @param url The failed URL. + */ +- (void)removeFailedURL:(nonnull NSURL *)url; + +/** + * Remove all the URL from failed black list. + */ +- (void)removeAllFailedURLs; + +/** + * Return the cache key for a given URL, does not considerate transformer or thumbnail. + * @note This method does not have context option, only use the url and manager level cacheKeyFilter to generate the cache key. + */ +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url; + +/** + * Return the cache key for a given URL and context option. + * @note The context option like `.thumbnailPixelSize` and `.imageTransformer` will effect the generated cache key, using this if you have those context associated. +*/ +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url context:(nullable SDWebImageContext *)context; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.m new file mode 100644 index 00000000..b434d783 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageManager.m @@ -0,0 +1,717 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageManager.h" +#import "SDImageCache.h" +#import "SDWebImageDownloader.h" +#import "UIImage+Metadata.h" +#import "SDAssociatedObject.h" +#import "SDWebImageError.h" +#import "SDInternalMacros.h" + +static id _defaultImageCache; +static id _defaultImageLoader; + +@interface SDWebImageCombinedOperation () + +@property (assign, nonatomic, getter = isCancelled) BOOL cancelled; +@property (strong, nonatomic, readwrite, nullable) id loaderOperation; +@property (strong, nonatomic, readwrite, nullable) id cacheOperation; +@property (weak, nonatomic, nullable) SDWebImageManager *manager; + +@end + +@interface SDWebImageManager () { + SD_LOCK_DECLARE(_failedURLsLock); // a lock to keep the access to `failedURLs` thread-safe + SD_LOCK_DECLARE(_runningOperationsLock); // a lock to keep the access to `runningOperations` thread-safe +} + +@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache; +@property (strong, nonatomic, readwrite, nonnull) id imageLoader; +@property (strong, nonatomic, nonnull) NSMutableSet *failedURLs; +@property (strong, nonatomic, nonnull) NSMutableSet *runningOperations; + +@end + +@implementation SDWebImageManager + ++ (id)defaultImageCache { + return _defaultImageCache; +} + ++ (void)setDefaultImageCache:(id)defaultImageCache { + if (defaultImageCache && ![defaultImageCache conformsToProtocol:@protocol(SDImageCache)]) { + return; + } + _defaultImageCache = defaultImageCache; +} + ++ (id)defaultImageLoader { + return _defaultImageLoader; +} + ++ (void)setDefaultImageLoader:(id)defaultImageLoader { + if (defaultImageLoader && ![defaultImageLoader conformsToProtocol:@protocol(SDImageLoader)]) { + return; + } + _defaultImageLoader = defaultImageLoader; +} + ++ (nonnull instancetype)sharedManager { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (nonnull instancetype)init { + id cache = [[self class] defaultImageCache]; + if (!cache) { + cache = [SDImageCache sharedImageCache]; + } + id loader = [[self class] defaultImageLoader]; + if (!loader) { + loader = [SDWebImageDownloader sharedDownloader]; + } + return [self initWithCache:cache loader:loader]; +} + +- (nonnull instancetype)initWithCache:(nonnull id)cache loader:(nonnull id)loader { + if ((self = [super init])) { + _imageCache = cache; + _imageLoader = loader; + _failedURLs = [NSMutableSet new]; + SD_LOCK_INIT(_failedURLsLock); + _runningOperations = [NSMutableSet new]; + SD_LOCK_INIT(_runningOperationsLock); + } + return self; +} + +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url { + if (!url) { + return @""; + } + + NSString *key; + // Cache Key Filter + id cacheKeyFilter = self.cacheKeyFilter; + if (cacheKeyFilter) { + key = [cacheKeyFilter cacheKeyForURL:url]; + } else { + key = url.absoluteString; + } + + return key; +} + +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url context:(nullable SDWebImageContext *)context { + if (!url) { + return @""; + } + + NSString *key; + // Cache Key Filter + id cacheKeyFilter = self.cacheKeyFilter; + if (context[SDWebImageContextCacheKeyFilter]) { + cacheKeyFilter = context[SDWebImageContextCacheKeyFilter]; + } + if (cacheKeyFilter) { + key = [cacheKeyFilter cacheKeyForURL:url]; + } else { + key = url.absoluteString; + } + + // Thumbnail Key Appending + NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { + CGSize thumbnailSize = CGSizeZero; +#if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; +#else + thumbnailSize = thumbnailSizeValue.CGSizeValue; +#endif + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + key = SDThumbnailedKeyForKey(key, thumbnailSize, preserveAspectRatio); + } + + // Transformer Key Appending + id transformer = self.transformer; + if (context[SDWebImageContextImageTransformer]) { + transformer = context[SDWebImageContextImageTransformer]; + if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) { + transformer = nil; + } + } + if (transformer) { + key = SDTransformedKeyForKey(key, transformer.transformerKey); + } + + return key; +} + +- (SDWebImageCombinedOperation *)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDInternalCompletionBlock)completedBlock { + return [self loadImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nonnull SDInternalCompletionBlock)completedBlock { + // Invoking this method without a completedBlock is pointless + NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); + + // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, Xcode won't + // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. + if ([url isKindOfClass:NSString.class]) { + url = [NSURL URLWithString:(NSString *)url]; + } + + // Prevents app crashing on argument type error like sending NSNull instead of NSURL + if (![url isKindOfClass:NSURL.class]) { + url = nil; + } + + SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new]; + operation.manager = self; + + BOOL isFailedUrl = NO; + if (url) { + SD_LOCK(_failedURLsLock); + isFailedUrl = [self.failedURLs containsObject:url]; + SD_UNLOCK(_failedURLsLock); + } + + if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { + NSString *description = isFailedUrl ? @"Image url is blacklisted" : @"Image url is nil"; + NSInteger code = isFailedUrl ? SDWebImageErrorBlackListed : SDWebImageErrorInvalidURL; + [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : description}] url:url]; + return operation; + } + + SD_LOCK(_runningOperationsLock); + [self.runningOperations addObject:operation]; + SD_UNLOCK(_runningOperationsLock); + + // Preprocess the options and context arg to decide the final the result for manager + SDWebImageOptionsResult *result = [self processedResultForURL:url options:options context:context]; + + // Start the entry to load image from cache + [self callCacheProcessForOperation:operation url:url options:result.options context:result.context progress:progressBlock completed:completedBlock]; + + return operation; +} + +- (void)cancelAll { + SD_LOCK(_runningOperationsLock); + NSSet *copiedOperations = [self.runningOperations copy]; + SD_UNLOCK(_runningOperationsLock); + [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; // This will call `safelyRemoveOperationFromRunning:` and remove from the array +} + +- (BOOL)isRunning { + BOOL isRunning = NO; + SD_LOCK(_runningOperationsLock); + isRunning = (self.runningOperations.count > 0); + SD_UNLOCK(_runningOperationsLock); + return isRunning; +} + +- (void)removeFailedURL:(NSURL *)url { + if (!url) { + return; + } + SD_LOCK(_failedURLsLock); + [self.failedURLs removeObject:url]; + SD_UNLOCK(_failedURLsLock); +} + +- (void)removeAllFailedURLs { + SD_LOCK(_failedURLsLock); + [self.failedURLs removeAllObjects]; + SD_UNLOCK(_failedURLsLock); +} + +#pragma mark - Private + +// Query normal cache process +- (void)callCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation + url:(nonnull NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + // Grab the image cache to use + id imageCache; + if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextImageCache]; + } else { + imageCache = self.imageCache; + } + // Get the query cache type + SDImageCacheType queryCacheType = SDImageCacheTypeAll; + if (context[SDWebImageContextQueryCacheType]) { + queryCacheType = [context[SDWebImageContextQueryCacheType] integerValue]; + } + + // Check whether we should query cache + BOOL shouldQueryCache = !SD_OPTIONS_CONTAINS(options, SDWebImageFromLoaderOnly); + if (shouldQueryCache) { + NSString *key = [self cacheKeyForURL:url context:context]; + @weakify(operation); + operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) { + @strongify(operation); + if (!operation || operation.isCancelled) { + // Image combined operation cancelled by user + [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] url:url]; + [self safelyRemoveOperationFromRunning:operation]; + return; + } else if (context[SDWebImageContextImageTransformer] && !cachedImage) { + // Have a chance to query original cache instead of downloading + [self callOriginalCacheProcessForOperation:operation url:url options:options context:context progress:progressBlock completed:completedBlock]; + return; + } + + // Continue download process + [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:cachedImage cachedData:cachedData cacheType:cacheType progress:progressBlock completed:completedBlock]; + }]; + } else { + // Continue download process + [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:SDImageCacheTypeNone progress:progressBlock completed:completedBlock]; + } +} + +// Query original cache process +- (void)callOriginalCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation + url:(nonnull NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + // Grab the image cache to use, choose standalone original cache firstly + id imageCache; + if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextOriginalImageCache]; + } else { + // if no standalone cache available, use default cache + if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextImageCache]; + } else { + imageCache = self.imageCache; + } + } + // Get the original query cache type + SDImageCacheType originalQueryCacheType = SDImageCacheTypeDisk; + if (context[SDWebImageContextOriginalQueryCacheType]) { + originalQueryCacheType = [context[SDWebImageContextOriginalQueryCacheType] integerValue]; + } + + // Check whether we should query original cache + BOOL shouldQueryOriginalCache = (originalQueryCacheType != SDImageCacheTypeNone); + if (shouldQueryOriginalCache) { + // Disable transformer for original cache key generation + SDWebImageMutableContext *tempContext = [context mutableCopy]; + tempContext[SDWebImageContextImageTransformer] = [NSNull null]; + NSString *key = [self cacheKeyForURL:url context:tempContext]; + @weakify(operation); + operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context cacheType:originalQueryCacheType completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) { + @strongify(operation); + if (!operation || operation.isCancelled) { + // Image combined operation cancelled by user + [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] url:url]; + [self safelyRemoveOperationFromRunning:operation]; + return; + } else if (context[SDWebImageContextImageTransformer] && !cachedImage) { + // Original image cache miss. Continue download process + [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:originalQueryCacheType progress:progressBlock completed:completedBlock]; + return; + } + + // Use the store cache process instead of downloading, and ignore .refreshCached option for now + [self callStoreCacheProcessForOperation:operation url:url options:options context:context downloadedImage:cachedImage downloadedData:cachedData finished:YES progress:progressBlock completed:completedBlock]; + + [self safelyRemoveOperationFromRunning:operation]; + }]; + } else { + // Continue download process + [self callDownloadProcessForOperation:operation url:url options:options context:context cachedImage:nil cachedData:nil cacheType:originalQueryCacheType progress:progressBlock completed:completedBlock]; + } +} + +// Download process +- (void)callDownloadProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation + url:(nonnull NSURL *)url + options:(SDWebImageOptions)options + context:(SDWebImageContext *)context + cachedImage:(nullable UIImage *)cachedImage + cachedData:(nullable NSData *)cachedData + cacheType:(SDImageCacheType)cacheType + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + // Grab the image loader to use + id imageLoader; + if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) { + imageLoader = context[SDWebImageContextImageLoader]; + } else { + imageLoader = self.imageLoader; + } + + // Check whether we should download image from network + BOOL shouldDownload = !SD_OPTIONS_CONTAINS(options, SDWebImageFromCacheOnly); + shouldDownload &= (!cachedImage || options & SDWebImageRefreshCached); + shouldDownload &= (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]); + if ([imageLoader respondsToSelector:@selector(canRequestImageForURL:options:context:)]) { + shouldDownload &= [imageLoader canRequestImageForURL:url options:options context:context]; + } else { + shouldDownload &= [imageLoader canRequestImageForURL:url]; + } + if (shouldDownload) { + if (cachedImage && options & SDWebImageRefreshCached) { + // If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image + // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. + [self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url]; + // Pass the cached image to the image loader. The image loader should check whether the remote image is equal to the cached image. + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextLoaderCachedImage] = cachedImage; + context = [mutableContext copy]; + } + + @weakify(operation); + operation.loaderOperation = [imageLoader requestImageWithURL:url options:options context:context progress:progressBlock completed:^(UIImage *downloadedImage, NSData *downloadedData, NSError *error, BOOL finished) { + @strongify(operation); + if (!operation || operation.isCancelled) { + // Image combined operation cancelled by user + [self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}] url:url]; + } else if (cachedImage && options & SDWebImageRefreshCached && [error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCacheNotModified) { + // Image refresh hit the NSURLCache cache, do not call the completion block + } else if ([error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCancelled) { + // Download operation cancelled by user before sending the request, don't block failed URL + [self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url]; + } else if (error) { + [self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url]; + BOOL shouldBlockFailedURL = [self shouldBlockFailedURLWithURL:url error:error options:options context:context]; + + if (shouldBlockFailedURL) { + SD_LOCK(self->_failedURLsLock); + [self.failedURLs addObject:url]; + SD_UNLOCK(self->_failedURLsLock); + } + } else { + if ((options & SDWebImageRetryFailed)) { + SD_LOCK(self->_failedURLsLock); + [self.failedURLs removeObject:url]; + SD_UNLOCK(self->_failedURLsLock); + } + // Continue store cache process + [self callStoreCacheProcessForOperation:operation url:url options:options context:context downloadedImage:downloadedImage downloadedData:downloadedData finished:finished progress:progressBlock completed:completedBlock]; + } + + if (finished) { + [self safelyRemoveOperationFromRunning:operation]; + } + }]; + } else if (cachedImage) { + [self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url]; + [self safelyRemoveOperationFromRunning:operation]; + } else { + // Image not in cache and download disallowed by delegate + [self callCompletionBlockForOperation:operation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES url:url]; + [self safelyRemoveOperationFromRunning:operation]; + } +} + +// Store cache process +- (void)callStoreCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation + url:(nonnull NSURL *)url + options:(SDWebImageOptions)options + context:(SDWebImageContext *)context + downloadedImage:(nullable UIImage *)downloadedImage + downloadedData:(nullable NSData *)downloadedData + finished:(BOOL)finished + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + // Grab the image cache to use, choose standalone original cache firstly + id imageCache; + if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextOriginalImageCache]; + } else { + // if no standalone cache available, use default cache + if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextImageCache]; + } else { + imageCache = self.imageCache; + } + } + // the target image store cache type + SDImageCacheType storeCacheType = SDImageCacheTypeAll; + if (context[SDWebImageContextStoreCacheType]) { + storeCacheType = [context[SDWebImageContextStoreCacheType] integerValue]; + } + // the original store image cache type + SDImageCacheType originalStoreCacheType = SDImageCacheTypeDisk; + if (context[SDWebImageContextOriginalStoreCacheType]) { + originalStoreCacheType = [context[SDWebImageContextOriginalStoreCacheType] integerValue]; + } + // Disable transformer for original cache key generation + SDWebImageMutableContext *tempContext = [context mutableCopy]; + tempContext[SDWebImageContextImageTransformer] = [NSNull null]; + NSString *key = [self cacheKeyForURL:url context:tempContext]; + id transformer = context[SDWebImageContextImageTransformer]; + if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) { + transformer = nil; + } + id cacheSerializer = context[SDWebImageContextCacheSerializer]; + + BOOL shouldTransformImage = downloadedImage && transformer; + shouldTransformImage = shouldTransformImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)); + shouldTransformImage = shouldTransformImage && (!downloadedImage.sd_isVector || (options & SDWebImageTransformVectorImage)); + BOOL shouldCacheOriginal = downloadedImage && finished; + + // if available, store original image to cache + if (shouldCacheOriginal) { + // normally use the store cache type, but if target image is transformed, use original store cache type instead + SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType; + if (cacheSerializer && (targetStoreCacheType == SDImageCacheTypeDisk || targetStoreCacheType == SDImageCacheTypeAll)) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + @autoreleasepool { + NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url]; + [self storeImage:downloadedImage imageData:cacheData forKey:key imageCache:imageCache cacheType:targetStoreCacheType options:options context:context completion:^{ + // Continue transform process + [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock]; + }]; + } + }); + } else { + [self storeImage:downloadedImage imageData:downloadedData forKey:key imageCache:imageCache cacheType:targetStoreCacheType options:options context:context completion:^{ + // Continue transform process + [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock]; + }]; + } + } else { + // Continue transform process + [self callTransformProcessForOperation:operation url:url options:options context:context originalImage:downloadedImage originalData:downloadedData finished:finished progress:progressBlock completed:completedBlock]; + } +} + +// Transform process +- (void)callTransformProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation + url:(nonnull NSURL *)url + options:(SDWebImageOptions)options + context:(SDWebImageContext *)context + originalImage:(nullable UIImage *)originalImage + originalData:(nullable NSData *)originalData + finished:(BOOL)finished + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + // Grab the image cache to use + id imageCache; + if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) { + imageCache = context[SDWebImageContextImageCache]; + } else { + imageCache = self.imageCache; + } + // the target image store cache type + SDImageCacheType storeCacheType = SDImageCacheTypeAll; + if (context[SDWebImageContextStoreCacheType]) { + storeCacheType = [context[SDWebImageContextStoreCacheType] integerValue]; + } + // transformed cache key + NSString *key = [self cacheKeyForURL:url context:context]; + id transformer = context[SDWebImageContextImageTransformer]; + if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) { + transformer = nil; + } + id cacheSerializer = context[SDWebImageContextCacheSerializer]; + + BOOL shouldTransformImage = originalImage && transformer; + shouldTransformImage = shouldTransformImage && (!originalImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)); + shouldTransformImage = shouldTransformImage && (!originalImage.sd_isVector || (options & SDWebImageTransformVectorImage)); + // if available, store transformed image to cache + if (shouldTransformImage) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + @autoreleasepool { + UIImage *transformedImage = [transformer transformedImageWithImage:originalImage forKey:key]; + if (transformedImage && finished) { + BOOL imageWasTransformed = ![transformedImage isEqual:originalImage]; + NSData *cacheData; + // pass nil if the image was transformed, so we can recalculate the data from the image + if (cacheSerializer && (storeCacheType == SDImageCacheTypeDisk || storeCacheType == SDImageCacheTypeAll)) { + cacheData = [cacheSerializer cacheDataWithImage:transformedImage originalData:(imageWasTransformed ? nil : originalData) imageURL:url]; + } else { + cacheData = (imageWasTransformed ? nil : originalData); + } + [self storeImage:transformedImage imageData:cacheData forKey:key imageCache:imageCache cacheType:storeCacheType options:options context:context completion:^{ + [self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; + }]; + } else { + [self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; + } + } + }); + } else { + [self callCompletionBlockForOperation:operation completion:completedBlock image:originalImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; + } +} + +#pragma mark - Helper + +- (void)safelyRemoveOperationFromRunning:(nullable SDWebImageCombinedOperation*)operation { + if (!operation) { + return; + } + SD_LOCK(_runningOperationsLock); + [self.runningOperations removeObject:operation]; + SD_UNLOCK(_runningOperationsLock); +} + +- (void)storeImage:(nullable UIImage *)image + imageData:(nullable NSData *)data + forKey:(nullable NSString *)key + imageCache:(nonnull id)imageCache + cacheType:(SDImageCacheType)cacheType + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + completion:(nullable SDWebImageNoParamsBlock)completion { + BOOL waitStoreCache = SD_OPTIONS_CONTAINS(options, SDWebImageWaitStoreCache); + // Check whether we should wait the store cache finished. If not, callback immediately + [imageCache storeImage:image imageData:data forKey:key cacheType:cacheType completion:^{ + if (waitStoreCache) { + if (completion) { + completion(); + } + } + }]; + if (!waitStoreCache) { + if (completion) { + completion(); + } + } +} + +- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation + completion:(nullable SDInternalCompletionBlock)completionBlock + error:(nullable NSError *)error + url:(nullable NSURL *)url { + [self callCompletionBlockForOperation:operation completion:completionBlock image:nil data:nil error:error cacheType:SDImageCacheTypeNone finished:YES url:url]; +} + +- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation + completion:(nullable SDInternalCompletionBlock)completionBlock + image:(nullable UIImage *)image + data:(nullable NSData *)data + error:(nullable NSError *)error + cacheType:(SDImageCacheType)cacheType + finished:(BOOL)finished + url:(nullable NSURL *)url { + dispatch_main_async_safe(^{ + if (completionBlock) { + completionBlock(image, data, error, cacheType, finished, url); + } + }); +} + +- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url + error:(nonnull NSError *)error + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context { + id imageLoader; + if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) { + imageLoader = context[SDWebImageContextImageLoader]; + } else { + imageLoader = self.imageLoader; + } + // Check whether we should block failed url + BOOL shouldBlockFailedURL; + if ([self.delegate respondsToSelector:@selector(imageManager:shouldBlockFailedURL:withError:)]) { + shouldBlockFailedURL = [self.delegate imageManager:self shouldBlockFailedURL:url withError:error]; + } else { + if ([imageLoader respondsToSelector:@selector(shouldBlockFailedURLWithURL:error:options:context:)]) { + shouldBlockFailedURL = [imageLoader shouldBlockFailedURLWithURL:url error:error options:options context:context]; + } else { + shouldBlockFailedURL = [imageLoader shouldBlockFailedURLWithURL:url error:error]; + } + } + + return shouldBlockFailedURL; +} + +- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context { + SDWebImageOptionsResult *result; + SDWebImageMutableContext *mutableContext = [SDWebImageMutableContext dictionary]; + + // Image Transformer from manager + if (!context[SDWebImageContextImageTransformer]) { + id transformer = self.transformer; + [mutableContext setValue:transformer forKey:SDWebImageContextImageTransformer]; + } + // Cache key filter from manager + if (!context[SDWebImageContextCacheKeyFilter]) { + id cacheKeyFilter = self.cacheKeyFilter; + [mutableContext setValue:cacheKeyFilter forKey:SDWebImageContextCacheKeyFilter]; + } + // Cache serializer from manager + if (!context[SDWebImageContextCacheSerializer]) { + id cacheSerializer = self.cacheSerializer; + [mutableContext setValue:cacheSerializer forKey:SDWebImageContextCacheSerializer]; + } + + if (mutableContext.count > 0) { + if (context) { + [mutableContext addEntriesFromDictionary:context]; + } + context = [mutableContext copy]; + } + + // Apply options processor + if (self.optionsProcessor) { + result = [self.optionsProcessor processedResultForURL:url options:options context:context]; + } + if (!result) { + // Use default options result + result = [[SDWebImageOptionsResult alloc] initWithOptions:options context:context]; + } + + return result; +} + +@end + + +@implementation SDWebImageCombinedOperation + +- (void)cancel { + @synchronized(self) { + if (self.isCancelled) { + return; + } + self.cancelled = YES; + if (self.cacheOperation) { + [self.cacheOperation cancel]; + self.cacheOperation = nil; + } + if (self.loaderOperation) { + [self.loaderOperation cancel]; + self.loaderOperation = nil; + } + [self.manager safelyRemoveOperationFromRunning:self]; + } +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.h new file mode 100644 index 00000000..50266db1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.h @@ -0,0 +1,21 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import + +/// A protocol represents cancelable operation. +@protocol SDWebImageOperation + +- (void)cancel; + +@end + +/// NSOperation conform to `SDWebImageOperation`. +@interface NSOperation (SDWebImageOperation) + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.m new file mode 100644 index 00000000..0d6e880d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOperation.m @@ -0,0 +1,14 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageOperation.h" + +/// NSOperation conform to `SDWebImageOperation`. +@implementation NSOperation (SDWebImageOperation) + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.h new file mode 100644 index 00000000..31ef153f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.h @@ -0,0 +1,72 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" + +@class SDWebImageOptionsResult; + +typedef SDWebImageOptionsResult * _Nullable(^SDWebImageOptionsProcessorBlock)(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context); + +/** + The options result contains both options and context. + */ +@interface SDWebImageOptionsResult : NSObject + +/** + WebCache options. + */ +@property (nonatomic, assign, readonly) SDWebImageOptions options; + +/** + Context options. + */ +@property (nonatomic, copy, readonly, nullable) SDWebImageContext *context; + +/** + Create a new options result. + + @param options options + @param context context + @return The options result contains both options and context. + */ +- (nonnull instancetype)initWithOptions:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context; + +@end + +/** + This is the protocol for options processor. + Options processor can be used, to control the final result for individual image request's `SDWebImageOptions` and `SDWebImageContext` + Implements the protocol to have a global control for each indivadual image request's option. + */ +@protocol SDWebImageOptionsProcessor + +/** + Return the processed options result for specify image URL, with its options and context + + @param url The URL to the image + @param options A mask to specify options to use for this request + @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + @return The processed result, contains both options and context + */ +- (nullable SDWebImageOptionsResult *)processedResultForURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +@end + +/** + A options processor class with block. + */ +@interface SDWebImageOptionsProcessor : NSObject + +- (nonnull instancetype)initWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block; ++ (nonnull instancetype)optionsProcessorWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.m new file mode 100644 index 00000000..8e7bc35d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageOptionsProcessor.m @@ -0,0 +1,59 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageOptionsProcessor.h" + +@interface SDWebImageOptionsResult () + +@property (nonatomic, assign) SDWebImageOptions options; +@property (nonatomic, copy, nullable) SDWebImageContext *context; + +@end + +@implementation SDWebImageOptionsResult + +- (instancetype)initWithOptions:(SDWebImageOptions)options context:(SDWebImageContext *)context { + self = [super init]; + if (self) { + self.options = options; + self.context = context; + } + return self; +} + +@end + +@interface SDWebImageOptionsProcessor () + +@property (nonatomic, copy, nonnull) SDWebImageOptionsProcessorBlock block; + +@end + +@implementation SDWebImageOptionsProcessor + +- (instancetype)initWithBlock:(SDWebImageOptionsProcessorBlock)block { + self = [super init]; + if (self) { + self.block = block; + } + return self; +} + ++ (instancetype)optionsProcessorWithBlock:(SDWebImageOptionsProcessorBlock)block { + SDWebImageOptionsProcessor *optionsProcessor = [[SDWebImageOptionsProcessor alloc] initWithBlock:block]; + return optionsProcessor; +} + +- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context { + if (!self.block) { + return nil; + } + return self.block(url, options, context); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.h new file mode 100644 index 00000000..a9b2c1f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.h @@ -0,0 +1,143 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageManager.h" + +@class SDWebImagePrefetcher; + +/** + A token represents a list of URLs, can be used to cancel the download. + */ +@interface SDWebImagePrefetchToken : NSObject + +/** + * Cancel the current prefetching. + */ +- (void)cancel; + +/** + list of URLs of current prefetching. + */ +@property (nonatomic, copy, readonly, nullable) NSArray *urls; + +@end + +/** + The prefetcher delegate protocol + */ +@protocol SDWebImagePrefetcherDelegate + +@optional + +/** + * Called when an image was prefetched. Which means it's called when one URL from any of prefetching finished. + * + * @param imagePrefetcher The current image prefetcher + * @param imageURL The image url that was prefetched + * @param finishedCount The total number of images that were prefetched (successful or not) + * @param totalCount The total number of images that were to be prefetched + */ +- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; + +/** + * Called when all images are prefetched. Which means it's called when all URLs from all of prefetching finished. + * @param imagePrefetcher The current image prefetcher + * @param totalCount The total number of images that were prefetched (whether successful or not) + * @param skippedCount The total number of images that were skipped + */ +- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; + +@end + +typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls); +typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls); + +/** + * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. + */ +@interface SDWebImagePrefetcher : NSObject + +/** + * The web image manager used by prefetcher to prefetch images. + * @note You can specify a standalone manager and downloader with custom configuration suitable for image prefetching. Such as `currentDownloadCount` or `downloadTimeout`. + */ +@property (strong, nonatomic, readonly, nonnull) SDWebImageManager *manager; + +/** + * Maximum number of URLs to prefetch at the same time. Defaults to 3. + */ +@property (nonatomic, assign) NSUInteger maxConcurrentPrefetchCount; + +/** + * The options for prefetcher. Defaults to SDWebImageLowPriority. + */ +@property (nonatomic, assign) SDWebImageOptions options; + +/** + * The context for prefetcher. Defaults to nil. + */ +@property (nonatomic, copy, nullable) SDWebImageContext *context; + +/** + * Queue options for prefetcher when call the progressBlock, completionBlock and delegate methods. Defaults to Main Queue. + * @note The call is asynchronously to avoid blocking target queue. + * @note The delegate queue should be set before any prefetching start and may not be changed during prefetching to avoid thread-safe problem. + */ +@property (strong, nonatomic, nonnull) dispatch_queue_t delegateQueue; + +/** + * The delegate for the prefetcher. Defaults to nil. + */ +@property (weak, nonatomic, nullable) id delegate; + +/** + * Returns the global shared image prefetcher instance. It use a standalone manager which is different from shared manager. + */ +@property (nonatomic, class, readonly, nonnull) SDWebImagePrefetcher *sharedImagePrefetcher; + +/** + * Allows you to instantiate a prefetcher with any arbitrary image manager. + */ +- (nonnull instancetype)initWithImageManager:(nonnull SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER; + +/** + * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property. + * Prefetching is separate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls. + * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch. + * + * @param urls list of URLs to prefetch + * @return the token to cancel the current prefetching. + */ +- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray *)urls; + +/** + * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching. It based on the image manager so the image may from the cache and network according to the `options` property. + * Prefetching is separate to each other, which means the progressBlock and completionBlock you provide is bind to the prefetching for the list of urls. + * Attention that call this will not cancel previous fetched urls. You should keep the token return by this to cancel or cancel all the prefetch. + * + * @param urls list of URLs to prefetch + * @param progressBlock block to be called when progress updates; + * first parameter is the number of completed (successful or not) requests, + * second parameter is the total number of images originally requested to be prefetched + * @param completionBlock block to be called when the current prefetching is completed + * first param is the number of completed (successful or not) requests, + * second parameter is the number of skipped requests + * @return the token to cancel the current prefetching. + */ +- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray *)urls + progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock + completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock; + +/** + * Remove and cancel all the prefeching for the prefetcher. + */ +- (void)cancelPrefetching; + + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.m new file mode 100644 index 00000000..b6632fa6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImagePrefetcher.m @@ -0,0 +1,305 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImagePrefetcher.h" +#import "SDAsyncBlockOperation.h" +#import "SDInternalMacros.h" +#import + +@interface SDWebImagePrefetchToken () { + @public + // Though current implementation, `SDWebImageManager` completion block is always on main queue. But however, there is no guarantee in docs. And we may introduce config to specify custom queue in the future. + // These value are just used as incrementing counter, keep thread-safe using memory_order_relaxed for performance. + atomic_ulong _skippedCount; + atomic_ulong _finishedCount; + atomic_flag _isAllFinished; + + unsigned long _totalCount; + + // Used to ensure NSPointerArray thread safe + SD_LOCK_DECLARE(_prefetchOperationsLock); + SD_LOCK_DECLARE(_loadOperationsLock); +} + +@property (nonatomic, copy, readwrite) NSArray *urls; +@property (nonatomic, strong) NSPointerArray *loadOperations; +@property (nonatomic, strong) NSPointerArray *prefetchOperations; +@property (nonatomic, weak) SDWebImagePrefetcher *prefetcher; +@property (nonatomic, copy, nullable) SDWebImagePrefetcherCompletionBlock completionBlock; +@property (nonatomic, copy, nullable) SDWebImagePrefetcherProgressBlock progressBlock; + +@end + +@interface SDWebImagePrefetcher () + +@property (strong, nonatomic, nonnull) SDWebImageManager *manager; +@property (strong, atomic, nonnull) NSMutableSet *runningTokens; +@property (strong, nonatomic, nonnull) NSOperationQueue *prefetchQueue; + +@end + +@implementation SDWebImagePrefetcher + ++ (nonnull instancetype)sharedImagePrefetcher { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (nonnull instancetype)init { + return [self initWithImageManager:[SDWebImageManager new]]; +} + +- (nonnull instancetype)initWithImageManager:(SDWebImageManager *)manager { + if ((self = [super init])) { + _manager = manager; + _runningTokens = [NSMutableSet set]; + _options = SDWebImageLowPriority; + _delegateQueue = dispatch_get_main_queue(); + _prefetchQueue = [NSOperationQueue new]; + self.maxConcurrentPrefetchCount = 3; + } + return self; +} + +- (void)setMaxConcurrentPrefetchCount:(NSUInteger)maxConcurrentPrefetchCount { + self.prefetchQueue.maxConcurrentOperationCount = maxConcurrentPrefetchCount; +} + +- (NSUInteger)maxConcurrentPrefetchCount { + return self.prefetchQueue.maxConcurrentOperationCount; +} + +#pragma mark - Prefetch +- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray *)urls { + return [self prefetchURLs:urls progress:nil completed:nil]; +} + +- (nullable SDWebImagePrefetchToken *)prefetchURLs:(nullable NSArray *)urls + progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock + completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock { + if (!urls || urls.count == 0) { + if (completionBlock) { + completionBlock(0, 0); + } + return nil; + } + SDWebImagePrefetchToken *token = [SDWebImagePrefetchToken new]; + token.prefetcher = self; + token.urls = urls; + token->_skippedCount = 0; + token->_finishedCount = 0; + token->_totalCount = token.urls.count; + atomic_flag_clear(&(token->_isAllFinished)); + token.loadOperations = [NSPointerArray weakObjectsPointerArray]; + token.prefetchOperations = [NSPointerArray weakObjectsPointerArray]; + token.progressBlock = progressBlock; + token.completionBlock = completionBlock; + [self addRunningToken:token]; + [self startPrefetchWithToken:token]; + + return token; +} + +- (void)startPrefetchWithToken:(SDWebImagePrefetchToken * _Nonnull)token { + for (NSURL *url in token.urls) { + @autoreleasepool { + @weakify(self); + SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) { + @strongify(self); + if (!self || asyncOperation.isCancelled) { + return; + } + id operation = [self.manager loadImageWithURL:url options:self.options context:self.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + @strongify(self); + if (!self) { + return; + } + if (!finished) { + return; + } + atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed); + if (error) { + // Add last failed + atomic_fetch_add_explicit(&(token->_skippedCount), 1, memory_order_relaxed); + } + + // Current operation finished + [self callProgressBlockForToken:token imageURL:imageURL]; + + if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) == token->_totalCount) { + // All finished + if (!atomic_flag_test_and_set_explicit(&(token->_isAllFinished), memory_order_relaxed)) { + [self callCompletionBlockForToken:token]; + [self removeRunningToken:token]; + } + } + [asyncOperation complete]; + }]; + NSAssert(operation != nil, @"Operation should not be nil, [SDWebImageManager loadImageWithURL:options:context:progress:completed:] break prefetch logic"); + SD_LOCK(token->_loadOperationsLock); + [token.loadOperations addPointer:(__bridge void *)operation]; + SD_UNLOCK(token->_loadOperationsLock); + }]; + SD_LOCK(token->_prefetchOperationsLock); + [token.prefetchOperations addPointer:(__bridge void *)prefetchOperation]; + SD_UNLOCK(token->_prefetchOperationsLock); + [self.prefetchQueue addOperation:prefetchOperation]; + } + } +} + +#pragma mark - Cancel +- (void)cancelPrefetching { + @synchronized(self.runningTokens) { + NSSet *copiedTokens = [self.runningTokens copy]; + [copiedTokens makeObjectsPerformSelector:@selector(cancel)]; + [self.runningTokens removeAllObjects]; + } +} + +- (void)callProgressBlockForToken:(SDWebImagePrefetchToken *)token imageURL:(NSURL *)url { + if (!token) { + return; + } + BOOL shouldCallDelegate = [self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]; + NSUInteger tokenFinishedCount = [self tokenFinishedCount]; + NSUInteger tokenTotalCount = [self tokenTotalCount]; + NSUInteger finishedCount = atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed); + NSUInteger totalCount = token->_totalCount; + dispatch_async(self.delegateQueue, ^{ + if (shouldCallDelegate) { + [self.delegate imagePrefetcher:self didPrefetchURL:url finishedCount:tokenFinishedCount totalCount:tokenTotalCount]; + } + if (token.progressBlock) { + token.progressBlock(finishedCount, totalCount); + } + }); +} + +- (void)callCompletionBlockForToken:(SDWebImagePrefetchToken *)token { + if (!token) { + return; + } + BOOL shoulCallDelegate = [self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)] && ([self countOfRunningTokens] == 1); // last one + NSUInteger tokenTotalCount = [self tokenTotalCount]; + NSUInteger tokenSkippedCount = [self tokenSkippedCount]; + NSUInteger finishedCount = atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed); + NSUInteger skippedCount = atomic_load_explicit(&(token->_skippedCount), memory_order_relaxed); + dispatch_async(self.delegateQueue, ^{ + if (shoulCallDelegate) { + [self.delegate imagePrefetcher:self didFinishWithTotalCount:tokenTotalCount skippedCount:tokenSkippedCount]; + } + if (token.completionBlock) { + token.completionBlock(finishedCount, skippedCount); + } + }); +} + +#pragma mark - Helper +- (NSUInteger)tokenTotalCount { + NSUInteger tokenTotalCount = 0; + @synchronized (self.runningTokens) { + for (SDWebImagePrefetchToken *token in self.runningTokens) { + tokenTotalCount += token->_totalCount; + } + } + return tokenTotalCount; +} + +- (NSUInteger)tokenSkippedCount { + NSUInteger tokenSkippedCount = 0; + @synchronized (self.runningTokens) { + for (SDWebImagePrefetchToken *token in self.runningTokens) { + tokenSkippedCount += atomic_load_explicit(&(token->_skippedCount), memory_order_relaxed); + } + } + return tokenSkippedCount; +} + +- (NSUInteger)tokenFinishedCount { + NSUInteger tokenFinishedCount = 0; + @synchronized (self.runningTokens) { + for (SDWebImagePrefetchToken *token in self.runningTokens) { + tokenFinishedCount += atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed); + } + } + return tokenFinishedCount; +} + +- (void)addRunningToken:(SDWebImagePrefetchToken *)token { + if (!token) { + return; + } + @synchronized (self.runningTokens) { + [self.runningTokens addObject:token]; + } +} + +- (void)removeRunningToken:(SDWebImagePrefetchToken *)token { + if (!token) { + return; + } + @synchronized (self.runningTokens) { + [self.runningTokens removeObject:token]; + } +} + +- (NSUInteger)countOfRunningTokens { + NSUInteger count = 0; + @synchronized (self.runningTokens) { + count = self.runningTokens.count; + } + return count; +} + +@end + +@implementation SDWebImagePrefetchToken + +- (instancetype)init { + self = [super init]; + if (self) { + SD_LOCK_INIT(_prefetchOperationsLock); + SD_LOCK_INIT(_loadOperationsLock); + } + return self; +} + +- (void)cancel { + SD_LOCK(_prefetchOperationsLock); + [self.prefetchOperations compact]; + for (id operation in self.prefetchOperations) { + id strongOperation = operation; + if (strongOperation) { + [strongOperation cancel]; + } + } + self.prefetchOperations.count = 0; + SD_UNLOCK(_prefetchOperationsLock); + + SD_LOCK(_loadOperationsLock); + [self.loadOperations compact]; + for (id operation in self.loadOperations) { + id strongOperation = operation; + if (strongOperation) { + [strongOperation cancel]; + } + } + self.loadOperations.count = 0; + SD_UNLOCK(_loadOperationsLock); + + self.completionBlock = nil; + self.progressBlock = nil; + [self.prefetcher removeRunningToken:self]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.h new file mode 100644 index 00000000..889372e4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.h @@ -0,0 +1,131 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_UIKIT || SD_MAC +#import "SDImageCache.h" + +#if SD_UIKIT +typedef UIViewAnimationOptions SDWebImageAnimationOptions; +#else +typedef NS_OPTIONS(NSUInteger, SDWebImageAnimationOptions) { + SDWebImageAnimationOptionAllowsImplicitAnimation = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext` + + SDWebImageAnimationOptionCurveEaseInOut = 0 << 16, // default + SDWebImageAnimationOptionCurveEaseIn = 1 << 16, + SDWebImageAnimationOptionCurveEaseOut = 2 << 16, + SDWebImageAnimationOptionCurveLinear = 3 << 16, + + SDWebImageAnimationOptionTransitionNone = 0 << 20, // default + SDWebImageAnimationOptionTransitionFlipFromLeft = 1 << 20, + SDWebImageAnimationOptionTransitionFlipFromRight = 2 << 20, + SDWebImageAnimationOptionTransitionCurlUp = 3 << 20, + SDWebImageAnimationOptionTransitionCurlDown = 4 << 20, + SDWebImageAnimationOptionTransitionCrossDissolve = 5 << 20, + SDWebImageAnimationOptionTransitionFlipFromTop = 6 << 20, + SDWebImageAnimationOptionTransitionFlipFromBottom = 7 << 20, +}; +#endif + +typedef void (^SDWebImageTransitionPreparesBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL); +typedef void (^SDWebImageTransitionAnimationsBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image); +typedef void (^SDWebImageTransitionCompletionBlock)(BOOL finished); + +/** + This class is used to provide a transition animation after the view category load image finished. Use this on `sd_imageTransition` in UIView+WebCache.h + for UIKit(iOS & tvOS), we use `+[UIView transitionWithView:duration:options:animations:completion]` for transition animation. + for AppKit(macOS), we use `+[NSAnimationContext runAnimationGroup:completionHandler:]` for transition animation. You can call `+[NSAnimationContext currentContext]` to grab the context during animations block. + @note These transition are provided for basic usage. If you need complicated animation, consider to directly use Core Animation or use `SDWebImageAvoidAutoSetImage` and implement your own after image load finished. + */ +@interface SDWebImageTransition : NSObject + +/** + By default, we set the image to the view at the beginning of the animations. You can disable this and provide custom set image process + */ +@property (nonatomic, assign) BOOL avoidAutoSetImage; +/** + The duration of the transition animation, measured in seconds. Defaults to 0.5. + */ +@property (nonatomic, assign) NSTimeInterval duration; +/** + The timing function used for all animations within this transition animation (macOS). + */ +@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction API_UNAVAILABLE(ios, tvos, watchos) API_DEPRECATED("Use SDWebImageAnimationOptions instead, or grab NSAnimationContext.currentContext and modify the timingFunction", macos(10.10, 10.10)); +/** + A mask of options indicating how you want to perform the animations. + */ +@property (nonatomic, assign) SDWebImageAnimationOptions animationOptions; +/** + A block object to be executed before the animation sequence starts. + */ +@property (nonatomic, copy, nullable) SDWebImageTransitionPreparesBlock prepares; +/** + A block object that contains the changes you want to make to the specified view. + */ +@property (nonatomic, copy, nullable) SDWebImageTransitionAnimationsBlock animations; +/** + A block object to be executed when the animation sequence ends. + */ +@property (nonatomic, copy, nullable) SDWebImageTransitionCompletionBlock completion; + +@end + +/** + Convenience way to create transition. Remember to specify the duration if needed. + for UIKit, these transition just use the correspond `animationOptions`. By default we enable `UIViewAnimationOptionAllowUserInteraction` to allow user interaction during transition. + for AppKit, these transition use Core Animation in `animations`. So your view must be layer-backed. Set `wantsLayer = YES` before you apply it. + */ +@interface SDWebImageTransition (Conveniences) + +/// Fade-in transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *fadeTransition; +/// Flip from left transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromLeftTransition; +/// Flip from right transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromRightTransition; +/// Flip from top transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromTopTransition; +/// Flip from bottom transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromBottomTransition; +/// Curl up transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlUpTransition; +/// Curl down transition. +@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlDownTransition; + +/// Fade-in transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)fadeTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(fade(duration:)); + +/// Flip from left transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)flipFromLeftTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromLeft(duration:)); + +/// Flip from right transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)flipFromRightTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromRight(duration:)); + +/// Flip from top transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)flipFromTopTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromTop(duration:)); + +/// Flip from bottom transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)flipFromBottomTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(flipFromBottom(duration:)); + +/// Curl up transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)curlUpTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(curlUp(duration:)); + +/// Curl down transition with duration. +/// @param duration transition duration, use ease-in-out ++ (nonnull instancetype)curlDownTransitionWithDuration:(NSTimeInterval)duration NS_SWIFT_NAME(curlDown(duration:)); + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.m new file mode 100644 index 00000000..4990a732 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/SDWebImageTransition.m @@ -0,0 +1,194 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageTransition.h" + +#if SD_UIKIT || SD_MAC + +#if SD_MAC +#import "SDWebImageTransitionInternal.h" +#import "SDInternalMacros.h" + +CAMediaTimingFunction * SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options) { + if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveLinear, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseIn, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseOut, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseInOut, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + } else { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; + } +} + +CATransition * SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options) { + if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCrossDissolve)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionFade; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromLeft)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromLeft; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromRight)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromRight; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromTop)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromTop; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromBottom)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromBottom; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlUp)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromTop; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlDown)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromBottom; + return trans; + } else { + return nil; + } +} +#endif + +@implementation SDWebImageTransition + +- (instancetype)init { + self = [super init]; + if (self) { + self.duration = 0.5; + } + return self; +} + +@end + +@implementation SDWebImageTransition (Conveniences) + ++ (SDWebImageTransition *)fadeTransition { + return [self fadeTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)fadeTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionCrossDissolve; +#endif + return transition; +} + ++ (SDWebImageTransition *)flipFromLeftTransition { + return [self flipFromLeftTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)flipFromLeftTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromLeft; +#endif + return transition; +} + ++ (SDWebImageTransition *)flipFromRightTransition { + return [self flipFromRightTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)flipFromRightTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromRight; +#endif + return transition; +} + ++ (SDWebImageTransition *)flipFromTopTransition { + return [self flipFromTopTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)flipFromTopTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionFlipFromTop | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromTop; +#endif + return transition; +} + ++ (SDWebImageTransition *)flipFromBottomTransition { + return [self flipFromBottomTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)flipFromBottomTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionFlipFromBottom | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromBottom; +#endif + return transition; +} + ++ (SDWebImageTransition *)curlUpTransition { + return [self curlUpTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)curlUpTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionCurlUp | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionCurlUp; +#endif + return transition; +} + ++ (SDWebImageTransition *)curlDownTransition { + return [self curlDownTransitionWithDuration:0.5]; +} + ++ (SDWebImageTransition *)curlDownTransitionWithDuration:(NSTimeInterval)duration { + SDWebImageTransition *transition = [SDWebImageTransition new]; + transition.duration = duration; +#if SD_UIKIT + transition.animationOptions = UIViewAnimationOptionTransitionCurlDown | UIViewAnimationOptionAllowUserInteraction; +#else + transition.animationOptions = SDWebImageAnimationOptionTransitionCurlDown; +#endif + transition.duration = duration; + return transition; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.h new file mode 100644 index 00000000..89d94b46 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.h @@ -0,0 +1,387 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_UIKIT + +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIButton. + */ +@interface UIButton (WebCache) + +#pragma mark - Image + +/** + * Get the current image URL. + */ +@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentImageURL; + +/** + * Get the image URL for a control state. + * + * @param state Which state you want to know the URL for. The values are described in UIControlState. + */ +- (nullable NSURL *)sd_imageURLForState:(UIControlState)state; + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +#pragma mark - Background Image + +/** + * Get the current background image URL. + */ +@property (nonatomic, strong, readonly, nullable) NSURL *sd_currentBackgroundImageURL; + +/** + * Get the background image URL for a control state. + * + * @param state Which state you want to know the URL for. The values are described in UIControlState. + */ +- (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state; + +/** + * Set the button `backgroundImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state NS_REFINED_FOR_SWIFT; + +/** + * Set the button `backgroundImage` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `backgroundImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `backgroundImage` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the button `backgroundImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `backgroundImage` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `backgroundImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `backgroundImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `backgroundImage` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +#pragma mark - Cancel + +/** + * Cancel the current image download + */ +- (void)sd_cancelImageLoadForState:(UIControlState)state; + +/** + * Cancel the current backgroundImage download + */ +- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.m new file mode 100644 index 00000000..4ccd0291 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIButton+WebCache.m @@ -0,0 +1,234 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIButton+WebCache.h" + +#if SD_UIKIT + +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" +#import "UIView+WebCache.h" +#import "SDInternalMacros.h" + +static char imageURLStorageKey; + +typedef NSMutableDictionary SDStateImageURLDictionary; + +static inline NSString * imageURLKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"image_%lu", (unsigned long)state]; +} + +static inline NSString * backgroundImageURLKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"backgroundImage_%lu", (unsigned long)state]; +} + +static inline NSString * imageOperationKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"UIButtonImageOperation%lu", (unsigned long)state]; +} + +static inline NSString * backgroundImageOperationKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"UIButtonBackgroundImageOperation%lu", (unsigned long)state]; +} + +@implementation UIButton (WebCache) + +#pragma mark - Image + +- (nullable NSURL *)sd_currentImageURL { + NSURL *url = self.sd_imageURLStorage[imageURLKeyForState(self.state)]; + + if (!url) { + url = self.sd_imageURLStorage[imageURLKeyForState(UIControlStateNormal)]; + } + + return url; +} + +- (nullable NSURL *)sd_imageURLForState:(UIControlState)state { + return self.sd_imageURLStorage[imageURLKeyForState(state)]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + if (!url) { + [self.sd_imageURLStorage removeObjectForKey:imageURLKeyForState(state)]; + } else { + self.sd_imageURLStorage[imageURLKeyForState(state)] = url; + } + + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextSetImageOperationKey] = imageOperationKeyForState(state); + @weakify(self); + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:mutableContext + setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + @strongify(self); + [self setImage:image forState:state]; + } + progress:progressBlock + completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +#pragma mark - Background Image + +- (nullable NSURL *)sd_currentBackgroundImageURL { + NSURL *url = self.sd_imageURLStorage[backgroundImageURLKeyForState(self.state)]; + + if (!url) { + url = self.sd_imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)]; + } + + return url; +} + +- (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state { + return self.sd_imageURLStorage[backgroundImageURLKeyForState(state)]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url + forState:(UIControlState)state + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + if (!url) { + [self.sd_imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)]; + } else { + self.sd_imageURLStorage[backgroundImageURLKeyForState(state)] = url; + } + + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextSetImageOperationKey] = backgroundImageOperationKeyForState(state); + @weakify(self); + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:mutableContext + setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + @strongify(self); + [self setBackgroundImage:image forState:state]; + } + progress:progressBlock + completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +#pragma mark - Cancel + +- (void)sd_cancelImageLoadForState:(UIControlState)state { + [self sd_cancelImageLoadOperationWithKey:imageOperationKeyForState(state)]; +} + +- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state { + [self sd_cancelImageLoadOperationWithKey:backgroundImageOperationKeyForState(state)]; +} + +#pragma mark - Private + +- (SDStateImageURLDictionary *)sd_imageURLStorage { + SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); + if (!storage) { + storage = [NSMutableDictionary dictionary]; + objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + + return storage; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.h new file mode 100644 index 00000000..482c8c40 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.h @@ -0,0 +1,24 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* (c) Fabrice Aneche +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" + +@interface UIImage (ExtendedCacheData) + +/** + Read and Write the extended object and bind it to the image. Which can hold some extra metadata like Image's scale factor, URL rich link, date, etc. + The extended object should conforms to NSCoding, which we use `NSKeyedArchiver` and `NSKeyedUnarchiver` to archive it to data, and write to disk cache. + @note The disk cache preserve both of the data and extended data with the same cache key. For manual query, use the `SDDiskCache` protocol method `extendedDataForKey:` instead. + @note You can specify arbitrary object conforms to NSCoding (NSObject protocol here is used to support object using `NS_ROOT_CLASS`, which is not NSObject subclass). If you load image from disk cache, you should check the extended object class to avoid corrupted data. + @warning This object don't need to implements NSSecureCoding (but it's recommended), because we allows arbitrary class. + */ +@property (nonatomic, strong, nullable) id sd_extendedObject; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.m new file mode 100644 index 00000000..05d29cff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ExtendedCacheData.m @@ -0,0 +1,23 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* (c) Fabrice Aneche +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "UIImage+ExtendedCacheData.h" +#import + +@implementation UIImage (ExtendedCacheData) + +- (id)sd_extendedObject { + return objc_getAssociatedObject(self, @selector(sd_extendedObject)); +} + +- (void)setSd_extendedObject:(id)sd_extendedObject { + objc_setAssociatedObject(self, @selector(sd_extendedObject), sd_extendedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.h new file mode 100644 index 00000000..f3687467 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.h @@ -0,0 +1,46 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +/** + UIImage category about force decode feature (avoid Image/IO's lazy decoding during rendering behavior). + */ +@interface UIImage (ForceDecode) + +/** + A bool value indicating whether the image has already been decoded. This can help to avoid extra force decode. + */ +@property (nonatomic, assign) BOOL sd_isDecoded; + +/** + Decode the provided image. This is useful if you want to force decode the image before rendering to improve performance. + + @param image The image to be decoded + @return The decoded image + */ ++ (nullable UIImage *)sd_decodedImageWithImage:(nullable UIImage *)image; + +/** + Decode and scale down the provided image + + @param image The image to be decoded + @return The decoded and scaled down image + */ ++ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image; + +/** + Decode and scale down the provided image with limit bytes + + @param image The image to be decoded + @param bytes The limit bytes size. Provide 0 to use the build-in limit. + @return The decoded and scaled down image + */ ++ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image limitBytes:(NSUInteger)bytes; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.m new file mode 100644 index 00000000..1b20bbd7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+ForceDecode.m @@ -0,0 +1,42 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+ForceDecode.h" +#import "SDImageCoderHelper.h" +#import "objc/runtime.h" + +@implementation UIImage (ForceDecode) + +- (BOOL)sd_isDecoded { + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isDecoded)); + return value.boolValue; +} + +- (void)setSd_isDecoded:(BOOL)sd_isDecoded { + objc_setAssociatedObject(self, @selector(sd_isDecoded), @(sd_isDecoded), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + ++ (nullable UIImage *)sd_decodedImageWithImage:(nullable UIImage *)image { + if (!image) { + return nil; + } + return [SDImageCoderHelper decodedImageWithImage:image]; +} + ++ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image { + return [self sd_decodedAndScaledDownImageWithImage:image limitBytes:0]; +} + ++ (nullable UIImage *)sd_decodedAndScaledDownImageWithImage:(nullable UIImage *)image limitBytes:(NSUInteger)bytes { + if (!image) { + return nil; + } + return [SDImageCoderHelper decodedAndScaledDownImageWithImage:image limitBytes:bytes]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.h new file mode 100644 index 00000000..5da8e197 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.h @@ -0,0 +1,26 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Laurin Brandner + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +/** + This category is just use as a convenience method. For more detail control, use methods in `UIImage+MultiFormat.h` or directly use `SDImageCoder`. + */ +@interface UIImage (GIF) + +/** + Creates an animated UIImage from an NSData. + This will create animated image if the data is Animated GIF. And will create a static image is the data is Static GIF. + + @param data The GIF data + @return The created image + */ ++ (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.m new file mode 100644 index 00000000..7158cf31 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+GIF.m @@ -0,0 +1,22 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Laurin Brandner + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+GIF.h" +#import "SDImageGIFCoder.h" + +@implementation UIImage (GIF) + ++ (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data { + if (!data) { + return nil; + } + return [[SDImageGIFCoder sharedCoder] decodedImageWithData:data options:0]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.h new file mode 100644 index 00000000..0ff2f2fd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.h @@ -0,0 +1,27 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +/** + UIImage category for memory cache cost. + */ +@interface UIImage (MemoryCacheCost) + +/** + The memory cache cost for specify image used by image cache. The cost function is the bytes size held in memory. + If you set some associated object to `UIImage`, you can set the custom value to indicate the memory cost. + + For `UIImage`, this method return the single frame bytes size when `image.images` is nil for static image. Return full frame bytes size when `image.images` is not nil for animated image. + For `NSImage`, this method return the single frame bytes size because `NSImage` does not store all frames in memory. + @note Note that because of the limitations of category this property can get out of sync if you create another instance with CGImage or other methods. + @note For custom animated class conforms to `SDAnimatedImage`, you can override this getter method in your subclass to return a more proper value instead, which representing the current frame's total bytes. + */ +@property (assign, nonatomic) NSUInteger sd_memoryCost; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.m new file mode 100644 index 00000000..b9365009 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MemoryCacheCost.m @@ -0,0 +1,47 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+MemoryCacheCost.h" +#import "objc/runtime.h" +#import "NSImage+Compatibility.h" + +FOUNDATION_STATIC_INLINE NSUInteger SDMemoryCacheCostForImage(UIImage *image) { + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + return 0; + } + NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef); + NSUInteger frameCount; +#if SD_MAC + frameCount = 1; +#elif SD_UIKIT || SD_WATCH + // Filter the same frame in `_UIAnimatedImage`. + frameCount = image.images.count > 1 ? [NSSet setWithArray:image.images].count : 1; +#endif + NSUInteger cost = bytesPerFrame * frameCount; + return cost; +} + +@implementation UIImage (MemoryCacheCost) + +- (NSUInteger)sd_memoryCost { + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_memoryCost)); + NSUInteger memoryCost; + if (value != nil) { + memoryCost = [value unsignedIntegerValue]; + } else { + memoryCost = SDMemoryCacheCostForImage(self); + } + return memoryCost; +} + +- (void)setSd_memoryCost:(NSUInteger)sd_memoryCost { + objc_setAssociatedObject(self, @selector(sd_memoryCost), @(sd_memoryCost), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.h new file mode 100644 index 00000000..6a278e2e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.h @@ -0,0 +1,68 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "NSData+ImageContentType.h" + +/** + UIImage category for image metadata, including animation, loop count, format, incremental, etc. + */ +@interface UIImage (Metadata) + +/** + * UIKit: + * For static image format, this value is always 0. + * For animated image format, 0 means infinite looping. + * Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods. + * AppKit: + * NSImage currently only support animated via `NSBitmapImageRep`(GIF) or `SDAnimatedImageRep`(APNG/GIF/WebP) unlike UIImage. + * The getter of this property will get the loop count from animated imageRep + * The setter of this property will set the loop count from animated imageRep + */ +@property (nonatomic, assign) NSUInteger sd_imageLoopCount; + +/** + * UIKit: + * Returns the `images`'s count by unapply the patch for the different frame durations. Which matches the real visible frame count when displaying on UIImageView. + * See more in `SDImageCoderHelper.animatedImageWithFrames`. + * Returns 1 for static image. + * AppKit: + * Returns the underlaying `NSBitmapImageRep` or `SDAnimatedImageRep` frame count. + * Returns 1 for static image. + */ +@property (nonatomic, assign, readonly) NSUInteger sd_imageFrameCount; + +/** + * UIKit: + * Check the `images` array property. + * AppKit: + * NSImage currently only support animated via GIF imageRep unlike UIImage. It will check the imageRep's frame count. + */ +@property (nonatomic, assign, readonly) BOOL sd_isAnimated; + +/** + * UIKit: + * Check the `isSymbolImage` property. Also check the system PDF(iOS 11+) && SVG(iOS 13+) support. + * AppKit: + * NSImage supports PDF && SVG && EPS imageRep, check the imageRep class. + */ +@property (nonatomic, assign, readonly) BOOL sd_isVector; + +/** + * The image format represent the original compressed image data format. + * If you don't manually specify a format, this information is retrieve from CGImage using `CGImageGetUTType`, which may return nil for non-CG based image. At this time it will return `SDImageFormatUndefined` as default value. + * @note Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods. + */ +@property (nonatomic, assign) SDImageFormat sd_imageFormat; + +/** + A bool value indicating whether the image is during incremental decoding and may not contains full pixels. + */ +@property (nonatomic, assign) BOOL sd_isIncremental; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.m new file mode 100644 index 00000000..b8f4fd82 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Metadata.m @@ -0,0 +1,189 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+Metadata.h" +#import "NSImage+Compatibility.h" +#import "SDInternalMacros.h" +#import "objc/runtime.h" + +@implementation UIImage (Metadata) + +#if SD_UIKIT || SD_WATCH + +- (NSUInteger)sd_imageLoopCount { + NSUInteger imageLoopCount = 0; + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageLoopCount)); + if ([value isKindOfClass:[NSNumber class]]) { + imageLoopCount = value.unsignedIntegerValue; + } + return imageLoopCount; +} + +- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount { + NSNumber *value = @(sd_imageLoopCount); + objc_setAssociatedObject(self, @selector(sd_imageLoopCount), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSUInteger)sd_imageFrameCount { + NSArray *animatedImages = self.images; + if (!animatedImages || animatedImages.count <= 1) { + return 1; + } + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageFrameCount)); + if ([value isKindOfClass:[NSNumber class]]) { + return [value unsignedIntegerValue]; + } + __block NSUInteger frameCount = 1; + __block UIImage *previousImage = animatedImages.firstObject; + [animatedImages enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) { + // ignore first + if (idx == 0) { + return; + } + if (![image isEqual:previousImage]) { + frameCount++; + } + previousImage = image; + }]; + objc_setAssociatedObject(self, @selector(sd_imageFrameCount), @(frameCount), OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + return frameCount; +} + +- (BOOL)sd_isAnimated { + return (self.images != nil); +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +- (BOOL)sd_isVector { + if (@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) { + // Xcode 11 supports symbol image, keep Xcode 10 compatible currently + SEL SymbolSelector = NSSelectorFromString(@"isSymbolImage"); + if ([self respondsToSelector:SymbolSelector] && [self performSelector:SymbolSelector]) { + return YES; + } + // SVG + SEL SVGSelector = SD_SEL_SPI(CGSVGDocument); + if ([self respondsToSelector:SVGSelector] && [self performSelector:SVGSelector]) { + return YES; + } + } + if (@available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) { + // PDF + SEL PDFSelector = SD_SEL_SPI(CGPDFPage); + if ([self respondsToSelector:PDFSelector] && [self performSelector:PDFSelector]) { + return YES; + } + } + return NO; +} +#pragma clang diagnostic pop + +#else + +- (NSUInteger)sd_imageLoopCount { + NSUInteger imageLoopCount = 0; + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (bitmapImageRep) { + imageLoopCount = [[bitmapImageRep valueForProperty:NSImageLoopCount] unsignedIntegerValue]; + } + return imageLoopCount; +} + +- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount { + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (bitmapImageRep) { + [bitmapImageRep setProperty:NSImageLoopCount withValue:@(sd_imageLoopCount)]; + } +} + +- (NSUInteger)sd_imageFrameCount { + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (bitmapImageRep) { + return [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue]; + } + return 1; +} + +- (BOOL)sd_isAnimated { + BOOL isAnimated = NO; + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + NSBitmapImageRep *bitmapImageRep; + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImageRep = (NSBitmapImageRep *)imageRep; + } + if (bitmapImageRep) { + NSUInteger frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue]; + isAnimated = frameCount > 1 ? YES : NO; + } + return isAnimated; +} + +- (BOOL)sd_isVector { + NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); + NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil]; + if ([imageRep isKindOfClass:[NSPDFImageRep class]]) { + return YES; + } + if ([imageRep isKindOfClass:[NSEPSImageRep class]]) { + return YES; + } + if ([NSStringFromClass(imageRep.class) hasSuffix:@"NSSVGImageRep"]) { + return YES; + } + return NO; +} + +#endif + +- (SDImageFormat)sd_imageFormat { + SDImageFormat imageFormat = SDImageFormatUndefined; + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageFormat)); + if ([value isKindOfClass:[NSNumber class]]) { + imageFormat = value.integerValue; + return imageFormat; + } + // Check CGImage's UTType, may return nil for non-Image/IO based image + if (@available(iOS 9.0, tvOS 9.0, macOS 10.11, watchOS 2.0, *)) { + CFStringRef uttype = CGImageGetUTType(self.CGImage); + imageFormat = [NSData sd_imageFormatFromUTType:uttype]; + } + return imageFormat; +} + +- (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat { + objc_setAssociatedObject(self, @selector(sd_imageFormat), @(sd_imageFormat), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)setSd_isIncremental:(BOOL)sd_isIncremental { + objc_setAssociatedObject(self, @selector(sd_isIncremental), @(sd_isIncremental), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (BOOL)sd_isIncremental { + NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isIncremental)); + return value.boolValue; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.h new file mode 100644 index 00000000..a0935b57 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.h @@ -0,0 +1,80 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "NSData+ImageContentType.h" + +/** + UIImage category for convenient image format decoding/encoding. + */ +@interface UIImage (MultiFormat) +#pragma mark - Decode +/** + Create and decode a image with the specify image data + + @param data The image data + @return The created image + */ ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data; + +/** + Create and decode a image with the specify image data and scale + + @param data The image data + @param scale The image scale factor. Should be greater than or equal to 1.0. + @return The created image + */ ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale; + +/** + Create and decode a image with the specify image data and scale, allow specify animate/static control + + @param data The image data + @param scale The image scale factor. Should be greater than or equal to 1.0. + @param firstFrameOnly Even if the image data is animated image format, decode the first frame only as static image. + @return The created image + */ ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly; + +#pragma mark - Encode +/** + Encode the current image to the data, the image format is unspecified + + @note If the receiver is `SDAnimatedImage`, this will return the animated image data if available. No more extra encoding process. + @return The encoded data. If can't encode, return nil + */ +- (nullable NSData *)sd_imageData; + +/** + Encode the current image to data with the specify image format + + @param imageFormat The specify image format + @return The encoded data. If can't encode, return nil + */ +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat NS_SWIFT_NAME(sd_imageData(as:)); + +/** + Encode the current image to data with the specify image format and compression quality + + @param imageFormat The specify image format + @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality. + @return The encoded data. If can't encode, return nil + */ +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality NS_SWIFT_NAME(sd_imageData(as:compressionQuality:)); + +/** + Encode the current image to data with the specify image format and compression quality, allow specify animate/static control + + @param imageFormat The specify image format + @param compressionQuality The quality of the resulting image data. Value between 0.0-1.0. Some coders may not support compression quality. + @param firstFrameOnly Even if the image is animated image, encode the first frame only as static image. + @return The encoded data. If can't encode, return nil + */ +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly NS_SWIFT_NAME(sd_imageData(as:compressionQuality:firstFrameOnly:)); + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.m new file mode 100644 index 00000000..04d08c54 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+MultiFormat.m @@ -0,0 +1,47 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+MultiFormat.h" +#import "SDImageCodersManager.h" + +@implementation UIImage (MultiFormat) + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data { + return [self sd_imageWithData:data scale:1]; +} + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale { + return [self sd_imageWithData:data scale:scale firstFrameOnly:NO]; +} + ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly { + if (!data) { + return nil; + } + SDImageCoderOptions *options = @{SDImageCoderDecodeScaleFactor : @(MAX(scale, 1)), SDImageCoderDecodeFirstFrameOnly : @(firstFrameOnly)}; + return [[SDImageCodersManager sharedManager] decodedImageWithData:data options:options]; +} + +- (nullable NSData *)sd_imageData { + return [self sd_imageDataAsFormat:SDImageFormatUndefined]; +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat { + return [self sd_imageDataAsFormat:imageFormat compressionQuality:1]; +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality { + return [self sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:NO]; +} + +- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly { + SDImageCoderOptions *options = @{SDImageCoderEncodeCompressionQuality : @(compressionQuality), SDImageCoderEncodeFirstFrameOnly : @(firstFrameOnly)}; + return [[SDImageCodersManager sharedManager] encodedDataWithImage:self format:imageFormat options:options]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.h new file mode 100644 index 00000000..06cb66da --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.h @@ -0,0 +1,146 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +typedef NS_ENUM(NSUInteger, SDImageScaleMode) { + SDImageScaleModeFill = 0, + SDImageScaleModeAspectFit = 1, + SDImageScaleModeAspectFill = 2 +}; + +#if SD_UIKIT || SD_WATCH +typedef UIRectCorner SDRectCorner; +#else +typedef NS_OPTIONS(NSUInteger, SDRectCorner) { + SDRectCornerTopLeft = 1 << 0, + SDRectCornerTopRight = 1 << 1, + SDRectCornerBottomLeft = 1 << 2, + SDRectCornerBottomRight = 1 << 3, + SDRectCornerAllCorners = ~0UL +}; +#endif + +/** + Provide some common method for `UIImage`. + Image process is based on Core Graphics and vImage. + */ +@interface UIImage (Transform) + +#pragma mark - Image Geometry + +/** + Returns a new image which is resized from this image. + You can specify a larger or smaller size than the image size. The image content will be changed with the scale mode. + + @param size The new size to be resized, values should be positive. + @param scaleMode The scale mode for image content. + @return The new image with the given size. + */ +- (nullable UIImage *)sd_resizedImageWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode; + +/** + Returns a new image which is cropped from this image. + + @param rect Image's inner rect. + @return The new image with the cropping rect. + */ +- (nullable UIImage *)sd_croppedImageWithRect:(CGRect)rect; + +/** + Rounds a new image with a given corner radius and corners. + + @param cornerRadius The radius of each corner oval. Values larger than half the + rectangle's width or height are clamped appropriately to + half the width or height. + @param corners A bitmask value that identifies the corners that you want + rounded. You can use this parameter to round only a subset + of the corners of the rectangle. + @param borderWidth The inset border line width. Values larger than half the rectangle's + width or height are clamped appropriately to half the width + or height. + @param borderColor The border stroke color. nil means clear color. + @return The new image with the round corner. + */ +- (nullable UIImage *)sd_roundedCornerImageWithRadius:(CGFloat)cornerRadius + corners:(SDRectCorner)corners + borderWidth:(CGFloat)borderWidth + borderColor:(nullable UIColor *)borderColor; + +/** + Returns a new rotated image (relative to the center). + + @param angle Rotated radians in counterclockwise.⟲ + @param fitSize YES: new image's size is extend to fit all content. + NO: image's size will not change, content may be clipped. + @return The new image with the rotation. + */ +- (nullable UIImage *)sd_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize; + +/** + Returns a new horizontally(vertically) flipped image. + + @param horizontal YES to flip the image horizontally. ⇋ + @param vertical YES to flip the image vertically. ⥯ + @return The new image with the flipping. + */ +- (nullable UIImage *)sd_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical; + +#pragma mark - Image Blending + +/** + Return a tinted image with the given color. This actually use alpha blending of current image and the tint color. + + @param tintColor The tint color. + @return The new image with the tint color. + */ +- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor; + +/** + Return the pixel color at specify position. The point is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based. + @note The point's x/y should not be smaller than 0, or greater than or equal to width/height. + @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself. + + @param point The position of pixel + @return The color for specify pixel, or nil if any error occur + */ +- (nullable UIColor *)sd_colorAtPoint:(CGPoint)point; + +/** + Return the pixel color array with specify rectangle. The rect is from the top-left to the bottom-right and 0-based. The returned the color is always be RGBA format. The image must be CG-based. + @note The rect's width/height should not be smaller than or equal to 0. The minX/minY should not be smaller than 0. The maxX/maxY should not be greater than width/height. Attention this limit is different from `sd_colorAtPoint:` (point: (0, 0) like rect: (0, 0, 1, 1)) + @note The overhead of object creation means this method is best suited for infrequent color sampling. For heavy image processing, grab the raw bitmap data and process yourself. + + @param rect The rectangle of pixels + @return The color array for specify pixels, or nil if any error occur + */ +- (nullable NSArray *)sd_colorsWithRect:(CGRect)rect; + +#pragma mark - Image Effect + +/** + Return a new image applied a blur effect. + + @param blurRadius The radius of the blur in points, 0 means no blur effect. + + @return The new image with blur effect, or nil if an error occurs (e.g. no enough memory). + */ +- (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius; + +#if SD_UIKIT || SD_MAC +/** + Return a new image applied a CIFilter. + + @param filter The CIFilter to be applied to the image. + @return The new image with the CIFilter, or nil if an error occurs (e.g. no + enough memory). + */ +- (nullable UIImage *)sd_filteredImageWithFilter:(nonnull CIFilter *)filter; +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.m new file mode 100644 index 00000000..66c22d26 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImage+Transform.m @@ -0,0 +1,711 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImage+Transform.h" +#import "NSImage+Compatibility.h" +#import "SDImageGraphics.h" +#import "SDGraphicsImageRenderer.h" +#import "NSBezierPath+SDRoundedCorners.h" +#import +#if SD_UIKIT || SD_MAC +#import +#endif + +static inline CGRect SDCGRectFitWithScaleMode(CGRect rect, CGSize size, SDImageScaleMode scaleMode) { + rect = CGRectStandardize(rect); + size.width = size.width < 0 ? -size.width : size.width; + size.height = size.height < 0 ? -size.height : size.height; + CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); + switch (scaleMode) { + case SDImageScaleModeAspectFit: + case SDImageScaleModeAspectFill: { + if (rect.size.width < 0.01 || rect.size.height < 0.01 || + size.width < 0.01 || size.height < 0.01) { + rect.origin = center; + rect.size = CGSizeZero; + } else { + CGFloat scale; + if (scaleMode == SDImageScaleModeAspectFit) { + if (size.width / size.height < rect.size.width / rect.size.height) { + scale = rect.size.height / size.height; + } else { + scale = rect.size.width / size.width; + } + } else { + if (size.width / size.height < rect.size.width / rect.size.height) { + scale = rect.size.width / size.width; + } else { + scale = rect.size.height / size.height; + } + } + size.width *= scale; + size.height *= scale; + rect.size = size; + rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5); + } + } break; + case SDImageScaleModeFill: + default: { + rect = rect; + } + } + return rect; +} + +static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitmapInfo) { + // Get alpha info, byteOrder info + CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; + CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask; + CGFloat r = 0, g = 0, b = 0, a = 1; + + BOOL byteOrderNormal = NO; + switch (byteOrderInfo) { + case kCGBitmapByteOrderDefault: { + byteOrderNormal = YES; + } break; + case kCGBitmapByteOrder32Little: { + } break; + case kCGBitmapByteOrder32Big: { + byteOrderNormal = YES; + } break; + default: break; + } + switch (alphaInfo) { + case kCGImageAlphaPremultipliedFirst: + case kCGImageAlphaFirst: { + if (byteOrderNormal) { + // ARGB8888 + a = pixel[0] / 255.0; + r = pixel[1] / 255.0; + g = pixel[2] / 255.0; + b = pixel[3] / 255.0; + } else { + // BGRA8888 + b = pixel[0] / 255.0; + g = pixel[1] / 255.0; + r = pixel[2] / 255.0; + a = pixel[3] / 255.0; + } + } + break; + case kCGImageAlphaPremultipliedLast: + case kCGImageAlphaLast: { + if (byteOrderNormal) { + // RGBA8888 + r = pixel[0] / 255.0; + g = pixel[1] / 255.0; + b = pixel[2] / 255.0; + a = pixel[3] / 255.0; + } else { + // ABGR8888 + a = pixel[0] / 255.0; + b = pixel[1] / 255.0; + g = pixel[2] / 255.0; + r = pixel[3] / 255.0; + } + } + break; + case kCGImageAlphaNone: { + if (byteOrderNormal) { + // RGB + r = pixel[0] / 255.0; + g = pixel[1] / 255.0; + b = pixel[2] / 255.0; + } else { + // BGR + b = pixel[0] / 255.0; + g = pixel[1] / 255.0; + r = pixel[2] / 255.0; + } + } + break; + case kCGImageAlphaNoneSkipLast: { + if (byteOrderNormal) { + // RGBX + r = pixel[0] / 255.0; + g = pixel[1] / 255.0; + b = pixel[2] / 255.0; + } else { + // XBGR + b = pixel[1] / 255.0; + g = pixel[2] / 255.0; + r = pixel[3] / 255.0; + } + } + break; + case kCGImageAlphaNoneSkipFirst: { + if (byteOrderNormal) { + // XRGB + r = pixel[1] / 255.0; + g = pixel[2] / 255.0; + b = pixel[3] / 255.0; + } else { + // BGRX + b = pixel[0] / 255.0; + g = pixel[1] / 255.0; + r = pixel[2] / 255.0; + } + } + break; + case kCGImageAlphaOnly: { + // A + a = pixel[0] / 255.0; + } + break; + default: + break; + } + + return [UIColor colorWithRed:r green:g blue:b alpha:a]; +} + +#if SD_UIKIT || SD_MAC +// Create-Rule, caller should call CGImageRelease +static inline CGImageRef _Nullable SDCreateCGImageFromCIImage(CIImage * _Nonnull ciImage) { + CGImageRef imageRef = NULL; + if (@available(iOS 10, macOS 10.12, tvOS 10, *)) { + imageRef = ciImage.CGImage; + } + if (!imageRef) { + CIContext *context = [CIContext context]; + imageRef = [context createCGImage:ciImage fromRect:ciImage.extent]; + } else { + CGImageRetain(imageRef); + } + return imageRef; +} +#endif + +@implementation UIImage (Transform) + +- (void)sd_drawInRect:(CGRect)rect context:(CGContextRef)context scaleMode:(SDImageScaleMode)scaleMode clipsToBounds:(BOOL)clips { + CGRect drawRect = SDCGRectFitWithScaleMode(rect, self.size, scaleMode); + if (drawRect.size.width == 0 || drawRect.size.height == 0) return; + if (clips) { + if (context) { + CGContextSaveGState(context); + CGContextAddRect(context, rect); + CGContextClip(context); + [self drawInRect:drawRect]; + CGContextRestoreGState(context); + } + } else { + [self drawInRect:drawRect]; + } +} + +- (nullable UIImage *)sd_resizedImageWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode { + if (size.width <= 0 || size.height <= 0) return nil; + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.scale = self.scale; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:size format:format]; + UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + [self sd_drawInRect:CGRectMake(0, 0, size.width, size.height) context:context scaleMode:scaleMode clipsToBounds:NO]; + }]; + return image; +} + +- (nullable UIImage *)sd_croppedImageWithRect:(CGRect)rect { + rect.origin.x *= self.scale; + rect.origin.y *= self.scale; + rect.size.width *= self.scale; + rect.size.height *= self.scale; + if (rect.size.width <= 0 || rect.size.height <= 0) return nil; + +#if SD_UIKIT || SD_MAC + // CIImage shortcut + if (self.CIImage) { + CGRect croppingRect = CGRectMake(rect.origin.x, self.size.height - CGRectGetMaxY(rect), rect.size.width, rect.size.height); + CIImage *ciImage = [self.CIImage imageByCroppingToRect:croppingRect]; +#if SD_UIKIT + UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + return image; + } +#endif + + CGImageRef imageRef = self.CGImage; + if (!imageRef) { + return nil; + } + + CGImageRef croppedImageRef = CGImageCreateWithImageInRect(imageRef, rect); + if (!croppedImageRef) { + return nil; + } +#if SD_UIKIT || SD_WATCH + UIImage *image = [UIImage imageWithCGImage:croppedImageRef scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCGImage:croppedImageRef scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + CGImageRelease(croppedImageRef); + return image; +} + +- (nullable UIImage *)sd_roundedCornerImageWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor { + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.scale = self.scale; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:self.size format:format]; + UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); + + CGFloat minSize = MIN(self.size.width, self.size.height); + if (borderWidth < minSize / 2) { +#if SD_UIKIT || SD_WATCH + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(cornerRadius, cornerRadius)]; +#else + NSBezierPath *path = [NSBezierPath sd_bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadius:cornerRadius]; +#endif + [path closePath]; + + CGContextSaveGState(context); + [path addClip]; + [self drawInRect:rect]; + CGContextRestoreGState(context); + } + + if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) { + CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale; + CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset); + CGFloat strokeRadius = cornerRadius > self.scale / 2 ? cornerRadius - self.scale / 2 : 0; +#if SD_UIKIT || SD_WATCH + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, strokeRadius)]; +#else + NSBezierPath *path = [NSBezierPath sd_bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadius:strokeRadius]; +#endif + [path closePath]; + + path.lineWidth = borderWidth; + [borderColor setStroke]; + [path stroke]; + } + }]; + return image; +} + +- (nullable UIImage *)sd_rotatedImageWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize { + size_t width = self.size.width; + size_t height = self.size.height; + CGRect newRect = CGRectApplyAffineTransform(CGRectMake(0, 0, width, height), + fitSize ? CGAffineTransformMakeRotation(angle) : CGAffineTransformIdentity); + +#if SD_UIKIT || SD_MAC + // CIImage shortcut + if (self.CIImage) { + CIImage *ciImage = self.CIImage; + if (fitSize) { + CGAffineTransform transform = CGAffineTransformMakeRotation(angle); + ciImage = [ciImage imageByApplyingTransform:transform]; + } else { + CIFilter *filter = [CIFilter filterWithName:@"CIStraightenFilter"]; + [filter setValue:ciImage forKey:kCIInputImageKey]; + [filter setValue:@(angle) forKey:kCIInputAngleKey]; + ciImage = filter.outputImage; + } +#if SD_UIKIT || SD_WATCH + UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + return image; + } +#endif + + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.scale = self.scale; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:newRect.size format:format]; + UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + CGContextSetShouldAntialias(context, true); + CGContextSetAllowsAntialiasing(context, true); + CGContextSetInterpolationQuality(context, kCGInterpolationHigh); + CGContextTranslateCTM(context, +(newRect.size.width * 0.5), +(newRect.size.height * 0.5)); +#if SD_UIKIT || SD_WATCH + // Use UIKit coordinate system counterclockwise (⟲) + CGContextRotateCTM(context, -angle); +#else + CGContextRotateCTM(context, angle); +#endif + + [self drawInRect:CGRectMake(-(width * 0.5), -(height * 0.5), width, height)]; + }]; + return image; +} + +- (nullable UIImage *)sd_flippedImageWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical { + size_t width = self.size.width; + size_t height = self.size.height; + +#if SD_UIKIT || SD_MAC + // CIImage shortcut + if (self.CIImage) { + CGAffineTransform transform = CGAffineTransformIdentity; + // Use UIKit coordinate system + if (horizontal) { + CGAffineTransform flipHorizontal = CGAffineTransformMake(-1, 0, 0, 1, width, 0); + transform = CGAffineTransformConcat(transform, flipHorizontal); + } + if (vertical) { + CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, height); + transform = CGAffineTransformConcat(transform, flipVertical); + } + CIImage *ciImage = [self.CIImage imageByApplyingTransform:transform]; +#if SD_UIKIT + UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + return image; + } +#endif + + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.scale = self.scale; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:self.size format:format]; + UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + // Use UIKit coordinate system + if (horizontal) { + CGAffineTransform flipHorizontal = CGAffineTransformMake(-1, 0, 0, 1, width, 0); + CGContextConcatCTM(context, flipHorizontal); + } + if (vertical) { + CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, height); + CGContextConcatCTM(context, flipVertical); + } + [self drawInRect:CGRectMake(0, 0, width, height)]; + }]; + return image; +} + +#pragma mark - Image Blending + +- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor { + BOOL hasTint = CGColorGetAlpha(tintColor.CGColor) > __FLT_EPSILON__; + if (!hasTint) { + return self; + } + +#if SD_UIKIT || SD_MAC + // CIImage shortcut + if (self.CIImage) { + CIImage *ciImage = self.CIImage; + CIImage *colorImage = [CIImage imageWithColor:[[CIColor alloc] initWithColor:tintColor]]; + colorImage = [colorImage imageByCroppingToRect:ciImage.extent]; + CIFilter *filter = [CIFilter filterWithName:@"CISourceAtopCompositing"]; + [filter setValue:colorImage forKey:kCIInputImageKey]; + [filter setValue:ciImage forKey:kCIInputBackgroundImageKey]; + ciImage = filter.outputImage; +#if SD_UIKIT + UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + return image; + } +#endif + + CGSize size = self.size; + CGRect rect = { CGPointZero, size }; + CGFloat scale = self.scale; + + // blend mode, see https://en.wikipedia.org/wiki/Alpha_compositing + CGBlendMode blendMode = kCGBlendModeSourceAtop; + + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.scale = scale; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:size format:format]; + UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + [self drawInRect:rect]; + CGContextSetBlendMode(context, blendMode); + CGContextSetFillColorWithColor(context, tintColor.CGColor); + CGContextFillRect(context, rect); + }]; + return image; +} + +- (nullable UIColor *)sd_colorAtPoint:(CGPoint)point { + CGImageRef imageRef = NULL; + // CIImage compatible +#if SD_UIKIT || SD_MAC + if (self.CIImage) { + imageRef = SDCreateCGImageFromCIImage(self.CIImage); + } +#endif + if (!imageRef) { + imageRef = self.CGImage; + CGImageRetain(imageRef); + } + if (!imageRef) { + return nil; + } + + // Check point + CGFloat width = CGImageGetWidth(imageRef); + CGFloat height = CGImageGetHeight(imageRef); + if (point.x < 0 || point.y < 0 || point.x >= width || point.y >= height) { + CGImageRelease(imageRef); + return nil; + } + + // Get pixels + CGDataProviderRef provider = CGImageGetDataProvider(imageRef); + if (!provider) { + CGImageRelease(imageRef); + return nil; + } + CFDataRef data = CGDataProviderCopyData(provider); + if (!data) { + CGImageRelease(imageRef); + return nil; + } + + // Get pixel at point + size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); + size_t components = CGImageGetBitsPerPixel(imageRef) / CGImageGetBitsPerComponent(imageRef); + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); + + CFRange range = CFRangeMake(bytesPerRow * point.y + components * point.x, 4); + if (CFDataGetLength(data) < range.location + range.length) { + CFRelease(data); + CGImageRelease(imageRef); + return nil; + } + Pixel_8888 pixel = {0}; + CFDataGetBytes(data, range, pixel); + CFRelease(data); + CGImageRelease(imageRef); + // Convert to color + return SDGetColorFromPixel(pixel, bitmapInfo); +} + +- (nullable NSArray *)sd_colorsWithRect:(CGRect)rect { + CGImageRef imageRef = NULL; + // CIImage compatible +#if SD_UIKIT || SD_MAC + if (self.CIImage) { + imageRef = SDCreateCGImageFromCIImage(self.CIImage); + } +#endif + if (!imageRef) { + imageRef = self.CGImage; + CGImageRetain(imageRef); + } + if (!imageRef) { + return nil; + } + + // Check rect + CGFloat width = CGImageGetWidth(imageRef); + CGFloat height = CGImageGetHeight(imageRef); + if (CGRectGetWidth(rect) <= 0 || CGRectGetHeight(rect) <= 0 || CGRectGetMinX(rect) < 0 || CGRectGetMinY(rect) < 0 || CGRectGetMaxX(rect) > width || CGRectGetMaxY(rect) > height) { + CGImageRelease(imageRef); + return nil; + } + + // Get pixels + CGDataProviderRef provider = CGImageGetDataProvider(imageRef); + if (!provider) { + CGImageRelease(imageRef); + return nil; + } + CFDataRef data = CGDataProviderCopyData(provider); + if (!data) { + CGImageRelease(imageRef); + return nil; + } + + // Get pixels with rect + size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); + size_t components = CGImageGetBitsPerPixel(imageRef) / CGImageGetBitsPerComponent(imageRef); + + size_t start = bytesPerRow * CGRectGetMinY(rect) + components * CGRectGetMinX(rect); + size_t end = bytesPerRow * (CGRectGetMaxY(rect) - 1) + components * CGRectGetMaxX(rect); + if (CFDataGetLength(data) < (CFIndex)end) { + CFRelease(data); + CGImageRelease(imageRef); + return nil; + } + + const UInt8 *pixels = CFDataGetBytePtr(data); + size_t row = CGRectGetMinY(rect); + size_t col = CGRectGetMaxX(rect); + + // Convert to color + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); + NSMutableArray *colors = [NSMutableArray arrayWithCapacity:CGRectGetWidth(rect) * CGRectGetHeight(rect)]; + for (size_t index = start; index < end; index += 4) { + if (index >= row * bytesPerRow + col * components) { + // Index beyond the end of current row, go next row + row++; + index = row * bytesPerRow + CGRectGetMinX(rect) * components; + index -= 4; + continue; + } + Pixel_8888 pixel = {pixels[index], pixels[index+1], pixels[index+2], pixels[index+3]}; + UIColor *color = SDGetColorFromPixel(pixel, bitmapInfo); + [colors addObject:color]; + } + CFRelease(data); + CGImageRelease(imageRef); + + return [colors copy]; +} + +#pragma mark - Image Effect + +// We use vImage to do box convolve for performance and support for watchOS. However, you can just use `CIFilter.CIGaussianBlur`. For other blur effect, use any filter in `CICategoryBlur` +- (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius { + if (self.size.width < 1 || self.size.height < 1) { + return nil; + } + BOOL hasBlur = blurRadius > __FLT_EPSILON__; + if (!hasBlur) { + return self; + } + + CGFloat scale = self.scale; + CGFloat inputRadius = blurRadius * scale; +#if SD_UIKIT || SD_MAC + if (self.CIImage) { + CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"]; + [filter setValue:self.CIImage forKey:kCIInputImageKey]; + [filter setValue:@(inputRadius) forKey:kCIInputRadiusKey]; + CIImage *ciImage = filter.outputImage; + ciImage = [ciImage imageByCroppingToRect:CGRectMake(0, 0, self.size.width, self.size.height)]; +#if SD_UIKIT + UIImage *image = [UIImage imageWithCIImage:ciImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCIImage:ciImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + return image; + } +#endif + + CGImageRef imageRef = self.CGImage; + + //convert to BGRA if it isn't + if (CGImageGetBitsPerPixel(imageRef) != 32 || + CGImageGetBitsPerComponent(imageRef) != 8 || + !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) { + SDGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); + [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; + imageRef = SDGraphicsGetImageFromCurrentImageContext().CGImage; + SDGraphicsEndImageContext(); + } + + vImage_Buffer effect = {}, scratch = {}; + vImage_Buffer *input = NULL, *output = NULL; + + vImage_CGImageFormat format = { + .bitsPerComponent = 8, + .bitsPerPixel = 32, + .colorSpace = NULL, + .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, //requests a BGRA buffer. + .version = 0, + .decode = NULL, + .renderingIntent = CGImageGetRenderingIntent(imageRef) + }; + + vImage_Error err; + err = vImageBuffer_InitWithCGImage(&effect, &format, NULL, imageRef, kvImageNoFlags); + if (err != kvImageNoError) { + NSLog(@"UIImage+Transform error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@", err, self); + return nil; + } + err = vImageBuffer_Init(&scratch, effect.height, effect.width, format.bitsPerPixel, kvImageNoFlags); + if (err != kvImageNoError) { + NSLog(@"UIImage+Transform error: vImageBuffer_Init returned error code %zi for inputImage: %@", err, self); + return nil; + } + + input = &effect; + output = &scratch; + + if (hasBlur) { + // A description of how to compute the box kernel width from the Gaussian + // radius (aka standard deviation) appears in the SVG spec: + // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement + // + // For larger values of 's' (s >= 2.0), an approximation can be used: Three + // successive box-blurs build a piece-wise quadratic convolution kernel, which + // approximates the Gaussian kernel to within roughly 3%. + // + // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) + // + // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel. + // + if (inputRadius - 2.0 < __FLT_EPSILON__) inputRadius = 2.0; + uint32_t radius = floor(inputRadius * 3.0 * sqrt(2 * M_PI) / 4 + 0.5); + radius |= 1; // force radius to be odd so that the three box-blur methodology works. + int iterations; + if (blurRadius * scale < 0.5) iterations = 1; + else if (blurRadius * scale < 1.5) iterations = 2; + else iterations = 3; + NSInteger tempSize = vImageBoxConvolve_ARGB8888(input, output, NULL, 0, 0, radius, radius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend); + void *temp = malloc(tempSize); + for (int i = 0; i < iterations; i++) { + vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend); + vImage_Buffer *tmp = input; + input = output; + output = tmp; + } + free(temp); + } + + CGImageRef effectCGImage = NULL; + effectCGImage = vImageCreateCGImageFromBuffer(input, &format, NULL, NULL, kvImageNoAllocate, NULL); + if (effectCGImage == NULL) { + effectCGImage = vImageCreateCGImageFromBuffer(input, &format, NULL, NULL, kvImageNoFlags, NULL); + free(input->data); + } + free(output->data); +#if SD_UIKIT || SD_WATCH + UIImage *outputImage = [UIImage imageWithCGImage:effectCGImage scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *outputImage = [[UIImage alloc] initWithCGImage:effectCGImage scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + CGImageRelease(effectCGImage); + + return outputImage; +} + +#if SD_UIKIT || SD_MAC +- (nullable UIImage *)sd_filteredImageWithFilter:(nonnull CIFilter *)filter { + CIImage *inputImage; + if (self.CIImage) { + inputImage = self.CIImage; + } else { + CGImageRef imageRef = self.CGImage; + if (!imageRef) { + return nil; + } + inputImage = [CIImage imageWithCGImage:imageRef]; + } + if (!inputImage) return nil; + + CIContext *context = [CIContext context]; + [filter setValue:inputImage forKey:kCIInputImageKey]; + CIImage *outputImage = filter.outputImage; + if (!outputImage) return nil; + + CGImageRef imageRef = [context createCGImage:outputImage fromRect:outputImage.extent]; + if (!imageRef) return nil; + +#if SD_UIKIT + UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; +#else + UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:self.scale orientation:kCGImagePropertyOrientationUp]; +#endif + CGImageRelease(imageRef); + + return image; +} +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.h new file mode 100644 index 00000000..6cd3ba61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.h @@ -0,0 +1,129 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_UIKIT + +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state. + */ +@interface UIImageView (HighlightedWebCache) + +/** + * Set the imageView `highlightedImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `highlightedImage` with an `url`, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the imageView `highlightedImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `highlightedImage` with an `url`, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.m new file mode 100644 index 00000000..96c09c1c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+HighlightedWebCache.m @@ -0,0 +1,76 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImageView+HighlightedWebCache.h" + +#if SD_UIKIT + +#import "UIView+WebCacheOperation.h" +#import "UIView+WebCache.h" +#import "SDInternalMacros.h" + +static NSString * const SDHighlightedImageOperationKey = @"UIImageViewImageOperationHighlighted"; + +@implementation UIImageView (HighlightedWebCache) + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; +} + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; +} + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setHighlightedImageWithURL:url options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + @weakify(self); + SDWebImageMutableContext *mutableContext; + if (context) { + mutableContext = [context mutableCopy]; + } else { + mutableContext = [NSMutableDictionary dictionary]; + } + mutableContext[SDWebImageContextSetImageOperationKey] = SDHighlightedImageOperationKey; + [self sd_internalSetImageWithURL:url + placeholderImage:nil + options:options + context:mutableContext + setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + @strongify(self); + self.highlightedImage = image; + } + progress:progressBlock + completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.h new file mode 100644 index 00000000..626de9d1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.h @@ -0,0 +1,194 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageManager.h" + +/** + * Usage with a UITableViewCell sub-class: + * + * @code + +#import + +... + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *MyIdentifier = @"MyIdentifier"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; + + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]; + } + + // Here we use the provided sd_setImageWithURL:placeholderImage: method to load the web image + // Ensure you use a placeholder image otherwise cells will be initialized with no image + [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder"]]; + + cell.textLabel.text = @"My Text"; + return cell; +} + + * @endcode + */ + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIImageView. + */ +@interface UIImageView (WebCache) + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder, custom options and context. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.m new file mode 100644 index 00000000..9d7f18e7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIImageView+WebCache.m @@ -0,0 +1,67 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImageView+WebCache.h" +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" +#import "UIView+WebCache.h" + +@implementation UIImageView (WebCache) + +- (void)sd_setImageWithURL:(nullable NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:context progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:nil progress:progressBlock completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + context:context + setImageBlock:nil + progress:progressBlock + completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, imageURL); + } + }]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.h new file mode 100644 index 00000000..ee9f761b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.h @@ -0,0 +1,109 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" +#import "SDWebImageManager.h" +#import "SDWebImageTransition.h" +#import "SDWebImageIndicator.h" + +/** + The value specify that the image progress unit count cannot be determined because the progressBlock is not been called. + */ +FOUNDATION_EXPORT const int64_t SDWebImageProgressUnitCountUnknown; /* 1LL */ + +typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL); + +/** + Integrates SDWebImage async downloading and caching of remote images with UIView subclass. + */ +@interface UIView (WebCache) + +/** + * Get the current image URL. + * + * @note Note that because of the limitations of categories this property can get out of sync if you use setImage: directly. + */ +@property (nonatomic, strong, readonly, nullable) NSURL *sd_imageURL; + +/** + * Get the current image operation key. Operation key is used to identify the different queries for one view instance (like UIButton). + * See more about this in `SDWebImageContextSetImageOperationKey`. + * If you cancel current image load, the key will be set to nil. + * @note You can use method `UIView+WebCacheOperation` to investigate different queries' operation. + */ +@property (nonatomic, strong, readonly, nullable) NSString *sd_latestOperationKey; + +/** + * The current image loading progress associated to the view. The unit count is the received size and excepted size of download. + * The `totalUnitCount` and `completedUnitCount` will be reset to 0 after a new image loading start (change from current queue). And they will be set to `SDWebImageProgressUnitCountUnknown` if the progressBlock not been called but the image loading success to mark the progress finished (change from main queue). + * @note You can use Key-Value Observing on the progress, but you should take care that the change to progress is from a background queue during download(the same as progressBlock). If you want to using KVO and update the UI, make sure to dispatch on the main queue. And it's recommend to use some KVO libs like KVOController because it's more safe and easy to use. + * @note The getter will create a progress instance if the value is nil. But by default, we don't create one. If you need to use Key-Value Observing, you must trigger the getter or set a custom progress instance before the loading start. The default value is nil. + * @note Note that because of the limitations of categories this property can get out of sync if you update the progress directly. + */ +@property (nonatomic, strong, null_resettable) NSProgress *sd_imageProgress; + +/** + * Set the imageView `image` with an `url` and optionally a placeholder image. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * @param setImageBlock Block used for custom set image code. If not provide, use the built-in set image code (supports `UIImageView/NSImageView` and `UIButton/NSButton` currently) + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. + * This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter. + * In case of error the image parameter is nil and the third parameter may contain an NSError. + * + * The forth parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache + * or from the memory cache or from the network. + * + * The fifth parameter normally is always YES. However, if you provide SDWebImageAvoidAutoSetImage with SDWebImageProgressiveLoad options to enable progressive downloading and set the image yourself. This block is thus called repeatedly with a partial image. When image is fully downloaded, the + * block is called a last time with the full image and the last parameter set to YES. + * + * The last parameter is the original image URL + */ +- (void)sd_internalSetImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + setImageBlock:(nullable SDSetImageBlock)setImageBlock + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock; + +/** + * Cancel the current image load + */ +- (void)sd_cancelCurrentImageLoad; + +#if SD_UIKIT || SD_MAC + +#pragma mark - Image Transition + +/** + The image transition when image load finished. See `SDWebImageTransition`. + If you specify nil, do not do transition. Defaults to nil. + */ +@property (nonatomic, strong, nullable) SDWebImageTransition *sd_imageTransition; + +#pragma mark - Image Indicator + +/** + The image indicator during the image loading. If you do not need indicator, specify nil. Defaults to nil + The setter will remove the old indicator view and add new indicator view to current view's subview. + @note Because this is UI related, you should access only from the main queue. + */ +@property (nonatomic, strong, nullable) id sd_imageIndicator; + +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.m new file mode 100644 index 00000000..35f10362 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCache.m @@ -0,0 +1,442 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIView+WebCache.h" +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" +#import "SDWebImageError.h" +#import "SDInternalMacros.h" +#import "SDWebImageTransitionInternal.h" +#import "SDImageCache.h" + +const int64_t SDWebImageProgressUnitCountUnknown = 1LL; + +@implementation UIView (WebCache) + +- (nullable NSURL *)sd_imageURL { + return objc_getAssociatedObject(self, @selector(sd_imageURL)); +} + +- (void)setSd_imageURL:(NSURL * _Nullable)sd_imageURL { + objc_setAssociatedObject(self, @selector(sd_imageURL), sd_imageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (nullable NSString *)sd_latestOperationKey { + return objc_getAssociatedObject(self, @selector(sd_latestOperationKey)); +} + +- (void)setSd_latestOperationKey:(NSString * _Nullable)sd_latestOperationKey { + objc_setAssociatedObject(self, @selector(sd_latestOperationKey), sd_latestOperationKey, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +- (NSProgress *)sd_imageProgress { + NSProgress *progress = objc_getAssociatedObject(self, @selector(sd_imageProgress)); + if (!progress) { + progress = [[NSProgress alloc] initWithParent:nil userInfo:nil]; + self.sd_imageProgress = progress; + } + return progress; +} + +- (void)setSd_imageProgress:(NSProgress *)sd_imageProgress { + objc_setAssociatedObject(self, @selector(sd_imageProgress), sd_imageProgress, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)sd_internalSetImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + context:(nullable SDWebImageContext *)context + setImageBlock:(nullable SDSetImageBlock)setImageBlock + progress:(nullable SDImageLoaderProgressBlock)progressBlock + completed:(nullable SDInternalCompletionBlock)completedBlock { + if (context) { + // copy to avoid mutable object + context = [context copy]; + } else { + context = [NSDictionary dictionary]; + } + NSString *validOperationKey = context[SDWebImageContextSetImageOperationKey]; + if (!validOperationKey) { + // pass through the operation key to downstream, which can used for tracing operation or image view class + validOperationKey = NSStringFromClass([self class]); + SDWebImageMutableContext *mutableContext = [context mutableCopy]; + mutableContext[SDWebImageContextSetImageOperationKey] = validOperationKey; + context = [mutableContext copy]; + } + self.sd_latestOperationKey = validOperationKey; + [self sd_cancelImageLoadOperationWithKey:validOperationKey]; + self.sd_imageURL = url; + + SDWebImageManager *manager = context[SDWebImageContextCustomManager]; + if (!manager) { + manager = [SDWebImageManager sharedManager]; + } else { + // remove this manager to avoid retain cycle (manger -> loader -> operation -> context -> manager) + SDWebImageMutableContext *mutableContext = [context mutableCopy]; + mutableContext[SDWebImageContextCustomManager] = nil; + context = [mutableContext copy]; + } + + BOOL shouldUseWeakCache = NO; + if ([manager.imageCache isKindOfClass:SDImageCache.class]) { + shouldUseWeakCache = ((SDImageCache *)manager.imageCache).config.shouldUseWeakMemoryCache; + } + if (!(options & SDWebImageDelayPlaceholder)) { + if (shouldUseWeakCache) { + NSString *key = [manager cacheKeyForURL:url context:context]; + // call memory cache to trigger weak cache sync logic, ignore the return value and go on normal query + // this unfortunately will cause twice memory cache query, but it's fast enough + // in the future the weak cache feature may be re-design or removed + [((SDImageCache *)manager.imageCache) imageFromMemoryCacheForKey:key]; + } + dispatch_main_async_safe(^{ + [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:SDImageCacheTypeNone imageURL:url]; + }); + } + + if (url) { + // reset the progress + NSProgress *imageProgress = objc_getAssociatedObject(self, @selector(sd_imageProgress)); + if (imageProgress) { + imageProgress.totalUnitCount = 0; + imageProgress.completedUnitCount = 0; + } + +#if SD_UIKIT || SD_MAC + // check and start image indicator + [self sd_startImageIndicator]; + id imageIndicator = self.sd_imageIndicator; +#endif + + SDImageLoaderProgressBlock combinedProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) { + if (imageProgress) { + imageProgress.totalUnitCount = expectedSize; + imageProgress.completedUnitCount = receivedSize; + } +#if SD_UIKIT || SD_MAC + if ([imageIndicator respondsToSelector:@selector(updateIndicatorProgress:)]) { + double progress = 0; + if (expectedSize != 0) { + progress = (double)receivedSize / expectedSize; + } + progress = MAX(MIN(progress, 1), 0); // 0.0 - 1.0 + dispatch_async(dispatch_get_main_queue(), ^{ + [imageIndicator updateIndicatorProgress:progress]; + }); + } +#endif + if (progressBlock) { + progressBlock(receivedSize, expectedSize, targetURL); + } + }; + @weakify(self); + id operation = [manager loadImageWithURL:url options:options context:context progress:combinedProgressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + @strongify(self); + if (!self) { return; } + // if the progress not been updated, mark it to complete state + if (imageProgress && finished && !error && imageProgress.totalUnitCount == 0 && imageProgress.completedUnitCount == 0) { + imageProgress.totalUnitCount = SDWebImageProgressUnitCountUnknown; + imageProgress.completedUnitCount = SDWebImageProgressUnitCountUnknown; + } + +#if SD_UIKIT || SD_MAC + // check and stop image indicator + if (finished) { + [self sd_stopImageIndicator]; + } +#endif + + BOOL shouldCallCompletedBlock = finished || (options & SDWebImageAvoidAutoSetImage); + BOOL shouldNotSetImage = ((image && (options & SDWebImageAvoidAutoSetImage)) || + (!image && !(options & SDWebImageDelayPlaceholder))); + SDWebImageNoParamsBlock callCompletedBlockClosure = ^{ + if (!self) { return; } + if (!shouldNotSetImage) { + [self sd_setNeedsLayout]; + } + if (completedBlock && shouldCallCompletedBlock) { + completedBlock(image, data, error, cacheType, finished, url); + } + }; + + // case 1a: we got an image, but the SDWebImageAvoidAutoSetImage flag is set + // OR + // case 1b: we got no image and the SDWebImageDelayPlaceholder is not set + if (shouldNotSetImage) { + dispatch_main_async_safe(callCompletedBlockClosure); + return; + } + + UIImage *targetImage = nil; + NSData *targetData = nil; + if (image) { + // case 2a: we got an image and the SDWebImageAvoidAutoSetImage is not set + targetImage = image; + targetData = data; + } else if (options & SDWebImageDelayPlaceholder) { + // case 2b: we got no image and the SDWebImageDelayPlaceholder flag is set + targetImage = placeholder; + targetData = nil; + } + +#if SD_UIKIT || SD_MAC + // check whether we should use the image transition + SDWebImageTransition *transition = nil; + BOOL shouldUseTransition = NO; + if (options & SDWebImageForceTransition) { + // Always + shouldUseTransition = YES; + } else if (cacheType == SDImageCacheTypeNone) { + // From network + shouldUseTransition = YES; + } else { + // From disk (and, user don't use sync query) + if (cacheType == SDImageCacheTypeMemory) { + shouldUseTransition = NO; + } else if (cacheType == SDImageCacheTypeDisk) { + if (options & SDWebImageQueryMemoryDataSync || options & SDWebImageQueryDiskDataSync) { + shouldUseTransition = NO; + } else { + shouldUseTransition = YES; + } + } else { + // Not valid cache type, fallback + shouldUseTransition = NO; + } + } + if (finished && shouldUseTransition) { + transition = self.sd_imageTransition; + } +#endif + dispatch_main_async_safe(^{ +#if SD_UIKIT || SD_MAC + [self sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL]; +#else + [self sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:cacheType imageURL:imageURL]; +#endif + callCompletedBlockClosure(); + }); + }]; + [self sd_setImageLoadOperation:operation forKey:validOperationKey]; + } else { +#if SD_UIKIT || SD_MAC + [self sd_stopImageIndicator]; +#endif + dispatch_main_async_safe(^{ + if (completedBlock) { + NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Image url is nil"}]; + completedBlock(nil, nil, error, SDImageCacheTypeNone, YES, url); + } + }); + } +} + +- (void)sd_cancelCurrentImageLoad { + [self sd_cancelImageLoadOperationWithKey:self.sd_latestOperationKey]; + self.sd_latestOperationKey = nil; +} + +- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL { +#if SD_UIKIT || SD_MAC + [self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:cacheType imageURL:imageURL]; +#else + // watchOS does not support view transition. Simplify the logic + if (setImageBlock) { + setImageBlock(image, imageData, cacheType, imageURL); + } else if ([self isKindOfClass:[UIImageView class]]) { + UIImageView *imageView = (UIImageView *)self; + [imageView setImage:image]; + } +#endif +} + +#if SD_UIKIT || SD_MAC +- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL { + UIView *view = self; + SDSetImageBlock finalSetImageBlock; + if (setImageBlock) { + finalSetImageBlock = setImageBlock; + } else if ([view isKindOfClass:[UIImageView class]]) { + UIImageView *imageView = (UIImageView *)view; + finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) { + imageView.image = setImage; + }; + } +#if SD_UIKIT + else if ([view isKindOfClass:[UIButton class]]) { + UIButton *button = (UIButton *)view; + finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) { + [button setImage:setImage forState:UIControlStateNormal]; + }; + } +#endif +#if SD_MAC + else if ([view isKindOfClass:[NSButton class]]) { + NSButton *button = (NSButton *)view; + finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) { + button.image = setImage; + }; + } +#endif + + if (transition) { + NSString *originalOperationKey = view.sd_latestOperationKey; + +#if SD_UIKIT + [UIView transitionWithView:view duration:0 options:0 animations:^{ + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + // 0 duration to let UIKit render placeholder and prepares block + if (transition.prepares) { + transition.prepares(view, image, imageData, cacheType, imageURL); + } + } completion:^(BOOL tempFinished) { + [UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{ + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + if (finalSetImageBlock && !transition.avoidAutoSetImage) { + finalSetImageBlock(image, imageData, cacheType, imageURL); + } + if (transition.animations) { + transition.animations(view, image); + } + } completion:^(BOOL finished) { + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + if (transition.completion) { + transition.completion(finished); + } + }]; + }]; +#elif SD_MAC + [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull prepareContext) { + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + // 0 duration to let AppKit render placeholder and prepares block + prepareContext.duration = 0; + if (transition.prepares) { + transition.prepares(view, image, imageData, cacheType, imageURL); + } + } completionHandler:^{ + [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + context.duration = transition.duration; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + CAMediaTimingFunction *timingFunction = transition.timingFunction; +#pragma clang diagnostic pop + if (!timingFunction) { + timingFunction = SDTimingFunctionFromAnimationOptions(transition.animationOptions); + } + context.timingFunction = timingFunction; + context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation); + if (finalSetImageBlock && !transition.avoidAutoSetImage) { + finalSetImageBlock(image, imageData, cacheType, imageURL); + } + CATransition *trans = SDTransitionFromAnimationOptions(transition.animationOptions); + if (trans) { + [view.layer addAnimation:trans forKey:kCATransition]; + } + if (transition.animations) { + transition.animations(view, image); + } + } completionHandler:^{ + if (!view.sd_latestOperationKey || ![originalOperationKey isEqualToString:view.sd_latestOperationKey]) { + return; + } + if (transition.completion) { + transition.completion(YES); + } + }]; + }]; +#endif + } else { + if (finalSetImageBlock) { + finalSetImageBlock(image, imageData, cacheType, imageURL); + } + } +} +#endif + +- (void)sd_setNeedsLayout { +#if SD_UIKIT + [self setNeedsLayout]; +#elif SD_MAC + [self setNeedsLayout:YES]; +#elif SD_WATCH + // Do nothing because WatchKit automatically layout the view after property change +#endif +} + +#if SD_UIKIT || SD_MAC + +#pragma mark - Image Transition +- (SDWebImageTransition *)sd_imageTransition { + return objc_getAssociatedObject(self, @selector(sd_imageTransition)); +} + +- (void)setSd_imageTransition:(SDWebImageTransition *)sd_imageTransition { + objc_setAssociatedObject(self, @selector(sd_imageTransition), sd_imageTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - Indicator +- (id)sd_imageIndicator { + return objc_getAssociatedObject(self, @selector(sd_imageIndicator)); +} + +- (void)setSd_imageIndicator:(id)sd_imageIndicator { + // Remove the old indicator view + id previousIndicator = self.sd_imageIndicator; + [previousIndicator.indicatorView removeFromSuperview]; + + objc_setAssociatedObject(self, @selector(sd_imageIndicator), sd_imageIndicator, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + // Add the new indicator view + UIView *view = sd_imageIndicator.indicatorView; + if (CGRectEqualToRect(view.frame, CGRectZero)) { + view.frame = self.bounds; + } + // Center the indicator view +#if SD_MAC + [view setFrameOrigin:CGPointMake(round((NSWidth(self.bounds) - NSWidth(view.frame)) / 2), round((NSHeight(self.bounds) - NSHeight(view.frame)) / 2))]; +#else + view.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); +#endif + view.hidden = NO; + [self addSubview:view]; +} + +- (void)sd_startImageIndicator { + id imageIndicator = self.sd_imageIndicator; + if (!imageIndicator) { + return; + } + dispatch_main_async_safe(^{ + [imageIndicator startAnimatingIndicator]; + }); +} + +- (void)sd_stopImageIndicator { + id imageIndicator = self.sd_imageIndicator; + if (!imageIndicator) { + return; + } + dispatch_main_async_safe(^{ + [imageIndicator stopAnimatingIndicator]; + }); +} + +#endif + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.h new file mode 100644 index 00000000..53a7045c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.h @@ -0,0 +1,48 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageOperation.h" + +/** + These methods are used to support canceling for UIView image loading, it's designed to be used internal but not external. + All the stored operations are weak, so it will be dealloced after image loading finished. If you need to store operations, use your own class to keep a strong reference for them. + */ +@interface UIView (WebCacheOperation) + +/** + * Get the image load operation for key + * + * @param key key for identifying the operations + * @return the image load operation + */ +- (nullable id)sd_imageLoadOperationForKey:(nullable NSString *)key; + +/** + * Set the image load operation (storage in a UIView based weak map table) + * + * @param operation the operation + * @param key key for storing the operation + */ +- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key; + +/** + * Cancel all operations for the current UIView and key + * + * @param key key for identifying the operations + */ +- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key; + +/** + * Just remove the operations corresponding to the current UIView and key without cancelling them + * + * @param key key for identifying the operations + */ +- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.m new file mode 100644 index 00000000..adb2c105 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Core/UIView+WebCacheOperation.m @@ -0,0 +1,84 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIView+WebCacheOperation.h" +#import "objc/runtime.h" + +static char loadOperationKey; + +// key is strong, value is weak because operation instance is retained by SDWebImageManager's runningOperations property +// we should use lock to keep thread-safe because these method may not be accessed from main queue +typedef NSMapTable> SDOperationsDictionary; + +@implementation UIView (WebCacheOperation) + +- (SDOperationsDictionary *)sd_operationDictionary { + @synchronized(self) { + SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); + if (operations) { + return operations; + } + operations = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0]; + objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + return operations; + } +} + +- (nullable id)sd_imageLoadOperationForKey:(nullable NSString *)key { + id operation; + if (key) { + SDOperationsDictionary *operationDictionary = [self sd_operationDictionary]; + @synchronized (self) { + operation = [operationDictionary objectForKey:key]; + } + } + return operation; +} + +- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key { + if (key) { + [self sd_cancelImageLoadOperationWithKey:key]; + if (operation) { + SDOperationsDictionary *operationDictionary = [self sd_operationDictionary]; + @synchronized (self) { + [operationDictionary setObject:operation forKey:key]; + } + } + } +} + +- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key { + if (key) { + // Cancel in progress downloader from queue + SDOperationsDictionary *operationDictionary = [self sd_operationDictionary]; + id operation; + + @synchronized (self) { + operation = [operationDictionary objectForKey:key]; + } + if (operation) { + if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) { + [operation cancel]; + } + @synchronized (self) { + [operationDictionary removeObjectForKey:key]; + } + } + } +} + +- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key { + if (key) { + SDOperationsDictionary *operationDictionary = [self sd_operationDictionary]; + @synchronized (self) { + [operationDictionary removeObjectForKey:key]; + } + } +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.h new file mode 100644 index 00000000..dfec18b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.h @@ -0,0 +1,24 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +#import "UIImage+Transform.h" + +@interface NSBezierPath (SDRoundedCorners) + +/** + Convenience way to create a bezier path with the specify rounding corners on macOS. Same as the one on `UIBezierPath`. + */ ++ (nonnull instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius; + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.m new file mode 100644 index 00000000..b6f7a011 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/NSBezierPath+SDRoundedCorners.m @@ -0,0 +1,42 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSBezierPath+SDRoundedCorners.h" + +#if SD_MAC + +@implementation NSBezierPath (SDRoundedCorners) + ++ (instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius { + NSBezierPath *path = [NSBezierPath bezierPath]; + + CGFloat maxCorner = MIN(NSWidth(rect), NSHeight(rect)) / 2; + + CGFloat topLeftRadius = MIN(maxCorner, (corners & SDRectCornerTopLeft) ? cornerRadius : 0); + CGFloat topRightRadius = MIN(maxCorner, (corners & SDRectCornerTopRight) ? cornerRadius : 0); + CGFloat bottomLeftRadius = MIN(maxCorner, (corners & SDRectCornerBottomLeft) ? cornerRadius : 0); + CGFloat bottomRightRadius = MIN(maxCorner, (corners & SDRectCornerBottomRight) ? cornerRadius : 0); + + NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); + NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); + NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect)); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect)); + + [path moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))]; + [path appendBezierPathWithArcFromPoint:topLeft toPoint:bottomLeft radius:topLeftRadius]; + [path appendBezierPathWithArcFromPoint:bottomLeft toPoint:bottomRight radius:bottomLeftRadius]; + [path appendBezierPathWithArcFromPoint:bottomRight toPoint:topRight radius:bottomRightRadius]; + [path appendBezierPathWithArcFromPoint:topRight toPoint:topLeft radius:topRightRadius]; + [path closePath]; + + return path; +} + +@end + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.h new file mode 100644 index 00000000..199cf4fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.h @@ -0,0 +1,14 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDWebImageCompat.h" + +/// Copy the associated object from source image to target image. The associated object including all the category read/write properties. +/// @param source source +/// @param target target +FOUNDATION_EXPORT void SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable target); diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.m new file mode 100644 index 00000000..a7c70763 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAssociatedObject.m @@ -0,0 +1,27 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDAssociatedObject.h" +#import "UIImage+Metadata.h" +#import "UIImage+ExtendedCacheData.h" +#import "UIImage+MemoryCacheCost.h" +#import "UIImage+ForceDecode.h" + +void SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable target) { + if (!source || !target) { + return; + } + // Image Metadata + target.sd_isIncremental = source.sd_isIncremental; + target.sd_imageLoopCount = source.sd_imageLoopCount; + target.sd_imageFormat = source.sd_imageFormat; + // Force Decode + target.sd_isDecoded = source.sd_isDecoded; + // Extended Cache Data + target.sd_extendedObject = source.sd_extendedObject; +} diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.h new file mode 100644 index 00000000..a3480deb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.h @@ -0,0 +1,21 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +@class SDAsyncBlockOperation; +typedef void (^SDAsyncBlock)(SDAsyncBlockOperation * __nonnull asyncOperation); + +/// A async block operation, success after you call `completer` (not like `NSBlockOperation` which is for sync block, success on return) +@interface SDAsyncBlockOperation : NSOperation + +- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block; ++ (nonnull instancetype)blockOperationWithBlock:(nonnull SDAsyncBlock)block; +- (void)complete; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.m new file mode 100644 index 00000000..0b2fefec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDAsyncBlockOperation.m @@ -0,0 +1,92 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDAsyncBlockOperation.h" + +@interface SDAsyncBlockOperation () + +@property (assign, nonatomic, getter = isExecuting) BOOL executing; +@property (assign, nonatomic, getter = isFinished) BOOL finished; +@property (nonatomic, copy, nonnull) SDAsyncBlock executionBlock; + +@end + +@implementation SDAsyncBlockOperation + +@synthesize executing = _executing; +@synthesize finished = _finished; + +- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block { + self = [super init]; + if (self) { + self.executionBlock = block; + } + return self; +} + ++ (nonnull instancetype)blockOperationWithBlock:(nonnull SDAsyncBlock)block { + SDAsyncBlockOperation *operation = [[SDAsyncBlockOperation alloc] initWithBlock:block]; + return operation; +} + +- (void)start { + @synchronized (self) { + if (self.isCancelled) { + self.finished = YES; + return; + } + + self.finished = NO; + self.executing = YES; + + if (self.executionBlock) { + self.executionBlock(self); + } else { + self.executing = NO; + self.finished = YES; + } + } +} + +- (void)cancel { + @synchronized (self) { + [super cancel]; + if (self.isExecuting) { + self.executing = NO; + self.finished = YES; + } + } +} + + +- (void)complete { + @synchronized (self) { + if (self.isExecuting) { + self.finished = YES; + self.executing = NO; + } + } + } + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _finished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _executing = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isConcurrent { + return YES; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.h new file mode 100644 index 00000000..5d5676b1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.h @@ -0,0 +1,18 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" + +/// Device information helper methods +@interface SDDeviceHelper : NSObject + ++ (NSUInteger)totalMemory; ++ (NSUInteger)freeMemory; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.m new file mode 100644 index 00000000..83d02296 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDeviceHelper.m @@ -0,0 +1,32 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDDeviceHelper.h" +#import + +@implementation SDDeviceHelper + ++ (NSUInteger)totalMemory { + return (NSUInteger)[[NSProcessInfo processInfo] physicalMemory]; +} + ++ (NSUInteger)freeMemory { + mach_port_t host_port = mach_host_self(); + mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); + vm_size_t page_size; + vm_statistics_data_t vm_stat; + kern_return_t kern; + + kern = host_page_size(host_port, &page_size); + if (kern != KERN_SUCCESS) return 0; + kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size); + if (kern != KERN_SUCCESS) return 0; + return vm_stat.free_count * page_size; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.h new file mode 100644 index 00000000..3ee8c6fd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.h @@ -0,0 +1,29 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDWebImageCompat.h" + +/// Cross-platform display link wrapper. Do not retain the target +/// Use `CADisplayLink` on iOS/tvOS, `CVDisplayLink` on macOS, `NSTimer` on watchOS +@interface SDDisplayLink : NSObject + +@property (readonly, nonatomic, weak, nullable) id target; +@property (readonly, nonatomic, assign, nonnull) SEL selector; +@property (readonly, nonatomic) CFTimeInterval duration; +@property (readonly, nonatomic) BOOL isRunning; + ++ (nonnull instancetype)displayLinkWithTarget:(nonnull id)target selector:(nonnull SEL)sel; + +- (void)addToRunLoop:(nonnull NSRunLoop *)runloop forMode:(nonnull NSRunLoopMode)mode; +- (void)removeFromRunLoop:(nonnull NSRunLoop *)runloop forMode:(nonnull NSRunLoopMode)mode; + +- (void)start; +- (void)stop; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.m new file mode 100644 index 00000000..1dcfd99f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDDisplayLink.m @@ -0,0 +1,227 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDDisplayLink.h" +#import "SDWeakProxy.h" +#if SD_MAC +#import +#elif SD_IOS || SD_TV +#import +#endif + +#if SD_MAC +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext); +#endif + +#define kSDDisplayLinkInterval 1.0 / 60 + +@interface SDDisplayLink () + +#if SD_MAC +@property (nonatomic, assign) CVDisplayLinkRef displayLink; +@property (nonatomic, assign) CVTimeStamp outputTime; +@property (nonatomic, copy) NSRunLoopMode runloopMode; +#elif SD_IOS || SD_TV +@property (nonatomic, strong) CADisplayLink *displayLink; +#else +@property (nonatomic, strong) NSTimer *displayLink; +@property (nonatomic, strong) NSRunLoop *runloop; +@property (nonatomic, copy) NSRunLoopMode runloopMode; +@property (nonatomic, assign) NSTimeInterval currentFireDate; +#endif + +@end + +@implementation SDDisplayLink + +- (void)dealloc { +#if SD_MAC + if (_displayLink) { + CVDisplayLinkRelease(_displayLink); + _displayLink = NULL; + } +#elif SD_IOS || SD_TV + [_displayLink invalidate]; + _displayLink = nil; +#else + [_displayLink invalidate]; + _displayLink = nil; +#endif +} + +- (instancetype)initWithTarget:(id)target selector:(SEL)sel { + self = [super init]; + if (self) { + _target = target; + _selector = sel; +#if SD_MAC + CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink); + CVDisplayLinkSetOutputCallback(_displayLink, DisplayLinkCallback, (__bridge void *)self); +#elif SD_IOS || SD_TV + SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self]; + _displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayLinkDidRefresh:)]; +#else + SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self]; + _displayLink = [NSTimer timerWithTimeInterval:kSDDisplayLinkInterval target:weakProxy selector:@selector(displayLinkDidRefresh:) userInfo:nil repeats:YES]; +#endif + } + return self; +} + ++ (instancetype)displayLinkWithTarget:(id)target selector:(SEL)sel { + SDDisplayLink *displayLink = [[SDDisplayLink alloc] initWithTarget:target selector:sel]; + return displayLink; +} + +- (CFTimeInterval)duration { +#if SD_MAC + CVTimeStamp outputTime = self.outputTime; + NSTimeInterval duration = 0; + double periodPerSecond = (double)outputTime.videoTimeScale * outputTime.rateScalar; + if (periodPerSecond > 0) { + duration = (double)outputTime.videoRefreshPeriod / periodPerSecond; + } +#elif SD_IOS || SD_TV +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSTimeInterval duration = 0; + if (@available(iOS 10.0, tvOS 10.0, *)) { + duration = self.displayLink.targetTimestamp - CACurrentMediaTime(); + } else { + duration = self.displayLink.duration * self.displayLink.frameInterval; + } +#pragma clang diagnostic pop +#else + NSTimeInterval duration = 0; + if (self.displayLink.isValid && self.currentFireDate != 0) { + NSTimeInterval nextFireDate = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink); + duration = nextFireDate - self.currentFireDate; + } +#endif + if (duration <= 0) { + duration = kSDDisplayLinkInterval; + } + return duration; +} + +- (BOOL)isRunning { +#if SD_MAC + return CVDisplayLinkIsRunning(self.displayLink); +#elif SD_IOS || SD_TV + return !self.displayLink.isPaused; +#else + return self.displayLink.isValid; +#endif +} + +- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode { + if (!runloop || !mode) { + return; + } +#if SD_MAC + self.runloopMode = mode; +#elif SD_IOS || SD_TV + [self.displayLink addToRunLoop:runloop forMode:mode]; +#else + self.runloop = runloop; + self.runloopMode = mode; + CFRunLoopMode cfMode; + if ([mode isEqualToString:NSDefaultRunLoopMode]) { + cfMode = kCFRunLoopDefaultMode; + } else if ([mode isEqualToString:NSRunLoopCommonModes]) { + cfMode = kCFRunLoopCommonModes; + } else { + cfMode = (__bridge CFStringRef)mode; + } + CFRunLoopAddTimer(runloop.getCFRunLoop, (__bridge CFRunLoopTimerRef)self.displayLink, cfMode); +#endif +} + +- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode { + if (!runloop || !mode) { + return; + } +#if SD_MAC + self.runloopMode = nil; +#elif SD_IOS || SD_TV + [self.displayLink removeFromRunLoop:runloop forMode:mode]; +#else + self.runloop = nil; + self.runloopMode = nil; + CFRunLoopMode cfMode; + if ([mode isEqualToString:NSDefaultRunLoopMode]) { + cfMode = kCFRunLoopDefaultMode; + } else if ([mode isEqualToString:NSRunLoopCommonModes]) { + cfMode = kCFRunLoopCommonModes; + } else { + cfMode = (__bridge CFStringRef)mode; + } + CFRunLoopRemoveTimer(runloop.getCFRunLoop, (__bridge CFRunLoopTimerRef)self.displayLink, cfMode); +#endif +} + +- (void)start { +#if SD_MAC + CVDisplayLinkStart(self.displayLink); +#elif SD_IOS || SD_TV + self.displayLink.paused = NO; +#else + if (self.displayLink.isValid) { + [self.displayLink fire]; + } else { + SDWeakProxy *weakProxy = [SDWeakProxy proxyWithTarget:self]; + self.displayLink = [NSTimer timerWithTimeInterval:kSDDisplayLinkInterval target:weakProxy selector:@selector(displayLinkDidRefresh:) userInfo:nil repeats:YES]; + [self addToRunLoop:self.runloop forMode:self.runloopMode]; + } +#endif +} + +- (void)stop { +#if SD_MAC + CVDisplayLinkStop(self.displayLink); +#elif SD_IOS || SD_TV + self.displayLink.paused = YES; +#else + [self.displayLink invalidate]; +#endif +} + +- (void)displayLinkDidRefresh:(id)displayLink { +#if SD_MAC + // CVDisplayLink does not use runloop, but we can provide similar behavior for modes + // May use `default` runloop to avoid extra callback when in `eventTracking` (mouse drag, scroll) or `modalPanel` (modal panel) + NSString *runloopMode = self.runloopMode; + if (![runloopMode isEqualToString:NSRunLoopCommonModes] && ![runloopMode isEqualToString:NSRunLoop.mainRunLoop.currentMode]) { + return; + } +#endif +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [_target performSelector:_selector withObject:self]; +#pragma clang diagnostic pop +#if SD_WATCH + self.currentFireDate = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink); +#endif +} + +@end + +#if SD_MAC +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { + // CVDisplayLink callback is not on main queue + SDDisplayLink *object = (__bridge SDDisplayLink *)displayLinkContext; + if (inOutputTime) { + object.outputTime = *inOutputTime; + } + __weak SDDisplayLink *weakObject = object; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakObject displayLinkDidRefresh:(__bridge id)(displayLink)]; + }); + return kCVReturnSuccess; +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.h new file mode 100644 index 00000000..3ce6bade --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.h @@ -0,0 +1,19 @@ +// +// This file is from https://gist.github.com/zydeco/6292773 +// +// Created by Jesús A. Álvarez on 2008-12-17. +// Copyright 2008-2009 namedfork.net. All rights reserved. +// + +#import + +/// File Extended Attribute (xattr) helper methods +@interface SDFileAttributeHelper : NSObject + ++ (nullable NSArray *)extendedAttributeNamesAtPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err; ++ (BOOL)hasExtendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err; ++ (nullable NSData *)extendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err; ++ (BOOL)setExtendedAttribute:(nonnull NSString *)name value:(nonnull NSData *)value atPath:(nonnull NSString *)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError * _Nullable * _Nullable)err; ++ (BOOL)removeExtendedAttribute:(nonnull NSString *)name atPath:(nonnull NSString *)path traverseLink:(BOOL)follow error:(NSError * _Nullable * _Nullable)err; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.m new file mode 100644 index 00000000..5122089d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDFileAttributeHelper.m @@ -0,0 +1,127 @@ +// +// This file is from https://gist.github.com/zydeco/6292773 +// +// Created by Jesús A. Álvarez on 2008-12-17. +// Copyright 2008-2009 namedfork.net. All rights reserved. +// + +#import "SDFileAttributeHelper.h" +#import + +@implementation SDFileAttributeHelper + ++ (NSArray*)extendedAttributeNamesAtPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err { + int flags = follow? 0 : XATTR_NOFOLLOW; + + // get size of name list + ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags); + if (nameBuffLen == -1) { + if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo: + @{ + @"error": [NSString stringWithUTF8String:strerror(errno)], + @"function": @"listxattr", + @":path": path, + @":traverseLink": @(follow) + } + ]; + return nil; + } else if (nameBuffLen == 0) return @[]; + + // get name list + NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen]; + listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags); + + // convert to array + NSMutableArray * names = [NSMutableArray arrayWithCapacity:5]; + char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen; + for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName)) + [names addObject:[NSString stringWithUTF8String:nextName]]; + return names.copy; +} + ++ (BOOL)hasExtendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err { + int flags = follow? 0 : XATTR_NOFOLLOW; + + // get size of name list + ssize_t nameBuffLen = listxattr([path fileSystemRepresentation], NULL, 0, flags); + if (nameBuffLen == -1) { + if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo: + @{ + @"error": [NSString stringWithUTF8String:strerror(errno)], + @"function": @"listxattr", + @":path": path, + @":traverseLink": @(follow) + } + ]; + return NO; + } else if (nameBuffLen == 0) return NO; + + // get name list + NSMutableData *nameBuff = [NSMutableData dataWithLength:nameBuffLen]; + listxattr([path fileSystemRepresentation], [nameBuff mutableBytes], nameBuffLen, flags); + + // find our name + char *nextName, *endOfNames = [nameBuff mutableBytes] + nameBuffLen; + for(nextName = [nameBuff mutableBytes]; nextName < endOfNames; nextName += 1+strlen(nextName)) + if (strcmp(nextName, [name UTF8String]) == 0) return YES; + return NO; +} + ++ (NSData *)extendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err { + int flags = follow? 0 : XATTR_NOFOLLOW; + // get length + ssize_t attrLen = getxattr([path fileSystemRepresentation], [name UTF8String], NULL, 0, 0, flags); + if (attrLen == -1) { + if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo: + @{ + @"error": [NSString stringWithUTF8String:strerror(errno)], + @"function": @"getxattr", + @":name": name, + @":path": path, + @":traverseLink": @(follow) + } + ]; + return nil; + } + + // get attribute data + NSMutableData *attrData = [NSMutableData dataWithLength:attrLen]; + getxattr([path fileSystemRepresentation], [name UTF8String], [attrData mutableBytes], attrLen, 0, flags); + return attrData; +} + ++ (BOOL)setExtendedAttribute:(NSString *)name value:(NSData *)value atPath:(NSString *)path traverseLink:(BOOL)follow overwrite:(BOOL)overwrite error:(NSError **)err { + int flags = (follow? 0 : XATTR_NOFOLLOW) | (overwrite? 0 : XATTR_CREATE); + if (0 == setxattr([path fileSystemRepresentation], [name UTF8String], [value bytes], [value length], 0, flags)) return YES; + // error + if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo: + @{ + @"error": [NSString stringWithUTF8String:strerror(errno)], + @"function": @"setxattr", + @":name": name, + @":value.length": @(value.length), + @":path": path, + @":traverseLink": @(follow), + @":overwrite": @(overwrite) + } + ]; + return NO; +} + ++ (BOOL)removeExtendedAttribute:(NSString *)name atPath:(NSString *)path traverseLink:(BOOL)follow error:(NSError **)err { + int flags = (follow? 0 : XATTR_NOFOLLOW); + if (0 == removexattr([path fileSystemRepresentation], [name UTF8String], flags)) return YES; + // error + if (err) *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo: + @{ + @"error": [NSString stringWithUTF8String:strerror(errno)], + @"function": @"removexattr", + @":name": name, + @":path": path, + @":traverseLink": @(follow) + } + ]; + return NO; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.h new file mode 100644 index 00000000..88dee489 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.h @@ -0,0 +1,23 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/// A Image-Asset manager to work like UIKit/AppKit's image cache behavior +/// Apple parse the Asset Catalog compiled file(`Assets.car`) by CoreUI.framework, however it's a private framework and there are no other ways to directly get the data. So we just process the normal bundle files :) +@interface SDImageAssetManager : NSObject + +@property (nonatomic, strong, nonnull) NSMapTable *imageTable; + ++ (nonnull instancetype)sharedAssetManager; +- (nullable NSString *)getPathForName:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle preferredScale:(nonnull CGFloat *)scale; +- (nullable UIImage *)imageForName:(nonnull NSString *)name; +- (void)storeImage:(nonnull UIImage *)image forName:(nonnull NSString *)name; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.m new file mode 100644 index 00000000..50a4da94 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageAssetManager.m @@ -0,0 +1,158 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageAssetManager.h" +#import "SDInternalMacros.h" + +static NSArray *SDBundlePreferredScales() { + static NSArray *scales; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#if SD_WATCH + CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale; +#elif SD_UIKIT + CGFloat screenScale = [UIScreen mainScreen].scale; +#elif SD_MAC + CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor; +#endif + if (screenScale <= 1) { + scales = @[@1,@2,@3]; + } else if (screenScale <= 2) { + scales = @[@2,@3,@1]; + } else { + scales = @[@3,@2,@1]; + } + }); + return scales; +} + +@implementation SDImageAssetManager { + SD_LOCK_DECLARE(_lock); +} + ++ (instancetype)sharedAssetManager { + static dispatch_once_t onceToken; + static SDImageAssetManager *assetManager; + dispatch_once(&onceToken, ^{ + assetManager = [[SDImageAssetManager alloc] init]; + }); + return assetManager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + NSPointerFunctionsOptions valueOptions; +#if SD_MAC + // Apple says that NSImage use a weak reference to value + valueOptions = NSPointerFunctionsWeakMemory; +#else + // Apple says that UIImage use a strong reference to value + valueOptions = NSPointerFunctionsStrongMemory; +#endif + _imageTable = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsCopyIn valueOptions:valueOptions]; + SD_LOCK_INIT(_lock); +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (void)dealloc { +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification { + SD_LOCK(_lock); + [self.imageTable removeAllObjects]; + SD_UNLOCK(_lock); +} + +- (NSString *)getPathForName:(NSString *)name bundle:(NSBundle *)bundle preferredScale:(CGFloat *)scale { + NSParameterAssert(name); + NSParameterAssert(bundle); + NSString *path; + if (name.length == 0) { + return path; + } + if ([name hasSuffix:@"/"]) { + return path; + } + NSString *extension = name.pathExtension; + if (extension.length == 0) { + // If no extension, follow Apple's doc, check PNG format + extension = @"png"; + } + name = [name stringByDeletingPathExtension]; + + CGFloat providedScale = *scale; + NSArray *scales = SDBundlePreferredScales(); + + // Check if file name contains scale + for (size_t i = 0; i < scales.count; i++) { + NSNumber *scaleValue = scales[i]; + if ([name hasSuffix:[NSString stringWithFormat:@"@%@x", scaleValue]]) { + path = [bundle pathForResource:name ofType:extension]; + if (path) { + *scale = scaleValue.doubleValue; // override + return path; + } + } + } + + // Search with provided scale first + if (providedScale != 0) { + NSString *scaledName = [name stringByAppendingFormat:@"@%@x", @(providedScale)]; + path = [bundle pathForResource:scaledName ofType:extension]; + if (path) { + return path; + } + } + + // Search with preferred scale + for (size_t i = 0; i < scales.count; i++) { + NSNumber *scaleValue = scales[i]; + if (scaleValue.doubleValue == providedScale) { + // Ignore provided scale + continue; + } + NSString *scaledName = [name stringByAppendingFormat:@"@%@x", scaleValue]; + path = [bundle pathForResource:scaledName ofType:extension]; + if (path) { + *scale = scaleValue.doubleValue; // override + return path; + } + } + + // Search without scale + path = [bundle pathForResource:name ofType:extension]; + + return path; +} + +- (UIImage *)imageForName:(NSString *)name { + NSParameterAssert(name); + UIImage *image; + SD_LOCK(_lock); + image = [self.imageTable objectForKey:name]; + SD_UNLOCK(_lock); + return image; +} + +- (void)storeImage:(UIImage *)image forName:(NSString *)name { + NSParameterAssert(image); + NSParameterAssert(name); + SD_LOCK(_lock); + [self.imageTable setObject:image forKey:name]; + SD_UNLOCK(_lock); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.h new file mode 100644 index 00000000..0debe6ca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.h @@ -0,0 +1,21 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/// This is used for operation management, but not for operation queue execute +@interface SDImageCachesManagerOperation : NSOperation + +@property (nonatomic, assign, readonly) NSUInteger pendingCount; + +- (void)beginWithTotalCount:(NSUInteger)totalCount; +- (void)completeOne; +- (void)done; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.m new file mode 100644 index 00000000..1313b683 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageCachesManagerOperation.m @@ -0,0 +1,83 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCachesManagerOperation.h" +#import "SDInternalMacros.h" + +@implementation SDImageCachesManagerOperation { + SD_LOCK_DECLARE(_pendingCountLock); +} + +@synthesize executing = _executing; +@synthesize finished = _finished; +@synthesize cancelled = _cancelled; +@synthesize pendingCount = _pendingCount; + +- (instancetype)init { + if (self = [super init]) { + SD_LOCK_INIT(_pendingCountLock); + _pendingCount = 0; + } + return self; +} + +- (void)beginWithTotalCount:(NSUInteger)totalCount { + self.executing = YES; + self.finished = NO; + _pendingCount = totalCount; +} + +- (NSUInteger)pendingCount { + SD_LOCK(_pendingCountLock); + NSUInteger pendingCount = _pendingCount; + SD_UNLOCK(_pendingCountLock); + return pendingCount; +} + +- (void)completeOne { + SD_LOCK(_pendingCountLock); + _pendingCount = _pendingCount > 0 ? _pendingCount - 1 : 0; + SD_UNLOCK(_pendingCountLock); +} + +- (void)cancel { + self.cancelled = YES; + [self reset]; +} + +- (void)done { + self.finished = YES; + self.executing = NO; + [self reset]; +} + +- (void)reset { + SD_LOCK(_pendingCountLock); + _pendingCount = 0; + SD_UNLOCK(_pendingCountLock); +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _finished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _executing = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (void)setCancelled:(BOOL)cancelled { + [self willChangeValueForKey:@"isCancelled"]; + _cancelled = cancelled; + [self didChangeValueForKey:@"isCancelled"]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageIOAnimatedCoderInternal.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageIOAnimatedCoderInternal.h new file mode 100644 index 00000000..f74be7e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDImageIOAnimatedCoderInternal.h @@ -0,0 +1,36 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import +#import "SDImageIOAnimatedCoder.h" + +// AVFileTypeHEIC/AVFileTypeHEIF is defined in AVFoundation via iOS 11, we use this without import AVFoundation +#define kSDUTTypeHEIC ((__bridge CFStringRef)@"public.heic") +#define kSDUTTypeHEIF ((__bridge CFStringRef)@"public.heif") +// HEIC Sequence (Animated Image) +#define kSDUTTypeHEICS ((__bridge CFStringRef)@"public.heics") +// kSDUTTypeWebP seems not defined in public UTI framework, Apple use the hardcode string, we define them :) +#define kSDUTTypeWebP ((__bridge CFStringRef)@"org.webmproject.webp") + +#define kSDUTTypeImage ((__bridge CFStringRef)@"public.image") +#define kSDUTTypeJPEG ((__bridge CFStringRef)@"public.jpeg") +#define kSDUTTypePNG ((__bridge CFStringRef)@"public.png") +#define kSDUTTypeTIFF ((__bridge CFStringRef)@"public.tiff") +#define kSDUTTypeSVG ((__bridge CFStringRef)@"public.svg-image") +#define kSDUTTypeGIF ((__bridge CFStringRef)@"com.compuserve.gif") +#define kSDUTTypePDF ((__bridge CFStringRef)@"com.adobe.pdf") + +@interface SDImageIOAnimatedCoder () + ++ (NSTimeInterval)frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source; ++ (NSUInteger)imageLoopCountWithSource:(nonnull CGImageSourceRef)source; ++ (nullable UIImage *)createFrameAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(nullable NSDictionary *)options; ++ (BOOL)canEncodeToFormat:(SDImageFormat)format; ++ (BOOL)canDecodeFromFormat:(SDImageFormat)format; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.h new file mode 100644 index 00000000..dfff5585 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.h @@ -0,0 +1,122 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import +#import +#import "SDmetamacros.h" + +#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\ + (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\ + (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\ + (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\ + (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) + +#ifndef SD_LOCK_DECLARE +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock +#else +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ +OSSpinLock lock##_deprecated; +#endif +#endif + +#ifndef SD_LOCK_DECLARE_STATIC +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock +#else +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ +static OSSpinLock lock##_deprecated; +#endif +#endif + +#ifndef SD_LOCK_INIT +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT +#else +#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \ +else lock##_deprecated = OS_SPINLOCK_INIT; +#endif +#endif + +#ifndef SD_LOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK(lock) os_unfair_lock_lock(&lock) +#else +#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \ +else OSSpinLockLock(&lock##_deprecated); +#endif +#endif + +#ifndef SD_UNLOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock) +#else +#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \ +else OSSpinLockUnlock(&lock##_deprecated); +#endif +#endif + +#ifndef SD_OPTIONS_CONTAINS +#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value)) +#endif + +#ifndef SD_CSTRING +#define SD_CSTRING(str) #str +#endif + +#ifndef SD_NSSTRING +#define SD_NSSTRING(str) @(SD_CSTRING(str)) +#endif + +#ifndef SD_SEL_SPI +#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(name)]) +#endif + +#ifndef weakify +#define weakify(...) \ +sd_keywordify \ +metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__) +#endif + +#ifndef strongify +#define strongify(...) \ +sd_keywordify \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Wshadow\"") \ +metamacro_foreach(sd_strongify_,, __VA_ARGS__) \ +_Pragma("clang diagnostic pop") +#endif + +#define sd_weakify_(INDEX, CONTEXT, VAR) \ +CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); + +#define sd_strongify_(INDEX, VAR) \ +__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_); + +#if DEBUG +#define sd_keywordify autoreleasepool {} +#else +#define sd_keywordify try {} @catch (...) {} +#endif + +#ifndef onExit +#define onExit \ +sd_keywordify \ +__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^ +#endif + +typedef void (^sd_cleanupBlock_t)(void); + +#if defined(__cplusplus) +extern "C" { +#endif + void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block); +#if defined(__cplusplus) +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.m new file mode 100644 index 00000000..e4981af2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDInternalMacros.m @@ -0,0 +1,13 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDInternalMacros.h" + +void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block) { + (*block)(); +} diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.h new file mode 100644 index 00000000..d92c682b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.h @@ -0,0 +1,20 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +/// A weak proxy which forward all the message to the target +@interface SDWeakProxy : NSProxy + +@property (nonatomic, weak, readonly, nullable) id target; + +- (nonnull instancetype)initWithTarget:(nonnull id)target; ++ (nonnull instancetype)proxyWithTarget:(nonnull id)target; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.m new file mode 100644 index 00000000..19a45931 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWeakProxy.m @@ -0,0 +1,79 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWeakProxy.h" + +@implementation SDWeakProxy + +- (instancetype)initWithTarget:(id)target { + _target = target; + return self; +} + ++ (instancetype)proxyWithTarget:(id)target { + return [[SDWeakProxy alloc] initWithTarget:target]; +} + +- (id)forwardingTargetForSelector:(SEL)selector { + return _target; +} + +- (void)forwardInvocation:(NSInvocation *)invocation { + void *null = NULL; + [invocation setReturnValue:&null]; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { + return [NSObject instanceMethodSignatureForSelector:@selector(init)]; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + return [_target respondsToSelector:aSelector]; +} + +- (BOOL)isEqual:(id)object { + return [_target isEqual:object]; +} + +- (NSUInteger)hash { + return [_target hash]; +} + +- (Class)superclass { + return [_target superclass]; +} + +- (Class)class { + return [_target class]; +} + +- (BOOL)isKindOfClass:(Class)aClass { + return [_target isKindOfClass:aClass]; +} + +- (BOOL)isMemberOfClass:(Class)aClass { + return [_target isMemberOfClass:aClass]; +} + +- (BOOL)conformsToProtocol:(Protocol *)aProtocol { + return [_target conformsToProtocol:aProtocol]; +} + +- (BOOL)isProxy { + return YES; +} + +- (NSString *)description { + return [_target description]; +} + +- (NSString *)debugDescription { + return [_target debugDescription]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWebImageTransitionInternal.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWebImageTransitionInternal.h new file mode 100644 index 00000000..1b70649a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDWebImageTransitionInternal.h @@ -0,0 +1,19 @@ +/* +* This file is part of the SDWebImage package. +* (c) Olivier Poitrey +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +#import + +/// Helper method for Core Animation transition +FOUNDATION_EXPORT CAMediaTimingFunction * _Nullable SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options); +FOUNDATION_EXPORT CATransition * _Nullable SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options); + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDmetamacros.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDmetamacros.h new file mode 100644 index 00000000..dd90d99b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/SDmetamacros.h @@ -0,0 +1,667 @@ +/** + * Macros for metaprogramming + * ExtendedC + * + * Copyright (C) 2012 Justin Spahr-Summers + * Released under the MIT license + */ + +#ifndef EXTC_METAMACROS_H +#define EXTC_METAMACROS_H + + +/** + * Executes one or more expressions (which may have a void type, such as a call + * to a function that returns no value) and always returns true. + */ +#define metamacro_exprify(...) \ + ((__VA_ARGS__), true) + +/** + * Returns a string representation of VALUE after full macro expansion. + */ +#define metamacro_stringify(VALUE) \ + metamacro_stringify_(VALUE) + +/** + * Returns A and B concatenated after full macro expansion. + */ +#define metamacro_concat(A, B) \ + metamacro_concat_(A, B) + +/** + * Returns the Nth variadic argument (starting from zero). At least + * N + 1 variadic arguments must be given. N must be between zero and twenty, + * inclusive. + */ +#define metamacro_at(N, ...) \ + metamacro_concat(metamacro_at, N)(__VA_ARGS__) + +/** + * Returns the number of arguments (up to twenty) provided to the macro. At + * least one argument must be provided. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_argcount(...) \ + metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +/** + * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is + * given. Only the index and current argument will thus be passed to MACRO. + */ +#define metamacro_foreach(MACRO, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) + +/** + * For each consecutive variadic argument (up to twenty), MACRO is passed the + * zero-based index of the current argument, CONTEXT, and then the argument + * itself. The results of adjoining invocations of MACRO are then separated by + * SEP. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * Identical to #metamacro_foreach_cxt. This can be used when the former would + * fail due to recursive macro expansion. + */ +#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * In consecutive order, appends each variadic argument (up to twenty) onto + * BASE. The resulting concatenations are then separated by SEP. + * + * This is primarily useful to manipulate a list of macro invocations into instead + * invoking a different, possibly related macro. + */ +#define metamacro_foreach_concat(BASE, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) + +/** + * Iterates COUNT times, each time invoking MACRO with the current index + * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO + * are then separated by SEP. + * + * COUNT must be an integer between zero and twenty, inclusive. + */ +#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ + metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) + +/** + * Returns the first argument given. At least one argument must be provided. + * + * This is useful when implementing a variadic macro, where you may have only + * one variadic argument, but no way to retrieve it (for example, because \c ... + * always needs to match at least one argument). + * + * @code + +#define varmacro(...) \ + metamacro_head(__VA_ARGS__) + + * @endcode + */ +#define metamacro_head(...) \ + metamacro_head_(__VA_ARGS__, 0) + +/** + * Returns every argument except the first. At least two arguments must be + * provided. + */ +#define metamacro_tail(...) \ + metamacro_tail_(__VA_ARGS__) + +/** + * Returns the first N (up to twenty) variadic arguments as a new argument list. + * At least N variadic arguments must be provided. + */ +#define metamacro_take(N, ...) \ + metamacro_concat(metamacro_take, N)(__VA_ARGS__) + +/** + * Removes the first N (up to twenty) variadic arguments from the given argument + * list. At least N variadic arguments must be provided. + */ +#define metamacro_drop(N, ...) \ + metamacro_concat(metamacro_drop, N)(__VA_ARGS__) + +/** + * Decrements VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_dec(VAL) \ + metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) + +/** + * Increments VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_inc(VAL) \ + metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + +/** + * If A is equal to B, the next argument list is expanded; otherwise, the + * argument list after that is expanded. A and B must be numbers between zero + * and twenty, inclusive. Additionally, B must be greater than or equal to A. + * + * @code + +// expands to true +metamacro_if_eq(0, 0)(true)(false) + +// expands to false +metamacro_if_eq(0, 1)(true)(false) + + * @endcode + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_if_eq(A, B) \ + metamacro_concat(metamacro_if_eq, A)(B) + +/** + * Identical to #metamacro_if_eq. This can be used when the former would fail + * due to recursive macro expansion. + */ +#define metamacro_if_eq_recursive(A, B) \ + metamacro_concat(metamacro_if_eq_recursive, A)(B) + +/** + * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and + * twenty, inclusive. + * + * For the purposes of this test, zero is considered even. + */ +#define metamacro_is_even(N) \ + metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) + +/** + * Returns the logical NOT of B, which must be the number zero or one. + */ +#define metamacro_not(B) \ + metamacro_at(B, 1, 0) + +// IMPLEMENTATION DETAILS FOLLOW! +// Do not write code that depends on anything below this line. +#define metamacro_stringify_(VALUE) # VALUE +#define metamacro_concat_(A, B) A ## B +#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) +#define metamacro_head_(FIRST, ...) FIRST +#define metamacro_tail_(FIRST, ...) __VA_ARGS__ +#define metamacro_consume_(...) +#define metamacro_expand_(...) __VA_ARGS__ + +// implemented from scratch so that metamacro_concat() doesn't end up nesting +#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) +#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG + +// metamacro_at expansions +#define metamacro_at0(...) metamacro_head(__VA_ARGS__) +#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) + +// metamacro_foreach_cxt expansions +#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_foreach_cxt_recursive expansions +#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_for_cxt expansions +#define metamacro_for_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) + +#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(1, CONTEXT) + +#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(2, CONTEXT) + +#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(3, CONTEXT) + +#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(4, CONTEXT) + +#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(5, CONTEXT) + +#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(6, CONTEXT) + +#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(7, CONTEXT) + +#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(8, CONTEXT) + +#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(9, CONTEXT) + +#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(10, CONTEXT) + +#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(11, CONTEXT) + +#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(12, CONTEXT) + +#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(13, CONTEXT) + +#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(14, CONTEXT) + +#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(15, CONTEXT) + +#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(16, CONTEXT) + +#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(17, CONTEXT) + +#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(18, CONTEXT) + +#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(19, CONTEXT) + +// metamacro_if_eq expansions +#define metamacro_if_eq0(VALUE) \ + metamacro_concat(metamacro_if_eq0_, VALUE) + +#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq0_1(...) metamacro_expand_ +#define metamacro_if_eq0_2(...) metamacro_expand_ +#define metamacro_if_eq0_3(...) metamacro_expand_ +#define metamacro_if_eq0_4(...) metamacro_expand_ +#define metamacro_if_eq0_5(...) metamacro_expand_ +#define metamacro_if_eq0_6(...) metamacro_expand_ +#define metamacro_if_eq0_7(...) metamacro_expand_ +#define metamacro_if_eq0_8(...) metamacro_expand_ +#define metamacro_if_eq0_9(...) metamacro_expand_ +#define metamacro_if_eq0_10(...) metamacro_expand_ +#define metamacro_if_eq0_11(...) metamacro_expand_ +#define metamacro_if_eq0_12(...) metamacro_expand_ +#define metamacro_if_eq0_13(...) metamacro_expand_ +#define metamacro_if_eq0_14(...) metamacro_expand_ +#define metamacro_if_eq0_15(...) metamacro_expand_ +#define metamacro_if_eq0_16(...) metamacro_expand_ +#define metamacro_if_eq0_17(...) metamacro_expand_ +#define metamacro_if_eq0_18(...) metamacro_expand_ +#define metamacro_if_eq0_19(...) metamacro_expand_ +#define metamacro_if_eq0_20(...) metamacro_expand_ + +#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) +#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) +#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) +#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) +#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) +#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) +#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) +#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) +#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) +#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) +#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) +#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) +#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) +#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) +#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) +#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) +#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) +#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) +#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) +#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) + +// metamacro_if_eq_recursive expansions +#define metamacro_if_eq_recursive0(VALUE) \ + metamacro_concat(metamacro_if_eq_recursive0_, VALUE) + +#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq_recursive0_1(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_2(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_3(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_4(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_5(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_6(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_7(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_8(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_9(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_10(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_11(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_12(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_13(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_14(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_15(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_16(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_17(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_18(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_19(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_20(...) metamacro_expand_ + +#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) + +// metamacro_take expansions +#define metamacro_take0(...) +#define metamacro_take1(...) metamacro_head(__VA_ARGS__) +#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) +#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) +#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) +#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) +#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) +#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) +#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) +#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) +#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) +#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) +#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) +#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) +#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) +#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) +#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) +#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) +#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) +#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) +#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) + +// metamacro_drop expansions +#define metamacro_drop0(...) __VA_ARGS__ +#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) +#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.h new file mode 100644 index 00000000..cf67186f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.h @@ -0,0 +1,18 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +@interface UIColor (SDHexString) + +/** + Convenience way to get hex string from color. The output should always be 32-bit RGBA hex string like `#00000000`. + */ +@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.m b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.m new file mode 100644 index 00000000..7b43c411 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/SDWebImage/Private/UIColor+SDHexString.m @@ -0,0 +1,42 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIColor+SDHexString.h" + +@implementation UIColor (SDHexString) + +- (NSString *)sd_hexString { + CGFloat red, green, blue, alpha; +#if SD_UIKIT + if (![self getRed:&red green:&green blue:&blue alpha:&alpha]) { + [self getWhite:&red alpha:&alpha]; + green = red; + blue = red; + } +#else + @try { + [self getRed:&red green:&green blue:&blue alpha:&alpha]; + } + @catch (NSException *exception) { + [self getWhite:&red alpha:&alpha]; + green = red; + blue = red; + } +#endif + + red = roundf(red * 255.f); + green = roundf(green * 255.f); + blue = roundf(blue * 255.f); + alpha = roundf(alpha * 255.f); + + uint hex = ((uint)alpha << 24) | ((uint)red << 16) | ((uint)green << 8) | ((uint)blue); + + return [NSString stringWithFormat:@"#%08x", hex]; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SDWebImage/WebImage/SDWebImage.h b/one-and-half-nibble/MobileApp/Pods/SDWebImage/WebImage/SDWebImage.h new file mode 100644 index 00000000..0e568003 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SDWebImage/WebImage/SDWebImage.h @@ -0,0 +1,89 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Florent Vilmart + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import + +//! Project version number for SDWebImage. +FOUNDATION_EXPORT double SDWebImageVersionNumber; + +//! Project version string for SDWebImage. +FOUNDATION_EXPORT const unsigned char SDWebImageVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +// Mac +#if __has_include() +#import +#endif +#if __has_include() +#import +#endif +#if __has_include() +#import +#endif + +// MapKit +#if __has_include() +#import +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/LICENSE b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/LICENSE new file mode 100644 index 00000000..f8c911ba --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/README.md b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/README.md new file mode 100644 index 00000000..a9ce9e0d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/README.md @@ -0,0 +1,218 @@ +# SVProgressHUD + +![Pod Version](https://img.shields.io/cocoapods/v/SVProgressHUD.svg?style=flat) +![Pod Platform](https://img.shields.io/cocoapods/p/SVProgressHUD.svg?style=flat) +![Pod License](https://img.shields.io/cocoapods/l/SVProgressHUD.svg?style=flat) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-green.svg?style=flat)](https://github.com/Carthage/Carthage) +[![CocoaPods compatible](https://img.shields.io/badge/CocoaPods-compatible-green.svg?style=flat)](https://cocoapods.org) + +`SVProgressHUD` is a clean and easy-to-use HUD meant to display the progress of an ongoing task on iOS and tvOS. + +![SVProgressHUD](http://f.cl.ly/items/2G1F1Z0M0k0h2U3V1p39/SVProgressHUD.gif) + +## Demo + +Try `SVProgressHUD` on [Appetize.io](https://appetize.io/app/p8r2cvy8kq74x7q7tjqf5gyatr). + +## Installation + +### From CocoaPods + +[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like `SVProgressHUD` in your projects. First, add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): + +```ruby +pod 'SVProgressHUD' +``` + +If you want to use the latest features of `SVProgressHUD` use normal external source dependencies. + +```ruby +pod 'SVProgressHUD', :git => 'https://github.com/SVProgressHUD/SVProgressHUD.git' +``` + +This pulls from the `master` branch directly. + +Second, install `SVProgressHUD` into your project: + +```ruby +pod install +``` + +### Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate `SVProgressHUD` into your Xcode project using Carthage, specify it in your `Cartfile`: + +```ogdl +github "SVProgressHUD/SVProgressHUD" +``` + +Run `carthage bootstrap` to build the framework in your repository's Carthage directory. You can then include it in your target's `carthage copy-frameworks` build phase. For more information on this, please see [Carthage's documentation](https://github.com/carthage/carthage#if-youre-building-for-ios-tvos-or-watchos). + +### Manually + +* Drag the `SVProgressHUD/SVProgressHUD` folder into your project. +* Take care that `SVProgressHUD.bundle` is added to `Targets->Build Phases->Copy Bundle Resources`. +* Add the **QuartzCore** framework to your project. + +## Swift + +Even though `SVProgressHUD` is written in Objective-C, it can be used in Swift with no hassle. If you use [CocoaPods](http://cocoapods.org) add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): + +```ruby +use_frameworks! +``` + +If you added `SVProgressHUD` manually, just add a [bridging header](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html) file to your project with the `SVProgressHUD` header included. + +## Usage + +(see sample Xcode project in `/Demo`) + +`SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]`). + +**Use `SVProgressHUD` wisely! Only use it if you absolutely need to perform a task before taking the user forward. Bad use case examples: pull to refresh, infinite scrolling, sending message.** + +Using `SVProgressHUD` in your app will usually look as simple as this (using Grand Central Dispatch): + +```objective-c +[SVProgressHUD show]; +dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // time-consuming task + dispatch_async(dispatch_get_main_queue(), ^{ + [SVProgressHUD dismiss]; + }); +}); +``` + +### Showing the HUD + +You can show the status of indeterminate tasks using one of the following: + +```objective-c ++ (void)show; ++ (void)showWithStatus:(NSString*)string; +``` + +If you'd like the HUD to reflect the progress of a task, use one of these: + +```objective-c ++ (void)showProgress:(CGFloat)progress; ++ (void)showProgress:(CGFloat)progress status:(NSString*)status; +``` + +### Dismissing the HUD + +The HUD can be dismissed using: + +```objective-c ++ (void)dismiss; ++ (void)dismissWithDelay:(NSTimeInterval)delay; +``` + +If you'd like to stack HUDs, you can balance out every show call using: + +``` ++ (void)popActivity; +``` + +The HUD will get dismissed once the popActivity calls will match the number of show calls. + +Or show a confirmation glyph before before getting dismissed a little bit later. The display time depends on `minimumDismissTimeInterval` and the length of the given string. + +```objective-c ++ (void)showInfoWithStatus:(NSString*)string; ++ (void)showSuccessWithStatus:(NSString*)string; ++ (void)showErrorWithStatus:(NSString*)string; ++ (void)showImage:(UIImage*)image status:(NSString*)string; +``` + +## Customization + +`SVProgressHUD` can be customized via the following methods: + +```objective-c ++ (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone ++ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat ++ (void)setContainerView:(UIView*)containerView; // default is window level ++ (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing ++ (void)setRingThickness:(CGFloat)width; // default is 2 pt ++ (void)setRingRadius:(CGFloat)radius; // default is 18 pt ++ (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt ++ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt ++ (void)setBorderColor:(nonnull UIColor*)color; // default is nil ++ (void)setBorderWidth:(CGFloat)width; // default is 0 ++ (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] ++ (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom ++ (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom ++ (void)setBackgroundLayerColor:(UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.4], only used for SVProgressHUDMaskTypeCustom ++ (void)setImageViewSize:(CGSize)size; // default is 28x28 pt ++ (void)setShouldTintImages:(BOOL)shouldTintImages; // default is YES ++ (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik ++ (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Freepik ++ (void)setErrorImage:(UIImage*)image; // default is bundled error image from Freepik ++ (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set ++ (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds ++ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds ++ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is CGFLOAT_MAX ++ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds ++ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds ++ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal ++ (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO +``` + +Additionally `SVProgressHUD` supports the `UIAppearance` protocol for most of the above methods. + +### Hint + +As standard `SVProgressHUD` offers two preconfigured styles: + +* `SVProgressHUDStyleLight`: White background with black spinner and text +* `SVProgressHUDStyleDark`: Black background with white spinner and text + +If you want to use custom colors use `setForegroundColor` and `setBackgroundColor:`. These implicitly set the HUD's style to `SVProgressHUDStyleCustom`. + +## Haptic Feedback + +For users with newer devices (starting with the iPhone 7), `SVProgressHUD` can automatically trigger haptic feedback depending on which HUD is being displayed. The feedback maps as follows: + +* `showSuccessWithStatus:` <-> `UINotificationFeedbackTypeSuccess` +* `showInfoWithStatus:` <-> `UINotificationFeedbackTypeWarning` +* `showErrorWithStatus:` <-> `UINotificationFeedbackTypeError` + +To enable this functionality, use `setHapticsEnabled:`. + +Users with devices prior to iPhone 7 will have no change in functionality. + +## Notifications + +`SVProgressHUD` posts four notifications via `NSNotificationCenter` in response to being shown/dismissed: +* `SVProgressHUDWillAppearNotification` when the show animation starts +* `SVProgressHUDDidAppearNotification` when the show animation completes +* `SVProgressHUDWillDisappearNotification` when the dismiss animation starts +* `SVProgressHUDDidDisappearNotification` when the dismiss animation completes + +Each notification passes a `userInfo` dictionary holding the HUD's status string (if any), retrievable via `SVProgressHUDStatusUserInfoKey`. + +`SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For this notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. + +## App Extensions + +When using `SVProgressHUD` in an App Extension, `#define SV_APP_EXTENSIONS` to avoid using unavailable APIs. Additionally call `setViewForExtension:` from your extensions view controller with `self.view`. + +## Contributing to this project + +If you have feature requests or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/SVProgressHUD/SVProgressHUD/issues/new). Please take a moment to +review the guidelines written by [Nicolas Gallagher](https://github.com/necolas): + +* [Bug reports](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#bugs) +* [Feature requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#features) +* [Pull requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#pull-requests) + +## License + +`SVProgressHUD` is distributed under the terms and conditions of the [MIT license](https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE.txt). The success, error and info icons are made by [Freepik](http://www.freepik.com) from [Flaticon](http://www.flaticon.com) and are licensed under [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/). + +## Credits + +`SVProgressHUD` is brought to you by [Sam Vermette](http://samvermette.com), [Tobias Tiemerding](http://tiemerding.com) and [contributors to the project](https://github.com/SVProgressHUD/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated. diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h new file mode 100644 index 00000000..b624dd0b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h @@ -0,0 +1,17 @@ +// +// SVIndefiniteAnimatedView.h +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. +// + +#import + +@interface SVIndefiniteAnimatedView : UIView + +@property (nonatomic, assign) CGFloat strokeThickness; +@property (nonatomic, assign) CGFloat radius; +@property (nonatomic, strong) UIColor *strokeColor; + +@end + diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m new file mode 100644 index 00000000..09a38d0b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m @@ -0,0 +1,137 @@ +// +// SVIndefiniteAnimatedView.m +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. +// + +#import "SVIndefiniteAnimatedView.h" +#import "SVProgressHUD.h" + +@interface SVIndefiniteAnimatedView () + +@property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer; + +@end + +@implementation SVIndefiniteAnimatedView + +- (void)willMoveToSuperview:(UIView*)newSuperview { + if (newSuperview) { + [self layoutAnimatedLayer]; + } else { + [_indefiniteAnimatedLayer removeFromSuperlayer]; + _indefiniteAnimatedLayer = nil; + } +} + +- (void)layoutAnimatedLayer { + CALayer *layer = self.indefiniteAnimatedLayer; + [self.layer addSublayer:layer]; + + CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); + CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); + layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); +} + +- (CAShapeLayer*)indefiniteAnimatedLayer { + if(!_indefiniteAnimatedLayer) { + CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); + UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (M_PI/2+M_PI*5) clockwise:YES]; + + _indefiniteAnimatedLayer = [CAShapeLayer layer]; + _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; + _indefiniteAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); + _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor; + _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor; + _indefiniteAnimatedLayer.lineWidth = self.strokeThickness; + _indefiniteAnimatedLayer.lineCap = kCALineCapRound; + _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel; + _indefiniteAnimatedLayer.path = smoothedPath.CGPath; + + CALayer *maskLayer = [CALayer layer]; + + NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; + NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; + NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + + NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"]; + + maskLayer.contents = (__bridge id)[[UIImage imageWithContentsOfFile:path] CGImage]; + maskLayer.frame = _indefiniteAnimatedLayer.bounds; + _indefiniteAnimatedLayer.mask = maskLayer; + + NSTimeInterval animationDuration = 1; + CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; + animation.fromValue = (id) 0; + animation.toValue = @(M_PI*2); + animation.duration = animationDuration; + animation.timingFunction = linearCurve; + animation.removedOnCompletion = NO; + animation.repeatCount = INFINITY; + animation.fillMode = kCAFillModeForwards; + animation.autoreverses = NO; + [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"]; + + CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; + animationGroup.duration = animationDuration; + animationGroup.repeatCount = INFINITY; + animationGroup.removedOnCompletion = NO; + animationGroup.timingFunction = linearCurve; + + CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; + strokeStartAnimation.fromValue = @0.015; + strokeStartAnimation.toValue = @0.515; + + CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndAnimation.fromValue = @0.485; + strokeEndAnimation.toValue = @0.985; + + animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation]; + [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"]; + + } + return _indefiniteAnimatedLayer; +} + +- (void)setFrame:(CGRect)frame { + if(!CGRectEqualToRect(frame, super.frame)) { + [super setFrame:frame]; + + if(self.superview) { + [self layoutAnimatedLayer]; + } + } + +} + +- (void)setRadius:(CGFloat)radius { + if(radius != _radius) { + _radius = radius; + + [_indefiniteAnimatedLayer removeFromSuperlayer]; + _indefiniteAnimatedLayer = nil; + + if(self.superview) { + [self layoutAnimatedLayer]; + } + } +} + +- (void)setStrokeColor:(UIColor*)strokeColor { + _strokeColor = strokeColor; + _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor; +} + +- (void)setStrokeThickness:(CGFloat)strokeThickness { + _strokeThickness = strokeThickness; + _indefiniteAnimatedLayer.lineWidth = _strokeThickness; +} + +- (CGSize)sizeThatFits:(CGSize)size { + return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h new file mode 100644 index 00000000..6de23b43 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.h @@ -0,0 +1,17 @@ +// +// SVProgressAnimatedView.h +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2017-2018 Tobias Tiemerding. All rights reserved. +// + +#import + +@interface SVProgressAnimatedView : UIView + +@property (nonatomic, assign) CGFloat radius; +@property (nonatomic, assign) CGFloat strokeThickness; +@property (nonatomic, strong) UIColor *strokeColor; +@property (nonatomic, assign) CGFloat strokeEnd; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m new file mode 100644 index 00000000..a347c85d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressAnimatedView.m @@ -0,0 +1,96 @@ +// +// SVProgressAnimatedView.m +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2017-2018 Tobias Tiemerding. All rights reserved. +// + +#import "SVProgressAnimatedView.h" + +@interface SVProgressAnimatedView () + +@property (nonatomic, strong) CAShapeLayer *ringAnimatedLayer; + +@end + +@implementation SVProgressAnimatedView + +- (void)willMoveToSuperview:(UIView*)newSuperview { + if (newSuperview) { + [self layoutAnimatedLayer]; + } else { + [_ringAnimatedLayer removeFromSuperlayer]; + _ringAnimatedLayer = nil; + } +} + +- (void)layoutAnimatedLayer { + CALayer *layer = self.ringAnimatedLayer; + [self.layer addSublayer:layer]; + + CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); + CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); + layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); +} + +- (CAShapeLayer*)ringAnimatedLayer { + if(!_ringAnimatedLayer) { + CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); + UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat)-M_PI_2 endAngle:(CGFloat) (M_PI + M_PI_2) clockwise:YES]; + + _ringAnimatedLayer = [CAShapeLayer layer]; + _ringAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; + _ringAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); + _ringAnimatedLayer.fillColor = [UIColor clearColor].CGColor; + _ringAnimatedLayer.strokeColor = self.strokeColor.CGColor; + _ringAnimatedLayer.lineWidth = self.strokeThickness; + _ringAnimatedLayer.lineCap = kCALineCapRound; + _ringAnimatedLayer.lineJoin = kCALineJoinBevel; + _ringAnimatedLayer.path = smoothedPath.CGPath; + } + return _ringAnimatedLayer; +} + +- (void)setFrame:(CGRect)frame { + if(!CGRectEqualToRect(frame, super.frame)) { + [super setFrame:frame]; + + if(self.superview) { + [self layoutAnimatedLayer]; + } + } +} + +- (void)setRadius:(CGFloat)radius { + if(radius != _radius) { + _radius = radius; + + [_ringAnimatedLayer removeFromSuperlayer]; + _ringAnimatedLayer = nil; + + if(self.superview) { + [self layoutAnimatedLayer]; + } + } +} + +- (void)setStrokeColor:(UIColor*)strokeColor { + _strokeColor = strokeColor; + _ringAnimatedLayer.strokeColor = strokeColor.CGColor; +} + +- (void)setStrokeThickness:(CGFloat)strokeThickness { + _strokeThickness = strokeThickness; + _ringAnimatedLayer.lineWidth = _strokeThickness; +} + +- (void)setStrokeEnd:(CGFloat)strokeEnd { + _strokeEnd = strokeEnd; + _ringAnimatedLayer.strokeEnd = _strokeEnd; +} + +- (CGSize)sizeThatFits:(CGSize)size { + return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png new file mode 100644 index 00000000..0150a03f Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png new file mode 100644 index 00000000..9a302b68 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png new file mode 100644 index 00000000..d07f3ce6 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png new file mode 100644 index 00000000..a57c8e44 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png new file mode 100644 index 00000000..aaf67985 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png new file mode 100644 index 00000000..c92518f8 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png new file mode 100644 index 00000000..a3a1f75c Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png new file mode 100644 index 00000000..1b333e7b Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png new file mode 100644 index 00000000..d56aa0c2 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png new file mode 100644 index 00000000..44769d02 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png new file mode 100644 index 00000000..a9d16532 Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png new file mode 100644 index 00000000..42bad9be Binary files /dev/null and b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png differ diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h new file mode 100644 index 00000000..6aa935c0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h @@ -0,0 +1,147 @@ +// +// SVProgressHUD.h +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2011-2018 Sam Vermette and contributors. All rights reserved. +// + +#import +#import + +extern NSString * _Nonnull const SVProgressHUDDidReceiveTouchEventNotification; +extern NSString * _Nonnull const SVProgressHUDDidTouchDownInsideNotification; +extern NSString * _Nonnull const SVProgressHUDWillDisappearNotification; +extern NSString * _Nonnull const SVProgressHUDDidDisappearNotification; +extern NSString * _Nonnull const SVProgressHUDWillAppearNotification; +extern NSString * _Nonnull const SVProgressHUDDidAppearNotification; + +extern NSString * _Nonnull const SVProgressHUDStatusUserInfoKey; + +typedef NS_ENUM(NSInteger, SVProgressHUDStyle) { + SVProgressHUDStyleLight, // default style, white HUD with black text, HUD background will be blurred + SVProgressHUDStyleDark, // black HUD and white text, HUD background will be blurred + SVProgressHUDStyleCustom // uses the fore- and background color properties +}; + +typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { + SVProgressHUDMaskTypeNone = 1, // default mask type, allow user interactions while HUD is displayed + SVProgressHUDMaskTypeClear, // don't allow user interactions with background objects + SVProgressHUDMaskTypeBlack, // don't allow user interactions with background objects and dim the UI in the back of the HUD (as seen in iOS 7 and above) + SVProgressHUDMaskTypeGradient, // don't allow user interactions with background objects and dim the UI with a a-la UIAlertView background gradient (as seen in iOS 6) + SVProgressHUDMaskTypeCustom // don't allow user interactions with background objects and dim the UI in the back of the HUD with a custom color +}; + +typedef NS_ENUM(NSUInteger, SVProgressHUDAnimationType) { + SVProgressHUDAnimationTypeFlat, // default animation type, custom flat animation (indefinite animated ring) + SVProgressHUDAnimationTypeNative // iOS native UIActivityIndicatorView +}; + +typedef void (^SVProgressHUDShowCompletion)(void); +typedef void (^SVProgressHUDDismissCompletion)(void); + +@interface SVProgressHUD : UIView + +#pragma mark - Customization + +@property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; // default is SVProgressHUDStyleLight +@property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDMaskTypeNone +@property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDAnimationTypeFlat +@property (strong, nonatomic, nullable) UIView *containerView; // if nil then use default window level +@property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; // default is CGSizeZero, can be used to avoid resizing for a larger message +@property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; // default is 2 pt +@property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; // default is 18 pt +@property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; // default is 24 pt +@property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; // default is 14 pt +@property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] +@property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor whiteColor] +@property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor blackColor] +@property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR;// default is [UIColor colorWithWhite:0 alpha:0.4] +@property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR; // default is 28x28 pt +@property (assign, nonatomic) BOOL shouldTintImages UI_APPEARANCE_SELECTOR; // default is YES +@property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR; // default is the bundled info image provided by Freepik +@property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR; // default is the bundled success image provided by Freepik +@property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR; // default is the bundled error image provided by Freepik +@property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR; // default is nil, only used if #define SV_APP_EXTENSIONS is set +@property (assign, nonatomic) NSTimeInterval graceTimeInterval; // default is 0 seconds +@property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; // default is 5.0 seconds +@property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval; // default is CGFLOAT_MAX + +@property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; // default is 0, 0 + +@property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 +@property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 + +@property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel; // default is UIWindowLevelNormal + +@property (assign, nonatomic) BOOL hapticsEnabled; // default is NO + ++ (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone ++ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat ++ (void)setContainerView:(nullable UIView*)containerView; // default is window level ++ (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message ++ (void)setRingThickness:(CGFloat)ringThickness; // default is 2 pt ++ (void)setRingRadius:(CGFloat)radius; // default is 18 pt ++ (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt ++ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt ++ (void)setBorderColor:(nonnull UIColor*)color; // default is nil ++ (void)setBorderWidth:(CGFloat)width; // default is 0 ++ (void)setFont:(nonnull UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] ++ (void)setForegroundColor:(nonnull UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom ++ (void)setBackgroundColor:(nonnull UIColor*)color; // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom ++ (void)setBackgroundLayerColor:(nonnull UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.5], only used for SVProgressHUDMaskTypeCustom ++ (void)setImageViewSize:(CGSize)size; // default is 28x28 pt ++ (void)setShouldTintImages:(BOOL)shouldTintImages; // default is YES ++ (void)setInfoImage:(nonnull UIImage*)image; // default is the bundled info image provided by Freepik ++ (void)setSuccessImage:(nonnull UIImage*)image; // default is the bundled success image provided by Freepik ++ (void)setErrorImage:(nonnull UIImage*)image; // default is the bundled error image provided by Freepik ++ (void)setViewForExtension:(nonnull UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set ++ (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds ++ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds ++ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is infinite ++ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds ++ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds ++ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal ++ (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO + +#pragma mark - Show Methods + ++ (void)show; ++ (void)showWithMaskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead."))); ++ (void)showWithStatus:(nullable NSString*)status; ++ (void)showWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showWithStatus: and setDefaultMaskType: instead."))); + ++ (void)showProgress:(float)progress; ++ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress: and setDefaultMaskType: instead."))); ++ (void)showProgress:(float)progress status:(nullable NSString*)status; ++ (void)showProgress:(float)progress status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress:status: and setDefaultMaskType: instead."))); + ++ (void)setStatus:(nullable NSString*)status; // change the HUD loading status while it's showing + +// stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later ++ (void)showInfoWithStatus:(nullable NSString*)status; ++ (void)showInfoWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showInfoWithStatus: and setDefaultMaskType: instead."))); ++ (void)showSuccessWithStatus:(nullable NSString*)status; ++ (void)showSuccessWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showSuccessWithStatus: and setDefaultMaskType: instead."))); ++ (void)showErrorWithStatus:(nullable NSString*)status; ++ (void)showErrorWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showErrorWithStatus: and setDefaultMaskType: instead."))); + +// shows a image + status, use white PNGs with the imageViewSize (default is 28x28 pt) ++ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status; ++ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showImage:status: and setDefaultMaskType: instead."))); + ++ (void)setOffsetFromCenter:(UIOffset)offset; ++ (void)resetOffsetFromCenter; + ++ (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed ++ (void)dismiss; ++ (void)dismissWithCompletion:(nullable SVProgressHUDDismissCompletion)completion; ++ (void)dismissWithDelay:(NSTimeInterval)delay; ++ (void)dismissWithDelay:(NSTimeInterval)delay completion:(nullable SVProgressHUDDismissCompletion)completion; + ++ (BOOL)isVisible; + ++ (NSTimeInterval)displayDurationForString:(nullable NSString*)string; + +@end + diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m new file mode 100644 index 00000000..2b669920 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m @@ -0,0 +1,1509 @@ +// +// SVProgressHUD.h +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2011-2018 Sam Vermette and contributors. All rights reserved. +// + +#if !__has_feature(objc_arc) +#error SVProgressHUD is ARC only. Either turn on ARC for the project or use -fobjc-arc flag +#endif + +#import "SVProgressHUD.h" +#import "SVIndefiniteAnimatedView.h" +#import "SVProgressAnimatedView.h" +#import "SVRadialGradientLayer.h" + +NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification"; +NSString * const SVProgressHUDDidTouchDownInsideNotification = @"SVProgressHUDDidTouchDownInsideNotification"; +NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification"; +NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification"; +NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification"; +NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification"; + +NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey"; + +static const CGFloat SVProgressHUDParallaxDepthPoints = 10.0f; +static const CGFloat SVProgressHUDUndefinedProgress = -1; +static const CGFloat SVProgressHUDDefaultAnimationDuration = 0.15f; +static const CGFloat SVProgressHUDVerticalSpacing = 12.0f; +static const CGFloat SVProgressHUDHorizontalSpacing = 12.0f; +static const CGFloat SVProgressHUDLabelSpacing = 8.0f; + + +@interface SVProgressHUD () + +@property (nonatomic, strong) NSTimer *graceTimer; +@property (nonatomic, strong) NSTimer *fadeOutTimer; + +@property (nonatomic, strong) UIControl *controlView; +@property (nonatomic, strong) UIView *backgroundView; +@property (nonatomic, strong) SVRadialGradientLayer *backgroundRadialGradientLayer; +@property (nonatomic, strong) UIVisualEffectView *hudView; +@property (nonatomic, strong) UILabel *statusLabel; +@property (nonatomic, strong) UIImageView *imageView; + +@property (nonatomic, strong) UIView *indefiniteAnimatedView; +@property (nonatomic, strong) SVProgressAnimatedView *ringView; +@property (nonatomic, strong) SVProgressAnimatedView *backgroundRingView; + +@property (nonatomic, readwrite) CGFloat progress; +@property (nonatomic, readwrite) NSUInteger activityCount; + +@property (nonatomic, readonly) CGFloat visibleKeyboardHeight; +@property (nonatomic, readonly) UIWindow *frontWindow; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 +@property (nonatomic, strong) UINotificationFeedbackGenerator *hapticGenerator NS_AVAILABLE_IOS(10_0); +#endif + +@end + +@implementation SVProgressHUD { + BOOL _isInitializing; +} + ++ (SVProgressHUD*)sharedView { + static dispatch_once_t once; + + static SVProgressHUD *sharedView; +#if !defined(SV_APP_EXTENSIONS) + dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[[UIApplication sharedApplication] delegate] window].bounds]; }); +#else + dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); +#endif + return sharedView; +} + + +#pragma mark - Setters + ++ (void)setStatus:(NSString*)status { + [[self sharedView] setStatus:status]; +} + ++ (void)setDefaultStyle:(SVProgressHUDStyle)style { + [self sharedView].defaultStyle = style; +} + ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType { + [self sharedView].defaultMaskType = maskType; +} + ++ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type { + [self sharedView].defaultAnimationType = type; +} + ++ (void)setContainerView:(nullable UIView*)containerView { + [self sharedView].containerView = containerView; +} + ++ (void)setMinimumSize:(CGSize)minimumSize { + [self sharedView].minimumSize = minimumSize; +} + ++ (void)setRingThickness:(CGFloat)ringThickness { + [self sharedView].ringThickness = ringThickness; +} + ++ (void)setRingRadius:(CGFloat)radius { + [self sharedView].ringRadius = radius; +} + ++ (void)setRingNoTextRadius:(CGFloat)radius { + [self sharedView].ringNoTextRadius = radius; +} + ++ (void)setCornerRadius:(CGFloat)cornerRadius { + [self sharedView].cornerRadius = cornerRadius; +} + ++ (void)setBorderColor:(nonnull UIColor*)color { + [self sharedView].hudView.layer.borderColor = color.CGColor; +} + ++ (void)setBorderWidth:(CGFloat)width { + [self sharedView].hudView.layer.borderWidth = width; +} + ++ (void)setFont:(UIFont*)font { + [self sharedView].font = font; +} + ++ (void)setForegroundColor:(UIColor*)color { + [self sharedView].foregroundColor = color; + [self setDefaultStyle:SVProgressHUDStyleCustom]; +} + ++ (void)setBackgroundColor:(UIColor*)color { + [self sharedView].backgroundColor = color; + [self setDefaultStyle:SVProgressHUDStyleCustom]; +} + ++ (void)setBackgroundLayerColor:(UIColor*)color { + [self sharedView].backgroundLayerColor = color; +} + ++ (void)setImageViewSize:(CGSize)size { + [self sharedView].imageViewSize = size; +} + ++ (void)setShouldTintImages:(BOOL)shouldTintImages { + [self sharedView].shouldTintImages = shouldTintImages; +} + ++ (void)setInfoImage:(UIImage*)image { + [self sharedView].infoImage = image; +} + ++ (void)setSuccessImage:(UIImage*)image { + [self sharedView].successImage = image; +} + ++ (void)setErrorImage:(UIImage*)image { + [self sharedView].errorImage = image; +} + ++ (void)setViewForExtension:(UIView*)view { + [self sharedView].viewForExtension = view; +} + ++ (void)setGraceTimeInterval:(NSTimeInterval)interval { + [self sharedView].graceTimeInterval = interval; +} + ++ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval { + [self sharedView].minimumDismissTimeInterval = interval; +} + ++ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval { + [self sharedView].maximumDismissTimeInterval = interval; +} + ++ (void)setFadeInAnimationDuration:(NSTimeInterval)duration { + [self sharedView].fadeInAnimationDuration = duration; +} + ++ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration { + [self sharedView].fadeOutAnimationDuration = duration; +} + ++ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel { + [self sharedView].maxSupportedWindowLevel = windowLevel; +} + ++ (void)setHapticsEnabled:(BOOL)hapticsEnabled { + [self sharedView].hapticsEnabled = hapticsEnabled; +} + +#pragma mark - Show Methods + ++ (void)show { + [self showWithStatus:nil]; +} + ++ (void)showWithMaskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self show]; + [self setDefaultMaskType:existingMaskType]; +} + ++ (void)showWithStatus:(NSString*)status { + [self showProgress:SVProgressHUDUndefinedProgress status:status]; +} + ++ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showWithStatus:status]; + [self setDefaultMaskType:existingMaskType]; +} + ++ (void)showProgress:(float)progress { + [self showProgress:progress status:nil]; +} + ++ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showProgress:progress]; + [self setDefaultMaskType:existingMaskType]; +} + ++ (void)showProgress:(float)progress status:(NSString*)status { + [[self sharedView] showProgress:progress status:status]; +} + ++ (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showProgress:progress status:status]; + [self setDefaultMaskType:existingMaskType]; +} + + +#pragma mark - Show, then automatically dismiss methods + ++ (void)showInfoWithStatus:(NSString*)status { + [self showImage:[self sharedView].infoImage status:status]; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10.0, *)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeWarning]; + }); + } +#endif +} + ++ (void)showInfoWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showInfoWithStatus:status]; + [self setDefaultMaskType:existingMaskType]; +} + ++ (void)showSuccessWithStatus:(NSString*)status { + [self showImage:[self sharedView].successImage status:status]; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10, *)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; + }); + } +#endif +} + ++ (void)showSuccessWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showSuccessWithStatus:status]; + [self setDefaultMaskType:existingMaskType]; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10.0, *)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; + }); + } +#endif +} + ++ (void)showErrorWithStatus:(NSString*)status { + [self showImage:[self sharedView].errorImage status:status]; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10.0, *)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeError]; + }); + } +#endif +} + ++ (void)showErrorWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showErrorWithStatus:status]; + [self setDefaultMaskType:existingMaskType]; + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10.0, *)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[self sharedView].hapticGenerator notificationOccurred:UINotificationFeedbackTypeError]; + }); + } +#endif +} + ++ (void)showImage:(UIImage*)image status:(NSString*)status { + NSTimeInterval displayInterval = [self displayDurationForString:status]; + [[self sharedView] showImage:image status:status duration:displayInterval]; +} + ++ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + SVProgressHUDMaskType existingMaskType = [self sharedView].defaultMaskType; + [self setDefaultMaskType:maskType]; + [self showImage:image status:status]; + [self setDefaultMaskType:existingMaskType]; +} + + +#pragma mark - Dismiss Methods + ++ (void)popActivity { + if([self sharedView].activityCount > 0) { + [self sharedView].activityCount--; + } + if([self sharedView].activityCount == 0) { + [[self sharedView] dismiss]; + } +} + ++ (void)dismiss { + [self dismissWithDelay:0.0 completion:nil]; +} + ++ (void)dismissWithCompletion:(SVProgressHUDDismissCompletion)completion { + [self dismissWithDelay:0.0 completion:completion]; +} + ++ (void)dismissWithDelay:(NSTimeInterval)delay { + [self dismissWithDelay:delay completion:nil]; +} + ++ (void)dismissWithDelay:(NSTimeInterval)delay completion:(SVProgressHUDDismissCompletion)completion { + [[self sharedView] dismissWithDelay:delay completion:completion]; +} + + +#pragma mark - Offset + ++ (void)setOffsetFromCenter:(UIOffset)offset { + [self sharedView].offsetFromCenter = offset; +} + ++ (void)resetOffsetFromCenter { + [self setOffsetFromCenter:UIOffsetZero]; +} + + +#pragma mark - Instance Methods + +- (instancetype)initWithFrame:(CGRect)frame { + if((self = [super initWithFrame:frame])) { + _isInitializing = YES; + + self.userInteractionEnabled = NO; + self.activityCount = 0; + + self.backgroundView.alpha = 0.0f; + self.imageView.alpha = 0.0f; + self.statusLabel.alpha = 0.0f; + self.indefiniteAnimatedView.alpha = 0.0f; + self.ringView.alpha = self.backgroundRingView.alpha = 0.0f; + + + _backgroundColor = [UIColor whiteColor]; + _foregroundColor = [UIColor blackColor]; + _backgroundLayerColor = [UIColor colorWithWhite:0 alpha:0.4]; + + // Set default values + _defaultMaskType = SVProgressHUDMaskTypeNone; + _defaultStyle = SVProgressHUDStyleLight; + _defaultAnimationType = SVProgressHUDAnimationTypeFlat; + _minimumSize = CGSizeZero; + _font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; + + _imageViewSize = CGSizeMake(28.0f, 28.0f); + _shouldTintImages = YES; + + NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; + NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; + NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + + _infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]]; + _successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]]; + _errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]]; + + _ringThickness = 2.0f; + _ringRadius = 18.0f; + _ringNoTextRadius = 24.0f; + + _cornerRadius = 14.0f; + + _graceTimeInterval = 0.0f; + _minimumDismissTimeInterval = 5.0; + _maximumDismissTimeInterval = CGFLOAT_MAX; + + _fadeInAnimationDuration = SVProgressHUDDefaultAnimationDuration; + _fadeOutAnimationDuration = SVProgressHUDDefaultAnimationDuration; + + _maxSupportedWindowLevel = UIWindowLevelNormal; + + _hapticsEnabled = NO; + + // Accessibility support + self.accessibilityIdentifier = @"SVProgressHUD"; + self.isAccessibilityElement = YES; + + _isInitializing = NO; + } + return self; +} + +- (void)updateHUDFrame { + // Check if an image or progress ring is displayed + BOOL imageUsed = (self.imageView.image) && !(self.imageView.hidden); + BOOL progressUsed = self.imageView.hidden; + + // Calculate size of string + CGRect labelRect = CGRectZero; + CGFloat labelHeight = 0.0f; + CGFloat labelWidth = 0.0f; + + if(self.statusLabel.text) { + CGSize constraintSize = CGSizeMake(200.0f, 300.0f); + labelRect = [self.statusLabel.text boundingRectWithSize:constraintSize + options:(NSStringDrawingOptions)(NSStringDrawingUsesFontLeading | NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin) + attributes:@{NSFontAttributeName: self.statusLabel.font} + context:NULL]; + labelHeight = ceilf(CGRectGetHeight(labelRect)); + labelWidth = ceilf(CGRectGetWidth(labelRect)); + } + + // Calculate hud size based on content + // For the beginning use default values, these + // might get update if string is too large etc. + CGFloat hudWidth; + CGFloat hudHeight; + + CGFloat contentWidth = 0.0f; + CGFloat contentHeight = 0.0f; + + if(imageUsed || progressUsed) { + contentWidth = CGRectGetWidth(imageUsed ? self.imageView.frame : self.indefiniteAnimatedView.frame); + contentHeight = CGRectGetHeight(imageUsed ? self.imageView.frame : self.indefiniteAnimatedView.frame); + } + + // |-spacing-content-spacing-| + hudWidth = SVProgressHUDHorizontalSpacing + MAX(labelWidth, contentWidth) + SVProgressHUDHorizontalSpacing; + + // |-spacing-content-(labelSpacing-label-)spacing-| + hudHeight = SVProgressHUDVerticalSpacing + labelHeight + contentHeight + SVProgressHUDVerticalSpacing; + if(self.statusLabel.text && (imageUsed || progressUsed)){ + // Add spacing if both content and label are used + hudHeight += SVProgressHUDLabelSpacing; + } + + // Update values on subviews + self.hudView.bounds = CGRectMake(0.0f, 0.0f, MAX(self.minimumSize.width, hudWidth), MAX(self.minimumSize.height, hudHeight)); + + // Animate value update + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + + // Spinner and image view + CGFloat centerY; + if(self.statusLabel.text) { + CGFloat yOffset = MAX(SVProgressHUDVerticalSpacing, (self.minimumSize.height - contentHeight - SVProgressHUDLabelSpacing - labelHeight) / 2.0f); + centerY = yOffset + contentHeight / 2.0f; + } else { + centerY = CGRectGetMidY(self.hudView.bounds); + } + self.indefiniteAnimatedView.center = CGPointMake(CGRectGetMidX(self.hudView.bounds), centerY); + if(self.progress != SVProgressHUDUndefinedProgress) { + self.backgroundRingView.center = self.ringView.center = CGPointMake(CGRectGetMidX(self.hudView.bounds), centerY); + } + self.imageView.center = CGPointMake(CGRectGetMidX(self.hudView.bounds), centerY); + + // Label + if(imageUsed || progressUsed) { + centerY = CGRectGetMaxY(imageUsed ? self.imageView.frame : self.indefiniteAnimatedView.frame) + SVProgressHUDLabelSpacing + labelHeight / 2.0f; + } else { + centerY = CGRectGetMidY(self.hudView.bounds); + } + self.statusLabel.frame = labelRect; + self.statusLabel.center = CGPointMake(CGRectGetMidX(self.hudView.bounds), centerY); + + [CATransaction commit]; +} + +#if TARGET_OS_IOS +- (void)updateMotionEffectForOrientation:(UIInterfaceOrientation)orientation { + UIInterpolatingMotionEffectType xMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis : UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis; + UIInterpolatingMotionEffectType yMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis : UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis; + [self updateMotionEffectForXMotionEffectType:xMotionEffectType yMotionEffectType:yMotionEffectType]; +} +#endif + +- (void)updateMotionEffectForXMotionEffectType:(UIInterpolatingMotionEffectType)xMotionEffectType yMotionEffectType:(UIInterpolatingMotionEffectType)yMotionEffectType { + UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:xMotionEffectType]; + effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); + effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); + + UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:yMotionEffectType]; + effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); + effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); + + UIMotionEffectGroup *effectGroup = [UIMotionEffectGroup new]; + effectGroup.motionEffects = @[effectX, effectY]; + + // Clear old motion effect, then add new motion effects + self.hudView.motionEffects = @[]; + [self.hudView addMotionEffect:effectGroup]; +} + +- (void)updateViewHierarchy { + // Add the overlay to the application window if necessary + if(!self.controlView.superview) { + if(self.containerView){ + [self.containerView addSubview:self.controlView]; + } else { +#if !defined(SV_APP_EXTENSIONS) + [self.frontWindow addSubview:self.controlView]; +#else + // If SVProgressHUD is used inside an app extension add it to the given view + if(self.viewForExtension) { + [self.viewForExtension addSubview:self.controlView]; + } +#endif + } + } else { + // The HUD is already on screen, but maybe not in front. Therefore + // ensure that overlay will be on top of rootViewController (which may + // be changed during runtime). + [self.controlView.superview bringSubviewToFront:self.controlView]; + } + + // Add self to the overlay view + if(!self.superview) { + [self.controlView addSubview:self]; + } +} + +- (void)setStatus:(NSString*)status { + self.statusLabel.text = status; + self.statusLabel.hidden = status.length == 0; + [self updateHUDFrame]; +} + +- (void)setGraceTimer:(NSTimer*)timer { + if(_graceTimer) { + [_graceTimer invalidate]; + _graceTimer = nil; + } + if(timer) { + _graceTimer = timer; + } +} + +- (void)setFadeOutTimer:(NSTimer*)timer { + if(_fadeOutTimer) { + [_fadeOutTimer invalidate]; + _fadeOutTimer = nil; + } + if(timer) { + _fadeOutTimer = timer; + } +} + + +#pragma mark - Notifications and their handling + +- (void)registerNotifications { +#if TARGET_OS_IOS + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIApplicationDidChangeStatusBarOrientationNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardWillHideNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardDidHideNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardWillShowNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardDidShowNotification + object:nil]; +#endif + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; +} + +- (NSDictionary*)notificationUserInfo { + return (self.statusLabel.text ? @{SVProgressHUDStatusUserInfoKey : self.statusLabel.text} : nil); +} + +- (void)positionHUD:(NSNotification*)notification { + CGFloat keyboardHeight = 0.0f; + double animationDuration = 0.0; + +#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS + self.frame = [[[UIApplication sharedApplication] delegate] window].bounds; + UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation; +#elif !defined(SV_APP_EXTENSIONS) && !TARGET_OS_IOS + self.frame= [UIApplication sharedApplication].keyWindow.bounds; +#else + if (self.viewForExtension) { + self.frame = self.viewForExtension.frame; + } else { + self.frame = UIScreen.mainScreen.bounds; + } +#if TARGET_OS_IOS + UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait; +#endif +#endif + +#if TARGET_OS_IOS + // Get keyboardHeight in regard to current state + if(notification) { + NSDictionary* keyboardInfo = [notification userInfo]; + CGRect keyboardFrame = [keyboardInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + animationDuration = [keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + + if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) { + keyboardHeight = CGRectGetWidth(keyboardFrame); + + if(UIInterfaceOrientationIsPortrait(orientation)) { + keyboardHeight = CGRectGetHeight(keyboardFrame); + } + } + } else { + keyboardHeight = self.visibleKeyboardHeight; + } +#endif + + // Get the currently active frame of the display (depends on orientation) + CGRect orientationFrame = self.bounds; + +#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS + CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame; +#else + CGRect statusBarFrame = CGRectZero; +#endif + +#if TARGET_OS_IOS + // Update the motion effects in regard to orientation + [self updateMotionEffectForOrientation:orientation]; +#else + [self updateMotionEffectForXMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis yMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; +#endif + + // Calculate available height for display + CGFloat activeHeight = CGRectGetHeight(orientationFrame); + if(keyboardHeight > 0) { + activeHeight += CGRectGetHeight(statusBarFrame) * 2; + } + activeHeight -= keyboardHeight; + + CGFloat posX = CGRectGetMidX(orientationFrame); + CGFloat posY = floorf(activeHeight*0.45f); + + CGFloat rotateAngle = 0.0; + CGPoint newCenter = CGPointMake(posX, posY); + + if(notification) { + // Animate update if notification was present + [UIView animateWithDuration:animationDuration + delay:0 + options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState) + animations:^{ + [self moveToPoint:newCenter rotateAngle:rotateAngle]; + [self.hudView setNeedsDisplay]; + } completion:nil]; + } else { + [self moveToPoint:newCenter rotateAngle:rotateAngle]; + } +} + +- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle { + self.hudView.transform = CGAffineTransformMakeRotation(angle); + if (self.containerView) { + self.hudView.center = CGPointMake(self.containerView.center.x + self.offsetFromCenter.horizontal, self.containerView.center.y + self.offsetFromCenter.vertical); + } else { + self.hudView.center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical); + } +} + + +#pragma mark - Event handling + +- (void)controlViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent*)event { + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidReceiveTouchEventNotification + object:self + userInfo:[self notificationUserInfo]]; + + UITouch *touch = event.allTouches.anyObject; + CGPoint touchLocation = [touch locationInView:self]; + + if(CGRectContainsPoint(self.hudView.frame, touchLocation)) { + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidTouchDownInsideNotification + object:self + userInfo:[self notificationUserInfo]]; + } +} + + +#pragma mark - Master show/dismiss methods + +- (void)showProgress:(float)progress status:(NSString*)status { + __weak SVProgressHUD *weakSelf = self; + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + __strong SVProgressHUD *strongSelf = weakSelf; + if(strongSelf){ + if(strongSelf.fadeOutTimer) { + strongSelf.activityCount = 0; + } + + // Stop timer + strongSelf.fadeOutTimer = nil; + strongSelf.graceTimer = nil; + + // Update / Check view hierarchy to ensure the HUD is visible + [strongSelf updateViewHierarchy]; + + // Reset imageView and fadeout timer if an image is currently displayed + strongSelf.imageView.hidden = YES; + strongSelf.imageView.image = nil; + + // Update text and set progress to the given value + strongSelf.statusLabel.hidden = status.length == 0; + strongSelf.statusLabel.text = status; + strongSelf.progress = progress; + + // Choose the "right" indicator depending on the progress + if(progress >= 0) { + // Cancel the indefiniteAnimatedView, then show the ringLayer + [strongSelf cancelIndefiniteAnimatedViewAnimation]; + + // Add ring to HUD + if(!strongSelf.ringView.superview){ + [strongSelf.hudView.contentView addSubview:strongSelf.ringView]; + } + if(!strongSelf.backgroundRingView.superview){ + [strongSelf.hudView.contentView addSubview:strongSelf.backgroundRingView]; + } + + // Set progress animated + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + strongSelf.ringView.strokeEnd = progress; + [CATransaction commit]; + + // Update the activity count + if(progress == 0) { + strongSelf.activityCount++; + } + } else { + // Cancel the ringLayer animation, then show the indefiniteAnimatedView + [strongSelf cancelRingLayerAnimation]; + + // Add indefiniteAnimatedView to HUD + [strongSelf.hudView.contentView addSubview:strongSelf.indefiniteAnimatedView]; + if([strongSelf.indefiniteAnimatedView respondsToSelector:@selector(startAnimating)]) { + [(id)strongSelf.indefiniteAnimatedView startAnimating]; + } + + // Update the activity count + strongSelf.activityCount++; + } + + // Fade in delayed if a grace time is set + if (self.graceTimeInterval > 0.0 && self.backgroundView.alpha == 0.0f) { + strongSelf.graceTimer = [NSTimer timerWithTimeInterval:self.graceTimeInterval target:strongSelf selector:@selector(fadeIn:) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:strongSelf.graceTimer forMode:NSRunLoopCommonModes]; + } else { + [strongSelf fadeIn:nil]; + } + + // Tell the Haptics Generator to prepare for feedback, which may come soon +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 + if (@available(iOS 10.0, *)) { + [strongSelf.hapticGenerator prepare]; + } +#endif + } + }]; +} + +- (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration { + __weak SVProgressHUD *weakSelf = self; + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + __strong SVProgressHUD *strongSelf = weakSelf; + if(strongSelf){ + // Stop timer + strongSelf.fadeOutTimer = nil; + strongSelf.graceTimer = nil; + + // Update / Check view hierarchy to ensure the HUD is visible + [strongSelf updateViewHierarchy]; + + // Reset progress and cancel any running animation + strongSelf.progress = SVProgressHUDUndefinedProgress; + [strongSelf cancelRingLayerAnimation]; + [strongSelf cancelIndefiniteAnimatedViewAnimation]; + + // Update imageView + if (self.shouldTintImages) { + if (image.renderingMode != UIImageRenderingModeAlwaysTemplate) { + strongSelf.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } + strongSelf.imageView.tintColor = strongSelf.foregroundColorForStyle;; + } else { + strongSelf.imageView.image = image; + } + strongSelf.imageView.hidden = NO; + + // Update text + strongSelf.statusLabel.hidden = status.length == 0; + strongSelf.statusLabel.text = status; + + // Fade in delayed if a grace time is set + // An image will be dismissed automatically. Thus pass the duration as userInfo. + if (self.graceTimeInterval > 0.0 && self.backgroundView.alpha == 0.0f) { + strongSelf.graceTimer = [NSTimer timerWithTimeInterval:self.graceTimeInterval target:strongSelf selector:@selector(fadeIn:) userInfo:@(duration) repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:strongSelf.graceTimer forMode:NSRunLoopCommonModes]; + } else { + [strongSelf fadeIn:@(duration)]; + } + } + }]; +} + +- (void)fadeIn:(id)data { + // Update the HUDs frame to the new content and position HUD + [self updateHUDFrame]; + [self positionHUD:nil]; + + // Update accessibility as well as user interaction + if(self.defaultMaskType != SVProgressHUDMaskTypeNone) { + self.controlView.userInteractionEnabled = YES; + self.accessibilityLabel = self.statusLabel.text ?: NSLocalizedString(@"Loading", nil); + self.isAccessibilityElement = YES; + } else { + self.controlView.userInteractionEnabled = NO; + self.hudView.accessibilityLabel = self.statusLabel.text ?: NSLocalizedString(@"Loading", nil); + self.hudView.isAccessibilityElement = YES; + } + + // Get duration + id duration = [data isKindOfClass:[NSTimer class]] ? ((NSTimer *)data).userInfo : data; + + // Show if not already visible + if(self.backgroundView.alpha != 1.0f) { + // Post notification to inform user + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification + object:self + userInfo:[self notificationUserInfo]]; + + // Shrink HUD to to make a nice appear / pop up animation + self.hudView.transform = self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.5f, 1/1.5f); + + __block void (^animationsBlock)(void) = ^{ + // Zoom HUD a little to make a nice appear / pop up animation + self.hudView.transform = CGAffineTransformIdentity; + + // Fade in all effects (colors, blur, etc.) + [self fadeInEffects]; + }; + + __block void (^completionBlock)(void) = ^{ + // Check if we really achieved to show the HUD (<=> alpha) + // and the change of these values has not been cancelled in between e.g. due to a dismissal + if(self.backgroundView.alpha == 1.0f){ + // Register observer <=> we now have to handle orientation changes etc. + [self registerNotifications]; + + // Post notification to inform user + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotification + object:self + userInfo:[self notificationUserInfo]]; + + // Update accessibility + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, self.statusLabel.text); + + // Dismiss automatically if a duration was passed as userInfo. We start a timer + // which then will call dismiss after the predefined duration + if(duration){ + self.fadeOutTimer = [NSTimer timerWithTimeInterval:[(NSNumber *)duration doubleValue] target:self selector:@selector(dismiss) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes]; + } + } + }; + + // Animate appearance + if (self.fadeInAnimationDuration > 0) { + // Animate appearance + [UIView animateWithDuration:self.fadeInAnimationDuration + delay:0 + options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) + animations:^{ + animationsBlock(); + } completion:^(BOOL finished) { + completionBlock(); + }]; + } else { + animationsBlock(); + completionBlock(); + } + + // Inform iOS to redraw the view hierarchy + [self setNeedsDisplay]; + } else { + // Update accessibility + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, self.statusLabel.text); + + // Dismiss automatically if a duration was passed as userInfo. We start a timer + // which then will call dismiss after the predefined duration + if(duration){ + self.fadeOutTimer = [NSTimer timerWithTimeInterval:[(NSNumber *)duration doubleValue] target:self selector:@selector(dismiss) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes]; + } + } +} + +- (void)dismiss { + [self dismissWithDelay:0.0 completion:nil]; +} + +- (void)dismissWithDelay:(NSTimeInterval)delay completion:(SVProgressHUDDismissCompletion)completion { + __weak SVProgressHUD *weakSelf = self; + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + __strong SVProgressHUD *strongSelf = weakSelf; + if(strongSelf){ + // Stop timer + strongSelf.graceTimer = nil; + + // Post notification to inform user + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification + object:nil + userInfo:[strongSelf notificationUserInfo]]; + + // Reset activity count + strongSelf.activityCount = 0; + + __block void (^animationsBlock)(void) = ^{ + // Shrink HUD a little to make a nice disappear animation + strongSelf.hudView.transform = CGAffineTransformScale(strongSelf.hudView.transform, 1/1.3f, 1/1.3f); + + // Fade out all effects (colors, blur, etc.) + [strongSelf fadeOutEffects]; + }; + + __block void (^completionBlock)(void) = ^{ + // Check if we really achieved to dismiss the HUD (<=> alpha values are applied) + // and the change of these values has not been cancelled in between e.g. due to a new show + if(self.backgroundView.alpha == 0.0f){ + // Clean up view hierarchy (overlays) + [strongSelf.controlView removeFromSuperview]; + [strongSelf.backgroundView removeFromSuperview]; + [strongSelf.hudView removeFromSuperview]; + [strongSelf removeFromSuperview]; + + // Reset progress and cancel any running animation + strongSelf.progress = SVProgressHUDUndefinedProgress; + [strongSelf cancelRingLayerAnimation]; + [strongSelf cancelIndefiniteAnimatedViewAnimation]; + + // Remove observer <=> we do not have to handle orientation changes etc. + [[NSNotificationCenter defaultCenter] removeObserver:strongSelf]; + + // Post notification to inform user + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification + object:strongSelf + userInfo:[strongSelf notificationUserInfo]]; + + // Tell the rootViewController to update the StatusBar appearance +#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS + UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; + [rootController setNeedsStatusBarAppearanceUpdate]; +#endif + + // Run an (optional) completionHandler + if (completion) { + completion(); + } + } + }; + + // UIViewAnimationOptionBeginFromCurrentState AND a delay doesn't always work as expected + // When UIViewAnimationOptionBeginFromCurrentState is set, animateWithDuration: evaluates the current + // values to check if an animation is necessary. The evaluation happens at function call time and not + // after the delay => the animation is sometimes skipped. Therefore we delay using dispatch_after. + + dispatch_time_t dipatchTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)); + dispatch_after(dipatchTime, dispatch_get_main_queue(), ^{ + if (strongSelf.fadeOutAnimationDuration > 0) { + // Animate appearance + [UIView animateWithDuration:strongSelf.fadeOutAnimationDuration + delay:0 + options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState) + animations:^{ + animationsBlock(); + } completion:^(BOOL finished) { + completionBlock(); + }]; + } else { + animationsBlock(); + completionBlock(); + } + }); + + // Inform iOS to redraw the view hierarchy + [strongSelf setNeedsDisplay]; + } + }]; +} + + +#pragma mark - Ring progress animation + +- (UIView*)indefiniteAnimatedView { + // Get the correct spinner for defaultAnimationType + if(self.defaultAnimationType == SVProgressHUDAnimationTypeFlat){ + // Check if spinner exists and is an object of different class + if(_indefiniteAnimatedView && ![_indefiniteAnimatedView isKindOfClass:[SVIndefiniteAnimatedView class]]){ + [_indefiniteAnimatedView removeFromSuperview]; + _indefiniteAnimatedView = nil; + } + + if(!_indefiniteAnimatedView){ + _indefiniteAnimatedView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero]; + } + + // Update styling + SVIndefiniteAnimatedView *indefiniteAnimatedView = (SVIndefiniteAnimatedView*)_indefiniteAnimatedView; + indefiniteAnimatedView.strokeColor = self.foregroundColorForStyle; + indefiniteAnimatedView.strokeThickness = self.ringThickness; + indefiniteAnimatedView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; + } else { + // Check if spinner exists and is an object of different class + if(_indefiniteAnimatedView && ![_indefiniteAnimatedView isKindOfClass:[UIActivityIndicatorView class]]){ + [_indefiniteAnimatedView removeFromSuperview]; + _indefiniteAnimatedView = nil; + } + + if(!_indefiniteAnimatedView){ + _indefiniteAnimatedView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + } + + // Update styling + UIActivityIndicatorView *activityIndicatorView = (UIActivityIndicatorView*)_indefiniteAnimatedView; + activityIndicatorView.color = self.foregroundColorForStyle; + } + [_indefiniteAnimatedView sizeToFit]; + + return _indefiniteAnimatedView; +} + +- (SVProgressAnimatedView*)ringView { + if(!_ringView) { + _ringView = [[SVProgressAnimatedView alloc] initWithFrame:CGRectZero]; + } + + // Update styling + _ringView.strokeColor = self.foregroundColorForStyle; + _ringView.strokeThickness = self.ringThickness; + _ringView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; + + return _ringView; +} + +- (SVProgressAnimatedView*)backgroundRingView { + if(!_backgroundRingView) { + _backgroundRingView = [[SVProgressAnimatedView alloc] initWithFrame:CGRectZero]; + _backgroundRingView.strokeEnd = 1.0f; + } + + // Update styling + _backgroundRingView.strokeColor = [self.foregroundColorForStyle colorWithAlphaComponent:0.1f]; + _backgroundRingView.strokeThickness = self.ringThickness; + _backgroundRingView.radius = self.statusLabel.text ? self.ringRadius : self.ringNoTextRadius; + + return _backgroundRingView; +} + +- (void)cancelRingLayerAnimation { + // Animate value update, stop animation + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + + [self.hudView.layer removeAllAnimations]; + self.ringView.strokeEnd = 0.0f; + + [CATransaction commit]; + + // Remove from view + [self.ringView removeFromSuperview]; + [self.backgroundRingView removeFromSuperview]; +} + +- (void)cancelIndefiniteAnimatedViewAnimation { + // Stop animation + if([self.indefiniteAnimatedView respondsToSelector:@selector(stopAnimating)]) { + [(id)self.indefiniteAnimatedView stopAnimating]; + } + // Remove from view + [self.indefiniteAnimatedView removeFromSuperview]; +} + + +#pragma mark - Utilities + ++ (BOOL)isVisible { + // Checking one alpha value is sufficient as they are all the same + return [self sharedView].backgroundView.alpha > 0.0f; +} + + +#pragma mark - Getters + ++ (NSTimeInterval)displayDurationForString:(NSString*)string { + CGFloat minimum = MAX((CGFloat)string.length * 0.06 + 0.5, [self sharedView].minimumDismissTimeInterval); + return MIN(minimum, [self sharedView].maximumDismissTimeInterval); +} + +- (UIColor*)foregroundColorForStyle { + if(self.defaultStyle == SVProgressHUDStyleLight) { + return [UIColor blackColor]; + } else if(self.defaultStyle == SVProgressHUDStyleDark) { + return [UIColor whiteColor]; + } else { + return self.foregroundColor; + } +} + +- (UIColor*)backgroundColorForStyle { + if(self.defaultStyle == SVProgressHUDStyleLight) { + return [UIColor whiteColor]; + } else if(self.defaultStyle == SVProgressHUDStyleDark) { + return [UIColor blackColor]; + } else { + return self.backgroundColor; + } +} + +- (UIControl*)controlView { + if(!_controlView) { + _controlView = [UIControl new]; + _controlView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _controlView.backgroundColor = [UIColor clearColor]; + _controlView.userInteractionEnabled = YES; + [_controlView addTarget:self action:@selector(controlViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown]; + } + + // Update frames +#if !defined(SV_APP_EXTENSIONS) + CGRect windowBounds = [[[UIApplication sharedApplication] delegate] window].bounds; + _controlView.frame = windowBounds; +#else + _controlView.frame = [UIScreen mainScreen].bounds; +#endif + + return _controlView; +} + +-(UIView *)backgroundView { + if(!_backgroundView){ + _backgroundView = [UIView new]; + _backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + } + if(!_backgroundView.superview){ + [self insertSubview:_backgroundView belowSubview:self.hudView]; + } + + // Update styling + if(self.defaultMaskType == SVProgressHUDMaskTypeGradient){ + if(!_backgroundRadialGradientLayer){ + _backgroundRadialGradientLayer = [SVRadialGradientLayer layer]; + } + if(!_backgroundRadialGradientLayer.superlayer){ + [_backgroundView.layer insertSublayer:_backgroundRadialGradientLayer atIndex:0]; + } + _backgroundView.backgroundColor = [UIColor clearColor]; + } else { + if(_backgroundRadialGradientLayer && _backgroundRadialGradientLayer.superlayer){ + [_backgroundRadialGradientLayer removeFromSuperlayer]; + } + if(self.defaultMaskType == SVProgressHUDMaskTypeBlack){ + _backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4]; + } else if(self.defaultMaskType == SVProgressHUDMaskTypeCustom){ + _backgroundView.backgroundColor = self.backgroundLayerColor; + } else { + _backgroundView.backgroundColor = [UIColor clearColor]; + } + } + + // Update frame + if(_backgroundView){ + _backgroundView.frame = self.bounds; + } + if(_backgroundRadialGradientLayer){ + _backgroundRadialGradientLayer.frame = self.bounds; + + // Calculate the new center of the gradient, it may change if keyboard is visible + CGPoint gradientCenter = self.center; + gradientCenter.y = (self.bounds.size.height - self.visibleKeyboardHeight)/2; + _backgroundRadialGradientLayer.gradientCenter = gradientCenter; + [_backgroundRadialGradientLayer setNeedsDisplay]; + } + + return _backgroundView; +} +- (UIVisualEffectView*)hudView { + if(!_hudView) { + _hudView = [UIVisualEffectView new]; + _hudView.layer.masksToBounds = YES; + _hudView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin; + } + if(!_hudView.superview) { + [self addSubview:_hudView]; + } + + // Update styling + _hudView.layer.cornerRadius = self.cornerRadius; + + return _hudView; +} + +- (UILabel*)statusLabel { + if(!_statusLabel) { + _statusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _statusLabel.backgroundColor = [UIColor clearColor]; + _statusLabel.adjustsFontSizeToFitWidth = YES; + _statusLabel.textAlignment = NSTextAlignmentCenter; + _statusLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; + _statusLabel.numberOfLines = 0; + } + if(!_statusLabel.superview) { + [self.hudView.contentView addSubview:_statusLabel]; + } + + // Update styling + _statusLabel.textColor = self.foregroundColorForStyle; + _statusLabel.font = self.font; + + return _statusLabel; +} + +- (UIImageView*)imageView { + if(_imageView && !CGSizeEqualToSize(_imageView.bounds.size, _imageViewSize)) { + [_imageView removeFromSuperview]; + _imageView = nil; + } + + if(!_imageView) { + _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, _imageViewSize.width, _imageViewSize.height)]; + } + if(!_imageView.superview) { + [self.hudView.contentView addSubview:_imageView]; + } + + return _imageView; +} + + +#pragma mark - Helper + +- (CGFloat)visibleKeyboardHeight { +#if !defined(SV_APP_EXTENSIONS) + UIWindow *keyboardWindow = nil; + for (UIWindow *testWindow in UIApplication.sharedApplication.windows) { + if(![testWindow.class isEqual:UIWindow.class]) { + keyboardWindow = testWindow; + break; + } + } + + for (__strong UIView *possibleKeyboard in keyboardWindow.subviews) { + NSString *viewName = NSStringFromClass(possibleKeyboard.class); + if([viewName hasPrefix:@"UI"]){ + if([viewName hasSuffix:@"PeripheralHostView"] || [viewName hasSuffix:@"Keyboard"]){ + return CGRectGetHeight(possibleKeyboard.bounds); + } else if ([viewName hasSuffix:@"InputSetContainerView"]){ + for (__strong UIView *possibleKeyboardSubview in possibleKeyboard.subviews) { + viewName = NSStringFromClass(possibleKeyboardSubview.class); + if([viewName hasPrefix:@"UI"] && [viewName hasSuffix:@"InputSetHostView"]) { + CGRect convertedRect = [possibleKeyboard convertRect:possibleKeyboardSubview.frame toView:self]; + CGRect intersectedRect = CGRectIntersection(convertedRect, self.bounds); + if (!CGRectIsNull(intersectedRect)) { + return CGRectGetHeight(intersectedRect); + } + } + } + } + } + } +#endif + return 0; +} + +- (UIWindow *)frontWindow { +#if !defined(SV_APP_EXTENSIONS) + NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator]; + for (UIWindow *window in frontToBackWindows) { + BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen; + BOOL windowIsVisible = !window.hidden && window.alpha > 0; + BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal && window.windowLevel <= self.maxSupportedWindowLevel); + BOOL windowKeyWindow = window.isKeyWindow; + + if(windowOnMainScreen && windowIsVisible && windowLevelSupported && windowKeyWindow) { + return window; + } + } +#endif + return nil; +} + +- (void)fadeInEffects { + if(self.defaultStyle != SVProgressHUDStyleCustom) { + // Add blur effect + UIBlurEffectStyle blurEffectStyle = self.defaultStyle == SVProgressHUDStyleDark ? UIBlurEffectStyleDark : UIBlurEffectStyleLight; + UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:blurEffectStyle]; + self.hudView.effect = blurEffect; + + // We omit UIVibrancy effect and use a suitable background color as an alternative. + // This will make everything more readable. See the following for details: + // https://www.omnigroup.com/developer/how-to-make-text-in-a-uivisualeffectview-readable-on-any-background + + self.hudView.backgroundColor = [self.backgroundColorForStyle colorWithAlphaComponent:0.6f]; + } else { + self.hudView.backgroundColor = self.backgroundColorForStyle; + } + + // Fade in views + self.backgroundView.alpha = 1.0f; + + self.imageView.alpha = 1.0f; + self.statusLabel.alpha = 1.0f; + self.indefiniteAnimatedView.alpha = 1.0f; + self.ringView.alpha = self.backgroundRingView.alpha = 1.0f; +} + +- (void)fadeOutEffects +{ + if(self.defaultStyle != SVProgressHUDStyleCustom) { + // Remove blur effect + self.hudView.effect = nil; + } + + // Remove background color + self.hudView.backgroundColor = [UIColor clearColor]; + + // Fade out views + self.backgroundView.alpha = 0.0f; + + self.imageView.alpha = 0.0f; + self.statusLabel.alpha = 0.0f; + self.indefiniteAnimatedView.alpha = 0.0f; + self.ringView.alpha = self.backgroundRingView.alpha = 0.0f; +} + +#if TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 +- (UINotificationFeedbackGenerator *)hapticGenerator NS_AVAILABLE_IOS(10_0) { + // Only return if haptics are enabled + if(!self.hapticsEnabled) { + return nil; + } + + if(!_hapticGenerator) { + _hapticGenerator = [[UINotificationFeedbackGenerator alloc] init]; + } + return _hapticGenerator; +} +#endif + + +#pragma mark - UIAppearance Setters + +- (void)setDefaultStyle:(SVProgressHUDStyle)style { + if (!_isInitializing) _defaultStyle = style; +} + +- (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType { + if (!_isInitializing) _defaultMaskType = maskType; +} + +- (void)setDefaultAnimationType:(SVProgressHUDAnimationType)animationType { + if (!_isInitializing) _defaultAnimationType = animationType; +} + +- (void)setContainerView:(UIView *)containerView { + if (!_isInitializing) _containerView = containerView; +} + +- (void)setMinimumSize:(CGSize)minimumSize { + if (!_isInitializing) _minimumSize = minimumSize; +} + +- (void)setRingThickness:(CGFloat)ringThickness { + if (!_isInitializing) _ringThickness = ringThickness; +} + +- (void)setRingRadius:(CGFloat)ringRadius { + if (!_isInitializing) _ringRadius = ringRadius; +} + +- (void)setRingNoTextRadius:(CGFloat)ringNoTextRadius { + if (!_isInitializing) _ringNoTextRadius = ringNoTextRadius; +} + +- (void)setCornerRadius:(CGFloat)cornerRadius { + if (!_isInitializing) _cornerRadius = cornerRadius; +} + +- (void)setFont:(UIFont*)font { + if (!_isInitializing) _font = font; +} + +- (void)setForegroundColor:(UIColor*)color { + if (!_isInitializing) _foregroundColor = color; +} + +- (void)setBackgroundColor:(UIColor*)color { + if (!_isInitializing) _backgroundColor = color; +} + +- (void)setBackgroundLayerColor:(UIColor*)color { + if (!_isInitializing) _backgroundLayerColor = color; +} + +- (void)setShouldTintImages:(BOOL)shouldTintImages { + if (!_isInitializing) _shouldTintImages = shouldTintImages; +} + +- (void)setInfoImage:(UIImage*)image { + if (!_isInitializing) _infoImage = image; +} + +- (void)setSuccessImage:(UIImage*)image { + if (!_isInitializing) _successImage = image; +} + +- (void)setErrorImage:(UIImage*)image { + if (!_isInitializing) _errorImage = image; +} + +- (void)setViewForExtension:(UIView*)view { + if (!_isInitializing) _viewForExtension = view; +} + +- (void)setOffsetFromCenter:(UIOffset)offset { + if (!_isInitializing) _offsetFromCenter = offset; +} + +- (void)setMinimumDismissTimeInterval:(NSTimeInterval)minimumDismissTimeInterval { + if (!_isInitializing) _minimumDismissTimeInterval = minimumDismissTimeInterval; +} + +- (void)setFadeInAnimationDuration:(NSTimeInterval)duration { + if (!_isInitializing) _fadeInAnimationDuration = duration; +} + +- (void)setFadeOutAnimationDuration:(NSTimeInterval)duration { + if (!_isInitializing) _fadeOutAnimationDuration = duration; +} + +- (void)setMaxSupportedWindowLevel:(UIWindowLevel)maxSupportedWindowLevel { + if (!_isInitializing) _maxSupportedWindowLevel = maxSupportedWindowLevel; +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h new file mode 100644 index 00000000..68d452a2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.h @@ -0,0 +1,14 @@ +// +// SVRadialGradientLayer.h +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2014-2018 Tobias Tiemerding. All rights reserved. +// + +#import + +@interface SVRadialGradientLayer : CALayer + +@property (nonatomic) CGPoint gradientCenter; + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m new file mode 100644 index 00000000..c62e0f85 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SVProgressHUD/SVProgressHUD/SVRadialGradientLayer.m @@ -0,0 +1,25 @@ +// +// SVRadialGradientLayer.m +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD +// +// Copyright (c) 2014-2018 Tobias Tiemerding. All rights reserved. +// + +#import "SVRadialGradientLayer.h" + +@implementation SVRadialGradientLayer + +- (void)drawInContext:(CGContextRef)context { + size_t locationsCount = 2; + CGFloat locations[2] = {0.0f, 1.0f}; + CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f}; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); + CGColorSpaceRelease(colorSpace); + + float radius = MIN(self.bounds.size.width , self.bounds.size.height); + CGContextDrawRadialGradient (context, gradient, self.gradientCenter, 0, self.gradientCenter, radius, kCGGradientDrawsAfterEndLocation); + CGGradientRelease(gradient); +} + +@end diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIO/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIO/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIO/Sources/NIO/Exports.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/Sources/NIO/Exports.swift new file mode 100644 index 00000000..71a5441e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIO/Sources/NIO/Exports.swift @@ -0,0 +1,16 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +@_exported import NIOCore +@_exported import NIOEmbedded +@_exported import NIOPosix diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/NIOAtomic.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/NIOAtomic.swift new file mode 100644 index 00000000..c959d5cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/NIOAtomic.swift @@ -0,0 +1,313 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import CNIOAtomics + +/// The protocol that all types that can be made atomic must conform to. +/// +/// **Do not add conformance to this protocol for arbitrary types**. Only a small range +/// of types have appropriate atomic operations supported by the CPU, and those types +/// already have conformances implemented. +public protocol NIOAtomicPrimitive { + associatedtype AtomicWrapper + static var nio_atomic_create_with_existing_storage: (UnsafeMutablePointer, Self) -> Void { get } + static var nio_atomic_compare_and_exchange: (UnsafeMutablePointer, Self, Self) -> Bool { get } + static var nio_atomic_add: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_sub: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_exchange: (UnsafeMutablePointer, Self) -> Self { get } + static var nio_atomic_load: (UnsafeMutablePointer) -> Self { get } + static var nio_atomic_store: (UnsafeMutablePointer, Self) -> Void { get } +} + +extension Bool: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic__Bool + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic__Bool_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic__Bool_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic__Bool_add + public static let nio_atomic_sub = catmc_nio_atomic__Bool_sub + public static let nio_atomic_exchange = catmc_nio_atomic__Bool_exchange + public static let nio_atomic_load = catmc_nio_atomic__Bool_load + public static let nio_atomic_store = catmc_nio_atomic__Bool_store +} + +extension Int8: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least8_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least8_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least8_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least8_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least8_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least8_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least8_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least8_t_store +} + +extension UInt8: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least8_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least8_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least8_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least8_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least8_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least8_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least8_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least8_t_store +} + +extension Int16: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least16_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least16_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least16_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least16_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least16_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least16_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least16_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least16_t_store +} + +extension UInt16: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least16_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least16_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least16_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least16_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least16_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least16_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least16_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least16_t_store +} + +extension Int32: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_int_least32_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_int_least32_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_int_least32_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_int_least32_t_add + public static let nio_atomic_sub = catmc_nio_atomic_int_least32_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_int_least32_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_int_least32_t_load + public static let nio_atomic_store = catmc_nio_atomic_int_least32_t_store +} + +extension UInt32: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uint_least32_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uint_least32_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uint_least32_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uint_least32_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uint_least32_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uint_least32_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uint_least32_t_load + public static let nio_atomic_store = catmc_nio_atomic_uint_least32_t_store +} + +extension Int64: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_long_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_long_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_long_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_long_long_add + public static let nio_atomic_sub = catmc_nio_atomic_long_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_long_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_long_long_load + public static let nio_atomic_store = catmc_nio_atomic_long_long_store +} + +extension UInt64: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_unsigned_long_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_unsigned_long_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_unsigned_long_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_unsigned_long_long_add + public static let nio_atomic_sub = catmc_nio_atomic_unsigned_long_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_unsigned_long_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_unsigned_long_long_load + public static let nio_atomic_store = catmc_nio_atomic_unsigned_long_long_store +} + +#if os(Windows) +extension Int: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_intptr_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_intptr_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_intptr_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_intptr_t_add + public static let nio_atomic_sub = catmc_nio_atomic_intptr_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_intptr_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_intptr_t_load + public static let nio_atomic_store = catmc_nio_atomic_intptr_t_store +} + +extension UInt: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_uintptr_t + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_uintptr_t_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_uintptr_t_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_uintptr_t_add + public static let nio_atomic_sub = catmc_nio_atomic_uintptr_t_sub + public static let nio_atomic_exchange = catmc_nio_atomic_uintptr_t_exchange + public static let nio_atomic_load = catmc_nio_atomic_uintptr_t_load + public static let nio_atomic_store = catmc_nio_atomic_uintptr_t_store +} +#else +extension Int: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_long_add + public static let nio_atomic_sub = catmc_nio_atomic_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_long_load + public static let nio_atomic_store = catmc_nio_atomic_long_store +} + +extension UInt: NIOAtomicPrimitive { + public typealias AtomicWrapper = catmc_nio_atomic_unsigned_long + public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic_unsigned_long_create_with_existing_storage + public static let nio_atomic_compare_and_exchange = catmc_nio_atomic_unsigned_long_compare_and_exchange + public static let nio_atomic_add = catmc_nio_atomic_unsigned_long_add + public static let nio_atomic_sub = catmc_nio_atomic_unsigned_long_sub + public static let nio_atomic_exchange = catmc_nio_atomic_unsigned_long_exchange + public static let nio_atomic_load = catmc_nio_atomic_unsigned_long_load + public static let nio_atomic_store = catmc_nio_atomic_unsigned_long_store +} +#endif + +/// An encapsulation of an atomic primitive object. +/// +/// Atomic objects support a wide range of atomic operations: +/// +/// - Compare and swap +/// - Add +/// - Subtract +/// - Exchange +/// - Load current value +/// - Store current value +/// +/// Atomic primitives are useful when building constructs that need to +/// communicate or cooperate across multiple threads. In the case of +/// SwiftNIO this usually involves communicating across multiple event loops. +/// +/// By necessity, all atomic values are references: after all, it makes no +/// sense to talk about managing an atomic value when each time it's modified +/// the thread that modified it gets a local copy! +public final class NIOAtomic { + @usableFromInline + typealias Manager = ManagedBufferPointer + + /// Create an atomic object with `value` + @inlinable + public static func makeAtomic(value: T) -> NIOAtomic { + let manager = Manager(bufferClass: self, minimumCapacity: 1) { _, _ in } + manager.withUnsafeMutablePointerToElements { + T.nio_atomic_create_with_existing_storage($0, value) + } + return manager.buffer as! NIOAtomic + } + + /// Atomically compares the value against `expected` and, if they are equal, + /// replaces the value with `desired`. + /// + /// This implementation conforms to C11's `atomic_compare_exchange_strong`. This + /// means that the compare-and-swap will always succeed if `expected` is equal to + /// value. Additionally, it uses a *sequentially consistent ordering*. For more + /// details on atomic memory models, check the documentation for C11's + /// `stdatomic.h`. + /// + /// - Parameter expected: The value that this object must currently hold for the + /// compare-and-swap to succeed. + /// - Parameter desired: The new value that this object will hold if the compare + /// succeeds. + /// - Returns: `True` if the exchange occurred, or `False` if `expected` did not + /// match the current value and so no exchange occurred. + @inlinable + public func compareAndExchange(expected: T, desired: T) -> Bool { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_compare_and_exchange($0, expected, desired) + } + } + + /// Atomically adds `rhs` to this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to add to this object. + /// - Returns: The previous value of this object, before the addition occurred. + @inlinable + @discardableResult + public func add(_ rhs: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_add($0, rhs) + } + } + + /// Atomically subtracts `rhs` from this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to subtract from this object. + /// - Returns: The previous value of this object, before the subtraction occurred. + @inlinable + @discardableResult + public func sub(_ rhs: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_sub($0, rhs) + } + } + + /// Atomically exchanges `value` for the current value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set this object to. + /// - Returns: The value previously held by this object. + @inlinable + public func exchange(with value: T) -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_exchange($0, value) + } + } + + /// Atomically loads and returns the value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Returns: The value of this object + @inlinable + public func load() -> T { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_load($0) + } + } + + /// Atomically replaces the value of this object with `value`. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set the object to. + @inlinable + public func store(_ value: T) -> Void { + return Manager(unsafeBufferObject: self).withUnsafeMutablePointerToElements { + return T.nio_atomic_store($0, value) + } + } + + deinit { + Manager(unsafeBufferObject: self).withUnsafeMutablePointers { headerPtr, elementsPtr in + elementsPtr.deinitialize(count: 1) + headerPtr.deinitialize(count: 1) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/atomics.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/atomics.swift new file mode 100644 index 00000000..af74f47d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/atomics.swift @@ -0,0 +1,585 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import CNIOAtomics + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin +fileprivate func sys_sched_yield() { + pthread_yield_np() +} +#elseif os(Windows) +import ucrt +import WinSDK +fileprivate func sys_sched_yield() { + Sleep(0) +} +#else +import Glibc +fileprivate func sys_sched_yield() { + _ = sched_yield() +} +#endif + +/// An atomic primitive object. +/// +/// Before using `UnsafeEmbeddedAtomic`, please consider whether your needs can be met by `Atomic` instead. +/// `UnsafeEmbeddedAtomic` is a value type, but atomics are heap-allocated. Thus, it is only safe to +/// use `UnsafeEmbeddedAtomic` in situations where the atomic can be guaranteed to be cleaned up (via calling `destroy`). +/// If you cannot make these guarantees, use `Atomic` instead, which manages this for you. +/// +/// Atomic objects support a wide range of atomic operations: +/// +/// - Compare and swap +/// - Add +/// - Subtract +/// - Exchange +/// - Load current value +/// - Store current value +/// +/// Atomic primitives are useful when building constructs that need to +/// communicate or cooperate across multiple threads. In the case of +/// SwiftNIO this usually involves communicating across multiple event loops. +public struct UnsafeEmbeddedAtomic { + @usableFromInline + internal let value: OpaquePointer + + /// Create an atomic object with `value`. + @inlinable + public init(value: T) { + self.value = T.atomic_create(value) + } + + /// Atomically compares the value against `expected` and, if they are equal, + /// replaces the value with `desired`. + /// + /// This implementation conforms to C11's `atomic_compare_exchange_strong`. This + /// means that the compare-and-swap will always succeed if `expected` is equal to + /// value. Additionally, it uses a *sequentially consistent ordering*. For more + /// details on atomic memory models, check the documentation for C11's + /// `stdatomic.h`. + /// + /// - Parameter expected: The value that this object must currently hold for the + /// compare-and-swap to succeed. + /// - Parameter desired: The new value that this object will hold if the compare + /// succeeds. + /// - Returns: `True` if the exchange occurred, or `False` if `expected` did not + /// match the current value and so no exchange occurred. + @inlinable + public func compareAndExchange(expected: T, desired: T) -> Bool { + return T.atomic_compare_and_exchange(self.value, expected, desired) + } + + /// Atomically adds `rhs` to this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to add to this object. + /// - Returns: The previous value of this object, before the addition occurred. + @discardableResult + @inlinable + public func add(_ rhs: T) -> T { + return T.atomic_add(self.value, rhs) + } + + /// Atomically subtracts `rhs` from this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to subtract from this object. + /// - Returns: The previous value of this object, before the subtraction occurred. + @discardableResult + @inlinable + public func sub(_ rhs: T) -> T { + return T.atomic_sub(self.value, rhs) + } + + /// Atomically exchanges `value` for the current value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set this object to. + /// - Returns: The value previously held by this object. + @inlinable + public func exchange(with value: T) -> T { + return T.atomic_exchange(self.value, value) + } + + /// Atomically loads and returns the value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Returns: The value of this object + @inlinable + public func load() -> T { + return T.atomic_load(self.value) + } + + /// Atomically replaces the value of this object with `value`. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set the object to. + @inlinable + public func store(_ value: T) -> Void { + T.atomic_store(self.value, value) + } + + /// Destroy the atomic value. + /// + /// This method is the source of the unsafety of this structure. This *must* be called, or you will leak memory with each + /// atomic. + public func destroy() { + T.atomic_destroy(self.value) + } +} + +/// An encapsulation of an atomic primitive object. +/// +/// Atomic objects support a wide range of atomic operations: +/// +/// - Compare and swap +/// - Add +/// - Subtract +/// - Exchange +/// - Load current value +/// - Store current value +/// +/// Atomic primitives are useful when building constructs that need to +/// communicate or cooperate across multiple threads. In the case of +/// SwiftNIO this usually involves communicating across multiple event loops. +/// +/// By necessity, all atomic values are references: after all, it makes no +/// sense to talk about managing an atomic value when each time it's modified +/// the thread that modified it gets a local copy! +@available(*, deprecated, message:"please use NIOAtomic instead") +public final class Atomic { + @usableFromInline + internal let embedded: UnsafeEmbeddedAtomic + + /// Create an atomic object with `value`. + @inlinable + public init(value: T) { + self.embedded = UnsafeEmbeddedAtomic(value: value) + } + + /// Atomically compares the value against `expected` and, if they are equal, + /// replaces the value with `desired`. + /// + /// This implementation conforms to C11's `atomic_compare_exchange_strong`. This + /// means that the compare-and-swap will always succeed if `expected` is equal to + /// value. Additionally, it uses a *sequentially consistent ordering*. For more + /// details on atomic memory models, check the documentation for C11's + /// `stdatomic.h`. + /// + /// - Parameter expected: The value that this object must currently hold for the + /// compare-and-swap to succeed. + /// - Parameter desired: The new value that this object will hold if the compare + /// succeeds. + /// - Returns: `True` if the exchange occurred, or `False` if `expected` did not + /// match the current value and so no exchange occurred. + @inlinable + public func compareAndExchange(expected: T, desired: T) -> Bool { + return self.embedded.compareAndExchange(expected: expected, desired: desired) + } + + /// Atomically adds `rhs` to this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to add to this object. + /// - Returns: The previous value of this object, before the addition occurred. + @discardableResult + @inlinable + public func add(_ rhs: T) -> T { + return self.embedded.add(rhs) + } + + /// Atomically subtracts `rhs` from this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter rhs: The value to subtract from this object. + /// - Returns: The previous value of this object, before the subtraction occurred. + @discardableResult + @inlinable + public func sub(_ rhs: T) -> T { + return self.embedded.sub(rhs) + } + + /// Atomically exchanges `value` for the current value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set this object to. + /// - Returns: The value previously held by this object. + @inlinable + public func exchange(with value: T) -> T { + return self.embedded.exchange(with: value) + } + + /// Atomically loads and returns the value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Returns: The value of this object + @inlinable + public func load() -> T { + return self.embedded.load() + } + + /// Atomically replaces the value of this object with `value`. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - Parameter value: The new value to set the object to. + @inlinable + public func store(_ value: T) -> Void { + self.embedded.store(value) + } + + deinit { + self.embedded.destroy() + } +} + +/// The protocol that all types that can be made atomic must conform to. +/// +/// **Do not add conformance to this protocol for arbitrary types**. Only a small range +/// of types have appropriate atomic operations supported by the CPU, and those types +/// already have conformances implemented. +public protocol AtomicPrimitive { + static var atomic_create: (Self) -> OpaquePointer { get } + static var atomic_destroy: (OpaquePointer) -> Void { get } + static var atomic_compare_and_exchange: (OpaquePointer, Self, Self) -> Bool { get } + static var atomic_add: (OpaquePointer, Self) -> Self { get } + static var atomic_sub: (OpaquePointer, Self) -> Self { get } + static var atomic_exchange: (OpaquePointer, Self) -> Self { get } + static var atomic_load: (OpaquePointer) -> Self { get } + static var atomic_store: (OpaquePointer, Self) -> Void { get } +} + +extension Bool: AtomicPrimitive { + public static let atomic_create = catmc_atomic__Bool_create + public static let atomic_destroy = catmc_atomic__Bool_destroy + public static let atomic_compare_and_exchange = catmc_atomic__Bool_compare_and_exchange + public static let atomic_add = catmc_atomic__Bool_add + public static let atomic_sub = catmc_atomic__Bool_sub + public static let atomic_exchange = catmc_atomic__Bool_exchange + public static let atomic_load = catmc_atomic__Bool_load + public static let atomic_store = catmc_atomic__Bool_store +} + +extension Int8: AtomicPrimitive { + public static let atomic_create = catmc_atomic_int_least8_t_create + public static let atomic_destroy = catmc_atomic_int_least8_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_int_least8_t_compare_and_exchange + public static let atomic_add = catmc_atomic_int_least8_t_add + public static let atomic_sub = catmc_atomic_int_least8_t_sub + public static let atomic_exchange = catmc_atomic_int_least8_t_exchange + public static let atomic_load = catmc_atomic_int_least8_t_load + public static let atomic_store = catmc_atomic_int_least8_t_store +} + +extension UInt8: AtomicPrimitive { + public static let atomic_create = catmc_atomic_uint_least8_t_create + public static let atomic_destroy = catmc_atomic_uint_least8_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_uint_least8_t_compare_and_exchange + public static let atomic_add = catmc_atomic_uint_least8_t_add + public static let atomic_sub = catmc_atomic_uint_least8_t_sub + public static let atomic_exchange = catmc_atomic_uint_least8_t_exchange + public static let atomic_load = catmc_atomic_uint_least8_t_load + public static let atomic_store = catmc_atomic_uint_least8_t_store +} + +extension Int16: AtomicPrimitive { + public static let atomic_create = catmc_atomic_int_least16_t_create + public static let atomic_destroy = catmc_atomic_int_least16_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_int_least16_t_compare_and_exchange + public static let atomic_add = catmc_atomic_int_least16_t_add + public static let atomic_sub = catmc_atomic_int_least16_t_sub + public static let atomic_exchange = catmc_atomic_int_least16_t_exchange + public static let atomic_load = catmc_atomic_int_least16_t_load + public static let atomic_store = catmc_atomic_int_least16_t_store +} + +extension UInt16: AtomicPrimitive { + public static let atomic_create = catmc_atomic_uint_least16_t_create + public static let atomic_destroy = catmc_atomic_uint_least16_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_uint_least16_t_compare_and_exchange + public static let atomic_add = catmc_atomic_uint_least16_t_add + public static let atomic_sub = catmc_atomic_uint_least16_t_sub + public static let atomic_exchange = catmc_atomic_uint_least16_t_exchange + public static let atomic_load = catmc_atomic_uint_least16_t_load + public static let atomic_store = catmc_atomic_uint_least16_t_store +} + +extension Int32: AtomicPrimitive { + public static let atomic_create = catmc_atomic_int_least32_t_create + public static let atomic_destroy = catmc_atomic_int_least32_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_int_least32_t_compare_and_exchange + public static let atomic_add = catmc_atomic_int_least32_t_add + public static let atomic_sub = catmc_atomic_int_least32_t_sub + public static let atomic_exchange = catmc_atomic_int_least32_t_exchange + public static let atomic_load = catmc_atomic_int_least32_t_load + public static let atomic_store = catmc_atomic_int_least32_t_store +} + +extension UInt32: AtomicPrimitive { + public static let atomic_create = catmc_atomic_uint_least32_t_create + public static let atomic_destroy = catmc_atomic_uint_least32_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_uint_least32_t_compare_and_exchange + public static let atomic_add = catmc_atomic_uint_least32_t_add + public static let atomic_sub = catmc_atomic_uint_least32_t_sub + public static let atomic_exchange = catmc_atomic_uint_least32_t_exchange + public static let atomic_load = catmc_atomic_uint_least32_t_load + public static let atomic_store = catmc_atomic_uint_least32_t_store +} + +extension Int64: AtomicPrimitive { + public static let atomic_create = catmc_atomic_long_long_create + public static let atomic_destroy = catmc_atomic_long_long_destroy + public static let atomic_compare_and_exchange = catmc_atomic_long_long_compare_and_exchange + public static let atomic_add = catmc_atomic_long_long_add + public static let atomic_sub = catmc_atomic_long_long_sub + public static let atomic_exchange = catmc_atomic_long_long_exchange + public static let atomic_load = catmc_atomic_long_long_load + public static let atomic_store = catmc_atomic_long_long_store +} + +extension UInt64: AtomicPrimitive { + public static let atomic_create = catmc_atomic_unsigned_long_long_create + public static let atomic_destroy = catmc_atomic_unsigned_long_long_destroy + public static let atomic_compare_and_exchange = catmc_atomic_unsigned_long_long_compare_and_exchange + public static let atomic_add = catmc_atomic_unsigned_long_long_add + public static let atomic_sub = catmc_atomic_unsigned_long_long_sub + public static let atomic_exchange = catmc_atomic_unsigned_long_long_exchange + public static let atomic_load = catmc_atomic_unsigned_long_long_load + public static let atomic_store = catmc_atomic_unsigned_long_long_store +} + +#if os(Windows) +extension Int: AtomicPrimitive { + public static let atomic_create = catmc_atomic_intptr_t_create + public static let atomic_destroy = catmc_atomic_intptr_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_intptr_t_compare_and_exchange + public static let atomic_add = catmc_atomic_intptr_t_add + public static let atomic_sub = catmc_atomic_intptr_t_sub + public static let atomic_exchange = catmc_atomic_intptr_t_exchange + public static let atomic_load = catmc_atomic_intptr_t_load + public static let atomic_store = catmc_atomic_intptr_t_store +} + +extension UInt: AtomicPrimitive { + public static let atomic_create = catmc_atomic_uintptr_t_create + public static let atomic_destroy = catmc_atomic_uintptr_t_destroy + public static let atomic_compare_and_exchange = catmc_atomic_uintptr_t_compare_and_exchange + public static let atomic_add = catmc_atomic_uintptr_t_add + public static let atomic_sub = catmc_atomic_uintptr_t_sub + public static let atomic_exchange = catmc_atomic_uintptr_t_exchange + public static let atomic_load = catmc_atomic_uintptr_t_load + public static let atomic_store = catmc_atomic_uintptr_t_store +} +#else +extension Int: AtomicPrimitive { + public static let atomic_create = catmc_atomic_long_create + public static let atomic_destroy = catmc_atomic_long_destroy + public static let atomic_compare_and_exchange = catmc_atomic_long_compare_and_exchange + public static let atomic_add = catmc_atomic_long_add + public static let atomic_sub = catmc_atomic_long_sub + public static let atomic_exchange = catmc_atomic_long_exchange + public static let atomic_load = catmc_atomic_long_load + public static let atomic_store = catmc_atomic_long_store +} + +extension UInt: AtomicPrimitive { + public static let atomic_create = catmc_atomic_unsigned_long_create + public static let atomic_destroy = catmc_atomic_unsigned_long_destroy + public static let atomic_compare_and_exchange = catmc_atomic_unsigned_long_compare_and_exchange + public static let atomic_add = catmc_atomic_unsigned_long_add + public static let atomic_sub = catmc_atomic_unsigned_long_sub + public static let atomic_exchange = catmc_atomic_unsigned_long_exchange + public static let atomic_load = catmc_atomic_unsigned_long_load + public static let atomic_store = catmc_atomic_unsigned_long_store +} +#endif + +/// `AtomicBox` is a heap-allocated box which allows lock-free access to an instance of a Swift class. +/// +/// - warning: The use of `AtomicBox` should be avoided because it requires an implementation of a spin-lock +/// (more precisely a CAS loop) to operate correctly. +@available(*, deprecated, message: "AtomicBox is deprecated without replacement because the original implementation doesn't work.") +public final class AtomicBox { + private let storage: NIOAtomic + + public init(value: T) { + let ptr = Unmanaged.passRetained(value) + self.storage = NIOAtomic.makeAtomic(value: UInt(bitPattern: ptr.toOpaque())) + } + + deinit { + let oldPtrBits = self.storage.exchange(with: 0xdeadbee) + let oldPtr = Unmanaged.fromOpaque(UnsafeRawPointer(bitPattern: oldPtrBits)!) + oldPtr.release() + } + + /// Atomically compares the value against `expected` and, if they are equal, + /// replaces the value with `desired`. + /// + /// This implementation conforms to C11's `atomic_compare_exchange_strong`. This + /// means that the compare-and-swap will always succeed if `expected` is equal to + /// value. Additionally, it uses a *sequentially consistent ordering*. For more + /// details on atomic memory models, check the documentation for C11's + /// `stdatomic.h`. + /// + /// + /// - warning: The implementation of `exchange` contains a _Compare and Exchange loop_, ie. it may busy wait with + /// 100% CPU load. + /// + /// - Parameter expected: The value that this object must currently hold for the + /// compare-and-swap to succeed. + /// - Parameter desired: The new value that this object will hold if the compare + /// succeeds. + /// - Returns: `True` if the exchange occurred, or `False` if `expected` did not + /// match the current value and so no exchange occurred. + public func compareAndExchange(expected: T, desired: T) -> Bool { + return withExtendedLifetime(desired) { + let expectedPtr = Unmanaged.passUnretained(expected) + let desiredPtr = Unmanaged.passUnretained(desired) + let expectedPtrBits = UInt(bitPattern: expectedPtr.toOpaque()) + let desiredPtrBits = UInt(bitPattern: desiredPtr.toOpaque()) + + while true { + if self.storage.compareAndExchange(expected: expectedPtrBits, desired: desiredPtrBits) { + if desiredPtrBits != expectedPtrBits { + _ = desiredPtr.retain() + expectedPtr.release() + } + return true + } else { + let currentPtrBits = self.storage.load() + if currentPtrBits == 0 || currentPtrBits == expectedPtrBits { + sys_sched_yield() + continue + } else { + return false + } + } + } + } + } + + /// Atomically exchanges `value` for the current value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - warning: The implementation of `exchange` contains a _Compare and Exchange loop_, ie. it may busy wait with + /// 100% CPU load. + /// + /// - Parameter value: The new value to set this object to. + /// - Returns: The value previously held by this object. + public func exchange(with value: T) -> T { + let newPtr = Unmanaged.passRetained(value) + let newPtrBits = UInt(bitPattern: newPtr.toOpaque()) + + // step 1: We need to actually CAS loop here to swap out a non-0 value with the new one. + var oldPtrBits: UInt = 0 + while true { + let speculativeVal = self.storage.load() + guard speculativeVal != 0 else { + sys_sched_yield() + continue + } + if self.storage.compareAndExchange(expected: speculativeVal, desired: newPtrBits) { + oldPtrBits = speculativeVal + break + } + } + + // step 2: After having gained 'ownership' of the old value, we can release the Unmanaged. + let oldPtr = Unmanaged.fromOpaque(UnsafeRawPointer(bitPattern: oldPtrBits)!) + return oldPtr.takeRetainedValue() + } + + /// Atomically loads and returns the value of this object. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - warning: The implementation of `exchange` contains a _Compare and Exchange loop_, ie. it may busy wait with + /// 100% CPU load. + /// + /// - Returns: The value of this object + public func load() -> T { + // step 1: We need to gain ownership of the value by successfully swapping 0 (marker value) in. + var ptrBits: UInt = 0 + while true { + let speculativeVal = self.storage.load() + guard speculativeVal != 0 else { + sys_sched_yield() + continue + } + if self.storage.compareAndExchange(expected: speculativeVal, desired: 0) { + ptrBits = speculativeVal + break + } + } + + // step 2: We now consumed a +1'd version of val, so we have all the time in the world to retain it. + let ptr = Unmanaged.fromOpaque(UnsafeRawPointer(bitPattern: ptrBits)!) + let value = ptr.takeUnretainedValue() + + // step 3: Now, let's exchange it back into the store + let casWorked = self.storage.compareAndExchange(expected: 0, desired: ptrBits) + precondition(casWorked) // this _has_ to work because `0` means we own it exclusively. + return value + } + + /// Atomically replaces the value of this object with `value`. + /// + /// This implementation uses a *relaxed* memory ordering. This guarantees nothing + /// more than that this operation is atomic: there is no guarantee that any other + /// event will be ordered before or after this one. + /// + /// - warning: The implementation of `exchange` contains a _Compare and Exchange loop_, ie. it may busy wait with + /// 100% CPU load. + /// + /// - Parameter value: The new value to set the object to. + public func store(_ value: T) -> Void { + _ = self.exchange(with: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/lock.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/lock.swift new file mode 100644 index 00000000..e75cd2a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOConcurrencyHelpers/Sources/NIOConcurrencyHelpers/lock.swift @@ -0,0 +1,288 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin +#elseif os(Windows) +import ucrt +import WinSDK +#else +import Glibc +#endif + +/// A threading lock based on `libpthread` instead of `libdispatch`. +/// +/// This object provides a lock on top of a single `pthread_mutex_t`. This kind +/// of lock is safe to use with `libpthread`-based threading models, such as the +/// one used by NIO. On Windows, the lock is based on the substantially similar +/// `SRWLOCK` type. +public final class Lock { +#if os(Windows) + fileprivate let mutex: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) +#else + fileprivate let mutex: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) +#endif + + /// Create a new lock. + public init() { +#if os(Windows) + InitializeSRWLock(self.mutex) +#else + var attr = pthread_mutexattr_t() + pthread_mutexattr_init(&attr) + debugOnly { + pthread_mutexattr_settype(&attr, .init(PTHREAD_MUTEX_ERRORCHECK)) + } + + let err = pthread_mutex_init(self.mutex, &attr) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") +#endif + } + + deinit { +#if os(Windows) + // SRWLOCK does not need to be free'd +#else + let err = pthread_mutex_destroy(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") +#endif + mutex.deallocate() + } + + /// Acquire the lock. + /// + /// Whenever possible, consider using `withLock` instead of this method and + /// `unlock`, to simplify lock handling. + public func lock() { +#if os(Windows) + AcquireSRWLockExclusive(self.mutex) +#else + let err = pthread_mutex_lock(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") +#endif + } + + /// Release the lock. + /// + /// Whenever possible, consider using `withLock` instead of this method and + /// `lock`, to simplify lock handling. + public func unlock() { +#if os(Windows) + ReleaseSRWLockExclusive(self.mutex) +#else + let err = pthread_mutex_unlock(self.mutex) + precondition(err == 0, "\(#function) failed in pthread_mutex with error \(err)") +#endif + } +} + +extension Lock { + /// Acquire the lock for the duration of the given block. + /// + /// This convenience method should be preferred to `lock` and `unlock` in + /// most situations, as it ensures that the lock will be released regardless + /// of how `body` exits. + /// + /// - Parameter body: The block to execute while holding the lock. + /// - Returns: The value returned by the block. + @inlinable + public func withLock(_ body: () throws -> T) rethrows -> T { + self.lock() + defer { + self.unlock() + } + return try body() + } + + // specialise Void return (for performance) + @inlinable + public func withLockVoid(_ body: () throws -> Void) rethrows -> Void { + try self.withLock(body) + } +} + +/// A `Lock` with a built-in state variable. +/// +/// This class provides a convenience addition to `Lock`: it provides the ability to wait +/// until the state variable is set to a specific value to acquire the lock. +public final class ConditionLock { + private var _value: T + private let mutex: Lock +#if os(Windows) + private let cond: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) +#else + private let cond: UnsafeMutablePointer = + UnsafeMutablePointer.allocate(capacity: 1) +#endif + + /// Create the lock, and initialize the state variable to `value`. + /// + /// - Parameter value: The initial value to give the state variable. + public init(value: T) { + self._value = value + self.mutex = Lock() +#if os(Windows) + InitializeConditionVariable(self.cond) +#else + let err = pthread_cond_init(self.cond, nil) + precondition(err == 0, "\(#function) failed in pthread_cond with error \(err)") +#endif + } + + deinit { +#if os(Windows) + // condition variables do not need to be explicitly destroyed +#else + let err = pthread_cond_destroy(self.cond) + precondition(err == 0, "\(#function) failed in pthread_cond with error \(err)") +#endif + self.cond.deallocate() + } + + /// Acquire the lock, regardless of the value of the state variable. + public func lock() { + self.mutex.lock() + } + + /// Release the lock, regardless of the value of the state variable. + public func unlock() { + self.mutex.unlock() + } + + /// The value of the state variable. + /// + /// Obtaining the value of the state variable requires acquiring the lock. + /// This means that it is not safe to access this property while holding the + /// lock: it is only safe to use it when not holding it. + public var value: T { + self.lock() + defer { + self.unlock() + } + return self._value + } + + /// Acquire the lock when the state variable is equal to `wantedValue`. + /// + /// - Parameter wantedValue: The value to wait for the state variable + /// to have before acquiring the lock. + public func lock(whenValue wantedValue: T) { + self.lock() + while true { + if self._value == wantedValue { + break + } +#if os(Windows) + let result = SleepConditionVariableSRW(self.cond, self.mutex.mutex, INFINITE, 0) + precondition(result, "\(#function) failed in SleepConditionVariableSRW with error \(GetLastError())") +#else + let err = pthread_cond_wait(self.cond, self.mutex.mutex) + precondition(err == 0, "\(#function) failed in pthread_cond with error \(err)") +#endif + } + } + + /// Acquire the lock when the state variable is equal to `wantedValue`, + /// waiting no more than `timeoutSeconds` seconds. + /// + /// - Parameter wantedValue: The value to wait for the state variable + /// to have before acquiring the lock. + /// - Parameter timeoutSeconds: The number of seconds to wait to acquire + /// the lock before giving up. + /// - Returns: `true` if the lock was acquired, `false` if the wait timed out. + public func lock(whenValue wantedValue: T, timeoutSeconds: Double) -> Bool { + precondition(timeoutSeconds >= 0) + +#if os(Windows) + var dwMilliseconds: DWORD = DWORD(timeoutSeconds * 1000) + + self.lock() + while true { + if self._value == wantedValue { + return true + } + + let dwWaitStart = timeGetTime() + if !SleepConditionVariableSRW(self.cond, self.mutex.mutex, + dwMilliseconds, 0) { + let dwError = GetLastError() + if (dwError == ERROR_TIMEOUT) { + self.unlock() + return false + } + fatalError("SleepConditionVariableSRW: \(dwError)") + } + + // NOTE: this may be a spurious wakeup, adjust the timeout accordingly + dwMilliseconds = dwMilliseconds - (timeGetTime() - dwWaitStart) + } +#else + let nsecPerSec: Int64 = 1000000000 + self.lock() + /* the timeout as a (seconds, nano seconds) pair */ + let timeoutNS = Int64(timeoutSeconds * Double(nsecPerSec)) + + var curTime = timeval() + gettimeofday(&curTime, nil) + + let allNSecs: Int64 = timeoutNS + Int64(curTime.tv_usec) * 1000 + var timeoutAbs = timespec(tv_sec: curTime.tv_sec + Int((allNSecs / nsecPerSec)), + tv_nsec: Int(allNSecs % nsecPerSec)) + assert(timeoutAbs.tv_nsec >= 0 && timeoutAbs.tv_nsec < Int(nsecPerSec)) + assert(timeoutAbs.tv_sec >= curTime.tv_sec) + while true { + if self._value == wantedValue { + return true + } + switch pthread_cond_timedwait(self.cond, self.mutex.mutex, &timeoutAbs) { + case 0: + continue + case ETIMEDOUT: + self.unlock() + return false + case let e: + fatalError("caught error \(e) when calling pthread_cond_timedwait") + } + } +#endif + } + + /// Release the lock, setting the state variable to `newValue`. + /// + /// - Parameter newValue: The value to give to the state variable when we + /// release the lock. + public func unlock(withValue newValue: T) { + self._value = newValue + self.unlock() +#if os(Windows) + WakeAllConditionVariable(self.cond) +#else + let err = pthread_cond_broadcast(self.cond) + precondition(err == 0, "\(#function) failed in pthread_cond with error \(err)") +#endif + } +} + +/// A utility function that runs the body code only in debug builds, without +/// emitting compiler warnings. +/// +/// This is currently the only way to do this in Swift: see +/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion. +@inlinable +internal func debugOnly(_ body: () -> Void) { + assert({ body(); return true }()) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AddressedEnvelope.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AddressedEnvelope.swift new file mode 100644 index 00000000..2f6f86b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AddressedEnvelope.swift @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A data structure for processing addressed datagrams, such as those used by UDP. +/// +/// The AddressedEnvelope is used extensively on `DatagramChannel`s in order to keep track +/// of source or destination address metadata: that is, where some data came from or where +/// it is going. +public struct AddressedEnvelope { + public var remoteAddress: SocketAddress + public var data: DataType + /// Any metadata associated with this `AddressedEnvelope` + public var metadata: Metadata? = nil + + public init(remoteAddress: SocketAddress, data: DataType) { + self.remoteAddress = remoteAddress + self.data = data + } + + public init(remoteAddress: SocketAddress, data: DataType, metadata: Metadata?) { + self.remoteAddress = remoteAddress + self.data = data + self.metadata = metadata + } + + /// Any metadata associated with an `AddressedEnvelope` + public struct Metadata: Hashable { + /// Details of any congestion state. + public var ecnState: NIOExplicitCongestionNotificationState + public var packetInfo: NIOPacketInfo? + + public init(ecnState: NIOExplicitCongestionNotificationState) { + self.ecnState = ecnState + self.packetInfo = nil + } + + public init(ecnState: NIOExplicitCongestionNotificationState, packetInfo: NIOPacketInfo?) { + self.ecnState = ecnState + self.packetInfo = packetInfo + } + } +} + +extension AddressedEnvelope: CustomStringConvertible { + public var description: String { + return "AddressedEnvelope { remoteAddress: \(self.remoteAddress), data: \(self.data) }" + } +} + +extension AddressedEnvelope: Equatable where DataType: Equatable {} + +extension AddressedEnvelope: Hashable where DataType: Hashable {} + +/// Possible Explicit Congestion Notification States +public enum NIOExplicitCongestionNotificationState: Hashable { + /// Non-ECN Capable Transport. + case transportNotCapable + /// ECN Capable Transport (flag 0). + case transportCapableFlag0 + /// ECN Capable Transport (flag 1). + case transportCapableFlag1 + /// Congestion Experienced. + case congestionExperienced +} + +public struct NIOPacketInfo: Hashable { + public var destinationAddress: SocketAddress + public var interfaceIndex: Int + + public init(destinationAddress: SocketAddress, interfaceIndex: Int) { + self.destinationAddress = destinationAddress + self.interfaceIndex = interfaceIndex + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport+OldXcodes.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport+OldXcodes.swift new file mode 100644 index 00000000..6535e877 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport+OldXcodes.swift @@ -0,0 +1,215 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if compiler(>=5.5) && !compiler(>=5.5.2) && canImport(_Concurrency) + +extension EventLoopFuture { + /// Get the value/error from an `EventLoopFuture` in an `async` context. + /// + /// This function can be used to bridge an `EventLoopFuture` into the `async` world. Ie. if you're in an `async` + /// function and want to get the result of this future. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func get() async throws -> Value { + return try await withUnsafeThrowingContinuation { cont in + self.whenComplete { result in + switch result { + case .success(let value): + cont.resume(returning: value) + case .failure(let error): + cont.resume(throwing: error) + } + } + } + } +} + +extension EventLoopGroup { + /// Shuts down the event loop gracefully. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func shutdownGracefully() async throws { + return try await withCheckedThrowingContinuation { cont in + self.shutdownGracefully { error in + if let error = error { + cont.resume(throwing: error) + } else { + cont.resume() + } + } + } + } +} + +extension EventLoopPromise { + /// Complete a future with the result (or error) of the `async` function `body`. + /// + /// This function can be used to bridge the `async` world into an `EventLoopPromise`. + /// + /// - parameters: + /// - body: The `async` function to run. + /// - returns: A `Task` which was created to `await` the `body`. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @discardableResult + @inlinable + public func completeWithTask(_ body: @escaping @Sendable () async throws -> Value) -> Task { + Task { + do { + let value = try await body() + self.succeed(value) + } catch { + self.fail(error) + } + } + } +} + +extension Channel { + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - promise: the `EventLoopPromise` that will be notified once the `write` operation completes, + /// or `nil` if not interested in the outcome of the operation. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func writeAndFlush(_ any: T) async throws { + try await self.writeAndFlush(any).get() + } + + /// Set `option` to `value` on this `Channel`. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func setOption(_ option: Option, value: Option.Value) async throws { + try await self.setOption(option, value: value).get() + } + + /// Get the value of `option` for this `Channel`. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func getOption(_ option: Option) async throws -> Option.Value { + return try await self.getOption(option).get() + } +} + +extension ChannelOutboundInvoker { + /// Register on an `EventLoop` and so have all its IO handled. + /// + /// - returns: the future which will be notified once the operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func register(file: StaticString = #file, line: UInt = #line) async throws { + try await self.register(file: file, line: line).get() + } + + /// Bind to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should bind the `Channel`. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func bind(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) async throws { + try await self.bind(to: address, file: file, line: line).get() + } + + /// Connect to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should connect the `Channel`. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func connect(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) async throws { + try await self.connect(to: address, file: file, line: line).get() + } + + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - returns: the future which will be notified once the `write` operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func writeAndFlush(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) async throws { + try await self.writeAndFlush(data, file: file, line: line).get() + } + + /// Close the `Channel` and so the connection if one exists. + /// + /// - parameters: + /// - mode: the `CloseMode` that is used + /// - returns: the future which will be notified once the operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func close(mode: CloseMode = .all, file: StaticString = #file, line: UInt = #line) async throws { + try await self.close(mode: mode, file: file, line: line).get() + } + + /// Trigger a custom user outbound event which will flow through the `ChannelPipeline`. + /// + /// - parameters: + /// - event: the event itself. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func triggerUserOutboundEvent(_ event: Any, file: StaticString = #file, line: UInt = #line) async throws { + try await self.triggerUserOutboundEvent(event, file: file, line: line).get() + } +} + +extension ChannelPipeline { + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func addHandler(_ handler: ChannelHandler, + name: String? = nil, + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandler(handler, name: name, position: position).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func removeHandler(_ handler: RemovableChannelHandler) async throws { + try await self.removeHandler(handler).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func removeHandler(name: String) async throws { + try await self.removeHandler(name: name).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func removeHandler(context: ChannelHandlerContext) async throws { + try await self.removeHandler(context: context).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func context(handler: ChannelHandler) async throws -> ChannelHandlerContext { + return try await self.context(handler: handler).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func context(name: String) async throws -> ChannelHandlerContext { + return try await self.context(name: name).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + @inlinable + public func context(handlerType: Handler.Type) async throws -> ChannelHandlerContext { + return try await self.context(handlerType: handlerType).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func addHandlers(_ handlers: [ChannelHandler], + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandlers(handlers, position: position).get() + } + + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) + public func addHandlers(_ handlers: ChannelHandler..., + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandlers(handlers, position: position) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport.swift new file mode 100644 index 00000000..36c8dfa3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/AsyncAwaitSupport.swift @@ -0,0 +1,339 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021-2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if swift(>=5.5) && canImport(_Concurrency) +public typealias NIOSendable = Swift.Sendable +#else +public typealias NIOSendable = Any +#endif + +#if compiler(>=5.5.2) && canImport(_Concurrency) + +extension EventLoopFuture { + /// Get the value/error from an `EventLoopFuture` in an `async` context. + /// + /// This function can be used to bridge an `EventLoopFuture` into the `async` world. Ie. if you're in an `async` + /// function and want to get the result of this future. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func get() async throws -> Value { + return try await withUnsafeThrowingContinuation { cont in + self.whenComplete { result in + switch result { + case .success(let value): + cont.resume(returning: value) + case .failure(let error): + cont.resume(throwing: error) + } + } + } + } +} + +extension EventLoopGroup { + /// Shuts down the event loop gracefully. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func shutdownGracefully() async throws { + return try await withCheckedThrowingContinuation { cont in + self.shutdownGracefully { error in + if let error = error { + cont.resume(throwing: error) + } else { + cont.resume() + } + } + } + } +} + +extension EventLoopPromise { + /// Complete a future with the result (or error) of the `async` function `body`. + /// + /// This function can be used to bridge the `async` world into an `EventLoopPromise`. + /// + /// - parameters: + /// - body: The `async` function to run. + /// - returns: A `Task` which was created to `await` the `body`. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @discardableResult + @inlinable + public func completeWithTask(_ body: @escaping @Sendable () async throws -> Value) -> Task { + Task { + do { + let value = try await body() + self.succeed(value) + } catch { + self.fail(error) + } + } + } +} + +extension Channel { + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - promise: the `EventLoopPromise` that will be notified once the `write` operation completes, + /// or `nil` if not interested in the outcome of the operation. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func writeAndFlush(_ any: T) async throws { + try await self.writeAndFlush(any).get() + } + + /// Set `option` to `value` on this `Channel`. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func setOption(_ option: Option, value: Option.Value) async throws { + try await self.setOption(option, value: value).get() + } + + /// Get the value of `option` for this `Channel`. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func getOption(_ option: Option) async throws -> Option.Value { + return try await self.getOption(option).get() + } +} + +extension ChannelOutboundInvoker { + /// Register on an `EventLoop` and so have all its IO handled. + /// + /// - returns: the future which will be notified once the operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func register(file: StaticString = #file, line: UInt = #line) async throws { + try await self.register(file: file, line: line).get() + } + + /// Bind to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should bind the `Channel`. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func bind(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) async throws { + try await self.bind(to: address, file: file, line: line).get() + } + + /// Connect to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should connect the `Channel`. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func connect(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) async throws { + try await self.connect(to: address, file: file, line: line).get() + } + + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - returns: the future which will be notified once the `write` operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func writeAndFlush(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) async throws { + try await self.writeAndFlush(data, file: file, line: line).get() + } + + /// Close the `Channel` and so the connection if one exists. + /// + /// - parameters: + /// - mode: the `CloseMode` that is used + /// - returns: the future which will be notified once the operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func close(mode: CloseMode = .all, file: StaticString = #file, line: UInt = #line) async throws { + try await self.close(mode: mode, file: file, line: line).get() + } + + /// Trigger a custom user outbound event which will flow through the `ChannelPipeline`. + /// + /// - parameters: + /// - event: the event itself. + /// - returns: the future which will be notified once the operation completes. + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func triggerUserOutboundEvent(_ event: Any, file: StaticString = #file, line: UInt = #line) async throws { + try await self.triggerUserOutboundEvent(event, file: file, line: line).get() + } +} + +extension ChannelPipeline { + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func addHandler(_ handler: ChannelHandler, + name: String? = nil, + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandler(handler, name: name, position: position).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func removeHandler(_ handler: RemovableChannelHandler) async throws { + try await self.removeHandler(handler).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func removeHandler(name: String) async throws { + try await self.removeHandler(name: name).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func removeHandler(context: ChannelHandlerContext) async throws { + try await self.removeHandler(context: context).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func context(handler: ChannelHandler) async throws -> ChannelHandlerContext { + return try await self.context(handler: handler).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func context(name: String) async throws -> ChannelHandlerContext { + return try await self.context(name: name).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + @inlinable + public func context(handlerType: Handler.Type) async throws -> ChannelHandlerContext { + return try await self.context(handlerType: handlerType).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func addHandlers(_ handlers: [ChannelHandler], + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandlers(handlers, position: position).get() + } + + @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) + public func addHandlers(_ handlers: ChannelHandler..., + position: ChannelPipeline.Position = .last) async throws { + try await self.addHandlers(handlers, position: position) + } +} + +public struct NIOTooManyBytesError: Error { + public init() {} + } + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncSequence where Element: RandomAccessCollection, Element.Element == UInt8 { + /// Accumulates an ``Swift/AsyncSequence`` of ``Swift/RandomAccessCollection``s into a single `accumulationBuffer`. + /// - Parameters: + /// - accumulationBuffer: buffer to write all the elements of `self` into + /// - maxBytes: The maximum number of bytes this method is allowed to write into `accumulationBuffer` + /// - Throws: `NIOTooManyBytesError` if the the sequence contains more than `maxBytes`. + /// Note that previous elements of `self` might already be write to `accumulationBuffer`. + @inlinable + public func collect( + upTo maxBytes: Int, + into accumulationBuffer: inout ByteBuffer + ) async throws { + precondition(maxBytes >= 0, "`maxBytes` must be greater than or equal to zero") + var bytesRead = 0 + for try await fragment in self { + bytesRead += fragment.count + guard bytesRead <= maxBytes else { + throw NIOTooManyBytesError() + } + accumulationBuffer.writeBytes(fragment) + } + } + + /// Accumulates an ``Swift/AsyncSequence`` of ``Swift/RandomAccessCollection``s into a single ``NIO/ByteBuffer``. + /// - Parameters: + /// - maxBytes: The maximum number of bytes this method is allowed to accumulate + /// - allocator: Allocator used for allocating the result `ByteBuffer` + /// - Throws: `NIOTooManyBytesError` if the the sequence contains more than `maxBytes`. + @inlinable + public func collect( + upTo maxBytes: Int, + using allocator: ByteBufferAllocator + ) async throws -> ByteBuffer { + precondition(maxBytes >= 0, "`maxBytes` must be greater than or equal to zero") + var accumulationBuffer = allocator.buffer(capacity: Swift.min(maxBytes, 1024)) + try await self.collect(upTo: maxBytes, into: &accumulationBuffer) + return accumulationBuffer + } +} + +// MARK: optimised methods for ByteBuffer + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncSequence where Element == ByteBuffer { + /// Accumulates an ``Swift/AsyncSequence`` of ``ByteBuffer``s into a single `accumulationBuffer`. + /// - Parameters: + /// - accumulationBuffer: buffer to write all the elements of `self` into + /// - maxBytes: The maximum number of bytes this method is allowed to write into `accumulationBuffer` + /// - Throws: ``NIOTooManyBytesError`` if the the sequence contains more than `maxBytes`. + /// Note that previous elements of `self` might be already write to `accumulationBuffer`. + @inlinable + public func collect( + upTo maxBytes: Int, + into accumulationBuffer: inout ByteBuffer + ) async throws { + precondition(maxBytes >= 0, "`maxBytes` must be greater than or equal to zero") + var bytesRead = 0 + for try await fragment in self { + bytesRead += fragment.readableBytes + guard bytesRead <= maxBytes else { + throw NIOTooManyBytesError() + } + accumulationBuffer.writeImmutableBuffer(fragment) + } + } + + /// Accumulates an ``Swift/AsyncSequence`` of ``ByteBuffer``s into a single ``ByteBuffer``. + /// - Parameters: + /// - maxBytes: The maximum number of bytes this method is allowed to accumulate + /// - Throws: `NIOTooManyBytesError` if the the sequence contains more than `maxBytes`. + @inlinable + public func collect( + upTo maxBytes: Int + ) async throws -> ByteBuffer { + precondition(maxBytes >= 0, "`maxBytes` must be greater than or equal to zero") + // we use the first `ByteBuffer` to accumulate all subsequent `ByteBuffer`s into. + // this has also the benefit of not copying at all, + // if the async sequence contains only one element. + var iterator = self.makeAsyncIterator() + guard var head = try await iterator.next() else { + return ByteBuffer() + } + guard head.readableBytes <= maxBytes else { + throw NIOTooManyBytesError() + } + + let tail = AsyncSequenceFromIterator(iterator) + // it is guaranteed that + // `maxBytes >= 0 && head.readableBytes >= 0 && head.readableBytes <= maxBytes` + // This implies that `maxBytes - head.readableBytes >= 0` + // we can therefore use wrapping subtraction + try await tail.collect(upTo: maxBytes &- head.readableBytes, into: &head) + return head + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +struct AsyncSequenceFromIterator: AsyncSequence { + @usableFromInline typealias Element = AsyncIterator.Element + + @usableFromInline var iterator: AsyncIterator + + @inlinable init(_ iterator: AsyncIterator) { + self.iterator = iterator + } + + @inlinable func makeAsyncIterator() -> AsyncIterator { + self.iterator + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/BSDSocketAPI.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/BSDSocketAPI.swift new file mode 100644 index 00000000..60b3ee69 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/BSDSocketAPI.swift @@ -0,0 +1,385 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) +import ucrt + +import let WinSDK.IPPROTO_IP +import let WinSDK.IPPROTO_IPV6 +import let WinSDK.IPPROTO_TCP + +import let WinSDK.IP_ADD_MEMBERSHIP +import let WinSDK.IP_DROP_MEMBERSHIP +import let WinSDK.IP_MULTICAST_IF +import let WinSDK.IP_MULTICAST_LOOP +import let WinSDK.IP_MULTICAST_TTL +import let WinSDK.IPV6_JOIN_GROUP +import let WinSDK.IPV6_LEAVE_GROUP +import let WinSDK.IPV6_MULTICAST_HOPS +import let WinSDK.IPV6_MULTICAST_IF +import let WinSDK.IPV6_MULTICAST_LOOP +import let WinSDK.IPV6_V6ONLY + +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 +import let WinSDK.AF_UNIX + +import let WinSDK.PF_INET +import let WinSDK.PF_INET6 +import let WinSDK.PF_UNIX + +import let WinSDK.SO_ERROR +import let WinSDK.SO_KEEPALIVE +import let WinSDK.SO_LINGER +import let WinSDK.SO_RCVBUF +import let WinSDK.SO_RCVTIMEO +import let WinSDK.SO_REUSEADDR + +import let WinSDK.SOL_SOCKET + +import let WinSDK.TCP_NODELAY + +import struct WinSDK.SOCKET + +import func WinSDK.inet_ntop +import func WinSDK.inet_pton +#elseif os(Linux) || os(Android) +import Glibc +import CNIOLinux + +private let sysInet_ntop: @convention(c) (CInt, UnsafeRawPointer?, UnsafeMutablePointer?, socklen_t) -> UnsafePointer? = inet_ntop +private let sysInet_pton: @convention(c) (CInt, UnsafePointer?, UnsafeMutableRawPointer?) -> CInt = inet_pton +#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin + +private let sysInet_ntop: @convention(c) (CInt, UnsafeRawPointer?, UnsafeMutablePointer?, socklen_t) -> UnsafePointer? = inet_ntop +private let sysInet_pton: @convention(c) (CInt, UnsafePointer?, UnsafeMutableRawPointer?) -> CInt = inet_pton +#endif + +#if os(Android) +let IFF_BROADCAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_BROADCAST.rawValue) +let IFF_POINTOPOINT: CUnsignedInt = numericCast(SwiftGlibc.IFF_POINTOPOINT.rawValue) +let IFF_MULTICAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_MULTICAST.rawValue) +#if arch(arm) +let SO_RCVTIMEO = SO_RCVTIMEO_OLD +let SO_TIMESTAMP = SO_TIMESTAMP_OLD +#endif +#elseif os(Linux) +// Work around SO_TIMESTAMP/SO_RCVTIMEO being awkwardly defined in glibc. +let SO_TIMESTAMP = CNIOLinux_SO_TIMESTAMP +let SO_RCVTIMEO = CNIOLinux_SO_RCVTIMEO +#endif + +public enum NIOBSDSocket { +#if os(Windows) + public typealias Handle = SOCKET +#else + public typealias Handle = CInt +#endif +} + +extension NIOBSDSocket { + /// Specifies the addressing scheme that the socket can use. + public struct AddressFamily: RawRepresentable { + public typealias RawValue = CInt + public var rawValue: RawValue + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + } +} + +extension NIOBSDSocket.AddressFamily: Equatable { +} + +extension NIOBSDSocket.AddressFamily: Hashable { +} + +extension NIOBSDSocket { + /// Specifies the type of protocol that the socket can use. + public struct ProtocolFamily: RawRepresentable { + public typealias RawValue = CInt + public var rawValue: RawValue + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + } +} + +extension NIOBSDSocket.ProtocolFamily: Equatable { +} + +extension NIOBSDSocket.ProtocolFamily: Hashable { +} + +extension NIOBSDSocket { + /// Defines socket option levels. + public struct OptionLevel: RawRepresentable { + public typealias RawValue = CInt + public var rawValue: RawValue + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + } +} + +extension NIOBSDSocket.OptionLevel: Equatable { +} + +extension NIOBSDSocket.OptionLevel: Hashable { +} + +extension NIOBSDSocket { + /// Defines configuration option names. + public struct Option: RawRepresentable { + public typealias RawValue = CInt + public var rawValue: RawValue + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + } +} + +extension NIOBSDSocket.Option: Equatable { +} + +extension NIOBSDSocket.Option: Hashable { +} + +// Address Family +extension NIOBSDSocket.AddressFamily { + /// Address for IP version 4. + public static let inet: NIOBSDSocket.AddressFamily = + NIOBSDSocket.AddressFamily(rawValue: AF_INET) + + /// Address for IP version 6. + public static let inet6: NIOBSDSocket.AddressFamily = + NIOBSDSocket.AddressFamily(rawValue: AF_INET6) + + /// Unix local to host address. + public static let unix: NIOBSDSocket.AddressFamily = + NIOBSDSocket.AddressFamily(rawValue: AF_UNIX) +} + +// Protocol Family +extension NIOBSDSocket.ProtocolFamily { + /// IP network 4 protocol. + public static let inet: NIOBSDSocket.ProtocolFamily = + NIOBSDSocket.ProtocolFamily(rawValue: PF_INET) + + /// IP network 6 protocol. + public static let inet6: NIOBSDSocket.ProtocolFamily = + NIOBSDSocket.ProtocolFamily(rawValue: PF_INET6) + + /// UNIX local to the host. + public static let unix: NIOBSDSocket.ProtocolFamily = + NIOBSDSocket.ProtocolFamily(rawValue: PF_UNIX) +} + +#if !os(Windows) + extension NIOBSDSocket.ProtocolFamily { + /// UNIX local to the host, alias for `PF_UNIX` (`.unix`) + public static let local: NIOBSDSocket.ProtocolFamily = + NIOBSDSocket.ProtocolFamily(rawValue: PF_LOCAL) + } +#endif + + +// Option Level +extension NIOBSDSocket.OptionLevel { + /// Socket options that apply only to IP sockets. + #if os(Linux) || os(Android) + public static let ip: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: CInt(IPPROTO_IP)) + #else + public static let ip: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: IPPROTO_IP) + #endif + + /// Socket options that apply only to IPv6 sockets. + #if os(Linux) || os(Android) + public static let ipv6: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: CInt(IPPROTO_IPV6)) + #elseif os(Windows) + public static let ipv6: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: IPPROTO_IPV6.rawValue) + #else + public static let ipv6: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: IPPROTO_IPV6) + #endif + + /// Socket options that apply only to TCP sockets. + #if os(Linux) || os(Android) + public static let tcp: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: CInt(IPPROTO_TCP)) + #elseif os(Windows) + public static let tcp: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: IPPROTO_TCP.rawValue) + #else + public static let tcp: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: IPPROTO_TCP) + #endif + + /// Socket options that apply to all sockets. + public static let socket: NIOBSDSocket.OptionLevel = + NIOBSDSocket.OptionLevel(rawValue: SOL_SOCKET) +} + +// IPv4 Options +extension NIOBSDSocket.Option { + /// Add a multicast group membership. + public static let ip_add_membership: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_ADD_MEMBERSHIP) + + /// Drop a multicast group membership. + public static let ip_drop_membership: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_DROP_MEMBERSHIP) + + /// Set the interface for outgoing multicast packets. + public static let ip_multicast_if: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_MULTICAST_IF) + + /// Control multicast loopback. + public static let ip_multicast_loop: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_MULTICAST_LOOP) + + /// Control multicast time-to-live. + public static let ip_multicast_ttl: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_MULTICAST_TTL) +} + +// IPv6 Options +extension NIOBSDSocket.Option { + /// Add an IPv6 group membership. + public static let ipv6_join_group: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_JOIN_GROUP) + + /// Drop an IPv6 group membership. + public static let ipv6_leave_group: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_LEAVE_GROUP) + + /// Specify the maximum number of router hops for an IPv6 packet. + public static let ipv6_multicast_hops: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_MULTICAST_HOPS) + + /// Set the interface for outgoing multicast packets. + public static let ipv6_multicast_if: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_MULTICAST_IF) + + /// Control multicast loopback. + public static let ipv6_multicast_loop: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_MULTICAST_LOOP) + + /// Indicates if a socket created for the `AF_INET6` address family is + /// restricted to IPv6 only. + public static let ipv6_v6only: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_V6ONLY) +} + +// TCP Options +extension NIOBSDSocket.Option { + /// Disables the Nagle algorithm for send coalescing. + public static let tcp_nodelay: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: TCP_NODELAY) +} + +#if os(Linux) || os(FreeBSD) || os(Android) +extension NIOBSDSocket.Option { + /// Get information about the TCP connection. + public static let tcp_info: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: TCP_INFO) +} +#endif + +#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) +extension NIOBSDSocket.Option { + /// Get information about the TCP connection. + public static let tcp_connection_info: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: TCP_CONNECTION_INFO) +} +#endif + +// Socket Options +extension NIOBSDSocket.Option { + /// Get the error status and clear. + public static let so_error: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_ERROR) + + /// Use keep-alives. + public static let so_keepalive: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_KEEPALIVE) + + /// Linger on close if unsent data is present. + public static let so_linger: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_LINGER) + + /// Specifies the total per-socket buffer space reserved for receives. + public static let so_rcvbuf: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_RCVBUF) + + /// Specifies the receive timeout. + public static let so_rcvtimeo: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_RCVTIMEO) + + /// Allows the socket to be bound to an address that is already in use. + public static let so_reuseaddr: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_REUSEADDR) +} + +#if !os(Windows) +extension NIOBSDSocket.Option { + /// Indicate when to generate timestamps. + public static let so_timestamp: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: SO_TIMESTAMP) +} +#endif + +extension NIOBSDSocket { + // Sadly this was defined on BSDSocket, and we need it for SocketAddress. + @inline(never) + internal static func inet_pton(addressFamily: NIOBSDSocket.AddressFamily, addressDescription: UnsafePointer, address: UnsafeMutableRawPointer) throws { + #if os(Windows) + // TODO(compnerd) use `InetPtonW` to ensure that we handle unicode properly + switch WinSDK.inet_pton(family.rawValue, addressDescription, address) { + case 0: throw IOError(errnoCode: EINVAL, reason: "inet_pton") + case 1: return + default: throw IOError(winsock: WSAGetLastError(), reason: "inet_pton") + } + #else + switch sysInet_pton(CInt(addressFamily.rawValue), addressDescription, address) { + case 0: throw IOError(errnoCode: EINVAL, reason: #function) + case 1: return + default: throw IOError(errnoCode: errno, reason: #function) + } + #endif + } + + @discardableResult + @inline(never) + internal static func inet_ntop(addressFamily: NIOBSDSocket.AddressFamily, addressBytes: UnsafeRawPointer, addressDescription: UnsafeMutablePointer, addressDescriptionLength: socklen_t) throws -> UnsafePointer { + #if os(Windows) + // TODO(compnerd) use `InetNtopW` to ensure that we handle unicode properly + guard let result = WinSDK.inet_ntop(family.rawValue, addressBytes, addressDescription, + Int(addressDescriptionLength)) else { + throw IOError(windows: GetLastError(), reason: "inet_ntop") + } + return result + #else + switch sysInet_ntop(CInt(addressFamily.rawValue), addressBytes, addressDescription, addressDescriptionLength) { + case .none: throw IOError(errnoCode: errno, reason: #function) + case .some(let ptr): return ptr + } + #endif + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-aux.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-aux.swift new file mode 100644 index 00000000..be56d1b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-aux.swift @@ -0,0 +1,823 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch + +extension ByteBuffer { + + // MARK: Bytes ([UInt8]) APIs + + /// Get `length` bytes starting at `index` and return the result as `[UInt8]`. This will not change the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index of the bytes of interest into the `ByteBuffer`. + /// - length: The number of bytes of interest. + /// - returns: A `[UInt8]` value containing the bytes of interest or `nil` if the bytes `ByteBuffer` are not readable. + @inlinable + public func getBytes(at index: Int, length: Int) -> [UInt8]? { + guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + return nil + } + + return self.withUnsafeReadableBytes { ptr in + // this is not technically correct because we shouldn't just bind + // the memory to `UInt8` but it's not a real issue either and we + // need to work around https://bugs.swift.org/browse/SR-9604 + Array(UnsafeRawBufferPointer(fastRebase: ptr[range]).bindMemory(to: UInt8.self)) + } + } + + /// Read `length` bytes off this `ByteBuffer`, move the reader index forward by `length` bytes and return the result + /// as `[UInt8]`. + /// + /// - parameters: + /// - length: The number of bytes to be read from this `ByteBuffer`. + /// - returns: A `[UInt8]` value containing `length` bytes or `nil` if there aren't at least `length` bytes readable. + @inlinable + public mutating func readBytes(length: Int) -> [UInt8]? { + guard let result = self.getBytes(at: self.readerIndex, length: length) else { + return nil + } + self._moveReaderIndex(forwardBy: length) + return result + } + + // MARK: StaticString APIs + + /// Write the static `string` into this `ByteBuffer` using UTF-8 encoding, moving the writer index forward appropriately. + /// + /// - parameters: + /// - string: The string to write. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeStaticString(_ string: StaticString) -> Int { + let written = self.setStaticString(string, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Write the static `string` into this `ByteBuffer` at `index` using UTF-8 encoding, moving the writer index forward appropriately. + /// + /// - parameters: + /// - string: The string to write. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written. + @inlinable + public mutating func setStaticString(_ string: StaticString, at index: Int) -> Int { + // please do not replace the code below with code that uses `string.withUTF8Buffer { ... }` (see SR-7541) + return self.setBytes(UnsafeRawBufferPointer(start: string.utf8Start, + count: string.utf8CodeUnitCount), at: index) + } + + // MARK: String APIs + /// Write `string` into this `ByteBuffer` using UTF-8 encoding, moving the writer index forward appropriately. + /// + /// - parameters: + /// - string: The string to write. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeString(_ string: String) -> Int { + let written = self.setString(string, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Write `string` into this `ByteBuffer` null terminated using UTF-8 encoding, moving the writer index forward appropriately. + /// + /// - parameters: + /// - string: The string to write. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeNullTerminatedString(_ string: String) -> Int { + let written = self.setNullTerminatedString(string, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + @inline(never) + @inlinable + mutating func _setStringSlowpath(_ string: String, at index: Int) -> Int { + // slow path, let's try to force the string to be native + if let written = (string + "").utf8.withContiguousStorageIfAvailable({ utf8Bytes in + self.setBytes(utf8Bytes, at: index) + }) { + return written + } else { + return self.setBytes(string.utf8, at: index) + } + } + + /// Write `string` into this `ByteBuffer` at `index` using UTF-8 encoding. Does not move the writer index. + /// + /// - parameters: + /// - string: The string to write. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func setString(_ string: String, at index: Int) -> Int { + // Do not implement setString via setSubstring. Before Swift version 5.3, + // Substring.UTF8View did not implement withContiguousStorageIfAvailable + // and therefore had no fast access to the backing storage. + if let written = string.utf8.withContiguousStorageIfAvailable({ utf8Bytes in + self.setBytes(utf8Bytes, at: index) + }) { + // fast path, directly available + return written + } else { + return self._setStringSlowpath(string, at: index) + } + } + + /// Write `string` null terminated into this `ByteBuffer` at `index` using UTF-8 encoding. Does not move the writer index. + /// + /// - parameters: + /// - string: The string to write. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written. + @inlinable + public mutating func setNullTerminatedString(_ string: String, at index: Int) -> Int { + let length = self.setString(string, at: index) + self.setInteger(UInt8(0), at: index &+ length) + return length &+ 1 + } + + /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index into `ByteBuffer` containing the string of interest. + /// - length: The number of bytes making up the string. + /// - returns: A `String` value containing the UTF-8 decoded selected bytes from this `ByteBuffer` or `nil` if + /// the requested bytes are not readable. + @inlinable + public func getString(at index: Int, length: Int) -> String? { + guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + return nil + } + return self.withUnsafeReadableBytes { pointer in + assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) + return String(decoding: UnsafeRawBufferPointer(fastRebase: pointer[range]), as: Unicode.UTF8.self) + } + } + + /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index into `ByteBuffer` containing the null terminated string of interest. + /// - returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there isn't a complete null-terminated string, + /// including null-terminator, in the readable bytes after `index` in the buffer + @inlinable + public func getNullTerminatedString(at index: Int) -> String? { + guard let stringLength = self._getNullTerminatedStringLength(at: index) else { + return nil + } + return self.getString(at: index, length: stringLength) + } + + @inlinable + func _getNullTerminatedStringLength(at index: Int) -> Int? { + guard self.readerIndex <= index && index < self.writerIndex else { + return nil + } + guard let endIndex = self.readableBytesView[index...].firstIndex(of: 0) else { + return nil + } + return endIndex &- index + } + + /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index forward by `length`. + /// + /// - parameters: + /// - length: The number of bytes making up the string. + /// - returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. + @inlinable + public mutating func readString(length: Int) -> String? { + guard let result = self.getString(at: self.readerIndex, length: length) else { + return nil + } + self._moveReaderIndex(forwardBy: length) + return result + } + + /// Read a null terminated string off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index + /// forward by the string's length and its null terminator. + /// + /// - returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there isn't a complete null-terminated string, + /// including null-terminator, in the readable bytes of the buffer + @inlinable + public mutating func readNullTerminatedString() -> String? { + guard let stringLength = self._getNullTerminatedStringLength(at: self.readerIndex) else { + return nil + } + let result = self.readString(length: stringLength) + self.moveReaderIndex(forwardBy: 1) // move forward by null terminator + return result + } + + // MARK: Substring APIs + /// Write `substring` into this `ByteBuffer` using UTF-8 encoding, moving the writer index forward appropriately. + /// + /// - parameters: + /// - substring: The substring to write. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeSubstring(_ substring: Substring) -> Int { + let written = self.setSubstring(substring, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Write `substring` into this `ByteBuffer` at `index` using UTF-8 encoding. Does not move the writer index. + /// + /// - parameters: + /// - substring: The substring to write. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written + @discardableResult + @inlinable + public mutating func setSubstring(_ substring: Substring, at index: Int) -> Int { + // Substring.UTF8View implements withContiguousStorageIfAvailable starting with + // Swift version 5.3. + if let written = substring.utf8.withContiguousStorageIfAvailable({ utf8Bytes in + self.setBytes(utf8Bytes, at: index) + }) { + // fast path, directly available + return written + } else { + // slow path, convert to string + return self.setString(String(substring), at: index) + } + } + + // MARK: DispatchData APIs + /// Write `dispatchData` into this `ByteBuffer`, moving the writer index forward appropriately. + /// + /// - parameters: + /// - dispatchData: The `DispatchData` instance to write to the `ByteBuffer`. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeDispatchData(_ dispatchData: DispatchData) -> Int { + let written = self.setDispatchData(dispatchData, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Write `dispatchData` into this `ByteBuffer` at `index`. Does not move the writer index. + /// + /// - parameters: + /// - dispatchData: The `DispatchData` to write. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func setDispatchData(_ dispatchData: DispatchData, at index: Int) -> Int { + let allBytesCount = dispatchData.count + self.reserveCapacity(index + allBytesCount) + self.withVeryUnsafeMutableBytes { destCompleteStorage in + assert(destCompleteStorage.count >= index + allBytesCount) + let dest = destCompleteStorage[index ..< index + allBytesCount] + dispatchData.copyBytes(to: .init(fastRebase: dest), count: dest.count) + } + return allBytesCount + } + + /// Get the bytes at `index` from this `ByteBuffer` as a `DispatchData`. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index into `ByteBuffer` containing the string of interest. + /// - length: The number of bytes. + /// - returns: A `DispatchData` value deserialized from this `ByteBuffer` or `nil` if the requested bytes + /// are not readable. + @inlinable + public func getDispatchData(at index: Int, length: Int) -> DispatchData? { + guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + return nil + } + return self.withUnsafeReadableBytes { pointer in + return DispatchData(bytes: UnsafeRawBufferPointer(fastRebase: pointer[range])) + } + } + + /// Read `length` bytes off this `ByteBuffer` and return them as a `DispatchData`. Move the reader index forward by `length`. + /// + /// - parameters: + /// - length: The number of bytes. + /// - returns: A `DispatchData` value containing the bytes from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. + @inlinable + public mutating func readDispatchData(length: Int) -> DispatchData? { + guard let result = self.getDispatchData(at: self.readerIndex, length: length) else { + return nil + } + self._moveReaderIndex(forwardBy: length) + return result + } + + + // MARK: Other APIs + + /// Yields an immutable buffer pointer containing this `ByteBuffer`'s readable bytes. Will move the reader index + /// by the number of bytes returned by `body`. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and returns the number of bytes it processed. + /// - returns: The number of bytes read. + @discardableResult + @inlinable + public mutating func readWithUnsafeReadableBytes(_ body: (UnsafeRawBufferPointer) throws -> Int) rethrows -> Int { + let bytesRead = try self.withUnsafeReadableBytes({ try body($0) }) + self._moveReaderIndex(forwardBy: bytesRead) + return bytesRead + } + + /// Yields an immutable buffer pointer containing this `ByteBuffer`'s readable bytes. Will move the reader index + /// by the number of bytes `body` returns in the first tuple component. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and returns the number of bytes it processed along with some other value. + /// - returns: The value `body` returned in the second tuple component. + @inlinable + public mutating func readWithUnsafeReadableBytes(_ body: (UnsafeRawBufferPointer) throws -> (Int, T)) rethrows -> T { + let (bytesRead, ret) = try self.withUnsafeReadableBytes({ try body($0) }) + self._moveReaderIndex(forwardBy: bytesRead) + return ret + } + + /// Yields a mutable buffer pointer containing this `ByteBuffer`'s readable bytes. You may modify the yielded bytes. + /// Will move the reader index by the number of bytes returned by `body` but leave writer index as it was. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and returns the number of bytes it processed. + /// - returns: The number of bytes read. + @discardableResult + @inlinable + public mutating func readWithUnsafeMutableReadableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> Int) rethrows -> Int { + let bytesRead = try self.withUnsafeMutableReadableBytes({ try body($0) }) + self._moveReaderIndex(forwardBy: bytesRead) + return bytesRead + } + + /// Yields a mutable buffer pointer containing this `ByteBuffer`'s readable bytes. You may modify the yielded bytes. + /// Will move the reader index by the number of bytes `body` returns in the first tuple component but leave writer index as it was. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and returns the number of bytes it processed along with some other value. + /// - returns: The value `body` returned in the second tuple component. + @inlinable + public mutating func readWithUnsafeMutableReadableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> (Int, T)) rethrows -> T { + let (bytesRead, ret) = try self.withUnsafeMutableReadableBytes({ try body($0) }) + self._moveReaderIndex(forwardBy: bytesRead) + return ret + } + + /// Copy `buffer`'s readable bytes into this `ByteBuffer` starting at `index`. Does not move any of the reader or writer indices. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to copy. + /// - index: The index for the first byte. + /// - returns: The number of bytes written. + @discardableResult + @available(*, deprecated, renamed: "setBuffer(_:at:)") + public mutating func set(buffer: ByteBuffer, at index: Int) -> Int { + return self.setBuffer(buffer, at: index) + } + + /// Copy `buffer`'s readable bytes into this `ByteBuffer` starting at `index`. Does not move any of the reader or writer indices. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to copy. + /// - index: The index for the first byte. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func setBuffer(_ buffer: ByteBuffer, at index: Int) -> Int { + return buffer.withUnsafeReadableBytes{ p in + self.setBytes(p, at: index) + } + } + + /// Write `buffer`'s readable bytes into this `ByteBuffer` starting at `writerIndex`. This will move both this + /// `ByteBuffer`'s writer index as well as `buffer`'s reader index by the number of bytes readable in `buffer`. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to write. + /// - returns: The number of bytes written to this `ByteBuffer` which is equal to the number of bytes read from `buffer`. + @discardableResult + @inlinable + public mutating func writeBuffer(_ buffer: inout ByteBuffer) -> Int { + let written = self.setBuffer(buffer, at: writerIndex) + self._moveWriterIndex(forwardBy: written) + buffer._moveReaderIndex(forwardBy: written) + return written + } + + /// Write `bytes`, a `Sequence` of `UInt8` into this `ByteBuffer`. Moves the writer index forward by the number of bytes written. + /// + /// - parameters: + /// - bytes: A `Collection` of `UInt8` to be written. + /// - returns: The number of bytes written or `bytes.count`. + @discardableResult + @inlinable + public mutating func writeBytes(_ bytes: Bytes) -> Int where Bytes.Element == UInt8 { + let written = self.setBytes(bytes, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Write `bytes` into this `ByteBuffer`. Moves the writer index forward by the number of bytes written. + /// + /// - parameters: + /// - bytes: An `UnsafeRawBufferPointer` + /// - returns: The number of bytes written or `bytes.count`. + @discardableResult + @inlinable + public mutating func writeBytes(_ bytes: UnsafeRawBufferPointer) -> Int { + let written = self.setBytes(bytes, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Writes `byte` `count` times. Moves the writer index forward by the number of bytes written. + /// + /// - parameter byte: The `UInt8` byte to repeat. + /// - parameter count: How many times to repeat the given `byte` + /// - returns: How many bytes were written. + @discardableResult + @inlinable + public mutating func writeRepeatingByte(_ byte: UInt8, count: Int) -> Int { + let written = self.setRepeatingByte(byte, count: count, at: self.writerIndex) + self._moveWriterIndex(forwardBy: written) + return written + } + + /// Sets the given `byte` `count` times at the given `index`. Will reserve more memory if necessary. Does not move the writer index. + /// + /// - parameter byte: The `UInt8` byte to repeat. + /// - parameter count: How many times to repeat the given `byte` + /// - returns: How many bytes were written. + @discardableResult + @inlinable + public mutating func setRepeatingByte(_ byte: UInt8, count: Int, at index: Int) -> Int { + precondition(count >= 0, "Can't write fewer than 0 bytes") + self.reserveCapacity(index + count) + self.withVeryUnsafeMutableBytes { pointer in + let dest = UnsafeMutableRawBufferPointer(fastRebase: pointer[index ..< index+count]) + _ = dest.initializeMemory(as: UInt8.self, repeating: byte) + } + return count + } + + /// Slice the readable bytes off this `ByteBuffer` without modifying the reader index. This method will return a + /// `ByteBuffer` sharing the underlying storage with the `ByteBuffer` the method was invoked on. The returned + /// `ByteBuffer` will contain the bytes in the range `readerIndex.. ByteBuffer { + return self.getSlice(at: self.readerIndex, length: self.readableBytes)! // must work, bytes definitely in the buffer + } + + /// Slice `length` bytes off this `ByteBuffer` and move the reader index forward by `length`. + /// If enough bytes are readable the `ByteBuffer` returned by this method will share the underlying storage with + /// the `ByteBuffer` the method was invoked on. + /// The returned `ByteBuffer` will contain the bytes in the range `readerIndex..<(readerIndex + length)` of the + /// original `ByteBuffer`. + /// The `readerIndex` of the returned `ByteBuffer` will be `0`, the `writerIndex` will be `length`. + /// + /// - note: Because `ByteBuffer` implements copy-on-write a copy of the storage will be automatically triggered when either of the `ByteBuffer`s sharing storage is written to. + /// + /// - parameters: + /// - length: The number of bytes to slice off. + /// - returns: A `ByteBuffer` sharing storage containing `length` bytes or `nil` if the not enough bytes were readable. + @inlinable + public mutating func readSlice(length: Int) -> ByteBuffer? { + guard let result = self.getSlice_inlineAlways(at: self.readerIndex, length: length) else { + return nil + } + self._moveReaderIndex(forwardBy: length) + return result + } + + @discardableResult + @inlinable + public mutating func writeImmutableBuffer(_ buffer: ByteBuffer) -> Int { + var mutable = buffer + return self.writeBuffer(&mutable) + } +} + +extension ByteBuffer { + /// Return an empty `ByteBuffer` allocated with `ByteBufferAllocator()`. + /// + /// Calling this constructor will not allocate because it will return a `ByteBuffer` that wraps a shared storage + /// object. As soon as you write to the constructed buffer however, you will incur an allocation because a + /// copy-on-write will happen. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` it is + /// recommended using `channel.allocator.buffer(capacity: 0)`. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init() { + self = ByteBufferAllocator.zeroCapacityWithDefaultAllocator + } + + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space using + /// the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(string:)`. Or if you want to write multiple items into the + /// buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeString` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(string: String) { + self = ByteBufferAllocator().buffer(string: string) + } + + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space using + /// the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(substring:)`. Or if you want to write multiple items into + /// the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeSubstring` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(substring string: Substring) { + self = ByteBufferAllocator().buffer(substring: string) + } + + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space using + /// the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(staticString:)`. Or if you want to write multiple items into + /// the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeStaticString` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(staticString string: StaticString) { + self = ByteBufferAllocator().buffer(staticString: string) + } + + /// Create a fresh `ByteBuffer` containing the `bytes`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `bytes` and potentially some extra space using + /// the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(bytes:)`. Or if you want to write multiple items into the + /// buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeBytes` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(bytes: Bytes) where Bytes.Element == UInt8 { + self = ByteBufferAllocator().buffer(bytes: bytes) + } + + /// Create a fresh `ByteBuffer` containing the bytes of the byte representation in the given `endianness` of + /// `integer`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `integer` and potentially some extra space using + /// the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(integer:)`. Or if you want to write multiple items into the + /// buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeInteger` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(integer: I, endianness: Endianness = .big, as: I.Type = I.self) { + self = ByteBufferAllocator().buffer(integer: integer, endianness: endianness, as: `as`) + } + + /// Create a fresh `ByteBuffer` containing `count` repetitions of `byte`. + /// + /// This will allocate a new `ByteBuffer` with at least `count` bytes. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(repeating:count:)`. Or if you want to write multiple items + /// into the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeRepeatingByte` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(repeating byte: UInt8, count: Int) { + self = ByteBufferAllocator().buffer(repeating: byte, count: count) + } + + /// Create a fresh `ByteBuffer` containing the readable bytes of `buffer`. + /// + /// This may allocate a new `ByteBuffer` with enough space to fit `buffer` and potentially some extra space using + /// the default allocator. + /// + /// - note: Use this method only if you deliberately want to reallocate a potentially smaller `ByteBuffer` than the + /// one you already have. Given that `ByteBuffer` is a value type, defensive copies are not necessary. If + /// you have a `ByteBuffer` but would like the `readerIndex` to start at `0`, consider `readSlice` instead. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(buffer:)`. Or if you want to write multiple items into the + /// buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeImmutableBuffer` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(buffer: ByteBuffer) { + self = ByteBufferAllocator().buffer(buffer: buffer) + } + + /// Create a fresh `ByteBuffer` containing the bytes contained in the given `DispatchData`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit the bytes of the `DispatchData` and potentially + /// some extra space using the default allocator. + /// + /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we + /// recommend using `channel.allocator.buffer(dispatchData:)`. Or if you want to write multiple items into + /// the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right + /// size followed by a `writeDispatchData` instead of using this method. This allows SwiftNIO to do + /// accounting and optimisations of resources acquired for operations on a given `Channel` in the future. + @inlinable + public init(dispatchData: DispatchData) { + self = ByteBufferAllocator().buffer(dispatchData: dispatchData) + } +} + +extension ByteBufferAllocator { + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(string: String) -> ByteBuffer { + var buffer = self.buffer(capacity: string.utf8.count) + buffer.writeString(string) + return buffer + } + + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(substring string: Substring) -> ByteBuffer { + var buffer = self.buffer(capacity: string.utf8.count) + buffer.writeSubstring(string) + return buffer + } + + /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `string` and potentially some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(staticString string: StaticString) -> ByteBuffer { + var buffer = self.buffer(capacity: string.utf8CodeUnitCount) + buffer.writeStaticString(string) + return buffer + } + + /// Create a fresh `ByteBuffer` containing the `bytes`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `bytes` and potentially some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(bytes: Bytes) -> ByteBuffer where Bytes.Element == UInt8 { + var buffer = self.buffer(capacity: bytes.underestimatedCount) + buffer.writeBytes(bytes) + return buffer + } + + /// Create a fresh `ByteBuffer` containing the bytes of the byte representation in the given `endianness` of + /// `integer`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit `integer` and potentially some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(integer: I, + endianness: Endianness = .big, + as: I.Type = I.self) -> ByteBuffer { + var buffer = self.buffer(capacity: MemoryLayout.size) + buffer.writeInteger(integer, endianness: endianness, as: `as`) + return buffer + } + + /// Create a fresh `ByteBuffer` containing `count` repetitions of `byte`. + /// + /// This will allocate a new `ByteBuffer` with at least `count` bytes. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(repeating byte: UInt8, count: Int) -> ByteBuffer { + var buffer = self.buffer(capacity: count) + buffer.writeRepeatingByte(byte, count: count) + return buffer + } + + /// Create a fresh `ByteBuffer` containing the readable bytes of `buffer`. + /// + /// This may allocate a new `ByteBuffer` with enough space to fit `buffer` and potentially some extra space. + /// + /// - note: Use this method only if you deliberately want to reallocate a potentially smaller `ByteBuffer` than the + /// one you already have. Given that `ByteBuffer` is a value type, defensive copies are not necessary. If + /// you have a `ByteBuffer` but would like the `readerIndex` to start at `0`, consider `readSlice` instead. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(buffer: ByteBuffer) -> ByteBuffer { + var newBuffer = self.buffer(capacity: buffer.readableBytes) + newBuffer.writeImmutableBuffer(buffer) + return newBuffer + } + + /// Create a fresh `ByteBuffer` containing the bytes contained in the given `DispatchData`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit the bytes of the `DispatchData` and potentially + /// some extra space. + /// + /// - returns: The `ByteBuffer` containing the written bytes. + @inlinable + public func buffer(dispatchData: DispatchData) -> ByteBuffer { + var buffer = self.buffer(capacity: dispatchData.count) + buffer.writeDispatchData(dispatchData) + return buffer + } +} + + +extension Optional where Wrapped == ByteBuffer { + /// If `nil`, replace `self` with `.some(buffer)`. If non-`nil`, write `buffer`'s readable bytes into the + /// `ByteBuffer` starting at `writerIndex`. + /// + /// This method will not modify `buffer`, meaning its `readerIndex` and `writerIndex` stays intact. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to write. + /// - returns: The number of bytes written to this `ByteBuffer` which is equal to the number of `readableBytes` in + /// `buffer`. + @discardableResult + @inlinable + public mutating func setOrWriteImmutableBuffer(_ buffer: ByteBuffer) -> Int { + var mutable = buffer + return self.setOrWriteBuffer(&mutable) + } + + /// If `nil`, replace `self` with `.some(buffer)`. If non-`nil`, write `buffer`'s readable bytes into the + /// `ByteBuffer` starting at `writerIndex`. + /// + /// This will move both this `ByteBuffer`'s writer index as well as `buffer`'s reader index by the number of bytes + /// readable in `buffer`. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to write. + /// - returns: The number of bytes written to this `ByteBuffer` which is equal to the number of bytes read from `buffer`. + @discardableResult + @inlinable + public mutating func setOrWriteBuffer(_ buffer: inout ByteBuffer) -> Int { + if self == nil { + let readableBytes = buffer.readableBytes + self = buffer + buffer.moveReaderIndex(to: buffer.writerIndex) + return readableBytes + } else { + return self!.writeBuffer(&buffer) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-conversions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-conversions.swift new file mode 100644 index 00000000..188d1d01 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-conversions.swift @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch + +extension Array where Element == UInt8 { + + /// Creates a `[UInt8]` from the given buffer. The entire readable portion of the buffer will be read. + /// - parameter buffer: The buffer to read. + @inlinable + public init(buffer: ByteBuffer) { + var buffer = buffer + self = buffer.readBytes(length: buffer.readableBytes)! + } + +} + +extension String { + + /// Creates a `String` from a given `ByteBuffer`. The entire readable portion of the buffer will be read. + /// - parameter buffer: The buffer to read. + @inlinable + public init(buffer: ByteBuffer) { + var buffer = buffer + self = buffer.readString(length: buffer.readableBytes)! + } + +} + +extension DispatchData { + + /// Creates a `DispatchData` from a given `ByteBuffer`. The entire readable portion of the buffer will be read. + /// - parameter buffer: The buffer to read. + @inlinable + public init(buffer: ByteBuffer) { + var buffer = buffer + self = buffer.readDispatchData(length: buffer.readableBytes)! + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-core.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-core.swift new file mode 100644 index 00000000..45279577 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-core.swift @@ -0,0 +1,1113 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) +import ucrt +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#else +import Glibc +#endif + +@usableFromInline let sysMalloc: @convention(c) (size_t) -> UnsafeMutableRawPointer? = malloc +@usableFromInline let sysRealloc: @convention(c) (UnsafeMutableRawPointer?, size_t) -> UnsafeMutableRawPointer? = realloc + +/// Xcode 13 GM shipped with a bug in the SDK that caused `free`'s first argument to be annotated as +/// non-nullable. To that end, we define a thunk through to `free` that matches that constraint, as we +/// never pass a `nil` pointer to it. +@usableFromInline let sysFree: @convention(c) (UnsafeMutableRawPointer) -> Void = { free($0) } + +extension _ByteBufferSlice: Equatable {} + +/// The slice of a `ByteBuffer`, it's different from `Range` because the lower bound is actually only +/// 24 bits (the upper bound is still 32). Before constructing, you need to make sure the lower bound actually +/// fits within 24 bits, otherwise the behaviour is undefined. +@usableFromInline +struct _ByteBufferSlice { + @usableFromInline private(set) var upperBound: ByteBuffer._Index + @usableFromInline private(set) var _begin: _UInt24 + @inlinable var lowerBound: ByteBuffer._Index { + return UInt32(self._begin) + } + @inlinable var count: Int { + // Safe: the only constructors that set this enforce that upperBound > lowerBound, so + // this cannot underflow. + return Int(self.upperBound &- self.lowerBound) + } + @inlinable init() { + self._begin = .init(0) + self.upperBound = .init(0) + } + @inlinable static var maxSupportedLowerBound: ByteBuffer._Index { + return ByteBuffer._Index(_UInt24.max) + } +} + +extension _ByteBufferSlice { + @inlinable init(_ range: Range) { + self._begin = _UInt24(range.lowerBound) + self.upperBound = range.upperBound + } +} + +extension _ByteBufferSlice: CustomStringConvertible { + @usableFromInline + var description: String { + return "_ByteBufferSlice { \(self.lowerBound)..<\(self.upperBound) }" + } +} + +/// The preferred allocator for `ByteBuffer` values. The allocation strategy is opaque but is currently libc's +/// `malloc`, `realloc` and `free`. +/// +/// - note: `ByteBufferAllocator` is thread-safe. +public struct ByteBufferAllocator { + + /// Create a fresh `ByteBufferAllocator`. In the future the allocator might use for example allocation pools and + /// therefore it's recommended to reuse `ByteBufferAllocators` where possible instead of creating fresh ones in + /// many places. + @inlinable public init() { + self.init(hookedMalloc: { sysMalloc($0) }, + hookedRealloc: { sysRealloc($0, $1) }, + hookedFree: { sysFree($0) }, + hookedMemcpy: { $0.copyMemory(from: $1, byteCount: $2) }) + } + + @inlinable + internal init(hookedMalloc: @escaping @convention(c) (size_t) -> UnsafeMutableRawPointer?, + hookedRealloc: @escaping @convention(c) (UnsafeMutableRawPointer?, size_t) -> UnsafeMutableRawPointer?, + hookedFree: @escaping @convention(c) (UnsafeMutableRawPointer) -> Void, + hookedMemcpy: @escaping @convention(c) (UnsafeMutableRawPointer, UnsafeRawPointer, size_t) -> Void) { + self.malloc = hookedMalloc + self.realloc = hookedRealloc + self.free = hookedFree + self.memcpy = hookedMemcpy + } + + /// Request a freshly allocated `ByteBuffer` of size `capacity` or larger. + /// + /// - note: The passed `capacity` is the `ByteBuffer`'s initial capacity, it will grow automatically if necessary. + /// + /// - note: If `capacity` is `0`, this function will not allocate. If you want to trigger an allocation immediately, + /// also call `.clear()`. + /// + /// - parameters: + /// - capacity: The initial capacity of the returned `ByteBuffer`. + @inlinable + public func buffer(capacity: Int) -> ByteBuffer { + precondition(capacity >= 0, "ByteBuffer capacity must be positive.") + guard capacity > 0 else { + return ByteBufferAllocator.zeroCapacityWithDefaultAllocator + } + return ByteBuffer(allocator: self, startingCapacity: capacity) + } + + @usableFromInline + internal static let zeroCapacityWithDefaultAllocator = ByteBuffer(allocator: ByteBufferAllocator(), startingCapacity: 0) + + @usableFromInline internal let malloc: @convention(c) (size_t) -> UnsafeMutableRawPointer? + @usableFromInline internal let realloc: @convention(c) (UnsafeMutableRawPointer?, size_t) -> UnsafeMutableRawPointer? + @usableFromInline internal let free: @convention(c) (UnsafeMutableRawPointer) -> Void + @usableFromInline internal let memcpy: @convention(c) (UnsafeMutableRawPointer, UnsafeRawPointer, size_t) -> Void +} + +@inlinable func _toCapacity(_ value: Int) -> ByteBuffer._Capacity { + return ByteBuffer._Capacity(truncatingIfNeeded: value) +} + +@inlinable func _toIndex(_ value: Int) -> ByteBuffer._Index { + return ByteBuffer._Index(truncatingIfNeeded: value) +} + +/// `ByteBuffer` stores contiguously allocated raw bytes. It is a random and sequential accessible sequence of zero or +/// more bytes (octets). +/// +/// ### Allocation +/// Use `allocator.buffer(capacity: desiredCapacity)` to allocate a new `ByteBuffer`. +/// +/// ### Supported types +/// A variety of types can be read/written from/to a `ByteBuffer`. Using Swift's `extension` mechanism you can easily +/// create `ByteBuffer` support for your own data types. Out of the box, `ByteBuffer` supports for example the following +/// types (non-exhaustive list): +/// +/// - `String`/`StaticString` +/// - Swift's various (unsigned) integer types +/// - `Foundation`'s `Data` +/// - `[UInt8]` and generally any `Collection` of `UInt8` +/// +/// ### Random Access +/// For every supported type `ByteBuffer` usually contains two methods for random access: +/// +/// 1. `get(at: Int, length: Int)` where `` is for example `String`, `Data`, `Bytes` (for `[UInt8]`) +/// 2. `set(at: Int)` +/// +/// Example: +/// +/// var buf = ... +/// buf.setString("Hello World", at: 0) +/// buf.moveWriterIndex(to: 11) +/// let helloWorld = buf.getString(at: 0, length: 11) +/// +/// let written = buf.setInteger(17 as Int, at: 11) +/// buf.moveWriterIndex(forwardBy: written) +/// let seventeen: Int? = buf.getInteger(at: 11) +/// +/// If needed, `ByteBuffer` will automatically resize its storage to accommodate your `set` request. +/// +/// ### Sequential Access +/// `ByteBuffer` provides two properties which are indices into the `ByteBuffer` to support sequential access: +/// - `readerIndex`, the index of the next readable byte +/// - `writerIndex`, the index of the next byte to write +/// +/// For every supported type `ByteBuffer` usually contains two methods for sequential access: +/// +/// 1. `read(length: Int)` to read `length` bytes from the current `readerIndex` (and then advance the reader +/// index by `length` bytes) +/// 2. `write(Type)` to write, advancing the `writerIndex` by the appropriate amount +/// +/// Example: +/// +/// var buf = ... +/// buf.writeString("Hello World") +/// buf.writeInteger(17 as Int) +/// let helloWorld = buf.readString(length: 11) +/// let seventeen: Int = buf.readInteger() +/// +/// ### Layout +/// +-------------------+------------------+------------------+ +/// | discardable bytes | readable bytes | writable bytes | +/// | | (CONTENT) | | +/// +-------------------+------------------+------------------+ +/// | | | | +/// 0 <= readerIndex <= writerIndex <= capacity +/// +/// The 'discardable bytes' are usually bytes that have already been read, they can however still be accessed using +/// the random access methods. 'Readable bytes' are the bytes currently available to be read using the sequential +/// access interface (`read`/`write`). Getting `writableBytes` (bytes beyond the writer index) is undefined +/// behaviour and might yield arbitrary bytes (_not_ `0` initialised). +/// +/// ### Slicing +/// `ByteBuffer` supports slicing a `ByteBuffer` without copying the underlying storage. +/// +/// Example: +/// +/// var buf = ... +/// let dataBytes: [UInt8] = [0xca, 0xfe, 0xba, 0xbe] +/// let dataBytesLength = UInt32(dataBytes.count) +/// buf.writeInteger(dataBytesLength) /* the header */ +/// buf.writeBytes(dataBytes) /* the data */ +/// let bufDataBytesOnly = buf.getSlice(at: 4, length: dataBytes.count) +/// /* `bufDataByteOnly` and `buf` will share their storage */ +/// +/// ### Notes +/// All `ByteBuffer` methods that don't contain the word 'unsafe' will only allow you to access the 'readable bytes'. +/// +public struct ByteBuffer { + @usableFromInline typealias Slice = _ByteBufferSlice + @usableFromInline typealias Allocator = ByteBufferAllocator + // these two type aliases should be made `@usableFromInline internal` for + // the 2.0 release when we can drop Swift 4.0 & 4.1 support. The reason they + // must be public is because Swift 4.0 and 4.1 don't support attributes for + // typealiases and Swift 4.2 warns if those attributes aren't present and + // the type is internal. + public typealias _Index = UInt32 + public typealias _Capacity = UInt32 + + @usableFromInline var _storage: _Storage + @usableFromInline var _readerIndex: _Index + @usableFromInline var _writerIndex: _Index + @usableFromInline var _slice: Slice + + // MARK: Internal _Storage for CoW + @usableFromInline final class _Storage { + @usableFromInline private(set) var capacity: _Capacity + @usableFromInline private(set) var bytes: UnsafeMutableRawPointer + @usableFromInline let allocator: ByteBufferAllocator + + @inlinable + init(bytesNoCopy: UnsafeMutableRawPointer, capacity: _Capacity, allocator: ByteBufferAllocator) { + self.bytes = bytesNoCopy + self.capacity = capacity + self.allocator = allocator + } + + deinit { + self.deallocate() + } + + @inlinable + var fullSlice: _ByteBufferSlice { + return _ByteBufferSlice(0.. UnsafeMutableRawPointer { + let ptr = allocator.malloc(size_t(bytes))! + /* bind the memory so we can assume it elsewhere to be bound to UInt8 */ + ptr.bindMemory(to: UInt8.self, capacity: Int(bytes)) + return ptr + } + + @inlinable + func allocateStorage() -> _Storage { + return self.allocateStorage(capacity: self.capacity) + } + + @inlinable + func allocateStorage(capacity: _Capacity) -> _Storage { + let newCapacity = capacity == 0 ? 0 : capacity.nextPowerOf2ClampedToMax() + return _Storage(bytesNoCopy: _Storage._allocateAndPrepareRawMemory(bytes: newCapacity, allocator: self.allocator), + capacity: newCapacity, + allocator: self.allocator) + } + + @inlinable + func reallocSlice(_ slice: Range, capacity: _Capacity) -> _Storage { + assert(slice.count <= capacity) + let new = self.allocateStorage(capacity: capacity) + self.allocator.memcpy(new.bytes, self.bytes.advanced(by: Int(slice.lowerBound)), size_t(slice.count)) + return new + } + + @inlinable + func reallocStorage(capacity minimumNeededCapacity: _Capacity) { + let newCapacity = minimumNeededCapacity.nextPowerOf2ClampedToMax() + let ptr = self.allocator.realloc(self.bytes, size_t(newCapacity))! + /* bind the memory so we can assume it elsewhere to be bound to UInt8 */ + ptr.bindMemory(to: UInt8.self, capacity: Int(newCapacity)) + self.bytes = ptr + self.capacity = newCapacity + } + + private func deallocate() { + self.allocator.free(self.bytes) + } + + @inlinable + static func reallocated(minimumCapacity: _Capacity, allocator: Allocator) -> _Storage { + let newCapacity = minimumCapacity == 0 ? 0 : minimumCapacity.nextPowerOf2ClampedToMax() + // TODO: Use realloc if possible + return _Storage(bytesNoCopy: _Storage._allocateAndPrepareRawMemory(bytes: newCapacity, allocator: allocator), + capacity: newCapacity, + allocator: allocator) + } + + func dumpBytes(slice: Slice, offset: Int, length: Int) -> String { + var desc = "[" + let bytes = UnsafeRawBufferPointer(start: self.bytes, count: Int(self.capacity)) + for byte in bytes[Int(slice.lowerBound) + offset ..< Int(slice.lowerBound) + offset + length] { + let hexByte = String(byte, radix: 16) + desc += " \(hexByte.count == 1 ? "0" : "")\(hexByte)" + } + desc += " ]" + return desc + } + } + + @inlinable + @inline(never) + mutating func _copyStorageAndRebase(capacity: _Capacity, resetIndices: Bool = false) { + // This math has to be very careful, because we already know that in some call paths _readerIndex exceeds 1 << 24, and lots of this math + // is in UInt32 space. It's not hard for us to trip some of these conditions. As a result, I've heavily commented this + // fairly heavily to explain the math. + + // Step 1: If we are resetting the indices, we need to slide the allocation by at least the current value of _readerIndex, so the new + // value of _readerIndex will be 0. Otherwise we can leave them as they are. + let indexRebaseAmount = resetIndices ? self._readerIndex : 0 + + // Step 2: We also want to only copy the bytes within the slice, and move them to index 0. As a result, we have this + // state space after the copy-and-rebase: + // + // +--------------+------------------------+-------------------+ + // | resetIndices | self._slice.lowerBound | self._readerIndex | + // +--------------+------------------------+-------------------+ + // | true | 0 | 0 | + // | false | 0 | self._readerIndex | + // +--------------+------------------------+-------------------+ + // + // The maximum value of _readerIndex (and so indexRebaseAmount) is UInt32.max, but that can only happen if the lower bound + // of the slice is 0, when this addition would be safe. Recall that _readerIndex is an index _into_ the slice, and the upper bound of + // the slice must be stored into a UInt32, so the capacity can never be more than UInt32.max. As _slice.lowerBound advances, _readerIndex + // must shrink. In the worst case, _readerIndex == _slice.count == (_slice.upperBound - _slice.lowerBound), so it is always safe to add + // _slice.lowerBound to _readerIndex. This cannot overflow. + // + // This value ends up storing the lower bound of the bytes we want to copy. + let storageRebaseAmount = self._slice.lowerBound + indexRebaseAmount + + // Step 3: Here we need to find out the range within the slice that defines the upper bound of the range of bytes we want to copy. + // This will be the smallest of: + // + // 1. The target requested capacity, in bytes, as a UInt32 (the argument `capacity`), added to the lower bound. The resulting size of + // the slice is equal to the argument `capacity`. + // 2. The upper bound of the current slice. This will be smaller than (1) if there are fewer bytes in the current buffer than the size of + // the requested capacity. + // + // This math is checked on purpose: we should not pass a value of capacity that is larger than the size of the buffer, and if resetIndices is + // true then we shouldn't pass a value that is larger than readable bytes. If we do, that's an error. + let storageUpperBound = min(self._slice.upperBound, storageRebaseAmount + capacity) + + // Step 4: Allocate the new buffer and copy the slice of bytes we want to keep. + let newSlice = storageRebaseAmount ..< storageUpperBound + self._storage = self._storage.reallocSlice(newSlice, capacity: capacity) + + // Step 5: Fixup the indices. These should never trap, but we're going to leave them checked because this method is fiddly. + self._moveReaderIndex(to: self._readerIndex - indexRebaseAmount) + self._moveWriterIndex(to: self._writerIndex - indexRebaseAmount) + + // Step 6: As we've reallocated the buffer, we can now use the entire new buffer as our slice. + self._slice = self._storage.fullSlice + } + + @inlinable + @inline(never) + mutating func _copyStorageAndRebase(extraCapacity: _Capacity = 0, resetIndices: Bool = false) { + self._copyStorageAndRebase(capacity: _toCapacity(self._slice.count) + extraCapacity, resetIndices: resetIndices) + } + + @inlinable + @inline(never) + mutating func _ensureAvailableCapacity(_ capacity: _Capacity, at index: _Index) { + assert(isKnownUniquelyReferenced(&self._storage)) + + let totalNeededCapacityWhenKeepingSlice = self._slice.lowerBound + index + capacity + if totalNeededCapacityWhenKeepingSlice > self._slice.upperBound { + // we need to at least adjust the slice's upper bound which we can do as we're the unique owner of the storage, + // let's see if adjusting the slice's upper bound buys us enough storage + if totalNeededCapacityWhenKeepingSlice > self._storage.capacity { + let newStorageMinCapacity = index + capacity + // nope, we need to actually re-allocate again. If our slice does not start at 0, let's also rebase + if self._slice.lowerBound == 0 { + self._storage.reallocStorage(capacity: newStorageMinCapacity) + } else { + self._storage = self._storage.reallocSlice(self._slice.lowerBound ..< self._slice.upperBound, + capacity: newStorageMinCapacity) + } + self._slice = self._storage.fullSlice + } else { + // yes, let's just extend the slice until the end of the buffer + self._slice = _ByteBufferSlice(_slice.lowerBound ..< self._storage.capacity) + } + } + assert(self._slice.lowerBound + index + capacity <= self._slice.upperBound) + assert(self._slice.lowerBound >= 0, "illegal slice: negative lower bound: \(self._slice.lowerBound)") + assert(self._slice.upperBound <= self._storage.capacity, "illegal slice: upper bound (\(self._slice.upperBound)) exceeds capacity: \(self._storage.capacity)") + } + + // MARK: Internal API + + @inlinable + mutating func _moveReaderIndex(to newIndex: _Index) { + assert(newIndex >= 0 && newIndex <= writerIndex) + self._readerIndex = newIndex + } + + @inlinable + mutating func _moveReaderIndex(forwardBy offset: Int) { + let newIndex = self._readerIndex + _toIndex(offset) + self._moveReaderIndex(to: newIndex) + } + + @inlinable + mutating func _moveWriterIndex(to newIndex: _Index) { + assert(newIndex >= 0 && newIndex <= _toCapacity(self._slice.count)) + self._writerIndex = newIndex + } + + @inlinable + mutating func _moveWriterIndex(forwardBy offset: Int) { + let newIndex = self._writerIndex + _toIndex(offset) + self._moveWriterIndex(to: newIndex) + } + + @inlinable + mutating func _setBytes(_ bytes: UnsafeRawBufferPointer, at index: _Index) -> _Capacity { + let bytesCount = bytes.count + let newEndIndex: _Index = index + _toIndex(bytesCount) + if !isKnownUniquelyReferenced(&self._storage) { + let extraCapacity = newEndIndex > self._slice.upperBound ? newEndIndex - self._slice.upperBound : 0 + self._copyStorageAndRebase(extraCapacity: extraCapacity) + } + self._ensureAvailableCapacity(_Capacity(bytesCount), at: index) + self._setBytesAssumingUniqueBufferAccess(bytes, at: index) + return _toCapacity(bytesCount) + } + + @inlinable + mutating func _setBytesAssumingUniqueBufferAccess(_ bytes: UnsafeRawBufferPointer, at index: _Index) { + let targetPtr = UnsafeMutableRawBufferPointer(fastRebase: self._slicedStorageBuffer.dropFirst(Int(index))) + targetPtr.copyMemory(from: bytes) + } + + @inline(never) + @inlinable + @_specialize(where Bytes == CircularBuffer) + mutating func _setSlowPath(bytes: Bytes, at index: _Index) -> _Capacity where Bytes.Element == UInt8 { + func ensureCapacityAndReturnStorageBase(capacity: Int) -> UnsafeMutablePointer { + self._ensureAvailableCapacity(_Capacity(capacity), at: index) + let newBytesPtr = UnsafeMutableRawBufferPointer(fastRebase: self._slicedStorageBuffer[Int(index) ..< Int(index) + Int(capacity)]) + return newBytesPtr.bindMemory(to: UInt8.self).baseAddress! + } + let underestimatedByteCount = bytes.underestimatedCount + let newPastEndIndex: _Index = index + _toIndex(underestimatedByteCount) + if !isKnownUniquelyReferenced(&self._storage) { + let extraCapacity = newPastEndIndex > self._slice.upperBound ? newPastEndIndex - self._slice.upperBound : 0 + self._copyStorageAndRebase(extraCapacity: extraCapacity) + } + + var base = ensureCapacityAndReturnStorageBase(capacity: underestimatedByteCount) + var (iterator, idx) = UnsafeMutableBufferPointer(start: base, count: underestimatedByteCount).initialize(from: bytes) + assert(idx == underestimatedByteCount) + while let b = iterator.next() { + base = ensureCapacityAndReturnStorageBase(capacity: idx + 1) + base[idx] = b + idx += 1 + } + return _toCapacity(idx) + } + + @inlinable + mutating func _setBytes(_ bytes: Bytes, at index: _Index) -> _Capacity where Bytes.Element == UInt8 { + if let written = bytes.withContiguousStorageIfAvailable({ bytes in + self._setBytes(UnsafeRawBufferPointer(bytes), at: index) + }) { + // fast path, we've got access to the contiguous bytes + return written + } else { + return self._setSlowPath(bytes: bytes, at: index) + } + } + + // MARK: Public Core API + + @inlinable init(allocator: ByteBufferAllocator, startingCapacity: Int) { + let startingCapacity = _toCapacity(startingCapacity) + self._readerIndex = 0 + self._writerIndex = 0 + self._storage = _Storage.reallocated(minimumCapacity: startingCapacity, allocator: allocator) + self._slice = self._storage.fullSlice + } + + /// The number of bytes writable until `ByteBuffer` will need to grow its underlying storage which will likely + /// trigger a copy of the bytes. + @inlinable public var writableBytes: Int { + // this cannot over/overflow because both values are positive and writerIndex<=slice.count, checked on ingestion + return Int(_toCapacity(self._slice.count) &- self._writerIndex) + } + + /// The number of bytes readable (`readableBytes` = `writerIndex` - `readerIndex`). + @inlinable public var readableBytes: Int { + // this cannot under/overflow because both are positive and writer >= reader (checked on ingestion of bytes). + return Int(self._writerIndex &- self._readerIndex) + } + + /// The current capacity of the storage of this `ByteBuffer`, this is not constant and does _not_ signify the number + /// of bytes that have been written to this `ByteBuffer`. + @inlinable + public var capacity: Int { + return self._slice.count + } + + /// The current capacity of the underlying storage of this `ByteBuffer`. + /// A COW slice of the buffer (e.g. readSlice(length: x)) will posses the same storageCapacity as the original + /// buffer until new data is written. + @inlinable + public var storageCapacity: Int { + return self._storage.fullSlice.count + } + + /// Reserves enough space to store the specified number of bytes. + /// + /// This method will ensure that the buffer has space for at least as many bytes as requested. + /// This includes any bytes already stored, and completely disregards the reader/writer indices. + /// If the buffer already has space to store the requested number of bytes, this method will be + /// a no-op. + /// + /// - parameters: + /// - minimumCapacity: The minimum number of bytes this buffer must be able to store. + @inlinable + public mutating func reserveCapacity(_ minimumCapacity: Int) { + guard minimumCapacity > self.capacity else { + return + } + let targetCapacity = _toCapacity(minimumCapacity) + + if isKnownUniquelyReferenced(&self._storage) { + // We have the unique reference. If we have the full slice, we can realloc. Otherwise + // we have to copy memory anyway. + self._ensureAvailableCapacity(targetCapacity, at: 0) + } else { + // We don't have a unique reference here, so we need to allocate and copy, no + // optimisations available. + self._copyStorageAndRebase(capacity: targetCapacity) + } + } + + /// Reserves enough space to write at least the specified number of bytes. + /// + /// This method will ensure that the buffer has enough writable space for at least as many bytes + /// as requested. If the buffer already has space to write the requested number of bytes, this + /// method will be a no-op. + /// + /// - Parameter minimumWritableBytes: The minimum number of writable bytes this buffer must have. + @inlinable + public mutating func reserveCapacity(minimumWritableBytes: Int) { + return self.reserveCapacity(self.writerIndex + minimumWritableBytes) + } + + @inlinable + @inline(never) + mutating func _copyStorageAndRebaseIfNeeded() { + if !isKnownUniquelyReferenced(&self._storage) { + self._copyStorageAndRebase() + } + } + + @inlinable + var _slicedStorageBuffer: UnsafeMutableRawBufferPointer { + return UnsafeMutableRawBufferPointer(start: self._storage.bytes.advanced(by: Int(self._slice.lowerBound)), + count: self._slice.count) + } + + /// Yields a mutable buffer pointer containing this `ByteBuffer`'s readable bytes. You may modify those bytes. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes. + /// - returns: The value returned by `body`. + @inlinable + public mutating func withUnsafeMutableReadableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + self._copyStorageAndRebaseIfNeeded() + // this is safe because we always know that readerIndex >= writerIndex + let range = Range(uncheckedBounds: (lower: self.readerIndex, upper: self.writerIndex)) + return try body(.init(fastRebase: self._slicedStorageBuffer[range])) + } + + /// Yields the bytes currently writable (`bytesWritable` = `capacity` - `writerIndex`). Before reading those bytes you must first + /// write to them otherwise you will trigger undefined behaviour. The writer index will remain unchanged. + /// + /// - note: In almost all cases you should use `writeWithUnsafeMutableBytes` which will move the write pointer instead of this method + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and return the number of bytes written. + /// - returns: The number of bytes written. + @inlinable + public mutating func withUnsafeMutableWritableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + self._copyStorageAndRebaseIfNeeded() + return try body(.init(fastRebase: self._slicedStorageBuffer.dropFirst(self.writerIndex))) + } + + /// This vends a pointer of the `ByteBuffer` at the `writerIndex` after ensuring that the buffer has at least `minimumWritableBytes` of writable bytes available. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - minimumWritableBytes: The number of writable bytes to reserve capacity for before vending the `ByteBuffer` pointer to `body`. + /// - body: The closure that will accept the yielded bytes and return the number of bytes written. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeWithUnsafeMutableBytes(minimumWritableBytes: Int, _ body: (UnsafeMutableRawBufferPointer) throws -> Int) rethrows -> Int { + if minimumWritableBytes > 0 { + self.reserveCapacity(minimumWritableBytes: minimumWritableBytes) + } + let bytesWritten = try self.withUnsafeMutableWritableBytes({ try body($0) }) + self._moveWriterIndex(to: self._writerIndex + _toIndex(bytesWritten)) + return bytesWritten + } + + @available(*, deprecated, message: "please use writeWithUnsafeMutableBytes(minimumWritableBytes:_:) instead to ensure sufficient write capacity.") + @discardableResult + @inlinable + public mutating func writeWithUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> Int) rethrows -> Int { + return try self.writeWithUnsafeMutableBytes(minimumWritableBytes: 0, { try body($0) }) + } + + /// This vends a pointer to the storage of the `ByteBuffer`. It's marked as _very unsafe_ because it might contain + /// uninitialised memory and it's undefined behaviour to read it. In most cases you should use `withUnsafeReadableBytes`. + /// + /// - warning: Do not escape the pointer from the closure for later use. + @inlinable + public func withVeryUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + return try body(.init(self._slicedStorageBuffer)) + } + + /// This vends a pointer to the storage of the `ByteBuffer`. It's marked as _very unsafe_ because it might contain + /// uninitialised memory and it's undefined behaviour to read it. In most cases you should use `withUnsafeMutableWritableBytes`. + /// + /// - warning: Do not escape the pointer from the closure for later use. + @inlinable + public mutating func withVeryUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + self._copyStorageAndRebaseIfNeeded() // this will trigger a CoW if necessary + return try body(.init(self._slicedStorageBuffer)) + } + + /// Yields a buffer pointer containing this `ByteBuffer`'s readable bytes. + /// + /// - warning: Do not escape the pointer from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes. + /// - returns: The value returned by `body`. + @inlinable + public func withUnsafeReadableBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + // This is safe, writerIndex >= readerIndex + let range = Range(uncheckedBounds: (lower: self.readerIndex, upper: self.writerIndex)) + return try body(.init(fastRebase: self._slicedStorageBuffer[range])) + } + + /// Yields a buffer pointer containing this `ByteBuffer`'s readable bytes. You may hold a pointer to those bytes + /// even after the closure returned iff you model the lifetime of those bytes correctly using the `Unmanaged` + /// instance. If you don't require the pointer after the closure returns, use `withUnsafeReadableBytes`. + /// + /// If you escape the pointer from the closure, you _must_ call `storageManagement.retain()` to get ownership to + /// the bytes and you also must call `storageManagement.release()` if you no longer require those bytes. Calls to + /// `retain` and `release` must be balanced. + /// + /// - parameters: + /// - body: The closure that will accept the yielded bytes and the `storageManagement`. + /// - returns: The value returned by `body`. + @inlinable + public func withUnsafeReadableBytesWithStorageManagement(_ body: (UnsafeRawBufferPointer, Unmanaged) throws -> T) rethrows -> T { + let storageReference: Unmanaged = Unmanaged.passUnretained(self._storage) + // This is safe, writerIndex >= readerIndex + let range = Range(uncheckedBounds: (lower: self.readerIndex, upper: self.writerIndex)) + return try body(.init(fastRebase: self._slicedStorageBuffer[range]), storageReference) + } + + /// See `withUnsafeReadableBytesWithStorageManagement` and `withVeryUnsafeBytes`. + @inlinable + public func withVeryUnsafeBytesWithStorageManagement(_ body: (UnsafeRawBufferPointer, Unmanaged) throws -> T) rethrows -> T { + let storageReference: Unmanaged = Unmanaged.passUnretained(self._storage) + return try body(.init(self._slicedStorageBuffer), storageReference) + } + + @inlinable + @inline(never) + func _copyIntoByteBufferWithSliceIndex0_slowPath(index: _Index, length: _Capacity) -> ByteBuffer { + var new = self + new._moveWriterIndex(to: index + length) + new._moveReaderIndex(to: index) + new._copyStorageAndRebase(capacity: length, resetIndices: true) + return new + } + + /// Returns a slice of size `length` bytes, starting at `index`. The `ByteBuffer` this is invoked on and the + /// `ByteBuffer` returned will share the same underlying storage. However, the byte at `index` in this `ByteBuffer` + /// will correspond to index `0` in the returned `ByteBuffer`. + /// The `readerIndex` of the returned `ByteBuffer` will be `0`, the `writerIndex` will be `length`. + /// + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The index the requested slice starts at. + /// - length: The length of the requested slice. + /// - returns: A `ByteBuffer` containing the selected bytes as readable bytes or `nil` if the selected bytes were + /// not readable in the initial `ByteBuffer`. + @inlinable + public func getSlice(at index: Int, length: Int) -> ByteBuffer? { + return self.getSlice_inlineAlways(at: index, length: length) + } + + @inline(__always) + @inlinable + internal func getSlice_inlineAlways(at index: Int, length: Int) -> ByteBuffer? { + guard index >= 0 && length >= 0 && index >= self.readerIndex && length <= self.writerIndex && index <= self.writerIndex &- length else { + return nil + } + let index = _toIndex(index) + let length = _toCapacity(length) + + // The arithmetic below is safe because: + // 1. maximum `writerIndex` <= self._slice.count (see `_moveWriterIndex`) + // 2. `self._slice.lowerBound + self._slice.count` is always safe (because it's `self._slice.upperBound`) + // 3. `index` is inside the range `self.readerIndex ... self.writerIndex` (the `guard` above) + // + // This means that the largest number that `index` could have is equal to + // `self._slice_.upperBound = self._slice.lowerBound + self._slice.count` and that + // is guaranteed to be expressible as a `UInt32` (because it's actually stored as such). + let sliceStartIndex: UInt32 = self._slice.lowerBound + index + + guard sliceStartIndex <= ByteBuffer.Slice.maxSupportedLowerBound else { + // the slice's begin is past the maximum supported slice begin value (16 MiB) so the only option we have + // is copy the slice into a fresh buffer. The slice begin will then be at index 0. + return self._copyIntoByteBufferWithSliceIndex0_slowPath(index: index, length: length) + } + var new = self + assert(sliceStartIndex == self._slice.lowerBound &+ index) + + // - The arithmetic below is safe because + // 1. `writerIndex` <= `self._slice.count` (see `_moveWriterIndex`) + // 2. `length` <= `self.writerIndex` (see `guard`s) + // 3. `sliceStartIndex` + `self._slice.count` is always safe (because that's `self._slice.upperBound`. + // - The range construction is safe because `length` >= 0 (see `guard` at the beginning of the function). + new._slice = _ByteBufferSlice(Range(uncheckedBounds: (lower: sliceStartIndex, + upper: sliceStartIndex &+ length))) + new._moveReaderIndex(to: 0) + new._moveWriterIndex(to: length) + return new + } + + /// Discard the bytes before the reader index. The byte at index `readerIndex` before calling this method will be + /// at index `0` after the call returns. + /// + /// - returns: `true` if one or more bytes have been discarded, `false` if there are no bytes to discard. + @inlinable + @discardableResult public mutating func discardReadBytes() -> Bool { + guard self._readerIndex > 0 else { + return false + } + + if self._readerIndex == self._writerIndex { + // If the whole buffer was consumed we can just reset the readerIndex and writerIndex to 0 and move on. + self._moveWriterIndex(to: 0) + self._moveReaderIndex(to: 0) + return true + } + + if isKnownUniquelyReferenced(&self._storage) { + self._storage.bytes.advanced(by: Int(self._slice.lowerBound)) + .copyMemory(from: self._storage.bytes.advanced(by: Int(self._slice.lowerBound + self._readerIndex)), + byteCount: self.readableBytes) + let indexShift = self._readerIndex + self._moveReaderIndex(to: 0) + self._moveWriterIndex(to: self._writerIndex - indexShift) + } else { + self._copyStorageAndRebase(extraCapacity: 0, resetIndices: true) + } + return true + } + + /// The reader index or the number of bytes previously read from this `ByteBuffer`. `readerIndex` is `0` for a + /// newly allocated `ByteBuffer`. + @inlinable + public var readerIndex: Int { + return Int(self._readerIndex) + } + + /// The write index or the number of bytes previously written to this `ByteBuffer`. `writerIndex` is `0` for a + /// newly allocated `ByteBuffer`. + @inlinable + public var writerIndex: Int { + return Int(self._writerIndex) + } + + /// Set both reader index and writer index to `0`. This will reset the state of this `ByteBuffer` to the state + /// of a freshly allocated one, if possible without allocations. This is the cheapest way to recycle a `ByteBuffer` + /// for a new use-case. + /// + /// - note: This method will allocate if the underlying storage is referenced by another `ByteBuffer`. Even if an + /// allocation is necessary this will be cheaper as the copy of the storage is elided. + @inlinable + public mutating func clear() { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.allocateStorage() + } + self._slice = self._storage.fullSlice + self._moveWriterIndex(to: 0) + self._moveReaderIndex(to: 0) + } + + /// Set both reader index and writer index to `0`. This will reset the state of this `ByteBuffer` to the state + /// of a freshly allocated one, if possible without allocations. This is the cheapest way to recycle a `ByteBuffer` + /// for a new use-case. + /// + /// - note: This method will allocate if the underlying storage is referenced by another `ByteBuffer`. Even if an + /// allocation is necessary this will be cheaper as the copy of the storage is elided. + /// + /// - parameters: + /// - minimumCapacity: The minimum capacity that will be (re)allocated for this buffer + @available(*, deprecated, message: "Use an `Int` as the argument") + public mutating func clear(minimumCapacity: UInt32) { + self.clear(minimumCapacity: Int(minimumCapacity)) + } + + /// Set both reader index and writer index to `0`. This will reset the state of this `ByteBuffer` to the state + /// of a freshly allocated one, if possible without allocations. This is the cheapest way to recycle a `ByteBuffer` + /// for a new use-case. + /// + /// - note: This method will allocate if the underlying storage is referenced by another `ByteBuffer`. Even if an + /// allocation is necessary this will be cheaper as the copy of the storage is elided. + /// + /// - parameters: + /// - minimumCapacity: The minimum capacity that will be (re)allocated for this buffer + @inlinable + public mutating func clear(minimumCapacity: Int) { + precondition(minimumCapacity >= 0, "Cannot have a minimum capacity < 0") + precondition(minimumCapacity <= _Capacity.max, "Minimum capacity must be <= \(_Capacity.max)") + + let minimumCapacity = _Capacity(minimumCapacity) + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.allocateStorage(capacity: minimumCapacity) + } else if minimumCapacity > self._storage.capacity { + self._storage.reallocStorage(capacity: minimumCapacity) + } + self._slice = self._storage.fullSlice + + self._moveWriterIndex(to: 0) + self._moveReaderIndex(to: 0) + } +} + +extension ByteBuffer: CustomStringConvertible { + /// A `String` describing this `ByteBuffer`. Example: + /// + /// ByteBuffer { readerIndex: 0, writerIndex: 4, readableBytes: 4, capacity: 512, storageCapacity: 1024, slice: 256..<768, storage: 0x0000000103001000 (1024 bytes)} + /// + /// The format of the description is not API. + /// + /// - returns: A description of this `ByteBuffer`. + public var description: String { + return """ + ByteBuffer { \ + readerIndex: \(self.readerIndex), \ + writerIndex: \(self.writerIndex), \ + readableBytes: \(self.readableBytes), \ + capacity: \(self.capacity), \ + storageCapacity: \(self.storageCapacity), \ + slice: \(self._slice), \ + storage: \(self._storage.bytes) (\(self._storage.capacity) bytes) \ + } + """ + } + + /// A `String` describing this `ByteBuffer` with some portion of the readable bytes dumped too. Example: + /// + /// ByteBuffer { readerIndex: 0, writerIndex: 4, readableBytes: 4, capacity: 512, slice: 256..<768, storage: 0x0000000103001000 (1024 bytes)} + /// readable bytes (max 1k): [ 00 01 02 03 ] + /// + /// The format of the description is not API. + /// + /// - returns: A description of this `ByteBuffer` useful for debugging. + public var debugDescription: String { + return "\(self.description)\nreadable bytes (max 1k): \(self._storage.dumpBytes(slice: self._slice, offset: self.readerIndex, length: min(1024, self.readableBytes)))" + } +} + +/* change types to the user visible `Int` */ +extension ByteBuffer { + /// Copy the collection of `bytes` into the `ByteBuffer` at `index`. Does not move the writer index. + @discardableResult + @inlinable + public mutating func setBytes(_ bytes: Bytes, at index: Int) -> Int where Bytes.Element == UInt8 { + return Int(self._setBytes(bytes, at: _toIndex(index))) + } + + /// Copy `bytes` into the `ByteBuffer` at `index`. Does not move the writer index. + @discardableResult + @inlinable + public mutating func setBytes(_ bytes: UnsafeRawBufferPointer, at index: Int) -> Int { + return Int(self._setBytes(bytes, at: _toIndex(index))) + } + + /// Move the reader index forward by `offset` bytes. + /// + /// - warning: By contract the bytes between (including) `readerIndex` and (excluding) `writerIndex` must be + /// initialised, ie. have been written before. Also the `readerIndex` must always be less than or equal + /// to the `writerIndex`. Failing to meet either of these requirements leads to undefined behaviour. + /// - parameters: + /// - offset: The number of bytes to move the reader index forward by. + @inlinable + public mutating func moveReaderIndex(forwardBy offset: Int) { + let newIndex = self._readerIndex + _toIndex(offset) + precondition(newIndex >= 0 && newIndex <= writerIndex, "new readerIndex: \(newIndex), expected: range(0, \(writerIndex))") + self._moveReaderIndex(to: newIndex) + } + + /// Set the reader index to `offset`. + /// + /// - warning: By contract the bytes between (including) `readerIndex` and (excluding) `writerIndex` must be + /// initialised, ie. have been written before. Also the `readerIndex` must always be less than or equal + /// to the `writerIndex`. Failing to meet either of these requirements leads to undefined behaviour. + /// - parameters: + /// - offset: The offset in bytes to set the reader index to. + @inlinable + public mutating func moveReaderIndex(to offset: Int) { + let newIndex = _toIndex(offset) + precondition(newIndex >= 0 && newIndex <= writerIndex, "new readerIndex: \(newIndex), expected: range(0, \(writerIndex))") + self._moveReaderIndex(to: newIndex) + } + + /// Move the writer index forward by `offset` bytes. + /// + /// - warning: By contract the bytes between (including) `readerIndex` and (excluding) `writerIndex` must be + /// initialised, ie. have been written before. Also the `readerIndex` must always be less than or equal + /// to the `writerIndex`. Failing to meet either of these requirements leads to undefined behaviour. + /// - parameters: + /// - offset: The number of bytes to move the writer index forward by. + @inlinable + public mutating func moveWriterIndex(forwardBy offset: Int) { + let newIndex = self._writerIndex + _toIndex(offset) + precondition(newIndex >= 0 && newIndex <= _toCapacity(self._slice.count),"new writerIndex: \(newIndex), expected: range(0, \(_toCapacity(self._slice.count)))") + self._moveWriterIndex(to: newIndex) + } + + /// Set the writer index to `offset`. + /// + /// - warning: By contract the bytes between (including) `readerIndex` and (excluding) `writerIndex` must be + /// initialised, ie. have been written before. Also the `readerIndex` must always be less than or equal + /// to the `writerIndex`. Failing to meet either of these requirements leads to undefined behaviour. + /// - parameters: + /// - offset: The offset in bytes to set the reader index to. + @inlinable + public mutating func moveWriterIndex(to offset: Int) { + let newIndex = _toIndex(offset) + precondition(newIndex >= 0 && newIndex <= _toCapacity(self._slice.count),"new writerIndex: \(newIndex), expected: range(0, \(_toCapacity(self._slice.count)))") + self._moveWriterIndex(to: newIndex) + } +} + +extension ByteBuffer { + /// Copies `length` `bytes` starting at the `fromIndex` to `toIndex`. Does not move the writer index. + /// + /// - Note: Overlapping ranges, for example `copyBytes(at: 1, to: 2, length: 5)` are allowed. + /// - Precondition: The range represented by `fromIndex` and `length` must be readable bytes, + /// that is: `fromIndex >= readerIndex` and `fromIndex + length <= writerIndex`. + /// - Parameter fromIndex: The index of the first byte to copy. + /// - Parameter toIndex: The index into to which the first byte will be copied. + /// - Parameter length: The number of bytes which should be copied. + @discardableResult + @inlinable + public mutating func copyBytes(at fromIndex: Int, to toIndex: Int, length: Int) throws -> Int { + switch length { + case ..<0: + throw CopyBytesError.negativeLength + case 0: + return 0 + default: + () + } + guard self.readerIndex <= fromIndex && fromIndex + length <= self.writerIndex else { + throw CopyBytesError.unreadableSourceBytes + } + + if !isKnownUniquelyReferenced(&self._storage) { + let newEndIndex = max(self._writerIndex, _toIndex(toIndex + length)) + self._copyStorageAndRebase(capacity: newEndIndex) + } + + self._ensureAvailableCapacity(_Capacity(length), at: _toIndex(toIndex)) + self.withVeryUnsafeBytes { ptr in + let srcPtr = UnsafeRawBufferPointer(start: ptr.baseAddress!.advanced(by: fromIndex), count: length) + self._setBytesAssumingUniqueBufferAccess(srcPtr, at: _toIndex(toIndex)) + } + + return length + } + + /// Errors thrown when calling `copyBytes`. + public struct CopyBytesError: Error { + private enum BaseError: Hashable { + case negativeLength + case unreadableSourceBytes + } + + private var baseError: BaseError + + /// The length of the bytes to copy was negative. + public static let negativeLength: CopyBytesError = .init(baseError: .negativeLength) + + /// The bytes to copy are not readable. + public static let unreadableSourceBytes: CopyBytesError = .init(baseError: .unreadableSourceBytes) + } +} + +extension ByteBuffer.CopyBytesError: Hashable { } + +extension ByteBuffer.CopyBytesError: CustomDebugStringConvertible { + public var debugDescription: String { + return String(describing: self.baseError) + } +} + +extension ByteBuffer: Equatable { + // TODO: I don't think this makes sense. This should compare bytes 0.. Bool { + guard lhs.readableBytes == rhs.readableBytes else { + return false + } + + if lhs._slice == rhs._slice && lhs._storage === rhs._storage { + return true + } + + return lhs.withUnsafeReadableBytes { lPtr in + rhs.withUnsafeReadableBytes { rPtr in + // Shouldn't get here otherwise because of readableBytes check + assert(lPtr.count == rPtr.count) + return memcmp(lPtr.baseAddress!, rPtr.baseAddress!, lPtr.count) == 0 + } + } + } +} + +extension ByteBuffer: Hashable { + /// The hash value for the readable bytes. + @inlinable + public func hash(into hasher: inout Hasher) { + self.withUnsafeReadableBytes { ptr in + hasher.combine(bytes: ptr) + } + } +} + +extension ByteBuffer { + /// Modify this `ByteBuffer` if this `ByteBuffer` is known to uniquely own its storage. + /// + /// In some cases it is possible that code is holding a `ByteBuffer` that has been shared with other + /// parts of the code, and may want to mutate that `ByteBuffer`. In some cases it may be worth modifying + /// a `ByteBuffer` only if that `ByteBuffer` is guaranteed to not perform a copy-on-write operation to do + /// so, for example when a different buffer could be used or more cheaply allocated instead. + /// + /// This function will execute the provided block only if it is guaranteed to be able to avoid a copy-on-write + /// operation. If it cannot execute the block the returned value will be `nil`. + /// + /// - parameters: + /// - body: The modification operation to execute, with this `ByteBuffer` passed `inout` as an argument. + /// - returns: The return value of `body`. + @inlinable + public mutating func modifyIfUniquelyOwned(_ body: (inout ByteBuffer) throws -> T) rethrows -> T? { + if isKnownUniquelyReferenced(&self._storage) { + return try body(&self) + } else { + return nil + } + } +} + +extension ByteBuffer { + @inlinable + func rangeWithinReadableBytes(index: Int, length: Int) -> Range? { + guard index >= self.readerIndex && length >= 0 else { + return nil + } + + // both these &-s are safe, they can't underflow because both left & right side are >= 0 (and index >= readerIndex) + let indexFromReaderIndex = index &- self.readerIndex + assert(indexFromReaderIndex >= 0) + guard indexFromReaderIndex <= self.readableBytes &- length else { + return nil + } + + let upperBound = indexFromReaderIndex &+ length // safe, can't overflow, we checked it above. + + // uncheckedBounds is safe because `length` is >= 0, so the lower bound will always be lower/equal to upper + return Range(uncheckedBounds: (lower: indexFromReaderIndex, upper: upperBound)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-int.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-int.swift new file mode 100644 index 00000000..2618b6fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-int.swift @@ -0,0 +1,178 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension ByteBuffer { + @inlinable + func _toEndianness (value: T, endianness: Endianness) -> T { + switch endianness { + case .little: + return value.littleEndian + case .big: + return value.bigEndian + } + } + + /// Read an integer off this `ByteBuffer`, move the reader index forward by the integer's byte size and return the result. + /// + /// - parameters: + /// - endianness: The endianness of the integer in this `ByteBuffer` (defaults to big endian). + /// - as: the desired `FixedWidthInteger` type (optional parameter) + /// - returns: An integer value deserialized from this `ByteBuffer` or `nil` if there aren't enough bytes readable. + @inlinable + public mutating func readInteger(endianness: Endianness = .big, as: T.Type = T.self) -> T? { + guard let result = self.getInteger(at: self.readerIndex, endianness: endianness, as: T.self) else { + return nil + } + self._moveReaderIndex(forwardBy: MemoryLayout.size) + return result + } + + /// Get the integer at `index` from this `ByteBuffer`. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index of the bytes for the integer into the `ByteBuffer`. + /// - endianness: The endianness of the integer in this `ByteBuffer` (defaults to big endian). + /// - as: the desired `FixedWidthInteger` type (optional parameter) + /// - returns: An integer value deserialized from this `ByteBuffer` or `nil` if the bytes of interest are not + /// readable. + @inlinable + public func getInteger(at index: Int, endianness: Endianness = Endianness.big, as: T.Type = T.self) -> T? { + guard let range = self.rangeWithinReadableBytes(index: index, length: MemoryLayout.size) else { + return nil + } + + if T.self == UInt8.self { + assert(range.count == 1) + return self.withUnsafeReadableBytes { ptr in + ptr[range.startIndex] as! T + } + } + + return self.withUnsafeReadableBytes { ptr in + var value: T = 0 + withUnsafeMutableBytes(of: &value) { valuePtr in + valuePtr.copyMemory(from: UnsafeRawBufferPointer(fastRebase: ptr[range])) + } + return _toEndianness(value: value, endianness: endianness) + } + } + + /// Write `integer` into this `ByteBuffer`, moving the writer index forward appropriately. + /// + /// - parameters: + /// - integer: The integer to serialize. + /// - endianness: The endianness to use, defaults to big endian. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func writeInteger(_ integer: T, + endianness: Endianness = .big, + as: T.Type = T.self) -> Int { + let bytesWritten = self.setInteger(integer, at: self.writerIndex, endianness: endianness) + self._moveWriterIndex(forwardBy: bytesWritten) + return Int(bytesWritten) + } + + /// Write `integer` into this `ByteBuffer` starting at `index`. This does not alter the writer index. + /// + /// - parameters: + /// - integer: The integer to serialize. + /// - index: The index of the first byte to write. + /// - endianness: The endianness to use, defaults to big endian. + /// - returns: The number of bytes written. + @discardableResult + @inlinable + public mutating func setInteger(_ integer: T, at index: Int, endianness: Endianness = .big, as: T.Type = T.self) -> Int { + var value = _toEndianness(value: integer, endianness: endianness) + return Swift.withUnsafeBytes(of: &value) { ptr in + self.setBytes(ptr, at: index) + } + } +} + +extension FixedWidthInteger { + /// Returns the next power of two. + @inlinable + func nextPowerOf2() -> Self { + guard self != 0 else { + return 1 + } + return 1 << (Self.bitWidth - (self - 1).leadingZeroBitCount) + } + + /// Returns the previous power of 2, or self if it already is. + @inlinable + func previousPowerOf2() -> Self { + guard self != 0 else { + return 0 + } + + return 1 << ((Self.bitWidth - 1) - self.leadingZeroBitCount) + } +} + +extension UInt32 { + /// Returns the next power of two unless that would overflow, in which case UInt32.max (on 64-bit systems) or + /// Int32.max (on 32-bit systems) is returned. The returned value is always safe to be cast to Int and passed + /// to malloc on all platforms. + @inlinable + func nextPowerOf2ClampedToMax() -> UInt32 { + guard self > 0 else { + return 1 + } + + var n = self + + #if arch(arm) || arch(i386) + // on 32-bit platforms we can't make use of a whole UInt32.max (as it doesn't fit in an Int) + let max = UInt32(Int.max) + #else + // on 64-bit platforms we're good + let max = UInt32.max + #endif + + n -= 1 + n |= n >> 1 + n |= n >> 2 + n |= n >> 4 + n |= n >> 8 + n |= n >> 16 + if n != max { + n += 1 + } + + return n + } +} + +/// Endianness refers to the sequential order in which bytes are arranged into larger numerical values when stored in +/// memory or when transmitted over digital links. +public enum Endianness { + /// The endianness of the machine running this program. + public static let host: Endianness = hostEndianness0() + + private static func hostEndianness0() -> Endianness { + let number: UInt32 = 0x12345678 + return number == number.bigEndian ? .big : .little + } + + /// big endian, the most significant byte (MSB) is at the lowest address + case big + + /// little endian, the least significant byte (LSB) is at the lowest address + case little +} + + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-lengthPrefix.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-lengthPrefix.swift new file mode 100644 index 00000000..30071729 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-lengthPrefix.swift @@ -0,0 +1,146 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension ByteBuffer { + public struct LengthPrefixError: Swift.Error { + private enum BaseError { + case messageLengthDoesNotFitExactlyIntoRequiredIntegerFormat + case messageCouldNotBeReadSuccessfully + } + private var baseError: BaseError + + public static let messageLengthDoesNotFitExactlyIntoRequiredIntegerFormat: LengthPrefixError = .init(baseError: .messageLengthDoesNotFitExactlyIntoRequiredIntegerFormat) + public static let messageCouldNotBeReadSuccessfully: LengthPrefixError = .init(baseError: .messageCouldNotBeReadSuccessfully) + } +} + +extension ByteBuffer { + /// Prefixes a message written by `writeMessage` with the number of bytes written as an `Integer`. + /// - Parameters: + /// - endianness: The endianness of the length prefix `Integer` in this `ByteBuffer` (defaults to big endian). + /// - integer: the desired `Integer` type used to write the length prefix + /// - writeMessage: A closure that takes a buffer, writes a message to it and returns the number of bytes written + /// - Throws: If the number of bytes written during `writeMessage` can not be exactly represented as the given `Integer` i.e. if the number of bytes written is greater than `Integer.max` + /// - Returns: Number of total bytes written + @discardableResult + @inlinable + public mutating func writeLengthPrefixed( + endianness: Endianness = .big, + as integer: Integer.Type, + writeMessage: (inout ByteBuffer) throws -> Int + ) throws -> Int where Integer: FixedWidthInteger { + var totalBytesWritten = 0 + + let lengthPrefixIndex = self.writerIndex + // Write a zero as a placeholder which will later be overwritten by the actual number of bytes written + totalBytesWritten += self.writeInteger(.zero, endianness: endianness, as: Integer.self) + + let startWriterIndex = self.writerIndex + let messageLength = try writeMessage(&self) + let endWriterIndex = self.writerIndex + + totalBytesWritten += messageLength + + let actualBytesWritten = endWriterIndex - startWriterIndex + assert( + actualBytesWritten == messageLength, + "writeMessage returned \(messageLength) bytes, but actually \(actualBytesWritten) bytes were written, but they should be the same" + ) + + guard let lengthPrefix = Integer(exactly: messageLength) else { + throw LengthPrefixError.messageLengthDoesNotFitExactlyIntoRequiredIntegerFormat + } + + self.setInteger(lengthPrefix, at: lengthPrefixIndex, endianness: endianness, as: Integer.self) + + return totalBytesWritten + } +} + +extension ByteBuffer { + /// Reads an `Integer` from `self`, reads a slice of that length and passes it to `readMessage`. + /// It is checked that `readMessage` returns a non-nil value. + /// + /// The `readerIndex` is **not** moved forward if the length prefix could not be read or `self` does not contain enough bytes. Otherwise `readerIndex` is moved forward even if `readMessage` throws or returns nil. + /// - Parameters: + /// - endianness: The endianness of the length prefix `Integer` in this `ByteBuffer` (defaults to big endian). + /// - integer: the desired `Integer` type used to read the length prefix + /// - readMessage: A closure that takes a `ByteBuffer` slice which contains the message after the length prefix + /// - Throws: if `readMessage` returns nil + /// - Returns: `nil` if the length prefix could not be read, + /// the length prefix is negative or + /// the buffer does not contain enough bytes to read a message of this length. + /// Otherwise the result of `readMessage`. + @inlinable + public mutating func readLengthPrefixed( + endianness: Endianness = .big, + as integer: Integer.Type, + readMessage: (ByteBuffer) throws -> Result? + ) throws -> Result? where Integer: FixedWidthInteger { + guard let buffer = self.readLengthPrefixedSlice(endianness: endianness, as: Integer.self) else { + return nil + } + guard let result = try readMessage(buffer) else { + throw LengthPrefixError.messageCouldNotBeReadSuccessfully + } + return result + } + + /// Reads an `Integer` from `self` and reads a slice of that length from `self` and returns it. + /// + /// If nil is returned, `readerIndex` is **not** moved forward. + /// - Parameters: + /// - endianness: The endianness of the length prefix `Integer` in this `ByteBuffer` (defaults to big endian). + /// - integer: the desired `Integer` type used to read the length prefix + /// - Returns: `nil` if the length prefix could not be read, + /// the length prefix is negative or + /// the buffer does not contain enough bytes to read a message of this length. + /// Otherwise the message after the length prefix. + @inlinable + public mutating func readLengthPrefixedSlice( + endianness: Endianness = .big, + as integer: Integer.Type + ) -> ByteBuffer? where Integer: FixedWidthInteger { + guard let result = self.getLengthPrefixedSlice(at: self.readerIndex, endianness: endianness, as: Integer.self) else { + return nil + } + self._moveReaderIndex(forwardBy: MemoryLayout.size + result.readableBytes) + return result + } + + /// Gets an `Integer` from `self` and gets a slice of that length from `self` and returns it. + /// + /// - Parameters: + /// - endianness: The endianness of the length prefix `Integer` in this `ByteBuffer` (defaults to big endian). + /// - integer: the desired `Integer` type used to get the length prefix + /// - Returns: `nil` if the length prefix could not be read, + /// the length prefix is negative or + /// the buffer does not contain enough bytes to read a message of this length. + /// Otherwise the message after the length prefix. + @inlinable + public func getLengthPrefixedSlice( + at index: Int, + endianness: Endianness = .big, + as integer: Integer.Type + ) -> ByteBuffer? where Integer: FixedWidthInteger { + guard let lengthPrefix = self.getInteger(at: index, endianness: endianness, as: Integer.self), + let messageLength = Int(exactly: lengthPrefix), + let messageBuffer = self.getSlice(at: index + MemoryLayout.size, length: messageLength) + else { + return nil + } + + return messageBuffer + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-multi-int.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-multi-int.swift new file mode 100644 index 00000000..d602d947 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-multi-int.swift @@ -0,0 +1,2034 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// NOTE: THIS FILE IS AUTO-GENERATED BY dev/generate-bytebuffer-multi-int.sh + +extension ByteBuffer { + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2).Type = (T1, T2).self) -> (T1, T2)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, endianness: Endianness = .big, as: (T1, T2).Type = (T1, T2).self) -> Int { + var v1: T1 + var v2: T2 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3).Type = (T1, T2, T3).self) -> (T1, T2, T3)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, endianness: Endianness = .big, as: (T1, T2, T3).Type = (T1, T2, T3).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4).Type = (T1, T2, T3, T4).self) -> (T1, T2, T3, T4)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, endianness: Endianness = .big, as: (T1, T2, T3, T4).Type = (T1, T2, T3, T4).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5).Type = (T1, T2, T3, T4, T5).self) -> (T1, T2, T3, T4, T5)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5).Type = (T1, T2, T3, T4, T5).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6).Type = (T1, T2, T3, T4, T5, T6).self) -> (T1, T2, T3, T4, T5, T6)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6).Type = (T1, T2, T3, T4, T5, T6).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7).Type = (T1, T2, T3, T4, T5, T6, T7).self) -> (T1, T2, T3, T4, T5, T6, T7)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7).Type = (T1, T2, T3, T4, T5, T6, T7).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8).Type = (T1, T2, T3, T4, T5, T6, T7, T8).self) -> (T1, T2, T3, T4, T5, T6, T7, T8)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8).Type = (T1, T2, T3, T4, T5, T6, T7, T8).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var v11: T11 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v11) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10), T11(bigEndian: v11)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10), T11(littleEndian: v11)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, _ value11: T11, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + var v11: T11 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + v11 = value11.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + v11 = value11.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v11, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var v11: T11 = 0 + var v12: T12 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v11) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v12) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10), T11(bigEndian: v11), T12(bigEndian: v12)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10), T11(littleEndian: v11), T12(littleEndian: v12)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, _ value11: T11, _ value12: T12, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + var v11: T11 + var v12: T12 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + v11 = value11.bigEndian + v12 = value12.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + v11 = value11.littleEndian + v12 = value12.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v11, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v12, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var v11: T11 = 0 + var v12: T12 = 0 + var v13: T13 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v11) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v12) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v13) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10), T11(bigEndian: v11), T12(bigEndian: v12), T13(bigEndian: v13)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10), T11(littleEndian: v11), T12(littleEndian: v12), T13(littleEndian: v13)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, _ value11: T11, _ value12: T12, _ value13: T13, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + var v11: T11 + var v12: T12 + var v13: T13 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + v11 = value11.bigEndian + v12 = value12.bigEndian + v13 = value13.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + v11 = value11.littleEndian + v12 = value12.littleEndian + v13 = value13.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v11, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v12, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v13, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var v11: T11 = 0 + var v12: T12 = 0 + var v13: T13 = 0 + var v14: T14 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v11) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v12) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v13) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v14) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10), T11(bigEndian: v11), T12(bigEndian: v12), T13(bigEndian: v13), T14(bigEndian: v14)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10), T11(littleEndian: v11), T12(littleEndian: v12), T13(littleEndian: v13), T14(littleEndian: v14)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, _ value11: T11, _ value12: T12, _ value13: T13, _ value14: T14, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + var v11: T11 + var v12: T12 + var v13: T13 + var v14: T14 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + v11 = value11.bigEndian + v12 = value12.bigEndian + v13 = value13.bigEndian + v14 = value14.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + v11 = value11.littleEndian + v12 = value12.littleEndian + v13 = value13.littleEndian + v14 = value14.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v11, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v12, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v13, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v14, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + + @inlinable + @_alwaysEmitIntoClient + public mutating func readMultipleIntegers(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15).self) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)? { + var bytesRequired: Int = MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + bytesRequired &+= MemoryLayout.size + + guard self.readableBytes >= bytesRequired else { + return nil + } + + var v1: T1 = 0 + var v2: T2 = 0 + var v3: T3 = 0 + var v4: T4 = 0 + var v5: T5 = 0 + var v6: T6 = 0 + var v7: T7 = 0 + var v8: T8 = 0 + var v9: T9 = 0 + var v10: T10 = 0 + var v11: T11 = 0 + var v12: T12 = 0 + var v13: T13 = 0 + var v14: T14 = 0 + var v15: T15 = 0 + var offset = 0 + self.readWithUnsafeReadableBytes { ptr -> Int in + assert(ptr.count >= bytesRequired) + let basePtr = ptr.baseAddress! // safe, ptr is non-empty + withUnsafeMutableBytes(of: &v1) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v2) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v3) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v4) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v5) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v6) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v7) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v8) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v9) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v10) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v11) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v12) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v13) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v14) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + withUnsafeMutableBytes(of: &v15) { destPtr in + destPtr.baseAddress!.copyMemory(from: basePtr + offset, byteCount: MemoryLayout.size) + } + offset = offset &+ MemoryLayout.size + assert(offset == bytesRequired) + return offset + } + switch endianness { + case .big: + return (T1(bigEndian: v1), T2(bigEndian: v2), T3(bigEndian: v3), T4(bigEndian: v4), T5(bigEndian: v5), T6(bigEndian: v6), T7(bigEndian: v7), T8(bigEndian: v8), T9(bigEndian: v9), T10(bigEndian: v10), T11(bigEndian: v11), T12(bigEndian: v12), T13(bigEndian: v13), T14(bigEndian: v14), T15(bigEndian: v15)) + case .little: + return (T1(littleEndian: v1), T2(littleEndian: v2), T3(littleEndian: v3), T4(littleEndian: v4), T5(littleEndian: v5), T6(littleEndian: v6), T7(littleEndian: v7), T8(littleEndian: v8), T9(littleEndian: v9), T10(littleEndian: v10), T11(littleEndian: v11), T12(littleEndian: v12), T13(littleEndian: v13), T14(littleEndian: v14), T15(littleEndian: v15)) + } + } + + @inlinable + @_alwaysEmitIntoClient + @discardableResult + public mutating func writeMultipleIntegers(_ value1: T1, _ value2: T2, _ value3: T3, _ value4: T4, _ value5: T5, _ value6: T6, _ value7: T7, _ value8: T8, _ value9: T9, _ value10: T10, _ value11: T11, _ value12: T12, _ value13: T13, _ value14: T14, _ value15: T15, endianness: Endianness = .big, as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15).self) -> Int { + var v1: T1 + var v2: T2 + var v3: T3 + var v4: T4 + var v5: T5 + var v6: T6 + var v7: T7 + var v8: T8 + var v9: T9 + var v10: T10 + var v11: T11 + var v12: T12 + var v13: T13 + var v14: T14 + var v15: T15 + switch endianness { + case .big: + v1 = value1.bigEndian + v2 = value2.bigEndian + v3 = value3.bigEndian + v4 = value4.bigEndian + v5 = value5.bigEndian + v6 = value6.bigEndian + v7 = value7.bigEndian + v8 = value8.bigEndian + v9 = value9.bigEndian + v10 = value10.bigEndian + v11 = value11.bigEndian + v12 = value12.bigEndian + v13 = value13.bigEndian + v14 = value14.bigEndian + v15 = value15.bigEndian + case .little: + v1 = value1.littleEndian + v2 = value2.littleEndian + v3 = value3.littleEndian + v4 = value4.littleEndian + v5 = value5.littleEndian + v6 = value6.littleEndian + v7 = value7.littleEndian + v8 = value8.littleEndian + v9 = value9.littleEndian + v10 = value10.littleEndian + v11 = value11.littleEndian + v12 = value12.littleEndian + v13 = value13.littleEndian + v14 = value14.littleEndian + v15 = value15.littleEndian + } + + var spaceNeeded: Int = MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + spaceNeeded &+= MemoryLayout.size + + return self.writeWithUnsafeMutableBytes(minimumWritableBytes: spaceNeeded) { ptr -> Int in + assert(ptr.count >= spaceNeeded) + var offset = 0 + let basePtr = ptr.baseAddress! // safe: pointer is non zero length + (basePtr + offset).copyMemory(from: &v1, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v2, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v3, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v4, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v5, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v6, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v7, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v8, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v9, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v10, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v11, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v12, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v13, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v14, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + (basePtr + offset).copyMemory(from: &v15, byteCount: MemoryLayout.size) + offset = offset &+ MemoryLayout.size + assert(offset == spaceNeeded) + return offset + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-views.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-views.swift new file mode 100644 index 00000000..101198a2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ByteBuffer-views.swift @@ -0,0 +1,256 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A view into a portion of a `ByteBuffer`. +/// +/// A `ByteBufferView` is useful whenever a `Collection where Element == UInt8` representing a portion of a +/// `ByteBuffer` is needed. +public struct ByteBufferView: RandomAccessCollection { + public typealias Element = UInt8 + public typealias Index = Int + public typealias SubSequence = ByteBufferView + + /* private but usableFromInline */ @usableFromInline var _buffer: ByteBuffer + /* private but usableFromInline */ @usableFromInline var _range: Range + + @inlinable + internal init(buffer: ByteBuffer, range: Range) { + precondition(range.lowerBound >= 0 && range.upperBound <= buffer.capacity) + self._buffer = buffer + self._range = range + } + + /// Creates a `ByteBufferView` from the readable bytes of the given `buffer`. + @inlinable + public init(_ buffer: ByteBuffer) { + self = ByteBufferView(buffer: buffer, range: buffer.readerIndex ..< buffer.writerIndex) + } + + @inlinable + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try self._buffer.withVeryUnsafeBytes { ptr in + try body(UnsafeRawBufferPointer(start: ptr.baseAddress!.advanced(by: self._range.lowerBound), + count: self._range.count)) + } + } + + @inlinable + public var startIndex: Index { + return self._range.lowerBound + } + + @inlinable + public var endIndex: Index { + return self._range.upperBound + } + + @inlinable + public func index(after i: Index) -> Index { + return i + 1 + } + + @inlinable + public var count: Int { + // Unchecked is safe here: Range enforces that upperBound is strictly greater than + // lower bound, and we guarantee that _range.lowerBound >= 0. + return self._range.upperBound &- self._range.lowerBound + } + + @inlinable + public subscript(position: Index) -> UInt8 { + get { + guard position >= self._range.lowerBound && position < self._range.upperBound else { + preconditionFailure("index \(position) out of range") + } + return self._buffer.getInteger(at: position)! // range check above + } + set { + guard position >= self._range.lowerBound && position < self._range.upperBound else { + preconditionFailure("index \(position) out of range") + } + self._buffer.setInteger(newValue, at: position) + } + } + + @inlinable + public subscript(range: Range) -> ByteBufferView { + get { + return ByteBufferView(buffer: self._buffer, range: range) + } + set { + self.replaceSubrange(range, with: newValue) + } + } + + @inlinable + public func withContiguousStorageIfAvailable(_ body: (UnsafeBufferPointer) throws -> R) rethrows -> R? { + return try self.withUnsafeBytes { bytes in + return try body(bytes.bindMemory(to: UInt8.self)) + } + } + + @inlinable + public func _customIndexOfEquatableElement(_ element : Element) -> Index?? { + return .some(self.withUnsafeBytes { ptr -> Index? in + return ptr.firstIndex(of: element).map { $0 + self._range.lowerBound } + }) + } + + @inlinable + public func _customLastIndexOfEquatableElement(_ element: Element) -> Index?? { + return .some(self.withUnsafeBytes { ptr -> Index? in + return ptr.lastIndex(of: element).map { $0 + self._range.lowerBound } + }) + } + + @inlinable + public func _customContainsEquatableElement(_ element: Element) -> Bool? { + return .some(self.withUnsafeBytes { ptr -> Bool in + return ptr.contains(element) + }) + } + + @inlinable + public func _copyContents( + initializing ptr: UnsafeMutableBufferPointer + ) -> (Iterator, UnsafeMutableBufferPointer.Index) { + precondition(ptr.count >= self.count) + + let bytesToWrite = self.count + + let endIndex = self.withContiguousStorageIfAvailable { ourBytes in + ptr.initialize(from: ourBytes).1 + } + precondition(endIndex == bytesToWrite) + + let iterator = self[self.endIndex..(_ subrange: Range, with newElements: C) where ByteBufferView.Element == C.Element { + precondition(subrange.startIndex >= self.startIndex && subrange.endIndex <= self.endIndex, + "subrange out of bounds") + + if newElements.count == subrange.count { + self._buffer.setBytes(newElements, at: subrange.startIndex) + } else if newElements.count < subrange.count { + // Replace the subrange. + self._buffer.setBytes(newElements, at: subrange.startIndex) + + // Remove the unwanted bytes between the newly copied bytes and the end of the subrange. + // try! is fine here: the copied range is within the view and the length can't be negative. + try! self._buffer.copyBytes(at: subrange.endIndex, + to: subrange.startIndex.advanced(by: newElements.count), + length: subrange.endIndex.distance(to: self._buffer.writerIndex)) + + // Shorten the range. + let removedBytes = subrange.count - newElements.count + self._buffer.moveWriterIndex(to: self._buffer.writerIndex - removedBytes) + self._range = self._range.dropLast(removedBytes) + } else { + // Make space for the new elements. + // try! is fine here: the copied range is within the view and the length can't be negative. + try! self._buffer.copyBytes(at: subrange.endIndex, + to: subrange.startIndex.advanced(by: newElements.count), + length: subrange.endIndex.distance(to: self._buffer.writerIndex)) + + // Replace the bytes. + self._buffer.setBytes(newElements, at: subrange.startIndex) + + // Widen the range. + let additionalByteCount = newElements.count - subrange.count + self._buffer.moveWriterIndex(forwardBy: additionalByteCount) + self._range = self._range.startIndex ..< self._range.endIndex.advanced(by: additionalByteCount) + + } + } +} + +extension ByteBuffer { + /// A view into the readable bytes of the `ByteBuffer`. + @inlinable + public var readableBytesView: ByteBufferView { + return ByteBufferView(self) + } + + /// Returns a view into some portion of the readable bytes of a `ByteBuffer`. + /// + /// - parameters: + /// - index: The index the view should start at + /// - length: The length of the view (in bytes) + /// - returns: A view into a portion of a `ByteBuffer` or `nil` if the requested bytes were not readable. + @inlinable + public func viewBytes(at index: Int, length: Int) -> ByteBufferView? { + guard length >= 0 && index >= self.readerIndex && index <= self.writerIndex - length else { + return nil + } + + return ByteBufferView(buffer: self, range: index ..< (index + length)) + } + + /// Create a `ByteBuffer` from the given `ByteBufferView`s range. + /// + /// - parameter view: The `ByteBufferView` which you want to get a `ByteBuffer` from. + @inlinable + public init(_ view: ByteBufferView) { + self = view._buffer.getSlice(at: view.startIndex, length: view.count)! + } +} + +extension ByteBufferView: Equatable { + /// required by `Equatable` + @inlinable + public static func == (lhs: ByteBufferView, rhs: ByteBufferView) -> Bool { + + guard lhs._range.count == rhs._range.count else { + return false + } + + // A well-formed ByteBufferView can never have a range that is out-of-bounds of the backing ByteBuffer. + // As a result, these getSlice calls can never fail, and we'd like to know it if they do. + let leftBufferSlice = lhs._buffer.getSlice(at: lhs._range.startIndex, length: lhs._range.count)! + let rightBufferSlice = rhs._buffer.getSlice(at: rhs._range.startIndex, length: rhs._range.count)! + + return leftBufferSlice == rightBufferSlice + } +} + +extension ByteBufferView: Hashable { + /// required by `Hashable` + @inlinable + public func hash(into hasher: inout Hasher) { + // A well-formed ByteBufferView can never have a range that is out-of-bounds of the backing ByteBuffer. + // As a result, this getSlice call can never fail, and we'd like to know it if it does. + hasher.combine(self._buffer.getSlice(at: self._range.startIndex, length: self._range.count)!) + } +} + +extension ByteBufferView: ExpressibleByArrayLiteral { + /// required by `ExpressibleByArrayLiteral` + @inlinable + public init(arrayLiteral elements: Element...) { + self.init(elements) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Channel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Channel.swift new file mode 100644 index 00000000..5c48771c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Channel.swift @@ -0,0 +1,397 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOConcurrencyHelpers + +/// The core `Channel` methods that are for internal use of the `Channel` implementation only. +/// +/// - warning: If you are not implementing a custom `Channel` type, you should never call any of these. +/// +/// - note: All methods must be called from the `EventLoop` thread. +public protocol ChannelCore: AnyObject { + /// Returns the local bound `SocketAddress`. + func localAddress0() throws -> SocketAddress + + /// Return the connected `SocketAddress`. + func remoteAddress0() throws -> SocketAddress + + /// Register with the `EventLoop` to receive I/O notifications. + /// + /// - parameters: + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func register0(promise: EventLoopPromise?) + + /// Register channel as already connected or bound socket. + /// - parameters: + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func registerAlreadyConfigured0(promise: EventLoopPromise?) + + /// Bind to a `SocketAddress`. + /// + /// - parameters: + /// - to: The `SocketAddress` to which we should bind the `Channel`. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func bind0(to: SocketAddress, promise: EventLoopPromise?) + + /// Connect to a `SocketAddress`. + /// + /// - parameters: + /// - to: The `SocketAddress` to which we should connect the `Channel`. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func connect0(to: SocketAddress, promise: EventLoopPromise?) + + /// Write the given data to the outbound buffer. + /// + /// - parameters: + /// - data: The data to write, wrapped in a `NIOAny`. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func write0(_ data: NIOAny, promise: EventLoopPromise?) + + /// Try to flush out all previous written messages that are pending. + func flush0() + + /// Request that the `Channel` perform a read when data is ready. + func read0() + + /// Close the `Channel`. + /// + /// - parameters: + /// - error: The `Error` which will be used to fail any pending writes. + /// - mode: The `CloseMode` to apply. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) + + /// Trigger an outbound event. + /// + /// - parameters: + /// - event: The triggered event. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) + + /// Called when data was read from the `Channel` but it was not consumed by any `ChannelInboundHandler` in the `ChannelPipeline`. + /// + /// - parameters: + /// - data: The data that was read, wrapped in a `NIOAny`. + func channelRead0(_ data: NIOAny) + + /// Called when an inbound error was encountered but was not consumed by any `ChannelInboundHandler` in the `ChannelPipeline`. + /// + /// - parameters: + /// - error: The `Error` that was encountered. + func errorCaught0(error: Error) +} + +/// A `Channel` is easiest thought of as a network socket. But it can be anything that is capable of I/O operations such +/// as read, write, connect, and bind. +/// +/// - note: All operations on `Channel` are thread-safe. +/// +/// In SwiftNIO, all I/O operations are asynchronous and hence all operations on `Channel` are asynchronous too. This means +/// that all I/O operations will return immediately, usually before the work has been completed. The `EventLoopPromise`s +/// passed to or returned by the operations are used to retrieve the result of an operation after it has completed. +/// +/// A `Channel` owns its `ChannelPipeline` which handles all I/O events and requests associated with the `Channel`. +public protocol Channel: AnyObject, ChannelOutboundInvoker { + /// The `Channel`'s `ByteBuffer` allocator. This is _the only_ supported way of allocating `ByteBuffer`s to be used with this `Channel`. + var allocator: ByteBufferAllocator { get } + + /// The `closeFuture` will fire when the `Channel` has been closed. + var closeFuture: EventLoopFuture { get } + + /// The `ChannelPipeline` which handles all I/O events and requests associated with this `Channel`. + var pipeline: ChannelPipeline { get } + + /// The local `SocketAddress`. + var localAddress: SocketAddress? { get } + + /// The remote peer's `SocketAddress`. + var remoteAddress: SocketAddress? { get } + + /// `Channel`s are hierarchical and might have a parent `Channel`. `Channel` hierarchies are in use for certain + /// protocols such as HTTP/2. + var parent: Channel? { get } + + /// Set `option` to `value` on this `Channel`. + func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture + + /// Get the value of `option` for this `Channel`. + func getOption(_ option: Option) -> EventLoopFuture + + /// Returns if this `Channel` is currently writable. + var isWritable: Bool { get } + + /// Returns if this `Channel` is currently active. Active is defined as the period of time after the + /// `channelActive` and before `channelInactive` has fired. The main use for this is to know if `channelActive` + /// or `channelInactive` can be expected next when `handlerAdded` was received. + var isActive: Bool { get } + + /// Reach out to the `_ChannelCore`. + /// + /// - warning: Unsafe, this is for use in NIO's core only. + var _channelCore: ChannelCore { get } + + /// Returns a view of the `Channel` exposing synchronous versions of `setOption` and `getOption`. + /// The default implementation returns `nil`, and `Channel` implementations must opt in to + /// support this behavior. + var syncOptions: NIOSynchronousChannelOptions? { get } +} + +extension Channel { + /// Default implementation: `NIOSynchronousChannelOptions` are not supported. + public var syncOptions: NIOSynchronousChannelOptions? { + return nil + } +} + +public protocol NIOSynchronousChannelOptions { + /// Set `option` to `value` on this `Channel`. + /// + /// - Important: Must be called on the `EventLoop` the `Channel` is running on. + func setOption(_ option: Option, value: Option.Value) throws + + /// Get the value of `option` for this `Channel`. + /// + /// - Important: Must be called on the `EventLoop` the `Channel` is running on. + func getOption(_ option: Option) throws -> Option.Value +} + +/// Default implementations which will start on the head of the `ChannelPipeline`. +extension Channel { + + public func bind(to address: SocketAddress, promise: EventLoopPromise?) { + pipeline.bind(to: address, promise: promise) + } + + public func connect(to address: SocketAddress, promise: EventLoopPromise?) { + pipeline.connect(to: address, promise: promise) + } + + public func write(_ data: NIOAny, promise: EventLoopPromise?) { + pipeline.write(data, promise: promise) + } + + public func flush() { + pipeline.flush() + } + + public func writeAndFlush(_ data: NIOAny, promise: EventLoopPromise?) { + pipeline.writeAndFlush(data, promise: promise) + } + + public func read() { + pipeline.read() + } + + public func close(mode: CloseMode = .all, promise: EventLoopPromise?) { + pipeline.close(mode: mode, promise: promise) + } + + public func register(promise: EventLoopPromise?) { + pipeline.register(promise: promise) + } + + public func registerAlreadyConfigured0(promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + public func triggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) { + pipeline.triggerUserOutboundEvent(event, promise: promise) + } +} + + +/// Provides special extension to make writing data to the `Channel` easier by removing the need to wrap data in `NIOAny` manually. +extension Channel { + + /// Write data into the `Channel`, automatically wrapping with `NIOAny`. + /// + /// - seealso: `ChannelOutboundInvoker.write`. + public func write(_ any: T) -> EventLoopFuture { + return self.write(NIOAny(any)) + } + + /// Write data into the `Channel`, automatically wrapping with `NIOAny`. + /// + /// - seealso: `ChannelOutboundInvoker.write`. + public func write(_ any: T, promise: EventLoopPromise?) { + self.write(NIOAny(any), promise: promise) + } + + /// Write and flush data into the `Channel`, automatically wrapping with `NIOAny`. + /// + /// - seealso: `ChannelOutboundInvoker.writeAndFlush`. + public func writeAndFlush(_ any: T) -> EventLoopFuture { + return self.writeAndFlush(NIOAny(any)) + } + + + /// Write and flush data into the `Channel`, automatically wrapping with `NIOAny`. + /// + /// - seealso: `ChannelOutboundInvoker.writeAndFlush`. + public func writeAndFlush(_ any: T, promise: EventLoopPromise?) { + self.writeAndFlush(NIOAny(any), promise: promise) + } +} + +extension ChannelCore { + /// Unwraps the given `NIOAny` as a specific concrete type. + /// + /// This method is intended for use when writing custom `ChannelCore` implementations. + /// This can safely be called in methods like `write0` to extract data from the `NIOAny` + /// provided in those cases. + /// + /// Note that if the unwrap fails, this will cause a runtime trap. `ChannelCore` + /// implementations should be concrete about what types they support writing. If multiple + /// types are supported, consider using a tagged union to store the type information like + /// NIO's own `IOData`, which will minimise the amount of runtime type checking. + /// + /// - parameters: + /// - data: The `NIOAny` to unwrap. + /// - as: The type to extract from the `NIOAny`. + /// - returns: The content of the `NIOAny`. + @inlinable + public func unwrapData(_ data: NIOAny, as: T.Type = T.self) -> T { + return data.forceAs() + } + + /// Attempts to unwrap the given `NIOAny` as a specific concrete type. + /// + /// This method is intended for use when writing custom `ChannelCore` implementations. + /// This can safely be called in methods like `write0` to extract data from the `NIOAny` + /// provided in those cases. + /// + /// If the unwrap fails, this will return `nil`. `ChannelCore` implementations should almost + /// always support only one runtime type, so in general they should avoid using this and prefer + /// using `unwrapData` instead. This method exists for rare use-cases where tolerating type + /// mismatches is acceptable. + /// + /// - parameters: + /// - data: The `NIOAny` to unwrap. + /// - as: The type to extract from the `NIOAny`. + /// - returns: The content of the `NIOAny`, or `nil` if the type is incorrect. + /// - warning: If you are implementing a `ChannelCore`, you should use `unwrapData` unless you + /// are doing something _extremely_ unusual. + @inlinable + public func tryUnwrapData(_ data: NIOAny, as: T.Type = T.self) -> T? { + return data.tryAs() + } + + /// Removes the `ChannelHandler`s from the `ChannelPipeline` belonging to `channel`, and + /// closes that `ChannelPipeline`. + /// + /// This method is intended for use when writing custom `ChannelCore` implementations. + /// This can be called from `close0` to tear down the `ChannelPipeline` when closure is + /// complete. + /// + /// - parameters: + /// - channel: The `Channel` whose `ChannelPipeline` will be closed. + @available(*, deprecated, renamed: "removeHandlers(pipeline:)") + public func removeHandlers(channel: Channel) { + self.removeHandlers(pipeline: channel.pipeline) + } + + /// Removes the `ChannelHandler`s from the `ChannelPipeline` `pipeline`, and + /// closes that `ChannelPipeline`. + /// + /// This method is intended for use when writing custom `ChannelCore` implementations. + /// This can be called from `close0` to tear down the `ChannelPipeline` when closure is + /// complete. + /// + /// - parameters: + /// - pipeline: The `ChannelPipline` to be closed. + public func removeHandlers(pipeline: ChannelPipeline) { + pipeline.removeHandlers() + } +} + +/// An error that can occur on `Channel` operations. +public enum ChannelError: Error { + /// Tried to connect on a `Channel` that is already connecting. + case connectPending + + /// Connect operation timed out + case connectTimeout(TimeAmount) + + /// Unsupported operation triggered on a `Channel`. For example `connect` on a `ServerSocketChannel`. + case operationUnsupported + + /// An I/O operation (e.g. read/write/flush) called on a channel that is already closed. + case ioOnClosedChannel + + /// Close was called on a channel that is already closed. + case alreadyClosed + + /// Output-side of the channel is closed. + case outputClosed + + /// Input-side of the channel is closed. + case inputClosed + + /// A read operation reached end-of-file. This usually means the remote peer closed the socket but it's still + /// open locally. + case eof + + /// A `DatagramChannel` `write` was made with a buffer that is larger than the MTU for the connection, and so the + /// datagram was not written. Either shorten the datagram or manually fragment, and then try again. + case writeMessageTooLarge + + /// A `DatagramChannel` `write` was made with an address that was not reachable and so could not be delivered. + case writeHostUnreachable + + /// The local address of the `Channel` could not be determined. + case unknownLocalAddress + + /// The address family of the multicast group was not valid for this `Channel`. + case badMulticastGroupAddressFamily + + /// The address family of the provided multicast group join is not valid for this `Channel`. + case badInterfaceAddressFamily + + /// An attempt was made to join a multicast group that does not correspond to a multicast + /// address. + case illegalMulticastAddress(SocketAddress) + + /// Multicast is not supported on Interface + @available(*, deprecated, renamed: "NIOMulticastNotSupportedError") + case multicastNotSupported(NIONetworkInterface) + + /// An operation that was inappropriate given the current `Channel` state was attempted. + case inappropriateOperationForState + + /// An attempt was made to remove a ChannelHandler that is not removable. + case unremovableHandler +} + +extension ChannelError: Equatable { } + +/// The removal of a `ChannelHandler` using `ChannelPipeline.removeHandler` has been attempted more than once. +public struct NIOAttemptedToRemoveHandlerMultipleTimesError: Error {} + +/// An `Channel` related event that is passed through the `ChannelPipeline` to notify the user. +public enum ChannelEvent: Equatable { + /// `ChannelOptions.allowRemoteHalfClosure` is `true` and input portion of the `Channel` was closed. + case inputClosed + /// Output portion of the `Channel` was closed. + case outputClosed +} + +/// A `Channel` user event that is sent when the `Channel` has been asked to quiesce. +/// +/// The action(s) that should be taken after receiving this event are both application and protocol dependent. If the +/// protocol supports a notion of requests and responses, it might make sense to stop accepting new requests but finish +/// processing the request currently in flight. +public struct ChannelShouldQuiesceEvent { + public init() { + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandler.swift new file mode 100644 index 00000000..575b0575 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandler.swift @@ -0,0 +1,345 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// Base protocol for handlers that handle I/O events or intercept an I/O operation. +/// +/// All methods are called from within the `EventLoop` that is assigned to the `Channel` itself. +// +/// You should _never_ implement this protocol directly. Please implement one of its sub-protocols. +public protocol ChannelHandler: AnyObject { + /// Called when this `ChannelHandler` is added to the `ChannelPipeline`. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func handlerAdded(context: ChannelHandlerContext) + + /// Called when this `ChannelHandler` is removed from the `ChannelPipeline`. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func handlerRemoved(context: ChannelHandlerContext) +} + +/// Untyped `ChannelHandler` which handles outbound I/O events or intercept an outbound I/O operation. +/// +/// Despite the fact that `write` is one of the methods on this `protocol`, you should avoid assuming that "outbound" events are to do with +/// writing to channel sources. Instead, "outbound" events are events that are passed *to* the channel source (e.g. a socket): that is, things you tell +/// the channel source to do. That includes `write` ("write this data to the channel source"), but it also includes `read` ("please begin attempting to read from +/// the channel source") and `bind` ("please bind the following address"), which have nothing to do with sending data. +/// +/// We _strongly_ advise against implementing this protocol directly. Please implement `ChannelOutboundHandler`. +public protocol _ChannelOutboundHandler: ChannelHandler { + + /// Called to request that the `Channel` register itself for I/O events with its `EventLoop`. + /// This should call `context.register` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func register(context: ChannelHandlerContext, promise: EventLoopPromise?) + + /// Called to request that the `Channel` bind to a specific `SocketAddress`. + /// + /// This should call `context.bind` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - to: The `SocketAddress` to which this `Channel` should bind. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func bind(context: ChannelHandlerContext, to: SocketAddress, promise: EventLoopPromise?) + + /// Called to request that the `Channel` connect to a given `SocketAddress`. + /// + /// This should call `context.connect` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - to: The `SocketAddress` to which the the `Channel` should connect. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func connect(context: ChannelHandlerContext, to: SocketAddress, promise: EventLoopPromise?) + + /// Called to request a write operation. The write operation will write the messages through the + /// `ChannelPipeline`. Those are then ready to be flushed to the actual `Channel` when + /// `Channel.flush` or `ChannelHandlerContext.flush` is called. + /// + /// This should call `context.write` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - data: The data to write through the `Channel`, wrapped in a `NIOAny`. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) + + /// Called to request that the `Channel` flush all pending writes. The flush operation will try to flush out all previous written messages + /// that are pending. + /// + /// This should call `context.flush` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or just + /// discard it if the flush should be suppressed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func flush(context: ChannelHandlerContext) + + /// Called to request that the `Channel` perform a read when data is ready. The read operation will signal that we are ready to read more data. + /// + /// This should call `context.read` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or just + /// discard it if the read should be suppressed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func read(context: ChannelHandlerContext) + + /// Called to request that the `Channel` close itself down`. + /// + /// This should call `context.close` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - mode: The `CloseMode` to apply + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) + + /// Called when an user outbound event is triggered. + /// + /// This should call `context.triggerUserOutboundEvent` to forward the operation to the next `_ChannelOutboundHandler` in the `ChannelPipeline` or + /// complete the `EventLoopPromise` to let the caller know that the operation completed. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - event: The triggered event. + /// - promise: The `EventLoopPromise` which should be notified once the operation completes, or nil if no notification should take place. + func triggerUserOutboundEvent(context: ChannelHandlerContext, event: Any, promise: EventLoopPromise?) +} + +/// Untyped `ChannelHandler` which handles inbound I/O events. +/// +/// Despite the fact that `channelRead` is one of the methods on this `protocol`, you should avoid assuming that "inbound" events are to do with +/// reading from channel sources. Instead, "inbound" events are events that originate *from* the channel source (e.g. the socket): that is, events that the +/// channel source tells you about. This includes things like `channelRead` ("there is some data to read"), but it also includes things like +/// `channelWritabilityChanged` ("this source is no longer marked writable"). +/// +/// We _strongly_ advise against implementing this protocol directly. Please implement `ChannelInboundHandler`. +public protocol _ChannelInboundHandler: ChannelHandler { + + /// Called when the `Channel` has successfully registered with its `EventLoop` to handle I/O. + /// + /// This should call `context.fireChannelRegistered` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelRegistered(context: ChannelHandlerContext) + + /// Called when the `Channel` has unregistered from its `EventLoop`, and so will no longer be receiving I/O events. + /// + /// This should call `context.fireChannelUnregistered` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelUnregistered(context: ChannelHandlerContext) + + /// Called when the `Channel` has become active, and is able to send and receive data. + /// + /// This should call `context.fireChannelActive` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelActive(context: ChannelHandlerContext) + + /// Called when the `Channel` has become inactive and is no longer able to send and receive data`. + /// + /// This should call `context.fireChannelInactive` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelInactive(context: ChannelHandlerContext) + + /// Called when some data has been read from the remote peer. + /// + /// This should call `context.fireChannelRead` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - data: The data read from the remote peer, wrapped in a `NIOAny`. + func channelRead(context: ChannelHandlerContext, data: NIOAny) + + /// Called when the `Channel` has completed its current read loop, either because no more data is available to read from the transport at this time, or because the `Channel` needs to yield to the event loop to process other I/O events for other `Channel`s. + /// If `ChannelOptions.autoRead` is `false` no further read attempt will be made until `ChannelHandlerContext.read` or `Channel.read` is explicitly called. + /// + /// This should call `context.fireChannelReadComplete` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelReadComplete(context: ChannelHandlerContext) + + /// The writability state of the `Channel` has changed, either because it has buffered more data than the writability high water mark, or because the amount of buffered data has dropped below the writability low water mark. + /// You can check the state with `Channel.isWritable`. + /// + /// This should call `context.fireChannelWritabilityChanged` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + func channelWritabilityChanged(context: ChannelHandlerContext) + + /// Called when a user inbound event has been triggered. + /// + /// This should call `context.fireUserInboundEventTriggered` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the event. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - event: The event. + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) + + /// An error was encountered earlier in the inbound `ChannelPipeline`. + /// + /// This should call `context.fireErrorCaught` to forward the operation to the next `_ChannelInboundHandler` in the `ChannelPipeline` if you want to allow the next handler to also handle the error. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ChannelHandler` belongs to. + /// - error: The `Error` that was encountered. + func errorCaught(context: ChannelHandlerContext, error: Error) +} + +// Default implementations for the ChannelHandler protocol +extension ChannelHandler { + + /// Do nothing by default. + public func handlerAdded(context: ChannelHandlerContext) { + } + + /// Do nothing by default. + public func handlerRemoved(context: ChannelHandlerContext) { + } +} + +/// Provides default implementations for all methods defined by `_ChannelOutboundHandler`. +/// +/// These default implementations will just call `context.methodName` to forward to the next `_ChannelOutboundHandler` in +/// the `ChannelPipeline` until the operation is handled by the `Channel` itself. +extension _ChannelOutboundHandler { + + public func register(context: ChannelHandlerContext, promise: EventLoopPromise?) { + context.register(promise: promise) + } + + public func bind(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + context.bind(to: address, promise: promise) + } + + public func connect(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + context.connect(to: address, promise: promise) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + context.write(data, promise: promise) + } + + public func flush(context: ChannelHandlerContext) { + context.flush() + } + + public func read(context: ChannelHandlerContext) { + context.read() + } + + public func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + context.close(mode: mode, promise: promise) + } + + public func triggerUserOutboundEvent(context: ChannelHandlerContext, event: Any, promise: EventLoopPromise?) { + context.triggerUserOutboundEvent(event, promise: promise) + } +} + +/// Provides default implementations for all methods defined by `_ChannelInboundHandler`. +/// +/// These default implementations will just `context.fire*` to forward to the next `_ChannelInboundHandler` in +/// the `ChannelPipeline` until the operation is handled by the `Channel` itself. +extension _ChannelInboundHandler { + + public func channelRegistered(context: ChannelHandlerContext) { + context.fireChannelRegistered() + } + + public func channelUnregistered(context: ChannelHandlerContext) { + context.fireChannelUnregistered() + } + + public func channelActive(context: ChannelHandlerContext) { + context.fireChannelActive() + } + + public func channelInactive(context: ChannelHandlerContext) { + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + context.fireChannelRead(data) + } + + public func channelReadComplete(context: ChannelHandlerContext) { + context.fireChannelReadComplete() + } + + public func channelWritabilityChanged(context: ChannelHandlerContext) { + context.fireChannelWritabilityChanged() + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + context.fireUserInboundEventTriggered(event) + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + context.fireErrorCaught(error) + } +} + +/// A `RemovableChannelHandler` is a `ChannelHandler` that can be dynamically removed from a `ChannelPipeline` whilst +/// the `Channel` is operating normally. +/// A `RemovableChannelHandler` is required to remove itself from the `ChannelPipeline` (using +/// `ChannelHandlerContext.removeHandler`) as soon as possible. +/// +/// - note: When a `Channel` gets torn down, every `ChannelHandler` in the `Channel`'s `ChannelPipeline` will be +/// removed from the `ChannelPipeline`. Those removals however happen synchronously and are not going through +/// the methods of this protocol. +public protocol RemovableChannelHandler: ChannelHandler { + /// Ask the receiving `RemovableChannelHandler` to remove itself from the `ChannelPipeline` as soon as possible. + /// The receiving `RemovableChannelHandler` may elect to remove itself sometime after this method call, rather than + /// immediately, but if it does so it must take the necessary precautions to handle events arriving between the + /// invocation of this method and the call to `ChannelHandlerContext.removeHandler` that triggers the actual + /// removal. + /// + /// - note: Like the other `ChannelHandler` methods, this method should not be invoked by the user directly. To + /// remove a `RemovableChannelHandler` from the `ChannelPipeline`, use `ChannelPipeline.remove`. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` of the `RemovableChannelHandler` to be removed from the `ChannelPipeline`. + /// - removalToken: The removal token to hand to `ChannelHandlerContext.removeHandler` to trigger the actual + /// removal from the `ChannelPipeline`. + func removeHandler(context: ChannelHandlerContext, removalToken: ChannelHandlerContext.RemovalToken) +} + +extension RemovableChannelHandler { + // Implements the default behaviour which is to synchronously remove the handler from the pipeline. Thanks to this, + // stateless `ChannelHandler`s can just use `RemovableChannelHandler` as a marker-protocol and declare themselves + // as removable without writing any extra code. + public func removeHandler(context: ChannelHandlerContext, removalToken: ChannelHandlerContext.RemovalToken) { + precondition(context.handler === self) + context.leavePipeline(removalToken: removalToken) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandlers.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandlers.swift new file mode 100644 index 00000000..38e35259 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelHandlers.swift @@ -0,0 +1,338 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +// Contains ChannelHandler implementations which are generic and can be re-used easily. +// +// + + +/// A `ChannelHandler` that implements a backoff for a `ServerChannel` when accept produces an `IOError`. +/// These errors are often recoverable by reducing the rate at which we call accept. +public final class AcceptBackoffHandler: ChannelDuplexHandler, RemovableChannelHandler { + public typealias InboundIn = Channel + public typealias OutboundIn = Channel + + private var nextReadDeadlineNS: Optional + private let backoffProvider: (IOError) -> TimeAmount? + private var scheduledRead: Optional> + + /// Default implementation used as `backoffProvider` which delays accept by 1 second. + public static func defaultBackoffProvider(error: IOError) -> TimeAmount? { + return .seconds(1) + } + + /// Create a new instance + /// + /// - parameters: + /// - backoffProvider: returns a `TimeAmount` which will be the amount of time to wait before attempting another `read`. + public init(backoffProvider: @escaping (IOError) -> TimeAmount? = AcceptBackoffHandler.defaultBackoffProvider) { + self.backoffProvider = backoffProvider + self.nextReadDeadlineNS = nil + self.scheduledRead = nil + } + + public func read(context: ChannelHandlerContext) { + // If we already have a read scheduled there is no need to schedule another one. + guard scheduledRead == nil else { return } + + if let deadline = self.nextReadDeadlineNS { + let now = NIODeadline.now() + if now >= deadline { + // The backoff already expired, just do a read. + doRead(context) + } else { + // Schedule the read to be executed after the backoff time elapsed. + scheduleRead(at: deadline, context: context) + } + } else { + context.read() + } + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + if let ioError = error as? IOError { + if let amount = backoffProvider(ioError) { + self.nextReadDeadlineNS = .now() + amount + if let scheduled = self.scheduledRead { + scheduled.cancel() + scheduleRead(at: self.nextReadDeadlineNS!, context: context) + } + } + } + context.fireErrorCaught(error) + } + + public func channelInactive(context: ChannelHandlerContext) { + if let scheduled = self.scheduledRead { + scheduled.cancel() + self.scheduledRead = nil + } + self.nextReadDeadlineNS = nil + context.fireChannelInactive() + } + + public func handlerRemoved(context: ChannelHandlerContext) { + if let scheduled = self.scheduledRead { + // Cancel the previous scheduled read and trigger a read directly. This is needed as otherwise we may never read again. + scheduled.cancel() + self.scheduledRead = nil + context.read() + } + self.nextReadDeadlineNS = nil + } + + private func scheduleRead(at: NIODeadline, context: ChannelHandlerContext) { + self.scheduledRead = context.eventLoop.scheduleTask(deadline: at) { + self.doRead(context) + } + } + + private func doRead(_ context: ChannelHandlerContext) { + // Reset the backoff time and read. + self.nextReadDeadlineNS = nil + self.scheduledRead = nil + context.read() + } +} + +/** + ChannelHandler implementation which enforces back-pressure by stopping to read from the remote peer when it cannot write back fast enough. + It will start reading again once pending data was written. +*/ +public final class BackPressureHandler: ChannelDuplexHandler, RemovableChannelHandler { + public typealias OutboundIn = NIOAny + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + public typealias OutboundOut = ByteBuffer + + private var pendingRead = false + private var writable: Bool = true + + public init() { } + + public func read(context: ChannelHandlerContext) { + if writable { + context.read() + } else { + pendingRead = true + } + } + + public func channelWritabilityChanged(context: ChannelHandlerContext) { + self.writable = context.channel.isWritable + if writable { + mayRead(context: context) + } else { + context.flush() + } + + // Propagate the event as the user may still want to do something based on it. + context.fireChannelWritabilityChanged() + } + + public func handlerRemoved(context: ChannelHandlerContext) { + mayRead(context: context) + } + + private func mayRead(context: ChannelHandlerContext) { + if pendingRead { + pendingRead = false + context.read() + } + } +} + +/// Triggers an IdleStateEvent when a Channel has not performed read, write, or both operation for a while. +public final class IdleStateHandler: ChannelDuplexHandler, RemovableChannelHandler { + public typealias InboundIn = NIOAny + public typealias InboundOut = NIOAny + public typealias OutboundIn = NIOAny + public typealias OutboundOut = NIOAny + + ///A user event triggered by IdleStateHandler when a Channel is idle. + public enum IdleStateEvent { + /// Will be triggered when no write was performed for the specified amount of time + case write + /// Will be triggered when no read was performed for the specified amount of time + case read + /// Will be triggered when neither read nor write was performed for the specified amount of time + case all + } + + public let readTimeout: TimeAmount? + public let writeTimeout: TimeAmount? + public let allTimeout: TimeAmount? + + private var reading = false + private var lastReadTime: NIODeadline = .distantPast + private var lastWriteCompleteTime: NIODeadline = .distantPast + private var scheduledReaderTask: Optional> + private var scheduledWriterTask: Optional> + private var scheduledAllTask: Optional> + + public init(readTimeout: TimeAmount? = nil, writeTimeout: TimeAmount? = nil, allTimeout: TimeAmount? = nil) { + self.readTimeout = readTimeout + self.writeTimeout = writeTimeout + self.allTimeout = allTimeout + self.scheduledAllTask = nil + self.scheduledReaderTask = nil + self.scheduledWriterTask = nil + } + + public func handlerAdded(context: ChannelHandlerContext) { + if context.channel.isActive { + initIdleTasks(context) + } + } + + public func handlerRemoved(context: ChannelHandlerContext) { + cancelIdleTasks(context) + } + + public func channelActive(context: ChannelHandlerContext) { + initIdleTasks(context) + context.fireChannelActive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + if readTimeout != nil || allTimeout != nil { + reading = true + } + context.fireChannelRead(data) + } + + public func channelReadComplete(context: ChannelHandlerContext) { + if (readTimeout != nil || allTimeout != nil) && reading { + lastReadTime = .now() + reading = false + } + context.fireChannelReadComplete() + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + if writeTimeout == nil && allTimeout == nil { + context.write(data, promise: promise) + return + } + + let writePromise = promise ?? context.eventLoop.makePromise() + writePromise.futureResult.whenComplete { (_: Result) in + self.lastWriteCompleteTime = .now() + } + context.write(data, promise: writePromise) + } + + private func shouldReschedule(_ context: ChannelHandlerContext) -> Bool { + if context.channel.isActive { + return true + } + return false + } + + private func makeReadTimeoutTask(_ context: ChannelHandlerContext, _ timeout: TimeAmount) -> (() -> Void) { + return { + guard self.shouldReschedule(context) else { + return + } + + if self.reading { + self.scheduledReaderTask = context.eventLoop.scheduleTask(in: timeout, self.makeReadTimeoutTask(context, timeout)) + return + } + + let diff = .now() - self.lastReadTime + if diff >= timeout { + // Reader is idle - set a new timeout and trigger an event through the pipeline + self.scheduledReaderTask = context.eventLoop.scheduleTask(in: timeout, self.makeReadTimeoutTask(context, timeout)) + + context.fireUserInboundEventTriggered(IdleStateEvent.read) + } else { + // Read occurred before the timeout - set a new timeout with shorter delay. + self.scheduledReaderTask = context.eventLoop.scheduleTask(deadline: self.lastReadTime + timeout, self.makeReadTimeoutTask(context, timeout)) + } + } + } + + private func makeWriteTimeoutTask(_ context: ChannelHandlerContext, _ timeout: TimeAmount) -> (() -> Void) { + return { + guard self.shouldReschedule(context) else { + return + } + + let lastWriteTime = self.lastWriteCompleteTime + let diff = .now() - lastWriteTime + + if diff >= timeout { + // Writer is idle - set a new timeout and notify the callback. + self.scheduledWriterTask = context.eventLoop.scheduleTask(in: timeout, self.makeWriteTimeoutTask(context, timeout)) + + context.fireUserInboundEventTriggered(IdleStateEvent.write) + } else { + // Write occurred before the timeout - set a new timeout with shorter delay. + self.scheduledWriterTask = context.eventLoop.scheduleTask(deadline: self.lastWriteCompleteTime + timeout, self.makeWriteTimeoutTask(context, timeout)) + } + } + } + + private func makeAllTimeoutTask(_ context: ChannelHandlerContext, _ timeout: TimeAmount) -> (() -> Void) { + return { + guard self.shouldReschedule(context) else { + return + } + + if self.reading { + self.scheduledReaderTask = context.eventLoop.scheduleTask(in: timeout, self.makeAllTimeoutTask(context, timeout)) + return + } + let lastRead = self.lastReadTime + let lastWrite = self.lastWriteCompleteTime + let latestLast = max(lastRead, lastWrite) + + let diff = .now() - latestLast + if diff >= timeout { + // Reader is idle - set a new timeout and trigger an event through the pipeline + self.scheduledReaderTask = context.eventLoop.scheduleTask(in: timeout, self.makeAllTimeoutTask(context, timeout)) + + context.fireUserInboundEventTriggered(IdleStateEvent.all) + } else { + // Read occurred before the timeout - set a new timeout with shorter delay. + self.scheduledReaderTask = context.eventLoop.scheduleTask(deadline: latestLast + timeout, self.makeAllTimeoutTask(context, timeout)) + } + } + } + + private func schedule(_ context: ChannelHandlerContext, _ amount: TimeAmount?, _ body: @escaping (ChannelHandlerContext, TimeAmount) -> (() -> Void) ) -> Scheduled? { + if let timeout = amount { + return context.eventLoop.scheduleTask(in: timeout, body(context, timeout)) + } + return nil + } + + private func initIdleTasks(_ context: ChannelHandlerContext) { + let now = NIODeadline.now() + lastReadTime = now + lastWriteCompleteTime = now + scheduledReaderTask = schedule(context, readTimeout, makeReadTimeoutTask) + scheduledWriterTask = schedule(context, writeTimeout, makeWriteTimeoutTask) + scheduledAllTask = schedule(context, allTimeout, makeAllTimeoutTask) + } + + private func cancelIdleTasks(_ context: ChannelHandlerContext) { + scheduledReaderTask?.cancel() + scheduledWriterTask?.cancel() + scheduledAllTask?.cancel() + scheduledReaderTask = nil + scheduledWriterTask = nil + scheduledAllTask = nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelInvoker.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelInvoker.swift new file mode 100644 index 00000000..951b4a0a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelInvoker.swift @@ -0,0 +1,245 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +/// Allows users to invoke an "outbound" operation related to a `Channel` that will flow through the `ChannelPipeline` until +/// it will finally be executed by the the `ChannelCore` implementation. +public protocol ChannelOutboundInvoker { + + /// Register on an `EventLoop` and so have all its IO handled. + /// + /// - parameters: + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func register(promise: EventLoopPromise?) + + /// Bind to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should bind the `Channel`. + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func bind(to: SocketAddress, promise: EventLoopPromise?) + + /// Connect to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should connect the `Channel`. + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func connect(to: SocketAddress, promise: EventLoopPromise?) + + /// Write data to the remote peer. + /// + /// Be aware that to be sure that data is really written to the remote peer you need to call `flush` or use `writeAndFlush`. + /// Calling `write` multiple times and then `flush` may allow the `Channel` to `write` multiple data objects to the remote peer with one syscall. + /// + /// - parameters: + /// - data: the data to write + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func write(_ data: NIOAny, promise: EventLoopPromise?) + + /// Flush data that was previously written via `write` to the remote peer. + func flush() + + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - promise: the `EventLoopPromise` that will be notified once the `write` operation completes, + /// or `nil` if not interested in the outcome of the operation. + func writeAndFlush(_ data: NIOAny, promise: EventLoopPromise?) + + /// Signal that we want to read from the `Channel` once there is data ready. + /// + /// If `ChannelOptions.autoRead` is set for a `Channel` (which is the default) this method is automatically invoked by the transport implementation, + /// otherwise it's the user's responsibility to call this method manually once new data should be read and processed. + /// + func read() + + /// Close the `Channel` and so the connection if one exists. + /// + /// - parameters: + /// - mode: the `CloseMode` that is used + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func close(mode: CloseMode, promise: EventLoopPromise?) + + /// Trigger a custom user outbound event which will flow through the `ChannelPipeline`. + /// + /// - parameters: + /// - promise: the `EventLoopPromise` that will be notified once the operation completes, + /// or `nil` if not interested in the outcome of the operation. + func triggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) + + /// The `EventLoop` which is used by this `ChannelOutboundInvoker` for execution. + var eventLoop: EventLoop { get } +} + +/// Extra `ChannelOutboundInvoker` methods. Each method that returns a `EventLoopFuture` will just do the following: +/// - create a new `EventLoopPromise` +/// - call the corresponding method that takes a `EventLoopPromise` +/// - return `EventLoopPromise.futureResult` +extension ChannelOutboundInvoker { + + /// Register on an `EventLoop` and so have all its IO handled. + /// + /// - returns: the future which will be notified once the operation completes. + public func register(file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + register(promise: promise) + return promise.futureResult + } + + /// Bind to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should bind the `Channel`. + /// - returns: the future which will be notified once the operation completes. + public func bind(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + bind(to: address, promise: promise) + return promise.futureResult + } + + /// Connect to a `SocketAddress`. + /// - parameters: + /// - to: the `SocketAddress` to which we should connect the `Channel`. + /// - returns: the future which will be notified once the operation completes. + public func connect(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + connect(to: address, promise: promise) + return promise.futureResult + } + + /// Write data to the remote peer. + /// + /// Be aware that to be sure that data is really written to the remote peer you need to call `flush` or use `writeAndFlush`. + /// Calling `write` multiple times and then `flush` may allow the `Channel` to `write` multiple data objects to the remote peer with one syscall. + /// + /// - parameters: + /// - data: the data to write + /// - returns: the future which will be notified once the operation completes. + public func write(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + write(data, promise: promise) + return promise.futureResult + } + + /// Shortcut for calling `write` and `flush`. + /// + /// - parameters: + /// - data: the data to write + /// - returns: the future which will be notified once the `write` operation completes. + public func writeAndFlush(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + writeAndFlush(data, promise: promise) + return promise.futureResult + } + + /// Close the `Channel` and so the connection if one exists. + /// + /// - parameters: + /// - mode: the `CloseMode` that is used + /// - returns: the future which will be notified once the operation completes. + public func close(mode: CloseMode = .all, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + close(mode: mode, promise: promise) + return promise.futureResult + } + + /// Trigger a custom user outbound event which will flow through the `ChannelPipeline`. + /// + /// - parameters: + /// - event: the event itself. + /// - returns: the future which will be notified once the operation completes. + public func triggerUserOutboundEvent(_ event: Any, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + let promise = makePromise(file: file, line: line) + triggerUserOutboundEvent(event, promise: promise) + return promise.futureResult + } + + private func makePromise(file: StaticString = #file, line: UInt = #line) -> EventLoopPromise { + return eventLoop.makePromise(file: file, line: line) + } +} + +/// Fire inbound events related to a `Channel` through the `ChannelPipeline` until its end is reached or it's consumed by a `ChannelHandler`. +public protocol ChannelInboundInvoker { + + /// Called once a `Channel` was registered to its `EventLoop` and so IO will be processed. + func fireChannelRegistered() + + /// Called once a `Channel` was unregistered from its `EventLoop` which means no IO will be handled for a `Channel` anymore. + func fireChannelUnregistered() + + /// Called once a `Channel` becomes active. + /// + /// What active means depends on the `Channel` implementation and semantics. + /// For example for TCP it means the `Channel` is connected to the remote peer. + func fireChannelActive() + + /// Called once a `Channel` becomes inactive. + /// + /// What inactive means depends on the `Channel` implementation and semantics. + /// For example for TCP it means the `Channel` was disconnected from the remote peer and closed. + func fireChannelInactive() + + /// Called once there is some data read for a `Channel` that needs processing. + /// + /// - parameters: + /// - data: the data that was read and is ready to be processed. + func fireChannelRead(_ data: NIOAny) + + /// Called once there is no more data to read immediately on a `Channel`. Any new data received will be handled later. + func fireChannelReadComplete() + + /// Called when a `Channel`'s writable state changes. + /// + /// The writability state of a Channel depends on watermarks that can be set via `Channel.setOption` and how much data + /// is still waiting to be transferred to the remote peer. + /// You should take care to enforce some kind of backpressure if the channel becomes unwritable which means `Channel.isWritable` + /// will return `false` to ensure you do not consume too much memory due to queued writes. What exactly you should do here depends on the + /// protocol and other semantics. But for example you may want to stop writing to the `Channel` until `Channel.writable` becomes + /// `true` again or stop reading at all. + func fireChannelWritabilityChanged() + + /// Called when an inbound operation `Error` was caught. + /// + /// Be aware that for inbound operations this method is called while for outbound operations defined in `ChannelOutboundInvoker` + /// the `EventLoopFuture` or `EventLoopPromise` will be notified. + /// + /// - parameters: + /// - error: the error we encountered. + func fireErrorCaught(_ error: Error) + + /// Trigger a custom user inbound event which will flow through the `ChannelPipeline`. + /// + /// - parameters: + /// - event: the event itself. + func fireUserInboundEventTriggered(_ event: Any) +} + +/// A protocol that signals that outbound and inbound events are triggered by this invoker. +public protocol ChannelInvoker: ChannelOutboundInvoker, ChannelInboundInvoker { } + +/// Specify what kind of close operation is requested. +public enum CloseMode { + /// Close the output (writing) side of the `Channel` without closing the actual file descriptor. + /// This is an optional mode which means it may not be supported by all `Channel` implementations. + case output + + /// Close the input (reading) side of the `Channel` without closing the actual file descriptor. + /// This is an optional mode which means it may not be supported by all `Channel` implementations. + case input + + /// Close the whole `Channel (file descriptor). + case all +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelOption.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelOption.swift new file mode 100644 index 00000000..d84ef067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelOption.swift @@ -0,0 +1,387 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A configuration option that can be set on a `Channel` to configure different behaviour. +public protocol ChannelOption: Equatable { + /// The type of the `ChannelOption`'s value. + associatedtype Value +} + +public typealias SocketOptionName = Int32 +#if os(Linux) || os(Android) + public typealias SocketOptionLevel = Int + public typealias SocketOptionValue = Int +#else + public typealias SocketOptionLevel = CInt + public typealias SocketOptionValue = CInt +#endif + +@available(*, deprecated, renamed: "ChannelOptions.Types.SocketOption") +public typealias SocketOption = ChannelOptions.Types.SocketOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.AllocatorOption") +public typealias AllocatorOption = ChannelOptions.Types.AllocatorOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.RecvAllocatorOption") +public typealias RecvAllocatorOption = ChannelOptions.Types.RecvAllocatorOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.AutoReadOption") +public typealias AutoReadOption = ChannelOptions.Types.AutoReadOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.WriteSpinOption") +public typealias WriteSpinOption = ChannelOptions.Types.WriteSpinOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.MaxMessagesPerReadOption") +public typealias MaxMessagesPerReadOption = ChannelOptions.Types.MaxMessagesPerReadOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.BacklogOption") +public typealias BacklogOption = ChannelOptions.Types.BacklogOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.DatagramVectorReadMessageCountOption") +public typealias DatagramVectorReadMessageCountOption = ChannelOptions.Types.DatagramVectorReadMessageCountOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.WriteBufferWaterMark") +public typealias WriteBufferWaterMark = ChannelOptions.Types.WriteBufferWaterMark + +@available(*, deprecated, renamed: "ChannelOptions.Types.WriteBufferWaterMarkOption") +public typealias WriteBufferWaterMarkOption = ChannelOptions.Types.WriteBufferWaterMarkOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.ConnectTimeoutOption") +public typealias ConnectTimeoutOption = ChannelOptions.Types.ConnectTimeoutOption + +@available(*, deprecated, renamed: "ChannelOptions.Types.AllowRemoteHalfClosureOption") +public typealias AllowRemoteHalfClosureOption = ChannelOptions.Types.AllowRemoteHalfClosureOption + +extension ChannelOptions { + public enum Types { + + /// `SocketOption` allows users to specify configuration settings that are directly applied to the underlying socket file descriptor. + /// + /// Valid options are typically found in the various man pages like `man 4 tcp`. + public struct SocketOption: ChannelOption, Equatable { + public typealias Value = (SocketOptionValue) + + public var optionLevel: NIOBSDSocket.OptionLevel + public var optionName: NIOBSDSocket.Option + + public var level: SocketOptionLevel { + get { + return SocketOptionLevel(optionLevel.rawValue) + } + set { + self.optionLevel = NIOBSDSocket.OptionLevel(rawValue: CInt(newValue)) + } + } + public var name: SocketOptionName { + get { + return SocketOptionName(optionName.rawValue) + } + set { + self.optionName = NIOBSDSocket.Option(rawValue: CInt(newValue)) + } + } + + #if !os(Windows) + /// Create a new `SocketOption`. + /// + /// - parameters: + /// - level: The level for the option as defined in `man setsockopt`, e.g. SO_SOCKET. + /// - name: The name of the option as defined in `man setsockopt`, e.g. `SO_REUSEADDR`. + public init(level: SocketOptionLevel, name: SocketOptionName) { + self.optionLevel = NIOBSDSocket.OptionLevel(rawValue: CInt(level)) + self.optionName = NIOBSDSocket.Option(rawValue: CInt(name)) + } + #endif + + /// Create a new `SocketOption`. + /// + /// - parameters: + /// - level: The level for the option as defined in `man setsockopt`, e.g. SO_SOCKET. + /// - name: The name of the option as defined in `man setsockopt`, e.g. `SO_REUSEADDR`. + public init(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) { + self.optionLevel = level + self.optionName = name + } + } + + /// `AllocatorOption` allows to specify the `ByteBufferAllocator` to use. + public struct AllocatorOption: ChannelOption { + public typealias Value = ByteBufferAllocator + + public init() {} + } + + /// `RecvAllocatorOption` allows users to specify the `RecvByteBufferAllocator` to use. + public struct RecvAllocatorOption: ChannelOption { + public typealias Value = RecvByteBufferAllocator + + public init() {} + } + + /// `AutoReadOption` allows users to configure if a `Channel` should automatically call `Channel.read` again once all data was read from the transport or + /// if the user is responsible to call `Channel.read` manually. + public struct AutoReadOption: ChannelOption { + public typealias Value = Bool + + public init() {} + } + + /// `WriteSpinOption` allows users to configure the number of repetitions of a only partially successful write call before considering the `Channel` not writable. + /// Setting this option to `0` means that we only issue one write call and if that call does not write all the bytes, + /// we consider the `Channel` not writable. + public struct WriteSpinOption: ChannelOption { + public typealias Value = UInt + + public init() {} + } + + /// `MaxMessagesPerReadOption` allows users to configure the maximum number of read calls to the underlying transport are performed before wait again until + /// there is more to read and be notified. + public struct MaxMessagesPerReadOption: ChannelOption { + public typealias Value = UInt + + public init() {} + } + + /// `BacklogOption` allows users to configure the `backlog` value as specified in `man 2 listen`. This is only useful for `ServerSocketChannel`s. + public struct BacklogOption: ChannelOption { + public typealias Value = Int32 + + public init() {} + } + + /// `DatagramVectorReadMessageCountOption` allows users to configure the number of messages to attempt to read in a single syscall on a + /// datagram `Channel`. + /// + /// Some datagram `Channel`s have extremely high datagram throughput. This can occur when the single datagram socket is encapsulating + /// many logical "connections" (e.g. with QUIC) or when the datagram socket is simply serving an enormous number of consumers (e.g. + /// with a public-facing DNS server). In this case the overhead of one syscall per datagram is profoundly limiting. Using this + /// `ChannelOption` allows the `Channel` to read multiple datagrams at once. + /// + /// Note that simply increasing this number will not necessarily bring performance gains and may in fact cause data loss. Any increase + /// to this should be matched by increasing the size of the buffers allocated by the `Channel` `RecvByteBufferAllocator` (as set by + /// `ChannelOption.recvAllocator`) proportionally. For example, to receive 10 messages at a time, set the size of the buffers allocated + /// by the `RecvByteBufferAllocator` to at least 10x the size of the maximum datagram size you wish to receive. + /// + /// Naturally, this option is only valid on datagram channels. + /// + /// This option only works on the following platforms: + /// + /// - Linux + /// - FreeBSD + /// - Android + /// + /// On all other platforms, setting it has no effect. + /// + /// Set this option to 0 to disable vector reads and to use serial reads instead. + public struct DatagramVectorReadMessageCountOption: ChannelOption { + public typealias Value = Int + + public init() { } + } + + /// When set to true IP level ECN information will be reported through `AddressedEnvelope.Metadata` + public struct ExplicitCongestionNotificationsOption: ChannelOption { + public typealias Value = Bool + public init() {} + } + + /// The watermark used to detect when `Channel.isWritable` returns `true` or `false`. + public struct WriteBufferWaterMark { + /// The low mark setting for a `Channel`. + /// + /// When the amount of buffered bytes in the `Channel`s outbound buffer drops below this value the `Channel` will be + /// marked as writable again (after it was non-writable). + public let low: Int + + /// The high mark setting for a `Channel`. + /// + /// When the amount of buffered bytes in the `Channel`s outbound exceeds this value the `Channel` will be + /// marked as non-writable. It will be marked as writable again once the amount of buffered bytes drops below `low`. + public let high: Int + + /// Create a new instance. + /// + /// Valid initialization is restricted to `1 <= low <= high`. + /// + /// - parameters: + /// - low: The low watermark. + /// - high: The high watermark. + public init(low: Int, high: Int) { + precondition(low >= 1, "low must be >= 1 but was \(low)") + precondition(high >= low, "low must be <= high, but was low: \(low) high: \(high)") + self.low = low + self.high = high + } + } + + /// `WriteBufferWaterMarkOption` allows users to configure when a `Channel` should be marked as writable or not. Once the amount of bytes queued in a + /// `Channel`s outbound buffer is larger than `WriteBufferWaterMark.high` the channel will be marked as non-writable and so + /// `Channel.isWritable` will return `false`. Once we were able to write some data out of the outbound buffer and the amount of bytes queued + /// falls below `WriteBufferWaterMark.low` the `Channel` will become writable again. Once this happens `Channel.writable` will return + /// `true` again. These writability changes are also propagated through the `ChannelPipeline` and so can be intercepted via `ChannelInboundHandler.channelWritabilityChanged`. + public struct WriteBufferWaterMarkOption: ChannelOption { + public typealias Value = WriteBufferWaterMark + + public init() {} + } + + /// `ConnectTimeoutOption` allows users to configure the `TimeAmount` after which a connect will fail if it was not established in the meantime. May be + /// `nil`, in which case the connection attempt will never time out. + public struct ConnectTimeoutOption: ChannelOption { + public typealias Value = TimeAmount? + + public init() {} + } + + /// `AllowRemoteHalfClosureOption` allows users to configure whether the `Channel` will close itself when its remote + /// peer shuts down its send stream, or whether it will remain open. If set to `false` (the default), the `Channel` + /// will be closed automatically if the remote peer shuts down its send stream. If set to true, the `Channel` will + /// not be closed: instead, a `ChannelEvent.inboundClosed` user event will be sent on the `ChannelPipeline`, + /// and no more data will be received. + public struct AllowRemoteHalfClosureOption: ChannelOption { + public typealias Value = Bool + + public init() {} + } + + /// When set to true IP level Packet Info information will be reported through `AddressedEnvelope.Metadata` for UDP packets. + public struct ReceivePacketInfo: ChannelOption { + public typealias Value = Bool + public init() {} + } + } +} + +/// Provides `ChannelOption`s to be used with a `Channel`, `Bootstrap` or `ServerBootstrap`. +public struct ChannelOptions { + #if !os(Windows) + public static let socket = { (level: SocketOptionLevel, name: SocketOptionName) -> Types.SocketOption in + .init(level: NIOBSDSocket.OptionLevel(rawValue: CInt(level)), name: NIOBSDSocket.Option(rawValue: CInt(name))) + } + #endif + + /// - seealso: `SocketOption`. + public static let socketOption = { (name: NIOBSDSocket.Option) -> Types.SocketOption in + .init(level: .socket, name: name) + } + + /// - seealso: `SocketOption`. + public static let tcpOption = { (name: NIOBSDSocket.Option) -> Types.SocketOption in + .init(level: .tcp, name: name) + } + + /// - seealso: `AllocatorOption`. + public static let allocator = Types.AllocatorOption() + + /// - seealso: `RecvAllocatorOption`. + public static let recvAllocator = Types.RecvAllocatorOption() + + /// - seealso: `AutoReadOption`. + public static let autoRead = Types.AutoReadOption() + + /// - seealso: `MaxMessagesPerReadOption`. + public static let maxMessagesPerRead = Types.MaxMessagesPerReadOption() + + /// - seealso: `BacklogOption`. + public static let backlog = Types.BacklogOption() + + /// - seealso: `WriteSpinOption`. + public static let writeSpin = Types.WriteSpinOption() + + /// - seealso: `WriteBufferWaterMarkOption`. + public static let writeBufferWaterMark = Types.WriteBufferWaterMarkOption() + + /// - seealso: `ConnectTimeoutOption`. + public static let connectTimeout = Types.ConnectTimeoutOption() + + /// - seealso: `AllowRemoteHalfClosureOption`. + public static let allowRemoteHalfClosure = Types.AllowRemoteHalfClosureOption() + + /// - seealso: `DatagramVectorReadMessageCountOption` + public static let datagramVectorReadMessageCount = Types.DatagramVectorReadMessageCountOption() + + /// - seealso: `ExplicitCongestionNotificationsOption` + public static let explicitCongestionNotification = Types.ExplicitCongestionNotificationsOption() + + /// - seealso: `ReceivePacketInfo` + public static let receivePacketInfo = Types.ReceivePacketInfo() +} + +extension ChannelOptions { + /// A type-safe storage facility for `ChannelOption`s. You will only ever need this if you implement your own + /// `Channel` that needs to store `ChannelOption`s. + public struct Storage { + @usableFromInline + internal var _storage: [(Any, (Any, (Channel) -> (Any, Any) -> EventLoopFuture))] + + public init() { + self._storage = [] + self._storage.reserveCapacity(2) + } + + /// Add `Options`, a `ChannelOption` to the `ChannelOptions.Storage`. + /// + /// - parameters: + /// - key: the key for the option + /// - value: the value for the option + @inlinable + public mutating func append(key newKey: Option, value newValue: Option.Value) { + func applier(_ t: Channel) -> (Any, Any) -> EventLoopFuture { + return { (option, value) in + return t.setOption(option as! Option, value: value as! Option.Value) + } + } + var hasSet = false + self._storage = self._storage.map { currentKeyAndValue in + let (currentKey, _) = currentKeyAndValue + if let currentKey = currentKey as? Option, currentKey == newKey { + hasSet = true + return (currentKey, (newValue, applier)) + } else { + return currentKeyAndValue + } + } + if !hasSet { + self._storage.append((newKey, (newValue, applier))) + } + } + + /// Apply all stored `ChannelOption`s to `Channel`. + /// + /// - parameters: + /// - channel: The `Channel` to apply the `ChannelOption`s to + /// - returns: + /// - An `EventLoopFuture` that is fulfilled when all `ChannelOption`s have been applied to the `Channel`. + public func applyAllChannelOptions(to channel: Channel) -> EventLoopFuture { + let applyPromise = channel.eventLoop.makePromise(of: Void.self) + var it = self._storage.makeIterator() + + func applyNext() { + guard let (key, (value, applier)) = it.next() else { + // If we reached the end, everything is applied. + applyPromise.succeed(()) + return + } + + applier(channel)(key, value).map { + applyNext() + }.cascadeFailure(to: applyPromise) + } + applyNext() + + return applyPromise.futureResult + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelPipeline.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelPipeline.swift new file mode 100644 index 00000000..ef96f405 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ChannelPipeline.swift @@ -0,0 +1,1979 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A list of `ChannelHandler`s that handle or intercept inbound events and outbound operations of a +/// `Channel`. `ChannelPipeline` implements an advanced form of the Intercepting Filter pattern +/// to give a user full control over how an event is handled and how the `ChannelHandler`s in a pipeline +/// interact with each other. +/// +/// # Creation of a pipeline +/// +/// Each `Channel` has its own `ChannelPipeline` and it is created automatically when a new `Channel` is created. +/// +/// # How an event flows in a pipeline +/// +/// The following diagram describes how I/O events are typically processed by `ChannelHandler`s in a `ChannelPipeline`. +/// An I/O event is handled by either a `ChannelInboundHandler` or a `ChannelOutboundHandler` +/// and is forwarded to the next handler in the `ChannelPipeline` by calling the event propagation methods defined in +/// `ChannelHandlerContext`, such as `ChannelHandlerContext.fireChannelRead` and +/// `ChannelHandlerContext.write`. +/// +/// ``` +/// I/O Request +/// via `Channel` or +/// `ChannelHandlerContext` +/// | +/// +---------------------------------------------------+---------------+ +/// | ChannelPipeline | | +/// | TAIL \|/ | +/// | +---------------------+ +-----------+----------+ | +/// | | Inbound Handler N | | Outbound Handler 1 | | +/// | +----------+----------+ +-----------+----------+ | +/// | /|\ | | +/// | | \|/ | +/// | +----------+----------+ +-----------+----------+ | +/// | | Inbound Handler N-1 | | Outbound Handler 2 | | +/// | +----------+----------+ +-----------+----------+ | +/// | /|\ . | +/// | . . | +/// | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()| +/// | [ method call] [method call] | +/// | . . | +/// | . \|/ | +/// | +----------+----------+ +-----------+----------+ | +/// | | Inbound Handler 2 | | Outbound Handler M-1 | | +/// | +----------+----------+ +-----------+----------+ | +/// | /|\ | | +/// | | \|/ | +/// | +----------+----------+ +-----------+----------+ | +/// | | Inbound Handler 1 | | Outbound Handler M | | +/// | +----------+----------+ +-----------+----------+ | +/// | /|\ HEAD | | +/// +---------------+-----------------------------------+---------------+ +/// | \|/ +/// +---------------+-----------------------------------+---------------+ +/// | | | | +/// | [ Socket.read ] [ Socket.write ] | +/// | | +/// | SwiftNIO Internal I/O Threads (Transport Implementation) | +/// +-------------------------------------------------------------------+ +/// ``` +/// +/// An inbound event is handled by the inbound handlers in the head-to-tail direction as shown on the left side of the +/// diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the +/// diagram. The inbound data is often read from a remote peer via the actual input operation such as +/// `Socket.read`. If an inbound event goes beyond the tail inbound handler, it is discarded +/// silently, or logged if it needs your attention. +/// +/// An outbound event is handled by the outbound handlers in the tail-to-head direction as shown on the right side of the +/// diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. +/// If an outbound event goes beyond the head outbound handler, it is handled by an I/O thread associated with the +/// `Channel`. The I/O thread often performs the actual output operation such as `Socket.write`. +/// +/// +/// For example, let us assume that we created the following pipeline: +/// +/// ``` +/// ChannelPipeline p = ... +/// let future = p.add(name: "1", handler: InboundHandlerA()).flatMap { +/// p.add(name: "2", handler: InboundHandlerB()) +/// }.flatMap { +/// p.add(name: "3", handler: OutboundHandlerA()) +/// }.flatMap { +/// p.add(name: "4", handler: OutboundHandlerB()) +/// }.flatMap { +/// p.add(name: "5", handler: InboundOutboundHandlerX()) +/// } +/// // Handle the future as well .... +/// ``` +/// +/// In the example above, a class whose name starts with `Inbound` is an inbound handler. +/// A class whose name starts with `Outbound` is an outbound handler. +/// +/// In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. +/// When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle, `ChannelPipeline` skips +/// the evaluation of certain handlers to shorten the stack depth: +/// +/// - 3 and 4 don't implement `ChannelInboundHandler`, and therefore the actual evaluation order of an inbound event will be: 1, 2, and 5. +/// - 1 and 2 don't implement `ChannelOutboundHandler`, and therefore the actual evaluation order of a outbound event will be: 5, 4, and 3. +/// - If 5 implements both `ChannelInboundHandler` and `ChannelOutboundHandler`, the evaluation order of an inbound and a outbound event could be 125 and 543 respectively. +/// +/// Note: Handlers may choose not to propagate messages down the pipeline immediately. For example a handler may need to wait +/// for additional data before sending a protocol event to the next handler in the pipeline. Due to this you can't assume that later handlers +/// in the pipeline will receive the same number of events as were sent, or that events of different types will arrive in the same order. +/// For example - a user event could overtake a data event if a handler is aggregating data events before propagating but immediately +/// propagating user events. +/// +/// # Forwarding an event to the next handler +/// +/// As you might noticed in the diagram above, a handler has to invoke the event propagation methods in +/// `ChannelHandlerContext` to forward an event to its next handler. +/// Those methods include: +/// +/// - Inbound event propagation methods defined in `ChannelInboundInvoker` +/// - Outbound event propagation methods defined in `ChannelOutboundInvoker`. +/// +/// # Building a pipeline +/// +/// A user is supposed to have one or more `ChannelHandler`s in a `ChannelPipeline` to receive I/O events (e.g. read) and +/// to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers +/// in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the +/// protocol and business logic: +/// +/// - Protocol Decoder - translates binary data (e.g. `ByteBuffer`) into a struct / class +/// - Protocol Encoder - translates a struct / class into binary data (e.g. `ByteBuffer`) +/// - Business Logic Handler - performs the actual business logic (e.g. database access) +/// +/// # Thread safety +/// +/// A `ChannelHandler` can be added or removed at any time because a `ChannelPipeline` is thread safe. +public final class ChannelPipeline: ChannelInvoker { + private var head: Optional + private var tail: Optional + + private var idx: Int = 0 + internal private(set) var destroyed: Bool = false + + /// The `EventLoop` that is used by the underlying `Channel`. + public let eventLoop: EventLoop + + /// The `Channel` that this `ChannelPipeline` belongs to. + /// + /// - note: This will be nil after the channel has closed + private var _channel: Optional + + /// The `Channel` that this `ChannelPipeline` belongs to. + internal var channel: Channel { + self.eventLoop.assertInEventLoop() + assert(self._channel != nil || self.destroyed) + return self._channel ?? DeadChannel(pipeline: self) + } + + /// Add a `ChannelHandler` to the `ChannelPipeline`. + /// + /// - parameters: + /// - name: the name to use for the `ChannelHandler` when it's added. If none is specified it will generate a name. + /// - handler: the `ChannelHandler` to add + /// - position: The position in the `ChannelPipeline` to add `handler`. Defaults to `.last`. + /// - returns: the `EventLoopFuture` which will be notified once the `ChannelHandler` was added. + public func addHandler(_ handler: ChannelHandler, + name: String? = nil, + position: ChannelPipeline.Position = .last) -> EventLoopFuture { + let future: EventLoopFuture + + if self.eventLoop.inEventLoop { + future = self.eventLoop.makeCompletedFuture(self.addHandlerSync(handler, name: name, position: position)) + } else { + future = self.eventLoop.submit { + try self.addHandlerSync(handler, name: name, position: position).get() + } + } + + return future + } + + /// Synchronously add a `ChannelHandler` to the `ChannelPipeline`. + /// + /// May only be called from on the event loop. + /// + /// - parameters: + /// - handler: the `ChannelHandler` to add + /// - name: the name to use for the `ChannelHandler` when it's added. If none is specified a name will be generated. + /// - position: The position in the `ChannelPipeline` to add `handler`. Defaults to `.last`. + /// - returns: the result of adding this handler - either success or failure with an error code if this could not be completed. + fileprivate func addHandlerSync(_ handler: ChannelHandler, + name: String? = nil, + position: ChannelPipeline.Position = .last) -> Result { + self.eventLoop.assertInEventLoop() + + if self.destroyed { + return .failure(ChannelError.ioOnClosedChannel) + } + + switch position { + case .first: + return self.add0(name: name, + handler: handler, + relativeContext: head!, + operation: self.add0(context:after:)) + case .last: + return self.add0(name: name, + handler: handler, + relativeContext: tail!, + operation: self.add0(context:before:)) + case .before(let beforeHandler): + return self.add0(name: name, + handler: handler, + relativeHandler: beforeHandler, + operation: self.add0(context:before:)) + case .after(let afterHandler): + return self.add0(name: name, + handler: handler, + relativeHandler: afterHandler, + operation: self.add0(context:after:)) + } + } + + /// Synchronously add a `ChannelHandler` to the pipeline, relative to another `ChannelHandler`, + /// where the insertion is done by a specific operation. + /// + /// May only be called from on the event loop. + /// + /// This will search the pipeline for `relativeHandler` and, if it cannot find it, will fail + /// `promise` with `ChannelPipelineError.notFound`. + /// + /// - parameters: + /// - name: The name to use for the `ChannelHandler` when its added. If none is specified, a name will be + /// automatically generated. + /// - handler: The `ChannelHandler` to add. + /// - relativeHandler: The `ChannelHandler` already in the `ChannelPipeline` that `handler` will be + /// inserted relative to. + /// - operation: A callback that will insert `handler` relative to `relativeHandler`. + /// - returns: the result of adding this handler - either success or failure with an error code if this could not be completed. + private func add0(name: String?, + handler: ChannelHandler, + relativeHandler: ChannelHandler, + operation: (ChannelHandlerContext, ChannelHandlerContext) -> Void) -> Result { + self.eventLoop.assertInEventLoop() + if self.destroyed { + return .failure(ChannelError.ioOnClosedChannel) + } + + guard let context = self.contextForPredicate0({ $0.handler === relativeHandler }) else { + return .failure(ChannelPipelineError.notFound) + } + + return self.add0(name: name, handler: handler, relativeContext: context, operation: operation) + } + + /// Synchronously add a `ChannelHandler` to the pipeline, relative to a `ChannelHandlerContext`, + /// where the insertion is done by a specific operation. + /// + /// May only be called from on the event loop. + /// + /// This method is more efficient than the one that takes a `relativeHandler` as it does not need to + /// search the pipeline for the insertion point. It should be used whenever possible. + /// + /// - parameters: + /// - name: The name to use for the `ChannelHandler` when its added. If none is specified, a name will be + /// automatically generated. + /// - handler: The `ChannelHandler` to add. + /// - relativeContext: The `ChannelHandlerContext` already in the `ChannelPipeline` that `handler` will be + /// inserted relative to. + /// - operation: A callback that will insert `handler` relative to `relativeHandler`. + /// - returns: the result of adding this handler - either success or failure with an error code if this could not be completed. + private func add0(name: String?, + handler: ChannelHandler, + relativeContext: ChannelHandlerContext, + operation: (ChannelHandlerContext, ChannelHandlerContext) -> Void) -> Result { + self.eventLoop.assertInEventLoop() + + if self.destroyed { + return .failure(ChannelError.ioOnClosedChannel) + } + + let context = ChannelHandlerContext(name: name ?? nextName(), handler: handler, pipeline: self) + operation(context, relativeContext) + + context.invokeHandlerAdded() + return .success(()) + } + + /// Synchronously add a single new `ChannelHandlerContext` after one that currently exists in the + /// pipeline. + /// + /// Must be called from within the event loop thread, as it synchronously manipulates the + /// `ChannelHandlerContext`s on the `ChannelPipeline`. + /// + /// - parameters: + /// - new: The `ChannelHandlerContext` to add to the pipeline. + /// - existing: The `ChannelHandlerContext` that `new` will be added after. + private func add0(context new: ChannelHandlerContext, after existing: ChannelHandlerContext) { + self.eventLoop.assertInEventLoop() + + let next = existing.next + new.prev = existing + new.next = next + existing.next = new + next?.prev = new + } + + /// Synchronously add a single new `ChannelHandlerContext` before one that currently exists in the + /// pipeline. + /// + /// Must be called from within the event loop thread, as it synchronously manipulates the + /// `ChannelHandlerContext`s on the `ChannelPipeline`. + /// + /// - parameters: + /// - new: The `ChannelHandlerContext` to add to the pipeline. + /// - existing: The `ChannelHandlerContext` that `new` will be added before. + private func add0(context new: ChannelHandlerContext, before existing: ChannelHandlerContext) { + self.eventLoop.assertInEventLoop() + + let prev = existing.prev + new.prev = prev + new.next = existing + existing.prev = new + prev?.next = new + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - handler: the `ChannelHandler` to remove. + /// - returns: the `EventLoopFuture` which will be notified once the `ChannelHandler` was removed. + public func removeHandler(_ handler: RemovableChannelHandler) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.removeHandler(handler, promise: promise) + return promise.futureResult + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - name: the name that was used to add the `ChannelHandler` to the `ChannelPipeline` before. + /// - returns: the `EventLoopFuture` which will be notified once the `ChannelHandler` was removed. + public func removeHandler(name: String) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.removeHandler(name: name, promise: promise) + return promise.futureResult + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - context: the `ChannelHandlerContext` that belongs to `ChannelHandler` that should be removed. + /// - returns: the `EventLoopFuture` which will be notified once the `ChannelHandler` was removed. + public func removeHandler(context: ChannelHandlerContext) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.removeHandler(context: context, promise: promise) + return promise.futureResult + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - handler: the `ChannelHandler` to remove. + /// - promise: An `EventLoopPromise` that will complete when the `ChannelHandler` is removed. + public func removeHandler(_ handler: RemovableChannelHandler, promise: EventLoopPromise?) { + func removeHandler0() { + switch self.contextSync(handler: handler) { + case .success(let context): + self.removeHandler(context: context, promise: promise) + case .failure(let error): + promise?.fail(error) + } + } + + if self.eventLoop.inEventLoop { + removeHandler0() + } else { + self.eventLoop.execute { + removeHandler0() + } + } + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - name: the name that was used to add the `ChannelHandler` to the `ChannelPipeline` before. + /// - promise: An `EventLoopPromise` that will complete when the `ChannelHandler` is removed. + public func removeHandler(name: String, promise: EventLoopPromise?) { + func removeHandler0() { + switch self.contextSync(name: name) { + case .success(let context): + self.removeHandler(context: context, promise: promise) + case .failure(let error): + promise?.fail(error) + } + } + + if self.eventLoop.inEventLoop { + removeHandler0() + } else { + self.eventLoop.execute { + removeHandler0() + } + } + } + + /// Remove a `ChannelHandler` from the `ChannelPipeline`. + /// + /// - parameters: + /// - context: the `ChannelHandlerContext` that belongs to `ChannelHandler` that should be removed. + /// - promise: An `EventLoopPromise` that will complete when the `ChannelHandler` is removed. + public func removeHandler(context: ChannelHandlerContext, promise: EventLoopPromise?) { + guard context.handler is RemovableChannelHandler else { + promise?.fail(ChannelError.unremovableHandler) + return + } + func removeHandler0() { + context.startUserTriggeredRemoval(promise: promise) + } + + if self.eventLoop.inEventLoop { + removeHandler0() + } else { + self.eventLoop.execute { + removeHandler0() + } + } + } + + /// Returns the `ChannelHandlerContext` that belongs to a `ChannelHandler`. + /// + /// - parameters: + /// - handler: the `ChannelHandler` for which the `ChannelHandlerContext` should be returned + /// - returns: the `EventLoopFuture` which will be notified once the the operation completes. + public func context(handler: ChannelHandler) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: ChannelHandlerContext.self) + + if self.eventLoop.inEventLoop { + promise.completeWith(self.contextSync(handler: handler)) + } else { + self.eventLoop.execute { + promise.completeWith(self.contextSync(handler: handler)) + } + } + + return promise.futureResult + } + + /// Synchronously returns the `ChannelHandlerContext` that belongs to a `ChannelHandler`. + /// + /// - Important: This must be called on the `EventLoop`. + /// - parameters: + /// - handler: the `ChannelHandler` for which the `ChannelHandlerContext` should be returned + /// - returns: the `ChannelHandlerContext` that belongs to the `ChannelHandler`, if one exists. + fileprivate func contextSync(handler: ChannelHandler) -> Result { + return self._contextSync({ $0.handler === handler }) + } + + /// Returns the `ChannelHandlerContext` that belongs to a `ChannelHandler`. + /// + /// - parameters: + /// - name: the name that was used to add the `ChannelHandler` to the `ChannelPipeline` before. + /// - returns: the `EventLoopFuture` which will be notified once the the operation completes. + public func context(name: String) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: ChannelHandlerContext.self) + + if self.eventLoop.inEventLoop { + promise.completeWith(self.contextSync(name: name)) + } else { + self.eventLoop.execute { + promise.completeWith(self.contextSync(name: name)) + } + } + + return promise.futureResult + } + + /// Synchronously finds and returns the `ChannelHandlerContext` that belongs to the + /// `ChannelHandler` with the given name. + /// + /// - Important: This must be called on the `EventLoop`. + /// - Parameter name: The name of the `ChannelHandler` to find. + /// - Returns: the `ChannelHandlerContext` that belongs to the `ChannelHandler`, if one exists. + fileprivate func contextSync(name: String) -> Result { + return self._contextSync({ $0.name == name }) + } + + /// Returns the `ChannelHandlerContext` that belongs to a `ChannelHandler` of the given type. + /// + /// If multiple channel handlers of the same type are present in the pipeline, returns the context + /// belonging to the first such handler. + /// + /// - parameters: + /// - handlerType: The type of the handler to search for. + /// - returns: the `EventLoopFuture` which will be notified once the the operation completes. + @inlinable + public func context(handlerType: Handler.Type) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: ChannelHandlerContext.self) + + if self.eventLoop.inEventLoop { + promise.completeWith(self._contextSync(handlerType: handlerType)) + } else { + self.eventLoop.execute { + promise.completeWith(self._contextSync(handlerType: handlerType)) + } + } + + return promise.futureResult + } + + /// Synchronously finds and returns the `ChannelHandlerContext` that belongs to the first + /// `ChannelHandler` of the given type. + /// + /// - Important: This must be called on the `EventLoop`. + /// - Parameter handlerType: The type of handler to search for. + /// - Returns: the `ChannelHandlerContext` that belongs to the `ChannelHandler`, if one exists. + @inlinable // should be fileprivate + internal func _contextSync(handlerType: Handler.Type) -> Result { + return self._contextSync({ $0.handler is Handler }) + } + + /// Synchronously finds a `ChannelHandlerContext` in the `ChannelPipeline`. + /// - Important: This must be called on the `EventLoop`. + @usableFromInline // should be fileprivate + internal func _contextSync(_ body: (ChannelHandlerContext) -> Bool) -> Result { + self.eventLoop.assertInEventLoop() + + if let context = self.contextForPredicate0(body) { + return .success(context) + } else { + return .failure(ChannelPipelineError.notFound) + } + } + + /// Returns a `ChannelHandlerContext` which matches. + /// + /// This skips head and tail (as these are internal and should not be accessible by the user). + /// + /// - parameters: + /// - body: The predicate to execute per `ChannelHandlerContext` in the `ChannelPipeline`. + /// - returns: The first `ChannelHandlerContext` that matches or `nil` if none did. + private func contextForPredicate0(_ body: (ChannelHandlerContext) -> Bool) -> ChannelHandlerContext? { + var curCtx: ChannelHandlerContext? = self.head?.next + while let context = curCtx, context !== self.tail { + if body(context) { + return context + } + curCtx = context.next + } + + return nil + } + + /// Remove a `ChannelHandlerContext` from the `ChannelPipeline` directly without going through the + /// `RemovableChannelHandler` API. This must only be used to clear the pipeline on `Channel` tear down and + /// as a result of the `leavePipeline` call in the `RemovableChannelHandler` API. + internal func removeHandlerFromPipeline(context: ChannelHandlerContext, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + let nextCtx = context.next + let prevCtx = context.prev + + if let prevCtx = prevCtx { + prevCtx.next = nextCtx + } + if let nextCtx = nextCtx { + nextCtx.prev = prevCtx + } + + context.invokeHandlerRemoved() + promise?.succeed(()) + + // We need to keep the current node alive until after the callout in case the user uses the context. + context.next = nil + context.prev = nil + } + + /// Returns the next name to use for a `ChannelHandler`. + private func nextName() -> String { + self.eventLoop.assertInEventLoop() + + let name = "handler\(idx)" + idx += 1 + return name + } + + /// Remove all the `ChannelHandler`s from the `ChannelPipeline` and destroy these. + /// + /// This method must only be called from within the `EventLoop`. It should only be called from a `ChannelCore` + /// implementation. Once called, the `ChannelPipeline` is no longer active and cannot be used again. + func removeHandlers() { + self.eventLoop.assertInEventLoop() + + if let head = self.head { + while let context = head.next { + removeHandlerFromPipeline(context: context, promise: nil) + } + removeHandlerFromPipeline(context: self.head!, promise: nil) + } + self.head = nil + self.tail = nil + + self.destroyed = true + self._channel = nil + } + + // Just delegate to the head and tail context + public func fireChannelRegistered() { + if eventLoop.inEventLoop { + fireChannelRegistered0() + } else { + eventLoop.execute { + self.fireChannelRegistered0() + } + } + } + + public func fireChannelUnregistered() { + if eventLoop.inEventLoop { + fireChannelUnregistered0() + } else { + eventLoop.execute { + self.fireChannelUnregistered0() + } + } + } + + public func fireChannelInactive() { + if eventLoop.inEventLoop { + fireChannelInactive0() + } else { + eventLoop.execute { + self.fireChannelInactive0() + } + } + } + + public func fireChannelActive() { + if eventLoop.inEventLoop { + fireChannelActive0() + } else { + eventLoop.execute { + self.fireChannelActive0() + } + } + } + + public func fireChannelRead(_ data: NIOAny) { + if eventLoop.inEventLoop { + fireChannelRead0(data) + } else { + eventLoop.execute { + self.fireChannelRead0(data) + } + } + } + + public func fireChannelReadComplete() { + if eventLoop.inEventLoop { + fireChannelReadComplete0() + } else { + eventLoop.execute { + self.fireChannelReadComplete0() + } + } + } + + public func fireChannelWritabilityChanged() { + if eventLoop.inEventLoop { + fireChannelWritabilityChanged0() + } else { + eventLoop.execute { + self.fireChannelWritabilityChanged0() + } + } + } + + public func fireUserInboundEventTriggered(_ event: Any) { + if eventLoop.inEventLoop { + fireUserInboundEventTriggered0(event) + } else { + eventLoop.execute { + self.fireUserInboundEventTriggered0(event) + } + } + } + + public func fireErrorCaught(_ error: Error) { + if eventLoop.inEventLoop { + fireErrorCaught0(error: error) + } else { + eventLoop.execute { + self.fireErrorCaught0(error: error) + } + } + } + + public func close(mode: CloseMode = .all, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + close0(mode: mode, promise: promise) + } else { + eventLoop.execute { + self.close0(mode: mode, promise: promise) + } + } + } + + public func flush() { + if eventLoop.inEventLoop { + flush0() + } else { + eventLoop.execute { + self.flush0() + } + } + } + + public func read() { + if eventLoop.inEventLoop { + read0() + } else { + eventLoop.execute { + self.read0() + } + } + } + + public func write(_ data: NIOAny, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + write0(data, promise: promise) + } else { + eventLoop.execute { + self.write0(data, promise: promise) + } + } + } + + public func writeAndFlush(_ data: NIOAny, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + writeAndFlush0(data, promise: promise) + } else { + eventLoop.execute { + self.writeAndFlush0(data, promise: promise) + } + } + } + + public func bind(to address: SocketAddress, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + bind0(to: address, promise: promise) + } else { + eventLoop.execute { + self.bind0(to: address, promise: promise) + } + } + } + + public func connect(to address: SocketAddress, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + connect0(to: address, promise: promise) + } else { + eventLoop.execute { + self.connect0(to: address, promise: promise) + } + } + } + + public func register(promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + register0(promise: promise) + } else { + eventLoop.execute { + self.register0(promise: promise) + } + } + } + + public func triggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + triggerUserOutboundEvent0(event, promise: promise) + } else { + eventLoop.execute { + self.triggerUserOutboundEvent0(event, promise: promise) + } + } + } + + // These methods are expected to only be called from within the EventLoop + + private var firstOutboundCtx: ChannelHandlerContext? { + return self.tail?.prev + } + + private var firstInboundCtx: ChannelHandlerContext? { + return self.head?.next + } + + private func close0(mode: CloseMode, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeClose(mode: mode, promise: promise) + } else { + promise?.fail(ChannelError.alreadyClosed) + } + } + + private func flush0() { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeFlush() + } + } + + private func read0() { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeRead() + } + } + + private func write0(_ data: NIOAny, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeWrite(data, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func writeAndFlush0(_ data: NIOAny, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeWriteAndFlush(data, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeBind(to: address, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func connect0(to address: SocketAddress, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeConnect(to: address, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func register0(promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeRegister(promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + if let firstOutboundCtx = firstOutboundCtx { + firstOutboundCtx.invokeTriggerUserOutboundEvent(event, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + private func fireChannelRegistered0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelRegistered() + } + } + + private func fireChannelUnregistered0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelUnregistered() + } + } + + private func fireChannelInactive0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelInactive() + } + } + + private func fireChannelActive0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelActive() + } + } + + private func fireChannelRead0(_ data: NIOAny) { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelRead(data) + } + } + + private func fireChannelReadComplete0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelReadComplete() + } + } + + private func fireChannelWritabilityChanged0() { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeChannelWritabilityChanged() + } + } + + private func fireUserInboundEventTriggered0(_ event: Any) { + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeUserInboundEventTriggered(event) + } + } + + private func fireErrorCaught0(error: Error) { + assert((error as? ChannelError).map { $0 != .eof } ?? true) + if let firstInboundCtx = firstInboundCtx { + firstInboundCtx.invokeErrorCaught(error) + } + } + + private var inEventLoop: Bool { + return eventLoop.inEventLoop + } + + /// Create `ChannelPipeline` for a given `Channel`. This method should never be called by the end-user + /// directly: it is only intended for use with custom `Channel` implementations. Users should always use + /// `channel.pipeline` to access the `ChannelPipeline` for a `Channel`. + /// + /// - parameters: + /// - channel: The `Channel` this `ChannelPipeline` is created for. + public init(channel: Channel) { + self._channel = channel + self.eventLoop = channel.eventLoop + self.head = nil // we need to initialise these to `nil` so we can use `self` in the lines below + self.tail = nil // we need to initialise these to `nil` so we can use `self` in the lines below + + self.head = ChannelHandlerContext(name: HeadChannelHandler.name, handler: HeadChannelHandler.sharedInstance, pipeline: self) + self.tail = ChannelHandlerContext(name: TailChannelHandler.name, handler: TailChannelHandler.sharedInstance, pipeline: self) + self.head?.next = self.tail + self.tail?.prev = self.head + } +} + +extension ChannelPipeline { + /// Adds the provided channel handlers to the pipeline in the order given, taking account + /// of the behaviour of `ChannelHandler.add(first:)`. + /// + /// - parameters: + /// - handlers: The array of `ChannelHandler`s to be added. + /// - position: The position in the `ChannelPipeline` to add `handlers`. Defaults to `.last`. + /// + /// - returns: A future that will be completed when all of the supplied `ChannelHandler`s were added. + public func addHandlers(_ handlers: [ChannelHandler], + position: ChannelPipeline.Position = .last) -> EventLoopFuture { + let future: EventLoopFuture + + if self.eventLoop.inEventLoop { + future = self.eventLoop.makeCompletedFuture(self.addHandlersSync(handlers, position: position)) + } else { + future = self.eventLoop.submit { + try self.addHandlersSync(handlers, position: position).get() + } + } + + return future + } + + /// Adds the provided channel handlers to the pipeline in the order given, taking account + /// of the behaviour of `ChannelHandler.add(first:)`. + /// + /// - parameters: + /// - handlers: One or more `ChannelHandler`s to be added. + /// - position: The position in the `ChannelPipeline` to add `handlers`. Defaults to `.last`. + /// + /// - returns: A future that will be completed when all of the supplied `ChannelHandler`s were added. + public func addHandlers(_ handlers: ChannelHandler..., + position: ChannelPipeline.Position = .last) -> EventLoopFuture { + return self.addHandlers(handlers, position: position) + } + + /// Synchronously adds the provided `ChannelHandler`s to the pipeline in the order given, taking + /// account of the behaviour of `ChannelHandler.add(first:)`. + /// + /// - Important: Must be called on the `EventLoop`. + /// - Parameters: + /// - handlers: The array of `ChannelHandler`s to add. + /// - position: The position in the `ChannelPipeline` to add the handlers. + /// - Returns: A result representing whether the handlers were added or not. + fileprivate func addHandlersSync(_ handlers: [ChannelHandler], + position: ChannelPipeline.Position) -> Result { + switch position { + case .first, .after: + return self._addHandlersSync(handlers.reversed(), position: position) + case .last, .before: + return self._addHandlersSync(handlers, position: position) + } + } + + /// Synchronously adds a sequence of `ChannelHandlers` to the pipeline at the given position. + /// + /// - Important: Must be called on the `EventLoop`. + /// - Parameters: + /// - handlers: A sequence of handlers to add. + /// - position: The position in the `ChannelPipeline` to add the handlers. + /// - Returns: A result representing whether the handlers were added or not. + private func _addHandlersSync(_ handlers: Handlers, + position: ChannelPipeline.Position) -> Result where Handlers.Element == ChannelHandler { + self.eventLoop.assertInEventLoop() + + for handler in handlers { + let result = self.addHandlerSync(handler, position: position) + switch result { + case .success: + () + case .failure: + return result + } + } + + return .success(()) + } +} + +// MARK: - Synchronous View + +extension ChannelPipeline { + /// A view of a `ChannelPipeline` which may be used to invoke synchronous operations. + /// + /// All functions **must** be called from the pipeline's event loop. + public struct SynchronousOperations { + @usableFromInline + internal let _pipeline: ChannelPipeline + + fileprivate init(pipeline: ChannelPipeline) { + self._pipeline = pipeline + } + + /// The `EventLoop` of the `Channel` this synchronous operations view corresponds to. + public var eventLoop: EventLoop { + return self._pipeline.eventLoop + } + + /// Add a handler to the pipeline. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameters: + /// - handler: The handler to add. + /// - name: The name to use for the `ChannelHandler` when it's added. If no name is specified the one will be generated. + /// - position: The position in the `ChannelPipeline` to add `handler`. Defaults to `.last`. + public func addHandler(_ handler: ChannelHandler, + name: String? = nil, + position: ChannelPipeline.Position = .last) throws { + try self._pipeline.addHandlerSync(handler, name: name, position: position).get() + } + + /// Add an array of handlers to the pipeline. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameters: + /// - handlers: The handlers to add. + /// - position: The position in the `ChannelPipeline` to add `handlers`. Defaults to `.last`. + public func addHandlers(_ handlers: [ChannelHandler], + position: ChannelPipeline.Position = .last) throws { + try self._pipeline.addHandlersSync(handlers, position: position).get() + } + + /// Add one or more handlers to the pipeline. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameters: + /// - handlers: The handlers to add. + /// - position: The position in the `ChannelPipeline` to add `handlers`. Defaults to `.last`. + public func addHandlers(_ handlers: ChannelHandler..., + position: ChannelPipeline.Position = .last) throws { + try self._pipeline.addHandlersSync(handlers, position: position).get() + } + + /// Returns the `ChannelHandlerContext` for the given handler instance if it is in + /// the `ChannelPipeline`, if it exists. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameter handler: The handler belonging to the context to fetch. + /// - Returns: The `ChannelHandlerContext` associated with the handler. + public func context(handler: ChannelHandler) throws -> ChannelHandlerContext { + return try self._pipeline._contextSync({ $0.handler === handler }).get() + } + + /// Returns the `ChannelHandlerContext` for the handler with the given name, if one exists. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameter name: The name of the handler whose context is being fetched. + /// - Returns: The `ChannelHandlerContext` associated with the handler. + public func context(name: String) throws -> ChannelHandlerContext { + return try self._pipeline.contextSync(name: name).get() + } + + /// Returns the `ChannelHandlerContext` for the handler of given type, if one exists. + /// + /// - Important: This *must* be called on the event loop. + /// - Parameter name: The name of the handler whose context is being fetched. + /// - Returns: The `ChannelHandlerContext` associated with the handler. + @inlinable + public func context(handlerType: Handler.Type) throws -> ChannelHandlerContext { + return try self._pipeline._contextSync(handlerType: handlerType).get() + } + + /// Returns the `ChannelHandler` of the given type from the `ChannelPipeline`, if it exists. + /// + /// - Important: This *must* be called on the event loop. + /// - Returns: A `ChannelHandler` of the given type if one exists in the `ChannelPipeline`. + @inlinable + public func handler(type _: Handler.Type) throws -> Handler { + return try self._pipeline._handlerSync(type: Handler.self).get() + } + + /// Fires `channelRegistered` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelRegistered() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelRegistered0() + } + + /// Fires `channelUnregistered` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelUnregistered() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelUnregistered0() + } + + /// Fires `channelInactive` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelInactive() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelInactive0() + } + + /// Fires `channelActive` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelActive() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelActive0() + } + + /// Fires `channelRead` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelRead(_ data: NIOAny) { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelRead0(data) + } + + /// Fires `channelReadComplete` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelReadComplete() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelReadComplete0() + } + + /// Fires `channelWritabilityChanged` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireChannelWritabilityChanged() { + self.eventLoop.assertInEventLoop() + self._pipeline.fireChannelWritabilityChanged0() + } + + /// Fires `userInboundEventTriggered` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireUserInboundEventTriggered(_ event: Any) { + self.eventLoop.assertInEventLoop() + self._pipeline.fireUserInboundEventTriggered0(event) + } + + /// Fires `errorCaught` from the head to the tail. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func fireErrorCaught(_ error: Error) { + self.eventLoop.assertInEventLoop() + self._pipeline.fireErrorCaught0(error: error) + } + + /// Fires `close` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func close(mode: CloseMode = .all, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.close0(mode: mode, promise: promise) + } + + /// Fires `flush` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func flush() { + self.eventLoop.assertInEventLoop() + self._pipeline.flush0() + } + + /// Fires `read` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func read() { + self.eventLoop.assertInEventLoop() + self._pipeline.read0() + } + + /// Fires `write` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func write(_ data: NIOAny, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.write0(data, promise: promise) + } + + /// Fires `writeAndFlush` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func writeAndFlush(_ data: NIOAny, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.writeAndFlush0(data, promise: promise) + } + + /// Fires `bind` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func bind(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.bind0(to: address, promise: promise) + } + + /// Fires `connect` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func connect(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.connect0(to: address, promise: promise) + } + + /// Fires `register` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func register(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.register0(promise: promise) + } + + /// Fires `triggerUserOutboundEvent` from the tail to the head. + /// + /// This method should typically only be called by `Channel` implementations directly. + public func triggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.triggerUserOutboundEvent0(event, promise: promise) + } + } + + /// Returns a view of operations which can be performed synchronously on this pipeline. All + /// operations **must** be called on the event loop. + public var syncOperations: SynchronousOperations { + return SynchronousOperations(pipeline: self) + } +} + +extension ChannelPipeline { + /// A `Position` within the `ChannelPipeline` used to insert handlers into the `ChannelPipeline`. + public enum Position { + /// The first `ChannelHandler` -- the front of the `ChannelPipeline`. + case first + + /// The last `ChannelHandler` -- the back of the `ChannelPipeline`. + case last + + /// Before the given `ChannelHandler`. + case before(ChannelHandler) + + /// After the given `ChannelHandler`. + case after(ChannelHandler) + } +} + +/// Special `ChannelHandler` that forwards all events to the `Channel.Unsafe` implementation. +/* private but tests */ final class HeadChannelHandler: _ChannelOutboundHandler { + + static let name = "head" + static let sharedInstance = HeadChannelHandler() + + private init() { } + + func register(context: ChannelHandlerContext, promise: EventLoopPromise?) { + context.channel._channelCore.register0(promise: promise) + } + + func bind(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + context.channel._channelCore.bind0(to: address, promise: promise) + } + + func connect(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + context.channel._channelCore.connect0(to: address, promise: promise) + } + + func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + context.channel._channelCore.write0(data, promise: promise) + } + + func flush(context: ChannelHandlerContext) { + context.channel._channelCore.flush0() + } + + func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + context.channel._channelCore.close0(error: mode.error, mode: mode, promise: promise) + } + + func read(context: ChannelHandlerContext) { + context.channel._channelCore.read0() + } + + func triggerUserOutboundEvent(context: ChannelHandlerContext, event: Any, promise: EventLoopPromise?) { + context.channel._channelCore.triggerUserOutboundEvent0(event, promise: promise) + } + +} + +private extension CloseMode { + /// Returns the error to fail outstanding operations writes with. + var error: ChannelError { + switch self { + case .all: + return .ioOnClosedChannel + case .output: + return .outputClosed + case .input: + return .inputClosed + } + } +} + +/// Special `ChannelInboundHandler` which will consume all inbound events. +/* private but tests */ final class TailChannelHandler: _ChannelInboundHandler { + + static let name = "tail" + static let sharedInstance = TailChannelHandler() + + private init() { } + + func channelRegistered(context: ChannelHandlerContext) { + // Discard + } + + func channelUnregistered(context: ChannelHandlerContext) { + // Discard + } + + func channelActive(context: ChannelHandlerContext) { + // Discard + } + + func channelInactive(context: ChannelHandlerContext) { + // Discard + } + + func channelReadComplete(context: ChannelHandlerContext) { + // Discard + } + + func channelWritabilityChanged(context: ChannelHandlerContext) { + // Discard + } + + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + // Discard + } + + func errorCaught(context: ChannelHandlerContext, error: Error) { + context.channel._channelCore.errorCaught0(error: error) + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + context.channel._channelCore.channelRead0(data) + } +} + +/// `Error` that is used by the `ChannelPipeline` to inform the user of an error. +public enum ChannelPipelineError: Error { + /// `ChannelHandler` was already removed. + case alreadyRemoved + /// `ChannelHandler` was not found. + case notFound +} + +/// Every `ChannelHandler` has -- when added to a `ChannelPipeline` -- a corresponding `ChannelHandlerContext` which is +/// the way `ChannelHandler`s can interact with other `ChannelHandler`s in the pipeline. +/// +/// Most `ChannelHandler`s need to send events through the `ChannelPipeline` which they do by calling the respective +/// method on their `ChannelHandlerContext`. In fact all the `ChannelHandler` default implementations just forward +/// the event using the `ChannelHandlerContext`. +/// +/// Many events are instrumental for a `ChannelHandler`'s life-cycle and it is therefore very important to send them +/// at the right point in time. Often, the right behaviour is to react to an event and then forward it to the next +/// `ChannelHandler`. +public final class ChannelHandlerContext: ChannelInvoker { + // visible for ChannelPipeline to modify + fileprivate var next: Optional + fileprivate var prev: Optional + + public let pipeline: ChannelPipeline + + public var channel: Channel { + return self.pipeline.channel + } + + public var handler: ChannelHandler { + return self.inboundHandler ?? self.outboundHandler! + } + + public var remoteAddress: SocketAddress? { + do { + // Fast-path access to the remoteAddress. + return try self.channel._channelCore.remoteAddress0() + } catch ChannelError.ioOnClosedChannel { + // Channel was closed already but we may still have the address cached so try to access it via the Channel + // so we are able to use it in channelInactive(...) / handlerRemoved(...) methods. + return self.channel.remoteAddress + } catch { + return nil + } + } + + public var localAddress: SocketAddress? { + do { + // Fast-path access to the localAddress. + return try self.channel._channelCore.localAddress0() + } catch ChannelError.ioOnClosedChannel { + // Channel was closed already but we may still have the address cached so try to access it via the Channel + // so we are able to use it in channelInactive(...) / handlerRemoved(...) methods. + return self.channel.localAddress + } catch { + return nil + } + } + + public var eventLoop: EventLoop { + return self.pipeline.eventLoop + } + + public let name: String + private let inboundHandler: _ChannelInboundHandler? + private let outboundHandler: _ChannelOutboundHandler? + private var removeHandlerInvoked = false + private var userTriggeredRemovalStarted = false + + // Only created from within ChannelPipeline + fileprivate init(name: String, handler: ChannelHandler, pipeline: ChannelPipeline) { + self.name = name + self.pipeline = pipeline + self.inboundHandler = handler as? _ChannelInboundHandler + self.outboundHandler = handler as? _ChannelOutboundHandler + self.next = nil + self.prev = nil + precondition(self.inboundHandler != nil || self.outboundHandler != nil, "ChannelHandlers need to either be inbound or outbound") + } + + /// Send a `channelRegistered` event to the next (inbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `channelRegistered` event using this method at the right point in time, that is usually when received. + public func fireChannelRegistered() { + self.next?.invokeChannelRegistered() + } + + /// Send a `channelUnregistered` event to the next (inbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `channelUnregistered` event using this method at the right point in time, that is usually when received. + public func fireChannelUnregistered() { + self.next?.invokeChannelUnregistered() + } + + /// Send a `channelActive` event to the next (inbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `channelActive` event using this method at the right point in time, that is often when received. + public func fireChannelActive() { + self.next?.invokeChannelActive() + } + + /// Send a `channelInactive` event to the next (inbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `channelInactive` event using this method at the right point in time, that is often when received. + public func fireChannelInactive() { + self.next?.invokeChannelInactive() + } + + /// Send data to the next inbound `ChannelHandler`. The data should be of type `ChannelInboundHandler.InboundOut`. + public func fireChannelRead(_ data: NIOAny) { + self.next?.invokeChannelRead(data) + } + + /// Signal to the next `ChannelHandler` that a read burst has finished. + public func fireChannelReadComplete() { + self.next?.invokeChannelReadComplete() + } + + /// Send a `writabilityChanged` event to the next (inbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `writabilityChanged` event using this method at the right point in time, that is usually when received. + public func fireChannelWritabilityChanged() { + self.next?.invokeChannelWritabilityChanged() + } + + /// Send an error to the next inbound `ChannelHandler`. + public func fireErrorCaught(_ error: Error) { + self.next?.invokeErrorCaught(error) + } + + /// Send a user event to the next inbound `ChannelHandler`. + public func fireUserInboundEventTriggered(_ event: Any) { + self.next?.invokeUserInboundEventTriggered(event) + } + + /// Send a `register` event to the next (outbound) `ChannelHandler` in the `ChannelPipeline`. + /// + /// - note: For correct operation it is very important to forward any `register` event using this method at the right point in time, that is usually when received. + public func register(promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeRegister(promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + /// Send a `bind` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `bind` event reaches the `HeadChannelHandler` a `ServerSocketChannel` will be bound. + /// + /// - parameters: + /// - address: The address to bind to. + /// - promise: The promise fulfilled when the socket is bound or failed if it cannot be bound. + public func bind(to address: SocketAddress, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeBind(to: address, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + /// Send a `connect` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `connect` event reaches the `HeadChannelHandler` a `SocketChannel` will be connected. + /// + /// - parameters: + /// - address: The address to connect to. + /// - promise: The promise fulfilled when the socket is connected or failed if it cannot be connected. + public func connect(to address: SocketAddress, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeConnect(to: address, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + /// Send a `write` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `write` event reaches the `HeadChannelHandler` the data will be enqueued to be written on the next + /// `flush` event. + /// + /// - parameters: + /// - data: The data to write, should be of type `ChannelOutboundHandler.OutboundOut`. + /// - promise: The promise fulfilled when the data has been written or failed if it cannot be written. + public func write(_ data: NIOAny, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeWrite(data, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + /// Send a `flush` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `flush` event reaches the `HeadChannelHandler` the data previously enqueued will be attempted to be + /// written to the socket. + /// + /// - parameters: + /// - promise: The promise fulfilled when the previously written data been flushed or failed if it cannot be flushed. + public func flush() { + if let outboundNext = self.prev { + outboundNext.invokeFlush() + } + } + + /// Send a `write` event followed by a `flush` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `write` event reaches the `HeadChannelHandler` the data will be enqueued to be written when the `flush` + /// also reaches the `HeadChannelHandler`. + /// + /// - parameters: + /// - data: The data to write, should be of type `ChannelOutboundHandler.OutboundOut`. + /// - promise: The promise fulfilled when the previously written data been written and flushed or if that failed. + public func writeAndFlush(_ data: NIOAny, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeWriteAndFlush(data, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + /// Send a `read` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `read` event reaches the `HeadChannelHandler` the interest to read data will be signalled to the + /// `Selector`. This will subsequently -- when data becomes readable -- cause `channelRead` events containing the + /// data being sent through the `ChannelPipeline`. + public func read() { + if let outboundNext = self.prev { + outboundNext.invokeRead() + } + } + + /// Send a `close` event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// When the `close` event reaches the `HeadChannelHandler` the socket will be closed. + /// + /// - parameters: + /// - mode: The `CloseMode` to use. + /// - promise: The promise fulfilled when the `Channel` has been closed or failed if it the closing failed. + public func close(mode: CloseMode = .all, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeClose(mode: mode, promise: promise) + } else { + promise?.fail(ChannelError.alreadyClosed) + } + } + + /// Send a user event to the next outbound `ChannelHandler` in the `ChannelPipeline`. + /// + /// - parameters: + /// - event: The user event to send. + /// - promise: The promise fulfilled when the user event has been sent or failed if it couldn't be sent. + public func triggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) { + if let outboundNext = self.prev { + outboundNext.invokeTriggerUserOutboundEvent(event, promise: promise) + } else { + promise?.fail(ChannelError.ioOnClosedChannel) + } + } + + fileprivate func invokeChannelRegistered() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelRegistered(context: self) + } else { + self.next?.invokeChannelRegistered() + } + } + + fileprivate func invokeChannelUnregistered() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelUnregistered(context: self) + } else { + self.next?.invokeChannelUnregistered() + } + } + + fileprivate func invokeChannelActive() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelActive(context: self) + } else { + self.next?.invokeChannelActive() + } + } + + fileprivate func invokeChannelInactive() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelInactive(context: self) + } else { + self.next?.invokeChannelInactive() + } + } + + fileprivate func invokeChannelRead(_ data: NIOAny) { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelRead(context: self, data: data) + } else { + self.next?.invokeChannelRead(data) + } + } + + fileprivate func invokeChannelReadComplete() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelReadComplete(context: self) + } else { + self.next?.invokeChannelReadComplete() + } + } + + fileprivate func invokeChannelWritabilityChanged() { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.channelWritabilityChanged(context: self) + } else { + self.next?.invokeChannelWritabilityChanged() + } + } + + fileprivate func invokeErrorCaught(_ error: Error) { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.errorCaught(context: self, error: error) + } else { + self.next?.invokeErrorCaught(error) + } + } + + fileprivate func invokeUserInboundEventTriggered(_ event: Any) { + self.eventLoop.assertInEventLoop() + + if let inboundHandler = self.inboundHandler { + inboundHandler.userInboundEventTriggered(context: self, event: event) + } else { + self.next?.invokeUserInboundEventTriggered(event) + } + } + + fileprivate func invokeRegister(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.register(context: self, promise: promise) + } else { + self.prev?.invokeRegister(promise: promise) + } + } + + fileprivate func invokeBind(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.bind(context: self, to: address, promise: promise) + } else { + self.prev?.invokeBind(to: address, promise: promise) + } + } + + fileprivate func invokeConnect(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.connect(context: self, to: address, promise: promise) + } else { + self.prev?.invokeConnect(to: address, promise: promise) + } + } + + fileprivate func invokeWrite(_ data: NIOAny, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.write(context: self, data: data, promise: promise) + } else { + self.prev?.invokeWrite(data, promise: promise) + } + } + + fileprivate func invokeFlush() { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.flush(context: self) + } else { + self.prev?.invokeFlush() + } + } + + fileprivate func invokeWriteAndFlush(_ data: NIOAny, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.write(context: self, data: data, promise: promise) + outboundHandler.flush(context: self) + } else { + self.prev?.invokeWriteAndFlush(data, promise: promise) + } + } + + fileprivate func invokeRead() { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.read(context: self) + } else { + self.prev?.invokeRead() + } + } + + fileprivate func invokeClose(mode: CloseMode, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.close(context: self, mode: mode, promise: promise) + } else { + self.prev?.invokeClose(mode: mode, promise: promise) + } + } + + fileprivate func invokeTriggerUserOutboundEvent(_ event: Any, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + if let outboundHandler = self.outboundHandler { + outboundHandler.triggerUserOutboundEvent(context: self, event: event, promise: promise) + } else { + self.prev?.invokeTriggerUserOutboundEvent(event, promise: promise) + } + } + + fileprivate func invokeHandlerAdded() { + self.eventLoop.assertInEventLoop() + + handler.handlerAdded(context: self) + } + + fileprivate func invokeHandlerRemoved() { + self.eventLoop.assertInEventLoop() + guard !self.removeHandlerInvoked else { + return + } + self.removeHandlerInvoked = true + + handler.handlerRemoved(context: self) + } +} + +extension ChannelHandlerContext { + /// A `RemovalToken` is handed to a `RemovableChannelHandler` when its `removeHandler` function is invoked. A + /// `RemovableChannelHandler` is then required to remove itself from the `ChannelPipeline`. The removal process + /// is finalized by handing the `RemovalToken` to the `ChannelHandlerContext.leavePipeline` function. + public struct RemovalToken { + internal let promise: EventLoopPromise? + } + + /// Synchronously remove the `ChannelHandler` with the given `ChannelHandlerContext`. + /// + /// - note: This function must only be used from a `RemovableChannelHandler` to remove itself. Calling this method + /// on any other `ChannelHandlerContext` leads to undefined behaviour. + /// + /// - parameters: + /// - removalToken: The removal token received from `RemovableChannelHandler.removeHandler` + public func leavePipeline(removalToken: RemovalToken) { + self.eventLoop.preconditionInEventLoop() + self.pipeline.removeHandlerFromPipeline(context: self, promise: removalToken.promise) + } + + internal func startUserTriggeredRemoval(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + guard !self.userTriggeredRemovalStarted else { + promise?.fail(NIOAttemptedToRemoveHandlerMultipleTimesError()) + return + } + self.userTriggeredRemovalStarted = true + (self.handler as! RemovableChannelHandler).removeHandler(context: self, + removalToken: .init(promise: promise)) + } +} + +extension ChannelPipeline: CustomDebugStringConvertible { + public var debugDescription: String { + // This method forms output in the following format: + // + // ChannelPipeline[0x0000000000000000]: + // [I] ↓↑ [O] + // ↓↑ [] + // ↓↑ [] + // ↓↑ [] + // + var desc = ["ChannelPipeline[\(ObjectIdentifier(self))]:"] + let debugInfos = self.collectHandlerDebugInfos() + let maxIncomingTypeNameCount = debugInfos.filter { $0.isIncoming } + .map { $0.typeName.count } + .max() ?? 0 + let maxOutgoingTypeNameCount = debugInfos.filter { $0.isOutgoing } + .map { $0.typeName.count } + .max() ?? 0 + + func whitespace(count: Int) -> String { + return String(repeating: " ", count: count) + } + + if debugInfos.isEmpty { + desc.append(" ") + } else { + desc.append(whitespace(count: maxIncomingTypeNameCount - 2) + "[I] ↓↑ [O]") + for debugInfo in debugInfos { + var line = [String]() + line.append(" ") + if debugInfo.isIncoming { + line.append(whitespace(count: maxIncomingTypeNameCount - debugInfo.typeName.count)) + line.append(debugInfo.typeName) + } else { + line.append(whitespace(count: maxIncomingTypeNameCount)) + } + line.append(" ↓↑ ") + if debugInfo.isOutgoing { + line.append(debugInfo.typeName) + line.append(whitespace(count: maxOutgoingTypeNameCount - debugInfo.typeName.count)) + } else { + line.append(whitespace(count: maxOutgoingTypeNameCount)) + } + line.append(" ") + line.append("[\(debugInfo.name)]") + desc.append(line.joined()) + } + } + + return desc.joined(separator: "\n") + } + + /// Returns the first `ChannelHandler` of the given type. + /// + /// - parameters: + /// - type: the type of `ChannelHandler` to return. + @inlinable + public func handler(type _: Handler.Type) -> EventLoopFuture { + return self.context(handlerType: Handler.self).map { context in + guard let typedContext = context.handler as? Handler else { + preconditionFailure("Expected channel handler of type \(Handler.self), got \(type(of: context.handler)) instead.") + } + + return typedContext + } + } + + /// Synchronously finds and returns the first `ChannelHandler` of the given type. + /// + /// - Important: This must be called on the `EventLoop`. + /// - Parameters: + /// - type: the type of `ChannelHandler` to return. + @inlinable // should be fileprivate + internal func _handlerSync(type _: Handler.Type) -> Result { + return self._contextSync(handlerType: Handler.self).map { context in + guard let typedContext = context.handler as? Handler else { + preconditionFailure("Expected channel handler of type \(Handler.self), got \(type(of: context.handler)) instead.") + } + return typedContext + } + } + + private struct ChannelHandlerDebugInfo { + let handler: ChannelHandler + let name: String + var isIncoming: Bool { + return self.handler is _ChannelInboundHandler + } + var isOutgoing: Bool { + return self.handler is _ChannelOutboundHandler + } + var typeName: String { + return "\(type(of: self.handler))" + } + } + + private func collectHandlerDebugInfos() -> [ChannelHandlerDebugInfo] { + var handlers = [ChannelHandlerDebugInfo]() + var node = self.head?.next + while let context = node, context !== self.tail { + handlers.append(.init(handler: context.handler, name: context.name)) + node = context.next + } + return handlers + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/CircularBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/CircularBuffer.swift new file mode 100644 index 00000000..3e00eb96 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/CircularBuffer.swift @@ -0,0 +1,822 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An automatically expanding ring buffer implementation backed by a `ContiguousArray`. Even though this implementation +/// will automatically expand if more elements than `initialCapacity` are stored, it's advantageous to prevent +/// expansions from happening frequently. Expansions will always force an allocation and a copy to happen. +public struct CircularBuffer: CustomStringConvertible { + @usableFromInline + internal private(set) var _buffer: ContiguousArray + + @usableFromInline + internal private(set) var headBackingIndex: Int + + @usableFromInline + internal private(set) var tailBackingIndex: Int + + @inlinable + internal var mask: Int { + return self._buffer.count &- 1 + } + + @inlinable + internal mutating func advanceHeadIdx(by: Int) { + self.headBackingIndex = indexAdvanced(index: self.headBackingIndex, by: by) + } + + @inlinable + internal mutating func advanceTailIdx(by: Int) { + self.tailBackingIndex = indexAdvanced(index: self.tailBackingIndex, by: by) + } + + @inlinable + internal func indexBeforeHeadIdx() -> Int { + return self.indexAdvanced(index: self.headBackingIndex, by: -1) + } + + @inlinable + internal func indexBeforeTailIdx() -> Int { + return self.indexAdvanced(index: self.tailBackingIndex, by: -1) + } + + @inlinable + internal func indexAdvanced(index: Int, by: Int) -> Int { + return (index &+ by) & self.mask + } + + /// An opaque `CircularBuffer` index. + /// + /// You may get indices offset from other indices by using `CircularBuffer.index(:offsetBy:)`, + /// `CircularBuffer.index(before:)`, or `CircularBuffer.index(after:)`. + /// + /// - note: Every index is invalidated as soon as you perform a length-changing operating on the `CircularBuffer` + /// but remains valid when you replace one item by another using the subscript. + public struct Index: Comparable { + @usableFromInline private(set) var _backingIndex: UInt32 + @usableFromInline private(set) var _backingCheck: _UInt24 + @usableFromInline private(set) var isIndexGEQHeadIndex: Bool + + @inlinable + internal var backingIndex: Int { + return Int(self._backingIndex) + } + + @inlinable + internal init(backingIndex: Int, backingCount: Int, backingIndexOfHead: Int) { + self.isIndexGEQHeadIndex = backingIndex >= backingIndexOfHead + self._backingCheck = .max + self._backingIndex = UInt32(backingIndex) + debugOnly { + // if we can, we store the check for the backing here + self._backingCheck = backingCount < Int(_UInt24.max) ? _UInt24(UInt32(backingCount)) : .max + } + } + + @inlinable + public static func == (lhs: Index, rhs: Index) -> Bool { + return lhs._backingIndex == rhs._backingIndex && + lhs._backingCheck == rhs._backingCheck && + lhs.isIndexGEQHeadIndex == rhs.isIndexGEQHeadIndex + } + + @inlinable + public static func < (lhs: Index, rhs: Index) -> Bool { + if lhs.isIndexGEQHeadIndex && rhs.isIndexGEQHeadIndex { + return lhs.backingIndex < rhs.backingIndex + } else if lhs.isIndexGEQHeadIndex && !rhs.isIndexGEQHeadIndex { + return true + } else if !lhs.isIndexGEQHeadIndex && rhs.isIndexGEQHeadIndex { + return false + } else { + return lhs.backingIndex < rhs.backingIndex + } + } + + @usableFromInline + internal func isValidIndex(for ring: CircularBuffer) -> Bool { + return self._backingCheck == _UInt24.max || Int(self._backingCheck) == ring.count + } + } +} + +// MARK: Collection/MutableCollection implementation +extension CircularBuffer: Collection, MutableCollection { + public typealias Element = Element + public typealias Indices = DefaultIndices> + public typealias RangeType = Range where Bound: Strideable, Bound.Stride: SignedInteger + public typealias SubSequence = CircularBuffer + + /// Returns the position immediately after the given index. + /// + /// The successor of an index must be well defined. For an index `i` into a + /// collection `c`, calling `c.index(after: i)` returns the same index every + /// time. + /// + /// - Parameter i: A valid index of the collection. `i` must be less than + /// `endIndex`. + /// - Returns: The index value immediately after `i`. + @inlinable + public func index(after: Index) -> Index { + return self.index(after, offsetBy: 1) + } + + /// Returns the index before `index`. + @inlinable + public func index(before: Index) -> Index { + return self.index(before, offsetBy: -1) + } + + /// Accesses the element at the specified index. + /// + /// You can subscript `CircularBuffer` with any valid index other than the + /// `CircularBuffer`'s end index. The end index refers to the position one + /// past the last element of a collection, so it doesn't correspond with an + /// element. + /// + /// - Parameter position: The position of the element to access. `position` + /// must be a valid index of the collection that is not equal to the + /// `endIndex` property. + /// + /// - Complexity: O(1) + @inlinable + public subscript(position: Index) -> Element { + get { + assert(position.isValidIndex(for: self), + "illegal index used, index was for CircularBuffer with count \(position._backingCheck), " + + "but actual count is \(self.count)") + return self._buffer[position.backingIndex]! + } + set { + assert(position.isValidIndex(for: self), + "illegal index used, index was for CircularBuffer with count \(position._backingCheck), " + + "but actual count is \(self.count)") + self._buffer[position.backingIndex] = newValue + } + } + + /// The position of the first element in a nonempty `CircularBuffer`. + /// + /// If the `CircularBuffer` is empty, `startIndex` is equal to `endIndex`. + @inlinable + public var startIndex: Index { + return .init(backingIndex: self.headBackingIndex, + backingCount: self.count, + backingIndexOfHead: self.headBackingIndex) + } + + /// The `CircularBuffer`'s "past the end" position---that is, the position one + /// greater than the last valid subscript argument. + /// + /// When you need a range that includes the last element of a collection, use + /// the half-open range operator (`..<`) with `endIndex`. The `..<` operator + /// creates a range that doesn't include the upper bound, so it's always + /// safe to use with `endIndex`. + /// + /// If the `CircularBuffer` is empty, `endIndex` is equal to `startIndex`. + @inlinable + public var endIndex: Index { + return .init(backingIndex: self.tailBackingIndex, + backingCount: self.count, + backingIndexOfHead: self.headBackingIndex) + } + + /// Returns the distance between two indices. + /// + /// Unless the collection conforms to the `BidirectionalCollection` protocol, + /// `start` must be less than or equal to `end`. + /// + /// - Parameters: + /// - start: A valid index of the collection. + /// - end: Another valid index of the collection. If `end` is equal to + /// `start`, the result is zero. + /// - Returns: The distance between `start` and `end`. The result can be + /// negative only if the collection conforms to the + /// `BidirectionalCollection` protocol. + /// + /// - Complexity: O(1) if the collection conforms to + /// `RandomAccessCollection`; otherwise, O(*k*), where *k* is the + /// resulting distance. + @inlinable + public func distance(from start: CircularBuffer.Index, to end: CircularBuffer.Index) -> Int { + let backingCount = self._buffer.count + + switch (start.isIndexGEQHeadIndex, end.isIndexGEQHeadIndex) { + case (true, true): + return end.backingIndex &- start.backingIndex + case (true, false): + return backingCount &- (start.backingIndex &- end.backingIndex) + case (false, true): + return -(backingCount &- (end.backingIndex &- start.backingIndex)) + case (false, false): + return end.backingIndex &- start.backingIndex + } + } + + @inlinable + public func _copyContents( + initializing buffer: UnsafeMutableBufferPointer + ) -> (Iterator, UnsafeMutableBufferPointer.Index) { + precondition(buffer.count >= self.count) + + guard var ptr = buffer.baseAddress else { + return (self.makeIterator(), buffer.startIndex) + } + + if self.tailBackingIndex >= self.headBackingIndex { + for index in self.headBackingIndex.. Index { + return .init(backingIndex: (i.backingIndex &+ distance) & self.mask, + backingCount: self.count, + backingIndexOfHead: self.headBackingIndex) + } + + @inlinable + public subscript(bounds: Range) -> SubSequence { + get { + precondition(self.distance(from: self.startIndex, to: bounds.lowerBound) >= 0) + precondition(self.distance(from: bounds.upperBound, to: self.endIndex) >= 0) + + var newRing = self + newRing.headBackingIndex = bounds.lowerBound.backingIndex + newRing.tailBackingIndex = bounds.upperBound.backingIndex + return newRing + } + set { + precondition(self.distance(from: self.startIndex, to: bounds.lowerBound) >= 0) + precondition(self.distance(from: bounds.upperBound, to: self.endIndex) >= 0) + + self.replaceSubrange(bounds, with: newValue) + } + } +} + +extension CircularBuffer { + + /// Allocates a buffer that can hold up to `initialCapacity` elements and initialise an empty ring backed by + /// the buffer. When the ring grows to more than `initialCapacity` elements the buffer will be expanded. + @inlinable + public init(initialCapacity: Int) { + let capacity = Int(UInt32(initialCapacity).nextPowerOf2()) + self.headBackingIndex = 0 + self.tailBackingIndex = 0 + self._buffer = ContiguousArray(repeating: nil, count: capacity) + assert(self._buffer.count == capacity) + } + + /// Allocates an empty buffer. + @inlinable + public init() { + self = .init(initialCapacity: 16) + } + + /// Append an element to the end of the ring buffer. + /// + /// Amortized *O(1)* + @inlinable + public mutating func append(_ value: Element) { + self._buffer[self.tailBackingIndex] = value + self.advanceTailIdx(by: 1) + + if self.headBackingIndex == self.tailBackingIndex { + // No more room left for another append so grow the buffer now. + self._doubleCapacity() + } + } + + /// Prepend an element to the front of the ring buffer. + /// + /// Amortized *O(1)* + @inlinable + public mutating func prepend(_ value: Element) { + let idx = self.indexBeforeHeadIdx() + self._buffer[idx] = value + self.advanceHeadIdx(by: -1) + + if self.headBackingIndex == self.tailBackingIndex { + // No more room left for another append so grow the buffer now. + self._doubleCapacity() + } + } + + /// Double the capacity of the buffer and adjust the headIdx and tailIdx. + /// + /// Must only be called when buffer is full. + @inlinable + internal mutating func _doubleCapacity() { + // Double the storage. This can't use _resizeAndFlatten because the buffer is + // full at this stage. That's ok: we have some optimised code paths for this use-case. + let newCapacity = self.capacity << 1 + assert(self.headBackingIndex == self.tailBackingIndex) + + var newBacking: ContiguousArray = [] + precondition(newCapacity > 0, "Can't change capacity to \(newCapacity)") + assert(newCapacity % 2 == 0) + assert(newCapacity > self.capacity) + + newBacking.reserveCapacity(newCapacity) + newBacking.append(contentsOf: self._buffer[self.headBackingIndex...]) + newBacking.append(contentsOf: self._buffer[.. = [] + precondition(newCapacity > 0, "Can't change capacity to \(newCapacity)") + assert(newCapacity % 2 == 0) + assert(newCapacity > self.capacity) + + newBacking.reserveCapacity(newCapacity) + + if self.tailBackingIndex >= self.headBackingIndex { + newBacking.append(contentsOf: self._buffer[self.headBackingIndex.. Element { + get { + return self[self.index(self.startIndex, offsetBy: offset)] + } + set { + self[self.index(self.startIndex, offsetBy: offset)] = newValue + } + } + + /// Returns whether the ring is empty. + @inlinable + public var isEmpty: Bool { + return self.headBackingIndex == self.tailBackingIndex + } + + /// Returns the number of element in the ring. + @inlinable + public var count: Int { + if self.tailBackingIndex >= self.headBackingIndex { + return self.tailBackingIndex &- self.headBackingIndex + } else { + return self._buffer.count &- (self.headBackingIndex &- self.tailBackingIndex) + } + } + + /// The total number of elements that the ring can contain without allocating new storage. + @inlinable + public var capacity: Int { + return self._buffer.count + } + + /// Removes all members from the circular buffer whist keeping the capacity. + @inlinable + public mutating func removeAll(keepingCapacity: Bool = false) { + if keepingCapacity { + self.removeFirst(self.count) + } else { + self._buffer.removeAll(keepingCapacity: false) + self._buffer.append(nil) + } + self.headBackingIndex = 0 + self.tailBackingIndex = 0 + assert(self.verifyInvariants()) + } + + + /// Modify the element at `index`. + /// + /// This function exists to provide a method of modifying the element in its underlying backing storage, instead + /// of copying it out, modifying it, and copying it back in. This emulates the behaviour of the `_modify` accessor + /// that is part of the generalized accessors work. That accessor is currently underscored and not safe to use, so + /// this is the next best thing. + /// + /// Note that this function is not guaranteed to be fast. In particular, as it is both generic and accepts a closure + /// it is possible that it will be slower than using the get/modify/set path that occurs with the subscript. If you + /// are interested in using this function for performance you *must* test and verify that the optimisation applies + /// correctly in your situation. + /// + /// - parameters: + /// - index: The index of the object that should be modified. If this index is invalid this function will trap. + /// - modifyFunc: The function to apply to the modified object. + @inlinable + public mutating func modify(_ index: Index, _ modifyFunc: (inout Element) throws -> Result) rethrows -> Result { + return try modifyFunc(&self._buffer[index.backingIndex]!) + } + + // MARK: CustomStringConvertible implementation + /// Returns a human readable description of the ring. + public var description: String { + var desc = "[ " + for el in self._buffer.enumerated() { + if el.0 == self.headBackingIndex { + desc += "<" + } else if el.0 == self.tailBackingIndex { + desc += ">" + } + desc += el.1.map { "\($0) " } ?? "_ " + } + desc += "]" + desc += " (bufferCapacity: \(self._buffer.count), ringLength: \(self.count))" + return desc + } +} + +// MARK: - RangeReplaceableCollection +extension CircularBuffer: RangeReplaceableCollection { + /// Removes and returns the first element of the `CircularBuffer`. + /// + /// Calling this method may invalidate all saved indices of this + /// `CircularBuffer`. Do not rely on a previously stored index value after + /// altering a `CircularBuffer` with any operation that can change its length. + /// + /// - Returns: The first element of the `CircularBuffer` if the `CircularBuffer` is not + /// empty; otherwise, `nil`. + /// + /// - Complexity: O(1) + @inlinable + public mutating func popFirst() -> Element? { + if count > 0 { + return self.removeFirst() + } else { + return nil + } + } + + /// Removes and returns the last element of the `CircularBuffer`. + /// + /// Calling this method may invalidate all saved indices of this + /// `CircularBuffer`. Do not rely on a previously stored index value after + /// altering a `CircularBuffer` with any operation that can change its length. + /// + /// - Returns: The last element of the `CircularBuffer` if the `CircularBuffer` is not + /// empty; otherwise, `nil`. + /// + /// - Complexity: O(1) + @inlinable + public mutating func popLast() -> Element? { + if count > 0 { + return self.removeLast() + } else { + return nil + } + } + + /// Removes the specified number of elements from the end of the + /// `CircularBuffer`. + /// + /// Attempting to remove more elements than exist in the `CircularBuffer` + /// triggers a runtime error. + /// + /// Calling this method may invalidate all saved indices of this + /// `CircularBuffer`. Do not rely on a previously stored index value after + /// altering a `CircularBuffer` with any operation that can change its length. + /// + /// - Parameter k: The number of elements to remove from the `CircularBuffer`. + /// `k` must be greater than or equal to zero and must not exceed the + /// number of elements in the `CircularBuffer`. + /// + /// - Complexity: O(*k*), where *k* is the specified number of elements. + @inlinable + public mutating func removeLast(_ k: Int) { + precondition(k <= self.count, "Number of elements to drop bigger than the amount of elements in the buffer.") + var idx = self.tailBackingIndex + for _ in 0 ..< k { + idx = self.indexAdvanced(index: idx, by: -1) + self._buffer[idx] = nil + } + self.tailBackingIndex = idx + } + + + /// Removes the specified number of elements from the beginning of the + /// `CircularBuffer`. + /// + /// Calling this method may invalidate any existing indices for use with this + /// `CircularBuffer`. + /// + /// - Parameter k: The number of elements to remove. + /// `k` must be greater than or equal to zero and must not exceed the + /// number of elements in the `CircularBuffer`. + /// + /// - Complexity: O(*k*), where *k* is the specified number of elements. + @inlinable + public mutating func removeFirst(_ k: Int) { + precondition(k <= self.count, "Number of elements to drop bigger than the amount of elements in the buffer.") + var idx = self.headBackingIndex + for _ in 0 ..< k { + self._buffer[idx] = nil + idx = self.indexAdvanced(index: idx, by: 1) + } + self.headBackingIndex = idx + } + + /// Removes and returns the first element of the `CircularBuffer`. + /// + /// The `CircularBuffer` must not be empty. + /// + /// Calling this method may invalidate any existing indices for use with this + /// `CircularBuffer`. + /// + /// - Returns: The removed element. + /// + /// - Complexity: O(*1*) + @discardableResult + @inlinable + public mutating func removeFirst() -> Element { + defer { + self.removeFirst(1) + } + return self.first! + } + + /// Removes and returns the last element of the `CircularBuffer`. + /// + /// The `CircularBuffer` must not be empty. + /// + /// Calling this method may invalidate all saved indices of this + /// `CircularBuffer`. Do not rely on a previously stored index value after + /// altering the `CircularBuffer` with any operation that can change its length. + /// + /// - Returns: The last element of the `CircularBuffer`. + /// + /// - Complexity: O(*1*) + @discardableResult + @inlinable + public mutating func removeLast() -> Element { + defer { + self.removeLast(1) + } + return self.last! + } + + /// Replaces the specified subrange of elements with the given `CircularBuffer`. + /// + /// - Parameter subrange: The subrange of the collection to replace. The bounds of the range must be valid indices + /// of the `CircularBuffer`. + /// + /// - Parameter newElements: The new elements to add to the `CircularBuffer`. + /// + /// *O(n)* where _n_ is the length of the new elements collection if the subrange equals to _n_ + /// + /// *O(m)* where _m_ is the combined length of the collection and _newElements_ + @inlinable + public mutating func replaceSubrange(_ subrange: Range, with newElements: C) where Element == C.Element { + precondition(subrange.lowerBound >= self.startIndex && subrange.upperBound <= self.endIndex, + "Subrange out of bounds") + assert(subrange.lowerBound.isValidIndex(for: self), + "illegal index used, index was for CircularBuffer with count \(subrange.lowerBound._backingCheck), " + + "but actual count is \(self.count)") + assert(subrange.upperBound.isValidIndex(for: self), + "illegal index used, index was for CircularBuffer with count \(subrange.upperBound._backingCheck), " + + "but actual count is \(self.count)") + + let subrangeCount = self.distance(from: subrange.lowerBound, to: subrange.upperBound) + + if subrangeCount == newElements.count { + var index = subrange.lowerBound + for element in newElements { + self._buffer[index.backingIndex] = element + index = self.index(after: index) + } + } else if subrangeCount == self.count && newElements.isEmpty { + self.removeSubrange(subrange) + } else { + var newBuffer: ContiguousArray = [] + let neededNewCapacity = self.count + newElements.count - subrangeCount + 1 /* always one spare */ + let newCapacity = Swift.max(self.capacity, neededNewCapacity.nextPowerOf2()) + newBuffer.reserveCapacity(newCapacity) + + // This mapping is required due to an inconsistent ability to append sequences of non-optional + // to optional sequences. + // https://bugs.swift.org/browse/SR-7921 + newBuffer.append(contentsOf: self[self.startIndex ..< subrange.lowerBound].lazy.map { $0 }) + newBuffer.append(contentsOf: newElements.lazy.map { $0 }) + newBuffer.append(contentsOf: self[subrange.upperBound.. 0 { + newBuffer.append(contentsOf: repeatElement(nil, count: repetitionCount)) + } + self._buffer = newBuffer + self.headBackingIndex = 0 + self.tailBackingIndex = newBuffer.count &- repetitionCount + } + assert(self.verifyInvariants()) + } + + /// Removes the elements in the specified subrange from the circular buffer. + /// + /// - Parameter bounds: The range of the circular buffer to be removed. The bounds of the range must be valid indices of the collection. + @inlinable + public mutating func removeSubrange(_ bounds: Range) { + precondition(bounds.upperBound >= self.startIndex && bounds.upperBound <= self.endIndex, "Invalid bounds.") + + let boundsCount = self.distance(from: bounds.lowerBound, to: bounds.upperBound) + switch boundsCount { + case 1: + remove(at: bounds.lowerBound) + case self.count: + self = .init(initialCapacity: self._buffer.count) + default: + replaceSubrange(bounds, with: []) + } + assert(self.verifyInvariants()) + } + + /// Removes & returns the item at `position` from the buffer + /// + /// - Parameter position: The index of the item to be removed from the buffer. + /// + /// *O(1)* if the position is `headIdx` or `tailIdx`. + /// otherwise + /// *O(n)* where *n* is the number of elements between `position` and `tailIdx`. + @discardableResult + @inlinable + public mutating func remove(at position: Index) -> Element { + assert(position.isValidIndex(for: self), + "illegal index used, index was for CircularBuffer with count \(position._backingCheck), " + + "but actual count is \(self.count)") + defer { + assert(self.verifyInvariants()) + } + precondition(self.indices.contains(position), "Position out of bounds.") + var bufferIndex = position.backingIndex + let element = self._buffer[bufferIndex]! + + switch bufferIndex { + case self.headBackingIndex: + self.advanceHeadIdx(by: 1) + self._buffer[bufferIndex] = nil + case self.indexBeforeTailIdx(): + self.advanceTailIdx(by: -1) + self._buffer[bufferIndex] = nil + default: + self._buffer[bufferIndex] = nil + var nextIndex = self.indexAdvanced(index: bufferIndex, by: 1) + while nextIndex != self.tailBackingIndex { + self._buffer.swapAt(bufferIndex, nextIndex) + bufferIndex = nextIndex + nextIndex = self.indexAdvanced(index: bufferIndex, by: 1) + } + self.advanceTailIdx(by: -1) + } + + return element + } + + /// The first `Element` of the `CircularBuffer` (or `nil` if empty). + @inlinable + public var first: Element? { + // We implement this here to work around https://bugs.swift.org/browse/SR-14516 + guard !self.isEmpty else { + return nil + } + return self[self.startIndex] + } + + /// Prepares the `CircularBuffer` to store the specified number of elements. + @inlinable + public mutating func reserveCapacity(_ minimumCapacity: Int) { + if self.capacity >= minimumCapacity { + // Already done, do nothing. + return + } + + // We need to allocate a larger buffer. We take this opportunity to make ourselves contiguous + // again as needed. + let targetCapacity = minimumCapacity.nextPowerOf2() + self._resizeAndFlatten(newCapacity: targetCapacity) + } +} + +extension CircularBuffer { + @usableFromInline + internal func verifyInvariants() -> Bool { + var index = self.headBackingIndex + while index != self.tailBackingIndex { + if self._buffer[index] == nil { + return false + } + index = self.indexAdvanced(index: index, by: 1) + } + return true + } + + // this is not a general invariant (not true for CircularBuffer that have been sliced) + private func unreachableAreNil() -> Bool { + var index = self.tailBackingIndex + while index != self.headBackingIndex { + if self._buffer[index] != nil { + return false + } + index = self.indexAdvanced(index: index, by: 1) + } + return true + } + + internal func testOnly_verifyInvariantsForNonSlices() -> Bool { + return self.verifyInvariants() && self.unreachableAreNil() + } +} + +extension CircularBuffer: Equatable where Element: Equatable { + public static func ==(lhs: CircularBuffer, rhs: CircularBuffer) -> Bool { + return lhs.count == rhs.count && zip(lhs, rhs).allSatisfy(==) + } +} + +extension CircularBuffer: Hashable where Element: Hashable { + public func hash(into hasher: inout Hasher) { + for element in self { + hasher.combine(element) + } + } +} + +extension CircularBuffer: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: Element...) { + self.init(elements) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Codec.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Codec.swift new file mode 100644 index 00000000..c4ef6a4a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Codec.swift @@ -0,0 +1,814 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// State of the current decoding process. +public enum DecodingState { + /// Continue decoding. + case `continue` + + /// Stop decoding until more data is ready to be processed. + case needMoreData +} + +/// Common errors thrown by `ByteToMessageDecoder`s. +public enum ByteToMessageDecoderError: Error { + /// More data has been received by a `ByteToMessageHandler` despite the fact that an error has previously been + /// emitted. The associated `Error` is the error previously emitted and the `ByteBuffer` is the extra data that has + /// been received. The common cause for this error to be emitted is the user not having torn down the `Channel` + /// after previously an `Error` has been sent through the pipeline using `fireErrorCaught`. + case dataReceivedInErrorState(Error, ByteBuffer) + + /// This error can be thrown by `ByteToMessageDecoder`s if there was unexpectedly some left-over data when the + /// `ByteToMessageDecoder` was removed from the pipeline or the `Channel` was closed. + case leftoverDataWhenDone(ByteBuffer) +} + +extension ByteToMessageDecoderError { + // TODO: For NIO 3, make this an enum case (or whatever best way for Errors we have come up with). + /// This error can be thrown by `ByteToMessageDecoder`s if the incoming payload is larger than the max specified. + public struct PayloadTooLargeError: Error { + public init() {} + } +} + + +/// `ByteToMessageDecoder`s decode bytes in a stream-like fashion from `ByteBuffer` to another message type. +/// +/// ### Purpose +/// +/// A `ByteToMessageDecoder` provides a simplified API for handling streams of incoming data that can be broken +/// up into messages. This API boils down to two methods: `decode`, and `decodeLast`. These two methods, when +/// implemented, will be used by a `ByteToMessageHandler` paired with a `ByteToMessageDecoder` to decode the +/// incoming byte stream into a sequence of messages. +/// +/// The reason this helper exists is to smooth away some of the boilerplate and edge case handling code that +/// is often necessary when implementing parsers in a SwiftNIO `ChannelPipeline`. A `ByteToMessageDecoder` +/// never needs to worry about how inbound bytes will be buffered, as `ByteToMessageHandler` deals with that +/// automatically. A `ByteToMessageDecoder` also never needs to worry about memory exclusivity violations +/// that can occur when re-entrant `ChannelPipeline` operations occur, as `ByteToMessageHandler` will deal with +/// those as well. +/// +/// ### Implementing ByteToMessageDecoder +/// +/// A type that implements `ByteToMessageDecoder` may implement two methods: decode and decodeLast. Implementations +/// must implement decode: if they do not implement decodeLast, a default implementation will be used that +/// simply calls decode. +/// +/// `decode` is the main decoding method, and is the one that will be called most often. `decode` is invoked +/// whenever data is received by the wrapping `ByteToMessageHandler`. It is invoked with a `ByteBuffer` containing +/// all the received data (including any data previously buffered), as well as a `ChannelHandlerContext` that can be +/// used in the `decode` function. +/// +/// `decode` is called in a loop by the `ByteToMessageHandler`. This loop continues until one of two cases occurs: +/// +/// 1. The input `ByteBuffer` has no more readable bytes (i.e. `.readableBytes == 0`); OR +/// 2. The `decode` method returns `.needMoreData`. +/// +/// The reason this method is invoked in a loop is to ensure that the stream-like properties of inbound data are +/// respected. It is entirely possible for `ByteToMessageDecoder` to receive either fewer bytes than a single message, +/// or multiple messages in one go. Rather than have the `ByteToMessageDecoder` handle all of the complexity of this, +/// the logic can be boiled down to a single choice: has the `ByteToMessageDecoder` been able to move the state forward +/// or not? If it has, rather than containing an internal loop it may simply return `.continue` in order to request that +/// `decode` be invoked again immediately. If it has not, it can return `.needMoreData` to ask to be left alone until more +/// data has been returned from the network. +/// +/// Essentially, if the next parsing step could not be taken because there wasn't enough data available, return `.needMoreData`. +/// Otherwise, return `.continue`. This will allow a `ByteToMessageDecoder` implementation to ignore the awkward way data +/// arrives from the network, and to just treat it as a series of `decode` calls. +/// +/// `decodeLast` is a cousin of `decode`. It is also called in a loop, but unlike with `decode` this loop will only ever +/// occur once: when the `ChannelHandlerContext` belonging to this `ByteToMessageDecoder` is about to become invalidated. +/// This invalidation happens in two situations: when EOF is received from the network, or when the `ByteToMessageDecoder` +/// is being removed from the `ChannelPipeline`. The distinction between these two states is captured by the value of +/// `seenEOF`. +/// +/// In this condition, the `ByteToMessageDecoder` must now produce any final messages it can with the bytes it has +/// available. In protocols where EOF is used as a message delimiter, having `decodeLast` called with `seenEOF == true` +/// may produce further messages. In other cases, `decodeLast` may choose to deliver any buffered bytes as "leftovers", +/// either in error messages or via `channelRead`. This can occur if, for example, a protocol upgrade is occurring. +/// +/// As with `decode`, `decodeLast` is invoked in a loop. This allows the same simplification as `decode` allows: when +/// a message is completely parsed, the `decodeLast` function can return `.continue` and be re-invoked from the top, +/// rather than containing an internal loop. +/// +/// Note that the value of `seenEOF` may change between calls to `decodeLast` in some rare situations. +/// +/// ### Implementers Notes +/// +/// /// `ByteToMessageHandler` will turn your `ByteToMessageDecoder` into a `ChannelInboundHandler`. `ByteToMessageHandler` +/// also solves a couple of tricky issues for you. Most importantly, in a `ByteToMessageDecoder` you do _not_ need to +/// worry about re-entrancy. Your code owns the passed-in `ByteBuffer` for the duration of the `decode`/`decodeLast` call and +/// can modify it at will. +/// +/// If a custom frame decoder is required, then one needs to be careful when implementing +/// one with `ByteToMessageDecoder`. Ensure there are enough bytes in the buffer for a +/// complete frame by checking `buffer.readableBytes`. If there are not enough bytes +/// for a complete frame, return without modifying the reader index to allow more bytes to arrive. +/// +/// To check for complete frames without modifying the reader index, use methods like `buffer.getInteger`. +/// You _MUST_ use the reader index when using methods like `buffer.getInteger`. +/// For example calling `buffer.getInteger(at: 0)` is assuming the frame starts at the beginning of the buffer, which +/// is not always the case. Use `buffer.getInteger(at: buffer.readerIndex)` instead. +/// +/// If you move the reader index forward, either manually or by using one of `buffer.read*` methods, you must ensure +/// that you no longer need to see those bytes again as they will not be returned to you the next time `decode` is +/// called. If you still need those bytes to come back, consider taking a local copy of buffer inside the function to +/// perform your read operations on. +/// +/// The `ByteBuffer` passed in as `buffer` is a slice of a larger buffer owned by the `ByteToMessageDecoder` +/// implementation. Some aspects of this buffer are preserved across calls to `decode`, meaning that any changes to +/// those properties you make in your `decode` method will be reflected in the next call to decode. In particular, +/// moving the reader index forward persists across calls. When your method returns, if the reader index has advanced, +/// those bytes are considered "consumed" and will not be available in future calls to `decode`. +/// Please note, however, that the numerical value of the `readerIndex` itself is not preserved, and may not be the same +/// from one call to the next. Please do not rely on this numerical value: if you need +/// to recall where a byte is relative to the `readerIndex`, use an offset rather than an absolute value. +/// +/// ### Using ByteToMessageDecoder +/// +/// To add a `ByteToMessageDecoder` to the `ChannelPipeline` use +/// +/// channel.pipeline.addHandler(ByteToMessageHandler(MyByteToMessageDecoder())) +/// +public protocol ByteToMessageDecoder { + /// The type of the messages this `ByteToMessageDecoder` decodes to. + associatedtype InboundOut + + /// Decode from a `ByteBuffer`. + /// + /// This method will be called in a loop until either the input `ByteBuffer` has nothing to read left or + /// `DecodingState.needMoreData` is returned. If `DecodingState.continue` is returned and the `ByteBuffer` + /// contains more readable bytes, this method will immediately be invoked again, unless `decodeLast` needs + /// to be invoked instead. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ByteToMessageDecoder` belongs to. + /// - buffer: The `ByteBuffer` from which we decode. + /// - returns: `DecodingState.continue` if we should continue calling this method or `DecodingState.needMoreData` if it should be called + /// again once more data is present in the `ByteBuffer`. + mutating func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState + + /// Decode from a `ByteBuffer` when no more data is incoming and the `ByteToMessageDecoder` is about to leave + /// the pipeline. + /// + /// This method is called in a loop only once, when the `ChannelHandlerContext` goes inactive (i.e. when `channelInactive` is fired or + /// the `ByteToMessageDecoder` is removed from the pipeline). + /// + /// Like with `decode`, this method will be called in a loop until either `DecodingState.needMoreData` is returned from the method + /// or until the input `ByteBuffer` has no more readable bytes. If `DecodingState.continue` is returned and the `ByteBuffer` + /// contains more readable bytes, this method will immediately be invoked again. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ByteToMessageDecoder` belongs to. + /// - buffer: The `ByteBuffer` from which we decode. + /// - seenEOF: `true` if EOF has been seen. Usually if this is `false` the handler has been removed. + /// - returns: `DecodingState.continue` if we should continue calling this method or `DecodingState.needMoreData` if it should be called + /// again when more data is present in the `ByteBuffer`. + mutating func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState + + /// Called once this `ByteToMessageDecoder` is removed from the `ChannelPipeline`. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ByteToMessageDecoder` belongs to. + mutating func decoderRemoved(context: ChannelHandlerContext) + + /// Called when this `ByteToMessageDecoder` is added to the `ChannelPipeline`. + /// + /// - parameters: + /// - context: The `ChannelHandlerContext` which this `ByteToMessageDecoder` belongs to. + mutating func decoderAdded(context: ChannelHandlerContext) + + /// Determine if the read bytes in the given `ByteBuffer` should be reclaimed and their associated memory freed. + /// Be aware that reclaiming memory may involve memory copies and so is not free. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` to check + /// - return: `true` if memory should be reclaimed, `false` otherwise. + mutating func shouldReclaimBytes(buffer: ByteBuffer) -> Bool +} + +/// Some `ByteToMessageDecoder`s need to observe `write`s (which are outbound events). `ByteToMessageDecoder`s which +/// implement the `WriteObservingByteToMessageDecoder` protocol will be notified about every outbound write. +/// +/// `WriteObservingByteToMessageDecoder` may only observe a `write` and must not try to transform or block it in any +/// way. After the `write` method returns the `write` will be forwarded to the next outbound handler. +public protocol WriteObservingByteToMessageDecoder: ByteToMessageDecoder { + /// The type of `write`s. + associatedtype OutboundIn + + /// `write` is called for every incoming `write` incoming to the corresponding `ByteToMessageHandler`. + /// + /// - parameters: + /// - data: The data that was written. + mutating func write(data: OutboundIn) +} + +extension ByteToMessageDecoder { + public mutating func decoderRemoved(context: ChannelHandlerContext) { + } + + public mutating func decoderAdded(context: ChannelHandlerContext) { + } + + /// Default implementation to detect once bytes should be reclaimed. + public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool { + // We want to reclaim in the following cases: + // + // 1. If there is at least 2kB of memory to reclaim + // 2. If the buffer is more than 50% reclaimable memory and is at least + // 1kB in size. + if buffer.readerIndex >= 2048 { + return true + } + return buffer.storageCapacity > 1024 && (buffer.storageCapacity - buffer.readerIndex) < buffer.readerIndex + } + + public func wrapInboundOut(_ value: InboundOut) -> NIOAny { + return NIOAny(value) + } + + public mutating func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + while try self.decode(context: context, buffer: &buffer) == .continue {} + return .needMoreData + } +} + +private struct B2MDBuffer { + /// `B2MDBuffer`'s internal state, either we're already processing a buffer or we're ready to. + private enum State { + case processingInProgress + case ready + } + + /// Can we produce a buffer to be processed right now or not? + enum BufferAvailability { + /// No, because no bytes available + case nothingAvailable + /// No, because we're already processing one + case bufferAlreadyBeingProcessed + /// Yes please, here we go. + case available(ByteBuffer) + } + + /// Result of a try to process a buffer. + enum BufferProcessingResult { + /// Could not process a buffer because we are already processing one on the same call stack. + case cannotProcessReentrantly + /// Yes, we did process some. + case didProcess(DecodingState) + } + + private var state: State = .ready + private var buffers: CircularBuffer = CircularBuffer(initialCapacity: 4) + private let emptyByteBuffer: ByteBuffer + + init(emptyByteBuffer: ByteBuffer) { + assert(emptyByteBuffer.readableBytes == 0) + self.emptyByteBuffer = emptyByteBuffer + } +} + +// MARK: B2MDBuffer Main API +extension B2MDBuffer { + /// Start processing some bytes if possible, if we receive a returned buffer (through `.available(ByteBuffer)`) + /// we _must_ indicate the processing has finished by calling `finishProcessing`. + mutating func startProcessing(allowEmptyBuffer: Bool) -> BufferAvailability { + switch self.state { + case .processingInProgress: + return .bufferAlreadyBeingProcessed + case .ready where self.buffers.count > 0: + var buffer = self.buffers.removeFirst() + buffer.writeBuffers(self.buffers) + self.buffers.removeAll(keepingCapacity: self.buffers.capacity < 16) // don't grow too much + if buffer.readableBytes > 0 || allowEmptyBuffer { + self.state = .processingInProgress + return .available(buffer) + } else { + return .nothingAvailable + } + case .ready: + assert(self.buffers.isEmpty) + if allowEmptyBuffer { + self.state = .processingInProgress + return .available(self.emptyByteBuffer) + } + return .nothingAvailable + } + } + + mutating func finishProcessing(remainder buffer: inout ByteBuffer) -> Void { + assert(self.state == .processingInProgress) + self.state = .ready + if buffer.readableBytes == 0 && self.buffers.isEmpty { + // fast path, no bytes left and no other buffers, just return + return + } + if buffer.readableBytes > 0 { + self.buffers.prepend(buffer) + } else { + buffer.discardReadBytes() + buffer.writeBuffers(self.buffers) + self.buffers.removeAll(keepingCapacity: self.buffers.capacity < 16) // don't grow too much + self.buffers.append(buffer) + } + } + + mutating func append(buffer: ByteBuffer) { + if buffer.readableBytes > 0 { + self.buffers.append(buffer) + } + } +} + +// MARK: B2MDBuffer Helpers +private extension ByteBuffer { + mutating func writeBuffers(_ buffers: CircularBuffer) { + guard buffers.count > 0 else { + return + } + var requiredCapacity: Int = self.writerIndex + for buffer in buffers { + requiredCapacity += buffer.readableBytes + } + self.reserveCapacity(requiredCapacity) + for var buffer in buffers { + self.writeBuffer(&buffer) + } + } +} + +private extension B2MDBuffer { + func _testOnlyOneBuffer() -> ByteBuffer? { + switch self.buffers.count { + case 0: + return nil + case 1: + return self.buffers.first + default: + let firstIndex = self.buffers.startIndex + var firstBuffer = self.buffers[firstIndex] + for var buffer in self.buffers[self.buffers.index(after: firstIndex)...] { + firstBuffer.writeBuffer(&buffer) + } + return firstBuffer + } + } +} + +/// A handler which turns a given `ByteToMessageDecoder` into a `ChannelInboundHandler` that can then be added to a +/// `ChannelPipeline`. +/// +/// Most importantly, `ByteToMessageHandler` handles the tricky buffer management for you and flattens out all +/// re-entrancy on `channelRead` that may happen in the `ChannelPipeline`. +public final class ByteToMessageHandler { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = Decoder.InboundOut + + private enum DecodeMode { + /// This is a usual decode, ie. not the last chunk + case normal + + /// Last chunk + case last + } + + private enum RemovalState { + /// Not added to any `ChannelPipeline` yet. + case notAddedToPipeline + + /// No one tried to remove this handler. + case notBeingRemoved + + /// The user-triggered removal has been started but isn't complete yet. This state will not be entered if the + /// removal is triggered by Channel teardown. + case removalStarted + + /// The user-triggered removal is complete. This state will not be entered if the removal is triggered by + /// Channel teardown. + case removalCompleted + + /// This handler has been removed from the pipeline. + case handlerRemovedCalled + } + + private enum State { + case active + case leftoversNeedProcessing + case done + case error(Error) + + var isError: Bool { + switch self { + case .active, .leftoversNeedProcessing, .done: + return false + case .error: + return true + } + } + + var isFinalState: Bool { + switch self { + case .active, .leftoversNeedProcessing: + return false + case .done, .error: + return true + } + } + + var isActive: Bool { + switch self { + case .done, .error, .leftoversNeedProcessing: + return false + case .active: + return true + } + } + + var isLeftoversNeedProcessing: Bool { + switch self { + case .done, .error, .active: + return false + case .leftoversNeedProcessing: + return true + } + } + } + + internal private(set) var decoder: Decoder? // only `nil` if we're already decoding (ie. we're re-entered) + private let maximumBufferSize: Int? + private var queuedWrites = CircularBuffer(initialCapacity: 1) // queues writes received whilst we're already decoding (re-entrant write) + private var state: State = .active { + willSet { + assert(!self.state.isFinalState, "illegal state on state set: \(self.state)") // we can never leave final states + } + } + private var removalState: RemovalState = .notAddedToPipeline + // sadly to construct a B2MDBuffer we need an empty ByteBuffer which we can only get from the allocator, so IUO. + private var buffer: B2MDBuffer! + private var seenEOF: Bool = false + private var selfAsCanDequeueWrites: CanDequeueWrites? = nil + + /// @see: ByteToMessageHandler.init(_:maximumBufferSize) + public convenience init(_ decoder: Decoder) { + self.init(decoder, maximumBufferSize: nil) + } + + /// Initialize a `ByteToMessageHandler`. + /// + /// - parameters: + /// - decoder: The `ByteToMessageDecoder` to decode the bytes into message. + /// - maximumBufferSize: The maximum number of bytes to aggregate in-memory. + public init(_ decoder: Decoder, maximumBufferSize: Int? = nil) { + self.decoder = decoder + self.maximumBufferSize = maximumBufferSize + } + + deinit { + if self.removalState != .notAddedToPipeline { + // we have been added to the pipeline, if not, we don't need to check our state. + assert(self.removalState == .handlerRemovedCalled, + "illegal state in deinit: removalState = \(self.removalState)") + assert(self.state.isFinalState, "illegal state in deinit: state = \(self.state)") + } + } +} + +// MARK: ByteToMessageHandler: Test Helpers +extension ByteToMessageHandler { + internal var cumulationBuffer: ByteBuffer? { + return self.buffer._testOnlyOneBuffer() + } +} + +private protocol CanDequeueWrites { + func dequeueWrites() +} + +extension ByteToMessageHandler: CanDequeueWrites where Decoder: WriteObservingByteToMessageDecoder { + fileprivate func dequeueWrites() { + while self.queuedWrites.count > 0 { + // self.decoder can't be `nil`, this is only allowed to be called when we're not already on the stack + self.decoder!.write(data: self.unwrapOutboundIn(self.queuedWrites.removeFirst())) + } + } +} + + +// MARK: ByteToMessageHandler's Main API +extension ByteToMessageHandler { + @inline(__always) // allocations otherwise (reconsider with Swift 5.1) + private func withNextBuffer(allowEmptyBuffer: Bool, _ body: (inout Decoder, inout ByteBuffer) throws -> DecodingState) rethrows -> B2MDBuffer.BufferProcessingResult { + switch self.buffer.startProcessing(allowEmptyBuffer: allowEmptyBuffer) { + case .bufferAlreadyBeingProcessed: + return .cannotProcessReentrantly + case .nothingAvailable: + return .didProcess(.needMoreData) + case .available(var buffer): + var possiblyReclaimBytes = false + var decoder: Decoder? = nil + swap(&decoder, &self.decoder) + assert(decoder != nil) // self.decoder only `nil` if we're being re-entered, but .available means we're not + defer { + swap(&decoder, &self.decoder) + if buffer.readableBytes > 0 && possiblyReclaimBytes { + // we asserted above that the decoder we just swapped back in was non-nil so now `self.decoder` must + // be non-nil. + if self.decoder!.shouldReclaimBytes(buffer: buffer) { + buffer.discardReadBytes() + } + } + self.buffer.finishProcessing(remainder: &buffer) + } + let decodeResult = try body(&decoder!, &buffer) + + // If we .continue, there's no point in trying to reclaim bytes because we'll loop again. If we need more + // data on the other hand, we should try to reclaim some of those bytes. + possiblyReclaimBytes = decodeResult == .needMoreData + return .didProcess(decodeResult) + } + } + + private func processLeftovers(context: ChannelHandlerContext) { + guard self.state.isActive else { + // we are processing or have already processed the leftovers + return + } + + do { + switch try self.decodeLoop(context: context, decodeMode: .last) { + case .didProcess: + self.state = .done + case .cannotProcessReentrantly: + self.state = .leftoversNeedProcessing + } + } catch { + self.state = .error(error) + context.fireErrorCaught(error) + } + } + + private func tryDecodeWrites() { + if self.queuedWrites.count > 0 { + // this must succeed because unless we implement `CanDequeueWrites`, `queuedWrites` must always be empty. + self.selfAsCanDequeueWrites!.dequeueWrites() + } + } + + private func decodeLoop(context: ChannelHandlerContext, decodeMode: DecodeMode) throws -> B2MDBuffer.BufferProcessingResult { + assert(!self.state.isError) + var allowEmptyBuffer = decodeMode == .last + while (self.state.isActive && self.removalState == .notBeingRemoved) || decodeMode == .last { + let result = try self.withNextBuffer(allowEmptyBuffer: allowEmptyBuffer) { decoder, buffer in + let decoderResult: DecodingState + if decodeMode == .normal { + assert(self.state.isActive, "illegal state for normal decode: \(self.state)") + decoderResult = try decoder.decode(context: context, buffer: &buffer) + } else { + allowEmptyBuffer = false + decoderResult = try decoder.decodeLast(context: context, buffer: &buffer, seenEOF: self.seenEOF) + } + if decoderResult == .needMoreData, let maximumBufferSize = self.maximumBufferSize, buffer.readableBytes > maximumBufferSize { + throw ByteToMessageDecoderError.PayloadTooLargeError() + } + return decoderResult + } + switch result { + case .didProcess(.continue): + self.tryDecodeWrites() + continue + case .didProcess(.needMoreData): + if self.queuedWrites.count > 0 { + self.tryDecodeWrites() + continue // we might have received more, so let's spin once more + } else { + return .didProcess(.needMoreData) + } + case .cannotProcessReentrantly: + return .cannotProcessReentrantly + } + } + return .didProcess(.continue) + } +} + + +// MARK: ByteToMessageHandler: ChannelInboundHandler +extension ByteToMessageHandler: ChannelInboundHandler { + + public func handlerAdded(context: ChannelHandlerContext) { + guard self.removalState == .notAddedToPipeline else { + preconditionFailure("\(self) got readded to a ChannelPipeline but ByteToMessageHandler is single-use") + } + self.removalState = .notBeingRemoved + self.buffer = B2MDBuffer(emptyByteBuffer: context.channel.allocator.buffer(capacity: 0)) + // here we can force it because we know that the decoder isn't in use if we're just adding this handler + self.selfAsCanDequeueWrites = self as? CanDequeueWrites // we need to cache this as it allocates. + self.decoder!.decoderAdded(context: context) + } + + + public func handlerRemoved(context: ChannelHandlerContext) { + // very likely, the removal state is `.notBeingRemoved` or `.removalCompleted` here but we can't assert it + // because the pipeline might be torn down during the formal removal process. + self.removalState = .handlerRemovedCalled + if !self.state.isFinalState { + self.state = .done + } + + self.selfAsCanDequeueWrites = nil + + // here we can force it because we know that the decoder isn't in use because the removal is always + // eventLoop.execute'd + self.decoder!.decoderRemoved(context: context) + } + + /// Calls `decode` until there is nothing left to decode. + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let buffer = self.unwrapInboundIn(data) + if case .error(let error) = self.state { + context.fireErrorCaught(ByteToMessageDecoderError.dataReceivedInErrorState(error, buffer)) + return + } + self.buffer.append(buffer: buffer) + do { + switch try self.decodeLoop(context: context, decodeMode: .normal) { + case .didProcess: + switch self.state { + case .active: + () // cool, all normal + case .done, .error: + () // fair, all done already + case .leftoversNeedProcessing: + // seems like we received a `channelInactive` or `handlerRemoved` whilst we were processing a read + switch try self.decodeLoop(context: context, decodeMode: .last) { + case .didProcess: + () // expected and cool + case .cannotProcessReentrantly: + preconditionFailure("bug in NIO: non-reentrant decode loop couldn't run \(self), \(self.state)") + } + self.state = .done + } + case .cannotProcessReentrantly: + // fine, will be done later + () + } + } catch { + self.state = .error(error) + context.fireErrorCaught(error) + } + } + + /// Call `decodeLast` before forward the event through the pipeline. + public func channelInactive(context: ChannelHandlerContext) { + self.seenEOF = true + + self.processLeftovers(context: context) + + context.fireChannelInactive() + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if event as? ChannelEvent == .some(.inputClosed) { + self.seenEOF = true + + self.processLeftovers(context: context) + } + context.fireUserInboundEventTriggered(event) + } +} + +extension ByteToMessageHandler: ChannelOutboundHandler, _ChannelOutboundHandler where Decoder: WriteObservingByteToMessageDecoder { + public typealias OutboundIn = Decoder.OutboundIn + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + if self.decoder != nil { + let data = self.unwrapOutboundIn(data) + assert(self.queuedWrites.isEmpty) + self.decoder!.write(data: data) + } else { + self.queuedWrites.append(data) + } + context.write(data, promise: promise) + } +} + +/// A protocol for straightforward encoders which encode custom messages to `ByteBuffer`s. +/// To add a `MessageToByteEncoder` to a `ChannelPipeline`, use +/// `channel.pipeline.addHandler(MessageToByteHandler(myEncoder)`. +public protocol MessageToByteEncoder { + associatedtype OutboundIn + + /// Called once there is data to encode. + /// + /// - parameters: + /// - data: The data to encode into a `ByteBuffer`. + /// - out: The `ByteBuffer` into which we want to encode. + func encode(data: OutboundIn, out: inout ByteBuffer) throws +} + +extension ByteToMessageHandler: RemovableChannelHandler { + public func removeHandler(context: ChannelHandlerContext, removalToken: ChannelHandlerContext.RemovalToken) { + precondition(self.removalState == .notBeingRemoved) + self.removalState = .removalStarted + context.eventLoop.execute { + self.processLeftovers(context: context) + assert(!self.state.isLeftoversNeedProcessing, "illegal state: \(self.state)") + switch self.removalState { + case .removalStarted: + self.removalState = .removalCompleted + case .handlerRemovedCalled: + // if we're here, then the channel has also been torn down between the start and the completion of + // the user-triggered removal. That's okay. + () + default: + assertionFailure("illegal removal state: \(self.removalState)") + } + // this is necessary as it'll complete the promise. + context.leavePipeline(removalToken: removalToken) + } + } +} + +/// A handler which turns a given `MessageToByteEncoder` into a `ChannelOutboundHandler` that can then be added to a +/// `ChannelPipeline`. +public final class MessageToByteHandler: ChannelOutboundHandler { + public typealias OutboundOut = ByteBuffer + public typealias OutboundIn = Encoder.OutboundIn + + private enum State { + case notInChannelYet + case operational + case error(Error) + case done + + var readyToBeAddedToChannel: Bool { + switch self { + case .notInChannelYet: + return true + case .operational, .error, .done: + return false + } + } + } + + private var state: State = .notInChannelYet + private let encoder: Encoder + private var buffer: ByteBuffer? = nil + + public init(_ encoder: Encoder) { + self.encoder = encoder + } +} + +extension MessageToByteHandler { + public func handlerAdded(context: ChannelHandlerContext) { + precondition(self.state.readyToBeAddedToChannel, + "illegal state when adding to Channel: \(self.state)") + self.state = .operational + self.buffer = context.channel.allocator.buffer(capacity: 256) + } + + public func handlerRemoved(context: ChannelHandlerContext) { + self.state = .done + self.buffer = nil + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + switch self.state { + case .notInChannelYet: + preconditionFailure("MessageToByteHandler.write called before it was added to a Channel") + case .error(let error): + promise?.fail(error) + context.fireErrorCaught(error) + return + case .done: + // let's just ignore this + return + case .operational: + // there's actually some work to do here + break + } + let data = self.unwrapOutboundIn(data) + + do { + self.buffer!.clear() + try self.encoder.encode(data: data, out: &self.buffer!) + context.write(self.wrapOutboundOut(self.buffer!), promise: promise) + } catch { + self.state = .error(error) + promise?.fail(error) + context.fireErrorCaught(error) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ConvenienceOptionSupport.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ConvenienceOptionSupport.swift new file mode 100644 index 00000000..66cc0ec4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/ConvenienceOptionSupport.swift @@ -0,0 +1,186 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: Universal Client Bootstrap +extension NIOClientTCPBootstrapProtocol { + /// Apply any understood convenience options to the bootstrap, removing them from the set of options if they are consumed. + /// - parameters: + /// - options: The options to try applying - the options applied should be consumed from here. + /// - returns: The updated bootstrap with and options applied. + public func _applyChannelConvenienceOptions(_ options: inout ChannelOptions.TCPConvenienceOptions) -> Self { + // Default is to consume no options and not update self. + return self + } +} + +extension NIOClientTCPBootstrap { + /// Specifies some `TCPConvenienceOption`s to be applied to the channel. + /// These are preferred over regular channel options as they are easier to use and restrict + /// options to those which a normal user would consider. + /// - Parameter options: Set of convenience options to apply. + /// - Returns: The updated bootstrap (`self` being mutated) + public func channelConvenienceOptions(_ options: ChannelOptions.TCPConvenienceOptions) -> NIOClientTCPBootstrap { + var optionsRemaining = options + // First give the underlying a chance to consume options. + let withUnderlyingOverrides = + NIOClientTCPBootstrap(self, + updating: underlyingBootstrap._applyChannelConvenienceOptions(&optionsRemaining)) + // Default apply any remaining options. + return optionsRemaining.applyFallbackMapping(withUnderlyingOverrides) + } +} + +// MARK: Utility +extension ChannelOptions.Types { + /// Has an option been set? + /// Option has a value of generic type ValueType. + public enum ConvenienceOptionValue { + /// The option was not set. + case notSet + /// The option was set with a value of type ValueType. + case set(ValueType) + } +} + +extension ChannelOptions.Types.ConvenienceOptionValue where ValueType == () { + /// Convenience method working with bool options as bool values for set. + public var isSet: Bool { + get { + switch self { + case .notSet: + return false + case .set(()): + return true + } + } + } +} + +extension ChannelOptions.Types.ConvenienceOptionValue where ValueType == () { + fileprivate init(flag: Bool) { + if flag { + self = .set(()) + } else { + self = .notSet + } + } +} + +// MARK: TCP - data +extension ChannelOptions { + /// A TCP channel option which can be applied to a bootstrap using convenience notation. + public struct TCPConvenienceOption: Hashable { + fileprivate var data: ConvenienceOption + + private init(_ data: ConvenienceOption) { + self.data = data + } + + fileprivate enum ConvenienceOption: Hashable { + case allowLocalEndpointReuse + case disableAutoRead + case allowRemoteHalfClosure + } + } +} + +/// Approved convenience options. +extension ChannelOptions.TCPConvenienceOption { + /// Allow immediately reusing a local address. + public static let allowLocalEndpointReuse = ChannelOptions.TCPConvenienceOption(.allowLocalEndpointReuse) + + /// The user will manually call `Channel.read` once all the data is read from the transport. + public static let disableAutoRead = ChannelOptions.TCPConvenienceOption(.disableAutoRead) + + /// Allows users to configure whether the `Channel` will close itself when its remote + /// peer shuts down its send stream, or whether it will remain open. If set to `false` (the default), the `Channel` + /// will be closed automatically if the remote peer shuts down its send stream. If set to true, the `Channel` will + /// not be closed: instead, a `ChannelEvent.inboundClosed` user event will be sent on the `ChannelPipeline`, + /// and no more data will be received. + public static let allowRemoteHalfClosure = + ChannelOptions.TCPConvenienceOption(.allowRemoteHalfClosure) +} + +extension ChannelOptions { + /// A set of `TCPConvenienceOption`s + public struct TCPConvenienceOptions: ExpressibleByArrayLiteral, Hashable { + var allowLocalEndpointReuse = false + var disableAutoRead = false + var allowRemoteHalfClosure = false + + /// Construct from an array literal. + @inlinable + public init(arrayLiteral elements: TCPConvenienceOption...) { + for element in elements { + self.add(element) + } + } + + @usableFromInline + mutating func add(_ element: TCPConvenienceOption) { + switch element.data { + case .allowLocalEndpointReuse: + self.allowLocalEndpointReuse = true + case .allowRemoteHalfClosure: + self.allowRemoteHalfClosure = true + case .disableAutoRead: + self.disableAutoRead = true + } + } + + /// Caller is consuming the knowledge that `allowLocalEndpointReuse` was set or not. + /// The setting will nolonger be set after this call. + /// - Returns: If `allowLocalEndpointReuse` was set. + public mutating func consumeAllowLocalEndpointReuse() -> Types.ConvenienceOptionValue { + defer { + self.allowLocalEndpointReuse = false + } + return Types.ConvenienceOptionValue(flag: self.allowLocalEndpointReuse) + } + + /// Caller is consuming the knowledge that disableAutoRead was set or not. + /// The setting will nolonger be set after this call. + /// - Returns: If disableAutoRead was set. + public mutating func consumeDisableAutoRead() -> Types.ConvenienceOptionValue { + defer { + self.disableAutoRead = false + } + return Types.ConvenienceOptionValue(flag: self.disableAutoRead) + } + + /// Caller is consuming the knowledge that allowRemoteHalfClosure was set or not. + /// The setting will nolonger be set after this call. + /// - Returns: If allowRemoteHalfClosure was set. + public mutating func consumeAllowRemoteHalfClosure() -> Types.ConvenienceOptionValue { + defer { + self.allowRemoteHalfClosure = false + } + return Types.ConvenienceOptionValue(flag: self.allowRemoteHalfClosure) + } + + mutating func applyFallbackMapping(_ universalBootstrap: NIOClientTCPBootstrap) -> NIOClientTCPBootstrap { + var result = universalBootstrap + if self.consumeAllowLocalEndpointReuse().isSet { + result = result.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) + } + if self.consumeAllowRemoteHalfClosure().isSet { + result = result.channelOption(ChannelOptions.allowRemoteHalfClosure, value: true) + } + if self.consumeDisableAutoRead().isSet { + result = result.channelOption(ChannelOptions.autoRead, value: false) + } + return result + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DeadChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DeadChannel.swift new file mode 100644 index 00000000..060be94a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DeadChannel.swift @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A `DeadChannelCore` is a `ChannelCore` for a `DeadChannel`. A `DeadChannel` is used as a replacement `Channel` when +/// the original `Channel` is closed. Given that the original `Channel` is closed the `DeadChannelCore` should fail +/// all operations. +private final class DeadChannelCore: ChannelCore { + func localAddress0() throws -> SocketAddress { + throw ChannelError.ioOnClosedChannel + } + + func remoteAddress0() throws -> SocketAddress { + throw ChannelError.ioOnClosedChannel + } + + func register0(promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func registerAlreadyConfigured0(promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func bind0(to: SocketAddress, promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func connect0(to: SocketAddress, promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func write0(_ data: NIOAny, promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func flush0() { + } + + func read0() { + } + + func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + promise?.fail(ChannelError.alreadyClosed) + } + + func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + promise?.fail(ChannelError.ioOnClosedChannel) + } + + func channelRead0(_ data: NIOAny) { + // a `DeadChannel` should never be in any running `ChannelPipeline` and therefore the `TailChannelHandler` + // should never invoke this. + fatalError("\(#function) called on DeadChannelCore") + } + + func errorCaught0(error: Error) { + // a `DeadChannel` should never be in any running `ChannelPipeline` and therefore the `TailChannelHandler` + // should never invoke this. + fatalError("\(#function) called on DeadChannelCore") + } +} + +/// This represents a `Channel` which is already closed and therefore all the operations do fail. +/// A `ChannelPipeline` that is associated with a closed `Channel` must be careful to no longer use that original +/// channel as it only holds an unowned reference to the original `Channel`. `DeadChannel` serves as a replacement +/// that can be used when the original `Channel` might no longer be valid. +internal final class DeadChannel: Channel { + let eventLoop: EventLoop + let pipeline: ChannelPipeline + + public var closeFuture: EventLoopFuture { + return self.eventLoop.makeSucceededFuture(()) + } + + internal init(pipeline: ChannelPipeline) { + self.pipeline = pipeline + self.eventLoop = pipeline.eventLoop + } + + // This is `Channel` API so must be thread-safe. + var allocator: ByteBufferAllocator { + return ByteBufferAllocator() + } + + var localAddress: SocketAddress? { + return nil + } + + var remoteAddress: SocketAddress? { + return nil + } + + let parent: Channel? = nil + + func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + return self.pipeline.eventLoop.makeFailedFuture(ChannelError.ioOnClosedChannel) + } + + func getOption(_ option: Option) -> EventLoopFuture { + return eventLoop.makeFailedFuture(ChannelError.ioOnClosedChannel) + } + + let isWritable = false + let isActive = false + let _channelCore: ChannelCore = DeadChannelCore() +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DispatchQueue+WithFuture.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DispatchQueue+WithFuture.swift new file mode 100644 index 00000000..f85ea96d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/DispatchQueue+WithFuture.swift @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch + +extension DispatchQueue { + /// Schedules a work item for immediate execution and immediately returns with an `EventLoopFuture` providing the + /// result. For example: + /// + /// let futureResult = DispatchQueue.main.asyncWithFuture(eventLoop: myEventLoop) { () -> String in + /// callbackMayBlock() + /// } + /// try let value = futureResult.wait() + /// + /// - parameters: + /// - eventLoop: the `EventLoop` on which to processes the IO / task specified by `callbackMayBlock`. + /// - callbackMayBlock: The scheduled callback for the IO / task. + /// - returns a new `EventLoopFuture` with value returned by the `block` parameter. + @inlinable + public func asyncWithFuture( + eventLoop: EventLoop, + _ callbackMayBlock: @escaping () throws -> NewValue + ) -> EventLoopFuture { + let promise = eventLoop.makePromise(of: NewValue.self) + + self.async { + do { + let result = try callbackMayBlock() + promise.succeed(result) + } catch { + promise.fail(error) + } + } + return promise.futureResult + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop+Deprecated.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop+Deprecated.swift new file mode 100644 index 00000000..3bc9bfab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop+Deprecated.swift @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension EventLoop { + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func makeFailedFuture(_ error: Error, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + return self.makeFailedFuture(error) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func makeSucceededFuture(_ value: Success, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture { + return self.makeSucceededFuture(value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop.swift new file mode 100644 index 00000000..0f6e88cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoop.swift @@ -0,0 +1,917 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOConcurrencyHelpers +import Dispatch + +/// Returned once a task was scheduled on the `EventLoop` for later execution. +/// +/// A `Scheduled` allows the user to either `cancel()` the execution of the scheduled task (if possible) or obtain a reference to the `EventLoopFuture` that +/// will be notified once the execution is complete. +public struct Scheduled { + /* private but usableFromInline */ @usableFromInline let _promise: EventLoopPromise + /* private but usableFromInline */ @usableFromInline let _cancellationTask: (() -> Void) + + @inlinable + public init(promise: EventLoopPromise, cancellationTask: @escaping () -> Void) { + self._promise = promise + self._cancellationTask = cancellationTask + } + + /// Try to cancel the execution of the scheduled task. + /// + /// Whether this is successful depends on whether the execution of the task already begun. + /// This means that cancellation is not guaranteed. + @inlinable + public func cancel() { + self._promise.fail(EventLoopError.cancelled) + self._cancellationTask() + } + + /// Returns the `EventLoopFuture` which will be notified once the execution of the scheduled task completes. + @inlinable + public var futureResult: EventLoopFuture { + return self._promise.futureResult + } +} + +/// Returned once a task was scheduled to be repeatedly executed on the `EventLoop`. +/// +/// A `RepeatedTask` allows the user to `cancel()` the repeated scheduling of further tasks. +public final class RepeatedTask { + private let delay: TimeAmount + private let eventLoop: EventLoop + private let cancellationPromise: EventLoopPromise? + private var scheduled: Optional>> + private var task: Optional<(RepeatedTask) -> EventLoopFuture> + + internal init(interval: TimeAmount, eventLoop: EventLoop, cancellationPromise: EventLoopPromise? = nil, task: @escaping (RepeatedTask) -> EventLoopFuture) { + self.delay = interval + self.eventLoop = eventLoop + self.cancellationPromise = cancellationPromise + self.task = task + self.scheduled = nil + } + + internal func begin(in delay: TimeAmount) { + if self.eventLoop.inEventLoop { + self.begin0(in: delay) + } else { + self.eventLoop.execute { + self.begin0(in: delay) + } + } + } + + private func begin0(in delay: TimeAmount) { + self.eventLoop.assertInEventLoop() + guard let task = self.task else { + return + } + self.scheduled = self.eventLoop.scheduleTask(in: delay) { + task(self) + } + self.reschedule() + } + + /// Try to cancel the execution of the repeated task. + /// + /// Whether the execution of the task is immediately canceled depends on whether the execution of a task has already begun. + /// This means immediate cancellation is not guaranteed. + /// + /// The safest way to cancel is by using the passed reference of `RepeatedTask` inside the task closure. + /// + /// If the promise parameter is not `nil`, the passed promise is fulfilled when cancellation is complete. + /// Passing a promise does not prevent fulfillment of any promise provided on original task creation. + public func cancel(promise: EventLoopPromise? = nil) { + if self.eventLoop.inEventLoop { + self.cancel0(localCancellationPromise: promise) + } else { + self.eventLoop.execute { + self.cancel0(localCancellationPromise: promise) + } + } + } + + private func cancel0(localCancellationPromise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self.scheduled?.cancel() + self.scheduled = nil + self.task = nil + + // Possible states at this time are: + // 1) Task is scheduled but has not yet executed. + // 2) Task is currently executing and invoked `cancel()` on itself. + // 3) Task is currently executing and `cancel0()` has been reentrantly invoked. + // 4) NOT VALID: Task is currently executing and has NOT invoked `cancel()` (`EventLoop` guarantees serial execution) + // 5) NOT VALID: Task has completed execution in a success state (`reschedule()` ensures state #2). + // 6) Task has completed execution in a failure state. + // 7) Task has been fully cancelled at a previous time. + // + // It is desirable that the task has fully completed any execution before any cancellation promise is + // fulfilled. States 2 and 3 occur during execution, so the requirement is implemented by deferring + // fulfillment to the next `EventLoop` cycle. The delay is harmless to other states and distinguishing + // them from 2 and 3 is not practical (or necessarily possible), so is used unconditionally. Check the + // promises for nil so as not to otherwise invoke `execute()` unnecessarily. + if self.cancellationPromise != nil || localCancellationPromise != nil { + self.eventLoop.execute { + self.cancellationPromise?.succeed(()) + localCancellationPromise?.succeed(()) + } + } + } + + private func reschedule() { + self.eventLoop.assertInEventLoop() + guard let scheduled = self.scheduled else { + return + } + + scheduled.futureResult.whenSuccess { future in + future.hop(to: self.eventLoop).whenComplete { (_: Result) in + self.reschedule0() + } + } + + scheduled.futureResult.whenFailure { (_: Error) in + self.cancel0(localCancellationPromise: nil) + } + } + + private func reschedule0() { + self.eventLoop.assertInEventLoop() + guard self.task != nil else { + return + } + self.scheduled = self.eventLoop.scheduleTask(in: self.delay) { + // we need to repeat this as we might have been cancelled in the meantime + guard let task = self.task else { + return self.eventLoop.makeSucceededFuture(()) + } + return task(self) + } + self.reschedule() + } +} + +/// An iterator over the `EventLoop`s forming an `EventLoopGroup`. +/// +/// Usually returned by an `EventLoopGroup`'s `makeIterator()` method. +/// +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) +/// group.makeIterator().forEach { loop in +/// // Do something with each loop +/// } +/// +public struct EventLoopIterator: Sequence, IteratorProtocol { + public typealias Element = EventLoop + private var eventLoops: IndexingIterator<[EventLoop]> + + /// Create an `EventLoopIterator` from an array of `EventLoop`s. + public init(_ eventLoops: [EventLoop]) { + self.eventLoops = eventLoops.makeIterator() + } + + /// Advances to the next `EventLoop` and returns it, or `nil` if no next element exists. + /// + /// - returns: The next `EventLoop` if a next element exists; otherwise, `nil`. + public mutating func next() -> EventLoop? { + return self.eventLoops.next() + } +} + +/// An EventLoop processes IO / tasks in an endless loop for `Channel`s until it's closed. +/// +/// Usually multiple `Channel`s share the same `EventLoop` for processing IO / tasks and so share the same processing `NIOThread`. +/// For a better understanding of how such an `EventLoop` works internally the following pseudo code may be helpful: +/// +/// ``` +/// while eventLoop.isOpen { +/// /// Block until there is something to process for 1...n Channels +/// let readyChannels = blockUntilIoOrTasksAreReady() +/// /// Loop through all the Channels +/// for channel in readyChannels { +/// /// Process IO and / or tasks for the Channel. +/// /// This may include things like: +/// /// - accept new connection +/// /// - connect to a remote host +/// /// - read from socket +/// /// - write to socket +/// /// - tasks that were submitted via EventLoop methods +/// /// and others. +/// processIoAndTasks(channel) +/// } +/// } +/// ``` +/// +/// Because an `EventLoop` may be shared between multiple `Channel`s it's important to _NOT_ block while processing IO / tasks. This also includes long running computations which will have the same +/// effect as blocking in this case. +public protocol EventLoop: EventLoopGroup { + /// Returns `true` if the current `NIOThread` is the same as the `NIOThread` that is tied to this `EventLoop`. `false` otherwise. + var inEventLoop: Bool { get } + + /// Submit a given task to be executed by the `EventLoop` + func execute(_ task: @escaping () -> Void) + + /// Submit a given task to be executed by the `EventLoop`. Once the execution is complete the returned `EventLoopFuture` is notified. + /// + /// - parameters: + /// - task: The closure that will be submitted to the `EventLoop` for execution. + /// - returns: `EventLoopFuture` that is notified once the task was executed. + func submit(_ task: @escaping () throws -> T) -> EventLoopFuture + + /// Schedule a `task` that is executed by this `EventLoop` at the given time. + /// + /// - parameters: + /// - task: The synchronous task to run. As with everything that runs on the `EventLoop`, it must not block. + /// - returns: A `Scheduled` object which may be used to cancel the task if it has not yet run, or to wait + /// on the completion of the task. + /// + /// - note: You can only cancel a task before it has started executing. + @discardableResult + func scheduleTask(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled + + /// Schedule a `task` that is executed by this `EventLoop` after the given amount of time. + /// + /// - parameters: + /// - task: The synchronous task to run. As with everything that runs on the `EventLoop`, it must not block. + /// - returns: A `Scheduled` object which may be used to cancel the task if it has not yet run, or to wait + /// on the completion of the task. + /// + /// - note: You can only cancel a task before it has started executing. + /// - note: The `in` value is clamped to a maximum when running on a Darwin-kernel. + @discardableResult + func scheduleTask(in: TimeAmount, _ task: @escaping () throws -> T) -> Scheduled + + /// Asserts that the current thread is the one tied to this `EventLoop`. + /// Otherwise, the process will be abnormally terminated as per the semantics of `preconditionFailure(_:file:line:)`. + func preconditionInEventLoop(file: StaticString, line: UInt) + + /// Asserts that the current thread is _not_ the one tied to this `EventLoop`. + /// Otherwise, the process will be abnormally terminated as per the semantics of `preconditionFailure(_:file:line:)`. + func preconditionNotInEventLoop(file: StaticString, line: UInt) + + /// Return a succeeded `Void` future. + /// + /// Semantically, this function is equivalent to calling `makeSucceededFuture(())`. + /// Contrary to `makeSucceededFuture`, `makeSucceededVoidFuture` is a customization point for `EventLoop`s which + /// allows `EventLoop`s to cache a pre-succeeded `Void` future to prevent superfluous allocations. + func makeSucceededVoidFuture() -> EventLoopFuture + + /// Must crash if it is not safe to call `wait()` on an `EventLoopFuture`. + /// + /// This method is a debugging hook that can be used to override the behaviour of `EventLoopFuture.wait()` when called. + /// By default this simply becomes `preconditionNotInEventLoop`, but some `EventLoop`s are capable of more exhaustive + /// checking and can validate that the wait is not occurring on an entire `EventLoopGroup`, or even more broadly. + /// + /// This method should not be called by users directly, it should only be implemented by `EventLoop` implementers that + /// need to customise the behaviour. + func _preconditionSafeToWait(file: StaticString, line: UInt) + + /// Debug hook: track a promise creation and its location. + /// + /// This debug hook is called by EventLoopFutures and EventLoopPromises when they are created, and tracks the location + /// of their creation. It combines with `_promiseCompleted` to provide high-fidelity diagnostics for debugging leaked + /// promises. + /// + /// In release mode, this function will never be called. + /// + /// It is valid for an `EventLoop` not to implement any of the two `_promise` functions. If either of them are implemented, + /// however, both of them should be implemented. + func _promiseCreated(futureIdentifier: _NIOEventLoopFutureIdentifier, file: StaticString, line: UInt) + + /// Debug hook: complete a specific promise and return its creation location. + /// + /// This debug hook is called by EventLoopFutures and EventLoopPromises when they are deinited, and removes the data from + /// the promise tracking map and, if available, provides that data as its return value. It combines with `_promiseCreated` + /// to provide high-fidelity diagnostics for debugging leaked promises. + /// + /// In release mode, this function will never be called. + /// + /// It is valid for an `EventLoop` not to implement any of the two `_promise` functions. If either of them are implemented, + /// however, both of them should be implemented. + func _promiseCompleted(futureIdentifier: _NIOEventLoopFutureIdentifier) -> (file: StaticString, line: UInt)? +} + +extension EventLoop { + /// Default implementation of `makeSucceededVoidFuture`: Return a fresh future (which will allocate). + public func makeSucceededVoidFuture() -> EventLoopFuture { + return EventLoopFuture(eventLoop: self, value: ()) + } + + public func _preconditionSafeToWait(file: StaticString, line: UInt) { + self.preconditionNotInEventLoop(file: file, line: line) + } + + /// Default implementation of `_promiseCreated`: does nothing. + public func _promiseCreated(futureIdentifier: _NIOEventLoopFutureIdentifier, file: StaticString, line: UInt) { + return + } + + /// Default implementation of `_promiseCompleted`: does nothing. + public func _promiseCompleted(futureIdentifier: _NIOEventLoopFutureIdentifier) -> (file: StaticString, line: UInt)? { + return nil + } +} + +extension EventLoopGroup { + public var description: String { + return String(describing: self) + } +} + +/// Represents a time _interval_. +/// +/// - note: `TimeAmount` should not be used to represent a point in time. +public struct TimeAmount: Hashable { + @available(*, deprecated, message: "This typealias doesn't serve any purpose. Please use Int64 directly.") + public typealias Value = Int64 + + /// The nanoseconds representation of the `TimeAmount`. + public let nanoseconds: Int64 + + private init(_ nanoseconds: Int64) { + self.nanoseconds = nanoseconds + } + + /// Creates a new `TimeAmount` for the given amount of nanoseconds. + /// + /// - parameters: + /// - amount: the amount of nanoseconds this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func nanoseconds(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount) + } + + /// Creates a new `TimeAmount` for the given amount of microseconds. + /// + /// - parameters: + /// - amount: the amount of microseconds this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func microseconds(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount * 1000) + } + + /// Creates a new `TimeAmount` for the given amount of milliseconds. + /// + /// - parameters: + /// - amount: the amount of milliseconds this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func milliseconds(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount * (1000 * 1000)) + } + + /// Creates a new `TimeAmount` for the given amount of seconds. + /// + /// - parameters: + /// - amount: the amount of seconds this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func seconds(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount * (1000 * 1000 * 1000)) + } + + /// Creates a new `TimeAmount` for the given amount of minutes. + /// + /// - parameters: + /// - amount: the amount of minutes this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func minutes(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount * (1000 * 1000 * 1000 * 60)) + } + + /// Creates a new `TimeAmount` for the given amount of hours. + /// + /// - parameters: + /// - amount: the amount of hours this `TimeAmount` represents. + /// - returns: the `TimeAmount` for the given amount. + public static func hours(_ amount: Int64) -> TimeAmount { + return TimeAmount(amount * (1000 * 1000 * 1000 * 60 * 60)) + } +} + +extension TimeAmount: Comparable { + public static func < (lhs: TimeAmount, rhs: TimeAmount) -> Bool { + return lhs.nanoseconds < rhs.nanoseconds + } +} + +extension TimeAmount: AdditiveArithmetic { + /// The zero value for `TimeAmount`. + public static var zero: TimeAmount { + return TimeAmount.nanoseconds(0) + } + + public static func + (lhs: TimeAmount, rhs: TimeAmount) -> TimeAmount { + return TimeAmount(lhs.nanoseconds + rhs.nanoseconds) + } + + public static func +=(lhs: inout TimeAmount, rhs: TimeAmount) { + lhs = lhs + rhs + } + + public static func - (lhs: TimeAmount, rhs: TimeAmount) -> TimeAmount { + return TimeAmount(lhs.nanoseconds - rhs.nanoseconds) + } + + public static func -=(lhs: inout TimeAmount, rhs: TimeAmount) { + lhs = lhs - rhs + } + + public static func * (lhs: T, rhs: TimeAmount) -> TimeAmount { + return TimeAmount(Int64(lhs) * rhs.nanoseconds) + } + + public static func * (lhs: TimeAmount, rhs: T) -> TimeAmount { + return TimeAmount(lhs.nanoseconds * Int64(rhs)) + } +} + +/// Represents a point in time. +/// +/// Stores the time in nanoseconds as returned by `DispatchTime.now().uptimeNanoseconds` +/// +/// `NIODeadline` allow chaining multiple tasks with the same deadline without needing to +/// compute new timeouts for each step +/// +/// ``` +/// func doSomething(deadline: NIODeadline) -> EventLoopFuture { +/// return step1(deadline: deadline).flatMap { +/// step2(deadline: deadline) +/// } +/// } +/// doSomething(deadline: .now() + .seconds(5)) +/// ``` +/// +/// - note: `NIODeadline` should not be used to represent a time interval +public struct NIODeadline: Equatable, Hashable { + @available(*, deprecated, message: "This typealias doesn't serve any purpose, please use UInt64 directly.") + public typealias Value = UInt64 + + // This really should be an UInt63 but we model it as Int64 with >=0 assert + private var _uptimeNanoseconds: Int64 { + didSet { + assert(self._uptimeNanoseconds >= 0) + } + } + + /// The nanoseconds since boot representation of the `NIODeadline`. + public var uptimeNanoseconds: UInt64 { + return .init(self._uptimeNanoseconds) + } + + public static let distantPast = NIODeadline(0) + public static let distantFuture = NIODeadline(.init(Int64.max)) + + private init(_ nanoseconds: Int64) { + precondition(nanoseconds >= 0) + self._uptimeNanoseconds = nanoseconds + } + + public static func now() -> NIODeadline { + return NIODeadline.uptimeNanoseconds(DispatchTime.now().uptimeNanoseconds) + } + + public static func uptimeNanoseconds(_ nanoseconds: UInt64) -> NIODeadline { + return NIODeadline(Int64(min(UInt64(Int64.max), nanoseconds))) + } +} + +extension NIODeadline: Comparable { + public static func < (lhs: NIODeadline, rhs: NIODeadline) -> Bool { + return lhs.uptimeNanoseconds < rhs.uptimeNanoseconds + } + + public static func > (lhs: NIODeadline, rhs: NIODeadline) -> Bool { + return lhs.uptimeNanoseconds > rhs.uptimeNanoseconds + } +} + +extension NIODeadline: CustomStringConvertible { + public var description: String { + return self.uptimeNanoseconds.description + } +} + +extension NIODeadline { + public static func - (lhs: NIODeadline, rhs: NIODeadline) -> TimeAmount { + // This won't ever crash, NIODeadlines are guaranteed to be within 0 ..< 2^63-1 nanoseconds so the result can + // definitely be stored in a TimeAmount (which is an Int64). + return .nanoseconds(Int64(lhs.uptimeNanoseconds) - Int64(rhs.uptimeNanoseconds)) + } + + public static func + (lhs: NIODeadline, rhs: TimeAmount) -> NIODeadline { + let partial: Int64 + let overflow: Bool + (partial, overflow) = Int64(lhs.uptimeNanoseconds).addingReportingOverflow(rhs.nanoseconds) + if overflow { + assert(rhs.nanoseconds > 0) // this certainly must have overflowed towards +infinity + return NIODeadline.distantFuture + } + guard partial >= 0 else { + return NIODeadline.uptimeNanoseconds(0) + } + return NIODeadline(partial) + } + + public static func - (lhs: NIODeadline, rhs: TimeAmount) -> NIODeadline { + if rhs.nanoseconds < 0 { + // The addition won't crash because the worst that could happen is `UInt64(Int64.max) + UInt64(Int64.max)` + // which fits into an UInt64 (and will then be capped to Int64.max == distantFuture by `uptimeNanoseconds`). + return NIODeadline.uptimeNanoseconds(lhs.uptimeNanoseconds + rhs.nanoseconds.magnitude) + } else if rhs.nanoseconds > lhs.uptimeNanoseconds { + // Cap it at `0` because otherwise this would be negative. + return NIODeadline.init(0) + } else { + // This will be positive but still fix in an Int64. + let result = Int64(lhs.uptimeNanoseconds) - rhs.nanoseconds + assert(result >= 0) + return NIODeadline(result) + } + } +} + +extension EventLoop { + /// Submit `task` to be run on this `EventLoop`. + /// + /// The returned `EventLoopFuture` will be completed when `task` has finished running. It will be succeeded with + /// `task`'s return value or failed if the execution of `task` threw an error. + /// + /// - parameters: + /// - task: The synchronous task to run. As everything that runs on the `EventLoop`, it must not block. + /// - returns: An `EventLoopFuture` containing the result of `task`'s execution. + @inlinable + public func submit(_ task: @escaping () throws -> T) -> EventLoopFuture { + let promise: EventLoopPromise = makePromise(file: #file, line: #line) + + self.execute { + do { + promise.succeed(try task()) + } catch let err { + promise.fail(err) + } + } + + return promise.futureResult + } + + /// Submit `task` to be run on this `EventLoop`. + /// + /// The returned `EventLoopFuture` will be completed when `task` has finished running. It will be identical to + /// the `EventLoopFuture` returned by `task`. + /// + /// - parameters: + /// - task: The asynchronous task to run. As with everything that runs on the `EventLoop`, it must not block. + /// - returns: An `EventLoopFuture` identical to the `EventLoopFuture` returned from `task`. + @inlinable + public func flatSubmit(_ task: @escaping () -> EventLoopFuture) -> EventLoopFuture { + return self.submit(task).flatMap { $0 } + } + + /// Schedule a `task` that is executed by this `EventLoop` at the given time. + /// + /// - parameters: + /// - task: The asynchronous task to run. As with everything that runs on the `EventLoop`, it must not block. + /// - returns: A `Scheduled` object which may be used to cancel the task if it has not yet run, or to wait + /// on the full execution of the task, including its returned `EventLoopFuture`. + /// + /// - note: You can only cancel a task before it has started executing. + @discardableResult + @inlinable + public func flatScheduleTask(deadline: NIODeadline, + file: StaticString = #file, + line: UInt = #line, + _ task: @escaping () throws -> EventLoopFuture) -> Scheduled { + let promise: EventLoopPromise = self.makePromise(file:#file, line: line) + let scheduled = self.scheduleTask(deadline: deadline, task) + + scheduled.futureResult.flatMap { $0 }.cascade(to: promise) + return .init(promise: promise, cancellationTask: { scheduled.cancel() }) + } + + /// Schedule a `task` that is executed by this `EventLoop` after the given amount of time. + /// + /// - parameters: + /// - task: The asynchronous task to run. As everything that runs on the `EventLoop`, it must not block. + /// - returns: A `Scheduled` object which may be used to cancel the task if it has not yet run, or to wait + /// on the full execution of the task, including its returned `EventLoopFuture`. + /// + /// - note: You can only cancel a task before it has started executing. + @discardableResult + @inlinable + public func flatScheduleTask(in delay: TimeAmount, + file: StaticString = #file, + line: UInt = #line, + _ task: @escaping () throws -> EventLoopFuture) -> Scheduled { + let promise: EventLoopPromise = self.makePromise(file: file, line: line) + let scheduled = self.scheduleTask(in: delay, task) + + scheduled.futureResult.flatMap { $0 }.cascade(to: promise) + return .init(promise: promise, cancellationTask: { scheduled.cancel() }) + } + + /// Creates and returns a new `EventLoopPromise` that will be notified using this `EventLoop` as execution `NIOThread`. + @inlinable + public func makePromise(of type: T.Type = T.self, file: StaticString = #file, line: UInt = #line) -> EventLoopPromise { + return EventLoopPromise(eventLoop: self, file: file, line: line) + } + + /// Creates and returns a new `EventLoopFuture` that is already marked as failed. Notifications will be done using this `EventLoop` as execution `NIOThread`. + /// + /// - parameters: + /// - error: the `Error` that is used by the `EventLoopFuture`. + /// - returns: a failed `EventLoopFuture`. + @inlinable + public func makeFailedFuture(_ error: Error) -> EventLoopFuture { + return EventLoopFuture(eventLoop: self, error: error) + } + + /// Creates and returns a new `EventLoopFuture` that is already marked as success. Notifications will be done using this `EventLoop` as execution `NIOThread`. + /// + /// - parameters: + /// - result: the value that is used by the `EventLoopFuture`. + /// - returns: a succeeded `EventLoopFuture`. + @inlinable + public func makeSucceededFuture(_ value: Success) -> EventLoopFuture { + if Success.self == Void.self { + // The as! will always succeed because we previously checked that Success.self == Void.self. + return self.makeSucceededVoidFuture() as! EventLoopFuture + } else { + return EventLoopFuture(eventLoop: self, value: value) + } + } + + /// Creates and returns a new `EventLoopFuture` that is marked as succeeded or failed with the value held by `result`. + /// + /// - Parameters: + /// - result: The value that is used by the `EventLoopFuture` + /// - Returns: A completed `EventLoopFuture`. + @inlinable + public func makeCompletedFuture(_ result: Result) -> EventLoopFuture { + switch result { + case .success(let value): + return self.makeSucceededFuture(value) + case .failure(let error): + return self.makeFailedFuture(error) + } + } + + /// An `EventLoop` forms a singular `EventLoopGroup`, returning itself as the 'next' `EventLoop`. + /// + /// - returns: Itself, because an `EventLoop` forms a singular `EventLoopGroup`. + public func next() -> EventLoop { + return self + } + + /// An `EventLoop` forms a singular `EventLoopGroup`, returning itself as 'any' `EventLoop`. + /// + /// - returns: Itself, because an `EventLoop` forms a singular `EventLoopGroup`. + public func any() -> EventLoop { + return self + } + + /// Close this `EventLoop`. + public func close() throws { + // Do nothing + } + + /// Schedule a repeated task to be executed by the `EventLoop` with a fixed delay between the end and start of each + /// task. + /// + /// - parameters: + /// - initialDelay: The delay after which the first task is executed. + /// - delay: The delay between the end of one task and the start of the next. + /// - promise: If non-nil, a promise to fulfill when the task is cancelled and all execution is complete. + /// - task: The closure that will be executed. + /// - return: `RepeatedTask` + @discardableResult + public func scheduleRepeatedTask(initialDelay: TimeAmount, delay: TimeAmount, notifying promise: EventLoopPromise? = nil, _ task: @escaping (RepeatedTask) throws -> Void) -> RepeatedTask { + let futureTask: (RepeatedTask) -> EventLoopFuture = { repeatedTask in + do { + try task(repeatedTask) + return self.makeSucceededFuture(()) + } catch { + return self.makeFailedFuture(error) + } + } + return self.scheduleRepeatedAsyncTask(initialDelay: initialDelay, delay: delay, notifying: promise, futureTask) + } + + /// Schedule a repeated asynchronous task to be executed by the `EventLoop` with a fixed delay between the end and + /// start of each task. + /// + /// - note: The delay is measured from the completion of one run's returned future to the start of the execution of + /// the next run. For example: If you schedule a task once per second but your task takes two seconds to + /// complete, the time interval between two subsequent runs will actually be three seconds (2s run time plus + /// the 1s delay.) + /// + /// - parameters: + /// - initialDelay: The delay after which the first task is executed. + /// - delay: The delay between the end of one task and the start of the next. + /// - promise: If non-nil, a promise to fulfill when the task is cancelled and all execution is complete. + /// - task: The closure that will be executed. Task will keep repeating regardless of whether the future + /// gets fulfilled with success or error. + /// + /// - return: `RepeatedTask` + @discardableResult + public func scheduleRepeatedAsyncTask(initialDelay: TimeAmount, + delay: TimeAmount, + notifying promise: EventLoopPromise? = nil, + _ task: @escaping (RepeatedTask) -> EventLoopFuture) -> RepeatedTask { + let repeated = RepeatedTask(interval: delay, eventLoop: self, cancellationPromise: promise, task: task) + repeated.begin(in: initialDelay) + return repeated + } + + /// Returns an `EventLoopIterator` over this `EventLoop`. + /// + /// - returns: `EventLoopIterator` + public func makeIterator() -> EventLoopIterator { + return EventLoopIterator([self]) + } + + /// Asserts that the current thread is the one tied to this `EventLoop`. + /// Otherwise, if running in debug mode, the process will be abnormally terminated as per the semantics of + /// `preconditionFailure(_:file:line:)`. Never has any effect in release mode. + /// + /// - note: This is not a customization point so calls to this function can be fully optimized out in release mode. + @inlinable + public func assertInEventLoop(file: StaticString = #file, line: UInt = #line) { + debugOnly { + self.preconditionInEventLoop(file: file, line: line) + } + } + + /// Asserts that the current thread is _not_ the one tied to this `EventLoop`. + /// Otherwise, if running in debug mode, the process will be abnormally terminated as per the semantics of + /// `preconditionFailure(_:file:line:)`. Never has any effect in release mode. + /// + /// - note: This is not a customization point so calls to this function can be fully optimized out in release mode. + @inlinable + public func assertNotInEventLoop(file: StaticString = #file, line: UInt = #line) { + debugOnly { + self.preconditionNotInEventLoop(file: file, line: line) + } + } + + /// Checks the necessary condition of currently running on the called `EventLoop` for making forward progress. + @inlinable + public func preconditionInEventLoop(file: StaticString = #file, line: UInt = #line) { + precondition(self.inEventLoop, file: file, line: line) + } + + /// Checks the necessary condition of currently _not_ running on the called `EventLoop` for making forward progress. + @inlinable + public func preconditionNotInEventLoop(file: StaticString = #file, line: UInt = #line) { + precondition(!self.inEventLoop, file: file, line: line) + } +} + +/// Provides an endless stream of `EventLoop`s to use. +public protocol EventLoopGroup: AnyObject { + /// Returns the next `EventLoop` to use, this is useful for load balancing. + /// + /// The algorithm that is used to select the next `EventLoop` is specific to each `EventLoopGroup`. A common choice + /// is _round robin_. + /// + /// Please note that you should only be using `next()` if you want to load balance over all `EventLoop`s of the + /// `EventLoopGroup`. If the actual `EventLoop` does not matter much, `any()` should be preferred because it can + /// try to return you the _current_ `EventLoop` which usually is faster because the number of thread switches can + /// be reduced. + /// + /// The rule of thumb is: If you are trying to do _load balancing_, use `next()`. If you just want to create a new + /// future or kick off some operation, use `any()`. + + func next() -> EventLoop + + /// Returns any `EventLoop` from the `EventLoopGroup`, a common choice is the current `EventLoop`. + /// + /// - warning: You cannot rely on the returned `EventLoop` being the current one, not all `EventLoopGroup`s support + /// choosing the current one. Use this method only if you are truly happy with _any_ `EventLoop` of this + /// `EventLoopGroup` instance. + /// + /// - note: You will only receive the current `EventLoop` here iff the current `EventLoop` belongs to the + /// `EventLoopGroup` you call `any()` on. + /// + /// This method is useful having access to an `EventLoopGroup` without the knowledge of which `EventLoop` would be + /// the best one to select to create a new `EventLoopFuture`. This commonly happens in libraries where the user + /// cannot indicate what `EventLoop` they would like their futures on. + /// + /// Typically, it is faster to kick off a new operation on the _current_ `EventLoop` because that minimised thread + /// switches. Hence, if situations where you don't need precise knowledge of what `EventLoop` some code is running + /// on, use `any()` to indicate this. + /// + /// The rule of thumb is: If you are trying to do _load balancing_, use `next()`. If you just want to create a new + /// future or kick off some operation, use `any()`. + func any() -> EventLoop + + /// Shuts down the eventloop gracefully. This function is clearly an outlier in that it uses a completion + /// callback instead of an EventLoopFuture. The reason for that is that NIO's EventLoopFutures will call back on an event loop. + /// The virtue of this function is to shut the event loop down. To work around that we call back on a DispatchQueue + /// instead. + func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) + + /// Returns an `EventLoopIterator` over the `EventLoop`s in this `EventLoopGroup`. + /// + /// - returns: `EventLoopIterator` + func makeIterator() -> EventLoopIterator + + /// Must crash if it's not safe to call `syncShutdownGracefully` in the current context. + /// + /// This method is a debug hook that can be used to override the behaviour of `syncShutdownGracefully` + /// when called. By default it does nothing. + func _preconditionSafeToSyncShutdown(file: StaticString, line: UInt) +} + +extension EventLoopGroup { + /// The default implementation of `any()` just returns the `next()` EventLoop but it's highly recommended to + /// override this and return the current `EventLoop` if possible. + public func any() -> EventLoop { + return self.next() + } +} + +extension EventLoopGroup { + public func shutdownGracefully(_ callback: @escaping (Error?) -> Void) { + self.shutdownGracefully(queue: .global(), callback) + } + + public func syncShutdownGracefully() throws { + self._preconditionSafeToSyncShutdown(file: #file, line: #line) + + let errorStorageLock = Lock() + var errorStorage: Error? = nil + let continuation = DispatchWorkItem {} + self.shutdownGracefully { error in + if let error = error { + errorStorageLock.withLock { + errorStorage = error + } + } + continuation.perform() + } + continuation.wait() + try errorStorageLock.withLock { + if let error = errorStorage { + throw error + } + } + } + + public func _preconditionSafeToSyncShutdown(file: StaticString, line: UInt) { + return + } +} + +/// This type is intended to be used by libraries which use NIO, and offer their users either the option +/// to `.share` an existing event loop group or create (and manage) a new one (`.createNew`) and let it be +/// managed by given library and its lifecycle. +public enum NIOEventLoopGroupProvider { + /// Use an `EventLoopGroup` provided by the user. + /// The owner of this group is responsible for its lifecycle. + case shared(EventLoopGroup) + /// Create a new `EventLoopGroup` when necessary. + /// The library which accepts this provider takes ownership of the created event loop group, + /// and must ensure its proper shutdown when the library is being shut down. + case createNew +} + +/// Different `Error`s that are specific to `EventLoop` operations / implementations. +public enum EventLoopError: Error { + /// An operation was executed that is not supported by the `EventLoop` + case unsupportedOperation + + /// An scheduled task was cancelled. + case cancelled + + /// The `EventLoop` was shutdown already. + case shutdown + + /// Shutting down the `EventLoop` failed. + case shutdownFailed +} + +extension EventLoopError: CustomStringConvertible { + public var description: String { + switch self { + case .unsupportedOperation: + return "EventLoopError: the executed operation is not supported by the event loop" + case .cancelled: + return "EventLoopError: the scheduled task was cancelled" + case .shutdown: + return "EventLoopError: the event loop is shutdown" + case .shutdownFailed: + return "EventLoopError: failed to shutdown the event loop" + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+Deprecated.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+Deprecated.swift new file mode 100644 index 00000000..886a6148 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+Deprecated.swift @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension EventLoopFuture { + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func flatMap(file: StaticString = #file, line: UInt = #line, _ callback: @escaping (Value) -> EventLoopFuture) -> EventLoopFuture { + return self.flatMap(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func flatMapThrowing(file: StaticString = #file, + line: UInt = #line, + _ callback: @escaping (Value) throws -> NewValue) -> EventLoopFuture { + return self.flatMapThrowing(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func flatMapErrorThrowing(file: StaticString = #file, line: UInt = #line, _ callback: @escaping (Error) throws -> Value) -> EventLoopFuture { + return self.flatMapErrorThrowing(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func map(file: StaticString = #file, line: UInt = #line, _ callback: @escaping (Value) -> (NewValue)) -> EventLoopFuture { + return self.map(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func flatMapError(file: StaticString = #file, line: UInt = #line, _ callback: @escaping (Error) -> EventLoopFuture) -> EventLoopFuture { + return self.flatMapError(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func flatMapResult(file: StaticString = #file, + line: UInt = #line, + _ body: @escaping (Value) -> Result) -> EventLoopFuture { + return self.flatMapResult(body) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func recover(file: StaticString = #file, line: UInt = #line, _ callback: @escaping (Error) -> Value) -> EventLoopFuture { + return self.recover(callback) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func and(_ other: EventLoopFuture, + file: StaticString = #file, + line: UInt = #line) -> EventLoopFuture<(Value, OtherValue)> { + return self.and(other) + } + + @inlinable + @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") + public func and(value: OtherValue, + file: StaticString = #file, + line: UInt = #line) -> EventLoopFuture<(Value, OtherValue)> { + return self.and(value: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+WithEventLoop.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+WithEventLoop.swift new file mode 100644 index 00000000..29323a68 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture+WithEventLoop.swift @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension EventLoopFuture { + /// When the current `EventLoopFuture` is fulfilled, run the provided callback, + /// which will provide a new `EventLoopFuture` alongside the `EventLoop` associated with this future. + /// + /// This allows you to dynamically dispatch new asynchronous tasks as phases in a + /// longer series of processing steps. Note that you can use the results of the + /// current `EventLoopFuture` when determining how to dispatch the next operation. + /// + /// This works well when you have APIs that already know how to return `EventLoopFuture`s. + /// You can do something with the result of one and just return the next future: + /// + /// ``` + /// let d1 = networkRequest(args).future() + /// let d2 = d1.flatMapWithEventLoop { t, eventLoop -> EventLoopFuture in + /// eventLoop.makeSucceededFuture(t + 1) + /// } + /// d2.whenSuccess { u in + /// NSLog("Result of second request: \(u)") + /// } + /// ``` + /// + /// Note: In a sense, the `EventLoopFuture` is returned before it's created. + /// + /// - parameters: + /// - callback: Function that will receive the value of this `EventLoopFuture` and return + /// a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value. + @inlinable + public func flatMapWithEventLoop(_ callback: @escaping (Value, EventLoop) -> EventLoopFuture) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { [eventLoop = self.eventLoop] in + switch self._value! { + case .success(let t): + let futureU = callback(t, eventLoop) + if futureU.eventLoop.inEventLoop { + return futureU._addCallback { + next._setValue(value: futureU._value!) + } + } else { + futureU.cascade(to: next) + return CallbackList() + } + case .failure(let error): + return next._setValue(value: .failure(error)) + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is in an error state, run the provided callback, which + /// may recover from the error by returning an `EventLoopFuture`. The callback is intended to potentially + /// recover from the error by returning a new `EventLoopFuture` that will eventually contain the recovered + /// result. + /// + /// If the callback cannot recover it should return a failed `EventLoopFuture`. + /// + /// - parameters: + /// - callback: Function that will receive the error value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the recovered value. + @inlinable + public func flatMapErrorWithEventLoop(_ callback: @escaping (Error, EventLoop) -> EventLoopFuture) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { [eventLoop = self.eventLoop] in + switch self._value! { + case .success(let t): + return next._setValue(value: .success(t)) + case .failure(let e): + let t = callback(e, eventLoop) + if t.eventLoop.inEventLoop { + return t._addCallback { + next._setValue(value: t._value!) + } + } else { + t.cascade(to: next) + return CallbackList() + } + } + } + return next.futureResult + } + + /// Returns a new `EventLoopFuture` that fires only when this `EventLoopFuture` and + /// all the provided `futures` complete. It then provides the result of folding the value of this + /// `EventLoopFuture` with the values of all the provided `futures`. + /// + /// This function is suited when you have APIs that already know how to return `EventLoopFuture`s. + /// + /// The returned `EventLoopFuture` will fail as soon as the a failure is encountered in any of the + /// `futures` (or in this one). However, the failure will not occur until all preceding + /// `EventLoopFutures` have completed. At the point the failure is encountered, all subsequent + /// `EventLoopFuture` objects will no longer be waited for. This function therefore fails fast: once + /// a failure is encountered, it will immediately fail the overall EventLoopFuture. + /// + /// - parameters: + /// - futures: An array of `EventLoopFuture` to wait for. + /// - with: A function that will be used to fold the values of two `EventLoopFuture`s and return a new value wrapped in an `EventLoopFuture`. + /// - returns: A new `EventLoopFuture` with the folded value whose callbacks run on `self.eventLoop`. + @inlinable + public func foldWithEventLoop(_ futures: [EventLoopFuture], + with combiningFunction: @escaping (Value, OtherValue, EventLoop) -> EventLoopFuture) -> EventLoopFuture { + func fold0(eventLoop: EventLoop) -> EventLoopFuture { + let body = futures.reduce(self) { (f1: EventLoopFuture, f2: EventLoopFuture) -> EventLoopFuture in + let newFuture = f1.and(f2).flatMap { (args: (Value, OtherValue)) -> EventLoopFuture in + let (f1Value, f2Value) = args + self.eventLoop.assertInEventLoop() + return combiningFunction(f1Value, f2Value, eventLoop) + } + assert(newFuture.eventLoop === self.eventLoop) + return newFuture + } + return body + } + + if self.eventLoop.inEventLoop { + return fold0(eventLoop: self.eventLoop) + } else { + let promise = self.eventLoop.makePromise(of: Value.self) + self.eventLoop.execute { [eventLoop = self.eventLoop] in + fold0(eventLoop: eventLoop).cascade(to: promise) + } + return promise.futureResult + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture.swift new file mode 100644 index 00000000..f78fbf68 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/EventLoopFuture.swift @@ -0,0 +1,1582 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOConcurrencyHelpers +import Dispatch + +/// Internal list of callbacks. +/// +/// Most of these are closures that pull a value from one future, call a user callback, push the +/// result into another, then return a list of callbacks from the target future that are now ready to be invoked. +/// +/// In particular, note that _run() here continues to obtain and execute lists of callbacks until it completes. +/// This eliminates recursion when processing `flatMap()` chains. +@usableFromInline +internal struct CallbackList { + @usableFromInline + internal typealias Element = () -> CallbackList + @usableFromInline + internal var firstCallback: Optional + @usableFromInline + internal var furtherCallbacks: Optional<[Element]> + + @inlinable + internal init() { + self.firstCallback = nil + self.furtherCallbacks = nil + } + + @inlinable + internal mutating func append(_ callback: @escaping () -> CallbackList) { + if self.firstCallback == nil { + self.firstCallback = callback + } else { + if self.furtherCallbacks != nil { + self.furtherCallbacks!.append(callback) + } else { + self.furtherCallbacks = [callback] + } + } + } + + @inlinable + internal func _allCallbacks() -> CircularBuffer { + switch (self.firstCallback, self.furtherCallbacks) { + case (.none, _): + return [] + case (.some(let onlyCallback), .none): + return [onlyCallback] + default: + var array: CircularBuffer = [] + self.appendAllCallbacks(&array) + return array + } + } + + @inlinable + internal func appendAllCallbacks(_ array: inout CircularBuffer) { + switch (self.firstCallback, self.furtherCallbacks) { + case (.none, _): + return + case (.some(let onlyCallback), .none): + array.append(onlyCallback) + case (.some(let first), .some(let others)): + array.reserveCapacity(array.count + 1 + others.count) + array.append(first) + array.append(contentsOf: others) + } + } + + @inlinable + internal func _run() { + switch (self.firstCallback, self.furtherCallbacks) { + case (.none, _): + return + case (.some(let onlyCallback), .none): + var onlyCallback = onlyCallback + loop: while true { + let cbl = onlyCallback() + switch (cbl.firstCallback, cbl.furtherCallbacks) { + case (.none, _): + break loop + case (.some(let ocb), .none): + onlyCallback = ocb + continue loop + case (.some(_), .some(_)): + var pending = cbl._allCallbacks() + while let f = pending.popFirst() { + let next = f() + next.appendAllCallbacks(&pending) + } + break loop + } + } + default: + var pending = self._allCallbacks() + while let f = pending.popFirst() { + let next = f() + next.appendAllCallbacks(&pending) + } + } + } +} + +/// Internal error for operations that return results that were not replaced +@usableFromInline +internal struct OperationPlaceholderError: Error { + @usableFromInline + internal init() {} +} + +/// A promise to provide a result later. +/// +/// This is the provider API for `EventLoopFuture`. If you want to return an +/// unfulfilled `EventLoopFuture` -- presumably because you are interfacing to +/// some asynchronous service that will return a real result later, follow this +/// pattern: +/// +/// ``` +/// func someAsyncOperation(args) -> EventLoopFuture { +/// let promise = eventLoop.makePromise(of: ResultType.self) +/// someAsyncOperationWithACallback(args) { result -> Void in +/// // when finished... +/// promise.succeed(result) +/// // if error... +/// promise.fail(error) +/// } +/// return promise.futureResult +/// } +/// ``` +/// +/// Note that the future result is returned before the async process has provided a value. +/// +/// It's actually not very common to use this directly. Usually, you really want one +/// of the following: +/// +/// * If you have an `EventLoopFuture` and want to do something else after it completes, +/// use `.flatMap()` +/// * If you already have a value and need an `EventLoopFuture<>` object to plug into +/// some other API, create an already-resolved object with `eventLoop.makeSucceededFuture(result)` +/// or `eventLoop.newFailedFuture(error:)`. +/// +/// - note: `EventLoopPromise` has reference semantics. +public struct EventLoopPromise { + /// The `EventLoopFuture` which is used by the `EventLoopPromise`. You can use it to add callbacks which are notified once the + /// `EventLoopPromise` is completed. + public let futureResult: EventLoopFuture + + @inlinable + internal static func makeUnleakablePromise(eventLoop: EventLoop, line: UInt = #line) -> EventLoopPromise { + return EventLoopPromise(eventLoop: eventLoop, + file: "BUG in SwiftNIO (please report), unleakable promise leaked.", + line: line) + } + + /// General initializer + /// + /// - parameters: + /// - eventLoop: The event loop this promise is tied to. + /// - file: The file this promise was allocated in, for debugging purposes. + /// - line: The line this promise was allocated on, for debugging purposes. + @inlinable + internal init(eventLoop: EventLoop, file: StaticString, line: UInt) { + self.futureResult = EventLoopFuture(_eventLoop: eventLoop, file: file, line: line) + } + + /// Deliver a successful result to the associated `EventLoopFuture` object. + /// + /// - parameters: + /// - value: The successful result of the operation. + @inlinable + public func succeed(_ value: Value) { + self._resolve(value: .success(value)) + } + + /// Deliver an error to the associated `EventLoopFuture` object. + /// + /// - parameters: + /// - error: The error from the operation. + @inlinable + public func fail(_ error: Error) { + self._resolve(value: .failure(error)) + } + + /// Complete the promise with the passed in `EventLoopFuture`. + /// + /// This method is equivalent to invoking `future.cascade(to: promise)`, + /// but sometimes may read better than its cascade counterpart. + /// + /// - parameters: + /// - future: The future whose value will be used to succeed or fail this promise. + /// - seealso: `EventLoopFuture.cascade(to:)` + @inlinable + public func completeWith(_ future: EventLoopFuture) { + future.cascade(to: self) + } + + /// Complete the promise with the passed in `Result`. + /// + /// This method is equivalent to invoking: + /// ``` + /// switch result { + /// case .success(let value): + /// promise.succeed(value) + /// case .failure(let error): + /// promise.fail(error) + /// } + /// ``` + /// + /// - parameters: + /// - result: The result which will be used to succeed or fail this promise. + @inlinable + public func completeWith(_ result: Result) { + self._resolve(value: result) + } + + /// Fire the associated `EventLoopFuture` on the appropriate event loop. + /// + /// This method provides the primary difference between the `EventLoopPromise` and most + /// other `Promise` implementations: specifically, all callbacks fire on the `EventLoop` + /// that was used to create the promise. + /// + /// - parameters: + /// - value: The value to fire the future with. + @inlinable + internal func _resolve(value: Result) { + if self.futureResult.eventLoop.inEventLoop { + self._setValue(value: value)._run() + } else { + self.futureResult.eventLoop.execute { + self._setValue(value: value)._run() + } + } + } + + /// Set the future result and get the associated callbacks. + /// + /// - parameters: + /// - value: The result of the promise. + /// - returns: The callback list to run. + @inlinable + internal func _setValue(value: Result) -> CallbackList { + return self.futureResult._setValue(value: value) + } +} + + +/// Holder for a result that will be provided later. +/// +/// Functions that promise to do work asynchronously can return an `EventLoopFuture`. +/// The recipient of such an object can then observe it to be notified when the operation completes. +/// +/// The provider of a `EventLoopFuture` can create and return a placeholder object +/// before the actual result is available. For example: +/// +/// ``` +/// func getNetworkData(args) -> EventLoopFuture { +/// let promise = eventLoop.makePromise(of: NetworkResponse.self) +/// queue.async { +/// . . . do some work . . . +/// promise.succeed(response) +/// . . . if it fails, instead . . . +/// promise.fail(error) +/// } +/// return promise.futureResult +/// } +/// ``` +/// +/// Note that this function returns immediately; the promise object will be given a value +/// later on. This behaviour is common to Future/Promise implementations in many programming +/// languages. If you are unfamiliar with this kind of object, the following resources may be +/// helpful: +/// +/// - [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) +/// - [Scala](http://docs.scala-lang.org/overviews/core/futures.html) +/// - [Python](https://docs.google.com/document/d/10WOZgLQaYNpOrag-eTbUm-JUCCfdyfravZ4qSOQPg1M/edit) +/// +/// If you receive a `EventLoopFuture` from another function, you have a number of options: +/// The most common operation is to use `flatMap()` or `map()` to add a function that will be called +/// with the eventual result. Both methods returns a new `EventLoopFuture` immediately +/// that will receive the return value from your function, but they behave differently. If you have +/// a function that can return synchronously, the `map` function will transform the result of type +/// `Value` to a the new result of type `NewValue` and return an `EventLoopFuture`. +/// +/// ``` +/// let networkData = getNetworkData(args) +/// +/// // When network data is received, convert it. +/// let processedResult: EventLoopFuture = networkData.map { (n: NetworkResponse) -> Processed in +/// ... parse network data .... +/// return processedResult +/// } +/// ``` +/// +/// If however you need to do more asynchronous processing, you can call `flatMap()`. The return value of the +/// function passed to `flatMap` must be a new `EventLoopFuture` object: the return value of `flatMap()` is +/// a new `EventLoopFuture` that will contain the eventual result of both the original operation and +/// the subsequent one. +/// +/// ``` +/// // When converted network data is available, begin the database operation. +/// let databaseResult: EventLoopFuture = processedResult.flatMap { (p: Processed) -> EventLoopFuture in +/// return someDatabaseOperation(p) +/// } +/// ``` +/// +/// In essence, future chains created via `flatMap()` provide a form of data-driven asynchronous programming +/// that allows you to dynamically declare data dependencies for your various operations. +/// +/// `EventLoopFuture` chains created via `flatMap()` are sufficient for most purposes. All of the registered +/// functions will eventually run in order. If one of those functions throws an error, that error will +/// bypass the remaining functions. You can use `flatMapError()` to handle and optionally recover from +/// errors in the middle of a chain. +/// +/// At the end of an `EventLoopFuture` chain, you can use `whenSuccess()` or `whenFailure()` to add an +/// observer callback that will be invoked with the result or error at that point. (Note: If you ever +/// find yourself invoking `promise.succeed()` from inside a `whenSuccess()` callback, you probably should +/// use `flatMap()` or `cascade(to:)` instead.) +/// +/// `EventLoopFuture` objects are typically obtained by: +/// * Using `.flatMap()` on an existing future to create a new future for the next step in a series of operations. +/// * Initializing an `EventLoopFuture` that already has a value or an error +/// +/// ### Threading and Futures +/// +/// One of the major performance advantages of NIO over something like Node.js or Python’s asyncio is that NIO will +/// by default run multiple event loops at once, on different threads. As most network protocols do not require +/// blocking operation, at least in their low level implementations, this provides enormous speedups on machines +/// with many cores such as most modern servers. +/// +/// However, it can present a challenge at higher levels of abstraction when coordination between those threads +/// becomes necessary. This is usually the case whenever the events on one connection (that is, one `Channel`) depend +/// on events on another one. As these `Channel`s may be scheduled on different event loops (and so different threads) +/// care needs to be taken to ensure that communication between the two loops is done in a thread-safe manner that +/// avoids concurrent mutation of shared state from multiple loops at once. +/// +/// The main primitives NIO provides for this use are the `EventLoopPromise` and `EventLoopFuture`. As their names +/// suggest, these two objects are aware of event loops, and so can help manage the safety and correctness of your +/// programs. However, understanding the exact semantics of these objects is critical to ensuring the safety of your code. +/// +/// #### Callbacks +/// +/// The most important principle of the `EventLoopPromise` and `EventLoopFuture` is this: all callbacks registered on +/// an `EventLoopFuture` will execute on the thread corresponding to the event loop that created the `Future`, +/// *regardless* of what thread succeeds or fails the corresponding `EventLoopPromise`. +/// +/// This means that if *your code* created the `EventLoopPromise`, you can be extremely confident of what thread the +/// callback will execute on: after all, you held the event loop in hand when you created the `EventLoopPromise`. +/// However, if your code is handed an `EventLoopFuture` or `EventLoopPromise`, and you want to register callbacks +/// on those objects, you cannot be confident that those callbacks will execute on the same `EventLoop` that your +/// code does. +/// +/// This presents a problem: how do you ensure thread-safety when registering callbacks on an arbitrary +/// `EventLoopFuture`? The short answer is that when you are holding an `EventLoopFuture`, you can always obtain a +/// new `EventLoopFuture` whose callbacks will execute on your event loop. You do this by calling +/// `EventLoopFuture.hop(to:)`. This function returns a new `EventLoopFuture` whose callbacks are guaranteed +/// to fire on the provided event loop. As an added bonus, `hopTo` will check whether the provided `EventLoopFuture` +/// was already scheduled to dispatch on the event loop in question, and avoid doing any work if that was the case. +/// +/// This means that for any `EventLoopFuture` that your code did not create itself (via +/// `EventLoopPromise.futureResult`), use of `hopTo` is **strongly encouraged** to help guarantee thread-safety. It +/// should only be elided when thread-safety is provably not needed. +/// +/// The "thread affinity" of `EventLoopFuture`s is critical to writing safe, performant concurrent code without +/// boilerplate. It allows you to avoid needing to write or use locks in your own code, instead using the natural +/// synchronization of the `EventLoop` to manage your thread-safety. In general, if any of your `ChannelHandler`s +/// or `EventLoopFuture` callbacks need to invoke a lock (either directly or in the form of `DispatchQueue`) this +/// should be considered a code smell worth investigating: the `EventLoop`-based synchronization guarantees of +/// `EventLoopFuture` should be sufficient to guarantee thread-safety. +public final class EventLoopFuture { + // TODO: Provide a tracing facility. It would be nice to be able to set '.debugTrace = true' on any EventLoopFuture or EventLoopPromise and have every subsequent chained EventLoopFuture report the success result or failure error. That would simplify some debugging scenarios. + @usableFromInline + internal var _value: Optional> + + /// The `EventLoop` which is tied to the `EventLoopFuture` and is used to notify all registered callbacks. + public let eventLoop: EventLoop + + /// Callbacks that should be run when this `EventLoopFuture` gets a value. + /// These callbacks may give values to other `EventLoopFuture`s; if that happens, + /// they return any callbacks from those `EventLoopFuture`s so that we can run + /// the entire chain from the top without recursing. + @usableFromInline + internal var _callbacks: CallbackList + + @inlinable + internal init(_eventLoop eventLoop: EventLoop, file: StaticString, line: UInt) { + self.eventLoop = eventLoop + self._value = nil + self._callbacks = .init() + + debugOnly { + eventLoop._promiseCreated(futureIdentifier: _NIOEventLoopFutureIdentifier(self), file: file, line: line) + } + } + + /// A EventLoopFuture that has already succeeded + @inlinable + internal init(eventLoop: EventLoop, value: Value) { + self.eventLoop = eventLoop + self._value = .success(value) + self._callbacks = .init() + } + + /// A EventLoopFuture that has already failed + @inlinable + internal init(eventLoop: EventLoop, error: Error) { + self.eventLoop = eventLoop + self._value = .failure(error) + self._callbacks = .init() + } + + deinit { + debugOnly { + if let creation = eventLoop._promiseCompleted(futureIdentifier: _NIOEventLoopFutureIdentifier(self)) { + if self._value == nil { + fatalError("leaking promise created at \(creation)", file: creation.file, line: creation.line) + } + } else { + precondition(self._value != nil, "leaking an unfulfilled Promise") + } + } + } +} + +extension EventLoopFuture: Equatable { + public static func ==(lhs: EventLoopFuture, rhs: EventLoopFuture) -> Bool { + return lhs === rhs + } +} + +// MARK: flatMap and map + +// 'flatMap' and 'map' implementations. This is really the key of the entire system. +extension EventLoopFuture { + /// When the current `EventLoopFuture` is fulfilled, run the provided callback, + /// which will provide a new `EventLoopFuture`. + /// + /// This allows you to dynamically dispatch new asynchronous tasks as phases in a + /// longer series of processing steps. Note that you can use the results of the + /// current `EventLoopFuture` when determining how to dispatch the next operation. + /// + /// This works well when you have APIs that already know how to return `EventLoopFuture`s. + /// You can do something with the result of one and just return the next future: + /// + /// ``` + /// let d1 = networkRequest(args).future() + /// let d2 = d1.flatMap { t -> EventLoopFuture in + /// . . . something with t . . . + /// return netWorkRequest(args) + /// } + /// d2.whenSuccess { u in + /// NSLog("Result of second request: \(u)") + /// } + /// ``` + /// + /// Note: In a sense, the `EventLoopFuture` is returned before it's created. + /// + /// - parameters: + /// - callback: Function that will receive the value of this `EventLoopFuture` and return + /// a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value. + @inlinable + public func flatMap(_ callback: @escaping (Value) -> EventLoopFuture) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let t): + let futureU = callback(t) + if futureU.eventLoop.inEventLoop { + return futureU._addCallback { + next._setValue(value: futureU._value!) + } + } else { + futureU.cascade(to: next) + return CallbackList() + } + case .failure(let error): + return next._setValue(value: .failure(error)) + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is fulfilled, run the provided callback, which + /// performs a synchronous computation and returns a new value of type `NewValue`. The provided + /// callback may optionally `throw`. + /// + /// Operations performed in `flatMapThrowing` should not block, or they will block the entire + /// event loop. `flatMapThrowing` is intended for use when you have a data-driven function that + /// performs a simple data transformation that can potentially error. + /// + /// If your callback function throws, the returned `EventLoopFuture` will error. + /// + /// - parameters: + /// - callback: Function that will receive the value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value. + @inlinable + public func flatMapThrowing(_ callback: @escaping (Value) throws -> NewValue) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let t): + do { + let r = try callback(t) + return next._setValue(value: .success(r)) + } catch { + return next._setValue(value: .failure(error)) + } + case .failure(let e): + return next._setValue(value: .failure(e)) + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is in an error state, run the provided callback, which + /// may recover from the error and returns a new value of type `Value`. The provided callback may optionally `throw`, + /// in which case the `EventLoopFuture` will be in a failed state with the new thrown error. + /// + /// Operations performed in `flatMapErrorThrowing` should not block, or they will block the entire + /// event loop. `flatMapErrorThrowing` is intended for use when you have the ability to synchronously + /// recover from errors. + /// + /// If your callback function throws, the returned `EventLoopFuture` will error. + /// + /// - parameters: + /// - callback: Function that will receive the error value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value or a rethrown error. + @inlinable + public func flatMapErrorThrowing(_ callback: @escaping (Error) throws -> Value) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let t): + return next._setValue(value: .success(t)) + case .failure(let e): + do { + let r = try callback(e) + return next._setValue(value: .success(r)) + } catch { + return next._setValue(value: .failure(error)) + } + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is fulfilled, run the provided callback, which + /// performs a synchronous computation and returns a new value of type `NewValue`. + /// + /// Operations performed in `map` should not block, or they will block the entire event + /// loop. `map` is intended for use when you have a data-driven function that performs + /// a simple data transformation that cannot error. + /// + /// If you have a data-driven function that can throw, you should use `flatMapThrowing` + /// instead. + /// + /// ``` + /// let future1 = eventually() + /// let future2 = future1.map { T -> U in + /// ... stuff ... + /// return u + /// } + /// let future3 = future2.map { U -> V in + /// ... stuff ... + /// return v + /// } + /// ``` + /// + /// - parameters: + /// - callback: Function that will receive the value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value. + @inlinable + public func map(_ callback: @escaping (Value) -> (NewValue)) -> EventLoopFuture { + if NewValue.self == Value.self && NewValue.self == Void.self { + self.whenSuccess(callback as! (Value) -> Void) + return self as! EventLoopFuture + } else { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + return next._setValue(value: self._value!.map(callback)) + } + return next.futureResult + } + } + + /// When the current `EventLoopFuture` is in an error state, run the provided callback, which + /// may recover from the error by returning an `EventLoopFuture`. The callback is intended to potentially + /// recover from the error by returning a new `EventLoopFuture` that will eventually contain the recovered + /// result. + /// + /// If the callback cannot recover it should return a failed `EventLoopFuture`. + /// + /// - parameters: + /// - callback: Function that will receive the error value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the recovered value. + @inlinable + public func flatMapError(_ callback: @escaping (Error) -> EventLoopFuture) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let t): + return next._setValue(value: .success(t)) + case .failure(let e): + let t = callback(e) + if t.eventLoop.inEventLoop { + return t._addCallback { + next._setValue(value: t._value!) + } + } else { + t.cascade(to: next) + return CallbackList() + } + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is fulfilled, run the provided callback, which + /// performs a synchronous computation and returns either a new value (of type `NewValue`) or + /// an error depending on the `Result` returned by the closure. + /// + /// Operations performed in `flatMapResult` should not block, or they will block the entire + /// event loop. `flatMapResult` is intended for use when you have a data-driven function that + /// performs a simple data transformation that can potentially error. + /// + /// + /// - parameters: + /// - body: Function that will receive the value of this `EventLoopFuture` and return + /// a new value or error lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the eventual value. + @inlinable + public func flatMapResult(_ body: @escaping (Value) -> Result) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let value): + switch body(value) { + case .success(let newValue): + return next._setValue(value: .success(newValue)) + case .failure(let error): + return next._setValue(value: .failure(error)) + } + case .failure(let e): + return next._setValue(value: .failure(e)) + } + } + return next.futureResult + } + + /// When the current `EventLoopFuture` is in an error state, run the provided callback, which + /// can recover from the error and return a new value of type `Value`. The provided callback may not `throw`, + /// so this function should be used when the error is always recoverable. + /// + /// Operations performed in `recover` should not block, or they will block the entire + /// event loop. `recover` is intended for use when you have the ability to synchronously + /// recover from errors. + /// + /// - parameters: + /// - callback: Function that will receive the error value of this `EventLoopFuture` and return + /// a new value lifted into a new `EventLoopFuture`. + /// - returns: A future that will receive the recovered value. + @inlinable + public func recover(_ callback: @escaping (Error) -> Value) -> EventLoopFuture { + let next = EventLoopPromise.makeUnleakablePromise(eventLoop: self.eventLoop) + self._whenComplete { + switch self._value! { + case .success(let t): + return next._setValue(value: .success(t)) + case .failure(let e): + return next._setValue(value: .success(callback(e))) + } + } + return next.futureResult + } + + + /// Add a callback. If there's already a value, invoke it and return the resulting list of new callback functions. + @inlinable + internal func _addCallback(_ callback: @escaping () -> CallbackList) -> CallbackList { + self.eventLoop.assertInEventLoop() + if self._value == nil { + self._callbacks.append(callback) + return CallbackList() + } + return callback() + } + + /// Add a callback. If there's already a value, run as much of the chain as we can. + @inlinable + internal func _whenComplete(_ callback: @escaping () -> CallbackList) { + if self.eventLoop.inEventLoop { + self._addCallback(callback)._run() + } else { + self.eventLoop.execute { + self._addCallback(callback)._run() + } + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has a success result. + /// + /// An observer callback cannot return a value, meaning that this function cannot be chained + /// from. If you are attempting to create a computation pipeline, consider `map` or `flatMap`. + /// If you find yourself passing the results from this `EventLoopFuture` to a new `EventLoopPromise` + /// in the body of this function, consider using `cascade` instead. + /// + /// - parameters: + /// - callback: The callback that is called with the successful result of the `EventLoopFuture`. + @inlinable + public func whenSuccess(_ callback: @escaping (Value) -> Void) { + self._whenComplete { + if case .success(let t) = self._value! { + callback(t) + } + return CallbackList() + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has a failure result. + /// + /// An observer callback cannot return a value, meaning that this function cannot be chained + /// from. If you are attempting to create a computation pipeline, consider `recover` or `flatMapError`. + /// If you find yourself passing the results from this `EventLoopFuture` to a new `EventLoopPromise` + /// in the body of this function, consider using `cascade` instead. + /// + /// - parameters: + /// - callback: The callback that is called with the failed result of the `EventLoopFuture`. + @inlinable + public func whenFailure(_ callback: @escaping (Error) -> Void) { + self._whenComplete { + if case .failure(let e) = self._value! { + callback(e) + } + return CallbackList() + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has any result. + /// + /// - parameters: + /// - callback: The callback that is called when the `EventLoopFuture` is fulfilled. + @inlinable + public func whenComplete(_ callback: @escaping (Result) -> Void) { + self._whenComplete { + callback(self._value!) + return CallbackList() + } + } + + + /// Internal: Set the value and return a list of callbacks that should be invoked as a result. + @inlinable + internal func _setValue(value: Result) -> CallbackList { + self.eventLoop.assertInEventLoop() + if self._value == nil { + self._value = value + let callbacks = self._callbacks + self._callbacks = CallbackList() + return callbacks + } + return CallbackList() + } +} + +// MARK: and + +extension EventLoopFuture { + /// Return a new `EventLoopFuture` that succeeds when this "and" another + /// provided `EventLoopFuture` both succeed. It then provides the pair + /// of results. If either one fails, the combined `EventLoopFuture` will fail with + /// the first error encountered. + @inlinable + public func and(_ other: EventLoopFuture) -> EventLoopFuture<(Value, OtherValue)> { + let promise = EventLoopPromise<(Value, OtherValue)>.makeUnleakablePromise(eventLoop: self.eventLoop) + var tvalue: Value? + var uvalue: OtherValue? + + assert(self.eventLoop === promise.futureResult.eventLoop) + self._whenComplete { () -> CallbackList in + switch self._value! { + case .failure(let error): + return promise._setValue(value: .failure(error)) + case .success(let t): + if let u = uvalue { + return promise._setValue(value: .success((t, u))) + } else { + tvalue = t + } + } + return CallbackList() + } + + let hopOver = other.hop(to: self.eventLoop) + hopOver._whenComplete { () -> CallbackList in + self.eventLoop.assertInEventLoop() + switch other._value! { + case .failure(let error): + return promise._setValue(value: .failure(error)) + case .success(let u): + if let t = tvalue { + return promise._setValue(value: .success((t, u))) + } else { + uvalue = u + } + } + return CallbackList() + } + + return promise.futureResult + } + + /// Return a new EventLoopFuture that contains this "and" another value. + /// This is just syntactic sugar for `future.and(loop.makeSucceedFuture(value))`. + @inlinable + public func and(value: OtherValue) -> EventLoopFuture<(Value, OtherValue)> { + return self.and(EventLoopFuture(eventLoop: self.eventLoop, value: value)) + } +} + +// MARK: cascade + +extension EventLoopFuture { + /// Fulfills the given `EventLoopPromise` with the results from this `EventLoopFuture`. + /// + /// This is useful when allowing users to provide promises for you to fulfill, but + /// when you are calling functions that return their own promises. They allow you to + /// tidy up your computational pipelines. + /// + /// For example: + /// ``` + /// doWork().flatMap { + /// doMoreWork($0) + /// }.flatMap { + /// doYetMoreWork($0) + /// }.flatMapError { + /// maybeRecoverFromError($0) + /// }.map { + /// transformData($0) + /// }.cascade(to: userPromise) + /// ``` + /// + /// - Parameter to: The `EventLoopPromise` to fulfill with the results of this future. + /// - SeeAlso: `EventLoopPromise.completeWith(_:)` + @inlinable + public func cascade(to promise: EventLoopPromise?) { + guard let promise = promise else { return } + self.whenComplete { result in + switch result { + case let .success(value): promise.succeed(value) + case let .failure(error): promise.fail(error) + } + } + } + + /// Fulfills the given `EventLoopPromise` only when this `EventLoopFuture` succeeds. + /// + /// If you are doing work that fulfills a type that doesn't match the expected `EventLoopPromise` value, add an + /// intermediate `map`. + /// + /// For example: + /// ``` + /// let boolPromise = eventLoop.makePromise(of: Bool.self) + /// doWorkReturningInt().map({ $0 >= 0 }).cascade(to: boolPromise) + /// ``` + /// + /// - Parameter to: The `EventLoopPromise` to fulfill when a successful result is available. + @inlinable + public func cascadeSuccess(to promise: EventLoopPromise?) { + guard let promise = promise else { return } + self.whenSuccess { promise.succeed($0) } + } + + /// Fails the given `EventLoopPromise` with the error from this `EventLoopFuture` if encountered. + /// + /// This is an alternative variant of `cascade` that allows you to potentially return early failures in + /// error cases, while passing the user `EventLoopPromise` onwards. + /// + /// - Parameter to: The `EventLoopPromise` that should fail with the error of this `EventLoopFuture`. + @inlinable + public func cascadeFailure(to promise: EventLoopPromise?) { + guard let promise = promise else { return } + self.whenFailure { promise.fail($0) } + } +} + +// MARK: wait + +extension EventLoopFuture { + /// Wait for the resolution of this `EventLoopFuture` by blocking the current thread until it + /// resolves. + /// + /// If the `EventLoopFuture` resolves with a value, that value is returned from `wait()`. If + /// the `EventLoopFuture` resolves with an error, that error will be thrown instead. + /// `wait()` will block whatever thread it is called on, so it must not be called on event loop + /// threads: it is primarily useful for testing, or for building interfaces between blocking + /// and non-blocking code. + /// + /// - returns: The value of the `EventLoopFuture` when it completes. + /// - throws: The error value of the `EventLoopFuture` if it errors. + @inlinable + public func wait(file: StaticString = #file, line: UInt = #line) throws -> Value { + self.eventLoop._preconditionSafeToWait(file: file, line: line) + + var v: Result? = nil + let lock = ConditionLock(value: 0) + self._whenComplete { () -> CallbackList in + lock.lock() + v = self._value + lock.unlock(withValue: 1) + return CallbackList() + } + lock.lock(whenValue: 1) + lock.unlock() + + switch(v!) { + case .success(let result): + return result + case .failure(let error): + throw error + } + } +} + +// MARK: fold + +extension EventLoopFuture { + /// Returns a new `EventLoopFuture` that fires only when this `EventLoopFuture` and + /// all the provided `futures` complete. It then provides the result of folding the value of this + /// `EventLoopFuture` with the values of all the provided `futures`. + /// + /// This function is suited when you have APIs that already know how to return `EventLoopFuture`s. + /// + /// The returned `EventLoopFuture` will fail as soon as the a failure is encountered in any of the + /// `futures` (or in this one). However, the failure will not occur until all preceding + /// `EventLoopFutures` have completed. At the point the failure is encountered, all subsequent + /// `EventLoopFuture` objects will no longer be waited for. This function therefore fails fast: once + /// a failure is encountered, it will immediately fail the overall EventLoopFuture. + /// + /// - parameters: + /// - futures: An array of `EventLoopFuture` to wait for. + /// - with: A function that will be used to fold the values of two `EventLoopFuture`s and return a new value wrapped in an `EventLoopFuture`. + /// - returns: A new `EventLoopFuture` with the folded value whose callbacks run on `self.eventLoop`. + @inlinable + public func fold(_ futures: [EventLoopFuture], + with combiningFunction: @escaping (Value, OtherValue) -> EventLoopFuture) -> EventLoopFuture { + func fold0() -> EventLoopFuture { + let body = futures.reduce(self) { (f1: EventLoopFuture, f2: EventLoopFuture) -> EventLoopFuture in + let newFuture = f1.and(f2).flatMap { (args: (Value, OtherValue)) -> EventLoopFuture in + let (f1Value, f2Value) = args + self.eventLoop.assertInEventLoop() + return combiningFunction(f1Value, f2Value) + } + assert(newFuture.eventLoop === self.eventLoop) + return newFuture + } + return body + } + + if self.eventLoop.inEventLoop { + return fold0() + } else { + let promise = self.eventLoop.makePromise(of: Value.self) + self.eventLoop.execute { + fold0().cascade(to: promise) + } + return promise.futureResult + } + } +} + +// MARK: reduce + +extension EventLoopFuture { + /// Returns a new `EventLoopFuture` that fires only when all the provided futures complete. + /// The new `EventLoopFuture` contains the result of reducing the `initialResult` with the + /// values of the `[EventLoopFuture]`. + /// + /// This function makes copies of the result for each EventLoopFuture, for a version which avoids + /// making copies, check out `reduce(into:)`. + /// + /// The returned `EventLoopFuture` will fail as soon as a failure is encountered in any of the + /// `futures`. However, the failure will not occur until all preceding + /// `EventLoopFutures` have completed. At the point the failure is encountered, all subsequent + /// `EventLoopFuture` objects will no longer be waited for. This function therefore fails fast: once + /// a failure is encountered, it will immediately fail the overall `EventLoopFuture`. + /// + /// - parameters: + /// - initialResult: An initial result to begin the reduction. + /// - futures: An array of `EventLoopFuture` to wait for. + /// - eventLoop: The `EventLoop` on which the new `EventLoopFuture` callbacks will fire. + /// - nextPartialResult: The bifunction used to produce partial results. + /// - returns: A new `EventLoopFuture` with the reduced value. + public static func reduce(_ initialResult: Value, + _ futures: [EventLoopFuture], + on eventLoop: EventLoop, + _ nextPartialResult: @escaping (Value, InputValue) -> Value) -> EventLoopFuture { + let f0 = eventLoop.makeSucceededFuture(initialResult) + + let body = f0.fold(futures) { (t: Value, u: InputValue) -> EventLoopFuture in + eventLoop.makeSucceededFuture(nextPartialResult(t, u)) + } + + return body + } + + /// Returns a new `EventLoopFuture` that fires only when all the provided futures complete. + /// The new `EventLoopFuture` contains the result of combining the `initialResult` with the + /// values of the `[EventLoopFuture]`. This function is analogous to the standard library's + /// `reduce(into:)`, which does not make copies of the result type for each `EventLoopFuture`. + /// + /// The returned `EventLoopFuture` will fail as soon as a failure is encountered in any of the + /// `futures`. However, the failure will not occur until all preceding + /// `EventLoopFutures` have completed. At the point the failure is encountered, all subsequent + /// `EventLoopFuture` objects will no longer be waited for. This function therefore fails fast: once + /// a failure is encountered, it will immediately fail the overall `EventLoopFuture`. + /// + /// - parameters: + /// - initialResult: An initial result to begin the reduction. + /// - futures: An array of `EventLoopFuture` to wait for. + /// - eventLoop: The `EventLoop` on which the new `EventLoopFuture` callbacks will fire. + /// - updateAccumulatingResult: The bifunction used to combine partialResults with new elements. + /// - returns: A new `EventLoopFuture` with the combined value. + public static func reduce(into initialResult: Value, + _ futures: [EventLoopFuture], + on eventLoop: EventLoop, + _ updateAccumulatingResult: @escaping (inout Value, InputValue) -> Void) -> EventLoopFuture { + let p0 = eventLoop.makePromise(of: Value.self) + var value: Value = initialResult + + let f0 = eventLoop.makeSucceededFuture(()) + let future = f0.fold(futures) { (_: (), newValue: InputValue) -> EventLoopFuture in + eventLoop.assertInEventLoop() + updateAccumulatingResult(&value, newValue) + return eventLoop.makeSucceededFuture(()) + } + + future.whenSuccess { + eventLoop.assertInEventLoop() + p0.succeed(value) + } + future.whenFailure { (error) in + eventLoop.assertInEventLoop() + p0.fail(error) + } + return p0.futureResult + } +} + +// MARK: "fail fast" reduce + +extension EventLoopFuture { + /// Returns a new `EventLoopFuture` that succeeds only if all of the provided futures succeed. + /// + /// This method acts as a successful completion notifier - values fulfilled by each future are discarded. + /// + /// The returned `EventLoopFuture` fails as soon as any of the provided futures fail. + /// + /// If it is desired to always succeed, regardless of failures, use `andAllComplete` instead. + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFutures`s to wait for. + /// - on: The `EventLoop` on which the new `EventLoopFuture` callbacks will execute on. + /// - Returns: A new `EventLoopFuture` that waits for the other futures to succeed. + @inlinable + public static func andAllSucceed(_ futures: [EventLoopFuture], on eventLoop: EventLoop) -> EventLoopFuture { + let promise = eventLoop.makePromise(of: Void.self) + EventLoopFuture.andAllSucceed(futures, promise: promise) + return promise.futureResult + } + + /// Succeeds the promise if all of the provided futures succeed. If any of the provided + /// futures fail then the `promise` will be failed -- even if some futures are yet to complete. + /// + /// If the results of all futures should be collected use `andAllComplete` instead. + /// + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFutures`s to wait for. + /// - promise: The `EventLoopPromise` to complete with the result of this call. + @inlinable + public static func andAllSucceed(_ futures: [EventLoopFuture], promise: EventLoopPromise) { + let eventLoop = promise.futureResult.eventLoop + + if eventLoop.inEventLoop { + self._reduceSuccesses0(promise, futures, eventLoop, onValue: { _, _ in }) + } else { + eventLoop.execute { + self._reduceSuccesses0(promise, futures, eventLoop, onValue: { _, _ in }) + } + } + } + + /// Returns a new `EventLoopFuture` that succeeds only if all of the provided futures succeed. + /// The new `EventLoopFuture` will contain all of the values fulfilled by the futures. + /// + /// The returned `EventLoopFuture` will fail as soon as any of the futures fails. + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFuture`s to wait on for fulfilled values. + /// - on: The `EventLoop` on which the new `EventLoopFuture` callbacks will fire. + /// - Returns: A new `EventLoopFuture` with all of the values fulfilled by the provided futures. + public static func whenAllSucceed(_ futures: [EventLoopFuture], on eventLoop: EventLoop) -> EventLoopFuture<[Value]> { + let promise = eventLoop.makePromise(of: [Value].self) + EventLoopFuture.whenAllSucceed(futures, promise: promise) + return promise.futureResult + } + + /// Completes the `promise` with the values of all `futures` if all provided futures succeed. If + /// any of the provided futures fail then `promise` will be failed. + /// + /// If the _results of all futures should be collected use `andAllComplete` instead. + /// + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFutures`s to wait for. + /// - promise: The `EventLoopPromise` to complete with the result of this call. + public static func whenAllSucceed(_ futures: [EventLoopFuture], promise: EventLoopPromise<[Value]>) { + let eventLoop = promise.futureResult.eventLoop + let reduced = eventLoop.makePromise(of: Void.self) + + var results: [Value?] = .init(repeating: nil, count: futures.count) + let callback = { (index: Int, result: Value) in + results[index] = result + } + + if eventLoop.inEventLoop { + self._reduceSuccesses0(reduced, futures, eventLoop, onValue: callback) + } else { + eventLoop.execute { + self._reduceSuccesses0(reduced, futures, eventLoop, onValue: callback) + } + } + + reduced.futureResult.whenComplete { result in + switch result { + case .success: + // verify that all operations have been completed + assert(!results.contains(where: { $0 == nil })) + promise.succeed(results.map { $0! }) + case .failure(let error): + promise.fail(error) + } + } + } + + /// Loops through the futures array and attaches callbacks to execute `onValue` on the provided `EventLoop` when + /// they succeed. The `onValue` will receive the index of the future that fulfilled the provided `Result`. + /// + /// Once all the futures have succeed, the provided promise will succeed. + /// Once any future fails, the provided promise will fail. + @inlinable + internal static func _reduceSuccesses0(_ promise: EventLoopPromise, + _ futures: [EventLoopFuture], + _ eventLoop: EventLoop, + onValue: @escaping (Int, InputValue) -> Void) { + eventLoop.assertInEventLoop() + + var remainingCount = futures.count + + if remainingCount == 0 { + promise.succeed(()) + return + } + + // Sends the result to `onValue` in case of success and succeeds/fails the input promise, if appropriate. + func processResult(_ index: Int, _ result: Result) { + switch result { + case .success(let result): + onValue(index, result) + remainingCount -= 1 + + if remainingCount == 0 { + promise.succeed(()) + } + case .failure(let error): + promise.fail(error) + } + } + // loop through the futures to chain callbacks to execute on the initiating event loop and grab their index + // in the "futures" to pass their result to the caller + for (index, future) in futures.enumerated() { + if future.eventLoop.inEventLoop, + let result = future._value { + // Fast-track already-fulfilled results without the overhead of calling `whenComplete`. This can yield a + // ~20% performance improvement in the case of large arrays where all elements are already fulfilled. + processResult(index, result) + if case .failure = result { + return // Once the promise is failed, future results do not need to be processed. + } + } else { + future.hop(to: eventLoop) + .whenComplete { result in processResult(index, result) } + } + } + } +} + +// MARK: "fail slow" reduce + +extension EventLoopFuture { + /// Returns a new `EventLoopFuture` that succeeds when all of the provided `EventLoopFuture`s complete. + /// + /// The returned `EventLoopFuture` always succeeds, acting as a completion notification. + /// Values fulfilled by each future are discarded. + /// + /// If the results are needed, use `whenAllComplete` instead. + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFuture`s to wait for. + /// - on: The `EventLoop` on which the new `EventLoopFuture` callbacks will execute on. + /// - Returns: A new `EventLoopFuture` that succeeds after all futures complete. + @inlinable + public static func andAllComplete(_ futures: [EventLoopFuture], on eventLoop: EventLoop) -> EventLoopFuture { + let promise = eventLoop.makePromise(of: Void.self) + EventLoopFuture.andAllComplete(futures, promise: promise) + return promise.futureResult + } + + /// Completes a `promise` when all of the provided `EventLoopFuture`s have completed. + /// + /// The promise will always be succeeded, regardless of the outcome of the individual futures. + /// + /// If the results are required, use `whenAllComplete` instead. + /// + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFuture`s to wait for. + /// - promise: The `EventLoopPromise` to succeed when all futures have completed. + @inlinable + public static func andAllComplete(_ futures: [EventLoopFuture], promise: EventLoopPromise) { + let eventLoop = promise.futureResult.eventLoop + + if eventLoop.inEventLoop { + self._reduceCompletions0(promise, futures, eventLoop, onResult: { _, _ in }) + } else { + eventLoop.execute { + self._reduceCompletions0(promise, futures, eventLoop, onResult: { _, _ in }) + } + } + } + + /// Returns a new `EventLoopFuture` that succeeds when all of the provided `EventLoopFuture`s complete. + /// The new `EventLoopFuture` will contain an array of results, maintaining ordering for each of the `EventLoopFuture`s. + /// + /// The returned `EventLoopFuture` always succeeds, regardless of any failures from the waiting futures. + /// + /// If it is desired to flatten them into a single `EventLoopFuture` that fails on the first `EventLoopFuture` failure, + /// use one of the `reduce` methods instead. + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFuture`s to gather results from. + /// - on: The `EventLoop` on which the new `EventLoopFuture` callbacks will fire. + /// - Returns: A new `EventLoopFuture` with all the results of the provided futures. + @inlinable + public static func whenAllComplete(_ futures: [EventLoopFuture], + on eventLoop: EventLoop) -> EventLoopFuture<[Result]> { + let promise = eventLoop.makePromise(of: [Result].self) + EventLoopFuture.whenAllComplete(futures, promise: promise) + return promise.futureResult + } + + /// Completes a `promise` with the results of all provided `EventLoopFuture`s. + /// + /// The promise will always be succeeded, regardless of the outcome of the futures. + /// + /// - Parameters: + /// - futures: An array of homogenous `EventLoopFuture`s to gather results from. + /// - promise: The `EventLoopPromise` to complete with the result of the futures. + @inlinable + public static func whenAllComplete(_ futures: [EventLoopFuture], + promise: EventLoopPromise<[Result]>) { + let eventLoop = promise.futureResult.eventLoop + let reduced = eventLoop.makePromise(of: Void.self) + + var results: [Result] = .init(repeating: .failure(OperationPlaceholderError()), count: futures.count) + let callback = { (index: Int, result: Result) in + results[index] = result + } + + if eventLoop.inEventLoop { + self._reduceCompletions0(reduced, futures, eventLoop, onResult: callback) + } else { + eventLoop.execute { + self._reduceCompletions0(reduced, futures, eventLoop, onResult: callback) + } + } + + reduced.futureResult.whenComplete { result in + switch result { + case .success: + // verify that all operations have been completed + assert(!results.contains(where: { + guard case let .failure(error) = $0 else { return false } + return error is OperationPlaceholderError + })) + promise.succeed(results) + + case .failure(let error): + promise.fail(error) + } + } + } + + /// Loops through the futures array and attaches callbacks to execute `onResult` on the provided `EventLoop` when + /// they complete. The `onResult` will receive the index of the future that fulfilled the provided `Result`. + /// + /// Once all the futures have completed, the provided promise will succeed. + @inlinable + internal static func _reduceCompletions0(_ promise: EventLoopPromise, + _ futures: [EventLoopFuture], + _ eventLoop: EventLoop, + onResult: @escaping (Int, Result) -> Void) { + eventLoop.assertInEventLoop() + + var remainingCount = futures.count + + if remainingCount == 0 { + promise.succeed(()) + return + } + + // Sends the result to `onResult` in case of success and succeeds the input promise, if appropriate. + func processResult(_ index: Int, _ result: Result) { + onResult(index, result) + remainingCount -= 1 + + if remainingCount == 0 { + promise.succeed(()) + } + } + // loop through the futures to chain callbacks to execute on the initiating event loop and grab their index + // in the "futures" to pass their result to the caller + for (index, future) in futures.enumerated() { + if future.eventLoop.inEventLoop, + let result = future._value { + // Fast-track already-fulfilled results without the overhead of calling `whenComplete`. This can yield a + // ~30% performance improvement in the case of large arrays where all elements are already fulfilled. + processResult(index, result) + } else { + future.hop(to: eventLoop) + .whenComplete { result in processResult(index, result) } + } + } + } +} + +// MARK: hop + +extension EventLoopFuture { + /// Returns an `EventLoopFuture` that fires when this future completes, but executes its callbacks on the + /// target event loop instead of the original one. + /// + /// It is common to want to "hop" event loops when you arrange some work: for example, you're closing one channel + /// from another, and want to hop back when the close completes. This method lets you spell that requirement + /// succinctly. It also contains an optimisation for the case when the loop you're hopping *from* is the same as + /// the one you're hopping *to*, allowing you to avoid doing allocations in that case. + /// + /// - parameters: + /// - to: The `EventLoop` that the returned `EventLoopFuture` will run on. + /// - returns: An `EventLoopFuture` whose callbacks run on `target` instead of the original loop. + @inlinable + public func hop(to target: EventLoop) -> EventLoopFuture { + if target === self.eventLoop { + // We're already on that event loop, nothing to do here. Save an allocation. + return self + } + let hoppingPromise = target.makePromise(of: Value.self) + self.cascade(to: hoppingPromise) + return hoppingPromise.futureResult + } +} + +// MARK: always + +extension EventLoopFuture { + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has any result. + /// + /// - parameters: + /// - callback: the callback that is called when the `EventLoopFuture` is fulfilled. + /// - returns: the current `EventLoopFuture` + @inlinable + public func always(_ callback: @escaping (Result) -> Void) -> EventLoopFuture { + self.whenComplete { result in callback(result) } + return self + } +} + +// MARK: unwrap + +extension EventLoopFuture { + /// Unwrap an `EventLoopFuture` where its type parameter is an `Optional`. + /// + /// Unwrap a future returning a new `EventLoopFuture`. When the resolved future's value is `Optional.some(...)` + /// the new future is created with the identical value. Otherwise the `Error` passed in the `orError` parameter + /// is thrown. For example: + /// ``` + /// do { + /// try promise.futureResult.unwrap(orError: ErrorToThrow).wait() + /// } catch ErrorToThrow { + /// ... + /// } + /// ``` + /// + /// - parameters: + /// - orError: the `Error` that is thrown when then resolved future's value is `Optional.none`. + /// - returns: an new `EventLoopFuture` with new type parameter `NewValue` and the same value as the resolved + /// future. + /// - throws: the `Error` passed in the `orError` parameter when the resolved future's value is `Optional.none`. + @inlinable + public func unwrap(orError error: Error) -> EventLoopFuture where Value == Optional { + return self.flatMapThrowing { (value) throws -> NewValue in + guard let value = value else { + throw error + } + return value + } + } + + /// Unwrap an `EventLoopFuture` where its type parameter is an `Optional`. + /// + /// Unwraps a future returning a new `EventLoopFuture` with either: the value passed in the `orReplace` + /// parameter when the future resolved with value Optional.none, or the same value otherwise. For example: + /// ``` + /// promise.futureResult.unwrap(orReplace: 42).wait() + /// ``` + /// + /// - parameters: + /// - orReplace: the value of the returned `EventLoopFuture` when then resolved future's value is `Optional.some()`. + /// - returns: an new `EventLoopFuture` with new type parameter `NewValue` and the value passed in the `orReplace` parameter. + @inlinable + public func unwrap(orReplace replacement: NewValue) -> EventLoopFuture where Value == Optional { + return self.map { (value) -> NewValue in + guard let value = value else { + return replacement + } + return value + } + } + + /// Unwrap an `EventLoopFuture` where its type parameter is an `Optional`. + /// + /// Unwraps a future returning a new `EventLoopFuture` with either: the value returned by the closure passed in + /// the `orElse` parameter when the future resolved with value Optional.none, or the same value otherwise. For example: + /// ``` + /// var x = 2 + /// promise.futureResult.unwrap(orElse: { x * 2 }).wait() + /// ``` + /// + /// - parameters: + /// - orElse: a closure that returns the value of the returned `EventLoopFuture` when then resolved future's value + /// is `Optional.some()`. + /// - returns: an new `EventLoopFuture` with new type parameter `NewValue` and with the value returned by the closure + /// passed in the `orElse` parameter. + @inlinable + public func unwrap(orElse callback: @escaping () -> NewValue) -> EventLoopFuture where Value == Optional { + return self.map { (value) -> NewValue in + guard let value = value else { + return callback() + } + return value + } + } +} + +// MARK: may block + +extension EventLoopFuture { + /// Chain an `EventLoopFuture` providing the result of a IO / task that may block. For example: + /// + /// promise.futureResult.flatMapBlocking(onto: DispatchQueue.global()) { value in Int + /// blockingTask(value) + /// } + /// + /// - parameters: + /// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is scheduled. + /// - callbackMayBlock: Function that will receive the value of this `EventLoopFuture` and return + /// a new `EventLoopFuture`. + @inlinable + public func flatMapBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Value) throws -> NewValue) + -> EventLoopFuture { + return self.flatMap { result in + queue.asyncWithFuture(eventLoop: self.eventLoop) { try callbackMayBlock(result) } + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has a success result. The observer callback is permitted to block. + /// + /// An observer callback cannot return a value, meaning that this function cannot be chained + /// from. If you are attempting to create a computation pipeline, consider `map` or `flatMap`. + /// If you find yourself passing the results from this `EventLoopFuture` to a new `EventLoopPromise` + /// in the body of this function, consider using `cascade` instead. + /// + /// - parameters: + /// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is scheduled. + /// - callbackMayBlock: The callback that is called with the successful result of the `EventLoopFuture`. + @inlinable + public func whenSuccessBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Value) -> Void) { + self.whenSuccess { value in + queue.async { callbackMayBlock(value) } + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has a failure result. The observer callback is permitted to block. + /// + /// An observer callback cannot return a value, meaning that this function cannot be chained + /// from. If you are attempting to create a computation pipeline, consider `recover` or `flatMapError`. + /// If you find yourself passing the results from this `EventLoopFuture` to a new `EventLoopPromise` + /// in the body of this function, consider using `cascade` instead. + /// + /// - parameters: + /// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is scheduled. + /// - callbackMayBlock: The callback that is called with the failed result of the `EventLoopFuture`. + @inlinable + public func whenFailureBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Error) -> Void) { + self.whenFailure { err in + queue.async { callbackMayBlock(err) } + } + } + + /// Adds an observer callback to this `EventLoopFuture` that is called when the + /// `EventLoopFuture` has any result. The observer callback is permitted to block. + /// + /// - parameters: + /// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is scheduled. + /// - callbackMayBlock: The callback that is called when the `EventLoopFuture` is fulfilled. + @inlinable + public func whenCompleteBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Result) -> Void) { + self.whenComplete { value in + queue.async { callbackMayBlock(value) } + } + } +} + + +/// An opaque identifier for a specific `EventLoopFuture`. +/// +/// This is used only when attempting to provide high-fidelity diagnostics of leaked +/// `EventLoopFuture`s. It is entirely opaque and can only be stored in a simple +/// tracking data structure. +public struct _NIOEventLoopFutureIdentifier: Hashable { + private var opaqueID: UInt + + @usableFromInline + internal init(_ future: EventLoopFuture) { + self.opaqueID = _NIOEventLoopFutureIdentifier.obfuscatePointerValue(future: future) + } + + + private static func obfuscatePointerValue(future: EventLoopFuture) -> UInt { + // Note: + // 1. 0xbf15ca5d is randomly picked such that it fits into both 32 and 64 bit address spaces + // 2. XOR with 0xbf15ca5d so that Memory Graph Debugger and other memory debugging tools + // won't see it as a reference. + return UInt(bitPattern: ObjectIdentifier(future)) ^ 0xbf15ca5d + } +} + +// EventLoopPromise is a reference type, but by its very nature is Sendable. +extension EventLoopPromise: NIOSendable { } + +#if swift(>=5.5) && canImport(_Concurrency) + +// EventLoopFuture is a reference type, but it is Sendable. However, we enforce +// that by way of the guarantees of the EventLoop protocol, so the compiler cannot +// check it. +extension EventLoopFuture: @unchecked NIOSendable { } + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileDescriptor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileDescriptor.swift new file mode 100644 index 00000000..b97d874b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileDescriptor.swift @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public protocol FileDescriptor { + + /// Will be called with the file descriptor if still open, if not it will + /// throw an `IOError`. + /// + /// The ownership of the file descriptor must not escape the `body` as it's completely managed by the + /// implementation of the `FileDescriptor` protocol. + /// + /// - parameters: + /// - body: The closure to execute if the `FileDescriptor` is still open. + /// - throws: If either the `FileDescriptor` was closed before or the closure throws by itself. + func withUnsafeFileDescriptor(_ body: (CInt) throws -> T) throws -> T + + /// `true` if this `FileDescriptor` is open (which means it was not closed yet). + var isOpen: Bool { get } + + /// Close this `FileDescriptor`. + func close() throws +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileHandle.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileHandle.swift new file mode 100644 index 00000000..afdbce6d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileHandle.swift @@ -0,0 +1,170 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(Windows) +import ucrt +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Linux) || os(Android) +import Glibc +#endif + +/// A `NIOFileHandle` is a handle to an open file. +/// +/// When creating a `NIOFileHandle` it takes ownership of the underlying file descriptor. When a `NIOFileHandle` is no longer +/// needed you must `close` it or take back ownership of the file descriptor using `takeDescriptorOwnership`. +/// +/// - note: One underlying file descriptor should usually be managed by one `NIOFileHandle` only. +/// +/// - warning: Failing to manage the lifetime of a `NIOFileHandle` correctly will result in undefined behaviour. +/// +/// - warning: `NIOFileHandle` objects are not thread-safe and are mutable. They also cannot be fully thread-safe as they refer to a global underlying file descriptor. +public final class NIOFileHandle: FileDescriptor { + public private(set) var isOpen: Bool + private let descriptor: CInt + + /// Create a `NIOFileHandle` taking ownership of `descriptor`. You must call `NIOFileHandle.close` or `NIOFileHandle.takeDescriptorOwnership` before + /// this object can be safely released. + public init(descriptor: CInt) { + self.descriptor = descriptor + self.isOpen = true + } + + deinit { + assert(!self.isOpen, "leaked open NIOFileHandle(descriptor: \(self.descriptor)). Call `close()` to close or `takeDescriptorOwnership()` to take ownership and close by some other means.") + } + + /// Duplicates this `NIOFileHandle`. This means that a new `NIOFileHandle` object with a new underlying file descriptor + /// is returned. The caller takes ownership of the returned `NIOFileHandle` and is responsible for closing it. + /// + /// - warning: The returned `NIOFileHandle` is not fully independent, the seek pointer is shared as documented by `dup(2)`. + /// + /// - returns: A new `NIOFileHandle` with a fresh underlying file descriptor but shared seek pointer. + public func duplicate() throws -> NIOFileHandle { + return try withUnsafeFileDescriptor { fd in + NIOFileHandle(descriptor: try SystemCalls.dup(descriptor: fd)) + } + } + + /// Take the ownership of the underlying file descriptor. This is similar to `close()` but the underlying file + /// descriptor remains open. The caller is responsible for closing the file descriptor by some other means. + /// + /// After calling this, the `NIOFileHandle` cannot be used for anything else and all the operations will throw. + /// + /// - returns: The underlying file descriptor, now owned by the caller. + public func takeDescriptorOwnership() throws -> CInt { + guard self.isOpen else { + throw IOError(errnoCode: EBADF, reason: "can't close file (as it's not open anymore).") + } + + self.isOpen = false + return self.descriptor + } + + public func close() throws { + try withUnsafeFileDescriptor { fd in + try SystemCalls.close(descriptor: fd) + } + + self.isOpen = false + } + + public func withUnsafeFileDescriptor(_ body: (CInt) throws -> T) throws -> T { + guard self.isOpen else { + throw IOError(errnoCode: EBADF, reason: "file descriptor already closed!") + } + return try body(self.descriptor) + } +} + +extension NIOFileHandle { + /// `Mode` represents file access modes. + public struct Mode: OptionSet { + public let rawValue: UInt8 + + public init(rawValue: UInt8) { + self.rawValue = rawValue + } + + internal var posixFlags: CInt { + switch self { + case [.read, .write]: + return O_RDWR + case .read: + return O_RDONLY + case .write: + return O_WRONLY + default: + preconditionFailure("Unsupported mode value") + } + } + + /// Opens file for reading + public static let read = Mode(rawValue: 1 << 0) + /// Opens file for writing + public static let write = Mode(rawValue: 1 << 1) + } + + /// `Flags` allows to specify additional flags to `Mode`, such as permission for file creation. + public struct Flags { + internal var posixMode: mode_t + internal var posixFlags: CInt + + public static let `default` = Flags(posixMode: 0, posixFlags: 0) + + /// Allows file creation when opening file for writing. File owner is set to the effective user ID of the process. + /// + /// - parameters: + /// - posixMode: `file mode` applied when file is created. Default permissions are: read and write for fileowner, read for owners group and others. + public static func allowFileCreation(posixMode: mode_t = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) -> Flags { + return Flags(posixMode: posixMode, posixFlags: O_CREAT) + } + + /// Allows the specification of POSIX flags (e.g. `O_TRUNC`) and mode (e.g. `S_IWUSR`) + /// + /// - parameters: + /// - flags: The POSIX open flags (the second parameter for `open(2)`). + /// - mode: The POSIX mode (the third parameter for `open(2)`). + /// - returns: A `NIOFileHandle.Mode` equivalent to the given POSIX flags and mode. + public static func posix(flags: CInt, mode: mode_t) -> Flags { + return Flags(posixMode: mode, posixFlags: flags) + } + } + + /// Open a new `NIOFileHandle`. This operation is blocking. + /// + /// - parameters: + /// - path: The path of the file to open. The ownership of the file descriptor is transferred to this `NIOFileHandle` and so it will be closed once `close` is called. + /// - mode: Access mode. Default mode is `.read`. + /// - flags: Additional POSIX flags. + public convenience init(path: String, mode: Mode = .read, flags: Flags = .default) throws { + let fd = try SystemCalls.open(file: path, oFlag: mode.posixFlags | O_CLOEXEC | flags.posixFlags, mode: flags.posixMode) + self.init(descriptor: fd) + } + + /// Open a new `NIOFileHandle`. This operation is blocking. + /// + /// - parameters: + /// - path: The path of the file to open. The ownership of the file descriptor is transferred to this `NIOFileHandle` and so it will be closed once `close` is called. + public convenience init(path: String) throws { + // This function is here because we had a function like this in NIO 2.0, and the one above doesn't quite match. Sadly we can't + // really deprecate this either, because it'll be preferred to the one above in many cases. + try self.init(path: path, mode: .read, flags: .default) + } +} + +extension NIOFileHandle: CustomStringConvertible { + public var description: String { + return "FileHandle { descriptor: \(self.descriptor) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileRegion.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileRegion.swift new file mode 100644 index 00000000..c787ba72 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/FileRegion.swift @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(Windows) +import ucrt +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Linux) || os(Android) +import Glibc +#endif + + +/// A `FileRegion` represent a readable portion usually created to be sent over the network. +/// +/// Usually a `FileRegion` will allow the underlying transport to use `sendfile` to transfer its content and so allows transferring +/// the file content without copying it into user-space at all. If the actual transport implementation really can make use of sendfile +/// or if it will need to copy the content to user-space first and use `write` / `writev` is an implementation detail. That said +/// using `FileRegion` is the recommended way to transfer file content if possible. +/// +/// One important note, depending your `ChannelPipeline` setup it may not be possible to use a `FileRegion` as a `ChannelHandler` may +/// need access to the bytes (in a `ByteBuffer`) to transform these. +/// +/// - note: It is important to manually manage the lifetime of the `NIOFileHandle` used to create a `FileRegion`. +public struct FileRegion { + + /// The `NIOFileHandle` that is used by this `FileRegion`. + public let fileHandle: NIOFileHandle + + private let _endIndex: UInt64 + private var _readerIndex: _UInt56 + + /// The current reader index of this `FileRegion` + private(set) public var readerIndex: Int { + get { + return Int(self._readerIndex) + } + set { + self._readerIndex = _UInt56(newValue) + } + } + + /// The end index of this `FileRegion`. + public var endIndex: Int { + return Int(self._endIndex) + } + + /// Create a new `FileRegion` from an open `NIOFileHandle`. + /// + /// - parameters: + /// - fileHandle: the `NIOFileHandle` to use. + /// - readerIndex: the index (offset) on which the reading will start. + /// - endIndex: the index which represent the end of the readable portion. + public init(fileHandle: NIOFileHandle, readerIndex: Int, endIndex: Int) { + precondition(readerIndex <= endIndex, "readerIndex(\(readerIndex) must be <= endIndex(\(endIndex).") + + self.fileHandle = fileHandle + self._readerIndex = _UInt56(readerIndex) + self._endIndex = UInt64(endIndex) + } + + /// The number of readable bytes within this FileRegion (taking the `readerIndex` and `endIndex` into account). + public var readableBytes: Int { + return endIndex - readerIndex + } + + /// Move the readerIndex forward by `offset`. + public mutating func moveReaderIndex(forwardBy offset: Int) { + let newIndex = self.readerIndex + offset + assert(offset >= 0 && newIndex <= endIndex, "new readerIndex: \(newIndex), expected: range(0, \(endIndex))") + self.readerIndex = newIndex + } +} + +extension FileRegion { + /// Create a new `FileRegion` forming a complete file. + /// + /// - parameters: + /// - fileHandle: An open `NIOFileHandle` to the file. + public init(fileHandle: NIOFileHandle) throws { + let eof = try fileHandle.withUnsafeFileDescriptor { (fd: CInt) throws -> off_t in + let eof = try SystemCalls.lseek(descriptor: fd, offset: 0, whence: SEEK_END) + try SystemCalls.lseek(descriptor: fd, offset: 0, whence: SEEK_SET) + return eof + } + self.init(fileHandle: fileHandle, readerIndex: 0, endIndex: Int(eof)) + } + +} + +extension FileRegion: Equatable { + public static func ==(lhs: FileRegion, rhs: FileRegion) -> Bool { + return lhs.fileHandle === rhs.fileHandle && lhs.readerIndex == rhs.readerIndex && lhs.endIndex == rhs.endIndex + } +} + +extension FileRegion: CustomStringConvertible { + public var description: String { + return "FileRegion { handle: \(self.fileHandle), readerIndex: \(self.readerIndex), endIndex: \(self.endIndex) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IO.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IO.swift new file mode 100644 index 00000000..da62e5ca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IO.swift @@ -0,0 +1,140 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) +import typealias WinSDK.DWORD +#elseif os(Linux) || os(Android) +import Glibc +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#endif + +/// An `Error` for an IO operation. +public struct IOError: Swift.Error { + @available(*, deprecated, message: "NIO no longer uses FailureDescription.") + public enum FailureDescription { + case function(StaticString) + case reason(String) + } + + /// The actual reason (in an human-readable form) for this `IOError`. + private var failureDescription: String + + @available(*, deprecated, message: "NIO no longer uses FailureDescription, use IOError.description for a human-readable error description") + public var reason: FailureDescription { + return .reason(self.failureDescription) + } + + private enum Error { + #if os(Windows) + case windows(DWORD) + case winsock(CInt) + #endif + case errno(CInt) + } + + private let error: Error + + /// The `errno` that was set for the operation. + public var errnoCode: CInt { + switch self.error { + case .errno(let code): + return code + #if os(Windows) + default: + fatalError("IOError domain is not `errno`") + #endif + } + } + +#if os(Windows) + public init(windows code: DWORD, reason: String) { + self.error = .windows(code) + self.failureDescription = reason + } + + public init(winsock code: CInt, reason: String) { + self.error = .winsock(code) + self.failureDescription = reason + } +#endif + + /// Creates a new `IOError`` + /// + /// - parameters: + /// - errorCode: the `errno` that was set for the operation. + /// - reason: the actual reason (in an human-readable form). + public init(errnoCode code: CInt, reason: String) { + self.error = .errno(code) + self.failureDescription = reason + } + + /// Creates a new `IOError`` + /// + /// - parameters: + /// - errorCode: the `errno` that was set for the operation. + /// - function: The function the error happened in, the human readable description will be generated automatically when needed. + @available(*, deprecated, renamed: "init(errnoCode:reason:)") + public init(errnoCode code: CInt, function: StaticString) { + self.error = .errno(code) + self.failureDescription = "\(function)" + } +} + +/// Returns a reason to use when constructing a `IOError`. +/// +/// - parameters: +/// - errorCode: the `errno` that was set for the operation. +/// - reason: what failed +/// - returns: the constructed reason. +private func reasonForError(errnoCode: CInt, reason: String) -> String { + if let errorDescC = strerror(errnoCode) { + return "\(reason): \(String(cString: errorDescC)) (errno: \(errnoCode))" + } else { + return "\(reason): Broken strerror, unknown error: \(errnoCode)" + } +} + +extension IOError: CustomStringConvertible { + public var description: String { + return self.localizedDescription + } + + public var localizedDescription: String { + return reasonForError(errnoCode: self.errnoCode, reason: self.failureDescription) + } +} + +// FIXME: Duplicated with NIO. +/// An result for an IO operation that was done on a non-blocking resource. +enum CoreIOResult: Equatable { + + /// Signals that the IO operation could not be completed as otherwise we would need to block. + case wouldBlock(T) + + /// Signals that the IO operation was completed. + case processed(T) +} + +internal extension CoreIOResult where T: FixedWidthInteger { + var result: T { + switch self { + case .processed(let value): + return value + case .wouldBlock(_): + fatalError("cannot unwrap CoreIOResult") + } + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IOData.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IOData.swift new file mode 100644 index 00000000..f53814b0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IOData.swift @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// `IOData` unifies standard SwiftNIO types that are raw bytes of data; currently `ByteBuffer` and `FileRegion`. +/// +/// Many `ChannelHandler`s receive or emit bytes and in most cases this can be either a `ByteBuffer` or a `FileRegion` +/// from disk. To still form a well-typed `ChannelPipeline` such handlers should receive and emit value of type `IOData`. +public enum IOData { + /// A `ByteBuffer`. + case byteBuffer(ByteBuffer) + + /// A `FileRegion`. + /// + /// Sending a `FileRegion` through the `ChannelPipeline` using `write` can be useful because some `Channel`s can + /// use `sendfile` to send a `FileRegion` more efficiently. + case fileRegion(FileRegion) +} + +/// `IOData` objects are comparable just like the values they wrap. +extension IOData: Equatable {} + +/// `IOData` provide a number of readable bytes. +extension IOData { + /// Returns the number of readable bytes in this `IOData`. + public var readableBytes: Int { + switch self { + case .byteBuffer(let buf): + return buf.readableBytes + case .fileRegion(let region): + return region.readableBytes + } + } + + /// Move the readerIndex forward by `offset`. + public mutating func moveReaderIndex(forwardBy: Int) { + switch self { + case .byteBuffer(var buffer): + buffer.moveReaderIndex(forwardBy: forwardBy) + self = .byteBuffer(buffer) + case .fileRegion(var fileRegion): + fileRegion.moveReaderIndex(forwardBy: forwardBy) + self = .fileRegion(fileRegion) + } + } +} + +extension IOData: CustomStringConvertible { + public var description: String { + switch self { + case .byteBuffer(let byteBuffer): + return "IOData { \(byteBuffer) }" + case .fileRegion(let fileRegion): + return "IOData { \(fileRegion) }" + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerBitPacking.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerBitPacking.swift new file mode 100644 index 00000000..6eff57f9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerBitPacking.swift @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// FIXME: Duplicated in NIO. + +@usableFromInline +enum _IntegerBitPacking {} + +extension _IntegerBitPacking { + @inlinable + static func packUU(_ left: Left, + _ right: Right, + type: Result.Type = Result.self) -> Result { + assert(MemoryLayout.size + MemoryLayout.size <= MemoryLayout.size) + + let resultLeft = Result(left) + let resultRight = Result(right) + let result = (resultLeft << Right.bitWidth) | resultRight + assert(result.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount) + return result + } + + @inlinable + static func unpackUU(_ input: Input, + leftType: Left.Type = Left.self, + rightType: Right.Type = Right.self) -> (Left, Right) { + assert(MemoryLayout.size + MemoryLayout.size <= MemoryLayout.size) + + let leftMask = Input(Left.max) + let rightMask = Input(Right.max) + let right = input & rightMask + let left = (input >> Right.bitWidth) & leftMask + + assert(input.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount) + return (Left(left), Right(right)) + } +} + +@usableFromInline +enum IntegerBitPacking {} + +extension IntegerBitPacking { + @inlinable + static func packUInt32UInt16UInt8(_ left: UInt32, _ middle: UInt16, _ right: UInt8) -> UInt64 { + return _IntegerBitPacking.packUU( + _IntegerBitPacking.packUU(right, middle, type: UInt32.self), + left + ) + } + + @inlinable + static func unpackUInt32UInt16UInt8(_ value: UInt64) -> (UInt32, UInt16, UInt8) { + let leftRight = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self) + let left = _IntegerBitPacking.unpackUU(leftRight.0, leftType: UInt8.self, rightType: UInt16.self) + return (leftRight.1, left.1, left.0) + } + + @inlinable + static func packUInt8UInt8(_ left: UInt8, _ right: UInt8) -> UInt16 { + return _IntegerBitPacking.packUU(left, right) + } + + @inlinable + static func unpackUInt8UInt8(_ value: UInt16) -> (UInt8, UInt8) { + return _IntegerBitPacking.unpackUU(value) + } + + @inlinable + static func packUInt16UInt8(_ left: UInt16, _ right: UInt8) -> UInt32 { + return _IntegerBitPacking.packUU(left, right) + } + + @inlinable + static func unpackUInt16UInt8(_ value: UInt32) -> (UInt16, UInt8) { + return _IntegerBitPacking.unpackUU(value) + } + + @inlinable + static func packUInt32CInt(_ left: UInt32, _ right: CInt) -> UInt64 { + return _IntegerBitPacking.packUU(left, UInt32(truncatingIfNeeded: right)) + } + + @inlinable + static func unpackUInt32CInt(_ value: UInt64) -> (UInt32, CInt) { + let unpacked = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self) + return (unpacked.0, CInt(truncatingIfNeeded: unpacked.1)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerTypes.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerTypes.swift new file mode 100644 index 00000000..88edccb4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/IntegerTypes.swift @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: _UInt24 + +// FIXME: Duplicated in NIO. + +/// A 24-bit unsigned integer value type. +@usableFromInline +struct _UInt24 { + @usableFromInline var _backing: (UInt16, UInt8) + + @inlinable + init(_ value: UInt32) { + assert(value & 0xff_00_00_00 == 0, "value \(value) too large for _UInt24") + self._backing = IntegerBitPacking.unpackUInt16UInt8(value) + } + + static let bitWidth: Int = 24 + + @usableFromInline + static let max: _UInt24 = .init((UInt32(1) << 24) - 1) + + @usableFromInline + static let min: _UInt24 = .init(0) +} + +extension UInt32 { + @inlinable + init(_ value: _UInt24) { + self = IntegerBitPacking.packUInt16UInt8(value._backing.0, value._backing.1) + } +} + +extension Int { + @inlinable + init(_ value: _UInt24) { + self = Int(UInt32(value)) + } +} + + +extension _UInt24: Equatable { + @inlinable + public static func ==(lhs: _UInt24, rhs: _UInt24) -> Bool { + return lhs._backing == rhs._backing + } +} + +extension _UInt24: CustomStringConvertible { + @usableFromInline + var description: String { + return UInt32(self).description + } +} + +// MARK: _UInt56 + +/// A 56-bit unsigned integer value type. +struct _UInt56 { + @usableFromInline var _backing: (UInt32, UInt16, UInt8) + + @inlinable init(_ value: UInt64) { + self._backing = IntegerBitPacking.unpackUInt32UInt16UInt8(value) + } + + static let bitWidth: Int = 56 + + private static let initializeUInt64 : UInt64 = (1 << 56) - 1 + static let max: _UInt56 = .init(initializeUInt64) + static let min: _UInt56 = .init(0) +} + +extension _UInt56 { + init(_ value: Int) { + self.init(UInt64(value)) + } +} + +extension UInt64 { + init(_ value: _UInt56) { + self = IntegerBitPacking.packUInt32UInt16UInt8(value._backing.0, + value._backing.1, + value._backing.2) + } +} + +extension Int { + init(_ value: _UInt56) { + self = Int(UInt64(value)) + } +} + +extension _UInt56: Equatable { + @inlinable + public static func ==(lhs: _UInt56, rhs: _UInt56) -> Bool { + return lhs._backing == rhs._backing + } +} + +extension _UInt56: CustomStringConvertible { + var description: String { + return UInt64(self).description + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Interfaces.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Interfaces.swift new file mode 100644 index 00000000..3e3ff1c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Interfaces.swift @@ -0,0 +1,481 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(Linux) || os(FreeBSD) || os(Android) +import Glibc +import CNIOLinux +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Windows) +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 + +import let WinSDK.INET_ADDRSTRLEN +import let WinSDK.INET6_ADDRSTRLEN + +import struct WinSDK.ADDRESS_FAMILY +import struct WinSDK.IP_ADAPTER_ADDRESSES +import struct WinSDK.IP_ADAPTER_UNICAST_ADDRESS + +import typealias WinSDK.UINT8 +#endif + +#if !os(Windows) +private extension ifaddrs { + var dstaddr: UnsafeMutablePointer? { + #if os(Linux) || os(Android) + return self.ifa_ifu.ifu_dstaddr + #elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + return self.ifa_dstaddr + #endif + } + + var broadaddr: UnsafeMutablePointer? { + #if os(Linux) || os(Android) + return self.ifa_ifu.ifu_broadaddr + #elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + return self.ifa_dstaddr + #endif + } +} +#endif + +/// A representation of a single network interface on a system. +@available(*, deprecated, renamed: "NIONetworkDevice") +public final class NIONetworkInterface { + // This is a class because in almost all cases this will carry + // four structs that are backed by classes, and so will incur 4 + // refcount operations each time it is copied. + + /// The name of the network interface. + public let name: String + + /// The address associated with the given network interface. + public let address: SocketAddress + + /// The netmask associated with this address, if any. + public let netmask: SocketAddress? + + /// The broadcast address associated with this socket interface, if it has one. Some + /// interfaces do not, especially those that have a `pointToPointDestinationAddress`. + public let broadcastAddress: SocketAddress? + + /// The address of the peer on a point-to-point interface, if this is one. Some + /// interfaces do not have such an address: most of those have a `broadcastAddress` + /// instead. + public let pointToPointDestinationAddress: SocketAddress? + + /// If the Interface supports Multicast + public let multicastSupported: Bool + + /// The index of the interface, as provided by `if_nametoindex`. + public let interfaceIndex: Int + + internal init?(_ caddr: ifaddrs) { + self.name = String(cString: caddr.ifa_name) + + guard caddr.ifa_addr != nil else { + return nil + } + + guard let address = caddr.ifa_addr!.convert() else { + return nil + } + self.address = address + + if let netmask = caddr.ifa_netmask { + self.netmask = netmask.convert() + } else { + self.netmask = nil + } + + if (caddr.ifa_flags & UInt32(IFF_BROADCAST)) != 0, let addr = caddr.broadaddr { + self.broadcastAddress = addr.convert() + self.pointToPointDestinationAddress = nil + } else if (caddr.ifa_flags & UInt32(IFF_POINTOPOINT)) != 0, let addr = caddr.dstaddr { + self.broadcastAddress = nil + self.pointToPointDestinationAddress = addr.convert() + } else { + self.broadcastAddress = nil + self.pointToPointDestinationAddress = nil + } + + if (caddr.ifa_flags & UInt32(IFF_MULTICAST)) != 0 { + self.multicastSupported = true + } else { + self.multicastSupported = false + } + + do { + self.interfaceIndex = Int(try SystemCalls.if_nametoindex(caddr.ifa_name)) + } catch { + return nil + } + } +} + +@available(*, deprecated, renamed: "NIONetworkDevice") +extension NIONetworkInterface: CustomDebugStringConvertible { + public var debugDescription: String { + let baseString = "Interface \(self.name): address \(self.address)" + let maskString = self.netmask != nil ? " netmask \(self.netmask!)" : "" + return baseString + maskString + } +} + +@available(*, deprecated, renamed: "NIONetworkDevice") +extension NIONetworkInterface: Equatable { + public static func ==(lhs: NIONetworkInterface, rhs: NIONetworkInterface) -> Bool { + return lhs.name == rhs.name && + lhs.address == rhs.address && + lhs.netmask == rhs.netmask && + lhs.broadcastAddress == rhs.broadcastAddress && + lhs.pointToPointDestinationAddress == rhs.pointToPointDestinationAddress && + lhs.interfaceIndex == rhs.interfaceIndex + } +} + +/// A helper extension for working with sockaddr pointers. +extension UnsafeMutablePointer where Pointee == sockaddr { + /// Converts the `sockaddr` to a `SocketAddress`. + fileprivate func convert() -> SocketAddress? { + let addressBytes = UnsafeRawPointer(self) + switch NIOBSDSocket.AddressFamily(rawValue: CInt(pointee.sa_family)) { + case .inet: + return SocketAddress(addressBytes.load(as: sockaddr_in.self)) + case .inet6: + return SocketAddress(addressBytes.load(as: sockaddr_in6.self)) + case .unix: + return SocketAddress(addressBytes.load(as: sockaddr_un.self)) + default: + return nil + } + } +} + +/// A representation of a single network device on a system. +public struct NIONetworkDevice { + private var backing: Backing + + /// The name of the network device. + public var name: String { + get { + return self.backing.name + } + set { + self.uniquifyIfNeeded() + self.backing.name = newValue + } + } + + /// The address associated with the given network device. + public var address: SocketAddress? { + get { + return self.backing.address + } + set { + self.uniquifyIfNeeded() + self.backing.address = newValue + } + } + + /// The netmask associated with this address, if any. + public var netmask: SocketAddress? { + get { + return self.backing.netmask + } + set { + self.uniquifyIfNeeded() + self.backing.netmask = newValue + } + } + + /// The broadcast address associated with this socket interface, if it has one. Some + /// interfaces do not, especially those that have a `pointToPointDestinationAddress`. + public var broadcastAddress: SocketAddress? { + get { + return self.backing.broadcastAddress + } + set { + self.uniquifyIfNeeded() + self.backing.broadcastAddress = newValue + } + } + + /// The address of the peer on a point-to-point interface, if this is one. Some + /// interfaces do not have such an address: most of those have a `broadcastAddress` + /// instead. + public var pointToPointDestinationAddress: SocketAddress? { + get { + return self.backing.pointToPointDestinationAddress + } + set { + self.uniquifyIfNeeded() + self.backing.pointToPointDestinationAddress = newValue + } + } + + /// If the Interface supports Multicast + public var multicastSupported: Bool { + get { + return self.backing.multicastSupported + } + set { + self.uniquifyIfNeeded() + self.backing.multicastSupported = newValue + } + } + + /// The index of the interface, as provided by `if_nametoindex`. + public var interfaceIndex: Int { + get { + return self.backing.interfaceIndex + } + set { + self.uniquifyIfNeeded() + self.backing.interfaceIndex = newValue + } + } + + /// Create a brand new network interface. + /// + /// This constructor will fail if NIO does not understand the format of the underlying + /// socket address family. This is quite common: for example, Linux will return AF_PACKET + /// addressed interfaces on most platforms, which NIO does not currently understand. +#if os(Windows) + internal init?(_ pAdapter: UnsafeMutablePointer, + _ pAddress: UnsafeMutablePointer) { + guard let backing = Backing(pAdapter, pAddress) else { + return nil + } + self.backing = backing + } +#else + internal init?(_ caddr: ifaddrs) { + guard let backing = Backing(caddr) else { + return nil + } + + self.backing = backing + } +#endif + +#if !os(Windows) + /// Convert a `NIONetworkInterface` to a `NIONetworkDevice`. As `NIONetworkDevice`s are a superset of `NIONetworkInterface`s, + /// it is always possible to perform this conversion. + @available(*, deprecated, message: "This is a compatibility helper, and will be removed in a future release") + public init(_ interface: NIONetworkInterface) { + self.backing = Backing( + name: interface.name, + address: interface.address, + netmask: interface.netmask, + broadcastAddress: interface.broadcastAddress, + pointToPointDestinationAddress: interface.pointToPointDestinationAddress, + multicastSupported: interface.multicastSupported, + interfaceIndex: interface.interfaceIndex + ) + } +#endif + + public init(name: String, + address: SocketAddress?, + netmask: SocketAddress?, + broadcastAddress: SocketAddress?, + pointToPointDestinationAddress: SocketAddress, + multicastSupported: Bool, + interfaceIndex: Int) { + self.backing = Backing( + name: name, + address: address, + netmask: netmask, + broadcastAddress: broadcastAddress, + pointToPointDestinationAddress: pointToPointDestinationAddress, + multicastSupported: multicastSupported, + interfaceIndex: interfaceIndex + ) + } + + private mutating func uniquifyIfNeeded() { + if !isKnownUniquelyReferenced(&self.backing) { + self.backing = Backing(copying: self.backing) + } + } +} + +extension NIONetworkDevice { + fileprivate final class Backing { + /// The name of the network interface. + var name: String + + /// The address associated with the given network interface. + var address: SocketAddress? + + /// The netmask associated with this address, if any. + var netmask: SocketAddress? + + /// The broadcast address associated with this socket interface, if it has one. Some + /// interfaces do not, especially those that have a `pointToPointDestinationAddress`. + var broadcastAddress: SocketAddress? + + /// The address of the peer on a point-to-point interface, if this is one. Some + /// interfaces do not have such an address: most of those have a `broadcastAddress` + /// instead. + var pointToPointDestinationAddress: SocketAddress? + + /// If the Interface supports Multicast + var multicastSupported: Bool + + /// The index of the interface, as provided by `if_nametoindex`. + var interfaceIndex: Int + + /// Create a brand new network interface. + /// + /// This constructor will fail if NIO does not understand the format of the underlying + /// socket address family. This is quite common: for example, Linux will return AF_PACKET + /// addressed interfaces on most platforms, which NIO does not currently understand. +#if os(Windows) + internal init?(_ pAdapter: UnsafeMutablePointer, + _ pAddress: UnsafeMutablePointer) { + self.name = String(decodingCString: pAdapter.pointee.FriendlyName, + as: UTF16.self) + self.address = pAddress.pointee.Address.lpSockaddr.convert() + + // TODO: convert the prefix length to the mask itself + let v4mask: (UINT8) -> SocketAddress? = { _ in + var buffer: [CChar] = + Array(repeating: 0, count: Int(INET_ADDRSTRLEN)) + var mask: sockaddr_in = sockaddr_in() + mask.sin_family = ADDRESS_FAMILY(AF_INET) + _ = buffer.withUnsafeMutableBufferPointer { + try! NIOBSDSocket.inet_ntop(af: .inet, src: &mask, + dst: $0.baseAddress!, + size: INET_ADDRSTRLEN) + } + return SocketAddress(mask) + } + let v6mask: (UINT8) -> SocketAddress? = { _ in + var buffer: [CChar] = + Array(repeating: 0, count: Int(INET6_ADDRSTRLEN)) + var mask: sockaddr_in6 = sockaddr_in6() + mask.sin6_family = ADDRESS_FAMILY(AF_INET6) + _ = buffer.withUnsafeMutableBufferPointer { + try! NIOBSDSocket.inet_ntop(af: .inet6, src: &mask, + dst: $0.baseAddress!, + size: INET6_ADDRSTRLEN) + } + return SocketAddress(mask) + } + + switch pAddress.pointee.Address.lpSockaddr.pointee.sa_family { + case ADDRESS_FAMILY(AF_INET): + self.netmask = v4mask(pAddress.pointee.OnLinkPrefixLength) + self.interfaceIndex = Int(pAdapter.pointee.IfIndex) + break + case ADDRESS_FAMILY(AF_INET6): + self.netmask = v6mask(pAddress.pointee.OnLinkPrefixLength) + self.interfaceIndex = Int(pAdapter.pointee.Ipv6IfIndex) + break + default: + return nil + } + + // TODO(compnerd) handle broadcast/ppp/multicast information + self.broadcastAddress = nil + self.pointToPointDestinationAddress = nil + self.multicastSupported = false + } +#else + internal init?(_ caddr: ifaddrs) { + self.name = String(cString: caddr.ifa_name) + self.address = caddr.ifa_addr.flatMap { $0.convert() } + self.netmask = caddr.ifa_netmask.flatMap { $0.convert() } + + if (caddr.ifa_flags & UInt32(IFF_BROADCAST)) != 0, let addr = caddr.broadaddr { + self.broadcastAddress = addr.convert() + self.pointToPointDestinationAddress = nil + } else if (caddr.ifa_flags & UInt32(IFF_POINTOPOINT)) != 0, let addr = caddr.dstaddr { + self.broadcastAddress = nil + self.pointToPointDestinationAddress = addr.convert() + } else { + self.broadcastAddress = nil + self.pointToPointDestinationAddress = nil + } + + self.multicastSupported = (caddr.ifa_flags & UInt32(IFF_MULTICAST)) != 0 + do { + self.interfaceIndex = Int(try SystemCalls.if_nametoindex(caddr.ifa_name)) + } catch { + return nil + } + } +#endif + + init(copying original: Backing) { + self.name = original.name + self.address = original.address + self.netmask = original.netmask + self.broadcastAddress = original.broadcastAddress + self.pointToPointDestinationAddress = original.pointToPointDestinationAddress + self.multicastSupported = original.multicastSupported + self.interfaceIndex = original.interfaceIndex + } + + init(name: String, + address: SocketAddress?, + netmask: SocketAddress?, + broadcastAddress: SocketAddress?, + pointToPointDestinationAddress: SocketAddress?, + multicastSupported: Bool, + interfaceIndex: Int) { + self.name = name + self.address = address + self.netmask = netmask + self.broadcastAddress = broadcastAddress + self.pointToPointDestinationAddress = pointToPointDestinationAddress + self.multicastSupported = multicastSupported + self.interfaceIndex = interfaceIndex + } + } +} + +extension NIONetworkDevice: CustomDebugStringConvertible { + public var debugDescription: String { + let baseString = "Device \(self.name): address \(String(describing: self.address))" + let maskString = self.netmask != nil ? " netmask \(self.netmask!)" : "" + return baseString + maskString + } +} + +// Sadly, as this is class-backed we cannot synthesise the implementation. +extension NIONetworkDevice: Equatable { + public static func ==(lhs: NIONetworkDevice, rhs: NIONetworkDevice) -> Bool { + return lhs.name == rhs.name && + lhs.address == rhs.address && + lhs.netmask == rhs.netmask && + lhs.broadcastAddress == rhs.broadcastAddress && + lhs.pointToPointDestinationAddress == rhs.pointToPointDestinationAddress && + lhs.interfaceIndex == rhs.interfaceIndex + } +} + +extension NIONetworkDevice: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine(self.name) + hasher.combine(self.address) + hasher.combine(self.netmask) + hasher.combine(self.broadcastAddress) + hasher.combine(self.pointToPointDestinationAddress) + hasher.combine(self.interfaceIndex) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Linux.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Linux.swift new file mode 100644 index 00000000..f463deec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Linux.swift @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// This is a companion to System.swift that provides only Linux specials: either things that exist +// only on Linux, or things that have Linux-specific extensions. + +#if os(Linux) || os(Android) +import CNIOLinux +enum Linux { + static let cfsQuotaPath = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us" + static let cfsPeriodPath = "/sys/fs/cgroup/cpu/cpu.cfs_period_us" + static let cpuSetPath = "/sys/fs/cgroup/cpuset/cpuset.cpus" + + private static func firstLineOfFile(path: String) throws -> Substring { + let fh = try NIOFileHandle(path: path) + defer { try! fh.close() } + // linux doesn't properly report /sys/fs/cgroup/* files lengths so we use a reasonable limit + var buf = ByteBufferAllocator().buffer(capacity: 1024) + try buf.writeWithUnsafeMutableBytes(minimumWritableBytes: buf.capacity) { ptr in + let res = try fh.withUnsafeFileDescriptor { fd -> CoreIOResult in + return try SystemCalls.read(descriptor: fd, pointer: ptr.baseAddress!, size: ptr.count) + } + switch res { + case .processed(let n): + return n + case .wouldBlock: + preconditionFailure("read returned EWOULDBLOCK despite a blocking fd") + } + } + return String(buffer: buf).prefix(while: { $0 != "\n" }) + } + + private static func countCoreIds(cores: Substring) -> Int { + let ids = cores.split(separator: "-", maxSplits: 1) + guard + let first = ids.first.flatMap({ Int($0, radix: 10) }), + let last = ids.last.flatMap({ Int($0, radix: 10) }), + last >= first + else { preconditionFailure("cpuset format is incorrect") } + return 1 + last - first + } + + static func coreCount(cpuset cpusetPath: String) -> Int? { + guard + let cpuset = try? firstLineOfFile(path: cpusetPath).split(separator: ","), + !cpuset.isEmpty + else { return nil } + return cpuset.map(countCoreIds).reduce(0, +) + } + + static func coreCount(quota quotaPath: String, period periodPath: String) -> Int? { + guard + let quota = try? Int(firstLineOfFile(path: quotaPath)), + quota > 0 + else { return nil } + guard + let period = try? Int(firstLineOfFile(path: periodPath)), + period > 0 + else { return nil } + return (quota - 1 + period) / period // always round up if fractional CPU quota requested + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MarkedCircularBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MarkedCircularBuffer.swift new file mode 100644 index 00000000..b1190274 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MarkedCircularBuffer.swift @@ -0,0 +1,192 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A circular buffer that allows one object at a time to be "marked" and easily identified and retrieved later. +/// +/// This object is used extensively within SwiftNIO to handle flushable buffers. It can be used to store buffered +/// writes and mark how far through the buffer the user has flushed, and therefore how far through the buffer is +/// safe to write. +public struct MarkedCircularBuffer: CustomStringConvertible { + @usableFromInline internal var _buffer: CircularBuffer + @usableFromInline internal var _markedIndexOffset: Int? /* nil: nothing marked */ + + /// Create a new instance. + /// + /// - parameters: + /// - initialCapacity: The initial capacity of the internal storage. + @inlinable + public init(initialCapacity: Int) { + self._buffer = CircularBuffer(initialCapacity: initialCapacity) + } + + // MARK: Forwarding + + /// Appends an entry to the buffer, expanding it if needed. + @inlinable + public mutating func append(_ value: Element) { + self._buffer.append(value) + } + + /// Removes the first element from the buffer. + @inlinable + public mutating func removeFirst() -> Element { + assert(self._buffer.count > 0) + return self.popFirst()! + } + + @inlinable + public mutating func popFirst() -> Element? { + if let markedIndexOffset = self._markedIndexOffset { + if markedIndexOffset > 0 { + self._markedIndexOffset = markedIndexOffset - 1 + } else { + self._markedIndexOffset = nil + } + } + return self._buffer.popFirst() + } + + /// The first element in the buffer. + @inlinable + public var first: Element? { + return self._buffer.first + } + + /// If the buffer is empty. + @inlinable + public var isEmpty: Bool { + return self._buffer.isEmpty + } + + /// The number of elements in the buffer. + @inlinable + public var count: Int { + return self._buffer.count + } + + @inlinable + public var description: String { + return self._buffer.description + } + + // MARK: Marking + + /// Marks the buffer at the current index, making the last index in the buffer marked. + @inlinable + public mutating func mark() { + let count = self._buffer.count + if count > 0 { + self._markedIndexOffset = count - 1 + } else { + assert(self._markedIndexOffset == nil, "marked index is \(self._markedIndexOffset.debugDescription)") + } + } + + /// Returns true if the buffer is currently marked at the given index. + @inlinable + public func isMarked(index: Index) -> Bool { + assert(index >= self.startIndex, "index must not be negative") + precondition(index < self.endIndex, "index \(index) out of range (0..<\(self._buffer.count))") + if let markedIndexOffset = self._markedIndexOffset { + return self.index(self.startIndex, offsetBy: markedIndexOffset) == index + } else { + return false + } + } + + /// Returns the index of the marked element. + @inlinable + public var markedElementIndex: Index? { + if let markedIndexOffset = self._markedIndexOffset { + assert(markedIndexOffset >= 0) + return self.index(self.startIndex, offsetBy: markedIndexOffset) + } else { + return nil + } + } + + /// Returns the marked element. + @inlinable + public var markedElement: Element? { + return self.markedElementIndex.map { self._buffer[$0] } + } + + /// Returns true if the buffer has been marked at all. + @inlinable + public var hasMark: Bool { + return self._markedIndexOffset != nil + } +} + +extension MarkedCircularBuffer: Collection, MutableCollection { + public typealias RangeType = Range where Bound: Strideable, Bound.Stride: SignedInteger + public typealias Index = CircularBuffer.Index + public typealias SubSequence = CircularBuffer + + @inlinable + public func index(after i: Index) -> Index { + return self._buffer.index(after: i) + } + + @inlinable + public var startIndex: Index { return self._buffer.startIndex } + + @inlinable + public var endIndex: Index { return self._buffer.endIndex } + + /// Retrieves the element at the given index from the buffer, without removing it. + @inlinable + public subscript(index: Index) -> Element { + get { + return self._buffer[index] + } + set { + self._buffer[index] = newValue + } + } + + @inlinable + public subscript(bounds: Range) -> SubSequence { + get { + return self._buffer[bounds] + } + set { + var index = bounds.lowerBound + var iterator = newValue.makeIterator() + while let newElement = iterator.next(), index != bounds.upperBound { + self._buffer[index] = newElement + formIndex(after: &index) + } + precondition(iterator.next() == nil && index == bounds.upperBound) + } + } +} + +extension MarkedCircularBuffer: RandomAccessCollection { + @inlinable + public func index(_ i: Index, offsetBy distance: Int) -> Index { + return self._buffer.index(i, offsetBy: distance) + } + + @inlinable + public func distance(from start: Index, to end: Index) -> Int { + return self._buffer.distance(from: start, to: end) + } + + @inlinable + public func index(before i: Index) -> Index { + return self._buffer.index(before: i) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MulticastChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MulticastChannel.swift new file mode 100644 index 00000000..9669617d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/MulticastChannel.swift @@ -0,0 +1,179 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A `MulticastChannel` is a `Channel` that supports IP multicast operations: that is, a channel that can join multicast +/// groups. +/// +/// - note: As with `Channel`, all operations on a `MulticastChannel` are thread-safe. +public protocol MulticastChannel: Channel { + /// Request that the `MulticastChannel` join the multicast group given by `group`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + func joinGroup(_ group: SocketAddress, promise: EventLoopPromise?) + +#if !os(Windows) + /// Request that the `MulticastChannel` join the multicast group given by `group` on the interface + /// given by `interface`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - interface: The interface on which to join the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + @available(*, deprecated, renamed: "joinGroup(_:device:promise:)") + func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise?) +#endif + + /// Request that the `MulticastChannel` join the multicast group given by `group` on the device + /// given by `device`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - device: The device on which to join the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) + + /// Request that the `MulticastChannel` leave the multicast group given by `group`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + func leaveGroup(_ group: SocketAddress, promise: EventLoopPromise?) + +#if !os(Windows) + /// Request that the `MulticastChannel` leave the multicast group given by `group` on the interface + /// given by `interface`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - interface: The interface on which to leave the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + @available(*, deprecated, renamed: "leaveGroup(_:device:promise:)") + func leaveGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise?) +#endif + + /// Request that the `MulticastChannel` leave the multicast group given by `group` on the device + /// given by `device`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - device: The device on which to leave the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) +} + + +// MARK:- Default implementations for MulticastChannel +extension MulticastChannel { + public func joinGroup(_ group: SocketAddress, promise: EventLoopPromise?) { + self.joinGroup(group, device: nil, promise: promise) + } + + public func joinGroup(_ group: SocketAddress) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.joinGroup(group, promise: promise) + return promise.futureResult + } + +#if !os(Windows) + @available(*, deprecated, renamed: "joinGroup(_:device:)") + public func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.joinGroup(group, interface: interface, promise: promise) + return promise.futureResult + } +#endif + + public func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.joinGroup(group, device: device, promise: promise) + return promise.futureResult + } + + public func leaveGroup(_ group: SocketAddress, promise: EventLoopPromise?) { + self.leaveGroup(group, device: nil, promise: promise) + } + + public func leaveGroup(_ group: SocketAddress) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.leaveGroup(group, promise: promise) + return promise.futureResult + } + +#if !os(Windows) + @available(*, deprecated, renamed: "leaveGroup(_:device:)") + public func leaveGroup(_ group: SocketAddress, interface: NIONetworkInterface?) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.leaveGroup(group, interface: interface, promise: promise) + return promise.futureResult + } +#endif + + public func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.leaveGroup(group, device: device, promise: promise) + return promise.futureResult + } +} + +// MARK:- API Compatibility shims for MulticastChannel +extension MulticastChannel { + /// Request that the `MulticastChannel` join the multicast group given by `group` on the device + /// given by `device`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - device: The device on which to join the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + public func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) { + // We just fail this in the default implementation. Users should override it. + promise?.fail(NIOMulticastNotImplementedError()) + } + + /// Request that the `MulticastChannel` leave the multicast group given by `group` on the device + /// given by `device`. + /// + /// - parameters: + /// - group: The IP address corresponding to the relevant multicast group. + /// - device: The device on which to leave the given group, or `nil` to allow the kernel to choose. + /// - promise: The `EventLoopPromise` that will be notified once the operation is complete, or + /// `nil` if you are not interested in the result of the operation. + public func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) { + // We just fail this in the default implementation. Users should override it. + promise?.fail(NIOMulticastNotImplementedError()) + } +} + +/// Multicast is not supported on this interface. +public struct NIOMulticastNotSupportedError: Error { + public var device: NIONetworkDevice + + public init(device: NIONetworkDevice) { + self.device = device + } +} + +/// Multicast has not been properly implemented on this channel. +public struct NIOMulticastNotImplementedError: Error { + public init() {} +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOAny.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOAny.swift new file mode 100644 index 00000000..fce3eb96 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOAny.swift @@ -0,0 +1,264 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// `NIOAny` is an opaque container for values of *any* type, similar to Swift's builtin `Any` type. Contrary to +/// `Any` the overhead of `NIOAny` depends on the the type of the wrapped value. Certain types that are important +/// for the performance of a SwiftNIO application like `ByteBuffer`, `FileRegion` and `AddressEnvelope` can be expected +/// to be wrapped almost without overhead. All others will have similar performance as if they were passed as an `Any` as +/// `NIOAny` just like `Any` will contain them within an existential container. +/// +/// The most important use-cases for `NIOAny` are values travelling through the `ChannelPipeline` whose type can't +/// be calculated at compile time. For example: +/// +/// - the `channelRead` of any `ChannelInboundHandler` +/// - the `write` method of a `ChannelOutboundHandler` +/// +/// The abstraction that delivers a `NIOAny` to user code must provide a mechanism to unwrap a `NIOAny` as a +/// certain type known at run-time. Canonical example: +/// +/// class SandwichHandler: ChannelInboundHandler { +/// typealias InboundIn = Bacon /* we expected to be delivered `Bacon` ... */ +/// typealias InboundOut = Sandwich /* ... and we will make and deliver a `Sandwich` from that */ +/// +/// func channelRead(context: ChannelHandlerContext, data: NIOAny) { +/// /* we receive the `Bacon` as a `NIOAny` as at compile-time the exact configuration of the channel +/// pipeline can't be computed. The pipeline can't be computed at compile time as it can change +/// dynamically at run-time. Yet, we assert that in any configuration the channel handler before +/// `SandwichHandler` does actually send us a stream of `Bacon`. +/// */ +/// let bacon = self.unwrapInboundIn(data) /* `Bacon` or crash */ +/// let sandwich = makeSandwich(bacon) +/// context.fireChannelRead(self.wrapInboundOut(sandwich)) /* as promised we deliver a wrapped `Sandwich` */ +/// } +/// } +public struct NIOAny { + @usableFromInline + /* private but _versioned */ let _storage: _NIOAny + + /// Wrap a value in a `NIOAny`. In most cases you should not create a `NIOAny` directly using this constructor. + /// The abstraction that accepts values of type `NIOAny` must also provide a mechanism to do the wrapping. An + /// example is a `ChannelInboundHandler` which provides `self.wrapInboundOut(aValueOfTypeInboundOut)`. + @inlinable + public init(_ value: T) { + self._storage = _NIOAny(value) + } + + @usableFromInline + enum _NIOAny { + case ioData(IOData) + case bufferEnvelope(AddressedEnvelope) + case other(Any) + + @inlinable + init(_ value: T) { + switch value { + case let value as ByteBuffer: + self = .ioData(.byteBuffer(value)) + case let value as FileRegion: + self = .ioData(.fileRegion(value)) + case let value as IOData: + self = .ioData(value) + case let value as AddressedEnvelope: + self = .bufferEnvelope(value) + default: + assert(!(value is NIOAny)) + self = .other(value) + } + } + } + + /// Try unwrapping the wrapped message as `ByteBuffer`. + /// + /// returns: The wrapped `ByteBuffer` or `nil` if the wrapped message is not a `ByteBuffer`. + @inlinable + func tryAsByteBuffer() -> ByteBuffer? { + if case .ioData(.byteBuffer(let bb)) = self._storage { + return bb + } else { + return nil + } + } + + /// Force unwrapping the wrapped message as `ByteBuffer`. + /// + /// returns: The wrapped `ByteBuffer` or crash if the wrapped message is not a `ByteBuffer`. + @inlinable + func forceAsByteBuffer() -> ByteBuffer { + if let v = tryAsByteBuffer() { + return v + } else { + fatalError("tried to decode as type \(ByteBuffer.self) but found \(Mirror(reflecting: Mirror(reflecting: self._storage).children.first!.value).subjectType) with contents \(self._storage)") + } + } + + /// Try unwrapping the wrapped message as `IOData`. + /// + /// returns: The wrapped `IOData` or `nil` if the wrapped message is not a `IOData`. + @inlinable + func tryAsIOData() -> IOData? { + if case .ioData(let data) = self._storage { + return data + } else { + return nil + } + } + + /// Force unwrapping the wrapped message as `IOData`. + /// + /// returns: The wrapped `IOData` or crash if the wrapped message is not a `IOData`. + @inlinable + func forceAsIOData() -> IOData { + if let v = tryAsIOData() { + return v + } else { + fatalError("tried to decode as type \(IOData.self) but found \(Mirror(reflecting: Mirror(reflecting: self._storage).children.first!.value).subjectType) with contents \(self._storage)") + } + } + + /// Try unwrapping the wrapped message as `FileRegion`. + /// + /// returns: The wrapped `FileRegion` or `nil` if the wrapped message is not a `FileRegion`. + @inlinable + func tryAsFileRegion() -> FileRegion? { + if case .ioData(.fileRegion(let f)) = self._storage { + return f + } else { + return nil + } + } + + /// Force unwrapping the wrapped message as `FileRegion`. + /// + /// returns: The wrapped `FileRegion` or crash if the wrapped message is not a `FileRegion`. + @inlinable + func forceAsFileRegion() -> FileRegion { + if let v = tryAsFileRegion() { + return v + } else { + fatalError("tried to decode as type \(FileRegion.self) but found \(Mirror(reflecting: Mirror(reflecting: self._storage).children.first!.value).subjectType) with contents \(self._storage)") + } + } + + /// Try unwrapping the wrapped message as `AddressedEnvelope`. + /// + /// returns: The wrapped `AddressedEnvelope` or `nil` if the wrapped message is not an `AddressedEnvelope`. + @inlinable + func tryAsByteEnvelope() -> AddressedEnvelope? { + if case .bufferEnvelope(let e) = self._storage { + return e + } else { + return nil + } + } + + /// Force unwrapping the wrapped message as `AddressedEnvelope`. + /// + /// returns: The wrapped `AddressedEnvelope` or crash if the wrapped message is not an `AddressedEnvelope`. + @inlinable + func forceAsByteEnvelope() -> AddressedEnvelope { + if let e = tryAsByteEnvelope() { + return e + } else { + fatalError("tried to decode as type \(AddressedEnvelope.self) but found \(Mirror(reflecting: Mirror(reflecting: self._storage).children.first!.value).subjectType) with contents \(self._storage)") + } + } + + /// Try unwrapping the wrapped message as `T`. + /// + /// returns: The wrapped `T` or `nil` if the wrapped message is not a `T`. + @inlinable + func tryAsOther(type: T.Type = T.self) -> T? { + switch self._storage { + case .bufferEnvelope(let v): + return v as? T + case .ioData(let v): + return v as? T + case .other(let v): + return v as? T + } + } + + /// Force unwrapping the wrapped message as `T`. + /// + /// returns: The wrapped `T` or crash if the wrapped message is not a `T`. + @inlinable + func forceAsOther(type: T.Type = T.self) -> T { + if let v = tryAsOther(type: type) { + return v + } else { + fatalError("tried to decode as type \(T.self) but found \(Mirror(reflecting: Mirror(reflecting: self._storage).children.first!.value).subjectType) with contents \(self._storage)") + } + } + + /// Force unwrapping the wrapped message as `T`. + /// + /// returns: The wrapped `T` or crash if the wrapped message is not a `T`. + @inlinable + func forceAs(type: T.Type = T.self) -> T { + switch T.self { + case let t where t == ByteBuffer.self: + return self.forceAsByteBuffer() as! T + case let t where t == FileRegion.self: + return self.forceAsFileRegion() as! T + case let t where t == IOData.self: + return self.forceAsIOData() as! T + case let t where t == AddressedEnvelope.self: + return self.forceAsByteEnvelope() as! T + default: + return self.forceAsOther(type: type) + } + } + + /// Try unwrapping the wrapped message as `T`. + /// + /// returns: The wrapped `T` or `nil` if the wrapped message is not a `T`. + @inlinable + func tryAs(type: T.Type = T.self) -> T? { + switch T.self { + case let t where t == ByteBuffer.self: + return self.tryAsByteBuffer() as! T? + case let t where t == FileRegion.self: + return self.tryAsFileRegion() as! T? + case let t where t == IOData.self: + return self.tryAsIOData() as! T? + case let t where t == AddressedEnvelope.self: + return self.tryAsByteEnvelope() as! T? + default: + return self.tryAsOther(type: type) + } + } + + /// Unwrap the wrapped message. + /// + /// returns: The wrapped message. + @inlinable + func asAny() -> Any { + switch self._storage { + case .ioData(.byteBuffer(let bb)): + return bb + case .ioData(.fileRegion(let f)): + return f + case .bufferEnvelope(let e): + return e + case .other(let o): + return o + } + } +} + +extension NIOAny: CustomStringConvertible { + public var description: String { + return "NIOAny { \(self.asAny()) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOCloseOnErrorHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOCloseOnErrorHandler.swift new file mode 100644 index 00000000..955e67f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/NIOCloseOnErrorHandler.swift @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// A `ChannelInboundHandler` that closes the channel when an error is caught +public final class NIOCloseOnErrorHandler: ChannelInboundHandler { + + public typealias InboundIn = NIOAny + + /// Initialize a `NIOCloseOnErrorHandler` + public init() {} + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + context.fireErrorCaught(error) + context.close(promise: nil) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/PointerHelpers.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/PointerHelpers.swift new file mode 100644 index 00000000..0acc2f2c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/PointerHelpers.swift @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: Rebasing shims + +// FIXME: Duplicated in NIO. + +// These methods are shimmed in to NIO until https://github.com/apple/swift/pull/34879 is resolved. +// They address the fact that the current rebasing initializers are surprisingly expensive and do excessive +// checked arithmetic. This expense forces them to often be outlined, reducing the ability to optimise out +// further preconditions and branches. +extension UnsafeRawBufferPointer { + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } + + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } +} + +extension UnsafeMutableRawBufferPointer { + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/RecvByteBufferAllocator.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/RecvByteBufferAllocator.swift new file mode 100644 index 00000000..698687b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/RecvByteBufferAllocator.swift @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// Allocates `ByteBuffer`s to be used to read bytes from a `Channel` and records the number of the actual bytes that were used. +public protocol RecvByteBufferAllocator { + /// Allocates a new `ByteBuffer` that will be used to read bytes from a `Channel`. + func buffer(allocator: ByteBufferAllocator) -> ByteBuffer + + /// Records the actual number of bytes that were read by the last socket call. + /// + /// - parameters: + /// - actualReadBytes: The number of bytes that were used by the previous allocated `ByteBuffer` + /// - returns: `true` if the next call to `buffer` may return a bigger buffer then the last call to `buffer`. + mutating func record(actualReadBytes: Int) -> Bool +} + + + +/// `RecvByteBufferAllocator` which will always return a `ByteBuffer` with the same fixed size no matter what was recorded. +public struct FixedSizeRecvByteBufferAllocator: RecvByteBufferAllocator { + public let capacity: Int + + public init(capacity: Int) { + precondition(capacity > 0) + self.capacity = capacity + } + + public mutating func record(actualReadBytes: Int) -> Bool { + // Returns false as we always allocate the same size of buffers. + return false + } + + public func buffer(allocator: ByteBufferAllocator) -> ByteBuffer { + return allocator.buffer(capacity: capacity) + } +} + +/// `RecvByteBufferAllocator` which will gracefully increment or decrement the buffer size on the feedback that was recorded. +public struct AdaptiveRecvByteBufferAllocator: RecvByteBufferAllocator { + public let minimum: Int + public let maximum: Int + public let initial: Int + + private var nextReceiveBufferSize: Int + private var decreaseNow: Bool + + private static let maximumAllocationSize = 1 << 30 + + public init() { + self.init(minimum: 64, initial: 2048, maximum: 65536) + } + + public init(minimum: Int, initial: Int, maximum: Int) { + precondition(minimum >= 0, "minimum: \(minimum)") + precondition(initial >= minimum, "initial: \(initial)") + precondition(maximum >= initial, "maximum: \(maximum)") + + // We need to round all of these numbers to a power of 2. Initial will be rounded down, + // minimum down, and maximum up. + self.minimum = min(minimum, AdaptiveRecvByteBufferAllocator.maximumAllocationSize).previousPowerOf2() + self.initial = min(initial, AdaptiveRecvByteBufferAllocator.maximumAllocationSize).previousPowerOf2() + self.maximum = min(maximum, AdaptiveRecvByteBufferAllocator.maximumAllocationSize).nextPowerOf2() + + self.nextReceiveBufferSize = self.initial + self.decreaseNow = false + } + + public func buffer(allocator: ByteBufferAllocator) -> ByteBuffer { + return allocator.buffer(capacity: self.nextReceiveBufferSize) + } + + public mutating func record(actualReadBytes: Int) -> Bool { + precondition(self.nextReceiveBufferSize % 2 == 0) + precondition(self.nextReceiveBufferSize >= self.minimum) + precondition(self.nextReceiveBufferSize <= self.maximum) + + var mayGrow = false + + // This right shift is safe: nextReceiveBufferSize can never be negative, so this will stop at 0. + let lowerBound = self.nextReceiveBufferSize &>> 1 + + // Here we need to be careful with 32-bit systems: if maximum is too large then any shift or multiply will overflow, which + // we don't want. Instead we check, and clamp to this current value if we overflow. + let upperBoundCandidate = Int(truncatingIfNeeded: Int64(self.nextReceiveBufferSize) &<< 1) + let upperBound = upperBoundCandidate <= 0 ? self.nextReceiveBufferSize : upperBoundCandidate + + if actualReadBytes <= lowerBound && lowerBound >= self.minimum { + if self.decreaseNow { + self.nextReceiveBufferSize = lowerBound + self.decreaseNow = false + } else { + self.decreaseNow = true + } + } else if actualReadBytes >= self.nextReceiveBufferSize && upperBound <= self.maximum && + self.nextReceiveBufferSize != upperBound { + self.nextReceiveBufferSize = upperBound + self.decreaseNow = false + mayGrow = true + } else { + self.decreaseNow = false + } + + return mayGrow + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SingleStepByteToMessageDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SingleStepByteToMessageDecoder.swift new file mode 100644 index 00000000..1a77d1e8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SingleStepByteToMessageDecoder.swift @@ -0,0 +1,301 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// A simplified version of `ByteToMessageDecoder` that can generate zero or one messages for each invocation of `decode` or `decodeLast`. +/// Having `decode` and `decodeLast` return an optional message avoids re-entrancy problems, since the functions relinquish exclusive access +/// to the `ByteBuffer` when returning. This allows for greatly simplified processing. +/// +/// Many `ByteToMessageDecoder`'s can trivially be translated to `NIOSingleStepByteToMessageDecoder`'s. You should not implement +/// `ByteToMessageDecoder`'s `decode` and `decodeLast` methods. +public protocol NIOSingleStepByteToMessageDecoder: ByteToMessageDecoder { + /// The decoded type this `NIOSingleStepByteToMessageDecoder` decodes to. To conform to `ByteToMessageDecoder` it must be called + /// `InboundOut` - see https://bugs.swift.org/browse/SR-11868. + associatedtype InboundOut + + /// Decode from a `ByteBuffer`. + /// + /// This method will be called in a loop until either the input `ByteBuffer` has nothing to read left or `nil` is returned. If non-`nil` is + /// returned and the `ByteBuffer` contains more readable bytes, this method will immediately be invoked again, unless `decodeLast` needs + /// to be invoked instead. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` from which we decode. + /// - returns: A message if one can be decoded or `nil` if it should be called again once more data is present in the `ByteBuffer`. + mutating func decode(buffer: inout ByteBuffer) throws -> InboundOut? + + /// Decode from a `ByteBuffer` when no more data is incoming. + /// + /// Like with `decode`, this method will be called in a loop until either `nil` is returned from the method or until the input `ByteBuffer` + /// has no more readable bytes. If non-`nil` is returned and the `ByteBuffer` contains more readable bytes, this method will immediately + /// be invoked again. + /// + /// Once `nil` is returned, neither `decode` nor `decodeLast` will be called again. If there are no bytes left, `decodeLast` will be called + /// once with an empty buffer. + /// + /// - parameters: + /// - buffer: The `ByteBuffer` from which we decode. + /// - seenEOF: `true` if EOF has been seen. + /// - returns: A message if one can be decoded or `nil` if no more messages can be produced. + mutating func decodeLast(buffer: inout ByteBuffer, seenEOF: Bool) throws -> InboundOut? +} + + +// MARK: NIOSingleStepByteToMessageDecoder: ByteToMessageDecoder +extension NIOSingleStepByteToMessageDecoder { + public mutating func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + if let message = try self.decode(buffer: &buffer) { + context.fireChannelRead(self.wrapInboundOut(message)) + return .continue + } else { + return .needMoreData + } + } + + public mutating func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + if let message = try self.decodeLast(buffer: &buffer, seenEOF: seenEOF) { + context.fireChannelRead(self.wrapInboundOut(message)) + return .continue + } else { + return .needMoreData + } + } +} + + +/// `NIOSingleStepByteToMessageProcessor` uses a `NIOSingleStepByteToMessageDecoder` to produce messages +/// from a stream of incoming bytes. It works like `ByteToMessageHandler` but may be used outside of the channel pipeline. This allows +/// processing of wrapped protocols in a general way. +/// +/// A `NIOSingleStepByteToMessageProcessor` is first initialized with a `NIOSingleStepByteToMessageDecoder`. Then +/// call `process` as each `ByteBuffer` is received from the stream. The closure is called repeatedly with each message produced by +/// the decoder. +/// +/// When your stream ends, call `finishProcessing` to ensure all buffered data is passed to your decoder. This will call `decodeLast` +/// one or more times with any remaining data. +/// +/// ### Example +/// +/// Below is an example of a protocol decoded by `TwoByteStringCodec` that is sent over HTTP. `RawBodyMessageHandler` forwards the headers +/// and trailers directly and uses `NIOSingleStepByteToMessageProcessor` to send whole decoded messages. +/// +/// class TwoByteStringCodec: NIOSingleStepByteToMessageDecoder { +/// typealias InboundOut = String +/// +/// public func decode(buffer: inout ByteBuffer) throws -> InboundOut? { +/// return buffer.readString(length: 2) +/// } +/// +/// public func decodeLast(buffer: inout ByteBuffer, seenEOF: Bool) throws -> InboundOut? { +/// return try self.decode(buffer: &buffer) +/// } +/// } +/// +/// class RawBodyMessageHandler: ChannelInboundHandler { +/// typealias InboundIn = HTTPServerRequestPart // alias for HTTPPart +/// // This converts the body from ByteBuffer to String, our message type +/// typealias InboundOut = HTTPPart +/// +/// private var messageProcessor: NIOSingleStepByteToMessageProcessor? = nil +/// +/// func channelRead(context: ChannelHandlerContext, data: NIOAny) { +/// let req = self.unwrapInboundIn(data) +/// do { +/// switch req { +/// case .head(let head): +/// // simply forward on the head +/// context.fireChannelRead(self.wrapInboundOut(.head(head))) +/// case .body(let body): +/// if self.messageProcessor == nil { +/// self.messageProcessor = NIOSingleStepByteToMessageProcessor(TwoByteStringCodec()) +/// } +/// try self.messageProcessor!.process(buffer: body) { message in +/// self.channelReadMessage(context: context, message: message) +/// } +/// case .end(let trailers): +/// // Forward on any remaining messages and the trailers +/// try self.messageProcessor?.finishProcessing(seenEOF: false) { message in +/// self.channelReadMessage(context: context, message: message) +/// } +/// context.fireChannelRead(self.wrapInboundOut(.end(trailers))) +/// } +/// } catch { +/// context.fireErrorCaught(error) +/// } +/// } +/// +/// // Forward on the body messages as whole messages +/// func channelReadMessage(context: ChannelHandlerContext, message: String) { +/// context.fireChannelRead(self.wrapInboundOut(.body(message))) +/// } +/// } +/// +/// private class DecodedBodyHTTPHandler: ChannelInboundHandler { +/// typealias InboundIn = HTTPPart +/// typealias OutboundOut = HTTPServerResponsePart +/// +/// var msgs: [String] = [] +/// +/// func channelRead(context: ChannelHandlerContext, data: NIOAny) { +/// let message = self.unwrapInboundIn(data) +/// +/// switch message { +/// case .head(let head): +/// print("head: \(head)") +/// case .body(let msg): +/// self.msgs.append(msg) +/// case .end(let trailers): +/// print("trailers: \(trailers)") +/// var responseBuffer = context.channel.allocator.buffer(capacity: 32) +/// for msg in msgs { +/// responseBuffer.writeString(msg) +/// responseBuffer.writeStaticString("\n") +/// } +/// var headers = HTTPHeaders() +/// headers.add(name: "content-length", value: String(responseBuffer.readableBytes)) +/// +/// context.write(self.wrapOutboundOut(HTTPServerResponsePart.head( +/// HTTPResponseHead(version: .http1_1, +/// status: .ok, headers: headers))), promise: nil) +/// +/// context.write(self.wrapOutboundOut(HTTPServerResponsePart.body( +/// .byteBuffer(responseBuffer))), promise: nil) +/// context.writeAndFlush(self.wrapOutboundOut(HTTPServerResponsePart.end(nil)), promise: nil) +/// } +/// } +/// } +/// +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) +/// let bootstrap = ServerBootstrap(group: group).childChannelInitializer({channel in +/// channel.pipeline.configureHTTPServerPipeline(withPipeliningAssistance: true, withErrorHandling: true).flatMap { _ in +/// channel.pipeline.addHandlers([RawBodyMessageHandler(), DecodedBodyHTTPHandler()]) +/// } +/// }) +/// let channelFuture = bootstrap.bind(host: "127.0.0.1", port: 0) +/// +public final class NIOSingleStepByteToMessageProcessor { + @usableFromInline + enum DecodeMode { + /// This is a usual decode, ie. not the last chunk + case normal + /// Last chunk + case last + } + + @usableFromInline + internal private(set) var decoder: Decoder + @usableFromInline + let maximumBufferSize: Int? + @usableFromInline + internal private(set) var _buffer: ByteBuffer? + + /// Initialize a `NIOSingleStepByteToMessageProcessor`. + /// + /// - parameters: + /// - decoder: The `NIOSingleStepByteToMessageDecoder` to decode the bytes into message. + /// - maximumBufferSize: The maximum number of bytes to aggregate in-memory. + @inlinable + public init(_ decoder: Decoder, maximumBufferSize: Int? = nil) { + self.decoder = decoder + self.maximumBufferSize = maximumBufferSize + } + + @inlinable + func _append(_ buffer: ByteBuffer) { + if self._buffer == nil || self._buffer!.readableBytes == 0 { + self._buffer = buffer + } else { + var buffer = buffer + self._buffer!.writeBuffer(&buffer) + } + } + + @inlinable + func _withNonCoWBuffer(_ body: (inout ByteBuffer) throws -> Decoder.InboundOut?) throws -> Decoder.InboundOut? { + guard var buffer = self._buffer else { + return nil + } + + if buffer.readableBytes == 0 { + return nil + } + + self._buffer = nil // To avoid CoW + let result = try body(&buffer) + self._buffer = buffer + return result + } + + @inlinable + func _decodeLoop(decodeMode: DecodeMode, seenEOF: Bool = false, _ messageReceiver: (Decoder.InboundOut) throws -> Void) throws { + // we want to call decodeLast once with an empty buffer if we have nothing + if decodeMode == .last && (self._buffer == nil || self._buffer!.readableBytes == 0) { + var emptyBuffer = self._buffer == nil ? ByteBuffer() : self._buffer! + if let message = try self.decoder.decodeLast(buffer: &emptyBuffer, seenEOF: seenEOF) { + try messageReceiver(message) + } + return + } + + // buffer can only be nil if we're called from finishProcessing which is handled above + assert(self._buffer != nil) + + func decodeOnce(buffer: inout ByteBuffer) throws -> Decoder.InboundOut? { + if decodeMode == .normal { + return try self.decoder.decode(buffer: &buffer) + } else { + return try self.decoder.decodeLast(buffer: &buffer, seenEOF: seenEOF) + } + } + + while let message = try self._withNonCoWBuffer(decodeOnce) { + try messageReceiver(message) + } + + if let maximumBufferSize = self.maximumBufferSize, self._buffer!.readableBytes > maximumBufferSize { + throw ByteToMessageDecoderError.PayloadTooLargeError() + } + + // force unwrapping is safe because nil case is handled already and asserted above + if self._buffer!.readerIndex > 0, self.decoder.shouldReclaimBytes(buffer: self._buffer!) { + self._buffer!.discardReadBytes() + } + } +} + + +// MARK: NIOSingleStepByteToMessageProcessor Public API +extension NIOSingleStepByteToMessageProcessor { + /// Feed data into the `NIOSingleStepByteToMessageProcessor` + /// + /// - parameters: + /// - buffer: The `ByteBuffer` containing the next data in the stream + /// - messageReceiver: A closure called for each message produced by the `Decoder` + @inlinable + public func process(buffer: ByteBuffer, _ messageReceiver: (Decoder.InboundOut) throws -> Void) throws { + self._append(buffer) + try self._decodeLoop(decodeMode: .normal, messageReceiver) + } + + /// Call when there is no data left in the stream. Calls `Decoder`.`decodeLast` one or more times. If there is no data left + /// `decodeLast` will be called one time with an empty `ByteBuffer`. + /// + /// - parameters: + /// - seenEOF: Whether an EOF was seen on the stream. + /// - messageReceiver: A closure called for each message produced by the `Decoder`. + @inlinable + public func finishProcessing(seenEOF: Bool, _ messageReceiver: (Decoder.InboundOut) throws -> Void) throws { + try self._decodeLoop(decodeMode: .last, seenEOF: seenEOF, messageReceiver) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketAddresses.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketAddresses.swift new file mode 100644 index 00000000..db1ee810 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketAddresses.swift @@ -0,0 +1,648 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 + +import func WinSDK.FreeAddrInfoW +import func WinSDK.GetAddrInfoW + +import struct WinSDK.ADDRESS_FAMILY +import struct WinSDK.ADDRINFOW +import struct WinSDK.in_addr_t + +import typealias WinSDK.u_short +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +import CNIOLinux +#endif + +/// Special `Error` that may be thrown if we fail to create a `SocketAddress`. +public enum SocketAddressError: Error { + /// The host is unknown (could not be resolved). + case unknown(host: String, port: Int) + /// The requested `SocketAddress` is not supported. + case unsupported + /// The requested UDS path is too long. + case unixDomainSocketPathTooLong + /// Unable to parse a given IP string + case failedToParseIPString(String) +} + +extension SocketAddressError { + /// Unable to parse a given IP ByteBuffer + public struct FailedToParseIPByteBuffer: Error, Hashable { + public var address: ByteBuffer + + public init(address: ByteBuffer) { + self.address = address + } + } +} + +/// Represent a socket address to which we may want to connect or bind. +public enum SocketAddress: CustomStringConvertible { + + /// A single IPv4 address for `SocketAddress`. + public struct IPv4Address { + private let _storage: Box<(address: sockaddr_in, host: String)> + + /// The libc socket address for an IPv4 address. + public var address: sockaddr_in { return _storage.value.address } + + /// The host this address is for, if known. + public var host: String { return _storage.value.host } + + fileprivate init(address: sockaddr_in, host: String) { + self._storage = Box((address: address, host: host)) + } + } + + /// A single IPv6 address for `SocketAddress`. + public struct IPv6Address { + private let _storage: Box<(address: sockaddr_in6, host: String)> + + /// The libc socket address for an IPv6 address. + public var address: sockaddr_in6 { return _storage.value.address } + + /// The host this address is for, if known. + public var host: String { return _storage.value.host } + + fileprivate init(address: sockaddr_in6, host: String) { + self._storage = Box((address: address, host: host)) + } + } + + /// A single Unix socket address for `SocketAddress`. + public struct UnixSocketAddress { + private let _storage: Box + + /// The libc socket address for a Unix Domain Socket. + public var address: sockaddr_un { return _storage.value } + + fileprivate init(address: sockaddr_un) { + self._storage = Box(address) + } + } + + /// An IPv4 `SocketAddress`. + case v4(IPv4Address) + + /// An IPv6 `SocketAddress`. + case v6(IPv6Address) + + /// An UNIX Domain `SocketAddress`. + case unixDomainSocket(UnixSocketAddress) + + /// A human-readable description of this `SocketAddress`. Mostly useful for logging. + public var description: String { + let addressString: String + let port: String + let host: String? + let type: String + switch self { + case .v4(let addr): + host = addr.host.isEmpty ? nil : addr.host + type = "IPv4" + var mutAddr = addr.address.sin_addr + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + addressString = try! descriptionForAddress(family: .inet, bytes: &mutAddr, length: Int(INET_ADDRSTRLEN)) + + port = "\(self.port!)" + case .v6(let addr): + host = addr.host.isEmpty ? nil : addr.host + type = "IPv6" + var mutAddr = addr.address.sin6_addr + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + addressString = try! descriptionForAddress(family: .inet6, bytes: &mutAddr, length: Int(INET6_ADDRSTRLEN)) + + port = "\(self.port!)" + case .unixDomainSocket(_): + host = nil + type = "UDS" + return "[\(type)]\(self.pathname ?? "")" + } + + return "[\(type)]\(host.map { "\($0)/\(addressString):" } ?? "\(addressString):")\(port)" + } + + @available(*, deprecated, renamed: "SocketAddress.protocol") + public var protocolFamily: Int32 { + return Int32(self.protocol.rawValue) + } + + /// Returns the protocol family as defined in `man 2 socket` of this `SocketAddress`. + public var `protocol`: NIOBSDSocket.ProtocolFamily { + switch self { + case .v4: + return .inet + case .v6: + return .inet6 + case .unixDomainSocket: + return .unix + } + } + + /// Get the IP address as a string + public var ipAddress: String? { + switch self { + case .v4(let addr): + var mutAddr = addr.address.sin_addr + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + return try! descriptionForAddress(family: .inet, bytes: &mutAddr, length: Int(INET_ADDRSTRLEN)) + case .v6(let addr): + var mutAddr = addr.address.sin6_addr + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + return try! descriptionForAddress(family: .inet6, bytes: &mutAddr, length: Int(INET6_ADDRSTRLEN)) + case .unixDomainSocket(_): + return nil + } + } + + /// Get and set the port associated with the address, if defined. + /// When setting to `nil` the port will default to `0` for compatible sockets. The rationale for this is that both `nil` and `0` can + /// be interpreted as "no preference". + /// Setting a non-nil value for a unix domain socket is invalid and will result in a fatal error. + public var port: Int? { + get { + switch self { + case .v4(let addr): + // looks odd but we need to first convert the endianness as `in_port_t` and then make the result an `Int`. + return Int(in_port_t(bigEndian: addr.address.sin_port)) + case .v6(let addr): + // looks odd but we need to first convert the endianness as `in_port_t` and then make the result an `Int`. + return Int(in_port_t(bigEndian: addr.address.sin6_port)) + case .unixDomainSocket: + return nil + } + } + set { + switch self { + case .v4(let addr): + var mutAddr = addr.address + mutAddr.sin_port = in_port_t(newValue ?? 0).bigEndian + self = .v4(.init(address: mutAddr, host: addr.host)) + case .v6(let addr): + var mutAddr = addr.address + mutAddr.sin6_port = in_port_t(newValue ?? 0).bigEndian + self = .v6(.init(address: mutAddr, host: addr.host)) + case .unixDomainSocket: + precondition(newValue == nil, "attempting to set a non-nil value to a unix socket is not valid") + } + } + } + + /// Get the pathname of a UNIX domain socket as a string + public var pathname: String? { + switch self { + case .v4: + return nil + case .v6: + return nil + case .unixDomainSocket(let addr): + // This is a static assert that exists just to verify the safety of the assumption below. + assert(Swift.type(of: addr.address.sun_path.0) == CChar.self) + let pathname: String = withUnsafePointer(to: addr.address.sun_path) { ptr in + // Homogeneous tuples are always implicitly also bound to their element type, so this assumption below is safe. + let charPtr = UnsafeRawPointer(ptr).assumingMemoryBound(to: CChar.self) + return String(cString: charPtr) + } + return pathname + } + } + + /// Calls the given function with a pointer to a `sockaddr` structure and the associated size + /// of that structure. + public func withSockAddr(_ body: (UnsafePointer, Int) throws -> T) rethrows -> T { + switch self { + case .v4(let addr): + return try addr.address.withSockAddr({ try body($0, $1) }) + case .v6(let addr): + return try addr.address.withSockAddr({ try body($0, $1) }) + case .unixDomainSocket(let addr): + return try addr.address.withSockAddr({ try body($0, $1) }) + } + } + + /// Creates a new IPv4 `SocketAddress`. + /// + /// - parameters: + /// - addr: the `sockaddr_in` that holds the ipaddress and port. + /// - host: the hostname that resolved to the ipaddress. + public init(_ addr: sockaddr_in, host: String) { + self = .v4(.init(address: addr, host: host)) + } + + /// Creates a new IPv6 `SocketAddress`. + /// + /// - parameters: + /// - addr: the `sockaddr_in` that holds the ipaddress and port. + /// - host: the hostname that resolved to the ipaddress. + public init(_ addr: sockaddr_in6, host: String) { + self = .v6(.init(address: addr, host: host)) + } + + /// Creates a new IPv4 `SocketAddress`. + /// + /// - parameters: + /// - addr: the `sockaddr_in` that holds the ipaddress and port. + public init(_ addr: sockaddr_in) { + self = .v4(.init(address: addr, host: addr.addressDescription())) + } + + /// Creates a new IPv6 `SocketAddress`. + /// + /// - parameters: + /// - addr: the `sockaddr_in` that holds the ipaddress and port. + public init(_ addr: sockaddr_in6) { + self = .v6(.init(address: addr, host: addr.addressDescription())) + } + + /// Creates a new Unix Domain Socket `SocketAddress`. + /// + /// - parameters: + /// - addr: the `sockaddr_un` that holds the socket path. + public init(_ addr: sockaddr_un) { + self = .unixDomainSocket(.init(address: addr)) + } + + /// Creates a new UDS `SocketAddress`. + /// + /// - parameters: + /// - path: the path to use for the `SocketAddress`. + /// - returns: the `SocketAddress` for the given path. + /// - throws: may throw `SocketAddressError.unixDomainSocketPathTooLong` if the path is too long. + public init(unixDomainSocketPath: String) throws { + guard unixDomainSocketPath.utf8.count <= 103 else { + throw SocketAddressError.unixDomainSocketPathTooLong + } + + let pathBytes = unixDomainSocketPath.utf8 + [0] + + var addr = sockaddr_un() + addr.sun_family = sa_family_t(NIOBSDSocket.AddressFamily.unix.rawValue) + + pathBytes.withUnsafeBytes { srcBuffer in + withUnsafeMutableBytes(of: &addr.sun_path) { dstPtr in + dstPtr.copyMemory(from: srcBuffer) + } + } + + self = .unixDomainSocket(.init(address: addr)) + } + + /// Create a new `SocketAddress` for an IP address in string form. + /// + /// - parameters: + /// - string: The IP address, in string form. + /// - port: The target port. + /// - returns: the `SocketAddress` corresponding to this string and port combination. + /// - throws: may throw `SocketAddressError.failedToParseIPString` if the IP address cannot be parsed. + public init(ipAddress: String, port: Int) throws { + self = try ipAddress.withCString { + do { + var ipv4Addr = in_addr() + try NIOBSDSocket.inet_pton(addressFamily: .inet, addressDescription: $0, address: &ipv4Addr) + + var addr = sockaddr_in() + addr.sin_family = sa_family_t(NIOBSDSocket.AddressFamily.inet.rawValue) + addr.sin_port = in_port_t(port).bigEndian + addr.sin_addr = ipv4Addr + + return .v4(.init(address: addr, host: "")) + } catch { + // If `inet_pton` fails as an IPv4 address, we will try as an + // IPv6 address. + } + + do { + var ipv6Addr = in6_addr() + try NIOBSDSocket.inet_pton(addressFamily: .inet6, addressDescription: $0, address: &ipv6Addr) + + var addr = sockaddr_in6() + addr.sin6_family = sa_family_t(NIOBSDSocket.AddressFamily.inet6.rawValue) + addr.sin6_port = in_port_t(port).bigEndian + addr.sin6_flowinfo = 0 + addr.sin6_addr = ipv6Addr + addr.sin6_scope_id = 0 + return .v6(.init(address: addr, host: "")) + } catch { + // If `inet_pton` fails as an IPv6 address (and has failed as an + // IPv4 address above), we will throw an error below. + } + + throw SocketAddressError.failedToParseIPString(ipAddress) + } + } + + /// Create a new `SocketAddress` for an IP address in ByteBuffer form. + /// + /// - parameters: + /// - packedIPAddress: The IP address, in ByteBuffer form. + /// - port: The target port. + /// - returns: the `SocketAddress` corresponding to this string and port combination. + /// - throws: may throw `SocketAddressError.failedToParseIPByteBuffer` if the IP address cannot be parsed. + public init(packedIPAddress: ByteBuffer, port: Int) throws { + let packed = packedIPAddress.readableBytesView + + switch packedIPAddress.readableBytes { + case 4: + var ipv4Addr = sockaddr_in() + ipv4Addr.sin_family = sa_family_t(AF_INET) + ipv4Addr.sin_port = in_port_t(port).bigEndian + withUnsafeMutableBytes(of: &ipv4Addr.sin_addr) { $0.copyBytes(from: packed) } + self = .v4(.init(address: ipv4Addr, host: "")) + case 16: + var ipv6Addr = sockaddr_in6() + ipv6Addr.sin6_family = sa_family_t(AF_INET6) + ipv6Addr.sin6_port = in_port_t(port).bigEndian + withUnsafeMutableBytes(of: &ipv6Addr.sin6_addr) { $0.copyBytes(from: packed) } + self = .v6(.init(address: ipv6Addr, host: "")) + default: + throw SocketAddressError.FailedToParseIPByteBuffer(address: packedIPAddress) + } + } + + /// Creates a new `SocketAddress` for the given host (which will be resolved) and port. + /// + /// - warning: This is a blocking call, so please avoid calling this from an `EventLoop`. + /// + /// - parameters: + /// - host: the hostname which should be resolved. + /// - port: the port itself + /// - returns: the `SocketAddress` for the host / port pair. + /// - throws: a `SocketAddressError.unknown` if we could not resolve the `host`, or `SocketAddressError.unsupported` if the address itself is not supported (yet). + public static func makeAddressResolvingHost(_ host: String, port: Int) throws -> SocketAddress { +#if os(Windows) + return try host.withCString(encodedAs: UTF16.self) { wszHost in + return try String(port).withCString(encodedAs: UTF16.self) { wszPort in + var pResult: UnsafeMutablePointer? + + guard GetAddrInfoW(wszHost, wszPort, nil, &pResult) == 0 else { + throw SocketAddressError.unknown(host: host, port: port) + } + + defer { + FreeAddrInfoW(pResult) + } + + if let pResult = pResult { + let addressBytes = UnsafeRawPointer(pResult.pointee.ai_addr) + switch pResult.pointee.ai_family { + case AF_INET: + return .v4(IPv4Address(address: addressBytes.load(as: sockaddr_in.self), host: host)) + case AF_INET6: + return .v6(IPv6Address(address: addressBytes.load(as: sockaddr_in6.self), host: host)) + default: + break + } + } + + throw SocketAddressErro.unsupported + } + } +#else + var info: UnsafeMutablePointer? + + /* FIXME: this is blocking! */ + if getaddrinfo(host, String(port), nil, &info) != 0 { + throw SocketAddressError.unknown(host: host, port: port) + } + + defer { + if info != nil { + freeaddrinfo(info) + } + } + + if let info = info, let addrPointer = info.pointee.ai_addr { + let addressBytes = UnsafeRawPointer(addrPointer) + switch NIOBSDSocket.AddressFamily(rawValue: info.pointee.ai_family) { + case .inet: + return .v4(.init(address: addressBytes.load(as: sockaddr_in.self), host: host)) + case .inet6: + return .v6(.init(address: addressBytes.load(as: sockaddr_in6.self), host: host)) + default: + throw SocketAddressError.unsupported + } + } else { + /* this is odd, getaddrinfo returned NULL */ + throw SocketAddressError.unsupported + } +#endif + } +} + +/// We define an extension on `SocketAddress` that gives it an elementwise equatable conformance, using +/// only the elements defined on the structure in their man pages (excluding lengths). +extension SocketAddress: Equatable { + public static func ==(lhs: SocketAddress, rhs: SocketAddress) -> Bool { + switch (lhs, rhs) { + case (.v4(let addr1), .v4(let addr2)): + return addr1.address.sin_family == addr2.address.sin_family && + addr1.address.sin_port == addr2.address.sin_port && + addr1.address.sin_addr.s_addr == addr2.address.sin_addr.s_addr + case (.v6(let addr1), .v6(let addr2)): + guard addr1.address.sin6_family == addr2.address.sin6_family && + addr1.address.sin6_port == addr2.address.sin6_port && + addr1.address.sin6_flowinfo == addr2.address.sin6_flowinfo && + addr1.address.sin6_scope_id == addr2.address.sin6_scope_id else { + return false + } + + var s6addr1 = addr1.address.sin6_addr + var s6addr2 = addr2.address.sin6_addr + return memcmp(&s6addr1, &s6addr2, MemoryLayout.size(ofValue: s6addr1)) == 0 + case (.unixDomainSocket(let addr1), .unixDomainSocket(let addr2)): + guard addr1.address.sun_family == addr2.address.sun_family else { + return false + } + + let bufferSize = MemoryLayout.size(ofValue: addr1.address.sun_path) + + + // Swift implicitly binds the memory for homogeneous tuples to both the tuple type and the element type. + // This allows us to use assumingMemoryBound(to:) for managing the types. However, we add a static assertion here to validate + // that the element type _really is_ what we're assuming it to be. + assert(Swift.type(of: addr1.address.sun_path.0) == CChar.self) + assert(Swift.type(of: addr2.address.sun_path.0) == CChar.self) + return withUnsafePointer(to: addr1.address.sun_path) { sunpath1 in + return withUnsafePointer(to: addr2.address.sun_path) { sunpath2 in + let typedSunpath1 = UnsafeRawPointer(sunpath1).assumingMemoryBound(to: CChar.self) + let typedSunpath2 = UnsafeRawPointer(sunpath2).assumingMemoryBound(to: CChar.self) + return strncmp(typedSunpath1, typedSunpath2, bufferSize) == 0 + } + } + case (.v4, _), (.v6, _), (.unixDomainSocket, _): + return false + } + } +} + +/// We define an extension on `SocketAddress` that gives it an elementwise hashable conformance, using +/// only the elements defined on the structure in their man pages (excluding lengths). +extension SocketAddress: Hashable { + public func hash(into hasher: inout Hasher) { + switch self { + case .unixDomainSocket(let uds): + hasher.combine(0) + hasher.combine(uds.address.sun_family) + + let pathSize = MemoryLayout.size(ofValue: uds.address.sun_path) + + // Swift implicitly binds the memory of homogeneous tuples to both the tuple type and the element type. + // We can therefore use assumingMemoryBound(to:) for pointer type conversion. We add a static assert just to + // validate that we are actually right about the element type. + assert(Swift.type(of: uds.address.sun_path.0) == CChar.self) + withUnsafePointer(to: uds.address.sun_path) { pathPtr in + let typedPathPointer = UnsafeRawPointer(pathPtr).assumingMemoryBound(to: CChar.self) + let length = strnlen(typedPathPointer, pathSize) + let bytes = UnsafeRawBufferPointer(start: UnsafeRawPointer(typedPathPointer), count: length) + hasher.combine(bytes: bytes) + } + case .v4(let v4Addr): + hasher.combine(1) + hasher.combine(v4Addr.address.sin_family) + hasher.combine(v4Addr.address.sin_port) + hasher.combine(v4Addr.address.sin_addr.s_addr) + case .v6(let v6Addr): + hasher.combine(2) + hasher.combine(v6Addr.address.sin6_family) + hasher.combine(v6Addr.address.sin6_port) + hasher.combine(v6Addr.address.sin6_flowinfo) + hasher.combine(v6Addr.address.sin6_scope_id) + withUnsafeBytes(of: v6Addr.address.sin6_addr) { + hasher.combine(bytes: $0) + } + } + } +} + + +extension SocketAddress { + /// Whether this `SocketAddress` corresponds to a multicast address. + public var isMulticast: Bool { + switch self { + case .unixDomainSocket: + // No multicast on unix sockets. + return false + case .v4(let v4Addr): + // For IPv4 a multicast address is in the range 224.0.0.0/4. + // The easy way to check if this is the case is to just mask off + // the address. + let v4WireAddress = v4Addr.address.sin_addr.s_addr + let mask = in_addr_t(0xF000_0000 as UInt32).bigEndian + let subnet = in_addr_t(0xE000_0000 as UInt32).bigEndian + return v4WireAddress & mask == subnet + case .v6(let v6Addr): + // For IPv6 a multicast address is in the range ff00::/8. + // Here we don't need a bitmask, as all the top bits are set, + // so we can just ask for equality on the top byte. + var v6WireAddress = v6Addr.address.sin6_addr + return withUnsafeBytes(of: &v6WireAddress) { $0[0] == 0xff } + } + } +} + +protocol SockAddrProtocol { + func withSockAddr(_ body: (UnsafePointer, Int) throws -> R) rethrows -> R +} + +/// Returns a description for the given address. +internal func descriptionForAddress(family: NIOBSDSocket.AddressFamily, bytes: UnsafeRawPointer, length byteCount: Int) throws -> String { + var addressBytes: [Int8] = Array(repeating: 0, count: byteCount) + return try addressBytes.withUnsafeMutableBufferPointer { (addressBytesPtr: inout UnsafeMutableBufferPointer) -> String in + try NIOBSDSocket.inet_ntop(addressFamily: family, addressBytes: bytes, + addressDescription: addressBytesPtr.baseAddress!, + addressDescriptionLength: socklen_t(byteCount)) + return addressBytesPtr.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: byteCount) { addressBytesPtr -> String in + String(cString: addressBytesPtr) + } + } +} + +extension sockaddr_in: SockAddrProtocol { + func withSockAddr(_ body: (UnsafePointer, Int) throws -> R) rethrows -> R { + return try withUnsafeBytes(of: self) { p in + try body(p.baseAddress!.assumingMemoryBound(to: sockaddr.self), p.count) + } + } + + /// Returns a description of the `sockaddr_in`. + func addressDescription() -> String { + return withUnsafePointer(to: self.sin_addr) { addrPtr in + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + try! descriptionForAddress(family: .inet, bytes: addrPtr, length: Int(INET_ADDRSTRLEN)) + } + } +} + +extension sockaddr_in6: SockAddrProtocol { + func withSockAddr(_ body: (UnsafePointer, Int) throws -> R) rethrows -> R { + return try withUnsafeBytes(of: self) { p in + try body(p.baseAddress!.assumingMemoryBound(to: sockaddr.self), p.count) + } + } + + /// Returns a description of the `sockaddr_in6`. + func addressDescription() -> String { + return withUnsafePointer(to: self.sin6_addr) { addrPtr in + // this uses inet_ntop which is documented to only fail if family is not AF_INET or AF_INET6 (or ENOSPC) + try! descriptionForAddress(family: .inet6, bytes: addrPtr, length: Int(INET6_ADDRSTRLEN)) + } + } +} + +extension sockaddr_un: SockAddrProtocol { + func withSockAddr(_ body: (UnsafePointer, Int) throws -> R) rethrows -> R { + return try withUnsafeBytes(of: self) { p in + try body(p.baseAddress!.assumingMemoryBound(to: sockaddr.self), p.count) + } + } +} + +extension sockaddr_storage: SockAddrProtocol { + func withSockAddr(_ body: (UnsafePointer, Int) throws -> R) rethrows -> R { + return try withUnsafeBytes(of: self) { p in + try body(p.baseAddress!.assumingMemoryBound(to: sockaddr.self), p.count) + } + } +} + +// MARK: Workarounds for SR-14268 +// We need these free functions to expose our extension methods, because otherwise +// the compiler falls over when we try to access them from test code. As these functions +// exist purely to make the behaviours accessible from test code, we name them truly awfully. +func __testOnly_addressDescription(_ addr: sockaddr_in) -> String { + return addr.addressDescription() +} + +func __testOnly_addressDescription(_ addr: sockaddr_in6) -> String { + return addr.addressDescription() +} + +func __testOnly_withSockAddr( + _ addr: sockaddr_in, _ body: (UnsafePointer, Int) throws -> ReturnType +) rethrows -> ReturnType { + return try addr.withSockAddr(body) +} + +func __testOnly_withSockAddr( + _ addr: sockaddr_in6, _ body: (UnsafePointer, Int) throws -> ReturnType +) rethrows -> ReturnType { + return try addr.withSockAddr(body) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketOptionProvider.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketOptionProvider.swift new file mode 100644 index 00000000..cabcafd7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SocketOptionProvider.swift @@ -0,0 +1,283 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#elseif os(Linux) || os(Android) +import Glibc +#endif + +/// This protocol defines an object, most commonly a `Channel`, that supports +/// setting and getting socket options (via `setsockopt`/`getsockopt` or similar). +/// It provides a strongly typed API that makes working with larger, less-common +/// socket options easier than the `ChannelOption` API allows. +/// +/// The API is divided into two portions. For socket options that NIO has prior +/// knowledge about, the API has strongly and safely typed APIs that only allow +/// users to use the exact correct type for the socket option. This will ensure +/// that the API is safe to use, and these are encouraged where possible. +/// +/// These safe APIs are built on top of an "unsafe" API that is also exposed to +/// users as part of this protocol. The "unsafe" API is unsafe in the same way +/// that `UnsafePointer` is: incorrect use of the API allows all kinds of +/// memory-unsafe behaviour. This API is necessary for socket options that NIO +/// does not have prior knowledge of, but wherever possible users are discouraged +/// from using it. +/// +/// ### Relationship to SocketOption +/// +/// All `Channel` objects that implement this protocol should also support the +/// `SocketOption` `ChannelOption` for simple socket options (those with C `int` +/// values). These are the most common socket option types, and so this `ChannelOption` +/// represents a convenient shorthand for using this protocol where the type allows, +/// as well as avoiding the need to cast to this protocol. +/// +/// - note: Like the `Channel` protocol, all methods in this protocol are +/// thread-safe. +public protocol SocketOptionProvider { + /// The `EventLoop` which is used by this `SocketOptionProvider` for execution. + var eventLoop: EventLoop { get } + + #if !os(Windows) + /// Set a socket option for a given level and name to the specified value. + /// + /// This function is not memory-safe: if you set the generic type parameter incorrectly, + /// this function will still execute, and this can cause you to incorrectly interpret memory + /// and thereby read uninitialized or invalid memory. If at all possible, please use one of + /// the safe functions defined by this protocol. + /// + /// - parameters: + /// - level: The socket option level, e.g. `SOL_SOCKET` or `IPPROTO_IP`. + /// - name: The name of the socket option, e.g. `SO_REUSEADDR`. + /// - value: The value to set the socket option to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + func unsafeSetSocketOption(level: SocketOptionLevel, name: SocketOptionName, value: Value) -> EventLoopFuture + #endif + + /// Set a socket option for a given level and name to the specified value. + /// + /// This function is not memory-safe: if you set the generic type parameter incorrectly, + /// this function will still execute, and this can cause you to incorrectly interpret memory + /// and thereby read uninitialized or invalid memory. If at all possible, please use one of + /// the safe functions defined by this protocol. + /// + /// - parameters: + /// - level: The socket option level, e.g. `SOL_SOCKET` or `IPPROTO_IP`. + /// - name: The name of the socket option, e.g. `SO_REUSEADDR`. + /// - value: The value to set the socket option to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + func unsafeSetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: Value) -> EventLoopFuture + + #if !os(Windows) + /// Obtain the value of the socket option for the given level and name. + /// + /// This function is not memory-safe: if you set the generic type parameter incorrectly, + /// this function will still execute, and this can cause you to incorrectly interpret memory + /// and thereby read uninitialized or invalid memory. If at all possible, please use one of + /// the safe functions defined by this protocol. + /// + /// - parameters: + /// - level: The socket option level, e.g. `SOL_SOCKET` or `IPPROTO_IP`. + /// - name: The name of the socket option, e.g. `SO_REUSEADDR`. + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + func unsafeGetSocketOption(level: SocketOptionLevel, name: SocketOptionName) -> EventLoopFuture + #endif + + /// Obtain the value of the socket option for the given level and name. + /// + /// This function is not memory-safe: if you set the generic type parameter incorrectly, + /// this function will still execute, and this can cause you to incorrectly interpret memory + /// and thereby read uninitialized or invalid memory. If at all possible, please use one of + /// the safe functions defined by this protocol. + /// + /// - parameters: + /// - level: The socket option level, e.g. `SOL_SOCKET` or `IPPROTO_IP`. + /// - name: The name of the socket option, e.g. `SO_REUSEADDR`. + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + func unsafeGetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) -> EventLoopFuture +} + +#if !os(Windows) + extension SocketOptionProvider { + func unsafeSetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: Value) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: SocketOptionLevel(level.rawValue), name: SocketOptionName(name.rawValue), value: value) + } + + func unsafeGetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) -> EventLoopFuture { + return self.unsafeGetSocketOption(level: SocketOptionLevel(level.rawValue), name: SocketOptionName(name.rawValue)) + } + } +#endif + +// MARK:- Safe helper methods. +// Hello code reader! All the methods in this extension are "safe" wrapper methods that define the correct +// types for `setSocketOption` and `getSocketOption` and call those methods on behalf of the user. These +// wrapper methods are memory safe. All of these methods are basically identical, and have been copy-pasted +// around. As a result, if you change one, you should probably change them all. +// +// You are welcome to add more helper methods here, but each helper method you add must be tested. +extension SocketOptionProvider { + /// Sets the socket option SO_LINGER to `value`. + /// + /// - parameters: + /// - value: The value to set SO_LINGER to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setSoLinger(_ value: linger) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .socket, name: .so_linger, value: value) + } + + /// Gets the value of the socket option SO_LINGER. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getSoLinger() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .socket, name: .so_linger) + } + + /// Sets the socket option IP_MULTICAST_IF to `value`. + /// + /// - parameters: + /// - value: The value to set IP_MULTICAST_IF to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPMulticastIF(_ value: in_addr) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ip, name: .ip_multicast_if, value: value) + } + + /// Gets the value of the socket option IP_MULTICAST_IF. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPMulticastIF() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ip, name: .ip_multicast_if) + } + + /// Sets the socket option IP_MULTICAST_TTL to `value`. + /// + /// - parameters: + /// - value: The value to set IP_MULTICAST_TTL to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPMulticastTTL(_ value: CUnsignedChar) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ip, name: .ip_multicast_ttl, value: value) + } + + /// Gets the value of the socket option IP_MULTICAST_TTL. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPMulticastTTL() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ip, name: .ip_multicast_ttl) + } + + /// Sets the socket option IP_MULTICAST_LOOP to `value`. + /// + /// - parameters: + /// - value: The value to set IP_MULTICAST_LOOP to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPMulticastLoop(_ value: CUnsignedChar) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ip, name: .ip_multicast_loop, value: value) + } + + /// Gets the value of the socket option IP_MULTICAST_LOOP. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPMulticastLoop() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ip, name: .ip_multicast_loop) + } + + /// Sets the socket option IPV6_MULTICAST_IF to `value`. + /// + /// - parameters: + /// - value: The value to set IPV6_MULTICAST_IF to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPv6MulticastIF(_ value: CUnsignedInt) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ipv6, name: .ipv6_multicast_if, value: value) + } + + /// Gets the value of the socket option IPV6_MULTICAST_IF. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPv6MulticastIF() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ipv6, name: .ipv6_multicast_if) + } + + /// Sets the socket option IPV6_MULTICAST_HOPS to `value`. + /// + /// - parameters: + /// - value: The value to set IPV6_MULTICAST_HOPS to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPv6MulticastHops(_ value: CInt) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ipv6, name: .ipv6_multicast_hops, value: value) + } + + /// Gets the value of the socket option IPV6_MULTICAST_HOPS. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPv6MulticastHops() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ipv6, name: .ipv6_multicast_hops) + } + + /// Sets the socket option IPV6_MULTICAST_LOOP to `value`. + /// + /// - parameters: + /// - value: The value to set IPV6_MULTICAST_LOOP to. + /// - returns: An `EventLoopFuture` that fires when the option has been set, + /// or if an error has occurred. + public func setIPv6MulticastLoop(_ value: CUnsignedInt) -> EventLoopFuture { + return self.unsafeSetSocketOption(level: .ipv6, name: .ipv6_multicast_loop, value: value) + } + + /// Gets the value of the socket option IPV6_MULTICAST_LOOP. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getIPv6MulticastLoop() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .ipv6, name: .ipv6_multicast_loop) + } + + #if os(Linux) || os(FreeBSD) || os(Android) + /// Gets the value of the socket option TCP_INFO. + /// + /// This socket option cannot be set. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getTCPInfo() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .tcp, name: .tcp_info) + } + #endif + + #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + /// Gets the value of the socket option TCP_CONNECTION_INFO. + /// + /// This socket option cannot be set. + /// + /// - returns: An `EventLoopFuture` containing the value of the socket option, or + /// any error that occurred while retrieving the socket option. + public func getTCPConnectionInfo() -> EventLoopFuture { + return self.unsafeGetSocketOption(level: .tcp, name: .tcp_connection_info) + } + #endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SystemCallHelpers.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SystemCallHelpers.swift new file mode 100644 index 00000000..9451e30c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/SystemCallHelpers.swift @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +// This file contains code that ensures errno is captured correctly when doing syscalls and no ARC traffic can happen inbetween that *could* change the errno +// value before we were able to read it. +// It's important that all static methods are declared with `@inline(never)` so it's not possible any ARC traffic happens while we need to read errno. +// +// Created by Norman Maurer on 11/10/17. +// +// This file arguably shouldn't be here in NIOCore, but due to early design decisions we accidentally exposed a few types that +// know about system calls into the core API (looking at you, FileHandle). As a result we need support for a small number of system calls. +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#elseif os(Windows) +import CNIOWindows +#else +#error("bad os") +#endif + +private let sysDup: @convention(c) (CInt) -> CInt = dup +private let sysClose: @convention(c) (CInt) -> CInt = close +private let sysOpenWithMode: @convention(c) (UnsafePointer, CInt, mode_t) -> CInt = open +private let sysLseek: @convention(c) (CInt, off_t, CInt) -> off_t = lseek +private let sysRead: @convention(c) (CInt, UnsafeMutableRawPointer?, size_t) -> size_t = read +private let sysIfNameToIndex: @convention(c) (UnsafePointer?) -> CUnsignedInt = if_nametoindex + +#if !os(Windows) +private let sysGetifaddrs: @convention(c) (UnsafeMutablePointer?>?) -> CInt = getifaddrs +#endif + +private func isUnacceptableErrno(_ code: Int32) -> Bool { + switch code { + case EFAULT, EBADF: + return true + default: + return false + } +} + +private func preconditionIsNotUnacceptableErrno(err: CInt, where function: String) -> Void { + // strerror is documented to return "Unknown error: ..." for illegal value so it won't ever fail + precondition(!isUnacceptableErrno(err), "unacceptable errno \(err) \(String(cString: strerror(err)!)) in \(function))") +} + +/* + * Sorry, we really try hard to not use underscored attributes. In this case + * however we seem to break the inlining threshold which makes a system call + * take twice the time, ie. we need this exception. + */ +@inline(__always) +@discardableResult +internal func syscall(blocking: Bool, + where function: String = #function, + _ body: () throws -> T) + throws -> CoreIOResult { + while true { + let res = try body() + if res == -1 { + let err = errno + switch (err, blocking) { + case (EINTR, _): + continue + case (EWOULDBLOCK, true): + return .wouldBlock(0) + default: + preconditionIsNotUnacceptableErrno(err: err, where: function) + throw IOError(errnoCode: err, reason: function) + } + } + return .processed(res) + } +} + +enum SystemCalls { + @discardableResult + @inline(never) + internal static func dup(descriptor: CInt) throws -> CInt { + return try syscall(blocking: false) { + sysDup(descriptor) + }.result + } + + @inline(never) + internal static func close(descriptor: CInt) throws { + let res = sysClose(descriptor) + if res == -1 { + let err = errno + + // There is really nothing "sane" we can do when EINTR was reported on close. + // So just ignore it and "assume" everything is fine == we closed the file descriptor. + // + // For more details see: + // - https://bugs.chromium.org/p/chromium/issues/detail?id=269623 + // - https://lwn.net/Articles/576478/ + if err != EINTR { + preconditionIsNotUnacceptableErrno(err: err, where: #function) + throw IOError(errnoCode: err, reason: "close") + } + } + } + + @inline(never) + internal static func open(file: UnsafePointer, oFlag: CInt, mode: mode_t) throws -> CInt { + return try syscall(blocking: false) { + sysOpenWithMode(file, oFlag, mode) + }.result + } + + @discardableResult + @inline(never) + internal static func lseek(descriptor: CInt, offset: off_t, whence: CInt) throws -> off_t { + return try syscall(blocking: false) { + sysLseek(descriptor, offset, whence) + }.result + } + + @inline(never) + internal static func read(descriptor: CInt, pointer: UnsafeMutableRawPointer, size: size_t) throws -> CoreIOResult { + return try syscall(blocking: true) { + sysRead(descriptor, pointer, size) + } + } + + @inline(never) + internal static func if_nametoindex(_ name: UnsafePointer?) throws -> CUnsignedInt { + return try syscall(blocking: false) { + sysIfNameToIndex(name) + }.result + } + + #if !os(Windows) + @inline(never) + internal static func getifaddrs(_ addrs: UnsafeMutablePointer?>) throws { + _ = try syscall(blocking: false) { + sysGetifaddrs(addrs) + } + } + #endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/TypeAssistedChannelHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/TypeAssistedChannelHandler.swift new file mode 100644 index 00000000..00c09d51 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/TypeAssistedChannelHandler.swift @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// ChannelHandler which will emit data by calling `ChannelHandlerContext.write`. +/// +/// We _strongly_ advice against implementing this protocol directly. Please implement `ChannelInboundHandler` or / and `ChannelOutboundHandler`. +public protocol _EmittingChannelHandler { + /// The type of the outbound data which will be forwarded to the next `ChannelOutboundHandler` in the `ChannelPipeline`. + associatedtype OutboundOut = Never + + /// Wrap the provided `OutboundOut` that will be passed to the next `ChannelOutboundHandler` by calling `ChannelHandlerContext.write`. + @inlinable + func wrapOutboundOut(_ value: OutboundOut) -> NIOAny +} + +/// Default implementations for `_EmittingChannelHandler`. +extension _EmittingChannelHandler { + @inlinable + public func wrapOutboundOut(_ value: OutboundOut) -> NIOAny { + return NIOAny(value) + } +} + +/// `ChannelHandler` which handles inbound I/O events for a `Channel`. +/// +/// Please refer to `_ChannelInboundHandler` and `_EmittingChannelHandler` for more details on the provided methods. +public protocol ChannelInboundHandler: _ChannelInboundHandler, _EmittingChannelHandler { + /// The type of the inbound data which is wrapped in `NIOAny`. + associatedtype InboundIn + + /// The type of the inbound data which will be forwarded to the next `ChannelInboundHandler` in the `ChannelPipeline`. + associatedtype InboundOut = Never + + /// Unwrap the provided `NIOAny` that was passed to `channelRead`. + @inlinable + func unwrapInboundIn(_ value: NIOAny) -> InboundIn + + /// Wrap the provided `InboundOut` that will be passed to the next `ChannelInboundHandler` by calling `ChannelHandlerContext.fireChannelRead`. + @inlinable + func wrapInboundOut(_ value: InboundOut) -> NIOAny +} + +/// Default implementations for `ChannelInboundHandler`. +extension ChannelInboundHandler { + @inlinable + public func unwrapInboundIn(_ value: NIOAny) -> InboundIn { + return value.forceAs() + } + + @inlinable + public func wrapInboundOut(_ value: InboundOut) -> NIOAny { + return NIOAny(value) + } +} + +/// `ChannelHandler` which handles outbound I/O events or intercept an outbound I/O operation for a `Channel`. +/// +/// Please refer to `_ChannelOutboundHandler` and `_EmittingChannelHandler` for more details on the provided methods. +public protocol ChannelOutboundHandler: _ChannelOutboundHandler, _EmittingChannelHandler { + /// The type of the outbound data which is wrapped in `NIOAny`. + associatedtype OutboundIn + + /// Unwrap the provided `NIOAny` that was passed to `write`. + @inlinable + func unwrapOutboundIn(_ value: NIOAny) -> OutboundIn +} + +/// Default implementations for `ChannelOutboundHandler`. +extension ChannelOutboundHandler { + @inlinable + public func unwrapOutboundIn(_ value: NIOAny) -> OutboundIn { + return value.forceAs() + } +} + +/// A combination of `ChannelInboundHandler` and `ChannelOutboundHandler`. +public typealias ChannelDuplexHandler = ChannelInboundHandler & ChannelOutboundHandler diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/UniversalBootstrapSupport.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/UniversalBootstrapSupport.swift new file mode 100644 index 00000000..f52923f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/UniversalBootstrapSupport.swift @@ -0,0 +1,261 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// `NIOClientTCPBootstrapProtocol` is implemented by various underlying transport mechanisms. Typically, +/// this will be the BSD Sockets API implemented by `ClientBootstrap`. +public protocol NIOClientTCPBootstrapProtocol { + /// Initialize the connected `SocketChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The connected `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - warning: The `handler` closure may be invoked _multiple times_ so it's usually the right choice to instantiate + /// `ChannelHandler`s within `handler`. The reason `handler` may be invoked multiple times is that to + /// successfully set up a connection multiple connections might be setup in the process. Assuming a + /// hostname that resolves to both IPv4 and IPv6 addresses, NIO will follow + /// [_Happy Eyeballs_](https://en.wikipedia.org/wiki/Happy_Eyeballs) and race both an IPv4 and an IPv6 + /// connection. It is possible that both connections get fully established before the IPv4 connection + /// will be closed again because the IPv6 connection 'won the race'. Therefore the `channelInitializer` + /// might be called multiple times and it's important not to share stateful `ChannelHandler`s in more + /// than one `Channel`. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self + + /// Sets the protocol handlers that will be added to the front of the `ChannelPipeline` right after the + /// `channelInitializer` has been called. + /// + /// Per bootstrap, you can only set the `protocolHandlers` once. Typically, `protocolHandlers` are used for the TLS + /// implementation. Most notably, `NIOClientTCPBootstrap`, NIO's "universal bootstrap" abstraction, uses + /// `protocolHandlers` to add the required `ChannelHandler`s for many TLS implementations. + func protocolHandlers(_ handlers: @escaping () -> [ChannelHandler]) -> Self + + /// Specifies a `ChannelOption` to be applied to the `SocketChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + func channelOption(_ option: Option, value: Option.Value) -> Self + + /// Apply any understood convenience options to the bootstrap, removing them from the set of options if they are consumed. + /// Method is optional to implement and should never be directly called by users. + /// - parameters: + /// - options: The options to try applying - the options applied should be consumed from here. + /// - returns: The updated bootstrap with and options applied. + func _applyChannelConvenienceOptions(_ options: inout ChannelOptions.TCPConvenienceOptions) -> Self + + /// - parameters: + /// - timeout: The timeout that will apply to the connection attempt. + func connectTimeout(_ timeout: TimeAmount) -> Self + + /// Specify the `host` and `port` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - host: The host to connect to. + /// - port: The port to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + func connect(host: String, port: Int) -> EventLoopFuture + + /// Specify the `address` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - address: The address to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + func connect(to address: SocketAddress) -> EventLoopFuture + + /// Specify the `unixDomainSocket` path to connect to for the UDS `Channel` that will be established. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + func connect(unixDomainSocketPath: String) -> EventLoopFuture +} + +/// `NIOClientTCPBootstrap` is a bootstrap that allows you to bootstrap client TCP connections using NIO on BSD Sockets, +/// NIO Transport Services, or other ways. +/// +/// Usually, to bootstrap a connection with SwiftNIO, you have to match the right `EventLoopGroup`, the right bootstrap, +/// and the right TLS implementation. Typical choices involve: +/// - `MultiThreadedEventLoopGroup`, `ClientBootstrap`, and `NIOSSLClientHandler` (from +/// [`swift-nio-ssl`](https://github.com/apple/swift-nio-ssl)) for NIO on BSD sockets. +/// - `NIOTSEventLoopGroup`, `NIOTSConnectionBootstrap`, and the Network.framework TLS implementation (all from +/// [`swift-nio-transport-services`](https://github.com/apple/swift-nio-transport-services). +/// +/// Bootstrapping connections that way works but is quite tedious for packages that support multiple ways of +/// bootstrapping. The idea behind `NIOClientTCPBootstrap` is to do all configuration in one place (when you initialize +/// a `NIOClientTCPBootstrap`) and then have a common API that works for all use-cases. +/// +/// Example: +/// +/// // This function combines the right pieces and returns you a "universal client bootstrap" +/// // (`NIOClientTCPBootstrap`). This allows you to bootstrap connections (with or without TLS) using either the +/// // NIO on sockets (`NIO`) or NIO on Network.framework (`NIOTransportServices`) stacks. +/// // The remainder of the code should be platform-independent. +/// func makeUniversalBootstrap(serverHostname: String) throws -> (NIOClientTCPBootstrap, EventLoopGroup) { +/// func useNIOOnSockets() throws -> (NIOClientTCPBootstrap, EventLoopGroup) { +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) +/// let sslContext = try NIOSSLContext(configuration: TLSConfiguration.forClient()) +/// let bootstrap = try NIOClientTCPBootstrap(ClientBootstrap(group: group), +/// tls: NIOSSLClientTLSProvider(context: sslContext, +/// serverHostname: serverHostname)) +/// return (bootstrap, group) +/// } +/// +/// #if canImport(Network) +/// if #available(macOS 10.14, iOS 12, tvOS 12, watchOS 3, *) { +/// // We run on a new-enough Darwin so we can use Network.framework +/// +/// let group = NIOTSEventLoopGroup() +/// let bootstrap = NIOClientTCPBootstrap(NIOTSConnectionBootstrap(group: group), +/// tls: NIOTSClientTLSProvider()) +/// return (bootstrap, group) +/// } else { +/// // We're on Darwin but not new enough for Network.framework, so we fall back on NIO on BSD sockets. +/// return try useNIOOnSockets() +/// } +/// #else +/// // We are on a non-Darwin platform, so we'll use BSD sockets. +/// return try useNIOOnSockets() +/// #endif +/// } +/// +/// let (bootstrap, group) = try makeUniversalBootstrap(serverHostname: "example.com") +/// let connection = try bootstrap +/// .channelInitializer { channel in +/// channel.pipeline.addHandler(PrintEverythingHandler { _ in }) +/// } +/// .enableTLS() +/// .connect(host: "example.com", port: 443) +/// .wait() +public struct NIOClientTCPBootstrap { + public let underlyingBootstrap: NIOClientTCPBootstrapProtocol + private let tlsEnablerTypeErased: (NIOClientTCPBootstrapProtocol) -> NIOClientTCPBootstrapProtocol + + /// Initialize a `NIOClientTCPBootstrap` using the underlying `Bootstrap` alongside a compatible `TLS` + /// implementation. + /// + /// - note: If you do not require `TLS`, you can use `NIOInsecureNoTLS` which supports only plain-text + /// connections. We highly recommend to always use TLS. + /// + /// - parameters: + /// - bootstrap: The underlying bootstrap to use. + /// - tls: The TLS implementation to use, needs to be compatible with `Bootstrap`. + public init(_ bootstrap: Bootstrap, tls: TLS) where TLS.Bootstrap == Bootstrap { + self.underlyingBootstrap = bootstrap + self.tlsEnablerTypeErased = { bootstrap in + return tls.enableTLS(bootstrap as! TLS.Bootstrap) + } + } + + private init(_ bootstrap: NIOClientTCPBootstrapProtocol, + tlsEnabler: @escaping (NIOClientTCPBootstrapProtocol) -> NIOClientTCPBootstrapProtocol) { + self.underlyingBootstrap = bootstrap + self.tlsEnablerTypeErased = tlsEnabler + } + + internal init(_ original : NIOClientTCPBootstrap, updating underlying : NIOClientTCPBootstrapProtocol) { + self.underlyingBootstrap = underlying + self.tlsEnablerTypeErased = original.tlsEnablerTypeErased + } + + /// Initialize the connected `SocketChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The connected `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - warning: The `handler` closure may be invoked _multiple times_ so it's usually the right choice to instantiate + /// `ChannelHandler`s within `handler`. The reason `handler` may be invoked multiple times is that to + /// successfully set up a connection multiple connections might be setup in the process. Assuming a + /// hostname that resolves to both IPv4 and IPv6 addresses, NIO will follow + /// [_Happy Eyeballs_](https://en.wikipedia.org/wiki/Happy_Eyeballs) and race both an IPv4 and an IPv6 + /// connection. It is possible that both connections get fully established before the IPv4 connection + /// will be closed again because the IPv6 connection 'won the race'. Therefore the `channelInitializer` + /// might be called multiple times and it's important not to share stateful `ChannelHandler`s in more + /// than one `Channel`. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + public func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> NIOClientTCPBootstrap { + return NIOClientTCPBootstrap(self.underlyingBootstrap.channelInitializer(handler), + tlsEnabler: self.tlsEnablerTypeErased) + } + + /// Specifies a `ChannelOption` to be applied to the `SocketChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + public func channelOption(_ option: Option, value: Option.Value) -> NIOClientTCPBootstrap { + return NIOClientTCPBootstrap(self.underlyingBootstrap.channelOption(option, value: value), + tlsEnabler: self.tlsEnablerTypeErased) + } + + /// - parameters: + /// - timeout: The timeout that will apply to the connection attempt. + public func connectTimeout(_ timeout: TimeAmount) -> NIOClientTCPBootstrap { + return NIOClientTCPBootstrap(self.underlyingBootstrap.connectTimeout(timeout), + tlsEnabler: self.tlsEnablerTypeErased) + } + + /// Specify the `host` and `port` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - host: The host to connect to. + /// - port: The port to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(host: String, port: Int) -> EventLoopFuture { + return self.underlyingBootstrap.connect(host: host, port: port) + } + + /// Specify the `address` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - address: The address to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(to address: SocketAddress) -> EventLoopFuture { + return self.underlyingBootstrap.connect(to: address) + } + + /// Specify the `unixDomainSocket` path to connect to for the UDS `Channel` that will be established. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(unixDomainSocketPath: String) -> EventLoopFuture { + return self.underlyingBootstrap.connect(unixDomainSocketPath: unixDomainSocketPath) + } + + + @discardableResult + public func enableTLS() -> NIOClientTCPBootstrap { + return NIOClientTCPBootstrap(self.tlsEnablerTypeErased(self.underlyingBootstrap), + tlsEnabler: self.tlsEnablerTypeErased) + } +} + +public protocol NIOClientTLSProvider { + associatedtype Bootstrap + + func enableTLS(_ bootstrap: Bootstrap) -> Bootstrap +} + +public struct NIOInsecureNoTLS: NIOClientTLSProvider { + public init() {} + + public func enableTLS(_ bootstrap: Bootstrap) -> Bootstrap { + fatalError("NIOInsecureNoTLS cannot enable TLS.") + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Utilities.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Utilities.swift new file mode 100644 index 00000000..ccd1c0ba --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOCore/Sources/NIOCore/Utilities.swift @@ -0,0 +1,202 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(Linux) || os(FreeBSD) || os(Android) +import CNIOLinux +import Glibc +#elseif os(Windows) +import let WinSDK.RelationProcessorCore + +import let WinSDK.AF_UNSPEC +import let WinSDK.ERROR_SUCCESS + +import func WinSDK.GetAdaptersAddresses +import func WinSDK.GetLastError +import func WinSDK.GetLogicalProcessorInformation + +import struct WinSDK.IP_ADAPTER_ADDRESSES +import struct WinSDK.IP_ADAPTER_UNICAST_ADDRESS +import struct WinSDK.SYSTEM_LOGICAL_PROCESSOR_INFORMATION +import struct WinSDK.ULONG + +import typealias WinSDK.DWORD +#elseif os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +import Darwin +#endif + +/// A utility function that runs the body code only in debug builds, without +/// emitting compiler warnings. +/// +/// This is currently the only way to do this in Swift: see +/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion. +@inlinable +internal func debugOnly(_ body: () -> Void) { + // FIXME: duplicated with NIO. + assert({ body(); return true }()) +} + +/// Allows to "box" another value. +final class Box { + // FIXME: Duplicated with NIO. + let value: T + init(_ value: T) { self.value = value } +} + +public enum System { + /// A utility function that returns an estimate of the number of *logical* cores + /// on the system. + /// + /// This value can be used to help provide an estimate of how many threads to use with + /// the `MultiThreadedEventLoopGroup`. The exact ratio between this number and the number + /// of threads to use is a matter for the programmer, and can be determined based on the + /// specific execution behaviour of the program. + /// + /// - returns: The logical core count on the system. + public static var coreCount: Int { +#if os(Windows) + var dwLength: DWORD = 0 + _ = GetLogicalProcessorInformation(nil, &dwLength) + + let alignment: Int = + MemoryLayout.alignment + let pBuffer: UnsafeMutableRawPointer = + UnsafeMutableRawPointer.allocate(byteCount: Int(dwLength), + alignment: alignment) + defer { + pBuffer.deallocate() + } + + let dwSLPICount: Int = + Int(dwLength) / MemoryLayout.stride + let pSLPI: UnsafeMutablePointer = + pBuffer.bindMemory(to: SYSTEM_LOGICAL_PROCESSOR_INFORMATION.self, + capacity: dwSLPICount) + + let bResult: Bool = GetLogicalProcessorInformation(pSLPI, &dwLength) + precondition(bResult, "GetLogicalProcessorInformation: \(GetLastError())") + + return UnsafeBufferPointer(start: pSLPI, + count: dwSLPICount) + .filter { $0.Relationship == RelationProcessorCore } + .map { $0.ProcessorMask.nonzeroBitCount } + .reduce(0, +) +#elseif os(Linux) || os(Android) + if let quota = Linux.coreCount(quota: Linux.cfsQuotaPath, period: Linux.cfsPeriodPath) { + return quota + } else if let cpusetCount = Linux.coreCount(cpuset: Linux.cpuSetPath) { + return cpusetCount + } else { + return sysconf(CInt(_SC_NPROCESSORS_ONLN)) + } +#else + return sysconf(CInt(_SC_NPROCESSORS_ONLN)) +#endif + } + +#if !os(Windows) + /// A utility function that enumerates the available network interfaces on this machine. + /// + /// This function returns values that are true for a brief snapshot in time. These results can + /// change, and the returned values will not change to reflect them. This function must be called + /// again to get new results. + /// + /// - returns: An array of network interfaces available on this machine. + /// - throws: If an error is encountered while enumerating interfaces. + @available(*, deprecated, renamed: "enumerateDevices") + public static func enumerateInterfaces() throws -> [NIONetworkInterface] { + var interfaces: [NIONetworkInterface] = [] + interfaces.reserveCapacity(12) // Arbitrary choice. + + var interface: UnsafeMutablePointer? = nil + try SystemCalls.getifaddrs(&interface) + let originalInterface = interface + defer { + freeifaddrs(originalInterface) + } + + while let concreteInterface = interface { + if let nioInterface = NIONetworkInterface(concreteInterface.pointee) { + interfaces.append(nioInterface) + } + interface = concreteInterface.pointee.ifa_next + } + + return interfaces + } +#endif + + /// A utility function that enumerates the available network devices on this machine. + /// + /// This function returns values that are true for a brief snapshot in time. These results can + /// change, and the returned values will not change to reflect them. This function must be called + /// again to get new results. + /// + /// - returns: An array of network devices available on this machine. + /// - throws: If an error is encountered while enumerating interfaces. + public static func enumerateDevices() throws -> [NIONetworkDevice] { + var devices: [NIONetworkDevice] = [] + devices.reserveCapacity(12) // Arbitrary choice. + +#if os(Windows) + var ulSize: ULONG = 0 + _ = GetAdaptersAddresses(ULONG(AF_UNSPEC), 0, nil, nil, &ulSize) + + let stride: Int = MemoryLayout.stride + let pBuffer: UnsafeMutableBufferPointer = + UnsafeMutableBufferPointer.allocate(capacity: Int(ulSize) / stride) + defer { + pBuffer.deallocate() + } + + let ulResult: ULONG = + GetAdaptersAddresses(ULONG(AF_UNSPEC), 0, nil, pBuffer.baseAddress, + &ulSize) + guard ulResult == ERROR_SUCCESS else { + throw IOError(windows: ulResult, reason: "GetAdaptersAddresses") + } + + var pAdapter: UnsafeMutablePointer? = + UnsafeMutablePointer(pBuffer.baseAddress) + while pAdapter != nil { + let pUnicastAddresses: UnsafeMutablePointer? = + pAdapter!.pointee.FirstUnicastAddress + var pUnicastAddress: UnsafeMutablePointer? = + pUnicastAddresses + while pUnicastAddress != nil { + if let device = NIONetworkDevice(pAdapter!, pUnicastAddress!) { + devices.append(device) + } + pUnicastAddress = pUnicastAddress!.pointee.Next + } + pAdapter = pAdapter!.pointee.Next + } +#else + var interface: UnsafeMutablePointer? = nil + try SystemCalls.getifaddrs(&interface) + let originalInterface = interface + defer { + freeifaddrs(originalInterface) + } + + while let concreteInterface = interface { + if let nioInterface = NIONetworkDevice(concreteInterface.pointee) { + devices.append(nioInterface) + } + interface = concreteInterface.pointee.ifa_next + } + +#endif + return devices + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/Sources/NIOEmbedded/Embedded.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/Sources/NIOEmbedded/Embedded.swift new file mode 100644 index 00000000..e0f6cac9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOEmbedded/Sources/NIOEmbedded/Embedded.swift @@ -0,0 +1,763 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch +import _NIODataStructures +import NIOCore + + +private struct EmbeddedScheduledTask { + let id: UInt64 + let task: () -> Void + let failFn: (Error) -> () + let readyTime: NIODeadline + let insertOrder: UInt64 + + init(id: UInt64, readyTime: NIODeadline, insertOrder: UInt64, task: @escaping () -> Void, _ failFn: @escaping (Error) -> ()) { + self.id = id + self.readyTime = readyTime + self.insertOrder = insertOrder + self.task = task + self.failFn = failFn + } + + func fail(_ error: Error) { + self.failFn(error) + } +} + +extension EmbeddedScheduledTask: Comparable { + static func < (lhs: EmbeddedScheduledTask, rhs: EmbeddedScheduledTask) -> Bool { + if lhs.readyTime == rhs.readyTime { + return lhs.insertOrder < rhs.insertOrder + } else { + return lhs.readyTime < rhs.readyTime + } + } + + static func == (lhs: EmbeddedScheduledTask, rhs: EmbeddedScheduledTask) -> Bool { + return lhs.id == rhs.id + } +} + +/// An `EventLoop` that is embedded in the current running context with no external +/// control. +/// +/// Unlike more complex `EventLoop`s, such as `SelectableEventLoop`, the `EmbeddedEventLoop` +/// has no proper eventing mechanism. Instead, reads and writes are fully controlled by the +/// entity that instantiates the `EmbeddedEventLoop`. This property makes `EmbeddedEventLoop` +/// of limited use for many application purposes, but highly valuable for testing and other +/// kinds of mocking. +/// +/// Time is controllable on an `EmbeddedEventLoop`. It begins at `NIODeadline.uptimeNanoseconds(0)` +/// and may be advanced by a fixed amount by using `advanceTime(by:)`, or advanced to a point in +/// time with `advanceTime(to:)`. +/// +/// - warning: Unlike `SelectableEventLoop`, `EmbeddedEventLoop` **is not thread-safe**. This +/// is because it is intended to be run in the thread that instantiated it. Users are +/// responsible for ensuring they never call into the `EmbeddedEventLoop` in an +/// unsynchronized fashion. +public final class EmbeddedEventLoop: EventLoop { + /// The current "time" for this event loop. This is an amount in nanoseconds. + /* private but tests */ internal var _now: NIODeadline = .uptimeNanoseconds(0) + + private var scheduledTaskCounter: UInt64 = 0 + private var scheduledTasks = PriorityQueue() + + /// Keep track of where promises are allocated to ensure we can identify their source if they leak. + private var _promiseCreationStore: [_NIOEventLoopFutureIdentifier: (file: StaticString, line: UInt)] = [:] + + // The number of the next task to be created. We track the order so that when we execute tasks + // scheduled at the same time, we may do so in the order in which they were submitted for + // execution. + private var taskNumber: UInt64 = 0 + + private func nextTaskNumber() -> UInt64 { + defer { + self.taskNumber += 1 + } + return self.taskNumber + } + + /// - see: `EventLoop.inEventLoop` + public var inEventLoop: Bool { + return true + } + + /// Initialize a new `EmbeddedEventLoop`. + public init() { } + + /// - see: `EventLoop.scheduleTask(deadline:_:)` + @discardableResult + public func scheduleTask(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled { + let promise: EventLoopPromise = makePromise() + self.scheduledTaskCounter += 1 + let task = EmbeddedScheduledTask(id: self.scheduledTaskCounter, readyTime: deadline, insertOrder: self.nextTaskNumber(), task: { + do { + promise.succeed(try task()) + } catch let err { + promise.fail(err) + } + }, promise.fail) + + let taskId = task.id + let scheduled = Scheduled(promise: promise, cancellationTask: { + self.scheduledTasks.removeFirst { $0.id == taskId } + }) + scheduledTasks.push(task) + return scheduled + } + + /// - see: `EventLoop.scheduleTask(in:_:)` + @discardableResult + public func scheduleTask(in: TimeAmount, _ task: @escaping () throws -> T) -> Scheduled { + return scheduleTask(deadline: self._now + `in`, task) + } + + /// On an `EmbeddedEventLoop`, `execute` will simply use `scheduleTask` with a deadline of _now_. This means that + /// `task` will be run the next time you call `EmbeddedEventLoop.run`. + public func execute(_ task: @escaping () -> Void) { + self.scheduleTask(deadline: self._now, task) + } + + /// Run all tasks that have previously been submitted to this `EmbeddedEventLoop`, either by calling `execute` or + /// events that have been enqueued using `scheduleTask`/`scheduleRepeatedTask`/`scheduleRepeatedAsyncTask` and whose + /// deadlines have expired. + /// + /// - seealso: `EmbeddedEventLoop.advanceTime`. + public func run() { + // Execute all tasks that are currently enqueued to be executed *now*. + self.advanceTime(to: self._now) + } + + /// Runs the event loop and moves "time" forward by the given amount, running any scheduled + /// tasks that need to be run. + public func advanceTime(by increment: TimeAmount) { + self.advanceTime(to: self._now + increment) + } + + /// Runs the event loop and moves "time" forward to the given point in time, running any scheduled + /// tasks that need to be run. + /// + /// - Note: If `deadline` is before the current time, the current time will not be advanced. + public func advanceTime(to deadline: NIODeadline) { + let newTime = max(deadline, self._now) + + while let nextTask = self.scheduledTasks.peek() { + guard nextTask.readyTime <= newTime else { + break + } + + // Now we want to grab all tasks that are ready to execute at the same + // time as the first. + var tasks = Array() + while let candidateTask = self.scheduledTasks.peek(), candidateTask.readyTime == nextTask.readyTime { + tasks.append(candidateTask) + self.scheduledTasks.pop() + } + + // Set the time correctly before we call into user code, then + // call in for all tasks. + self._now = nextTask.readyTime + + for task in tasks { + task.task() + } + } + + // Finally ensure we got the time right. + self._now = newTime + } + + internal func drainScheduledTasksByRunningAllCurrentlyScheduledTasks() { + var currentlyScheduledTasks = self.scheduledTasks + while let nextTask = currentlyScheduledTasks.pop() { + self._now = nextTask.readyTime + nextTask.task() + } + // Just fail all the remaining scheduled tasks. Despite having run all the tasks that were + // scheduled when we entered the method this may still contain tasks as running the tasks + // may have enqueued more tasks. + while let task = self.scheduledTasks.pop() { + task.fail(EventLoopError.shutdown) + } + } + + /// - see: `EventLoop.close` + func close() throws { + // Nothing to do here + } + + /// - see: `EventLoop.shutdownGracefully` + public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) { + run() + queue.sync { + callback(nil) + } + } + + public func _preconditionSafeToWait(file: StaticString, line: UInt) { + // EmbeddedEventLoop always allows a wait, as waiting will essentially always block + // wait() + return + } + + public func _promiseCreated(futureIdentifier: _NIOEventLoopFutureIdentifier, file: StaticString, line: UInt) { + precondition(_isDebugAssertConfiguration()) + self._promiseCreationStore[futureIdentifier] = (file: file, line: line) + } + + public func _promiseCompleted(futureIdentifier: _NIOEventLoopFutureIdentifier) -> (file: StaticString, line: UInt)? { + precondition(_isDebugAssertConfiguration()) + return self._promiseCreationStore.removeValue(forKey: futureIdentifier) + } + + public func _preconditionSafeToSyncShutdown(file: StaticString, line: UInt) { + // EmbeddedEventLoop always allows a sync shutdown. + return + } + + deinit { + precondition(scheduledTasks.isEmpty, "Embedded event loop freed with unexecuted scheduled tasks!") + } +} + +@usableFromInline +class EmbeddedChannelCore: ChannelCore { + var isOpen: Bool = true + var isActive: Bool = false + + var eventLoop: EventLoop + var closePromise: EventLoopPromise + var error: Optional + + private let pipeline: ChannelPipeline + + init(pipeline: ChannelPipeline, eventLoop: EventLoop) { + closePromise = eventLoop.makePromise() + self.pipeline = pipeline + self.eventLoop = eventLoop + self.error = nil + } + + deinit { + assert(!self.isOpen && !self.isActive, + "leaked an open EmbeddedChannel, maybe forgot to call channel.finish()?") + isOpen = false + closePromise.succeed(()) + } + + /// Contains the flushed items that went into the `Channel` (and on a regular channel would have hit the network). + @usableFromInline + var outboundBuffer: CircularBuffer = CircularBuffer() + + /// Contains the unflushed items that went into the `Channel` + @usableFromInline + var pendingOutboundBuffer: MarkedCircularBuffer<(NIOAny, EventLoopPromise?)> = MarkedCircularBuffer(initialCapacity: 16) + + /// Contains the items that travelled the `ChannelPipeline` all the way and hit the tail channel handler. On a + /// regular `Channel` these items would be lost. + @usableFromInline + var inboundBuffer: CircularBuffer = CircularBuffer() + + @usableFromInline + func localAddress0() throws -> SocketAddress { + throw ChannelError.operationUnsupported + } + + @usableFromInline + func remoteAddress0() throws -> SocketAddress { + throw ChannelError.operationUnsupported + } + + @usableFromInline + func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + guard self.isOpen else { + promise?.fail(ChannelError.alreadyClosed) + return + } + isOpen = false + isActive = false + promise?.succeed(()) + + // As we called register() in the constructor of EmbeddedChannel we also need to ensure we call unregistered here. + self.pipeline.syncOperations.fireChannelInactive() + self.pipeline.syncOperations.fireChannelUnregistered() + + eventLoop.execute { + // ensure this is executed in a delayed fashion as the users code may still traverse the pipeline + self.removeHandlers(pipeline: self.pipeline) + self.closePromise.succeed(()) + } + } + + @usableFromInline + func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + promise?.succeed(()) + } + + @usableFromInline + func connect0(to address: SocketAddress, promise: EventLoopPromise?) { + isActive = true + promise?.succeed(()) + self.pipeline.syncOperations.fireChannelActive() + } + + @usableFromInline + func register0(promise: EventLoopPromise?) { + promise?.succeed(()) + self.pipeline.syncOperations.fireChannelRegistered() + } + + @usableFromInline + func registerAlreadyConfigured0(promise: EventLoopPromise?) { + isActive = true + register0(promise: promise) + self.pipeline.syncOperations.fireChannelActive() + } + + @usableFromInline + func write0(_ data: NIOAny, promise: EventLoopPromise?) { + self.pendingOutboundBuffer.append((data, promise)) + } + + @usableFromInline + func flush0() { + self.pendingOutboundBuffer.mark() + + while self.pendingOutboundBuffer.hasMark, let dataAndPromise = self.pendingOutboundBuffer.popFirst() { + self.addToBuffer(buffer: &self.outboundBuffer, data: dataAndPromise.0) + dataAndPromise.1?.succeed(()) + } + } + + @usableFromInline + func read0() { + // NOOP + } + + public final func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + @usableFromInline + func channelRead0(_ data: NIOAny) { + addToBuffer(buffer: &inboundBuffer, data: data) + } + + public func errorCaught0(error: Error) { + if self.error == nil { + self.error = error + } + } + + private func addToBuffer(buffer: inout CircularBuffer, data: T) { + buffer.append(data) + } +} + +/// `EmbeddedChannel` is a `Channel` implementation that does neither any +/// actual IO nor has a proper eventing mechanism. The prime use-case for +/// `EmbeddedChannel` is in unit tests when you want to feed the inbound events +/// and check the outbound events manually. +/// +/// Please remember to call `finish()` when you are no longer using this +/// `EmbeddedChannel`. +/// +/// To feed events through an `EmbeddedChannel`'s `ChannelPipeline` use +/// `EmbeddedChannel.writeInbound` which accepts data of any type. It will then +/// forward that data through the `ChannelPipeline` and the subsequent +/// `ChannelInboundHandler` will receive it through the usual `channelRead` +/// event. The user is responsible for making sure the first +/// `ChannelInboundHandler` expects data of that type. +/// +/// `EmbeddedChannel` automatically collects arriving outbound data and makes it +/// available one-by-one through `readOutbound`. +/// +/// - note: `EmbeddedChannel` is currently only compatible with +/// `EmbeddedEventLoop`s and cannot be used with `SelectableEventLoop`s from +/// for example `MultiThreadedEventLoopGroup`. +/// - warning: Unlike other `Channel`s, `EmbeddedChannel` **is not thread-safe**. This +/// is because it is intended to be run in the thread that instantiated it. Users are +/// responsible for ensuring they never call into an `EmbeddedChannel` in an +/// unsynchronized fashion. `EmbeddedEventLoop`s notes also apply as +/// `EmbeddedChannel` uses an `EmbeddedEventLoop` as its `EventLoop`. +public final class EmbeddedChannel: Channel { + /// `LeftOverState` represents any left-over inbound, outbound, and pending outbound events that hit the + /// `EmbeddedChannel` and were not consumed when `finish` was called on the `EmbeddedChannel`. + /// + /// `EmbeddedChannel` is most useful in testing and usually in unit tests, you want to consume all inbound and + /// outbound data to verify they are what you expect. Therefore, when you `finish` an `EmbeddedChannel` it will + /// return if it's either `.clean` (no left overs) or that it has `.leftOvers`. + public enum LeftOverState { + /// The `EmbeddedChannel` is clean, ie. no inbound, outbound, or pending outbound data left on `finish`. + case clean + + /// The `EmbeddedChannel` has inbound, outbound, or pending outbound data left on `finish`. + case leftOvers(inbound: [NIOAny], outbound: [NIOAny], pendingOutbound: [NIOAny]) + + /// `true` if the `EmbeddedChannel` was `clean` on `finish`, ie. there is no unconsumed inbound, outbound, or + /// pending outbound data left on the `Channel`. + public var isClean: Bool { + if case .clean = self { + return true + } else { + return false + } + } + + /// `true` if the `EmbeddedChannel` if there was unconsumed inbound, outbound, or pending outbound data left + /// on the `Channel` when it was `finish`ed. + public var hasLeftOvers: Bool { + return !self.isClean + } + } + + /// `BufferState` represents the state of either the inbound, or the outbound `EmbeddedChannel` buffer. These + /// buffers contain data that travelled the `ChannelPipeline` all the way. + /// + /// If the last `ChannelHandler` explicitly (by calling `fireChannelRead`) or implicitly (by not implementing + /// `channelRead`) sends inbound data into the end of the `EmbeddedChannel`, it will be held in the + /// `EmbeddedChannel`'s inbound buffer. Similarly for `write` on the outbound side. The state of the respective + /// buffer will be returned from `writeInbound`/`writeOutbound` as a `BufferState`. + public enum BufferState { + /// The buffer is empty. + case empty + + /// The buffer is non-empty. + case full([NIOAny]) + + /// Returns `true` is the buffer was empty. + public var isEmpty: Bool { + if case .empty = self { + return true + } else { + return false + } + } + + /// Returns `true` if the buffer was non-empty. + public var isFull: Bool { + return !self.isEmpty + } + } + + /// `WrongTypeError` is throws if you use `readInbound` or `readOutbound` and request a certain type but the first + /// item in the respective buffer is of a different type. + public struct WrongTypeError: Error, Equatable { + /// The type you expected. + public let expected: Any.Type + + /// The type of the actual first element. + public let actual: Any.Type + + public init(expected: Any.Type, actual: Any.Type) { + self.expected = expected + self.actual = actual + } + + public static func == (lhs: WrongTypeError, rhs: WrongTypeError) -> Bool { + return lhs.expected == rhs.expected && lhs.actual == rhs.actual + } + } + + /// Returns `true` if the `EmbeddedChannel` is 'active'. + /// + /// An active `EmbeddedChannel` can be closed by calling `close` or `finish` on the `EmbeddedChannel`. + /// + /// - note: An `EmbeddedChannel` starts _inactive_ and can be activated, for example by calling `connect`. + public var isActive: Bool { return channelcore.isActive } + + /// - see: `Channel.closeFuture` + public var closeFuture: EventLoopFuture { return channelcore.closePromise.futureResult } + + @usableFromInline + /*private but usableFromInline */ lazy var channelcore: EmbeddedChannelCore = EmbeddedChannelCore(pipeline: self._pipeline, eventLoop: self.eventLoop) + + /// - see: `Channel._channelCore` + public var _channelCore: ChannelCore { + return channelcore + } + + /// - see: `Channel.pipeline` + public var pipeline: ChannelPipeline { + return _pipeline + } + + /// - see: `Channel.isWritable` + public var isWritable: Bool = true + + /// Synchronously closes the `EmbeddedChannel`. + /// + /// Errors in the `EmbeddedChannel` can be consumed using `throwIfErrorCaught`. + /// + /// - parameters: + /// - acceptAlreadyClosed: Whether `finish` should throw if the `EmbeddedChannel` has been previously `close`d. + /// - returns: The `LeftOverState` of the `EmbeddedChannel`. If all the inbound and outbound events have been + /// consumed (using `readInbound` / `readOutbound`) and there are no pending outbound events (unflushed + /// writes) this will be `.clean`. If there are any unconsumed inbound, outbound, or pending outbound + /// events, the `EmbeddedChannel` will returns those as `.leftOvers(inbound:outbound:pendingOutbound:)`. + public func finish(acceptAlreadyClosed: Bool) throws -> LeftOverState { + do { + try close().wait() + } catch let error as ChannelError { + guard error == .alreadyClosed && acceptAlreadyClosed else { + throw error + } + } + self.embeddedEventLoop.drainScheduledTasksByRunningAllCurrentlyScheduledTasks() + self.embeddedEventLoop.run() + try throwIfErrorCaught() + let c = self.channelcore + if c.outboundBuffer.isEmpty && c.inboundBuffer.isEmpty && c.pendingOutboundBuffer.isEmpty { + return .clean + } else { + return .leftOvers(inbound: Array(c.inboundBuffer), + outbound: Array(c.outboundBuffer), + pendingOutbound: c.pendingOutboundBuffer.map { $0.0 }) + } + } + + /// Synchronously closes the `EmbeddedChannel`. + /// + /// This method will throw if the `Channel` hit any unconsumed errors or if the `close` fails. Errors in the + /// `EmbeddedChannel` can be consumed using `throwIfErrorCaught`. + /// + /// - returns: The `LeftOverState` of the `EmbeddedChannel`. If all the inbound and outbound events have been + /// consumed (using `readInbound` / `readOutbound`) and there are no pending outbound events (unflushed + /// writes) this will be `.clean`. If there are any unconsumed inbound, outbound, or pending outbound + /// events, the `EmbeddedChannel` will returns those as `.leftOvers(inbound:outbound:pendingOutbound:)`. + public func finish() throws -> LeftOverState { + return try self.finish(acceptAlreadyClosed: false) + } + + private var _pipeline: ChannelPipeline! + + /// - see: `Channel.allocator` + public var allocator: ByteBufferAllocator = ByteBufferAllocator() + + /// - see: `Channel.eventLoop` + public var eventLoop: EventLoop { + return self.embeddedEventLoop + } + + /// Returns the `EmbeddedEventLoop` that this `EmbeddedChannel` uses. This will return the same instance as + /// `EmbeddedChannel.eventLoop` but as the concrete `EmbeddedEventLoop` rather than as `EventLoop` existential. + public var embeddedEventLoop: EmbeddedEventLoop = EmbeddedEventLoop() + + /// - see: `Channel.localAddress` + public var localAddress: SocketAddress? = nil + + /// - see: `Channel.remoteAddress` + public var remoteAddress: SocketAddress? = nil + + /// `nil` because `EmbeddedChannel`s don't have parents. + public let parent: Channel? = nil + + /// If available, this method reads one element of type `T` out of the `EmbeddedChannel`'s outbound buffer. If the + /// first element was of a different type than requested, `EmbeddedChannel.WrongTypeError` will be thrown, if there + /// are no elements in the outbound buffer, `nil` will be returned. + /// + /// Data hits the `EmbeddedChannel`'s outbound buffer when data was written using `write`, then `flush`ed, and + /// then travelled the `ChannelPipeline` all the way too the front. For data to hit the outbound buffer, the very + /// first `ChannelHandler` must have written and flushed it either explicitly (by calling + /// `ChannelHandlerContext.write` and `flush`) or implicitly by not implementing `write`/`flush`. + /// + /// - note: Outbound events travel the `ChannelPipeline` _back to front_. + /// - note: `EmbeddedChannel.writeOutbound` will `write` data through the `ChannelPipeline`, starting with last + /// `ChannelHandler`. + @inlinable + public func readOutbound(as type: T.Type = T.self) throws -> T? { + return try _readFromBuffer(buffer: &channelcore.outboundBuffer) + } + + /// If available, this method reads one element of type `T` out of the `EmbeddedChannel`'s inbound buffer. If the + /// first element was of a different type than requested, `EmbeddedChannel.WrongTypeError` will be thrown, if there + /// are no elements in the outbound buffer, `nil` will be returned. + /// + /// Data hits the `EmbeddedChannel`'s inbound buffer when data was send through the pipeline using `fireChannelRead` + /// and then travelled the `ChannelPipeline` all the way too the back. For data to hit the inbound buffer, the + /// last `ChannelHandler` must have send the event either explicitly (by calling + /// `ChannelHandlerContext.fireChannelRead`) or implicitly by not implementing `channelRead`. + /// + /// - note: `EmbeddedChannel.writeInbound` will fire data through the `ChannelPipeline` using `fireChannelRead`. + @inlinable + public func readInbound(as type: T.Type = T.self) throws -> T? { + return try _readFromBuffer(buffer: &channelcore.inboundBuffer) + } + + /// Sends an inbound `channelRead` event followed by a `channelReadComplete` event through the `ChannelPipeline`. + /// + /// The immediate effect being that the first `ChannelInboundHandler` will get its `channelRead` method called + /// with the data you provide. + /// + /// - parameters: + /// - data: The data to fire through the pipeline. + /// - returns: The state of the inbound buffer which contains all the events that travelled the `ChannelPipeline` + // all the way. + @inlinable + @discardableResult public func writeInbound(_ data: T) throws -> BufferState { + pipeline.fireChannelRead(NIOAny(data)) + pipeline.fireChannelReadComplete() + try throwIfErrorCaught() + return self.channelcore.inboundBuffer.isEmpty ? .empty : .full(Array(self.channelcore.inboundBuffer)) + } + + /// Sends an outbound `writeAndFlush` event through the `ChannelPipeline`. + /// + /// The immediate effect being that the first `ChannelOutboundHandler` will get its `write` method called + /// with the data you provide. Note that the first `ChannelOutboundHandler` in the pipeline is the _last_ handler + /// because outbound events travel the pipeline from back to front. + /// + /// - parameters: + /// - data: The data to fire through the pipeline. + /// - returns: The state of the outbound buffer which contains all the events that travelled the `ChannelPipeline` + // all the way. + @inlinable + @discardableResult public func writeOutbound(_ data: T) throws -> BufferState { + try writeAndFlush(NIOAny(data)).wait() + return self.channelcore.outboundBuffer.isEmpty ? .empty : .full(Array(self.channelcore.outboundBuffer)) + } + + /// This method will throw the error that is stored in the `EmbeddedChannel` if any. + /// + /// The `EmbeddedChannel` will store an error some error travels the `ChannelPipeline` all the way past its end. + public func throwIfErrorCaught() throws { + if let error = channelcore.error { + channelcore.error = nil + throw error + } + } + + @inlinable + func _readFromBuffer(buffer: inout CircularBuffer) throws -> T? { + if buffer.isEmpty { + return nil + } + let elem = buffer.removeFirst() + guard let t = self._channelCore.tryUnwrapData(elem, as: T.self) else { + throw WrongTypeError(expected: T.self, actual: type(of: self._channelCore.tryUnwrapData(elem, as: Any.self)!)) + } + return t + } + + /// Create a new instance. + /// + /// During creation it will automatically also register itself on the `EmbeddedEventLoop`. + /// + /// - parameters: + /// - handler: The `ChannelHandler` to add to the `ChannelPipeline` before register or `nil` if none should be added. + /// - loop: The `EmbeddedEventLoop` to use. + public convenience init(handler: ChannelHandler? = nil, loop: EmbeddedEventLoop = EmbeddedEventLoop()) { + let handlers = handler.map { [$0] } ?? [] + self.init(handlers: handlers, loop: loop) + } + + /// Create a new instance. + /// + /// During creation it will automatically also register itself on the `EmbeddedEventLoop`. + /// + /// - parameters: + /// - handlers: The `ChannelHandler`s to add to the `ChannelPipeline` before register. + /// - loop: The `EmbeddedEventLoop` to use. + public init(handlers: [ChannelHandler], loop: EmbeddedEventLoop = EmbeddedEventLoop()) { + self.embeddedEventLoop = loop + self._pipeline = ChannelPipeline(channel: self) + + try! self._pipeline.syncOperations.addHandlers(handlers) + + // This will never throw... + try! register().wait() + } + + /// - see: `Channel.setOption` + @inlinable + public func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + self.setOptionSync(option, value: value) + return self.eventLoop.makeSucceededVoidFuture() + } + + @inlinable + internal func setOptionSync(_ option: Option, value: Option.Value) { + // No options supported + fatalError("no options supported") + } + + /// - see: `Channel.getOption` + @inlinable + public func getOption(_ option: Option) -> EventLoopFuture { + return self.eventLoop.makeSucceededFuture(self.getOptionSync(option)) + } + + @inlinable + internal func getOptionSync(_ option: Option) -> Option.Value { + if option is ChannelOptions.Types.AutoReadOption { + return true as! Option.Value + } + fatalError("option \(option) not supported") + } + + /// Fires the (outbound) `bind` event through the `ChannelPipeline`. If the event hits the `EmbeddedChannel` which + /// happens when it travels the `ChannelPipeline` all the way to the front, this will also set the + /// `EmbeddedChannel`'s `localAddress`. + /// + /// - parameters: + /// - address: The address to fake-bind to. + /// - promise: The `EventLoopPromise` which will be fulfilled when the fake-bind operation has been done. + public func bind(to address: SocketAddress, promise: EventLoopPromise?) { + promise?.futureResult.whenSuccess { + self.localAddress = address + } + pipeline.bind(to: address, promise: promise) + } + + /// Fires the (outbound) `connect` event through the `ChannelPipeline`. If the event hits the `EmbeddedChannel` + /// which happens when it travels the `ChannelPipeline` all the way to the front, this will also set the + /// `EmbeddedChannel`'s `remoteAddress`. + /// + /// - parameters: + /// - address: The address to fake-bind to. + /// - promise: The `EventLoopPromise` which will be fulfilled when the fake-bind operation has been done. + public func connect(to address: SocketAddress, promise: EventLoopPromise?) { + promise?.futureResult.whenSuccess { + self.remoteAddress = address + } + pipeline.connect(to: address, promise: promise) + } +} + +extension EmbeddedChannel { + public struct SynchronousOptions: NIOSynchronousChannelOptions { + @usableFromInline + internal let channel: EmbeddedChannel + + fileprivate init(channel: EmbeddedChannel) { + self.channel = channel + } + + @inlinable + public func setOption(_ option: Option, value: Option.Value) throws { + self.channel.setOptionSync(option, value: value) + } + + @inlinable + public func getOption(_ option: Option) throws -> Option.Value { + return self.channel.getOptionSync(option) + } + } + + public final var syncOptions: NIOSynchronousChannelOptions? { + return SynchronousOptions(channel: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/README.md new file mode 100644 index 00000000..13a17b9b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/README.md @@ -0,0 +1,44 @@ +# NIOExtras + +NIOExtras is a good place for code that is related to NIO but not core. It can also be used to incubate APIs for tasks that are possible with core-NIO but are cumbersome today. + +What makes a good contribution to NIOExtras? + +- a protocol encoder/decoder pair (also called "codec") that is often used but is small enough so it doesn't need its own repository +- a helper to achieve a task that is harder-than-necessary to achieve with core-NIO + +## Code Quality / Stability + +All code will go through code review like in the other repositories related to the SwiftNIO project. + +`swift-nio-extras` part of the SwiftNIO 2 family of repositories and depends on the following: + +- [`swift-nio`](https://github.com/apple/swift-nio), version 2.30.0 or better. +- Swift 5.4. +- `zlib` and its development headers installed on the system. But don't worry, you'll find `zlib` on pretty much any UNIX system that can compile any sort of code. + +To depend on `swift-nio-extras`, put the following in the `dependencies` of your `Package.swift`: + +```swift +.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.0.0"), +``` + +### Support for older Swift versions + +Earlier versions of SwiftNIO (2.39.x and lower) and SwiftNIOExtras (1.10.x and lower) supported Swift 5.2 and 5.3, SwiftNIO (2.29.x and lower) and SwiftNIOExtras (1.9.x and lower) supported Swift 5.0 and 5.1. + +On the [`nio-extras-0.1`](https://github.com/apple/swift-nio-extras/tree/nio-extras-0.1) branch, you can find the `swift-nio-extras` version for the SwiftNIO 1 family. It requires Swift 4.1 or better. + +## Current Contents + +- [`QuiescingHelper`](Sources/NIOExtras/QuiescingHelper.swift): Helps to quiesce + a server by notifying user code when all previously open connections have closed. +- [`LineBasedFrameDecoder`](Sources/NIOExtras/LineBasedFrameDecoder.swift) Splits incoming `ByteBuffer`s on line endings. +- [`FixedLengthFrameDecoder`](Sources/NIOExtras/FixedLengthFrameDecoder.swift) Splits incoming `ByteBuffer`s by a fixed number of bytes. +- [`LengthFieldBasedFrameDecoder`](Sources/NIOExtras/LengthFieldBasedFrameDecoder.swift) Splits incoming `ByteBuffer`s by a number of bytes specified in a fixed length header contained within the buffer. +- [`LengthFieldPrepender`](Sources/NIOExtras/LengthFieldPrepender.swift) Prepends the number of bytes to outgoing `ByteBuffer`s as a fixed length header. Can be used in a codec pair with the `LengthFieldBasedFrameDecoder`. +- [`RequestResponseHandler`](Sources/NIOExtras/RequestResponseHandler.swift) Matches a request and a promise with the corresponding response. +- [`HTTPResponseCompressor`](Sources/NIOHTTPCompression/HTTPResponseCompressor.swift) Compresses the body of every HTTP/1 response message. +- [`DebugInboundsEventHandler`](Sources/NIOExtras/DebugInboundEventsHandler.swift) Prints out all inbound events that travel through the `ChannelPipeline`. +- [`DebugOutboundsEventHandler`](Sources/NIOExtras/DebugOutboundEventsHandler.swift) Prints out all outbound events that travel through the `ChannelPipeline`. +- [`WritePCAPHandler`](Sources/NIOExtras/WritePCAPHandler.swift) A `ChannelHandler` that writes `.pcap` containing the traffic of the `ChannelPipeline` that you can inspect with Wireshark/tcpdump. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugInboundEventsHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugInboundEventsHandler.swift new file mode 100644 index 00000000..eb53d243 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugInboundEventsHandler.swift @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(macOS) || os(tvOS) || os(iOS) || os(watchOS) +import Darwin +#else +import Glibc +#endif + +import NIOCore + +/// ChannelInboundHandler that prints all inbound events that pass through the pipeline by default, +/// overridable by providing your own closure for custom logging. See DebugOutboundEventsHandler for outbound events. +public class DebugInboundEventsHandler: ChannelInboundHandler { + + public typealias InboundIn = Any + public typealias InboudOut = Any + + public enum Event { + case registered + case unregistered + case active + case inactive + case read(data: NIOAny) + case readComplete + case writabilityChanged(isWritable: Bool) + case userInboundEventTriggered(event: Any) + case errorCaught(Error) + } + + var logger: (Event, ChannelHandlerContext) -> () + + public init(logger: @escaping (Event, ChannelHandlerContext) -> () = DebugInboundEventsHandler.defaultPrint) { + self.logger = logger + } + + public func channelRegistered(context: ChannelHandlerContext) { + logger(.registered, context) + context.fireChannelRegistered() + } + + public func channelUnregistered(context: ChannelHandlerContext) { + logger(.unregistered, context) + context.fireChannelUnregistered() + } + + public func channelActive(context: ChannelHandlerContext) { + logger(.active, context) + context.fireChannelActive() + } + + public func channelInactive(context: ChannelHandlerContext) { + logger(.inactive, context) + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + logger(.read(data: data), context) + context.fireChannelRead(data) + } + + public func channelReadComplete(context: ChannelHandlerContext) { + logger(.readComplete, context) + context.fireChannelReadComplete() + } + + public func channelWritabilityChanged(context: ChannelHandlerContext) { + logger(.writabilityChanged(isWritable: context.channel.isWritable), context) + context.fireChannelWritabilityChanged() + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + logger(.userInboundEventTriggered(event: event), context) + context.fireUserInboundEventTriggered(event) + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + logger(.errorCaught(error), context) + context.fireErrorCaught(error) + } + + public static func defaultPrint(event: Event, in context: ChannelHandlerContext) { + let message: String + switch event { + case .registered: + message = "Channel registered" + case .unregistered: + message = "Channel unregistered" + case .active: + message = "Channel became active" + case .inactive: + message = "Channel became inactive" + case .read(let data): + message = "Channel read \(data)" + case .readComplete: + message = "Channel completed reading" + case .writabilityChanged(let isWritable): + message = "Channel writability changed to \(isWritable)" + case .userInboundEventTriggered(let event): + message = "Channel user inbound event \(event) triggered" + case .errorCaught(let error): + message = "Channel caught error: \(error)" + } + print(message + " in \(context.name)") + fflush(stdout) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugOutboundEventsHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugOutboundEventsHandler.swift new file mode 100644 index 00000000..43d83a81 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/DebugOutboundEventsHandler.swift @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(macOS) || os(tvOS) || os(iOS) || os(watchOS) +import Darwin +#else +import Glibc +#endif + +import NIOCore + +/// ChannelOutboundHandler that prints all outbound events that pass through the pipeline by default, +/// overridable by providing your own closure for custom logging. See DebugInboundEventsHandler for inbound events. +public class DebugOutboundEventsHandler: ChannelOutboundHandler { + + public typealias OutboundIn = Any + public typealias OutboundOut = Any + + public enum Event { + case register + case bind(address: SocketAddress) + case connect(address: SocketAddress) + case write(data: NIOAny) + case flush + case read + case close(mode: CloseMode) + case triggerUserOutboundEvent(event: Any) + } + + var logger: (Event, ChannelHandlerContext) -> () + + public init(logger: @escaping (Event, ChannelHandlerContext) -> () = DebugOutboundEventsHandler.defaultPrint) { + self.logger = logger + } + + public func register(context: ChannelHandlerContext, promise: EventLoopPromise?) { + logger(.register, context) + context.register(promise: promise) + } + + public func bind(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + logger(.bind(address: address), context) + context.bind(to: address, promise: promise) + } + + public func connect(context: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise?) { + logger(.connect(address: address), context) + context.connect(to: address, promise: promise) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + logger(.write(data: data), context) + context.write(data, promise: promise) + } + + public func flush(context: ChannelHandlerContext) { + logger(.flush, context) + context.flush() + } + + public func read(context: ChannelHandlerContext) { + logger(.read, context) + context.read() + } + + public func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + logger(.close(mode: mode), context) + context.close(mode: mode, promise: promise) + } + + public func triggerUserOutboundEvent(context: ChannelHandlerContext, event: Any, promise: EventLoopPromise?) { + logger(.triggerUserOutboundEvent(event: event), context) + context.triggerUserOutboundEvent(event, promise: promise) + } + + public static func defaultPrint(event: Event, in context: ChannelHandlerContext) { + let message: String + switch event { + case .register: + message = "Registering channel" + case .bind(let address): + message = "Binding to \(address)" + case .connect(let address): + message = "Connecting to \(address)" + case .write(let data): + message = "Writing \(data)" + case .flush: + message = "Flushing" + case .read: + message = "Reading" + case .close(let mode): + message = "Closing with mode \(mode)" + print() + case .triggerUserOutboundEvent(let event): + message = "Triggering user outbound event: { \(event) }" + } + print(message + " in \(context.name)") + fflush(stdout) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/FixedLengthFrameDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/FixedLengthFrameDecoder.swift new file mode 100644 index 00000000..2929d6d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/FixedLengthFrameDecoder.swift @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +/// +/// A decoder that splits the received `ByteBuffer` by a fixed number +/// of bytes. For example, if you received the following four fragmented packets: +/// +/// +---+----+------+----+ +/// | A | BC | DEFG | HI | +/// +---+----+------+----+ +/// +/// A `FixedLengthFrameDecoder` will decode them into the +/// following three packets with the fixed length: +/// +/// +-----+-----+-----+ +/// | ABC | DEF | GHI | +/// +-----+-----+-----+ +/// +public final class FixedLengthFrameDecoder: ByteToMessageDecoder { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + + public var cumulationBuffer: ByteBuffer? + + private let frameLength: Int + + /// Create `FixedLengthFrameDecoder` with a given frame length. + /// + /// - parameters: + /// - frameLength: The length of a frame. + public init(frameLength: Int) { + self.frameLength = frameLength + } + + public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + guard let slice = buffer.readSlice(length: frameLength) else { + return .needMoreData + } + + context.fireChannelRead(self.wrapInboundOut(slice)) + return .continue + } + + public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + while case .continue = try self.decode(context: context, buffer: &buffer) {} + if buffer.readableBytes > 0 { + context.fireErrorCaught(NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer)) + } + return .needMoreData + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming+ContentLengthHeader.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming+ContentLengthHeader.swift new file mode 100644 index 00000000..7cc17005 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming+ContentLengthHeader.swift @@ -0,0 +1,195 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +extension NIOJSONRPCFraming { + /// `ContentLengthHeaderFrameEncoder` is responsible for emitting JSON-RPC wire protocol with 'Content-Length' + /// HTTP-like headers as used by for example by LSP (Language Server Protocol). + public final class ContentLengthHeaderFrameEncoder: ChannelOutboundHandler { + /// We'll get handed one message through the `Channel` and ... + public typealias OutboundIn = ByteBuffer + /// ... will encode it into a `ByteBuffer`. + public typealias OutboundOut = ByteBuffer + + private var scratchBuffer: ByteBuffer! + + public init() {} + + public func handlerAdded(context: ChannelHandlerContext) { + self.scratchBuffer = context.channel.allocator.buffer(capacity: 512) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let data = self.unwrapOutboundIn(data) + // Step 1, clear the target buffer (note, we are re-using it so if we get lucky we don't need to + // allocate at all. + self.scratchBuffer.clear() + + // Step 2, write the wire protocol for the header. + self.scratchBuffer.writeStaticString("Content-Length: ") + self.scratchBuffer.writeString(String(data.readableBytes, radix: 10)) + self.scratchBuffer.writeStaticString("\r\n\r\n") + + // Step 3, send header and the raw message through the `Channel`. + if data.readableBytes > 0 { + context.write(self.wrapOutboundOut(self.scratchBuffer), promise: nil) + context.write(self.wrapOutboundOut(data), promise: promise) + } else { + context.write(self.wrapOutboundOut(self.scratchBuffer), promise: promise) + } + } + } + + /// `ContentLengthHeaderFrameDecoder` is responsible for parsing JSON-RPC wire protocol with 'Content-Length' + /// HTTP-like headers as used by for example by LSP (Language Server Protocol). + public struct ContentLengthHeaderFrameDecoder: ByteToMessageDecoder { + /// We're emitting one `ByteBuffer` corresponding exactly to one full payload, no headers etc. + public typealias InboundOut = ByteBuffer + + /// `ContentLengthHeaderFrameDecoder` is a simple state machine. + private enum State { + /// either we're waiting for the end of the header block or a new header field, ... + case waitingForHeaderNameOrHeaderBlockEnd + /// ... or for a header value, or ... + case waitingForHeaderValue(name: String) + /// ... or for the payload of a given size. + case waitingForPayload(length: Int) + } + + /// A `DecodingError` is sent through the pipeline if anything went wrong. + public enum DecodingError: Error, Equatable { + /// Missing 'Content-Length' header. + case missingContentLengthHeader + + /// The value of the 'Content-Length' header was illegal, for example a negative number. + case illegalContentLengthHeaderValue(String) + } + + public init() {} + + // We start waiting for a header field (or the end of a header block). + private var state: State = .waitingForHeaderNameOrHeaderBlockEnd + private var payloadLength: Int? = nil + + // Finishes a header block, most of the time that's very straighforward but we need to verify a few + // things here. + private mutating func processHeaderBlockEnd(context: ChannelHandlerContext) throws -> DecodingState { + if let payloadLength = self.payloadLength { + if payloadLength == 0 { + // special case, we're not actually waiting for anything if it's 0 bytes... + self.state = .waitingForHeaderNameOrHeaderBlockEnd + self.payloadLength = nil + context.fireChannelRead(self.wrapInboundOut(context.channel.allocator.buffer(capacity: 0))) + return .continue + } + // cool, let's just shift to the `.waitingForPayload` state and continue. + self.state = .waitingForPayload(length: payloadLength) + self.payloadLength = nil + return .continue + } else { + // this happens if we reached the end of the header block but we haven't seen the Content-Length + // header, that's an error. It will be sent through the `Channel` and decoder won't be called + // again. + throw DecodingError.missingContentLengthHeader + } + } + + // `decode` will be invoked whenever there is more data available (or if we return `.continue`). + public mutating func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + switch self.state { + case .waitingForHeaderNameOrHeaderBlockEnd: + // Given that we're waiting for the end of a header block or a new header field, it's sensible to + // check if this might be the end of the block. + if buffer.readableBytesView.starts(with: "\r\n".utf8) { + buffer.moveReaderIndex(forwardBy: 2) // skip \r\n\r\n + return try self.processHeaderBlockEnd(context: context) + } + + // Given that this is not the end of a header block, it must be a new header field. A new header field + // must always have a colon (or we don't have enough data). + if let colonIndex = buffer.readableBytesView.firstIndex(of: UInt8(ascii: ":")) { + let headerName = buffer.readString(length: colonIndex - buffer.readableBytesView.startIndex)! + buffer.moveReaderIndex(forwardBy: 1) // skip the colon + self.state = .waitingForHeaderValue(name: headerName.trimmed().lowercased()) + return .continue + } + + return .needMoreData + case .waitingForHeaderValue(name: let headerName): + // Cool, we're waiting for a header value (ie. we're after the colon). + + // Let's not bother unless we found the whole thing + guard let newlineIndex = buffer.readableBytesView.firstIndex(of: UInt8(ascii: "\n")) else { + return .needMoreData + } + + // Is this a header we actually care about? + if headerName == "content-length" { + // Yes, let's parse the int. + let headerValue = buffer.readString(length: newlineIndex - buffer.readableBytesView.startIndex + 1)! + if let length = UInt32(headerValue.trimmed()) { // anything more than 4GB or negative doesn't make sense + self.payloadLength = .init(length) + } else { + throw DecodingError.illegalContentLengthHeaderValue(headerValue) + } + } else { + // Nope, let's just skip over it + buffer.moveReaderIndex(forwardBy: newlineIndex - buffer.readableBytesView.startIndex + 1) + } + + // but in any case, we're now waiting for a new header or the end of the header block again. + self.state = .waitingForHeaderNameOrHeaderBlockEnd + return .continue + case .waitingForPayload(length: let length): + // That's the easiest case, let's just wait until we have enough data. + if let payload = buffer.readSlice(length: length) { + // Cool, we got enough data, let's go back waiting for a new header block. + self.state = .waitingForHeaderNameOrHeaderBlockEnd + // And send what we found through the pipeline. + context.fireChannelRead(self.wrapInboundOut(payload)) + return .continue + } else { + return .needMoreData + } + } + } + + /// Invoked when the `Channel` is being brough down. + public mutating func decodeLast(context: ChannelHandlerContext, + buffer: inout ByteBuffer, + seenEOF: Bool) throws -> DecodingState { + // Last chance to decode anything. + while try self.decode(context: context, buffer: &buffer) == .continue {} + + if buffer.readableBytes > 0 { + // Oops, there are leftovers that don't form a full message, we could ignore those but it doesn't hurt to send + // an error. + throw ByteToMessageDecoderError.leftoverDataWhenDone(buffer) + } + return .needMoreData + } + } +} + +extension String { + func trimmed() -> Substring { + guard let firstElementIndex = self.firstIndex(where: { !$0.isWhitespace }) else { + return Substring("") + } + + let lastElementIndex = self.reversed().firstIndex(where: { !$0.isWhitespace })! + return self[firstElementIndex ..< lastElementIndex.base] + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming.swift new file mode 100644 index 00000000..2ba0c114 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/JSONRPCFraming.swift @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public enum NIOJSONRPCFraming { + // just a name-space +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldBasedFrameDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldBasedFrameDecoder.swift new file mode 100644 index 00000000..81dbaad2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldBasedFrameDecoder.swift @@ -0,0 +1,236 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +extension ByteBuffer { + @inlinable + mutating func get24UInt( + at index: Int, + endianness: Endianness = .big + ) -> UInt32? { + let mostSignificant: UInt16 + let leastSignificant: UInt8 + switch endianness { + case .big: + guard let uint16 = self.getInteger(at: index, endianness: .big, as: UInt16.self), + let uint8 = self.getInteger(at: index + 2, endianness: .big, as: UInt8.self) else { return nil } + mostSignificant = uint16 + leastSignificant = uint8 + case .little: + guard let uint8 = self.getInteger(at: index, endianness: .little, as: UInt8.self), + let uint16 = self.getInteger(at: index + 1, endianness: .little, as: UInt16.self) else { return nil } + mostSignificant = uint16 + leastSignificant = uint8 + } + return (UInt32(mostSignificant) << 8) &+ UInt32(leastSignificant) + } + @inlinable + mutating func read24UInt( + endianness: Endianness = .big + ) -> UInt32? { + guard let integer = get24UInt(at: self.readerIndex, endianness: endianness) else { return nil } + self.moveReaderIndex(forwardBy: 3) + return integer + } +} + +public enum NIOLengthFieldBasedFrameDecoderError: Error { + /// This error can be thrown by `LengthFieldBasedFrameDecoder` if the length field value is larger than `Int.max` + case lengthFieldValueTooLarge + /// This error can be thrown by `LengthFieldBasedFrameDecoder` if the length field value is larger than `LengthFieldBasedFrameDecoder.maxSupportedLengthFieldSize` + case lengthFieldValueLargerThanMaxSupportedSize +} + +/// +/// A decoder that splits the received `ByteBuffer` by the number of bytes specified in a fixed length header +/// contained within the buffer. +/// For example, if you received the following four fragmented packets: +/// +---+----+------+----+ +/// | A | BC | DEFG | HI | +/// +---+----+------+----+ +/// +/// Given that the specified header length is 1 byte, +/// where the first header specifies 3 bytes while the second header specifies 4 bytes, +/// a `LengthFieldBasedFrameDecoder` will decode them into the following packets: +/// +/// +-----+------+ +/// | BCD | FGHI | +/// +-----+------+ +/// +/// 'A' and 'E' will be the headers and will not be passed forward. +/// +public final class LengthFieldBasedFrameDecoder: ByteToMessageDecoder { + /// Maximum supported length field size in bytes of `LengthFieldBasedFrameDecoder` and is currently `Int32.max` + public static let maxSupportedLengthFieldSize: Int = Int(Int32.max) + /// + /// An enumeration to describe the length of a piece of data in bytes. + /// + public enum ByteLength { + case one + case two + case four + case eight + + fileprivate var bitLength: NIOLengthFieldBitLength { + switch self { + case .one: return .oneByte + case .two: return .twoBytes + case .four: return .fourBytes + case .eight: return .eightBytes + } + } + } + + /// + /// The decoder has two distinct sections of data to read. + /// Each must be fully present before it is considered as read. + /// During the time when it is not present the decoder must wait. `DecoderReadState` details that waiting state. + /// + private enum DecoderReadState { + case waitingForHeader + case waitingForFrame(length: Int) + } + + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + + public var cumulationBuffer: ByteBuffer? + private var readState: DecoderReadState = .waitingForHeader + + private let lengthFieldLength: NIOLengthFieldBitLength + private let lengthFieldEndianness: Endianness + + /// Create `LengthFieldBasedFrameDecoder` with a given frame length. + /// + /// - parameters: + /// - lengthFieldLength: The length of the field specifying the remaining length of the frame. + /// - lengthFieldEndianness: The endianness of the field specifying the remaining length of the frame. + /// + public convenience init(lengthFieldLength: ByteLength, lengthFieldEndianness: Endianness = .big) { + self.init(lengthFieldBitLength: lengthFieldLength.bitLength, lengthFieldEndianness: lengthFieldEndianness) + } + + /// Create `LengthFieldBasedFrameDecoder` with a given frame length. + /// + /// - parameters: + /// - lengthFieldBitLength: The length of the field specifying the remaining length of the frame. + /// - lengthFieldEndianness: The endianness of the field specifying the remaining length of the frame. + /// + public init(lengthFieldBitLength: NIOLengthFieldBitLength, lengthFieldEndianness: Endianness = .big) { + self.lengthFieldLength = lengthFieldBitLength + self.lengthFieldEndianness = lengthFieldEndianness + } + + public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + + if case .waitingForHeader = self.readState { + try self.readNextLengthFieldToState(buffer: &buffer) + } + + guard case .waitingForFrame(let frameLength) = self.readState else { + return .needMoreData + } + + guard let frameBuffer = try self.readNextFrame(buffer: &buffer, frameLength: frameLength) else { + return .needMoreData + } + + context.fireChannelRead(self.wrapInboundOut(frameBuffer)) + + return .continue + } + + public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + // we'll just try to decode as much as we can as usually + while case .continue = try self.decode(context: context, buffer: &buffer) {} + if buffer.readableBytes > 0 { + context.fireErrorCaught(NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer)) + } + return .needMoreData + } + + /// + /// Attempts to read the header data. Updates the status is successful. + /// + /// - parameters: + /// - buffer: The buffer containing the integer frame length. + /// + private func readNextLengthFieldToState(buffer: inout ByteBuffer) throws { + + // Convert the length field to an integer specifying the length + guard let lengthFieldValue = try self.readFrameLength(for: &buffer) else { + return + } + + self.readState = .waitingForFrame(length: lengthFieldValue) + } + + /// + /// Attempts to read the body data for a given length. Updates the status is successful. + /// + /// - parameters: + /// - buffer: The buffer containing the frame data. + /// - frameLength: The length of the frame data to be read. + /// + private func readNextFrame(buffer: inout ByteBuffer, frameLength: Int) throws -> ByteBuffer? { + + guard let contentsFieldSlice = buffer.readSlice(length: frameLength) else { + return nil + } + + self.readState = .waitingForHeader + + return contentsFieldSlice + } + + /// + /// Decodes the specified region of the buffer into an unadjusted frame length. The default implementation is + /// capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer. + /// + /// - parameters: + /// - buffer: The buffer containing the integer frame length. + /// + private func readFrameLength(for buffer: inout ByteBuffer) throws -> Int? { + let frameLength: Int? + switch self.lengthFieldLength.bitLength { + case .bits8: + frameLength = buffer.readInteger(endianness: self.lengthFieldEndianness, as: UInt8.self).map { Int($0) } + case .bits16: + frameLength = buffer.readInteger(endianness: self.lengthFieldEndianness, as: UInt16.self).map { Int($0) } + case .bits24: + frameLength = buffer.read24UInt(endianness: self.lengthFieldEndianness).map { Int($0) } + case .bits32: + frameLength = try buffer.readInteger(endianness: self.lengthFieldEndianness, as: UInt32.self).map { + guard let size = Int(exactly: $0) else { + throw NIOLengthFieldBasedFrameDecoderError.lengthFieldValueTooLarge + } + return size + } + case .bits64: + frameLength = try buffer.readInteger(endianness: self.lengthFieldEndianness, as: UInt64.self).map { + guard let size = Int(exactly: $0) else { + throw NIOLengthFieldBasedFrameDecoderError.lengthFieldValueTooLarge + } + return size + } + } + + if let frameLength = frameLength, + frameLength > LengthFieldBasedFrameDecoder.maxSupportedLengthFieldSize { + throw NIOLengthFieldBasedFrameDecoderError.lengthFieldValueLargerThanMaxSupportedSize + } + return frameLength + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldPrepender.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldPrepender.swift new file mode 100644 index 00000000..62423661 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LengthFieldPrepender.swift @@ -0,0 +1,135 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +extension ByteBuffer { + @discardableResult + @inlinable + mutating func write24UInt( + _ integer: UInt32, + endianness: Endianness = .big + ) -> Int { + precondition(integer & 0xFF_FF_FF == integer, "integer value does not fit into 24 bit integer") + switch endianness { + case .little: + return writeInteger(UInt8(integer & 0xFF), endianness: .little) + + writeInteger(UInt16((integer >> 8) & 0xFF_FF), endianness: .little) + case .big: + return writeInteger(UInt16((integer >> 8) & 0xFF_FF), endianness: .big) + + writeInteger(UInt8(integer & 0xFF), endianness: .big) + } + } +} + + +public enum LengthFieldPrependerError: Error { + case messageDataTooLongForLengthField +} + +/// +/// An encoder that takes a `ByteBuffer` message and prepends the number of bytes in the message. +/// The length field is always the same fixed length specified on construction. +/// These bytes contain a binary specification of the message size. +/// +/// For example, if you received a packet with the 3 byte length (BCD)... +/// Given that the specified header length is 1 byte, there would be a single byte prepended which contains the number 3 +/// +---+-----+ +/// | A | BCD | ('A' contains 0x03) +/// +---+-----+ +/// This initial prepended byte is called the 'length field'. +/// +public final class LengthFieldPrepender: ChannelOutboundHandler { + /// + /// An enumeration to describe the length of a piece of data in bytes. + /// + public enum ByteLength { + case one + case two + case four + case eight + + fileprivate var bitLength: NIOLengthFieldBitLength { + switch self { + case .one: return .oneByte + case .two: return .twoBytes + case .four: return .fourBytes + case .eight: return .eightBytes + } + } + } + + public typealias OutboundIn = ByteBuffer + public typealias OutboundOut = ByteBuffer + + private let lengthFieldLength: NIOLengthFieldBitLength + private let lengthFieldEndianness: Endianness + + private var lengthBuffer: ByteBuffer? + + /// Create `LengthFieldPrepender` with a given length field length. + /// + /// - parameters: + /// - lengthFieldLength: The length of the field specifying the remaining length of the frame. + /// - lengthFieldEndianness: The endianness of the field specifying the remaining length of the frame. + /// + public convenience init(lengthFieldLength: ByteLength, lengthFieldEndianness: Endianness = .big) { + self.init(lengthFieldBitLength: lengthFieldLength.bitLength, lengthFieldEndianness: lengthFieldEndianness) + } + public init(lengthFieldBitLength: NIOLengthFieldBitLength, lengthFieldEndianness: Endianness = .big) { + // The value contained in the length field must be able to be represented by an integer type on the platform. + // ie. .eight == 64bit which would not fit into the Int type on a 32bit platform. + precondition(lengthFieldBitLength.length <= Int.bitWidth/8) + + self.lengthFieldLength = lengthFieldBitLength + self.lengthFieldEndianness = lengthFieldEndianness + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + + let dataBuffer = self.unwrapOutboundIn(data) + let dataLength = dataBuffer.readableBytes + + guard dataLength <= self.lengthFieldLength.max else { + promise?.fail(LengthFieldPrependerError.messageDataTooLongForLengthField) + return + } + + var dataLengthBuffer: ByteBuffer + + if let existingBuffer = self.lengthBuffer { + dataLengthBuffer = existingBuffer + dataLengthBuffer.clear() + } else { + dataLengthBuffer = context.channel.allocator.buffer(capacity: self.lengthFieldLength.length) + self.lengthBuffer = dataLengthBuffer + } + + switch self.lengthFieldLength.bitLength { + case .bits8: + dataLengthBuffer.writeInteger(UInt8(dataLength), endianness: self.lengthFieldEndianness) + case .bits16: + dataLengthBuffer.writeInteger(UInt16(dataLength), endianness: self.lengthFieldEndianness) + case .bits24: + dataLengthBuffer.write24UInt(UInt32(dataLength), endianness: self.lengthFieldEndianness) + case .bits32: + dataLengthBuffer.writeInteger(UInt32(dataLength), endianness: self.lengthFieldEndianness) + case .bits64: + dataLengthBuffer.writeInteger(UInt64(dataLength), endianness: self.lengthFieldEndianness) + } + + context.write(self.wrapOutboundOut(dataLengthBuffer), promise: nil) + context.write(data, promise: promise) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LineBasedFrameDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LineBasedFrameDecoder.swift new file mode 100644 index 00000000..b27ab15d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/LineBasedFrameDecoder.swift @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A decoder that splits incoming `ByteBuffer`s around line end +/// character(s) (`'\n'` or `'\r\n'`). +/// +/// Let's, for example, consider the following received buffer: +/// +/// +----+-------+------------+ +/// | AB | C\nDE | F\r\nGHI\n | +/// +----+-------+------------+ +/// +/// A instance of `LineBasedFrameDecoder` will split this buffer +/// as follows: +/// +/// +-----+-----+-----+ +/// | ABC | DEF | GHI | +/// +-----+-----+-----+ +/// +public class LineBasedFrameDecoder: ByteToMessageDecoder { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + public var cumulationBuffer: ByteBuffer? + // keep track of the last scan offset from the buffer's reader index (if we didn't find the delimiter) + private var lastScanOffset = 0 + + public init() { } + + public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + if let frame = try self.findNextFrame(buffer: &buffer) { + context.fireChannelRead(wrapInboundOut(frame)) + return .continue + } else { + return .needMoreData + } + } + + public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + while try self.decode(context: context, buffer: &buffer) == .continue {} + if buffer.readableBytes > 0 { + context.fireErrorCaught(NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer)) + } + return .needMoreData + } + + private func findNextFrame(buffer: inout ByteBuffer) throws -> ByteBuffer? { + let view = buffer.readableBytesView.dropFirst(self.lastScanOffset) + // look for the delimiter + if let delimiterIndex = view.firstIndex(of: 0x0A) { // '\n' + let length = delimiterIndex - buffer.readerIndex + let dropCarriageReturn = delimiterIndex > buffer.readableBytesView.startIndex && + buffer.readableBytesView[delimiterIndex - 1] == 0x0D // '\r' + let buff = buffer.readSlice(length: dropCarriageReturn ? length - 1 : length) + // drop the delimiter (and trailing carriage return if appicable) + buffer.moveReaderIndex(forwardBy: dropCarriageReturn ? 2 : 1) + // reset the last scan start index since we found a line + self.lastScanOffset = 0 + return buff + } + // next scan we start where we stopped + self.lastScanOffset = buffer.readableBytes + return nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOExtrasError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOExtrasError.swift new file mode 100644 index 00000000..8c88b1ba --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOExtrasError.swift @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +public protocol NIOExtrasError: Equatable, Error { } + +/// Errors that are raised in NIOExtras. +public enum NIOExtrasErrors { + + /// Error indicating that after an operation some unused bytes are left. + public struct LeftOverBytesError: NIOExtrasError { + public let leftOverBytes: ByteBuffer + } + + /// The channel was closed before receiving a response to a request. + public struct ClosedBeforeReceivingResponse: NIOExtrasError {} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOLengthFieldBitLength.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOLengthFieldBitLength.swift new file mode 100644 index 00000000..38978b79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/NIOLengthFieldBitLength.swift @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An struct to describe the length of a piece of data in bits +public struct NIOLengthFieldBitLength { + internal enum Backing { + case bits8 + case bits16 + case bits24 + case bits32 + case bits64 + } + internal let bitLength: Backing + + public static let oneByte = NIOLengthFieldBitLength(bitLength: .bits8) + public static let twoBytes = NIOLengthFieldBitLength(bitLength: .bits16) + public static let threeBytes = NIOLengthFieldBitLength(bitLength: .bits24) + public static let fourBytes = NIOLengthFieldBitLength(bitLength: .bits32) + public static let eightBytes = NIOLengthFieldBitLength(bitLength: .bits64) + + public static let eightBits = NIOLengthFieldBitLength(bitLength: .bits8) + public static let sixteenBits = NIOLengthFieldBitLength(bitLength: .bits16) + public static let twentyFourBits = NIOLengthFieldBitLength(bitLength: .bits24) + public static let thirtyTwoBits = NIOLengthFieldBitLength(bitLength: .bits32) + public static let sixtyFourBits = NIOLengthFieldBitLength(bitLength: .bits64) + + internal var length: Int { + switch bitLength { + case .bits8: + return 1 + case .bits16: + return 2 + case .bits24: + return 3 + case .bits32: + return 4 + case .bits64: + return 8 + } + } + + internal var max: UInt { + switch bitLength { + case .bits8: + return UInt(UInt8.max) + case .bits16: + return UInt(UInt16.max) + case .bits24: + return (UInt(UInt16.max) << 8) &+ UInt(UInt8.max) + case .bits32: + return UInt(UInt32.max) + case .bits64: + return UInt(UInt64.max) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/PCAPRingBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/PCAPRingBuffer.swift new file mode 100644 index 00000000..01da4787 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/PCAPRingBuffer.swift @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +// MARK: NIOPCAPRingBuffer +/// Storage for the most recent set of packets captured subject to constraints. +/// Use `addFragment` as the sink to a `NIOWritePCAPHandler` and call `emitPCAP` +/// when you wish to get the recorded data. +/// - Warning: This class is not thread safe so should only be called from one thread. +public class NIOPCAPRingBuffer { + private var pcapFragments: CircularBuffer + private var pcapCurrentBytes: Int + private let maximumFragments: Int + private let maximumBytes: Int + + /// Initialise the buffer, setting constraints. + /// - Parameters: + /// - maximumFragments: The maximum number of pcap fragments to store. + /// - maximumBytes: The maximum number of bytes to store - note, data written may exceed this by the header size. + public init(maximumFragments: Int, maximumBytes: Int) { + precondition(maximumFragments > 0) + precondition(maximumBytes > 0) + self.maximumFragments = maximumFragments + self.maximumBytes = maximumBytes + self.pcapCurrentBytes = 0 + self.pcapFragments = CircularBuffer(initialCapacity: maximumFragments) + } + + /// Initialise the buffer, setting constraints + /// - Parameter maximumBytes: The maximum number of bytes to store - note, data written may exceed this by the header size. + public convenience init(maximumBytes: Int) { + self.init(maximumFragments: .max, maximumBytes: maximumBytes) + } + + /// Initialise the buffer, setting constraints + /// - Parameter maximumFragments: The maximum number of pcap fragments to store. + public convenience init(maximumFragments: Int) { + self.init(maximumFragments: maximumFragments, maximumBytes: .max) + } + + @discardableResult + private func popFirst() -> ByteBuffer? { + let popped = self.pcapFragments.popFirst() + if let popped = popped { + self.pcapCurrentBytes -= popped.readableBytes + } + return popped + } + + private func append(_ buffer: ByteBuffer) { + self.pcapFragments.append(buffer) + self.pcapCurrentBytes += buffer.readableBytes + assert(self.pcapFragments.count <= self.maximumFragments) + // It's expected that the caller will have made room if required + // for the fragment but we may well go over on bytes - they're + // expected to fix that afterwards. + } + + /// Record a fragment into the buffer, making space if required. + /// - Parameter buffer: ByteBuffer containing a pcap fragment to store + public func addFragment(_ buffer: ByteBuffer) { + // Make sure we don't go over on the number of fragments. + if self.pcapFragments.count >= self.maximumFragments { + self.popFirst() + } + precondition(self.pcapFragments.count < self.maximumFragments) + + // Add the new fragment + self.append(buffer) + + // Trim if we've exceeded byte limit - this could remove multiple, and indeed all fragments. + while self.pcapCurrentBytes > self.maximumBytes { + self.popFirst() + } + precondition(self.pcapCurrentBytes <= self.maximumBytes) + } + + /// Emit the captured data to a consuming function; then clear the captured data. + /// - Returns: A ciruclar buffer of captured fragments. + public func emitPCAP() -> CircularBuffer { + let toReturn = self.pcapFragments // Copy before clearing. + self.pcapFragments.removeAll(keepingCapacity: true) + self.pcapCurrentBytes = 0 + return toReturn + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/QuiescingHelper.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/QuiescingHelper.swift new file mode 100644 index 00000000..c1f0f984 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/QuiescingHelper.swift @@ -0,0 +1,252 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +private enum ShutdownError: Error { + case alreadyShutdown +} + +/// Collects a number of channels that are open at the moment. To prevent races, `ChannelCollector` uses the +/// `EventLoop` of the server `Channel` that it gets passed to synchronise. It is important to call the +/// `channelAdded` method in the same event loop tick as the `Channel` is actually created. +private final class ChannelCollector { + enum LifecycleState { + case upAndRunning + case shuttingDown + case shutdownCompleted + } + private var openChannels: [ObjectIdentifier: Channel] = [:] + private let serverChannel: Channel + private var fullyShutdownPromise: EventLoopPromise? = nil + private var lifecycleState = LifecycleState.upAndRunning + + private var eventLoop: EventLoop { + return self.serverChannel.eventLoop + } + + /// Initializes a `ChannelCollector` for `Channel`s accepted by `serverChannel`. + init(serverChannel: Channel) { + self.serverChannel = serverChannel + } + + /// Add a channel to the `ChannelCollector`. + /// + /// - note: This must be called on `serverChannel.eventLoop`. + /// + /// - parameters: + /// - channel: The `Channel` to add to the `ChannelCollector`. + func channelAdded(_ channel: Channel) throws { + self.eventLoop.assertInEventLoop() + + guard self.lifecycleState != .shutdownCompleted else { + channel.close(promise: nil) + throw ShutdownError.alreadyShutdown + } + + self.openChannels[ObjectIdentifier(channel)] = channel + } + + private func shutdownCompleted() { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleState == .shuttingDown) + + self.lifecycleState = .shutdownCompleted + self.fullyShutdownPromise?.succeed(()) + } + + private func channelRemoved0(_ channel: Channel) { + self.eventLoop.assertInEventLoop() + precondition(self.openChannels.keys.contains(ObjectIdentifier(channel)), + "channel \(channel) not in ChannelCollector \(self.openChannels)") + + self.openChannels.removeValue(forKey: ObjectIdentifier(channel)) + if self.lifecycleState != .upAndRunning && self.openChannels.isEmpty { + shutdownCompleted() + } + } + + /// Remove a previously added `Channel` from the `ChannelCollector`. + /// + /// - note: This method can be called from any thread. + /// + /// - parameters: + /// - channel: The `Channel` to be removed. + func channelRemoved(_ channel: Channel) { + if self.eventLoop.inEventLoop { + self.channelRemoved0(channel) + } else { + self.eventLoop.execute { + self.channelRemoved0(channel) + } + } + } + + private func initiateShutdown0(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + precondition(self.lifecycleState == .upAndRunning) + + self.lifecycleState = .shuttingDown + + if let promise = promise { + if let alreadyExistingPromise = self.fullyShutdownPromise { + alreadyExistingPromise.futureResult.cascade(to: promise) + } else { + self.fullyShutdownPromise = promise + } + } + + self.serverChannel.close().cascadeFailure(to: self.fullyShutdownPromise) + + for channel in self.openChannels.values { + channel.eventLoop.execute { + channel.pipeline.fireUserInboundEventTriggered(ChannelShouldQuiesceEvent()) + } + } + + if self.openChannels.isEmpty { + shutdownCompleted() + } + } + + /// Initiate the shutdown fulfilling `promise` when all the previously registered `Channel`s have been closed. + /// + /// - parameters: + /// - promise: The `EventLoopPromise` to fulfill when the shutdown of all previously registered `Channel`s has been completed. + func initiateShutdown(promise: EventLoopPromise?) { + if self.serverChannel.eventLoop.inEventLoop { + self.serverChannel.pipeline.fireUserInboundEventTriggered(ChannelShouldQuiesceEvent()) + } else { + self.eventLoop.execute { + self.serverChannel.pipeline.fireUserInboundEventTriggered(ChannelShouldQuiesceEvent()) + } + } + + if self.eventLoop.inEventLoop { + self.initiateShutdown0(promise: promise) + } else { + self.eventLoop.execute { + self.initiateShutdown0(promise: promise) + } + } + } +} + +/// A `ChannelHandler` that adds all channels that it receives through the `ChannelPipeline` to a `ChannelCollector`. +/// +/// - note: This is only useful to be added to a server `Channel` in `ServerBootstrap.serverChannelInitializer`. +private final class CollectAcceptedChannelsHandler: ChannelInboundHandler { + typealias InboundIn = Channel + + private let channelCollector: ChannelCollector + + /// Initialise with a `ChannelCollector` to add the received `Channels` to. + init(channelCollector: ChannelCollector) { + self.channelCollector = channelCollector + } + + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if event is ChannelShouldQuiesceEvent { + // ServerQuiescingHelper will close us anyway + return + } + context.fireUserInboundEventTriggered(event) + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let channel = self.unwrapInboundIn(data) + do { + try self.channelCollector.channelAdded(channel) + let closeFuture = channel.closeFuture + closeFuture.whenComplete { (_: Result<(), Error>) in + self.channelCollector.channelRemoved(channel) + } + context.fireChannelRead(data) + } catch ShutdownError.alreadyShutdown { + channel.close(promise: nil) + } catch { + fatalError("unexpected error \(error)") + } + } +} + +/// Helper that can be used to orchestrate the quiescing of a server `Channel` and all the child `Channel`s that are +/// open at a given point in time. +/// +/// `ServerQuiescingHelper` makes it easy to collect all child `Channel`s that a given server `Channel` accepts. When +/// the quiescing period starts (that is when `ServerQuiescingHelper.initiateShutdown` is invoked), it will perform the +/// following actions: +/// +/// 1. close the server `Channel` so no further connections get accepted +/// 2. send a `ChannelShouldQuiesceEvent` user event to all currently still open child `Channel`s +/// 3. after all previously open child `Channel`s have closed, notify the `EventLoopPromise` that was passed to `shutdown`. +/// +/// Example use: +/// +/// let group = MultiThreadedEventLoopGroup(numThreads: [...]) +/// let quiesce = ServerQuiescingHelper(group: group) +/// let serverChannel = try ServerBootstrap(group: group) +/// .serverChannelInitializer { channel in +/// // add the collection handler so all accepted child channels get collected +/// channel.pipeline.add(handler: quiesce.makeServerChannelHandler(channel: channel)) +/// } +/// // further bootstrap configuration +/// .bind([...]) +/// .wait() +/// // [...] +/// let fullyShutdownPromise: EventLoopPromise = group.next().newPromise() +/// // initiate the shutdown +/// quiesce.initiateShutdown(promise: fullyShutdownPromise) +/// // wait for the shutdown to complete +/// try fullyShutdownPromise.futureResult.wait() +/// +public final class ServerQuiescingHelper { + private let channelCollectorPromise: EventLoopPromise + + /// Initialize with a given `EventLoopGroup`. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use to allocate new promises and the like. + public init(group: EventLoopGroup) { + self.channelCollectorPromise = group.next().makePromise() + } + + /// Create the `ChannelHandler` for the server `channel` to collect all accepted child `Channel`s. + /// + /// - parameters: + /// - channel: The server `Channel` whose child `Channel`s to collect + /// - returns: a `ChannelHandler` that the user must add to the server `Channel`s pipeline + public func makeServerChannelHandler(channel: Channel) -> ChannelHandler { + let collector = ChannelCollector(serverChannel: channel) + self.channelCollectorPromise.succeed(collector) + return CollectAcceptedChannelsHandler(channelCollector: collector) + } + + /// Initiate the shutdown. The following actions will be performed: + /// + /// 1. close the server `Channel` so no further connections get accepted + /// 2. send a `ChannelShouldQuiesceEvent` user event to all currently still open child `Channel`s + /// 3. after all previously open child `Channel`s have closed, notify `promise` + /// + /// - parameters: + /// - promise: The `EventLoopPromise` that will be fulfilled when the shutdown is complete. + public func initiateShutdown(promise: EventLoopPromise?) { + let f = self.channelCollectorPromise.futureResult.map { channelCollector in + channelCollector.initiateShutdown(promise: promise) + } + if let promise = promise { + f.cascadeFailure(to: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/RequestResponseHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/RequestResponseHandler.swift new file mode 100644 index 00000000..011e58eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/RequestResponseHandler.swift @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// `RequestResponseHandler` receives a `Request` alongside an `EventLoopPromise` from the `Channel`'s +/// outbound side. It will fulfill the promise with the `Response` once it's received from the `Channel`'s inbound +/// side. +/// +/// `RequestResponseHandler` does support pipelining `Request`s and it will send them pipelined further down the +/// `Channel`. Should `RequestResponseHandler` receive an error from the `Channel`, it will fail all promises meant for +/// the outstanding `Reponse`s and close the `Channel`. All requests enqueued after an error occured will be immediately +/// failed with the first error the channel received. +/// +/// `RequestResponseHandler` requires that the `Response`s arrive on `Channel` in the same order as the `Request`s +/// were submitted. +public final class RequestResponseHandler: ChannelDuplexHandler { + public typealias InboundIn = Response + public typealias InboundOut = Never + public typealias OutboundIn = (Request, EventLoopPromise) + public typealias OutboundOut = Request + + private enum State { + case operational + case error(Error) + + var isOperational: Bool { + switch self { + case .operational: + return true + case .error: + return false + } + } + } + + private var state: State = .operational + private var promiseBuffer: CircularBuffer> + + + /// Create a new `RequestResponseHandler`. + /// + /// - parameters: + /// - initialBufferCapacity: `RequestResponseHandler` saves the promises for all outstanding responses in a + /// buffer. `initialBufferCapacity` is the initial capacity for this buffer. You usually do not need to set + /// this parameter unless you intend to pipeline very deeply and don't want the buffer to resize. + public init(initialBufferCapacity: Int = 4) { + self.promiseBuffer = CircularBuffer(initialCapacity: initialBufferCapacity) + } + + public func channelInactive(context: ChannelHandlerContext) { + switch self.state { + case .error: + // We failed any outstanding promises when we entered the error state and will fail any + // new promises in write. + assert(self.promiseBuffer.count == 0) + case .operational: + let promiseBuffer = self.promiseBuffer + self.promiseBuffer.removeAll() + promiseBuffer.forEach { promise in + promise.fail(NIOExtrasErrors.ClosedBeforeReceivingResponse()) + } + } + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + guard self.state.isOperational else { + // we're in an error state, ignore further responses + assert(self.promiseBuffer.count == 0) + return + } + + let response = self.unwrapInboundIn(data) + let promise = self.promiseBuffer.removeFirst() + + promise.succeed(response) + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + guard self.state.isOperational else { + assert(self.promiseBuffer.count == 0) + return + } + self.state = .error(error) + let promiseBuffer = self.promiseBuffer + self.promiseBuffer.removeAll() + context.close(promise: nil) + promiseBuffer.forEach { + $0.fail(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let (request, responsePromise) = self.unwrapOutboundIn(data) + switch self.state { + case .error(let error): + assert(self.promiseBuffer.count == 0) + responsePromise.fail(error) + promise?.fail(error) + case .operational: + self.promiseBuffer.append(responsePromise) + context.write(self.wrapOutboundOut(request), promise: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/WritePCAPHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/WritePCAPHandler.swift new file mode 100644 index 00000000..c3723a95 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOExtras/Sources/NIOExtras/WritePCAPHandler.swift @@ -0,0 +1,717 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(macOS) || os(tvOS) || os(iOS) || os(watchOS) +import Darwin +#else +import Glibc +#endif +import Dispatch + +import NIOCore + +let sysWrite = write + +struct TCPHeader { + struct Flags: OptionSet { + var rawValue: UInt8 + + init(rawValue: UInt8) { + self.rawValue = rawValue + } + + static let fin = Flags(rawValue: 1 << 0) + static let syn = Flags(rawValue: 1 << 1) + static let rst = Flags(rawValue: 1 << 2) + static let psh = Flags(rawValue: 1 << 3) + static let ack = Flags(rawValue: 1 << 4) + static let urg = Flags(rawValue: 1 << 5) + static let ece = Flags(rawValue: 1 << 6) + static let cwr = Flags(rawValue: 1 << 7) + } + + var flags: Flags + var ackNumber: UInt32? + var sequenceNumber: UInt32 + var srcPort: UInt16 + var dstPort: UInt16 +} + +struct PCAPRecordHeader { + enum Error: Swift.Error { + case incompatibleAddressPair(SocketAddress, SocketAddress) + } + enum AddressTuple { + case v4(src: SocketAddress.IPv4Address, dst: SocketAddress.IPv4Address) + case v6(src: SocketAddress.IPv6Address, dst: SocketAddress.IPv6Address) + + var srcPort: UInt16 { + switch self { + case .v4(src: let src, dst: _): + return UInt16(bigEndian: src.address.sin_port) + case .v6(src: let src, dst: _): + return UInt16(bigEndian: src.address.sin6_port) + } + } + + var dstPort: UInt16 { + switch self { + case .v4(src: _, dst: let dst): + return UInt16(bigEndian: dst.address.sin_port) + case .v6(src: _, dst: let dst): + return UInt16(bigEndian: dst.address.sin6_port) + } + } + } + + var payloadLength: Int + var addresses: AddressTuple + var time: timeval + var tcp: TCPHeader + + init(payloadLength: Int, addresses: AddressTuple, time: timeval, tcp: TCPHeader) { + self.payloadLength = payloadLength + self.addresses = addresses + self.time = time + self.tcp = tcp + + assert(addresses.srcPort == Int(tcp.srcPort)) + assert(addresses.dstPort == Int(tcp.dstPort)) + assert(tcp.ackNumber == nil ? !tcp.flags.contains([.ack]) : tcp.flags.contains([.ack])) + } + + init(payloadLength: Int, src: SocketAddress, dst: SocketAddress, tcp: TCPHeader) throws { + let addressTuple: AddressTuple + switch (src, dst) { + case (.v4(let src), .v4(let dst)): + addressTuple = .v4(src: src, dst: dst) + case (.v6(let src), .v6(let dst)): + addressTuple = .v6(src: src, dst: dst) + default: + throw Error.incompatibleAddressPair(src, dst) + } + self = .init(payloadLength: payloadLength, addresses: addressTuple, tcp: tcp) + } + + init(payloadLength: Int, addresses: AddressTuple, tcp: TCPHeader) { + var tv = timeval() + gettimeofday(&tv, nil) + self = .init(payloadLength: payloadLength, addresses: addresses, time: tv, tcp: tcp) + } +} + +/// A `ChannelHandler` that can write a [`.pcap` file](https://en.wikipedia.org/wiki/Pcap) containing the send/received +/// data as synthesized TCP packet captures. +/// +/// You will be able to open the `.pcap` file in for example [Wireshark](https://www.wireshark.org) or +/// [`tcpdump`](http://www.tcpdump.org). Using `NIOWritePCAPHandler` to write your `.pcap` files can be useful for +/// example when your real network traffic is TLS protected (so `tcpdump`/Wireshark can't read it directly), or if you +/// don't have enough privileges on the running host to dump the network traffic. +/// +/// `NIOWritePCAPHandler` will also work with Unix Domain Sockets in which case it will still synthesize a TCP packet +/// capture with local address `111.111.111.111` (port `1111`) and remote address `222.222.222.222` (port `2222`). +public class NIOWritePCAPHandler: RemovableChannelHandler { + public enum Mode { + case client + case server + } + + /// Settings for `NIOWritePCAPHandler`. + public struct Settings { + /// When to issue data into the `.pcap` file. + public enum EmitPCAP { + /// Write the data immediately when `NIOWritePCAPHandler` saw the event on the `ChannelPipeline`. + /// + /// For writes this means when the `write` event is triggered. Please note that this will write potentially + /// unflushed data into the `.pcap` file. + /// + /// If in doubt, prefer `.whenCompleted`. + case whenIssued + + /// Write the data when the event completed. + /// + /// For writes this means when the `write` promise is succeeded. The `whenCompleted` mode mirrors most + /// closely what's actually sent over the wire. + case whenCompleted + } + + /// When to emit the data from the `write` event into the `.pcap` file. + public var emitPCAPWrites: EmitPCAP + + /// Default settings for the `NIOWritePCAPHandler`. + public init() { + self = .init(emitPCAPWrites: .whenCompleted) + } + + /// Settings with customization. + /// + /// - parameters: + /// - emitPCAPWrites: When to issue the writes into the `.pcap` file, see `EmitPCAP`. + public init(emitPCAPWrites: EmitPCAP) { + self.emitPCAPWrites = emitPCAPWrites + } + } + + private enum CloseState { + case notClosing + case closedInitiatorLocal + case closedInitiatorRemote + } + + private let fileSink: (ByteBuffer) -> Void + private let mode: Mode + private let maxPayloadSize = Int(UInt16.max - 40 /* needs to fit into the IPv4 header which adds 40 */) + private let settings: Settings + private var buffer: ByteBuffer! + private var readInboundBytes: UInt64 = 0 + private var writtenOutboundBytes: UInt64 = 0 + private var closeState = CloseState.notClosing + + private static let fakeLocalAddress = try! SocketAddress(ipAddress: "111.111.111.111", port: 1111) + private static let fakeRemoteAddress = try! SocketAddress(ipAddress: "222.222.222.222", port: 2222) + + private var localAddress: SocketAddress? + private var remoteAddress: SocketAddress? + + public static var pcapFileHeader: ByteBuffer { + var buffer = ByteBufferAllocator().buffer(capacity: 24) + buffer.writePCAPHeader() + return buffer + } + + /// Initialize a `NIOWritePCAPHandler`. + /// + /// - parameters: + /// - fakeLocalAddress: Allows you to optionally override the local address to be different from the real one. + /// - fakeRemoteAddress: Allows you to optionally override the remote address to be different from the real one. + /// - settings: The settings for the `NIOWritePCAPHandler`. + /// - fileSink: The `fileSink` closure is called every time a new chunk of the `.pcap` file is ready to be + /// written to disk or elsewhere. See `SynchronizedFileSink` for a convenient way to write to + /// disk. + public init(mode: Mode, + fakeLocalAddress: SocketAddress? = nil, + fakeRemoteAddress: SocketAddress? = nil, + settings: Settings, + fileSink: @escaping (ByteBuffer) -> Void) { + self.settings = settings + self.fileSink = fileSink + self.mode = mode + if let fakeLocalAddress = fakeLocalAddress { + self.localAddress = fakeLocalAddress + } + if let fakeRemoteAddress = fakeRemoteAddress { + self.remoteAddress = fakeRemoteAddress + } + } + + /// Initialize a `NIOWritePCAPHandler` with default settings. + /// + /// - parameters: + /// - fakeLocalAddress: Allows you to optionally override the local address to be different from the real one. + /// - fakeRemoteAddress: Allows you to optionally override the remote address to be different from the real one. + /// - fileSink: The `fileSink` closure is called every time a new chunk of the `.pcap` file is ready to be + /// written to disk or elsewhere. See `NIOSynchronizedFileSink` for a convenient way to write to + /// disk. + public convenience init(mode: Mode, + fakeLocalAddress: SocketAddress? = nil, + fakeRemoteAddress: SocketAddress? = nil, + fileSink: @escaping (ByteBuffer) -> Void) { + self.init(mode: mode, + fakeLocalAddress: fakeLocalAddress, + fakeRemoteAddress: fakeRemoteAddress, + settings: Settings(), + fileSink: fileSink) + } + + private func writeBuffer(_ buffer: ByteBuffer) { + self.fileSink(buffer) + } + + private func localAddress(context: ChannelHandlerContext) -> SocketAddress { + if let localAddress = self.localAddress { + return localAddress + } else { + let localAddress = context.channel.localAddress ?? NIOWritePCAPHandler.fakeLocalAddress + self.localAddress = localAddress + return localAddress + } + } + + private func remoteAddress(context: ChannelHandlerContext) -> SocketAddress { + if let remoteAddress = self.remoteAddress { + return remoteAddress + } else { + let remoteAddress = context.channel.remoteAddress ?? NIOWritePCAPHandler.fakeRemoteAddress + self.remoteAddress = remoteAddress + return remoteAddress + } + } + + private func clientAddress(context: ChannelHandlerContext) -> SocketAddress { + switch self.mode { + case .client: + return self.localAddress(context: context) + case .server: + return self.remoteAddress(context: context) + } + } + + private func serverAddress(context: ChannelHandlerContext) -> SocketAddress { + switch self.mode { + case .client: + return self.remoteAddress(context: context) + case .server: + return self.localAddress(context: context) + } + } + + private func takeSensiblySizedPayload(buffer: inout ByteBuffer) -> ByteBuffer? { + guard buffer.readableBytes > 0 else { + return nil + } + + return buffer.readSlice(length: min(buffer.readableBytes, self.maxPayloadSize)) + } + + private func sequenceNumber(byteCount: UInt64) -> UInt32 { + return UInt32(byteCount % (UInt64(UInt32.max) + 1)) + } +} + +extension NIOWritePCAPHandler: ChannelDuplexHandler { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + public typealias OutboundIn = IOData + public typealias OutboundOut = IOData + + public func handlerAdded(context: ChannelHandlerContext) { + self.buffer = context.channel.allocator.buffer(capacity: 256) + } + + public func channelActive(context: ChannelHandlerContext) { + self.buffer.clear() + self.readInboundBytes = 1 + self.writtenOutboundBytes = 1 + do { + let clientAddress = self.clientAddress(context: context) + let serverAddress = self.serverAddress(context: context) + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: clientAddress, + dst: serverAddress, + tcp: TCPHeader(flags: [.syn], + ackNumber: nil, + sequenceNumber: 0, + srcPort: .init(clientAddress.port!), + dstPort: .init(serverAddress.port!)))) + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: serverAddress, + dst: clientAddress, + tcp: TCPHeader(flags: [.syn, .ack], + ackNumber: 1, + sequenceNumber: 0, + srcPort: .init(serverAddress.port!), + dstPort: .init(clientAddress.port!)))) + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: clientAddress, + dst: serverAddress, + tcp: TCPHeader(flags: [.ack], + ackNumber: 1, + sequenceNumber: 1, + srcPort: .init(clientAddress.port!), + dstPort: .init(serverAddress.port!)))) + self.writeBuffer(self.buffer) + } catch { + context.fireErrorCaught(error) + } + context.fireChannelActive() + } + + public func channelInactive(context: ChannelHandlerContext) { + let didLocalInitiateTheClose: Bool + switch self.closeState { + case .closedInitiatorLocal: + didLocalInitiateTheClose = true + case .closedInitiatorRemote: + didLocalInitiateTheClose = false + case .notClosing: + self.closeState = .closedInitiatorRemote + didLocalInitiateTheClose = false + } + + self.buffer.clear() + do { + let closeInitiatorAddress = didLocalInitiateTheClose ? self.localAddress(context: context) : self.remoteAddress(context: context) + let closeRecipientAddress = didLocalInitiateTheClose ? self.remoteAddress(context: context) : self.localAddress(context: context) + let initiatorSeq = self.sequenceNumber(byteCount: didLocalInitiateTheClose ? + self.writtenOutboundBytes : self.readInboundBytes) + let recipientSeq = self.sequenceNumber(byteCount: didLocalInitiateTheClose ? + self.readInboundBytes : self.writtenOutboundBytes) + + // terminate the connection cleanly + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: closeInitiatorAddress, + dst: closeRecipientAddress, + tcp: TCPHeader(flags: [.fin], + ackNumber: nil, + sequenceNumber: initiatorSeq, + srcPort: .init(closeInitiatorAddress.port!), + dstPort: .init(closeRecipientAddress.port!)))) + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: closeRecipientAddress, + dst: closeInitiatorAddress, + tcp: TCPHeader(flags: [.ack, .fin], + ackNumber: initiatorSeq + 1, + sequenceNumber: recipientSeq, + srcPort: .init(closeRecipientAddress.port!), + dstPort: .init(closeInitiatorAddress.port!)))) + try self.buffer.writePCAPRecord(.init(payloadLength: 0, + src: closeInitiatorAddress, + dst: closeRecipientAddress, + tcp: TCPHeader(flags: [.ack], + ackNumber: recipientSeq + 1, + sequenceNumber: initiatorSeq + 1, + srcPort: .init(closeInitiatorAddress.port!), + dstPort: .init(closeRecipientAddress.port!)))) + self.writeBuffer(self.buffer) + } catch { + context.fireErrorCaught(error) + } + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + defer { + context.fireChannelRead(data) + } + guard self.closeState == .notClosing else { + return + } + + let data = self.unwrapInboundIn(data) + guard data.readableBytes > 0 else { + return + } + + self.buffer.clear() + do { + var data = data + while var payloadToSend = self.takeSensiblySizedPayload(buffer: &data) { + try self.buffer.writePCAPRecord(.init(payloadLength: payloadToSend.readableBytes, + src: self.remoteAddress(context: context), + dst: self.localAddress(context: context), + tcp: TCPHeader(flags: [], + ackNumber: nil, + sequenceNumber: self.sequenceNumber(byteCount: self.readInboundBytes), + srcPort: .init(self.remoteAddress(context: context).port!), + dstPort: .init(self.localAddress(context: context).port!)))) + self.readInboundBytes += UInt64(payloadToSend.readableBytes) + self.buffer.writeBuffer(&payloadToSend) + } + assert(data.readableBytes == 0) + self.writeBuffer(self.buffer) + } catch { + context.fireErrorCaught(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + var buffer = self.unwrapInboundIn(data) + + func emitWrites() { + do { + self.buffer.clear() + while var payloadToSend = self.takeSensiblySizedPayload(buffer: &buffer) { + try self.buffer.writePCAPRecord(.init(payloadLength: payloadToSend.readableBytes, + src: self.localAddress(context: context), + dst: self.remoteAddress(context: context), + tcp: TCPHeader(flags: [], + ackNumber: nil, + sequenceNumber: self.sequenceNumber(byteCount: self.writtenOutboundBytes), + srcPort: .init(self.localAddress(context: context).port!), + dstPort: .init(self.remoteAddress(context: context).port!)))) + self.writtenOutboundBytes += UInt64(payloadToSend.readableBytes) + self.buffer.writeBuffer(&payloadToSend) + } + self.writeBuffer(self.buffer) + } catch { + context.fireErrorCaught(error) + } + } + + switch self.settings.emitPCAPWrites { + case .whenCompleted: + let promise = promise ?? context.eventLoop.makePromise() + promise.futureResult.whenSuccess { + emitWrites() + } + context.write(data, promise: promise) + case .whenIssued: + emitWrites() + context.write(data, promise: promise) + } + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if let event = event as? ChannelEvent { + if event == .inputClosed { + switch self.closeState { + case .closedInitiatorLocal: + () // fair enough, we already closed locally + case .closedInitiatorRemote: + () // that's odd but okay + case .notClosing: + self.closeState = .closedInitiatorRemote + } + } + } + context.fireUserInboundEventTriggered(event) + } + + public func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + switch self.closeState { + case .closedInitiatorLocal: + () // weird, this looks like a double-close + case .closedInitiatorRemote: + () // fair enough, already closed I guess + case .notClosing: + self.closeState = .closedInitiatorLocal + } + context.close(mode: mode, promise: promise) + } +} + +extension ByteBuffer { + mutating func writePCAPHeader() { + // guint32 magic_number; /* magic number */ + self.writeInteger(0xa1b2c3d4, endianness: .host, as: UInt32.self) + // guint16 version_major; /* major version number */ + self.writeInteger(2, endianness: .host, as: UInt16.self) + // guint16 version_minor; /* minor version number * + self.writeInteger(4, endianness: .host, as: UInt16.self) + // gint32 thiszone; /* GMT to local correction */ + self.writeInteger(0, endianness: .host, as: UInt32.self) + // guint32 sigfigs; /* accuracy of timestamps */ + self.writeInteger(0, endianness: .host, as: UInt32.self) + // guint32 snaplen; /* max length of captured packets, in octets */ + self.writeInteger(.max, endianness: .host, as: UInt32.self) + // guint32 network; /* data link type */ + self.writeInteger(0, endianness: .host, as: UInt32.self) + } + + mutating func writePCAPRecord(_ record: PCAPRecordHeader) throws { + let rawDataLength = record.payloadLength + let tcpLength = rawDataLength + 20 /* TCP header length */ + + // record + // guint32 ts_sec; /* timestamp seconds */ + self.writeInteger(.init(record.time.tv_sec), endianness: .host, as: UInt32.self) + // guint32 ts_usec; /* timestamp microseconds */ + self.writeInteger(.init(record.time.tv_usec), endianness: .host, as: UInt32.self) + // continued below ... + + switch record.addresses { + case .v4(let la, let ra): + let ipv4WholeLength = tcpLength + 20 /* IPv4 header length, included in IPv4 */ + let recordLength = ipv4WholeLength + 4 /* 32 bits for protocol id */ + + // record, continued + // guint32 incl_len; /* number of octets of packet saved in file */ + self.writeInteger(.init(recordLength), endianness: .host, as: UInt32.self) + // guint32 orig_len; /* actual length of packet */ + self.writeInteger(.init(recordLength), endianness: .host, as: UInt32.self) + + self.writeInteger(2, endianness: .host, as: UInt32.self) // IPv4 + + // IPv4 packet + self.writeInteger(0x45, as: UInt8.self) // IP version (4) & IHL (5) + self.writeInteger(0, as: UInt8.self) // DSCP + self.writeInteger(.init(ipv4WholeLength), as: UInt16.self) + + self.writeInteger(0, as: UInt16.self) // identification + self.writeInteger(0x4000 /* this set's "don't fragment" */, as: UInt16.self) // flags & fragment offset + self.writeInteger(.max /* we don't care about TTL */, as: UInt8.self) // TTL + self.writeInteger(6, as: UInt8.self) // TCP + self.writeInteger(0, as: UInt16.self) // checksum + self.writeInteger(la.address.sin_addr.s_addr, endianness: .host, as: UInt32.self) + self.writeInteger(ra.address.sin_addr.s_addr, endianness: .host, as: UInt32.self) + case .v6(let la, let ra): + let ipv6PayloadLength = tcpLength + let recordLength = ipv6PayloadLength + 4 /* 32 bits for protocol id */ + 40 /* IPv6 header length */ + + // record, continued + // guint32 incl_len; /* number of octets of packet saved in file */ + self.writeInteger(.init(recordLength), endianness: .host, as: UInt32.self) + // guint32 orig_len; /* actual length of packet */ + self.writeInteger(.init(recordLength), endianness: .host, as: UInt32.self) + + self.writeInteger(24, endianness: .host, as: UInt32.self) // IPv6 + + // IPv6 packet + self.writeInteger(/* version */ (6 << 28), as: UInt32.self) // IP version (6) & fancy stuff + self.writeInteger(.init(ipv6PayloadLength), as: UInt16.self) + self.writeInteger(6, as: UInt8.self) // TCP + self.writeInteger(.max /* we don't care about TTL */, as: UInt8.self) // hop limit (like TTL) + + var laAddress = la.address + withUnsafeBytes(of: &laAddress.sin6_addr) { ptr in + assert(ptr.count == 16) + self.writeBytes(ptr) + } + var raAddress = ra.address + withUnsafeBytes(of: &raAddress.sin6_addr) { ptr in + assert(ptr.count == 16) + self.writeBytes(ptr) + } + } + + // TCP + self.writeInteger(record.tcp.srcPort, as: UInt16.self) + self.writeInteger(record.tcp.dstPort, as: UInt16.self) + + self.writeInteger(record.tcp.sequenceNumber, as: UInt32.self) // seq no + self.writeInteger(record.tcp.ackNumber ?? 0, as: UInt32.self) // ack no + + self.writeInteger(5 << 12 | UInt16(record.tcp.flags.rawValue), as: UInt16.self) // data offset + reserved bits + fancy stuff + self.writeInteger(.max /* we don't do actual window sizes */, as: UInt16.self) // window size + self.writeInteger(0xbad /* fake */, as: UInt16.self) // checksum + self.writeInteger(0, as: UInt16.self) // urgent pointer + } +} + +extension NIOWritePCAPHandler { + /// A synchronised file sink that uses a `DispatchQueue` to do all the necessary write synchronously. + /// + /// A `SynchronizedFileSink` is thread-safe so can be used from any thread/`EventLoop`. After use, you + /// _must_ call `syncClose` on the `SynchronizedFileSink` to shut it and all the associated resources down. Failing + /// to do so triggers undefined behaviour. + public class SynchronizedFileSink { + private let fileHandle: NIOFileHandle + private let workQueue: DispatchQueue + private let writesGroup = DispatchGroup() + private let errorHandler: (Swift.Error) -> Void + private var state: State = .running /* protected by `workQueue` */ + + public enum FileWritingMode { + case appendToExistingPCAPFile + case createNewPCAPFile + } + + public struct Error: Swift.Error { + public var errorCode: Int + + internal enum ErrorCode: Int { + case cannotOpenFileError = 1 + case cannotWriteToFileError + } + } + + private enum State { + case running + case error(Swift.Error) + } + + /// Creates a `SynchronizedFileSink` for writing to a `.pcap` file at `path`. + /// + /// Typically, after you created a `SynchronizedFileSink`, you will hand `myFileSink.write` to + /// `NIOWritePCAPHandler`'s constructor so `NIOPCAPHandler` can write `.pcap` files. Example: + /// + /// ```swift + /// let fileSink = try NIOWritePCAPHandler.SynchronizedFileSink.fileSinkWritingToFile(path: "test.pcap", + /// errorHandler: { error in + /// print("ERROR: \(error)") + /// }) + /// defer { + /// try fileSink.syncClose() + /// } + /// // [...] + /// channel.pipeline.addHandler(NIOWritePCAPHandler(mode: .server, fileSink: fileSink.write)) + /// ``` + /// + /// - parameters: + /// - path: The path of the `.pcap` file to write. + /// - fileWritingMode: Whether to append to an existing `.pcap` file or to create a new `.pcap` file. If you + /// choose to append to an existing `.pcap` file, the file header does not get written. + /// - errorHandler: Invoked when an unrecoverable error has occured. In this event you may log the error and + /// you must then `syncClose` the `SynchronizedFileSink`. When `errorHandler` has been + /// called, no further writes will be attempted and `errorHandler` will also not be called + /// again. + public static func fileSinkWritingToFile(path: String, + fileWritingMode: FileWritingMode = .createNewPCAPFile, + errorHandler: @escaping (Swift.Error) -> Void) throws -> SynchronizedFileSink { + let oflag: CInt = fileWritingMode == FileWritingMode.createNewPCAPFile ? (O_TRUNC | O_CREAT) : O_APPEND + let fd = try path.withCString { pathPtr -> CInt in + let fd = open(pathPtr, O_WRONLY | oflag, 0o600) + guard fd >= 0 else { + throw SynchronizedFileSink.Error(errorCode: Error.ErrorCode.cannotOpenFileError.rawValue) + } + return fd + } + + if fileWritingMode == .createNewPCAPFile { + let writeOk = NIOWritePCAPHandler.pcapFileHeader.withUnsafeReadableBytes { ptr in + return sysWrite(fd, ptr.baseAddress, ptr.count) == ptr.count + } + guard writeOk else { + throw SynchronizedFileSink.Error(errorCode: Error.ErrorCode.cannotWriteToFileError.rawValue) + } + } + return SynchronizedFileSink(fileHandle: NIOFileHandle(descriptor: fd), + errorHandler: errorHandler) + } + + private init(fileHandle: NIOFileHandle, + errorHandler: @escaping (Swift.Error) -> Void) { + self.fileHandle = fileHandle + self.workQueue = DispatchQueue(label: "io.swiftnio.extras.WritePCAPHandler.SynchronizedFileSink.workQueue") + self.errorHandler = errorHandler + } + + /// Synchronously close this `SynchronizedFileSink` and any associated resources. + /// + /// After use, it is mandatory to close a `SynchronizedFileSink` exactly once. `syncClose` may be called from + /// any thread but not from an `EventLoop` as it will block. + public func syncClose() throws { + self.writesGroup.wait() + try self.workQueue.sync { + try self.fileHandle.close() + } + } + + public func write(buffer: ByteBuffer) { + self.workQueue.async(group: self.writesGroup) { + guard case .running = self.state else { + return + } + do { + try self.fileHandle.withUnsafeFileDescriptor { fd in + var buffer = buffer + while buffer.readableBytes > 0 { + try buffer.readWithUnsafeReadableBytes { dataPtr in + let r = sysWrite(fd, dataPtr.baseAddress, dataPtr.count) + assert(r != 0, "write returned 0 but we tried to write \(dataPtr.count) bytes") + guard r > 0 else { + throw Error.init(errorCode: Error.ErrorCode.cannotWriteToFileError.rawValue) + } + return r + } + } + } + } catch { + self.state = .error(error) + self.errorHandler(error) + } + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/ByteBuffer-foundation.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/ByteBuffer-foundation.swift new file mode 100644 index 00000000..46cd0057 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/ByteBuffer-foundation.swift @@ -0,0 +1,305 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import Foundation + + +/// Errors that may be thrown by ByteBuffer methods that call into Foundation. +public enum ByteBufferFoundationError: Error { + /// Attempting to encode the given string failed. + case failedToEncodeString +} + + +/* + * This is NIO's `NIOFoundationCompat` module which at the moment only adds `ByteBuffer` utility methods + * for Foundation's `Data` type. + * + * The reason that it's not in the `NIO` module is that we don't want to have any direct Foundation dependencies + * in `NIO` as Foundation is problematic for a few reasons: + * + * - its implementation is different on Linux and on macOS which means our macOS tests might be inaccurate + * - on macOS Foundation is mostly written in ObjC which means the autorelease pool might get populated + * - `swift-corelibs-foundation` (the OSS Foundation used on Linux) links the world which will prevent anyone from + * having static binaries. It can also cause problems in the choice of an SSL library as Foundation already brings + * the platforms OpenSSL in which might cause problems. + */ + +extension ByteBuffer { + /// Controls how bytes are transferred between `ByteBuffer` and other storage types. + public enum ByteTransferStrategy { + /// Force a copy of the bytes. + case copy + + /// Do not copy the bytes if at all possible. + case noCopy + + /// Use a heuristic to decide whether to copy the bytes or not. + case automatic + } + + // MARK: - Data APIs + + /// Read `length` bytes off this `ByteBuffer`, move the reader index forward by `length` bytes and return the result + /// as `Data`. + /// + /// `ByteBuffer` will use a heuristic to decide whether to copy the bytes or whether to reference `ByteBuffer`'s + /// underlying storage from the returned `Data` value. If you want manual control over the byte transferring + /// behaviour, please use `readData(length:byteTransferStrategy:)`. + /// + /// - parameters: + /// - length: The number of bytes to be read from this `ByteBuffer`. + /// - returns: A `Data` value containing `length` bytes or `nil` if there aren't at least `length` bytes readable. + public mutating func readData(length: Int) -> Data? { + return self.readData(length: length, byteTransferStrategy: .automatic) + } + + + /// Read `length` bytes off this `ByteBuffer`, move the reader index forward by `length` bytes and return the result + /// as `Data`. + /// + /// - parameters: + /// - length: The number of bytes to be read from this `ByteBuffer`. + /// - byteTransferStrategy: Controls how to transfer the bytes. See `ByteTransferStrategy` for an explanation + /// of the options. + /// - returns: A `Data` value containing `length` bytes or `nil` if there aren't at least `length` bytes readable. + public mutating func readData(length: Int, byteTransferStrategy: ByteTransferStrategy) -> Data? { + guard let result = self.getData(at: self.readerIndex, length: length, byteTransferStrategy: byteTransferStrategy) else { + return nil + } + self.moveReaderIndex(forwardBy: length) + return result + } + + /// Return `length` bytes starting at `index` and return the result as `Data`. This will not change the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// `ByteBuffer` will use a heuristic to decide whether to copy the bytes or whether to reference `ByteBuffer`'s + /// underlying storage from the returned `Data` value. If you want manual control over the byte transferring + /// behaviour, please use `getData(at:byteTransferStrategy:)`. + /// + /// - parameters: + /// - index: The starting index of the bytes of interest into the `ByteBuffer` + /// - length: The number of bytes of interest + /// - returns: A `Data` value containing the bytes of interest or `nil` if the selected bytes are not readable. + public func getData(at index: Int, length: Int) -> Data? { + return self.getData(at: index, length: length, byteTransferStrategy: .automatic) + } + + /// Return `length` bytes starting at `index` and return the result as `Data`. This will not change the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index of the bytes of interest into the `ByteBuffer` + /// - length: The number of bytes of interest + /// - byteTransferStrategy: Controls how to transfer the bytes. See `ByteTransferStrategy` for an explanation + /// of the options. + /// - returns: A `Data` value containing the bytes of interest or `nil` if the selected bytes are not readable. + public func getData(at index0: Int, length: Int, byteTransferStrategy: ByteTransferStrategy) -> Data? { + let index = index0 - self.readerIndex + guard index >= 0 && length >= 0 && index <= self.readableBytes - length else { + return nil + } + let doCopy: Bool + switch byteTransferStrategy { + case .copy: + doCopy = true + case .noCopy: + doCopy = false + case .automatic: + doCopy = length <= 256*1024 + } + + return self.withUnsafeReadableBytesWithStorageManagement { ptr, storageRef in + if doCopy { + return Data(bytes: UnsafeMutableRawPointer(mutating: ptr.baseAddress!.advanced(by: index)), + count: Int(length)) + } else { + _ = storageRef.retain() + return Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: ptr.baseAddress!.advanced(by: index)), + count: Int(length), + deallocator: .custom { _, _ in storageRef.release() }) + } + } + } + + // MARK: - Foundation String APIs + + /// Get a `String` decoding `length` bytes starting at `index` with `encoding`. This will not change the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// - parameters: + /// - index: The starting index of the bytes of interest into the `ByteBuffer`. + /// - length: The number of bytes of interest. + /// - encoding: The `String` encoding to be used. + /// - returns: A `String` value containing the bytes of interest or `nil` if the selected bytes are not readable or + /// cannot be decoded with the given encoding. + public func getString(at index: Int, length: Int, encoding: String.Encoding) -> String? { + guard let data = self.getData(at: index, length: length) else { + return nil + } + return String(data: data, encoding: encoding) + } + + /// Read a `String` decoding `length` bytes with `encoding` from the `readerIndex`, moving the `readerIndex` appropriately. + /// + /// - parameters: + /// - length: The number of bytes to read. + /// - encoding: The `String` encoding to be used. + /// - returns: A `String` value containing the bytes of interest or `nil` if the `ByteBuffer` doesn't contain enough bytes, or + /// if those bytes cannot be decoded with the given encoding. + public mutating func readString(length: Int, encoding: String.Encoding) -> String? { + guard length <= self.readableBytes else { + return nil + } + + guard let string = self.getString(at: self.readerIndex, length: length, encoding: encoding) else { + return nil + } + self.moveReaderIndex(forwardBy: length) + return string + } + + /// Write `string` into this `ByteBuffer` using the encoding `encoding`, moving the writer index forward appropriately. + /// + /// - parameters: + /// - string: The string to write. + /// - encoding: The encoding to use to encode the string. + /// - returns: The number of bytes written. + @discardableResult + public mutating func writeString(_ string: String, encoding: String.Encoding) throws -> Int { + let written = try self.setString(string, encoding: encoding, at: self.writerIndex) + self.moveWriterIndex(forwardBy: written) + return written + } + + /// Write `string` into this `ByteBuffer` at `index` using the encoding `encoding`. Does not move the writer index. + /// + /// - parameters: + /// - string: The string to write. + /// - encoding: The encoding to use to encode the string. + /// - index: The index for the first serialized byte. + /// - returns: The number of bytes written. + @discardableResult + public mutating func setString(_ string: String, encoding: String.Encoding, at index: Int) throws -> Int { + guard let data = string.data(using: encoding) else { + throw ByteBufferFoundationError.failedToEncodeString + } + return self.setBytes(data, at: index) + } + + public init(data: Data) { + self = ByteBufferAllocator().buffer(data: data) + } + + // MARK: ContiguousBytes and DataProtocol + /// Write `bytes` into this `ByteBuffer` at the writer index, moving the writer index forward appropriately. + /// + /// - parameters: + /// - bytes: The bytes to write. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func writeContiguousBytes(_ bytes: Bytes) -> Int { + let written = self.setContiguousBytes(bytes, at: self.writerIndex) + self.moveWriterIndex(forwardBy: written) + return written + } + + /// Write `bytes` into this `ByteBuffer` at `index`. Does not move the writer index. + /// + /// - parameters: + /// - bytes: The bytes to write. + /// - index: The index for the first byte. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func setContiguousBytes(_ bytes: Bytes, at index: Int) -> Int { + return bytes.withUnsafeBytes { bufferPointer in + self.setBytes(bufferPointer, at: index) + } + } + + /// Write the bytes of `data` into this `ByteBuffer` at the writer index, moving the writer index forward appropriately. + /// + /// - parameters: + /// - data: The data to write. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func writeData(_ data: D) -> Int { + let written = self.setData(data, at: self.writerIndex) + self.moveWriterIndex(forwardBy: written) + return written + } + + /// Write the bytes of `data` into this `ByteBuffer` at `index`. Does not move the writer index. + /// + /// - parameters: + /// - data: The data to write. + /// - index: The index for the first byte. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func setData(_ data: D, at index: Int) -> Int { + // DataProtocol refines RandomAccessCollection, so getting `count` must be O(1). This avoids + // intermediate allocations in the awkward case by ensuring we definitely have sufficient + // space for these writes. + self.reserveCapacity(minimumWritableBytes: data.count) + + var written = 0 + for region in data.regions { + written += self.setContiguousBytes(region, at: index + written) + } + return written + } +} + +extension ByteBufferAllocator { + /// Create a fresh `ByteBuffer` containing the bytes contained in the given `Data`. + /// + /// This will allocate a new `ByteBuffer` with enough space to fit the bytes of the `Data` and potentially + /// some extra space using Swift's default allocator. + public func buffer(data: Data) -> ByteBuffer { + var buffer = self.buffer(capacity: data.count) + buffer.writeBytes(data) + return buffer + } +} + +// MARK: - Conformances +extension ByteBufferView: ContiguousBytes {} + +extension ByteBufferView: DataProtocol { + public typealias Regions = CollectionOfOne + + public var regions: CollectionOfOne { + return .init(self) + } +} + +extension ByteBufferView: MutableDataProtocol {} + +// MARK: - Data +extension Data { + + /// Creates a `Data` from a given `ByteBuffer`. The entire readable portion of the buffer will be read. + /// - parameter buffer: The buffer to read. + public init(buffer: ByteBuffer, byteTransferStrategy: ByteBuffer.ByteTransferStrategy = .automatic) { + var buffer = buffer + self = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: byteTransferStrategy)! + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/Codable+ByteBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/Codable+ByteBuffer.swift new file mode 100644 index 00000000..b1d30bde --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/Codable+ByteBuffer.swift @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import Foundation + +extension ByteBuffer { + /// Attempts to decode the `length` bytes from `index` using the `JSONDecoder` `decoder` as `T`. + /// + /// - parameters: + /// - type: The type type that is attempted to be decoded. + /// - decoder: The `JSONDecoder` that is used for the decoding. + /// - index: The index of the first byte to decode. + /// - length: The number of bytes to decode. + /// - returns: The decoded value if successful or `nil` if there are not enough readable bytes available. + @inlinable + public func getJSONDecodable(_ type: T.Type, + decoder: JSONDecoder = JSONDecoder(), + at index: Int, length: Int) throws -> T? { + guard let data = self.getData(at: index, length: length, byteTransferStrategy: .noCopy) else { + return nil + } + return try decoder.decode(T.self, from: data) + } + + /// Reads `length` bytes from this `ByteBuffer` and then attempts to decode them using the `JSONDecoder` `decoder`. + /// + /// - parameters: + /// - type: The type type that is attempted to be decoded. + /// - decoder: The `JSONDecoder` that is used for the decoding. + /// - length: The number of bytes to decode. + /// - returns: The decoded value is successful or `nil` if there are not enough readable bytes available. + @inlinable + public mutating func readJSONDecodable(_ type: T.Type, + decoder: JSONDecoder = JSONDecoder(), + length: Int) throws -> T? { + guard let decoded = try self.getJSONDecodable(T.self, + decoder: decoder, + at: self.readerIndex, + length: length) else { + return nil + } + self.moveReaderIndex(forwardBy: length) + return decoded + } + + /// Encodes `value` using the `JSONEncoder` `encoder` and set the resulting bytes into this `ByteBuffer` at the + /// given `index`. + /// + /// - note: The `writerIndex` remains unchanged. + /// + /// - parameters: + /// - value: An `Encodable` value to encode. + /// - encoder: The `JSONEncoder` to encode `value` with. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func setJSONEncodable(_ value: T, + encoder: JSONEncoder = JSONEncoder(), + at index: Int) throws -> Int { + let data = try encoder.encode(value) + return self.setBytes(data, at: index) + } + + /// Encodes `value` using the `JSONEncoder` `encoder` and writes the resulting bytes into this `ByteBuffer`. + /// + /// If successful, this will move the writer index forward by the number of bytes written. + /// + /// - parameters: + /// - value: An `Encodable` value to encode. + /// - encoder: The `JSONEncoder` to encode `value` with. + /// - returns: The number of bytes written. + @inlinable + @discardableResult + public mutating func writeJSONEncodable(_ value: T, + encoder: JSONEncoder = JSONEncoder()) throws -> Int { + let result = try self.setJSONEncodable(value, encoder: encoder, at: self.writerIndex) + self.moveWriterIndex(forwardBy: result) + return result + } +} + +extension JSONDecoder { + /// Returns a value of the type you specify, decoded from a JSON object inside the readable bytes of a `ByteBuffer`. + /// + /// If the `ByteBuffer` does not contain valid JSON, this method throws the + /// `DecodingError.dataCorrupted(_:)` error. If a value within the JSON + /// fails to decode, this method throws the corresponding error. + /// + /// - note: The provided `ByteBuffer` remains unchanged, neither the `readerIndex` nor the `writerIndex` will move. + /// If you would like the `readerIndex` to move, consider using `ByteBuffer.readJSONDecodable(_:length:)`. + /// + /// - parameters: + /// - type: The type of the value to decode from the supplied JSON object. + /// - buffer: The `ByteBuffer` that contains JSON object to decode. + /// - returns: The decoded object. + public func decode(_ type: T.Type, from buffer: ByteBuffer) throws -> T { + return try buffer.getJSONDecodable(T.self, + decoder: self, + at: buffer.readerIndex, + length: buffer.readableBytes)! // must work, enough readable bytes + } +} + +extension JSONEncoder { + /// Writes a JSON-encoded representation of the value you supply into the supplied `ByteBuffer`. + /// + /// - parameters: + /// - value: The value to encode as JSON. + /// - buffer: The `ByteBuffer` to encode into. + public func encode(_ value: T, + into buffer: inout ByteBuffer) throws { + try buffer.writeJSONEncodable(value, encoder: self) + } + + /// Writes a JSON-encoded representation of the value you supply into a `ByteBuffer` that is freshly allocated. + /// + /// - parameters: + /// - value: The value to encode as JSON. + /// - allocator: The `ByteBufferAllocator` which is used to allocate the `ByteBuffer` to be returned. + /// - returns: The `ByteBuffer` containing the encoded JSON. + public func encodeAsByteBuffer(_ value: T, allocator: ByteBufferAllocator) throws -> ByteBuffer { + let data = try self.encode(value) + var buffer = allocator.buffer(capacity: data.count) + buffer.writeBytes(data) + return buffer + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/JSONSerialization+ByteBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/JSONSerialization+ByteBuffer.swift new file mode 100644 index 00000000..5dfc5fb2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOFoundationCompat/Sources/NIOFoundationCompat/JSONSerialization+ByteBuffer.swift @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import Foundation + +extension JSONSerialization { + + /// Attempts to derive a Foundation object from a ByteBuffer and return it as `T`. + /// + /// - parameters: + /// - buffer: The ByteBuffer being used to derive the Foundation type. + /// - options: The reading option used when the parser derives the Foundation type from the ByteBuffer. + /// - returns: The Foundation value if successful or `nil` if there was an issue creating the Foundation type. + @inlinable + public static func jsonObject(with buffer: ByteBuffer, + options opt: JSONSerialization.ReadingOptions = []) throws -> Any { + return try JSONSerialization.jsonObject(with: Data(buffer: buffer), options: opt) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/README.md new file mode 100644 index 00000000..8c22e164 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/README.md @@ -0,0 +1,37 @@ +# SwiftNIO HTTP/2 + +This project contains HTTP/2 support for Swift projects using [SwiftNIO](https://github.com/apple/swift-nio). To get started, check the [API docs](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html). + +## Building + +`swift-nio-http2` is a SwiftPM project and can be built and tested very simply: + +```bash +$ swift build +$ swift test +``` + +## Versions + +Just like the rest of the SwiftNIO family, swift-nio-http2 follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document +declaring [SwiftNIO's Public API](https://github.com/apple/swift-nio/blob/main/docs/public-api.md). + +### `swift-nio-http2` 1.x + +`swift-nio-http2` versions 1.x are a pure-Swift implementation of the HTTP/2 protocol for SwiftNIO. It's part of the SwiftNIO 2 family of repositories and does not have any dependencies besides [`swift-nio`](https://github.com/apple/swift-nio) and Swift 5. As the latest version, it lives on the [`main`](https://github.com/apple/swift-nio-http2) branch. + +To depend on `swift-nio-http2`, put the following in the `dependencies` of your `Package.swift`: + + .package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.19.2"), + +SwiftNIO HTTP2 1.21.x and later support Swift 5.4 and above. 1.20.x and earlier also support Swift 5.2 and 5.3. 1.17.x and earlier also support Swift 5.0 and 5.1. + +### `swift-nio-http2` 0.x + +The legacy `swift-nio-http` 0.x is part of the SwiftNIO 1 family of repositories and works on Swift 4.1 and newer but requires [nghttp2](https://nghttp2.org) to be installed on your system. The source code can be found on the [`nghttp2-support-branch`](https://github.com/apple/swift-nio-http2/tree/nghttp2-support-branch). + + +## Developing SwiftNIO HTTP/2 + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see [`CONTRIBUTING.md`](/CONTRIBUTING.md) in this repository. + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/DynamicHeaderTable.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/DynamicHeaderTable.swift new file mode 100644 index 00000000..7fae8484 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/DynamicHeaderTable.swift @@ -0,0 +1,129 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// Implements the dynamic part of the HPACK header table, as defined in +/// [RFC 7541 § 2.3](https://httpwg.org/specs/rfc7541.html#dynamic.table). +@usableFromInline +struct DynamicHeaderTable: NIOSendable { + public static let defaultSize = 4096 + + /// The actual table, with items looked up by index. + private var storage: HeaderTableStorage + + /// The length of the contents of the table. + var length: Int { + return self.storage.length + } + + /// The size to which the dynamic table may currently grow. Represents + /// the current maximum length signaled by the peer via a table-resize + /// value at the start of an encoded header block. + /// + /// - note: This value cannot exceed `self.maximumTableLength`. + var allowedLength: Int { + get { + return self.storage.maxSize + } + set { + self.storage.setTableSize(to: newValue) + } + } + + /// The maximum permitted size of the dynamic header table as set + /// through a SETTINGS_HEADER_TABLE_SIZE value in a SETTINGS frame. + var maximumTableLength: Int { + didSet { + if self.allowedLength > maximumTableLength { + self.allowedLength = maximumTableLength + } + } + } + + /// The number of items in the table. + var count: Int { + return self.storage.count + } + + init(maximumLength: Int = DynamicHeaderTable.defaultSize) { + self.storage = HeaderTableStorage(maxSize: maximumLength) + self.maximumTableLength = maximumLength + self.allowedLength = maximumLength // until we're told otherwise, this is what we assume the other side expects. + } + + /// Subscripts into the dynamic table alone, using a zero-based index. + subscript(i: Int) -> HeaderTableEntry { + return self.storage[i] + } + + // internal for testing + func dumpHeaders() -> String { + return self.storage.dumpHeaders(offsetBy: StaticHeaderTable.count) + } + + // internal for testing -- clears the dynamic table + mutating func clear() { + self.storage.purge(toRelease: self.storage.length) + } + + /// Searches the table for a matching header, optionally with a particular value. If + /// a match is found, returns the index of the item and an indication whether it contained + /// the matching value as well. + /// + /// Invariants: If `value` is `nil`, result `containsValue` is `false`. + /// + /// - Parameters: + /// - name: The name of the header for which to search. + /// - value: Optional value for the header to find. Default is `nil`. + /// - Returns: A tuple containing the matching index and, if a value was specified as a + /// parameter, an indication whether that value was also found. Returns `nil` + /// if no matching header name could be located. + func findExistingHeader(named name: String, value: String?) -> (index: Int, containsValue: Bool)? { + // looking for both name and value, but can settle for just name if no value + // has been provided. Return the first matching name (lowest index) in that case. + guard let value = value else { + // no `first` on AnySequence, just `first(where:)` + return self.storage.firstIndex(matching: name).map { ($0, false) } + } + + // If we have a value, locate the index of the lowest header which contains that + // value, but if no value matches, return the index of the lowest header with a + // matching name alone. + switch self.storage.closestMatch(name: name, value: value) { + case .full(let index): + return (index, true) + case .partial(let index): + return (index, false) + case .none: + return nil + } + } + + /// Appends a header to the table. Note that if this succeeds, the new item's index + /// is always zero. + /// + /// This call may result in an empty table, as per RFC 7541 § 4.4: + /// > "It is not an error to attempt to add an entry that is larger than the maximum size; + /// > an attempt to add an entry larger than the maximum size causes the table to be + /// > emptied of all existing entries and results in an empty table." + /// + /// - Parameters: + /// - name: A String representing the name of the header field. + /// - value: A String representing the value of the header field. + /// - Returns: `true` if the header was added to the table, `false` if not. + mutating func addHeader(named name: String, value: String) { + self.storage.add(name: name, value: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKDecoder.swift new file mode 100644 index 00000000..548933c3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKDecoder.swift @@ -0,0 +1,261 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// An `HPACKDecoder` maintains its own dynamic header table and uses that to +/// decode indexed HTTP headers, along with Huffman-encoded strings and +/// HPACK-encoded integers. +/// +/// There are two pieces of shared state: the dynamic header table and an +/// internal `ByteBuffer` used for decode operations. Each decode operation +/// will update the header table as described in RFC 7541, appending and +/// evicting items as described there. +/// +/// - note: This type is not thread-safe. It is designed to be owned and operated +/// by a single HTTP/2 stream, operating on a single NIO `EventLoop`. +public struct HPACKDecoder: NIOSendable { + public static var maxDynamicTableSize: Int { + return DynamicHeaderTable.defaultSize + } + + /// The default value of the maximum header list size for the decoder. + /// + /// This value is somewhat arbitrary, but 16kB should be sufficiently large to decode all reasonably + /// sized header lists. + public static var defaultMaxHeaderListSize: Int { + return 1<<14 + } + + // private but tests + var headerTable: IndexedHeaderTable + + var dynamicTableLength: Int { + return headerTable.dynamicTableLength + } + + /// The current allowed length of the dynamic portion of the header table. May be + /// less than the current protocol-assigned maximum supplied by a SETTINGS frame. + public private(set) var allowedDynamicTableLength: Int { + get { return self.headerTable.dynamicTableAllowedLength } + set { self.headerTable.dynamicTableAllowedLength = newValue } + } + + /// The maximum size of the header list. + public var maxHeaderListSize: Int + + /// A string value discovered in a HPACK buffer. The value can either indicate an entry + /// in the header table index or the start of an inline literal string. + enum HPACKString { + case indexed(index: Int) + case literal + + init(fromEncodedInteger value: Int) { + switch value { + case 0: + self = .literal + default: + self = .indexed(index: value) + } + } + } + + /// The maximum size of the dynamic table as set by the enclosing protocol. This is defined in RFC 7541 + /// to be the sum of [name-octet-count] + [value-octet-count] + 32 for + /// each header it contains. + public var maxDynamicTableLength: Int { + get { return headerTable.maxDynamicTableLength } + /* private but tests */ + set { headerTable.maxDynamicTableLength = newValue } + } + + /// Creates a new decoder + /// + /// - Parameter maxDynamicTableSize: Maximum allowed size of the dynamic header table. + public init(allocator: ByteBufferAllocator, maxDynamicTableSize: Int = HPACKDecoder.maxDynamicTableSize) { + self.init(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize, maxHeaderListSize: HPACKDecoder.defaultMaxHeaderListSize) + } + + /// Creates a new decoder + /// + /// - Parameter maxDynamicTableSize: Maximum allowed size of the dynamic header table. + /// - Parameter maxHeaderListSize: Maximum allowed size of a decoded header list. + public init(allocator: ByteBufferAllocator, maxDynamicTableSize: Int, maxHeaderListSize: Int) { + precondition(maxHeaderListSize > 0, "Max header list size must be positive!") + self.headerTable = IndexedHeaderTable(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize) + self.maxHeaderListSize = maxHeaderListSize + } + + /// Reads HPACK encoded header data from a `ByteBuffer`. + /// + /// It is expected that the buffer cover only the bytes of the header list, i.e. + /// that this is in fact a slice containing only the payload bytes of a + /// `HEADERS` or `CONTINUATION` frame. + /// + /// - Parameter buffer: A byte buffer containing the encoded header bytes. + /// - Returns: An array of (name, value) pairs. + /// - Throws: HpackDecoder.Error in the event of a decode failure. + public mutating func decodeHeaders(from buffer: inout ByteBuffer) throws -> HPACKHeaders { + let readerIndex = buffer.readerIndex + + do { + var headers: [HPACKHeader] = [] + headers.reserveCapacity(16) + + var listSize = 0 + + while buffer.readableBytes > 0 { + switch try self.decodeHeader(from: &buffer) { + case .tableSizeChange: + // RFC 7541 § 4.2 : + // + // 2. "This dynamic table size update MUST occur at the beginning of the first header block + // following the change to the dynamic table size." + guard headers.count == 0 else { + // If our decode buffer has any data in it, then this is out of place. + // Treat it as an invalid input + throw NIOHPACKErrors.IllegalDynamicTableSizeChange() + } + case .header(let header): + listSize += header.size + guard listSize <= self.maxHeaderListSize else { + throw NIOHPACKErrors.MaxHeaderListSizeViolation() + } + + headers.append(header) + } + } + + return HPACKHeaders(headers: headers) + } catch { + buffer.moveReaderIndex(to: readerIndex) + throw error + } + } + + enum DecodeResult { + case tableSizeChange + case header(HPACKHeader) + } + + private mutating func decodeHeader(from buffer: inout ByteBuffer) throws -> DecodeResult { + // peek at the first byte to decide how many significant bits of that byte we + // will need to include in our decoded integer. Some values use a one-bit prefix, + // some use two, or four. + // This one-byte read is guaranteed safe because `decodeHeaders(from:)` only calls into + // this function if at least one byte is available to read. + let initial: UInt8 = buffer.getInteger(at: buffer.readerIndex)! + switch initial { + case let x where x & 0b1000_0000 == 0b1000_0000: + // 0b1xxxxxxx -- one-bit prefix, seven bits of value + // purely-indexed header field/value + let hidx = try buffer.readEncodedInteger(withPrefix: 7) + guard hidx != 0 else { + throw NIOHPACKErrors.ZeroHeaderIndex() + } + return try .header(self.decodeIndexedHeader(from: Int(hidx))) + + case let x where x & 0b1100_0000 == 0b0100_0000: + // 0b01xxxxxx -- two-bit prefix, six bits of value + // literal header with possibly-indexed name + let hidx = try buffer.readEncodedInteger(withPrefix: 6) + return try .header(self.decodeLiteralHeader(from: &buffer, headerName: HPACKString(fromEncodedInteger: hidx), addToIndex: true)) + + case let x where x & 0b1111_0000 == 0b0000_0000: + // 0b0000xxxx -- four-bit prefix, four bits of value + // literal header with possibly-indexed name, not added to dynamic table + let hidx = try buffer.readEncodedInteger(withPrefix: 4) + var header = try self.decodeLiteralHeader(from: &buffer, headerName: HPACKString(fromEncodedInteger: hidx), addToIndex: false) + header.indexing = .nonIndexable + return .header(header) + + case let x where x & 0b1111_0000 == 0b0001_0000: + // 0b0001xxxx -- four-bit prefix, four bits of value + // literal header with possibly-indexed name, never added to dynamic table nor + // rewritten by proxies + let hidx = try buffer.readEncodedInteger(withPrefix: 4) + var header = try self.decodeLiteralHeader(from: &buffer, headerName: HPACKString(fromEncodedInteger: hidx), addToIndex: false) + header.indexing = .neverIndexed + return .header(header) + + case let x where x & 0b1110_0000 == 0b0010_0000: + // 0b001xxxxx -- three-bit prefix, five bits of value + // dynamic header table size update + let newMaxLength = try Int(buffer.readEncodedInteger(withPrefix: 5)) + + // RFC 7541 § 4.2 : + // + // 1. "the chosen size MUST stay lower than or equal to the maximum set by the protocol." + guard newMaxLength <= self.headerTable.maxDynamicTableLength else { + throw NIOHPACKErrors.InvalidDynamicTableSize(requestedSize: newMaxLength, allowedSize: self.headerTable.maxDynamicTableLength) + } + + self.allowedDynamicTableLength = newMaxLength + return .tableSizeChange + + default: + throw NIOHPACKErrors.InvalidHeaderStartByte(byte: initial) + } + } + + private mutating func decodeIndexedHeader(from hidx: Int) throws -> HPACKHeader { + let (name, value) = try self.headerTable.header(at: hidx) + return HPACKHeader(name: name, value: value) + } + + private mutating func decodeLiteralHeader(from buffer: inout ByteBuffer, headerName: HPACKString, + addToIndex: Bool) throws -> HPACKHeader { + let name: String + + switch headerName { + case .indexed(let idx): + (name, _) = try self.headerTable.header(at: idx) + case .literal: + name = try self.readEncodedString(from: &buffer) + guard name.utf8.count > 0 else { + // This isn't explicitly forbidden by RFC 7541, but it *is* forbidden by RFC 7230. + throw NIOHPACKErrors.EmptyLiteralHeaderFieldName() + } + } + + let value = try self.readEncodedString(from: &buffer) + + if addToIndex { + try headerTable.add(headerNamed: name, value: value) + } + + return HPACKHeader(name: name, value: value) + } + + private mutating func readEncodedString(from buffer: inout ByteBuffer) throws -> String { + // peek to read the encoding bit + guard let initialByte: UInt8 = buffer.getInteger(at: buffer.readerIndex) else { + throw NIOHPACKErrors.InsufficientInput() + } + let huffmanEncoded = initialByte & 0x80 == 0x80 + + // read the length; there's a seven-bit prefix here (one-bit encoding flag) + let len = try Int(buffer.readEncodedInteger(withPrefix: 7)) + guard len <= buffer.readableBytes else { + throw NIOHPACKErrors.StringLengthBeyondPayloadSize(length: len, available: buffer.readableBytes) + } + + if huffmanEncoded { + return try buffer.readHuffmanEncodedString(length: len) + } else { + // This force-unwrap is safe as we have checked above that len is less than or equal to the buffer readable bytes. + return buffer.readString(length: len)! + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKEncoder.swift new file mode 100644 index 00000000..7b5ea0d0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKEncoder.swift @@ -0,0 +1,338 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// An `HPACKEncoder` maintains its own dynamic header table and uses that to +/// encode HTTP headers to an internal byte buffer. +/// +/// This encoder functions as an accumulator: each encode operation will append +/// bytes to a buffer maintained by the encoder, which must be cleared using +/// `reset()` before the encode can be re-used. It maintains a header table for +/// outbound header indexing, and will update the header table as described in +/// RFC 7541, appending and evicting items as described there. +public struct HPACKEncoder { + /// The default size of the encoder's dynamic header table. + public static var defaultDynamicTableSize: Int { return DynamicHeaderTable.defaultSize } + private static let defaultDataBufferSize = 128 + + public struct HeaderDefinition: NIOSendable { + var name: String + var value: String + var indexing: HPACKIndexing + } + + private enum EncoderState { + case idle + case resized(smallestMaxTableSize: Int?) + case encoding + } + + // private but tests + var headerIndexTable: IndexedHeaderTable + + private var state: EncoderState + private var buffer: ByteBuffer + + /// Whether to use Huffman encoding. + public let useHuffmanEncoding: Bool + + /// The current size of the dynamic table. + /// + /// This is defined as the sum of [name] + [value] + 32 for each header. + public var dynamicTableSize: Int { + return self.headerIndexTable.dynamicTableLength + } + + /// The current maximum size to which the dynamic header table may grow. + public private(set) var allowedDynamicTableSize: Int { + get { return self.headerIndexTable.dynamicTableAllowedLength } + set { self.headerIndexTable.dynamicTableAllowedLength = newValue } + } + + /// The hard maximum size of the dynamic header table, set via an HTTP/2 + /// SETTINGS frame. + public var maximumDynamicTableSize: Int { + get { return self.headerIndexTable.maxDynamicTableLength } + set { self.headerIndexTable.maxDynamicTableLength = newValue } + } + + /// Sets the maximum size for the dynamic table and encodes the new value + /// at the start of the current packed header block to send to the peer. + /// + /// - Parameter size: The new maximum size for the dynamic header table. + /// - Throws: If the encoder is currently in use, or if the requested size + /// exceeds the maximum value negotiated with the peer. + public mutating func setDynamicTableSize(_ size: Int) throws { + guard size <= self.maximumDynamicTableSize else { + throw NIOHPACKErrors.InvalidDynamicTableSize(requestedSize: size, allowedSize: self.maximumDynamicTableSize) + } + guard size != self.allowedDynamicTableSize else { + // no need to change anything + return + } + + switch self.state { + case .idle: + self.state = .resized(smallestMaxTableSize: nil) + case .resized(nil) where size > self.allowedDynamicTableSize: + self.state = .resized(smallestMaxTableSize: self.allowedDynamicTableSize) + case .resized(let smallest?) where size < smallest: + self.state = .resized(smallestMaxTableSize: nil) + case .encoding: + throw NIOHPACKErrors.EncoderAlreadyActive() + default: + // we don't need to change smallest recorded resize value + break + } + + // set the new size on our dynamic table + self.allowedDynamicTableSize = size + } + + /// Initializer and returns a new HPACK encoder. + /// + /// - Parameters: + /// - allocator: An allocator for `ByteBuffer`s. + /// - maxDynamicTableSize: An initial maximum size for the encoder's dynamic header table. + public init(allocator: ByteBufferAllocator, useHuffmanEncoding: Bool = true, maxDynamicTableSize: Int = HPACKEncoder.defaultDynamicTableSize) { + self.headerIndexTable = IndexedHeaderTable(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize) + self.useHuffmanEncoding = useHuffmanEncoding + self.state = .idle + + // In my ideal world this allocation would be of size 0, but we need to have it be a little bit bigger to support the incremental encoding + // mode. I want to remove it: see https://github.com/apple/swift-nio-http2/issues/85. + self.buffer = allocator.buffer(capacity: 128) + } + + /// Sets up the encoder to begin encoding a new header block. + /// + /// - Parameter allocator: Used to allocate the `ByteBuffer` that will contain the encoded + /// bytes, obtained from `endEncoding()`. + public mutating func beginEncoding(allocator: ByteBufferAllocator) throws { + if case .encoding = self.state { + throw NIOHPACKErrors.EncoderAlreadyActive() + } + + self.buffer.clear() + + switch self.state { + case .idle: + self.state = .encoding + case .resized(nil): + // one resize + self.buffer.write(encodedInteger: UInt(self.allowedDynamicTableSize), prefix: 5, prefixBits: 0x20) + self.state = .encoding + case let .resized(smallestSize?): + // two resizes, one smaller than the other + self.buffer.write(encodedInteger: UInt(smallestSize), prefix: 5, prefixBits: 0x20) + self.buffer.write(encodedInteger: UInt(self.allowedDynamicTableSize), prefix: 5, prefixBits: 0x20) + self.state = .encoding + default: + break + } + } + + /// Finishes encoding the current header block and returns the resulting buffer. + public mutating func endEncoding() throws -> ByteBuffer { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + + self.state = .idle + return self.buffer + } + + /// A one-shot encoder that writes to a provided buffer. + /// + /// In general this encoding mechanism is more efficient than the incremental one. + public mutating func encode(headers: HPACKHeaders, to buffer: inout ByteBuffer) throws { + if case .encoding = self.state { + throw NIOHPACKErrors.EncoderAlreadyActive() + } + + swap(&self.buffer, &buffer) + defer { + swap(&self.buffer, &buffer) + self.state = .idle + } + + switch self.state { + case .idle: + self.state = .encoding + case .resized(nil): + // one resize + self.buffer.write(encodedInteger: UInt(self.allowedDynamicTableSize), prefix: 5, prefixBits: 0x20) + self.state = .encoding + case let .resized(smallestSize?): + // two resizes, one smaller than the other + self.buffer.write(encodedInteger: UInt(smallestSize), prefix: 5, prefixBits: 0x20) + self.buffer.write(encodedInteger: UInt(self.allowedDynamicTableSize), prefix: 5, prefixBits: 0x20) + self.state = .encoding + default: + break + } + + try self.append(headers: headers) + } + + /// Appends() headers in the default fashion: indexed if possible, literal+indexable if not. + /// + /// - Parameter headers: A sequence of key/value pairs representing HTTP headers. + public mutating func append(headers: S) throws where S.Element == (name: String, value: String) { + try self.append(headers: headers.lazy.map { HeaderDefinition(name: $0.0, value: $0.1, indexing: .indexable) }) + } + + /// Appends headers with their specified indexability. + /// + /// - Parameter headers: A sequence of key/value/indexability tuples representing HTTP headers. + public mutating func append(headers: S) throws where S.Element == HeaderDefinition { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + + for header in headers { + switch header.indexing { + case .indexable: + try self._appendIndexed(header: header.name, value: header.value) + case .nonIndexable: + self._appendNonIndexed(header: header.name, value: header.value) + case .neverIndexed: + self._appendNeverIndexed(header: header.name, value: header.value) + } + } + } + + /// Appends a set of headers with their associated indexability. + /// + /// - Parameter headers: A `HPACKHeaders` structure containing a set of HTTP/2 header values. + public mutating func append(headers: HPACKHeaders) throws { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + + for header in headers { + switch header.indexable { + case .indexable: + try self._appendIndexed(header: header.name, value: header.value) + case .nonIndexable: + self._appendNonIndexed(header: header.name, value: header.value) + case .neverIndexed: + self._appendNeverIndexed(header: header.name, value: header.value) + } + } + } + + /// Appends a header/value pair, using indexed names/values if possible. If no indexed pair is available, + /// it will use an indexed header and literal value, or a literal header and value. The name/value pair + /// will be indexed for future use. + public mutating func append(header name: String, value: String) throws { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + try self._appendIndexed(header: name, value: value) + } + + /// Returns `true` if the item needs to be added to the header table + private mutating func _appendIndexed(header name: String, value: String) throws { + if let (index, hasValue) = self.headerIndexTable.firstHeaderMatch(for: name, value: value) { + if hasValue { + // purely indexed. Nice & simple. + self.buffer.write(encodedInteger: UInt(index), prefix: 7, prefixBits: 0x80) + // everything is indexed-- nothing more to do! + return + } else { + // no value, so append the index to represent the name, followed by the value's + // length + self.buffer.write(encodedInteger: UInt(index), prefix: 6, prefixBits: 0x40) + // now encode and append the value string + self.appendEncodedString(value) + } + } else { + // no indexed name or value. Have to add them both, with a zero index. + _ = self.buffer.writeInteger(UInt8(0x40)) + self.appendEncodedString(name) + self.appendEncodedString(value) + } + + // add to the header table + try self.headerIndexTable.add(headerNamed: name, value: value) + } + + private mutating func appendEncodedString(_ string: String) { + let utf8 = string.utf8 + + // encode the value + if self.useHuffmanEncoding { + // problem: we need to encode the length before the encoded bytes, so we can't just receive the length + // after encoding to the target buffer itself. So we have to determine the length first. + self.buffer.write(encodedInteger: UInt(ByteBuffer.huffmanEncodedLength(of: utf8)), prefix: 7, prefixBits: 0x80) + self.buffer.writeHuffmanEncoded(bytes: utf8) + } else { + self.buffer.write(encodedInteger: UInt(utf8.count), prefix: 7, prefixBits: 0) + self.buffer.writeBytes(utf8) + } + } + + /// Appends a header that is *not* to be entered into the dynamic header table, but allows that + /// stipulation to be overriden by a proxy server/rewriter. + public mutating func appendNonIndexed(header: String, value: String) throws { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + self._appendNonIndexed(header: header, value: value) + } + + private mutating func _appendNonIndexed(header: String, value: String) { + if let (index, _) = self.headerIndexTable.firstHeaderMatch(for: header, value: nil) { + // we actually don't care if it has a value in this instance; we're only indexing the + // name. + self.buffer.write(encodedInteger: UInt(index), prefix: 4, prefixBits: 0) + // now append the value + self.appendEncodedString(value) + } else { + self.buffer.writeInteger(UInt8(0)) // top 4 bits are zero, and index is zero (no index) + self.appendEncodedString(header) + self.appendEncodedString(value) + } + } + + /// Appends a header that is *never* indexed, preventing even rewriting proxies from doing so. + public mutating func appendNeverIndexed(header: String, value: String) throws { + guard case .encoding = self.state else { + throw NIOHPACKErrors.EncoderNotStarted() + } + self._appendNeverIndexed(header: header, value: value) + } + + private mutating func _appendNeverIndexed(header: String, value: String) { + if let (index, _) = self.headerIndexTable.firstHeaderMatch(for: header, value: nil) { + // we only use the index in this instance + self.buffer.write(encodedInteger: UInt(index), prefix: 4, prefixBits: 0x10) + // now append the value + self.appendEncodedString(value) + } else { + self.buffer.writeInteger(UInt8(0x10)) // prefix bits + zero index + self.appendEncodedString(header) + self.appendEncodedString(value) + } + } +} + +// The `@unchecked` is needed because at the time of writing `NIOCore` didn't have `Sendable` support. +#if swift(>=5.5) && canImport(_Concurrency) +extension HPACKEncoder: @unchecked Sendable { + +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKErrors.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKErrors.swift new file mode 100644 index 00000000..d818c64f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKErrors.swift @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +public protocol NIOHPACKError : Error, Equatable { } + +/// Errors raised by NIOHPACK while encoding/decoding data. +public enum NIOHPACKErrors { + /// An indexed header referenced an index that doesn't exist in our + /// header tables. + public struct InvalidHeaderIndex : NIOHPACKError { + /// The offending index. + public let suppliedIndex: Int + + /// The highest index we have available. + public let availableIndex: Int + } + + /// A header block indicated an indexed header with no accompanying + /// value, but the index referenced an entry with no value of its own + /// e.g. one of the many valueless items in the static header table. + public struct IndexedHeaderWithNoValue : NIOHPACKError { + /// The offending index. + public let index: Int + } + + /// An encoded string contained an invalid length that extended + /// beyond its frame's payload size. + public struct StringLengthBeyondPayloadSize : NIOHPACKError { + /// The length supplied. + public let length: Int + + /// The available number of bytes. + public let available: Int + } + + /// Decoded string data could not be parsed as valid UTF-8. + public struct InvalidUTF8Data : NIOHPACKError { + /// The offending bytes. + public let bytes: ByteBuffer + } + + /// The start byte of a header did not match any format allowed by + /// the HPACK specification. + public struct InvalidHeaderStartByte : NIOHPACKError { + /// The offending byte. + public let byte: UInt8 + } + + /// A dynamic table size update specified an invalid size. + public struct InvalidDynamicTableSize : NIOHPACKError { + /// The offending size. + public let requestedSize: Int + + /// The actual maximum size that was set by the protocol. + public let allowedSize: Int + } + + /// A dynamic table size update was found outside its allowed place. + /// They may only be included at the start of a header block. + public struct IllegalDynamicTableSizeChange : NIOHPACKError {} + + /// A new header could not be added to the dynamic table. Usually + /// this means the header itself is larger than the current + /// dynamic table size. + public struct FailedToAddIndexedHeader : NIOHPACKError where Name.Element == UInt8, Value.Element == UInt8 { + /// The table size required to be able to add this header to the table. + public let bytesNeeded: Int + + /// The name of the header that could not be written. + public let name: Name + + /// The value of the header that could not be written. + public let value: Value + + public static func == (lhs: NIOHPACKErrors.FailedToAddIndexedHeader, rhs: NIOHPACKErrors.FailedToAddIndexedHeader) -> Bool { + guard lhs.bytesNeeded == rhs.bytesNeeded else { + return false + } + return lhs.name.elementsEqual(rhs.name) && lhs.value.elementsEqual(rhs.value) + } + } + + /// Ran out of input bytes while decoding. + public struct InsufficientInput : NIOHPACKError {} + + /// HPACK encoder asked to begin a new header block while partway through encoding + /// another block. + public struct EncoderAlreadyActive : NIOHPACKError {} + + /// HPACK encoder asked to append a header without first calling `beginEncoding(allocator:)`. + public struct EncoderNotStarted : NIOHPACKError {} + + /// HPACK decoder asked to decode an indexed header with index zero. + public struct ZeroHeaderIndex: NIOHPACKError { + public init() { } + } + + /// HPACK decoder asked to decode a header list that would violate the configured + /// max header list size. + public struct MaxHeaderListSizeViolation: NIOHPACKError { + public init() { } + } + + /// HPACK decoder asked to decode a header field name that was empty. + public struct EmptyLiteralHeaderFieldName: NIOHPACKError { + public init() { } + } + + /// The integer being decoded is not representable by this implementation. + public struct UnrepresentableInteger: NIOHPACKError { + public init() {} + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKHeader.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKHeader.swift new file mode 100644 index 00000000..eb599d67 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HPACKHeader.swift @@ -0,0 +1,665 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHTTP1 + +/// Very similar to `NIOHTTP1.HTTPHeaders`, but with extra data for storing indexing +/// information. +public struct HPACKHeaders: ExpressibleByDictionaryLiteral, NIOSendable { + /// The maximum size of the canonical connection header value array to use when removing + /// connection headers during `HTTPHeaders` normalisation. When using an array the removal + /// is O(H·C) where H is the length of headers to noramlize and C is the length of the + /// connection header value array. + /// + /// Beyond this limit we construct a set of the connection header values to reduce the + /// complexity to O(H). + /// + /// We use an array for small connection header lists as it is cheaper (values don't need to be + /// hashed and constructing a set incurs an additional allocation). The value of 32 was picked + /// as the crossover point where using an array became more expensive than using a set when + /// running the `hpackheaders_normalize_httpheaders_removing_10k_conn_headers` performance test + /// with varying input sizes. + @usableFromInline + static let connectionHeaderValueArraySizeLimit = 32 + + @usableFromInline + internal var headers: [HPACKHeader] + + // see 8.1.2.2. Connection-Specific Header Fields in RFC 7540 + @usableFromInline + static let illegalHeaders: [String] = ["connection", "keep-alive", "proxy-connection", + "transfer-encoding", "upgrade"] + + /// Constructor that can be used to map between `HTTPHeaders` and `HPACKHeaders` types. + @inlinable + public init(httpHeaders: HTTPHeaders, normalizeHTTPHeaders: Bool) { + if normalizeHTTPHeaders { + self.headers = httpHeaders.map { HPACKHeader(name: $0.name.lowercased(), value: $0.value) } + + let connectionHeaderValue = httpHeaders[canonicalForm: "connection"] + + // Above a limit we use a set rather than scanning the connection header value array. + // See `Self.connectionHeaderValueArraySizeLimit`. + if connectionHeaderValue.count > Self.connectionHeaderValueArraySizeLimit { + var headersToRemove = Set(connectionHeaderValue) + // Since we have a set we can just merge in the illegal headers. + headersToRemove.formUnion(Self.illegalHeaders.lazy.map { $0[...] }) + self.headers.removeAll { header in + headersToRemove.contains(header.name[...]) + } + } else { + self.headers.removeAll { header in + connectionHeaderValue.contains(header.name[...]) || + HPACKHeaders.illegalHeaders.contains(header.name) + } + } + } else { + self.headers = httpHeaders.map { HPACKHeader(name: $0.name, value: $0.value) } + } + } + + /// Constructor that can be used to map between `HTTPHeaders` and `HPACKHeaders` types. + @inlinable + public init(httpHeaders: HTTPHeaders) { + self.init(httpHeaders: httpHeaders, normalizeHTTPHeaders: true) + } + + /// Construct a `HPACKHeaders` structure. + /// + /// The indexability of all headers is assumed to be the default, i.e. indexable and + /// rewritable by proxies. + /// + /// - parameters + /// - headers: An initial set of headers to use to populate the header block. + @inlinable + public init(_ headers: [(String, String)] = []) { + self.headers = headers.map { HPACKHeader(name: $0.0, value: $0.1) } + } + + /// Construct a `HPACKHeaders` structure. + /// + /// The indexability of all headers is assumed to be the default, i.e. indexable and + /// rewritable by proxies. + /// + /// - Parameter elements: name, value pairs provided by a dictionary literal. + @inlinable + public init(dictionaryLiteral elements: (String, String)...) { + self.init(elements) + } + + /// Construct a `HPACKHeaders` structure. + /// + /// The indexability of all headers is assumed to be the default, i.e. indexable and + /// rewritable by proxies. + /// + /// - parameters + /// - headers: An initial set of headers to use to populate the header block. + /// - allocator: The allocator to use to allocate the underlying storage. + @available(*, deprecated, renamed: "init(_:)") + public init(_ headers: [(String, String)] = [], allocator: ByteBufferAllocator) { + // We no longer use an allocator so we don't need this method anymore. + self.init(headers) + } + + /// Internal initializer to make things easier for unit tests. + @inlinable + init(fullHeaders: [(HPACKIndexing, String, String)]) { + self.headers = fullHeaders.map { HPACKHeader(name: $0.1, value: $0.2, indexing: $0.0) } + } + + /// Internal initializer for use in HPACK decoding. + @inlinable + init(headers: [HPACKHeader]) { + self.headers = headers + } + + /// Add a header name/value pair to the block. + /// + /// This method is strictly additive: if there are other values for the given header name + /// already in the block, this will add a new entry. `add` performs case-insensitive + /// comparisons on the header field name. + /// + /// - Parameter name: The header field name. This must be an ASCII string. For HTTP/2 lowercase + /// header names are strongly encouraged. + /// - Parameter value: The header field value to add for the given name. + @inlinable + public mutating func add(name: String, value: String, indexing: HPACKIndexing = .indexable) { + precondition(!name.utf8.contains(where: { !$0.isASCII }), "name must be ASCII") + self.headers.append(HPACKHeader(name: name, value: value, indexing: indexing)) + } + + /// Add a sequence of header name/value pairs to the block. + /// + /// This method is strictly additive: if there are other entries with the same header + /// name already in the block, this will add new entries. + /// + /// - Parameter contentsOf: The sequence of header name/value pairs. Header names must be ASCII + /// strings. For HTTP/2 lowercase header names are strongly recommended. + @inlinable + public mutating func add(contentsOf other: S, indexing: HPACKIndexing = .indexable) where S.Element == (String, String) { + self.reserveCapacity(self.headers.count + other.underestimatedCount) + for (name, value) in other { + self.add(name: name, value: value, indexing: indexing) + } + } + + /// Add a sequence of header name/value/indexing triplet to the block. + /// + /// This method is strictly additive: if there are other entries with the same header + /// name already in the block, this will add new entries. + /// + /// - Parameter contentsOf: The sequence of header name/value/indexing triplets. Header names + /// must be ASCII strings. For HTTP/2 lowercase header names are strongly recommended. + @inlinable + public mutating func add(contentsOf other: S) where S.Element == HPACKHeaders.Element { + self.reserveCapacity(self.headers.count + other.underestimatedCount) + for (name, value, indexing) in other { + self.add(name: name, value: value, indexing: indexing) + } + } + + /// Add a header name/value pair to the block, replacing any previous values for the + /// same header name that are already in the block. + /// + /// This is a supplemental method to `add` that essentially combines `remove` and `add` + /// in a single function. It can be used to ensure that a header block is in a + /// well-defined form without having to check whether the value was previously there. + /// Like `add`, this method performs case-insensitive comparisons of the header field + /// names. + /// + /// - Parameter name: The header field name. For maximum compatibility this should be an + /// ASCII string. For future-proofing with HTTP/2 lowercase header names are strongly + /// recommended. + /// - Parameter value: The header field value to add for the given name. + @inlinable + public mutating func replaceOrAdd(name: String, value: String, indexing: HPACKIndexing = .indexable) { + self.remove(name: name) + self.add(name: name, value: value, indexing: indexing) + } + + /// Remove all values for a given header name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. + /// + /// - Parameter name: The name of the header field to remove from the block. + @inlinable + public mutating func remove(name nameToRemove: String) { + self.headers.removeAll { header in + return nameToRemove.isEqualCaseInsensitiveASCIIBytes(to: header.name) + } + } + + /// Retrieve all of the values for a given header field name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. It + /// does not return a maximally-decomposed list of the header fields, but instead + /// returns them in their original representation: that means that a comma-separated + /// header field list may contain more than one entry, some of which contain commas + /// and some do not. If you want a representation of the header fields suitable for + /// performing computation on, consider `getCanonicalForm`. + /// + /// - Parameter name: The header field name whose values are to be retrieved. + /// - Returns: A list of the values for that header field name. + @inlinable + public subscript(name: String) -> [String] { + guard !self.headers.isEmpty else { + return [] + } + + var array: [String] = [] + for header in self.headers { + if header.name.isEqualCaseInsensitiveASCIIBytes(to: name) { + array.append(header.value) + } + } + + return array + } + + /// Retrieves the first value for a given header field name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. It + /// does not return the first value from a maximally-decomposed list of the header fields, + /// but instead returns the first value from the original representation: that means + /// that a comma-separated header field list may contain more than one entry, some of + /// which contain commas and some do not. If you want a representation of the header fields + /// suitable for performing computation on, consider `getCanonicalForm`. + /// + /// - Parameter name: The header field name whose first value should be retrieved. + /// - Returns: The first value for the header field name. + @inlinable + public func first(name: String) -> String? { + guard !self.headers.isEmpty else { + return nil + } + + return self.headers.first { $0.name.isEqualCaseInsensitiveASCIIBytes(to: name) }?.value + } + + /// Checks if a header is present. + /// + /// - parameters: + /// - name: The name of the header + /// - returns: `true` if a header with the name (and value) exists, `false` otherwise. + @inlinable + public func contains(name: String) -> Bool { + guard !self.headers.isEmpty else { + return false + } + + for header in self.headers { + if header.name.isEqualCaseInsensitiveASCIIBytes(to: name) { + return true + } + } + return false + } + + /// Retrieves the header values for the given header field in "canonical form": that is, + /// splitting them on commas as extensively as possible such that multiple values received on the + /// one line are returned as separate entries. Also respects the fact that Set-Cookie should not + /// be split in this way. + /// + /// - Parameter name: The header field name whose values are to be retrieved. + /// - Returns: A list of the values for that header field name. + @inlinable + public subscript(canonicalForm name: String) -> [String] { + let result = self[name] + guard result.count > 0 else { + return [] + } + + // It's not safe to split Set-Cookie on comma. + if name.isEqualCaseInsensitiveASCIIBytes(to: "set-cookie") { + return result + } + + // We slightly overcommit here to try to reduce the amount of resizing we do. + var trimmedResults: [String] = [] + trimmedResults.reserveCapacity(result.count * 4) + + // This loop operates entirely on the UTF-8 views. This vastly reduces the cost of this slicing and dicing. + for field in result { + for entry in field.utf8._lazySplit(separator: UInt8(ascii: ",")) { + let trimmed = entry._trimWhitespace() + if trimmed.isEmpty { + continue + } + + // This constructor pair kinda sucks, but you can't create a String from a slice of UTF8View as + // cheaply as you can with a Substring, so we go through that initializer instead. + trimmedResults.append(String(Substring(trimmed))) + } + } + + return trimmedResults + } + + /// Special internal function for use by tests. + internal subscript(position: Int) -> (String, String) { + precondition(position < self.headers.endIndex, "Position \(position) is beyond bounds of \(self.headers.endIndex)") + let header = self.headers[position] + return (header.name, header.value) + } +} + +extension HPACKHeaders { + /// The total number of headers that can be contained without allocating new storage. + @inlinable + public var capacity: Int { + return self.headers.capacity + } + + /// Reserves enough space to store the specified number of headers. + /// + /// - Parameter minimumCapacity: The requested number of headers to store. + @inlinable + public mutating func reserveCapacity(_ minimumCapacity: Int) { + self.headers.reserveCapacity(minimumCapacity) + } +} + +extension HPACKHeaders: RandomAccessCollection { + public typealias Element = (name: String, value: String, indexable: HPACKIndexing) + + public struct Index: Comparable { + @usableFromInline + let _base: Array.Index + + @inlinable + init(_base: Array.Index) { + self._base = _base + } + + @inlinable + public static func < (lhs: Index, rhs: Index) -> Bool { + return lhs._base < rhs._base + } + } + + @inlinable + public var startIndex: HPACKHeaders.Index { + return .init(_base: self.headers.startIndex) + } + + @inlinable + public var endIndex: HPACKHeaders.Index { + return .init(_base: self.headers.endIndex) + } + + @inlinable + public func index(before i: HPACKHeaders.Index) -> HPACKHeaders.Index { + return .init(_base: self.headers.index(before: i._base)) + } + + @inlinable + public func index(after i: HPACKHeaders.Index) -> HPACKHeaders.Index { + return .init(_base: self.headers.index(after: i._base)) + } + + @inlinable + public subscript(position: HPACKHeaders.Index) -> Element { + let element = self.headers[position._base] + return (name: element.name, value: element.value, indexable: element.indexing) + } + + // Why are we providing an `Iterator` when we could just use the default one? + // The answer is that we changed from Sequence to RandomAccessCollection in a SemVer minor release. The + // previous code had a special-case Iterator, and so to avoid breaking that abstraction we need to provide one + // here too. Happily, however, we can simply delegate to the underlying Iterator type. + + /// An iterator of HTTP header fields. + /// + /// This iterator will return each value for a given header name separately. That + /// means that `name` is not guaranteed to be unique in a given block of headers. + public struct Iterator: IteratorProtocol { + @usableFromInline + var _base: Array.Iterator + + @inlinable + init(_ base: HPACKHeaders) { + self._base = base.headers.makeIterator() + } + + @inlinable + public mutating func next() -> Element? { + guard let element = self._base.next() else { + return nil + } + return (name: element.name, value: element.value, indexable: element.indexing) + } + } + + @inlinable + public func makeIterator() -> HPACKHeaders.Iterator { + return Iterator(self) + } +} + + +extension HPACKHeaders: CustomStringConvertible { + public var description: String { + var headersArray: [(HPACKIndexing, String, String)] = [] + headersArray.reserveCapacity(self.headers.count) + + for h in self.headers { + headersArray.append((h.indexing, h.name, h.value)) + } + return headersArray.description + } +} + +// NOTE: This is a bad definition of equatable and hashable. In particular, both order and +// indexability are ignored. We should change it, but we should be careful when we do so. +// More discussion at https://github.com/apple/swift-nio-http2/issues/342. +extension HPACKHeaders: Equatable { + @inlinable + public static func ==(lhs: HPACKHeaders, rhs: HPACKHeaders) -> Bool { + guard lhs.headers.count == rhs.headers.count else { + return false + } + let lhsNames = Set(lhs.headers.map { $0.name }) + let rhsNames = Set(rhs.headers.map { $0.name }) + guard lhsNames == rhsNames else { + return false + } + + for name in lhsNames { + guard lhs[name].sorted() == rhs[name].sorted() else { + return false + } + } + + return true + } +} + +extension HPACKHeaders: Hashable { + @inlinable + public func hash(into hasher: inout Hasher) { + // Discriminator, to indicate that this is a collection. This improves the performance + // of Sets and Dictionaries that include collections of HPACKHeaders by reducing hash collisions. + hasher.combine(self.count) + + // This emulates the logic used in equatability, but we sort it to ensure that + // we hash equivalently. + let names = Set(self.headers.lazy.map { $0.name }).sorted() + for name in names { + hasher.combine(self[name].sorted()) + } + } +} + +/// Defines the types of indexing and rewriting operations a decoder may take with +/// regard to this header. +public enum HPACKIndexing: CustomStringConvertible, NIOSendable { + /// Header may be written into the dynamic index table or may be rewritten by + /// proxy servers. + case indexable + /// Header is not written to the dynamic index table, but proxies may rewrite + /// it en-route, as long as they preserve its non-indexable attribute. + case nonIndexable + /// Header may not be written to the dynamic index table, and proxies must + /// pass it on as-is without rewriting. + case neverIndexed + + public var description: String { + switch self { + case .indexable: + return "[]" + case .nonIndexable: + return "[non-indexable]" + case .neverIndexed: + return "[neverIndexed]" + } + } +} + +@usableFromInline +internal struct HPACKHeader: NIOSendable { + @usableFromInline + var indexing: HPACKIndexing + + @usableFromInline + var name: String + + @usableFromInline + var value: String + + @inlinable + internal init(name: String, value: String, indexing: HPACKIndexing = .indexable) { + self.indexing = indexing + self.name = name + self.value = value + } +} + + +extension HPACKHeader { + @inlinable + internal var size: Int { + // RFC 7541 § 4.1: + // + // The size of an entry is the sum of its name's length in octets (as defined in + // Section 5.2), its value's length in octets, and 32. + // + // The size of an entry is calculated using the length of its name and value + // without any Huffman encoding applied. + return name.utf8.count + value.utf8.count + 32 + } +} + + +internal extension UInt8 { + @inlinable + var isASCII: Bool { + return self <= 127 + } +} + +/* private but inlinable */ +internal extension UTF8.CodeUnit { + @inlinable + var isASCIIWhitespace: Bool { + switch self { + case UInt8(ascii: " "), + UInt8(ascii: "\t"): + return true + default: + return false + } + } +} + +extension Substring.UTF8View { + @inlinable + func _trimWhitespace() -> Substring.UTF8View { + guard let firstNonWhitespace = self.firstIndex(where: { !$0.isASCIIWhitespace }) else { + // The whole substring is ASCII whitespace. + return Substring().utf8 + } + + // There must be at least one non-ascii whitespace character, so banging here is safe. + let lastNonWhitespace = self.lastIndex(where: { !$0.isASCIIWhitespace })! + return self[firstNonWhitespace...lastNonWhitespace] + } +} + +extension String.UTF8View { + @inlinable + func _lazySplit(separator: UTF8.CodeUnit) -> LazyUTF8ViewSplitSequence { + return LazyUTF8ViewSplitSequence(self, separator: separator) + } + + @usableFromInline + struct LazyUTF8ViewSplitSequence: Sequence { + @usableFromInline typealias Element = Substring.UTF8View + + @usableFromInline var _baseView: String.UTF8View + @usableFromInline var _separator: UTF8.CodeUnit + + @inlinable + init(_ baseView: String.UTF8View, separator: UTF8.CodeUnit) { + self._baseView = baseView + self._separator = separator + } + + @inlinable + func makeIterator() -> Iterator { + return Iterator(self) + } + + @usableFromInline + struct Iterator: IteratorProtocol { + @usableFromInline var _base: LazyUTF8ViewSplitSequence + @usableFromInline var _lastSplitIndex: Substring.UTF8View.Index + + @inlinable + init(_ base: LazyUTF8ViewSplitSequence) { + self._base = base + self._lastSplitIndex = base._baseView.startIndex + } + + @inlinable + mutating func next() -> Substring.UTF8View? { + let endIndex = self._base._baseView.endIndex + + guard self._lastSplitIndex != endIndex else { + return nil + } + + let restSlice = self._base._baseView[self._lastSplitIndex...] + + if let nextSplitIndex = restSlice.firstIndex(of: self._base._separator) { + // The separator is present. We want to drop the separator, so we need to advance the index past this point. + self._lastSplitIndex = self._base._baseView.index(after: nextSplitIndex) + return restSlice[.. Bool { + // fast path: we can get the underlying bytes of both + let maybeMaybeResult = self.withContiguousStorageIfAvailable { lhsBuffer -> Bool? in + other.withContiguousStorageIfAvailable { rhsBuffer in + if lhsBuffer.count != rhsBuffer.count { + return false + } + + for idx in 0 ..< lhsBuffer.count { + // let's hope this gets vectorised ;) + if lhsBuffer[idx] & 0xdf != rhsBuffer[idx] & 0xdf && lhsBuffer[idx].isASCII { + return false + } + } + return true + } + } + + if let maybeResult = maybeMaybeResult, let result = maybeResult { + return result + } else { + return self._compareCaseInsensitiveASCIIBytesSlowPath(to: other) + } + } + + @inlinable + @inline(never) + func _compareCaseInsensitiveASCIIBytesSlowPath(to other: String.UTF8View) -> Bool { + return self.elementsEqual(other, by: { return (($0 & 0xdf) == ($1 & 0xdf) && $0.isASCII) }) + } +} + + +extension String { + @inlinable + internal func isEqualCaseInsensitiveASCIIBytes(to: String) -> Bool { + return self.utf8.compareCaseInsensitiveASCIIBytes(to: to.utf8) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HeaderTables.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HeaderTables.swift new file mode 100644 index 00000000..dc092706 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HeaderTables.swift @@ -0,0 +1,212 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +internal struct HeaderTableEntry: NIOSendable { + var name: String + + var value: String + + // RFC 7541 § 4.1: + // + // The size of an entry is the sum of its name's length in octets (as defined in + // Section 5.2), its value's length in octets, and 32. + // + // The size of an entry is calculated using the length of its name and value + // without any Huffman encoding applied. + var length: Int { + return self.name.utf8.count + self.value.utf8.count + 32 + } +} + +/// Storage for the header tables, both static and dynamic. Similar in spirit to +/// `HPACKHeaders` and `NIOHTTP1.HTTPHeaders`, but uses a ring buffer to hold the bytes to +/// avoid allocation churn while evicting and replacing entries. +@usableFromInline +struct HeaderTableStorage { + static let defaultMaxSize = 4096 + + private var headers: CircularBuffer + + internal private(set) var maxSize: Int + internal private(set) var length: Int = 0 + + var count: Int { + return self.headers.count + } + + init(maxSize: Int = HeaderTableStorage.defaultMaxSize) { + self.maxSize = maxSize + self.headers = CircularBuffer(initialCapacity: self.maxSize / 64) // rough guess: 64 bytes per header + } + + init(staticHeaderList: [(String, String)]) { + self.headers = CircularBuffer(initialCapacity: staticHeaderList.count) + + var len = 0 + for header in staticHeaderList { + let entry = HeaderTableEntry(name: header.0, value: header.1) + self.headers.append(entry) + len += entry.length + } + + self.maxSize = len + } + + subscript(index: Int) -> HeaderTableEntry { + let baseIndex = self.headers.index(self.headers.startIndex, offsetBy: index) + return self.headers[baseIndex] + } + + enum MatchType { + case full(Int) + case partial(Int) + case none + } + + func closestMatch(name: String, value: String) -> MatchType { + var partialIndex: Int? = nil + + // Yes, I'm manually reimplementing IndexingIterator here. This is because + // the excess ARC in this loop shows up in our profiles pretty substantially, + // and it's triggered by https://bugs.swift.org/browse/SR-13931. + // + // Working around this until the above is resolved. + var offset = 0 + var index = self.headers.startIndex + + while index < self.headers.endIndex { + defer { + // Unchecked arithmetic is safe here, we can't overflow as offset can never exceed count. + offset &+= 1 + self.headers.formIndex(after: &index) + } + + // Check if the header name matches. + guard self.headers[index].name.isEqualCaseInsensitiveASCIIBytes(to: name) else { + continue + } + + if partialIndex == nil { + partialIndex = offset + } + + if value == self.headers[index].value { + return .full(offset) + } + } + + if let partial = partialIndex { + return .partial(partial) + } else { + return .none + } + } + + func firstIndex(matching name: String) -> Int? { + for (idx, header) in self.headers.enumerated() { + if header.name.isEqualCaseInsensitiveASCIIBytes(to: name) { + return idx + } + } + return nil + } + + mutating func setTableSize(to newSize: Int) { + precondition(newSize >= 0) + if newSize < self.length { + // need to clear out some things first. + while newSize < self.length { + purgeOne() + } + } + + self.maxSize = newSize + } + + mutating func add(name: String, value: String) { + let entry = HeaderTableEntry(name: name, value: value) + + var newLength = self.length + entry.length + if newLength > self.maxSize { + self.purge(toRelease: newLength - maxSize) + newLength = self.length + entry.length + } + + + if newLength > self.maxSize { + // We can't free up enough space. This is not an error: RFC 7541 § 4.4 explicitly allows it. + // In this case, the append fails but the above purge is preserved. + return + } + + self.headers.prepend(entry) + self.length = newLength + } + + /// Purges `toRelease` bytes from the table, where 'bytes' refers to the byte-count + /// of a table entry specified in RFC 7541: [name octets] + [value octets] + 32. + /// + /// - parameter toRelease: The table entry length of bytes to remove from the table. + mutating func purge(toRelease count: Int) { + guard count < self.length else { + // clear all the things + self.headers.removeAll() + self.length = 0 + return + } + + var available = self.maxSize - self.length + let needed = available + count + while available < needed && !self.headers.isEmpty { + available += self.purgeOne() + } + } + + @discardableResult + private mutating func purgeOne() -> Int { + precondition(self.headers.isEmpty == false, "should not call purgeOne() unless we have something to purge") + // Remember: we're removing from the *end* of the header list, since we *prepend* new items there, but we're + // removing bytes from the *start* of the storage, because we *append* there. + let entry = self.headers.removeLast() + self.length -= entry.length + return entry.length + } + + // internal for testing + func dumpHeaders(offsetBy amount: Int = 0) -> String { + return self.headers.enumerated().reduce("") { + $0 + "\($1.0 + amount) - \($1.1.name) : \($1.1.value)\n" + } + } +} + +extension HeaderTableStorage : CustomStringConvertible { + @usableFromInline + var description: String { + var array: [(String, String)] = [] + for header in self.headers { + array.append((header.name, header.value)) + } + return array.description + } +} + +// The `@unchecked` is needed because at the time of writing `NIOCore` didn't have `Sendable` support. +#if swift(>=5.5) && canImport(_Concurrency) +extension HeaderTableStorage: @unchecked Sendable { + +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanCoding.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanCoding.swift new file mode 100644 index 00000000..82c779db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanCoding.swift @@ -0,0 +1,289 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// Adds HPACK-conformant Huffman encoding to `ByteBuffer`. Note that the implementation is *not* +/// thread safe. The intended use is to be within a single HTTP2StreamChannel or similar, on a +/// single EventLoop. +extension ByteBuffer { + fileprivate struct _EncoderState { + var offset = 0 + var remainingBits = 8 + } + + /// Returns the number of *bits* required to encode a given string. + fileprivate static func encodedBitLength(of bytes: C) -> Int where C.Element == UInt8 { + let clen = bytes.reduce(0) { $0 + StaticHuffmanTable[Int($1)].nbits } + // round up to nearest multiple of 8 for EOS prefix + return (clen + 7) & ~7 + } + + /// Returns the number of bytes required to encode a given string. + static func huffmanEncodedLength(of bytes: C) -> Int where C.Element == UInt8 { + return self.encodedBitLength(of: bytes) / 8 + } + + /// Encodes the given string to the buffer, using HPACK Huffman encoding. + /// + /// - Parameter string: The string data to encode. + /// - Returns: The number of bytes used while encoding the string. + @discardableResult + mutating func setHuffmanEncoded(bytes stringBytes: C) -> Int where C.Element == UInt8 { + let clen = ByteBuffer.encodedBitLength(of: stringBytes) + self.ensureBitsAvailable(clen) + + return self.withUnsafeMutableWritableBytes { bytes in + var state = _EncoderState() + + for ch in stringBytes { + ByteBuffer.appendSym_fast(StaticHuffmanTable[Int(ch)], &state, bytes: bytes) + } + + if state.remainingBits > 0 && state.remainingBits < 8 { + // set all remaining bits of the last byte to 1 + bytes[state.offset] |= UInt8(1 << state.remainingBits) - 1 + state.offset += 1 + state.remainingBits = (state.offset == bytes.count ? 0 : 8) + } + + return state.offset + } + } + + @discardableResult + mutating func writeHuffmanEncoded(bytes stringBytes: C) -> Int where C.Element == UInt8 { + let written = self.setHuffmanEncoded(bytes: stringBytes) + self.moveWriterIndex(forwardBy: written) + return written + } + + fileprivate static func appendSym_fast(_ sym: HuffmanTableEntry, _ state: inout _EncoderState, bytes: UnsafeMutableRawBufferPointer) { + // will it fit as-is? + if sym.nbits == state.remainingBits { + bytes[state.offset] |= UInt8(sym.bits) + state.offset += 1 + state.remainingBits = state.offset == bytes.count ? 0 : 8 + } else if sym.nbits < state.remainingBits { + let diff = state.remainingBits - sym.nbits + bytes[state.offset] |= UInt8(sym.bits << diff) + state.remainingBits -= sym.nbits + } else { + var (code, nbits) = sym + + nbits -= state.remainingBits + bytes[state.offset] |= UInt8(code >> nbits) + state.offset += 1 + + if nbits & 0x7 != 0 { + // align code to MSB + code <<= 8 - (nbits & 0x7) + } + + // we can short-circuit if less than 8 bits are remaining + if nbits < 8 { + bytes[state.offset] = UInt8(truncatingIfNeeded: code) + state.remainingBits = 8 - nbits + return + } + + // longer path for larger amounts + switch nbits { + case _ where nbits > 24: + bytes[state.offset] = UInt8(truncatingIfNeeded: code >> 24) + nbits -= 8 + state.offset += 1 + fallthrough + case _ where nbits > 16: + bytes[state.offset] = UInt8(truncatingIfNeeded: code >> 16) + nbits -= 8 + state.offset += 1 + fallthrough + case _ where nbits > 8: + bytes[state.offset] = UInt8(truncatingIfNeeded: code >> 8) + nbits -= 8 + state.offset += 1 + default: + break + } + + if nbits == 8 { + bytes[state.offset] = UInt8(truncatingIfNeeded: code) + state.offset += 1 + state.remainingBits = state.offset == bytes.count ? 0 : 8 + } else { + state.remainingBits = 8 - nbits + bytes[state.offset] = UInt8(truncatingIfNeeded: code) + } + } + } + + fileprivate mutating func ensureBitsAvailable(_ bits: Int) { + let bytesNeeded = bits / 8 + if bytesNeeded <= self.writableBytes { + // just zero the requested number of bytes before we start OR-ing in our values + self.withUnsafeMutableWritableBytes { ptr in + ptr.copyBytes(from: repeatElement(0, count: bytesNeeded)) + } + return + } + + let neededToAdd = bytesNeeded - self.writableBytes + let newLength = self.capacity + neededToAdd + + // reallocate to ensure we have the room we need + self.reserveCapacity(newLength) + + // now zero all writable bytes that we expect to use + self.withUnsafeMutableWritableBytes { ptr in + ptr.copyBytes(from: repeatElement(0, count: bytesNeeded)) + } + } +} + +/// Errors that may be encountered by the Huffman decoder. +public enum HuffmanDecodeError +{ + /// The decoder entered an invalid state. Usually this means invalid input. + public struct InvalidState : NIOHPACKError { + fileprivate init() {} + } + + /// The output data could not be validated as UTF-8. + public struct InvalidUTF8 : NIOHPACKError { + fileprivate init() {} + } +} + +/// The decoder table. This structure doesn't actually take up any space, I think? +fileprivate let decoderTable = HuffmanDecoderTable() + +extension ByteBuffer { + + /// Decodes a huffman-encoded string from the `ByteBuffer`. + /// + /// - Parameter at: The location of the encoded bytes to read. + /// - Parameter length: The number of huffman-encoded octets to read. + /// - Returns: The decoded `String`. + /// - Throws: HuffmanDecodeError if the data could not be decoded. + @discardableResult + func getHuffmanEncodedString(at index: Int, length: Int) throws -> String { + precondition(index + length <= self.capacity, "Requested range out of bounds: \(index ..< index+length) vs. \(self.capacity)") + if length == 0 { + return "" + } + + // We have a rough heuristic here, which is that the maximal compression efficiency of the huffman table is 2x. + let capacity = length * 2 + + let decoded = try String(customUnsafeUninitializedCapacity: capacity) { backingStorage in + var state: UInt8 = 0 + + // We do unchecked math on offset. Offset is strictly unable to get any larger than `length * 2`, + // and we already did checked multiplication on that value. + var offset = 0 + var acceptable = false + + // We force-unwrap here to crash if we attempt to decode out of bounds. + for ch in self.viewBytes(at: index, length: length)! { + var t = decoderTable[state: state, nybble: ch >> 4] + if t.flags.contains(.failure) { + throw HuffmanDecodeError.InvalidState() + } + if t.flags.contains(.symbol) { + backingStorage[offset] = t.sym + offset &+= 1 + } + + t = decoderTable[state: t.state, nybble: ch & 0xf] + if t.flags.contains(.failure) { + throw HuffmanDecodeError.InvalidState() + } + if t.flags.contains(.symbol) { + backingStorage[offset] = t.sym + offset &+= 1 + } + + state = t.state + acceptable = t.flags.contains(.accepted) + } + + guard acceptable else { + throw HuffmanDecodeError.InvalidState() + } + + return offset + } + + + return decoded + } + + /// Decodes a huffman-encoded string from the provided `ByteBuffer`, starting at the buffer's + /// current `readerIndex`. Updates the `readerIndex` when it completes. + /// + /// - Parameter length: The number of huffman-encoded octets to read. + /// - Returns: The decoded `String`. + /// - Throws: HuffmanDecodeError if the data could not be decoded. + @discardableResult + mutating func readHuffmanEncodedString(length: Int) throws -> String { + let result = try self.getHuffmanEncodedString(at: self.readerIndex, length: length) + self.moveReaderIndex(forwardBy: length) + return result + } +} + +extension String { + /// This is a backport of a proposed String initializer that will allow writing directly into an uninitialized String's backing memory. + /// This feature will be useful when decoding Huffman-encoded HPACK strings. + /// + /// As this API does not exist prior to 5.3 on Linux, or on older Apple platforms, we fake it out with a pointer and accept the extra copy. + init(backportUnsafeUninitializedCapacity capacity: Int, + initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int) rethrows { + let buffer = UnsafeMutableBufferPointer.allocate(capacity: capacity) + defer { + buffer.deallocate() + } + + + let initializedCount = try initializer(buffer) + precondition(initializedCount <= capacity, "Overran buffer in initializer!") + + self = String(decoding: UnsafeMutableBufferPointer(start: buffer.baseAddress!, count: initializedCount), as: UTF8.self) + } +} + +// Frustratingly, Swift 5.3 shipped before the macOS 11 SDK did, so we cannot gate the availability of +// this declaration on having the 5.3 compiler. This has caused a number of build issues. While updating +// to newer Xcodes does work, we can save ourselves some hassle and just wait until 5.4 to get this +// enhancement on Apple platforms. +#if (compiler(>=5.3) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))) || compiler(>=5.4) +extension String { + init(customUnsafeUninitializedCapacity capacity: Int, + initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int) rethrows { + if #available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) { + try self.init(unsafeUninitializedCapacity: capacity, initializingUTF8With: initializer) + } else { + try self.init(backportUnsafeUninitializedCapacity: capacity, initializingUTF8With: initializer) + } + } +} +#else +extension String { + init(customUnsafeUninitializedCapacity capacity: Int, + initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int) rethrows { + try self.init(backportUnsafeUninitializedCapacity: capacity, initializingUTF8With: initializer) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanTables.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanTables.swift new file mode 100644 index 00000000..182ba91b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/HuffmanTables.swift @@ -0,0 +1,5410 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +typealias HuffmanTableEntry = (bits: UInt32, nbits: Int) + +/// Base-64 decoding has been jovially purloined from swift-corelibs-foundation/.../NSData.swift. +/// The ranges of ASCII characters that are used to encode data in Base64. +private let base64ByteMappings: [Range] = [ + 65 ..< 91, // A-Z + 97 ..< 123, // a-z + 48 ..< 58, // 0-9 + 43 ..< 44, // + + 47 ..< 48, // / +] +/** + Padding character used when the number of bytes to encode is not divisible by 3 + */ +private let base64Padding : UInt8 = 61 // = + +/** + This method takes a byte with a character from Base64-encoded string + and gets the binary value that the character corresponds to. + + - parameter byte: The byte with the Base64 character. + - returns: Base64DecodedByte value containing the result (Valid , Invalid, Padding) + */ +private enum Base64DecodedByte { + case valid(UInt8) + case invalid + case padding +} + +private func base64DecodeByte(_ byte: UInt8) -> Base64DecodedByte { + guard byte != base64Padding else {return .padding} + var decodedStart: UInt8 = 0 + for range in base64ByteMappings { + if range.contains(byte) { + let result = decodedStart + (byte - range.lowerBound) + return .valid(result) + } + decodedStart += range.upperBound - range.lowerBound + } + return .invalid +} + +/** + This method decodes Base64-encoded data. + + If the input contains any bytes that are not valid Base64 characters, + this will return nil. + + - parameter bytes: The Base64 bytes + - parameter options: Options for handling invalid input + - returns: The decoded bytes. + */ +private func base64DecodeBytes(_ bytes: C, ignoreUnknownCharacters: Bool = false) -> [UInt8]? where C.Element == UInt8 { + var decodedBytes = [UInt8]() + decodedBytes.reserveCapacity((bytes.count/3)*2) + + var currentByte : UInt8 = 0 + var validCharacterCount = 0 + var paddingCount = 0 + var index = 0 + + + for base64Char in bytes { + + let value : UInt8 + + switch base64DecodeByte(base64Char) { + case .valid(let v): + value = v + validCharacterCount += 1 + case .invalid: + if ignoreUnknownCharacters { + continue + } else { + return nil + } + case .padding: + paddingCount += 1 + continue + } + + //padding found in the middle of the sequence is invalid + if paddingCount > 0 { + return nil + } + + switch index%4 { + case 0: + currentByte = (value << 2) + case 1: + currentByte |= (value >> 4) + decodedBytes.append(currentByte) + currentByte = (value << 4) + case 2: + currentByte |= (value >> 2) + decodedBytes.append(currentByte) + currentByte = (value << 6) + case 3: + currentByte |= value + decodedBytes.append(currentByte) + default: + fatalError() + } + + index += 1 + } + + guard (validCharacterCount + paddingCount)%4 == 0 else { + //invalid character count + return nil + } + return decodedBytes +} + +internal let StaticHuffmanTable: [HuffmanTableEntry] = [ + (0x1ff8, 13), (0x7fffd8, 23), (0xfffffe2, 28), (0xfffffe3, 28), (0xfffffe4, 28), (0xfffffe5, 28), + (0xfffffe6, 28), (0xfffffe7, 28), (0xfffffe8, 28), (0xffffea, 24), (0x3ffffffc, 30), (0xfffffe9, 28), + (0xfffffea, 28), (0x3ffffffd, 30), (0xfffffeb, 28), (0xfffffec, 28), (0xfffffed, 28), (0xfffffee, 28), + (0xfffffef, 28), (0xffffff0, 28), (0xffffff1, 28), (0xffffff2, 28), (0x3ffffffe, 30), (0xffffff3, 28), + (0xffffff4, 28), (0xffffff5, 28), (0xffffff6, 28), (0xffffff7, 28), (0xffffff8, 28), (0xffffff9, 28), + (0xffffffa, 28), (0xffffffb, 28), (0x14, 6), (0x3f8, 10), (0x3f9, 10), (0xffa, 12), + (0x1ff9, 13), (0x15, 6), (0xf8, 8), (0x7fa, 11), (0x3fa, 10), (0x3fb, 10), + (0xf9, 8), (0x7fb, 11), (0xfa, 8), (0x16, 6), (0x17, 6), (0x18, 6), + (0x0, 5), (0x1, 5), (0x2, 5), (0x19, 6), (0x1a, 6), (0x1b, 6), + (0x1c, 6), (0x1d, 6), (0x1e, 6), (0x1f, 6), (0x5c, 7), (0xfb, 8), + (0x7ffc, 15), (0x20, 6), (0xffb, 12), (0x3fc, 10), (0x1ffa, 13), (0x21, 6), + (0x5d, 7), (0x5e, 7), (0x5f, 7), (0x60, 7), (0x61, 7), (0x62, 7), + (0x63, 7), (0x64, 7), (0x65, 7), (0x66, 7), (0x67, 7), (0x68, 7), + (0x69, 7), (0x6a, 7), (0x6b, 7), (0x6c, 7), (0x6d, 7), (0x6e, 7), + (0x6f, 7), (0x70, 7), (0x71, 7), (0x72, 7), (0xfc, 8), (0x73, 7), + (0xfd, 8), (0x1ffb, 13), (0x7fff0, 19), (0x1ffc, 13), (0x3ffc, 14), (0x22, 6), + (0x7ffd, 15), (0x3, 5), (0x23, 6), (0x4, 5), (0x24, 6), (0x5, 5), + (0x25, 6), (0x26, 6), (0x27, 6), (0x6, 5), (0x74, 7), (0x75, 7), + (0x28, 6), (0x29, 6), (0x2a, 6), (0x7, 5), (0x2b, 6), (0x76, 7), + (0x2c, 6), (0x8, 5), (0x9, 5), (0x2d, 6), (0x77, 7), (0x78, 7), + (0x79, 7), (0x7a, 7), (0x7b, 7), (0x7ffe, 15), (0x7fc, 11), (0x3ffd, 14), + (0x1ffd, 13), (0xffffffc, 28), (0xfffe6, 20), (0x3fffd2, 22), (0xfffe7, 20), (0xfffe8, 20), + (0x3fffd3, 22), (0x3fffd4, 22), (0x3fffd5, 22), (0x7fffd9, 23), (0x3fffd6, 22), (0x7fffda, 23), + (0x7fffdb, 23), (0x7fffdc, 23), (0x7fffdd, 23), (0x7fffde, 23), (0xffffeb, 24), (0x7fffdf, 23), + (0xffffec, 24), (0xffffed, 24), (0x3fffd7, 22), (0x7fffe0, 23), (0xffffee, 24), (0x7fffe1, 23), + (0x7fffe2, 23), (0x7fffe3, 23), (0x7fffe4, 23), (0x1fffdc, 21), (0x3fffd8, 22), (0x7fffe5, 23), + (0x3fffd9, 22), (0x7fffe6, 23), (0x7fffe7, 23), (0xffffef, 24), (0x3fffda, 22), (0x1fffdd, 21), + (0xfffe9, 20), (0x3fffdb, 22), (0x3fffdc, 22), (0x7fffe8, 23), (0x7fffe9, 23), (0x1fffde, 21), + (0x7fffea, 23), (0x3fffdd, 22), (0x3fffde, 22), (0xfffff0, 24), (0x1fffdf, 21), (0x3fffdf, 22), + (0x7fffeb, 23), (0x7fffec, 23), (0x1fffe0, 21), (0x1fffe1, 21), (0x3fffe0, 22), (0x1fffe2, 21), + (0x7fffed, 23), (0x3fffe1, 22), (0x7fffee, 23), (0x7fffef, 23), (0xfffea, 20), (0x3fffe2, 22), + (0x3fffe3, 22), (0x3fffe4, 22), (0x7ffff0, 23), (0x3fffe5, 22), (0x3fffe6, 22), (0x7ffff1, 23), + (0x3ffffe0, 26), (0x3ffffe1, 26), (0xfffeb, 20), (0x7fff1, 19), (0x3fffe7, 22), (0x7ffff2, 23), + (0x3fffe8, 22), (0x1ffffec, 25), (0x3ffffe2, 26), (0x3ffffe3, 26), (0x3ffffe4, 26), (0x7ffffde, 27), + (0x7ffffdf, 27), (0x3ffffe5, 26), (0xfffff1, 24), (0x1ffffed, 25), (0x7fff2, 19), (0x1fffe3, 21), + (0x3ffffe6, 26), (0x7ffffe0, 27), (0x7ffffe1, 27), (0x3ffffe7, 26), (0x7ffffe2, 27), (0xfffff2, 24), + (0x1fffe4, 21), (0x1fffe5, 21), (0x3ffffe8, 26), (0x3ffffe9, 26), (0xffffffd, 28), (0x7ffffe3, 27), + (0x7ffffe4, 27), (0x7ffffe5, 27), (0xfffec, 20), (0xfffff3, 24), (0xfffed, 20), (0x1fffe6, 21), + (0x3fffe9, 22), (0x1fffe7, 21), (0x1fffe8, 21), (0x7ffff3, 23), (0x3fffea, 22), (0x3fffeb, 22), + (0x1ffffee, 25), (0x1ffffef, 25), (0xfffff4, 24), (0xfffff5, 24), (0x3ffffea, 26), (0x7ffff4, 23), + (0x3ffffeb, 26), (0x7ffffe6, 27), (0x3ffffec, 26), (0x3ffffed, 26), (0x7ffffe7, 27), (0x7ffffe8, 27), + (0x7ffffe9, 27), (0x7ffffea, 27), (0x7ffffeb, 27), (0xffffffe, 28), (0x7ffffec, 27), (0x7ffffed, 27), + (0x7ffffee, 27), (0x7ffffef, 27), (0x7fffff0, 27), (0x3ffffee, 26), (0x3fffffff, 30) +] + +// Great googly-moogly that's a large array! This comes from the nice folks at nghttp. + +/* + This implementation of a Huffman decoding table for HTTP/2 is essentially a + Swift port of the C tables from nghttp2's Huffman decoding implementation, + and is thus clearly a derivative work of the nghttp2 file + ``nghttp2_hd_huffman_data.c``, obtained from https://github.com/tatsuhiro-t/nghttp2/. + That work is also available under the Apache 2.0 license under the following terms: + + Copyright (c) 2013 Tatsuhiro Tsujikawa + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +typealias HuffmanDecodeEntry = (state: UInt8, flags: HuffmanDecoderFlags, sym: UInt8) + +internal struct HuffmanDecoderFlags : OptionSet +{ + var rawValue: UInt8 + + static let none = HuffmanDecoderFlags([]) + static let accepted = HuffmanDecoderFlags(rawValue: 0b001) + static let symbol = HuffmanDecoderFlags(rawValue: 0b010) + static let failure = HuffmanDecoderFlags(rawValue: 0b100) +} + +/** + This was described nicely by `@Lukasa` in his Python implementation: + + The essence of this approach is that it builds a finite state machine out of + 4-bit nybbles of Huffman coded data. The input function passes 4 bits worth of + data to the state machine each time, which uses those 4 bits of data along with + the current accumulated state data to process the data given. + + For the sake of efficiency, the in-memory representation of the states, + transitions, and result values of the state machine are represented as a long + list containing three-tuples. This list is enormously long, and viewing it as + an in-memory representation is not very clear, but it is laid out here in a way + that is intended to be *somewhat* more clear. + + Essentially, the list is structured as 256 collections of 16 entries (one for + each nybble) of three-tuples. Each collection is called a "node", and the + zeroth collection is called the "root node". The state machine tracks one + value: the "state" byte. + + For each nybble passed to the state machine, it first multiplies the "state" + byte by 16 and adds the numerical value of the nybble. This number is the index + into the large flat list. + + The three-tuple that is found by looking up that index consists of three + values: + + - a new state value, used for subsequent decoding + - a collection of flags, used to determine whether data is emitted or whether + the state machine is complete. + - the byte value to emit, assuming that emitting a byte is required. + + The flags are consulted, if necessary a byte is emitted, and then the next + nybble is used. This continues until the state machine believes it has + completely Huffman-decoded the data. + + This approach has relatively little indirection, and therefore performs + relatively well. The total number of loop + iterations is 4x the number of bytes passed to the decoder. + */ +internal struct HuffmanDecoderTable { + subscript(state state: UInt8, nybble nybble: UInt8) -> HuffmanDecodeEntry { + assert(nybble < 16) + let index = (Int(state) * 16) + Int(nybble) + return HuffmanDecoderTable.rawTable[index] + } + + // You would not *believe* how much faster this compiles now. + // TODO(jim): decide if it's worth dropping the un-encoded raw bytes into + // a segment of the binary, i.e. __DATA,__huffman_decode_table. I don't know + // how to do that (automatically) via SwiftPM though, only via Xcode. + private static let rawTable: [HuffmanDecodeEntry] = { + let base64_table_bytes: StaticString = """ + BAAABQAABwAACAAACwAADAAAEAAAEwAAGQAAHAAAIAAAIwAAKgAAMQAAOQAAQAEA + AAMwAAMxAAMyAANhAANjAANlAANpAANvAANzAAN0DQAADgAAEQAAEgAAFAAAFQAA + AQIwFgMwAQIxFgMxAQIyFgMyAQJhFgNhAQJjFgNjAQJlFgNlAQJpFgNpAQJvFgNv + AgIwCQIwFwIwKAMwAgIxCQIxFwIxKAMxAgIyCQIyFwIyKAMyAgJhCQJhFwJhKANh + AwIwBgIwCgIwDwIwGAIwHwIwKQIwOAMwAwIxBgIxCgIxDwIxGAIxHwIxKQIxOAMx + AwIyBgIyCgIyDwIyGAIyHwIyKQIyOAMyAwJhBgJhCgJhDwJhGAJhHwJhKQJhOANh + AgJjCQJjFwJjKANjAgJlCQJlFwJlKANlAgJpCQJpFwJpKANpAgJvCQJvFwJvKANv + AwJjBgJjCgJjDwJjGAJjHwJjKQJjOANjAwJlBgJlCgJlDwJlGAJlHwJlKQJlOANl + AwJpBgJpCgJpDwJpGAJpHwJpKQJpOANpAwJvBgJvCgJvDwJvGAJvHwJvKQJvOANv + AQJzFgNzAQJ0FgN0AAMgAAMlAAMtAAMuAAMvAAMzAAM0AAM1AAM2AAM3AAM4AAM5 + AgJzCQJzFwJzKANzAgJ0CQJ0FwJ0KAN0AQIgFgMgAQIlFgMlAQItFgMtAQIuFgMu + AwJzBgJzCgJzDwJzGAJzHwJzKQJzOANzAwJ0BgJ0CgJ0DwJ0GAJ0HwJ0KQJ0OAN0 + AgIgCQIgFwIgKAMgAgIlCQIlFwIlKAMlAgItCQItFwItKAMtAgIuCQIuFwIuKAMu + AwIgBgIgCgIgDwIgGAIgHwIgKQIgOAMgAwIlBgIlCgIlDwIlGAIlHwIlKQIlOAMl + AwItBgItCgItDwItGAItHwItKQItOAMtAwIuBgIuCgIuDwIuGAIuHwIuKQIuOAMu + AQIvFgMvAQIzFgMzAQI0FgM0AQI1FgM1AQI2FgM2AQI3FgM3AQI4FgM4AQI5FgM5 + AgIvCQIvFwIvKAMvAgIzCQIzFwIzKAMzAgI0CQI0FwI0KAM0AgI1CQI1FwI1KAM1 + AwIvBgIvCgIvDwIvGAIvHwIvKQIvOAMvAwIzBgIzCgIzDwIzGAIzHwIzKQIzOAMz + AwI0BgI0CgI0DwI0GAI0HwI0KQI0OAM0AwI1BgI1CgI1DwI1GAI1HwI1KQI1OAM1 + AgI2CQI2FwI2KAM2AgI3CQI3FwI3KAM3AgI4CQI4FwI4KAM4AgI5CQI5FwI5KAM5 + AwI2BgI2CgI2DwI2GAI2HwI2KQI2OAM2AwI3BgI3CgI3DwI3GAI3HwI3KQI3OAM3 + AwI4BgI4CgI4DwI4GAI4HwI4KQI4OAM4AwI5BgI5CgI5DwI5GAI5HwI5KQI5OAM5 + GgAAGwAAHQAAHgAAIQAAIgAAJAAAJQAAKwAALgAAMgAANQAAOgAAPQAAQQAARAEA + AAM9AANBAANfAANiAANkAANmAANnAANoAANsAANtAANuAANwAANyAAN1JgAAJwAA + AQI9FgM9AQJBFgNBAQJfFgNfAQJiFgNiAQJkFgNkAQJmFgNmAQJnFgNnAQJoFgNo + AgI9CQI9FwI9KAM9AgJBCQJBFwJBKANBAgJfCQJfFwJfKANfAgJiCQJiFwJiKANi + AwI9BgI9CgI9DwI9GAI9HwI9KQI9OAM9AwJBBgJBCgJBDwJBGAJBHwJBKQJBOANB + AwJfBgJfCgJfDwJfGAJfHwJfKQJfOANfAwJiBgJiCgJiDwJiGAJiHwJiKQJiOANi + AgJkCQJkFwJkKANkAgJmCQJmFwJmKANmAgJnCQJnFwJnKANnAgJoCQJoFwJoKANo + AwJkBgJkCgJkDwJkGAJkHwJkKQJkOANkAwJmBgJmCgJmDwJmGAJmHwJmKQJmOANm + AwJnBgJnCgJnDwJnGAJnHwJnKQJnOANnAwJoBgJoCgJoDwJoGAJoHwJoKQJoOANo + AQJsFgNsAQJtFgNtAQJuFgNuAQJwFgNwAQJyFgNyAQJ1FgN1AAM6AANCAANDAANE + AgJsCQJsFwJsKANsAgJtCQJtFwJtKANtAgJuCQJuFwJuKANuAgJwCQJwFwJwKANw + AwJsBgJsCgJsDwJsGAJsHwJsKQJsOANsAwJtBgJtCgJtDwJtGAJtHwJtKQJtOANt + AwJuBgJuCgJuDwJuGAJuHwJuKQJuOANuAwJwBgJwCgJwDwJwGAJwHwJwKQJwOANw + AgJyCQJyFwJyKANyAgJ1CQJ1FwJ1KAN1AQI6FgM6AQJCFgNCAQJDFgNDAQJEFgNE + AwJyBgJyCgJyDwJyGAJyHwJyKQJyOANyAwJ1BgJ1CgJ1DwJ1GAJ1HwJ1KQJ1OAN1 + AgI6CQI6FwI6KAM6AgJCCQJCFwJCKANCAgJDCQJDFwJDKANDAgJECQJEFwJEKANE + AwI6BgI6CgI6DwI6GAI6HwI6KQI6OAM6AwJCBgJCCgJCDwJCGAJCHwJCKQJCOANC + AwJDBgJDCgJDDwJDGAJDHwJDKQJDOANDAwJEBgJECgJEDwJEGAJEHwJEKQJEOANE + LAAALQAALwAAMAAAMwAANAAANgAANwAAOwAAPAAAPgAAPwAAQgAAQwAARQAASAEA + AANFAANGAANHAANIAANJAANKAANLAANMAANNAANOAANPAANQAANRAANSAANTAANU + AQJFFgNFAQJGFgNGAQJHFgNHAQJIFgNIAQJJFgNJAQJKFgNKAQJLFgNLAQJMFgNM + AgJFCQJFFwJFKANFAgJGCQJGFwJGKANGAgJHCQJHFwJHKANHAgJICQJIFwJIKANI + AwJFBgJFCgJFDwJFGAJFHwJFKQJFOANFAwJGBgJGCgJGDwJGGAJGHwJGKQJGOANG + AwJHBgJHCgJHDwJHGAJHHwJHKQJHOANHAwJIBgJICgJIDwJIGAJIHwJIKQJIOANI + AgJJCQJJFwJJKANJAgJKCQJKFwJKKANKAgJLCQJLFwJLKANLAgJMCQJMFwJMKANM + AwJJBgJJCgJJDwJJGAJJHwJJKQJJOANJAwJKBgJKCgJKDwJKGAJKHwJKKQJKOANK + AwJLBgJLCgJLDwJLGAJLHwJLKQJLOANLAwJMBgJMCgJMDwJMGAJMHwJMKQJMOANM + AQJNFgNNAQJOFgNOAQJPFgNPAQJQFgNQAQJRFgNRAQJSFgNSAQJTFgNTAQJUFgNU + AgJNCQJNFwJNKANNAgJOCQJOFwJOKANOAgJPCQJPFwJPKANPAgJQCQJQFwJQKANQ + AwJNBgJNCgJNDwJNGAJNHwJNKQJNOANNAwJOBgJOCgJODwJOGAJOHwJOKQJOOANO + AwJPBgJPCgJPDwJPGAJPHwJPKQJPOANPAwJQBgJQCgJQDwJQGAJQHwJQKQJQOANQ + AgJRCQJRFwJRKANRAgJSCQJSFwJSKANSAgJTCQJTFwJTKANTAgJUCQJUFwJUKANU + AwJRBgJRCgJRDwJRGAJRHwJRKQJROANRAwJSBgJSCgJSDwJSGAJSHwJSKQJSOANS + AwJTBgJTCgJTDwJTGAJTHwJTKQJTOANTAwJUBgJUCgJUDwJUGAJUHwJUKQJUOANU + AANVAANWAANXAANZAANqAANrAANxAAN2AAN3AAN4AAN5AAN6RgAARwAASQAASgEA + AQJVFgNVAQJWFgNWAQJXFgNXAQJZFgNZAQJqFgNqAQJrFgNrAQJxFgNxAQJ2FgN2 + AgJVCQJVFwJVKANVAgJWCQJWFwJWKANWAgJXCQJXFwJXKANXAgJZCQJZFwJZKANZ + AwJVBgJVCgJVDwJVGAJVHwJVKQJVOANVAwJWBgJWCgJWDwJWGAJWHwJWKQJWOANW + AwJXBgJXCgJXDwJXGAJXHwJXKQJXOANXAwJZBgJZCgJZDwJZGAJZHwJZKQJZOANZ + AgJqCQJqFwJqKANqAgJrCQJrFwJrKANrAgJxCQJxFwJxKANxAgJ2CQJ2FwJ2KAN2 + AwJqBgJqCgJqDwJqGAJqHwJqKQJqOANqAwJrBgJrCgJrDwJrGAJrHwJrKQJrOANr + AwJxBgJxCgJxDwJxGAJxHwJxKQJxOANxAwJ2BgJ2CgJ2DwJ2GAJ2HwJ2KQJ2OAN2 + AQJ3FgN3AQJ4FgN4AQJ5FgN5AQJ6FgN6AAMmAAMqAAMsAAM7AANYAANaSwAATgAA + AgJ3CQJ3FwJ3KAN3AgJ4CQJ4FwJ4KAN4AgJ5CQJ5FwJ5KAN5AgJ6CQJ6FwJ6KAN6 + AwJ3BgJ3CgJ3DwJ3GAJ3HwJ3KQJ3OAN3AwJ4BgJ4CgJ4DwJ4GAJ4HwJ4KQJ4OAN4 + AwJ5BgJ5CgJ5DwJ5GAJ5HwJ5KQJ5OAN5AwJ6BgJ6CgJ6DwJ6GAJ6HwJ6KQJ6OAN6 + AQImFgMmAQIqFgMqAQIsFgMsAQI7FgM7AQJYFgNYAQJaFgNaTAAATQAATwAAUQAA + AgImCQImFwImKAMmAgIqCQIqFwIqKAMqAgIsCQIsFwIsKAMsAgI7CQI7FwI7KAM7 + AwImBgImCgImDwImGAImHwImKQImOAMmAwIqBgIqCgIqDwIqGAIqHwIqKQIqOAMq + AwIsBgIsCgIsDwIsGAIsHwIsKQIsOAMsAwI7BgI7CgI7DwI7GAI7HwI7KQI7OAM7 + AgJYCQJYFwJYKANYAgJaCQJaFwJaKANaAAMhAAMiAAMoAAMpAAM/UAAAUgAAVAAA + AwJYBgJYCgJYDwJYGAJYHwJYKQJYOANYAwJaBgJaCgJaDwJaGAJaHwJaKQJaOANa + AQIhFgMhAQIiFgMiAQIoFgMoAQIpFgMpAQI/FgM/AAMnAAMrAAN8UwAAVQAAWAAA + AgIhCQIhFwIhKAMhAgIiCQIiFwIiKAMiAgIoCQIoFwIoKAMoAgIpCQIpFwIpKAMp + AwIhBgIhCgIhDwIhGAIhHwIhKQIhOAMhAwIiBgIiCgIiDwIiGAIiHwIiKQIiOAMi + AwIoBgIoCgIoDwIoGAIoHwIoKQIoOAMoAwIpBgIpCgIpDwIpGAIpHwIpKQIpOAMp + AgI/CQI/FwI/KAM/AQInFgMnAQIrFgMrAQJ8FgN8AAMjAAM+VgAAVwAAWQAAWgAA + AwI/BgI/CgI/DwI/GAI/HwI/KQI/OAM/AgInCQInFwInKAMnAgIrCQIrFwIrKAMr + AwInBgInCgInDwInGAInHwInKQInOAMnAwIrBgIrCgIrDwIrGAIrHwIrKQIrOAMr + AgJ8CQJ8FwJ8KAN8AQIjFgMjAQI+FgM+AAMAAAMkAANAAANbAANdAAN+WwAAXAAA + AwJ8BgJ8CgJ8DwJ8GAJ8HwJ8KQJ8OAN8AgIjCQIjFwIjKAMjAgI+CQI+FwI+KAM+ + AwIjBgIjCgIjDwIjGAIjHwIjKQIjOAMjAwI+BgI+CgI+DwI+GAI+HwI+KQI+OAM+ + AQIAFgMAAQIkFgMkAQJAFgNAAQJbFgNbAQJdFgNdAQJ+FgN+AANeAAN9XQAAXgAA + AgIACQIAFwIAKAMAAgIkCQIkFwIkKAMkAgJACQJAFwJAKANAAgJbCQJbFwJbKANb + AwIABgIACgIADwIAGAIAHwIAKQIAOAMAAwIkBgIkCgIkDwIkGAIkHwIkKQIkOAMk + AwJABgJACgJADwJAGAJAHwJAKQJAOANAAwJbBgJbCgJbDwJbGAJbHwJbKQJbOANb + AgJdCQJdFwJdKANdAgJ+CQJ+FwJ+KAN+AQJeFgNeAQJ9FgN9AAM8AANgAAN7XwAA + AwJdBgJdCgJdDwJdGAJdHwJdKQJdOANdAwJ+BgJ+CgJ+DwJ+GAJ+HwJ+KQJ+OAN+ + AgJeCQJeFwJeKANeAgJ9CQJ9FwJ9KAN9AQI8FgM8AQJgFgNgAQJ7FgN7YAAAbgAA + AwJeBgJeCgJeDwJeGAJeHwJeKQJeOANeAwJ9BgJ9CgJ9DwJ9GAJ9HwJ9KQJ9OAN9 + AgI8CQI8FwI8KAM8AgJgCQJgFwJgKANgAgJ7CQJ7FwJ7KAN7YQAAZQAAbwAAhQAA + AwI8BgI8CgI8DwI8GAI8HwI8KQI8OAM8AwJgBgJgCgJgDwJgGAJgHwJgKQJgOANg + AwJ7BgJ7CgJ7DwJ7GAJ7HwJ7KQJ7OAN7YgAAYwAAZgAAaQAAcAAAdwAAhgAAmQAA + AANcAAPDAAPQZAAAZwAAaAAAagAAawAAcQAAdAAAeAAAfgAAhwAAjgAAmgAAqQAA + AQJcFgNcAQLDFgPDAQLQFgPQAAOAAAOCAAODAAOiAAO4AAPCAAPgAAPibAAAbQAA + AgJcCQJcFwJcKANcAgLDCQLDFwLDKAPDAgLQCQLQFwLQKAPQAQKAFgOAAQKCFgOC + AwJcBgJcCgJcDwJcGAJcHwJcKQJcOANcAwLDBgLDCgLDDwLDGALDHwLDKQLDOAPD + AwLQBgLQCgLQDwLQGALQHwLQKQLQOAPQAgKACQKAFwKAKAOAAgKCCQKCFwKCKAOC + AwKABgKACgKADwKAGAKAHwKAKQKAOAOAAwKCBgKCCgKCDwKCGAKCHwKCKQKCOAOC + AQKDFgODAQKiFgOiAQK4FgO4AQLCFgPCAQLgFgPgAQLiFgPiAAOZAAOhAAOnAAOs + AgKDCQKDFwKDKAODAgKiCQKiFwKiKAOiAgK4CQK4FwK4KAO4AgLCCQLCFwLCKAPC + AwKDBgKDCgKDDwKDGAKDHwKDKQKDOAODAwKiBgKiCgKiDwKiGAKiHwKiKQKiOAOi + AwK4BgK4CgK4DwK4GAK4HwK4KQK4OAO4AwLCBgLCCgLCDwLCGALCHwLCKQLCOAPC + AgLgCQLgFwLgKAPgAgLiCQLiFwLiKAPiAQKZFgOZAQKhFgOhAQKnFgOnAQKsFgOs + AwLgBgLgCgLgDwLgGALgHwLgKQLgOAPgAwLiBgLiCgLiDwLiGALiHwLiKQLiOAPi + AgKZCQKZFwKZKAOZAgKhCQKhFwKhKAOhAgKnCQKnFwKnKAOnAgKsCQKsFwKsKAOs + AwKZBgKZCgKZDwKZGAKZHwKZKQKZOAOZAwKhBgKhCgKhDwKhGAKhHwKhKQKhOAOh + AwKnBgKnCgKnDwKnGAKnHwKnKQKnOAOnAwKsBgKsCgKsDwKsGAKsHwKsKQKsOAOs + cgAAcwAAdQAAdgAAeQAAewAAfwAAggAAiAAAiwAAjwAAkgAAmwAAogAAqgAAtAAA + AAOwAAOxAAOzAAPRAAPYAAPZAAPjAAPlAAPmegAAfAAAfQAAgAAAgQAAgwAAhAAA + AQKwFgOwAQKxFgOxAQKzFgOzAQLRFgPRAQLYFgPYAQLZFgPZAQLjFgPjAQLlFgPl + AgKwCQKwFwKwKAOwAgKxCQKxFwKxKAOxAgKzCQKzFwKzKAOzAgLRCQLRFwLRKAPR + AwKwBgKwCgKwDwKwGAKwHwKwKQKwOAOwAwKxBgKxCgKxDwKxGAKxHwKxKQKxOAOx + AwKzBgKzCgKzDwKzGAKzHwKzKQKzOAOzAwLRBgLRCgLRDwLRGALRHwLRKQLROAPR + AgLYCQLYFwLYKAPYAgLZCQLZFwLZKAPZAgLjCQLjFwLjKAPjAgLlCQLlFwLlKAPl + AwLYBgLYCgLYDwLYGALYHwLYKQLYOAPYAwLZBgLZCgLZDwLZGALZHwLZKQLZOAPZ + AwLjBgLjCgLjDwLjGALjHwLjKQLjOAPjAwLlBgLlCgLlDwLlGALlHwLlKQLlOAPl + AQLmFgPmAAOBAAOEAAOFAAOGAAOIAAOSAAOaAAOcAAOgAAOjAAOkAAOpAAOqAAOt + AgLmCQLmFwLmKAPmAQKBFgOBAQKEFgOEAQKFFgOFAQKGFgOGAQKIFgOIAQKSFgOS + AwLmBgLmCgLmDwLmGALmHwLmKQLmOAPmAgKBCQKBFwKBKAOBAgKECQKEFwKEKAOE + AwKBBgKBCgKBDwKBGAKBHwKBKQKBOAOBAwKEBgKECgKEDwKEGAKEHwKEKQKEOAOE + AgKFCQKFFwKFKAOFAgKGCQKGFwKGKAOGAgKICQKIFwKIKAOIAgKSCQKSFwKSKAOS + AwKFBgKFCgKFDwKFGAKFHwKFKQKFOAOFAwKGBgKGCgKGDwKGGAKGHwKGKQKGOAOG + AwKIBgKICgKIDwKIGAKIHwKIKQKIOAOIAwKSBgKSCgKSDwKSGAKSHwKSKQKSOAOS + AQKaFgOaAQKcFgOcAQKgFgOgAQKjFgOjAQKkFgOkAQKpFgOpAQKqFgOqAQKtFgOt + AgKaCQKaFwKaKAOaAgKcCQKcFwKcKAOcAgKgCQKgFwKgKAOgAgKjCQKjFwKjKAOj + AwKaBgKaCgKaDwKaGAKaHwKaKQKaOAOaAwKcBgKcCgKcDwKcGAKcHwKcKQKcOAOc + AwKgBgKgCgKgDwKgGAKgHwKgKQKgOAOgAwKjBgKjCgKjDwKjGAKjHwKjKQKjOAOj + AgKkCQKkFwKkKAOkAgKpCQKpFwKpKAOpAgKqCQKqFwKqKAOqAgKtCQKtFwKtKAOt + AwKkBgKkCgKkDwKkGAKkHwKkKQKkOAOkAwKpBgKpCgKpDwKpGAKpHwKpKQKpOAOp + AwKqBgKqCgKqDwKqGAKqHwKqKQKqOAOqAwKtBgKtCgKtDwKtGAKtHwKtKQKtOAOt + iQAAigAAjAAAjQAAkAAAkQAAkwAAlgAAnAAAnwAAowAApgAAqwAArgAAtQAAvgAA + AAOyAAO1AAO5AAO6AAO7AAO9AAO+AAPEAAPGAAPkAAPoAAPplAAAlQAAlwAAmAAA + AQKyFgOyAQK1FgO1AQK5FgO5AQK6FgO6AQK7FgO7AQK9FgO9AQK+FgO+AQLEFgPE + AgKyCQKyFwKyKAOyAgK1CQK1FwK1KAO1AgK5CQK5FwK5KAO5AgK6CQK6FwK6KAO6 + AwKyBgKyCgKyDwKyGAKyHwKyKQKyOAOyAwK1BgK1CgK1DwK1GAK1HwK1KQK1OAO1 + AwK5BgK5CgK5DwK5GAK5HwK5KQK5OAO5AwK6BgK6CgK6DwK6GAK6HwK6KQK6OAO6 + AgK7CQK7FwK7KAO7AgK9CQK9FwK9KAO9AgK+CQK+FwK+KAO+AgLECQLEFwLEKAPE + AwK7BgK7CgK7DwK7GAK7HwK7KQK7OAO7AwK9BgK9CgK9DwK9GAK9HwK9KQK9OAO9 + AwK+BgK+CgK+DwK+GAK+HwK+KQK+OAO+AwLEBgLECgLEDwLEGALEHwLEKQLEOAPE + AQLGFgPGAQLkFgPkAQLoFgPoAQLpFgPpAAMBAAOHAAOJAAOKAAOLAAOMAAONAAOP + AgLGCQLGFwLGKAPGAgLkCQLkFwLkKAPkAgLoCQLoFwLoKAPoAgLpCQLpFwLpKAPp + AwLGBgLGCgLGDwLGGALGHwLGKQLGOAPGAwLkBgLkCgLkDwLkGALkHwLkKQLkOAPk + AwLoBgLoCgLoDwLoGALoHwLoKQLoOAPoAwLpBgLpCgLpDwLpGALpHwLpKQLpOAPp + AQIBFgMBAQKHFgOHAQKJFgOJAQKKFgOKAQKLFgOLAQKMFgOMAQKNFgONAQKPFgOP + AgIBCQIBFwIBKAMBAgKHCQKHFwKHKAOHAgKJCQKJFwKJKAOJAgKKCQKKFwKKKAOK + AwIBBgIBCgIBDwIBGAIBHwIBKQIBOAMBAwKHBgKHCgKHDwKHGAKHHwKHKQKHOAOH + AwKJBgKJCgKJDwKJGAKJHwKJKQKJOAOJAwKKBgKKCgKKDwKKGAKKHwKKKQKKOAOK + AgKLCQKLFwKLKAOLAgKMCQKMFwKMKAOMAgKNCQKNFwKNKAONAgKPCQKPFwKPKAOP + AwKLBgKLCgKLDwKLGAKLHwKLKQKLOAOLAwKMBgKMCgKMDwKMGAKMHwKMKQKMOAOM + AwKNBgKNCgKNDwKNGAKNHwKNKQKNOAONAwKPBgKPCgKPDwKPGAKPHwKPKQKPOAOP + nQAAngAAoAAAoQAApAAApQAApwAAqAAArAAArQAArwAAsQAAtgAAuQAAvwAAzwAA + AAOTAAOVAAOWAAOXAAOYAAObAAOdAAOeAAOlAAOmAAOoAAOuAAOvAAO0AAO2AAO3 + AQKTFgOTAQKVFgOVAQKWFgOWAQKXFgOXAQKYFgOYAQKbFgObAQKdFgOdAQKeFgOe + AgKTCQKTFwKTKAOTAgKVCQKVFwKVKAOVAgKWCQKWFwKWKAOWAgKXCQKXFwKXKAOX + AwKTBgKTCgKTDwKTGAKTHwKTKQKTOAOTAwKVBgKVCgKVDwKVGAKVHwKVKQKVOAOV + AwKWBgKWCgKWDwKWGAKWHwKWKQKWOAOWAwKXBgKXCgKXDwKXGAKXHwKXKQKXOAOX + AgKYCQKYFwKYKAOYAgKbCQKbFwKbKAObAgKdCQKdFwKdKAOdAgKeCQKeFwKeKAOe + AwKYBgKYCgKYDwKYGAKYHwKYKQKYOAOYAwKbBgKbCgKbDwKbGAKbHwKbKQKbOAOb + AwKdBgKdCgKdDwKdGAKdHwKdKQKdOAOdAwKeBgKeCgKeDwKeGAKeHwKeKQKeOAOe + AQKlFgOlAQKmFgOmAQKoFgOoAQKuFgOuAQKvFgOvAQK0FgO0AQK2FgO2AQK3FgO3 + AgKlCQKlFwKlKAOlAgKmCQKmFwKmKAOmAgKoCQKoFwKoKAOoAgKuCQKuFwKuKAOu + AwKlBgKlCgKlDwKlGAKlHwKlKQKlOAOlAwKmBgKmCgKmDwKmGAKmHwKmKQKmOAOm + AwKoBgKoCgKoDwKoGAKoHwKoKQKoOAOoAwKuBgKuCgKuDwKuGAKuHwKuKQKuOAOu + AgKvCQKvFwKvKAOvAgK0CQK0FwK0KAO0AgK2CQK2FwK2KAO2AgK3CQK3FwK3KAO3 + AwKvBgKvCgKvDwKvGAKvHwKvKQKvOAOvAwK0BgK0CgK0DwK0GAK0HwK0KQK0OAO0 + AwK2BgK2CgK2DwK2GAK2HwK2KQK2OAO2AwK3BgK3CgK3DwK3GAK3HwK3KQK3OAO3 + AAO8AAO/AAPFAAPnAAPvsAAAsgAAswAAtwAAuAAAugAAuwAAwAAAxwAA0AAA3wAA + AQK8FgO8AQK/FgO/AQLFFgPFAQLnFgPnAQLvFgPvAAMJAAOOAAOQAAORAAOUAAOf + AgK8CQK8FwK8KAO8AgK/CQK/FwK/KAO/AgLFCQLFFwLFKAPFAgLnCQLnFwLnKAPn + AwK8BgK8CgK8DwK8GAK8HwK8KQK8OAO8AwK/BgK/CgK/DwK/GAK/HwK/KQK/OAO/ + AwLFBgLFCgLFDwLFGALFHwLFKQLFOAPFAwLnBgLnCgLnDwLnGALnHwLnKQLnOAPn + AgLvCQLvFwLvKAPvAQIJFgMJAQKOFgOOAQKQFgOQAQKRFgORAQKUFgOUAQKfFgOf + AwLvBgLvCgLvDwLvGALvHwLvKQLvOAPvAgIJCQIJFwIJKAMJAgKOCQKOFwKOKAOO + AwIJBgIJCgIJDwIJGAIJHwIJKQIJOAMJAwKOBgKOCgKODwKOGAKOHwKOKQKOOAOO + AgKQCQKQFwKQKAOQAgKRCQKRFwKRKAORAgKUCQKUFwKUKAOUAgKfCQKfFwKfKAOf + AwKQBgKQCgKQDwKQGAKQHwKQKQKQOAOQAwKRBgKRCgKRDwKRGAKRHwKRKQKROAOR + AwKUBgKUCgKUDwKUGAKUHwKUKQKUOAOUAwKfBgKfCgKfDwKfGAKfHwKfKQKfOAOf + AAOrAAPOAAPXAAPhAAPsAAPtvAAAvQAAwQAAxAAAyAAAywAA0QAA2AAA4AAA7gAA + AQKrFgOrAQLOFgPOAQLXFgPXAQLhFgPhAQLsFgPsAQLtFgPtAAPHAAPPAAPqAAPr + AgKrCQKrFwKrKAOrAgLOCQLOFwLOKAPOAgLXCQLXFwLXKAPXAgLhCQLhFwLhKAPh + AwKrBgKrCgKrDwKrGAKrHwKrKQKrOAOrAwLOBgLOCgLODwLOGALOHwLOKQLOOAPO + AwLXBgLXCgLXDwLXGALXHwLXKQLXOAPXAwLhBgLhCgLhDwLhGALhHwLhKQLhOAPh + AgLsCQLsFwLsKAPsAgLtCQLtFwLtKAPtAQLHFgPHAQLPFgPPAQLqFgPqAQLrFgPr + AwLsBgLsCgLsDwLsGALsHwLsKQLsOAPsAwLtBgLtCgLtDwLtGALtHwLtKQLtOAPt + AgLHCQLHFwLHKAPHAgLPCQLPFwLPKAPPAgLqCQLqFwLqKAPqAgLrCQLrFwLrKAPr + AwLHBgLHCgLHDwLHGALHHwLHKQLHOAPHAwLPBgLPCgLPDwLPGALPHwLPKQLPOAPP + AwLqBgLqCgLqDwLqGALqHwLqKQLqOAPqAwLrBgLrCgLrDwLrGALrHwLrKQLrOAPr + wgAAwwAAxQAAxgAAyQAAygAAzAAAzQAA0gAA1QAA2QAA3AAA4QAA5wAA7wAA9gAA + AAPAAAPBAAPIAAPJAAPKAAPNAAPSAAPVAAPaAAPbAAPuAAPwAAPyAAPzAAP/zgAA + AQLAFgPAAQLBFgPBAQLIFgPIAQLJFgPJAQLKFgPKAQLNFgPNAQLSFgPSAQLVFgPV + AgLACQLAFwLAKAPAAgLBCQLBFwLBKAPBAgLICQLIFwLIKAPIAgLJCQLJFwLJKAPJ + AwLABgLACgLADwLAGALAHwLAKQLAOAPAAwLBBgLBCgLBDwLBGALBHwLBKQLBOAPB + AwLIBgLICgLIDwLIGALIHwLIKQLIOAPIAwLJBgLJCgLJDwLJGALJHwLJKQLJOAPJ + AgLKCQLKFwLKKAPKAgLNCQLNFwLNKAPNAgLSCQLSFwLSKAPSAgLVCQLVFwLVKAPV + AwLKBgLKCgLKDwLKGALKHwLKKQLKOAPKAwLNBgLNCgLNDwLNGALNHwLNKQLNOAPN + AwLSBgLSCgLSDwLSGALSHwLSKQLSOAPSAwLVBgLVCgLVDwLVGALVHwLVKQLVOAPV + AQLaFgPaAQLbFgPbAQLuFgPuAQLwFgPwAQLyFgPyAQLzFgPzAQL/FgP/AAPLAAPM + AgLaCQLaFwLaKAPaAgLbCQLbFwLbKAPbAgLuCQLuFwLuKAPuAgLwCQLwFwLwKAPw + AwLaBgLaCgLaDwLaGALaHwLaKQLaOAPaAwLbBgLbCgLbDwLbGALbHwLbKQLbOAPb + AwLuBgLuCgLuDwLuGALuHwLuKQLuOAPuAwLwBgLwCgLwDwLwGALwHwLwKQLwOAPw + AgLyCQLyFwLyKAPyAgLzCQLzFwLzKAPzAgL/CQL/FwL/KAP/AQLLFgPLAQLMFgPM + AwLyBgLyCgLyDwLyGALyHwLyKQLyOAPyAwLzBgLzCgLzDwLzGALzHwLzKQLzOAPz + AwL/BgL/CgL/DwL/GAL/HwL/KQL/OAP/AgLLCQLLFwLLKAPLAgLMCQLMFwLMKAPM + AwLLBgLLCgLLDwLLGALLHwLLKQLLOAPLAwLMBgLMCgLMDwLMGALMHwLMKQLMOAPM + 0wAA1AAA1gAA1wAA2gAA2wAA3QAA3gAA4gAA5AAA6AAA6wAA8AAA8wAA9wAA+gAA + AAPTAAPUAAPWAAPdAAPeAAPfAAPxAAP0AAP1AAP2AAP3AAP4AAP6AAP7AAP8AAP9 + AQLTFgPTAQLUFgPUAQLWFgPWAQLdFgPdAQLeFgPeAQLfFgPfAQLxFgPxAQL0FgP0 + AgLTCQLTFwLTKAPTAgLUCQLUFwLUKAPUAgLWCQLWFwLWKAPWAgLdCQLdFwLdKAPd + AwLTBgLTCgLTDwLTGALTHwLTKQLTOAPTAwLUBgLUCgLUDwLUGALUHwLUKQLUOAPU + AwLWBgLWCgLWDwLWGALWHwLWKQLWOAPWAwLdBgLdCgLdDwLdGALdHwLdKQLdOAPd + AgLeCQLeFwLeKAPeAgLfCQLfFwLfKAPfAgLxCQLxFwLxKAPxAgL0CQL0FwL0KAP0 + AwLeBgLeCgLeDwLeGALeHwLeKQLeOAPeAwLfBgLfCgLfDwLfGALfHwLfKQLfOAPf + AwLxBgLxCgLxDwLxGALxHwLxKQLxOAPxAwL0BgL0CgL0DwL0GAL0HwL0KQL0OAP0 + AQL1FgP1AQL2FgP2AQL3FgP3AQL4FgP4AQL6FgP6AQL7FgP7AQL8FgP8AQL9FgP9 + AgL1CQL1FwL1KAP1AgL2CQL2FwL2KAP2AgL3CQL3FwL3KAP3AgL4CQL4FwL4KAP4 + AwL1BgL1CgL1DwL1GAL1HwL1KQL1OAP1AwL2BgL2CgL2DwL2GAL2HwL2KQL2OAP2 + AwL3BgL3CgL3DwL3GAL3HwL3KQL3OAP3AwL4BgL4CgL4DwL4GAL4HwL4KQL4OAP4 + AgL6CQL6FwL6KAP6AgL7CQL7FwL7KAP7AgL8CQL8FwL8KAP8AgL9CQL9FwL9KAP9 + AwL6BgL6CgL6DwL6GAL6HwL6KQL6OAP6AwL7BgL7CgL7DwL7GAL7HwL7KQL7OAP7 + AwL8BgL8CgL8DwL8GAL8HwL8KQL8OAP8AwL9BgL9CgL9DwL9GAL9HwL9KQL9OAP9 + AAP+4wAA5QAA5gAA6QAA6gAA7AAA7QAA8QAA8gAA9AAA9QAA+AAA+QAA+wAA/AAA + AQL+FgP+AAMCAAMDAAMEAAMFAAMGAAMHAAMIAAMLAAMMAAMOAAMPAAMQAAMRAAMS + AgL+CQL+FwL+KAP+AQICFgMCAQIDFgMDAQIEFgMEAQIFFgMFAQIGFgMGAQIHFgMH + AwL+BgL+CgL+DwL+GAL+HwL+KQL+OAP+AgICCQICFwICKAMCAgIDCQIDFwIDKAMD + AwICBgICCgICDwICGAICHwICKQICOAMCAwIDBgIDCgIDDwIDGAIDHwIDKQIDOAMD + AgIECQIEFwIEKAMEAgIFCQIFFwIFKAMFAgIGCQIGFwIGKAMGAgIHCQIHFwIHKAMH + AwIEBgIECgIEDwIEGAIEHwIEKQIEOAMEAwIFBgIFCgIFDwIFGAIFHwIFKQIFOAMF + AwIGBgIGCgIGDwIGGAIGHwIGKQIGOAMGAwIHBgIHCgIHDwIHGAIHHwIHKQIHOAMH + AQIIFgMIAQILFgMLAQIMFgMMAQIOFgMOAQIPFgMPAQIQFgMQAQIRFgMRAQISFgMS + AgIICQIIFwIIKAMIAgILCQILFwILKAMLAgIMCQIMFwIMKAMMAgIOCQIOFwIOKAMO + AwIIBgIICgIIDwIIGAIIHwIIKQIIOAMIAwILBgILCgILDwILGAILHwILKQILOAML + AwIMBgIMCgIMDwIMGAIMHwIMKQIMOAMMAwIOBgIOCgIODwIOGAIOHwIOKQIOOAMO + AgIPCQIPFwIPKAMPAgIQCQIQFwIQKAMQAgIRCQIRFwIRKAMRAgISCQISFwISKAMS + AwIPBgIPCgIPDwIPGAIPHwIPKQIPOAMPAwIQBgIQCgIQDwIQGAIQHwIQKQIQOAMQ + AwIRBgIRCgIRDwIRGAIRHwIRKQIROAMRAwISBgISCgISDwISGAISHwISKQISOAMS + AAMTAAMUAAMVAAMXAAMYAAMZAAMaAAMbAAMcAAMdAAMeAAMfAAN/AAPcAAP5/QAA + AQITFgMTAQIUFgMUAQIVFgMVAQIXFgMXAQIYFgMYAQIZFgMZAQIaFgMaAQIbFgMb + AgITCQITFwITKAMTAgIUCQIUFwIUKAMUAgIVCQIVFwIVKAMVAgIXCQIXFwIXKAMX + AwITBgITCgITDwITGAITHwITKQITOAMTAwIUBgIUCgIUDwIUGAIUHwIUKQIUOAMU + AwIVBgIVCgIVDwIVGAIVHwIVKQIVOAMVAwIXBgIXCgIXDwIXGAIXHwIXKQIXOAMX + AgIYCQIYFwIYKAMYAgIZCQIZFwIZKAMZAgIaCQIaFwIaKAMaAgIbCQIbFwIbKAMb + AwIYBgIYCgIYDwIYGAIYHwIYKQIYOAMYAwIZBgIZCgIZDwIZGAIZHwIZKQIZOAMZ + AwIaBgIaCgIaDwIaGAIaHwIaKQIaOAMaAwIbBgIbCgIbDwIbGAIbHwIbKQIbOAMb + AQIcFgMcAQIdFgMdAQIeFgMeAQIfFgMfAQJ/FgN/AQLcFgPcAQL5FgP5/gAA/wAA + AgIcCQIcFwIcKAMcAgIdCQIdFwIdKAMdAgIeCQIeFwIeKAMeAgIfCQIfFwIfKAMf + AwIcBgIcCgIcDwIcGAIcHwIcKQIcOAMcAwIdBgIdCgIdDwIdGAIdHwIdKQIdOAMd + AwIeBgIeCgIeDwIeGAIeHwIeKQIeOAMeAwIfBgIfCgIfDwIfGAIfHwIfKQIfOAMf + AgJ/CQJ/FwJ/KAN/AgLcCQLcFwLcKAPcAgL5CQL5FwL5KAP5AAMKAAMNAAMWAAQA + AwJ/BgJ/CgJ/DwJ/GAJ/HwJ/KQJ/OAN/AwLcBgLcCgLcDwLcGALcHwLcKQLcOAPc + AwL5BgL5CgL5DwL5GAL5HwL5KQL5OAP5AQIKFgMKAQINFgMNAQIWFgMWAAQAAAQA + AgIKCQIKFwIKKAMKAgINCQINFwINKAMNAgIWCQIWFwIWKAMWAAQAAAQAAAQAAAQA + AwIKBgIKCgIKDwIKGAIKHwIKKQIKOAMKAwINBgINCgINDwINGAINHwINKQINOAMN + AwIWBgIWCgIWDwIWGAIWHwIWKQIWOAMWAAQAAAQAAAQAAAQAAAQAAAQAAAQAAAQA + """ + return base64_table_bytes.withUTF8Buffer { buf in + // ignore newlines in the input + guard let result = base64DecodeBytes(buf, ignoreUnknownCharacters: true) else { + fatalError("Failed to decode huffman decoder table from base-64 encoding") + } + return result.withUnsafeBytes { ptr in + assert(ptr.count % 3 == 0) + let dptr = ptr.baseAddress!.assumingMemoryBound(to: HuffmanDecodeEntry.self) + let dbuf = UnsafeBufferPointer(start: dptr, count: ptr.count / 3) + return Array(dbuf) + } + } + }() + + // for posterity, here's what the table effectively looks like: + /* + private static let rawTable: [HuffmanDecodeEntry] = [ + + /* 0 */ + + (4, .none, 0), + (5, .none, 0), + (7, .none, 0), + (8, .none, 0), + (11, .none, 0), + (12, .none, 0), + (16, .none, 0), + (19, .none, 0), + (25, .none, 0), + (28, .none, 0), + (32, .none, 0), + (35, .none, 0), + (42, .none, 0), + (49, .none, 0), + (57, .none, 0), + (64, .accepted, 0), + + /* 1 */ + + (0, [.accepted, .symbol], 48), + (0, [.accepted, .symbol], 49), + (0, [.accepted, .symbol], 50), + (0, [.accepted, .symbol], 97), + (0, [.accepted, .symbol], 99), + (0, [.accepted, .symbol], 101), + (0, [.accepted, .symbol], 105), + (0, [.accepted, .symbol], 111), + (0, [.accepted, .symbol], 115), + (0, [.accepted, .symbol], 116), + (13, .none, 0), + (14, .none, 0), + (17, .none, 0), + (18, .none, 0), + (20, .none, 0), + (21, .none, 0), + + /* 2 */ + + (1, .symbol, 48), + (22, [.accepted, .symbol], 48), + (1, .symbol, 49), + (22, [.accepted, .symbol], 49), + (1, .symbol, 50), + (22, [.accepted, .symbol], 50), + (1, .symbol, 97), + (22, [.accepted, .symbol], 97), + (1, .symbol, 99), + (22, [.accepted, .symbol], 99), + (1, .symbol, 101), + (22, [.accepted, .symbol], 101), + (1, .symbol, 105), + (22, [.accepted, .symbol], 105), + (1, .symbol, 111), + (22, [.accepted, .symbol], 111), + + /* 3 */ + + (2, .symbol, 48), + (9, .symbol, 48), + (23, .symbol, 48), + (40, [.accepted, .symbol], 48), + (2, .symbol, 49), + (9, .symbol, 49), + (23, .symbol, 49), + (40, [.accepted, .symbol], 49), + (2, .symbol, 50), + (9, .symbol, 50), + (23, .symbol, 50), + (40, [.accepted, .symbol], 50), + (2, .symbol, 97), + (9, .symbol, 97), + (23, .symbol, 97), + (40, [.accepted, .symbol], 97), + + /* 4 */ + + (3, .symbol, 48), + (6, .symbol, 48), + (10, .symbol, 48), + (15, .symbol, 48), + (24, .symbol, 48), + (31, .symbol, 48), + (41, .symbol, 48), + (56, [.accepted, .symbol], 48), + (3, .symbol, 49), + (6, .symbol, 49), + (10, .symbol, 49), + (15, .symbol, 49), + (24, .symbol, 49), + (31, .symbol, 49), + (41, .symbol, 49), + (56, [.accepted, .symbol], 49), + + /* 5 */ + + (3, .symbol, 50), + (6, .symbol, 50), + (10, .symbol, 50), + (15, .symbol, 50), + (24, .symbol, 50), + (31, .symbol, 50), + (41, .symbol, 50), + (56, [.accepted, .symbol], 50), + (3, .symbol, 97), + (6, .symbol, 97), + (10, .symbol, 97), + (15, .symbol, 97), + (24, .symbol, 97), + (31, .symbol, 97), + (41, .symbol, 97), + (56, [.accepted, .symbol], 97), + + /* 6 */ + + (2, .symbol, 99), + (9, .symbol, 99), + (23, .symbol, 99), + (40, [.accepted, .symbol], 99), + (2, .symbol, 101), + (9, .symbol, 101), + (23, .symbol, 101), + (40, [.accepted, .symbol], 101), + (2, .symbol, 105), + (9, .symbol, 105), + (23, .symbol, 105), + (40, [.accepted, .symbol], 105), + (2, .symbol, 111), + (9, .symbol, 111), + (23, .symbol, 111), + (40, [.accepted, .symbol], 111), + + /* 7 */ + + (3, .symbol, 99), + (6, .symbol, 99), + (10, .symbol, 99), + (15, .symbol, 99), + (24, .symbol, 99), + (31, .symbol, 99), + (41, .symbol, 99), + (56, [.accepted, .symbol], 99), + (3, .symbol, 101), + (6, .symbol, 101), + (10, .symbol, 101), + (15, .symbol, 101), + (24, .symbol, 101), + (31, .symbol, 101), + (41, .symbol, 101), + (56, [.accepted, .symbol], 101), + + /* 8 */ + + (3, .symbol, 105), + (6, .symbol, 105), + (10, .symbol, 105), + (15, .symbol, 105), + (24, .symbol, 105), + (31, .symbol, 105), + (41, .symbol, 105), + (56, [.accepted, .symbol], 105), + (3, .symbol, 111), + (6, .symbol, 111), + (10, .symbol, 111), + (15, .symbol, 111), + (24, .symbol, 111), + (31, .symbol, 111), + (41, .symbol, 111), + (56, [.accepted, .symbol], 111), + + /* 9 */ + + (1, .symbol, 115), + (22, [.accepted, .symbol], 115), + (1, .symbol, 116), + (22, [.accepted, .symbol], 116), + (0, [.accepted, .symbol], 32), + (0, [.accepted, .symbol], 37), + (0, [.accepted, .symbol], 45), + (0, [.accepted, .symbol], 46), + (0, [.accepted, .symbol], 47), + (0, [.accepted, .symbol], 51), + (0, [.accepted, .symbol], 52), + (0, [.accepted, .symbol], 53), + (0, [.accepted, .symbol], 54), + (0, [.accepted, .symbol], 55), + (0, [.accepted, .symbol], 56), + (0, [.accepted, .symbol], 57), + + /* 10 */ + + (2, .symbol, 115), + (9, .symbol, 115), + (23, .symbol, 115), + (40, [.accepted, .symbol], 115), + (2, .symbol, 116), + (9, .symbol, 116), + (23, .symbol, 116), + (40, [.accepted, .symbol], 116), + (1, .symbol, 32), + (22, [.accepted, .symbol], 32), + (1, .symbol, 37), + (22, [.accepted, .symbol], 37), + (1, .symbol, 45), + (22, [.accepted, .symbol], 45), + (1, .symbol, 46), + (22, [.accepted, .symbol], 46), + + /* 11 */ + + (3, .symbol, 115), + (6, .symbol, 115), + (10, .symbol, 115), + (15, .symbol, 115), + (24, .symbol, 115), + (31, .symbol, 115), + (41, .symbol, 115), + (56, [.accepted, .symbol], 115), + (3, .symbol, 116), + (6, .symbol, 116), + (10, .symbol, 116), + (15, .symbol, 116), + (24, .symbol, 116), + (31, .symbol, 116), + (41, .symbol, 116), + (56, [.accepted, .symbol], 116), + + /* 12 */ + + (2, .symbol, 32), + (9, .symbol, 32), + (23, .symbol, 32), + (40, [.accepted, .symbol], 32), + (2, .symbol, 37), + (9, .symbol, 37), + (23, .symbol, 37), + (40, [.accepted, .symbol], 37), + (2, .symbol, 45), + (9, .symbol, 45), + (23, .symbol, 45), + (40, [.accepted, .symbol], 45), + (2, .symbol, 46), + (9, .symbol, 46), + (23, .symbol, 46), + (40, [.accepted, .symbol], 46), + + /* 13 */ + + (3, .symbol, 32), + (6, .symbol, 32), + (10, .symbol, 32), + (15, .symbol, 32), + (24, .symbol, 32), + (31, .symbol, 32), + (41, .symbol, 32), + (56, [.accepted, .symbol], 32), + (3, .symbol, 37), + (6, .symbol, 37), + (10, .symbol, 37), + (15, .symbol, 37), + (24, .symbol, 37), + (31, .symbol, 37), + (41, .symbol, 37), + (56, [.accepted, .symbol], 37), + + /* 14 */ + + (3, .symbol, 45), + (6, .symbol, 45), + (10, .symbol, 45), + (15, .symbol, 45), + (24, .symbol, 45), + (31, .symbol, 45), + (41, .symbol, 45), + (56, [.accepted, .symbol], 45), + (3, .symbol, 46), + (6, .symbol, 46), + (10, .symbol, 46), + (15, .symbol, 46), + (24, .symbol, 46), + (31, .symbol, 46), + (41, .symbol, 46), + (56, [.accepted, .symbol], 46), + + /* 15 */ + + (1, .symbol, 47), + (22, [.accepted, .symbol], 47), + (1, .symbol, 51), + (22, [.accepted, .symbol], 51), + (1, .symbol, 52), + (22, [.accepted, .symbol], 52), + (1, .symbol, 53), + (22, [.accepted, .symbol], 53), + (1, .symbol, 54), + (22, [.accepted, .symbol], 54), + (1, .symbol, 55), + (22, [.accepted, .symbol], 55), + (1, .symbol, 56), + (22, [.accepted, .symbol], 56), + (1, .symbol, 57), + (22, [.accepted, .symbol], 57), + + /* 16 */ + + (2, .symbol, 47), + (9, .symbol, 47), + (23, .symbol, 47), + (40, [.accepted, .symbol], 47), + (2, .symbol, 51), + (9, .symbol, 51), + (23, .symbol, 51), + (40, [.accepted, .symbol], 51), + (2, .symbol, 52), + (9, .symbol, 52), + (23, .symbol, 52), + (40, [.accepted, .symbol], 52), + (2, .symbol, 53), + (9, .symbol, 53), + (23, .symbol, 53), + (40, [.accepted, .symbol], 53), + + /* 17 */ + + (3, .symbol, 47), + (6, .symbol, 47), + (10, .symbol, 47), + (15, .symbol, 47), + (24, .symbol, 47), + (31, .symbol, 47), + (41, .symbol, 47), + (56, [.accepted, .symbol], 47), + (3, .symbol, 51), + (6, .symbol, 51), + (10, .symbol, 51), + (15, .symbol, 51), + (24, .symbol, 51), + (31, .symbol, 51), + (41, .symbol, 51), + (56, [.accepted, .symbol], 51), + + /* 18 */ + + (3, .symbol, 52), + (6, .symbol, 52), + (10, .symbol, 52), + (15, .symbol, 52), + (24, .symbol, 52), + (31, .symbol, 52), + (41, .symbol, 52), + (56, [.accepted, .symbol], 52), + (3, .symbol, 53), + (6, .symbol, 53), + (10, .symbol, 53), + (15, .symbol, 53), + (24, .symbol, 53), + (31, .symbol, 53), + (41, .symbol, 53), + (56, [.accepted, .symbol], 53), + + /* 19 */ + + (2, .symbol, 54), + (9, .symbol, 54), + (23, .symbol, 54), + (40, [.accepted, .symbol], 54), + (2, .symbol, 55), + (9, .symbol, 55), + (23, .symbol, 55), + (40, [.accepted, .symbol], 55), + (2, .symbol, 56), + (9, .symbol, 56), + (23, .symbol, 56), + (40, [.accepted, .symbol], 56), + (2, .symbol, 57), + (9, .symbol, 57), + (23, .symbol, 57), + (40, [.accepted, .symbol], 57), + + /* 20 */ + + (3, .symbol, 54), + (6, .symbol, 54), + (10, .symbol, 54), + (15, .symbol, 54), + (24, .symbol, 54), + (31, .symbol, 54), + (41, .symbol, 54), + (56, [.accepted, .symbol], 54), + (3, .symbol, 55), + (6, .symbol, 55), + (10, .symbol, 55), + (15, .symbol, 55), + (24, .symbol, 55), + (31, .symbol, 55), + (41, .symbol, 55), + (56, [.accepted, .symbol], 55), + + /* 21 */ + + (3, .symbol, 56), + (6, .symbol, 56), + (10, .symbol, 56), + (15, .symbol, 56), + (24, .symbol, 56), + (31, .symbol, 56), + (41, .symbol, 56), + (56, [.accepted, .symbol], 56), + (3, .symbol, 57), + (6, .symbol, 57), + (10, .symbol, 57), + (15, .symbol, 57), + (24, .symbol, 57), + (31, .symbol, 57), + (41, .symbol, 57), + (56, [.accepted, .symbol], 57), + + /* 22 */ + + (26, .none, 0), + (27, .none, 0), + (29, .none, 0), + (30, .none, 0), + (33, .none, 0), + (34, .none, 0), + (36, .none, 0), + (37, .none, 0), + (43, .none, 0), + (46, .none, 0), + (50, .none, 0), + (53, .none, 0), + (58, .none, 0), + (61, .none, 0), + (65, .none, 0), + (68, .accepted, 0), + + /* 23 */ + + (0, [.accepted, .symbol], 61), + (0, [.accepted, .symbol], 65), + (0, [.accepted, .symbol], 95), + (0, [.accepted, .symbol], 98), + (0, [.accepted, .symbol], 100), + (0, [.accepted, .symbol], 102), + (0, [.accepted, .symbol], 103), + (0, [.accepted, .symbol], 104), + (0, [.accepted, .symbol], 108), + (0, [.accepted, .symbol], 109), + (0, [.accepted, .symbol], 110), + (0, [.accepted, .symbol], 112), + (0, [.accepted, .symbol], 114), + (0, [.accepted, .symbol], 117), + (38, .none, 0), + (39, .none, 0), + + /* 24 */ + + (1, .symbol, 61), + (22, [.accepted, .symbol], 61), + (1, .symbol, 65), + (22, [.accepted, .symbol], 65), + (1, .symbol, 95), + (22, [.accepted, .symbol], 95), + (1, .symbol, 98), + (22, [.accepted, .symbol], 98), + (1, .symbol, 100), + (22, [.accepted, .symbol], 100), + (1, .symbol, 102), + (22, [.accepted, .symbol], 102), + (1, .symbol, 103), + (22, [.accepted, .symbol], 103), + (1, .symbol, 104), + (22, [.accepted, .symbol], 104), + + /* 25 */ + + (2, .symbol, 61), + (9, .symbol, 61), + (23, .symbol, 61), + (40, [.accepted, .symbol], 61), + (2, .symbol, 65), + (9, .symbol, 65), + (23, .symbol, 65), + (40, [.accepted, .symbol], 65), + (2, .symbol, 95), + (9, .symbol, 95), + (23, .symbol, 95), + (40, [.accepted, .symbol], 95), + (2, .symbol, 98), + (9, .symbol, 98), + (23, .symbol, 98), + (40, [.accepted, .symbol], 98), + + /* 26 */ + + (3, .symbol, 61), + (6, .symbol, 61), + (10, .symbol, 61), + (15, .symbol, 61), + (24, .symbol, 61), + (31, .symbol, 61), + (41, .symbol, 61), + (56, [.accepted, .symbol], 61), + (3, .symbol, 65), + (6, .symbol, 65), + (10, .symbol, 65), + (15, .symbol, 65), + (24, .symbol, 65), + (31, .symbol, 65), + (41, .symbol, 65), + (56, [.accepted, .symbol], 65), + + /* 27 */ + + (3, .symbol, 95), + (6, .symbol, 95), + (10, .symbol, 95), + (15, .symbol, 95), + (24, .symbol, 95), + (31, .symbol, 95), + (41, .symbol, 95), + (56, [.accepted, .symbol], 95), + (3, .symbol, 98), + (6, .symbol, 98), + (10, .symbol, 98), + (15, .symbol, 98), + (24, .symbol, 98), + (31, .symbol, 98), + (41, .symbol, 98), + (56, [.accepted, .symbol], 98), + + /* 28 */ + + (2, .symbol, 100), + (9, .symbol, 100), + (23, .symbol, 100), + (40, [.accepted, .symbol], 100), + (2, .symbol, 102), + (9, .symbol, 102), + (23, .symbol, 102), + (40, [.accepted, .symbol], 102), + (2, .symbol, 103), + (9, .symbol, 103), + (23, .symbol, 103), + (40, [.accepted, .symbol], 103), + (2, .symbol, 104), + (9, .symbol, 104), + (23, .symbol, 104), + (40, [.accepted, .symbol], 104), + + /* 29 */ + + (3, .symbol, 100), + (6, .symbol, 100), + (10, .symbol, 100), + (15, .symbol, 100), + (24, .symbol, 100), + (31, .symbol, 100), + (41, .symbol, 100), + (56, [.accepted, .symbol], 100), + (3, .symbol, 102), + (6, .symbol, 102), + (10, .symbol, 102), + (15, .symbol, 102), + (24, .symbol, 102), + (31, .symbol, 102), + (41, .symbol, 102), + (56, [.accepted, .symbol], 102), + + /* 30 */ + + (3, .symbol, 103), + (6, .symbol, 103), + (10, .symbol, 103), + (15, .symbol, 103), + (24, .symbol, 103), + (31, .symbol, 103), + (41, .symbol, 103), + (56, [.accepted, .symbol], 103), + (3, .symbol, 104), + (6, .symbol, 104), + (10, .symbol, 104), + (15, .symbol, 104), + (24, .symbol, 104), + (31, .symbol, 104), + (41, .symbol, 104), + (56, [.accepted, .symbol], 104), + + /* 31 */ + + (1, .symbol, 108), + (22, [.accepted, .symbol], 108), + (1, .symbol, 109), + (22, [.accepted, .symbol], 109), + (1, .symbol, 110), + (22, [.accepted, .symbol], 110), + (1, .symbol, 112), + (22, [.accepted, .symbol], 112), + (1, .symbol, 114), + (22, [.accepted, .symbol], 114), + (1, .symbol, 117), + (22, [.accepted, .symbol], 117), + (0, [.accepted, .symbol], 58), + (0, [.accepted, .symbol], 66), + (0, [.accepted, .symbol], 67), + (0, [.accepted, .symbol], 68), + + /* 32 */ + + (2, .symbol, 108), + (9, .symbol, 108), + (23, .symbol, 108), + (40, [.accepted, .symbol], 108), + (2, .symbol, 109), + (9, .symbol, 109), + (23, .symbol, 109), + (40, [.accepted, .symbol], 109), + (2, .symbol, 110), + (9, .symbol, 110), + (23, .symbol, 110), + (40, [.accepted, .symbol], 110), + (2, .symbol, 112), + (9, .symbol, 112), + (23, .symbol, 112), + (40, [.accepted, .symbol], 112), + + /* 33 */ + + (3, .symbol, 108), + (6, .symbol, 108), + (10, .symbol, 108), + (15, .symbol, 108), + (24, .symbol, 108), + (31, .symbol, 108), + (41, .symbol, 108), + (56, [.accepted, .symbol], 108), + (3, .symbol, 109), + (6, .symbol, 109), + (10, .symbol, 109), + (15, .symbol, 109), + (24, .symbol, 109), + (31, .symbol, 109), + (41, .symbol, 109), + (56, [.accepted, .symbol], 109), + + /* 34 */ + + (3, .symbol, 110), + (6, .symbol, 110), + (10, .symbol, 110), + (15, .symbol, 110), + (24, .symbol, 110), + (31, .symbol, 110), + (41, .symbol, 110), + (56, [.accepted, .symbol], 110), + (3, .symbol, 112), + (6, .symbol, 112), + (10, .symbol, 112), + (15, .symbol, 112), + (24, .symbol, 112), + (31, .symbol, 112), + (41, .symbol, 112), + (56, [.accepted, .symbol], 112), + + /* 35 */ + + (2, .symbol, 114), + (9, .symbol, 114), + (23, .symbol, 114), + (40, [.accepted, .symbol], 114), + (2, .symbol, 117), + (9, .symbol, 117), + (23, .symbol, 117), + (40, [.accepted, .symbol], 117), + (1, .symbol, 58), + (22, [.accepted, .symbol], 58), + (1, .symbol, 66), + (22, [.accepted, .symbol], 66), + (1, .symbol, 67), + (22, [.accepted, .symbol], 67), + (1, .symbol, 68), + (22, [.accepted, .symbol], 68), + + /* 36 */ + + (3, .symbol, 114), + (6, .symbol, 114), + (10, .symbol, 114), + (15, .symbol, 114), + (24, .symbol, 114), + (31, .symbol, 114), + (41, .symbol, 114), + (56, [.accepted, .symbol], 114), + (3, .symbol, 117), + (6, .symbol, 117), + (10, .symbol, 117), + (15, .symbol, 117), + (24, .symbol, 117), + (31, .symbol, 117), + (41, .symbol, 117), + (56, [.accepted, .symbol], 117), + + /* 37 */ + + (2, .symbol, 58), + (9, .symbol, 58), + (23, .symbol, 58), + (40, [.accepted, .symbol], 58), + (2, .symbol, 66), + (9, .symbol, 66), + (23, .symbol, 66), + (40, [.accepted, .symbol], 66), + (2, .symbol, 67), + (9, .symbol, 67), + (23, .symbol, 67), + (40, [.accepted, .symbol], 67), + (2, .symbol, 68), + (9, .symbol, 68), + (23, .symbol, 68), + (40, [.accepted, .symbol], 68), + + /* 38 */ + + (3, .symbol, 58), + (6, .symbol, 58), + (10, .symbol, 58), + (15, .symbol, 58), + (24, .symbol, 58), + (31, .symbol, 58), + (41, .symbol, 58), + (56, [.accepted, .symbol], 58), + (3, .symbol, 66), + (6, .symbol, 66), + (10, .symbol, 66), + (15, .symbol, 66), + (24, .symbol, 66), + (31, .symbol, 66), + (41, .symbol, 66), + (56, [.accepted, .symbol], 66), + + /* 39 */ + + (3, .symbol, 67), + (6, .symbol, 67), + (10, .symbol, 67), + (15, .symbol, 67), + (24, .symbol, 67), + (31, .symbol, 67), + (41, .symbol, 67), + (56, [.accepted, .symbol], 67), + (3, .symbol, 68), + (6, .symbol, 68), + (10, .symbol, 68), + (15, .symbol, 68), + (24, .symbol, 68), + (31, .symbol, 68), + (41, .symbol, 68), + (56, [.accepted, .symbol], 68), + + /* 40 */ + + (44, .none, 0), + (45, .none, 0), + (47, .none, 0), + (48, .none, 0), + (51, .none, 0), + (52, .none, 0), + (54, .none, 0), + (55, .none, 0), + (59, .none, 0), + (60, .none, 0), + (62, .none, 0), + (63, .none, 0), + (66, .none, 0), + (67, .none, 0), + (69, .none, 0), + (72, .accepted, 0), + + /* 41 */ + + (0, [.accepted, .symbol], 69), + (0, [.accepted, .symbol], 70), + (0, [.accepted, .symbol], 71), + (0, [.accepted, .symbol], 72), + (0, [.accepted, .symbol], 73), + (0, [.accepted, .symbol], 74), + (0, [.accepted, .symbol], 75), + (0, [.accepted, .symbol], 76), + (0, [.accepted, .symbol], 77), + (0, [.accepted, .symbol], 78), + (0, [.accepted, .symbol], 79), + (0, [.accepted, .symbol], 80), + (0, [.accepted, .symbol], 81), + (0, [.accepted, .symbol], 82), + (0, [.accepted, .symbol], 83), + (0, [.accepted, .symbol], 84), + + /* 42 */ + + (1, .symbol, 69), + (22, [.accepted, .symbol], 69), + (1, .symbol, 70), + (22, [.accepted, .symbol], 70), + (1, .symbol, 71), + (22, [.accepted, .symbol], 71), + (1, .symbol, 72), + (22, [.accepted, .symbol], 72), + (1, .symbol, 73), + (22, [.accepted, .symbol], 73), + (1, .symbol, 74), + (22, [.accepted, .symbol], 74), + (1, .symbol, 75), + (22, [.accepted, .symbol], 75), + (1, .symbol, 76), + (22, [.accepted, .symbol], 76), + + /* 43 */ + + (2, .symbol, 69), + (9, .symbol, 69), + (23, .symbol, 69), + (40, [.accepted, .symbol], 69), + (2, .symbol, 70), + (9, .symbol, 70), + (23, .symbol, 70), + (40, [.accepted, .symbol], 70), + (2, .symbol, 71), + (9, .symbol, 71), + (23, .symbol, 71), + (40, [.accepted, .symbol], 71), + (2, .symbol, 72), + (9, .symbol, 72), + (23, .symbol, 72), + (40, [.accepted, .symbol], 72), + + /* 44 */ + + (3, .symbol, 69), + (6, .symbol, 69), + (10, .symbol, 69), + (15, .symbol, 69), + (24, .symbol, 69), + (31, .symbol, 69), + (41, .symbol, 69), + (56, [.accepted, .symbol], 69), + (3, .symbol, 70), + (6, .symbol, 70), + (10, .symbol, 70), + (15, .symbol, 70), + (24, .symbol, 70), + (31, .symbol, 70), + (41, .symbol, 70), + (56, [.accepted, .symbol], 70), + + /* 45 */ + + (3, .symbol, 71), + (6, .symbol, 71), + (10, .symbol, 71), + (15, .symbol, 71), + (24, .symbol, 71), + (31, .symbol, 71), + (41, .symbol, 71), + (56, [.accepted, .symbol], 71), + (3, .symbol, 72), + (6, .symbol, 72), + (10, .symbol, 72), + (15, .symbol, 72), + (24, .symbol, 72), + (31, .symbol, 72), + (41, .symbol, 72), + (56, [.accepted, .symbol], 72), + + /* 46 */ + + (2, .symbol, 73), + (9, .symbol, 73), + (23, .symbol, 73), + (40, [.accepted, .symbol], 73), + (2, .symbol, 74), + (9, .symbol, 74), + (23, .symbol, 74), + (40, [.accepted, .symbol], 74), + (2, .symbol, 75), + (9, .symbol, 75), + (23, .symbol, 75), + (40, [.accepted, .symbol], 75), + (2, .symbol, 76), + (9, .symbol, 76), + (23, .symbol, 76), + (40, [.accepted, .symbol], 76), + + /* 47 */ + + (3, .symbol, 73), + (6, .symbol, 73), + (10, .symbol, 73), + (15, .symbol, 73), + (24, .symbol, 73), + (31, .symbol, 73), + (41, .symbol, 73), + (56, [.accepted, .symbol], 73), + (3, .symbol, 74), + (6, .symbol, 74), + (10, .symbol, 74), + (15, .symbol, 74), + (24, .symbol, 74), + (31, .symbol, 74), + (41, .symbol, 74), + (56, [.accepted, .symbol], 74), + + /* 48 */ + + (3, .symbol, 75), + (6, .symbol, 75), + (10, .symbol, 75), + (15, .symbol, 75), + (24, .symbol, 75), + (31, .symbol, 75), + (41, .symbol, 75), + (56, [.accepted, .symbol], 75), + (3, .symbol, 76), + (6, .symbol, 76), + (10, .symbol, 76), + (15, .symbol, 76), + (24, .symbol, 76), + (31, .symbol, 76), + (41, .symbol, 76), + (56, [.accepted, .symbol], 76), + + /* 49 */ + + (1, .symbol, 77), + (22, [.accepted, .symbol], 77), + (1, .symbol, 78), + (22, [.accepted, .symbol], 78), + (1, .symbol, 79), + (22, [.accepted, .symbol], 79), + (1, .symbol, 80), + (22, [.accepted, .symbol], 80), + (1, .symbol, 81), + (22, [.accepted, .symbol], 81), + (1, .symbol, 82), + (22, [.accepted, .symbol], 82), + (1, .symbol, 83), + (22, [.accepted, .symbol], 83), + (1, .symbol, 84), + (22, [.accepted, .symbol], 84), + + /* 50 */ + + (2, .symbol, 77), + (9, .symbol, 77), + (23, .symbol, 77), + (40, [.accepted, .symbol], 77), + (2, .symbol, 78), + (9, .symbol, 78), + (23, .symbol, 78), + (40, [.accepted, .symbol], 78), + (2, .symbol, 79), + (9, .symbol, 79), + (23, .symbol, 79), + (40, [.accepted, .symbol], 79), + (2, .symbol, 80), + (9, .symbol, 80), + (23, .symbol, 80), + (40, [.accepted, .symbol], 80), + + /* 51 */ + + (3, .symbol, 77), + (6, .symbol, 77), + (10, .symbol, 77), + (15, .symbol, 77), + (24, .symbol, 77), + (31, .symbol, 77), + (41, .symbol, 77), + (56, [.accepted, .symbol], 77), + (3, .symbol, 78), + (6, .symbol, 78), + (10, .symbol, 78), + (15, .symbol, 78), + (24, .symbol, 78), + (31, .symbol, 78), + (41, .symbol, 78), + (56, [.accepted, .symbol], 78), + + /* 52 */ + + (3, .symbol, 79), + (6, .symbol, 79), + (10, .symbol, 79), + (15, .symbol, 79), + (24, .symbol, 79), + (31, .symbol, 79), + (41, .symbol, 79), + (56, [.accepted, .symbol], 79), + (3, .symbol, 80), + (6, .symbol, 80), + (10, .symbol, 80), + (15, .symbol, 80), + (24, .symbol, 80), + (31, .symbol, 80), + (41, .symbol, 80), + (56, [.accepted, .symbol], 80), + + /* 53 */ + + (2, .symbol, 81), + (9, .symbol, 81), + (23, .symbol, 81), + (40, [.accepted, .symbol], 81), + (2, .symbol, 82), + (9, .symbol, 82), + (23, .symbol, 82), + (40, [.accepted, .symbol], 82), + (2, .symbol, 83), + (9, .symbol, 83), + (23, .symbol, 83), + (40, [.accepted, .symbol], 83), + (2, .symbol, 84), + (9, .symbol, 84), + (23, .symbol, 84), + (40, [.accepted, .symbol], 84), + + /* 54 */ + + (3, .symbol, 81), + (6, .symbol, 81), + (10, .symbol, 81), + (15, .symbol, 81), + (24, .symbol, 81), + (31, .symbol, 81), + (41, .symbol, 81), + (56, [.accepted, .symbol], 81), + (3, .symbol, 82), + (6, .symbol, 82), + (10, .symbol, 82), + (15, .symbol, 82), + (24, .symbol, 82), + (31, .symbol, 82), + (41, .symbol, 82), + (56, [.accepted, .symbol], 82), + + /* 55 */ + + (3, .symbol, 83), + (6, .symbol, 83), + (10, .symbol, 83), + (15, .symbol, 83), + (24, .symbol, 83), + (31, .symbol, 83), + (41, .symbol, 83), + (56, [.accepted, .symbol], 83), + (3, .symbol, 84), + (6, .symbol, 84), + (10, .symbol, 84), + (15, .symbol, 84), + (24, .symbol, 84), + (31, .symbol, 84), + (41, .symbol, 84), + (56, [.accepted, .symbol], 84), + + /* 56 */ + + (0, [.accepted, .symbol], 85), + (0, [.accepted, .symbol], 86), + (0, [.accepted, .symbol], 87), + (0, [.accepted, .symbol], 89), + (0, [.accepted, .symbol], 106), + (0, [.accepted, .symbol], 107), + (0, [.accepted, .symbol], 113), + (0, [.accepted, .symbol], 118), + (0, [.accepted, .symbol], 119), + (0, [.accepted, .symbol], 120), + (0, [.accepted, .symbol], 121), + (0, [.accepted, .symbol], 122), + (70, .none, 0), + (71, .none, 0), + (73, .none, 0), + (74, .accepted, 0), + + /* 57 */ + + (1, .symbol, 85), + (22, [.accepted, .symbol], 85), + (1, .symbol, 86), + (22, [.accepted, .symbol], 86), + (1, .symbol, 87), + (22, [.accepted, .symbol], 87), + (1, .symbol, 89), + (22, [.accepted, .symbol], 89), + (1, .symbol, 106), + (22, [.accepted, .symbol], 106), + (1, .symbol, 107), + (22, [.accepted, .symbol], 107), + (1, .symbol, 113), + (22, [.accepted, .symbol], 113), + (1, .symbol, 118), + (22, [.accepted, .symbol], 118), + + /* 58 */ + + (2, .symbol, 85), + (9, .symbol, 85), + (23, .symbol, 85), + (40, [.accepted, .symbol], 85), + (2, .symbol, 86), + (9, .symbol, 86), + (23, .symbol, 86), + (40, [.accepted, .symbol], 86), + (2, .symbol, 87), + (9, .symbol, 87), + (23, .symbol, 87), + (40, [.accepted, .symbol], 87), + (2, .symbol, 89), + (9, .symbol, 89), + (23, .symbol, 89), + (40, [.accepted, .symbol], 89), + + /* 59 */ + + (3, .symbol, 85), + (6, .symbol, 85), + (10, .symbol, 85), + (15, .symbol, 85), + (24, .symbol, 85), + (31, .symbol, 85), + (41, .symbol, 85), + (56, [.accepted, .symbol], 85), + (3, .symbol, 86), + (6, .symbol, 86), + (10, .symbol, 86), + (15, .symbol, 86), + (24, .symbol, 86), + (31, .symbol, 86), + (41, .symbol, 86), + (56, [.accepted, .symbol], 86), + + /* 60 */ + + (3, .symbol, 87), + (6, .symbol, 87), + (10, .symbol, 87), + (15, .symbol, 87), + (24, .symbol, 87), + (31, .symbol, 87), + (41, .symbol, 87), + (56, [.accepted, .symbol], 87), + (3, .symbol, 89), + (6, .symbol, 89), + (10, .symbol, 89), + (15, .symbol, 89), + (24, .symbol, 89), + (31, .symbol, 89), + (41, .symbol, 89), + (56, [.accepted, .symbol], 89), + + /* 61 */ + + (2, .symbol, 106), + (9, .symbol, 106), + (23, .symbol, 106), + (40, [.accepted, .symbol], 106), + (2, .symbol, 107), + (9, .symbol, 107), + (23, .symbol, 107), + (40, [.accepted, .symbol], 107), + (2, .symbol, 113), + (9, .symbol, 113), + (23, .symbol, 113), + (40, [.accepted, .symbol], 113), + (2, .symbol, 118), + (9, .symbol, 118), + (23, .symbol, 118), + (40, [.accepted, .symbol], 118), + + /* 62 */ + + (3, .symbol, 106), + (6, .symbol, 106), + (10, .symbol, 106), + (15, .symbol, 106), + (24, .symbol, 106), + (31, .symbol, 106), + (41, .symbol, 106), + (56, [.accepted, .symbol], 106), + (3, .symbol, 107), + (6, .symbol, 107), + (10, .symbol, 107), + (15, .symbol, 107), + (24, .symbol, 107), + (31, .symbol, 107), + (41, .symbol, 107), + (56, [.accepted, .symbol], 107), + + /* 63 */ + + (3, .symbol, 113), + (6, .symbol, 113), + (10, .symbol, 113), + (15, .symbol, 113), + (24, .symbol, 113), + (31, .symbol, 113), + (41, .symbol, 113), + (56, [.accepted, .symbol], 113), + (3, .symbol, 118), + (6, .symbol, 118), + (10, .symbol, 118), + (15, .symbol, 118), + (24, .symbol, 118), + (31, .symbol, 118), + (41, .symbol, 118), + (56, [.accepted, .symbol], 118), + + /* 64 */ + + (1, .symbol, 119), + (22, [.accepted, .symbol], 119), + (1, .symbol, 120), + (22, [.accepted, .symbol], 120), + (1, .symbol, 121), + (22, [.accepted, .symbol], 121), + (1, .symbol, 122), + (22, [.accepted, .symbol], 122), + (0, [.accepted, .symbol], 38), + (0, [.accepted, .symbol], 42), + (0, [.accepted, .symbol], 44), + (0, [.accepted, .symbol], 59), + (0, [.accepted, .symbol], 88), + (0, [.accepted, .symbol], 90), + (75, .none, 0), + (78, .none, 0), + + /* 65 */ + + (2, .symbol, 119), + (9, .symbol, 119), + (23, .symbol, 119), + (40, [.accepted, .symbol], 119), + (2, .symbol, 120), + (9, .symbol, 120), + (23, .symbol, 120), + (40, [.accepted, .symbol], 120), + (2, .symbol, 121), + (9, .symbol, 121), + (23, .symbol, 121), + (40, [.accepted, .symbol], 121), + (2, .symbol, 122), + (9, .symbol, 122), + (23, .symbol, 122), + (40, [.accepted, .symbol], 122), + + /* 66 */ + + (3, .symbol, 119), + (6, .symbol, 119), + (10, .symbol, 119), + (15, .symbol, 119), + (24, .symbol, 119), + (31, .symbol, 119), + (41, .symbol, 119), + (56, [.accepted, .symbol], 119), + (3, .symbol, 120), + (6, .symbol, 120), + (10, .symbol, 120), + (15, .symbol, 120), + (24, .symbol, 120), + (31, .symbol, 120), + (41, .symbol, 120), + (56, [.accepted, .symbol], 120), + + /* 67 */ + + (3, .symbol, 121), + (6, .symbol, 121), + (10, .symbol, 121), + (15, .symbol, 121), + (24, .symbol, 121), + (31, .symbol, 121), + (41, .symbol, 121), + (56, [.accepted, .symbol], 121), + (3, .symbol, 122), + (6, .symbol, 122), + (10, .symbol, 122), + (15, .symbol, 122), + (24, .symbol, 122), + (31, .symbol, 122), + (41, .symbol, 122), + (56, [.accepted, .symbol], 122), + + /* 68 */ + + (1, .symbol, 38), + (22, [.accepted, .symbol], 38), + (1, .symbol, 42), + (22, [.accepted, .symbol], 42), + (1, .symbol, 44), + (22, [.accepted, .symbol], 44), + (1, .symbol, 59), + (22, [.accepted, .symbol], 59), + (1, .symbol, 88), + (22, [.accepted, .symbol], 88), + (1, .symbol, 90), + (22, [.accepted, .symbol], 90), + (76, .none, 0), + (77, .none, 0), + (79, .none, 0), + (81, .none, 0), + + /* 69 */ + + (2, .symbol, 38), + (9, .symbol, 38), + (23, .symbol, 38), + (40, [.accepted, .symbol], 38), + (2, .symbol, 42), + (9, .symbol, 42), + (23, .symbol, 42), + (40, [.accepted, .symbol], 42), + (2, .symbol, 44), + (9, .symbol, 44), + (23, .symbol, 44), + (40, [.accepted, .symbol], 44), + (2, .symbol, 59), + (9, .symbol, 59), + (23, .symbol, 59), + (40, [.accepted, .symbol], 59), + + /* 70 */ + + (3, .symbol, 38), + (6, .symbol, 38), + (10, .symbol, 38), + (15, .symbol, 38), + (24, .symbol, 38), + (31, .symbol, 38), + (41, .symbol, 38), + (56, [.accepted, .symbol], 38), + (3, .symbol, 42), + (6, .symbol, 42), + (10, .symbol, 42), + (15, .symbol, 42), + (24, .symbol, 42), + (31, .symbol, 42), + (41, .symbol, 42), + (56, [.accepted, .symbol], 42), + + /* 71 */ + + (3, .symbol, 44), + (6, .symbol, 44), + (10, .symbol, 44), + (15, .symbol, 44), + (24, .symbol, 44), + (31, .symbol, 44), + (41, .symbol, 44), + (56, [.accepted, .symbol], 44), + (3, .symbol, 59), + (6, .symbol, 59), + (10, .symbol, 59), + (15, .symbol, 59), + (24, .symbol, 59), + (31, .symbol, 59), + (41, .symbol, 59), + (56, [.accepted, .symbol], 59), + + /* 72 */ + + (2, .symbol, 88), + (9, .symbol, 88), + (23, .symbol, 88), + (40, [.accepted, .symbol], 88), + (2, .symbol, 90), + (9, .symbol, 90), + (23, .symbol, 90), + (40, [.accepted, .symbol], 90), + (0, [.accepted, .symbol], 33), + (0, [.accepted, .symbol], 34), + (0, [.accepted, .symbol], 40), + (0, [.accepted, .symbol], 41), + (0, [.accepted, .symbol], 63), + (80, .none, 0), + (82, .none, 0), + (84, .none, 0), + + /* 73 */ + + (3, .symbol, 88), + (6, .symbol, 88), + (10, .symbol, 88), + (15, .symbol, 88), + (24, .symbol, 88), + (31, .symbol, 88), + (41, .symbol, 88), + (56, [.accepted, .symbol], 88), + (3, .symbol, 90), + (6, .symbol, 90), + (10, .symbol, 90), + (15, .symbol, 90), + (24, .symbol, 90), + (31, .symbol, 90), + (41, .symbol, 90), + (56, [.accepted, .symbol], 90), + + /* 74 */ + + (1, .symbol, 33), + (22, [.accepted, .symbol], 33), + (1, .symbol, 34), + (22, [.accepted, .symbol], 34), + (1, .symbol, 40), + (22, [.accepted, .symbol], 40), + (1, .symbol, 41), + (22, [.accepted, .symbol], 41), + (1, .symbol, 63), + (22, [.accepted, .symbol], 63), + (0, [.accepted, .symbol], 39), + (0, [.accepted, .symbol], 43), + (0, [.accepted, .symbol], 124), + (83, .none, 0), + (85, .none, 0), + (88, .none, 0), + + /* 75 */ + + (2, .symbol, 33), + (9, .symbol, 33), + (23, .symbol, 33), + (40, [.accepted, .symbol], 33), + (2, .symbol, 34), + (9, .symbol, 34), + (23, .symbol, 34), + (40, [.accepted, .symbol], 34), + (2, .symbol, 40), + (9, .symbol, 40), + (23, .symbol, 40), + (40, [.accepted, .symbol], 40), + (2, .symbol, 41), + (9, .symbol, 41), + (23, .symbol, 41), + (40, [.accepted, .symbol], 41), + + /* 76 */ + + (3, .symbol, 33), + (6, .symbol, 33), + (10, .symbol, 33), + (15, .symbol, 33), + (24, .symbol, 33), + (31, .symbol, 33), + (41, .symbol, 33), + (56, [.accepted, .symbol], 33), + (3, .symbol, 34), + (6, .symbol, 34), + (10, .symbol, 34), + (15, .symbol, 34), + (24, .symbol, 34), + (31, .symbol, 34), + (41, .symbol, 34), + (56, [.accepted, .symbol], 34), + + /* 77 */ + + (3, .symbol, 40), + (6, .symbol, 40), + (10, .symbol, 40), + (15, .symbol, 40), + (24, .symbol, 40), + (31, .symbol, 40), + (41, .symbol, 40), + (56, [.accepted, .symbol], 40), + (3, .symbol, 41), + (6, .symbol, 41), + (10, .symbol, 41), + (15, .symbol, 41), + (24, .symbol, 41), + (31, .symbol, 41), + (41, .symbol, 41), + (56, [.accepted, .symbol], 41), + + /* 78 */ + + (2, .symbol, 63), + (9, .symbol, 63), + (23, .symbol, 63), + (40, [.accepted, .symbol], 63), + (1, .symbol, 39), + (22, [.accepted, .symbol], 39), + (1, .symbol, 43), + (22, [.accepted, .symbol], 43), + (1, .symbol, 124), + (22, [.accepted, .symbol], 124), + (0, [.accepted, .symbol], 35), + (0, [.accepted, .symbol], 62), + (86, .none, 0), + (87, .none, 0), + (89, .none, 0), + (90, .none, 0), + + /* 79 */ + + (3, .symbol, 63), + (6, .symbol, 63), + (10, .symbol, 63), + (15, .symbol, 63), + (24, .symbol, 63), + (31, .symbol, 63), + (41, .symbol, 63), + (56, [.accepted, .symbol], 63), + (2, .symbol, 39), + (9, .symbol, 39), + (23, .symbol, 39), + (40, [.accepted, .symbol], 39), + (2, .symbol, 43), + (9, .symbol, 43), + (23, .symbol, 43), + (40, [.accepted, .symbol], 43), + + /* 80 */ + + (3, .symbol, 39), + (6, .symbol, 39), + (10, .symbol, 39), + (15, .symbol, 39), + (24, .symbol, 39), + (31, .symbol, 39), + (41, .symbol, 39), + (56, [.accepted, .symbol], 39), + (3, .symbol, 43), + (6, .symbol, 43), + (10, .symbol, 43), + (15, .symbol, 43), + (24, .symbol, 43), + (31, .symbol, 43), + (41, .symbol, 43), + (56, [.accepted, .symbol], 43), + + /* 81 */ + + (2, .symbol, 124), + (9, .symbol, 124), + (23, .symbol, 124), + (40, [.accepted, .symbol], 124), + (1, .symbol, 35), + (22, [.accepted, .symbol], 35), + (1, .symbol, 62), + (22, [.accepted, .symbol], 62), + (0, [.accepted, .symbol], 0), + (0, [.accepted, .symbol], 36), + (0, [.accepted, .symbol], 64), + (0, [.accepted, .symbol], 91), + (0, [.accepted, .symbol], 93), + (0, [.accepted, .symbol], 126), + (91, .none, 0), + (92, .none, 0), + + /* 82 */ + + (3, .symbol, 124), + (6, .symbol, 124), + (10, .symbol, 124), + (15, .symbol, 124), + (24, .symbol, 124), + (31, .symbol, 124), + (41, .symbol, 124), + (56, [.accepted, .symbol], 124), + (2, .symbol, 35), + (9, .symbol, 35), + (23, .symbol, 35), + (40, [.accepted, .symbol], 35), + (2, .symbol, 62), + (9, .symbol, 62), + (23, .symbol, 62), + (40, [.accepted, .symbol], 62), + + /* 83 */ + + (3, .symbol, 35), + (6, .symbol, 35), + (10, .symbol, 35), + (15, .symbol, 35), + (24, .symbol, 35), + (31, .symbol, 35), + (41, .symbol, 35), + (56, [.accepted, .symbol], 35), + (3, .symbol, 62), + (6, .symbol, 62), + (10, .symbol, 62), + (15, .symbol, 62), + (24, .symbol, 62), + (31, .symbol, 62), + (41, .symbol, 62), + (56, [.accepted, .symbol], 62), + + /* 84 */ + + (1, .symbol, 0), + (22, [.accepted, .symbol], 0), + (1, .symbol, 36), + (22, [.accepted, .symbol], 36), + (1, .symbol, 64), + (22, [.accepted, .symbol], 64), + (1, .symbol, 91), + (22, [.accepted, .symbol], 91), + (1, .symbol, 93), + (22, [.accepted, .symbol], 93), + (1, .symbol, 126), + (22, [.accepted, .symbol], 126), + (0, [.accepted, .symbol], 94), + (0, [.accepted, .symbol], 125), + (93, .none, 0), + (94, .none, 0), + + /* 85 */ + + (2, .symbol, 0), + (9, .symbol, 0), + (23, .symbol, 0), + (40, [.accepted, .symbol], 0), + (2, .symbol, 36), + (9, .symbol, 36), + (23, .symbol, 36), + (40, [.accepted, .symbol], 36), + (2, .symbol, 64), + (9, .symbol, 64), + (23, .symbol, 64), + (40, [.accepted, .symbol], 64), + (2, .symbol, 91), + (9, .symbol, 91), + (23, .symbol, 91), + (40, [.accepted, .symbol], 91), + + /* 86 */ + + (3, .symbol, 0), + (6, .symbol, 0), + (10, .symbol, 0), + (15, .symbol, 0), + (24, .symbol, 0), + (31, .symbol, 0), + (41, .symbol, 0), + (56, [.accepted, .symbol], 0), + (3, .symbol, 36), + (6, .symbol, 36), + (10, .symbol, 36), + (15, .symbol, 36), + (24, .symbol, 36), + (31, .symbol, 36), + (41, .symbol, 36), + (56, [.accepted, .symbol], 36), + + /* 87 */ + + (3, .symbol, 64), + (6, .symbol, 64), + (10, .symbol, 64), + (15, .symbol, 64), + (24, .symbol, 64), + (31, .symbol, 64), + (41, .symbol, 64), + (56, [.accepted, .symbol], 64), + (3, .symbol, 91), + (6, .symbol, 91), + (10, .symbol, 91), + (15, .symbol, 91), + (24, .symbol, 91), + (31, .symbol, 91), + (41, .symbol, 91), + (56, [.accepted, .symbol], 91), + + /* 88 */ + + (2, .symbol, 93), + (9, .symbol, 93), + (23, .symbol, 93), + (40, [.accepted, .symbol], 93), + (2, .symbol, 126), + (9, .symbol, 126), + (23, .symbol, 126), + (40, [.accepted, .symbol], 126), + (1, .symbol, 94), + (22, [.accepted, .symbol], 94), + (1, .symbol, 125), + (22, [.accepted, .symbol], 125), + (0, [.accepted, .symbol], 60), + (0, [.accepted, .symbol], 96), + (0, [.accepted, .symbol], 123), + (95, .none, 0), + + /* 89 */ + + (3, .symbol, 93), + (6, .symbol, 93), + (10, .symbol, 93), + (15, .symbol, 93), + (24, .symbol, 93), + (31, .symbol, 93), + (41, .symbol, 93), + (56, [.accepted, .symbol], 93), + (3, .symbol, 126), + (6, .symbol, 126), + (10, .symbol, 126), + (15, .symbol, 126), + (24, .symbol, 126), + (31, .symbol, 126), + (41, .symbol, 126), + (56, [.accepted, .symbol], 126), + + /* 90 */ + + (2, .symbol, 94), + (9, .symbol, 94), + (23, .symbol, 94), + (40, [.accepted, .symbol], 94), + (2, .symbol, 125), + (9, .symbol, 125), + (23, .symbol, 125), + (40, [.accepted, .symbol], 125), + (1, .symbol, 60), + (22, [.accepted, .symbol], 60), + (1, .symbol, 96), + (22, [.accepted, .symbol], 96), + (1, .symbol, 123), + (22, [.accepted, .symbol], 123), + (96, .none, 0), + (110, .none, 0), + + /* 91 */ + + (3, .symbol, 94), + (6, .symbol, 94), + (10, .symbol, 94), + (15, .symbol, 94), + (24, .symbol, 94), + (31, .symbol, 94), + (41, .symbol, 94), + (56, [.accepted, .symbol], 94), + (3, .symbol, 125), + (6, .symbol, 125), + (10, .symbol, 125), + (15, .symbol, 125), + (24, .symbol, 125), + (31, .symbol, 125), + (41, .symbol, 125), + (56, [.accepted, .symbol], 125), + + /* 92 */ + + (2, .symbol, 60), + (9, .symbol, 60), + (23, .symbol, 60), + (40, [.accepted, .symbol], 60), + (2, .symbol, 96), + (9, .symbol, 96), + (23, .symbol, 96), + (40, [.accepted, .symbol], 96), + (2, .symbol, 123), + (9, .symbol, 123), + (23, .symbol, 123), + (40, [.accepted, .symbol], 123), + (97, .none, 0), + (101, .none, 0), + (111, .none, 0), + (133, .none, 0), + + /* 93 */ + + (3, .symbol, 60), + (6, .symbol, 60), + (10, .symbol, 60), + (15, .symbol, 60), + (24, .symbol, 60), + (31, .symbol, 60), + (41, .symbol, 60), + (56, [.accepted, .symbol], 60), + (3, .symbol, 96), + (6, .symbol, 96), + (10, .symbol, 96), + (15, .symbol, 96), + (24, .symbol, 96), + (31, .symbol, 96), + (41, .symbol, 96), + (56, [.accepted, .symbol], 96), + + /* 94 */ + + (3, .symbol, 123), + (6, .symbol, 123), + (10, .symbol, 123), + (15, .symbol, 123), + (24, .symbol, 123), + (31, .symbol, 123), + (41, .symbol, 123), + (56, [.accepted, .symbol], 123), + (98, .none, 0), + (99, .none, 0), + (102, .none, 0), + (105, .none, 0), + (112, .none, 0), + (119, .none, 0), + (134, .none, 0), + (153, .none, 0), + + /* 95 */ + + (0, [.accepted, .symbol], 92), + (0, [.accepted, .symbol], 195), + (0, [.accepted, .symbol], 208), + (100, .none, 0), + (103, .none, 0), + (104, .none, 0), + (106, .none, 0), + (107, .none, 0), + (113, .none, 0), + (116, .none, 0), + (120, .none, 0), + (126, .none, 0), + (135, .none, 0), + (142, .none, 0), + (154, .none, 0), + (169, .none, 0), + + /* 96 */ + + (1, .symbol, 92), + (22, [.accepted, .symbol], 92), + (1, .symbol, 195), + (22, [.accepted, .symbol], 195), + (1, .symbol, 208), + (22, [.accepted, .symbol], 208), + (0, [.accepted, .symbol], 128), + (0, [.accepted, .symbol], 130), + (0, [.accepted, .symbol], 131), + (0, [.accepted, .symbol], 162), + (0, [.accepted, .symbol], 184), + (0, [.accepted, .symbol], 194), + (0, [.accepted, .symbol], 224), + (0, [.accepted, .symbol], 226), + (108, .none, 0), + (109, .none, 0), + + /* 97 */ + + (2, .symbol, 92), + (9, .symbol, 92), + (23, .symbol, 92), + (40, [.accepted, .symbol], 92), + (2, .symbol, 195), + (9, .symbol, 195), + (23, .symbol, 195), + (40, [.accepted, .symbol], 195), + (2, .symbol, 208), + (9, .symbol, 208), + (23, .symbol, 208), + (40, [.accepted, .symbol], 208), + (1, .symbol, 128), + (22, [.accepted, .symbol], 128), + (1, .symbol, 130), + (22, [.accepted, .symbol], 130), + + /* 98 */ + + (3, .symbol, 92), + (6, .symbol, 92), + (10, .symbol, 92), + (15, .symbol, 92), + (24, .symbol, 92), + (31, .symbol, 92), + (41, .symbol, 92), + (56, [.accepted, .symbol], 92), + (3, .symbol, 195), + (6, .symbol, 195), + (10, .symbol, 195), + (15, .symbol, 195), + (24, .symbol, 195), + (31, .symbol, 195), + (41, .symbol, 195), + (56, [.accepted, .symbol], 195), + + /* 99 */ + + (3, .symbol, 208), + (6, .symbol, 208), + (10, .symbol, 208), + (15, .symbol, 208), + (24, .symbol, 208), + (31, .symbol, 208), + (41, .symbol, 208), + (56, [.accepted, .symbol], 208), + (2, .symbol, 128), + (9, .symbol, 128), + (23, .symbol, 128), + (40, [.accepted, .symbol], 128), + (2, .symbol, 130), + (9, .symbol, 130), + (23, .symbol, 130), + (40, [.accepted, .symbol], 130), + + /* 100 */ + + (3, .symbol, 128), + (6, .symbol, 128), + (10, .symbol, 128), + (15, .symbol, 128), + (24, .symbol, 128), + (31, .symbol, 128), + (41, .symbol, 128), + (56, [.accepted, .symbol], 128), + (3, .symbol, 130), + (6, .symbol, 130), + (10, .symbol, 130), + (15, .symbol, 130), + (24, .symbol, 130), + (31, .symbol, 130), + (41, .symbol, 130), + (56, [.accepted, .symbol], 130), + + /* 101 */ + + (1, .symbol, 131), + (22, [.accepted, .symbol], 131), + (1, .symbol, 162), + (22, [.accepted, .symbol], 162), + (1, .symbol, 184), + (22, [.accepted, .symbol], 184), + (1, .symbol, 194), + (22, [.accepted, .symbol], 194), + (1, .symbol, 224), + (22, [.accepted, .symbol], 224), + (1, .symbol, 226), + (22, [.accepted, .symbol], 226), + (0, [.accepted, .symbol], 153), + (0, [.accepted, .symbol], 161), + (0, [.accepted, .symbol], 167), + (0, [.accepted, .symbol], 172), + + /* 102 */ + + (2, .symbol, 131), + (9, .symbol, 131), + (23, .symbol, 131), + (40, [.accepted, .symbol], 131), + (2, .symbol, 162), + (9, .symbol, 162), + (23, .symbol, 162), + (40, [.accepted, .symbol], 162), + (2, .symbol, 184), + (9, .symbol, 184), + (23, .symbol, 184), + (40, [.accepted, .symbol], 184), + (2, .symbol, 194), + (9, .symbol, 194), + (23, .symbol, 194), + (40, [.accepted, .symbol], 194), + + /* 103 */ + + (3, .symbol, 131), + (6, .symbol, 131), + (10, .symbol, 131), + (15, .symbol, 131), + (24, .symbol, 131), + (31, .symbol, 131), + (41, .symbol, 131), + (56, [.accepted, .symbol], 131), + (3, .symbol, 162), + (6, .symbol, 162), + (10, .symbol, 162), + (15, .symbol, 162), + (24, .symbol, 162), + (31, .symbol, 162), + (41, .symbol, 162), + (56, [.accepted, .symbol], 162), + + /* 104 */ + + (3, .symbol, 184), + (6, .symbol, 184), + (10, .symbol, 184), + (15, .symbol, 184), + (24, .symbol, 184), + (31, .symbol, 184), + (41, .symbol, 184), + (56, [.accepted, .symbol], 184), + (3, .symbol, 194), + (6, .symbol, 194), + (10, .symbol, 194), + (15, .symbol, 194), + (24, .symbol, 194), + (31, .symbol, 194), + (41, .symbol, 194), + (56, [.accepted, .symbol], 194), + + /* 105 */ + + (2, .symbol, 224), + (9, .symbol, 224), + (23, .symbol, 224), + (40, [.accepted, .symbol], 224), + (2, .symbol, 226), + (9, .symbol, 226), + (23, .symbol, 226), + (40, [.accepted, .symbol], 226), + (1, .symbol, 153), + (22, [.accepted, .symbol], 153), + (1, .symbol, 161), + (22, [.accepted, .symbol], 161), + (1, .symbol, 167), + (22, [.accepted, .symbol], 167), + (1, .symbol, 172), + (22, [.accepted, .symbol], 172), + + /* 106 */ + + (3, .symbol, 224), + (6, .symbol, 224), + (10, .symbol, 224), + (15, .symbol, 224), + (24, .symbol, 224), + (31, .symbol, 224), + (41, .symbol, 224), + (56, [.accepted, .symbol], 224), + (3, .symbol, 226), + (6, .symbol, 226), + (10, .symbol, 226), + (15, .symbol, 226), + (24, .symbol, 226), + (31, .symbol, 226), + (41, .symbol, 226), + (56, [.accepted, .symbol], 226), + + /* 107 */ + + (2, .symbol, 153), + (9, .symbol, 153), + (23, .symbol, 153), + (40, [.accepted, .symbol], 153), + (2, .symbol, 161), + (9, .symbol, 161), + (23, .symbol, 161), + (40, [.accepted, .symbol], 161), + (2, .symbol, 167), + (9, .symbol, 167), + (23, .symbol, 167), + (40, [.accepted, .symbol], 167), + (2, .symbol, 172), + (9, .symbol, 172), + (23, .symbol, 172), + (40, [.accepted, .symbol], 172), + + /* 108 */ + + (3, .symbol, 153), + (6, .symbol, 153), + (10, .symbol, 153), + (15, .symbol, 153), + (24, .symbol, 153), + (31, .symbol, 153), + (41, .symbol, 153), + (56, [.accepted, .symbol], 153), + (3, .symbol, 161), + (6, .symbol, 161), + (10, .symbol, 161), + (15, .symbol, 161), + (24, .symbol, 161), + (31, .symbol, 161), + (41, .symbol, 161), + (56, [.accepted, .symbol], 161), + + /* 109 */ + + (3, .symbol, 167), + (6, .symbol, 167), + (10, .symbol, 167), + (15, .symbol, 167), + (24, .symbol, 167), + (31, .symbol, 167), + (41, .symbol, 167), + (56, [.accepted, .symbol], 167), + (3, .symbol, 172), + (6, .symbol, 172), + (10, .symbol, 172), + (15, .symbol, 172), + (24, .symbol, 172), + (31, .symbol, 172), + (41, .symbol, 172), + (56, [.accepted, .symbol], 172), + + /* 110 */ + + (114, .none, 0), + (115, .none, 0), + (117, .none, 0), + (118, .none, 0), + (121, .none, 0), + (123, .none, 0), + (127, .none, 0), + (130, .none, 0), + (136, .none, 0), + (139, .none, 0), + (143, .none, 0), + (146, .none, 0), + (155, .none, 0), + (162, .none, 0), + (170, .none, 0), + (180, .none, 0), + + /* 111 */ + + (0, [.accepted, .symbol], 176), + (0, [.accepted, .symbol], 177), + (0, [.accepted, .symbol], 179), + (0, [.accepted, .symbol], 209), + (0, [.accepted, .symbol], 216), + (0, [.accepted, .symbol], 217), + (0, [.accepted, .symbol], 227), + (0, [.accepted, .symbol], 229), + (0, [.accepted, .symbol], 230), + (122, .none, 0), + (124, .none, 0), + (125, .none, 0), + (128, .none, 0), + (129, .none, 0), + (131, .none, 0), + (132, .none, 0), + + /* 112 */ + + (1, .symbol, 176), + (22, [.accepted, .symbol], 176), + (1, .symbol, 177), + (22, [.accepted, .symbol], 177), + (1, .symbol, 179), + (22, [.accepted, .symbol], 179), + (1, .symbol, 209), + (22, [.accepted, .symbol], 209), + (1, .symbol, 216), + (22, [.accepted, .symbol], 216), + (1, .symbol, 217), + (22, [.accepted, .symbol], 217), + (1, .symbol, 227), + (22, [.accepted, .symbol], 227), + (1, .symbol, 229), + (22, [.accepted, .symbol], 229), + + /* 113 */ + + (2, .symbol, 176), + (9, .symbol, 176), + (23, .symbol, 176), + (40, [.accepted, .symbol], 176), + (2, .symbol, 177), + (9, .symbol, 177), + (23, .symbol, 177), + (40, [.accepted, .symbol], 177), + (2, .symbol, 179), + (9, .symbol, 179), + (23, .symbol, 179), + (40, [.accepted, .symbol], 179), + (2, .symbol, 209), + (9, .symbol, 209), + (23, .symbol, 209), + (40, [.accepted, .symbol], 209), + + /* 114 */ + + (3, .symbol, 176), + (6, .symbol, 176), + (10, .symbol, 176), + (15, .symbol, 176), + (24, .symbol, 176), + (31, .symbol, 176), + (41, .symbol, 176), + (56, [.accepted, .symbol], 176), + (3, .symbol, 177), + (6, .symbol, 177), + (10, .symbol, 177), + (15, .symbol, 177), + (24, .symbol, 177), + (31, .symbol, 177), + (41, .symbol, 177), + (56, [.accepted, .symbol], 177), + + /* 115 */ + + (3, .symbol, 179), + (6, .symbol, 179), + (10, .symbol, 179), + (15, .symbol, 179), + (24, .symbol, 179), + (31, .symbol, 179), + (41, .symbol, 179), + (56, [.accepted, .symbol], 179), + (3, .symbol, 209), + (6, .symbol, 209), + (10, .symbol, 209), + (15, .symbol, 209), + (24, .symbol, 209), + (31, .symbol, 209), + (41, .symbol, 209), + (56, [.accepted, .symbol], 209), + + /* 116 */ + + (2, .symbol, 216), + (9, .symbol, 216), + (23, .symbol, 216), + (40, [.accepted, .symbol], 216), + (2, .symbol, 217), + (9, .symbol, 217), + (23, .symbol, 217), + (40, [.accepted, .symbol], 217), + (2, .symbol, 227), + (9, .symbol, 227), + (23, .symbol, 227), + (40, [.accepted, .symbol], 227), + (2, .symbol, 229), + (9, .symbol, 229), + (23, .symbol, 229), + (40, [.accepted, .symbol], 229), + + /* 117 */ + + (3, .symbol, 216), + (6, .symbol, 216), + (10, .symbol, 216), + (15, .symbol, 216), + (24, .symbol, 216), + (31, .symbol, 216), + (41, .symbol, 216), + (56, [.accepted, .symbol], 216), + (3, .symbol, 217), + (6, .symbol, 217), + (10, .symbol, 217), + (15, .symbol, 217), + (24, .symbol, 217), + (31, .symbol, 217), + (41, .symbol, 217), + (56, [.accepted, .symbol], 217), + + /* 118 */ + + (3, .symbol, 227), + (6, .symbol, 227), + (10, .symbol, 227), + (15, .symbol, 227), + (24, .symbol, 227), + (31, .symbol, 227), + (41, .symbol, 227), + (56, [.accepted, .symbol], 227), + (3, .symbol, 229), + (6, .symbol, 229), + (10, .symbol, 229), + (15, .symbol, 229), + (24, .symbol, 229), + (31, .symbol, 229), + (41, .symbol, 229), + (56, [.accepted, .symbol], 229), + + /* 119 */ + + (1, .symbol, 230), + (22, [.accepted, .symbol], 230), + (0, [.accepted, .symbol], 129), + (0, [.accepted, .symbol], 132), + (0, [.accepted, .symbol], 133), + (0, [.accepted, .symbol], 134), + (0, [.accepted, .symbol], 136), + (0, [.accepted, .symbol], 146), + (0, [.accepted, .symbol], 154), + (0, [.accepted, .symbol], 156), + (0, [.accepted, .symbol], 160), + (0, [.accepted, .symbol], 163), + (0, [.accepted, .symbol], 164), + (0, [.accepted, .symbol], 169), + (0, [.accepted, .symbol], 170), + (0, [.accepted, .symbol], 173), + + /* 120 */ + + (2, .symbol, 230), + (9, .symbol, 230), + (23, .symbol, 230), + (40, [.accepted, .symbol], 230), + (1, .symbol, 129), + (22, [.accepted, .symbol], 129), + (1, .symbol, 132), + (22, [.accepted, .symbol], 132), + (1, .symbol, 133), + (22, [.accepted, .symbol], 133), + (1, .symbol, 134), + (22, [.accepted, .symbol], 134), + (1, .symbol, 136), + (22, [.accepted, .symbol], 136), + (1, .symbol, 146), + (22, [.accepted, .symbol], 146), + + /* 121 */ + + (3, .symbol, 230), + (6, .symbol, 230), + (10, .symbol, 230), + (15, .symbol, 230), + (24, .symbol, 230), + (31, .symbol, 230), + (41, .symbol, 230), + (56, [.accepted, .symbol], 230), + (2, .symbol, 129), + (9, .symbol, 129), + (23, .symbol, 129), + (40, [.accepted, .symbol], 129), + (2, .symbol, 132), + (9, .symbol, 132), + (23, .symbol, 132), + (40, [.accepted, .symbol], 132), + + /* 122 */ + + (3, .symbol, 129), + (6, .symbol, 129), + (10, .symbol, 129), + (15, .symbol, 129), + (24, .symbol, 129), + (31, .symbol, 129), + (41, .symbol, 129), + (56, [.accepted, .symbol], 129), + (3, .symbol, 132), + (6, .symbol, 132), + (10, .symbol, 132), + (15, .symbol, 132), + (24, .symbol, 132), + (31, .symbol, 132), + (41, .symbol, 132), + (56, [.accepted, .symbol], 132), + + /* 123 */ + + (2, .symbol, 133), + (9, .symbol, 133), + (23, .symbol, 133), + (40, [.accepted, .symbol], 133), + (2, .symbol, 134), + (9, .symbol, 134), + (23, .symbol, 134), + (40, [.accepted, .symbol], 134), + (2, .symbol, 136), + (9, .symbol, 136), + (23, .symbol, 136), + (40, [.accepted, .symbol], 136), + (2, .symbol, 146), + (9, .symbol, 146), + (23, .symbol, 146), + (40, [.accepted, .symbol], 146), + + /* 124 */ + + (3, .symbol, 133), + (6, .symbol, 133), + (10, .symbol, 133), + (15, .symbol, 133), + (24, .symbol, 133), + (31, .symbol, 133), + (41, .symbol, 133), + (56, [.accepted, .symbol], 133), + (3, .symbol, 134), + (6, .symbol, 134), + (10, .symbol, 134), + (15, .symbol, 134), + (24, .symbol, 134), + (31, .symbol, 134), + (41, .symbol, 134), + (56, [.accepted, .symbol], 134), + + /* 125 */ + + (3, .symbol, 136), + (6, .symbol, 136), + (10, .symbol, 136), + (15, .symbol, 136), + (24, .symbol, 136), + (31, .symbol, 136), + (41, .symbol, 136), + (56, [.accepted, .symbol], 136), + (3, .symbol, 146), + (6, .symbol, 146), + (10, .symbol, 146), + (15, .symbol, 146), + (24, .symbol, 146), + (31, .symbol, 146), + (41, .symbol, 146), + (56, [.accepted, .symbol], 146), + + /* 126 */ + + (1, .symbol, 154), + (22, [.accepted, .symbol], 154), + (1, .symbol, 156), + (22, [.accepted, .symbol], 156), + (1, .symbol, 160), + (22, [.accepted, .symbol], 160), + (1, .symbol, 163), + (22, [.accepted, .symbol], 163), + (1, .symbol, 164), + (22, [.accepted, .symbol], 164), + (1, .symbol, 169), + (22, [.accepted, .symbol], 169), + (1, .symbol, 170), + (22, [.accepted, .symbol], 170), + (1, .symbol, 173), + (22, [.accepted, .symbol], 173), + + /* 127 */ + + (2, .symbol, 154), + (9, .symbol, 154), + (23, .symbol, 154), + (40, [.accepted, .symbol], 154), + (2, .symbol, 156), + (9, .symbol, 156), + (23, .symbol, 156), + (40, [.accepted, .symbol], 156), + (2, .symbol, 160), + (9, .symbol, 160), + (23, .symbol, 160), + (40, [.accepted, .symbol], 160), + (2, .symbol, 163), + (9, .symbol, 163), + (23, .symbol, 163), + (40, [.accepted, .symbol], 163), + + /* 128 */ + + (3, .symbol, 154), + (6, .symbol, 154), + (10, .symbol, 154), + (15, .symbol, 154), + (24, .symbol, 154), + (31, .symbol, 154), + (41, .symbol, 154), + (56, [.accepted, .symbol], 154), + (3, .symbol, 156), + (6, .symbol, 156), + (10, .symbol, 156), + (15, .symbol, 156), + (24, .symbol, 156), + (31, .symbol, 156), + (41, .symbol, 156), + (56, [.accepted, .symbol], 156), + + /* 129 */ + + (3, .symbol, 160), + (6, .symbol, 160), + (10, .symbol, 160), + (15, .symbol, 160), + (24, .symbol, 160), + (31, .symbol, 160), + (41, .symbol, 160), + (56, [.accepted, .symbol], 160), + (3, .symbol, 163), + (6, .symbol, 163), + (10, .symbol, 163), + (15, .symbol, 163), + (24, .symbol, 163), + (31, .symbol, 163), + (41, .symbol, 163), + (56, [.accepted, .symbol], 163), + + /* 130 */ + + (2, .symbol, 164), + (9, .symbol, 164), + (23, .symbol, 164), + (40, [.accepted, .symbol], 164), + (2, .symbol, 169), + (9, .symbol, 169), + (23, .symbol, 169), + (40, [.accepted, .symbol], 169), + (2, .symbol, 170), + (9, .symbol, 170), + (23, .symbol, 170), + (40, [.accepted, .symbol], 170), + (2, .symbol, 173), + (9, .symbol, 173), + (23, .symbol, 173), + (40, [.accepted, .symbol], 173), + + /* 131 */ + + (3, .symbol, 164), + (6, .symbol, 164), + (10, .symbol, 164), + (15, .symbol, 164), + (24, .symbol, 164), + (31, .symbol, 164), + (41, .symbol, 164), + (56, [.accepted, .symbol], 164), + (3, .symbol, 169), + (6, .symbol, 169), + (10, .symbol, 169), + (15, .symbol, 169), + (24, .symbol, 169), + (31, .symbol, 169), + (41, .symbol, 169), + (56, [.accepted, .symbol], 169), + + /* 132 */ + + (3, .symbol, 170), + (6, .symbol, 170), + (10, .symbol, 170), + (15, .symbol, 170), + (24, .symbol, 170), + (31, .symbol, 170), + (41, .symbol, 170), + (56, [.accepted, .symbol], 170), + (3, .symbol, 173), + (6, .symbol, 173), + (10, .symbol, 173), + (15, .symbol, 173), + (24, .symbol, 173), + (31, .symbol, 173), + (41, .symbol, 173), + (56, [.accepted, .symbol], 173), + + /* 133 */ + + (137, .none, 0), + (138, .none, 0), + (140, .none, 0), + (141, .none, 0), + (144, .none, 0), + (145, .none, 0), + (147, .none, 0), + (150, .none, 0), + (156, .none, 0), + (159, .none, 0), + (163, .none, 0), + (166, .none, 0), + (171, .none, 0), + (174, .none, 0), + (181, .none, 0), + (190, .none, 0), + + /* 134 */ + + (0, [.accepted, .symbol], 178), + (0, [.accepted, .symbol], 181), + (0, [.accepted, .symbol], 185), + (0, [.accepted, .symbol], 186), + (0, [.accepted, .symbol], 187), + (0, [.accepted, .symbol], 189), + (0, [.accepted, .symbol], 190), + (0, [.accepted, .symbol], 196), + (0, [.accepted, .symbol], 198), + (0, [.accepted, .symbol], 228), + (0, [.accepted, .symbol], 232), + (0, [.accepted, .symbol], 233), + (148, .none, 0), + (149, .none, 0), + (151, .none, 0), + (152, .none, 0), + + /* 135 */ + + (1, .symbol, 178), + (22, [.accepted, .symbol], 178), + (1, .symbol, 181), + (22, [.accepted, .symbol], 181), + (1, .symbol, 185), + (22, [.accepted, .symbol], 185), + (1, .symbol, 186), + (22, [.accepted, .symbol], 186), + (1, .symbol, 187), + (22, [.accepted, .symbol], 187), + (1, .symbol, 189), + (22, [.accepted, .symbol], 189), + (1, .symbol, 190), + (22, [.accepted, .symbol], 190), + (1, .symbol, 196), + (22, [.accepted, .symbol], 196), + + /* 136 */ + + (2, .symbol, 178), + (9, .symbol, 178), + (23, .symbol, 178), + (40, [.accepted, .symbol], 178), + (2, .symbol, 181), + (9, .symbol, 181), + (23, .symbol, 181), + (40, [.accepted, .symbol], 181), + (2, .symbol, 185), + (9, .symbol, 185), + (23, .symbol, 185), + (40, [.accepted, .symbol], 185), + (2, .symbol, 186), + (9, .symbol, 186), + (23, .symbol, 186), + (40, [.accepted, .symbol], 186), + + /* 137 */ + + (3, .symbol, 178), + (6, .symbol, 178), + (10, .symbol, 178), + (15, .symbol, 178), + (24, .symbol, 178), + (31, .symbol, 178), + (41, .symbol, 178), + (56, [.accepted, .symbol], 178), + (3, .symbol, 181), + (6, .symbol, 181), + (10, .symbol, 181), + (15, .symbol, 181), + (24, .symbol, 181), + (31, .symbol, 181), + (41, .symbol, 181), + (56, [.accepted, .symbol], 181), + + /* 138 */ + + (3, .symbol, 185), + (6, .symbol, 185), + (10, .symbol, 185), + (15, .symbol, 185), + (24, .symbol, 185), + (31, .symbol, 185), + (41, .symbol, 185), + (56, [.accepted, .symbol], 185), + (3, .symbol, 186), + (6, .symbol, 186), + (10, .symbol, 186), + (15, .symbol, 186), + (24, .symbol, 186), + (31, .symbol, 186), + (41, .symbol, 186), + (56, [.accepted, .symbol], 186), + + /* 139 */ + + (2, .symbol, 187), + (9, .symbol, 187), + (23, .symbol, 187), + (40, [.accepted, .symbol], 187), + (2, .symbol, 189), + (9, .symbol, 189), + (23, .symbol, 189), + (40, [.accepted, .symbol], 189), + (2, .symbol, 190), + (9, .symbol, 190), + (23, .symbol, 190), + (40, [.accepted, .symbol], 190), + (2, .symbol, 196), + (9, .symbol, 196), + (23, .symbol, 196), + (40, [.accepted, .symbol], 196), + + /* 140 */ + + (3, .symbol, 187), + (6, .symbol, 187), + (10, .symbol, 187), + (15, .symbol, 187), + (24, .symbol, 187), + (31, .symbol, 187), + (41, .symbol, 187), + (56, [.accepted, .symbol], 187), + (3, .symbol, 189), + (6, .symbol, 189), + (10, .symbol, 189), + (15, .symbol, 189), + (24, .symbol, 189), + (31, .symbol, 189), + (41, .symbol, 189), + (56, [.accepted, .symbol], 189), + + /* 141 */ + + (3, .symbol, 190), + (6, .symbol, 190), + (10, .symbol, 190), + (15, .symbol, 190), + (24, .symbol, 190), + (31, .symbol, 190), + (41, .symbol, 190), + (56, [.accepted, .symbol], 190), + (3, .symbol, 196), + (6, .symbol, 196), + (10, .symbol, 196), + (15, .symbol, 196), + (24, .symbol, 196), + (31, .symbol, 196), + (41, .symbol, 196), + (56, [.accepted, .symbol], 196), + + /* 142 */ + + (1, .symbol, 198), + (22, [.accepted, .symbol], 198), + (1, .symbol, 228), + (22, [.accepted, .symbol], 228), + (1, .symbol, 232), + (22, [.accepted, .symbol], 232), + (1, .symbol, 233), + (22, [.accepted, .symbol], 233), + (0, [.accepted, .symbol], 1), + (0, [.accepted, .symbol], 135), + (0, [.accepted, .symbol], 137), + (0, [.accepted, .symbol], 138), + (0, [.accepted, .symbol], 139), + (0, [.accepted, .symbol], 140), + (0, [.accepted, .symbol], 141), + (0, [.accepted, .symbol], 143), + + /* 143 */ + + (2, .symbol, 198), + (9, .symbol, 198), + (23, .symbol, 198), + (40, [.accepted, .symbol], 198), + (2, .symbol, 228), + (9, .symbol, 228), + (23, .symbol, 228), + (40, [.accepted, .symbol], 228), + (2, .symbol, 232), + (9, .symbol, 232), + (23, .symbol, 232), + (40, [.accepted, .symbol], 232), + (2, .symbol, 233), + (9, .symbol, 233), + (23, .symbol, 233), + (40, [.accepted, .symbol], 233), + + /* 144 */ + + (3, .symbol, 198), + (6, .symbol, 198), + (10, .symbol, 198), + (15, .symbol, 198), + (24, .symbol, 198), + (31, .symbol, 198), + (41, .symbol, 198), + (56, [.accepted, .symbol], 198), + (3, .symbol, 228), + (6, .symbol, 228), + (10, .symbol, 228), + (15, .symbol, 228), + (24, .symbol, 228), + (31, .symbol, 228), + (41, .symbol, 228), + (56, [.accepted, .symbol], 228), + + /* 145 */ + + (3, .symbol, 232), + (6, .symbol, 232), + (10, .symbol, 232), + (15, .symbol, 232), + (24, .symbol, 232), + (31, .symbol, 232), + (41, .symbol, 232), + (56, [.accepted, .symbol], 232), + (3, .symbol, 233), + (6, .symbol, 233), + (10, .symbol, 233), + (15, .symbol, 233), + (24, .symbol, 233), + (31, .symbol, 233), + (41, .symbol, 233), + (56, [.accepted, .symbol], 233), + + /* 146 */ + + (1, .symbol, 1), + (22, [.accepted, .symbol], 1), + (1, .symbol, 135), + (22, [.accepted, .symbol], 135), + (1, .symbol, 137), + (22, [.accepted, .symbol], 137), + (1, .symbol, 138), + (22, [.accepted, .symbol], 138), + (1, .symbol, 139), + (22, [.accepted, .symbol], 139), + (1, .symbol, 140), + (22, [.accepted, .symbol], 140), + (1, .symbol, 141), + (22, [.accepted, .symbol], 141), + (1, .symbol, 143), + (22, [.accepted, .symbol], 143), + + /* 147 */ + + (2, .symbol, 1), + (9, .symbol, 1), + (23, .symbol, 1), + (40, [.accepted, .symbol], 1), + (2, .symbol, 135), + (9, .symbol, 135), + (23, .symbol, 135), + (40, [.accepted, .symbol], 135), + (2, .symbol, 137), + (9, .symbol, 137), + (23, .symbol, 137), + (40, [.accepted, .symbol], 137), + (2, .symbol, 138), + (9, .symbol, 138), + (23, .symbol, 138), + (40, [.accepted, .symbol], 138), + + /* 148 */ + + (3, .symbol, 1), + (6, .symbol, 1), + (10, .symbol, 1), + (15, .symbol, 1), + (24, .symbol, 1), + (31, .symbol, 1), + (41, .symbol, 1), + (56, [.accepted, .symbol], 1), + (3, .symbol, 135), + (6, .symbol, 135), + (10, .symbol, 135), + (15, .symbol, 135), + (24, .symbol, 135), + (31, .symbol, 135), + (41, .symbol, 135), + (56, [.accepted, .symbol], 135), + + /* 149 */ + + (3, .symbol, 137), + (6, .symbol, 137), + (10, .symbol, 137), + (15, .symbol, 137), + (24, .symbol, 137), + (31, .symbol, 137), + (41, .symbol, 137), + (56, [.accepted, .symbol], 137), + (3, .symbol, 138), + (6, .symbol, 138), + (10, .symbol, 138), + (15, .symbol, 138), + (24, .symbol, 138), + (31, .symbol, 138), + (41, .symbol, 138), + (56, [.accepted, .symbol], 138), + + /* 150 */ + + (2, .symbol, 139), + (9, .symbol, 139), + (23, .symbol, 139), + (40, [.accepted, .symbol], 139), + (2, .symbol, 140), + (9, .symbol, 140), + (23, .symbol, 140), + (40, [.accepted, .symbol], 140), + (2, .symbol, 141), + (9, .symbol, 141), + (23, .symbol, 141), + (40, [.accepted, .symbol], 141), + (2, .symbol, 143), + (9, .symbol, 143), + (23, .symbol, 143), + (40, [.accepted, .symbol], 143), + + /* 151 */ + + (3, .symbol, 139), + (6, .symbol, 139), + (10, .symbol, 139), + (15, .symbol, 139), + (24, .symbol, 139), + (31, .symbol, 139), + (41, .symbol, 139), + (56, [.accepted, .symbol], 139), + (3, .symbol, 140), + (6, .symbol, 140), + (10, .symbol, 140), + (15, .symbol, 140), + (24, .symbol, 140), + (31, .symbol, 140), + (41, .symbol, 140), + (56, [.accepted, .symbol], 140), + + /* 152 */ + + (3, .symbol, 141), + (6, .symbol, 141), + (10, .symbol, 141), + (15, .symbol, 141), + (24, .symbol, 141), + (31, .symbol, 141), + (41, .symbol, 141), + (56, [.accepted, .symbol], 141), + (3, .symbol, 143), + (6, .symbol, 143), + (10, .symbol, 143), + (15, .symbol, 143), + (24, .symbol, 143), + (31, .symbol, 143), + (41, .symbol, 143), + (56, [.accepted, .symbol], 143), + + /* 153 */ + + (157, .none, 0), + (158, .none, 0), + (160, .none, 0), + (161, .none, 0), + (164, .none, 0), + (165, .none, 0), + (167, .none, 0), + (168, .none, 0), + (172, .none, 0), + (173, .none, 0), + (175, .none, 0), + (177, .none, 0), + (182, .none, 0), + (185, .none, 0), + (191, .none, 0), + (207, .none, 0), + + /* 154 */ + + (0, [.accepted, .symbol], 147), + (0, [.accepted, .symbol], 149), + (0, [.accepted, .symbol], 150), + (0, [.accepted, .symbol], 151), + (0, [.accepted, .symbol], 152), + (0, [.accepted, .symbol], 155), + (0, [.accepted, .symbol], 157), + (0, [.accepted, .symbol], 158), + (0, [.accepted, .symbol], 165), + (0, [.accepted, .symbol], 166), + (0, [.accepted, .symbol], 168), + (0, [.accepted, .symbol], 174), + (0, [.accepted, .symbol], 175), + (0, [.accepted, .symbol], 180), + (0, [.accepted, .symbol], 182), + (0, [.accepted, .symbol], 183), + + /* 155 */ + + (1, .symbol, 147), + (22, [.accepted, .symbol], 147), + (1, .symbol, 149), + (22, [.accepted, .symbol], 149), + (1, .symbol, 150), + (22, [.accepted, .symbol], 150), + (1, .symbol, 151), + (22, [.accepted, .symbol], 151), + (1, .symbol, 152), + (22, [.accepted, .symbol], 152), + (1, .symbol, 155), + (22, [.accepted, .symbol], 155), + (1, .symbol, 157), + (22, [.accepted, .symbol], 157), + (1, .symbol, 158), + (22, [.accepted, .symbol], 158), + + /* 156 */ + + (2, .symbol, 147), + (9, .symbol, 147), + (23, .symbol, 147), + (40, [.accepted, .symbol], 147), + (2, .symbol, 149), + (9, .symbol, 149), + (23, .symbol, 149), + (40, [.accepted, .symbol], 149), + (2, .symbol, 150), + (9, .symbol, 150), + (23, .symbol, 150), + (40, [.accepted, .symbol], 150), + (2, .symbol, 151), + (9, .symbol, 151), + (23, .symbol, 151), + (40, [.accepted, .symbol], 151), + + /* 157 */ + + (3, .symbol, 147), + (6, .symbol, 147), + (10, .symbol, 147), + (15, .symbol, 147), + (24, .symbol, 147), + (31, .symbol, 147), + (41, .symbol, 147), + (56, [.accepted, .symbol], 147), + (3, .symbol, 149), + (6, .symbol, 149), + (10, .symbol, 149), + (15, .symbol, 149), + (24, .symbol, 149), + (31, .symbol, 149), + (41, .symbol, 149), + (56, [.accepted, .symbol], 149), + + /* 158 */ + + (3, .symbol, 150), + (6, .symbol, 150), + (10, .symbol, 150), + (15, .symbol, 150), + (24, .symbol, 150), + (31, .symbol, 150), + (41, .symbol, 150), + (56, [.accepted, .symbol], 150), + (3, .symbol, 151), + (6, .symbol, 151), + (10, .symbol, 151), + (15, .symbol, 151), + (24, .symbol, 151), + (31, .symbol, 151), + (41, .symbol, 151), + (56, [.accepted, .symbol], 151), + + /* 159 */ + + (2, .symbol, 152), + (9, .symbol, 152), + (23, .symbol, 152), + (40, [.accepted, .symbol], 152), + (2, .symbol, 155), + (9, .symbol, 155), + (23, .symbol, 155), + (40, [.accepted, .symbol], 155), + (2, .symbol, 157), + (9, .symbol, 157), + (23, .symbol, 157), + (40, [.accepted, .symbol], 157), + (2, .symbol, 158), + (9, .symbol, 158), + (23, .symbol, 158), + (40, [.accepted, .symbol], 158), + + /* 160 */ + + (3, .symbol, 152), + (6, .symbol, 152), + (10, .symbol, 152), + (15, .symbol, 152), + (24, .symbol, 152), + (31, .symbol, 152), + (41, .symbol, 152), + (56, [.accepted, .symbol], 152), + (3, .symbol, 155), + (6, .symbol, 155), + (10, .symbol, 155), + (15, .symbol, 155), + (24, .symbol, 155), + (31, .symbol, 155), + (41, .symbol, 155), + (56, [.accepted, .symbol], 155), + + /* 161 */ + + (3, .symbol, 157), + (6, .symbol, 157), + (10, .symbol, 157), + (15, .symbol, 157), + (24, .symbol, 157), + (31, .symbol, 157), + (41, .symbol, 157), + (56, [.accepted, .symbol], 157), + (3, .symbol, 158), + (6, .symbol, 158), + (10, .symbol, 158), + (15, .symbol, 158), + (24, .symbol, 158), + (31, .symbol, 158), + (41, .symbol, 158), + (56, [.accepted, .symbol], 158), + + /* 162 */ + + (1, .symbol, 165), + (22, [.accepted, .symbol], 165), + (1, .symbol, 166), + (22, [.accepted, .symbol], 166), + (1, .symbol, 168), + (22, [.accepted, .symbol], 168), + (1, .symbol, 174), + (22, [.accepted, .symbol], 174), + (1, .symbol, 175), + (22, [.accepted, .symbol], 175), + (1, .symbol, 180), + (22, [.accepted, .symbol], 180), + (1, .symbol, 182), + (22, [.accepted, .symbol], 182), + (1, .symbol, 183), + (22, [.accepted, .symbol], 183), + + /* 163 */ + + (2, .symbol, 165), + (9, .symbol, 165), + (23, .symbol, 165), + (40, [.accepted, .symbol], 165), + (2, .symbol, 166), + (9, .symbol, 166), + (23, .symbol, 166), + (40, [.accepted, .symbol], 166), + (2, .symbol, 168), + (9, .symbol, 168), + (23, .symbol, 168), + (40, [.accepted, .symbol], 168), + (2, .symbol, 174), + (9, .symbol, 174), + (23, .symbol, 174), + (40, [.accepted, .symbol], 174), + + /* 164 */ + + (3, .symbol, 165), + (6, .symbol, 165), + (10, .symbol, 165), + (15, .symbol, 165), + (24, .symbol, 165), + (31, .symbol, 165), + (41, .symbol, 165), + (56, [.accepted, .symbol], 165), + (3, .symbol, 166), + (6, .symbol, 166), + (10, .symbol, 166), + (15, .symbol, 166), + (24, .symbol, 166), + (31, .symbol, 166), + (41, .symbol, 166), + (56, [.accepted, .symbol], 166), + + /* 165 */ + + (3, .symbol, 168), + (6, .symbol, 168), + (10, .symbol, 168), + (15, .symbol, 168), + (24, .symbol, 168), + (31, .symbol, 168), + (41, .symbol, 168), + (56, [.accepted, .symbol], 168), + (3, .symbol, 174), + (6, .symbol, 174), + (10, .symbol, 174), + (15, .symbol, 174), + (24, .symbol, 174), + (31, .symbol, 174), + (41, .symbol, 174), + (56, [.accepted, .symbol], 174), + + /* 166 */ + + (2, .symbol, 175), + (9, .symbol, 175), + (23, .symbol, 175), + (40, [.accepted, .symbol], 175), + (2, .symbol, 180), + (9, .symbol, 180), + (23, .symbol, 180), + (40, [.accepted, .symbol], 180), + (2, .symbol, 182), + (9, .symbol, 182), + (23, .symbol, 182), + (40, [.accepted, .symbol], 182), + (2, .symbol, 183), + (9, .symbol, 183), + (23, .symbol, 183), + (40, [.accepted, .symbol], 183), + + /* 167 */ + + (3, .symbol, 175), + (6, .symbol, 175), + (10, .symbol, 175), + (15, .symbol, 175), + (24, .symbol, 175), + (31, .symbol, 175), + (41, .symbol, 175), + (56, [.accepted, .symbol], 175), + (3, .symbol, 180), + (6, .symbol, 180), + (10, .symbol, 180), + (15, .symbol, 180), + (24, .symbol, 180), + (31, .symbol, 180), + (41, .symbol, 180), + (56, [.accepted, .symbol], 180), + + /* 168 */ + + (3, .symbol, 182), + (6, .symbol, 182), + (10, .symbol, 182), + (15, .symbol, 182), + (24, .symbol, 182), + (31, .symbol, 182), + (41, .symbol, 182), + (56, [.accepted, .symbol], 182), + (3, .symbol, 183), + (6, .symbol, 183), + (10, .symbol, 183), + (15, .symbol, 183), + (24, .symbol, 183), + (31, .symbol, 183), + (41, .symbol, 183), + (56, [.accepted, .symbol], 183), + + /* 169 */ + + (0, [.accepted, .symbol], 188), + (0, [.accepted, .symbol], 191), + (0, [.accepted, .symbol], 197), + (0, [.accepted, .symbol], 231), + (0, [.accepted, .symbol], 239), + (176, .none, 0), + (178, .none, 0), + (179, .none, 0), + (183, .none, 0), + (184, .none, 0), + (186, .none, 0), + (187, .none, 0), + (192, .none, 0), + (199, .none, 0), + (208, .none, 0), + (223, .none, 0), + + /* 170 */ + + (1, .symbol, 188), + (22, [.accepted, .symbol], 188), + (1, .symbol, 191), + (22, [.accepted, .symbol], 191), + (1, .symbol, 197), + (22, [.accepted, .symbol], 197), + (1, .symbol, 231), + (22, [.accepted, .symbol], 231), + (1, .symbol, 239), + (22, [.accepted, .symbol], 239), + (0, [.accepted, .symbol], 9), + (0, [.accepted, .symbol], 142), + (0, [.accepted, .symbol], 144), + (0, [.accepted, .symbol], 145), + (0, [.accepted, .symbol], 148), + (0, [.accepted, .symbol], 159), + + /* 171 */ + + (2, .symbol, 188), + (9, .symbol, 188), + (23, .symbol, 188), + (40, [.accepted, .symbol], 188), + (2, .symbol, 191), + (9, .symbol, 191), + (23, .symbol, 191), + (40, [.accepted, .symbol], 191), + (2, .symbol, 197), + (9, .symbol, 197), + (23, .symbol, 197), + (40, [.accepted, .symbol], 197), + (2, .symbol, 231), + (9, .symbol, 231), + (23, .symbol, 231), + (40, [.accepted, .symbol], 231), + + /* 172 */ + + (3, .symbol, 188), + (6, .symbol, 188), + (10, .symbol, 188), + (15, .symbol, 188), + (24, .symbol, 188), + (31, .symbol, 188), + (41, .symbol, 188), + (56, [.accepted, .symbol], 188), + (3, .symbol, 191), + (6, .symbol, 191), + (10, .symbol, 191), + (15, .symbol, 191), + (24, .symbol, 191), + (31, .symbol, 191), + (41, .symbol, 191), + (56, [.accepted, .symbol], 191), + + /* 173 */ + + (3, .symbol, 197), + (6, .symbol, 197), + (10, .symbol, 197), + (15, .symbol, 197), + (24, .symbol, 197), + (31, .symbol, 197), + (41, .symbol, 197), + (56, [.accepted, .symbol], 197), + (3, .symbol, 231), + (6, .symbol, 231), + (10, .symbol, 231), + (15, .symbol, 231), + (24, .symbol, 231), + (31, .symbol, 231), + (41, .symbol, 231), + (56, [.accepted, .symbol], 231), + + /* 174 */ + + (2, .symbol, 239), + (9, .symbol, 239), + (23, .symbol, 239), + (40, [.accepted, .symbol], 239), + (1, .symbol, 9), + (22, [.accepted, .symbol], 9), + (1, .symbol, 142), + (22, [.accepted, .symbol], 142), + (1, .symbol, 144), + (22, [.accepted, .symbol], 144), + (1, .symbol, 145), + (22, [.accepted, .symbol], 145), + (1, .symbol, 148), + (22, [.accepted, .symbol], 148), + (1, .symbol, 159), + (22, [.accepted, .symbol], 159), + + /* 175 */ + + (3, .symbol, 239), + (6, .symbol, 239), + (10, .symbol, 239), + (15, .symbol, 239), + (24, .symbol, 239), + (31, .symbol, 239), + (41, .symbol, 239), + (56, [.accepted, .symbol], 239), + (2, .symbol, 9), + (9, .symbol, 9), + (23, .symbol, 9), + (40, [.accepted, .symbol], 9), + (2, .symbol, 142), + (9, .symbol, 142), + (23, .symbol, 142), + (40, [.accepted, .symbol], 142), + + /* 176 */ + + (3, .symbol, 9), + (6, .symbol, 9), + (10, .symbol, 9), + (15, .symbol, 9), + (24, .symbol, 9), + (31, .symbol, 9), + (41, .symbol, 9), + (56, [.accepted, .symbol], 9), + (3, .symbol, 142), + (6, .symbol, 142), + (10, .symbol, 142), + (15, .symbol, 142), + (24, .symbol, 142), + (31, .symbol, 142), + (41, .symbol, 142), + (56, [.accepted, .symbol], 142), + + /* 177 */ + + (2, .symbol, 144), + (9, .symbol, 144), + (23, .symbol, 144), + (40, [.accepted, .symbol], 144), + (2, .symbol, 145), + (9, .symbol, 145), + (23, .symbol, 145), + (40, [.accepted, .symbol], 145), + (2, .symbol, 148), + (9, .symbol, 148), + (23, .symbol, 148), + (40, [.accepted, .symbol], 148), + (2, .symbol, 159), + (9, .symbol, 159), + (23, .symbol, 159), + (40, [.accepted, .symbol], 159), + + /* 178 */ + + (3, .symbol, 144), + (6, .symbol, 144), + (10, .symbol, 144), + (15, .symbol, 144), + (24, .symbol, 144), + (31, .symbol, 144), + (41, .symbol, 144), + (56, [.accepted, .symbol], 144), + (3, .symbol, 145), + (6, .symbol, 145), + (10, .symbol, 145), + (15, .symbol, 145), + (24, .symbol, 145), + (31, .symbol, 145), + (41, .symbol, 145), + (56, [.accepted, .symbol], 145), + + /* 179 */ + + (3, .symbol, 148), + (6, .symbol, 148), + (10, .symbol, 148), + (15, .symbol, 148), + (24, .symbol, 148), + (31, .symbol, 148), + (41, .symbol, 148), + (56, [.accepted, .symbol], 148), + (3, .symbol, 159), + (6, .symbol, 159), + (10, .symbol, 159), + (15, .symbol, 159), + (24, .symbol, 159), + (31, .symbol, 159), + (41, .symbol, 159), + (56, [.accepted, .symbol], 159), + + /* 180 */ + + (0, [.accepted, .symbol], 171), + (0, [.accepted, .symbol], 206), + (0, [.accepted, .symbol], 215), + (0, [.accepted, .symbol], 225), + (0, [.accepted, .symbol], 236), + (0, [.accepted, .symbol], 237), + (188, .none, 0), + (189, .none, 0), + (193, .none, 0), + (196, .none, 0), + (200, .none, 0), + (203, .none, 0), + (209, .none, 0), + (216, .none, 0), + (224, .none, 0), + (238, .none, 0), + + /* 181 */ + + (1, .symbol, 171), + (22, [.accepted, .symbol], 171), + (1, .symbol, 206), + (22, [.accepted, .symbol], 206), + (1, .symbol, 215), + (22, [.accepted, .symbol], 215), + (1, .symbol, 225), + (22, [.accepted, .symbol], 225), + (1, .symbol, 236), + (22, [.accepted, .symbol], 236), + (1, .symbol, 237), + (22, [.accepted, .symbol], 237), + (0, [.accepted, .symbol], 199), + (0, [.accepted, .symbol], 207), + (0, [.accepted, .symbol], 234), + (0, [.accepted, .symbol], 235), + + /* 182 */ + + (2, .symbol, 171), + (9, .symbol, 171), + (23, .symbol, 171), + (40, [.accepted, .symbol], 171), + (2, .symbol, 206), + (9, .symbol, 206), + (23, .symbol, 206), + (40, [.accepted, .symbol], 206), + (2, .symbol, 215), + (9, .symbol, 215), + (23, .symbol, 215), + (40, [.accepted, .symbol], 215), + (2, .symbol, 225), + (9, .symbol, 225), + (23, .symbol, 225), + (40, [.accepted, .symbol], 225), + + /* 183 */ + + (3, .symbol, 171), + (6, .symbol, 171), + (10, .symbol, 171), + (15, .symbol, 171), + (24, .symbol, 171), + (31, .symbol, 171), + (41, .symbol, 171), + (56, [.accepted, .symbol], 171), + (3, .symbol, 206), + (6, .symbol, 206), + (10, .symbol, 206), + (15, .symbol, 206), + (24, .symbol, 206), + (31, .symbol, 206), + (41, .symbol, 206), + (56, [.accepted, .symbol], 206), + + /* 184 */ + + (3, .symbol, 215), + (6, .symbol, 215), + (10, .symbol, 215), + (15, .symbol, 215), + (24, .symbol, 215), + (31, .symbol, 215), + (41, .symbol, 215), + (56, [.accepted, .symbol], 215), + (3, .symbol, 225), + (6, .symbol, 225), + (10, .symbol, 225), + (15, .symbol, 225), + (24, .symbol, 225), + (31, .symbol, 225), + (41, .symbol, 225), + (56, [.accepted, .symbol], 225), + + /* 185 */ + + (2, .symbol, 236), + (9, .symbol, 236), + (23, .symbol, 236), + (40, [.accepted, .symbol], 236), + (2, .symbol, 237), + (9, .symbol, 237), + (23, .symbol, 237), + (40, [.accepted, .symbol], 237), + (1, .symbol, 199), + (22, [.accepted, .symbol], 199), + (1, .symbol, 207), + (22, [.accepted, .symbol], 207), + (1, .symbol, 234), + (22, [.accepted, .symbol], 234), + (1, .symbol, 235), + (22, [.accepted, .symbol], 235), + + /* 186 */ + + (3, .symbol, 236), + (6, .symbol, 236), + (10, .symbol, 236), + (15, .symbol, 236), + (24, .symbol, 236), + (31, .symbol, 236), + (41, .symbol, 236), + (56, [.accepted, .symbol], 236), + (3, .symbol, 237), + (6, .symbol, 237), + (10, .symbol, 237), + (15, .symbol, 237), + (24, .symbol, 237), + (31, .symbol, 237), + (41, .symbol, 237), + (56, [.accepted, .symbol], 237), + + /* 187 */ + + (2, .symbol, 199), + (9, .symbol, 199), + (23, .symbol, 199), + (40, [.accepted, .symbol], 199), + (2, .symbol, 207), + (9, .symbol, 207), + (23, .symbol, 207), + (40, [.accepted, .symbol], 207), + (2, .symbol, 234), + (9, .symbol, 234), + (23, .symbol, 234), + (40, [.accepted, .symbol], 234), + (2, .symbol, 235), + (9, .symbol, 235), + (23, .symbol, 235), + (40, [.accepted, .symbol], 235), + + /* 188 */ + + (3, .symbol, 199), + (6, .symbol, 199), + (10, .symbol, 199), + (15, .symbol, 199), + (24, .symbol, 199), + (31, .symbol, 199), + (41, .symbol, 199), + (56, [.accepted, .symbol], 199), + (3, .symbol, 207), + (6, .symbol, 207), + (10, .symbol, 207), + (15, .symbol, 207), + (24, .symbol, 207), + (31, .symbol, 207), + (41, .symbol, 207), + (56, [.accepted, .symbol], 207), + + /* 189 */ + + (3, .symbol, 234), + (6, .symbol, 234), + (10, .symbol, 234), + (15, .symbol, 234), + (24, .symbol, 234), + (31, .symbol, 234), + (41, .symbol, 234), + (56, [.accepted, .symbol], 234), + (3, .symbol, 235), + (6, .symbol, 235), + (10, .symbol, 235), + (15, .symbol, 235), + (24, .symbol, 235), + (31, .symbol, 235), + (41, .symbol, 235), + (56, [.accepted, .symbol], 235), + + /* 190 */ + + (194, .none, 0), + (195, .none, 0), + (197, .none, 0), + (198, .none, 0), + (201, .none, 0), + (202, .none, 0), + (204, .none, 0), + (205, .none, 0), + (210, .none, 0), + (213, .none, 0), + (217, .none, 0), + (220, .none, 0), + (225, .none, 0), + (231, .none, 0), + (239, .none, 0), + (246, .none, 0), + + /* 191 */ + + (0, [.accepted, .symbol], 192), + (0, [.accepted, .symbol], 193), + (0, [.accepted, .symbol], 200), + (0, [.accepted, .symbol], 201), + (0, [.accepted, .symbol], 202), + (0, [.accepted, .symbol], 205), + (0, [.accepted, .symbol], 210), + (0, [.accepted, .symbol], 213), + (0, [.accepted, .symbol], 218), + (0, [.accepted, .symbol], 219), + (0, [.accepted, .symbol], 238), + (0, [.accepted, .symbol], 240), + (0, [.accepted, .symbol], 242), + (0, [.accepted, .symbol], 243), + (0, [.accepted, .symbol], 255), + (206, .none, 0), + + /* 192 */ + + (1, .symbol, 192), + (22, [.accepted, .symbol], 192), + (1, .symbol, 193), + (22, [.accepted, .symbol], 193), + (1, .symbol, 200), + (22, [.accepted, .symbol], 200), + (1, .symbol, 201), + (22, [.accepted, .symbol], 201), + (1, .symbol, 202), + (22, [.accepted, .symbol], 202), + (1, .symbol, 205), + (22, [.accepted, .symbol], 205), + (1, .symbol, 210), + (22, [.accepted, .symbol], 210), + (1, .symbol, 213), + (22, [.accepted, .symbol], 213), + + /* 193 */ + + (2, .symbol, 192), + (9, .symbol, 192), + (23, .symbol, 192), + (40, [.accepted, .symbol], 192), + (2, .symbol, 193), + (9, .symbol, 193), + (23, .symbol, 193), + (40, [.accepted, .symbol], 193), + (2, .symbol, 200), + (9, .symbol, 200), + (23, .symbol, 200), + (40, [.accepted, .symbol], 200), + (2, .symbol, 201), + (9, .symbol, 201), + (23, .symbol, 201), + (40, [.accepted, .symbol], 201), + + /* 194 */ + + (3, .symbol, 192), + (6, .symbol, 192), + (10, .symbol, 192), + (15, .symbol, 192), + (24, .symbol, 192), + (31, .symbol, 192), + (41, .symbol, 192), + (56, [.accepted, .symbol], 192), + (3, .symbol, 193), + (6, .symbol, 193), + (10, .symbol, 193), + (15, .symbol, 193), + (24, .symbol, 193), + (31, .symbol, 193), + (41, .symbol, 193), + (56, [.accepted, .symbol], 193), + + /* 195 */ + + (3, .symbol, 200), + (6, .symbol, 200), + (10, .symbol, 200), + (15, .symbol, 200), + (24, .symbol, 200), + (31, .symbol, 200), + (41, .symbol, 200), + (56, [.accepted, .symbol], 200), + (3, .symbol, 201), + (6, .symbol, 201), + (10, .symbol, 201), + (15, .symbol, 201), + (24, .symbol, 201), + (31, .symbol, 201), + (41, .symbol, 201), + (56, [.accepted, .symbol], 201), + + /* 196 */ + + (2, .symbol, 202), + (9, .symbol, 202), + (23, .symbol, 202), + (40, [.accepted, .symbol], 202), + (2, .symbol, 205), + (9, .symbol, 205), + (23, .symbol, 205), + (40, [.accepted, .symbol], 205), + (2, .symbol, 210), + (9, .symbol, 210), + (23, .symbol, 210), + (40, [.accepted, .symbol], 210), + (2, .symbol, 213), + (9, .symbol, 213), + (23, .symbol, 213), + (40, [.accepted, .symbol], 213), + + /* 197 */ + + (3, .symbol, 202), + (6, .symbol, 202), + (10, .symbol, 202), + (15, .symbol, 202), + (24, .symbol, 202), + (31, .symbol, 202), + (41, .symbol, 202), + (56, [.accepted, .symbol], 202), + (3, .symbol, 205), + (6, .symbol, 205), + (10, .symbol, 205), + (15, .symbol, 205), + (24, .symbol, 205), + (31, .symbol, 205), + (41, .symbol, 205), + (56, [.accepted, .symbol], 205), + + /* 198 */ + + (3, .symbol, 210), + (6, .symbol, 210), + (10, .symbol, 210), + (15, .symbol, 210), + (24, .symbol, 210), + (31, .symbol, 210), + (41, .symbol, 210), + (56, [.accepted, .symbol], 210), + (3, .symbol, 213), + (6, .symbol, 213), + (10, .symbol, 213), + (15, .symbol, 213), + (24, .symbol, 213), + (31, .symbol, 213), + (41, .symbol, 213), + (56, [.accepted, .symbol], 213), + + /* 199 */ + + (1, .symbol, 218), + (22, [.accepted, .symbol], 218), + (1, .symbol, 219), + (22, [.accepted, .symbol], 219), + (1, .symbol, 238), + (22, [.accepted, .symbol], 238), + (1, .symbol, 240), + (22, [.accepted, .symbol], 240), + (1, .symbol, 242), + (22, [.accepted, .symbol], 242), + (1, .symbol, 243), + (22, [.accepted, .symbol], 243), + (1, .symbol, 255), + (22, [.accepted, .symbol], 255), + (0, [.accepted, .symbol], 203), + (0, [.accepted, .symbol], 204), + + /* 200 */ + + (2, .symbol, 218), + (9, .symbol, 218), + (23, .symbol, 218), + (40, [.accepted, .symbol], 218), + (2, .symbol, 219), + (9, .symbol, 219), + (23, .symbol, 219), + (40, [.accepted, .symbol], 219), + (2, .symbol, 238), + (9, .symbol, 238), + (23, .symbol, 238), + (40, [.accepted, .symbol], 238), + (2, .symbol, 240), + (9, .symbol, 240), + (23, .symbol, 240), + (40, [.accepted, .symbol], 240), + + /* 201 */ + + (3, .symbol, 218), + (6, .symbol, 218), + (10, .symbol, 218), + (15, .symbol, 218), + (24, .symbol, 218), + (31, .symbol, 218), + (41, .symbol, 218), + (56, [.accepted, .symbol], 218), + (3, .symbol, 219), + (6, .symbol, 219), + (10, .symbol, 219), + (15, .symbol, 219), + (24, .symbol, 219), + (31, .symbol, 219), + (41, .symbol, 219), + (56, [.accepted, .symbol], 219), + + /* 202 */ + + (3, .symbol, 238), + (6, .symbol, 238), + (10, .symbol, 238), + (15, .symbol, 238), + (24, .symbol, 238), + (31, .symbol, 238), + (41, .symbol, 238), + (56, [.accepted, .symbol], 238), + (3, .symbol, 240), + (6, .symbol, 240), + (10, .symbol, 240), + (15, .symbol, 240), + (24, .symbol, 240), + (31, .symbol, 240), + (41, .symbol, 240), + (56, [.accepted, .symbol], 240), + + /* 203 */ + + (2, .symbol, 242), + (9, .symbol, 242), + (23, .symbol, 242), + (40, [.accepted, .symbol], 242), + (2, .symbol, 243), + (9, .symbol, 243), + (23, .symbol, 243), + (40, [.accepted, .symbol], 243), + (2, .symbol, 255), + (9, .symbol, 255), + (23, .symbol, 255), + (40, [.accepted, .symbol], 255), + (1, .symbol, 203), + (22, [.accepted, .symbol], 203), + (1, .symbol, 204), + (22, [.accepted, .symbol], 204), + + /* 204 */ + + (3, .symbol, 242), + (6, .symbol, 242), + (10, .symbol, 242), + (15, .symbol, 242), + (24, .symbol, 242), + (31, .symbol, 242), + (41, .symbol, 242), + (56, [.accepted, .symbol], 242), + (3, .symbol, 243), + (6, .symbol, 243), + (10, .symbol, 243), + (15, .symbol, 243), + (24, .symbol, 243), + (31, .symbol, 243), + (41, .symbol, 243), + (56, [.accepted, .symbol], 243), + + /* 205 */ + + (3, .symbol, 255), + (6, .symbol, 255), + (10, .symbol, 255), + (15, .symbol, 255), + (24, .symbol, 255), + (31, .symbol, 255), + (41, .symbol, 255), + (56, [.accepted, .symbol], 255), + (2, .symbol, 203), + (9, .symbol, 203), + (23, .symbol, 203), + (40, [.accepted, .symbol], 203), + (2, .symbol, 204), + (9, .symbol, 204), + (23, .symbol, 204), + (40, [.accepted, .symbol], 204), + + /* 206 */ + + (3, .symbol, 203), + (6, .symbol, 203), + (10, .symbol, 203), + (15, .symbol, 203), + (24, .symbol, 203), + (31, .symbol, 203), + (41, .symbol, 203), + (56, [.accepted, .symbol], 203), + (3, .symbol, 204), + (6, .symbol, 204), + (10, .symbol, 204), + (15, .symbol, 204), + (24, .symbol, 204), + (31, .symbol, 204), + (41, .symbol, 204), + (56, [.accepted, .symbol], 204), + + /* 207 */ + + (211, .none, 0), + (212, .none, 0), + (214, .none, 0), + (215, .none, 0), + (218, .none, 0), + (219, .none, 0), + (221, .none, 0), + (222, .none, 0), + (226, .none, 0), + (228, .none, 0), + (232, .none, 0), + (235, .none, 0), + (240, .none, 0), + (243, .none, 0), + (247, .none, 0), + (250, .none, 0), + + /* 208 */ + + (0, [.accepted, .symbol], 211), + (0, [.accepted, .symbol], 212), + (0, [.accepted, .symbol], 214), + (0, [.accepted, .symbol], 221), + (0, [.accepted, .symbol], 222), + (0, [.accepted, .symbol], 223), + (0, [.accepted, .symbol], 241), + (0, [.accepted, .symbol], 244), + (0, [.accepted, .symbol], 245), + (0, [.accepted, .symbol], 246), + (0, [.accepted, .symbol], 247), + (0, [.accepted, .symbol], 248), + (0, [.accepted, .symbol], 250), + (0, [.accepted, .symbol], 251), + (0, [.accepted, .symbol], 252), + (0, [.accepted, .symbol], 253), + + /* 209 */ + + (1, .symbol, 211), + (22, [.accepted, .symbol], 211), + (1, .symbol, 212), + (22, [.accepted, .symbol], 212), + (1, .symbol, 214), + (22, [.accepted, .symbol], 214), + (1, .symbol, 221), + (22, [.accepted, .symbol], 221), + (1, .symbol, 222), + (22, [.accepted, .symbol], 222), + (1, .symbol, 223), + (22, [.accepted, .symbol], 223), + (1, .symbol, 241), + (22, [.accepted, .symbol], 241), + (1, .symbol, 244), + (22, [.accepted, .symbol], 244), + + /* 210 */ + + (2, .symbol, 211), + (9, .symbol, 211), + (23, .symbol, 211), + (40, [.accepted, .symbol], 211), + (2, .symbol, 212), + (9, .symbol, 212), + (23, .symbol, 212), + (40, [.accepted, .symbol], 212), + (2, .symbol, 214), + (9, .symbol, 214), + (23, .symbol, 214), + (40, [.accepted, .symbol], 214), + (2, .symbol, 221), + (9, .symbol, 221), + (23, .symbol, 221), + (40, [.accepted, .symbol], 221), + + /* 211 */ + + (3, .symbol, 211), + (6, .symbol, 211), + (10, .symbol, 211), + (15, .symbol, 211), + (24, .symbol, 211), + (31, .symbol, 211), + (41, .symbol, 211), + (56, [.accepted, .symbol], 211), + (3, .symbol, 212), + (6, .symbol, 212), + (10, .symbol, 212), + (15, .symbol, 212), + (24, .symbol, 212), + (31, .symbol, 212), + (41, .symbol, 212), + (56, [.accepted, .symbol], 212), + + /* 212 */ + + (3, .symbol, 214), + (6, .symbol, 214), + (10, .symbol, 214), + (15, .symbol, 214), + (24, .symbol, 214), + (31, .symbol, 214), + (41, .symbol, 214), + (56, [.accepted, .symbol], 214), + (3, .symbol, 221), + (6, .symbol, 221), + (10, .symbol, 221), + (15, .symbol, 221), + (24, .symbol, 221), + (31, .symbol, 221), + (41, .symbol, 221), + (56, [.accepted, .symbol], 221), + + /* 213 */ + + (2, .symbol, 222), + (9, .symbol, 222), + (23, .symbol, 222), + (40, [.accepted, .symbol], 222), + (2, .symbol, 223), + (9, .symbol, 223), + (23, .symbol, 223), + (40, [.accepted, .symbol], 223), + (2, .symbol, 241), + (9, .symbol, 241), + (23, .symbol, 241), + (40, [.accepted, .symbol], 241), + (2, .symbol, 244), + (9, .symbol, 244), + (23, .symbol, 244), + (40, [.accepted, .symbol], 244), + + /* 214 */ + + (3, .symbol, 222), + (6, .symbol, 222), + (10, .symbol, 222), + (15, .symbol, 222), + (24, .symbol, 222), + (31, .symbol, 222), + (41, .symbol, 222), + (56, [.accepted, .symbol], 222), + (3, .symbol, 223), + (6, .symbol, 223), + (10, .symbol, 223), + (15, .symbol, 223), + (24, .symbol, 223), + (31, .symbol, 223), + (41, .symbol, 223), + (56, [.accepted, .symbol], 223), + + /* 215 */ + + (3, .symbol, 241), + (6, .symbol, 241), + (10, .symbol, 241), + (15, .symbol, 241), + (24, .symbol, 241), + (31, .symbol, 241), + (41, .symbol, 241), + (56, [.accepted, .symbol], 241), + (3, .symbol, 244), + (6, .symbol, 244), + (10, .symbol, 244), + (15, .symbol, 244), + (24, .symbol, 244), + (31, .symbol, 244), + (41, .symbol, 244), + (56, [.accepted, .symbol], 244), + + /* 216 */ + + (1, .symbol, 245), + (22, [.accepted, .symbol], 245), + (1, .symbol, 246), + (22, [.accepted, .symbol], 246), + (1, .symbol, 247), + (22, [.accepted, .symbol], 247), + (1, .symbol, 248), + (22, [.accepted, .symbol], 248), + (1, .symbol, 250), + (22, [.accepted, .symbol], 250), + (1, .symbol, 251), + (22, [.accepted, .symbol], 251), + (1, .symbol, 252), + (22, [.accepted, .symbol], 252), + (1, .symbol, 253), + (22, [.accepted, .symbol], 253), + + /* 217 */ + + (2, .symbol, 245), + (9, .symbol, 245), + (23, .symbol, 245), + (40, [.accepted, .symbol], 245), + (2, .symbol, 246), + (9, .symbol, 246), + (23, .symbol, 246), + (40, [.accepted, .symbol], 246), + (2, .symbol, 247), + (9, .symbol, 247), + (23, .symbol, 247), + (40, [.accepted, .symbol], 247), + (2, .symbol, 248), + (9, .symbol, 248), + (23, .symbol, 248), + (40, [.accepted, .symbol], 248), + + /* 218 */ + + (3, .symbol, 245), + (6, .symbol, 245), + (10, .symbol, 245), + (15, .symbol, 245), + (24, .symbol, 245), + (31, .symbol, 245), + (41, .symbol, 245), + (56, [.accepted, .symbol], 245), + (3, .symbol, 246), + (6, .symbol, 246), + (10, .symbol, 246), + (15, .symbol, 246), + (24, .symbol, 246), + (31, .symbol, 246), + (41, .symbol, 246), + (56, [.accepted, .symbol], 246), + + /* 219 */ + + (3, .symbol, 247), + (6, .symbol, 247), + (10, .symbol, 247), + (15, .symbol, 247), + (24, .symbol, 247), + (31, .symbol, 247), + (41, .symbol, 247), + (56, [.accepted, .symbol], 247), + (3, .symbol, 248), + (6, .symbol, 248), + (10, .symbol, 248), + (15, .symbol, 248), + (24, .symbol, 248), + (31, .symbol, 248), + (41, .symbol, 248), + (56, [.accepted, .symbol], 248), + + /* 220 */ + + (2, .symbol, 250), + (9, .symbol, 250), + (23, .symbol, 250), + (40, [.accepted, .symbol], 250), + (2, .symbol, 251), + (9, .symbol, 251), + (23, .symbol, 251), + (40, [.accepted, .symbol], 251), + (2, .symbol, 252), + (9, .symbol, 252), + (23, .symbol, 252), + (40, [.accepted, .symbol], 252), + (2, .symbol, 253), + (9, .symbol, 253), + (23, .symbol, 253), + (40, [.accepted, .symbol], 253), + + /* 221 */ + + (3, .symbol, 250), + (6, .symbol, 250), + (10, .symbol, 250), + (15, .symbol, 250), + (24, .symbol, 250), + (31, .symbol, 250), + (41, .symbol, 250), + (56, [.accepted, .symbol], 250), + (3, .symbol, 251), + (6, .symbol, 251), + (10, .symbol, 251), + (15, .symbol, 251), + (24, .symbol, 251), + (31, .symbol, 251), + (41, .symbol, 251), + (56, [.accepted, .symbol], 251), + + /* 222 */ + + (3, .symbol, 252), + (6, .symbol, 252), + (10, .symbol, 252), + (15, .symbol, 252), + (24, .symbol, 252), + (31, .symbol, 252), + (41, .symbol, 252), + (56, [.accepted, .symbol], 252), + (3, .symbol, 253), + (6, .symbol, 253), + (10, .symbol, 253), + (15, .symbol, 253), + (24, .symbol, 253), + (31, .symbol, 253), + (41, .symbol, 253), + (56, [.accepted, .symbol], 253), + + /* 223 */ + + (0, [.accepted, .symbol], 254), + (227, .none, 0), + (229, .none, 0), + (230, .none, 0), + (233, .none, 0), + (234, .none, 0), + (236, .none, 0), + (237, .none, 0), + (241, .none, 0), + (242, .none, 0), + (244, .none, 0), + (245, .none, 0), + (248, .none, 0), + (249, .none, 0), + (251, .none, 0), + (252, .none, 0), + + /* 224 */ + + (1, .symbol, 254), + (22, [.accepted, .symbol], 254), + (0, [.accepted, .symbol], 2), + (0, [.accepted, .symbol], 3), + (0, [.accepted, .symbol], 4), + (0, [.accepted, .symbol], 5), + (0, [.accepted, .symbol], 6), + (0, [.accepted, .symbol], 7), + (0, [.accepted, .symbol], 8), + (0, [.accepted, .symbol], 11), + (0, [.accepted, .symbol], 12), + (0, [.accepted, .symbol], 14), + (0, [.accepted, .symbol], 15), + (0, [.accepted, .symbol], 16), + (0, [.accepted, .symbol], 17), + (0, [.accepted, .symbol], 18), + + /* 225 */ + + (2, .symbol, 254), + (9, .symbol, 254), + (23, .symbol, 254), + (40, [.accepted, .symbol], 254), + (1, .symbol, 2), + (22, [.accepted, .symbol], 2), + (1, .symbol, 3), + (22, [.accepted, .symbol], 3), + (1, .symbol, 4), + (22, [.accepted, .symbol], 4), + (1, .symbol, 5), + (22, [.accepted, .symbol], 5), + (1, .symbol, 6), + (22, [.accepted, .symbol], 6), + (1, .symbol, 7), + (22, [.accepted, .symbol], 7), + + /* 226 */ + + (3, .symbol, 254), + (6, .symbol, 254), + (10, .symbol, 254), + (15, .symbol, 254), + (24, .symbol, 254), + (31, .symbol, 254), + (41, .symbol, 254), + (56, [.accepted, .symbol], 254), + (2, .symbol, 2), + (9, .symbol, 2), + (23, .symbol, 2), + (40, [.accepted, .symbol], 2), + (2, .symbol, 3), + (9, .symbol, 3), + (23, .symbol, 3), + (40, [.accepted, .symbol], 3), + + /* 227 */ + + (3, .symbol, 2), + (6, .symbol, 2), + (10, .symbol, 2), + (15, .symbol, 2), + (24, .symbol, 2), + (31, .symbol, 2), + (41, .symbol, 2), + (56, [.accepted, .symbol], 2), + (3, .symbol, 3), + (6, .symbol, 3), + (10, .symbol, 3), + (15, .symbol, 3), + (24, .symbol, 3), + (31, .symbol, 3), + (41, .symbol, 3), + (56, [.accepted, .symbol], 3), + + /* 228 */ + + (2, .symbol, 4), + (9, .symbol, 4), + (23, .symbol, 4), + (40, [.accepted, .symbol], 4), + (2, .symbol, 5), + (9, .symbol, 5), + (23, .symbol, 5), + (40, [.accepted, .symbol], 5), + (2, .symbol, 6), + (9, .symbol, 6), + (23, .symbol, 6), + (40, [.accepted, .symbol], 6), + (2, .symbol, 7), + (9, .symbol, 7), + (23, .symbol, 7), + (40, [.accepted, .symbol], 7), + + /* 229 */ + + (3, .symbol, 4), + (6, .symbol, 4), + (10, .symbol, 4), + (15, .symbol, 4), + (24, .symbol, 4), + (31, .symbol, 4), + (41, .symbol, 4), + (56, [.accepted, .symbol], 4), + (3, .symbol, 5), + (6, .symbol, 5), + (10, .symbol, 5), + (15, .symbol, 5), + (24, .symbol, 5), + (31, .symbol, 5), + (41, .symbol, 5), + (56, [.accepted, .symbol], 5), + + /* 230 */ + + (3, .symbol, 6), + (6, .symbol, 6), + (10, .symbol, 6), + (15, .symbol, 6), + (24, .symbol, 6), + (31, .symbol, 6), + (41, .symbol, 6), + (56, [.accepted, .symbol], 6), + (3, .symbol, 7), + (6, .symbol, 7), + (10, .symbol, 7), + (15, .symbol, 7), + (24, .symbol, 7), + (31, .symbol, 7), + (41, .symbol, 7), + (56, [.accepted, .symbol], 7), + + /* 231 */ + + (1, .symbol, 8), + (22, [.accepted, .symbol], 8), + (1, .symbol, 11), + (22, [.accepted, .symbol], 11), + (1, .symbol, 12), + (22, [.accepted, .symbol], 12), + (1, .symbol, 14), + (22, [.accepted, .symbol], 14), + (1, .symbol, 15), + (22, [.accepted, .symbol], 15), + (1, .symbol, 16), + (22, [.accepted, .symbol], 16), + (1, .symbol, 17), + (22, [.accepted, .symbol], 17), + (1, .symbol, 18), + (22, [.accepted, .symbol], 18), + + /* 232 */ + + (2, .symbol, 8), + (9, .symbol, 8), + (23, .symbol, 8), + (40, [.accepted, .symbol], 8), + (2, .symbol, 11), + (9, .symbol, 11), + (23, .symbol, 11), + (40, [.accepted, .symbol], 11), + (2, .symbol, 12), + (9, .symbol, 12), + (23, .symbol, 12), + (40, [.accepted, .symbol], 12), + (2, .symbol, 14), + (9, .symbol, 14), + (23, .symbol, 14), + (40, [.accepted, .symbol], 14), + + /* 233 */ + + (3, .symbol, 8), + (6, .symbol, 8), + (10, .symbol, 8), + (15, .symbol, 8), + (24, .symbol, 8), + (31, .symbol, 8), + (41, .symbol, 8), + (56, [.accepted, .symbol], 8), + (3, .symbol, 11), + (6, .symbol, 11), + (10, .symbol, 11), + (15, .symbol, 11), + (24, .symbol, 11), + (31, .symbol, 11), + (41, .symbol, 11), + (56, [.accepted, .symbol], 11), + + /* 234 */ + + (3, .symbol, 12), + (6, .symbol, 12), + (10, .symbol, 12), + (15, .symbol, 12), + (24, .symbol, 12), + (31, .symbol, 12), + (41, .symbol, 12), + (56, [.accepted, .symbol], 12), + (3, .symbol, 14), + (6, .symbol, 14), + (10, .symbol, 14), + (15, .symbol, 14), + (24, .symbol, 14), + (31, .symbol, 14), + (41, .symbol, 14), + (56, [.accepted, .symbol], 14), + + /* 235 */ + + (2, .symbol, 15), + (9, .symbol, 15), + (23, .symbol, 15), + (40, [.accepted, .symbol], 15), + (2, .symbol, 16), + (9, .symbol, 16), + (23, .symbol, 16), + (40, [.accepted, .symbol], 16), + (2, .symbol, 17), + (9, .symbol, 17), + (23, .symbol, 17), + (40, [.accepted, .symbol], 17), + (2, .symbol, 18), + (9, .symbol, 18), + (23, .symbol, 18), + (40, [.accepted, .symbol], 18), + + /* 236 */ + + (3, .symbol, 15), + (6, .symbol, 15), + (10, .symbol, 15), + (15, .symbol, 15), + (24, .symbol, 15), + (31, .symbol, 15), + (41, .symbol, 15), + (56, [.accepted, .symbol], 15), + (3, .symbol, 16), + (6, .symbol, 16), + (10, .symbol, 16), + (15, .symbol, 16), + (24, .symbol, 16), + (31, .symbol, 16), + (41, .symbol, 16), + (56, [.accepted, .symbol], 16), + + /* 237 */ + + (3, .symbol, 17), + (6, .symbol, 17), + (10, .symbol, 17), + (15, .symbol, 17), + (24, .symbol, 17), + (31, .symbol, 17), + (41, .symbol, 17), + (56, [.accepted, .symbol], 17), + (3, .symbol, 18), + (6, .symbol, 18), + (10, .symbol, 18), + (15, .symbol, 18), + (24, .symbol, 18), + (31, .symbol, 18), + (41, .symbol, 18), + (56, [.accepted, .symbol], 18), + + /* 238 */ + + (0, [.accepted, .symbol], 19), + (0, [.accepted, .symbol], 20), + (0, [.accepted, .symbol], 21), + (0, [.accepted, .symbol], 23), + (0, [.accepted, .symbol], 24), + (0, [.accepted, .symbol], 25), + (0, [.accepted, .symbol], 26), + (0, [.accepted, .symbol], 27), + (0, [.accepted, .symbol], 28), + (0, [.accepted, .symbol], 29), + (0, [.accepted, .symbol], 30), + (0, [.accepted, .symbol], 31), + (0, [.accepted, .symbol], 127), + (0, [.accepted, .symbol], 220), + (0, [.accepted, .symbol], 249), + (253, .none, 0), + + /* 239 */ + + (1, .symbol, 19), + (22, [.accepted, .symbol], 19), + (1, .symbol, 20), + (22, [.accepted, .symbol], 20), + (1, .symbol, 21), + (22, [.accepted, .symbol], 21), + (1, .symbol, 23), + (22, [.accepted, .symbol], 23), + (1, .symbol, 24), + (22, [.accepted, .symbol], 24), + (1, .symbol, 25), + (22, [.accepted, .symbol], 25), + (1, .symbol, 26), + (22, [.accepted, .symbol], 26), + (1, .symbol, 27), + (22, [.accepted, .symbol], 27), + + /* 240 */ + + (2, .symbol, 19), + (9, .symbol, 19), + (23, .symbol, 19), + (40, [.accepted, .symbol], 19), + (2, .symbol, 20), + (9, .symbol, 20), + (23, .symbol, 20), + (40, [.accepted, .symbol], 20), + (2, .symbol, 21), + (9, .symbol, 21), + (23, .symbol, 21), + (40, [.accepted, .symbol], 21), + (2, .symbol, 23), + (9, .symbol, 23), + (23, .symbol, 23), + (40, [.accepted, .symbol], 23), + + /* 241 */ + + (3, .symbol, 19), + (6, .symbol, 19), + (10, .symbol, 19), + (15, .symbol, 19), + (24, .symbol, 19), + (31, .symbol, 19), + (41, .symbol, 19), + (56, [.accepted, .symbol], 19), + (3, .symbol, 20), + (6, .symbol, 20), + (10, .symbol, 20), + (15, .symbol, 20), + (24, .symbol, 20), + (31, .symbol, 20), + (41, .symbol, 20), + (56, [.accepted, .symbol], 20), + + /* 242 */ + + (3, .symbol, 21), + (6, .symbol, 21), + (10, .symbol, 21), + (15, .symbol, 21), + (24, .symbol, 21), + (31, .symbol, 21), + (41, .symbol, 21), + (56, [.accepted, .symbol], 21), + (3, .symbol, 23), + (6, .symbol, 23), + (10, .symbol, 23), + (15, .symbol, 23), + (24, .symbol, 23), + (31, .symbol, 23), + (41, .symbol, 23), + (56, [.accepted, .symbol], 23), + + /* 243 */ + + (2, .symbol, 24), + (9, .symbol, 24), + (23, .symbol, 24), + (40, [.accepted, .symbol], 24), + (2, .symbol, 25), + (9, .symbol, 25), + (23, .symbol, 25), + (40, [.accepted, .symbol], 25), + (2, .symbol, 26), + (9, .symbol, 26), + (23, .symbol, 26), + (40, [.accepted, .symbol], 26), + (2, .symbol, 27), + (9, .symbol, 27), + (23, .symbol, 27), + (40, [.accepted, .symbol], 27), + + /* 244 */ + + (3, .symbol, 24), + (6, .symbol, 24), + (10, .symbol, 24), + (15, .symbol, 24), + (24, .symbol, 24), + (31, .symbol, 24), + (41, .symbol, 24), + (56, [.accepted, .symbol], 24), + (3, .symbol, 25), + (6, .symbol, 25), + (10, .symbol, 25), + (15, .symbol, 25), + (24, .symbol, 25), + (31, .symbol, 25), + (41, .symbol, 25), + (56, [.accepted, .symbol], 25), + + /* 245 */ + + (3, .symbol, 26), + (6, .symbol, 26), + (10, .symbol, 26), + (15, .symbol, 26), + (24, .symbol, 26), + (31, .symbol, 26), + (41, .symbol, 26), + (56, [.accepted, .symbol], 26), + (3, .symbol, 27), + (6, .symbol, 27), + (10, .symbol, 27), + (15, .symbol, 27), + (24, .symbol, 27), + (31, .symbol, 27), + (41, .symbol, 27), + (56, [.accepted, .symbol], 27), + + /* 246 */ + + (1, .symbol, 28), + (22, [.accepted, .symbol], 28), + (1, .symbol, 29), + (22, [.accepted, .symbol], 29), + (1, .symbol, 30), + (22, [.accepted, .symbol], 30), + (1, .symbol, 31), + (22, [.accepted, .symbol], 31), + (1, .symbol, 127), + (22, [.accepted, .symbol], 127), + (1, .symbol, 220), + (22, [.accepted, .symbol], 220), + (1, .symbol, 249), + (22, [.accepted, .symbol], 249), + (254, .none, 0), + (255, .none, 0), + + /* 247 */ + + (2, .symbol, 28), + (9, .symbol, 28), + (23, .symbol, 28), + (40, [.accepted, .symbol], 28), + (2, .symbol, 29), + (9, .symbol, 29), + (23, .symbol, 29), + (40, [.accepted, .symbol], 29), + (2, .symbol, 30), + (9, .symbol, 30), + (23, .symbol, 30), + (40, [.accepted, .symbol], 30), + (2, .symbol, 31), + (9, .symbol, 31), + (23, .symbol, 31), + (40, [.accepted, .symbol], 31), + + /* 248 */ + + (3, .symbol, 28), + (6, .symbol, 28), + (10, .symbol, 28), + (15, .symbol, 28), + (24, .symbol, 28), + (31, .symbol, 28), + (41, .symbol, 28), + (56, [.accepted, .symbol], 28), + (3, .symbol, 29), + (6, .symbol, 29), + (10, .symbol, 29), + (15, .symbol, 29), + (24, .symbol, 29), + (31, .symbol, 29), + (41, .symbol, 29), + (56, [.accepted, .symbol], 29), + + /* 249 */ + + (3, .symbol, 30), + (6, .symbol, 30), + (10, .symbol, 30), + (15, .symbol, 30), + (24, .symbol, 30), + (31, .symbol, 30), + (41, .symbol, 30), + (56, [.accepted, .symbol], 30), + (3, .symbol, 31), + (6, .symbol, 31), + (10, .symbol, 31), + (15, .symbol, 31), + (24, .symbol, 31), + (31, .symbol, 31), + (41, .symbol, 31), + (56, [.accepted, .symbol], 31), + + /* 250 */ + + (2, .symbol, 127), + (9, .symbol, 127), + (23, .symbol, 127), + (40, [.accepted, .symbol], 127), + (2, .symbol, 220), + (9, .symbol, 220), + (23, .symbol, 220), + (40, [.accepted, .symbol], 220), + (2, .symbol, 249), + (9, .symbol, 249), + (23, .symbol, 249), + (40, [.accepted, .symbol], 249), + (0, [.accepted, .symbol], 10), + (0, [.accepted, .symbol], 13), + (0, [.accepted, .symbol], 22), + (0, .failure, 0), + + /* 251 */ + + (3, .symbol, 127), + (6, .symbol, 127), + (10, .symbol, 127), + (15, .symbol, 127), + (24, .symbol, 127), + (31, .symbol, 127), + (41, .symbol, 127), + (56, [.accepted, .symbol], 127), + (3, .symbol, 220), + (6, .symbol, 220), + (10, .symbol, 220), + (15, .symbol, 220), + (24, .symbol, 220), + (31, .symbol, 220), + (41, .symbol, 220), + (56, [.accepted, .symbol], 220), + + /* 252 */ + + (3, .symbol, 249), + (6, .symbol, 249), + (10, .symbol, 249), + (15, .symbol, 249), + (24, .symbol, 249), + (31, .symbol, 249), + (41, .symbol, 249), + (56, [.accepted, .symbol], 249), + (1, .symbol, 10), + (22, [.accepted, .symbol], 10), + (1, .symbol, 13), + (22, [.accepted, .symbol], 13), + (1, .symbol, 22), + (22, [.accepted, .symbol], 22), + (0, .failure, 0), + (0, .failure, 0), + + /* 253 */ + + (2, .symbol, 10), + (9, .symbol, 10), + (23, .symbol, 10), + (40, [.accepted, .symbol], 10), + (2, .symbol, 13), + (9, .symbol, 13), + (23, .symbol, 13), + (40, [.accepted, .symbol], 13), + (2, .symbol, 22), + (9, .symbol, 22), + (23, .symbol, 22), + (40, [.accepted, .symbol], 22), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + + /* 254 */ + + (3, .symbol, 10), + (6, .symbol, 10), + (10, .symbol, 10), + (15, .symbol, 10), + (24, .symbol, 10), + (31, .symbol, 10), + (41, .symbol, 10), + (56, [.accepted, .symbol], 10), + (3, .symbol, 13), + (6, .symbol, 13), + (10, .symbol, 13), + (15, .symbol, 13), + (24, .symbol, 13), + (31, .symbol, 13), + (41, .symbol, 13), + (56, [.accepted, .symbol], 13), + + /* 255 */ + + (3, .symbol, 22), + (6, .symbol, 22), + (10, .symbol, 22), + (15, .symbol, 22), + (24, .symbol, 22), + (31, .symbol, 22), + (41, .symbol, 22), + (56, [.accepted, .symbol], 22), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + (0, .failure, 0), + ] + */ +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IndexedHeaderTable.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IndexedHeaderTable.swift new file mode 100644 index 00000000..10069cb0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IndexedHeaderTable.swift @@ -0,0 +1,199 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// The unified header table used by HTTP/2, encompassing both static and dynamic tables. +public struct IndexedHeaderTable { + // private but tests + @usableFromInline + let staticTable: HeaderTableStorage + @usableFromInline + var dynamicTable: DynamicHeaderTable + + // TODO(cory): This property should be removed, we only keep it for use in headerViews(at:). + private var allocator: ByteBufferAllocator + + /// Creates a new header table, optionally specifying a maximum size for the dynamic + /// portion of the table. + /// + /// - Parameter maxDynamicTableSize: Maximum size of the dynamic table. Default = 4096. + init(allocator: ByteBufferAllocator, maxDynamicTableSize: Int = DynamicHeaderTable.defaultSize) { + self.staticTable = HeaderTableStorage(staticHeaderList: StaticHeaderTable) + self.dynamicTable = DynamicHeaderTable(maximumLength: maxDynamicTableSize) + self.allocator = allocator + } + + /// Obtains the header key/value pair at the given index within the table. + /// + /// - note: Per RFC 7541, this uses a *1-based* index. + /// - Parameter index: The index to query. + /// - Returns: A tuple containing the name and value of the stored header. + /// - Throws: `NIOHPACKErrors.InvalidHeaderIndex` if the supplied index was invalid. + public func header(at index: Int) throws -> (name: String, value: String) { + let result: HeaderTableEntry + if index < self.staticTable.count { + result = self.staticTable[index] + } else if index - self.staticTable.count < self.dynamicTable.count { + result = self.dynamicTable[index - self.staticTable.count] + } else { + throw NIOHPACKErrors.InvalidHeaderIndex(suppliedIndex: index, availableIndex: self.staticTable.count + self.dynamicTable.count - 1) + } + + return (name: result.name, value: result.value) + } + + /// Obtains the header key/value pair at the given index within the table as sequences of + /// raw bytes. + /// + /// Now deprecated in favour of the method that uses Strings to avoid allocations. + /// + /// - note: Per RFC 7541, this uses a *1-based* index. + /// - Parameter index: The index to query. + /// - Returns: A tuple containing the name and value of the stored header. + /// - Throws: `NIOHPACKErrors.InvalidHeaderIndex` if the supplied index was invalid. + @available(*, deprecated, renamed: "header(at:)") + public func headerViews(at index: Int) throws -> (name: ByteBufferView, value: ByteBufferView) { + let (name, value) = try self.header(at: index) + + var nameBuffer = self.allocator.buffer(capacity: name.utf8.count) + var valueBuffer = self.allocator.buffer(capacity: value.utf8.count) + nameBuffer.writeString(name) + valueBuffer.writeString(value) + + return (nameBuffer.readableBytesView, valueBuffer.readableBytesView) + } + + /// Searches the table to locate an existing header with the given name and value. If + /// no item exists that contains a matching value, it will return the index of the first + /// item with a matching header name instead, to be encoded as index+value. + /// + /// - Parameters: + /// - name: The name of the header to locate. + /// - value: The value for which to search. + /// - Returns: A tuple containing the index of any located header, and a boolean indicating + /// whether the item at that index also contains a matching value. Returns `nil` + /// if no match could be found. + public func firstHeaderMatch(for name: String, value: String?) -> (index: Int, matchesValue: Bool)? { + var firstHeaderIndex: Int? = nil + + if let value = value { + // We've been asked to find a full match if we can. Begin by searching the static table. If we + // find a full match there, great, otherwise we only have a partial result and need to search + // the dynamic table too. + switch self.staticTable.closestMatch(name: name, value: value) { + case .full(let index): + return (index, true) + case .partial(let index): + firstHeaderIndex = index + case .none: + break + } + } else { + // We have not been asked for a full match. Search only the names of the static table. If we + // find one, we're done. + if let index = self.staticTable.firstIndex(matching: name) { + return (index, false) + } + } + + // no complete match: search the dynamic table now + if let result = self.dynamicTable.findExistingHeader(named: name, value: value) { + if let staticIndex = firstHeaderIndex, result.containsValue == false { + // Dynamic table can't match the value, and we have a name match in the static + // table. In this case, we prefer the static table. + return (staticIndex, false) + } else { + // Either no match in the static table, or the dynamic table has a header with + // a matching value. Return that, but update the index appropriately. + return (result.index + StaticHeaderTable.count, result.containsValue) + } + } else if let staticIndex = firstHeaderIndex { + // nothing in the dynamic table, but the static table had a name match + return (staticIndex, false) + } else { + // no match anywhere, you'll have to encode the whole thing + return nil + } + } + + /// Appends a header to the table. + /// + /// This call may result in an empty table, as per RFC 7541 § 4.4: + /// > "It is not an error to attempt to add an entry that is larger than the maximum size; + /// > an attempt to add an entry larger than the maximum size causes the table to be + /// > emptied of all existing entries and results in an empty table." + /// + /// - Parameters: + /// - name: The name of the header to insert. + /// - value: The value of the header to insert. + /// - Returns: `true` if the header was added to the table, `false` if not. + public mutating func add(headerNamed name: String, value: String) throws { + // This function is unnecessarily marked throws, but none of its underlying functions throw anymore. + self.dynamicTable.addHeader(named: name, value: value) + } + + /// Appends a header to the table. + /// + /// This call may result in an empty table, as per RFC 7541 § 4.4: + /// > "It is not an error to attempt to add an entry that is larger than the maximum size; + /// > an attempt to add an entry larger than the maximum size causes the table to be + /// > emptied of all existing entries and results in an empty table." + /// + /// This method is deprecated in favour of the version that takes Strings, as that version performs + /// better. + /// + /// - Parameters: + /// - name: A sequence of contiguous bytes containing the name of the header to insert. + /// - value: A sequence of contiguous bytes containing the value of the header to insert. + @available(*, deprecated, renamed: "add(headerNamed:value:)") + public mutating func add(headerNamed name: Name, value: Value) throws where Name.Element == UInt8, Value.Element == UInt8 { + let nameString = String(decoding: name, as: UTF8.self) + let valueString = String(decoding: value, as: UTF8.self) + + try self.add(headerNamed: nameString, value: valueString) + } + + /// Internal for test access. + internal func dumpHeaders() -> String { + return "\(staticTable.dumpHeaders())\n\(dynamicTable.dumpHeaders())" + } + + /// The length, in bytes, of the dynamic portion of the header table. + public var dynamicTableLength: Int { + return self.dynamicTable.length + } + + /// The current allowed length of the dynamic portion of the header table. May be + /// less than the current protocol-assigned maximum supplied by a SETTINGS frame. + public var dynamicTableAllowedLength: Int { + get { return self.dynamicTable.allowedLength } + set { self.dynamicTable.allowedLength = newValue } + } + + /// The hard limit on the size to which the dynamic table may grow. Only a SETTINGS + /// frame can change this: it can't grow beyond this size due to changes within + /// header blocks. + public var maxDynamicTableLength: Int { + get { return self.dynamicTable.maximumTableLength } + set { self.dynamicTable.maximumTableLength = newValue } + } +} + +// The `@unchecked` is needed because at the time of writing `NIOCore` didn't have `Sendable` support. +#if swift(>=5.5) && canImport(_Concurrency) +extension IndexedHeaderTable: @unchecked Sendable { + +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IntegerCoding.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IntegerCoding.swift new file mode 100644 index 00000000..222f49e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/IntegerCoding.swift @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/* private but tests */ +/// Encodes an integer value into a provided memory location. +/// +/// - Parameters: +/// - value: The integer value to encode. +/// - buffer: The location at which to begin encoding. +/// - prefix: The number of bits available for use in the first byte at `buffer`. +/// - prefixBits: Existing bits to place in that first byte of `buffer` before encoding `value`. +/// - Returns: Returns the number of bytes used to encode the integer. +@discardableResult +func encodeInteger(_ value: UInt, to buffer: inout ByteBuffer, + prefix: Int, prefixBits: UInt8 = 0) -> Int { + assert(prefix <= 8) + assert(prefix >= 1) + + let start = buffer.writerIndex + + // The prefix is always hard-coded, and must fit within 8, so unchecked math here is definitely safe. + let k = (1 &<< prefix) &- 1 + var initialByte = prefixBits + + if value < k { + // it fits already! + initialByte |= UInt8(truncatingIfNeeded: value) + buffer.writeInteger(initialByte) + return 1 + } + + // if it won't fit in this byte altogether, fill in all the remaining bits and move + // to the next byte. + initialByte |= UInt8(truncatingIfNeeded: k) + buffer.writeInteger(initialByte) + + // deduct the initial [prefix] bits from the value, then encode it seven bits at a time into + // the remaining bytes. + // We can safely use unchecked subtraction here: we know that `k` is zero or greater, and that `value` is + // either the same value or greater. As a result, this can be unchecked: it's always safe. + var n = value &- UInt(k) + while n >= 128 { + let nextByte = (1 << 7) | UInt8(truncatingIfNeeded: n & 0x7f) + buffer.writeInteger(nextByte) + n >>= 7 + } + + buffer.writeInteger(UInt8(truncatingIfNeeded: n)) + return buffer.writerIndex &- start +} + +fileprivate let valueMask: UInt8 = 127 +fileprivate let continuationMask: UInt8 = 128 + +/* private but tests */ +struct DecodedInteger { + var value: Int + var bytesRead: Int +} + +/* private but tests */ +func decodeInteger(from bytes: ByteBufferView, prefix: Int) throws -> DecodedInteger { + precondition((1...8).contains(prefix)) + if bytes.isEmpty { + throw NIOHPACKErrors.InsufficientInput() + } + + // See RFC 7541 § 5.1 for details of the encoding/decoding. + + var index = bytes.startIndex + // The shifting and arithmetic operate on 'Int' and prefix is 1...8, so these unchecked operations are + // fine and the result must fit in a UInt8. + let prefixMask = UInt8(truncatingIfNeeded: (1 &<< prefix) &- 1) + let prefixBits = bytes[index] & prefixMask + + if prefixBits != prefixMask { + // The prefix bits aren't all '1', so they represent the whole value, we're done. + return DecodedInteger(value: Int(prefixBits), bytesRead: 1) + } + + var accumulator = Int(prefixMask) + bytes.formIndex(after: &index) + + // for the remaining bytes, as long as the top bit is set, consume the low seven bits. + var shift: Int = 0 + var byte: UInt8 = 0 + + repeat { + if index == bytes.endIndex { + throw NIOHPACKErrors.InsufficientInput() + } + + byte = bytes[index] + + let value = Int(byte & valueMask) + + // The shift cannot overflow: the value of 'shift' is strictly less than 'Int.bitWidth'. + let (multiplicationResult, multiplicationOverflowed) = value.multipliedReportingOverflow(by: (1 &<< shift)) + if multiplicationOverflowed { + throw NIOHPACKErrors.UnrepresentableInteger() + } + + let (additionResult, additionOverflowed) = accumulator.addingReportingOverflow(multiplicationResult) + if additionOverflowed { + throw NIOHPACKErrors.UnrepresentableInteger() + } + + accumulator = additionResult + + // Unchecked is fine, there's no chance of it overflowing given the possible values of 'Int.bitWidth'. + shift &+= 7 + if shift >= Int.bitWidth { + throw NIOHPACKErrors.UnrepresentableInteger() + } + + bytes.formIndex(after: &index) + } while byte & continuationMask == continuationMask + + return DecodedInteger(value: accumulator, bytesRead: bytes.distance(from: bytes.startIndex, to: index)) +} + +extension ByteBuffer { + mutating func readEncodedInteger(withPrefix prefix: Int) throws -> Int { + let result = try decodeInteger(from: self.readableBytesView, prefix: prefix) + self.moveReaderIndex(forwardBy: result.bytesRead) + return result.value + } + + mutating func write(encodedInteger value: UInt, prefix: Int = 0, prefixBits: UInt8 = 0) { + encodeInteger(value, to: &self, prefix: prefix, prefixBits: prefixBits) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/StaticHeaderTable.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/StaticHeaderTable.swift new file mode 100644 index 00000000..fa216edf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHPACK/Sources/NIOHPACK/StaticHeaderTable.swift @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +internal let StaticHeaderTable: [(String, String)] = [ + ("", ""), // real indexing begins at 1 + (":authority", ""), + (":method", "GET"), + (":method", "POST"), + (":path", "/"), + (":path", "/index.html"), + (":scheme", "http"), + (":scheme", "https"), + (":status", "200"), + (":status", "204"), + (":status", "206"), + (":status", "304"), + (":status", "400"), + (":status", "404"), + (":status", "500"), + ("accept-charset", ""), + ("accept-encoding", "gzip, deflate"), + ("accept-language", ""), + ("accept-ranges", ""), + ("accept", ""), + ("access-control-allow-origin", ""), + ("age", ""), + ("allow", ""), + ("authorization", ""), + ("cache-control", ""), + ("content-disposition", ""), + ("content-encoding", ""), + ("content-language", ""), + ("content-length", ""), + ("content-location", ""), + ("content-range", ""), + ("content-type", ""), + ("cookie", ""), + ("date", ""), + ("etag", ""), + ("expect", ""), + ("expires", ""), + ("from", ""), + ("host", ""), + ("if-match", ""), + ("if-modified-since", ""), + ("if-none-match", ""), + ("if-range", ""), + ("if-unmodified-since", ""), + ("last-modified", ""), + ("link", ""), + ("location", ""), + ("max-forwards", ""), + ("proxy-authenticate", ""), + ("proxy-authorization", ""), + ("range", ""), + ("referer", ""), + ("refresh", ""), + ("retry-after", ""), + ("server", ""), + ("set-cookie", ""), + ("strict-transport-security", ""), + ("transfer-encoding", ""), + ("user-agent", ""), + ("vary", ""), + ("via", ""), + ("www-authenticate", "") +] diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/ByteCollectionUtils.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/ByteCollectionUtils.swift new file mode 100644 index 00000000..75ee72d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/ByteCollectionUtils.swift @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +fileprivate let defaultWhitespaces = [" ", "\t"].map({$0.utf8.first!}) + +extension ByteBufferView { + internal func trim(limitingElements: [UInt8]) -> ByteBufferView { + guard let lastNonWhitespaceIndex = self.lastIndex(where: { !limitingElements.contains($0) }), + let firstNonWhitespaceIndex = self.firstIndex(where: { !limitingElements.contains($0) }) else { + // This buffer is entirely trimmed elements, so trim it to nothing. + return self[self.startIndex.. ByteBufferView { + return trim(limitingElements: defaultWhitespaces) + } +} + +extension Sequence where Self.Element == UInt8 { + /// Compares the collection of `UInt8`s to a case insensitive collection. + /// + /// This collection could be get from applying the `UTF8View` + /// property on the string protocol. + /// + /// - Parameter bytes: The string constant in the form of a collection of `UInt8` + /// - Returns: Whether the collection contains **EXACTLY** this array or no, but by ignoring case. + internal func compareCaseInsensitiveASCIIBytes(to: T) -> Bool + where T.Element == UInt8 { + // fast path: we can get the underlying bytes of both + let maybeMaybeResult = self.withContiguousStorageIfAvailable { lhsBuffer -> Bool? in + to.withContiguousStorageIfAvailable { rhsBuffer in + if lhsBuffer.count != rhsBuffer.count { + return false + } + + for idx in 0 ..< lhsBuffer.count { + // let's hope this gets vectorised ;) + if lhsBuffer[idx] & 0xdf != rhsBuffer[idx] & 0xdf { + return false + } + } + return true + } + } + + if let maybeResult = maybeMaybeResult, let result = maybeResult { + return result + } else { + return self.elementsEqual(to, by: {return ($0 & 0xdf) == ($1 & 0xdf)}) + } + } +} + +extension String { + internal func isEqualCaseInsensitiveASCIIBytes(to: String) -> Bool { + return self.utf8.compareCaseInsensitiveASCIIBytes(to: to.utf8) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPDecoder.swift new file mode 100644 index 00000000..9cbd9f90 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPDecoder.swift @@ -0,0 +1,912 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +#if compiler(>=5.1) +@_implementationOnly import CNIOHTTPParser +#else +import CNIOHTTPParser +#endif + +private extension UnsafeMutablePointer where Pointee == http_parser { + /// Returns the `KeepAliveState` for the current message that is parsed. + var keepAliveState: KeepAliveState { + return c_nio_http_should_keep_alive(self) == 0 ? .close : .keepAlive + } +} + +private enum HTTPDecodingState { + case beforeMessageBegin + case afterMessageBegin + case url + case headerName + case headerValue + case trailerName + case trailerValue + case headersComplete +} + +private class BetterHTTPParser { + var delegate: HTTPDecoderDelegate! = nil + private var parser: http_parser? = http_parser() // nil if unaccessible because reference passed away exclusively + private var settings = http_parser_settings() + private var decodingState: HTTPDecodingState = .beforeMessageBegin + private var firstNonDiscardableOffset: Int? = nil + private var currentFieldByteLength = 0 + private var httpParserOffset = 0 + private var rawBytesView: UnsafeRawBufferPointer = .init(start: UnsafeRawPointer(bitPattern: 0xcafbabe), count: 0) + private var httpErrno: http_errno? = nil + private var richerError: Error? = nil + private let kind: HTTPDecoderKind + var requestHeads = CircularBuffer(initialCapacity: 1) + + enum MessageContinuation { + case normal + case skipBody + case error(http_errno) + } + + private static func fromOpaque(_ opaque: UnsafePointer?) -> BetterHTTPParser { + return Unmanaged.fromOpaque(UnsafeRawPointer(opaque!.pointee.data)).takeUnretainedValue() + } + + init(kind: HTTPDecoderKind) { + self.kind = kind + c_nio_http_parser_settings_init(&self.settings) + self.withExclusiveHTTPParser { parserPtr in + switch kind { + case .request: + c_nio_http_parser_init(parserPtr, HTTP_REQUEST) + case .response: + c_nio_http_parser_init(parserPtr, HTTP_RESPONSE) + } + } + self.settings.on_body = { opaque, bytes, len in + BetterHTTPParser.fromOpaque(opaque).didReceiveBodyData(UnsafeRawBufferPointer(start: bytes, count: len)) + return 0 + } + self.settings.on_header_field = { opaque, bytes, len in + BetterHTTPParser.fromOpaque(opaque).didReceiveHeaderFieldData(UnsafeRawBufferPointer(start: bytes, count: len)) + return 0 + } + self.settings.on_header_value = { opaque, bytes, len in + BetterHTTPParser.fromOpaque(opaque).didReceiveHeaderValueData(UnsafeRawBufferPointer(start: bytes, count: len)) + return 0 + } + self.settings.on_status = { opaque, bytes, len in + BetterHTTPParser.fromOpaque(opaque).didReceiveStatusData(UnsafeRawBufferPointer(start: bytes, count: len)) + return 0 + } + self.settings.on_url = { opaque, bytes, len in + BetterHTTPParser.fromOpaque(opaque).didReceiveURLData(UnsafeRawBufferPointer(start: bytes, count: len)) + return 0 + } + self.settings.on_chunk_complete = { opaque in + BetterHTTPParser.fromOpaque(opaque).didReceiveChunkCompleteNotification() + return 0 + } + self.settings.on_chunk_header = { opaque in + BetterHTTPParser.fromOpaque(opaque).didReceiveChunkHeaderNotification() + return 0 + } + self.settings.on_message_begin = { opaque in + BetterHTTPParser.fromOpaque(opaque).didReceiveMessageBeginNotification() + return 0 + } + self.settings.on_headers_complete = { opaque in + let parser = BetterHTTPParser.fromOpaque(opaque) + switch parser.didReceiveHeadersCompleteNotification(versionMajor: Int(opaque!.pointee.http_major), + versionMinor: Int(opaque!.pointee.http_minor), + statusCode: Int(opaque!.pointee.status_code), + isUpgrade: opaque!.pointee.upgrade != 0, + method: http_method(rawValue: opaque!.pointee.method), + keepAliveState: opaque!.keepAliveState) { + case .normal: + return 0 + case .skipBody: + return 1 + case .error(let err): + parser.httpErrno = err + return -1 // error + } + } + self.settings.on_message_complete = { opaque in + BetterHTTPParser.fromOpaque(opaque).didReceiveMessageCompleteNotification() + return 0 + } + } + + private func start(bytes: UnsafeRawBufferPointer, newState: HTTPDecodingState) { + assert(self.firstNonDiscardableOffset == nil) + self.firstNonDiscardableOffset = bytes.baseAddress! - self.rawBytesView.baseAddress! + self.decodingState = newState + } + + private func finish(_ callout: (inout HTTPDecoderDelegate, UnsafeRawBufferPointer) -> Void) { + var currentFieldByteLength = 0 + swap(¤tFieldByteLength, &self.currentFieldByteLength) + let start = self.rawBytesView.startIndex + self.firstNonDiscardableOffset! + let end = start + currentFieldByteLength + self.firstNonDiscardableOffset = nil + precondition(start >= self.rawBytesView.startIndex && end <= self.rawBytesView.endIndex) + callout(&self.delegate, .init(rebasing: self.rawBytesView[start ..< end])) + } + + private func didReceiveBodyData(_ bytes: UnsafeRawBufferPointer) { + self.delegate.didReceiveBody(bytes) + } + + private func didReceiveHeaderFieldData(_ bytes: UnsafeRawBufferPointer) { + switch self.decodingState { + case .headerName, .trailerName: + () + case .headerValue: + self.finish { delegate, bytes in + delegate.didReceiveHeaderValue(bytes) + } + self.start(bytes: bytes, newState: .headerName) + case .trailerValue: + self.finish { delegate, bytes in + delegate.didReceiveTrailerValue(bytes) + } + self.start(bytes: bytes, newState: .trailerName) + case .url: + self.finish { delegate, bytes in + delegate.didReceiveURL(bytes) + } + self.start(bytes: bytes, newState: .headerName) + case .headersComplete: + // these are trailers + self.start(bytes: bytes, newState: .trailerName) + case .afterMessageBegin: + // in case we're parsing responses + self.start(bytes: bytes, newState: .headerName) + case .beforeMessageBegin: + preconditionFailure() + } + self.currentFieldByteLength += bytes.count + } + + private func didReceiveHeaderValueData(_ bytes: UnsafeRawBufferPointer) { + switch self.decodingState { + case .headerValue, .trailerValue: + () + case .headerName: + self.finish { delegate, bytes in + delegate.didReceiveHeaderName(bytes) + } + self.start(bytes: bytes, newState: .headerValue) + case .trailerName: + self.finish { delegate, bytes in + delegate.didReceiveTrailerName(bytes) + } + self.start(bytes: bytes, newState: .trailerValue) + case .beforeMessageBegin, .afterMessageBegin, .headersComplete, .url: + preconditionFailure() + } + self.currentFieldByteLength += bytes.count + } + + private func didReceiveStatusData(_ bytes: UnsafeRawBufferPointer) { + // we don't do anything special here because we'll need the whole 'head' anyway + } + + private func didReceiveURLData(_ bytes: UnsafeRawBufferPointer) { + switch self.decodingState { + case .url: + () + case .afterMessageBegin: + self.start(bytes: bytes, newState: .url) + case .beforeMessageBegin, .headersComplete, .headerName, .headerValue, .trailerName, .trailerValue: + preconditionFailure() + } + self.currentFieldByteLength += bytes.count + } + + private func didReceiveChunkCompleteNotification() { + // nothing special to do, we handle chunks just like any other body part + } + + private func didReceiveChunkHeaderNotification() { + // nothing special to do, we handle chunks just like any other body part + } + + private func didReceiveMessageBeginNotification() { + switch self.decodingState { + case .beforeMessageBegin: + self.decodingState = .afterMessageBegin + case .headersComplete, .headerName, .headerValue, .trailerName, .trailerValue, .afterMessageBegin, .url: + preconditionFailure() + } + } + + private func didReceiveMessageCompleteNotification() { + switch self.decodingState { + case .headersComplete: + () + case .trailerValue: + self.finish { delegate, bytes in + delegate.didReceiveTrailerValue(bytes) + } + case .beforeMessageBegin, .headerName, .headerValue, .trailerName, .afterMessageBegin, .url: + preconditionFailure() + } + self.decodingState = .beforeMessageBegin + self.delegate.didFinishMessage() + } + + private func didReceiveHeadersCompleteNotification(versionMajor: Int, + versionMinor: Int, + statusCode: Int, + isUpgrade: Bool, + method: http_method, + keepAliveState: KeepAliveState) -> MessageContinuation { + switch self.decodingState { + case .headerValue: + self.finish { delegate, bytes in + delegate.didReceiveHeaderValue(bytes) + } + case .url: + self.finish { delegate, bytes in + delegate.didReceiveURL(bytes) + } + case .afterMessageBegin: + // we're okay here for responses (as they don't have URLs) but for requests we must have seen a URL/headers + precondition(self.kind == .response) + case .beforeMessageBegin, .headersComplete, .headerName, .trailerName, .trailerValue: + preconditionFailure() + } + assert(self.firstNonDiscardableOffset == nil) + self.decodingState = .headersComplete + + var skipBody = false + + if self.kind == .response { + // http_parser doesn't correctly handle responses to HEAD requests. We have to do something + // annoyingly opaque here, and in those cases return 1 instead of 0. This forces http_parser + // to not expect a request body. + // + // The same logic applies to CONNECT: RFC 7230 says that regardless of what the headers say, + // responses to CONNECT never have HTTP-level bodies. + // + // Finally, we need to work around a bug in http_parser for 1XX, 204, and 304 responses. + // RFC 7230 says: + // + // > ... any response with a 1xx (Informational), + // > 204 (No Content), or 304 (Not Modified) status + // > code is always terminated by the first empty line after the + // > header fields, regardless of the header fields present in the + // > message, and thus cannot contain a message body. + // + // However, http_parser only does this for responses that do not contain length fields. That + // does not meet the requirement of RFC 7230. This is an outstanding http_parser issue: + // https://github.com/nodejs/http-parser/issues/251. As a result, we check for these status + // codes and override http_parser's handling as well. + guard !self.requestHeads.isEmpty else { + self.richerError = NIOHTTPDecoderError.unsolicitedResponse + return .error(HPE_UNKNOWN) + } + + if 100 <= statusCode && statusCode < 200 && statusCode != 101 { + // if the response status is in the range of 100..<200 but not 101 we don't want to + // pop the request method. The actual request head is expected with the next HTTP + // head. + skipBody = true + } else { + let method = self.requestHeads.removeFirst().method + if method == .HEAD || method == .CONNECT { + skipBody = true + } else if statusCode / 100 == 1 || // 1XX codes + statusCode == 204 || statusCode == 304 { + skipBody = true + } + } + } + + let success = self.delegate.didFinishHead(versionMajor: versionMajor, + versionMinor: versionMinor, + isUpgrade: isUpgrade, + method: method, + statusCode: statusCode, + keepAliveState: keepAliveState) + guard success else { + return .error(HPE_INVALID_VERSION) + } + + return skipBody ? .skipBody : .normal + } + + func start() { + self.withExclusiveHTTPParser { parserPtr in + parserPtr.pointee.data = Unmanaged.passRetained(self).toOpaque() + } + } + + func stop() { + self.withExclusiveHTTPParser { parserPtr in + let selfRef = parserPtr.pointee.data + Unmanaged.fromOpaque(selfRef!).release() + parserPtr.pointee.data = UnsafeMutableRawPointer(bitPattern: 0xdedbeef) + } + } + + @inline(__always) // this need to be optimised away + func withExclusiveHTTPParser(_ body: (UnsafeMutablePointer) -> T) -> T { + var parser: http_parser? = nil + assert(self.parser != nil, "parser must not be nil here, must be a re-entrancy issue") + swap(&parser, &self.parser) + defer { + assert(self.parser == nil, "parser must not nil here") + swap(&parser, &self.parser) + } + return body(&parser!) + } + + func feedInput(_ bytes: UnsafeRawBufferPointer?) throws -> Int { + var parserErrno: UInt32 = 0 + let parserConsumed = self.withExclusiveHTTPParser { parserPtr -> Int in + let parserResult: Int + if let bytes = bytes { + self.rawBytesView = bytes + defer { + self.rawBytesView = .init(start: UnsafeRawPointer(bitPattern: 0xdafbabe), count: 0) + } + parserResult = c_nio_http_parser_execute_swift(parserPtr, + &self.settings, + bytes.baseAddress! + self.httpParserOffset, + bytes.count - self.httpParserOffset) + } else { + parserResult = c_nio_http_parser_execute(parserPtr, &self.settings, nil, 0) + } + parserErrno = parserPtr.pointee.http_errno + return parserResult + } + assert(parserConsumed >= 0) + // self.parser must be non-nil here because we can't be re-entered here (ByteToMessageDecoder guarantee) + guard parserErrno == 0 else { + // if we chose to abort (eg. wrong HTTP version) the error will be in self.httpErrno, otherwise http_parser + // will tell us... + // self.parser must be non-nil here because we can't be re-entered here (ByteToMessageDecoder guarantee) + // If we have a richer error than the errno code, and the errno is unknown, we'll use it. Otherwise, we use the + // error from http_parser. + let err = self.httpErrno ?? http_errno(rawValue: parserErrno) + if err == HPE_UNKNOWN, let richerError = self.richerError { + throw richerError + } else { + throw HTTPParserError.httpError(fromCHTTPParserErrno: err)! + } + } + if let firstNonDiscardableOffset = self.firstNonDiscardableOffset { + self.httpParserOffset += parserConsumed - firstNonDiscardableOffset + self.firstNonDiscardableOffset = 0 + return firstNonDiscardableOffset + } else { + // By definition we've consumed all of the http parser offset at this stage. There may still be bytes + // left in the buffer though: we didn't consume them because they aren't ours to consume, as they may belong + // to an upgraded protocol. + // + // Set the HTTP parser offset back to zero, and tell the parent that we consumed + // the whole buffer. + let consumedBytes = self.httpParserOffset + parserConsumed + self.httpParserOffset = 0 + return consumedBytes + } + } +} + +private protocol HTTPDecoderDelegate { + mutating func didReceiveBody(_ bytes: UnsafeRawBufferPointer) + mutating func didReceiveHeaderName(_ bytes: UnsafeRawBufferPointer) + mutating func didReceiveHeaderValue(_ bytes: UnsafeRawBufferPointer) + mutating func didReceiveTrailerName(_ bytes: UnsafeRawBufferPointer) + mutating func didReceiveTrailerValue(_ bytes: UnsafeRawBufferPointer) + mutating func didReceiveURL(_ bytes: UnsafeRawBufferPointer) + mutating func didFinishHead(versionMajor: Int, + versionMinor: Int, + isUpgrade: Bool, + method: http_method, + statusCode: Int, + keepAliveState: KeepAliveState) -> Bool + mutating func didFinishMessage() +} + +/// A `ByteToMessageDecoder` used to decode HTTP/1.x responses. See the documentation +/// on `HTTPDecoder` for more. +/// +/// The `HTTPResponseDecoder` must be placed later in the channel pipeline than the `HTTPRequestEncoder`, +/// as it needs to see the outbound messages in order to keep track of what the HTTP request methods +/// were for accurate decoding. +/// +/// Rather than set this up manually, consider using `ChannelPipeline.addHTTPClientHandlers`. +public typealias HTTPResponseDecoder = HTTPDecoder + +/// A `ByteToMessageDecoder` used to decode HTTP requests. See the documentation +/// on `HTTPDecoder` for more. +/// +/// While the `HTTPRequestDecoder` does not currently have a specific ordering requirement in the +/// `ChannelPipeline` (unlike `HTTPResponseDecoder`), it is possible that it will develop one. For +/// that reason, applications should try to ensure that the `HTTPRequestDecoder` *later* in the +/// `ChannelPipeline` than the `HTTPResponseEncoder`. +/// +/// Rather than set this up manually, consider using `ChannelPipeline.configureHTTPServerPipeline`. +public typealias HTTPRequestDecoder = HTTPDecoder + +public enum HTTPDecoderKind { + case request + case response +} + +extension HTTPDecoder: WriteObservingByteToMessageDecoder where In == HTTPClientResponsePart, Out == HTTPClientRequestPart { + public typealias OutboundIn = Out + + public func write(data: HTTPClientRequestPart) { + if case .head(let head) = data { + self.parser.requestHeads.append(head) + } + } +} + +/// A `ChannelInboundHandler` that parses HTTP/1-style messages, converting them from +/// unstructured bytes to a sequence of HTTP messages. +/// +/// The `HTTPDecoder` is a generic channel handler which can produce messages in +/// either the form of `HTTPClientResponsePart` or `HTTPServerRequestPart`: that is, +/// it produces messages that correspond to the semantic units of HTTP produced by +/// the remote peer. +public final class HTTPDecoder: ByteToMessageDecoder, HTTPDecoderDelegate { + public typealias InboundOut = In + + // things we build incrementally + private var headers: [(String, String)] = [] + private var trailers: [(String, String)]? = nil + private var currentHeaderName: String? = nil + private var url: String? = nil + private var isUpgrade: Bool? = nil + + // temporary, set and unset by `feedInput` + private var buffer: ByteBuffer? = nil + private var context: ChannelHandlerContext? = nil + + // the actual state + private let parser: BetterHTTPParser + private let leftOverBytesStrategy: RemoveAfterUpgradeStrategy + private let informationalResponseStrategy: NIOInformationalResponseStrategy + private let kind: HTTPDecoderKind + private var stopParsing = false // set on upgrade or HTTP version error + private var lastResponseHeaderWasInformational = false + + /// Creates a new instance of `HTTPDecoder`. + /// + /// - parameters: + /// - leftOverBytesStrategy: The strategy to use when removing the decoder from the pipeline and an upgrade was, + /// detected. Note that this does not affect what happens on EOF. + public convenience init(leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes) { + self.init(leftOverBytesStrategy: leftOverBytesStrategy, informationalResponseStrategy: .drop) + } + + /// Creates a new instance of `HTTPDecoder`. + /// + /// - parameters: + /// - leftOverBytesStrategy: The strategy to use when removing the decoder from the pipeline and an upgrade was, + /// detected. Note that this does not affect what happens on EOF. + /// - informationalResponseStrategy: Should informational responses (like http status 100) be forwarded or dropped. + /// Default is `.drop`. This property is only respected when decoding responses. + public init(leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes, informationalResponseStrategy: NIOInformationalResponseStrategy = .drop) { + self.headers.reserveCapacity(16) + if In.self == HTTPServerRequestPart.self { + self.kind = .request + } else if In.self == HTTPClientResponsePart.self { + self.kind = .response + } else { + preconditionFailure("unknown HTTP message type \(In.self)") + } + self.parser = BetterHTTPParser(kind: kind) + self.leftOverBytesStrategy = leftOverBytesStrategy + self.informationalResponseStrategy = informationalResponseStrategy + } + + func didReceiveBody(_ bytes: UnsafeRawBufferPointer) { + let offset = self.buffer!.withUnsafeReadableBytes { allBytes -> Int in + let offset = bytes.baseAddress! - allBytes.baseAddress! + assert(offset >= 0) + assert(offset + bytes.count <= allBytes.count) + return offset + } + self.buffer!.moveReaderIndex(forwardBy: offset) + switch self.kind { + case .request: + self.context!.fireChannelRead(NIOAny(HTTPServerRequestPart.body(self.buffer!.readSlice(length: bytes.count)!))) + case .response: + self.context!.fireChannelRead(NIOAny(HTTPClientResponsePart.body(self.buffer!.readSlice(length: bytes.count)!))) + } + + } + + func didReceiveHeaderName(_ bytes: UnsafeRawBufferPointer) { + assert(self.currentHeaderName == nil) + self.currentHeaderName = String(decoding: bytes, as: Unicode.UTF8.self) + } + + func didReceiveHeaderValue(_ bytes: UnsafeRawBufferPointer) { + self.headers.append((self.currentHeaderName!, String(decoding: bytes, as: Unicode.UTF8.self))) + self.currentHeaderName = nil + } + + func didReceiveTrailerName(_ bytes: UnsafeRawBufferPointer) { + assert(self.currentHeaderName == nil) + self.currentHeaderName = String(decoding: bytes, as: Unicode.UTF8.self) + } + + func didReceiveTrailerValue(_ bytes: UnsafeRawBufferPointer) { + if self.trailers == nil { + self.trailers = [] + } + self.trailers?.append((self.currentHeaderName!, String(decoding: bytes, as: Unicode.UTF8.self))) + self.currentHeaderName = nil + } + + func didReceiveURL(_ bytes: UnsafeRawBufferPointer) { + assert(self.url == nil) + self.url = String(decoding: bytes, as: Unicode.UTF8.self) + } + + func didFinishHead(versionMajor: Int, + versionMinor: Int, + isUpgrade: Bool, + method: http_method, + statusCode: Int, + keepAliveState: KeepAliveState) -> Bool { + let message: NIOAny? + + guard versionMajor == 1 else { + self.stopParsing = true + self.context!.fireErrorCaught(HTTPParserError.invalidVersion) + return false + } + + switch self.kind { + case .request: + let reqHead = HTTPRequestHead(version: .init(major: versionMajor, minor: versionMinor), + method: HTTPMethod.from(httpParserMethod: method), + uri: self.url!, + headers: HTTPHeaders(self.headers, + keepAliveState: keepAliveState)) + message = NIOAny(HTTPServerRequestPart.head(reqHead)) + + case .response where (100..<200).contains(statusCode) && statusCode != 101: + self.lastResponseHeaderWasInformational = true + switch self.informationalResponseStrategy.base { + case .forward: + let resHeadPart = HTTPClientResponsePart.head( + versionMajor: versionMajor, + versionMinor: versionMinor, + statusCode: statusCode, + keepAliveState: keepAliveState, + headers: self.headers + ) + message = NIOAny(resHeadPart) + case .drop: + message = nil + } + + case .response: + self.lastResponseHeaderWasInformational = false + let resHeadPart = HTTPClientResponsePart.head( + versionMajor: versionMajor, + versionMinor: versionMinor, + statusCode: statusCode, + keepAliveState: keepAliveState, + headers: self.headers + ) + message = NIOAny(resHeadPart) + } + self.url = nil + self.headers.removeAll(keepingCapacity: true) + if let message = message { + self.context!.fireChannelRead(message) + } + self.isUpgrade = isUpgrade + return true + } + + func didFinishMessage() { + var trailers: [(String, String)]? = nil + swap(&trailers, &self.trailers) + switch self.kind { + case .request: + self.context!.fireChannelRead(NIOAny(HTTPServerRequestPart.end(trailers.map(HTTPHeaders.init)))) + case .response: + if !self.lastResponseHeaderWasInformational { + self.context!.fireChannelRead(NIOAny(HTTPClientResponsePart.end(trailers.map(HTTPHeaders.init)))) + } + } + self.stopParsing = self.isUpgrade! + self.isUpgrade = nil + } + + public func decoderAdded(context: ChannelHandlerContext) { + self.parser.delegate = self + self.parser.start() + } + + public func decoderRemoved(context: ChannelHandlerContext) { + self.parser.stop() + self.parser.delegate = nil + } + + private func feedEOF(context: ChannelHandlerContext) throws { + self.context = context + defer { + self.context = nil + } + // we don't care how much http_parser consumed here because we just fed an EOF so there won't be any more data. + _ = try self.parser.feedInput(nil) + } + + private func feedInput(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws { + self.buffer = buffer + self.context = context + defer { + self.buffer = nil + self.context = nil + } + let consumed = try buffer.withUnsafeReadableBytes { bytes -> Int in + try self.parser.feedInput(bytes) + } + buffer.moveReaderIndex(forwardBy: consumed) + } + + public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { + if !self.stopParsing { + try self.feedInput(context: context, buffer: &buffer) + } + return .needMoreData + } + + public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + if !self.stopParsing { + while buffer.readableBytes > 0, case .continue = try self.decode(context: context, buffer: &buffer) {} + if seenEOF { + try self.feedEOF(context: context) + } + } + if buffer.readableBytes > 0 && !seenEOF { + // We only do this if we haven't seen EOF because the left-overs strategy must only be invoked when we're + // sure that this is the completion of an upgrade. + switch self.leftOverBytesStrategy { + case .dropBytes: + () + case .fireError: + context.fireErrorCaught(ByteToMessageDecoderError.leftoverDataWhenDone(buffer)) + case .forwardBytes: + context.fireChannelRead(NIOAny(buffer)) + } + } + return .needMoreData + } +} + +/// Strategy to use when a HTTPDecoder is removed from a pipeline after a HTTP upgrade was detected. +public enum RemoveAfterUpgradeStrategy { + /// Forward all the remaining bytes that are currently buffered in the deccoder to the next handler in the pipeline. + case forwardBytes + /// Fires a `ByteToMessageDecoder.leftoverDataWhenDone` error through the pipeline + case fireError + /// Discard all the remaining bytes that are currently buffered in the decoder. + case dropBytes +} + +/// Strategy to use when a HTTPDecoder receives an informational HTTP response (1xx except 101) +public struct NIOInformationalResponseStrategy: Hashable { + enum Base { + case drop + case forward + } + + var base: Base + private init(_ base: Base) { + self.base = base + } + + /// Drop the informational response and only forward the "real" response + public static let drop = Self(.drop) + /// Forward the informational response and then forward the "real" response. This will result in + /// multiple `head` before an `end` is emitted. + public static let forward = Self(.forward) +} + +extension HTTPParserError { + /// Create a `HTTPParserError` from an error returned by `http_parser`. + /// + /// - Parameter fromCHTTPParserErrno: The error from the underlying library. + /// - Returns: The corresponding `HTTPParserError`, or `nil` if there is no + /// corresponding error. + static func httpError(fromCHTTPParserErrno: http_errno) -> HTTPParserError? { + switch fromCHTTPParserErrno { + case HPE_INVALID_EOF_STATE: + return .invalidEOFState + case HPE_HEADER_OVERFLOW: + return .headerOverflow + case HPE_CLOSED_CONNECTION: + return .closedConnection + case HPE_INVALID_VERSION: + return .invalidVersion + case HPE_INVALID_STATUS: + return .invalidStatus + case HPE_INVALID_METHOD: + return .invalidMethod + case HPE_INVALID_URL: + return .invalidURL + case HPE_INVALID_HOST: + return .invalidHost + case HPE_INVALID_PORT: + return .invalidPort + case HPE_INVALID_PATH: + return .invalidPath + case HPE_INVALID_QUERY_STRING: + return .invalidQueryString + case HPE_INVALID_FRAGMENT: + return .invalidFragment + case HPE_LF_EXPECTED: + return .lfExpected + case HPE_INVALID_HEADER_TOKEN: + return .invalidHeaderToken + case HPE_INVALID_CONTENT_LENGTH: + return .invalidContentLength + case HPE_UNEXPECTED_CONTENT_LENGTH: + return .unexpectedContentLength + case HPE_INVALID_CHUNK_SIZE: + return .invalidChunkSize + case HPE_INVALID_CONSTANT: + return .invalidConstant + case HPE_STRICT: + return .strictModeAssertion + case HPE_PAUSED: + return .paused + case HPE_UNKNOWN: + return .unknown + case HPE_INVALID_TRANSFER_ENCODING: + // The downside of enums here, we don't have a case for this. Map it to .unknown for now. + return .unknown + default: + return nil + } + } +} + +extension HTTPMethod { + /// Create a `HTTPMethod` from a given `http_method` produced by + /// `http_parser`. + /// + /// - Parameter httpParserMethod: The method returned by `http_parser`. + /// - Returns: The corresponding `HTTPMethod`. + static func from(httpParserMethod: http_method) -> HTTPMethod { + switch httpParserMethod { + case HTTP_DELETE: + return .DELETE + case HTTP_GET: + return .GET + case HTTP_HEAD: + return .HEAD + case HTTP_POST: + return .POST + case HTTP_PUT: + return .PUT + case HTTP_CONNECT: + return .CONNECT + case HTTP_OPTIONS: + return .OPTIONS + case HTTP_TRACE: + return .TRACE + case HTTP_COPY: + return .COPY + case HTTP_LOCK: + return .LOCK + case HTTP_MKCOL: + return .MKCOL + case HTTP_MOVE: + return .MOVE + case HTTP_PROPFIND: + return .PROPFIND + case HTTP_PROPPATCH: + return .PROPPATCH + case HTTP_SEARCH: + return .SEARCH + case HTTP_UNLOCK: + return .UNLOCK + case HTTP_BIND: + return .BIND + case HTTP_REBIND: + return .REBIND + case HTTP_UNBIND: + return .UNBIND + case HTTP_ACL: + return .ACL + case HTTP_REPORT: + return .REPORT + case HTTP_MKACTIVITY: + return .MKACTIVITY + case HTTP_CHECKOUT: + return .CHECKOUT + case HTTP_MERGE: + return .MERGE + case HTTP_MSEARCH: + return .MSEARCH + case HTTP_NOTIFY: + return .NOTIFY + case HTTP_SUBSCRIBE: + return .SUBSCRIBE + case HTTP_UNSUBSCRIBE: + return .UNSUBSCRIBE + case HTTP_PATCH: + return .PATCH + case HTTP_PURGE: + return .PURGE + case HTTP_MKCALENDAR: + return .MKCALENDAR + case HTTP_LINK: + return .LINK + case HTTP_UNLINK: + return .UNLINK + case HTTP_SOURCE: + // This isn't ideal really. + return .RAW(value: "SOURCE") + default: + fatalError("Unexpected http_method \(httpParserMethod)") + } + } +} + + +/// Errors thrown by `HTTPRequestDecoder` and `HTTPResponseDecoder` in addition to +/// `HTTPParserError`. +public struct NIOHTTPDecoderError: Error { + private enum BaseError: Hashable { + case unsolicitedResponse + } + + private let baseError: BaseError +} + + +extension NIOHTTPDecoderError { + /// A response was received from a server without an associated request having been sent. + public static let unsolicitedResponse: NIOHTTPDecoderError = .init(baseError: .unsolicitedResponse) +} + + +extension NIOHTTPDecoderError: Hashable { } + + +extension NIOHTTPDecoderError: CustomDebugStringConvertible { + public var debugDescription: String { + return String(describing: self.baseError) + } +} + +extension HTTPClientResponsePart { + fileprivate static func head( + versionMajor: Int, + versionMinor: Int, + statusCode: Int, + keepAliveState: KeepAliveState, + headers: [(String, String)] + ) -> HTTPClientResponsePart { + HTTPClientResponsePart.head(HTTPResponseHead( + version: .init(major: versionMajor, minor: versionMinor), + status: .init(statusCode: statusCode), + headers: HTTPHeaders(headers, keepAliveState: keepAliveState) + )) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPEncoder.swift new file mode 100644 index 00000000..16956886 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPEncoder.swift @@ -0,0 +1,568 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +private func writeChunk(wrapOutboundOut: (IOData) -> NIOAny, context: ChannelHandlerContext, isChunked: Bool, chunk: IOData, promise: EventLoopPromise?) { + let (mW1, mW2, mW3): (EventLoopPromise?, EventLoopPromise?, EventLoopPromise?) + + switch (isChunked, promise) { + case (true, .some(let p)): + /* chunked encoding and the user's interested: we need three promises and need to cascade into the users promise */ + let (w1, w2, w3) = (context.eventLoop.makePromise() as EventLoopPromise, context.eventLoop.makePromise() as EventLoopPromise, context.eventLoop.makePromise() as EventLoopPromise) + w1.futureResult.and(w2.futureResult).and(w3.futureResult).map { (_: ((((), ()), ()))) in }.cascade(to: p) + (mW1, mW2, mW3) = (w1, w2, w3) + case (false, .some(let p)): + /* not chunked, so just use the user's promise for the actual data */ + (mW1, mW2, mW3) = (nil, p, nil) + case (_, .none): + /* user isn't interested, let's not bother even allocating promises */ + (mW1, mW2, mW3) = (nil, nil, nil) + } + + let readableBytes = chunk.readableBytes + + /* we don't want to copy the chunk unnecessarily and therefore call write an annoyingly large number of times */ + if isChunked { + var buffer = context.channel.allocator.buffer(capacity: 32) + let len = String(readableBytes, radix: 16) + buffer.writeString(len) + buffer.writeStaticString("\r\n") + context.write(wrapOutboundOut(.byteBuffer(buffer)), promise: mW1) + + context.write(wrapOutboundOut(chunk), promise: mW2) + + // Just move the buffers readerIndex to only make the \r\n readable and depend on COW semantics. + buffer.moveReaderIndex(forwardBy: buffer.readableBytes - 2) + context.write(wrapOutboundOut(.byteBuffer(buffer)), promise: mW3) + } else { + context.write(wrapOutboundOut(chunk), promise: mW2) + } +} + +private func writeTrailers(wrapOutboundOut: (IOData) -> NIOAny, context: ChannelHandlerContext, isChunked: Bool, trailers: HTTPHeaders?, promise: EventLoopPromise?) { + switch (isChunked, promise) { + case (true, let p): + var buffer: ByteBuffer + if let trailers = trailers { + buffer = context.channel.allocator.buffer(capacity: 256) + buffer.writeStaticString("0\r\n") + buffer.write(headers: trailers) // Includes trailing CRLF. + } else { + buffer = context.channel.allocator.buffer(capacity: 8) + buffer.writeStaticString("0\r\n\r\n") + } + context.write(wrapOutboundOut(.byteBuffer(buffer)), promise: p) + case (false, .some(let p)): + // Not chunked so we have nothing to write. However, we don't want to satisfy this promise out-of-order + // so we issue a zero-length write down the chain. + let buf = context.channel.allocator.buffer(capacity: 0) + context.write(wrapOutboundOut(.byteBuffer(buf)), promise: p) + case (false, .none): + break + } +} + +// starting about swift-5.0-DEVELOPMENT-SNAPSHOT-2019-01-20-a, this doesn't get automatically inlined, which costs +// 2 extra allocations so we need to help the optimiser out. +@inline(__always) +private func writeHead(wrapOutboundOut: (IOData) -> NIOAny, writeStartLine: (inout ByteBuffer) -> Void, context: ChannelHandlerContext, headers: HTTPHeaders, promise: EventLoopPromise?) { + + var buffer = context.channel.allocator.buffer(capacity: 256) + writeStartLine(&buffer) + buffer.write(headers: headers) + context.write(wrapOutboundOut(.byteBuffer(buffer)), promise: promise) +} + +/// The type of framing that is used to mark the end of the body. +private enum BodyFraming { + case chunked + case contentLength + case neither +} + +/// Adjusts the response/request headers to ensure that the response/request will be well-framed. +/// +/// This method strips Content-Length and Transfer-Encoding headers from responses/requests that must +/// not have a body. It also adds Transfer-Encoding headers to responses/requests that do have bodies +/// but do not have any other transport headers when using HTTP/1.1. This ensures that we can +/// always safely reuse a connection. +/// +/// Note that for HTTP/1.0 if there is no Content-Length then the response should be followed +/// by connection close. We require that the user send that connection close: we don't do it. +private func correctlyFrameTransportHeaders(hasBody: HTTPMethod.HasBody, headers: inout HTTPHeaders, version: HTTPVersion) -> BodyFraming { + switch hasBody { + case .no: + headers.remove(name: "content-length") + headers.remove(name: "transfer-encoding") + return .neither + case .yes: + if headers.contains(name: "content-length") { + return .contentLength + } + if version.major == 1 && version.minor >= 1 { + headers.replaceOrAdd(name: "transfer-encoding", value: "chunked") + return .chunked + } else { + return .neither + } + case .unlikely: + if headers.contains(name: "content-length") { + return .contentLength + } + if version.major == 1 && version.minor >= 1 { + return headers["transfer-encoding"].first == "chunked" ? .chunked : .neither + } + return .neither + } +} + +/// A `ChannelOutboundHandler` that can serialize HTTP requests. +/// +/// This channel handler is used to translate messages from a series of +/// `HTTPClientRequestPart` into the HTTP/1.1 wire format. +public final class HTTPRequestEncoder: ChannelOutboundHandler, RemovableChannelHandler { + public typealias OutboundIn = HTTPClientRequestPart + public typealias OutboundOut = IOData + + private var isChunked = false + + public init () { } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + switch self.unwrapOutboundIn(data) { + case .head(var request): + assert(!(request.headers.contains(name: "content-length") && + request.headers[canonicalForm: "transfer-encoding"].contains("chunked"[...])), + "illegal HTTP sent: \(request) contains both a content-length and transfer-encoding:chunked") + self.isChunked = correctlyFrameTransportHeaders(hasBody: request.method.hasRequestBody, + headers: &request.headers, version: request.version) == .chunked + + writeHead(wrapOutboundOut: self.wrapOutboundOut, writeStartLine: { buffer in + buffer.write(request: request) + }, context: context, headers: request.headers, promise: promise) + case .body(let bodyPart): + guard bodyPart.readableBytes > 0 else { + // Empty writes shouldn't send any bytes in chunked or identity encoding. + context.write(self.wrapOutboundOut(bodyPart), promise: promise) + return + } + + writeChunk(wrapOutboundOut: self.wrapOutboundOut, context: context, isChunked: self.isChunked, chunk: bodyPart, promise: promise) + case .end(let trailers): + writeTrailers(wrapOutboundOut: self.wrapOutboundOut, context: context, isChunked: self.isChunked, trailers: trailers, promise: promise) + } + } +} + +/// A `ChannelOutboundHandler` that can serialize HTTP responses. +/// +/// This channel handler is used to translate messages from a series of +/// `HTTPServerResponsePart` into the HTTP/1.1 wire format. +public final class HTTPResponseEncoder: ChannelOutboundHandler, RemovableChannelHandler { + public typealias OutboundIn = HTTPServerResponsePart + public typealias OutboundOut = IOData + + private var isChunked = false + + public init () { } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + switch self.unwrapOutboundIn(data) { + case .head(var response): + assert(!(response.headers.contains(name: "content-length") && + response.headers[canonicalForm: "transfer-encoding"].contains("chunked"[...])), + "illegal HTTP sent: \(response) contains both a content-length and transfer-encoding:chunked") + self.isChunked = correctlyFrameTransportHeaders(hasBody: response.status.mayHaveResponseBody ? .yes : .no, + headers: &response.headers, version: response.version) == .chunked + + writeHead(wrapOutboundOut: self.wrapOutboundOut, writeStartLine: { buffer in + buffer.write(response: response) + }, context: context, headers: response.headers, promise: promise) + case .body(let bodyPart): + writeChunk(wrapOutboundOut: self.wrapOutboundOut, context: context, isChunked: self.isChunked, chunk: bodyPart, promise: promise) + case .end(let trailers): + writeTrailers(wrapOutboundOut: self.wrapOutboundOut, context: context, isChunked: self.isChunked, trailers: trailers, promise: promise) + } + } +} + +private extension ByteBuffer { + private mutating func write(status: HTTPResponseStatus) { + self.writeString(String(status.code)) + self.writeWhitespace() + self.writeString(status.reasonPhrase) + } + + mutating func write(response: HTTPResponseHead) { + switch (response.version.major, response.version.minor, response.status) { + // Optimization for HTTP/1.0 + case (1, 0, .custom(_, _)): + self.writeStaticString("HTTP/1.0 ") + self.write(status: response.status) + self.writeStaticString("\r\n") + case (1, 0, .continue): + self.writeStaticString("HTTP/1.0 100 Continue\r\n") + case (1, 0, .switchingProtocols): + self.writeStaticString("HTTP/1.0 101 Switching Protocols\r\n") + case (1, 0, .processing): + self.writeStaticString("HTTP/1.0 102 Processing\r\n") + case (1, 0, .ok): + self.writeStaticString("HTTP/1.0 200 OK\r\n") + case (1, 0, .created): + self.writeStaticString("HTTP/1.0 201 Created\r\n") + case (1, 0, .accepted): + self.writeStaticString("HTTP/1.0 202 Accepted\r\n") + case (1, 0, .nonAuthoritativeInformation): + self.writeStaticString("HTTP/1.0 203 Non-Authoritative Information\r\n") + case (1, 0, .noContent): + self.writeStaticString("HTTP/1.0 204 No Content\r\n") + case (1, 0, .resetContent): + self.writeStaticString("HTTP/1.0 205 Reset Content\r\n") + case (1, 0, .partialContent): + self.writeStaticString("HTTP/1.0 206 Partial Content\r\n") + case (1, 0, .multiStatus): + self.writeStaticString("HTTP/1.0 207 Multi-Status\r\n") + case (1, 0, .alreadyReported): + self.writeStaticString("HTTP/1.0 208 Already Reported\r\n") + case (1, 0, .imUsed): + self.writeStaticString("HTTP/1.0 226 IM Used\r\n") + case (1, 0, .multipleChoices): + self.writeStaticString("HTTP/1.0 300 Multiple Choices\r\n") + case (1, 0, .movedPermanently): + self.writeStaticString("HTTP/1.0 301 Moved Permanently\r\n") + case (1, 0, .found): + self.writeStaticString("HTTP/1.0 302 Found\r\n") + case (1, 0, .seeOther): + self.writeStaticString("HTTP/1.0 303 See Other\r\n") + case (1, 0, .notModified): + self.writeStaticString("HTTP/1.0 304 Not Modified\r\n") + case (1, 0, .useProxy): + self.writeStaticString("HTTP/1.0 305 Use Proxy\r\n") + case (1, 0, .temporaryRedirect): + self.writeStaticString("HTTP/1.0 307 Tempory Redirect\r\n") + case (1, 0, .permanentRedirect): + self.writeStaticString("HTTP/1.0 308 Permanent Redirect\r\n") + case (1, 0, .badRequest): + self.writeStaticString("HTTP/1.0 400 Bad Request\r\n") + case (1, 0, .unauthorized): + self.writeStaticString("HTTP/1.0 401 Unauthorized\r\n") + case (1, 0, .paymentRequired): + self.writeStaticString("HTTP/1.0 402 Payment Required\r\n") + case (1, 0, .forbidden): + self.writeStaticString("HTTP/1.0 403 Forbidden\r\n") + case (1, 0, .notFound): + self.writeStaticString("HTTP/1.0 404 Not Found\r\n") + case (1, 0, .methodNotAllowed): + self.writeStaticString("HTTP/1.0 405 Method Not Allowed\r\n") + case (1, 0, .notAcceptable): + self.writeStaticString("HTTP/1.0 406 Not Acceptable\r\n") + case (1, 0, .proxyAuthenticationRequired): + self.writeStaticString("HTTP/1.0 407 Proxy Authentication Required\r\n") + case (1, 0, .requestTimeout): + self.writeStaticString("HTTP/1.0 408 Request Timeout\r\n") + case (1, 0, .conflict): + self.writeStaticString("HTTP/1.0 409 Conflict\r\n") + case (1, 0, .gone): + self.writeStaticString("HTTP/1.0 410 Gone\r\n") + case (1, 0, .lengthRequired): + self.writeStaticString("HTTP/1.0 411 Length Required\r\n") + case (1, 0, .preconditionFailed): + self.writeStaticString("HTTP/1.0 412 Precondition Failed\r\n") + case (1, 0, .payloadTooLarge): + self.writeStaticString("HTTP/1.0 413 Payload Too Large\r\n") + case (1, 0, .uriTooLong): + self.writeStaticString("HTTP/1.0 414 URI Too Long\r\n") + case (1, 0, .unsupportedMediaType): + self.writeStaticString("HTTP/1.0 415 Unsupported Media Type\r\n") + case (1, 0, .rangeNotSatisfiable): + self.writeStaticString("HTTP/1.0 416 Range Not Satisfiable\r\n") + case (1, 0, .expectationFailed): + self.writeStaticString("HTTP/1.0 417 Expectation Failed\r\n") + case (1, 0, .misdirectedRequest): + self.writeStaticString("HTTP/1.0 421 Misdirected Request\r\n") + case (1, 0, .unprocessableEntity): + self.writeStaticString("HTTP/1.0 422 Unprocessable Entity\r\n") + case (1, 0, .locked): + self.writeStaticString("HTTP/1.0 423 Locked\r\n") + case (1, 0, .failedDependency): + self.writeStaticString("HTTP/1.0 424 Failed Dependency\r\n") + case (1, 0, .upgradeRequired): + self.writeStaticString("HTTP/1.0 426 Upgrade Required\r\n") + case (1, 0, .preconditionRequired): + self.writeStaticString("HTTP/1.0 428 Precondition Required\r\n") + case (1, 0, .tooManyRequests): + self.writeStaticString("HTTP/1.0 429 Too Many Requests\r\n") + case (1, 0, .requestHeaderFieldsTooLarge): + self.writeStaticString("HTTP/1.0 431 Request Header Fields Too Large\r\n") + case (1, 0, .unavailableForLegalReasons): + self.writeStaticString("HTTP/1.0 451 Unavailable For Legal Reasons\r\n") + case (1, 0, .internalServerError): + self.writeStaticString("HTTP/1.0 500 Internal Server Error\r\n") + case (1, 0, .notImplemented): + self.writeStaticString("HTTP/1.0 501 Not Implemented\r\n") + case (1, 0, .badGateway): + self.writeStaticString("HTTP/1.0 502 Bad Gateway\r\n") + case (1, 0, .serviceUnavailable): + self.writeStaticString("HTTP/1.0 503 Service Unavailable\r\n") + case (1, 0, .gatewayTimeout): + self.writeStaticString("HTTP/1.0 504 Gateway Timeout\r\n") + case (1, 0, .httpVersionNotSupported): + self.writeStaticString("HTTP/1.0 505 HTTP Version Not Supported\r\n") + case (1, 0, .variantAlsoNegotiates): + self.writeStaticString("HTTP/1.0 506 Variant Also Negotiates\r\n") + case (1, 0, .insufficientStorage): + self.writeStaticString("HTTP/1.0 507 Insufficient Storage\r\n") + case (1, 0, .loopDetected): + self.writeStaticString("HTTP/1.0 508 Loop Detected\r\n") + case (1, 0, .notExtended): + self.writeStaticString("HTTP/1.0 510 Not Extended\r\n") + case (1, 0, .networkAuthenticationRequired): + self.writeStaticString("HTTP/1.1 511 Network Authentication Required\r\n") + + // Optimization for HTTP/1.1 + case (1, 1, .custom(_, _)): + self.writeStaticString("HTTP/1.1 ") + self.write(status: response.status) + self.writeStaticString("\r\n") + case (1, 1, .continue): + self.writeStaticString("HTTP/1.1 100 Continue\r\n") + case (1, 1, .switchingProtocols): + self.writeStaticString("HTTP/1.1 101 Switching Protocols\r\n") + case (1, 1, .processing): + self.writeStaticString("HTTP/1.1 102 Processing\r\n") + case (1, 1, .ok): + self.writeStaticString("HTTP/1.1 200 OK\r\n") + case (1, 1, .created): + self.writeStaticString("HTTP/1.1 201 Created\r\n") + case (1, 1, .accepted): + self.writeStaticString("HTTP/1.1 202 Accepted\r\n") + case (1, 1, .nonAuthoritativeInformation): + self.writeStaticString("HTTP/1.1 203 Non-Authoritative Information\r\n") + case (1, 1, .noContent): + self.writeStaticString("HTTP/1.1 204 No Content\r\n") + case (1, 1, .resetContent): + self.writeStaticString("HTTP/1.1 205 Reset Content\r\n") + case (1, 1, .partialContent): + self.writeStaticString("HTTP/1.1 206 Partial Content\r\n") + case (1, 1, .multiStatus): + self.writeStaticString("HTTP/1.1 207 Multi-Status\r\n") + case (1, 1, .alreadyReported): + self.writeStaticString("HTTP/1.1 208 Already Reported\r\n") + case (1, 1, .imUsed): + self.writeStaticString("HTTP/1.1 226 IM Used\r\n") + case (1, 1, .multipleChoices): + self.writeStaticString("HTTP/1.1 300 Multiple Choices\r\n") + case (1, 1, .movedPermanently): + self.writeStaticString("HTTP/1.1 301 Moved Permanently\r\n") + case (1, 1, .found): + self.writeStaticString("HTTP/1.1 302 Found\r\n") + case (1, 1, .seeOther): + self.writeStaticString("HTTP/1.1 303 See Other\r\n") + case (1, 1, .notModified): + self.writeStaticString("HTTP/1.1 304 Not Modified\r\n") + case (1, 1, .useProxy): + self.writeStaticString("HTTP/1.1 305 Use Proxy\r\n") + case (1, 1, .temporaryRedirect): + self.writeStaticString("HTTP/1.1 307 Tempory Redirect\r\n") + case (1, 1, .permanentRedirect): + self.writeStaticString("HTTP/1.1 308 Permanent Redirect\r\n") + case (1, 1, .badRequest): + self.writeStaticString("HTTP/1.1 400 Bad Request\r\n") + case (1, 1, .unauthorized): + self.writeStaticString("HTTP/1.1 401 Unauthorized\r\n") + case (1, 1, .paymentRequired): + self.writeStaticString("HTTP/1.1 402 Payment Required\r\n") + case (1, 1, .forbidden): + self.writeStaticString("HTTP/1.1 403 Forbidden\r\n") + case (1, 1, .notFound): + self.writeStaticString("HTTP/1.1 404 Not Found\r\n") + case (1, 1, .methodNotAllowed): + self.writeStaticString("HTTP/1.1 405 Method Not Allowed\r\n") + case (1, 1, .notAcceptable): + self.writeStaticString("HTTP/1.1 406 Not Acceptable\r\n") + case (1, 1, .proxyAuthenticationRequired): + self.writeStaticString("HTTP/1.1 407 Proxy Authentication Required\r\n") + case (1, 1, .requestTimeout): + self.writeStaticString("HTTP/1.1 408 Request Timeout\r\n") + case (1, 1, .conflict): + self.writeStaticString("HTTP/1.1 409 Conflict\r\n") + case (1, 1, .gone): + self.writeStaticString("HTTP/1.1 410 Gone\r\n") + case (1, 1, .lengthRequired): + self.writeStaticString("HTTP/1.1 411 Length Required\r\n") + case (1, 1, .preconditionFailed): + self.writeStaticString("HTTP/1.1 412 Precondition Failed\r\n") + case (1, 1, .payloadTooLarge): + self.writeStaticString("HTTP/1.1 413 Payload Too Large\r\n") + case (1, 1, .uriTooLong): + self.writeStaticString("HTTP/1.1 414 URI Too Long\r\n") + case (1, 1, .unsupportedMediaType): + self.writeStaticString("HTTP/1.1 415 Unsupported Media Type\r\n") + case (1, 1, .rangeNotSatisfiable): + self.writeStaticString("HTTP/1.1 416 Request Range Not Satisified\r\n") + case (1, 1, .expectationFailed): + self.writeStaticString("HTTP/1.1 417 Expectation Failed\r\n") + case (1, 1, .misdirectedRequest): + self.writeStaticString("HTTP/1.1 421 Misdirected Request\r\n") + case (1, 1, .unprocessableEntity): + self.writeStaticString("HTTP/1.1 422 Unprocessable Entity\r\n") + case (1, 1, .locked): + self.writeStaticString("HTTP/1.1 423 Locked\r\n") + case (1, 1, .failedDependency): + self.writeStaticString("HTTP/1.1 424 Failed Dependency\r\n") + case (1, 1, .upgradeRequired): + self.writeStaticString("HTTP/1.1 426 Upgrade Required\r\n") + case (1, 1, .preconditionRequired): + self.writeStaticString("HTTP/1.1 428 Precondition Required\r\n") + case (1, 1, .tooManyRequests): + self.writeStaticString("HTTP/1.1 429 Too Many Requests\r\n") + case (1, 1, .requestHeaderFieldsTooLarge): + self.writeStaticString("HTTP/1.1 431 Range Not Satisfiable\r\n") + case (1, 1, .unavailableForLegalReasons): + self.writeStaticString("HTTP/1.1 451 Unavailable For Legal Reasons\r\n") + case (1, 1, .internalServerError): + self.writeStaticString("HTTP/1.1 500 Internal Server Error\r\n") + case (1, 1, .notImplemented): + self.writeStaticString("HTTP/1.1 501 Not Implemented\r\n") + case (1, 1, .badGateway): + self.writeStaticString("HTTP/1.1 502 Bad Gateway\r\n") + case (1, 1, .serviceUnavailable): + self.writeStaticString("HTTP/1.1 503 Service Unavailable\r\n") + case (1, 1, .gatewayTimeout): + self.writeStaticString("HTTP/1.1 504 Gateway Timeout\r\n") + case (1, 1, .httpVersionNotSupported): + self.writeStaticString("HTTP/1.1 505 HTTP Version Not Supported\r\n") + case (1, 1, .variantAlsoNegotiates): + self.writeStaticString("HTTP/1.1 506 Variant Also Negotiates\r\n") + case (1, 1, .insufficientStorage): + self.writeStaticString("HTTP/1.1 507 Insufficient Storage\r\n") + case (1, 1, .loopDetected): + self.writeStaticString("HTTP/1.1 508 Loop Detected\r\n") + case (1, 1, .notExtended): + self.writeStaticString("HTTP/1.1 510 Not Extended\r\n") + case (1, 1, .networkAuthenticationRequired): + self.writeStaticString("HTTP/1.1 511 Network Authentication Required\r\n") + + // Fallback for non-known HTTP version + default: + self.write(version: response.version) + self.writeWhitespace() + self.write(status: response.status) + self.writeStaticString("\r\n") + } + } + + private mutating func write(version: HTTPVersion) { + switch (version.minor, version.major) { + case (1, 0): + self.writeStaticString("HTTP/1.0") + case (1, 1): + self.writeStaticString("HTTP/1.1") + default: + self.writeStaticString("HTTP/") + self.writeString(String(version.major)) + self.writeStaticString(".") + self.writeString(String(version.minor)) + } + } + + mutating func write(request: HTTPRequestHead) { + self.write(method: request.method) + self.writeWhitespace() + self.writeString(request.uri) + self.writeWhitespace() + self.write(version: request.version) + self.writeStaticString("\r\n") + } + + mutating func writeWhitespace() { + self.writeInteger(32, as: UInt8.self) + } + + private mutating func write(method: HTTPMethod) { + switch method { + case .GET: + self.writeStaticString("GET") + case .PUT: + self.writeStaticString("PUT") + case .ACL: + self.writeStaticString("ACL") + case .HEAD: + self.writeStaticString("HEAD") + case .POST: + self.writeStaticString("POST") + case .COPY: + self.writeStaticString("COPY") + case .LOCK: + self.writeStaticString("LOCK") + case .MOVE: + self.writeStaticString("MOVE") + case .BIND: + self.writeStaticString("BIND") + case .LINK: + self.writeStaticString("LINK") + case .PATCH: + self.writeStaticString("PATCH") + case .TRACE: + self.writeStaticString("TRACE") + case .MKCOL: + self.writeStaticString("MKCOL") + case .MERGE: + self.writeStaticString("MERGE") + case .PURGE: + self.writeStaticString("PURGE") + case .NOTIFY: + self.writeStaticString("NOTIFY") + case .SEARCH: + self.writeStaticString("SEARCH") + case .UNLOCK: + self.writeStaticString("UNLOCK") + case .REBIND: + self.writeStaticString("REBIND") + case .UNBIND: + self.writeStaticString("UNBIND") + case .REPORT: + self.writeStaticString("REPORT") + case .DELETE: + self.writeStaticString("DELETE") + case .UNLINK: + self.writeStaticString("UNLINK") + case .CONNECT: + self.writeStaticString("CONNECT") + case .MSEARCH: + self.writeStaticString("MSEARCH") + case .OPTIONS: + self.writeStaticString("OPTIONS") + case .PROPFIND: + self.writeStaticString("PROPFIND") + case .CHECKOUT: + self.writeStaticString("CHECKOUT") + case .PROPPATCH: + self.writeStaticString("PROPPATCH") + case .SUBSCRIBE: + self.writeStaticString("SUBSCRIBE") + case .MKCALENDAR: + self.writeStaticString("MKCALENDAR") + case .MKACTIVITY: + self.writeStaticString("MKACTIVITY") + case .UNSUBSCRIBE: + self.writeStaticString("UNSUBSCRIBE") + case .SOURCE: + self.writeStaticString("SOURCE") + case .RAW(let value): + self.writeString(value) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPPipelineSetup.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPPipelineSetup.swift new file mode 100644 index 00000000..cf488630 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPPipelineSetup.swift @@ -0,0 +1,242 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// Configuration required to configure a HTTP client pipeline for upgrade. +/// +/// See the documentation for `HTTPClientUpgradeHandler` for details on these +/// properties. +public typealias NIOHTTPClientUpgradeConfiguration = (upgraders: [NIOHTTPClientProtocolUpgrader], completionHandler: (ChannelHandlerContext) -> Void) + +/// Configuration required to configure a HTTP server pipeline for upgrade. +/// +/// See the documentation for `HTTPServerUpgradeHandler` for details on these +/// properties. +@available(*, deprecated, renamed: "NIOHTTPServerUpgradeConfiguration") +public typealias HTTPUpgradeConfiguration = NIOHTTPServerUpgradeConfiguration + +public typealias NIOHTTPServerUpgradeConfiguration = (upgraders: [HTTPServerProtocolUpgrader], completionHandler: (ChannelHandlerContext) -> Void) + +extension ChannelPipeline { + /// Configure a `ChannelPipeline` for use as a HTTP client. + /// + /// - parameters: + /// - position: The position in the `ChannelPipeline` where to add the HTTP client handlers. Defaults to `.last`. + /// - leftOverBytesStrategy: The strategy to use when dealing with leftover bytes after removing the `HTTPDecoder` + /// from the pipeline. + /// - returns: An `EventLoopFuture` that will fire when the pipeline is configured. + public func addHTTPClientHandlers(position: Position = .last, + leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes) -> EventLoopFuture { + return self.addHTTPClientHandlers(position: position, + leftOverBytesStrategy: leftOverBytesStrategy, + withClientUpgrade: nil) + } + + /// Configure a `ChannelPipeline` for use as a HTTP client with a client upgrader configuration. + /// + /// - parameters: + /// - position: The position in the `ChannelPipeline` where to add the HTTP client handlers. Defaults to `.last`. + /// - leftOverBytesStrategy: The strategy to use when dealing with leftover bytes after removing the `HTTPDecoder` + /// from the pipeline. + /// - upgrade: Add a `HTTPClientUpgradeHandler` to the pipeline, configured for + /// HTTP upgrade. Should be a tuple of an array of `HTTPClientProtocolUpgrader` and + /// the upgrade completion handler. See the documentation on `HTTPClientUpgradeHandler` + /// for more details. + /// - returns: An `EventLoopFuture` that will fire when the pipeline is configured. + public func addHTTPClientHandlers(position: Position = .last, + leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes, + withClientUpgrade upgrade: NIOHTTPClientUpgradeConfiguration?) -> EventLoopFuture { + let future: EventLoopFuture + + if self.eventLoop.inEventLoop { + let result = Result { + try self.syncOperations.addHTTPClientHandlers(position: position, + leftOverBytesStrategy: leftOverBytesStrategy, + withClientUpgrade: upgrade) + } + future = self.eventLoop.makeCompletedFuture(result) + } else { + future = self.eventLoop.submit { + return try self.syncOperations.addHTTPClientHandlers(position: position, + leftOverBytesStrategy: leftOverBytesStrategy, + withClientUpgrade: upgrade) + } + } + + return future + } + + /// Configure a `ChannelPipeline` for use as a HTTP server. + /// + /// This function knows how to set up all first-party HTTP channel handlers appropriately + /// for server use. It supports the following features: + /// + /// 1. Providing assistance handling clients that pipeline HTTP requests, using the + /// `HTTPServerPipelineHandler`. + /// 2. Supporting HTTP upgrade, using the `HTTPServerUpgradeHandler`. + /// + /// This method will likely be extended in future with more support for other first-party + /// features. + /// + /// - parameters: + /// - position: Where in the pipeline to add the HTTP server handlers, defaults to `.last`. + /// - pipelining: Whether to provide assistance handling HTTP clients that pipeline + /// their requests. Defaults to `true`. If `false`, users will need to handle + /// clients that pipeline themselves. + /// - upgrade: Whether to add a `HTTPServerUpgradeHandler` to the pipeline, configured for + /// HTTP upgrade. Defaults to `nil`, which will not add the handler to the pipeline. If + /// provided should be a tuple of an array of `HTTPServerProtocolUpgrader` and the upgrade + /// completion handler. See the documentation on `HTTPServerUpgradeHandler` for more + /// details. + /// - errorHandling: Whether to provide assistance handling protocol errors (e.g. + /// failure to parse the HTTP request) by sending 400 errors. Defaults to `true`. + /// - returns: An `EventLoopFuture` that will fire when the pipeline is configured. + public func configureHTTPServerPipeline(position: ChannelPipeline.Position = .last, + withPipeliningAssistance pipelining: Bool = true, + withServerUpgrade upgrade: NIOHTTPServerUpgradeConfiguration? = nil, + withErrorHandling errorHandling: Bool = true) -> EventLoopFuture { + let future: EventLoopFuture + + if self.eventLoop.inEventLoop { + let result = Result { + try self.syncOperations.configureHTTPServerPipeline(position: position, + withPipeliningAssistance: pipelining, + withServerUpgrade: upgrade, + withErrorHandling: errorHandling) + } + future = self.eventLoop.makeCompletedFuture(result) + } else { + future = self.eventLoop.submit { + try self.syncOperations.configureHTTPServerPipeline(position: position, + withPipeliningAssistance: pipelining, + withServerUpgrade: upgrade, + withErrorHandling: errorHandling) + } + } + + return future + } +} + +extension ChannelPipeline.SynchronousOperations { + /// Configure a `ChannelPipeline` for use as a HTTP client with a client upgrader configuration. + /// + /// - important: This **must** be called on the Channel's event loop. + /// - parameters: + /// - position: The position in the `ChannelPipeline` where to add the HTTP client handlers. Defaults to `.last`. + /// - leftOverBytesStrategy: The strategy to use when dealing with leftover bytes after removing the `HTTPDecoder` + /// from the pipeline. + /// - upgrade: Add a `HTTPClientUpgradeHandler` to the pipeline, configured for + /// HTTP upgrade. Should be a tuple of an array of `HTTPClientProtocolUpgrader` and + /// the upgrade completion handler. See the documentation on `HTTPClientUpgradeHandler` + /// for more details. + /// - throws: If the pipeline could not be configured. + public func addHTTPClientHandlers(position: ChannelPipeline.Position = .last, + leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes, + withClientUpgrade upgrade: NIOHTTPClientUpgradeConfiguration? = nil) throws { + // Why two separate functions? When creating the array of handlers to add to the pipeline, when we don't have + // an upgrade handler -- i.e. just an array literal -- the compiler is able to promote the array to the stack + // which saves an allocation. That's not the case when the upgrade handler is present. + if let upgrade = upgrade { + try self._addHTTPClientHandlers(position: position, + leftOverBytesStrategy: leftOverBytesStrategy, + withClientUpgrade: upgrade) + } else { + try self._addHTTPClientHandlers(position: position, + leftOverBytesStrategy: leftOverBytesStrategy) + } + } + + private func _addHTTPClientHandlers(position: ChannelPipeline.Position, + leftOverBytesStrategy: RemoveAfterUpgradeStrategy) throws { + self.eventLoop.assertInEventLoop() + let requestEncoder = HTTPRequestEncoder() + let responseDecoder = HTTPResponseDecoder(leftOverBytesStrategy: leftOverBytesStrategy) + let handlers: [ChannelHandler] = [requestEncoder, ByteToMessageHandler(responseDecoder)] + try self.addHandlers(handlers, position: position) + } + + private func _addHTTPClientHandlers(position: ChannelPipeline.Position, + leftOverBytesStrategy: RemoveAfterUpgradeStrategy, + withClientUpgrade upgrade: NIOHTTPClientUpgradeConfiguration) throws { + self.eventLoop.assertInEventLoop() + let requestEncoder = HTTPRequestEncoder() + let responseDecoder = HTTPResponseDecoder(leftOverBytesStrategy: leftOverBytesStrategy) + var handlers: [RemovableChannelHandler] = [requestEncoder, ByteToMessageHandler(responseDecoder)] + + let upgrader = NIOHTTPClientUpgradeHandler(upgraders: upgrade.upgraders, + httpHandlers: handlers, + upgradeCompletionHandler: upgrade.completionHandler) + handlers.append(upgrader) + + try self.addHandlers(handlers, position: position) + } + + /// Configure a `ChannelPipeline` for use as a HTTP server. + /// + /// This function knows how to set up all first-party HTTP channel handlers appropriately + /// for server use. It supports the following features: + /// + /// 1. Providing assistance handling clients that pipeline HTTP requests, using the + /// `HTTPServerPipelineHandler`. + /// 2. Supporting HTTP upgrade, using the `HTTPServerUpgradeHandler`. + /// + /// This method will likely be extended in future with more support for other first-party + /// features. + /// + /// - important: This **must** be called on the Channel's event loop. + /// - parameters: + /// - position: Where in the pipeline to add the HTTP server handlers, defaults to `.last`. + /// - pipelining: Whether to provide assistance handling HTTP clients that pipeline + /// their requests. Defaults to `true`. If `false`, users will need to handle + /// clients that pipeline themselves. + /// - upgrade: Whether to add a `HTTPServerUpgradeHandler` to the pipeline, configured for + /// HTTP upgrade. Defaults to `nil`, which will not add the handler to the pipeline. If + /// provided should be a tuple of an array of `HTTPServerProtocolUpgrader` and the upgrade + /// completion handler. See the documentation on `HTTPServerUpgradeHandler` for more + /// details. + /// - errorHandling: Whether to provide assistance handling protocol errors (e.g. + /// failure to parse the HTTP request) by sending 400 errors. Defaults to `true`. + /// - throws: If the pipeline could not be configured. + public func configureHTTPServerPipeline(position: ChannelPipeline.Position = .last, + withPipeliningAssistance pipelining: Bool = true, + withServerUpgrade upgrade: NIOHTTPServerUpgradeConfiguration? = nil, + withErrorHandling errorHandling: Bool = true) throws { + self.eventLoop.assertInEventLoop() + + let responseEncoder = HTTPResponseEncoder() + let requestDecoder = HTTPRequestDecoder(leftOverBytesStrategy: upgrade == nil ? .dropBytes : .forwardBytes) + + var handlers: [RemovableChannelHandler] = [responseEncoder, ByteToMessageHandler(requestDecoder)] + + if pipelining { + handlers.append(HTTPServerPipelineHandler()) + } + + if errorHandling { + handlers.append(HTTPServerProtocolErrorHandler()) + } + + if let (upgraders, completionHandler) = upgrade { + let upgrader = HTTPServerUpgradeHandler(upgraders: upgraders, + httpEncoder: responseEncoder, + extraHTTPHandlers: Array(handlers.dropFirst()), + upgradeCompletionHandler: completionHandler) + handlers.append(upgrader) + } + + try self.addHandlers(handlers, position: position) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerPipelineHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerPipelineHandler.swift new file mode 100644 index 00000000..b2860dee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerPipelineHandler.swift @@ -0,0 +1,472 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// A utility function that runs the body code only in debug builds, without +/// emitting compiler warnings. +/// +/// This is currently the only way to do this in Swift: see +/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion. +internal func debugOnly(_ body: () -> Void) { + assert({ body(); return true }()) +} + +/// A `ChannelHandler` that handles HTTP pipelining by buffering inbound data until a +/// response has been sent. +/// +/// This handler ensures that HTTP server pipelines only process one request at a time. +/// This is the safest way for pipelining-unaware code to operate, as it ensures that +/// mutation of any shared server state is not parallelised, and that responses are always +/// sent for each request in turn. In almost all cases this is the behaviour that a +/// pipeline will want. This is achieved without doing too much buffering by preventing +/// the `Channel` from reading from the socket until a complete response is processed, +/// ensuring that a malicious client is not capable of overwhelming a server by shoving +/// an enormous amount of data down the `Channel` while a server is processing a +/// slow response. +/// +/// See [RFC 7320 Section 6.3.2](https://tools.ietf.org/html/rfc7230#section-6.3.2) for +/// more details on safely handling HTTP pipelining. +/// +/// In addition to handling the request buffering, this `ChannelHandler` is aware of +/// TCP half-close. While there are very few HTTP clients that are capable of TCP +/// half-close, clients that are not HTTP specific (e.g. `netcat`) may trigger a TCP +/// half-close. Having this `ChannelHandler` be aware of TCP half-close makes it easier +/// to build HTTP servers that are resilient to this kind of behaviour. +/// +/// The TCP half-close handling is done by buffering the half-close notification along +/// with the HTTP request parts. The half-close notification will be delivered in order +/// with the rest of the reads. If the half-close occurs either before a request is received +/// or during a request body upload, it will be delivered immediately. If a half-close is +/// received immediately after `HTTPServerRequestPart.end`, it will also be passed along +/// immediately, allowing this signal to be seen by the HTTP server as early as possible. +public final class HTTPServerPipelineHandler: ChannelDuplexHandler, RemovableChannelHandler { + public typealias InboundIn = HTTPServerRequestPart + public typealias InboundOut = HTTPServerRequestPart + public typealias OutboundIn = HTTPServerResponsePart + public typealias OutboundOut = HTTPServerResponsePart + + public init() { + self.nextExpectedInboundMessage = nil + self.nextExpectedOutboundMessage = nil + + debugOnly { + self.nextExpectedInboundMessage = .head + self.nextExpectedOutboundMessage = .head + } + } + + /// The state of the HTTP connection. + private enum ConnectionState { + /// We are waiting for a HTTP response to complete before we + /// let the next request in. + case responseEndPending + + /// We are in the middle of both a request and a response and waiting for both `.end`s. + case requestAndResponseEndPending + + /// Nothing is active on this connection, the next message we expect would be a request `.head`. + case idle + + /// The server has responded early, before the request has completed. We need + /// to wait for the request to complete, but won't block anything. + case requestEndPending + + mutating func requestHeadReceived() { + switch self { + case .idle: + self = .requestAndResponseEndPending + case .requestAndResponseEndPending, .responseEndPending, .requestEndPending: + preconditionFailure("received request head in state \(self)") + } + } + + mutating func responseEndReceived() { + switch self { + case .responseEndPending: + // Got the response we were waiting for. + self = .idle + case .requestAndResponseEndPending: + // We got a response while still receiving a request, which we have to + // wait for. + self = .requestEndPending + case .requestEndPending, .idle: + preconditionFailure("Unexpectedly received a response in state \(self)") + } + } + + mutating func requestEndReceived() { + switch self { + case .requestEndPending: + // Got the request end we were waiting for. + self = .idle + case .requestAndResponseEndPending: + // We got a request and the response isn't done, wait for the + // response. + self = .responseEndPending + case .responseEndPending, .idle: + preconditionFailure("Received second request") + } + } + } + + /// The events that this handler buffers while waiting for the server to + /// generate a response. + private enum BufferedEvent { + /// A channelRead event. + case channelRead(NIOAny) + + case error(HTTPParserError) + + /// A TCP half-close. This is buffered to ensure that subsequent channel + /// handlers that are aware of TCP half-close are informed about it in + /// the appropriate order. + case halfClose + } + + /// The connection state + private var state = ConnectionState.idle + + /// While we're waiting to send the response we don't read from the socket. + /// This keeps track of whether we need to call read() when we've send our response. + private var readPending = false + + /// The buffered HTTP requests that are not going to be addressed yet. In general clients + /// don't pipeline, so this initially allocates no space for data at all. Clients that + /// do pipeline will cause dynamic resizing of the buffer, which is generally acceptable. + private var eventBuffer = CircularBuffer(initialCapacity: 0) + + enum NextExpectedMessageType { + case head + case bodyOrEnd + } + + enum LifecycleState { + /// Operating normally, accepting all events. + case acceptingEvents + + /// Quiescing but we're still waiting for the request's `.end` which means we still need to process input. + case quiescingWaitingForRequestEnd + + /// Quiescing and the last request's `.end` has been seen which means we no longer accept any input. + case quiescingLastRequestEndReceived + + /// Quiescing and we have issued a channel close. Further I/O here is not expected, and won't be managed. + case quiescingCompleted + } + + private var lifecycleState: LifecycleState = .acceptingEvents + + // always `nil` in release builds, never `nil` in debug builds + private var nextExpectedInboundMessage: Optional + // always `nil` in release builds, never `nil` in debug builds + private var nextExpectedOutboundMessage: Optional + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + switch self.lifecycleState { + case .quiescingLastRequestEndReceived, .quiescingCompleted: + // We're done, no more data for you. + return + case .acceptingEvents, .quiescingWaitingForRequestEnd: + // Still accepting I/O + () + } + + if self.eventBuffer.count != 0 || self.state == .responseEndPending { + self.eventBuffer.append(.channelRead(data)) + return + } else { + self.deliverOneMessage(context: context, data: data) + } + } + + private func deliverOneMessage(context: ChannelHandlerContext, data: NIOAny) { + assert(self.lifecycleState != .quiescingLastRequestEndReceived && + self.lifecycleState != .quiescingCompleted, + "deliverOneMessage called in lifecycle illegal state \(self.lifecycleState)") + let msg = self.unwrapInboundIn(data) + + debugOnly { + switch msg { + case .head: + assert(self.nextExpectedInboundMessage == .head) + self.nextExpectedInboundMessage = .bodyOrEnd + case .body: + assert(self.nextExpectedInboundMessage == .bodyOrEnd) + case .end: + assert(self.nextExpectedInboundMessage == .bodyOrEnd) + self.nextExpectedInboundMessage = .head + } + } + + switch msg { + case .head: + self.state.requestHeadReceived() + case .end: + // New request is complete. We don't want any more data from now on. + self.state.requestEndReceived() + + if self.lifecycleState == .quiescingWaitingForRequestEnd { + self.lifecycleState = .quiescingLastRequestEndReceived + self.eventBuffer.removeAll() + } + if self.lifecycleState == .quiescingLastRequestEndReceived && self.state == .idle { + self.lifecycleState = .quiescingCompleted + context.close(promise: nil) + } + case .body: + () + } + + context.fireChannelRead(data) + } + + private func deliverOneError(context: ChannelHandlerContext, error: Error) { + // there is one interesting case in this error sending logic: If we receive a `HTTPParserError` and we haven't + // received a full request nor the beginning of a response we should treat this as a full request. The reason + // is that what the user will probably do is send a `.badRequest` response and we should be in a state which + // allows that. + if (self.state == .idle || self.state == .requestEndPending) && error is HTTPParserError { + self.state = .responseEndPending + } + context.fireErrorCaught(error) + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + switch event { + case is ChannelShouldQuiesceEvent: + assert(self.lifecycleState == .acceptingEvents, + "unexpected lifecycle state when receiving ChannelShouldQuiesceEvent: \(self.lifecycleState)") + switch self.state { + case .responseEndPending: + // we're not in the middle of a request, let's just shut the door + self.lifecycleState = .quiescingLastRequestEndReceived + self.eventBuffer.removeAll() + case .idle: + // we're completely idle, let's just close + self.lifecycleState = .quiescingCompleted + self.eventBuffer.removeAll() + context.close(promise: nil) + case .requestEndPending, .requestAndResponseEndPending: + // we're in the middle of a request, we'll need to keep accepting events until we see the .end + self.lifecycleState = .quiescingWaitingForRequestEnd + } + case ChannelEvent.inputClosed: + // We only buffer half-close if there are request parts we're waiting to send. + // Otherwise we deliver the half-close immediately. + if case .responseEndPending = self.state, self.eventBuffer.count > 0 { + self.eventBuffer.append(.halfClose) + } else { + context.fireUserInboundEventTriggered(event) + } + default: + context.fireUserInboundEventTriggered(event) + } + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + guard let httpError = error as? HTTPParserError else { + self.deliverOneError(context: context, error: error) + return + } + if case .responseEndPending = self.state { + self.eventBuffer.append(.error(httpError)) + return + } + self.deliverOneError(context: context, error: error) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + assert(self.state != .requestEndPending, + "Received second response while waiting for first one to complete") + debugOnly { + let res = self.unwrapOutboundIn(data) + switch res { + case .head(let head) where head.isInformational: + assert(self.nextExpectedOutboundMessage == .head) + case .head: + assert(self.nextExpectedOutboundMessage == .head) + self.nextExpectedOutboundMessage = .bodyOrEnd + case .body: + assert(self.nextExpectedOutboundMessage == .bodyOrEnd) + case .end: + assert(self.nextExpectedOutboundMessage == .bodyOrEnd) + self.nextExpectedOutboundMessage = .head + } + } + + var startReadingAgain = false + + switch self.unwrapOutboundIn(data) { + case .head(var head) where self.lifecycleState != .acceptingEvents: + if head.isKeepAlive { + head.headers.replaceOrAdd(name: "connection", value: "close") + } + context.write(self.wrapOutboundOut(.head(head)), promise: promise) + case .end: + startReadingAgain = true + + switch self.lifecycleState { + case .quiescingWaitingForRequestEnd where self.state == .responseEndPending: + // we just received the .end that we're missing so we can fall through to closing the connection + fallthrough + case .quiescingLastRequestEndReceived: + self.lifecycleState = .quiescingCompleted + context.write(data).flatMap { + context.close() + }.cascade(to: promise) + case .acceptingEvents, .quiescingWaitingForRequestEnd: + context.write(data, promise: promise) + case .quiescingCompleted: + // Uh, why are we writing more data here? We'll write it, but it should be guaranteed + // to fail. + assertionFailure("Wrote in quiescing completed state") + context.write(data, promise: promise) + } + case .body, .head: + context.write(data, promise: promise) + } + + if startReadingAgain { + self.state.responseEndReceived() + self.deliverPendingRequests(context: context) + self.startReading(context: context) + } + } + + public func read(context: ChannelHandlerContext) { + switch self.lifecycleState { + case .quiescingLastRequestEndReceived, .quiescingCompleted: + // We swallow all reads now, as we're going to close the connection. + () + case .acceptingEvents, .quiescingWaitingForRequestEnd: + if case .responseEndPending = self.state { + self.readPending = true + } else { + context.read() + } + } + } + + public func handlerRemoved(context: ChannelHandlerContext) { + // We're being removed from the pipeline. We need to do a few things: + // + // 1. If we have buffered events, deliver them. While we shouldn't be + // re-entrantly called, we want to ensure that so we take a local copy. + // 2. If we are quiescing, we swallowed a quiescing event from the user: replay it, + // as the user has hopefully added a handler that will do something with this. + // 3. Finally, if we have a read pending, we need to release it. + // + // The basic theory here is that if there is anything we were going to do when we received + // either a request .end or a response .end, we do it now because there is no future for us. + // We also need to ensure we do not drop any data on the floor. + // + // At this stage we are no longer in the pipeline, so all further content should be + // blocked from reaching us. Thus we can avoid mutating our own internal state any + // longer. + let bufferedEvents = self.eventBuffer + for event in bufferedEvents { + switch event { + case .channelRead(let read): + context.fireChannelRead(read) + case .halfClose: + context.fireUserInboundEventTriggered(ChannelEvent.inputClosed) + case .error(let error): + context.fireErrorCaught(error) + } + } + + + switch self.lifecycleState { + case .quiescingLastRequestEndReceived, .quiescingWaitingForRequestEnd: + context.fireUserInboundEventTriggered(ChannelShouldQuiesceEvent()) + case .acceptingEvents, .quiescingCompleted: + // Either we haven't quiesced, or we succeeded in doing it. + () + } + + if self.readPending { + context.read() + } + } + + public func channelInactive(context: ChannelHandlerContext) { + // Welp, this channel isn't going to work anymore. We may as well drop our pending events here, as we + // cannot be expected to act on them any longer. + // + // Side note: it's important that we drop these. If we don't, handlerRemoved will deliver them all. + // While it's fair to immediately pipeline a channel where the user chose to remove the HTTPPipelineHandler, + // it's deeply unfair to do so to a user that didn't choose to do that, where it happened to them only because + // the channel closed. + // + // We set keepingCapacity to avoid this reallocating a buffer, as we'll just free it shortly anyway. + self.eventBuffer.removeAll(keepingCapacity: true) + context.fireChannelInactive() + } + + /// A response has been sent: we can now start passing reads through + /// again if there are no further pending requests, and send any read() + /// call we may have swallowed. + private func startReading(context: ChannelHandlerContext) { + if self.readPending && self.state != .responseEndPending { + switch self.lifecycleState { + case .quiescingLastRequestEndReceived, .quiescingCompleted: + // No more reads in these states. + () + case .acceptingEvents, .quiescingWaitingForRequestEnd: + self.readPending = false + context.read() + } + } + } + + /// A response has been sent: deliver all pending requests and + /// mark the channel ready to handle more requests. + private func deliverPendingRequests(context: ChannelHandlerContext) { + var deliveredRead = false + + while self.state != .responseEndPending, let event = self.eventBuffer.first { + self.eventBuffer.removeFirst() + + switch event { + case .channelRead(let read): + self.deliverOneMessage(context: context, data: read) + deliveredRead = true + case .error(let error): + self.deliverOneError(context: context, error: error) + case .halfClose: + // When we fire the half-close, we want to forget all prior reads. + // They will just trigger further half-close notifications we don't + // need. + self.readPending = false + context.fireUserInboundEventTriggered(ChannelEvent.inputClosed) + } + } + + if deliveredRead { + context.fireChannelReadComplete() + } + + // We need to quickly check whether there is an EOF waiting here, because + // if there is we should also unbuffer it and pass it along. There is no + // advantage in sitting on it, and it may help the later channel handlers + // be more sensible about keep-alive logic if they can see this early. + // This is done after `fireChannelReadComplete` to keep the same observable + // behaviour as `SocketChannel`, which fires these events in this order. + if case .some(.halfClose) = self.eventBuffer.first { + self.eventBuffer.removeFirst() + self.readPending = false + context.fireUserInboundEventTriggered(ChannelEvent.inputClosed) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerProtocolErrorHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerProtocolErrorHandler.swift new file mode 100644 index 00000000..c48cdccf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerProtocolErrorHandler.swift @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// A simple channel handler that catches errors emitted by parsing HTTP requests +/// and sends 400 Bad Request responses. +/// +/// This channel handler provides the basic behaviour that the majority of simple HTTP +/// servers want. This handler does not suppress the parser errors: it allows them to +/// continue to pass through the pipeline so that other handlers (e.g. logging ones) can +/// deal with the error. +public final class HTTPServerProtocolErrorHandler: ChannelDuplexHandler, RemovableChannelHandler { + public typealias InboundIn = HTTPServerRequestPart + public typealias InboundOut = HTTPServerRequestPart + public typealias OutboundIn = HTTPServerResponsePart + public typealias OutboundOut = HTTPServerResponsePart + + private var hasUnterminatedResponse: Bool = false + + public init() {} + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + guard error is HTTPParserError else { + context.fireErrorCaught(error) + return + } + + // Any HTTPParserError is automatically fatal, and we don't actually need (or want) to + // provide that error to the client: we just want to tell it that it screwed up and then + // let the rest of the pipeline shut the door in its face. However, we can only send an + // HTTP error response if another response hasn't started yet. + // + // A side note here: we cannot block or do any delayed work. ByteToMessageDecoder is going + // to come along and close the channel right after we return from this function. + if !self.hasUnterminatedResponse { + let headers = HTTPHeaders([("Connection", "close"), ("Content-Length", "0")]) + let head = HTTPResponseHead(version: .http1_1, status: .badRequest, headers: headers) + context.write(self.wrapOutboundOut(.head(head)), promise: nil) + context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil) + } + + // Now pass the error on in case someone else wants to see it. + context.fireErrorCaught(error) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let res = self.unwrapOutboundIn(data) + switch res { + case .head(let head) where head.isInformational: + precondition(!self.hasUnterminatedResponse) + case .head: + precondition(!self.hasUnterminatedResponse) + self.hasUnterminatedResponse = true + case .body: + precondition(self.hasUnterminatedResponse) + case .end: + precondition(self.hasUnterminatedResponse) + self.hasUnterminatedResponse = false + } + context.write(data, promise: promise) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerUpgradeHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerUpgradeHandler.swift new file mode 100644 index 00000000..4e16419c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPServerUpgradeHandler.swift @@ -0,0 +1,344 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// Errors that may be raised by the `HTTPServerProtocolUpgrader`. +public enum HTTPServerUpgradeErrors: Error { + case invalidHTTPOrdering +} + +/// User events that may be fired by the `HTTPServerProtocolUpgrader`. +public enum HTTPServerUpgradeEvents { + /// Fired when HTTP upgrade has completed and the + /// `HTTPServerProtocolUpgrader` is about to remove itself from the + /// `ChannelPipeline`. + case upgradeComplete(toProtocol: String, upgradeRequest: HTTPRequestHead) +} + + +/// An object that implements `HTTPServerProtocolUpgrader` knows how to handle HTTP upgrade to +/// a protocol on a server-side channel. +public protocol HTTPServerProtocolUpgrader { + /// The protocol this upgrader knows how to support. + var supportedProtocol: String { get } + + /// All the header fields the protocol needs in the request to successfully upgrade. These header fields + /// will be provided to the handler when it is asked to handle the upgrade. They will also be validated + /// against the inbound request's Connection header field. + var requiredUpgradeHeaders: [String] { get } + + /// Builds the upgrade response headers. Should return any headers that need to be supplied to the client + /// in the 101 Switching Protocols response. If upgrade cannot proceed for any reason, this function should + /// fail the future. + func buildUpgradeResponse(channel: Channel, upgradeRequest: HTTPRequestHead, initialResponseHeaders: HTTPHeaders) -> EventLoopFuture + + /// Called when the upgrade response has been flushed. At this time it is safe to mutate the channel pipeline + /// to add whatever channel handlers are required. Until the returned `EventLoopFuture` succeeds, all received + /// data will be buffered. + func upgrade(context: ChannelHandlerContext, upgradeRequest: HTTPRequestHead) -> EventLoopFuture +} + +/// A server-side channel handler that receives HTTP requests and optionally performs a HTTP-upgrade. +/// Removes itself from the channel pipeline after the first inbound request on the connection, regardless of +/// whether the upgrade succeeded or not. +/// +/// This handler behaves a bit differently from its Netty counterpart because it does not allow upgrade +/// on any request but the first on a connection. This is primarily to handle clients that pipeline: it's +/// sufficiently difficult to ensure that the upgrade happens at a safe time while dealing with pipelined +/// requests that we choose to punt on it entirely and not allow it. As it happens this is mostly fine: +/// the odds of someone needing to upgrade midway through the lifetime of a connection are very low. +public final class HTTPServerUpgradeHandler: ChannelInboundHandler, RemovableChannelHandler { + public typealias InboundIn = HTTPServerRequestPart + public typealias InboundOut = HTTPServerRequestPart + public typealias OutboundOut = HTTPServerResponsePart + + private let upgraders: [String: HTTPServerProtocolUpgrader] + private let upgradeCompletionHandler: (ChannelHandlerContext) -> Void + + private let httpEncoder: HTTPResponseEncoder? + private let extraHTTPHandlers: [RemovableChannelHandler] + + /// Whether we've already seen the first request. + private var seenFirstRequest = false + + /// The closure that should be invoked when the end of the upgrade request is received if any. + private var upgradeState: UpgradeState = .idle + private var receivedMessages: CircularBuffer = CircularBuffer() + + /// Create a `HTTPServerUpgradeHandler`. + /// + /// - Parameter upgraders: All `HTTPServerProtocolUpgrader` objects that this pipeline will be able + /// to use to handle HTTP upgrade. + /// - Parameter httpEncoder: The `HTTPResponseEncoder` encoding responses from this handler and which will + /// be removed from the pipeline once the upgrade response is sent. This is used to ensure + /// that the pipeline will be in a clean state after upgrade. + /// - Parameter extraHTTPHandlers: Any other handlers that are directly related to handling HTTP. At the very least + /// this should include the `HTTPDecoder`, but should also include any other handler that cannot tolerate + /// receiving non-HTTP data. + /// - Parameter upgradeCompletionHandler: A block that will be fired when HTTP upgrade is complete. + public init(upgraders: [HTTPServerProtocolUpgrader], httpEncoder: HTTPResponseEncoder, extraHTTPHandlers: [RemovableChannelHandler], upgradeCompletionHandler: @escaping (ChannelHandlerContext) -> Void) { + var upgraderMap = [String: HTTPServerProtocolUpgrader]() + for upgrader in upgraders { + upgraderMap[upgrader.supportedProtocol.lowercased()] = upgrader + } + self.upgraders = upgraderMap + self.upgradeCompletionHandler = upgradeCompletionHandler + self.httpEncoder = httpEncoder + self.extraHTTPHandlers = extraHTTPHandlers + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + guard !self.seenFirstRequest else { + // We're waiting for upgrade to complete: buffer this data. + self.receivedMessages.append(data) + return + } + + let requestPart = unwrapInboundIn(data) + + switch self.upgradeState { + case .idle: + self.firstRequestHeadReceived(context: context, requestPart: requestPart) + case .awaitingUpgrader: + if case .end = requestPart { + // This is the end of the first request. Swallow it, we're buffering the rest. + self.seenFirstRequest = true + } + case .upgraderReady(let upgrade): + if case .end = requestPart { + // This is the end of the first request, and we can upgrade. Time to kick it off. + self.seenFirstRequest = true + upgrade() + } + case .upgradeFailed: + // We were re-entrantly called while delivering the request head. We can just pass this through. + context.fireChannelRead(data) + case .upgradeComplete: + preconditionFailure("Upgrade has completed but we have not seen a whole request and still got re-entrantly called.") + case .upgrading: + preconditionFailure("We think we saw .end before and began upgrading, but somehow we have not set seenFirstRequest") + } + } + + public func removeHandler(context: ChannelHandlerContext, removalToken: ChannelHandlerContext.RemovalToken) { + // We have been formally removed from the pipeline. We should send any buffered data we have. + // Note that we loop twice. This is because we want to guard against being reentrantly called from fireChannelReadComplete. + while self.receivedMessages.count > 0 { + while self.receivedMessages.count > 0 { + let bufferedPart = self.receivedMessages.removeFirst() + context.fireChannelRead(bufferedPart) + } + + context.fireChannelReadComplete() + } + + context.leavePipeline(removalToken: removalToken) + } + + private func firstRequestHeadReceived(context: ChannelHandlerContext, requestPart: HTTPServerRequestPart) { + // We should decide if we're going to upgrade based on the first request header: if we aren't upgrading, + // by the time the body comes in we should be out of the pipeline. That means that if we don't think we're + // upgrading, the only thing we should see is a request head. Anything else in an error. + guard case .head(let request) = requestPart else { + context.fireErrorCaught(HTTPServerUpgradeErrors.invalidHTTPOrdering) + self.notUpgrading(context: context, data: requestPart) + return + } + + // Ok, we have a HTTP request. Check if it's an upgrade. If it's not, we want to pass it on and remove ourselves + // from the channel pipeline. + let requestedProtocols = request.headers[canonicalForm: "upgrade"].map(String.init) + guard requestedProtocols.count > 0 else { + self.notUpgrading(context: context, data: requestPart) + return + } + + // Cool, this is an upgrade request. + // We'll attempt to upgrade. This may take a while, so while we're waiting more data can come in. + self.upgradeState = .awaitingUpgrader + + self.handleUpgrade(context: context, request: request, requestedProtocols: requestedProtocols) + .hop(to: context.eventLoop) // the user might return a future from another EventLoop. + .whenSuccess { callback in + assert(context.eventLoop.inEventLoop) + if let callback = callback { + self.gotUpgrader(upgrader: callback) + } else { + self.notUpgrading(context: context, data: requestPart) + } + } + } + + /// The core of the upgrade handling logic. + /// + /// - returns: An `EventLoopFuture` that will contain a callback to invoke if upgrade is requested, or nil if upgrade has failed. Never returns a failed future. + private func handleUpgrade(context: ChannelHandlerContext, request: HTTPRequestHead, requestedProtocols: [String]) -> EventLoopFuture<(() -> Void)?> { + let connectionHeader = Set(request.headers[canonicalForm: "connection"].map { $0.lowercased() }) + let allHeaderNames = Set(request.headers.map { $0.name.lowercased() }) + + // We now set off a chain of Futures to try to find a protocol upgrade. While this is blocking, we need to buffer inbound data. + let protocolIterator = requestedProtocols.makeIterator() + return self.handleUpgradeForProtocol(context: context, protocolIterator: protocolIterator, request: request, allHeaderNames: allHeaderNames, connectionHeader: connectionHeader) + } + + /// Attempt to upgrade a single protocol. + /// + /// Will recurse through `protocolIterator` if upgrade fails. + private func handleUpgradeForProtocol(context: ChannelHandlerContext, protocolIterator: Array.Iterator, request: HTTPRequestHead, allHeaderNames: Set, connectionHeader: Set) -> EventLoopFuture<(() -> Void)?> { + // We want a local copy of the protocol iterator. We'll pass it to the next invocation of the function. + var protocolIterator = protocolIterator + guard let proto = protocolIterator.next() else { + // We're done! No suitable protocol for upgrade. + return context.eventLoop.makeSucceededFuture(nil) + } + + guard let upgrader = self.upgraders[proto.lowercased()] else { + return self.handleUpgradeForProtocol(context: context, protocolIterator: protocolIterator, request: request, allHeaderNames: allHeaderNames, connectionHeader: connectionHeader) + } + + let requiredHeaders = Set(upgrader.requiredUpgradeHeaders.map { $0.lowercased() }) + guard requiredHeaders.isSubset(of: allHeaderNames) && requiredHeaders.isSubset(of: connectionHeader) else { + return self.handleUpgradeForProtocol(context: context, protocolIterator: protocolIterator, request: request, allHeaderNames: allHeaderNames, connectionHeader: connectionHeader) + } + + let responseHeaders = self.buildUpgradeHeaders(protocol: proto) + return upgrader.buildUpgradeResponse(channel: context.channel, upgradeRequest: request, initialResponseHeaders: responseHeaders).map { finalResponseHeaders in + return { + // Ok, we're upgrading. + self.upgradeState = .upgrading + + // Before we finish the upgrade we have to remove the HTTPDecoder and any other non-Encoder HTTP + // handlers from the pipeline, to prevent them parsing any more data. We'll buffer the data until + // that completes. + // While there are a lot of Futures involved here it's quite possible that all of this code will + // actually complete synchronously: we just want to program for the possibility that it won't. + // Once that's done, we send the upgrade response, then remove the HTTP encoder, then call the + // internal handler, then call the user code, and then finally when the user code is done we do + // our final cleanup steps, namely we replay the received data we buffered in the meantime and + // then remove ourselves from the pipeline. + self.removeExtraHandlers(context: context).flatMap { + self.sendUpgradeResponse(context: context, upgradeRequest: request, responseHeaders: finalResponseHeaders) + }.flatMap { + self.removeHandler(context: context, handler: self.httpEncoder) + }.map { + self.upgradeCompletionHandler(context) + }.flatMap { + upgrader.upgrade(context: context, upgradeRequest: request) + }.map { + context.fireUserInboundEventTriggered(HTTPServerUpgradeEvents.upgradeComplete(toProtocol: proto, upgradeRequest: request)) + self.upgradeState = .upgradeComplete + }.whenComplete { (_: Result) in + // When we remove ourselves we'll be delivering any buffered data. + context.pipeline.removeHandler(context: context, promise: nil) + } + } + }.flatMapError { error in + // No upgrade here. We want to fire the error down the pipeline, and then try another loop iteration. + context.fireErrorCaught(error) + return self.handleUpgradeForProtocol(context: context, protocolIterator: protocolIterator, request: request, allHeaderNames: allHeaderNames, connectionHeader: connectionHeader) + } + } + + private func gotUpgrader(upgrader: @escaping (() -> Void)) { + switch self.upgradeState { + case .awaitingUpgrader: + self.upgradeState = .upgraderReady(upgrader) + if self.seenFirstRequest { + // Ok, we're good to go, we can upgrade. Otherwise we're waiting for .end, which + // will trigger the upgrade. + upgrader() + } + case .idle, .upgradeComplete, .upgraderReady, .upgradeFailed, .upgrading: + preconditionFailure("Unexpected upgrader state: \(self.upgradeState)") + } + } + + /// Sends the 101 Switching Protocols response for the pipeline. + private func sendUpgradeResponse(context: ChannelHandlerContext, upgradeRequest: HTTPRequestHead, responseHeaders: HTTPHeaders) -> EventLoopFuture { + var response = HTTPResponseHead(version: .http1_1, status: .switchingProtocols) + response.headers = responseHeaders + return context.writeAndFlush(wrapOutboundOut(HTTPServerResponsePart.head(response))) + } + + /// Called when we know we're not upgrading. Passes the data on and then removes this object from the pipeline. + private func notUpgrading(context: ChannelHandlerContext, data: HTTPServerRequestPart) { + self.upgradeState = .upgradeFailed + + if !self.seenFirstRequest { + // We haven't seen the first request .end. That means we're not buffering anything, and we can + // just deliver data. + assert(self.receivedMessages.isEmpty) + context.fireChannelRead(self.wrapInboundOut(data)) + } else { + // This is trickier. We've seen the first request .end, so we now need to deliver the .head we + // got passed, as well as the .end we swallowed, and any buffered parts. While we're doing this + // we may be re-entrantly called, which will cause us to buffer new parts. To make that safe, we + // must ensure we aren't holding the buffer mutably, so no for loop for us. + context.fireChannelRead(self.wrapInboundOut(data)) + context.fireChannelRead(self.wrapInboundOut(.end(nil))) + } + + context.fireChannelReadComplete() + + // Ok, we've delivered all the parts. We can now remove ourselves, which should happen synchronously. + context.pipeline.removeHandler(context: context, promise: nil) + } + + /// Builds the initial mandatory HTTP headers for HTTP upgrade responses. + private func buildUpgradeHeaders(`protocol`: String) -> HTTPHeaders { + return HTTPHeaders([("connection", "upgrade"), ("upgrade", `protocol`)]) + } + + /// Removes the given channel handler from the channel pipeline. + private func removeHandler(context: ChannelHandlerContext, handler: RemovableChannelHandler?) -> EventLoopFuture { + if let handler = handler { + return context.pipeline.removeHandler(handler) + } else { + return context.eventLoop.makeSucceededFuture(()) + } + } + + /// Removes any extra HTTP-related handlers from the channel pipeline. + private func removeExtraHandlers(context: ChannelHandlerContext) -> EventLoopFuture { + guard self.extraHTTPHandlers.count > 0 else { + return context.eventLoop.makeSucceededFuture(()) + } + + return .andAllSucceed(self.extraHTTPHandlers.map { context.pipeline.removeHandler($0) }, + on: context.eventLoop) + } +} + +extension HTTPServerUpgradeHandler { + /// The state of the upgrade handler. + private enum UpgradeState { + /// Awaiting some activity. + case idle + + /// The request head has been received. We're currently running the future chain awaiting an upgrader. + case awaitingUpgrader + + /// We have an upgrader, which means we can begin upgrade. + case upgraderReady(() -> Void) + + /// The upgrade is in process. + case upgrading + + /// The upgrade has failed, and we are being removed from the pipeline. + case upgradeFailed + + /// The upgrade has succeeded, and we are being removed from the pipeline. + case upgradeComplete + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPTypes.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPTypes.swift new file mode 100644 index 00000000..e382bba6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/HTTPTypes.swift @@ -0,0 +1,1474 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +let crlf: StaticString = "\r\n" +let headerSeparator: StaticString = ": " + +extension HTTPHeaders { + internal enum ConnectionHeaderValue { + case keepAlive + case close + case unspecified + } +} + +// Keep track of keep alive state. +internal enum KeepAliveState { + // We know keep alive should be used. + case keepAlive + // We know we should close the connection. + case close + // We need to scan the headers to find out if keep alive is used or not + case unknown +} + +/// A representation of the request line and header fields of a HTTP request. +public struct HTTPRequestHead: Equatable { + private final class _Storage { + var method: HTTPMethod + var uri: String + var version: HTTPVersion + + init(method: HTTPMethod, uri: String, version: HTTPVersion) { + self.method = method + self.uri = uri + self.version = version + } + + func copy() -> _Storage { + return .init(method: self.method, uri: self.uri, version: self.version) + } + } + + private var _storage: _Storage + + /// The header fields for this HTTP request. + // warning: do not put this in `_Storage` as it'd trigger a CoW on every mutation + public var headers: HTTPHeaders + + /// The HTTP method for this request. + public var method: HTTPMethod { + get { + return self._storage.method + } + set { + self.copyStorageIfNotUniquelyReferenced() + self._storage.method = newValue + } + } + + // This request's URI. + public var uri: String { + get { + return self._storage.uri + } + set { + self.copyStorageIfNotUniquelyReferenced() + self._storage.uri = newValue + } + } + + /// The version for this HTTP request. + public var version: HTTPVersion { + get { + return self._storage.version + } + set { + self.copyStorageIfNotUniquelyReferenced() + self._storage.version = newValue + } + } + + /// Create a `HTTPRequestHead` + /// + /// - parameters: + /// - version: The version for this HTTP request. + /// - method: The HTTP method for this request. + /// - uri: The URI used on this request. + /// - headers: This request's HTTP headers. + public init(version: HTTPVersion, method: HTTPMethod, uri: String, headers: HTTPHeaders) { + self._storage = .init(method: method, uri: uri, version: version) + self.headers = headers + } + + /// Create a `HTTPRequestHead` + /// + /// - Parameter version: The version for this HTTP request. + /// - Parameter method: The HTTP method for this request. + /// - Parameter uri: The URI used on this request. + public init(version: HTTPVersion, method: HTTPMethod, uri: String) { + self.init(version: version, method: method, uri: uri, headers: HTTPHeaders()) + } + + public static func ==(lhs: HTTPRequestHead, rhs: HTTPRequestHead) -> Bool { + return lhs.method == rhs.method && lhs.uri == rhs.uri && lhs.version == rhs.version && lhs.headers == rhs.headers + } + + private mutating func copyStorageIfNotUniquelyReferenced () { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + } +} + +/// The parts of a complete HTTP message, either request or response. +/// +/// A HTTP message is made up of a request or status line with several headers, +/// encoded by `.head`, zero or more body parts, and optionally some trailers. To +/// indicate that a complete HTTP message has been sent or received, we use `.end`, +/// which may also contain any trailers that make up the message. +public enum HTTPPart { + case head(HeadT) + case body(BodyT) + case end(HTTPHeaders?) +} + +extension HTTPPart: Equatable {} + +/// The components of a HTTP request from the view of a HTTP client. +public typealias HTTPClientRequestPart = HTTPPart + +/// The components of a HTTP request from the view of a HTTP server. +public typealias HTTPServerRequestPart = HTTPPart + +/// The components of a HTTP response from the view of a HTTP client. +public typealias HTTPClientResponsePart = HTTPPart + +/// The components of a HTTP response from the view of a HTTP server. +public typealias HTTPServerResponsePart = HTTPPart + +extension HTTPRequestHead { + /// Whether this HTTP request is a keep-alive request: that is, whether the + /// connection should remain open after the request is complete. + public var isKeepAlive: Bool { + return headers.isKeepAlive(version: version) + } +} + +extension HTTPResponseHead { + /// Whether this HTTP response is a keep-alive request: that is, whether the + /// connection should remain open after the request is complete. + public var isKeepAlive: Bool { + return self.headers.isKeepAlive(version: self.version) + } +} + +/// A representation of the status line and header fields of a HTTP response. +public struct HTTPResponseHead: Equatable { + private final class _Storage { + var status: HTTPResponseStatus + var version: HTTPVersion + init(status: HTTPResponseStatus, version: HTTPVersion) { + self.status = status + self.version = version + } + func copy() -> _Storage { + return .init(status: self.status, version: self.version) + } + } + + private var _storage: _Storage + + /// The HTTP headers on this response. + // warning: do not put this in `_Storage` as it'd trigger a CoW on every mutation + public var headers: HTTPHeaders + + /// The HTTP response status. + public var status: HTTPResponseStatus { + get { + return self._storage.status + } + set { + self.copyStorageIfNotUniquelyReferenced() + self._storage.status = newValue + } + } + + /// The HTTP version that corresponds to this response. + public var version: HTTPVersion { + get { + return self._storage.version + } + set { + self.copyStorageIfNotUniquelyReferenced() + self._storage.version = newValue + } + } + + /// Create a `HTTPResponseHead` + /// + /// - Parameter version: The version for this HTTP response. + /// - Parameter status: The status for this HTTP response. + /// - Parameter headers: The headers for this HTTP response. + public init(version: HTTPVersion, status: HTTPResponseStatus, headers: HTTPHeaders = HTTPHeaders()) { + self.headers = headers + self._storage = _Storage(status: status, version: version) + } + + public static func ==(lhs: HTTPResponseHead, rhs: HTTPResponseHead) -> Bool { + return lhs.status == rhs.status && lhs.version == rhs.version && lhs.headers == rhs.headers + } + + private mutating func copyStorageIfNotUniquelyReferenced () { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + } +} + +extension HTTPResponseHead { + /// Determines if the head is purely informational. If a head is informational another head will follow this + /// head eventually. + var isInformational: Bool { + 100 <= self.status.code && self.status.code < 200 && self.status.code != 101 + } +} + +private extension UInt8 { + var isASCII: Bool { + return self <= 127 + } +} + +extension HTTPHeaders { + func isKeepAlive(version: HTTPVersion) -> Bool { + switch self.keepAliveState { + case .close: + return false + case .keepAlive: + return true + case .unknown: + var state = KeepAliveState.unknown + for word in self[canonicalForm: "connection"] { + if word.utf8.compareCaseInsensitiveASCIIBytes(to: "close".utf8) { + // if we see multiple values, that's clearly bad and we default to 'close' + state = state != .unknown ? .close : .close + } else if word.utf8.compareCaseInsensitiveASCIIBytes(to: "keep-alive".utf8) { + // if we see multiple values, that's clearly bad and we default to 'close' + state = state != .unknown ? .close : .keepAlive + } + } + + switch state { + case .close: + return false + case .keepAlive: + return true + case .unknown: + // HTTP 1.1 use keep-alive by default if not otherwise told. + return version.major == 1 && version.minor >= 1 + } + } + } +} + +/// A representation of a block of HTTP header fields. +/// +/// HTTP header fields are a complex data structure. The most natural representation +/// for these is a sequence of two-tuples of field name and field value, both as +/// strings. This structure preserves that representation, but provides a number of +/// convenience features in addition to it. +/// +/// For example, this structure enables access to header fields based on the +/// case-insensitive form of the field name, but preserves the original case of the +/// field when needed. It also supports recomposing headers to a maximally joined +/// or split representation, such that header fields that are able to be repeated +/// can be represented appropriately. +public struct HTTPHeaders: CustomStringConvertible, ExpressibleByDictionaryLiteral { + @usableFromInline + internal var headers: [(String, String)] + internal var keepAliveState: KeepAliveState = .unknown + + public var description: String { + return self.headers.description + } + + internal var names: [String] { + return self.headers.map { $0.0 } + } + + internal init(_ headers: [(String, String)], keepAliveState: KeepAliveState) { + self.headers = headers + self.keepAliveState = keepAliveState + } + + internal func isConnectionHeader(_ name: String) -> Bool { + return name.utf8.compareCaseInsensitiveASCIIBytes(to: "connection".utf8) + } + + /// Construct a `HTTPHeaders` structure. + /// + /// - parameters + /// - headers: An initial set of headers to use to populate the header block. + /// - allocator: The allocator to use to allocate the underlying storage. + public init(_ headers: [(String, String)] = []) { + // Note: this initializer exists because of https://bugs.swift.org/browse/SR-7415. + // Otherwise we'd only have the one below with a default argument for `allocator`. + self.init(headers, keepAliveState: .unknown) + } + + /// Construct a `HTTPHeaders` structure. + /// + /// - parameters + /// - elements: name, value pairs provided by a dictionary literal. + public init(dictionaryLiteral elements: (String, String)...) { + self.init(elements) + } + + /// Add a header name/value pair to the block. + /// + /// This method is strictly additive: if there are other values for the given header name + /// already in the block, this will add a new entry. + /// + /// - Parameter name: The header field name. For maximum compatibility this should be an + /// ASCII string. For future-proofing with HTTP/2 lowercase header names are strongly + /// recommended. + /// - Parameter value: The header field value to add for the given name. + public mutating func add(name: String, value: String) { + precondition(!name.utf8.contains(where: { !$0.isASCII }), "name must be ASCII") + self.headers.append((name, value)) + if self.isConnectionHeader(name) { + self.keepAliveState = .unknown + } + } + + /// Add a sequence of header name/value pairs to the block. + /// + /// This method is strictly additive: if there are other entries with the same header + /// name already in the block, this will add new entries. + /// + /// - Parameter contentsOf: The sequence of header name/value pairs. For maximum compatibility + /// the header should be an ASCII string. For future-proofing with HTTP/2 lowercase header + /// names are strongly recommended. + @inlinable + public mutating func add(contentsOf other: S) where S.Element == (String, String) { + self.headers.reserveCapacity(self.headers.count + other.underestimatedCount) + for (name, value) in other { + self.add(name: name, value: value) + } + } + + /// Add another block of headers to the block. + /// + /// - Parameter contentsOf: The block of headers to add to these headers. + public mutating func add(contentsOf other: HTTPHeaders) { + self.headers.append(contentsOf: other.headers) + if other.keepAliveState == .unknown { + self.keepAliveState = .unknown + } + } + + /// Add a header name/value pair to the block, replacing any previous values for the + /// same header name that are already in the block. + /// + /// This is a supplemental method to `add` that essentially combines `remove` and `add` + /// in a single function. It can be used to ensure that a header block is in a + /// well-defined form without having to check whether the value was previously there. + /// Like `add`, this method performs case-insensitive comparisons of the header field + /// names. + /// + /// - Parameter name: The header field name. For maximum compatibility this should be an + /// ASCII string. For future-proofing with HTTP/2 lowercase header names are strongly + // recommended. + /// - Parameter value: The header field value to add for the given name. + public mutating func replaceOrAdd(name: String, value: String) { + if self.isConnectionHeader(name) { + self.keepAliveState = .unknown + } + self.remove(name: name) + self.add(name: name, value: value) + } + + /// Remove all values for a given header name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. + /// + /// - Parameter name: The name of the header field to remove from the block. + public mutating func remove(name nameToRemove: String) { + if self.isConnectionHeader(nameToRemove) { + self.keepAliveState = .unknown + } + self.headers.removeAll { (name, _) in + if nameToRemove.utf8.count != name.utf8.count { + return false + } + + return nameToRemove.utf8.compareCaseInsensitiveASCIIBytes(to: name.utf8) + } + } + + /// Retrieve all of the values for a give header field name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. It + /// does not return a maximally-decomposed list of the header fields, but instead + /// returns them in their original representation: that means that a comma-separated + /// header field list may contain more than one entry, some of which contain commas + /// and some do not. If you want a representation of the header fields suitable for + /// performing computation on, consider `subscript(canonicalForm:)`. + /// + /// - Parameter name: The header field name whose values are to be retrieved. + /// - Returns: A list of the values for that header field name. + public subscript(name: String) -> [String] { + return self.headers.reduce(into: []) { target, lr in + let (key, value) = lr + if key.utf8.compareCaseInsensitiveASCIIBytes(to: name.utf8) { + target.append(value) + } + } + } + + /// Retrieves the first value for a given header field name from the block. + /// + /// This method uses case-insensitive comparisons for the header field name. It + /// does not return the first value from a maximally-decomposed list of the header fields, + /// but instead returns the first value from the original representation: that means + /// that a comma-separated header field list may contain more than one entry, some of + /// which contain commas and some do not. If you want a representation of the header fields + /// suitable for performing computation on, consider `subscript(canonicalForm:)`. + /// + /// - Parameter name: The header field name whose first value should be retrieved. + /// - Returns: The first value for the header field name. + public func first(name: String) -> String? { + guard !self.headers.isEmpty else { + return nil + } + + return self.headers.first { header in header.0.isEqualCaseInsensitiveASCIIBytes(to: name) }?.1 + } + + /// Checks if a header is present + /// + /// - parameters: + /// - name: The name of the header + // - returns: `true` if a header with the name (and value) exists, `false` otherwise. + public func contains(name: String) -> Bool { + for kv in self.headers { + if kv.0.utf8.compareCaseInsensitiveASCIIBytes(to: name.utf8) { + return true + } + } + return false + } + + /// Retrieves the header values for the given header field in "canonical form": that is, + /// splitting them on commas as extensively as possible such that multiple values received on the + /// one line are returned as separate entries. Also respects the fact that Set-Cookie should not + /// be split in this way. + /// + /// - Parameter name: The header field name whose values are to be retrieved. + /// - Returns: A list of the values for that header field name. + public subscript(canonicalForm name: String) -> [Substring] { + let result = self[name] + + guard result.count > 0 else { + return [] + } + + // It's not safe to split Set-Cookie on comma. + guard name.lowercased() != "set-cookie" else { + return result.map { $0[...] } + } + + return result.flatMap { $0.split(separator: ",").map { $0.trimWhitespace() } } + } +} + +extension HTTPHeaders { + + /// The total number of headers that can be contained without allocating new storage. + public var capacity: Int { + return self.headers.capacity + } + + /// Reserves enough space to store the specified number of headers. + /// + /// - Parameter minimumCapacity: The requested number of headers to store. + public mutating func reserveCapacity(_ minimumCapacity: Int) { + self.headers.reserveCapacity(minimumCapacity) + } +} + +extension ByteBuffer { + + /// Serializes this HTTP header block to bytes suitable for writing to the wire. + /// + /// - Parameter buffer: A buffer to write the serialized bytes into. Will increment + /// the writer index of this buffer. + mutating func write(headers: HTTPHeaders) { + for header in headers.headers { + self.writeString(header.0) + self.writeStaticString(": ") + self.writeString(header.1) + self.writeStaticString("\r\n") + } + self.writeStaticString(crlf) + } +} + +extension HTTPHeaders: RandomAccessCollection { + public typealias Element = (name: String, value: String) + + public struct Index: Comparable { + fileprivate let base: Array<(String, String)>.Index + public static func < (lhs: Index, rhs: Index) -> Bool { + return lhs.base < rhs.base + } + } + + public var startIndex: HTTPHeaders.Index { + return .init(base: self.headers.startIndex) + } + + public var endIndex: HTTPHeaders.Index { + return .init(base: self.headers.endIndex) + } + + public func index(before i: HTTPHeaders.Index) -> HTTPHeaders.Index { + return .init(base: self.headers.index(before: i.base)) + } + + public func index(after i: HTTPHeaders.Index) -> HTTPHeaders.Index { + return .init(base: self.headers.index(after: i.base)) + } + + public subscript(position: HTTPHeaders.Index) -> Element { + return self.headers[position.base] + } +} + +extension UTF8.CodeUnit { + var isASCIIWhitespace: Bool { + switch self { + case UInt8(ascii: " "), + UInt8(ascii: "\t"): + return true + + default: + return false + } + } +} + +extension String { + func trimASCIIWhitespace() -> Substring { + return Substring(self).trimWhitespace() + } +} + +extension Substring { + fileprivate func trimWhitespace() -> Substring { + guard let firstNonWhitespace = self.utf8.firstIndex(where: { !$0.isASCIIWhitespace }) else { + // The whole substring is ASCII whitespace. + return Substring() + } + + // There must be at least one non-ascii whitespace character, so banging here is safe. + let lastNonWhitespace = self.utf8.lastIndex(where: { !$0.isASCIIWhitespace })! + return Substring(self.utf8[firstNonWhitespace...lastNonWhitespace]) + } +} + +extension HTTPHeaders: Equatable { + public static func ==(lhs: HTTPHeaders, rhs: HTTPHeaders) -> Bool { + guard lhs.headers.count == rhs.headers.count else { + return false + } + let lhsNames = Set(lhs.names.map { $0.lowercased() }) + let rhsNames = Set(rhs.names.map { $0.lowercased() }) + guard lhsNames == rhsNames else { + return false + } + + for name in lhsNames { + guard lhs[name].sorted() == rhs[name].sorted() else { + return false + } + } + + return true + } +} + +public enum HTTPMethod: Equatable { + internal enum HasBody { + case yes + case no + case unlikely + } + + case GET + case PUT + case ACL + case HEAD + case POST + case COPY + case LOCK + case MOVE + case BIND + case LINK + case PATCH + case TRACE + case MKCOL + case MERGE + case PURGE + case NOTIFY + case SEARCH + case UNLOCK + case REBIND + case UNBIND + case REPORT + case DELETE + case UNLINK + case CONNECT + case MSEARCH + case OPTIONS + case PROPFIND + case CHECKOUT + case PROPPATCH + case SUBSCRIBE + case MKCALENDAR + case MKACTIVITY + case UNSUBSCRIBE + case SOURCE + case RAW(value: String) + + /// Whether requests with this verb may have a request body. + internal var hasRequestBody: HasBody { + switch self { + case .TRACE: + return .no + case .POST, .PUT, .PATCH: + return .yes + case .GET, .CONNECT, .OPTIONS, .HEAD, .DELETE: + fallthrough + default: + return .unlikely + } + } +} + +/// A structure representing a HTTP version. +public struct HTTPVersion: Equatable { + /// Create a HTTP version. + /// + /// - Parameter major: The major version number. + /// - Parameter minor: The minor version number. + public init(major: Int, minor: Int) { + self._major = UInt16(major) + self._minor = UInt16(minor) + } + + private var _minor: UInt16 + private var _major: UInt16 + + /// The major version number. + public var major: Int { + get { + return Int(self._major) + } + set { + self._major = UInt16(newValue) + } + } + + /// The minor version number. + public var minor: Int { + get { + return Int(self._minor) + } + set { + self._minor = UInt16(newValue) + } + } + + /// HTTP/3 + public static let http3 = HTTPVersion(major: 3, minor: 0) + + /// HTTP/2 + public static let http2 = HTTPVersion(major: 2, minor: 0) + + /// HTTP/1.1 + public static let http1_1 = HTTPVersion(major: 1, minor: 1) + + /// HTTP/1.0 + public static let http1_0 = HTTPVersion(major: 1, minor: 0) + + /// HTTP/0.9 (not supported by SwiftNIO) + public static let http0_9 = HTTPVersion(major: 0, minor: 9) +} + +extension HTTPParserError: CustomDebugStringConvertible { + public var debugDescription: String { + switch self { + case .invalidCharactersUsed: + return "illegal characters used in URL/headers" + case .trailingGarbage: + return "trailing garbage bytes" + case .invalidEOFState: + return "stream ended at an unexpected time" + case .headerOverflow: + return "too many header bytes seen; overflow detected" + case .closedConnection: + return "data received after completed connection: close message" + case .invalidVersion: + return "invalid HTTP version" + case .invalidStatus: + return "invalid HTTP status code" + case .invalidMethod: + return "invalid HTTP method" + case .invalidURL: + return "invalid URL" + case .invalidHost: + return "invalid host" + case .invalidPort: + return "invalid port" + case .invalidPath: + return "invalid path" + case .invalidQueryString: + return "invalid query string" + case .invalidFragment: + return "invalid fragment" + case .lfExpected: + return "LF character expected" + case .invalidHeaderToken: + return "invalid character in header" + case .invalidContentLength: + return "invalid character in content-length header" + case .unexpectedContentLength: + return "unexpected content-length header" + case .invalidChunkSize: + return "invalid character in chunk size header" + case .invalidConstant: + return "invalid constant string" + case .invalidInternalState: + return "invalid internal state (swift-http-parser error)" + case .strictModeAssertion: + return "strict mode assertion" + case .paused: + return "paused (swift-http-parser error)" + case .unknown: + return "unknown (http_parser error)" + } + } +} + +/// Errors that can be raised while parsing HTTP/1.1. +public enum HTTPParserError: Error { + case invalidCharactersUsed + case trailingGarbage + /* from CHTTPParser */ + case invalidEOFState + case headerOverflow + case closedConnection + case invalidVersion + case invalidStatus + case invalidMethod + case invalidURL + case invalidHost + case invalidPort + case invalidPath + case invalidQueryString + case invalidFragment + case lfExpected + case invalidHeaderToken + case invalidContentLength + case unexpectedContentLength + case invalidChunkSize + case invalidConstant + case invalidInternalState + case strictModeAssertion + case paused + case unknown +} + +extension HTTPResponseStatus { + /// The numerical status code for a given HTTP response status. + public var code: UInt { + get { + switch self { + case .continue: + return 100 + case .switchingProtocols: + return 101 + case .processing: + return 102 + case .ok: + return 200 + case .created: + return 201 + case .accepted: + return 202 + case .nonAuthoritativeInformation: + return 203 + case .noContent: + return 204 + case .resetContent: + return 205 + case .partialContent: + return 206 + case .multiStatus: + return 207 + case .alreadyReported: + return 208 + case .imUsed: + return 226 + case .multipleChoices: + return 300 + case .movedPermanently: + return 301 + case .found: + return 302 + case .seeOther: + return 303 + case .notModified: + return 304 + case .useProxy: + return 305 + case .temporaryRedirect: + return 307 + case .permanentRedirect: + return 308 + case .badRequest: + return 400 + case .unauthorized: + return 401 + case .paymentRequired: + return 402 + case .forbidden: + return 403 + case .notFound: + return 404 + case .methodNotAllowed: + return 405 + case .notAcceptable: + return 406 + case .proxyAuthenticationRequired: + return 407 + case .requestTimeout: + return 408 + case .conflict: + return 409 + case .gone: + return 410 + case .lengthRequired: + return 411 + case .preconditionFailed: + return 412 + case .payloadTooLarge: + return 413 + case .uriTooLong: + return 414 + case .unsupportedMediaType: + return 415 + case .rangeNotSatisfiable: + return 416 + case .expectationFailed: + return 417 + case .imATeapot: + return 418 + case .misdirectedRequest: + return 421 + case .unprocessableEntity: + return 422 + case .locked: + return 423 + case .failedDependency: + return 424 + case .upgradeRequired: + return 426 + case .preconditionRequired: + return 428 + case .tooManyRequests: + return 429 + case .requestHeaderFieldsTooLarge: + return 431 + case .unavailableForLegalReasons: + return 451 + case .internalServerError: + return 500 + case .notImplemented: + return 501 + case .badGateway: + return 502 + case .serviceUnavailable: + return 503 + case .gatewayTimeout: + return 504 + case .httpVersionNotSupported: + return 505 + case .variantAlsoNegotiates: + return 506 + case .insufficientStorage: + return 507 + case .loopDetected: + return 508 + case .notExtended: + return 510 + case .networkAuthenticationRequired: + return 511 + case .custom(code: let code, reasonPhrase: _): + return code + } + } + } + + /// The string reason phrase for a given HTTP response status. + public var reasonPhrase: String { + get { + switch self { + case .continue: + return "Continue" + case .switchingProtocols: + return "Switching Protocols" + case .processing: + return "Processing" + case .ok: + return "OK" + case .created: + return "Created" + case .accepted: + return "Accepted" + case .nonAuthoritativeInformation: + return "Non-Authoritative Information" + case .noContent: + return "No Content" + case .resetContent: + return "Reset Content" + case .partialContent: + return "Partial Content" + case .multiStatus: + return "Multi-Status" + case .alreadyReported: + return "Already Reported" + case .imUsed: + return "IM Used" + case .multipleChoices: + return "Multiple Choices" + case .movedPermanently: + return "Moved Permanently" + case .found: + return "Found" + case .seeOther: + return "See Other" + case .notModified: + return "Not Modified" + case .useProxy: + return "Use Proxy" + case .temporaryRedirect: + return "Temporary Redirect" + case .permanentRedirect: + return "Permanent Redirect" + case .badRequest: + return "Bad Request" + case .unauthorized: + return "Unauthorized" + case .paymentRequired: + return "Payment Required" + case .forbidden: + return "Forbidden" + case .notFound: + return "Not Found" + case .methodNotAllowed: + return "Method Not Allowed" + case .notAcceptable: + return "Not Acceptable" + case .proxyAuthenticationRequired: + return "Proxy Authentication Required" + case .requestTimeout: + return "Request Timeout" + case .conflict: + return "Conflict" + case .gone: + return "Gone" + case .lengthRequired: + return "Length Required" + case .preconditionFailed: + return "Precondition Failed" + case .payloadTooLarge: + return "Payload Too Large" + case .uriTooLong: + return "URI Too Long" + case .unsupportedMediaType: + return "Unsupported Media Type" + case .rangeNotSatisfiable: + return "Range Not Satisfiable" + case .expectationFailed: + return "Expectation Failed" + case .imATeapot: + return "I'm a teapot" + case .misdirectedRequest: + return "Misdirected Request" + case .unprocessableEntity: + return "Unprocessable Entity" + case .locked: + return "Locked" + case .failedDependency: + return "Failed Dependency" + case .upgradeRequired: + return "Upgrade Required" + case .preconditionRequired: + return "Precondition Required" + case .tooManyRequests: + return "Too Many Requests" + case .requestHeaderFieldsTooLarge: + return "Request Header Fields Too Large" + case .unavailableForLegalReasons: + return "Unavailable For Legal Reasons" + case .internalServerError: + return "Internal Server Error" + case .notImplemented: + return "Not Implemented" + case .badGateway: + return "Bad Gateway" + case .serviceUnavailable: + return "Service Unavailable" + case .gatewayTimeout: + return "Gateway Timeout" + case .httpVersionNotSupported: + return "HTTP Version Not Supported" + case .variantAlsoNegotiates: + return "Variant Also Negotiates" + case .insufficientStorage: + return "Insufficient Storage" + case .loopDetected: + return "Loop Detected" + case .notExtended: + return "Not Extended" + case .networkAuthenticationRequired: + return "Network Authentication Required" + case .custom(code: _, reasonPhrase: let phrase): + return phrase + } + } + } +} + +/// A HTTP response status code. +public enum HTTPResponseStatus { + /* use custom if you want to use a non-standard response code or + have it available in a (UInt, String) pair from a higher-level web framework. */ + case custom(code: UInt, reasonPhrase: String) + + /* all the codes from http://www.iana.org/assignments/http-status-codes */ + + // 1xx + case `continue` + case switchingProtocols + case processing + // TODO: add '103: Early Hints' (requires bumping SemVer major). + + // 2xx + case ok + case created + case accepted + case nonAuthoritativeInformation + case noContent + case resetContent + case partialContent + case multiStatus + case alreadyReported + case imUsed + + // 3xx + case multipleChoices + case movedPermanently + case found + case seeOther + case notModified + case useProxy + case temporaryRedirect + case permanentRedirect + + // 4xx + case badRequest + case unauthorized + case paymentRequired + case forbidden + case notFound + case methodNotAllowed + case notAcceptable + case proxyAuthenticationRequired + case requestTimeout + case conflict + case gone + case lengthRequired + case preconditionFailed + case payloadTooLarge + case uriTooLong + case unsupportedMediaType + case rangeNotSatisfiable + case expectationFailed + case imATeapot + case misdirectedRequest + case unprocessableEntity + case locked + case failedDependency + case upgradeRequired + case preconditionRequired + case tooManyRequests + case requestHeaderFieldsTooLarge + case unavailableForLegalReasons + + // 5xx + case internalServerError + case notImplemented + case badGateway + case serviceUnavailable + case gatewayTimeout + case httpVersionNotSupported + case variantAlsoNegotiates + case insufficientStorage + case loopDetected + case notExtended + case networkAuthenticationRequired + + /// Whether responses with this status code may have a response body. + public var mayHaveResponseBody: Bool { + switch self { + case .`continue`, + .switchingProtocols, + .processing, + .noContent, + .custom where (code < 200) && (code >= 100): + return false + default: + return true + } + } + + /// Initialize a `HTTPResponseStatus` from a given status and reason. + /// + /// - Parameter statusCode: The integer value of the HTTP response status code + /// - Parameter reasonPhrase: The textual reason phrase from the response. This will be + /// discarded in favor of the default if the `statusCode` matches one that we know. + public init(statusCode: Int, reasonPhrase: String = "") { + switch statusCode { + case 100: + self = .`continue` + case 101: + self = .switchingProtocols + case 102: + self = .processing + case 200: + self = .ok + case 201: + self = .created + case 202: + self = .accepted + case 203: + self = .nonAuthoritativeInformation + case 204: + self = .noContent + case 205: + self = .resetContent + case 206: + self = .partialContent + case 207: + self = .multiStatus + case 208: + self = .alreadyReported + case 226: + self = .imUsed + case 300: + self = .multipleChoices + case 301: + self = .movedPermanently + case 302: + self = .found + case 303: + self = .seeOther + case 304: + self = .notModified + case 305: + self = .useProxy + case 307: + self = .temporaryRedirect + case 308: + self = .permanentRedirect + case 400: + self = .badRequest + case 401: + self = .unauthorized + case 402: + self = .paymentRequired + case 403: + self = .forbidden + case 404: + self = .notFound + case 405: + self = .methodNotAllowed + case 406: + self = .notAcceptable + case 407: + self = .proxyAuthenticationRequired + case 408: + self = .requestTimeout + case 409: + self = .conflict + case 410: + self = .gone + case 411: + self = .lengthRequired + case 412: + self = .preconditionFailed + case 413: + self = .payloadTooLarge + case 414: + self = .uriTooLong + case 415: + self = .unsupportedMediaType + case 416: + self = .rangeNotSatisfiable + case 417: + self = .expectationFailed + case 418: + self = .imATeapot + case 421: + self = .misdirectedRequest + case 422: + self = .unprocessableEntity + case 423: + self = .locked + case 424: + self = .failedDependency + case 426: + self = .upgradeRequired + case 428: + self = .preconditionRequired + case 429: + self = .tooManyRequests + case 431: + self = .requestHeaderFieldsTooLarge + case 451: + self = .unavailableForLegalReasons + case 500: + self = .internalServerError + case 501: + self = .notImplemented + case 502: + self = .badGateway + case 503: + self = .serviceUnavailable + case 504: + self = .gatewayTimeout + case 505: + self = .httpVersionNotSupported + case 506: + self = .variantAlsoNegotiates + case 507: + self = .insufficientStorage + case 508: + self = .loopDetected + case 510: + self = .notExtended + case 511: + self = .networkAuthenticationRequired + default: + self = .custom(code: UInt(statusCode), reasonPhrase: reasonPhrase) + } + } +} + +extension HTTPResponseStatus: Equatable {} + +extension HTTPResponseStatus: Hashable {} + +extension HTTPRequestHead: CustomStringConvertible { + public var description: String { + return "HTTPRequestHead { method: \(self.method), uri: \"\(self.uri)\", version: \(self.version), headers: \(self.headers) }" + } +} + +extension HTTPResponseHead: CustomStringConvertible { + public var description: String { + return "HTTPResponseHead { version: \(self.version), status: \(self.status), headers: \(self.headers) }" + } +} + +extension HTTPVersion: CustomStringConvertible { + public var description: String { + return "HTTP/\(self.major).\(self.minor)" + } +} + +extension HTTPMethod: RawRepresentable { + public var rawValue: String { + switch self { + case .GET: + return "GET" + case .PUT: + return "PUT" + case .ACL: + return "ACL" + case .HEAD: + return "HEAD" + case .POST: + return "POST" + case .COPY: + return "COPY" + case .LOCK: + return "LOCK" + case .MOVE: + return "MOVE" + case .BIND: + return "BIND" + case .LINK: + return "LINK" + case .PATCH: + return "PATCH" + case .TRACE: + return "TRACE" + case .MKCOL: + return "MKCOL" + case .MERGE: + return "MERGE" + case .PURGE: + return "PURGE" + case .NOTIFY: + return "NOTIFY" + case .SEARCH: + return "SEARCH" + case .UNLOCK: + return "UNLOCK" + case .REBIND: + return "REBIND" + case .UNBIND: + return "UNBIND" + case .REPORT: + return "REPORT" + case .DELETE: + return "DELETE" + case .UNLINK: + return "UNLINK" + case .CONNECT: + return "CONNECT" + case .MSEARCH: + return "MSEARCH" + case .OPTIONS: + return "OPTIONS" + case .PROPFIND: + return "PROPFIND" + case .CHECKOUT: + return "CHECKOUT" + case .PROPPATCH: + return "PROPPATCH" + case .SUBSCRIBE: + return "SUBSCRIBE" + case .MKCALENDAR: + return "MKCALENDAR" + case .MKACTIVITY: + return "MKACTIVITY" + case .UNSUBSCRIBE: + return "UNSUBSCRIBE" + case .SOURCE: + return "SOURCE" + case let .RAW(value): + return value + } + } + + public init(rawValue: String) { + switch rawValue { + case "GET": + self = .GET + case "PUT": + self = .PUT + case "ACL": + self = .ACL + case "HEAD": + self = .HEAD + case "POST": + self = .POST + case "COPY": + self = .COPY + case "LOCK": + self = .LOCK + case "MOVE": + self = .MOVE + case "BIND": + self = .BIND + case "LINK": + self = .LINK + case "PATCH": + self = .PATCH + case "TRACE": + self = .TRACE + case "MKCOL": + self = .MKCOL + case "MERGE": + self = .MERGE + case "PURGE": + self = .PURGE + case "NOTIFY": + self = .NOTIFY + case "SEARCH": + self = .SEARCH + case "UNLOCK": + self = .UNLOCK + case "REBIND": + self = .REBIND + case "UNBIND": + self = .UNBIND + case "REPORT": + self = .REPORT + case "DELETE": + self = .DELETE + case "UNLINK": + self = .UNLINK + case "CONNECT": + self = .CONNECT + case "MSEARCH": + self = .MSEARCH + case "OPTIONS": + self = .OPTIONS + case "PROPFIND": + self = .PROPFIND + case "CHECKOUT": + self = .CHECKOUT + case "PROPPATCH": + self = .PROPPATCH + case "SUBSCRIBE": + self = .SUBSCRIBE + case "MKCALENDAR": + self = .MKCALENDAR + case "MKACTIVITY": + self = .MKACTIVITY + case "UNSUBSCRIBE": + self = .UNSUBSCRIBE + case "SOURCE": + self = .SOURCE + default: + self = .RAW(value: rawValue) + } + } +} + +extension HTTPResponseHead { + internal var contentLength: Int? { + return headers.contentLength + } +} + +extension HTTPRequestHead { + internal var contentLength: Int? { + return headers.contentLength + } +} + +extension HTTPHeaders { + internal var contentLength: Int? { + return self.first(name: "content-length").flatMap { Int($0) } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPClientUpgradeHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPClientUpgradeHandler.swift new file mode 100644 index 00000000..e2b082df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPClientUpgradeHandler.swift @@ -0,0 +1,396 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// Errors that may be raised by the `HTTPClientProtocolUpgrader`. +public struct NIOHTTPClientUpgradeError: Hashable, Error { + + // Uses the open enum style to allow additional errors to be added in future. + private enum Code: Hashable { + case responseProtocolNotFound + case invalidHTTPOrdering + case upgraderDeniedUpgrade + case writingToHandlerDuringUpgrade + case writingToHandlerAfterUpgradeCompleted + case writingToHandlerAfterUpgradeFailed + case receivedResponseBeforeRequestSent + case receivedResponseAfterUpgradeCompleted + } + + private var code: Code + + private init(_ code: Code) { + self.code = code + } + + public static let responseProtocolNotFound = NIOHTTPClientUpgradeError(.responseProtocolNotFound) + public static let invalidHTTPOrdering = NIOHTTPClientUpgradeError(.invalidHTTPOrdering) + public static let upgraderDeniedUpgrade = NIOHTTPClientUpgradeError(.upgraderDeniedUpgrade) + public static let writingToHandlerDuringUpgrade = NIOHTTPClientUpgradeError(.writingToHandlerDuringUpgrade) + public static let writingToHandlerAfterUpgradeCompleted = NIOHTTPClientUpgradeError(.writingToHandlerAfterUpgradeCompleted) + public static let writingToHandlerAfterUpgradeFailed = NIOHTTPClientUpgradeError(.writingToHandlerAfterUpgradeFailed) + public static let receivedResponseBeforeRequestSent = NIOHTTPClientUpgradeError(.receivedResponseBeforeRequestSent) + public static let receivedResponseAfterUpgradeCompleted = NIOHTTPClientUpgradeError(.receivedResponseAfterUpgradeCompleted) +} + +extension NIOHTTPClientUpgradeError: CustomStringConvertible { + public var description: String { + return String(describing: self.code) + } +} + +/// An object that implements `NIOHTTPClientProtocolUpgrader` knows how to handle HTTP upgrade to +/// a protocol on a client-side channel. +/// It has the option of denying this upgrade based upon the server response. +public protocol NIOHTTPClientProtocolUpgrader { + + /// The protocol this upgrader knows how to support. + var supportedProtocol: String { get } + + /// All the header fields the protocol requires in the request to successfully upgrade. + /// These header fields will be added to the outbound request's "Connection" header field. + /// It is the responsibility of the custom headers call to actually add these required headers. + var requiredUpgradeHeaders: [String] { get } + + /// Additional headers to be added to the request, beyond the "Upgrade" and "Connection" headers. + func addCustom(upgradeRequestHeaders: inout HTTPHeaders) + + /// Gives the receiving upgrader the chance to deny the upgrade based on the upgrade HTTP response. + func shouldAllowUpgrade(upgradeResponse: HTTPResponseHead) -> Bool + + /// Called when the upgrade response has been flushed. At this time it is safe to mutate the channel + /// pipeline to add whatever channel handlers are required. + /// Until the returned `EventLoopFuture` succeeds, all received data will be buffered. + func upgrade(context: ChannelHandlerContext, upgradeResponse: HTTPResponseHead) -> EventLoopFuture +} + +/// A client-side channel handler that sends a HTTP upgrade handshake request to perform a HTTP-upgrade. +/// When the first HTTP request is sent, this handler will add all appropriate headers to perform an upgrade to +/// the a protocol. It may add headers for a set of protocols in preference order. +/// If the upgrade fails (i.e. response is not 101 Switching Protocols), this handler simply +/// removes itself from the pipeline. If the upgrade is successful, it upgrades the pipeline to the new protocol. +/// +/// The request sends an order of preference to request which protocol it would like to use for the upgrade. +/// It will only upgrade to the protocol that is returned first in the list and does not currently +/// have the capability to upgrade to multiple simultaneous layered protocols. +public final class NIOHTTPClientUpgradeHandler: ChannelDuplexHandler, RemovableChannelHandler { + + public typealias OutboundIn = HTTPClientRequestPart + public typealias OutboundOut = HTTPClientRequestPart + + public typealias InboundIn = HTTPClientResponsePart + public typealias InboundOut = HTTPClientResponsePart + + private var upgraders: [NIOHTTPClientProtocolUpgrader] + private let httpHandlers: [RemovableChannelHandler] + private let upgradeCompletionHandler: (ChannelHandlerContext) -> Void + + /// Whether we've already seen the first response from our initial upgrade request. + private var seenFirstResponse = false + + private var upgradeState: UpgradeState = .requestRequired + + private var receivedMessages: CircularBuffer = CircularBuffer() + + /// Create a `HTTPClientUpgradeHandler`. + /// + /// - Parameter upgraders: All `HTTPClientProtocolUpgrader` objects that will add their upgrade request + /// headers and handle the upgrade if there is a response for their protocol. They should be placed in + /// order of the preference for the upgrade. + /// - Parameter httpHandlers: All `RemovableChannelHandler` objects which will be removed from the pipeline + /// once the upgrade response is sent. This is used to ensure that the pipeline will be in a clean state + /// after the upgrade. It should include any handlers that are directly related to handling HTTP. + /// At the very least this should include the `HTTPEncoder` and `HTTPDecoder`, but should also include + /// any other handler that cannot tolerate receiving non-HTTP data. + /// - Parameter upgradeCompletionHandler: A closure that will be fired when HTTP upgrade is complete. + public init(upgraders: [NIOHTTPClientProtocolUpgrader], + httpHandlers: [RemovableChannelHandler], + upgradeCompletionHandler: @escaping (ChannelHandlerContext) -> Void) { + + precondition(upgraders.count > 0, "A minimum of one protocol upgrader must be specified.") + + self.upgraders = upgraders + self.httpHandlers = httpHandlers + self.upgradeCompletionHandler = upgradeCompletionHandler + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + + switch self.upgradeState { + + case .requestRequired: + let updatedData = self.addHeadersToOutboundOut(data: data) + context.write(updatedData, promise: promise) + + case .awaitingConfirmationResponse: + // Still have full http stack. + context.write(data, promise: promise) + + case .upgraderReady, .upgrading: + promise?.fail(NIOHTTPClientUpgradeError.writingToHandlerDuringUpgrade) + context.fireErrorCaught(NIOHTTPClientUpgradeError.writingToHandlerDuringUpgrade) + + case .upgradingAddingHandlers: + // These are most likely messages immediately fired by a new protocol handler. + // As that is added last we can just forward them on. + context.write(data, promise: promise) + + case .upgradeComplete: + // Upgrade complete and this handler should have been removed from the pipeline. + promise?.fail(NIOHTTPClientUpgradeError.writingToHandlerAfterUpgradeCompleted) + context.fireErrorCaught(NIOHTTPClientUpgradeError.writingToHandlerAfterUpgradeCompleted) + + case .upgradeFailed: + // Upgrade failed and this handler should have been removed from the pipeline. + promise?.fail(NIOHTTPClientUpgradeError.writingToHandlerAfterUpgradeCompleted) + context.fireErrorCaught(NIOHTTPClientUpgradeError.writingToHandlerAfterUpgradeCompleted) + } + } + + private func addHeadersToOutboundOut(data: NIOAny) -> NIOAny { + + let interceptedOutgoingRequest = self.unwrapOutboundIn(data) + + if case .head(var requestHead) = interceptedOutgoingRequest { + + self.upgradeState = .awaitingConfirmationResponse + + self.addConnectionHeaders(to: &requestHead) + self.addUpgradeHeaders(to: &requestHead) + return self.wrapOutboundOut(.head(requestHead)) + } + + return data + } + + private func addConnectionHeaders(to requestHead: inout HTTPRequestHead) { + + let requiredHeaders = ["upgrade"] + self.upgraders.flatMap { $0.requiredUpgradeHeaders } + requestHead.headers.add(name: "Connection", value: requiredHeaders.joined(separator: ",")) + } + + private func addUpgradeHeaders(to requestHead: inout HTTPRequestHead) { + + let allProtocols = self.upgraders.map { $0.supportedProtocol.lowercased() } + requestHead.headers.add(name: "Upgrade", value: allProtocols.joined(separator: ",")) + + // Allow each upgrader the chance to add custom headers. + for upgrader in self.upgraders { + upgrader.addCustom(upgradeRequestHeaders: &requestHead.headers) + } + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + + guard !self.seenFirstResponse else { + // We're waiting for upgrade to complete: buffer this data. + self.receivedMessages.append(data) + return + } + + let responsePart = unwrapInboundIn(data) + + switch self.upgradeState { + case .awaitingConfirmationResponse: + self.firstResponseHeadReceived(context: context, responsePart: responsePart) + case .upgrading, .upgradingAddingHandlers: + if case .end = responsePart { + // This is the end of the first response. Swallow it, we're buffering the rest. + self.seenFirstResponse = true + } + case .upgraderReady(let upgrade): + if case .end = responsePart { + // This is the end of the first response, and we can upgrade. Time to kick it off. + self.seenFirstResponse = true + upgrade() + } + case .upgradeFailed: + // We were reentrantly called while delivering the response head. We can just pass this through. + context.fireChannelRead(data) + case .upgradeComplete: + //Upgrade has completed but we have not seen a whole response and still got reentrantly called. + context.fireErrorCaught(NIOHTTPClientUpgradeError.receivedResponseAfterUpgradeCompleted) + case .requestRequired: + //We are receiving an upgrade response and we have not requested the upgrade. + context.fireErrorCaught(NIOHTTPClientUpgradeError.receivedResponseBeforeRequestSent) + } + } + + private func firstResponseHeadReceived(context: ChannelHandlerContext, responsePart: HTTPClientResponsePart) { + + // We should decide if we're can upgrade based on the first response header: if we aren't upgrading, + // by the time the body comes in we should be out of the pipeline. That means that if we don't think we're + // upgrading, the only thing we should see is a response head. Anything else in an error. + guard case .head(let response) = responsePart else { + self.notUpgrading(context: context, data: responsePart, error: .invalidHTTPOrdering) + return + } + + // Assess whether the upgrade response has accepted our upgrade request. + guard case .switchingProtocols = response.status else { + self.notUpgrading(context: context, data: responsePart, error: nil) + return + } + + do { + let callback = try self.handleUpgrade(context: context, upgradeResponse: response) + self.gotUpgrader(upgrader: callback) + } catch { + let clientError = error as? NIOHTTPClientUpgradeError + self.notUpgrading(context: context, data: responsePart, error: clientError) + } + } + + private func handleUpgrade(context: ChannelHandlerContext, upgradeResponse response: HTTPResponseHead) throws -> (() -> Void) { + + // Ok, we have a HTTP response. Check if it's an upgrade confirmation. + // If it's not, we want to pass it on and remove ourselves from the channel pipeline. + let acceptedProtocols = response.headers[canonicalForm: "upgrade"] + + // At the moment we only upgrade to the first protocol returned from the server. + guard let protocolName = acceptedProtocols.first?.lowercased() else { + // There are no upgrade protocols returned. + throw NIOHTTPClientUpgradeError.responseProtocolNotFound + } + + return try self.handleUpgradeForProtocol(context: context, + protocolName: protocolName, + response: response) + } + + /// Attempt to upgrade a single protocol. + private func handleUpgradeForProtocol(context: ChannelHandlerContext, protocolName: String, response: HTTPResponseHead) throws -> (() -> Void) { + + let matchingUpgrader = self.upgraders + .first(where: { $0.supportedProtocol.lowercased() == protocolName }) + + guard let upgrader = matchingUpgrader else { + // There is no upgrader for this protocol. + throw NIOHTTPClientUpgradeError.responseProtocolNotFound + } + + guard upgrader.shouldAllowUpgrade(upgradeResponse: response) else { + // The upgrader says no. + throw NIOHTTPClientUpgradeError.upgraderDeniedUpgrade + } + + return self.performUpgrade(context: context, upgrader: upgrader, response: response) + } + + private func performUpgrade(context: ChannelHandlerContext, upgrader: NIOHTTPClientProtocolUpgrader, response: HTTPResponseHead) -> () -> Void { + + // Before we start the upgrade we have to remove the HTTPEncoder and HTTPDecoder handlers from the + // pipeline, to prevent them parsing any more data. We'll buffer the incoming data until that completes. + // While there are a lot of Futures involved here it's quite possible that all of this code will + // actually complete synchronously: we just want to program for the possibility that it won't. + // Once that's done, we call the internal handler, then call the upgrader code, and then finally when the + // upgrader code is done, we do our final cleanup steps, namely we replay the received data we + // buffered in the meantime and then remove ourselves from the pipeline. + return { + self.upgradeState = .upgrading + + self.removeHTTPHandlers(context: context) + .map { + // Let the other handlers be removed before continuing with upgrade. + self.upgradeCompletionHandler(context) + self.upgradeState = .upgradingAddingHandlers + } + .flatMap { + upgrader.upgrade(context: context, upgradeResponse: response) + } + .map { + // We unbuffer any buffered data here. + + // If we received any, we fire readComplete. + let fireReadComplete = self.receivedMessages.count > 0 + while self.receivedMessages.count > 0 { + let bufferedPart = self.receivedMessages.removeFirst() + context.fireChannelRead(bufferedPart) + } + if fireReadComplete { + context.fireChannelReadComplete() + } + + // We wait with the state change until _after_ the channel reads here. + // This is to prevent firing writes in response to these reads after we went to .upgradeComplete + // See: https://github.com/apple/swift-nio/issues/1279 + self.upgradeState = .upgradeComplete + } + .whenComplete { _ in + context.pipeline.removeHandler(context: context, promise: nil) + } + } + } + + /// Removes any extra HTTP-related handlers from the channel pipeline. + private func removeHTTPHandlers(context: ChannelHandlerContext) -> EventLoopFuture { + guard self.httpHandlers.count > 0 else { + return context.eventLoop.makeSucceededFuture(()) + } + + let removeFutures = self.httpHandlers.map { context.pipeline.removeHandler($0) } + return .andAllSucceed(removeFutures, on: context.eventLoop) + } + + private func gotUpgrader(upgrader: @escaping (() -> Void)) { + + self.upgradeState = .upgraderReady(upgrader) + if self.seenFirstResponse { + // Ok, we're good to go, we can upgrade. Otherwise we're waiting for .end, which + // will trigger the upgrade. + upgrader() + } + } + + private func notUpgrading(context: ChannelHandlerContext, data: HTTPClientResponsePart, error: NIOHTTPClientUpgradeError?) { + + self.upgradeState = .upgradeFailed + + if let error = error { + context.fireErrorCaught(error) + } + + assert(self.receivedMessages.isEmpty) + context.fireChannelRead(self.wrapInboundOut(data)) + + // We've delivered the data. We can now remove ourselves, which should happen synchronously. + context.pipeline.removeHandler(context: context, promise: nil) + } +} + +extension NIOHTTPClientUpgradeHandler { + /// The state of the upgrade handler. + fileprivate enum UpgradeState { + /// Request not sent. This will need to be sent to initiate the upgrade. + case requestRequired + + /// Awaiting confirmation response which will allow the upgrade to zero one or more protocols. + case awaitingConfirmationResponse + + /// The response head has been received. We have an upgrader, which means we can begin upgrade. + case upgraderReady(() -> Void) + + /// The response head has been received. The upgrade is in process. + case upgrading + + /// The upgrade is in process and all of the http handlers have been removed. + case upgradingAddingHandlers + + /// The upgrade has succeeded, and we are being removed from the pipeline. + case upgradeComplete + + /// The upgrade has failed. + case upgradeFailed + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPObjectAggregator.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPObjectAggregator.swift new file mode 100644 index 00000000..fec32d47 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP1/Sources/NIOHTTP1/NIOHTTPObjectAggregator.swift @@ -0,0 +1,399 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// The parts of a complete HTTP response from the view of the client. +/// +/// A full HTTP request is made up of a response header encoded by `.head` +/// and an optional `.body`. +public struct NIOHTTPServerRequestFull { + public var head: HTTPRequestHead + public var body: ByteBuffer? + + public init(head: HTTPRequestHead, body: ByteBuffer?) { + self.head = head + self.body = body + } +} + +extension NIOHTTPServerRequestFull: Equatable {} + +/// The parts of a complete HTTP response from the view of the client. +/// +/// A full HTTP response is made up of a response header encoded by `.head` +/// and an optional `.body`. +public struct NIOHTTPClientResponseFull { + public var head: HTTPResponseHead + public var body: ByteBuffer? + + public init(head: HTTPResponseHead, body: ByteBuffer?) { + self.head = head + self.body = body + } +} + +extension NIOHTTPClientResponseFull: Equatable {} + +public struct NIOHTTPObjectAggregatorError: Error, Equatable { + private enum Base { + case frameTooLong + case connectionClosed + case endingIgnoredMessage + case unexpectedMessageHead + case unexpectedMessageBody + case unexpectedMessageEnd + } + + private var base: Base + + private init(base: Base) { + self.base = base + } + + public static let frameTooLong = NIOHTTPObjectAggregatorError(base: .frameTooLong) + public static let connectionClosed = NIOHTTPObjectAggregatorError(base: .connectionClosed) + public static let endingIgnoredMessage = NIOHTTPObjectAggregatorError(base: .endingIgnoredMessage) + public static let unexpectedMessageHead = NIOHTTPObjectAggregatorError(base: .unexpectedMessageHead) + public static let unexpectedMessageBody = NIOHTTPObjectAggregatorError(base: .unexpectedMessageBody) + public static let unexpectedMessageEnd = NIOHTTPObjectAggregatorError(base: .unexpectedMessageEnd) +} + +public struct NIOHTTPObjectAggregatorEvent: Hashable { + private enum Base { + case httpExpectationFailed + case httpFrameTooLong + } + + private var base: Base + + private init(base: Base) { + self.base = base + } + + public static let httpExpectationFailed = NIOHTTPObjectAggregatorEvent(base: .httpExpectationFailed) + public static let httpFrameTooLong = NIOHTTPObjectAggregatorEvent(base: .httpFrameTooLong) +} + +/// The state of the aggregator connection. +internal enum AggregatorState { + /// Nothing is active on this connection, the next message we expect would be a request `.head`. + case idle + + /// Ill-behaving client may be sending content that is too large + case ignoringContent + + /// We are receiving and aggregating a request + case receiving + + /// Connection should be closed + case closed + + mutating func messageHeadReceived() throws { + switch self { + case .idle: + self = .receiving + case .ignoringContent, .receiving: + throw NIOHTTPObjectAggregatorError.unexpectedMessageHead + case .closed: + throw NIOHTTPObjectAggregatorError.connectionClosed + } + } + + mutating func messageBodyReceived() throws { + switch self { + case .receiving: + () + case .ignoringContent: + throw NIOHTTPObjectAggregatorError.frameTooLong + case .idle: + throw NIOHTTPObjectAggregatorError.unexpectedMessageBody + case .closed: + throw NIOHTTPObjectAggregatorError.connectionClosed + } + } + + + mutating func messageEndReceived() throws { + switch self { + case .receiving: + // Got the request end we were waiting for. + self = .idle + case .ignoringContent: + // Expected transition from a state where message contents are getting + // ignored because the message is too large. Throwing an error prevents + // the normal control flow from continuing into dispatching the completed + // invalid message to the next handler. + self = .idle + throw NIOHTTPObjectAggregatorError.endingIgnoredMessage + case .idle: + throw NIOHTTPObjectAggregatorError.unexpectedMessageEnd + case .closed: + throw NIOHTTPObjectAggregatorError.connectionClosed + } + } + + mutating func handlingOversizeMessage() { + switch self { + case .receiving, .idle: + self = .ignoringContent + case .ignoringContent, .closed: + // If we are already ignoring content or connection is closed, should not get here + preconditionFailure("Unreachable state: should never handle overized message in \(self)") + } + } + + mutating func closed() { + self = .closed + } +} + +/// A `ChannelInboundHandler` that handles HTTP chunked `HTTPServerRequestPart` +/// messages by aggregating individual message chunks into a single +/// `NIOHTTPServerRequestFull`. +/// +/// This is achieved by buffering the contents of all received `HTTPServerRequestPart` +/// messages until `HTTPServerRequestPart.end` is received, then assembling the +/// full message and firing a channel read upstream with it. It is useful for when you do not +/// want to deal with chunked messages and just want to receive everything at once, and +/// are happy with the additional memory used and delay handling of the message until +/// everything has been received. +/// +/// `NIOHTTPServerRequestAggregator` may end up sending a `HTTPResponseHead`: +/// - Response status `413 Request Entity Too Large` when either the +/// `content-length` or the bytes received so far exceed `maxContentLength`. +/// +/// `NIOHTTPServerRequestAggregator` may close the connection if it is impossible +/// to recover: +/// - If `content-length` is too large and `keep-alive` is off. +/// - If the bytes received exceed `maxContentLength` and the client didn't signal +/// `content-length` +public final class NIOHTTPServerRequestAggregator: ChannelInboundHandler, RemovableChannelHandler { + public typealias InboundIn = HTTPServerRequestPart + public typealias InboundOut = NIOHTTPServerRequestFull + + // Aggregator may generate responses of its own + public typealias OutboundOut = HTTPServerResponsePart + + private var fullMessageHead: HTTPRequestHead? = nil + private var buffer: ByteBuffer! = nil + private var maxContentLength: Int + private var closeOnExpectationFailed: Bool + private var state: AggregatorState + + public init(maxContentLength: Int, closeOnExpectationFailed: Bool = false) { + precondition(maxContentLength >= 0, "maxContentLength must not be negative") + self.maxContentLength = maxContentLength + self.closeOnExpectationFailed = closeOnExpectationFailed + self.state = .idle + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let msg = self.unwrapInboundIn(data) + var serverResponse: HTTPResponseHead? = nil + + do { + switch msg { + case .head(let httpHead): + try self.state.messageHeadReceived() + serverResponse = self.beginAggregation(context: context, request: httpHead, message: msg) + case .body(var content): + try self.state.messageBodyReceived() + serverResponse = self.aggregate(context: context, content: &content, message: msg) + case .end(let trailingHeaders): + try self.state.messageEndReceived() + self.endAggregation(context: context, trailingHeaders: trailingHeaders) + } + } catch let error as NIOHTTPObjectAggregatorError { + context.fireErrorCaught(error) + // Won't be able to complete those + self.fullMessageHead = nil + self.buffer.clear() + } catch let error { + context.fireErrorCaught(error) + } + + // Generated a server response to send back + if let response = serverResponse { + context.write(self.wrapOutboundOut(.head(response)), promise: nil) + context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil) + if response.status == .payloadTooLarge { + // If indicated content length is too large + self.state.handlingOversizeMessage() + context.fireErrorCaught(NIOHTTPObjectAggregatorError.frameTooLong) + context.fireUserInboundEventTriggered(NIOHTTPObjectAggregatorEvent.httpFrameTooLong) + } + if !response.headers.isKeepAlive(version: response.version) { + context.close(promise: nil) + self.state.closed() + } + } + } + + private func beginAggregation(context: ChannelHandlerContext, request: HTTPRequestHead, message: InboundIn) -> HTTPResponseHead? { + self.fullMessageHead = request + if let contentLength = request.contentLength, contentLength > self.maxContentLength { + return self.handleOversizeMessage(message: message) + } + return nil + } + + private func aggregate(context: ChannelHandlerContext, content: inout ByteBuffer, message: InboundIn) -> HTTPResponseHead? { + if (content.readableBytes > self.maxContentLength - self.buffer.readableBytes) { + return self.handleOversizeMessage(message: message) + } else { + self.buffer.writeBuffer(&content) + return nil + } + } + + private func endAggregation(context: ChannelHandlerContext, trailingHeaders: HTTPHeaders?) { + if var aggregated = self.fullMessageHead { + // Remove `Trailer` from existing header fields and append trailer fields to existing header fields + // See rfc7230 4.1.3 Decoding Chunked + if let headers = trailingHeaders { + aggregated.headers.remove(name: "trailer") + aggregated.headers.add(contentsOf: headers) + } + + let fullMessage = NIOHTTPServerRequestFull(head: aggregated, + body: self.buffer.readableBytes > 0 ? self.buffer : nil) + self.fullMessageHead = nil + self.buffer.clear() + context.fireChannelRead(NIOAny(fullMessage)) + } + } + + private func handleOversizeMessage(message: InboundIn) -> HTTPResponseHead { + var payloadTooLargeHead = HTTPResponseHead( + version: self.fullMessageHead?.version ?? .http1_1, + status: .payloadTooLarge, + headers: HTTPHeaders([("content-length", "0")])) + + switch message { + case .head(let request): + if !request.isKeepAlive { + // If keep-alive is off and, no need to leave the connection open. + // Send back a 413 and close the connection. + payloadTooLargeHead.headers.add(name: "connection", value: "close") + } + default: + // The client started to send data already, close because it's impossible to recover. + // Send back a 413 and close the connection. + payloadTooLargeHead.headers.add(name: "connection", value: "close") + } + + return payloadTooLargeHead + } + + public func handlerAdded(context: ChannelHandlerContext) { + self.buffer = context.channel.allocator.buffer(capacity: 0) + } +} + +/// A `ChannelInboundHandler` that handles HTTP chunked `HTTPClientResponsePart` +/// messages by aggregating individual message chunks into a single +/// `NIOHTTPClientResponseFull`. +/// +/// This is achieved by buffering the contents of all received `HTTPClientResponsePart` +/// messages until `HTTPClientResponsePart.end` is received, then assembling the +/// full message and firing a channel read upstream with it. Useful when you do not +/// want to deal with chunked messages and just want to receive everything at once, and +/// are happy with the additional memory used and delay handling of the message until +/// everything has been received. +/// +/// If `NIOHTTPClientResponseAggregator` encounters a message larger than +/// `maxContentLength`, it discards the aggregated contents until the next +/// `HTTPClientResponsePart.end` and signals that via +/// `fireUserInboundEventTriggered`. +public final class NIOHTTPClientResponseAggregator: ChannelInboundHandler, RemovableChannelHandler { + public typealias InboundIn = HTTPClientResponsePart + public typealias InboundOut = NIOHTTPClientResponseFull + + private var fullMessageHead: HTTPResponseHead? = nil + private var buffer: ByteBuffer! = nil + private var maxContentLength: Int + private var state: AggregatorState + + public init(maxContentLength: Int) { + precondition(maxContentLength >= 0, "maxContentLength must not be negative") + self.maxContentLength = maxContentLength + self.state = .idle + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let msg = self.unwrapInboundIn(data) + + do { + switch msg { + case .head(let httpHead): + try self.state.messageHeadReceived() + try self.beginAggregation(context: context, response: httpHead) + case .body(var content): + try self.state.messageBodyReceived() + try self.aggregate(context: context, content: &content) + case .end(let trailingHeaders): + try self.state.messageEndReceived() + self.endAggregation(context: context, trailingHeaders: trailingHeaders) + } + } catch let error as NIOHTTPObjectAggregatorError { + context.fireErrorCaught(error) + // Won't be able to complete those + self.fullMessageHead = nil + self.buffer.clear() + } catch let error { + context.fireErrorCaught(error) + } + } + + private func beginAggregation(context: ChannelHandlerContext, response: HTTPResponseHead) throws { + self.fullMessageHead = response + if let contentLength = response.contentLength, contentLength > self.maxContentLength { + self.state.handlingOversizeMessage() + context.fireUserInboundEventTriggered(NIOHTTPObjectAggregatorEvent.httpFrameTooLong) + context.fireErrorCaught(NIOHTTPObjectAggregatorError.frameTooLong) + } + } + + private func aggregate(context: ChannelHandlerContext, content: inout ByteBuffer) throws { + if (content.readableBytes > self.maxContentLength - self.buffer.readableBytes) { + self.state.handlingOversizeMessage() + context.fireUserInboundEventTriggered(NIOHTTPObjectAggregatorEvent.httpFrameTooLong) + context.fireErrorCaught(NIOHTTPObjectAggregatorError.frameTooLong) + } else { + self.buffer.writeBuffer(&content) + } + } + + private func endAggregation(context: ChannelHandlerContext, trailingHeaders: HTTPHeaders?) { + if var aggregated = self.fullMessageHead { + // Remove `Trailer` from existing header fields and append trailer fields to existing header fields + // See rfc7230 4.1.3 Decoding Chunked + if let headers = trailingHeaders { + aggregated.headers.remove(name: "trailer") + aggregated.headers.add(contentsOf: headers) + } + + let fullMessage = NIOHTTPClientResponseFull( + head: aggregated, + body: self.buffer.readableBytes > 0 ? self.buffer : nil) + self.fullMessageHead = nil + self.buffer.clear() + context.fireChannelRead(NIOAny(fullMessage)) + } + } + + public func handlerAdded(context: ChannelHandlerContext) { + self.buffer = context.channel.allocator.buffer(capacity: 0) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/README.md new file mode 100644 index 00000000..8c22e164 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/README.md @@ -0,0 +1,37 @@ +# SwiftNIO HTTP/2 + +This project contains HTTP/2 support for Swift projects using [SwiftNIO](https://github.com/apple/swift-nio). To get started, check the [API docs](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html). + +## Building + +`swift-nio-http2` is a SwiftPM project and can be built and tested very simply: + +```bash +$ swift build +$ swift test +``` + +## Versions + +Just like the rest of the SwiftNIO family, swift-nio-http2 follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document +declaring [SwiftNIO's Public API](https://github.com/apple/swift-nio/blob/main/docs/public-api.md). + +### `swift-nio-http2` 1.x + +`swift-nio-http2` versions 1.x are a pure-Swift implementation of the HTTP/2 protocol for SwiftNIO. It's part of the SwiftNIO 2 family of repositories and does not have any dependencies besides [`swift-nio`](https://github.com/apple/swift-nio) and Swift 5. As the latest version, it lives on the [`main`](https://github.com/apple/swift-nio-http2) branch. + +To depend on `swift-nio-http2`, put the following in the `dependencies` of your `Package.swift`: + + .package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.19.2"), + +SwiftNIO HTTP2 1.21.x and later support Swift 5.4 and above. 1.20.x and earlier also support Swift 5.2 and 5.3. 1.17.x and earlier also support Swift 5.0 and 5.1. + +### `swift-nio-http2` 0.x + +The legacy `swift-nio-http` 0.x is part of the SwiftNIO 1 family of repositories and works on Swift 4.1 and newer but requires [nghttp2](https://nghttp2.org) to be installed on your system. The source code can be found on the [`nghttp2-support-branch`](https://github.com/apple/swift-nio-http2/tree/nghttp2-support-branch). + + +## Developing SwiftNIO HTTP/2 + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see [`CONTRIBUTING.md`](/CONTRIBUTING.md) in this repository. + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStateMachine.swift new file mode 100644 index 00000000..d5438866 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStateMachine.swift @@ -0,0 +1,1749 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore +import NIOHPACK + +/// A state machine that governs the connection-level state of a HTTP/2 connection. +/// +/// ### Overview +/// +/// A HTTP/2 protocol implementation is fundamentally built on a pair of interlocking state machines: +/// one for the connection as a whole, and then one for each stream on the connection. All frames sent +/// and received on a HTTP/2 connection cause state transitions in either or both of these state +/// machines, and the set of valid state transitions in these state machines forms the complete set of +/// valid frame sequences in HTTP/2. +/// +/// Not all frames need to pass through both state machines. As a general heuristic, if a frame carries a +/// stream ID field, it must pass through both the connection state machine and the stream state machine for +/// the associated stream. If it does not, then it must only pass through the connection state machine. This +/// is not a *complete* description of the way the connection behaves (see the note about PRIORITY frames +/// below), but it's a good enough operating heuristic to get through the rest of the code. +/// +/// The stream state machine is handled by `HTTP2StreamStateMachine`. +/// +/// ### Function +/// +/// The responsibilities of this state machine are as follows: +/// +/// 1) Manage the connection setup process, ensuring that the approriate client/server preamble is sent and +/// received. +/// 2) Manage the inbound and outbound connection flow control windows. +/// 3) Keep track of the bi-directional values of HTTP/2 settings. +/// 4) Manage connection cleanup, shutdown, and quiescing. +/// +/// ### Implementation +/// +/// All state associated with a HTTP/2 connection lives inside a single Swift enum. This enum constrains when +/// state is available, ensuring that it is not possible to query data that is not meaningful in the given state. +/// Operations on this state machine occur by calling specific functions on the structure, which will spin the +/// enum as needed and perform whatever state transitions are required. +/// +/// #### PRIORITY frames +/// +/// A brief digression is required on HTTP/2 PRIORITY frames. These frames appear to be sent "on" a specific +/// stream, as they carry a stream ID like all other stream-specific frames. However, unlike all other stream +/// specific frames they can be sent for streams in *any* state (including idle and fullyQuiesced, meaning they can +/// be sent for streams that have never existed or that passed away long ago), and have no effect on the stream +/// state (causing no state transitions). They only ever affect the priority tree, which neither this object nor +/// any of the streams actually maintains. +/// +/// For this reason, PRIORITY frames do not actually participate in the stream state machine: only the +/// connection one. This is unlike all other frames that carry stream IDs. Essentially, they are connection-scoped +/// frames that just incidentally have a stream ID on them, rather than stream-scoped frames like all the others. +struct HTTP2ConnectionStateMachine { + /// The state required for a connection that is currently idle. + fileprivate struct IdleConnectionState: ConnectionStateWithRole, ConnectionStateWithConfiguration { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + } + + /// The state required for a connection that has sent a connection preface. + fileprivate struct PrefaceSentState: ConnectionStateWithRole, ConnectionStateWithConfiguration, MaySendFrames, HasLocalSettings, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var localInitialWindowSize: UInt32 { + return HTTP2SettingsState.defaultInitialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + init(fromIdle idleState: IdleConnectionState, localSettings settings: HTTP2SettingsState) { + self.role = idleState.role + self.headerBlockValidation = idleState.headerBlockValidation + self.contentLengthValidation = idleState.contentLengthValidation + self.localSettings = settings + self.streamState = ConnectionStreamState() + + self.inboundFlowControlWindow = HTTP2FlowControlWindow(initialValue: settings.initialWindowSize) + self.outboundFlowControlWindow = HTTP2FlowControlWindow(initialValue: HTTP2SettingsState.defaultInitialWindowSize) + } + } + + /// The state required for a connection that has received a connection preface. + fileprivate struct PrefaceReceivedState: ConnectionStateWithRole, ConnectionStateWithConfiguration, MayReceiveFrames, HasRemoteSettings, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return HTTP2SettingsState.defaultInitialWindowSize + } + + init(fromIdle idleState: IdleConnectionState, remoteSettings settings: HTTP2SettingsState) { + self.role = idleState.role + self.headerBlockValidation = idleState.headerBlockValidation + self.contentLengthValidation = idleState.contentLengthValidation + self.remoteSettings = settings + self.streamState = ConnectionStreamState() + + self.inboundFlowControlWindow = HTTP2FlowControlWindow(initialValue: HTTP2SettingsState.defaultInitialWindowSize) + self.outboundFlowControlWindow = HTTP2FlowControlWindow(initialValue: settings.initialWindowSize) + } + } + + /// The state required for a connection that is active. + fileprivate struct ActiveConnectionState: ConnectionStateWithRole, ConnectionStateWithConfiguration, MaySendFrames, MayReceiveFrames, HasLocalSettings, HasRemoteSettings, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + init(fromPrefaceReceived state: PrefaceReceivedState, localSettings settings: HTTP2SettingsState) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.localSettings = settings + + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.inboundFlowControlWindow = state.inboundFlowControlWindow + } + + init(fromPrefaceSent state: PrefaceSentState, remoteSettings settings: HTTP2SettingsState) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.streamState = state.streamState + self.remoteSettings = settings + + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.inboundFlowControlWindow = state.inboundFlowControlWindow + } + } + + /// The state required for a connection that is quiescing, but where the local peer has not yet sent its + /// preface. + fileprivate struct QuiescingPrefaceReceivedState: ConnectionStateWithRole, ConnectionStateWithConfiguration, RemotelyQuiescingState, MayReceiveFrames, HasRemoteSettings, QuiescingState, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var lastLocalStreamID: HTTP2StreamID + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return HTTP2SettingsState.defaultInitialWindowSize + } + + var quiescedByServer: Bool { + return self.role == .client + } + + init(fromPrefaceReceived state: PrefaceReceivedState, lastStreamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + + self.lastLocalStreamID = lastStreamID + } + } + + /// The state required for a connection that is quiescing, but where the remote peer has not yet sent its + /// preface. + fileprivate struct QuiescingPrefaceSentState: ConnectionStateWithRole, ConnectionStateWithConfiguration, LocallyQuiescingState, MaySendFrames, HasLocalSettings, QuiescingState, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var lastRemoteStreamID: HTTP2StreamID + + var localInitialWindowSize: UInt32 { + return HTTP2SettingsState.defaultInitialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + var quiescedByServer: Bool { + return self.role == .server + } + + init(fromPrefaceSent state: PrefaceSentState, lastStreamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + + self.lastRemoteStreamID = lastStreamID + } + } + + /// The state required for a connection that is quiescing due to the remote peer quiescing the connection. + fileprivate struct RemotelyQuiescedState: ConnectionStateWithRole, ConnectionStateWithConfiguration, RemotelyQuiescingState, MayReceiveFrames, MaySendFrames, HasLocalSettings, HasRemoteSettings, QuiescingState, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var lastLocalStreamID: HTTP2StreamID + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + var quiescedByServer: Bool { + return self.role == .client + } + + init(fromActive state: ActiveConnectionState, lastLocalStreamID streamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastLocalStreamID = streamID + } + + init(fromQuiescingPrefaceReceived state: QuiescingPrefaceReceivedState, localSettings settings: HTTP2SettingsState) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.remoteSettings = state.remoteSettings + self.localSettings = settings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastLocalStreamID = state.lastLocalStreamID + } + } + + /// The state required for a connection that is quiescing due to the local user quiescing the connection. + fileprivate struct LocallyQuiescedState: ConnectionStateWithRole, ConnectionStateWithConfiguration, LocallyQuiescingState, MaySendFrames, MayReceiveFrames, HasLocalSettings, HasRemoteSettings, QuiescingState, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + + var lastRemoteStreamID: HTTP2StreamID + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + var quiescedByServer: Bool { + return self.role == .server + } + + init(fromActive state: ActiveConnectionState, lastRemoteStreamID streamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastRemoteStreamID = streamID + } + + init(fromQuiescingPrefaceSent state: QuiescingPrefaceSentState, remoteSettings settings: HTTP2SettingsState) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.remoteSettings = settings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastRemoteStreamID = state.lastRemoteStreamID + } + } + + /// The state required for a connection that is quiescing due to both peers sending GOAWAY. + fileprivate struct BothQuiescingState: ConnectionStateWithRole, ConnectionStateWithConfiguration, LocallyQuiescingState, RemotelyQuiescingState, MaySendFrames, MayReceiveFrames, HasLocalSettings, HasRemoteSettings, QuiescingState, HasFlowControlWindows { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var localSettings: HTTP2SettingsState + var remoteSettings: HTTP2SettingsState + var streamState: ConnectionStreamState + var inboundFlowControlWindow: HTTP2FlowControlWindow + var outboundFlowControlWindow: HTTP2FlowControlWindow + var lastLocalStreamID: HTTP2StreamID + var lastRemoteStreamID: HTTP2StreamID + + var localInitialWindowSize: UInt32 { + return self.remoteSettings.initialWindowSize + } + + var remoteInitialWindowSize: UInt32 { + return self.localSettings.initialWindowSize + } + + var quiescedByServer: Bool { + return true + } + + init(fromRemotelyQuiesced state: RemotelyQuiescedState, lastRemoteStreamID streamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastLocalStreamID = state.lastLocalStreamID + + self.lastRemoteStreamID = streamID + } + + init(fromLocallyQuiesced state: LocallyQuiescedState, lastLocalStreamID streamID: HTTP2StreamID) { + self.role = state.role + self.headerBlockValidation = state.headerBlockValidation + self.contentLengthValidation = state.contentLengthValidation + self.localSettings = state.localSettings + self.remoteSettings = state.remoteSettings + self.streamState = state.streamState + self.inboundFlowControlWindow = state.inboundFlowControlWindow + self.outboundFlowControlWindow = state.outboundFlowControlWindow + self.lastRemoteStreamID = state.lastRemoteStreamID + + self.lastLocalStreamID = streamID + } + } + + /// The state required for a connection that has completely quiesced. + fileprivate struct FullyQuiescedState: ConnectionStateWithRole, ConnectionStateWithConfiguration, LocallyQuiescingState, RemotelyQuiescingState, SendAndReceiveGoawayState { + let role: ConnectionRole + var headerBlockValidation: ValidationState + var contentLengthValidation: ValidationState + var streamState: ConnectionStreamState + var lastLocalStreamID: HTTP2StreamID + var lastRemoteStreamID: HTTP2StreamID + + init(previousState: PreviousState) { + self.role = previousState.role + self.headerBlockValidation = previousState.headerBlockValidation + self.contentLengthValidation = previousState.contentLengthValidation + self.streamState = previousState.streamState + self.lastLocalStreamID = previousState.lastLocalStreamID + self.lastRemoteStreamID = previousState.lastRemoteStreamID + } + + init(previousState: PreviousState) { + self.role = previousState.role + self.headerBlockValidation = previousState.headerBlockValidation + self.contentLengthValidation = previousState.contentLengthValidation + self.streamState = previousState.streamState + self.lastLocalStreamID = .maxID + self.lastRemoteStreamID = previousState.lastRemoteStreamID + } + + init(previousState: PreviousState) { + self.role = previousState.role + self.headerBlockValidation = previousState.headerBlockValidation + self.contentLengthValidation = previousState.contentLengthValidation + self.streamState = previousState.streamState + self.lastLocalStreamID = previousState.lastLocalStreamID + self.lastRemoteStreamID = .maxID + } + } + + fileprivate enum State { + /// The connection has not begun yet. This state is usually used while the underlying transport connection + /// is being established. No data can be sent or received at this time. + case idle(IdleConnectionState) + + /// Our preface has been sent, and we are awaiting the preface from the remote peer. In general we're more + /// likely to enter this state as a client than a server, but users may choose to reduce latency by + /// aggressively emitting the server preface before the client preface has been received. In either case, + /// in this state we are waiting for the remote peer to send its preface. + case prefaceSent(PrefaceSentState) + + /// We have received a preface from the remote peer, and we are waiting to send our own preface. In general + /// we're more likely to enter this state as a server than as a client, but remote peers may be attempting + /// to reduce latency by aggressively emitting the server preface before they have received our preface. + /// In either case, in this state we are waiting for the local user to emit the preface. + case prefaceReceived(PrefaceReceivedState) + + /// Both peers have exchanged their preface and the connection is fully active. In this state new streams + /// may be created, potentially by either peer, and the connection is fully useable. + case active(ActiveConnectionState) + + /// The remote peer has sent a GOAWAY frame that quiesces the connection, preventing the creation of new + /// streams. However, there are still active streams that have been allowed to complete, so the connection + /// is not entirely inactive. + case remotelyQuiesced(RemotelyQuiescedState) + + /// The local user has sent a GOAWAY frame that quiesces the connection, preventing the creation of new + /// streams. However, there are still active streams that have been allowed to complete, so the connection + /// is not entirely inactive. + case locallyQuiesced(LocallyQuiescedState) + + /// Both peers have emitted a GOAWAY frame that quiesces the connection, preventing the creation of new + /// streams. However, there are still active streams that have been allowed to complete, so the connection + /// is not entirely inactive. + case bothQuiescing(BothQuiescingState) + + /// We have sent our preface, and sent a GOAWAY, but we haven't received the remote preface yet. + /// This is a weird state, unlikely to be encountered in most programs, but it's technically possible. + case quiescingPrefaceSent(QuiescingPrefaceSentState) + + /// We have received a preface, and received a GOAWAY, but we haven't sent our preface yet. + /// This is a weird state, unlikely to be encountered in most programs, but it's technically possible. + case quiescingPrefaceReceived(QuiescingPrefaceReceivedState) + + /// The connection has completed, either cleanly or with an error. In this state, no further activity may + /// occur on the connection. + case fullyQuiesced(FullyQuiescedState) + + /// This is not a real state: it's used when we are in the middle of a function invocation, to avoid CoWs + /// when modifying the associated data. + case modifying + } + + /// The possible roles an endpoint may play in a connection. + enum ConnectionRole { + case server + case client + } + + /// The state of a specific validation option. + enum ValidationState { + case enabled + case disabled + } + + private var state: State + + init(role: ConnectionRole, headerBlockValidation: ValidationState = .enabled, contentLengthValidation: ValidationState = .enabled) { + self.state = .idle(.init(role: role, headerBlockValidation: headerBlockValidation, contentLengthValidation: contentLengthValidation)) + } + + /// Whether this connection is closed. + var fullyQuiesced: Bool { + switch self.state { + case .fullyQuiesced: + return true + default: + return false + } + } + + /// Whether the preamble can be sent. + var mustSendPreamble: Bool { + switch self.state { + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + return true + default: + return false + } + } +} + +// MARK:- State modifying methods +// +// These methods form the implementation of the public API of the HTTP2ConnectionStateMachine. Each of these methods +// performs a state transition, and can be used to validate that a specific action is acceptable on a connection in this state. +extension HTTP2ConnectionStateMachine { + /// Called when a SETTINGS frame has been received from the remote peer + mutating func receiveSettings(_ payload: HTTP2Frame.FramePayload.Settings, frameEncoder: inout HTTP2FrameEncoder, frameDecoder: inout HTTP2FrameDecoder) -> (StateMachineResultWithEffect, PostFrameOperation) { + switch payload { + case .ack: + // No action is ever required after receiving a settings ACK + return (self.receiveSettingsAck(frameEncoder: &frameEncoder), .nothing) + case .settings(let settings): + return self.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + } + } + + /// Called when the user has sent a settings update. + /// + /// Note that this function assumes that this is not a settings ACK, as settings ACK frames are not + /// allowed to be sent by the user. They are always emitted by the implementation. + mutating func sendSettings(_ settings: HTTP2Settings) -> StateMachineResultWithEffect { + let validationResult = self.validateSettings(settings) + + guard case .succeed = validationResult else { + return .init(result: validationResult, effect: nil) + } + + switch self.state { + case .idle(let state): + self.avoidingStateMachineCoW { newState in + var settingsState = HTTP2SettingsState(localState: true) + settingsState.emitSettings(settings) + newState = .prefaceSent(.init(fromIdle: state, localSettings: settingsState)) + } + + case .prefaceReceived(let state): + self.avoidingStateMachineCoW { newState in + var settingsState = HTTP2SettingsState(localState: true) + settingsState.emitSettings(settings) + newState = .active(.init(fromPrefaceReceived: state, localSettings: settingsState)) + } + + case .prefaceSent(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .prefaceSent(state) + } + + case .active(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .active(state) + } + + case .quiescingPrefaceSent(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .quiescingPrefaceSent(state) + } + + case .quiescingPrefaceReceived(let state): + self.avoidingStateMachineCoW { newState in + var settingsState = HTTP2SettingsState(localState: true) + settingsState.emitSettings(settings) + newState = .remotelyQuiesced(.init(fromQuiescingPrefaceReceived: state, localSettings: settingsState)) + } + + case .remotelyQuiesced(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .remotelyQuiesced(state) + } + + case .locallyQuiesced(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .locallyQuiesced(state) + } + + case .bothQuiescing(var state): + self.avoidingStateMachineCoW { newState in + state.localSettings.emitSettings(settings) + newState = .bothQuiescing(state) + } + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + + return .init(result: .succeed, effect: nil) + } + + /// Called when a HEADERS frame has been received from the remote peer. + mutating func receiveHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // If we're still waiting for the remote preface, they are not allowed to send us a HEADERS frame yet! + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + // Called when a HEADERS frame has been sent by the local user. + mutating func sendHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .prefaceSent(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendHeaders(streamID: streamID, headers: headers, isEndStreamSet: endStream) + newState = .quiescingPrefaceSent(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // If we're still waiting for the local preface, we are not allowed to send a HEADERS frame yet! + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a DATA frame has been received. + mutating func receiveData(streamID: HTTP2StreamID, contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // If we're still waiting for the remote preface, we are not allowed to receive a DATA frame yet! + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a user is trying to send a DATA frame. + mutating func sendData(streamID: HTTP2StreamID, contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .prefaceSent(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendData(streamID: streamID, contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + newState = .quiescingPrefaceSent(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // If we're still waiting for the local preface, we are not allowed to send a DATA frame yet! + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + func receivePriority() -> StateMachineResultWithEffect { + // So long as we've received the preamble and haven't fullyQuiesced, a PRIORITY frame is basically always + // an acceptable thing to receive. The only rule is that it mustn't form a cycle in the priority + // tree, but we don't maintain enough state in this object to enforce that. + switch self.state { + case .prefaceReceived, .active, .locallyQuiesced, .remotelyQuiesced, .bothQuiescing, .quiescingPrefaceReceived: + return StateMachineResultWithEffect(result: .succeed, effect: nil) + + case .idle, .prefaceSent, .quiescingPrefaceSent: + return StateMachineResultWithEffect(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return StateMachineResultWithEffect(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + func sendPriority() -> StateMachineResultWithEffect { + // So long as we've sent the preamble and haven't fullyQuiesced, a PRIORITY frame is basically always + // an acceptable thing to send. The only rule is that it mustn't form a cycle in the priority + // tree, but we don't maintain enough state in this object to enforce that. + switch self.state { + case .prefaceSent, .active, .locallyQuiesced, .remotelyQuiesced, .bothQuiescing, .quiescingPrefaceSent: + return .init(result: .succeed, effect: nil) + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a RST_STREAM frame has been received. + mutating func receiveRstStream(streamID: HTTP2StreamID, reason: HTTP2ErrorCode) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveRstStream(streamID: streamID, reason: reason) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // We're waiting for the remote preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when sending a RST_STREAM frame. + mutating func sendRstStream(streamID: HTTP2StreamID, reason: HTTP2ErrorCode) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .prefaceSent(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendRstStream(streamID: streamID, reason: reason) + newState = .quiescingPrefaceSent(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // We're waiting for the local preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a PUSH_PROMISE frame has been initiated on a given stream. + /// + /// If this method returns a stream error, the stream error should be assumed to apply to both the original + /// and child stream. + mutating func receivePushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + // In states that support a push promise we have two steps. Firstly, we want to create the child stream; then we want to + // pass the PUSH_PROMISE frame through the stream state machine for the parent stream. + // + // The reason we do things in this order is that if for any reason the PUSH_PROMISE frame is invalid on the parent stream, + // we want to take out both the child stream and the parent stream. We can only do that if we have a child stream state to + // modify. For this reason, we unconditionally allow the remote peer to consume the stream. The only case where this is *not* + // true is when the child stream itself cannot be validly created, because the stream ID used by the remote peer is invalid. + // In this case this is a connection error, anyway, so we don't worry too much about it. + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .locallyQuiesced(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .remotelyQuiesced(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .bothQuiescing(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // We're waiting for the remote preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + mutating func sendPushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendPushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .prefaceSent(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendPushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendPushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .locallyQuiesced(state) + return result + } + + case .remotelyQuiesced, .bothQuiescing: + // We have been quiesced, and may not create new streams. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.createdStreamAfterGoaway(), type: .protocolError), effect: nil) + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendPushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + newState = .quiescingPrefaceSent(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // We're waiting for the local preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a PING frame has been received from the network. + mutating func receivePing(ackFlagSet: Bool) -> (StateMachineResultWithEffect, PostFrameOperation) { + // Pings are pretty straightforward: they're basically always allowed. This is a bit weird, but I can find no text in + // RFC 7540 that says that receiving PINGs with ACK flags set when no PING ACKs are expected is forbidden. This is + // very strange, but we allow it. + switch self.state { + case .prefaceReceived, .active, .locallyQuiesced, .remotelyQuiesced, .bothQuiescing, .quiescingPrefaceReceived: + return (.init(result: .succeed, effect: nil), ackFlagSet ? .nothing : .sendAck) + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // We're waiting for the remote preface. + return (.init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil), .nothing) + + case .fullyQuiesced: + return (.init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil), .nothing) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a PING frame is about to be sent. + mutating func sendPing() -> StateMachineResultWithEffect { + // Pings are pretty straightforward: they're basically always allowed. This is a bit weird, but I can find no text in + // RFC 7540 that says that sending PINGs with ACK flags set when no PING ACKs are expected is forbidden. This is + // very strange, but we allow it. + switch self.state { + case .prefaceSent, .active, .locallyQuiesced, .remotelyQuiesced, .bothQuiescing, .quiescingPrefaceSent: + return .init(result: .succeed, effect: nil) + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // We're waiting for the local preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + + /// Called when we receive a GOAWAY frame. + mutating func receiveGoaway(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + // GOAWAY frames are some of the most subtle frames in HTTP/2, they cause a number of state transitions all at once. + // In particular, the value of lastStreamID heavily affects the state transitions we perform here. + // In this case, all streams initiated by us that have stream IDs higher than lastStreamID will be closed, effective + // immediately. If this leaves us with zero streams, the connection is fullyQuiesced. Otherwise, we are quiescing. + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = QuiescingPrefaceReceivedState(fromPrefaceReceived: state, lastStreamID: lastStreamID) + newState = .quiescingPrefaceReceived(newStateData) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = RemotelyQuiescedState(fromActive: state, lastLocalStreamID: lastStreamID) + newState = .remotelyQuiesced(newStateData) + newState.closeIfNeeded(newStateData) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = BothQuiescingState(fromLocallyQuiesced: state, lastLocalStreamID: lastStreamID) + newState = .bothQuiescing(newStateData) + newState.closeIfNeeded(newStateData) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + newState = .remotelyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // We're waiting for the preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + // We allow duplicate GOAWAY here, so long as it ratchets correctly. + let result = state.receiveGoAwayFrame(lastStreamID: lastStreamID) + newState = .fullyQuiesced(state) + return result + } + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when the user attempts to send a GOAWAY frame. + mutating func sendGoaway(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + // GOAWAY frames are some of the most subtle frames in HTTP/2, they cause a number of state transitions all at once. + // In particular, the value of lastStreamID heavily affects the state transitions we perform here. + // In this case, all streams initiated by us that have stream IDs higher than lastStreamID will be closed, effective + // immediately. If this leaves us with zero streams, the connection is fullyQuiesced. Otherwise, we are quiescing. + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = QuiescingPrefaceSentState(fromPrefaceSent: state, lastStreamID: lastStreamID) + newState = .quiescingPrefaceSent(newStateData) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = LocallyQuiescedState(fromActive: state, lastRemoteStreamID: lastStreamID) + newState = .locallyQuiesced(newStateData) + newState.closeIfNeeded(newStateData) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + newState = .locallyQuiesced(state) + newState.closeIfNeeded(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + let newStateData = BothQuiescingState(fromRemotelyQuiesced: state, lastRemoteStreamID: lastStreamID) + newState = .bothQuiescing(newStateData) + newState.closeIfNeeded(newStateData) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + newState = .bothQuiescing(state) + newState.closeIfNeeded(state) + return result + } + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + newState = .quiescingPrefaceSent(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // We're waiting for the preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + // We allow duplicate GOAWAY here, so long as it ratchets downwards. + let result = state.sendGoAwayFrame(lastStreamID: lastStreamID) + newState = .fullyQuiesced(state) + return result + } + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a WINDOW_UPDATE frame has been received. + mutating func receiveWindowUpdate(streamID: HTTP2StreamID, windowIncrement: UInt32) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .active(state) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .locallyQuiesced(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .remotelyQuiesced(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .bothQuiescing(state) + return result + } + + case .idle, .prefaceSent, .quiescingPrefaceSent: + // We're waiting for the preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when a WINDOW_UPDATE frame is sent. + mutating func sendWindowUpdate(streamID: HTTP2StreamID, windowIncrement: UInt32) -> StateMachineResultWithEffect { + switch self.state { + case .prefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .prefaceSent(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .active(state) + return result + } + + case .quiescingPrefaceSent(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .quiescingPrefaceSent(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .locallyQuiesced(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .remotelyQuiesced(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement) + newState = .bothQuiescing(state) + return result + } + + case .idle, .prefaceReceived, .quiescingPrefaceReceived: + // We're waiting for the preface. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.missingPreface(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Called when an ALTSVC frame has been received. + /// + /// At present the frame is unconditionally ignored. + mutating func receiveAlternativeService(origin: String?, field: ByteBuffer?) -> StateMachineResultWithEffect { + // We don't support ALTSVC frames right now so we just ignore them. + // + // From RFC 7838 § 4: + // > The ALTSVC frame is a non-critical extension to HTTP/2. Endpoints + // > that do not support this frame will ignore it (as per the + // > extensibility rules defined in Section 4.1 of RFC7540). + return .init(result: .ignoreFrame, effect: .none) + } + + /// Called when an ALTSVC frame is sent. + /// + /// At present the frame is not handled, calling this function will trap. + mutating func sendAlternativeService(origin: String?, field: ByteBuffer?) -> Never { + fatalError("Currently ALTSVC frames are unhandled.") + } + + /// Called when an ORIGIN frame has been received. + /// + /// At present the frame is unconditionally ignored. + mutating func receiveOrigin(origins: [String]) -> StateMachineResultWithEffect { + // We don't support ORIGIN frames right now so we just ignore them. + // + // From RFC 8336 § 2.1: + // > The ORIGIN frame is a non-critical extension to HTTP/2. Endpoints + // > that do not support this frame can safely ignore it upon receipt. + return .init(result: .ignoreFrame, effect: .none) + } + + /// Called when an ORIGIN frame is sent. + /// + /// At present the frame is not handled, calling this function will trap. + mutating func sendOrigin(origins: [String]) -> Never { + fatalError("Currently ORIGIN frames are unhandled.") + } +} + +// Mark:- Private helper methods +extension HTTP2ConnectionStateMachine { + /// Called when we have received a SETTINGS frame from the remote peer. Applies the changes immediately. + private mutating func receiveSettingsChange(_ settings: HTTP2Settings, frameDecoder: inout HTTP2FrameDecoder) -> (StateMachineResultWithEffect, PostFrameOperation) { + let validationResult = self.validateSettings(settings) + + guard case .succeed = validationResult else { + return (.init(result: validationResult, effect: nil), .nothing) + } + + switch self.state { + case .idle(let state): + return self.avoidingStateMachineCoW { newState in + var newStateData = PrefaceReceivedState(fromIdle: state, remoteSettings: HTTP2SettingsState(localState: false)) + let result = newStateData.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .prefaceReceived(newStateData) + return result + } + + case .prefaceSent(let state): + return self.avoidingStateMachineCoW { newState in + var newStateData = ActiveConnectionState(fromPrefaceSent: state, remoteSettings: HTTP2SettingsState(localState: false)) + let result = newStateData.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .active(newStateData) + return result + } + + case .prefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .prefaceReceived(state) + return result + } + + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .active(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .remotelyQuiesced(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .locallyQuiesced(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .bothQuiescing(state) + return result + } + + case .quiescingPrefaceSent(let state): + return self.avoidingStateMachineCoW { newState in + var newStateData = LocallyQuiescedState(fromQuiescingPrefaceSent: state, remoteSettings: HTTP2SettingsState(localState: false)) + let result = newStateData.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .locallyQuiesced(newStateData) + return result + } + + case .quiescingPrefaceReceived(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsChange(settings, frameDecoder: &frameDecoder) + newState = .quiescingPrefaceReceived(state) + return result + } + + case .fullyQuiesced: + return (.init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil), .nothing) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + private mutating func receiveSettingsAck(frameEncoder: inout HTTP2FrameEncoder) -> StateMachineResultWithEffect { + // We can only receive a SETTINGS ACK after we've sent our own preface *and* the remote peer has + // sent its own. That means we have to be active or quiescing. + switch self.state { + case .active(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsAck(frameEncoder: &frameEncoder) + newState = .active(state) + return result + } + + case .locallyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsAck(frameEncoder: &frameEncoder) + newState = .locallyQuiesced(state) + return result + } + + case .remotelyQuiesced(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsAck(frameEncoder: &frameEncoder) + newState = .remotelyQuiesced(state) + return result + } + + case .bothQuiescing(var state): + return self.avoidingStateMachineCoW { newState in + let result = state.receiveSettingsAck(frameEncoder: &frameEncoder) + newState = .bothQuiescing(state) + return result + } + + case .idle, .prefaceSent, .prefaceReceived, .quiescingPrefaceReceived, .quiescingPrefaceSent: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.receivedBadSettings(), type: .protocolError), effect: nil) + + case .fullyQuiesced: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.ioOnClosedConnection(), type: .protocolError), effect: nil) + + case .modifying: + preconditionFailure("Must not be left in modifying state") + } + } + + /// Validates a single HTTP/2 settings block. + /// + /// - parameters: + /// - settings: The HTTP/2 settings block to validate. + /// - returns: The result of the validation. + private func validateSettings(_ settings: HTTP2Settings) -> StateMachineResult { + for setting in settings { + switch setting.parameter { + case .enablePush: + guard setting._value == 0 || setting._value == 1 else { + return .connectionError(underlyingError: NIOHTTP2Errors.invalidSetting(setting: setting), type: .protocolError) + } + case .initialWindowSize: + guard setting._value <= HTTP2FlowControlWindow.maxSize else { + return .connectionError(underlyingError: NIOHTTP2Errors.invalidSetting(setting: setting), type: .flowControlError) + } + case .maxFrameSize: + guard setting._value >= (1 << 14) && setting._value <= ((1 << 24) - 1) else { + return .connectionError(underlyingError: NIOHTTP2Errors.invalidSetting(setting: setting), type: .protocolError) + } + default: + // All other settings have unrestricted ranges. + break + } + } + + return .succeed + } +} + +extension HTTP2ConnectionStateMachine.State { + // Sets the connection state to fullyQuiesced if necessary. + // + // We should only call this when a server has quiesced the connection. As long as only the client has quiesced the + // connection more work can always be done. + mutating func closeIfNeeded(_ state: CurrentState) { + if state.quiescedByServer && state.streamState.openStreams == 0 { + self = .fullyQuiesced(.init(previousState: state)) + } + } + + // Sets the connection state to fullyQuiesced if necessary. + // + // We should only call this when a server has quiesced the connection. As long as only the client has quiesced the + // connection more work can always be done. + mutating func closeIfNeeded(_ state: CurrentState) { + if state.quiescedByServer && state.streamState.openStreams == 0 { + self = .fullyQuiesced(.init(previousState: state)) + } + } + + // Sets the connection state to fullyQuiesced if necessary. + // + // We should only call this when a server has quiesced the connection. As long as only the client has quiesced the + // connection more work can always be done. + mutating func closeIfNeeded(_ state: CurrentState) { + if state.quiescedByServer && state.streamState.openStreams == 0 { + self = .fullyQuiesced(.init(previousState: state)) + } + } +} + +// MARK: CoW helpers +extension HTTP2ConnectionStateMachine { + /// So, uh...this function needs some explaining. + /// + /// While the state machine logic above is great, there is a downside to having all of the state machine data in + /// associated data on enumerations: any modification of that data will trigger copy on write for heap-allocated + /// data. That means that for _every operation on the state machine_ we will CoW our underlying state, which is + /// not good. + /// + /// The way we can avoid this is by using this helper function. It will temporarily set state to a value with no + /// associated data, before attempting the body of the function. It will also verify that the state machine never + /// remains in this bad state. + /// + /// A key note here is that all callers must ensure that they return to a good state before they exit. + /// + /// Sadly, because it's generic and has a closure, we need to force it to be inlined at all call sites, which is + /// not ideal. + @inline(__always) + private mutating func avoidingStateMachineCoW(_ body: (inout State) -> ReturnType) -> ReturnType { + self.state = .modifying + defer { + assert(!self.isModifying) + } + + return body(&self.state) + } + + private var isModifying: Bool { + if case .modifying = self.state { + return true + } else { + return false + } + } +} + + +extension HTTP2StreamID { + /// Confirms that this kind of stream ID may be initiated by a peer in the specific role. + /// + /// RFC 7540 limits odd stream IDs to being initiated by clients, and even stream IDs to + /// being initiated by servers. This method confirms this. + func mayBeInitiatedBy(_ role: HTTP2ConnectionStateMachine.ConnectionRole) -> Bool { + switch role { + case .client: + return self.isClientInitiated + case .server: + return self.isServerInitiated + } + } +} + + +/// A simple protocol that provides helpers that apply to all connection states that keep track of a role. +private protocol ConnectionStateWithRole { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } +} + +extension ConnectionStateWithRole { + var peerRole: HTTP2ConnectionStateMachine.ConnectionRole { + switch self.role { + case .client: + return .server + case .server: + return .client + } + } +} + +/// A simple protocol that provides helpers that apply to all connection states that have configuration. +private protocol ConnectionStateWithConfiguration { + var headerBlockValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var contentLengthValidation: HTTP2ConnectionStateMachine.ValidationState { get} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStreamsState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStreamsState.swift new file mode 100644 index 00000000..22dc2095 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStreamsState.swift @@ -0,0 +1,369 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + + +/// A representation of the state of the HTTP/2 streams in a single HTTP/2 connection. +struct ConnectionStreamState { + /// The "safe" default value of SETTINGS_MAX_CONCURRENT_STREAMS. + static let defaultMaxConcurrentStreams: UInt32 = 100 + + fileprivate static let emptyStreamMap = StreamMap.empty() + + /// The underlying data storage for the HTTP/2 stream state. + private var activeStreams: StreamMap + + /// A collection of recently reset streams. + /// + /// The recently closed streams are stored to provide better resilience against synchronization errors between + /// the local and remote sides of the connection. Specifically, if a stream was recently closed, frames may have + /// been in flight that should not be considered errors. We maintain a small amount of state to protect against + /// this case. + private var recentlyResetStreams: CircularBuffer + + /// The maximum number of reset streams we'll persist. + /// + /// TODO (cory): Make this configurable! + private let maxResetStreams: Int = 32 + + /// The current number of streams that are active and that were initiated by the client. + private var clientStreamCount: UInt32 = 0 + + /// The current number of streams that are active and that were initiated by the server. + private var serverStreamCount: UInt32 = 0 + + /// The highest stream ID opened or reserved by the client. + private var lastClientStreamID: HTTP2StreamID = .rootStream + + /// The highest stream ID opened or reserved by the server. + private var lastServerStreamID: HTTP2StreamID = .rootStream + + /// The maximum number of streams that may be active at once, initiated by the client. + /// + /// Corresponds to the value of SETTINGS_MAX_CONCURRENT_STREAMS set by the client. + var maxClientInitiatedStreams: UInt32 = ConnectionStreamState.defaultMaxConcurrentStreams + + /// The maximum number of streams that may be active at once, initiated by the server. + /// + /// Corresponds to the value of SETTINGS_MAX_CONCURRENT_STREAMS set by the server. + var maxServerInitiatedStreams: UInt32 = ConnectionStreamState.defaultMaxConcurrentStreams + + /// The total number of streams currently active. + var openStreams: Int { + return Int(self.clientStreamCount) + Int(self.serverStreamCount) + } + + init() { + self.activeStreams = StreamMap() + self.recentlyResetStreams = CircularBuffer(initialCapacity: self.maxResetStreams) + } + + /// Create stream state for a remotely pushed stream. + /// + /// Unlike with idle streams, which are served by `modifyStreamStateCreateIfNeeded`, for pushed streams we do not + /// have to perform a modification operation. For this reason, we can use a simpler control flow. + /// + /// - parameters: + /// - streamID: The ID of the pushed stream. + /// - remoteInitialWindowSize: The initial window size of the remote peer. + /// - throws: If the stream ID is invalid. + mutating func createRemotelyPushedStream(streamID: HTTP2StreamID, remoteInitialWindowSize: UInt32) throws { + try self.reserveServerStreamID(streamID) + let streamState = HTTP2StreamStateMachine(receivedPushPromiseCreatingStreamID: streamID, remoteInitialWindowSize: remoteInitialWindowSize) + self.activeStreams.insert(streamState) + } + + /// Create stream state for a locally pushed stream. + /// + /// Unlike with idle streams, which are served by `modifyStreamStateCreateIfNeeded`, for pushed streams we do not + /// have to perform a modification operation. For this reason, we can use a simpler control flow. + /// + /// - parameters: + /// - streamID: The ID of the pushed stream. + /// - localInitialWindowSize: Our initial window size.. + /// - throws: If the stream ID is invalid. + mutating func createLocallyPushedStream(streamID: HTTP2StreamID, localInitialWindowSize: UInt32) throws { + try self.reserveServerStreamID(streamID) + let streamState = HTTP2StreamStateMachine(sentPushPromiseCreatingStreamID: streamID, localInitialWindowSize: localInitialWindowSize) + self.activeStreams.insert(streamState) + } + + /// Obtains a stream state machine in order to modify its state, potentially creating it if necessary. + /// + /// The `creator` block will be called if the stream does not exist already. The `modifier` block will be called + /// if the stream was created, or if it was found in the map. + /// + /// - parameters: + /// - streamID: The ID of the stream to modify. + /// - localRole: The connection role of the local peer. + /// - localInitialWindowSize: The initial size of the local flow control window for new streams. + /// - remoteInitialWindowSize: The initial size of the remote flow control window for new streams. + /// - modifier: A block that will be invoked to modify the stream state, if present. + /// - throws: Any errors thrown from the creator. + /// - returns: The result of the state modification, as well as any state change that occurred to the stream. + mutating func modifyStreamStateCreateIfNeeded(streamID: HTTP2StreamID, + localRole: HTTP2StreamStateMachine.StreamRole, + localInitialWindowSize: UInt32, + remoteInitialWindowSize: UInt32, + modifier: (inout HTTP2StreamStateMachine) -> StateMachineResultWithStreamEffect) throws -> StateMachineResultWithStreamEffect { + func creator() throws -> HTTP2StreamStateMachine { + try self.reserveClientStreamID(streamID) + let initialValue = HTTP2StreamStateMachine(streamID: streamID, + localRole: localRole, + localInitialWindowSize: localInitialWindowSize, + remoteInitialWindowSize: remoteInitialWindowSize) + return initialValue + } + + // FIXME(cory): This isn't ideal, but it's necessary to avoid issues with overlapping accesses on the activeStreams + // map. The above closure takes a mutable copy of self, which is a big issue, so we should investigate whether + // it's possible for me to be smarter here. + var activeStreams = ConnectionStreamState.emptyStreamMap + swap(&activeStreams, &self.activeStreams) + defer { + swap(&activeStreams, &self.activeStreams) + } + + guard let result = try activeStreams.transformOrCreateAutoClose(streamID: streamID, creator, modifier) else { + preconditionFailure("Stream was missing even though we should have created it!") + } + + if let effect = result.effect, effect.closedStream { + self.streamClosed(streamID) + } + + return result + } + + /// Obtains a stream state machine in order to modify its state. + /// + /// The block will be called so long as the stream exists in the currently active streams. If it does not, we will check + /// whether the stream has been closed already. + /// + /// - parameters: + /// - streamID: The ID of the stream to modify. + /// - ignoreRecentlyReset: Whether a recently reset stream should be ignored. Should be set to `true` when receiving frames. + /// - ignoreClosed: Whether a closed stream should be ignored. Should be set to `true` when receiving window update or reset stream frames. + /// - modifier: A block that will be invoked to modify the stream state, if present. + /// - returns: The result of the state modification, as well as any state change that occurred to the stream. + mutating func modifyStreamState(streamID: HTTP2StreamID, + ignoreRecentlyReset: Bool, + ignoreClosed: Bool = false, + _ modifier: (inout HTTP2StreamStateMachine) -> StateMachineResultWithStreamEffect) -> StateMachineResultWithStreamEffect { + guard let result = self.activeStreams.autoClosingTransform(streamID: streamID, modifier) else { + return StateMachineResultWithStreamEffect(result: self.streamMissing(streamID: streamID, ignoreRecentlyReset: ignoreRecentlyReset, ignoreClosed: ignoreClosed), effect: nil) + } + + if let effect = result.effect, effect.closedStream { + self.streamClosed(streamID) + } + + return result + } + + /// Obtains a stream state machine in order to modify its state due to a stream reset initiated locally. + /// + /// The block will be called so long as the stream exists in the currently active streams. If it does not, we will check + /// whether the stream has been closed already. + /// + /// This block must close the stream. Failing to do so is a programming error. + /// + /// - parameters: + /// - streamID: The ID of the stream to modify. + /// - modifier: A block that will be invoked to modify the stream state, if present. + /// - returns: The result of the state modification, as well as any state change that occurred to the stream. + @inline(__always) + mutating func locallyResetStreamState(streamID: HTTP2StreamID, + _ modifier: (inout HTTP2StreamStateMachine) -> StateMachineResultWithStreamEffect) -> StateMachineResultWithStreamEffect { + guard let result = self.activeStreams.autoClosingTransform(streamID: streamID, modifier) else { + // We never ignore recently reset streams here, as this should only ever be used when *sending* frames. + return StateMachineResultWithStreamEffect(result: self.streamMissing(streamID: streamID, ignoreRecentlyReset: false, ignoreClosed: false), effect: nil) + } + + + guard let effect = result.effect, effect.closedStream else { + preconditionFailure("Locally resetting stream state did not close it!") + } + self.recentlyResetStreams.prependWithoutExpanding(streamID) + self.streamClosed(streamID) + + return result + } + + /// Performs a state-modifying operation on all streams. + /// + /// As with the other block-taking functions in this module, this is @inline(__always) to ensure + /// that we don't end up actually heap-allocating a closure here. We're sorry about it! + @inline(__always) + mutating func forAllStreams(_ body: (inout HTTP2StreamStateMachine) throws -> Void) rethrows { + try self.activeStreams.mutatingForEachValue(body) + } + + /// Adjusts the stream state to reserve a client stream ID. + mutating func reserveClientStreamID(_ streamID: HTTP2StreamID) throws { + guard self.clientStreamCount < self.maxClientInitiatedStreams else { + throw NIOHTTP2Errors.maxStreamsViolation() + } + + guard streamID > self.lastClientStreamID else { + throw NIOHTTP2Errors.streamIDTooSmall() + } + + guard streamID.mayBeInitiatedBy(.client) else { + throw NIOHTTP2Errors.invalidStreamIDForPeer() + } + + self.lastClientStreamID = streamID + self.clientStreamCount += 1 + } + + /// Adjusts the stream state to reserve a server stream ID. + mutating func reserveServerStreamID(_ streamID: HTTP2StreamID) throws { + guard self.serverStreamCount < self.maxServerInitiatedStreams else { + throw NIOHTTP2Errors.maxStreamsViolation() + } + + guard streamID > self.lastServerStreamID else { + throw NIOHTTP2Errors.streamIDTooSmall() + } + + guard streamID.mayBeInitiatedBy(.server) else { + throw NIOHTTP2Errors.invalidStreamIDForPeer() + } + + self.lastServerStreamID = streamID + self.serverStreamCount += 1 + } + + /// Drop all streams with stream IDs larger than the given stream ID that were initiated by the given role. + /// + /// - parameters: + /// - streamID: The last stream ID the remote peer is promising to handle. + /// - droppedLocally: Whether this drop was caused by sending a GOAWAY frame or receiving it. + /// - initiator: The peer that sent the GOAWAY frame. + /// - returns: the stream IDs closed by this operation. + mutating func dropAllStreamsWithIDHigherThan(_ streamID: HTTP2StreamID, + droppedLocally: Bool, + initiatedBy initiator: HTTP2ConnectionStateMachine.ConnectionRole) -> [HTTP2StreamID]? { + var droppedIDs: [HTTP2StreamID] = [] + self.activeStreams.dropDataWithStreamIDGreaterThan(streamID, initiatedBy: initiator) { data in + droppedIDs = data.map { $0.streamID } + } + + guard droppedIDs.count > 0 else { + return nil + } + + if droppedLocally { + self.recentlyResetStreams.prependWithoutExpanding(contentsOf: droppedIDs) + } + + switch initiator { + case .client: + self.clientStreamCount -= UInt32(droppedIDs.count) + case .server: + self.serverStreamCount -= UInt32(droppedIDs.count) + } + + return droppedIDs + } + + /// Determines the state machine result to generate when we've been asked to modify a missing stream. + /// + /// - parameters: + /// - streamID: The ID of the missing stream. + /// - ignoreRecentlyReset: Whether a recently reset stream should be ignored. + /// - ignoreClosed: Whether a closed stream should be ignored. + /// - returns: A `StateMachineResult` for this frame error. + private func streamMissing(streamID: HTTP2StreamID, ignoreRecentlyReset: Bool, ignoreClosed: Bool) -> StateMachineResult { + if ignoreRecentlyReset && self.recentlyResetStreams.contains(streamID) { + return .ignoreFrame + } + + switch streamID.mayBeInitiatedBy(.client) { + case true where streamID > self.lastClientStreamID, + false where streamID > self.lastServerStreamID: + // The stream in question is idle. + return .connectionError(underlyingError: NIOHTTP2Errors.noSuchStream(streamID: streamID), type: .protocolError) + default: + // This stream must have already been closed. + if ignoreClosed { + return .ignoreFrame + } else { + return .connectionError(underlyingError: NIOHTTP2Errors.noSuchStream(streamID: streamID), type: .streamClosed) + } + } + } + + private mutating func streamClosed(_ streamID: HTTP2StreamID) { + assert(!self.activeStreams.contains(streamID: streamID)) + if streamID.mayBeInitiatedBy(.client) { + self.clientStreamCount -= 1 + } else { + self.serverStreamCount -= 1 + } + } +} + + +extension CircularBuffer { + // CircularBuffer may never be "full": that is, capacity may never equal count. + var effectiveCapacity: Int { + return self.capacity - 1 + } + + /// Prepends `element` without expanding the capacity, by dropping the + /// element at the end if necessary. + mutating func prependWithoutExpanding(_ element: Element) { + if self.effectiveCapacity == self.count { + self.removeLast() + } + self.prepend(element) + } + + // NOTE: this could be generic over RandomAccessCollection if we wanted, I'm just saving code size by defining + // it specifically for now. + mutating func prependWithoutExpanding(contentsOf newElements: [Element]) { + // We're going to need to insert these new elements _backwards_, as though they were inserted + // one at a time. + var newElements = newElements.reversed()[...] + let newElementCount = newElements.count + let freeSpace = self.effectiveCapacity - self.count + + if newElementCount >= self.effectiveCapacity { + // We need to completely replace the storage, and then only insert `self.effectiveCapacity` elements. + self.removeAll(keepingCapacity: true) + newElements = newElements.prefix(self.effectiveCapacity) + } else if newElementCount > freeSpace { + // We need to free up enough space to store everything we need, but some of the old elements will remain. + let elementsToRemove = newElementCount - freeSpace + self.removeLast(elementsToRemove) + } + + assert(newElements.count <= self.effectiveCapacity - self.count) + self.insert(contentsOf: newElements, at: self.startIndex) + } +} + + +extension StreamStateChange { + fileprivate var closedStream: Bool { + switch self { + case .streamClosed, .streamCreatedAndClosed: + return true + case .streamCreated, .windowSizeChange: + return false + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/MayReceiveFrames.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/MayReceiveFrames.swift new file mode 100644 index 00000000..a90ed0a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/MayReceiveFrames.swift @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving frames, for those states that +/// can validly receive any frames. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol MayReceiveFrames: + ReceivingHeadersState, + ReceivingDataState, + ReceivingPushPromiseState, + ReceivingWindowUpdateState, + ReceivingRstStreamState, + ReceivingGoawayState { } diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingDataState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingDataState.swift new file mode 100644 index 00000000..3becaf1f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingDataState.swift @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving DATA frames, for those states that +/// can validly receive data. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingDataState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } + + var inboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension ReceivingDataState { + /// Called to receive a DATA frame. + mutating func receiveData(streamID: HTTP2StreamID, contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + do { + try self.inboundFlowControlWindow.consume(flowControlledBytes: flowControlledBytes) + } catch let error where error is NIOHTTP2Errors.FlowControlViolation { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .flowControlError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: true) { + $0.receiveData(contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + } + + // We need to be a bit careful here. The backing code may have triggered either an ignoreFrame or streamError. While both of these + // need to be honored, in those cases we also need to make sure the user knows that the frame did consume some flow control window! + return StateMachineResultWithEffect.withGuaranteedFlowControlEffect(result, connectionState: self) + } +} + + +private extension StateMachineResultWithEffect { + static func withGuaranteedFlowControlEffect(_ result: StateMachineResultWithStreamEffect, connectionState: ConnectionState) -> StateMachineResultWithEffect { + // In most cases, this will update the underlying effect with the new flow control window info. + var newResult = StateMachineResultWithEffect(result, + inboundFlowControlWindow: connectionState.inboundFlowControlWindow, + outboundFlowControlWindow: connectionState.outboundFlowControlWindow) + if newResult.effect == nil { + // But if we aren't noting it anywhere else, we note it here. + newResult.effect = .flowControlChange(.init(localConnectionWindowSize: Int(connectionState.outboundFlowControlWindow), remoteConnectionWindowSize: Int(connectionState.inboundFlowControlWindow), localStreamWindowSize: nil)) + } + + return newResult + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingGoAwayState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingGoAwayState.swift new file mode 100644 index 00000000..ee4db498 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingGoAwayState.swift @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving GOAWAY frames, for those states that +/// can validly be quiesced. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingGoawayState { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var streamState: ConnectionStreamState { get set } +} + +extension ReceivingGoawayState { + mutating func receiveGoAwayFrame(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + guard lastStreamID.mayBeInitiatedBy(self.role) || lastStreamID == .rootStream || lastStreamID == .maxID else { + // The remote peer has sent a GOAWAY with an invalid stream ID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.invalidStreamIDForPeer(), type: .protocolError), effect: nil) + } + + let droppedStreams = self.streamState.dropAllStreamsWithIDHigherThan(lastStreamID, droppedLocally: false, initiatedBy: self.role) + let effect: NIOHTTP2ConnectionStateChange? = droppedStreams.map { .bulkStreamClosure(.init(closedStreams: $0)) } + return .init(result: .succeed, effect: effect) + } +} + +extension ReceivingGoawayState where Self: RemotelyQuiescingState { + mutating func receiveGoAwayFrame(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + guard lastStreamID.mayBeInitiatedBy(self.role) || lastStreamID == .rootStream || lastStreamID == .maxID else { + // The remote peer has sent a GOAWAY with an invalid stream ID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.invalidStreamIDForPeer(), type: .protocolError), effect: nil) + } + + if lastStreamID > self.lastLocalStreamID { + // The remote peer has attempted to raise the lastStreamID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.raisedGoawayLastStreamID(), type: .protocolError), effect: nil) + } + + let droppedStreams = self.streamState.dropAllStreamsWithIDHigherThan(lastStreamID, droppedLocally: false, initiatedBy: self.role) + let effect: NIOHTTP2ConnectionStateChange? = droppedStreams.map { .bulkStreamClosure(.init(closedStreams: $0)) } + self.lastLocalStreamID = lastStreamID + return .init(result: .succeed, effect: effect) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingHeadersState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingHeadersState.swift new file mode 100644 index 00000000..4bac538b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingHeadersState.swift @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +/// A protocol that provides implementation for receiving HEADERS frames, for those states that +/// can validly accept headers. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingHeadersState: HasFlowControlWindows { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var headerBlockValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var contentLengthValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var streamState: ConnectionStreamState { get set } + + var localInitialWindowSize: UInt32 { get } + + var remoteInitialWindowSize: UInt32 { get } +} + +extension ReceivingHeadersState { + /// Called when we receive a HEADERS frame in this state. + mutating func receiveHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + let result: StateMachineResultWithStreamEffect + let validateHeaderBlock = self.headerBlockValidation == .enabled + let validateContentLength = self.contentLengthValidation == .enabled + + if self.role == .server && streamID.mayBeInitiatedBy(.client) { + do { + result = try self.streamState.modifyStreamStateCreateIfNeeded(streamID: streamID, localRole: .server, localInitialWindowSize: self.localInitialWindowSize, remoteInitialWindowSize: self.remoteInitialWindowSize) { + $0.receiveHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + } catch { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } else { + // HEADERS cannot create streams for servers, so this must be for a stream we already know about. + result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: true) { + $0.receiveHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + } + + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} + + +extension ReceivingHeadersState where Self: LocallyQuiescingState { + /// Called when we receive a HEADERS frame in this state. + /// + /// If we've quiesced this connection, the remote peer is no longer allowed to create new streams. + /// We ignore any frame that appears to be creating a new stream, and then prevent this from creating + /// new streams. + mutating func receiveHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + let validateHeaderBlock = self.headerBlockValidation == .enabled + let validateContentLength = self.contentLengthValidation == .enabled + + if streamID.mayBeInitiatedBy(.client) && streamID > self.lastRemoteStreamID { + return StateMachineResultWithEffect(result: .ignoreFrame, effect: nil) + } + + // At this stage we've quiesced, so the remote peer is not allowed to create new streams. + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: true) { + $0.receiveHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingPushPromiseState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingPushPromiseState.swift new file mode 100644 index 00000000..9079486c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingPushPromiseState.swift @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +/// A protocol that provides implementation for receiving PUSH_PROMISE frames, for those states that +/// can validly accept pushed streams. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingPushPromiseState: HasFlowControlWindows { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var headerBlockValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var streamState: ConnectionStreamState { get set } + + var remoteInitialWindowSize: UInt32 { get } + + var peerMayPush: Bool { get } +} + +extension ReceivingPushPromiseState { + mutating func receivePushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + return self._receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + } + + fileprivate mutating func _receivePushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + // In states that support a push promise we have two steps. Firstly, we want to create the child stream; then we want to + // pass the PUSH_PROMISE frame through the stream state machine for the parent stream. + // + // The reason we do things in this order is that if for any reason the PUSH_PROMISE frame is invalid on the parent stream, + // we want to take out both the child stream and the parent stream. We can only do that if we have a child stream state to + // modify. For this reason, we unconditionally allow the remote peer to consume the stream. The only case where this is *not* + // true is when the child stream itself cannot be validly created, because the stream ID used by the remote peer is invalid. + // In this case this is a connection error, anyway, so we don't worry too much about it. + // + // Before any of this, though, we need to check whether the remote peer is even allowed to push! + guard self.peerMayPush else { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: NIOHTTP2Errors.pushInViolationOfSetting(), type: .protocolError), effect: nil) + } + + let validateHeaderBlock = self.headerBlockValidation == .enabled + + do { + try self.streamState.createRemotelyPushedStream(streamID: childStreamID, + remoteInitialWindowSize: self.remoteInitialWindowSize) + + let result = self.streamState.modifyStreamState(streamID: originalStreamID, ignoreRecentlyReset: true) { + $0.receivePushPromise(headers: headers, validateHeaderBlock: validateHeaderBlock) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } catch { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } + + /// Whether the remote peer may push. + var peerMayPush: Bool { + // In the case where we don't have local settings, we have to assume the default value, in which servers may push and clients may not. + return self.role == .client + } +} + +extension ReceivingPushPromiseState where Self: LocallyQuiescingState { + mutating func receivePushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + // This check is duplicated here, because the protocol error of violating this setting is more important than ignoring the frame. + guard self.peerMayPush else { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: NIOHTTP2Errors.pushInViolationOfSetting(), type: .protocolError), effect: nil) + } + + // If we're a client, the server is forbidden from initiating new streams, as we quiesced. However, RFC 7540 wants us to ignore this. + if self.role == .client { + return StateMachineResultWithEffect(result: .ignoreFrame, effect: nil) + } + + // We're a server, so the remote peer can't initiate a stream with a PUSH_PROMISE, but that's ok, the stream state machine + // will forbid this as it normally does. + return self._receivePushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + } +} + +extension ReceivingPushPromiseState where Self: HasLocalSettings { + var peerMayPush: Bool { + return self.localSettings.enablePush == 1 && self.role == .client + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingRstStreamState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingRstStreamState.swift new file mode 100644 index 00000000..ac84dec5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingRstStreamState.swift @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving RST_STREAM frames, for those states that +/// can validly receive such frames. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingRstStreamState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } +} + +extension ReceivingRstStreamState { + /// Called to receive a RST_STREAM frame. + mutating func receiveRstStream(streamID: HTTP2StreamID, reason: HTTP2ErrorCode) -> StateMachineResultWithEffect { + // RFC 7540 § 6.4 does not explicitly forbid a peer sending + // multiple RST_STREAMs for the same stream which means we should ignore subsequent RST_STREAMs. + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: true, ignoreClosed: true) { + $0.receiveRstStream(reason: reason) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingWindowUpdateState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingWindowUpdateState.swift new file mode 100644 index 00000000..ec8d1e0f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameReceivingStates/ReceivingWindowUpdateState.swift @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving WINDOW_UPDATE frames, for those states that +/// can validly be updated. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol ReceivingWindowUpdateState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } + + var outboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension ReceivingWindowUpdateState { + mutating func receiveWindowUpdate(streamID: HTTP2StreamID, increment: UInt32) -> StateMachineResultWithEffect { + if streamID == .rootStream { + // This is an update for the connection. We police the errors here. + do { + try self.outboundFlowControlWindow.windowUpdate(by: increment) + let flowControlSize: NIOHTTP2ConnectionStateChange = .flowControlChange(.init(localConnectionWindowSize: Int(self.outboundFlowControlWindow), + remoteConnectionWindowSize: Int(self.inboundFlowControlWindow), + localStreamWindowSize: nil)) + return StateMachineResultWithEffect(result: .succeed, effect: flowControlSize) + } catch let error where error is NIOHTTP2Errors.InvalidFlowControlWindowSize { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.InvalidWindowIncrementSize { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } else { + // This is an update for a specific stream: it's responsible for policing any errors. + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: true, ignoreClosed: true) { + $0.receiveWindowUpdate(windowIncrement: increment) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/MaySendFrames.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/MaySendFrames.swift new file mode 100644 index 00000000..886be79c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/MaySendFrames.swift @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for sending frames, for those states that +/// can validly send any frames. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol MaySendFrames: + SendingHeadersState, + SendingDataState, + SendingPushPromiseState, + SendingWindowUpdateState, + SendingRstStreamState, + SendingGoawayState { } diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingDataState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingDataState.swift new file mode 100644 index 00000000..87f7e2d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingDataState.swift @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for sending DATA frames, for those states that +/// can validly be sending data. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingDataState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } + + var outboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension SendingDataState { + /// Called to send a DATA frame. + mutating func sendData(streamID: HTTP2StreamID, contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + do { + try self.outboundFlowControlWindow.consume(flowControlledBytes: flowControlledBytes) + } catch let error where error is NIOHTTP2Errors.FlowControlViolation { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .flowControlError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: false) { + $0.sendData(contentLength: contentLength, flowControlledBytes: flowControlledBytes, isEndStreamSet: endStream) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingGoawayState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingGoawayState.swift new file mode 100644 index 00000000..018080f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingGoawayState.swift @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for sending GOAWAY frames, for those states that +/// can validly initiate quiescing. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingGoawayState { + var peerRole: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var streamState: ConnectionStreamState { get set } +} + +extension SendingGoawayState { + mutating func sendGoAwayFrame(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + guard lastStreamID.mayBeInitiatedBy(self.peerRole) || lastStreamID == .rootStream || lastStreamID == .maxID else { + // The user has sent a GOAWAY with an invalid stream ID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.invalidStreamIDForPeer(), type: .protocolError), effect: nil) + } + + let droppedStreams = self.streamState.dropAllStreamsWithIDHigherThan(lastStreamID, droppedLocally: true, initiatedBy: self.peerRole) + let effect: NIOHTTP2ConnectionStateChange? = droppedStreams.map { .bulkStreamClosure(.init(closedStreams: $0)) } + return .init(result: .succeed, effect: effect) + } +} + +extension SendingGoawayState where Self: LocallyQuiescingState { + mutating func sendGoAwayFrame(lastStreamID: HTTP2StreamID) -> StateMachineResultWithEffect { + guard lastStreamID.mayBeInitiatedBy(self.peerRole) || lastStreamID == .rootStream || lastStreamID == .maxID else { + // The user has sent a GOAWAY with an invalid stream ID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.invalidStreamIDForPeer(), type: .protocolError), effect: nil) + } + + if lastStreamID > self.lastRemoteStreamID { + // The user has attempted to raise the lastStreamID. + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.raisedGoawayLastStreamID(), type: .protocolError), effect: nil) + } + + // Ok, this is a valid request, so we can now process it like .active. + let droppedStreams = self.streamState.dropAllStreamsWithIDHigherThan(lastStreamID, droppedLocally: true, initiatedBy: self.peerRole) + let effect: NIOHTTP2ConnectionStateChange? = droppedStreams.map { .bulkStreamClosure(.init(closedStreams: $0)) } + self.lastRemoteStreamID = lastStreamID + return .init(result: .succeed, effect: effect) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingHeadersState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingHeadersState.swift new file mode 100644 index 00000000..1b485590 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingHeadersState.swift @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + + +/// A protocol that provides implementation for sending HEADERS frames, for those states that +/// can validly send headers. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingHeadersState: HasFlowControlWindows { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var headerBlockValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var contentLengthValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var streamState: ConnectionStreamState { get set } + + var localInitialWindowSize: UInt32 { get } + + var remoteInitialWindowSize: UInt32 { get } +} + +extension SendingHeadersState { + /// Called when we send a HEADERS frame in this state. + mutating func sendHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + let result: StateMachineResultWithStreamEffect + let validateHeaderBlock = self.headerBlockValidation == .enabled + let validateContentLength = self.contentLengthValidation == .enabled + + if self.role == .client && streamID.mayBeInitiatedBy(.client) { + do { + result = try self.streamState.modifyStreamStateCreateIfNeeded(streamID: streamID, + localRole: .client, + localInitialWindowSize: self.localInitialWindowSize, + remoteInitialWindowSize: self.remoteInitialWindowSize) { + $0.sendHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + } catch { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } else { + // HEADERS cannot create streams for servers, so this must be for a stream we already know about. + result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: false) { + $0.sendHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + } + + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} + + +extension SendingHeadersState where Self: RemotelyQuiescingState { + /// If we've been remotely quiesced, we're forbidden from creating new streams. So we can only possibly + /// be modifying an existing one. + mutating func sendHeaders(streamID: HTTP2StreamID, headers: HPACKHeaders, isEndStreamSet endStream: Bool) -> StateMachineResultWithEffect { + let validateHeaderBlock = self.headerBlockValidation == .enabled + let validateContentLength = self.contentLengthValidation == .enabled + + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: false) { + $0.sendHeaders(headers: headers, validateHeaderBlock: validateHeaderBlock, validateContentLength: validateContentLength, isEndStreamSet: endStream) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingPushPromiseState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingPushPromiseState.swift new file mode 100644 index 00000000..6306c7e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingPushPromiseState.swift @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +/// A protocol that provides implementation for sending PUSH_PROMISE frames, for those states that +/// can validly send pushed streams. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingPushPromiseState: HasFlowControlWindows { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var headerBlockValidation: HTTP2ConnectionStateMachine.ValidationState { get } + + var streamState: ConnectionStreamState { get set } + + var localInitialWindowSize: UInt32 { get } + + var mayPush: Bool { get } +} + +extension SendingPushPromiseState { + mutating func sendPushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + return self._sendPushPromise(originalStreamID: originalStreamID, childStreamID: childStreamID, headers: headers) + } + + fileprivate mutating func _sendPushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + let validateHeaderBlock = self.headerBlockValidation == .enabled + + // While receivePushPromise has a two step process involving creating the child stream first, here we do it the other + // way around. This is because we don't want to bother creating a child stream if the headers aren't valid, and because + // we don't have to emit a frame to report the error (we just return it to the user), we don't have to have a stream + // whose state we can modify. + func parentStateModifier(stateMachine: inout HTTP2StreamStateMachine) -> StateMachineResultWithStreamEffect { + return stateMachine.sendPushPromise(headers: headers, validateHeaderBlock: validateHeaderBlock) + } + + // First, however, we need to check we can push at all! + guard self.mayPush else { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: NIOHTTP2Errors.pushInViolationOfSetting(), type: .protocolError), effect: nil) + } + + do { + let result = StateMachineResultWithEffect( + self.streamState.modifyStreamState(streamID: originalStreamID, ignoreRecentlyReset: false, parentStateModifier), + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow + ) + guard case .succeed = result.result else { + return result + } + + try self.streamState.createLocallyPushedStream(streamID: childStreamID, localInitialWindowSize: self.localInitialWindowSize) + return result + } catch { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } + + /// Whether we may push. + var mayPush: Bool { + // In the case where we don't have remote settings, we have to assume the default value, in which case if we're a server we may push. + return self.role == .server + } + +} + +extension SendingPushPromiseState where Self: RemotelyQuiescingState { + mutating func sendPushPromise(originalStreamID: HTTP2StreamID, childStreamID: HTTP2StreamID, headers: HPACKHeaders) -> StateMachineResultWithEffect { + // This call should never be used, but we do want to ensure that conforming types cannot enter the above method. + // The state machine should return early in all cases where we might end up calling this function. + preconditionFailure("Must not be called") + } +} + +extension SendingPushPromiseState where Self: HasRemoteSettings { + var mayPush: Bool { + return self.remoteSettings.enablePush == 1 && self.role == .server + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingRstStreamState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingRstStreamState.swift new file mode 100644 index 00000000..2d52fbcf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingRstStreamState.swift @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for sending RST_STREAM frames, for those states that +/// can validly send such frames. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingRstStreamState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } +} + +extension SendingRstStreamState { + /// Called to send a RST_STREAM frame. + mutating func sendRstStream(streamID: HTTP2StreamID, reason: HTTP2ErrorCode) -> StateMachineResultWithEffect { + let result = self.streamState.locallyResetStreamState(streamID: streamID) { + $0.sendRstStream(reason: reason) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingWindowUpdateState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingWindowUpdateState.swift new file mode 100644 index 00000000..72440bd6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/FrameSendingStates/SendingWindowUpdateState.swift @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol that provides implementation for receiving WINDOW_UPDATE frames, for those states that +/// can validly be updated. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol SendingWindowUpdateState: HasFlowControlWindows { + var streamState: ConnectionStreamState { get set } + + var inboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension SendingWindowUpdateState { + mutating func sendWindowUpdate(streamID: HTTP2StreamID, increment: UInt32) -> StateMachineResultWithEffect { + if streamID == .rootStream { + // This is an update for the connection. We police the errors here. + do { + try self.inboundFlowControlWindow.windowUpdate(by: increment) + return StateMachineResultWithEffect(result: .succeed, effect: nil) + } catch let error where error is NIOHTTP2Errors.InvalidFlowControlWindowSize { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.InvalidWindowIncrementSize { + return StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } else { + // This is an update for a specific stream: it's responsible for policing any errors. + let result = self.streamState.modifyStreamState(streamID: streamID, ignoreRecentlyReset: false) { + $0.sendWindowUpdate(windowIncrement: increment) + } + return StateMachineResultWithEffect(result, + inboundFlowControlWindow: self.inboundFlowControlWindow, + outboundFlowControlWindow: self.outboundFlowControlWindow) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HTTP2SettingsState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HTTP2SettingsState.swift new file mode 100644 index 00000000..3700b0b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HTTP2SettingsState.swift @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// The view of HTTP/2 settings at any given time is a combination of initial values and acknowledged +/// updates sent via SETTINGS frames. This requires a structure to keep track of this holistic view of +/// the current settings. +/// +/// This specific requirement makes this structure a useful place to keep track of pending SETTINGS ACKs +/// from remote peers. +struct HTTP2SettingsState { + /// The current value of the HTTP/2 settings. + private var currentSettingsValues: [HTTP2SettingsParameter: UInt32] + + /// An array of unacknowledged SETTINGS frames. These settings will be applied + /// when the SETTINGS frame is acknowledged. + private var unacknowlegedSettingsFrames: [HTTP2Settings] + + /// A callback that is invoked whenever a setting value has changed. + typealias OnValueChangeCallback = (_ setting: HTTP2SettingsParameter, _ oldValue: UInt32?, _ newValue: UInt32) throws -> Void + + init(localState: Bool) { + // Create the settings dictionary, and ensure it has space for the known SETTINGS values. + self.currentSettingsValues = [.headerTableSize: 4096, .enablePush: 1, .initialWindowSize: HTTP2SettingsState.defaultInitialWindowSize, .maxFrameSize: 1<<14] + self.currentSettingsValues.reserveCapacity(8) + + // Create space for the unacknowledged SETTINGS frame data to be stored. In general this will be empty, + // and the vastly most-common case is to have only one entry here. Additionally, the settings state + // for the remote peer should never have an un-ACKed SETTINGS frame, as we auto-ACK all SETTINGS. + // As a result, we never reserve more than 1 entry. Users that emit multiple SETTINGS frames without + // acknowledgement will incur some memory management overhead. + self.unacknowlegedSettingsFrames = Array() + if localState { + self.unacknowlegedSettingsFrames.reserveCapacity(1) + } + } + + /// Creates an empty state, suitable for use as a dummy value when trying to avoid CoW operations. + private init() { + self.currentSettingsValues = [:] + self.unacknowlegedSettingsFrames = [] + } + + /// Obtain the current value of a settings parameter. + subscript(_ parameter: HTTP2SettingsParameter) -> UInt32? { + get { + return self.currentSettingsValues[parameter] + } + } + + /// The current value of SETTINGS_INITIAL_WINDOW_SIZE. + var initialWindowSize: UInt32 { + // We can force-unwrap here as this setting always has a value. + return self[.initialWindowSize]! + } + + /// The current value of SETTINGS_ENABLE_PUSH. + var enablePush: UInt32 { + // We can force-unwrap here as this setting always has a value. + return self[.enablePush]! + } + + /// The default value of SETTINGS_INITIAL_WINDOW_SIZE. + static let defaultInitialWindowSize: UInt32 = 65535 + + /// Called when SETTINGS are about to be emitted to the network. + /// + /// This function assumes that settings have been validated by the state machine. + /// + /// - parameters: + /// - settings: The settings to emit. + mutating func emitSettings(_ settings: HTTP2Settings) { + self.unacknowlegedSettingsFrames.append(settings) + } + + /// Called when a SETTINGS ACK has been received. + /// + /// This applies the pending SETTINGS values. If there are no pending SETTINGS values, this will throw. + /// + /// - parameters: + /// - onValueChange: A callback that will be invoked once for each setting change. + mutating func receiveSettingsAck(onValueChange: OnValueChangeCallback) throws { + guard self.unacknowlegedSettingsFrames.count > 0 else { + throw NIOHTTP2Errors.receivedBadSettings() + } + + try self.applySettings(self.unacknowlegedSettingsFrames.removeFirst(), onValueChange: onValueChange) + } + + /// Called when a SETTINGS frame has been received from the network. + /// + /// This function assumes that settings have been validated by the state machine. + /// + /// We auto-ACK all SETTINGS, so this applies the settings immediately. + /// + /// - parameters: + /// - settings: The received settings. + /// - onValueChange: A callback that will be invoked once for each setting change. + mutating func receiveSettings(_ settings: HTTP2Settings, onValueChange: OnValueChangeCallback) rethrows { + return try self.applySettings(settings, onValueChange: onValueChange) + } + + /// Applies the given HTTP/2 settings to this state. + /// + /// This function assumes that settings have been validated by the state machine. + /// + /// - parameters: + /// - settings: The settings to apply. + /// - onValueChange: A callback that will be invoked once for each setting change. + private mutating func applySettings(_ settings: HTTP2Settings, onValueChange: OnValueChangeCallback) rethrows { + for setting in settings { + let oldValue = self.currentSettingsValues.updateValue(setting._value, forKey: setting.parameter) + try onValueChange(setting.parameter, oldValue, setting._value) + } + } + + /// Obtain an empty dummy value, suitable for using as a temporary to avoid CoW operations. + static func dummyValue() -> HTTP2SettingsState { + return HTTP2SettingsState() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasFlowControlWindows.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasFlowControlWindows.swift new file mode 100644 index 00000000..b1622014 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasFlowControlWindows.swift @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol implemented by HTTP/2 connection state machine states with flow control windows. +protocol HasFlowControlWindows { + var inboundFlowControlWindow: HTTP2FlowControlWindow { get } + + var outboundFlowControlWindow: HTTP2FlowControlWindow { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasLocalSettings.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasLocalSettings.swift new file mode 100644 index 00000000..9e45af66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasLocalSettings.swift @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol implemented by HTTP/2 connection state machine states with local settings. +/// +/// This protocol provides implementations that can apply changes to the local settings. +protocol HasLocalSettings { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var localSettings: HTTP2SettingsState { get set } + + var streamState: ConnectionStreamState { get set } + + var inboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension HasLocalSettings { + mutating func receiveSettingsAck(frameEncoder: inout HTTP2FrameEncoder) -> StateMachineResultWithEffect { + // We do a little switcheroo here to avoid problems with overlapping accesses to + // self. It's a little more complex than normal because HTTP2SettingsState has + // two CoWable objects, and we don't want to CoW either of them, so we shove a dummy + // value in `self` to avoid that. + var temporarySettings = HTTP2SettingsState.dummyValue() + swap(&temporarySettings, &self.localSettings) + defer { + swap(&temporarySettings, &self.localSettings) + } + + var effect = NIOHTTP2ConnectionStateChange.LocalSettingsChanged() + + do { + try temporarySettings.receiveSettingsAck { (setting, originalValue, newValue) in + switch setting { + case .maxConcurrentStreams: + if self.role == .client { + self.streamState.maxServerInitiatedStreams = newValue + } else { + self.streamState.maxClientInitiatedStreams = newValue + } + case .headerTableSize: + frameEncoder.headerEncoder.maximumDynamicTableSize = Int(newValue) + case .initialWindowSize: + // We default the value of SETTINGS_INITIAL_WINDOW_SIZE, so originalValue mustn't be nil. + // The max value of SETTINGS_INITIAL_WINDOW_SIZE is Int32.max, so we can safely fit it into that here. + let delta = Int32(newValue) - Int32(originalValue!) + + try self.streamState.forAllStreams { + try $0.localInitialWindowSizeChanged(by: delta) + } + + // We do a += here because the value may change multiple times in one settings block. This way, we correctly + // respect that possibility. + effect.streamWindowSizeChange += Int(delta) + case .maxFrameSize: + effect.newMaxFrameSize = newValue + case .maxHeaderListSize: + effect.newMaxHeaderListSize = newValue + default: + // No operation required + return + } + } + return .init(result: .succeed, effect: .localSettingsChanged(effect)) + } catch { + return .init(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasRemoteSettings.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasRemoteSettings.swift new file mode 100644 index 00000000..033cc0c4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/HasRemoteSettings.swift @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A protocol implemented by HTTP/2 connection state machine states with remote settings. +/// +/// This protocol provides implementations that can apply changes to the remote settings. +protocol HasRemoteSettings { + var role: HTTP2ConnectionStateMachine.ConnectionRole { get } + + var remoteSettings: HTTP2SettingsState { get set } + + var streamState: ConnectionStreamState { get set } + + var outboundFlowControlWindow: HTTP2FlowControlWindow { get set } +} + +extension HasRemoteSettings { + mutating func receiveSettingsChange(_ settings: HTTP2Settings, frameDecoder: inout HTTP2FrameDecoder) -> (StateMachineResultWithEffect, PostFrameOperation) { + // We do a little switcheroo here to avoid problems with overlapping accesses to + // self. It's a little more complex than normal because HTTP2SettingsState has + // two CoWable objects, and we don't want to CoW either of them, so we shove a dummy + // value in `self` to avoid that. + var temporarySettings = HTTP2SettingsState.dummyValue() + swap(&temporarySettings, &self.remoteSettings) + defer { + swap(&temporarySettings, &self.remoteSettings) + } + + var effect = NIOHTTP2ConnectionStateChange.RemoteSettingsChanged() + + do { + try temporarySettings.receiveSettings(settings) { (setting, originalValue, newValue) in + switch setting { + case .maxConcurrentStreams: + if self.role == .client { + self.streamState.maxClientInitiatedStreams = newValue + } else { + self.streamState.maxServerInitiatedStreams = newValue + } + effect.newMaxConcurrentStreams = newValue + case .headerTableSize: + frameDecoder.headerDecoder.maxDynamicTableLength = Int(newValue) + case .initialWindowSize: + // We default the value of SETTINGS_INITIAL_WINDOW_SIZE, so originalValue mustn't be nil. + // The max value of SETTINGS_INITIAL_WINDOW_SIZE is Int32.max, so we can safely fit it into that here. + let delta = Int32(newValue) - Int32(originalValue!) + + try self.streamState.forAllStreams { + try $0.remoteInitialWindowSizeChanged(by: delta) + } + + // We do a += here because the value may change multiple times in one settings block. This way, we correctly + // respect that possibility. + effect.streamWindowSizeChange += Int(delta) + case .maxFrameSize: + effect.newMaxFrameSize = newValue + default: + // No operation required + return + } + } + return (.init(result: .succeed, effect: .remoteSettingsChanged(effect)), .sendAck) + } catch let err where err is NIOHTTP2Errors.InvalidFlowControlWindowSize { + return (.init(result: .connectionError(underlyingError: err, type: .flowControlError), effect: nil), .nothing) + } catch { + preconditionFailure("Unexpected error thrown: \(error)") + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/LocallyQuiescingState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/LocallyQuiescingState.swift new file mode 100644 index 00000000..aa416a8b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/LocallyQuiescingState.swift @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A state where the connection is being quiesced by the local peer. In this state, +/// the remote peer may not initiate new streams. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol LocallyQuiescingState { + var lastRemoteStreamID: HTTP2StreamID { get set } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/QuiescingState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/QuiescingState.swift new file mode 100644 index 00000000..af0eb339 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/QuiescingState.swift @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A state where the connection is being quiesced by someone. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol QuiescingState { + var streamState: ConnectionStreamState { get } + + var quiescedByServer: Bool { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/RemotelyQuiescingState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/RemotelyQuiescingState.swift new file mode 100644 index 00000000..8464f789 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/RemotelyQuiescingState.swift @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A state where the connection is being quiesced by the remote peer. In this state, +/// the local peer may not initiate new streams. +/// +/// This protocol should only be conformed to by states for the HTTP/2 connection state machine. +protocol RemotelyQuiescingState { + var lastLocalStreamID: HTTP2StreamID { get set } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/SendAndReceiveGoawayState.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/SendAndReceiveGoawayState.swift new file mode 100644 index 00000000..82f898bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/SendAndReceiveGoawayState.swift @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +typealias SendAndReceiveGoawayState = SendingGoawayState & ReceivingGoawayState diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/StateMachineResult.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/StateMachineResult.swift new file mode 100644 index 00000000..03dfd10d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ConnectionStateMachine/StateMachineResult.swift @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// The event triggered by this state transition attempt. +/// +/// All state transition attempts trigger one of three results. Firstly, they succeed, in which case +/// the frame may be passed on (either outwards, to the serializer, or inwards, to the user). +/// Alternatively, the frame itself may trigger an error. +/// +/// Errors triggered by frames come in two types: connection errors, and stream errors. This refers +/// to the scope at which the error occurs. Stream errors occur at stream scope, and therefore should +/// lead to the teardown of only the affected stream (e.g. RST_STREAM frame emission). Connection errors +/// occur at connection scope: either there is no stream available to tear down, or the error is so +/// foundational that the connection can not be recovered. In either case, the mechanism for tolerating +/// that is to tear the entire connection down, via GOAWAY frame. +/// +/// In both cases, there is an associated kind of error as represented by a `HTTP2ErrorCode`, that +/// should be reported to the remote peer. Additionally, there is an error fired by the internal state +/// machine that can be reported to the user. This enum ensures that both can be propagated out. +enum StateMachineResult { + /// An error that transitions the stream into a fatal error state. This should cause emission of + /// RST_STREAM frames. + case streamError(streamID: HTTP2StreamID, underlyingError: Error, type: HTTP2ErrorCode) + + /// An error that transitions the entire connection into a fatal error state. This should cause + /// emission of GOAWAY frames. + case connectionError(underlyingError: Error, type: HTTP2ErrorCode) + + /// The frame itself was not valid, but it is also not an error. Drop the frame. + case ignoreFrame + + /// The state transition succeeded, the frame may be passed on. + case succeed +} + + +/// Operations that may need to be performed after receiving a frame. +enum PostFrameOperation { + /// An appropriate ACK must be sent. + case sendAck + + /// No operation is needed. + case nothing +} + + +/// An encapsulation of a state machine result along with a possible triggered state change. +struct StateMachineResultWithEffect { + var result: StateMachineResult + + var effect: NIOHTTP2ConnectionStateChange? + + init(result: StateMachineResult, effect: NIOHTTP2ConnectionStateChange?) { + self.result = result + self.effect = effect + } + + init(_ streamEffect: StateMachineResultWithStreamEffect, + inboundFlowControlWindow: HTTP2FlowControlWindow, + outboundFlowControlWindow: HTTP2FlowControlWindow) { + self.result = streamEffect.result + self.effect = streamEffect.effect.map { + NIOHTTP2ConnectionStateChange($0, inboundFlowControlWindow: inboundFlowControlWindow, outboundFlowControlWindow: outboundFlowControlWindow) + } + } +} + +/// An encapsulation of a state machine result along with a state change on a single stream. +struct StateMachineResultWithStreamEffect { + var result: StateMachineResult + + var effect: StreamStateChange? +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ContentLengthVerifier.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ContentLengthVerifier.swift new file mode 100644 index 00000000..e8198205 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/ContentLengthVerifier.swift @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +/// An object that verifies that a content-length field on a HTTP request or +/// response is respected. +struct ContentLengthVerifier { + private var expectedContentLength: Int? +} + +extension ContentLengthVerifier { + /// A chunk of data has been received from the network. + mutating func receivedDataChunk(length: Int) throws { + assert(length >= 0, "received data chunks must be positive") + + // If there was no content-length, don't keep track. + guard let expectedContentLength = self.expectedContentLength else { + return + } + + let newContentLength = expectedContentLength - length + if newContentLength < 0 { + throw NIOHTTP2Errors.contentLengthViolated() + } + self.expectedContentLength = newContentLength + } + + /// Called when end of stream has been received. Validates that the complete body was received. + func endOfStream() throws { + switch self.expectedContentLength { + case .none, .some(0): + break + default: + throw NIOHTTP2Errors.contentLengthViolated() + } + } +} + +extension ContentLengthVerifier { + internal init(_ headers: HPACKHeaders) { + self.expectedContentLength = headers[canonicalForm: "content-length"].first.flatMap { Int($0, radix: 10) } + } + + /// The verifier for use when content length verification is disabled. + internal static var disabled: ContentLengthVerifier { + return ContentLengthVerifier(expectedContentLength: nil) + } +} + +extension ContentLengthVerifier: CustomStringConvertible { + var description: String { + return "ContentLengthVerifier(length: \(String(describing: self.expectedContentLength)))" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/DOSHeuristics.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/DOSHeuristics.swift new file mode 100644 index 00000000..e083444e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/DOSHeuristics.swift @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// Implements some simple denial of service heuristics on inbound frames. +struct DOSHeuristics { + /// The number of "empty" (zero bytes of useful payload) DATA frames we've received since the + /// last useful frame. + /// + /// We reset this count each time we see END_STREAM, or a HEADERS frame, both of which we count + /// as doing useful work. We have a small budget for these because we want to tolerate buggy + /// implementations that occasionally emit empty DATA frames, but don't want to drown in them. + private var receivedEmptyDataFrames: Int + + /// The maximum number of "empty" data frames we're willing to tolerate. + private let maximumSequentialEmptyDataFrames: Int + + internal init(maximumSequentialEmptyDataFrames: Int) { + precondition(maximumSequentialEmptyDataFrames >= 0, + "maximum sequential empty data frames must be positive, got \(maximumSequentialEmptyDataFrames)") + self.maximumSequentialEmptyDataFrames = maximumSequentialEmptyDataFrames + self.receivedEmptyDataFrames = 0 + } +} + + +extension DOSHeuristics { + mutating func process(_ frame: HTTP2Frame) throws { + switch frame.payload { + case .data(let payload): + if payload.data.readableBytes == 0 { + self.receivedEmptyDataFrames += 1 + } + + if payload.endStream { + self.receivedEmptyDataFrames = 0 + } + case .headers: + self.receivedEmptyDataFrames = 0 + case .alternativeService, .goAway, .origin, .ping, .priority, .pushPromise, .rstStream, .settings, .windowUpdate: + // Currently we don't assess these for DoS risk. + () + } + + if self.receivedEmptyDataFrames > self.maximumSequentialEmptyDataFrames { + throw NIOHTTP2Errors.excessiveEmptyDataFrames() + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift new file mode 100644 index 00000000..92047f14 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift @@ -0,0 +1,420 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + + +/// An object that buffers new stream creation attempts to avoid violating +/// the HTTP/2 setting `SETTINGS_MAX_CONCURRENT_STREAMS`. +/// +/// HTTP/2 provides tools for bounding the maximum amount of concurrent streams that a +/// given peer can create. This is used to limit the amount of state that a peer will need +/// to allocate for a given connection. +struct ConcurrentStreamBuffer { + fileprivate struct FrameBuffer { + var frames: MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)> + var streamID: HTTP2StreamID + var currentlyUnblocking: Bool + + init(streamID: HTTP2StreamID) { + self.streamID = streamID + self.frames = MarkedCircularBuffer(initialCapacity: 16) + self.currentlyUnblocking = false + } + } + + /// The mode of the HTTP/2 channel in which we're operating: client or server. + let mode: NIOHTTP2Handler.ParserMode + + /// The current number of active outbound streams. + private(set) var currentOutboundStreams: Int = 0 + + /// The maximum number of active outbound streams, as set by the remote peer. + var maxOutboundStreams: Int + + /// The last outbound stream we initiated. + private var lastOutboundStream: HTTP2StreamID = .rootStream + + /// The frames we've buffered are stored here. + /// + /// This circular buffer has an interesting property: by definition, it should always be sorted. This is because + /// correct construction of new streams requires that stream IDs monotonically increase. As we always pop streams off the + /// front and push them on the back of this buffer, it should remain in a sorted order forever. We have code that maintains + /// this invariant. + /// + /// We regularly search this buffer, and rely on the ability to safely and quickly binary search this buffer. + private var bufferedFrames = SortedCircularBuffer(initialRingCapacity: 16) + + init(mode: NIOHTTP2Handler.ParserMode, initialMaxOutboundStreams: Int) { + self.mode = mode + self.maxOutboundStreams = initialMaxOutboundStreams + } + + /// Called when a stream has been closed. + /// + /// Notes that the current number of outbound streams may have gone down, which is useful information + /// when flushing writes. + mutating func streamClosed(_ streamID: HTTP2StreamID) -> MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)>? { + // We only care about outbound streams. + if streamID.mayBeInitiatedBy(self.mode) { + self.currentOutboundStreams -= 1 + + // We should check whether we have frames here. We shouldn't, but we might, and we need to return them if we do. + if let bufferIndex = self.bufferedFrames.binarySearch(key: { $0.streamID }, needle: streamID) { + let buffer = self.bufferedFrames.remove(at: bufferIndex) + if buffer.frames.count > 0 { + return buffer.frames + } + } + } + + return nil + } + + func invalidateBuffer(reason: ChannelError) { + for buffer in self.bufferedFrames { + for (_, promise) in buffer.frames { + promise?.fail(reason) + } + } + } + + mutating func streamCreated(_ streamID: HTTP2StreamID) { + // We only care about outbound streams. + guard streamID.mayBeInitiatedBy(self.mode) else { + return + } + + self.currentOutboundStreams += 1 + precondition(self.currentOutboundStreams <= self.maxOutboundStreams) + precondition(self.lastOutboundStream <= streamID) + self.lastOutboundStream = streamID + } + + mutating func flushReceived() { + self.bufferedFrames.markFlushPoint() + } + + mutating func processOutboundFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?, channelWritable: Bool) throws -> OutboundFrameAction { + // If this frame is not for a locally initiated stream, then that's fine, just pass it on. Even if the channel isn't + // writable, one of the other two buffers should catch this. + guard frame.streamID != .rootStream && frame.streamID.mayBeInitiatedBy(self.mode) else { + return .forward + } + + // Working out what to do here is awkward. The first concern is whether we're currently buffering frames for streams. + // If we are, it's possible we're buffering frames for this stream already. That may happen even when the stream is technically + // "live" if we have been re-entrantly called and haven't yet finished draining the buffer for this stream. As a result, if we're + // buffering frames we need to check if we're buffering for this stream. If we are, we just append to that buffer. If we're not, + // we don't yet know whether we should be buffering. + // + // Before we search our buffers for this stream we do a quick soundness check: if its stream ID is lower than the first element in the + // array, it won't be there. + // + // Again, we choose to ignore channel writability here because one of the other buffers should catch this frame. + if let firstElement = self.bufferedFrames.first, + frame.streamID >= firstElement.streamID, + let bufferIndex = self.bufferedFrames.binarySearch(key: { $0.streamID }, needle: frame.streamID) { + return self.bufferFrame(frame, promise: promise, bufferIndex: bufferIndex) + } + + // Ok, we're not currently buffering frames for this stream. + // + // Now we need to check if this is for a stream that has already been opened. If it is, and we aren't buffering it, pass + // the frame through. Again, we ignore channel writability here because we don't need to delay state changes: one of the + // other buffers will catch this and it'll be fine. + if frame.streamID <= self.lastOutboundStream { + return .forward + } + + // Now we want to see whether we're allowed to initiate a new stream. If we aren't, then we will buffer this stream. + if self.currentOutboundStreams >= self.maxOutboundStreams || !channelWritable { + // Ok, we can't create a new stream, either due to MAX_CONCURRENT_STREAMS limits or because the channel isn't writable. In this case we + // need to buffer this. We can only have gotten this far if either this stream ID is lower than the first stream ID, or if it's higher + // but doesn't match something in the buffer. As a result, it is an error for this frame to have a stream ID lower than or equal to the + // highest stream ID in the buffer: if it did, we should have found it when we searched above. If that constraint is breached, fail the write. + if let lastElement = self.bufferedFrames.last, frame.streamID <= lastElement.streamID { + throw NIOHTTP2Errors.streamIDTooSmall() + } + + // Ok, the stream ID is fine: buffer this frame. + self.bufferFrameForNewStream(frame, promise: promise) + return .nothing + } else if let lastElement = self.bufferedFrames.last, !lastElement.currentlyUnblocking { + // In principle we can create a new stream, and the channel is writable. However, we have at least one stream that is currently buffered and not unblocking. + // This buffer probably has a HEADERS frame in it, and we really don't want to violate the ordering requirements that implies, so we'll buffer this anyway. + // We still want StreamIDTooSmall protection here. + if frame.streamID <= lastElement.streamID { + throw NIOHTTP2Errors.streamIDTooSmall() + } + + // Ok, the stream ID is fine: buffer this frame. + self.bufferFrameForNewStream(frame, promise: promise) + return .nothing + } + + // Good news, we're allowed to send this frame! Let's do it. + return .forward + } + + /// Returns the next flushed frame on a stream that is either currently active or which can be + /// made active. + mutating func nextFlushedWritableFrame() -> (HTTP2Frame, EventLoopPromise?)? { + // The stream buffers are bisected into two segments. The first, towards the start of the buffer, + // are currently unblocking: that is, we have a buffer, but the stream has been initiated already. + // The second set are those that have not currently been unblocked. Due to the requirements of + // ascending stream ID, if any of these have been flushed then the first one *must* have been. + // Thus, if we have room for another outbound stream, check the next stream and see if it has a + // flushed frame. If it does, flip its unblocking bit to true and grab the next frame out of it. + // Otherwise, we're done. + var index = self.bufferedFrames.startIndex + while index < self.bufferedFrames.endIndex { + guard self.bufferedFrames[index].currentlyUnblocking else { + // We've run out of currently unblocking frames. To the next step! + break + } + + if self.bufferedFrames[index].frames.hasMark { + return self.bufferedFrames.nextWriteFor(index) + } + + self.bufferedFrames.formIndex(after: &index) + } + + // Ok, last shot. Does the next stream exist? If not, we're done. + guard index < self.bufferedFrames.endIndex else { + return nil + } + + // Do we have room to start a new stream? + guard self.currentOutboundStreams < self.maxOutboundStreams else { + return nil + } + + // We have room and the stream exists. Does it have flushed frames? + guard self.bufferedFrames[index].frames.hasMark else { + return nil + } + + // It has flushed frames! Flip it to "unbuffering" and emit the first frame. + self.bufferedFrames.beginUnblocking(index) + return self.bufferedFrames.nextWriteFor(index) + } + + private mutating func bufferFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?, bufferIndex index: SortedCircularBuffer.Index) -> OutboundFrameAction { + // Ok, we need to buffer this frame, and we know we have the index for it. What we do here depends on this frame type. For + // almost all frames, we just append them to the buffer. For RST_STREAM, however, we're in a different spot. RST_STREAM is a + // request to drop all resources for a given stream. We know we have some, but we shouldn't wait to unblock them, we should + // just kill them now and immediately free the resources. + if case .rstStream(let reason) = frame.payload { + // We're going to remove the buffer and fail all the writes. + let writeBuffer = self.bufferedFrames.remove(at: index) + + // If we're currently unbuffering this stream, we need to pass the RST_STREAM frame on for correctness. If we aren't, just + // kill it. + if writeBuffer.currentlyUnblocking { + return .forwardAndDrop(writeBuffer.frames, NIOHTTP2Errors.streamClosed(streamID: frame.streamID, errorCode: reason)) + } else { + return .succeedAndDrop(writeBuffer.frames, NIOHTTP2Errors.streamClosed(streamID: frame.streamID, errorCode: reason)) + } + } + + // Ok, this is a frame we want to buffer. Append it. + self.bufferedFrames.bufferWrite(index: index, frame: frame, promise: promise) + return .nothing + } + + private mutating func bufferFrameForNewStream(_ frame: HTTP2Frame, promise: EventLoopPromise?) { + // We need to buffer this frame. We should have previously checked that it's safe to buffer, so + // we charge on. + assert(self.bufferedFrames.count == 0 || (frame.streamID > self.bufferedFrames.last!.streamID)) + + var frameBuffer = FrameBuffer(streamID: frame.streamID) + frameBuffer.frames.append((frame, promise)) + self.bufferedFrames.append(frameBuffer, key: { $0.streamID }) + } +} + +/// A simple wrapper around CircularBuffer that ensures that it remains sorted. +/// +/// This removes CircularBuffer's MutableCollection conformance because it's not necessary +/// for our use-case here, and it greatly complicates the implementation. If we need it back +/// at any point we can arrange to return it. +/// +/// I could have implemented this as a more general `SortedRandomAccessCollection` structure and +/// then provided specific hooks for appropriate implementations of `MutableCollection`, but altogether +/// that seemed unnecessary. Instead, we provide basically just the surface area we need, but with the +/// implementation of binarySearch written against the RandomAccessCollection protocol to make it more +/// portable in the future. +private struct SortedCircularBuffer { + private var _base: CircularBuffer + + init(initialRingCapacity: Int) { + self._base = CircularBuffer(initialCapacity: initialRingCapacity) + } + + /// Appends an element to this CircularBuffer. Traps if the element is not larger than the current end of this buffer. + mutating func append(_ element: Element, key: (Element) -> SortKey) { + if let last = self._base.last { + precondition(key(element) >= key(last), "Attempted to append unsorted element") + } + + self._base.append(element) + } + + mutating func bufferWrite(index: Index, frame: HTTP2Frame, promise: EventLoopPromise?) { + // To make this work without CoW, we need to temporarily swap out either the entire element or the circular buffer within it to ensure that it + // is held loosely. We choose to swap the circular buffer within it as it avoids even temporarily violating the invariant that the + // backing array is sorted. + assert(frame.streamID == self._base[index].streamID) + + var tempBuffer = MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)>(initialCapacity: 0) + swap(&tempBuffer, &self._base[index].frames) + tempBuffer.append((frame, promise)) + swap(&tempBuffer, &self._base[index].frames) + } + + mutating func beginUnblocking(_ index: Index) { + assert(!self._base[index].currentlyUnblocking) + self._base[index].currentlyUnblocking = true + } + + mutating func nextWriteFor(_ index: Index) -> (HTTP2Frame, EventLoopPromise?) { + // It is an error to call this when there is nothing in the backing buffer! + + // To make this work without CoW, we need to temporarily swap out either the entire element or the circular buffer within it to ensure that it + // is held loosely. We choose to swap the circular buffer within it as it avoids even temporarily violating the invariant that the + // backing array is sorted. + var tempBuffer = MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)>(initialCapacity: 0) + swap(&tempBuffer, &self._base[index].frames) + let write = tempBuffer.removeFirst() + swap(&tempBuffer, &self._base[index].frames) + + if self._base[index].frames.count == 0 { + // We're done here, drop the buffer. + self._base.remove(at: index) + } + + return write + } + + mutating func remove(at index: Index) -> Element { + // This one is easy: simple removal does what we need here. + return self._base.remove(at: index) + } + + mutating func markFlushPoint() { + var index = self._base.startIndex + while index < self._base.endIndex { + // This cannot CoW as it doesn't modify the circular buffer underneath the MCB. + self._base[index].frames.mark() + self._base.formIndex(after: &index) + } + } +} + +extension SortedCircularBuffer: RandomAccessCollection { + typealias Element = CircularBuffer.Element + typealias Index = CircularBuffer.Index + typealias SubSequence = CircularBuffer.SubSequence + typealias Indices = CircularBuffer.Indices + + var startIndex: Index { + return self._base.startIndex + } + + var endIndex: Index { + return self._base.endIndex + } + + var indices: Indices { + return self._base.indices + } + + func distance(from start: Index, to end: Index) -> Int { + return self._base.distance(from: start, to: end) + } + + func formIndex(after i: inout Index) { + self._base.formIndex(after: &i) + } + + func formIndex(before i: inout Index) { + self._base.formIndex(before: &i) + } + + func index(_ i: Index, offsetBy distance: Int) -> Index { + return self._base.index(i, offsetBy: distance) + } + + func index(_ i: Index, offsetBy distance: Int, limitedBy limit: Index) -> Index? { + return self._base.index(i, offsetBy: distance, limitedBy: limit) + } + + func index(after i: Index) -> Index { + return self._base.index(after: i) + } + + func index(before i: Index) -> Index { + return self._base.index(before: i) + } + + subscript(_ i: Index) -> Element { + return self._base[i] + } + + subscript(_ range: Range) -> SubSequence { + return self._base[range] + } +} + +extension SortedCircularBuffer { + func binarySearch(key: (Element) -> SearchKey, needle: SearchKey) -> Index? { + var bottomIndex = self.startIndex + var topIndex = self.endIndex + var sliceSize = self.distance(from: bottomIndex, to: topIndex) + + while sliceSize > 0 { + let middleIndex = self.index(bottomIndex, offsetBy: sliceSize / 2) + + switch key(self[middleIndex]) { + case let potentialKey where potentialKey > needle: + // Too big. We want to search everything smaller than here. + topIndex = middleIndex + case let potentialKey where potentialKey < needle: + // Too small. We want to search everything larger than here. + bottomIndex = self.index(after: middleIndex) + case let potentialKey: + // Got an answer! + assert(potentialKey == needle) + return middleIndex + } + + sliceSize = self.distance(from: bottomIndex, to: topIndex) + } + + return nil + } +} + + +private extension HTTP2StreamID { + func mayBeInitiatedBy(_ mode: NIOHTTP2Handler.ParserMode) -> Bool { + switch mode { + case .client: + return self.networkStreamID % 2 == 1 + case .server: + return self.networkStreamID % 2 == 0 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift new file mode 100644 index 00000000..2d74ea09 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + + +/// A buffer that stores outbound control frames. +/// +/// In general it is preferential to buffer outbound frames instead of passing them into the channel. +/// This is because once the frame has left the HTTP2 handler and moved into the Channel it is no longer +/// easy for us to tell how much data has been buffered. The larger the buffer grows, the more likely it +/// is that the peer is consuming resources of ours that we need for other use-cases, and in some cases +/// this may amount to an actual denial of service attack. +/// +/// We have a number of buffers that handle data frames, but a similar concern applies to control frames +/// too. Control frames need to be emitted with relatively high priority, but they should only be emitted +/// when it will be reasonably possible to write them to the network. As long as it is not possible, we +/// want to store them where we can see them, and use the buffer size to make choices about the connection. +struct ControlFrameBuffer { + /// Any control frame writes that may need to be emitted. + private var pendingControlFrames: MarkedCircularBuffer + + /// The maximum size of the buffer. If we have to buffer more frames than this, + /// we'll kill the connection. + internal var maximumBufferSize: Int +} + + +// MARK:- ControlFrameBuffer initializers +extension ControlFrameBuffer { + internal init(maximumBufferSize: Int) { + // We allocate a circular buffer of reasonable size to ensure that if we ever do have to + // buffer control frames that we won't need to resize this too aggressively. + self.pendingControlFrames = MarkedCircularBuffer(initialCapacity: 16) + self.maximumBufferSize = maximumBufferSize + } +} + + +// MARK:- ControlFrameBuffer frame processing +extension ControlFrameBuffer { + internal mutating func processOutboundFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?, channelWritable: Bool) throws -> OutboundFrameAction { + switch frame.payload { + case .data: + // These frames are not buffered here. If it reached us, it's because we believe the channel is writable, + // and we must have no control frames buffered. + assert(channelWritable, "Received flushed data frame without writable channel") + assert(self.pendingControlFrames.count == 0, "Received flush data frames while buffering control frames") + return .forward + default: + // Control frames. These are what we buffer. We buffer them in two cases: either we have something else + // already buffered (to ensure ordering stays correct), or the channel isn't writable. + if !channelWritable || self.pendingControlFrames.count > 0 { + try self.bufferFrame(frame, promise: promise) + return .nothing + } else { + return .forward + } + } + } + + internal mutating func flushReceived() { + self.pendingControlFrames.mark() + } + + internal mutating func nextFlushedWritableFrame() -> PendingControlFrame? { + if self.pendingControlFrames.hasMark && self.pendingControlFrames.count > 0 { + return self.pendingControlFrames.removeFirst() + } else { + return nil + } + } + + internal func invalidateBuffer(reason: ChannelError) { + for write in self.pendingControlFrames { + write.promise?.fail(reason) + } + } + + private mutating func bufferFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?) throws { + guard self.pendingControlFrames.count < self.maximumBufferSize else { + // Appending another frame would violate the maximum buffer size. We're storing too many frames here, + // we gotta move on. + throw NIOHTTP2Errors.excessiveOutboundFrameBuffering() + } + self.pendingControlFrames.append(PendingControlFrame(frame: frame, promise: promise)) + } +} + + +// MARK:- ControlFrameBuffer.PendingControlFrame definition +extension ControlFrameBuffer { + /// A buffered control frame write and its associated promise. + struct PendingControlFrame { + var frame: HTTP2Frame + var promise: EventLoopPromise? + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFlowControlBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFlowControlBuffer.swift new file mode 100644 index 00000000..5a5cc5a0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFlowControlBuffer.swift @@ -0,0 +1,466 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// A structure that manages buffering outbound frames for active streams to ensure that those streams do not violate flow control rules. +/// +/// This buffer is an extremely performance sensitive part of the HTTP/2 stack. This is because all outbound data passes through it, and +/// all application data needs to be actively buffered by it. The result of this is that state management is extremely expensive, and we +/// need efficient algorithms to process them. +/// +/// The core of the data structure are a collection of `StreamFlowControlState` objects. These objects keep track of the flow control window +/// available for a given stream, as well as any pending writes that may be present on the stream. The pending writes include both DATA and +/// HEADERS frames, as if we've buffered any DATA frames we need to queue HEADERS frames up behind them. +/// +/// Data is appended to these objects on write(). Each write() will trigger both a lookup in the stream data buffers _and_ an append to a +/// data buffer. It is therefore deeply important that both of these operations are as cheap as possible. +/// +/// However, these operations are fundamentally constant in size. Once we have found the stream data buffer, we do not need to worry about +/// all the others. The cost of the write() operation is therefore no more expensive than the cost of the lookup. The same is unfortunately +/// not true for flush(). +/// +/// When we get a flush(), we need to update a bunch of state. In particular, we need to record any previously-written frames that are +/// now flushed, as well as compute which streams may have become writable as a result of the flush call. In early versions of this code +/// we would do a linear scan across _all buffers_, check whether they were writable before, mark their flush point, check if they'd become +/// writable, and then store them in the set of flushable streams. This was monstrously expensive, and worse still the cost was not proportional +/// to the amount of writing done but to the amount of flushing done and the number of active streams. +/// +/// The current design avoids this by having the `StreamFlowControlState` be much more explicit about when it transitions from non-writable to +/// writable and back again. This allows us to keep an Array of writable streams that we use to avoid needing to touch all the streams whenever +/// a flush occurs. This greatly reduces our workload! Additionally, by caching all stream state changes we are not forced to perform repeated +/// expensive computations, but can instead incrementalise the cost on a per-write instead of per-flush basis, keeping track of exactly the +/// decisions we're making. +internal struct OutboundFlowControlBuffer { + /// A buffer of the data sent on the stream that has not yet been passed to the the connection state machine. + private var streamDataBuffers: StreamMap + + /// The streams that have been written to since the last flush. + /// + /// This object is a cache that is used to keep track of what streams need to be modified whenever we get a flush() + /// call. Streams that have been invalidated or removed don't get removed from here: we deal with them once we flush + /// and go to find them to actually write from them. They are not a correctness problem. + private var writableStreams: Set = Set() + + /// The streams with pending data to output. + private var flushableStreams: Set = Set() + + /// The current size of the connection flow control window. May be negative. + internal var connectionWindowSize: Int + + /// The current value of SETTINGS_MAX_FRAME_SIZE set by the peer. + internal var maxFrameSize: Int + + internal init(initialConnectionWindowSize: Int = 65535, initialMaxFrameSize: Int = 1<<14) { + // TODO(cory): HEAP! This should be a heap, sorted off the number of pending bytes! + self.streamDataBuffers = StreamMap() + self.connectionWindowSize = initialConnectionWindowSize + self.maxFrameSize = initialMaxFrameSize + + // Avoid some resizes. + self.writableStreams.reserveCapacity(16) + self.flushableStreams.reserveCapacity(16) + } + + internal mutating func processOutboundFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?) throws -> OutboundFrameAction { + // A side note: there is no special handling for RST_STREAM frames here, unlike in the concurrent streams buffer. This is because + // RST_STREAM frames will cause stream closure notifications, which will force us to drop our buffers. For this reason we can + // simplify our code here, which helps a lot. + let streamID = frame.streamID + + switch frame.payload { + case .data: + // We buffer DATA frames. + if !self.streamDataBuffers.apply(streamID: streamID, { $0.bufferWrite((frame.payload, promise)) }) { + // We don't have this stream ID. This is an internal error, but we won't precondition on it as + // it can happen due to channel handler misconfiguration or other weirdness. We'll just complain. + throw NIOHTTP2Errors.noSuchStream(streamID: streamID) + } + + self.writableStreams.insert(streamID) + return .nothing + case .headers: + // Headers are special. If we have a data frame buffered, we buffer behind it to avoid frames + // being reordered. However, if we don't have a data frame buffered we pass the headers frame on + // immediately, as there is no risk of violating ordering guarantees. + let bufferResult = self.streamDataBuffers.modify(streamID: streamID) { (state: inout StreamFlowControlState) -> Bool in + if state.haveBufferedDataFrame { + state.bufferWrite((frame.payload, promise)) + return true + } else { + return false + } + } + + switch bufferResult { + case .some(true): + self.writableStreams.insert(streamID) + return .nothing + case .some(false), .none: + // We don't need to buffer this, pass it on. + return .forward + } + default: + // For all other frame types, we don't care about them, pass them on. + return .forward + } + } + + internal mutating func flushReceived() { + // Mark the flush points on all the streams we believe are writable. + // We need to double-check here: has their flow control window dropped below zero? If it + // has, the streamID isn't actually writable, and we should abandon adding it here. However, + // we still mark the flush point. + for streamID in self.writableStreams { + let actuallyWritable: Bool? = self.streamDataBuffers.modify(streamID: streamID) { dataBuffer in + dataBuffer.markFlushPoint() + return dataBuffer.hasFlowControlWindowSpaceForNextWrite + } + if let actuallyWritable = actuallyWritable, actuallyWritable { + self.flushableStreams.insert(streamID) + } + } + + self.writableStreams.removeAll(keepingCapacity: true) + } + + private func nextStreamToSend() -> HTTP2StreamID? { + return self.flushableStreams.first + } + + internal mutating func updateWindowOfStream(_ streamID: HTTP2StreamID, newSize: Int32) { + assert(streamID != .rootStream) + + self.streamDataBuffers.apply(streamID: streamID) { + switch $0.updateWindowSize(newSize: Int(newSize)) { + case .unchanged: + // No change, do nothing. + () + case .changed(newValue: true): + // Became writable, and specifically became _flushable_. + self.flushableStreams.insert(streamID) + case .changed(newValue: false): + // Became unwritable. + self.flushableStreams.remove(streamID) + } + } + } + + internal func invalidateBuffer(reason: ChannelError) { + self.streamDataBuffers.forEachValue { buffer in + buffer.failAllWrites(error: reason) + } + } + + internal mutating func streamCreated(_ streamID: HTTP2StreamID, initialWindowSize: UInt32) { + assert(streamID != .rootStream) + + let streamState = StreamFlowControlState(streamID: streamID, initialWindowSize: Int(initialWindowSize)) + self.streamDataBuffers.insert(streamState) + } + + // We received a stream closed event. Drop any stream state we're holding. + // + // - returns: Any buffered stream state we may have been holding so their promises can be failed. + internal mutating func streamClosed(_ streamID: HTTP2StreamID) -> MarkedCircularBuffer<(HTTP2Frame.FramePayload, EventLoopPromise?)>? { + self.flushableStreams.remove(streamID) + guard var streamData = self.streamDataBuffers.removeValue(forStreamID: streamID) else { + // Huh, we didn't have any data for this stream. Oh well. That was easy. + return nil + } + + // To avoid too much work higher up the stack, we only return writes from here if there actually are any. + let writes = streamData.evacuatePendingWrites() + if writes.count > 0 { + return writes + } else { + return nil + } + } + + internal mutating func nextFlushedWritableFrame() -> (HTTP2Frame, EventLoopPromise?)? { + // If the channel isn't writable, we don't want to send anything. + guard let nextStreamID = self.nextStreamToSend(), self.connectionWindowSize > 0 else { + return nil + } + + let nextWrite = self.streamDataBuffers.modify(streamID: nextStreamID) { (state: inout StreamFlowControlState) -> DataBuffer.BufferElement in + let (nextWrite, writabilityState) = state.nextWrite(maxSize: min(self.connectionWindowSize, self.maxFrameSize)) + + switch writabilityState { + case .changed(newValue: false): + self.flushableStreams.remove(nextStreamID) + case .changed(newValue: true), .unchanged: + () + } + + return nextWrite + } + guard let (payload, promise) = nextWrite else { + // The stream was not present. This is weird, it shouldn't ever happen, but we tolerate it, and recurse. + self.flushableStreams.remove(nextStreamID) + return self.nextFlushedWritableFrame() + } + + let frame = HTTP2Frame(streamID: nextStreamID, payload: payload) + return (frame, promise) + } + + internal mutating func initialWindowSizeChanged(_ delta: Int) { + self.streamDataBuffers.mutatingForEachValue { + switch $0.updateWindowSize(newSize: $0.currentWindowSize + delta) { + case .unchanged: + // No change, do nothing. + () + case .changed(newValue: true): + // Became flushable + self.flushableStreams.insert($0.streamID) + case .changed(newValue: false): + // Became unflushable. + self.flushableStreams.remove($0.streamID) + } + } + } +} + + +// MARK: Priority API +extension OutboundFlowControlBuffer { + /// A frame with new priority data has been received that affects prioritisation of outbound frames. + internal mutating func priorityUpdate(streamID: HTTP2StreamID, priorityData: HTTP2Frame.StreamPriorityData) throws { + // Right now we don't actually do anything with priority information. However, we do want to police some parts of + // RFC 7540 § 5.3, where we can, so this hook is already in place for us to extend later. + if streamID == priorityData.dependency { + // Streams may not depend on themselves! + throw NIOHTTP2Errors.priorityCycle(streamID: streamID) + } + } +} + + +private struct StreamFlowControlState: PerStreamData { + let streamID: HTTP2StreamID + internal private(set) var currentWindowSize: Int + private var dataBuffer: DataBuffer + + var haveBufferedDataFrame: Bool { + return self.dataBuffer.haveBufferedDataFrame + } + + var hasFlowControlWindowSpaceForNextWrite: Bool { + return self.currentWindowSize > 0 || self.dataBuffer.nextWriteIsZeroSized + } + + init(streamID: HTTP2StreamID, initialWindowSize: Int) { + self.streamID = streamID + self.currentWindowSize = initialWindowSize + self.dataBuffer = DataBuffer() + } + + mutating func bufferWrite(_ write: DataBuffer.BufferElement) { + self.dataBuffer.bufferWrite(write) + } + + mutating func updateWindowSize(newSize: Int) -> WritabilityState { + let oldWindowSize = self.currentWindowSize + self.currentWindowSize = newSize + + // If we have no marked writes, nothing changed. + guard self.dataBuffer.hasMark else { + return .unchanged + } + + if oldWindowSize <= 0 && self.currentWindowSize > 0 { + // Window opened. We can now write. + return .changed(newValue: true) + } + + if self.currentWindowSize <= 0 && oldWindowSize > 0 { + // Window closed. We can now only write if the first write is zero-sized. + if self.dataBuffer.nextWriteIsZeroSized { + return .unchanged + } + + return .changed(newValue: false) + } + + return .unchanged + } + + mutating func markFlushPoint() { + self.dataBuffer.markFlushPoint() + } + + /// Removes all pending writes, invalidating this structure as it does so. + mutating func evacuatePendingWrites() -> MarkedCircularBuffer { + return self.dataBuffer.evacuatePendingWrites() + } + + func failAllWrites(error: ChannelError) { + self.dataBuffer.failAllWrites(error: error) + } + + mutating func nextWrite(maxSize: Int) -> (DataBuffer.BufferElement, WritabilityState) { + assert(maxSize > 0) + let writeSize = min(maxSize, currentWindowSize) + let nextWrite = self.dataBuffer.nextWrite(maxSize: writeSize) + var writabilityState = WritabilityState.unchanged + + if case .data(let payload) = nextWrite.0 { + self.currentWindowSize -= payload.data.readableBytes + + if !self.dataBuffer.hasMark { + // Eaten the mark, no longer writable. + writabilityState = .changed(newValue: false) + } else if !self.hasFlowControlWindowSpaceForNextWrite { + // No flow control space for writing anymore. + writabilityState = .changed(newValue: false) + } + } else if !self.dataBuffer.hasMark { + // Eaten the mark, no longer writable. + writabilityState = .changed(newValue: false) + } + + assert(self.currentWindowSize >= 0) + return (nextWrite, writabilityState) + } +} + + +private struct DataBuffer { + typealias BufferElement = (HTTP2Frame.FramePayload, EventLoopPromise?) + + private var bufferedChunks: MarkedCircularBuffer + + var haveBufferedDataFrame: Bool { + return self.bufferedChunks.count > 0 + } + + var nextWriteIsZeroSized: Bool { + return self.bufferedChunks.first?.0.isZeroSizedWrite ?? false + } + + var hasMark: Bool { + return self.bufferedChunks.hasMark + } + + /// An empty buffer, we use this avoid an allocation in 'evacuatePendingWrites'. + private static let emptyBuffer = MarkedCircularBuffer(initialCapacity: 0) + + init() { + self.bufferedChunks = MarkedCircularBuffer(initialCapacity: 8) + } + + mutating func bufferWrite(_ write: BufferElement) { + self.bufferedChunks.append(write) + } + + /// Marks the current point in the buffer as the place up to which we have flushed. + mutating func markFlushPoint() { + self.bufferedChunks.mark() + } + + mutating func nextWrite(maxSize: Int) -> BufferElement { + assert(maxSize >= 0) + assert(self.hasMark) + precondition(self.bufferedChunks.count > 0) + + let firstElementIndex = self.bufferedChunks.startIndex + + // First check that the next write is DATA. If it's not, just pass it on. + guard case .data(var contents) = self.bufferedChunks[firstElementIndex].0 else { + return self.bufferedChunks.removeFirst() + } + + // Now check if we have enough space to return the next DATA frame wholesale. + let firstElementReadableBytes = contents.data.readableBytes + if firstElementReadableBytes <= maxSize { + // Return the whole element. + return self.bufferedChunks.removeFirst() + } + + // Here we have too many bytes. So we need to slice out a copy of the data we need + // and leave the rest. + let dataSlice = contents.data.slicePrefix(maxSize) + self.bufferedChunks[self.bufferedChunks.startIndex].0 = .data(contents) + return (.data(.init(data: dataSlice)), nil) + } + + /// Removes all pending writes, invalidating this structure as it does so. + mutating func evacuatePendingWrites() -> MarkedCircularBuffer { + var buffer = DataBuffer.emptyBuffer + swap(&buffer, &self.bufferedChunks) + return buffer + } + + func failAllWrites(error: ChannelError) { + for chunk in self.bufferedChunks { + chunk.1?.fail(error) + } + } +} + + +/// Used to communicate whether a stream has had its writability state change. +fileprivate enum WritabilityState { + case changed(newValue: Bool) + case unchanged +} + + +private extension IOData { + mutating func slicePrefix(_ length: Int) -> IOData { + assert(length < self.readableBytes) + + switch self { + case .byteBuffer(var buf): + // This force-unwrap is safe, as we only invoke this when we have already checked the length. + let newBuf = buf.readSlice(length: length)! + self = .byteBuffer(buf) + return .byteBuffer(newBuf) + + case .fileRegion(var region): + let newRegion = FileRegion(fileHandle: region.fileHandle, readerIndex: region.readerIndex, endIndex: region.readerIndex + length) + region.moveReaderIndex(forwardBy: length) + self = .fileRegion(region) + return .fileRegion(newRegion) + } + } +} + + +extension HTTP2Frame.FramePayload { + fileprivate var isZeroSizedWrite: Bool { + switch self { + case .data(let payload): + return payload.data.readableBytes == 0 && payload.paddingBytes == nil + default: + return true + } + } +} + + +extension StreamMap where Element == StreamFlowControlState { + // + /// Apply a transform to a wrapped DataBuffer. + /// + /// - parameters: + /// - body: A block that will modify the contained value in the + /// optional, if there is one present. + /// - returns: Whether the value was present or not. + @discardableResult + fileprivate mutating func apply(streamID: HTTP2StreamID, _ body: (inout Element) -> Void) -> Bool { + return self.modify(streamID: streamID, body) != nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFrameBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFrameBuffer.swift new file mode 100644 index 00000000..7a4190bb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/Frame Buffers/OutboundFrameBuffer.swift @@ -0,0 +1,388 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// The result of receiving a frame that is about to be sent. +internal enum OutboundFrameAction { + /// The caller should forward the frame on. + case forward + + /// This object has buffered the frame, no action should be taken. + case nothing + + /// A number of frames have to be dropped on the floor due to a RST_STREAM frame being emitted, and the RST_STREAM + /// frame itself must be forwarded. + /// This cannot be done automatically without potentially causing exclusive access violations. + case forwardAndDrop(MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)>, NIOHTTP2Errors.StreamClosed) + + /// A number of frames have to be dropped on the floor due to a RST_STREAM frame being emitted, and the RST_STREAM + /// frame itself should be succeeded and not forwarded. + /// This cannot be done automatically without potentially causing exclusive access violations. + case succeedAndDrop(MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)>, NIOHTTP2Errors.StreamClosed) +} + +/// A buffer of outbound frames used in HTTP/2 connections. +/// +/// Outbound frames have to pass through a number of buffers before they can be sent to the network. Most frames, +/// particularly control frames, are never buffered, but a small number of frames are. These need to pass through +/// the buffers in order to ensure that we avoid violating certain parts of the HTTP/2 protocol. +/// +/// This object provides a "compound" buffer that is made up of multiple smaller buffers. This buffer passes the +/// frames through in order and understands the relationship of the various buffers to each other. +internal struct CompoundOutboundBuffer { + /// A buffer that ensures we don't violate SETTINGS_MAX_CONCURRENT_STREAMS. This is the first buffer all + /// frames pass through. + private var concurrentStreamsBuffer: ConcurrentStreamBuffer + + /// A buffer that ensures we don't violate HTTP/2 flow control. This is the second buffer all frames pass through. + private var flowControlBuffer: OutboundFlowControlBuffer + + /// A buffer that ensures that we store outbound control frames somewhere we can keep track of htem. This is the + /// third buffer all frames pass through. + private var controlFrameBuffer: ControlFrameBuffer +} + + +// MARK: CompoundOutboundBuffer initializers +extension CompoundOutboundBuffer { + internal init(mode: NIOHTTP2Handler.ParserMode, initialMaxOutboundStreams: Int, maxBufferedControlFrames: Int) { + self.concurrentStreamsBuffer = ConcurrentStreamBuffer(mode: mode, initialMaxOutboundStreams: initialMaxOutboundStreams) + self.flowControlBuffer = OutboundFlowControlBuffer() + self.controlFrameBuffer = ControlFrameBuffer(maximumBufferSize: maxBufferedControlFrames) + } +} + +// MARK: CompoundOutboundBuffer outbound methods +// +// Note that this does not quite conform to OutboundFrameBuffer. This is because the implementation of nextFlushedWritableFrame may in principle +// cause an error that requires us to error out on a frame, and we cannot make outcalls from this structure. +extension CompoundOutboundBuffer { + mutating func processOutboundFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?, channelWritable: Bool) throws -> OutboundFrameAction { + var framesToDrop: MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)> = MarkedCircularBuffer(initialCapacity: 0) + var error: NIOHTTP2Errors.StreamClosed? = nil + + // The outbound frames pass through the buffers in order, with the following logic: + // + // 1. If a buffer returns .nothing, return .nothing as the frame has been buffered. + // 2. If a buffer returns .forward, pass to the next buffer. + // 3. If a buffer returns .forwardAndDrop, pass to the next buffer and store the dropped frames. Future buffers may append + // to the dropped frames. + // 4. If a buffer returns .succeedAndDrop, return .succeedAndDrop. + // The return value of the last buffer is the return value of the compound buffer, unless we returned early. + switch try self.concurrentStreamsBuffer.processOutboundFrame(frame, promise: promise, channelWritable: channelWritable) { + case .nothing: + return .nothing + case .succeedAndDrop(let framesToDrop, let error): + return .succeedAndDrop(framesToDrop, error) + case .forwardAndDrop(let newFramesToDrop, let newError): + for frame in newFramesToDrop { + framesToDrop.append(frame) + } + error = newError + break + case .forward: + break + } + + switch try self.flowControlBuffer.processOutboundFrame(frame, promise: promise) { + case .nothing: + return .nothing + case .succeedAndDrop(let framesToDrop, let error): + return .succeedAndDrop(framesToDrop, error) + case .forwardAndDrop(let newFramesToDrop, let newError): + for frame in newFramesToDrop { + framesToDrop.append(frame) + } + error = newError + break + case .forward: + break + } + + switch try self.controlFrameBuffer.processOutboundFrame(frame, promise: promise, channelWritable: channelWritable) { + case .nothing: + return .nothing + case .forward: + break + case .succeedAndDrop, .forwardAndDrop: + preconditionFailure("Control frame buffer may never drop internal frames") + } + + // Ok, we're at the end. If we have an error, return .forwardAndDrop. Otherwise, return .forward. + if let error = error { + return .forwardAndDrop(framesToDrop, error) + } else { + return .forward + } + } + + mutating func flushReceived() { + // Here we just tell every buffer that we have got a flush. + self.concurrentStreamsBuffer.flushReceived() + self.flowControlBuffer.flushReceived() + self.controlFrameBuffer.flushReceived() + } + + enum FlushedWritableFrameResult { + case noFrame + case frame(HTTP2Frame, EventLoopPromise?) + case error(EventLoopPromise?, Error) + } + + mutating func nextFlushedWritableFrame(channelWritable: Bool) -> FlushedWritableFrameResult { + // Before we get to the meat of this: check if the channel is writable. If it's not, we're not doing any work. + guard channelWritable else { + return .noFrame + } + + // Ok, the channel is writable, so we may be able to unbuffer some frames. How do we do it? + // + // First, we check if we have any buffered control frames. Control frames *must* be emitted first, so we want to check that first. + // If there are no buffered control frames, we can then eagerly do as much work as possible on the concurrent streams buffer + // before we get to the flow control buffer. We spin over the concurrent streams buffer, unbuffering everything we can and passing it + // to the flow control buffer and then to the control frame buffer. + // + // We expect only two possible outcomes from this forwarding: .forward or .nothing. If we get .nothing, we continue + // the loop. If we get .forward, we pass the frame to the control frame buffer which again can only give us .forward + // or .nothing. If we get .nothing, we continue the loop. Otherwise, if we get .forward we return the frame, as we can + // send it to the network. + // + // If we get to the end of the loop without forwarding a frame, we mark a new flush point on the flowControlBuffer + // and then do a smaller version of the above loop, now looping on the control frame buffer. Finally, we attempt to go to the + // control frame buffer once more: though in the current version of the code there is no way to have to buffer again here, + // we should still be careful and ensure that we follow the buffering flow. + + // Let's start with the control frame buffer. + if let flushedFrame = self.controlFrameBuffer.nextFlushedWritableFrame() { + return .frame(flushedFrame.frame, flushedFrame.promise) + } + + // Ok, now to move on to work on the concurrent streams buffer. + while let (frame, promise) = self.concurrentStreamsBuffer.nextFlushedWritableFrame() { + do { + if try self.flowControlBuffer.processOutboundFrame(frame, promise: promise).shouldForward && + self.controlFrameBuffer.processOutboundFrame(frame, promise: promise, channelWritable: channelWritable).shouldForward { + return .frame(frame, promise) + } + } catch { + return .error(promise, error) + } + } + + // Mark the flush point, as any frame we forwarded on is by definition flushed. + self.flowControlBuffer.flushReceived() + + while let (frame, promise) = self.flowControlBuffer.nextFlushedWritableFrame() { + do { + if try self.controlFrameBuffer.processOutboundFrame(frame, promise: promise, channelWritable: channelWritable).shouldForward { + return .frame(frame, promise) + } + } catch { + return .error(promise, error) + } + } + + // Mark the flush point again. There either is or is not a frame to write here. + self.controlFrameBuffer.flushReceived() + + if let flushedFrame = self.controlFrameBuffer.nextFlushedWritableFrame() { + return .frame(flushedFrame.frame, flushedFrame.promise) + } else { + return .noFrame + } + } +} + +// MARK: CompoundOutboundBuffer state change methods. +extension CompoundOutboundBuffer { + mutating func streamCreated(_ streamID: HTTP2StreamID, initialWindowSize: UInt32) { + self.concurrentStreamsBuffer.streamCreated(streamID) + self.flowControlBuffer.streamCreated(streamID, initialWindowSize: initialWindowSize) + } + + mutating func streamClosed(_ streamID: HTTP2StreamID) -> DroppedPromisesCollection { + var droppedPromises = DroppedPromisesCollection() + droppedPromises.droppedConcurrentStreamsFrames = self.concurrentStreamsBuffer.streamClosed(streamID) + droppedPromises.droppedFlowControlFrames = self.flowControlBuffer.streamClosed(streamID) + return droppedPromises + } + + func invalidateBuffer() { + self.concurrentStreamsBuffer.invalidateBuffer(reason: ChannelError.ioOnClosedChannel) + self.flowControlBuffer.invalidateBuffer(reason: ChannelError.ioOnClosedChannel) + self.controlFrameBuffer.invalidateBuffer(reason: ChannelError.ioOnClosedChannel) + } + + mutating func updateStreamWindow(_ streamID: HTTP2StreamID, newSize: Int32) { + self.flowControlBuffer.updateWindowOfStream(streamID, newSize: newSize) + } + + mutating func initialWindowSizeChanged(_ delta: Int) { + self.flowControlBuffer.initialWindowSizeChanged(delta) + } + + mutating func priorityUpdate(streamID: HTTP2StreamID, priorityData: HTTP2Frame.StreamPriorityData) throws { + try self.flowControlBuffer.priorityUpdate(streamID: streamID, priorityData: priorityData) + } + + var maxFrameSize: Int { + get { + return self.flowControlBuffer.maxFrameSize + } + set { + self.flowControlBuffer.maxFrameSize = newValue + } + } + + var connectionWindowSize: Int { + get { + return self.flowControlBuffer.connectionWindowSize + } + set { + self.flowControlBuffer.connectionWindowSize = newValue + } + } + + var maxOutboundStreams: Int { + get { + return self.concurrentStreamsBuffer.maxOutboundStreams + } + set { + self.concurrentStreamsBuffer.maxOutboundStreams = newValue + } + } +} + +// MARK: CompoundOutboundBuffer.DroppedPromisesCollection +extension CompoundOutboundBuffer { + /// A structure that contains promises dropped by the buffers when a stream has been closed. + struct DroppedPromisesCollection { + typealias ConcurrentStreamsFrames = MarkedCircularBuffer<(HTTP2Frame, EventLoopPromise?)> + typealias FlowControlFrames = MarkedCircularBuffer<(HTTP2Frame.FramePayload, EventLoopPromise?)> + + var droppedConcurrentStreamsFrames: ConcurrentStreamsFrames? + var droppedFlowControlFrames: FlowControlFrames? + } +} + +extension CompoundOutboundBuffer.DroppedPromisesCollection: Collection { + typealias Element = EventLoopPromise? + + struct Index: Comparable { + fileprivate enum BackingIndex: Equatable { + case concurrentStreams(ConcurrentStreamsFrames.Index) + case flowControl(FlowControlFrames.Index) + case endIndex + } + + fileprivate private(set) var backingIndex: BackingIndex + + fileprivate init(_ backingIndex: BackingIndex) { + self.backingIndex = backingIndex + } + + static func < (lhs: Index, rhs: Index) -> Bool { + switch (lhs.backingIndex, rhs.backingIndex) { + case (.concurrentStreams, .flowControl), + (.concurrentStreams, .endIndex): + return true + case (.concurrentStreams(let lhsBackingIndex), .concurrentStreams(let rhsBackingIndex)): + return lhsBackingIndex < rhsBackingIndex + case (.flowControl, .concurrentStreams): + return false + case (.flowControl, .endIndex): + return true + case (.flowControl(let lhsBackingIndex), .flowControl(let rhsBackingIndex)): + return lhsBackingIndex < rhsBackingIndex + case (.endIndex, _): + return false + } + } + } + + var startIndex: Index { + if let concurrentStreams = self.droppedConcurrentStreamsFrames { + return Index(.concurrentStreams(concurrentStreams.startIndex)) + } else if let flowControl = self.droppedFlowControlFrames { + return Index(.flowControl(flowControl.startIndex)) + } else { + return Index(.endIndex) + } + } + + var endIndex: Index { + return Index(.endIndex) + } + + func index(after index: Index) -> Index { + // These force unwraps are safe, as the index will never point at a collection we don't have. + switch index.backingIndex { + case .concurrentStreams(let baseIndex): + let newBaseIndex = self.droppedConcurrentStreamsFrames!.index(after: baseIndex) + if newBaseIndex != self.droppedConcurrentStreamsFrames!.endIndex { + return Index(.concurrentStreams(newBaseIndex)) + } + + // Gotta move on. + if let flowControl = self.droppedFlowControlFrames { + return Index(.flowControl(flowControl.startIndex)) + } else { + return Index(.endIndex) + } + case .flowControl(let baseIndex): + let newBaseIndex = self.droppedFlowControlFrames!.index(after: baseIndex) + if newBaseIndex != self.droppedFlowControlFrames!.endIndex { + return Index(.flowControl(newBaseIndex)) + } else { + return Index(.endIndex) + } + case .endIndex: + return Index(.endIndex) + } + } + + subscript(_ index: Index) -> Element { + switch index.backingIndex { + case .concurrentStreams(let baseIndex): + return self.droppedConcurrentStreamsFrames![baseIndex].1 + case .flowControl(let baseIndex): + return self.droppedFlowControlFrames![baseIndex].1 + case .endIndex: + preconditionFailure("Attempted to subscript with endIndex") + } + } + + var count: Int { + // An override of count to ensure that we get faster performance than index walking. + let droppedConcurrentStreams = self.droppedConcurrentStreamsFrames?.count ?? 0 + let droppedFlowControl = self.droppedFlowControlFrames?.count ?? 0 + return droppedConcurrentStreams + droppedFlowControl + } +} + + +extension OutboundFrameAction { + /// Whether this frame should be forwarded. Must only be used in cases where the frame + /// cannot lead to drops. + fileprivate var shouldForward: Bool { + switch self { + case .forward: + return true + case .nothing: + return false + case .forwardAndDrop, .succeedAndDrop: + preconditionFailure("Asked to drop frames despite that being impossible") + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HPACKHeaders+Validation.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HPACKHeaders+Validation.swift new file mode 100644 index 00000000..83aebbaa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HPACKHeaders+Validation.swift @@ -0,0 +1,396 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +extension HPACKHeaders { + /// Checks that a given HPACKHeaders block is a valid request header block, meeting all of the constraints of RFC 7540. + /// + /// If the header block is not valid, throws an error. + internal func validateRequestBlock() throws { + return try RequestBlockValidator.validateBlock(self) + } + + /// Checks that a given HPACKHeaders block is a valid response header block, meeting all of the constraints of RFC 7540. + /// + /// If the header block is not valid, throws an error. + internal func validateResponseBlock() throws { + return try ResponseBlockValidator.validateBlock(self) + } + + /// Checks that a given HPACKHeaders block is a valid trailer block, meeting all of the constraints of RFC 7540. + /// + /// If the header block is not valid, throws an error. + internal func validateTrailersBlock() throws { + return try TrailersValidator.validateBlock(self) + } +} + + +/// A HTTP/2 header block is divided into two sections: the leading section, containing pseudo-headers, and +/// the regular header section. Once the first regular header has been seen and we have transitioned into the +/// header section, it is an error to see a pseudo-header again in this block. +fileprivate enum BlockSection { + case pseudoHeaders + case headers + + fileprivate mutating func validField(_ field: HeaderFieldName) throws { + switch (self, field.fieldType) { + case (.pseudoHeaders, .pseudoHeaderField), + (.headers, .regularHeaderField): + // Another header of the same type we're expecting. Do nothing. + break + + case (.pseudoHeaders, .regularHeaderField): + // The regular header fields have begun. + self = .headers + + case (.headers, .pseudoHeaderField): + // This is an error: it's not allowed to send a pseudo-header field once a regular + // header field has been sent. + throw NIOHTTP2Errors.pseudoHeaderAfterRegularHeader(":\(field.baseName)") + } + } +} + + +/// A `HeaderBlockValidator` is an object that can confirm that a HPACK block meets certain constraints. +fileprivate protocol HeaderBlockValidator { + init() + + var allowedPseudoHeaderFields: PseudoHeaders { get } + + var mandatoryPseudoHeaderFields: PseudoHeaders { get } + + mutating func validateNextField(name: HeaderFieldName, value: String, pseudoHeaderType: PseudoHeaders?) throws +} + + +extension HeaderBlockValidator { + /// Validates that a header block meets the requirements of this `HeaderBlockValidator`. + fileprivate static func validateBlock(_ block: HPACKHeaders) throws { + var validator = Self() + var blockSection = BlockSection.pseudoHeaders + var seenPseudoHeaders = PseudoHeaders(rawValue: 0) + + for (name, value, _) in block { + let fieldName = try HeaderFieldName(name) + try blockSection.validField(fieldName) + try fieldName.legalHeaderField(value: value) + + let thisPseudoHeaderFieldType = try seenPseudoHeaders.seenNewHeaderField(fieldName) + + try validator.validateNextField(name: fieldName, value: value, pseudoHeaderType: thisPseudoHeaderFieldType) + } + + // We must only have seen pseudo-header fields allowed on this type of header block, + // and at least the mandatory set. + guard validator.allowedPseudoHeaderFields.isSuperset(of: seenPseudoHeaders) && + validator.mandatoryPseudoHeaderFields.isSubset(of: seenPseudoHeaders) else { + throw NIOHTTP2Errors.invalidPseudoHeaders(block) + } + } +} + + +/// An object that can be used to validate if a given header block is a valid request header block. +fileprivate struct RequestBlockValidator { + private var isConnectRequest: Bool = false +} + +extension RequestBlockValidator: HeaderBlockValidator { + fileprivate mutating func validateNextField(name: HeaderFieldName, value: String, pseudoHeaderType: PseudoHeaders?) throws { + // We have a wrinkle here: the set of allowed and mandatory pseudo headers for requests depends on whether this request is a CONNECT request. + // If it isn't, RFC 7540 § 8.1.2.3 rules, and says that: + // + // > All HTTP/2 requests MUST include exactly one valid value for the ":method", ":scheme", and ":path" pseudo-header fields + // + // Unfortunately, it also has an extra clause that says "unless it is a CONNECT request". That clause makes RFC 7540 § 8.3 relevant, which + // says: + // + // > The ":scheme" and ":path" pseudo-header fields MUST be omitted. + // + // Implicitly, the :authority pseudo-header field must be present here as well, as § 8.3 imposes a specific form on that header field which + // cannot make much sense if the field is optional. + // + // This is further complicated by RFC 8441 (Bootstrapping WebSockets with HTTP/2) which defines the "extended" CONNECT method. RFC 8441 § 4 + // says: + // + // > A new pseudo-header field :protocol MAY be included on request HEADERS indicating the desired protocol to be spoken on the tunnel + // > created by CONNECT. + // + // > On requests that contain the :protocol pseudo-header field, the :scheme and :path pseudo-header fields of the target URI + // > MUST also be included. + // + // > On requests bearing the :protocol pseudo-header field, the :authority pseudo-header field is interpreted according to + // > Section 8.1.2.3 of [RFC7540] instead of Section 8.3 of that document. + // + // We can summarise these rules loosely by saying that: + // + // - On non-CONNECT requests or CONNECT requests with the :protocol pseudo-header, :method, :scheme, and :path are mandatory, :authority is allowed. + // - On CONNECT requests without the :protocol pseudo-header, :method and :authority are mandatory, no others are allowed. + // + // This is a bit awkward. + // + // For now we don't support extended-CONNECT, but when we do we'll need to update the logic here. + if let pseudoHeaderType = pseudoHeaderType { + assert(name.fieldType == .pseudoHeaderField) + + switch pseudoHeaderType { + case .method: + // This is a method pseudo-header. Check if the value is CONNECT. + self.isConnectRequest = value == "CONNECT" + case .path: + // This is a path pseudo-header. It must not be empty. + if value.utf8.count == 0 { + throw NIOHTTP2Errors.emptyPathHeader() + } + default: + break + } + } else { + assert(name.fieldType == .regularHeaderField) + + // We want to check that if the TE header field is present, it only contains "trailers". + if name.baseName == "te" && value != "trailers" { + throw NIOHTTP2Errors.forbiddenHeaderField(name: String(name.baseName), value: value) + } + } + } + + var allowedPseudoHeaderFields: PseudoHeaders { + // For the logic behind this if statement, see the comment in validateNextField. + if self.isConnectRequest { + return .allowedConnectRequestHeaders + } else { + return .allowedRequestHeaders + } + } + + var mandatoryPseudoHeaderFields: PseudoHeaders { + // For the logic behind this if statement, see the comment in validateNextField. + if self.isConnectRequest { + return .mandatoryConnectRequestHeaders + } else { + return .mandatoryRequestHeaders + } + } +} + + +/// An object that can be used to validate if a given header block is a valid response header block. +fileprivate struct ResponseBlockValidator { + let allowedPseudoHeaderFields: PseudoHeaders = .allowedResponseHeaders + + let mandatoryPseudoHeaderFields: PseudoHeaders = .mandatoryResponseHeaders +} + +extension ResponseBlockValidator: HeaderBlockValidator { + fileprivate mutating func validateNextField(name: HeaderFieldName, value: String, pseudoHeaderType: PseudoHeaders?) throws { + return + } +} + + +/// An object that can be used to validate if a given header block is a valid trailer block. +fileprivate struct TrailersValidator { + let allowedPseudoHeaderFields: PseudoHeaders = [] + + let mandatoryPseudoHeaderFields: PseudoHeaders = [] +} + +extension TrailersValidator: HeaderBlockValidator { + fileprivate mutating func validateNextField(name: HeaderFieldName, value: String, pseudoHeaderType: PseudoHeaders?) throws { + return + } +} + + +/// A structure that carries the details of a specific header field name. +/// +/// Used to validate the correctness of a specific header field name at a given +/// point in a header block. +fileprivate struct HeaderFieldName { + /// The type of this header-field: pseudo-header or regular. + fileprivate var fieldType: FieldType + + /// The base name of this header field, which is the name with any leading colon stripped off. + fileprivate var baseName: Substring +} + +extension HeaderFieldName { + /// The types of header fields in HTTP/2. + enum FieldType { + case pseudoHeaderField + case regularHeaderField + } +} + +extension HeaderFieldName { + fileprivate init(_ fieldName: String) throws { + let fieldSubstring = Substring(fieldName) + let fieldBytes = fieldSubstring.utf8 + + let baseNameBytes: Substring.UTF8View + if fieldBytes.first == UInt8(ascii: ":") { + baseNameBytes = fieldBytes.dropFirst() + self.fieldType = .pseudoHeaderField + self.baseName = fieldSubstring.dropFirst() + } else { + baseNameBytes = fieldBytes + self.fieldType = .regularHeaderField + self.baseName = fieldSubstring + } + + guard baseNameBytes.isValidFieldName else { + throw NIOHTTP2Errors.invalidHTTP2HeaderFieldName(fieldName) + } + } + + func legalHeaderField(value: String) throws { + // RFC 7540 § 8.1.2.2 forbids all connection-specific header fields. A connection-specific header field technically + // is one that is listed in the Connection header, but could also be proxy-connection & transfer-encoding, even though + // those are not usually listed in the Connection header. For defensiveness sake, we forbid those too. + // + // There is one more wrinkle, which is that the client is allowed to send TE: trailers, and forbidden from sending TE + // with anything else. We police that separately, as TE is only defined on requests, so we can avoid checking for it + // on responses and trailers. + guard self.fieldType == .regularHeaderField else { + // Pseudo-headers are never connection-specific. + return + } + + switch self.baseName { + case "connection", "transfer-encoding", "proxy-connection": + throw NIOHTTP2Errors.forbiddenHeaderField(name: String(self.baseName), value: value) + default: + return + } + } +} + + +extension Substring.UTF8View { + /// Whether this is a valid HTTP/2 header field name. + fileprivate var isValidFieldName: Bool { + /// RFC 7230 defines header field names as matching the `token` ABNF, which is: + /// + /// token = 1*tchar + /// + /// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + /// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + /// / DIGIT / ALPHA + /// ; any VCHAR, except delimiters + /// + /// DIGIT = %x30-39 + /// ; 0-9 + /// + /// ALPHA = %x41-5A / %x61-7A ; A-Z / a-z + /// + /// RFC 7540 subsequently clarifies that HTTP/2 headers must be converted to lowercase before + /// sending. This therefore excludes the range A-Z in ALPHA. If we convert tchar to the range syntax + /// used in DIGIT and ALPHA, and then collapse the ranges that are more than two elements long, we get: + /// + /// tchar = %x21 / %x23-27 / %x2A / %x2B / %x2D / %x2E / %x5E-60 / %x7C / %x7E / %x30-39 / + /// / %x41-5A / %x61-7A + /// + /// Now we can strip out the uppercase characters, and shuffle these so they're in ascending order: + /// + /// tchar = %x21 / %x23-27 / %x2A / %x2B / %x2D / %x2E / %x30-39 / %x5E-60 / %x61-7A + /// / %x7C / %x7E + /// + /// Then we can also spot that we have a pair of ranges that bump into each other and do one further level + /// of collapsing. + /// + /// tchar = %x21 / %x23-27 / %x2A / %x2B / %x2D / %x2E / %x30-39 / %x5E-7A + /// / %x7C / %x7E + /// + /// We can then translate this into a straightforward switch statement to check whether the code + /// units are valid. + return self.allSatisfy { codeUnit in + switch codeUnit { + case 0x21, 0x23...0x27, 0x2a, 0x2b, 0x2d, 0x2e, 0x30...0x39, + 0x5e...0x7a, 0x7c, 0x7e: + return true + default: + return false + } + } + } +} + + +/// A set of all pseudo-headers defined in HTTP/2. +fileprivate struct PseudoHeaders: OptionSet { + var rawValue: UInt8 + + static let path = PseudoHeaders(rawValue: 1 << 0) + static let method = PseudoHeaders(rawValue: 1 << 1) + static let scheme = PseudoHeaders(rawValue: 1 << 2) + static let authority = PseudoHeaders(rawValue: 1 << 3) + static let status = PseudoHeaders(rawValue: 1 << 4) + + static let mandatoryRequestHeaders: PseudoHeaders = [.path, .method, .scheme] + static let allowedRequestHeaders: PseudoHeaders = [.path, .method, .scheme, .authority] + static let mandatoryConnectRequestHeaders: PseudoHeaders = [.method, .authority] + static let allowedConnectRequestHeaders: PseudoHeaders = [.method, .authority] + static let mandatoryResponseHeaders: PseudoHeaders = [.status] + static let allowedResponseHeaders: PseudoHeaders = [.status] +} + +extension PseudoHeaders { + /// Obtain a PseudoHeaders optionset containing the bit for a known pseudo header. Fails if this is an unknown pseudoheader. + /// Traps if this is not a pseudo-header at all. + init?(headerFieldName name: HeaderFieldName) { + precondition(name.fieldType == .pseudoHeaderField) + + switch name.baseName { + case "path": + self = .path + case "method": + self = .method + case "scheme": + self = .scheme + case "authority": + self = .authority + case "status": + self = .status + default: + return nil + } + } +} + +extension PseudoHeaders { + /// Updates this set of PseudoHeaders with any new pseudo headers we've seen. Also returns a PseudoHeaders that marks + /// the type of this specific header field. + mutating func seenNewHeaderField(_ name: HeaderFieldName) throws -> PseudoHeaders? { + // We need to check if this is a pseudo-header field we've seen before and one we recognise. + // We only want to see a pseudo-header field once. + guard name.fieldType == .pseudoHeaderField else { + return nil + } + + guard let pseudoHeaderType = PseudoHeaders(headerFieldName: name) else { + throw NIOHTTP2Errors.unknownPseudoHeader(":\(name.baseName)") + } + + if self.contains(pseudoHeaderType) { + throw NIOHTTP2Errors.duplicatePseudoHeader(":\(name.baseName)") + } + + self.formUnion(pseudoHeaderType) + + return pseudoHeaderType + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ChannelHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ChannelHandler.swift new file mode 100644 index 00000000..d8365c7e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ChannelHandler.swift @@ -0,0 +1,678 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore +import NIOHPACK + + +/// NIO's default settings used for initial settings values on HTTP/2 streams, when the user hasn't +/// overridden that. This limits the max concurrent streams to 100, and limits the max header list +/// size to 16kB, to avoid trivial resource exhaustion on NIO HTTP/2 users. +public let nioDefaultSettings = [ + HTTP2Setting(parameter: .maxConcurrentStreams, value: 100), + HTTP2Setting(parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize), +] + + +public final class NIOHTTP2Handler: ChannelDuplexHandler { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = HTTP2Frame + public typealias OutboundIn = HTTP2Frame + public typealias OutboundOut = IOData + + /// The magic string sent by clients at the start of a HTTP/2 connection. + private static let clientMagic: StaticString = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + + /// The connection state machine. We always have one of these. + private var stateMachine: HTTP2ConnectionStateMachine + + /// The frame decoder. Right now this is optional because it needs an allocator, which + /// we don't have until the channel is up. The rules of handler lifecycles mean that + /// this can never fail to unwrap in a proper program. + private var frameDecoder: HTTP2FrameDecoder! + + /// The frame encoder. Right now this is optional because it needs an allocator, which + /// we don't have until the channel is up. The rules of handler lifecycles mean that + /// this can never fail to unwrap in a proper program. + private var frameEncoder: HTTP2FrameEncoder! + + /// The buffer we write data into. This is optional because we need an allocator, which + /// we don't have until the channel is up. The rules of handler lifecycles mean that + /// this can never fail to unwrap in a proper program. + private var writeBuffer: ByteBuffer! + + /// A buffer where we write inbound events before we deliver them. This avoids us reordering + /// user events and frames when re-entrant operations occur. + private var inboundEventBuffer: InboundEventBuffer = InboundEventBuffer() + + /// A buffer for outbound frames. In some cases it is necessary to buffer outbound frames before + /// sending, if sending them would trigger a protocol violation. Those buffered frames live here. + private var outboundBuffer: CompoundOutboundBuffer + + /// This flag is set to false each time we issue a flush, and set to true + /// each time we write a frame. This allows us to avoid flushing unnecessarily. + private var wroteFrame: Bool = false + + /// This object deploys heuristics to attempt to detect denial of service attacks. + private var denialOfServiceValidator: DOSHeuristics + + /// The mode this handler is operating in. + private let mode: ParserMode + + /// The initial local settings of this connection. Sent as part of the preamble. + private let initialSettings: HTTP2Settings + + // TODO(cory): We should revisit this: ideally we won't drop frames but would still deliver them where + // possible, but I'm not doing that right now. + /// Whether the channel has closed. If it has, we abort the decode loop, as we don't delay channelInactive. + private var channelClosed: Bool = false + + /// A cached copy of the channel writability state. Updated in channelWritabilityChanged notifications, and used + /// to determine buffering strategies. + private var channelWritable: Bool = true + + /// This variable is set to `true` when we are inside `unbufferAndFlushAutomaticFrames` and protects us from reentering the method + /// which can cause an infinite recursion. + private var isUnbufferingAndFlushingAutomaticFrames = false + + /// The mode for this parser to operate in: client or server. + public enum ParserMode { + /// Client mode + case client + + /// Server mode + case server + } + + /// Whether a certain operation has validation enabled or not. + public enum ValidationState { + case enabled + + case disabled + } + + public convenience init(mode: ParserMode, + initialSettings: HTTP2Settings = nioDefaultSettings, + headerBlockValidation: ValidationState = .enabled, + contentLengthValidation: ValidationState = .enabled) { + self.init(mode: mode, + initialSettings: initialSettings, + headerBlockValidation: headerBlockValidation, + contentLengthValidation: contentLengthValidation, + maximumSequentialEmptyDataFrames: 1, + maximumBufferedControlFrames: 10000) + } + + public init(mode: ParserMode, + initialSettings: HTTP2Settings = nioDefaultSettings, + headerBlockValidation: ValidationState = .enabled, + contentLengthValidation: ValidationState = .enabled, + maximumSequentialEmptyDataFrames: Int = 1, + maximumBufferedControlFrames: Int = 10000) { + self.stateMachine = HTTP2ConnectionStateMachine(role: .init(mode), headerBlockValidation: .init(headerBlockValidation), contentLengthValidation: .init(contentLengthValidation)) + self.mode = mode + self.initialSettings = initialSettings + self.outboundBuffer = CompoundOutboundBuffer(mode: mode, initialMaxOutboundStreams: 100, maxBufferedControlFrames: maximumBufferedControlFrames) + self.denialOfServiceValidator = DOSHeuristics(maximumSequentialEmptyDataFrames: maximumSequentialEmptyDataFrames) + } + + public func handlerAdded(context: ChannelHandlerContext) { + self.frameDecoder = HTTP2FrameDecoder(allocator: context.channel.allocator, expectClientMagic: self.mode == .server) + self.frameEncoder = HTTP2FrameEncoder(allocator: context.channel.allocator) + self.writeBuffer = context.channel.allocator.buffer(capacity: 128) + + if context.channel.isActive { + self.writeAndFlushPreamble(context: context) + } + } + + public func handlerRemoved(context: ChannelHandlerContext) { + // Any frames we're buffering need to be dropped. + self.outboundBuffer.invalidateBuffer() + } + + public func channelActive(context: ChannelHandlerContext) { + self.writeAndFlushPreamble(context: context) + context.fireChannelActive() + } + + public func channelInactive(context: ChannelHandlerContext) { + self.channelClosed = true + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let data = self.unwrapInboundIn(data) + self.frameDecoder.append(bytes: data) + + // Before we go in here we need to deliver any pending user events. This is because + // we may have been called re-entrantly. + self.processPendingUserEvents(context: context) + + // We parse eagerly to attempt to give back buffers to the reading channel wherever possible. + self.frameDecodeLoop(context: context) + } + + public func channelReadComplete(context: ChannelHandlerContext) { + self.outboundBuffer.flushReceived() + self.unbufferAndFlushAutomaticFrames(context: context) + context.fireChannelReadComplete() + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let frame = self.unwrapOutboundIn(data) + self.writeBufferedFrame(context: context, frame: frame, promise: promise) + } + + public func flush(context: ChannelHandlerContext) { + // We need to always flush here, so we'll pretend we wrote an automatic frame even if we didn't. + self.outboundBuffer.flushReceived() + self.unbufferAndFlushAutomaticFrames(context: context) + } + + public func channelWritabilityChanged(context: ChannelHandlerContext) { + // Update the writability status. If the channel has become writeable, we can also attempt to unbuffer some frames here. + self.channelWritable = context.channel.isWritable + if self.channelWritable { + self.unbufferAndFlushAutomaticFrames(context: context) + } + context.fireChannelWritabilityChanged() + } +} + + +/// Inbound frame handling. +extension NIOHTTP2Handler { + /// Spins over the frame decoder parsing frames and sending them down the channel pipeline. + private func frameDecodeLoop(context: ChannelHandlerContext) { + while !self.channelClosed, let (nextFrame, length) = self.decodeFrame(context: context) { + guard case .continue = self.processFrame(nextFrame, flowControlledLength: length, context: context) else { + break + } + } + } + + /// Decodes a single frame. Returns `nil` if there is no frame to process, or if an error occurred. + private func decodeFrame(context: ChannelHandlerContext) -> (HTTP2Frame, flowControlledLength: Int)? { + do { + return try self.frameDecoder.nextFrame() + } catch InternalError.codecError(let code) { + self.inboundConnectionErrorTriggered(context: context, underlyingError: NIOHTTP2Errors.unableToParseFrame(), reason: code) + return nil + } catch is NIOHTTP2Errors.BadClientMagic { + self.inboundConnectionErrorTriggered(context: context, underlyingError: NIOHTTP2Errors.badClientMagic(), reason: .protocolError) + return nil + } catch is NIOHTTP2Errors.ExcessivelyLargeHeaderBlock { + self.inboundConnectionErrorTriggered(context: context, underlyingError: NIOHTTP2Errors.excessivelyLargeHeaderBlock(), reason: .protocolError) + return nil + } catch { + self.inboundConnectionErrorTriggered(context: context, underlyingError: error, reason: .internalError) + return nil + } + } + + enum FrameProcessResult { + case `continue` + case stop + } + + private func processFrame(_ frame: HTTP2Frame, flowControlledLength: Int, context: ChannelHandlerContext) -> FrameProcessResult { + // All frames have one basic processing step: do we send them on, or drop them? + // Some frames have further processing steps, regarding triggering user events or other operations. + // Here we centralise this processing. + var result: StateMachineResultWithEffect + + switch frame.payload { + case .alternativeService(let origin, let field): + result = self.stateMachine.receiveAlternativeService(origin: origin, field: field) + case .origin(let origins): + result = self.stateMachine.receiveOrigin(origins: origins) + case .data(let dataBody): + result = self.stateMachine.receiveData(streamID: frame.streamID, contentLength: dataBody.data.readableBytes, flowControlledBytes: flowControlledLength, isEndStreamSet: dataBody.endStream) + case .goAway(let lastStreamID, _, _): + result = self.stateMachine.receiveGoaway(lastStreamID: lastStreamID) + case .headers(let headerBody): + result = self.stateMachine.receiveHeaders(streamID: frame.streamID, headers: headerBody.headers, isEndStreamSet: headerBody.endStream) + + // Apply a priority update if one is here. If this fails, it may cause a connection error. + if let priorityData = headerBody.priorityData { + do { + try self.outboundBuffer.priorityUpdate(streamID: frame.streamID, priorityData: priorityData) + } catch { + result = StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + } + + case .ping(let pingData, let ack): + let (stateMachineResult, postPingOperation) = self.stateMachine.receivePing(ackFlagSet: ack) + result = stateMachineResult + switch postPingOperation { + case .nothing: + break + case .sendAck: + let responseFrame = HTTP2Frame(streamID: frame.streamID, payload: .ping(pingData, ack: true)) + self.writeBufferedFrame(context: context, frame: responseFrame, promise: nil) + } + + case .priority(let priorityData): + result = self.stateMachine.receivePriority() + + // Apply a priority update if one is here. If this fails, it may cause a connection error. + do { + try self.outboundBuffer.priorityUpdate(streamID: frame.streamID, priorityData: priorityData) + } catch { + result = StateMachineResultWithEffect(result: .connectionError(underlyingError: error, type: .protocolError), effect: nil) + } + + case .pushPromise(let pushedStreamData): + result = self.stateMachine.receivePushPromise(originalStreamID: frame.streamID, childStreamID: pushedStreamData.pushedStreamID, headers: pushedStreamData.headers) + case .rstStream(let reason): + result = self.stateMachine.receiveRstStream(streamID: frame.streamID, reason: reason) + case .settings(let newSettings): + let (stateMachineResult, postSettingsOperation) = self.stateMachine.receiveSettings(newSettings, + frameEncoder: &self.frameEncoder, + frameDecoder: &self.frameDecoder) + result = stateMachineResult + switch postSettingsOperation { + case .nothing: + break + case .sendAck: + self.writeBufferedFrame(context: context, frame: HTTP2Frame(streamID: .rootStream, payload: .settings(.ack)), promise: nil) + } + + case .windowUpdate(let increment): + result = self.stateMachine.receiveWindowUpdate(streamID: frame.streamID, windowIncrement: UInt32(increment)) + } + + self.processDoSRisk(frame, result: &result) + self.processStateChange(result.effect) + + let returnValue: FrameProcessResult + switch result.result { + case .succeed: + // Frame is good, we can pass it on. + context.fireChannelRead(self.wrapInboundOut(frame)) + returnValue = .continue + case .ignoreFrame: + // Frame is good but no action needs to be taken. + returnValue = .continue + case .connectionError(let underlyingError, let errorCode): + // We should stop parsing on received connection errors, the connection is going away anyway. + self.inboundConnectionErrorTriggered(context: context, underlyingError: underlyingError, reason: errorCode) + returnValue = .stop + case .streamError(let streamID, let underlyingError, let errorCode): + // We can continue parsing on stream errors in most cases, the frame is just ignored. + self.inboundStreamErrorTriggered(context: context, streamID: streamID, underlyingError: underlyingError, reason: errorCode) + returnValue = .continue + } + + // Before we return the loop we process any user events that are currently pending. + // These will likely only be ones that were generated now. + self.processPendingUserEvents(context: context) + + return returnValue + } + + /// A connection error was hit while receiving a frame. + private func inboundConnectionErrorTriggered(context: ChannelHandlerContext, underlyingError: Error, reason: HTTP2ErrorCode) { + // A connection error brings the entire connection down. We attempt to write a GOAWAY frame, and then report this + // error. It's possible that we'll be unable to write the GOAWAY frame, but that also just logs the error. + // Because we don't know what data the user handled before we got this, we propose that they may have seen all of it. + // The user may choose to fire a more specific error if they wish. + let goAwayFrame = HTTP2Frame(streamID: .rootStream, payload: .goAway(lastStreamID: .maxID, errorCode: reason, opaqueData: nil)) + self.writeUnbufferedFrame(context: context, frame: goAwayFrame) + self.flushIfNecessary(context: context) + context.fireErrorCaught(underlyingError) + } + + /// A stream error was hit while receiving a frame. + private func inboundStreamErrorTriggered(context: ChannelHandlerContext, streamID: HTTP2StreamID, underlyingError: Error, reason: HTTP2ErrorCode) { + // A stream error brings down a single stream, causing a RST_STREAM frame. We attempt to write this, and then report + // the error. It's possible that we'll be unable to write this, which will likely escalate this error, but that's + // the user's issue. + let rstStreamFrame = HTTP2Frame(streamID: streamID, payload: .rstStream(reason)) + self.writeBufferedFrame(context: context, frame: rstStreamFrame, promise: nil) + self.flushIfNecessary(context: context) + context.fireErrorCaught(underlyingError) + } + + /// Emit any pending user events. + private func processPendingUserEvents(context: ChannelHandlerContext) { + for event in self.inboundEventBuffer { + context.fireUserInboundEventTriggered(event) + } + } + + private func processDoSRisk(_ frame: HTTP2Frame, result: inout StateMachineResultWithEffect) { + do { + try self.denialOfServiceValidator.process(frame) + } catch { + result.result = StateMachineResult.connectionError(underlyingError: error, type: .enhanceYourCalm) + result.effect = nil + } + } +} + + +/// Outbound frame handling. +extension NIOHTTP2Handler { + /// Issues the preamble when necessary. + private func writeAndFlushPreamble(context: ChannelHandlerContext) { + guard self.stateMachine.mustSendPreamble else { + return + } + + if case .client = self.mode { + self.writeBuffer.clear() + self.writeBuffer.writeStaticString(NIOHTTP2Handler.clientMagic) + context.write(self.wrapOutboundOut(.byteBuffer(self.writeBuffer)), promise: nil) + } + + let initialSettingsFrame = HTTP2Frame(streamID: .rootStream, payload: .settings(.settings(self.initialSettings))) + self.writeUnbufferedFrame(context: context, frame: initialSettingsFrame) + self.flushIfNecessary(context: context) + } + + /// Write a frame that is allowed to be buffered (that is, that participates in the outbound frame buffer). + private func writeBufferedFrame(context: ChannelHandlerContext, frame: HTTP2Frame, promise: EventLoopPromise?) { + do { + switch try self.outboundBuffer.processOutboundFrame(frame, promise: promise, channelWritable: self.channelWritable) { + case .nothing: + // Nothing to do, got buffered. + break + case .forward: + self.processOutboundFrame(context: context, frame: frame, promise: promise) + case .forwardAndDrop(let framesToDrop, let error): + // We need to forward this frame, and then fail these promises. + self.processOutboundFrame(context: context, frame: frame, promise: promise) + for (_, promise) in framesToDrop { + promise?.fail(error) + } + case .succeedAndDrop(let framesToDrop, let error): + // We need to succeed this frame promise and fail the others. We fail the others first to keep the + // promises in order. + for (_, promise) in framesToDrop { + promise?.fail(error) + } + promise?.succeed(()) + } + } catch let error where error is NIOHTTP2Errors.ExcessiveOutboundFrameBuffering { + self.inboundConnectionErrorTriggered(context: context, underlyingError: error, reason: .enhanceYourCalm) + } catch { + promise?.fail(error) + } + } + + /// Write a frame that is not allowed to be buffered. These are usually GOAWAY frames, which must be urgently emitted as the connection + /// is about to be lost. These frames may not have associated promises. + private func writeUnbufferedFrame(context: ChannelHandlerContext, frame: HTTP2Frame) { + self.processOutboundFrame(context: context, frame: frame, promise: nil) + } + + private func processOutboundFrame(context: ChannelHandlerContext, frame: HTTP2Frame, promise: EventLoopPromise?) { + let result: StateMachineResultWithEffect + + switch frame.payload { + case .alternativeService(let origin, let field): + // Returns 'Never'; alt service frames are not currently handled. + self.stateMachine.sendAlternativeService(origin: origin, field: field) + case .origin(let origins): + // Returns 'Never'; origin frames are not currently handled. + self.stateMachine.sendOrigin(origins: origins) + case .data(let data): + // TODO(cory): Correctly account for padding data. + result = self.stateMachine.sendData(streamID: frame.streamID, contentLength: data.data.readableBytes, flowControlledBytes: data.data.readableBytes, isEndStreamSet: data.endStream) + case .goAway(let lastStreamID, _, _): + result = self.stateMachine.sendGoaway(lastStreamID: lastStreamID) + case .headers(let headerContent): + result = self.stateMachine.sendHeaders(streamID: frame.streamID, headers: headerContent.headers, isEndStreamSet: headerContent.endStream) + case .ping: + result = self.stateMachine.sendPing() + case .priority: + result = self.stateMachine.sendPriority() + case .pushPromise(let pushedContent): + result = self.stateMachine.sendPushPromise(originalStreamID: frame.streamID, childStreamID: pushedContent.pushedStreamID, headers: pushedContent.headers) + case .rstStream(let reason): + result = self.stateMachine.sendRstStream(streamID: frame.streamID, reason: reason) + case .settings(.settings(let newSettings)): + result = self.stateMachine.sendSettings(newSettings) + case .settings(.ack): + // We do not allow sending SETTINGS ACK frames. However, we emit them automatically ourselves, so we + // choose to tolerate it, even if users do the wrong thing. + result = .init(result: .succeed, effect: nil) + case .windowUpdate(let increment): + result = self.stateMachine.sendWindowUpdate(streamID: frame.streamID, windowIncrement: UInt32(increment)) + } + + self.processStateChange(result.effect) + + switch result.result { + case .ignoreFrame: + preconditionFailure("Cannot be asked to ignore outbound frames.") + case .connectionError(let underlyingError, _): + self.outboundConnectionErrorTriggered(context: context, promise: promise, underlyingError: underlyingError) + return + case .streamError(streamID: let streamID, underlyingError: let underlyingError, _): + self.outboundStreamErrorTriggered(context: context, promise: promise, streamID: streamID, underlyingError: underlyingError) + return + case .succeed: + self.writeBuffer.clear() + self.encodeAndWriteFrame(context: context, frame: frame, promise: promise) + } + + // This may have caused user events that need to be fired, so do so. + self.processPendingUserEvents(context: context) + } + + /// Encodes a frame and writes it to the network. + private func encodeAndWriteFrame(context: ChannelHandlerContext, frame: HTTP2Frame, promise: EventLoopPromise?) { + let extraFrameData: IOData? + + do { + extraFrameData = try self.frameEncoder.encode(frame: frame, to: &self.writeBuffer) + } catch InternalError.codecError { + self.outboundConnectionErrorTriggered(context: context, promise: promise, underlyingError: NIOHTTP2Errors.unableToSerializeFrame()) + return + } catch { + self.outboundConnectionErrorTriggered(context: context, promise: promise, underlyingError: error) + return + } + + // Ok, if we got here we're good to send data. We want to attach the promise to the latest write, not + // always the frame header. + self.wroteFrame = true + if let extraFrameData = extraFrameData { + context.write(self.wrapOutboundOut(.byteBuffer(self.writeBuffer)), promise: nil) + context.write(self.wrapOutboundOut(extraFrameData), promise: promise) + } else { + context.write(self.wrapOutboundOut(.byteBuffer(self.writeBuffer)), promise: promise) + } + } + + /// A connection error was hit while attempting to send a frame. + private func outboundConnectionErrorTriggered(context: ChannelHandlerContext, promise: EventLoopPromise?, underlyingError: Error) { + promise?.fail(underlyingError) + context.fireErrorCaught(underlyingError) + } + + /// A stream error was hit while attempting to send a frame. + private func outboundStreamErrorTriggered(context: ChannelHandlerContext, promise: EventLoopPromise?, streamID: HTTP2StreamID, underlyingError: Error) { + promise?.fail(underlyingError) + context.fireErrorCaught(NIOHTTP2Errors.streamError(streamID: streamID, baseError: underlyingError)) + } +} + + +// MARK:- Helpers +extension NIOHTTP2Handler { + private func processStateChange(_ stateChange: NIOHTTP2ConnectionStateChange?) { + guard let stateChange = stateChange else { + return + } + + switch stateChange { + case .streamClosed(let streamClosedData): + self.outboundBuffer.connectionWindowSize = streamClosedData.localConnectionWindowSize + self.inboundEventBuffer.pendingUserEvent(StreamClosedEvent(streamID: streamClosedData.streamID, reason: streamClosedData.reason)) + self.inboundEventBuffer.pendingUserEvent(NIOHTTP2WindowUpdatedEvent(streamID: .rootStream, inboundWindowSize: streamClosedData.remoteConnectionWindowSize, outboundWindowSize: streamClosedData.localConnectionWindowSize)) + + let droppedPromises = self.outboundBuffer.streamClosed(streamClosedData.streamID) + self.failDroppedPromises(droppedPromises, streamID: streamClosedData.streamID, errorCode: streamClosedData.reason ?? .cancel) + case .streamCreated(let streamCreatedData): + self.outboundBuffer.streamCreated(streamCreatedData.streamID, initialWindowSize: streamCreatedData.localStreamWindowSize.map(UInt32.init) ?? 0) + self.inboundEventBuffer.pendingUserEvent(NIOHTTP2StreamCreatedEvent(streamID: streamCreatedData.streamID, + localInitialWindowSize: streamCreatedData.localStreamWindowSize.map(UInt32.init), + remoteInitialWindowSize: streamCreatedData.remoteStreamWindowSize.map(UInt32.init))) + case .bulkStreamClosure(let streamClosureData): + for droppedStream in streamClosureData.closedStreams { + self.inboundEventBuffer.pendingUserEvent(StreamClosedEvent(streamID: droppedStream, reason: .cancel)) + + let droppedPromises = self.outboundBuffer.streamClosed(droppedStream) + self.failDroppedPromises(droppedPromises, streamID: droppedStream, errorCode: .cancel) + } + case .flowControlChange(let change): + self.outboundBuffer.connectionWindowSize = change.localConnectionWindowSize + self.inboundEventBuffer.pendingUserEvent(NIOHTTP2WindowUpdatedEvent(streamID: .rootStream, inboundWindowSize: change.remoteConnectionWindowSize, outboundWindowSize: change.localConnectionWindowSize)) + if let streamSize = change.localStreamWindowSize { + self.outboundBuffer.updateStreamWindow(streamSize.streamID, newSize: streamSize.localStreamWindowSize.map(Int32.init) ?? 0) + self.inboundEventBuffer.pendingUserEvent(NIOHTTP2WindowUpdatedEvent(streamID: streamSize.streamID, inboundWindowSize: streamSize.remoteStreamWindowSize, outboundWindowSize: streamSize.localStreamWindowSize)) + } + case .streamCreatedAndClosed(let cAndCData): + self.outboundBuffer.streamCreated(cAndCData.streamID, initialWindowSize: 0) + let droppedPromises = self.outboundBuffer.streamClosed(cAndCData.streamID) + self.failDroppedPromises(droppedPromises, streamID: cAndCData.streamID, errorCode: .cancel) + case .remoteSettingsChanged(let settingsChange): + if settingsChange.streamWindowSizeChange != 0 { + self.outboundBuffer.initialWindowSizeChanged(settingsChange.streamWindowSizeChange) + } + if let newMaxFrameSize = settingsChange.newMaxFrameSize { + self.frameEncoder.maxFrameSize = newMaxFrameSize + self.outboundBuffer.maxFrameSize = Int(newMaxFrameSize) + } + if let newMaxConcurrentStreams = settingsChange.newMaxConcurrentStreams { + self.outboundBuffer.maxOutboundStreams = Int(newMaxConcurrentStreams) + } + case .localSettingsChanged(let settingsChange): + if settingsChange.streamWindowSizeChange != 0 { + self.inboundEventBuffer.pendingUserEvent(NIOHTTP2BulkStreamWindowChangeEvent(delta: settingsChange.streamWindowSizeChange)) + } + if let newMaxFrameSize = settingsChange.newMaxFrameSize { + self.frameDecoder.maxFrameSize = newMaxFrameSize + } + if let newMaxHeaderListSize = settingsChange.newMaxHeaderListSize { + self.frameDecoder.headerDecoder.maxHeaderListSize = Int(newMaxHeaderListSize) + } + } + } + + private func unbufferAndFlushAutomaticFrames(context: ChannelHandlerContext) { + if self.isUnbufferingAndFlushingAutomaticFrames { + // Don't allow infinite recursion through this method. + return + } + + self.isUnbufferingAndFlushingAutomaticFrames = true + + loop: while true { + switch self.outboundBuffer.nextFlushedWritableFrame(channelWritable: self.channelWritable) { + case .noFrame: + break loop + case .error(let promise, let error): + promise?.fail(error) + case .frame(let frame, let promise): + self.processOutboundFrame(context: context, frame: frame, promise: promise) + } + } + + self.isUnbufferingAndFlushingAutomaticFrames = false + self.flushIfNecessary(context: context) + } + + /// Emits a flush if a frame has been written. + private func flushIfNecessary(context: ChannelHandlerContext) { + if self.wroteFrame { + self.wroteFrame = false + context.flush() + } + } + + /// Fails any promises in the given collection with a 'StreamClosed' error. + private func failDroppedPromises(_ promises: CompoundOutboundBuffer.DroppedPromisesCollection, + streamID: HTTP2StreamID, + errorCode: HTTP2ErrorCode, + file: String = #file, line: UInt = #line) { + // 'NIOHTTP2Errors.streamClosed' always allocates, if there are no promises then there's no + // need to create the error. + guard promises.contains(where: { $0 != nil }) else { + return + } + + let error = NIOHTTP2Errors.streamClosed(streamID: streamID, errorCode: errorCode, file: file, line: line) + for promise in promises { + promise?.fail(error) + } + } +} + + +private extension HTTP2ConnectionStateMachine.ConnectionRole { + init(_ role: NIOHTTP2Handler.ParserMode) { + switch role { + case .client: + self = .client + case .server: + self = .server + } + } +} + + +extension HTTP2ConnectionStateMachine.ValidationState { + init(_ state: NIOHTTP2Handler.ValidationState) { + switch state { + case .enabled: + self = .enabled + case .disabled: + self = .disabled + } + } +} + + +extension NIOHTTP2Handler: CustomStringConvertible { + public var description: String { + return "NIOHTTP2Handler(mode: \(String(describing: self.mode)))" + } +} + + +extension NIOHTTP2Handler: CustomDebugStringConvertible { + public var debugDescription: String { + return """ +NIOHTTP2Handler( + stateMachine: \(String(describing: self.stateMachine)), + frameDecoder: \(String(describing: self.frameDecoder)), + frameEncoder: \(String(describing: self.frameEncoder)), + writeBuffer: \(String(describing: self.writeBuffer)), + inboundEventBuffer: \(String(describing: self.inboundEventBuffer)), + outboundBuffer: \(String(describing: self.outboundBuffer)), + wroteFrame: \(String(describing: self.wroteFrame)), + denialOfServiceValidator: \(String(describing: self.denialOfServiceValidator)), + mode: \(String(describing: self.mode)), + initialSettings: \(String(describing: self.initialSettings)), + channelClosed: \(String(describing: self.channelClosed)), + channelWritable: \(String(describing: self.channelWritable)) +) +""" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ConnectionStateChange.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ConnectionStateChange.swift new file mode 100644 index 00000000..870fd3b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ConnectionStateChange.swift @@ -0,0 +1,213 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An `NIOHTTP2ConnectionStateChange` provides information about the state change +/// that occurred as a result of a single frame being sent or received. +/// +/// This enumeration allows users to avoid needing to replicate the complete HTTP/2 +/// state machine. Instead, users can use this enumeration to determine the new state +/// of the connection and affected streams. +internal enum NIOHTTP2ConnectionStateChange: Hashable { + /// A stream has been created. + case streamCreated(StreamCreated) + + /// A stream has been closed. + case streamClosed(StreamClosed) + + /// A stream was created and then immediately closed. This can happen when a stream reserved + /// via PUSH_PROMISE has a HEADERS frame with END_STREAM sent on it by the server. + case streamCreatedAndClosed(StreamCreatedAndClosed) + + /// A frame was sent or received that changes some flow control windows. + case flowControlChange(FlowControlChange) + + /// Multiple streams have been closed. This happens as a result of a GOAWAY frame + /// being sent or received. + case bulkStreamClosure(BulkStreamClosure) + + /// The remote peer's settings have been changed. + case remoteSettingsChanged(RemoteSettingsChanged) + + /// The local peer's settings have been changed. + case localSettingsChanged(LocalSettingsChanged) + + /// A stream has been created. + internal struct StreamCreated: Hashable { + internal var streamID: HTTP2StreamID + + /// The initial local stream window size. This may be nil if there is no local stream window. + /// This occurs if the stream has been pushed by the remote peer, in which case we will never be able + /// to send on it. + internal var localStreamWindowSize: Int? + + /// The initial remote stream window size. This may be nil if there is no remote stream window. + /// This occurs if the stream has been pushed by the local peer, in which case tje remote peer will never be able + /// to send on it. + internal var remoteStreamWindowSize: Int? + + internal init(streamID: HTTP2StreamID, localStreamWindowSize: Int?, remoteStreamWindowSize: Int?) { + self.streamID = streamID + self.localStreamWindowSize = localStreamWindowSize + self.remoteStreamWindowSize = remoteStreamWindowSize + } + } + + /// A stream has been closed. + internal struct StreamClosed: Hashable { + internal var streamID: HTTP2StreamID + + internal var localConnectionWindowSize: Int + + internal var remoteConnectionWindowSize: Int + + internal var reason: HTTP2ErrorCode? + + internal init(streamID: HTTP2StreamID, localConnectionWindowSize: Int, remoteConnectionWindowSize: Int, reason: HTTP2ErrorCode?) { + self.streamID = streamID + self.localConnectionWindowSize = localConnectionWindowSize + self.remoteConnectionWindowSize = remoteConnectionWindowSize + self.reason = reason + } + } + + /// A stream has been created and immediately closed. In this case, the only relevant bit of information + /// is the stream ID: flow control windows are not relevant as this frame is not flow controlled and does + /// not change window sizes. + internal struct StreamCreatedAndClosed: Hashable { + internal var streamID: HTTP2StreamID + + internal init(streamID: HTTP2StreamID) { + self.streamID = streamID + } + } + + /// A flow control window has changed. + /// + /// A change to a flow control window may affect the connection window and optionally + /// may also affect a stream window. This occurs due to the sending or receiving of + /// a flow controlled frame or a window update frame. Flow controlled frames change + /// both the connection and stream window sizes: window update frames change + /// only one. To avoid ambiguity, we report the current window size of the connection + /// on all such events, and the relevant stream if there is one (which there usually is). + internal struct FlowControlChange: Hashable { + internal var localConnectionWindowSize: Int + + internal var remoteConnectionWindowSize: Int + + internal var localStreamWindowSize: StreamWindowSizeChange? + + /// The information about the stream window size. Either the local or remote + /// stream window information may be nil, if there is no flow control window + /// for that direction (e.g. if the stream is half-closed). + internal struct StreamWindowSizeChange: Hashable { + internal var streamID: HTTP2StreamID + + internal var localStreamWindowSize: Int? + + internal var remoteStreamWindowSize: Int? + + internal init(streamID: HTTP2StreamID, localStreamWindowSize: Int?, remoteStreamWindowSize: Int?) { + self.streamID = streamID + self.localStreamWindowSize = localStreamWindowSize + self.remoteStreamWindowSize = remoteStreamWindowSize + } + } + + internal init(localConnectionWindowSize: Int, remoteConnectionWindowSize: Int, localStreamWindowSize: StreamWindowSizeChange?) { + self.localConnectionWindowSize = localConnectionWindowSize + self.remoteConnectionWindowSize = remoteConnectionWindowSize + self.localStreamWindowSize = localStreamWindowSize + } + } + + /// A large number of streams have been closed at once. + internal struct BulkStreamClosure: Hashable { + internal var closedStreams: [HTTP2StreamID] + + internal init(closedStreams: [HTTP2StreamID]) { + self.closedStreams = closedStreams + } + } + + /// The remote peer's settings have changed in a way that is not trivial to decode. + /// + /// This object keeps track of the change on all stream window sizes via + /// SETTINGS frame. + internal struct RemoteSettingsChanged: Hashable { + internal var streamWindowSizeChange: Int = 0 + + internal var newMaxFrameSize: UInt32? + + internal var newMaxConcurrentStreams: UInt32? + } + + /// The local peer's settings have changed in a way that is not trivial to decode. + /// + /// This object keeps track of the change on all stream window sizes via + /// SETTINGS frame. + internal struct LocalSettingsChanged: Hashable { + internal var streamWindowSizeChange: Int = 0 + + internal var newMaxFrameSize: UInt32? + + internal var newMaxHeaderListSize: UInt32? + } +} + + +/// A representation of a state change at the level of a single stream. +/// +/// While the NIOHTTP2ConnectionStateChange is an object that affects an entire connection, +/// it is more accurately the composition of an effect on a single stream and a wider effect on a +/// connection. This object encapsulates the effect on a single stream, and can be used along with +/// other information to bootstrap a NIOHTTP2ConnectionStateChange. +/// +/// Where possible, this object uses the structures from NIOHTTP2ConnectionStateChange. Where not possible +/// it defines its own. +internal enum StreamStateChange: Hashable { + case streamCreated(NIOHTTP2ConnectionStateChange.StreamCreated) + + case streamClosed(StreamClosed) + + case windowSizeChange(NIOHTTP2ConnectionStateChange.FlowControlChange.StreamWindowSizeChange) + + case streamCreatedAndClosed(NIOHTTP2ConnectionStateChange.StreamCreatedAndClosed) + + struct StreamClosed: Hashable { + var streamID: HTTP2StreamID + + var reason: HTTP2ErrorCode? + } +} + + +internal extension NIOHTTP2ConnectionStateChange { + init(_ streamChange: StreamStateChange, inboundFlowControlWindow: HTTP2FlowControlWindow, outboundFlowControlWindow: HTTP2FlowControlWindow) { + switch streamChange { + case .streamClosed(let streamClosedState): + self = .streamClosed(.init(streamID: streamClosedState.streamID, + localConnectionWindowSize: Int(outboundFlowControlWindow), + remoteConnectionWindowSize: Int(inboundFlowControlWindow), + reason: streamClosedState.reason)) + case .streamCreated(let streamCreated): + self = .streamCreated(streamCreated) + case .streamCreatedAndClosed(let streamCreatedAndClosed): + self = .streamCreatedAndClosed(streamCreatedAndClosed) + case .windowSizeChange(let streamSizeChange): + self = .flowControlChange(.init(localConnectionWindowSize: Int(outboundFlowControlWindow), + remoteConnectionWindowSize: Int(inboundFlowControlWindow), + localStreamWindowSize: streamSizeChange)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Error.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Error.swift new file mode 100644 index 00000000..8aaee05b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Error.swift @@ -0,0 +1,1479 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK + +public protocol NIOHTTP2Error: Equatable, Error { } + +/// Errors that NIO raises when handling HTTP/2 connections. +public enum NIOHTTP2Errors { + public static func excessiveOutboundFrameBuffering(file: String = #file, line: UInt = #line) -> ExcessiveOutboundFrameBuffering { + return ExcessiveOutboundFrameBuffering(file: file, line: line) + } + + public static func invalidALPNToken(file: String = #file, line: UInt = #line) -> InvalidALPNToken { + return InvalidALPNToken(file: file, line: line) + } + + public static func noSuchStream(streamID: HTTP2StreamID, file: String = #file, line: UInt = #line) -> NoSuchStream { + return NoSuchStream(streamID: streamID, file: file, line: line) + } + + public static func streamClosed(streamID: HTTP2StreamID, errorCode: HTTP2ErrorCode, file: String = #file, line: UInt = #line) -> StreamClosed { + return StreamClosed(streamID: streamID, errorCode: errorCode, file: file, line: line) + } + + public static func badClientMagic(file: String = #file, line: UInt = #line) -> BadClientMagic { + return BadClientMagic(file: file, line: line) + } + + public static func badStreamStateTransition(from state: NIOHTTP2StreamState? = nil, file: String = #file, line: UInt = #line) -> BadStreamStateTransition { + return BadStreamStateTransition(from: state, file: file, line: line) + } + + public static func invalidFlowControlWindowSize(delta: Int, currentWindowSize: Int, file: String = #file, line: UInt = #line) -> InvalidFlowControlWindowSize { + return InvalidFlowControlWindowSize(delta: delta, currentWindowSize: currentWindowSize, file: file, line: line) + } + + public static func flowControlViolation(file: String = #file, line: UInt = #line) -> FlowControlViolation { + return FlowControlViolation(file: file, line: line) + } + + public static func invalidSetting(setting: HTTP2Setting, file: String = #file, line: UInt = #line) -> InvalidSetting { + return InvalidSetting(setting: setting, file: file, line: line) + } + + public static func ioOnClosedConnection(file: String = #file, line: UInt = #line) -> IOOnClosedConnection { + return IOOnClosedConnection(file: file, line: line) + } + + public static func receivedBadSettings(file: String = #file, line: UInt = #line) -> ReceivedBadSettings { + return ReceivedBadSettings(file: file, line: line) + } + + public static func maxStreamsViolation(file: String = #file, line: UInt = #line) -> MaxStreamsViolation { + return MaxStreamsViolation(file: file, line: line) + } + + public static func streamIDTooSmall(file: String = #file, line: UInt = #line) -> StreamIDTooSmall { + return StreamIDTooSmall(file: file, line: line) + } + + public static func missingPreface(file: String = #file, line: UInt = #line) -> MissingPreface { + return MissingPreface(file: file, line: line) + } + + public static func createdStreamAfterGoaway(file: String = #file, line: UInt = #line) -> CreatedStreamAfterGoaway { + return CreatedStreamAfterGoaway(file: file, line: line) + } + + public static func invalidStreamIDForPeer(file: String = #file, line: UInt = #line) -> InvalidStreamIDForPeer { + return InvalidStreamIDForPeer(file: file, line: line) + } + + public static func raisedGoawayLastStreamID(file: String = #file, line: UInt = #line) -> RaisedGoawayLastStreamID { + return RaisedGoawayLastStreamID(file: file, line: line) + } + + public static func invalidWindowIncrementSize(file: String = #file, line: UInt = #line) -> InvalidWindowIncrementSize { + return InvalidWindowIncrementSize(file: file, line: line) + } + + public static func pushInViolationOfSetting(file: String = #file, line: UInt = #line) -> PushInViolationOfSetting { + return PushInViolationOfSetting(file: file, line: line) + } + + public static func unsupported(info: String, file: String = #file, line: UInt = #line) -> Unsupported { + return Unsupported(info: info, file: file, line: line) + } + + public static func unableToSerializeFrame(file: String = #file, line: UInt = #line) -> UnableToSerializeFrame { + return UnableToSerializeFrame(file: file, line: line) + } + + public static func unableToParseFrame(file: String = #file, line: UInt = #line) -> UnableToParseFrame { + return UnableToParseFrame(file: file, line: line) + } + + public static func missingPseudoHeader(_ name: String, file: String = #file, line: UInt = #line) -> MissingPseudoHeader { + return MissingPseudoHeader(name, file: file, line: line) + } + + public static func duplicatePseudoHeader(_ name: String, file: String = #file, line: UInt = #line) -> DuplicatePseudoHeader { + return DuplicatePseudoHeader(name, file: file, line: line) + } + + public static func pseudoHeaderAfterRegularHeader(_ name: String, file: String = #file, line: UInt = #line) -> PseudoHeaderAfterRegularHeader { + return PseudoHeaderAfterRegularHeader(name, file: file, line: line) + } + + public static func unknownPseudoHeader(_ name: String, file: String = #file, line: UInt = #line) -> UnknownPseudoHeader { + return UnknownPseudoHeader(name, file: file, line: line) + } + + public static func invalidPseudoHeaders(_ block: HPACKHeaders, file: String = #file, line: UInt = #line) -> InvalidPseudoHeaders { + return InvalidPseudoHeaders(block, file: file, line: line) + } + + public static func missingHostHeader(file: String = #file, line: UInt = #line) -> MissingHostHeader { + return MissingHostHeader(file: file, line: line) + } + + public static func duplicateHostHeader(file: String = #file, line: UInt = #line) -> DuplicateHostHeader { + return DuplicateHostHeader(file: file, line: line) + } + + public static func emptyPathHeader(file: String = #file, line: UInt = #line) -> EmptyPathHeader { + return EmptyPathHeader(file: file, line: line) + } + + public static func invalidStatusValue(_ value: String, file: String = #file, line: UInt = #line) -> InvalidStatusValue { + return InvalidStatusValue(value, file: file, line: line) + } + + public static func priorityCycle(streamID: HTTP2StreamID, file: String = #file, line: UInt = #line) -> PriorityCycle { + return PriorityCycle(streamID: streamID, file: file, line: line) + } + + public static func trailersWithoutEndStream(streamID: HTTP2StreamID, file: String = #file, line: UInt = #line) -> TrailersWithoutEndStream { + return TrailersWithoutEndStream(streamID: streamID, file: file, line: line) + } + + public static func invalidHTTP2HeaderFieldName(_ fieldName: String, file: String = #file, line: UInt = #line) -> InvalidHTTP2HeaderFieldName { + return InvalidHTTP2HeaderFieldName(fieldName, file: file, line: line) + } + + public static func forbiddenHeaderField(name: String, value: String, file: String = #file, line: UInt = #line) -> ForbiddenHeaderField { + return ForbiddenHeaderField(name: name, value: value, file: file, line: line) + } + + public static func contentLengthViolated(file: String = #file, line: UInt = #line) -> ContentLengthViolated { + return ContentLengthViolated(file: file, line: line) + } + + public static func excessiveEmptyDataFrames(file: String = #file, line: UInt = #line) -> ExcessiveEmptyDataFrames { + return ExcessiveEmptyDataFrames(file: file, line: line) + } + + public static func excessivelyLargeHeaderBlock(file: String = #file, line: UInt = #line) -> ExcessivelyLargeHeaderBlock { + return ExcessivelyLargeHeaderBlock(file: file, line: line) + } + + public static func noStreamIDAvailable(file: String = #file, line: UInt = #line) -> NoStreamIDAvailable { + return NoStreamIDAvailable(file: file, line: line) + } + + public static func streamError(streamID: HTTP2StreamID, baseError: Error) -> StreamError { + return StreamError(streamID: streamID, baseError: baseError) + } + + /// The outbound frame buffers have become filled, and it is not possible to buffer + /// further outbound frames. This occurs when the remote peer is generating work + /// faster than they are consuming the result. Additional buffering runs the risk of + /// memory exhaustion. + public struct ExcessiveOutboundFrameBuffering: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "excessiveOutboundFrameBuffering") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: ExcessiveOutboundFrameBuffering, rhs: ExcessiveOutboundFrameBuffering) -> Bool { + return true + } + } + + /// NIO's upgrade handler encountered a successful upgrade to a protocol that it + /// does not recognise. + public struct InvalidALPNToken: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "invalidALPNToken") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: InvalidALPNToken, rhs: InvalidALPNToken) -> Bool { + return true + } + } + + /// An attempt was made to issue a write on a stream that does not exist. + public struct NoSuchStream: NIOHTTP2Error { + /// The stream ID that was used that does not exist. + public var streamID: HTTP2StreamID + + /// The location where the error was thrown. + public let location: String + + @available(*, deprecated, renamed: "noSuchStream") + public init(streamID: HTTP2StreamID) { + self.init(streamID: streamID, file: #file, line: #line) + } + + fileprivate init(streamID: HTTP2StreamID, file: String, line: UInt) { + self.streamID = streamID + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: NoSuchStream, rhs: NoSuchStream) -> Bool { + return lhs.streamID == rhs.streamID + } + } + + /// A stream was closed. + public struct StreamClosed: NIOHTTP2Error { + /// The stream ID that was closed. + public var streamID: HTTP2StreamID + + /// The error code associated with the closure. + public var errorCode: HTTP2ErrorCode + + /// The file and line where the error was created. + public let location: String + + @available(*, deprecated, renamed: "streamClosed") + public init(streamID: HTTP2StreamID, errorCode: HTTP2ErrorCode) { + self.init(streamID: streamID, errorCode: errorCode, file: #file, line: #line) + } + + fileprivate init(streamID: HTTP2StreamID, errorCode: HTTP2ErrorCode, file: String, line: UInt) { + self.streamID = streamID + self.errorCode = errorCode + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: StreamClosed, rhs: StreamClosed) -> Bool { + return lhs.streamID == rhs.streamID && lhs.errorCode == rhs.errorCode + } + } + + public struct BadClientMagic: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "badClientMagic") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: BadClientMagic, rhs: BadClientMagic) -> Bool { + return true + } + } + + /// A stream state transition was attempted that was not valid. + public struct BadStreamStateTransition: NIOHTTP2Error, CustomStringConvertible { + public let fromState: NIOHTTP2StreamState? + + /// The location where the error was thrown. + public let location: String + + public var description: String { + let stateName = self.fromState != nil ? "\(self.fromState!)" : "unknown state" + return "BadStreamStateTransition(fromState: \(stateName), location: \(self.location))" + } + + fileprivate init(from state: NIOHTTP2StreamState?, file: String, line: UInt) { + self.fromState = state + self.location = _location(file: file, line: line) + } + + @available(*, deprecated, renamed: "badStreamStateTransition") + public init() { + self.init(from: nil, file: #file, line: #line) + } + + public static func ==(lhs: BadStreamStateTransition, rhs: BadStreamStateTransition) -> Bool { + return lhs.fromState == rhs.fromState + } + } + + /// An attempt was made to change the flow control window size, either via + /// SETTINGS or WINDOW_UPDATE, but this change would move the flow control + /// window size out of bounds. + public struct InvalidFlowControlWindowSize: NIOHTTP2Error, CustomStringConvertible { + private var storage: Storage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + private final class Storage: Equatable { + var delta: Int + var currentWindowSize: Int + var file: String + var line: UInt + + var location: String { + return _location(file: self.file, line: self.line) + } + + init(delta: Int, currentWindowSize: Int, file: String, line: UInt) { + self.delta = delta + self.currentWindowSize = currentWindowSize + self.file = file + self.line = line + } + + func copy() -> Storage { + return Storage(delta: self.delta, currentWindowSize: self.currentWindowSize, file: self.file, line: self.line) + } + + static func ==(lhs: Storage, rhs: Storage) -> Bool { + return lhs.delta == rhs.delta && lhs.currentWindowSize == rhs.currentWindowSize + } + } + + /// The delta being applied to the flow control window. + public var delta: Int { + get { + return self.storage.delta + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.delta = newValue + } + } + + /// The size of the flow control window before the delta was applied. + public var currentWindowSize: Int { + get { + return self.storage.currentWindowSize + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.currentWindowSize = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "InvalidFlowControlWindowSize(delta: \(self.delta), currentWindowSize: \(self.currentWindowSize), location: \(self.location))" + } + + @available(*, deprecated, renamed: "invalidFlowControlWindowSize") + public init(delta: Int, currentWindowSize: Int) { + self.init(delta: delta, currentWindowSize: currentWindowSize, file: #file, line: #line) + } + + fileprivate init(delta: Int, currentWindowSize: Int, file: String, line: UInt) { + self.storage = Storage(delta: delta, currentWindowSize: currentWindowSize, file: file, line: line) + } + } + + /// A frame was sent or received that violates HTTP/2 flow control rules. + public struct FlowControlViolation: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "flowControlViolation") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: FlowControlViolation, rhs: FlowControlViolation) -> Bool { + return true + } + } + + /// A SETTINGS frame was sent or received with an invalid setting. + public struct InvalidSetting: NIOHTTP2Error { + /// The invalid setting. + public var setting: HTTP2Setting + + /// The location where the error was thrown. + public let location: String + + @available(*, deprecated, renamed: "invalidSetting") + public init(setting: HTTP2Setting) { + self.init(setting: setting, file: #file, line: #line) + } + + fileprivate init(setting: HTTP2Setting, file: String, line: UInt) { + self.setting = setting + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: InvalidSetting, rhs: InvalidSetting) -> Bool { + return lhs.setting == rhs.setting + } + } + + /// An attempt to perform I/O was made on a connection that is already closed. + public struct IOOnClosedConnection: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "ioOnClosedConnection") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: IOOnClosedConnection, rhs: IOOnClosedConnection) -> Bool { + return true + } + } + + /// A SETTINGS frame was received that is invalid. + public struct ReceivedBadSettings: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "receivedBadSettings") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: ReceivedBadSettings, rhs: ReceivedBadSettings) -> Bool { + return true + } + } + + /// A violation of SETTINGS_MAX_CONCURRENT_STREAMS occurred. + public struct MaxStreamsViolation: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "maxStreamsViolation") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: MaxStreamsViolation, rhs: MaxStreamsViolation) -> Bool { + return true + } + } + + /// An attempt was made to use a stream ID that is too small. + public struct StreamIDTooSmall: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "streamIDTooSmall") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: StreamIDTooSmall, rhs: StreamIDTooSmall) -> Bool { + return true + } + } + + /// An attempt was made to send a frame without having previously sent a connection preface! + public struct MissingPreface: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "missingPreface") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: MissingPreface, rhs: MissingPreface) -> Bool { + return true + } + } + + /// An attempt was made to create a stream after a GOAWAY frame has forbidden further + /// stream creation. + public struct CreatedStreamAfterGoaway: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "createdStreamAfterGoaway") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: CreatedStreamAfterGoaway, rhs: CreatedStreamAfterGoaway) -> Bool { + return true + } + } + + /// A peer has attempted to create a stream with a stream ID it is not permitted to use. + public struct InvalidStreamIDForPeer: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "invalidStreamIDForPeer") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: InvalidStreamIDForPeer, rhs: InvalidStreamIDForPeer) -> Bool { + return true + } + } + + /// An attempt was made to send a new GOAWAY frame whose lastStreamID is higher than the previous value. + public struct RaisedGoawayLastStreamID: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "raisedGoawayLastStreamID") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: RaisedGoawayLastStreamID, rhs: RaisedGoawayLastStreamID) -> Bool { + return true + } + } + + /// The size of the window increment is invalid. + public struct InvalidWindowIncrementSize: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "invalidWindowIncrementSize") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: InvalidWindowIncrementSize, rhs: InvalidWindowIncrementSize) -> Bool { + return true + } + } + + /// An attempt was made to push a stream, even though the settings forbid it. + public struct PushInViolationOfSetting: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "pushInViolationOfSetting") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: PushInViolationOfSetting, rhs: PushInViolationOfSetting) -> Bool { + return true + } + } + + /// An attempt was made to use a currently unsupported feature. + public struct Unsupported: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var info: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "Unsupported(info: \(self.info), location: \(self.location))" + } + + @available(*, deprecated, renamed: "unsupported") + public init(info: String) { + self.init(info: info, file: #file, line: #line) + } + + fileprivate init(info: String, file: String, line: UInt) { + self.storage = .init(info, file: file, line: line) + } + } + + public struct UnableToSerializeFrame: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "unableToSerializeFrame") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: UnableToSerializeFrame, rhs: UnableToSerializeFrame) -> Bool { + return true + } + } + + public struct UnableToParseFrame: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "unableToParseFrame") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: UnableToParseFrame, rhs: UnableToParseFrame) -> Bool { + return true + } + } + + /// A pseudo-header field is missing. + public struct MissingPseudoHeader: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var name: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "MissingPseudoHeader(name: \(self.name), location: \(self.location))" + } + + @available(*, deprecated, renamed: "missingPseudoHeader") + public init(_ name: String) { + self.init(name, file: #file, line: #line) + } + + fileprivate init(_ name: String, file: String, line: UInt) { + self.storage = .init(name, file: file, line: line) + } + } + + /// A pseudo-header field has been duplicated. + public struct DuplicatePseudoHeader: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var name: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "DuplicatePseudoHeader(name: \(self.name), location: \(self.location))" + } + + @available(*, deprecated, renamed: "duplicatePseudoHeader") + public init(_ name: String) { + self.init(name, file: #file, line: #line) + } + + fileprivate init(_ name: String, file: String, line: UInt) { + self.storage = .init(name, file: file, line: line) + } + } + + /// A header block contained a pseudo-header after a regular header. + public struct PseudoHeaderAfterRegularHeader: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var name: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "PseudoHeaderAfterRegularHeader(name: \(self.name), location: \(self.location))" + } + + @available(*, deprecated, renamed: "pseudoHeaderAfterRegularHeader") + public init(_ name: String) { + self.init(name, file: #file, line: #line) + } + + fileprivate init(_ name: String, file: String, line: UInt) { + self.storage = .init(name, file: file, line: line) + } + } + + /// An unknown pseudo-header was received. + public struct UnknownPseudoHeader: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var name: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "UnknownPseudoHeader(name: \(self.name), location: \(self.location))" + } + + @available(*, deprecated, renamed: "unknownPseudoHeader") + public init(_ name: String) { + self.init(name, file: #file, line: #line) + } + + fileprivate init(_ name: String, file: String, line: UInt) { + self.storage = .init(name, file: file, line: line) + } + } + + /// A header block was received with an invalid set of pseudo-headers for the block type. + public struct InvalidPseudoHeaders: NIOHTTP2Error { + public var headerBlock: HPACKHeaders + + /// The location where the error was thrown. + public let location: String + + @available(*, deprecated, renamed: "invalidPseudoHeaders") + public init(_ block: HPACKHeaders) { + self.init(block, file: #file, line: #line) + } + + fileprivate init(_ block: HPACKHeaders, file: String, line: UInt) { + self.headerBlock = block + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: InvalidPseudoHeaders, rhs: InvalidPseudoHeaders) -> Bool { + return lhs.headerBlock == rhs.headerBlock + } + } + + /// An outbound request was about to be sent, but does not contain a Host header. + public struct MissingHostHeader: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "missingHostHeader") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: MissingHostHeader, rhs: MissingHostHeader) -> Bool { + return true + } + } + + /// An outbound request was about to be sent, but it contains a duplicated Host header. + public struct DuplicateHostHeader: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "duplicateHostHeader") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: DuplicateHostHeader, rhs: DuplicateHostHeader) -> Bool { + return true + } + } + + /// A HTTP/2 header block was received with an empty :path header. + public struct EmptyPathHeader: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "emptyPathHeader") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: EmptyPathHeader, rhs: EmptyPathHeader) -> Bool { + return true + } + } + + /// A :status header was received with an invalid value. + public struct InvalidStatusValue: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var value: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "InvalidStatusValue(value: \(self.value), location: \(self.location))" + } + + @available(*, deprecated, renamed: "invalidStatusValue") + public init(_ value: String) { + self.init(value, file: #file, line: #line) + } + + fileprivate init(_ value: String, file: String, line: UInt) { + self.storage = .init(value, file: file, line: line) + } + } + + /// A priority update was received that would create a PRIORITY cycle. + public struct PriorityCycle: NIOHTTP2Error { + /// The affected stream ID. + public var streamID: HTTP2StreamID + + /// The location where the error was thrown. + public let location: String + + @available(*, deprecated, renamed: "priorityCycle") + public init(streamID: HTTP2StreamID) { + self.init(streamID: streamID, file: #file, line: #line) + } + + fileprivate init(streamID: HTTP2StreamID, file: String, line: UInt) { + self.streamID = streamID + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: PriorityCycle, rhs: PriorityCycle) -> Bool { + return lhs.streamID == rhs.streamID + } + } + + /// An attempt was made to send trailers without setting END_STREAM on them. + public struct TrailersWithoutEndStream: NIOHTTP2Error { + /// The affected stream ID. + public var streamID: HTTP2StreamID + + /// The location where the error was thrown. + public let location: String + + @available(*, deprecated, renamed: "trailersWithoutEndStream") + public init(streamID: HTTP2StreamID) { + self.init(streamID: streamID, file: #file, line: #line) + } + + fileprivate init(streamID: HTTP2StreamID, file: String, line: UInt) { + self.streamID = streamID + self.location = _location(file: file, line: line) + } + + public static func ==(lhs: TrailersWithoutEndStream, rhs: TrailersWithoutEndStream) -> Bool { + return lhs.streamID == rhs.streamID + } + } + + /// An attempt was made to send a header field with a field name that is not valid in HTTP/2. + public struct InvalidHTTP2HeaderFieldName: NIOHTTP2Error, CustomStringConvertible { + private var storage: StringAndLocationStorage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var fieldName: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "InvalidHTTP2HeaderFieldName(fieldName: \(self.fieldName), location: \(self.location))" + } + + @available(*, deprecated, renamed: "invalidHTTP2HeaderFieldName") + public init(_ name: String) { + self.init(name, file: #file, line: #line) + } + + fileprivate init(_ name: String, file: String, line: UInt) { + self.storage = .init(name, file: file, line: line) + } + } + + /// Connection-specific header fields are forbidden in HTTP/2: this error is raised when one is + /// sent or received. + public struct ForbiddenHeaderField: NIOHTTP2Error, CustomStringConvertible { + private var storage: Storage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + private final class Storage: Equatable { + var name: String + var value: String + var file: String + var line: UInt + + var location: String { + return _location(file: self.file, line: self.line) + } + + init(name: String, value: String, file: String, line: UInt) { + self.name = name + self.value = value + self.file = file + self.line = line + } + + func copy() -> Storage { + return Storage(name: self.name, value: self.value, file: self.file, line: self.line) + } + + static func ==(lhs: Storage, rhs: Storage) -> Bool { + return lhs.name == rhs.name && lhs.value == rhs.value + } + } + + public var name: String { + get { + return self.storage.name + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.name = newValue + } + } + + public var value: String { + get { + return self.storage.value + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.value = newValue + } + } + + /// The file and line where the error was created. + public var location: String { + get { + return self.storage.location + } + } + + public var description: String { + return "ForbiddenHeaderField(name: \(self.name), value: \(self.value), location: \(self.location))" + } + + @available(*, deprecated, renamed: "forbiddenHeaderField") + public init(name: String, value: String) { + self.init(name: name, value: value, file: #file, line: #line) + } + + fileprivate init(name: String, value: String, file: String, line: UInt) { + self.storage = Storage(name: name, value: value, file: file, line: line) + } + } + + /// A request or response has violated the expected content length, either exceeding or falling beneath it. + public struct ContentLengthViolated: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "contentLengthViolated") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: ContentLengthViolated, rhs: ContentLengthViolated) -> Bool { + return true + } + } + + /// The remote peer has sent an excessive number of empty DATA frames, which looks like a denial of service + /// attempt, so the connection has been closed. + public struct ExcessiveEmptyDataFrames: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "excessiveEmptyDataFrames") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: ExcessiveEmptyDataFrames, rhs: ExcessiveEmptyDataFrames) -> Bool { + return true + } + } + + /// The remote peer has sent a header block so large that NIO refuses to buffer any more data than that. + public struct ExcessivelyLargeHeaderBlock: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "excessivelyLargeHeaderBlock") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: ExcessivelyLargeHeaderBlock, rhs: ExcessivelyLargeHeaderBlock) -> Bool { + return true + } + } + + /// The channel does not yet have a stream ID, as it has not reached the network yet. + public struct NoStreamIDAvailable: NIOHTTP2Error { + private let file: String + private let line: UInt + + /// The location where the error was thrown. + public var location: String { + return _location(file: self.file, line: self.line) + } + + @available(*, deprecated, renamed: "noStreamIDAvailable") + public init() { + self.init(file: #file, line: #line) + } + + fileprivate init(file: String, line: UInt) { + self.file = file + self.line = line + } + + public static func ==(lhs: NoStreamIDAvailable, rhs: NoStreamIDAvailable) -> Bool { + return true + } + } + + /// A StreamError was hit during outbound frame processing. + /// + /// Stream errors are wrappers around another error of some other kind that occurred on a specific stream. + /// As they are a wrapper error, they carry a "real" error in the `baseError`. Additionally, they cannot + /// meaningfully be `Equatable`, so they aren't. There's also no additional location information: that's + /// provided by the base error. + public struct StreamError: Error { + private final class Storage { + var streamID: HTTP2StreamID + var baseError: Error + + init(streamID: HTTP2StreamID, baseError: Error) { + self.baseError = baseError + self.streamID = streamID + } + + func copy() -> Storage { + return Storage( + streamID: self.streamID, + baseError: self.baseError + ) + } + } + + private var storage: Storage + + private mutating func copyStorageIfNotUniquelyReferenced() { + if !isKnownUniquelyReferenced(&self.storage) { + self.storage = self.storage.copy() + } + } + + public var baseError: Error { + get { + return self.storage.baseError + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.baseError = newValue + } + } + + public var streamID: HTTP2StreamID { + get { + return self.storage.streamID + } + set { + self.copyStorageIfNotUniquelyReferenced() + self.storage.streamID = newValue + } + } + + public var description: String { + return "StreamError(streamID: \(self.streamID), baseError: \(self.baseError))" + } + + fileprivate init(streamID: HTTP2StreamID, baseError: Error) { + self.storage = .init(streamID: streamID, baseError: baseError) + } + } +} + + +/// This enum covers errors that are thrown internally for messaging reasons. These should +/// not leak. +internal enum InternalError: Error { + case attemptedToCreateStream + + case codecError(code: HTTP2ErrorCode) + + // Used to record that an impossible situation occured. Crashes in debug mode, errors in + // release mode. + static func impossibleSituation(file: StaticString = #file, line: UInt = #line) -> InternalError { + assertionFailure(file: file, line: line) + return .codecError(code: .internalError) + } +} + +extension InternalError: Hashable { } + +private func _location(file: String, line: UInt) -> String { + return "\(file):\(line)" +} + +private final class StringAndLocationStorage: Equatable { + var value: String + var file: String + var line: UInt + + var location: String { + return _location(file: self.file, line: self.line) + } + + init(_ value: String, file: String, line: UInt) { + self.value = value + self.file = file + self.line = line + } + + func copy() -> StringAndLocationStorage { + return StringAndLocationStorage(self.value, file: self.file, line: self.line) + } + + static func ==(lhs: StringAndLocationStorage, rhs: StringAndLocationStorage) -> Bool { + // Only compare the value. The 'file' is not relevant here. + return lhs.value == rhs.value + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ErrorCode.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ErrorCode.swift new file mode 100644 index 00000000..e38ddf5f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ErrorCode.swift @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// An HTTP/2 error code. +public struct HTTP2ErrorCode: NIOSendable { + /// The underlying network representation of the error code. + public var networkCode: Int { + get { + return Int(self._networkCode) + } + set { + self._networkCode = UInt32(newValue) + } + } + + /// The underlying network representation of the error code. + fileprivate var _networkCode: UInt32 + + /// Create a HTTP/2 error code from the given network value. + public init(networkCode: Int) { + self._networkCode = UInt32(networkCode) + } + + /// Create a `HTTP2ErrorCode` from the 32-bit integer it corresponds to. + internal init(_ networkInteger: UInt32) { + self._networkCode = networkInteger + } + + /// The associated condition is not a result of an error. For example, + /// a GOAWAY might include this code to indicate graceful shutdown of + /// a connection. + public static let noError = HTTP2ErrorCode(networkCode: 0x0) + + /// The endpoint detected an unspecific protocol error. This error is + /// for use when a more specific error code is not available. + public static let protocolError = HTTP2ErrorCode(networkCode: 0x01) + + /// The endpoint encountered an unexpected internal error. + public static let internalError = HTTP2ErrorCode(networkCode: 0x02) + + /// The endpoint detected that its peer violated the flow-control + /// protocol. + public static let flowControlError = HTTP2ErrorCode(networkCode: 0x03) + + /// The endpoint sent a SETTINGS frame but did not receive a + /// response in a timely manner. + public static let settingsTimeout = HTTP2ErrorCode(networkCode: 0x04) + + /// The endpoint received a frame after a stream was half-closed. + public static let streamClosed = HTTP2ErrorCode(networkCode: 0x05) + + /// The endpoint received a frame with an invalid size. + public static let frameSizeError = HTTP2ErrorCode(networkCode: 0x06) + + /// The endpoint refused the stream prior to performing any + /// application processing. + public static let refusedStream = HTTP2ErrorCode(networkCode: 0x07) + + /// Used by the endpoint to indicate that the stream is no + /// longer needed. + public static let cancel = HTTP2ErrorCode(networkCode: 0x08) + + /// The endpoint is unable to maintain the header compression + /// context for the connection. + public static let compressionError = HTTP2ErrorCode(networkCode: 0x09) + + /// The connection established in response to a CONNECT request + /// was reset or abnormally closed. + public static let connectError = HTTP2ErrorCode(networkCode: 0x0a) + + /// The endpoint detected that its peer is exhibiting a behavior + /// that might be generating excessive load. + public static let enhanceYourCalm = HTTP2ErrorCode(networkCode: 0x0b) + + /// The underlying transport has properties that do not meet + /// minimum security requirements. + public static let inadequateSecurity = HTTP2ErrorCode(networkCode: 0x0c) + + /// The endpoint requires that HTTP/1.1 be used instead of HTTP/2. + public static let http11Required = HTTP2ErrorCode(networkCode: 0x0d) +} + +extension HTTP2ErrorCode: Equatable { } + +extension HTTP2ErrorCode: Hashable { } + +extension HTTP2ErrorCode: CustomDebugStringConvertible { + public var debugDescription: String { + let errorCodeDescription: String + switch self { + case .noError: + errorCodeDescription = "No Error" + case .protocolError: + errorCodeDescription = "ProtocolError" + case .internalError: + errorCodeDescription = "Internal Error" + case .flowControlError: + errorCodeDescription = "Flow Control Error" + case .settingsTimeout: + errorCodeDescription = "Settings Timeout" + case .streamClosed: + errorCodeDescription = "Stream Closed" + case .frameSizeError: + errorCodeDescription = "Frame Size Error" + case .refusedStream: + errorCodeDescription = "Refused Stream" + case .cancel: + errorCodeDescription = "Cancel" + case .compressionError: + errorCodeDescription = "Compression Error" + case .connectError: + errorCodeDescription = "Connect Error" + case .enhanceYourCalm: + errorCodeDescription = "Enhance Your Calm" + case .inadequateSecurity: + errorCodeDescription = "Inadequate Security" + case .http11Required: + errorCodeDescription = "HTTP/1.1 Required" + default: + errorCodeDescription = "Unknown Error" + } + + return "HTTP2ErrorCode<0x\(String(self.networkCode, radix: 16)) \(errorCodeDescription)>" + } +} + +public extension UInt32 { + /// Create a 32-bit integer corresponding to the given `HTTP2ErrorCode`. + init(http2ErrorCode code: HTTP2ErrorCode) { + self = code._networkCode + } +} + +public extension Int { + /// Create an integer corresponding to the given `HTTP2ErrorCode`. + init(http2ErrorCode code: HTTP2ErrorCode) { + self = code.networkCode + } +} + +public extension ByteBuffer { + /// Serializes a `HTTP2ErrorCode` into a `ByteBuffer` in the appropriate endianness + /// for use in HTTP/2. + /// + /// - parameters: + /// - code: The `HTTP2ErrorCode` to serialize. + /// - returns: The number of bytes written. + mutating func write(http2ErrorCode code: HTTP2ErrorCode) -> Int { + return self.writeInteger(UInt32(http2ErrorCode: code)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FlowControlWindow.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FlowControlWindow.swift new file mode 100644 index 00000000..b65b2b30 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FlowControlWindow.swift @@ -0,0 +1,188 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +struct HTTP2FlowControlWindow { + /// The maximum flow control window size allowed by RFC 7540. + static let maxSize: Int32 = Int32.max + + /// The maximum increment to the flow control window size allowed by RFC 7540. + private static let maxIncrement: Int32 = Int32.max + + /// The integer size of this flow control window. + /// + /// From RFC 7540 § 6.9.1: + /// + /// > A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets. + /// + /// This means that we can store this safely in an Int32. This value is hidden, because we want + /// to ensure that we have a nice safe wrapper that can report errors and ensure that the flow + /// control window never exits the allowed range. + /// + /// The reason we use Int32 instead of UInt32 is that the flow control window may also go negative. + /// From RFC 7540 § 6.9.2: + /// + /// > In addition to changing the flow-control window for streams that are not yet active, a + /// > SETTINGS frame can alter the initial flow-control window size for streams with active + /// > flow-control windows (that is, streams in the "open" or "half-closed (remote)" state). + /// > When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of + /// > all stream flow-control windows that it maintains by the difference between the new value + /// > and the old value. + /// > + /// > A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available space in a flow-control + /// > window to become negative. A sender MUST track the negative flow-control window and MUST + /// > NOT send new flow-controlled frames until it receives WINDOW_UPDATE frames that cause the + /// > flow-control window to become positive. + /// + /// The most-negative a flow-control window can go occurs in the following case: + /// + /// - A stream was created with initial window size of 2 ** 31 - 1 (a.k.a. Int32.max) + /// - Int32.max bytes were sent, leaving the window size at zero. + /// - The value of SETTINGS_INITIAL_WINDOW_SIZE was set to 0, leading to a window size delta of + /// -(Int32.max), and setting the window size to -(Int32.max). + /// + /// As -(Int32.max) definitionally still fits into Int32, Int32 is the appropriate type to use here. + fileprivate private(set) var windowSize: Int32 + + init(initialValue: Int) { + precondition(initialValue >= 0, "Flow control windows may not begin negative") + precondition(initialValue <= HTTP2FlowControlWindow.maxSize, + "Flow control windows may not exceed \(HTTP2FlowControlWindow.maxSize) bytes") + + self.windowSize = Int32(initialValue) + } + + init(initialValue: Int32) { + precondition(initialValue >= 0, "Flow control windows may not begin negative") + precondition(initialValue <= HTTP2FlowControlWindow.maxSize, + "Flow control windows may not exceed \(HTTP2FlowControlWindow.maxSize) bytes") + + self.windowSize = initialValue + } + + init(initialValue: UInt32) { + self.init(initialValue: Int32(initialValue)) + } + + /// Increment the flow control window as a result of a WINDOW_UPDATE frame. + /// + /// This method will asserts if `amount` is outside the allowed range, as the allowed range is enforced by + /// the valid values of a WINDOW_UPDATE frame. It is assumed that the frame parser validates the values in + /// WINDOW_UPDATE frames. + /// + /// - parameters: + /// - amount: The size of the increment. + /// - throws: When `amount` is outside of RFC 7540's allowed range, or when it would move this value outside + /// of the allowed range. + mutating func windowUpdate(by amount: UInt32) throws { + assert(amount <= HTTP2FlowControlWindow.maxIncrement) + + guard amount >= 1 else { + throw NIOHTTP2Errors.invalidWindowIncrementSize() + } + + // We now need to bounds check to confirm that our window size will remain in the valid range. We use + // subtraction to avoid integer overflow. Note that if the current window size is negative then all window + // update increments are valid. + guard (self.windowSize < 0) || (HTTP2FlowControlWindow.maxSize - self.windowSize >= amount) else { + throw NIOHTTP2Errors.invalidFlowControlWindowSize(delta: Int(amount), currentWindowSize: Int(self.windowSize)) + } + + self.windowSize += Int32(amount) + } + + /// Change the flow control window as a result of a change to SETTINGS_INITIAL_WINDOW_SIZE. + /// + /// This method will trap if `amount` is outside the allowed range, as the allowed range is implicitly enforced + /// so long as the values of SETTINGS_INITIAL_WINDOW_SIZE are correctly policed. The allowed range here is fairly + /// large, however. + /// + /// This method will throw if this change forces the flow control window size to become larger than the maximum flow + /// control window size. + /// + /// - parameters: + /// - amount: The size of the increment/decrement. + /// - throws: When `amount` would move the flow control window outside the allowed range. + mutating func initialSizeChanged(by amount: Int32) throws { + assert(amount >= -(Int32.max)) + + guard (self.windowSize < 0) || (HTTP2FlowControlWindow.maxSize - self.windowSize >= amount) else { + throw NIOHTTP2Errors.invalidFlowControlWindowSize(delta: Int(amount), currentWindowSize: Int(self.windowSize)) + } + + self.windowSize += amount + } + + /// Consume a portion of the flow control window. + /// + /// - parameters: + /// - flowControlledBytes: The number of flow controlled bytes to consume + mutating func consume(flowControlledBytes size: Int) throws { + assert(size >= 0) + // TODO(cory): This is the max value of SETTINGS_MAX_FRAME_SIZE, we should name this thing. + assert(size <= (1 << 24) - 1) + + let size = Int32(size) + + guard self.windowSize >= size else { + throw NIOHTTP2Errors.flowControlViolation() + } + + self.windowSize -= size + } +} + +extension HTTP2FlowControlWindow: ExpressibleByIntegerLiteral { + typealias IntegerLiteralType = Int32 + + init(integerLiteral initialValue: Int32) { + precondition(initialValue >= 0, "Flow control windows may not begin negative") + precondition(initialValue <= HTTP2FlowControlWindow.maxSize, + "Flow control windows may not exceed \(HTTP2FlowControlWindow.maxSize) bytes") + + self.windowSize = initialValue + } +} + +extension HTTP2FlowControlWindow: CustomStringConvertible { + var description: String { + return self.windowSize.description + } +} + +extension HTTP2FlowControlWindow: Equatable { } + +extension HTTP2FlowControlWindow: Hashable { } + +extension HTTP2FlowControlWindow: Comparable { + static func < (lhs: HTTP2FlowControlWindow, rhs: HTTP2FlowControlWindow) -> Bool { + return lhs.windowSize < rhs.windowSize + } + + static func > (lhs: HTTP2FlowControlWindow, rhs: HTTP2FlowControlWindow) -> Bool { + return lhs.windowSize > rhs.windowSize + } + + static func <= (lhs: HTTP2FlowControlWindow, rhs: HTTP2FlowControlWindow) -> Bool { + return lhs.windowSize <= rhs.windowSize + } + + static func >= (lhs: HTTP2FlowControlWindow, rhs: HTTP2FlowControlWindow) -> Bool { + return lhs.windowSize >= rhs.windowSize + } +} + +extension Int { + init(_ window: HTTP2FlowControlWindow) { + self = Int(window.windowSize) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Frame.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Frame.swift new file mode 100644 index 00000000..32cf4670 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Frame.swift @@ -0,0 +1,305 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHTTP1 +import NIOHPACK + +/// A representation of a single HTTP/2 frame. +public struct HTTP2Frame: NIOSendable { + + /// The frame stream ID as a 32-bit integer. + public var streamID: HTTP2StreamID + + /// The payload of this HTTP/2 frame. + public var payload: FramePayload + + /// Stream priority data, used in PRIORITY frames and optionally in HEADERS frames. + public struct StreamPriorityData: Equatable, Hashable, NIOSendable { + public var exclusive: Bool + public var dependency: HTTP2StreamID + public var weight: UInt8 + } + + /// Frame-type-specific payload data. + public enum FramePayload { + /// A DATA frame, containing raw bytes. + /// + /// See [RFC 7540 § 6.1](https://httpwg.org/specs/rfc7540.html#rfc.section.6.1). + indirect case data(FramePayload.Data) + + /// A HEADERS frame, containing all headers or trailers associated with a request + /// or response. + /// + /// Note that swift-nio-http2 automatically coalesces HEADERS and CONTINUATION + /// frames into a single `FramePayload.headers` instance. + /// + /// See [RFC 7540 § 6.2](https://httpwg.org/specs/rfc7540.html#rfc.section.6.2). + indirect case headers(Headers) + + /// A PRIORITY frame, used to change priority and dependency ordering among + /// streams. + /// + /// See [RFC 7540 § 6.3](https://httpwg.org/specs/rfc7540.html#rfc.section.6.3). + case priority(StreamPriorityData) + + /// A RST_STREAM (reset stream) frame, sent when a stream has encountered an error + /// condition and needs to be terminated as a result. + /// + /// See [RFC 7540 § 6.4](https://httpwg.org/specs/rfc7540.html#rfc.section.6.4). + case rstStream(HTTP2ErrorCode) + + /// A SETTINGS frame, containing various connection--level settings and their + /// desired values. + /// + /// See [RFC 7540 § 6.5](https://httpwg.org/specs/rfc7540.html#rfc.section.6.5). + case settings(Settings) + + /// A PUSH_PROMISE frame, used to notify a peer in advance of streams that a sender + /// intends to initiate. It performs much like a request's HEADERS frame, informing + /// a peer that the response for a theoretical request like the one in the promise + /// will arrive on a new stream. + /// + /// As with the HEADERS frame, swift-nio-http2 will coalesce an initial PUSH_PROMISE + /// frame with any CONTINUATION frames that follow, emitting a single + /// `FramePayload.pushPromise` instance for the complete set. + /// + /// See [RFC 7540 § 6.6](https://httpwg.org/specs/rfc7540.html#rfc.section.6.6). + /// + /// For more information on server push in HTTP/2, see + /// [RFC 7540 § 8.2](https://httpwg.org/specs/rfc7540.html#rfc.section.8.2). + indirect case pushPromise(PushPromise) + + /// A PING frame, used to measure round-trip time between endpoints. + /// + /// See [RFC 7540 § 6.7](https://httpwg.org/specs/rfc7540.html#rfc.section.6.7). + case ping(HTTP2PingData, ack: Bool) + + /// A GOAWAY frame, used to request that a peer immediately cease communication with + /// the sender. It contains a stream ID indicating the last stream that will be processed + /// by the sender, an error code (if the shutdown was caused by an error), and optionally + /// some additional diagnostic data. + /// + /// See [RFC 7540 § 6.8](https://httpwg.org/specs/rfc7540.html#rfc.section.6.8). + indirect case goAway(lastStreamID: HTTP2StreamID, errorCode: HTTP2ErrorCode, opaqueData: ByteBuffer?) + + /// A WINDOW_UPDATE frame. This is used to implement flow control of DATA frames, + /// allowing peers to advertise and update the amount of data they are prepared to + /// process at any given moment. + /// + /// See [RFC 7540 § 6.9](https://httpwg.org/specs/rfc7540.html#rfc.section.6.9). + case windowUpdate(windowSizeIncrement: Int) + + /// An ALTSVC frame. This is sent by an HTTP server to indicate alternative origin + /// locations for accessing the same resource, for instance via another protocol, + /// or over TLS. It consists of an origin and a list of alternate protocols and + /// the locations at which they may be addressed. + /// + /// See [RFC 7838 § 4](https://tools.ietf.org/html/rfc7838#section-4). + /// + /// - Important: ALTSVC frames are not currently supported. Any received ALTSVC frames will + /// be ignored. Attempting to send an ALTSVC frame will result in a fatal error. + indirect case alternativeService(origin: String?, field: ByteBuffer?) + + /// An ORIGIN frame. This allows servers which allow access to multiple origins + /// via the same socket connection to identify which origins may be accessed in + /// this manner. + /// + /// See [RFC 8336 § 2](https://tools.ietf.org/html/rfc8336#section-2). + /// + /// - Important: ORIGIN frames are not currently supported. Any received ORIGIN frames will + /// be ignored. Attempting to send an ORIGIN frame will result in a fatal error. + case origin([String]) + + /// The payload of a DATA frame. + public struct Data { + /// The application data carried within the DATA frame. + public var data: IOData + + /// The value of the END_STREAM flag on this frame. + public var endStream: Bool + + /// The underlying number of padding bytes. If nil, no padding is present. + internal private(set) var _paddingBytes: UInt8? + + /// The number of padding bytes sent in this frame. If nil, this frame was not padded. + public var paddingBytes: Int? { + get { + return self._paddingBytes.map { Int($0) } + } + set { + if let newValue = newValue { + precondition(newValue >= 0 && newValue <= Int(UInt8.max), "Invalid padding byte length: \(newValue)") + self._paddingBytes = UInt8(newValue) + } else { + self._paddingBytes = nil + } + } + } + + public init(data: IOData, endStream: Bool = false, paddingBytes: Int? = nil) { + self.data = data + self.endStream = endStream + self.paddingBytes = paddingBytes + } + } + + /// The payload of a HEADERS frame. + public struct Headers: NIOSendable { + /// The decoded header block belonging to this HEADERS frame. + public var headers: HPACKHeaders + + /// The stream priority data transmitted on this frame, if any. + public var priorityData: StreamPriorityData? + + /// The value of the END_STREAM flag on this frame. + public var endStream: Bool + + /// The underlying number of padding bytes. If nil, no padding is present. + internal private(set) var _paddingBytes: UInt8? + + /// The number of padding bytes sent in this frame. If nil, this frame was not padded. + public var paddingBytes: Int? { + get { + return self._paddingBytes.map { Int($0) } + } + set { + if let newValue = newValue { + precondition(newValue >= 0 && newValue <= Int(UInt8.max), "Invalid padding byte length: \(newValue)") + self._paddingBytes = UInt8(newValue) + } else { + self._paddingBytes = nil + } + } + } + + public init(headers: HPACKHeaders, priorityData: StreamPriorityData? = nil, endStream: Bool = false, paddingBytes: Int? = nil) { + self.headers = headers + self.priorityData = priorityData + self.endStream = endStream + self.paddingBytes = paddingBytes + } + } + + /// The payload of a SETTINGS frame. + public enum Settings: NIOSendable { + /// This SETTINGS frame contains new SETTINGS. + case settings(HTTP2Settings) + + /// This is a SETTINGS ACK. + case ack + } + + public struct PushPromise: NIOSendable { + /// The pushed stream ID. + public var pushedStreamID: HTTP2StreamID + + /// The decoded header block belonging to this PUSH_PROMISE frame. + public var headers: HPACKHeaders + + /// The underlying number of padding bytes. If nil, no padding is present. + internal private(set) var _paddingBytes: UInt8? + + /// The number of padding bytes sent in this frame. If nil, this frame was not padded. + public var paddingBytes: Int? { + get { + return self._paddingBytes.map { Int($0) } + } + set { + if let newValue = newValue { + precondition(newValue >= 0 && newValue <= Int(UInt8.max), "Invalid padding byte length: \(newValue)") + self._paddingBytes = UInt8(newValue) + } else { + self._paddingBytes = nil + } + } + } + + public init(pushedStreamID: HTTP2StreamID, headers: HPACKHeaders, paddingBytes: Int? = nil) { + self.headers = headers + self.pushedStreamID = pushedStreamID + self.paddingBytes = paddingBytes + } + } + + /// The one-byte identifier used to indicate the type of a frame on the wire. + var code: UInt8 { + switch self { + case .data: return 0x0 + case .headers: return 0x1 + case .priority: return 0x2 + case .rstStream: return 0x3 + case .settings: return 0x4 + case .pushPromise: return 0x5 + case .ping: return 0x6 + case .goAway: return 0x7 + case .windowUpdate: return 0x8 + case .alternativeService: return 0xa + case .origin: return 0xc + } + } + } + + /// Constructs a frame header for a given stream ID. All flags are unset. + public init(streamID: HTTP2StreamID, payload: HTTP2Frame.FramePayload) { + self.payload = payload + self.streamID = streamID + } +} + +extension HTTP2Frame.FramePayload { + /// A shorthand heuristic for how many bytes we assume a frame consumes on the wire. + /// + /// Here we concern ourselves only with per-stream frames: that is, `HEADERS`, `DATA`, + /// `WINDOW_UDPATE`, `RST_STREAM`, and I guess `PRIORITY`. As a simple heuristic we + /// hard code fixed lengths for fixed length frames, use a calculated length for + /// variable length frames, and just ignore encoded headers because it's not worth doing a better + /// job. + var estimatedFrameSize: Int { + let frameHeaderSize = 9 + + switch self { + case .data(let d): + let paddingBytes = d.paddingBytes.map { $0 + 1 } ?? 0 + return d.data.readableBytes + paddingBytes + frameHeaderSize + case .headers(let h): + let paddingBytes = h.paddingBytes.map { $0 + 1 } ?? 0 + return paddingBytes + frameHeaderSize + case .priority: + return frameHeaderSize + 5 + case .pushPromise(let p): + // Like headers, this is variably size, and we just ignore the encoded headers because + // it's not worth having a heuristic. + let paddingBytes = p.paddingBytes.map { $0 + 1 } ?? 0 + return paddingBytes + frameHeaderSize + case .rstStream: + return frameHeaderSize + 4 + case .windowUpdate: + return frameHeaderSize + 4 + default: + // Unknown or unexpected control frame: say 9 bytes. + return frameHeaderSize + } + } +} + +// The `@unchecked` is needed because at the time of writing `NIOCore` didn't have `Sendable` support. +#if swift(>=5.5) && canImport(_Concurrency) +extension HTTP2Frame.FramePayload: @unchecked Sendable { + +} +extension HTTP2Frame.FramePayload.Data: @unchecked Sendable { + +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameEncoder.swift new file mode 100644 index 00000000..82953da7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameEncoder.swift @@ -0,0 +1,250 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHPACK + +struct HTTP2FrameEncoder { + var headerEncoder: HPACKEncoder + + // RFC 7540 § 6.5.2 puts the initial value of SETTINGS_MAX_FRAME_SIZE at 2**14 octets + var maxFrameSize: UInt32 = 1<<14 + + init(allocator: ByteBufferAllocator) { + self.headerEncoder = HPACKEncoder(allocator: allocator) + } + + /// Encodes the frame and optionally returns one or more blobs of data + /// ready for the system. + /// + /// Returned data blobs would include anything of potentially flexible + /// length, such as DATA payloads, header fragments in HEADERS or PUSH_PROMISE + /// frames, and so on. This is to avoid manually copying chunks of data which + /// we could just enqueue separately in sequence on the channel. Generally, if + /// we have a byte buffer somewhere, we will return that separately rather than + /// copy it into another buffer, with the corresponding allocation overhead. + /// + /// - Parameters: + /// - frame: The frame to encode. + /// - buf: Destination buffer for the encoded frame. + /// - Returns: An array containing zero or more additional buffers to send, in + /// order. These may contain data frames' payload bytes, encoded + /// header fragments, etc. + /// - Throws: Errors returned from HPACK encoder. + mutating func encode(frame: HTTP2Frame, to buf: inout ByteBuffer) throws -> IOData? { + // note our starting point + let start = buf.writerIndex + +// +-----------------------------------------------+ +// | Length (24) | +// +---------------+---------------+---------------+ +// | Type (8) | Flags (8) | +// +-+-------------+---------------+-------------------------------+ +// |R| Stream Identifier (31) | +// +=+=============================================================+ +// | Frame Payload (0...) ... +// +---------------------------------------------------------------+ + + // skip 24-bit length for now, we'll fill that in later + buf.moveWriterIndex(forwardBy: 3) + + // 8-bit type + buf.writeInteger(frame.payload.code) + + // skip the 8 bit flags for now, we'll fill it in later as well. + let flagsIndex = buf.writerIndex + var flags = FrameFlags() + buf.moveWriterIndex(forwardBy: 1) + + // 32-bit stream identifier -- ensuring the top bit is empty + buf.writeInteger(Int32(frame.streamID)) + + // frame payload follows, which depends on the frame type itself + let payloadStart = buf.writerIndex + let extraFrameData: IOData? + let payloadSize: Int + + switch frame.payload { + case .data(let dataContent): + if dataContent.paddingBytes != nil { + // we don't support sending padded frames just now + throw NIOHTTP2Errors.unsupported(info: "Padding is not supported on sent frames at this time") + } + + if dataContent.endStream { + flags.insert(.endStream) + } + extraFrameData = dataContent.data + payloadSize = dataContent.data.readableBytes + + case .headers(let headerData): + if headerData.paddingBytes != nil { + // we don't support sending padded frames just now + throw NIOHTTP2Errors.unsupported(info: "Padding is not supported on sent frames at this time") + } + + flags.insert(.endHeaders) + if headerData.endStream { + flags.insert(.endStream) + } + + if let priority = headerData.priorityData { + flags.insert(.priority) + var dependencyRaw = UInt32(priority.dependency) + if priority.exclusive { + dependencyRaw |= 0x8000_0000 + } + buf.writeInteger(dependencyRaw) + buf.writeInteger(priority.weight) + } + + try self.headerEncoder.encode(headers: headerData.headers, to: &buf) + payloadSize = buf.writerIndex - payloadStart + extraFrameData = nil + + case .priority(let priorityData): + var raw = UInt32(priorityData.dependency) + if priorityData.exclusive { + raw |= 0x8000_0000 + } + buf.writeInteger(raw) + buf.writeInteger(priorityData.weight) + + extraFrameData = nil + payloadSize = 5 + + case .rstStream(let errcode): + buf.writeInteger(UInt32(errcode.networkCode)) + + payloadSize = 4 + extraFrameData = nil + + case .settings(.settings(let settings)): + for setting in settings { + buf.writeInteger(setting.parameter.networkRepresentation) + buf.writeInteger(setting._value) + } + + payloadSize = settings.count * 6 + extraFrameData = nil + + case .settings(.ack): + payloadSize = 0 + extraFrameData = nil + flags.insert(.ack) + + case .pushPromise(let pushPromiseData): + if pushPromiseData.paddingBytes != nil { + // we don't support sending padded frames just now + throw NIOHTTP2Errors.unsupported(info: "Padding is not supported on sent frames at this time") + } + + let streamVal: UInt32 = UInt32(pushPromiseData.pushedStreamID) + buf.writeInteger(streamVal) + + try self.headerEncoder.encode(headers: pushPromiseData.headers, to: &buf) + + payloadSize = buf.writerIndex - payloadStart + extraFrameData = nil + flags.insert(.endHeaders) + + case .ping(let pingData, let ack): + withUnsafeBytes(of: pingData.bytes) { ptr -> Void in + _ = buf.writeBytes(ptr) + } + + if ack { + flags.insert(.ack) + } + + payloadSize = 8 + extraFrameData = nil + + case .goAway(let lastStreamID, let errorCode, let opaqueData): + let streamVal: UInt32 = UInt32(lastStreamID) & ~0x8000_0000 + buf.writeInteger(streamVal) + buf.writeInteger(UInt32(errorCode.networkCode)) + + if let data = opaqueData { + payloadSize = data.readableBytes + 8 + extraFrameData = .byteBuffer(data) + } else { + payloadSize = 8 + extraFrameData = nil + } + + case .windowUpdate(let size): + buf.writeInteger(UInt32(size) & ~0x8000_0000) + payloadSize = 4 + extraFrameData = nil + + case .alternativeService(let origin, let field): + if let org = origin { + buf.moveWriterIndex(forwardBy: 2) + let start = buf.writerIndex + buf.writeString(org) + buf.setInteger(UInt16(buf.writerIndex - start), at: payloadStart) + } else { + buf.writeInteger(UInt16(0)) + } + + if let value = field { + payloadSize = buf.writerIndex - payloadStart + value.readableBytes + extraFrameData = .byteBuffer(value) + } else { + payloadSize = buf.writerIndex - payloadStart + extraFrameData = nil + } + + case .origin(let origins): + for origin in origins { + let sizeLoc = buf.writerIndex + buf.moveWriterIndex(forwardBy: 2) + + let start = buf.writerIndex + buf.writeString(origin) + buf.setInteger(UInt16(buf.writerIndex - start), at: sizeLoc) + } + + payloadSize = buf.writerIndex - payloadStart + extraFrameData = nil + } + + // Confirm we're not about to violate SETTINGS_MAX_FRAME_SIZE. + guard payloadSize <= Int(self.maxFrameSize) else { + throw InternalError.codecError(code: .frameSizeError) + } + + // Write the frame data. This is the payload size and the flags byte. + buf.writePayloadSize(payloadSize, at: start) + buf.setInteger(flags.rawValue, at: flagsIndex) + + // all bytes to write are in the provided buffer now + return extraFrameData + } +} + +extension ByteBuffer { + fileprivate mutating func writePayloadSize(_ size: Int, at location: Int) { + // Yes, this performs better than running a UInt8 through the generic write(integer:) three times. + var bytes: (UInt8, UInt8, UInt8) + bytes.0 = UInt8((size & 0xff_00_00) >> 16) + bytes.1 = UInt8((size & 0x00_ff_00) >> 8) + bytes.2 = UInt8( size & 0x00_00_ff) + withUnsafeBytes(of: bytes) { ptr in + _ = self.setBytes(ptr, at: location) + } + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameParser.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameParser.swift new file mode 100644 index 00000000..712e592a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2FrameParser.swift @@ -0,0 +1,1365 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHPACK + +/// Ingests HTTP/2 data and produces frames. You feed data in, and sometimes you'll get a complete frame out. +struct HTTP2FrameDecoder { + private static let clientMagicBytes = Array("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".utf8) + + /// The result of a pass through the decoder state machine. + private enum ParseResult { + case needMoreData + case `continue` + case frame(HTTP2Frame, flowControlledLength: Int) + } + + private struct IgnoredFrame: Error {} + + /// The state for a parser that is waiting for the client magic. + private struct ClientMagicState { + private var pendingBytes: ByteBuffer? + + init() { + self.pendingBytes = nil + } + + mutating func process() throws -> AccumulatingFrameHeaderParserState? { + // The client magic is 24 octets long: If we don't have it, keep waiting. + guard var pendingBytes = self.pendingBytes, + let clientMagic = pendingBytes.readSlice(length: 24) else { + return nil + } + + guard clientMagic.readableBytesView.elementsEqual(HTTP2FrameDecoder.clientMagicBytes) else { + throw NIOHTTP2Errors.badClientMagic() + } + + return AccumulatingFrameHeaderParserState(unusedBytes: pendingBytes) + } + + mutating func accumulate(bytes: ByteBuffer) { + self.pendingBytes.setOrWriteImmutableBuffer(bytes) + } + } + + /// The state for a parser that is currently accumulating the bytes of a frame header. + private struct AccumulatingFrameHeaderParserState { + private(set) var unusedBytes: ByteBuffer + + init(unusedBytes: ByteBuffer) { + self.unusedBytes = unusedBytes + if self.unusedBytes.readableBytes == 0 { + // if it's an empty buffer, reset the read/write indices so the read/write indices + // don't just race each other & cause many many reallocations and larger allocations + self.unusedBytes.quietlyReset() + } + } + + enum NextState { + case awaitingPaddingLengthByte(AwaitingPaddingLengthByteParserState) + case accumulatingPayload(AccumulatingPayloadParserState) + case simulatingDataFrames(SimulatingDataFramesParserState) + } + + /// Process the frame header. + /// + /// We have three possible transitions here: we can transition to awaiting a padding + /// length byte, we can transition to simulating data frames, or we can transition to + /// processing any non-padded non-DATA frame. + /// + /// We also do pro-active verification of the state here. + mutating func process(maxFrameSize: UInt32, maxHeaderListSize: Int) throws -> NextState? { + guard let header = self.unusedBytes.readFrameHeader() else { + return nil + } + + // Confirm that SETTINGS_MAX_FRAME_SIZE is respected. + guard header.length <= maxFrameSize else { + throw InternalError.codecError(code: .frameSizeError) + } + + switch header.type { + case .data: + // ensure we're on a valid stream + guard header.streamID != .rootStream else { + // DATA frames cannot appear on the root stream + throw InternalError.codecError(code: .protocolError) + } + + if header.flags.contains(.padded) { + guard header.length > 0 else { + // There needs to be at least the padding length byte, so the minimum frame size is 1. + throw InternalError.codecError(code: .protocolError) + } + return .awaitingPaddingLengthByte( + AwaitingPaddingLengthByteParserState(fromAccumulatingFrameHeader: self, frameHeader: header) + ) + } else { + return .simulatingDataFrames( + SimulatingDataFramesParserState(fromIdle: self, header: header, remainingBytes: header.length) + ) + } + + case .headers, .pushPromise: + // Before we move on, do a quick preflight: if this frame header is for a frame that will + // definitely violate SETTINGS_MAX_HEADER_LIST_SIZE, quit now. + if header.length > maxHeaderListSize { + throw NIOHTTP2Errors.excessivelyLargeHeaderBlock() + } + + if header.flags.contains(.padded) { + guard header.length > 0 else { + // There needs to be at least the padding length byte, so the minimum frame size is 1. + throw InternalError.codecError(code: .protocolError) + } + + return .awaitingPaddingLengthByte( + AwaitingPaddingLengthByteParserState(fromAccumulatingFrameHeader: self, frameHeader: header) + ) + } else { + return .accumulatingPayload(AccumulatingPayloadParserState(fromIdle: self, header: header)) + } + + default: + return .accumulatingPayload(AccumulatingPayloadParserState(fromIdle: self, header: header)) + } + } + + mutating func accumulate(bytes: ByteBuffer) { + self.unusedBytes.writeImmutableBuffer(bytes) + } + } + + private struct AwaitingPaddingLengthByteParserState { + private var header: FrameHeader + private var accumulatedBytes: ByteBuffer + + init(fromAccumulatingFrameHeader state: AccumulatingFrameHeaderParserState, frameHeader: FrameHeader) { + precondition(frameHeader.type.supportsPadding) + precondition(frameHeader.flags.contains(.padded)) + + precondition(frameHeader.length > 0) + self.header = frameHeader + self.accumulatedBytes = state.unusedBytes + } + + enum NextState { + case simulatingDataFrames(SimulatingDataFramesParserState) + case accumulatingPayload(AccumulatingPayloadParserState) + } + + /// Process the padding length byte. + /// + /// Only HEADERS/PUSH_PROMISE and DATA frames can have padding length bytes, + /// so we can only go to the states that process those frames. + mutating func process() throws -> NextState? { + // If we can, strip the padding byte. + guard let expectedPadding = self.accumulatedBytes.readInteger(as: UInt8.self) else { + return nil + } + + // Amend the header to remove the `.padded` flag and update the expected length. + // We know that `self.header.length > 0` (as shown in our init), so we can use unchecked math. + var unpaddedHeader = self.header + unpaddedHeader.flags.remove(.padded) + unpaddedHeader.length &-= 1 + + if unpaddedHeader.length < Int(expectedPadding) { + // Padding that exceeds the remaining payload size MUST be treated as a PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + if unpaddedHeader.type == .data { + return .simulatingDataFrames( + SimulatingDataFramesParserState( + header: unpaddedHeader, + accumulatedBytes: self.accumulatedBytes, + expectedPadding: expectedPadding + ) + ) + } else { + return .accumulatingPayload( + AccumulatingPayloadParserState( + header: unpaddedHeader, + accumulatedBytes: self.accumulatedBytes, + expectedPadding: expectedPadding + ) + ) + } + } + + mutating func accumulate(bytes: ByteBuffer) { + self.accumulatedBytes.writeImmutableBuffer(bytes) + } + } + + /// The state for a parser that is currently accumulating payload data associated with + /// a successfully decoded frame header. + private struct AccumulatingPayloadParserState { + private(set) var header: FrameHeader + private var accumulatedBytes: ByteBuffer + private var expectedPadding: Int? + + init(fromIdle state: AccumulatingFrameHeaderParserState, header: FrameHeader) { + self.header = header + self.accumulatedBytes = state.unusedBytes + self.expectedPadding = nil + } + + init(header: FrameHeader, accumulatedBytes: ByteBuffer, expectedPadding: UInt8) { + // In this state we must not see a .padded header: it has to have been stripped earlier. + // Do not remove this first precondition without removing the unchecked math in process(). + precondition(header.length >= Int(expectedPadding)) + precondition((!header.type.supportsPadding) || (!header.flags.contains(.padded))) + + self.header = header + self.accumulatedBytes = accumulatedBytes + self.expectedPadding = Int(expectedPadding) + } + + enum ProcessResult { + case accumulateHeaderBlockFragments(AccumulatingHeaderBlockFragmentsParserState) + case parseFrame(header: FrameHeader, payloadBytes: ByteBuffer, paddingBytes: Int?, nextState: AccumulatingFrameHeaderParserState) + } + + /// Process a frame. + /// + /// This has two edges: either we parse out a frame body for consumption, or we jump over to + /// the CONTINUATION-sequence logic. + mutating func process() throws -> ProcessResult? { + switch self.header.type { + case .continuation: + // This is an unsolicited CONTINUATION frame + throw InternalError.codecError(code: .protocolError) + + case .data: + // This is an internal programming error, we got into a bad state. DATA frames are + // handled separately. + throw InternalError.impossibleSituation() + + default: + break + } + + guard var payloadBytes = self.accumulatedBytes.readSlice(length: self.header.length) else { + return nil + } + + // We're going to pretend the padding isn't there, by stripping off the trailing portion that contains the padding + // and rewriting the header to imply it was never there. + var syntheticHeader = self.header + + if let padding = self.expectedPadding { + // Drop the padding off the back. The precondition in our constructor means we know that subtracting padding from + // the writer index and header length are both safe. + payloadBytes.moveWriterIndex(to: payloadBytes.writerIndex &- padding) + syntheticHeader.length &-= padding + } + + // entire frame is available -- handle the beginning of a CONTINUATION sequence first. + if self.header.beginsContinuationSequence { + // don't emit these, coalesce them with following CONTINUATION frames + return .accumulateHeaderBlockFragments( + AccumulatingHeaderBlockFragmentsParserState( + header: syntheticHeader, + initialPayload: payloadBytes, + incomingPayload: self.accumulatedBytes, + originalPaddingBytes: self.expectedPadding + ) + ) + } + + // Before we read the frame, we save our state back. This ensures that if we throw an error here, we've + // appropriately skipped the frame payload. + let expectedPadding = self.expectedPadding + let nextState = AccumulatingFrameHeaderParserState(unusedBytes: self.accumulatedBytes) + + return .parseFrame( + header: syntheticHeader, payloadBytes: payloadBytes, paddingBytes: expectedPadding, nextState: nextState + ) + } + + mutating func accumulate(bytes: ByteBuffer) { + self.accumulatedBytes.writeImmutableBuffer(bytes) + } + } + + /// The state for a parser that is currently emitting simulated DATA frames. + /// + /// In this state we are receiving bytes associated with a DATA frame. We have + /// read the header successfully and, instead of accumulating all the payload bytes + /// and emitting the single monolithic DATA frame sent by our peer, we instead emit + /// one DATA frame for each payload chunk we receive from the networking stack. This + /// allows us to make use of the existing `ByteBuffer`s allocated by the stack, + /// and lets us avoid compiling a large buffer in our own memory. Note that it's + /// entirely plausible for a 20MB payload to be split into four 5MB DATA frames, + /// such that the client of this library will already be accumulating them into + /// some form of buffer or file. Our breaking this into (say) twenty 1MB DATA + /// frames will not affect that, and will avoid additional allocations and copies + /// in the meantime. + /// + /// This object is also responsible for ensuring we correctly manage flow control + /// for DATA frames. It does this by notifying the state machine up front of the + /// total flow controlled size of the underlying frame, even if it is synthesising + /// partial frames. All subsequent partial frames have a flow controlled length of + /// zero. This ensures that the upper layer can correctly enforce flow control + /// windows. + private struct SimulatingDataFramesParserState { + private(set) var header: FrameHeader + private var payload: ByteBuffer + private var remainingByteCount: Int + private var flowControlledLength: Int + private var expectedPadding: Int? + + init(fromIdle state: AccumulatingFrameHeaderParserState, header: FrameHeader, remainingBytes: Int) { + self.header = header + self.payload = state.unusedBytes + self.expectedPadding = nil + self.remainingByteCount = remainingBytes + self.flowControlledLength = header.length + } + + init(header: FrameHeader, accumulatedBytes: ByteBuffer, expectedPadding: UInt8) { + // In this state we must not see a .padded header: it has to have been stripped earlier. + precondition(header.length >= Int(expectedPadding)) + precondition((!header.type.supportsPadding) || (!header.flags.contains(.padded))) + + self.header = header + self.payload = accumulatedBytes + self.expectedPadding = Int(expectedPadding) + self.remainingByteCount = header.length + self.flowControlledLength = header.length + 1 // Include the .padding byte + } + + /// The result of successful processing: we always produce a DATA frame, and have + /// to jump to a new state. + struct ProcessResult { + var frame: HTTP2Frame + var flowControlledLength: Int + var nextState: NextState + } + + enum NextState { + case simulatingDataFrames(SimulatingDataFramesParserState) + case strippingTrailingPadding(StrippingTrailingPaddingState) + case accumulatingFrameHeader(AccumulatingFrameHeaderParserState) + } + + /// Process a frame while we're synthesizing data frames. + /// + /// In this state if we succesfully move forward at all we'll produce a DATA frame, as + /// well as a new target state. + mutating func process() throws -> ProcessResult? { + // Making sure the padded flag should be gone. + assert(!self.header.flags.contains(.padded)) + + let payloadSize = self.remainingByteCount - (self.expectedPadding ?? 0) + guard payloadSize >= 0 else { + // This math shouldn't end up short, but we'll defend against it anyway. + throw InternalError.impossibleSituation() + } + + if payloadSize > 0 && self.payload.readableBytes == 0 { + // We can't make progress here, return early. + return nil + } + + // create a frame using these bytes, or a subset thereof + let dataPayload: HTTP2Frame.FramePayload.Data + let nextState: NextState + + // We extract the flow controlled length early because we only ever emit it once for a given frame. We set it to zero here so that all other frames will + // return 0 as a flow controlled length. + let flowControlledLength = self.flowControlledLength + self.flowControlledLength = 0 + + if let frameByteSlice = self.payload.readSlice(length: payloadSize) { + // Here we have the last actual bytes of the payload. + // As this is the final bytes of the payload, we report the padding size here (it conceptually trails) and the + // value of the END_STREAM flag. + dataPayload = HTTP2Frame.FramePayload.Data( + data: .byteBuffer(frameByteSlice), + endStream: self.header.flags.contains(.endStream), + paddingBytes: self.expectedPadding + ) + nextState = self.computeNextStateForFinalFrame() + } else { + dataPayload = self.createSynthesizedFrame() + nextState = .simulatingDataFrames(self) + } + + let outputFrame = HTTP2Frame(streamID: self.header.streamID, payload: .data(dataPayload)) + return ProcessResult(frame: outputFrame, flowControlledLength: flowControlledLength, nextState: nextState) + } + + private func computeNextStateForFinalFrame() -> NextState { + if let padding = self.expectedPadding, padding > 0 { + // We need to strip the padding. + return .strippingTrailingPadding( + StrippingTrailingPaddingState( + fromSimulatingDataFramesState: self, + excessBytes: self.payload, + expectedPadding: padding + ) + ) + } else { + return .accumulatingFrameHeader(AccumulatingFrameHeaderParserState(unusedBytes: self.payload)) + } + } + + private mutating func createSynthesizedFrame() -> HTTP2Frame.FramePayload.Data { + // We don't want to synthesise empty data frames. Zero-length data frames go through a different method + // branch. + precondition(self.payload.readableBytes > 0) + + let frameBytes = self.payload // entire thing + self.remainingByteCount -= frameBytes.readableBytes + self.payload.quietlyReset() + + return HTTP2Frame.FramePayload.Data( + data: .byteBuffer(frameBytes), + endStream: false, // We're synthesising frames, there can't be END_STREAM here. + paddingBytes: nil // We put all the padding on the last frame in the sequence. + ) + } + + mutating func accumulate(bytes: ByteBuffer) { + self.payload.writeImmutableBuffer(bytes) + } + } + + /// State for a parser that is stripping trailing padidng from a frame. + /// + /// This is currently used for DATA frames only. For HEADERS/PUSH_PROMISE frames the edges around + /// CONTINUATION frames mean that it's easier for us to await the entire frame, including padding, + /// before we strip it. + private struct StrippingTrailingPaddingState { + private var header: FrameHeader + private var excessBytes: ByteBuffer + private var expectedPadding: Int + + init(fromSimulatingDataFramesState state: SimulatingDataFramesParserState, excessBytes: ByteBuffer, expectedPadding: Int) { + precondition(expectedPadding > 0) + + self.header = state.header + self.excessBytes = excessBytes + self.expectedPadding = expectedPadding + } + + init(fromAccumulatingPayloadState state: AccumulatingPayloadParserState, excessBytes: ByteBuffer, expectedPadding: Int) { + precondition(expectedPadding > 0) + + self.header = state.header + self.excessBytes = excessBytes + self.expectedPadding = expectedPadding + } + + enum NextState { + case accumulatingFrameHeader(AccumulatingFrameHeaderParserState) + case strippingTrailingPadding(StrippingTrailingPaddingState) + } + + mutating func process() -> NextState? { + if self.excessBytes.readableBytes >= self.expectedPadding { + // All the padding is here. + self.excessBytes.moveReaderIndex(forwardBy: self.expectedPadding) + return .accumulatingFrameHeader(AccumulatingFrameHeaderParserState(unusedBytes: self.excessBytes)) + } else if self.excessBytes.readableBytes > 0 { + // We're short on padding. Strip some and move forward. + // Unchecked is safe here: we know that `readableBytes` is positive, and smaller than `expectedPadding`. + self.expectedPadding &-= self.excessBytes.readableBytes + self.excessBytes.moveReaderIndex(to: self.excessBytes.writerIndex) + return .strippingTrailingPadding(self) + } else { + // Do nothing, we don't have any bytes to consume. + return nil + } + } + + mutating func accumulate(bytes: ByteBuffer) { + self.excessBytes.writeImmutableBuffer(bytes) + } + } + + /// The state for a parser that is accumulating the payload of a CONTINUATION frame. + /// + /// The CONTINUATION frame must follow from an existing HEADERS or PUSH_PROMISE frame, + /// whose details are kept in this state. + private struct AccumulatingContinuationPayloadParserState { + private var initialHeader: FrameHeader + private var continuationHeader: FrameHeader + private var currentFrameBytes: ByteBuffer + private var continuationPayload: ByteBuffer + private var originalPaddingBytes: Int? + + init(fromAccumulatingHeaderBlockFragments acc: AccumulatingHeaderBlockFragmentsParserState, + continuationHeader: FrameHeader) { + precondition(acc.header.beginsContinuationSequence) + precondition(continuationHeader.type == .continuation) + + self.initialHeader = acc.header + self.continuationHeader = continuationHeader + self.currentFrameBytes = acc.accumulatedPayload + self.continuationPayload = acc.incomingPayload + self.originalPaddingBytes = acc.originalPaddingBytes + } + + /// The result of successful processing: we either produce a frame and move to the new accumulating state, + /// or we continue accumulating + enum ProcessResult { + case accumulateContinuationHeader(AccumulatingHeaderBlockFragmentsParserState) + case parseFrame(header: FrameHeader, payloadBytes: ByteBuffer, paddingBytes: Int?, nextState: AccumulatingFrameHeaderParserState) + } + + mutating func process() throws -> ProcessResult? { + guard let continuationPayload = self.continuationPayload.readSlice(length: self.continuationHeader.length) else { + return nil + } + + // We need to flatten this out. Let's synthesise a new frame with a new header. + var header = self.initialHeader + header.length += self.continuationHeader.length + self.currentFrameBytes.writeImmutableBuffer(continuationPayload) + let payload = self.currentFrameBytes + + // we have collected enough bytes: is this the last CONTINUATION frame? + guard self.continuationHeader.flags.contains(.endHeaders) else { + // nope, switch back to accumulating fragments + return .accumulateContinuationHeader( + AccumulatingHeaderBlockFragmentsParserState( + header: header, + initialPayload: payload, + incomingPayload: self.continuationPayload, + originalPaddingBytes: self.originalPaddingBytes + ) + ) + } + + // It is! Let's add .endHeaders to our fake frame. + header.flags.formUnion(.endHeaders) + let nextState = AccumulatingFrameHeaderParserState(unusedBytes: self.continuationPayload) + return .parseFrame(header: header, payloadBytes: payload, paddingBytes: self.originalPaddingBytes, nextState: nextState) + } + + mutating func accumulate(bytes: ByteBuffer) { + self.continuationPayload.writeImmutableBuffer(bytes) + } + } + + /// This state is accumulating the various CONTINUATION frames into a single HEADERS or + /// PUSH_PROMISE frame. + /// + /// The `incomingPayload` member holds any bytes from a following frame that haven't yet + /// accumulated enough to parse the next frame and move to the next state. + private struct AccumulatingHeaderBlockFragmentsParserState { + private(set) var header: FrameHeader + private(set) var accumulatedPayload: ByteBuffer + private(set) var incomingPayload: ByteBuffer + private(set) var originalPaddingBytes: Int? + + init(header: FrameHeader, initialPayload: ByteBuffer, incomingPayload: ByteBuffer, originalPaddingBytes: Int?) { + precondition(header.beginsContinuationSequence) + self.header = header + self.accumulatedPayload = initialPayload + self.incomingPayload = incomingPayload + self.originalPaddingBytes = originalPaddingBytes + } + + mutating func process(maxHeaderListSize: Int) throws -> AccumulatingContinuationPayloadParserState? { + // we have an entire HEADERS/PUSH_PROMISE frame, but one or more CONTINUATION frames + // are arriving. Wait for them. + guard let header = self.incomingPayload.readFrameHeader() else { + return nil + } + + // incoming frame: should be CONTINUATION + guard header.type == .continuation else { + throw InternalError.codecError(code: .protocolError) + } + + // This must be for the stream we're buffering header block fragments for, or this is an error. + guard header.streamID == self.header.streamID else { + throw InternalError.codecError(code: .protocolError) + } + + // Check whether there is any possibility of this payload decompressing and fitting in max header list size. + // If there isn't, kill it. + guard self.header.length + header.length <= maxHeaderListSize else { + throw NIOHTTP2Errors.excessivelyLargeHeaderBlock() + } + + return AccumulatingContinuationPayloadParserState(fromAccumulatingHeaderBlockFragments: self, continuationHeader: header) + } + + mutating func accumulate(bytes: ByteBuffer) { + self.incomingPayload.writeImmutableBuffer(bytes) + } + } + + private enum ParserState { + /// We are waiting for the initial client magic string. + case awaitingClientMagic(ClientMagicState) + + /// This parser has been freshly allocated and has never seen any bytes. + case initialized + + /// We are not in the middle of parsing any frames, we're waiting for a full frame header to arrive. + case accumulatingFrameHeader(AccumulatingFrameHeaderParserState) + + /// We're waiting for the padding length byte. + case awaitingPaddingLengthByte(AwaitingPaddingLengthByteParserState) + + /// We are accumulating payload bytes for a single frame. + case accumulatingPayload(AccumulatingPayloadParserState) + + /// We are receiving bytes from a DATA frame payload, and are emitting multiple DATA frames, + /// one for each chunk of bytes we see here. + case simulatingDataFrames(SimulatingDataFramesParserState) + + /// We've parsed a frame, but we're eating the trailing padding. + case strippingTrailingPadding(StrippingTrailingPaddingState) + + /// We are accumulating a CONTINUATION frame. + case accumulatingContinuationPayload(AccumulatingContinuationPayloadParserState) + + /// We are waiting for a new CONTINUATION frame to arrive. + case accumulatingHeaderBlockFragments(AccumulatingHeaderBlockFragmentsParserState) + + /// A temporary state where we are appending data to a buffer. Must always be exited after the append operation. + case appending + + // MARK: Constructors from the sub-state results. This just hides some noise in the state machine code. + init(_ targetState: AccumulatingFrameHeaderParserState.NextState) { + switch targetState { + case .awaitingPaddingLengthByte(let state): + self = .awaitingPaddingLengthByte(state) + case .accumulatingPayload(let state): + self = .accumulatingPayload(state) + case .simulatingDataFrames(let state): + self = .simulatingDataFrames(state) + } + } + + init(_ targetState: AwaitingPaddingLengthByteParserState.NextState) { + switch targetState { + case .accumulatingPayload(let state): + self = .accumulatingPayload(state) + case .simulatingDataFrames(let state): + self = .simulatingDataFrames(state) + } + } + + init(_ targetState: SimulatingDataFramesParserState.NextState) { + switch targetState { + case .accumulatingFrameHeader(let state): + self = .accumulatingFrameHeader(state) + case .simulatingDataFrames(let state): + self = .simulatingDataFrames(state) + case .strippingTrailingPadding(let state): + self = .strippingTrailingPadding(state) + } + } + + init(_ targetState: StrippingTrailingPaddingState.NextState) { + switch targetState { + case .strippingTrailingPadding(let state): + self = .strippingTrailingPadding(state) + case .accumulatingFrameHeader(let state): + self = .accumulatingFrameHeader(state) + } + } + } + + internal var headerDecoder: HPACKDecoder + private var state: ParserState + + // RFC 7540 § 6.5.2 puts the initial value of SETTINGS_MAX_FRAME_SIZE at 2**14 octets + internal var maxFrameSize: UInt32 = 1<<14 + + /// Creates a new HTTP2 frame decoder. + /// + /// - parameter allocator: A `ByteBufferAllocator` used when accumulating blocks of data + /// and decoding headers. + /// - parameter expectClientMagic: Whether the parser should expect to receive the bytes of + /// client magic string before frame parsing begins. + init(allocator: ByteBufferAllocator, expectClientMagic: Bool) { + self.headerDecoder = HPACKDecoder(allocator: allocator) + + if expectClientMagic { + self.state = .awaitingClientMagic(ClientMagicState()) + } else { + self.state = .initialized + } + } + + /// Used to pass bytes to the decoder. + /// + /// Once you've added bytes, call `nextFrame()` repeatedly to obtain any frames that can + /// be decoded from the bytes previously accumulated. + /// + /// - Parameter bytes: Raw bytes received, ready to decode. + mutating func append(bytes: ByteBuffer) { + switch self.state { + case .awaitingClientMagic(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .awaitingClientMagic(state) + } + case .initialized: + self.state = .accumulatingFrameHeader(AccumulatingFrameHeaderParserState(unusedBytes: bytes)) + case .accumulatingFrameHeader(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .accumulatingFrameHeader(state) + } + case .awaitingPaddingLengthByte(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .awaitingPaddingLengthByte(state) + } + case .accumulatingPayload(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .accumulatingPayload(state) + } + case .simulatingDataFrames(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .simulatingDataFrames(state) + } + case .strippingTrailingPadding(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .strippingTrailingPadding(state) + } + case .accumulatingContinuationPayload(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .accumulatingContinuationPayload(state) + } + case .accumulatingHeaderBlockFragments(var state): + self.avoidingParserCoW { newState in + state.accumulate(bytes: bytes) + newState = .accumulatingHeaderBlockFragments(state) + } + case .appending: + preconditionFailure("Cannot recursively append in appending state") + } + } + + /// Attempts to decode a frame from the accumulated bytes passed to + /// `append(bytes:)`. + /// + /// - returns: A decoded frame, or `nil` if no frame could be decoded. + /// - throws: An error if a decoded frame violated the HTTP/2 protocol + /// rules. + mutating func nextFrame() throws -> (HTTP2Frame, flowControlledLength: Int)? { + // Start running through our state machine until we run out of bytes or we emit a frame. + while true { + switch (try self.processNextState()) { + case .needMoreData: + return nil + case .frame(let frame, let flowControlledLength): + return (frame, flowControlledLength) + case .continue: + continue + } + } + + } + + private mutating func processNextState() throws -> ParseResult { + switch self.state { + case .awaitingClientMagic(var state): + guard let newState = try state.process() else { + return .needMoreData + } + + self.state = .accumulatingFrameHeader(newState) + return .continue + + case .initialized: + // no bytes, no frame + return .needMoreData + + case .accumulatingFrameHeader(var state): + guard let targetState = try state.process(maxFrameSize: self.maxFrameSize, maxHeaderListSize: self.headerDecoder.maxHeaderListSize) else { + return .needMoreData + } + + self.state = .init(targetState) + return .continue + + case .awaitingPaddingLengthByte(var state): + guard let targetState = try state.process() else { + return .needMoreData + } + + self.state = .init(targetState) + return .continue + + + case .accumulatingPayload(var state): + guard let processResult = try state.process() else { + return .needMoreData + } + + switch processResult { + case .accumulateHeaderBlockFragments(let state): + self.state = .accumulatingHeaderBlockFragments(state) + return .continue + + case .parseFrame(header: let header, payloadBytes: var payloadBytes, paddingBytes: let paddingBytes, nextState: let nextState): + // Save off the state first, because if the frame payload parse throws we want to be able to skip over the frame. + self.state = .accumulatingFrameHeader(nextState) + + // an entire frame's data, including HEADERS/PUSH_PROMISE with the END_HEADERS flag set + // this may legitimately return nil if we ignore the frame + let result = try self.readFrame(withHeader: header, from: &payloadBytes, paddingBytes: paddingBytes) + + if payloadBytes.readableBytes > 0 { + // Enforce that we consumed all the bytes. + throw InternalError.codecError(code: .frameSizeError) + } + + // if we got a frame, return it. If not that means we consumed and ignored a frame, so we + // should go round again. + // We cannot emit DATA frames from here, so the flow controlled length is always 0. + if let frame = result { + return .frame(frame, flowControlledLength: 0) + } else { + return .continue + } + } + + case .simulatingDataFrames(var state): + guard let processResult = try state.process() else { + return .needMoreData + } + + self.state = .init(processResult.nextState) + return .frame(processResult.frame, flowControlledLength: processResult.flowControlledLength) + + case .strippingTrailingPadding(var state): + guard let nextState = state.process() else { + return .needMoreData + } + + self.state = .init(nextState) + return .continue + + case .accumulatingContinuationPayload(var state): + guard let processResult = try state.process() else { + return .needMoreData + } + + switch processResult { + case .accumulateContinuationHeader(let state): + self.state = .accumulatingHeaderBlockFragments(state) + return .continue + + case .parseFrame(header: let header, payloadBytes: var payloadBytes, paddingBytes: let paddingBytes, nextState: let nextState): + // Save off the state first, because if the frame payload parse throws we want to be able to skip over the frame. + self.state = .accumulatingFrameHeader(nextState) + + // an entire frame's data, including HEADERS/PUSH_PROMISE with the END_HEADERS flag set + // this may legitimately return nil if we ignore the frame + let result = try self.readFrame(withHeader: header, from: &payloadBytes, paddingBytes: paddingBytes) + + if payloadBytes.readableBytes > 0 { + // Enforce that we consumed all the bytes. + throw InternalError.codecError(code: .frameSizeError) + } + + // if we got a frame, return it. If not that means we consumed and ignored a frame, so we + // should go round again. + // We cannot emit DATA frames from here, so the flow controlled length is always 0. + if let frame = result { + return .frame(frame, flowControlledLength: 0) + } else { + return .continue + } + } + + case .accumulatingHeaderBlockFragments(var state): + guard let processResult = try state.process(maxHeaderListSize: self.headerDecoder.maxHeaderListSize) else { + return .needMoreData + } + + self.state = .accumulatingContinuationPayload(processResult) + return .continue + + case .appending: + preconditionFailure("Attempting to process in appending state") + } + } + + private mutating func readFrame(withHeader header: FrameHeader, from bytes: inout ByteBuffer, paddingBytes: Int?) throws -> HTTP2Frame? { + assert(bytes.readableBytes == header.length, "Buffer should contain exactly \(header.length) bytes.") + + let flags = header.flags + let streamID = header.streamID + + let payload: HTTP2Frame.FramePayload + do { + switch header.type { + case .data: + // Data frames never come through this flow. + preconditionFailure() + case .headers: + precondition(flags.contains(.endHeaders)) + payload = try self.parseHeadersFramePayload( + streamID: streamID, + flags: flags, + bytes: &bytes, + paddingBytes: paddingBytes + ) + case .priority: + payload = try self.parsePriorityFramePayload(streamID: streamID, bytes: &bytes) + case .rstStream: + payload = try self.parseRstStreamFramePayload(streamID: streamID, bytes: &bytes) + case .settings: + payload = try self.parseSettingsFramePayload(streamID: streamID, flags: flags, bytes: &bytes) + case .pushPromise: + precondition(flags.contains(.endHeaders)) + payload = try self.parsePushPromiseFramePayload( + streamID: streamID, + flags: flags, + bytes: &bytes, + paddingBytes: paddingBytes + ) + case .ping: + payload = try self.parsePingFramePayload(streamID: streamID, flags: flags, bytes: &bytes) + case .goAway: + payload = try self.parseGoAwayFramePayload(streamID: streamID, bytes: &bytes) + case .windowUpdate: + payload = try self.parseWindowUpdateFramePayload(bytes: &bytes) + case .continuation: + // CONTINUATION frame should never be found here -- we should have handled them elsewhere + preconditionFailure("Unexpected continuation frame") + case .altSvc: + payload = try self.parseAltSvcFramePayload(streamID: streamID, bytes: &bytes) + case .origin: + payload = try self.parseOriginFramePayload(streamID: streamID, bytes: &bytes) + default: + // RFC 7540 § 4.1 https://httpwg.org/specs/rfc7540.html#FrameHeader + // "Implementations MUST ignore and discard any frame that has a type that is unknown." + bytes.moveReaderIndex(forwardBy: header.length) + return nil + } + } catch is IgnoredFrame { + return nil + } catch _ as NIOHPACKError { + // convert into a connection error of type COMPRESSION_ERROR + throw InternalError.codecError(code: .compressionError) + } + + return HTTP2Frame(streamID: streamID, payload: payload) + } + + private mutating func parseHeadersFramePayload(streamID: HTTP2StreamID, flags: FrameFlags, bytes: inout ByteBuffer, paddingBytes: Int?) throws -> HTTP2Frame.FramePayload { + // HEADERS frame : RFC 7540 § 6.2 + guard streamID != .rootStream else { + // HEADERS frames MUST be associated with a stream. If a HEADERS frame is received whose + // stream identifier field is 0x0, the recipient MUST respond with a connection error + // (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + let priorityData: HTTP2Frame.StreamPriorityData? + if flags.contains(.priority) { + // If we don't have enough length for the priority data, that's an error. + guard let (rawStreamID, weight) = bytes.readMultipleIntegers(as: (UInt32, UInt8).self) else { + throw InternalError.codecError(code: .protocolError) + } + + priorityData = HTTP2Frame.StreamPriorityData(exclusive: (rawStreamID & 0x8000_0000 != 0), + dependency: HTTP2StreamID(networkID: rawStreamID), + weight: weight) + } else { + priorityData = nil + } + + let headers = try self.headerDecoder.decodeHeaders(from: &bytes) + let headersPayload = HTTP2Frame.FramePayload.Headers(headers: headers, + priorityData: priorityData, + endStream: flags.contains(.endStream), + paddingBytes: paddingBytes) + + return .headers(headersPayload) + } + + private func parsePriorityFramePayload(streamID: HTTP2StreamID, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // PRIORITY frame : RFC 7540 § 6.3 + guard streamID != .rootStream else { + // The PRIORITY frame always identifies a stream. If a PRIORITY frame is received + // with a stream identifier of 0x0, the recipient MUST respond with a connection error + // (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + guard let (rawStreamID, weight) = bytes.readMultipleIntegers(as: (UInt32, UInt8).self) else { + // A PRIORITY frame with a length other than 5 octets MUST be treated as a stream + // error (Section 5.4.2) of type FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + + let priorityData = HTTP2Frame.StreamPriorityData(exclusive: rawStreamID & 0x8000_0000 != 0, + dependency: HTTP2StreamID(networkID: rawStreamID), + weight: weight) + return .priority(priorityData) + } + + private func parseRstStreamFramePayload(streamID: HTTP2StreamID, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // RST_STREAM frame : RFC 7540 § 6.4 + guard streamID != .rootStream else { + // RST_STREAM frames MUST be associated with a stream. If a RST_STREAM frame is + // received with a stream identifier of 0x0, the recipient MUST treat this as a + // connection error (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + guard let errorCode = bytes.readInteger(as: UInt32.self) else { + // A RST_STREAM frame with a length other than 4 octets MUST be treated as a + // connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + + return .rstStream(HTTP2ErrorCode(errorCode)) + } + + private func parseSettingsFramePayload(streamID: HTTP2StreamID, flags: FrameFlags, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // SETTINGS frame : RFC 7540 § 6.5 + guard streamID == .rootStream else { + // SETTINGS frames always apply to a connection, never a single stream. The stream + // identifier for a SETTINGS frame MUST be zero (0x0). If an endpoint receives a + // SETTINGS frame whose stream identifier field is anything other than 0x0, the + // endpoint MUST respond with a connection error (Section 5.4.1) of type + // PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + let readableBytes = bytes.readableBytes + + if flags.contains(.ack) { + guard readableBytes == 0 else { + // When [the ACK flag] is set, the payload of the SETTINGS frame MUST be empty. + // Receipt of a SETTINGS frame with the ACK flag set and a length field value + // other than 0 MUST be treated as a connection error (Section 5.4.1) of type + // FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + + return .settings(.ack) + } else if readableBytes % 6 != 0 { + // A SETTINGS frame with a length other than a multiple of 6 octets MUST be treated + // as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + + var settings: [HTTP2Setting] = [] + settings.reserveCapacity(readableBytes / 6) + + while let (settingsIdentifier, value) = bytes.readMultipleIntegers(as: (UInt16, UInt32).self) { + let identifier = HTTP2SettingsParameter(fromPayload: settingsIdentifier) + settings.append(HTTP2Setting(parameter: identifier, value: Int(value))) + } + + // This assert should be utterly safe: we're reading 6 bytes at a time above, so there's no way for us to + // fail to achieve this. It exists only to give us some proximate notification if there was a mistake above. + assert(bytes.readableBytes == 0) + + return .settings(.settings(settings)) + } + + private mutating func parsePushPromiseFramePayload(streamID: HTTP2StreamID, flags: FrameFlags, bytes: inout ByteBuffer, paddingBytes: Int?) throws -> HTTP2Frame.FramePayload { + // PUSH_PROMISE frame : RFC 7540 § 6.6 + guard streamID != .rootStream else { + // The stream identifier of a PUSH_PROMISE frame indicates the stream it is associated with. + // If the stream identifier field specifies the value 0x0, a recipient MUST respond with a + // connection error (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + guard let rawPromisedStreamID = bytes.readInteger(as: UInt32.self) else { + throw InternalError.codecError(code: .frameSizeError) + } + + let promisedStreamID = HTTP2StreamID(networkID: rawPromisedStreamID) + + guard promisedStreamID != .rootStream else { + throw InternalError.codecError(code: .protocolError) + } + + let headers = try self.headerDecoder.decodeHeaders(from: &bytes) + + let pushPromiseContent = HTTP2Frame.FramePayload.PushPromise(pushedStreamID: promisedStreamID, headers: headers, paddingBytes: paddingBytes) + return .pushPromise(pushPromiseContent) + } + + private func parsePingFramePayload(streamID: HTTP2StreamID, flags: FrameFlags, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // PING frame : RFC 7540 § 6.7 + guard let tuple = bytes.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self) else { + // Receipt of a PING frame with a length field value other than 8 MUST be treated + // as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + guard streamID == .rootStream else { + // PING frames are not associated with any individual stream. If a PING frame is + // received with a stream identifier field value other than 0x0, the recipient MUST + // respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + return .ping(HTTP2PingData(withTuple: tuple), ack: flags.contains(.ack)) + } + + private func parseGoAwayFramePayload(streamID: HTTP2StreamID, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // GOAWAY frame : RFC 7540 § 6.8 + guard streamID == .rootStream else { + // The GOAWAY frame applies to the connection, not a specific stream. An endpoint + // MUST treat a GOAWAY frame with a stream identifier other than 0x0 as a connection + // error (Section 5.4.1) of type PROTOCOL_ERROR. + throw InternalError.codecError(code: .protocolError) + } + + guard let (rawLastStreamID, errorCode) = bytes.readMultipleIntegers(as: (UInt32, UInt32).self) else { + // Must have at least 8 bytes of data (last-stream-id plus error-code). + throw InternalError.codecError(code: .frameSizeError) + } + + // Anything left over is the debug data. + let debugData = bytes.readableBytes > 0 ? bytes : nil + bytes.moveReaderIndex(to: bytes.writerIndex) + + return .goAway(lastStreamID: HTTP2StreamID(networkID: rawLastStreamID), + errorCode: HTTP2ErrorCode(errorCode), + opaqueData: debugData) + } + + private func parseWindowUpdateFramePayload(bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // WINDOW_UPDATE frame : RFC 7540 § 6.9 + guard let rawWindowSizeIncrement = bytes.readInteger(as: UInt32.self) else { + // A WINDOW_UPDATE frame with a length other than 4 octets MUST be treated as a + // connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. + throw InternalError.codecError(code: .frameSizeError) + } + + return .windowUpdate(windowSizeIncrement: Int(rawWindowSizeIncrement & ~0x8000_0000)) + } + + private func parseAltSvcFramePayload(streamID: HTTP2StreamID, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // ALTSVC frame : RFC 7838 § 4 + guard let originLen = bytes.readInteger(as: UInt16.self) else { + // Must be at least two bytes, to contain the length of the optional 'Origin' field. + throw InternalError.codecError(code: .frameSizeError) + } + + // For historical reasons we defined the origin as optional, and set to `nil` when the + // origin len was 0, so we need to preserve that here. + let origin: String? + if originLen > 0 { + guard let originString = bytes.readString(length: Int(originLen)) else { + throw InternalError.codecError(code: .frameSizeError) + } + + origin = originString + } else { + origin = nil + } + + // For historical reasons we also defined the field value as optional, and set to `nil` when there were + // no remaining bytes, so we preserve that here as well. + let value: ByteBuffer? + if bytes.readableBytes > 0 { + value = bytes + bytes.moveReaderIndex(to: bytes.writerIndex) + } else { + value = nil + } + + // Double-check the frame values. + if streamID == .rootStream && originLen == 0 { + // MUST have origin on root stream + throw IgnoredFrame() + } + if streamID != .rootStream && originLen != 0 { + // MUST NOT have origin on non-root stream + throw IgnoredFrame() + } + + return .alternativeService(origin: origin, field: value) + } + + private func parseOriginFramePayload(streamID: HTTP2StreamID, bytes: inout ByteBuffer) throws -> HTTP2Frame.FramePayload { + // ORIGIN frame : RFC 8336 § 2 + var origins: [String] = [] + while let originLen = bytes.readInteger(as: UInt16.self) { + guard let origin = bytes.readString(length: Int(originLen)) else { + throw InternalError.codecError(code: .frameSizeError) + } + origins.append(origin) + } + + if bytes.readableBytes > 0 { + // Invalid frame length + throw InternalError.codecError(code: .frameSizeError) + } + + // Now double-check that we can safely use this frame. + guard streamID == .rootStream else { + // The ORIGIN frame MUST be sent on stream 0; an ORIGIN frame on any + // other stream is invalid and MUST be ignored. + throw IgnoredFrame() + } + + return .origin(origins) + } +} + +fileprivate struct FrameHeader { + var length: Int // actually 24-bits + var type: FrameType + var flags: FrameFlags + var streamID: HTTP2StreamID + + fileprivate struct FrameType: Hashable { + private var rawValue: UInt8 + + fileprivate init(_ rawValue: UInt8) { + self.rawValue = rawValue + } + + static let data = FrameType(0) + static let headers = FrameType(1) + static let priority = FrameType(2) + static let rstStream = FrameType(3) + static let settings = FrameType(4) + static let pushPromise = FrameType(5) + static let ping = FrameType(6) + static let goAway = FrameType(7) + static let windowUpdate = FrameType(8) + static let continuation = FrameType(9) + static let altSvc = FrameType(10) + static let origin = FrameType(12) + + var supportsPadding: Bool { + return self == .data || self == .headers || self == .pushPromise + } + } + + var beginsContinuationSequence: Bool { + return (self.type == .headers || self.type == .pushPromise) && !self.flags.contains(.endHeaders) + } +} + +extension ByteBuffer { + fileprivate mutating func readFrameHeader() -> FrameHeader? { + guard let (lenHigh, lenLow, type, flags, rawStreamID) = self.readMultipleIntegers(as: (UInt16, UInt8, UInt8, UInt8, UInt32).self) else { + return nil + } + + return FrameHeader( + length: Int(lenHigh) << 8 | Int(lenLow), + type: FrameHeader.FrameType(type), + flags: FrameFlags(rawValue: flags), + streamID: HTTP2StreamID(networkID: rawStreamID) + ) + } + + fileprivate mutating func quietlyReset() { + self.moveReaderIndex(to: 0) + self.moveWriterIndex(to: 0) + } +} + + +/// The flags supported by the frame types understood by this protocol. +struct FrameFlags: OptionSet, CustomStringConvertible { + internal typealias RawValue = UInt8 + + internal private(set) var rawValue: UInt8 + + internal init(rawValue: UInt8) { + self.rawValue = rawValue + } + + /// END_STREAM flag. Valid on DATA and HEADERS frames. + internal static let endStream = FrameFlags(rawValue: 0x01) + + /// ACK flag. Valid on SETTINGS and PING frames. + internal static let ack = FrameFlags(rawValue: 0x01) + + /// END_HEADERS flag. Valid on HEADERS, CONTINUATION, and PUSH_PROMISE frames. + internal static let endHeaders = FrameFlags(rawValue: 0x04) + + /// PADDED flag. Valid on DATA, HEADERS, CONTINUATION, and PUSH_PROMISE frames. + /// + /// NB: swift-nio-http2 does not automatically pad outgoing frames. + internal static let padded = FrameFlags(rawValue: 0x08) + + /// PRIORITY flag. Valid on HEADERS frames, specifically as the first frame sent + /// on a new stream. + internal static let priority = FrameFlags(rawValue: 0x20) + + // useful for test cases + internal static var allFlags: FrameFlags = [.endStream, .endHeaders, .padded, .priority] + + internal var description: String { + var strings: [String] = [] + for i in 0..<8 { + let flagBit: UInt8 = 1 << i + if (self.rawValue & flagBit) != 0 { + strings.append(String(flagBit, radix: 16, uppercase: true)) + } + } + return "[\(strings.joined(separator: ", "))]" + } +} + + +// MARK: CoW helpers +extension HTTP2FrameDecoder { + /// So, uh...this function needs some explaining. + /// + /// There is a downside to having all of the parser data in associated data on enumerations: any modification of + /// that data will trigger copy on write for heap-allocated data. That means that when we append data to the underlying + /// ByteBuffer we will CoW it, which is not good. + /// + /// The way we can avoid this is by using this helper function. It will temporarily set state to a value with no + /// associated data, before attempting the body of the function. It will also verify that the parser never + /// remains in this bad state. + /// + /// A key note here is that all callers must ensure that they return to a good state before they exit. + /// + /// Sadly, because it's generic and has a closure, we need to force it to be inlined at all call sites, which is + /// not ideal. + @inline(__always) + private mutating func avoidingParserCoW(_ body: (inout ParserState) -> ReturnType) -> ReturnType { + self.state = .appending + defer { + assert(!self.isAppending) + } + + return body(&self.state) + } + + private var isAppending: Bool { + if case .appending = self.state { + return true + } else { + return false + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PingData.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PingData.swift new file mode 100644 index 00000000..b259ba8c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PingData.swift @@ -0,0 +1,147 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// The opaque data contained in a HTTP/2 ping frame. +/// +/// A HTTP/2 ping frame must contain 8 bytes of opaque data that is controlled entirely by the sender. +/// This data type encapsulates those 8 bytes while providing a friendly interface for them. +public struct HTTP2PingData: NIOSendable { + /// The underlying bytes to be sent to the wire. These are in network byte order. + public var bytes: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) + + /// Exposes the `HTTP2PingData` as an unsigned 64-bit integer. This property will perform any + /// endianness transition that is required, meaning that there is no need to byte swap the result + /// or before setting this property. + public var integer: UInt64 { + // Note: this is the safest way to do this, because it automatically does the right thing + // from a byte order perspective. It's not necessarily the fastest though, and it's definitely + // not the prettiest. + get { + var rval = UInt64(bytes.0) << 56 + rval += UInt64(bytes.1) << 48 + rval += UInt64(bytes.2) << 40 + rval += UInt64(bytes.3) << 32 + rval += UInt64(bytes.4) << 24 + rval += UInt64(bytes.5) << 16 + rval += UInt64(bytes.6) << 8 + rval += UInt64(bytes.7) + return rval + } + set { + self.bytes = ( + UInt8(newValue >> 56), UInt8(truncatingIfNeeded: newValue >> 48), + UInt8(truncatingIfNeeded: newValue >> 40), UInt8(truncatingIfNeeded: newValue >> 32), + UInt8(truncatingIfNeeded: newValue >> 24), UInt8(truncatingIfNeeded: newValue >> 16), + UInt8(truncatingIfNeeded: newValue >> 8), UInt8(truncatingIfNeeded: newValue) + ) + } + } + + /// Create a new, blank, `HTTP2PingData`. + public init() { + self.bytes = (0, 0, 0, 0, 0, 0, 0, 0) + } + + /// Create a `HTTP2PingData` containing the 64-bit integer provided in network byte order. + public init(withInteger integer: UInt64) { + self.init() + self.integer = integer + } + + /// Create a `HTTP2PingData` from a tuple of bytes. + public init(withTuple tuple: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)) { + self.bytes = tuple + } +} + +extension HTTP2PingData: RandomAccessCollection, MutableCollection { + public typealias Index = Int + public typealias Element = UInt8 + + public var startIndex: Index { + return 0 + } + + public var endIndex: Index { + return 7 + } + + public subscript(_ index: Index) -> Element { + get { + switch index { + case 0: + return self.bytes.0 + case 1: + return self.bytes.1 + case 2: + return self.bytes.2 + case 3: + return self.bytes.3 + case 4: + return self.bytes.4 + case 5: + return self.bytes.5 + case 6: + return self.bytes.6 + case 7: + return self.bytes.7 + default: + preconditionFailure("Invalid index into HTTP2PingData: \(index)") + } + } + set { + switch index { + case 0: + self.bytes.0 = newValue + case 1: + self.bytes.1 = newValue + case 2: + self.bytes.2 = newValue + case 3: + self.bytes.3 = newValue + case 4: + self.bytes.4 = newValue + case 5: + self.bytes.5 = newValue + case 6: + self.bytes.6 = newValue + case 7: + self.bytes.7 = newValue + default: + preconditionFailure("Invalid index into HTTP2PingData: \(index)") + } + } + } +} + +extension HTTP2PingData: Equatable { + public static func ==(lhs: HTTP2PingData, rhs: HTTP2PingData) -> Bool { + return lhs.bytes.0 == rhs.bytes.0 && + lhs.bytes.1 == rhs.bytes.1 && + lhs.bytes.2 == rhs.bytes.2 && + lhs.bytes.3 == rhs.bytes.3 && + lhs.bytes.4 == rhs.bytes.4 && + lhs.bytes.5 == rhs.bytes.5 && + lhs.bytes.6 == rhs.bytes.6 && + lhs.bytes.7 == rhs.bytes.7 + } +} + +extension HTTP2PingData: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine(self.integer) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift new file mode 100644 index 00000000..efe80cae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift @@ -0,0 +1,273 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOTLS + +/// The supported ALPN protocol tokens for NIO's HTTP/2 abstraction layer. +/// +/// These can be used to configure your TLS handler appropriately such that it +/// can negotiate HTTP/2 on secure connections. For example, using swift-nio-ssl, +/// you could configure the pipeline like this: +/// +/// let config = TLSConfiguration.forClient(applicationProtocols: NIOHTTP2SupportedALPNProtocols) +/// let context = try SSLContext(configuration: config) +/// channel.pipeline.add(handler: OpenSSLClientHandler(context: context, serverHostname: "example.com")).then { +/// channel.pipeline.configureHTTP2SecureUpgrade(...) +/// } +/// +/// Configuring for servers is very similar, but is left as an exercise for the reader. +public let NIOHTTP2SupportedALPNProtocols = ["h2", "http/1.1"] + +extension ChannelPipeline { + /// Configures a channel pipeline to perform a HTTP/2 secure upgrade. + /// + /// HTTP/2 secure upgrade uses the Application Layer Protocol Negotiation TLS extension to + /// negotiate the inner protocol as part of the TLS handshake. For this reason, until the TLS + /// handshake is complete, the ultimate configuration of the channel pipeline cannot be known. + /// + /// This function configures the pipeline with a pair of callbacks that will handle the result + /// of the negotiation. It explicitly **does not** configure a TLS handler to actually attempt + /// to negotiate ALPN. The supported ALPN protocols are provided in + /// `NIOHTTP2SupportedALPNProtocols`: please ensure that the TLS handler you are using for your + /// pipeline is appropriately configured to perform this protocol negotiation. + /// + /// If negotiation results in an unexpected protocol, the pipeline will close the connection + /// and no callback will fire. + /// + /// This configuration is acceptable for use on both client and server channel pipelines. + /// + /// - parameters: + /// - h2PipelineConfigurator: A callback that will be invoked if HTTP/2 has been negogiated, and that + /// should configure the pipeline for HTTP/2 use. Must return a future that completes when the + /// pipeline has been fully mutated. + /// - http1PipelineConfigurator: A callback that will be invoked if HTTP/1.1 has been explicitly + /// negotiated, or if no protocol was negotiated. Must return a future that completes when the + /// pipeline has been fully mutated. + /// - returns: An `EventLoopFuture` that completes when the pipeline is ready to negotiate. + @available(*, deprecated, renamed: "Channel.configureHTTP2SecureUpgrade(h2ChannelConfigurator:http1ChannelConfigurator:)") + public func configureHTTP2SecureUpgrade(h2PipelineConfigurator: @escaping (ChannelPipeline) -> EventLoopFuture, + http1PipelineConfigurator: @escaping (ChannelPipeline) -> EventLoopFuture) -> EventLoopFuture { + let alpnHandler = ApplicationProtocolNegotiationHandler { result in + switch result { + case .negotiated("h2"): + // Successful upgrade to HTTP/2. Let the user configure the pipeline. + return h2PipelineConfigurator(self) + case .negotiated("http/1.1"), .fallback: + // Explicit or implicit HTTP/1.1 choice. + return http1PipelineConfigurator(self) + case .negotiated: + // We negotiated something that isn't HTTP/1.1. This is a bad scene, and is a good indication + // of a user configuration error. We're going to close the connection directly. + return self.close().flatMap { self.eventLoop.makeFailedFuture(NIOHTTP2Errors.InvalidALPNToken()) } + } + } + + return self.addHandler(alpnHandler) + } +} + +extension Channel { + /// Configures a `ChannelPipeline` to speak HTTP/2. + /// + /// In general this is not entirely useful by itself, as HTTP/2 is a negotiated protocol. This helper does not handle negotiation. + /// Instead, this simply adds the handlers required to speak HTTP/2 after negotiation has completed, or when agreed by prior knowledge. + /// Whenever possible use this function to setup a HTTP/2 server pipeline, as it allows that pipeline to evolve without breaking your code. + /// + /// - parameters: + /// - mode: The mode this pipeline will operate in, server or client. + /// - initialLocalSettings: The settings that will be used when establishing the connection. These will be sent to the peer as part of the + /// handshake. + /// - position: The position in the pipeline into which to insert these handlers. + /// - inboundStreamStateInitializer: A closure that will be called whenever the remote peer initiates a new stream. This should almost always + /// be provided, especially on servers. + /// - returns: An `EventLoopFuture` containing the `HTTP2StreamMultiplexer` inserted into this pipeline, which can be used to initiate new streams. + @available(*, deprecated, renamed: "configureHTTP2Pipeline(mode:initialLocalSettings:position:targetWindowSize:inboundStreamInitializer:)") + public func configureHTTP2Pipeline(mode: NIOHTTP2Handler.ParserMode, + initialLocalSettings: [HTTP2Setting] = nioDefaultSettings, + position: ChannelPipeline.Position = .last, + inboundStreamStateInitializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)? = nil) -> EventLoopFuture { + return self.configureHTTP2Pipeline(mode: mode, initialLocalSettings: initialLocalSettings, position: position, targetWindowSize: 65535, inboundStreamStateInitializer: inboundStreamStateInitializer) + } + + /// Configures a `ChannelPipeline` to speak HTTP/2. + /// + /// In general this is not entirely useful by itself, as HTTP/2 is a negotiated protocol. This helper does not handle negotiation. + /// Instead, this simply adds the handlers required to speak HTTP/2 after negotiation has completed, or when agreed by prior knowledge. + /// Whenever possible use this function to setup a HTTP/2 server pipeline, as it allows that pipeline to evolve without breaking your code. + /// + /// - parameters: + /// - mode: The mode this pipeline will operate in, server or client. + /// - initialLocalSettings: The settings that will be used when establishing the connection. These will be sent to the peer as part of the + /// handshake. + /// - position: The position in the pipeline into which to insert these handlers. + /// - targetWindowSize: The target size of the HTTP/2 flow control window. + /// - inboundStreamStateInitializer: A closure that will be called whenever the remote peer initiates a new stream. This should almost always + /// be provided, especially on servers. + /// - returns: An `EventLoopFuture` containing the `HTTP2StreamMultiplexer` inserted into this pipeline, which can be used to initiate new streams. + @available(*, deprecated, renamed: "configureHTTP2Pipeline(mode:initialLocalSettings:position:targetWindowSize:inboundStreamInitializer:)") + public func configureHTTP2Pipeline(mode: NIOHTTP2Handler.ParserMode, + initialLocalSettings: [HTTP2Setting] = nioDefaultSettings, + position: ChannelPipeline.Position = .last, + targetWindowSize: Int, + inboundStreamStateInitializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)? = nil) -> EventLoopFuture { + var handlers = [ChannelHandler]() + handlers.reserveCapacity(2) // Update this if we need to add more handlers, to avoid unnecessary reallocation. + handlers.append(NIOHTTP2Handler(mode: mode, initialSettings: initialLocalSettings)) + let multiplexer = HTTP2StreamMultiplexer(mode: mode, channel: self, targetWindowSize: targetWindowSize, inboundStreamStateInitializer: inboundStreamStateInitializer) + handlers.append(multiplexer) + + return self.pipeline.addHandlers(handlers, position: position).map { multiplexer } + } + + /// Configures a `ChannelPipeline` to speak HTTP/2. + /// + /// In general this is not entirely useful by itself, as HTTP/2 is a negotiated protocol. This helper does not handle negotiation. + /// Instead, this simply adds the handlers required to speak HTTP/2 after negotiation has completed, or when agreed by prior knowledge. + /// Whenever possible use this function to setup a HTTP/2 server pipeline, as it allows that pipeline to evolve without breaking your code. + /// + /// - parameters: + /// - mode: The mode this pipeline will operate in, server or client. + /// - initialLocalSettings: The settings that will be used when establishing the connection. These will be sent to the peer as part of the + /// handshake. + /// - position: The position in the pipeline into which to insert these handlers. + /// - targetWindowSize: The target size of the HTTP/2 flow control window. + /// - inboundStreamInitializer: A closure that will be called whenever the remote peer initiates a new stream. This should almost always + /// be provided, especially on servers. + /// - returns: An `EventLoopFuture` containing the `HTTP2StreamMultiplexer` inserted into this pipeline, which can be used to initiate new streams. + public func configureHTTP2Pipeline(mode: NIOHTTP2Handler.ParserMode, + initialLocalSettings: [HTTP2Setting] = nioDefaultSettings, + position: ChannelPipeline.Position = .last, + targetWindowSize: Int = 65535, + inboundStreamInitializer: ((Channel) -> EventLoopFuture)?) -> EventLoopFuture { + var handlers = [ChannelHandler]() + handlers.reserveCapacity(2) // Update this if we need to add more handlers, to avoid unnecessary reallocation. + handlers.append(NIOHTTP2Handler(mode: mode, initialSettings: initialLocalSettings)) + let multiplexer = HTTP2StreamMultiplexer(mode: mode, channel: self, targetWindowSize: targetWindowSize, inboundStreamInitializer: inboundStreamInitializer) + handlers.append(multiplexer) + + return self.pipeline.addHandlers(handlers, position: position).map { multiplexer } + } + + /// Configures a channel to perform a HTTP/2 secure upgrade. + /// + /// HTTP/2 secure upgrade uses the Application Layer Protocol Negotiation TLS extension to + /// negotiate the inner protocol as part of the TLS handshake. For this reason, until the TLS + /// handshake is complete, the ultimate configuration of the channel pipeline cannot be known. + /// + /// This function configures the channel with a pair of callbacks that will handle the result + /// of the negotiation. It explicitly **does not** configure a TLS handler to actually attempt + /// to negotiate ALPN. The supported ALPN protocols are provided in + /// `NIOHTTP2SupportedALPNProtocols`: please ensure that the TLS handler you are using for your + /// pipeline is appropriately configured to perform this protocol negotiation. + /// + /// If negotiation results in an unexpected protocol, the pipeline will close the connection + /// and no callback will fire. + /// + /// This configuration is acceptable for use on both client and server channel pipelines. + /// + /// - parameters: + /// - h2ChannelConfigurator: A callback that will be invoked if HTTP/2 has been negogiated, and that + /// should configure the channel for HTTP/2 use. Must return a future that completes when the + /// channel has been fully mutated. + /// - http1ChannelConfigurator: A callback that will be invoked if HTTP/1.1 has been explicitly + /// negotiated, or if no protocol was negotiated. Must return a future that completes when the + /// channel has been fully mutated. + /// - returns: An `EventLoopFuture` that completes when the channel is ready to negotiate. + public func configureHTTP2SecureUpgrade(h2ChannelConfigurator: @escaping (Channel) -> EventLoopFuture, + http1ChannelConfigurator: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + let alpnHandler = ApplicationProtocolNegotiationHandler { result in + switch result { + case .negotiated("h2"): + // Successful upgrade to HTTP/2. Let the user configure the pipeline. + return h2ChannelConfigurator(self) + case .negotiated("http/1.1"), .fallback: + // Explicit or implicit HTTP/1.1 choice. + return http1ChannelConfigurator(self) + case .negotiated: + // We negotiated something that isn't HTTP/1.1. This is a bad scene, and is a good indication + // of a user configuration error. We're going to close the connection directly. + return self.close().flatMap { self.eventLoop.makeFailedFuture(NIOHTTP2Errors.invalidALPNToken()) } + } + } + + return self.pipeline.addHandler(alpnHandler) + } + + /// Configures a `ChannelPipeline` to speak either HTTP or HTTP/2 according to what can be negotiated with the client. + /// + /// This helper takes care of configuring the server pipeline such that it negotiates whether to + /// use HTTP/1.1 or HTTP/2. Once the protocol to use for the channel has been negotiated, the + /// provided callback will configure the application-specific handlers in a protocol-agnostic way. + /// + /// This function doesn't configure the TLS handler. Callers of this function need to add a TLS + /// handler appropriately configured to perform protocol negotiation. + /// + /// - parameters: + /// - h2ConnectionChannelConfigurator: An optional callback that will be invoked only + /// when the negotiated protocol is H2 to configure the connection channel. + /// - configurator: A callback that will be invoked after a protocol has been negotiated. + /// The callback only needs to add application-specific handlers and must return a future + /// that completes when the channel has been fully mutated. + /// - returns: `EventLoopFuture` that completes when the channel is ready. + public func configureCommonHTTPServerPipeline( + h2ConnectionChannelConfigurator: ((Channel) -> EventLoopFuture)? = nil, + _ configurator: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + return self.configureCommonHTTPServerPipeline(h2ConnectionChannelConfigurator: h2ConnectionChannelConfigurator, targetWindowSize: 65535, configurator) + } + + /// Configures a `ChannelPipeline` to speak either HTTP or HTTP/2 according to what can be negotiated with the client. + /// + /// This helper takes care of configuring the server pipeline such that it negotiates whether to + /// use HTTP/1.1 or HTTP/2. Once the protocol to use for the channel has been negotiated, the + /// provided callback will configure the application-specific handlers in a protocol-agnostic way. + /// + /// This function doesn't configure the TLS handler. Callers of this function need to add a TLS + /// handler appropriately configured to perform protocol negotiation. + /// + /// - parameters: + /// - h2ConnectionChannelConfigurator: An optional callback that will be invoked only + /// when the negotiated protocol is H2 to configure the connection channel. + /// - targetWindowSize: The target size of the HTTP/2 flow control window. + /// - configurator: A callback that will be invoked after a protocol has been negotiated. + /// The callback only needs to add application-specific handlers and must return a future + /// that completes when the channel has been fully mutated. + /// - returns: `EventLoopFuture` that completes when the channel is ready. + public func configureCommonHTTPServerPipeline( + h2ConnectionChannelConfigurator: ((Channel) -> EventLoopFuture)? = nil, + targetWindowSize: Int, + _ configurator: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + let h2ChannelConfigurator = { (channel: Channel) -> EventLoopFuture in + channel.configureHTTP2Pipeline(mode: .server, targetWindowSize: targetWindowSize) { streamChannel -> EventLoopFuture in + streamChannel.pipeline.addHandler(HTTP2FramePayloadToHTTP1ServerCodec()).flatMap { () -> EventLoopFuture in + configurator(streamChannel) + } + }.flatMap { (_: HTTP2StreamMultiplexer) in + if let h2ConnectionChannelConfigurator = h2ConnectionChannelConfigurator { + return h2ConnectionChannelConfigurator(channel) + } else { + return channel.eventLoop.makeSucceededFuture(()) + } + } + } + let http1ChannelConfigurator = { (channel: Channel) -> EventLoopFuture in + channel.pipeline.configureHTTPServerPipeline().flatMap { _ in + configurator(channel) + } + } + return self.configureHTTP2SecureUpgrade(h2ChannelConfigurator: h2ChannelConfigurator, + http1ChannelConfigurator: http1ChannelConfigurator) + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Settings.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Settings.swift new file mode 100644 index 00000000..c71df1cc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Settings.swift @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A collection of HTTP/2 settings. +/// +/// This is a typealias because we may change this into a custom structure at some stage. +public typealias HTTP2Settings = [HTTP2Setting] + +/// A HTTP/2 settings parameter that allows representing both known and unknown HTTP/2 +/// settings parameters. +public struct HTTP2SettingsParameter: NIOSendable { + internal let networkRepresentation: UInt16 + + /// Create a `HTTP2SettingsParameter` that is not known to NIO. + /// + /// If this is a known parameter, use one of the static values. + public init(extensionSetting: Int) { + self.networkRepresentation = UInt16(extensionSetting) + } + + /// Initialize a `HTTP2SettingsParameter` from nghttp2's representation. + internal init(fromNetwork value: Int32) { + self.networkRepresentation = UInt16(value) + } + + /// Initialize a `HTTP2SettingsParameter` from a network `UInt16`. + internal init(fromPayload value: UInt16) { + self.networkRepresentation = value + } + + /// A helper to initialize the static parameters. + private init(_ value: UInt16) { + self.networkRepresentation = value + } + + /// Corresponds to SETTINGS_HEADER_TABLE_SIZE + public static let headerTableSize = HTTP2SettingsParameter(1) + + /// Corresponds to SETTINGS_ENABLE_PUSH. + public static let enablePush = HTTP2SettingsParameter(2) + + /// Corresponds to SETTINGS_MAX_CONCURRENT_STREAMS + public static let maxConcurrentStreams = HTTP2SettingsParameter(3) + + /// Corresponds to SETTINGS_INITIAL_WINDOW_SIZE + public static let initialWindowSize = HTTP2SettingsParameter(4) + + /// Corresponds to SETTINGS_MAX_FRAME_SIZE + public static let maxFrameSize = HTTP2SettingsParameter(5) + + /// Corresponds to SETTINGS_MAX_HEADER_LIST_SIZE + public static let maxHeaderListSize = HTTP2SettingsParameter(6) + + /// Corresponds to SETTINGS_ENABLE_CONNECT_PROTOCOL from RFC 8441. + public static let enableConnectProtocol = HTTP2SettingsParameter(8) +} + +extension HTTP2SettingsParameter: Equatable { } + +extension HTTP2SettingsParameter: Hashable { } + +/// A single setting for HTTP/2, a combination of a `HTTP2SettingsParameter` and its value. +public struct HTTP2Setting: NIOSendable { + /// The settings parameter for this setting. + public var parameter: HTTP2SettingsParameter + + /// The value of the settings parameter. This must be a 32-bit number. + public var value: Int { + get { + return Int(self._value) + } + set { + self._value = UInt32(newValue) + } + } + + /// The value of the setting. Swift doesn't like using explicitly-sized integers in general, + /// so we use this as an internal implementation detail and expose it via a computed Int + /// property. + internal var _value: UInt32 + + /// Create a new `HTTP2Setting`. + public init(parameter: HTTP2SettingsParameter, value: Int) { + self.parameter = parameter + self._value = UInt32(value) + } +} + +extension HTTP2Setting: Equatable { + public static func ==(lhs: HTTP2Setting, rhs: HTTP2Setting) -> Bool { + return lhs.parameter == rhs.parameter && lhs._value == rhs._value + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Stream.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Stream.swift new file mode 100644 index 00000000..6b023984 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2Stream.swift @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOHTTP1 +import NIOHPACK + +extension HPACKHeaders { + /// Whether this `HTTPHeaders` corresponds to a final response or not. + /// + /// This function is only valid if called on a response header block. If the :status header + /// is not present, this will throw. + fileprivate func isInformationalResponse() throws -> Bool { + return try self.peekPseudoHeader(name: ":status").first! == "1" + } +} + +/// A state machine that keeps track of the header blocks sent or received and that determines the type of any +/// new header block. +struct HTTP2HeadersStateMachine { + /// The list of possible header frame types. + /// + /// This is used in combination with introspection of the HTTP header blocks to determine what HTTP header block + /// a certain HTTP header is. + enum HeaderType { + /// A request header block. + case requestHead + + /// An informational response header block. These can be sent zero or more times. + case informationalResponseHead + + /// A final response header block. + case finalResponseHead + + /// A trailer block. Once this is sent no further header blocks are acceptable. + case trailer + } + + /// The previous header block. + private var previousHeader: HeaderType? + + /// The mode of this connection: client or server. + private let mode: NIOHTTP2Handler.ParserMode + + init(mode: NIOHTTP2Handler.ParserMode) { + self.mode = mode + } + + /// Called when about to process a HTTP headers block to determine its type. + mutating func newHeaders(block: HPACKHeaders) throws -> HeaderType { + let newType: HeaderType + + switch (self.mode, self.previousHeader) { + case (.server, .none): + // The first header block received on a server mode stream must be a request block. + newType = .requestHead + case (.client, .none), + (.client, .some(.informationalResponseHead)): + // The first header block received on a client mode stream may be either informational or final, + // depending on the value of the :status pseudo-header. Alternatively, if the previous + // header block was informational, the same possibilities apply. + newType = try block.isInformationalResponse() ? .informationalResponseHead : .finalResponseHead + case (.server, .some(.requestHead)), + (.client, .some(.finalResponseHead)): + // If the sevrer has already received a request head, or the client has already received a final response, + // this is a trailer block. + newType = .trailer + case (.server, .some(.informationalResponseHead)), + (.server, .some(.finalResponseHead)), + (.client, .some(.requestHead)): + // These states should not be reachable! + preconditionFailure("Invalid internal state!") + case (.server, .some(.trailer)), + (.client, .some(.trailer)): + // TODO(cory): This should probably throw, as this can happen in malformed programs without the world ending. + preconditionFailure("Sending too many header blocks.") + } + + self.previousHeader = newType + return newType + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamChannel.swift new file mode 100644 index 00000000..11557c91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamChannel.swift @@ -0,0 +1,927 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + + +/// The various channel options specific to `HTTP2StreamChannel`s. +/// +/// Please note that some of NIO's regular `ChannelOptions` are valid on `HTTP2StreamChannel`s. +public struct HTTP2StreamChannelOptions: NIOSendable { + /// - seealso: `StreamIDOption`. + public static let streamID: HTTP2StreamChannelOptions.Types.StreamIDOption = .init() +} + +extension HTTP2StreamChannelOptions { + public enum Types {} +} + +@available(*, deprecated, renamed: "HTTP2StreamChannelOptions.Types.StreamIDOption") +public typealias StreamIDOption = HTTP2StreamChannelOptions.Types.StreamIDOption + +extension HTTP2StreamChannelOptions.Types { + /// `StreamIDOption` allows users to query the stream ID for a given `HTTP2StreamChannel`. + /// + /// On active `HTTP2StreamChannel`s, it is possible that a channel handler or user may need to know which + /// stream ID the channel owns. This channel option allows that query. Please note that this channel option + /// is *get-only*: that is, it cannot be used with `setOption`. The stream ID for a given `HTTP2StreamChannel` + /// is immutable. + /// + /// If a channel is not active, the stream ID will not be present, and attempting to + /// get this channel option will fail. + public struct StreamIDOption: ChannelOption { + public typealias Value = HTTP2StreamID + + public init() { } + } +} + +/// The current state of a stream channel. +private enum StreamChannelState { + /// The stream has been created, but not configured. + case idle + + /// The is "active": we haven't sent channelActive yet, but it exists on the network and any shutdown must cause a frame to be emitted. + case remoteActive + + /// This is also "active", but different to the above: we've sent channelActive, but the NIOHTTP2Handler hasn't seen the frame yet, + /// and so we can close this channel without action if needed. + case localActive + + /// This is actually active: channelActive has been fired and the HTTP2Handler believes this stream exists. + case active + + /// We are closing from a state where channelActive had been fired. In practice this is only ever active, as + /// in localActive we transition directly to closed. + case closing + + /// We're closing from a state where we have never fired channel active, but where the channel was on the network. + /// This means we need to send frames and wait for their side effects. + case closingNeverActivated + + /// We're fully closed. + case closed + + mutating func activate() { + switch self { + case .idle: + self = .localActive + case .remoteActive: + self = .active + case .localActive, .active, .closing, .closingNeverActivated, .closed: + preconditionFailure("Became active from state \(self)") + } + } + + mutating func networkActive() { + switch self { + case .idle: + self = .remoteActive + case .localActive: + self = .active + case .closed: + preconditionFailure("Stream must be reset on network activation when closed") + case .remoteActive, .active, .closing, .closingNeverActivated: + preconditionFailure("Cannot become network active twice, in state \(self)") + } + } + + mutating func beginClosing() { + switch self { + case .active, .closing: + self = .closing + case .closingNeverActivated, .remoteActive: + self = .closingNeverActivated + case .idle, .localActive: + preconditionFailure("Idle streams immediately close") + case .closed: + preconditionFailure("Cannot begin closing while closed") + } + } + + mutating func completeClosing() { + switch self { + case .idle, .remoteActive, .closing, .closingNeverActivated, .active, .localActive: + self = .closed + case .closed: + preconditionFailure("Complete closing from \(self)") + } + } +} + +// The type of data read from and written to the channel. +enum HTTP2StreamDataType { + /// `HTTP2Frame` + case frame + /// `HTTP2Frame.FramePayload` + case framePayload +} + +private enum HTTP2StreamData { + case frame(HTTP2Frame) + case framePayload(HTTP2Frame.FramePayload) + + var estimatedFrameSize: Int { + switch self { + case .frame(let frame): + return frame.payload.estimatedFrameSize + case .framePayload(let payload): + return payload.estimatedFrameSize + } + } +} + +final class HTTP2StreamChannel: Channel, ChannelCore { + /// The stream data type of the channel. + private let streamDataType: HTTP2StreamDataType + + internal init(allocator: ByteBufferAllocator, + parent: Channel, + multiplexer: HTTP2StreamMultiplexer, + streamID: HTTP2StreamID?, + targetWindowSize: Int32, + outboundBytesHighWatermark: Int, + outboundBytesLowWatermark: Int, + streamDataType: HTTP2StreamDataType) { + self.allocator = allocator + self.closePromise = parent.eventLoop.makePromise() + self.localAddress = parent.localAddress + self.remoteAddress = parent.remoteAddress + self.parent = parent + self.eventLoop = parent.eventLoop + self.streamID = streamID + self.multiplexer = multiplexer + self.windowManager = InboundWindowManager(targetSize: Int32(targetWindowSize)) + self._isActiveAtomic = .makeAtomic(value: false) + self._isWritable = .makeAtomic(value: true) + self.state = .idle + self.streamDataType = streamDataType + self.writabilityManager = StreamChannelFlowController(highWatermark: outboundBytesHighWatermark, + lowWatermark: outboundBytesLowWatermark, + parentIsWritable: parent.isWritable) + + // To begin with we initialize autoRead to false, but we are going to fetch it from our parent before we + // go much further. + self.autoRead = false + self._pipeline = ChannelPipeline(channel: self) + } + + internal func configure(initializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)?, userPromise promise: EventLoopPromise?) { + assert(self.streamDataType == .frame) + // We need to configure this channel. This involves doing four things: + // 1. Setting our autoRead state from the parent + // 2. Calling the initializer, if provided. + // 3. Activating when complete. + // 4. Catching errors if they occur. + self.getAutoReadFromParent { autoReadResult in + switch autoReadResult { + case .success(let autoRead): + self.autoRead = autoRead + if let initializer = initializer { + // This initializer callback can only be invoked if we already have a stream ID. + // So we force-unwrap here. + initializer(self, self.streamID!).whenComplete { result in + switch result { + case .success: + self.postInitializerActivate(promise: promise) + case .failure(let error): + self.configurationFailed(withError: error, promise: promise) + } + } + } else { + self.postInitializerActivate(promise: promise) + } + case .failure(let error): + self.configurationFailed(withError: error, promise: promise) + } + } + } + + internal func configure(initializer: ((Channel) -> EventLoopFuture)?, userPromise promise: EventLoopPromise?) { + assert(self.streamDataType == .framePayload) + // We need to configure this channel. This involves doing four things: + // 1. Setting our autoRead state from the parent + // 2. Calling the initializer, if provided. + // 3. Activating when complete. + // 4. Catching errors if they occur. + self.getAutoReadFromParent { autoReadResult in + switch autoReadResult { + case .success(let autoRead): + self.autoRead = autoRead + if let initializer = initializer { + initializer(self).whenComplete { result in + switch result { + case .success: + self.postInitializerActivate(promise: promise) + case .failure(let error): + self.configurationFailed(withError: error, promise: promise) + } + } + } else { + self.postInitializerActivate(promise: promise) + } + case .failure(let error): + self.configurationFailed(withError: error, promise: promise) + } + } + } + + /// Gets the 'autoRead' option from the parent channel and invokes the `body` closure with the + /// result. This may be done synchronously if the parent `Channel` supports synchronous options. + private func getAutoReadFromParent(_ body: @escaping (Result) -> Void) { + // This force unwrap is safe as parent is assigned in the initializer, and never unassigned. + // Note we also don't set the value here: the additional `map` causes an extra allocation + // when using a Swift 5.0 compiler. + if let syncOptions = self.parent!.syncOptions { + let autoRead = Result(catching: { try syncOptions.getOption(ChannelOptions.autoRead) }) + body(autoRead) + } else { + self.parent!.getOption(ChannelOptions.autoRead).whenComplete { autoRead in + body(autoRead) + } + } + } + + /// Activates the channel if the parent channel is active and succeeds the given `promise`. + private func postInitializerActivate(promise: EventLoopPromise?) { + // This force unwrap is safe as parent is assigned in the initializer, and never unassigned. + // If parent is not active, we expect to receive a channelActive later. + if self.parent!.isActive { + self.performActivation() + } + + // We aren't using cascade here to avoid the allocations it causes. + promise?.succeed(self) + } + + /// Handle any error that occurred during configuration. + private func configurationFailed(withError error: Error, promise: EventLoopPromise?) { + switch self.state { + case .idle, .localActive, .closed: + // The stream isn't open on the network, nothing to close. + self.errorEncountered(error: error) + case .remoteActive, .active, .closing, .closingNeverActivated: + // In all of these states the stream is still on the network and we may need to take action. + self.closedWhileOpen() + } + + promise?.fail(error) + } + + /// Activates this channel. + internal func performActivation() { + precondition(self.parent?.isActive ?? false, "Parent must be active to activate the child") + + if self.state == .closed || self.state == .closingNeverActivated { + // We're already closed, or we've been asked to close and are waiting for the network. + // No need to activate in either case + return + } + + self.modifyingState { $0.activate() } + self.pipeline.fireChannelActive() + self.tryToAutoRead() + self.deliverPendingWrites() + } + + internal func networkActivationReceived() { + if self.state == .closed { + // Uh-oh: we got an activation but we think we're closed! We need to send a RST_STREAM frame. We'll only do it if we have a stream ID. + if let streamID = self.streamID { + let resetFrame = HTTP2Frame(streamID: streamID, payload: .rstStream(.cancel)) + self.parent?.writeAndFlush(resetFrame, promise: nil) + } + return + } + self.modifyingState { $0.networkActive() } + + if self.writabilityManager.isWritable != self._isWritable.load() { + // We have probably delayed telling the user that this channel isn't writable, but we should do + // it now. + self._isWritable.store(self.writabilityManager.isWritable) + self.pipeline.fireChannelWritabilityChanged() + } + + // If we got here, we may need to flush some pending reads. Notably we don't call read0 here as + // we don't actually want to start reading before activation, which tryToRead will refuse to do. + if self.pendingReads.count > 0 { + self.tryToRead() + } + } + + private var _pipeline: ChannelPipeline! + + public let allocator: ByteBufferAllocator + + private let closePromise: EventLoopPromise<()> + + private let multiplexer: HTTP2StreamMultiplexer + + public var closeFuture: EventLoopFuture { + return self.closePromise.futureResult + } + + public var pipeline: ChannelPipeline { + return self._pipeline + } + + public let localAddress: SocketAddress? + + public let remoteAddress: SocketAddress? + + public let parent: Channel? + + func localAddress0() throws -> SocketAddress { + fatalError() + } + + func remoteAddress0() throws -> SocketAddress { + fatalError() + } + + func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + if self.eventLoop.inEventLoop { + do { + return self.eventLoop.makeSucceededFuture(try self.setOption0(option, value: value)) + } catch { + return self.eventLoop.makeFailedFuture(error) + } + } else { + return self.eventLoop.submit { try self.setOption0(option, value: value) } + } + } + + public func getOption(_ option: Option) -> EventLoopFuture { + if self.eventLoop.inEventLoop { + do { + return self.eventLoop.makeSucceededFuture(try self.getOption0(option)) + } catch { + return self.eventLoop.makeFailedFuture(error) + } + } else { + return self.eventLoop.submit { try self.getOption0(option) } + } + } + + private func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.preconditionInEventLoop() + + switch option { + case _ as ChannelOptions.Types.AutoReadOption: + self.autoRead = value as! Bool + default: + fatalError("setting option \(option) on HTTP2StreamChannel not supported") + } + } + + private func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.preconditionInEventLoop() + + switch option { + case _ as HTTP2StreamChannelOptions.Types.StreamIDOption: + if let streamID = self.streamID { + return streamID as! Option.Value + } else { + throw NIOHTTP2Errors.noStreamIDAvailable() + } + case _ as ChannelOptions.Types.AutoReadOption: + return self.autoRead as! Option.Value + default: + fatalError("option \(option) not supported on HTTP2StreamChannel") + } + } + + public var isWritable: Bool { + return self._isWritable.load() + } + + private let _isWritable: NIOAtomic + + private var _isActive: Bool { + return self.state == .active || self.state == .closing || self.state == .localActive + } + + public var isActive: Bool { + return self._isActiveAtomic.load() + } + + private let _isActiveAtomic: NIOAtomic + + public var _channelCore: ChannelCore { + return self + } + + public let eventLoop: EventLoop + + internal var streamID: HTTP2StreamID? + + private var state: StreamChannelState + + private var windowManager: InboundWindowManager + + /// If close0 was called but the stream could not synchronously close (because it's currently + /// active), the promise is stored here until it can be fulfilled. + private var pendingClosePromise: EventLoopPromise? + + /// A buffer of pending inbound reads delivered from the parent channel. + /// + /// In the future this buffer will be used to manage interactions with read() and even, one day, + /// with flow control. For now, though, all this does is hold frames until we have set the + /// channel up. + private var pendingReads: CircularBuffer = CircularBuffer(initialCapacity: 8) + + /// Whether `autoRead` is enabled. By default, all `HTTP2StreamChannel` objects inherit their `autoRead` + /// state from their parent. + private var autoRead: Bool + + /// Whether a call to `read` has happened without any frames available to read (that is, whether newly + /// received frames should be immediately delivered to the pipeline). + private var unsatisfiedRead: Bool = false + + /// A buffer of pending outbound writes to deliver to the parent channel. + /// + /// To correctly respect flushes, we deliberately withold frames from the parent channel until this + /// stream is flushed, at which time we deliver them all. This buffer holds the pending ones. + private var pendingWrites: MarkedCircularBuffer<(HTTP2StreamData, EventLoopPromise?)> = MarkedCircularBuffer(initialCapacity: 8) + + /// A list node used to hold stream channels. + internal var streamChannelListNode: StreamChannelListNode = StreamChannelListNode() + + /// An object that controls whether this channel should be writable. + private var writabilityManager: StreamChannelFlowController + + public func register0(promise: EventLoopPromise?) { + fatalError("not implemented \(#function)") + } + + public func bind0(to: SocketAddress, promise: EventLoopPromise?) { + fatalError("not implemented \(#function)") + } + + public func connect0(to: SocketAddress, promise: EventLoopPromise?) { + fatalError("not implemented \(#function)") + } + + public func write0(_ data: NIOAny, promise: EventLoopPromise?) { + guard self.state != .closed else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + let streamData: HTTP2StreamData + switch self.streamDataType { + case .frame: + streamData = .frame(self.unwrapData(data)) + case .framePayload: + streamData = .framePayload(self.unwrapData(data)) + } + + // We need a promise to attach our flow control callback to. + // Regardless of whether the write succeeded or failed, we don't count + // the bytes any longer. + let promise = promise ?? self.eventLoop.makePromise() + let writeSize = streamData.estimatedFrameSize + + // Right now we deal with this math by just attaching a callback to all promises. This is going + // to be annoyingly expensive, but for now it's the most straightforward approach. + promise.futureResult.hop(to: self.eventLoop).whenComplete { (_: Result) in + if case .changed(newValue: let value) = self.writabilityManager.wroteBytes(writeSize) { + self.changeWritability(to: value) + } + } + self.pendingWrites.append((streamData, promise)) + + // Ok, we can make an outcall now, which means we can safely deal with the flow control. + if case .changed(newValue: let value) = self.writabilityManager.bufferedBytes(writeSize) { + self.changeWritability(to: value) + } + } + + public func flush0() { + self.pendingWrites.mark() + + if self._isActive { + self.deliverPendingWrites() + } + } + + public func read0() { + if self.unsatisfiedRead { + // We already have an unsatisfied read, let's do nothing. + return + } + + // At this stage, we have an unsatisfied read. If there is no pending data to read, + // we're going to call read() on the parent channel. Otherwise, we're going to + // succeed the read out of our pending data. + self.unsatisfiedRead = true + if self.pendingReads.count > 0 { + self.tryToRead() + } else { + self.parent?.read() + } + } + + public func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + // If the stream is already closed, we can fail this early and abort processing. If it's not, we need to emit a + // RST_STREAM frame. + guard self.state != .closed else { + promise?.fail(ChannelError.alreadyClosed) + return + } + + // Store the pending close promise: it'll be succeeded later. + if let promise = promise { + if let pendingPromise = self.pendingClosePromise { + pendingPromise.futureResult.cascade(to: promise) + } else { + self.pendingClosePromise = promise + } + } + + switch self.state { + case .idle, .localActive, .closed: + // The stream isn't open on the network, just go straight to closed cleanly. + self.closedCleanly() + case .remoteActive, .active, .closing, .closingNeverActivated: + // In all of these states the stream is still on the network and we need to wait. + self.closedWhileOpen() + } + } + + public func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + // do nothing + } + + public func channelRead0(_ data: NIOAny) { + // do nothing + } + + public func errorCaught0(error: Error) { + // do nothing + } + + /// Called when the channel was closed from the pipeline while the stream is still open. + /// + /// Will emit a RST_STREAM frame in order to close the stream. Note that this function does not + /// directly close the stream: it waits until the stream closed notification is fired. + private func closedWhileOpen() { + precondition(self.state != .closed) + guard self.state != .closing else { + // If we're already closing, nothing to do here. + return + } + + self.modifyingState { $0.beginClosing() } + // We should have a stream ID here, force-unwrap is safe. + let resetFrame = HTTP2Frame(streamID: self.streamID!, payload: .rstStream(.cancel)) + self.receiveOutboundFrame(resetFrame, promise: nil) + self.multiplexer.childChannelFlush() + } + + private func closedCleanly() { + guard self.state != .closed else { + return + } + self.modifyingState { $0.completeClosing() } + self.dropPendingReads() + self.failPendingWrites(error: ChannelError.eof) + if let promise = self.pendingClosePromise { + self.pendingClosePromise = nil + promise.succeed(()) + } + self.pipeline.fireChannelInactive() + + self.eventLoop.execute { + self.removeHandlers(pipeline: self.pipeline) + self.closePromise.succeed(()) + if let streamID = self.streamID { + self.multiplexer.childChannelClosed(streamID: streamID) + } else { + self.multiplexer.childChannelClosed(channelID: ObjectIdentifier(self)) + } + } + } + + fileprivate func errorEncountered(error: Error) { + guard self.state != .closed else { + return + } + self.modifyingState { $0.completeClosing() } + self.dropPendingReads() + self.failPendingWrites(error: error) + if let promise = self.pendingClosePromise { + self.pendingClosePromise = nil + promise.fail(error) + } + self.pipeline.fireErrorCaught(error) + self.pipeline.fireChannelInactive() + + self.eventLoop.execute { + self.removeHandlers(pipeline: self.pipeline) + self.closePromise.fail(error) + if let streamID = self.streamID { + self.multiplexer.childChannelClosed(streamID: streamID) + } else { + self.multiplexer.childChannelClosed(channelID: ObjectIdentifier(self)) + } + } + } + + private func tryToRead() { + // If there's no read to satisfy, no worries about it. + guard self.unsatisfiedRead else { + return + } + + // If we're not active, we will hold on to these reads. + guard self._isActive else { + return + } + + // If there are no pending reads, do nothing. + guard self.pendingReads.count > 0 else { + return + } + + // Ok, we're satisfying a read here. + self.unsatisfiedRead = false + self.deliverPendingReads() + self.tryToAutoRead() + } + + private func changeWritability(to newWritability: Bool) { + self._isWritable.store(newWritability) + self.pipeline.fireChannelWritabilityChanged() + } + + private func tryToAutoRead() { + if self.autoRead { + // If auto-read is turned on, recurse into channelPipeline.read(). + // This cannot recurse indefinitely unless frames are being delivered + // by the read stacks, which is generally fairly unlikely to continue unbounded. + self.pipeline.read() + } + } +} + +// MARK:- Functions used to manage pending reads and writes. +private extension HTTP2StreamChannel { + /// Drop all pending reads. + private func dropPendingReads() { + /// We don't need to report the dropped reads, just remove them all. + self.pendingReads.removeAll() + } + + /// Deliver all pending reads to the channel. + private func deliverPendingReads() { + assert(self._isActive) + while self.pendingReads.count > 0 { + let frame = self.pendingReads.removeFirst() + + let anyStreamData: NIOAny + let dataLength: Int? + + switch self.streamDataType { + case .frame: + anyStreamData = NIOAny(frame) + case .framePayload: + anyStreamData = NIOAny(frame.payload) + } + + switch frame.payload { + case .data(let data): + dataLength = data.data.readableBytes + default: + dataLength = nil + } + + self.pipeline.fireChannelRead(anyStreamData) + + if let size = dataLength, let increment = self.windowManager.bufferedFrameEmitted(size: size) { + // To have a pending read, we must have a stream ID. + let frame = HTTP2Frame(streamID: self.streamID!, payload: .windowUpdate(windowSizeIncrement: increment)) + self.receiveOutboundFrame(frame, promise: nil) + // This flush should really go away, but we need it for now until we sort out window management. + self.multiplexer.childChannelFlush() + } + } + self.pipeline.fireChannelReadComplete() + } + + /// Delivers all pending flushed writes to the parent channel. + private func deliverPendingWrites() { + // If there are no pending writes, don't bother with the processing. + guard self.pendingWrites.hasMark else { + return + } + + // Get a streamID from the multiplexer if we haven't got one already. + if self.streamID == nil { + self.streamID = self.multiplexer.requestStreamID(forChannel: self) + } + + while self.pendingWrites.hasMark { + let (streamData, promise) = self.pendingWrites.removeFirst() + let frame: HTTP2Frame + + switch streamData { + case .frame(let f): + frame = f + case .framePayload(let payload): + // This unwrap is okay: we just ensured that `self.streamID` was set above. + frame = HTTP2Frame(streamID: self.streamID!, payload: payload) + } + + self.receiveOutboundFrame(frame, promise: promise) + } + self.multiplexer.childChannelFlush() + } + + /// Fails all pending writes with the given error. + private func failPendingWrites(error: Error) { + assert(self.state == .closed) + while self.pendingWrites.count > 0 { + self.pendingWrites.removeFirst().1?.fail(error) + } + } +} + +// MARK:- Functions used to communicate between the `HTTP2StreamMultiplexer` and the `HTTP2StreamChannel`. +internal extension HTTP2StreamChannel { + /// Called when a frame is received from the network. + /// + /// - parameters: + /// - frame: The `HTTP2Frame` received from the network. + func receiveInboundFrame(_ frame: HTTP2Frame) { + guard self.state != .closed else { + // Do nothing + return + } + + // Record the size of the frame so that when we receive a window update event our + // calculation on whether we emit a WINDOW_UPDATE frame is based on the bytes we have + // actually delivered into the pipeline. + if case .data(let dataPayload) = frame.payload { + self.windowManager.bufferedFrameReceived(size: dataPayload.data.readableBytes) + + // No further window update frames should be sent. + if dataPayload.endStream { + self.windowManager.closed = true + } + } else if case .headers(let headersPayload) = frame.payload, headersPayload.endStream { + // No further window update frames should be sent. + self.windowManager.closed = true + } + + self.pendingReads.append(frame) + } + + /// Called when a frame is sent to the network. + /// + /// - parameters: + /// - frame: The `HTTP2Frame` to send to the network. + /// - promise: The promise associated with the frame write. + private func receiveOutboundFrame(_ frame: HTTP2Frame, promise: EventLoopPromise?) { + guard self.state != .closed else { + let error = ChannelError.alreadyClosed + promise?.fail(error) + self.errorEncountered(error: error) + return + } + self.multiplexer.childChannelWrite(frame, promise: promise) + } + + /// Called when a stream closure is received from the network. + /// + /// - parameters: + /// - reason: The reason received from the network, if any. + func receiveStreamClosed(_ reason: HTTP2ErrorCode?) { + // Avoid emitting any WINDOW_UPDATE frames now that we're closed. + self.windowManager.closed = true + + // The stream is closed, we should force forward all pending frames, even without + // unsatisfied read, to ensure the handlers can see all frames before receiving + // channelInactive. + if self.pendingReads.count > 0 && self._isActive { + self.unsatisfiedRead = false + self.deliverPendingReads() + } + + if let reason = reason { + // To receive from the network, it must be safe to force-unwrap here. + let err = NIOHTTP2Errors.streamClosed(streamID: self.streamID!, errorCode: reason) + self.errorEncountered(error: err) + } else { + self.closedCleanly() + } + } + + func receiveWindowUpdatedEvent(_ windowSize: Int) { + if let increment = self.windowManager.newWindowSize(windowSize) { + // To receive from the network, it must be safe to force-unwrap here. + let frame = HTTP2Frame(streamID: self.streamID!, payload: .windowUpdate(windowSizeIncrement: increment)) + self.receiveOutboundFrame(frame, promise: nil) + // This flush should really go away, but we need it for now until we sort out window management. + self.multiplexer.childChannelFlush() + } + } + + func initialWindowSizeChanged(delta: Int) { + if let increment = self.windowManager.initialWindowSizeChanged(delta: delta) { + // To receive from the network, it must be safe to force-unwrap here. + let frame = HTTP2Frame(streamID: self.streamID!, payload: .windowUpdate(windowSizeIncrement: increment)) + self.receiveOutboundFrame(frame, promise: nil) + // This flush should really go away, but we need it for now until we sort out window management. + self.multiplexer.childChannelFlush() + } + } + + func receiveParentChannelReadComplete() { + self.tryToRead() + } + + func parentChannelWritabilityChanged(newValue: Bool) { + // There's a trick here that's worth noting: if the child channel hasn't either sent a frame + // or been activated on the network, we don't actually want to change the observable writability. + // This is because in this case we really want user code to send a frame as soon as possible to avoid + // issues with their stream ID becoming out of date. Once the state transitions we can update + // the writability if needed. + guard case .changed(newValue: let localValue) = self.writabilityManager.parentWritabilityChanged(newValue) else { + return + } + + // Ok, the writability changed. + switch self.state { + case .idle, .localActive: + // Do nothing here. + return + case .remoteActive, .active, .closing, .closingNeverActivated, .closed: + self._isWritable.store(localValue) + self.pipeline.fireChannelWritabilityChanged() + } + } + + func receiveStreamError(_ error: NIOHTTP2Errors.StreamError) { + assert(error.streamID == self.streamID) + self.pipeline.fireErrorCaught(error.baseError) + } +} + +extension HTTP2StreamChannel { + // A helper function used to ensure that state modification leads to changes in the channel active atomic. + private func modifyingState(_ closure: (inout StreamChannelState) throws -> ReturnType) rethrows -> ReturnType { + defer { + self._isActiveAtomic.store(self._isActive) + } + return try closure(&self.state) + } +} + +// MARK: Custom String Convertible +extension HTTP2StreamChannel { + public var description: String { + return "HTTP2StreamChannel(streamID: \(String(describing: self.streamID)), isActive: \(self.isActive), isWritable: \(self.isWritable))" + } +} + +extension HTTP2StreamChannel { + internal struct SynchronousOptions: NIOSynchronousChannelOptions { + private let channel: HTTP2StreamChannel + + fileprivate init(channel: HTTP2StreamChannel) { + self.channel = channel + } + + /// Set `option` to `value` on this `Channel`. + /// + /// - Important: Must be called on the `EventLoop` the `Channel` is running on. + public func setOption(_ option: Option, value: Option.Value) throws { + try self.channel.setOption0(option, value: value) + } + + /// Get the value of `option` for this `Channel`. + /// + /// - Important: Must be called on the `EventLoop` the `Channel` is running on. + public func getOption(_ option: Option) throws -> Option.Value { + return try self.channel.getOption0(option) + } + } + + /// Returns a view of the `Channel` exposing synchronous versions of `setOption` and `getOption`. + public var syncOptions: NIOSynchronousChannelOptions? { + return SynchronousOptions(channel: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamID.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamID.swift new file mode 100644 index 00000000..5a040c23 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamID.swift @@ -0,0 +1,156 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A single HTTP/2 stream ID. +/// +/// Every stream in HTTP/2 has a unique 31-bit stream ID. This stream ID monotonically +/// increases over the lifetime of the connection. While the stream ID is a 31-bit +/// integer on the wire, it does not meaningfully *behave* like a 31-bit integer: it is +/// not reasonable to perform mathematics on it, for example. +/// +/// For this reason, SwiftNIO encapsulates the idea of this type into the HTTP2StreamID +/// structure. +public struct HTTP2StreamID: NIOSendable { + /// The stream ID as a 32 bit integer that will be sent on the network. This will + /// always be positive. + internal var networkStreamID: Int32 + + /// The root stream on a HTTP/2 connection, stream 0. + /// + /// This can safely be used across all connections to identify stream 0. + public static let rootStream: HTTP2StreamID = 0 + + /// The largest possible stream ID on a HTTP/2 connection. + /// + /// This should not usually be used to manage a specific stream. Instead, it's a sentinel + /// that can be used to "quiesce" a HTTP/2 connection on a GOAWAY frame. + public static let maxID: HTTP2StreamID = HTTP2StreamID(Int32.max) + + /// Returns a boolean indicating whether this stream ID relates to a client initiated stream. + public var isClientInitiated: Bool { + return self.networkStreamID % 2 == 1 + } + + /// Returns a boolean indicating whether this stream ID relates to a server initiated stream. + public var isServerInitiated: Bool { + // Noone may initiate the root stream. + return self.networkStreamID % 2 == 0 && self != .rootStream + } + + /// Create a `HTTP2StreamID` for a specific integer value. + public init(_ integerID: Int) { + precondition(integerID >= 0 && integerID <= Int32.max, "\(integerID) is not a valid HTTP/2 stream ID value") + self.networkStreamID = Int32(integerID) + } + + /// Create a `HTTP2StreamID` for a specific integer value. + public init(_ integerID: Int32) { + precondition(integerID >= 0, "\(integerID) is not a valid HTTP/2 stream ID value") + self.networkStreamID = integerID + } + + /// Create a `HTTP2StreamID` from a 32-bit value received as part of a frame. + /// + /// This will ignore the most significant bit of the provided value. + internal init(networkID: UInt32) { + self.networkStreamID = Int32(networkID & ~0x8000_0000) + } +} + +// MARK:- Equatable conformance for HTTP2StreamID +extension HTTP2StreamID: Equatable { } + + +// MARK:- Hashable conformance for HTTP2StreamID +extension HTTP2StreamID: Hashable { } + + +// MARK:- Comparable conformance for HTTP2StreamID +extension HTTP2StreamID: Comparable { + public static func <(lhs: HTTP2StreamID, rhs: HTTP2StreamID) -> Bool { + return lhs.networkStreamID < rhs.networkStreamID + } + + public static func >(lhs: HTTP2StreamID, rhs: HTTP2StreamID) -> Bool { + return lhs.networkStreamID > rhs.networkStreamID + } + + public static func <=(lhs: HTTP2StreamID, rhs: HTTP2StreamID) -> Bool { + return lhs.networkStreamID <= rhs.networkStreamID + } + + public static func >=(lhs: HTTP2StreamID, rhs: HTTP2StreamID) -> Bool { + return lhs.networkStreamID >= rhs.networkStreamID + } +} + + +// MARK:- CustomStringConvertible conformance for HTTP2StreamID +extension HTTP2StreamID: CustomStringConvertible { + public var description: String { + return "HTTP2StreamID(\(String(describing: self.networkStreamID)))" + } +} + + +// MARK:- ExpressibleByIntegerLiteral conformance for HTTP2StreamID +extension HTTP2StreamID: ExpressibleByIntegerLiteral { + public typealias IntegerLiteralType = Int32 + + public init(integerLiteral value: IntegerLiteralType) { + precondition(value >= 0 && value <= Int32.max, "\(value) is not a valid HTTP/2 stream ID value") + self.networkStreamID = value + } +} + + +// MARK:- Strideable conformance for HTTP2StreamID +extension HTTP2StreamID: Strideable { + public typealias Stride = Int + + public func advanced(by n: Stride) -> HTTP2StreamID { + return HTTP2StreamID(self.networkStreamID + Int32(n)) + } + + public func distance(to other: HTTP2StreamID) -> Stride { + return Int(other.networkStreamID - self.networkStreamID) + } +} + + +// MARK:- Helper initializers for integer conversion. +public extension Int { + /// Create an Int holding the integer value of this streamID. + init(_ http2StreamID: HTTP2StreamID) { + self = Int(http2StreamID.networkStreamID) + } +} + + +public extension Int32 { + /// Create an Int32 holding the integer value of this streamID. + init(_ http2StreamID: HTTP2StreamID) { + self = http2StreamID.networkStreamID + } +} + + +internal extension UInt32 { + /// Create a UInt32 holding the integer value of this streamID. + init(_ http2StreamID: HTTP2StreamID) { + self = UInt32(http2StreamID.networkStreamID) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift new file mode 100644 index 00000000..85bbc4ae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift @@ -0,0 +1,465 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A channel handler that creates a child channel for each HTTP/2 stream. +/// +/// In general in NIO applications it is helpful to consider each HTTP/2 stream as an +/// independent stream of HTTP/2 frames. This multiplexer achieves this by creating a +/// number of in-memory `HTTP2StreamChannel` objects, one for each stream. These operate +/// on `HTTP2Frame` objects as their base communication atom, as opposed to the regular +/// NIO `SelectableChannel` objects which use `ByteBuffer` and `IOData`. +public final class HTTP2StreamMultiplexer: ChannelInboundHandler, ChannelOutboundHandler { + public typealias InboundIn = HTTP2Frame + public typealias InboundOut = HTTP2Frame + public typealias OutboundIn = HTTP2Frame + public typealias OutboundOut = HTTP2Frame + + // Streams which have a stream ID. + private var streams: [HTTP2StreamID: MultiplexerAbstractChannel] = [:] + // Streams which don't yet have a stream ID assigned to them. + private var pendingStreams: [ObjectIdentifier: MultiplexerAbstractChannel] = [:] + private let inboundStreamStateInitializer: MultiplexerAbstractChannel.InboundStreamStateInitializer + private let channel: Channel + private var context: ChannelHandlerContext! + private var nextOutboundStreamID: HTTP2StreamID + private var connectionFlowControlManager: InboundWindowManager + private var flushState: FlushState = .notReading + private var didReadChannels: StreamChannelList = StreamChannelList() + private let streamChannelOutboundBytesHighWatermark: Int + private let streamChannelOutboundBytesLowWatermark: Int + private let targetWindowSize: Int + + public func handlerAdded(context: ChannelHandlerContext) { + // We now need to check that we're on the same event loop as the one we were originally given. + // If we weren't, this is a hard failure, as there is a thread-safety issue here. + self.channel.eventLoop.preconditionInEventLoop() + self.context = context + } + + public func handlerRemoved(context: ChannelHandlerContext) { + self.context = nil + self.didReadChannels.removeAll() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let frame = self.unwrapInboundIn(data) + let streamID = frame.streamID + + self.flushState.startReading() + + guard streamID != .rootStream else { + // For stream 0 we forward all frames on to the main channel. + context.fireChannelRead(data) + return + } + + if case .priority = frame.payload { + // Priority frames are special cases, and are always forwarded to the parent stream. + context.fireChannelRead(data) + return + } + + if let channel = self.streams[streamID] { + channel.receiveInboundFrame(frame) + if !channel.inList { + self.didReadChannels.append(channel) + } + } else if case .headers = frame.payload { + let channel = MultiplexerAbstractChannel( + allocator: self.channel.allocator, + parent: self.channel, + multiplexer: self, + streamID: streamID, + targetWindowSize: Int32(self.targetWindowSize), + outboundBytesHighWatermark: self.streamChannelOutboundBytesHighWatermark, + outboundBytesLowWatermark: self.streamChannelOutboundBytesLowWatermark, + inboundStreamStateInitializer: self.inboundStreamStateInitializer + ) + + self.streams[streamID] = channel + channel.configureInboundStream(initializer: self.inboundStreamStateInitializer) + channel.receiveInboundFrame(frame) + + if !channel.inList { + self.didReadChannels.append(channel) + } + } else { + // This frame is for a stream we know nothing about. We can't do much about it, so we + // are going to fire an error and drop the frame. + let error = NIOHTTP2Errors.noSuchStream(streamID: streamID) + context.fireErrorCaught(error) + } + } + + public func channelReadComplete(context: ChannelHandlerContext) { + // Call channelReadComplete on the children until this has been propagated enough. + while let channel = self.didReadChannels.removeFirst() { + channel.receiveParentChannelReadComplete() + } + + if case .flushPending = self.flushState { + self.flushState = .notReading + context.flush() + } else { + self.flushState = .notReading + } + + context.fireChannelReadComplete() + } + + public func flush(context: ChannelHandlerContext) { + switch self.flushState { + case .reading, .flushPending: + self.flushState = .flushPending + case .notReading: + context.flush() + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + /* for now just forward */ + context.write(data, promise: promise) + } + + public func channelActive(context: ChannelHandlerContext) { + // We just got channelActive. Any previously existing channels may be marked active. + self.activateChannels(self.streams.values, context: context) + self.activateChannels(self.pendingStreams.values, context: context) + + context.fireChannelActive() + } + + private func activateChannels(_ channels: Channels, context: ChannelHandlerContext) where Channels.Element == MultiplexerAbstractChannel { + for channel in channels { + // We double-check the channel activity here, because it's possible action taken during + // the activation of one of the child channels will cause the parent to close! + if context.channel.isActive { + channel.performActivation() + } + } + } + + public func channelInactive(context: ChannelHandlerContext) { + for channel in self.streams.values { + channel.receiveStreamClosed(nil) + } + for channel in self.pendingStreams.values { + channel.receiveStreamClosed(nil) + } + + context.fireChannelInactive() + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + switch event { + case let evt as StreamClosedEvent: + if let channel = self.streams[evt.streamID] { + channel.receiveStreamClosed(evt.reason) + } + case let evt as NIOHTTP2WindowUpdatedEvent where evt.streamID == .rootStream: + // This force-unwrap is safe: we always have a connection window. + self.newConnectionWindowSize(newSize: evt.inboundWindowSize!, context: context) + case let evt as NIOHTTP2WindowUpdatedEvent: + if let channel = self.streams[evt.streamID], let windowSize = evt.inboundWindowSize { + channel.receiveWindowUpdatedEvent(windowSize) + } + case let evt as NIOHTTP2BulkStreamWindowChangeEvent: + // Here we need to pull the channels out so we aren't holding the streams dict mutably. This is because it + // will trigger an overlapping access violation if we do. + let channels = self.streams.values + for channel in channels { + channel.initialWindowSizeChanged(delta: evt.delta) + } + case let evt as NIOHTTP2StreamCreatedEvent: + if let channel = self.streams[evt.streamID] { + channel.networkActivationReceived() + } + default: + break + } + + context.fireUserInboundEventTriggered(event) + } + + public func channelWritabilityChanged(context: ChannelHandlerContext) { + for channel in self.streams.values { + channel.parentChannelWritabilityChanged(newValue: context.channel.isWritable) + } + for channel in self.pendingStreams.values { + channel.parentChannelWritabilityChanged(newValue: context.channel.isWritable) + } + + context.fireChannelWritabilityChanged() + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + if let streamError = error as? NIOHTTP2Errors.StreamError, + let channel = self.streams[streamError.streamID] { + channel.receiveStreamError(streamError) + } + + context.fireErrorCaught(error) + } + + private func newConnectionWindowSize(newSize: Int, context: ChannelHandlerContext) { + guard let increment = self.connectionFlowControlManager.newWindowSize(newSize) else { + return + } + + // This is too much flushing, but for now it'll have to do. + let frame = HTTP2Frame(streamID: .rootStream, payload: .windowUpdate(windowSizeIncrement: increment)) + context.writeAndFlush(self.wrapOutboundOut(frame), promise: nil) + } + + /// Create a new `HTTP2StreamMultiplexer`. + /// + /// - parameters: + /// - mode: The mode of the HTTP/2 connection being used: server or client. + /// - channel: The Channel to which this `HTTP2StreamMultiplexer` belongs. + /// - targetWindowSize: The target inbound connection and stream window size. Defaults to 65535 bytes. + /// - inboundStreamStateInitializer: A block that will be invoked to configure each new child stream + /// channel that is created by the remote peer. For servers, these are channels created by + /// receiving a `HEADERS` frame from a client. For clients, these are channels created by + /// receiving a `PUSH_PROMISE` frame from a server. To initiate a new outbound channel, use + /// `createStreamChannel`. + @available(*, deprecated, renamed: "init(mode:channel:targetWindowSize:outboundBufferSizeHighWatermark:outboundBufferSizeLowWatermark:inboundStreamInitializer:)") + public convenience init(mode: NIOHTTP2Handler.ParserMode, channel: Channel, targetWindowSize: Int = 65535, inboundStreamStateInitializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)? = nil) { + // We default to an 8kB outbound buffer size: this is a good trade off for avoiding excessive buffering while ensuring that decent + // throughput can be maintained. We use 4kB as the low water mark. + self.init(mode: mode, + channel: channel, + targetWindowSize: targetWindowSize, + outboundBufferSizeHighWatermark: 8192, + outboundBufferSizeLowWatermark: 4096, + inboundStreamStateInitializer: .includesStreamID(inboundStreamStateInitializer)) + } + + /// Create a new `HTTP2StreamMultiplexer`. + /// + /// - parameters: + /// - mode: The mode of the HTTP/2 connection being used: server or client. + /// - channel: The Channel to which this `HTTP2StreamMultiplexer` belongs. + /// - targetWindowSize: The target inbound connection and stream window size. Defaults to 65535 bytes. + /// - outboundBufferSizeHighWatermark: The high watermark for the number of bytes of writes that are + /// allowed to be un-sent on any child stream. This is broadly analogous to a regular socket send buffer. + /// Defaults to 8196 bytes. + /// - outboundBufferSizeLowWatermark: The low watermark for the number of bytes of writes that are + /// allowed to be un-sent on any child stream. This is broadly analogous to a regular socket send buffer. + /// Defaults to 4092 bytes. + /// - inboundStreamInitializer: A block that will be invoked to configure each new child stream + /// channel that is created by the remote peer. For servers, these are channels created by + /// receiving a `HEADERS` frame from a client. For clients, these are channels created by + /// receiving a `PUSH_PROMISE` frame from a server. To initiate a new outbound channel, use + /// `createStreamChannel`. + public convenience init(mode: NIOHTTP2Handler.ParserMode, + channel: Channel, + targetWindowSize: Int = 65535, + outboundBufferSizeHighWatermark: Int = 8196, + outboundBufferSizeLowWatermark: Int = 4092, + inboundStreamInitializer: ((Channel) -> EventLoopFuture)?) { + self.init(mode: mode, + channel: channel, + targetWindowSize: targetWindowSize, + outboundBufferSizeHighWatermark: outboundBufferSizeHighWatermark, + outboundBufferSizeLowWatermark: outboundBufferSizeLowWatermark, + inboundStreamStateInitializer: .excludesStreamID(inboundStreamInitializer)) + } + + /// Create a new `HTTP2StreamMultiplexer`. + /// + /// - parameters: + /// - mode: The mode of the HTTP/2 connection being used: server or client. + /// - channel: The Channel to which this `HTTP2StreamMultiplexer` belongs. + /// - targetWindowSize: The target inbound connection and stream window size. Defaults to 65535 bytes. + /// - outboundBufferSizeHighWatermark: The high watermark for the number of bytes of writes that are + /// allowed to be un-sent on any child stream. This is broadly analogous to a regular socket send buffer. + /// - outboundBufferSizeLowWatermark: The low watermark for the number of bytes of writes that are + /// allowed to be un-sent on any child stream. This is broadly analogous to a regular socket send buffer. + /// - inboundStreamStateInitializer: A block that will be invoked to configure each new child stream + /// channel that is created by the remote peer. For servers, these are channels created by + /// receiving a `HEADERS` frame from a client. For clients, these are channels created by + /// receiving a `PUSH_PROMISE` frame from a server. To initiate a new outbound channel, use + /// `createStreamChannel`. + @available(*, deprecated, renamed: "init(mode:channel:targetWindowSize:outboundBufferSizeHighWatermark:outboundBufferSizeLowWatermark:inboundStreamInitializer:)") + public convenience init(mode: NIOHTTP2Handler.ParserMode, + channel: Channel, + targetWindowSize: Int = 65535, + outboundBufferSizeHighWatermark: Int, + outboundBufferSizeLowWatermark: Int, + inboundStreamStateInitializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)? = nil) { + self.init(mode: mode, + channel: channel, + targetWindowSize: targetWindowSize, + outboundBufferSizeHighWatermark: outboundBufferSizeHighWatermark, + outboundBufferSizeLowWatermark: outboundBufferSizeLowWatermark, + inboundStreamStateInitializer: .includesStreamID(inboundStreamStateInitializer)) + } + + private init(mode: NIOHTTP2Handler.ParserMode, + channel: Channel, + targetWindowSize: Int = 65535, + outboundBufferSizeHighWatermark: Int, + outboundBufferSizeLowWatermark: Int, + inboundStreamStateInitializer: MultiplexerAbstractChannel.InboundStreamStateInitializer) { + self.inboundStreamStateInitializer = inboundStreamStateInitializer + self.channel = channel + self.targetWindowSize = max(0, min(targetWindowSize, Int(Int32.max))) + self.connectionFlowControlManager = InboundWindowManager(targetSize: Int32(targetWindowSize)) + self.streamChannelOutboundBytesHighWatermark = outboundBufferSizeHighWatermark + self.streamChannelOutboundBytesLowWatermark = outboundBufferSizeLowWatermark + + switch mode { + case .client: + self.nextOutboundStreamID = 1 + case .server: + self.nextOutboundStreamID = 2 + } + } +} + + +extension HTTP2StreamMultiplexer { + /// The state of the multiplexer for flush coalescing. + /// + /// The stream multiplexer aims to perform limited flush coalescing on the read side by delaying flushes from the child and + /// parent channels until channelReadComplete is received. To do this we need to track what state we're in. + enum FlushState { + /// No channelReads have been fired since the last channelReadComplete, so we probably aren't reading. Let any + /// flushes through. + case notReading + + /// We've started reading, but don't have any pending flushes. + case reading + + /// We're in the read loop, and have received a flush. + case flushPending + + mutating func startReading() { + if case .notReading = self { + self = .reading + } + } + } +} + + +extension HTTP2StreamMultiplexer { + /// Create a new `Channel` for a new stream initiated by this peer. + /// + /// This method is intended for situations where the NIO application is initiating the stream. For clients, + /// this is for all request streams. For servers, this is for pushed streams. + /// + /// - note: + /// Resources for the stream will be freed after it has been closed. + /// + /// - parameters: + /// - promise: An `EventLoopPromise` that will be succeeded with the new activated channel, or + /// failed if an error occurs. + /// - streamStateInitializer: A callback that will be invoked to allow you to configure the + /// `ChannelPipeline` for the newly created channel. + public func createStreamChannel(promise: EventLoopPromise?, _ streamStateInitializer: @escaping (Channel) -> EventLoopFuture) { + self.channel.eventLoop.execute { + let channel = MultiplexerAbstractChannel( + allocator: self.channel.allocator, + parent: self.channel, + multiplexer: self, + streamID: nil, + targetWindowSize: Int32(self.targetWindowSize), + outboundBytesHighWatermark: self.streamChannelOutboundBytesHighWatermark, + outboundBytesLowWatermark: self.streamChannelOutboundBytesLowWatermark, + inboundStreamStateInitializer: .excludesStreamID(nil) + ) + self.pendingStreams[channel.channelID] = channel + channel.configure(initializer: streamStateInitializer, userPromise: promise) + } + } + + /// Create a new `Channel` for a new stream initiated by this peer. + /// + /// This method is intended for situations where the NIO application is initiating the stream. For clients, + /// this is for all request streams. For servers, this is for pushed streams. + /// + /// - note: + /// Resources for the stream will be freed after it has been closed. + /// + /// - parameters: + /// - promise: An `EventLoopPromise` that will be succeeded with the new activated channel, or + /// failed if an error occurs. + /// - streamStateInitializer: A callback that will be invoked to allow you to configure the + /// `ChannelPipeline` for the newly created channel. + @available(*, deprecated, message: "The signature of 'streamStateInitializer' has changed to '(Channel) -> EventLoopFuture'") + public func createStreamChannel(promise: EventLoopPromise?, _ streamStateInitializer: @escaping (Channel, HTTP2StreamID) -> EventLoopFuture) { + self.channel.eventLoop.execute { + let streamID = self.nextStreamID() + let channel = MultiplexerAbstractChannel( + allocator: self.channel.allocator, + parent: self.channel, + multiplexer: self, + streamID: streamID, + targetWindowSize: Int32(self.targetWindowSize), + outboundBytesHighWatermark: self.streamChannelOutboundBytesHighWatermark, + outboundBytesLowWatermark: self.streamChannelOutboundBytesLowWatermark, + inboundStreamStateInitializer: .includesStreamID(nil) + ) + self.streams[streamID] = channel + channel.configure(initializer: streamStateInitializer, userPromise: promise) + } + } + + private func nextStreamID() -> HTTP2StreamID { + let streamID = self.nextOutboundStreamID + self.nextOutboundStreamID = HTTP2StreamID(Int32(streamID) + 2) + return streamID + } +} + + +// MARK:- Child to parent calls +extension HTTP2StreamMultiplexer { + internal func childChannelClosed(streamID: HTTP2StreamID) { + self.streams.removeValue(forKey: streamID) + } + + internal func childChannelClosed(channelID: ObjectIdentifier) { + self.pendingStreams.removeValue(forKey: channelID) + } + + internal func childChannelWrite(_ frame: HTTP2Frame, promise: EventLoopPromise?) { + self.context.write(self.wrapOutboundOut(frame), promise: promise) + } + + internal func childChannelFlush() { + self.flush(context: self.context) + } + + /// Requests a `HTTP2StreamID` for the given `Channel`. + /// + /// - Precondition: The `channel` must not already have a `streamID`. + internal func requestStreamID(forChannel channel: Channel) -> HTTP2StreamID { + let channelID = ObjectIdentifier(channel) + + // This unwrap shouldn't fail: the multiplexer owns the stream and the stream only requests + // a streamID once. + guard let abstractChannel = self.pendingStreams.removeValue(forKey: channelID) else { + preconditionFailure("No pending streams have channelID \(channelID)") + } + assert(abstractChannel.channelID == channelID) + + let streamID = self.nextStreamID() + self.streams[streamID] = abstractChannel + return streamID + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ToHTTP1Codec.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ToHTTP1Codec.swift new file mode 100644 index 00000000..ae733efc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2ToHTTP1Codec.swift @@ -0,0 +1,714 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHTTP1 +import NIOHPACK + +// MARK: - Client + +fileprivate struct BaseClientCodec { + private let protocolString: String + private let normalizeHTTPHeaders: Bool + + private var headerStateMachine: HTTP2HeadersStateMachine = HTTP2HeadersStateMachine(mode: .client) + + private var outgoingHTTP1RequestHead: HTTPRequestHead? + + /// Initializes a `BaseClientCodec`. + /// + /// - parameters: + /// - httpProtocol: The protocol (usually `"http"` or `"https"` that is used). + /// - normalizeHTTPHeaders: Whether to automatically normalize the HTTP headers to be suitable for HTTP/2. + /// The normalization will for example lower-case all header names (as required by the + /// HTTP/2 spec) and remove headers that are unsuitable for HTTP/2 such as + /// headers related to HTTP/1's keep-alive behaviour. Unless you are sure that all your + /// headers conform to the HTTP/2 spec, you should leave this parameter set to `true`. + fileprivate init(httpProtocol: HTTP2FramePayloadToHTTP1ClientCodec.HTTPProtocol, normalizeHTTPHeaders: Bool) { + self.normalizeHTTPHeaders = normalizeHTTPHeaders + + switch httpProtocol { + case .http: + self.protocolString = "http" + case .https: + self.protocolString = "https" + } + } + + mutating func processInboundData(_ data: HTTP2Frame.FramePayload) throws -> (first: HTTPClientResponsePart?, second: HTTPClientResponsePart?) { + switch data { + case .headers(let headerContent): + switch try self.headerStateMachine.newHeaders(block: headerContent.headers) { + case .trailer: + return (first: .end(HTTPHeaders(regularHeadersFrom: headerContent.headers)), second: nil) + + case .informationalResponseHead: + return (first: .head(try HTTPResponseHead(http2HeaderBlock: headerContent.headers)), second: nil) + + case .finalResponseHead: + guard let outgoingHTTP1RequestHead = outgoingHTTP1RequestHead else { + preconditionFailure("Expected not to get a response without having sent a request") + } + self.outgoingHTTP1RequestHead = nil + let respHead = try HTTPResponseHead( + http2HeaderBlock: headerContent.headers, + requestHead: outgoingHTTP1RequestHead, + endStream: headerContent.endStream + ) + let first = HTTPClientResponsePart.head(respHead) + var second: HTTPClientResponsePart? = nil + if headerContent.endStream { + second = .end(nil) + } + return (first: first, second: second) + + case .requestHead: + preconditionFailure("A client can not receive request heads") + } + case .data(let content): + guard case .byteBuffer(let b) = content.data else { + preconditionFailure("Received DATA frame with non-bytebuffer IOData") + } + + var first = HTTPClientResponsePart.body(b) + var second: HTTPClientResponsePart? = nil + if content.endStream { + if b.readableBytes == 0 { + first = .end(nil) + } else { + second = .end(nil) + } + } + return (first: first, second: second) + case .alternativeService, .rstStream, .priority, .windowUpdate, .settings, .pushPromise, .ping, .goAway, .origin: + // These don't have an HTTP/1 equivalent, so let's drop them. + return (first: nil, second: nil) + } + } + + mutating func processOutboundData(_ data: HTTPClientRequestPart, allocator: ByteBufferAllocator) throws -> HTTP2Frame.FramePayload { + switch data { + case .head(let head): + precondition(self.outgoingHTTP1RequestHead == nil, "Only a single HTTP request allowed per HTTP2 stream") + let h1Headers = try HTTPHeaders(requestHead: head, protocolString: self.protocolString) + self.outgoingHTTP1RequestHead = head + let headerContent = HTTP2Frame.FramePayload.Headers(headers: HPACKHeaders(httpHeaders: h1Headers, + normalizeHTTPHeaders: self.normalizeHTTPHeaders)) + return .headers(headerContent) + case .body(let body): + return .data(HTTP2Frame.FramePayload.Data(data: body)) + case .end(let trailers): + if let trailers = trailers { + return .headers(.init(headers: HPACKHeaders(httpHeaders: trailers, + normalizeHTTPHeaders: self.normalizeHTTPHeaders), + endStream: true)) + } else { + return .data(.init(data: .byteBuffer(allocator.buffer(capacity: 0)), endStream: true)) + } + } + } +} + +/// A simple channel handler that translates HTTP/2 concepts into HTTP/1 data types, +/// and vice versa, for use on the client side. +/// +/// This channel handler should be used alongside the `HTTP2StreamMultiplexer` to +/// help provide a HTTP/1.1-like abstraction on top of a HTTP/2 multiplexed +/// connection. +@available(*, deprecated, renamed: "HTTP2FramePayloadToHTTP1ClientCodec") +public final class HTTP2ToHTTP1ClientCodec: ChannelInboundHandler, ChannelOutboundHandler { + public typealias InboundIn = HTTP2Frame + public typealias InboundOut = HTTPClientResponsePart + + public typealias OutboundIn = HTTPClientRequestPart + public typealias OutboundOut = HTTP2Frame + + /// The HTTP protocol scheme being used on this connection. + public typealias HTTPProtocol = HTTP2FramePayloadToHTTP1ClientCodec.HTTPProtocol + + private let streamID: HTTP2StreamID + private var baseCodec: BaseClientCodec + + /// Initializes a `HTTP2ToHTTP1ClientCodec` for the given `HTTP2StreamID`. + /// + /// - parameters: + /// - streamID: The HTTP/2 stream ID this `HTTP2ToHTTP1ClientCodec` will be used for + /// - httpProtocol: The protocol (usually `"http"` or `"https"` that is used). + /// - normalizeHTTPHeaders: Whether to automatically normalize the HTTP headers to be suitable for HTTP/2. + /// The normalization will for example lower-case all header names (as required by the + /// HTTP/2 spec) and remove headers that are unsuitable for HTTP/2 such as + /// headers related to HTTP/1's keep-alive behaviour. Unless you are sure that all your + /// headers conform to the HTTP/2 spec, you should leave this parameter set to `true`. + public init(streamID: HTTP2StreamID, httpProtocol: HTTPProtocol, normalizeHTTPHeaders: Bool) { + self.streamID = streamID + self.baseCodec = BaseClientCodec(httpProtocol: httpProtocol, normalizeHTTPHeaders: normalizeHTTPHeaders) + } + + /// Initializes a `HTTP2ToHTTP1ClientCodec` for the given `HTTP2StreamID`. + /// + /// - parameters: + /// - streamID: The HTTP/2 stream ID this `HTTP2ToHTTP1ClientCodec` will be used for + /// - httpProtocol: The protocol (usually `"http"` or `"https"` that is used). + public convenience init(streamID: HTTP2StreamID, httpProtocol: HTTPProtocol) { + self.init(streamID: streamID, httpProtocol: httpProtocol, normalizeHTTPHeaders: true) + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let frame = self.unwrapInboundIn(data) + do { + let (first, second) = try self.baseCodec.processInboundData(frame.payload) + if let first = first { + context.fireChannelRead(self.wrapInboundOut(first)) + } + if let second = second { + context.fireChannelRead(self.wrapInboundOut(second)) + } + } catch { + context.fireErrorCaught(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let responsePart = self.unwrapOutboundIn(data) + + do { + let transformedPayload = try self.baseCodec.processOutboundData(responsePart, allocator: context.channel.allocator) + let part = HTTP2Frame(streamID: self.streamID, payload: transformedPayload) + context.write(self.wrapOutboundOut(part), promise: promise) + } catch { + promise?.fail(error) + context.fireErrorCaught(error) + } + } +} + +/// A simple channel handler that translates HTTP/2 concepts into HTTP/1 data types, +/// and vice versa, for use on the client side. +/// +/// This channel handler should be used alongside the `HTTP2StreamMultiplexer` to +/// help provide a HTTP/1.1-like abstraction on top of a HTTP/2 multiplexed +/// connection. +/// +/// This handler uses `HTTP2Frame.FramePayload` as its HTTP/2 currency type. +public final class HTTP2FramePayloadToHTTP1ClientCodec: ChannelInboundHandler, ChannelOutboundHandler { + public typealias InboundIn = HTTP2Frame.FramePayload + public typealias InboundOut = HTTPClientResponsePart + + public typealias OutboundIn = HTTPClientRequestPart + public typealias OutboundOut = HTTP2Frame.FramePayload + + private var baseCodec: BaseClientCodec + + /// The HTTP protocol scheme being used on this connection. + public enum HTTPProtocol { + case https + case http + } + + /// Initializes a `HTTP2PayloadToHTTP1ClientCodec`. + /// + /// - parameters: + /// - httpProtocol: The protocol (usually `"http"` or `"https"` that is used). + /// - normalizeHTTPHeaders: Whether to automatically normalize the HTTP headers to be suitable for HTTP/2. + /// The normalization will for example lower-case all header names (as required by the + /// HTTP/2 spec) and remove headers that are unsuitable for HTTP/2 such as + /// headers related to HTTP/1's keep-alive behaviour. Unless you are sure that all your + /// headers conform to the HTTP/2 spec, you should leave this parameter set to `true`. + public init(httpProtocol: HTTPProtocol, normalizeHTTPHeaders: Bool = true) { + self.baseCodec = BaseClientCodec(httpProtocol: httpProtocol, normalizeHTTPHeaders: normalizeHTTPHeaders) + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let payload = self.unwrapInboundIn(data) + do { + let (first, second) = try self.baseCodec.processInboundData(payload) + if let first = first { + context.fireChannelRead(self.wrapInboundOut(first)) + } + if let second = second { + context.fireChannelRead(self.wrapInboundOut(second)) + } + } catch { + context.fireErrorCaught(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let requestPart = self.unwrapOutboundIn(data) + + do { + let transformedPayload = try self.baseCodec.processOutboundData(requestPart, allocator: context.channel.allocator) + context.write(self.wrapOutboundOut(transformedPayload), promise: promise) + } catch { + promise?.fail(error) + context.fireErrorCaught(error) + } + } +} + +// MARK: - Server + +fileprivate struct BaseServerCodec { + private let normalizeHTTPHeaders: Bool + private var headerStateMachine: HTTP2HeadersStateMachine = HTTP2HeadersStateMachine(mode: .server) + + init(normalizeHTTPHeaders: Bool) { + self.normalizeHTTPHeaders = normalizeHTTPHeaders + } + + mutating func processInboundData(_ data: HTTP2Frame.FramePayload) throws -> (first: HTTPServerRequestPart?, second: HTTPServerRequestPart?) { + switch data { + case .headers(let headerContent): + if case .trailer = try self.headerStateMachine.newHeaders(block: headerContent.headers) { + return (first: .end(HTTPHeaders(regularHeadersFrom: headerContent.headers)), second: nil) + } else { + let reqHead = try HTTPRequestHead(http2HeaderBlock: headerContent.headers, isEndStream: headerContent.endStream) + + let first = HTTPServerRequestPart.head(reqHead) + var second: HTTPServerRequestPart? = nil + if headerContent.endStream { + second = .end(nil) + } + return (first: first, second: second) + } + case .data(let dataContent): + guard case .byteBuffer(let b) = dataContent.data else { + preconditionFailure("Received non-byteBuffer IOData from network") + } + var first = HTTPServerRequestPart.body(b) + var second: HTTPServerRequestPart? = nil + if dataContent.endStream { + if b.readableBytes == 0 { + first = .end(nil) + } else { + second = .end(nil) + } + } + return (first: first, second: second) + default: + // Any other frame type is ignored. + return (first: nil, second: nil) + } + } + + mutating func processOutboundData(_ data: HTTPServerResponsePart, allocator: ByteBufferAllocator) -> HTTP2Frame.FramePayload { + switch data { + case .head(let head): + let h1 = HTTPHeaders(responseHead: head) + let payload = HTTP2Frame.FramePayload.Headers(headers: HPACKHeaders(httpHeaders: h1, + normalizeHTTPHeaders: self.normalizeHTTPHeaders)) + return .headers(payload) + case .body(let body): + let payload = HTTP2Frame.FramePayload.Data(data: body) + return .data(payload) + case .end(let trailers): + if let trailers = trailers { + return .headers(.init(headers: HPACKHeaders(httpHeaders: trailers, + normalizeHTTPHeaders: self.normalizeHTTPHeaders), + endStream: true)) + } else { + return .data(.init(data: .byteBuffer(allocator.buffer(capacity: 0)), endStream: true)) + } + } + } +} + + +/// A simple channel handler that translates HTTP/2 concepts into HTTP/1 data types, +/// and vice versa, for use on the server side. +/// +/// This channel handler should be used alongside the `HTTP2StreamMultiplexer` to +/// help provide a HTTP/1.1-like abstraction on top of a HTTP/2 multiplexed +/// connection. +@available(*, deprecated, renamed: "HTTP2FramePayloadToHTTP1ServerCodec") +public final class HTTP2ToHTTP1ServerCodec: ChannelInboundHandler, ChannelOutboundHandler { + public typealias InboundIn = HTTP2Frame + public typealias InboundOut = HTTPServerRequestPart + + public typealias OutboundIn = HTTPServerResponsePart + public typealias OutboundOut = HTTP2Frame + + private let streamID: HTTP2StreamID + private var baseCodec: BaseServerCodec + + /// Initializes a `HTTP2ToHTTP1ServerCodec` for the given `HTTP2StreamID`. + /// + /// - parameters: + /// - streamID: The HTTP/2 stream ID this `HTTP2ToHTTP1ServerCodec` will be used for + /// - normalizeHTTPHeaders: Whether to automatically normalize the HTTP headers to be suitable for HTTP/2. + /// The normalization will for example lower-case all header names (as required by the + /// HTTP/2 spec) and remove headers that are unsuitable for HTTP/2 such as + /// headers related to HTTP/1's keep-alive behaviour. Unless you are sure that all your + /// headers conform to the HTTP/2 spec, you should leave this parameter set to `true`. + public init(streamID: HTTP2StreamID, normalizeHTTPHeaders: Bool) { + self.streamID = streamID + self.baseCodec = BaseServerCodec(normalizeHTTPHeaders: normalizeHTTPHeaders) + } + + public convenience init(streamID: HTTP2StreamID) { + self.init(streamID: streamID, normalizeHTTPHeaders: true) + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let frame = self.unwrapInboundIn(data) + + do { + let (first, second) = try self.baseCodec.processInboundData(frame.payload) + if let first = first { + context.fireChannelRead(self.wrapInboundOut(first)) + } + if let second = second { + context.fireChannelRead(self.wrapInboundOut(second)) + } + } catch { + context.fireErrorCaught(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let responsePart = self.unwrapOutboundIn(data) + let transformedPayload = self.baseCodec.processOutboundData(responsePart, allocator: context.channel.allocator) + let part = HTTP2Frame(streamID: self.streamID, payload: transformedPayload) + context.write(self.wrapOutboundOut(part), promise: promise) + } +} + +/// A simple channel handler that translates HTTP/2 concepts into HTTP/1 data types, +/// and vice versa, for use on the server side. +/// +/// This channel handler should be used alongside the `HTTP2StreamMultiplexer` to +/// help provide a HTTP/1.1-like abstraction on top of a HTTP/2 multiplexed +/// connection. +/// +/// This handler uses `HTTP2Frame.FramePayload` as its HTTP/2 currency type. +public final class HTTP2FramePayloadToHTTP1ServerCodec: ChannelInboundHandler, ChannelOutboundHandler { + public typealias InboundIn = HTTP2Frame.FramePayload + public typealias InboundOut = HTTPServerRequestPart + + public typealias OutboundIn = HTTPServerResponsePart + public typealias OutboundOut = HTTP2Frame.FramePayload + + private var baseCodec: BaseServerCodec + + /// Initializes a `HTTP2PayloadToHTTP1ServerCodec`. + /// + /// - parameters: + /// - normalizeHTTPHeaders: Whether to automatically normalize the HTTP headers to be suitable for HTTP/2. + /// The normalization will for example lower-case all header names (as required by the + /// HTTP/2 spec) and remove headers that are unsuitable for HTTP/2 such as + /// headers related to HTTP/1's keep-alive behaviour. Unless you are sure that all your + /// headers conform to the HTTP/2 spec, you should leave this parameter set to `true`. + public init(normalizeHTTPHeaders: Bool = true) { + self.baseCodec = BaseServerCodec(normalizeHTTPHeaders: normalizeHTTPHeaders) + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let payload = self.unwrapInboundIn(data) + + do { + let (first, second) = try self.baseCodec.processInboundData(payload) + if let first = first { + context.fireChannelRead(self.wrapInboundOut(first)) + } + if let second = second { + context.fireChannelRead(self.wrapInboundOut(second)) + } + } catch { + context.fireErrorCaught(error) + } + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let responsePart = self.unwrapOutboundIn(data) + let transformedPayload = self.baseCodec.processOutboundData(responsePart, allocator: context.channel.allocator) + context.write(self.wrapOutboundOut(transformedPayload), promise: promise) + } +} + +private extension HTTPMethod { + /// Create a `HTTPMethod` from the string representation of that method. + init(methodString: String) { + switch methodString { + case "GET": + self = .GET + case "PUT": + self = .PUT + case "ACL": + self = .ACL + case "HEAD": + self = .HEAD + case "POST": + self = .POST + case "COPY": + self = .COPY + case "LOCK": + self = .LOCK + case "MOVE": + self = .MOVE + case "BIND": + self = .BIND + case "LINK": + self = .LINK + case "PATCH": + self = .PATCH + case "TRACE": + self = .TRACE + case "MKCOL": + self = .MKCOL + case "MERGE": + self = .MERGE + case "PURGE": + self = .PURGE + case "NOTIFY": + self = .NOTIFY + case "SEARCH": + self = .SEARCH + case "UNLOCK": + self = .UNLOCK + case "REBIND": + self = .REBIND + case "UNBIND": + self = .UNBIND + case "REPORT": + self = .REPORT + case "DELETE": + self = .DELETE + case "UNLINK": + self = .UNLINK + case "CONNECT": + self = .CONNECT + case "MSEARCH": + self = .MSEARCH + case "OPTIONS": + self = .OPTIONS + case "PROPFIND": + self = .PROPFIND + case "CHECKOUT": + self = .CHECKOUT + case "PROPPATCH": + self = .PROPPATCH + case "SUBSCRIBE": + self = .SUBSCRIBE + case "MKCALENDAR": + self = .MKCALENDAR + case "MKACTIVITY": + self = .MKACTIVITY + case "UNSUBSCRIBE": + self = .UNSUBSCRIBE + default: + self = .RAW(value: methodString) + } + } +} + +// MARK:- Methods for creating `HTTPRequestHead`/`HTTPResponseHead` objects from +// header blocks generated by the HTTP/2 layer. +internal extension HTTPRequestHead { + /// Create a `HTTPRequestHead` from the header block. + init(http2HeaderBlock headers: HPACKHeaders, isEndStream: Bool) throws { + // A request head should have only up to four psuedo-headers. + let method = HTTPMethod(methodString: try headers.peekPseudoHeader(name: ":method")) + let version = HTTPVersion(major: 2, minor: 0) + let uri = try headers.peekPseudoHeader(name: ":path") + + // Here we peek :scheme just to confirm it's there: we want the throw effect, but we don't care about the value. + _ = try headers.peekPseudoHeader(name: ":scheme") + + let authority = try headers.peekPseudoHeader(name: ":authority") + + // We do a manual implementation of HTTPHeaders(regularHeadersFrom:) here because we may + // need to add an extra Host: and Transfer-Encoding: header here, and that can cause copies + // if we're unlucky. We need headers.count - 2 spaces: we remove :method, :path, :scheme, + // and :authority, but we may add in Host and Transfer-Encoding + var rawHeaders: [(String, String)] = [] + rawHeaders.reserveCapacity(headers.count - 2) + if !headers.contains(name: "host") { + rawHeaders.append(("host", authority)) + } + switch method { + case .GET, .HEAD, .DELETE, .CONNECT, .TRACE: + // A user agent SHOULD NOT send a Content-Length header field when the request + // message does not contain a payload body and the method semantics do not + // anticipate such a body. + // + // There is an interesting case here, in which the header frame does not have the + // endStream flag set, because the HTTP1 to HTTP2 translation on the client side, emits + // header frame and endStream in two frames. What do we want to do in those cases? + // + // The payload has no defined semantics as defined in RFC7231, but we are not sure, if + // we will receive a payload eventually. In most cases, there won't be a payload and + // therefore we should not add transfer-encoding headers. If there is a content-length + // header, we should keep it. + break + + default: + if !headers.contains(name: "content-length") { + if isEndStream { + rawHeaders.append(("content-length", "0")) + } else { + rawHeaders.append(("transfer-encoding", "chunked")) + } + } + } + rawHeaders.appendRegularHeaders(from: headers) + + self.init(version: version, method: method, uri: uri, headers: HTTPHeaders(rawHeaders)) + } +} + + +internal extension HTTPResponseHead { + /// Create a `HTTPResponseHead` from the header block. Use this for informational responses. + init(http2HeaderBlock headers: HPACKHeaders) throws { + // A response head should have only one psuedo-header. We strip it off. + let statusHeader = try headers.peekPseudoHeader(name: ":status") + guard let integerStatus = Int(statusHeader, radix: 10) else { + throw NIOHTTP2Errors.invalidStatusValue(statusHeader) + } + let status = HTTPResponseStatus(statusCode: integerStatus) + self.init(version: .init(major: 2, minor: 0), status: status, headers: HTTPHeaders(regularHeadersFrom: headers)) + } + + /// Create a `HTTPResponseHead` from the header block. Use this for non-informational responses. + init(http2HeaderBlock headers: HPACKHeaders, requestHead: HTTPRequestHead, endStream: Bool) throws { + try self.init(http2HeaderBlock: headers) + + // NOTE: We don't need to create the header array here ourselves. The HTTP/1 response + // headers, will not contain a :status field, but may contain a "Transfer-Encoding" + // field. For this reason the default allocation works great for us. + if self.shouldAddContentLengthOrTransferEncodingHeaderToResponse(hpackHeaders: headers, requestHead: requestHead) { + if endStream { + self.headers.add(name: "content-length", value: "0") + } else { + self.headers.add(name: "transfer-encoding", value: "chunked") + } + } + } + + private func shouldAddContentLengthOrTransferEncodingHeaderToResponse( + hpackHeaders: HPACKHeaders, requestHead: HTTPRequestHead + ) -> Bool { + let statusCode = self.status.code + return !(100..<200).contains(statusCode) + && statusCode != 204 + && statusCode != 304 + && requestHead.method != .HEAD + && requestHead.method != .CONNECT + && !hpackHeaders.contains(name: "content-length") // compare on h2 headers - for speed + } +} + + +extension HPACKHeaders { + /// Grabs a pseudo-header from a header block. Does not remove it. + /// + /// - parameter: + /// - name: The header name to find. + /// - returns: The value for this pseudo-header. + /// - throws: If there is no such header, or multiple. + internal func peekPseudoHeader(name: String) throws -> String { + // This could be done with .lazy.filter.map but that generates way more ARC traffic. + var headerValue: String? = nil + + for (fieldName, fieldValue, _) in self { + if name == fieldName { + guard headerValue == nil else { + throw NIOHTTP2Errors.duplicatePseudoHeader(name) + } + headerValue = fieldValue + } + } + + if let headerValue = headerValue { + return headerValue + } else { + throw NIOHTTP2Errors.missingPseudoHeader(name) + } + } +} + + +extension HTTPHeaders { + fileprivate init(requestHead: HTTPRequestHead, protocolString: String) throws { + // To avoid too much allocation we create an array first, and then initialize the HTTPHeaders from it. + // We want to ensure this array is large enough so we only have to allocate once. We will need an + // array that is the same as the number of headers in requestHead.headers + 3: we're adding :path, + // :method, and :scheme, and transforming Host to :authority. + var newHeaders: [(String, String)] = [] + newHeaders.reserveCapacity(requestHead.headers.count + 3) + + // TODO(cory): This is potentially wrong if the URI contains more than just a path. + newHeaders.append((":path", requestHead.uri)) + newHeaders.append((":method", requestHead.method.rawValue)) + newHeaders.append((":scheme", protocolString)) + + // We store a place for the :authority header, even though we don't know what it is. We'll find it later and + // change it when we do. This avoids us needing to potentially search this header block twice. + var authorityHeader: String? = nil + newHeaders.append((":authority", "")) + + // Now fill in the others, except for any Host header we might find, which will become an :authority header. + for header in requestHead.headers { + if header.name.lowercased() == "host" { + if authorityHeader != nil { + throw NIOHTTP2Errors.duplicateHostHeader() + } + + authorityHeader = header.value + } else { + newHeaders.append((header.name, header.value)) + } + } + + // Now we go back and fill in the authority header. + guard let actualAuthorityHeader = authorityHeader else { + throw NIOHTTP2Errors.missingHostHeader() + } + newHeaders[3].1 = actualAuthorityHeader + + self.init(newHeaders) + } + + fileprivate init(responseHead: HTTPResponseHead) { + // To avoid too much allocation we create an array first, and then initialize the HTTPHeaders from it. + // This array will need to be the size of the response headers + 1, for the :status field. + var newHeaders: [(String, String)] = [] + newHeaders.reserveCapacity(responseHead.headers.count + 1) + newHeaders.append((":status", String(responseHead.status.code))) + responseHead.headers.forEach { newHeaders.append(($0.name, $0.value)) } + + self.init(newHeaders) + } + + internal init(regularHeadersFrom oldHeaders: HPACKHeaders) { + // We need to create an array to write the header fields into. + var newHeaders: [(String, String)] = [] + newHeaders.reserveCapacity(oldHeaders.count) + newHeaders.appendRegularHeaders(from: oldHeaders) + self.init(newHeaders) + } +} + + +extension Array where Element == (String, String) { + mutating func appendRegularHeaders(from headers: HPACKHeaders) { + for (name, value, _) in headers { + if name.first == ":" { + continue + } + + self.append((name, value)) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2UserEvents.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2UserEvents.swift new file mode 100644 index 00000000..3d28451d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/HTTP2UserEvents.swift @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A `StreamClosedEvent` is fired whenever a stream is closed. +/// +/// This event is fired whether the stream is closed normally, or via RST_STREAM, +/// or via GOAWAY. Normal closure is indicated by having `reason` be `nil`. In the +/// case of closure by GOAWAY the `reason` is always `.refusedStream`, indicating that +/// the remote peer has not processed this stream. In the case of RST_STREAM, +/// the `reason` contains the error code sent by the peer in the RST_STREAM frame. +public struct StreamClosedEvent: NIOSendable { + /// The stream ID of the stream that is closed. + public let streamID: HTTP2StreamID + + /// The reason for the stream closure. `nil` if the stream was closed without + /// error. Otherwise, the error code indicating why the stream was closed. + public let reason: HTTP2ErrorCode? + + public init(streamID: HTTP2StreamID, reason: HTTP2ErrorCode?) { + self.streamID = streamID + self.reason = reason + } +} + +extension StreamClosedEvent: Hashable { } + + +/// A `NIOHTTP2WindowUpdatedEvent` is fired whenever a flow control window is changed. +/// This includes changes on the connection flow control window, which is signalled by +/// this event having `streamID` set to `.rootStream`. +public struct NIOHTTP2WindowUpdatedEvent { + /// The stream ID of the window that has been changed. May be .rootStream, in which + /// case the connection window has changed. + public let streamID: HTTP2StreamID + + /// The new inbound window size for this stream, if any. May be nil if this stream is half-closed. + public var inboundWindowSize: Int? { + get { + return self._inboundWindowSize.map { Int($0) } + } + set { + self._inboundWindowSize = newValue.map { Int32($0) } + } + } + + /// The new outbound window size for this stream, if any. May be nil if this stream is half-closed. + public var outboundWindowSize: Int? { + get { + return self._outboundWindowSize.map { Int($0) } + } + set { + self._outboundWindowSize = newValue.map { Int32($0) } + } + } + + private var _inboundWindowSize: Int32? + + private var _outboundWindowSize: Int32? + + public init(streamID: HTTP2StreamID, inboundWindowSize: Int?, outboundWindowSize: Int?) { + // We use Int here instead of Int32. Nonetheless, the value must fit in the Int32 range. + precondition(inboundWindowSize == nil || inboundWindowSize! <= Int(HTTP2FlowControlWindow.maxSize)) + precondition(outboundWindowSize == nil || outboundWindowSize! <= Int(HTTP2FlowControlWindow.maxSize)) + precondition(inboundWindowSize == nil || inboundWindowSize! >= Int(Int32.min)) + precondition(outboundWindowSize == nil || outboundWindowSize! >= Int(Int32.min)) + + self.streamID = streamID + self._inboundWindowSize = inboundWindowSize.map { Int32($0) } + self._outboundWindowSize = outboundWindowSize.map { Int32($0) } + } +} + +extension NIOHTTP2WindowUpdatedEvent: Hashable { } + + +/// A `NIOHTTP2StreamCreatedEvent` is fired whenever a HTTP/2 stream is created. +public struct NIOHTTP2StreamCreatedEvent { + public let streamID: HTTP2StreamID + + /// The initial local stream window size. May be nil if this stream may never have data sent on it. + public let localInitialWindowSize: UInt32? + + /// The initial remote stream window size. May be nil if this stream may never have data received on it. + public let remoteInitialWidowSize: UInt32? + + public init(streamID: HTTP2StreamID, localInitialWindowSize: UInt32?, remoteInitialWindowSize: UInt32?) { + self.streamID = streamID + self.localInitialWindowSize = localInitialWindowSize + self.remoteInitialWidowSize = remoteInitialWindowSize + } +} + +extension NIOHTTP2StreamCreatedEvent: Hashable { } + +/// A `NIOHTTP2BulkStreamWindowChangeEvent` is fired whenever all of the remote flow control windows for a given stream have been changed. +/// +/// This occurs when an ACK to a SETTINGS frame is received that changes the value of SETTINGS_INITIAL_WINDOW_SIZE. This is only fired +/// when the local peer has changed its settings. +public struct NIOHTTP2BulkStreamWindowChangeEvent { + /// The change in the remote stream window sizes. + public let delta: Int + + public init(delta: Int) { + self.delta = delta + } +} + +extension NIOHTTP2BulkStreamWindowChangeEvent: Hashable { } diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundEventBuffer.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundEventBuffer.swift new file mode 100644 index 00000000..420125c6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundEventBuffer.swift @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// A buffer of pending user events. +/// +/// This buffer is used to ensure that we deliver user events and frames correctly from +/// the `NIOHTTP2Handler` in the face of reentrancy. Specifically, it is possible that +/// a re-entrant call will lead to `NIOHTTP2Handler.channelRead` being on the stack twice. +/// In this case, we do not want to deliver frames or user events out of order. Rather than +/// force the stack to unwind, we have this temporary storage location where all user events go. +/// This will be drained both before and after any frame read operation, to ensure that we +/// have always delivered all pending user events before we deliver a frame. +/// Deliberately not threadsafe or `Sendable`. +class InboundEventBuffer { + fileprivate var buffer: CircularBuffer = CircularBuffer(initialCapacity: 8) + + func pendingUserEvent(_ event: Any) { + self.buffer.append(event) + } +} + + +// MARK:- Sequence conformance +extension InboundEventBuffer: Sequence { + typealias Element = Any + + func makeIterator() -> InboundEventBufferIterator { + return InboundEventBufferIterator(self) + } + + struct InboundEventBufferIterator: IteratorProtocol { + typealias Element = InboundEventBuffer.Element + + let inboundBuffer: InboundEventBuffer + + fileprivate init(_ buffer: InboundEventBuffer) { + self.inboundBuffer = buffer + } + + func next() -> Element? { + if self.inboundBuffer.buffer.count > 0 { + return self.inboundBuffer.buffer.removeFirst() + } else { + return nil + } + } + } +} + + +// MARK:- CustomStringConvertible conformance +extension InboundEventBuffer: CustomStringConvertible { + var description: String { + return "InboundEventBuffer { \(self.buffer) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundWindowManager.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundWindowManager.swift new file mode 100644 index 00000000..42989891 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/InboundWindowManager.swift @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A simple structure that manages an inbound flow control window. +/// +/// For now, this just aims to emit window update frames whenever the flow control window drops below a certain size. It's very naive. +/// We'll worry about the rest of it later. +struct InboundWindowManager { + private var targetWindowSize: Int32 + + /// The last window size we were told about. Used when we get changes to SETTINGS_INITIAL_WINDOW_SIZE. + private var lastWindowSize: Int? + + /// The number of bytes of buffered frames. + private var bufferedBytes: Int = 0 + + /// Whether the inbound window is closed. If this is true then no window size changes will be emitted. + var closed = false + + init(targetSize: Int32) { + assert(targetSize <= HTTP2FlowControlWindow.maxSize) + assert(targetSize >= 0) + + self.targetWindowSize = targetSize + } + + mutating func newWindowSize(_ newSize: Int) -> Int? { + self.lastWindowSize = newSize + + // The new size assumes all frames have been delivered to the stream. This isn't necessarily + // the case so we need to take the size of any buffered frames into account here. + return self.calculateWindowIncrement(windowSize: newSize + self.bufferedBytes) + } + + mutating func initialWindowSizeChanged(delta: Int) -> Int? { + self.targetWindowSize += Int32(delta) + + if let lastWindowSize = self.lastWindowSize { + // The delta applies to the current window size as well. + return self.newWindowSize(lastWindowSize + delta) + } else { + return nil + } + } + + mutating func bufferedFrameReceived(size: Int) { + self.bufferedBytes += size + } + + mutating func bufferedFrameEmitted(size: Int) -> Int? { + // Consume the bytes we just emitted. + self.bufferedBytes -= size + assert(self.bufferedBytes >= 0) + + guard let lastWindowSize = self.lastWindowSize else { + return nil + } + + return self.calculateWindowIncrement(windowSize: lastWindowSize + self.bufferedBytes) + } + + private func calculateWindowIncrement(windowSize: Int) -> Int? { + // No point calculating an increment if we're closed. + if self.closed { + return nil + } + + // The simplest case is where newSize >= targetWindowSize. In that case, we do nothing. + // + // The next simplest case is where 0 <= newSize < targetWindowSize. In that case, + // if targetWindowSize >= newSize * 2, we update to full size. + // + // The other case is where newSize is negative. This can happen. In those cases, we want to + // increment by Int32.max or the total distance between newSize and targetWindowSize, + // whichever is *smaller*. This ensures the result fits into Int32. + if windowSize >= self.targetWindowSize { + return nil + } else if windowSize >= 0 { + let increment = self.targetWindowSize - Int32(windowSize) + if increment >= windowSize { + return Int(increment) + } else { + return nil + } + } else { + // All math in here happens on 64-bit ints to avoid overflow issues. + let windowSize = Int64(windowSize) + let targetWindowSize = Int64(self.targetWindowSize) + + let increment = min(abs(windowSize) + targetWindowSize, Int64(Int32.max)) + return Int(increment) + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/MultiplexerAbstractChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/MultiplexerAbstractChannel.swift new file mode 100644 index 00000000..d6f76b9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/MultiplexerAbstractChannel.swift @@ -0,0 +1,156 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// This structure defines an abstraction over `HTTP2StreamChannel` that is used +/// by the `HTTP2StreamMultiplexer`. +/// +/// The goal of this type is to help reduce the coupling between +/// `HTTP2StreamMultiplexer` and `HTTP2Channel`. By providing this abstraction layer, +/// it makes it easier for us to change the potential backing implementation without +/// having to modify `HTTP2StreamMultiplexer`. +/// +/// Note that while this is a `struct`, this `struct` has _reference semantics_. +/// The implementation of `Equatable` & `Hashable` on this type reinforces that requirement. +struct MultiplexerAbstractChannel { + private var baseChannel: HTTP2StreamChannel + + init(allocator: ByteBufferAllocator, + parent: Channel, + multiplexer: HTTP2StreamMultiplexer, + streamID: HTTP2StreamID?, + targetWindowSize: Int32, + outboundBytesHighWatermark: Int, + outboundBytesLowWatermark: Int, + inboundStreamStateInitializer: InboundStreamStateInitializer) { + switch inboundStreamStateInitializer { + case .includesStreamID: + assert(streamID != nil) + self.baseChannel = .init(allocator: allocator, + parent: parent, + multiplexer: multiplexer, + streamID: streamID, + targetWindowSize: targetWindowSize, + outboundBytesHighWatermark: outboundBytesHighWatermark, + outboundBytesLowWatermark: outboundBytesLowWatermark, + streamDataType: .frame) + + case .excludesStreamID: + self.baseChannel = .init(allocator: allocator, + parent: parent, + multiplexer: multiplexer, + streamID: streamID, + targetWindowSize: targetWindowSize, + outboundBytesHighWatermark: outboundBytesHighWatermark, + outboundBytesLowWatermark: outboundBytesLowWatermark, + streamDataType: .framePayload) + } + } +} + +extension MultiplexerAbstractChannel { + enum InboundStreamStateInitializer { + case includesStreamID(((Channel, HTTP2StreamID) -> EventLoopFuture)?) + case excludesStreamID(((Channel) -> EventLoopFuture)?) + } +} + +// MARK: API for HTTP2StreamMultiplexer +extension MultiplexerAbstractChannel { + var streamID: HTTP2StreamID? { + return self.baseChannel.streamID + } + + var channelID: ObjectIdentifier { + return ObjectIdentifier(self.baseChannel) + } + + var inList: Bool { + return self.baseChannel.inList + } + + var streamChannelListNode: StreamChannelListNode { + get { + return self.baseChannel.streamChannelListNode + } + nonmutating set { + self.baseChannel.streamChannelListNode = newValue + } + } + + func configureInboundStream(initializer: InboundStreamStateInitializer) { + switch initializer { + case .includesStreamID(let initializer): + self.baseChannel.configure(initializer: initializer, userPromise: nil) + case .excludesStreamID(let initializer): + self.baseChannel.configure(initializer: initializer, userPromise: nil) + } + } + + func configure(initializer: ((Channel, HTTP2StreamID) -> EventLoopFuture)?, userPromise promise: EventLoopPromise?) { + self.baseChannel.configure(initializer: initializer, userPromise: promise) + } + + func configure(initializer: ((Channel) -> EventLoopFuture)?, userPromise promise: EventLoopPromise?) { + self.baseChannel.configure(initializer: initializer, userPromise: promise) + } + + func performActivation() { + self.baseChannel.performActivation() + } + + func networkActivationReceived() { + self.baseChannel.networkActivationReceived() + } + + func receiveInboundFrame(_ frame: HTTP2Frame) { + self.baseChannel.receiveInboundFrame(frame) + } + + func receiveParentChannelReadComplete() { + self.baseChannel.receiveParentChannelReadComplete() + } + + func initialWindowSizeChanged(delta: Int) { + self.baseChannel.initialWindowSizeChanged(delta: delta) + } + + func receiveWindowUpdatedEvent(_ windowSize: Int) { + self.baseChannel.receiveWindowUpdatedEvent(windowSize) + } + + func parentChannelWritabilityChanged(newValue: Bool) { + self.baseChannel.parentChannelWritabilityChanged(newValue: newValue) + } + + func receiveStreamClosed(_ reason: HTTP2ErrorCode?) { + self.baseChannel.receiveStreamClosed(reason) + } + + func receiveStreamError(_ error: NIOHTTP2Errors.StreamError) { + self.baseChannel.receiveStreamError(error) + } +} + +extension MultiplexerAbstractChannel: Equatable { + static func ==(lhs: MultiplexerAbstractChannel, rhs: MultiplexerAbstractChannel) -> Bool { + return lhs.baseChannel === rhs.baseChannel + } +} + +extension MultiplexerAbstractChannel: Hashable { + func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(self.baseChannel)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelFlowController.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelFlowController.swift new file mode 100644 index 00000000..dd4a782c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelFlowController.swift @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// The outbound flow control manager for `HTTP2StreamChannel` objects. +/// +/// `HTTP2StreamChannel` objects need a separate piece of outbound flow control +/// management from the one used in HTTP/2. This is because we don't want the +/// size of the remote peer's HTTP/2 flow control window to in any meaningful way affect +/// the resources we allow ourselves to consume locally. +/// +/// Our flow control strategy here is in two parts. The first is a watermarked +/// pending-byte-based flow control strategy that uses the number of writes that have been +/// issued by the channel but not written to the network. If these writes move past a certain +/// threshold, the channel writability state will change. +/// +/// The second is a parent-channel based observation. If the parent channel is not writable, +/// there is no reason to tell the stream channels that they can write either, as those writes +/// will simply back up in the parent. +/// +/// The observed effect is that the `HTTP2StreamChannel` is writable only if both of the above +/// strategies are writable: if either is not writable, neither is the `HTTP2StreamChannel`. +struct StreamChannelFlowController { + private var watermarkedController: WatermarkedFlowController + + private var parentIsWritable: Bool + + internal init(highWatermark: Int, lowWatermark: Int, parentIsWritable: Bool) { + self.watermarkedController = WatermarkedFlowController(highWatermark: highWatermark, lowWatermark: lowWatermark) + self.parentIsWritable = parentIsWritable + } +} + + +extension StreamChannelFlowController { + /// Whether the `HTTP2StreamChannel` should be writable. + var isWritable: Bool { + return self.watermarkedController.isWritable && self.parentIsWritable + } +} + + +extension StreamChannelFlowController { + /// A value representing a change in writability. + enum WritabilityChange: Hashable { + /// No writability change occurred + case noChange + + /// Writability changed to a new value. + case changed(newValue: Bool) + } +} + + +extension StreamChannelFlowController { + /// Notifies the flow controller that we have queued some bytes for writing to the network. + mutating func bufferedBytes(_ bufferedBytes: Int) -> WritabilityChange { + return self.mayChangeWritability { + $0.watermarkedController.bufferedBytes(bufferedBytes) + } + } + + /// Notifies the flow controller that we have successfully written some bytes to the network. + mutating func wroteBytes(_ writtenBytes: Int) -> WritabilityChange { + return self.mayChangeWritability { + $0.watermarkedController.wroteBytes(writtenBytes) + } + } + + mutating func parentWritabilityChanged(_ newWritability: Bool) -> WritabilityChange { + return self.mayChangeWritability { + $0.parentIsWritable = newWritability + } + } + + private mutating func mayChangeWritability(_ body: (inout StreamChannelFlowController) -> Void) -> WritabilityChange { + let wasWritable = self.isWritable + body(&self) + let isWritable = self.isWritable + + if wasWritable != isWritable { + return .changed(newValue: isWritable) + } else { + return .noChange + } + } +} + + +extension StreamChannelFlowController: Equatable { } + + +extension StreamChannelFlowController: CustomDebugStringConvertible { + var debugDescription: String { + return "StreamChannelFlowController(parentIsWritable: \(self.parentIsWritable), watermarkedController: \(self.watermarkedController.debugDescription))" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelList.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelList.swift new file mode 100644 index 00000000..87dae995 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamChannelList.swift @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// A linked list for storing MultiplexerAbstractChannels. +/// +/// Note that while this object *could* conform to `Sequence`, there is minimal value in doing +/// that here, as it's so single-use. If we find ourselves needing to expand on this data type +/// in future we can revisit that idea. +struct StreamChannelList { + private var head: MultiplexerAbstractChannel? + private var tail: MultiplexerAbstractChannel? +} + +/// A node for objects stored in an intrusive linked list. +/// +/// Any object that wishes to be stored in a linked list must embed one of these nodes. +struct StreamChannelListNode { + fileprivate enum ListState { + case inList(next: MultiplexerAbstractChannel?) + case notInList + } + + fileprivate var state: ListState = .notInList + + internal init() { } +} + + +extension StreamChannelList { + /// Append an element to the linked list. + mutating func append(_ element: MultiplexerAbstractChannel) { + precondition(!element.inList) + + guard case .notInList = element.streamChannelListNode.state else { + preconditionFailure("Appended an element already in a list") + } + + element.streamChannelListNode.state = .inList(next: nil) + + if let tail = self.tail { + tail.streamChannelListNode.state = .inList(next: element) + self.tail = element + } else { + assert(self.head == nil) + self.head = element + self.tail = element + } + } + + mutating func removeFirst() -> MultiplexerAbstractChannel? { + guard let head = self.head else { + assert(self.tail == nil) + return nil + } + + guard case .inList(let next) = head.streamChannelListNode.state else { + preconditionFailure("Popped an element not in a list") + } + + self.head = next + if self.head == nil { + assert(self.tail == head) + self.tail = nil + } + + head.streamChannelListNode = .init() + return head + } + + mutating func removeAll() { + while self.removeFirst() != nil { } + } +} + + +// MARK:- IntrusiveLinkedListElement helpers. +extension HTTP2StreamChannel { + /// Whether this element is currently in a list. + internal var inList: Bool { + switch self.streamChannelListNode.state { + case .inList: + return true + case .notInList: + return false + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamMap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamMap.swift new file mode 100644 index 00000000..ac0075ea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamMap.swift @@ -0,0 +1,340 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +fileprivate let binarySearchThreshold = 200 + +/// StreamMap is a specialized data structure built to optimise lookups of per-stream state. +/// +/// It is common when working with HTTP/2 to need to store "per-stream" state. This is state that is +/// reproduced once per stream, and independent. In general we want to be able to store this state in such +/// a way that we can look it up by stream ID as efficiently as possible. +/// +/// Naively we can use a dictionary for this, but dictionaries incur substantial hashing costs. This is +/// straightforward, but we can do better by noting that streams are inherently _ordered_. That is, within +/// a stream ID space (client or server), all streams are created in stricly ascending order. As a result +/// we can efficiently use linear scans to find streams in arrays instead, so long as we have a separate array +/// for both client and server-initated streams. +/// +/// This data structure encapsulates this idea. To tolerate high-load cases, we don't actually use `Array` +/// directly: instead we use `CircularBuffer`. This reduces our need to reallocate memory because we can re-use +/// slots from previous stream data. It also avoids the need to compact the array, as old streams are more likely +/// to complete before new ones, which would leave gaps at the front of the array. +/// +/// Finally, we have to discuss the complexity of lookups. By moving from a dictionary we go from O(1) to O(n) cost +/// for lookups. This is worse! Why would we want this? +/// +/// Well, most of the time the number of streams on any given connection is very low. On modern processors, it is often +/// faster to do a linear search of an array than to do the hashing required to index into the dictionary. Linear scans +/// are cache-friendly and branch-predictor-friendly, which means it can in some cases be cheaper to do a linear scan of +/// 100 items than to do a binary search or hash table lookup. +/// +/// Our strategy here is therefore hybrid. Up to 200 streams we will do linear searches to find our stream. Beyond that, +/// we'll do a binary search. +struct StreamMap { + private var serverInitiated: CircularBuffer + private var clientInitiated: CircularBuffer + + init() { + // We begin by creating our circular buffers at 16 elements in size. This is a good balance between not wasting too + // much memory, but avoiding the first few quadratic resizes. + self.serverInitiated = CircularBuffer(initialCapacity: 16) + self.clientInitiated = CircularBuffer(initialCapacity: 16) + } + + fileprivate init(serverInitiated: CircularBuffer, clientInitiated: CircularBuffer) { + self.serverInitiated = serverInitiated + self.clientInitiated = clientInitiated + } + + /// Creates an "empty" stream map. This should be used only to create static singletons + /// whose purpose is to be swapped to avoid CoWs. Otherwise use regular init(). + static func empty() -> StreamMap { + let sortaEmptyCircularBuffer = CircularBuffer() + return StreamMap(serverInitiated: sortaEmptyCircularBuffer, clientInitiated: sortaEmptyCircularBuffer) + } + + func contains(streamID: HTTP2StreamID) -> Bool { + if streamID.mayBeInitiatedBy(.client) { + return self.clientInitiated.findIndexForStreamID(streamID) != nil + } else { + return self.serverInitiated.findIndexForStreamID(streamID) != nil + } + } + + /// Calls the closure with the given element, if it is present. Returns nil if the element is not present. + mutating func modify(streamID: HTTP2StreamID, _ body: (inout Element) throws -> ReturnType) rethrows -> ReturnType? { + if streamID.mayBeInitiatedBy(.client) { + guard let index = self.clientInitiated.findIndexForStreamID(streamID) else { + return nil + } + return try self.clientInitiated.modify(index, body) + } else { + guard let index = self.serverInitiated.findIndexForStreamID(streamID) else { + return nil + } + return try self.serverInitiated.modify(index, body) + } + } + + mutating func insert(_ element: Element) { + let streamID = element.streamID + + if streamID.mayBeInitiatedBy(.client) { + assert((self.clientInitiated.last?.streamID ?? 0) < streamID) + self.clientInitiated.append(element) + } else { + assert((self.serverInitiated.last?.streamID ?? 0) < streamID) + self.serverInitiated.append(element) + } + } + + mutating func mutatingForEachValue(_ body: (inout Element) throws -> Void) rethrows { + try self.clientInitiated.mutatingForEach(body) + try self.serverInitiated.mutatingForEach(body) + } + + func forEachValue(_ body: (Element) throws -> Void) rethrows { + try self.clientInitiated.forEach(body) + try self.serverInitiated.forEach(body) + } + + @discardableResult + mutating func removeValue(forStreamID streamID: HTTP2StreamID) -> Element? { + if streamID.mayBeInitiatedBy(.client), let index = self.clientInitiated.findIndexForStreamID(streamID) { + return self.clientInitiated.remove(at: index) + } else if streamID.mayBeInitiatedBy(.server), let index = self.serverInitiated.findIndexForStreamID(streamID) { + return self.serverInitiated.remove(at: index) + } else { + return nil + } + } + + func elements(initiatedBy: HTTP2ConnectionStateMachine.ConnectionRole) -> CircularBuffer.Iterator { + switch initiatedBy { + case .client: + return self.clientInitiated.makeIterator() + case .server: + return self.serverInitiated.makeIterator() + } + } + + /// This is a special case helper for the ConnectionStreamsState, which has to handle GOAWAY. In that case we + /// drop all stream state for a bunch of streams all at once. These streams are guaranteed to be sequential and based at a certain stream ID. + /// + /// It's useful to get that data back too, and helpfully CircularBuffer will let us slice it out. We can't return it though: that will cause the mutation + /// to trigger a CoW. Instead we pass it to the caller in a block, and then do the removal. + /// + /// This helper can turn a complex operation that involves repeated resizing of the base objects into a much faster one that also avoids + /// allocation. + mutating func dropDataWithStreamIDGreaterThan(_ streamID: HTTP2StreamID, + initiatedBy role: HTTP2ConnectionStateMachine.ConnectionRole, + _ block: (CircularBuffer.SubSequence) -> Void) { + switch role { + case .client: + let index = self.clientInitiated.findIndexForFirstStreamIDLargerThan(streamID) + block(self.clientInitiated[index...]) + self.clientInitiated.removeSubrange(index...) + case .server: + let index = self.serverInitiated.findIndexForFirstStreamIDLargerThan(streamID) + block(self.serverInitiated[index...]) + self.serverInitiated.removeSubrange(index...) + } + } +} + +internal extension StreamMap where Element == HTTP2StreamStateMachine { + // This function exists as a performance optimisation: we can keep track of the index and where we are, and + // thereby avoid searching the array twice. + // + /// Transform the value of an HTTP2StreamStateMachine, closing it if it ends up closed. + /// + /// - parameters: + /// - modifier: A block that will modify the contained value in the + /// map, if there is one present. + /// - returns: The return value of the block or `nil` if the element was not present. + mutating func autoClosingTransform(streamID: HTTP2StreamID, _ modifier: (inout Element) -> T) -> T? { + if streamID.mayBeInitiatedBy(.client) { + return self.clientInitiated.autoClosingTransform(streamID: streamID, modifier) + } else { + return self.serverInitiated.autoClosingTransform(streamID: streamID, modifier) + } + } + + + // This function exists as a performance optimisation: we can keep track of the index and where we are, and + // thereby avoid searching the array twice. + mutating func transformOrCreateAutoClose(streamID: HTTP2StreamID, + _ creator: () throws -> Element, + _ transformer: (inout Element) -> T) rethrows -> T? { + if streamID.mayBeInitiatedBy(.client) { + return try self.clientInitiated.transformOrCreateAutoClose(streamID: streamID, creator, transformer) + } else { + return try self.serverInitiated.transformOrCreateAutoClose(streamID: streamID, creator, transformer) + } + } +} + +extension CircularBuffer where Element: PerStreamData { + fileprivate mutating func mutatingForEach(_ body: (inout Element) throws -> Void) rethrows { + var index = self.startIndex + let endIndex = self.endIndex + while index != endIndex { + try self.modify(index, body) + self.formIndex(after: &index) + } + } + + fileprivate func findIndexForStreamID(_ streamID: HTTP2StreamID) -> Index? { + if self.count < binarySearchThreshold { + return self.linearScanForStreamID(streamID) + } else { + return self.binarySearchForStreamID(streamID) + } + } + + private func linearScanForStreamID(_ streamID: HTTP2StreamID) -> Index? { + var index = self.startIndex + + while index < self.endIndex { + let currentStreamID = self[index].streamID + if currentStreamID == streamID { + return index + } + if currentStreamID > streamID { + // Stop looping, we won't find this. + return nil + } + self.formIndex(after: &index) + } + + return nil + } + + // Binary search is somewhat complex code compared to a linear scan, so we don't want to inline this code if we can avoid it. + @inline(never) + private func binarySearchForStreamID(_ streamID: HTTP2StreamID) -> Index? { + var left = self.startIndex + var right = self.endIndex + + while left != right { + let pivot = self.index(left, offsetBy: self.distance(from: left, to: right) / 2) + let currentStreamID = self[pivot].streamID + if currentStreamID > streamID { + right = pivot + } else if currentStreamID == streamID { + return pivot + } else { + left = self.index(after: pivot) + } + } + + return nil + } + + fileprivate func findIndexForFirstStreamIDLargerThan(_ streamID: HTTP2StreamID) -> Index { + if self.count < binarySearchThreshold { + return self.linearScanForFirstStreamIDLargerThan(streamID) + } else { + return self.binarySearchForFirstStreamIDLargerThan(streamID) + } + } + + private func linearScanForFirstStreamIDLargerThan(_ streamID: HTTP2StreamID) -> Index { + var index = self.startIndex + + while index < self.endIndex { + let currentStreamID = self[index].streamID + if currentStreamID > streamID { + return index + } + self.formIndex(after: &index) + } + + return self.endIndex + } + + // Binary search is somewhat complex code compared to a linear scan, so we don't want to inline this code if we can avoid it. + @inline(never) + private func binarySearchForFirstStreamIDLargerThan(_ streamID: HTTP2StreamID) -> Index { + var left = self.startIndex + var right = self.endIndex + + while left != right { + let pivot = self.index(left, offsetBy: self.distance(from: left, to: right) / 2) + let currentStreamID = self[pivot].streamID + if currentStreamID > streamID { + right = pivot + } else if currentStreamID == streamID { + // The stream ID is the one after. + return self.index(after: pivot) + } else { + left = self.index(after: pivot) + } + } + + return left + } +} + +extension CircularBuffer where Element == HTTP2StreamStateMachine { + // This function exists as a performance optimisation: we can keep track of the index and where we are, and + // thereby avoid searching the array twice. + // + /// Transform the value of an HTTP2StreamStateMachine, closing it if it ends up closed. + /// + /// - parameters: + /// - modifier: A block that will modify the contained value in the + /// map, if there is one present. + /// - returns: The return value of the block or `nil` if the element was not in the map. + mutating func autoClosingTransform(streamID: HTTP2StreamID, _ modifier: (inout Element) -> ResultType) -> ResultType? { + guard let index = self.findIndexForStreamID(streamID) else { + return nil + } + + return self.modifyAutoClose(index: index, modifier) + } + + // This function exists as a performance optimisation: we can keep track of the index and where we are, and + // thereby avoid searching the array twice. + mutating func transformOrCreateAutoClose(streamID: HTTP2StreamID, + _ creator: () throws -> Element, + _ transformer: (inout Element) -> ResultType) rethrows -> ResultType? { + if let index = self.findIndexForStreamID(streamID) { + return self.modifyAutoClose(index: index, transformer) + } else { + self.append(try creator()) + let index = self.index(before: self.endIndex) + return self.modifyAutoClose(index: index, transformer) + } + } + + private mutating func modifyAutoClose(index: Index, _ modifier: (inout Element) -> ResultType) -> ResultType { + let (result, closed): (ResultType, HTTP2StreamStateMachine.StreamClosureState) = self.modify(index) { + let result = modifier(&$0) + return (result, $0.closed) + } + + if case .closed = closed { + self.remove(at: index) + } + + return result + } +} + +protocol PerStreamData { + var streamID: HTTP2StreamID { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamStateMachine.swift new file mode 100644 index 00000000..0cfcd827 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/StreamStateMachine.swift @@ -0,0 +1,1082 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOHPACK +import NIOCore + +/// A HTTP/2 protocol implementation is fundamentally built on top of two interlocking finite +/// state machines. The full description of this is in ConnectionStateMachine.swift. +/// +/// This file contains the implementation of the per-stream state machine. A HTTP/2 stream goes +/// through a number of states in its lifecycle, and the specific states it passes through depend +/// on how the stream is created and what it is for. RFC 7540 claims to have a state machine +/// diagram for a HTTP/2 stream, which I have reproduced below: +/// +/// +--------+ +/// send PP | | recv PP +/// ,--------| idle |--------. +/// / | | \ +/// v +--------+ v +/// +----------+ | +----------+ +/// | | | send H / | | +/// ,------| reserved | | recv H | reserved |------. +/// | | (local) | | | (remote) | | +/// | +----------+ v +----------+ | +/// | | +--------+ | | +/// | | recv ES | | send ES | | +/// | send H | ,-------| open |-------. | recv H | +/// | | / | | \ | | +/// | v v +--------+ v v | +/// | +----------+ | +----------+ | +/// | | half | | | half | | +/// | | closed | | send R / | closed | | +/// | | (remote) | | recv R | (local) | | +/// | +----------+ | +----------+ | +/// | | | | | +/// | | send ES / | recv ES / | | +/// | | send R / v send R / | | +/// | | recv R +--------+ recv R | | +/// | send R / `----------->| |<-----------' send R / | +/// | recv R | closed | recv R | +/// `----------------------->| |<----------------------' +/// +--------+ +/// +/// send: endpoint sends this frame +/// recv: endpoint receives this frame +/// +/// H: HEADERS frame (with implied CONTINUATIONs) +/// PP: PUSH_PROMISE frame (with implied CONTINUATIONs) +/// ES: END_STREAM flag +/// R: RST_STREAM frame +/// +/// Unfortunately, this state machine diagram is not really entirely sufficient, as it +/// underspecifies many aspects of the system. One particular note is that it does not +/// encode the validity of some of these transitions: for example, send PP or recv PP +/// are only valid for certain kinds of peers. +/// +/// Ultimately, however, this diagram provides the basis for our state machine +/// implementation in this file. The state machine aims to enforce the correctness of +/// the protocol. +/// +/// Remote peers that violate the protocol requirements should be notified early. +/// HTTP/2 is unusual in that the vast majority of implementations are strict about +/// RFC violations, and we should be as well. Therefore, the state machine exists to +/// constrain the remote peer's actions: if they take an action that leads to an invalid +/// state transition, we will report this to the remote peer (and to our user). +/// +/// Additionally, we want to enforce that our users do not violate the correctness of the +/// protocol. In this early implementation if the user violates protocol correctness, no +/// action is taken: the stream remains in its prior state, and no frame is emitted. +/// In future it may become configurable such that if the user violates the correctness of +/// the protocol, NIO will proactively close the stream to avoid consuming resources. +/// +/// ### Implementation +/// +/// The core of the state machine implementation is a `State` enum. This enum demarcates all +/// valid states of the stream, and enforces only valid transitions between those states. +/// Attempts to make invalid transitions between those states will be rejected by this enum. +/// +/// Additionally, this enum stores all relevant data about the stream that is associated with +/// its stream state as associated data. This ensures that it is not possible to store a stream +/// state that requires associated data without providing it. +/// +/// To prevent future maintainers from being tempted to circumvent the rules in this state machine, +/// the `State` enum is wrapped in a `struct` (this `struct`, in fact) that prevents programmers +/// from directly setting the state of a stream. +/// +/// Operations on the state machine are performed by calling specific functions corresponding to +/// the operation that is about to occur. +struct HTTP2StreamStateMachine { + fileprivate enum State { + // TODO(cory): Can we remove the idle state? Streams shouldn't sit in idle for long periods + // of time, they should immediately transition out, so can we avoid it entirely? + /// In the idle state, the stream has not been opened by either peer. + /// This is usually a temporary state, and we expect rapid transitions out of this state. + /// In this state we keep track of whether we are in a client or server connection, as it + /// limits the transitions we can make. In all other states, being either a client or server + /// is either not relevant, or encoded in the state itself implicitly. + case idle(localRole: StreamRole, localWindow: HTTP2FlowControlWindow, remoteWindow: HTTP2FlowControlWindow) + + /// In the reservedRemote state, the stream has been opened by the remote peer emitting a + /// PUSH_PROMISE frame. We are expecting to receive a HEADERS frame for the pushed response. In this + /// state we are definitionally a client. + case reservedRemote(remoteWindow: HTTP2FlowControlWindow) + + /// In the reservedLocal state, the stream has been opened by the local user sending a PUSH_PROMISE + /// frame. We now need to send a HEADERS frame for the pushed response. In this state we are definitionally + /// a server. + case reservedLocal(localWindow: HTTP2FlowControlWindow) + + /// This state does not exist on the diagram above. It encodes the notion that this stream has + /// been opened by the local user sending a HEADERS frame, but we have not yet received the remote + /// peer's final HEADERS frame in response. It is possible we have received non-final HEADERS frames + /// from the remote peer in this state, however. If we are in this state, we must be a client: servers + /// initiating streams put them into reservedLocal, and then sending HEADERS transfers them directly to + /// halfClosedRemoteLocalActive. + case halfOpenLocalPeerIdle(localWindow: HTTP2FlowControlWindow, localContentLength: ContentLengthVerifier, remoteWindow: HTTP2FlowControlWindow) + + /// This state does not exist on the diagram above. It encodes the notion that this stream has + /// been opened by the remote user sending a HEADERS frame, but we have not yet sent our HEADERS frame + /// in response. If we are in this state, we must be a server: clients receiving streams that were opened + /// by servers put them into reservedRemote, and then receiving the response HEADERS transitions them directly + /// to halfClosedLocalPeerActive. + case halfOpenRemoteLocalIdle(localWindow: HTTP2FlowControlWindow, remoteContentLength: ContentLengthVerifier, remoteWindow: HTTP2FlowControlWindow) + + /// This state is when both peers have sent a HEADERS frame, but neither has sent a frame with END_STREAM + /// set. Both peers may exchange data fully. In this state we keep track of whether we are a client or a + /// server, as only servers may push new streams. + case fullyOpen(localRole: StreamRole, localContentLength: ContentLengthVerifier, remoteContentLength: ContentLengthVerifier, localWindow: HTTP2FlowControlWindow, remoteWindow: HTTP2FlowControlWindow) + + /// In the halfClosedLocalPeerIdle state, the local user has sent END_STREAM, but the remote peer has not + /// yet sent its HEADERS frame. This mostly happens on GET requests, when END_HEADERS and END_STREAM are + /// present on the same frame, and so the stream transitions directly from idle to this state. + /// This peer can no longer send data. We are expecting a headers frame from the remote peer. + /// + /// In this state we must be a client, as this state can only be entered by the local peer sending + /// END_STREAM before we receive HEADERS. This cannot happen to a server, as we must have initiated + /// this stream to have half closed it before we receive HEADERS, and if we had initiated the stream via + /// PUSH_PROMISE (as a server must), the stream would be halfClosedRemote, not halfClosedLocal. + case halfClosedLocalPeerIdle(remoteWindow: HTTP2FlowControlWindow) + + /// In the halfClosedLocalPeerActive state, the local user has sent END_STREAM, and the remote peer has + /// sent its HEADERS frame. This happens when we send END_STREAM from the fullyOpen state, or when we + /// receive a HEADERS in reservedRemote. This peer can no longer send data. The remote peer may continue + /// to do so. We are not expecting a HEADERS frame from the remote peer. + /// + /// Both servers and clients can be in this state. + /// + /// We keep track of whether this stream was initiated by us or by the peer, which can be determined based + /// on how we entered this state. If we came from fullyOpen and we're a client, then this peer was initiated + /// by us: if we're a server, it was initiated by the peer. This is because server-initiated streams never + /// enter fullyOpen, as the client is never actually open on those streams. If we came here from + /// reservedRemote, this stream must be peer initiated, as this is the client side of a pushed stream. + case halfClosedLocalPeerActive(localRole: StreamRole, initiatedBy: StreamRole, remoteContentLength: ContentLengthVerifier, remoteWindow: HTTP2FlowControlWindow) + + /// In the halfClosedRemoteLocalIdle state, the remote peer has sent END_STREAM, but the local user has not + /// yet sent its HEADERS frame. This mostly happens on GET requests, when END_HEADERS and END_STREAM are + /// present on the same frame, and so the stream transitions directly from idle to this state. + /// This peer is expected to send a HEADERS frame. The remote peer may no longer send data. + /// + /// In this state we must be a server, as this state can only be entered by the remote peer sending + /// END_STREAM before we send HEADERS. This cannot happen to a client, as the remote peer must have initiated + /// this stream to have half closed it before we send HEADERS, and that will cause a client to enter halfClosedLocal, + /// not halfClosedRemote. + case halfClosedRemoteLocalIdle(localWindow: HTTP2FlowControlWindow) + + /// In the halfClosedRemoteLocalActive state, the remote peer has sent END_STREAM, and the local user has + /// sent its HEADERS frame. This happens when we receive END_STREAM in the fullyOpen state, or when we + /// send a HEADERS frame in reservedLocal. This peer is not expected to send a HEADERS frame. + /// The remote peer may no longer send data. + /// + /// Both servers and clients can be in this state. + /// + /// We keep track of whether this stream was initiated by us or by the peer, which can be determined based + /// on how we entered this state. If we came from fullyOpen and we're a client, then this stream was initiated + /// by us: if we're a server, it was initiated by the peer. This is because server-initiated streams never + /// enter fullyOpen, as the client is never actually open on those streams. If we came here from + /// reservedLocal, this stream must be initiated by us, as this is the server side of a pushed stream. + case halfClosedRemoteLocalActive(localRole: StreamRole, initiatedBy: StreamRole, localContentLength: ContentLengthVerifier, localWindow: HTTP2FlowControlWindow) + + /// Both peers have sent their END_STREAM flags, and the stream is closed. In this stage no further data + /// may be exchanged. + case closed(reason: HTTP2ErrorCode?) + } + + /// The possible roles an endpoint may play in a given stream. + enum StreamRole { + /// A server. Servers initiate streams by pushing them. + case server + + /// A client. Clients initiate streams by sending requests. + case client + } + + /// Whether the stream has been closed. + internal enum StreamClosureState: Hashable { + case closed(HTTP2ErrorCode?) + + case notClosed + } + + /// Whether this stream has been closed. + /// + /// This property should be used only for asserting correct state. + internal var closed: StreamClosureState { + switch self.state { + case .closed(let reason): + return .closed(reason) + default: + return .notClosed + } + } + + /// The current state of this stream. + private var state: State + + /// The ID of this stream. + internal let streamID: HTTP2StreamID + + /// Creates a new, idle, HTTP/2 stream. + init(streamID: HTTP2StreamID, localRole: StreamRole, localInitialWindowSize: UInt32, remoteInitialWindowSize: UInt32) { + let localWindow = HTTP2FlowControlWindow(initialValue: localInitialWindowSize) + let remoteWindow = HTTP2FlowControlWindow(initialValue: remoteInitialWindowSize) + + self.streamID = streamID + self.state = .idle(localRole: localRole, localWindow: localWindow, remoteWindow: remoteWindow) + } + + /// Creates a new HTTP/2 stream for a stream that was created by receiving a PUSH_PROMISE frame + /// on another stream. + init(receivedPushPromiseCreatingStreamID streamID: HTTP2StreamID, remoteInitialWindowSize: UInt32) { + self.streamID = streamID + self.state = .reservedRemote(remoteWindow: HTTP2FlowControlWindow(initialValue: remoteInitialWindowSize)) + } + + /// Creates a new HTTP/2 stream for a stream that was created by sending a PUSH_PROMISE frame on + /// another stream. + init(sentPushPromiseCreatingStreamID streamID: HTTP2StreamID, localInitialWindowSize: UInt32) { + self.streamID = streamID + self.state = .reservedLocal(localWindow: HTTP2FlowControlWindow(initialValue: localInitialWindowSize)) + } +} + +// MARK:- State transition functions +// +// The events that may cause the state machine to change state. +// +// This enumeration contains entries for sending and receiving all per-stream frames except for PRIORITY. +// The per-connection frames (GOAWAY, PING, some WINDOW_UPDATE) are managed by the connection state machine +// instead of the stream one, and so are not covered here. This enumeration excludes PRIORITY frames, because +// while PRIORITY frames are technically per-stream they can be sent at any time on an active connection, +// regardless of the state of the affected stream. For this reason, they are not so much per-stream frames +// as per-connection frames that happen to have a stream ID. +extension HTTP2StreamStateMachine { + /// Called when a HEADERS frame is being sent. Validates that the frame may be sent in this state, that + /// it meets the requirements of RFC 7540 for containing a well-formed header block, and additionally + /// checks whether the value of the end stream bit is acceptable. If all checks pass, transitions the + /// state to the appropriate next entry. + mutating func sendHeaders(headers: HPACKHeaders, validateHeaderBlock: Bool, validateContentLength: Bool, isEndStreamSet endStream: Bool) -> StateMachineResultWithStreamEffect { + do { + // We can send headers in the following states: + // + // - idle, when we are a client, in which case we are sending our request headers + // - halfOpenRemoteLocalIdle, in which case we are a server sending either informational or final headers + // - halfOpenLocalPeerIdle, in which case we are a client sending trailers + // - reservedLocal, in which case we are a server sending either informational or final headers + // - fullyOpen, in which case we are sending trailers + // - halfClosedRemoteLocalIdle, in which case we area server sending either informational or final headers + // (see the comment on halfClosedRemoteLocalIdle for more) + // - halfClosedRemoteLocalActive, in which case we are sending trailers + // + // In idle or reservedLocal we are opening the stream. In reservedLocal, halfClosedRemoteLocalIdle, or halfClosedremoteLocalActive + // we may be closing the stream. The keen-eyed may notice that reservedLocal may both open *and* close a stream. This is a bit awkward + // for us, and requires a separate event. + switch self.state { + case .idle(.client, localWindow: let localWindow, remoteWindow: let remoteWindow): + let targetState: State + let localContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try localContentLength.endOfStream() + targetState = .halfClosedLocalPeerIdle(remoteWindow: remoteWindow) + } else { + targetState = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + } + + let targetEffect: StreamStateChange = .streamCreated(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + return self.processRequestHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetState: targetState, + targetEffect: targetEffect) + + case .halfOpenRemoteLocalIdle(localWindow: let localWindow, remoteContentLength: let remoteContentLength, remoteWindow: let remoteWindow): + let targetState: State + let localContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try localContentLength.endOfStream() + targetState = .halfClosedLocalPeerActive(localRole: .server, initiatedBy: .client, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + } else { + targetState = .fullyOpen(localRole: .server, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + } + + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: nil) + + case .halfOpenLocalPeerIdle(localWindow: _, localContentLength: let localContentLength, remoteWindow: let remoteWindow): + try localContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .halfClosedLocalPeerIdle(remoteWindow: remoteWindow), + targetEffect: nil) + + case .reservedLocal(let localWindow): + let targetState: State + let targetEffect: StreamStateChange + let localContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try localContentLength.endOfStream() + targetState = .closed(reason: nil) + targetEffect = .streamCreatedAndClosed(.init(streamID: self.streamID)) + } else { + targetState = .halfClosedRemoteLocalActive(localRole: .server, initiatedBy: .server, localContentLength: localContentLength, localWindow: localWindow) + targetEffect = .streamCreated(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + } + + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: targetEffect) + + case .fullyOpen(let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: _, remoteWindow: let remoteWindow): + try localContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .halfClosedLocalPeerActive(localRole: localRole, initiatedBy: .client, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow), + targetEffect: nil) + + case .halfClosedRemoteLocalIdle(let localWindow): + let targetState: State + let targetEffect: StreamStateChange? + let localContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try localContentLength.endOfStream() + targetState = .closed(reason: nil) + targetEffect = .streamClosed(.init(streamID: self.streamID, reason: nil)) + } else { + targetState = .halfClosedRemoteLocalActive(localRole: .server, initiatedBy: .client, localContentLength: localContentLength, localWindow: localWindow) + targetEffect = nil + } + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: targetEffect) + + case .halfClosedRemoteLocalActive(localRole: _, initiatedBy: _, localContentLength: let localContentLength, localWindow: _): + try localContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .closed(reason: nil), + targetEffect: .streamClosed(.init(streamID: self.streamID, reason: nil))) + + // Sending a HEADERS frame as an idle server, or on a closed stream, is a connection error + // of type PROTOCOL_ERROR. In any other state, sending a HEADERS frame is a stream error of + // type PROTOCOL_ERROR. + // (Authors note: I can find nothing in the RFC that actually states what kind of error is + // triggered for HEADERS frames outside the valid states. So I just guessed here based on what + // seems reasonable to me: specifically, if we have a stream to fail, fail it, otherwise treat + // the error as connection scoped.) + case .idle(.server, _, _), .closed: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + case .reservedRemote, .halfClosedLocalPeerIdle, .halfClosedLocalPeerActive: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.ContentLengthViolated { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } + + mutating func receiveHeaders(headers: HPACKHeaders, validateHeaderBlock: Bool, validateContentLength: Bool, isEndStreamSet endStream: Bool) -> StateMachineResultWithStreamEffect { + do { + // We can receive headers in the following states: + // + // - idle, when we are a server, in which case we are receiving request headers + // - halfOpenLocalPeerIdle, in which case we are receiving either informational or final response headers + // - halfOpenRemoteLocalIdle, in which case we are receiving trailers + // - reservedRemote, in which case we are a client receiving either informational or final response headers + // - fullyOpen, in which case we are receiving trailers + // - halfClosedLocalPeerIdle, in which case we are receiving either informational or final headers + // (see the comment on halfClosedLocalPeerIdle for more) + // - halfClosedLocalPeerActive, in which case we are receiving trailers + // + // In idle or reservedRemote we are opening the stream. In reservedRemote, halfClosedLocalPeerIdle, or halfClosedLocalPeerActive + // we may be closing the stream. The keen-eyed may notice that reservedLocal may both open *and* close a stream. This is a bit awkward + // for us, and requires a separate event. + switch self.state { + case .idle(.server, localWindow: let localWindow, remoteWindow: let remoteWindow): + let targetState: State + let remoteContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try remoteContentLength.endOfStream() + targetState = .halfClosedRemoteLocalIdle(localWindow: localWindow) + } else { + targetState = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + } + + let targetEffect: StreamStateChange = .streamCreated(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + return self.processRequestHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetState: targetState, + targetEffect: targetEffect) + + case .halfOpenLocalPeerIdle(localWindow: let localWindow, localContentLength: let localContentLength, remoteWindow: let remoteWindow): + let targetState: State + let remoteContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try remoteContentLength.endOfStream() + targetState = .halfClosedRemoteLocalActive(localRole: .client, initiatedBy: .client, localContentLength: localContentLength, localWindow: localWindow) + } else { + targetState = .fullyOpen(localRole: .client, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + } + + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: nil) + + case .halfOpenRemoteLocalIdle(localWindow: let localWindow, remoteContentLength: let remoteContentLength, remoteWindow: _): + try remoteContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .halfClosedRemoteLocalIdle(localWindow: localWindow), + targetEffect: nil) + + case .reservedRemote(let remoteWindow): + let targetState: State + let targetEffect: StreamStateChange + let remoteContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try remoteContentLength.endOfStream() + targetState = .closed(reason: nil) + targetEffect = .streamCreatedAndClosed(.init(streamID: self.streamID)) + } else { + targetState = .halfClosedLocalPeerActive(localRole: .client, initiatedBy: .server, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + targetEffect = .streamCreated(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + } + + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: targetEffect) + + case .fullyOpen(let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: let localWindow, remoteWindow: _): + try remoteContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .halfClosedRemoteLocalActive(localRole: localRole, initiatedBy: .client, localContentLength: localContentLength, localWindow: localWindow), + targetEffect: nil) + + case .halfClosedLocalPeerIdle(let remoteWindow): + let targetState: State + let targetEffect: StreamStateChange? + let remoteContentLength = validateContentLength ? ContentLengthVerifier(headers) : .disabled + + if endStream { + try remoteContentLength.endOfStream() + targetState = .closed(reason: nil) + targetEffect = .streamClosed(.init(streamID: self.streamID, reason: nil)) + } else { + targetState = .halfClosedLocalPeerActive(localRole: .client, initiatedBy: .client, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + targetEffect = nil + } + + return self.processResponseHeaders(headers, + validateHeaderBlock: validateHeaderBlock, + targetStateIfFinal: targetState, + targetEffectIfFinal: targetEffect) + + case .halfClosedLocalPeerActive(localRole: _, initiatedBy: _, remoteContentLength: let remoteContentLength, remoteWindow: _): + try remoteContentLength.endOfStream() + return self.processTrailers(headers, + validateHeaderBlock: validateHeaderBlock, + isEndStreamSet: endStream, + targetState: .closed(reason: nil), + targetEffect: .streamClosed(.init(streamID: self.streamID, reason: nil))) + + // Receiving a HEADERS frame as an idle client, or on a closed stream, is a connection error + // of type PROTOCOL_ERROR. In any other state, receiving a HEADERS frame is a stream error of + // type PROTOCOL_ERROR. + // (Authors note: I can find nothing in the RFC that actually states what kind of error is + // triggered for HEADERS frames outside the valid states. So I just guessed here based on what + // seems reasonable to me: specifically, if we have a stream to fail, fail it, otherwise treat + // the error as connection scoped.) + case .idle(.client, _, _), .closed: + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + case .reservedLocal, .halfClosedRemoteLocalIdle, .halfClosedRemoteLocalActive: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.ContentLengthViolated { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } + + mutating func sendData(contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithStreamEffect { + do { + // We can send DATA frames in the following states: + // + // - halfOpenLocalPeerIdle, in which case we are a client sending request data before the server + // has sent its final response headers. + // - fullyOpen, where we could be either a client or a server using a fully bi-directional stream. + // - halfClosedRemoteLocalActive, where the remote peer has completed its data, but we have more to send. + // + // Valid data frames always have a stream effect, because they consume flow control windows. + switch self.state { + case .halfOpenLocalPeerIdle(localWindow: var localWindow, localContentLength: var localContentLength, remoteWindow: let remoteWindow): + try localWindow.consume(flowControlledBytes: flowControlledBytes) + try localContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange + if endStream { + try localContentLength.endOfStream() + self.state = .halfClosedLocalPeerIdle(remoteWindow: remoteWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + } else { + self.state = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + } + + return .init(result: .succeed, effect: effect) + + case .fullyOpen(let localRole, localContentLength: var localContentLength, remoteContentLength: let remoteContentLength, localWindow: var localWindow, remoteWindow: let remoteWindow): + try localWindow.consume(flowControlledBytes: flowControlledBytes) + try localContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + if endStream { + try localContentLength.endOfStream() + self.state = .halfClosedLocalPeerActive(localRole: localRole, initiatedBy: .client, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + } else { + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + } + + return .init(result: .succeed, effect: effect) + + case .halfClosedRemoteLocalActive(let localRole, let initiatedBy, var localContentLength, var localWindow): + try localWindow.consume(flowControlledBytes: flowControlledBytes) + try localContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange + if endStream { + try localContentLength.endOfStream() + self.state = .closed(reason: nil) + effect = .streamClosed(.init(streamID: self.streamID, reason: nil)) + } else { + self.state = .halfClosedRemoteLocalActive(localRole: localRole, initiatedBy: initiatedBy, localContentLength: localContentLength, localWindow: localWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + } + + return .init(result: .succeed, effect: effect) + + // Sending a DATA frame outside any of these states is a stream error of type STREAM_CLOSED (RFC7540 § 6.1) + case .idle, .halfOpenRemoteLocalIdle, .reservedLocal, .reservedRemote, .halfClosedLocalPeerIdle, + .halfClosedLocalPeerActive, .halfClosedRemoteLocalIdle, .closed: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .streamClosed), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.FlowControlViolation { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.ContentLengthViolated { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } + + mutating func receiveData(contentLength: Int, flowControlledBytes: Int, isEndStreamSet endStream: Bool) -> StateMachineResultWithStreamEffect { + do { + // We can receive DATA frames in the following states: + // + // - halfOpenRemoteLocalIdle, in which case we are a server receiving request data before we have + // sent our final response headers. + // - fullyOpen, where we could be either a client or a server using a fully bi-directional stream. + // - halfClosedLocalPeerActive, whe have completed our data, but the remote peer has more to send. + switch self.state { + case .halfOpenRemoteLocalIdle(localWindow: let localWindow, remoteContentLength: var remoteContentLength, remoteWindow: var remoteWindow): + try remoteWindow.consume(flowControlledBytes: flowControlledBytes) + try remoteContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange + if endStream { + try remoteContentLength.endOfStream() + self.state = .halfClosedRemoteLocalIdle(localWindow: localWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + } else { + self.state = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + } + + return .init(result: .succeed, effect: effect) + + case .fullyOpen(let localRole, localContentLength: let localContentLength, remoteContentLength: var remoteContentLength, localWindow: let localWindow, remoteWindow: var remoteWindow): + try remoteWindow.consume(flowControlledBytes: flowControlledBytes) + try remoteContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange + if endStream { + try remoteContentLength.endOfStream() + self.state = .halfClosedRemoteLocalActive(localRole: localRole, initiatedBy: .client, localContentLength: localContentLength, localWindow: localWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + } else { + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + } + + return .init(result: .succeed, effect: effect) + + case .halfClosedLocalPeerActive(let localRole, let initiatedBy, var remoteContentLength, var remoteWindow): + try remoteWindow.consume(flowControlledBytes: flowControlledBytes) + try remoteContentLength.receivedDataChunk(length: contentLength) + + let effect: StreamStateChange + if endStream { + try remoteContentLength.endOfStream() + self.state = .closed(reason: nil) + effect = .streamClosed(.init(streamID: self.streamID, reason: nil)) + } else { + self.state = .halfClosedLocalPeerActive(localRole: localRole, initiatedBy: initiatedBy, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + effect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + } + + return .init(result: .succeed, effect: effect) + + // Receiving a DATA frame outside any of these states is a stream error of type STREAM_CLOSED (RFC7540 § 6.1) + case .idle, .halfOpenLocalPeerIdle, .reservedLocal, .reservedRemote, .halfClosedLocalPeerIdle, + .halfClosedRemoteLocalActive, .halfClosedRemoteLocalIdle, .closed: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .streamClosed), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.FlowControlViolation { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.ContentLengthViolated { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + } + + mutating func sendPushPromise(headers: HPACKHeaders, validateHeaderBlock: Bool) -> StateMachineResultWithStreamEffect { + // We can send PUSH_PROMISE frames in the following states: + // + // - fullyOpen when we are a server. In this case we assert that the stream was initiated by the client. + // - halfOpenRemoteLocalIdle, which only servers can enter on streams initiated by clients. + // - halfClosedRemoteLocalIdle, which only servers can enter on streams initiated by clients. + // - halfClosedRemoteLocalActive, when we are a server, and when the stream was initiated by the client. + // + // RFC 7540 § 6.6 forbids sending PUSH_PROMISE frames on locally-initiated streams. + // + // PUSH_PROMISE frames never have stream effects: they cannot create or close streams, or affect flow control state. + switch self.state { + case .fullyOpen(localRole: .server, localContentLength: _, remoteContentLength: _, localWindow: _, remoteWindow: _), + .halfOpenRemoteLocalIdle(localWindow: _, remoteContentLength: _, remoteWindow: _), + .halfClosedRemoteLocalIdle(localWindow: _), + .halfClosedRemoteLocalActive(localRole: .server, initiatedBy: .client, localContentLength: _, localWindow: _): + return self.processRequestHeaders(headers, validateHeaderBlock: validateHeaderBlock, targetState: self.state, targetEffect: nil) + + // Sending a PUSH_PROMISE frame outside any of these states is a stream error of type PROTOCOL_ERROR. + // Authors note: I cannot find a citation for this in RFC 7540, but this seems a sensible choice. + case .idle, .reservedLocal, .reservedRemote, .halfClosedLocalPeerIdle, .halfClosedLocalPeerActive, + .halfOpenLocalPeerIdle, .closed, + .fullyOpen(localRole: .client, localContentLength: _, remoteContentLength: _, localWindow: _, remoteWindow: _), + .halfClosedRemoteLocalActive(localRole: .client, initiatedBy: _, localContentLength: _, localWindow: _), + .halfClosedRemoteLocalActive(localRole: .server, initiatedBy: .server, localContentLength: _, localWindow: _): + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } + + mutating func receivePushPromise(headers: HPACKHeaders, validateHeaderBlock: Bool) -> StateMachineResultWithStreamEffect { + // We can receive PUSH_PROMISE frames in the following states: + // + // - fullyOpen when we are a client. In this case we assert that the stream was initiated by us. + // - halfOpenLocalPeerIdle, which only clients can enter on streams they initiated. + // - halfClosedLocalPeerIdle, which only clients can enter on streams they initiated. + // - halfClosedLocalPeerActive, when we are a client, and when the stream was initiated by us. + // + // RFC 7540 § 6.6 forbids receiving PUSH_PROMISE frames on remotely-initiated streams. + switch self.state { + case .fullyOpen(localRole: .client, localContentLength: _, remoteContentLength: _, localWindow: _, remoteWindow: _), + .halfOpenLocalPeerIdle(localWindow: _, localContentLength: _, remoteWindow: _), + .halfClosedLocalPeerIdle(remoteWindow: _), + .halfClosedLocalPeerActive(localRole: .client, initiatedBy: .client, remoteContentLength: _, remoteWindow: _): + return self.processRequestHeaders(headers, validateHeaderBlock: validateHeaderBlock, targetState: self.state, targetEffect: nil) + + // Receiving a PUSH_PROMISE frame outside any of these states is a stream error of type PROTOCOL_ERROR. + // Authors note: I cannot find a citation for this in RFC 7540, but this seems a sensible choice. + case .idle, .reservedLocal, .reservedRemote, .halfClosedRemoteLocalIdle, + .halfClosedRemoteLocalActive, .halfOpenRemoteLocalIdle, .closed, + .fullyOpen(localRole: .server, localContentLength: _, remoteContentLength: _, localWindow: _, remoteWindow: _), + .halfClosedLocalPeerActive(localRole: .server, initiatedBy: _, remoteContentLength: _, remoteWindow: _), + .halfClosedLocalPeerActive(localRole: .client, initiatedBy: .server, remoteContentLength: _, remoteWindow: _): + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } + + mutating func sendWindowUpdate(windowIncrement: UInt32) -> StateMachineResultWithStreamEffect { + let windowEffect: StreamStateChange + + do { + // RFC 7540 does not limit the states in which WINDOW_UDPATE frames can be sent. For this reason we need to be + // fairly conservative about applying limits. In essence, we allow sending WINDOW_UPDATE frames in all but the + // following states: + // + // - idle, because the stream hasn't been created yet so the stream ID is invalid + // - reservedLocal, because the remote peer will never be able to send data + // - halfClosedRemoteLocalIdle and halfClosedRemoteLocalActive, because the remote peer has sent END_STREAM and + // can send no further data + // - closed, because the entire stream is closed now + switch self.state { + case .reservedRemote(remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .reservedRemote(remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + + case .halfOpenLocalPeerIdle(localWindow: let localWindow, localContentLength: let localContentLength, remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .halfOpenRemoteLocalIdle(localWindow: let localWindow, remoteContentLength: let remoteContentLength, remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .fullyOpen(localRole: let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: let localWindow, remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .halfClosedLocalPeerIdle(remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .halfClosedLocalPeerIdle(remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + + case .halfClosedLocalPeerActive(localRole: let localRole, initiatedBy: let initiatedBy, remoteContentLength: let remoteContentLength, remoteWindow: var remoteWindow): + try remoteWindow.windowUpdate(by: windowIncrement) + self.state = .halfClosedLocalPeerActive(localRole: localRole, initiatedBy: initiatedBy, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: nil, remoteStreamWindowSize: Int(remoteWindow))) + + case .idle, .reservedLocal, .halfClosedRemoteLocalIdle, .halfClosedRemoteLocalActive, .closed: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.InvalidFlowControlWindowSize { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.InvalidWindowIncrementSize { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + + return .init(result: .succeed, effect: windowEffect) + } + + mutating func receiveWindowUpdate(windowIncrement: UInt32) -> StateMachineResultWithStreamEffect { + let windowEffect: StreamStateChange? + + do { + // RFC 7540 does not limit the states in which WINDOW_UDPATE frames can be received. For this reason we need to be + // fairly conservative about applying limits. In essence, we allow receiving WINDOW_UPDATE frames in all but the + // following states: + // + // - idle, because the stream hasn't been created yet so the stream ID is invalid + // - reservedRemote, because we will never be able to send data so it's silly to manipulate our flow control window + // - closed, because the entire stream is closed now + // + // Note that, unlike with sending, we allow receiving window update frames when we are half-closed. This is because + // it is possible that those frames may have been in flight when we were closing the stream, and so we shouldn't cause + // the stream to explode simply for that reason. In this case, we just ignore the data. + switch self.state { + case .reservedLocal(localWindow: var localWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .reservedLocal(localWindow: localWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + + case .halfOpenLocalPeerIdle(localWindow: var localWindow, localContentLength: let localContentLength, remoteWindow: let remoteWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .halfOpenRemoteLocalIdle(localWindow: var localWindow, remoteContentLength: let remoteContentLength, remoteWindow: let remoteWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .fullyOpen(localRole: let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: var localWindow, remoteWindow: let remoteWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: Int(remoteWindow))) + + case .halfClosedRemoteLocalIdle(localWindow: var localWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .halfClosedRemoteLocalIdle(localWindow: localWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + + case .halfClosedRemoteLocalActive(localRole: let localRole, initiatedBy: let initiatedBy, localContentLength: let localContentLength, localWindow: var localWindow): + try localWindow.windowUpdate(by: windowIncrement) + self.state = .halfClosedRemoteLocalActive(localRole: localRole, initiatedBy: initiatedBy, localContentLength: localContentLength, localWindow: localWindow) + windowEffect = .windowSizeChange(.init(streamID: self.streamID, localStreamWindowSize: Int(localWindow), remoteStreamWindowSize: nil)) + + case .halfClosedLocalPeerIdle, .halfClosedLocalPeerActive: + // No-op, see above + windowEffect = nil + + case .idle, .reservedRemote, .closed: + return .init(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + } catch let error where error is NIOHTTP2Errors.InvalidFlowControlWindowSize { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .flowControlError), effect: nil) + } catch let error where error is NIOHTTP2Errors.InvalidWindowIncrementSize { + return .init(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } catch { + preconditionFailure("Unexpected error: \(error)") + } + + return .init(result: .succeed, effect: windowEffect) + } + + mutating func sendRstStream(reason: HTTP2ErrorCode) -> StateMachineResultWithStreamEffect { + // We can send RST_STREAM frames in all states, including idle. We allow it in idle because errors may be occurred when receiving a stream opening + // frame e.g. request headers. + self.state = .closed(reason: reason) + return .init(result: .succeed, effect: .streamClosed(.init(streamID: self.streamID, reason: reason))) + } + + mutating func receiveRstStream(reason: HTTP2ErrorCode) -> StateMachineResultWithStreamEffect { + // We can receive RST_STREAM frames in any state but idle. + if case .idle = self.state { + return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.badStreamStateTransition(from: NIOHTTP2StreamState.get(self.state)), type: .protocolError), effect: nil) + } + + self.state = .closed(reason: reason) + return .init(result: .succeed, effect: .streamClosed(.init(streamID: self.streamID, reason: reason))) + } + + /// The local value of SETTINGS_INITIAL_WINDOW_SIZE has been changed, and the change has been ACKed. + /// + /// This change causes the remote flow control window to be resized. + mutating func localInitialWindowSizeChanged(by change: Int32) throws { + switch self.state { + case .idle(localRole: let role, localWindow: let localWindow, remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .idle(localRole: role, localWindow: localWindow, remoteWindow: remoteWindow) + + case .reservedRemote(remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .reservedRemote(remoteWindow: remoteWindow) + + case .halfOpenLocalPeerIdle(localWindow: let localWindow, localContentLength: let localContentLength, remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + + case .halfOpenRemoteLocalIdle(localWindow: let localWindow, remoteContentLength: let remoteContentLength, remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + + case .fullyOpen(localRole: let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: let localWindow, remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + + case .halfClosedLocalPeerIdle(remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .halfClosedLocalPeerIdle(remoteWindow: remoteWindow) + + case .halfClosedLocalPeerActive(localRole: let localRole, initiatedBy: let initiatedBy, remoteContentLength: let remoteContentLength, remoteWindow: var remoteWindow): + try remoteWindow.initialSizeChanged(by: change) + self.state = .halfClosedLocalPeerActive(localRole: localRole, initiatedBy: initiatedBy, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + + case .reservedLocal, .halfClosedRemoteLocalIdle, .halfClosedRemoteLocalActive: + // In these states the remote side of this stream is closed and will never be open, so its flow control window is not relevant. + // This is a no-op. + break + + case .closed: + // This should never occur. + preconditionFailure("Updated window of a closed stream.") + } + } + + /// The remote value of SETTINGS_INITIAL_WINDOW_SIZE has been changed. + /// + /// This change causes the local flow control window to be resized. + mutating func remoteInitialWindowSizeChanged(by change: Int32) throws { + switch self.state { + case .idle(localRole: let role, localWindow: var localWindow, remoteWindow: let remoteWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .idle(localRole: role, localWindow: localWindow, remoteWindow: remoteWindow) + + case .reservedLocal(localWindow: var localWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .reservedLocal(localWindow: localWindow) + + case .halfOpenLocalPeerIdle(localWindow: var localWindow, localContentLength: let localContentLength, remoteWindow: let remoteWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .halfOpenLocalPeerIdle(localWindow: localWindow, localContentLength: localContentLength, remoteWindow: remoteWindow) + + case .halfOpenRemoteLocalIdle(localWindow: var localWindow, remoteContentLength: let remoteContentLength, remoteWindow: let remoteWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .halfOpenRemoteLocalIdle(localWindow: localWindow, remoteContentLength: remoteContentLength, remoteWindow: remoteWindow) + + case .fullyOpen(localRole: let localRole, localContentLength: let localContentLength, remoteContentLength: let remoteContentLength, localWindow: var localWindow, remoteWindow: let remoteWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .fullyOpen(localRole: localRole, localContentLength: localContentLength, remoteContentLength: remoteContentLength, localWindow: localWindow, remoteWindow: remoteWindow) + + case .halfClosedRemoteLocalIdle(localWindow: var localWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .halfClosedRemoteLocalIdle(localWindow: localWindow) + + case .halfClosedRemoteLocalActive(localRole: let localRole, initiatedBy: let initiatedBy, localContentLength: let localContentLength, localWindow: var localWindow): + try localWindow.initialSizeChanged(by: change) + self.state = .halfClosedRemoteLocalActive(localRole: localRole, initiatedBy: initiatedBy, localContentLength: localContentLength, localWindow: localWindow) + + case .reservedRemote, .halfClosedLocalPeerIdle, .halfClosedLocalPeerActive: + // In these states the local side of this stream is closed and will never be open, so its flow control window is not relevant. + // This is a no-op. + break + + case .closed: + // This should never occur. + preconditionFailure("Updated window of a closed stream.") + } + } +} + +// MARK:- Functions for handling headers frames. +extension HTTP2StreamStateMachine { + /// Validate that the request headers meet the requirements of RFC 7540. If they do, + /// transitions to the target state. + private mutating func processRequestHeaders(_ headers: HPACKHeaders, validateHeaderBlock: Bool, targetState target: State, targetEffect effect: StreamStateChange?) -> StateMachineResultWithStreamEffect { + if validateHeaderBlock { + do { + try headers.validateRequestBlock() + } catch { + return StateMachineResultWithStreamEffect(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } + } + + self.state = target + return StateMachineResultWithStreamEffect(result: .succeed, effect: effect) + } + + /// Validate that the response headers meet the requirements of RFC 7540. Also characterises + /// them to check whether the headers are informational or final, and if the headers are + /// valid and correspond to a final response, transitions to the appropriate target state. + private mutating func processResponseHeaders(_ headers: HPACKHeaders, validateHeaderBlock: Bool, targetStateIfFinal finalState: State, targetEffectIfFinal finalEffect: StreamStateChange?) -> StateMachineResultWithStreamEffect { + if validateHeaderBlock { + do { + try headers.validateResponseBlock() + } catch { + return StateMachineResultWithStreamEffect(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } + } + + // The barest minimum of functionality is to distinguish final and non-final headers, so we do that for now. + if !headers.isInformationalResponse { + // Non-informational responses cause state transitions. + self.state = finalState + return StateMachineResultWithStreamEffect(result: .succeed, effect: finalEffect) + } else { + return StateMachineResultWithStreamEffect(result: .succeed, effect: nil) + } + } + + /// Validates that the trailers meet the requirements of RFC 7540. If they do, transitions to the + /// target final state. + private mutating func processTrailers(_ headers: HPACKHeaders, validateHeaderBlock: Bool, isEndStreamSet endStream: Bool, targetState target: State, targetEffect effect: StreamStateChange?) -> StateMachineResultWithStreamEffect { + if validateHeaderBlock { + do { + try headers.validateTrailersBlock() + } catch { + return StateMachineResultWithStreamEffect(result: .streamError(streamID: self.streamID, underlyingError: error, type: .protocolError), effect: nil) + } + } + + // End stream must be set on trailers. + guard endStream else { + return StateMachineResultWithStreamEffect(result: .streamError(streamID: self.streamID, underlyingError: NIOHTTP2Errors.trailersWithoutEndStream(streamID: self.streamID), type: .protocolError), effect: nil) + } + + self.state = target + return StateMachineResultWithStreamEffect(result: .succeed, effect: effect) + } +} + +extension HTTP2StreamStateMachine: PerStreamData { } + + +private extension HPACKHeaders { + /// Whether this `HPACKHeaders` corresponds to a final response or not. + /// + /// This property is only valid if called on a response header block. If the :status header + /// is not present, this will return "false" + var isInformationalResponse: Bool { + return self.first { $0.name == ":status" }?.value.first == "1" + } +} + +/// A state of a `HTTP2StreamStateMachine`. This copy in effect mirrors `HTTP2StreamStateMachine.state` but without associated values. +public struct NIOHTTP2StreamState: Hashable, CustomStringConvertible, NIOSendable { + private enum State { + case idle + case reservedRemote + case reservedLocal + case halfOpenLocalPeerIdle + case halfOpenRemoteLocalIdle + case fullyOpen + case halfClosedLocalPeerIdle + case halfClosedLocalPeerActive + case halfClosedRemoteLocalIdle + case halfClosedRemoteLocalActive + case closed + } + + private var state: State + + private init(state: State) { + self.state = state + } + + public var description: String { + return "\(state)" + } + + public static let idle = NIOHTTP2StreamState(state: .idle) + public static let reservedRemote = NIOHTTP2StreamState(state: .reservedRemote) + public static let reservedLocal = NIOHTTP2StreamState(state: .reservedLocal) + public static let halfOpenLocalPeerIdle = NIOHTTP2StreamState(state: .halfOpenLocalPeerIdle) + public static let halfOpenRemoteLocalIdle = NIOHTTP2StreamState(state: .halfOpenRemoteLocalIdle) + public static let fullyOpen = NIOHTTP2StreamState(state: .fullyOpen) + public static let halfClosedLocalPeerIdle = NIOHTTP2StreamState(state: .halfClosedLocalPeerIdle) + public static let halfClosedLocalPeerActive = NIOHTTP2StreamState(state: .halfClosedLocalPeerActive) + public static let halfClosedRemoteLocalIdle = NIOHTTP2StreamState(state: .halfClosedRemoteLocalIdle) + public static let halfClosedRemoteLocalActive = NIOHTTP2StreamState(state: .halfClosedRemoteLocalActive) + public static let closed = NIOHTTP2StreamState(state: .closed) + + fileprivate static func get(_ state: HTTP2StreamStateMachine.State) -> NIOHTTP2StreamState { + switch state { + case .idle: return idle + case .reservedRemote: return reservedRemote + case .reservedLocal: return reservedLocal + case .halfOpenLocalPeerIdle: return halfOpenLocalPeerIdle + case .halfOpenRemoteLocalIdle: return halfOpenRemoteLocalIdle + case .fullyOpen: return fullyOpen + case .halfClosedLocalPeerIdle: return halfClosedLocalPeerIdle + case .halfClosedLocalPeerActive: return halfClosedLocalPeerActive + case .halfClosedRemoteLocalIdle: return halfClosedRemoteLocalIdle + case .halfClosedRemoteLocalActive: return halfClosedRemoteLocalActive + case .closed: return closed + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/WatermarkedFlowController.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/WatermarkedFlowController.swift new file mode 100644 index 00000000..726b8188 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOHTTP2/Sources/NIOHTTP2/WatermarkedFlowController.swift @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + + +/// Keeps track of whether or not a `Channel` should be able to write based on watermarks. +/// +/// A `WatermarkedFlowController` is a straightforward object that keeps track of +/// the number of to-be-written bytes in a `Channel`, as well as the trajectory of those +/// bytes. This allows a `Channel` to buffer a certain number of bytes before flipping its +/// writability state, and then allows draining to a different watermark before the state flips +/// again. +/// +/// The goal here is to constrain the number of resources allocated for a task, while also ensuring +/// that `Channel` writability state doesn't flick between writable and not-writable rapidly. This produces +/// a more stable system that responds better to changes in the underlying network. +/// +/// The controller keeps track of the number of pending bytes (that is, bytes that have been written but not yet +/// reached the network), as well as a high and a low watermark. If the number of pending bytes exceeds the high +/// watermark, the writability state changes to false. If the number of pending bytes is below the low watermark, +/// the writability state changes to true. +/// +/// If the number of pending bytes is between the two watermarks, the writability state remains in whatever the previous +/// state was. This essentially causes a "lag" in the change of writability state: once the state flips, it will take a while +/// for the number of pending bytes to cross the other threshold to cause the state to flip again. +struct WatermarkedFlowController { + /// The "high" water mark. If the number of pending bytes exceeds this number, the + /// writability state will change to "false". + private let highWatermark: UInt + + /// The "low" watermark. If the number of pending bytes is lower than this number, the + /// writability state will change to "true". + private let lowWatermark: UInt + + /// The number of pending bytes waiting to be written to the network. + private var pendingBytes: UInt + + /// Whether the `Channel` should consider itself writable or not. + internal private(set) var isWritable: Bool + + internal init(highWatermark: Int, lowWatermark: Int) { + precondition(lowWatermark < highWatermark, "Low watermark \(lowWatermark) exceeds or meets High watermark \(highWatermark)") + + self.highWatermark = UInt(highWatermark) + self.lowWatermark = UInt(lowWatermark) + self.pendingBytes = 0 + self.isWritable = true + } +} + + +extension WatermarkedFlowController { + /// Notifies the flow controller that we have buffered some bytes to send to the network. + mutating func bufferedBytes(_ bufferedBytes: Int) { + self.pendingBytes += UInt(bufferedBytes) + if self.pendingBytes > self.highWatermark { + self.isWritable = false + } + } + + /// Notifies the flow controller that we have successfully written some bytes to the network. + mutating func wroteBytes(_ writtenBytes: Int) { + self.pendingBytes -= UInt(writtenBytes) + if self.pendingBytes < self.lowWatermark { + self.isWritable = true + } + } +} + + +extension WatermarkedFlowController: Equatable { } + + +extension WatermarkedFlowController: CustomDebugStringConvertible { + var debugDescription: String { + return "WatermarkedFlowController(highWatermark: \(self.highWatermark), lowWatermark: \(self.lowWatermark), pendingBytes: \(self.pendingBytes), isWritable: \(self.isWritable))" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPICommon.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPICommon.swift new file mode 100644 index 00000000..e79aec61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPICommon.swift @@ -0,0 +1,324 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +#if os(Windows) +import ucrt + +import let WinSDK.INVALID_SOCKET + +import let WinSDK.IPPROTO_IP +import let WinSDK.IPPROTO_IPV6 +import let WinSDK.IPPROTO_TCP + +import let WinSDK.IP_ADD_MEMBERSHIP +import let WinSDK.IP_DROP_MEMBERSHIP +import let WinSDK.IP_MULTICAST_IF +import let WinSDK.IP_MULTICAST_LOOP +import let WinSDK.IP_MULTICAST_TTL +import let WinSDK.IP_RECVTOS +import let WinSDK.IPV6_JOIN_GROUP +import let WinSDK.IPV6_LEAVE_GROUP +import let WinSDK.IPV6_MULTICAST_HOPS +import let WinSDK.IPV6_MULTICAST_IF +import let WinSDK.IPV6_MULTICAST_LOOP +import let WinSDK.IPV6_RECVTCLASS +import let WinSDK.IPV6_V6ONLY + +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 +import let WinSDK.AF_UNIX + +import let WinSDK.PF_INET +import let WinSDK.PF_INET6 +import let WinSDK.PF_UNIX + +import let WinSDK.SOCK_DGRAM +import let WinSDK.SOCK_STREAM + +import let WinSDK.SO_ERROR +import let WinSDK.SO_KEEPALIVE +import let WinSDK.SO_LINGER +import let WinSDK.SO_RCVBUF +import let WinSDK.SO_RCVTIMEO +import let WinSDK.SO_REUSEADDR + +import let WinSDK.SOL_SOCKET + +import let WinSDK.TCP_NODELAY + +import struct WinSDK.SOCKET + +import struct WinSDK.WSACMSGHDR +import struct WinSDK.WSAMSG + +import struct WinSDK.socklen_t + +internal typealias msghdr = WSAMSG +internal typealias cmsghdr = WSACMSGHDR +#endif + +protocol _SocketShutdownProtocol { + var cValue: CInt { get } +} + +internal enum Shutdown: _SocketShutdownProtocol { + case RD + case WR + case RDWR +} + +extension NIOBSDSocket { +#if os(Windows) + internal static let invalidHandle: Handle = INVALID_SOCKET +#else + internal static let invalidHandle: Handle = -1 +#endif +} + +extension NIOBSDSocket { + /// Specifies the type of socket. + internal struct SocketType: RawRepresentable { + public typealias RawValue = CInt + public var rawValue: RawValue + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + } +} + +extension NIOBSDSocket.SocketType: Equatable { +} + +extension NIOBSDSocket.SocketType: Hashable { +} + +// Socket Types +extension NIOBSDSocket.SocketType { + /// Supports datagrams, which are connectionless, unreliable messages of a + /// fixed (typically small) maximum length. + #if os(Linux) + internal static let datagram: NIOBSDSocket.SocketType = + NIOBSDSocket.SocketType(rawValue: CInt(SOCK_DGRAM.rawValue)) + #else + internal static let datagram: NIOBSDSocket.SocketType = + NIOBSDSocket.SocketType(rawValue: SOCK_DGRAM) + #endif + + /// Supports reliable, two-way, connection-based byte streams without + /// duplication of data and without preservation of boundaries. + #if os(Linux) + internal static let stream: NIOBSDSocket.SocketType = + NIOBSDSocket.SocketType(rawValue: CInt(SOCK_STREAM.rawValue)) + #else + internal static let stream: NIOBSDSocket.SocketType = + NIOBSDSocket.SocketType(rawValue: SOCK_STREAM) + #endif +} + +// IPv4 Options +extension NIOBSDSocket.Option { + /// Request that we are passed type of service details when receiving + /// datagrams. + /// + /// Not public as the way to request this is to use + /// `ChannelOptions.explicitCongestionNotification` which works for both + /// IPv4 and IPv6. + static let ip_recv_tos: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IP_RECVTOS) + + /// Request that we are passed destination address and the receiving interface index when + /// receiving datagrams. + /// + /// This option is not public as the way to request this is to use + /// `ChannelOptions.receivePacketInfo` which works for both + /// IPv4 and IPv6. + static let ip_recv_pktinfo: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: Posix.IP_RECVPKTINFO) +} + +// IPv6 Options +extension NIOBSDSocket.Option { + /// Request that we are passed traffic class details when receiving + /// datagrams. + /// + /// Not public as the way to request this is to use + /// `ChannelOptions.explicitCongestionNotification` which works for both + /// IPv4 and IPv6. + static let ipv6_recv_tclass: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: IPV6_RECVTCLASS) + + /// Request that we are passed destination address and the receiving interface index when + /// receiving datagrams. + /// + /// This option is not public as the way to request this is to use + /// `ChannelOptions.receivePacketInfo` which works for both + /// IPv4 and IPv6. + static let ipv6_recv_pktinfo: NIOBSDSocket.Option = + NIOBSDSocket.Option(rawValue: Posix.IPV6_RECVPKTINFO) +} + +/// This protocol defines the methods that are expected to be found on +/// `NIOBSDSocket`. While defined as a protocol there is no expectation that any +/// object other than `NIOBSDSocket` will implement this protocol: instead, this +/// protocol acts as a reference for what new supported operating systems must +/// implement. +protocol _BSDSocketProtocol { + static func accept(socket s: NIOBSDSocket.Handle, + address addr: UnsafeMutablePointer?, + address_len addrlen: UnsafeMutablePointer?) throws -> NIOBSDSocket.Handle? + + static func bind(socket s: NIOBSDSocket.Handle, + address addr: UnsafePointer, + address_len namelen: socklen_t) throws + + static func close(socket s: NIOBSDSocket.Handle) throws + + static func connect(socket s: NIOBSDSocket.Handle, + address name: UnsafePointer, + address_len namelen: socklen_t) throws -> Bool + + static func getpeername(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws + + static func getsockname(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws + + static func getsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeMutableRawPointer, + option_len optlen: UnsafeMutablePointer) throws + + static func listen(socket s: NIOBSDSocket.Handle, backlog: CInt) throws + + static func recv(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeMutableRawPointer, + length len: size_t) throws -> IOResult + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func recvmsg(socket: NIOBSDSocket.Handle, + msgHdr: UnsafeMutablePointer, flags: CInt) + throws -> IOResult + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func sendmsg(socket: NIOBSDSocket.Handle, + msgHdr: UnsafePointer, flags: CInt) + throws -> IOResult + + static func send(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeRawPointer, + length len: size_t) throws -> IOResult + + static func setsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeRawPointer, + option_len optlen: socklen_t) throws + + static func shutdown(socket: NIOBSDSocket.Handle, how: Shutdown) throws + + static func socket(domain af: NIOBSDSocket.ProtocolFamily, + type: NIOBSDSocket.SocketType, + `protocol`: CInt) throws -> NIOBSDSocket.Handle + + static func recvmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, + flags: CInt, + timeout: UnsafeMutablePointer?) throws -> IOResult + + static func sendmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, + flags: CInt) throws -> IOResult + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func pread(socket: NIOBSDSocket.Handle, + pointer: UnsafeMutableRawPointer, + size: size_t, + offset: off_t) throws -> IOResult + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func pwrite(socket: NIOBSDSocket.Handle, + pointer: UnsafeRawPointer, + size: size_t, + offset: off_t) throws -> IOResult + +#if !os(Windows) + // NOTE: We do not support this on Windows as WSAPoll behaves differently + // from poll with reporting of failed connections (Connect Report 309411), + // which recommended that you use NetAPI instead. + // + // This is safe to exclude as this is a testing-only API. + static func poll(fds: UnsafeMutablePointer, nfds: nfds_t, + timeout: CInt) throws -> CInt +#endif + + static func sendfile(socket s: NIOBSDSocket.Handle, + fd: CInt, + offset: off_t, + len: off_t) throws -> IOResult + + // MARK: non-BSD APIs added by NIO + + static func setNonBlocking(socket: NIOBSDSocket.Handle) throws + + static func cleanupUnixDomainSocket(atPath path: String) throws +} + +/// If this extension is hitting a compile error, your platform is missing one +/// of the functions defined above! +extension NIOBSDSocket: _BSDSocketProtocol { } + +/// This protocol defines the methods that are expected to be found on +/// `NIOBSDControlMessage`. While defined as a protocol there is no expectation +/// that any object other than `NIOBSDControlMessage` will implement this +/// protocol: instead, this protocol acts as a reference for what new supported +/// operating systems must implement. +protocol _BSDSocketControlMessageProtocol { + static func firstHeader(inside msghdr: UnsafePointer) + -> UnsafeMutablePointer? + + static func nextHeader(inside msghdr: UnsafeMutablePointer, + after: UnsafeMutablePointer) + -> UnsafeMutablePointer? + + static func data(for header: UnsafePointer) + -> UnsafeRawBufferPointer? + + static func data(for header: UnsafeMutablePointer) + -> UnsafeMutableRawBufferPointer? + + static func length(payloadSize: size_t) -> size_t + + static func space(payloadSize: size_t) -> size_t +} + +/// If this extension is hitting a compile error, your platform is missing one +/// of the functions defined above! +enum NIOBSDSocketControlMessage: _BSDSocketControlMessageProtocol { } + +/// The requested UDS path exists and has wrong type (not a socket). +public struct UnixDomainSocketPathWrongType: Error {} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIPosix.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIPosix.swift new file mode 100644 index 00000000..52ba498a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIPosix.swift @@ -0,0 +1,270 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +#if os(Linux) || os(Android) || os(FreeBSD) || os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + +extension Shutdown { + internal var cValue: CInt { + switch self { + case .RD: + return CInt(Posix.SHUT_RD) + case .WR: + return CInt(Posix.SHUT_WR) + case .RDWR: + return CInt(Posix.SHUT_RDWR) + } + } +} + +// MARK: Implementation of _BSDSocketProtocol for POSIX systems +extension NIOBSDSocket { + static func accept(socket s: NIOBSDSocket.Handle, + address addr: UnsafeMutablePointer?, + address_len addrlen: UnsafeMutablePointer?) throws -> NIOBSDSocket.Handle? { + return try Posix.accept(descriptor: s, addr: addr, len: addrlen) + } + + static func bind(socket s: NIOBSDSocket.Handle, + address addr: UnsafePointer, + address_len namelen: socklen_t) throws { + return try Posix.bind(descriptor: s, ptr: addr, bytes: Int(namelen)) + } + + static func close(socket s: NIOBSDSocket.Handle) throws { + return try Posix.close(descriptor: s) + } + + static func connect(socket s: NIOBSDSocket.Handle, + address name: UnsafePointer, + address_len namelen: socklen_t) throws -> Bool { + return try Posix.connect(descriptor: s, addr: name, size: namelen) + } + + static func getpeername(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws { + return try Posix.getpeername(socket: s, address: name, addressLength: namelen) + } + + static func getsockname(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws { + return try Posix.getsockname(socket: s, address: name, addressLength: namelen) + } + + static func getsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeMutableRawPointer, + option_len optlen: UnsafeMutablePointer) throws { + return try Posix.getsockopt(socket: socket, + level: level.rawValue, + optionName: optname.rawValue, + optionValue: optval, + optionLen: optlen) + } + + static func listen(socket s: NIOBSDSocket.Handle, backlog: CInt) throws { + return try Posix.listen(descriptor: s, backlog: backlog) + } + + static func recv(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeMutableRawPointer, + length len: size_t) throws -> IOResult { + return try Posix.read(descriptor: s, pointer: buf, size: len) + } + + static func recvmsg(socket: NIOBSDSocket.Handle, + msgHdr: UnsafeMutablePointer, flags: CInt) + throws -> IOResult { + return try Posix.recvmsg(descriptor: socket, msgHdr: msgHdr, flags: flags) + } + + static func sendmsg(socket: NIOBSDSocket.Handle, + msgHdr: UnsafePointer, flags: CInt) + throws -> IOResult { + return try Posix.sendmsg(descriptor: socket, msgHdr: msgHdr, flags: flags) + } + + static func send(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeRawPointer, + length len: size_t) throws -> IOResult { + return try Posix.write(descriptor: s, pointer: buf, size: len) + } + + static func setsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeRawPointer, + option_len optlen: socklen_t) throws { + return try Posix.setsockopt(socket: socket, + level: level.rawValue, + optionName: optname.rawValue, + optionValue: optval, + optionLen: optlen) + } + + static func shutdown(socket: NIOBSDSocket.Handle, how: Shutdown) throws { + return try Posix.shutdown(descriptor: socket, how: how) + } + + static func socket(domain af: NIOBSDSocket.ProtocolFamily, + type: NIOBSDSocket.SocketType, + `protocol`: CInt) throws -> NIOBSDSocket.Handle { + return try Posix.socket(domain: af, type: type, protocol: `protocol`) + } + + static func recvmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, + flags: CInt, + timeout: UnsafeMutablePointer?) throws -> IOResult { + return try Posix.recvmmsg(sockfd: socket, + msgvec: msgvec, + vlen: vlen, + flags: flags, + timeout: timeout) + } + + static func sendmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, + flags: CInt) throws -> IOResult { + return try Posix.sendmmsg(sockfd: socket, + msgvec: msgvec, + vlen: vlen, + flags: flags) + } + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func pread(socket: NIOBSDSocket.Handle, + pointer: UnsafeMutableRawPointer, + size: size_t, + offset: off_t) throws -> IOResult { + return try Posix.pread(descriptor: socket, + pointer: pointer, + size: size, + offset: offset) + } + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + static func pwrite(socket: NIOBSDSocket.Handle, + pointer: UnsafeRawPointer, + size: size_t, + offset: off_t) throws -> IOResult { + return try Posix.pwrite(descriptor: socket, pointer: pointer, size: size, offset: offset) + } + + static func poll(fds: UnsafeMutablePointer, + nfds: nfds_t, + timeout: CInt) throws -> CInt { + return try Posix.poll(fds: fds, nfds: nfds, timeout: timeout) + } + + static func sendfile(socket s: NIOBSDSocket.Handle, + fd: CInt, + offset: off_t, + len: off_t) throws -> IOResult { + return try Posix.sendfile(descriptor: s, fd: fd, offset: offset, count: size_t(len)) + } + + static func setNonBlocking(socket: NIOBSDSocket.Handle) throws { + return try Posix.setNonBlocking(socket: socket) + } + + static func cleanupUnixDomainSocket(atPath path: String) throws { + do { + var sb: stat = stat() + try withUnsafeMutablePointer(to: &sb) { sbPtr in + try Posix.stat(pathname: path, outStat: sbPtr) + } + + // Only unlink the existing file if it is a socket + if sb.st_mode & S_IFSOCK == S_IFSOCK { + try Posix.unlink(pathname: path) + } else { + throw UnixDomainSocketPathWrongType() + } + } catch let err as IOError { + // If the filepath did not exist, we consider it cleaned up + if err.errnoCode == ENOENT { + return + } + throw err + } + } +} + +#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) +import CNIODarwin +private let CMSG_FIRSTHDR = CNIODarwin_CMSG_FIRSTHDR +private let CMSG_NXTHDR = CNIODarwin_CMSG_NXTHDR +private let CMSG_DATA = CNIODarwin_CMSG_DATA +private let CMSG_DATA_MUTABLE = CNIODarwin_CMSG_DATA_MUTABLE +private let CMSG_SPACE = CNIODarwin_CMSG_SPACE +private let CMSG_LEN = CNIODarwin_CMSG_LEN +#else +import CNIOLinux +private let CMSG_FIRSTHDR = CNIOLinux_CMSG_FIRSTHDR +private let CMSG_NXTHDR = CNIOLinux_CMSG_NXTHDR +private let CMSG_DATA = CNIOLinux_CMSG_DATA +private let CMSG_DATA_MUTABLE = CNIOLinux_CMSG_DATA_MUTABLE +private let CMSG_SPACE = CNIOLinux_CMSG_SPACE +private let CMSG_LEN = CNIOLinux_CMSG_LEN +#endif + +// MARK: _BSDSocketControlMessageProtocol implementation +extension NIOBSDSocketControlMessage { + static func firstHeader(inside msghdr: UnsafePointer) + -> UnsafeMutablePointer? { + return CMSG_FIRSTHDR(msghdr) + } + + static func nextHeader(inside msghdr: UnsafeMutablePointer, + after: UnsafeMutablePointer) + -> UnsafeMutablePointer? { + return CMSG_NXTHDR(msghdr, after) + } + + static func data(for header: UnsafePointer) + -> UnsafeRawBufferPointer? { + let data = CMSG_DATA(header) + let length = + size_t(header.pointee.cmsg_len) - NIOBSDSocketControlMessage.length(payloadSize: 0) + return UnsafeRawBufferPointer(start: data, count: Int(length)) + } + + static func data(for header: UnsafeMutablePointer) + -> UnsafeMutableRawBufferPointer? { + let data = CMSG_DATA_MUTABLE(header) + let length = + size_t(header.pointee.cmsg_len) - NIOBSDSocketControlMessage.length(payloadSize: 0) + return UnsafeMutableRawBufferPointer(start: data, count: Int(length)) + } + + static func length(payloadSize: size_t) -> size_t { + return CMSG_LEN(payloadSize) + } + + static func space(payloadSize: size_t) -> size_t { + return CMSG_SPACE(payloadSize) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIWindows.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIWindows.swift new file mode 100644 index 00000000..c2502164 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BSDSocketAPIWindows.swift @@ -0,0 +1,535 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) +import ucrt + +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 +import let WinSDK.AF_UNIX + +import let WinSDK.FIONBIO + +import let WinSDK.INET_ADDRSTRLEN +import let WinSDK.INET6_ADDRSTRLEN + +import let WinSDK.INVALID_HANDLE_VALUE +import let WinSDK.INVALID_SOCKET + +import let WinSDK.IPPROTO_IP +import let WinSDK.IPPROTO_IPV6 +import let WinSDK.IPPROTO_TCP + +import let WinSDK.IP_ADD_MEMBERSHIP +import let WinSDK.IP_DROP_MEMBERSHIP +import let WinSDK.IP_MULTICAST_IF +import let WinSDK.IP_MULTICAST_LOOP +import let WinSDK.IP_MULTICAST_TTL + +import let WinSDK.IPV6_JOIN_GROUP +import let WinSDK.IPV6_LEAVE_GROUP +import let WinSDK.IPV6_MULTICAST_HOPS +import let WinSDK.IPV6_MULTICAST_IF +import let WinSDK.IPV6_MULTICAST_LOOP +import let WinSDK.IPV6_V6ONLY + +import let WinSDK.PF_INET +import let WinSDK.PF_INET6 +import let WinSDK.PF_UNIX + +import let WinSDK.TCP_NODELAY + +import let WinSDK.SD_BOTH +import let WinSDK.SD_RECEIVE +import let WinSDK.SD_SEND + +import let WinSDK.SO_ERROR +import let WinSDK.SO_KEEPALIVE +import let WinSDK.SO_LINGER +import let WinSDK.SO_RCVBUF +import let WinSDK.SO_RCVTIMEO +import let WinSDK.SO_REUSEADDR +import let WinSDK.SO_REUSE_UNICASTPORT + +import let WinSDK.SOL_SOCKET + +import let WinSDK.SOCK_DGRAM +import let WinSDK.SOCK_STREAM + +import let WinSDK.SOCKET_ERROR + +import let WinSDK.TF_USE_KERNEL_APC + +import func WinSDK.accept +import func WinSDK.bind +import func WinSDK.closesocket +import func WinSDK.connect +import func WinSDK.getpeername +import func WinSDK.getsockname +import func WinSDK.ioctlsocket +import func WinSDK.listen +import func WinSDK.shutdown +import func WinSDK.socket +import func WinSDK.GetLastError +import func WinSDK.ReadFile +import func WinSDK.TransmitFile +import func WinSDK.WriteFile +import func WinSDK.WSAGetLastError +import func WinSDK.WSAIoctl + +import struct WinSDK.socklen_t +import struct WinSDK.u_long +import struct WinSDK.DWORD +import struct WinSDK.HANDLE +import struct WinSDK.LINGER +import struct WinSDK.OVERLAPPED +import struct WinSDK.SOCKADDR +import struct WinSDK.SOCKADDR_IN +import struct WinSDK.SOCKADDR_IN6 +import struct WinSDK.SOCKADDR_UN +import struct WinSDK.SOCKADDR_STORAGE + +import typealias WinSDK.LPFN_WSARECVMSG + +internal typealias sockaddr_in = SOCKADDR_IN +internal typealias sockaddr_in6 = SOCKADDR_IN6 +internal typealias sockaddr_un = SOCKADDR_UN +internal typealias sockaddr_storage = SOCKADDR_STORAGE + +public typealias linger = LINGER + +fileprivate var IOC_IN: DWORD { + 0x8000_0000 +} + +fileprivate var IOC_OUT: DWORD { + 0x4000_0000 +} + +fileprivate var IOC_INOUT: DWORD { + IOC_IN | IOC_OUT +} + +fileprivate var IOC_WS2: DWORD { + 0x0800_0000 +} + +fileprivate func _WSAIORW(_ x: DWORD, _ y: DWORD) -> DWORD { + IOC_INOUT | x | y +} + +fileprivate var SIO_GET_EXTENSION_FUNCTION_POINTER: DWORD { + _WSAIORW(IOC_WS2, 6) +} + +fileprivate var WSAID_WSARECVMSG: _GUID { + _GUID(Data1: 0xf689d7c8, Data2: 0x6f1f, Data3: 0x436b, + Data4: (0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22)) +} + +fileprivate var WSAID_WSASENDMSG: _GUID { + _GUID(Data1: 0xa441e712, Data2: 0x754f, Data3: 0x43ca, + Data4: (0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d)) +} + +// TODO(compnerd) rather than query the `WSARecvMsg` and `WSASendMsg` on each +// message, we should query that and cache the value. This requires +// understanding the lifetime validity of the pointer. +// TODO(compnerd) create a simpler shared wrapper to query the extension +// function from WinSock and de-duplicate the operations in +// `NIOBSDSocketAPI.recvmsg` and `NIOBSDSocketAPI.sendmsg`. + +import CNIOWindows + +extension Shutdown { + internal var cValue: CInt { + switch self { + case .RD: + return WinSDK.SD_RECEIVE + case .WR: + return WinSDK.SD_SEND + case .RDWR: + return WinSDK.SD_BOTH + } + } +} + +// MARK: _BSDSocketProtocol implementation +extension NIOBSDSocket { + @inline(never) + static func accept(socket s: NIOBSDSocket.Handle, + address addr: UnsafeMutablePointer?, + address_len addrlen: UnsafeMutablePointer?) throws -> NIOBSDSocket.Handle? { + let socket: NIOBSDSocket.Handle = WinSDK.accept(s, addr, addrlen) + if socket == WinSDK.INVALID_SOCKET { + throw IOError(winsock: WSAGetLastError(), reason: "accept") + } + return socket + } + + @inline(never) + static func bind(socket s: NIOBSDSocket.Handle, + address addr: UnsafePointer, + address_len namelen: socklen_t) throws { + if WinSDK.bind(s, addr, namelen) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "bind") + } + } + + @inline(never) + static func close(socket s: NIOBSDSocket.Handle) throws { + if WinSDK.closesocket(s) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "close") + } + } + + @inline(never) + static func connect(socket s: NIOBSDSocket.Handle, + address name: UnsafePointer, + address_len namelen: socklen_t) throws -> Bool { + if WinSDK.connect(s, name, namelen) == SOCKET_ERROR { + let iResult = WSAGetLastError() + if iResult == WSAEWOULDBLOCK { return true } + throw IOError(winsock: WSAGetLastError(), reason: "connect") + } + return true + } + + @inline(never) + static func getpeername(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws { + if WinSDK.getpeername(s, name, namelen) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "getpeername") + } + } + + @inline(never) + static func getsockname(socket s: NIOBSDSocket.Handle, + address name: UnsafeMutablePointer, + address_len namelen: UnsafeMutablePointer) throws { + if WinSDK.getsockname(s, name, namelen) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "getsockname") + } + } + + @inline(never) + static func getsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeMutableRawPointer, + option_len optlen: UnsafeMutablePointer) throws { + if CNIOWindows_getsockopt(socket, level.rawValue, optname.rawValue, + optval, optlen) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "getsockopt") + } + } + + @inline(never) + static func listen(socket s: NIOBSDSocket.Handle, backlog: CInt) throws { + if WinSDK.listen(s, backlog) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "listen") + } + } + + @inline(never) + static func recv(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeMutableRawPointer, + length len: size_t) throws -> IOResult { + let iResult: CInt = CNIOWindows_recv(s, buf, CInt(len), 0) + if iResult == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "recv") + } + return .processed(size_t(iResult)) + } + + @inline(never) + static func recvmsg(socket s: NIOBSDSocket.Handle, + msgHdr lpMsg: UnsafeMutablePointer, + flags: CInt) + throws -> IOResult { + // TODO(compnerd) see comment above + var InBuffer = WSAID_WSARECVMSG + var pfnWSARecvMsg: LPFN_WSARECVMSG? + var cbBytesReturned: DWORD = 0 + if WinSDK.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, + &InBuffer, DWORD(MemoryLayout.stride(ofValue: InBuffer)), + &pfnWSARecvMsg, + DWORD(MemoryLayout.stride(ofValue: pfnWSARecvMsg)), + &cbBytesReturned, nil, nil) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "WSAIoctl") + } + + guard let WSARecvMsg = pfnWSARecvMsg else { + throw IOError(windows: DWORD(ERROR_INVALID_FUNCTION), + reason: "recvmsg") + } + + var dwNumberOfBytesRecvd: DWORD = 0 + // FIXME(compnerd) is the socket guaranteed to not be overlapped? + if WSARecvMsg(s, lpMsg, &dwNumberOfBytesRecvd, nil, nil) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "recvmsg") + } + return .processed(size_t(dwNumberOfBytesRecvd)) + } + + @inline(never) + static func sendmsg(socket Handle: NIOBSDSocket.Handle, + msgHdr lpMsg: UnsafePointer, + flags dwFlags: CInt) throws -> IOResult { + // TODO(compnerd) see comment above + var InBuffer = WSAID_WSASENDMSG + var pfnWSASendMsg: LPFN_WSASENDMSG? + var cbBytesReturned: DWORD = 0 + if WinSDK.WSAIoctl(Handle, SIO_GET_EXTENSION_FUNCTION_POINTER, + &InBuffer, DWORD(MemoryLayout.stride(ofValue: InBuffer)), + &pfnWSASendMsg, + DWORD(MemoryLayout.stride(ofValue: pfnWSASendMsg)), + &cbBytesReturned, nil, nil) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "WSAIoctl") + } + + guard let WSASendMsg = pfnWSASendMsg else { + throw IOError(windows: DWORD(ERROR_INVALID_FUNCTION), + reason: "sendmsg") + } + + let lpMsg: LPWSAMSG = UnsafeMutablePointer(mutating: lpMsg) + var NumberOfBytesSent: DWORD = 0 + // FIXME(compnerd) is the socket guaranteed to not be overlapped? + if WSASendMsg(Handle, lpMsg, DWORD(dwFlags), &NumberOfBytesSent, nil, + nil) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "sendmsg") + } + return .processed(size_t(NumberOfBytesSent)) + } + + @inline(never) + static func send(socket s: NIOBSDSocket.Handle, + buffer buf: UnsafeRawPointer, + length len: size_t) throws -> IOResult { + let iResult: CInt = CNIOWindows_send(s, buf, CInt(len), 0) + if iResult == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "send") + } + return .processed(size_t(iResult)) + } + + @inline(never) + static func setsockopt(socket: NIOBSDSocket.Handle, + level: NIOBSDSocket.OptionLevel, + option_name optname: NIOBSDSocket.Option, + option_value optval: UnsafeRawPointer, + option_len optlen: socklen_t) throws { + if CNIOWindows_setsockopt(socket, level.rawValue, optname.rawValue, + optval, optlen) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "setsockopt") + } + } + + @inline(never) + static func shutdown(socket: NIOBSDSocket.Handle, how: Shutdown) throws { + if WinSDK.shutdown(socket, how.cValue) == SOCKET_ERROR { + throw IOError(winsock: WSAGetLastError(), reason: "shutdown") + } + } + + @inline(never) + static func socket(domain af: NIOBSDSocket.ProtocolFamily, + type: NIOBSDSocket.SocketType, + `protocol`: CInt) throws -> NIOBSDSocket.Handle { + let socket: NIOBSDSocket.Handle = WinSDK.socket(af.rawValue, type.rawValue, `protocol`) + if socket == WinSDK.INVALID_SOCKET { + throw IOError(winsock: WSAGetLastError(), reason: "socket") + } + return socket + } + + @inline(never) + static func recvmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, flags: CInt, + timeout: UnsafeMutablePointer?) + throws -> IOResult { + return .processed(Int(CNIOWindows_recvmmsg(socket, msgvec, vlen, flags, timeout))) + } + + @inline(never) + static func sendmmsg(socket: NIOBSDSocket.Handle, + msgvec: UnsafeMutablePointer, + vlen: CUnsignedInt, flags: CInt) + throws -> IOResult { + return .processed(Int(CNIOWindows_sendmmsg(socket, msgvec, vlen, flags))) + } + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + @inline(never) + static func pread(socket: NIOBSDSocket.Handle, + pointer: UnsafeMutableRawPointer, + size: size_t, offset: off_t) throws -> IOResult { + var ovlOverlapped: OVERLAPPED = OVERLAPPED() + ovlOverlapped.OffsetHigh = DWORD(UInt32(offset >> 32) & 0xffffffff) + ovlOverlapped.Offset = DWORD(UInt32(offset >> 0) & 0xffffffff) + var nNumberOfBytesRead: DWORD = 0 + if !ReadFile(HANDLE(bitPattern: UInt(socket)), pointer, DWORD(size), + &nNumberOfBytesRead, &ovlOverlapped) { + throw IOError(windows: GetLastError(), reason: "ReadFile") + } + return .processed(size_t(nNumberOfBytesRead)) + } + + // NOTE: this should return a `ssize_t`, however, that is not a standard + // type, and defining that type is difficult. Opt to return a `size_t` + // which is the same size, but is unsigned. + @inline(never) + static func pwrite(socket: NIOBSDSocket.Handle, pointer: UnsafeRawPointer, + size: size_t, offset: off_t) throws -> IOResult { + var ovlOverlapped: OVERLAPPED = OVERLAPPED() + ovlOverlapped.OffsetHigh = DWORD(UInt32(offset >> 32) & 0xffffffff) + ovlOverlapped.Offset = DWORD(UInt32(offset >> 0) & 0xffffffff) + var nNumberOfBytesWritten: DWORD = 0 + if !WriteFile(HANDLE(bitPattern: UInt(socket)), pointer, DWORD(size), + &nNumberOfBytesWritten, &ovlOverlapped) { + throw IOError(windows: GetLastError(), reason: "WriteFile") + } + return .processed(size_t(nNumberOfBytesWritten)) + } + + @inline(never) + static func sendfile(socket s: NIOBSDSocket.Handle, fd: CInt, offset: off_t, + len nNumberOfBytesToWrite: off_t) + throws -> IOResult { + let hFile: HANDLE = HANDLE(bitPattern: ucrt._get_osfhandle(fd))! + if hFile == INVALID_HANDLE_VALUE { + throw IOError(errnoCode: EBADF, reason: "_get_osfhandle") + } + + var ovlOverlapped: OVERLAPPED = OVERLAPPED() + ovlOverlapped.Offset = DWORD(UInt32(offset >> 0) & 0xffffffff) + ovlOverlapped.OffsetHigh = DWORD(UInt32(offset >> 32) & 0xffffffff) + if !TransmitFile(s, hFile, DWORD(nNumberOfBytesToWrite), 0, + &ovlOverlapped, nil, DWORD(TF_USE_KERNEL_APC)) { + throw IOError(winsock: WSAGetLastError(), reason: "TransmitFile") + } + + return .processed(Int(nNumberOfBytesToWrite)) + } +} + +extension NIOBSDSocket { + @inline(never) + static func setNonBlocking(socket: NIOBSDSocket.Handle) throws { + var ulMode: u_long = 1 + if WinSDK.ioctlsocket(socket, FIONBIO, &ulMode) == SOCKET_ERROR { + let iResult = WSAGetLastError() + if iResult == WSAEINVAL { + throw NIOFcntlFailedError() + } + throw IOError(winsock: WSAGetLastError(), reason: "ioctlsocket") + } + } + + static func cleanupUnixDomainSocket(atPath path: String) throws { + guard let hFile = (path.withCString(encodedAs: UTF16.self) { + CreateFileW($0, GENERIC_READ, + DWORD(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), + nil, DWORD(OPEN_EXISTING), + DWORD(FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS), + nil) + }) else { + throw IOError(windows: DWORD(EBADF), reason: "CreateFileW") + } + defer { CloseHandle(hFile) } + + let ftFileType = GetFileType(hFile) + let dwError = GetLastError() + guard dwError == NO_ERROR, ftFileType != FILE_TYPE_DISK else { + throw IOError(windows: dwError, reason: "GetFileType") + } + + var fiInformation: BY_HANDLE_FILE_INFORMATION = + BY_HANDLE_FILE_INFORMATION() + guard GetFileInformationByHandle(hFile, &fiInformation) else { + throw IOError(windows: GetLastError(), reason: "GetFileInformationByHandle") + } + + guard fiInformation.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT else { + throw UnixDomainSocketPathWrongType() + } + + var nBytesWritten: DWORD = 0 + var dbReparseDataBuffer: CNIOWindows_REPARSE_DATA_BUFFER = + CNIOWindows_REPARSE_DATA_BUFFER() + try withUnsafeMutablePointer(to: &dbReparseDataBuffer) { + if !DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nil, 0, $0, + DWORD(MemoryLayout.stride), + &nBytesWritten, nil) { + throw IOError(windows: GetLastError(), reason: "DeviceIoControl") + } + } + + guard dbReparseDataBuffer.ReparseTag == IO_REPARSE_TAG_AF_UNIX else { + throw UnixDomainSocketPathWrongType() + } + + var fdi: FILE_DISPOSITION_INFO_EX = FILE_DISPOSITION_INFO_EX() + fdi.Flags = DWORD(FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS) + + if !SetFileInformationByHandle(hFile, FileDispositionInfoEx, &fdi, + DWORD(MemoryLayout.stride)) { + throw IOError(windows: GetLastError(), reason: "GetFileInformationByHandle") + } + } +} + +// MARK: _BSDSocketControlMessageProtocol implementation +extension NIOBSDSocketControlMessage { + static func firstHeader(inside msghdr: UnsafePointer) + -> UnsafeMutablePointer? { + return CNIOWindows_CMSG_FIRSTHDR(msghdr) + } + + static func nextHeader(inside msghdr: UnsafeMutablePointer, + after: UnsafeMutablePointer) + -> UnsafeMutablePointer? { + return CNIOWindows_CMSG_NXTHDR(msghdr, after) + } + + static func data(for header: UnsafePointer) + -> UnsafeRawBufferPointer? { + let data = CNIOWindows_CMSG_DATA(header) + let length = + size_t(header.pointee.cmsg_len) - NIOBSDSocketControlMessage.length(payloadSize: 0) + return UnsafeRawBufferPointer(start: data, count: Int(length)) + } + + static func data(for header: UnsafeMutablePointer) + -> UnsafeMutableRawBufferPointer? { + let data = CNIOWindows_CMSG_DATA_MUTABLE(header) + let length = + size_t(header.pointee.cmsg_len) - NIOBSDSocketControlMessage.length(payloadSize: 0) + return UnsafeMutableRawBufferPointer(start: data, count: Int(length)) + } + + static func length(payloadSize: size_t) -> size_t { + return CNIOWindows_CMSG_LEN(payloadSize) + } + + static func space(payloadSize: size_t) -> size_t { + return CNIOWindows_CMSG_SPACE(payloadSize) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocket.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocket.swift new file mode 100644 index 00000000..1e6962fe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocket.swift @@ -0,0 +1,420 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + +#if os(Windows) +import let WinSDK.EAFNOSUPPORT +import let WinSDK.EBADF +import let WinSDK.ENOENT + +import let WinSDK.FILE_ATTRIBUTE_REPARSE_POINT +import let WinSDK.FILE_FLAG_BACKUP_SEMANTICS +import let WinSDK.FILE_FLAG_OPEN_REPARSE_POINT +import let WinSDK.FILE_SHARE_DELETE +import let WinSDK.FILE_SHARE_READ +import let WinSDK.FILE_SHARE_WRITE +import let WinSDK.FileDispositionInfoEx + +import let WinSDK.GENERIC_READ + +import let WinSDK.INET_ADDRSTRLEN +import let WinSDK.INET6_ADDRSTRLEN + +import let WinSDK.INVALID_HANDLE_VALUE +import let WinSDK.INVALID_SOCKET + +import let WinSDK.IO_REPARSE_TAG_AF_UNIX + +import let WinSDK.NO_ERROR + +import let WinSDK.OPEN_EXISTING + +import func WinSDK.CloseHandle +import func WinSDK.CreateFileW +import func WinSDK.DeviceIoControl +import func WinSDK.GetFileInformationByHandle +import func WinSDK.GetFileType +import func WinSDK.GetLastError +import func WinSDK.SetFileInformationByHandle + +import struct WinSDK.BY_HANDLE_FILE_INFORMATION +import struct WinSDK.DWORD +import struct WinSDK.FILE_DISPOSITION_INFO +import struct WinSDK.socklen_t + +import CNIOWindows +#endif + +protocol Registration { + /// The `SelectorEventSet` in which the `Registration` is interested. + var interested: SelectorEventSet { get set } + var registrationID: SelectorRegistrationID { get set } +} + +// sockaddr_storage is basically just a boring data structure that we can +// convert to being something sensible. These functions copy the data as +// needed. +// +// Annoyingly, these functions are mutating. This is required to work around +// https://bugs.swift.org/browse/SR-2749 on Ubuntu 14.04: basically, we need to +// avoid getting the Swift compiler to copy the sockaddr_storage for any reason: +// only our rebinding copy here is allowed. +extension sockaddr_storage { + mutating func withMutableSockAddr(_ body: (UnsafeMutablePointer, Int) throws -> R) rethrows -> R { + return try withUnsafeMutableBytes(of: &self) { p in + try body(p.baseAddress!.assumingMemoryBound(to: sockaddr.self), p.count) + } + } + + /// Converts the `socketaddr_storage` to a `sockaddr_in`. + /// + /// This will crash if `ss_family` != AF_INET! + func convert() -> sockaddr_in { + precondition(self.ss_family == NIOBSDSocket.AddressFamily.inet.rawValue) + return withUnsafeBytes(of: self) { + $0.load(as: sockaddr_in.self) + } + } + + /// Converts the `socketaddr_storage` to a `sockaddr_in6`. + /// + /// This will crash if `ss_family` != AF_INET6! + func convert() -> sockaddr_in6 { + precondition(self.ss_family == NIOBSDSocket.AddressFamily.inet6.rawValue) + return withUnsafeBytes(of: self) { + $0.load(as: sockaddr_in6.self) + } + } + + /// Converts the `socketaddr_storage` to a `sockaddr_un`. + /// + /// This will crash if `ss_family` != AF_UNIX! + func convert() -> sockaddr_un { + precondition(self.ss_family == NIOBSDSocket.AddressFamily.unix.rawValue) + return withUnsafeBytes(of: self) { + $0.load(as: sockaddr_un.self) + } + } + + /// Converts the `socketaddr_storage` to a `SocketAddress`. + func convert() -> SocketAddress { + switch NIOBSDSocket.AddressFamily(rawValue: CInt(self.ss_family)) { + case .inet: + let sockAddr: sockaddr_in = self.convert() + return SocketAddress(sockAddr) + case .inet6: + let sockAddr: sockaddr_in6 = self.convert() + return SocketAddress(sockAddr) + case .unix: + return SocketAddress(self.convert() as sockaddr_un) + default: + fatalError("unknown sockaddr family \(self.ss_family)") + } + } +} + +/// A helper extension for working with sockaddr pointers. +extension UnsafeMutablePointer where Pointee == sockaddr { + /// Converts the `sockaddr` to a `SocketAddress`. + func convert() -> SocketAddress? { + let addressBytes = UnsafeRawPointer(self) + switch NIOBSDSocket.AddressFamily(rawValue: CInt(pointee.sa_family)) { + case .inet: + return SocketAddress(addressBytes.load(as: sockaddr_in.self)) + case .inet6: + return SocketAddress(addressBytes.load(as: sockaddr_in6.self)) + case .unix: + return SocketAddress(addressBytes.load(as: sockaddr_un.self)) + default: + return nil + } + } +} + +/// Base class for sockets. +/// +/// This should not be created directly but one of its sub-classes should be used, like `ServerSocket` or `Socket`. +class BaseSocket: BaseSocketProtocol { + typealias SelectableType = BaseSocket + + private var descriptor: NIOBSDSocket.Handle + public var isOpen: Bool { + #if os(Windows) + return descriptor != NIOBSDSocket.invalidHandle + #else + return descriptor >= 0 + #endif + } + + /// Returns the local bound `SocketAddress` of the socket. + /// + /// - returns: The local bound address. + /// - throws: An `IOError` if the retrieval of the address failed. + func localAddress() throws -> SocketAddress { + return try get_addr { + try NIOBSDSocket.getsockname(socket: $0, address: $1, address_len: $2) + } + } + + /// Returns the connected `SocketAddress` of the socket. + /// + /// - returns: The connected address. + /// - throws: An `IOError` if the retrieval of the address failed. + func remoteAddress() throws -> SocketAddress { + return try get_addr { + try NIOBSDSocket.getpeername(socket: $0, address: $1, address_len: $2) + } + } + + /// Internal helper function for retrieval of a `SocketAddress`. + private func get_addr(_ body: (NIOBSDSocket.Handle, UnsafeMutablePointer, UnsafeMutablePointer) throws -> Void) throws -> SocketAddress { + var addr = sockaddr_storage() + + try addr.withMutableSockAddr { addressPtr, size in + var size = socklen_t(size) + + try self.withUnsafeHandle { + try body($0, addressPtr, &size) + } + } + return addr.convert() + } + + /// Create a new socket and return the file descriptor of it. + /// + /// - parameters: + /// - protocolFamily: The protocol family to use (usually `AF_INET6` or `AF_INET`). + /// - type: The type of the socket to create. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - returns: the file descriptor of the socket that was created. + /// - throws: An `IOError` if creation of the socket failed. + static func makeSocket(protocolFamily: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, setNonBlocking: Bool = false) throws -> NIOBSDSocket.Handle { + var sockType: CInt = type.rawValue + #if os(Linux) + if setNonBlocking { + sockType = type.rawValue | Linux.SOCK_NONBLOCK + } + #endif + let sock = try NIOBSDSocket.socket(domain: protocolFamily, + type: NIOBSDSocket.SocketType(rawValue: sockType), + protocol: 0) + #if !os(Linux) + if setNonBlocking { + do { + try NIOBSDSocket.setNonBlocking(socket: sock) + } catch { + // best effort close + try? NIOBSDSocket.close(socket: sock) + throw error + } + } + #endif + if protocolFamily == .inet6 { + var zero: Int32 = 0 + do { + try NIOBSDSocket.setsockopt(socket: sock, level: .ipv6, option_name: .ipv6_v6only, option_value: &zero, option_len: socklen_t(MemoryLayout.size(ofValue: zero))) + } catch let e as IOError { + if e.errnoCode != EAFNOSUPPORT { + // Ignore error that may be thrown by close. + _ = try? NIOBSDSocket.close(socket: sock) + throw e + } + /* we couldn't enable dual IP4/6 support, that's okay too. */ + } catch let e { + fatalError("Unexpected error type \(e)") + } + } + return sock + } + + /// Cleanup the unix domain socket. + /// + /// Deletes the associated file if it exists and has socket type. Does nothing if pathname does not exist. + /// + /// - parameters: + /// - unixDomainSocketPath: The pathname of the UDS. + /// - throws: An `UnixDomainSocketPathWrongType` if the pathname exists and is not a socket. + static func cleanupSocket(unixDomainSocketPath: String) throws { + try NIOBSDSocket.cleanupUnixDomainSocket(atPath: unixDomainSocketPath) + } + + /// Create a new instance. + /// + /// The ownership of the passed in descriptor is transferred to this class. A user must call `close` to close the underlying + /// file descriptor once it's not needed / used anymore. + /// + /// - parameters: + /// - descriptor: The file descriptor to wrap. + init(socket descriptor: NIOBSDSocket.Handle) throws { + #if os(Windows) + precondition(descriptor != NIOBSDSocket.invalidHandle, "invalid socket") + #else + precondition(descriptor >= 0, "invalid socket") + #endif + self.descriptor = descriptor + do { + try self.ignoreSIGPIPE() + } catch { + self.descriptor = NIOBSDSocket.invalidHandle // We have to unset the fd here, otherwise we'll crash with "leaking open BaseSocket" + throw error + } + } + + deinit { + assert(!self.isOpen, "leak of open BaseSocket") + } + + func ignoreSIGPIPE() throws { + try BaseSocket.ignoreSIGPIPE(socket: self.descriptor) + } + + /// Set the socket as non-blocking. + /// + /// All I/O operations will not block and so may return before the actual action could be completed. + /// + /// throws: An `IOError` if the operation failed. + final func setNonBlocking() throws { + return try self.withUnsafeHandle { + try NIOBSDSocket.setNonBlocking(socket: $0) + } + } + + /// Set the given socket option. + /// + /// This basically just delegates to `setsockopt` syscall. + /// + /// - parameters: + /// - level: The protocol level (see `man setsockopt`). + /// - name: The name of the option to set. + /// - value: The value for the option. + /// - throws: An `IOError` if the operation failed. + func setOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: T) throws { + if level == .tcp && name == .tcp_nodelay && (try? self.localAddress().protocol) == Optional.some(.unix) { + // setting TCP_NODELAY on UNIX domain sockets will fail. Previously we had a bug where we would ignore + // most socket options settings so for the time being we'll just ignore this. Let's revisit for NIO 2.0. + return + } + return try self.withUnsafeHandle { + var val = value + + try NIOBSDSocket.setsockopt( + socket: $0, + level: level, + option_name: name, + option_value: &val, + option_len: socklen_t(MemoryLayout.size(ofValue: val))) + } + } + + /// Get the given socket option value. + /// + /// This basically just delegates to `getsockopt` syscall. + /// + /// - parameters: + /// - level: The protocol level (see `man getsockopt`). + /// - name: The name of the option to set. + /// - throws: An `IOError` if the operation failed. + final func getOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) throws -> T { + return try self.withUnsafeHandle { fd in + var length = socklen_t(MemoryLayout.size) + let storage = UnsafeMutableRawBufferPointer.allocate(byteCount: MemoryLayout.stride, + alignment: MemoryLayout.alignment) + // write zeroes into the memory as Linux's getsockopt doesn't zero them out + storage.initializeMemory(as: UInt8.self, repeating: 0) + let val = storage.bindMemory(to: T.self).baseAddress! + // initialisation will be done by getsockopt + defer { + val.deinitialize(count: 1) + storage.deallocate() + } + + try NIOBSDSocket.getsockopt(socket: fd, level: level, option_name: name, option_value: val, option_len: &length) + return val.pointee + } + } + + /// Bind the socket to the given `SocketAddress`. + /// + /// - parameters: + /// - address: The `SocketAddress` to which the socket should be bound. + /// - throws: An `IOError` if the operation failed. + func bind(to address: SocketAddress) throws { + try self.withUnsafeHandle { fd in + try address.withSockAddr { + try NIOBSDSocket.bind(socket: fd, address: $0, address_len: socklen_t($1)) + } + } + } + + /// Close the socket. + /// + /// After the socket was closed all other methods will throw an `IOError` when called. + /// + /// - throws: An `IOError` if the operation failed. + func close() throws { + try NIOBSDSocket.close(socket: try self.takeDescriptorOwnership()) + } + + /// Takes the file descriptor's ownership. + /// + /// After this call, `BaseSocket` considers itself to be closed and the caller is responsible for actually closing + /// the underlying file descriptor. + /// + /// - throws: An `IOError` if the operation failed. + final func takeDescriptorOwnership() throws -> NIOBSDSocket.Handle { + return try self.withUnsafeHandle { + self.descriptor = NIOBSDSocket.invalidHandle + return $0 + } + } +} + +extension BaseSocket: Selectable { + func withUnsafeHandle(_ body: (NIOBSDSocket.Handle) throws -> T) throws -> T { + guard self.isOpen else { + throw IOError(errnoCode: EBADF, reason: "file descriptor already closed!") + } + return try body(self.descriptor) + } +} + +extension BaseSocket: CustomStringConvertible { + var description: String { + return "BaseSocket { fd=\(self.descriptor) }" + } +} + +// MARK: Workarounds for SR-14268 +// We need these free functions to expose our extension methods, because otherwise +// the compiler falls over when we try to access them from test code. As these functions +// exist purely to make the behaviours accessible from test code, we name them truly awfully. +func __testOnly_convertSockAddr(_ addr: sockaddr_storage) -> sockaddr_in { + return addr.convert() +} + +func __testOnly_convertSockAddr(_ addr: sockaddr_storage) -> sockaddr_in6 { + return addr.convert() +} + +func __testOnly_convertSockAddr(_ addr: sockaddr_storage) -> sockaddr_un { + return addr.convert() +} + +func __testOnly_withMutableSockAddr( + _ addr: inout sockaddr_storage, _ body: (UnsafeMutablePointer, Int) throws -> ReturnType +) rethrows -> ReturnType { + return try addr.withMutableSockAddr(body) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel+SocketOptionProvider.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel+SocketOptionProvider.swift new file mode 100644 index 00000000..03eff149 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel+SocketOptionProvider.swift @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +extension BaseSocketChannel: SocketOptionProvider { + #if !os(Windows) + func unsafeSetSocketOption(level: SocketOptionLevel, name: SocketOptionName, value: Value) -> EventLoopFuture { + return unsafeSetSocketOption(level: NIOBSDSocket.OptionLevel(rawValue: CInt(level)), name: NIOBSDSocket.Option(rawValue: CInt(name)), value: value) + } + #endif + + func unsafeSetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: Value) -> EventLoopFuture { + if eventLoop.inEventLoop { + let promise = eventLoop.makePromise(of: Void.self) + executeAndComplete(promise) { + try setSocketOption0(level: level, name: name, value: value) + } + return promise.futureResult + } else { + return eventLoop.submit { + try self.setSocketOption0(level: level, name: name, value: value) + } + } + } + + #if !os(Windows) + func unsafeGetSocketOption(level: SocketOptionLevel, name: SocketOptionName) -> EventLoopFuture { + return unsafeGetSocketOption(level: NIOBSDSocket.OptionLevel(rawValue: CInt(level)), name: NIOBSDSocket.Option(rawValue: CInt(name))) + } + #endif + + func unsafeGetSocketOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) -> EventLoopFuture { + if eventLoop.inEventLoop { + let promise = eventLoop.makePromise(of: Value.self) + executeAndComplete(promise) { + try getSocketOption0(level: level, name: name) + } + return promise.futureResult + } else { + return eventLoop.submit { + try self.getSocketOption0(level: level, name: name) + } + } + } + + func setSocketOption0(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: Value) throws { + try self.socket.setOption(level: level, name: name, value: value) + } + + func getSocketOption0(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) throws -> Value { + return try self.socket.getOption(level: level, name: name) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel.swift new file mode 100644 index 00000000..801f5af5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseSocketChannel.swift @@ -0,0 +1,1323 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + +private struct SocketChannelLifecycleManager { + // MARK: Types + private enum State { + case fresh + case preRegistered // register() has been run but the selector doesn't know about it yet + case fullyRegistered // fully registered, ie. the selector knows about it + case activated + case closed + } + + private enum Event { + case activate + case beginRegistration + case finishRegistration + case close + } + + // MARK: properties + private let eventLoop: EventLoop + // this is queried from the Channel, ie. must be thread-safe + internal let isActiveAtomic: NIOAtomic + // these are only to be accessed on the EventLoop + + // have we seen the `.readEOF` notification + // note: this can be `false` on a deactivated channel, we might just have torn it down. + var hasSeenEOFNotification: Bool = false + + private var currentState: State = .fresh { + didSet { + self.eventLoop.assertInEventLoop() + switch (oldValue, self.currentState) { + case (_, .activated): + self.isActiveAtomic.store(true) + case (.activated, _): + self.isActiveAtomic.store(false) + default: + () + } + } + } + + // MARK: API + // isActiveAtomic needs to be injected as it's accessed from arbitrary threads and `SocketChannelLifecycleManager` is usually held mutable + internal init(eventLoop: EventLoop, isActiveAtomic: NIOAtomic) { + self.eventLoop = eventLoop + self.isActiveAtomic = isActiveAtomic + } + + // this is called from Channel's deinit, so don't assert we're on the EventLoop! + internal var canBeDestroyed: Bool { + return self.currentState == .closed + } + + @inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined + internal mutating func beginRegistration() -> ((EventLoopPromise?, ChannelPipeline) -> Void) { + return self.moveState(event: .beginRegistration) + } + + @inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined + internal mutating func finishRegistration() -> ((EventLoopPromise?, ChannelPipeline) -> Void) { + return self.moveState(event: .finishRegistration) + } + + @inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined + internal mutating func close() -> ((EventLoopPromise?, ChannelPipeline) -> Void) { + return self.moveState(event: .close) + } + + @inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined + internal mutating func activate() -> ((EventLoopPromise?, ChannelPipeline) -> Void) { + return self.moveState(event: .activate) + } + + // MARK: private API + @inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined + private mutating func moveState(event: Event) -> ((EventLoopPromise?, ChannelPipeline) -> Void) { + self.eventLoop.assertInEventLoop() + + switch (self.currentState, event) { + // origin: .fresh + case (.fresh, .beginRegistration): + self.currentState = .preRegistered + return { promise, pipeline in + promise?.succeed(()) + pipeline.syncOperations.fireChannelRegistered() + } + + case (.fresh, .close): + self.currentState = .closed + return { (promise, _: ChannelPipeline) in + promise?.succeed(()) + } + + // origin: .preRegistered + case (.preRegistered, .finishRegistration): + self.currentState = .fullyRegistered + return { (promise, _: ChannelPipeline) in + promise?.succeed(()) + } + + // origin: .fullyRegistered + case (.fullyRegistered, .activate): + self.currentState = .activated + return { promise, pipeline in + promise?.succeed(()) + pipeline.syncOperations.fireChannelActive() + } + + // origin: .preRegistered || .fullyRegistered + case (.preRegistered, .close), (.fullyRegistered, .close): + self.currentState = .closed + return { promise, pipeline in + promise?.succeed(()) + pipeline.syncOperations.fireChannelUnregistered() + } + + // origin: .activated + case (.activated, .close): + self.currentState = .closed + return { promise, pipeline in + promise?.succeed(()) + pipeline.syncOperations.fireChannelInactive() + pipeline.syncOperations.fireChannelUnregistered() + } + + // bad transitions + case (.fresh, .activate), // should go through .registered first + (.preRegistered, .activate), // need to first be fully registered + (.preRegistered, .beginRegistration), // already registered + (.fullyRegistered, .beginRegistration), // already registered + (.activated, .activate), // already activated + (.activated, .beginRegistration), // already fully registered (and activated) + (.activated, .finishRegistration), // already fully registered (and activated) + (.fullyRegistered, .finishRegistration), // already fully registered + (.fresh, .finishRegistration), // need to register lazily first + (.closed, _): // already closed + self.badTransition(event: event) + } + } + + private func badTransition(event: Event) -> Never { + preconditionFailure("illegal transition: state=\(self.currentState), event=\(event)") + } + + // MARK: convenience properties + internal var isActive: Bool { + self.eventLoop.assertInEventLoop() + return self.currentState == .activated + } + + internal var isPreRegistered: Bool { + self.eventLoop.assertInEventLoop() + switch self.currentState { + case .fresh, .closed: + return false + case .preRegistered, .fullyRegistered, .activated: + return true + } + } + + internal var isRegisteredFully: Bool { + self.eventLoop.assertInEventLoop() + switch self.currentState { + case .fresh, .closed, .preRegistered: + return false + case .fullyRegistered, .activated: + return true + } + } + + /// Returns whether the underlying file descriptor is open. This property will always be true (even before registration) + /// until the Channel is closed. + internal var isOpen: Bool { + self.eventLoop.assertInEventLoop() + return self.currentState != .closed + } +} + +/// The base class for all socket-based channels in NIO. +/// +/// There are many types of specialised socket-based channel in NIO. Each of these +/// has different logic regarding how exactly they read from and write to the network. +/// However, they share a great deal of common logic around the managing of their +/// file descriptors. +/// +/// For this reason, `BaseSocketChannel` exists to provide a common core implementation of +/// the `SelectableChannel` protocol. It uses a number of private functions to provide hooks +/// for subclasses to implement the specific logic to handle their writes and reads. +class BaseSocketChannel: SelectableChannel, ChannelCore { + typealias SelectableType = SocketType.SelectableType + + struct AddressCache { + // deliberately lets because they must always be updated together (so forcing `init` is useful). + let local: Optional + let remote: Optional + + init(local: SocketAddress?, remote: SocketAddress?) { + self.local = local + self.remote = remote + } + } + + // MARK: - Stored Properties + // MARK: Constants & atomics (accessible everywhere) + public let parent: Channel? + internal let socket: SocketType + private let closePromise: EventLoopPromise + internal let selectableEventLoop: SelectableEventLoop + private let _offEventLoopLock = Lock() + private let isActiveAtomic: NIOAtomic = .makeAtomic(value: false) + // just a thread-safe way of having something to print about the socket from any thread + internal let socketDescription: String + + // MARK: Variables, on EventLoop thread only + var readPending = false + var pendingConnect: Optional> + var recvAllocator: RecvByteBufferAllocator + var maxMessagesPerRead: UInt = 4 + private var inFlushNow: Bool = false // Guard against re-entrance of flushNow() method. + private var autoRead: Bool = true + + // MARK: Variables that are really constants + private var _pipeline: ChannelPipeline! = nil // this is really a constant (set in .init) but needs `self` to be constructed and therefore a `var`. Do not change as this needs to accessed from arbitrary threads + + // MARK: Special variables, please read comments. + // For reads guarded by _either_ `self._offEventLoopLock` or the EL thread + // Writes are guarded by _offEventLoopLock _and_ the EL thread. + // PLEASE don't use these directly and use the non-underscored computed properties instead. + private var _addressCache = AddressCache(local: nil, remote: nil) // please use `self.addressesCached` instead + private var _bufferAllocatorCache: ByteBufferAllocator // please use `self.bufferAllocatorCached` instead. + + // MARK: - Computed properties + // This is called from arbitrary threads. + internal var addressesCached: AddressCache { + get { + if self.eventLoop.inEventLoop { + return self._addressCache + } else { + return self._offEventLoopLock.withLock { + return self._addressCache + } + } + } + set { + self.eventLoop.preconditionInEventLoop() + self._offEventLoopLock.withLock { + self._addressCache = newValue + } + } + } + + // This is called from arbitrary threads. + private var bufferAllocatorCached: ByteBufferAllocator { + get { + if self.eventLoop.inEventLoop { + return self._bufferAllocatorCache + } else { + return self._offEventLoopLock.withLock { + return self._bufferAllocatorCache + } + } + } + set { + self.eventLoop.preconditionInEventLoop() + self._offEventLoopLock.withLock { + self._bufferAllocatorCache = newValue + } + } + } + + // We start with the invalid empty set of selector events we're interested in. This is to make sure we later on + // (in `becomeFullyRegistered0`) seed the initial event correctly. + internal var interestedEvent: SelectorEventSet = [] { + didSet { + assert(self.interestedEvent.contains(.reset), "impossible to unregister for reset") + } + } + + private var lifecycleManager: SocketChannelLifecycleManager { + didSet { + self.eventLoop.assertInEventLoop() + } + } + + private var bufferAllocator: ByteBufferAllocator = ByteBufferAllocator() { + didSet { + self.eventLoop.assertInEventLoop() + self.bufferAllocatorCached = self.bufferAllocator + } + } + + public final var _channelCore: ChannelCore { return self } + + // This is `Channel` API so must be thread-safe. + public final var localAddress: SocketAddress? { + return self.addressesCached.local + } + + // This is `Channel` API so must be thread-safe. + public final var remoteAddress: SocketAddress? { + return self.addressesCached.remote + } + + /// `false` if the whole `Channel` is closed and so no more IO operation can be done. + var isOpen: Bool { + self.eventLoop.assertInEventLoop() + return self.lifecycleManager.isOpen + } + + var isRegistered: Bool { + self.eventLoop.assertInEventLoop() + return self.lifecycleManager.isPreRegistered + } + + // This is `Channel` API so must be thread-safe. + public var isActive: Bool { + return self.isActiveAtomic.load() + } + + // This is `Channel` API so must be thread-safe. + public final var closeFuture: EventLoopFuture { + return self.closePromise.futureResult + } + + public final var eventLoop: EventLoop { + return selectableEventLoop + } + + // This is `Channel` API so must be thread-safe. + public var isWritable: Bool { + return true + } + + // This is `Channel` API so must be thread-safe. + public final var allocator: ByteBufferAllocator { + return self.bufferAllocatorCached + } + + // This is `Channel` API so must be thread-safe. + public final var pipeline: ChannelPipeline { + return self._pipeline + } + + // MARK: Methods to override in subclasses. + func writeToSocket() throws -> OverallWriteResult { + fatalError("must be overridden") + } + + /// Read data from the underlying socket and dispatch it to the `ChannelPipeline` + /// + /// - returns: `true` if any data was read, `false` otherwise. + @discardableResult func readFromSocket() throws -> ReadResult { + fatalError("this must be overridden by sub class") + } + + // MARK: - Datatypes + + /// Indicates if a selectable should registered or not for IO notifications. + enum IONotificationState { + /// We should be registered for IO notifications. + case register + + /// We should not be registered for IO notifications. + case unregister + } + + enum ReadResult { + /// Nothing was read by the read operation. + case none + + /// Some data was read by the read operation. + case some + } + + /// Returned by the `private func readable0()` to inform the caller about the current state of the underlying read stream. + /// This is mostly useful when receiving `.readEOF` as we then need to drain the read stream fully (ie. until we receive EOF or error of course) + private enum ReadStreamState: Equatable { + /// Everything seems normal + case normal(ReadResult) + + /// We saw EOF. + case eof + + /// A read error was received. + case error + } + + /// Begin connection of the underlying socket. + /// + /// - parameters: + /// - to: The `SocketAddress` to connect to. + /// - returns: `true` if the socket connected synchronously, `false` otherwise. + func connectSocket(to address: SocketAddress) throws -> Bool { + fatalError("this must be overridden by sub class") + } + + /// Make any state changes needed to complete the connection process. + func finishConnectSocket() throws { + fatalError("this must be overridden by sub class") + } + + /// Returns if there are any flushed, pending writes to be sent over the network. + func hasFlushedPendingWrites() -> Bool { + fatalError("this must be overridden by sub class") + } + + /// Buffer a write in preparation for a flush. + func bufferPendingWrite(data: NIOAny, promise: EventLoopPromise?) { + fatalError("this must be overridden by sub class") + } + + /// Mark a flush point. This is called when flush is received, and instructs + /// the implementation to record the flush. + func markFlushPoint() { + fatalError("this must be overridden by sub class") + } + + /// Called when closing, to instruct the specific implementation to discard all pending + /// writes. + func cancelWritesOnClose(error: Error) { + fatalError("this must be overridden by sub class") + } + + // MARK: Common base socket logic. + init(socket: SocketType, parent: Channel?, eventLoop: SelectableEventLoop, recvAllocator: RecvByteBufferAllocator) throws { + self._bufferAllocatorCache = self.bufferAllocator + self.socket = socket + self.selectableEventLoop = eventLoop + self.closePromise = eventLoop.makePromise() + self.parent = parent + self.recvAllocator = recvAllocator + // As the socket may already be connected we should ensure we start with the correct addresses cached. + self._addressCache = .init(local: try? socket.localAddress(), remote: try? socket.remoteAddress()) + self.lifecycleManager = SocketChannelLifecycleManager(eventLoop: eventLoop, isActiveAtomic: self.isActiveAtomic) + self.socketDescription = socket.description + self.pendingConnect = nil + self._pipeline = ChannelPipeline(channel: self) + } + + deinit { + assert(self.lifecycleManager.canBeDestroyed, + "leak of open Channel, state: \(String(describing: self.lifecycleManager))") + } + + public final func localAddress0() throws -> SocketAddress { + self.eventLoop.assertInEventLoop() + guard self.isOpen else { + throw ChannelError.ioOnClosedChannel + } + return try self.socket.localAddress() + } + + public final func remoteAddress0() throws -> SocketAddress { + self.eventLoop.assertInEventLoop() + guard self.isOpen else { + throw ChannelError.ioOnClosedChannel + } + return try self.socket.remoteAddress() + } + + /// Flush data to the underlying socket and return if this socket needs to be registered for write notifications. + /// + /// This method can be called re-entrantly but it will return immediately because the first call is responsible + /// for sending all flushed writes, even the ones that are accumulated whilst `flushNow()` is running. + /// + /// - returns: If this socket should be registered for write notifications. Ie. `IONotificationState.register` if + /// _not_ all data could be written, so notifications are necessary; and `IONotificationState.unregister` + /// if everything was written and we don't need to be notified about writability at the moment. + func flushNow() -> IONotificationState { + self.eventLoop.assertInEventLoop() + + // Guard against re-entry as data that will be put into `pendingWrites` will just be picked up by + // `writeToSocket`. + guard !self.inFlushNow else { + return .unregister + } + + assert(!self.inFlushNow) + self.inFlushNow = true + defer { + self.inFlushNow = false + } + + var newWriteRegistrationState: IONotificationState = .unregister + do { + while newWriteRegistrationState == .unregister && self.hasFlushedPendingWrites() && self.isOpen { + assert(self.lifecycleManager.isActive) + let writeResult = try self.writeToSocket() + switch writeResult.writeResult { + case .couldNotWriteEverything: + newWriteRegistrationState = .register + case .writtenCompletely: + newWriteRegistrationState = .unregister + } + + if writeResult.writabilityChange { + // We went from not writable to writable. + self.pipeline.syncOperations.fireChannelWritabilityChanged() + } + } + } catch let err { + // If there is a write error we should try drain the inbound before closing the socket as there may be some data pending. + // We ignore any error that is thrown as we will use the original err to close the channel and notify the user. + if self.readIfNeeded0() { + assert(self.lifecycleManager.isActive) + + // We need to continue reading until there is nothing more to be read from the socket as we will not have another chance to drain it. + var readAtLeastOnce = false + while let read = try? self.readFromSocket(), read == .some { + readAtLeastOnce = true + } + if readAtLeastOnce && self.lifecycleManager.isActive { + self.pipeline.fireChannelReadComplete() + } + } + + self.close0(error: err, mode: .all, promise: nil) + + // we handled all writes + return .unregister + } + + assert((newWriteRegistrationState == .register && self.hasFlushedPendingWrites()) || + (newWriteRegistrationState == .unregister && !self.hasFlushedPendingWrites()), + "illegal flushNow decision: \(newWriteRegistrationState) and \(self.hasFlushedPendingWrites())") + return newWriteRegistrationState + } + + public final func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + if eventLoop.inEventLoop { + let promise = eventLoop.makePromise(of: Void.self) + executeAndComplete(promise) { try self.setOption0(option, value: value) } + return promise.futureResult + } else { + return eventLoop.submit { try self.setOption0(option, value: value) } + } + } + + func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case let option as ChannelOptions.Types.SocketOption: + try self.setSocketOption0(level: option.optionLevel, name: option.optionName, value: value) + case _ as ChannelOptions.Types.AllocatorOption: + bufferAllocator = value as! ByteBufferAllocator + case _ as ChannelOptions.Types.RecvAllocatorOption: + recvAllocator = value as! RecvByteBufferAllocator + case _ as ChannelOptions.Types.AutoReadOption: + let auto = value as! Bool + let old = self.autoRead + self.autoRead = auto + + // We only want to call read0() or pauseRead0() if we already registered to the EventLoop if not this will be automatically done + // once register0 is called. Beside this we also only need to do it when the value actually change. + if self.lifecycleManager.isPreRegistered && old != auto { + if auto { + read0() + } else { + pauseRead0() + } + } + case _ as ChannelOptions.Types.MaxMessagesPerReadOption: + maxMessagesPerRead = value as! UInt + default: + fatalError("option \(option) not supported") + } + } + + public func getOption(_ option: Option) -> EventLoopFuture { + if eventLoop.inEventLoop { + do { + return self.eventLoop.makeSucceededFuture(try self.getOption0(option)) + } catch { + return self.eventLoop.makeFailedFuture(error) + } + } else { + return self.eventLoop.submit { try self.getOption0(option) } + } + } + + func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case let option as ChannelOptions.Types.SocketOption: + return try self.getSocketOption0(level: option.optionLevel, name: option.optionName) + case _ as ChannelOptions.Types.AllocatorOption: + return bufferAllocator as! Option.Value + case _ as ChannelOptions.Types.RecvAllocatorOption: + return recvAllocator as! Option.Value + case _ as ChannelOptions.Types.AutoReadOption: + return autoRead as! Option.Value + case _ as ChannelOptions.Types.MaxMessagesPerReadOption: + return maxMessagesPerRead as! Option.Value + default: + fatalError("option \(option) not supported") + } + } + + /// Triggers a `ChannelPipeline.read()` if `autoRead` is enabled.` + /// + /// - returns: `true` if `readPending` is `true`, `false` otherwise. + @discardableResult func readIfNeeded0() -> Bool { + self.eventLoop.assertInEventLoop() + if !self.lifecycleManager.isActive { + return false + } + + if !readPending && autoRead { + self.pipeline.syncOperations.read() + } + return readPending + } + + // Methods invoked from the HeadHandler of the ChannelPipeline + public func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + executeAndComplete(promise) { + try socket.bind(to: address) + self.updateCachedAddressesFromSocket(updateRemote: false) + } + } + + public final func write0(_ data: NIOAny, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + // Channel was already closed, fail the promise and not even queue it. + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + guard self.lifecycleManager.isActive else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + + bufferPendingWrite(data: data, promise: promise) + } + + private func registerForWritable() { + self.eventLoop.assertInEventLoop() + + guard !self.interestedEvent.contains(.write) else { + // nothing to do if we were previously interested in write + return + } + self.safeReregister(interested: self.interestedEvent.union(.write)) + } + + func unregisterForWritable() { + self.eventLoop.assertInEventLoop() + + guard self.interestedEvent.contains(.write) else { + // nothing to do if we were not previously interested in write + return + } + self.safeReregister(interested: self.interestedEvent.subtracting(.write)) + } + + public final func flush0() { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + return + } + + self.markFlushPoint() + + guard self.lifecycleManager.isActive else { + return + } + + if !isWritePending() && flushNow() == .register { + assert(self.lifecycleManager.isPreRegistered) + registerForWritable() + } + } + + public func read0() { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + return + } + readPending = true + + if self.lifecycleManager.isPreRegistered { + registerForReadable() + } + } + + private final func pauseRead0() { + self.eventLoop.assertInEventLoop() + + if self.lifecycleManager.isPreRegistered { + unregisterForReadable() + } + } + + private final func registerForReadable() { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isRegisteredFully) + + guard !self.lifecycleManager.hasSeenEOFNotification else { + // we have seen an EOF notification before so there's no point in registering for reads + return + } + + guard !self.interestedEvent.contains(.read) else { + return + } + + self.safeReregister(interested: self.interestedEvent.union(.read)) + } + + private final func registerForReadEOF() { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isRegisteredFully) + + guard !self.lifecycleManager.hasSeenEOFNotification else { + // we have seen an EOF notification before so there's no point in registering for reads + return + } + + guard !self.interestedEvent.contains(.readEOF) else { + return + } + + self.safeReregister(interested: self.interestedEvent.union(.readEOF)) + } + + internal final func unregisterForReadable() { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isRegisteredFully) + + guard self.interestedEvent.contains(.read) else { + return + } + + self.safeReregister(interested: self.interestedEvent.subtracting(.read)) + } + + /// Closes the this `BaseChannelChannel` and fulfills `promise` with the result of the _close_ operation. + /// So unless either the deregistration or the close itself fails, `promise` will be succeeded regardless of + /// `error`. `error` is used to fail outstanding writes (if any) and the `connectPromise` if set. + /// + /// - parameters: + /// - error: The error to fail the outstanding (if any) writes/connect with. + /// - mode: The close mode, must be `.all` for `BaseSocketChannel` + /// - promise: The promise that gets notified about the result of the deregistration/close operations. + public func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + promise?.fail(ChannelError.alreadyClosed) + return + } + + guard mode == .all else { + promise?.fail(ChannelError.operationUnsupported) + return + } + + // === BEGIN: No user callouts === + + // this is to register all error callouts as all the callouts must happen after we transition out state + var errorCallouts: [(ChannelPipeline) -> Void] = [] + + self.interestedEvent = .reset + do { + try selectableEventLoop.deregister(channel: self) + } catch let err { + errorCallouts.append { pipeline in + pipeline.syncOperations.fireErrorCaught(err) + } + } + + let p: EventLoopPromise? + do { + try socket.close() + p = promise + } catch { + errorCallouts.append { (_: ChannelPipeline) in + promise?.fail(error) + // Set p to nil as we want to ensure we pass nil to becomeInactive0(...) so we not try to notify the promise again. + } + p = nil + } + + // Transition our internal state. + let callouts = self.lifecycleManager.close() + + // === END: No user callouts (now that our state is reconciled, we can call out to user code.) === + + // this must be the first to call out as it transitions the PendingWritesManager into the closed state + // and we assert elsewhere that the PendingWritesManager has the same idea of 'open' as we have in here. + self.cancelWritesOnClose(error: error) + + // this should be a no-op as we shouldn't have any + errorCallouts.forEach { + $0(self.pipeline) + } + + if let connectPromise = self.pendingConnect { + self.pendingConnect = nil + connectPromise.fail(error) + } + + callouts(p, self.pipeline) + + eventLoop.execute { + // ensure this is executed in a delayed fashion as the users code may still traverse the pipeline + self.removeHandlers(pipeline: self.pipeline) + + self.closePromise.succeed(()) + + // Now reset the addresses as we notified all handlers / futures. + self.unsetCachedAddressesFromSocket() + } + } + + + public final func register0(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + guard !self.lifecycleManager.isPreRegistered else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + + guard self.selectableEventLoop.isOpen else { + let error = EventLoopError.shutdown + self.pipeline.syncOperations.fireErrorCaught(error) + // `close0`'s error is about the result of the `close` operation, ... + self.close0(error: error, mode: .all, promise: nil) + // ... therefore we need to fail the registration `promise` separately. + promise?.fail(error) + return + } + + // we can't fully register yet as epoll would give us EPOLLHUP if bind/connect wasn't called yet. + self.lifecycleManager.beginRegistration()(promise, self.pipeline) + } + + public final func registerAlreadyConfigured0(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + assert(self.isOpen) + assert(!self.lifecycleManager.isActive) + let registerPromise = self.eventLoop.makePromise(of: Void.self) + self.register0(promise: registerPromise) + registerPromise.futureResult.whenFailure { (_: Error) in + self.close(promise: nil) + } + registerPromise.futureResult.cascadeFailure(to: promise) + + if self.lifecycleManager.isPreRegistered { + // we expect kqueue/epoll registration to always succeed which is basically true, except for errors that + // should be fatal (EBADF, EFAULT, ESRCH, ENOMEM) and a two 'table full' (EMFILE, ENFILE) error kinds which + // we don't handle yet but might do in the future (#469). + try! becomeFullyRegistered0() + if self.lifecycleManager.isRegisteredFully { + self.becomeActive0(promise: promise) + } + } + } + + public final func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + // Methods invoked from the EventLoop itself + public final func writable() { + self.eventLoop.assertInEventLoop() + assert(self.isOpen) + + self.finishConnect() // If we were connecting, that has finished. + + switch self.flushNow() { + case .unregister: + // Everything was written or connect was complete, let's unregister from writable. + self.finishWritable() + case .register: + assert(!self.isOpen || self.interestedEvent.contains(.write)) + () // nothing to do because given that we just received `writable`, we're still registered for writable. + } + } + + private func finishConnect() { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isPreRegistered) + + if let connectPromise = self.pendingConnect { + assert(!self.lifecycleManager.isActive) + + do { + try self.finishConnectSocket() + } catch { + assert(!self.lifecycleManager.isActive) + // close0 fails the connectPromise itself so no need to do it here + self.close0(error: error, mode: .all, promise: nil) + return + } + // now this has succeeded, becomeActive0 will actually fulfill this. + self.pendingConnect = nil + // We already know what the local address is. + self.updateCachedAddressesFromSocket(updateLocal: false, updateRemote: true) + self.becomeActive0(promise: connectPromise) + } else { + assert(self.lifecycleManager.isActive) + } + } + + private func finishWritable() { + self.eventLoop.assertInEventLoop() + + if self.isOpen { + assert(self.lifecycleManager.isPreRegistered) + assert(!self.hasFlushedPendingWrites()) + self.unregisterForWritable() + } + } + + func writeEOF() { + fatalError("\(self) received writeEOF which is unexpected") + } + + func readEOF() { + assert(!self.lifecycleManager.hasSeenEOFNotification) + self.lifecycleManager.hasSeenEOFNotification = true + + // we can't be not active but still registered here; this would mean that we got a notification about a + // channel before we're ready to receive them. + assert(self.lifecycleManager.isRegisteredFully, + "illegal state: \(self): active: \(self.lifecycleManager.isActive), registered: \(self.lifecycleManager.isRegisteredFully)") + + self.readEOF0() + + assert(!self.interestedEvent.contains(.read)) + assert(!self.interestedEvent.contains(.readEOF)) + } + + final func readEOF0() { + if self.lifecycleManager.isRegisteredFully { + // we're unregistering from `readEOF` here as we want this to be one-shot. We're then synchronously + // reading all input until the EOF that we're guaranteed to see. After that `readEOF` becomes uninteresting + // and would anyway fire constantly. + self.safeReregister(interested: self.interestedEvent.subtracting(.readEOF)) + + loop: while self.lifecycleManager.isActive { + switch self.readable0() { + case .eof: + // on EOF we stop the loop and we're done with our processing for `readEOF`. + // we could both be registered & active (if our channel supports half-closure) or unregistered & inactive (if it doesn't). + break loop + case .error: + // we should be unregistered and inactive now (as `readable0` would've called close). + assert(!self.lifecycleManager.isActive) + assert(!self.lifecycleManager.isPreRegistered) + break loop + case .normal(.none): + preconditionFailure("got .readEOF and read returned not reading any bytes, nor EOF.") + case .normal(.some): + // normal, note that there is no guarantee we're still active (as the user might have closed in callout) + continue loop + } + } + } + } + + // this _needs_ to synchronously cause the fd to be unregistered because we cannot unregister from `reset`. In + // other words: Failing to unregister the whole selector will cause NIO to spin at 100% CPU constantly delivering + // the `reset` event. + final func reset() { + self.readEOF0() + + if self.socket.isOpen { + assert(self.lifecycleManager.isPreRegistered) + let error: IOError + // if the socket is still registered (and therefore open), let's try to get the actual socket error from the socket + do { + let result: Int32 = try self.socket.getOption(level: .socket, name: .so_error) + if result != 0 { + // we have a socket error, let's forward + // this path will be executed on Linux (EPOLLERR) & Darwin (ev.fflags != 0) + error = IOError(errnoCode: result, reason: "connection reset (error set)") + } else { + // we don't have a socket error, this must be connection reset without an error then + // this path should only be executed on Linux (EPOLLHUP, no EPOLLERR) + #if os(Linux) + let message: String = "connection reset (no error set)" + #else + let message: String = "BUG IN SwiftNIO (possibly #572), please report! Connection reset (no error set)." + #endif + error = IOError(errnoCode: ECONNRESET, reason: message) + } + self.close0(error: error, mode: .all, promise: nil) + } catch { + self.close0(error: error, mode: .all, promise: nil) + } + } + assert(!self.lifecycleManager.isPreRegistered) + } + + public final func readable() { + assert(!self.lifecycleManager.hasSeenEOFNotification, + "got a read notification after having already seen .readEOF") + self.readable0() + } + + @discardableResult + private final func readable0() -> ReadStreamState { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isActive) + + defer { + if self.isOpen && !self.readPending { + unregisterForReadable() + } + } + + let readResult: ReadResult + do { + readResult = try self.readFromSocket() + } catch let err { + let readStreamState: ReadStreamState + // ChannelError.eof is not something we want to fire through the pipeline as it just means the remote + // peer closed / shutdown the connection. + if let channelErr = err as? ChannelError, channelErr == ChannelError.eof { + readStreamState = .eof + // Directly call getOption0 as we are already on the EventLoop and so not need to create an extra future. + + // getOption0 can only fail if the channel is not active anymore but we assert further up that it is. If + // that's not the case this is a precondition failure and we would like to know. + if self.lifecycleManager.isActive, try! self.getOption0(ChannelOptions.allowRemoteHalfClosure) { + // If we want to allow half closure we will just mark the input side of the Channel + // as closed. + assert(self.lifecycleManager.isActive) + self.pipeline.syncOperations.fireChannelReadComplete() + if self.shouldCloseOnReadError(err) { + self.close0(error: err, mode: .input, promise: nil) + } + self.readPending = false + return .eof + } + } else { + readStreamState = .error + self.pipeline.syncOperations.fireErrorCaught(err) + } + + // Call before triggering the close of the Channel. + if readStreamState != .error, self.lifecycleManager.isActive { + self.pipeline.syncOperations.fireChannelReadComplete() + } + + if self.shouldCloseOnReadError(err) { + self.close0(error: err, mode: .all, promise: nil) + } + + return readStreamState + } + // This assert needs to be disabled for io_uring, as the io_uring backend does not have the implicit synchronisation between + // modifications to the poll mask and the actual returned events on the completion queue that kqueue and epoll has. + // For kqueue and epoll, there is an implicit synchronisation point such that after a modification of the poll mask has been + // issued, the next call to reap events will be sure to not include events which does not match the new poll mask. + // Specifically for this assert, it means that we will be guaranteed to never receive a POLLIN notification unless there are + // bytes available to read. + + // For a fully asynchronous backend like io_uring, there are no such implicit synchronisation point, so after we have + // submitted the asynchronous event to change the poll mask, we may still reap pending asynchronous replies for the old + // poll mask, and thus receive a POLLIN even though we have modified the mask visavi the kernel. + // Which would trigger the assert. + + // The only way to avoid that race, would be to use heavy handed synchronisation primitives like IOSQE_IO_DRAIN (basically + // flushing all pending requests and wait for a fake event result to sync up) which would be awful for performance, + // so better skip the assert() for io_uring instead. + #if !SWIFTNIO_USE_IO_URING + assert(readResult == .some) + #endif + if self.lifecycleManager.isActive { + self.pipeline.syncOperations.fireChannelReadComplete() + } + self.readIfNeeded0() + return .normal(readResult) + } + + /// Returns `true` if the `Channel` should be closed as result of the given `Error` which happened during `readFromSocket`. + /// + /// - parameters: + /// - err: The `Error` which was thrown by `readFromSocket`. + /// - returns: `true` if the `Channel` should be closed, `false` otherwise. + func shouldCloseOnReadError(_ err: Error) -> Bool { + return true + } + + internal final func updateCachedAddressesFromSocket(updateLocal: Bool = true, updateRemote: Bool = true) { + self.eventLoop.assertInEventLoop() + assert(updateLocal || updateRemote) + let cached = self.addressesCached + let local = updateLocal ? try? self.localAddress0() : cached.local + let remote = updateRemote ? try? self.remoteAddress0() : cached.remote + self.addressesCached = AddressCache(local: local, remote: remote) + } + + internal final func unsetCachedAddressesFromSocket() { + self.eventLoop.assertInEventLoop() + self.addressesCached = AddressCache(local: nil, remote: nil) + } + + public final func connect0(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + guard pendingConnect == nil else { + promise?.fail(ChannelError.connectPending) + return + } + + guard self.lifecycleManager.isPreRegistered else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + + do { + if try !self.connectSocket(to: address) { + // We aren't connected, we'll get the remote address later. + self.updateCachedAddressesFromSocket(updateLocal: true, updateRemote: false) + if promise != nil { + self.pendingConnect = promise + } else { + self.pendingConnect = eventLoop.makePromise() + } + try self.becomeFullyRegistered0() + self.registerForWritable() + } else { + self.updateCachedAddressesFromSocket() + self.becomeActive0(promise: promise) + } + } catch let error { + assert(self.lifecycleManager.isPreRegistered) + // We would like to have this assertion here, but we want to be able to go through this + // code path in cases where connect() is being called on channels that are already active. + //assert(!self.lifecycleManager.isActive) + // We're going to set the promise as the pending connect promise, and let close0 fail it for us. + self.pendingConnect = promise + self.close0(error: error, mode: .all, promise: nil) + } + } + + public func channelRead0(_ data: NIOAny) { + // Do nothing by default + // note: we can't assert that we're active here as TailChannelHandler will call this on channelRead + } + + public func errorCaught0(error: Error) { + // Do nothing + } + + private func isWritePending() -> Bool { + return self.interestedEvent.contains(.write) + } + + private final func safeReregister(interested: SelectorEventSet) { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isRegisteredFully) + + guard self.isOpen else { + assert(self.interestedEvent == .reset, "interestedEvent=\(self.interestedEvent) even though we're closed") + return + } + if interested == interestedEvent { + // we don't need to update and so cause a syscall if we already are registered with the correct event + return + } + interestedEvent = interested + do { + try selectableEventLoop.reregister(channel: self) + } catch let err { + self.pipeline.syncOperations.fireErrorCaught(err) + self.close0(error: err, mode: .all, promise: nil) + } + } + + private func safeRegister(interested: SelectorEventSet) throws { + self.eventLoop.assertInEventLoop() + assert(!self.lifecycleManager.isRegisteredFully) + + guard self.isOpen else { + throw ChannelError.ioOnClosedChannel + } + + self.interestedEvent = interested + do { + try self.selectableEventLoop.register(channel: self) + } catch { + self.pipeline.syncOperations.fireErrorCaught(error) + self.close0(error: error, mode: .all, promise: nil) + throw error + } + } + + final func becomeFullyRegistered0() throws { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isPreRegistered) + assert(!self.lifecycleManager.isRegisteredFully) + + // The initial set of interested events must not contain `.readEOF` because when connect doesn't return + // synchronously, kevent might send us a `readEOF` because the `writable` event that marks the connect as completed. + // See SocketChannelTest.testServerClosesTheConnectionImmediately for a regression test. + try self.safeRegister(interested: [.reset]) + self.lifecycleManager.finishRegistration()(nil, self.pipeline) + } + + final func becomeActive0(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + assert(self.lifecycleManager.isPreRegistered) + if !self.lifecycleManager.isRegisteredFully { + do { + try self.becomeFullyRegistered0() + assert(self.lifecycleManager.isRegisteredFully) + } catch { + self.close0(error: error, mode: .all, promise: promise) + return + } + } + self.lifecycleManager.activate()(promise, self.pipeline) + guard self.lifecycleManager.isOpen else { + // in the user callout for `channelActive` the channel got closed. + return + } + self.registerForReadEOF() + self.readIfNeeded0() + } + + func register(selector: Selector, interested: SelectorEventSet) throws { + fatalError("must override") + } + + func deregister(selector: Selector, mode: CloseMode) throws { + fatalError("must override") + } + + func reregister(selector: Selector, interested: SelectorEventSet) throws { + fatalError("must override") + } +} + +extension BaseSocketChannel { + public struct SynchronousOptions: NIOSynchronousChannelOptions { + @usableFromInline // should be private + internal let _channel: BaseSocketChannel + + @inlinable // should be fileprivate + internal init(_channel channel: BaseSocketChannel) { + self._channel = channel + } + + @inlinable + public func setOption(_ option: Option, value: Option.Value) throws { + try self._channel.setOption0(option, value: value) + } + + @inlinable + public func getOption(_ option: Option) throws -> Option.Value { + return try self._channel.getOption0(option) + } + } + + public final var syncOptions: NIOSynchronousChannelOptions? { + return SynchronousOptions(_channel: self) + } +} + +/// Execute the given function and synchronously complete the given `EventLoopPromise` (if not `nil`). +func executeAndComplete(_ promise: EventLoopPromise?, _ body: () throws -> Value) { + do { + let result = try body() + promise?.succeed(result) + } catch let e { + promise?.fail(e) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseStreamSocketChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseStreamSocketChannel.swift new file mode 100644 index 00000000..0f09c01a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/BaseStreamSocketChannel.swift @@ -0,0 +1,257 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +class BaseStreamSocketChannel: BaseSocketChannel { + internal var connectTimeoutScheduled: Optional> + private var allowRemoteHalfClosure: Bool = false + private var inputShutdown: Bool = false + private var outputShutdown: Bool = false + private let pendingWrites: PendingStreamWritesManager + + override init(socket: Socket, + parent: Channel?, + eventLoop: SelectableEventLoop, + recvAllocator: RecvByteBufferAllocator) throws { + self.pendingWrites = PendingStreamWritesManager(iovecs: eventLoop.iovecs, storageRefs: eventLoop.storageRefs) + self.connectTimeoutScheduled = nil + try super.init(socket: socket, parent: parent, eventLoop: eventLoop, recvAllocator: recvAllocator) + } + + deinit { + // We should never have any pending writes left as otherwise we may leak callbacks + assert(self.pendingWrites.isEmpty) + } + + // MARK: BaseSocketChannel's must override API that might be further refined by subclasses + override func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.AllowRemoteHalfClosureOption: + self.allowRemoteHalfClosure = value as! Bool + case _ as ChannelOptions.Types.WriteSpinOption: + self.pendingWrites.writeSpinCount = value as! UInt + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + self.pendingWrites.waterMark = value as! ChannelOptions.Types.WriteBufferWaterMark + default: + try super.setOption0(option, value: value) + } + } + + override func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.AllowRemoteHalfClosureOption: + return self.allowRemoteHalfClosure as! Option.Value + case _ as ChannelOptions.Types.WriteSpinOption: + return self.pendingWrites.writeSpinCount as! Option.Value + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + return self.pendingWrites.waterMark as! Option.Value + default: + return try super.getOption0(option) + } + } + + // Hook for customizable socket shutdown processing for subclasses, e.g. PipeChannel + func shutdownSocket(mode: CloseMode) throws { + switch mode { + case .output: + try self.socket.shutdown(how: .WR) + self.outputShutdown = true + case .input: + try socket.shutdown(how: .RD) + self.inputShutdown = true + case .all: + break + } + } + + // MARK: BaseSocketChannel's must override API that cannot be further refined by subclasses + // This is `Channel` API so must be thread-safe. + final override public var isWritable: Bool { + return self.pendingWrites.isWritable + } + + final override var isOpen: Bool { + self.eventLoop.assertInEventLoop() + assert(super.isOpen == self.pendingWrites.isOpen) + return super.isOpen + } + + final override func readFromSocket() throws -> ReadResult { + self.eventLoop.assertInEventLoop() + // Just allocate one time for the while read loop. This is fine as ByteBuffer is a struct and uses COW. + var buffer = self.recvAllocator.buffer(allocator: allocator) + var result = ReadResult.none + for i in 1...self.maxMessagesPerRead { + guard self.isOpen && !self.inputShutdown else { + throw ChannelError.eof + } + // Reset reader and writerIndex and so allow to have the buffer filled again. This is better here than at + // the end of the loop to not do an allocation when the loop exits. + buffer.clear() + switch try buffer.withMutableWritePointer(body: { try self.socket.read(pointer: $0) }) { + case .processed(let bytesRead): + if bytesRead > 0 { + let mayGrow = recvAllocator.record(actualReadBytes: bytesRead) + + self.readPending = false + + assert(self.isActive) + self.pipeline.syncOperations.fireChannelRead(NIOAny(buffer)) + result = .some + + if buffer.writableBytes > 0 { + // If we did not fill the whole buffer with read(...) we should stop reading and wait until we get notified again. + // Otherwise chances are good that the next read(...) call will either read nothing or only a very small amount of data. + // Also this will allow us to call fireChannelReadComplete() which may give the user the chance to flush out all pending + // writes. + return result + } else if mayGrow && i < self.maxMessagesPerRead { + // if the ByteBuffer may grow on the next allocation due we used all the writable bytes we should allocate a new `ByteBuffer` to allow ramping up how much data + // we are able to read on the next read operation. + buffer = self.recvAllocator.buffer(allocator: allocator) + } + } else { + if self.inputShutdown { + // We received a EOF because we called shutdown on the fd by ourself, unregister from the Selector and return + self.readPending = false + self.unregisterForReadable() + return result + } + // end-of-file + throw ChannelError.eof + } + case .wouldBlock(let bytesRead): + assert(bytesRead == 0) + return result + } + } + return result + } + + final override func writeToSocket() throws -> OverallWriteResult { + let result = try self.pendingWrites.triggerAppropriateWriteOperations(scalarBufferWriteOperation: { ptr in + guard ptr.count > 0 else { + // No need to call write if the buffer is empty. + return .processed(0) + } + // normal write + return try self.socket.write(pointer: ptr) + }, vectorBufferWriteOperation: { ptrs in + // Gathering write + try self.socket.writev(iovecs: ptrs) + }, scalarFileWriteOperation: { descriptor, index, endIndex in + try self.socket.sendFile(fd: descriptor, offset: index, count: endIndex - index) + }) + return result + } + + final override func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + do { + switch mode { + case .output: + if self.outputShutdown { + promise?.fail(ChannelError.outputClosed) + return + } + try self.shutdownSocket(mode: mode) + // Fail all pending writes and so ensure all pending promises are notified + self.pendingWrites.failAll(error: error, close: false) + self.unregisterForWritable() + promise?.succeed(()) + + self.pipeline.fireUserInboundEventTriggered(ChannelEvent.outputClosed) + case .input: + if self.inputShutdown { + promise?.fail(ChannelError.inputClosed) + return + } + switch error { + case ChannelError.eof: + // No need to explicit call socket.shutdown(...) as we received an EOF and the call would only cause + // ENOTCON + self.inputShutdown = true + break + default: + try self.shutdownSocket(mode: mode) + } + self.unregisterForReadable() + promise?.succeed(()) + + self.pipeline.fireUserInboundEventTriggered(ChannelEvent.inputClosed) + case .all: + if let timeout = self.connectTimeoutScheduled { + self.connectTimeoutScheduled = nil + timeout.cancel() + } + super.close0(error: error, mode: mode, promise: promise) + } + } catch let err { + promise?.fail(err) + } + } + + final override func hasFlushedPendingWrites() -> Bool { + return self.pendingWrites.isFlushPending + } + + final override func markFlushPoint() { + // Even if writable() will be called later by the EventLoop we still need to mark the flush checkpoint so we are sure all the flushed messages + // are actually written once writable() is called. + self.pendingWrites.markFlushCheckpoint() + } + + final override func cancelWritesOnClose(error: Error) { + self.pendingWrites.failAll(error: error, close: true) + } + + @discardableResult + final override func readIfNeeded0() -> Bool { + if self.inputShutdown { + return false + } + return super.readIfNeeded0() + } + + final override public func read0() { + if self.inputShutdown { + return + } + super.read0() + } + + final override func bufferPendingWrite(data: NIOAny, promise: EventLoopPromise?) { + if self.outputShutdown { + promise?.fail(ChannelError.outputClosed) + return + } + + let data = self.unwrapData(data, as: IOData.self) + + if !self.pendingWrites.add(data: data, promise: promise) { + self.pipeline.syncOperations.fireChannelWritabilityChanged() + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Bootstrap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Bootstrap.swift new file mode 100644 index 00000000..c0f5a0e2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Bootstrap.swift @@ -0,0 +1,1125 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// The type of all `channelInitializer` callbacks. +internal typealias ChannelInitializerCallback = (Channel) -> EventLoopFuture + +/// Common functionality for all NIO on sockets bootstraps. +internal enum NIOOnSocketsBootstraps { + internal static func isCompatible(group: EventLoopGroup) -> Bool { + return group is SelectableEventLoop || group is MultiThreadedEventLoopGroup + } +} + +/// A `ServerBootstrap` is an easy way to bootstrap a `ServerSocketChannel` when creating network servers. +/// +/// Example: +/// +/// ```swift +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) +/// defer { +/// try! group.syncShutdownGracefully() +/// } +/// let bootstrap = ServerBootstrap(group: group) +/// // Specify backlog and enable SO_REUSEADDR for the server itself +/// .serverChannelOption(ChannelOptions.backlog, value: 256) +/// .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) +/// +/// // Set the handlers that are applied to the accepted child `Channel`s. +/// .childChannelInitializer { channel in +/// // Ensure we don't read faster then we can write by adding the BackPressureHandler into the pipeline. +/// channel.pipeline.addHandler(BackPressureHandler()).flatMap { () in +/// // make sure to instantiate your `ChannelHandlers` inside of +/// // the closure as it will be invoked once per connection. +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// } +/// +/// // Enable SO_REUSEADDR for the accepted Channels +/// .childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) +/// .childChannelOption(ChannelOptions.maxMessagesPerRead, value: 16) +/// .childChannelOption(ChannelOptions.recvAllocator, value: AdaptiveRecvByteBufferAllocator()) +/// let channel = try! bootstrap.bind(host: host, port: port).wait() +/// /* the server will now be accepting connections */ +/// +/// try! channel.closeFuture.wait() // wait forever as we never close the Channel +/// ``` +/// +/// The `EventLoopFuture` returned by `bind` will fire with a `ServerSocketChannel`. This is the channel that owns the listening socket. +/// Each time it accepts a new connection it will fire a `SocketChannel` through the `ChannelPipeline` via `fireChannelRead`: as a result, +/// the `ServerSocketChannel` operates on `Channel`s as inbound messages. Outbound messages are not supported on a `ServerSocketChannel` +/// which means that each write attempt will fail. +/// +/// Accepted `SocketChannel`s operate on `ByteBuffer` as inbound data, and `IOData` as outbound data. +public final class ServerBootstrap { + + private let group: EventLoopGroup + private let childGroup: EventLoopGroup + private var serverChannelInit: Optional + private var childChannelInit: Optional + @usableFromInline + internal var _serverChannelOptions: ChannelOptions.Storage + @usableFromInline + internal var _childChannelOptions: ChannelOptions.Storage + + /// Create a `ServerBootstrap` on the `EventLoopGroup` `group`. + /// + /// The `EventLoopGroup` `group` must be compatible, otherwise the program will crash. `ServerBootstrap` is + /// compatible only with `MultiThreadedEventLoopGroup` as well as the `EventLoop`s returned by + /// `MultiThreadedEventLoopGroup.next`. See `init(validatingGroup:childGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup`s are compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `bind` of the `ServerSocketChannel` and to accept new `SocketChannel`s with. + public convenience init(group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + preconditionFailure("ServerBootstrap is only compatible with MultiThreadedEventLoopGroup and " + + "SelectableEventLoop. You tried constructing one with \(group) which is incompatible.") + } + self.init(validatingGroup: group, childGroup: group)! + } + + /// Create a `ServerBootstrap` on the `EventLoopGroup` `group` which accepts `Channel`s on `childGroup`. + /// + /// The `EventLoopGroup`s `group` and `childGroup` must be compatible, otherwise the program will crash. + /// `ServerBootstrap` is compatible only with `MultiThreadedEventLoopGroup` as well as the `EventLoop`s returned by + /// `MultiThreadedEventLoopGroup.next`. See `init(validatingGroup:childGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup`s are compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `bind` of the `ServerSocketChannel` and to accept new `SocketChannel`s with. + /// - childGroup: The `EventLoopGroup` to run the accepted `SocketChannel`s on. + public convenience init(group: EventLoopGroup, childGroup: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) && NIOOnSocketsBootstraps.isCompatible(group: childGroup) else { + preconditionFailure("ServerBootstrap is only compatible with MultiThreadedEventLoopGroup and " + + "SelectableEventLoop. You tried constructing one with group: \(group) and " + + "childGroup: \(childGroup) at least one of which is incompatible.") + } + self.init(validatingGroup: group, childGroup: childGroup)! + + } + + /// Create a `ServerBootstrap` on the `EventLoopGroup` `group` which accepts `Channel`s on `childGroup`, validating + /// that the `EventLoopGroup`s are compatible with `ServerBootstrap`. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `bind` of the `ServerSocketChannel` and to accept new `SocketChannel`s with. + /// - childGroup: The `EventLoopGroup` to run the accepted `SocketChannel`s on. If `nil`, `group` is used. + public init?(validatingGroup group: EventLoopGroup, childGroup: EventLoopGroup? = nil) { + let childGroup = childGroup ?? group + guard NIOOnSocketsBootstraps.isCompatible(group: group) && NIOOnSocketsBootstraps.isCompatible(group: childGroup) else { + return nil + } + + self.group = group + self.childGroup = childGroup + self._serverChannelOptions = ChannelOptions.Storage() + self._childChannelOptions = ChannelOptions.Storage() + self.serverChannelInit = nil + self.childChannelInit = nil + self._serverChannelOptions.append(key: ChannelOptions.tcpOption(.tcp_nodelay), value: 1) + } + + /// Initialize the `ServerSocketChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The `ServerSocketChannel` uses the accepted `Channel`s as inbound messages. + /// + /// - note: To set the initializer for the accepted `SocketChannel`s, look at `ServerBootstrap.childChannelInitializer`. + /// + /// - parameters: + /// - initializer: A closure that initializes the provided `Channel`. + public func serverChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self { + self.serverChannelInit = initializer + return self + } + + /// Initialize the accepted `SocketChannel`s with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. Note that if the `initializer` fails then the error will be + /// fired in the *parent* channel. + /// + /// - warning: The `initializer` will be invoked once for every accepted connection. Therefore it's usually the + /// right choice to instantiate stateful `ChannelHandler`s within the closure to make sure they are not + /// accidentally shared across `Channel`s. There are expert use-cases where stateful handler need to be + /// shared across `Channel`s in which case the user is responsible to synchronise the state access + /// appropriately. + /// + /// The accepted `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - parameters: + /// - initializer: A closure that initializes the provided `Channel`. + public func childChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self { + self.childChannelInit = initializer + return self + } + + /// Specifies a `ChannelOption` to be applied to the `ServerSocketChannel`. + /// + /// - note: To specify options for the accepted `SocketChannel`s, look at `ServerBootstrap.childChannelOption`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + @inlinable + public func serverChannelOption(_ option: Option, value: Option.Value) -> Self { + self._serverChannelOptions.append(key: option, value: value) + return self + } + + /// Specifies a `ChannelOption` to be applied to the accepted `SocketChannel`s. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + @inlinable + public func childChannelOption(_ option: Option, value: Option.Value) -> Self { + self._childChannelOptions.append(key: option, value: value) + return self + } + + /// Specifies a timeout to apply to a bind attempt. Currently unsupported. + /// + /// - parameters: + /// - timeout: The timeout that will apply to the bind attempt. + public func bindTimeout(_ timeout: TimeAmount) -> Self { + return self + } + + /// Bind the `ServerSocketChannel` to `host` and `port`. + /// + /// - parameters: + /// - host: The host to bind on. + /// - port: The port to bind on. + public func bind(host: String, port: Int) -> EventLoopFuture { + return bind0 { + return try SocketAddress.makeAddressResolvingHost(host, port: port) + } + } + + /// Bind the `ServerSocketChannel` to `address`. + /// + /// - parameters: + /// - address: The `SocketAddress` to bind on. + public func bind(to address: SocketAddress) -> EventLoopFuture { + return bind0 { address } + } + + /// Bind the `ServerSocketChannel` to a UNIX Domain Socket. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system. + public func bind(unixDomainSocketPath: String) -> EventLoopFuture { + return bind0 { + try SocketAddress(unixDomainSocketPath: unixDomainSocketPath) + } + } + + /// Bind the `ServerSocketChannel` to a UNIX Domain Socket. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system. + /// - cleanupExistingSocketFile: Whether to cleanup an existing socket file at `path`. + public func bind(unixDomainSocketPath: String, cleanupExistingSocketFile: Bool) -> EventLoopFuture { + if cleanupExistingSocketFile { + do { + try BaseSocket.cleanupSocket(unixDomainSocketPath: unixDomainSocketPath) + } catch { + return group.next().makeFailedFuture(error) + } + } + + return self.bind(unixDomainSocketPath: unixDomainSocketPath) + } + + #if !os(Windows) + /// Use the existing bound socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound stream socket. + @available(*, deprecated, renamed: "withBoundSocket(_:)") + public func withBoundSocket(descriptor: CInt) -> EventLoopFuture { + return withBoundSocket(descriptor) + } + #endif + + /// Use the existing bound socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound stream socket. + public func withBoundSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture { + func makeChannel(_ eventLoop: SelectableEventLoop, _ childEventLoopGroup: EventLoopGroup) throws -> ServerSocketChannel { + return try ServerSocketChannel(socket: socket, eventLoop: eventLoop, group: childEventLoopGroup) + } + return bind0(makeServerChannel: makeChannel) { (eventLoop, serverChannel) in + let promise = eventLoop.makePromise(of: Void.self) + serverChannel.registerAlreadyConfigured0(promise: promise) + return promise.futureResult + } + } + + private func bind0(_ makeSocketAddress: () throws -> SocketAddress) -> EventLoopFuture { + let address: SocketAddress + do { + address = try makeSocketAddress() + } catch { + return group.next().makeFailedFuture(error) + } + func makeChannel(_ eventLoop: SelectableEventLoop, _ childEventLoopGroup: EventLoopGroup) throws -> ServerSocketChannel { + return try ServerSocketChannel(eventLoop: eventLoop, + group: childEventLoopGroup, + protocolFamily: address.protocol) + } + + return bind0(makeServerChannel: makeChannel) { (eventLoop, serverChannel) in + serverChannel.registerAndDoSynchronously { serverChannel in + serverChannel.bind(to: address) + } + } + } + + private func bind0(makeServerChannel: (_ eventLoop: SelectableEventLoop, _ childGroup: EventLoopGroup) throws -> ServerSocketChannel, _ register: @escaping (EventLoop, ServerSocketChannel) -> EventLoopFuture) -> EventLoopFuture { + let eventLoop = self.group.next() + let childEventLoopGroup = self.childGroup + let serverChannelOptions = self._serverChannelOptions + let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.makeSucceededFuture(()) } + let childChannelInit = self.childChannelInit + let childChannelOptions = self._childChannelOptions + + let serverChannel: ServerSocketChannel + do { + serverChannel = try makeServerChannel(eventLoop as! SelectableEventLoop, childEventLoopGroup) + } catch { + return eventLoop.makeFailedFuture(error) + } + + return eventLoop.submit { + serverChannelOptions.applyAllChannelOptions(to: serverChannel).flatMap { + serverChannelInit(serverChannel) + }.flatMap { + serverChannel.pipeline.addHandler(AcceptHandler(childChannelInitializer: childChannelInit, + childChannelOptions: childChannelOptions), + name: "AcceptHandler") + }.flatMap { + register(eventLoop, serverChannel) + }.map { + serverChannel as Channel + }.flatMapError { error in + serverChannel.close0(error: error, mode: .all, promise: nil) + return eventLoop.makeFailedFuture(error) + } + }.flatMap { + $0 + } + } + + private class AcceptHandler: ChannelInboundHandler { + public typealias InboundIn = SocketChannel + + private let childChannelInit: ((Channel) -> EventLoopFuture)? + private let childChannelOptions: ChannelOptions.Storage + + init(childChannelInitializer: ((Channel) -> EventLoopFuture)?, childChannelOptions: ChannelOptions.Storage) { + self.childChannelInit = childChannelInitializer + self.childChannelOptions = childChannelOptions + } + + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if event is ChannelShouldQuiesceEvent { + context.channel.close().whenFailure { error in + context.fireErrorCaught(error) + } + } + context.fireUserInboundEventTriggered(event) + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let accepted = self.unwrapInboundIn(data) + let ctxEventLoop = context.eventLoop + let childEventLoop = accepted.eventLoop + let childChannelInit = self.childChannelInit ?? { (_: Channel) in childEventLoop.makeSucceededFuture(()) } + + @inline(__always) + func setupChildChannel() -> EventLoopFuture { + return self.childChannelOptions.applyAllChannelOptions(to: accepted).flatMap { () -> EventLoopFuture in + childEventLoop.assertInEventLoop() + return childChannelInit(accepted) + } + } + + @inline(__always) + func fireThroughPipeline(_ future: EventLoopFuture) { + ctxEventLoop.assertInEventLoop() + future.flatMap { (_) -> EventLoopFuture in + ctxEventLoop.assertInEventLoop() + guard context.channel.isActive else { + return context.eventLoop.makeFailedFuture(ChannelError.ioOnClosedChannel) + } + context.fireChannelRead(data) + return context.eventLoop.makeSucceededFuture(()) + }.whenFailure { error in + ctxEventLoop.assertInEventLoop() + self.closeAndFire(context: context, accepted: accepted, err: error) + } + } + + if childEventLoop === ctxEventLoop { + fireThroughPipeline(setupChildChannel()) + } else { + fireThroughPipeline(childEventLoop.flatSubmit { + return setupChildChannel() + }.hop(to: ctxEventLoop)) + } + } + + private func closeAndFire(context: ChannelHandlerContext, accepted: SocketChannel, err: Error) { + accepted.close(promise: nil) + if context.eventLoop.inEventLoop { + context.fireErrorCaught(err) + } else { + context.eventLoop.execute { + context.fireErrorCaught(err) + } + } + } + } +} + +private extension Channel { + func registerAndDoSynchronously(_ body: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + // this is pretty delicate at the moment: + // In many cases `body` must be _synchronously_ follow `register`, otherwise in our current + // implementation, `epoll` will send us `EPOLLHUP`. To have it run synchronously, we need to invoke the + // `flatMap` on the eventloop that the `register` will succeed on. + self.eventLoop.assertInEventLoop() + return self.register().flatMap { + self.eventLoop.assertInEventLoop() + return body(self) + } + } +} + +/// A `ClientBootstrap` is an easy way to bootstrap a `SocketChannel` when creating network clients. +/// +/// Usually you re-use a `ClientBootstrap` once you set it up and called `connect` multiple times on it. +/// This way you ensure that the same `EventLoop`s will be shared across all your connections. +/// +/// Example: +/// +/// ```swift +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) +/// defer { +/// try! group.syncShutdownGracefully() +/// } +/// let bootstrap = ClientBootstrap(group: group) +/// // Enable SO_REUSEADDR. +/// .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) +/// .channelInitializer { channel in +/// // always instantiate the handler _within_ the closure as +/// // it may be called multiple times (for example if the hostname +/// // resolves to both IPv4 and IPv6 addresses, cf. Happy Eyeballs). +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// try! bootstrap.connect(host: "example.org", port: 12345).wait() +/// /* the Channel is now connected */ +/// ``` +/// +/// The connected `SocketChannel` will operate on `ByteBuffer` as inbound and on `IOData` as outbound messages. +public final class ClientBootstrap: NIOClientTCPBootstrapProtocol { + private let group: EventLoopGroup + private var protocolHandlers: Optional<() -> [ChannelHandler]> + private var _channelInitializer: ChannelInitializerCallback + private var channelInitializer: ChannelInitializerCallback { + if let protocolHandlers = self.protocolHandlers { + return { channel in + self._channelInitializer(channel).flatMap { + channel.pipeline.addHandlers(protocolHandlers(), position: .first) + } + } + } else { + return self._channelInitializer + } + } + @usableFromInline + internal var _channelOptions: ChannelOptions.Storage + private var connectTimeout: TimeAmount = TimeAmount.seconds(10) + private var resolver: Optional + private var bindTarget: Optional + + /// Create a `ClientBootstrap` on the `EventLoopGroup` `group`. + /// + /// The `EventLoopGroup` `group` must be compatible, otherwise the program will crash. `ClientBootstrap` is + /// compatible only with `MultiThreadedEventLoopGroup` as well as the `EventLoop`s returned by + /// `MultiThreadedEventLoopGroup.next`. See `init(validatingGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup` is compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public convenience init(group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + preconditionFailure("ClientBootstrap is only compatible with MultiThreadedEventLoopGroup and " + + "SelectableEventLoop. You tried constructing one with \(group) which is incompatible.") + } + self.init(validatingGroup: group)! + } + + /// Create a `ClientBootstrap` on the `EventLoopGroup` `group`, validating that `group` is compatible. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public init?(validatingGroup group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + return nil + } + self.group = group + self._channelOptions = ChannelOptions.Storage() + self._channelOptions.append(key: ChannelOptions.tcpOption(.tcp_nodelay), value: 1) + self._channelInitializer = { channel in channel.eventLoop.makeSucceededFuture(()) } + self.protocolHandlers = nil + self.resolver = nil + self.bindTarget = nil + } + + /// Initialize the connected `SocketChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The connected `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - warning: The `handler` closure may be invoked _multiple times_ so it's usually the right choice to instantiate + /// `ChannelHandler`s within `handler`. The reason `handler` may be invoked multiple times is that to + /// successfully set up a connection multiple connections might be setup in the process. Assuming a + /// hostname that resolves to both IPv4 and IPv6 addresses, NIO will follow + /// [_Happy Eyeballs_](https://en.wikipedia.org/wiki/Happy_Eyeballs) and race both an IPv4 and an IPv6 + /// connection. It is possible that both connections get fully established before the IPv4 connection + /// will be closed again because the IPv6 connection 'won the race'. Therefore the `channelInitializer` + /// might be called multiple times and it's important not to share stateful `ChannelHandler`s in more + /// than one `Channel`. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + public func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self { + self._channelInitializer = handler + return self + } + + /// Sets the protocol handlers that will be added to the front of the `ChannelPipeline` right after the + /// `channelInitializer` has been called. + /// + /// Per bootstrap, you can only set the `protocolHandlers` once. Typically, `protocolHandlers` are used for the TLS + /// implementation. Most notably, `NIOClientTCPBootstrap`, NIO's "universal bootstrap" abstraction, uses + /// `protocolHandlers` to add the required `ChannelHandler`s for many TLS implementations. + public func protocolHandlers(_ handlers: @escaping () -> [ChannelHandler]) -> Self { + precondition(self.protocolHandlers == nil, "protocol handlers can only be set once") + self.protocolHandlers = handlers + return self + } + + /// Specifies a `ChannelOption` to be applied to the `SocketChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + @inlinable + public func channelOption(_ option: Option, value: Option.Value) -> Self { + self._channelOptions.append(key: option, value: value) + return self + } + + /// Specifies a timeout to apply to a connection attempt. + /// + /// - parameters: + /// - timeout: The timeout that will apply to the connection attempt. + public func connectTimeout(_ timeout: TimeAmount) -> Self { + self.connectTimeout = timeout + return self + } + + /// Specifies the `Resolver` to use or `nil` if the default should be used. + /// + /// - parameters: + /// - resolver: The resolver that will be used during the connection attempt. + public func resolver(_ resolver: Resolver?) -> Self { + self.resolver = resolver + return self + } + + /// Bind the `SocketChannel` to `address`. + /// + /// Using `bind` is not necessary unless you need the local address to be bound to a specific address. + /// + /// - note: Using `bind` will disable Happy Eyeballs on this `Channel`. + /// + /// - parameters: + /// - address: The `SocketAddress` to bind on. + public func bind(to address: SocketAddress) -> ClientBootstrap { + self.bindTarget = address + return self + } + + func makeSocketChannel(eventLoop: EventLoop, + protocolFamily: NIOBSDSocket.ProtocolFamily) throws -> SocketChannel { + return try SocketChannel(eventLoop: eventLoop as! SelectableEventLoop, protocolFamily: protocolFamily) + } + + /// Specify the `host` and `port` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - host: The host to connect to. + /// - port: The port to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(host: String, port: Int) -> EventLoopFuture { + let loop = self.group.next() + let resolver = self.resolver ?? GetaddrinfoResolver(loop: loop, + aiSocktype: .stream, + aiProtocol: CInt(IPPROTO_TCP)) + let connector = HappyEyeballsConnector(resolver: resolver, + loop: loop, + host: host, + port: port, + connectTimeout: self.connectTimeout) { eventLoop, protocolFamily in + return self.initializeAndRegisterNewChannel(eventLoop: eventLoop, protocolFamily: protocolFamily) { + $0.eventLoop.makeSucceededFuture(()) + } + } + return connector.resolveAndConnect() + } + + private func connect(freshChannel channel: Channel, address: SocketAddress) -> EventLoopFuture { + let connectPromise = channel.eventLoop.makePromise(of: Void.self) + channel.connect(to: address, promise: connectPromise) + let cancelTask = channel.eventLoop.scheduleTask(in: self.connectTimeout) { + connectPromise.fail(ChannelError.connectTimeout(self.connectTimeout)) + channel.close(promise: nil) + } + + connectPromise.futureResult.whenComplete { (_: Result) in + cancelTask.cancel() + } + return connectPromise.futureResult + } + + internal func testOnly_connect(injectedChannel: SocketChannel, + to address: SocketAddress) -> EventLoopFuture { + return self.initializeAndRegisterChannel(injectedChannel) { channel in + return self.connect(freshChannel: channel, address: address) + } + } + + /// Specify the `address` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - address: The address to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(to address: SocketAddress) -> EventLoopFuture { + return self.initializeAndRegisterNewChannel(eventLoop: self.group.next(), + protocolFamily: address.protocol) { channel in + return self.connect(freshChannel: channel, address: address) + } + } + + /// Specify the `unixDomainSocket` path to connect to for the UDS `Channel` that will be established. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(unixDomainSocketPath: String) -> EventLoopFuture { + do { + let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath) + return self.connect(to: address) + } catch { + return self.group.next().makeFailedFuture(error) + } + } + + #if !os(Windows) + /// Use the existing connected socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the connected stream socket. + /// - returns: an `EventLoopFuture` to deliver the `Channel`. + @available(*, deprecated, renamed: "withConnectedSocket(_:)") + public func withConnectedSocket(descriptor: CInt) -> EventLoopFuture { + return self.withConnectedSocket(descriptor) + } + #endif + + /// Use the existing connected socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the connected stream socket. + /// - returns: an `EventLoopFuture` to deliver the `Channel`. + public func withConnectedSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture { + let eventLoop = group.next() + let channelInitializer = self.channelInitializer + let channel: SocketChannel + do { + channel = try SocketChannel(eventLoop: eventLoop as! SelectableEventLoop, socket: socket) + } catch { + return eventLoop.makeFailedFuture(error) + } + + func setupChannel() -> EventLoopFuture { + eventLoop.assertInEventLoop() + return self._channelOptions.applyAllChannelOptions(to: channel).flatMap { + channelInitializer(channel) + }.flatMap { + eventLoop.assertInEventLoop() + let promise = eventLoop.makePromise(of: Void.self) + channel.registerAlreadyConfigured0(promise: promise) + return promise.futureResult + }.map { + channel + }.flatMapError { error in + channel.close0(error: error, mode: .all, promise: nil) + return channel.eventLoop.makeFailedFuture(error) + } + } + + if eventLoop.inEventLoop { + return setupChannel() + } else { + return eventLoop.flatSubmit { setupChannel() } + } + } + + private func initializeAndRegisterNewChannel(eventLoop: EventLoop, + protocolFamily: NIOBSDSocket.ProtocolFamily, + _ body: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + let channel: SocketChannel + do { + channel = try self.makeSocketChannel(eventLoop: eventLoop, protocolFamily: protocolFamily) + } catch { + return eventLoop.makeFailedFuture(error) + } + return self.initializeAndRegisterChannel(channel, body) + } + + private func initializeAndRegisterChannel(_ channel: SocketChannel, + _ body: @escaping (Channel) -> EventLoopFuture) -> EventLoopFuture { + let channelInitializer = self.channelInitializer + let channelOptions = self._channelOptions + let eventLoop = channel.eventLoop + + @inline(__always) + func setupChannel() -> EventLoopFuture { + eventLoop.assertInEventLoop() + return channelOptions.applyAllChannelOptions(to: channel).flatMap { + if let bindTarget = self.bindTarget { + return channel.bind(to: bindTarget).flatMap { + channelInitializer(channel) + } + } else { + return channelInitializer(channel) + } + }.flatMap { + eventLoop.assertInEventLoop() + return channel.registerAndDoSynchronously(body) + }.map { + channel + }.flatMapError { error in + channel.close0(error: error, mode: .all, promise: nil) + return channel.eventLoop.makeFailedFuture(error) + } + } + + if eventLoop.inEventLoop { + return setupChannel() + } else { + return eventLoop.flatSubmit { + setupChannel() + } + } + } +} + +/// A `DatagramBootstrap` is an easy way to bootstrap a `DatagramChannel` when creating datagram clients +/// and servers. +/// +/// Example: +/// +/// ```swift +/// let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) +/// defer { +/// try! group.syncShutdownGracefully() +/// } +/// let bootstrap = DatagramBootstrap(group: group) +/// // Enable SO_REUSEADDR. +/// .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) +/// .channelInitializer { channel in +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// let channel = try! bootstrap.bind(host: "127.0.0.1", port: 53).wait() +/// /* the Channel is now ready to send/receive datagrams */ +/// +/// try channel.closeFuture.wait() // Wait until the channel un-binds. +/// ``` +/// +/// The `DatagramChannel` will operate on `AddressedEnvelope` as inbound and outbound messages. +public final class DatagramBootstrap { + + private let group: EventLoopGroup + private var channelInitializer: Optional + @usableFromInline + internal var _channelOptions: ChannelOptions.Storage + + /// Create a `DatagramBootstrap` on the `EventLoopGroup` `group`. + /// + /// The `EventLoopGroup` `group` must be compatible, otherwise the program will crash. `DatagramBootstrap` is + /// compatible only with `MultiThreadedEventLoopGroup` as well as the `EventLoop`s returned by + /// `MultiThreadedEventLoopGroup.next`. See `init(validatingGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup` is compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public convenience init(group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + preconditionFailure("DatagramBootstrap is only compatible with MultiThreadedEventLoopGroup and " + + "SelectableEventLoop. You tried constructing one with \(group) which is incompatible.") + } + self.init(validatingGroup: group)! + } + + /// Create a `DatagramBootstrap` on the `EventLoopGroup` `group`, validating that `group` is compatible. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public init?(validatingGroup group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + return nil + } + self._channelOptions = ChannelOptions.Storage() + self.group = group + self.channelInitializer = nil + } + + /// Initialize the bound `DatagramChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + public func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self { + self.channelInitializer = handler + return self + } + + /// Specifies a `ChannelOption` to be applied to the `DatagramChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + @inlinable + public func channelOption(_ option: Option, value: Option.Value) -> Self { + self._channelOptions.append(key: option, value: value) + return self + } + + #if !os(Windows) + /// Use the existing bound socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound datagram socket. + @available(*, deprecated, renamed: "withBoundSocket(_:)") + public func withBoundSocket(descriptor: CInt) -> EventLoopFuture { + return self.withBoundSocket(descriptor) + } + #endif + + /// Use the existing bound socket file descriptor. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound datagram socket. + public func withBoundSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture { + func makeChannel(_ eventLoop: SelectableEventLoop) throws -> DatagramChannel { + return try DatagramChannel(eventLoop: eventLoop, socket: socket) + } + return bind0(makeChannel: makeChannel) { (eventLoop, channel) in + let promise = eventLoop.makePromise(of: Void.self) + channel.registerAlreadyConfigured0(promise: promise) + return promise.futureResult + } + } + + /// Bind the `DatagramChannel` to `host` and `port`. + /// + /// - parameters: + /// - host: The host to bind on. + /// - port: The port to bind on. + public func bind(host: String, port: Int) -> EventLoopFuture { + return bind0 { + return try SocketAddress.makeAddressResolvingHost(host, port: port) + } + } + + /// Bind the `DatagramChannel` to `address`. + /// + /// - parameters: + /// - address: The `SocketAddress` to bind on. + public func bind(to address: SocketAddress) -> EventLoopFuture { + return bind0 { address } + } + + /// Bind the `DatagramChannel` to a UNIX Domain Socket. + /// + /// - parameters: + /// - unixDomainSocketPath: The path of the UNIX Domain Socket to bind on. `path` must not exist, it will be created by the system. + public func bind(unixDomainSocketPath: String) -> EventLoopFuture { + return bind0 { + return try SocketAddress(unixDomainSocketPath: unixDomainSocketPath) + } + } + + /// Bind the `DatagramChannel` to a UNIX Domain Socket. + /// + /// - parameters: + /// - unixDomainSocketPath: The path of the UNIX Domain Socket to bind on. `path` must not exist, it will be created by the system. + /// - cleanupExistingSocketFile: Whether to cleanup an existing socket file at `path`. + public func bind(unixDomainSocketPath: String, cleanupExistingSocketFile: Bool) -> EventLoopFuture { + if cleanupExistingSocketFile { + do { + try BaseSocket.cleanupSocket(unixDomainSocketPath: unixDomainSocketPath) + } catch { + return group.next().makeFailedFuture(error) + } + } + + return self.bind(unixDomainSocketPath: unixDomainSocketPath) + } + + private func bind0(_ makeSocketAddress: () throws -> SocketAddress) -> EventLoopFuture { + let address: SocketAddress + do { + address = try makeSocketAddress() + } catch { + return group.next().makeFailedFuture(error) + } + func makeChannel(_ eventLoop: SelectableEventLoop) throws -> DatagramChannel { + return try DatagramChannel(eventLoop: eventLoop, + protocolFamily: address.protocol) + } + return bind0(makeChannel: makeChannel) { (eventLoop, channel) in + channel.register().flatMap { + channel.bind(to: address) + } + } + } + + private func bind0(makeChannel: (_ eventLoop: SelectableEventLoop) throws -> DatagramChannel, _ registerAndBind: @escaping (EventLoop, DatagramChannel) -> EventLoopFuture) -> EventLoopFuture { + let eventLoop = self.group.next() + let channelInitializer = self.channelInitializer ?? { _ in eventLoop.makeSucceededFuture(()) } + let channelOptions = self._channelOptions + + let channel: DatagramChannel + do { + channel = try makeChannel(eventLoop as! SelectableEventLoop) + } catch { + return eventLoop.makeFailedFuture(error) + } + + func setupChannel() -> EventLoopFuture { + eventLoop.assertInEventLoop() + return channelOptions.applyAllChannelOptions(to: channel).flatMap { + channelInitializer(channel) + }.flatMap { + eventLoop.assertInEventLoop() + return registerAndBind(eventLoop, channel) + }.map { + channel + }.flatMapError { error in + eventLoop.makeFailedFuture(error) + } + } + + if eventLoop.inEventLoop { + return setupChannel() + } else { + return eventLoop.flatSubmit { + setupChannel() + } + } + } +} + +/// A `NIOPipeBootstrap` is an easy way to bootstrap a `PipeChannel` which uses two (uni-directional) UNIX pipes +/// and makes a `Channel` out of them. +/// +/// Example bootstrapping a `Channel` using `stdin` and `stdout`: +/// +/// let channel = try NIOPipeBootstrap(group: group) +/// .channelInitializer { channel in +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// .withPipes(inputDescriptor: STDIN_FILENO, outputDescriptor: STDOUT_FILENO) +/// +public final class NIOPipeBootstrap { + private let group: EventLoopGroup + private var channelInitializer: Optional + @usableFromInline + internal var _channelOptions: ChannelOptions.Storage + + /// Create a `NIOPipeBootstrap` on the `EventLoopGroup` `group`. + /// + /// The `EventLoopGroup` `group` must be compatible, otherwise the program will crash. `NIOPipeBootstrap` is + /// compatible only with `MultiThreadedEventLoopGroup` as well as the `EventLoop`s returned by + /// `MultiThreadedEventLoopGroup.next`. See `init(validatingGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup`s are compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public convenience init(group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + preconditionFailure("NIOPipeBootstrap is only compatible with MultiThreadedEventLoopGroup and " + + "SelectableEventLoop. You tried constructing one with \(group) which is incompatible.") + } + self.init(validatingGroup: group)! + } + + /// Create a `NIOPipeBootstrap` on the `EventLoopGroup` `group`, validating that `group` is compatible. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public init?(validatingGroup group: EventLoopGroup) { + guard NIOOnSocketsBootstraps.isCompatible(group: group) else { + return nil + } + + self._channelOptions = ChannelOptions.Storage() + self.group = group + self.channelInitializer = nil + } + + /// Initialize the connected `PipeChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The connected `Channel` will operate on `ByteBuffer` as inbound and outbound messages. Please note that + /// `IOData.fileRegion` is _not_ supported for `PipeChannel`s because `sendfile` only works on sockets. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + public func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self { + self.channelInitializer = handler + return self + } + + /// Specifies a `ChannelOption` to be applied to the `PipeChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + @inlinable + public func channelOption(_ option: Option, value: Option.Value) -> Self { + self._channelOptions.append(key: option, value: value) + return self + } + + private func validateFileDescriptorIsNotAFile(_ descriptor: CInt) throws { + var s: stat = .init() + try withUnsafeMutablePointer(to: &s) { ptr in + try Posix.fstat(descriptor: descriptor, outStat: ptr) + } + switch s.st_mode & S_IFMT { + case S_IFREG, S_IFDIR, S_IFLNK, S_IFBLK: + throw ChannelError.operationUnsupported + default: + () // Let's default to ok + } + } + + /// Create the `PipeChannel` with the provided file descriptor which is used for both input & output. + /// + /// This method is useful for specialilsed use-cases where you want to use `NIOPipeBootstrap` for say a serial line. + /// + /// - note: If this method returns a succeeded future, SwiftNIO will close `fileDescriptor` when the `Channel` + /// becomes inactive. You _must not_ do any further operations with `fileDescriptor`, including `close`. + /// If this method returns a failed future, you still own the file descriptor and are responsible for + /// closing it. + /// + /// - parameters: + /// - fileDescriptor: The _Unix file descriptor_ for the input & output. + /// - returns: an `EventLoopFuture` to deliver the `Channel`. + public func withInputOutputDescriptor(_ fileDescriptor: CInt) -> EventLoopFuture { + let inputFD = fileDescriptor + let outputFD = dup(fileDescriptor) + + return self.withPipes(inputDescriptor: inputFD, outputDescriptor: outputFD).flatMapErrorThrowing { error in + try! Posix.close(descriptor: outputFD) + throw error + } + } + + /// Create the `PipeChannel` with the provided input and output file descriptors. + /// + /// The input and output file descriptors must be distinct. If you have a single file descriptor, consider using + /// `ClientBootstrap.withConnectedSocket(descriptor:)` if it's a socket or + /// `NIOPipeBootstrap.withInputOutputDescriptor` if it is not a socket. + /// + /// - note: If this method returns a succeeded future, SwiftNIO will close `inputDescriptor` and `outputDescriptor` + /// when the `Channel` becomes inactive. You _must not_ do any further operations `inputDescriptor` or + /// `outputDescriptor`, including `close`. + /// If this method returns a failed future, you still own the file descriptors and are responsible for + /// closing them. + /// + /// - parameters: + /// - inputDescriptor: The _Unix file descriptor_ for the input (ie. the read side). + /// - outputDescriptor: The _Unix file descriptor_ for the output (ie. the write side). + /// - returns: an `EventLoopFuture` to deliver the `Channel`. + public func withPipes(inputDescriptor: CInt, outputDescriptor: CInt) -> EventLoopFuture { + precondition(inputDescriptor >= 0 && outputDescriptor >= 0 && inputDescriptor != outputDescriptor, + "illegal file descriptor pair. The file descriptors \(inputDescriptor), \(outputDescriptor) " + + "must be distinct and both positive integers.") + let eventLoop = group.next() + do { + try self.validateFileDescriptorIsNotAFile(inputDescriptor) + try self.validateFileDescriptorIsNotAFile(outputDescriptor) + } catch { + return eventLoop.makeFailedFuture(error) + } + + let channelInitializer = self.channelInitializer ?? { _ in eventLoop.makeSucceededFuture(()) } + let channel: PipeChannel + do { + let inputFH = NIOFileHandle(descriptor: inputDescriptor) + let outputFH = NIOFileHandle(descriptor: outputDescriptor) + channel = try PipeChannel(eventLoop: eventLoop as! SelectableEventLoop, + inputPipe: inputFH, + outputPipe: outputFH) + } catch { + return eventLoop.makeFailedFuture(error) + } + + func setupChannel() -> EventLoopFuture { + eventLoop.assertInEventLoop() + return self._channelOptions.applyAllChannelOptions(to: channel).flatMap { + channelInitializer(channel) + }.flatMap { + eventLoop.assertInEventLoop() + let promise = eventLoop.makePromise(of: Void.self) + channel.registerAlreadyConfigured0(promise: promise) + return promise.futureResult + }.map { + channel + }.flatMapError { error in + channel.close0(error: error, mode: .all, promise: nil) + return channel.eventLoop.makeFailedFuture(error) + } + } + + if eventLoop.inEventLoop { + return setupChannel() + } else { + return eventLoop.flatSubmit { + setupChannel() + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ControlMessage.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ControlMessage.swift new file mode 100644 index 00000000..62e2d729 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ControlMessage.swift @@ -0,0 +1,339 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import CNIODarwin +#elseif os(Linux) || os(FreeBSD) || os(Android) +import CNIOLinux +#endif + +/// Memory for use as `cmsghdr` and associated data. +/// Supports multiple messages each with enough storage for multiple `cmsghdr` +struct UnsafeControlMessageStorage: Collection { + let bytesPerMessage: Int + var buffer: UnsafeMutableRawBufferPointer + + /// Initialise which includes allocating memory + /// parameter: + /// - bytesPerMessage: How many bytes have been allocated for each supported message. + /// - buffer: The memory allocated to use for control messages. + private init(bytesPerMessage: Int, buffer: UnsafeMutableRawBufferPointer) { + self.bytesPerMessage = bytesPerMessage + self.buffer = buffer + } + + /// Allocate new memory - Caller must call `deallocate` when no longer required. + /// parameter: + /// - msghdrCount: How many `msghdr` structures will be fed from this buffer - we assume 4 Int32 cmsgs for each. + static func allocate(msghdrCount: Int) -> UnsafeControlMessageStorage { + // Guess that 4 Int32 payload messages is enough for anyone. + let bytesPerMessage = NIOBSDSocketControlMessage.space(payloadSize: MemoryLayout.stride) * 4 + let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: bytesPerMessage * msghdrCount, + alignment: MemoryLayout.alignment) + return UnsafeControlMessageStorage(bytesPerMessage: bytesPerMessage, buffer: buffer) + } + + mutating func deallocate() { + self.buffer.deallocate() + self.buffer = UnsafeMutableRawBufferPointer(start: UnsafeMutableRawPointer(bitPattern: 0x7eadbeef), count: 0) + } + + /// Get the part of the buffer for use with a message. + public subscript(position: Int) -> UnsafeMutableRawBufferPointer { + return UnsafeMutableRawBufferPointer( + fastRebase: self.buffer[(position * self.bytesPerMessage)..<((position+1) * self.bytesPerMessage)]) + } + + var startIndex: Int { return 0 } + + var endIndex: Int { return self.buffer.count / self.bytesPerMessage } + + func index(after: Int) -> Int { + return after + 1 + } + +} + +/// Representation of a `cmsghdr` and associated data. +/// Unsafe as captures pointers and must not escape the scope where those pointers are valid. +struct UnsafeControlMessage { + var level: CInt + var type: CInt + var data: UnsafeRawBufferPointer? +} + +/// Collection representation of `cmsghdr` structures and associated data from `recvmsg` +/// Unsafe as captures pointers held in msghdr structure which must not escape scope of validity. +struct UnsafeControlMessageCollection { + private var messageHeader: msghdr + + init(messageHeader: msghdr) { + self.messageHeader = messageHeader + } +} + +// Add the `Collection` functionality to UnsafeControlMessageCollection. +extension UnsafeControlMessageCollection: Collection { + typealias Element = UnsafeControlMessage + + struct Index: Equatable, Comparable { + fileprivate var cmsgPointer: UnsafeMutablePointer? + + static func < (lhs: UnsafeControlMessageCollection.Index, + rhs: UnsafeControlMessageCollection.Index) -> Bool { + // nil is high, as that's the end of the collection. + switch (lhs.cmsgPointer, rhs.cmsgPointer) { + case (.some(let lhs), .some(let rhs)): + return lhs < rhs + case (.some, .none): + return true + case (.none, .some), (.none, .none): + return false + } + } + + fileprivate init(cmsgPointer: UnsafeMutablePointer?) { + self.cmsgPointer = cmsgPointer + } + } + + var startIndex: Index { + var messageHeader = self.messageHeader + return withUnsafePointer(to: &messageHeader) { messageHeaderPtr in + let firstCMsg = NIOBSDSocketControlMessage.firstHeader(inside: messageHeaderPtr) + return Index(cmsgPointer: firstCMsg) + } + } + + var endIndex: Index { return Index(cmsgPointer: nil) } + + func index(after: Index) -> Index { + var msgHdr = messageHeader + return withUnsafeMutablePointer(to: &msgHdr) { messageHeaderPtr in + return Index(cmsgPointer: NIOBSDSocketControlMessage.nextHeader(inside: messageHeaderPtr, + after: after.cmsgPointer!)) + } + } + + public subscript(position: Index) -> Element { + let cmsg = position.cmsgPointer! + return UnsafeControlMessage(level: cmsg.pointee.cmsg_level, + type: cmsg.pointee.cmsg_type, + data: NIOBSDSocketControlMessage.data(for: cmsg)) + } +} + +/// Small struct to link a buffer used for control bytes and the processing of those bytes. +struct UnsafeReceivedControlBytes { + var controlBytesBuffer: UnsafeMutableRawBufferPointer + /// Set when a message is received which is using the controlBytesBuffer - the lifetime will be tied to that of `controlBytesBuffer` + var receivedControlMessages: UnsafeControlMessageCollection? + + init(controlBytesBuffer: UnsafeMutableRawBufferPointer) { + self.controlBytesBuffer = controlBytesBuffer + } +} + +/// Extract information from a collection of control messages. +struct ControlMessageParser { + var ecnValue: NIOExplicitCongestionNotificationState = .transportNotCapable // Default + var packetInfo: NIOPacketInfo? = nil + + init(parsing controlMessagesReceived: UnsafeControlMessageCollection) { + for controlMessage in controlMessagesReceived { + self.receiveMessage(controlMessage) + } + } + + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + private static let ipv4TosType = IP_RECVTOS + #else + private static let ipv4TosType = IP_TOS // Linux + #endif + + static func _readCInt(data: UnsafeRawBufferPointer) -> CInt { + assert(data.count == MemoryLayout.size) + precondition(data.count >= MemoryLayout.size) + var readValue = CInt(0) + withUnsafeMutableBytes(of: &readValue) { valuePtr in + valuePtr.copyMemory(from: data) + } + return readValue + } + + private mutating func receiveMessage(_ controlMessage: UnsafeControlMessage) { + if controlMessage.level == IPPROTO_IP { + self.receiveIPv4Message(controlMessage) + } else if controlMessage.level == IPPROTO_IPV6 { + self.receiveIPv6Message(controlMessage) + } + } + + private mutating func receiveIPv4Message(_ controlMessage: UnsafeControlMessage) { + if controlMessage.type == ControlMessageParser.ipv4TosType { + if let data = controlMessage.data { + assert(data.count == 1) + precondition(data.count >= 1) + let readValue = CInt(data[0]) + self.ecnValue = .init(receivedValue: readValue) + } + } else if controlMessage.type == Posix.IP_PKTINFO { + if let data = controlMessage.data { + let info = data.load(as: in_pktinfo.self) + var addr = sockaddr_in() + addr.sin_family = sa_family_t(NIOBSDSocket.AddressFamily.inet.rawValue) + addr.sin_port = in_port_t(0) + addr.sin_addr = info.ipi_addr + self.packetInfo = NIOPacketInfo(destinationAddress: SocketAddress(addr, host: ""), + interfaceIndex: Int(info.ipi_ifindex)) + } + + } + } + + private mutating func receiveIPv6Message(_ controlMessage: UnsafeControlMessage) { + if controlMessage.type == IPV6_TCLASS { + if let data = controlMessage.data { + let readValue = ControlMessageParser._readCInt(data: data) + self.ecnValue = .init(receivedValue: readValue) + } + } else if controlMessage.type == Posix.IPV6_PKTINFO { + if let data = controlMessage.data { + let info = data.load(as: in6_pktinfo.self) + var addr = sockaddr_in6() + addr.sin6_family = sa_family_t(NIOBSDSocket.AddressFamily.inet6.rawValue) + addr.sin6_port = in_port_t(0) + addr.sin6_flowinfo = 0 + addr.sin6_addr = info.ipi6_addr + addr.sin6_scope_id = 0 + self.packetInfo = NIOPacketInfo(destinationAddress: SocketAddress(addr, host: ""), + interfaceIndex: Int(info.ipi6_ifindex)) + } + } + } +} + +extension NIOExplicitCongestionNotificationState { + /// Initialise a NIOExplicitCongestionNotificationState from a value received via either TCLASS or TOS cmsg. + init(receivedValue: CInt) { + switch receivedValue & Posix.IPTOS_ECN_MASK { + case Posix.IPTOS_ECN_ECT1: + self = .transportCapableFlag1 + case Posix.IPTOS_ECN_ECT0: + self = .transportCapableFlag0 + case Posix.IPTOS_ECN_CE: + self = .congestionExperienced + default: + self = .transportNotCapable + } + } +} + +extension CInt { + /// Create a CInt encoding of ExplicitCongestionNotification suitable for sending in TCLASS or TOS cmsg. + init(ecnValue: NIOExplicitCongestionNotificationState) { + switch ecnValue { + case .transportNotCapable: + self = Posix.IPTOS_ECN_NOTECT + case .transportCapableFlag0: + self = Posix.IPTOS_ECN_ECT0 + case .transportCapableFlag1: + self = Posix.IPTOS_ECN_ECT1 + case .congestionExperienced: + self = Posix.IPTOS_ECN_CE + } + } +} + +struct UnsafeOutboundControlBytes { + private var controlBytes: UnsafeMutableRawBufferPointer + private var writePosition: UnsafeMutableRawBufferPointer.Index + + /// This structure must not outlive `controlBytes` + init(controlBytes: UnsafeMutableRawBufferPointer) { + self.controlBytes = controlBytes + self.writePosition = controlBytes.startIndex + } + + mutating func appendControlMessage(level: CInt, type: CInt, payload: CInt) { + self.appendGenericControlMessage(level: level, type: type, payload: payload) + } + + /// Appends a control message. + /// PayloadType needs to be trivial (eg CInt) + private mutating func appendGenericControlMessage(level: CInt, + type: CInt, + payload: PayloadType) { + let writableBuffer = UnsafeMutableRawBufferPointer(fastRebase: self.controlBytes[writePosition...]) + + let requiredSize = NIOBSDSocketControlMessage.space(payloadSize: MemoryLayout.stride(ofValue: payload)) + precondition(writableBuffer.count >= requiredSize, "Insufficient size for cmsghdr and data") + + let bufferBase = writableBuffer.baseAddress! + // Binding to cmsghdr is safe here as this is the only place where we bind to non-Raw. + let cmsghdrPtr = bufferBase.bindMemory(to: cmsghdr.self, capacity: 1) + cmsghdrPtr.pointee.cmsg_level = level + cmsghdrPtr.pointee.cmsg_type = type + cmsghdrPtr.pointee.cmsg_len = .init(NIOBSDSocketControlMessage.length(payloadSize: MemoryLayout.size(ofValue: payload))) + + let dataPointer = NIOBSDSocketControlMessage.data(for: cmsghdrPtr)! + precondition(dataPointer.count >= MemoryLayout.stride) + dataPointer.storeBytes(of: payload, as: PayloadType.self) + + self.writePosition += requiredSize + } + + /// The result is only valid while this is valid. + var validControlBytes: UnsafeMutableRawBufferPointer { + if writePosition == 0 { + return UnsafeMutableRawBufferPointer(start: nil, count: 0) + } + return UnsafeMutableRawBufferPointer(fastRebase: self.controlBytes[0 ..< self.writePosition]) + } + +} + +extension UnsafeOutboundControlBytes { + /// Add a message describing the explicit congestion state if requested in metadata and valid for this protocol. + /// Parameters: + /// - metadata: Metadata from the addressed envelope which will describe any desired state. + /// - protocolFamily: The type of protocol to encode for. + internal mutating func appendExplicitCongestionState(metadata: AddressedEnvelope.Metadata?, + protocolFamily: NIOBSDSocket.ProtocolFamily?) { + guard let metadata = metadata else { return } + + switch protocolFamily { + case .some(.inet): + self.appendControlMessage(level: .init(IPPROTO_IP), + type: IP_TOS, + payload: CInt(ecnValue: metadata.ecnState)) + case .some(.inet6): + self.appendControlMessage(level: .init(IPPROTO_IPV6), + type: IPV6_TCLASS, + payload: CInt(ecnValue: metadata.ecnState)) + default: + // Nothing to do - if we get here the user is probably making a mistake. + break + } + } +} + +extension AddressedEnvelope.Metadata { + /// It's assumed the caller has checked that congestion information is required before calling. + internal init(from controlMessagesReceived: UnsafeControlMessageCollection) { + let controlMessageReceiver = ControlMessageParser(parsing: controlMessagesReceived) + self.init(ecnState: controlMessageReceiver.ecnValue, packetInfo: controlMessageReceiver.packetInfo) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/DatagramVectorReadManager.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/DatagramVectorReadManager.swift new file mode 100644 index 00000000..bad36684 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/DatagramVectorReadManager.swift @@ -0,0 +1,263 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// An object that manages issuing vector reads for datagram channels. +/// +/// Datagram channels have slightly complex read semantics, as high-throughput datagram +/// channels would like to use gathering reads to minimise syscall overhead. This requires +/// managing memory carefully, as well as includes some complex logic that needs to be +/// carefully arranged. For this reason, we store this logic on this separate struct +/// that makes understanding the code a lot simpler. +struct DatagramVectorReadManager { + enum ReadResult { + case some(reads: [AddressedEnvelope], totalSize: Int) + case none + } + + /// The number of messages that will be read in each syscall. + var messageCount: Int { + get { + return self.messageVector.count + } + set { + precondition(newValue >= 0) + self.messageVector.deinitializeAndDeallocate() + self.ioVector.deinitializeAndDeallocate() + self.sockaddrVector.deinitializeAndDeallocate() + self.controlMessageStorage.deallocate() + + self.messageVector = .allocateAndInitialize(repeating: MMsgHdr(msg_hdr: msghdr(), msg_len: 0), count: newValue) + self.ioVector = .allocateAndInitialize(repeating: IOVector(), count: newValue) + self.sockaddrVector = .allocateAndInitialize(repeating: sockaddr_storage(), count: newValue) + self.controlMessageStorage = UnsafeControlMessageStorage.allocate(msghdrCount: newValue) + } + } + + /// The vector of MMsgHdrs that are used for the gathering reads. + private var messageVector: UnsafeMutableBufferPointer + + /// The vector of iovec structures needed by msghdr structures. + private var ioVector: UnsafeMutableBufferPointer + + /// The vector of sockaddr structures used for saving addresses. + private var sockaddrVector: UnsafeMutableBufferPointer + + /// Storage to use for `cmsghdr` data when reading messages. + private var controlMessageStorage: UnsafeControlMessageStorage + + // FIXME(cory): Right now there's no good API for specifying the various parameters of multi-read, especially how + // it should interact with RecvByteBufferAllocator. For now I'm punting on this to see if I can get it working, + // but we should design it back. + fileprivate init(messageVector: UnsafeMutableBufferPointer, + ioVector: UnsafeMutableBufferPointer, + sockaddrVector: UnsafeMutableBufferPointer, + controlMessageStorage: UnsafeControlMessageStorage) { + self.messageVector = messageVector + self.ioVector = ioVector + self.sockaddrVector = sockaddrVector + self.controlMessageStorage = controlMessageStorage + } + + /// Performs a socket vector read. + /// + /// This method takes a single byte buffer and segments it into `messageCount` pieces. It then + /// prepares and issues a single recvmmsg syscall, instructing the kernel to write multiple datagrams + /// into that single buffer. Assuming that some datagrams have been successfully read, it then slices + /// that large buffer up into multiple buffers, prepares a series of AddressedEnvelope structures + /// appropriately, and then returns that result to the caller. + /// + /// - warning: If buffer is not at least 1.5kB times `messageCount`, this will almost certainly lead to + /// dropped data. Caution should be taken to ensure that the RecvByteBufferAllocator is allocating an + /// appropriate amount of memory. + /// - warning: Unlike most of the rest of SwiftNIO, the read managers use withVeryUnsafeMutableBytes to + /// obtain a pointer to the entire buffer storage. This is because they assume they own the entire + /// buffer. + /// + /// - parameters: + /// - socket: The underlying socket from which to read. + /// - buffer: The single large buffer into which reads will be written. + /// - parseControlMessages: Should control messages be reported up using metadata. + func readFromSocket(socket: Socket, + buffer: inout ByteBuffer, + parseControlMessages: Bool) throws -> ReadResult { + assert(buffer.readerIndex == 0, "Buffer was not cleared between calls to readFromSocket!") + + let messageSize = buffer.capacity / self.messageCount + + let result = try buffer.withVeryUnsafeMutableBytes { bufferPointer -> IOResult in + for i in 0...size), + msg_iov: self.ioVector.baseAddress! + i, + msg_iovlen: 1, // This is weird, but each message gets only one array. Duh. + msg_control: controlBytes.baseAddress, + msg_controllen: .init(controlBytes.count), + msg_flags: 0) + self.messageVector[i] = MMsgHdr(msg_hdr: msgHdr, msg_len: 0) + + // Note that we don't set up the sockaddr vector: that's because it needs no initialization, + // it's written into by the kernel. + } + + // We've set up our pointers, it's time to get going. We now issue the call. + return try socket.recvmmsg(msgs: self.messageVector) + } + + switch result { + case .wouldBlock(let messagesProcessed): + assert(messagesProcessed == 0) + return .none + case .processed(let messagesProcessed): + buffer.moveWriterIndex(to: messageSize * messagesProcessed) + return self.buildMessages(messageCount: messagesProcessed, + sliceSize: messageSize, + buffer: &buffer, + parseControlMessages: parseControlMessages) + } + } + + /// Destroys this vector read manager, rendering it impossible to re-use. Use of the vector read manager after this is called is not possible. + mutating func deallocate() { + self.messageVector.deinitializeAndDeallocate() + self.ioVector.deinitializeAndDeallocate() + self.sockaddrVector.deinitializeAndDeallocate() + self.controlMessageStorage.deallocate() + } + + private func buildMessages(messageCount: Int, + sliceSize: Int, + buffer: inout ByteBuffer, + parseControlMessages: Bool) -> ReadResult { + var sliceOffset = buffer.readerIndex + var totalReadSize = 0 + + var results = Array>() + results.reserveCapacity(messageCount) + + for i in 0...Metadata? + if parseControlMessages { + let controlMessagesReceived = + UnsafeControlMessageCollection(messageHeader: self.messageVector[i].msg_hdr) + metadata = .init(from: controlMessagesReceived) + } else { + metadata = nil + } + + // Now we've finally constructed a useful AddressedEnvelope. We can store it in the results array temporarily. + results.append(AddressedEnvelope(remoteAddress: address, data: slice, metadata: metadata)) + } + + // Ok, all built. Now we can return these values to the caller. + return .some(reads: results, totalSize: totalReadSize) + } +} + +extension DatagramVectorReadManager { + /// Allocates and initializes a new DatagramVectorReadManager. + /// + /// - parameters: + /// - messageCount: The number of vector reads to support initially. + static func allocate(messageCount: Int) -> DatagramVectorReadManager { + let messageVector = UnsafeMutableBufferPointer.allocateAndInitialize(repeating: MMsgHdr(msg_hdr: msghdr(), msg_len: 0), count: messageCount) + let ioVector = UnsafeMutableBufferPointer.allocateAndInitialize(repeating: IOVector(), count: messageCount) + let sockaddrVector = UnsafeMutableBufferPointer.allocateAndInitialize(repeating: sockaddr_storage(), count: messageCount) + let controlMessageStorage = UnsafeControlMessageStorage.allocate(msghdrCount: messageCount) + + return DatagramVectorReadManager(messageVector: messageVector, + ioVector: ioVector, + sockaddrVector: sockaddrVector, + controlMessageStorage: controlMessageStorage) + } +} + + +extension Optional where Wrapped == DatagramVectorReadManager { + /// Updates the message count of the wrapped `DatagramVectorReadManager` to the new value. + /// + /// If the new value is 0 or negative, will destroy the contained vector read manager and set + /// self to `nil`. + mutating func updateMessageCount(_ newCount: Int) { + if newCount > 0 { + if self != nil { + self!.messageCount = newCount + } else { + self = DatagramVectorReadManager.allocate(messageCount: newCount) + } + } else { + if self != nil { + self!.deallocate() + } + self = nil + } + } +} + + +extension UnsafeMutableBufferPointer { + /// Safely creates an UnsafeMutableBufferPointer that can be used by the rest of the code. It ensures that + /// the memory has been bound, allocated, and initialized, such that other Swift code can use it safely without + /// worrying. + fileprivate static func allocateAndInitialize(repeating element: Element, count: Int) -> UnsafeMutableBufferPointer { + let newPointer = UnsafeMutableBufferPointer.allocate(capacity: count) + newPointer.initialize(repeating: element) + return newPointer + } + + /// This safely destroys an UnsafeMutableBufferPointer by deinitializing and deallocating + /// the underlying memory. This ensures that if the pointer contains non-trivial Swift + /// types that no accidental memory leaks will occur, as can happen if UnsafeMutableBufferPointer.deallocate() + /// is used. + fileprivate func deinitializeAndDeallocate() { + guard let basePointer = self.baseAddress else { + // If there's no base address, who cares? + return + } + + // This is the safe way to do things: the moment that deinitialize + // is called, we deallocate. + let rawPointer = basePointer.deinitialize(count: self.count) + rawPointer.deallocate() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/FileDescriptor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/FileDescriptor.swift new file mode 100644 index 00000000..c5a49a6c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/FileDescriptor.swift @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +extension FileDescriptor { + internal static func setNonBlocking(fileDescriptor: CInt) throws { + let flags = try Posix.fcntl(descriptor: fileDescriptor, command: F_GETFL, value: 0) + do { + let ret = try Posix.fcntl(descriptor: fileDescriptor, command: F_SETFL, value: flags | O_NONBLOCK) + assert(ret == 0, "unexpectedly, fcntl(\(fileDescriptor), F_SETFL, \(flags) | O_NONBLOCK) returned \(ret)") + } catch let error as IOError { + if error.errnoCode == EINVAL { + // Darwin seems to sometimes do this despite the docs claiming it can't happen + throw NIOFcntlFailedError() + } + throw error + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/GetaddrinfoResolver.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/GetaddrinfoResolver.swift new file mode 100644 index 00000000..cc7f7154 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/GetaddrinfoResolver.swift @@ -0,0 +1,223 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +/// A DNS resolver built on top of the libc `getaddrinfo` function. +/// +/// This is the lowest-common-denominator resolver available to NIO. It's not really a very good +/// solution because the `getaddrinfo` call blocks during the DNS resolution, meaning that this resolver +/// will block a thread for as long as it takes to perform the getaddrinfo call. To prevent it from blocking `EventLoop` +/// threads, it will offload the blocking `getaddrinfo` calls to a `DispatchQueue`. +/// One advantage from leveraging `getaddrinfo` is the automatic conformance to RFC 6724, which removes some of the work +/// needed to implement it. +/// +/// This resolver is a single-use object: it can only be used to perform a single host resolution. + +import Dispatch + +#if os(Linux) || os(FreeBSD) || os(Android) +import CNIOLinux +#endif + +#if os(Windows) +import let WinSDK.AF_INET +import let WinSDK.AF_INET6 + +import func WinSDK.FreeAddrInfoW +import func WinSDK.GetAddrInfoW +import func WinSDK.gai_strerrorA + +import struct WinSDK.ADDRESS_FAMILY +import struct WinSDK.ADDRINFOW +import struct WinSDK.SOCKADDR_IN +import struct WinSDK.SOCKADDR_IN6 +#endif + +// A thread-specific variable where we store the offload queue if we're on an `SelectableEventLoop`. +let offloadQueueTSV = ThreadSpecificVariable() + + +internal class GetaddrinfoResolver: Resolver { + private let v4Future: EventLoopPromise<[SocketAddress]> + private let v6Future: EventLoopPromise<[SocketAddress]> + private let aiSocktype: NIOBSDSocket.SocketType + private let aiProtocol: CInt + + /// Create a new resolver. + /// + /// - parameters: + /// - loop: The `EventLoop` whose thread this resolver will block. + /// - aiSocktype: The sock type to use as hint when calling getaddrinfo. + /// - aiProtocol: the protocol to use as hint when calling getaddrinfo. + init(loop: EventLoop, aiSocktype: NIOBSDSocket.SocketType, aiProtocol: CInt) { + self.v4Future = loop.makePromise() + self.v6Future = loop.makePromise() + self.aiSocktype = aiSocktype + self.aiProtocol = aiProtocol + } + + /// Initiate a DNS A query for a given host. + /// + /// Due to the nature of `getaddrinfo`, we only actually call the function once, in the AAAA query. + /// That means this just returns the future for the A results, which in practice will always have been + /// satisfied by the time this function is called. + /// + /// - parameters: + /// - host: The hostname to do an A lookup on. + /// - port: The port we'll be connecting to. + /// - returns: An `EventLoopFuture` that fires with the result of the lookup. + func initiateAQuery(host: String, port: Int) -> EventLoopFuture<[SocketAddress]> { + return v4Future.futureResult + } + + /// Initiate a DNS AAAA query for a given host. + /// + /// Due to the nature of `getaddrinfo`, we only actually call the function once, in this function. + /// That means this function call actually blocks: sorry! + /// + /// - parameters: + /// - host: The hostname to do an AAAA lookup on. + /// - port: The port we'll be connecting to. + /// - returns: An `EventLoopFuture` that fires with the result of the lookup. + func initiateAAAAQuery(host: String, port: Int) -> EventLoopFuture<[SocketAddress]> { + self.offloadQueue().async { + self.resolveBlocking(host: host, port: port) + } + return v6Future.futureResult + } + + private func offloadQueue() -> DispatchQueue { + if let offloadQueue = offloadQueueTSV.currentValue { + return offloadQueue + } else { + if MultiThreadedEventLoopGroup.currentEventLoop != nil { + // Okay, we're on an SelectableEL thread. Let's stuff our queue into the thread local. + let offloadQueue = DispatchQueue(label: "io.swiftnio.GetaddrinfoResolver.offloadQueue") + offloadQueueTSV.currentValue = offloadQueue + return offloadQueue + } else { + return DispatchQueue.global() + } + } + } + + /// Cancel all outstanding DNS queries. + /// + /// This method is called whenever queries that have not completed no longer have their + /// results needed. The resolver should, if possible, abort any outstanding queries and + /// clean up their state. + /// + /// In the getaddrinfo case this is a no-op, as the resolver blocks. + func cancelQueries() { } + + /// Perform the DNS queries and record the result. + /// + /// - parameters: + /// - host: The hostname to do the DNS queries on. + /// - port: The port we'll be connecting to. + private func resolveBlocking(host: String, port: Int) { +#if os(Windows) + host.withCString(encodedAs: UTF16.self) { wszHost in + String(port).withCString(encodedAs: UTF16.self) { wszPort in + var pResult: UnsafeMutablePointer? + + var aiHints: ADDRINFOW = ADDRINFOW() + aiHints.ai_socktype = self.aiSocktype.rawValue + aiHints.ai_protocol = self.aiProtocol + + let iResult = GetAddrInfoW(wszHost, wszPort, &aiHints, &pResult) + guard iResult == 0 else { + self.fail(SocketAddressError.unknown(host: host, port: port)) + return + } + + if let pResult = pResult { + self.parseAndPublishResults(pResult, host: host) + FreeAddrInfoW(pResult) + } else { + self.fail(SocketAddressError.unsupported) + } + } + } +#else + var info: UnsafeMutablePointer? + + var hint = addrinfo() + hint.ai_socktype = self.aiSocktype.rawValue + hint.ai_protocol = self.aiProtocol + guard getaddrinfo(host, String(port), &hint, &info) == 0 else { + self.fail(SocketAddressError.unknown(host: host, port: port)) + return + } + + if let info = info { + self.parseAndPublishResults(info, host: host) + freeaddrinfo(info) + } else { + /* this is odd, getaddrinfo returned NULL */ + self.fail(SocketAddressError.unsupported) + } +#endif + } + + /// Parses the DNS results from the `addrinfo` linked list. + /// + /// - parameters: + /// - info: The pointer to the first of the `addrinfo` structures in the list. + /// - host: The hostname we resolved. +#if os(Windows) + internal typealias CAddrInfo = ADDRINFOW +#else + internal typealias CAddrInfo = addrinfo +#endif + + private func parseAndPublishResults(_ info: UnsafeMutablePointer, host: String) { + var v4Results: [SocketAddress] = [] + var v6Results: [SocketAddress] = [] + + var info: UnsafeMutablePointer = info + while true { + let addressBytes = UnsafeRawPointer(info.pointee.ai_addr) + switch NIOBSDSocket.AddressFamily(rawValue: info.pointee.ai_family) { + case .inet: + // Force-unwrap must be safe, or libc did the wrong thing. + v4Results.append(.init(addressBytes!.load(as: sockaddr_in.self), host: host)) + case .inet6: + // Force-unwrap must be safe, or libc did the wrong thing. + v6Results.append(.init(addressBytes!.load(as: sockaddr_in6.self), host: host)) + default: + self.fail(SocketAddressError.unsupported) + return + } + + guard let nextInfo = info.pointee.ai_next else { + break + } + + info = nextInfo + } + + v6Future.succeed(v6Results) + v4Future.succeed(v4Results) + } + + /// Record an error and fail the lookup process. + /// + /// - parameters: + /// - error: The error encountered during lookup. + private func fail(_ error: Error) { + self.v6Future.fail(error) + self.v4Future.fail(error) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/HappyEyeballs.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/HappyEyeballs.swift new file mode 100644 index 00000000..04ea1af1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/HappyEyeballs.swift @@ -0,0 +1,643 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +// This module implements Happy Eyeballs 2 (RFC 8305). A few notes should be made about the design. +// +// The natural implementation of RFC 8305 is to use an explicit FSM, and this module does so. However, +// it doesn't use the natural Swift idiom for an FSM of using an enum with mutating methods. The reason +// for this is that the RFC 8305 FSM here needs to trigger a number of concurrent asynchronous operations, +// each of which will register callbacks that attempt to mutate `self`. This gets tricky fast, because enums +// are value types, while all of these callbacks need to trigger state transitions on the same underlying +// state machine. +// +// For this reason, we fall back to the less Swifty but more clear approach of embedding the FSM in a class. +// We naturally still use an enum to hold our state, but the FSM is now inside a class, which makes the shared +// state nature of this FSM a bit clearer. + +private extension Array where Element == EventLoopFuture { + mutating func remove(element: Element) { + guard let channelIndex = self.firstIndex(where: { $0 === element }) else { + return + } + + remove(at: channelIndex) + } +} + +/// An error that occurred during connection to a given target. +public struct SingleConnectionFailure { + /// The target we were trying to connect to when we encountered the error. + public let target: SocketAddress + + /// The error we encountered. + public let error: Error +} + +/// A representation of all the errors that happened during an attempt to connect +/// to a given host and port. +public struct NIOConnectionError: Error { + /// The hostname SwiftNIO was trying to connect to. + public let host: String + + /// The port SwiftNIO was trying to connect to. + public let port: Int + + /// The error we encountered doing the DNS A lookup, if any. + public fileprivate(set) var dnsAError: Error? = nil + + /// The error we encountered doing the DNS AAAA lookup, if any. + public fileprivate(set) var dnsAAAAError: Error? = nil + + /// The errors we encountered during the connection attempts. + public fileprivate(set) var connectionErrors: [SingleConnectionFailure] = [] + + fileprivate init(host: String, port: Int) { + self.host = host + self.port = port + } +} + +/// A simple iterator that manages iterating over the possible targets. +/// +/// This iterator knows how to merge together the A and AAAA records in a sensible way: +/// specifically, it keeps track of what the last address family it emitted was, and emits the +/// address of the opposite family next. +private struct TargetIterator: IteratorProtocol { + typealias Element = SocketAddress + + private enum AddressFamily { + case v4 + case v6 + } + + private var previousAddressFamily: AddressFamily = .v4 + private var aQueryResults: [SocketAddress] = [] + private var aaaaQueryResults: [SocketAddress] = [] + + mutating func aResultsAvailable(_ results: [SocketAddress]) { + aQueryResults.append(contentsOf: results) + } + + mutating func aaaaResultsAvailable(_ results: [SocketAddress]) { + aaaaQueryResults.append(contentsOf: results) + } + + mutating func next() -> Element? { + switch previousAddressFamily { + case .v4: + return popAAAA() ?? popA() + case .v6: + return popA() ?? popAAAA() + } + } + + private mutating func popA() -> SocketAddress? { + if aQueryResults.count > 0 { + previousAddressFamily = .v4 + return aQueryResults.removeFirst() + } + + return nil + } + + private mutating func popAAAA() -> SocketAddress? { + if aaaaQueryResults.count > 0 { + previousAddressFamily = .v6 + return aaaaQueryResults.removeFirst() + } + + return nil + } +} + +/// Given a DNS resolver and an event loop, attempts to establish a connection to +/// the target host over both IPv4 and IPv6. +/// +/// This class provides the code that implements RFC 8305: Happy Eyeballs 2. This +/// is a connection establishment strategy that attempts to efficiently and quickly +/// establish connections to a host that has multiple IP addresses available to it, +/// potentially over two different IP protocol versions (4 and 6). +/// +/// This class should be created when a connection attempt is made and will remain +/// active until a connection is established. It is responsible for actually creating +/// connections and managing timeouts. +/// +/// This class's public API is thread-safe: the constructor and `resolveAndConnect` can +/// be called from any thread. `resolveAndConnect` will dispatch itself to the event +/// loop to force serialization. +/// +/// This class's private API is *not* thread-safe, and expects to be called from the +/// event loop thread of the `loop` it is passed. +internal class HappyEyeballsConnector { + /// An enum for keeping track of connection state. + private enum ConnectionState { + /// Initial state. No work outstanding. + case idle + + /// All name queries are currently outstanding. + case resolving + + /// The A query has resolved, but the AAAA query is outstanding and the + /// resolution delay has not yet elapsed. + case aResolvedWaiting + + /// The A query has resolved and the resolution delay has elapsed. We can + /// begin connecting immediately, but should not give up if we run out of + /// targets until the AAAA result returns. + case aResolvedConnecting + + /// The AAAA query has resolved. We can begin connecting immediately, but + /// should not give up if we run out of targets until the AAAA result returns. + case aaaaResolved + + /// All DNS results are in. We can make connection attempts until we run out + /// of targets. + case allResolved + + /// The connection attempt is complete. + case complete + } + + /// An enum of inputs for the connector state machine. + private enum ConnectorInput { + /// Begin DNS resolution. + case resolve + + /// The A record lookup completed. + case resolverACompleted + + /// The AAAA record lookup completed. + case resolverAAAACompleted + + /// The delay between the A result and the AAAA result has elapsed. + case resolutionDelayElapsed + + /// The delay between starting one connection and the next has elapsed. + case connectDelayElapsed + + /// The overall connect timeout has elapsed. + case connectTimeoutElapsed + + /// A connection attempt has succeeded. + case connectSuccess + + /// A connection attempt has failed. + case connectFailed + + /// There are no connect targets remaining: all have been connected to and + /// failed. + case noTargetsRemaining + } + + /// The DNS resolver provided by the user. + private let resolver: Resolver + + /// The event loop this connector will run on. + private let loop: EventLoop + + /// The host name we're connecting to. + private let host: String + + /// The port we're connecting to. + private let port: Int + + /// A callback, provided by the user, that is used to build a channel. + /// + /// This callback is expected to build *and register* a channel with the event loop that + /// was used with this resolver. It is free to set up the channel asynchronously, but note + /// that the time taken to set the channel up will be counted against the connection delay, + /// meaning that long channel setup times may cause more connections to be outstanding + /// than intended. + /// + /// The channel builder callback takes an event loop and a protocol family as arguments. + private let channelBuilderCallback: (EventLoop, NIOBSDSocket.ProtocolFamily) -> EventLoopFuture + + /// The amount of time to wait for an AAAA response to come in after a A response is + /// received. By default this is 50ms. + private let resolutionDelay: TimeAmount + + /// A reference to the task that will execute after the resolution delay expires, if + /// one is scheduled. This is held to ensure that we can cancel this task if the AAAA + /// response comes in before the resolution delay expires. + private var resolutionTask: Optional> + + /// The amount of time to wait for a connection to succeed before beginning a new connection + /// attempt. By default this is 250ms. + private let connectionDelay: TimeAmount + + /// A reference to the task that will execute after the connection delay expires, if one + /// is scheduled. This is held to ensure that we can cancel this task if a connection + /// succeeds before the connection delay expires. + private var connectionTask: Optional> + + /// The amount of time to allow for the overall connection process before timing it out. + private let connectTimeout: TimeAmount + + /// A reference to the task that will time us out. + private var timeoutTask: Optional> + + /// The promise that will hold the final connected channel. + private let resolutionPromise: EventLoopPromise + + /// Our state machine state. + private var state: ConnectionState + + /// Our iterator of resolved targets. This keeps track of what targets are left to have + /// connection attempts made to them, and emits them in the appropriate order as needed. + private var targets: TargetIterator = TargetIterator() + + /// An array of futures of channels that are currently attempting to connect. + /// + /// This is kept to ensure that we can clean up after ourselves once a connection succeeds, + /// and throw away all pending connection attempts that are no longer needed. + private var pendingConnections: [EventLoopFuture] = [] + + /// The number of DNS resolutions that have returned. + /// + /// This is used to keep track of whether we need to cancel the outstanding resolutions + /// during cleanup. + private var dnsResolutions: Int = 0 + + /// An object that holds any errors we encountered. + private var error: NIOConnectionError + + init(resolver: Resolver, + loop: EventLoop, + host: String, + port: Int, + connectTimeout: TimeAmount, + resolutionDelay: TimeAmount = .milliseconds(50), + connectionDelay: TimeAmount = .milliseconds(250), + channelBuilderCallback: @escaping (EventLoop, NIOBSDSocket.ProtocolFamily) -> EventLoopFuture) { + self.resolver = resolver + self.loop = loop + self.host = host + self.port = port + self.connectTimeout = connectTimeout + self.channelBuilderCallback = channelBuilderCallback + self.resolutionTask = nil + self.connectionTask = nil + self.timeoutTask = nil + + self.state = .idle + self.resolutionPromise = self.loop.makePromise() + self.error = NIOConnectionError(host: host, port: port) + + precondition(resolutionDelay.nanoseconds > 0, "Resolution delay must be greater than zero, got \(resolutionDelay).") + self.resolutionDelay = resolutionDelay + + precondition(connectionDelay >= .milliseconds(100) && connectionDelay <= .milliseconds(2000), "Connection delay must be between 100 and 2000 ms, got \(connectionDelay)") + self.connectionDelay = connectionDelay + } + + /// Initiate a DNS resolution attempt using Happy Eyeballs 2. + /// + /// returns: An `EventLoopFuture` that fires with a connected `Channel`. + public func resolveAndConnect() -> EventLoopFuture { + // We dispatch ourselves onto the event loop, rather than do all the rest of our processing from outside it. + self.loop.execute { + self.timeoutTask = self.loop.scheduleTask(in: self.connectTimeout) { self.processInput(.connectTimeoutElapsed) } + self.processInput(.resolve) + } + return resolutionPromise.futureResult + } + + /// Spin the state machine. + /// + /// - parameters: + /// - input: The input to the state machine. + private func processInput(_ input: ConnectorInput) { + switch (state, input) { + // Only one valid transition from idle: to start resolving. + case (.idle, .resolve): + state = .resolving + beginDNSResolution() + + // In the resolving state, we can exit three ways: either the A query returns, + // the AAAA does, or the overall connect timeout fires. + case (.resolving, .resolverACompleted): + state = .aResolvedWaiting + beginResolutionDelay() + case (.resolving, .resolverAAAACompleted): + state = .aaaaResolved + beginConnecting() + case (.resolving, .connectTimeoutElapsed): + state = .complete + timedOut() + + // In the aResolvedWaiting state, we can exit three ways: the AAAA query returns, + // the resolution delay elapses, or the overall connect timeout fires. + case (.aResolvedWaiting, .resolverAAAACompleted): + state = .allResolved + beginConnecting() + case (.aResolvedWaiting, .resolutionDelayElapsed): + state = .aResolvedConnecting + beginConnecting() + case (.aResolvedWaiting, .connectTimeoutElapsed): + state = .complete + timedOut() + + // In the aResolvedConnecting state, a number of inputs are valid: the AAAA result can + // return, the connectionDelay can elapse, the overall connection timeout can fire, + // a connection can succeed, a connection can fail, and we can run out of targets. + case (.aResolvedConnecting, .resolverAAAACompleted): + state = .allResolved + connectToNewTargets() + case (.aResolvedConnecting, .connectDelayElapsed): + connectionDelayElapsed() + case (.aResolvedConnecting, .connectTimeoutElapsed): + state = .complete + timedOut() + case (.aResolvedConnecting, .connectSuccess): + state = .complete + connectSuccess() + case (.aResolvedConnecting, .connectFailed): + connectFailed() + case (.aResolvedConnecting, .noTargetsRemaining): + // We are still waiting for the AAAA query, so we + // do nothing. + break + + // In the aaaaResolved state, a number of inputs are valid: the A result can return, + // the connectionDelay can elapse, the overall connection timeout can fire, a connection + // can succeed, a connection can fail, and we can run out of targets. + case (.aaaaResolved, .resolverACompleted): + state = .allResolved + connectToNewTargets() + case (.aaaaResolved, .connectDelayElapsed): + connectionDelayElapsed() + case (.aaaaResolved, .connectTimeoutElapsed): + state = .complete + timedOut() + case (.aaaaResolved, .connectSuccess): + state = .complete + connectSuccess() + case (.aaaaResolved, .connectFailed): + connectFailed() + case (.aaaaResolved, .noTargetsRemaining): + // We are still waiting for the A query, so we + // do nothing. + break + + // In the allResolved state, a number of inputs are valid: the connectionDelay can elapse, + // the overall connection timeout can fire, a connection can succeed, a connection can fail, + // and possibly we can run out of targets. + case (.allResolved, .connectDelayElapsed): + connectionDelayElapsed() + case (.allResolved, .connectTimeoutElapsed): + state = .complete + timedOut() + case (.allResolved, .connectSuccess): + state = .complete + connectSuccess() + case (.allResolved, .connectFailed): + connectFailed() + case (.allResolved, .noTargetsRemaining): + state = .complete + failed() + + // Once we've completed, it's not impossible that we'll get state machine events for + // some amounts of work. For example, we could get late DNS results and late connection + // notifications, and can also get late scheduled task callbacks. We want to just quietly + // ignore these, as our transition into the complete state should have already sent + // cleanup messages to all of these things. + case (.complete, .resolverACompleted), + (.complete, .resolverAAAACompleted), + (.complete, .connectSuccess), + (.complete, .connectFailed), + (.complete, .connectDelayElapsed), + (.complete, .connectTimeoutElapsed), + (.complete, .resolutionDelayElapsed): + break + default: + fatalError("Invalid FSM transition attempt: state \(state), input \(input)") + } + } + + /// Fire off a pair of DNS queries. + private func beginDNSResolution() { + // Per RFC 8305 Section 3, we need to send A and AAAA queries. + // The two queries SHOULD be made as soon after one another as possible, + // with the AAAA query made first and immediately followed by the A + // query. + whenAAAALookupComplete(future: resolver.initiateAAAAQuery(host: host, port: port)) + whenALookupComplete(future: resolver.initiateAQuery(host: host, port: port)) + } + + /// Called when the A query has completed before the AAAA query. + /// + /// Happy Eyeballs 2 prefers to connect over IPv6 if it's possible to do so. This means that + /// if the A lookup completes first we want to wait a small amount of time before we begin our + /// connection attempts, in the hope that the AAAA lookup will complete. + /// + /// This method sets off a scheduled task for the resolution delay. + private func beginResolutionDelay() { + resolutionTask = loop.scheduleTask(in: resolutionDelay, resolutionDelayComplete) + } + + /// Called when we're ready to start connecting to targets. + /// + /// This function sets off the first connection attempt, and also sets the connect delay task. + private func beginConnecting() { + precondition(connectionTask == nil, "beginConnecting called while connection attempts outstanding") + guard let target = targets.next() else { + if self.pendingConnections.isEmpty { + processInput(.noTargetsRemaining) + } + return + } + + connectionTask = loop.scheduleTask(in: connectionDelay) { self.processInput(.connectDelayElapsed) } + connectToTarget(target) + } + + /// Called when the state machine wants us to connect to new targets, but we may already + /// be connecting. + /// + /// This method takes into account the possibility that we may still be connecting to + /// other targets. + private func connectToNewTargets() { + guard connectionTask == nil else { + // Already connecting, no need to do anything here. + return + } + + // We're not in the middle of connecting, so we can start connecting! + beginConnecting() + } + + /// Called when the connection delay timer has elapsed. + /// + /// When the connection delay elapses we are going to initiate another connection + /// attempt. + private func connectionDelayElapsed() { + connectionTask = nil + beginConnecting() + } + + /// Called when an outstanding connection attempt fails. + /// + /// This method checks that we don't have any connection attempts outstanding. If + /// we discover we don't, it automatically triggers the next connection attempt. + private func connectFailed() { + if self.pendingConnections.isEmpty { + self.connectionTask?.cancel() + self.connectionTask = nil + beginConnecting() + } + } + + /// Called when an outstanding connection attempt succeeds. + /// + /// Cleans up internal state. + private func connectSuccess() { + cleanUp() + } + + /// Called when the overall connection timeout fires. + /// + /// Cleans up internal state and fails the connection promise. + private func timedOut() { + cleanUp() + self.resolutionPromise.fail(ChannelError.connectTimeout(self.connectTimeout)) + } + + /// Called when we've attempted to connect to all our resolved targets, + /// and were unable to connect to any of them. + /// + /// Asserts that there is nothing left on the internal state, and then fails the connection + /// promise. + private func failed() { + precondition(pendingConnections.isEmpty, "failed with pending connections") + cleanUp() + self.resolutionPromise.fail(self.error) + } + + /// Called to connect to a given target. + /// + /// - parameters: + /// - target: The address to connect to. + private func connectToTarget(_ target: SocketAddress) { + let channelFuture = channelBuilderCallback(self.loop, target.protocol) + pendingConnections.append(channelFuture) + + channelFuture.whenSuccess { channel in + // If we are in the complete state then we want to abandon this channel. Otherwise, begin + // connecting. + if case .complete = self.state { + self.pendingConnections.remove(element: channelFuture) + channel.close(promise: nil) + } else { + channel.connect(to: target).map { + // The channel has connected. If we are in the complete state we want to abandon this channel. + // Otherwise, fire the channel connected event. Either way we don't want the channel future to + // be in our list of pending connections, so we don't either double close or close the connection + // we want to use. + self.pendingConnections.remove(element: channelFuture) + + if case .complete = self.state { + channel.close(promise: nil) + } else { + self.processInput(.connectSuccess) + self.resolutionPromise.succeed(channel) + } + }.whenFailure { err in + // The connection attempt failed. If we're in the complete state then there's nothing + // to do. Otherwise, notify the state machine of the failure. + if case .complete = self.state { + assert(self.pendingConnections.firstIndex { $0 === channelFuture } == nil, "failed but was still in pending connections") + } else { + self.error.connectionErrors.append(SingleConnectionFailure(target: target, error: err)) + self.pendingConnections.remove(element: channelFuture) + self.processInput(.connectFailed) + } + } + } + } + channelFuture.whenFailure { error in + self.error.connectionErrors.append(SingleConnectionFailure(target: target, error: error)) + self.pendingConnections.remove(element: channelFuture) + self.processInput(.connectFailed) + } + } + + // Cleans up all internal state, ensuring that there are no reference cycles and allowing + // everything to eventually be deallocated. + private func cleanUp() { + assert(self.state == .complete, "Clean up in invalid state \(self.state)") + + if dnsResolutions < 2 { + resolver.cancelQueries() + } + + if let resolutionTask = self.resolutionTask { + resolutionTask.cancel() + self.resolutionTask = nil + } + + if let connectionTask = self.connectionTask { + connectionTask.cancel() + self.connectionTask = nil + } + + if let timeoutTask = self.timeoutTask { + timeoutTask.cancel() + self.timeoutTask = nil + } + + let connections = self.pendingConnections + self.pendingConnections = [] + for connection in connections { + connection.whenSuccess { channel in channel.close(promise: nil) } + } + } + + /// A future callback that fires when a DNS A lookup completes. + private func whenALookupComplete(future: EventLoopFuture<[SocketAddress]>) { + future.map { results in + self.targets.aResultsAvailable(results) + }.recover { err in + self.error.dnsAError = err + }.whenComplete { (_: Result) in + self.dnsResolutions += 1 + self.processInput(.resolverACompleted) + } + } + + /// A future callback that fires when a DNS AAAA lookup completes. + private func whenAAAALookupComplete(future: EventLoopFuture<[SocketAddress]>) { + future.map { results in + self.targets.aaaaResultsAvailable(results) + }.recover { err in + self.error.dnsAAAAError = err + }.whenComplete { (_: Result) in + // It's possible that we were waiting to time out here, so if we were we should + // cancel that. + self.resolutionTask?.cancel() + self.resolutionTask = nil + + self.dnsResolutions += 1 + + self.processInput(.resolverAAAACompleted) + } + } + + /// A future callback that fires when the resolution delay completes. + private func resolutionDelayComplete() { + resolutionTask = nil + processInput(.resolutionDelayElapsed) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IO.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IO.swift new file mode 100644 index 00000000..452749b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IO.swift @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +internal extension IOResult where T: FixedWidthInteger { + var result: T { + switch self { + case .processed(let value): + return value + case .wouldBlock(_): + fatalError("cannot unwrap IOResult") + } + } +} + +/// An result for an IO operation that was done on a non-blocking resource. +enum IOResult: Equatable { + + /// Signals that the IO operation could not be completed as otherwise we would need to block. + case wouldBlock(T) + + /// Signals that the IO operation was completed. + case processed(T) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerBitPacking.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerBitPacking.swift new file mode 100644 index 00000000..6d89a9d8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerBitPacking.swift @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@usableFromInline +enum _IntegerBitPacking {} + +extension _IntegerBitPacking { + @inlinable + static func packUU(_ left: Left, + _ right: Right, + type: Result.Type = Result.self) -> Result { + assert(MemoryLayout.size + MemoryLayout.size <= MemoryLayout.size) + + let resultLeft = Result(left) + let resultRight = Result(right) + let result = (resultLeft << Right.bitWidth) | resultRight + assert(result.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount) + return result + } + + @inlinable + static func unpackUU(_ input: Input, + leftType: Left.Type = Left.self, + rightType: Right.Type = Right.self) -> (Left, Right) { + assert(MemoryLayout.size + MemoryLayout.size <= MemoryLayout.size) + + let leftMask = Input(Left.max) + let rightMask = Input(Right.max) + let right = input & rightMask + let left = (input >> Right.bitWidth) & leftMask + + assert(input.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount) + return (Left(left), Right(right)) + } +} + +@usableFromInline +enum IntegerBitPacking {} + +extension IntegerBitPacking { + @inlinable + static func packUInt32UInt16UInt8(_ left: UInt32, _ middle: UInt16, _ right: UInt8) -> UInt64 { + return _IntegerBitPacking.packUU( + _IntegerBitPacking.packUU(right, middle, type: UInt32.self), + left + ) + } + + @inlinable + static func unpackUInt32UInt16UInt8(_ value: UInt64) -> (UInt32, UInt16, UInt8) { + let leftRight = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self) + let left = _IntegerBitPacking.unpackUU(leftRight.0, leftType: UInt8.self, rightType: UInt16.self) + return (leftRight.1, left.1, left.0) + } + + @inlinable + static func packUInt8UInt8(_ left: UInt8, _ right: UInt8) -> UInt16 { + return _IntegerBitPacking.packUU(left, right) + } + + @inlinable + static func unpackUInt8UInt8(_ value: UInt16) -> (UInt8, UInt8) { + return _IntegerBitPacking.unpackUU(value) + } + + @inlinable + static func packUInt16UInt8(_ left: UInt16, _ right: UInt8) -> UInt32 { + return _IntegerBitPacking.packUU(left, right) + } + + @inlinable + static func unpackUInt16UInt8(_ value: UInt32) -> (UInt16, UInt8) { + return _IntegerBitPacking.unpackUU(value) + } + + @inlinable + static func packUInt32CInt(_ left: UInt32, _ right: CInt) -> UInt64 { + return _IntegerBitPacking.packUU(left, UInt32(truncatingIfNeeded: right)) + } + + @inlinable + static func unpackUInt32CInt(_ value: UInt64) -> (UInt32, CInt) { + let unpacked = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self) + return (unpacked.0, CInt(truncatingIfNeeded: unpacked.1)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerTypes.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerTypes.swift new file mode 100644 index 00000000..e0cf571b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/IntegerTypes.swift @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: _UInt24 + +/// A 24-bit unsigned integer value type. +@usableFromInline +struct _UInt24 { + @usableFromInline var _backing: (UInt16, UInt8) + + @inlinable + init(_ value: UInt32) { + assert(value & 0xff_00_00_00 == 0, "value \(value) too large for _UInt24") + self._backing = IntegerBitPacking.unpackUInt16UInt8(value) + } + + static let bitWidth: Int = 24 + + @usableFromInline + static let max: _UInt24 = .init((UInt32(1) << 24) - 1) + + @usableFromInline + static let min: _UInt24 = .init(0) +} + +extension UInt32 { + @inlinable + init(_ value: _UInt24) { + self = IntegerBitPacking.packUInt16UInt8(value._backing.0, value._backing.1) + } +} + +extension Int { + @inlinable + init(_ value: _UInt24) { + self = Int(UInt32(value)) + } +} + + +extension _UInt24: Equatable { + @inlinable + public static func ==(lhs: _UInt24, rhs: _UInt24) -> Bool { + return lhs._backing == rhs._backing + } +} + +extension _UInt24: CustomStringConvertible { + @usableFromInline + var description: String { + return UInt32(self).description + } +} + +// MARK: _UInt56 + +/// A 56-bit unsigned integer value type. +struct _UInt56 { + @usableFromInline var _backing: (UInt32, UInt16, UInt8) + + @inlinable init(_ value: UInt64) { + self._backing = IntegerBitPacking.unpackUInt32UInt16UInt8(value) + } + + static let bitWidth: Int = 56 + + private static let initializeUInt64 : UInt64 = (1 << 56) - 1 + static let max: _UInt56 = .init(initializeUInt64) + static let min: _UInt56 = .init(0) +} + +extension _UInt56 { + init(_ value: Int) { + self.init(UInt64(value)) + } +} + +extension UInt64 { + init(_ value: _UInt56) { + self = IntegerBitPacking.packUInt32UInt16UInt8(value._backing.0, + value._backing.1, + value._backing.2) + } +} + +extension Int { + init(_ value: _UInt56) { + self = Int(UInt64(value)) + } +} + +extension _UInt56: Equatable { + @inlinable + public static func ==(lhs: _UInt56, rhs: _UInt56) -> Bool { + return lhs._backing == rhs._backing + } +} + +extension _UInt56: CustomStringConvertible { + var description: String { + return UInt64(self).description + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Linux.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Linux.swift new file mode 100644 index 00000000..4d998a0f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Linux.swift @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// This is a companion to System.swift that provides only Linux specials: either things that exist +// only on Linux, or things that have Linux-specific extensions. + +#if os(Linux) || os(Android) +import CNIOLinux + +internal enum TimerFd { + internal static let TFD_CLOEXEC = CNIOLinux.TFD_CLOEXEC + internal static let TFD_NONBLOCK = CNIOLinux.TFD_NONBLOCK + + @inline(never) + internal static func timerfd_settime(fd: CInt, flags: CInt, newValue: UnsafePointer, oldValue: UnsafeMutablePointer?) throws { + _ = try syscall(blocking: false) { + CNIOLinux.timerfd_settime(fd, flags, newValue, oldValue) + } + } + + @inline(never) + internal static func timerfd_create(clockId: CInt, flags: CInt) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.timerfd_create(clockId, flags) + }.result + } +} + +internal enum EventFd { + internal static let EFD_CLOEXEC = CNIOLinux.EFD_CLOEXEC + internal static let EFD_NONBLOCK = CNIOLinux.EFD_NONBLOCK + internal typealias eventfd_t = CNIOLinux.eventfd_t + + @inline(never) + internal static func eventfd_write(fd: CInt, value: UInt64) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.eventfd_write(fd, value) + }.result + } + + @inline(never) + internal static func eventfd_read(fd: CInt, value: UnsafeMutablePointer) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.eventfd_read(fd, value) + }.result + } + + @inline(never) + internal static func eventfd(initval: CUnsignedInt, flags: CInt) throws -> CInt { + return try syscall(blocking: false) { + // Note: Please do _not_ remove the `numericCast`, this is to allow compilation in Ubuntu 14.04 and + // other Linux distros which ship a glibc from before this commit: + // https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=69eb9a183c19e8739065e430758e4d3a2c5e4f1a + // which changes the first argument from `CInt` to `CUnsignedInt` (from Sat, 20 Sep 2014). + CNIOLinux.eventfd(numericCast(initval), flags) + }.result + } +} + +internal enum Epoll { + internal typealias epoll_event = CNIOLinux.epoll_event + + internal static let EPOLL_CTL_ADD: CInt = numericCast(CNIOLinux.EPOLL_CTL_ADD) + internal static let EPOLL_CTL_MOD: CInt = numericCast(CNIOLinux.EPOLL_CTL_MOD) + internal static let EPOLL_CTL_DEL: CInt = numericCast(CNIOLinux.EPOLL_CTL_DEL) + + #if os(Android) + internal static let EPOLLIN: CUnsignedInt = 1 //numericCast(CNIOLinux.EPOLLIN) + internal static let EPOLLOUT: CUnsignedInt = 4 //numericCast(CNIOLinux.EPOLLOUT) + internal static let EPOLLERR: CUnsignedInt = 8 // numericCast(CNIOLinux.EPOLLERR) + internal static let EPOLLRDHUP: CUnsignedInt = 8192 //numericCast(CNIOLinux.EPOLLRDHUP) + internal static let EPOLLHUP: CUnsignedInt = 16 //numericCast(CNIOLinux.EPOLLHUP) + internal static let EPOLLET: CUnsignedInt = 2147483648 //numericCast(CNIOLinux.EPOLLET) + #else + internal static let EPOLLIN: CUnsignedInt = numericCast(CNIOLinux.EPOLLIN.rawValue) + internal static let EPOLLOUT: CUnsignedInt = numericCast(CNIOLinux.EPOLLOUT.rawValue) + internal static let EPOLLERR: CUnsignedInt = numericCast(CNIOLinux.EPOLLERR.rawValue) + internal static let EPOLLRDHUP: CUnsignedInt = numericCast(CNIOLinux.EPOLLRDHUP.rawValue) + internal static let EPOLLHUP: CUnsignedInt = numericCast(CNIOLinux.EPOLLHUP.rawValue) + internal static let EPOLLET: CUnsignedInt = numericCast(CNIOLinux.EPOLLET.rawValue) + #endif + + internal static let ENOENT: CUnsignedInt = numericCast(CNIOLinux.ENOENT) + + + @inline(never) + internal static func epoll_create(size: CInt) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.epoll_create(size) + }.result + } + + @inline(never) + @discardableResult + internal static func epoll_ctl(epfd: CInt, op: CInt, fd: CInt, event: UnsafeMutablePointer) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.epoll_ctl(epfd, op, fd, event) + }.result + } + + @inline(never) + internal static func epoll_wait(epfd: CInt, events: UnsafeMutablePointer, maxevents: CInt, timeout: CInt) throws -> CInt { + return try syscall(blocking: false) { + CNIOLinux.epoll_wait(epfd, events, maxevents, timeout) + }.result + } +} + +internal enum Linux { +#if os(Android) + static let SOCK_CLOEXEC = Glibc.SOCK_CLOEXEC + static let SOCK_NONBLOCK = Glibc.SOCK_NONBLOCK +#else + static let SOCK_CLOEXEC = CInt(bitPattern: Glibc.SOCK_CLOEXEC.rawValue) + static let SOCK_NONBLOCK = CInt(bitPattern: Glibc.SOCK_NONBLOCK.rawValue) +#endif + @inline(never) + internal static func accept4(descriptor: CInt, + addr: UnsafeMutablePointer?, + len: UnsafeMutablePointer?, + flags: CInt) throws -> CInt? { + guard case let .processed(fd) = try syscall(blocking: true, { + CNIOLinux.CNIOLinux_accept4(descriptor, addr, len, flags) + }) else { + return nil + } + return fd + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/LinuxCPUSet.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/LinuxCPUSet.swift new file mode 100644 index 00000000..766b0c2c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/LinuxCPUSet.swift @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Linux) || os(Android) +import CNIOLinux + + /// A set that contains CPU ids to use. + struct LinuxCPUSet { + /// The ids of all the cpus. + let cpuIds: Set + + /// Create a new instance + /// + /// - arguments: + /// - cpuIds: The `Set` of CPU ids. It must be non-empty and can not contain invalid ids. + init(cpuIds: Set) { + precondition(!cpuIds.isEmpty) + self.cpuIds = cpuIds + } + + /// Create a new instance + /// + /// - arguments: + /// - cpuId: The CPU id. + init(_ cpuId: Int) { + let ids: Set = [cpuId] + self.init(cpuIds: ids) + } + } + + extension LinuxCPUSet: Equatable {} + + /// Linux specific extension to `NIOThread`. + extension NIOThread { + /// Specify the thread-affinity of the `NIOThread` itself. + var affinity: LinuxCPUSet { + get { + var cpuset = cpu_set_t() + + // Ensure the cpuset is empty (and so nothing is selected yet). + CNIOLinux_CPU_ZERO(&cpuset) + + let res = self.withUnsafeThreadHandle { p in + CNIOLinux_pthread_getaffinity_np(p, MemoryLayout.size(ofValue: cpuset), &cpuset) + } + + precondition(res == 0, "pthread_getaffinity_np failed: \(res)") + + let set = Set((CInt(0).. __kernel_timespec { + var ts = __kernel_timespec() + ts.tv_sec = self.nanoseconds / 1_000_000_000 + ts.tv_nsec = self.nanoseconds % 1_000_000_000 + return ts + } +} + +// URingUserData supports (un)packing into an `UInt64` as io_uring has a user_data 64-bit payload which is set in the SQE +// and returned in the CQE. We're using 56 of those 64 bits, 32 for the file descriptor, 16 for a "registration ID" and 8 +// for the type of event issued (poll/modify/delete). +@usableFromInline struct URingUserData { + @usableFromInline var fileDescriptor: CInt + @usableFromInline var registrationID: UInt16 // SelectorRegistrationID truncated, only have room for bottom 16 bits (could be expanded to 24 if required) + @usableFromInline var eventType: CQEEventType + @usableFromInline var padding: Int8 // reserved for future use + + @inlinable init(registrationID: SelectorRegistrationID, fileDescriptor: CInt, eventType: CQEEventType) { + assert(MemoryLayout.size == MemoryLayout.size) + self.registrationID = UInt16(truncatingIfNeeded: registrationID.rawValue) + self.fileDescriptor = fileDescriptor + self.eventType = eventType + self.padding = 0 + } + + @inlinable init(rawValue: UInt64) { + let unpacked = IntegerBitPacking.unpackUInt32UInt16UInt8(rawValue) + self = .init(registrationID: SelectorRegistrationID(rawValue: UInt32(unpacked.1)), + fileDescriptor: CInt(unpacked.0), + eventType: CQEEventType(rawValue:unpacked.2)!) + } +} + +extension UInt64 { + init(_ uringUserData: URingUserData) { + let fd = uringUserData.fileDescriptor + let eventType = uringUserData.eventType.rawValue + assert(fd >= 0, "\(fd) is not a valid file descriptor") + assert(eventType >= 0, "\(eventType) is not a valid eventType") + + self = IntegerBitPacking.packUInt32UInt16UInt8(UInt32(truncatingIfNeeded: fd), + uringUserData.registrationID, + eventType) + } +} + +// These are the events returned up to the selector +internal struct URingEvent { + var fd: CInt + var pollMask: UInt32 + var registrationID: UInt16 // we just have the truncated lower 16 bits of the registrationID + var pollCancelled: Bool + init () { + self.fd = -1 + self.pollMask = 0 + self.registrationID = 0 + self.pollCancelled = false + } +} + +// This is the key we use for merging events in our internal hashtable +struct FDEventKey: Hashable { + var fileDescriptor: CInt + var registrationID: UInt16 // we just have the truncated lower 16 bits of the registrationID + + init(_ f: CInt, _ s: UInt16) { + self.fileDescriptor = f + self.registrationID = s + } +} + +final internal class URing { + internal static let POLLIN: CUnsignedInt = numericCast(CNIOLinux.POLLIN) + internal static let POLLOUT: CUnsignedInt = numericCast(CNIOLinux.POLLOUT) + internal static let POLLERR: CUnsignedInt = numericCast(CNIOLinux.POLLERR) + internal static let POLLRDHUP: CUnsignedInt = CNIOLinux_POLLRDHUP() // numericCast(CNIOLinux.POLLRDHUP) + internal static let POLLHUP: CUnsignedInt = numericCast(CNIOLinux.POLLHUP) + internal static let POLLCANCEL: CUnsignedInt = 0xF0000000 // Poll cancelled, need to reregister for singleshot polls + + private var ring = io_uring() + private let ringEntries: CUnsignedInt = 8192 + private let cqeMaxCount: UInt32 = 8192 // this is the max chunk of CQE we take. + + var cqes: UnsafeMutablePointer?> + var fdEvents = [FDEventKey : UInt32]() // fd, sequence_identifier : merged event_poll_return + var emptyCqe = io_uring_cqe() + + var fd: CInt { + return ring.ring_fd + } + + static var io_uring_use_multishot_poll: Bool { + #if SWIFTNIO_IO_URING_MULTISHOT + return true + #else + return false + #endif + } + + func _dumpCqes(_ header:String, count: Int = 1) { + #if SWIFTNIO_IO_URING_DEBUG_DUMP_CQE + func _debugPrintCQE(_ s: String) { + print("Q [\(NIOThread.current)] " + s) + } + + if count < 0 { + return + } + + _debugPrintCQE(header + " CQE:s [\(cqes)] - ring flags are [\(ring.flags)]") + for i in 0..?>.allocate(capacity: Int(cqeMaxCount)) + cqes.initialize(repeating:&emptyCqe, count:Int(cqeMaxCount)) + } + + deinit { + cqes.deallocate() + } + + internal func io_uring_queue_init() throws -> () { + if (CNIOLinux.io_uring_queue_init(ringEntries, &ring, 0 ) != 0) + { + throw URingError.uringSetupFailure + } + + _debugPrint("io_uring_queue_init \(self.ring.ring_fd)") + } + + internal func io_uring_queue_exit() { + _debugPrint("io_uring_queue_exit \(self.ring.ring_fd)") + CNIOLinux.io_uring_queue_exit(&ring) + } + + // Adopting some retry code from queue.c from liburing with slight + // modifications - we never want to have to handle retries of + // SQE allocation in all places it could possibly occur. + // If the SQ ring is full, we may need to submit IO first + func withSQE(_ body: (UnsafeMutablePointer?) throws -> R) rethrows -> R + { + // io_uring_submit can fail here due to backpressure from kernel for not reaping CQE:s. + // + // I think we should consider handling that as a fatalError, as fundamentally the ring size is too small + // compared to the amount of events the user tries to push through in a single eventloop tick. + // + // This is mostly a problem for synthetic tests that e.g. do a huge amount of registration modifications. + // + // This is a slight design issue with SwiftNIO in general that should be discussed. + // + while true { + if let sqe = CNIOLinux.io_uring_get_sqe(&ring) { + return try body(sqe) + } + self.io_uring_flush() + } + } + + // Ok, this was a bummer - turns out that flushing multiple SQE:s + // can fail midflight and this will actually happen for real when e.g. a socket + // has gone down and we are re-registering polls this means we will silently lose any + // entries after the failed fd. Ouch. Proper approach is to use io_uring_sq_ready() in a loop. + // See: https://github.com/axboe/liburing/issues/309 + internal func io_uring_flush() { // When using SQPOLL this is basically a NOP + var waitingSubmissions: UInt32 = 0 + var submissionCount = 0 + var retval: CInt + + waitingSubmissions = CNIOLinux.io_uring_sq_ready(&ring) + + loop: while (waitingSubmissions > 0) + { + retval = CNIOLinux.io_uring_submit(&ring) + submissionCount += 1 + + switch retval { + // We can get -EAGAIN if the CQE queue is full and we get back pressure from + // the kernel to start processing CQE:s. If we break here with unsubmitted + // SQE:s, they will stay pending on the user-level side and be flushed + // to the kernel after we had the opportunity to reap more CQE:s + // In practice it will be at the end of whenReady the next + // time around. Given the async nature, this is fine, we will not + // lose any submissions. We could possibly still get stuck + // trying to get new SQE if the actual SQE queue is full, but + // that would be due to user error in usage IMHO and we should fatalError there. + case -EAGAIN, -EBUSY: + _debugPrint("io_uring_flush io_uring_submit -EBUSY/-EAGAIN waitingSubmissions[\(waitingSubmissions)] submissionCount[\(submissionCount)]. Breaking out and resubmitting later (whenReady() end).") + break loop + // -ENOMEM when there is not enough memory to do internal allocations on the kernel side. + // Right nog we just loop with a sleep trying to buy time, but could also possibly fatalError here. + // See: https://github.com/axboe/liburing/issues/309 + case -ENOMEM: + usleep(10_000) // let's not busy loop to give the kernel some time to recover if possible + _debugPrint("io_uring_flush io_uring_submit -ENOMEM \(submissionCount)") + case 0: + _debugPrint("io_uring_flush io_uring_submit submitted 0, so far needed submissionCount[\(submissionCount)] waitingSubmissions[\(waitingSubmissions)] submitted [\(retval)] SQE:s this iteration") + break + case 1...: + _debugPrint("io_uring_flush io_uring_submit needed [\(submissionCount)] submission(s), submitted [\(retval)] SQE:s out of [\(waitingSubmissions)] possible") + break + default: // other errors + fatalError("Unexpected error [\(retval)] from io_uring_submit ") + } + + waitingSubmissions = CNIOLinux.io_uring_sq_ready(&ring) + } + } + + // we stuff event type into the upper byte, the next 3 bytes gives us the sequence number (16M before wrap) and final 4 bytes are fd. + internal func io_uring_prep_poll_add(fileDescriptor: CInt, pollMask: UInt32, registrationID: SelectorRegistrationID, submitNow: Bool = true, multishot: Bool = true) -> () { + let bitPattern = UInt64(URingUserData(registrationID: registrationID, fileDescriptor: fileDescriptor, eventType:CQEEventType.poll)) + let bitpatternAsPointer = UnsafeMutableRawPointer.init(bitPattern: UInt(bitPattern)) + + _debugPrint("io_uring_prep_poll_add fileDescriptor[\(fileDescriptor)] pollMask[\(pollMask)] bitpatternAsPointer[\(String(describing:bitpatternAsPointer))] submitNow[\(submitNow)] multishot[\(multishot)]") + + self.withSQE { sqe in + CNIOLinux.io_uring_prep_poll_add(sqe, fileDescriptor, pollMask) + CNIOLinux.io_uring_sqe_set_data(sqe, bitpatternAsPointer) // must be done after prep_poll_add, otherwise zeroed out. + + if multishot { + sqe!.pointee.len |= IORING_POLL_ADD_MULTI; // turn on multishots, set through environment variable + } + } + + if submitNow { + self.io_uring_flush() + } + } + + internal func io_uring_prep_poll_remove(fileDescriptor: CInt, pollMask: UInt32, registrationID: SelectorRegistrationID, submitNow: Bool = true, link: Bool = false) -> () { + let bitPattern = UInt64(URingUserData(registrationID: registrationID, + fileDescriptor: fileDescriptor, + eventType:CQEEventType.poll)) + let userbitPattern = UInt64(URingUserData(registrationID: registrationID, + fileDescriptor: fileDescriptor, + eventType:CQEEventType.pollDelete)) + + _debugPrint("io_uring_prep_poll_remove fileDescriptor[\(fileDescriptor)] pollMask[\(pollMask)] bitpatternAsPointer[\(String(describing: bitPattern))] userBitpatternAsPointer[\(String(describing: userbitPattern))] submitNow[\(submitNow)] link[\(link)]") + + self.withSQE { sqe in + CNIOLinux.io_uring_prep_poll_remove(sqe, .init(userData: bitPattern)) + CNIOLinux.io_uring_sqe_set_data(sqe, .init(userData: userbitPattern)) // must be done after prep_poll_add, otherwise zeroed out. + + if link { + CNIOLinux_io_uring_set_link_flag(sqe) + } + } + + if submitNow { + self.io_uring_flush() + } + } + + // the update/multishot polls are + internal func io_uring_poll_update(fileDescriptor: CInt, newPollmask: UInt32, oldPollmask: UInt32, registrationID: SelectorRegistrationID, submitNow: Bool = true, multishot: Bool = true) -> () { + + let bitpattern = UInt64(URingUserData(registrationID: registrationID, + fileDescriptor: fileDescriptor, + eventType:CQEEventType.poll)) + let userbitPattern = UInt64(URingUserData(registrationID: registrationID, + fileDescriptor: fileDescriptor, + eventType:CQEEventType.pollModify)) + + _debugPrint("io_uring_poll_update fileDescriptor[\(fileDescriptor)] oldPollmask[\(oldPollmask)] newPollmask[\(newPollmask)] userBitpatternAsPointer[\(String(describing: userbitPattern))]") + + self.withSQE { sqe in + // "Documentation" for multishot polls and updates here: + // https://git.kernel.dk/cgit/linux-block/commit/?h=poll-multiple&id=33021a19e324fb747c2038416753e63fd7cd9266 + var flags = IORING_POLL_UPDATE_EVENTS | IORING_POLL_UPDATE_USER_DATA + if multishot { + flags |= IORING_POLL_ADD_MULTI // ask for multiple updates + } + + CNIOLinux.io_uring_prep_poll_update(sqe, .init(userData: bitpattern), .init(userData: bitpattern), newPollmask, flags) + CNIOLinux.io_uring_sqe_set_data(sqe, .init(userData: userbitPattern)) + } + + if submitNow { + self.io_uring_flush() + } + } + + internal func _debugPrint(_ s: @autoclosure () -> String) + { + #if SWIFTNIO_IO_URING_DEBUG_URING + print("L [\(NIOThread.current)] " + s()) + #endif + } + + // We merge results into fdEvents on (fd, registrationID) for the given CQE + // this minimizes amount of events propagating up and allows Selector to discard + // events with an old sequence identifier. + internal func _process_cqe(events: UnsafeMutablePointer, cqeIndex: Int, multishot: Bool) { + let bitPattern = UInt(bitPattern:io_uring_cqe_get_data(cqes[cqeIndex])) + let uringUserData = URingUserData(rawValue: UInt64(bitPattern)) + let result = cqes[cqeIndex]!.pointee.res + + switch uringUserData.eventType { + case .poll: + switch result { + case -ECANCELED: + var pollError: UInt32 = 0 + assert(uringUserData.fileDescriptor >= 0, "fd must be zero or greater") + if multishot { // -ECANCELED for streaming polls, should signal error + pollError = URing.POLLERR | URing.POLLHUP + } else { // this just signals that Selector just should resubmit a new fresh poll + pollError = URing.POLLCANCEL + } + if let current = fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = current | pollError + } else { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = pollError + } + break + // We can validly receive an EBADF as a close() can race vis-a-vis pending SQE:s + // with polls / pollModifications - in that case, we should just discard the result. + // This is similar to the assert in BaseSocketChannel and is due to the lack + // of implicit synchronization with regard to registration changes for io_uring + // - we simply can't know when the kernel will process our SQE without + // heavy-handed synchronization which would dump performance. + // Discussion here: + // https://github.com/apple/swift-nio/pull/1804#discussion_r621304055 + // including clarifications from @isilence (one of the io_uring developers) + case -EBADF: + _debugPrint("Failed poll with -EBADF for cqeIndex[\(cqeIndex)]") + break + case ..<0: // other errors + fatalError("Failed poll with unexpected error (\(result) for cqeIndex[\(cqeIndex)]") + break + case 0: // successfull chained add for singleshots, not an event + break + default: // positive success + assert(uringUserData.fileDescriptor >= 0, "fd must be zero or greater") + let uresult = UInt32(result) + + if let current = fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = current | uresult + } else { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = uresult + } + } + case .pollModify: // we only get this for multishot modifications + switch result { + case -ECANCELED: // -ECANCELED for streaming polls, should signal error + assert(uringUserData.fileDescriptor >= 0, "fd must be zero or greater") + + let pollError = URing.POLLERR // URing.POLLERR // (URing.POLLHUP | URing.POLLERR) + if let current = fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = current | pollError + } else { + fdEvents[FDEventKey(uringUserData.fileDescriptor, uringUserData.registrationID)] = pollError + } + break + case -EALREADY: + _debugPrint("Failed pollModify with -EALREADY for cqeIndex[\(cqeIndex)]") + break + case -ENOENT: + _debugPrint("Failed pollModify with -ENOENT for cqeIndex [\(cqeIndex)]") + break + // See the description for EBADF handling above in the poll case for rationale of allowing EBADF. + case -EBADF: + _debugPrint("Failed pollModify with -EBADF for cqeIndex[\(cqeIndex)]") + break + case ..<0: // other errors + fatalError("Failed pollModify with unexpected error (\(result) for cqeIndex[\(cqeIndex)]") + break + case 0: // successfull chained add, not an event + break + default: // positive success + fatalError("pollModify returned > 0") + } + break + case .pollDelete: + break + } + } + + internal func io_uring_peek_batch_cqe(events: UnsafeMutablePointer, maxevents: UInt32, multishot: Bool = true) -> Int { + var eventCount = 0 + var currentCqeCount = CNIOLinux.io_uring_peek_batch_cqe(&ring, cqes, cqeMaxCount) + + if currentCqeCount == 0 { + _debugPrint("io_uring_peek_batch_cqe found zero events, breaking out") + return 0 + } + + _debugPrint("io_uring_peek_batch_cqe found [\(currentCqeCount)] events") + + self._dumpCqes("io_uring_peek_batch_cqe", count: Int(currentCqeCount)) + + assert(currentCqeCount >= 0, "currentCqeCount should never be negative") + assert(maxevents > 0, "maxevents should be a positive number") + + for cqeIndex in 0 ..< currentCqeCount + { + self._process_cqe(events: events, cqeIndex: Int(cqeIndex), multishot:multishot) + + if (fdEvents.count == maxevents) // ensure we don't generate more events than maxevents + { + _debugPrint("io_uring_peek_batch_cqe breaking loop early, currentCqeCount [\(currentCqeCount)] maxevents [\(maxevents)]") + currentCqeCount = maxevents // to make sure we only cq_advance the correct amount + break + } + } + + io_uring_cq_advance(&ring, currentCqeCount) // bulk variant of io_uring_cqe_seen(&ring, dataPointer) + + // we just return single event per fd, sequencenumber pair + eventCount = 0 + for (eventKey, pollMask) in fdEvents { + assert(eventCount < maxevents) + assert(eventKey.fileDescriptor >= 0) + + events[eventCount].fd = eventKey.fileDescriptor + events[eventCount].pollMask = pollMask + events[eventCount].registrationID = eventKey.registrationID + if (pollMask & URing.POLLCANCEL) != 0 { + events[eventCount].pollMask &= ~URing.POLLCANCEL + events[eventCount].pollCancelled = true + } + eventCount += 1 + } + + fdEvents.removeAll(keepingCapacity: true) // reused for next batch + + _debugPrint("io_uring_peek_batch_cqe returning [\(eventCount)] events, fdEvents.count [\(fdEvents.count)]") + + return eventCount + } + + internal func _io_uring_wait_cqe_shared(events: UnsafeMutablePointer, error: Int32, multishot: Bool) throws -> Int { + var eventCount = 0 + + switch error { + case 0: + break + case -CNIOLinux.EINTR: + _debugPrint("_io_uring_wait_cqe_shared got CNIOLinux.EINTR") + return eventCount + case -CNIOLinux.ETIME: + _debugPrint("_io_uring_wait_cqe_shared timed out with -CNIOLinux.ETIME") + CNIOLinux.io_uring_cqe_seen(&ring, cqes[0]) + return eventCount + default: + _debugPrint("URingError.uringWaitCqeFailure \(error)") + throw URingError.uringWaitCqeFailure + } + + self._dumpCqes("_io_uring_wait_cqe_shared") + + self._process_cqe(events: events, cqeIndex: 0, multishot:multishot) + + CNIOLinux.io_uring_cqe_seen(&ring, cqes[0]) + + if let firstEvent = fdEvents.first { + events[0].fd = firstEvent.key.fileDescriptor + events[0].pollMask = firstEvent.value + events[0].registrationID = firstEvent.key.registrationID + eventCount = 1 + } else { + _debugPrint("_io_uring_wait_cqe_shared if let firstEvent = fdEvents.first failed") + } + + fdEvents.removeAll(keepingCapacity: true) // reused for next batch + + return eventCount + } + + internal func io_uring_wait_cqe(events: UnsafeMutablePointer, maxevents: UInt32, multishot: Bool = true) throws -> Int { + _debugPrint("io_uring_wait_cqe") + + let error = CNIOLinux.io_uring_wait_cqe(&ring, cqes) + + return try self._io_uring_wait_cqe_shared(events: events, error: error, multishot:multishot) + } + + internal func io_uring_wait_cqe_timeout(events: UnsafeMutablePointer, maxevents: UInt32, timeout: TimeAmount, multishot: Bool = true) throws -> Int { + var ts = timeout.kernelTimespec() + + _debugPrint("io_uring_wait_cqe_timeout.ETIME milliseconds \(ts)") + + let error = CNIOLinux.io_uring_wait_cqe_timeout(&ring, cqes, &ts) + + return try self._io_uring_wait_cqe_shared(events: events, error: error, multishot:multishot) + } +} + +// MARK: Conversion helpers +// Newer versions of liburing changed one of the method arguments from UnsafeMutableRawPointer +// to UInt64 in order to allow 32-bit systems to work properly. We therefore need a way to +// transform a UInt64 into either of these types. These two initializers help us do that in +// a way that supports both the old and new format in source. +extension UInt64 { + init(userData: UInt64) { + self = userData + } +} + +extension Optional where Wrapped == UnsafeMutableRawPointer { + init(userData: UInt64) { + // This will crash on 32-bit systems: that's fine, our liburing support + // never worked on 32-bit for older libraries anyway. + self = .init(bitPattern: UInt(userData)) + } +} + +#endif + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift new file mode 100644 index 00000000..5bd05833 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift @@ -0,0 +1,395 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers +import Dispatch + +struct NIORegistration: Registration { + enum ChannelType { + case serverSocketChannel(ServerSocketChannel) + case socketChannel(SocketChannel) + case datagramChannel(DatagramChannel) + case pipeChannel(PipeChannel, PipeChannel.Direction) + } + + var channel: ChannelType + + /// The `SelectorEventSet` in which this `NIORegistration` is interested in. + var interested: SelectorEventSet + + /// The registration ID for this `NIORegistration` used by the `Selector`. + var registrationID: SelectorRegistrationID +} + +private let nextEventLoopGroupID = NIOAtomic.makeAtomic(value: 0) + +/// Called per `NIOThread` that is created for an EventLoop to do custom initialization of the `NIOThread` before the actual `EventLoop` is run on it. +typealias ThreadInitializer = (NIOThread) -> Void + +/// An `EventLoopGroup` which will create multiple `EventLoop`s, each tied to its own `NIOThread`. +/// +/// The effect of initializing a `MultiThreadedEventLoopGroup` is to spawn `numberOfThreads` fresh threads which will +/// all run their own `EventLoop`. Those threads will not be shut down until `shutdownGracefully` or +/// `syncShutdownGracefully` is called. +/// +/// - note: It's good style to call `MultiThreadedEventLoopGroup.shutdownGracefully` or +/// `MultiThreadedEventLoopGroup.syncShutdownGracefully` when you no longer need this `EventLoopGroup`. In +/// many cases that is just before your program exits. +/// - warning: Unit tests often spawn one `MultiThreadedEventLoopGroup` per unit test to force isolation between the +/// tests. In those cases it's important to shut the `MultiThreadedEventLoopGroup` down at the end of the +/// test. A good place to start a `MultiThreadedEventLoopGroup` is the `setUp` method of your `XCTestCase` +/// subclass, a good place to shut it down is the `tearDown` method. +public final class MultiThreadedEventLoopGroup: EventLoopGroup { + + private enum RunState { + case running + case closing([(DispatchQueue, (Error?) -> Void)]) + case closed(Error?) + } + + private static let threadSpecificEventLoop = ThreadSpecificVariable() + + private let myGroupID: Int + private let index = NIOAtomic.makeAtomic(value: 0) + private var eventLoops: [SelectableEventLoop] + private let shutdownLock: Lock = Lock() + private var runState: RunState = .running + + private static func runTheLoop(thread: NIOThread, + parentGroup: MultiThreadedEventLoopGroup? /* nil iff thread take-over */, + canEventLoopBeShutdownIndividually: Bool, + selectorFactory: @escaping () throws -> NIOPosix.Selector, + initializer: @escaping ThreadInitializer, + _ callback: @escaping (SelectableEventLoop) -> Void) { + assert(NIOThread.current == thread) + initializer(thread) + + do { + let loop = SelectableEventLoop(thread: thread, + parentGroup: parentGroup, + selector: try selectorFactory(), + canBeShutdownIndividually: canEventLoopBeShutdownIndividually) + threadSpecificEventLoop.currentValue = loop + defer { + threadSpecificEventLoop.currentValue = nil + } + callback(loop) + try loop.run() + } catch { + // We fatalError here because the only reasons this can be hit is if the underlying kqueue/epoll give us + // errors that we cannot handle which is an unrecoverable error for us. + fatalError("Unexpected error while running SelectableEventLoop: \(error).") + } + } + + private static func setupThreadAndEventLoop(name: String, + parentGroup: MultiThreadedEventLoopGroup, + selectorFactory: @escaping () throws -> NIOPosix.Selector, + initializer: @escaping ThreadInitializer) -> SelectableEventLoop { + let lock = Lock() + /* the `loopUpAndRunningGroup` is done by the calling thread when the EventLoop has been created and was written to `_loop` */ + let loopUpAndRunningGroup = DispatchGroup() + + /* synchronised by `lock` */ + var _loop: SelectableEventLoop! = nil + + loopUpAndRunningGroup.enter() + NIOThread.spawnAndRun(name: name, detachThread: false) { t in + MultiThreadedEventLoopGroup.runTheLoop(thread: t, + parentGroup: parentGroup, + canEventLoopBeShutdownIndividually: false, // part of MTELG + selectorFactory: selectorFactory, + initializer: initializer) { l in + lock.withLock { + _loop = l + } + loopUpAndRunningGroup.leave() + } + } + loopUpAndRunningGroup.wait() + return lock.withLock { _loop } + } + + /// Creates a `MultiThreadedEventLoopGroup` instance which uses `numberOfThreads`. + /// + /// - note: Don't forget to call `shutdownGracefully` or `syncShutdownGracefully` when you no longer need this + /// `EventLoopGroup`. If you forget to shut the `EventLoopGroup` down you will leak `numberOfThreads` + /// (kernel) threads which are costly resources. This is especially important in unit tests where one + /// `MultiThreadedEventLoopGroup` is started per test case. + /// + /// - arguments: + /// - numberOfThreads: The number of `Threads` to use. + public convenience init(numberOfThreads: Int) { + self.init(numberOfThreads: numberOfThreads, selectorFactory: NIOPosix.Selector.init) + } + + internal convenience init(numberOfThreads: Int, + selectorFactory: @escaping () throws -> NIOPosix.Selector) { + precondition(numberOfThreads > 0, "numberOfThreads must be positive") + let initializers: [ThreadInitializer] = Array(repeating: { _ in }, count: numberOfThreads) + self.init(threadInitializers: initializers, selectorFactory: selectorFactory) + } + + /// Creates a `MultiThreadedEventLoopGroup` instance which uses the given `ThreadInitializer`s. One `NIOThread` per `ThreadInitializer` is created and used. + /// + /// - arguments: + /// - threadInitializers: The `ThreadInitializer`s to use. + internal init(threadInitializers: [ThreadInitializer], + selectorFactory: @escaping () throws -> NIOPosix.Selector = NIOPosix.Selector.init) { + let myGroupID = nextEventLoopGroupID.add(1) + self.myGroupID = myGroupID + var idx = 0 + self.eventLoops = [] // Just so we're fully initialised and can vend `self` to the `SelectableEventLoop`. + self.eventLoops = threadInitializers.map { initializer in + // Maximum name length on linux is 16 by default. + let ev = MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name: "NIO-ELT-\(myGroupID)-#\(idx)", + parentGroup: self, + selectorFactory: selectorFactory, + initializer: initializer) + idx += 1 + return ev + } + } + + /// Returns the `EventLoop` for the calling thread. + /// + /// - returns: The current `EventLoop` for the calling thread or `nil` if none is assigned to the thread. + public static var currentEventLoop: EventLoop? { + return self.currentSelectableEventLoop + } + + internal static var currentSelectableEventLoop: SelectableEventLoop? { + return threadSpecificEventLoop.currentValue + } + + /// Returns an `EventLoopIterator` over the `EventLoop`s in this `MultiThreadedEventLoopGroup`. + /// + /// - returns: `EventLoopIterator` + public func makeIterator() -> EventLoopIterator { + return EventLoopIterator(self.eventLoops) + } + + /// Returns the next `EventLoop` from this `MultiThreadedEventLoopGroup`. + /// + /// `MultiThreadedEventLoopGroup` uses _round robin_ across all its `EventLoop`s to select the next one. + /// + /// - returns: The next `EventLoop` to use. + public func next() -> EventLoop { + return eventLoops[abs(index.add(1) % eventLoops.count)] + } + + /// Returns the current `EventLoop` if we are on an `EventLoop` of this `MultiThreadedEventLoopGroup` instance. + /// + /// - returns: The `EventLoop`. + public func any() -> EventLoop { + if let loop = Self.currentSelectableEventLoop, + // We are on `loop`'s thread, so we may ask for the its parent group. + loop.parentGroupCallableFromThisEventLoopOnly() === self { + // Nice, we can return this. + loop.assertInEventLoop() + return loop + } else { + // Oh well, let's just vend the next one then. + return self.next() + } + } + + /// Shut this `MultiThreadedEventLoopGroup` down which causes the `EventLoop`s and their associated threads to be + /// shut down and release their resources. + /// + /// Even though calling `shutdownGracefully` more than once should be avoided, it is safe to do so and execution + /// of the `handler` is guaranteed. + /// + /// - parameters: + /// - queue: The `DispatchQueue` to run `handler` on when the shutdown operation completes. + /// - handler: The handler which is called after the shutdown operation completes. The parameter will be `nil` + /// on success and contain the `Error` otherwise. + public func shutdownGracefully(queue: DispatchQueue, _ handler: @escaping (Error?) -> Void) { + // This method cannot perform its final cleanup using EventLoopFutures, because it requires that all + // our event loops still be alive, and they may not be. Instead, we use Dispatch to manage + // our shutdown signaling, and then do our cleanup once the DispatchQueue is empty. + let g = DispatchGroup() + let q = DispatchQueue(label: "nio.shutdownGracefullyQueue", target: queue) + let wasRunning: Bool = self.shutdownLock.withLock { + // We need to check the current `runState` and react accordingly. + switch self.runState { + case .running: + // If we are still running, we set the `runState` to `closing`, + // so that potential future invocations know, that the shutdown + // has already been initiaited. + self.runState = .closing([]) + return true + case .closing(var callbacks): + // If we are currently closing, we need to register the `handler` + // for invocation after the shutdown is completed. + callbacks.append((q, handler)) + self.runState = .closing(callbacks) + return false + case .closed(let error): + // If we are already closed, we can directly dispatch the `handler` + q.async { + handler(error) + } + return false + } + } + + // If the `runState` was not `running` when `shutdownGracefully` was called, + // the shutdown has already been initiated and we have to return here. + guard wasRunning else { + return + } + + var result: Result = .success(()) + + for loop in self.eventLoops { + g.enter() + loop.initiateClose(queue: q) { closeResult in + switch closeResult { + case .success: + () + case .failure(let error): + result = .failure(error) + } + g.leave() + } + } + + g.notify(queue: q) { + for loop in self.eventLoops { + loop.syncFinaliseClose(joinThread: true) + } + var overallError: Error? + var queueCallbackPairs: [(DispatchQueue, (Error?) -> Void)]? = nil + self.shutdownLock.withLock { + switch self.runState { + case .closed, .running: + preconditionFailure("MultiThreadedEventLoopGroup in illegal state when closing: \(self.runState)") + case .closing(let callbacks): + queueCallbackPairs = callbacks + switch result { + case .success: + overallError = nil + case .failure(let error): + overallError = error + } + self.runState = .closed(overallError) + } + } + + queue.async { + handler(overallError) + } + for queueCallbackPair in queueCallbackPairs! { + queueCallbackPair.0.async { + queueCallbackPair.1(overallError) + } + } + } + } + + /// Convert the calling thread into an `EventLoop`. + /// + /// This function will not return until the `EventLoop` has stopped. You can initiate stopping the `EventLoop` by + /// calling `eventLoop.shutdownGracefully` which will eventually make this function return. + /// + /// - parameters: + /// - callback: Called _on_ the `EventLoop` that the calling thread was converted to, providing you the + /// `EventLoop` reference. Just like usually on the `EventLoop`, do not block in `callback`. + public static func withCurrentThreadAsEventLoop(_ callback: @escaping (EventLoop) -> Void) { + let callingThread = NIOThread.current + MultiThreadedEventLoopGroup.runTheLoop(thread: callingThread, + parentGroup: nil, + canEventLoopBeShutdownIndividually: true, + selectorFactory: NIOPosix.Selector.init, + initializer: { _ in }) { loop in + loop.assertInEventLoop() + callback(loop) + } + } + + public func _preconditionSafeToSyncShutdown(file: StaticString, line: UInt) { + if let eventLoop = MultiThreadedEventLoopGroup.currentEventLoop { + preconditionFailure(""" + BUG DETECTED: syncShutdownGracefully() must not be called when on an EventLoop. + Calling syncShutdownGracefully() on any EventLoop can lead to deadlocks. + Current eventLoop: \(eventLoop) + """, file: file, line: line) + } + } +} + +extension MultiThreadedEventLoopGroup: CustomStringConvertible { + public var description: String { + return "MultiThreadedEventLoopGroup { threadPattern = NIO-ELT-\(self.myGroupID)-#* }" + } +} + +@usableFromInline +internal struct ScheduledTask { + /// The id of the scheduled task. + /// + /// - Important: This id has two purposes. First, it is used to give this struct an identity so that we can implement ``Equatable`` + /// Second, it is used to give the tasks an order which we use to execute them. + /// This means, the ids need to be unique for a given ``SelectableEventLoop`` and they need to be in ascending order. + @usableFromInline + let id: UInt64 + let task: () -> Void + private let failFn: (Error) ->() + @usableFromInline + internal let _readyTime: NIODeadline + + @usableFromInline + init(id: UInt64, _ task: @escaping () -> Void, _ failFn: @escaping (Error) -> Void, _ time: NIODeadline) { + self.id = id + self.task = task + self.failFn = failFn + self._readyTime = time + } + + func readyIn(_ t: NIODeadline) -> TimeAmount { + if _readyTime < t { + return .nanoseconds(0) + } + return _readyTime - t + } + + func fail(_ error: Error) { + failFn(error) + } +} + +extension ScheduledTask: CustomStringConvertible { + @usableFromInline + var description: String { + return "ScheduledTask(readyTime: \(self._readyTime))" + } +} + +extension ScheduledTask: Comparable { + @usableFromInline + static func < (lhs: ScheduledTask, rhs: ScheduledTask) -> Bool { + if lhs._readyTime == rhs._readyTime { + return lhs.id < rhs.id + } else { + return lhs._readyTime < rhs._readyTime + } + } + + @usableFromInline + static func == (lhs: ScheduledTask, rhs: ScheduledTask) -> Bool { + return lhs.id == rhs.id + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NIOThreadPool.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NIOThreadPool.swift new file mode 100644 index 00000000..6e475dc4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NIOThreadPool.swift @@ -0,0 +1,266 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch +import NIOCore +import NIOConcurrencyHelpers + +/// Errors that may be thrown when executing work on a `NIOThreadPool` +public enum NIOThreadPoolError { + + /// The `NIOThreadPool` was not active. + public struct ThreadPoolInactive: Error { } +} + + +/// A thread pool that should be used if some (kernel thread) blocking work +/// needs to be performed for which no non-blocking API exists. +/// +/// When using NIO it is crucial not to block any of the `EventLoop`s as that +/// leads to slow downs or stalls of arbitrary other work. Unfortunately though +/// there are tasks that applications need to achieve for which no non-blocking +/// APIs exist. In those cases `NIOThreadPool` can be used but should be +/// treated as a last resort. +/// +/// - note: The prime example for missing non-blocking APIs is file IO on UNIX. +/// The OS does not provide a usable and truly non-blocking API but with +/// `NonBlockingFileIO` NIO provides a high-level API for file IO that should +/// be preferred to running blocking file IO system calls directly on +/// `NIOThreadPool`. Under the covers `NonBlockingFileIO` will use +/// `NIOThreadPool` on all currently supported platforms though. +public final class NIOThreadPool { + + /// The state of the `WorkItem`. + public enum WorkItemState { + /// The `WorkItem` is active now and in process by the `NIOThreadPool`. + case active + /// The `WorkItem` was cancelled and will not be processed by the `NIOThreadPool`. + case cancelled + } + + /// The work that should be done by the `NIOThreadPool`. + public typealias WorkItem = (WorkItemState) -> Void + + private enum State { + /// The `NIOThreadPool` is already stopped. + case stopped + /// The `NIOThreadPool` is shutting down, the array has one boolean entry for each thread indicating if it has shut down already. + case shuttingDown([Bool]) + /// The `NIOThreadPool` is up and running, the `CircularBuffer` containing the yet unprocessed `WorkItems`. + case running(CircularBuffer) + } + private let semaphore = DispatchSemaphore(value: 0) + private let lock = Lock() + private var threads: [NIOThread]? = nil // protected by `lock` + private var state: State = .stopped + private let numberOfThreads: Int + + /// Gracefully shutdown this `NIOThreadPool`. All tasks will be run before shutdown will take place. + /// + /// - parameters: + /// - queue: The `DispatchQueue` used to executed the callback + /// - callback: The function to be executed once the shutdown is complete. + public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) { + let g = DispatchGroup() + let threadsToJoin = self.lock.withLock { () -> [NIOThread] in + switch self.state { + case .running(let items): + queue.async { + items.forEach { $0(.cancelled) } + } + self.state = .shuttingDown(Array(repeating: true, count: numberOfThreads)) + (0.. WorkItem? in + switch self.state { + case .running(var items): + items.append(body) + self.state = .running(items) + self.semaphore.signal() + return nil + case .shuttingDown, .stopped: + return body + } + } + /* if item couldn't be added run it immediately indicating that it couldn't be run */ + item.map { $0(.cancelled) } + } + + /// Initialize a `NIOThreadPool` thread pool with `numberOfThreads` threads. + /// + /// - parameters: + /// - numberOfThreads: The number of threads to use for the thread pool. + public init(numberOfThreads: Int) { + self.numberOfThreads = numberOfThreads + } + + private func process(identifier: Int) { + var item: WorkItem? = nil + repeat { + /* wait until work has become available */ + item = nil // ensure previous work item is not retained for duration of semaphore wait + self.semaphore.wait() + + item = self.lock.withLock { () -> (WorkItem)? in + switch self.state { + case .running(var items): + let item = items.removeFirst() + self.state = .running(items) + return item + case .shuttingDown(var aliveStates): + assert(aliveStates[identifier]) + aliveStates[identifier] = false + self.state = .shuttingDown(aliveStates) + return nil + case .stopped: + return nil + } + } + /* if there was a work item popped, run it */ + item.map { $0(.active) } + } while item != nil + } + + /// Start the `NIOThreadPool` if not already started. + public func start() { + let alreadyRunning: Bool = self.lock.withLock { + switch self.state { + case .running(_): + return true + case .shuttingDown(_): + // This should never happen + fatalError("start() called while in shuttingDown") + case .stopped: + self.state = .running(CircularBuffer(initialCapacity: 16)) + return false + } + } + + if alreadyRunning { + return + } + + let group = DispatchGroup() + + self.lock.withLock { + assert(self.threads == nil) + self.threads = [] + self.threads?.reserveCapacity(self.numberOfThreads) + } + + for id in 0..(eventLoop: EventLoop, _ body: @escaping () throws -> T) -> EventLoopFuture { + let promise = eventLoop.makePromise(of: T.self) + self.submit { shouldRun in + guard case shouldRun = NIOThreadPool.WorkItemState.active else { + promise.fail(NIOThreadPoolError.ThreadPoolInactive()) + return + } + do { + try promise.succeed(body()) + } catch { + promise.fail(error) + } + } + return promise.futureResult + } +} + +extension NIOThreadPool { + public func shutdownGracefully(_ callback: @escaping (Error?) -> Void) { + self.shutdownGracefully(queue: .global(), callback) + } + + public func syncShutdownGracefully() throws { + let errorStorageLock = Lock() + var errorStorage: Swift.Error? = nil + let continuation = DispatchWorkItem {} + self.shutdownGracefully { error in + if let error = error { + errorStorageLock.withLock { + errorStorage = error + } + } + continuation.perform() + } + continuation.wait() + try errorStorageLock.withLock { + if let error = errorStorage { + throw error + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NonBlockingFileIO.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NonBlockingFileIO.swift new file mode 100644 index 00000000..fe18905a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/NonBlockingFileIO.swift @@ -0,0 +1,502 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + +/// `NonBlockingFileIO` is a helper that allows you to read files without blocking the calling thread. +/// +/// It is worth noting that `kqueue`, `epoll` or `poll` returning claiming a file is readable does not mean that the +/// data is already available in the kernel's memory. In other words, a `read` from a file can still block even if +/// reported as readable. This behaviour is also documented behaviour: +/// +/// - [`poll`](http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html): "Regular files shall always poll TRUE for reading and writing." +/// - [`epoll`](http://man7.org/linux/man-pages/man7/epoll.7.html): "epoll is simply a faster poll(2), and can be used wherever the latter is used since it shares the same semantics." +/// - [`kqueue`](https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2): "Returns when the file pointer is not at the end of file." +/// +/// `NonBlockingFileIO` helps to work around this issue by maintaining its own thread pool that is used to read the data +/// from the files into memory. It will then hand the (in-memory) data back which makes it available without the possibility +/// of blocking. +public struct NonBlockingFileIO { + /// The default and recommended size for `NonBlockingFileIO`'s thread pool. + public static let defaultThreadPoolSize = 2 + + /// The default and recommended chunk size. + public static let defaultChunkSize = 128*1024 + + /// `NonBlockingFileIO` errors. + public enum Error: Swift.Error { + /// `NonBlockingFileIO` is meant to be used with file descriptors that are set to the default (blocking) mode. + /// It doesn't make sense to use it with a file descriptor where `O_NONBLOCK` is set therefore this error is + /// raised when that was requested. + case descriptorSetToNonBlocking + } + + private let threadPool: NIOThreadPool + + /// Initialize a `NonBlockingFileIO` which uses the `NIOThreadPool`. + /// + /// - parameters: + /// - threadPool: The `NIOThreadPool` that will be used for all the IO. + public init(threadPool: NIOThreadPool) { + self.threadPool = threadPool + } + + /// Read a `FileRegion` in chunks of `chunkSize` bytes on `NonBlockingFileIO`'s private thread + /// pool which is separate from any `EventLoop` thread. + /// + /// `chunkHandler` will be called on `eventLoop` for every chunk that was read. Assuming `fileRegion.readableBytes` is greater than + /// zero and there are enough bytes available `chunkHandler` will be called `1 + |_ fileRegion.readableBytes / chunkSize _|` + /// times, delivering `chunkSize` bytes each time. If less than `fileRegion.readableBytes` bytes can be read from the file, + /// `chunkHandler` will be called less often with the last invocation possibly being of less than `chunkSize` bytes. + /// + /// The allocation and reading of a subsequent chunk will only be attempted when `chunkHandler` succeeds. + /// + /// This method will not use the file descriptor's seek pointer which means there is no danger of reading from the + /// same `FileRegion` in multiple threads. + /// + /// - parameters: + /// - fileRegion: The file region to read. + /// - chunkSize: The size of the individual chunks to deliver. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the chunks. + /// - eventLoop: The `EventLoop` to call `chunkHandler` on. + /// - chunkHandler: Called for every chunk read. The next chunk will be read upon successful completion of the returned `EventLoopFuture`. If the returned `EventLoopFuture` fails, the overall operation is aborted. + /// - returns: An `EventLoopFuture` which is the result of the overall operation. If either the reading of `fileHandle` or `chunkHandler` fails, the `EventLoopFuture` will fail too. If the reading of `fileHandle` as well as `chunkHandler` always succeeded, the `EventLoopFuture` will succeed too. + public func readChunked(fileRegion: FileRegion, + chunkSize: Int = NonBlockingFileIO.defaultChunkSize, + allocator: ByteBufferAllocator, + eventLoop: EventLoop, + chunkHandler: @escaping (ByteBuffer) -> EventLoopFuture) -> EventLoopFuture { + let readableBytes = fileRegion.readableBytes + return self.readChunked(fileHandle: fileRegion.fileHandle, + fromOffset: Int64(fileRegion.readerIndex), + byteCount: readableBytes, + chunkSize: chunkSize, + allocator: allocator, + eventLoop: eventLoop, + chunkHandler: chunkHandler) + } + + /// Read `byteCount` bytes in chunks of `chunkSize` bytes from `fileHandle` in `NonBlockingFileIO`'s private thread + /// pool which is separate from any `EventLoop` thread. + /// + /// `chunkHandler` will be called on `eventLoop` for every chunk that was read. Assuming `byteCount` is greater than + /// zero and there are enough bytes available `chunkHandler` will be called `1 + |_ byteCount / chunkSize _|` + /// times, delivering `chunkSize` bytes each time. If less than `byteCount` bytes can be read from `descriptor`, + /// `chunkHandler` will be called less often with the last invocation possibly being of less than `chunkSize` bytes. + /// + /// The allocation and reading of a subsequent chunk will only be attempted when `chunkHandler` succeeds. + /// + /// - note: `readChunked(fileRegion:chunkSize:allocator:eventLoop:chunkHandler:)` should be preferred as it uses + /// `FileRegion` object instead of raw `NIOFileHandle`s. In case you do want to use raw `NIOFileHandle`s, + /// please consider using `readChunked(fileHandle:fromOffset:chunkSize:allocator:eventLoop:chunkHandler:)` + /// because it doesn't use the file descriptor's seek pointer (which may be shared with other file + /// descriptors and even across processes.) + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to read from. + /// - byteCount: The number of bytes to read from `fileHandle`. + /// - chunkSize: The size of the individual chunks to deliver. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the chunks. + /// - eventLoop: The `EventLoop` to call `chunkHandler` on. + /// - chunkHandler: Called for every chunk read. The next chunk will be read upon successful completion of the returned `EventLoopFuture`. If the returned `EventLoopFuture` fails, the overall operation is aborted. + /// - returns: An `EventLoopFuture` which is the result of the overall operation. If either the reading of `fileHandle` or `chunkHandler` fails, the `EventLoopFuture` will fail too. If the reading of `fileHandle` as well as `chunkHandler` always succeeded, the `EventLoopFuture` will succeed too. + public func readChunked(fileHandle: NIOFileHandle, + byteCount: Int, + chunkSize: Int = NonBlockingFileIO.defaultChunkSize, + allocator: ByteBufferAllocator, + eventLoop: EventLoop, chunkHandler: @escaping (ByteBuffer) -> EventLoopFuture) -> EventLoopFuture { + return self.readChunked0(fileHandle: fileHandle, + fromOffset: nil, + byteCount: byteCount, + chunkSize: chunkSize, + allocator: allocator, + eventLoop: eventLoop, + chunkHandler: chunkHandler) + } + + /// Read `byteCount` bytes from offset `fileOffset` in chunks of `chunkSize` bytes from `fileHandle` in `NonBlockingFileIO`'s private thread + /// pool which is separate from any `EventLoop` thread. + /// + /// `chunkHandler` will be called on `eventLoop` for every chunk that was read. Assuming `byteCount` is greater than + /// zero and there are enough bytes available `chunkHandler` will be called `1 + |_ byteCount / chunkSize _|` + /// times, delivering `chunkSize` bytes each time. If less than `byteCount` bytes can be read from `descriptor`, + /// `chunkHandler` will be called less often with the last invocation possibly being of less than `chunkSize` bytes. + /// + /// The allocation and reading of a subsequent chunk will only be attempted when `chunkHandler` succeeds. + /// + /// This method will not use the file descriptor's seek pointer which means there is no danger of reading from the + /// same `NIOFileHandle` in multiple threads. + /// + /// - note: `readChunked(fileRegion:chunkSize:allocator:eventLoop:chunkHandler:)` should be preferred as it uses + /// `FileRegion` object instead of raw `NIOFileHandle`s. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to read from. + /// - byteCount: The number of bytes to read from `fileHandle`. + /// - chunkSize: The size of the individual chunks to deliver. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the chunks. + /// - eventLoop: The `EventLoop` to call `chunkHandler` on. + /// - chunkHandler: Called for every chunk read. The next chunk will be read upon successful completion of the returned `EventLoopFuture`. If the returned `EventLoopFuture` fails, the overall operation is aborted. + /// - returns: An `EventLoopFuture` which is the result of the overall operation. If either the reading of `fileHandle` or `chunkHandler` fails, the `EventLoopFuture` will fail too. If the reading of `fileHandle` as well as `chunkHandler` always succeeded, the `EventLoopFuture` will succeed too. + public func readChunked(fileHandle: NIOFileHandle, + fromOffset fileOffset: Int64, + byteCount: Int, + chunkSize: Int = NonBlockingFileIO.defaultChunkSize, + allocator: ByteBufferAllocator, + eventLoop: EventLoop, + chunkHandler: @escaping (ByteBuffer) -> EventLoopFuture) -> EventLoopFuture { + return self.readChunked0(fileHandle: fileHandle, + fromOffset: fileOffset, + byteCount: byteCount, + chunkSize: chunkSize, + allocator: allocator, + eventLoop: eventLoop, + chunkHandler: chunkHandler) + } + + private func readChunked0(fileHandle: NIOFileHandle, + fromOffset: Int64?, + byteCount: Int, + chunkSize: Int, + allocator: ByteBufferAllocator, + eventLoop: EventLoop, chunkHandler: @escaping (ByteBuffer) -> EventLoopFuture) -> EventLoopFuture { + precondition(chunkSize > 0, "chunkSize must be > 0 (is \(chunkSize))") + let remainingReads = 1 + (byteCount / chunkSize) + let lastReadSize = byteCount % chunkSize + + let promise = eventLoop.makePromise(of: Void.self) + + func _read(remainingReads: Int, bytesReadSoFar: Int64) { + if remainingReads > 1 || (remainingReads == 1 && lastReadSize > 0) { + let readSize = remainingReads > 1 ? chunkSize : lastReadSize + assert(readSize > 0) + let readFuture = self.read0(fileHandle: fileHandle, + fromOffset: fromOffset.map { $0 + bytesReadSoFar }, + byteCount: readSize, + allocator: allocator, + eventLoop: eventLoop) + readFuture.whenComplete { (result) in + switch result { + case .success(let buffer): + guard buffer.readableBytes > 0 else { + // EOF, call `chunkHandler` one more time. + let handlerFuture = chunkHandler(buffer) + handlerFuture.cascade(to: promise) + return + } + let bytesRead = Int64(buffer.readableBytes) + chunkHandler(buffer).whenComplete { result in + switch result { + case .success(_): + eventLoop.assertInEventLoop() + _read(remainingReads: remainingReads - 1, + bytesReadSoFar: bytesReadSoFar + bytesRead) + case .failure(let error): + promise.fail(error) + } + } + case .failure(let error): + promise.fail(error) + } + } + } else { + promise.succeed(()) + } + } + _read(remainingReads: remainingReads, bytesReadSoFar: 0) + + return promise.futureResult + } + + /// Read a `FileRegion` in `NonBlockingFileIO`'s private thread pool which is separate from any `EventLoop` thread. + /// + /// The returned `ByteBuffer` will not have less than `fileRegion.readableBytes` unless we hit end-of-file in which + /// case the `ByteBuffer` will contain the bytes available to read. + /// + /// This method will not use the file descriptor's seek pointer which means there is no danger of reading from the + /// same `FileRegion` in multiple threads. + /// + /// - note: Only use this function for small enough `FileRegion`s as it will need to allocate enough memory to hold `fileRegion.readableBytes` bytes. + /// - note: In most cases you should prefer one of the `readChunked` functions. + /// + /// - parameters: + /// - fileRegion: The file region to read. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the returned `ByteBuffer`. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which delivers a `ByteBuffer` if the read was successful or a failure on error. + public func read(fileRegion: FileRegion, allocator: ByteBufferAllocator, eventLoop: EventLoop) -> EventLoopFuture { + let readableBytes = fileRegion.readableBytes + return self.read(fileHandle: fileRegion.fileHandle, + fromOffset: Int64(fileRegion.readerIndex), + byteCount: readableBytes, + allocator: allocator, + eventLoop: eventLoop) + } + + /// Read `byteCount` bytes from `fileHandle` in `NonBlockingFileIO`'s private thread pool which is separate from any `EventLoop` thread. + /// + /// The returned `ByteBuffer` will not have less than `byteCount` bytes unless we hit end-of-file in which + /// case the `ByteBuffer` will contain the bytes available to read. + /// + /// - note: Only use this function for small enough `byteCount`s as it will need to allocate enough memory to hold `byteCount` bytes. + /// - note: `read(fileRegion:allocator:eventLoop:)` should be preferred as it uses `FileRegion` object instead of + /// raw `NIOFileHandle`s. In case you do want to use raw `NIOFileHandle`s, + /// please consider using `read(fileHandle:fromOffset:byteCount:allocator:eventLoop:)` + /// because it doesn't use the file descriptor's seek pointer (which may be shared with other file + /// descriptors and even across processes.) + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to read. + /// - byteCount: The number of bytes to read from `fileHandle`. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the returned `ByteBuffer`. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which delivers a `ByteBuffer` if the read was successful or a failure on error. + public func read(fileHandle: NIOFileHandle, + byteCount: Int, + allocator: ByteBufferAllocator, + eventLoop: EventLoop) -> EventLoopFuture { + return self.read0(fileHandle: fileHandle, + fromOffset: nil, + byteCount: byteCount, + allocator: allocator, + eventLoop: eventLoop) + } + + /// Read `byteCount` bytes starting at `fileOffset` from `fileHandle` in `NonBlockingFileIO`'s private thread pool + /// which is separate from any `EventLoop` thread. + /// + /// The returned `ByteBuffer` will not have less than `byteCount` bytes unless we hit end-of-file in which + /// case the `ByteBuffer` will contain the bytes available to read. + /// + /// This method will not use the file descriptor's seek pointer which means there is no danger of reading from the + /// same `fileHandle` in multiple threads. + /// + /// - note: Only use this function for small enough `byteCount`s as it will need to allocate enough memory to hold `byteCount` bytes. + /// - note: `read(fileRegion:allocator:eventLoop:)` should be preferred as it uses `FileRegion` object instead of raw `NIOFileHandle`s. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to read. + /// - fileOffset: The offset to read from. + /// - byteCount: The number of bytes to read from `fileHandle`. + /// - allocator: A `ByteBufferAllocator` used to allocate space for the returned `ByteBuffer`. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which delivers a `ByteBuffer` if the read was successful or a failure on error. + public func read(fileHandle: NIOFileHandle, + fromOffset fileOffset: Int64, + byteCount: Int, + allocator: ByteBufferAllocator, + eventLoop: EventLoop) -> EventLoopFuture { + return self.read0(fileHandle: fileHandle, + fromOffset: fileOffset, + byteCount: byteCount, + allocator: allocator, + eventLoop: eventLoop) + } + + private func read0(fileHandle: NIOFileHandle, + fromOffset: Int64?, // > 2 GB offset is reasonable on 32-bit systems + byteCount: Int, + allocator: ByteBufferAllocator, + eventLoop: EventLoop) -> EventLoopFuture { + guard byteCount > 0 else { + return eventLoop.makeSucceededFuture(allocator.buffer(capacity: 0)) + } + + var buf = allocator.buffer(capacity: byteCount) + return self.threadPool.runIfActive(eventLoop: eventLoop) { () -> ByteBuffer in + var bytesRead = 0 + while bytesRead < byteCount { + let n = try buf.writeWithUnsafeMutableBytes(minimumWritableBytes: byteCount - bytesRead) { ptr in + let res = try fileHandle.withUnsafeFileDescriptor { descriptor -> IOResult in + if let offset = fromOffset { + return try Posix.pread(descriptor: descriptor, + pointer: ptr.baseAddress!, + size: byteCount - bytesRead, + offset: off_t(offset) + off_t(bytesRead)) + } else { + return try Posix.read(descriptor: descriptor, + pointer: ptr.baseAddress!, + size: byteCount - bytesRead) + } + } + switch res { + case .processed(let n): + assert(n >= 0, "read claims to have read a negative number of bytes \(n)") + return n + case .wouldBlock: + throw Error.descriptorSetToNonBlocking + } + } + if n == 0 { + // EOF + break + } else { + bytesRead += n + } + } + return buf + } + } + + /// Changes the file size of `fileHandle` to `size`. + /// + /// If `size` is smaller than the current file size, the remaining bytes will be truncated and are lost. If `size` + /// is larger than the current file size, the gap will be filled with zero bytes. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to write to. + /// - size: The new file size in bytes to write. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which is fulfilled if the write was successful or fails on error. + public func changeFileSize(fileHandle: NIOFileHandle, + size: Int64, + eventLoop: EventLoop) -> EventLoopFuture<()> { + return self.threadPool.runIfActive(eventLoop: eventLoop) { + try fileHandle.withUnsafeFileDescriptor { descriptor -> Void in + try Posix.ftruncate(descriptor: descriptor, size: off_t(size)) + } + } + } + + /// Returns the length of the file associated with `fileHandle`. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to read from. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which is fulfilled if the write was successful or fails on error. + public func readFileSize(fileHandle: NIOFileHandle, + eventLoop: EventLoop) -> EventLoopFuture { + return self.threadPool.runIfActive(eventLoop: eventLoop) { + return try fileHandle.withUnsafeFileDescriptor { descriptor in + let curr = try Posix.lseek(descriptor: descriptor, offset: 0, whence: SEEK_CUR) + let eof = try Posix.lseek(descriptor: descriptor, offset: 0, whence: SEEK_END) + try Posix.lseek(descriptor: descriptor, offset: curr, whence: SEEK_SET) + return Int64(eof) + } + } + } + + /// Write `buffer` to `fileHandle` in `NonBlockingFileIO`'s private thread pool which is separate from any `EventLoop` thread. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to write to. + /// - buffer: The `ByteBuffer` to write. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which is fulfilled if the write was successful or fails on error. + public func write(fileHandle: NIOFileHandle, + buffer: ByteBuffer, + eventLoop: EventLoop) -> EventLoopFuture<()> { + return self.write0(fileHandle: fileHandle, toOffset: nil, buffer: buffer, eventLoop: eventLoop) + } + + /// Write `buffer` starting from `toOffset` to `fileHandle` in `NonBlockingFileIO`'s private thread pool which is separate from any `EventLoop` thread. + /// + /// - parameters: + /// - fileHandle: The `NIOFileHandle` to write to. + /// - toOffset: The file offset to write to. + /// - buffer: The `ByteBuffer` to write. + /// - eventLoop: The `EventLoop` to create the returned `EventLoopFuture` from. + /// - returns: An `EventLoopFuture` which is fulfilled if the write was successful or fails on error. + public func write(fileHandle: NIOFileHandle, + toOffset: Int64, + buffer: ByteBuffer, + eventLoop: EventLoop) -> EventLoopFuture<()> { + return self.write0(fileHandle: fileHandle, toOffset: toOffset, buffer: buffer, eventLoop: eventLoop) + } + + private func write0(fileHandle: NIOFileHandle, + toOffset: Int64?, + buffer: ByteBuffer, + eventLoop: EventLoop) -> EventLoopFuture<()> { + let byteCount = buffer.readableBytes + + guard byteCount > 0 else { + return eventLoop.makeSucceededFuture(()) + } + + return self.threadPool.runIfActive(eventLoop: eventLoop) { + var buf = buffer + + var offsetAccumulator: Int = 0 + repeat { + let n = try buf.readWithUnsafeReadableBytes { ptr in + precondition(ptr.count == byteCount - offsetAccumulator) + let res: IOResult = try fileHandle.withUnsafeFileDescriptor { descriptor in + if let toOffset = toOffset { + return try Posix.pwrite(descriptor: descriptor, + pointer: ptr.baseAddress!, + size: byteCount - offsetAccumulator, + offset: off_t(toOffset + Int64(offsetAccumulator))) + } else { + return try Posix.write(descriptor: descriptor, + pointer: ptr.baseAddress!, + size: byteCount - offsetAccumulator) + } + } + switch res { + case .processed(let n): + assert(n >= 0, "write claims to have written a negative number of bytes \(n)") + return n + case .wouldBlock: + throw Error.descriptorSetToNonBlocking + } + } + offsetAccumulator += n + } while offsetAccumulator < byteCount + } + } + + /// Open the file at `path` for reading on a private thread pool which is separate from any `EventLoop` thread. + /// + /// This function will return (a future) of the `NIOFileHandle` associated with the file opened and a `FileRegion` + /// comprising of the whole file. The caller must close the returned `NIOFileHandle` when it's no longer needed. + /// + /// - note: The reason this returns the `NIOFileHandle` and the `FileRegion` is that both the opening of a file as well as the querying of its size are blocking. + /// + /// - parameters: + /// - path: The path of the file to be opened for reading. + /// - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire. + /// - returns: An `EventLoopFuture` containing the `NIOFileHandle` and the `FileRegion` comprising the whole file. + public func openFile(path: String, eventLoop: EventLoop) -> EventLoopFuture<(NIOFileHandle, FileRegion)> { + return self.threadPool.runIfActive(eventLoop: eventLoop) { + let fh = try NIOFileHandle(path: path) + do { + let fr = try FileRegion(fileHandle: fh) + return (fh, fr) + } catch { + _ = try? fh.close() + throw error + } + } + } + + /// Open the file at `path` with specified access mode and POSIX flags on a private thread pool which is separate from any `EventLoop` thread. + /// + /// This function will return (a future) of the `NIOFileHandle` associated with the file opened. + /// The caller must close the returned `NIOFileHandle` when it's no longer needed. + /// + /// - parameters: + /// - path: The path of the file to be opened for writing. + /// - mode: File access mode. + /// - flags: Additional POSIX flags. + /// - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire. + /// - returns: An `EventLoopFuture` containing the `NIOFileHandle`. + public func openFile(path: String, mode: NIOFileHandle.Mode, flags: NIOFileHandle.Flags = .default, eventLoop: EventLoop) -> EventLoopFuture { + return self.threadPool.runIfActive(eventLoop: eventLoop) { + return try NIOFileHandle(path: path, mode: mode, flags: flags) + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingDatagramWritesManager.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingDatagramWritesManager.swift new file mode 100644 index 00000000..ed7529ca --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingDatagramWritesManager.swift @@ -0,0 +1,570 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore +import NIOConcurrencyHelpers + +private struct PendingDatagramWrite { + var data: ByteBuffer + var promise: Optional> + let address: SocketAddress + var metadata: AddressedEnvelope.Metadata? + + /// A helper function that copies the underlying sockaddr structure into temporary storage, + /// and then returns the length. + /// + /// This copying is an annoyance, but one way or another this copy will have to happen as + /// we do not want to expose the backing socket address to libc in case it mutates it. Because + /// we are using a box to store the underlying sockaddr, if libc ever did mess with that data + /// it will screw any other values pointing to that box. That would be a pretty bad scene. And + /// in most cases we're not copying large values here: only for UDS does this become a problem. + func copySocketAddress(_ target: UnsafeMutablePointer) -> socklen_t { + let erased = UnsafeMutableRawPointer(target) + + switch address { + case .v4(let innerAddress): + erased.storeBytes(of: innerAddress.address, as: sockaddr_in.self) + return socklen_t(MemoryLayout.size(ofValue: innerAddress.address)) + case .v6(let innerAddress): + erased.storeBytes(of: innerAddress.address, as: sockaddr_in6.self) + return socklen_t(MemoryLayout.size(ofValue: innerAddress.address)) + case .unixDomainSocket: + fatalError("UDS with datagrams is currently not supported") + } + } +} + +fileprivate extension Error { + /// Returns whether the error is "recoverable" from the perspective of datagram sending. + /// + /// - returns: `true` if the error is recoverable, `false` otherwise. + var isRecoverable: Bool { + switch self { + case let e as IOError where e.errnoCode == EMSGSIZE, + let e as IOError where e.errnoCode == EHOSTUNREACH: + return true + default: + return false + } + } +} + +/// Does the setup required to trigger a `sendmmsg`. +private func doPendingDatagramWriteVectorOperation(pending: PendingDatagramWritesState, + iovecs: UnsafeMutableBufferPointer, + msgs: UnsafeMutableBufferPointer, + addresses: UnsafeMutableBufferPointer, + storageRefs: UnsafeMutableBufferPointer>, + controlMessageStorage: UnsafeControlMessageStorage, + _ body: (UnsafeMutableBufferPointer) throws -> IOResult) throws -> IOResult { + assert(msgs.count >= Socket.writevLimitIOVectors, "Insufficiently sized buffer for a maximal sendmmsg") + assert(controlMessageStorage.count >= Socket.writevLimitIOVectors, + "Insufficiently sized control message storage for a maximal sendmmsg") + + // the numbers of storage refs that we need to decrease later. + var c = 0 + var toWrite: Int = 0 + + for p in pending.flushedWrites { + // Must not write more than Int32.max in one go. + // TODO(cory): I can't see this limit documented in a man page anywhere, but it seems + // plausible given that a similar limit exists for TCP. For now we assume it's present + // in UDP until I can do some research to validate the existence of this limit. + guard (Socket.writevLimitBytes - toWrite >= p.data.readableBytes) else { + if c == 0 { + // The first buffer is larger than the writev limit. Let's throw, and fall back to linear processing. + throw IOError(errnoCode: EMSGSIZE, reason: "synthetic error for overlarge write") + } else { + break + } + } + + // Must not write more than writevLimitIOVectors in one go + guard c < Socket.writevLimitIOVectors else { + break + } + + let toWriteForThisBuffer = p.data.readableBytes + toWrite += numericCast(toWriteForThisBuffer) + + p.data.withUnsafeReadableBytesWithStorageManagement { ptr, storageRef in + storageRefs[c] = storageRef.retain() + let addressLen = p.copySocketAddress(addresses.baseAddress! + c) + iovecs[c] = iovec(iov_base: UnsafeMutableRawPointer(mutating: ptr.baseAddress!), iov_len: numericCast(toWriteForThisBuffer)) + + var controlBytes = UnsafeOutboundControlBytes(controlBytes: controlMessageStorage[c]) + controlBytes.appendExplicitCongestionState(metadata: p.metadata, protocolFamily: p.address.protocol) + let controlMessageBytePointer = controlBytes.validControlBytes + + let msg = msghdr(msg_name: addresses.baseAddress! + c, + msg_namelen: addressLen, + msg_iov: iovecs.baseAddress! + c, + msg_iovlen: 1, + msg_control: controlMessageBytePointer.baseAddress, + msg_controllen: .init(controlMessageBytePointer.count), + msg_flags: 0) + msgs[c] = MMsgHdr(msg_hdr: msg, msg_len: CUnsignedInt(toWriteForThisBuffer)) + } + c += 1 + } + defer { + for i in 0.., Error?) + + private var pendingWrites = MarkedCircularBuffer(initialCapacity: 16) + private var chunks: Int = 0 + public private(set) var bytes: Int64 = 0 + + public var nextWrite: PendingDatagramWrite? { + return self.pendingWrites.first + } + + /// Subtract `bytes` from the number of outstanding bytes to write. + private mutating func subtractOutstanding(bytes: Int) { + assert(self.bytes >= bytes, "allegedly written more bytes (\(bytes)) than outstanding (\(self.bytes))") + self.bytes -= numericCast(bytes) + } + + /// Indicates that the first outstanding write was written. + /// + /// - returns: The promise that the caller must fire, along with an error to fire it with if it needs one. + private mutating func wroteFirst(error: Error? = nil) -> DatagramWritePromiseFiller? { + let first = self.pendingWrites.removeFirst() + self.chunks -= 1 + self.subtractOutstanding(bytes: first.data.readableBytes) + if let promise = first.promise { + return (promise, error) + } + return nil + } + + /// Initialise a new, empty `PendingWritesState`. + public init() { } + + /// Check if there are no outstanding writes. + public var isEmpty: Bool { + if self.pendingWrites.isEmpty { + assert(self.chunks == 0) + assert(self.bytes == 0) + assert(!self.pendingWrites.hasMark) + return true + } else { + assert(self.chunks > 0 && self.bytes >= 0) + return false + } + } + + /// Add a new write and optionally the corresponding promise to the list of outstanding writes. + public mutating func append(_ chunk: PendingDatagramWrite) { + self.pendingWrites.append(chunk) + self.chunks += 1 + self.bytes += numericCast(chunk.data.readableBytes) + } + + /// Mark the flush checkpoint. + /// + /// All writes before this checkpoint will eventually be written to the socket. + public mutating func markFlushCheckpoint() { + self.pendingWrites.mark() + } + + /// Indicate that a write has happened, this may be a write of multiple outstanding writes (using for example `sendmmsg`). + /// + /// - warning: The closure will simply fulfill all the promises in order. If one of those promises does for example close the `Channel` we might see subsequent writes fail out of order. Example: Imagine the user issues three writes: `A`, `B` and `C`. Imagine that `A` and `B` both get successfully written in one write operation but the user closes the `Channel` in `A`'s callback. Then overall the promises will be fulfilled in this order: 1) `A`: success 2) `C`: error 3) `B`: success. Note how `B` and `C` get fulfilled out of order. + /// + /// - parameters: + /// - data: The result of the write operation: namely, for each datagram we attempted to write, the number of bytes we wrote. + /// - messages: The vector messages written, if any. + /// - returns: A promise and the error that should be sent to it, if any, and a `WriteResult` which indicates if we could write everything or not. + public mutating func didWrite(_ data: IOResult, messages: UnsafeMutableBufferPointer?) -> (DatagramWritePromiseFiller?, OneWriteOperationResult) { + switch data { + case .processed(let written): + if let messages = messages { + return didVectorWrite(written: written, messages: messages) + } else { + return didScalarWrite(written: written) + } + case .wouldBlock: + return (nil, .wouldBlock) + } + } + + public mutating func recoverableError(_ error: Error) -> (DatagramWritePromiseFiller?, OneWriteOperationResult) { + // When we've hit an error we treat it like fully writing the first datagram. We aren't going to try to + // send it again. + let promiseFiller = self.wroteFirst(error: error) + let result: OneWriteOperationResult = self.pendingWrites.hasMark ? .writtenPartially : .writtenCompletely + + return (promiseFiller, result) + } + + /// Indicates that a vector write succeeded. + /// + /// - parameters: + /// - written: The number of messages successfully written. + /// - messages: The list of message objects. + /// - returns: A closure that the caller _needs_ to run which will fulfill the promises of the writes, and a `WriteResult` that indicates if we could write + /// everything or not. + private mutating func didVectorWrite(written: Int, messages: UnsafeMutableBufferPointer) -> (DatagramWritePromiseFiller?, OneWriteOperationResult) { + var fillers: [DatagramWritePromiseFiller] = [] + fillers.reserveCapacity(written) + + // This was a vector write. We wrote `written` number of messages. + let writes = messages[messages.startIndex...messages.index(messages.startIndex, offsetBy: written - 1)] + var promiseFiller: DatagramWritePromiseFiller? + + for write in writes { + let written = write.msg_len + let thisWriteFiller = didScalarWrite(written: Int(written)).0 + assert(thisWriteFiller?.1 == nil, "didVectorWrite called with errors on single writes!") + + switch (promiseFiller, thisWriteFiller) { + case (.some(let all), .some(let this)): + all.0.futureResult.cascade(to: this.0) + case (.none, .some(let this)): + promiseFiller = this + case (.some, .none), + (.none, .none): + break + } + } + + // If we no longer have a mark, we wrote everything. + let result: OneWriteOperationResult = self.pendingWrites.hasMark ? .writtenPartially : .writtenCompletely + return (promiseFiller, result) + } + + /// Indicates that a scalar write succeeded. + /// + /// - parameters: + /// - written: The number of bytes successfully written. + /// - returns: All the promises that must be fired, and a `WriteResult` that indicates if we could write + /// everything or not. + private mutating func didScalarWrite(written: Int) -> (DatagramWritePromiseFiller?, OneWriteOperationResult) { + precondition(written <= self.pendingWrites.first!.data.readableBytes, + "Appeared to write more bytes (\(written)) than the datagram contained (\(self.pendingWrites.first!.data.readableBytes))") + let writeFiller = self.wroteFirst() + // If we no longer have a mark, we wrote everything. + let result: OneWriteOperationResult = self.pendingWrites.hasMark ? .writtenPartially : .writtenCompletely + return (writeFiller, result) + } + + /// Is there a pending flush? + public var isFlushPending: Bool { + return self.pendingWrites.hasMark + } + + /// Fail all the outstanding writes. + /// + /// - warning: See the warning for `didWrite`. + /// + /// - returns: Nothing + public mutating func failAll(error: Error) { + var promises: [EventLoopPromise] = [] + promises.reserveCapacity(self.pendingWrites.count) + + while !self.pendingWrites.isEmpty { + let w = self.pendingWrites.removeFirst() + self.chunks -= 1 + self.bytes -= numericCast(w.data.readableBytes) + w.promise.map { promises.append($0) } + } + + promises.forEach { $0.fail(error) } + } + + /// Returns the best mechanism to write pending data at the current point in time. + var currentBestWriteMechanism: WriteMechanism { + switch self.pendingWrites.markedElementIndex { + case .some(let e) where self.pendingWrites.distance(from: self.pendingWrites.startIndex, to: e) > 0: + return .vectorBufferWrite + case .some(let e): + // The compiler can't prove this, but it must be so. + assert(self.pendingWrites.distance(from: e, to: self.pendingWrites.startIndex) == 0) + return .scalarBufferWrite + default: + return .nothingToBeWritten + } + } +} + +// This extension contains a lazy sequence that makes other parts of the code work better. +extension PendingDatagramWritesState { + struct FlushedDatagramWriteSequence: Sequence, IteratorProtocol { + private let pendingWrites: PendingDatagramWritesState + private var index: CircularBuffer.Index + private let markedIndex: CircularBuffer.Index? + + init(_ pendingWrites: PendingDatagramWritesState) { + self.pendingWrites = pendingWrites + self.index = pendingWrites.pendingWrites.startIndex + self.markedIndex = pendingWrites.pendingWrites.markedElementIndex + } + + mutating func next() -> PendingDatagramWrite? { + while let markedIndex = self.markedIndex, self.pendingWrites.pendingWrites.distance(from: self.index, + to: markedIndex) >= 0 { + let element = self.pendingWrites.pendingWrites[index] + index = self.pendingWrites.pendingWrites.index(after: index) + return element + } + + return nil + } + } + + var flushedWrites: FlushedDatagramWriteSequence { + return FlushedDatagramWriteSequence(self) + } +} + +/// This class manages the writing of pending writes to datagram sockets. The state is held in a `PendingWritesState` +/// value. The most important purpose of this object is to call `sendto` or `sendmmsg` depending on the writes held and +/// the availability of the functions. +final class PendingDatagramWritesManager: PendingWritesManager { + /// Storage for mmsghdr structures. Only present on Linux because Darwin does not support + /// gathering datagram writes. + private var msgs: UnsafeMutableBufferPointer + + /// Storage for the references to the buffers used when we perform gathering writes. Only present + /// on Linux because Darwin does not support gathering datagram writes. + private var storageRefs: UnsafeMutableBufferPointer> + + /// Storage for iovec structures. Only present on Linux because this is only needed when we call + /// sendmmsg: sendto doesn't require any iovecs. + private var iovecs: UnsafeMutableBufferPointer + + /// Storage for sockaddr structures. Only present on Linux because Darwin does not support gathering + /// writes. + private var addresses: UnsafeMutableBufferPointer + + private var controlMessageStorage: UnsafeControlMessageStorage + + private var state = PendingDatagramWritesState() + + internal var waterMark: ChannelOptions.Types.WriteBufferWaterMark = ChannelOptions.Types.WriteBufferWaterMark(low: 32 * 1024, high: 64 * 1024) + internal let channelWritabilityFlag: NIOAtomic = .makeAtomic(value: true) + internal var publishedWritability = true + internal var writeSpinCount: UInt = 16 + private(set) var isOpen = true + + /// Initialize with a pre-allocated array of message headers and storage references. We pass in these pre-allocated + /// objects to save allocations. They can be safely be re-used for all `Channel`s on a given `EventLoop` as an + /// `EventLoop` always runs on one and the same thread. That means that there can't be any writes of more than + /// one `Channel` on the same `EventLoop` at the same time. + /// + /// - parameters: + /// - msgs: A pre-allocated array of `MMsgHdr` elements + /// - iovecs: A pre-allocated array of `IOVector` elements + /// - addresses: A pre-allocated array of `sockaddr_storage` elements + /// - storageRefs: A pre-allocated array of storage management tokens used to keep storage elements alive during a vector write operation + /// - controlMessageStorage: Pre-allocated memory for storing cmsghdr data during a vector write operation. + init(msgs: UnsafeMutableBufferPointer, + iovecs: UnsafeMutableBufferPointer, + addresses: UnsafeMutableBufferPointer, + storageRefs: UnsafeMutableBufferPointer>, + controlMessageStorage: UnsafeControlMessageStorage) { + self.msgs = msgs + self.iovecs = iovecs + self.addresses = addresses + self.storageRefs = storageRefs + self.controlMessageStorage = controlMessageStorage + } + + /// Mark the flush checkpoint. + func markFlushCheckpoint() { + self.state.markFlushCheckpoint() + } + + /// Is there a flush pending? + var isFlushPending: Bool { + return self.state.isFlushPending + } + + /// Are there any outstanding writes currently? + var isEmpty: Bool { + return self.state.isEmpty + } + + /// Add a pending write. + /// + /// - parameters: + /// - envelope: The `AddressedEnvelope` to write. + /// - promise: Optionally an `EventLoopPromise` that will get the write operation's result + /// - result: If the `Channel` is still writable after adding the write of `data`. + func add(envelope: AddressedEnvelope, promise: EventLoopPromise?) -> Bool { + assert(self.isOpen) + self.state.append(.init(data: envelope.data, + promise: promise, + address: envelope.remoteAddress, + metadata: envelope.metadata)) + + if self.state.bytes > waterMark.high && channelWritabilityFlag.compareAndExchange(expected: true, desired: false) { + // Returns false to signal the Channel became non-writable and we need to notify the user. + self.publishedWritability = false + return false + } + return true + } + + /// Returns the best mechanism to write pending data at the current point in time. + var currentBestWriteMechanism: WriteMechanism { + return self.state.currentBestWriteMechanism + } + + /// Triggers the appropriate write operation. This is a fancy way of saying trigger either `sendto` or `sendmmsg`. + /// On platforms that do not support a gathering write operation, + /// + /// - parameters: + /// - scalarWriteOperation: An operation that writes a single, contiguous array of bytes (usually `sendto`). + /// - vectorWriteOperation: An operation that writes multiple contiguous arrays of bytes (usually `sendmmsg`). + /// - returns: The `WriteResult` and whether the `Channel` is now writable. + func triggerAppropriateWriteOperations(scalarWriteOperation: (UnsafeRawBufferPointer, UnsafePointer, socklen_t, AddressedEnvelope.Metadata?) throws -> IOResult, + vectorWriteOperation: (UnsafeMutableBufferPointer) throws -> IOResult) throws -> OverallWriteResult { + return try self.triggerWriteOperations { writeMechanism in + switch writeMechanism { + case .scalarBufferWrite: + return try triggerScalarBufferWrite(scalarWriteOperation: { try scalarWriteOperation($0, $1, $2, $3) }) + case .vectorBufferWrite: + do { + return try triggerVectorBufferWrite(vectorWriteOperation: { try vectorWriteOperation($0) }) + } catch { + // If the error we just hit is recoverable, we fall back to single write mode to + // isolate exactly which write triggered the problem. + guard error.isRecoverable else { + throw error + } + + return try triggerScalarBufferWrite(scalarWriteOperation: { try scalarWriteOperation($0, $1, $2, $3) }) + } + case .scalarFileWrite: + preconditionFailure("PendingDatagramWritesManager was handed a file write") + case .nothingToBeWritten: + assertionFailure("called \(#function) with nothing available to be written") + return OneWriteOperationResult.writtenCompletely + } + } + } + + /// To be called after a write operation (usually selected and run by `triggerAppropriateWriteOperation`) has + /// completed. + /// + /// - parameters: + /// - data: The result of the write operation. + private func didWrite(_ data: IOResult, messages: UnsafeMutableBufferPointer?) -> OneWriteOperationResult { + let (promise, result) = self.state.didWrite(data, messages: messages) + + if self.state.bytes < waterMark.low { + channelWritabilityFlag.store(true) + } + + self.fulfillPromise(promise) + return result + } + + /// Called after a scalar write operation has hit an error. Attempts to map some tolerable datagram errors to + /// useful errors and fail the individual write, rather than fail the entire connection. If the error cannot + /// be tolerated by a datagram application, will rethrow the error. + /// + /// - parameters: + /// - error: The error we hit. + /// - returns: A `WriteResult` indicating whether the writes should continue. + /// - throws: Any error that cannot be ignored by a datagram write. + private func handleError(_ error: Error) throws -> OneWriteOperationResult { + switch error { + case let e as IOError where e.errnoCode == EMSGSIZE: + let (promise, result) = self.state.recoverableError(ChannelError.writeMessageTooLarge) + self.fulfillPromise(promise) + return result + case let e as IOError where e.errnoCode == EHOSTUNREACH: + let (promise, result) = self.state.recoverableError(ChannelError.writeHostUnreachable) + self.fulfillPromise(promise) + return result + default: + throw error + } + } + + /// Trigger a write of a single object where an object can either be a contiguous array of bytes or a region of a file. + /// + /// - parameters: + /// - scalarWriteOperation: An operation that writes a single, contiguous array of bytes (usually `sendto`). + private func triggerScalarBufferWrite(scalarWriteOperation: (UnsafeRawBufferPointer, UnsafePointer, socklen_t, AddressedEnvelope.Metadata?) throws -> IOResult) rethrows -> OneWriteOperationResult { + assert(self.state.isFlushPending && self.isOpen && !self.state.isEmpty, + "illegal state for scalar datagram write operation: flushPending: \(self.state.isFlushPending), isOpen: \(self.isOpen), empty: \(self.state.isEmpty)") + let pending = self.state.nextWrite! + do { + let writeResult = try pending.address.withSockAddr { (addrPtr, addrSize) in + try pending.data.withUnsafeReadableBytes { + try scalarWriteOperation($0, addrPtr, socklen_t(addrSize), pending.metadata) + } + } + return self.didWrite(writeResult, messages: nil) + } catch { + return try self.handleError(error) + } + } + + /// Trigger a vector write operation. In other words: Write multiple contiguous arrays of bytes. + /// + /// - parameters: + /// - vectorWriteOperation: The vector write operation to use. Usually `sendmmsg`. + private func triggerVectorBufferWrite(vectorWriteOperation: (UnsafeMutableBufferPointer) throws -> IOResult) throws -> OneWriteOperationResult { + assert(self.state.isFlushPending && self.isOpen && !self.state.isEmpty, + "illegal state for vector datagram write operation: flushPending: \(self.state.isFlushPending), isOpen: \(self.isOpen), empty: \(self.state.isEmpty)") + return self.didWrite(try doPendingDatagramWriteVectorOperation(pending: self.state, + iovecs: self.iovecs, + msgs: self.msgs, + addresses: self.addresses, + storageRefs: self.storageRefs, + controlMessageStorage: self.controlMessageStorage, + { try vectorWriteOperation($0) }), + messages: self.msgs) + } + + private func fulfillPromise(_ promise: PendingDatagramWritesState.DatagramWritePromiseFiller?) { + if let promise = promise, let error = promise.1 { + promise.0.fail(error) + } else if let promise = promise { + promise.0.succeed(()) + } + } + + /// Fail all the outstanding writes. This is useful if for example the `Channel` is closed. + func failAll(error: Error, close: Bool) { + if close { + assert(self.isOpen) + self.isOpen = false + } + + self.state.failAll(error: error) + + assert(self.state.isEmpty) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingWritesManager.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingWritesManager.swift new file mode 100644 index 00000000..9cb3812d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PendingWritesManager.swift @@ -0,0 +1,519 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore +import NIOConcurrencyHelpers + +private struct PendingStreamWrite { + var data: IOData + var promise: Optional> +} + +/// Does the setup required to issue a writev. +/// +/// - parameters: +/// - pending: The currently pending writes. +/// - iovecs: Pre-allocated storage (per `EventLoop`) for `iovecs`. +/// - storageRefs: Pre-allocated storage references (per `EventLoop`) to manage the lifetime of the buffers to be passed to `writev`. +/// - body: The function that actually does the vector write (usually `writev`). +/// - returns: A tuple of the number of items attempted to write and the result of the write operation. +private func doPendingWriteVectorOperation(pending: PendingStreamWritesState, + iovecs: UnsafeMutableBufferPointer, + storageRefs: UnsafeMutableBufferPointer>, + _ body: (UnsafeBufferPointer) throws -> IOResult) throws -> (itemCount: Int, writeResult: IOResult) { + assert(iovecs.count >= Socket.writevLimitIOVectors, "Insufficiently sized buffer for a maximal writev") + + // Clamp the number of writes we're willing to issue to the limit for writev. + let count = min(pending.flushedChunks, Socket.writevLimitIOVectors) + + // the numbers of storage refs that we need to decrease later. + var numberOfUsedStorageSlots = 0 + var toWrite: Int = 0 + + loop: for i in 0..= buffer.readableBytes) else { + break loop + } + let toWriteForThisBuffer = min(Socket.writevLimitBytes, buffer.readableBytes) + toWrite += numericCast(toWriteForThisBuffer) + + buffer.withUnsafeReadableBytesWithStorageManagement { ptr, storageRef in + storageRefs[i] = storageRef.retain() + iovecs[i] = iovec(iov_base: UnsafeMutableRawPointer(mutating: ptr.baseAddress!), iov_len: numericCast(toWriteForThisBuffer)) + } + numberOfUsedStorageSlots += 1 + case .fileRegion: + assert(numberOfUsedStorageSlots != 0, "first item in doPendingWriteVectorOperation was a FileRegion") + // We found a FileRegion so stop collecting + break loop + } + } + defer { + for i in 0..(initialCapacity: 16) + public private(set) var bytes: Int64 = 0 + + public var flushedChunks: Int { + return self.pendingWrites.markedElementIndex.map { + self.pendingWrites.distance(from: self.pendingWrites.startIndex, to: $0) + 1 + } ?? 0 + } + + /// Subtract `bytes` from the number of outstanding bytes to write. + private mutating func subtractOutstanding(bytes: Int) { + assert(self.bytes >= bytes, "allegedly written more bytes (\(bytes)) than outstanding (\(self.bytes))") + self.bytes -= numericCast(bytes) + } + + /// Indicates that the first outstanding write was written in its entirety. + /// + /// - returns: The `EventLoopPromise` of the write or `nil` if none was provided. The promise needs to be fulfilled by the caller. + /// + private mutating func fullyWrittenFirst() -> EventLoopPromise? { + let first = self.pendingWrites.removeFirst() + self.subtractOutstanding(bytes: first.data.readableBytes) + return first.promise + } + + /// Indicates that the first outstanding object has been partially written. + /// + /// - parameters: + /// - bytes: How many bytes of the item were written. + private mutating func partiallyWrittenFirst(bytes: Int) { + self.pendingWrites[self.pendingWrites.startIndex].data.moveReaderIndex(forwardBy: bytes) + self.subtractOutstanding(bytes: bytes) + } + + /// Initialise a new, empty `PendingWritesState`. + public init() { } + + /// Check if there are no outstanding writes. + public var isEmpty: Bool { + if self.pendingWrites.isEmpty { + assert(self.bytes == 0) + assert(!self.pendingWrites.hasMark) + return true + } else { + assert(self.bytes >= 0) + return false + } + } + + /// Add a new write and optionally the corresponding promise to the list of outstanding writes. + public mutating func append(_ chunk: PendingStreamWrite) { + self.pendingWrites.append(chunk) + switch chunk.data { + case .byteBuffer(let buffer): + self.bytes += numericCast(buffer.readableBytes) + case .fileRegion(let fileRegion): + self.bytes += numericCast(fileRegion.readableBytes) + } + } + + /// Get the outstanding write at `index`. + public subscript(index: Int) -> PendingStreamWrite { + return self.pendingWrites[self.pendingWrites.index(self.pendingWrites.startIndex, offsetBy: index)] + } + + /// Mark the flush checkpoint. + /// + /// All writes before this checkpoint will eventually be written to the socket. + public mutating func markFlushCheckpoint() { + self.pendingWrites.mark() + } + + /// Indicate that a write has happened, this may be a write of multiple outstanding writes (using for example `writev`). + /// + /// - warning: The promises will be returned in order. If one of those promises does for example close the `Channel` we might see subsequent writes fail out of order. Example: Imagine the user issues three writes: `A`, `B` and `C`. Imagine that `A` and `B` both get successfully written in one write operation but the user closes the `Channel` in `A`'s callback. Then overall the promises will be fulfilled in this order: 1) `A`: success 2) `C`: error 3) `B`: success. Note how `B` and `C` get fulfilled out of order. + /// + /// - parameters: + /// - writeResult: The result of the write operation. + /// - returns: A tuple of a promise and a `OneWriteResult`. The promise is the first promise that needs to be notified of the write result. + /// This promise will cascade the result to all other promises that need notifying. If no promises need to be notified, will be `nil`. + /// The write result will indicate whether we were able to write everything or not. + public mutating func didWrite(itemCount: Int, result writeResult: IOResult) -> (EventLoopPromise?, OneWriteOperationResult) { + switch writeResult { + case .wouldBlock(0): + return (nil, .wouldBlock) + case .processed(let written), .wouldBlock(let written): + var promise0: EventLoopPromise? + assert(written >= 0, "allegedly written a negative amount of bytes: \(written)") + var unaccountedWrites = written + for _ in 0..= headItemReadableBytes { + unaccountedWrites -= headItemReadableBytes + /* we wrote at least the whole head item, so drop it and succeed the promise */ + if let promise = self.fullyWrittenFirst() { + if let p = promise0 { + p.futureResult.cascade(to: promise) + } else { + promise0 = promise + } + } + } else { + /* we could only write a part of the head item, so don't drop it but remember what we wrote */ + self.partiallyWrittenFirst(bytes: unaccountedWrites) + + // may try again depending on the writeSpinCount + return (promise0, .writtenPartially) + } + } + assert(unaccountedWrites == 0, "after doing all the accounting for the byte written, \(unaccountedWrites) bytes of unaccounted writes remain.") + return (promise0, .writtenCompletely) + } + } + + /// Is there a pending flush? + public var isFlushPending: Bool { + return self.pendingWrites.hasMark + } + + /// Remove all pending writes and return a `EventLoopPromise` which will cascade notifications to all. + /// + /// - warning: See the warning for `didWrite`. + /// + /// - returns: promise that needs to be failed, or `nil` if there were no pending writes. + public mutating func removeAll() -> EventLoopPromise? { + var promise0: EventLoopPromise? + + while !self.pendingWrites.isEmpty { + if let p = self.fullyWrittenFirst() { + if let promise = promise0 { + promise.futureResult.cascade(to: p) + } else { + promise0 = p + } + } + } + return promise0 + } + + /// Returns the best mechanism to write pending data at the current point in time. + var currentBestWriteMechanism: WriteMechanism { + switch self.flushedChunks { + case 0: + return .nothingToBeWritten + case 1: + switch self.pendingWrites.first!.data { + case .byteBuffer: + return .scalarBufferWrite + case .fileRegion: + return .scalarFileWrite + } + default: + let startIndex = self.pendingWrites.startIndex + switch (self.pendingWrites[startIndex].data, + self.pendingWrites[self.pendingWrites.index(after: startIndex)].data) { + case (.byteBuffer, .byteBuffer): + return .vectorBufferWrite + case (.byteBuffer, .fileRegion): + return .scalarBufferWrite + case (.fileRegion, _): + return .scalarFileWrite + } + } + } +} + +/// This class manages the writing of pending writes to stream sockets. The state is held in a `PendingWritesState` +/// value. The most important purpose of this object is to call `write`, `writev` or `sendfile` depending on the +/// currently pending writes. +final class PendingStreamWritesManager: PendingWritesManager { + private var state = PendingStreamWritesState() + private var iovecs: UnsafeMutableBufferPointer + private var storageRefs: UnsafeMutableBufferPointer> + + internal var waterMark: ChannelOptions.Types.WriteBufferWaterMark = ChannelOptions.Types.WriteBufferWaterMark(low: 32 * 1024, high: 64 * 1024) + internal let channelWritabilityFlag: NIOAtomic = .makeAtomic(value: true) + internal var publishedWritability = true + + internal var writeSpinCount: UInt = 16 + + private(set) var isOpen = true + + /// Mark the flush checkpoint. + func markFlushCheckpoint() { + self.state.markFlushCheckpoint() + } + + /// Is there a flush pending? + var isFlushPending: Bool { + return self.state.isFlushPending + } + + /// Are there any outstanding writes currently? + var isEmpty: Bool { + return self.state.isEmpty + } + + /// Add a pending write alongside its promise. + /// + /// - parameters: + /// - data: The `IOData` to write. + /// - promise: Optionally an `EventLoopPromise` that will get the write operation's result + /// - result: If the `Channel` is still writable after adding the write of `data`. + func add(data: IOData, promise: EventLoopPromise?) -> Bool { + assert(self.isOpen) + self.state.append(.init(data: data, promise: promise)) + + if self.state.bytes > waterMark.high && channelWritabilityFlag.compareAndExchange(expected: true, desired: false) { + // Returns false to signal the Channel became non-writable and we need to notify the user. + self.publishedWritability = false + return false + } + return true + } + + /// Returns the best mechanism to write pending data at the current point in time. + var currentBestWriteMechanism: WriteMechanism { + return self.state.currentBestWriteMechanism + } + + /// Triggers the appropriate write operation. This is a fancy way of saying trigger either `write`, `writev` or + /// `sendfile`. + /// + /// - parameters: + /// - scalarBufferWriteOperation: An operation that writes a single, contiguous array of bytes (usually `write`). + /// - vectorBufferWriteOperation: An operation that writes multiple contiguous arrays of bytes (usually `writev`). + /// - scalarFileWriteOperation: An operation that writes a region of a file descriptor (usually `sendfile`). + /// - returns: The `OneWriteOperationResult` and whether the `Channel` is now writable. + func triggerAppropriateWriteOperations(scalarBufferWriteOperation: (UnsafeRawBufferPointer) throws -> IOResult, + vectorBufferWriteOperation: (UnsafeBufferPointer) throws -> IOResult, + scalarFileWriteOperation: (CInt, Int, Int) throws -> IOResult) throws -> OverallWriteResult { + return try self.triggerWriteOperations { writeMechanism in + switch writeMechanism { + case .scalarBufferWrite: + return try triggerScalarBufferWrite({ try scalarBufferWriteOperation($0) }) + case .vectorBufferWrite: + return try triggerVectorBufferWrite({ try vectorBufferWriteOperation($0) }) + case .scalarFileWrite: + return try triggerScalarFileWrite({ try scalarFileWriteOperation($0, $1, $2) }) + case .nothingToBeWritten: + assertionFailure("called \(#function) with nothing available to be written") + return .writtenCompletely + } + } + } + + /// To be called after a write operation (usually selected and run by `triggerAppropriateWriteOperation`) has + /// completed. + /// + /// - parameters: + /// - itemCount: The number of items we tried to write. + /// - result: The result of the write operation. + private func didWrite(itemCount: Int, result: IOResult) -> OneWriteOperationResult { + let (promise, result) = self.state.didWrite(itemCount: itemCount, result: result) + + if self.state.bytes < waterMark.low { + channelWritabilityFlag.store(true) + } + + promise?.succeed(()) + return result + } + + /// Trigger a write of a single `ByteBuffer` (usually using `write(2)`). + /// + /// - parameters: + /// - operation: An operation that writes a single, contiguous array of bytes (usually `write`). + private func triggerScalarBufferWrite(_ operation: (UnsafeRawBufferPointer) throws -> IOResult) throws -> OneWriteOperationResult { + assert(self.state.isFlushPending && !self.state.isEmpty && self.isOpen, + "single write called in illegal state: flush pending: \(self.state.isFlushPending), empty: \(self.state.isEmpty), isOpen: \(self.isOpen)") + + switch self.state[0].data { + case .byteBuffer(let buffer): + return self.didWrite(itemCount: 1, result: try buffer.withUnsafeReadableBytes({ try operation($0) })) + case .fileRegion: + preconditionFailure("called \(#function) but first item to write was a FileRegion") + } + } + + /// Trigger a write of a single `FileRegion` (usually using `sendfile(2)`). + /// + /// - parameters: + /// - operation: An operation that writes a region of a file descriptor. + private func triggerScalarFileWrite(_ operation: (CInt, Int, Int) throws -> IOResult) throws -> OneWriteOperationResult { + assert(self.state.isFlushPending && !self.state.isEmpty && self.isOpen, + "single write called in illegal state: flush pending: \(self.state.isFlushPending), empty: \(self.state.isEmpty), isOpen: \(self.isOpen)") + + switch self.state[0].data { + case .fileRegion(let file): + let readerIndex = file.readerIndex + let endIndex = file.endIndex + return try file.fileHandle.withUnsafeFileDescriptor { fd in + self.didWrite(itemCount: 1, result: try operation(fd, readerIndex, endIndex)) + } + case .byteBuffer: + preconditionFailure("called \(#function) but first item to write was a ByteBuffer") + } + } + + /// Trigger a vector write operation. In other words: Write multiple contiguous arrays of bytes. + /// + /// - parameters: + /// - operation: The vector write operation to use. Usually `writev`. + private func triggerVectorBufferWrite(_ operation: (UnsafeBufferPointer) throws -> IOResult) throws -> OneWriteOperationResult { + assert(self.state.isFlushPending && !self.state.isEmpty && self.isOpen, + "vector write called in illegal state: flush pending: \(self.state.isFlushPending), empty: \(self.state.isEmpty), isOpen: \(self.isOpen)") + let result = try doPendingWriteVectorOperation(pending: self.state, + iovecs: self.iovecs, + storageRefs: self.storageRefs, + { try operation($0) }) + return self.didWrite(itemCount: result.itemCount, result: result.writeResult) + } + + /// Fail all the outstanding writes. This is useful if for example the `Channel` is closed. + func failAll(error: Error, close: Bool) { + if close { + assert(self.isOpen) + self.isOpen = false + } + + self.state.removeAll()?.fail(error) + + assert(self.state.isEmpty) + } + + /// Initialize with a pre-allocated array of IO vectors and storage references. We pass in these pre-allocated + /// objects to save allocations. They can be safely be re-used for all `Channel`s on a given `EventLoop` as an + /// `EventLoop` always runs on one and the same thread. That means that there can't be any writes of more than + /// one `Channel` on the same `EventLoop` at the same time. + /// + /// - parameters: + /// - iovecs: A pre-allocated array of `IOVector` elements + /// - storageRefs: A pre-allocated array of storage management tokens used to keep storage elements alive during a vector write operation + init(iovecs: UnsafeMutableBufferPointer, storageRefs: UnsafeMutableBufferPointer>) { + self.iovecs = iovecs + self.storageRefs = storageRefs + } +} + +internal enum WriteMechanism { + case scalarBufferWrite + case vectorBufferWrite + case scalarFileWrite + case nothingToBeWritten +} + +internal protocol PendingWritesManager: AnyObject { + var isOpen: Bool { get } + var isFlushPending: Bool { get } + var writeSpinCount: UInt { get } + var currentBestWriteMechanism: WriteMechanism { get } + var channelWritabilityFlag: NIOAtomic { get } + + /// Represents the writability state the last time we published a writability change to the `Channel`. + /// This is used in `triggerWriteOperations` to determine whether we need to trigger a writability + /// change. + var publishedWritability: Bool { get set } +} + +extension PendingWritesManager { + // This is called from `Channel` API so must be thread-safe. + var isWritable: Bool { + return self.channelWritabilityFlag.load() + } + + internal func triggerWriteOperations(triggerOneWriteOperation: (WriteMechanism) throws -> OneWriteOperationResult) throws -> OverallWriteResult { + var result = OverallWriteResult(writeResult: .couldNotWriteEverything, writabilityChange: false) + + writeSpinLoop: for _ in 0...self.writeSpinCount { + var oneResult: OneWriteOperationResult + repeat { + guard self.isOpen && self.isFlushPending else { + result.writeResult = .writtenCompletely + break writeSpinLoop + } + + oneResult = try triggerOneWriteOperation(self.currentBestWriteMechanism) + if oneResult == .wouldBlock { + break writeSpinLoop + } + } while oneResult == .writtenCompletely + } + + // Please note that the re-entrancy protection in `flushNow` expects this code to try to write _all_ the data + // that is flushed. If we receive a `flush` whilst processing a previous `flush`, we won't do anything because + // we expect this loop to attempt to attempt all writes, even ones that arrive after this method begins to run. + // + // In other words, don't return `.writtenCompletely` unless you've written everything the PendingWritesManager + // knows to be flushed. + // + // Also, it is very important to not do any outcalls to user code outside of the loop until the `flushNow` + // re-entrancy protection is off again. + + if !self.publishedWritability { + // When we last published a writability change the `Channel` wasn't writable, signal back to the caller + // whether we should emit a writability change. + result.writabilityChange = self.isWritable + self.publishedWritability = result.writabilityChange + } + return result + } +} + +extension PendingStreamWritesManager: CustomStringConvertible { + var description: String { + return "PendingStreamWritesManager { isFlushPending: \(self.isFlushPending), " + + /* */ "writabilityFlag: \(self.channelWritabilityFlag.load())), state: \(self.state) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipeChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipeChannel.swift new file mode 100644 index 00000000..c851953f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipeChannel.swift @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +final class PipeChannel: BaseStreamSocketChannel { + private let pipePair: PipePair + + internal enum Direction { + case input + case output + } + + init(eventLoop: SelectableEventLoop, + inputPipe: NIOFileHandle, + outputPipe: NIOFileHandle) throws { + self.pipePair = try PipePair(inputFD: inputPipe, outputFD: outputPipe) + try super.init(socket: self.pipePair, + parent: nil, + eventLoop: eventLoop, + recvAllocator: AdaptiveRecvByteBufferAllocator()) + } + + func registrationForInput(interested: SelectorEventSet, registrationID: SelectorRegistrationID) -> NIORegistration { + return NIORegistration(channel: .pipeChannel(self, .input), + interested: interested, + registrationID: registrationID) + } + + func registrationForOutput(interested: SelectorEventSet, registrationID: SelectorRegistrationID) -> NIORegistration { + return NIORegistration(channel: .pipeChannel(self, .output), + interested: interested, + registrationID: registrationID) + } + + override func connectSocket(to address: SocketAddress) throws -> Bool { + throw ChannelError.operationUnsupported + } + + override func finishConnectSocket() throws { + throw ChannelError.inappropriateOperationForState + } + + override func register(selector: Selector, interested: SelectorEventSet) throws { + try selector.register(selectable: self.pipePair.inputFD, + interested: interested.intersection([.read, .reset]), + makeRegistration: self.registrationForInput) + try selector.register(selectable: self.pipePair.outputFD, + interested: interested.intersection([.write, .reset]), + makeRegistration: self.registrationForOutput) + + } + + override func deregister(selector: Selector, mode: CloseMode) throws { + if (mode == .all || mode == .input) && self.pipePair.inputFD.isOpen { + try selector.deregister(selectable: self.pipePair.inputFD) + } + if (mode == .all || mode == .output) && self.pipePair.outputFD.isOpen { + try selector.deregister(selectable: self.pipePair.outputFD) + } + } + + override func reregister(selector: Selector, interested: SelectorEventSet) throws { + if self.pipePair.inputFD.isOpen { + try selector.reregister(selectable: self.pipePair.inputFD, + interested: interested.intersection([.read, .reset])) + } + if self.pipePair.outputFD.isOpen { + try selector.reregister(selectable: self.pipePair.outputFD, + interested: interested.intersection([.write, .reset])) + } + } + + override func readEOF() { + super.readEOF() + guard self.pipePair.inputFD.isOpen else { + return + } + try! self.selectableEventLoop.deregister(channel: self, mode: .input) + try! self.pipePair.inputFD.close() + } + + override func writeEOF() { + guard self.pipePair.outputFD.isOpen else { + return + } + try! self.selectableEventLoop.deregister(channel: self, mode: .output) + try! self.pipePair.outputFD.close() + } + + override func shutdownSocket(mode: CloseMode) throws { + switch mode { + case .input: + try! self.selectableEventLoop.deregister(channel: self, mode: .input) + case .output: + try! self.selectableEventLoop.deregister(channel: self, mode: .output) + case .all: + break + } + try super.shutdownSocket(mode: mode) + } +} + +extension PipeChannel: CustomStringConvertible { + var description: String { + return "PipeChannel { \(self.socketDescription), active = \(self.isActive), localAddress = \(self.localAddress.debugDescription), remoteAddress = \(self.remoteAddress.debugDescription) }" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipePair.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipePair.swift new file mode 100644 index 00000000..e24c518b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PipePair.swift @@ -0,0 +1,171 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +struct SelectableFileHandle { + var handle: NIOFileHandle + + var isOpen: Bool { + return handle.isOpen + } + + init(_ handle: NIOFileHandle) { + self.handle = handle + } + + func close() throws { + try handle.close() + } +} + +extension SelectableFileHandle: Selectable { + func withUnsafeHandle(_ body: (CInt) throws -> T) throws -> T { + return try self.handle.withUnsafeFileDescriptor(body) + } +} + +final class PipePair: SocketProtocol { + typealias SelectableType = SelectableFileHandle + + let inputFD: SelectableFileHandle + let outputFD: SelectableFileHandle + + init(inputFD: NIOFileHandle, outputFD: NIOFileHandle) throws { + self.inputFD = SelectableFileHandle(inputFD) + self.outputFD = SelectableFileHandle(outputFD) + try self.ignoreSIGPIPE() + for fileHandle in [inputFD, outputFD] { + try fileHandle.withUnsafeFileDescriptor { + try NIOFileHandle.setNonBlocking(fileDescriptor: $0) + } + } + } + + func ignoreSIGPIPE() throws { + for fileHandle in [self.inputFD, self.outputFD] { + try fileHandle.withUnsafeHandle { + try PipePair.ignoreSIGPIPE(descriptor: $0) + } + } + } + + var description: String { + return "PipePair { in=\(inputFD), out=\(outputFD) }" + } + + func connect(to address: SocketAddress) throws -> Bool { + throw ChannelError.operationUnsupported + } + + func finishConnect() throws { + throw ChannelError.operationUnsupported + } + + func write(pointer: UnsafeRawBufferPointer) throws -> IOResult { + return try self.outputFD.withUnsafeHandle { + try Posix.write(descriptor: $0, pointer: pointer.baseAddress!, size: pointer.count) + } + } + + func writev(iovecs: UnsafeBufferPointer) throws -> IOResult { + return try self.outputFD.withUnsafeHandle { + try Posix.writev(descriptor: $0, iovecs: iovecs) + } + } + + func read(pointer: UnsafeMutableRawBufferPointer) throws -> IOResult { + return try self.inputFD.withUnsafeHandle { + try Posix.read(descriptor: $0, pointer: pointer.baseAddress!, size: pointer.count) + } + } + + func recvmsg(pointer: UnsafeMutableRawBufferPointer, + storage: inout sockaddr_storage, + storageLen: inout socklen_t, + controlBytes: inout UnsafeReceivedControlBytes) throws -> IOResult { + throw ChannelError.operationUnsupported + } + + func sendmsg(pointer: UnsafeRawBufferPointer, + destinationPtr: UnsafePointer, + destinationSize: socklen_t, + controlBytes: UnsafeMutableRawBufferPointer) throws -> IOResult { + throw ChannelError.operationUnsupported + } + + func sendFile(fd: CInt, offset: Int, count: Int) throws -> IOResult { + throw ChannelError.operationUnsupported + } + + func recvmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult { + throw ChannelError.operationUnsupported + } + + func sendmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult { + throw ChannelError.operationUnsupported + } + + func shutdown(how: Shutdown) throws { + switch how { + case .RD: + try self.inputFD.close() + case .WR: + try self.outputFD.close() + case .RDWR: + try self.close() + } + } + + var isOpen: Bool { + return self.inputFD.isOpen || self.outputFD.isOpen + } + + func close() throws { + guard self.inputFD.isOpen || self.outputFD.isOpen else { + throw ChannelError.alreadyClosed + } + let r1 = Result { + if self.inputFD.isOpen { + try self.inputFD.close() + } + } + let r2 = Result { + if self.outputFD.isOpen { + try self.outputFD.close() + } + } + try r1.get() + try r2.get() + } + + func bind(to address: SocketAddress) throws { + throw ChannelError.operationUnsupported + } + + func localAddress() throws -> SocketAddress { + throw ChannelError.operationUnsupported + } + + func remoteAddress() throws -> SocketAddress { + throw ChannelError.operationUnsupported + } + + func setOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: T) throws { + throw ChannelError.operationUnsupported + } + + func getOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) throws -> T { + throw ChannelError.operationUnsupported + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PointerHelpers.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PointerHelpers.swift new file mode 100644 index 00000000..918fbf6d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/PointerHelpers.swift @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: Rebasing shims + +// These methods are shimmed in to NIO until https://github.com/apple/swift/pull/34879 is resolved. +// They address the fact that the current rebasing initializers are surprisingly expensive and do excessive +// checked arithmetic. This expense forces them to often be outlined, reducing the ability to optimise out +// further preconditions and branches. +extension UnsafeRawBufferPointer { + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } + + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } +} + +extension UnsafeMutableRawBufferPointer { + @inlinable + init(fastRebase slice: Slice) { + let base = slice.base.baseAddress?.advanced(by: slice.startIndex) + self.init(start: base, count: slice.endIndex &- slice.startIndex) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Resolver.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Resolver.swift new file mode 100644 index 00000000..9c89c82c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Resolver.swift @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A protocol that covers an object that does DNS lookups. +/// +/// In general the rules for the resolver are relatively broad: there are no specific requirements on how +/// it operates. However, the rest of the code assumes that it obeys RFC 6724, particularly section 6 on +/// ordering returned addresses. That is, the IPv6 and IPv4 responses should be ordered by the destination +/// address ordering rules from that RFC. This specification is widely implemented by getaddrinfo +/// implementations, so any implementation based on getaddrinfo will work just fine. In the future, a custom +/// resolver will need also to implement these sorting rules. +public protocol Resolver { + /// Initiate a DNS A query for a given host. + /// + /// - parameters: + /// - host: The hostname to do an A lookup on. + /// - port: The port we'll be connecting to. + /// - returns: An `EventLoopFuture` that fires with the result of the lookup. + func initiateAQuery(host: String, port: Int) -> EventLoopFuture<[SocketAddress]> + + /// Initiate a DNS AAAA query for a given host. + /// + /// - parameters: + /// - host: The hostname to do an AAAA lookup on. + /// - port: The port we'll be connecting to. + /// - returns: An `EventLoopFuture` that fires with the result of the lookup. + func initiateAAAAQuery(host: String, port: Int) -> EventLoopFuture<[SocketAddress]> + + /// Cancel all outstanding DNS queries. + /// + /// This method is called whenever queries that have not completed no longer have their + /// results needed. The resolver should, if possible, abort any outstanding queries and + /// clean up their state. + /// + /// This method is not guaranteed to terminate the outstanding queries. + func cancelQueries() +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Selectable.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Selectable.swift new file mode 100644 index 00000000..e2427732 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Selectable.swift @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// Represents a selectable resource which can be registered to a `Selector` to +/// be notified once there are some events ready for it. +/// +/// - warning: +/// `Selectable`s are not thread-safe, only to be used on the appropriate +/// `EventLoop`. +protocol Selectable { + func withUnsafeHandle(_: (NIOBSDSocket.Handle) throws -> T) throws -> T +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableChannel.swift new file mode 100644 index 00000000..8ecc84b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableChannel.swift @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + +/// A `SelectableChannel` is a `Channel` that can be used with a `Selector` which notifies a user when certain events +/// are possible. On UNIX a `Selector` is usually an abstraction of `select`, `poll`, `epoll` or `kqueue`. +/// +/// - warning: `SelectableChannel` methods and properties are _not_ thread-safe (unless they also belong to `Channel`). +internal protocol SelectableChannel: Channel { + /// The type of the `Selectable`. A `Selectable` is usually wrapping a file descriptor that can be registered in a + /// `Selector`. + associatedtype SelectableType: Selectable + + var isOpen: Bool { get } + + /// The event(s) of interest. + var interestedEvent: SelectorEventSet { get } + + /// Called when the `SelectableChannel` is ready to be written. + func writable() + + /// Called when the `SelectableChannel` is ready to be read. + func readable() + + /// Called when the read side of the `SelectableChannel` hit EOF. + func readEOF() + + /// Called when the write side of the `SelectableChannel` hit EOF. + func writeEOF() + + /// Called when the `SelectableChannel` was reset (ie. is now unusable) + func reset() + + func register(selector: Selector, interested: SelectorEventSet) throws + + func deregister(selector: Selector, mode: CloseMode) throws + + func reregister(selector: Selector, interested: SelectorEventSet) throws +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableEventLoop.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableEventLoop.swift new file mode 100644 index 00000000..29f6c2c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectableEventLoop.swift @@ -0,0 +1,668 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Dispatch +import NIOCore +import NIOConcurrencyHelpers +import _NIODataStructures + +/// Execute the given closure and ensure we release all auto pools if needed. +@inlinable +internal func withAutoReleasePool(_ execute: () throws -> T) rethrows -> T { +#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + return try autoreleasepool { + try execute() + } +#else + return try execute() +#endif +} + +/// `EventLoop` implementation that uses a `Selector` to get notified once there is more I/O or tasks to process. +/// The whole processing of I/O and tasks is done by a `NIOThread` that is tied to the `SelectableEventLoop`. This `NIOThread` +/// is guaranteed to never change! +@usableFromInline +internal final class SelectableEventLoop: EventLoop { + /// The different state in the lifecycle of an `EventLoop` seen from _outside_ the `EventLoop`. + private enum ExternalState { + /// `EventLoop` is open and so can process more work. + case open + /// `EventLoop` is currently in the process of closing. + case closing + /// `EventLoop` is closed. + case closed + /// `EventLoop` is closed and is currently trying to reclaim resources (such as the EventLoop thread). + case reclaimingResources + /// `EventLoop` is closed and all the resources (such as the EventLoop thread) have been reclaimed. + case resourcesReclaimed + } + + /// The different state in the lifecycle of an `EventLoop` seen from _inside_ the `EventLoop`. + private enum InternalState { + case runningAndAcceptingNewRegistrations + case runningButNotAcceptingNewRegistrations + case noLongerRunning + case exitingThread + } + + /* private but tests */ internal let _selector: NIOPosix.Selector + private let thread: NIOThread + @usableFromInline + // _pendingTaskPop is set to `true` if the event loop is about to pop tasks off the task queue. + // This may only be read/written while holding the _tasksLock. + internal var _pendingTaskPop = false + @usableFromInline + internal var scheduledTaskCounter = NIOAtomic.makeAtomic(value: UInt64(0)) + @usableFromInline + internal var _scheduledTasks = PriorityQueue() + + // We only need the ScheduledTask's task closure. However, an `Array<() -> Void>` allocates + // for every appended closure. https://bugs.swift.org/browse/SR-15872 + private var tasksCopy = ContiguousArray() + @usableFromInline + internal var _succeededVoidFuture: Optional> = nil { + didSet { + self.assertInEventLoop() + } + } + + private let canBeShutdownIndividually: Bool + @usableFromInline + internal let _tasksLock = Lock() + private let _externalStateLock = Lock() + private var externalStateLock: Lock { + // The assert is here to check that we never try to read the external state on the EventLoop unless we're + // shutting down. + assert(!self.inEventLoop || self.internalState != .runningAndAcceptingNewRegistrations, + "lifecycle lock taken whilst up and running and in EventLoop") + return self._externalStateLock + } + private var internalState: InternalState = .runningAndAcceptingNewRegistrations // protected by the EventLoop thread + private var externalState: ExternalState = .open // protected by externalStateLock + + private let _iovecs: UnsafeMutablePointer + private let _storageRefs: UnsafeMutablePointer> + + let iovecs: UnsafeMutableBufferPointer + let storageRefs: UnsafeMutableBufferPointer> + + // Used for gathering UDP writes. + private let _msgs: UnsafeMutablePointer + private let _addresses: UnsafeMutablePointer + let msgs: UnsafeMutableBufferPointer + let addresses: UnsafeMutableBufferPointer + + // Used for UDP control messages. + private(set) var controlMessageStorage: UnsafeControlMessageStorage + + // The `_parentGroup` will always be set unless this is a thread takeover or we shut down. + @usableFromInline + internal var _parentGroup: Optional + + /// Creates a new `SelectableEventLoop` instance that is tied to the given `pthread_t`. + + private let promiseCreationStoreLock = Lock() + private var _promiseCreationStore: [_NIOEventLoopFutureIdentifier: (file: StaticString, line: UInt)] = [:] + + @usableFromInline + internal func _promiseCreated(futureIdentifier: _NIOEventLoopFutureIdentifier, file: StaticString, line: UInt) { + precondition(_isDebugAssertConfiguration()) + self.promiseCreationStoreLock.withLock { + self._promiseCreationStore[futureIdentifier] = (file: file, line: line) + } + } + + @usableFromInline + internal func _promiseCompleted(futureIdentifier: _NIOEventLoopFutureIdentifier) -> (file: StaticString, line: UInt)? { + precondition(_isDebugAssertConfiguration()) + return self.promiseCreationStoreLock.withLock { + self._promiseCreationStore.removeValue(forKey: futureIdentifier) + } + } + + @usableFromInline + internal func _preconditionSafeToWait(file: StaticString, line: UInt) { + let explainer: () -> String = { """ +BUG DETECTED: wait() must not be called when on an EventLoop. +Calling wait() on any EventLoop can lead to +- deadlocks +- stalling processing of other connections (Channels) that are handled on the EventLoop that wait was called on + +Further information: +- current eventLoop: \(MultiThreadedEventLoopGroup.currentEventLoop.debugDescription) +- event loop associated to future: \(self) +""" + } + precondition(!self.inEventLoop, explainer(), file: file, line: line) + precondition(MultiThreadedEventLoopGroup.currentEventLoop == nil, explainer(), file: file, line: line) + } + + @usableFromInline + internal var _validInternalStateToScheduleTasks: Bool { + switch self.internalState { + case .exitingThread: + return false + case .runningAndAcceptingNewRegistrations, .runningButNotAcceptingNewRegistrations, .noLongerRunning: + return true + } + } + + // access with `externalStateLock` held + private var validExternalStateToScheduleTasks: Bool { + switch self.externalState { + case .open, .closing: + return true + case .closed, .reclaimingResources, .resourcesReclaimed: + return false + } + } + + internal var testsOnly_validExternalStateToScheduleTasks: Bool { + return self.externalStateLock.withLock { + return self.validExternalStateToScheduleTasks + } + } + + internal init(thread: NIOThread, + parentGroup: MultiThreadedEventLoopGroup?, /* nil iff thread take-over */ + selector: NIOPosix.Selector, + canBeShutdownIndividually: Bool) { + self._parentGroup = parentGroup + self._selector = selector + self.thread = thread + self._iovecs = UnsafeMutablePointer.allocate(capacity: Socket.writevLimitIOVectors) + self._storageRefs = UnsafeMutablePointer.allocate(capacity: Socket.writevLimitIOVectors) + self.iovecs = UnsafeMutableBufferPointer(start: self._iovecs, count: Socket.writevLimitIOVectors) + self.storageRefs = UnsafeMutableBufferPointer(start: self._storageRefs, count: Socket.writevLimitIOVectors) + self._msgs = UnsafeMutablePointer.allocate(capacity: Socket.writevLimitIOVectors) + self._addresses = UnsafeMutablePointer.allocate(capacity: Socket.writevLimitIOVectors) + self.msgs = UnsafeMutableBufferPointer(start: _msgs, count: Socket.writevLimitIOVectors) + self.addresses = UnsafeMutableBufferPointer(start: _addresses, count: Socket.writevLimitIOVectors) + self.controlMessageStorage = UnsafeControlMessageStorage.allocate(msghdrCount: Socket.writevLimitIOVectors) + // We will process 4096 tasks per while loop. + self.tasksCopy.reserveCapacity(4096) + self.canBeShutdownIndividually = canBeShutdownIndividually + // note: We are creating a reference cycle here that we'll break when shutting the SelectableEventLoop down. + // note: We have to create the promise and complete it because otherwise we'll hit a loop in `makeSucceededFuture`. This is + // fairly dumb, but it's the only option we have. + let voidPromise = self.makePromise(of: Void.self) + voidPromise.succeed(()) + self._succeededVoidFuture = voidPromise.futureResult + } + + deinit { + assert(self.internalState == .exitingThread, + "illegal internal state on deinit: \(self.internalState)") + assert(self.externalState == .resourcesReclaimed, + "illegal external state on shutdown: \(self.externalState)") + _iovecs.deallocate() + _storageRefs.deallocate() + _msgs.deallocate() + _addresses.deallocate() + self.controlMessageStorage.deallocate() + } + + /// Is this `SelectableEventLoop` still open (ie. not shutting down or shut down) + internal var isOpen: Bool { + self.assertInEventLoop() + switch self.internalState { + case .noLongerRunning, .runningButNotAcceptingNewRegistrations, .exitingThread: + return false + case .runningAndAcceptingNewRegistrations: + return true + } + } + + /// Register the given `SelectableChannel` with this `SelectableEventLoop`. After this point all I/O for the `SelectableChannel` will be processed by this `SelectableEventLoop` until it + /// is deregistered by calling `deregister`. + internal func register(channel: C) throws { + self.assertInEventLoop() + + // Don't allow registration when we're closed. + guard self.isOpen else { + throw EventLoopError.shutdown + } + + try channel.register(selector: self._selector, interested: channel.interestedEvent) + } + + /// Deregister the given `SelectableChannel` from this `SelectableEventLoop`. + internal func deregister(channel: C, mode: CloseMode = .all) throws { + self.assertInEventLoop() + guard self.isOpen else { + // It's possible the EventLoop was closed before we were able to call deregister, so just return in this case as there is no harm. + return + } + + try channel.deregister(selector: self._selector, mode: mode) + } + + /// Register the given `SelectableChannel` with this `SelectableEventLoop`. This should be done whenever `channel.interestedEvents` has changed and it should be taken into account when + /// waiting for new I/O for the given `SelectableChannel`. + internal func reregister(channel: C) throws { + self.assertInEventLoop() + + try channel.reregister(selector: self._selector, interested: channel.interestedEvent) + } + + /// - see: `EventLoop.inEventLoop` + @usableFromInline + internal var inEventLoop: Bool { + return thread.isCurrent + } + + /// - see: `EventLoop.scheduleTask(deadline:_:)` + @inlinable + internal func scheduleTask(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled { + let promise: EventLoopPromise = self.makePromise() + let task = ScheduledTask(id: self.scheduledTaskCounter.add(1), { + do { + promise.succeed(try task()) + } catch let err { + promise.fail(err) + } + }, { error in + promise.fail(error) + }, deadline) + + let taskId = task.id + let scheduled = Scheduled(promise: promise, cancellationTask: { + self._tasksLock.withLockVoid { + self._scheduledTasks.removeFirst(where: { $0.id == taskId }) + } + // We don't need to wake up the selector here, the scheduled task will never be picked up. Waking up the + // selector would mean that we may be able to recalculate the shutdown to a later date. The cost of not + // doing the recalculation is one potentially unnecessary wakeup which is exactly what we're + // saving here. So in the worst case, we didn't do a performance optimisation, in the best case, we saved + // one wakeup. + }) + + do { + try self._schedule0(task) + } catch { + promise.fail(error) + } + + return scheduled + } + + /// - see: `EventLoop.scheduleTask(in:_:)` + @inlinable + internal func scheduleTask(in: TimeAmount, _ task: @escaping () throws -> T) -> Scheduled { + return scheduleTask(deadline: .now() + `in`, task) + } + + // - see: `EventLoop.execute` + @inlinable + internal func execute(_ task: @escaping () -> Void) { + // nothing we can do if we fail enqueuing here. + try? self._schedule0(ScheduledTask(id: self.scheduledTaskCounter.add(1), task, { error in + // do nothing + }, .now())) + } + + /// Add the `ScheduledTask` to be executed. + @usableFromInline + internal func _schedule0(_ task: ScheduledTask) throws { + if self.inEventLoop { + precondition(self._validInternalStateToScheduleTasks, + "BUG IN NIO (please report): EventLoop is shutdown, yet we're on the EventLoop.") + + self._tasksLock.withLockVoid { + self._scheduledTasks.push(task) + } + } else { + let shouldWakeSelector: Bool = self.externalStateLock.withLock { + guard self.validExternalStateToScheduleTasks else { + print("ERROR: Cannot schedule tasks on an EventLoop that has already shut down. " + + "This will be upgraded to a forced crash in future SwiftNIO versions.") + return false + } + + return self._tasksLock.withLock { + self._scheduledTasks.push(task) + + if self._pendingTaskPop == false { + // Our job to wake the selector. + self._pendingTaskPop = true + return true + } else { + // There is already an event-loop-tick scheduled, we don't need to wake the selector. + return false + } + } + } + + // We only need to wake up the selector if we're not in the EventLoop. If we're in the EventLoop already, we're + // either doing IO tasks (which happens before checking the scheduled tasks) or we're running a scheduled task + // already which means that we'll check at least once more if there are other scheduled tasks runnable. While we + // had the task lock we also checked whether the loop was _already_ going to be woken. This saves us a syscall on + // hot loops. + // + // In the future we'll use an MPSC queue here and that will complicate things, so we may get some spurious wakeups, + // but as long as we're using the big dumb lock we can make this optimization safely. + if shouldWakeSelector { + try self._wakeupSelector() + } + } + } + + /// Wake the `Selector` which means `Selector.whenReady(...)` will unblock. + @usableFromInline + internal func _wakeupSelector() throws { + try _selector.wakeup() + } + + /// Handle the given `SelectorEventSet` for the `SelectableChannel`. + internal final func handleEvent(_ ev: SelectorEventSet, channel: C) { + guard channel.isOpen else { + return + } + + // process resets first as they'll just cause the writes to fail anyway. + if ev.contains(.reset) { + channel.reset() + } else { + if ev.contains(.writeEOF) { + channel.writeEOF() + + guard channel.isOpen else { + return + } + } else if ev.contains(.write) { + channel.writable() + + guard channel.isOpen else { + return + } + } + + if ev.contains(.readEOF) { + channel.readEOF() + } else if ev.contains(.read) { + channel.readable() + } + } + } + + private func currentSelectorStrategy(nextReadyTask: ScheduledTask?) -> SelectorStrategy { + guard let sched = nextReadyTask else { + // No tasks to handle so just block. If any tasks were added in the meantime wakeup(...) was called and so this + // will directly unblock. + return .block + } + + let nextReady = sched.readyIn(.now()) + if nextReady <= .nanoseconds(0) { + // Something is ready to be processed just do a non-blocking select of events. + return .now + } else { + return .blockUntilTimeout(nextReady) + } + } + + /// Start processing I/O and tasks for this `SelectableEventLoop`. This method will continue running (and so block) until the `SelectableEventLoop` is closed. + internal func run() throws { + self.preconditionInEventLoop() + defer { + var scheduledTasksCopy = ContiguousArray() + var iterations = 0 + repeat { // We may need to do multiple rounds of this because failing tasks may lead to more work. + scheduledTasksCopy.removeAll(keepingCapacity: true) + + self._tasksLock.withLockVoid { + // In this state we never want the selector to be woken again, so we pretend we're permanently running. + self._pendingTaskPop = true + + // reserve the correct capacity so we don't need to realloc later on. + scheduledTasksCopy.reserveCapacity(self._scheduledTasks.count) + while let sched = self._scheduledTasks.pop() { + scheduledTasksCopy.append(sched) + } + } + + // Fail all the scheduled tasks. + for task in scheduledTasksCopy { + task.fail(EventLoopError.shutdown) + } + iterations += 1 + } while scheduledTasksCopy.count > 0 && iterations < 1000 + precondition(scheduledTasksCopy.count == 0, "EventLoop \(self) didn't quiesce after 1000 ticks.") + + assert(self.internalState == .noLongerRunning, "illegal state: \(self.internalState)") + self.internalState = .exitingThread + } + var nextReadyTask: ScheduledTask? = nil + self._tasksLock.withLock { + if let firstTask = self._scheduledTasks.peek() { + // The reason this is necessary is a very interesting race: + // In theory (and with `makeEventLoopFromCallingThread` even in practise), we could publish an + // `EventLoop` reference _before_ the EL thread has entered the `run` function. + // If that is the case, we need to schedule the first wakeup at the ready time for this task that was + // enqueued really early on, so let's do that :). + nextReadyTask = firstTask + } + } + while self.internalState != .noLongerRunning && self.internalState != .exitingThread { + // Block until there are events to handle or the selector was woken up + /* for macOS: in case any calls we make to Foundation put objects into an autoreleasepool */ + try withAutoReleasePool { + try self._selector.whenReady( + strategy: currentSelectorStrategy(nextReadyTask: nextReadyTask), + onLoopBegin: { self._tasksLock.withLockVoid { self._pendingTaskPop = true } } + ) { ev in + switch ev.registration.channel { + case .serverSocketChannel(let chan): + self.handleEvent(ev.io, channel: chan) + case .socketChannel(let chan): + self.handleEvent(ev.io, channel: chan) + case .datagramChannel(let chan): + self.handleEvent(ev.io, channel: chan) + case .pipeChannel(let chan, let direction): + var ev = ev + if ev.io.contains(.reset) { + // .reset needs special treatment here because we're dealing with two separate pipes instead + // of one socket. So we turn .reset input .readEOF/.writeEOF. + ev.io.subtract([.reset]) + ev.io.formUnion([direction == .input ? .readEOF : .writeEOF]) + } + self.handleEvent(ev.io, channel: chan) + } + } + } + + // We need to ensure we process all tasks, even if a task added another task again + while true { + // TODO: Better locking + self._tasksLock.withLockVoid { + if !self._scheduledTasks.isEmpty { + // We only fetch the time one time as this may be expensive and is generally good enough as if we miss anything we will just do a non-blocking select again anyway. + let now: NIODeadline = .now() + + // Make a copy of the tasks so we can execute these while not holding the lock anymore + while tasksCopy.count < tasksCopy.capacity, let task = self._scheduledTasks.peek() { + if task.readyIn(now) <= .nanoseconds(0) { + self._scheduledTasks.pop() + self.tasksCopy.append(task) + } else { + nextReadyTask = task + break + } + } + } else { + // Reset nextReadyTask to nil which means we will do a blocking select. + nextReadyTask = nil + } + + if self.tasksCopy.isEmpty { + // We will not continue to loop here. We need to be woken if a new task is enqueued. + self._pendingTaskPop = false + } + } + + // all pending tasks are set to occur in the future, so we can stop looping. + if self.tasksCopy.isEmpty { + break + } + + // Execute all the tasks that were submitted + for task in self.tasksCopy { + /* for macOS: in case any calls we make to Foundation put objects into an autoreleasepool */ + withAutoReleasePool { + task.task() + } + } + // Drop everything (but keep the capacity) so we can fill it again on the next iteration. + self.tasksCopy.removeAll(keepingCapacity: true) + } + } + + // This EventLoop was closed so also close the underlying selector. + try self._selector.close() + + // This breaks the retain cycle created in `init`. + self._succeededVoidFuture = nil + } + + internal func initiateClose(queue: DispatchQueue, completionHandler: @escaping (Result) -> Void) { + func doClose() { + self.assertInEventLoop() + self._parentGroup = nil // break the cycle + // There should only ever be one call into this function so we need to be up and running, ... + assert(self.internalState == .runningAndAcceptingNewRegistrations) + self.internalState = .runningButNotAcceptingNewRegistrations + + self.externalStateLock.withLock { + // ... but before this call happened, the lifecycle state should have been changed on some other thread. + assert(self.externalState == .closing) + } + + self._selector.closeGently(eventLoop: self).whenComplete { result in + self.assertInEventLoop() + assert(self.internalState == .runningButNotAcceptingNewRegistrations) + self.internalState = .noLongerRunning + self.execute {} // force a new event loop tick, so the event loop definitely stops looping very soon. + self.externalStateLock.withLock { + assert(self.externalState == .closing) + self.externalState = .closed + } + queue.async { + completionHandler(result) + } + } + } + if self.inEventLoop { + queue.async { + self.initiateClose(queue: queue, completionHandler: completionHandler) + } + } else { + let goAhead = self.externalStateLock.withLock { () -> Bool in + if self.externalState == .open { + self.externalState = .closing + return true + } else { + return false + } + } + guard goAhead else { + queue.async { + completionHandler(Result.failure(EventLoopError.shutdown)) + } + return + } + self.execute { + doClose() + } + } + } + + internal func syncFinaliseClose(joinThread: Bool) { + // This may not be true in the future but today we need to join all ELs that can't be shut down individually. + assert(joinThread != self.canBeShutdownIndividually) + let goAhead = self.externalStateLock.withLock { () -> Bool in + switch self.externalState { + case .closed: + self.externalState = .reclaimingResources + return true + case .resourcesReclaimed, .reclaimingResources: + return false + default: + preconditionFailure("illegal lifecycle state in syncFinaliseClose: \(self.externalState)") + } + } + guard goAhead else { + return + } + if joinThread { + self.thread.join() + } + self.externalStateLock.withLock { + precondition(self.externalState == .reclaimingResources) + self.externalState = .resourcesReclaimed + } + } + + @usableFromInline + func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) { + if self.canBeShutdownIndividually { + self.initiateClose(queue: queue) { result in + self.syncFinaliseClose(joinThread: false) // This thread was taken over by somebody else + switch result { + case .success: + callback(nil) + case .failure(let error): + callback(error) + } + } + } else { + // This function is never called legally because the only possibly owner of an `SelectableEventLoop` is + // `MultiThreadedEventLoopGroup` which calls `initiateClose` followed by `syncFinaliseClose`. + queue.async { + callback(EventLoopError.unsupportedOperation) + } + } + } + + @inlinable + public func makeSucceededVoidFuture() -> EventLoopFuture { + guard self.inEventLoop, let voidFuture = self._succeededVoidFuture else { + // We have to create the promise and complete it because otherwise we'll hit a loop in `makeSucceededFuture`. This is + // fairly dumb, but it's the only option we have. This one can only happen after the loop is shut down, or when calling from off the loop. + let voidPromise = self.makePromise(of: Void.self) + voidPromise.succeed(()) + return voidPromise.futureResult + } + return voidFuture + } + + @inlinable + internal func parentGroupCallableFromThisEventLoopOnly() -> MultiThreadedEventLoopGroup? { + self.assertInEventLoop() + return self._parentGroup + } +} + +extension SelectableEventLoop: CustomStringConvertible, CustomDebugStringConvertible { + @usableFromInline + var description: String { + return "SelectableEventLoop { selector = \(self._selector), thread = \(self.thread) }" + } + + @usableFromInline + var debugDescription: String { + return self._tasksLock.withLock { + return "SelectableEventLoop { selector = \(self._selector), thread = \(self.thread), scheduledTasks = \(self._scheduledTasks.description) }" + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorEpoll.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorEpoll.swift new file mode 100644 index 00000000..a8a9376a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorEpoll.swift @@ -0,0 +1,296 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +#if !SWIFTNIO_USE_IO_URING + +#if os(Linux) || os(Android) + +/// Represents the `epoll` filters/events we might use: +/// +/// - `hangup` corresponds to `EPOLLHUP` +/// - `readHangup` corresponds to `EPOLLRDHUP` +/// - `input` corresponds to `EPOLLIN` +/// - `output` corresponds to `EPOLLOUT` +/// - `error` corresponds to `EPOLLERR` +private struct EpollFilterSet: OptionSet, Equatable { + typealias RawValue = UInt8 + + let rawValue: RawValue + + static let _none = EpollFilterSet([]) + static let hangup = EpollFilterSet(rawValue: 1 << 0) + static let readHangup = EpollFilterSet(rawValue: 1 << 1) + static let input = EpollFilterSet(rawValue: 1 << 2) + static let output = EpollFilterSet(rawValue: 1 << 3) + static let error = EpollFilterSet(rawValue: 1 << 4) + + init(rawValue: RawValue) { + self.rawValue = rawValue + } +} + +extension EpollFilterSet { + /// Convert NIO's `SelectorEventSet` set to a `EpollFilterSet` + init(selectorEventSet: SelectorEventSet) { + var thing: EpollFilterSet = [.error, .hangup] + if selectorEventSet.contains(.read) { + thing.formUnion(.input) + } + if selectorEventSet.contains(.write) { + thing.formUnion(.output) + } + if selectorEventSet.contains(.readEOF) { + thing.formUnion(.readHangup) + } + self = thing + } +} + +extension SelectorEventSet { + var epollEventSet: UInt32 { + assert(self != ._none) + // EPOLLERR | EPOLLHUP is always set unconditionally anyway but it's easier to understand if we explicitly ask. + var filter: UInt32 = Epoll.EPOLLERR | Epoll.EPOLLHUP + let epollFilters = EpollFilterSet(selectorEventSet: self) + if epollFilters.contains(.input) { + filter |= Epoll.EPOLLIN + } + if epollFilters.contains(.output) { + filter |= Epoll.EPOLLOUT + } + if epollFilters.contains(.readHangup) { + filter |= Epoll.EPOLLRDHUP + } + assert(filter & Epoll.EPOLLHUP != 0) // both of these are reported + assert(filter & Epoll.EPOLLERR != 0) // always and can't be masked. + return filter + } + + fileprivate init(epollEvent: Epoll.epoll_event) { + var selectorEventSet: SelectorEventSet = ._none + if epollEvent.events & Epoll.EPOLLIN != 0 { + selectorEventSet.formUnion(.read) + } + if epollEvent.events & Epoll.EPOLLOUT != 0 { + selectorEventSet.formUnion(.write) + } + if epollEvent.events & Epoll.EPOLLRDHUP != 0 { + selectorEventSet.formUnion(.readEOF) + } + if epollEvent.events & Epoll.EPOLLHUP != 0 || epollEvent.events & Epoll.EPOLLERR != 0 { + selectorEventSet.formUnion(.reset) + } + self = selectorEventSet + } +} + +// EPollUserData supports (un)packing into an `UInt64` because epoll has a user info field that we can attach which is +// up to 64 bits wide. We're using all of those 64 bits, 32 for a "registration ID" and 32 for the file descriptor. +@usableFromInline struct EPollUserData { + @usableFromInline var registrationID: SelectorRegistrationID + @usableFromInline var fileDescriptor: CInt + + @inlinable init(registrationID: SelectorRegistrationID, fileDescriptor: CInt) { + assert(MemoryLayout.size == MemoryLayout.size) + self.registrationID = registrationID + self.fileDescriptor = fileDescriptor + } + + @inlinable init(rawValue: UInt64) { + let unpacked = IntegerBitPacking.unpackUInt32CInt(rawValue) + self = .init(registrationID: SelectorRegistrationID(rawValue: unpacked.0), fileDescriptor: unpacked.1) + } +} + +extension UInt64 { + @inlinable + init(_ epollUserData: EPollUserData) { + let fd = epollUserData.fileDescriptor + assert(fd >= 0, "\(fd) is not a valid file descriptor") + self = IntegerBitPacking.packUInt32CInt(epollUserData.registrationID.rawValue, fd) + } +} + +extension Selector: _SelectorBackendProtocol { + func initialiseState0() throws { + self.selectorFD = try Epoll.epoll_create(size: 128) + self.eventFD = try EventFd.eventfd(initval: 0, flags: Int32(EventFd.EFD_CLOEXEC | EventFd.EFD_NONBLOCK)) + self.timerFD = try TimerFd.timerfd_create(clockId: CLOCK_MONOTONIC, flags: Int32(TimerFd.TFD_CLOEXEC | TimerFd.TFD_NONBLOCK)) + + self.lifecycleState = .open + + var ev = Epoll.epoll_event() + ev.events = SelectorEventSet.read.epollEventSet + ev.data.u64 = UInt64(EPollUserData(registrationID: .initialRegistrationID, + fileDescriptor: self.eventFD)) + + try Epoll.epoll_ctl(epfd: self.selectorFD, op: Epoll.EPOLL_CTL_ADD, fd: self.eventFD, event: &ev) + + var timerev = Epoll.epoll_event() + timerev.events = Epoll.EPOLLIN | Epoll.EPOLLERR | Epoll.EPOLLRDHUP + timerev.data.u64 = UInt64(EPollUserData(registrationID: .initialRegistrationID, + fileDescriptor: self.timerFD)) + try Epoll.epoll_ctl(epfd: self.selectorFD, op: Epoll.EPOLL_CTL_ADD, fd: self.timerFD, event: &timerev) + } + + func deinitAssertions0() { + assert(self.eventFD == -1, "self.eventFD == \(self.eventFD) in deinitAssertions0, forgot close?") + assert(self.timerFD == -1, "self.timerFD == \(self.timerFD) in deinitAssertions0, forgot close?") + } + + func register0(selectable: S, + fileDescriptor: CInt, + interested: SelectorEventSet, + registrationID: SelectorRegistrationID) throws { + var ev = Epoll.epoll_event() + ev.events = interested.epollEventSet + ev.data.u64 = UInt64(EPollUserData(registrationID: registrationID, fileDescriptor: fileDescriptor)) + + try Epoll.epoll_ctl(epfd: self.selectorFD, op: Epoll.EPOLL_CTL_ADD, fd: fileDescriptor, event: &ev) + } + + func reregister0(selectable: S, + fileDescriptor: CInt, + oldInterested: SelectorEventSet, + newInterested: SelectorEventSet, + registrationID: SelectorRegistrationID) throws { + var ev = Epoll.epoll_event() + ev.events = newInterested.epollEventSet + ev.data.u64 = UInt64(EPollUserData(registrationID: registrationID, fileDescriptor: fileDescriptor)) + + _ = try Epoll.epoll_ctl(epfd: self.selectorFD, op: Epoll.EPOLL_CTL_MOD, fd: fileDescriptor, event: &ev) + } + + func deregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws { + var ev = Epoll.epoll_event() + _ = try Epoll.epoll_ctl(epfd: self.selectorFD, op: Epoll.EPOLL_CTL_DEL, fd: fileDescriptor, event: &ev) + } + + /// Apply the given `SelectorStrategy` and execute `body` once it's complete (which may produce `SelectorEvent`s to handle). + /// + /// - parameters: + /// - strategy: The `SelectorStrategy` to apply + /// - body: The function to execute for each `SelectorEvent` that was produced. + func whenReady0(strategy: SelectorStrategy, onLoopBegin loopStart: () -> Void, _ body: (SelectorEvent) throws -> Void) throws -> Void { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't call whenReady for selector as it's \(self.lifecycleState).") + } + let ready: Int + + switch strategy { + case .now: + ready = Int(try Epoll.epoll_wait(epfd: self.selectorFD, events: events, maxevents: Int32(eventsCapacity), timeout: 0)) + case .blockUntilTimeout(let timeAmount): + // Only call timerfd_settime if we're not already scheduled one that will cover it. + // This guards against calling timerfd_settime if not needed as this is generally speaking + // expensive. + let next = NIODeadline.now() + timeAmount + if next < self.earliestTimer { + self.earliestTimer = next + + var ts = itimerspec() + ts.it_value = timespec(timeAmount: timeAmount) + try TimerFd.timerfd_settime(fd: self.timerFD, flags: 0, newValue: &ts, oldValue: nil) + } + fallthrough + case .block: + ready = Int(try Epoll.epoll_wait(epfd: self.selectorFD, events: events, maxevents: Int32(eventsCapacity), timeout: -1)) + } + + loopStart() + + for i in 0.. 0 the user might have changed the registrations since then. + assert(i != 0 || selectorEvent.isSubset(of: registration.interested), "selectorEvent: \(selectorEvent), registration: \(registration)") + + // in any case we only want what the user is currently registered for & what we got + selectorEvent = selectorEvent.intersection(registration.interested) + + guard selectorEvent != ._none else { + continue + } + + try body((SelectorEvent(io: selectorEvent, registration: registration))) + } + } + } + growEventArrayIfNeeded(ready: ready) + } + + /// Close the `Selector`. + /// + /// After closing the `Selector` it's no longer possible to use it. + public func close0() throws { + self.externalSelectorFDLock.withLock { + // We try! all of the closes because close can only fail in the following ways: + // - EINTR, which we eat in Posix.close + // - EIO, which can only happen for on-disk files + // - EBADF, which can't happen here because we would crash as EBADF is marked unacceptable + // Therefore, we assert here that close will always succeed and if not, that's a NIO bug we need to know + // about. + + try! Posix.close(descriptor: self.timerFD) + self.timerFD = -1 + + try! Posix.close(descriptor: self.eventFD) + self.eventFD = -1 + + try! Posix.close(descriptor: self.selectorFD) + self.selectorFD = -1 + } + } + + /* attention, this may (will!) be called from outside the event loop, ie. can't access mutable shared state (such as `self.open`) */ + func wakeup0() throws { + assert(NIOThread.current != self.myThread) + try self.externalSelectorFDLock.withLock { + guard self.eventFD >= 0 else { + throw EventLoopError.shutdown + } + _ = try EventFd.eventfd_write(fd: self.eventFD, value: 1) + } + } +} + +#endif + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorGeneric.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorGeneric.swift new file mode 100644 index 00000000..6146efd8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorGeneric.swift @@ -0,0 +1,432 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOConcurrencyHelpers + +internal enum SelectorLifecycleState { + case open + case closing + case closed +} + +extension Optional { + internal func withUnsafeOptionalPointer(_ body: (UnsafePointer?) throws -> T) rethrows -> T { + if var this = self { + return try withUnsafePointer(to: &this) { x in + try body(x) + } + } else { + return try body(nil) + } + } +} + +extension timespec { + init(timeAmount amount: TimeAmount) { + let nsecPerSec: Int64 = 1_000_000_000 + let ns = amount.nanoseconds + let sec = ns / nsecPerSec + self = timespec(tv_sec: Int(sec), tv_nsec: Int(ns - sec * nsecPerSec)) + } +} + +/// Represents IO events NIO might be interested in. `SelectorEventSet` is used for two purposes: +/// 1. To express interest in a given event set and +/// 2. for notifications about an IO event set that has occurred. +/// +/// For example, if you were interested in reading and writing data from/to a socket and also obviously if the socket +/// receives a connection reset, express interest with `[.read, .write, .reset]`. +/// If then suddenly the socket becomes both readable and writable, the eventing mechanism will tell you about that +/// fact using `[.read, .write]`. +struct SelectorEventSet: OptionSet, Equatable { + + typealias RawValue = UInt8 + + let rawValue: RawValue + + /// It's impossible to actually register for no events, therefore `_none` should only be used to bootstrap a set + /// of flags or to compare against spurious wakeups. + static let _none = SelectorEventSet([]) + + /// Connection reset or other errors. + static let reset = SelectorEventSet(rawValue: 1 << 0) + + /// EOF at the read/input end of a `Selectable`. + static let readEOF = SelectorEventSet(rawValue: 1 << 1) + + /// Interest in/availability of data to be read + static let read = SelectorEventSet(rawValue: 1 << 2) + + /// Interest in/availability of data to be written + static let write = SelectorEventSet(rawValue: 1 << 3) + + /// EOF at the write/output end of a `Selectable`. + /// + /// - note: This is rarely used because in many cases, there is no signal that this happened. + static let writeEOF = SelectorEventSet(rawValue: 1 << 4) + + init(rawValue: SelectorEventSet.RawValue) { + self.rawValue = rawValue + } +} + +internal let isEarlyEOFDeliveryWorkingOnThisOS: Bool = { + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + return false // rdar://53656794 , once fixed we need to do an OS version check here. + #else + return true + #endif +}() + +/// This protocol defines the methods that are expected to be found on +/// `Selector`. While defined as a protocol there is no expectation that any +/// object other than `Selector` will implement this protocol: instead, this +/// protocol acts as a reference for what new supported selector backends +/// must implement. +protocol _SelectorBackendProtocol { + associatedtype R: Registration + func initialiseState0() throws + func deinitAssertions0() // allows actual implementation to run some assertions as part of the class deinit + func register0(selectable: S, fileDescriptor: CInt, interested: SelectorEventSet, registrationID: SelectorRegistrationID) throws + func reregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, newInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws + func deregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws + /* attention, this may (will!) be called from outside the event loop, ie. can't access mutable shared state (such as `self.open`) */ + func wakeup0() throws + /// Apply the given `SelectorStrategy` and execute `body` once it's complete (which may produce `SelectorEvent`s to handle). + /// + /// - parameters: + /// - strategy: The `SelectorStrategy` to apply + /// - body: The function to execute for each `SelectorEvent` that was produced. + func whenReady0(strategy: SelectorStrategy, onLoopBegin: () -> Void, _ body: (SelectorEvent) throws -> Void) throws -> Void + func close0() throws +} + + +/// A `Selector` allows a user to register different `Selectable` sources to an underlying OS selector, and for that selector to notify them once IO is ready for them to process. +/// +/// This implementation offers an consistent API over epoll/liburing (for linux) and kqueue (for Darwin, BSD). +/// There are specific subclasses per API type with a shared common superclass providing overall scaffolding. + +/* this is deliberately not thread-safe, only the wakeup() function may be called unprotectedly */ +internal class Selector { + var lifecycleState: SelectorLifecycleState + var registrations = [Int: R]() + var registrationID: SelectorRegistrationID = .initialRegistrationID + + let myThread: NIOThread + // The rules for `self.selectorFD`, `self.eventFD`, and `self.timerFD`: + // reads: `self.externalSelectorFDLock` OR access from the EventLoop thread + // writes: `self.externalSelectorFDLock` AND access from the EventLoop thread + let externalSelectorFDLock = Lock() + var selectorFD: CInt = -1 // -1 == we're closed + + // Here we add the stored properties that are used by the specific backends + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + typealias EventType = kevent + #elseif os(Linux) || os(Android) + #if !SWIFTNIO_USE_IO_URING + typealias EventType = Epoll.epoll_event + var earliestTimer: NIODeadline = .distantFuture + var eventFD: CInt = -1 // -1 == we're closed + var timerFD: CInt = -1 // -1 == we're closed + #else + typealias EventType = URingEvent + var eventFD: CInt = -1 // -1 == we're closed + var ring = URing() + let multishot = URing.io_uring_use_multishot_poll // if true, we run with streaming multishot polls + let deferReregistrations = true // if true we only flush once at reentring whenReady() - saves syscalls + var deferredReregistrationsPending = false // true if flush needed when reentring whenReady() + #endif + #else + #error("Unsupported platform, no suitable selector backend (we need kqueue or epoll support)") + #endif + + var events: UnsafeMutablePointer + var eventsCapacity = 64 + + internal func testsOnly_withUnsafeSelectorFD(_ body: (CInt) throws -> T) throws -> T { + assert(self.myThread != NIOThread.current) + return try self.externalSelectorFDLock.withLock { + guard self.selectorFD != -1 else { + throw EventLoopError.shutdown + } + return try body(self.selectorFD) + } + } + + init() throws { + self.myThread = NIOThread.current + self.lifecycleState = .closed + events = Selector.allocateEventsArray(capacity: eventsCapacity) + try self.initialiseState0() + } + + deinit { + self.deinitAssertions0() + assert(self.registrations.count == 0, "left-over registrations: \(self.registrations)") + assert(self.lifecycleState == .closed, "Selector \(self.lifecycleState) (expected .closed) on deinit") + assert(self.selectorFD == -1, "self.selectorFD == \(self.selectorFD) on Selector deinit, forgot close?") + Selector.deallocateEventsArray(events: events, capacity: eventsCapacity) + } + + private static func allocateEventsArray(capacity: Int) -> UnsafeMutablePointer { + let events: UnsafeMutablePointer = UnsafeMutablePointer.allocate(capacity: capacity) + events.initialize(to: EventType()) + return events + } + + private static func deallocateEventsArray(events: UnsafeMutablePointer, capacity: Int) { + events.deinitialize(count: capacity) + events.deallocate() + } + + func growEventArrayIfNeeded(ready: Int) { + assert(self.myThread == NIOThread.current) + guard ready == eventsCapacity else { + return + } + Selector.deallocateEventsArray(events: events, capacity: eventsCapacity) + + // double capacity + eventsCapacity = ready << 1 + events = Selector.allocateEventsArray(capacity: eventsCapacity) + } + + /// Register `Selectable` on the `Selector`. + /// + /// - parameters: + /// - selectable: The `Selectable` to register. + /// - interested: The `SelectorEventSet` in which we are interested and want to be notified about. + /// - makeRegistration: Creates the registration data for the given `SelectorEventSet`. + func register(selectable: S, + interested: SelectorEventSet, + makeRegistration: (SelectorEventSet, SelectorRegistrationID) -> R) throws { + assert(self.myThread == NIOThread.current) + assert(interested.contains(.reset)) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't register on selector as it's \(self.lifecycleState).") + } + + try selectable.withUnsafeHandle { fd in + assert(registrations[Int(fd)] == nil) + try self.register0(selectable: selectable, + fileDescriptor: fd, + interested: interested, + registrationID: self.registrationID) + let registration = makeRegistration(interested, self.registrationID.nextRegistrationID()) + registrations[Int(fd)] = registration + } + } + + /// Re-register `Selectable`, must be registered via `register` before. + /// + /// - parameters: + /// - selectable: The `Selectable` to re-register. + /// - interested: The `SelectorEventSet` in which we are interested and want to be notified about. + func reregister(selectable: S, interested: SelectorEventSet) throws { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't re-register on selector as it's \(self.lifecycleState).") + } + assert(interested.contains(.reset), "must register for at least .reset but tried registering for \(interested)") + try selectable.withUnsafeHandle { fd in + var reg = registrations[Int(fd)]! + try self.reregister0(selectable: selectable, + fileDescriptor: fd, + oldInterested: reg.interested, + newInterested: interested, + registrationID: reg.registrationID) + reg.interested = interested + self.registrations[Int(fd)] = reg + } + } + + /// Deregister `Selectable`, must be registered via `register` before. + /// + /// After the `Selectable is deregistered no `SelectorEventSet` will be produced anymore for the `Selectable`. + /// + /// - parameters: + /// - selectable: The `Selectable` to deregister. + func deregister(selectable: S) throws { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't deregister from selector as it's \(self.lifecycleState).") + } + + try selectable.withUnsafeHandle { fd in + guard let reg = registrations.removeValue(forKey: Int(fd)) else { + return + } + try self.deregister0(selectable: selectable, + fileDescriptor: fd, + oldInterested: reg.interested, + registrationID: reg.registrationID) + } + } + + /// Apply the given `SelectorStrategy` and execute `body` once it's complete (which may produce `SelectorEvent`s to handle). + /// + /// - parameters: + /// - strategy: The `SelectorStrategy` to apply + /// - onLoopBegin: A function executed after the selector returns, just before the main loop begins.. + /// - body: The function to execute for each `SelectorEvent` that was produced. + func whenReady(strategy: SelectorStrategy, onLoopBegin loopStart: () -> Void, _ body: (SelectorEvent) throws -> Void) throws -> Void { + try self.whenReady0(strategy: strategy, onLoopBegin: loopStart, body) + } + + /// Close the `Selector`. + /// + /// After closing the `Selector` it's no longer possible to use it. + public func close() throws { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't close selector as it's \(self.lifecycleState).") + } + try self.close0() + self.lifecycleState = .closed + self.registrations.removeAll() + } + + /* attention, this may (will!) be called from outside the event loop, ie. can't access mutable shared state (such as `self.open`) */ + func wakeup() throws { + try self.wakeup0() + } +} + +extension Selector: CustomStringConvertible { + var description: String { + func makeDescription() -> String { + return "Selector { descriptor = \(self.selectorFD) }" + } + + if NIOThread.current == self.myThread { + return makeDescription() + } else { + return self.externalSelectorFDLock.withLock { + makeDescription() + } + } + } +} + +/// An event that is triggered once the `Selector` was able to select something. +struct SelectorEvent { + public let registration: R + public var io: SelectorEventSet + + /// Create new instance + /// + /// - parameters: + /// - io: The `SelectorEventSet` that triggered this event. + /// - registration: The registration that belongs to the event. + init(io: SelectorEventSet, registration: R) { + self.io = io + self.registration = registration + } +} + +extension Selector where R == NIORegistration { + /// Gently close the `Selector` after all registered `Channel`s are closed. + func closeGently(eventLoop: EventLoop) -> EventLoopFuture { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + return eventLoop.makeFailedFuture(IOError(errnoCode: EBADF, reason: "can't close selector gently as it's \(self.lifecycleState).")) + } + + let futures: [EventLoopFuture] = self.registrations.map { (_, reg: NIORegistration) -> EventLoopFuture in + // The futures will only be notified (of success) once also the closeFuture of each Channel is notified. + // This only happens after all other actions on the Channel is complete and all events are propagated through the + // ChannelPipeline. We do this to minimize the risk to left over any tasks / promises that are tied to the + // EventLoop itself. + func closeChannel(_ chan: Channel) -> EventLoopFuture { + chan.close(promise: nil) + return chan.closeFuture + } + + switch reg.channel { + case .serverSocketChannel(let chan): + return closeChannel(chan) + case .socketChannel(let chan): + return closeChannel(chan) + case .datagramChannel(let chan): + return closeChannel(chan) + case .pipeChannel(let chan, _): + return closeChannel(chan) + } + }.map { future in + future.flatMapErrorThrowing { error in + if let error = error as? ChannelError, error == .alreadyClosed { + return () + } else { + throw error + } + } + } + + guard futures.count > 0 else { + return eventLoop.makeSucceededFuture(()) + } + + return .andAllSucceed(futures, on: eventLoop) + } +} + +/// The strategy used for the `Selector`. +enum SelectorStrategy { + /// Block until there is some IO ready to be processed or the `Selector` is explicitly woken up. + case block + + /// Block until there is some IO ready to be processed, the `Selector` is explicitly woken up or the given `TimeAmount` elapsed. + case blockUntilTimeout(TimeAmount) + + /// Try to select all ready IO at this point in time without blocking at all. + case now +} + +/// A Registration on a `Selector`, which is interested in an `SelectorEventSet`. +/// `registrationID` is used by the event notification backends (kqueue, epoll, ...) +/// to mark events to allow for filtering of received return values to not be delivered to a +/// new `Registration` instance that receives the same file descriptor. Ok if it wraps. +/// Needed for i.e. testWeDoNotDeliverEventsForPreviouslyClosedChannels to succeed. +@usableFromInline struct SelectorRegistrationID: Hashable { + @usableFromInline var _rawValue: UInt32 + + @inlinable var rawValue: UInt32 { + return self._rawValue + } + + @inlinable static var initialRegistrationID: SelectorRegistrationID { + return SelectorRegistrationID(rawValue: .max) + } + + @inlinable mutating func nextRegistrationID() -> SelectorRegistrationID { + let current = self + // Overflow is okay here, this is just for very short-term disambiguation + self._rawValue = self._rawValue &+ 1 + return current + } + + @inlinable init(rawValue: UInt32) { + self._rawValue = rawValue + } + + @inlinable static func ==(_ lhs: SelectorRegistrationID, _ rhs: SelectorRegistrationID) -> Bool { + return lhs._rawValue == rhs._rawValue + } + + @inlinable func hash(into hasher: inout Hasher) { + hasher.combine(self._rawValue) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorKqueue.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorKqueue.swift new file mode 100644 index 00000000..93c821eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorKqueue.swift @@ -0,0 +1,388 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + +/// Represents the `kqueue` filters we might use: +/// +/// - `except` corresponds to `EVFILT_EXCEPT` +/// - `read` corresponds to `EVFILT_READ` +/// - `write` corresponds to `EVFILT_WRITE` +private struct KQueueEventFilterSet: OptionSet, Equatable { + typealias RawValue = UInt8 + + let rawValue: RawValue + + static let _none = KQueueEventFilterSet([]) + // skipping `1 << 0` because kqueue doesn't have a direct match for `.reset` (`EPOLLHUP` for epoll) + static let except = KQueueEventFilterSet(rawValue: 1 << 1) + static let read = KQueueEventFilterSet(rawValue: 1 << 2) + static let write = KQueueEventFilterSet(rawValue: 1 << 3) + + init(rawValue: RawValue) { + self.rawValue = rawValue + } +} + +extension KQueueEventFilterSet { + /// Convert NIO's `SelectorEventSet` set to a `KQueueEventFilterSet` + init(selectorEventSet: SelectorEventSet) { + var kqueueFilterSet: KQueueEventFilterSet = .init(rawValue: 0) + if selectorEventSet.contains(.read) { + kqueueFilterSet.formUnion(.read) + } + + if selectorEventSet.contains(.write) { + kqueueFilterSet.formUnion(.write) + } + + if isEarlyEOFDeliveryWorkingOnThisOS && selectorEventSet.contains(.readEOF) { + kqueueFilterSet.formUnion(.except) + } + self = kqueueFilterSet + } + + /// Calculate the kqueue filter changes that are necessary to transition from `previousKQueueFilterSet` to `self`. + /// The `body` closure is then called with the changes necessary expressed as a number of `kevent`. + /// + /// - parameters: + /// - previousKQueueFilterSet: The previous filter set that is currently registered with kqueue. + /// - fileDescriptor: The file descriptor the `kevent`s should be generated to. + /// - body: The closure that will then apply the change set. + func calculateKQueueFilterSetChanges(previousKQueueFilterSet: KQueueEventFilterSet, + fileDescriptor: CInt, + registrationID: SelectorRegistrationID, + _ body: (UnsafeMutableBufferPointer) throws -> Void) rethrows { + // we only use three filters (EVFILT_READ, EVFILT_WRITE and EVFILT_EXCEPT) so the number of changes would be 3. + var kevents = KeventTriple() + + let differences = previousKQueueFilterSet.symmetricDifference(self) // contains all the events that need a change (either need to be added or removed) + + func calculateKQueueChange(event: KQueueEventFilterSet) -> UInt16? { + guard differences.contains(event) else { + return nil + } + return UInt16(self.contains(event) ? EV_ADD : EV_DELETE) + } + + for (event, filter) in [(KQueueEventFilterSet.read, EVFILT_READ), (.write, EVFILT_WRITE), (.except, EVFILT_EXCEPT)] { + if let flags = calculateKQueueChange(event: event) { + kevents.appendEvent(fileDescriptor: fileDescriptor, filter: filter, flags: flags, registrationID: registrationID) + } + } + + try kevents.withUnsafeBufferPointer(body) + } +} + +extension SelectorRegistrationID { + init(kqueueUData: UnsafeMutableRawPointer?) { + self = .init(rawValue: UInt32(truncatingIfNeeded: UInt(bitPattern: kqueueUData))) + } +} + +/* this is deliberately not thread-safe, only the wakeup() function may be called unprotectedly */ +extension Selector: _SelectorBackendProtocol { + private static func toKQueueTimeSpec(strategy: SelectorStrategy) -> timespec? { + switch strategy { + case .block: + return nil + case .now: + return timespec(tv_sec: 0, tv_nsec: 0) + case .blockUntilTimeout(let nanoseconds): + // A scheduledTask() specified with a zero or negative timeAmount, will be scheduled immediately + // and therefore SHOULD NOT result in a kevent being created with a negative or zero timespec. + precondition(nanoseconds.nanoseconds > 0, "\(nanoseconds) is invalid (0 < nanoseconds)") + + var ts = timespec(timeAmount: nanoseconds) + // Check that the timespec tv_nsec field conforms to the definition in the C11 standard (ISO/IEC 9899:2011). + assert((0..<1_000_000_000).contains(ts.tv_nsec), "\(ts) is invalid (0 <= tv_nsec < 1_000_000_000)") + + // The maximum value in seconds supported by the Darwin-kernel interval timer (kern_time.c:itimerfix()) + // (note that - whilst unlikely - this value *could* change). + let sysIntervalTimerMaxSec = 100_000_000 + + // Clamp the timespec tv_sec value to the maximum supported by the Darwin-kernel. + // Whilst this schedules the event far into the future (several years) it will still be triggered provided + // the system stays up. + ts.tv_sec = min(ts.tv_sec, sysIntervalTimerMaxSec) + + return ts + } + } + + /// Apply a kqueue changeset by calling the `kevent` function with the `kevent`s supplied in `keventBuffer`. + private func kqueueApplyEventChangeSet(keventBuffer: UnsafeMutableBufferPointer) throws { + // WARNING: This is called on `self.myThread` OR with `self.externalSelectorFDLock` held. + // So it MUST NOT touch anything on `self.` apart from constants and `self.selectorFD`. + guard keventBuffer.count > 0 else { + // nothing to do + return + } + do { + try KQueue.kevent(kq: self.selectorFD, + changelist: keventBuffer.baseAddress!, + nchanges: CInt(keventBuffer.count), + eventlist: nil, + nevents: 0, + timeout: nil) + } catch let err as IOError { + if err.errnoCode == EINTR { + // See https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 + // When kevent() call fails with EINTR error, all changes in the changelist have been applied. + return + } + throw err + } + } + + private func kqueueUpdateEventNotifications(selectable: S, interested: SelectorEventSet, oldInterested: SelectorEventSet?, registrationID: SelectorRegistrationID) throws { + assert(self.myThread == NIOThread.current) + let oldKQueueFilters = KQueueEventFilterSet(selectorEventSet: oldInterested ?? ._none) + let newKQueueFilters = KQueueEventFilterSet(selectorEventSet: interested) + assert(interested.contains(.reset)) + assert(oldInterested?.contains(.reset) ?? true) + + try selectable.withUnsafeHandle { + try newKQueueFilters.calculateKQueueFilterSetChanges(previousKQueueFilterSet: oldKQueueFilters, + fileDescriptor: $0, + registrationID: registrationID, + kqueueApplyEventChangeSet) + } + } + + func initialiseState0() throws { + + self.selectorFD = try KQueue.kqueue() + self.lifecycleState = .open + + var event = kevent() + event.ident = 0 + event.filter = Int16(EVFILT_USER) + event.fflags = UInt32(NOTE_FFNOP) + event.data = 0 + event.udata = nil + event.flags = UInt16(EV_ADD | EV_ENABLE | EV_CLEAR) + try withUnsafeMutablePointer(to: &event) { ptr in + try kqueueApplyEventChangeSet(keventBuffer: UnsafeMutableBufferPointer(start: ptr, count: 1)) + } + } + + func deinitAssertions0() { + } + + func register0(selectable: S, fileDescriptor: CInt, interested: SelectorEventSet, registrationID: SelectorRegistrationID) throws { + try kqueueUpdateEventNotifications(selectable: selectable, interested: interested, oldInterested: nil, registrationID: registrationID) + } + + func reregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, newInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws { + try kqueueUpdateEventNotifications(selectable: selectable, interested: newInterested, oldInterested: oldInterested, registrationID: registrationID) + } + + func deregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws { + try kqueueUpdateEventNotifications(selectable: selectable, interested: .reset, oldInterested: oldInterested, registrationID: registrationID) + } + + /// Apply the given `SelectorStrategy` and execute `body` once it's complete (which may produce `SelectorEvent`s to handle). + /// + /// - parameters: + /// - strategy: The `SelectorStrategy` to apply + /// - body: The function to execute for each `SelectorEvent` that was produced. + func whenReady0(strategy: SelectorStrategy, onLoopBegin loopStart: () -> Void, _ body: (SelectorEvent) throws -> Void) throws -> Void { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't call whenReady for selector as it's \(self.lifecycleState).") + } + + let timespec = Selector.toKQueueTimeSpec(strategy: strategy) + let ready = try timespec.withUnsafeOptionalPointer { ts in + Int(try KQueue.kevent(kq: self.selectorFD, changelist: nil, nchanges: 0, eventlist: events, nevents: Int32(eventsCapacity), timeout: ts)) + } + + loopStart() + + for i in 0.. 0 the user might have changed the registrations since then. + assert(i != 0 || selectorEvent.isSubset(of: registration.interested), "selectorEvent: \(selectorEvent), registration: \(registration)") + + // in any case we only want what the user is currently registered for & what we got + selectorEvent = selectorEvent.intersection(registration.interested) + + guard selectorEvent != ._none else { + continue + } + try body((SelectorEvent(io: selectorEvent, registration: registration))) + } + + growEventArrayIfNeeded(ready: ready) + } + + /// Close the `Selector`. + /// + /// After closing the `Selector` it's no longer possible to use it. + func close0() throws { + + self.externalSelectorFDLock.withLock { + // We try! all of the closes because close can only fail in the following ways: + // - EINTR, which we eat in Posix.close + // - EIO, which can only happen for on-disk files + // - EBADF, which can't happen here because we would crash as EBADF is marked unacceptable + // Therefore, we assert here that close will always succeed and if not, that's a NIO bug we need to know + // about. + // We limit close to only be for positive FD:s though, as subclasses (e.g. uring) + // may already have closed some of these FD:s in their close function. + + + try! Posix.close(descriptor: self.selectorFD) + self.selectorFD = -1 + } + } + + /* attention, this may (will!) be called from outside the event loop, ie. can't access mutable shared state (such as `self.open`) */ + func wakeup0() throws { + assert(NIOThread.current != self.myThread) + try self.externalSelectorFDLock.withLock { + guard self.selectorFD >= 0 else { + throw EventLoopError.shutdown + } + var event = kevent() + event.ident = 0 + event.filter = Int16(EVFILT_USER) + event.fflags = UInt32(NOTE_TRIGGER | NOTE_FFNOP) + event.data = 0 + event.udata = nil + event.flags = 0 + try withUnsafeMutablePointer(to: &event) { ptr in + try self.kqueueApplyEventChangeSet(keventBuffer: UnsafeMutableBufferPointer(start: ptr, count: 1)) + } + } + } +} + +extension kevent { + /// Update a kevent for a given filter, file descriptor, and set of flags. + mutating func setEvent(fileDescriptor fd: CInt, filter: CInt, flags: UInt16, registrationID: SelectorRegistrationID) { + self.ident = UInt(fd) + self.filter = Int16(filter) + self.flags = flags + self.udata = UnsafeMutableRawPointer(bitPattern: UInt(registrationID.rawValue)) + + // On macOS, EVFILT_EXCEPT will fire whenever there is unread data in the socket receive + // buffer. This is not a behaviour we want from EVFILT_EXCEPT: we only want it to tell us + // about actually exceptional conditions. For this reason, when we set EVFILT_EXCEPT + // we do it with NOTE_LOWAT set to Int.max, which will ensure that there is never enough data + // in the send buffer to trigger EVFILT_EXCEPT. Thanks to the sensible design of kqueue, + // this only affects our EXCEPT filter: EVFILT_READ behaves separately. + if filter == EVFILT_EXCEPT { + self.fflags = CUnsignedInt(NOTE_LOWAT) + self.data = Int.max + } else { + self.fflags = 0 + self.data = 0 + } + } +} + +/// This structure encapsulates our need to create up to three kevent entries when calculating kevent filter +/// set changes. We want to be able to store these kevent objects on the stack, which we historically did with +/// unsafe pointers. This object replaces that unsafe code with safe code, and attempts to achieve the same +/// performance constraints. +fileprivate struct KeventTriple { + // We need to store this in a tuple to achieve C-style memory layout. + private var kevents = (kevent(), kevent(), kevent()) + + private var initialized = 0 + + private subscript(_ event: Int) -> kevent { + get { + switch event { + case 0: + return kevents.0 + case 1: + return kevents.1 + case 2: + return kevents.2 + default: + preconditionFailure() + } + } + set { + switch event { + case 0: + kevents.0 = newValue + case 1: + kevents.1 = newValue + case 2: + kevents.2 = newValue + default: + preconditionFailure() + } + } + } + + mutating func appendEvent(fileDescriptor fd: CInt, filter: CInt, flags: UInt16, registrationID: SelectorRegistrationID) { + defer { + // Unchecked math is safe here: we access through the subscript, which will trap on out-of-bounds value, so we'd trap + // well before we overflow. + self.initialized &+= 1 + } + + self[self.initialized].setEvent(fileDescriptor: fd, filter: filter, flags: flags, registrationID: registrationID) + } + + mutating func withUnsafeBufferPointer(_ body: (UnsafeMutableBufferPointer) throws -> Void) rethrows { + try withUnsafeMutablePointer(to: &self.kevents) { keventPtr in + // Pointer to a homogeneous tuple of a given type is also implicitly bound to the element type, so + // we can safely pun this here. + let typedPointer = UnsafeMutableRawPointer(keventPtr).assumingMemoryBound(to: kevent.self) + let typedBufferPointer = UnsafeMutableBufferPointer(start: typedPointer, count: self.initialized) + try body(typedBufferPointer) + } + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorUring.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorUring.swift new file mode 100644 index 00000000..b418feb7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SelectorUring.swift @@ -0,0 +1,363 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +#if SWIFTNIO_USE_IO_URING +#if os(Linux) || os(Android) + +/// Represents the `poll` filters/events we might use from io_uring: +/// +/// - `hangup` corresponds to `POLLHUP` +/// - `readHangup` corresponds to `POLLRDHUP` +/// - `input` corresponds to `POLLIN` +/// - `output` corresponds to `POLLOUT` +/// - `error` corresponds to `POLLERR` +private struct URingFilterSet: OptionSet, Equatable { + typealias RawValue = UInt8 + + let rawValue: RawValue + + static let _none = URingFilterSet([]) + static let hangup = URingFilterSet(rawValue: 1 << 0) + static let readHangup = URingFilterSet(rawValue: 1 << 1) + static let input = URingFilterSet(rawValue: 1 << 2) + static let output = URingFilterSet(rawValue: 1 << 3) + static let error = URingFilterSet(rawValue: 1 << 4) + + init(rawValue: RawValue) { + self.rawValue = rawValue + } +} + +extension URingFilterSet { + /// Convert NIO's `SelectorEventSet` set to a `URingFilterSet` + init(selectorEventSet: SelectorEventSet) { + var thing: URingFilterSet = [.error, .hangup] + if selectorEventSet.contains(.read) { + thing.formUnion(.input) + } + if selectorEventSet.contains(.write) { + thing.formUnion(.output) + } + if selectorEventSet.contains(.readEOF) { + thing.formUnion(.readHangup) + } + self = thing + } +} + +extension SelectorEventSet { + var uringEventSet: UInt32 { + assert(self != ._none) + // POLLERR | POLLHUP is always set unconditionally anyway but it's easier to understand if we explicitly ask. + var filter: UInt32 = URing.POLLERR | URing.POLLHUP + let uringFilters = URingFilterSet(selectorEventSet: self) + if uringFilters.contains(.input) { + filter |= URing.POLLIN + } + if uringFilters.contains(.output) { + filter |= URing.POLLOUT + } + if uringFilters.contains(.readHangup) { + filter |= URing.POLLRDHUP + } + assert(filter & URing.POLLHUP != 0) // both of these are reported + assert(filter & URing.POLLERR != 0) // always and can't be masked. + return filter + } + + fileprivate init(uringEvent: UInt32) { + var selectorEventSet: SelectorEventSet = ._none + if uringEvent & URing.POLLIN != 0 { + selectorEventSet.formUnion(.read) + } + if uringEvent & URing.POLLOUT != 0 { + selectorEventSet.formUnion(.write) + } + if uringEvent & URing.POLLRDHUP != 0 { + selectorEventSet.formUnion(.readEOF) + } + if uringEvent & URing.POLLHUP != 0 || uringEvent & URing.POLLERR != 0 { + selectorEventSet.formUnion(.reset) + } + self = selectorEventSet + } +} + +extension Selector: _SelectorBackendProtocol { + internal func _debugPrint(_ s: @autoclosure () -> String) { + #if SWIFTNIO_IO_URING_DEBUG_SELECTOR + print("S [\(NIOThread.current)] " + s()) + #endif + } + + func initialiseState0() throws { + try ring.io_uring_queue_init() + self.selectorFD = ring.fd + + // eventfd are always singleshot and re-register each time around + // as certain use cases of nio seems to generate superfluous wakeups. + // (at least its tested for that in some of the performance tests + // e.g. future_whenallsucceed_100k_deferred_off_loop, future_whenallcomplete_100k_deferred_off_loop + // ) - if using normal ET multishots, we would get 100k events to handle basically. + // so using single shot for wakeups makes those tests run 30-35% faster approx. + + self.eventFD = try EventFd.eventfd(initval: 0, flags: Int32(EventFd.EFD_CLOEXEC | EventFd.EFD_NONBLOCK)) + + ring.io_uring_prep_poll_add(fileDescriptor: self.eventFD, + pollMask: URing.POLLIN, + registrationID:SelectorRegistrationID(rawValue: 0), + multishot:false) // wakeups + + self.lifecycleState = .open + _debugPrint("URingSelector up and running fd [\(self.selectorFD)] wakeups on event_fd [\(self.eventFD)]") + } + + func deinitAssertions0() { + assert(self.eventFD == -1, "self.eventFD == \(self.eventFD) on deinitAssertions0 deinit, forgot close?") + } + + func register0(selectable: S, + fileDescriptor: CInt, + interested: SelectorEventSet, + registrationID: SelectorRegistrationID) throws { + _debugPrint("register interested \(interested) uringEventSet [\(interested.uringEventSet)] registrationID[\(registrationID)]") + self.deferredReregistrationsPending = true + ring.io_uring_prep_poll_add(fileDescriptor: fileDescriptor, + pollMask: interested.uringEventSet, + registrationID: registrationID, + submitNow: !deferReregistrations, + multishot: multishot) + } + + func reregister0(selectable: S, + fileDescriptor: CInt, + oldInterested: SelectorEventSet, + newInterested: SelectorEventSet, + registrationID: SelectorRegistrationID) throws { + _debugPrint("Re-register old \(oldInterested) new \(newInterested) uringEventSet [\(oldInterested.uringEventSet)] reg.uringEventSet [\(newInterested.uringEventSet)]") + + self.deferredReregistrationsPending = true + if multishot { + ring.io_uring_poll_update(fileDescriptor: fileDescriptor, + newPollmask: newInterested.uringEventSet, + oldPollmask: oldInterested.uringEventSet, + registrationID: registrationID, + submitNow: !deferReregistrations, + multishot: true) + } else { + ring.io_uring_prep_poll_remove(fileDescriptor: fileDescriptor, + pollMask: oldInterested.uringEventSet, + registrationID: registrationID, + submitNow:!deferReregistrations, + link: true) // next event linked will cancel if this event fails + + ring.io_uring_prep_poll_add(fileDescriptor: fileDescriptor, + pollMask: newInterested.uringEventSet, + registrationID: registrationID, + submitNow: !deferReregistrations, + multishot: false) + } + } + + func deregister0(selectable: S, fileDescriptor: CInt, oldInterested: SelectorEventSet, registrationID: SelectorRegistrationID) throws { + _debugPrint("deregister interested \(selectable) reg.interested.uringEventSet [\(oldInterested.uringEventSet)]") + + self.deferredReregistrationsPending = true + ring.io_uring_prep_poll_remove(fileDescriptor: fileDescriptor, + pollMask: oldInterested.uringEventSet, + registrationID: registrationID, + submitNow:!deferReregistrations) + } + + private func shouldRefreshPollForEvent(selectorEvent:SelectorEventSet) -> Bool { + if selectorEvent.contains(.read) { + // as we don't do exhaustive reads, we need to prod the kernel for + // new events, would be even better if we knew if we had read all there is + return true + } + // If the event is fully handled, we can return false to avoid reregistration for multishot polls. + return false + } + + /// Apply the given `SelectorStrategy` and execute `body` once it's complete (which may produce `SelectorEvent`s to handle). + /// + /// - parameters: + /// - strategy: The `SelectorStrategy` to apply + /// - body: The function to execute for each `SelectorEvent` that was produced. + func whenReady0(strategy: SelectorStrategy, onLoopBegin loopStart: () -> Void, _ body: (SelectorEvent) throws -> Void) throws -> Void { + assert(self.myThread == NIOThread.current) + guard self.lifecycleState == .open else { + throw IOError(errnoCode: EBADF, reason: "can't call whenReady for selector as it's \(self.lifecycleState).") + } + + var ready: Int = 0 + + // flush reregistration of pending modifications if needed (nop in SQPOLL mode) + // basically this elides all reregistrations and deregistrations into a single + // syscall instead of one for each. Future improvement would be to also merge + // the pending pollmasks (now each change will be queued, but we could also + // merge the masks for reregistrations) - but the most important thing is to + // only trap into the kernel once for the set of changes, so needs to be measured. + if deferReregistrations && self.deferredReregistrationsPending { + self.deferredReregistrationsPending = false + ring.io_uring_flush() + } + + switch strategy { + case .now: + _debugPrint("whenReady.now") + ready = Int(ring.io_uring_peek_batch_cqe(events: events, maxevents: UInt32(eventsCapacity), multishot:multishot)) + case .blockUntilTimeout(let timeAmount): + _debugPrint("whenReady.blockUntilTimeout") + ready = try Int(ring.io_uring_wait_cqe_timeout(events: events, maxevents: UInt32(eventsCapacity), timeout:timeAmount, multishot:multishot)) + case .block: + _debugPrint("whenReady.block") + ready = Int(ring.io_uring_peek_batch_cqe(events: events, maxevents: UInt32(eventsCapacity), multishot:multishot)) // first try to consume any existing + + if (ready <= 0) // otherwise block (only single supported, but we will use batch peek cqe next run around... + { + ready = try ring.io_uring_wait_cqe(events: events, maxevents: UInt32(eventsCapacity), multishot:multishot) + } + } + + loopStart() + + for i in 0..= 0 else { + throw EventLoopError.shutdown + } + _ = try EventFd.eventfd_write(fd: self.eventFD, value: 1) + } + } +} + +#endif + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ServerSocket.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ServerSocket.swift new file mode 100644 index 00000000..78c7875a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ServerSocket.swift @@ -0,0 +1,135 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A server socket that can accept new connections. +/* final but tests */ class ServerSocket: BaseSocket, ServerSocketProtocol { + typealias SocketType = ServerSocket + private let cleanupOnClose: Bool + + public final class func bootstrap(protocolFamily: NIOBSDSocket.ProtocolFamily, host: String, port: Int) throws -> ServerSocket { + let socket = try ServerSocket(protocolFamily: protocolFamily) + try socket.bind(to: SocketAddress.makeAddressResolvingHost(host, port: port)) + try socket.listen() + return socket + } + + /// Create a new instance. + /// + /// - parameters: + /// - protocolFamily: The protocol family to use (usually `AF_INET6` or `AF_INET`). + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if creation of the socket failed. + init(protocolFamily: NIOBSDSocket.ProtocolFamily, setNonBlocking: Bool = false) throws { + let sock = try BaseSocket.makeSocket(protocolFamily: protocolFamily, type: .stream, setNonBlocking: setNonBlocking) + switch protocolFamily { + case .unix: + cleanupOnClose = true + default: + cleanupOnClose = false + } + try super.init(socket: sock) + } + + /// Create a new instance. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound socket. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if socket is invalid. + #if !os(Windows) + @available(*, deprecated, renamed: "init(socket:setNonBlocking:)") + convenience init(descriptor: CInt, setNonBlocking: Bool = false) throws { + try self.init(socket: descriptor, setNonBlocking: setNonBlocking) + } + #endif + + /// Create a new instance. + /// + /// - parameters: + /// - descriptor: The _Unix file descriptor_ representing the bound socket. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if socket is invalid. + init(socket: NIOBSDSocket.Handle, setNonBlocking: Bool = false) throws { + cleanupOnClose = false // socket already bound, owner must clean up + try super.init(socket: socket) + if setNonBlocking { + try self.setNonBlocking() + } + } + + /// Start to listen for new connections. + /// + /// - parameters: + /// - backlog: The backlog to use. + /// - throws: An `IOError` if creation of the socket failed. + func listen(backlog: Int32 = 128) throws { + try withUnsafeHandle { + _ = try NIOBSDSocket.listen(socket: $0, backlog: backlog) + } + } + + /// Accept a new connection + /// + /// - parameters: + /// - setNonBlocking: set non-blocking mode on the returned `Socket`. On Linux this will use accept4 with SOCK_NONBLOCK to save a system call. + /// - returns: A `Socket` once a new connection was established or `nil` if this `ServerSocket` is in non-blocking mode and there is no new connection that can be accepted when this method is called. + /// - throws: An `IOError` if the operation failed. + func accept(setNonBlocking: Bool = false) throws -> Socket? { + return try withUnsafeHandle { fd in + #if os(Linux) + let flags: Int32 + if setNonBlocking { + flags = Linux.SOCK_NONBLOCK + } else { + flags = 0 + } + let result = try Linux.accept4(descriptor: fd, addr: nil, len: nil, flags: flags) + #else + let result = try NIOBSDSocket.accept(socket: fd, address: nil, address_len: nil) + #endif + + guard let fd = result else { + return nil + } + let sock = try Socket(socket: fd) + #if !os(Linux) + if setNonBlocking { + do { + try sock.setNonBlocking() + } catch { + // best effort + try? sock.close() + throw error + } + } + #endif + return sock + } + } + + /// Close the socket. + /// + /// After the socket was closed all other methods will throw an `IOError` when called. + /// + /// - throws: An `IOError` if the operation failed. + override func close() throws { + let maybePathname = self.cleanupOnClose ? (try? self.localAddress().pathname) : nil + try super.close() + if let socketPath = maybePathname { + try BaseSocket.cleanupSocket(unixDomainSocketPath: socketPath) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Socket.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Socket.swift new file mode 100644 index 00000000..03932867 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Socket.swift @@ -0,0 +1,315 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// The container used for writing multiple buffers via `writev`. +typealias IOVector = iovec + +// TODO: scattering support +/* final but tests */ class Socket: BaseSocket, SocketProtocol { + typealias SocketType = Socket + + /// The maximum number of bytes to write per `writev` call. + static var writevLimitBytes = Int(Int32.max) + + /// The maximum number of `IOVector`s to write per `writev` call. + static let writevLimitIOVectors: Int = Posix.UIO_MAXIOV + + /// Create a new instance. + /// + /// - parameters: + /// - protocolFamily: The protocol family to use (usually `AF_INET6` or `AF_INET`). + /// - type: The type of the socket to create. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if creation of the socket failed. + init(protocolFamily: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, setNonBlocking: Bool = false) throws { + let sock = try BaseSocket.makeSocket(protocolFamily: protocolFamily, type: type, setNonBlocking: setNonBlocking) + try super.init(socket: sock) + } + + /// Create a new instance out of an already established socket. + /// + /// - parameters: + /// - descriptor: The existing socket descriptor. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if could not change the socket into non-blocking + #if !os(Windows) + @available(*, deprecated, renamed: "init(socket:setNonBlocking:)") + convenience init(descriptor: CInt, setNonBlocking: Bool) throws { + try self.init(socket: descriptor, setNonBlocking: setNonBlocking) + } + #endif + + /// Create a new instance out of an already established socket. + /// + /// - parameters: + /// - descriptor: The existing socket descriptor. + /// - setNonBlocking: Set non-blocking mode on the socket. + /// - throws: An `IOError` if could not change the socket into non-blocking + init(socket: NIOBSDSocket.Handle, setNonBlocking: Bool) throws { + try super.init(socket: socket) + if setNonBlocking { + try self.setNonBlocking() + } + } + + /// Create a new instance. + /// + /// The ownership of the passed in descriptor is transferred to this class. A user must call `close` to close the underlying + /// file descriptor once it's not needed / used anymore. + /// + /// - parameters: + /// - descriptor: The file descriptor to wrap. + #if !os(Windows) + @available(*, deprecated, renamed: "init(socket:)") + convenience init(descriptor: CInt) throws { + try self.init(socket: descriptor) + } + #endif + + /// Create a new instance. + /// + /// The ownership of the passed in descriptor is transferred to this class. A user must call `close` to close the underlying + /// file descriptor once it's not needed / used anymore. + /// + /// - parameters: + /// - descriptor: The file descriptor to wrap. + override init(socket: NIOBSDSocket.Handle) throws { + try super.init(socket: socket) + } + + /// Connect to the `SocketAddress`. + /// + /// - parameters: + /// - address: The `SocketAddress` to which the connection should be established. + /// - returns: `true` if the connection attempt completes, `false` if `finishConnect` must be called later to complete the connection attempt. + /// - throws: An `IOError` if the operation failed. + func connect(to address: SocketAddress) throws -> Bool { + return try withUnsafeHandle { fd in + return try address.withSockAddr { (ptr, size) in + return try NIOBSDSocket.connect(socket: fd, address: ptr, + address_len: socklen_t(size)) + } + } + } + + /// Finish a previous non-blocking `connect` operation. + /// + /// - throws: An `IOError` if the operation failed. + func finishConnect() throws { + let result: Int32 = try getOption(level: .socket, name: .so_error) + if result != 0 { + throw IOError(errnoCode: result, reason: "finishing a non-blocking connect failed") + } + } + + /// Write data to the remote peer. + /// + /// - parameters: + /// - pointer: Pointer (and size) to data to write. + /// - returns: The `IOResult` which indicates how much data could be written and if the operation returned before all could be written (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func write(pointer: UnsafeRawBufferPointer) throws -> IOResult { + return try withUnsafeHandle { + try NIOBSDSocket.send(socket: $0, buffer: pointer.baseAddress!, + length: pointer.count) + } + } + + /// Write data to the remote peer (gathering writes). + /// + /// - parameters: + /// - iovecs: The `IOVector`s to write. + /// - returns: The `IOResult` which indicates how much data could be written and if the operation returned before all could be written (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func writev(iovecs: UnsafeBufferPointer) throws -> IOResult { + return try withUnsafeHandle { + try Posix.writev(descriptor: $0, iovecs: iovecs) + } + } + + /// Send data to a destination. + /// + /// - parameters: + /// - pointer: Pointer (and size) to the data to send. + /// - destinationPtr: The destination to which the data should be sent. + /// - destinationSize: The size of the destination address given. + /// - controlBytes: Extra `cmsghdr` information. + /// - returns: The `IOResult` which indicates how much data could be written and if the operation returned before all could be written + /// (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func sendmsg(pointer: UnsafeRawBufferPointer, + destinationPtr: UnsafePointer, + destinationSize: socklen_t, + controlBytes: UnsafeMutableRawBufferPointer) throws -> IOResult { + // Dubious const casts - it should be OK as there is no reason why this should get mutated + // just bad const declaration below us. + var vec = iovec(iov_base: UnsafeMutableRawPointer(mutating: pointer.baseAddress!), iov_len: numericCast(pointer.count)) + let notConstCorrectDestinationPtr = UnsafeMutableRawPointer(mutating: destinationPtr) + + return try withUnsafeHandle { handle in + return try withUnsafeMutablePointer(to: &vec) { vecPtr in +#if os(Windows) + var messageHeader = + WSAMSG(name: notConstCorrectDestinationPtr + .assumingMemoryBound(to: sockaddr.self), + namelen: destinationSize, + lpBuffers: vecPtr, + dwBufferCount: 1, + Control: WSABUF(len: ULONG(controlBytes.count), + buf: controlBytes.baseAddress? + .bindMemory(to: CHAR.self, + capacity: controlBytes.count)), + dwFlags: 0) +#else + var messageHeader = msghdr(msg_name: notConstCorrectDestinationPtr, + msg_namelen: destinationSize, + msg_iov: vecPtr, + msg_iovlen: 1, + msg_control: controlBytes.baseAddress, + msg_controllen: .init(controlBytes.count), + msg_flags: 0) +#endif + return try NIOBSDSocket.sendmsg(socket: handle, msgHdr: &messageHeader, flags: 0) + } + } + } + + /// Read data from the socket. + /// + /// - parameters: + /// - pointer: The pointer (and size) to the storage into which the data should be read. + /// - returns: The `IOResult` which indicates how much data could be read and if the operation returned before all could be read (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func read(pointer: UnsafeMutableRawBufferPointer) throws -> IOResult { + return try withUnsafeHandle { + try Posix.read(descriptor: $0, pointer: pointer.baseAddress!, size: pointer.count) + } + } + + /// Receive data from the socket, along with aditional control information. + /// + /// - parameters: + /// - pointer: The pointer (and size) to the storage into which the data should be read. + /// - storage: The address from which the data was received + /// - storageLen: The size of the storage itself. + /// - controlBytes: A buffer in memory for use receiving control bytes. This parameter will be modified to hold any data actually received. + /// - returns: The `IOResult` which indicates how much data could be received and if the operation returned before all the data could be received + /// (because the socket is in non-blocking mode) + /// - throws: An `IOError` if the operation failed. + func recvmsg(pointer: UnsafeMutableRawBufferPointer, + storage: inout sockaddr_storage, + storageLen: inout socklen_t, + controlBytes: inout UnsafeReceivedControlBytes) throws -> IOResult { + var vec = iovec(iov_base: pointer.baseAddress, iov_len: numericCast(pointer.count)) + + return try withUnsafeMutablePointer(to: &vec) { vecPtr in + return try storage.withMutableSockAddr { (sockaddrPtr, _) in +#if os(Windows) + var messageHeader = + WSAMSG(name: sockaddrPtr, namelen: storageLen, + lpBuffers: vecPtr, dwBufferCount: 1, + Control: WSABUF(len: ULONG(controlBytes.controlBytesBuffer.count), + buf: controlBytes.controlBytesBuffer.baseAddress? + .bindMemory(to: CHAR.self, + capacity: controlBytes.controlBytesBuffer.count)), + dwFlags: 0) + defer { + // We need to write back the length of the message. + storageLen = messageHeader.namelen + } +#else + var messageHeader = msghdr(msg_name: sockaddrPtr, + msg_namelen: storageLen, + msg_iov: vecPtr, + msg_iovlen: 1, + msg_control: controlBytes.controlBytesBuffer.baseAddress, + msg_controllen: .init(controlBytes.controlBytesBuffer.count), + msg_flags: 0) + defer { + // We need to write back the length of the message. + storageLen = messageHeader.msg_namelen + } +#endif + + let result = try withUnsafeMutablePointer(to: &messageHeader) { messageHeader in + return try withUnsafeHandle { fd in + return try NIOBSDSocket.recvmsg(socket: fd, msgHdr: messageHeader, flags: 0) + } + } + + // Only look at the control bytes if all is good. + if case .processed = result { + controlBytes.receivedControlMessages = UnsafeControlMessageCollection(messageHeader: messageHeader) + } + + return result + } + } + } + + /// Send the content of a file descriptor to the remote peer (if possible a zero-copy strategy is applied). + /// + /// - parameters: + /// - fd: The file descriptor of the file to send. + /// - offset: The offset in the file. + /// - count: The number of bytes to send. + /// - returns: The `IOResult` which indicates how much data could be send and if the operation returned before all could be send (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func sendFile(fd: CInt, offset: Int, count: Int) throws -> IOResult { + return try withUnsafeHandle { + try NIOBSDSocket.sendfile(socket: $0, fd: fd, offset: off_t(offset), + len: off_t(count)) + } + } + + /// Receive `MMsgHdr`s. + /// + /// - parameters: + /// - msgs: The pointer to the `MMsgHdr`s into which the received message will be stored. + /// - returns: The `IOResult` which indicates how many messages could be received and if the operation returned before all messages could be received (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func recvmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult { + return try withUnsafeHandle { + try NIOBSDSocket.recvmmsg(socket: $0, msgvec: msgs.baseAddress!, + vlen: CUnsignedInt(msgs.count), flags: 0, + timeout: nil) + } + } + + /// Send `MMsgHdr`s. + /// + /// - parameters: + /// - msgs: The pointer to the `MMsgHdr`s which will be send. + /// - returns: The `IOResult` which indicates how many messages could be send and if the operation returned before all messages could be send (because the socket is in non-blocking mode). + /// - throws: An `IOError` if the operation failed. + func sendmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult { + return try withUnsafeHandle { + try NIOBSDSocket.sendmmsg(socket: $0, msgvec: msgs.baseAddress!, + vlen: CUnsignedInt(msgs.count), flags: 0) + } + } + + /// Shutdown the socket. + /// + /// - parameters: + /// - how: the mode of `Shutdown`. + /// - throws: An `IOError` if the operation failed. + func shutdown(how: Shutdown) throws { + return try withUnsafeHandle { + try NIOBSDSocket.shutdown(socket: $0, how: how) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketChannel.swift new file mode 100644 index 00000000..7e9eca34 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketChannel.swift @@ -0,0 +1,927 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +#if os(Windows) +import let WinSDK.ECONNABORTED +import let WinSDK.ECONNREFUSED +import let WinSDK.EMFILE +import let WinSDK.ENFILE +import let WinSDK.ENOBUFS +import let WinSDK.ENOMEM +#endif + +extension ByteBuffer { + mutating func withMutableWritePointer(body: (UnsafeMutableRawBufferPointer) throws -> IOResult) rethrows -> IOResult { + var singleResult: IOResult! + _ = try self.writeWithUnsafeMutableBytes(minimumWritableBytes: 0) { ptr in + let localWriteResult = try body(ptr) + singleResult = localWriteResult + switch localWriteResult { + case .processed(let written): + return written + case .wouldBlock(let written): + return written + } + } + return singleResult + } +} + +/// A `Channel` for a client socket. +/// +/// - note: All operations on `SocketChannel` are thread-safe. +final class SocketChannel: BaseStreamSocketChannel { + private var connectTimeout: TimeAmount? = nil + + init(eventLoop: SelectableEventLoop, protocolFamily: NIOBSDSocket.ProtocolFamily) throws { + let socket = try Socket(protocolFamily: protocolFamily, type: .stream, setNonBlocking: true) + try super.init(socket: socket, parent: nil, eventLoop: eventLoop, recvAllocator: AdaptiveRecvByteBufferAllocator()) + } + + init(eventLoop: SelectableEventLoop, socket: NIOBSDSocket.Handle) throws { + let sock = try Socket(socket: socket, setNonBlocking: true) + try super.init(socket: sock, parent: nil, eventLoop: eventLoop, recvAllocator: AdaptiveRecvByteBufferAllocator()) + } + + init(socket: Socket, parent: Channel? = nil, eventLoop: SelectableEventLoop) throws { + try super.init(socket: socket, parent: parent, eventLoop: eventLoop, recvAllocator: AdaptiveRecvByteBufferAllocator()) + } + + override func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.ConnectTimeoutOption: + connectTimeout = value as? TimeAmount + default: + try super.setOption0(option, value: value) + } + } + + override func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.ConnectTimeoutOption: + return connectTimeout as! Option.Value + default: + return try super.getOption0(option) + } + } + + func registrationFor(interested: SelectorEventSet, registrationID: SelectorRegistrationID) -> NIORegistration { + return NIORegistration(channel: .socketChannel(self), + interested: interested, + registrationID: registrationID) + } + + override func connectSocket(to address: SocketAddress) throws -> Bool { + if try self.socket.connect(to: address) { + return true + } + if let timeout = connectTimeout { + connectTimeoutScheduled = eventLoop.scheduleTask(in: timeout) { () -> Void in + if self.pendingConnect != nil { + // The connection was still not established, close the Channel which will also fail the pending promise. + self.close0(error: ChannelError.connectTimeout(timeout), mode: .all, promise: nil) + } + } + } + + return false + } + + override func finishConnectSocket() throws { + if let scheduled = self.connectTimeoutScheduled { + // Connection established so cancel the previous scheduled timeout. + self.connectTimeoutScheduled = nil + scheduled.cancel() + } + try self.socket.finishConnect() + } + + + override func register(selector: Selector, interested: SelectorEventSet) throws { + try selector.register(selectable: self.socket, + interested: interested, + makeRegistration: self.registrationFor) + } + + override func deregister(selector: Selector, mode: CloseMode) throws { + assert(mode == .all) + try selector.deregister(selectable: self.socket) + } + + override func reregister(selector: Selector, interested: SelectorEventSet) throws { + try selector.reregister(selectable: self.socket, interested: interested) + } +} + +/// A `Channel` for a server socket. +/// +/// - note: All operations on `ServerSocketChannel` are thread-safe. +final class ServerSocketChannel: BaseSocketChannel { + + private var backlog: Int32 = 128 + private let group: EventLoopGroup + + /// The server socket channel is never writable. + // This is `Channel` API so must be thread-safe. + override public var isWritable: Bool { return false } + + convenience init(eventLoop: SelectableEventLoop, group: EventLoopGroup, protocolFamily: NIOBSDSocket.ProtocolFamily) throws { + try self.init(serverSocket: try ServerSocket(protocolFamily: protocolFamily, setNonBlocking: true), eventLoop: eventLoop, group: group) + } + + init(serverSocket: ServerSocket, eventLoop: SelectableEventLoop, group: EventLoopGroup) throws { + self.group = group + try super.init(socket: serverSocket, + parent: nil, + eventLoop: eventLoop, + recvAllocator: AdaptiveRecvByteBufferAllocator()) + } + + convenience init(socket: NIOBSDSocket.Handle, eventLoop: SelectableEventLoop, group: EventLoopGroup) throws { + let sock = try ServerSocket(socket: socket, setNonBlocking: true) + try self.init(serverSocket: sock, eventLoop: eventLoop, group: group) + try self.socket.listen(backlog: backlog) + } + + func registrationFor(interested: SelectorEventSet, registrationID: SelectorRegistrationID) -> NIORegistration { + return NIORegistration(channel: .serverSocketChannel(self), + interested: interested, + registrationID: registrationID) + } + + override func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.BacklogOption: + backlog = value as! Int32 + default: + try super.setOption0(option, value: value) + } + } + + override func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.BacklogOption: + return backlog as! Option.Value + default: + return try super.getOption0(option) + } + } + + override public func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + guard self.isOpen else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + guard self.isRegistered else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + + let p = eventLoop.makePromise(of: Void.self) + p.futureResult.map { + // It's important to call the methods before we actually notify the original promise for ordering reasons. + self.becomeActive0(promise: promise) + }.whenFailure{ error in + promise?.fail(error) + } + executeAndComplete(p) { + try socket.bind(to: address) + self.updateCachedAddressesFromSocket(updateRemote: false) + try self.socket.listen(backlog: backlog) + } + } + + override func connectSocket(to address: SocketAddress) throws -> Bool { + throw ChannelError.operationUnsupported + } + + override func finishConnectSocket() throws { + throw ChannelError.operationUnsupported + } + + override func readFromSocket() throws -> ReadResult { + var result = ReadResult.none + for _ in 1...maxMessagesPerRead { + guard self.isOpen else { + throw ChannelError.eof + } + if let accepted = try self.socket.accept(setNonBlocking: true) { + readPending = false + result = .some + do { + let chan = try SocketChannel(socket: accepted, + parent: self, + eventLoop: group.next() as! SelectableEventLoop) + assert(self.isActive) + self.pipeline.syncOperations.fireChannelRead(NIOAny(chan)) + } catch { + try? accepted.close() + throw error + } + } else { + break + } + } + return result + } + + override func shouldCloseOnReadError(_ err: Error) -> Bool { + if err is NIOFcntlFailedError { + // See: + // - https://github.com/apple/swift-nio/issues/1030 + // - https://github.com/apple/swift-nio/issues/1598 + // on Darwin, fcntl(fd, F_SETFL, O_NONBLOCK) or fcntl(fd, F_SETNOSIGPIPE) + // sometimes returns EINVAL... + return false + } + guard let err = err as? IOError else { return true } + + switch err.errnoCode { + case ECONNABORTED, + EMFILE, + ENFILE, + ENOBUFS, + ENOMEM: + // These are errors we may be able to recover from. The user may just want to stop accepting connections for example + // or provide some other means of back-pressure. This could be achieved by a custom ChannelDuplexHandler. + return false + default: + return true + } + } + + override func cancelWritesOnClose(error: Error) { + // No writes to cancel. + return + } + + override public func channelRead0(_ data: NIOAny) { + self.eventLoop.assertInEventLoop() + + let ch = self.unwrapData(data, as: SocketChannel.self) + ch.eventLoop.execute { + ch.register().flatMapThrowing { + guard ch.isOpen else { + throw ChannelError.ioOnClosedChannel + } + ch.becomeActive0(promise: nil) + }.whenFailure { error in + ch.close(promise: nil) + } + } + } + + override func hasFlushedPendingWrites() -> Bool { + return false + } + + override func bufferPendingWrite(data: NIOAny, promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + override func markFlushPoint() { + // We do nothing here: flushes are no-ops. + } + + override func flushNow() -> IONotificationState { + return IONotificationState.unregister + } + + override func register(selector: Selector, interested: SelectorEventSet) throws { + try selector.register(selectable: self.socket, + interested: interested, + makeRegistration: self.registrationFor) + } + + override func deregister(selector: Selector, mode: CloseMode) throws { + assert(mode == .all) + try selector.deregister(selectable: self.socket) + } + + override func reregister(selector: Selector, interested: SelectorEventSet) throws { + try selector.reregister(selectable: self.socket, interested: interested) + } +} + +/// A channel used with datagram sockets. +/// +/// Currently, it does not support connected mode which is well worth adding. +final class DatagramChannel: BaseSocketChannel { + private var reportExplicitCongestionNotifications = false + private var receivePacketInfo = false + + // Guard against re-entrance of flushNow() method. + private let pendingWrites: PendingDatagramWritesManager + + /// Support for vector reads, if enabled. + private var vectorReadManager: Optional + // This is `Channel` API so must be thread-safe. + override public var isWritable: Bool { + return pendingWrites.isWritable + } + + override var isOpen: Bool { + self.eventLoop.assertInEventLoop() + assert(super.isOpen == self.pendingWrites.isOpen) + return super.isOpen + } + + convenience init(eventLoop: SelectableEventLoop, socket: NIOBSDSocket.Handle) throws { + let socket = try Socket(socket: socket) + + do { + try self.init(socket: socket, eventLoop: eventLoop) + } catch { + try? socket.close() + throw error + } + } + + deinit { + if var vectorReadManager = self.vectorReadManager { + vectorReadManager.deallocate() + } + } + + init(eventLoop: SelectableEventLoop, protocolFamily: NIOBSDSocket.ProtocolFamily) throws { + self.vectorReadManager = nil + let socket = try Socket(protocolFamily: protocolFamily, type: .datagram) + do { + try socket.setNonBlocking() + } catch let err { + try? socket.close() + throw err + } + + self.pendingWrites = PendingDatagramWritesManager(msgs: eventLoop.msgs, + iovecs: eventLoop.iovecs, + addresses: eventLoop.addresses, + storageRefs: eventLoop.storageRefs, + controlMessageStorage: eventLoop.controlMessageStorage) + + try super.init(socket: socket, + parent: nil, + eventLoop: eventLoop, + recvAllocator: FixedSizeRecvByteBufferAllocator(capacity: 2048)) + } + + init(socket: Socket, parent: Channel? = nil, eventLoop: SelectableEventLoop) throws { + self.vectorReadManager = nil + try socket.setNonBlocking() + self.pendingWrites = PendingDatagramWritesManager(msgs: eventLoop.msgs, + iovecs: eventLoop.iovecs, + addresses: eventLoop.addresses, + storageRefs: eventLoop.storageRefs, + controlMessageStorage: eventLoop.controlMessageStorage) + try super.init(socket: socket, parent: parent, eventLoop: eventLoop, recvAllocator: FixedSizeRecvByteBufferAllocator(capacity: 2048)) + } + + // MARK: Datagram Channel overrides required by BaseSocketChannel + + override func setOption0(_ option: Option, value: Option.Value) throws { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.WriteSpinOption: + pendingWrites.writeSpinCount = value as! UInt + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + pendingWrites.waterMark = value as! ChannelOptions.Types.WriteBufferWaterMark + case _ as ChannelOptions.Types.DatagramVectorReadMessageCountOption: + // We only support vector reads on these OSes. Let us know if there's another OS with this syscall! + #if os(Linux) || os(FreeBSD) || os(Android) + self.vectorReadManager.updateMessageCount(value as! Int) + #else + break + #endif + case _ as ChannelOptions.Types.ExplicitCongestionNotificationsOption: + let valueAsInt: CInt = value as! Bool ? 1 : 0 + switch self.localAddress?.protocol { + case .some(.inet): + self.reportExplicitCongestionNotifications = true + try self.socket.setOption(level: .ip, + name: .ip_recv_tos, + value: valueAsInt) + case .some(.inet6): + self.reportExplicitCongestionNotifications = true + try self.socket.setOption(level: .ipv6, + name: .ipv6_recv_tclass, + value: valueAsInt) + default: + // Explicit congestion notification is only supported for IP + throw ChannelError.operationUnsupported + } + case _ as ChannelOptions.Types.ReceivePacketInfo: + let valueAsInt: CInt = value as! Bool ? 1 : 0 + switch self.localAddress?.protocol { + case .some(.inet): + self.receivePacketInfo = true + try self.socket.setOption(level: .ip, + name: .ip_recv_pktinfo, + value: valueAsInt) + case .some(.inet6): + self.receivePacketInfo = true + try self.socket.setOption(level: .ipv6, + name: .ipv6_recv_pktinfo, + value: valueAsInt) + default: + // Receiving packet info is only supported for IP + throw ChannelError.operationUnsupported + } + break + default: + try super.setOption0(option, value: value) + } + } + + override func getOption0(_ option: Option) throws -> Option.Value { + self.eventLoop.assertInEventLoop() + + guard isOpen else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.WriteSpinOption: + return pendingWrites.writeSpinCount as! Option.Value + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + return pendingWrites.waterMark as! Option.Value + case _ as ChannelOptions.Types.DatagramVectorReadMessageCountOption: + return (self.vectorReadManager?.messageCount ?? 0) as! Option.Value + case _ as ChannelOptions.Types.ExplicitCongestionNotificationsOption: + switch self.localAddress?.protocol { + case .some(.inet): + return try (self.socket.getOption(level: .ip, + name: .ip_recv_tos) != 0) as! Option.Value + case .some(.inet6): + return try (self.socket.getOption(level: .ipv6, + name: .ipv6_recv_tclass) != 0) as! Option.Value + default: + // Explicit congestion notification is only supported for IP + throw ChannelError.operationUnsupported + } + case _ as ChannelOptions.Types.ReceivePacketInfo: + switch self.localAddress?.protocol { + case .some(.inet): + return try (self.socket.getOption(level: .ip, + name: .ip_recv_pktinfo) != 0) as! Option.Value + case .some(.inet6): + return try (self.socket.getOption(level: .ipv6, + name: .ipv6_recv_pktinfo) != 0) as! Option.Value + default: + // Receiving packet info is only supported for IP + throw ChannelError.operationUnsupported + } + default: + return try super.getOption0(option) + } + } + + func registrationFor(interested: SelectorEventSet, registrationID: SelectorRegistrationID) -> NIORegistration { + return NIORegistration(channel: .datagramChannel(self), + interested: interested, + registrationID: registrationID) + } + + override func connectSocket(to address: SocketAddress) throws -> Bool { + // For now we don't support operating in connected mode for datagram channels. + throw ChannelError.operationUnsupported + } + + override func finishConnectSocket() throws { + // For now we don't support operating in connected mode for datagram channels. + throw ChannelError.operationUnsupported + } + + override func readFromSocket() throws -> ReadResult { + if self.vectorReadManager != nil { + return try self.vectorReadFromSocket() + } else { + return try self.singleReadFromSocket() + } + } + + private func singleReadFromSocket() throws -> ReadResult { + var rawAddress = sockaddr_storage() + var rawAddressLength = socklen_t(MemoryLayout.size) + var buffer = self.recvAllocator.buffer(allocator: self.allocator) + var readResult = ReadResult.none + + // These control bytes must not escape the current call stack + let controlBytesBuffer: UnsafeMutableRawBufferPointer + if self.reportExplicitCongestionNotifications || self.receivePacketInfo { + controlBytesBuffer = self.selectableEventLoop.controlMessageStorage[0] + } else { + controlBytesBuffer = UnsafeMutableRawBufferPointer(start: nil, count: 0) + } + + for i in 1...self.maxMessagesPerRead { + guard self.isOpen else { + throw ChannelError.eof + } + buffer.clear() + + var controlBytes = UnsafeReceivedControlBytes(controlBytesBuffer: controlBytesBuffer) + + let result = try buffer.withMutableWritePointer { + try self.socket.recvmsg(pointer: $0, + storage: &rawAddress, + storageLen: &rawAddressLength, + controlBytes: &controlBytes) + } + switch result { + case .processed(let bytesRead): + assert(bytesRead > 0) + assert(self.isOpen) + let mayGrow = recvAllocator.record(actualReadBytes: bytesRead) + readPending = false + + let metadata: AddressedEnvelope.Metadata? + if self.reportExplicitCongestionNotifications || self.receivePacketInfo, + let controlMessagesReceived = controlBytes.receivedControlMessages { + metadata = .init(from: controlMessagesReceived) + } else { + metadata = nil + } + + let msg = AddressedEnvelope(remoteAddress: rawAddress.convert(), + data: buffer, + metadata: metadata) + assert(self.isActive) + self.pipeline.syncOperations.fireChannelRead(NIOAny(msg)) + if mayGrow && i < maxMessagesPerRead { + buffer = recvAllocator.buffer(allocator: allocator) + } + readResult = .some + case .wouldBlock(let bytesRead): + assert(bytesRead == 0) + return readResult + } + } + return readResult + } + + private func vectorReadFromSocket() throws -> ReadResult { + #if os(Linux) || os(FreeBSD) || os(Android) + var buffer = self.recvAllocator.buffer(allocator: self.allocator) + var readResult = ReadResult.none + + readLoop: for i in 1...self.maxMessagesPerRead { + guard self.isOpen else { + throw ChannelError.eof + } + guard let vectorReadManager = self.vectorReadManager else { + // The vector read manager went away. This happens if users unset the vector read manager + // during channelRead. It's unlikely, but we tolerate it by aborting the read early. + break readLoop + } + buffer.clear() + + // This force-unwrap is safe, as we checked whether this is nil in the caller. + let result = try vectorReadManager.readFromSocket( + socket: self.socket, + buffer: &buffer, + parseControlMessages: self.reportExplicitCongestionNotifications || self.receivePacketInfo) + switch result { + case .some(let results, let totalRead): + assert(self.isOpen) + assert(self.isActive) + + let mayGrow = recvAllocator.record(actualReadBytes: totalRead) + readPending = false + + var messageIterator = results.makeIterator() + while self.isActive, let message = messageIterator.next() { + pipeline.fireChannelRead(NIOAny(message)) + } + + if mayGrow && i < maxMessagesPerRead { + buffer = recvAllocator.buffer(allocator: allocator) + } + readResult = .some + case .none: + break readLoop + } + } + + return readResult + #else + fatalError("Cannot perform vector reads on this operating system") + #endif + } + + override func shouldCloseOnReadError(_ err: Error) -> Bool { + guard let err = err as? IOError else { return true } + + switch err.errnoCode { + // ECONNREFUSED can happen on linux if the previous sendto(...) failed. + // See also: + // - https://bugzilla.redhat.com/show_bug.cgi?id=1375 + // - https://lists.gt.net/linux/kernel/39575 + case ECONNREFUSED, + ENOMEM: + // These are errors we may be able to recover from. + return false + default: + return true + } + } + /// Buffer a write in preparation for a flush. + override func bufferPendingWrite(data: NIOAny, promise: EventLoopPromise?) { + let data = self.unwrapData(data, as: AddressedEnvelope.self) + + if !self.pendingWrites.add(envelope: data, promise: promise) { + assert(self.isActive) + self.pipeline.syncOperations.fireChannelWritabilityChanged() + } + } + + override final func hasFlushedPendingWrites() -> Bool { + return self.pendingWrites.isFlushPending + } + + /// Mark a flush point. This is called when flush is received, and instructs + /// the implementation to record the flush. + override func markFlushPoint() { + // Even if writable() will be called later by the EventLoop we still need to mark the flush checkpoint so we are sure all the flushed messages + // are actually written once writable() is called. + self.pendingWrites.markFlushCheckpoint() + } + + /// Called when closing, to instruct the specific implementation to discard all pending + /// writes. + override func cancelWritesOnClose(error: Error) { + self.pendingWrites.failAll(error: error, close: true) + } + + override func writeToSocket() throws -> OverallWriteResult { + let result = try self.pendingWrites.triggerAppropriateWriteOperations( + scalarWriteOperation: { (ptr, destinationPtr, destinationSize, metadata) in + guard ptr.count > 0 else { + // No need to call write if the buffer is empty. + return .processed(0) + } + // normal write + // Control bytes must not escape current stack. + var controlBytes = UnsafeOutboundControlBytes( + controlBytes: self.selectableEventLoop.controlMessageStorage[0]) + controlBytes.appendExplicitCongestionState(metadata: metadata, + protocolFamily: self.localAddress?.protocol) + return try self.socket.sendmsg(pointer: ptr, + destinationPtr: destinationPtr, + destinationSize: destinationSize, + controlBytes: controlBytes.validControlBytes) + + }, + vectorWriteOperation: { msgs in + return try self.socket.sendmmsg(msgs: msgs) + } + ) + return result + } + + + // MARK: Datagram Channel overrides not required by BaseSocketChannel + + override func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + guard self.isRegistered else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + do { + try socket.bind(to: address) + self.updateCachedAddressesFromSocket(updateRemote: false) + becomeActive0(promise: promise) + } catch let err { + promise?.fail(err) + } + } + + override func register(selector: Selector, interested: SelectorEventSet) throws { + try selector.register(selectable: self.socket, + interested: interested, + makeRegistration: self.registrationFor) + } + + override func deregister(selector: Selector, mode: CloseMode) throws { + assert(mode == .all) + try selector.deregister(selectable: self.socket) + } + + override func reregister(selector: Selector, interested: SelectorEventSet) throws { + try selector.reregister(selectable: self.socket, interested: interested) + } +} + +extension SocketChannel: CustomStringConvertible { + var description: String { + return "SocketChannel { \(self.socketDescription), active = \(self.isActive), localAddress = \(self.localAddress.debugDescription), remoteAddress = \(self.remoteAddress.debugDescription) }" + } +} + +extension ServerSocketChannel: CustomStringConvertible { + var description: String { + return "ServerSocketChannel { \(self.socketDescription), active = \(self.isActive), localAddress = \(self.localAddress.debugDescription), remoteAddress = \(self.remoteAddress.debugDescription) }" + } +} + +extension DatagramChannel: CustomStringConvertible { + var description: String { + return "DatagramChannel { \(self.socketDescription), active = \(self.isActive), localAddress = \(self.localAddress.debugDescription), remoteAddress = \(self.remoteAddress.debugDescription) }" + } +} + +extension DatagramChannel: MulticastChannel { + /// The socket options for joining and leaving multicast groups are very similar. + /// This enum allows us to write a single function to do all the work, and then + /// at the last second pull out the correct socket option name. + private enum GroupOperation { + /// Join a multicast group. + case join + + /// Leave a multicast group. + case leave + + /// Given a socket option level, returns the appropriate socket option name for + /// this group operation. + /// + /// - parameters: + /// - level: The socket option level. Must be one of `IPPROTO_IP` or + /// `IPPROTO_IPV6`. Will trap if an invalid value is provided. + /// - returns: The socket option name to use for this group operation. + func optionName(level: NIOBSDSocket.OptionLevel) -> NIOBSDSocket.Option { + switch (self, level) { + case (.join, .ip): + return .ip_add_membership + case (.leave, .ip): + return .ip_drop_membership + case (.join, .ipv6): + return .ipv6_join_group + case (.leave, .ipv6): + return .ipv6_leave_group + default: + preconditionFailure("Unexpected socket option level: \(level)") + } + } + } + +#if !os(Windows) + @available(*, deprecated, renamed: "joinGroup(_:device:promise:)") + func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + self.performGroupOperation0(group, device: interface.map { NIONetworkDevice($0) }, promise: promise, operation: .join) + } else { + eventLoop.execute { + self.performGroupOperation0(group, device: interface.map { NIONetworkDevice($0) }, promise: promise, operation: .join) + } + } + } + + @available(*, deprecated, renamed: "leaveGroup(_:device:promise:)") + func leaveGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + self.performGroupOperation0(group, device: interface.map { NIONetworkDevice($0) }, promise: promise, operation: .leave) + } else { + eventLoop.execute { + self.performGroupOperation0(group, device: interface.map { NIONetworkDevice($0) }, promise: promise, operation: .leave) + } + } + } +#endif + + func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + self.performGroupOperation0(group, device: device, promise: promise, operation: .join) + } else { + eventLoop.execute { + self.performGroupOperation0(group, device: device, promise: promise, operation: .join) + } + } + } + + func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise?) { + if eventLoop.inEventLoop { + self.performGroupOperation0(group, device: device, promise: promise, operation: .leave) + } else { + eventLoop.execute { + self.performGroupOperation0(group, device: device, promise: promise, operation: .leave) + } + } + } + + /// The implementation of `joinGroup` and `leaveGroup`. + /// + /// Joining and leaving a multicast group ultimately corresponds to a single, carefully crafted, socket option. + private func performGroupOperation0(_ group: SocketAddress, + device: NIONetworkDevice?, + promise: EventLoopPromise?, + operation: GroupOperation) { + self.eventLoop.assertInEventLoop() + + guard self.isActive else { + promise?.fail(ChannelError.inappropriateOperationForState) + return + } + + // Check if the device supports multicast + if let device = device { + guard device.multicastSupported else { + promise?.fail(NIOMulticastNotSupportedError(device: device)) + return + } + } + + // We need to check that we have the appropriate address types in all cases. They all need to overlap with + // the address type of this channel, or this cannot work. + guard let localAddress = self.localAddress else { + promise?.fail(ChannelError.unknownLocalAddress) + return + } + + guard localAddress.protocol == group.protocol else { + promise?.fail(ChannelError.badMulticastGroupAddressFamily) + return + } + + // Ok, now we need to check that the group we've been asked to join is actually a multicast group. + guard group.isMulticast else { + promise?.fail(ChannelError.illegalMulticastAddress(group)) + return + } + + // Ok, we now have reason to believe this will actually work. We need to pass this on to the socket. + do { + switch (group, device?.address) { + case (.unixDomainSocket, _): + preconditionFailure("Should not be reachable, UNIX sockets are never multicast addresses") + case (.v4(let groupAddress), .some(.v4(let interfaceAddress))): + // IPv4Binding with specific target interface. + let multicastRequest = ip_mreq(imr_multiaddr: groupAddress.address.sin_addr, imr_interface: interfaceAddress.address.sin_addr) + try self.socket.setOption(level: .ip, name: operation.optionName(level: .ip), value: multicastRequest) + case (.v4(let groupAddress), .none): + // IPv4 binding without target interface. + let multicastRequest = ip_mreq(imr_multiaddr: groupAddress.address.sin_addr, imr_interface: in_addr(s_addr: INADDR_ANY)) + try self.socket.setOption(level: .ip, name: operation.optionName(level: .ip), value: multicastRequest) + case (.v6(let groupAddress), .some(.v6)): + // IPv6 binding with specific target interface. + let multicastRequest = ipv6_mreq(ipv6mr_multiaddr: groupAddress.address.sin6_addr, ipv6mr_interface: UInt32(device!.interfaceIndex)) + try self.socket.setOption(level: .ipv6, name: operation.optionName(level: .ipv6), value: multicastRequest) + case (.v6(let groupAddress), .none): + // IPv6 binding with no specific interface requested. + let multicastRequest = ipv6_mreq(ipv6mr_multiaddr: groupAddress.address.sin6_addr, ipv6mr_interface: 0) + try self.socket.setOption(level: .ipv6, name: operation.optionName(level: .ipv6), value: multicastRequest) + case (.v4, .some(.v6)), (.v6, .some(.v4)), (.v4, .some(.unixDomainSocket)), (.v6, .some(.unixDomainSocket)): + // Mismatched group and interface address: this is an error. + throw ChannelError.badInterfaceAddressFamily + } + + promise?.succeed(()) + } catch { + promise?.fail(error) + return + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketProtocols.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketProtocols.swift new file mode 100644 index 00000000..bd3e86de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/SocketProtocols.swift @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore + +protocol BaseSocketProtocol: CustomStringConvertible { + associatedtype SelectableType: Selectable + + var isOpen: Bool { get } + + func close() throws + + func bind(to address: SocketAddress) throws + + func localAddress() throws -> SocketAddress + + func remoteAddress() throws -> SocketAddress + + func setOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option, value: T) throws + + func getOption(level: NIOBSDSocket.OptionLevel, name: NIOBSDSocket.Option) throws -> T +} + +protocol ServerSocketProtocol: BaseSocketProtocol { + func listen(backlog: Int32) throws + + func accept(setNonBlocking: Bool) throws -> Socket? +} + +protocol SocketProtocol: BaseSocketProtocol { + func connect(to address: SocketAddress) throws -> Bool + + func finishConnect() throws + + func write(pointer: UnsafeRawBufferPointer) throws -> IOResult + + func writev(iovecs: UnsafeBufferPointer) throws -> IOResult + + func read(pointer: UnsafeMutableRawBufferPointer) throws -> IOResult + + func recvmsg(pointer: UnsafeMutableRawBufferPointer, + storage: inout sockaddr_storage, + storageLen: inout socklen_t, + controlBytes: inout UnsafeReceivedControlBytes) throws -> IOResult + + func sendmsg(pointer: UnsafeRawBufferPointer, + destinationPtr: UnsafePointer, + destinationSize: socklen_t, + controlBytes: UnsafeMutableRawBufferPointer) throws -> IOResult + + func sendFile(fd: CInt, offset: Int, count: Int) throws -> IOResult + + func recvmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult + + func sendmmsg(msgs: UnsafeMutableBufferPointer) throws -> IOResult + + func shutdown(how: Shutdown) throws + + func ignoreSIGPIPE() throws +} + +#if os(Linux) || os(Android) +// This is a lazily initialised global variable that when read for the first time, will ignore SIGPIPE. +private let globallyIgnoredSIGPIPE: Bool = { + /* no F_SETNOSIGPIPE on Linux :( */ + _ = Glibc.signal(SIGPIPE, SIG_IGN) + return true +}() +#endif + +extension BaseSocketProtocol { + // used by `BaseSocket` and `PipePair`. + internal static func ignoreSIGPIPE(descriptor fd: CInt) throws { + #if os(Linux) || os(Android) + let haveWeIgnoredSIGPIEThisIsHereToTriggerIgnoringIt = globallyIgnoredSIGPIPE + guard haveWeIgnoredSIGPIEThisIsHereToTriggerIgnoringIt else { + fatalError("BUG in NIO. We did not ignore SIGPIPE, this code path should definitely not be reachable.") + } + #elseif os(Windows) + // Deliberately empty: SIGPIPE just ain't a thing on Windows + #else + assert(fd >= 0, "illegal file descriptor \(fd)") + do { + try Posix.fcntl(descriptor: fd, command: F_SETNOSIGPIPE, value: 1) + } catch let error as IOError { + if error.errnoCode == EINVAL { + // Darwin seems to sometimes do this despite the docs claiming it can't happen + throw NIOFcntlFailedError() + } + try? Posix.close(descriptor: fd) // don't care about failure here + throw error + } + #endif + } + + internal static func ignoreSIGPIPE(socket handle: NIOBSDSocket.Handle) throws { + #if os(Windows) + // Deliberately empty: SIGPIPE just ain't a thing on Windows + #else + try ignoreSIGPIPE(descriptor: handle) + #endif + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/System.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/System.swift new file mode 100644 index 00000000..9c53662d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/System.swift @@ -0,0 +1,658 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +// This file contains code that ensures errno is captured correctly when doing syscalls and no ARC traffic can happen inbetween that *could* change the errno +// value before we were able to read it. +// It's important that all static methods are declared with `@inline(never)` so it's not possible any ARC traffic happens while we need to read errno. + +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +@_exported import Darwin.C +import CNIODarwin +internal typealias MMsgHdr = CNIODarwin_mmsghdr +#elseif os(Linux) || os(FreeBSD) || os(Android) +@_exported import Glibc +import CNIOLinux +internal typealias MMsgHdr = CNIOLinux_mmsghdr +internal typealias in6_pktinfo = CNIOLinux_in6_pktinfo +#elseif os(Windows) +import CNIOWindows +internal typealias sockaddr = WinSDK.SOCKADDR +internal typealias MMsgHdr = CNIOWindows_mmsghdr +#else +let badOS = { fatalError("unsupported OS") }() +#endif + +#if os(Android) +let INADDR_ANY = UInt32(0) // #define INADDR_ANY ((unsigned long int) 0x00000000) +let IFF_BROADCAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_BROADCAST.rawValue) +let IFF_POINTOPOINT: CUnsignedInt = numericCast(SwiftGlibc.IFF_POINTOPOINT.rawValue) +let IFF_MULTICAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_MULTICAST.rawValue) +internal typealias in_port_t = UInt16 +extension ipv6_mreq { // http://lkml.iu.edu/hypermail/linux/kernel/0106.1/0080.html + init (ipv6mr_multiaddr: in6_addr, ipv6mr_interface: UInt32) { + self.init(ipv6mr_multiaddr: ipv6mr_multiaddr, + ipv6mr_ifindex: Int32(bitPattern: ipv6mr_interface)) + } +} +#if arch(arm) +let S_IFSOCK = UInt32(SwiftGlibc.S_IFSOCK) +let S_IFMT = UInt32(SwiftGlibc.S_IFMT) +let S_IFREG = UInt32(SwiftGlibc.S_IFREG) +let S_IFDIR = UInt32(SwiftGlibc.S_IFDIR) +let S_IFLNK = UInt32(SwiftGlibc.S_IFLNK) +let S_IFBLK = UInt32(SwiftGlibc.S_IFBLK) +#endif +#endif + +// Declare aliases to share more code and not need to repeat #if #else blocks +#if !os(Windows) +private let sysClose = close +private let sysShutdown = shutdown +private let sysBind = bind +private let sysFcntl: (CInt, CInt, CInt) -> CInt = fcntl +private let sysSocket = socket +private let sysSetsockopt = setsockopt +private let sysGetsockopt = getsockopt +private let sysListen = listen +private let sysAccept = accept +private let sysConnect = connect +private let sysOpen: (UnsafePointer, CInt) -> CInt = open +private let sysOpenWithMode: (UnsafePointer, CInt, mode_t) -> CInt = open +private let sysFtruncate = ftruncate +private let sysWrite = write +private let sysPwrite = pwrite +private let sysRead = read +private let sysPread = pread +private let sysLseek = lseek +private let sysPoll = poll +#endif + +#if os(Android) +func sysRecvFrom_wrapper(sockfd: CInt, buf: UnsafeMutableRawPointer, len: CLong, flags: CInt, src_addr: UnsafeMutablePointer, addrlen: UnsafeMutablePointer) -> CLong { + return recvfrom(sockfd, buf, len, flags, src_addr, addrlen) // src_addr is 'UnsafeMutablePointer', but it need to be 'UnsafePointer' +} +func sysWritev_wrapper(fd: CInt, iov: UnsafePointer?, iovcnt: CInt) -> CLong { + return CLong(writev(fd, iov, iovcnt)) // cast 'Int32' to 'CLong' +} +private let sysWritev = sysWritev_wrapper +#elseif !os(Windows) +private let sysWritev: @convention(c) (Int32, UnsafePointer?, CInt) -> CLong = writev +#endif +#if !os(Windows) +private let sysRecvMsg: @convention(c) (CInt, UnsafeMutablePointer?, CInt) -> ssize_t = recvmsg +private let sysSendMsg: @convention(c) (CInt, UnsafePointer?, CInt) -> ssize_t = sendmsg +#endif +private let sysDup: @convention(c) (CInt) -> CInt = dup +#if !os(Windows) +private let sysGetpeername: @convention(c) (CInt, UnsafeMutablePointer?, UnsafeMutablePointer?) -> CInt = getpeername +private let sysGetsockname: @convention(c) (CInt, UnsafeMutablePointer?, UnsafeMutablePointer?) -> CInt = getsockname +#endif +private let sysFreeifaddrs: @convention(c) (UnsafeMutablePointer?) -> Void = freeifaddrs +private let sysIfNameToIndex: @convention(c) (UnsafePointer?) -> CUnsignedInt = if_nametoindex +#if !os(Windows) +private let sysSocketpair: @convention(c) (CInt, CInt, CInt, UnsafeMutablePointer?) -> CInt = socketpair +#endif + +#if os(Linux) +private let sysFstat: @convention(c) (CInt, UnsafeMutablePointer) -> CInt = fstat +private let sysStat: @convention(c) (UnsafePointer, UnsafeMutablePointer) -> CInt = stat +private let sysUnlink: @convention(c) (UnsafePointer) -> CInt = unlink +#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(Android) +private let sysFstat: @convention(c) (CInt, UnsafeMutablePointer?) -> CInt = fstat +private let sysStat: @convention(c) (UnsafePointer?, UnsafeMutablePointer?) -> CInt = stat +private let sysUnlink: @convention(c) (UnsafePointer?) -> CInt = unlink +#endif +#if os(Linux) || os(Android) +private let sysSendMmsg: @convention(c) (CInt, UnsafeMutablePointer?, CUnsignedInt, CInt) -> CInt = CNIOLinux_sendmmsg +private let sysRecvMmsg: @convention(c) (CInt, UnsafeMutablePointer?, CUnsignedInt, CInt, UnsafeMutablePointer?) -> CInt = CNIOLinux_recvmmsg +#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +private let sysKevent = kevent +private let sysSendMmsg: @convention(c) (CInt, UnsafeMutablePointer?, CUnsignedInt, CInt) -> CInt = CNIODarwin_sendmmsg +private let sysRecvMmsg: @convention(c) (CInt, UnsafeMutablePointer?, CUnsignedInt, CInt, UnsafeMutablePointer?) -> CInt = CNIODarwin_recvmmsg +#endif + +private func isUnacceptableErrno(_ code: Int32) -> Bool { + // On iOS, EBADF is a possible result when a file descriptor has been reaped in the background. + // In particular, it's possible to get EBADF from accept(), where the underlying accept() FD + // is valid but the accepted one is not. The right solution here is to perform a check for + // SO_ISDEFUNCT when we see this happen, but we haven't yet invested the time to do that. + // In the meantime, we just tolerate EBADF on iOS. + #if os(iOS) || os(watchOS) || os(tvOS) + switch code { + case EFAULT: + return true + default: + return false + } + #else + switch code { + case EFAULT, EBADF: + return true + default: + return false + } + #endif +} + +private func isUnacceptableErrnoOnClose(_ code: Int32) -> Bool { + // We treat close() differently to all other FDs: we still want to catch EBADF here. + switch code { + case EFAULT, EBADF: + return true + default: + return false + } +} + +private func isUnacceptableErrnoForbiddingEINVAL(_ code: Int32) -> Bool { + // We treat read() and pread() differently since we also want to catch EINVAL. + #if os(iOS) || os(watchOS) || os(tvOS) + switch code { + case EFAULT, EINVAL: + return true + default: + return false + } + #else + switch code { + case EFAULT, EBADF, EINVAL: + return true + default: + return false + } + #endif +} + +private func preconditionIsNotUnacceptableErrno(err: CInt, where function: String) -> Void { + // strerror is documented to return "Unknown error: ..." for illegal value so it won't ever fail + precondition(!isUnacceptableErrno(err), "unacceptable errno \(err) \(String(cString: strerror(err)!)) in \(function))") +} + +private func preconditionIsNotUnacceptableErrnoOnClose(err: CInt, where function: String) -> Void { + // strerror is documented to return "Unknown error: ..." for illegal value so it won't ever fail + precondition(!isUnacceptableErrnoOnClose(err), "unacceptable errno \(err) \(String(cString: strerror(err)!)) in \(function))") +} + +private func preconditionIsNotUnacceptableErrnoForbiddingEINVAL(err: CInt, where function: String) -> Void { + // strerror is documented to return "Unknown error: ..." for illegal value so it won't ever fail + precondition(!isUnacceptableErrnoForbiddingEINVAL(err), "unacceptable errno \(err) \(String(cString: strerror(err)!)) in \(function))") +} + + +/* + * Sorry, we really try hard to not use underscored attributes. In this case + * however we seem to break the inlining threshold which makes a system call + * take twice the time, ie. we need this exception. + */ +@inline(__always) +@discardableResult +internal func syscall(blocking: Bool, + where function: String = #function, + _ body: () throws -> T) + throws -> IOResult { + while true { + let res = try body() + if res == -1 { + let err = errno + switch (err, blocking) { + case (EINTR, _): + continue + case (EWOULDBLOCK, true): + return .wouldBlock(0) + default: + preconditionIsNotUnacceptableErrno(err: err, where: function) + throw IOError(errnoCode: err, reason: function) + } + } + return .processed(res) + } +} + + +/* + * Sorry, we really try hard to not use underscored attributes. In this case + * however we seem to break the inlining threshold which makes a system call + * take twice the time, ie. we need this exception. + */ +@inline(__always) +@discardableResult +internal func syscallForbiddingEINVAL(where function: String = #function, + _ body: () throws -> T) + throws -> IOResult { + while true { + let res = try body() + if res == -1 { + let err = errno + switch err { + case EINTR: + continue + case EWOULDBLOCK: + return .wouldBlock(0) + default: + preconditionIsNotUnacceptableErrnoForbiddingEINVAL(err: err, where: function) + throw IOError(errnoCode: err, reason: function) + } + } + return .processed(res) + } +} + +internal enum Posix { +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + static let UIO_MAXIOV: Int = 1024 + static let SHUT_RD: CInt = CInt(Darwin.SHUT_RD) + static let SHUT_WR: CInt = CInt(Darwin.SHUT_WR) + static let SHUT_RDWR: CInt = CInt(Darwin.SHUT_RDWR) + static let IPTOS_ECN_NOTECT: CInt = CNIODarwin_IPTOS_ECN_NOTECT + static let IPTOS_ECN_MASK: CInt = CNIODarwin_IPTOS_ECN_MASK + static let IPTOS_ECN_ECT0: CInt = CNIODarwin_IPTOS_ECN_ECT0 + static let IPTOS_ECN_ECT1: CInt = CNIODarwin_IPTOS_ECN_ECT1 + static let IPTOS_ECN_CE: CInt = CNIODarwin_IPTOS_ECN_CE + static let IP_RECVPKTINFO: CInt = CNIODarwin.IP_RECVPKTINFO + static let IP_PKTINFO: CInt = CNIODarwin.IP_PKTINFO + static let IPV6_RECVPKTINFO: CInt = CNIODarwin_IPV6_RECVPKTINFO + static let IPV6_PKTINFO: CInt = CNIODarwin_IPV6_PKTINFO +#elseif os(Linux) || os(FreeBSD) || os(Android) + + static let UIO_MAXIOV: Int = Int(Glibc.UIO_MAXIOV) + static let SHUT_RD: CInt = CInt(Glibc.SHUT_RD) + static let SHUT_WR: CInt = CInt(Glibc.SHUT_WR) + static let SHUT_RDWR: CInt = CInt(Glibc.SHUT_RDWR) + #if os(Android) + static let IPTOS_ECN_NOTECT: CInt = CInt(CNIOLinux.IPTOS_ECN_NOTECT) + #else + static let IPTOS_ECN_NOTECT: CInt = CInt(CNIOLinux.IPTOS_ECN_NOT_ECT) + #endif + static let IPTOS_ECN_MASK: CInt = CInt(CNIOLinux.IPTOS_ECN_MASK) + static let IPTOS_ECN_ECT0: CInt = CInt(CNIOLinux.IPTOS_ECN_ECT0) + static let IPTOS_ECN_ECT1: CInt = CInt(CNIOLinux.IPTOS_ECN_ECT1) + static let IPTOS_ECN_CE: CInt = CInt(CNIOLinux.IPTOS_ECN_CE) + static let IP_RECVPKTINFO: CInt = CInt(CNIOLinux.IP_PKTINFO) + static let IP_PKTINFO: CInt = CInt(CNIOLinux.IP_PKTINFO) + static let IPV6_RECVPKTINFO: CInt = CInt(CNIOLinux.IPV6_RECVPKTINFO) + static let IPV6_PKTINFO: CInt = CInt(CNIOLinux.IPV6_PKTINFO) +#else + static var UIO_MAXIOV: Int { + fatalError("unsupported OS") + } + static var SHUT_RD: Int { + fatalError("unsupported OS") + } + static var SHUT_WR: Int { + fatalError("unsupported OS") + } + static var SHUT_RDWR: Int { + fatalError("unsupported OS") + } +#endif + +#if !os(Windows) + @inline(never) + internal static func shutdown(descriptor: CInt, how: Shutdown) throws { + _ = try syscall(blocking: false) { + sysShutdown(descriptor, how.cValue) + } + } + + @inline(never) + internal static func close(descriptor: CInt) throws { + let res = sysClose(descriptor) + if res == -1 { + let err = errno + + // There is really nothing "sane" we can do when EINTR was reported on close. + // So just ignore it and "assume" everything is fine == we closed the file descriptor. + // + // For more details see: + // - https://bugs.chromium.org/p/chromium/issues/detail?id=269623 + // - https://lwn.net/Articles/576478/ + if err != EINTR { + preconditionIsNotUnacceptableErrnoOnClose(err: err, where: #function) + throw IOError(errnoCode: err, reason: "close") + } + } + } + + @inline(never) + internal static func bind(descriptor: CInt, ptr: UnsafePointer, bytes: Int) throws { + _ = try syscall(blocking: false) { + sysBind(descriptor, ptr, socklen_t(bytes)) + } + } + + @inline(never) + @discardableResult + // TODO: Allow varargs + internal static func fcntl(descriptor: CInt, command: CInt, value: CInt) throws -> CInt { + return try syscall(blocking: false) { + sysFcntl(descriptor, command, value) + }.result + } + + @inline(never) + internal static func socket(domain: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, `protocol`: CInt) throws -> CInt { + return try syscall(blocking: false) { + return sysSocket(domain.rawValue, type.rawValue, `protocol`) + }.result + } + + @inline(never) + internal static func setsockopt(socket: CInt, level: CInt, optionName: CInt, + optionValue: UnsafeRawPointer, optionLen: socklen_t) throws { + _ = try syscall(blocking: false) { + sysSetsockopt(socket, level, optionName, optionValue, optionLen) + } + } + + @inline(never) + internal static func getsockopt(socket: CInt, level: CInt, optionName: CInt, + optionValue: UnsafeMutableRawPointer, + optionLen: UnsafeMutablePointer) throws { + _ = try syscall(blocking: false) { + sysGetsockopt(socket, level, optionName, optionValue, optionLen) + }.result + } + + @inline(never) + internal static func listen(descriptor: CInt, backlog: CInt) throws { + _ = try syscall(blocking: false) { + sysListen(descriptor, backlog) + } + } + + @inline(never) + internal static func accept(descriptor: CInt, + addr: UnsafeMutablePointer?, + len: UnsafeMutablePointer?) throws -> CInt? { + let result: IOResult = try syscall(blocking: true) { + return sysAccept(descriptor, addr, len) + } + + if case .processed(let fd) = result { + return fd + } else { + return nil + } + } + + @inline(never) + internal static func connect(descriptor: CInt, addr: UnsafePointer, size: socklen_t) throws -> Bool { + do { + _ = try syscall(blocking: false) { + sysConnect(descriptor, addr, size) + } + return true + } catch let err as IOError { + if err.errnoCode == EINPROGRESS { + return false + } + throw err + } + } + + @inline(never) + internal static func open(file: UnsafePointer, oFlag: CInt, mode: mode_t) throws -> CInt { + return try syscall(blocking: false) { + sysOpenWithMode(file, oFlag, mode) + }.result + } + + @inline(never) + internal static func open(file: UnsafePointer, oFlag: CInt) throws -> CInt { + return try syscall(blocking: false) { + sysOpen(file, oFlag) + }.result + } + + @inline(never) + @discardableResult + internal static func ftruncate(descriptor: CInt, size: off_t) throws -> CInt { + return try syscall(blocking: false) { + sysFtruncate(descriptor, size) + }.result + } + + @inline(never) + internal static func write(descriptor: CInt, pointer: UnsafeRawPointer, size: Int) throws -> IOResult { + return try syscall(blocking: true) { + sysWrite(descriptor, pointer, size) + } + } + + @inline(never) + internal static func pwrite(descriptor: CInt, pointer: UnsafeRawPointer, size: Int, offset: off_t) throws -> IOResult { + return try syscall(blocking: true) { + sysPwrite(descriptor, pointer, size, offset) + } + } + +#if !os(Windows) + @inline(never) + internal static func writev(descriptor: CInt, iovecs: UnsafeBufferPointer) throws -> IOResult { + return try syscall(blocking: true) { + sysWritev(descriptor, iovecs.baseAddress!, CInt(iovecs.count)) + } + } +#endif + + @inline(never) + internal static func read(descriptor: CInt, pointer: UnsafeMutableRawPointer, size: size_t) throws -> IOResult { + return try syscallForbiddingEINVAL { + sysRead(descriptor, pointer, size) + } + } + + @inline(never) + internal static func pread(descriptor: CInt, pointer: UnsafeMutableRawPointer, size: size_t, offset: off_t) throws -> IOResult { + return try syscallForbiddingEINVAL { + sysPread(descriptor, pointer, size, offset) + } + } + + @inline(never) + internal static func recvmsg(descriptor: CInt, msgHdr: UnsafeMutablePointer, flags: CInt) throws -> IOResult { + return try syscall(blocking: true) { + sysRecvMsg(descriptor, msgHdr, flags) + } + } + + @inline(never) + internal static func sendmsg(descriptor: CInt, msgHdr: UnsafePointer, flags: CInt) throws -> IOResult { + return try syscall(blocking: true) { + sysSendMsg(descriptor, msgHdr, flags) + } + } + + @discardableResult + @inline(never) + internal static func lseek(descriptor: CInt, offset: off_t, whence: CInt) throws -> off_t { + return try syscall(blocking: false) { + sysLseek(descriptor, offset, whence) + }.result + } +#endif + + @discardableResult + @inline(never) + internal static func dup(descriptor: CInt) throws -> CInt { + return try syscall(blocking: false) { + sysDup(descriptor) + }.result + } + +#if !os(Windows) + // It's not really posix but exists on Linux and MacOS / BSD so just put it here for now to keep it simple + @inline(never) + internal static func sendfile(descriptor: CInt, fd: CInt, offset: off_t, count: size_t) throws -> IOResult { + var written: off_t = 0 + do { + _ = try syscall(blocking: false) { () -> ssize_t in + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + var w: off_t = off_t(count) + let result: CInt = Darwin.sendfile(fd, descriptor, offset, &w, nil, 0) + written = w + return ssize_t(result) + #elseif os(Linux) || os(FreeBSD) || os(Android) + var off: off_t = offset + let result: ssize_t = Glibc.sendfile(descriptor, fd, &off, count) + if result >= 0 { + written = off_t(result) + } else { + written = 0 + } + return result + #else + fatalError("unsupported OS") + #endif + } + return .processed(Int(written)) + } catch let err as IOError { + if err.errnoCode == EAGAIN { + return .wouldBlock(Int(written)) + } + throw err + } + } + + @inline(never) + internal static func sendmmsg(sockfd: CInt, msgvec: UnsafeMutablePointer, vlen: CUnsignedInt, flags: CInt) throws -> IOResult { + return try syscall(blocking: true) { + Int(sysSendMmsg(sockfd, msgvec, vlen, flags)) + } + } + + @inline(never) + internal static func recvmmsg(sockfd: CInt, msgvec: UnsafeMutablePointer, vlen: CUnsignedInt, flags: CInt, timeout: UnsafeMutablePointer?) throws -> IOResult { + return try syscall(blocking: true) { + Int(sysRecvMmsg(sockfd, msgvec, vlen, flags, timeout)) + } + } + + @inline(never) + internal static func getpeername(socket: CInt, address: UnsafeMutablePointer, addressLength: UnsafeMutablePointer) throws { + _ = try syscall(blocking: false) { + return sysGetpeername(socket, address, addressLength) + } + } + + @inline(never) + internal static func getsockname(socket: CInt, address: UnsafeMutablePointer, addressLength: UnsafeMutablePointer) throws { + _ = try syscall(blocking: false) { + return sysGetsockname(socket, address, addressLength) + } + } +#endif + + @inline(never) + internal static func if_nametoindex(_ name: UnsafePointer?) throws -> CUnsignedInt { + return try syscall(blocking: false) { + sysIfNameToIndex(name) + }.result + } + +#if !os(Windows) + @inline(never) + internal static func poll(fds: UnsafeMutablePointer, nfds: nfds_t, timeout: CInt) throws -> CInt { + return try syscall(blocking: false) { + sysPoll(fds, nfds, timeout) + }.result + } + + @inline(never) + internal static func fstat(descriptor: CInt, outStat: UnsafeMutablePointer) throws { + _ = try syscall(blocking: false) { + sysFstat(descriptor, outStat) + } + } + + @inline(never) + internal static func stat(pathname: String, outStat: UnsafeMutablePointer) throws { + _ = try syscall(blocking: false) { + sysStat(pathname, outStat) + } + } + + @inline(never) + internal static func unlink(pathname: String) throws { + _ = try syscall(blocking: false) { + sysUnlink(pathname) + } + } + + @inline(never) + internal static func socketpair(domain: NIOBSDSocket.ProtocolFamily, + type: NIOBSDSocket.SocketType, + protocol: CInt, + socketVector: UnsafeMutablePointer?) throws { + _ = try syscall(blocking: false) { + sysSocketpair(domain.rawValue, type.rawValue, `protocol`, socketVector) + } + } +#endif +} + +/// `NIOFcntlFailedError` indicates that NIO was unable to perform an +/// operation on a socket. +/// +/// This error should never happen, unfortunately, we have seen this happen on Darwin. +public struct NIOFcntlFailedError: Error {} + +/// `NIOFailedToSetSocketNonBlockingError` indicates that NIO was unable to set a socket to non-blocking mode, either +/// when connecting a socket as a client or when accepting a socket as a server. +/// +/// This error should never happen because a socket should always be able to be set to non-blocking mode. Unfortunately, +/// we have seen this happen on Darwin. +@available(*, deprecated, renamed: "NIOFcntlFailedError") +public struct NIOFailedToSetSocketNonBlockingError: Error {} + +#if !os(Windows) +internal extension Posix { + static func setNonBlocking(socket: CInt) throws { + let flags = try Posix.fcntl(descriptor: socket, command: F_GETFL, value: 0) + do { + let ret = try Posix.fcntl(descriptor: socket, command: F_SETFL, value: flags | O_NONBLOCK) + assert(ret == 0, "unexpectedly, fcntl(\(socket), F_SETFL, \(flags) | O_NONBLOCK) returned \(ret)") + } catch let error as IOError { + if error.errnoCode == EINVAL { + // Darwin seems to sometimes do this despite the docs claiming it can't happen + throw NIOFcntlFailedError() + } + throw error + } + } +} +#endif + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +internal enum KQueue { + + // TODO: Figure out how to specify a typealias to the kevent struct without run into trouble with the swift compiler + + @inline(never) + internal static func kqueue() throws -> CInt { + return try syscall(blocking: false) { + Darwin.kqueue() + }.result + } + + @inline(never) + @discardableResult + internal static func kevent(kq: CInt, changelist: UnsafePointer?, nchanges: CInt, eventlist: UnsafeMutablePointer?, nevents: CInt, timeout: UnsafePointer?) throws -> CInt { + return try syscall(blocking: false) { + sysKevent(kq, changelist, nchanges, eventlist, nevents, timeout) + }.result + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Thread.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Thread.swift new file mode 100644 index 00000000..a8953b39 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Thread.swift @@ -0,0 +1,218 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Linux) || os(FreeBSD) || os(Android) +import CNIOLinux +#endif + +enum LowLevelThreadOperations { + +} + +protocol ThreadOps { + associatedtype ThreadHandle + associatedtype ThreadSpecificKey + associatedtype ThreadSpecificKeyDestructor + + static func threadName(_ thread: ThreadHandle) -> String? + static func run(handle: inout ThreadHandle?, args: Box, detachThread: Bool) + static func isCurrentThread(_ thread: ThreadHandle) -> Bool + static func compareThreads(_ lhs: ThreadHandle, _ rhs: ThreadHandle) -> Bool + static var currentThread: ThreadHandle { get } + static func joinThread(_ thread: ThreadHandle) + static func allocateThreadSpecificValue(destructor: ThreadSpecificKeyDestructor) -> ThreadSpecificKey + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) +} + +/// A Thread that executes some runnable block. +/// +/// All methods exposed are thread-safe. +final class NIOThread { + internal typealias ThreadBoxValue = (body: (NIOThread) -> Void, name: String?) + internal typealias ThreadBox = Box + + private let desiredName: String? + + /// The thread handle used by this instance. + private let handle: ThreadOpsSystem.ThreadHandle + + /// Create a new instance + /// + /// - arguments: + /// - handle: The `ThreadOpsSystem.ThreadHandle` that is wrapped and used by the `NIOThread`. + internal init(handle: ThreadOpsSystem.ThreadHandle, desiredName: String?) { + self.handle = handle + self.desiredName = desiredName + } + + /// Execute the given body with the `pthread_t` that is used by this `NIOThread` as argument. + /// + /// - warning: Do not escape `pthread_t` from the closure for later use. + /// + /// - parameters: + /// - body: The closure that will accept the `pthread_t`. + /// - returns: The value returned by `body`. + internal func withUnsafeThreadHandle(_ body: (ThreadOpsSystem.ThreadHandle) throws -> T) rethrows -> T { + return try body(self.handle) + } + + /// Get current name of the `NIOThread` or `nil` if not set. + var currentName: String? { + return ThreadOpsSystem.threadName(self.handle) + } + + func join() { + ThreadOpsSystem.joinThread(self.handle) + } + + /// Spawns and runs some task in a `NIOThread`. + /// + /// - arguments: + /// - name: The name of the `NIOThread` or `nil` if no specific name should be set. + /// - body: The function to execute within the spawned `NIOThread`. + /// - detach: Whether to detach the thread. If the thread is not detached it must be `join`ed. + static func spawnAndRun(name: String? = nil, detachThread: Bool = true, + body: @escaping (NIOThread) -> Void) { + var handle: ThreadOpsSystem.ThreadHandle? = nil + + // Store everything we want to pass into the c function in a Box so we + // can hand-over the reference. + let tuple: ThreadBoxValue = (body: body, name: name) + let box = ThreadBox(tuple) + + ThreadOpsSystem.run(handle: &handle, args: box, detachThread: detachThread) + } + + /// Returns `true` if the calling thread is the same as this one. + var isCurrent: Bool { + return ThreadOpsSystem.isCurrentThread(self.handle) + } + + /// Returns the current running `NIOThread`. + static var current: NIOThread { + let handle = ThreadOpsSystem.currentThread + return NIOThread(handle: handle, desiredName: nil) + } +} + +extension NIOThread: CustomStringConvertible { + var description: String { + let desiredName = self.desiredName + let actualName = self.currentName + + switch (desiredName, actualName) { + case (.some(let desiredName), .some(desiredName)): + // We know the current, actual name and the desired name and they match. This is hopefully the most common + // situation. + return "NIOThread(name = \(desiredName))" + case (.some(let desiredName), .some(let actualName)): + // We know both names but they're not equal. That's odd but not impossible, some misbehaved library might + // have changed the name. + return "NIOThread(desiredName = \(desiredName), actualName = \(actualName))" + case (.some(let desiredName), .none): + // We only know the desired name and can't get the actual thread name. The OS might not be able to provide + // the name to us. + return "NIOThread(desiredName = \(desiredName))" + case (.none, .some(let actualName)): + // We only know the actual name. This can happen when we don't have a reference to the actually spawned + // thread but rather ask for the current thread and then print it. + return "NIOThread(actualName = \(actualName))" + case (.none, .none): + // We know nothing, sorry. + return "NIOThread(n/a)" + } + } +} + +/// A `ThreadSpecificVariable` is a variable that can be read and set like a normal variable except that it holds +/// different variables per thread. +/// +/// `ThreadSpecificVariable` is thread-safe so it can be used with multiple threads at the same time but the value +/// returned by `currentValue` is defined per thread. +public final class ThreadSpecificVariable { + /* the actual type in there is `Box<(ThreadSpecificVariable, T)>` but we can't use that as C functions can't capture (even types) */ + private typealias BoxedType = Box<(AnyObject, AnyObject)> + + internal class Key { + private var underlyingKey: ThreadOpsSystem.ThreadSpecificKey + + internal init(destructor: @escaping ThreadOpsSystem.ThreadSpecificKeyDestructor) { + self.underlyingKey = ThreadOpsSystem.allocateThreadSpecificValue(destructor: destructor) + } + + deinit { + ThreadOpsSystem.deallocateThreadSpecificValue(self.underlyingKey) + } + + public func get() -> UnsafeMutableRawPointer? { + return ThreadOpsSystem.getThreadSpecificValue(self.underlyingKey) + } + + public func set(value: UnsafeMutableRawPointer?) { + ThreadOpsSystem.setThreadSpecificValue(key: self.underlyingKey, value: value) + } + } + + private let key: Key + + /// Initialize a new `ThreadSpecificVariable` without a current value (`currentValue == nil`). + public init() { + self.key = Key(destructor: { + Unmanaged.fromOpaque(($0 as UnsafeMutableRawPointer?)!).release() + }) + } + + /// Initialize a new `ThreadSpecificVariable` with `value` for the calling thread. After calling this, the calling + /// thread will see `currentValue == value` but on all other threads `currentValue` will be `nil` until changed. + /// + /// - parameters: + /// - value: The value to set for the calling thread. + public convenience init(value: Value) { + self.init() + self.currentValue = value + } + + /// The value for the current thread. + public var currentValue: Value? { + /// Get the current value for the calling thread. + get { + guard let raw = self.key.get() else { return nil } + // parenthesize the return value to silence the cast warning + return (Unmanaged + .fromOpaque(raw) + .takeUnretainedValue() + .value.1 as! Value) + } + + /// Set the current value for the calling threads. The `currentValue` for all other threads remains unchanged. + set { + if let raw = self.key.get() { + Unmanaged.fromOpaque(raw).release() + } + self.key.set(value: newValue.map { Unmanaged.passRetained(Box((self, $0))).toOpaque() }) + } + } +} + +extension NIOThread: Equatable { + static func ==(lhs: NIOThread, rhs: NIOThread) -> Bool { + return lhs.withUnsafeThreadHandle { lhs in + rhs.withUnsafeThreadHandle { rhs in + ThreadOpsSystem.compareThreads(lhs, rhs) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadPosix.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadPosix.swift new file mode 100644 index 00000000..39745aee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadPosix.swift @@ -0,0 +1,157 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Linux) || os(Android) || os(FreeBSD) || os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + +#if os(Linux) || os(Android) +import CNIOLinux + +private let sys_pthread_getname_np = CNIOLinux_pthread_getname_np +private let sys_pthread_setname_np = CNIOLinux_pthread_setname_np +private typealias ThreadDestructor = @convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? +#elseif os(iOS) || os(macOS) || os(tvOS) || os(watchOS) +private let sys_pthread_getname_np = pthread_getname_np +// Emulate the same method signature as pthread_setname_np on Linux. +private func sys_pthread_setname_np(_ p: pthread_t, _ pointer: UnsafePointer) -> Int32 { + assert(pthread_equal(pthread_self(), p) != 0) + pthread_setname_np(pointer) + // Will never fail on macOS so just return 0 which will be used on linux to signal it not failed. + return 0 +} +private typealias ThreadDestructor = @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? + +#endif + +private func sysPthread_create(handle: UnsafeMutablePointer, + destructor: @escaping ThreadDestructor, + args: UnsafeMutableRawPointer?) -> CInt { + #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + return pthread_create(handle, nil, destructor, args) + #else + var handleLinux = pthread_t() + let result = pthread_create(&handleLinux, + nil, + destructor, + args) + handle.pointee = handleLinux + return result + #endif +} + + +typealias ThreadOpsSystem = ThreadOpsPosix + +enum ThreadOpsPosix: ThreadOps { + typealias ThreadHandle = pthread_t + typealias ThreadSpecificKey = pthread_key_t + #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer) -> Void + #else + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer?) -> Void + #endif + + static func threadName(_ thread: ThreadOpsSystem.ThreadHandle) -> String? { + // 64 bytes should be good enough as on Linux the limit is usually 16 + // and it's very unlikely a user will ever set something longer + // anyway. + var chars: [CChar] = Array(repeating: 0, count: 64) + return chars.withUnsafeMutableBufferPointer { ptr in + guard sys_pthread_getname_np(thread, ptr.baseAddress!, ptr.count) == 0 else { + return nil + } + + let buffer: UnsafeRawBufferPointer = + UnsafeRawBufferPointer(UnsafeBufferPointer(rebasing: ptr.prefix { $0 != 0 })) + return String(decoding: buffer, as: Unicode.UTF8.self) + } + } + + static func run(handle: inout ThreadOpsSystem.ThreadHandle?, args: Box, detachThread: Bool) { + let argv0 = Unmanaged.passRetained(args).toOpaque() + let res = sysPthread_create(handle: &handle, destructor: { + // Cast to UnsafeMutableRawPointer? and force unwrap to make the + // same code work on macOS and Linux. + let boxed = Unmanaged + .fromOpaque(($0 as UnsafeMutableRawPointer?)!) + .takeRetainedValue() + let (body, name) = (boxed.value.body, boxed.value.name) + let hThread: ThreadOpsSystem.ThreadHandle = pthread_self() + + if let name = name { + let maximumThreadNameLength: Int + #if os(Linux) || os(Android) + maximumThreadNameLength = 15 + #else + maximumThreadNameLength = .max + #endif + name.prefix(maximumThreadNameLength).withCString { namePtr in + // this is non-critical so we ignore the result here, we've seen + // EPERM in containers. + _ = sys_pthread_setname_np(hThread, namePtr) + } + } + + body(NIOThread(handle: hThread, desiredName: name)) + + return nil + }, args: argv0) + precondition(res == 0, "Unable to create thread: \(res)") + + if detachThread { + let detachError = pthread_detach(handle!) + precondition(detachError == 0, "pthread_detach failed with error \(detachError)") + } + + } + + static func isCurrentThread(_ thread: ThreadOpsSystem.ThreadHandle) -> Bool { + return pthread_equal(thread, pthread_self()) != 0 + } + + static var currentThread: ThreadOpsSystem.ThreadHandle { + return pthread_self() + } + + static func joinThread(_ thread: ThreadOpsSystem.ThreadHandle) { + let err = pthread_join(thread, nil) + assert(err == 0, "pthread_join failed with \(err)") + } + + static func allocateThreadSpecificValue(destructor: @escaping ThreadSpecificKeyDestructor) -> ThreadSpecificKey { + var value = pthread_key_t() + let result = pthread_key_create(&value, Optional(destructor)) + precondition(result == 0, "pthread_key_create failed: \(result)") + return value + } + + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) { + let result = pthread_key_delete(key) + precondition(result == 0, "pthread_key_delete failed: \(result)") + } + + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? { + return pthread_getspecific(key) + } + + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) { + let result = pthread_setspecific(key, value) + precondition(result == 0, "pthread_setspecific failed: \(result)") + } + + static func compareThreads(_ lhs: ThreadOpsSystem.ThreadHandle, _ rhs: ThreadOpsSystem.ThreadHandle) -> Bool { + return pthread_equal(lhs, rhs) != 0 + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadWindows.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadWindows.swift new file mode 100644 index 00000000..34873a0c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/ThreadWindows.swift @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) + +import WinSDK + + +typealias ThreadOpsSystem = ThreadOpsWindows +enum ThreadOpsWindows: ThreadOps { + typealias ThreadHandle = HANDLE + typealias ThreadSpecificKey = DWORD + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer?) -> Void + + static func threadName(_ thread: ThreadOpsSystem.ThreadHandle) -> String? { + var pszBuffer: PWSTR? + GetThreadDescription(thread, &pszBuffer) + guard let buffer = pszBuffer else { return nil } + let string: String = String(decodingCString: buffer, as: UTF16.self) + LocalFree(buffer) + return string + } + + static func run(handle: inout ThreadOpsSystem.ThreadHandle?, args: Box, detachThread: Bool) { + let argv0 = Unmanaged.passRetained(args).toOpaque() + + // FIXME(compnerd) this should use the `stdcall` calling convention + let routine: @convention(c) (UnsafeMutableRawPointer?) -> CUnsignedInt = { + let boxed = Unmanaged.fromOpaque($0!).takeRetainedValue() + let (body, name) = (boxed.value.body, boxed.value.name) + let hThread: ThreadOpsSystem.ThreadHandle = GetCurrentThread() + + if let name = name { + _ = name.withCString(encodedAs: UTF16.self) { + SetThreadDescription(hThread, $0) + } + } + + body(NIOThread(handle: hThread, desiredName: name)) + + return 0 + } + let hThread: HANDLE = + HANDLE(bitPattern: _beginthreadex(nil, 0, routine, argv0, 0, nil))! + + if detachThread { + CloseHandle(hThread) + } + } + + static func isCurrentThread(_ thread: ThreadOpsSystem.ThreadHandle) -> Bool { + return CompareObjectHandles(thread, GetCurrentThread()) + } + + static var currentThread: ThreadOpsSystem.ThreadHandle { + return GetCurrentThread() + } + + static func joinThread(_ thread: ThreadOpsSystem.ThreadHandle) { + let dwResult: DWORD = WaitForSingleObject(thread, INFINITE) + assert(dwResult == WAIT_OBJECT_0, "WaitForSingleObject: \(GetLastError())") + } + + static func allocateThreadSpecificValue(destructor: @escaping ThreadSpecificKeyDestructor) -> ThreadSpecificKey { + return FlsAlloc(destructor) + } + + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) { + let dwResult: Bool = FlsFree(key) + precondition(dwResult, "FlsFree: \(GetLastError())") + } + + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? { + return FlsGetValue(key) + } + + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) { + FlsSetValue(key, value) + } + + static func compareThreads(_ lhs: ThreadOpsSystem.ThreadHandle, _ rhs: ThreadOpsSystem.ThreadHandle) -> Bool { + return CompareObjectHandles(lhs, rhs) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Utilities.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Utilities.swift new file mode 100644 index 00000000..43329b98 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOPosix/Sources/NIOPosix/Utilities.swift @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A utility function that runs the body code only in debug builds, without +/// emitting compiler warnings. +/// +/// This is currently the only way to do this in Swift: see +/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion. +@inlinable +internal func debugOnly(_ body: () -> Void) { + assert({ body(); return true }()) +} + +/// Allows to "box" another value. +final class Box { + let value: T + init(_ value: T) { self.value = value } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/README.md new file mode 100644 index 00000000..9a91146f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/README.md @@ -0,0 +1,53 @@ +# SwiftNIO SSL + +SwiftNIO SSL is a Swift package that contains an implementation of TLS based on BoringSSL. This package allows users of [SwiftNIO](https://github.com/apple/swift-nio) to write protocol clients and servers that use TLS to secure data in flight. + +The name is inspired primarily by the names of the library this package uses (BoringSSL), and not because we don't know the name of the protocol. We know the protocol is TLS! + +To get started, check out the [API docs](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html). + +## Using SwiftNIO SSL + +SwiftNIO SSL provides two `ChannelHandler`s to use to secure a data stream: the `NIOSSLClientHandler` and the `NIOSSLServerHandler`. Each of these can be added to a `Channel` to secure the communications on that channel. + +Additionally, we provide a number of low-level primitives for configuring your TLS connections. These will be shown below. + +To secure a server connection, you will need a X.509 certificate chain in a file (either PEM or DER, but PEM is far easier), and the associated private key for the leaf certificate. These objects can then be wrapped up in a `TLSConfiguration` object that is used to initialize the `ChannelHandler`. + +For example: + +```swift +let configuration = TLSConfiguration.makeServerConfiguration( + certificateChain: try NIOSSLCertificate.fromPEMFile("cert.pem").map { .certificate($0) }, + privateKey: .file("key.pem") +) +let sslContext = try NIOSSLContext(configuration: configuration) + +let server = ServerBootstrap(group: group) + .childChannelInitializer { channel in + // important: The handler must be initialized _inside_ the `childChannelInitializer` + let handler = try NIOSSLServerHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` + +For clients, it is a bit simpler as there is no need to have a certificate chain or private key (though clients *may* have these things). Setup for clients may be done like this: + +```swift +let configuration = TLSConfiguration.makeClientConfiguration() +let sslContext = try NIOSSLContext(configuration: configuration) + +let client = ClientBootstrap(group: group) + .channelInitializer { channel in + // important: The handler must be initialized _inside_ the `channelInitializer` + let handler = try NIOSSLClientHandler(context: sslContext) + + [...] + channel.pipeline.addHandler(handler) + [...] + } +``` +Note that SwiftNIO SSL currently requires Swift 5.4 and above. Release 2.13.x and prior support Swift 5.0 and 5.1, Release 2.18.x and prior supports Swift 5.2 and 5.3. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ByteBufferBIO.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ByteBufferBIO.swift new file mode 100644 index 00000000..d14be8e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ByteBufferBIO.swift @@ -0,0 +1,375 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +@_implementationOnly import CNIOBoringSSL + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + + +/// The BoringSSL entry point to write to the `ByteBufferBIO`. This thunk unwraps the user data +/// and then passes the call on to the specific BIO reference. +/// +/// This specific type signature is annoying (I'd rather have UnsafeRawPointer, and rather than a separate +/// len I'd like a buffer pointer), but this interface is required because this is passed to an BoringSSL +/// function pointer and so needs to be @convention(c). +internal func boringSSLBIOWriteFunc(bio: UnsafeMutablePointer?, buf: UnsafePointer?, len: CInt) -> CInt { + guard let concreteBIO = bio, let concreteBuf = buf else { + preconditionFailure("Invalid pointers in boringSSLBIOWriteFunc: bio: \(String(describing: bio)) buf: \(String(describing: buf))") + } + + // This unwrap may fail if the user has dropped the ref to the ByteBufferBIO but still has + // a ref to the other pointer. Sigh heavily and just fail. + guard let userPtr = CNIOBoringSSL_BIO_get_data(concreteBIO) else { + return -1 + } + + // Begin by clearing retry flags. We do this at all BoringSSL entry points. + CNIOBoringSSL_BIO_clear_retry_flags(concreteBIO) + + // In the event a write of 0 bytes has been asked for, just return early, don't bother with the other work. + guard len > 0 else { + return 0 + } + + let swiftBIO: ByteBufferBIO = Unmanaged.fromOpaque(userPtr).takeUnretainedValue() + let bufferPtr = UnsafeRawBufferPointer(start: concreteBuf, count: Int(len)) + return swiftBIO.sslWrite(buffer: bufferPtr) +} + +/// The BoringSSL entry point to read from the `ByteBufferBIO`. This thunk unwraps the user data +/// and then passes the call on to the specific BIO reference. +/// +/// This specific type signature is annoying (I'd rather have UnsafeRawPointer, and rather than a separate +/// len I'd like a buffer pointer), but this interface is required because this is passed to an BoringSSL +/// function pointer and so needs to be @convention(c). +internal func boringSSLBIOReadFunc(bio: UnsafeMutablePointer?, buf: UnsafeMutablePointer?, len: CInt) -> CInt { + guard let concreteBIO = bio, let concreteBuf = buf else { + preconditionFailure("Invalid pointers in boringSSLBIOReadFunc: bio: \(String(describing: bio)) buf: \(String(describing: buf))") + } + + // This unwrap may fail if the user has dropped the ref to the ByteBufferBIO but still has + // a ref to the other pointer. Sigh heavily and just fail. + guard let userPtr = CNIOBoringSSL_BIO_get_data(concreteBIO) else { + return -1 + } + + // Begin by clearing retry flags. We do this at all BoringSSL entry points. + CNIOBoringSSL_BIO_clear_retry_flags(concreteBIO) + + // In the event a read for 0 bytes has been asked for, just return early, don't bother with the other work. + guard len > 0 else { + return 0 + } + + let swiftBIO: ByteBufferBIO = Unmanaged.fromOpaque(userPtr).takeUnretainedValue() + let bufferPtr = UnsafeMutableRawBufferPointer(start: concreteBuf, count: Int(len)) + return swiftBIO.sslRead(buffer: bufferPtr) +} + +/// The BoringSSL entry point for `puts`. This is a silly function, so we're just going to implement it +/// in terms of write. +/// +/// This specific type signature is annoying (I'd rather have UnsafeRawPointer, and rather than a separate +/// len I'd like a buffer pointer), but this interface is required because this is passed to an BoringSSL +/// function pointer and so needs to be @convention(c). +internal func boringSSLBIOPutsFunc(bio: UnsafeMutablePointer?, buf: UnsafePointer?) -> CInt { + guard let concreteBIO = bio, let concreteBuf = buf else { + preconditionFailure("Invalid pointers in boringSSLBIOPutsFunc: bio: \(String(describing: bio)) buf: \(String(describing: buf))") + } + return boringSSLBIOWriteFunc(bio: concreteBIO, buf: concreteBuf, len: CInt(strlen(concreteBuf))) +} + +/// The BoringSSL entry point for `gets`. This is a *really* silly function and we can't implement it nicely +/// in terms of read, so we just refuse to support it. +/// +/// This specific type signature is annoying (I'd rather have UnsafeRawPointer, and rather than a separate +/// len I'd like a buffer pointer), but this interface is required because this is passed to an BoringSSL +/// function pointer and so needs to be @convention(c). +internal func boringSSLBIOGetsFunc(bio: UnsafeMutablePointer?, buf: UnsafeMutablePointer?, len: CInt) -> CInt { + return -2 +} + +/// The BoringSSL entry point for `BIO_ctrl`. We don't support most of these. +internal func boringSSLBIOCtrlFunc(bio: UnsafeMutablePointer?, cmd: CInt, larg: CLong, parg: UnsafeMutableRawPointer?) -> CLong { + switch cmd { + case BIO_CTRL_GET_CLOSE: + return CLong(CNIOBoringSSL_BIO_get_shutdown(bio)) + case BIO_CTRL_SET_CLOSE: + CNIOBoringSSL_BIO_set_shutdown(bio, CInt(larg)) + return 1 + case BIO_CTRL_FLUSH: + return 1 + default: + return 0 + } +} + +internal func boringSSLBIOCreateFunc(bio: UnsafeMutablePointer?) -> CInt { + return 1 +} + +internal func boringSSLBIODestroyFunc(bio: UnsafeMutablePointer?) -> CInt { + return 1 +} + + +/// An BoringSSL BIO object that wraps `ByteBuffer` objects. +/// +/// BoringSSL extensively uses an abstraction called `BIO` to manage its input and output +/// channels. For NIO we want a BIO that operates entirely in-memory, and it's tempting +/// to assume that BoringSSL's `BIO_s_mem` is the best choice for that. However, ultimately +/// `BIO_s_mem` is a flat memory buffer that we end up using as a staging between one +/// `ByteBuffer` of plaintext and one of ciphertext. We'd like to cut out that middleman. +/// +/// For this reason, we want to create an object that implements the `BIO` abstraction +/// but which use `ByteBuffer`s to do so. This allows us to avoid unnecessary memory copies, +/// which can be a really large win. +final class ByteBufferBIO { + /// The unsafe pointer to the BoringSSL BIO_METHOD. + /// + /// This is used to give BoringSSL pointers to the methods that need to be invoked when + /// using a ByteBufferBIO. There will only ever be one value of this in a NIO program, + /// and it will always be non-NULL. Failure to initialize this structure is fatal to + /// the program. + private static let boringSSLBIOMethod: UnsafeMutablePointer = { + guard boringSSLIsInitialized else { + preconditionFailure("Failed to initialize BoringSSL") + } + + let bioType = CNIOBoringSSL_BIO_get_new_index() | BIO_TYPE_SOURCE_SINK + guard let method = CNIOBoringSSL_BIO_meth_new(bioType, "ByteBuffer BIO") else { + preconditionFailure("Unable to allocate new BIO_METHOD") + } + + CNIOBoringSSL_BIO_meth_set_write(method, boringSSLBIOWriteFunc) + CNIOBoringSSL_BIO_meth_set_read(method, boringSSLBIOReadFunc) + CNIOBoringSSL_BIO_meth_set_puts(method, boringSSLBIOPutsFunc) + CNIOBoringSSL_BIO_meth_set_gets(method, boringSSLBIOGetsFunc) + CNIOBoringSSL_BIO_meth_set_ctrl(method, boringSSLBIOCtrlFunc) + CNIOBoringSSL_BIO_meth_set_create(method, boringSSLBIOCreateFunc) + CNIOBoringSSL_BIO_meth_set_destroy(method, boringSSLBIODestroyFunc) + + return method + }() + + /// Pointer to the backing BoringSSL BIO object. + /// + /// Generally speaking BoringSSL wants to own the object initialization logic for a BIO. + /// This doesn't work for us, because we'd like to ensure that the `ByteBufferBIO` is + /// correctly initialized with all the state it needs. One of those bits of state is + /// a `ByteBuffer`, which BoringSSL cannot give us, so we need to build our `ByteBufferBIO` + /// *first* and then use that to drive `BIO` initialization. + /// + /// Because of this split initialization dance, we elect to initialize this data structure, + /// and have it own building an BoringSSL `BIO` structure. + private let bioPtr: UnsafeMutablePointer + + /// The buffer of bytes received from the network. + /// + /// By default, `ByteBufferBIO` expects to pass data directly to BoringSSL whenever it + /// is received. It is, in essence, a temporary container for a `ByteBuffer` on the + /// read side. This provides a powerful optimisation, which is that the read buffer + /// passed to the `NIOSSLHandler` can be re-used immediately upon receipt. Given that + /// the `NIOSSLHandler` is almost always the first handler in the pipeline, this greatly + /// improves the allocation profile of busy connections, which can more-easily re-use + /// the receive buffer. + private var inboundBuffer: ByteBuffer? + + /// The buffer of bytes to send to the network. + /// + /// While on the read side `ByteBufferBIO` expects to hold each bytebuffer only temporarily, + /// on the write side we attempt to coalesce as many writes as possible. This is because a + /// buffer can only be re-used if it is flushed to the network, and that can only happen + /// on flush calls, so we are incentivised to write as many SSL_write calls into one buffer + /// as possible. + private var outboundBuffer: ByteBuffer + + /// Whether the outbound buffer should be cleared before writing. + /// + /// This is true only if we've flushed the buffer to the network. Rather than track an annoying + /// boolean for this, we use a quick check on the properties of the buffer itself. This clear + /// wants to be delayed as long as possible to maximise the possibility that it does not + /// trigger an allocation. + private var mustClearOutboundBuffer: Bool { + return outboundBuffer.readerIndex == outboundBuffer.writerIndex && outboundBuffer.readerIndex > 0 + } + + init(allocator: ByteBufferAllocator) { + // We allocate enough space for a single TLS record. We may not actually write a record that size, but we want to + // give ourselves the option. We may also write more data than that: if we do, the ByteBuffer will just handle it. + self.outboundBuffer = allocator.buffer(capacity: SSL_MAX_RECORD_SIZE) + + guard let bio = CNIOBoringSSL_BIO_new(ByteBufferBIO.boringSSLBIOMethod) else { + preconditionFailure("Unable to initialize custom BIO") + } + + // We now need to complete the BIO initialization. The BIO takes an owned reference to self here, + // which is broken on close(). + self.bioPtr = bio + CNIOBoringSSL_BIO_set_data(self.bioPtr, Unmanaged.passRetained(self).toOpaque()) + CNIOBoringSSL_BIO_set_init(self.bioPtr, 1) + CNIOBoringSSL_BIO_set_shutdown(self.bioPtr, 1) + } + + deinit { + // In debug mode we assert that we've been closed. + assert(CNIOBoringSSL_BIO_get_data(self.bioPtr) == nil, "must call close() on ByteBufferBIO before deinit") + + // On deinit we need to drop our reference to the BIO. + CNIOBoringSSL_BIO_free(self.bioPtr) + } + + /// Shuts down the BIO, rendering it unable to be used. + /// + /// This method is idempotent: it is safe to call more than once. + internal func close() { + guard let selfRef = CNIOBoringSSL_BIO_get_data(self.bioPtr) else { + // Shutdown is safe to call more than once. + return + } + + // We consume the original retain of self, and then nil out the ref in the BIO so that this can't happen again. + Unmanaged.fromOpaque(selfRef).release() + CNIOBoringSSL_BIO_set_data(self.bioPtr, nil) + } + + /// Obtain an owned pointer to the backing BoringSSL BIO object. + /// + /// This pointer is safe to use elsewhere, as it has increased the reference to the backing + /// `BIO`. This makes it safe to use with BoringSSL functions that require an owned reference + /// (that is, that consume a reference count). + /// + /// Note that the BIO may not remain useful for long periods of time: if the `ByteBufferBIO` + /// object that owns the BIO goes out of scope, the BIO will have its pointers invalidated + /// and will no longer be able to send/receive data. + internal func retainedBIO() -> UnsafeMutablePointer { + CNIOBoringSSL_BIO_up_ref(self.bioPtr) + return self.bioPtr + } + + + /// Called to obtain the outbound ciphertext written by BoringSSL. + /// + /// This function obtains a buffer of ciphertext that needs to be written to the network. In a + /// normal application, this should be obtained on a call to `flush`. If no bytes have been flushed + /// to the network, then this call will return `nil` rather than an empty byte buffer, to help signal + /// that the `write` call should be elided. + /// + /// - returns: A buffer of ciphertext to send to the network, or `nil` if no buffer is available. + func outboundCiphertext() -> ByteBuffer? { + guard self.outboundBuffer.readableBytes > 0 else { + // No data to send. + return nil + } + + /// Once we return from this function, we want to account for the bytes we've handed off. + defer { + self.outboundBuffer.moveReaderIndex(to: self.outboundBuffer.writerIndex) + } + + return self.outboundBuffer + } + + /// Stores a buffer received from the network for delivery to BoringSSL. + /// + /// Whenever a buffer is received from the network, it is passed to the BIO via this function + /// call. In almost all cases this BIO should be immediately consumed by BoringSSL, but in some cases + /// it may not be. In those cases, additional calls will cause byte-by-byte copies. This should + /// be avoided, but usually only happens during asynchronous certificate verification in the + /// handshake. + /// + /// - parameters: + /// - buffer: The buffer of ciphertext bytes received from the network. + func receiveFromNetwork(buffer: ByteBuffer) { + var buffer = buffer + + if self.inboundBuffer == nil { + self.inboundBuffer = buffer + } else { + self.inboundBuffer!.writeBuffer(&buffer) + } + } + + /// Retrieves any inbound data that has not been processed by BoringSSL. + /// + /// When unwrapping TLS from a connection, there may be application bytes that follow the terminating + /// CLOSE_NOTIFY message. Those bytes may be in the buffer passed to this BIO, and so we need to + /// retrieve them. + /// + /// This function extracts those bytes and returns them to the user, and drops the reference to them + /// in this BIO. + /// + /// - returns: The unconsumed `ByteBuffer`, if any. + func evacuateInboundData() -> ByteBuffer? { + defer { + self.inboundBuffer = nil + } + return self.inboundBuffer + } + + /// BoringSSL has requested to read ciphertext bytes from the network. + /// + /// This function is invoked whenever BoringSSL is looking to read data. + /// + /// - parameters: + /// - buffer: The buffer for NIO to copy bytes into. + /// - returns: The number of bytes we have copied. + fileprivate func sslRead(buffer: UnsafeMutableRawBufferPointer) -> CInt { + guard var inboundBuffer = self.inboundBuffer else { + // We have no bytes to read. Mark this as "needs read retry". + CNIOBoringSSL_BIO_set_retry_read(self.bioPtr) + return -1 + } + + let bytesToCopy = min(buffer.count, inboundBuffer.readableBytes) + _ = inboundBuffer.readWithUnsafeReadableBytes { bytePointer in + assert(bytePointer.count >= bytesToCopy, "Copying more bytes (\(bytesToCopy)) than fits in readable bytes \((bytePointer.count))") + assert(buffer.count >= bytesToCopy, "Copying more bytes (\(bytesToCopy) than contained in source buffer (\(buffer.count))") + buffer.baseAddress!.copyMemory(from: bytePointer.baseAddress!, byteCount: bytesToCopy) + return bytesToCopy + } + + // If we have read all the bytes from the inbound buffer, nil it out. + if inboundBuffer.readableBytes > 0 { + self.inboundBuffer = inboundBuffer + } else { + self.inboundBuffer = nil + } + + return CInt(bytesToCopy) + } + + /// BoringSSL has requested to write ciphertext bytes from the network. + /// + /// - parameters: + /// - buffer: The buffer for NIO to copy bytes from. + /// - returns: The number of bytes we have copied. + fileprivate func sslWrite(buffer: UnsafeRawBufferPointer) -> CInt { + if self.mustClearOutboundBuffer { + // We just flushed, and this is a new write. Let's clear the buffer now. + self.outboundBuffer.clear() + assert(!self.mustClearOutboundBuffer) + } + + let writtenBytes = self.outboundBuffer.writeBytes(buffer) + return CInt(writtenBytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/CustomPrivateKey.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/CustomPrivateKey.swift new file mode 100644 index 00000000..d89654ee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/CustomPrivateKey.swift @@ -0,0 +1,278 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +@_implementationOnly import CNIOBoringSSL + +/// `NIOSSLCustomPrivateKey` defines the interface of a custom, non-BoringSSL private key. +/// +/// In a number of circumstances it is advantageous to store a TLS private key in some form of high-security storage, +/// such as a smart card. In these cases it is not possible to represent the TLS private key directly as a sequence +/// of bytes that BoringSSL will understand. +/// +/// This protocol allows a type to implement callbacks that perform the specific operation required by the TLS handshake. +/// Implementers are required to specify what signature algorithms they support, and then must implement **only one** of +/// the `sign`/`decrypt` functions. For elliptic curve keys, implementers should implement `sign`. For RSA keys, +/// implementers should implement `sign` and, if supporting RSA key exchange in TLS versions before 1.3, you should +/// also implement `decrypt`. +/// +/// If the same `NIOSSLCustomPrivateKey` implementation is used by multiple channels at once, then no synchronization +/// is imposed by SwiftNIO. The calls to the protocol requirements will be made on event loop threads, so if further +/// synchronization is required it is up to the implementer to provide it. Note that it is unacceptable to block in +/// these functions, and so potentially blocking operations must delegate to another thread. +public protocol NIOSSLCustomPrivateKey { + /// The signature algorithms supported by this key. + var signatureAlgorithms: [SignatureAlgorithm] { get } + + /// Called to perform a signing operation. + /// + /// The data being passed to the call has not been hashed, and it is the responsibility of the implementer + /// to ensure that the data _is_ hashed before use. `algorithm` will control what hash algorithm should be used. + /// This call will always execute on `channel.eventLoop`. + /// + /// This function should be implemented by both EC and RSA keys. + /// + /// - parameters: + /// - channel: The `Channel` representing the connection for which we are performing the signing operation. + /// - algorithm: The `SignatureAlgorithm` that should be used to generate the signature. + /// - data: The data to be signed. + /// - returns: An `EventLoopFuture` that will be fulfilled with a `ByteBuffer` containing the signature bytes, if + /// the signing operation completes, or that will be failed with a relevant `Error` if the signature could not + /// be produced. + func sign(channel: Channel, algorithm: SignatureAlgorithm, data: ByteBuffer) -> EventLoopFuture + + /// Called to perform a decryption operation. + /// + /// The data being passed to the call should be decrypted using _raw_ RSA public key decryption, without padding. + /// This call will always execute on `channel.eventLoop`. + /// + /// This function should only be implemented for RSA keys, and then only if you support RSA key exchange. If you + /// are only using TLS 1.3 and later, this function is entirely unnecessary and it will never be called. + /// + /// - parameters: + /// - channel: The `Channel` representing the connection for which we are performing the decryption operation. + /// - data: The data to be decrypted. + /// - returns: An `EventLoopFuture` that will be fulfilled with a `ByteBuffer` containing the decrypted bytes, if + /// the decryption operation completes, or that will be failed with a relevant `Error` if the decrypted bytes + /// could not be produced. + func decrypt(channel: Channel, data: ByteBuffer) -> EventLoopFuture +} + +/// This is a type-erased wrapper that can be used to encapsulate a NIOSSLCustomPrivateKey and provide it with +/// hashability and equatability. +/// +/// While generally speaking type-erasure has some nasty performance problems, we only need the type-erasure for +/// Hashable conformance, which we don't use in any production code: only the tests use it. To that end, we don't +/// mind too much that we need to do this. +@usableFromInline +internal struct AnyNIOSSLCustomPrivateKey: NIOSSLCustomPrivateKey, Hashable { + @usableFromInline let _value: NIOSSLCustomPrivateKey + + @usableFromInline let _equalsFunction: (NIOSSLCustomPrivateKey) -> Bool + + @usableFromInline let _hashFunction: (inout Hasher) -> Void + + @inlinable init(_ key: CustomKey) { + self._value = key + self._equalsFunction = { ($0 as? CustomKey) == key } + self._hashFunction = { $0.combine(key) } + } + + // This method does not need to be @inlinable for performance, but it needs to be _at least_ + // @usableFromInline as it's a protocol requirement on a @usableFromInline type. + @inlinable var signatureAlgorithms: [SignatureAlgorithm] { + return self._value.signatureAlgorithms + } + + // This method does not need to be @inlinable for performance, but it needs to be _at least_ + // @usableFromInline as it's a protocol requirement on a @usableFromInline type. + @inlinable func sign(channel: Channel, algorithm: SignatureAlgorithm, data: ByteBuffer) -> EventLoopFuture { + return self._value.sign(channel: channel, algorithm: algorithm, data: data) + } + + // This method does not need to be @inlinable for performance, but it needs to be _at least_ + // @usableFromInline as it's a protocol requirement on a @usableFromInline type. + @inlinable func decrypt(channel: Channel, data: ByteBuffer) -> EventLoopFuture { + return self._value.decrypt(channel: channel, data: data) + } + + // This method does not need to be @inlinable for performance, but it needs to be _at least_ + // @usableFromInline as it's a protocol requirement on a @usableFromInline type. + @inlinable func hash(into hasher: inout Hasher) { + self._hashFunction(&hasher) + } + + // This method does not need to be @inlinable for performance, but it needs to be _at least_ + // @usableFromInline as it's a protocol requirement on a @usableFromInline type. + @inlinable static func ==(lhs: AnyNIOSSLCustomPrivateKey, rhs: AnyNIOSSLCustomPrivateKey) -> Bool { + return lhs._equalsFunction(rhs._value) + } +} + +extension SSLConnection { + fileprivate var customKey: NIOSSLCustomPrivateKey? { + guard case .some(.privateKey(let key)) = self.parentContext.configuration.privateKey, + case .custom(let customKey) = key.representation else { + return nil + } + + return customKey + } + + fileprivate func customPrivateKeySign( + signatureAlgorithm: UInt16, + in: UnsafeBufferPointer + ) -> ssl_private_key_result_t { + precondition(self.customPrivateKeyResult == nil) + + guard let customKey = self.customKey else { + preconditionFailure() + } + + let wrappedAlgorithm = SignatureAlgorithm(rawValue: signatureAlgorithm) + guard customKey.signatureAlgorithms.contains(wrappedAlgorithm) else { + return ssl_private_key_failure + } + + // This force-unwrap pair is safe: we can only handshake while we're in a pipeline. + let channel = self.parentHandler!.channel! + var inputBytes = channel.allocator.buffer(capacity: `in`.count) + inputBytes.writeBytes(`in`) + + let result = customKey.sign(channel: channel, algorithm: wrappedAlgorithm, data: inputBytes) + result.whenComplete { signingResult in + self.storeCustomPrivateKeyResult(signingResult, channel: channel) + } + + return ssl_private_key_retry + } + + fileprivate func customPrivateKeyDecrypt( + in: UnsafeBufferPointer + ) -> ssl_private_key_result_t { + precondition(self.customPrivateKeyResult == nil) + + guard let customKey = self.customKey else { + preconditionFailure() + } + + // This force-unwrap pair is safe: we can only handshake while we're in a pipeline. + let channel = self.parentHandler!.channel! + var inputBytes = channel.allocator.buffer(capacity: `in`.count) + inputBytes.writeBytes(`in`) + + let result = customKey.decrypt(channel: channel, data: inputBytes) + result.whenComplete { decryptionResult in + self.storeCustomPrivateKeyResult(decryptionResult, channel: channel) + } + + return ssl_private_key_retry + } + + fileprivate func customPrivateKeyComplete(out: inout UnsafeMutableBufferPointer) -> ssl_private_key_result_t { + switch self.customPrivateKeyResult { + case .none: + return ssl_private_key_retry + case .some(.failure): + return ssl_private_key_failure + case .some(.success(let signingResult)): + guard signingResult.readableBytes <= out.count else { + return ssl_private_key_failure + } + + let (_, lastIndex) = out.initialize(from: signingResult.readableBytesView) + out = UnsafeMutableBufferPointer(rebasing: out[.., channel: Channel) { + // When we complete here we need to set our result state, and then ask to respin the handshake. + // If we can't respin the handshake because we've dropped the parent handler, that's fine, no harm no foul. + // For that reason, we tolerate both the verify manager and the parent handler being nil. + channel.eventLoop.execute { + precondition(self.customPrivateKeyResult == nil) + self.customPrivateKeyResult = result + self.parentHandler?.resumeHandshake() + } + } +} + +// We heap-allocate the SSL_PRIVATE_KEY_METHOD we need because we can't define a static stored property with fixed address +// in Swift. +internal let customPrivateKeyMethod: UnsafePointer = { + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + pointer.pointee = .init(sign: customKeySign, decrypt: customKeyDecrypt, complete: customKeyComplete) + return UnsafePointer(pointer) +}() + +/// This is our entry point from BoringSSL when we've been asked to do a sign. +fileprivate func customKeySign( + ssl: OpaquePointer?, out: UnsafeMutablePointer?, outLen: UnsafeMutablePointer?, + maxOut: size_t, signatureAlgorithm: UInt16, in: UnsafePointer?, inLen: Int +) -> ssl_private_key_result_t { + guard let ssl = ssl, out != nil, let outLen = outLen, let `in` = `in` else { + preconditionFailure() + } + + let connection = SSLConnection.loadConnectionFromSSL(ssl) + let inBuffer = UnsafeBufferPointer(start: `in`, count: inLen) + + // We never return anything here. + outLen.pointee = 0 + + return connection.customPrivateKeySign(signatureAlgorithm: signatureAlgorithm, in: inBuffer) +} + +/// This is our entry point from BoringSSL when we've been asked to do a decrypt. +fileprivate func customKeyDecrypt( + ssl: OpaquePointer?, out: UnsafeMutablePointer?, outLen: UnsafeMutablePointer?, + maxOut: Int, in: UnsafePointer?, inLen: Int +) -> ssl_private_key_result_t { + guard let ssl = ssl, out != nil, let outLen = outLen, let `in` = `in` else { + preconditionFailure() + } + + let connection = SSLConnection.loadConnectionFromSSL(ssl) + let inBuffer = UnsafeBufferPointer(start: `in`, count: inLen) + + // We never return anything here. + outLen.pointee = 0 + + return connection.customPrivateKeyDecrypt(in: inBuffer) +} + + +/// When BoringSSL is asking if we're done with our key operation, we come here. +fileprivate func customKeyComplete( + ssl: OpaquePointer?, out: UnsafeMutablePointer?, outLen: UnsafeMutablePointer?, + maxOut: Int +) -> ssl_private_key_result_t { + guard let ssl = ssl, let out = out, let outLen = outLen else { + preconditionFailure() + } + + let connection = SSLConnection.loadConnectionFromSSL(ssl) + var outBuffer = UnsafeMutableBufferPointer(start: out, count: maxOut) + let result = connection.customPrivateKeyComplete(out: &outBuffer) + + if result != ssl_private_key_success { + // We need to set outLen to zero here. + outLen.pointee = 0 + } else { + outLen.pointee = outBuffer.count + } + + return result +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/IdentityVerification.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/IdentityVerification.swift new file mode 100644 index 00000000..220f9468 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/IdentityVerification.swift @@ -0,0 +1,327 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + + +private let asciiIDNAIdentifier: ArraySlice = Array("xn--".utf8)[...] +private let asciiCapitals: ClosedRange = (UInt8(ascii: "A")...UInt8(ascii: "Z")) +private let asciiLowercase: ClosedRange = (UInt8(ascii: "a")...UInt8(ascii: "z")) +private let asciiNumbers: ClosedRange = (UInt8(ascii: "0")...UInt8(ascii: "9")) +private let asciiHyphen: UInt8 = UInt8(ascii: "-") +private let asciiPeriod: UInt8 = UInt8(ascii: ".") +private let asciiAsterisk: UInt8 = UInt8(ascii: "*") + + +extension String { + /// Calls `fn` with an `Array` pointing to a + /// non-NULL-terminated sequence of ASCII bytes. If the string this method + /// is called on contains non-ACSII code points, this method throws. + /// + /// This method exists to avoid doing repeated loops over the string buffer. + /// In a naive implementation we'd loop at least three times: once to lowercase + /// the string, once to get a buffer pointer to a contiguous buffer, and once + /// to confirm the string is ASCII. Here we can do that all in one loop. + fileprivate func withLowercaseASCIIBuffer(_ fn: (Array) throws -> T) throws -> T { + let buffer: [UInt8] = try self.utf8.map { codeUnit in + guard codeUnit.isValidDNSCharacter else { + throw NIOSSLExtraError.serverHostnameImpossibleToMatch(hostname: self) + } + + // We know we have only ASCII printables, we can safely unconditionally set the 6 bit to 1 to lowercase. + return codeUnit | (0x20) + } + + return try fn(buffer) + } +} + + +extension Collection { + /// Splits a collection in two around a given index. This index may be nil, in which case the split + /// will occur around the end. + fileprivate func splitAroundIndex(_ index: Index?) -> (SubSequence, SubSequence) { + guard let index = index else { + return (self[...], self[self.endIndex...]) + } + + let subsequentIndex = self.index(after: index) + return (self[.. Bool { + if let serverHostname = serverHostname { + return try serverHostname.withLowercaseASCIIBuffer { + try validIdentityForService(serverHostname: $0, + socketAddress: socketAddress, + leafCertificate: leafCertificate) + } + } else { + return try validIdentityForService(serverHostname: nil as Array?, + socketAddress: socketAddress, + leafCertificate: leafCertificate) + } +} + +private func validIdentityForService(serverHostname: Array?, + socketAddress: SocketAddress, + leafCertificate: NIOSSLCertificate) throws -> Bool { + // Before we begin, we want to locate the first period in our own domain name. We need to do + // this because we may need to match a wildcard label. + var serverHostnameSlice: ArraySlice? = nil + var firstPeriodIndex: ArraySlice.Index? = nil + + if let serverHostname = serverHostname { + var tempServerHostnameSlice = serverHostname[...] + + + // Strip trailing period + if tempServerHostnameSlice.last == .some(asciiPeriod) { + tempServerHostnameSlice = tempServerHostnameSlice.dropLast() + } + + firstPeriodIndex = tempServerHostnameSlice.firstIndex(of: asciiPeriod) + serverHostnameSlice = tempServerHostnameSlice + } + + // We want to begin by checking the subjectAlternativeName fields. If there are any fields + // in there that we could validate against (either IP or hostname) we will validate against + // them, and then refuse to check the commonName field. If there are no SAN fields to + // validate against, we'll check commonName. + var checkedMatch = false + if let alternativeNames = leafCertificate._subjectAlternativeNames() { + for name in alternativeNames { + checkedMatch = true + + switch name.nameType { + case .dnsName: + let dnsName = Array(name.contents) + if matchHostname(ourHostname: serverHostnameSlice, firstPeriodIndex: firstPeriodIndex, dnsName: dnsName) { + return true + } + case .ipAddress: + if let ip = _SubjectAlternativeName.IPAddress(name), + matchIpAddress(socketAddress: socketAddress, certificateIP: ip) + { + return true + } + default: + continue + } + } + } + + guard !checkedMatch else { + // We had some subject alternative names, but none matched. We failed here. + return false + } + + // In the absence of any matchable subjectAlternativeNames, we can fall back to checking + // the common name. This is a deprecated practice, and in a future release we should + // stop doing this. + guard let commonName = leafCertificate.commonName() else { + // No CN, no match. + return false + } + + // We have a common name. Let's check it against the provided hostname. We never check + // the common name against the IP address. + return matchHostname(ourHostname: serverHostnameSlice, firstPeriodIndex: firstPeriodIndex, dnsName: commonName) +} + + +private func matchHostname(ourHostname: ArraySlice?, firstPeriodIndex: ArraySlice.Index?, dnsName: Array) -> Bool { + guard let ourHostname = ourHostname else { + // No server hostname was provided, so we cannot match. + return false + } + + // Now we validate the cert hostname. + var dnsName = ArraySlice(dnsName) + guard let validatedHostname = AnalysedCertificateHostname(baseName: &dnsName) else { + // This is a hostname we can't match, return false. + return false + } + return validatedHostname.validMatchForName(ourHostname, firstPeriodIndexForName: firstPeriodIndex) +} + + +private func matchIpAddress(socketAddress: SocketAddress, certificateIP: _SubjectAlternativeName.IPAddress) -> Bool { + // These match if the two underlying IP address structures match. + switch (socketAddress, certificateIP) { + case (.v4(let address), .ipv4(var addr2)): + var addr1 = address.address.sin_addr + return memcmp(&addr1, &addr2, MemoryLayout.size) == 0 + case (.v6(let address), .ipv6(var addr2)): + var addr1 = address.address.sin6_addr + return memcmp(&addr1, &addr2, MemoryLayout.size) == 0 + default: + // Different protocol families, no match. + return false + } +} + + +/// This structure contains a certificate hostname that has been analysed and prepared for matching. +/// +/// A certificate hostname that is valid for matching meets the following criteria: +/// +/// 1. Contains only valid DNS characters, plus the ASCII asterisk. +/// 2. Contains zero or one ASCII asterisks. +/// 3. Any ASCII asterisk present must be in the first DNS label (i.e. before the first period). +/// 4. If the first label contains an ASCII asterisk, it must not also be an IDN A label. +/// +/// Answering these questions potentially relies on multiple searches through the hostname. That's not +/// ideal: it'd be better to do a single search that both validates the domain name meets the criteria +/// and that also records information needed to validate that the name matches the one we're searching for. +/// That's what this structure does. +fileprivate struct AnalysedCertificateHostname { + /// The type we use to store the base name. The other types on this object are chosen relative to that. + fileprivate typealias BaseNameType = ArraySlice + + private var name: NameType + + fileprivate init?(baseName: inout BaseNameType) { + // First, strip a trailing period from this name. + if baseName.last == .some(asciiPeriod) { + baseName = baseName.dropLast() + } + + // Ok, start looping. + var index = baseName.startIndex + var firstPeriodIndex: Optional = nil + var asteriskIndex: Optional = nil + + while index < baseName.endIndex { + switch baseName[index] { + case asciiPeriod where firstPeriodIndex == nil: + // This is the first period we've seen, great. Future + // periods will be ignored. + firstPeriodIndex = index + + case asciiCapitals, asciiLowercase, asciiNumbers, asciiHyphen, asciiPeriod: + // Valid character, no notes. + break + + case asciiAsterisk where asteriskIndex == nil && firstPeriodIndex == nil: + // Found an asterisk, it's the first one, and it precedes any periods. + asteriskIndex = index + + case asciiAsterisk: + // An extra asterisk, or an asterisk after a period, is unacceptable. + return nil + + default: + // Unacceptable character in the name. + return nil + } + + baseName.formIndex(after: &index) + } + + // Now we can finally initialize ourself. + if let asteriskIndex = asteriskIndex { + // One final check: if we found a wildcard, we need to confirm that the first label isn't an IDNA A label. + guard baseName.prefix(4) != asciiIDNAIdentifier else { + return nil + } + + self.name = .wildcard(baseName, asteriskIndex: asteriskIndex, firstPeriodIndex: firstPeriodIndex) + } else { + self.name = .singleName(baseName) + } + } + + /// Whether this parsed name is a valid match for the one passed in. + fileprivate func validMatchForName(_ target: BaseNameType, firstPeriodIndexForName: BaseNameType.Index?) -> Bool { + switch self.name { + case .singleName(let baseName): + // For non-wildcard names, we just do a straightforward string comparison. + return baseName == target + + case .wildcard(let baseName, asteriskIndex: let asteriskIndex, firstPeriodIndex: let firstPeriodIndex): + // The wildcard can appear more-or-less anywhere in the first label. The wildcard + // character itself can match any number of characters, though it must match at least + // one. + // The algorithm for this is simple: first, we split the two names on their first period to get their + // first label and their subsequent components. Second, we check that the subcomponents match a straightforward + // bytewise comparison: if that fails, we can avoid the expensive wildcard checking operation. + // Third, we split the wildcard label on the wildcard character, and and confirm that + // the characters *before* the wildcard are the prefix of the target first label, and that the + // characters *after* the wildcard are the suffix of the target first label. This works well because + // the empty string is a prefix and suffix of all strings. + let (wildcardLabel, remainingComponents) = baseName.splitAroundIndex(firstPeriodIndex) + let (targetFirstLabel, targetRemainingComponents) = target.splitAroundIndex(firstPeriodIndexForName) + + guard remainingComponents == targetRemainingComponents else { + // Wildcard is irrelevant, the remaining components don't match. + return false + } + + guard targetFirstLabel.count >= wildcardLabel.count else { + // The target label cannot possibly match the wildcard. + return false + } + + let (wildcardLabelPrefix, wildcardLabelSuffix) = wildcardLabel.splitAroundIndex(asteriskIndex) + + return (targetFirstLabel.prefix(wildcardLabelPrefix.count) == wildcardLabelPrefix && + targetFirstLabel.suffix(wildcardLabelSuffix.count) == wildcardLabelSuffix) + } + } +} + + +extension AnalysedCertificateHostname { + private enum NameType { + case wildcard(BaseNameType, asteriskIndex: BaseNameType.Index, firstPeriodIndex: Optional) + case singleName(BaseNameType) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/LinuxCABundle.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/LinuxCABundle.swift new file mode 100644 index 00000000..2702504f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/LinuxCABundle.swift @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Linux) || os(FreeBSD) +/// The path to the root CA bundle file. +/// +/// May be nil if we could not find the root CA bundle file. +internal let rootCAFilePath: String? = locateRootCAFile() + +/// The path to the root CA bundle directory. +/// +/// May be nil if we could not find the root CA bundle directory. +internal let rootCADirectoryPath: String? = locateRootCADirectory() + + +/// This is a list of root CA file search paths. This list contains paths as validated against several distributions. +/// If you are attempting to use SwiftNIO SSL on a platform that is not covered here and certificate validation is +/// failing, please open a pull request that adds the appropriate search path. +private let rootCAFileSearchPaths = [ + "/etc/ssl/certs/ca-certificates.crt", // Ubuntu, Debian, Arch, Alpine, + "/etc/pki/tls/certs/ca-bundle.crt", // Fedora +] + + +/// This is a list of root CA directory search paths. +/// +/// This list contains paths as validated against several distributions. If you are aware of a CA bundle on a specific distribution +/// that is not present here, please open a pull request that adds the appropriate search path. +/// Some distributions do not ship CA directories: as such, it is not a problem if a distribution that is present in rootCAFileSearchPaths +/// is not present in this list. +private let rootCADirectorySearchPaths = [ + "/etc/ssl/certs", // Ubuntu, Debian, Arch, Alpine +] + + +private func locateRootCAFile() -> String? { + // We need to find the root CA file. We have a list of search paths: let's use them. + return rootCAFileSearchPaths.first(where: { FileSystemObject.pathType(path: $0) == .file }) +} + +private func locateRootCADirectory() -> String? { + return rootCADirectorySearchPaths.first(where: { FileSystemObject.pathType(path: $0) == .directory }) +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLClientHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLClientHandler.swift new file mode 100644 index 00000000..f9c997ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLClientHandler.swift @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +extension String { + private func isIPAddress() -> Bool { + // We need some scratch space to let inet_pton write into. + var ipv4Addr = in_addr() + var ipv6Addr = in6_addr() + + return self.withCString { ptr in + return inet_pton(AF_INET, ptr, &ipv4Addr) == 1 || + inet_pton(AF_INET6, ptr, &ipv6Addr) == 1 + } + } + + func validateSNIServerName() throws { + guard !self.isIPAddress() else { + throw NIOSSLExtraError.cannotUseIPAddressInSNI(ipAddress: self) + } + + // no 0 bytes + guard !self.utf8.contains(0) else { + throw NIOSSLExtraError.invalidSNIHostname + } + + guard (1 ... 255).contains(self.utf8.count) else { + throw NIOSSLExtraError.invalidSNIHostname + } + } +} + +/// A channel handler that wraps a channel in TLS using NIOSSL. +/// This handler can be used in channels that are acting as the client +/// in the TLS dialog. For server connections, use the `NIOSSLServerHandler`. +public final class NIOSSLClientHandler: NIOSSLHandler { + public convenience init(context: NIOSSLContext, serverHostname: String?) throws { + try self.init(context: context, serverHostname: serverHostname, optionalCustomVerificationCallback: nil) + } + + @available(*, deprecated, renamed: "init(context:serverHostname:customVerificationCallback:)") + public init(context: NIOSSLContext, serverHostname: String?, verificationCallback: NIOSSLVerificationCallback? = nil) throws { + guard let connection = context.createConnection() else { + fatalError("Failed to create new connection in NIOSSLContext") + } + + connection.setConnectState() + if let serverHostname = serverHostname { + try serverHostname.validateSNIServerName() + + // IP addresses must not be provided in the SNI extension, so filter them. + do { + try connection.setServerName(name: serverHostname) + } catch { + preconditionFailure("Bug in NIOSSL (please report): \(Array(serverHostname.utf8)) passed NIOSSL's hostname test but failed in BoringSSL.") + } + } + + if let verificationCallback = verificationCallback { + connection.setVerificationCallback(verificationCallback) + } + + super.init(connection: connection, shutdownTimeout: context.configuration.shutdownTimeout) + } + + + public convenience init(context: NIOSSLContext, serverHostname: String?, customVerificationCallback: @escaping NIOSSLCustomVerificationCallback) throws { + try self.init(context: context, serverHostname: serverHostname, optionalCustomVerificationCallback: customVerificationCallback) + } + + // This exists to handle the explosion of initializers we got when I tried to deprecate the first one. At least they all pass through one path now. + private init(context: NIOSSLContext, serverHostname: String?, optionalCustomVerificationCallback: NIOSSLCustomVerificationCallback?) throws { + guard let connection = context.createConnection() else { + fatalError("Failed to create new connection in NIOSSLContext") + } + + connection.setConnectState() + if let serverHostname = serverHostname { + try serverHostname.validateSNIServerName() + + // IP addresses must not be provided in the SNI extension, so filter them. + do { + try connection.setServerName(name: serverHostname) + } catch { + preconditionFailure("Bug in NIOSSL (please report): \(Array(serverHostname.utf8)) passed NIOSSL's hostname test but failed in BoringSSL.") + } + } + + if let verificationCallback = optionalCustomVerificationCallback { + connection.setCustomVerificationCallback(CustomVerifyManager(callback: verificationCallback)) + } + + super.init(connection: connection, shutdownTimeout: context.configuration.shutdownTimeout) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLHandler.swift new file mode 100644 index 00000000..0a1c0e96 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLHandler.swift @@ -0,0 +1,759 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +@_implementationOnly import CNIOBoringSSL +import NIOTLS + +/// The base class for all NIOSSL handlers. This class cannot actually be instantiated by +/// users directly: instead, users must select which mode they would like their handler to +/// operate in, client or server. +/// +/// This class exists to deal with the reality that for almost the entirety of the lifetime +/// of a TLS connection there is no meaningful distinction between a server and a client. +/// For this reason almost the entirety of the implementation for the channel and server +/// handlers in NIOSSL is shared, in the form of this parent class. +public class NIOSSLHandler : ChannelInboundHandler, ChannelOutboundHandler, RemovableChannelHandler { + public typealias OutboundIn = ByteBuffer + public typealias OutboundOut = ByteBuffer + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + + private enum ConnectionState { + case idle + case handshaking + case active + case unwrapping(Scheduled) + case closing(Scheduled) + case unwrapped + case closed + } + + private var state: ConnectionState = .idle + private var connection: SSLConnection + private var plaintextReadBuffer: ByteBuffer? + private var bufferedWrites: MarkedCircularBuffer + private var closePromise: EventLoopPromise? + private var shutdownPromise: EventLoopPromise? + private var didDeliverData: Bool = false + private var storedContext: ChannelHandlerContext? = nil + private var shutdownTimeout: TimeAmount + + internal var channel: Channel? { + return self.storedContext?.channel + } + + internal init(connection: SSLConnection, shutdownTimeout: TimeAmount) { + self.connection = connection + self.bufferedWrites = MarkedCircularBuffer(initialCapacity: 96) // 96 brings the total size of the buffer to just shy of one page + self.shutdownTimeout = shutdownTimeout + } + + public func handlerAdded(context: ChannelHandlerContext) { + self.storedContext = context + self.connection.setAllocator(context.channel.allocator) + self.connection.parentHandler = self + self.connection.eventLoop = context.eventLoop + + self.plaintextReadBuffer = context.channel.allocator.buffer(capacity: SSL_MAX_RECORD_SIZE) + // If this channel is already active, immediately begin handshaking. + if context.channel.isActive { + doHandshakeStep(context: context) + } + } + + public func handlerRemoved(context: ChannelHandlerContext) { + /// Get the connection to drop any state it might have. This state can cause reference cycles, + /// so we need to break those when we know it's safe to do so. This is a good safe point, as no + /// further I/O can possibly occur. + self.connection.close() + + // We now want to drop the stored context. + self.storedContext = nil + } + + public func channelActive(context: ChannelHandlerContext) { + // We fire this a bit early, entirely on purpose. This is because + // in doHandshakeStep we may end up closing the channel again, and + // if we do we want to make sure that the channelInactive message received + // by later channel handlers makes sense. + context.fireChannelActive() + doHandshakeStep(context: context) + } + + public func channelInactive(context: ChannelHandlerContext) { + // This fires when the TCP connection goes away. Whatever happens, we end up in the closed + // state here. This function calls out to a lot of user code, so we need to make sure we're + // keeping track of the state we're in properly before we do anything else. + let oldState = state + state = .closed + let channelError: NIOSSLError + + switch oldState { + case .closed, .idle: + // Nothing to do, but discard any buffered writes we still have. + discardBufferedWrites(reason: ChannelError.ioOnClosedChannel) + // Return early + context.fireChannelInactive() + return + case .handshaking: + // In this case the channel is going through the doHandshake steps and + // a channelInactive is fired taking down the connection. + // This case propogates a .handshakeFailed instead of an .uncleanShutdown. + // We use a synthetic error here as the error stack will be empty, and we should try to + // provide some diagnostic help. + channelError = NIOSSLError.handshakeFailed(.sslError([.eofDuringHandshake])) + default: + // This is a ragged EOF: we weren't sent a CLOSE_NOTIFY. We want to send a user + // event to notify about this before we propagate channelInactive. We also want to fail all + // these writes. + channelError = NIOSSLError.uncleanShutdown + } + let shutdownPromise = self.shutdownPromise + self.shutdownPromise = nil + let closePromise = self.closePromise + self.closePromise = nil + + shutdownPromise?.fail(channelError) + closePromise?.fail(channelError) + context.fireErrorCaught(channelError) + discardBufferedWrites(reason: channelError) + + context.fireChannelInactive() + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let binaryData = unwrapInboundIn(data) + + // The logic: feed the buffers, then take an action based on state. + connection.consumeDataFromNetwork(binaryData) + + switch state { + case .handshaking: + doHandshakeStep(context: context) + case .active: + doDecodeData(context: context) + doUnbufferWrites(context: context) + case .closing: + // Handle both natural close events and close events where data is still in + // flight. Sending through doDecodeData will handle both conditions. + doDecodeData(context: context) + case .unwrapping: + self.doShutdownStep(context: context) + default: + context.fireErrorCaught(NIOSSLError.readInInvalidTLSState) + channelClose(context: context, reason: NIOSSLError.readInInvalidTLSState) + } + } + + public func channelReadComplete(context: ChannelHandlerContext) { + guard let receiveBuffer = self.plaintextReadBuffer else { + preconditionFailure("channelReadComplete called before handlerAdded") + } + + self.doFlushReadData(context: context, receiveBuffer: receiveBuffer, readOnEmptyBuffer: true) + self.writeDataToNetwork(context: context, promise: nil) + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + bufferWrite(data: unwrapOutboundIn(data), promise: promise) + } + + public func flush(context: ChannelHandlerContext) { + bufferFlush() + doUnbufferWrites(context: context) + } + + public func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + guard mode == .all else { + // TODO: Support also other modes ? + promise?.fail(ChannelError.operationUnsupported) + return + } + + switch state { + case .closing: + // We're in the process of TLS shutdown, so let's let that happen. However, + // we want to cascade the result of the first request into this new one. + if let promise = promise, let closePromise = self.closePromise { + closePromise.futureResult.cascade(to: promise) + } else if let promise = promise { + self.closePromise = promise + } + case .unwrapping(let scheduledShutdown): + // We've been asked to close the connection, but we were currently unwrapping. + // We don't have to send any CLOSE_NOTIFY, but we now need to upgrade ourselves: + // closing is a more extreme activity than unwrapping. + self.state = .closing(scheduledShutdown) + if let promise = promise, let closePromise = self.closePromise { + closePromise.futureResult.cascade(to: promise) + } else if let promise = promise { + self.closePromise = promise + } + case .idle: + state = .closed + fallthrough + case .closed, .unwrapped: + // For idle, closed, and unwrapped connections we immediately pass this on to the next + // channel handler. + context.close(promise: promise) + case .active, .handshaking: + // We need to begin processing shutdown now. We can't fire the promise for a + // while though. + self.state = .closing(self.scheduleTimedOutShutdown(context: context)) + closePromise = promise + doShutdownStep(context: context) + } + } + + /// Attempt to perform another stage of the TLS handshake. + /// + /// A TLS connection has a multi-step handshake that requires at least two messages sent by each + /// peer. As a result, a handshake will never complete in a single call to BoringSSL. This method + /// will call `doHandshake`, and will then attempt to write whatever data this generated to the + /// network. If we are waiting on data from the remote peer, this method will do nothing. + /// + /// This method must not be called once the connection is established. + private func doHandshakeStep(context: ChannelHandlerContext) { + let result = connection.doHandshake() + + switch result { + case .incomplete: + state = .handshaking + writeDataToNetwork(context: context, promise: nil) + case .complete: + do { + try validateHostname(context: context) + } catch { + // This counts as a failure. + context.fireErrorCaught(error) + channelClose(context: context, reason: error) + return + } + + state = .active + writeDataToNetwork(context: context, promise: nil) + + // TODO(cory): This event should probably fire out of the BoringSSL info callback. + let negotiatedProtocol = connection.getAlpnProtocol() + context.fireUserInboundEventTriggered(TLSUserEvent.handshakeCompleted(negotiatedProtocol: negotiatedProtocol)) + + // We need to unbuffer any pending writes and reads. We will have pending writes if the user attempted to + // write before we completed the handshake. We may also have pending reads if the user sent data immediately + // after their FINISHED record. We decode the reads first, as those reads may trigger writes. + self.doDecodeData(context: context) + self.doUnbufferWrites(context: context) + case .failed(let err): + writeDataToNetwork(context: context, promise: nil) + + // If there's a failed private key operation, we fire both errors. + if case .failure(let privateKeyError) = self.connection.customPrivateKeyResult { + context.fireErrorCaught(privateKeyError) + } + + context.fireErrorCaught(NIOSSLError.handshakeFailed(err)) + channelClose(context: context, reason: NIOSSLError.handshakeFailed(err)) + } + } + + /// Attempt to perform a stage of orderly TLS shutdown. + /// + /// Orderly TLS shutdown requires each peer to send a TLS CloseNotify message. + /// This message is a signal that the data being sent has been completely sent, + /// without truncation. Where possible we attempt to perform an orderly shutdown, + /// and so we will send a CloseNotify. We also try to wait for the remote peer to + /// send a CloseNotify in response. This means we may call this multiple times, + /// potentially writing our own CloseNotify each time. + /// + /// Once `state` has transitioned to `.closed`, further calls to this method will + /// do nothing. + private func doShutdownStep(context: ChannelHandlerContext) { + if case .closed = self.state { + return + } + + let result = connection.doShutdown() + + var uncleanScheduledShutdown: Scheduled? + let targetCompleteState: ConnectionState + switch self.state { + case .closing(let scheduledShutdown): + uncleanScheduledShutdown = scheduledShutdown + targetCompleteState = .closed + case .unwrapping(let scheduledShutdown): + uncleanScheduledShutdown = scheduledShutdown + targetCompleteState = .unwrapped + default: + preconditionFailure("Shutting down in a non-shutting-down state") + } + + switch result { + case .incomplete: + writeDataToNetwork(context: context, promise: nil) + case .complete: + uncleanScheduledShutdown?.cancel() + self.state = targetCompleteState + writeDataToNetwork(context: context, promise: nil) + + // TODO(cory): This should probably fire out of the BoringSSL info callback. + context.fireUserInboundEventTriggered(TLSUserEvent.shutdownCompleted) + + switch targetCompleteState { + case .closed: + self.channelClose(context: context, reason: NIOTLSUnwrappingError.closeRequestedDuringUnwrap) + case .unwrapped: + self.channelUnwrap(context: context) + default: + preconditionFailure("Cannot be in \(targetCompleteState) at this code point") + } + case .failed(let err): + uncleanScheduledShutdown?.cancel() + // TODO(cory): This should probably fire out of the BoringSSL info callback. + context.fireErrorCaught(NIOSSLError.shutdownFailed(err)) + channelClose(context: context, reason: NIOSSLError.shutdownFailed(err)) + } + } + + /// Creates a scheduled task to perform an unclean shutdown in event of a clean shutdown timing + /// out. This task should be cancelled if the shutdown does not time out. + private func scheduleTimedOutShutdown(context: ChannelHandlerContext) -> Scheduled { + return context.eventLoop.scheduleTask(in: self.shutdownTimeout) { + switch self.state { + case .idle, .handshaking, .active: + preconditionFailure("Cannot schedule timed out shutdown on non-shutting down handler") + + case .closed, .unwrapped: + // This means we raced with the shutdown completing. We just let this one go: do nothing. + return + + case .closing: + // We're closing, the only thing we do here is exit. + self.state = .closed + self.channelClose(context: context, reason: NIOSSLCloseTimedOutError()) + + case .unwrapping: + // The user only wants us to error and unwrap, not to close. + self.state = .unwrapped + self.channelUnwrap(context: context, failedWithError: NIOSSLCloseTimedOutError()) + } + } + } + + /// Loops over the `SSL` object, decoding encrypted application data until there is + /// no more available. + private func doDecodeData(context: ChannelHandlerContext) { + guard var receiveBuffer = self.plaintextReadBuffer else { + preconditionFailure("didDecodeData called without handlerAdded firing.") + } + + // We nil the read buffer here. This is done on purpose: we do it to ensure + // that we don't have two references to the buffer, otherwise readDataFromNetwork + // will trigger a CoW every time. We need to put this back on every exit from this + // function, or before any call-out, to avoid re-entrancy issues. We validate the + // requirement for this being non-nil on exit at the very least. + self.plaintextReadBuffer = nil + defer { + assert(self.plaintextReadBuffer != nil) + } + + readLoop: while true { + let result = connection.readDataFromNetwork(outputBuffer: &receiveBuffer) + + switch result { + case .complete: + // Good read. Keep going + continue readLoop + + case .incomplete: + self.plaintextReadBuffer = receiveBuffer + break readLoop + + case .failed(BoringSSLError.zeroReturn): + switch self.state { + case .idle, .handshaking: + preconditionFailure("Should not get zeroReturn in \(self.state)") + case .closed, .unwrapped: + // This is an unexpected place to be, but it's not totally impossible. Assume this + // is the result of a wonky I/O pattern and just ignore it. + self.plaintextReadBuffer = receiveBuffer + break readLoop + case .active: + self.state = .closing(self.scheduleTimedOutShutdown(context: context)) + case .unwrapping, .closing: + break + } + + // This is a clean EOF: we can just start doing our own clean shutdown. + self.doFlushReadData(context: context, receiveBuffer: receiveBuffer, readOnEmptyBuffer: false) + doShutdownStep(context: context) + writeDataToNetwork(context: context, promise: nil) + break readLoop + + case .failed(let err): + self.state = .closed + self.plaintextReadBuffer = receiveBuffer + context.fireErrorCaught(err) + channelClose(context: context, reason: err) + break readLoop + } + } + } + + /// Flushes any pending read plaintext. This is called whenever we hit a flush + /// point for reads: either channelReadComplete, or we receive a CLOSE_NOTIFY. + /// + /// This function will always set the empty buffer back to be the plaintext read buffer. + /// Do not do this in your own code. + private func doFlushReadData(context: ChannelHandlerContext, receiveBuffer: ByteBuffer, readOnEmptyBuffer: Bool) { + defer { + // All exits from this function must restore the plaintext read buffer. + assert(self.plaintextReadBuffer != nil) + } + + // We only want to fire channelReadComplete in a situation where we have actually sent the user some data, otherwise + // we'll be confusing the hell out of them. + if receiveBuffer.writerIndex > receiveBuffer.readerIndex { + // We need to be very careful here: we must not call out before we fix up our local view of this buffer. In this + // case, we're going to set the indices back to where they were. In this case we are deliberately *not* calling + // clear(), as we don't want to trigger a CoW for our own local refs. + var ourNewBuffer = receiveBuffer + ourNewBuffer.moveReaderIndex(to: 0) + ourNewBuffer.moveWriterIndex(to: 0) + self.plaintextReadBuffer = ourNewBuffer + + // Ok, we can now pass the receive buffer on and fire channelReadComplete. + context.fireChannelRead(self.wrapInboundOut(receiveBuffer)) + context.fireChannelReadComplete() + } else if readOnEmptyBuffer { + // We didn't deliver data, but the channel is still active. If this channel has got + // autoread turned off then we should call read again, because otherwise the user + // will never see any result from their read call. + self.plaintextReadBuffer = receiveBuffer + context.channel.getOption(ChannelOptions.autoRead).whenSuccess { autoRead in + if !autoRead { + context.read() + } + } + } else { + // Regardless of what happens here, we need to put the plaintext read buffer back. Very important. + self.plaintextReadBuffer = receiveBuffer + } + } + + /// Encrypts application data and writes it to the channel. + /// + /// This method always flushes. For this reason, it should only ever be called when a flush + /// is intended. + private func writeDataToNetwork(context: ChannelHandlerContext, promise: EventLoopPromise?) { + // There may be no data to write, in which case we can just exit early. + guard let dataToWrite = connection.getDataForNetwork() else { + if let promise = promise { + // If we have a promise, we need to enforce ordering so we issue a zero-length write that + // the event loop will have to handle. + let buffer = context.channel.allocator.buffer(capacity: 0) + context.writeAndFlush(wrapInboundOut(buffer), promise: promise) + } + return + } + + context.writeAndFlush(self.wrapInboundOut(dataToWrite), promise: promise) + } + + /// Close the underlying channel. + /// + /// This method does not perform any kind of I/O. Instead, it simply calls ChannelHandlerContext.close with + /// any promise we may have already been given. It also transitions our state into closed. This should only be + /// used to clean up after an error, or to perform the final call to close after a clean shutdown attempt. + private func channelClose(context: ChannelHandlerContext, reason: Error) { + state = .closed + + let shutdownPromise = self.shutdownPromise + self.shutdownPromise = nil + + let closePromise = self.closePromise + self.closePromise = nil + + shutdownPromise?.fail(reason) + context.close(promise: closePromise) + } + + private func channelUnwrap(context: ChannelHandlerContext, failedWithError error: Error? = nil) { + assert(self.closePromise == nil) + self.state = .unwrapped + + let shutdownPromise = self.shutdownPromise + self.shutdownPromise = nil + + // We create a promise here to make sure we operate in the special magic state + // where we are not in the pipeline any more, but we still have a valid context. + let removalPromise: EventLoopPromise = context.eventLoop.makePromise() + let removalFuture = removalPromise.futureResult.map { + // Now drop the writes. + self.discardBufferedWrites(reason: NIOTLSUnwrappingError.unflushedWriteOnUnwrap) + + if let unconsumedData = self.connection.extractUnconsumedData() { + context.fireChannelRead(self.wrapInboundOut(unconsumedData)) + } + + if let error = error { + context.fireErrorCaught(error) + } + } + + if let promise = shutdownPromise { + removalFuture.whenComplete { result in + switch (result, error) { + case(.success, .none): + promise.succeed(()) + case (.success, .some(let error)): + promise.fail(error) + case (.failure(let failure), _): + promise.fail(failure) + } + } + removalFuture.cascade(to: promise) + } + + // Ok, we've unwrapped. Let's get out of the channel. + context.channel.pipeline.removeHandler(context: context, promise: removalPromise) + } + + /// Validates the hostname from the certificate against the hostname provided by + /// the user, assuming one has been provided at all. + private func validateHostname(context: ChannelHandlerContext) throws { + guard connection.validateHostnames else { + return + } + + // If there is no remote address, something weird is happening here. We can't + // validate a certificate without it, so bail. + guard let ipAddress = context.channel.remoteAddress else { + throw NIOSSLError.cannotFindPeerIP + } + + try connection.validateHostname(address: ipAddress) + } +} + +extension NIOSSLHandler { + /// Variable that can be queried during the connection lifecycle to grab the `TLSVersion` used on the `SSLConnection`. + public var tlsVersion: TLSVersion? { + return self.connection.getTLSVersionForConnection() + } +} + +extension Channel { + /// API to extract the `TLSVersion` from an EventLoopFuture. + public func nioSSL_tlsVersion() -> EventLoopFuture { + return self.pipeline.handler(type: NIOSSLHandler.self).map { + $0.tlsVersion + } + } +} + +extension ChannelPipeline.SynchronousOperations { + /// API to query the `TLSVersion` directly from the `ChannelPipeline`. + public func nioSSL_tlsVersion() throws -> TLSVersion? { + let handler = try self.handler(type: NIOSSLHandler.self) + return handler.tlsVersion + } +} + +// MARK:- Extension APIs for users. +extension NIOSSLHandler { + /// Called to instruct this handler to perform an orderly TLS shutdown and then remove itself + /// from the pipeline. This will leave the connection established, but remove the TLS wrapper + /// from it. + /// + /// This will send a CLOSE_NOTIFY and wait for the corresponding CLOSE_NOTIFY. When that next + /// CLOSE_NOTIFY is received, this handler will pass on all pending writes and remove itself + /// from the channel pipeline. If the shutdown times out then an error will fire down the + /// pipeline, this handler will remove itself from the pipeline, but the channel will not be + /// automatically closed. + /// + /// This function **is not thread-safe**: you **must** call it from the correct event + /// loop thread. + /// + /// - parameters: + /// - promise: An `EventLoopPromise` that will be completed when the unwrapping has + /// completed. + public func stopTLS(promise: EventLoopPromise?) { + switch self.state { + case .unwrapping, .closing: + // We're shutting down here. Nothing has to be done, but we should keep track of this promise. + if let promise = promise, let shutdownPromise = self.shutdownPromise { + shutdownPromise.futureResult.cascade(to: promise) + } else if let promise = promise { + self.shutdownPromise = promise + } + + case .idle: + // We've never activated, it's easy to remove TLS from a connection that never had it. + guard let storedContext = self.storedContext else { + promise?.fail(NIOTLSUnwrappingError.invalidInternalState) + return + } + + self.state = .unwrapped + self.shutdownPromise = promise + self.channelUnwrap(context: storedContext) + + case .handshaking, .active: + // Time to try to strip TLS. + guard let storedContext = self.storedContext else { + promise?.fail(NIOTLSUnwrappingError.invalidInternalState) + return + } + + self.state = .unwrapping(self.scheduleTimedOutShutdown(context: storedContext)) + self.shutdownPromise = promise + self.doShutdownStep(context: storedContext) + + case .unwrapped: + // We are already unwrapped. Succeed the promise, do nothing. + promise?.succeed(()) + + case .closed: + promise?.fail(NIOTLSUnwrappingError.alreadyClosed) + } + } +} + + +// MARK: Code that handles buffering/unbuffering writes. +extension NIOSSLHandler { + private typealias BufferedWrite = (data: ByteBuffer, promise: EventLoopPromise?) + + private func bufferWrite(data: ByteBuffer, promise: EventLoopPromise?) { + bufferedWrites.append((data: data, promise: promise)) + } + + private func bufferFlush() { + bufferedWrites.mark() + } + + private func discardBufferedWrites(reason: Error) { + while self.bufferedWrites.count > 0 { + let bufferedWrite = self.bufferedWrites.removeFirst() + bufferedWrite.promise?.fail(reason) + } + } + + private func doUnbufferWrites(context: ChannelHandlerContext) { + // Return early if the user hasn't called flush. + guard bufferedWrites.hasMark else { + return + } + + // These are some annoying variables we use to persist state across invocations of + // our closures. A better version of this code might be able to simplify this somewhat. + var promises: [EventLoopPromise] = [] + var didWrite = false + + do { + try bufferedWrites.forEachElementUntilMark { element in + var data = element.data + let writeSuccessful = try self._encodeSingleWrite(buf: &data) + if writeSuccessful { + didWrite = true + if let promise = element.promise { promises.append(promise) } + } + return writeSuccessful + } + + // If we got this far and did a write, we should shove the data out to the + // network. + if didWrite { + let ourPromise: EventLoopPromise? = promises.flattenPromises(on: context.eventLoop) + self.writeDataToNetwork(context: context, promise: ourPromise) + } + } catch { + // We encountered an error, it's cleanup time. Close ourselves down. + channelClose(context: context, reason: error) + // Fail any writes we've previously encoded but not flushed. + promises.forEach { $0.fail(error) } + // Fail everything else. + self.discardBufferedWrites(reason: error) + } + } + + /// Given a ByteBuffer to encode, passes it to BoringSSL and handles the result. + private func _encodeSingleWrite(buf: inout ByteBuffer) throws -> Bool { + let result = self.connection.writeDataToNetwork(&buf) + + switch result { + case .complete: + return true + case .incomplete: + // Ok, we can't write. Let's stop. + return false + case .failed(let err): + // Once a write fails, all writes must fail. This includes prior writes + // that successfully made it through BoringSSL. + throw err + } + } +} + +fileprivate extension MarkedCircularBuffer { + mutating func forEachElementUntilMark(callback: (Element) throws -> Bool) rethrows { + // This function generates quite a lot of ARC traffic, as it needs to pass a copy of .first + // into the closure. Sadly, MarkedCircularBuffer won't let us put something in _front_ of the + // marked index, so we cannot ensure that everything has only one owner here. Until we can + // do something about that, we just have to live with this. + while try self.hasMark && callback(self.first!) { + _ = self.removeFirst() + } + } +} + + +fileprivate extension Array where Element == EventLoopPromise { + /// Given an array of promises, flattens it out to a single promise. + /// If the array is empty, returns nil. + func flattenPromises(on loop: EventLoop) -> EventLoopPromise? { + guard self.count > 0 else { + return nil + } + + let ourPromise = loop.makePromise(of: Void.self) + + // We don't use cascade here because cascade has to create one closure per + // promise. We can do better by creating only a single closure that dispatches + // the result to all promises. + ourPromise.futureResult.whenComplete { result in + switch result { + case .success: + self.forEach { $0.succeed(()) } + case .failure(let error): + self.forEach { $0.fail(error) } + } + } + + return ourPromise + } +} + + +// MARK:- Code for handling asynchronous handshake resumption. +extension NIOSSLHandler { + internal func resumeHandshake() { + guard let storedContext = self.storedContext else { + // Oh well, the connection is dead. Do nothing. + return + } + + self.doHandshakeStep(context: storedContext) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLServerHandler.swift new file mode 100644 index 00000000..5f98fee1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/NIOSSLServerHandler.swift @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A channel handler that wraps a channel in TLS using NIOSSL. This +/// handler can be used in channels that are acting as the server in +/// the TLS dialog. For client connections, use the `NIOSSLClientHandler`. +public final class NIOSSLServerHandler: NIOSSLHandler { + public convenience init(context: NIOSSLContext) { + self.init(context: context, optionalCustomVerificationCallback: nil) + } + + @available(*, deprecated, renamed: "init(context:customVerificationCallback:)") + public init(context: NIOSSLContext, verificationCallback: NIOSSLVerificationCallback? = nil) throws { + guard let connection = context.createConnection() else { + fatalError("Failed to create new connection in NIOSSLContext") + } + + connection.setAcceptState() + + if let verificationCallback = verificationCallback { + connection.setVerificationCallback(verificationCallback) + } + + super.init(connection: connection, shutdownTimeout: context.configuration.shutdownTimeout) + } + + public convenience init(context: NIOSSLContext, customVerificationCallback: @escaping NIOSSLCustomVerificationCallback) { + self.init(context: context, optionalCustomVerificationCallback: customVerificationCallback) + } + + /// This exists to handle the explosion of initializers I got when I deprecated the first one. + private init(context: NIOSSLContext, optionalCustomVerificationCallback: NIOSSLCustomVerificationCallback?) { + guard let connection = context.createConnection() else { + fatalError("Failed to create new connection in NIOSSLContext") + } + + connection.setAcceptState() + + if let customVerificationCallback = optionalCustomVerificationCallback { + connection.setCustomVerificationCallback(.init(callback: customVerificationCallback)) + } + + super.init(connection: connection, shutdownTimeout: context.configuration.shutdownTimeout) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ObjectIdentifier.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ObjectIdentifier.swift new file mode 100644 index 00000000..6b53c33d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/ObjectIdentifier.swift @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL +@_implementationOnly import CNIOBoringSSLShims + +/// Object Identifier (OID) +public struct NIOSSLObjectIdentifier: Hashable { + fileprivate final class Storage { + + /// All operations accessing `reference` need to be implemented while guaranteeing that the enclosing `self` has a reference count of at least one. + /// Otherwise `reference` could already be freed. This would result in undefined behaviour as we access a dangling pointer. + /// One way we can guarantee this is by implementation all operations as methods/computed properties on `Storage`. + /// Swift guarantees that `self` is not deallocated during the execution of a method/computed property on `self`. + private let reference: OpaquePointer + + fileprivate init?(_ string: String) { + let result = string.withCString { string in + // If no_name (the last parameter of CNIOBoringSSL_OBJ_txt2obj) is 0 then long names and + // short names will be interpreted as well as numerical forms. + // If no_name is 1 only the numerical form is acceptable. + // source: https://www.openssl.org/docs/manmaster/man3/OBJ_txt2obj.html + CNIOBoringSSL_OBJ_txt2obj(string, 1) + } + guard let reference = result else { + return nil + } + self.reference = reference + } + + fileprivate init(takingOwnershipOf reference: OpaquePointer) { + self.reference = reference + } + + deinit { + CNIOBoringSSL_ASN1_OBJECT_free(reference) + } + } + + private let storage: Storage + + /// Creates a Object Identifier (OID) from its textual dotted representation (e.g. `1.2.3`) + /// - Parameter string: textual dotted representation of an OID + public init?(_ string: String) { + guard let storage = Storage(string) else { + return nil + } + self.storage = storage + } + + /// Creates an Object Identifier (OID) from an OpenSSL reference. + /// - Note: initialising an ``NIOSSLObjectIdentifier`` takes ownership of the reference and will free it after the reference count drops to zero + /// - Parameter reference: reference to a valid OpenSSL OID aka OBJ + internal init(takingOwnershipOf reference: OpaquePointer) { + self.storage = Storage(takingOwnershipOf: reference) + } +} + +extension NIOSSLObjectIdentifier.Storage: Equatable { + fileprivate static func == (lhs: NIOSSLObjectIdentifier.Storage, rhs: NIOSSLObjectIdentifier.Storage) -> Bool { + CNIOBoringSSL_OBJ_cmp(lhs.reference, rhs.reference) == 0 + } +} + +extension NIOSSLObjectIdentifier.Storage: Hashable { + fileprivate func hash(into hasher: inout Hasher) { + let length = CNIOBoringSSL_OBJ_length(self.reference) + let data = CNIOBoringSSL_OBJ_get0_data(self.reference) + let buffer = UnsafeRawBufferPointer(start: data, count: length) + hasher.combine(bytes: buffer) + } +} + +extension NIOSSLObjectIdentifier.Storage: LosslessStringConvertible { + fileprivate var description: String { + var failed = false + let oid = String(customUnsafeUninitializedCapacity: 80) { buffer in + // OBJ_obj2txt() is awkward and messy to use: it doesn't follow the convention of other OpenSSL functions where the buffer can be set to NULL to determine the amount of data that should be written. Instead buf must point to a valid buffer and buf_len should be set to a positive value. A buffer length of 80 should be more than enough to handle any OID encountered in practice. + // source: https://linux.die.net/man/3/obj_obj2txt + let result = buffer.withMemoryRebound(to: CChar.self) { buffer in + // If no_name (the last argument of CNIOBoringSSL_OBJ_obj2txt) is 0 then + // if the object has a long or short name then that will be used, + // otherwise the numerical form will be used. + // If no_name is 1 then the numerical form will always be used. + // source: https://www.openssl.org/docs/manmaster/man3/OBJ_obj2txt.html + CNIOBoringSSL_OBJ_obj2txt(buffer.baseAddress, Int32(buffer.count), self.reference, 1) + } + guard result >= 0 else { + // result of -1 indicates an error + failed = true + return 0 + } + return Int(result) + } + guard !failed else { + return "failed to convert OID to string" + } + return oid + } +} + +extension NIOSSLObjectIdentifier: LosslessStringConvertible { + public var description: String { + self.storage.description + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/PosixPort.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/PosixPort.swift new file mode 100644 index 00000000..225ef815 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/PosixPort.swift @@ -0,0 +1,154 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// This file contains a version of the SwiftNIO Posix enum. This is necessary +// because SwiftNIO's version is internal. Our version exists for the same reason: +// to ensure errno is captured correctly when doing syscalls, and that no ARC traffic +// can happen inbetween that *could* change the errno value before we were able to +// read it. +// +// The code is an exact port from SwiftNIO, so if that version ever becomes public we +// can lift anything missing from there and move it over without change. +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +import NIOCore + +#if os(Android) +internal typealias FILEPointer = OpaquePointer +#else +internal typealias FILEPointer = UnsafeMutablePointer +#endif + +private let sysFopen: @convention(c) (UnsafePointer?, UnsafePointer?) -> FILEPointer? = fopen +private let sysMlock: @convention(c) (UnsafeRawPointer?, size_t) -> CInt = mlock +private let sysMunlock: @convention(c) (UnsafeRawPointer?, size_t) -> CInt = munlock +private let sysFclose: @convention(c) (FILEPointer?) -> CInt = fclose + +// Sadly, stat, lstat, and readlink have different signatures with glibc and macOS libc. +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(Android) +private let sysStat: @convention(c) (UnsafePointer?, UnsafeMutablePointer?) -> CInt = stat(_:_:) +private let sysReadlink: @convention(c) (UnsafePointer?, UnsafeMutablePointer?, Int) -> Int = readlink +private let sysLstat: @convention(c) (UnsafePointer?, UnsafeMutablePointer?) -> Int32 = lstat + +#elseif os(Linux) || os(FreeBSD) +private let sysStat: @convention(c) (UnsafePointer, UnsafeMutablePointer) -> CInt = stat(_:_:) +private let sysReadlink: @convention(c) (UnsafePointer, UnsafeMutablePointer, Int) -> Int = readlink +private let sysLstat: @convention(c) (UnsafePointer, UnsafeMutablePointer) -> Int32 = lstat +#endif + + +// MARK:- Copied code from SwiftNIO +private func isUnacceptableErrno(_ code: CInt) -> Bool { + switch code { + case EFAULT, EBADF: + return true + default: + return false + } +} + +/* Sorry, we really try hard to not use underscored attributes. In this case however we seem to break the inlining threshold which makes a system call take twice the time, ie. we need this exception. */ +@inline(__always) +internal func wrapSyscall(where function: String = #function, _ body: () throws -> T) throws -> T { + while true { + let res = try body() + if res == -1 { + let err = errno + if err == EINTR { + continue + } + assert(!isUnacceptableErrno(err), "unacceptable errno \(err) \(strerror(err)!)") + throw IOError(errnoCode: err, reason: function) + } + return res + } +} + +/* Sorry, we really try hard to not use underscored attributes. In this case however we seem to break the inlining threshold which makes a system call take twice the time, ie. we need this exception. */ +@inline(__always) +internal func wrapErrorIsNullReturnCall(where function: String = #function, _ body: () throws -> T?) throws -> T { + while true { + guard let res = try body() else { + let err = errno + if err == EINTR { + continue + } + assert(!isUnacceptableErrno(err), "unacceptable errno \(err) \(strerror(err)!)") + throw IOError(errnoCode: err, reason: function) + } + return res + } +} + +// MARK:- Our functions +internal enum Posix { + @inline(never) + internal static func fopen(file: UnsafePointer, mode: UnsafePointer) throws -> FILEPointer { + return try wrapErrorIsNullReturnCall { + sysFopen(file, mode) + } + } + + @inline(never) + internal static func fclose(file: FILEPointer) throws -> CInt { + return try wrapSyscall { + sysFclose(file) + } + } + + @inline(never) + internal static func readlink(path: UnsafePointer, buf: UnsafeMutablePointer, bufSize: Int) throws -> Int { + return try wrapSyscall { + sysReadlink(path, buf, bufSize) + } + } + + @inline(never) + @discardableResult + internal static func stat(path: UnsafePointer, buf: UnsafeMutablePointer) throws -> CInt { + return try wrapSyscall { + sysStat(path, buf) + } + } + + @inline(never) + @discardableResult + internal static func lstat(path: UnsafePointer, buf: UnsafeMutablePointer) throws -> Int32 { + return try wrapSyscall { + sysLstat(path, buf) + } + } + + @inline(never) + @discardableResult + internal static func mlock(addr: UnsafeRawPointer, len: size_t) throws -> CInt { + return try wrapSyscall { + sysMlock(addr, len) + } + } + + @inline(never) + @discardableResult + internal static func munlock(addr: UnsafeRawPointer, len: size_t) throws -> CInt { + return try wrapSyscall { + sysMunlock(addr, len) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCallbacks.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCallbacks.swift new file mode 100644 index 00000000..2d62b6ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCallbacks.swift @@ -0,0 +1,245 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +/// The result of an attempt to verify an X.509 certificate. +public enum NIOSSLVerificationResult { + /// The certificate was successfully verified. + case certificateVerified + + /// The certificate was not verified. + case failed + + internal init(fromBoringSSLPreverify preverify: CInt) { + switch preverify { + case 1: + self = .certificateVerified + case 0: + self = .failed + default: + preconditionFailure("Invalid preverify value: \(preverify)") + } + } +} + +/// A custom verification callback. +/// +/// This verification callback is usually called more than once per connection, as it is called once +/// per certificate in the peer's complete certificate chain (including the root CA). The calls proceed +/// from root to leaf, ending with the peer's leaf certificate. Each time it is invoked with 2 arguments: +/// +/// 1. The result of the BoringSSL verification for this certificate +/// 2. The `SSLCertificate` for this level of the chain. +/// +/// Please be cautious with calling out from this method. This method is always invoked on the event loop, +/// so you must not block or wait. It is not possible to return an `EventLoopFuture` from this method, as it +/// must not block or wait. Additionally, this method must take care to ensure that it does not cause any +/// ChannelHandler to recursively call back into the `NIOSSLHandler` that triggered it, as making re-entrant +/// calls into BoringSSL is not supported by SwiftNIO and leads to undefined behaviour. +/// +/// In general, the only safe thing to do here is to either perform some cryptographic operations, to log, +/// or to store the `NIOSSLCertificate` somewhere for later consumption. The easiest way to be sure that the +/// `NIOSSLCertificate` is safe to consume is to wait for a user event that shows the handshake as completed, +/// or for channelInactive. +/// +/// warning: This callback uses the old-style OpenSSL callback behaviour and is excessively complex to program with. +/// Instead, prefer using the NIOSSLCustomVerificationCallback style which receives the entire trust chain at once, +/// and also supports asynchronous certificate verification. +public typealias NIOSSLVerificationCallback = (NIOSSLVerificationResult, NIOSSLCertificate) -> NIOSSLVerificationResult + + +/// A custom verification callback that allows completely overriding the certificate verification logic of BoringSSL. +/// +/// This verification callback is called no more than once per connection attempt. It is invoked with two arguments: +/// +/// 1. The certificate chain presented by the peer, in the order the peer presented them (with the first certificate +/// being the leaf certificate presented by the peer). +/// 2. An `EventLoopPromise` that must be completed to signal the result of the verification. +/// +/// Please be cautious with calling out from this method. This method is always invoked on the event loop, +/// so you must not block or wait. However, you may perform asynchronous work by leaving the event loop context: +/// when the verification is complete you must complete the provided `EventLoopPromise`. +/// +/// This method must take care to ensure that it does not cause any `ChannelHandler` to recursively call back into +/// the `NIOSSLHandler` that triggered it, as making re-entrant calls into BoringSSL is not supported by SwiftNIO and +/// leads to undefined behaviour. It is acceptable to leave the event loop context and then call into the `NIOSSLHandler`, +/// as this will not be re-entrant. +/// +/// Note that setting this callback will override _all_ verification logic that BoringSSL provides. +public typealias NIOSSLCustomVerificationCallback = ([NIOSSLCertificate], EventLoopPromise) -> Void + + +/// A callback that can be used to implement `SSLKEYLOGFILE` support. +/// +/// Wireshark can decrypt packet captures that contain encrypted TLS connections if they have access to the +/// session keys used to perform the encryption. These keys are normally stored in a file that has a specific +/// file format. This callback is the low-level primitive that can be used to write such a file. +/// +/// When set, this callback will be invoked once per secret. The provided `ByteBuffer` will contain the bytes +/// that need to be written into the file, including the newline character. +/// +/// - warning: Please be aware that enabling support for `SSLKEYLOGFILE` through this callback will put the secrecy of +/// your connections at risk. You should only do so when you are confident that it will not be possible to +/// extract those secrets unnecessarily. +/// +public typealias NIOSSLKeyLogCallback = (ByteBuffer) -> Void + + +/// An object that provides helpers for working with a NIOSSLKeyLogCallback +internal struct KeyLogCallbackManager { + private var callback: NIOSSLKeyLogCallback + + init(callback: @escaping NIOSSLKeyLogCallback) { + self.callback = callback + } +} + +extension KeyLogCallbackManager { + /// Called to log a string to the user. + func log(_ stringPointer: UnsafePointer) { + let len = strlen(stringPointer) + + // We don't cache this because `log` can be called from arbitrary threads concurrently. + var scratchBuffer = ByteBufferAllocator().buffer(capacity: len + 1) + + let bufferPointer = UnsafeRawBufferPointer(start: stringPointer, count: Int(len)) + scratchBuffer.writeBytes(bufferPointer) + scratchBuffer.writeInteger(UInt8(ascii: "\n")) + self.callback(scratchBuffer) + } +} + + +/// A struct that provides helpers for working with a NIOSSLCustomVerificationCallback. +internal struct CustomVerifyManager { + private var callback: CallbackType + + private var result: PendingResult = .notStarted + + init(callback: @escaping NIOSSLCustomVerificationCallback) { + self.callback = .public(callback) + } + + init(callback: @escaping InternalCallback) { + self.callback = .internal(callback) + } +} + + +extension CustomVerifyManager { + private enum PendingResult: Hashable { + case notStarted + + case pendingResult + + case complete(NIOSSLVerificationResult) + } +} + + +extension CustomVerifyManager { + mutating func process(on connection: SSLConnection) -> ssl_verify_result_t { + // First, check if we have a result. + switch self.result { + case .complete(.certificateVerified): + return ssl_verify_ok + case .complete(.failed): + return ssl_verify_invalid + case .pendingResult: + // Ask me again. + return ssl_verify_retry + case .notStarted: + // The rest of this method handles this case. + break + } + + self.result = .pendingResult + + // Ok, no result. We need a promise for the user to use to supply a result. + guard let eventLoop = connection.eventLoop else { + // No event loop. We cannot possibly be negotiating here. + preconditionFailure("No event loop present") + } + + let promise = eventLoop.makePromise(of: NIOSSLVerificationResult.self) + + // We need to attach our "do the thing" callback. This will always invoke the "ask me again" API, and it will do so in a separate + // event loop tick to avoid awkward re-entrancy with this method. + promise.futureResult.whenComplete { result in + // When we complete here we need to set our result state, and then ask to respin certificate verification. + // If we can't respin verification because we've dropped the parent handler, that's fine, no harm no foul. + // For that reason, we tolerate both the verify manager and the parent handler being nil. + eventLoop.execute { + // Note that we don't close over self here: that's to deal with the fact that this is a struct, and we don't want to + // escape the mutable ownership of self. + precondition(connection.customVerificationManager == nil || connection.customVerificationManager?.result == .some(.pendingResult)) + connection.customVerificationManager?.result = .complete(NIOSSLVerificationResult(result)) + connection.parentHandler?.resumeHandshake() + } + } + + // Ok, let's do it. + self.callback.invoke(on: connection, promise: promise) + return ssl_verify_retry + } +} + + +extension CustomVerifyManager { + private enum CallbackType { + case `public`(NIOSSLCustomVerificationCallback) + case `internal`(InternalCallback) + + /// For user-supplied callbacks we need to give them public types. For internal ones, we just pass the + /// `EventLoopPromise` object through. + func invoke(on connection: SSLConnection, promise: EventLoopPromise) { + switch self { + case .public(let publicCallback): + do { + let certificates = try connection.peerCertificateChain() + publicCallback(certificates, promise) + } catch { + promise.fail(error) + } + + case .internal(let internalCallback): + internalCallback(promise) + } + } + } + + internal typealias InternalCallback = (EventLoopPromise) -> Void +} + + +extension NIOSSLVerificationResult { + init(_ result: Result) { + switch result { + case .success(let s): + self = s + case .failure: + self = .failed + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCertificate.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCertificate.swift new file mode 100644 index 00000000..8d1fe4a0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLCertificate.swift @@ -0,0 +1,448 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL +@_implementationOnly import CNIOBoringSSLShims +import NIOCore + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import struct Darwin.time_t +#elseif canImport(Glibc) +import struct Glibc.time_t +#endif + +/// A reference to a BoringSSL Certificate object (`X509 *`). +/// +/// This thin wrapper class allows us to use ARC to automatically manage +/// the memory associated with this TLS certificate. That ensures that BoringSSL +/// will not free the underlying buffer until we are done with the certificate. +/// +/// This class also provides several convenience constructors that allow users +/// to obtain an in-memory representation of a TLS certificate from a buffer of +/// bytes or from a file path. +public class NIOSSLCertificate { + @usableFromInline + internal let _ref: OpaquePointer/**/ + + @inlinable + internal func withUnsafeMutableX509Pointer(_ body: (OpaquePointer) throws -> ResultType) rethrows -> ResultType { + return try body(self._ref) + } + + // Internal to this class we can just access the ref directly. + private var ref: OpaquePointer { + return self._ref + } + + public var serialNumber: [UInt8] { + let serialNumber = CNIOBoringSSL_X509_get_serialNumber(self.ref)! + return Array(UnsafeBufferPointer(start: serialNumber.pointee.data, count: Int(serialNumber.pointee.length))) + } + + private init(withOwnedReference ref: OpaquePointer) { + self._ref = ref + } + + /// Create a NIOSSLCertificate from a file at a given path in either PEM or + /// DER format. + /// + /// Note that this method will only ever load the first certificate from a given file. + public convenience init(file: String, format: NIOSSLSerializationFormats) throws { + let fileObject = try Posix.fopen(file: file, mode: "rb") + defer { + fclose(fileObject) + } + + let x509: OpaquePointer? + switch format { + case .pem: + x509 = CNIOBoringSSL_PEM_read_X509(fileObject, nil, nil, nil) + case .der: + x509 = CNIOBoringSSL_d2i_X509_fp(fileObject, nil) + } + + if x509 == nil { + throw NIOSSLError.failedToLoadCertificate + } + + self.init(withOwnedReference: x509!) + } + + /// Create a NIOSSLCertificate from a buffer of bytes in either PEM or + /// DER format. + /// + /// - SeeAlso: `NIOSSLCertificate.init(bytes:format:)` + @available(*, deprecated, renamed: "NIOSSLCertificate.init(bytes:format:)") + public convenience init(buffer: [Int8], format: NIOSSLSerializationFormats) throws { + try self.init(bytes: buffer.map(UInt8.init), format: format) + } + + /// Create a NIOSSLCertificate from a buffer of bytes in either PEM or + /// DER format. + public convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats) throws { + let ref = bytes.withUnsafeBytes { (ptr) -> OpaquePointer? in + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + + defer { + CNIOBoringSSL_BIO_free(bio) + } + + switch format { + case .pem: + return CNIOBoringSSL_PEM_read_bio_X509(bio, nil, nil, nil) + case .der: + return CNIOBoringSSL_d2i_X509_bio(bio, nil) + } + } + + if ref == nil { + throw NIOSSLError.failedToLoadCertificate + } + + self.init(withOwnedReference: ref!) + } + + /// Create a NIOSSLCertificate from a buffer of bytes in either PEM or DER format. + internal convenience init(bytes ptr: UnsafeRawBufferPointer, format: NIOSSLSerializationFormats) throws { + // TODO(cory): + // The body of this method is exactly identical to the initializer above, except for the "withUnsafeBytes" call. + // ContiguousBytes would have been the lowest effort way to reduce this duplication, but we can't use it without + // bringing Foundation in. Probably we should use Sequence where Element == UInt8 and the withUnsafeContiguousBytesIfAvailable + // method, but that's a much more substantial refactor. Let's do it later. + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + + defer { + CNIOBoringSSL_BIO_free(bio) + } + + let ref: OpaquePointer? + + switch format { + case .pem: + ref = CNIOBoringSSL_PEM_read_bio_X509(bio, nil, nil, nil) + case .der: + ref = CNIOBoringSSL_d2i_X509_bio(bio, nil) + } + + if ref == nil { + throw NIOSSLError.failedToLoadCertificate + } + + self.init(withOwnedReference: ref!) + } + + /// Create a NIOSSLCertificate wrapping a pointer into BoringSSL. + /// + /// This is a function that should be avoided as much as possible because it plays poorly with + /// BoringSSL's reference-counted memory. This function does not increment the reference count for the `X509` + /// object here, nor does it duplicate it: it just takes ownership of the copy here. This object + /// **will** deallocate the underlying `X509` object when deinited, and so if you need to keep that + /// `X509` object alive you should call `X509_dup` before passing the pointer here. + /// + /// In general, however, this function should be avoided in favour of one of the convenience + /// initializers, which ensure that the lifetime of the `X509` object is better-managed. + static func fromUnsafePointer(takingOwnership pointer: OpaquePointer) -> NIOSSLCertificate { + return NIOSSLCertificate(withOwnedReference: pointer) + } + + /// Get a collection of the alternative names in the certificate. + public func _subjectAlternativeNames() -> _SubjectAlternativeNames? { + guard let sanExtension = CNIOBoringSSL_X509_get_ext_d2i(self.ref, NID_subject_alt_name, nil, nil) else { + return nil + } + return _SubjectAlternativeNames(nameStack: OpaquePointer(sanExtension)) + } + + /// Extracts the SHA1 hash of the subject name before it has been truncated. + /// + /// - returns: Numeric hash of the subject name. + internal func getSubjectNameHash() -> UInt { + return CNIOBoringSSL_X509_subject_name_hash(self.ref) + } + + /// Returns the commonName field in the Subject of this certificate. + /// + /// It is technically possible to have multiple common names in a certificate. As the primary + /// purpose of this field in SwiftNIO is to validate TLS certificates, we only ever return + /// the *most significant* (i.e. last) instance of commonName in the subject. + internal func commonName() -> [UInt8]? { + // No subject name is unexpected, but it gives us an easy time of handling this at least. + guard let subjectName = CNIOBoringSSL_X509_get_subject_name(self.ref) else { + return nil + } + + // Per the man page, to find the first entry we set lastIndex to -1. When there are no + // more entries, -1 is returned as the index of the next entry. + var lastIndex: CInt = -1 + var nextIndex: CInt = -1 + repeat { + lastIndex = nextIndex + nextIndex = CNIOBoringSSL_X509_NAME_get_index_by_NID(subjectName, NID_commonName, lastIndex) + } while nextIndex >= 0 + + // It's totally allowed to have no commonName. + guard lastIndex >= 0 else { + return nil + } + + // This is very unlikely, but it could happen. + guard let nameData = CNIOBoringSSL_X509_NAME_ENTRY_get_data(CNIOBoringSSL_X509_NAME_get_entry(subjectName, lastIndex)) else { + return nil + } + + // Cool, we have the name. Let's have BoringSSL give it to us in UTF-8 form and then put those bytes + // into our own array. + var encodedName: UnsafeMutablePointer? = nil + let stringLength = CNIOBoringSSL_ASN1_STRING_to_UTF8(&encodedName, nameData) + + guard let namePtr = encodedName else { + return nil + } + + let arr = [UInt8](UnsafeBufferPointer(start: namePtr, count: Int(stringLength))) + CNIOBoringSSL_OPENSSL_free(namePtr) + return arr + } + + deinit { + CNIOBoringSSL_X509_free(ref) + } +} + +// MARK:- Utility Functions +// We don't really want to get too far down the road of providing helpers for things like certificates +// and private keys: this is really the domain of alternative cryptography libraries. However, to +// enable users of swift-nio-ssl to use other cryptography libraries it will be helpful to provide +// the ability to obtain the bytes that correspond to certificates and keys. +extension NIOSSLCertificate { + /// Obtain the public key for this `NIOSSLCertificate`. + /// + /// - returns: This certificate's `NIOSSLPublicKey`. + /// - throws: If an error is encountered extracting the key. + public func extractPublicKey() throws -> NIOSSLPublicKey { + guard let key = CNIOBoringSSL_X509_get_pubkey(self.ref) else { + fatalError("Failed to extract a public key reference") + } + + return NIOSSLPublicKey.fromInternalPointer(takingOwnership: key) + } + + /// Extracts the bytes of this certificate in DER format. + /// + /// - returns: The DER-encoded bytes for this certificate. + /// - throws: If an error occurred while serializing the certificate. + public func toDERBytes() throws -> [UInt8] { + return try self.withUnsafeDERCertificateBuffer { Array($0) } + } + + /// Create an array of `NIOSSLCertificate`s from a buffer of bytes in PEM format. + /// + /// - Parameter buffer: The PEM buffer to read certificates from. + /// - Throws: If an error is encountered while reading certificates. + /// - SeeAlso: `NIOSSLCertificate.fromPEMBytes(_:)` + @available(*, deprecated, renamed: "NIOSSLCertificate.fromPEMBytes(_:)") + public class func fromPEMBuffer(_ buffer: [Int8]) throws -> [NIOSSLCertificate] { + return try fromPEMBytes(buffer.map(UInt8.init)) + } + + /// Create an array of `NIOSSLCertificate`s from a buffer of bytes in PEM format. + /// + /// - Parameter bytes: The PEM buffer to read certificates from. + /// - Throws: If an error is encountered while reading certificates. + public class func fromPEMBytes(_ bytes: [UInt8]) throws -> [NIOSSLCertificate] { + CNIOBoringSSL_ERR_clear_error() + defer { + CNIOBoringSSL_ERR_clear_error() + } + + return try bytes.withUnsafeBytes { (ptr) -> [NIOSSLCertificate] in + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress, CInt(ptr.count))! + defer { + CNIOBoringSSL_BIO_free(bio) + } + + return try readCertificatesFromBIO(bio) + } + } + + /// Create an array of `NIOSSLCertificate`s from a file at a given path in PEM format. + /// + /// - Parameter file: The PEM file to read certificates from. + /// - Throws: If an error is encountered while reading certificates. + public class func fromPEMFile(_ path: String) throws -> [NIOSSLCertificate] { + CNIOBoringSSL_ERR_clear_error() + defer { + CNIOBoringSSL_ERR_clear_error() + } + + guard let bio = CNIOBoringSSL_BIO_new(CNIOBoringSSL_BIO_s_file()) else { + fatalError("Failed to create a BIO handle to read a PEM file") + } + defer { + CNIOBoringSSL_BIO_free(bio) + } + + guard CNIOBoringSSL_BIO_read_filename(bio, path) > 0 else { + throw NIOSSLError.failedToLoadCertificate + } + + return try readCertificatesFromBIO(bio) + } + + /// Returns the timestamp before which this certificate is not valid. + /// + /// The value is in seconds since the UNIX epoch. + public var notValidBefore: time_t { + // This ref is owned by self. + let notBefore = CNIOBoringSSL_X509_get0_notBefore(self.ref)! + return notBefore.timeSinceEpoch + } + + /// Returns the timestamp after which this certificate is not valid. + /// + /// The value is in seconds since the UNIX epoch. + public var notValidAfter: time_t { + // This ref is owned by self. + let notAfter = CNIOBoringSSL_X509_get0_notAfter(self.ref)! + return notAfter.timeSinceEpoch + } + + /// Reads `NIOSSLCertificate`s from the given BIO. + private class func readCertificatesFromBIO(_ bio: UnsafeMutablePointer) throws -> [NIOSSLCertificate] { + guard let x509 = CNIOBoringSSL_PEM_read_bio_X509_AUX(bio, nil, nil, nil) else { + throw NIOSSLError.failedToLoadCertificate + } + + var certificates = [NIOSSLCertificate(withOwnedReference: x509)] + + while let x = CNIOBoringSSL_PEM_read_bio_X509(bio, nil, nil, nil) { + certificates.append(.init(withOwnedReference: x)) + } + + let err = CNIOBoringSSL_ERR_peek_error() + + // If we hit the end of the file then it's not a real error, we just read as much as we could. + if CNIOBoringSSLShims_ERR_GET_LIB(err) == ERR_LIB_PEM && CNIOBoringSSLShims_ERR_GET_REASON(err) == PEM_R_NO_START_LINE { + CNIOBoringSSL_ERR_clear_error() + } else { + throw NIOSSLError.failedToLoadCertificate + } + + return certificates + } + + /// Calls the given body function with a temporary buffer containing the DER-encoded bytes of this + /// certificate. This function does allocate for these bytes, but there is no way to avoid doing so with the + /// X509 API in BoringSSL. + /// + /// The pointer provided to the closure is not valid beyond the lifetime of this method call. + private func withUnsafeDERCertificateBuffer(_ body: (UnsafeRawBufferPointer) throws -> T) throws -> T { + guard let bio = CNIOBoringSSL_BIO_new(CNIOBoringSSL_BIO_s_mem()) else { + fatalError("Failed to malloc for a BIO handler") + } + + defer { + CNIOBoringSSL_BIO_free(bio) + } + + let rc = CNIOBoringSSL_i2d_X509_bio(bio, self.ref) + guard rc == 1 else { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + + var dataPtr: UnsafeMutablePointer? = nil + let length = CNIOBoringSSL_BIO_get_mem_data(bio, &dataPtr) + + guard let bytes = dataPtr.map({ UnsafeRawBufferPointer(start: $0, count: length) }) else { + fatalError("Failed to map bytes from a certificate") + } + + return try body(bytes) + } +} + +extension NIOSSLCertificate: Equatable { + public static func ==(lhs: NIOSSLCertificate, rhs: NIOSSLCertificate) -> Bool { + return CNIOBoringSSL_X509_cmp(lhs.ref, rhs.ref) == 0 + } +} + + +extension NIOSSLCertificate: Hashable { + public func hash(into hasher: inout Hasher) { + // We just hash the DER bytes of the cert. If we can't get the bytes, this is a fatal error as + // we have no way to recover from it. It's unfortunate that this allocates, but the code to hash + // a certificate in any other way is too fragile to justify. + try! self.withUnsafeDERCertificateBuffer { hasher.combine(bytes: $0) } + } +} + +extension NIOSSLCertificate: CustomStringConvertible { + + public var description: String { + let serialNumber = self.serialNumber.map { String($0, radix: 16) }.reduce("", +) + var desc = "" + } + +} + +extension UnsafePointer where Pointee == ASN1_TIME { + var timeSinceEpoch: time_t { + let epochTime = CNIOBoringSSL_ASN1_TIME_new()! + defer { + CNIOBoringSSL_ASN1_TIME_free(epochTime) + } + + // This sets the ASN1_TIME to epoch time. + CNIOBoringSSL_ASN1_TIME_set(epochTime, 0) + var day = CInt(0) + var seconds = CInt(0) + + let rc = CNIOBoringSSL_ASN1_TIME_diff(&day, &seconds, epochTime, self) + precondition(rc != 0) + + // 86400 seconds in a day + return time_t(day) * 86400 + time_t(seconds) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLConnection.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLConnection.swift new file mode 100644 index 00000000..e44923b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLConnection.swift @@ -0,0 +1,543 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +@_implementationOnly import CNIOBoringSSL + +internal let SSL_MAX_RECORD_SIZE = 16 * 1024 + +/// This is used as the application data index to store pointers to `SSLConnection` objects in +/// `SSL` objects. It is only safe to use after BoringSSL initialization. As it's declared global, +/// it will be lazily initialized and protected by a dispatch_once, ensuring that it's thread-safe. +internal let sslConnectionExDataIndex = CNIOBoringSSL_SSL_get_ex_new_index(0, nil, nil, nil, nil) + +/// Encodes the return value of a non-blocking BoringSSL method call. +/// +/// This enum maps BoringSSL's return values to a small number of cases. A success +/// value naturally maps to `.complete`, and most errors map to `.failed`. However, +/// the BoringSSL "errors" `WANT_READ` and `WANT_WRITE` are mapped to `.incomplete`, to +/// help distinguish them from the other error cases. This makes it easier for code to +/// handle the "must wait for more data" case by calling it out directly. +enum AsyncOperationResult { + case incomplete + case complete(T) + case failed(BoringSSLError) +} + +/// A wrapper class that encapsulates BoringSSL's `SSL *` object. +/// +/// This class represents a single TLS connection, and performs all of crypto and record +/// framing required by TLS. It also records the configuration and parent `NIOSSLContext` object +/// used to create the connection. +internal final class SSLConnection { + private let ssl: OpaquePointer + internal let parentContext: NIOSSLContext + private var bio: ByteBufferBIO? + internal var expectedHostname: String? + internal var role: ConnectionRole? + internal var parentHandler: NIOSSLHandler? + internal var eventLoop: EventLoop? + + /// Deprecated in favour of customVerificationManager + private var verificationCallback: NIOSSLVerificationCallback? + internal var customVerificationManager: CustomVerifyManager? + internal var customPrivateKeyResult: Result? + + /// Whether certificate hostnames should be validated. + var validateHostnames: Bool { + if case .fullVerification = parentContext.configuration.certificateVerification { + return true + } + return false + } + + init(ownedSSL: OpaquePointer, parentContext: NIOSSLContext) { + self.ssl = ownedSSL + self.parentContext = parentContext + + // We pass the SSL object an unowned reference to this object. + let pointerToSelf = Unmanaged.passUnretained(self).toOpaque() + CNIOBoringSSL_SSL_set_ex_data(self.ssl, sslConnectionExDataIndex, pointerToSelf) + + self.setRenegotiationSupport(self.parentContext.configuration.renegotiationSupport) + } + + deinit { + CNIOBoringSSL_SSL_free(ssl) + } + + /// Configures this as a server connection. + func setAcceptState() { + CNIOBoringSSL_SSL_set_accept_state(ssl) + self.role = .server + } + + /// Configures this as a client connection. + func setConnectState() { + CNIOBoringSSL_SSL_set_connect_state(ssl) + self.role = .client + } + + func setAllocator(_ allocator: ByteBufferAllocator) { + self.bio = ByteBufferBIO(allocator: allocator) + + // This weird dance where we pass the *exact same* pointer in to both objects is because, weirdly, + // the BoringSSL docs claim that only one reference count will be consumed here. We therefore need to + // avoid calling BIO_up_ref too many times. + let bioPtr = self.bio!.retainedBIO() + CNIOBoringSSL_SSL_set_bio(self.ssl, bioPtr, bioPtr) + } + + /// Sets the value of the SNI extension to send to the server. + /// + /// This method must only be called with a hostname, not an IP address. Sending + /// an IP address in the SNI extension is invalid, and may result in handshake + /// failure. + func setServerName(name: String) throws { + CNIOBoringSSL_ERR_clear_error() + let rc = name.withCString { + return CNIOBoringSSL_SSL_set_tlsext_host_name(ssl, $0) + } + guard rc == 1 else { + throw BoringSSLError.invalidSNIName(BoringSSLError.buildErrorStack()) + } + self.expectedHostname = name + } + + /// Sets the BoringSSL old-style verification callback. + /// + /// This is deprecated in favour of the new-style verification callback in SSLContext. + func setVerificationCallback(_ callback: @escaping NIOSSLVerificationCallback) { + // Store the verification callback. We need to do this to keep it alive throughout the connection. + // We'll drop this when we're told that it's no longer needed to ensure we break the reference cycles + // that this callback inevitably produces. + self.verificationCallback = callback + + // We need to know what the current mode is. + let currentMode = CNIOBoringSSL_SSL_get_verify_mode(self.ssl) + CNIOBoringSSL_SSL_set_verify(self.ssl, currentMode) { preverify, storeContext in + // To start out, let's grab the certificate we're operating on. + guard let certPointer = CNIOBoringSSL_X509_STORE_CTX_get_current_cert(storeContext) else { + preconditionFailure("Can only have verification function invoked with actual certificate: bad store \(String(describing: storeContext))") + } + CNIOBoringSSL_X509_up_ref(certPointer) + let cert = NIOSSLCertificate.fromUnsafePointer(takingOwnership: certPointer) + + // Next, prepare the verification result. + let verificationResult = NIOSSLVerificationResult(fromBoringSSLPreverify: preverify) + + // Now, grab the SSLConnection object. + guard let ssl = CNIOBoringSSL_X509_STORE_CTX_get_ex_data(storeContext, CNIOBoringSSL_SSL_get_ex_data_X509_STORE_CTX_idx()) else { + preconditionFailure("Unable to obtain SSL * from X509_STORE_CTX * \(String(describing: storeContext))") + } + let connection = SSLConnection.loadConnectionFromSSL(OpaquePointer(ssl)) + switch connection.verificationCallback!(verificationResult, cert) { + case .certificateVerified: + return 1 + case .failed: + return 0 + } + } + } + + func setCustomVerificationCallback(_ callbackManager: CustomVerifyManager) { + // Store the verification callback. We need to do this to keep it alive throughout the connection. + // We'll drop this when we're told that it's no longer needed to ensure we break the reference cycles + // that this callback inevitably produces. + self.customVerificationManager = callbackManager + + // We need to know what the current mode is. + // Note that this also has the effect of ensuring that if we disabled certificate validation + // it actually _stays_ disabled: if the verify mode is no-verification, this callback never gets called. + let currentMode = CNIOBoringSSL_SSL_get_verify_mode(self.ssl) + CNIOBoringSSL_SSL_set_custom_verify(self.ssl, currentMode) { ssl, outAlert in + guard let unwrappedSSL = ssl else { + preconditionFailure("Unexpected null pointer in custom verification callback. ssl: \(String(describing: ssl))") + } + + // Ok, this call may be a resumption of a previous negotiation. We need to check if our connection object has a pre-existing verifiation state. + let connection = SSLConnection.loadConnectionFromSSL(unwrappedSSL) + + // We force unwrap the custom verification manager because for it to not be set is a programmer error. + return connection.customVerificationManager!.process(on: connection) + } + } + + /// Sets whether renegotiation is supported. + func setRenegotiationSupport(_ state: NIORenegotiationSupport) { + var baseState: ssl_renegotiate_mode_t + + switch state { + case .none: + baseState = ssl_renegotiate_never + case .once: + baseState = ssl_renegotiate_once + case .always: + baseState = ssl_renegotiate_freely + } + + CNIOBoringSSL_SSL_set_renegotiate_mode(self.ssl, baseState) + } + + /// Performs hostname validation against the peer certificate using the configured server name. + func validateHostname(address: SocketAddress) throws { + // We want the leaf certificate. + guard let peerCert = self.getPeerCertificate() else { + throw NIOSSLError.noCertificateToValidate + } + + guard try validIdentityForService(serverHostname: self.expectedHostname, + socketAddress: address, + leafCertificate: peerCert) else { + throw NIOSSLExtraError.failedToValidateHostname(expectedName: self.expectedHostname ?? "") + } + } + + /// Spins the handshake state machine and performs the next step of the handshake + /// protocol. + /// + /// This method may write data into internal buffers that must be sent: call + /// `getDataForNetwork` after this method is called. This method also consumes + /// data from internal buffers: call `consumeDataFromNetwork` before calling this + /// method. + func doHandshake() -> AsyncOperationResult { + CNIOBoringSSL_ERR_clear_error() + let rc = CNIOBoringSSL_SSL_do_handshake(ssl) + + if (rc == 1) { return .complete(rc) } + + let result = CNIOBoringSSL_SSL_get_error(ssl, rc) + let error = BoringSSLError.fromSSLGetErrorResult(result)! + + switch error { + case .wantRead, + .wantWrite, + .wantCertificateVerify: + return .incomplete + default: + return .failed(error) + } + } + + /// Spins the shutdown state machine and performs the next step of the shutdown + /// protocol. + /// + /// This method may write data into internal buffers that must be sent: call + /// `getDataForNetwork` after this method is called. This method also consumes + /// data from internal buffers: call `consumeDataFromNetwork` before calling this + /// method. + func doShutdown() -> AsyncOperationResult { + CNIOBoringSSL_ERR_clear_error() + let rc = CNIOBoringSSL_SSL_shutdown(ssl) + + switch rc { + case 1: + return .complete(rc) + case 0: + return .incomplete + default: + let result = CNIOBoringSSL_SSL_get_error(ssl, rc) + let error = BoringSSLError.fromSSLGetErrorResult(result)! + + switch error { + case .wantRead, + .wantWrite: + return .incomplete + default: + return .failed(error) + } + } + } + + /// Given some unprocessed data from the remote peer, places it into + /// BoringSSL's receive buffer ready for handling by BoringSSL. + /// + /// This method should be called whenever data is received from the remote + /// peer. It must be immediately followed by an I/O operation, e.g. `readDataFromNetwork` + /// or `doHandshake` or `doShutdown`. + func consumeDataFromNetwork(_ data: ByteBuffer) { + self.bio!.receiveFromNetwork(buffer: data) + } + + /// Obtains some encrypted data ready for the network from BoringSSL. + /// + /// This call obtains only data that BoringSSL has already written into its send + /// buffer. As a result, it should be called last, after all other operations have + /// been performed, to allow BoringSSL to write as much data as necessary into the + /// `BIO`. + /// + /// Returns `nil` if there is no data to write. Otherwise, returns all of the pending + /// data. + func getDataForNetwork() -> ByteBuffer? { + return self.bio!.outboundCiphertext() + } + + /// Attempts to decrypt any application data sent by the remote peer, and fills a buffer + /// containing the cleartext bytes. + /// + /// This method can only consume data previously fed into BoringSSL in `consumeDataFromNetwork`. + func readDataFromNetwork(outputBuffer: inout ByteBuffer) -> AsyncOperationResult { + // TODO(cory): It would be nice to have an withUnsafeMutableWriteableBytes here, but we don't, so we + // need to make do with writeWithUnsafeMutableBytes instead. The core issue is that we can't + // safely return any of the error values that SSL_read might provide here because writeWithUnsafeMutableBytes + // will try to use that as the number of bytes written and blow up. If we could prevent it doing that (which + // we can with reading) that would be grand, but we can't, so instead we need to use a temp variable. Not ideal. + // + // We require that there is space to write at least one TLS record. + var bytesRead: CInt = 0 + let rc = outputBuffer.writeWithUnsafeMutableBytes(minimumWritableBytes: SSL_MAX_RECORD_SIZE) { (pointer) -> Int in + bytesRead = CNIOBoringSSL_SSL_read(self.ssl, pointer.baseAddress, CInt(pointer.count)) + return bytesRead >= 0 ? Int(bytesRead) : 0 + } + + if bytesRead > 0 { + return .complete(rc) + } else { + let result = CNIOBoringSSL_SSL_get_error(ssl, CInt(bytesRead)) + let error = BoringSSLError.fromSSLGetErrorResult(result)! + + switch error { + case .wantRead, + .wantWrite: + return .incomplete + default: + return .failed(error) + } + } + } + + /// Encrypts cleartext application data ready for sending on the network. + /// + /// This call will only write the data into BoringSSL's internal buffers. It needs to be obtained + /// by calling `getDataForNetwork` after this call completes. + func writeDataToNetwork(_ data: inout ByteBuffer) -> AsyncOperationResult { + // BoringSSL does not allow calling SSL_write with zero-length buffers. Zero-length + // writes always succeed. + guard data.readableBytes > 0 else { + return .complete(0) + } + + let writtenBytes = data.withUnsafeReadableBytes { (pointer) -> CInt in + return CNIOBoringSSL_SSL_write(ssl, pointer.baseAddress, CInt(pointer.count)) + } + + if writtenBytes > 0 { + // The default behaviour of SSL_write is to only return once *all* of the data has been written, + // unless the underlying BIO cannot satisfy the need (in which case WANT_WRITE will be returned). + // We're using our BIO, which is always writable, so WANT_WRITE cannot fire so we'd always + // expect this to write the complete quantity of readable bytes in our buffer. + precondition(writtenBytes == data.readableBytes) + data.moveReaderIndex(forwardBy: Int(writtenBytes)) + return .complete(writtenBytes) + } else { + let result = CNIOBoringSSL_SSL_get_error(ssl, writtenBytes) + let error = BoringSSLError.fromSSLGetErrorResult(result)! + + switch error { + case .wantRead, .wantWrite: + return .incomplete + default: + return .failed(error) + } + } + } + + /// Returns the protocol negotiated via ALPN, if any. Returns `nil` if no protocol + /// was negotiated. + func getAlpnProtocol() -> String? { + var protoName = UnsafePointer(bitPattern: 0) + var protoLen: CUnsignedInt = 0 + + CNIOBoringSSL_SSL_get0_alpn_selected(ssl, &protoName, &protoLen) + guard protoLen > 0 else { + return nil + } + + return String(decoding: UnsafeBufferPointer(start: protoName, count: Int(protoLen)), as: UTF8.self) + } + + /// Get the leaf certificate from the peer certificate chain as a managed object, + /// if available. + func getPeerCertificate() -> NIOSSLCertificate? { + guard let certPtr = CNIOBoringSSL_SSL_get_peer_certificate(ssl) else { + return nil + } + + return NIOSSLCertificate.fromUnsafePointer(takingOwnership: certPtr) + } + + /// Drops persistent connection state. + /// + /// Must only be called when the connection is no longer needed. The rest of this object + /// preconditions on that being true, so we'll find out quickly when that's not the case. + func close() { + /// Drop the verification callbacks. This breaks any reference cycles that are inevitably + /// created by these callbacks. + self.verificationCallback = nil + self.customVerificationManager = nil + + // Also drop the reference to the parent channel handler, which is a trivial reference cycle. + self.parentHandler = nil + + // And finally drop the data stored by the bytebuffer BIO + self.bio?.close() + } + + /// Retrieves any inbound data that has not been processed by BoringSSL. + /// + /// When unwrapping TLS from a connection, there may be application bytes that follow the terminating + /// CLOSE_NOTIFY message. Those bytes may have been passed to this `SSLConnection`, and so we need to + /// retrieve them. + /// + /// This function extracts those bytes and returns them to the user. This should only be called when + /// the connection has been shutdown. + /// + /// - returns: The unconsumed `ByteBuffer`, if any. + func extractUnconsumedData() -> ByteBuffer? { + return self.bio?.evacuateInboundData() + } + + /// Returns an optional `TLSVersion` used on a `Channel` through the `NIOSSLHandler` APIs. + func getTLSVersionForConnection() -> TLSVersion? { + let uint16Version = CNIOBoringSSL_SSL_version(self.ssl) + switch uint16Version { + case TLS1_3_VERSION: + return .tlsv13 + case TLS1_2_VERSION: + return .tlsv12 + case TLS1_1_VERSION: + return .tlsv11 + case TLS1_VERSION: + return .tlsv1 + default: + return nil + } + } +} + + +/// MARK: ConnectionRole +extension SSLConnection { + internal enum ConnectionRole { + case server + case client + } +} + + +// MARK: Certificate Peer Chain Buffers +extension SSLConnection { + /// A collection of buffers representing the DER-encoded bytes of the peer certificate chain. + struct PeerCertificateChainBuffers { + private let basePointer: OpaquePointer + + fileprivate init(basePointer: OpaquePointer) { + self.basePointer = basePointer + } + } + + /// Invokes a block with a collection of pointers to DER-encoded bytes of the peer certificate chain. + /// + /// The pointers are only guaranteed to be valid for the duration of this call: it is undefined behaviour to escape + /// any of these pointers from the block, or the certificate iterator itself from the block. Users must either use the + /// bytes synchronously within the block, or they must copy them to a new buffer that they own. + /// + /// If there are no peer certificates, the body will be called with nil. + func withPeerCertificateChainBuffers(_ body: (PeerCertificateChainBuffers?) throws -> Result) rethrows -> Result { + guard let stackPointer = CNIOBoringSSL_SSL_get0_peer_certificates(self.ssl) else { + return try body(nil) + } + + return try body(PeerCertificateChainBuffers(basePointer: stackPointer)) + } + + /// The certificate chain presented by the peer. + func peerCertificateChain() throws -> [NIOSSLCertificate] { + return try self.withPeerCertificateChainBuffers { buffers in + guard let buffers = buffers else { + return [] + } + + return try buffers.map { try NIOSSLCertificate(bytes: $0, format: .der) } + } + } +} + +extension SSLConnection.PeerCertificateChainBuffers: RandomAccessCollection { + struct Index: Hashable, Comparable, Strideable { + typealias Stride = Int + + fileprivate var index: Int + + fileprivate init(_ index: Int) { + self.index = index + } + + static func < (lhs: Index, rhs: Index) -> Bool { + return lhs.index < rhs.index + } + + func advanced(by n: SSLConnection.PeerCertificateChainBuffers.Index.Stride) -> SSLConnection.PeerCertificateChainBuffers.Index { + var result = self + result.index += n + return result + } + + func distance(to other: SSLConnection.PeerCertificateChainBuffers.Index) -> SSLConnection.PeerCertificateChainBuffers.Index.Stride { + return other.index - self.index + } + } + + typealias Element = UnsafeRawBufferPointer + + var startIndex: Index { + return Index(0) + } + + var endIndex: Index { + return Index(self.count) + } + + var count: Int { + return CNIOBoringSSL_sk_CRYPTO_BUFFER_num(self.basePointer) + } + + subscript(_ index: Index) -> UnsafeRawBufferPointer { + precondition(index < self.endIndex) + guard let ptr = CNIOBoringSSL_sk_CRYPTO_BUFFER_value(self.basePointer, index.index) else { + preconditionFailure("Unable to locate backing pointer.") + } + guard let dataPointer = CNIOBoringSSL_CRYPTO_BUFFER_data(ptr) else { + preconditionFailure("Unable to retrieve data pointer from crypto_buffer") + } + let byteCount = CNIOBoringSSL_CRYPTO_BUFFER_len(ptr) + + // We want an UnsafeRawBufferPointer here, so we need to erase the pointer type. + let bufferDataPointer = UnsafeBufferPointer(start: dataPointer, count: byteCount) + return UnsafeRawBufferPointer(bufferDataPointer) + } +} + +// MARK: Helpers for managing ex_data +extension SSLConnection { + // Loads an SSLConnection from an SSL*. Does not take ownership of the pointer. + static func loadConnectionFromSSL(_ ssl: OpaquePointer) -> SSLConnection { + guard let connectionPointer = CNIOBoringSSL_SSL_get_ex_data(ssl, sslConnectionExDataIndex) else { + // Uh-ok, our application state is gone. Don't let this error silently pass, go bang. + preconditionFailure("Unable to find application data from SSL * \(ssl), index \(sslConnectionExDataIndex)") + } + + return Unmanaged.fromOpaque(connectionPointer).takeUnretainedValue() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLContext.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLContext.swift new file mode 100644 index 00000000..9fe10b7e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLContext.swift @@ -0,0 +1,775 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +@_implementationOnly import CNIOBoringSSL +@_implementationOnly import CNIOBoringSSLShims + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +// This is a neat trick. Swift lazily initializes module-globals based on when they're first +// used. This lets us defer BoringSSL intialization as late as possible and only do it if people +// actually create any object that uses BoringSSL. +internal var boringSSLIsInitialized: Bool = initializeBoringSSL() + +internal enum FileSystemObject { + case directory + case file + + static internal func pathType(path: String) -> FileSystemObject? { + var statObj = stat() + do { + try Posix.stat(path: path, buf: &statObj) + } catch { + return nil + } + +#if os(Android) && arch(arm) + return (statObj.st_mode & UInt32(Glibc.S_IFDIR)) != 0 ? .directory : .file +#else + return (statObj.st_mode & S_IFDIR) != 0 ? .directory : .file +#endif + } +} + +// This bizarre extension to UnsafeBufferPointer is very useful for handling ALPN identifiers. BoringSSL +// likes to work with them in wire format, so rather than us decoding them we can just encode ours to +// the wire format and then work with them from there. +private extension UnsafeBufferPointer where Element == UInt8 { + func locateAlpnIdentifier(identifier: UnsafeBufferPointer) -> (index: Int, length: Int)? { + precondition(identifier.count != 0) + let targetLength = Int(identifier[0]) + + var index = 0 + outerLoop: while index < self.count { + let length = Int(self[index]) + guard index + length + 1 <= self.count else { + // Invalid length of ALPN identifier, no match. + return nil + } + + guard targetLength == length else { + index += length + 1 + continue outerLoop + } + + for innerIndex in 1...length { + guard identifier[innerIndex] == self[index + innerIndex] else { + index += length + 1 + continue outerLoop + } + } + + // Found it + return (index: index + 1, length: length) + } + return nil + } +} + +private func alpnCallback(ssl: OpaquePointer?, + out: UnsafeMutablePointer?>?, + outlen: UnsafeMutablePointer?, + in: UnsafePointer?, + inlen: UInt32, + appData: UnsafeMutableRawPointer?) -> CInt { + // Perform some soundness checks. We don't want NULL pointers around here. + guard let ssl = ssl, let out = out, let outlen = outlen, let `in` = `in` else { + return SSL_TLSEXT_ERR_NOACK + } + + // We want to take the SSL pointer and extract the parent Swift object. + let parentCtx = CNIOBoringSSL_SSL_get_SSL_CTX(ssl)! + let parentPtr = CNIOBoringSSLShims_SSL_CTX_get_app_data(parentCtx)! + let parentSwiftContext: NIOSSLContext = Unmanaged.fromOpaque(parentPtr).takeUnretainedValue() + + let offeredProtocols = UnsafeBufferPointer(start: `in`, count: Int(inlen)) + guard let (index, length) = parentSwiftContext.alpnSelectCallback(offeredProtocols: offeredProtocols) else { + out.pointee = nil + outlen.pointee = 0 + return SSL_TLSEXT_ERR_NOACK + } + + out.pointee = `in` + index + outlen.pointee = UInt8(length) + return SSL_TLSEXT_ERR_OK +} + +/// A wrapper class that encapsulates BoringSSL's `SSL_CTX *` object. +/// +/// This object is thread-safe and can be shared across TLS connections in your application. Even if the connections +/// are associated with `Channel`s from different `EventLoop`s. +/// +/// - Note: Creating a `NIOSSLContext` is a very expensive operation because BoringSSL will usually need to load and +/// parse large number of certificates from the system trust store. Therefore, creating a +/// `NIOSSLContext` will likely allocate many thousand times and will also _perform blocking disk I/O_. +/// +/// - Warning: Avoid creating `NIOSSLContext`s on any `EventLoop` because it does _blocking disk I/O_. +public final class NIOSSLContext { + private let sslContext: OpaquePointer + private let callbackManager: CallbackManagerProtocol? + private var keyLogManager: KeyLogCallbackManager? + internal let configuration: TLSConfiguration + + /// Initialize a context that will create multiple connections, all with the same + /// configuration. + internal init(configuration: TLSConfiguration, callbackManager: CallbackManagerProtocol?) throws { + guard boringSSLIsInitialized else { fatalError("Failed to initialize BoringSSL") } + guard let context = CNIOBoringSSL_SSL_CTX_new(CNIOBoringSSL_TLS_method()) else { fatalError("Failed to create new BoringSSL context") } + + let minTLSVersion: CInt + switch configuration.minimumTLSVersion { + case .tlsv13: + minTLSVersion = TLS1_3_VERSION + case .tlsv12: + minTLSVersion = TLS1_2_VERSION + case .tlsv11: + minTLSVersion = TLS1_1_VERSION + case .tlsv1: + minTLSVersion = TLS1_VERSION + } + var returnCode = CNIOBoringSSL_SSL_CTX_set_min_proto_version(context, UInt16(minTLSVersion)) + precondition(1 == returnCode) + + let maxTLSVersion: CInt + + switch configuration.maximumTLSVersion { + case .some(.tlsv1): + maxTLSVersion = TLS1_VERSION + case .some(.tlsv11): + maxTLSVersion = TLS1_1_VERSION + case .some(.tlsv12): + maxTLSVersion = TLS1_2_VERSION + case .some(.tlsv13), .none: + // Unset defaults to TLS1.3 for now. BoringSSL's default is TLS 1.2. + maxTLSVersion = TLS1_3_VERSION + } + returnCode = CNIOBoringSSL_SSL_CTX_set_max_proto_version(context, UInt16(maxTLSVersion)) + precondition(1 == returnCode) + + // Cipher suites. We just pass this straight to BoringSSL. + returnCode = CNIOBoringSSL_SSL_CTX_set_cipher_list(context, configuration.cipherSuites) + precondition(1 == returnCode) + + // On non-Linux platforms, when using the platform default trust roots, we make use of a + // custom verify callback. If we have also been presented with additional trust roots of + // type `.file`, we take the opportunity now to load them in memory to avoid doing so + // repeatedly on the request path. + // + // However, to avoid closely coupling this code with other parts (e.g. the platform-specific + // concerns, and the defaulting of `trustRoots` to `.default` when `nil`), we unilaterally + // convert any `additionalTrustRoots` of type `.file` to `.certificates`. + var configuration = configuration + configuration.additionalTrustRoots = try configuration.additionalTrustRoots.map { trustRoots in + switch trustRoots { + case .file(let path): + return .certificates(try NIOSSLCertificate.fromPEMFile(path)) + default: + return trustRoots + } + } + + // Configure certificate validation + try NIOSSLContext.configureCertificateValidation( + context: context, + verification: configuration.certificateVerification, + trustRoots: configuration.trustRoots, + additionalTrustRoots: configuration.additionalTrustRoots, + sendCANames: configuration.sendCANameList) + + // Configure verification algorithms + if let verifySignatureAlgorithms = configuration.verifySignatureAlgorithms { + returnCode = verifySignatureAlgorithms + .map { $0.rawValue } + .withUnsafeBufferPointer { algo in + CNIOBoringSSL_SSL_CTX_set_verify_algorithm_prefs(context, algo.baseAddress, algo.count) + } + if returnCode != 1 { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + } + + // Configure signing algorithms + if let signingSignatureAlgorithms = configuration.resolvedSigningSignatureAlgorithms { + returnCode = signingSignatureAlgorithms + .map { $0.rawValue } + .withUnsafeBufferPointer { algo in + CNIOBoringSSL_SSL_CTX_set_signing_algorithm_prefs(context, algo.baseAddress, algo.count) + } + if returnCode != 1 { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + } + + // If we were given a certificate chain to use, load it and its associated private key. Before + // we do, set up a passphrase callback if we need to. + if let callbackManager = callbackManager { + CNIOBoringSSL_SSL_CTX_set_default_passwd_cb(context, { globalBoringSSLPassphraseCallback(buf: $0, size: $1, rwflag: $2, u: $3) }) + CNIOBoringSSL_SSL_CTX_set_default_passwd_cb_userdata(context, Unmanaged.passUnretained(callbackManager as AnyObject).toOpaque()) + } + + var leaf = true + try configuration.certificateChain.forEach { + switch $0 { + case .file(let p): + NIOSSLContext.useCertificateChainFile(p, context: context) + leaf = false + case .certificate(let cert): + if leaf { + try NIOSSLContext.setLeafCertificate(cert, context: context) + leaf = false + } else { + try NIOSSLContext.addAdditionalChainCertificate(cert, context: context) + } + } + } + + if let pkey = configuration.privateKey { + switch pkey { + case .file(let p): + try NIOSSLContext.usePrivateKeyFile(p, context: context) + case .privateKey(let key): + try NIOSSLContext.setPrivateKey(key, context: context) + } + } + + if configuration.encodedApplicationProtocols.count > 0 { + try NIOSSLContext.setAlpnProtocols(configuration.encodedApplicationProtocols, context: context) + NIOSSLContext.setAlpnCallback(context: context) + } + + // Add a key log callback. + if let keyLogCallback = configuration.keyLogCallback { + self.keyLogManager = KeyLogCallbackManager(callback: keyLogCallback) + try NIOSSLContext.setKeylogCallback(context: context) + } else { + self.keyLogManager = nil + } + + self.sslContext = context + self.configuration = configuration + self.callbackManager = callbackManager + + // Always make it possible to get from an SSL_CTX structure back to this. + let ptrToSelf = Unmanaged.passUnretained(self).toOpaque() + CNIOBoringSSLShims_SSL_CTX_set_app_data(context, ptrToSelf) + } + + /// Initialize a context that will create multiple connections, all with the same + /// configuration. + /// + /// - Note: Creating a `NIOSSLContext` is a very expensive operation because BoringSSL will usually need to load and + /// parse large number of certificates from the system trust store. Therefore, creating a + /// `NIOSSLContext` will likely allocate many thousand times and will also _perform blocking disk I/O_. + /// + /// - Warning: Avoid creating `NIOSSLContext`s on any `EventLoop` because it does _blocking disk I/O_. + public convenience init(configuration: TLSConfiguration) throws { + try self.init(configuration: configuration, callbackManager: nil) + } + + /// Initialize a context that will create multiple connections, all with the same + /// configuration, along with a callback that will be called when needed to decrypt any + /// encrypted private keys. + /// + /// - Note: Creating a `NIOSSLContext` is a very expensive operation because BoringSSL will usually need to load and + /// parse large number of certificates from the system trust store. Therefore, creating a + /// `NIOSSLContext` will likely allocate many thousand times and will also _perform blocking disk I/O_. + /// + /// - Warning: Avoid creating `NIOSSLContext`s on any `EventLoop` because it does _blocking disk I/O_. + /// + /// - parameters: + /// - configuration: The `TLSConfiguration` to use for all the connections with this + /// `NIOSSLContext`. + /// - passphraseCallback: The callback to use to decrypt any private keys used by this + /// `NIOSSLContext`. For more details on this parameter see the documentation for + /// `NIOSSLPassphraseCallback`. + public convenience init(configuration: TLSConfiguration, + passphraseCallback: @escaping NIOSSLPassphraseCallback) throws where T.Element == UInt8 { + let manager = BoringSSLPassphraseCallbackManager(userCallback: passphraseCallback) + try self.init(configuration: configuration, callbackManager: manager) + } + + /// Create a new connection object with the configuration from this + /// context. + internal func createConnection() -> SSLConnection? { + guard let ssl = CNIOBoringSSL_SSL_new(self.sslContext) else { + return nil + } + + let conn = SSLConnection(ownedSSL: ssl, parentContext: self) + + // If we need to turn on the validation on Apple platforms, do it here. + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + switch self.configuration.trustRoots { + case .some(.default), .none: + conn.setCustomVerificationCallback(CustomVerifyManager(callback: { + do { + conn.performSecurityFrameworkValidation(promise: $0, peerCertificates: try conn.getPeerCertificatesAsSecCertificate()) + } catch { + $0.fail(error) + } + })) + case .some(.certificates), .some(.file): + break + } + #endif + + return conn + } + + fileprivate func alpnSelectCallback(offeredProtocols: UnsafeBufferPointer) -> (index: Int, length: Int)? { + for possibility in configuration.encodedApplicationProtocols { + let match = possibility.withUnsafeBufferPointer { + offeredProtocols.locateAlpnIdentifier(identifier: $0) + } + if match != nil { return match } + } + + return nil + } + + deinit { + CNIOBoringSSL_SSL_CTX_free(self.sslContext) + } +} + + +extension NIOSSLContext { + private static func useCertificateChainFile(_ path: String, context: OpaquePointer) { + // TODO(cory): This shouldn't be an assert but should instead be actual error handling. + // assert(path.isFileURL) + let result = path.withCString { (pointer) -> CInt in + return CNIOBoringSSL_SSL_CTX_use_certificate_chain_file(context, pointer) + } + + // TODO(cory): again, some error handling would be good. + precondition(result == 1) + } + + private static func setLeafCertificate(_ cert: NIOSSLCertificate, context: OpaquePointer) throws { + let rc = cert.withUnsafeMutableX509Pointer { ref in + CNIOBoringSSL_SSL_CTX_use_certificate(context, ref) + } + guard rc == 1 else { + throw NIOSSLError.failedToLoadCertificate + } + } + + private static func addAdditionalChainCertificate(_ cert: NIOSSLCertificate, context: OpaquePointer) throws { + let rc = cert.withUnsafeMutableX509Pointer { ref in + CNIOBoringSSL_SSL_CTX_add1_chain_cert(context, ref) + } + guard rc == 1 else { + throw NIOSSLError.failedToLoadCertificate + } + } + + private static func setPrivateKey(_ key: NIOSSLPrivateKey, context: OpaquePointer) throws { + switch key.representation { + case .native: + let rc = key.withUnsafeMutableEVPPKEYPointer { ref in + CNIOBoringSSL_SSL_CTX_use_PrivateKey(context, ref) + } + guard 1 == rc else { + throw NIOSSLError.failedToLoadPrivateKey + } + case .custom: + CNIOBoringSSL_SSL_CTX_set_private_key_method(context, customPrivateKeyMethod) + } + } + + private static func usePrivateKeyFile(_ path: String, context: OpaquePointer) throws { + let pathExtension = path.split(separator: ".").last + let fileType: CInt + + switch pathExtension?.lowercased() { + case .some("pem"): + fileType = SSL_FILETYPE_PEM + case .some("der"), .some("key"): + fileType = SSL_FILETYPE_ASN1 + default: + // TODO(cory): Again, error handling here would be good. + fatalError("Unknown private key file type.") + } + + let result = path.withCString { (pointer) -> CInt in + return CNIOBoringSSL_SSL_CTX_use_PrivateKey_file(context, pointer, fileType) + } + + guard result == 1 else { + throw NIOSSLError.failedToLoadPrivateKey + } + } + + private static func setAlpnProtocols(_ protocols: [[UInt8]], context: OpaquePointer) throws { + // This copy should be done infrequently, so we don't worry too much about it. + let protoBuf = protocols.reduce([UInt8](), +) + let rc = protoBuf.withUnsafeBufferPointer { + CNIOBoringSSL_SSL_CTX_set_alpn_protos(context, $0.baseAddress!, CUnsignedInt($0.count)) + } + + // Annoyingly this function reverses the error convention: 0 is success, non-zero is failure. + if rc != 0 { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.failedToSetALPN(errorStack) + } + } + + private static func setAlpnCallback(context: OpaquePointer) { + // This extra closure here is very silly, but it exists to allow us to avoid writing down the type of the first + // argument. Combined with the helper above, the compiler will be able to solve its way to success here. + CNIOBoringSSL_SSL_CTX_set_alpn_select_cb(context, + { alpnCallback(ssl: $0, out: $1, outlen: $2, in: $3, inlen: $4, appData: $5) }, + nil) + } +} + +// Configuring certificate verification +extension NIOSSLContext { + private static func configureCertificateValidation(context: OpaquePointer, verification: CertificateVerification, trustRoots: NIOSSLTrustRoots?, additionalTrustRoots: [NIOSSLAdditionalTrustRoots], sendCANames: Bool) throws { + // If validation is turned on, set the trust roots and turn on cert validation. + switch verification { + case .fullVerification, .noHostnameVerification: + CNIOBoringSSL_SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nil) + + // Also, set TRUSTED_FIRST to work around dumb clients that don't know what they're doing and send + // untrusted root certs. X509_VERIFY_PARAM will or-in the flags, so we don't need to load them first. + // This is get0 so we can just ignore the pointer, we don't have an owned ref. + let trustParams = CNIOBoringSSL_SSL_CTX_get0_param(context)! + CNIOBoringSSL_X509_VERIFY_PARAM_set_flags(trustParams, CUnsignedLong(X509_V_FLAG_TRUSTED_FIRST)) + + func configureTrustRoots(trustRoots: NIOSSLTrustRoots) throws { + switch trustRoots { + case .default: + try NIOSSLContext.platformDefaultConfiguration(context: context) + case .file(let path): + try NIOSSLContext.loadVerifyLocations(path, context: context, sendCANames: sendCANames) + case .certificates(let certs): + for cert in certs { + try NIOSSLContext.addRootCertificate(cert, context: context) + // Add the CA name from the trust root + if sendCANames { + try NIOSSLContext.addCACertificateNameToList(context: context, certificate: cert) + } + } + } + } + try configureTrustRoots(trustRoots: trustRoots ?? .default) + try additionalTrustRoots.forEach { try configureTrustRoots(trustRoots: .init(from: $0)) } + default: + break + } + } + + private static func addCACertificateNameToList(context: OpaquePointer, certificate: NIOSSLCertificate) throws { + // Adds the CA name extracted from cert to the list of CAs sent to the client when requesting a client certificate. + try certificate.withUnsafeMutableX509Pointer { ref in + guard 1 == CNIOBoringSSL_SSL_CTX_add_client_CA(context, ref) else { + throw NIOSSLError.failedToLoadCertificate + } + } + } + + private static func loadVerifyLocations(_ path: String, context: OpaquePointer, sendCANames: Bool) throws { + let isDirectory: Bool + switch FileSystemObject.pathType(path: path) { + case .some(.directory): + isDirectory = true + case .some(.file): + isDirectory = false + case .none: + throw NIOSSLError.noSuchFilesystemObject + } + + let result = path.withCString { (pointer) -> CInt in + let file = !isDirectory ? pointer : nil + let directory = isDirectory ? pointer: nil + return CNIOBoringSSL_SSL_CTX_load_verify_locations(context, file, directory) + } + + if result == 0 { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } else if sendCANames, !isDirectory { + // For single CA file, add the CA name from the trust root. + // This could be from a location like /etc/ssl/cert.pem as an example. + CNIOBoringSSL_SSL_CTX_set_client_CA_list(context, CNIOBoringSSL_SSL_load_client_CA_file(path)) + } else if sendCANames, isDirectory { + // Match the c_rehash directory format and load the certificate based on this criteria. + let certificateFilePaths = try DirectoryContents(path: path).filter { + try self._isRehashFormat(path: $0) + } + // Load only the certificates that resolve to an existing certificate in the directory. + for symPath in certificateFilePaths { + // c_rehash only support pem files. + let cert = try NIOSSLCertificate(file: symPath, format: .pem) + try addCACertificateNameToList(context: context, certificate: cert) + } + } + } + + private static func addRootCertificate(_ cert: NIOSSLCertificate, context: OpaquePointer) throws { + let store = CNIOBoringSSL_SSL_CTX_get_cert_store(context)! + let rc = cert.withUnsafeMutableX509Pointer { ref in + CNIOBoringSSL_X509_STORE_add_cert(store, ref) + } + if 0 == rc { + throw NIOSSLError.failedToLoadCertificate + } + } + + private static func platformDefaultConfiguration(context: OpaquePointer) throws { + // Platform default trust is configured differently in different places. + // On Linux, we use our searched heuristics to guess about where the platform trust store is. + // On Darwin, we use a custom callback that is set later, in createConnection + #if os(Linux) + let result = rootCAFilePath.withCString { rootCAFilePointer in + rootCADirectoryPath.withCString { rootCADirectoryPointer in + CNIOBoringSSL_SSL_CTX_load_verify_locations(context, rootCAFilePointer, rootCADirectoryPointer) + } + } + + if result == 0 { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + #endif + } + + private static func setKeylogCallback(context: OpaquePointer) throws { + CNIOBoringSSL_SSL_CTX_set_keylog_callback(context) { (ssl, linePointer) in + guard let ssl = ssl, let linePointer = linePointer else { + return + } + + // We want to take the SSL pointer and extract the parent Swift object. These force-unwraps are for + // safety: a correct NIO program can never fail to set these pointers, and if it does failing loudly is + // more useful than failing quietly. + let parentCtx = CNIOBoringSSL_SSL_get_SSL_CTX(ssl)! + let parentPtr = CNIOBoringSSLShims_SSL_CTX_get_app_data(parentCtx)! + let parentSwiftContext: NIOSSLContext = Unmanaged.fromOpaque(parentPtr).takeUnretainedValue() + + // Similarly, this force-unwrap is safe because a correct NIO program can never fail to unwrap this entry + // either. + parentSwiftContext.keyLogManager!.log(linePointer) + } + } + + /// Takes a path and determines if the file at this path is of c_rehash format . + internal static func _isRehashFormat(path: String) throws -> Bool { + // Check if the element’s name matches the c_rehash symlink name format. + // The links created are of the form HHHHHHHH.D, where each H is a hexadecimal character and D is a single decimal digit. + let utf8PathView = path.utf8 + let utf8PathSplitView = utf8PathView.split(separator: UInt8(ascii: "/")) + + // Make sure the path is at least 10 units long + guard let lastPathComponent = utf8PathSplitView.last, + lastPathComponent.count == 10 else { return false } + // Split into filename parts HHHHHHHH.D -> [[HHHHHHHH], [D]] + let filenameParts = lastPathComponent.split(separator: UInt8(ascii: ".")) + + // Double check that the extension did not fail to cast to an integer. + // Make sure that the filename is an 8 character hex based file name. + guard filenameParts.count == 2, + let filename = filenameParts.first, + let fileExtension = filenameParts.last, + fileExtension.count == 1, + filename.count == 8, + filename.allSatisfy({ $0.isHexDigit }), + fileExtension.first == UInt8(ascii: "0") else { return false } + + // Check if the element is a symlink. If it is not, return false. + var buffer = stat() + let _ = try Posix.lstat(path: path, buf: &buffer) + // Check the mode to make sure this is a symlink +#if os(Android) && arch(arm) + if (buffer.st_mode & UInt32(Glibc.S_IFMT)) != UInt32(Glibc.S_IFLNK) { return false } +#else + if (buffer.st_mode & S_IFMT) != S_IFLNK { return false } +#endif + + // Return true at this point because the file format is considered to be in rehash format and a symlink. + // Rehash format being "%08lx.%d" or HHHHHHHH.D + return true + } +} + +extension NIOSSLContext { + /// Exposes the CA Name list count from BoringSSL's STACK_OF(X509_NAME) + func getX509NameListCount() -> Int { + guard let caNameList = CNIOBoringSSL_SSL_CTX_get_client_CA_list(self.sslContext) else { + return 0 + } + return CNIOBoringSSL_sk_X509_NAME_num(caNameList) + } +} + +// For accessing STACK_OF(SSL_CIPHER) from a SSLContext +extension NIOSSLContext { + /// A collection of buffers representing a STACK_OF(SSL_CIPHER) + struct NIOTLSCipherBuffers { + private let basePointer: OpaquePointer + + fileprivate init(basePointer: OpaquePointer) { + self.basePointer = basePointer + } + } + + /// Invokes a block with a collection of pointers to STACK_OF(SSL_CIPHER). + /// + /// The pointers are only guaranteed to be valid for the duration of this call. This method aligns with the RandomAccessCollection protocol + /// to access UInt16 pointers at a specific index. This pointer is used to safely access id values of the cipher to create a new NIOTLSCipher. + fileprivate func withStackOfCipherSuiteBuffers(_ body: (NIOTLSCipherBuffers?) throws -> Result) rethrows -> Result { + guard let stackPointer = CNIOBoringSSL_SSL_CTX_get_ciphers(self.sslContext) else { + return try body(nil) + } + return try body(NIOTLSCipherBuffers(basePointer: stackPointer)) + } + + /// Access cipher suites applied to the context + internal var cipherSuites: [NIOTLSCipher] { + return self.withStackOfCipherSuiteBuffers { buffers in + guard let buffers = buffers else { + return [] + } + return Array(buffers) + } + } +} + +extension NIOSSLContext.NIOTLSCipherBuffers: RandomAccessCollection { + + struct Index: Hashable, Comparable, Strideable { + typealias Stride = Int + + fileprivate var index: Int + + fileprivate init(_ index: Int) { + self.index = index + } + + static func < (lhs: Index, rhs: Index) -> Bool { + return lhs.index < rhs.index + } + + func advanced(by n: NIOSSLContext.NIOTLSCipherBuffers.Index.Stride) -> NIOSSLContext.NIOTLSCipherBuffers.Index { + var result = self + result.index += n + return result + } + + func distance(to other: NIOSSLContext.NIOTLSCipherBuffers.Index) -> NIOSSLContext.NIOTLSCipherBuffers.Index.Stride { + return other.index - self.index + } + } + + typealias Element = NIOTLSCipher + + var startIndex: Index { + return Index(0) + } + + var endIndex: Index { + return Index(self.count) + } + + var count: Int { + return CNIOBoringSSL_sk_SSL_CIPHER_num(self.basePointer) + } + + subscript(position: Index) -> NIOTLSCipher { + precondition(position < self.endIndex) + precondition(position >= self.startIndex) + guard let ptr = CNIOBoringSSL_sk_SSL_CIPHER_value(self.basePointer, position.index) else { + preconditionFailure("Unable to locate backing pointer.") + } + let cipherID = CNIOBoringSSL_SSL_CIPHER_get_protocol_id(ptr) + return NIOTLSCipher(cipherID) + } +} + +extension Optional where Wrapped == String { + internal func withCString(_ body: (UnsafePointer?) throws -> Result) rethrows -> Result { + switch self { + case .some(let s): + return try s.withCString({ try body($0 ) }) + case .none: + return try body(nil) + } + } +} + +internal class DirectoryContents: Sequence, IteratorProtocol { + + typealias Element = String + let path: String + // Used to account between the differences of DIR being defined on Darwin. + // Otherwise an OpaquePointer needs to be used to account for the non-defined type in glibc. + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + let dir: UnsafeMutablePointer + #else + let dir: OpaquePointer + #endif + + init(path: String) { + self.path = path + self.dir = opendir(path) + } + + func next() -> String? { + if let dirent: UnsafeMutablePointer = readdir(self.dir) { + let name = withUnsafePointer(to: &dirent.pointee.d_name) { (ptr) -> String in + // Pointers to homogeneous tuples in Swift are always bound to both the tuple type and the element type, + // so the assumption below is safe. + let elementPointer = UnsafeRawPointer(ptr).assumingMemoryBound(to: CChar.self) + return String(cString: elementPointer) + } + return self.path + name + } + return nil + } + + deinit { + closedir(dir) + } +} + +// Used as part of the `_isRehashFormat` format to determine if the filename is a hexadecimal filename. +extension UTF8.CodeUnit { + private static let asciiZero = UInt8(ascii: "0") + private static let asciiNine = UInt8(ascii: "9") + private static let asciiLowercaseA = UInt8(ascii: "a") + private static let asciiLowercaseF = UInt8(ascii: "f") + private static let asciiUppercaseA = UInt8(ascii: "A") + private static let asciiUppercaseF = UInt8(ascii: "F") + + var isHexDigit: Bool { + switch self { + case (.asciiZero)...(.asciiNine), + (.asciiLowercaseA)...(.asciiLowercaseF), + (.asciiUppercaseA)...(.asciiUppercaseF): + return true + default: + return false + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLErrors.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLErrors.swift new file mode 100644 index 00000000..cbaae0e4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLErrors.swift @@ -0,0 +1,250 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL + +/// Wraps a single error from BoringSSL. +public struct BoringSSLInternalError: Equatable, CustomStringConvertible { + private enum Backing: Hashable { + case boringSSLErrorCode(UInt32) + case synthetic(String) + } + + private var backing: Backing + + private var errorMessage: String? { + switch self.backing { + case .boringSSLErrorCode(let errorCode): + // TODO(cory): This should become non-optional in the future, as it always succeeds. + var scratchBuffer = [CChar](repeating: 0, count: 512) + return scratchBuffer.withUnsafeMutableBufferPointer { pointer in + CNIOBoringSSL_ERR_error_string_n(errorCode, pointer.baseAddress!, pointer.count) + return String(cString: pointer.baseAddress!) + } + case .synthetic(let description): + return description + } + } + + private var errorCode: String { + switch self.backing { + case .boringSSLErrorCode(let code): + return String(code, radix: 10) + case .synthetic: + return "" + } + } + + public var description: String { + return "Error: \(errorCode) \(errorMessage ?? "")" + } + + init(errorCode: UInt32) { + self.backing = .boringSSLErrorCode(errorCode) + } + + private init(syntheticErrorDescription description: String) { + self.backing = .synthetic(description) + } + + /// Received EOF during the TLS handshake. + public static let eofDuringHandshake = Self(syntheticErrorDescription: "EOF during handshake") +} + +/// A representation of BoringSSL's internal error stack: a list of BoringSSL errors. +public typealias NIOBoringSSLErrorStack = [BoringSSLInternalError] + + +/// Errors that can be raised by NIO's BoringSSL wrapper. +public enum NIOSSLError: Error { + case writeDuringTLSShutdown + @available(*, deprecated, message: "unableToAllocateBoringSSLObject can no longer be thrown") + case unableToAllocateBoringSSLObject + case noSuchFilesystemObject + case failedToLoadCertificate + case failedToLoadPrivateKey + case handshakeFailed(BoringSSLError) + case shutdownFailed(BoringSSLError) + case cannotMatchULabel + case noCertificateToValidate + case unableToValidateCertificate + case cannotFindPeerIP + case readInInvalidTLSState + case uncleanShutdown +} + +extension NIOSSLError: Equatable {} + +/// Closing the TLS channel cleanly timed out, so it was closed uncleanly. +public struct NIOSSLCloseTimedOutError: Error {} + +/// An enum that wraps individual BoringSSL errors directly. +public enum BoringSSLError: Error { + case noError + case zeroReturn + case wantRead + case wantWrite + case wantConnect + case wantAccept + case wantX509Lookup + case wantCertificateVerify + case syscallError + case sslError(NIOBoringSSLErrorStack) + case unknownError(NIOBoringSSLErrorStack) + case invalidSNIName(NIOBoringSSLErrorStack) + case failedToSetALPN(NIOBoringSSLErrorStack) +} + +extension BoringSSLError: Equatable {} + + +internal extension BoringSSLError { + static func fromSSLGetErrorResult(_ result: CInt) -> BoringSSLError? { + switch result { + case SSL_ERROR_NONE: + return .noError + case SSL_ERROR_ZERO_RETURN: + return .zeroReturn + case SSL_ERROR_WANT_READ: + return .wantRead + case SSL_ERROR_WANT_WRITE: + return .wantWrite + case SSL_ERROR_WANT_CONNECT: + return .wantConnect + case SSL_ERROR_WANT_ACCEPT: + return .wantAccept + case SSL_ERROR_WANT_CERTIFICATE_VERIFY: + return .wantCertificateVerify + case SSL_ERROR_WANT_X509_LOOKUP: + return .wantX509Lookup + case SSL_ERROR_SYSCALL: + return .syscallError + case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: + // This is a terrible hack: we can't add cases to this enum, so we can't represent + // this directly. In all cases this should be the same as wantCertificateVerify, so we'll just use that. + return .wantCertificateVerify + case SSL_ERROR_SSL: + return .sslError(buildErrorStack()) + default: + return .unknownError(buildErrorStack()) + } + } + + static func buildErrorStack() -> NIOBoringSSLErrorStack { + var errorStack = NIOBoringSSLErrorStack() + + while true { + let errorCode = CNIOBoringSSL_ERR_get_error() + if errorCode == 0 { break } + errorStack.append(BoringSSLInternalError(errorCode: errorCode)) + } + + return errorStack + } +} + +/// Represents errors that may occur while attempting to unwrap TLS from a connection. +public enum NIOTLSUnwrappingError: Error { + /// The TLS channel has already been closed, so it is not possible to unwrap it. + case alreadyClosed + + /// The internal state of the handler is not able to process the unwrapping request. + case invalidInternalState + + /// We were unwrapping the connection, but during the unwrap process a close call + /// was made. This means the connection is now closed, not unwrapped. + case closeRequestedDuringUnwrap + + /// This write was failed because the channel was unwrapped before it was flushed. + case unflushedWriteOnUnwrap +} + + +/// This structure contains errors added to NIOSSL after the original `NIOSSLError` enum was +/// shipped. This is an extensible error object that allows us to evolve it going forward. +public struct NIOSSLExtraError: Error { + private var baseError: NIOSSLExtraError.BaseError + + private var _description: String? + + private init(baseError: NIOSSLExtraError.BaseError, description: String?) { + self.baseError = baseError + self._description = description + } +} + + +extension NIOSSLExtraError { + private enum BaseError: Equatable { + case failedToValidateHostname + case serverHostnameImpossibleToMatch + case cannotUseIPAddressInSNI + case invalidSNIHostname + } +} + + +extension NIOSSLExtraError { + /// NIOSSL was unable to validate the hostname presented by the remote peer. + public static let failedToValidateHostname = NIOSSLExtraError(baseError: .failedToValidateHostname, description: nil) + + /// The server hostname provided by the user cannot match any names in the certificate due to containing invalid characters. + public static let serverHostnameImpossibleToMatch = NIOSSLExtraError(baseError: .serverHostnameImpossibleToMatch, description: nil) + + /// IP addresses may not be used in SNI. + public static let cannotUseIPAddressInSNI = NIOSSLExtraError(baseError: .cannotUseIPAddressInSNI, description: nil) + + /// The SNI hostname requirements have not been met. + /// + /// - note: Should the provided SNI hostname be an IP address instead, `.cannotUseIPAddressInSNI` is thrown instead + /// of this error. + /// + /// Reasons a hostname might not meet the requirements: + /// - hostname in UTF8 is more than 255 bytes + /// - hostname is the empty string + /// - hostname contains the `0` unicode scalar (which would be encoded as the `0` byte which is unsupported). + public static let invalidSNIHostname = NIOSSLExtraError(baseError: .invalidSNIHostname, description: nil) + + @inline(never) + internal static func failedToValidateHostname(expectedName: String) -> NIOSSLExtraError { + let description = "Couldn't find \(expectedName) in certificate from peer" + return NIOSSLExtraError(baseError: .failedToValidateHostname, description: description) + } + + @inline(never) + internal static func serverHostnameImpossibleToMatch(hostname: String) -> NIOSSLExtraError { + let description = "The server hostname \(hostname) cannot be matched due to containing non-DNS characters" + return NIOSSLExtraError(baseError: .serverHostnameImpossibleToMatch, description: description) + } + + @inline(never) + internal static func cannotUseIPAddressInSNI(ipAddress: String) -> NIOSSLExtraError { + let description = "IP addresses cannot validly be used for Server Name Indication, got \(ipAddress)" + return NIOSSLExtraError(baseError: .cannotUseIPAddressInSNI, description: description) + } +} + + +extension NIOSSLExtraError: CustomStringConvertible { + public var description: String { + let formattedDescription = self._description.map { ": " + $0 } ?? "" + return "NIOSSLExtraError.\(String(describing: self.baseError))\(formattedDescription)" + } +} + +extension NIOSSLExtraError: Equatable { + public static func ==(lhs: NIOSSLExtraError, rhs: NIOSSLExtraError) -> Bool { + return lhs.baseError == rhs.baseError + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLInit.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLInit.swift new file mode 100644 index 00000000..3ddecc3b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLInit.swift @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL + +/// Initialize BoringSSL. Note that this function IS NOT THREAD SAFE, and so must be called inside +/// either an explicit or implicit dispatch_once. +func initializeBoringSSL() -> Bool { + CNIOBoringSSL_CRYPTO_library_init() + return true +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPKCS12Bundle.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPKCS12Bundle.swift new file mode 100644 index 00000000..ca9a3d66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPKCS12Bundle.swift @@ -0,0 +1,210 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL + + +/// A container of a single PKCS#12 bundle. +/// +/// PKCS#12 is a specification that defines an archive format for storing multiple +/// cryptographic objects together in one file. Its most common usage, and the one +/// that SwiftNIO is most interested in, is its use to bundle one or more X.509 +/// certificates (`NIOSSLCertificate`) together with an associated private key +/// (`NIOSSLPrivateKey`). +/// +/// ### Working with TLSConfiguration +/// +/// In many cases users will want to configure a `TLSConfiguration` with the data +/// from a PKCS#12 bundle. This object assists in unpacking that bundle into its +/// associated pieces. +/// +/// If you have a PKCS12 bundle, you configure a `TLSConfiguration` like this: +/// +/// let p12Bundle = NIOSSLPKCS12Bundle(file: pathToMyP12) +/// let config = TLSConfiguration.makeServerConfiguration( +/// certificateChain: p12Bundle.certificateChain, +/// privateKey: p12Bundle.privateKey +/// ) +/// +/// The created `TLSConfiguration` can then be safely used for your endpoint. +public struct NIOSSLPKCS12Bundle: Hashable { + public let certificateChain: [NIOSSLCertificate] + public let privateKey: NIOSSLPrivateKey + + private init(ref: OpaquePointer, passphrase: Bytes?) throws where Bytes.Element == UInt8 { + var pkey: UnsafeMutablePointer? = nil + var cert: OpaquePointer?/**/ = nil + var caCerts: OpaquePointer? = nil + + let rc = try passphrase.withSecureCString { passphrase in + CNIOBoringSSL_PKCS12_parse(ref, passphrase, &pkey, &cert, &caCerts) + } + guard rc == 1 else { + throw BoringSSLError.unknownError(BoringSSLError.buildErrorStack()) + } + + // Successfully parsed, let's unpack. The key and cert are mandatory, + // the ca stack is not. + guard let actualCert = cert, let actualKey = pkey else { + fatalError("Failed to obtain cert and pkey from a PKC12 file") + } + + let certStackSize = caCerts.map { CNIOBoringSSL_sk_X509_num($0) } ?? 0 + var certs = [NIOSSLCertificate]() + certs.reserveCapacity(Int(certStackSize) + 1) + certs.append(NIOSSLCertificate.fromUnsafePointer(takingOwnership: actualCert)) + + for idx in 0..(buffer: [UInt8], passphrase: Bytes?) throws where Bytes.Element == UInt8 { + guard boringSSLIsInitialized else { fatalError("Failed to initialize BoringSSL") } + + let p12 = buffer.withUnsafeBytes { pointer -> OpaquePointer? in + let bio = CNIOBoringSSL_BIO_new_mem_buf(pointer.baseAddress, CInt(pointer.count))! + defer { + CNIOBoringSSL_BIO_free(bio) + } + return CNIOBoringSSL_d2i_PKCS12_bio(bio, nil) + } + defer { + p12.map { CNIOBoringSSL_PKCS12_free($0) } + } + + if let p12 = p12 { + try self.init(ref: p12, passphrase: passphrase) + } else { + throw BoringSSLError.unknownError(BoringSSLError.buildErrorStack()) + } + } + + /// Create a `NIOSSLPKCS12Bundle` from the given bytes on disk, + /// optionally decrypting the bundle with the given passphrase. + /// + /// - parameters: + /// - file: The path to the PKCS#12 bundle on disk. + /// - passphrase: The passphrase used for the bundle, as a sequence of UTF-8 bytes. + public init(file: String, passphrase: Bytes?) throws where Bytes.Element == UInt8 { + guard boringSSLIsInitialized else { fatalError("Failed to initialize BoringSSL") } + + let fileObject = try Posix.fopen(file: file, mode: "rb") + defer { + fclose(fileObject) + } + + let p12 = CNIOBoringSSL_d2i_PKCS12_fp(fileObject, nil) + defer { + p12.map(CNIOBoringSSL_PKCS12_free) + } + + if let p12 = p12 { + try self.init(ref: p12, passphrase: passphrase) + } else { + throw BoringSSLError.unknownError(BoringSSLError.buildErrorStack()) + } + } + + /// Create a `NIOSSLPKCS12Bundle` from the given bytes on disk, + /// assuming it has no passphrase. + /// + /// If the bundle does have a passphrase, call `init(file:passphrase:)` instead. + /// + /// - parameters: + /// - file: The path to the PKCS#12 bundle on disk. + public init(file: String) throws { + try self.init(file: file, passphrase: Optional<[UInt8]>.none) + } + + /// Create a `NIOSSLPKCS12Bundle` from the given bytes in memory, + /// assuming it has no passphrase. + /// + /// If the bundle does have a passphrase, call `init(buffer:passphrase:)` instead. + /// + /// - parameters: + /// - buffer: The bytes of the PKCS#12 bundle. + public init(buffer: [UInt8]) throws { + try self.init(buffer: buffer, passphrase: Optional<[UInt8]>.none) + } +} + + +extension Collection where Element == UInt8 { + /// Provides a contiguous copy of the bytes of this collection in a heap-allocated + /// memory region that is locked into memory (that is, which can never be backed by a file), + /// and which will be scrubbed and freed after use, and which is null-terminated. + /// + /// This method should be used when it is necessary to take a secure copy of a collection of + /// bytes. Its implementation relies on BoringSSL directly. + func withSecureCString(_ block: (UnsafePointer) throws -> T) throws -> T { + // We need to allocate some memory and prevent it being swapped to disk while we use it. + // For that reason we use mlock. + let bufferSize = Int(self.count) + 1 + let bufferPtr = UnsafeMutableBufferPointer.allocate(capacity: bufferSize) + defer { + bufferPtr.deallocate() + } + + try Posix.mlock(addr: bufferPtr.baseAddress!, len: bufferPtr.count) + defer { + // If munlock fails take out the process. + try! Posix.munlock(addr: bufferPtr.baseAddress!, len: bufferPtr.count) + } + + let (_, nextIndex) = bufferPtr.initialize(from: self) + assert(nextIndex == (bufferPtr.endIndex - 1)) + + // Add a null terminator. + bufferPtr[nextIndex] = 0 + + defer { + // We use OpenSSL_cleanse here because the compiler can't optimize this away. + // .initialize(repeating: 0) can be, and empirically is, optimized away, bzero + // is deprecated, memset_s is not well supported cross-platform, and memset-to-zero + // is famously easily optimised away. This is our best bet. + CNIOBoringSSL_OPENSSL_cleanse(bufferPtr.baseAddress!, bufferPtr.count) + bufferPtr.baseAddress!.deinitialize(count: bufferPtr.count) + } + + // Ok, the memory is ready for use. Call the user. + return try bufferPtr.withMemoryRebound(to: Int8.self) { + try block($0.baseAddress!) + } + } +} + + +internal extension Optional where Wrapped: Collection, Wrapped.Element == UInt8 { + func withSecureCString(_ block: (UnsafePointer?) throws -> T) throws -> T { + if let `self` = self { + return try self.withSecureCString({ try block($0) }) + } else { + return try block(nil) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPrivateKey.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPrivateKey.swift new file mode 100644 index 00000000..c259125f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPrivateKey.swift @@ -0,0 +1,404 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL + +/// An `NIOSSLPassphraseCallback` is a callback that will be invoked by NIOSSL when it needs to +/// get access to a private key that is stored in encrypted form. +/// +/// This callback will be invoked with one argument, a non-escaping closure that must be called with the +/// passphrase. Failing to call the closure will cause decryption to fail. +/// +/// The reason this design has been used is to allow you to secure any memory storing the passphrase after +/// use. We guarantee that after the `NIOSSLPassphraseSetter` closure has been invoked the `Collection` +/// you have passed in will no longer be needed by BoringSSL, and so you can safely destroy any memory it +/// may be using if you need to. +public typealias NIOSSLPassphraseCallback = (NIOSSLPassphraseSetter) throws -> Void where Bytes.Element == UInt8 + + +/// An `NIOSSLPassphraseSetter` is a closure that you must invoke to provide a passphrase to BoringSSL. +/// It will be provided to you when your `NIOSSLPassphraseCallback` is invoked. +public typealias NIOSSLPassphraseSetter = (Bytes) -> Void where Bytes.Element == UInt8 + + +/// An internal protocol that exists to let us avoid problems with generic types. +/// +/// The issue we have here is that we want to allow users to use whatever collection type suits them best to set +/// the passphrase. For this reason, `NIOSSLPassphraseSetter` is a generic function, generic over the `Collection` +/// protocol. However, that causes us an issue, because we need to stuff that callback into an +/// `BoringSSLPassphraseCallbackManager` in order to create an `Unmanaged` and round-trip the pointer through C code. +/// +/// That makes `BoringSSLPassphraseCallbackManager` a generic object, and now we're in *real* trouble, becuase +/// `Unmanaged` requires us to specify the *complete* type of the object we want to unwrap. In this case, we +/// don't know it, because it's generic! +/// +/// Our way out is to note that while the class itself is generic, the only function we want to call in the +/// `globalBoringSSLPassphraseCallback` is not. Thus, rather than try to hold the actual specific `BoringSSLPassphraseManager`, +/// we can hold it inside a protocol existential instead, so long as that protocol existential gives us the correct +/// function to call. Hence: `CallbackManagerProtocol`, a private protocol with a single conforming type. +internal protocol CallbackManagerProtocol: AnyObject { + func invoke(buffer: UnsafeMutableBufferPointer) -> CInt +} + + +/// This class exists primarily to work around the fact that Swift does not let us stuff +/// a closure into an `Unmanaged`. Instead, we use this object to keep hold of it. +final class BoringSSLPassphraseCallbackManager: CallbackManagerProtocol where Bytes.Element == UInt8 { + private let userCallback: NIOSSLPassphraseCallback + + init(userCallback: @escaping NIOSSLPassphraseCallback){ + // We have to type-erase this. + self.userCallback = userCallback + } + + func invoke(buffer: UnsafeMutableBufferPointer) -> CInt { + var count: CInt = 0 + + do { + try self.userCallback { passphraseBytes in + // If we don't have enough space for the passphrase plus NUL, bail out. + guard passphraseBytes.count < buffer.count else { return } + _ = buffer.initialize(from: passphraseBytes.lazy.map { CChar($0) }) + count = CInt(passphraseBytes.count) + + // We need to add a NUL terminator, in case the user did not. + buffer[Int(passphraseBytes.count)] = 0 + } + } catch { + // If we hit an error here, we just need to tolerate it. We'll return zero-length. + count = 0 + } + + return count + } +} + + +/// Our global static BoringSSL passphrase callback. This is used as a thunk to dispatch out to +/// the user-provided callback. +func globalBoringSSLPassphraseCallback(buf: UnsafeMutablePointer?, + size: CInt, + rwflag: CInt, + u: UnsafeMutableRawPointer?) -> CInt { + guard let buffer = buf, let userData = u else { + preconditionFailure("Invalid pointers passed to passphrase callback, buf: \(String(describing: buf)) u: \(String(describing: u))") + } + let bufferPointer = UnsafeMutableBufferPointer(start: buffer, count: Int(size)) + guard let cbManager = Unmanaged.fromOpaque(userData).takeUnretainedValue() as? CallbackManagerProtocol else { + preconditionFailure("Failed to pass object that can handle callback") + } + return cbManager.invoke(buffer: bufferPointer) +} + + +/// A reference to an BoringSSL private key object in the form of an `EVP_PKEY *`. +/// +/// This thin wrapper class allows us to use ARC to automatically manage +/// the memory associated with this key. That ensures that BoringSSL +/// will not free the underlying buffer until we are done with the key. +/// +/// This class also provides several convenience constructors that allow users +/// to obtain an in-memory representation of a key from a buffer of +/// bytes or from a file path. +public class NIOSSLPrivateKey { + @usableFromInline + internal enum Representation { + case native(UnsafeMutableRawPointer /*(_ body: (UnsafeMutablePointer) throws -> ReturnType) rethrows -> ReturnType { + guard case .native(let pointer) = self.representation else { + preconditionFailure() + } + + return try body(pointer.assumingMemoryBound(to: EVP_PKEY.self)) + } + + private init(withReference ref: UnsafeMutablePointer) { + self.representation = .native(UnsafeMutableRawPointer(ref)) // erasing the type for @_implementationOnly import CNIOBoringSSL + } + + /// A delegating initializer for `init(file:format:passphraseCallback)` and `init(file:format:)`. + private convenience init(file: String, format: NIOSSLSerializationFormats, callbackManager: CallbackManagerProtocol?) throws { + let fileObject = try Posix.fopen(file: file, mode: "rb") + defer { + // If fclose fails there is nothing we can do about it. + _ = try? Posix.fclose(file: fileObject) + } + + let key = withExtendedLifetime(callbackManager) { callbackManager -> UnsafeMutablePointer? in + guard let bio = CNIOBoringSSL_BIO_new_fp(fileObject, BIO_NOCLOSE) else { + return nil + } + defer { + CNIOBoringSSL_BIO_free(bio) + } + + switch format { + case .pem: + // This annoying conditional binding is used to work around the fact that I cannot pass + // a variable to a function pointer argument. + if let callbackManager = callbackManager { + return CNIOBoringSSL_PEM_read_PrivateKey(fileObject, nil, { globalBoringSSLPassphraseCallback(buf: $0, size: $1, rwflag: $2, u: $3) }, Unmanaged.passUnretained(callbackManager as AnyObject).toOpaque()) + } else { + return CNIOBoringSSL_PEM_read_PrivateKey(fileObject, nil, nil, nil) + } + case .der: + return CNIOBoringSSL_d2i_PrivateKey_fp(fileObject, nil) + } + } + + if key == nil { + throw NIOSSLError.failedToLoadPrivateKey + } + + self.init(withReference: key!) + } + + /// A delegating initializer for `init(buffer:format:passphraseCallback)` and `init(buffer:format:)`. + private convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats, callbackManager: CallbackManagerProtocol?) throws { + let ref = bytes.withUnsafeBytes { (ptr) -> UnsafeMutablePointer? in + let bio = CNIOBoringSSL_BIO_new_mem_buf(ptr.baseAddress!, CInt(ptr.count))! + defer { + CNIOBoringSSL_BIO_free(bio) + } + + return withExtendedLifetime(callbackManager) { callbackManager -> UnsafeMutablePointer? in + switch format { + case .pem: + if let callbackManager = callbackManager { + // This annoying conditional binding is used to work around the fact that I cannot pass + // a variable to a function pointer argument. + return CNIOBoringSSL_PEM_read_bio_PrivateKey(bio, nil, { globalBoringSSLPassphraseCallback(buf: $0, size: $1, rwflag: $2, u: $3) }, Unmanaged.passUnretained(callbackManager as AnyObject).toOpaque()) + } else { + return CNIOBoringSSL_PEM_read_bio_PrivateKey(bio, nil, nil, nil) + } + case .der: + return CNIOBoringSSL_d2i_PrivateKey_bio(bio, nil) + } + } + } + + if ref == nil { + throw NIOSSLError.failedToLoadPrivateKey + } + + self.init(withReference: ref!) + } + + /// Create an NIOSSLPrivateKey from a file at a given path in either PEM or + /// DER format, providing a passphrase callback. + /// + /// - parameters: + /// - file: The path to the file to load. + /// - format: The format of the key to load, either DER or PEM. + public convenience init(file: String, format: NIOSSLSerializationFormats) throws { + try self.init(file: file, format: format, callbackManager: nil) + } + + /// Create an NIOSSLPrivateKey from a file at a given path in either PEM or + /// DER format, providing a passphrase callback. + /// + /// - parameters: + /// - file: The path to the file to load. + /// - format: The format of the key to load, either DER or PEM. + /// - passphraseCallback: A callback to invoke to obtain the passphrase for + /// encrypted keys. + public convenience init(file: String, format: NIOSSLSerializationFormats, passphraseCallback: @escaping NIOSSLPassphraseCallback) throws where T.Element == UInt8 { + let manager = BoringSSLPassphraseCallbackManager(userCallback: passphraseCallback) + try self.init(file: file, format: format, callbackManager: manager) + } + + /// Create an NIOSSLPrivateKey from a buffer of bytes in either PEM or + /// DER format. + /// + /// - parameters: + /// - buffer: The key bytes. + /// - format: The format of the key to load, either DER or PEM. + /// - SeeAlso: `NIOSSLPrivateKey.init(bytes:format:)` + @available(*, deprecated, renamed: "NIOSSLPrivateKey.init(bytes:format:)") + public convenience init(buffer: [Int8], format: NIOSSLSerializationFormats) throws { + try self.init(bytes: buffer.map(UInt8.init), format: format) + } + + /// Create an NIOSSLPrivateKey from a buffer of bytes in either PEM or + /// DER format. + /// + /// - parameters: + /// - bytes: The key bytes. + /// - format: The format of the key to load, either DER or PEM. + public convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats) throws { + try self.init(bytes: bytes, format: format, callbackManager: nil) + } + + /// Create an NIOSSLPrivateKey from a buffer of bytes in either PEM or + /// DER format. + /// + /// - parameters: + /// - buffer: The key bytes. + /// - format: The format of the key to load, either DER or PEM. + /// - passphraseCallback: Optionally a callback to invoke to obtain the passphrase for + /// encrypted keys. If not provided, or set to `nil`, the default BoringSSL + /// behaviour will be used, which prints a prompt and requests the passphrase from + /// stdin. + /// - SeeAlso: `NIOSSLPrivateKey.init(bytes:format:passphraseCallback:)` + @available(*, deprecated, renamed: "NIOSSLPrivateKey.init(bytes:format:passphraseCallback:)") + public convenience init(buffer: [Int8], format: NIOSSLSerializationFormats, passphraseCallback: @escaping NIOSSLPassphraseCallback) throws where T.Element == UInt8 { + try self.init(bytes: buffer.map(UInt8.init), format: format, passphraseCallback: passphraseCallback) + } + + /// Create an NIOSSLPrivateKey from a buffer of bytes in either PEM or + /// DER format. + /// + /// - parameters: + /// - bytes: The key bytes. + /// - format: The format of the key to load, either DER or PEM. + /// - passphraseCallback: Optionally a callback to invoke to obtain the passphrase for + /// encrypted keys. If not provided, or set to `nil`, the default BoringSSL + /// behaviour will be used, which prints a prompt and requests the passphrase from + /// stdin. + public convenience init(bytes: [UInt8], format: NIOSSLSerializationFormats, passphraseCallback: @escaping NIOSSLPassphraseCallback) throws where T.Element == UInt8 { + let manager = BoringSSLPassphraseCallbackManager(userCallback: passphraseCallback) + try self.init(bytes: bytes, format: format, callbackManager: manager) + } + + /// Create a `NIOSSLPrivateKey` from a custom private key callback. + /// + /// The private key, in addition to needing to conform to `NIOSSLCustomPrivateKey`, + /// is also required to be `Hashable`. This is because `NIOSSLPrivateKey`s are `Hashable`. + /// + /// - parameters: + /// - customPrivateKey: The custom private key to use with the TLS certificate. + @inlinable + public init(customPrivateKey: CustomKey) { + self.representation = .custom(AnyNIOSSLCustomPrivateKey(customPrivateKey)) + } + + /// Create an NIOSSLPrivateKey wrapping a pointer into BoringSSL. + /// + /// This is a function that should be avoided as much as possible because it plays poorly with + /// BoringSSL's reference-counted memory. This function does not increment the reference count for the EVP_PKEY + /// object here, nor does it duplicate it: it just takes ownership of the copy here. This object + /// **will** deallocate the underlying EVP_PKEY object when deinited, and so if you need to keep that + /// EVP_PKEY object alive you create a new EVP_PKEY before passing that object here. + /// + /// In general, however, this function should be avoided in favour of one of the convenience + /// initializers, which ensure that the lifetime of the EVP_PKEY object is better-managed. + static internal func fromUnsafePointer(takingOwnership pointer: UnsafeMutablePointer) -> NIOSSLPrivateKey { + return NIOSSLPrivateKey(withReference: pointer) + } + + deinit { + switch self.representation { + case .native(let ref): + CNIOBoringSSL_EVP_PKEY_free(ref.assumingMemoryBound(to: EVP_PKEY.self)) + case .custom: + // Merely dropping the ref is enough. + () + } + } +} + + +// MARK:- Utilities +extension NIOSSLPrivateKey { + /// Calls the given body function with a temporary buffer containing the DER-encoded bytes of this + /// private key. This function does allocate for these bytes, but there is no way to avoid doing so with the + /// X509 API in BoringSSL. + /// + /// The pointer provided to the closure is not valid beyond the lifetime of this method call. + /// + /// This method is only safe to call on native private keys. + private static func withUnsafeDERBuffer(of ref: UnsafeMutablePointer, _ body: (UnsafeRawBufferPointer) throws -> T) throws -> T { + guard let bio = CNIOBoringSSL_BIO_new(CNIOBoringSSL_BIO_s_mem()) else { + fatalError("Failed to malloc for a BIO handler") + } + + defer { + CNIOBoringSSL_BIO_free(bio) + } + + let rc = CNIOBoringSSL_i2d_PrivateKey_bio(bio, ref) + guard rc == 1 else { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + + var dataPtr: UnsafeMutablePointer? = nil + let length = CNIOBoringSSL_BIO_get_mem_data(bio, &dataPtr) + + guard let bytes = dataPtr.map({ UnsafeRawBufferPointer(start: $0, count: length) }) else { + fatalError("Failed to map bytes from a private key") + } + + return try body(bytes) + } + + /// The custom signing algorithms required by this private key, if any. + /// + /// Is `nil` when the key is a native key, as this is handled by BoringSSL. + internal var customSigningAlgorithms: [SignatureAlgorithm]? { + switch self.representation { + case .native: + return nil + case .custom(let customKey): + return customKey.signatureAlgorithms + } + } +} + + +extension NIOSSLPrivateKey: Equatable { + public static func ==(lhs: NIOSSLPrivateKey, rhs: NIOSSLPrivateKey) -> Bool { + switch (lhs.representation, rhs.representation) { + case (.native, .native): + // Annoyingly, EVP_PKEY_cmp does not have a traditional return value pattern. 1 means equal, 0 means non-equal, + // negative means error. Here we treat "error" as "not equal", because we have no error reporting mechanism from this call site, + // and anyway, BoringSSL considers "these keys aren't of the same type" to be an error, which is in my mind pretty ludicrous. + return lhs.withUnsafeMutableEVPPKEYPointer { lhsRef in + rhs.withUnsafeMutableEVPPKEYPointer { rhsRef in + CNIOBoringSSL_EVP_PKEY_cmp(lhsRef, rhsRef) == 1 + } + } + + case (.custom(let lhsCustom), .custom(let rhsCustom)): + return lhsCustom == rhsCustom + + case (.native, .custom), (.custom, .native): + return false + } + } +} + + +extension NIOSSLPrivateKey: Hashable { + public func hash(into hasher: inout Hasher) { + switch self.representation { + case .native(let ref): + // Sadly, BoringSSL doesn't provide us with a nice key hashing function. We therefore have only two options: + // we can either serialize the key into DER and feed that into the hasher, or we can attempt to hash the key parameters directly. + // We could attempt the latter, but frankly it causes a lot of pain for minimal gain, so we don't bother. This incurs an allocation, + // but that's ok. We crash if we hit an error here, as there is no way to recover. + hasher.combine(0) + try! NIOSSLPrivateKey.withUnsafeDERBuffer(of: ref.assumingMemoryBound(to: EVP_PKEY.self)) { hasher.combine(bytes: $0) } + case .custom(let custom): + hasher.combine(1) + custom.hash(into: &hasher) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPublicKey.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPublicKey.swift new file mode 100644 index 00000000..aa639275 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SSLPublicKey.swift @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL + +/// An `NIOSSLPublicKey` is an abstract handle to a public key owned by BoringSSL. +/// +/// This object is of minimal utility, as it cannot be used for very many operations +/// in `NIOSSL`. Its primary purpose is to allow extracting public keys from +/// `NIOSSLCertificate` objects to be serialized, so that they can be passed to +/// general-purpose cryptography libraries. +public class NIOSSLPublicKey { + private let _ref: UnsafeMutableRawPointer /**/ + + private var ref: UnsafeMutablePointer { + return self._ref.assumingMemoryBound(to: EVP_PKEY.self) + } + + fileprivate init(withOwnedReference ref: UnsafeMutablePointer) { + self._ref = UnsafeMutableRawPointer(ref) // erasing the type for @_implementationOnly import CNIOBoringSSL + } + + deinit { + CNIOBoringSSL_EVP_PKEY_free(self.ref) + } +} + +// MARK:- Helpful initializers +extension NIOSSLPublicKey { + /// Create an `NIOSSLPublicKey` object from an internal `EVP_PKEY` pointer. + /// + /// This method expects `pointer` to be passed at +1, and consumes that reference. + /// + /// - parameters: + /// - pointer: A pointer to an `EVP_PKEY` structure containing the public key. + /// - returns: An `NIOSSLPublicKey` wrapping the pointer. + internal static func fromInternalPointer(takingOwnership pointer: UnsafeMutablePointer) -> NIOSSLPublicKey { + return NIOSSLPublicKey(withOwnedReference: pointer) + } +} + +extension NIOSSLPublicKey { + /// Extracts the bytes of this public key in the SubjectPublicKeyInfo format. + /// + /// The SubjectPublicKeyInfo format is defined in RFC 5280. In addition to the raw key bytes, it also + /// provides an identifier of the algorithm, ensuring that the key can be unambiguously decoded. + /// + /// - returns: The DER-encoded SubjectPublicKeyInfo bytes for this public key. + /// - throws: If an error occurred while serializing the key. + public func toSPKIBytes() throws -> [UInt8] { + guard let bio = CNIOBoringSSL_BIO_new(CNIOBoringSSL_BIO_s_mem()) else { + fatalError("Failed to malloc for a BIO handler") + } + + defer { + CNIOBoringSSL_BIO_free(bio) + } + + let rc = CNIOBoringSSL_i2d_PUBKEY_bio(bio, self.ref) + guard rc == 1 else { + let errorStack = BoringSSLError.buildErrorStack() + throw BoringSSLError.unknownError(errorStack) + } + + var dataPtr: UnsafeMutablePointer? = nil + let length = CNIOBoringSSL_BIO_get_mem_data(bio, &dataPtr) + + guard let bytes = dataPtr.map({ UnsafeMutableRawBufferPointer(start: $0, count: length) }) else { + fatalError("Failed to map bytes from a public key") + } + + return Array(bytes) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SecurityFrameworkCertificateVerification.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SecurityFrameworkCertificateVerification.swift new file mode 100644 index 00000000..af9466e7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SecurityFrameworkCertificateVerification.swift @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import NIOCore +@_implementationOnly import CNIOBoringSSL + +// We can only use Security.framework to validate TLS certificates on Apple platforms. +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Dispatch +import Foundation +import Security + +extension SSLConnection { + func performSecurityFrameworkValidation(promise: EventLoopPromise, peerCertificates: [SecCertificate]) { + do { + guard case .default = self.parentContext.configuration.trustRoots ?? .default else { + preconditionFailure("This callback should only be used if we are using the system-default trust.") + } + + // This force-unwrap is safe as we must have decided if we're a client or a server before validation. + var trust: SecTrust? = nil + var result: OSStatus + let policy = SecPolicyCreateSSL(self.role! == .client, self.expectedHostname as CFString?) + result = SecTrustCreateWithCertificates(peerCertificates as CFArray, policy, &trust) + guard result == errSecSuccess, let actualTrust = trust else { + throw NIOSSLError.unableToValidateCertificate + } + + // If there are additional trust roots then we need to add them to the SecTrust as anchors. + let additionalAnchorCertificates: [SecCertificate] = try self.parentContext.configuration.additionalTrustRoots.flatMap { trustRoots -> [NIOSSLCertificate] in + guard case .certificates(let certs) = trustRoots else { + preconditionFailure("This callback happens on the request path, file-based additional trust roots should be pre-loaded when creating the SSLContext.") + } + return certs + }.map { + guard let secCert = SecCertificateCreateWithData(nil, Data(try $0.toDERBytes()) as CFData) else { + throw NIOSSLError.failedToLoadCertificate + } + return secCert + } + if !additionalAnchorCertificates.isEmpty { + guard SecTrustSetAnchorCertificates(actualTrust, additionalAnchorCertificates as CFArray) == errSecSuccess else { + throw NIOSSLError.failedToLoadCertificate + } + // To use additional anchors _and_ the built-in ones we must reenable the built-in ones expicitly. + guard SecTrustSetAnchorCertificatesOnly(actualTrust, false) == errSecSuccess else { + throw NIOSSLError.failedToLoadCertificate + } + } + + // We create a DispatchQueue here to be called back on, as this validation may perform network activity. + let callbackQueue = DispatchQueue(label: "io.swiftnio.ssl.validationCallbackQueue") + + // SecTrustEvaluateAsync and its cousin withError require that they are called from the same queue given to + // them as a parameter. Thus, we async away now. + callbackQueue.async { + let result: OSStatus + + if #available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *) { + result = SecTrustEvaluateAsyncWithError(actualTrust, callbackQueue) { (_, valid, _) in + promise.succeed(valid ? .certificateVerified : .failed) + } + } else { + result = SecTrustEvaluateAsync(actualTrust, callbackQueue) { (_, result) in + promise.completeWith(result) + } + } + + if result != errSecSuccess { + promise.fail(NIOSSLError.unableToValidateCertificate) + } + } + } catch { + promise.fail(error) + } + } +} + +extension EventLoopPromise where Value == NIOSSLVerificationResult { + fileprivate func completeWith(_ result: SecTrustResultType) { + switch result { + case .proceed, .unspecified: + // These two cases mean we have successfully validated the certificate. We're done! + self.succeed(.certificateVerified) + default: + // Oops, we failed. + self.succeed(.failed) + } + } +} + +extension SSLConnection { + func getPeerCertificatesAsSecCertificate() throws -> [SecCertificate] { + try self.withPeerCertificateChainBuffers { buffers in + guard let buffers = buffers else { + throw NIOSSLError.unableToValidateCertificate + } + + return try buffers.map { buffer in + let data = Data(bytes: buffer.baseAddress!, count: buffer.count) + guard let cert = SecCertificateCreateWithData(nil, data as CFData) else { + throw NIOSSLError.unableToValidateCertificate + } + return cert + } + } + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/String+unsafeUninitializedCapacity.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/String+unsafeUninitializedCapacity.swift new file mode 100644 index 00000000..6e3cfae0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/String+unsafeUninitializedCapacity.swift @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +extension String { + /// This is a backport of `String.init(unsafeUninitializedCapacity:initializingUTF8With:)` + /// that allows writing directly into an uninitialized String's backing memory. + /// + /// As this API does not exist on older Apple platforms, we fake it out with a pointer and accept the extra copy. + init( + customUnsafeUninitializedCapacity capacity: Int, + initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int + ) rethrows { + if #available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) { + try self.init(unsafeUninitializedCapacity: capacity, initializingUTF8With: initializer) + } else { + try self.init(backportUnsafeUninitializedCapacity: capacity, initializingUTF8With: initializer) + } + } + + private init( + backportUnsafeUninitializedCapacity capacity: Int, + initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int + ) rethrows { + let buffer = UnsafeMutableBufferPointer.allocate(capacity: capacity) + defer { + buffer.deallocate() + } + + + let initializedCount = try initializer(buffer) + precondition(initializedCount <= capacity, "Overran buffer in initializer!") + + self = String(decoding: UnsafeMutableBufferPointer(start: buffer.baseAddress!, count: initializedCount), as: UTF8.self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SubjectAlternativeName.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SubjectAlternativeName.swift new file mode 100644 index 00000000..254ca9de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/SubjectAlternativeName.swift @@ -0,0 +1,204 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL +@_implementationOnly import CNIOBoringSSLShims + +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#else +#error("unsupported os") +#endif + +/// Collection of all Subject Alternative Names from a `NIOSSLCertificate` +public struct _SubjectAlternativeNames { + + @usableFromInline + internal final class Storage { + + fileprivate let nameStack: OpaquePointer + @usableFromInline internal let stackSize: Int + + internal init(nameStack: OpaquePointer) { + self.nameStack = nameStack + self.stackSize = CNIOBoringSSLShims_sk_GENERAL_NAME_num(nameStack) + } + + public subscript(position: Int) -> Element { + guard let name = CNIOBoringSSLShims_sk_GENERAL_NAME_value(self.nameStack, position) else { + fatalError("Unexpected null pointer when unwrapping SAN value") + } + + let contents = UnsafeBufferPointer( + start: CNIOBoringSSL_ASN1_STRING_get0_data(name.pointee.d.ia5), + count: Int(CNIOBoringSSL_ASN1_STRING_length(name.pointee.d.ia5)) + ) + return .init(nameType: .init(name.pointee.type), contents: .init(collection: self, buffer: contents)) + } + + deinit { + CNIOBoringSSL_GENERAL_NAMES_free(self.nameStack) + } + } + + + @usableFromInline internal var storage: Storage + + internal init(nameStack: OpaquePointer) { + self.storage = .init(nameStack: nameStack) + } +} + +extension _SubjectAlternativeNames: RandomAccessCollection { + + @inlinable public subscript(position: Int) -> _SubjectAlternativeName { + precondition(self.indices.contains(position), "index \(position) out of bounds") + return self.storage[position] + } + + @inlinable public var startIndex: Int { 0 } + @inlinable public var endIndex: Int { self.storage.stackSize } +} + +public struct _SubjectAlternativeName { + + public struct NameType: Hashable { + public var rawValue: Int + + public init(_ rawCode: Int) { + self.rawValue = rawCode + } + + fileprivate init(_ rawCode: Int32) { + self.init(Int(rawCode)) + } + + public static let email = Self(GEN_EMAIL) + public static let dnsName = Self(GEN_DNS) + public static let ipAddress = Self(GEN_IPADD) + public static let uri = Self(GEN_URI) + } + + public struct Contents { + // only part of this type to keep a strong reference to the underlying storage of `buffer` + private let collection: _SubjectAlternativeNames.Storage + // lifetime automatically managed by `collection` + @usableFromInline internal let buffer: UnsafeBufferPointer + + internal init(collection: _SubjectAlternativeNames.Storage, buffer: UnsafeBufferPointer) { + self.collection = collection + self.buffer = buffer + } + + @inlinable public func withUnsafeBufferPointer( + _ body: (UnsafeBufferPointer) throws -> Result + ) rethrows -> Result { + try body(self.buffer) + } + } + + // should be replaced by `swift-nio`s `IPAddress` once https://github.com/apple/swift-nio/issues/1650 is resolved + internal enum IPAddress { + case ipv4(in_addr) + case ipv6(in6_addr) + } + + public var nameType: NameType + public var contents: Contents +} + +extension _SubjectAlternativeName.Contents: RandomAccessCollection { + + @inlinable public var startIndex: Int { self.buffer.startIndex } + @inlinable public var endIndex: Int { self.buffer.endIndex } + + @inlinable public subscript(position: Int) -> UInt8 { + precondition(self.indices.contains(position), "index \(position) out of bounds") + return self.buffer[position] + } +} + +extension _SubjectAlternativeName.IPAddress { + + internal init?(_ subjectAlternativeName: _SubjectAlternativeName) { + guard subjectAlternativeName.nameType == .ipAddress else { + return nil + } + switch subjectAlternativeName.contents.count { + case 4: + let addr = subjectAlternativeName.contents.withUnsafeBufferPointer { + $0.baseAddress.map { + UnsafeRawPointer($0).load(as: in_addr.self) + } + } + guard let innerAddr = addr else { + return nil + } + self = .ipv4(innerAddr) + case 16: + let addr = subjectAlternativeName.contents.withUnsafeBufferPointer { + $0.baseAddress.map { + UnsafeRawPointer($0).load(as: in6_addr.self) + } + } + guard let innerAddr = addr else { + return nil + } + self = .ipv6(innerAddr) + default: + return nil + } + } +} + +extension _SubjectAlternativeName.IPAddress: CustomStringConvertible { + + private static let ipv4AddressLength = 16 + private static let ipv6AddressLength = 46 + + /// A string representation of the IP address. + /// E.g. IPv4: `192.168.0.1` + /// E.g. IPv6: `2001:db8::1` + public var description: String { + switch self { + case .ipv4(let addr): + return Self.ipv4ToString(addr) + case .ipv6(let addr): + return Self.ipv6ToString(addr) + } + } + + static private func ipv4ToString(_ address: in_addr) -> String { + + var address = address + var dest: [CChar] = Array(repeating: 0, count: Self.ipv4AddressLength) + dest.withUnsafeMutableBufferPointer { pointer in + let result = inet_ntop(AF_INET, &address, pointer.baseAddress!, socklen_t(pointer.count)) + precondition(result != nil, "The IP address was invalid. This should never happen as we're within the IP address struct.") + } + return String(cString: &dest) + } + + static private func ipv6ToString(_ address: in6_addr) -> String { + var address = address + var dest: [CChar] = Array(repeating: 0, count: Self.ipv6AddressLength) + dest.withUnsafeMutableBufferPointer { pointer in + let result = inet_ntop(AF_INET6, &address, pointer.baseAddress!, socklen_t(pointer.count)) + precondition(result != nil, "The IP address was invalid. This should never happen as we're within the IP address struct.") + } + return String(cString: &dest) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/TLSConfiguration.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/TLSConfiguration.swift new file mode 100644 index 00000000..b7c47c9c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/TLSConfiguration.swift @@ -0,0 +1,805 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_implementationOnly import CNIOBoringSSL +import NIOCore + +/// Known and supported TLS versions. +public enum TLSVersion { + case tlsv1 + case tlsv11 + case tlsv12 + case tlsv13 +} + +/// Places NIOSSL can obtain certificates from. +public enum NIOSSLCertificateSource: Hashable { + @available(*, deprecated, message: "Use 'NIOSSLCertificate.fromPEMFile(_:)' to load the certificate(s) and use the '.certificate(NIOSSLCertificate)' case to provide them as a source") + case file(String) + case certificate(NIOSSLCertificate) +} + +/// Places NIOSSL can obtain private keys from. +public enum NIOSSLPrivateKeySource: Hashable { + case file(String) + case privateKey(NIOSSLPrivateKey) +} + +/// Places NIOSSL can obtain a trust store from. +public enum NIOSSLTrustRoots: Hashable { + /// Path to either a file of CA certificates in PEM format, or a directory containing CA certificates in PEM format. + /// + /// If a path to a file is provided, the file can contain several CA certificates identified by + /// + /// -----BEGIN CERTIFICATE----- + /// ... (CA certificate in base64 encoding) ... + /// -----END CERTIFICATE----- + /// + /// sequences. Before, between, and after the certificates, text is allowed which can be used e.g. + /// for descriptions of the certificates. + /// + /// If a path to a directory is provided, the files each contain one CA certificate in PEM format. + case file(String) + + /// A list of certificates. + case certificates([NIOSSLCertificate]) + + /// The system default root of trust. + case `default` + + internal init(from trustRoots: NIOSSLAdditionalTrustRoots) { + switch trustRoots { + case .file(let path): + self = .file(path) + case .certificates(let certs): + self = .certificates(certs) + } + } +} + +/// Places NIOSSL can obtain additional trust roots from. +public enum NIOSSLAdditionalTrustRoots: Hashable { + /// See `NIOSSLTrustRoots.file` + case file(String) + + /// See `NIOSSLTrustRoots.certificates` + case certificates([NIOSSLCertificate]) +} + +/// Available ciphers to use for TLS instead of a string based representation. +public struct NIOTLSCipher: RawRepresentable, Hashable { + public init(rawValue: UInt16) { + self.rawValue = rawValue + } + + public init(_ rawValue: RawValue) { + self.rawValue = rawValue + } + + public var rawValue: UInt16 + public typealias RawValue = UInt16 + + public static let TLS_RSA_WITH_AES_128_CBC_SHA = NIOTLSCipher(rawValue: 0x2F) + public static let TLS_RSA_WITH_AES_256_CBC_SHA = NIOTLSCipher(rawValue: 0x35) + public static let TLS_RSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher(rawValue: 0x9C) + public static let TLS_RSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher(rawValue: 0x9D) + public static let TLS_AES_128_GCM_SHA256 = NIOTLSCipher(rawValue: 0x1301) + public static let TLS_AES_256_GCM_SHA384 = NIOTLSCipher(rawValue: 0x1302) + public static let TLS_CHACHA20_POLY1305_SHA256 = NIOTLSCipher(rawValue: 0x1303) + public static let TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = NIOTLSCipher(rawValue: 0xC009) + public static let TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = NIOTLSCipher(rawValue: 0xC00A) + public static let TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = NIOTLSCipher(rawValue: 0xC013) + public static let TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = NIOTLSCipher(rawValue: 0xC014) + public static let TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher(rawValue: 0xC02B) + public static let TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher(rawValue: 0xC02C) + public static let TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = NIOTLSCipher(rawValue: 0xC02F) + public static let TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = NIOTLSCipher(rawValue: 0xC030) + public static let TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = NIOTLSCipher(rawValue: 0xCCA8) + public static let TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = NIOTLSCipher(rawValue: 0xCCA9) + + var standardName: String { + let boringSSLCipher = CNIOBoringSSL_SSL_get_cipher_by_value(self.rawValue) + return String(cString: CNIOBoringSSL_SSL_CIPHER_standard_name(boringSSLCipher)) + } +} + +/// Formats NIOSSL supports for serializing keys and certificates. +public enum NIOSSLSerializationFormats { + case pem + case der +} + +/// Certificate verification modes. +public enum CertificateVerification { + /// All certificate verification disabled. + case none + + /// Certificates will be validated against the trust store, but will not + /// be checked to see if they are valid for the given hostname. + case noHostnameVerification + + /// Certificates will be validated against the trust store and checked + /// against the hostname of the service we are contacting. + case fullVerification +} + +/// Support for TLS renegotiation. +/// +/// In general, renegotiation should not be enabled except in circumstances where it is absolutely necessary. +/// Renegotiation is only supported in TLS 1.2 and earlier, and generally does not work very well. NIOSSL will +/// disallow most uses of renegotiation: the only supported use-case is to perform post-connection authentication +/// *as a client*. There is no way to initiate a TLS renegotiation in NIOSSL. +public enum NIORenegotiationSupport { + /// No support for TLS renegotiation. The default and recommended setting. + case none + + /// Allow renegotiation exactly once. If you must use renegotiation, use this setting. + case once + + /// Allow repeated renegotiation. To be avoided. + case always +} + +/// Signature algorithms. The values are defined as in TLS 1.3 +public struct SignatureAlgorithm : RawRepresentable, Hashable { + + public typealias RawValue = UInt16 + public var rawValue: UInt16 + + public init(rawValue: UInt16) { + self.rawValue = rawValue + } + + public static let rsaPkcs1Sha1 = SignatureAlgorithm(rawValue: 0x0201) + public static let rsaPkcs1Sha256 = SignatureAlgorithm(rawValue: 0x0401) + public static let rsaPkcs1Sha384 = SignatureAlgorithm(rawValue: 0x0501) + public static let rsaPkcs1Sha512 = SignatureAlgorithm(rawValue: 0x0601) + public static let ecdsaSha1 = SignatureAlgorithm(rawValue: 0x0203) + public static let ecdsaSecp256R1Sha256 = SignatureAlgorithm(rawValue: 0x0403) + public static let ecdsaSecp384R1Sha384 = SignatureAlgorithm(rawValue: 0x0503) + public static let ecdsaSecp521R1Sha512 = SignatureAlgorithm(rawValue: 0x0603) + public static let rsaPssRsaeSha256 = SignatureAlgorithm(rawValue: 0x0804) + public static let rsaPssRsaeSha384 = SignatureAlgorithm(rawValue: 0x0805) + public static let rsaPssRsaeSha512 = SignatureAlgorithm(rawValue: 0x0806) + public static let ed25519 = SignatureAlgorithm(rawValue: 0x0807) +} + + +/// A secure default configuration of cipher suites for TLS 1.2 and earlier. +/// +/// The goal of this cipher suite string is: +/// - Prefer cipher suites that offer Perfect Forward Secrecy (DHE/ECDHE) +/// - Prefer ECDH(E) to DH(E) for performance. +/// - Prefer any AEAD cipher suite over non-AEAD suites for better performance and security +/// - Prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common +/// - Disable NULL authentication and encryption and any appearance of MD5 +public let defaultCipherSuites = [ + "ECDH+AESGCM", + "ECDH+CHACHA20", + "DH+AESGCM", + "DH+CHACHA20", + "ECDH+AES256", + "DH+AES256", + "ECDH+AES128", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + ].joined(separator: ":") + +/// Encodes a string to the wire format of an ALPN identifier. These MUST be ASCII, and so +/// this routine will crash the program if they aren't, as these are always user-supplied +/// strings. +internal func encodeALPNIdentifier(identifier: String) -> [UInt8] { + var encodedIdentifier = [UInt8]() + encodedIdentifier.append(UInt8(identifier.utf8.count)) + + for codePoint in identifier.unicodeScalars { + encodedIdentifier.append(contentsOf: Unicode.ASCII.encode(codePoint)!) + } + + return encodedIdentifier +} + +/// Decodes a string from the wire format of an ALPN identifier. These MUST be correctly +/// formatted ALPN identifiers, and so this routine will crash the program if they aren't. +internal func decodeALPNIdentifier(identifier: [UInt8]) -> String { + return String(decoding: identifier[1.. Bool { + let isKeyLoggerCallbacksEqual = withUnsafeBytes(of: self.keyLogCallback) { callbackPointer1 in + return withUnsafeBytes(of: comparing.keyLogCallback) { callbackPointer2 in + return callbackPointer1.elementsEqual(callbackPointer2) + } + } + + return self.minimumTLSVersion == comparing.minimumTLSVersion && + self.maximumTLSVersion == comparing.maximumTLSVersion && + self.cipherSuites == comparing.cipherSuites && + self.verifySignatureAlgorithms == comparing.verifySignatureAlgorithms && + self.signingSignatureAlgorithms == comparing.signingSignatureAlgorithms && + self.certificateVerification == comparing.certificateVerification && + self.trustRoots == comparing.trustRoots && + self.additionalTrustRoots == comparing.additionalTrustRoots && + self.certificateChain == comparing.certificateChain && + self.privateKey == comparing.privateKey && + self.encodedApplicationProtocols == comparing.encodedApplicationProtocols && + self.shutdownTimeout == comparing.shutdownTimeout && + isKeyLoggerCallbacksEqual && + self.renegotiationSupport == comparing.renegotiationSupport + } + + /// Returns a best effort hash of this TLS configuration. + /// + /// The "best effort" stems from the fact that we are hashing the pointer bytes of the `keyLogCallback` closure. + /// + /// - warning: You should probably not use this function. This function can return false-negatives, but not false-positives. + public func bestEffortHash(into hasher: inout Hasher) { + hasher.combine(minimumTLSVersion) + hasher.combine(maximumTLSVersion) + hasher.combine(cipherSuites) + hasher.combine(verifySignatureAlgorithms) + hasher.combine(signingSignatureAlgorithms) + hasher.combine(certificateVerification) + hasher.combine(trustRoots) + hasher.combine(additionalTrustRoots) + hasher.combine(certificateChain) + hasher.combine(privateKey) + hasher.combine(encodedApplicationProtocols) + hasher.combine(shutdownTimeout) + withUnsafeBytes(of: keyLogCallback) { closureBits in + hasher.combine(bytes: closureBits) + } + hasher.combine(renegotiationSupport) + } + + /// Creates a TLS configuration for use with client-side contexts. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + /// + /// For customising fields, modify the returned TLSConfiguration object. + public static func makeClientConfiguration() -> TLSConfiguration { + return TLSConfiguration(cipherSuites: defaultCipherSuites, + verifySignatureAlgorithms: nil, + signingSignatureAlgorithms: nil, + minimumTLSVersion: .tlsv1, + maximumTLSVersion: nil, + certificateVerification: .fullVerification, + trustRoots: .default, + certificateChain: [], + privateKey: nil, + applicationProtocols: [], + shutdownTimeout: .seconds(5), + keyLogCallback: nil, + renegotiationSupport: .none, + additionalTrustRoots: [], + sendCANameList: false) + } + + /// Create a TLS configuration for use with server-side contexts. + /// + /// This provides sensible defaults while requiring that you provide any data that is necessary + /// for server-side function. For client use, try `makeClientConfiguration` instead. + /// + /// For customising fields, modify the returned TLSConfiguration object. + public static func makeServerConfiguration( + certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource + ) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: defaultCipherSuites, + verifySignatureAlgorithms: nil, + signingSignatureAlgorithms: nil, + minimumTLSVersion: .tlsv1, + maximumTLSVersion: nil, + certificateVerification: .none, + trustRoots: .default, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: [], + shutdownTimeout: .seconds(5), + keyLogCallback: nil, + renegotiationSupport: .none, + additionalTrustRoots: [], + sendCANameList: false) + } +} + +// MARK: Deprecated constructors. + +extension TLSConfiguration { + /// Create a TLS configuration for use with server-side contexts. This allows setting the `NIOTLSCipher` property specifically. + /// + /// This provides sensible defaults while requiring that you provide any data that is necessary + /// for server-side function. For client use, try `makeClientConfiguration` instead. + @available(*, deprecated, renamed: "makeServerConfiguration(certificateChain:privateKey:)") + public static func forServer(certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + cipherSuites: [NIOTLSCipher], + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .none, + trustRoots: NIOSSLTrustRoots = .default, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + additionalTrustRoots: [NIOSSLAdditionalTrustRoots] = []) -> TLSConfiguration { + return TLSConfiguration(cipherSuiteValues: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: .none, // Servers never support renegotiation: there's no point. + additionalTrustRoots: additionalTrustRoots) + } + + /// Create a TLS configuration for use with server-side contexts. + /// + /// This provides sensible defaults while requiring that you provide any data that is necessary + /// for server-side function. For client use, try `makeClientConfiguration` instead. + @available(*, deprecated, renamed: "makeServerConfiguration(certificateChain:privateKey:)") + public static func forServer(certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + cipherSuites: String = defaultCipherSuites, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .none, + trustRoots: NIOSSLTrustRoots = .default, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: nil, + signingSignatureAlgorithms: nil, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: .none, // Servers never support renegotiation: there's no point. + additionalTrustRoots: []) + } + + /// Create a TLS configuration for use with server-side contexts. + /// + /// This provides sensible defaults while requiring that you provide any data that is necessary + /// for server-side function. For client use, try `makeClientConfiguration` instead. + @available(*, deprecated, renamed: "makeServerConfiguration(certificateChain:privateKey:)") + public static func forServer(certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + cipherSuites: String = defaultCipherSuites, + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .none, + trustRoots: NIOSSLTrustRoots = .default, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: .none, // Servers never support renegotiation: there's no point. + additionalTrustRoots: []) + } + + /// Create a TLS configuration for use with server-side contexts. + /// + /// This provides sensible defaults while requiring that you provide any data that is necessary + /// for server-side function. For client use, try `makeClientConfiguration` instead. + @available(*, deprecated, renamed: "makeServerConfiguration(certificateChain:privateKey:)") + public static func forServer(certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + cipherSuites: String = defaultCipherSuites, + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .none, + trustRoots: NIOSSLTrustRoots = .default, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + additionalTrustRoots: [NIOSSLAdditionalTrustRoots]) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: .none, // Servers never support renegotiation: there's no point. + additionalTrustRoots: additionalTrustRoots) + } + + /// Creates a TLS configuration for use with client-side contexts. This allows setting the `NIOTLSCipher` property specifically. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + @available(*, deprecated, renamed: "makeClientConfiguration()") + public static func forClient(cipherSuites: [NIOTLSCipher], + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .fullVerification, + trustRoots: NIOSSLTrustRoots = .default, + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + renegotiationSupport: NIORenegotiationSupport = .none, + additionalTrustRoots: [NIOSSLAdditionalTrustRoots] = []) -> TLSConfiguration { + return TLSConfiguration(cipherSuiteValues: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: renegotiationSupport, + additionalTrustRoots: additionalTrustRoots) + } + + /// Creates a TLS configuration for use with client-side contexts. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + @available(*, deprecated, renamed: "makeClientConfiguration()") + public static func forClient(cipherSuites: String = defaultCipherSuites, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .fullVerification, + trustRoots: NIOSSLTrustRoots = .default, + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: nil, + signingSignatureAlgorithms: nil, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: .none, // Default value is here for backward-compatibility. + additionalTrustRoots: []) + } + + + /// Creates a TLS configuration for use with client-side contexts. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + @available(*, deprecated, renamed: "makeClientConfiguration()") + public static func forClient(cipherSuites: String = defaultCipherSuites, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .fullVerification, + trustRoots: NIOSSLTrustRoots = .default, + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + renegotiationSupport: NIORenegotiationSupport) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: nil, + signingSignatureAlgorithms: nil, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: renegotiationSupport, + additionalTrustRoots: []) + } + + /// Creates a TLS configuration for use with client-side contexts. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + @available(*, deprecated, renamed: "makeClientConfiguration()") + public static func forClient(cipherSuites: String = defaultCipherSuites, + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .fullVerification, + trustRoots: NIOSSLTrustRoots = .default, + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + renegotiationSupport: NIORenegotiationSupport) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: renegotiationSupport, + additionalTrustRoots: []) + } + + /// Creates a TLS configuration for use with client-side contexts. + /// + /// This provides sensible defaults, and can be used without customisation. For server-side + /// contexts, you should use `makeServerConfiguration` instead. + @available(*, deprecated, renamed: "makeClientConfiguration()") + public static func forClient(cipherSuites: String = defaultCipherSuites, + verifySignatureAlgorithms: [SignatureAlgorithm]? = nil, + signingSignatureAlgorithms: [SignatureAlgorithm]? = nil, + minimumTLSVersion: TLSVersion = .tlsv1, + maximumTLSVersion: TLSVersion? = nil, + certificateVerification: CertificateVerification = .fullVerification, + trustRoots: NIOSSLTrustRoots = .default, + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + applicationProtocols: [String] = [], + shutdownTimeout: TimeAmount = .seconds(5), + keyLogCallback: NIOSSLKeyLogCallback? = nil, + renegotiationSupport: NIORenegotiationSupport = .none, + additionalTrustRoots: [NIOSSLAdditionalTrustRoots]) -> TLSConfiguration { + return TLSConfiguration(cipherSuites: cipherSuites, + verifySignatureAlgorithms: verifySignatureAlgorithms, + signingSignatureAlgorithms: signingSignatureAlgorithms, + minimumTLSVersion: minimumTLSVersion, + maximumTLSVersion: maximumTLSVersion, + certificateVerification: certificateVerification, + trustRoots: trustRoots, + certificateChain: certificateChain, + privateKey: privateKey, + applicationProtocols: applicationProtocols, + shutdownTimeout: shutdownTimeout, + keyLogCallback: keyLogCallback, + renegotiationSupport: renegotiationSupport, + additionalTrustRoots: additionalTrustRoots) + } +} + +extension TLSConfiguration { + /// Provides the resolved signature algorithms for signing, if any. + /// + /// Users can override the signature algorithms in two ways. Firstly, they can provide a + /// value for the `signingSignatureAlgorithms` field in the `TLSConfiguration` structure. + /// This acts as an artificial limiter, preventing certain algorithms from being used even + /// though a key might nominally support them. + /// + /// Secondly, users can provide a custom key. This custom key is only capable of using + /// certain signing algorithms. + /// + /// This property resolves these two into a single unified set by diffing them together. + /// If there is no override (i.e. a native key and no override of the + /// `signingSignatureAlgorithms` field then this returns `nil`. + internal var resolvedSigningSignatureAlgorithms: [SignatureAlgorithm]? { + switch (self.signingSignatureAlgorithms, self.privateKey?.customSigningAlgorithms) { + case (.none, .none): + // No overrides. + return nil + + case (.some(let manualOverrides), .none): + return manualOverrides + + case (.none, .some(let keyRequirements)): + return keyRequirements + + case (.some(let manualOverrides), .some(let keyRequirements)): + // Here we have to filter the set. We assume the two lists are small, and so we + // just use `Array.filter` instead of composing into a Set. Note that the order + // here is _semantic_: we have to filter the manual overrides array becuase + // that order was specified by the user, and we want to honor it. + return manualOverrides.filter { keyRequirements.contains($0) } + } + } +} + +extension NIOSSLPrivateKeySource { + /// The custom signing algorithms required by this private key, if any. + /// + /// Is `nil` when the key is a file-backed key, as this is handled by BoringSSL as a native key. + fileprivate var customSigningAlgorithms: [SignatureAlgorithm]? { + switch self { + case .file: + return nil + case .privateKey(let key): + return key.customSigningAlgorithms + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/UniversalBootstrapSupport.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/UniversalBootstrapSupport.swift new file mode 100644 index 00000000..31810c79 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOSSL/Sources/NIOSSL/UniversalBootstrapSupport.swift @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// A TLS provider to bootstrap TLS-enabled connections with `NIOClientTCPBootstrap`. +/// +/// Example: +/// +/// // TLS setup. +/// let configuration = TLSConfiguration.makeClientConfiguration() +/// let sslContext = try NIOSSLContext(configuration: configuration) +/// +/// // Creating the "universal bootstrap" with the `NIOSSLClientTLSProvider`. +/// let tlsProvider = NIOSSLClientTLSProvider(context: sslContext, serverHostname: "example.com") +/// let bootstrap = NIOClientTCPBootstrap(ClientBootstrap(group: group), tls: tlsProvider) +/// +/// // Bootstrapping a connection using the "universal bootstrapping mechanism" +/// let connection = bootstrap.enableTLS() +/// .connect(to: "example.com") +/// .wait() +public struct NIOSSLClientTLSProvider: NIOClientTLSProvider { + public typealias Bootstrap = Bootstrap + + let context: NIOSSLContext + let serverHostname: String? + let customVerificationCallback: NIOSSLCustomVerificationCallback? + + /// Construct the TLS provider with the necessary configuration. + public init(context: NIOSSLContext, + serverHostname: String?, + customVerificationCallback: NIOSSLCustomVerificationCallback? = nil) throws { + try serverHostname.map { + try $0.validateSNIServerName() + } + self.context = context + self.serverHostname = serverHostname + self.customVerificationCallback = customVerificationCallback + } + + /// Enable TLS on the bootstrap. This is not a function you will typically call as a user, it is called by + /// `NIOClientTCPBootstrap`. + public func enableTLS(_ bootstrap: Bootstrap) -> Bootstrap { + // NIOSSLClientHandler.init only throws because of `malloc` error and invalid SNI hostnames. We want to crash + // on malloc error and we pre-checked the SNI hostname in `init` so that should be impossible here. + return bootstrap.protocolHandlers { + if let customVerificationCallback = self.customVerificationCallback { + return [try! NIOSSLClientHandler(context: self.context, + serverHostname: self.serverHostname, + customVerificationCallback: customVerificationCallback)] + } else { + return [try! NIOSSLClientHandler(context: self.context, + serverHostname: self.serverHostname)] + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/ApplicationProtocolNegotiationHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/ApplicationProtocolNegotiationHandler.swift new file mode 100644 index 00000000..09be5fe6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/ApplicationProtocolNegotiationHandler.swift @@ -0,0 +1,138 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// The result of an ALPN negotiation. +/// +/// In a system expecting an ALPN negotiation to occur, a wide range of +/// possible things can happen. In the best case scenario it is possible for +/// the server and client to agree on a protocol to speak, in which case this +/// will be `.negotiated` with the relevant protocol provided as the associated +/// value. However, if for any reason it was not possible to negotiate a +/// protocol, whether because one peer didn't support ALPN or because there was no +/// protocol overlap, we should `fallback` to a default choice of some kind. +/// +/// Exactly what to do when falling back is the responsibility of a specific +/// implementation. +public enum ALPNResult: Equatable { + /// ALPN negotiation succeeded. The associated value is the ALPN token that + /// was negotiated. + case negotiated(String) + + /// ALPN negotiation either failed, or never took place. The application + /// should fall back to a default protocol choice or close the connection. + case fallback +} + +/// A helper `ChannelInboundHandler` that makes it easy to swap channel pipelines +/// based on the result of an ALPN negotiation. +/// +/// The standard pattern used by applications that want to use ALPN is to select +/// an application protocol based on the result, optionally falling back to some +/// default protocol. To do this in SwiftNIO requires that the channel pipeline be +/// reconfigured based on the result of the ALPN negotiation. This channel handler +/// encapsulates that logic in a generic form that doesn't depend on the specific +/// TLS implementation in use by using `TLSUserEvent` +/// +/// The user of this channel handler provides a single closure that is called with +/// an `ALPNResult` when the ALPN negotiation is complete. Based on that result +/// the user is free to reconfigure the `ChannelPipeline` as required, and should +/// return an `EventLoopFuture` that will complete when the pipeline is reconfigured. +/// +/// Until the `EventLoopFuture` completes, this channel handler will buffer inbound +/// data. When the `EventLoopFuture` completes, the buffered data will be replayed +/// down the channel. Then, finally, this channel handler will automatically remove +/// itself from the channel pipeline, leaving the pipeline in its final +/// configuration. +public final class ApplicationProtocolNegotiationHandler: ChannelInboundHandler, RemovableChannelHandler { + public typealias InboundIn = Any + public typealias InboundOut = Any + + private let completionHandler: (ALPNResult, Channel) -> EventLoopFuture + private var waitingForUser: Bool + private var eventBuffer: [NIOAny] + + /// Create an `ApplicationProtocolNegotiationHandler` with the given completion + /// callback. + /// + /// - Parameter alpnCompleteHandler: The closure that will fire when ALPN + /// negotiation has completed. + public init(alpnCompleteHandler: @escaping (ALPNResult, Channel) -> EventLoopFuture) { + self.completionHandler = alpnCompleteHandler + self.waitingForUser = false + self.eventBuffer = [] + } + + /// Create an `ApplicationProtocolNegotiationHandler` with the given completion + /// callback. + /// + /// - Parameter alpnCompleteHandler: The closure that will fire when ALPN + /// negotiation has completed. + public convenience init(alpnCompleteHandler: @escaping (ALPNResult) -> EventLoopFuture) { + self.init { result, _ in + alpnCompleteHandler(result) + } + } + + public func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + guard let tlsEvent = event as? TLSUserEvent else { + context.fireUserInboundEventTriggered(event) + return + } + + if case .handshakeCompleted(let p) = tlsEvent { + handshakeCompleted(context: context, negotiatedProtocol: p) + } else { + context.fireUserInboundEventTriggered(event) + } + } + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + if waitingForUser { + eventBuffer.append(data) + } else { + context.fireChannelRead(data) + } + } + + private func handshakeCompleted(context: ChannelHandlerContext, negotiatedProtocol: String?) { + waitingForUser = true + + let result: ALPNResult + if let negotiatedProtocol = negotiatedProtocol { + result = .negotiated(negotiatedProtocol) + } else { + result = .fallback + } + + let switchFuture = self.completionHandler(result, context.channel) + switchFuture.whenComplete { (_: Result) in + self.unbuffer(context: context) + context.pipeline.removeHandler(self, promise: nil) + } + } + + private func unbuffer(context: ChannelHandlerContext) { + for datum in eventBuffer { + context.fireChannelRead(datum) + } + let buffer = eventBuffer + eventBuffer = [] + waitingForUser = false + if buffer.count > 0 { + context.fireChannelReadComplete() + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/SNIHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/SNIHandler.swift new file mode 100644 index 00000000..e29cd9f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/SNIHandler.swift @@ -0,0 +1,428 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// The length of the TLS record header in bytes. +private let tlsRecordHeaderLength = 5 + +/// The content type identifier for a TLS handshake record. +private let tlsContentTypeHandshake: UInt8 = 22 + +/// The handshake type identifier for ClientHello records. +private let handshakeTypeClientHello: UInt8 = 1 + +/// The extension type for the SNI extension. +private let sniExtensionType: UInt16 = 0 + +/// The ServerName type for DNS host names. +private let sniHostNameType: UInt8 = 0 + +/// The result of the SNI parsing. If `hostname`, then the enum also +/// contains the hostname received in the SNI extension. If `fallback`, +/// then either we could not parse the SNI extension or it was not there +/// at all. +public enum SNIResult: Equatable { + case fallback + case hostname(String) +} + +private enum InternalSNIErrors: Error { + case invalidLengthInRecord + case invalidRecord + case recordIncomplete +} + +private extension ByteBuffer { + mutating func moveReaderIndexIfPossible(forwardBy distance: Int) throws { + guard self.readableBytes >= distance else { + throw InternalSNIErrors.invalidLengthInRecord + } + self.moveReaderIndex(forwardBy: distance) + } + + mutating func readIntegerIfPossible() throws -> T { + guard let integer: T = self.readInteger() else { + throw InternalSNIErrors.invalidLengthInRecord + } + return integer + } +} + +private extension Sequence where Element == UInt8 { + func decodeStringValidatingASCII() -> String? { + var bytesIterator = self.makeIterator() + var scalars: [Unicode.Scalar] = [] + scalars.reserveCapacity(self.underestimatedCount) + var decoder = Unicode.ASCII.Parser() + decode: while true { + switch decoder.parseScalar(from: &bytesIterator) { + case .valid(let v): + scalars.append(Unicode.Scalar(v[0])) + case .emptyInput: + break decode + case .error: + return nil + } + } + return String(scalars.map(Character.init)) + } +} + +/// A channel handler that can be used to arbitrarily edit a channel +/// pipeline based on the hostname requested in the Server Name Indication +/// portion of the TLS Client Hello. +/// +/// This handler is most commonly used when configuring TLS, to control +/// which certificates are going to be shown to the client. It can also be used +/// to ensure that only the resources required to serve a given virtual host are +/// actually present in the channel pipeline. +/// +/// This handler does not depend on any specific TLS implementation. Instead, it parses +/// the Client Hello itself, directly. This allows it to be generic across all possible +/// TLS backends that can be used with NIO. It also allows for the pipeline change to +/// be done asynchronously, providing more flexibility about how the user configures the +/// pipeline. +public final class SNIHandler: ByteToMessageDecoder { + public var cumulationBuffer: Optional + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + + private let completionHandler: (SNIResult) -> EventLoopFuture + private var waitingForUser: Bool + + public init(sniCompleteHandler: @escaping (SNIResult) -> EventLoopFuture) { + self.cumulationBuffer = nil + self.completionHandler = sniCompleteHandler + self.waitingForUser = false + } + + public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { + context.fireChannelRead(NIOAny(buffer)) + return .needMoreData + } + + // A note to maintainers: this method *never* returns `.continue`. + public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) -> DecodingState { + // If we've asked the user to mutate the pipeline already, we're not interested in + // this data. Keep waiting. + if waitingForUser { + return .needMoreData + } + + let serverName: String? + do { + serverName = try parseTLSDataForServerName(buffer: buffer) + } catch InternalSNIErrors.recordIncomplete { + // Nothing bad here, we just don't have enough data. + return .needMoreData + } catch { + // Some error occurred. Fall back and let the TLS stack + // handle it. + sniComplete(result: .fallback, context: context) + return .needMoreData + } + + if let serverName = serverName { + sniComplete(result: .hostname(serverName), context: context) + } else { + sniComplete(result: .fallback, context: context) + } + return .needMoreData + } + + /// Given a buffer of data that may contain a TLS Client Hello, parses the buffer looking for + /// a server name extension. If it can be found, returns the host name in that extension. If + /// no host name or extension is present, returns nil. If an error is encountered, throws. If + /// there is not enough data in the buffer yet, throws recordIncomplete. + private func parseTLSDataForServerName(buffer: ByteBuffer) throws -> String? { + // We're taking advantage of value semantics here: this copy of the buffer will reference + // the same underlying storage as the one we were passed, but any changes to it will not + // be reflected in the outer buffer. That saves us from needing to maintain offsets + // manually in this code. Thanks, Swift! + var tempBuffer = buffer + + // First, parse the header. + let contentLength = try parseRecordHeader(buffer: &tempBuffer) + guard tempBuffer.readableBytes >= contentLength else { + throw InternalSNIErrors.recordIncomplete + } + + // At this point we know we have enough, at least according to the outer layer. We now want to + // take a slice of our temp buffer so that we can make confident assertions about + // all of the length. This also prevents us messing stuff up. + // + // From this point onwards if we don't have enough data to satisfy a read, this is an error and + // we will fall back to let the upper layers handle it. + tempBuffer = tempBuffer.getSlice(at: tempBuffer.readerIndex, length: Int(contentLength))! // length check above + + // Now parse the handshake header. If the length of the handshake message is not exactly the + // length of this record, something has gone wrong and we should give up. + let handshakeLength = try parseHandshakeHeader(buffer: &tempBuffer) + guard tempBuffer.readableBytes == handshakeLength else { + throw InternalSNIErrors.invalidRecord + } + + // Now parse the client hello header. If the remaining length, which should be entirely extensions, + // is not exactly the length of this record, something has gone wrong and we should give up. + let extensionsLength = try parseClientHelloHeader(buffer: &tempBuffer) + guard tempBuffer.readableBytes == extensionsLength else { + throw InternalSNIErrors.invalidLengthInRecord + } + + return try parseExtensionsForServerName(buffer: &tempBuffer) + } + + /// Parses the TLS Record Header, ensuring that this is a handshake record and that + /// the basics of the data appear to be correct. + /// + /// Returns the content-length of the record. + private func parseRecordHeader(buffer: inout ByteBuffer) throws -> Int { + // First, the obvious check: are there enough bytes for us to parse a complete + // header? Because of this check we can use unsafe integer reads in the rest of + // this function, as we'll only ever read tlsRecordHeaderLength number of bytes + // here. + guard buffer.readableBytes >= tlsRecordHeaderLength else { + throw InternalSNIErrors.recordIncomplete + } + + // Check the content type. + let contentType: UInt8 = buffer.readInteger()! // length check above + guard contentType == tlsContentTypeHandshake else { + // Whatever this is, it's not a handshake message, so something has gone + // wrong. We're going to fall back to the default handler here and let + // that handler try to clean up this mess. + throw InternalSNIErrors.invalidRecord + } + + // Now, check the major version. + let majorVersion: UInt8 = buffer.readInteger()! // length check above + guard majorVersion == 3 else { + // A major version of 3 is the major version used for SSLv3 and all subsequent versions + // of the protocol. If that's not what this is, we don't know what's happening here. + // Again, let the default handler make sense of this. + throw InternalSNIErrors.invalidRecord + } + + // Skip the minor version byte, then grab the content length. + buffer.moveReaderIndex(forwardBy: 1) + let contentLength: UInt16 = buffer.readInteger()! // length check above + return Int(contentLength) + } + + /// Parses the header of a TLS Handshake Record. Returns the expected number + /// of bytes in the handshake body, or throws if this is not a ClientHello or + /// has some other problem. + private func parseHandshakeHeader(buffer: inout ByteBuffer) throws -> Int { + // Ok, we're looking at a handshake message. That looks like this: + // (see https://tools.ietf.org/html/rfc5246#section-7.4). + // + // struct { + // HandshakeType msg_type; /* handshake type */ + // uint24 length; /* bytes in message */ + // select (HandshakeType) { + // case hello_request: HelloRequest; + // case client_hello: ClientHello; + // case server_hello: ServerHello; + // case certificate: Certificate; + // case server_key_exchange: ServerKeyExchange; + // case certificate_request: CertificateRequest; + // case server_hello_done: ServerHelloDone; + // case certificate_verify: CertificateVerify; + // case client_key_exchange: ClientKeyExchange; + // case finished: Finished; + // } body; + // } Handshake; + // + // For the sake of our own happiness, we should check the handshake type and + // validate its length. uint24 is a stupid type, so we have to play some + // games here to get this to work. If we check that we have 4 bytes up-front + // we can use unsafe reads: fewer than 4 bytes makes this message bogus. + guard buffer.readableBytes >= 4 else { + throw InternalSNIErrors.invalidRecord + } + + let handshakeTypeAndLength: UInt32 = buffer.readInteger()! + let handshakeType: UInt8 = UInt8((handshakeTypeAndLength & 0xFF000000) >> 24) + let handshakeLength: UInt32 = handshakeTypeAndLength & 0x00FFFFFF + guard handshakeType == handshakeTypeClientHello else { + throw InternalSNIErrors.invalidRecord + } + + return Int(handshakeLength) + } + + /// Parses the header of the Client Hello record, and returns the total number of bytes + /// used for extensions, or throws if the header is invalid or corrupted in some way. + private func parseClientHelloHeader(buffer: inout ByteBuffer) throws -> Int { + // Ok dear reader, you've made it this far, now you get to see the true face of the + // ClientHello record. For context, this comes from + // https://tools.ietf.org/html/rfc5246#section-7.4.1.2 + // + // struct { + // ProtocolVersion client_version; + // Random random; + // SessionID session_id; + // CipherSuite cipher_suites<2..2^16-2>; + // CompressionMethod compression_methods<1..2^8-1>; + // select (extensions_present) { + // case false: + // struct {}; + // case true: + // Extension extensions<0..2^16-1>; + // }; + // } ClientHello; + // + // We want to go straight down to the extensions, but we can't do that because + // the SessionID, CipherSuite and CompressionMethod fields are variable length. + // So we skip to them, and then parse. The ProtocolVersion field is two bytes: + // the Random field is a 32-bit integer timestamp followed by a 28-byte array, + // totalling 32 bytes. All-in-all we want to skip forward 34 bytes. + // Unlike in other parsing methods we don't do an explicit length check here + // because we don't know how long these fields are supposed to be: all we do know + // is that the size of the ByteBuffer provides an upper bound on the size of this + // header, so we use safe reads which will throw if the buffer is too short. + try buffer.moveReaderIndexIfPossible(forwardBy: 34) + + let sessionIDLength: UInt8 = try buffer.readIntegerIfPossible() + try buffer.moveReaderIndexIfPossible(forwardBy: Int(sessionIDLength)) + + let cipherSuitesLength: UInt16 = try buffer.readIntegerIfPossible() + try buffer.moveReaderIndexIfPossible(forwardBy: Int(cipherSuitesLength)) + + let compressionMethodLength: UInt8 = try buffer.readIntegerIfPossible() + try buffer.moveReaderIndexIfPossible(forwardBy: Int(compressionMethodLength)) + + // Ok, we're at the extensions! Return the length. + let extensionsLength: UInt16 = try buffer.readIntegerIfPossible() + return Int(extensionsLength) + } + + /// Parses the extensions portion of a Client Hello looking for a ServerName extension. + /// Returns the host name in the ServerName extension, if any. If there is invalid data, + /// throws. If no host name can be found, either due to the ServerName extension not containing + /// one or due to no such extension being present, returns nil. + private func parseExtensionsForServerName(buffer: inout ByteBuffer) throws -> String? { + // The minimum number of bytes in an extension is 4: if we have fewer than that + // we're done. + while buffer.readableBytes >= 4 { + let extensionType: UInt16 = try buffer.readIntegerIfPossible() + let extensionLength: UInt16 = try buffer.readIntegerIfPossible() + + guard buffer.readableBytes >= extensionLength else { + throw InternalSNIErrors.invalidLengthInRecord + } + + guard extensionType == sniExtensionType else { + // Move forward by the length of this extension. + try buffer.moveReaderIndexIfPossible(forwardBy: Int(extensionLength)) + continue + } + + // We've found the server name extension. It's possible a malicious client could attempt a confused + // deputy attack by giving us contradictory lengths, so we again want to trim the bytebuffer down + // so that we never read past the advertised length of this extension. + buffer = buffer.getSlice(at: buffer.readerIndex, length: Int(extensionLength))! + return try parseServerNameExtension(buffer: &buffer) + } + return nil + } + + /// Parses a ServerName extension and returns the host name contained within, if any. If the extension + /// is invalid for any reason, this will throw. If the extension does not contain a hostname, returns + /// nil. + private func parseServerNameExtension(buffer: inout ByteBuffer) throws -> String? { + // The format of the SNI extension is here: https://tools.ietf.org/html/rfc6066#page-6 + // + // struct { + // NameType name_type; + // select (name_type) { + // case host_name: HostName; + // } name; + // } ServerName; + // + // enum { + // host_name(0), (255) + // } NameType; + // + // opaque HostName<1..2^16-1>; + // + // struct { + // ServerName server_name_list<1..2^16-1> + // } ServerNameList; + // + // Note, however, that this is pretty academic. The SNI extension forbids multiple entries + // in the ServerNameList that have the same NameType. As only one NameType is defined, we + // could safely assume this list is one entry long. + // + // HOWEVER! It is a bad idea to write code that assumes that an extension point will + // never be used, so let's try to parse this properly. We're going to parse only until we + // find a host_name entry. + // + // This also uses unsafe reads: at this point, if the buffer is short then we're screwed. + let nameBufferLength: UInt16 = try buffer.readIntegerIfPossible() + guard buffer.readableBytes >= nameBufferLength else { + throw InternalSNIErrors.invalidLengthInRecord + } + + // We are never looking for another extension, so this is now all that we care about in the + // world. Slice our way down to just that. + buffer = buffer.getSlice(at: buffer.readerIndex, length: Int(nameBufferLength))! + while buffer.readableBytes > 0 { + let nameType: UInt8 = try buffer.readIntegerIfPossible() + + // From the RFC: + // "For backward compatibility, all future data structures associated with new NameTypes + // MUST begin with a 16-bit length field." + let nameLength: UInt16 = try buffer.readIntegerIfPossible() + guard nameType == sniHostNameType else { + try buffer.moveReaderIndexIfPossible(forwardBy: Int(nameLength)) + continue + } + + let hostname = buffer.withUnsafeReadableBytes { ptr -> String? in + let nameLength = Int(nameLength) + guard nameLength <= ptr.count else { + return nil + } + return UnsafeRawBufferPointer(rebasing: ptr.prefix(nameLength)).decodeStringValidatingASCII() + } + if let hostname = hostname { + return hostname + } else { + throw InternalSNIErrors.invalidRecord + } + } + return nil + } + + /// Called when we either know the hostname being queried, or we know we can't + /// work it out. Either way, we're done now. + /// + /// The processing here is as follows: + /// + /// 1. Call the user back with the result of the SNI lookup. At this point we're going to + /// allow them to tweak the channel pipeline as they see fit. + /// 2. Wait for them to complete. In this time, we will continue to buffer all inbound + /// data. + /// 3. When the user completes, remove ourselves from the pipeline. This will trigger the + /// ByteToMessageDecoder to automatically deliver the buffered bytes to the next handler + /// in the pipeline, which is now responsible for the work. + private func sniComplete(result: SNIResult, context: ChannelHandlerContext) { + waitingForUser = true + completionHandler(result).whenSuccess { + context.pipeline.removeHandler(context: context, promise: nil) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/TLSEvents.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/TLSEvents.swift new file mode 100644 index 00000000..eada82ce --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTLS/Sources/NIOTLS/TLSEvents.swift @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// Common user events sent by all TLS implementations. +public enum TLSUserEvent: Equatable { + /// The TLS handshake has completed. If ALPN or NPN were used, + /// the negotiated protocol is provided as `negotiatedProtocol`. + case handshakeCompleted(negotiatedProtocol: String?) + + /// The TLS connection has been successfully and cleanly shut down. + /// No further application data can be sent or received at this time. + case shutdownCompleted +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/README.md new file mode 100644 index 00000000..bb0d11b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/README.md @@ -0,0 +1,83 @@ +# NIO Transport Services + +Extensions for [SwiftNIO](https://github.com/apple/swift-nio) to support Apple platforms as first-class citizens. + +## About NIO Transport Services + +NIO Transport Services is an extension to SwiftNIO that provides first-class support for Apple platforms by using [Network.framework](https://developer.apple.com/documentation/network) to provide network connectivity, and [Dispatch](https://developer.apple.com/documentation/dispatch) to provide concurrency. NIOTS provides an alternative [EventLoop](https://apple.github.io/swift-nio/docs/current/NIO/Protocols/EventLoop.html), [EventLoopGroup](https://apple.github.io/swift-nio/docs/current/NIO/Protocols/EventLoopGroup.html), and several alternative [Channels](https://apple.github.io/swift-nio/docs/current/NIO/Protocols/Channel.html) and Bootstraps. + +In addition to providing first-class support for Apple platforms, NIO Transport Services takes advantage of the richer API of Network.framework to provide more insight into the behaviour of the network than is normally available to NIO applications. This includes the ability to wait for connectivity until a network route is available, as well as all of the extra proxy and VPN support that is built directly into Network.framework. + +All regular NIO applications should work just fine with NIO Transport Services, simply by changing the event loops and bootstraps in use. + +## Why Transport Services? + +Network.framework is Apple's reference implementation of the [proposed post-sockets API](https://datatracker.ietf.org/wg/taps/charter/) that is currently being worked on by the Transport Services Working Group (taps) of the IETF. To indicate the proposed long-term future of interfaces like Network.framework, we decided to call this module NIOTransportServices. Also, NIONetworkFramework didn't appeal to us much as a name. + +## How to Use? + +NIO Transport Services primarily uses SwiftPM as its build tool, so we recommend using that as well. If you want to depend on NIO Transport Services in your own project, it's as simple as adding a dependencies clause to your Package.swift: + +``` +dependencies: [ + .package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.1.1") +] +``` + +and then adding the NIOTransportServices module to your target dependencies. + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add NIO Transport Services as a dependency to your Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter `https://github.com/apple/swift-nio-transport-services.git` and click Next twice. Finally, make sure `NIOTransportServices` is selected and click finish. Now will be able to `import NIOTransportServices` in your project. + +You can also use SwiftNIO Transport Services in an iOS project through CocoaPods: + + pod 'SwiftNIO', '~> 2.0.0' + pod 'SwiftNIOTransportServices', '~> 1.0.0' + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +``` +swift package generate-xcodeproj +``` + +and add the project as a sub-project by dragging it into your iOS project and adding the framework (`NIOTransportServices.framework`) in 'Build Phases' -> 'Link Binary Libraries'. + +Do note however that Network.framework requires macOS 10.14+, iOS 12+, or tvOS 12+. + +### Supported Platforms + +NIOTransportServices is supported where Network.framework is supported: macOS +10.14+, iOS 12+, tvOS 12+, and watchOS 6+. + +In order to allow dependencies to use NIOTransportServices when it's available +and fallback to NIO when it isn't, all code is behind import guards checking +the availability of Network.framework. As such NIOTransportServices may be +built on platforms where Network.framework is *not* available. +NIOTransportServices can be built on macOS 10.12+, iOS 10+, tvOS 10+, watchOS +6+ and Linux but is only functionally useful on macOS 10.14+, iOS 12+, tvOS 12+ +and watchOS 6+. + +## Versioning + +Just like the rest of the SwiftNIO family, `swift-nio-transport-services` follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document +declaring [SwiftNIO's Public API](https://github.com/apple/swift-nio/blob/main/docs/public-api.md). + +### `swift-nio-transport-services ` 1.x + +`swift-nio-transport-services` versions 1.x is part of the SwiftNIO 2 family of repositories and does not have any dependencies besides [`swift-nio`](https://github.com/apple/swift-nio), Swift 5.4, and an Apple OS supporting `Network.framework`. As the latest version, it lives on the [`main`](https://github.com/apple/swift-nio-transport-services) branch. + +To depend on `swift-nio-transport-services `, put the following in the `dependencies` of your `Package.swift`: + + .package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.0.0"), + +`swift-nio-transport-services` version 1.11.x and earlier support Swift 5.2 and 5.3. Earlier 1.x versions also support Swift 5.0 and 5.1. + +### `swift-nio-transport-services ` 0.x + +The legacy `swift-nio-transport-services` 0.x is part of the SwiftNIO 1 family of repositories and works with Swift 4.1 and newer. The source code can be found on the [`swift-nio-transport-services-swift-4-maintenance`](https://github.com/apple/swift-nio-transport-services/tree/swift-nio-transport-services-swift-4-maintenance) branch. + +## Developing NIO Transport Services + +For the most part, NIO Transport Services development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +Please note that all work on NIO Transport Services is covered by the [SwiftNIO Code of Conduct](https://github.com/apple/swift-nio/blob/main/CODE_OF_CONDUCT.md). + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOFilterEmptyWritesHandler.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOFilterEmptyWritesHandler.swift new file mode 100644 index 00000000..a50ceb16 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOFilterEmptyWritesHandler.swift @@ -0,0 +1,172 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + + +/// A `ChannelHandler` that checks for outbound writes of zero length, which are then dropped. This is +/// due to a bug in `Network Framework`, where zero byte TCP writes lead to stalled connections. +/// Write promises are confirmed in the correct order. +public final class NIOFilterEmptyWritesHandler: ChannelDuplexHandler { + public typealias InboundIn = ByteBuffer + public typealias InboundOut = ByteBuffer + public typealias OutboundIn = ByteBuffer + public typealias OutboundOut = ByteBuffer + + fileprivate enum ChannelState: Equatable { + case notActiveYet + case open + case closedFromLocal + case closedFromRemote + case error + } + + private var state: ChannelState = .notActiveYet + private var prefixEmptyWritePromise: Optional> + private var lastWritePromise: Optional> + + public init() { + self.prefixEmptyWritePromise = nil + self.lastWritePromise = nil + } + + public func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + switch self.state { + case .open: + let buffer = self.unwrapOutboundIn(data) + if buffer.readableBytes > 0 { + self.lastWritePromise = promise ?? context.eventLoop.makePromise() + context.write(data, promise: self.lastWritePromise) + } else { + /* + Empty writes need to be handled individually depending on: + A) Empty write occurring before any non-empty write needs a + separate promise to cascade from (prefix) + B) Non-empty writes carry a promise, that subsequent empty + writes can cascade from + */ + switch (self.prefixEmptyWritePromise, self.lastWritePromise, promise) { + case (_, _, .none): () + case (.none, .none, .some(let promise)): + self.prefixEmptyWritePromise = promise + case (_, .some(let lastWritePromise), .some(let promise)): + lastWritePromise.futureResult.cascade(to: promise) + case (.some(let prefixEmptyWritePromise), .none, .some(let promise)): + prefixEmptyWritePromise.futureResult.cascade(to: promise) + } + } + case .closedFromLocal, .closedFromRemote, .error: + // Since channel is closed, Network Framework bug is not triggered for empty writes + context.write(data, promise: promise) + case .notActiveYet: + preconditionFailure() + } + } + + public func flush(context: ChannelHandlerContext) { + self.lastWritePromise = nil + if let prefixEmptyWritePromise = self.prefixEmptyWritePromise { + self.prefixEmptyWritePromise = nil + prefixEmptyWritePromise.succeed(()) + } + + context.flush() + } +} + +// Connection state management +extension NIOFilterEmptyWritesHandler { + public func channelActive(context: ChannelHandlerContext) { + switch self.state { + case .notActiveYet: + self.state = .open + context.fireChannelActive() + case .closedFromLocal: + // Closed before we activated, not a problem. + assert(self.prefixEmptyWritePromise == nil) + case .open, .closedFromRemote, .error: + preconditionFailure() + } + } + + public func channelInactive(context: ChannelHandlerContext) { + let save = self.prefixEmptyWritePromise + self.prefixEmptyWritePromise = nil + self.lastWritePromise = nil + + switch self.state { + case .open: + self.state = .closedFromRemote + save?.fail(ChannelError.eof) + case .closedFromLocal, .closedFromRemote, .error: + assert(save == nil) + case .notActiveYet: + preconditionFailure() + } + context.fireChannelInactive() + } + + public func close(context: ChannelHandlerContext, mode: CloseMode, promise: EventLoopPromise?) { + let save = self.prefixEmptyWritePromise + self.prefixEmptyWritePromise = nil + self.lastWritePromise = nil + + switch (mode, self.state) { + case (.all, .open), + (.output, .open), + + // We allow closure in .notActiveYet because it is possible to close before the channelActive fires. + (.all, .notActiveYet), + (.output, .notActiveYet): + self.state = .closedFromLocal + save?.fail(ChannelError.outputClosed) + case (.all, .closedFromLocal), + (.output, .closedFromLocal), + (.all, .closedFromRemote), + (.output, .closedFromRemote), + (.all, .error), + (.output, .error): + assert(save == nil) + case (.input, _): + save?.fail(ChannelError.operationUnsupported) + } + + context.close(mode: mode, promise: promise) + } + + public func errorCaught(context: ChannelHandlerContext, error: Error) { + let save = self.prefixEmptyWritePromise + self.prefixEmptyWritePromise = nil + self.lastWritePromise = nil + + switch self.state { + case .open: + self.state = .error + save?.fail(error) + case .closedFromLocal, .closedFromRemote, .error: + assert(save == nil) + case .notActiveYet: + preconditionFailure() + } + + context.fireErrorCaught(error) + } + + public func handlerAdded(context: ChannelHandlerContext) { + assert(self.state == .notActiveYet) + if context.channel.isActive { + self.state = .open + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSBootstraps.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSBootstraps.swift new file mode 100644 index 00000000..4dfc210f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSBootstraps.swift @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import NIOCore + +/// Shared functionality across NIOTS bootstraps. +internal enum NIOTSBootstraps { + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + internal static func isCompatible(group: EventLoopGroup) -> Bool { + return group is NIOTSEventLoop || group is NIOTSEventLoopGroup + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSChannelOptions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSChannelOptions.swift new file mode 100644 index 00000000..88ad0148 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSChannelOptions.swift @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if canImport(Network) +import NIOCore +import Network + +/// Options that can be set explicitly and only on bootstraps provided by `NIOTransportServices`. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public struct NIOTSChannelOptions { + /// - seealso: `NIOTSWaitForActivityOption`. + public static let waitForActivity = NIOTSChannelOptions.Types.NIOTSWaitForActivityOption() + + public static let enablePeerToPeer = NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption() + + /// - See: NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse + public static let allowLocalEndpointReuse = NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse() + + public static let currentPath = NIOTSChannelOptions.Types.NIOTSCurrentPathOption() + + public static let metadata = { (definition: NWProtocolDefinition) -> NIOTSChannelOptions.Types.NIOTSMetadataOption in + .init(definition: definition) + } + + @available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + public static let establishmentReport = NIOTSChannelOptions.Types.NIOTSEstablishmentReportOption() + + @available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + public static let dataTransferReport = NIOTSChannelOptions.Types.NIOTSDataTransferReportOption() +} + + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSChannelOptions { + public enum Types { + /// `NIOTSWaitForActivityOption` controls whether the `Channel` should wait for connection changes + /// during the connection process if the connection attempt fails. If Network.framework believes that + /// a connection may succeed in future, it may transition into the `.waiting` state. By default, this option + /// is set to `true` and NIO allows this state transition, though it does count time in that state against + /// the timeout. If this option is set to `false`, transitioning into this state will be treated the same as + /// transitioning into the `failed` state, causing immediate connection failure. + /// + /// This option is only valid with `NIOTSConnectionBootstrap`. + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public struct NIOTSWaitForActivityOption: ChannelOption, Equatable { + public typealias Value = Bool + + public init() {} + } + + /// `NIOTSEnablePeerToPeerOption` controls whether the `Channel` will advertise services using peer-to-peer + /// connectivity. Setting this to true is the equivalent of setting `NWParameters.enablePeerToPeer` to + /// `true`. By default this option is set to `false`. + /// + /// This option must be set on the bootstrap: setting it after the channel is initialized will have no effect. + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public struct NIOTSEnablePeerToPeerOption: ChannelOption, Equatable { + public typealias Value = Bool + + public init() {} + } + + /// `NIOTSAllowLocalEndpointReuse` controls whether the `Channel` can reuse a TCP address recently used. + /// Setting this to true is the equivalent of setting at least one of REUSEADDR and REUSEPORT to + /// `true`. By default this option is set to `false`. + /// + /// This option must be set on the bootstrap: setting it after the channel is initialized will have no effect. + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public struct NIOTSAllowLocalEndpointReuse: ChannelOption, Equatable { + public typealias Value = Bool + + public init() {} + } + + /// `NIOTSCurrentPathOption` accesses the `NWConnection.currentPath` of the underlying connection. + /// + /// This option is only valid with `NIOTSConnectionBootstrap`. + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public struct NIOTSCurrentPathOption: ChannelOption, Equatable { + public typealias Value = NWPath + + public init() {} + } + + /// `NIOTSMetadataOption` accesses the metadata for a given `NWProtocol`. + /// + /// This option is only valid with `NIOTSConnectionBootstrap`. + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public struct NIOTSMetadataOption: ChannelOption, Equatable { + public typealias Value = NWProtocolMetadata + + let definition: NWProtocolDefinition + + public init(definition: NWProtocolDefinition) { + self.definition = definition + } + } + + /// `NIOTSEstablishmentReportOption` accesses the `NWConnection.EstablishmentReport` of the underlying connection. + /// + /// This option is only valid with `NIOTSConnectionBootstrap`. + @available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + public struct NIOTSEstablishmentReportOption: ChannelOption, Equatable { + public typealias Value = EventLoopFuture + + public init() {} + } + + /// `NIOTSDataTransferReportOption` accesses the `NWConnection.DataTransferReport` of the underlying connection. + /// + /// This option is only valid with `NIOTSConnectionBootstrap`. + @available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + public struct NIOTSDataTransferReportOption: ChannelOption, Equatable { + public typealias Value = NWConnection.PendingDataTransferReport + + public init() {} + } + } +} + +/// See: `NIOTSChannelOptions.Types.NIOTSWaitForActivityOption`. +@available(*, deprecated, renamed: "NIOTSChannelOptions.Types.NIOTSWaitForActivityOption") +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public typealias NIOTSWaitForActivityOption = NIOTSChannelOptions.Types.NIOTSWaitForActivityOption + + +/// See: `NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption` +@available(*, deprecated, renamed: "NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption") +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public typealias NIOTSEnablePeerToPeerOption = NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption + + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift new file mode 100644 index 00000000..7170b40c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionBootstrap.swift @@ -0,0 +1,263 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import NIOCore +import Dispatch +import Network + +/// A `NIOTSConnectionBootstrap` is an easy way to bootstrap a `NIOTSConnectionChannel` when creating network clients. +/// +/// Usually you re-use a `NIOTSConnectionBootstrap` once you set it up and called `connect` multiple times on it. +/// This way you ensure that the same `EventLoop`s will be shared across all your connections. +/// +/// Example: +/// +/// ```swift +/// let group = NIOTSEventLoopGroup() +/// defer { +/// try! group.syncShutdownGracefully() +/// } +/// let bootstrap = NIOTSConnectionBootstrap(group: group) +/// .channelInitializer { channel in +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// try! bootstrap.connect(host: "example.org", port: 12345).wait() +/// /* the Channel is now connected */ +/// ``` +/// +/// The connected `NIOTSConnectionChannel` will operate on `ByteBuffer` as inbound and on `IOData` as outbound messages. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public final class NIOTSConnectionBootstrap { + private let group: EventLoopGroup + private var channelInitializer: ((Channel) -> EventLoopFuture)? + private var connectTimeout: TimeAmount = TimeAmount.seconds(10) + private var channelOptions = ChannelOptions.Storage() + private var qos: DispatchQoS? + private var tcpOptions: NWProtocolTCP.Options = .init() + private var tlsOptions: NWProtocolTLS.Options? + private var protocolHandlers: Optional<() -> [ChannelHandler]> = nil + + /// Create a `NIOTSConnectionBootstrap` on the `EventLoopGroup` `group`. + /// + /// The `EventLoopGroup` `group` must be compatible, otherwise the program will crash. `NIOTSConnectionBootstrap` is + /// compatible only with `NIOTSEventLoopGroup` as well as the `EventLoop`s returned by + /// `NIOTSEventLoopGroup.next`. See `init(validatingGroup:)` for a fallible initializer for + /// situations where it's impossible to tell ahead of time if the `EventLoopGroup` is compatible or not. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public convenience init(group: EventLoopGroup) { + guard NIOTSBootstraps.isCompatible(group: group) else { + preconditionFailure("NIOTSConnectionBootstrap is only compatible with NIOTSEventLoopGroup and " + + "NIOTSEventLoop. You tried constructing one with \(group) which is incompatible.") + } + + self.init(validatingGroup: group)! + } + + /// Create a `NIOTSConnectionBootstrap` on the `NIOTSEventLoopGroup` `group`. + /// + /// - parameters: + /// - group: The `NIOTSEventLoopGroup` to use. + public convenience init(group: NIOTSEventLoopGroup) { + self.init(group: group as EventLoopGroup) + } + + /// Create a `NIOTSConnectionBootstrap` on the `NIOTSEventLoopGroup` `group`, validating + /// that the `EventLoopGroup` is compatible with `NIOTSConnectionBootstrap`. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use. + public init?(validatingGroup group: EventLoopGroup) { + guard NIOTSBootstraps.isCompatible(group: group) else { + return nil + } + + self.group = group + self.channelOptions.append(key: ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + } + + /// Initialize the connected `NIOTSConnectionChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The connected `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - parameters: + /// - handler: A closure that initializes the provided `Channel`. + public func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self { + self.channelInitializer = handler + return self + } + + /// Specifies a `ChannelOption` to be applied to the `NIOTSConnectionChannel`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + public func channelOption(_ option: Option, value: Option.Value) -> Self { + channelOptions.append(key: option, value: value) + return self + } + + /// Specifies a timeout to apply to a connection attempt. + // + /// - parameters: + /// - timeout: The timeout that will apply to the connection attempt. + public func connectTimeout(_ timeout: TimeAmount) -> Self { + self.connectTimeout = timeout + return self + } + + /// Specifies a QoS to use for this connection, instead of the default QoS for the + /// event loop. + /// + /// This allows unusually high or low priority workloads to be appropriately scheduled. + public func withQoS(_ qos: DispatchQoS) -> Self { + self.qos = qos + return self + } + + /// Specifies the TCP options to use on the `Channel`s. + /// + /// To retrieve the TCP options from connected channels, use + /// `NIOTSChannelOptions.TCPConfiguration`. It is not possible to change the + /// TCP configuration after `connect` is called. + public func tcpOptions(_ options: NWProtocolTCP.Options) -> Self { + self.tcpOptions = options + return self + } + + /// Specifies the TLS options to use on the `Channel`s. + /// + /// To retrieve the TLS options from connected channels, use + /// `NIOTSChannelOptions.TLSConfiguration`. It is not possible to change the + /// TLS configuration after `connect` is called. + public func tlsOptions(_ options: NWProtocolTLS.Options) -> Self { + self.tlsOptions = options + return self + } + + /// Specify the `host` and `port` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - host: The host to connect to. + /// - port: The port to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(host: String, port: Int) -> EventLoopFuture { + let validPortRange = Int(UInt16.min)...Int(UInt16.max) + guard validPortRange.contains(port) else { + return self.group.next().makeFailedFuture(NIOTSErrors.InvalidPort(port: port)) + } + + guard let actualPort = NWEndpoint.Port(rawValue: UInt16(port)) else { + return self.group.next().makeFailedFuture(NIOTSErrors.InvalidPort(port: port)) + } + return self.connect(endpoint: NWEndpoint.hostPort(host: .init(host), port: actualPort)) + } + + /// Specify the `address` to connect to for the TCP `Channel` that will be established. + /// + /// - parameters: + /// - address: The address to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(to address: SocketAddress) -> EventLoopFuture { + return self.connect { channel, promise in + channel.connect(to: address, promise: promise) + } + } + + /// Specify the `unixDomainSocket` path to connect to for the UDS `Channel` that will be established. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to connect to. + /// - returns: An `EventLoopFuture` to deliver the `Channel` when connected. + public func connect(unixDomainSocketPath: String) -> EventLoopFuture { + do { + let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath) + return connect(to: address) + } catch { + return group.next().makeFailedFuture(error) + } + } + + /// Specify the `endpoint` to connect to for the TCP `Channel` that will be established. + public func connect(endpoint: NWEndpoint) -> EventLoopFuture { + return self.connect { channel, promise in + channel.triggerUserOutboundEvent(NIOTSNetworkEvents.ConnectToNWEndpoint(endpoint: endpoint), + promise: promise) + } + } + + private func connect(_ connectAction: @escaping (Channel, EventLoopPromise) -> Void) -> EventLoopFuture { + let conn: Channel = NIOTSConnectionChannel(eventLoop: self.group.next() as! NIOTSEventLoop, + qos: self.qos, + tcpOptions: self.tcpOptions, + tlsOptions: self.tlsOptions) + let initializer = self.channelInitializer ?? { _ in conn.eventLoop.makeSucceededFuture(()) } + let channelOptions = self.channelOptions + + return conn.eventLoop.flatSubmit { + return channelOptions.applyAllChannelOptions(to: conn).flatMap { + initializer(conn) + }.flatMap { + conn.eventLoop.assertInEventLoop() + return conn.register() + }.flatMap { + let connectPromise: EventLoopPromise = conn.eventLoop.makePromise() + connectAction(conn, connectPromise) + let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) { + connectPromise.fail(ChannelError.connectTimeout(self.connectTimeout)) + conn.close(promise: nil) + } + + connectPromise.futureResult.whenComplete { (_: Result) in + cancelTask.cancel() + } + return connectPromise.futureResult + }.map { conn }.flatMapErrorThrowing { + conn.close(promise: nil) + throw $0 + } + } + } + + /// Sets the protocol handlers that will be added to the front of the `ChannelPipeline` right after the + /// `channelInitializer` has been called. + /// + /// Per bootstrap, you can only set the `protocolHandlers` once. Typically, `protocolHandlers` are used for the TLS + /// implementation. Most notably, `NIOClientTCPBootstrap`, NIO's "universal bootstrap" abstraction, uses + /// `protocolHandlers` to add the required `ChannelHandler`s for many TLS implementations. + public func protocolHandlers(_ handlers: @escaping () -> [ChannelHandler]) -> Self { + precondition(self.protocolHandlers == nil, "protocol handlers can only be set once") + self.protocolHandlers = handlers + return self + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionBootstrap: NIOClientTCPBootstrapProtocol { + /// Apply any understood shorthand options to the bootstrap, removing them from the set of options if they are consumed. + /// - parameters: + /// - options: The options to try applying - the options applied should be consumed from here. + /// - returns: The updated bootstrap with any understood options applied. + public func _applyChannelConvenienceOptions(_ options: inout ChannelOptions.TCPConvenienceOptions) -> Self { + var toReturn = self + if options.consumeAllowLocalEndpointReuse().isSet { + toReturn = self.channelOption(NIOTSChannelOptions.allowLocalEndpointReuse, value: true) + } + return toReturn + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionChannel.swift new file mode 100644 index 00000000..61c91954 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSConnectionChannel.swift @@ -0,0 +1,888 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Foundation +import NIOCore +import NIOConcurrencyHelpers +import NIOFoundationCompat +import NIOTLS +import Dispatch +import Network +import Security + +/// Channel options for the connection channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +private struct ConnectionChannelOptions { + /// Whether autoRead is enabled for this channel. + internal var autoRead: Bool = true + + /// Whether we support remote half closure. If not true, remote half closure will + /// cause connection drops. + internal var supportRemoteHalfClosure: Bool = false + + /// Whether this channel should wait for the connection to become active. + internal var waitForActivity: Bool = true +} + + +private typealias PendingWrite = (data: ByteBuffer, promise: EventLoopPromise?) + + +internal struct AddressCache { + // deliberately lets because they must always be updated together (so forcing `init` is useful). + let local: Optional + let remote: Optional + + init(local: SocketAddress?, remote: SocketAddress?) { + self.local = local + self.remote = remote + } +} + + +/// A structure that manages backpressure signaling on this channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +private struct BackpressureManager { + /// Whether the channel is writable, given the current watermark state. + /// + /// This is an atomic only because the channel writability flag needs to be safe to access from multiple + /// threads. All activity in this structure itself is expected to be thread-safe. + /// + /// All code that operates on this atomic uses load/store, not compareAndSwap. This is because we know + /// that this atomic is only ever written from one thread: the event loop thread. All unsynchronized + /// access is only reading. As a result, we don't have racing writes, and don't need CAS. This is good, + /// because in most cases these loads/stores will be free, as the user will never actually check the + /// channel writability from another thread, meaning this cache line is uncontended. CAS is never free: + /// it always has some substantial runtime cost over loads/stores. + let writable = NIOAtomic.makeAtomic(value: true) + + /// The number of bytes outstanding on the network. + private var outstandingBytes: Int = 0 + + /// The watermarks currently configured by the user. + private(set) var waterMarks = ChannelOptions.Types.WriteBufferWaterMark(low: 32 * 1024, high: 64 * 1024) + + /// Adds `newBytes` to the queue of outstanding bytes, and returns whether this + /// has caused a writability change. + /// + /// - parameters: + /// - newBytes: the number of bytes queued to send, but not yet sent. + /// - returns: Whether the state changed. + mutating func writabilityChanges(whenQueueingBytes newBytes: Int) -> Bool { + self.outstandingBytes += newBytes + if self.outstandingBytes > self.waterMarks.high && self.writable.load() { + self.writable.store(false) + return true + } + + return false + } + + /// Removes `sentBytes` from the queue of outstanding bytes, and returns whether this + /// has caused a writability change. + /// + /// - parameters: + /// - newBytes: the number of bytes sent to the network. + /// - returns: Whether the state changed. + mutating func writabilityChanges(whenBytesSent sentBytes: Int) -> Bool { + self.outstandingBytes -= sentBytes + if self.outstandingBytes < self.waterMarks.low && !self.writable.load() { + self.writable.store(true) + return true + } + + return false + } + + /// Updates the watermarks to `waterMarks`, and returns whether this change has changed the + /// writability state of the channel. + /// + /// - parameters: + /// - waterMarks: The new waterMarks to use. + /// - returns: Whether the state changed. + mutating func writabilityChanges(whenUpdatingWaterMarks waterMarks: ChannelOptions.Types.WriteBufferWaterMark) -> Bool { + let writable = self.writable.load() + self.waterMarks = waterMarks + + if writable && self.outstandingBytes > self.waterMarks.high { + self.writable.store(false) + return true + } else if !writable && self.outstandingBytes < self.waterMarks.low { + self.writable.store(true) + return true + } + + return false + } +} + + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal final class NIOTSConnectionChannel { + /// The `ByteBufferAllocator` for this `Channel`. + public let allocator = ByteBufferAllocator() + + /// An `EventLoopFuture` that will complete when this channel is finally closed. + public var closeFuture: EventLoopFuture { + return self.closePromise.futureResult + } + + /// The parent `Channel` for this one, if any. + public let parent: Channel? + + /// The `EventLoop` this `Channel` belongs to. + internal let tsEventLoop: NIOTSEventLoop + + private var _pipeline: ChannelPipeline! = nil // this is really a constant (set in .init) but needs `self` to be constructed and therefore a `var`. Do not change as this needs to accessed from arbitrary threads. + + internal let closePromise: EventLoopPromise + + /// The underlying `NWConnection` that this `Channel` wraps. This is only non-nil + /// after the initial connection attempt has been made. + private var nwConnection: NWConnection? + + /// The `DispatchQueue` that socket events for this connection will be dispatched onto. + private let connectionQueue: DispatchQueue + + /// An `EventLoopPromise` that will be succeeded or failed when a connection attempt succeeds or fails. + private var connectPromise: EventLoopPromise? + + /// The TCP options for this connection. + private var tcpOptions: NWProtocolTCP.Options + + /// The TLS options for this connection, if any. + private var tlsOptions: NWProtocolTLS.Options? + + /// The state of this connection channel. + internal var state: ChannelState = .idle + + /// The active state, used for safely reporting the channel state across threads. + internal var isActive0: NIOAtomic = .makeAtomic(value: false) + + /// The kinds of channel activation this channel supports + internal let supportedActivationType: ActivationType = .connect + + /// Whether a call to NWConnection.receive has been made, but the completion + /// handler has not yet been invoked. + private var outstandingRead: Bool = false + + /// The options for this channel. + private var options: ConnectionChannelOptions = ConnectionChannelOptions() + + /// Any pending writes that have yet to be delivered to the network stack. + private var pendingWrites = CircularBuffer(initialCapacity: 8) + + /// An object to keep track of pending writes and manage our backpressure signaling. + private var backpressureManager = BackpressureManager() + + /// The value of SO_REUSEADDR. + private var reuseAddress = false + + /// The value of SO_REUSEPORT. + private var reusePort = false + + /// The value of the allowLocalEndpointReuse option. + private var allowLocalEndpointReuse = false + + /// Whether to use peer-to-peer connectivity when connecting to Bonjour services. + private var enablePeerToPeer = false + + /// The cache of the local and remote socket addresses. Must be accessed using _addressCacheLock. + private var _addressCache = AddressCache(local: nil, remote: nil) + + /// A lock that guards the _addressCache. + private let _addressCacheLock = Lock() + + /// Create a `NIOTSConnectionChannel` on a given `NIOTSEventLoop`. + /// + /// Note that `NIOTSConnectionChannel` objects cannot be created on arbitrary loops types. + internal init(eventLoop: NIOTSEventLoop, + parent: Channel? = nil, + qos: DispatchQoS? = nil, + tcpOptions: NWProtocolTCP.Options, + tlsOptions: NWProtocolTLS.Options?) { + self.tsEventLoop = eventLoop + self.closePromise = eventLoop.makePromise() + self.parent = parent + self.connectionQueue = eventLoop.channelQueue(label: "nio.nioTransportServices.connectionchannel", qos: qos) + self.tcpOptions = tcpOptions + self.tlsOptions = tlsOptions + + // Must come last, as it requires self to be completely initialized. + self._pipeline = ChannelPipeline(channel: self) + } + + /// Create a `NIOTSConnectionChannel` with an already-established `NWConnection`. + internal convenience init(wrapping connection: NWConnection, + on eventLoop: NIOTSEventLoop, + parent: Channel, + qos: DispatchQoS? = nil, + tcpOptions: NWProtocolTCP.Options, + tlsOptions: NWProtocolTLS.Options?) { + self.init(eventLoop: eventLoop, + parent: parent, + qos: qos, + tcpOptions: tcpOptions, + tlsOptions: tlsOptions) + self.nwConnection = connection + } +} + + +// MARK:- NIOTSConnectionChannel implementation of Channel +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionChannel: Channel { + /// The `ChannelPipeline` for this `Channel`. + public var pipeline: ChannelPipeline { + return self._pipeline + } + + /// The local address for this channel. + public var localAddress: SocketAddress? { + return self._addressCacheLock.withLock { + return self._addressCache.local + } + } + + /// The remote address for this channel. + public var remoteAddress: SocketAddress? { + return self._addressCacheLock.withLock { + return self._addressCache.remote + } + } + + /// Whether this channel is currently writable. + public var isWritable: Bool { + return self.backpressureManager.writable.load() + } + + public var _channelCore: ChannelCore { + return self + } + + public func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + if self.eventLoop.inEventLoop { + return self.eventLoop.makeCompletedFuture(Result { try setOption0(option: option, value: value) }) + } else { + return self.eventLoop.submit { try self.setOption0(option: option, value: value) } + } + } + + private func setOption0(option: Option, value: Option.Value) throws { + self.eventLoop.preconditionInEventLoop() + + guard !self.closed else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.AutoReadOption: + self.options.autoRead = value as! Bool + self.readIfNeeded0() + case _ as ChannelOptions.Types.AllowRemoteHalfClosureOption: + self.options.supportRemoteHalfClosure = value as! Bool + case _ as ChannelOptions.Types.SocketOption: + let optionValue = option as! ChannelOptions.Types.SocketOption + + // SO_REUSEADDR and SO_REUSEPORT are handled here. + switch (optionValue.level, optionValue.name) { + case (SOL_SOCKET, SO_REUSEADDR): + self.reuseAddress = (value as! SocketOptionValue) != Int32(0) + case (SOL_SOCKET, SO_REUSEPORT): + self.reusePort = (value as! SocketOptionValue) != Int32(0) + default: + try self.tcpOptions.applyChannelOption(option: optionValue, value: value as! SocketOptionValue) + } + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + if self.backpressureManager.writabilityChanges(whenUpdatingWaterMarks: value as! ChannelOptions.Types.WriteBufferWaterMark) { + self.pipeline.fireChannelWritabilityChanged() + } + case _ as NIOTSChannelOptions.Types.NIOTSWaitForActivityOption: + let newValue = value as! Bool + self.options.waitForActivity = newValue + + if let state = self.nwConnection?.state, case .waiting(let err) = state { + // We're in waiting now, so we should drop the connection. + self.close0(error: err, mode: .all, promise: nil) + } + case is NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption: + self.enablePeerToPeer = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value + case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse: + self.allowLocalEndpointReuse = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value + default: + fatalError("option \(type(of: option)).\(option) not supported") + } + } + + public func getOption(_ option: Option) -> EventLoopFuture { + if self.eventLoop.inEventLoop { + return self.eventLoop.makeCompletedFuture(Result { try getOption0(option: option) }) + } else { + return eventLoop.submit { try self.getOption0(option: option) } + } + } + + func getOption0(option: Option) throws -> Option.Value { + self.eventLoop.preconditionInEventLoop() + + guard !self.closed else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case _ as ChannelOptions.Types.AutoReadOption: + return self.options.autoRead as! Option.Value + case _ as ChannelOptions.Types.AllowRemoteHalfClosureOption: + return self.options.supportRemoteHalfClosure as! Option.Value + case _ as ChannelOptions.Types.SocketOption: + let optionValue = option as! ChannelOptions.Types.SocketOption + + // SO_REUSEADDR and SO_REUSEPORT are handled here. + switch (optionValue.level, optionValue.name) { + case (SOL_SOCKET, SO_REUSEADDR): + return Int32(self.reuseAddress ? 1 : 0) as! Option.Value + case (SOL_SOCKET, SO_REUSEPORT): + return Int32(self.reusePort ? 1 : 0) as! Option.Value + default: + return try self.tcpOptions.valueFor(socketOption: optionValue) as! Option.Value + } + case _ as ChannelOptions.Types.WriteBufferWaterMarkOption: + return self.backpressureManager.waterMarks as! Option.Value + case _ as NIOTSChannelOptions.Types.NIOTSWaitForActivityOption: + return self.options.waitForActivity as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption: + return self.enablePeerToPeer as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse: + return self.allowLocalEndpointReuse as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSCurrentPathOption: + guard let currentPath = self.nwConnection?.currentPath else { + throw NIOTSErrors.NoCurrentPath() + } + return currentPath as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSMetadataOption: + let optionValue = option as! NIOTSChannelOptions.Types.NIOTSMetadataOption + guard let nwConnection = self.nwConnection else { + throw NIOTSErrors.NoCurrentConnection() + } + return nwConnection.metadata(definition: optionValue.definition) as! Option.Value + default: + // watchOS 6.0 availability is covered by the @available on this extension. + if #available(OSX 10.15, iOS 13.0, tvOS 13.0, *) { + switch option { + case is NIOTSChannelOptions.Types.NIOTSEstablishmentReportOption: + guard let nwConnection = self.nwConnection else { + throw NIOTSErrors.NoCurrentConnection() + } + let promise: EventLoopPromise = eventLoop.makePromise() + nwConnection.requestEstablishmentReport(queue: connectionQueue) { report in + promise.succeed(report) + } + return promise.futureResult as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSDataTransferReportOption: + guard let nwConnection = self.nwConnection else { + throw NIOTSErrors.NoCurrentConnection() + } + return nwConnection.startDataTransferReport() as! Option.Value + default: + break + } + } + + fatalError("option \(type(of: option)).\(option) not supported") + } + } +} + + +// MARK:- NIOTSConnectionChannel implementation of StateManagedChannel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionChannel: StateManagedChannel { + typealias ActiveSubstate = TCPSubstate + + /// A TCP connection may be fully open or partially open. In the fully open state, both + /// peers may send data. In the partially open states, only one of the two peers may send + /// data. + /// + /// We keep track of this to manage the half-closure state of the TCP connection. + enum TCPSubstate: ActiveChannelSubstate { + /// Both peers may send. + case open + + /// This end of the connection has sent a FIN. We may only receive data. + case halfClosedLocal + + /// The remote peer has sent a FIN. We may still send data, but cannot expect to + /// receive more. + case halfClosedRemote + + /// The channel is "active", but there can be no forward momentum here. The only valid + /// thing to do in this state is drop the channel. + case closed + + init() { + self = .open + } + } + + public func localAddress0() throws -> SocketAddress { + guard let localEndpoint = self.nwConnection?.currentPath?.localEndpoint else { + throw NIOTSErrors.NoCurrentPath() + } + // TODO: Support wider range of address types. + return try SocketAddress(fromNWEndpoint: localEndpoint) + } + + public func remoteAddress0() throws -> SocketAddress { + guard let remoteEndpoint = self.nwConnection?.currentPath?.remoteEndpoint else { + throw NIOTSErrors.NoCurrentPath() + } + // TODO: Support wider range of address types. + return try SocketAddress(fromNWEndpoint: remoteEndpoint) + } + + internal func alreadyConfigured0(promise: EventLoopPromise?) { + guard let connection = nwConnection else { + promise?.fail(NIOTSErrors.NotPreConfigured()) + return + } + + guard case .setup = connection.state else { + promise?.fail(NIOTSErrors.NotPreConfigured()) + return + } + + connection.stateUpdateHandler = self.stateUpdateHandler(newState:) + connection.betterPathUpdateHandler = self.betterPathHandler + connection.pathUpdateHandler = self.pathChangedHandler(newPath:) + connection.start(queue: self.connectionQueue) + } + + internal func beginActivating0(to target: NWEndpoint, promise: EventLoopPromise?) { + assert(self.nwConnection == nil) + assert(self.connectPromise == nil) + + // Before we start, we validate that the target won't cause a crash: see + // https://github.com/apple/swift-nio/issues/1617. + if case .hostPort(host: let host, port: _) = target, host == "" { + // We don't pass the promise in here because we'll actually not complete it. We complete it manually ourselves. + self.close0(error: NIOTSErrors.InvalidHostname(), mode: .all, promise: nil) + promise?.fail(NIOTSErrors.InvalidHostname()) + return + } + + self.connectPromise = promise + + let parameters = NWParameters(tls: self.tlsOptions, tcp: self.tcpOptions) + + // Network.framework munges REUSEADDR and REUSEPORT together, so we turn this on if we need + // either or it's been explicitly set. + parameters.allowLocalEndpointReuse = self.reuseAddress || self.reusePort || self.allowLocalEndpointReuse + + parameters.includePeerToPeer = self.enablePeerToPeer + + let connection = NWConnection(to: target, using: parameters) + connection.stateUpdateHandler = self.stateUpdateHandler(newState:) + connection.betterPathUpdateHandler = self.betterPathHandler + connection.pathUpdateHandler = self.pathChangedHandler(newPath:) + + // Ok, state is ready. Let's go! + self.nwConnection = connection + connection.start(queue: self.connectionQueue) + } + + public func write0(_ data: NIOAny, promise: EventLoopPromise?) { + guard self.isActive else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + // TODO: We would ideally support all of IOData here, gotta work out how to do that without HOL blocking + // all writes terribly. + // My best guess at this time is that Data(contentsOf:) may mmap the file in question, which would let us + // at least only block the network stack itself rather than our thread. I'm not certain though, especially + // on Linux. Should investigate. + let data = self.unwrapData(data, as: ByteBuffer.self) + self.pendingWrites.append((data, promise)) + + + /// This may cause our writability state to change. + if self.backpressureManager.writabilityChanges(whenQueueingBytes: data.readableBytes) { + self.pipeline.fireChannelWritabilityChanged() + } + } + + public func flush0() { + guard self.isActive else { + return + } + + guard let conn = self.nwConnection else { + preconditionFailure("nwconnection cannot be nil while channel is active") + } + + func completionCallback(promise: EventLoopPromise?, sentBytes: Int) -> ((NWError?) -> Void) { + return { error in + if let error = error { + promise?.fail(error) + } else { + promise?.succeed(()) + } + + if self.backpressureManager.writabilityChanges(whenBytesSent: sentBytes) { + self.pipeline.fireChannelWritabilityChanged() + } + } + } + + conn.batch { + while self.pendingWrites.count > 0 { + let write = self.pendingWrites.removeFirst() + let buffer = write.data + let content = buffer.getData(at: buffer.readerIndex, length: buffer.readableBytes) + conn.send(content: content, completion: .contentProcessed(completionCallback(promise: write.promise, sentBytes: buffer.readableBytes))) + } + } + } + + /// Perform a read from the network. + /// + /// This method has a slightly strange semantic, because we do not allow multiple reads at once. As a result, this + /// is a *request* to read, and if there is a read already being processed then this method will do nothing. + public func read0() { + guard self.inboundStreamOpen && !self.outstandingRead else { + return + } + + guard let conn = self.nwConnection else { + preconditionFailure("Connection should not be nil") + } + + // TODO: Can we do something sensible with these numbers? + self.outstandingRead = true + conn.receive(minimumIncompleteLength: 1, maximumLength: 8192, completion: self.dataReceivedHandler(content:context:isComplete:error:)) + } + + public func doClose0(error: Error) { + guard let conn = self.nwConnection else { + // We don't have a connection to close here, so we're actually done. Our old state + // was idle. + assert(self.pendingWrites.count == 0) + return + } + + // Step 1 is to tell the network stack we're done. + // TODO: Does this drop the connection fully, or can we keep receiving data? Must investigate. + conn.cancel() + + // Step 2 is to fail all outstanding writes. + self.dropOutstandingWrites(error: error) + + // Step 3 is to cancel a pending connect promise, if any. + if let pendingConnect = self.connectPromise { + self.connectPromise = nil + pendingConnect.fail(error) + } + } + + public func doHalfClose0(error: Error, promise: EventLoopPromise?) { + guard let conn = self.nwConnection else { + // We don't have a connection to half close, so fail the promise. + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + + do { + try self.state.closeOutput() + } catch ChannelError.outputClosed { + // Here we *only* fail the promise, no need to blow up the connection. + promise?.fail(ChannelError.outputClosed) + return + } catch { + // For any other error, this is fatal. + self.close0(error: error, mode: .all, promise: promise) + return + } + + func completionCallback(for promise: EventLoopPromise?) -> ((NWError?) -> Void) { + return { error in + if let error = error { + promise?.fail(error) + } else { + promise?.succeed(()) + } + } + } + + // It should not be possible to have a pending connect promise while we're doing half-closure. + assert(self.connectPromise == nil) + + // Step 1 is to tell the network stack we're done. + conn.send(content: nil, contentContext: .finalMessage, completion: .contentProcessed(completionCallback(for: promise))) + + // Step 2 is to fail all outstanding writes. + self.dropOutstandingWrites(error: error) + } + + public func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + switch event { + case let x as NIOTSNetworkEvents.ConnectToNWEndpoint: + self.connect0(to: x.endpoint, promise: promise) + default: + promise?.fail(ChannelError.operationUnsupported) + } + } + + public func channelRead0(_ data: NIOAny) { + // drop the data, do nothing + return + } + + public func errorCaught0(error: Error) { + // Currently we don't do anything with errors that pass through the pipeline + return + } + + /// A function that will trigger a socket read if necessary. + internal func readIfNeeded0() { + if self.options.autoRead { + self.pipeline.read() + } + } +} + + +// MARK:- Implementations of the callbacks passed to NWConnection. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionChannel { + /// Called by the underlying `NWConnection` when its internal state has changed. + private func stateUpdateHandler(newState: NWConnection.State) { + switch newState { + case .setup: + preconditionFailure("Should not be told about this state.") + case .waiting(let err): + if case .activating = self.state, self.options.waitForActivity { + // This means the connection cannot currently be completed. We should notify the pipeline + // here, or support this with a channel option or something, but for now for the sake of + // demos we will just allow ourselves into this stage. + self.pipeline.fireUserInboundEventTriggered(NIOTSNetworkEvents.WaitingForConnectivity(transientError: err)) + break + } + + // In this state we've transitioned into waiting, presumably from active or closing. In this + // version of NIO this is an error, but we should aim to support this at some stage. + self.close0(error: err, mode: .all, promise: nil) + case .preparing: + // This just means connections are being actively established. We have no specific action + // here. + break + case .ready: + // Transitioning to ready means the connection was succeeded. Hooray! + self.connectionComplete0() + case .cancelled: + // This is the network telling us we're closed. We don't need to actually do anything here + // other than check our state is ok. + assert(self.closed) + self.nwConnection = nil + case .failed(let err): + // The connection has failed for some reason. + self.close0(error: err, mode: .all, promise: nil) + default: + // This clause is here to help the compiler out: it's otherwise not able to + // actually validate that the switch is exhaustive. Trust me, it is. + fatalError("Unreachable") + } + } + + /// Called by the underlying `NWConnection` when a network receive has completed. + /// + /// The state matrix here is large. If `content` is non-nil, some data was received: we need to send it down the pipeline + /// and call channelReadComplete. This may be nil, in which case we expect either `isComplete` to be `true` or `error` + /// to be non-nil. `isComplete` indicates half-closure on the read side of a connection. `error` is set if the receive + /// did not complete due to an error, though there may still be some data. + private func dataReceivedHandler(content: Data?, context: NWConnection.ContentContext?, isComplete: Bool, error: NWError?) { + precondition(self.outstandingRead) + self.outstandingRead = false + + guard self.isActive else { + // If we're already not active, we aren't going to process any of this: it's likely the result of an extra + // read somewhere along the line. + return + } + + // First things first, if there's data we need to deliver it. + if let content = content { + // It would be nice if we didn't have to do this copy, but I'm not sure how to avoid it with the current Data + // APIs. + var buffer = self.allocator.buffer(capacity: content.count) + buffer.writeBytes(content) + self.pipeline.fireChannelRead(NIOAny(buffer)) + self.pipeline.fireChannelReadComplete() + } + + // Next, we want to check if there's an error. If there is, we're going to deliver it, and then close the connection with + // it. Otherwise, we're going to check if we read EOF, and if we did we'll close with that instead. + if let error = error { + self.pipeline.fireErrorCaught(error) + self.close0(error: error, mode: .all, promise: nil) + } else if isComplete { + self.didReadEOF() + } + + // Last, issue a new read automatically if we need to. + self.readIfNeeded0() + } + + /// Called by the underlying `NWConnection` when a better path for this connection is available. + /// + /// Notifies the channel pipeline of the new option. + private func betterPathHandler(available: Bool) { + if available { + self.pipeline.fireUserInboundEventTriggered(NIOTSNetworkEvents.BetterPathAvailable()) + } else { + self.pipeline.fireUserInboundEventTriggered(NIOTSNetworkEvents.BetterPathUnavailable()) + } + } + + /// Called by the underlying `NWConnection` when this connection changes its network path. + /// + /// Notifies the channel pipeline of the new path. + private func pathChangedHandler(newPath path: NWPath) { + self.pipeline.fireUserInboundEventTriggered(NIOTSNetworkEvents.PathChanged(newPath: path)) + } +} + + +// MARK:- Implementations of state management for the channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionChannel { + /// Whether the inbound side of the connection is still open. + private var inboundStreamOpen: Bool { + switch self.state { + case .active(.open), .active(.halfClosedLocal): + return true + case .idle, .registered, .activating, .active, .inactive: + return false + } + } + + /// Make the channel active. + private func connectionComplete0() { + let promise = self.connectPromise + self.connectPromise = nil + + // Before becoming active, update the cached addresses. + let localAddress = try? self.localAddress0() + let remoteAddress = try? self.remoteAddress0() + + self._addressCacheLock.withLock { + self._addressCache = AddressCache(local: localAddress, remote: remoteAddress) + } + + self.becomeActive0(promise: promise) + + if let metadata = self.nwConnection?.metadata(definition: NWProtocolTLS.definition) as? NWProtocolTLS.Metadata { + // This is a TLS connection, we may need to fire some other events. + let negotiatedProtocol = sec_protocol_metadata_get_negotiated_protocol(metadata.securityProtocolMetadata).map { + String(cString: $0) + } + self.pipeline.fireUserInboundEventTriggered(TLSUserEvent.handshakeCompleted(negotiatedProtocol: negotiatedProtocol)) + } + } + + /// Drop all outstanding writes. Must only be called in the inactive + /// state. + private func dropOutstandingWrites(error: Error) { + while self.pendingWrites.count > 0 { + self.pendingWrites.removeFirst().promise?.fail(error) + } + } + + /// Handle a read EOF. + /// + /// If the user has indicated they support half-closure, we will emit the standard half-closure + /// event. If they have not, we upgrade this to regular closure. + private func didReadEOF() { + if self.options.supportRemoteHalfClosure { + // This is a half-closure, but the connection is still valid. + do { + try self.state.closeInput() + } catch { + return self.close0(error: error, mode: .all, promise: nil) + } + + self.pipeline.fireUserInboundEventTriggered(ChannelEvent.inputClosed) + } else { + self.close0(error: ChannelError.eof, mode: .all, promise: nil) + } + } +} + + +// MARK:- Managing TCP substate. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +fileprivate extension ChannelState where ActiveSubstate == NIOTSConnectionChannel.TCPSubstate { + /// Close the input side of the TCP state machine. + mutating func closeInput() throws { + switch self { + case .active(.open): + self = .active(.halfClosedRemote) + case .active(.halfClosedLocal): + self = .active(.closed) + case .idle, .registered, .activating, .active(.halfClosedRemote), .active(.closed), .inactive: + throw NIOTSErrors.InvalidChannelStateTransition() + } + } + + /// Close the output side of the TCP state machine. + mutating func closeOutput() throws { + switch self { + case .active(.open): + self = .active(.halfClosedLocal) + case .active(.halfClosedRemote): + self = .active(.closed) + case .active(.halfClosedLocal), .active(.closed): + // This is a special case for closing the output, as it's user-controlled. If they already + // closed it, we want to throw a special error to tell them. + throw ChannelError.outputClosed + case .idle, .registered, .activating, .inactive: + throw NIOTSErrors.InvalidChannelStateTransition() + } + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionChannel { + internal struct SynchronousOptions: NIOSynchronousChannelOptions { + private let channel: NIOTSConnectionChannel + + fileprivate init(channel: NIOTSConnectionChannel) { + self.channel = channel + } + + public func setOption(_ option: Option, value: Option.Value) throws { + try self.channel.setOption0(option: option, value: value) + } + + public func getOption(_ option: Option) throws -> Option.Value { + return try self.channel.getOption0(option: option) + } + } + + public var syncOptions: NIOSynchronousChannelOptions? { + return SynchronousOptions(channel: self) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSErrors.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSErrors.swift new file mode 100644 index 00000000..52fde1f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSErrors.swift @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if canImport(Network) +import NIOCore + +/// A tag protocol that can be used to cover all errors thrown by `NIOTransportServices`. +/// +/// Users are strongly encouraged not to conform their own types to this protocol. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public protocol NIOTSError: Error, Equatable { } + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public enum NIOTSErrors { + /// `InvalidChannelStateTransition` is thrown when a channel has been asked to do something + /// that is incompatible with its current channel state: e.g. attempting to register an + /// already registered channel. + public struct InvalidChannelStateTransition: NIOTSError { } + + /// `NotPreConfigured` is thrown when a channel has had `registerAlreadyConfigured` + /// called on it, but has not had the appropriate underlying network object provided. + public struct NotPreConfigured: NIOTSError { } + + /// `UnsupportedSocketOption` is thrown when an attempt is made to configure a socket option that + /// is not supported by Network.framework. + public struct UnsupportedSocketOption: NIOTSError { + public let optionValue: ChannelOptions.Types.SocketOption + + public static func ==(lhs: UnsupportedSocketOption, rhs: UnsupportedSocketOption) -> Bool { + return lhs.optionValue == rhs.optionValue + } + } + + /// `NoCurrentPath` is thrown when an attempt is made to request path details from a channel and + /// that channel has no path available. This can manifest, for example, when asking for remote + /// or local addresses. + public struct NoCurrentPath: NIOTSError { } + + /// `NoCurrentConnection` is thrown when an attempt is made to request connection details from a channel and + /// that channel has no connection available. + public struct NoCurrentConnection: NIOTSError { } + + /// `InvalidPort` is thrown when the port passed to a method is not valid. + public struct InvalidPort: NIOTSError { + /// The provided port. + public let port: Int + } + + /// `UnableToResolveEndpoint` is thrown when an attempt is made to resolve a local endpoint, but + /// insufficient information is available to create it. + public struct UnableToResolveEndpoint: NIOTSError { } + + /// `BindTimeout` is thrown when a timeout set for a `NWListenerBootstrap.bind` call has been exceeded + /// without successfully binding the address. + public struct BindTimeout: NIOTSError { + public var timeout: TimeAmount + + public init(timeout: TimeAmount) { + self.timeout = timeout + } + } + + /// `InvalidHostname` is thrown when attempting to connect to an invalid host. + public struct InvalidHostname: NIOTSError { + public init() { } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoop.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoop.swift new file mode 100644 index 00000000..f6d76db5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoop.swift @@ -0,0 +1,250 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Dispatch +import Foundation +import Network + +import NIOCore +import NIOConcurrencyHelpers + +/// An `EventLoop` that interacts with `DispatchQoS` to help schedule upcoming work. +/// +/// `EventLoop`s that implement `QoSEventLoop` can interact with `Dispatch` to propagate information +/// about the QoS required for a specific task block. This allows tasks to be dispatched onto an +/// event loop with a different priority than the majority of tasks on that loop. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public protocol QoSEventLoop: EventLoop { + /// Submit a given task to be executed by the `EventLoop` at a given `qos`. + func execute(qos: DispatchQoS, _ task: @escaping () -> Void) -> Void + + /// Schedule a `task` that is executed by this `NIOTSEventLoop` after the given amount of time at the + /// given `qos`. + func scheduleTask(in time: TimeAmount, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled +} + + +/// The lifecycle state of a given event loop. +/// +/// Event loops have the ability to be shut down, and not restarted. When a loop is active it will accept +/// new registrations, and new scheduled work items. When a loop is shutting down it will no longer accept +/// new registrations, but it will continue to accept new scheduled work items. When a loop is closed, it +/// will accept neither new registrations nor new scheduled work items, but it will continue to process +/// the queue until it has drained. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +fileprivate enum LifecycleState { + case active + case closing + case closed +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal class NIOTSEventLoop: QoSEventLoop { + private let loop: DispatchQueue + private let taskQueue: DispatchQueue + private let inQueueKey: DispatchSpecificKey + private let loopID: UUID + private let defaultQoS: DispatchQoS + + /// All the channels registered to this event loop. + /// + /// This array does two jobs. Firstly, it ensures that these channels stay alive for as long as + /// they are registered: they cannot leak. Secondly, it provides a notification mechanism for + /// this event loop to deliver them specific kinds of events: in particular, to request that + /// they quiesce or shut themselves down. + private var registeredChannels: [ObjectIdentifier: Channel] = [:] + + /// The state of this event loop. + private var state = LifecycleState.active + + /// Whether this event loop is accepting new channels. + private var open: Bool { + return self.state == .active + } + + /// Returns whether the currently executing code is on the event loop. + /// + /// Due to limitations in Dispatch's API, this check is pessimistic: there are circumstances where a perfect + /// implementation *could* return `true`, but this version will be unable to prove that and will return `false`. + /// If you need to write an assertion about being in the event loop that must be correct, use SwiftNIO 1.11 or + /// later and call `preconditionInEventLoop` and `assertInEventLoop`. + /// + /// Further detail: The use of `DispatchQueue.sync(execute:)` to submit a block to a queue synchronously has the + /// effect of creating a state where the currently executing code is on two queues simultaneously - the one which + /// submitted the block, and the one on which the block runs. If another synchronous block is dispatched to a + /// third queue, that block is effectively running all three at once. Unfortunately, libdispatch maintains only + /// one "current" queue at a time as far as `DispatchQueue.getSpecific(key:)` is concerned, and it's always the + /// one actually executing code at the time. Therefore the queue belonging to the original event loop can't be + /// detected using its queue-specific data. No alternative API for the purpose exists (aside from assertions via + /// `dispatchPrecondition(condition:)`). Under these circumstances, `inEventLoop` will incorrectly be `false`, + /// even though the current code _is_ actually on the loop's queue. The only way to avoid this is to ensure no + /// callers ever use synchronous dispatch (which is impossible to enforce), or to hope that a future version of + /// libdispatch will provide a solution. + public var inEventLoop: Bool { + return DispatchQueue.getSpecific(key: self.inQueueKey) == self.loopID + } + + public init(qos: DispatchQoS) { + self.loop = DispatchQueue(label: "nio.transportservices.eventloop.loop", qos: qos, autoreleaseFrequency: .workItem) + self.taskQueue = DispatchQueue(label: "nio.transportservices.eventloop.taskqueue", target: self.loop) + self.loopID = UUID() + self.inQueueKey = DispatchSpecificKey() + self.defaultQoS = qos + loop.setSpecific(key: inQueueKey, value: self.loopID) + } + + public func execute(_ task: @escaping () -> Void) { + self.execute(qos: self.defaultQoS, task) + } + + public func execute(qos: DispatchQoS, _ task: @escaping () -> Void) { + // Ideally we'd not accept new work while closed. Sadly, that's not possible with the current APIs for this. + self.taskQueue.async(qos: qos, execute: task) + } + + public func scheduleTask(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled { + return self.scheduleTask(deadline: deadline, qos: self.defaultQoS, task) + } + + public func scheduleTask(deadline: NIODeadline, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled { + let p: EventLoopPromise = self.makePromise() + + // Dispatch support for cancellation exists at the work-item level, so we explicitly create one here. + // We set the QoS on this work item and explicitly enforce it when the block runs. + let timerSource = DispatchSource.makeTimerSource(queue: self.taskQueue) + timerSource.schedule(deadline: DispatchTime(uptimeNanoseconds: deadline.uptimeNanoseconds)) + timerSource.setEventHandler(qos: qos, flags: .enforceQoS) { + guard self.state != .closed else { + p.fail(EventLoopError.shutdown) + return + } + do { + p.succeed(try task()) + } catch { + p.fail(error) + } + } + timerSource.resume() + + // Create a retain cycle between the future and the timer source. This will be broken when the promise is + // completed by the event handler and this callback is run. + p.futureResult.whenComplete { _ in + timerSource.cancel() + } + + return Scheduled(promise: p, cancellationTask: { + timerSource.cancel() + }) + } + + public func scheduleTask(in time: TimeAmount, _ task: @escaping () throws -> T) -> Scheduled { + return self.scheduleTask(in: time, qos: self.defaultQoS, task) + } + + public func scheduleTask(in time: TimeAmount, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled { + return self.scheduleTask(deadline: NIODeadline.now() + time, qos: qos, task) + } + + public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) { + self.closeGently().map { + queue.async { callback(nil) } + }.whenFailure { error in + queue.async { callback(error) } + } + } + + @inlinable + public func preconditionInEventLoop(file: StaticString, line: UInt) { + dispatchPrecondition(condition: .onQueue(self.loop)) + } + + @inlinable + public func preconditionNotInEventLoop(file: StaticString, line: UInt) { + dispatchPrecondition(condition: .notOnQueue(self.loop)) + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSEventLoop { + /// Create a `DispatchQueue` to use for events on a given `Channel`. + /// + /// This `DispatchQueue` will be guaranteed to execute on this `EventLoop`, and + /// so is safe to use concurrently with the rest of the event loop. + internal func channelQueue(label: String, qos: DispatchQoS? = nil) -> DispatchQueue { + // If a QoS override is not requested, use the default. + let qos = qos ?? self.defaultQoS + return DispatchQueue(label: label, qos: qos, target: self.loop) + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSEventLoop { + internal func closeGently() -> EventLoopFuture { + let p: EventLoopPromise = self.makePromise() + self.taskQueue.async { + guard self.open else { + p.fail(EventLoopError.shutdown) + return + } + + // Ok, time to shut down. + self.state = .closing + + // We need to tell all currently-registered channels to close. + let futures: [EventLoopFuture] = self.registeredChannels.map { _, channel in + channel.close(promise: nil) + return channel.closeFuture.flatMapErrorThrowing { error in + if let error = error as? ChannelError, error == .alreadyClosed { + return () + } else { + throw error + } + } + } + + // The ordering here is important. + // We must not transition into the closed state until *after* the caller has been notified that the + // event loop is closed. Otherwise, this future is in real trouble, as if it needs to dispatch onto the + // event loop it will be forbidden from doing so. + let completionFuture = EventLoopFuture.andAllComplete(futures, on: self) + completionFuture.cascade(to: p) + completionFuture.whenComplete { (_: Result) in + self.state = .closed + } + } + return p.futureResult + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSEventLoop { + /// Record a given channel with this event loop. + internal func register(_ channel: Channel) throws { + guard self.open else { + throw EventLoopError.shutdown + } + + channel.eventLoop.assertInEventLoop() + self.registeredChannels[ObjectIdentifier(channel)] = channel + } + + // We don't allow deregister to fail, as it doesn't make any sense. + internal func deregister(_ channel: Channel) { + channel.eventLoop.assertInEventLoop() + let oldChannel = self.registeredChannels.removeValue(forKey: ObjectIdentifier(channel)) + assert(oldChannel != nil) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoopGroup.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoopGroup.swift new file mode 100644 index 00000000..267467e2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSEventLoopGroup.swift @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Foundation +import NIOCore +import NIOConcurrencyHelpers +import Dispatch +import Network + + +/// An `EventLoopGroup` containing `EventLoop`s specifically designed for use with +/// Network.framework's post-sockets networking API. +/// +/// These `EventLoop`s provide highly optimised and powerful networking tools for +/// the Darwin platforms. They have a number of advantages over the regular +/// `SelectableEventLoop` that NIO uses on other platforms. In particular: +/// +/// - The use of `DispatchQueue`s to schedule tasks allows the Darwin kernels to make +/// intelligent scheduling decisions, as well as to maintain QoS and ensure that +/// tasks required to handle networking in your application are given appropriate +/// priority by the system. +/// - Network.framework provides powerful tools for observing network state and managing +/// connections on devices with highly fluid networking environments, such as laptops +/// and mobile devices. These tools can be exposed to `Channel`s using this backend. +/// - Network.framework brings the networking stack into userspace, reducing the overhead +/// of most network operations by removing syscalls, and greatly increasing the safety +/// and security of the network stack. +/// - The applications networking needs are more effectively communicated to the kernel, +/// allowing mobile devices to change radio configuration and behaviour as needed to +/// take advantage of the various interfaces available on mobile devices. +/// +/// In general, when building applications whose primary purpose is to be deployed on Darwin +/// platforms, the `NIOTSEventLoopGroup` should be preferred over the +/// `MultiThreadedEventLoopGroup`. In particular, on iOS, the `NIOTSEventLoopGroup` is the +/// preferred networking backend. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public final class NIOTSEventLoopGroup: EventLoopGroup { + private let index = NIOAtomic.makeAtomic(value: 0) + private let eventLoops: [NIOTSEventLoop] + + public init(loopCount: Int = 1, defaultQoS: DispatchQoS = .default) { + precondition(loopCount > 0) + self.eventLoops = (0.. EventLoop { + return self.eventLoops[abs(index.add(1) % self.eventLoops.count)] + } + + /// Shuts down all of the event loops, rendering them unable to perform further work. + public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) { + let g = DispatchGroup() + let q = DispatchQueue(label: "nio.transportservices.shutdowngracefullyqueue", target: queue) + var error: Error? = nil + + for loop in self.eventLoops { + g.enter() + loop.closeGently().recover { err in + q.sync { error = err } + }.whenComplete { (_: Result) in + g.leave() + } + } + + g.notify(queue: q) { + callback(error) + } + } + + public func makeIterator() -> EventLoopIterator { + return EventLoopIterator(self.eventLoops) + } +} + +/// A TLS provider to bootstrap TLS-enabled connections with `NIOClientTCPBootstrap`. +/// +/// Example: +/// +/// // Creating the "universal bootstrap" with the `NIOTSClientTLSProvider`. +/// let tlsProvider = NIOTSClientTLSProvider() +/// let bootstrap = NIOClientTCPBootstrap(NIOTSConnectionBootstrap(group: group), tls: tlsProvider) +/// +/// // Bootstrapping a connection using the "universal bootstrapping mechanism" +/// let connection = bootstrap.enableTLS() +/// .connect(host: "example.com", port: 443) +/// .wait() +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public struct NIOTSClientTLSProvider: NIOClientTLSProvider { + public typealias Bootstrap = NIOTSConnectionBootstrap + + let tlsOptions: NWProtocolTLS.Options + + /// Construct the TLS provider. + public init(tlsOptions: NWProtocolTLS.Options = NWProtocolTLS.Options()) { + self.tlsOptions = tlsOptions + } + + /// Enable TLS on the bootstrap. This is not a function you will typically call as a user, it is called by + /// `NIOClientTCPBootstrap`. + public func enableTLS(_ bootstrap: NIOTSConnectionBootstrap) -> NIOTSConnectionBootstrap { + return bootstrap.tlsOptions(self.tlsOptions) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift new file mode 100644 index 00000000..053c3f7a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerBootstrap.swift @@ -0,0 +1,415 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import NIOCore +import Dispatch +import Network + +/// A `NIOTSListenerBootstrap` is an easy way to bootstrap a `NIOTSListenerChannel` when creating network servers. +/// +/// Example: +/// +/// ```swift +/// let group = NIOTSEventLoopGroup() +/// defer { +/// try! group.syncShutdownGracefully() +/// } +/// let bootstrap = NIOTSListenerBootstrap(group: group) +/// // Specify backlog and enable SO_REUSEADDR for the server itself +/// .serverChannelOption(ChannelOptions.backlog, value: 256) +/// .serverChannelOption(ChannelOptions.socketOption(.reuseaddr), value: 1) +/// +/// // Set the handlers that are applied to the accepted child `Channel`s. +/// .childChannelInitializer { channel in +/// // Ensure we don't read faster then we can write by adding the BackPressureHandler into the pipeline. +/// channel.pipeline.addHandler(BackPressureHandler()).flatMap { () in +/// // make sure to instantiate your `ChannelHandlers` inside of +/// // the closure as it will be invoked once per connection. +/// channel.pipeline.addHandler(MyChannelHandler()) +/// } +/// } +/// let channel = try! bootstrap.bind(host: host, port: port).wait() +/// /* the server will now be accepting connections */ +/// +/// try! channel.closeFuture.wait() // wait forever as we never close the Channel +/// ``` +/// +/// The `EventLoopFuture` returned by `bind` will fire with a `NIOTSListenerChannel`. This is the channel that owns the +/// listening socket. Each time it accepts a new connection it will fire a `NIOTSConnectionChannel` through the +/// `ChannelPipeline` via `fireChannelRead`: as a result, the `NIOTSListenerChannel` operates on `Channel`s as inbound +/// messages. Outbound messages are not supported on a `NIOTSListenerChannel` which means that each write attempt will +/// fail. +/// +/// Accepted `NIOTSConnectionChannel`s operate on `ByteBuffer` as inbound data, and `IOData` as outbound data. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public final class NIOTSListenerBootstrap { + private let group: EventLoopGroup + private let childGroup: EventLoopGroup + private var serverChannelInit: ((Channel) -> EventLoopFuture)? + private var childChannelInit: ((Channel) -> EventLoopFuture)? + private var serverChannelOptions = ChannelOptions.Storage() + private var childChannelOptions = ChannelOptions.Storage() + private var serverQoS: DispatchQoS? + private var childQoS: DispatchQoS? + private var tcpOptions: NWProtocolTCP.Options = .init() + private var tlsOptions: NWProtocolTLS.Options? + private var bindTimeout: TimeAmount? + + /// Create a `NIOTSListenerBootstrap` for the `EventLoopGroup` `group`. + /// + /// This initializer only exists to be more in-line with the NIO core bootstraps, in that they + /// may be constructed with an `EventLoopGroup` and by extenstion an `EventLoop`. As such an + /// existing `NIOTSEventLoop` may be used to initialize this bootstrap. Where possible the + /// initializers accepting `NIOTSEventLoopGroup` should be used instead to avoid the wrong + /// type being used. + /// + /// Note that the "real" solution is described in https://github.com/apple/swift-nio/issues/674. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `NIOTSListenerChannel`. + public convenience init(group: EventLoopGroup) { + self.init(group: group, childGroup: group) + } + + /// Create a `NIOTSListenerBootstrap` for the `NIOTSEventLoopGroup` `group`. + /// + /// - parameters: + /// - group: The `NIOTSEventLoopGroup` to use for the `NIOTSListenerChannel`. + public convenience init(group: NIOTSEventLoopGroup) { + self.init(group: group as EventLoopGroup) + } + + /// Create a `NIOTSListenerBootstrap`. + /// + /// This initializer only exists to be more in-line with the NIO core bootstraps, in that they + /// may be constructed with an `EventLoopGroup` and by extension an `EventLoop`. As such an + /// existing `NIOTSEventLoop` may be used to initialize this bootstrap. Where possible the + /// initializers accepting `NIOTSEventLoopGroup` should be used instead to avoid the wrong + /// type being used. + /// + /// Note that the "real" solution is described in https://github.com/apple/swift-nio/issues/674. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `bind` of the `NIOTSListenerChannel` + /// and to accept new `NIOTSConnectionChannel`s with. + /// - childGroup: The `EventLoopGroup` to run the accepted `NIOTSConnectionChannel`s on. + public convenience init(group: EventLoopGroup, childGroup: EventLoopGroup) { + guard NIOTSBootstraps.isCompatible(group: group) && NIOTSBootstraps.isCompatible(group: childGroup) else { + preconditionFailure("NIOTSListenerBootstrap is only compatible with NIOTSEventLoopGroup and " + + "NIOTSEventLoop. You tried constructing one with group: \(group) and " + + "childGroup: \(childGroup) at least one of which is incompatible.") + } + + self.init(validatingGroup: group, childGroup: childGroup)! + } + + /// Create a `NIOTSListenerBootstrap` on the `EventLoopGroup` `group` which accepts `Channel`s on `childGroup`, + /// validating that the `EventLoopGroup`s are compatible with `NIOTSListenerBootstrap`. + /// + /// - parameters: + /// - group: The `EventLoopGroup` to use for the `bind` of the `NIOTSListenerChannel` + /// and to accept new `NIOTSConnectionChannel`s with. + /// - childGroup: The `EventLoopGroup` to run the accepted `NIOTSConnectionChannel`s on. + public init?(validatingGroup group: EventLoopGroup, childGroup: EventLoopGroup? = nil) { + let childGroup = childGroup ?? group + guard NIOTSBootstraps.isCompatible(group: group) && NIOTSBootstraps.isCompatible(group: childGroup) else { + return nil + } + + self.group = group + self.childGroup = childGroup + + self.serverChannelOptions.append(key: ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + self.childChannelOptions.append(key: ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + } + + /// Create a `NIOTSListenerBootstrap`. + /// + /// - parameters: + /// - group: The `NIOTSEventLoopGroup` to use for the `bind` of the `NIOTSListenerChannel` + /// and to accept new `NIOTSConnectionChannel`s with. + /// - childGroup: The `NIOTSEventLoopGroup` to run the accepted `NIOTSConnectionChannel`s on. + public convenience init(group: NIOTSEventLoopGroup, childGroup: NIOTSEventLoopGroup) { + self.init(group: group as EventLoopGroup, childGroup: childGroup as EventLoopGroup) + } + + /// Initialize the `NIOTSListenerChannel` with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. + /// + /// The `NIOTSListenerChannel` uses the accepted `NIOTSConnectionChannel`s as inbound messages. + /// + /// - note: To set the initializer for the accepted `NIOTSConnectionChannel`s, look at + /// `NIOTSConnectionBootstrap.childChannelInitializer`. + /// + /// - parameters: + /// - initializer: A closure that initializes the provided `Channel`. + public func serverChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self { + self.serverChannelInit = initializer + return self + } + + /// Initialize the accepted `NIOTSConnectionChannel`s with `initializer`. The most common task in initializer is to add + /// `ChannelHandler`s to the `ChannelPipeline`. Note that if the `initializer` fails then the error will be + /// fired in the *parent* channel. + /// + /// The accepted `Channel` will operate on `ByteBuffer` as inbound and `IOData` as outbound messages. + /// + /// - parameters: + /// - initializer: A closure that initializes the provided `Channel`. + public func childChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self { + self.childChannelInit = initializer + return self + } + + /// Specifies a `ChannelOption` to be applied to the `NIOTSListenerChannel`. + /// + /// - note: To specify options for the accepted `NIOTSConnectionChannels`s, look at `NIOTSListenerBootstrap.childChannelOption`. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + public func serverChannelOption(_ option: Option, value: Option.Value) -> Self { + self.serverChannelOptions.append(key: option, value: value) + return self + } + + /// Specifies a `ChannelOption` to be applied to the accepted `NIOTSConnectionChannel`s. + /// + /// - parameters: + /// - option: The option to be applied. + /// - value: The value for the option. + public func childChannelOption(_ option: Option, value: Option.Value) -> Self { + self.childChannelOptions.append(key: option, value: value) + return self + } + + /// Specifies a timeout to apply to a bind attempt. + // + /// - parameters: + /// - timeout: The timeout that will apply to the bind attempt. + public func bindTimeout(_ timeout: TimeAmount) -> Self { + self.bindTimeout = timeout + return self + } + + /// Specifies a QoS to use for the server channel, instead of the default QoS for the + /// event loop. + /// + /// This allows unusually high or low priority workloads to be appropriately scheduled. + public func serverQoS(_ qos: DispatchQoS) -> Self { + self.serverQoS = qos + return self + } + + + /// Specifies a QoS to use for the child connections created from the server channel, + /// instead of the default QoS for the event loop. + /// + /// This allows unusually high or low priority workloads to be appropriately scheduled. + public func childQoS(_ qos: DispatchQoS) -> Self { + self.childQoS = qos + return self + } + + /// Specifies the TCP options to use on the child `Channel`s. + /// + /// To retrieve the TCP options from connected channels, use + /// `NIOTSChannelOptions.TCPConfiguration`. It is not possible to change the + /// TCP configuration after `bind` is called. + public func tcpOptions(_ options: NWProtocolTCP.Options) -> Self { + self.tcpOptions = options + return self + } + + /// Specifies the TLS options to use on the child `Channel`s. + /// + /// To retrieve the TLS options from connected channels, use + /// `NIOTSChannelOptions.TLSConfiguration`. It is not possible to change the + /// TLS configuration after `bind` is called. + public func tlsOptions(_ options: NWProtocolTLS.Options) -> Self { + self.tlsOptions = options + return self + } + + /// Bind the `NIOTSListenerChannel` to `host` and `port`. + /// + /// - parameters: + /// - host: The host to bind on. + /// - port: The port to bind on. + public func bind(host: String, port: Int) -> EventLoopFuture { + let validPortRange = Int(UInt16.min)...Int(UInt16.max) + guard validPortRange.contains(port) else { + return self.group.next().makeFailedFuture(NIOTSErrors.InvalidPort(port: port)) + } + + return self.bind0 { (channel, promise) in + do { + // NWListener does not actually resolve hostname-based NWEndpoints + // for use with requiredLocalEndpoint, so we fall back to + // SocketAddress for this. + let address = try SocketAddress.makeAddressResolvingHost(host, port: port) + channel.bind(to: address, promise: promise) + } catch { + promise.fail(error) + } + } + } + + /// Bind the `NIOTSListenerChannel` to `address`. + /// + /// - parameters: + /// - address: The `SocketAddress` to bind on. + public func bind(to address: SocketAddress) -> EventLoopFuture { + return self.bind0 { (channel, promise) in + channel.bind(to: address, promise: promise) + } + } + + /// Bind the `NIOTSListenerChannel` to a UNIX Domain Socket. + /// + /// - parameters: + /// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system. + public func bind(unixDomainSocketPath: String) -> EventLoopFuture { + return self.bind0 { (channel, promise) in + do { + let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath) + channel.bind(to: address, promise: promise) + } catch { + promise.fail(error) + } + } + } + + /// Bind the `NIOTSListenerChannel` to a given `NWEndpoint`. + /// + /// - parameters: + /// - endpoint: The `NWEndpoint` to bind this channel to. + public func bind(endpoint: NWEndpoint) -> EventLoopFuture { + return self.bind0 { (channel, promise) in + channel.triggerUserOutboundEvent(NIOTSNetworkEvents.BindToNWEndpoint(endpoint: endpoint), promise: promise) + } + } + + private func bind0(_ binder: @escaping (Channel, EventLoopPromise) -> Void) -> EventLoopFuture { + let eventLoop = self.group.next() as! NIOTSEventLoop + let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.makeSucceededFuture(()) } + let childChannelInit = self.childChannelInit + let serverChannelOptions = self.serverChannelOptions + let childChannelOptions = self.childChannelOptions + + let serverChannel = NIOTSListenerChannel(eventLoop: eventLoop, + qos: self.serverQoS, + tcpOptions: self.tcpOptions, + tlsOptions: self.tlsOptions, + childLoopGroup: self.childGroup, + childChannelQoS: self.childQoS, + childTCPOptions: self.tcpOptions, + childTLSOptions: self.tlsOptions) + + return eventLoop.submit { + return serverChannelOptions.applyAllChannelOptions(to: serverChannel).flatMap { + serverChannelInit(serverChannel) + }.flatMap { + eventLoop.assertInEventLoop() + return serverChannel.pipeline.addHandler(AcceptHandler(childChannelInitializer: childChannelInit, + childChannelOptions: childChannelOptions)) + }.flatMap { + serverChannel.register() + }.flatMap { + let bindPromise = eventLoop.makePromise(of: Void.self) + binder(serverChannel, bindPromise) + + if let bindTimeout = self.bindTimeout { + let cancelTask = eventLoop.scheduleTask(in: bindTimeout) { + bindPromise.fail(NIOTSErrors.BindTimeout(timeout: bindTimeout)) + serverChannel.close(promise: nil) + } + + bindPromise.futureResult.whenComplete { (_: Result) in + cancelTask.cancel() + } + } + return bindPromise.futureResult + }.map { + serverChannel as Channel + }.flatMapError { error in + serverChannel.close0(error: error, mode: .all, promise: nil) + return eventLoop.makeFailedFuture(error) + } + }.flatMap { + $0 + } + } +} + + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +private class AcceptHandler: ChannelInboundHandler { + typealias InboundIn = NIOTSConnectionChannel + typealias InboundOut = NIOTSConnectionChannel + + private let childChannelInitializer: ((Channel) -> EventLoopFuture)? + private let childChannelOptions: ChannelOptions.Storage + + init(childChannelInitializer: ((Channel) -> EventLoopFuture)?, + childChannelOptions: ChannelOptions.Storage) { + self.childChannelInitializer = childChannelInitializer + self.childChannelOptions = childChannelOptions + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let newChannel = self.unwrapInboundIn(data) + let childLoop = newChannel.eventLoop + let ctxEventLoop = context.eventLoop + let childInitializer = self.childChannelInitializer ?? { _ in childLoop.makeSucceededFuture(()) } + + + @inline(__always) + func setupChildChannel() -> EventLoopFuture { + return self.childChannelOptions.applyAllChannelOptions(to: newChannel).flatMap { () -> EventLoopFuture in + childLoop.assertInEventLoop() + return childInitializer(newChannel) + } + } + + @inline(__always) + func fireThroughPipeline(_ future: EventLoopFuture) { + ctxEventLoop.assertInEventLoop() + future.flatMap { (_) -> EventLoopFuture in + ctxEventLoop.assertInEventLoop() + guard context.channel.isActive else { + return newChannel.close().flatMapThrowing { + throw ChannelError.ioOnClosedChannel + } + } + context.fireChannelRead(self.wrapInboundOut(newChannel)) + return context.eventLoop.makeSucceededFuture(()) + }.whenFailure { error in + context.eventLoop.assertInEventLoop() + _ = newChannel.close() + context.fireErrorCaught(error) + } + } + + if childLoop === ctxEventLoop { + fireThroughPipeline(setupChildChannel()) + } else { + fireThroughPipeline(childLoop.flatSubmit { + return setupChildChannel() + }.hop(to: ctxEventLoop)) + } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerChannel.swift new file mode 100644 index 00000000..a6cbb55b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSListenerChannel.swift @@ -0,0 +1,496 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Foundation +import NIOCore +import NIOFoundationCompat +import NIOConcurrencyHelpers +import Dispatch +import Network + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal final class NIOTSListenerChannel { + /// The `ByteBufferAllocator` for this `Channel`. + public let allocator = ByteBufferAllocator() + + /// An `EventLoopFuture` that will complete when this channel is finally closed. + public var closeFuture: EventLoopFuture { + return self.closePromise.futureResult + } + + /// The parent `Channel` for this one, if any. + public let parent: Channel? = nil + + /// The `EventLoop` this `Channel` belongs to. + internal let tsEventLoop: NIOTSEventLoop + + private var _pipeline: ChannelPipeline! = nil // this is really a constant (set in .init) but needs `self` to be constructed and therefore a `var`. Do not change as this needs to accessed from arbitrary threads. + + internal let closePromise: EventLoopPromise + + /// The underlying `NWListener` that this `Channel` wraps. This is only non-nil + /// after the initial connection attempt has been made. + private var nwListener: NWListener? + + /// The TCP options for this listener. + private let tcpOptions: NWProtocolTCP.Options + + /// The TLS options for this listener. + private let tlsOptions: NWProtocolTLS.Options? + + /// The `DispatchQueue` that socket events for this connection will be dispatched onto. + private let connectionQueue: DispatchQueue + + /// An `EventLoopPromise` that will be succeeded or failed when a bind attempt succeeds or fails. + private var bindPromise: EventLoopPromise? + + /// The state of this connection channel. + internal var state: ChannelState = .idle + + /// The kinds of channel activation this channel supports + internal let supportedActivationType: ActivationType = .bind + + /// The active state, used for safely reporting the channel state across threads. + internal var isActive0: NIOAtomic = .makeAtomic(value: false) + + /// Whether a call to NWListener.receive has been made, but the completion + /// handler has not yet been invoked. + private var outstandingRead: Bool = false + + /// Whether autoRead is enabled for this channel. + private var autoRead: Bool = true + + /// The value of SO_REUSEADDR. + private var reuseAddress = false + + /// The value of SO_REUSEPORT. + private var reusePort = false + + /// The value of the allowLocalEndpointReuse option. + private var allowLocalEndpointReuse = false + + /// Whether to enable peer-to-peer connectivity when using Bonjour services. + private var enablePeerToPeer = false + + /// The event loop group to use for child channels. + private let childLoopGroup: EventLoopGroup + + /// The QoS to use for child channels. + private let childChannelQoS: DispatchQoS? + + /// The TCP options to use for child channels. + private let childTCPOptions: NWProtocolTCP.Options + + /// The TLS options to use for child channels. + private let childTLSOptions: NWProtocolTLS.Options? + + /// The cache of the local and remote socket addresses. Must be accessed using _addressCacheLock. + private var _addressCache = AddressCache(local: nil, remote: nil) + + /// A lock that guards the _addressCache. + private let _addressCacheLock = Lock() + + + /// Create a `NIOTSListenerChannel` on a given `NIOTSEventLoop`. + /// + /// Note that `NIOTSListenerChannel` objects cannot be created on arbitrary loops types. + internal init(eventLoop: NIOTSEventLoop, + qos: DispatchQoS? = nil, + tcpOptions: NWProtocolTCP.Options, + tlsOptions: NWProtocolTLS.Options?, + childLoopGroup: EventLoopGroup, + childChannelQoS: DispatchQoS?, + childTCPOptions: NWProtocolTCP.Options, + childTLSOptions: NWProtocolTLS.Options?) { + self.tsEventLoop = eventLoop + self.closePromise = eventLoop.makePromise() + self.connectionQueue = eventLoop.channelQueue(label: "nio.transportservices.listenerchannel", qos: qos) + self.tcpOptions = tcpOptions + self.tlsOptions = tlsOptions + self.childLoopGroup = childLoopGroup + self.childChannelQoS = childChannelQoS + self.childTCPOptions = childTCPOptions + self.childTLSOptions = childTLSOptions + + // Must come last, as it requires self to be completely initialized. + self._pipeline = ChannelPipeline(channel: self) + } +} + + +// MARK:- NIOTSListenerChannel implementation of Channel +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerChannel: Channel { + /// The `ChannelPipeline` for this `Channel`. + public var pipeline: ChannelPipeline { + return self._pipeline + } + + /// The local address for this channel. + public var localAddress: SocketAddress? { + return self._addressCacheLock.withLock { + return self._addressCache.local + } + } + + /// The remote address for this channel. + public var remoteAddress: SocketAddress? { + return self._addressCacheLock.withLock { + return self._addressCache.remote + } + } + + /// Whether this channel is currently writable. + public var isWritable: Bool { + // TODO: implement + return true + } + + public var _channelCore: ChannelCore { + return self + } + + public func setOption(_ option: Option, value: Option.Value) -> EventLoopFuture { + if self.eventLoop.inEventLoop { + return self.eventLoop.makeCompletedFuture(Result { try setOption0(option: option, value: value) }) + } else { + return self.eventLoop.submit { try self.setOption0(option: option, value: value) } + } + } + + fileprivate func setOption0(option: Option, value: Option.Value) throws { + self.eventLoop.preconditionInEventLoop() + + guard !self.closed else { + throw ChannelError.ioOnClosedChannel + } + + // TODO: Many more channel options, both from NIO and Network.framework. + switch option { + case is ChannelOptions.Types.AutoReadOption: + // AutoRead is currently mandatory for TS listeners. + if value as! ChannelOptions.Types.AutoReadOption.Value == false { + throw ChannelError.operationUnsupported + } + case let optionValue as ChannelOptions.Types.SocketOption: + // SO_REUSEADDR and SO_REUSEPORT are handled here. + switch (optionValue.level, optionValue.name) { + case (SOL_SOCKET, SO_REUSEADDR): + self.reuseAddress = (value as! SocketOptionValue) != Int32(0) + case (SOL_SOCKET, SO_REUSEPORT): + self.reusePort = (value as! SocketOptionValue) != Int32(0) + default: + try self.tcpOptions.applyChannelOption(option: optionValue, value: value as! SocketOptionValue) + } + case is NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption: + self.enablePeerToPeer = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value + case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse: + self.allowLocalEndpointReuse = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value + default: + fatalError("option \(option) not supported") + } + } + + public func getOption(_ option: Option) -> EventLoopFuture { + if eventLoop.inEventLoop { + return self.eventLoop.makeCompletedFuture(Result { try getOption0(option: option) }) + } else { + return eventLoop.submit { try self.getOption0(option: option) } + } + } + + fileprivate func getOption0(option: Option) throws -> Option.Value { + self.eventLoop.preconditionInEventLoop() + + guard !self.closed else { + throw ChannelError.ioOnClosedChannel + } + + switch option { + case is ChannelOptions.Types.AutoReadOption: + return autoRead as! Option.Value + case let optionValue as ChannelOptions.Types.SocketOption: + // SO_REUSEADDR and SO_REUSEPORT are handled here. + switch (optionValue.level, optionValue.name) { + case (SOL_SOCKET, SO_REUSEADDR): + return Int32(self.reuseAddress ? 1 : 0) as! Option.Value + case (SOL_SOCKET, SO_REUSEPORT): + return Int32(self.reusePort ? 1 : 0) as! Option.Value + default: + return try self.tcpOptions.valueFor(socketOption: optionValue) as! Option.Value + } + case is NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption: + return self.enablePeerToPeer as! Option.Value + case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse: + return self.allowLocalEndpointReuse as! Option.Value + default: + fatalError("option \(option) not supported") + } + } +} + + +// MARK:- NIOTSListenerChannel implementation of StateManagedChannel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerChannel: StateManagedChannel { + typealias ActiveSubstate = ListenerActiveSubstate + + /// Listener channels do not have active substates: they are either active or they + /// are not. + enum ListenerActiveSubstate: ActiveChannelSubstate { + case active + + init() { + self = .active + } + } + + func alreadyConfigured0(promise: EventLoopPromise?) { + fatalError("Not implemented") + } + + public func localAddress0() throws -> SocketAddress { + guard let listener = self.nwListener else { + throw ChannelError.ioOnClosedChannel + } + + guard let localEndpoint = listener.parameters.requiredLocalEndpoint else { + throw NIOTSErrors.UnableToResolveEndpoint() + } + + var address = try SocketAddress(fromNWEndpoint: localEndpoint) + + // If we were asked to bind port 0, we need to update that. + if let port = address.port, port == 0 { + // We were. Let's ask Network.framework what we got. Nothing is an unacceptable answer. + guard let actualPort = listener.port else { + throw NIOTSErrors.UnableToResolveEndpoint() + } + address.newPort(actualPort.rawValue) + } + + return address + } + + public func remoteAddress0() throws -> SocketAddress { + throw ChannelError.operationUnsupported + } + + internal func beginActivating0(to target: NWEndpoint, promise: EventLoopPromise?) { + assert(self.nwListener == nil) + assert(self.bindPromise == nil) + self.bindPromise = promise + + let parameters = NWParameters(tls: self.tlsOptions, tcp: self.tcpOptions) + + // If we have a target that is not for a Bonjour service, we treat this as a request for + // a specific local endpoint. That gets configured on the parameters. If this is a bonjour + // endpoint, we deal with that later, though if it has requested a specific interface we + // set that now. + switch target { + case .hostPort, .unix: + parameters.requiredLocalEndpoint = target + case .service(_, _, _, let interface): + parameters.requiredInterface = interface + default: + // We can't use `@unknown default` and explicitly list cases we know about since they + // would require availability checks within the switch statement (`.url` was added in + // macOS 10.15). + () + } + + // Network.framework munges REUSEADDR and REUSEPORT together, so we turn this on if we need + // either or it's been explicitly set. + parameters.allowLocalEndpointReuse = self.reuseAddress || self.reusePort || self.allowLocalEndpointReuse + + parameters.includePeerToPeer = self.enablePeerToPeer + + let listener: NWListener + do { + listener = try NWListener(using: parameters) + } catch { + self.close0(error: error, mode: .all, promise: nil) + return + } + + if case .service(let name, let type, let domain, _) = target { + // Ok, now we deal with Bonjour. + listener.service = NWListener.Service(name: name, type: type, domain: domain) + } + + listener.stateUpdateHandler = self.stateUpdateHandler(newState:) + listener.newConnectionHandler = self.newConnectionHandler(connection:) + + // Ok, state is ready. Let's go! + self.nwListener = listener + listener.start(queue: self.connectionQueue) + } + + public func write0(_ data: NIOAny, promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + public func flush0() { + // Flush is not supported on listening channels. + } + + /// Perform a read from the network. + /// + /// This method has a slightly strange semantic, because we do not allow multiple reads at once. As a result, this + /// is a *request* to read, and if there is a read already being processed then this method will do nothing. + public func read0() { + // AutoRead is currently mandatory, so this method does nothing. + } + + public func doClose0(error: Error) { + // Step 1: tell the networking stack (if created) that we're done. + if let listener = self.nwListener { + listener.cancel() + } + + // Step 2: fail any pending bind promise. + if let pendingBind = self.bindPromise { + self.bindPromise = nil + pendingBind.fail(error) + } + } + + public func doHalfClose0(error: Error, promise: EventLoopPromise?) { + promise?.fail(ChannelError.operationUnsupported) + } + + public func triggerUserOutboundEvent0(_ event: Any, promise: EventLoopPromise?) { + switch event { + case let x as NIOTSNetworkEvents.BindToNWEndpoint: + self.bind0(to: x.endpoint, promise: promise) + default: + promise?.fail(ChannelError.operationUnsupported) + } + } + + public func channelRead0(_ data: NIOAny) { + self.eventLoop.assertInEventLoop() + + let channel = self.unwrapData(data, as: NIOTSConnectionChannel.self) + let p: EventLoopPromise = channel.eventLoop.makePromise() + channel.eventLoop.execute { + channel.registerAlreadyConfigured0(promise: p) + p.futureResult.whenFailure { (_: Error) in + channel.close(promise: nil) + } + } + } + + public func errorCaught0(error: Error) { + // Currently we don't do anything with errors that pass through the pipeline + return + } + + /// A function that will trigger a socket read if necessary. + internal func readIfNeeded0() { + // AutoRead is currently mandatory, so this does nothing. + } +} + + +// MARK:- Implementations of the callbacks passed to NWListener. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerChannel { + /// Called by the underlying `NWListener` when its internal state has changed. + private func stateUpdateHandler(newState: NWListener.State) { + switch newState { + case .setup: + preconditionFailure("Should not be told about this state.") + case .waiting: + break + case .ready: + // Transitioning to ready means the bind succeeded. Hooray! + self.bindComplete0() + case .cancelled: + // This is the network telling us we're closed. We don't need to actually do anything here + // other than check our state is ok. + assert(self.closed) + self.nwListener = nil + case .failed(let err): + // The connection has failed for some reason. + self.close0(error: err, mode: .all, promise: nil) + default: + // This clause is here to help the compiler out: it's otherwise not able to + // actually validate that the switch is exhaustive. Trust me, it is. + fatalError("Unreachable") + } + } + + /// Called by the underlying `NWListener` when a new connection has been received. + private func newConnectionHandler(connection: NWConnection) { + guard self.isActive else { + return + } + + let newChannel = NIOTSConnectionChannel(wrapping: connection, + on: self.childLoopGroup.next() as! NIOTSEventLoop, + parent: self, + qos: self.childChannelQoS, + tcpOptions: self.childTCPOptions, + tlsOptions: self.childTLSOptions) + + self.pipeline.fireChannelRead(NIOAny(newChannel)) + self.pipeline.fireChannelReadComplete() + } +} + + +// MARK:- Implementations of state management for the channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerChannel { + /// Make the channel active. + private func bindComplete0() { + let promise = self.bindPromise + self.bindPromise = nil + + // Before becoming active, update the cached addresses. Remote is always nil. + let localAddress = try? self.localAddress0() + + self._addressCacheLock.withLock { + self._addressCache = AddressCache(local: localAddress, remote: nil) + } + + self.becomeActive0(promise: promise) + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerChannel { + internal struct SynchronousOptions: NIOSynchronousChannelOptions { + private let channel: NIOTSListenerChannel + + fileprivate init(channel: NIOTSListenerChannel) { + self.channel = channel + } + + public func setOption(_ option: Option, value: Option.Value) throws { + try self.channel.setOption0(option: option, value: value) + } + + public func getOption(_ option: Option) throws -> Option.Value { + return try self.channel.getOption0(option: option) + } + } + + public var syncOptions: NIOSynchronousChannelOptions? { + return SynchronousOptions(channel: self) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSNetworkEvents.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSNetworkEvents.swift new file mode 100644 index 00000000..7fdd489c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/NIOTSNetworkEvents.swift @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Network +import NIOCore + +/// A tag protocol that can be used to cover all network events emitted by `NIOTS`. +/// +/// Users are strongly encouraged not to conform their own types to this protocol. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public protocol NIOTSNetworkEvent: Equatable { } + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +public enum NIOTSNetworkEvents { + /// This event is fired whenever the OS has informed NIO that there is a better + /// path available to the endpoint that this `Channel` is currently connected to, + /// e.g. the current connection is using an expensive cellular connection and + /// a cheaper WiFi connection has become available. + /// + /// If you can handle this event, you should make a new connection attempt, and then + /// transfer your work to that connection before closing this one. + public struct BetterPathAvailable: NIOTSNetworkEvent { } + + /// This event is fired when the OS has informed NIO that no better path to the + /// to the remote endpoint than the one currently being used by this `Channel` is + /// currently available. + public struct BetterPathUnavailable: NIOTSNetworkEvent { } + + /// This event is fired whenever the OS has informed NIO that a new path is in use + /// for this `Channel`. + public struct PathChanged: NIOTSNetworkEvent { + /// The new path for this `Channel`. + public let newPath: NWPath + + /// Create a new `PathChanged` event. + public init(newPath: NWPath) { + self.newPath = newPath + } + } + + /// This event is fired as an outbound event when NIO would like to ask Network.framework + /// to handle the connection logic (e.g. its own DNS resolution and happy eyeballs racing). + /// This is temporary workaround until NIO 2.0 which should allow us to use the regular + /// `Channel.connect` method instead. + public struct ConnectToNWEndpoint: NIOTSNetworkEvent { + /// The endpoint to which we want to connect. + public let endpoint: NWEndpoint + } + + /// This event is fired as an outbound event when NIO would like to ask Network.framework + /// to handle the binding logic (e.g. its own support for bonjour and interface selection). + /// This is temporary workaround until NIO 2.0 which should allow us to use the regular + /// `Channel.bind` method instead. + public struct BindToNWEndpoint: NIOTSNetworkEvent { + /// The endpoint to which we want to bind. + public let endpoint: NWEndpoint + } + + /// This event is fired when when the OS has informed NIO that it cannot immediately connect + /// to the remote endpoint, but that it is possible that changes in network conditions may + /// allow connection in future. This can occur in cases where the route is not currently + /// satisfiable (e.g. because airplane mode is on, or because the app is forbidden from using cellular) + /// but where a change in network state may allow the connection. + public struct WaitingForConnectivity: NIOTSNetworkEvent { + /// The reason the connection couldn't be established at this time. + /// + /// Note that these reasons are _not fatal_: applications are strongly advised not to treat them + /// as fatal, and instead to use them as information to inform UI decisions. + public var transientError: NWError + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/SocketAddress+NWEndpoint.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/SocketAddress+NWEndpoint.swift new file mode 100644 index 00000000..8e27b54b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/SocketAddress+NWEndpoint.swift @@ -0,0 +1,130 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Darwin +import Foundation +import NIOCore +import Network + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension IPv4Address { + /// Create an `IPv4Address` object from a `sockaddr_in`. + internal init(fromSockAddr sockAddr: sockaddr_in) { + var localAddr = sockAddr + self = withUnsafeBytes(of: &localAddr.sin_addr) { + precondition($0.count == 4) + let addrData = Data(bytes: $0.baseAddress!, count: $0.count) + return IPv4Address(addrData)! + } + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension IPv6Address { + internal init(fromSockAddr sockAddr: sockaddr_in6) { + var localAddr = sockAddr + + // TODO: We should check whether we can reliably pull an interface declaration out + // here to be more useful. + self = withUnsafeBytes(of: &localAddr.sin6_addr) { + precondition($0.count == 16) + let addrData = Data(bytes: $0.baseAddress!, count: $0.count) + return IPv6Address(addrData)! + } + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NWEndpoint { + /// Create an `NWEndpoint` value from a NIO `SocketAddress`. + internal init(fromSocketAddress socketAddress: SocketAddress) { + switch socketAddress { + case .unixDomainSocket(let uds): + var address = uds.address + let path: String = withUnsafeBytes(of: &address.sun_path) { ptr in + let ptr = ptr.baseAddress!.bindMemory(to: UInt8.self, capacity: 104) + return String(cString: ptr) + } + self = NWEndpoint.unix(path: path) + case .v4(let v4Addr): + let v4Address = IPv4Address(fromSockAddr: v4Addr.address) + let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))! + self = NWEndpoint.hostPort(host: .ipv4(v4Address), port: port) + case .v6(let v6Addr): + let v6Address = IPv6Address(fromSockAddr: v6Addr.address) + let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))! + self = NWEndpoint.hostPort(host: .ipv6(v6Address), port: port) + } + } +} + +// TODO: We'll want to get rid of this when we support returning NWEndpoint directly from +// the various address-handling functions. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension SocketAddress { + internal init(fromNWEndpoint endpoint: NWEndpoint) throws { + switch endpoint { + case .hostPort(.ipv4(let host), let port): + var addr = sockaddr_in() + addr.sin_family = sa_family_t(AF_INET) + addr.sin_len = UInt8(MemoryLayout.size) + addr.sin_port = port.rawValue.bigEndian + host.rawValue.withUnsafeBytes { + precondition($0.count == 4) + memcpy(&addr.sin_addr, $0.baseAddress!, 4) + } + self = .init(addr, host: host.debugDescription) + case .hostPort(.ipv6(let host), let port): + var addr = sockaddr_in6() + addr.sin6_family = sa_family_t(AF_INET6) + addr.sin6_port = port.rawValue.bigEndian + addr.sin6_len = UInt8(MemoryLayout.size) + host.rawValue.withUnsafeBytes { + precondition($0.count == 16) + memcpy(&addr.sin6_addr, $0.baseAddress!, 16) + } + self = .init(addr, host: host.debugDescription) + case .unix(let path): + self = try .init(unixDomainSocketPath: path) + case .service, .hostPort: + throw NIOTSErrors.UnableToResolveEndpoint() + default: + // We can't use `@unknown default` and explicitly list cases we know about since they + // would require availability checks within the switch statement (`.url` was added in + // macOS 10.15). + throw NIOTSErrors.UnableToResolveEndpoint() + } + } +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal extension SocketAddress { + /// Change the port on this `SocketAddress` to a new value. + mutating func newPort(_ port: UInt16) { + switch self { + case .v4(let addr): + var address = addr.address + address.sin_port = port.bigEndian + self = SocketAddress(address, host: addr.host) + case .v6(let addr): + var address = addr.address + address.sin6_port = port.bigEndian + self = SocketAddress(address, host: addr.host) + case .unixDomainSocket: + preconditionFailure("Cannot set new port on UDS") + } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/StateManagedChannel.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/StateManagedChannel.swift new file mode 100644 index 00000000..f79f0e48 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/StateManagedChannel.swift @@ -0,0 +1,274 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Foundation +import NIOCore +import NIOFoundationCompat +import NIOConcurrencyHelpers +import Dispatch +import Network + + +/// An object that conforms to this protocol represents the substate of a channel in the +/// active state. This can be used to provide more fine-grained tracking of states +/// within the active state of a channel. Example uses include for tracking TCP half-closure +/// state in a TCP stream channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal protocol ActiveChannelSubstate { + /// Create the substate in its default initial state. + init() +} + + +/// A state machine enum that tracks the state of the connection channel. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal enum ChannelState { + case idle + case registered + case activating + case active(ActiveSubstate) + case inactive + + /// Unlike every other one of these methods, this one has a side-effect. This is because + /// it's impossible to correctly be in the reigstered state without verifying that + /// registration has occurred. + fileprivate mutating func register(eventLoop: NIOTSEventLoop, channel: Channel) throws { + guard case .idle = self else { + throw NIOTSErrors.InvalidChannelStateTransition() + } + try eventLoop.register(channel) + self = .registered + } + + fileprivate mutating func beginActivating() throws { + guard case .registered = self else { + throw NIOTSErrors.InvalidChannelStateTransition() + } + self = .activating + } + + fileprivate mutating func becomeActive() throws { + guard case .activating = self else { + throw NIOTSErrors.InvalidChannelStateTransition() + } + self = .active(ActiveSubstate()) + } + + fileprivate mutating func becomeInactive() throws -> ChannelState { + let oldState = self + + switch self { + case .idle, .registered, .activating, .active: + self = .inactive + case .inactive: + // In this state we're already closed. + throw ChannelError.alreadyClosed + } + + return oldState + } +} + + +/// The kinds of activation that a channel may support. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal enum ActivationType { + case connect + case bind +} + + +/// A protocol for `Channel` implementations with a simple Network.framework +/// state management layer. +/// +/// This protocol provides default hooks for managing state appropriately for a +/// given channel. It also provides some default implementations of `Channel` methods +/// for simple behaviours. +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal protocol StateManagedChannel: Channel, ChannelCore { + associatedtype ActiveSubstate: ActiveChannelSubstate + + var state: ChannelState { get set } + + var isActive0: NIOAtomic { get set } + + var tsEventLoop: NIOTSEventLoop { get } + + var closePromise: EventLoopPromise { get } + + var supportedActivationType: ActivationType { get } + + func beginActivating0(to: NWEndpoint, promise: EventLoopPromise?) -> Void + + func becomeActive0(promise: EventLoopPromise?) -> Void + + func alreadyConfigured0(promise: EventLoopPromise?) -> Void + + func doClose0(error: Error) -> Void + + func doHalfClose0(error: Error, promise: EventLoopPromise?) -> Void + + func readIfNeeded0() -> Void +} + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension StateManagedChannel { + public var eventLoop: EventLoop { + return self.tsEventLoop + } + + /// Whether this channel is currently active. + public var isActive: Bool { + return self.isActive0.load() + } + + /// Whether this channel is currently closed. This is not necessary for the public + /// API, it's just a convenient helper. + internal var closed: Bool { + switch self.state { + case .inactive: + return true + case .idle, .registered, .activating, .active: + return false + } + } + + public func register0(promise: EventLoopPromise?) { + // TODO: does this need to do anything more than this? + do { + try self.state.register(eventLoop: self.tsEventLoop, channel: self) + self.pipeline.fireChannelRegistered() + promise?.succeed(()) + } catch { + promise?.fail(error) + self.close0(error: error, mode: .all, promise: nil) + } + } + + public func registerAlreadyConfigured0(promise: EventLoopPromise?) { + do { + try self.state.register(eventLoop: self.tsEventLoop, channel: self) + self.pipeline.fireChannelRegistered() + try self.state.beginActivating() + promise?.succeed(()) + } catch { + promise?.fail(error) + self.close0(error: error, mode: .all, promise: nil) + return + } + + // Ok, we are registered and ready to begin activating. Tell the channel: it must + // call becomeActive0 directly. + self.alreadyConfigured0(promise: promise) + } + + public func connect0(to address: SocketAddress, promise: EventLoopPromise?) { + self.activateWithType(type: .connect, to: NWEndpoint(fromSocketAddress: address), promise: promise) + } + + public func connect0(to endpoint: NWEndpoint, promise: EventLoopPromise?) { + self.activateWithType(type: .connect, to: endpoint, promise: promise) + } + + public func bind0(to address: SocketAddress, promise: EventLoopPromise?) { + self.activateWithType(type: .bind, to: NWEndpoint(fromSocketAddress: address), promise: promise) + } + + public func bind0(to endpoint: NWEndpoint, promise: EventLoopPromise?) { + self.activateWithType(type: .bind, to: endpoint, promise: promise) + } + + public func close0(error: Error, mode: CloseMode, promise: EventLoopPromise?) { + switch mode { + case .all: + let oldState: ChannelState + do { + oldState = try self.state.becomeInactive() + } catch let thrownError { + promise?.fail(thrownError) + return + } + + self.isActive0.store(false) + + self.doClose0(error: error) + + switch oldState { + case .active: + self.pipeline.fireChannelInactive() + fallthrough + case .registered, .activating: + self.tsEventLoop.deregister(self) + self.pipeline.fireChannelUnregistered() + case .idle: + // If this was already idle we don't have anything to do. + break + case .inactive: + preconditionFailure("Should be prevented by state machine") + } + + // Next we fire the promise passed to this method. + promise?.succeed(()) + + // Now we schedule our final cleanup. We need to keep the channel pipeline alive for at least one more event + // loop tick, as more work might be using it. + self.eventLoop.execute { + self.removeHandlers(pipeline: self.pipeline) + self.closePromise.succeed(()) + } + + case .input: + promise?.fail(ChannelError.operationUnsupported) + + case .output: + self.doHalfClose0(error: error, promise: promise) + } + } + + public func becomeActive0(promise: EventLoopPromise?) { + // Here we crash if we cannot transition our state. That's because my understanding is that we + // should not be able to hit this. + do { + try self.state.becomeActive() + } catch { + self.close0(error: error, mode: .all, promise: promise) + return + } + + self.isActive0.store(true) + promise?.succeed(()) + self.pipeline.fireChannelActive() + self.readIfNeeded0() + } + + /// A helper to handle the fact that activation is mostly common across connect and bind, and that both are + /// not supported by a single channel type. + private func activateWithType(type: ActivationType, to endpoint: NWEndpoint, promise: EventLoopPromise?) { + guard type == self.supportedActivationType else { + promise?.fail(ChannelError.operationUnsupported) + return + } + + do { + try self.state.beginActivating() + } catch { + promise?.fail(error) + return + } + + self.beginActivating0(to: endpoint, promise: promise) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/TCPOptions+SocketChannelOption.swift b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/TCPOptions+SocketChannelOption.swift new file mode 100644 index 00000000..666b7cf5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftNIOTransportServices/Sources/NIOTransportServices/TCPOptions+SocketChannelOption.swift @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if canImport(Network) +import Foundation +import NIOCore +import Network + +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +internal extension NWProtocolTCP.Options { + /// Apply a given channel `SocketOption` to this protocol options state. + func applyChannelOption(option: ChannelOptions.Types.SocketOption, value: SocketOptionValue) throws { + switch (option.level, option.name) { + case (IPPROTO_TCP, TCP_NODELAY): + self.noDelay = value != 0 + case (IPPROTO_TCP, TCP_NOPUSH): + self.noPush = value != 0 + case (IPPROTO_TCP, TCP_NOOPT): + self.noOptions = value != 0 + case (IPPROTO_TCP, TCP_KEEPCNT): + self.keepaliveCount = Int(value) + case (IPPROTO_TCP, TCP_KEEPALIVE): + self.keepaliveIdle = Int(value) + case (IPPROTO_TCP, TCP_KEEPINTVL): + self.keepaliveInterval = Int(value) + case (IPPROTO_TCP, TCP_MAXSEG): + self.maximumSegmentSize = Int(value) + case (IPPROTO_TCP, TCP_CONNECTIONTIMEOUT): + self.connectionTimeout = Int(value) + case (IPPROTO_TCP, TCP_RXT_CONNDROPTIME): + self.connectionDropTime = Int(value) + case (IPPROTO_TCP, TCP_RXT_FINDROP): + self.retransmitFinDrop = value != 0 + case (IPPROTO_TCP, TCP_SENDMOREACKS): + self.disableAckStretching = value != 0 + case (SOL_SOCKET, SO_KEEPALIVE): + self.enableKeepalive = value != 0 + default: + throw NIOTSErrors.UnsupportedSocketOption(optionValue: option) + } + } + + /// Obtain the given `SocketOption` value for this protocol options state. + func valueFor(socketOption option: ChannelOptions.Types.SocketOption) throws -> SocketOptionValue { + switch (option.level, option.name) { + case (IPPROTO_TCP, TCP_NODELAY): + return self.noDelay ? 1 : 0 + case (IPPROTO_TCP, TCP_NOPUSH): + return self.noPush ? 1 : 0 + case (IPPROTO_TCP, TCP_NOOPT): + return self.noOptions ? 1 : 0 + case (IPPROTO_TCP, TCP_KEEPCNT): + return Int32(self.keepaliveCount) + case (IPPROTO_TCP, TCP_KEEPALIVE): + return Int32(self.keepaliveIdle) + case (IPPROTO_TCP, TCP_KEEPINTVL): + return Int32(self.keepaliveInterval) + case (IPPROTO_TCP, TCP_MAXSEG): + return Int32(self.maximumSegmentSize) + case (IPPROTO_TCP, TCP_CONNECTIONTIMEOUT): + return Int32(self.connectionTimeout) + case (IPPROTO_TCP, TCP_RXT_CONNDROPTIME): + return Int32(self.connectionDropTime) + case (IPPROTO_TCP, TCP_RXT_FINDROP): + return self.retransmitFinDrop ? 1 : 0 + case (IPPROTO_TCP, TCP_SENDMOREACKS): + return self.disableAckStretching ? 1 : 0 + case (SOL_SOCKET, SO_KEEPALIVE): + return self.enableKeepalive ? 1 : 0 + default: + throw NIOTSErrors.UnsupportedSocketOption(optionValue: option) + } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/LICENSE.txt new file mode 100644 index 00000000..4b3ed032 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/LICENSE.txt @@ -0,0 +1,211 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/README.md new file mode 100644 index 00000000..9956ee09 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/README.md @@ -0,0 +1,303 @@ +Swift logo + +# Swift Protobuf + +**Welcome to Swift Protobuf!** + +[Apple's Swift programming language](https://swift.org/) is a perfect +complement to [Google's Protocol +Buffer](https://developers.google.com/protocol-buffers/) ("protobuf") serialization +technology. +They both emphasize high performance and programmer safety. + +This project provides both the command-line program that adds Swift +code generation to Google's `protoc` and the runtime library that is +necessary for using the generated code. +After using the protoc plugin to generate Swift code from your .proto +files, you will need to add this library to your project. + +[![Build and Test](https://github.com/apple/swift-protobuf/workflows/Build%20and%20Test/badge.svg)](https://github.com/apple/swift-protobuf/actions?query=workflow%3A%22Build+and+Test%22) +[![Check Upstream Protos](https://github.com/apple/swift-protobuf/workflows/Check%20Upstream%20Proto%20Files/badge.svg)](https://github.com/apple/swift-protobuf/actions?query=workflow%3A%22Check+Upstream+Proto+Files%22) +[![Run Conformance Tests](https://github.com/apple/swift-protobuf/workflows/Run%20Conformance%20Tests/badge.svg)](https://github.com/apple/swift-protobuf/actions?query=workflow%3A%22Run+Conformance+Tests%22) + +# Features of SwiftProtobuf + +SwiftProtobuf offers many advantages over alternative serialization +systems: + +* Safety: The protobuf code-generation system avoids the + errors that are common with hand-built serialization code. +* Correctness: SwiftProtobuf passes both its own extensive + test suite and Google's full conformance test for protobuf + correctness. +* Schema-driven: Defining your data structures in a separate + `.proto` schema file clearly documents your communications + conventions. +* Idiomatic: SwiftProtobuf takes full advantage of the Swift language. + In particular, all generated types provide full Swift copy-on-write + value semantics. +* Efficient binary serialization: The `.serializedData()` + method returns a `Data` with a compact binary form of your data. + You can deserialize the data using the `init(serializedData:)` + initializer. +* Standard JSON serialization: The `.jsonUTF8Data()` method returns a JSON + form of your data that can be parsed with the `init(jsonUTF8Data:)` + initializer. +* Hashable, Equatable: The generated struct can be put into a + `Set<>` or `Dictionary<>`. +* Performant: The binary and JSON serializers have been + extensively optimized. +* Extensible: You can add your own Swift extensions to any + of the generated types. + +Best of all, you can take the same `.proto` file and generate +Java, C++, Python, or Objective-C for use on other platforms. The +generated code for those languages will use the exact same +serialization and deserialization conventions as SwiftProtobuf, making +it easy to exchange serialized data in binary or JSON forms, with no +additional effort on your part. + +# Documentation + +More information is available in the associated documentation: + + * [Google's protobuf documentation](https://developers.google.com/protocol-buffers/) + provides general information about protocol buffers, the protoc compiler, + and how to use protocol buffers with C++, Java, and other languages. + * [PLUGIN.md](Documentation/PLUGIN.md) documents the `protoc-gen-swift` + plugin that adds Swift support to the `protoc` program + * [API.md](Documentation/API.md) documents how to use the generated code. + This is recommended reading for anyone using SwiftProtobuf in their + project. + * [cocoadocs.org](http://cocoadocs.org/docsets/SwiftProtobuf/) has the generated + API documentation + * [INTERNALS.md](Documentation/INTERNALS.md) documents the internal structure + of the generated code and the library. This + should only be needed by folks interested in working on SwiftProtobuf + itself. + * [STYLE_GUIDELINES.md](Documentation/STYLE_GUIDELINES.md) documents the style + guidelines we have adopted in our codebase if you are interested in + contributing + +# Getting Started + +If you've worked with Protocol Buffers before, adding Swift support is very +simple: you just need to build the `protoc-gen-swift` program and copy it into +your PATH. +The `protoc` program will find and use it automatically, allowing you +to build Swift sources for your proto files. +You will also, of course, need to add the SwiftProtobuf runtime library to +your project as explained below. + +## System Requirements + +To use Swift with Protocol buffers, you'll need: + +* A Swift 4.2 or later compiler (Xcode 10.0 or later). Support is included +for the Swift Package Manager; or using the included Xcode project. The Swift +protobuf project is being developed and tested against the latest release +version of Swift available from [Swift.org](https://swift.org) + +* Google's protoc compiler. The Swift protoc plugin is being actively +developed and tested against the latest protobuf sources. +The SwiftProtobuf tests need a version of protoc which supports the +`swift_prefix` option (introduced in protoc 3.2.0). +It may work with earlier versions of protoc. +You can get recent versions from +[Google's github repository](https://github.com/protocolbuffers/protobuf). + +## Building and Installing the Code Generator Plugin + +To translate `.proto` files into Swift, you will need both Google's +protoc compiler and the SwiftProtobuf code generator plugin. + +Building the plugin should be simple on any supported Swift platform: + +``` +$ git clone https://github.com/apple/swift-protobuf.git +$ cd swift-protobuf +``` + +Pick what released version of SwiftProtobuf you are going to use. You can get +a list of tags with: + +``` +$ git tag -l +``` + +Once you pick the version you will use, set your local state to match, and +build the protoc plugin: + +``` +$ git checkout tags/[tag_name] +$ swift build -c release +``` + +This will create a binary called `protoc-gen-swift` in the `.build/release` +directory. + +To install, just copy this one executable into a directory that is +part of your `PATH` environment variable. + +NOTE: The Swift runtime support is now included with macOS. If you are +using old Xcode versions or are on older system versions, you might need +to use also use `--static-swift-stdlib` with `swift build`. + +### Alternatively install via Homebrew + +If you prefer using [Homebrew](https://brew.sh): + +``` +$ brew install swift-protobuf +``` + +This will install `protoc` compiler and Swift code generator plugin. + +## Converting .proto files into Swift + +To generate Swift output for your .proto files, you run the `protoc` command as +usual, using the `--swift_out=` option: + +``` +$ protoc --swift_out=. my.proto +``` + +The `protoc` program will automatically look for `protoc-gen-swift` in your +`PATH` and use it. + +Each `.proto` input file will get translated to a corresponding `.pb.swift` +file in the output directory. + +More information about building and using `protoc-gen-swift` can be found +in the [detailed Plugin documentation](Documentation/PLUGIN.md). + +## Adding the SwiftProtobuf library to your project... + +To use the generated code, you need to include the `SwiftProtobuf` library +module in your project. How you do this will vary depending on how +you're building your project. Note that in all cases, we strongly recommend +that you use the version of the SwiftProtobuf library that corresponds to +the version of `protoc-gen-swift` you used to generate the code. + +### ...using `swift build` + +After copying the `.pb.swift` files into your project, you will need to add the +[SwiftProtobuf library](https://github.com/apple/swift-protobuf) to your +project to support the generated code. +If you are using the Swift Package Manager, add a dependency to your +`Package.swift` file and import the `SwiftProtobuf` library into the desired +targets. Adjust the `"1.6.0"` here to match the `[tag_name]` you used to build +the plugin above: + +```swift +dependencies: [ + .package(name: "SwiftProtobuf", url: "https://github.com/apple/swift-protobuf.git", from: "1.6.0"), +], +targets: [ + .target(name: "MyTarget", dependencies: ["SwiftProtobuf"]), +] +``` + +### ...using Xcode + +If you are using Xcode, then you should: + +* Add the `.pb.swift` source files generated from your protos directly to your + project +* Add the appropriate `SwiftProtobuf_` target from the Xcode project + in this package to your project. + +### ...using CocoaPods + +If you're using CocoaPods, add this to your `Podfile` adjusting the `:tag` to +match the `[tag_name]` you used to build the plugin above: + +```ruby +pod 'SwiftProtobuf', '~> 1.0' +``` + +And run `pod install`. + +NOTE: CocoaPods 1.7 or newer is required. + +### ...using Carthage + +If you're using Carthage, add this to your `Cartfile` but adjust the tag to match the `[tag_name]` you used to build the plugin above: + +```ruby +github "apple/swift-protobuf" ~> 1.0 +``` + +Run `carthage update` and drag `SwiftProtobuf.framework` into your Xcode.project. + +# Quick Start + +Once you have installed the code generator, used it to +generate Swift code from your `.proto` file, and +added the SwiftProtobuf library to your project, you can +just use the generated types as you would any other Swift +struct. + +For example, you might start with the following very simple +proto file: +```protobuf +syntax = "proto3"; + +message BookInfo { + int64 id = 1; + string title = 2; + string author = 3; +} +``` + +Then generate Swift code using: +``` +$ protoc --swift_out=. DataModel.proto +``` + +The generated code will expose a Swift property for +each of the proto fields as well as a selection +of serialization and deserialization capabilities: +```swift +// Create a BookInfo object and populate it: +var info = BookInfo() +info.id = 1734 +info.title = "Really Interesting Book" +info.author = "Jane Smith" + +// As above, but generating a read-only value: +let info2 = BookInfo.with { + $0.id = 1735 + $0.title = "Even More Interesting" + $0.author = "Jane Q. Smith" + } + +// Serialize to binary protobuf format: +let binaryData: Data = try info.serializedData() + +// Deserialize a received Data object from `binaryData` +let decodedInfo = try BookInfo(serializedData: binaryData) + +// Serialize to JSON format as a Data object +let jsonData: Data = try info.jsonUTF8Data() + +// Deserialize from JSON format from `jsonData` +let receivedFromJSON = try BookInfo(jsonUTF8Data: jsonData) +``` + +You can find more information in the detailed +[API Documentation](Documentation/API.md). + +## Report any issues + +If you run into problems, please send us a detailed report. +At a minimum, please include: + +* The specific operating system and version (for example, "macOS 10.12.1" or + "Ubuntu 16.10") +* The version of Swift you have installed (from `swift --version`) +* The version of the protoc compiler you are working with from + `protoc --version` +* The specific version of this source code (you can use `git log -1` to get the + latest commit ID) +* Any local changes you may have diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyMessageStorage.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyMessageStorage.swift new file mode 100644 index 00000000..754a3f06 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyMessageStorage.swift @@ -0,0 +1,497 @@ +// Sources/SwiftProtobuf/AnyMessageStorage.swift - Custom stroage for Any WKT +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Hand written storage class for Google_Protobuf_Any to support on demand +/// transforms between the formats. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +#if !swift(>=4.2) +private let i_2166136261 = Int(bitPattern: 2166136261) +private let i_16777619 = Int(16777619) +#endif + +fileprivate func serializeAnyJSON( + for message: Message, + typeURL: String, + options: JSONEncodingOptions +) throws -> String { + var visitor = try JSONEncodingVisitor(type: type(of: message), options: options) + visitor.startObject(message: message) + visitor.encodeField(name: "@type", stringValue: typeURL) + if let m = message as? _CustomJSONCodable { + let value = try m.encodedJSONString(options: options) + visitor.encodeField(name: "value", jsonText: value) + } else { + try message.traverse(visitor: &visitor) + } + visitor.endObject() + return visitor.stringResult +} + +fileprivate func emitVerboseTextForm(visitor: inout TextFormatEncodingVisitor, message: Message, typeURL: String) { + let url: String + if typeURL.isEmpty { + url = buildTypeURL(forMessage: message, typePrefix: defaultAnyTypeURLPrefix) + } else { + url = typeURL + } + visitor.visitAnyVerbose(value: message, typeURL: url) +} + +fileprivate func asJSONObject(body: Data) -> Data { + let asciiOpenCurlyBracket = UInt8(ascii: "{") + let asciiCloseCurlyBracket = UInt8(ascii: "}") + var result = Data([asciiOpenCurlyBracket]) + result.append(body) + result.append(asciiCloseCurlyBracket) + return result +} + +fileprivate func unpack(contentJSON: Data, + extensions: ExtensionMap, + options: JSONDecodingOptions, + as messageType: Message.Type) throws -> Message { + guard messageType is _CustomJSONCodable.Type else { + let contentJSONAsObject = asJSONObject(body: contentJSON) + return try messageType.init(jsonUTF8Data: contentJSONAsObject, extensions: extensions, options: options) + } + + var value = String() + try contentJSON.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if body.count > 0 { + // contentJSON will be the valid JSON for inside an object (everything but + // the '{' and '}', so minimal validation is needed. + var scanner = JSONScanner(source: body, options: options, extensions: extensions) + while !scanner.complete { + let key = try scanner.nextQuotedString() + try scanner.skipRequiredColon() + if key == "value" { + value = try scanner.skip() + break + } + if !options.ignoreUnknownFields { + // The only thing within a WKT should be "value". + throw AnyUnpackError.malformedWellKnownTypeJSON + } + let _ = try scanner.skip() + try scanner.skipRequiredComma() + } + if !options.ignoreUnknownFields && !scanner.complete { + // If that wasn't the end, then there was another key, and WKTs should + // only have the one when not skipping unknowns. + throw AnyUnpackError.malformedWellKnownTypeJSON + } + } + } + return try messageType.init(jsonString: value, extensions: extensions, options: options) +} + +internal class AnyMessageStorage { + // The two properties generated Google_Protobuf_Any will reference. + var _typeURL = String() + var _value: Data { + // Remapped to the internal `state`. + get { + switch state { + case .binary(let value): + return value + case .message(let message): + do { + return try message.serializedData(partial: true) + } catch { + return Data() + } + case .contentJSON(let contentJSON, let options): + guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else { + return Data() + } + do { + let m = try unpack(contentJSON: contentJSON, + extensions: SimpleExtensionMap(), + options: options, + as: messageType) + return try m.serializedData(partial: true) + } catch { + return Data() + } + } + } + set { + state = .binary(newValue) + } + } + + enum InternalState { + // a serialized binary + // Note: Unlike contentJSON below, binary does not bother to capture the + // decoding options. This is because the actual binary format is the binary + // blob, i.e. - when decoding from binary, the spec doesn't include decoding + // the binary blob, it is pass through. Instead there is a public api for + // unpacking that takes new options when a developer decides to decode it. + case binary(Data) + // a message + case message(Message) + // parsed JSON with the @type removed and the decoding options. + case contentJSON(Data, JSONDecodingOptions) + } + var state: InternalState = .binary(Data()) + + static let defaultInstance = AnyMessageStorage() + + private init() {} + + init(copying source: AnyMessageStorage) { + _typeURL = source._typeURL + state = source.state + } + + func isA(_ type: M.Type) -> Bool { + if _typeURL.isEmpty { + return false + } + let encodedType = typeName(fromURL: _typeURL) + return encodedType == M.protoMessageName + } + + // This is only ever called with the expectation that target will be fully + // replaced during the unpacking and never as a merge. + func unpackTo( + target: inout M, + extensions: ExtensionMap?, + options: BinaryDecodingOptions + ) throws { + guard isA(M.self) else { + throw AnyUnpackError.typeMismatch + } + + switch state { + case .binary(let data): + target = try M(serializedData: data, extensions: extensions, partial: true, options: options) + + case .message(let msg): + if let message = msg as? M { + // Already right type, copy it over. + target = message + } else { + // Different type, serialize and parse. + let data = try msg.serializedData(partial: true) + target = try M(serializedData: data, extensions: extensions, partial: true) + } + + case .contentJSON(let contentJSON, let options): + target = try unpack(contentJSON: contentJSON, + extensions: extensions ?? SimpleExtensionMap(), + options: options, + as: M.self) as! M + } + } + + // Called before the message is traversed to do any error preflights. + // Since traverse() will use _value, this is our chance to throw + // when _value can't. + func preTraverse() throws { + switch state { + case .binary: + // Nothing to be checked. + break + + case .message: + // When set from a developer provided message, partial support + // is done. Any message that comes in from another format isn't + // checked, and transcoding the isInitialized requirement is + // never inserted. + break + + case .contentJSON(let contentJSON, let options): + // contentJSON requires we have the type available for decoding + guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else { + throw BinaryEncodingError.anyTranscodeFailure + } + do { + // Decodes the full JSON and then discard the result. + // The regular traversal will decode this again by querying the + // `value` field, but that has no way to fail. As a result, + // we need this to accurately handle decode errors. + _ = try unpack(contentJSON: contentJSON, + extensions: SimpleExtensionMap(), + options: options, + as: messageType) + } catch { + throw BinaryEncodingError.anyTranscodeFailure + } + } + } +} + +/// Custom handling for Text format. +extension AnyMessageStorage { + func decodeTextFormat(typeURL url: String, decoder: inout TextFormatDecoder) throws { + // Decoding the verbose form requires knowing the type. + _typeURL = url + guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: url) else { + // The type wasn't registered, can't parse it. + throw TextFormatDecodingError.malformedText + } + let terminator = try decoder.scanner.skipObjectStart() + var subDecoder = try TextFormatDecoder(messageType: messageType, scanner: decoder.scanner, terminator: terminator) + if messageType == Google_Protobuf_Any.self { + var any = Google_Protobuf_Any() + try any.decodeTextFormat(decoder: &subDecoder) + state = .message(any) + } else { + var m = messageType.init() + try m.decodeMessage(decoder: &subDecoder) + state = .message(m) + } + decoder.scanner = subDecoder.scanner + if try decoder.nextFieldNumber() != nil { + // Verbose any can never have additional keys. + throw TextFormatDecodingError.malformedText + } + } + + // Specialized traverse for writing out a Text form of the Any. + // This prefers the more-legible "verbose" format if it can + // use it, otherwise will fall back to simpler forms. + internal func textTraverse(visitor: inout TextFormatEncodingVisitor) { + switch state { + case .binary(let valueData): + if let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) { + // If we can decode it, we can write the readable verbose form: + do { + let m = try messageType.init(serializedData: valueData, partial: true) + emitVerboseTextForm(visitor: &visitor, message: m, typeURL: _typeURL) + return + } catch { + // Fall through to just print the type and raw binary data + } + } + if !_typeURL.isEmpty { + try! visitor.visitSingularStringField(value: _typeURL, fieldNumber: 1) + } + if !valueData.isEmpty { + try! visitor.visitSingularBytesField(value: valueData, fieldNumber: 2) + } + + case .message(let msg): + emitVerboseTextForm(visitor: &visitor, message: msg, typeURL: _typeURL) + + case .contentJSON(let contentJSON, let options): + // If we can decode it, we can write the readable verbose form: + if let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) { + do { + let m = try unpack(contentJSON: contentJSON, + extensions: SimpleExtensionMap(), + options: options, + as: messageType) + emitVerboseTextForm(visitor: &visitor, message: m, typeURL: _typeURL) + return + } catch { + // Fall through to just print the raw JSON data + } + } + if !_typeURL.isEmpty { + try! visitor.visitSingularStringField(value: _typeURL, fieldNumber: 1) + } + // Build a readable form of the JSON: + let contentJSONAsObject = asJSONObject(body: contentJSON) + visitor.visitAnyJSONDataField(value: contentJSONAsObject) + } + } +} + +/// The obvious goal for Hashable/Equatable conformance would be for +/// hash and equality to behave as if we always decoded the inner +/// object and hashed or compared that. Unfortunately, Any typically +/// stores serialized contents and we don't always have the ability to +/// deserialize it. Since none of our supported serializations are +/// fully deterministic, we can't even ensure that equality will +/// behave this way when the Any contents are in the same +/// serialization. +/// +/// As a result, we can only really perform a "best effort" equality +/// test. Of course, regardless of the above, we must guarantee that +/// hashValue is compatible with equality. +extension AnyMessageStorage { +#if swift(>=4.2) + // Can't use _valueData for a few reasons: + // 1. Since decode is done on demand, two objects could be equal + // but created differently (one from JSON, one for Message, etc.), + // and the hash values have to be equal even if we don't have data + // yet. + // 2. map<> serialization order is undefined. At the time of writing + // the Swift, Objective-C, and Go runtimes all tend to have random + // orders, so the messages could be identical, but in binary form + // they could differ. + public func hash(into hasher: inout Hasher) { + if !_typeURL.isEmpty { + hasher.combine(_typeURL) + } + } +#else // swift(>=4.2) + var hashValue: Int { + var hash: Int = i_2166136261 + if !_typeURL.isEmpty { + hash = (hash &* i_16777619) ^ _typeURL.hashValue + } + return hash + } +#endif // swift(>=4.2) + + func isEqualTo(other: AnyMessageStorage) -> Bool { + if (_typeURL != other._typeURL) { + return false + } + + // Since the library does lazy Any decode, equality is a very hard problem. + // It things exactly match, that's pretty easy, otherwise, one ends up having + // to error on saying they aren't equal. + // + // The best option would be to have Message forms and compare those, as that + // removes issues like map<> serialization order, some other protocol buffer + // implementation details/bugs around serialized form order, etc.; but that + // would also greatly slow down equality tests. + // + // Do our best to compare what is present have... + + // If both have messages, check if they are the same. + if case .message(let myMsg) = state, case .message(let otherMsg) = other.state, type(of: myMsg) == type(of: otherMsg) { + // Since the messages are known to be same type, we can claim both equal and + // not equal based on the equality comparison. + return myMsg.isEqualTo(message: otherMsg) + } + + // If both have serialized data, and they exactly match; the messages are equal. + // Because there could be map in the message, the fact that the data isn't the + // same doesn't always mean the messages aren't equal. Likewise, the binary could + // have been created by a library that doesn't order the fields, or the binary was + // created using the appending ability in of the binary format. + if case .binary(let myValue) = state, case .binary(let otherValue) = other.state, myValue == otherValue { + return true + } + + // If both have contentJSON, and they exactly match; the messages are equal. + // Because there could be map in the message (or the JSON could just be in a different + // order), the fact that the JSON isn't the same doesn't always mean the messages + // aren't equal. + if case .contentJSON(let myJSON, _) = state, + case .contentJSON(let otherJSON, _) = other.state, + myJSON == otherJSON { + return true + } + + // Out of options. To do more compares, the states conversions would have to be + // done to do comparisions; and since equality can be used somewhat removed from + // a developer (if they put protos in a Set, use them as keys to a Dictionary, etc), + // the conversion cost might be to high for those uses. Give up and say they aren't equal. + return false + } +} + +// _CustomJSONCodable support for Google_Protobuf_Any +extension AnyMessageStorage { + // Override the traversal-based JSON encoding + // This builds an Any JSON representation from one of: + // * The message we were initialized with, + // * The JSON fields we last deserialized, or + // * The protobuf field we were deserialized from. + // The last case requires locating the type, deserializing + // into an object, then reserializing back to JSON. + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + switch state { + case .binary(let valueData): + // Follow the C++ protostream_objectsource.cc's + // ProtoStreamObjectSource::RenderAny() special casing of an empty value. + guard !valueData.isEmpty else { + if _typeURL.isEmpty { + return "{}" + } + var jsonEncoder = JSONEncoder() + jsonEncoder.startField(name: "@type") + jsonEncoder.putStringValue(value: _typeURL) + jsonEncoder.endObject() + return jsonEncoder.stringResult + } + // Transcode by decoding the binary data to a message object + // and then recode back into JSON. + guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else { + // If we don't have the type available, we can't decode the + // binary value, so we're stuck. (The Google spec does not + // provide a way to just package the binary value for someone + // else to decode later.) + throw JSONEncodingError.anyTranscodeFailure + } + let m = try messageType.init(serializedData: valueData, partial: true) + return try serializeAnyJSON(for: m, typeURL: _typeURL, options: options) + + case .message(let msg): + // We should have been initialized with a typeURL, but + // ensure it wasn't cleared. + let url = !_typeURL.isEmpty ? _typeURL : buildTypeURL(forMessage: msg, typePrefix: defaultAnyTypeURLPrefix) + return try serializeAnyJSON(for: msg, typeURL: url, options: options) + + case .contentJSON(let contentJSON, _): + var jsonEncoder = JSONEncoder() + jsonEncoder.startObject() + jsonEncoder.startField(name: "@type") + jsonEncoder.putStringValue(value: _typeURL) + if !contentJSON.isEmpty { + jsonEncoder.append(staticText: ",") + // NOTE: This doesn't really take `options` into account since it is + // just reflecting out what was taken in originally. + jsonEncoder.append(utf8Data: contentJSON) + } + jsonEncoder.endObject() + return jsonEncoder.stringResult + } + } + + // TODO: If the type is well-known or has already been registered, + // we should consider decoding eagerly. Eager decoding would + // catch certain errors earlier (good) but would probably be + // a performance hit if the Any contents were never accessed (bad). + // Of course, we can't always decode eagerly (we don't always have the + // message type available), so the deferred logic here is still needed. + func decodeJSON(from decoder: inout JSONDecoder) throws { + try decoder.scanner.skipRequiredObjectStart() + // Reset state + _typeURL = String() + state = .binary(Data()) + if decoder.scanner.skipOptionalObjectEnd() { + return + } + + var jsonEncoder = JSONEncoder() + while true { + let key = try decoder.scanner.nextQuotedString() + try decoder.scanner.skipRequiredColon() + if key == "@type" { + _typeURL = try decoder.scanner.nextQuotedString() + } else { + jsonEncoder.startField(name: key) + let keyValueJSON = try decoder.scanner.skip() + jsonEncoder.append(text: keyValueJSON) + } + if decoder.scanner.skipOptionalObjectEnd() { + // Capture the options, but set the messageDepthLimit to be what + // was left right now, as that is the limit when the JSON is finally + // parsed. + var updatedOptions = decoder.options + updatedOptions.messageDepthLimit = decoder.scanner.recursionBudget + state = .contentJSON(jsonEncoder.dataResult, updatedOptions) + return + } + try decoder.scanner.skipRequiredComma() + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyUnpackError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyUnpackError.swift new file mode 100644 index 00000000..738b0fe9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/AnyUnpackError.swift @@ -0,0 +1,37 @@ +// Sources/SwiftProtobuf/AnyUnpackError.swift - Any Unpacking Errors +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Errors that can be throw when unpacking a Google_Protobuf_Any. +/// +// ----------------------------------------------------------------------------- + +/// Describes errors that can occur when unpacking an `Google_Protobuf_Any` +/// message. +/// +/// `Google_Protobuf_Any` messages can be decoded from protobuf binary, text +/// format, or JSON. The contents are not parsed immediately; the raw data is +/// held in the `Google_Protobuf_Any` message until you `unpack()` it into a +/// message. At this time, any error can occur that might have occurred from a +/// regular decoding operation. There are also other errors that can occur due +/// to problems with the `Any` value's structure. +public enum AnyUnpackError: Error { + /// The `type_url` field in the `Google_Protobuf_Any` message did not match + /// the message type provided to the `unpack()` method. + case typeMismatch + + /// Well-known types being decoded from JSON must have only two fields: the + /// `@type` field and a `value` field containing the specialized JSON coding + /// of the well-known type. + case malformedWellKnownTypeJSON + + /// The `Google_Protobuf_Any` message was malformed in some other way not + /// covered by the other error cases. + case malformedAnyField +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecoder.swift new file mode 100644 index 00000000..d5b0ebc8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecoder.swift @@ -0,0 +1,1481 @@ +// Sources/SwiftProtobuf/BinaryDecoder.swift - Binary decoding +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Protobuf binary format decoding engine. +/// +/// This provides the Decoder interface that interacts directly +/// with the generated code. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +internal struct BinaryDecoder: Decoder { + // Current position + private var p : UnsafeRawPointer + // Remaining bytes in input. + private var available : Int + // Position of start of field currently being parsed + private var fieldStartP : UnsafeRawPointer + // Position of end of field currently being parsed, nil if we don't know. + private var fieldEndP : UnsafeRawPointer? + // Whether or not the field value has actually been parsed + private var consumed = true + // Wire format for last-examined field + internal var fieldWireFormat = WireFormat.varint + // Field number for last-parsed field tag + private var fieldNumber: Int = 0 + // Collection of extension fields for this decode + private var extensions: ExtensionMap? + // The current group number. See decodeFullGroup(group:fieldNumber:) for how + // this is used. + private var groupFieldNumber: Int? + // The options for decoding. + private var options: BinaryDecodingOptions + + private var recursionBudget: Int + + // Collects the unknown data found while decoding a message. + private var unknownData: Data? + // Custom data to use as the unknown data while parsing a field. Used only by + // packed repeated enums; see below + private var unknownOverride: Data? + + private var complete: Bool {return available == 0} + + internal init( + forReadingFrom pointer: UnsafeRawPointer, + count: Int, + options: BinaryDecodingOptions, + extensions: ExtensionMap? = nil + ) { + // Assuming baseAddress is not nil. + p = pointer + available = count + fieldStartP = p + self.extensions = extensions + self.options = options + recursionBudget = options.messageDepthLimit + } + + internal init( + forReadingFrom pointer: UnsafeRawPointer, + count: Int, + parent: BinaryDecoder + ) { + self.init(forReadingFrom: pointer, + count: count, + options: parent.options, + extensions: parent.extensions) + recursionBudget = parent.recursionBudget + } + + private mutating func incrementRecursionDepth() throws { + recursionBudget -= 1 + if recursionBudget < 0 { + throw BinaryDecodingError.messageDepthLimit + } + } + + private mutating func decrementRecursionDepth() { + recursionBudget += 1 + // This should never happen, if it does, something is probably corrupting memory, and + // simply throwing doesn't make much sense. + if recursionBudget > options.messageDepthLimit { + fatalError("Somehow BinaryDecoding unwound more objects than it started") + } + } + + internal mutating func handleConflictingOneOf() throws { + /// Protobuf simply allows conflicting oneof values to overwrite + } + + /// Return the next field number or nil if there are no more fields. + internal mutating func nextFieldNumber() throws -> Int? { + // Since this is called for every field, I've taken some pains + // to optimize it, including unrolling a tweaked version of + // the varint parser. + if fieldNumber > 0 { + if let override = unknownOverride { + assert(!options.discardUnknownFields) + assert(fieldWireFormat != .startGroup && fieldWireFormat != .endGroup) + if unknownData == nil { + unknownData = override + } else { + unknownData!.append(override) + } + unknownOverride = nil + } else if !consumed { + if options.discardUnknownFields { + try skip() + } else { + let u = try getRawField() + if unknownData == nil { + unknownData = u + } else { + unknownData!.append(u) + } + } + } + } + + // Quit if end of input + if available == 0 { + return nil + } + + // Get the next field number + fieldStartP = p + fieldEndP = nil + let start = p + let c0 = start[0] + if let wireFormat = WireFormat(rawValue: c0 & 7) { + fieldWireFormat = wireFormat + } else { + throw BinaryDecodingError.malformedProtobuf + } + if (c0 & 0x80) == 0 { + p += 1 + available -= 1 + fieldNumber = Int(c0) >> 3 + } else { + fieldNumber = Int(c0 & 0x7f) >> 3 + if available < 2 { + throw BinaryDecodingError.malformedProtobuf + } + let c1 = start[1] + if (c1 & 0x80) == 0 { + p += 2 + available -= 2 + fieldNumber |= Int(c1) << 4 + } else { + fieldNumber |= Int(c1 & 0x7f) << 4 + if available < 3 { + throw BinaryDecodingError.malformedProtobuf + } + let c2 = start[2] + fieldNumber |= Int(c2 & 0x7f) << 11 + if (c2 & 0x80) == 0 { + p += 3 + available -= 3 + } else { + if available < 4 { + throw BinaryDecodingError.malformedProtobuf + } + let c3 = start[3] + fieldNumber |= Int(c3 & 0x7f) << 18 + if (c3 & 0x80) == 0 { + p += 4 + available -= 4 + } else { + if available < 5 { + throw BinaryDecodingError.malformedProtobuf + } + let c4 = start[4] + if c4 > 15 { + throw BinaryDecodingError.malformedProtobuf + } + fieldNumber |= Int(c4 & 0x7f) << 25 + p += 5 + available -= 5 + } + } + } + } + if fieldNumber != 0 { + consumed = false + + if fieldWireFormat == .endGroup { + if groupFieldNumber == fieldNumber { + // Reached the end of the current group, single the + // end of the message. + return nil + } else { + // .endGroup when not in a group or for a different + // group is an invalid binary. + throw BinaryDecodingError.malformedProtobuf + } + } + return fieldNumber + } + throw BinaryDecodingError.malformedProtobuf + } + + internal mutating func decodeSingularFloatField(value: inout Float) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + try decodeFourByteNumber(value: &value) + consumed = true + } + + internal mutating func decodeSingularFloatField(value: inout Float?) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + value = try decodeFloat() + consumed = true + } + + internal mutating func decodeRepeatedFloatField(value: inout [Float]) throws { + switch fieldWireFormat { + case WireFormat.fixed32: + let i = try decodeFloat() + value.append(i) + consumed = true + case WireFormat.lengthDelimited: + let bodyBytes = try decodeVarint() + if bodyBytes > 0 { + let itemSize = UInt64(MemoryLayout.size) + let itemCount = bodyBytes / itemSize + if bodyBytes % itemSize != 0 || bodyBytes > available { + throw BinaryDecodingError.truncated + } + value.reserveCapacity(value.count + Int(truncatingIfNeeded: itemCount)) + for _ in 1...itemCount { + value.append(try decodeFloat()) + } + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularDoubleField(value: inout Double) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + value = try decodeDouble() + consumed = true + } + + internal mutating func decodeSingularDoubleField(value: inout Double?) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + value = try decodeDouble() + consumed = true + } + + internal mutating func decodeRepeatedDoubleField(value: inout [Double]) throws { + switch fieldWireFormat { + case WireFormat.fixed64: + let i = try decodeDouble() + value.append(i) + consumed = true + case WireFormat.lengthDelimited: + let bodyBytes = try decodeVarint() + if bodyBytes > 0 { + let itemSize = UInt64(MemoryLayout.size) + let itemCount = bodyBytes / itemSize + if bodyBytes % itemSize != 0 || bodyBytes > available { + throw BinaryDecodingError.truncated + } + value.reserveCapacity(value.count + Int(truncatingIfNeeded: itemCount)) + for _ in 1...itemCount { + let i = try decodeDouble() + value.append(i) + } + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularInt32Field(value: inout Int32) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = Int32(truncatingIfNeeded: varint) + consumed = true + } + + internal mutating func decodeSingularInt32Field(value: inout Int32?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = Int32(truncatingIfNeeded: varint) + consumed = true + } + + internal mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(Int32(truncatingIfNeeded: varint)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let varint = try decoder.decodeVarint() + value.append(Int32(truncatingIfNeeded: varint)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularInt64Field(value: inout Int64) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let v = try decodeVarint() + value = Int64(bitPattern: v) + consumed = true + } + + internal mutating func decodeSingularInt64Field(value: inout Int64?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = Int64(bitPattern: varint) + consumed = true + } + + internal mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(Int64(bitPattern: varint)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let varint = try decoder.decodeVarint() + value.append(Int64(bitPattern: varint)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularUInt32Field(value: inout UInt32) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = UInt32(truncatingIfNeeded: varint) + consumed = true + } + + internal mutating func decodeSingularUInt32Field(value: inout UInt32?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = UInt32(truncatingIfNeeded: varint) + consumed = true + } + + internal mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(UInt32(truncatingIfNeeded: varint)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let t = try decoder.decodeVarint() + value.append(UInt32(truncatingIfNeeded: t)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularUInt64Field(value: inout UInt64) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + value = try decodeVarint() + consumed = true + } + + internal mutating func decodeSingularUInt64Field(value: inout UInt64?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + value = try decodeVarint() + consumed = true + } + + internal mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(varint) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let t = try decoder.decodeVarint() + value.append(t) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularSInt32Field(value: inout Int32) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + let t = UInt32(truncatingIfNeeded: varint) + value = ZigZag.decoded(t) + consumed = true + } + + internal mutating func decodeSingularSInt32Field(value: inout Int32?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + let t = UInt32(truncatingIfNeeded: varint) + value = ZigZag.decoded(t) + consumed = true + } + + internal mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + let t = UInt32(truncatingIfNeeded: varint) + value.append(ZigZag.decoded(t)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let varint = try decoder.decodeVarint() + let t = UInt32(truncatingIfNeeded: varint) + value.append(ZigZag.decoded(t)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularSInt64Field(value: inout Int64) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = ZigZag.decoded(varint) + consumed = true + } + + internal mutating func decodeSingularSInt64Field(value: inout Int64?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + value = ZigZag.decoded(varint) + consumed = true + } + + internal mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(ZigZag.decoded(varint)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let varint = try decoder.decodeVarint() + value.append(ZigZag.decoded(varint)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularFixed32Field(value: inout UInt32) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + var i: UInt32 = 0 + try decodeFourByteNumber(value: &i) + value = UInt32(littleEndian: i) + consumed = true + } + + internal mutating func decodeSingularFixed32Field(value: inout UInt32?) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + var i: UInt32 = 0 + try decodeFourByteNumber(value: &i) + value = UInt32(littleEndian: i) + consumed = true + } + + internal mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws { + switch fieldWireFormat { + case WireFormat.fixed32: + var i: UInt32 = 0 + try decodeFourByteNumber(value: &i) + value.append(UInt32(littleEndian: i)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value.reserveCapacity(value.count + n / MemoryLayout.size) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + var i: UInt32 = 0 + while !decoder.complete { + try decoder.decodeFourByteNumber(value: &i) + value.append(UInt32(littleEndian: i)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularFixed64Field(value: inout UInt64) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + var i: UInt64 = 0 + try decodeEightByteNumber(value: &i) + value = UInt64(littleEndian: i) + consumed = true + } + + internal mutating func decodeSingularFixed64Field(value: inout UInt64?) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + var i: UInt64 = 0 + try decodeEightByteNumber(value: &i) + value = UInt64(littleEndian: i) + consumed = true + } + + internal mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws { + switch fieldWireFormat { + case WireFormat.fixed64: + var i: UInt64 = 0 + try decodeEightByteNumber(value: &i) + value.append(UInt64(littleEndian: i)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value.reserveCapacity(value.count + n / MemoryLayout.size) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + var i: UInt64 = 0 + while !decoder.complete { + try decoder.decodeEightByteNumber(value: &i) + value.append(UInt64(littleEndian: i)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularSFixed32Field(value: inout Int32) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + var i: Int32 = 0 + try decodeFourByteNumber(value: &i) + value = Int32(littleEndian: i) + consumed = true + } + + internal mutating func decodeSingularSFixed32Field(value: inout Int32?) throws { + guard fieldWireFormat == WireFormat.fixed32 else { + return + } + var i: Int32 = 0 + try decodeFourByteNumber(value: &i) + value = Int32(littleEndian: i) + consumed = true + } + + internal mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws { + switch fieldWireFormat { + case WireFormat.fixed32: + var i: Int32 = 0 + try decodeFourByteNumber(value: &i) + value.append(Int32(littleEndian: i)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value.reserveCapacity(value.count + n / MemoryLayout.size) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + var i: Int32 = 0 + while !decoder.complete { + try decoder.decodeFourByteNumber(value: &i) + value.append(Int32(littleEndian: i)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularSFixed64Field(value: inout Int64) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + var i: Int64 = 0 + try decodeEightByteNumber(value: &i) + value = Int64(littleEndian: i) + consumed = true + } + + internal mutating func decodeSingularSFixed64Field(value: inout Int64?) throws { + guard fieldWireFormat == WireFormat.fixed64 else { + return + } + var i: Int64 = 0 + try decodeEightByteNumber(value: &i) + value = Int64(littleEndian: i) + consumed = true + } + + internal mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws { + switch fieldWireFormat { + case WireFormat.fixed64: + var i: Int64 = 0 + try decodeEightByteNumber(value: &i) + value.append(Int64(littleEndian: i)) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value.reserveCapacity(value.count + n / MemoryLayout.size) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + var i: Int64 = 0 + while !decoder.complete { + try decoder.decodeEightByteNumber(value: &i) + value.append(Int64(littleEndian: i)) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularBoolField(value: inout Bool) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + value = try decodeVarint() != 0 + consumed = true + } + + internal mutating func decodeSingularBoolField(value: inout Bool?) throws { + guard fieldWireFormat == WireFormat.varint else { + return + } + value = try decodeVarint() != 0 + consumed = true + } + + internal mutating func decodeRepeatedBoolField(value: inout [Bool]) throws { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + value.append(varint != 0) + consumed = true + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !decoder.complete { + let t = try decoder.decodeVarint() + value.append(t != 0) + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularStringField(value: inout String) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + if let s = utf8ToString(bytes: p, count: n) { + value = s + consumed = true + } else { + throw BinaryDecodingError.invalidUTF8 + } + } + + internal mutating func decodeSingularStringField(value: inout String?) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + if let s = utf8ToString(bytes: p, count: n) { + value = s + consumed = true + } else { + throw BinaryDecodingError.invalidUTF8 + } + } + + internal mutating func decodeRepeatedStringField(value: inout [String]) throws { + switch fieldWireFormat { + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + if let s = utf8ToString(bytes: p, count: n) { + value.append(s) + consumed = true + } else { + throw BinaryDecodingError.invalidUTF8 + } + default: + return + } + } + + internal mutating func decodeSingularBytesField(value: inout Data) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value = Data(bytes: p, count: n) + consumed = true + } + + internal mutating func decodeSingularBytesField(value: inout Data?) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value = Data(bytes: p, count: n) + consumed = true + } + + internal mutating func decodeRepeatedBytesField(value: inout [Data]) throws { + switch fieldWireFormat { + case WireFormat.lengthDelimited: + var n: Int = 0 + let p = try getFieldBodyBytes(count: &n) + value.append(Data(bytes: p, count: n)) + consumed = true + default: + return + } + } + + internal mutating func decodeSingularEnumField(value: inout E?) throws where E.RawValue == Int { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { + value = v + consumed = true + } + } + + internal mutating func decodeSingularEnumField(value: inout E) throws where E.RawValue == Int { + guard fieldWireFormat == WireFormat.varint else { + return + } + let varint = try decodeVarint() + if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { + value = v + consumed = true + } + } + + internal mutating func decodeRepeatedEnumField(value: inout [E]) throws where E.RawValue == Int { + switch fieldWireFormat { + case WireFormat.varint: + let varint = try decodeVarint() + if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { + value.append(v) + consumed = true + } + case WireFormat.lengthDelimited: + var n: Int = 0 + var extras: [Int32]? + let p = try getFieldBodyBytes(count: &n) + let ints = Varint.countVarintsInBuffer(start: p, count: n) + value.reserveCapacity(value.count + ints) + var subdecoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) + while !subdecoder.complete { + let u64 = try subdecoder.decodeVarint() + let i32 = Int32(truncatingIfNeeded: u64) + if let v = E(rawValue: Int(i32)) { + value.append(v) + } else if !options.discardUnknownFields { + if extras == nil { + extras = [] + } + extras!.append(i32) + } + } + if let extras = extras { + let fieldTag = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let bodySize = extras.reduce(0) { $0 + Varint.encodedSize(of: Int64($1)) } + let fieldSize = Varint.encodedSize(of: fieldTag.rawValue) + Varint.encodedSize(of: Int64(bodySize)) + bodySize + var field = Data(count: fieldSize) + field.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var encoder = BinaryEncoder(forWritingInto: baseAddress) + encoder.startField(tag: fieldTag) + encoder.putVarInt(value: Int64(bodySize)) + for v in extras { + encoder.putVarInt(value: Int64(v)) + } + } + } + unknownOverride = field + } + consumed = true + default: + return + } + } + + internal mutating func decodeSingularMessageField(value: inout M?) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var count: Int = 0 + let p = try getFieldBodyBytes(count: &count) + if value == nil { + value = M() + } + var subDecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) + try subDecoder.decodeFullMessage(message: &value!) + consumed = true + } + + internal mutating func decodeRepeatedMessageField(value: inout [M]) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var count: Int = 0 + let p = try getFieldBodyBytes(count: &count) + var newValue = M() + var subDecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) + try subDecoder.decodeFullMessage(message: &newValue) + value.append(newValue) + consumed = true + } + + internal mutating func decodeFullMessage(message: inout M) throws { + assert(unknownData == nil) + try incrementRecursionDepth() + try message.decodeMessage(decoder: &self) + decrementRecursionDepth() + guard complete else { + throw BinaryDecodingError.trailingGarbage + } + if let unknownData = unknownData { + message.unknownFields.append(protobufData: unknownData) + } + } + + internal mutating func decodeSingularGroupField(value: inout G?) throws { + var group = value ?? G() + if try decodeFullGroup(group: &group, fieldNumber: fieldNumber) { + value = group + consumed = true + } + } + + internal mutating func decodeRepeatedGroupField(value: inout [G]) throws { + var group = G() + if try decodeFullGroup(group: &group, fieldNumber: fieldNumber) { + value.append(group) + consumed = true + } + } + + private mutating func decodeFullGroup(group: inout G, fieldNumber: Int) throws -> Bool { + guard fieldWireFormat == WireFormat.startGroup else { + return false + } + try incrementRecursionDepth() + + // This works by making a clone of the current decoder state and + // setting `groupFieldNumber` to signal `nextFieldNumber()` to watch + // for that as a marker for having reached the end of a group/message. + // Groups within groups works because this effectively makes a stack + // of decoders, each one looking for their ending tag. + + var subDecoder = self + subDecoder.groupFieldNumber = fieldNumber + // startGroup was read, so current tag/data is done (otherwise the + // startTag will end up in the unknowns of the first thing decoded). + subDecoder.consumed = true + // The group (message) doesn't get any existing unknown fields from + // the parent. + subDecoder.unknownData = nil + try group.decodeMessage(decoder: &subDecoder) + guard subDecoder.fieldNumber == fieldNumber && subDecoder.fieldWireFormat == .endGroup else { + throw BinaryDecodingError.truncated + } + if let groupUnknowns = subDecoder.unknownData { + group.unknownFields.append(protobufData: groupUnknowns) + } + // Advance over what was parsed. + consume(length: available - subDecoder.available) + assert(recursionBudget == subDecoder.recursionBudget) + decrementRecursionDepth() + return true + } + + internal mutating func decodeMapField(fieldType: _ProtobufMap.Type, value: inout _ProtobufMap.BaseType) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var k: KeyType.BaseType? + var v: ValueType.BaseType? + var count: Int = 0 + let p = try getFieldBodyBytes(count: &count) + var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) + while let tag = try subdecoder.getTag() { + if tag.wireFormat == .endGroup { + throw BinaryDecodingError.malformedProtobuf + } + let fieldNumber = tag.fieldNumber + switch fieldNumber { + case 1: + try KeyType.decodeSingular(value: &k, from: &subdecoder) + case 2: + try ValueType.decodeSingular(value: &v, from: &subdecoder) + default: // Skip any other fields within the map entry object + try subdecoder.skip() + } + } + if !subdecoder.complete { + throw BinaryDecodingError.trailingGarbage + } + // A map<> definition can't provide a default value for the keys/values, + // so it is safe to use the proto3 default to get the right + // integer/string/bytes. The one catch is a proto2 enum (which can be the + // value) can have a non zero value, but that case is the next + // custom decodeMapField<>() method and handles it. + value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType.proto3DefaultValue + consumed = true + } + + internal mutating func decodeMapField(fieldType: _ProtobufEnumMap.Type, value: inout _ProtobufEnumMap.BaseType) throws where ValueType.RawValue == Int { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var k: KeyType.BaseType? + var v: ValueType? + var count: Int = 0 + let p = try getFieldBodyBytes(count: &count) + var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) + while let tag = try subdecoder.getTag() { + if tag.wireFormat == .endGroup { + throw BinaryDecodingError.malformedProtobuf + } + let fieldNumber = tag.fieldNumber + switch fieldNumber { + case 1: // Keys are basic types + try KeyType.decodeSingular(value: &k, from: &subdecoder) + case 2: // Value is an Enum type + try subdecoder.decodeSingularEnumField(value: &v) + if v == nil && tag.wireFormat == .varint { + // Enum decode fail and wire format was varint, so this had to + // have been a proto2 unknown enum value. This whole map entry + // into the parent message's unknown fields. If the wire format + // was wrong, treat it like an unknown field and drop it with + // the map entry. + return + } + default: // Skip any other fields within the map entry object + try subdecoder.skip() + } + } + if !subdecoder.complete { + throw BinaryDecodingError.trailingGarbage + } + // A map<> definition can't provide a default value for the keys, so it + // is safe to use the proto3 default to get the right integer/string/bytes. + value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType() + consumed = true + } + + internal mutating func decodeMapField(fieldType: _ProtobufMessageMap.Type, value: inout _ProtobufMessageMap.BaseType) throws { + guard fieldWireFormat == WireFormat.lengthDelimited else { + return + } + var k: KeyType.BaseType? + var v: ValueType? + var count: Int = 0 + let p = try getFieldBodyBytes(count: &count) + var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) + while let tag = try subdecoder.getTag() { + if tag.wireFormat == .endGroup { + throw BinaryDecodingError.malformedProtobuf + } + let fieldNumber = tag.fieldNumber + switch fieldNumber { + case 1: // Keys are basic types + try KeyType.decodeSingular(value: &k, from: &subdecoder) + case 2: // Value is a message type + try subdecoder.decodeSingularMessageField(value: &v) + default: // Skip any other fields within the map entry object + try subdecoder.skip() + } + } + if !subdecoder.complete { + throw BinaryDecodingError.trailingGarbage + } + // A map<> definition can't provide a default value for the keys, so it + // is safe to use the proto3 default to get the right integer/string/bytes. + value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType() + consumed = true + } + + internal mutating func decodeExtensionField( + values: inout ExtensionFieldValueSet, + messageType: Message.Type, + fieldNumber: Int + ) throws { + if let ext = extensions?[messageType, fieldNumber] { + try decodeExtensionField(values: &values, + messageType: messageType, + fieldNumber: fieldNumber, + messageExtension: ext) + } + } + + /// Helper to reuse between Extension decoding and MessageSet Extension decoding. + private mutating func decodeExtensionField( + values: inout ExtensionFieldValueSet, + messageType: Message.Type, + fieldNumber: Int, + messageExtension ext: AnyMessageExtension + ) throws { + assert(!consumed) + assert(fieldNumber == ext.fieldNumber) + + try values.modify(index: fieldNumber) { fieldValue in + // Message/Group extensions both will call back into the matching + // decode methods, so the recursion depth will be tracked there. + if fieldValue != nil { + try fieldValue!.decodeExtensionField(decoder: &self) + } else { + fieldValue = try ext._protobuf_newField(decoder: &self) + } + if consumed && fieldValue == nil { + // Really things should never get here, if the decoder says + // the bytes were consumed, then there should have been a + // field that consumed them (existing or created). This + // specific error result is to allow this to be more detectable. + throw BinaryDecodingError.internalExtensionError + } + } + } + + internal mutating func decodeExtensionFieldsAsMessageSet( + values: inout ExtensionFieldValueSet, + messageType: Message.Type + ) throws { + // Spin looking for the Item group, everything else will end up in unknown fields. + while let fieldNumber = try self.nextFieldNumber() { + guard fieldNumber == WireFormat.MessageSet.FieldNumbers.item && + fieldWireFormat == WireFormat.startGroup else { + continue + } + + // This is similiar to decodeFullGroup + + try incrementRecursionDepth() + var subDecoder = self + subDecoder.groupFieldNumber = fieldNumber + subDecoder.consumed = true + + let itemResult = try subDecoder.decodeMessageSetItem(values: &values, + messageType: messageType) + switch itemResult { + case .success: + // Advance over what was parsed. + consume(length: available - subDecoder.available) + consumed = true + case .handleAsUnknown: + // Nothing to do. + break + + case .malformed: + throw BinaryDecodingError.malformedProtobuf + } + + assert(recursionBudget == subDecoder.recursionBudget) + decrementRecursionDepth() + } + } + + private enum DecodeMessageSetItemResult { + case success + case handleAsUnknown + case malformed + } + + private mutating func decodeMessageSetItem( + values: inout ExtensionFieldValueSet, + messageType: Message.Type + ) throws -> DecodeMessageSetItemResult { + // This is loosely based on the C++: + // ExtensionSet::ParseMessageSetItem() + // WireFormat::ParseAndMergeMessageSetItem() + // (yes, there have two versions that are almost the same) + + var msgExtension: AnyMessageExtension? + var fieldData: Data? + + // In this loop, if wire types are wrong, things don't decode, + // just bail instead of letting things go into unknown fields. + // Wrongly formed MessageSets don't seem don't have real + // spelled out behaviors. + while let fieldNumber = try self.nextFieldNumber() { + switch fieldNumber { + case WireFormat.MessageSet.FieldNumbers.typeId: + var extensionFieldNumber: Int32 = 0 + try decodeSingularInt32Field(value: &extensionFieldNumber) + if extensionFieldNumber == 0 { return .malformed } + guard let ext = extensions?[messageType, Int(extensionFieldNumber)] else { + return .handleAsUnknown // Unknown extension. + } + msgExtension = ext + + // If there already was fieldData, decode it. + if let data = fieldData { + var wasDecoded = false + try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var extDecoder = BinaryDecoder(forReadingFrom: baseAddress, + count: body.count, + parent: self) + // Prime the decode to be correct. + extDecoder.consumed = false + extDecoder.fieldWireFormat = .lengthDelimited + try extDecoder.decodeExtensionField(values: &values, + messageType: messageType, + fieldNumber: fieldNumber, + messageExtension: ext) + wasDecoded = extDecoder.consumed + } + } + if !wasDecoded { + return .malformed + } + fieldData = nil + } + + case WireFormat.MessageSet.FieldNumbers.message: + if let ext = msgExtension { + assert(consumed == false) + try decodeExtensionField(values: &values, + messageType: messageType, + fieldNumber: ext.fieldNumber, + messageExtension: ext) + if !consumed { + return .malformed + } + } else { + // The C++ references ends up appending the blocks together as length + // delimited blocks, but the parsing will only use the first block. + // So just capture a block, and then skip any others that happen to + // be found. + if fieldData == nil { + var d: Data? + try decodeSingularBytesField(value: &d) + guard let data = d else { return .malformed } + // Save it as length delimited + let payloadSize = Varint.encodedSize(of: Int64(data.count)) + data.count + var payload = Data(count: payloadSize) + payload.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var encoder = BinaryEncoder(forWritingInto: baseAddress) + encoder.putBytesValue(value: data) + } + } + fieldData = payload + } else { + guard fieldWireFormat == .lengthDelimited else { return .malformed } + try skip() + consumed = true + } + } + + default: + // Skip everything else + try skip() + consumed = true + } + } + + return .success + } + + // + // Private building blocks for the parsing above. + // + // Having these be private gives the compiler maximum latitude for + // inlining. + // + + /// Private: Advance the current position. + private mutating func consume(length: Int) { + available -= length + p += length + } + + /// Private: Skip the body for the given tag. If the given tag is + /// a group, it parses up through the corresponding group end. + private mutating func skipOver(tag: FieldTag) throws { + switch tag.wireFormat { + case .varint: + // Don't need the value, just ensuring it is validly encoded. + let _ = try decodeVarint() + case .fixed64: + if available < 8 { + throw BinaryDecodingError.truncated + } + p += 8 + available -= 8 + case .lengthDelimited: + let n = try decodeVarint() + if n <= UInt64(available) { + p += Int(n) + available -= Int(n) + } else { + throw BinaryDecodingError.truncated + } + case .startGroup: + try incrementRecursionDepth() + while true { + if let innerTag = try getTagWithoutUpdatingFieldStart() { + if innerTag.wireFormat == .endGroup { + if innerTag.fieldNumber == tag.fieldNumber { + decrementRecursionDepth() + break + } else { + // .endGroup for a something other than the current + // group is an invalid binary. + throw BinaryDecodingError.malformedProtobuf + } + } else { + try skipOver(tag: innerTag) + } + } else { + throw BinaryDecodingError.truncated + } + } + case .endGroup: + throw BinaryDecodingError.malformedProtobuf + case .fixed32: + if available < 4 { + throw BinaryDecodingError.truncated + } + p += 4 + available -= 4 + } + } + + /// Private: Skip to the end of the current field. + /// + /// Assumes that fieldStartP was bookmarked by a previous + /// call to getTagType(). + /// + /// On exit, fieldStartP points to the first byte of the tag, fieldEndP points + /// to the first byte after the field contents, and p == fieldEndP. + private mutating func skip() throws { + if let end = fieldEndP { + p = end + } else { + // Rewind to start of current field. + available += p - fieldStartP + p = fieldStartP + guard let tag = try getTagWithoutUpdatingFieldStart() else { + throw BinaryDecodingError.truncated + } + try skipOver(tag: tag) + fieldEndP = p + } + } + + /// Private: Parse the next raw varint from the input. + private mutating func decodeVarint() throws -> UInt64 { + if available < 1 { + throw BinaryDecodingError.truncated + } + var start = p + var length = available + var c = start.load(fromByteOffset: 0, as: UInt8.self) + start += 1 + length -= 1 + if c & 0x80 == 0 { + p = start + available = length + return UInt64(c) + } + var value = UInt64(c & 0x7f) + var shift = UInt64(7) + while true { + if length < 1 || shift > 63 { + throw BinaryDecodingError.malformedProtobuf + } + c = start.load(fromByteOffset: 0, as: UInt8.self) + start += 1 + length -= 1 + value |= UInt64(c & 0x7f) << shift + if c & 0x80 == 0 { + p = start + available = length + return value + } + shift += 7 + } + } + + /// Private: Get the tag that starts a new field. + /// This also bookmarks the start of field for a possible skip(). + internal mutating func getTag() throws -> FieldTag? { + fieldStartP = p + fieldEndP = nil + return try getTagWithoutUpdatingFieldStart() + } + + /// Private: Parse and validate the next tag without + /// bookmarking the start of the field. This is used within + /// skip() to skip over fields within a group. + private mutating func getTagWithoutUpdatingFieldStart() throws -> FieldTag? { + if available < 1 { + return nil + } + let t = try decodeVarint() + if t < UInt64(UInt32.max) { + guard let tag = FieldTag(rawValue: UInt32(truncatingIfNeeded: t)) else { + throw BinaryDecodingError.malformedProtobuf + } + fieldWireFormat = tag.wireFormat + fieldNumber = tag.fieldNumber + return tag + } else { + throw BinaryDecodingError.malformedProtobuf + } + } + + /// Private: Return a Data containing the entirety of + /// the current field, including tag. + private mutating func getRawField() throws -> Data { + try skip() + return Data(bytes: fieldStartP, count: fieldEndP! - fieldStartP) + } + + /// Private: decode a fixed-length four-byte number. This generic + /// helper handles all four-byte number types. + private mutating func decodeFourByteNumber(value: inout T) throws { + guard available >= 4 else {throw BinaryDecodingError.truncated} + withUnsafeMutableBytes(of: &value) { dest -> Void in + dest.copyMemory(from: UnsafeRawBufferPointer(start: p, count: 4)) + } + consume(length: 4) + } + + /// Private: decode a fixed-length eight-byte number. This generic + /// helper handles all eight-byte number types. + private mutating func decodeEightByteNumber(value: inout T) throws { + guard available >= 8 else {throw BinaryDecodingError.truncated} + withUnsafeMutableBytes(of: &value) { dest -> Void in + dest.copyMemory(from: UnsafeRawBufferPointer(start: p, count: 8)) + } + consume(length: 8) + } + + private mutating func decodeFloat() throws -> Float { + var littleEndianBytes: UInt32 = 0 + try decodeFourByteNumber(value: &littleEndianBytes) + var nativeEndianBytes = UInt32(littleEndian: littleEndianBytes) + var float: Float = 0 + let n = MemoryLayout.size + memcpy(&float, &nativeEndianBytes, n) + return float + } + + private mutating func decodeDouble() throws -> Double { + var littleEndianBytes: UInt64 = 0 + try decodeEightByteNumber(value: &littleEndianBytes) + var nativeEndianBytes = UInt64(littleEndian: littleEndianBytes) + var double: Double = 0 + let n = MemoryLayout.size + memcpy(&double, &nativeEndianBytes, n) + return double + } + + /// Private: Get the start and length for the body of + // a length-delimited field. + private mutating func getFieldBodyBytes(count: inout Int) throws -> UnsafeRawPointer { + let length = try decodeVarint() + if length <= UInt64(available) { + count = Int(length) + let body = p + consume(length: count) + return body + } + throw BinaryDecodingError.truncated + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingError.swift new file mode 100644 index 00000000..016d8ad7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingError.swift @@ -0,0 +1,44 @@ +// Sources/SwiftProtobuf/BinaryDecodingError.swift - Protobuf binary decoding errors +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Protobuf binary format decoding errors +/// +// ----------------------------------------------------------------------------- + +/// Describes errors that can occur when decoding a message from binary format. +public enum BinaryDecodingError: Error { + /// Extraneous data remained after decoding should have been complete. + case trailingGarbage + + /// The decoder unexpectedly reached the end of the data before it was + /// expected. + case truncated + + /// A string field was not encoded as valid UTF-8. + case invalidUTF8 + + /// The binary data was malformed in some way, such as an invalid wire format + /// or field tag. + case malformedProtobuf + + /// The definition of the message or one of its nested messages has required + /// fields but the binary data did not include values for them. You must pass + /// `partial: true` during decoding if you wish to explicitly ignore missing + /// required fields. + case missingRequiredFields + + /// An internal error happened while decoding. If this is ever encountered, + /// please file an issue with SwiftProtobuf with as much details as possible + /// for what happened (proto definitions, bytes being decoded (if possible)). + case internalExtensionError + + /// Reached the nesting limit for messages within messages while decoding. + case messageDepthLimit +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingOptions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingOptions.swift new file mode 100644 index 00000000..f00d6502 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDecodingOptions.swift @@ -0,0 +1,39 @@ +// Sources/SwiftProtobuf/BinaryDecodingOptions.swift - Binary decoding options +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Binary decoding options +/// +// ----------------------------------------------------------------------------- + +/// Options for binary decoding. +public struct BinaryDecodingOptions { + /// The maximum nesting of message with messages. The default is 100. + /// + /// To prevent corrupt or malicious messages from causing stack overflows, + /// this controls how deep messages can be nested within other messages + /// while parsing. + public var messageDepthLimit: Int = 100 + + /// Discard unknown fields while parsing. The default is false, so parsering + /// does not discard unknown fields. + /// + /// The Protobuf binary format allows unknown fields to be still parsed + /// so the schema can be expanded without requiring all readers to be updated. + /// This works in part by haivng any unknown fields preserved so they can + /// be relayed on without loss. For a while the proto3 syntax definition + /// called for unknown fields to be dropped, but that lead to problems in + /// some case. The default is to follow the spec and keep them, but setting + /// this option to `true` allows a developer to strip them during a parse + /// in case they have a specific need to drop the unknown fields from the + /// object graph being created. + public var discardUnknownFields: Bool = false + + public init() {} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDelimited.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDelimited.swift new file mode 100644 index 00000000..10eaf052 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryDelimited.swift @@ -0,0 +1,234 @@ +// Sources/SwiftProtobuf/BinaryDelimited.swift - Delimited support +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Helpers to read/write message with a length prefix. +/// +// ----------------------------------------------------------------------------- + +#if !os(WASI) +import Foundation + +/// Helper methods for reading/writing messages with a length prefix. +public enum BinaryDelimited { + /// Additional errors for delimited message handing. + public enum Error: Swift.Error { + /// If a read/write to the stream fails, but the stream's `streamError` is nil, + /// this error will be throw instead since the stream didn't provide anything + /// more specific. A common cause for this can be failing to open the stream + /// before trying to read/write to it. + case unknownStreamError + + /// While reading/writing to the stream, less than the expected bytes was + /// read/written. + case truncated + } + + /// Serialize a single size-delimited message from the given stream. Delimited + /// format allows a single file or stream to contain multiple messages, + /// whereas normally writing multiple non-delimited messages to the same + /// stream would cause them to be merged. A delimited message is a varint + /// encoding the message size followed by a message of exactly that size. + /// + /// - Parameters: + /// - message: The message to be written. + /// - to: The `OutputStream` to write the message to. The stream is + /// is assumed to be ready to be written to. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - Throws: `BinaryEncodingError` if encoding fails, throws + /// `BinaryDelimited.Error` for some writing errors, or the + /// underlying `OutputStream.streamError` for a stream error. + public static func serialize( + message: Message, + to stream: OutputStream, + partial: Bool = false + ) throws { + // TODO: Revisit to avoid the extra buffering when encoding is streamed in general. + let serialized = try message.serializedData(partial: partial) + let totalSize = Varint.encodedSize(of: UInt64(serialized.count)) + serialized.count + var data = Data(count: totalSize) + data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var encoder = BinaryEncoder(forWritingInto: baseAddress) + encoder.putBytesValue(value: serialized) + } + } + + var written: Int = 0 + data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + // This assumingMemoryBound is technically unsafe, but without SR-11078 + // (https://bugs.swift.org/browse/SR-11087) we don't have another option. + // It should be "safe enough". + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + written = stream.write(pointer, maxLength: totalSize) + } + } + + if written != totalSize { + if written == -1 { + if let streamError = stream.streamError { + throw streamError + } + throw BinaryDelimited.Error.unknownStreamError + } + throw BinaryDelimited.Error.truncated + } + } + + /// Reads a single size-delimited message from the given stream. Delimited + /// format allows a single file or stream to contain multiple messages, + /// whereas normally parsing consumes the entire input. A delimited message + /// is a varint encoding the message size followed by a message of exactly + /// exactly that size. + /// + /// - Parameters: + /// - messageType: The type of message to read. + /// - from: The `InputStream` to read the data from. The stream is assumed + /// to be ready to read from. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Returns: The message read. + /// - Throws: `BinaryDecodingError` if decoding fails, throws + /// `BinaryDelimited.Error` for some reading errors, and the + /// underlying InputStream.streamError for a stream error. + public static func parse( + messageType: M.Type, + from stream: InputStream, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws -> M { + var message = M() + try merge(into: &message, + from: stream, + extensions: extensions, + partial: partial, + options: options) + return message + } + + /// Updates the message by reading a single size-delimited message from + /// the given stream. Delimited format allows a single file or stream to + /// contain multiple messages, whereas normally parsing consumes the entire + /// input. A delimited message is a varint encoding the message size + /// followed by a message of exactly that size. + /// + /// - Note: If this method throws an error, the message may still have been + /// partially mutated by the binary data that was decoded before the error + /// occurred. + /// + /// - Parameters: + /// - mergingTo: The message to merge the data into. + /// - from: The `InputStream` to read the data from. The stream is assumed + /// to be ready to read from. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Throws: `BinaryDecodingError` if decoding fails, throws + /// `BinaryDelimited.Error` for some reading errors, and the + /// underlying InputStream.streamError for a stream error. + public static func merge( + into message: inout M, + from stream: InputStream, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { + let length = try Int(decodeVarint(stream)) + if length == 0 { + // The message was all defaults, nothing to actually read. + return + } + + var data = Data(count: length) + var bytesRead: Int = 0 + data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + // This assumingMemoryBound is technically unsafe, but without SR-11078 + // (https://bugs.swift.org/browse/SR-11087) we don't have another option. + // It should be "safe enough". + let pointer = baseAddress.assumingMemoryBound(to: UInt8.self) + bytesRead = stream.read(pointer, maxLength: length) + } + } + + if bytesRead != length { + if bytesRead == -1 { + if let streamError = stream.streamError { + throw streamError + } + throw BinaryDelimited.Error.unknownStreamError + } + throw BinaryDelimited.Error.truncated + } + + try message.merge(serializedData: data, + extensions: extensions, + partial: partial, + options: options) + } +} + +// TODO: This should go away when encoding/decoding are more stream based +// as that should provide a more direct way to do this. This is basically +// a rewrite of BinaryDecoder.decodeVarint(). +internal func decodeVarint(_ stream: InputStream) throws -> UInt64 { + + // Buffer to reuse within nextByte. + let readBuffer = UnsafeMutablePointer.allocate(capacity: 1) + #if swift(>=4.1) + defer { readBuffer.deallocate() } + #else + defer { readBuffer.deallocate(capacity: 1) } + #endif + + func nextByte() throws -> UInt8 { + let bytesRead = stream.read(readBuffer, maxLength: 1) + if bytesRead != 1 { + if bytesRead == -1 { + if let streamError = stream.streamError { + throw streamError + } + throw BinaryDelimited.Error.unknownStreamError + } + throw BinaryDelimited.Error.truncated + } + return readBuffer[0] + } + + var value: UInt64 = 0 + var shift: UInt64 = 0 + while true { + let c = try nextByte() + value |= UInt64(c & 0x7f) << shift + if c & 0x80 == 0 { + return value + } + shift += 7 + if shift > 63 { + throw BinaryDecodingError.malformedProtobuf + } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncoder.swift new file mode 100644 index 00000000..a3809c28 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncoder.swift @@ -0,0 +1,153 @@ +// Sources/SwiftProtobuf/BinaryEncoder.swift - Binary encoding support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Core support for protobuf binary encoding. Note that this is built +/// on the general traversal machinery. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Encoder for Binary Protocol Buffer format +internal struct BinaryEncoder { + private var pointer: UnsafeMutableRawPointer + + init(forWritingInto pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + private mutating func append(_ byte: UInt8) { + pointer.storeBytes(of: byte, as: UInt8.self) + pointer = pointer.advanced(by: 1) + } + + private mutating func append(contentsOf data: Data) { + data.withUnsafeBytes { dataPointer in + if let baseAddress = dataPointer.baseAddress, dataPointer.count > 0 { + pointer.copyMemory(from: baseAddress, byteCount: dataPointer.count) + pointer = pointer.advanced(by: dataPointer.count) + } + } + } + + @discardableResult + private mutating func append(contentsOf bufferPointer: UnsafeRawBufferPointer) -> Int { + let count = bufferPointer.count + if let baseAddress = bufferPointer.baseAddress, count > 0 { + memcpy(pointer, baseAddress, count) + } + pointer = pointer.advanced(by: count) + return count + } + + func distance(pointer: UnsafeMutableRawPointer) -> Int { + return pointer.distance(to: self.pointer) + } + + mutating func appendUnknown(data: Data) { + append(contentsOf: data) + } + + mutating func startField(fieldNumber: Int, wireFormat: WireFormat) { + startField(tag: FieldTag(fieldNumber: fieldNumber, wireFormat: wireFormat)) + } + + mutating func startField(tag: FieldTag) { + putVarInt(value: UInt64(tag.rawValue)) + } + + mutating func putVarInt(value: UInt64) { + var v = value + while v > 127 { + append(UInt8(v & 0x7f | 0x80)) + v >>= 7 + } + append(UInt8(v)) + } + + mutating func putVarInt(value: Int64) { + putVarInt(value: UInt64(bitPattern: value)) + } + + mutating func putVarInt(value: Int) { + putVarInt(value: Int64(value)) + } + + mutating func putZigZagVarInt(value: Int64) { + let coded = ZigZag.encoded(value) + putVarInt(value: coded) + } + + mutating func putBoolValue(value: Bool) { + append(value ? 1 : 0) + } + + mutating func putFixedUInt64(value: UInt64) { + var v = value.littleEndian + let n = MemoryLayout.size + memcpy(pointer, &v, n) + pointer = pointer.advanced(by: n) + } + + mutating func putFixedUInt32(value: UInt32) { + var v = value.littleEndian + let n = MemoryLayout.size + memcpy(pointer, &v, n) + pointer = pointer.advanced(by: n) + } + + mutating func putFloatValue(value: Float) { + let n = MemoryLayout.size + var v = value + var nativeBytes: UInt32 = 0 + memcpy(&nativeBytes, &v, n) + var littleEndianBytes = nativeBytes.littleEndian + memcpy(pointer, &littleEndianBytes, n) + pointer = pointer.advanced(by: n) + } + + mutating func putDoubleValue(value: Double) { + let n = MemoryLayout.size + var v = value + var nativeBytes: UInt64 = 0 + memcpy(&nativeBytes, &v, n) + var littleEndianBytes = nativeBytes.littleEndian + memcpy(pointer, &littleEndianBytes, n) + pointer = pointer.advanced(by: n) + } + + // Write a string field, including the leading index/tag value. + mutating func putStringValue(value: String) { + let utf8 = value.utf8 + #if swift(>=5.0) + // If the String does not support an internal representation in a form + // of contiguous storage, body is not called and nil is returned. + let isAvailable = utf8.withContiguousStorageIfAvailable { (body: UnsafeBufferPointer) -> Int in + putVarInt(value: body.count) + return append(contentsOf: UnsafeRawBufferPointer(body)) + } + #else + let isAvailable: Int? = nil + #endif + if isAvailable == nil { + let count = utf8.count + putVarInt(value: count) + for b in utf8 { + pointer.storeBytes(of: b, as: UInt8.self) + pointer = pointer.advanced(by: 1) + } + } + } + + mutating func putBytesValue(value: Data) { + putVarInt(value: value.count) + append(contentsOf: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingError.swift new file mode 100644 index 00000000..cbf29b5a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingError.swift @@ -0,0 +1,27 @@ +// Sources/SwiftProtobuf/BinaryEncodingError.swift - Error constants +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Enum constants that identify the particular error. +/// +// ----------------------------------------------------------------------------- + +/// Describes errors that can occur when decoding a message from binary format. +public enum BinaryEncodingError: Error { + /// `Any` fields that were decoded from JSON cannot be re-encoded to binary + /// unless the object they hold is a well-known type or a type registered via + /// `Google_Protobuf_Any.register()`. + case anyTranscodeFailure + + /// The definition of the message or one of its nested messages has required + /// fields but the message being encoded did not include values for them. You + /// must pass `partial: true` during encoding if you wish to explicitly ignore + /// missing required fields. + case missingRequiredFields +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift new file mode 100644 index 00000000..2db485d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift @@ -0,0 +1,473 @@ +// Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift - Binary size calculation support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Visitor used during binary encoding that precalcuates the size of a +/// serialized message. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Visitor that calculates the binary-encoded size of a message so that a +/// properly sized `Data` or `UInt8` array can be pre-allocated before +/// serialization. +internal struct BinaryEncodingSizeVisitor: Visitor { + + /// Accumulates the required size of the message during traversal. + var serializedSize: Int = 0 + + init() {} + + mutating func visitUnknown(bytes: Data) throws { + serializedSize += bytes.count + } + + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt64Field(value: Int64(value), fieldNumber: fieldNumber) + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize + Varint.encodedSize(of: value) + } + + mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: UInt64(value), fieldNumber: fieldNumber) + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize + Varint.encodedSize(of: value) + } + + mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize + Varint.encodedSize(of: ZigZag.encoded(value)) + } + + mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize + Varint.encodedSize(of: ZigZag.encoded(value)) + } + + mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize + MemoryLayout.size + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize + 1 + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let count = value.utf8.count + serializedSize += tagSize + Varint.encodedSize(of: Int64(count)) + count + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let count = value.count + serializedSize += tagSize + Varint.encodedSize(of: Int64(count)) + count + } + + // The default impls for visitRepeated*Field would work, but by implementing + // these directly, the calculation for the tag overhead can be optimized and + // the fixed width fields can be simple multiplication. + + mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize + serializedSize += tagSize * value.count + MemoryLayout.size * value.count + } + + mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize + serializedSize += tagSize * value.count + 1 * value.count + } + + mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { + let count = $1.utf8.count + return $0 + Varint.encodedSize(of: Int64(count)) + count + } + serializedSize += tagSize * value.count + dataSize + } + + mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { + let count = $1.count + return $0 + Varint.encodedSize(of: Int64(count)) + count + } + serializedSize += tagSize * value.count + dataSize + } + + // Packed field handling. + + mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + serializedSize += + tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count * MemoryLayout.size + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize + let dataSize = value.count + serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitSingularEnumField(value: E, + fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .varint).encodedSize + serializedSize += tagSize + let dataSize = Varint.encodedSize(of: Int32(truncatingIfNeeded: value.rawValue)) + serializedSize += dataSize + } + + mutating func visitRepeatedEnumField(value: [E], + fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .varint).encodedSize + serializedSize += value.count * tagSize + let dataSize = value.reduce(0) { + $0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue)) + } + serializedSize += dataSize + } + + mutating func visitPackedEnumField(value: [E], + fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .varint).encodedSize + serializedSize += tagSize + let dataSize = value.reduce(0) { + $0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue)) + } + serializedSize += Varint.encodedSize(of: Int64(dataSize)) + dataSize + } + + mutating func visitSingularMessageField(value: M, + fieldNumber: Int) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .lengthDelimited).encodedSize + let messageSize = try value.serializedDataSize() + serializedSize += + tagSize + Varint.encodedSize(of: UInt64(messageSize)) + messageSize + } + + mutating func visitRepeatedMessageField(value: [M], + fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .lengthDelimited).encodedSize + serializedSize += value.count * tagSize + let dataSize = try value.reduce(0) { + let messageSize = try $1.serializedDataSize() + return $0 + Varint.encodedSize(of: UInt64(messageSize)) + messageSize + } + serializedSize += dataSize + } + + mutating func visitSingularGroupField(value: G, fieldNumber: Int) throws { + // The wire format doesn't matter here because the encoded size of the + // integer won't change based on the low three bits. + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .startGroup).encodedSize + serializedSize += 2 * tagSize + try value.traverse(visitor: &self) + } + + mutating func visitRepeatedGroupField(value: [G], + fieldNumber: Int) throws { + assert(!value.isEmpty) + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .startGroup).encodedSize + serializedSize += 2 * value.count * tagSize + for v in value { + try v.traverse(visitor: &self) + } + } + + mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int + ) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .lengthDelimited).encodedSize + for (k,v) in value { + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try ValueType.visitSingular(value: v, fieldNumber: 2, with: &sizer) + let entrySize = sizer.serializedSize + serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize + } + serializedSize += value.count * tagSize + } + + mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int + ) throws where ValueType.RawValue == Int { + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .lengthDelimited).encodedSize + for (k,v) in value { + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try sizer.visitSingularEnumField(value: v, fieldNumber: 2) + let entrySize = sizer.serializedSize + serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize + } + serializedSize += value.count * tagSize + } + + mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int + ) throws { + let tagSize = FieldTag(fieldNumber: fieldNumber, + wireFormat: .lengthDelimited).encodedSize + for (k,v) in value { + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try sizer.visitSingularMessageField(value: v, fieldNumber: 2) + let entrySize = sizer.serializedSize + serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize + } + serializedSize += value.count * tagSize + } + + mutating func visitExtensionFieldsAsMessageSet( + fields: ExtensionFieldValueSet, + start: Int, + end: Int + ) throws { + var sizer = BinaryEncodingMessageSetSizeVisitor() + try fields.traverse(visitor: &sizer, start: start, end: end) + serializedSize += sizer.serializedSize + } +} + +extension BinaryEncodingSizeVisitor { + + // Helper Visitor to compute the sizes when writing out the extensions as MessageSets. + internal struct BinaryEncodingMessageSetSizeVisitor: SelectiveVisitor { + var serializedSize: Int = 0 + + init() {} + + mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws { + var groupSize = WireFormat.MessageSet.itemTagsEncodedSize + + groupSize += Varint.encodedSize(of: Int32(fieldNumber)) + + let messageSize = try value.serializedDataSize() + groupSize += Varint.encodedSize(of: UInt64(messageSize)) + messageSize + + serializedSize += groupSize + } + + // SelectiveVisitor handles the rest. + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingVisitor.swift new file mode 100644 index 00000000..748de253 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/BinaryEncodingVisitor.swift @@ -0,0 +1,355 @@ +// Sources/SwiftProtobuf/BinaryEncodingVisitor.swift - Binary encoding support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Core support for protobuf binary encoding. Note that this is built +/// on the general traversal machinery. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Visitor that encodes a message graph in the protobuf binary wire format. +internal struct BinaryEncodingVisitor: Visitor { + + var encoder: BinaryEncoder + + /// Creates a new visitor that writes the binary-coded message into the memory + /// at the given pointer. + /// + /// - Precondition: `pointer` must point to an allocated block of memory that + /// is large enough to hold the entire encoded message. For performance + /// reasons, the encoder does not make any attempts to verify this. + init(forWritingInto pointer: UnsafeMutableRawPointer) { + encoder = BinaryEncoder(forWritingInto: pointer) + } + + init(encoder: BinaryEncoder) { + self.encoder = encoder + } + + mutating func visitUnknown(bytes: Data) throws { + encoder.appendUnknown(data: bytes) + } + + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed32) + encoder.putFloatValue(value: value) + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed64) + encoder.putDoubleValue(value: value) + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: UInt64(bitPattern: value), fieldNumber: fieldNumber) + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .varint) + encoder.putVarInt(value: value) + } + + mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularSInt64Field(value: Int64(value), fieldNumber: fieldNumber) + } + + mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: ZigZag.encoded(value), fieldNumber: fieldNumber) + } + + mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed32) + encoder.putFixedUInt32(value: value) + } + + mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed64) + encoder.putFixedUInt64(value: value) + } + + mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularFixed32Field(value: UInt32(bitPattern: value), fieldNumber: fieldNumber) + } + + mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularFixed64Field(value: UInt64(bitPattern: value), fieldNumber: fieldNumber) + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: value ? 1 : 0, fieldNumber: fieldNumber) + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putStringValue(value: value) + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putBytesValue(value: value) + } + + mutating func visitSingularEnumField(value: E, + fieldNumber: Int) throws { + try visitSingularUInt64Field(value: UInt64(bitPattern: Int64(value.rawValue)), + fieldNumber: fieldNumber) + } + + mutating func visitSingularMessageField(value: M, + fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let length = try value.serializedDataSize() + encoder.putVarInt(value: length) + try value.traverse(visitor: &self) + } + + mutating func visitSingularGroupField(value: G, fieldNumber: Int) throws { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .startGroup) + try value.traverse(visitor: &self) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .endGroup) + } + + // Repeated fields are handled by the default implementations in Visitor.swift + + + // Packed Fields + + mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putFloatValue(value: v) + } + } + + mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putDoubleValue(value: v) + } + } + + mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putVarInt(value: Int64(v)) + } + } + + mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putVarInt(value: v) + } + } + + mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putZigZagVarInt(value: Int64(v)) + } + } + + mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putZigZagVarInt(value: v) + } + } + + mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putVarInt(value: UInt64(v)) + } + } + + mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putVarInt(value: v) + } + } + + mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putFixedUInt32(value: v) + } + } + + mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putFixedUInt64(value: v) + } + } + + mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putFixedUInt32(value: UInt32(bitPattern: v)) + } + } + + mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count * MemoryLayout.size) + for v in value { + encoder.putFixedUInt64(value: UInt64(bitPattern: v)) + } + } + + mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + encoder.putVarInt(value: value.count) + for v in value { + encoder.putVarInt(value: v ? 1 : 0) + } + } + + mutating func visitPackedEnumField(value: [E], fieldNumber: Int) throws { + assert(!value.isEmpty) + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + let packedSize = value.reduce(0) { + $0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue)) + } + encoder.putVarInt(value: packedSize) + for v in value { + encoder.putVarInt(value: v.rawValue) + } + } + + mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int + ) throws { + for (k,v) in value { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try ValueType.visitSingular(value: v, fieldNumber: 2, with: &sizer) + let entrySize = sizer.serializedSize + encoder.putVarInt(value: entrySize) + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self) + try ValueType.visitSingular(value: v, fieldNumber: 2, with: &self) + } + } + + mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int + ) throws where ValueType.RawValue == Int { + for (k,v) in value { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try sizer.visitSingularEnumField(value: v, fieldNumber: 2) + let entrySize = sizer.serializedSize + encoder.putVarInt(value: entrySize) + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self) + try visitSingularEnumField(value: v, fieldNumber: 2) + } + } + + mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int + ) throws { + for (k,v) in value { + encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) + var sizer = BinaryEncodingSizeVisitor() + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer) + try sizer.visitSingularMessageField(value: v, fieldNumber: 2) + let entrySize = sizer.serializedSize + encoder.putVarInt(value: entrySize) + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self) + try visitSingularMessageField(value: v, fieldNumber: 2) + } + } + + mutating func visitExtensionFieldsAsMessageSet( + fields: ExtensionFieldValueSet, + start: Int, + end: Int + ) throws { + var subVisitor = BinaryEncodingMessageSetVisitor(encoder: encoder) + try fields.traverse(visitor: &subVisitor, start: start, end: end) + encoder = subVisitor.encoder + } +} + +extension BinaryEncodingVisitor { + + // Helper Visitor to when writing out the extensions as MessageSets. + internal struct BinaryEncodingMessageSetVisitor: SelectiveVisitor { + var encoder: BinaryEncoder + + init(encoder: BinaryEncoder) { + self.encoder = encoder + } + + mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws { + encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.itemStart.rawValue)) + + encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.typeId.rawValue)) + encoder.putVarInt(value: fieldNumber) + + encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.message.rawValue)) + + // Use a normal BinaryEncodingVisitor so any message fields end up in the + // normal wire format (instead of MessageSet format). + let length = try value.serializedDataSize() + encoder.putVarInt(value: length) + // Create the sub encoder after writing the length. + var subVisitor = BinaryEncodingVisitor(encoder: encoder) + try value.traverse(visitor: &subVisitor) + encoder = subVisitor.encoder + + encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.itemEnd.rawValue)) + } + + // SelectiveVisitor handles the rest. + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/CustomJSONCodable.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/CustomJSONCodable.swift new file mode 100644 index 00000000..2e1fd340 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/CustomJSONCodable.swift @@ -0,0 +1,36 @@ +// Sources/SwiftProtobuf/CustomJSONCodable.swift - Custom JSON support for WKTs +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Custom protocol for the WKTs to support their custom JSON encodings. +/// +// ----------------------------------------------------------------------------- + +/// Allows WKTs to provide their custom JSON encodings. +internal protocol _CustomJSONCodable { + func encodedJSONString(options: JSONEncodingOptions) throws -> String + mutating func decodeJSON(from: inout JSONDecoder) throws + + /// Called when the JSON `null` literal is encountered in a position where + /// a message of the conforming type is expected. The message type can then + /// handle the `null` value differently, if needed; for example, + /// `Google_Protobuf_Value` returns a special instance whose `kind` is set to + /// `.nullValue(.nullValue)`. + /// + /// The default behavior is to return `nil`, which indicates that `null` + /// should be treated as the absence of a message. + static func decodedFromJSONNull() throws -> Self? +} + +extension _CustomJSONCodable { + internal static func decodedFromJSONNull() -> Self? { + // Return nil by default. Concrete types can provide custom logic. + return nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Data+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Data+Extensions.swift new file mode 100644 index 00000000..3e359d73 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Data+Extensions.swift @@ -0,0 +1,34 @@ +// Sources/SwiftProtobuf/Data+Extensions.swift - Extension exposing new Data API +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extension exposing new Data API to Swift versions < 5.0. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +#if !swift(>=5.0) +internal extension Data { + @usableFromInline + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + let c = count + return try withUnsafeBytes { (p: UnsafePointer) throws -> T in + try body(UnsafeRawBufferPointer(start: p, count: c)) + } + } + + mutating func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + let c = count + return try withUnsafeMutableBytes { (p: UnsafeMutablePointer) throws -> T in + try body(UnsafeMutableRawBufferPointer(start: p, count: c)) + } + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Decoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Decoder.swift new file mode 100644 index 00000000..76c28f31 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Decoder.swift @@ -0,0 +1,150 @@ +// Sources/SwiftProtobuf/Decoder.swift - Basic field setting +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// In this way, the generated code only knows about schema +/// information; the decoder logic knows how to decode particular +/// wire types based on that information. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// This is the abstract protocol used by the generated code +/// to deserialize data. +/// +/// The generated code looks roughly like this: +/// +/// ``` +/// while fieldNumber = try decoder.nextFieldNumber() { +/// switch fieldNumber { +/// case 1: decoder.decodeRepeatedInt32Field(value: &_field) +/// ... etc ... +/// } +/// ``` +/// +/// For performance, this is mostly broken out into a separate method +/// for singular/repeated fields of every supported type. Note that +/// we don't distinguish "packed" here, since all existing decoders +/// treat "packed" the same as "repeated" at this level. (That is, +/// even when the serializer distinguishes packed and non-packed +/// forms, the deserializer always accepts both.) +/// +/// Generics come into play at only a few points: `Enum`s and `Message`s +/// use a generic type to locate the correct initializer. Maps and +/// extensions use generics to avoid the method explosion of having to +/// support a separate method for every map and extension type. Maps +/// do distinguish `Enum`-valued and `Message`-valued maps to avoid +/// polluting the generated `Enum` and `Message` types with all of the +/// necessary generic methods to support this. +public protocol Decoder { + /// Called by a `oneof` when it already has a value and is being asked to + /// accept a new value. Some formats require `oneof` decoding to fail in this + /// case. + mutating func handleConflictingOneOf() throws + + /// Returns the next field number, or nil when the end of the input is + /// reached. + /// + /// For JSON and text format, the decoder translates the field name to a + /// number at this point, based on information it obtained from the message + /// when it was initialized. + mutating func nextFieldNumber() throws -> Int? + + // Primitive field decoders + mutating func decodeSingularFloatField(value: inout Float) throws + mutating func decodeSingularFloatField(value: inout Float?) throws + mutating func decodeRepeatedFloatField(value: inout [Float]) throws + mutating func decodeSingularDoubleField(value: inout Double) throws + mutating func decodeSingularDoubleField(value: inout Double?) throws + mutating func decodeRepeatedDoubleField(value: inout [Double]) throws + mutating func decodeSingularInt32Field(value: inout Int32) throws + mutating func decodeSingularInt32Field(value: inout Int32?) throws + mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws + mutating func decodeSingularInt64Field(value: inout Int64) throws + mutating func decodeSingularInt64Field(value: inout Int64?) throws + mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws + mutating func decodeSingularUInt32Field(value: inout UInt32) throws + mutating func decodeSingularUInt32Field(value: inout UInt32?) throws + mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws + mutating func decodeSingularUInt64Field(value: inout UInt64) throws + mutating func decodeSingularUInt64Field(value: inout UInt64?) throws + mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws + mutating func decodeSingularSInt32Field(value: inout Int32) throws + mutating func decodeSingularSInt32Field(value: inout Int32?) throws + mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws + mutating func decodeSingularSInt64Field(value: inout Int64) throws + mutating func decodeSingularSInt64Field(value: inout Int64?) throws + mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws + mutating func decodeSingularFixed32Field(value: inout UInt32) throws + mutating func decodeSingularFixed32Field(value: inout UInt32?) throws + mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws + mutating func decodeSingularFixed64Field(value: inout UInt64) throws + mutating func decodeSingularFixed64Field(value: inout UInt64?) throws + mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws + mutating func decodeSingularSFixed32Field(value: inout Int32) throws + mutating func decodeSingularSFixed32Field(value: inout Int32?) throws + mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws + mutating func decodeSingularSFixed64Field(value: inout Int64) throws + mutating func decodeSingularSFixed64Field(value: inout Int64?) throws + mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws + mutating func decodeSingularBoolField(value: inout Bool) throws + mutating func decodeSingularBoolField(value: inout Bool?) throws + mutating func decodeRepeatedBoolField(value: inout [Bool]) throws + mutating func decodeSingularStringField(value: inout String) throws + mutating func decodeSingularStringField(value: inout String?) throws + mutating func decodeRepeatedStringField(value: inout [String]) throws + mutating func decodeSingularBytesField(value: inout Data) throws + mutating func decodeSingularBytesField(value: inout Data?) throws + mutating func decodeRepeatedBytesField(value: inout [Data]) throws + + // Decode Enum fields + mutating func decodeSingularEnumField(value: inout E) throws where E.RawValue == Int + mutating func decodeSingularEnumField(value: inout E?) throws where E.RawValue == Int + mutating func decodeRepeatedEnumField(value: inout [E]) throws where E.RawValue == Int + + // Decode Message fields + mutating func decodeSingularMessageField(value: inout M?) throws + mutating func decodeRepeatedMessageField(value: inout [M]) throws + + // Decode Group fields + mutating func decodeSingularGroupField(value: inout G?) throws + mutating func decodeRepeatedGroupField(value: inout [G]) throws + + // Decode Map fields. + // This is broken into separate methods depending on whether the value + // type is primitive (_ProtobufMap), enum (_ProtobufEnumMap), or message + // (_ProtobufMessageMap) + mutating func decodeMapField(fieldType: _ProtobufMap.Type, value: inout _ProtobufMap.BaseType) throws + mutating func decodeMapField(fieldType: _ProtobufEnumMap.Type, value: inout _ProtobufEnumMap.BaseType) throws where ValueType.RawValue == Int + mutating func decodeMapField(fieldType: _ProtobufMessageMap.Type, value: inout _ProtobufMessageMap.BaseType) throws + + // Decode extension fields + mutating func decodeExtensionField(values: inout ExtensionFieldValueSet, messageType: Message.Type, fieldNumber: Int) throws + + // Run a decode loop decoding the MessageSet format for Extensions. + mutating func decodeExtensionFieldsAsMessageSet(values: inout ExtensionFieldValueSet, + messageType: Message.Type) throws +} + +/// Most Decoders won't care about Extension handing as in MessageSet +/// format, so provide a default implementation simply looping on the +/// fieldNumbers and feeding through to extension decoding. +extension Decoder { + public mutating func decodeExtensionFieldsAsMessageSet( + values: inout ExtensionFieldValueSet, + messageType: Message.Type + ) throws { + while let fieldNumber = try self.nextFieldNumber() { + try self.decodeExtensionField(values: &values, + messageType: messageType, + fieldNumber: fieldNumber) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/DoubleParser.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/DoubleParser.swift new file mode 100644 index 00000000..92edb15d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/DoubleParser.swift @@ -0,0 +1,61 @@ +// Sources/SwiftProtobuf/DoubleParser.swift - Generally useful mathematical functions +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Numeric parsing helper for float and double strings +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Support parsing float/double values from UTF-8 +internal class DoubleParser { + // Temporary buffer so we can null-terminate the UTF-8 string + // before calling the C standard libray to parse it. + // In theory, JSON writers should be able to represent any IEEE Double + // in at most 25 bytes, but many writers will emit more digits than + // necessary, so we size this generously. + private var work = + UnsafeMutableBufferPointer.allocate(capacity: 128) + + deinit { + work.deallocate() + } + + func utf8ToDouble(bytes: UnsafeRawBufferPointer, + start: UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index) -> Double? { + return utf8ToDouble(bytes: UnsafeRawBufferPointer(rebasing: bytes[start.. Double? { + // Reject unreasonably long or short UTF8 number + if work.count <= bytes.count || bytes.count < 1 { + return nil + } + + #if swift(>=4.1) + UnsafeMutableRawBufferPointer(work).copyMemory(from: bytes) + #else + UnsafeMutableRawBufferPointer(work).copyBytes(from: bytes) + #endif + work[bytes.count] = 0 + + // Use C library strtod() to parse it + var e: UnsafeMutablePointer? = work.baseAddress + let d = strtod(work.baseAddress!, &e) + + // Fail if strtod() did not consume everything we expected + // or if strtod() thought the number was out of range. + if e != work.baseAddress! + bytes.count || !d.isFinite { + return nil + } + return d + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Enum.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Enum.swift new file mode 100644 index 00000000..d5965bc7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Enum.swift @@ -0,0 +1,95 @@ +// Sources/SwiftProtobuf/Enum.swift - Enum support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Generated enums conform to SwiftProtobuf.Enum +/// +/// See ProtobufTypes and JSONTypes for extension +/// methods to support binary and JSON coding. +/// +// ----------------------------------------------------------------------------- + +// TODO: `Enum` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. + +/// Generated enum types conform to this protocol. +public protocol Enum: RawRepresentable, Hashable { + /// Creates a new instance of the enum initialized to its default value. + init() + + /// Creates a new instance of the enum from the given raw integer value. + /// + /// For proto2 enums, this initializer will fail if the raw value does not + /// correspond to a valid enum value. For proto3 enums, this initializer never + /// fails; unknown values are created as instances of the `UNRECOGNIZED` case. + /// + /// - Parameter rawValue: The raw integer value from which to create the enum + /// value. + init?(rawValue: Int) + + /// The raw integer value of the enum value. + /// + /// For a recognized enum case, this is the integer value of the case as + /// defined in the .proto file. For `UNRECOGNIZED` cases in proto3, this is + /// the value that was originally decoded. + var rawValue: Int { get } +} + +extension Enum { +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(rawValue) + } +#else // swift(>=4.2) + public var hashValue: Int { + return rawValue + } +#endif // swift(>=4.2) + + /// Internal convenience property representing the name of the enum value (or + /// `nil` if it is an `UNRECOGNIZED` value or doesn't provide names). + /// + /// Since the text format and JSON names are always identical, we don't need + /// to distinguish them. + internal var name: _NameMap.Name? { + guard let nameProviding = Self.self as? _ProtoNameProviding.Type else { + return nil + } + return nameProviding._protobuf_nameMap.names(for: rawValue)?.proto + } + + /// Internal convenience initializer that returns the enum value with the + /// given name, if it provides names. + /// + /// Since the text format and JSON names are always identical, we don't need + /// to distinguish them. + /// + /// - Parameter name: The name of the enum case. + internal init?(name: String) { + guard let nameProviding = Self.self as? _ProtoNameProviding.Type, + let number = nameProviding._protobuf_nameMap.number(forJSONName: name) else { + return nil + } + self.init(rawValue: number) + } + + /// Internal convenience initializer that returns the enum value with the + /// given name, if it provides names. + /// + /// Since the text format and JSON names are always identical, we don't need + /// to distinguish them. + /// + /// - Parameter name: Buffer holding the UTF-8 bytes of the desired name. + internal init?(rawUTF8: UnsafeRawBufferPointer) { + guard let nameProviding = Self.self as? _ProtoNameProviding.Type, + let number = nameProviding._protobuf_nameMap.number(forJSONName: rawUTF8) else { + return nil + } + self.init(rawValue: number) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensibleMessage.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensibleMessage.swift new file mode 100644 index 00000000..f1fb9914 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensibleMessage.swift @@ -0,0 +1,73 @@ +// Sources/SwiftProtobuf/ExtensibleMessage.swift - Extension support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Additional capabilities needed by messages that allow extensions. +/// +// ----------------------------------------------------------------------------- + +// Messages that support extensions implement this protocol +public protocol ExtensibleMessage: Message { + var _protobuf_extensionFieldValues: ExtensionFieldValueSet { get set } +} + +extension ExtensibleMessage { + public mutating func setExtensionValue(ext: MessageExtension, value: F.ValueType) { + _protobuf_extensionFieldValues[ext.fieldNumber] = F(protobufExtension: ext, value: value) + } + + public func getExtensionValue(ext: MessageExtension) -> F.ValueType? { + if let fieldValue = _protobuf_extensionFieldValues[ext.fieldNumber] as? F { + return fieldValue.value + } + return nil + } + + public func hasExtensionValue(ext: MessageExtension) -> Bool { + return _protobuf_extensionFieldValues[ext.fieldNumber] is F + } + + public mutating func clearExtensionValue(ext: MessageExtension) { + _protobuf_extensionFieldValues[ext.fieldNumber] = nil + } +} + +// Additional specializations for the different types of repeated fields so +// setting them to an empty array clears them from the map. +extension ExtensibleMessage { + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [T.BaseType]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : RepeatedExtensionField(protobufExtension: ext, value: value) + } + + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [T.BaseType]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : PackedExtensionField(protobufExtension: ext, value: value) + } + + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [E]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : RepeatedEnumExtensionField(protobufExtension: ext, value: value) + } + + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [E]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : PackedEnumExtensionField(protobufExtension: ext, value: value) + } + + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [M]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : RepeatedMessageExtensionField(protobufExtension: ext, value: value) + } + + public mutating func setExtensionValue(ext: MessageExtension, Self>, value: [M]) { + _protobuf_extensionFieldValues[ext.fieldNumber] = + value.isEmpty ? nil : RepeatedGroupExtensionField(protobufExtension: ext, value: value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift new file mode 100644 index 00000000..fc48b0e2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift @@ -0,0 +1,97 @@ +// Sources/SwiftProtobuf/ExtensionFieldValueSet.swift - Extension support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A collection of extension field values on a particular object. +/// This is only used within messages to manage the values of extension fields; +/// it does not need to be very sophisticated. +/// +// ----------------------------------------------------------------------------- + +// TODO: `ExtensionFieldValueSet` should be `Sendable` but we cannot do so yet without possibly breaking compatibility. + +public struct ExtensionFieldValueSet: Hashable { + fileprivate var values = [Int : AnyExtensionField]() + + public static func ==(lhs: ExtensionFieldValueSet, + rhs: ExtensionFieldValueSet) -> Bool { + guard lhs.values.count == rhs.values.count else { + return false + } + for (index, l) in lhs.values { + if let r = rhs.values[index] { + if type(of: l) != type(of: r) { + return false + } + if !l.isEqual(other: r) { + return false + } + } else { + return false + } + } + return true + } + + public init() {} + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + // AnyExtensionField is not Hashable, and the Self constraint that would + // add breaks some of the uses of it; so the only choice is to manually + // mix things in. However, one must remember to do things in an order + // independent manner. + var hash = 16777619 + for (fieldNumber, v) in values { + var localHasher = hasher + localHasher.combine(fieldNumber) + v.hash(into: &localHasher) + hash = hash &+ localHasher.finalize() + } + hasher.combine(hash) + } +#else // swift(>=4.2) + public var hashValue: Int { + var hash = 16777619 + for (fieldNumber, v) in values { + // Note: This calculation cannot depend on the order of the items. + hash = hash &+ fieldNumber &+ v.hashValue + } + return hash + } +#endif // swift(>=4.2) + + public func traverse(visitor: inout V, start: Int, end: Int) throws { + let validIndexes = values.keys.filter {$0 >= start && $0 < end} + for i in validIndexes.sorted() { + let value = values[i]! + try value.traverse(visitor: &visitor) + } + } + + public subscript(index: Int) -> AnyExtensionField? { + get { return values[index] } + set { values[index] = newValue } + } + + mutating func modify(index: Int, _ modifier: (inout AnyExtensionField?) throws -> ReturnType) rethrows -> ReturnType { + // This internal helper exists to invoke the _modify accessor on Dictionary for the given operation, which can avoid CoWs + // during the modification operation. + return try modifier(&values[index]) + } + + public var isInitialized: Bool { + for (_, v) in values { + if !v.isInitialized { + return false + } + } + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFields.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFields.swift new file mode 100644 index 00000000..7aefd00c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionFields.swift @@ -0,0 +1,710 @@ +// Sources/SwiftProtobuf/ExtensionFields.swift - Extension support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Core protocols implemented by generated extensions. +/// +// ----------------------------------------------------------------------------- + +#if !swift(>=4.2) +private let i_2166136261 = Int(bitPattern: 2166136261) +private let i_16777619 = Int(16777619) +#endif + +// TODO: `AnyExtensionField` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. + +// +// Type-erased Extension field implementation. +// Note that it has no "self or associated type" references, so can +// be used as a protocol type. (In particular, although it does have +// a hashValue property, it cannot be Hashable.) +// +// This can encode, decode, return a hashValue and test for +// equality with some other extension field; but it's type-sealed +// so you can't actually access the contained value itself. +// +public protocol AnyExtensionField: CustomDebugStringConvertible { +#if swift(>=4.2) + func hash(into hasher: inout Hasher) +#else + var hashValue: Int { get } +#endif + var protobufExtension: AnyMessageExtension { get } + func isEqual(other: AnyExtensionField) -> Bool + + /// Merging field decoding + mutating func decodeExtensionField(decoder: inout T) throws + + /// Fields know their own type, so can dispatch to a visitor + func traverse(visitor: inout V) throws + + /// Check if the field is initialized. + var isInitialized: Bool { get } +} + +extension AnyExtensionField { + // Default implementation for extensions fields. The message types below provide + // custom versions. + public var isInitialized: Bool { return true } +} + +/// +/// The regular ExtensionField type exposes the value directly. +/// +public protocol ExtensionField: AnyExtensionField, Hashable { + associatedtype ValueType + var value: ValueType { get set } + init(protobufExtension: AnyMessageExtension, value: ValueType) + init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws +} + +/// +/// Singular field +/// +public struct OptionalExtensionField: ExtensionField { + public typealias BaseType = T.BaseType + public typealias ValueType = BaseType + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: OptionalExtensionField, + rhs: OptionalExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + + public var debugDescription: String { + get { + return String(reflecting: value) + } + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { return value.hashValue } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! OptionalExtensionField + return self == o + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + var v: ValueType? + try T.decodeSingular(value: &v, from: &decoder) + if let v = v { + value = v + } + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType? + try T.decodeSingular(value: &v, from: &decoder) + if let v = v { + self.init(protobufExtension: protobufExtension, value: v) + } else { + return nil + } + } + + public func traverse(visitor: inout V) throws { + try T.visitSingular(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor) + } +} + +/// +/// Repeated fields +/// +public struct RepeatedExtensionField: ExtensionField { + public typealias BaseType = T.BaseType + public typealias ValueType = [BaseType] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: RepeatedExtensionField, + rhs: RepeatedExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! RepeatedExtensionField + return self == o + } + + public var debugDescription: String { + return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]" + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try T.decodeRepeated(value: &value, from: &decoder) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try T.decodeRepeated(value: &v, from: &decoder) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try T.visitRepeated(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor) + } + } +} + +/// +/// Packed Repeated fields +/// +/// TODO: This is almost (but not quite) identical to RepeatedFields; +/// find a way to collapse the implementations. +/// +public struct PackedExtensionField: ExtensionField { + public typealias BaseType = T.BaseType + public typealias ValueType = [BaseType] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: PackedExtensionField, + rhs: PackedExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! PackedExtensionField + return self == o + } + + public var debugDescription: String { + return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]" + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try T.decodeRepeated(value: &value, from: &decoder) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try T.decodeRepeated(value: &v, from: &decoder) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try T.visitPacked(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor) + } + } +} + +/// +/// Enum extensions +/// +public struct OptionalEnumExtensionField: ExtensionField where E.RawValue == Int { + public typealias BaseType = E + public typealias ValueType = E + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: OptionalEnumExtensionField, + rhs: OptionalEnumExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + + public var debugDescription: String { + get { + return String(reflecting: value) + } + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { return value.hashValue } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! OptionalEnumExtensionField + return self == o + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + var v: ValueType? + try decoder.decodeSingularEnumField(value: &v) + if let v = v { + value = v + } + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType? + try decoder.decodeSingularEnumField(value: &v) + if let v = v { + self.init(protobufExtension: protobufExtension, value: v) + } else { + return nil + } + } + + public func traverse(visitor: inout V) throws { + try visitor.visitSingularEnumField( + value: value, + fieldNumber: protobufExtension.fieldNumber) + } +} + +/// +/// Repeated Enum fields +/// +public struct RepeatedEnumExtensionField: ExtensionField where E.RawValue == Int { + public typealias BaseType = E + public typealias ValueType = [E] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: RepeatedEnumExtensionField, + rhs: RepeatedEnumExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! RepeatedEnumExtensionField + return self == o + } + + public var debugDescription: String { + return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]" + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try decoder.decodeRepeatedEnumField(value: &value) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try decoder.decodeRepeatedEnumField(value: &v) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try visitor.visitRepeatedEnumField( + value: value, + fieldNumber: protobufExtension.fieldNumber) + } + } +} + +/// +/// Packed Repeated Enum fields +/// +/// TODO: This is almost (but not quite) identical to RepeatedEnumFields; +/// find a way to collapse the implementations. +/// +public struct PackedEnumExtensionField: ExtensionField where E.RawValue == Int { + public typealias BaseType = E + public typealias ValueType = [E] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: PackedEnumExtensionField, + rhs: PackedEnumExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! PackedEnumExtensionField + return self == o + } + + public var debugDescription: String { + return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]" + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try decoder.decodeRepeatedEnumField(value: &value) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try decoder.decodeRepeatedEnumField(value: &v) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try visitor.visitPackedEnumField( + value: value, + fieldNumber: protobufExtension.fieldNumber) + } + } +} + +// +// ========== Message ========== +// +public struct OptionalMessageExtensionField: + ExtensionField { + public typealias BaseType = M + public typealias ValueType = BaseType + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: OptionalMessageExtensionField, + rhs: OptionalMessageExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + + public var debugDescription: String { + get { + return String(reflecting: value) + } + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + value.hash(into: &hasher) + } +#else // swift(>=4.2) + public var hashValue: Int {return value.hashValue} +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! OptionalMessageExtensionField + return self == o + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + var v: ValueType? = value + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + self.value = v + } + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType? + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + self.init(protobufExtension: protobufExtension, value: v) + } else { + return nil + } + } + + public func traverse(visitor: inout V) throws { + try visitor.visitSingularMessageField( + value: value, fieldNumber: protobufExtension.fieldNumber) + } + + public var isInitialized: Bool { + return value.isInitialized + } +} + +public struct RepeatedMessageExtensionField: + ExtensionField { + public typealias BaseType = M + public typealias ValueType = [BaseType] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: RepeatedMessageExtensionField, + rhs: RepeatedMessageExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + for e in value { + e.hash(into: &hasher) + } + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! RepeatedMessageExtensionField + return self == o + } + + public var debugDescription: String { + return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]" + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try decoder.decodeRepeatedMessageField(value: &value) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try decoder.decodeRepeatedMessageField(value: &v) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try visitor.visitRepeatedMessageField( + value: value, fieldNumber: protobufExtension.fieldNumber) + } + } + + public var isInitialized: Bool { + return Internal.areAllInitialized(value) + } +} + +// +// ======== Groups within Messages ======== +// +// Protoc internally treats groups the same as messages, but +// they serialize very differently, so we have separate serialization +// handling here... +public struct OptionalGroupExtensionField: + ExtensionField { + public typealias BaseType = G + public typealias ValueType = BaseType + public var value: G + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: OptionalGroupExtensionField, + rhs: OptionalGroupExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int {return value.hashValue} +#endif // swift(>=4.2) + + public var debugDescription: String { get {return value.debugDescription} } + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! OptionalGroupExtensionField + return self == o + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + var v: ValueType? = value + try decoder.decodeSingularGroupField(value: &v) + if let v = v { + value = v + } + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType? + try decoder.decodeSingularGroupField(value: &v) + if let v = v { + self.init(protobufExtension: protobufExtension, value: v) + } else { + return nil + } + } + + public func traverse(visitor: inout V) throws { + try visitor.visitSingularGroupField( + value: value, fieldNumber: protobufExtension.fieldNumber) + } + + public var isInitialized: Bool { + return value.isInitialized + } +} + +public struct RepeatedGroupExtensionField: + ExtensionField { + public typealias BaseType = G + public typealias ValueType = [BaseType] + public var value: ValueType + public var protobufExtension: AnyMessageExtension + + public static func ==(lhs: RepeatedGroupExtensionField, + rhs: RepeatedGroupExtensionField) -> Bool { + return lhs.value == rhs.value + } + + public init(protobufExtension: AnyMessageExtension, value: ValueType) { + self.protobufExtension = protobufExtension + self.value = value + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + hasher.combine(value) + } +#else // swift(>=4.2) + public var hashValue: Int { + get { + var hash = i_2166136261 + for e in value { + hash = (hash &* i_16777619) ^ e.hashValue + } + return hash + } + } +#endif // swift(>=4.2) + + public var debugDescription: String { + return "[" + value.map{$0.debugDescription}.joined(separator: ",") + "]" + } + + public func isEqual(other: AnyExtensionField) -> Bool { + let o = other as! RepeatedGroupExtensionField + return self == o + } + + public mutating func decodeExtensionField(decoder: inout D) throws { + try decoder.decodeRepeatedGroupField(value: &value) + } + + public init?(protobufExtension: AnyMessageExtension, decoder: inout D) throws { + var v: ValueType = [] + try decoder.decodeRepeatedGroupField(value: &v) + self.init(protobufExtension: protobufExtension, value: v) + } + + public func traverse(visitor: inout V) throws { + if value.count > 0 { + try visitor.visitRepeatedGroupField( + value: value, fieldNumber: protobufExtension.fieldNumber) + } + } + + public var isInitialized: Bool { + return Internal.areAllInitialized(value) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionMap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionMap.swift new file mode 100644 index 00000000..e83b1c91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ExtensionMap.swift @@ -0,0 +1,38 @@ +// Sources/SwiftProtobuf/ExtensionMap.swift - Extension support +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A set of extensions that can be passed into deserializers +/// to provide details of the particular extensions that should +/// be recognized. +/// +// ----------------------------------------------------------------------------- + +/// A collection of extension objects. +/// +/// An `ExtensionMap` is used during decoding to look up +/// extension objects corresponding to the serialized data. +/// +/// This is a protocol so that developers can build their own +/// extension handling if they need something more complex than the +/// standard `SimpleExtensionMap` implementation. +public protocol ExtensionMap { + /// Returns the extension object describing an extension or nil + subscript(messageType: Message.Type, fieldNumber: Int) -> AnyMessageExtension? { get } + + /// Returns the field number for a message with a specific field name + /// + /// The field name here matches the format used by the protobuf + /// Text serialization: it typically looks like + /// `package.message.field_name`, where `package` is the package + /// for the proto file and `message` is the name of the message in + /// which the extension was defined. (This is different from the + /// message that is being extended!) + func fieldNumberForProto(messageType: Message.Type, protoFieldName: String) -> Int? +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTag.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTag.swift new file mode 100644 index 00000000..0a92cbb8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTag.swift @@ -0,0 +1,69 @@ +// Sources/SwiftProtobuf/FieldTag.swift - Describes a binary field tag +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Types related to binary encoded tags (field numbers and wire formats). +/// +// ----------------------------------------------------------------------------- + +/// Encapsulates the number and wire format of a field, which together form the +/// "tag". +/// +/// This type also validates tags in that it will never allow a tag with an +/// improper field number (such as zero) or wire format (such as 6 or 7) to +/// exist. In other words, a `FieldTag`'s properties never need to be tested +/// for validity because they are guaranteed correct at initialization time. +internal struct FieldTag: RawRepresentable { + + typealias RawValue = UInt32 + + /// The raw numeric value of the tag, which contains both the field number and + /// wire format. + let rawValue: UInt32 + + /// The field number component of the tag. + var fieldNumber: Int { + return Int(rawValue >> 3) + } + + /// The wire format component of the tag. + var wireFormat: WireFormat { + // This force-unwrap is safe because there are only two initialization + // paths: one that takes a WireFormat directly (and is guaranteed valid at + // compile-time), or one that takes a raw value but which only lets valid + // wire formats through. + return WireFormat(rawValue: UInt8(rawValue & 7))! + } + + /// A helper property that returns the number of bytes required to + /// varint-encode this tag. + var encodedSize: Int { + return Varint.encodedSize(of: rawValue) + } + + /// Creates a new tag from its raw numeric representation. + /// + /// Note that if the raw value given here is not a valid tag (for example, it + /// has an invalid wire format), this initializer will fail. + init?(rawValue: UInt32) { + // Verify that the field number and wire format are valid and fail if they + // are not. + guard rawValue & ~0x07 != 0, + let _ = WireFormat(rawValue: UInt8(rawValue % 8)) else { + return nil + } + self.rawValue = rawValue + } + + /// Creates a new tag by composing the given field number and wire format. + init(fieldNumber: Int, wireFormat: WireFormat) { + self.rawValue = UInt32(truncatingIfNeeded: fieldNumber) << 3 | + UInt32(wireFormat.rawValue) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTypes.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTypes.swift new file mode 100644 index 00000000..7fedcff8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/FieldTypes.swift @@ -0,0 +1,433 @@ +// Sources/SwiftProtobuf/FieldTypes.swift - Proto data types +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Serialization/deserialization support for each proto field type. +/// +/// Note that we cannot just extend the standard Int32, etc, types +/// with serialization information since proto language supports +/// distinct types (with different codings) that use the same +/// in-memory representation. For example, proto "sint32" and +/// "sfixed32" both are represented in-memory as Int32. +/// +/// These types are used generically and also passed into +/// various coding/decoding functions to provide type-specific +/// information. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +// TODO: `FieldType` and `FieldType.BaseType` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. + +// Note: The protobuf- and JSON-specific methods here are defined +// in ProtobufTypeAdditions.swift and JSONTypeAdditions.swift +public protocol FieldType { + // The Swift type used to store data for this field. For example, + // proto "sint32" fields use Swift "Int32" type. + associatedtype BaseType: Hashable + + // The default value for this field type before it has been set. + // This is also used, for example, when JSON decodes a "null" + // value for a field. + static var proto3DefaultValue: BaseType { get } + + // Generic reflector methods for looking up the correct + // encoding/decoding for extension fields, map keys, and map + // values. + static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws + static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws + static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws + static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws + static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws +} + +/// +/// Marker protocol for types that can be used as map keys +/// +public protocol MapKeyType: FieldType { + /// A comparision function for where order is needed. Can't use `Comparable` + /// because `Bool` doesn't conform, and since it is `public` there is no way + /// to add a conformance internal to SwiftProtobuf. + static func _lessThan(lhs: BaseType, rhs: BaseType) -> Bool +} + +// Default impl for anything `Comparable` +extension MapKeyType where BaseType: Comparable { + public static func _lessThan(lhs: BaseType, rhs: BaseType) -> Bool { + return lhs < rhs + } +} + +/// +/// Marker Protocol for types that can be used as map values. +/// +public protocol MapValueType: FieldType { +} + +// +// We have a struct for every basic proto field type which provides +// serialization/deserialization support as static methods. +// + +/// +/// Float traits +/// +public struct ProtobufFloat: FieldType, MapValueType { + public typealias BaseType = Float + public static var proto3DefaultValue: Float {return 0.0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularFloatField(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedFloatField(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularFloatField(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedFloatField(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedFloatField(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Double +/// +public struct ProtobufDouble: FieldType, MapValueType { + public typealias BaseType = Double + public static var proto3DefaultValue: Double {return 0.0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularDoubleField(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedDoubleField(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularDoubleField(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedDoubleField(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedDoubleField(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Int32 +/// +public struct ProtobufInt32: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int32 + public static var proto3DefaultValue: Int32 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularInt32Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedInt32Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedInt32Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Int64 +/// + +public struct ProtobufInt64: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int64 + public static var proto3DefaultValue: Int64 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularInt64Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedInt64Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedInt64Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// UInt32 +/// +public struct ProtobufUInt32: FieldType, MapKeyType, MapValueType { + public typealias BaseType = UInt32 + public static var proto3DefaultValue: UInt32 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularUInt32Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedUInt32Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularUInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedUInt32Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// UInt64 +/// + +public struct ProtobufUInt64: FieldType, MapKeyType, MapValueType { + public typealias BaseType = UInt64 + public static var proto3DefaultValue: UInt64 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularUInt64Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedUInt64Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularUInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedUInt64Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// SInt32 +/// +public struct ProtobufSInt32: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int32 + public static var proto3DefaultValue: Int32 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularSInt32Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedSInt32Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularSInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedSInt32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedSInt32Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// SInt64 +/// + +public struct ProtobufSInt64: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int64 + public static var proto3DefaultValue: Int64 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularSInt64Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedSInt64Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularSInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedSInt64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedSInt64Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Fixed32 +/// +public struct ProtobufFixed32: FieldType, MapKeyType, MapValueType { + public typealias BaseType = UInt32 + public static var proto3DefaultValue: UInt32 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularFixed32Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedFixed32Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularFixed32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedFixed32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedFixed32Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Fixed64 +/// +public struct ProtobufFixed64: FieldType, MapKeyType, MapValueType { + public typealias BaseType = UInt64 + public static var proto3DefaultValue: UInt64 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularFixed64Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedFixed64Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularFixed64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedFixed64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedFixed64Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// SFixed32 +/// +public struct ProtobufSFixed32: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int32 + public static var proto3DefaultValue: Int32 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularSFixed32Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedSFixed32Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularSFixed32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedSFixed32Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedSFixed32Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// SFixed64 +/// +public struct ProtobufSFixed64: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Int64 + public static var proto3DefaultValue: Int64 {return 0} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularSFixed64Field(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedSFixed64Field(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularSFixed64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedSFixed64Field(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedSFixed64Field(value: value, fieldNumber: fieldNumber) + } +} + +/// +/// Bool +/// +public struct ProtobufBool: FieldType, MapKeyType, MapValueType { + public typealias BaseType = Bool + public static var proto3DefaultValue: Bool {return false} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularBoolField(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedBoolField(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularBoolField(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedBoolField(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitPackedBoolField(value: value, fieldNumber: fieldNumber) + } + + /// Custom _lessThan since `Bool` isn't `Comparable`. + public static func _lessThan(lhs: BaseType, rhs: BaseType) -> Bool { + if !lhs { + return rhs + } + return false + } +} + +/// +/// String +/// +public struct ProtobufString: FieldType, MapKeyType, MapValueType { + public typealias BaseType = String + public static var proto3DefaultValue: String {return String()} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularStringField(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedStringField(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularStringField(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedStringField(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + assert(false) + } +} + +/// +/// Bytes +/// +public struct ProtobufBytes: FieldType, MapValueType { + public typealias BaseType = Data + public static var proto3DefaultValue: Data {return Data()} + public static func decodeSingular(value: inout BaseType?, from decoder: inout D) throws { + try decoder.decodeSingularBytesField(value: &value) + } + public static func decodeRepeated(value: inout [BaseType], from decoder: inout D) throws { + try decoder.decodeRepeatedBytesField(value: &value) + } + public static func visitSingular(value: BaseType, fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitSingularBytesField(value: value, fieldNumber: fieldNumber) + } + public static func visitRepeated(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + try visitor.visitRepeatedBytesField(value: value, fieldNumber: fieldNumber) + } + public static func visitPacked(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws { + assert(false) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift new file mode 100644 index 00000000..b680088c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift @@ -0,0 +1,174 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift - Well-known Any type +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extends the `Google_Protobuf_Any` type with various custom behaviors. +/// +// ----------------------------------------------------------------------------- + +// Explicit import of Foundation is necessary on Linux, +// don't remove unless obsolete on all platforms +import Foundation + +public let defaultAnyTypeURLPrefix: String = "type.googleapis.com" + +extension Google_Protobuf_Any { + /// Initialize an Any object from the provided message. + /// + /// This corresponds to the `pack` operation in the C++ API. + /// + /// Unlike the C++ implementation, the message is not immediately + /// serialized; it is merely stored until the Any object itself + /// needs to be serialized. This design avoids unnecessary + /// decoding/recoding when writing JSON format. + /// + /// - Parameters: + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - typePrefix: The prefix to be used when building the `type_url`. + /// Defaults to "type.googleapis.com". + /// - Throws: `BinaryEncodingError.missingRequiredFields` if `partial` is + /// false and `message` wasn't fully initialized. + public init( + message: Message, + partial: Bool = false, + typePrefix: String = defaultAnyTypeURLPrefix + ) throws { + if !partial && !message.isInitialized { + throw BinaryEncodingError.missingRequiredFields + } + self.init() + typeURL = buildTypeURL(forMessage:message, typePrefix: typePrefix) + _storage.state = .message(message) + } + + /// Creates a new `Google_Protobuf_Any` by decoding the given string + /// containing a serialized message in Protocol Buffer text format. + /// + /// - Parameters: + /// - textFormatString: The text format string to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - Throws: an instance of `TextFormatDecodingError` on failure. + public init( + textFormatString: String, + extensions: ExtensionMap? = nil + ) throws { + // TODO: Remove this api and default the options instead. This api has to + // exist for anything compiled against an older version of the library. + try self.init(textFormatString: textFormatString, + options: TextFormatDecodingOptions(), + extensions: extensions) + } + + /// Creates a new `Google_Protobuf_Any` by decoding the given string + /// containing a serialized message in Protocol Buffer text format. + /// + /// - Parameters: + /// - textFormatString: The text format string to decode. + /// - options: The `TextFormatDencodingOptions` to use. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - Throws: an instance of `TextFormatDecodingError` on failure. + public init( + textFormatString: String, + options: TextFormatDecodingOptions, + extensions: ExtensionMap? = nil + ) throws { + self.init() + if !textFormatString.isEmpty { + if let data = textFormatString.data(using: String.Encoding.utf8) { + try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var textDecoder = try TextFormatDecoder( + messageType: Google_Protobuf_Any.self, + utf8Pointer: baseAddress, + count: body.count, + options: options, + extensions: extensions) + try decodeTextFormat(decoder: &textDecoder) + if !textDecoder.complete { + throw TextFormatDecodingError.trailingGarbage + } + } + } + } + } + } + + /// Returns true if this `Google_Protobuf_Any` message contains the given + /// message type. + /// + /// The check is performed by looking at the passed `Message.Type` and the + /// `typeURL` of this message. + /// + /// - Parameter type: The concrete message type. + /// - Returns: True if the receiver contains the given message type. + public func isA(_ type: M.Type) -> Bool { + return _storage.isA(type) + } + +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + _storage.hash(into: &hasher) + } +#else // swift(>=4.2) + public var hashValue: Int { + return _storage.hashValue + } +#endif // swift(>=4.2) +} + +extension Google_Protobuf_Any { + internal func textTraverse(visitor: inout TextFormatEncodingVisitor) { + _storage.textTraverse(visitor: &visitor) + try! unknownFields.traverse(visitor: &visitor) + } +} + +extension Google_Protobuf_Any { + // Custom text format decoding support for Any objects. + // (Note: This is not a part of any protocol; it's invoked + // directly from TextFormatDecoder whenever it sees an attempt + // to decode an Any object) + internal mutating func decodeTextFormat( + decoder: inout TextFormatDecoder + ) throws { + // First, check if this uses the "verbose" Any encoding. + // If it does, and we have the type available, we can + // eagerly decode the contained Message object. + if let url = try decoder.scanner.nextOptionalAnyURL() { + try _uniqueStorage().decodeTextFormat(typeURL: url, decoder: &decoder) + } else { + // This is not using the specialized encoding, so we can use the + // standard path to decode the binary value. + // First, clear the fields so we don't waste time re-serializing + // the previous contents as this instances get replaced with a + // new value (can happen when a field name/number is repeated in + // the TextFormat input). + self.typeURL = "" + self.value = Data() + try decodeMessage(decoder: &decoder) + } + } +} + +extension Google_Protobuf_Any: _CustomJSONCodable { + internal func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return try _storage.encodedJSONString(options: options) + } + + internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + try _uniqueStorage().decodeJSON(from: &decoder) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift new file mode 100644 index 00000000..74fc010d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift @@ -0,0 +1,161 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift - Registry for JSON support +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Support for registering and looking up Message types. Used +/// in support of Google_Protobuf_Any. +/// +// ----------------------------------------------------------------------------- + +import Foundation +#if canImport(Dispatch) +import Dispatch +fileprivate var knownTypesQueue = + DispatchQueue(label: "org.swift.protobuf.typeRegistry", + attributes: .concurrent) +#endif + +// TODO: Should these first four be exposed as methods to go with +// the general registry support? + +internal func buildTypeURL(forMessage message: Message, typePrefix: String) -> String { + var url = typePrefix + let needsSlash = typePrefix.isEmpty || typePrefix.last != "/" + if needsSlash { + url += "/" + } + return url + typeName(fromMessage: message) +} + +internal func typeName(fromMessage message: Message) -> String { + let messageType = type(of: message) + return messageType.protoMessageName +} + +internal func typeName(fromURL s: String) -> String { + var typeStart = s.startIndex + var i = typeStart + while i < s.endIndex { + let c = s[i] + i = s.index(after: i) + if c == "/" { + typeStart = i + } + } + + return String(s[typeStart.. Bool { + let messageTypeName = messageType.protoMessageName + var result: Bool = false + execute(flags: .barrier) { + if let alreadyRegistered = knownTypes[messageTypeName] { + // Success/failure when something was already registered is + // based on if they are registering the same class or trying + // to register a different type + result = alreadyRegistered == messageType + } else { + knownTypes[messageTypeName] = messageType + result = true + } + } + + return result + } + + /// Returns the Message.Type expected for the given type URL. + public static func messageType(forTypeURL url: String) -> Message.Type? { + let messageTypeName = typeName(fromURL: url) + return messageType(forMessageName: messageTypeName) + } + + /// Returns the Message.Type expected for the given proto message name. + public static func messageType(forMessageName name: String) -> Message.Type? { + var result: Message.Type? + execute(flags: .none) { + result = knownTypes[name] + } + return result + } + +} + +fileprivate enum DispatchFlags { + case barrier + case none +} + +fileprivate func execute(flags: DispatchFlags, _ closure: () -> Void) { + #if !os(WASI) + switch flags { + case .barrier: + knownTypesQueue.sync(flags: .barrier) { + closure() + } + case .none: + knownTypesQueue.sync { + closure() + } + } + #else + closure() + #endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift new file mode 100644 index 00000000..0481af80 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift @@ -0,0 +1,231 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift - Extensions for Duration type +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extends the generated Duration struct with various custom behaviors: +/// * JSON coding and decoding +/// * Arithmetic operations +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let minDurationSeconds: Int64 = -maxDurationSeconds +private let maxDurationSeconds: Int64 = 315576000000 + +private func parseDuration(text: String) throws -> (Int64, Int32) { + var digits = [Character]() + var digitCount = 0 + var total = 0 + var chars = text.makeIterator() + var seconds: Int64? + var nanos: Int32 = 0 + var isNegative = false + while let c = chars.next() { + switch c { + case "-": + // Only accept '-' as very first character + if total > 0 { + throw JSONDecodingError.malformedDuration + } + digits.append(c) + isNegative = true + case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9": + digits.append(c) + digitCount += 1 + case ".": + if let _ = seconds { + throw JSONDecodingError.malformedDuration + } + let digitString = String(digits) + if let s = Int64(digitString), + s >= minDurationSeconds && s <= maxDurationSeconds { + seconds = s + } else { + throw JSONDecodingError.malformedDuration + } + digits.removeAll() + digitCount = 0 + case "s": + if let _ = seconds { + // Seconds already set, digits holds nanos + while (digitCount < 9) { + digits.append(Character("0")) + digitCount += 1 + } + while digitCount > 9 { + digits.removeLast() + digitCount -= 1 + } + let digitString = String(digits) + if let rawNanos = Int32(digitString) { + if isNegative { + nanos = -rawNanos + } else { + nanos = rawNanos + } + } else { + throw JSONDecodingError.malformedDuration + } + } else { + // No fraction, we just have an integral number of seconds + let digitString = String(digits) + if let s = Int64(digitString), + s >= minDurationSeconds && s <= maxDurationSeconds { + seconds = s + } else { + throw JSONDecodingError.malformedDuration + } + } + // Fail if there are characters after 's' + if chars.next() != nil { + throw JSONDecodingError.malformedDuration + } + return (seconds!, nanos) + default: + throw JSONDecodingError.malformedDuration + } + total += 1 + } + throw JSONDecodingError.malformedDuration +} + +private func formatDuration(seconds: Int64, nanos: Int32) -> String? { + let (seconds, nanos) = normalizeForDuration(seconds: seconds, nanos: nanos) + guard seconds >= minDurationSeconds && seconds <= maxDurationSeconds else { + return nil + } + let nanosString = nanosToString(nanos: nanos) // Includes leading '.' if needed + if seconds == 0 && nanos < 0 { + return "-0\(nanosString)s" + } + return "\(seconds)\(nanosString)s" +} + +extension Google_Protobuf_Duration { + /// Creates a new `Google_Protobuf_Duration` equal to the given number of + /// seconds and nanoseconds. + /// + /// - Parameter seconds: The number of seconds. + /// - Parameter nanos: The number of nanoseconds. + public init(seconds: Int64 = 0, nanos: Int32 = 0) { + self.init() + self.seconds = seconds + self.nanos = nanos + } +} + +extension Google_Protobuf_Duration: _CustomJSONCodable { + mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + let s = try decoder.scanner.nextQuotedString() + (seconds, nanos) = try parseDuration(text: s) + } + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + if let formatted = formatDuration(seconds: seconds, nanos: nanos) { + return "\"\(formatted)\"" + } else { + throw JSONEncodingError.durationRange + } + } +} + +extension Google_Protobuf_Duration: ExpressibleByFloatLiteral { + public typealias FloatLiteralType = Double + + /// Creates a new `Google_Protobuf_Duration` from a floating point literal + /// that is interpreted as a duration in seconds, rounded to the nearest + /// nanosecond. + public init(floatLiteral value: Double) { + let sd = trunc(value) + let nd = round((value - sd) * TimeInterval(nanosPerSecond)) + let (s, n) = normalizeForDuration(seconds: Int64(sd), nanos: Int32(nd)) + self.init(seconds: s, nanos: n) + } +} + +extension Google_Protobuf_Duration { + /// Creates a new `Google_Protobuf_Duration` that is equal to the given + /// `TimeInterval` (measured in seconds), rounded to the nearest nanosecond. + /// + /// - Parameter timeInterval: The `TimeInterval`. + public init(timeInterval: TimeInterval) { + let sd = trunc(timeInterval) + let nd = round((timeInterval - sd) * TimeInterval(nanosPerSecond)) + let (s, n) = normalizeForDuration(seconds: Int64(sd), nanos: Int32(nd)) + self.init(seconds: s, nanos: n) + } + + /// The `TimeInterval` (measured in seconds) equal to this duration. + public var timeInterval: TimeInterval { + return TimeInterval(self.seconds) + + TimeInterval(self.nanos) / TimeInterval(nanosPerSecond) + } +} + +private func normalizeForDuration( + seconds: Int64, + nanos: Int32 +) -> (seconds: Int64, nanos: Int32) { + var s = seconds + var n = nanos + + // If the magnitude of n exceeds a second then + // we need to factor it into s instead. + if n >= nanosPerSecond || n <= -nanosPerSecond { + s += Int64(n / nanosPerSecond) + n = n % nanosPerSecond + } + + // The Duration spec says that when s != 0, s and + // n must have the same sign. + if s > 0 && n < 0 { + n += nanosPerSecond + s -= 1 + } else if s < 0 && n > 0 { + n -= nanosPerSecond + s += 1 + } + + return (seconds: s, nanos: n) +} + +public prefix func - ( + operand: Google_Protobuf_Duration +) -> Google_Protobuf_Duration { + let (s, n) = normalizeForDuration(seconds: -operand.seconds, + nanos: -operand.nanos) + return Google_Protobuf_Duration(seconds: s, nanos: n) +} + +public func + ( + lhs: Google_Protobuf_Duration, + rhs: Google_Protobuf_Duration +) -> Google_Protobuf_Duration { + let (s, n) = normalizeForDuration(seconds: lhs.seconds + rhs.seconds, + nanos: lhs.nanos + rhs.nanos) + return Google_Protobuf_Duration(seconds: s, nanos: n) +} + +public func - ( + lhs: Google_Protobuf_Duration, + rhs: Google_Protobuf_Duration +) -> Google_Protobuf_Duration { + let (s, n) = normalizeForDuration(seconds: lhs.seconds - rhs.seconds, + nanos: lhs.nanos - rhs.nanos) + return Google_Protobuf_Duration(seconds: s, nanos: n) +} + +public func - ( + lhs: Google_Protobuf_Timestamp, + rhs: Google_Protobuf_Timestamp +) -> Google_Protobuf_Duration { + let (s, n) = normalizeForDuration(seconds: lhs.seconds - rhs.seconds, + nanos: lhs.nanos - rhs.nanos) + return Google_Protobuf_Duration(seconds: s, nanos: n) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift new file mode 100644 index 00000000..985f2154 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift @@ -0,0 +1,190 @@ +// Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift - Fieldmask extensions +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extend the generated FieldMask message with customized JSON coding and +/// convenience methods. +/// +// ----------------------------------------------------------------------------- + +// TODO: We should have utilities to apply a fieldmask to an arbitrary +// message, intersect two fieldmasks, etc. +// Google's C++ implementation does this by having utilities +// to build a tree of field paths that can be easily intersected, +// unioned, traversed to apply to submessages, etc. + +// True if the string only contains printable (non-control) +// ASCII characters. Note: This follows the ASCII standard; +// space is not a "printable" character. +private func isPrintableASCII(_ s: String) -> Bool { + for u in s.utf8 { + if u <= 0x20 || u >= 0x7f { + return false + } + } + return true +} + +private func ProtoToJSON(name: String) -> String? { + guard isPrintableASCII(name) else { return nil } + var jsonPath = String() + var chars = name.makeIterator() + while let c = chars.next() { + switch c { + case "_": + if let toupper = chars.next() { + switch toupper { + case "a"..."z": + jsonPath.append(String(toupper).uppercased()) + default: + return nil + } + } else { + return nil + } + case "A"..."Z": + return nil + case "a"..."z","0"..."9",".","(",")": + jsonPath.append(c) + default: + // TODO: Change this to `return nil` + // once we know everything legal is handled + // above. + jsonPath.append(c) + } + } + return jsonPath +} + +private func JSONToProto(name: String) -> String? { + guard isPrintableASCII(name) else { return nil } + var path = String() + for c in name { + switch c { + case "_": + return nil + case "A"..."Z": + path.append(Character("_")) + path.append(String(c).lowercased()) + case "a"..."z","0"..."9",".","(",")": + path.append(c) + default: + // TODO: Change to `return nil` once + // we know everything legal is being + // handled above + path.append(c) + } + } + return path +} + +private func parseJSONFieldNames(names: String) -> [String]? { + // An empty field mask is the empty string (no paths). + guard !names.isEmpty else { return [] } + var fieldNameCount = 0 + var fieldName = String() + var split = [String]() + for c in names { + switch c { + case ",": + if fieldNameCount == 0 { + return nil + } + if let pbName = JSONToProto(name: fieldName) { + split.append(pbName) + } else { + return nil + } + fieldName = String() + fieldNameCount = 0 + default: + fieldName.append(c) + fieldNameCount += 1 + } + } + if fieldNameCount == 0 { // Last field name can't be empty + return nil + } + if let pbName = JSONToProto(name: fieldName) { + split.append(pbName) + } else { + return nil + } + return split +} + +extension Google_Protobuf_FieldMask { + /// Creates a new `Google_Protobuf_FieldMask` from the given array of paths. + /// + /// The paths should match the names used in the .proto file, which may be + /// different than the corresponding Swift property names. + /// + /// - Parameter protoPaths: The paths from which to create the field mask, + /// defined using the .proto names for the fields. + public init(protoPaths: [String]) { + self.init() + paths = protoPaths + } + + /// Creates a new `Google_Protobuf_FieldMask` from the given paths. + /// + /// The paths should match the names used in the .proto file, which may be + /// different than the corresponding Swift property names. + /// + /// - Parameter protoPaths: The paths from which to create the field mask, + /// defined using the .proto names for the fields. + public init(protoPaths: String...) { + self.init(protoPaths: protoPaths) + } + + /// Creates a new `Google_Protobuf_FieldMask` from the given paths. + /// + /// The paths should match the JSON names of the fields, which may be + /// different than the corresponding Swift property names. + /// + /// - Parameter jsonPaths: The paths from which to create the field mask, + /// defined using the JSON names for the fields. + public init?(jsonPaths: String...) { + // TODO: This should fail if any of the conversions from JSON fails + #if swift(>=4.1) + self.init(protoPaths: jsonPaths.compactMap(JSONToProto)) + #else + self.init(protoPaths: jsonPaths.flatMap(JSONToProto)) + #endif + } + + // It would be nice if to have an initializer that accepted Swift property + // names, but translating between swift and protobuf/json property + // names is not entirely deterministic. +} + +extension Google_Protobuf_FieldMask: _CustomJSONCodable { + mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + let s = try decoder.scanner.nextQuotedString() + if let names = parseJSONFieldNames(names: s) { + paths = names + } else { + throw JSONDecodingError.malformedFieldMask + } + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + // Note: Proto requires alphanumeric field names, so there + // cannot be a ',' or '"' character to mess up this formatting. + var jsonPaths = [String]() + for p in paths { + if let jsonPath = ProtoToJSON(name: p) { + jsonPaths.append(jsonPath) + } else { + throw JSONEncodingError.fieldMaskConversion + } + } + return "\"" + jsonPaths.joined(separator: ",") + "\"" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift new file mode 100644 index 00000000..a26e0d73 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift @@ -0,0 +1,85 @@ +// Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift - ListValue extensions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// ListValue is a well-known message type that can be used to parse or encode +/// arbitrary JSON arrays without a predefined schema. +/// +// ----------------------------------------------------------------------------- + +extension Google_Protobuf_ListValue: ExpressibleByArrayLiteral { + // TODO: Give this a direct array interface by proxying the interesting + // bits down to values + public typealias Element = Google_Protobuf_Value + + /// Creates a new `Google_Protobuf_ListValue` from an array literal containing + /// `Google_Protobuf_Value` elements. + public init(arrayLiteral elements: Element...) { + self.init(values: elements) + } +} + +extension Google_Protobuf_ListValue: _CustomJSONCodable { + internal func encodedJSONString(options: JSONEncodingOptions) throws -> String { + var jsonEncoder = JSONEncoder() + jsonEncoder.append(text: "[") + var separator: StaticString = "" + for v in values { + jsonEncoder.append(staticText: separator) + try v.serializeJSONValue(to: &jsonEncoder, options: options) + separator = "," + } + jsonEncoder.append(text: "]") + return jsonEncoder.stringResult + } + + internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + if decoder.scanner.skipOptionalNull() { + return + } + try decoder.scanner.skipRequiredArrayStart() + // Since we override the JSON decoding, we can't rely + // on the default recursion depth tracking. + try decoder.scanner.incrementRecursionDepth() + if decoder.scanner.skipOptionalArrayEnd() { + decoder.scanner.decrementRecursionDepth() + return + } + while true { + var v = Google_Protobuf_Value() + try v.decodeJSON(from: &decoder) + values.append(v) + if decoder.scanner.skipOptionalArrayEnd() { + decoder.scanner.decrementRecursionDepth() + return + } + try decoder.scanner.skipRequiredComma() + } + } +} + +extension Google_Protobuf_ListValue { + /// Creates a new `Google_Protobuf_ListValue` from the given array of + /// `Google_Protobuf_Value` elements. + /// + /// - Parameter values: The list of `Google_Protobuf_Value` messages from + /// which to create the `Google_Protobuf_ListValue`. + public init(values: [Google_Protobuf_Value]) { + self.init() + self.values = values + } + + /// Accesses the `Google_Protobuf_Value` at the specified position. + /// + /// - Parameter index: The position of the element to access. + public subscript(index: Int) -> Google_Protobuf_Value { + get {return values[index]} + set(newValue) {values[index] = newValue} + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift new file mode 100644 index 00000000..3e88bfd3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift @@ -0,0 +1,28 @@ +// Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift - NullValue extensions +// +// Copyright (c) 2014 - 2020 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// NullValue is a well-known message type that can be used to parse or encode +/// JSON Null values. +/// +// ----------------------------------------------------------------------------- + +extension Google_Protobuf_NullValue: _CustomJSONCodable { + internal func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return "null" + } + internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + if decoder.scanner.skipOptionalNull() { + return + } + } + static func decodedFromJSONNull() -> Google_Protobuf_NullValue? { + return .nullValue + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift new file mode 100644 index 00000000..681f8214 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift @@ -0,0 +1,85 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift - Struct extensions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Struct is a well-known message type that can be used to parse or encode +/// arbitrary JSON objects without a predefined schema. +/// +// ----------------------------------------------------------------------------- + +extension Google_Protobuf_Struct: ExpressibleByDictionaryLiteral { + public typealias Key = String + public typealias Value = Google_Protobuf_Value + + /// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to + /// values of type `Google_Protobuf_Value`. + public init(dictionaryLiteral: (String, Google_Protobuf_Value)...) { + self.init() + for (k,v) in dictionaryLiteral { + fields[k] = v + } + } +} + +extension Google_Protobuf_Struct: _CustomJSONCodable { + internal func encodedJSONString(options: JSONEncodingOptions) throws -> String { + var jsonEncoder = JSONEncoder() + jsonEncoder.startObject() + var mapVisitor = JSONMapEncodingVisitor(encoder: jsonEncoder, options: options) + for (k,v) in fields { + try mapVisitor.visitSingularStringField(value: k, fieldNumber: 1) + try mapVisitor.visitSingularMessageField(value: v, fieldNumber: 2) + } + mapVisitor.encoder.endObject() + return mapVisitor.encoder.stringResult + } + + internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + try decoder.scanner.skipRequiredObjectStart() + if decoder.scanner.skipOptionalObjectEnd() { + return + } + while true { + let key = try decoder.scanner.nextQuotedString() + try decoder.scanner.skipRequiredColon() + var value = Google_Protobuf_Value() + try value.decodeJSON(from: &decoder) + fields[key] = value + if decoder.scanner.skipOptionalObjectEnd() { + return + } + try decoder.scanner.skipRequiredComma() + } + } +} + +extension Google_Protobuf_Struct { + /// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to + /// values of type `Google_Protobuf_Value`. + /// + /// - Parameter fields: The dictionary from field names to + /// `Google_Protobuf_Value` messages that should be used to create the + /// `Struct`. + public init(fields: [String: Google_Protobuf_Value]) { + self.init() + self.fields = fields + } + + /// Accesses the `Google_Protobuf_Value` with the given key for reading and + /// writing. + /// + /// This key-based subscript returns the `Value` for the given key if the key + /// is found in the `Struct`, or nil if the key is not found. If you assign + /// nil as the `Value` for the given key, the `Struct` removes that key and + /// its associated `Value`. + public subscript(key: String) -> Google_Protobuf_Value? { + get {return fields[key]} + set(newValue) {fields[key] = newValue} + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift new file mode 100644 index 00000000..ab0a68b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift @@ -0,0 +1,331 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift - Timestamp extensions +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extend the generated Timestamp message with customized JSON coding, +/// arithmetic operations, and convenience methods. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let minTimestampSeconds: Int64 = -62135596800 // 0001-01-01T00:00:00Z +private let maxTimestampSeconds: Int64 = 253402300799 // 9999-12-31T23:59:59Z + +// TODO: Add convenience methods to interoperate with standard +// date/time classes: an initializer that accepts Unix timestamp as +// Int or Double, an easy way to convert to/from Foundation's +// NSDateTime (on Apple platforms only?), others? + + +// Parse an RFC3339 timestamp into a pair of seconds-since-1970 and nanos. +private func parseTimestamp(s: String) throws -> (Int64, Int32) { + // Convert to an array of integer character values + let value = s.utf8.map{Int($0)} + if value.count < 20 { + throw JSONDecodingError.malformedTimestamp + } + // Since the format is fixed-layout, we can just decode + // directly as follows. + let zero = Int(48) + let nine = Int(57) + let dash = Int(45) + let colon = Int(58) + let plus = Int(43) + let letterT = Int(84) + let letterZ = Int(90) + let period = Int(46) + + func fromAscii2(_ digit0: Int, _ digit1: Int) throws -> Int { + if digit0 < zero || digit0 > nine || digit1 < zero || digit1 > nine { + throw JSONDecodingError.malformedTimestamp + } + return digit0 * 10 + digit1 - 528 + } + + func fromAscii4( + _ digit0: Int, + _ digit1: Int, + _ digit2: Int, + _ digit3: Int + ) throws -> Int { + if (digit0 < zero || digit0 > nine + || digit1 < zero || digit1 > nine + || digit2 < zero || digit2 > nine + || digit3 < zero || digit3 > nine) { + throw JSONDecodingError.malformedTimestamp + } + return digit0 * 1000 + digit1 * 100 + digit2 * 10 + digit3 - 53328 + } + + // Year: 4 digits followed by '-' + let year = try fromAscii4(value[0], value[1], value[2], value[3]) + if value[4] != dash || year < Int(1) || year > Int(9999) { + throw JSONDecodingError.malformedTimestamp + } + + // Month: 2 digits followed by '-' + let month = try fromAscii2(value[5], value[6]) + if value[7] != dash || month < Int(1) || month > Int(12) { + throw JSONDecodingError.malformedTimestamp + } + + // Day: 2 digits followed by 'T' + let mday = try fromAscii2(value[8], value[9]) + if value[10] != letterT || mday < Int(1) || mday > Int(31) { + throw JSONDecodingError.malformedTimestamp + } + + // Hour: 2 digits followed by ':' + let hour = try fromAscii2(value[11], value[12]) + if value[13] != colon || hour > Int(23) { + throw JSONDecodingError.malformedTimestamp + } + + // Minute: 2 digits followed by ':' + let minute = try fromAscii2(value[14], value[15]) + if value[16] != colon || minute > Int(59) { + throw JSONDecodingError.malformedTimestamp + } + + // Second: 2 digits (following char is checked below) + let second = try fromAscii2(value[17], value[18]) + if second > Int(61) { + throw JSONDecodingError.malformedTimestamp + } + + // timegm() is almost entirely useless. It's nonexistent on + // some platforms, broken on others. Everything else I've tried + // is even worse. Hence the code below. + // (If you have a better way to do this, try it and see if it + // passes the test suite on both Linux and OS X.) + + // Day of year + let mdayStart: [Int] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334] + var yday = Int64(mdayStart[month - 1]) + let isleap = (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0)) + if isleap && (month > 2) { + yday += 1 + } + yday += Int64(mday - 1) + + // Days since start of epoch (including leap days) + var daysSinceEpoch = yday + daysSinceEpoch += Int64(365 * year) - Int64(719527) + daysSinceEpoch += Int64((year - 1) / 4) + daysSinceEpoch -= Int64((year - 1) / 100) + daysSinceEpoch += Int64((year - 1) / 400) + + // Second within day + var daySec = Int64(hour) + daySec *= 60 + daySec += Int64(minute) + daySec *= 60 + daySec += Int64(second) + + // Seconds since start of epoch + let t = daysSinceEpoch * Int64(86400) + daySec + + // After seconds, comes various optional bits + var pos = 19 + + var nanos: Int32 = 0 + if value[pos] == period { // "." begins fractional seconds + pos += 1 + var digitValue = 100000000 + while pos < value.count && value[pos] >= zero && value[pos] <= nine { + nanos += Int32(digitValue * (value[pos] - zero)) + digitValue /= 10 + pos += 1 + } + } + + var seconds: Int64 = 0 + // "Z" or "+" or "-" starts Timezone offset + if pos >= value.count { + throw JSONDecodingError.malformedTimestamp + } else if value[pos] == plus || value[pos] == dash { + if pos + 6 > value.count { + throw JSONDecodingError.malformedTimestamp + } + let hourOffset = try fromAscii2(value[pos + 1], value[pos + 2]) + let minuteOffset = try fromAscii2(value[pos + 4], value[pos + 5]) + if hourOffset > Int(13) || minuteOffset > Int(59) || value[pos + 3] != colon { + throw JSONDecodingError.malformedTimestamp + } + var adjusted: Int64 = t + if value[pos] == plus { + adjusted -= Int64(hourOffset) * Int64(3600) + adjusted -= Int64(minuteOffset) * Int64(60) + } else { + adjusted += Int64(hourOffset) * Int64(3600) + adjusted += Int64(minuteOffset) * Int64(60) + } + if adjusted < minTimestampSeconds || adjusted > maxTimestampSeconds { + throw JSONDecodingError.malformedTimestamp + } + seconds = adjusted + pos += 6 + } else if value[pos] == letterZ { // "Z" indicator for UTC + seconds = t + pos += 1 + } else { + throw JSONDecodingError.malformedTimestamp + } + if pos != value.count { + throw JSONDecodingError.malformedTimestamp + } + return (seconds, nanos) +} + +private func formatTimestamp(seconds: Int64, nanos: Int32) -> String? { + let (seconds, nanos) = normalizeForTimestamp(seconds: seconds, nanos: nanos) + guard seconds >= minTimestampSeconds && seconds <= maxTimestampSeconds else { + return nil + } + + let (hh, mm, ss) = timeOfDayFromSecondsSince1970(seconds: seconds) + let (YY, MM, DD) = gregorianDateFromSecondsSince1970(seconds: seconds) + + let dateString = "\(fourDigit(YY))-\(twoDigit(MM))-\(twoDigit(DD))" + let timeString = "\(twoDigit(hh)):\(twoDigit(mm)):\(twoDigit(ss))" + let nanosString = nanosToString(nanos: nanos) // Includes leading '.' if needed + + return "\(dateString)T\(timeString)\(nanosString)Z" +} + +extension Google_Protobuf_Timestamp { + /// Creates a new `Google_Protobuf_Timestamp` equal to the given number of + /// seconds and nanoseconds. + /// + /// - Parameter seconds: The number of seconds. + /// - Parameter nanos: The number of nanoseconds. + public init(seconds: Int64 = 0, nanos: Int32 = 0) { + self.init() + self.seconds = seconds + self.nanos = nanos + } +} + +extension Google_Protobuf_Timestamp: _CustomJSONCodable { + mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + let s = try decoder.scanner.nextQuotedString() + (seconds, nanos) = try parseTimestamp(s: s) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + if let formatted = formatTimestamp(seconds: seconds, nanos: nanos) { + return "\"\(formatted)\"" + } else { + throw JSONEncodingError.timestampRange + } + } +} + +extension Google_Protobuf_Timestamp { + /// Creates a new `Google_Protobuf_Timestamp` initialized relative to 00:00:00 + /// UTC on 1 January 1970 by a given number of seconds. + /// + /// - Parameter timeIntervalSince1970: The `TimeInterval`, interpreted as + /// seconds relative to 00:00:00 UTC on 1 January 1970. + public init(timeIntervalSince1970: TimeInterval) { + let sd = floor(timeIntervalSince1970) + let nd = round((timeIntervalSince1970 - sd) * TimeInterval(nanosPerSecond)) + let (s, n) = normalizeForTimestamp(seconds: Int64(sd), nanos: Int32(nd)) + self.init(seconds: s, nanos: n) + } + + /// Creates a new `Google_Protobuf_Timestamp` initialized relative to 00:00:00 + /// UTC on 1 January 2001 by a given number of seconds. + /// + /// - Parameter timeIntervalSinceReferenceDate: The `TimeInterval`, + /// interpreted as seconds relative to 00:00:00 UTC on 1 January 2001. + public init(timeIntervalSinceReferenceDate: TimeInterval) { + let sd = floor(timeIntervalSinceReferenceDate) + let nd = round( + (timeIntervalSinceReferenceDate - sd) * TimeInterval(nanosPerSecond)) + // The addition of timeIntervalBetween1970And... is deliberately delayed + // until the input is separated into an integer part and a fraction + // part, so that we don't unnecessarily lose precision. + let (s, n) = normalizeForTimestamp( + seconds: Int64(sd) + Int64(Date.timeIntervalBetween1970AndReferenceDate), + nanos: Int32(nd)) + self.init(seconds: s, nanos: n) + } + + /// Creates a new `Google_Protobuf_Timestamp` initialized to the same time as + /// the given `Date`. + /// + /// - Parameter date: The `Date` with which to initialize the timestamp. + public init(date: Date) { + // Note: Internally, Date uses the "reference date," not the 1970 date. + // We use it when interacting with Dates so that Date doesn't perform + // any double arithmetic on our behalf, which might cost us precision. + self.init( + timeIntervalSinceReferenceDate: date.timeIntervalSinceReferenceDate) + } + + /// The interval between the timestamp and 00:00:00 UTC on 1 January 1970. + public var timeIntervalSince1970: TimeInterval { + return TimeInterval(self.seconds) + + TimeInterval(self.nanos) / TimeInterval(nanosPerSecond) + } + + /// The interval between the timestamp and 00:00:00 UTC on 1 January 2001. + public var timeIntervalSinceReferenceDate: TimeInterval { + return TimeInterval( + self.seconds - Int64(Date.timeIntervalBetween1970AndReferenceDate)) + + TimeInterval(self.nanos) / TimeInterval(nanosPerSecond) + } + + /// A `Date` initialized to the same time as the timestamp. + public var date: Date { + return Date( + timeIntervalSinceReferenceDate: self.timeIntervalSinceReferenceDate) + } +} + +private func normalizeForTimestamp( + seconds: Int64, + nanos: Int32 +) -> (seconds: Int64, nanos: Int32) { + // The Timestamp spec says that nanos must be in the range [0, 999999999), + // as in actual modular arithmetic. + + let s = seconds + Int64(div(nanos, nanosPerSecond)) + let n = mod(nanos, nanosPerSecond) + return (seconds: s, nanos: n) +} + +public func + ( + lhs: Google_Protobuf_Timestamp, + rhs: Google_Protobuf_Duration +) -> Google_Protobuf_Timestamp { + let (s, n) = normalizeForTimestamp(seconds: lhs.seconds + rhs.seconds, + nanos: lhs.nanos + rhs.nanos) + return Google_Protobuf_Timestamp(seconds: s, nanos: n) +} + +public func + ( + lhs: Google_Protobuf_Duration, + rhs: Google_Protobuf_Timestamp +) -> Google_Protobuf_Timestamp { + let (s, n) = normalizeForTimestamp(seconds: lhs.seconds + rhs.seconds, + nanos: lhs.nanos + rhs.nanos) + return Google_Protobuf_Timestamp(seconds: s, nanos: n) +} + +public func - ( + lhs: Google_Protobuf_Timestamp, + rhs: Google_Protobuf_Duration +) -> Google_Protobuf_Timestamp { + let (s, n) = normalizeForTimestamp(seconds: lhs.seconds - rhs.seconds, + nanos: lhs.nanos - rhs.nanos) + return Google_Protobuf_Timestamp(seconds: s, nanos: n) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift new file mode 100644 index 00000000..63301dcc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift @@ -0,0 +1,163 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift - Value extensions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Value is a well-known message type that can be used to parse or encode +/// arbitrary JSON without a predefined schema. +/// +// ----------------------------------------------------------------------------- + +extension Google_Protobuf_Value: ExpressibleByIntegerLiteral { + public typealias IntegerLiteralType = Int64 + + /// Creates a new `Google_Protobuf_Value` from an integer literal. + public init(integerLiteral value: Int64) { + self.init(kind: .numberValue(Double(value))) + } +} + +extension Google_Protobuf_Value: ExpressibleByFloatLiteral { + public typealias FloatLiteralType = Double + + /// Creates a new `Google_Protobuf_Value` from a floating point literal. + public init(floatLiteral value: Double) { + self.init(kind: .numberValue(value)) + } +} + +extension Google_Protobuf_Value: ExpressibleByBooleanLiteral { + public typealias BooleanLiteralType = Bool + + /// Creates a new `Google_Protobuf_Value` from a boolean literal. + public init(booleanLiteral value: Bool) { + self.init(kind: .boolValue(value)) + } +} + +extension Google_Protobuf_Value: ExpressibleByStringLiteral { + public typealias StringLiteralType = String + public typealias ExtendedGraphemeClusterLiteralType = String + public typealias UnicodeScalarLiteralType = String + + /// Creates a new `Google_Protobuf_Value` from a string literal. + public init(stringLiteral value: String) { + self.init(kind: .stringValue(value)) + } + + /// Creates a new `Google_Protobuf_Value` from a Unicode scalar literal. + public init(unicodeScalarLiteral value: String) { + self.init(kind: .stringValue(value)) + } + + /// Creates a new `Google_Protobuf_Value` from a character literal. + public init(extendedGraphemeClusterLiteral value: String) { + self.init(kind: .stringValue(value)) + } +} + +extension Google_Protobuf_Value: ExpressibleByNilLiteral { + /// Creates a new `Google_Protobuf_Value` from the nil literal. + public init(nilLiteral: ()) { + self.init(kind: .nullValue(.nullValue)) + } +} + +extension Google_Protobuf_Value: _CustomJSONCodable { + internal func encodedJSONString(options: JSONEncodingOptions) throws -> String { + var jsonEncoder = JSONEncoder() + try serializeJSONValue(to: &jsonEncoder, options: options) + return jsonEncoder.stringResult + } + + internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + let c = try decoder.scanner.peekOneCharacter() + switch c { + case "n": + if !decoder.scanner.skipOptionalNull() { + throw JSONDecodingError.failure + } + kind = .nullValue(.nullValue) + case "[": + var l = Google_Protobuf_ListValue() + try l.decodeJSON(from: &decoder) + kind = .listValue(l) + case "{": + var s = Google_Protobuf_Struct() + try s.decodeJSON(from: &decoder) + kind = .structValue(s) + case "t", "f": + let b = try decoder.scanner.nextBool() + kind = .boolValue(b) + case "\"": + let s = try decoder.scanner.nextQuotedString() + kind = .stringValue(s) + default: + let d = try decoder.scanner.nextDouble() + kind = .numberValue(d) + } + } + + internal static func decodedFromJSONNull() -> Google_Protobuf_Value? { + return Google_Protobuf_Value(kind: .nullValue(.nullValue)) + } +} + +extension Google_Protobuf_Value { + /// Creates a new `Google_Protobuf_Value` with the given kind. + fileprivate init(kind: OneOf_Kind) { + self.init() + self.kind = kind + } + + /// Creates a new `Google_Protobuf_Value` whose `kind` is `numberValue` with + /// the given floating-point value. + public init(numberValue: Double) { + self.init(kind: .numberValue(numberValue)) + } + + /// Creates a new `Google_Protobuf_Value` whose `kind` is `stringValue` with + /// the given string value. + public init(stringValue: String) { + self.init(kind: .stringValue(stringValue)) + } + + /// Creates a new `Google_Protobuf_Value` whose `kind` is `boolValue` with the + /// given boolean value. + public init(boolValue: Bool) { + self.init(kind: .boolValue(boolValue)) + } + + /// Creates a new `Google_Protobuf_Value` whose `kind` is `structValue` with + /// the given `Google_Protobuf_Struct` value. + public init(structValue: Google_Protobuf_Struct) { + self.init(kind: .structValue(structValue)) + } + + /// Creates a new `Google_Protobuf_Value` whose `kind` is `listValue` with the + /// given `Google_Struct_ListValue` value. + public init(listValue: Google_Protobuf_ListValue) { + self.init(kind: .listValue(listValue)) + } + + /// Writes out the JSON representation of the value to the given encoder. + internal func serializeJSONValue( + to encoder: inout JSONEncoder, + options: JSONEncodingOptions + ) throws { + switch kind { + case .nullValue?: encoder.putNullValue() + case .numberValue(let v)?: encoder.putDoubleValue(value: v) + case .stringValue(let v)?: encoder.putStringValue(value: v) + case .boolValue(let v)?: encoder.putBoolValue(value: v) + case .structValue(let v)?: encoder.append(text: try v.jsonString(options: options)) + case .listValue(let v)?: encoder.append(text: try v.jsonString(options: options)) + case nil: throw JSONEncodingError.missingValue + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift new file mode 100644 index 00000000..625262db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift @@ -0,0 +1,247 @@ +// Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift - Well-known wrapper type extensions +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extensions to the well-known types in wrapper.proto that customize the JSON +/// format of those messages and provide convenience initializers from literals. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Internal protocol that minimizes the code duplication across the multiple +/// wrapper types extended below. +protocol ProtobufWrapper { + + /// The wrapped protobuf type (for example, `ProtobufDouble`). + associatedtype WrappedType: FieldType + + /// Exposes the generated property to the extensions here. + var value: WrappedType.BaseType { get set } + + /// Exposes the parameterless initializer to the extensions here. + init() + + /// Creates a new instance of the wrapper with the given value. + init(_ value: WrappedType.BaseType) +} + +extension ProtobufWrapper { + mutating func decodeJSON(from decoder: inout JSONDecoder) throws { + var v: WrappedType.BaseType? + try WrappedType.decodeSingular(value: &v, from: &decoder) + value = v ?? WrappedType.proto3DefaultValue + } +} + +extension Google_Protobuf_DoubleValue: + ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufDouble + public typealias FloatLiteralType = WrappedType.BaseType + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(floatLiteral: FloatLiteralType) { + self.init(floatLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + if value.isFinite { + // Swift 4.2 and later guarantees that this is accurate + // enough to parse back to the exact value on the other end. + return value.description + } else { + // Protobuf-specific handling of NaN and infinities + var encoder = JSONEncoder() + encoder.putDoubleValue(value: value) + return encoder.stringResult + } + } +} + +extension Google_Protobuf_FloatValue: + ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufFloat + public typealias FloatLiteralType = Float + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(floatLiteral: FloatLiteralType) { + self.init(floatLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + if value.isFinite { + // Swift 4.2 and later guarantees that this is accurate + // enough to parse back to the exact value on the other end. + return value.description + } else { + // Protobuf-specific handling of NaN and infinities + var encoder = JSONEncoder() + encoder.putFloatValue(value: value) + return encoder.stringResult + } + } +} + +extension Google_Protobuf_Int64Value: + ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufInt64 + public typealias IntegerLiteralType = WrappedType.BaseType + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(integerLiteral: IntegerLiteralType) { + self.init(integerLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return "\"" + String(value) + "\"" + } +} + +extension Google_Protobuf_UInt64Value: + ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufUInt64 + public typealias IntegerLiteralType = WrappedType.BaseType + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(integerLiteral: IntegerLiteralType) { + self.init(integerLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return "\"" + String(value) + "\"" + } +} + +extension Google_Protobuf_Int32Value: + ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufInt32 + public typealias IntegerLiteralType = WrappedType.BaseType + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(integerLiteral: IntegerLiteralType) { + self.init(integerLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return String(value) + } +} + +extension Google_Protobuf_UInt32Value: + ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufUInt32 + public typealias IntegerLiteralType = WrappedType.BaseType + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(integerLiteral: IntegerLiteralType) { + self.init(integerLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return String(value) + } +} + +extension Google_Protobuf_BoolValue: + ProtobufWrapper, ExpressibleByBooleanLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufBool + public typealias BooleanLiteralType = Bool + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(booleanLiteral: Bool) { + self.init(booleanLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + return value ? "true" : "false" + } +} + +extension Google_Protobuf_StringValue: + ProtobufWrapper, ExpressibleByStringLiteral, _CustomJSONCodable { + + public typealias WrappedType = ProtobufString + public typealias StringLiteralType = String + public typealias ExtendedGraphemeClusterLiteralType = String + public typealias UnicodeScalarLiteralType = String + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + public init(stringLiteral: String) { + self.init(stringLiteral) + } + + public init(extendedGraphemeClusterLiteral: String) { + self.init(extendedGraphemeClusterLiteral) + } + + public init(unicodeScalarLiteral: String) { + self.init(unicodeScalarLiteral) + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + var encoder = JSONEncoder() + encoder.putStringValue(value: value) + return encoder.stringResult + } +} + +extension Google_Protobuf_BytesValue: ProtobufWrapper, _CustomJSONCodable { + + public typealias WrappedType = ProtobufBytes + + public init(_ value: WrappedType.BaseType) { + self.init() + self.value = value + } + + func encodedJSONString(options: JSONEncodingOptions) throws -> String { + var encoder = JSONEncoder() + encoder.putBytesValue(value: value) + return encoder.stringResult + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/HashVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/HashVisitor.swift new file mode 100644 index 00000000..395af2ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/HashVisitor.swift @@ -0,0 +1,426 @@ +// Sources/SwiftProtobuf/HashVisitor.swift - Hashing support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Hashing is basically a serialization problem, so we can leverage the +/// generated traversal methods for that. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let i_2166136261 = Int(bitPattern: 2166136261) +private let i_16777619 = Int(16777619) + +/// Computes the hash of a message by visiting its fields recursively. +/// +/// Note that because this visits every field, it has the potential to be slow +/// for large or deeply nested messages. Users who need to use such messages as +/// dictionary keys or set members can use a wrapper struct around the message +/// and use a custom Hashable implementation that looks at the subset of the +/// message fields they want to include. +internal struct HashVisitor: Visitor { + +#if swift(>=4.2) + internal private(set) var hasher: Hasher +#else // swift(>=4.2) + // Roughly based on FNV hash: http://tools.ietf.org/html/draft-eastlake-fnv-03 + private(set) var hashValue = i_2166136261 + + private mutating func mix(_ hash: Int) { + hashValue = (hashValue ^ hash) &* i_16777619 + } + + private mutating func mixMap(map: Dictionary) { + var mapHash = 0 + for (k, v) in map { + // Note: This calculation cannot depend on the order of the items. + mapHash = mapHash &+ (k.hashValue ^ v.hashValue) + } + mix(mapHash) + } +#endif // swift(>=4.2) + +#if swift(>=4.2) + init(_ hasher: Hasher) { + self.hasher = hasher + } +#else + init() {} +#endif + + mutating func visitUnknown(bytes: Data) throws { + #if swift(>=4.2) + hasher.combine(bytes) + #else + mix(bytes.hashValue) + #endif + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularEnumField(value: E, + fieldNumber: Int) { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitSingularMessageField(value: M, fieldNumber: Int) { + #if swift(>=4.2) + hasher.combine(fieldNumber) + value.hash(into: &hasher) + #else + mix(fieldNumber) + mix(value.hashValue) + #endif + } + + mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedMessageField(value: [M], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + for v in value { + v.hash(into: &hasher) + } + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws { + assert(!value.isEmpty) + #if swift(>=4.2) + hasher.combine(fieldNumber) + for v in value { + v.hash(into: &hasher) + } + #else + mix(fieldNumber) + for v in value { + mix(v.hashValue) + } + #endif + } + + mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int + ) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mixMap(map: value) + #endif + } + + mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int + ) throws where ValueType.RawValue == Int { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mixMap(map: value) + #endif + } + + mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int + ) throws { + #if swift(>=4.2) + hasher.combine(fieldNumber) + hasher.combine(value) + #else + mix(fieldNumber) + mixMap(map: value) + #endif + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Internal.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Internal.swift new file mode 100644 index 00000000..8619bbd9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Internal.swift @@ -0,0 +1,51 @@ +// Sources/SwiftProtobuf/Internal.swift - Message support +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Internal helpers on Messages for the library. These are public +/// just so the generated code can call them, but shouldn't be called +/// by developers directly. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Functions that are public only because they are used by generated message +/// implementations. NOT INTENDED TO BE CALLED BY CLIENTS. +public enum Internal { + + /// A singleton instance of an empty data that is used by the generated code + /// for default values. This is a performance enhancement to work around the + /// fact that the `Data` type in Swift involves a new heap allocation every + /// time an empty instance is initialized, instead of sharing a common empty + /// backing storage. + public static let emptyData = Data() + + /// Helper to loop over a list of Messages to see if they are all + /// initialized (see Message.isInitialized for what that means). + public static func areAllInitialized(_ listOfMessages: [Message]) -> Bool { + for msg in listOfMessages { + if !msg.isInitialized { + return false + } + } + return true + } + + /// Helper to loop over dictionary with values that are Messages to see if + /// they are all initialized (see Message.isInitialized for what that means). + public static func areAllInitialized(_ mapToMessages: [K: Message]) -> Bool { + for (_, msg) in mapToMessages { + if !msg.isInitialized { + return false + } + } + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecoder.swift new file mode 100644 index 00000000..5f085e45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecoder.swift @@ -0,0 +1,735 @@ +// Sources/SwiftProtobuf/JSONDecoder.swift - JSON format decoding +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON format decoding engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +internal struct JSONDecoder: Decoder { + internal var scanner: JSONScanner + internal var messageType: Message.Type + private var fieldCount = 0 + private var isMapKey = false + private var fieldNameMap: _NameMap? + + internal var options: JSONDecodingOptions { + return scanner.options + } + + mutating func handleConflictingOneOf() throws { + throw JSONDecodingError.conflictingOneOf + } + + internal init(source: UnsafeRawBufferPointer, options: JSONDecodingOptions, + messageType: Message.Type, extensions: ExtensionMap?) { + let scanner = JSONScanner(source: source, + options: options, + extensions: extensions) + self.init(scanner: scanner, messageType: messageType) + } + + private init(scanner: JSONScanner, messageType: Message.Type) { + self.scanner = scanner + self.messageType = messageType + } + + mutating func nextFieldNumber() throws -> Int? { + if scanner.skipOptionalObjectEnd() { + return nil + } + if fieldCount > 0 { + try scanner.skipRequiredComma() + } + let fieldNumber = try scanner.nextFieldNumber(names: fieldNameMap!, + messageType: messageType) + if let fieldNumber = fieldNumber { + fieldCount += 1 + return fieldNumber + } + return nil + } + + mutating func decodeSingularFloatField(value: inout Float) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + value = try scanner.nextFloat() + } + + mutating func decodeSingularFloatField(value: inout Float?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextFloat() + } + + mutating func decodeRepeatedFloatField(value: inout [Float]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextFloat() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularDoubleField(value: inout Double) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + value = try scanner.nextDouble() + } + + mutating func decodeSingularDoubleField(value: inout Double?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextDouble() + } + + mutating func decodeRepeatedDoubleField(value: inout [Double]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextDouble() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularInt32Field(value: inout Int32) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw JSONDecodingError.numberRange + } + value = Int32(truncatingIfNeeded: n) + } + + mutating func decodeSingularInt32Field(value: inout Int32?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw JSONDecodingError.numberRange + } + value = Int32(truncatingIfNeeded: n) + } + + mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw JSONDecodingError.numberRange + } + value.append(Int32(truncatingIfNeeded: n)) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularInt64Field(value: inout Int64) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + value = try scanner.nextSInt() + } + + mutating func decodeSingularInt64Field(value: inout Int64?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextSInt() + } + + mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextSInt() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularUInt32Field(value: inout UInt32) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw JSONDecodingError.numberRange + } + value = UInt32(truncatingIfNeeded: n) + } + + mutating func decodeSingularUInt32Field(value: inout UInt32?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw JSONDecodingError.numberRange + } + value = UInt32(truncatingIfNeeded: n) + } + + mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw JSONDecodingError.numberRange + } + value.append(UInt32(truncatingIfNeeded: n)) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularUInt64Field(value: inout UInt64) throws { + if scanner.skipOptionalNull() { + value = 0 + return + } + value = try scanner.nextUInt() + } + + mutating func decodeSingularUInt64Field(value: inout UInt64?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextUInt() + } + + mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextUInt() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularSInt32Field(value: inout Int32) throws { + try decodeSingularInt32Field(value: &value) + } + + mutating func decodeSingularSInt32Field(value: inout Int32?) throws { + try decodeSingularInt32Field(value: &value) + } + + mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws { + try decodeRepeatedInt32Field(value: &value) + } + + mutating func decodeSingularSInt64Field(value: inout Int64) throws { + try decodeSingularInt64Field(value: &value) + } + + mutating func decodeSingularSInt64Field(value: inout Int64?) throws { + try decodeSingularInt64Field(value: &value) + } + + mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws { + try decodeRepeatedInt64Field(value: &value) + } + + mutating func decodeSingularFixed32Field(value: inout UInt32) throws { + try decodeSingularUInt32Field(value: &value) + } + + mutating func decodeSingularFixed32Field(value: inout UInt32?) throws { + try decodeSingularUInt32Field(value: &value) + } + + mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws { + try decodeRepeatedUInt32Field(value: &value) + } + + mutating func decodeSingularFixed64Field(value: inout UInt64) throws { + try decodeSingularUInt64Field(value: &value) + } + + mutating func decodeSingularFixed64Field(value: inout UInt64?) throws { + try decodeSingularUInt64Field(value: &value) + } + + mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws { + try decodeRepeatedUInt64Field(value: &value) + } + + mutating func decodeSingularSFixed32Field(value: inout Int32) throws { + try decodeSingularInt32Field(value: &value) + } + + mutating func decodeSingularSFixed32Field(value: inout Int32?) throws { + try decodeSingularInt32Field(value: &value) + } + + mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws { + try decodeRepeatedInt32Field(value: &value) + } + + mutating func decodeSingularSFixed64Field(value: inout Int64) throws { + try decodeSingularInt64Field(value: &value) + } + + mutating func decodeSingularSFixed64Field(value: inout Int64?) throws { + try decodeSingularInt64Field(value: &value) + } + + mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws { + try decodeRepeatedInt64Field(value: &value) + } + + mutating func decodeSingularBoolField(value: inout Bool) throws { + if scanner.skipOptionalNull() { + value = false + return + } + if isMapKey { + value = try scanner.nextQuotedBool() + } else { + value = try scanner.nextBool() + } + } + + mutating func decodeSingularBoolField(value: inout Bool?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + if isMapKey { + value = try scanner.nextQuotedBool() + } else { + value = try scanner.nextBool() + } + } + + mutating func decodeRepeatedBoolField(value: inout [Bool]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextBool() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularStringField(value: inout String) throws { + if scanner.skipOptionalNull() { + value = String() + return + } + value = try scanner.nextQuotedString() + } + + mutating func decodeSingularStringField(value: inout String?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextQuotedString() + } + + mutating func decodeRepeatedStringField(value: inout [String]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextQuotedString() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularBytesField(value: inout Data) throws { + if scanner.skipOptionalNull() { + value = Data() + return + } + value = try scanner.nextBytesValue() + } + + mutating func decodeSingularBytesField(value: inout Data?) throws { + if scanner.skipOptionalNull() { + value = nil + return + } + value = try scanner.nextBytesValue() + } + + mutating func decodeRepeatedBytesField(value: inout [Data]) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + let n = try scanner.nextBytesValue() + value.append(n) + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularEnumField(value: inout E?) throws + where E.RawValue == Int { + if scanner.skipOptionalNull() { + if let customDecodable = E.self as? _CustomJSONCodable.Type { + value = try customDecodable.decodedFromJSONNull() as? E + return + } + value = nil + return + } + value = try scanner.nextEnumValue() as E + } + + mutating func decodeSingularEnumField(value: inout E) throws + where E.RawValue == Int { + if scanner.skipOptionalNull() { + if let customDecodable = E.self as? _CustomJSONCodable.Type { + value = try customDecodable.decodedFromJSONNull() as! E + return + } + value = E() + return + } + value = try scanner.nextEnumValue() + } + + mutating func decodeRepeatedEnumField(value: inout [E]) throws + where E.RawValue == Int { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + let maybeCustomDecodable = E.self as? _CustomJSONCodable.Type + while true { + if scanner.skipOptionalNull() { + if let customDecodable = maybeCustomDecodable { + let e = try customDecodable.decodedFromJSONNull() as! E + value.append(e) + } else { + throw JSONDecodingError.illegalNull + } + } else { + let e: E = try scanner.nextEnumValue() + value.append(e) + } + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + internal mutating func decodeFullObject(message: inout M) throws { + guard let nameProviding = (M.self as? _ProtoNameProviding.Type) else { + throw JSONDecodingError.missingFieldNames + } + fieldNameMap = nameProviding._protobuf_nameMap + if let m = message as? _CustomJSONCodable { + var customCodable = m + try customCodable.decodeJSON(from: &self) + message = customCodable as! M + } else { + try scanner.skipRequiredObjectStart() + if scanner.skipOptionalObjectEnd() { + return + } + try message.decodeMessage(decoder: &self) + } + } + + mutating func decodeSingularMessageField(value: inout M?) throws { + if scanner.skipOptionalNull() { + if M.self is _CustomJSONCodable.Type { + value = + try (M.self as! _CustomJSONCodable.Type).decodedFromJSONNull() as? M + return + } + // All other message field types treat 'null' as an unset + value = nil + return + } + if value == nil { + value = M() + } + var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self) + try subDecoder.decodeFullObject(message: &value!) + assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget) + scanner = subDecoder.scanner + } + + mutating func decodeRepeatedMessageField( + value: inout [M] + ) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredArrayStart() + if scanner.skipOptionalArrayEnd() { + return + } + while true { + if scanner.skipOptionalNull() { + var appended = false + if M.self is _CustomJSONCodable.Type { + if let message = try (M.self as! _CustomJSONCodable.Type) + .decodedFromJSONNull() as? M { + value.append(message) + appended = true + } + } + if !appended { + throw JSONDecodingError.illegalNull + } + } else { + var message = M() + var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self) + try subDecoder.decodeFullObject(message: &message) + value.append(message) + assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget) + scanner = subDecoder.scanner + } + if scanner.skipOptionalArrayEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeSingularGroupField(value: inout G?) throws { + throw JSONDecodingError.schemaMismatch + } + + mutating func decodeRepeatedGroupField(value: inout [G]) throws { + throw JSONDecodingError.schemaMismatch + } + + mutating func decodeMapField( + fieldType: _ProtobufMap.Type, + value: inout _ProtobufMap.BaseType + ) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredObjectStart() + if scanner.skipOptionalObjectEnd() { + return + } + while true { + // Next character must be double quote, because + // map keys must always be quoted strings. + let c = try scanner.peekOneCharacter() + if c != "\"" { + throw JSONDecodingError.unquotedMapKey + } + isMapKey = true + var keyField: KeyType.BaseType? + try KeyType.decodeSingular(value: &keyField, from: &self) + isMapKey = false + try scanner.skipRequiredColon() + var valueField: ValueType.BaseType? + try ValueType.decodeSingular(value: &valueField, from: &self) + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + } else { + throw JSONDecodingError.malformedMap + } + if scanner.skipOptionalObjectEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeMapField( + fieldType: _ProtobufEnumMap.Type, + value: inout _ProtobufEnumMap.BaseType + ) throws where ValueType.RawValue == Int { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredObjectStart() + if scanner.skipOptionalObjectEnd() { + return + } + while true { + // Next character must be double quote, because + // map keys must always be quoted strings. + let c = try scanner.peekOneCharacter() + if c != "\"" { + throw JSONDecodingError.unquotedMapKey + } + isMapKey = true + var keyField: KeyType.BaseType? + try KeyType.decodeSingular(value: &keyField, from: &self) + isMapKey = false + try scanner.skipRequiredColon() + var valueField: ValueType? + try decodeSingularEnumField(value: &valueField) + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + } else { + throw JSONDecodingError.malformedMap + } + if scanner.skipOptionalObjectEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeMapField( + fieldType: _ProtobufMessageMap.Type, + value: inout _ProtobufMessageMap.BaseType + ) throws { + if scanner.skipOptionalNull() { + return + } + try scanner.skipRequiredObjectStart() + if scanner.skipOptionalObjectEnd() { + return + } + while true { + // Next character must be double quote, because + // map keys must always be quoted strings. + let c = try scanner.peekOneCharacter() + if c != "\"" { + throw JSONDecodingError.unquotedMapKey + } + isMapKey = true + var keyField: KeyType.BaseType? + try KeyType.decodeSingular(value: &keyField, from: &self) + isMapKey = false + try scanner.skipRequiredColon() + var valueField: ValueType? + try decodeSingularMessageField(value: &valueField) + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + } else { + throw JSONDecodingError.malformedMap + } + if scanner.skipOptionalObjectEnd() { + return + } + try scanner.skipRequiredComma() + } + } + + mutating func decodeExtensionField( + values: inout ExtensionFieldValueSet, + messageType: Message.Type, + fieldNumber: Int + ) throws { + // Force-unwrap: we can only get here if the extension exists. + let ext = scanner.extensions[messageType, fieldNumber]! + + try values.modify(index: fieldNumber) { fieldValue in + if fieldValue != nil { + try fieldValue!.decodeExtensionField(decoder: &self) + } else { + fieldValue = try ext._protobuf_newField(decoder: &self) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingError.swift new file mode 100644 index 00000000..35a407c5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingError.swift @@ -0,0 +1,62 @@ +// Sources/SwiftProtobuf/JSONDecodingError.swift - JSON decoding errors +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON decoding errors +/// +// ----------------------------------------------------------------------------- + +public enum JSONDecodingError: Error { + /// Something was wrong + case failure + /// A number could not be parsed + case malformedNumber + /// Numeric value was out of range or was not an integer value when expected + case numberRange + /// A map could not be parsed + case malformedMap + /// A bool could not be parsed + case malformedBool + /// We expected a quoted string, or a quoted string has a malformed backslash sequence + case malformedString + /// We encountered malformed UTF8 + case invalidUTF8 + /// The message does not have fieldName information + case missingFieldNames + /// The data type does not match the schema description + case schemaMismatch + /// A value (text or numeric) for an enum was not found on the enum + case unrecognizedEnumValue + /// A 'null' token appeared in an illegal location. + /// For example, Protobuf JSON does not allow 'null' tokens to appear + /// in lists. + case illegalNull + /// A map key was not quoted + case unquotedMapKey + /// JSON RFC 7519 does not allow numbers to have extra leading zeros + case leadingZero + /// We hit the end of the JSON string and expected something more... + case truncated + /// A JSON Duration could not be parsed + case malformedDuration + /// A JSON Timestamp could not be parsed + case malformedTimestamp + /// A FieldMask could not be parsed + case malformedFieldMask + /// Extraneous data remained after decoding should have been complete + case trailingGarbage + /// More than one value was specified for the same oneof field + case conflictingOneOf + /// Reached the nesting limit for messages within messages while decoding. + case messageDepthLimit + /// Encountered an unknown field with the given name. When parsing JSON, you + /// can instead instruct the library to ignore this via + /// JSONDecodingOptions.ignoreUnknownFields. + case unknownField(String) +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingOptions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingOptions.swift new file mode 100644 index 00000000..2f06e39f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONDecodingOptions.swift @@ -0,0 +1,29 @@ +// Sources/SwiftProtobuf/JSONDecodingOptions.swift - JSON decoding options +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON decoding options +/// +// ----------------------------------------------------------------------------- + +/// Options for JSONDecoding. +public struct JSONDecodingOptions { + /// The maximum nesting of message with messages. The default is 100. + /// + /// To prevent corrupt or malicious messages from causing stack overflows, + /// this controls how deep messages can be nested within other messages + /// while parsing. + public var messageDepthLimit: Int = 100 + + /// If unknown fields in the JSON should be ignored. If they aren't + /// ignored, an error will be raised if one is encountered. + public var ignoreUnknownFields: Bool = false + + public init() {} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncoder.swift new file mode 100644 index 00000000..61c53f70 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncoder.swift @@ -0,0 +1,386 @@ +// Sources/SwiftProtobuf/JSONEncoder.swift - JSON Encoding support +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON serialization engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let asciiZero = UInt8(ascii: "0") +private let asciiOne = UInt8(ascii: "1") +private let asciiTwo = UInt8(ascii: "2") +private let asciiThree = UInt8(ascii: "3") +private let asciiFour = UInt8(ascii: "4") +private let asciiFive = UInt8(ascii: "5") +private let asciiSix = UInt8(ascii: "6") +private let asciiSeven = UInt8(ascii: "7") +private let asciiEight = UInt8(ascii: "8") +private let asciiNine = UInt8(ascii: "9") +private let asciiMinus = UInt8(ascii: "-") +private let asciiPlus = UInt8(ascii: "+") +private let asciiEquals = UInt8(ascii: "=") +private let asciiColon = UInt8(ascii: ":") +private let asciiComma = UInt8(ascii: ",") +private let asciiDoubleQuote = UInt8(ascii: "\"") +private let asciiBackslash = UInt8(ascii: "\\") +private let asciiForwardSlash = UInt8(ascii: "/") +private let asciiOpenSquareBracket = UInt8(ascii: "[") +private let asciiCloseSquareBracket = UInt8(ascii: "]") +private let asciiOpenCurlyBracket = UInt8(ascii: "{") +private let asciiCloseCurlyBracket = UInt8(ascii: "}") +private let asciiUpperA = UInt8(ascii: "A") +private let asciiUpperB = UInt8(ascii: "B") +private let asciiUpperC = UInt8(ascii: "C") +private let asciiUpperD = UInt8(ascii: "D") +private let asciiUpperE = UInt8(ascii: "E") +private let asciiUpperF = UInt8(ascii: "F") +private let asciiUpperZ = UInt8(ascii: "Z") +private let asciiLowerA = UInt8(ascii: "a") +private let asciiLowerZ = UInt8(ascii: "z") + +private let base64Digits: [UInt8] = { + var digits = [UInt8]() + digits.append(contentsOf: asciiUpperA...asciiUpperZ) + digits.append(contentsOf: asciiLowerA...asciiLowerZ) + digits.append(contentsOf: asciiZero...asciiNine) + digits.append(asciiPlus) + digits.append(asciiForwardSlash) + return digits +}() + +private let hexDigits: [UInt8] = { + var digits = [UInt8]() + digits.append(contentsOf: asciiZero...asciiNine) + digits.append(contentsOf: asciiUpperA...asciiUpperF) + return digits +}() + +internal struct JSONEncoder { + private var data = [UInt8]() + private var separator: UInt8? + + internal init() {} + + internal var dataResult: Data { return Data(data) } + + internal var stringResult: String { + get { + return String(bytes: data, encoding: String.Encoding.utf8)! + } + } + + /// Append a `StaticString` to the JSON text. Because + /// `StaticString` is already UTF8 internally, this is faster + /// than appending a regular `String`. + internal mutating func append(staticText: StaticString) { + let buff = UnsafeBufferPointer(start: staticText.utf8Start, count: staticText.utf8CodeUnitCount) + data.append(contentsOf: buff) + } + + /// Append a `_NameMap.Name` to the JSON text surrounded by quotes. + /// As with StaticString above, a `_NameMap.Name` provides pre-converted + /// UTF8 bytes, so this is much faster than appending a regular + /// `String`. + internal mutating func appendQuoted(name: _NameMap.Name) { + data.append(asciiDoubleQuote) + data.append(contentsOf: name.utf8Buffer) + data.append(asciiDoubleQuote) + } + + /// Append a `String` to the JSON text. + internal mutating func append(text: String) { + data.append(contentsOf: text.utf8) + } + + /// Append a raw utf8 in a `Data` to the JSON text. + internal mutating func append(utf8Data: Data) { + data.append(contentsOf: utf8Data) + } + + /// Begin a new field whose name is given as a `_NameMap.Name` + internal mutating func startField(name: _NameMap.Name) { + if let s = separator { + data.append(s) + } + appendQuoted(name: name) + data.append(asciiColon) + separator = asciiComma + } + + /// Begin a new field whose name is given as a `String`. + internal mutating func startField(name: String) { + if let s = separator { + data.append(s) + } + data.append(asciiDoubleQuote) + // Can avoid overhead of putStringValue, since + // the JSON field names are always clean ASCII. + data.append(contentsOf: name.utf8) + append(staticText: "\":") + separator = asciiComma + } + + /// Begin a new extension field + internal mutating func startExtensionField(name: String) { + if let s = separator { + data.append(s) + } + append(staticText: "\"[") + data.append(contentsOf: name.utf8) + append(staticText: "]\":") + separator = asciiComma + } + + /// Append an open square bracket `[` to the JSON. + internal mutating func startArray() { + data.append(asciiOpenSquareBracket) + separator = nil + } + + /// Append a close square bracket `]` to the JSON. + internal mutating func endArray() { + data.append(asciiCloseSquareBracket) + separator = asciiComma + } + + /// Append a comma `,` to the JSON. + internal mutating func comma() { + data.append(asciiComma) + } + + /// Append an open curly brace `{` to the JSON. + /// Assumes this object is part of an array of objects. + internal mutating func startArrayObject() { + if let s = separator { + data.append(s) + } + data.append(asciiOpenCurlyBracket) + separator = nil + } + + /// Append an open curly brace `{` to the JSON. + internal mutating func startObject() { + data.append(asciiOpenCurlyBracket) + separator = nil + } + + /// Append a close curly brace `}` to the JSON. + internal mutating func endObject() { + data.append(asciiCloseCurlyBracket) + separator = asciiComma + } + + /// Write a JSON `null` token to the output. + internal mutating func putNullValue() { + append(staticText: "null") + } + + /// Append a float value to the output. + /// This handles Nan and infinite values by + /// writing well-known string values. + internal mutating func putFloatValue(value: Float) { + if value.isNaN { + append(staticText: "\"NaN\"") + } else if !value.isFinite { + if value < 0 { + append(staticText: "\"-Infinity\"") + } else { + append(staticText: "\"Infinity\"") + } + } else { + data.append(contentsOf: value.debugDescription.utf8) + } + } + + /// Append a double value to the output. + /// This handles Nan and infinite values by + /// writing well-known string values. + internal mutating func putDoubleValue(value: Double) { + if value.isNaN { + append(staticText: "\"NaN\"") + } else if !value.isFinite { + if value < 0 { + append(staticText: "\"-Infinity\"") + } else { + append(staticText: "\"Infinity\"") + } + } else { + data.append(contentsOf: value.debugDescription.utf8) + } + } + + /// Append a UInt64 to the output (without quoting). + private mutating func appendUInt(value: UInt64) { + if value >= 10 { + appendUInt(value: value / 10) + } + data.append(asciiZero + UInt8(value % 10)) + } + + /// Append an Int64 to the output (without quoting). + private mutating func appendInt(value: Int64) { + if value < 0 { + data.append(asciiMinus) + // This is the twos-complement negation of value, + // computed in a way that won't overflow a 64-bit + // signed integer. + appendUInt(value: 1 + ~UInt64(bitPattern: value)) + } else { + appendUInt(value: UInt64(bitPattern: value)) + } + } + + /// Write an Enum as an int. + internal mutating func putEnumInt(value: Int) { + appendInt(value: Int64(value)) + } + + /// Write an `Int64` using protobuf JSON quoting conventions. + internal mutating func putInt64(value: Int64) { + data.append(asciiDoubleQuote) + appendInt(value: value) + data.append(asciiDoubleQuote) + } + + /// Write an `Int32` with quoting suitable for + /// using the value as a map key. + internal mutating func putQuotedInt32(value: Int32) { + data.append(asciiDoubleQuote) + appendInt(value: Int64(value)) + data.append(asciiDoubleQuote) + } + + /// Write an `Int32` in the default format. + internal mutating func putInt32(value: Int32) { + appendInt(value: Int64(value)) + } + + /// Write a `UInt64` using protobuf JSON quoting conventions. + internal mutating func putUInt64(value: UInt64) { + data.append(asciiDoubleQuote) + appendUInt(value: value) + data.append(asciiDoubleQuote) + } + + /// Write a `UInt32` with quoting suitable for + /// using the value as a map key. + internal mutating func putQuotedUInt32(value: UInt32) { + data.append(asciiDoubleQuote) + appendUInt(value: UInt64(value)) + data.append(asciiDoubleQuote) + } + + /// Write a `UInt32` in the default format. + internal mutating func putUInt32(value: UInt32) { + appendUInt(value: UInt64(value)) + } + + /// Write a `Bool` with quoting suitable for + /// using the value as a map key. + internal mutating func putQuotedBoolValue(value: Bool) { + data.append(asciiDoubleQuote) + putBoolValue(value: value) + data.append(asciiDoubleQuote) + } + + /// Write a `Bool` in the default format. + internal mutating func putBoolValue(value: Bool) { + if value { + append(staticText: "true") + } else { + append(staticText: "false") + } + } + + /// Append a string value escaping special characters as needed. + internal mutating func putStringValue(value: String) { + data.append(asciiDoubleQuote) + for c in value.unicodeScalars { + switch c.value { + // Special two-byte escapes + case 8: append(staticText: "\\b") + case 9: append(staticText: "\\t") + case 10: append(staticText: "\\n") + case 12: append(staticText: "\\f") + case 13: append(staticText: "\\r") + case 34: append(staticText: "\\\"") + case 92: append(staticText: "\\\\") + case 0...31, 127...159: // Hex form for C0 control chars + append(staticText: "\\u00") + data.append(hexDigits[Int(c.value / 16)]) + data.append(hexDigits[Int(c.value & 15)]) + case 23...126: + data.append(UInt8(truncatingIfNeeded: c.value)) + case 0x80...0x7ff: + data.append(0xc0 + UInt8(truncatingIfNeeded: c.value >> 6)) + data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f)) + case 0x800...0xffff: + data.append(0xe0 + UInt8(truncatingIfNeeded: c.value >> 12)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f)) + default: + data.append(0xf0 + UInt8(truncatingIfNeeded: c.value >> 18)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 12) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f)) + } + } + data.append(asciiDoubleQuote) + } + + /// Append a bytes value using protobuf JSON Base-64 encoding. + internal mutating func putBytesValue(value: Data) { + data.append(asciiDoubleQuote) + if value.count > 0 { + value.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let p = body.baseAddress, body.count > 0 { + var t: Int = 0 + var bytesInGroup: Int = 0 + for i in 0..> 18) & 63]) + data.append(base64Digits[(t >> 12) & 63]) + data.append(base64Digits[(t >> 6) & 63]) + data.append(base64Digits[t & 63]) + t = 0 + bytesInGroup = 0 + } + t = (t << 8) + Int(p[i]) + bytesInGroup += 1 + } + switch bytesInGroup { + case 3: + data.append(base64Digits[(t >> 18) & 63]) + data.append(base64Digits[(t >> 12) & 63]) + data.append(base64Digits[(t >> 6) & 63]) + data.append(base64Digits[t & 63]) + case 2: + t <<= 8 + data.append(base64Digits[(t >> 18) & 63]) + data.append(base64Digits[(t >> 12) & 63]) + data.append(base64Digits[(t >> 6) & 63]) + data.append(asciiEquals) + case 1: + t <<= 16 + data.append(base64Digits[(t >> 18) & 63]) + data.append(base64Digits[(t >> 12) & 63]) + data.append(asciiEquals) + data.append(asciiEquals) + default: + break + } + } + } + } + data.append(asciiDoubleQuote) + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingError.swift new file mode 100644 index 00000000..567f949e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingError.swift @@ -0,0 +1,35 @@ +// Sources/SwiftProtobuf/JSONEncodingError.swift - Error constants +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Enum constants that identify the particular error. +/// +// ----------------------------------------------------------------------------- + +public enum JSONEncodingError: Error { + /// Any fields that were decoded from binary format cannot be + /// re-encoded into JSON unless the object they hold is a + /// well-known type or a type registered with via + /// Google_Protobuf_Any.register() + case anyTranscodeFailure + /// Timestamp values can only be JSON encoded if they hold a value + /// between 0001-01-01Z00:00:00 and 9999-12-31Z23:59:59. + case timestampRange + /// Duration values can only be JSON encoded if they hold a value + /// less than +/- 100 years. + case durationRange + /// Field masks get edited when converting between JSON and protobuf + case fieldMaskConversion + /// Field names were not compiled into the binary + case missingFieldNames + /// Instances of `Google_Protobuf_Value` can only be encoded if they have a + /// valid `kind` (that is, they represent a null value, number, boolean, + /// string, struct, or list). + case missingValue +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingOptions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingOptions.swift new file mode 100644 index 00000000..95419096 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingOptions.swift @@ -0,0 +1,26 @@ +// Sources/SwiftProtobuf/JSONEncodingOptions.swift - JSON encoding options +// +// Copyright (c) 2014 - 2018 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON encoding options +/// +// ----------------------------------------------------------------------------- + +/// Options for JSONEncoding. +public struct JSONEncodingOptions { + + /// Always print enums as ints. By default they are printed as strings. + public var alwaysPrintEnumsAsInts: Bool = false + + /// Whether to preserve proto field names. + /// By default they are converted to JSON(lowerCamelCase) names. + public var preserveProtoFieldNames: Bool = false + + public init() {} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingVisitor.swift new file mode 100644 index 00000000..b250314e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONEncodingVisitor.swift @@ -0,0 +1,400 @@ +// Sources/SwiftProtobuf/JSONEncodingVisitor.swift - JSON encoding visitor +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Visitor that writes a message in JSON format. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Visitor that serializes a message into JSON format. +internal struct JSONEncodingVisitor: Visitor { + + private var encoder = JSONEncoder() + private var nameMap: _NameMap + private var extensions: ExtensionFieldValueSet? + private let options: JSONEncodingOptions + + /// The JSON text produced by the visitor, as raw UTF8 bytes. + var dataResult: Data { + return encoder.dataResult + } + + /// The JSON text produced by the visitor, as a String. + internal var stringResult: String { + return encoder.stringResult + } + + /// Creates a new visitor for serializing a message of the given type to JSON + /// format. + init(type: Message.Type, options: JSONEncodingOptions) throws { + if let nameProviding = type as? _ProtoNameProviding.Type { + self.nameMap = nameProviding._protobuf_nameMap + } else { + throw JSONEncodingError.missingFieldNames + } + self.options = options + } + + mutating func startArray() { + encoder.startArray() + } + + mutating func endArray() { + encoder.endArray() + } + + mutating func startObject(message: Message) { + self.extensions = (message as? ExtensibleMessage)?._protobuf_extensionFieldValues + encoder.startObject() + } + + mutating func startArrayObject(message: Message) { + self.extensions = (message as? ExtensibleMessage)?._protobuf_extensionFieldValues + encoder.startArrayObject() + } + + mutating func endObject() { + encoder.endObject() + } + + mutating func encodeField(name: String, stringValue value: String) { + encoder.startField(name: name) + encoder.putStringValue(value: value) + } + + mutating func encodeField(name: String, jsonText text: String) { + encoder.startField(name: name) + encoder.append(text: text) + } + + mutating func visitUnknown(bytes: Data) throws { + // JSON encoding has no provision for carrying proto2 unknown fields. + } + + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putFloatValue(value: value) + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putDoubleValue(value: value) + } + + mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putInt32(value: value) + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putInt64(value: value) + } + + mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putUInt32(value: value) + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putUInt64(value: value) + } + + mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putUInt32(value: value) + } + + mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putInt32(value: value) + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putBoolValue(value: value) + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putStringValue(value: value) + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.putBytesValue(value: value) + } + + private mutating func _visitRepeated( + value: [T], + fieldNumber: Int, + encode: (inout JSONEncoder, T) throws -> () + ) throws { + assert(!value.isEmpty) + try startField(for: fieldNumber) + var comma = false + encoder.startArray() + for v in value { + if comma { + encoder.comma() + } + comma = true + try encode(&encoder, v) + } + encoder.endArray() + } + + mutating func visitSingularEnumField(value: E, fieldNumber: Int) throws { + try startField(for: fieldNumber) + if let e = value as? _CustomJSONCodable { + let json = try e.encodedJSONString(options: options) + encoder.append(text: json) + } else if !options.alwaysPrintEnumsAsInts, let n = value.name { + encoder.appendQuoted(name: n) + } else { + encoder.putEnumInt(value: value.rawValue) + } + } + + mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws { + try startField(for: fieldNumber) + if let m = value as? _CustomJSONCodable { + let json = try m.encodedJSONString(options: options) + encoder.append(text: json) + } else if let newNameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap { + // Preserve outer object's name and extension maps; restore them before returning + let oldNameMap = self.nameMap + let oldExtensions = self.extensions + // Install inner object's name and extension maps + self.nameMap = newNameMap + startObject(message: value) + try value.traverse(visitor: &self) + endObject() + self.nameMap = oldNameMap + self.extensions = oldExtensions + } else { + throw JSONEncodingError.missingFieldNames + } + } + + mutating func visitSingularGroupField(value: G, fieldNumber: Int) throws { + // Google does not serialize groups into JSON + } + + mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Float) in + encoder.putFloatValue(value: v) + } + } + + mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Double) in + encoder.putDoubleValue(value: v) + } + } + + mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Int32) in + encoder.putInt32(value: v) + } + } + + mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Int64) in + encoder.putInt64(value: v) + } + } + + mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: UInt32) in + encoder.putUInt32(value: v) + } + } + + mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: UInt64) in + encoder.putUInt64(value: v) + } + } + + mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Bool) in + encoder.putBoolValue(value: v) + } + } + + mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: String) in + encoder.putStringValue(value: v) + } + } + + mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: Data) in + encoder.putBytesValue(value: v) + } + } + + mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { + if let _ = E.self as? _CustomJSONCodable.Type { + let options = self.options + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: E) throws in + let e = v as! _CustomJSONCodable + let json = try e.encodedJSONString(options: options) + encoder.append(text: json) + } + } else { + let alwaysPrintEnumsAsInts = options.alwaysPrintEnumsAsInts + try _visitRepeated(value: value, fieldNumber: fieldNumber) { + (encoder: inout JSONEncoder, v: E) throws in + if !alwaysPrintEnumsAsInts, let n = v.name { + encoder.appendQuoted(name: n) + } else { + encoder.putEnumInt(value: v.rawValue) + } + } + } + } + + mutating func visitRepeatedMessageField(value: [M], fieldNumber: Int) throws { + assert(!value.isEmpty) + try startField(for: fieldNumber) + var comma = false + encoder.startArray() + if let _ = M.self as? _CustomJSONCodable.Type { + for v in value { + if comma { + encoder.comma() + } + comma = true + let json = try v.jsonString(options: options) + encoder.append(text: json) + } + } else if let newNameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap { + // Preserve name and extension maps for outer object + let oldNameMap = self.nameMap + let oldExtensions = self.extensions + self.nameMap = newNameMap + for v in value { + startArrayObject(message: v) + try v.traverse(visitor: &self) + encoder.endObject() + } + // Restore outer object's name and extension maps before returning + self.nameMap = oldNameMap + self.extensions = oldExtensions + } else { + throw JSONEncodingError.missingFieldNames + } + encoder.endArray() + } + + mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws { + assert(!value.isEmpty) + // Google does not serialize groups into JSON + } + + // Packed fields are handled the same as non-packed fields, so JSON just + // relies on the default implementations in Visitor.swift + + + + mutating func visitMapField(fieldType: _ProtobufMap.Type, value: _ProtobufMap.BaseType, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.append(text: "{") + var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options) + for (k,v) in value { + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor) + try ValueType.visitSingular(value: v, fieldNumber: 2, with: &mapVisitor) + } + encoder = mapVisitor.encoder + encoder.append(text: "}") + } + + mutating func visitMapField(fieldType: _ProtobufEnumMap.Type, value: _ProtobufEnumMap.BaseType, fieldNumber: Int) throws where ValueType.RawValue == Int { + try startField(for: fieldNumber) + encoder.append(text: "{") + var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options) + for (k, v) in value { + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor) + try mapVisitor.visitSingularEnumField(value: v, fieldNumber: 2) + } + encoder = mapVisitor.encoder + encoder.append(text: "}") + } + + mutating func visitMapField(fieldType: _ProtobufMessageMap.Type, value: _ProtobufMessageMap.BaseType, fieldNumber: Int) throws { + try startField(for: fieldNumber) + encoder.append(text: "{") + var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options) + for (k,v) in value { + try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor) + try mapVisitor.visitSingularMessageField(value: v, fieldNumber: 2) + } + encoder = mapVisitor.encoder + encoder.append(text: "}") + } + + /// Helper function that throws an error if the field number could not be + /// resolved. + private mutating func startField(for number: Int) throws { + let name: _NameMap.Name? + + if options.preserveProtoFieldNames { + name = nameMap.names(for: number)?.proto + } else { + name = nameMap.names(for: number)?.json + } + + if let name = name { + encoder.startField(name: name) + } else if let name = extensions?[number]?.protobufExtension.fieldName { + encoder.startExtensionField(name: name) + } else { + throw JSONEncodingError.missingFieldNames + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift new file mode 100644 index 00000000..e15ac035 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift @@ -0,0 +1,174 @@ +// Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift - JSON map encoding visitor +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Visitor that writes out the key/value pairs for a JSON map. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Visitor that serializes a message into JSON map format. +/// +/// This expects to alternately visit the keys and values for a JSON +/// map. It only accepts singular values. Keys should be identified +/// as `fieldNumber:1`, values should be identified as `fieldNumber:2` +/// +internal struct JSONMapEncodingVisitor: SelectiveVisitor { + private var separator: StaticString? + internal var encoder: JSONEncoder + private let options: JSONEncodingOptions + + init(encoder: JSONEncoder, options: JSONEncodingOptions) { + self.encoder = encoder + self.options = options + } + + private mutating func startKey() { + if let s = separator { + encoder.append(staticText: s) + } else { + separator = "," + } + } + + private mutating func startValue() { + encoder.append(staticText: ":") + } + + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + // Doubles/Floats can never be map keys, only values + assert(fieldNumber == 2) + startValue() + encoder.putFloatValue(value: value) + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + // Doubles/Floats can never be map keys, only values + assert(fieldNumber == 2) + startValue() + encoder.putDoubleValue(value: value) + } + + mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + encoder.putQuotedInt32(value: value) + } else { + startValue() + encoder.putInt32(value: value) + } + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + } else { + startValue() + } + // Int64 fields are always quoted anyway + encoder.putInt64(value: value) + } + + mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + encoder.putQuotedUInt32(value: value) + } else { + startValue() + encoder.putUInt32(value: value) + } + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + } else { + startValue() + } + encoder.putUInt64(value: value) + } + + mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + encoder.putQuotedBoolValue(value: value) + } else { + startValue() + encoder.putBoolValue(value: value) + } + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + if fieldNumber == 1 { + startKey() + } else { + startValue() + } + encoder.putStringValue(value: value) + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + // Bytes can only be map values, never keys + assert(fieldNumber == 2) + startValue() + encoder.putBytesValue(value: value) + } + + mutating func visitSingularEnumField(value: E, fieldNumber: Int) throws { + // Enums can only be map values, never keys + assert(fieldNumber == 2) + startValue() + if !options.alwaysPrintEnumsAsInts, let n = value.name { + encoder.putStringValue(value: String(describing: n)) + } else { + encoder.putEnumInt(value: value.rawValue) + } + } + + mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws { + // Messages can only be map values, never keys + assert(fieldNumber == 2) + startValue() + let json = try value.jsonString(options: options) + encoder.append(text: json) + } + + // SelectiveVisitor will block: + // - single Groups + // - everything repeated + // - everything packed + // - all maps + // - unknown fields + // - extensions +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONScanner.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONScanner.swift new file mode 100644 index 00000000..8960a409 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/JSONScanner.swift @@ -0,0 +1,1537 @@ +// Sources/SwiftProtobuf/JSONScanner.swift - JSON format decoding +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// JSON format decoding engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let asciiBell = UInt8(7) +private let asciiBackspace = UInt8(8) +private let asciiTab = UInt8(9) +private let asciiNewLine = UInt8(10) +private let asciiVerticalTab = UInt8(11) +private let asciiFormFeed = UInt8(12) +private let asciiCarriageReturn = UInt8(13) +private let asciiZero = UInt8(ascii: "0") +private let asciiOne = UInt8(ascii: "1") +private let asciiSeven = UInt8(ascii: "7") +private let asciiNine = UInt8(ascii: "9") +private let asciiColon = UInt8(ascii: ":") +private let asciiPeriod = UInt8(ascii: ".") +private let asciiPlus = UInt8(ascii: "+") +private let asciiComma = UInt8(ascii: ",") +private let asciiSemicolon = UInt8(ascii: ";") +private let asciiDoubleQuote = UInt8(ascii: "\"") +private let asciiSingleQuote = UInt8(ascii: "\'") +private let asciiBackslash = UInt8(ascii: "\\") +private let asciiForwardSlash = UInt8(ascii: "/") +private let asciiHash = UInt8(ascii: "#") +private let asciiEqualSign = UInt8(ascii: "=") +private let asciiUnderscore = UInt8(ascii: "_") +private let asciiQuestionMark = UInt8(ascii: "?") +private let asciiSpace = UInt8(ascii: " ") +private let asciiOpenSquareBracket = UInt8(ascii: "[") +private let asciiCloseSquareBracket = UInt8(ascii: "]") +private let asciiOpenCurlyBracket = UInt8(ascii: "{") +private let asciiCloseCurlyBracket = UInt8(ascii: "}") +private let asciiOpenAngleBracket = UInt8(ascii: "<") +private let asciiCloseAngleBracket = UInt8(ascii: ">") +private let asciiMinus = UInt8(ascii: "-") +private let asciiLowerA = UInt8(ascii: "a") +private let asciiUpperA = UInt8(ascii: "A") +private let asciiLowerB = UInt8(ascii: "b") +private let asciiLowerE = UInt8(ascii: "e") +private let asciiUpperE = UInt8(ascii: "E") +private let asciiLowerF = UInt8(ascii: "f") +private let asciiUpperI = UInt8(ascii: "I") +private let asciiLowerL = UInt8(ascii: "l") +private let asciiLowerN = UInt8(ascii: "n") +private let asciiUpperN = UInt8(ascii: "N") +private let asciiLowerR = UInt8(ascii: "r") +private let asciiLowerS = UInt8(ascii: "s") +private let asciiLowerT = UInt8(ascii: "t") +private let asciiLowerU = UInt8(ascii: "u") +private let asciiLowerZ = UInt8(ascii: "z") +private let asciiUpperZ = UInt8(ascii: "Z") + +private func fromHexDigit(_ c: UnicodeScalar) -> UInt32? { + let n = c.value + if n >= 48 && n <= 57 { + return UInt32(n - 48) + } + switch n { + case 65, 97: return 10 + case 66, 98: return 11 + case 67, 99: return 12 + case 68, 100: return 13 + case 69, 101: return 14 + case 70, 102: return 15 + default: + return nil + } +} + +// Decode both the RFC 4648 section 4 Base 64 encoding and the RFC +// 4648 section 5 Base 64 variant. The section 5 variant is also +// known as "base64url" or the "URL-safe alphabet". +// Note that both "-" and "+" decode to 62 and "/" and "_" both +// decode as 63. +let base64Values: [Int] = [ +/* 0x00 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0x10 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0x20 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, +/* 0x30 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, +/* 0x40 */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +/* 0x50 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, +/* 0x60 */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, +/* 0x70 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, +/* 0x80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0x90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xa0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xb0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xc0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xd0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xe0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +/* 0xf0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +] + +/// Returns a `Data` value containing bytes equivalent to the given +/// Base64-encoded string, or nil if the conversion fails. +/// +/// Notes on Google's implementation (Base64Unescape() in strutil.cc): +/// * Google's C++ implementation accepts arbitrary whitespace +/// mixed in with the base-64 characters +/// * Google's C++ implementation ignores missing '=' characters +/// but if present, there must be the exact correct number of them. +/// * The conformance test requires us to accept both standard RFC4648 +/// Base 64 encoding and the "URL and Filename Safe Alphabet" variant. +/// +private func parseBytes( + source: UnsafeRawBufferPointer, + index: inout UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index +) throws -> Data { + let c = source[index] + if c != asciiDoubleQuote { + throw JSONDecodingError.malformedString + } + source.formIndex(after: &index) + + // Count the base-64 digits + // Ignore most unrecognized characters in this first pass, + // stop at the closing double quote. + let digitsStart = index + var rawChars = 0 + var sawSection4Characters = false + var sawSection5Characters = false + while index != end { + var digit = source[index] + if digit == asciiDoubleQuote { + break + } + + if digit == asciiBackslash { + source.formIndex(after: &index) + if index == end { + throw JSONDecodingError.malformedString + } + let escaped = source[index] + switch escaped { + case asciiLowerU: + // TODO: Parse hex escapes such as \u0041. Note that + // such escapes are going to be extremely rare, so + // there's little point in optimizing for them. + throw JSONDecodingError.malformedString + case asciiForwardSlash: + digit = escaped + default: + // Reject \b \f \n \r \t \" or \\ and all illegal escapes + throw JSONDecodingError.malformedString + } + } + + if digit == asciiPlus || digit == asciiForwardSlash { + sawSection4Characters = true + } else if digit == asciiMinus || digit == asciiUnderscore { + sawSection5Characters = true + } + let k = base64Values[Int(digit)] + if k >= 0 { + rawChars += 1 + } + source.formIndex(after: &index) + } + + // We reached the end without seeing the close quote + if index == end { + throw JSONDecodingError.malformedString + } + // Reject mixed encodings. + if sawSection4Characters && sawSection5Characters { + throw JSONDecodingError.malformedString + } + + // Allocate a Data object of exactly the right size + var value = Data(count: rawChars * 3 / 4) + + // Scan the digits again and populate the Data object. + // In this pass, we check for (and fail) if there are + // unexpected characters. But we don't check for end-of-input, + // because the loop above already verified that there was + // a closing double quote. + index = digitsStart + try value.withUnsafeMutableBytes { + (body: UnsafeMutableRawBufferPointer) in + if var p = body.baseAddress, body.count > 0 { + var n = 0 + var chars = 0 // # chars in current group + var padding = 0 // # padding '=' chars + digits: while true { + let digit = source[index] + var k = base64Values[Int(digit)] + if k < 0 { + switch digit { + case asciiDoubleQuote: + break digits + case asciiBackslash: + source.formIndex(after: &index) + let escaped = source[index] + switch escaped { + case asciiForwardSlash: + k = base64Values[Int(escaped)] + default: + // Note: Invalid backslash escapes were caught + // above; we should never get here. + throw JSONDecodingError.malformedString + } + case asciiSpace: + source.formIndex(after: &index) + continue digits + case asciiEqualSign: // Count padding + while true { + switch source[index] { + case asciiDoubleQuote: + break digits + case asciiSpace: + break + case 61: + padding += 1 + default: // Only '=' and whitespace permitted + throw JSONDecodingError.malformedString + } + source.formIndex(after: &index) + } + default: + throw JSONDecodingError.malformedString + } + } + n <<= 6 + n |= k + chars += 1 + if chars == 4 { + p[0] = UInt8(truncatingIfNeeded: n >> 16) + p[1] = UInt8(truncatingIfNeeded: n >> 8) + p[2] = UInt8(truncatingIfNeeded: n) + p += 3 + chars = 0 + n = 0 + } + source.formIndex(after: &index) + } + switch chars { + case 3: + p[0] = UInt8(truncatingIfNeeded: n >> 10) + p[1] = UInt8(truncatingIfNeeded: n >> 2) + if padding == 1 || padding == 0 { + return + } + case 2: + p[0] = UInt8(truncatingIfNeeded: n >> 4) + if padding == 2 || padding == 0 { + return + } + case 0: + if padding == 0 { + return + } + default: + break + } + throw JSONDecodingError.malformedString + } + } + source.formIndex(after: &index) + return value +} + +// JSON encoding allows a variety of \-escapes, including +// escaping UTF-16 code points (which may be surrogate pairs). +private func decodeString(_ s: String) -> String? { + var out = String.UnicodeScalarView() + var chars = s.unicodeScalars.makeIterator() + while let c = chars.next() { + switch c.value { + case UInt32(asciiBackslash): // backslash + if let escaped = chars.next() { + switch escaped.value { + case UInt32(asciiLowerU): // "\u" + // Exactly 4 hex digits: + if let digit1 = chars.next(), + let d1 = fromHexDigit(digit1), + let digit2 = chars.next(), + let d2 = fromHexDigit(digit2), + let digit3 = chars.next(), + let d3 = fromHexDigit(digit3), + let digit4 = chars.next(), + let d4 = fromHexDigit(digit4) { + let codePoint = ((d1 * 16 + d2) * 16 + d3) * 16 + d4 + if let scalar = UnicodeScalar(codePoint) { + out.append(scalar) + } else if codePoint < 0xD800 || codePoint >= 0xE000 { + // Not a valid Unicode scalar. + return nil + } else if codePoint >= 0xDC00 { + // Low surrogate without a preceding high surrogate. + return nil + } else { + // We have a high surrogate (in the range 0xD800..<0xDC00), so + // verify that it is followed by a low surrogate. + guard chars.next() == "\\", chars.next() == "u" else { + // High surrogate was not followed by a Unicode escape sequence. + return nil + } + if let digit1 = chars.next(), + let d1 = fromHexDigit(digit1), + let digit2 = chars.next(), + let d2 = fromHexDigit(digit2), + let digit3 = chars.next(), + let d3 = fromHexDigit(digit3), + let digit4 = chars.next(), + let d4 = fromHexDigit(digit4) { + let follower = ((d1 * 16 + d2) * 16 + d3) * 16 + d4 + guard 0xDC00 <= follower && follower < 0xE000 else { + // High surrogate was not followed by a low surrogate. + return nil + } + let high = codePoint - 0xD800 + let low = follower - 0xDC00 + let composed = 0x10000 | high << 10 | low + guard let composedScalar = UnicodeScalar(composed) else { + // Composed value is not a valid Unicode scalar. + return nil + } + out.append(composedScalar) + } else { + // Malformed \u escape for low surrogate + return nil + } + } + } else { + // Malformed \u escape + return nil + } + case UInt32(asciiLowerB): // \b + out.append("\u{08}") + case UInt32(asciiLowerF): // \f + out.append("\u{0c}") + case UInt32(asciiLowerN): // \n + out.append("\u{0a}") + case UInt32(asciiLowerR): // \r + out.append("\u{0d}") + case UInt32(asciiLowerT): // \t + out.append("\u{09}") + case UInt32(asciiDoubleQuote), UInt32(asciiBackslash), + UInt32(asciiForwardSlash): // " \ / + out.append(escaped) + default: + return nil // Unrecognized escape + } + } else { + return nil // Input ends with backslash + } + default: + out.append(c) + } + } + return String(out) +} + +/// +/// The basic scanner support is entirely private +/// +/// For performance, it works directly against UTF-8 bytes in memory. +/// +internal struct JSONScanner { + private let source: UnsafeRawBufferPointer + private var index: UnsafeRawBufferPointer.Index + private var numberParser = DoubleParser() + internal let options: JSONDecodingOptions + internal let extensions: ExtensionMap + internal var recursionBudget: Int + + /// True if the scanner has read all of the data from the source, with the + /// exception of any trailing whitespace (which is consumed by reading this + /// property). + internal var complete: Bool { + mutating get { + skipWhitespace() + return !hasMoreContent + } + } + + /// True if the scanner has not yet reached the end of the source. + private var hasMoreContent: Bool { + return index != source.endIndex + } + + /// The byte (UTF-8 code unit) at the scanner's current position. + private var currentByte: UInt8 { + return source[index] + } + + internal init( + source: UnsafeRawBufferPointer, + options: JSONDecodingOptions, + extensions: ExtensionMap? + ) { + self.source = source + self.index = source.startIndex + self.recursionBudget = options.messageDepthLimit + self.options = options + self.extensions = extensions ?? SimpleExtensionMap() + } + + internal mutating func incrementRecursionDepth() throws { + recursionBudget -= 1 + if recursionBudget < 0 { + throw JSONDecodingError.messageDepthLimit + } + } + + internal mutating func decrementRecursionDepth() { + recursionBudget += 1 + // This should never happen, if it does, something is probably corrupting memory, and + // simply throwing doesn't make much sense. + if recursionBudget > options.messageDepthLimit { + fatalError("Somehow JSONDecoding unwound more objects than it started") + } + } + + /// Advances the scanner to the next position in the source. + private mutating func advance() { + source.formIndex(after: &index) + } + + /// Skip whitespace + private mutating func skipWhitespace() { + while hasMoreContent { + let u = currentByte + switch u { + case asciiSpace, asciiTab, asciiNewLine, asciiCarriageReturn: + advance() + default: + return + } + } + } + + /// Returns (but does not consume) the next non-whitespace + /// character. This is used by google.protobuf.Value, for + /// example, for custom JSON parsing. + internal mutating func peekOneCharacter() throws -> Character { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + return Character(UnicodeScalar(UInt32(currentByte))!) + } + + // Parse the leading UInt64 from the provided utf8 bytes. + // + // This is called in three different situations: + // + // * Unquoted number. + // + // * Simple quoted number. If a number is quoted but has no + // backslashes, the caller can use this directly on the UTF8 by + // just verifying the quote marks. This code returns `nil` if it + // sees a backslash, in which case the caller will need to handle ... + // + // * Complex quoted number. In this case, the caller must parse the + // quoted value as a string, then convert the string to utf8 and + // use this to parse the result. This is slow but fortunately + // rare. + // + // In the common case where the number is written in integer form, + // this code does a simple straight conversion. If the number is in + // floating-point format, this uses a slower and less accurate + // approach: it identifies a substring comprising a float, and then + // uses Double() and UInt64() to convert that string to an unsigned + // integer. In particular, it cannot preserve full 64-bit integer + // values when they are written in floating-point format. + // + // If it encounters a "\" backslash character, it returns a nil. This + // is used by callers that are parsing quoted numbers. See nextSInt() + // and nextUInt() below. + private func parseBareUInt64( + source: UnsafeRawBufferPointer, + index: inout UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index + ) throws -> UInt64? { + if index == end { + throw JSONDecodingError.truncated + } + let start = index + let c = source[index] + switch c { + case asciiZero: // 0 + source.formIndex(after: &index) + if index != end { + let after = source[index] + switch after { + case asciiZero...asciiNine: // 0...9 + // leading '0' forbidden unless it is the only digit + throw JSONDecodingError.leadingZero + case asciiPeriod, asciiLowerE, asciiUpperE: // . e + // Slow path: JSON numbers can be written in floating-point notation + index = start + if let d = try parseBareDouble(source: source, + index: &index, + end: end) { + if let u = UInt64(exactly: d) { + return u + } + } + throw JSONDecodingError.malformedNumber + case asciiBackslash: + return nil + default: + return 0 + } + } + return 0 + case asciiOne...asciiNine: // 1...9 + var n = 0 as UInt64 + while index != end { + let digit = source[index] + switch digit { + case asciiZero...asciiNine: // 0...9 + let val = UInt64(digit - asciiZero) + if n > UInt64.max / 10 || n * 10 > UInt64.max - val { + throw JSONDecodingError.numberRange + } + source.formIndex(after: &index) + n = n * 10 + val + case asciiPeriod, asciiLowerE, asciiUpperE: // . e + // Slow path: JSON allows floating-point notation for integers + index = start + if let d = try parseBareDouble(source: source, + index: &index, + end: end) { + if let u = UInt64(exactly: d) { + return u + } + } + throw JSONDecodingError.malformedNumber + case asciiBackslash: + return nil + default: + return n + } + } + return n + case asciiBackslash: + return nil + default: + throw JSONDecodingError.malformedNumber + } + } + + // Parse the leading Int64 from the provided utf8. + // + // This uses parseBareUInt64() to do the heavy lifting; + // we just check for a leading minus and negate the result + // as necessary. + // + // As with parseBareUInt64(), if it encounters a "\" backslash + // character, it returns a nil. This allows callers to use this to + // do a "fast-path" decode of simple quoted numbers by parsing the + // UTF8 directly, only falling back to a full String decode when + // absolutely necessary. + private func parseBareSInt64( + source: UnsafeRawBufferPointer, + index: inout UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index + ) throws -> Int64? { + if index == end { + throw JSONDecodingError.truncated + } + let c = source[index] + if c == asciiMinus { // - + source.formIndex(after: &index) + if index == end { + throw JSONDecodingError.truncated + } + // character after '-' must be digit + let digit = source[index] + if digit < asciiZero || digit > asciiNine { + throw JSONDecodingError.malformedNumber + } + if let n = try parseBareUInt64(source: source, index: &index, end: end) { + let limit: UInt64 = 0x8000000000000000 // -Int64.min + if n >= limit { + if n > limit { + // Too large negative number + throw JSONDecodingError.numberRange + } else { + return Int64.min // Special case for Int64.min + } + } + return -Int64(bitPattern: n) + } else { + return nil + } + } else if let n = try parseBareUInt64(source: source, index: &index, end: end) { + if n > UInt64(bitPattern: Int64.max) { + throw JSONDecodingError.numberRange + } + return Int64(bitPattern: n) + } else { + return nil + } + } + + // Identify a floating-point token in the upcoming UTF8 bytes. + // + // This implements the full grammar defined by the JSON RFC 7159. + // Note that Swift's string-to-number conversions are much more + // lenient, so this is necessary if we want to accurately reject + // malformed JSON numbers. + // + // This is used by nextDouble() and nextFloat() to parse double and + // floating-point values, including values that happen to be in quotes. + // It's also used by the slow path in parseBareSInt64() and parseBareUInt64() + // above to handle integer values that are written in float-point notation. + private func parseBareDouble( + source: UnsafeRawBufferPointer, + index: inout UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index + ) throws -> Double? { + // RFC 7159 defines the grammar for JSON numbers as: + // number = [ minus ] int [ frac ] [ exp ] + if index == end { + throw JSONDecodingError.truncated + } + let start = index + var c = source[index] + if c == asciiBackslash { + return nil + } + + // Optional leading minus sign + if c == asciiMinus { // - + source.formIndex(after: &index) + if index == end { + index = start + throw JSONDecodingError.truncated + } + c = source[index] + if c == asciiBackslash { + return nil + } + } else if c == asciiUpperN { // Maybe NaN? + // Return nil, let the caller deal with it. + return nil + } + + if c == asciiUpperI { // Maybe Infinity, Inf, -Infinity, or -Inf ? + // Return nil, let the caller deal with it. + return nil + } + + // Integer part can be zero or a series of digits not starting with zero + // int = zero / (digit1-9 *DIGIT) + switch c { + case asciiZero: + // First digit can be zero only if not followed by a digit + source.formIndex(after: &index) + if index == end { + return 0.0 + } + c = source[index] + if c == asciiBackslash { + return nil + } + if c >= asciiZero && c <= asciiNine { + throw JSONDecodingError.leadingZero + } + case asciiOne...asciiNine: + while c >= asciiZero && c <= asciiNine { + source.formIndex(after: &index) + if index == end { + if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) { + return d + } else { + throw JSONDecodingError.invalidUTF8 + } + } + c = source[index] + if c == asciiBackslash { + return nil + } + } + default: + // Integer part cannot be empty + throw JSONDecodingError.malformedNumber + } + + // frac = decimal-point 1*DIGIT + if c == asciiPeriod { + source.formIndex(after: &index) + if index == end { + // decimal point must have a following digit + throw JSONDecodingError.truncated + } + c = source[index] + switch c { + case asciiZero...asciiNine: // 0...9 + while c >= asciiZero && c <= asciiNine { + source.formIndex(after: &index) + if index == end { + if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) { + return d + } else { + throw JSONDecodingError.invalidUTF8 + } + } + c = source[index] + if c == asciiBackslash { + return nil + } + } + case asciiBackslash: + return nil + default: + // decimal point must be followed by at least one digit + throw JSONDecodingError.malformedNumber + } + } + + // exp = e [ minus / plus ] 1*DIGIT + if c == asciiLowerE || c == asciiUpperE { + source.formIndex(after: &index) + if index == end { + // "e" must be followed by +,-, or digit + throw JSONDecodingError.truncated + } + c = source[index] + if c == asciiBackslash { + return nil + } + if c == asciiPlus || c == asciiMinus { // + - + source.formIndex(after: &index) + if index == end { + // must be at least one digit in exponent + throw JSONDecodingError.truncated + } + c = source[index] + if c == asciiBackslash { + return nil + } + } + switch c { + case asciiZero...asciiNine: + while c >= asciiZero && c <= asciiNine { + source.formIndex(after: &index) + if index == end { + if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) { + return d + } else { + throw JSONDecodingError.invalidUTF8 + } + } + c = source[index] + if c == asciiBackslash { + return nil + } + } + default: + // must be at least one digit in exponent + throw JSONDecodingError.malformedNumber + } + } + if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) { + return d + } else { + throw JSONDecodingError.invalidUTF8 + } + } + + /// Returns a fully-parsed string with all backslash escapes + /// correctly processed, or nil if next token is not a string. + /// + /// Assumes the leading quote has been verified (but not consumed) + private mutating func parseOptionalQuotedString() -> String? { + // Caller has already asserted that currentByte == quote here + var sawBackslash = false + advance() + let start = index + while hasMoreContent { + switch currentByte { + case asciiDoubleQuote: // " + let s = utf8ToString(bytes: source, start: start, end: index) + advance() + if let t = s { + if sawBackslash { + return decodeString(t) + } else { + return t + } + } else { + return nil // Invalid UTF8 + } + case asciiBackslash: // \ + advance() + guard hasMoreContent else { + return nil // Unterminated escape + } + sawBackslash = true + default: + break + } + advance() + } + return nil // Unterminated quoted string + } + + /// Parse an unsigned integer, whether or not its quoted. + /// This also handles cases such as quoted numbers that have + /// backslash escapes in them. + /// + /// This supports the full range of UInt64 (whether quoted or not) + /// unless the number is written in floating-point format. In that + /// case, we decode it with only Double precision. + internal mutating func nextUInt() throws -> UInt64 { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + if c == asciiDoubleQuote { + let start = index + advance() + if let u = try parseBareUInt64(source: source, + index: &index, + end: source.endIndex) { + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.malformedNumber + } + advance() + return u + } else { + // Couldn't parse because it had a "\" in the string, + // so parse out the quoted string and then reparse + // the result to get a UInt + index = start + let s = try nextQuotedString() + let raw = s.data(using: String.Encoding.utf8)! + let n = try raw.withUnsafeBytes { + (body: UnsafeRawBufferPointer) -> UInt64? in + if body.count > 0 { + var index = body.startIndex + let end = body.endIndex + if let u = try parseBareUInt64(source: body, + index: &index, + end: end) { + if index == end { + return u + } + } + } + return nil + } + if let n = n { + return n + } + } + } else if let u = try parseBareUInt64(source: source, + index: &index, + end: source.endIndex) { + return u + } + throw JSONDecodingError.malformedNumber + } + + /// Parse a signed integer, quoted or not, including handling + /// backslash escapes for quoted values. + /// + /// This supports the full range of Int64 (whether quoted or not) + /// unless the number is written in floating-point format. In that + /// case, we decode it with only Double precision. + internal mutating func nextSInt() throws -> Int64 { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + if c == asciiDoubleQuote { + let start = index + advance() + if let s = try parseBareSInt64(source: source, + index: &index, + end: source.endIndex) { + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.malformedNumber + } + advance() + return s + } else { + // Couldn't parse because it had a "\" in the string, + // so parse out the quoted string and then reparse + // the result as an SInt + index = start + let s = try nextQuotedString() + let raw = s.data(using: String.Encoding.utf8)! + let n = try raw.withUnsafeBytes { + (body: UnsafeRawBufferPointer) -> Int64? in + if body.count > 0 { + var index = body.startIndex + let end = body.endIndex + if let s = try parseBareSInt64(source: body, + index: &index, + end: end) { + if index == end { + return s + } + } + } + return nil + } + if let n = n { + return n + } + } + } else if let s = try parseBareSInt64(source: source, + index: &index, + end: source.endIndex) { + return s + } + throw JSONDecodingError.malformedNumber + } + + /// Parse the next Float value, regardless of whether it + /// is quoted, including handling backslash escapes for + /// quoted strings. + internal mutating func nextFloat() throws -> Float { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + if c == asciiDoubleQuote { // " + let start = index + advance() + if let d = try parseBareDouble(source: source, + index: &index, + end: source.endIndex) { + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.malformedNumber + } + advance() + return Float(d) + } else { + // Slow Path: parseBareDouble returned nil: It might be + // a valid float, but had something that + // parseBareDouble cannot directly handle. So we reset, + // try a full string parse, then examine the result: + index = start + let s = try nextQuotedString() + switch s { + case "NaN": return Float.nan + case "Inf": return Float.infinity + case "-Inf": return -Float.infinity + case "Infinity": return Float.infinity + case "-Infinity": return -Float.infinity + default: + let raw = s.data(using: String.Encoding.utf8)! + let n = try raw.withUnsafeBytes { + (body: UnsafeRawBufferPointer) -> Float? in + if body.count > 0 { + var index = body.startIndex + let end = body.endIndex + if let d = try parseBareDouble(source: body, + index: &index, + end: end) { + let f = Float(d) + if index == end && f.isFinite { + return f + } + } + } + return nil + } + if let n = n { + return n + } + } + } + } else { + if let d = try parseBareDouble(source: source, + index: &index, + end: source.endIndex) { + let f = Float(d) + if f.isFinite { + return f + } + } + } + throw JSONDecodingError.malformedNumber + } + + /// Parse the next Double value, regardless of whether it + /// is quoted, including handling backslash escapes for + /// quoted strings. + internal mutating func nextDouble() throws -> Double { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + if c == asciiDoubleQuote { // " + let start = index + advance() + if let d = try parseBareDouble(source: source, + index: &index, + end: source.endIndex) { + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.malformedNumber + } + advance() + return d + } else { + // Slow Path: parseBareDouble returned nil: It might be + // a valid float, but had something that + // parseBareDouble cannot directly handle. So we reset, + // try a full string parse, then examine the result: + index = start + let s = try nextQuotedString() + switch s { + case "NaN": return Double.nan + case "Inf": return Double.infinity + case "-Inf": return -Double.infinity + case "Infinity": return Double.infinity + case "-Infinity": return -Double.infinity + default: + let raw = s.data(using: String.Encoding.utf8)! + let n = try raw.withUnsafeBytes { + (body: UnsafeRawBufferPointer) -> Double? in + if body.count > 0 { + var index = body.startIndex + let end = body.endIndex + if let d = try parseBareDouble(source: body, + index: &index, + end: end) { + if index == end { + return d + } + } + } + return nil + } + if let n = n { + return n + } + } + } + } else { + if let d = try parseBareDouble(source: source, + index: &index, + end: source.endIndex) { + return d + } + } + throw JSONDecodingError.malformedNumber + } + + /// Return the contents of the following quoted string, + /// or throw an error if the next token is not a string. + internal mutating func nextQuotedString() throws -> String { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + if c != asciiDoubleQuote { + throw JSONDecodingError.malformedString + } + if let s = parseOptionalQuotedString() { + return s + } else { + throw JSONDecodingError.malformedString + } + } + + /// Return the contents of the following quoted string, + /// or nil if the next token is not a string. + /// This will only throw an error if the next token starts + /// out as a string but is malformed in some way. + internal mutating func nextOptionalQuotedString() throws -> String? { + skipWhitespace() + guard hasMoreContent else { + return nil + } + let c = currentByte + if c != asciiDoubleQuote { + return nil + } + return try nextQuotedString() + } + + /// Return a Data with the decoded contents of the + /// following base-64 string. + /// + /// Notes on Google's implementation: + /// * Google's C++ implementation accepts arbitrary whitespace + /// mixed in with the base-64 characters + /// * Google's C++ implementation ignores missing '=' characters + /// but if present, there must be the exact correct number of them. + /// * Google's C++ implementation accepts both "regular" and + /// "web-safe" base-64 variants (it seems to prefer the + /// web-safe version as defined in RFC 4648 + internal mutating func nextBytesValue() throws -> Data { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + return try parseBytes(source: source, index: &index, end: source.endIndex) + } + + /// Private function to help parse keywords. + private mutating func skipOptionalKeyword(bytes: [UInt8]) -> Bool { + let start = index + for b in bytes { + guard hasMoreContent else { + index = start + return false + } + let c = currentByte + if c != b { + index = start + return false + } + advance() + } + if hasMoreContent { + let c = currentByte + if (c >= asciiUpperA && c <= asciiUpperZ) || + (c >= asciiLowerA && c <= asciiLowerZ) { + index = start + return false + } + } + return true + } + + /// If the next token is the identifier "null", consume it and return true. + internal mutating func skipOptionalNull() -> Bool { + skipWhitespace() + if hasMoreContent && currentByte == asciiLowerN { + return skipOptionalKeyword(bytes: [ + asciiLowerN, asciiLowerU, asciiLowerL, asciiLowerL + ]) + } + return false + } + + /// Return the following Bool "true" or "false", including + /// full processing of quoted boolean values. (Used in map + /// keys, for instance.) + internal mutating func nextBool() throws -> Bool { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let c = currentByte + switch c { + case asciiLowerF: // f + if skipOptionalKeyword(bytes: [ + asciiLowerF, asciiLowerA, asciiLowerL, asciiLowerS, asciiLowerE + ]) { + return false + } + case asciiLowerT: // t + if skipOptionalKeyword(bytes: [ + asciiLowerT, asciiLowerR, asciiLowerU, asciiLowerE + ]) { + return true + } + default: + break + } + throw JSONDecodingError.malformedBool + } + + /// Return the following Bool "true" or "false", including + /// full processing of quoted boolean values. (Used in map + /// keys, for instance.) + internal mutating func nextQuotedBool() throws -> Bool { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.unquotedMapKey + } + if let s = parseOptionalQuotedString() { + switch s { + case "false": return false + case "true": return true + default: break + } + } + throw JSONDecodingError.malformedBool + } + + /// Returns pointer/count spanning the UTF8 bytes of the next regular + /// key or nil if the key contains a backslash (and therefore requires + /// the full string-parsing logic to properly parse). + private mutating func nextOptionalKey() throws -> UnsafeRawBufferPointer? { + skipWhitespace() + let stringStart = index + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + return nil + } + advance() + let nameStart = index + while hasMoreContent && currentByte != asciiDoubleQuote { + if currentByte == asciiBackslash { + index = stringStart // Reset to open quote + return nil + } + advance() + } + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let buff = UnsafeRawBufferPointer( + start: source.baseAddress! + nameStart, + count: index - nameStart) + advance() + return buff + } + + /// Parse a field name, look it up in the provided field name map, + /// and return the corresponding field number. + /// + /// Throws if field name cannot be parsed. + /// If it encounters an unknown field name, it throws + /// unless `options.ignoreUnknownFields` is set, in which case + /// it silently skips it. + internal mutating func nextFieldNumber( + names: _NameMap, + messageType: Message.Type + ) throws -> Int? { + while true { + var fieldName: String + if let key = try nextOptionalKey() { + // Fast path: We parsed it as UTF8 bytes... + try skipRequiredCharacter(asciiColon) // : + if let fieldNumber = names.number(forJSONName: key) { + return fieldNumber + } + if let s = utf8ToString(bytes: key.baseAddress!, count: key.count) { + fieldName = s + } else { + throw JSONDecodingError.invalidUTF8 + } + } else { + // Slow path: We parsed a String; lookups from String are slower. + fieldName = try nextQuotedString() + try skipRequiredCharacter(asciiColon) // : + if let fieldNumber = names.number(forJSONName: fieldName) { + return fieldNumber + } + } + if let first = fieldName.utf8.first, first == UInt8(ascii: "["), + let last = fieldName.utf8.last, last == UInt8(ascii: "]") + { + fieldName.removeFirst() + fieldName.removeLast() + if let fieldNumber = extensions.fieldNumberForProto(messageType: messageType, protoFieldName: fieldName) { + return fieldNumber + } + } + if !options.ignoreUnknownFields { + throw JSONDecodingError.unknownField(fieldName) + } + // Unknown field, skip it and try to parse the next field name + try skipValue() + if skipOptionalObjectEnd() { + return nil + } + try skipRequiredComma() + } + } + + /// Parse the next token as a string or numeric enum value. Throws + /// unrecognizedEnumValue if the string/number can't initialize the + /// enum. Will throw other errors if the JSON is malformed. + internal mutating func nextEnumValue() throws -> E { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte == asciiDoubleQuote { + if let name = try nextOptionalKey() { + if let e = E(rawUTF8: name) { + return e + } else { + throw JSONDecodingError.unrecognizedEnumValue + } + } + let name = try nextQuotedString() + if let e = E(name: name) { + return e + } else { + throw JSONDecodingError.unrecognizedEnumValue + } + } else { + let n = try nextSInt() + if let i = Int(exactly: n) { + if let e = E(rawValue: i) { + return e + } else { + throw JSONDecodingError.unrecognizedEnumValue + } + } else { + throw JSONDecodingError.numberRange + } + } + } + + /// Helper for skipping a single-character token. + private mutating func skipRequiredCharacter(_ required: UInt8) throws { + skipWhitespace() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + let next = currentByte + if next == required { + advance() + return + } + throw JSONDecodingError.failure + } + + /// Skip "{", throw if that's not the next character + internal mutating func skipRequiredObjectStart() throws { + try skipRequiredCharacter(asciiOpenCurlyBracket) // { + try incrementRecursionDepth() + } + + /// Skip ",", throw if that's not the next character + internal mutating func skipRequiredComma() throws { + try skipRequiredCharacter(asciiComma) + } + + /// Skip ":", throw if that's not the next character + internal mutating func skipRequiredColon() throws { + try skipRequiredCharacter(asciiColon) + } + + /// Skip "[", throw if that's not the next character + internal mutating func skipRequiredArrayStart() throws { + try skipRequiredCharacter(asciiOpenSquareBracket) // [ + } + + /// Helper for skipping optional single-character tokens + private mutating func skipOptionalCharacter(_ c: UInt8) -> Bool { + skipWhitespace() + if hasMoreContent && currentByte == c { + advance() + return true + } + return false + } + + /// If the next non-whitespace character is "[", skip it + /// and return true. Otherwise, return false. + internal mutating func skipOptionalArrayStart() -> Bool { + return skipOptionalCharacter(asciiOpenSquareBracket) + } + + /// If the next non-whitespace character is "]", skip it + /// and return true. Otherwise, return false. + internal mutating func skipOptionalArrayEnd() -> Bool { + return skipOptionalCharacter(asciiCloseSquareBracket) // ] + } + + /// If the next non-whitespace character is "}", skip it + /// and return true. Otherwise, return false. + internal mutating func skipOptionalObjectEnd() -> Bool { + let result = skipOptionalCharacter(asciiCloseCurlyBracket) // } + if result { + decrementRecursionDepth() + } + return result + } + + /// Return the next complete JSON structure as a string. + /// For example, this might return "true", or "123.456", + /// or "{\"foo\": 7, \"bar\": [8, 9]}" + /// + /// Used by Any to get the upcoming JSON value as a string. + /// Note: The value might be an object or array. + internal mutating func skip() throws -> String { + skipWhitespace() + let start = index + try skipValue() + if let s = utf8ToString(bytes: source, start: start, end: index) { + return s + } else { + throw JSONDecodingError.invalidUTF8 + } + } + + /// Advance index past the next value. This is used + /// by skip() and by unknown field handling. + /// Note: This handles objects {...} recursively but arrays [...] non-recursively + /// This avoids us requiring excessive stack space for deeply nested + /// arrays (which are not included in the recursion budget check). + private mutating func skipValue() throws { + skipWhitespace() + var totalArrayDepth = 0 + while true { + var arrayDepth = 0 + while skipOptionalArrayStart() { + arrayDepth += 1 + } + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + switch currentByte { + case asciiDoubleQuote: // " begins a string + try skipString() + case asciiOpenCurlyBracket: // { begins an object + try skipObject() + case asciiCloseSquareBracket: // ] ends an empty array + if arrayDepth == 0 { + throw JSONDecodingError.failure + } + // We also close out [[]] or [[[]]] here + while arrayDepth > 0 && skipOptionalArrayEnd() { + arrayDepth -= 1 + } + case asciiLowerN: // n must be null + if !skipOptionalKeyword(bytes: [ + asciiLowerN, asciiLowerU, asciiLowerL, asciiLowerL + ]) { + throw JSONDecodingError.truncated + } + case asciiLowerF: // f must be false + if !skipOptionalKeyword(bytes: [ + asciiLowerF, asciiLowerA, asciiLowerL, asciiLowerS, asciiLowerE + ]) { + throw JSONDecodingError.truncated + } + case asciiLowerT: // t must be true + if !skipOptionalKeyword(bytes: [ + asciiLowerT, asciiLowerR, asciiLowerU, asciiLowerE + ]) { + throw JSONDecodingError.truncated + } + default: // everything else is a number token + _ = try nextDouble() + } + totalArrayDepth += arrayDepth + while totalArrayDepth > 0 && skipOptionalArrayEnd() { + totalArrayDepth -= 1 + } + if totalArrayDepth > 0 { + try skipRequiredComma() + } else { + return + } + } + } + + /// Advance the index past the next complete {...} construct. + private mutating func skipObject() throws { + try skipRequiredObjectStart() + if skipOptionalObjectEnd() { + return + } + while true { + skipWhitespace() + try skipString() + try skipRequiredColon() + try skipValue() + if skipOptionalObjectEnd() { + return + } + try skipRequiredComma() + } + } + + /// Advance the index past the next complete quoted string. + /// + // Caveat: This does not fully validate; it will accept + // strings that have malformed \ escapes. + // + // It would be nice to do better, but I don't think it's critical, + // since there are many reasons that strings (and other tokens for + // that matter) may be skippable but not parseable. For example: + // Old clients that don't know new field types will skip fields + // they don't know; newer clients may reject the same input due to + // schema mismatches or other issues. + private mutating func skipString() throws { + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + if currentByte != asciiDoubleQuote { + throw JSONDecodingError.malformedString + } + advance() + while hasMoreContent { + let c = currentByte + switch c { + case asciiDoubleQuote: + advance() + return + case asciiBackslash: + advance() + guard hasMoreContent else { + throw JSONDecodingError.truncated + } + advance() + default: + advance() + } + } + throw JSONDecodingError.truncated + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MathUtils.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MathUtils.swift new file mode 100644 index 00000000..2e8550b9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MathUtils.swift @@ -0,0 +1,40 @@ +// Sources/SwiftProtobuf/MathUtils.swift - Generally useful mathematical functions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Generally useful mathematical and arithmetic functions. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Remainder in standard modular arithmetic (modulo). This coincides with (%) +/// when a > 0. +/// +/// - Parameters: +/// - a: The dividend. Can be positive, 0 or negative. +/// - b: The divisor. This must be positive, and is an error if 0 or negative. +/// - Returns: The unique value r such that 0 <= r < b and b * q + r = a for some q. +internal func mod(_ a: T, _ b: T) -> T { + assert(b > 0) + let r = a % b + return r >= 0 ? r : r + b +} + +/// Quotient in standard modular arithmetic (Euclidean division). This coincides +/// with (/) when a > 0. +/// +/// - Parameters: +/// - a: The dividend. Can be positive, 0 or negative. +/// - b: The divisor. This must be positive, and is an error if 0 or negative. +/// - Returns: The unique value q such that for some 0 <= r < b, b * q + r = a. +internal func div(_ a: T, _ b: T) -> T { + assert(b > 0) + return a >= 0 ? a / b : (a + 1) / b - 1 +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+AnyAdditions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+AnyAdditions.swift new file mode 100644 index 00000000..67d31782 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+AnyAdditions.swift @@ -0,0 +1,45 @@ +// Sources/SwiftProtobuf/Message+AnyAdditions.swift - Any-related Message extensions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extends the `Message` type with `Google_Protobuf_Any`-specific behavior. +/// +// ----------------------------------------------------------------------------- + +extension Message { + /// Initialize this message from the provided `google.protobuf.Any` + /// well-known type. + /// + /// This corresponds to the `unpack` method in the Google C++ API. + /// + /// If the Any object was decoded from Protobuf Binary or JSON + /// format, then the enclosed field data was stored and is not + /// fully decoded until you unpack the Any object into a message. + /// As such, this method will typically need to perform a full + /// deserialization of the enclosed data and can fail for any + /// reason that deserialization can fail. + /// + /// See `Google_Protobuf_Any.unpackTo()` for more discussion. + /// + /// - Parameter unpackingAny: the message to decode. + /// - Parameter extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - Parameter options: The BinaryDecodingOptions to use. + /// - Throws: an instance of `AnyUnpackError`, `JSONDecodingError`, or + /// `BinaryDecodingError` on failure. + public init( + unpackingAny: Google_Protobuf_Any, + extensions: ExtensionMap? = nil, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { + self.init() + try unpackingAny._storage.unpackTo(target: &self, extensions: extensions, options: options) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+BinaryAdditions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+BinaryAdditions.swift new file mode 100644 index 00000000..173cff94 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+BinaryAdditions.swift @@ -0,0 +1,204 @@ +// Sources/SwiftProtobuf/Message+BinaryAdditions.swift - Per-type binary coding +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extensions to `Message` to provide binary coding and decoding. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Binary encoding and decoding methods for messages. +extension Message { + /// Returns a `Data` value containing the Protocol Buffer binary format + /// serialization of the message. + /// + /// - Parameters: + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - Returns: A `Data` value containing the binary serialization of the + /// message. + /// - Throws: `BinaryEncodingError` if encoding fails. + public func serializedData(partial: Bool = false) throws -> Data { + if !partial && !isInitialized { + throw BinaryEncodingError.missingRequiredFields + } + let requiredSize = try serializedDataSize() + var data = Data(count: requiredSize) + try data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var visitor = BinaryEncodingVisitor(forWritingInto: baseAddress) + try traverse(visitor: &visitor) + // Currently not exposing this from the api because it really would be + // an internal error in the library and should never happen. + assert(requiredSize == visitor.encoder.distance(pointer: baseAddress)) + } + } + return data + } + + /// Returns the size in bytes required to encode the message in binary format. + /// This is used by `serializedData()` to precalculate the size of the buffer + /// so that encoding can proceed without bounds checks or reallocation. + internal func serializedDataSize() throws -> Int { + // Note: since this api is internal, it doesn't currently worry about + // needing a partial argument to handle proto2 syntax required fields. + // If this become public, it will need that added. + var visitor = BinaryEncodingSizeVisitor() + try traverse(visitor: &visitor) + return visitor.serializedSize + } + + /// Creates a new message by decoding the given `Data` value containing a + /// serialized message in Protocol Buffer binary format. + /// + /// - Parameters: + /// - serializedData: The binary-encoded message data to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Throws: `BinaryDecodingError` if decoding fails. + @inlinable + public init( + serializedData data: Data, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { + self.init() +#if swift(>=5.0) + try merge(contiguousBytes: data, extensions: extensions, partial: partial, options: options) +#else + try merge(serializedData: data, extensions: extensions, partial: partial, options: options) +#endif + } + +#if swift(>=5.0) + /// Creates a new message by decoding the given `ContiguousBytes` value + /// containing a serialized message in Protocol Buffer binary format. + /// + /// - Parameters: + /// - contiguousBytes: The binary-encoded message data to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Throws: `BinaryDecodingError` if decoding fails. + @inlinable + public init( + contiguousBytes bytes: Bytes, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { + self.init() + try merge(contiguousBytes: bytes, extensions: extensions, partial: partial, options: options) + } +#endif // #if swift(>=5.0) + + /// Updates the message by decoding the given `Data` value containing a + /// serialized message in Protocol Buffer binary format into the receiver. + /// + /// - Note: If this method throws an error, the message may still have been + /// partially mutated by the binary data that was decoded before the error + /// occurred. + /// + /// - Parameters: + /// - serializedData: The binary-encoded message data to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Throws: `BinaryDecodingError` if decoding fails. + @inlinable + public mutating func merge( + serializedData data: Data, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { +#if swift(>=5.0) + try merge(contiguousBytes: data, extensions: extensions, partial: partial, options: options) +#else + try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + try _merge(rawBuffer: body, extensions: extensions, partial: partial, options: options) + } +#endif // swift(>=5.0) + } + +#if swift(>=5.0) + /// Updates the message by decoding the given `ContiguousBytes` value + /// containing a serialized message in Protocol Buffer binary format into the + /// receiver. + /// + /// - Note: If this method throws an error, the message may still have been + /// partially mutated by the binary data that was decoded before the error + /// occurred. + /// + /// - Parameters: + /// - contiguousBytes: The binary-encoded message data to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - partial: If `false` (the default), this method will check + /// `Message.isInitialized` before encoding to verify that all required + /// fields are present. If any are missing, this method throws + /// `BinaryEncodingError.missingRequiredFields`. + /// - options: The BinaryDecodingOptions to use. + /// - Throws: `BinaryDecodingError` if decoding fails. + @inlinable + public mutating func merge( + contiguousBytes bytes: Bytes, + extensions: ExtensionMap? = nil, + partial: Bool = false, + options: BinaryDecodingOptions = BinaryDecodingOptions() + ) throws { + try bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + try _merge(rawBuffer: body, extensions: extensions, partial: partial, options: options) + } + } +#endif // swift(>=5.0) + + // Helper for `merge()`s to keep the Decoder internal to SwiftProtobuf while + // allowing the generic over ContiguousBytes to get better codegen from the + // compiler by being `@inlinable`. + @usableFromInline + internal mutating func _merge( + rawBuffer body: UnsafeRawBufferPointer, + extensions: ExtensionMap?, + partial: Bool, + options: BinaryDecodingOptions + ) throws { + if let baseAddress = body.baseAddress, body.count > 0 { + var decoder = BinaryDecoder(forReadingFrom: baseAddress, + count: body.count, + options: options, + extensions: extensions) + try decoder.decodeFullMessage(message: &self) + } + if !partial && !isInitialized { + throw BinaryDecodingError.missingRequiredFields + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONAdditions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONAdditions.swift new file mode 100644 index 00000000..56236db7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONAdditions.swift @@ -0,0 +1,150 @@ +// Sources/SwiftProtobuf/Message+JSONAdditions.swift - JSON format primitive types +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extensions to `Message` to support JSON encoding/decoding. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// JSON encoding and decoding methods for messages. +extension Message { + /// Returns a string containing the JSON serialization of the message. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to JSON. + /// + /// - Returns: A string containing the JSON serialization of the message. + /// - Parameters: + /// - options: The JSONEncodingOptions to use. + /// - Throws: `JSONEncodingError` if encoding fails. + public func jsonString( + options: JSONEncodingOptions = JSONEncodingOptions() + ) throws -> String { + if let m = self as? _CustomJSONCodable { + return try m.encodedJSONString(options: options) + } + let data = try jsonUTF8Data(options: options) + return String(data: data, encoding: String.Encoding.utf8)! + } + + /// Returns a Data containing the UTF-8 JSON serialization of the message. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to JSON. + /// + /// - Returns: A Data containing the JSON serialization of the message. + /// - Parameters: + /// - options: The JSONEncodingOptions to use. + /// - Throws: `JSONEncodingError` if encoding fails. + public func jsonUTF8Data( + options: JSONEncodingOptions = JSONEncodingOptions() + ) throws -> Data { + if let m = self as? _CustomJSONCodable { + let string = try m.encodedJSONString(options: options) + let data = string.data(using: String.Encoding.utf8)! // Cannot fail! + return data + } + var visitor = try JSONEncodingVisitor(type: Self.self, options: options) + visitor.startObject(message: self) + try traverse(visitor: &visitor) + visitor.endObject() + return visitor.dataResult + } + + /// Creates a new message by decoding the given string containing a + /// serialized message in JSON format. + /// + /// - Parameter jsonString: The JSON-formatted string to decode. + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public init( + jsonString: String, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws { + try self.init(jsonString: jsonString, extensions: nil, options: options) + } + + /// Creates a new message by decoding the given string containing a + /// serialized message in JSON format. + /// + /// - Parameter jsonString: The JSON-formatted string to decode. + /// - Parameter extensions: An ExtensionMap for looking up extensions by name + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public init( + jsonString: String, + extensions: ExtensionMap? = nil, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws { + if jsonString.isEmpty { + throw JSONDecodingError.truncated + } + if let data = jsonString.data(using: String.Encoding.utf8) { + try self.init(jsonUTF8Data: data, extensions: extensions, options: options) + } else { + throw JSONDecodingError.truncated + } + } + + /// Creates a new message by decoding the given `Data` containing a + /// serialized message in JSON format, interpreting the data as UTF-8 encoded + /// text. + /// + /// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented + /// as UTF-8 encoded text. + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public init( + jsonUTF8Data: Data, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws { + try self.init(jsonUTF8Data: jsonUTF8Data, extensions: nil, options: options) + } + + /// Creates a new message by decoding the given `Data` containing a + /// serialized message in JSON format, interpreting the data as UTF-8 encoded + /// text. + /// + /// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented + /// as UTF-8 encoded text. + /// - Parameter extensions: The extension map to use with this decode + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public init( + jsonUTF8Data: Data, + extensions: ExtensionMap? = nil, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws { + self.init() + try jsonUTF8Data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + // Empty input is valid for binary, but not for JSON. + guard body.count > 0 else { + throw JSONDecodingError.truncated + } + var decoder = JSONDecoder(source: body, options: options, + messageType: Self.self, extensions: extensions) + if decoder.scanner.skipOptionalNull() { + if let customCodable = Self.self as? _CustomJSONCodable.Type, + let message = try customCodable.decodedFromJSONNull() { + self = message as! Self + } else { + throw JSONDecodingError.illegalNull + } + } else { + try decoder.decodeFullObject(message: &self) + } + if !decoder.scanner.complete { + throw JSONDecodingError.trailingGarbage + } + } + } +} + diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONArrayAdditions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONArrayAdditions.swift new file mode 100644 index 00000000..4579bf43 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+JSONArrayAdditions.swift @@ -0,0 +1,146 @@ +// Sources/SwiftProtobuf/Array+JSONAdditions.swift - JSON format primitive types +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extensions to `Array` to support JSON encoding/decoding. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// JSON encoding and decoding methods for arrays of messages. +extension Message { + /// Returns a string containing the JSON serialization of the messages. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to JSON. + /// + /// - Returns: A string containing the JSON serialization of the messages. + /// - Parameters: + /// - collection: The list of messages to encode. + /// - options: The JSONEncodingOptions to use. + /// - Throws: `JSONEncodingError` if encoding fails. + public static func jsonString( + from collection: C, + options: JSONEncodingOptions = JSONEncodingOptions() + ) throws -> String where C.Iterator.Element == Self { + let data = try jsonUTF8Data(from: collection, options: options) + return String(data: data, encoding: String.Encoding.utf8)! + } + + /// Returns a Data containing the UTF-8 JSON serialization of the messages. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to JSON. + /// + /// - Returns: A Data containing the JSON serialization of the messages. + /// - Parameters: + /// - collection: The list of messages to encode. + /// - options: The JSONEncodingOptions to use. + /// - Throws: `JSONEncodingError` if encoding fails. + public static func jsonUTF8Data( + from collection: C, + options: JSONEncodingOptions = JSONEncodingOptions() + ) throws -> Data where C.Iterator.Element == Self { + var visitor = try JSONEncodingVisitor(type: Self.self, options: options) + visitor.startArray() + for message in collection { + visitor.startArrayObject(message: message) + try message.traverse(visitor: &visitor) + visitor.endObject() + } + visitor.endArray() + return visitor.dataResult + } + + /// Creates a new array of messages by decoding the given string containing a + /// serialized array of messages in JSON format. + /// + /// - Parameter jsonString: The JSON-formatted string to decode. + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public static func array( + fromJSONString jsonString: String, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws -> [Self] { + return try self.array(fromJSONString: jsonString, + extensions: SimpleExtensionMap(), + options: options) + } + + /// Creates a new array of messages by decoding the given string containing a + /// serialized array of messages in JSON format. + /// + /// - Parameter jsonString: The JSON-formatted string to decode. + /// - Parameter extensions: The extension map to use with this decode + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public static func array( + fromJSONString jsonString: String, + extensions: ExtensionMap = SimpleExtensionMap(), + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws -> [Self] { + if jsonString.isEmpty { + throw JSONDecodingError.truncated + } + if let data = jsonString.data(using: String.Encoding.utf8) { + return try array(fromJSONUTF8Data: data, extensions: extensions, options: options) + } else { + throw JSONDecodingError.truncated + } + } + + /// Creates a new array of messages by decoding the given `Data` containing a + /// serialized array of messages in JSON format, interpreting the data as + /// UTF-8 encoded text. + /// + /// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented + /// as UTF-8 encoded text. + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public static func array( + fromJSONUTF8Data jsonUTF8Data: Data, + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws -> [Self] { + return try self.array(fromJSONUTF8Data: jsonUTF8Data, + extensions: SimpleExtensionMap(), + options: options) + } + + /// Creates a new array of messages by decoding the given `Data` containing a + /// serialized array of messages in JSON format, interpreting the data as + /// UTF-8 encoded text. + /// + /// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented + /// as UTF-8 encoded text. + /// - Parameter extensions: The extension map to use with this decode + /// - Parameter options: The JSONDecodingOptions to use. + /// - Throws: `JSONDecodingError` if decoding fails. + public static func array( + fromJSONUTF8Data jsonUTF8Data: Data, + extensions: ExtensionMap = SimpleExtensionMap(), + options: JSONDecodingOptions = JSONDecodingOptions() + ) throws -> [Self] { + return try jsonUTF8Data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + var array = [Self]() + + if body.count > 0 { + var decoder = JSONDecoder(source: body, options: options, + messageType: Self.self, extensions: extensions) + try decoder.decodeRepeatedMessageField(value: &array) + if !decoder.scanner.complete { + throw JSONDecodingError.trailingGarbage + } + } + + return array + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+TextFormatAdditions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+TextFormatAdditions.swift new file mode 100644 index 00000000..7a9dc537 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message+TextFormatAdditions.swift @@ -0,0 +1,111 @@ +// Sources/SwiftProtobuf/Message+TextFormatAdditions.swift - Text format primitive types +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Extensions to `Message` to support text format encoding/decoding. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// Text format encoding and decoding methods for messages. +extension Message { + /// Returns a string containing the Protocol Buffer text format serialization + /// of the message. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to text format. + /// + /// - Returns: A string containing the text format serialization of the + /// message. + public func textFormatString() -> String { + // This is implemented as a separate zero-argument function + // to preserve binary compatibility. + return textFormatString(options: TextFormatEncodingOptions()) + } + + /// Returns a string containing the Protocol Buffer text format serialization + /// of the message. + /// + /// Unlike binary encoding, presence of required fields is not enforced when + /// serializing to JSON. + /// + /// - Returns: A string containing the text format serialization of the message. + /// - Parameters: + /// - options: The TextFormatEncodingOptions to use. + public func textFormatString( + options: TextFormatEncodingOptions + ) -> String { + var visitor = TextFormatEncodingVisitor(message: self, options: options) + if let any = self as? Google_Protobuf_Any { + any._storage.textTraverse(visitor: &visitor) + } else { + // Although the general traversal/encoding infrastructure supports + // throwing errors (needed for JSON/Binary WKTs support, binary format + // missing required fields); TextEncoding never actually does throw. + try! traverse(visitor: &visitor) + } + return visitor.result + } + + /// Creates a new message by decoding the given string containing a + /// serialized message in Protocol Buffer text format. + /// + /// - Parameters: + /// - textFormatString: The text format string to decode. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - Throws: an instance of `TextFormatDecodingError` on failure. + public init( + textFormatString: String, + extensions: ExtensionMap? = nil + ) throws { + // TODO: Remove this api and default the options instead. This api has to + // exist for anything compiled against an older version of the library. + try self.init(textFormatString: textFormatString, + options: TextFormatDecodingOptions(), + extensions: extensions) + } + + /// Creates a new message by decoding the given string containing a + /// serialized message in Protocol Buffer text format. + /// + /// - Parameters: + /// - textFormatString: The text format string to decode. + /// - options: The `TextFormatDencodingOptions` to use. + /// - extensions: An `ExtensionMap` used to look up and decode any + /// extensions in this message or messages nested within this message's + /// fields. + /// - Throws: an instance of `TextFormatDecodingError` on failure. + public init( + textFormatString: String, + options: TextFormatDecodingOptions, + extensions: ExtensionMap? = nil + ) throws { + self.init() + if !textFormatString.isEmpty { + if let data = textFormatString.data(using: String.Encoding.utf8) { + try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let baseAddress = body.baseAddress, body.count > 0 { + var decoder = try TextFormatDecoder(messageType: Self.self, + utf8Pointer: baseAddress, + count: body.count, + options: options, + extensions: extensions) + try decodeMessage(decoder: &decoder) + if !decoder.complete { + throw TextFormatDecodingError.trailingGarbage + } + } + } + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message.swift new file mode 100644 index 00000000..995162c2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Message.swift @@ -0,0 +1,218 @@ +// Sources/SwiftProtobuf/Message.swift - Message support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// + +// TODO: `Message` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. + +/// The protocol which all generated protobuf messages implement. +/// `Message` is the protocol type you should use whenever +/// you need an argument or variable which holds "some message". +/// +/// Generated messages also implement `Hashable`, and thus `Equatable`. +/// However, the protocol conformance is declared on a different protocol. +/// This allows you to use `Message` as a type directly: +/// +/// func consume(message: Message) { ... } +/// +/// Instead of needing to use it as a type constraint on a generic declaration: +/// +/// func consume(message: M) { ... } +/// +/// If you need to convince the compiler that your message is `Hashable` so +/// you can insert it into a `Set` or use it as a `Dictionary` key, use +/// a generic declaration with a type constraint: +/// +/// func insertIntoSet(message: M) { +/// mySet.insert(message) +/// } +/// +/// The actual functionality is implemented either in the generated code or in +/// default implementations of the below methods and properties. +public protocol Message: CustomDebugStringConvertible { + /// Creates a new message with all of its fields initialized to their default + /// values. + init() + + // Metadata + // Basic facts about this class and the proto message it was generated from + // Used by various encoders and decoders + + /// The fully-scoped name of the message from the original .proto file, + /// including any relevant package name. + static var protoMessageName: String { get } + + /// True if all required fields (if any) on this message and any nested + /// messages (recursively) have values set; otherwise, false. + var isInitialized: Bool { get } + + /// Some formats include enough information to transport fields that were + /// not known at generation time. When encountered, they are stored here. + var unknownFields: UnknownStorage { get set } + + // + // General serialization/deserialization machinery + // + + /// Decode all of the fields from the given decoder. + /// + /// This is a simple loop that repeatedly gets the next field number + /// from `decoder.nextFieldNumber()` and then uses the number returned + /// and the type information from the original .proto file to decide + /// what type of data should be decoded for that field. The corresponding + /// method on the decoder is then called to get the field value. + /// + /// This is the core method used by the deserialization machinery. It is + /// `public` to enable users to implement their own encoding formats by + /// conforming to `Decoder`; it should not be called otherwise. + /// + /// Note that this is not specific to binary encodng; formats that use + /// textual identifiers translate those to field numbers and also go + /// through this to decode messages. + /// + /// - Parameters: + /// - decoder: a `Decoder`; the `Message` will call the method + /// corresponding to the type of this field. + /// - Throws: an error on failure or type mismatch. The type of error + /// thrown depends on which decoder is used. + mutating func decodeMessage(decoder: inout D) throws + + /// Traverses the fields of the message, calling the appropriate methods + /// of the passed `Visitor` object. + /// + /// This is used internally by: + /// + /// * Protobuf binary serialization + /// * JSON serialization (with some twists to account for specialty JSON) + /// * Protobuf Text serialization + /// * `Hashable` computation + /// + /// Conceptually, serializers create visitor objects that are + /// then passed recursively to every message and field via generated + /// `traverse` methods. The details get a little involved due to + /// the need to allow particular messages to override particular + /// behaviors for specific encodings, but the general idea is quite simple. + func traverse(visitor: inout V) throws + + // Standard utility properties and methods. + // Most of these are simple wrappers on top of the visitor machinery. + // They are implemented in the protocol, not in the generated structs, + // so can be overridden in user code by defining custom extensions to + // the generated struct. + +#if swift(>=4.2) + /// An implementation of hash(into:) to provide conformance with the + /// `Hashable` protocol. + func hash(into hasher: inout Hasher) +#else // swift(>=4.2) + /// The hash value generated from this message's contents, for conformance + /// with the `Hashable` protocol. + var hashValue: Int { get } +#endif // swift(>=4.2) + + /// Helper to compare `Message`s when not having a specific type to use + /// normal `Equatable`. `Equatable` is provided with specific generated + /// types. + func isEqualTo(message: Message) -> Bool +} + +extension Message { + /// Generated proto2 messages that contain required fields, nested messages + /// that contain required fields, and/or extensions will provide their own + /// implementation of this property that tests that all required fields are + /// set. Users of the generated code SHOULD NOT override this property. + public var isInitialized: Bool { + // The generated code will include a specialization as needed. + return true + } + + /// A hash based on the message's full contents. +#if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + var visitor = HashVisitor(hasher) + try? traverse(visitor: &visitor) + hasher = visitor.hasher + } +#else // swift(>=4.2) + public var hashValue: Int { + var visitor = HashVisitor() + try? traverse(visitor: &visitor) + return visitor.hashValue + } +#endif // swift(>=4.2) + + /// A description generated by recursively visiting all fields in the message, + /// including messages. + public var debugDescription: String { + // TODO Ideally there would be something like serializeText() that can + // take a prefix so we could do something like: + // [class name]( + // [text format] + // ) + let className = String(reflecting: type(of: self)) + let header = "\(className):\n" + return header + textFormatString() + } + + /// Creates an instance of the message type on which this method is called, + /// executes the given block passing the message in as its sole `inout` + /// argument, and then returns the message. + /// + /// This method acts essentially as a "builder" in that the initialization of + /// the message is captured within the block, allowing the returned value to + /// be set in an immutable variable. For example, + /// + /// let msg = MyMessage.with { $0.myField = "foo" } + /// msg.myOtherField = 5 // error: msg is immutable + /// + /// - Parameter populator: A block or function that populates the new message, + /// which is passed into the block as an `inout` argument. + /// - Returns: The message after execution of the block. + public static func with( + _ populator: (inout Self) throws -> () + ) rethrows -> Self { + var message = Self() + try populator(&message) + return message + } +} + +/// Implementation base for all messages; not intended for client use. +/// +/// In general, use `SwiftProtobuf.Message` instead when you need a variable or +/// argument that can hold any type of message. Occasionally, you can use +/// `SwiftProtobuf.Message & Equatable` or `SwiftProtobuf.Message & Hashable` as +/// generic constraints if you need to write generic code that can be applied to +/// multiple message types that uses equality tests, puts messages in a `Set`, +/// or uses them as `Dictionary` keys. +public protocol _MessageImplementationBase: Message, Hashable { + + // Legacy function; no longer used, but left to maintain source compatibility. + func _protobuf_generated_isEqualTo(other: Self) -> Bool +} + +extension _MessageImplementationBase { + public func isEqualTo(message: Message) -> Bool { + guard let other = message as? Self else { + return false + } + return self == other + } + + // Legacy default implementation that is used by old generated code, current + // versions of the plugin/generator provide this directly, but this is here + // just to avoid breaking source compatibility. + public static func ==(lhs: Self, rhs: Self) -> Bool { + return lhs._protobuf_generated_isEqualTo(other: rhs) + } + + // Legacy function that is generated by old versions of the plugin/generator, + // defaulted to keep things simple without changing the api surface. + public func _protobuf_generated_isEqualTo(other: Self) -> Bool { + return self == other + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MessageExtension.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MessageExtension.swift new file mode 100644 index 00000000..ae35d6c2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/MessageExtension.swift @@ -0,0 +1,43 @@ +// Sources/SwiftProtobuf/MessageExtension.swift - Extension support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A 'Message Extension' is an immutable class object that describes +/// a particular extension field, including string and number +/// identifiers, serialization details, and the identity of the +/// message that is being extended. +/// +// ----------------------------------------------------------------------------- + +// TODO: `AnyMessageExtension` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. + +/// Type-erased MessageExtension field implementation. +public protocol AnyMessageExtension { + var fieldNumber: Int { get } + var fieldName: String { get } + var messageType: Message.Type { get } + func _protobuf_newField(decoder: inout D) throws -> AnyExtensionField? +} + +/// A "Message Extension" relates a particular extension field to +/// a particular message. The generic constraints allow +/// compile-time compatibility checks. +public class MessageExtension: AnyMessageExtension { + public let fieldNumber: Int + public let fieldName: String + public let messageType: Message.Type + public init(_protobuf_fieldNumber: Int, fieldName: String) { + self.fieldNumber = _protobuf_fieldNumber + self.fieldName = fieldName + self.messageType = MessageType.self + } + public func _protobuf_newField(decoder: inout D) throws -> AnyExtensionField? { + return try FieldType(protobufExtension: self, decoder: &decoder) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/NameMap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/NameMap.swift new file mode 100644 index 00000000..f2822e89 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/NameMap.swift @@ -0,0 +1,310 @@ +// Sources/SwiftProtobuf/NameMap.swift - Bidirectional number/name mapping +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- + +/// TODO: Right now, only the NameMap and the NameDescription enum +/// (which are directly used by the generated code) are public. +/// This means that code outside the library has no way to actually +/// use this data. We should develop and publicize a suitable API +/// for that purpose. (Which might be the same as the internal API.) + +/// This must be exactly the same as the corresponding code in the +/// protoc-gen-swift code generator. Changing it will break +/// compatibility of the library with older generated code. +/// +/// It does not necessarily need to match protoc's JSON field naming +/// logic, however. +private func toJsonFieldName(_ s: String) -> String { + var result = String() + var capitalizeNext = false + for c in s { + if c == "_" { + capitalizeNext = true + } else if capitalizeNext { + result.append(String(c).uppercased()) + capitalizeNext = false + } else { + result.append(String(c)) + } + } + return result +} + +/// Allocate static memory buffers to intern UTF-8 +/// string data. Track the buffers and release all of those buffers +/// in case we ever get deallocated. +fileprivate class InternPool { + private var interned = [UnsafeRawBufferPointer]() + + func intern(utf8: String.UTF8View) -> UnsafeRawBufferPointer { + #if swift(>=4.1) + let mutable = UnsafeMutableRawBufferPointer.allocate(byteCount: utf8.count, + alignment: MemoryLayout.alignment) + #else + let mutable = UnsafeMutableRawBufferPointer.allocate(count: utf8.count) + #endif + mutable.copyBytes(from: utf8) + let immutable = UnsafeRawBufferPointer(mutable) + interned.append(immutable) + return immutable + } + + func intern(utf8Ptr: UnsafeBufferPointer) -> UnsafeRawBufferPointer { + #if swift(>=4.1) + let mutable = UnsafeMutableRawBufferPointer.allocate(byteCount: utf8Ptr.count, + alignment: MemoryLayout.alignment) + #else + let mutable = UnsafeMutableRawBufferPointer.allocate(count: utf8.count) + #endif + mutable.copyBytes(from: utf8Ptr) + let immutable = UnsafeRawBufferPointer(mutable) + interned.append(immutable) + return immutable + } + + deinit { + for buff in interned { + #if swift(>=4.1) + buff.deallocate() + #else + let p = UnsafeMutableRawPointer(mutating: buff.baseAddress)! + p.deallocate(bytes: buff.count, alignedTo: 1) + #endif + } + } +} + +#if !swift(>=4.2) +// Constants for FNV hash http://tools.ietf.org/html/draft-eastlake-fnv-03 +private let i_2166136261 = Int(bitPattern: 2166136261) +private let i_16777619 = Int(16777619) +#endif + +/// An immutable bidirectional mapping between field/enum-case names +/// and numbers, used to record field names for text-based +/// serialization (JSON and text). These maps are lazily instantiated +/// for each message as needed, so there is no run-time overhead for +/// users who do not use text-based serialization formats. +public struct _NameMap: ExpressibleByDictionaryLiteral { + + /// An immutable interned string container. The `utf8Start` pointer + /// is guaranteed valid for the lifetime of the `NameMap` that you + /// fetched it from. Since `NameMap`s are only instantiated as + /// immutable static values, that should be the lifetime of the + /// program. + /// + /// Internally, this uses `StaticString` (which refers to a fixed + /// block of UTF-8 data) where possible. In cases where the string + /// has to be computed, it caches the UTF-8 bytes in an + /// unmovable and immutable heap area. + internal struct Name: Hashable, CustomStringConvertible { + // This should not be used outside of this file, as it requires + // coordinating the lifecycle with the lifecycle of the pool + // where the raw UTF8 gets interned. + fileprivate init(staticString: StaticString, pool: InternPool) { + self.nameString = .staticString(staticString) + if staticString.hasPointerRepresentation { + self.utf8Buffer = UnsafeRawBufferPointer(start: staticString.utf8Start, + count: staticString.utf8CodeUnitCount) + } else { + self.utf8Buffer = staticString.withUTF8Buffer { pool.intern(utf8Ptr: $0) } + } + } + + // This should not be used outside of this file, as it requires + // coordinating the lifecycle with the lifecycle of the pool + // where the raw UTF8 gets interned. + fileprivate init(string: String, pool: InternPool) { + let utf8 = string.utf8 + self.utf8Buffer = pool.intern(utf8: utf8) + self.nameString = .string(string) + } + + // This is for building a transient `Name` object sufficient for lookup purposes. + // It MUST NOT be exposed outside of this file. + fileprivate init(transientUtf8Buffer: UnsafeRawBufferPointer) { + self.nameString = .staticString("") + self.utf8Buffer = transientUtf8Buffer + } + + private(set) var utf8Buffer: UnsafeRawBufferPointer + + private enum NameString { + case string(String) + case staticString(StaticString) + } + private var nameString: NameString + + public var description: String { + switch nameString { + case .string(let s): return s + case .staticString(let s): return s.description + } + } + + #if swift(>=4.2) + public func hash(into hasher: inout Hasher) { + for byte in utf8Buffer { + hasher.combine(byte) + } + } + #else // swift(>=4.2) + public var hashValue: Int { + var h = i_2166136261 + for byte in utf8Buffer { + h = (h ^ Int(byte)) &* i_16777619 + } + return h + } + #endif // swift(>=4.2) + + public static func ==(lhs: Name, rhs: Name) -> Bool { + if lhs.utf8Buffer.count != rhs.utf8Buffer.count { + return false + } + return lhs.utf8Buffer.elementsEqual(rhs.utf8Buffer) + } + } + + /// The JSON and proto names for a particular field, enum case, or extension. + internal struct Names { + private(set) var json: Name? + private(set) var proto: Name + } + + /// A description of the names for a particular field or enum case. + /// The different forms here let us minimize the amount of string + /// data that we store in the binary. + /// + /// These are only used in the generated code to initialize a NameMap. + public enum NameDescription { + + /// The proto (text format) name and the JSON name are the same string. + case same(proto: StaticString) + + /// The JSON name can be computed from the proto string + case standard(proto: StaticString) + + /// The JSON and text format names are just different. + case unique(proto: StaticString, json: StaticString) + + /// Used for enum cases only to represent a value's primary proto name (the + /// first defined case) and its aliases. The JSON and text format names for + /// enums are always the same. + case aliased(proto: StaticString, aliases: [StaticString]) + } + + private var internPool = InternPool() + + /// The mapping from field/enum-case numbers to names. + private var numberToNameMap: [Int: Names] = [:] + + /// The mapping from proto/text names to field/enum-case numbers. + private var protoToNumberMap: [Name: Int] = [:] + + /// The mapping from JSON names to field/enum-case numbers. + /// Note that this also contains all of the proto/text names, + /// as required by Google's spec for protobuf JSON. + private var jsonToNumberMap: [Name: Int] = [:] + + /// Creates a new empty field/enum-case name/number mapping. + public init() {} + + /// Build the bidirectional maps between numbers and proto/JSON names. + public init(dictionaryLiteral elements: (Int, NameDescription)...) { + for (number, description) in elements { + switch description { + + case .same(proto: let p): + let protoName = Name(staticString: p, pool: internPool) + let names = Names(json: protoName, proto: protoName) + numberToNameMap[number] = names + protoToNumberMap[protoName] = number + jsonToNumberMap[protoName] = number + + case .standard(proto: let p): + let protoName = Name(staticString: p, pool: internPool) + let jsonString = toJsonFieldName(protoName.description) + let jsonName = Name(string: jsonString, pool: internPool) + let names = Names(json: jsonName, proto: protoName) + numberToNameMap[number] = names + protoToNumberMap[protoName] = number + jsonToNumberMap[protoName] = number + jsonToNumberMap[jsonName] = number + + case .unique(proto: let p, json: let j): + let jsonName = Name(staticString: j, pool: internPool) + let protoName = Name(staticString: p, pool: internPool) + let names = Names(json: jsonName, proto: protoName) + numberToNameMap[number] = names + protoToNumberMap[protoName] = number + jsonToNumberMap[protoName] = number + jsonToNumberMap[jsonName] = number + + case .aliased(proto: let p, aliases: let aliases): + let protoName = Name(staticString: p, pool: internPool) + let names = Names(json: protoName, proto: protoName) + numberToNameMap[number] = names + protoToNumberMap[protoName] = number + jsonToNumberMap[protoName] = number + for alias in aliases { + let protoName = Name(staticString: alias, pool: internPool) + protoToNumberMap[protoName] = number + jsonToNumberMap[protoName] = number + } + } + } + } + + /// Returns the name bundle for the field/enum-case with the given number, or + /// `nil` if there is no match. + internal func names(for number: Int) -> Names? { + return numberToNameMap[number] + } + + /// Returns the field/enum-case number that has the given JSON name, + /// or `nil` if there is no match. + /// + /// This is used by the Text format parser to look up field or enum + /// names using a direct reference to the un-decoded UTF8 bytes. + internal func number(forProtoName raw: UnsafeRawBufferPointer) -> Int? { + let n = Name(transientUtf8Buffer: raw) + return protoToNumberMap[n] + } + + /// Returns the field/enum-case number that has the given JSON name, + /// or `nil` if there is no match. + /// + /// This accepts a regular `String` and is used in JSON parsing + /// only when a field name or enum name was decoded from a string + /// containing backslash escapes. + /// + /// JSON parsing must interpret *both* the JSON name of the + /// field/enum-case provided by the descriptor *as well as* its + /// original proto/text name. + internal func number(forJSONName name: String) -> Int? { + let utf8 = Array(name.utf8) + return utf8.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in + let n = Name(transientUtf8Buffer: buffer) + return jsonToNumberMap[n] + } + } + + /// Returns the field/enum-case number that has the given JSON name, + /// or `nil` if there is no match. + /// + /// This is used by the JSON parser when a field name or enum name + /// required no special processing. As a result, we can avoid + /// copying the name and look up the number using a direct reference + /// to the un-decoded UTF8 bytes. + internal func number(forJSONName raw: UnsafeRawBufferPointer) -> Int? { + let n = Name(transientUtf8Buffer: raw) + return jsonToNumberMap[n] + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtoNameProviding.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtoNameProviding.swift new file mode 100644 index 00000000..8b5a81c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtoNameProviding.swift @@ -0,0 +1,23 @@ +// Sources/SwiftProtobuf/ProtoNameProviding.swift - Support for accessing proto names +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- + + +/// SwiftProtobuf Internal: Common support looking up field names. +/// +/// Messages conform to this protocol to provide the proto/text and JSON field +/// names for their fields. This allows these names to be pulled out into +/// extensions in separate files so that users can omit them in release builds +/// (reducing bloat and minimizing leaks of field names). +public protocol _ProtoNameProviding { + + /// The mapping between field numbers and proto/JSON field names defined in + /// the conforming message type. + static var _protobuf_nameMap: _NameMap { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift new file mode 100644 index 00000000..480305e6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift @@ -0,0 +1,43 @@ +// Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift - Version checking +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A scheme that ensures that generated protos cannot be compiled or linked +/// against a version of the runtime with which they are not compatible. +/// +/// In many cases, API changes themselves might introduce incompatibilities +/// between generated code and the runtime library, but we also want to protect +/// against cases where breaking behavioral changes (without affecting the API) +/// would cause generated code to be incompatible with a particular version of +/// the runtime. +/// +// ----------------------------------------------------------------------------- + + +/// An empty protocol that encodes the version of the runtime library. +/// +/// This protocol will be replaced with one containing a different version +/// number any time that breaking changes are made to the Swift Protobuf API. +/// Combined with the protocol below, this lets us verify that generated code is +/// never compiled against a version of the API with which it is incompatible. +/// +/// The version associated with a particular build of the compiler is defined as +/// `Version.compatibilityVersion` in `protoc-gen-swift`. That version and this +/// version must match for the generated protos to be compatible, so if you +/// update one, make sure to update it here and in the associated type below. +public protocol ProtobufAPIVersion_2 {} + +/// This protocol is expected to be implemented by a `fileprivate` type in each +/// source file emitted by `protoc-gen-swift`. It effectively creates a binding +/// between the version of the generated code and the version of this library, +/// causing a compile-time error (with reasonable diagnostics) if they are +/// incompatible. +public protocol ProtobufAPIVersionCheck { + associatedtype Version: ProtobufAPIVersion_2 +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufMap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufMap.swift new file mode 100644 index 00000000..a9c4d80e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ProtobufMap.swift @@ -0,0 +1,39 @@ +// Sources/SwiftProtobuf/ProtobufMap.swift - Map<> support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Generic type representing proto map<> fields. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// SwiftProtobuf Internal: Support for Encoding/Decoding. +public struct _ProtobufMap +{ + public typealias Key = KeyType.BaseType + public typealias Value = ValueType.BaseType + public typealias BaseType = Dictionary +} + +/// SwiftProtobuf Internal: Support for Encoding/Decoding. +public struct _ProtobufMessageMap +{ + public typealias Key = KeyType.BaseType + public typealias Value = ValueType + public typealias BaseType = Dictionary +} + +/// SwiftProtobuf Internal: Support for Encoding/Decoding. +public struct _ProtobufEnumMap +{ + public typealias Key = KeyType.BaseType + public typealias Value = ValueType + public typealias BaseType = Dictionary +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SelectiveVisitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SelectiveVisitor.swift new file mode 100644 index 00000000..e8dc4073 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SelectiveVisitor.swift @@ -0,0 +1,268 @@ +// Sources/SwiftProtobuf/SelectiveVisitor.swift - Base for custom Visitors +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A base for Visitors that only expect a subset of things to called. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// A base for Visitors that only expects a subset of things to called. +internal protocol SelectiveVisitor: Visitor { + // Adds nothing. +} + +/// Default impls for everything so things using this only have to write the +/// methods they expect. Asserts to catch developer errors, but becomes +/// nothing in release to keep code size small. +/// +/// NOTE: This is an impl for *everything*. This means the default impls +/// provided by Visitor to bridge packed->repeated, repeated->singular, etc +/// won't kick in. +extension SelectiveVisitor { + internal mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularEnumField(value: E, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitSingularGroupField(value: G, fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedMessageField(value: [M], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitPackedEnumField(value: [E], fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int) throws { + assert(false) + } + + internal mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int + ) throws where ValueType.RawValue == Int { + assert(false) + } + + internal mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int + ) throws { + assert(false) + } + + internal mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws { + assert(false) + } + + internal mutating func visitExtensionFieldsAsMessageSet( + fields: ExtensionFieldValueSet, + start: Int, + end: Int + ) throws { + assert(false) + } + + internal mutating func visitUnknown(bytes: Data) throws { + assert(false) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SimpleExtensionMap.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SimpleExtensionMap.swift new file mode 100644 index 00000000..ad470860 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/SimpleExtensionMap.swift @@ -0,0 +1,112 @@ +// Sources/SwiftProtobuf/SimpleExtensionMap.swift - Extension support +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A default implementation of ExtensionMap. +/// +// ----------------------------------------------------------------------------- + + +// Note: The generated code only relies on ExpressibleByArrayLiteral +public struct SimpleExtensionMap: ExtensionMap, ExpressibleByArrayLiteral, CustomDebugStringConvertible { + public typealias Element = AnyMessageExtension + + // Since type objects aren't Hashable, we can't do much better than this... + internal var fields = [Int: Array]() + + public init() {} + + public init(arrayLiteral: Element...) { + insert(contentsOf: arrayLiteral) + } + + public init(_ others: SimpleExtensionMap...) { + for other in others { + formUnion(other) + } + } + + public subscript(messageType: Message.Type, fieldNumber: Int) -> AnyMessageExtension? { + get { + if let l = fields[fieldNumber] { + for e in l { + if messageType == e.messageType { + return e + } + } + } + return nil + } + } + + public func fieldNumberForProto(messageType: Message.Type, protoFieldName: String) -> Int? { + // TODO: Make this faster... + for (_, list) in fields { + for e in list { + if e.fieldName == protoFieldName && e.messageType == messageType { + return e.fieldNumber + } + } + } + return nil + } + + public mutating func insert(_ newValue: Element) { + let fieldNumber = newValue.fieldNumber + if let l = fields[fieldNumber] { + let messageType = newValue.messageType + var newL = l.filter { return $0.messageType != messageType } + newL.append(newValue) + fields[fieldNumber] = newL + } else { + fields[fieldNumber] = [newValue] + } + } + + public mutating func insert(contentsOf: [Element]) { + for e in contentsOf { + insert(e) + } + } + + public mutating func formUnion(_ other: SimpleExtensionMap) { + for (fieldNumber, otherList) in other.fields { + if let list = fields[fieldNumber] { + var newList = list.filter { + for o in otherList { + if $0.messageType == o.messageType { return false } + } + return true + } + newList.append(contentsOf: otherList) + fields[fieldNumber] = newList + } else { + fields[fieldNumber] = otherList + } + } + } + + public func union(_ other: SimpleExtensionMap) -> SimpleExtensionMap { + var out = self + out.formUnion(other) + return out + } + + public var debugDescription: String { + var names = [String]() + for (_, list) in fields { + for e in list { + names.append("\(e.fieldName):(\(e.fieldNumber))") + } + } + let d = names.joined(separator: ",") + return "SimpleExtensionMap(\(d))" + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/StringUtils.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/StringUtils.swift new file mode 100644 index 00000000..aea5feef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/StringUtils.swift @@ -0,0 +1,106 @@ +// Sources/SwiftProtobuf/StringUtils.swift - String utility functions +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Utility functions for converting UTF8 bytes into Strings. +/// These functions must: +/// * Accept any valid UTF8, including a zero byte (which is +/// a valid UTF8 encoding of U+0000) +/// * Return nil for any invalid UTF8 +/// * Be fast (since they're extensively used by all decoders +/// and even some of the encoders) +/// +// ----------------------------------------------------------------------------- + +import Foundation + +// Note: Once our minimum support version is at least Swift 5.3, we should +// probably recast the following to use String(unsafeUninitializedCapacity:) + +// Note: We're trying to avoid Foundation's String(format:) since that's not +// universally available. + +fileprivate func formatZeroPaddedInt(_ value: Int32, digits: Int) -> String { + precondition(value >= 0) + let s = String(value) + if s.count >= digits { + return s + } else { + let pad = String(repeating: "0", count: digits - s.count) + return pad + s + } +} + +internal func twoDigit(_ value: Int32) -> String { + return formatZeroPaddedInt(value, digits: 2) +} +internal func threeDigit(_ value: Int32) -> String { + return formatZeroPaddedInt(value, digits: 3) +} +internal func fourDigit(_ value: Int32) -> String { + return formatZeroPaddedInt(value, digits: 4) +} +internal func sixDigit(_ value: Int32) -> String { + return formatZeroPaddedInt(value, digits: 6) +} +internal func nineDigit(_ value: Int32) -> String { + return formatZeroPaddedInt(value, digits: 9) +} + +// Wrapper that takes a buffer and start/end offsets +internal func utf8ToString( + bytes: UnsafeRawBufferPointer, + start: UnsafeRawBufferPointer.Index, + end: UnsafeRawBufferPointer.Index +) -> String? { + return utf8ToString(bytes: bytes.baseAddress! + start, count: end - start) +} + + +// Swift 4 introduced new faster String facilities +// that seem to work consistently across all platforms. + +// Notes on performance: +// +// The pre-verification here only takes about 10% of +// the time needed for constructing the string. +// Eliminating it would provide only a very minor +// speed improvement. +// +// On macOS, this is only about 25% faster than +// the Foundation initializer used below for Swift 3. +// On Linux, the Foundation initializer is much +// slower than on macOS, so this is a much bigger +// win there. +internal func utf8ToString(bytes: UnsafeRawPointer, count: Int) -> String? { + if count == 0 { + return String() + } + let codeUnits = UnsafeRawBufferPointer(start: bytes, count: count) + let sourceEncoding = Unicode.UTF8.self + + // Verify that the UTF-8 is valid. + var p = sourceEncoding.ForwardParser() + var i = codeUnits.makeIterator() + Loop: + while true { + switch p.parseScalar(from: &i) { + case .valid(_): + break + case .error: + return nil + case .emptyInput: + break Loop + } + } + + // This initializer is fast but does not reject broken + // UTF-8 (which is why we validate the UTF-8 above). + return String(decoding: codeUnits, as: sourceEncoding) + } diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecoder.swift new file mode 100644 index 00000000..1c99cf4e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecoder.swift @@ -0,0 +1,726 @@ +// Sources/SwiftProtobuf/TextFormatDecoder.swift - Text format decoding +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Test format decoding engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// +/// Provides a higher-level interface to the token stream coming +/// from a TextFormatScanner. In particular, this provides +/// single-token pushback and convenience functions for iterating +/// over complex structures. +/// +internal struct TextFormatDecoder: Decoder { + internal var scanner: TextFormatScanner + private var fieldCount = 0 + private var terminator: UInt8? + private var fieldNameMap: _NameMap? + private var messageType: Message.Type? + + internal var complete: Bool { + mutating get { + return scanner.complete + } + } + + internal init( + messageType: Message.Type, + utf8Pointer: UnsafeRawPointer, + count: Int, + options: TextFormatDecodingOptions, + extensions: ExtensionMap? + ) throws { + scanner = TextFormatScanner(utf8Pointer: utf8Pointer, count: count, options: options, extensions: extensions) + guard let nameProviding = (messageType as? _ProtoNameProviding.Type) else { + throw TextFormatDecodingError.missingFieldNames + } + fieldNameMap = nameProviding._protobuf_nameMap + self.messageType = messageType + } + + internal init(messageType: Message.Type, scanner: TextFormatScanner, terminator: UInt8?) throws { + self.scanner = scanner + self.terminator = terminator + guard let nameProviding = (messageType as? _ProtoNameProviding.Type) else { + throw TextFormatDecodingError.missingFieldNames + } + fieldNameMap = nameProviding._protobuf_nameMap + self.messageType = messageType + } + + mutating func handleConflictingOneOf() throws { + throw TextFormatDecodingError.conflictingOneOf + } + + mutating func nextFieldNumber() throws -> Int? { + if let terminator = terminator { + if scanner.skipOptionalObjectEnd(terminator) { + return nil + } + } + if fieldCount > 0 { + scanner.skipOptionalSeparator() + } + if let key = try scanner.nextOptionalExtensionKey() { + // Extension key; look up in the extension registry + if let fieldNumber = scanner.extensions?.fieldNumberForProto(messageType: messageType!, protoFieldName: key) { + fieldCount += 1 + return fieldNumber + } else { + throw TextFormatDecodingError.unknownField + } + } else if let fieldNumber = try scanner.nextFieldNumber(names: fieldNameMap!) { + fieldCount += 1 + return fieldNumber + } else if terminator == nil { + return nil + } else { + throw TextFormatDecodingError.truncated + } + + } + + mutating func decodeSingularFloatField(value: inout Float) throws { + try scanner.skipRequiredColon() + value = try scanner.nextFloat() + } + mutating func decodeSingularFloatField(value: inout Float?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextFloat() + } + mutating func decodeRepeatedFloatField(value: inout [Float]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextFloat() + value.append(n) + } + } else { + let n = try scanner.nextFloat() + value.append(n) + } + } + mutating func decodeSingularDoubleField(value: inout Double) throws { + try scanner.skipRequiredColon() + value = try scanner.nextDouble() + } + mutating func decodeSingularDoubleField(value: inout Double?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextDouble() + } + mutating func decodeRepeatedDoubleField(value: inout [Double]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextDouble() + value.append(n) + } + } else { + let n = try scanner.nextDouble() + value.append(n) + } + } + mutating func decodeSingularInt32Field(value: inout Int32) throws { + try scanner.skipRequiredColon() + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw TextFormatDecodingError.malformedNumber + } + value = Int32(truncatingIfNeeded: n) + } + mutating func decodeSingularInt32Field(value: inout Int32?) throws { + try scanner.skipRequiredColon() + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw TextFormatDecodingError.malformedNumber + } + value = Int32(truncatingIfNeeded: n) + } + mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw TextFormatDecodingError.malformedNumber + } + value.append(Int32(truncatingIfNeeded: n)) + } + } else { + let n = try scanner.nextSInt() + if n > Int64(Int32.max) || n < Int64(Int32.min) { + throw TextFormatDecodingError.malformedNumber + } + value.append(Int32(truncatingIfNeeded: n)) + } + } + mutating func decodeSingularInt64Field(value: inout Int64) throws { + try scanner.skipRequiredColon() + value = try scanner.nextSInt() + } + mutating func decodeSingularInt64Field(value: inout Int64?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextSInt() + } + mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextSInt() + value.append(n) + } + } else { + let n = try scanner.nextSInt() + value.append(n) + } + } + mutating func decodeSingularUInt32Field(value: inout UInt32) throws { + try scanner.skipRequiredColon() + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw TextFormatDecodingError.malformedNumber + } + value = UInt32(truncatingIfNeeded: n) + } + mutating func decodeSingularUInt32Field(value: inout UInt32?) throws { + try scanner.skipRequiredColon() + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw TextFormatDecodingError.malformedNumber + } + value = UInt32(truncatingIfNeeded: n) + } + mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw TextFormatDecodingError.malformedNumber + } + value.append(UInt32(truncatingIfNeeded: n)) + } + } else { + let n = try scanner.nextUInt() + if n > UInt64(UInt32.max) { + throw TextFormatDecodingError.malformedNumber + } + value.append(UInt32(truncatingIfNeeded: n)) + } + } + mutating func decodeSingularUInt64Field(value: inout UInt64) throws { + try scanner.skipRequiredColon() + value = try scanner.nextUInt() + } + mutating func decodeSingularUInt64Field(value: inout UInt64?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextUInt() + } + mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextUInt() + value.append(n) + } + } else { + let n = try scanner.nextUInt() + value.append(n) + } + } + mutating func decodeSingularSInt32Field(value: inout Int32) throws { + try decodeSingularInt32Field(value: &value) + } + mutating func decodeSingularSInt32Field(value: inout Int32?) throws { + try decodeSingularInt32Field(value: &value) + } + mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws { + try decodeRepeatedInt32Field(value: &value) + } + mutating func decodeSingularSInt64Field(value: inout Int64) throws { + try decodeSingularInt64Field(value: &value) + } + mutating func decodeSingularSInt64Field(value: inout Int64?) throws { + try decodeSingularInt64Field(value: &value) + } + mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws { + try decodeRepeatedInt64Field(value: &value) + } + mutating func decodeSingularFixed32Field(value: inout UInt32) throws { + try decodeSingularUInt32Field(value: &value) + } + mutating func decodeSingularFixed32Field(value: inout UInt32?) throws { + try decodeSingularUInt32Field(value: &value) + } + mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws { + try decodeRepeatedUInt32Field(value: &value) + } + mutating func decodeSingularFixed64Field(value: inout UInt64) throws { + try decodeSingularUInt64Field(value: &value) + } + mutating func decodeSingularFixed64Field(value: inout UInt64?) throws { + try decodeSingularUInt64Field(value: &value) + } + mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws { + try decodeRepeatedUInt64Field(value: &value) + } + mutating func decodeSingularSFixed32Field(value: inout Int32) throws { + try decodeSingularInt32Field(value: &value) + } + mutating func decodeSingularSFixed32Field(value: inout Int32?) throws { + try decodeSingularInt32Field(value: &value) + } + mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws { + try decodeRepeatedInt32Field(value: &value) + } + mutating func decodeSingularSFixed64Field(value: inout Int64) throws { + try decodeSingularInt64Field(value: &value) + } + mutating func decodeSingularSFixed64Field(value: inout Int64?) throws { + try decodeSingularInt64Field(value: &value) + } + mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws { + try decodeRepeatedInt64Field(value: &value) + } + mutating func decodeSingularBoolField(value: inout Bool) throws { + try scanner.skipRequiredColon() + value = try scanner.nextBool() + } + mutating func decodeSingularBoolField(value: inout Bool?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextBool() + } + mutating func decodeRepeatedBoolField(value: inout [Bool]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextBool() + value.append(n) + } + } else { + let n = try scanner.nextBool() + value.append(n) + } + } + mutating func decodeSingularStringField(value: inout String) throws { + try scanner.skipRequiredColon() + value = try scanner.nextStringValue() + } + mutating func decodeSingularStringField(value: inout String?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextStringValue() + } + mutating func decodeRepeatedStringField(value: inout [String]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextStringValue() + value.append(n) + } + } else { + let n = try scanner.nextStringValue() + value.append(n) + } + } + mutating func decodeSingularBytesField(value: inout Data) throws { + try scanner.skipRequiredColon() + value = try scanner.nextBytesValue() + } + mutating func decodeSingularBytesField(value: inout Data?) throws { + try scanner.skipRequiredColon() + value = try scanner.nextBytesValue() + } + mutating func decodeRepeatedBytesField(value: inout [Data]) throws { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let n = try scanner.nextBytesValue() + value.append(n) + } + } else { + let n = try scanner.nextBytesValue() + value.append(n) + } + } + + private mutating func decodeEnum() throws -> E where E.RawValue == Int { + if let name = try scanner.nextOptionalEnumName() { + if let b = E(rawUTF8: name) { + return b + } else { + throw TextFormatDecodingError.unrecognizedEnumValue + } + } + let number = try scanner.nextSInt() + if number >= Int64(Int32.min) && number <= Int64(Int32.max) { + let n = Int32(truncatingIfNeeded: number) + if let e = E(rawValue: Int(n)) { + return e + } else { + throw TextFormatDecodingError.unrecognizedEnumValue + } + } + throw TextFormatDecodingError.malformedText + + } + + mutating func decodeSingularEnumField(value: inout E?) throws where E.RawValue == Int { + try scanner.skipRequiredColon() + let e: E = try decodeEnum() + value = e + } + + mutating func decodeSingularEnumField(value: inout E) throws where E.RawValue == Int { + try scanner.skipRequiredColon() + let e: E = try decodeEnum() + value = e + } + + mutating func decodeRepeatedEnumField(value: inout [E]) throws where E.RawValue == Int { + try scanner.skipRequiredColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let e: E = try decodeEnum() + value.append(e) + } + } else { + let e: E = try decodeEnum() + value.append(e) + } + } + + mutating func decodeSingularMessageField(value: inout M?) throws { + _ = scanner.skipOptionalColon() + if value == nil { + value = M() + } + let terminator = try scanner.skipObjectStart() + var subDecoder = try TextFormatDecoder(messageType: M.self, scanner: scanner, terminator: terminator) + if M.self == Google_Protobuf_Any.self { + var any = value as! Google_Protobuf_Any? + try any!.decodeTextFormat(decoder: &subDecoder) + value = any as! M? + } else { + try value!.decodeMessage(decoder: &subDecoder) + } + assert((scanner.recursionBudget + 1) == subDecoder.scanner.recursionBudget) + scanner = subDecoder.scanner + } + + mutating func decodeRepeatedMessageField(value: inout [M]) throws { + _ = scanner.skipOptionalColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + let terminator = try scanner.skipObjectStart() + var subDecoder = try TextFormatDecoder(messageType: M.self, scanner: scanner, terminator: terminator) + if M.self == Google_Protobuf_Any.self { + var message = Google_Protobuf_Any() + try message.decodeTextFormat(decoder: &subDecoder) + value.append(message as! M) + } else { + var message = M() + try message.decodeMessage(decoder: &subDecoder) + value.append(message) + } + assert((scanner.recursionBudget + 1) == subDecoder.scanner.recursionBudget) + scanner = subDecoder.scanner + } + } else { + let terminator = try scanner.skipObjectStart() + var subDecoder = try TextFormatDecoder(messageType: M.self, scanner: scanner, terminator: terminator) + if M.self == Google_Protobuf_Any.self { + var message = Google_Protobuf_Any() + try message.decodeTextFormat(decoder: &subDecoder) + value.append(message as! M) + } else { + var message = M() + try message.decodeMessage(decoder: &subDecoder) + value.append(message) + } + assert((scanner.recursionBudget + 1) == subDecoder.scanner.recursionBudget) + scanner = subDecoder.scanner + } + } + + mutating func decodeSingularGroupField(value: inout G?) throws { + try decodeSingularMessageField(value: &value) + } + + mutating func decodeRepeatedGroupField(value: inout [G]) throws { + try decodeRepeatedMessageField(value: &value) + } + + private mutating func decodeMapEntry(mapType: _ProtobufMap.Type, value: inout _ProtobufMap.BaseType) throws { + var keyField: KeyType.BaseType? + var valueField: ValueType.BaseType? + let terminator = try scanner.skipObjectStart() + while true { + if scanner.skipOptionalObjectEnd(terminator) { + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + return + } else { + throw TextFormatDecodingError.malformedText + } + } + if let key = try scanner.nextKey() { + switch key { + case "key", "1": + try KeyType.decodeSingular(value: &keyField, from: &self) + case "value", "2": + try ValueType.decodeSingular(value: &valueField, from: &self) + default: + throw TextFormatDecodingError.unknownField + } + scanner.skipOptionalSeparator() + } else { + throw TextFormatDecodingError.malformedText + } + } + } + + mutating func decodeMapField(fieldType: _ProtobufMap.Type, value: inout _ProtobufMap.BaseType) throws { + _ = scanner.skipOptionalColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + try decodeMapEntry(mapType: fieldType, value: &value) + } + } else { + try decodeMapEntry(mapType: fieldType, value: &value) + } + } + + private mutating func decodeMapEntry(mapType: _ProtobufEnumMap.Type, value: inout _ProtobufEnumMap.BaseType) throws where ValueType.RawValue == Int { + var keyField: KeyType.BaseType? + var valueField: ValueType? + let terminator = try scanner.skipObjectStart() + while true { + if scanner.skipOptionalObjectEnd(terminator) { + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + return + } else { + throw TextFormatDecodingError.malformedText + } + } + if let key = try scanner.nextKey() { + switch key { + case "key", "1": + try KeyType.decodeSingular(value: &keyField, from: &self) + case "value", "2": + try decodeSingularEnumField(value: &valueField) + default: + throw TextFormatDecodingError.unknownField + } + scanner.skipOptionalSeparator() + } else { + throw TextFormatDecodingError.malformedText + } + } + } + + mutating func decodeMapField(fieldType: _ProtobufEnumMap.Type, value: inout _ProtobufEnumMap.BaseType) throws where ValueType.RawValue == Int { + _ = scanner.skipOptionalColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + try decodeMapEntry(mapType: fieldType, value: &value) + } + } else { + try decodeMapEntry(mapType: fieldType, value: &value) + } + } + + private mutating func decodeMapEntry(mapType: _ProtobufMessageMap.Type, value: inout _ProtobufMessageMap.BaseType) throws { + var keyField: KeyType.BaseType? + var valueField: ValueType? + let terminator = try scanner.skipObjectStart() + while true { + if scanner.skipOptionalObjectEnd(terminator) { + if let keyField = keyField, let valueField = valueField { + value[keyField] = valueField + return + } else { + throw TextFormatDecodingError.malformedText + } + } + if let key = try scanner.nextKey() { + switch key { + case "key", "1": + try KeyType.decodeSingular(value: &keyField, from: &self) + case "value", "2": + try decodeSingularMessageField(value: &valueField) + default: + throw TextFormatDecodingError.unknownField + } + scanner.skipOptionalSeparator() + } else { + throw TextFormatDecodingError.malformedText + } + } + } + + mutating func decodeMapField(fieldType: _ProtobufMessageMap.Type, value: inout _ProtobufMessageMap.BaseType) throws { + _ = scanner.skipOptionalColon() + if scanner.skipOptionalBeginArray() { + var firstItem = true + while true { + if scanner.skipOptionalEndArray() { + return + } + if firstItem { + firstItem = false + } else { + try scanner.skipRequiredComma() + } + try decodeMapEntry(mapType: fieldType, value: &value) + } + } else { + try decodeMapEntry(mapType: fieldType, value: &value) + } + } + + mutating func decodeExtensionField(values: inout ExtensionFieldValueSet, messageType: Message.Type, fieldNumber: Int) throws { + if let ext = scanner.extensions?[messageType, fieldNumber] { + try values.modify(index: fieldNumber) { fieldValue in + if fieldValue != nil { + try fieldValue!.decodeExtensionField(decoder: &self) + } else { + fieldValue = try ext._protobuf_newField(decoder: &self) + } + if fieldValue == nil { + // Really things should never get here, for TextFormat, decoding + // the value should always work or throw an error. This specific + // error result is to allow this to be more detectable. + throw TextFormatDecodingError.internalExtensionError + } + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingError.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingError.swift new file mode 100644 index 00000000..ea57bf56 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingError.swift @@ -0,0 +1,42 @@ +// Sources/SwiftProtobuf/TextFormatDecodingError.swift - Protobuf text format decoding errors +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Protobuf text format decoding errors +/// +// ----------------------------------------------------------------------------- + +public enum TextFormatDecodingError: Error { + /// Text data could not be parsed + case malformedText + /// A number could not be parsed + case malformedNumber + /// Extraneous data remained after decoding should have been complete + case trailingGarbage + /// The data stopped before we expected + case truncated + /// A string was not valid UTF8 + case invalidUTF8 + /// The data being parsed does not match the type specified in the proto file + case schemaMismatch + /// Field names were not compiled into the binary + case missingFieldNames + /// A field identifier (name or number) was not found on the message + case unknownField + /// The enum value was not recognized + case unrecognizedEnumValue + /// Text format rejects conflicting values for the same oneof field + case conflictingOneOf + /// An internal error happened while decoding. If this is ever encountered, + /// please file an issue with SwiftProtobuf with as much details as possible + /// for what happened (proto definitions, bytes being decoded (if possible)). + case internalExtensionError + /// Reached the nesting limit for messages within messages while decoding. + case messageDepthLimit +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingOptions.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingOptions.swift new file mode 100644 index 00000000..4713eba4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatDecodingOptions.swift @@ -0,0 +1,25 @@ +// Sources/SwiftProtobuf/TextFormatDecodingOptions.swift - Text format decoding options +// +// Copyright (c) 2014 - 2021 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Text format decoding options +/// +// ----------------------------------------------------------------------------- + +/// Options for TextFormatDecoding. +public struct TextFormatDecodingOptions { + /// The maximum nesting of message with messages. The default is 100. + /// + /// To prevent corrupt or malicious messages from causing stack overflows, + /// this controls how deep messages can be nested within other messages + /// while parsing. + public var messageDepthLimit: Int = 100 + + public init() {} +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatEncoder.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatEncoder.swift new file mode 100644 index 00000000..6fe217cd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatEncoder.swift @@ -0,0 +1,296 @@ +// Sources/SwiftProtobuf/TextFormatEncoder.swift - Text format encoding support +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Text format serialization engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let asciiSpace = UInt8(ascii: " ") +private let asciiColon = UInt8(ascii: ":") +private let asciiComma = UInt8(ascii: ",") +private let asciiMinus = UInt8(ascii: "-") +private let asciiBackslash = UInt8(ascii: "\\") +private let asciiDoubleQuote = UInt8(ascii: "\"") +private let asciiZero = UInt8(ascii: "0") +private let asciiOpenCurlyBracket = UInt8(ascii: "{") +private let asciiCloseCurlyBracket = UInt8(ascii: "}") +private let asciiOpenSquareBracket = UInt8(ascii: "[") +private let asciiCloseSquareBracket = UInt8(ascii: "]") +private let asciiNewline = UInt8(ascii: "\n") +private let asciiUpperA = UInt8(ascii: "A") + +private let tabSize = 2 +private let tab = [UInt8](repeating: asciiSpace, count: tabSize) + +/// TextFormatEncoder has no public members. +internal struct TextFormatEncoder { + private var data = [UInt8]() + private var indentString: [UInt8] = [] + var stringResult: String { + get { + return String(bytes: data, encoding: String.Encoding.utf8)! + } + } + + internal mutating func append(staticText: StaticString) { + let buff = UnsafeBufferPointer(start: staticText.utf8Start, count: staticText.utf8CodeUnitCount) + data.append(contentsOf: buff) + } + + internal mutating func append(name: _NameMap.Name) { + data.append(contentsOf: name.utf8Buffer) + } + + internal mutating func append(bytes: [UInt8]) { + data.append(contentsOf: bytes) + } + + private mutating func append(text: String) { + data.append(contentsOf: text.utf8) + } + + init() {} + + internal mutating func indent() { + data.append(contentsOf: indentString) + } + + mutating func emitFieldName(name: UnsafeRawBufferPointer) { + indent() + data.append(contentsOf: name) + } + + mutating func emitFieldName(name: StaticString) { + let buff = UnsafeRawBufferPointer(start: name.utf8Start, count: name.utf8CodeUnitCount) + emitFieldName(name: buff) + } + + mutating func emitFieldName(name: [UInt8]) { + indent() + data.append(contentsOf: name) + } + + mutating func emitExtensionFieldName(name: String) { + indent() + data.append(asciiOpenSquareBracket) + append(text: name) + data.append(asciiCloseSquareBracket) + } + + mutating func emitFieldNumber(number: Int) { + indent() + appendUInt(value: UInt64(number)) + } + + mutating func startRegularField() { + append(staticText: ": ") + } + mutating func endRegularField() { + data.append(asciiNewline) + } + + // In Text format, a message-valued field writes the name + // without a trailing colon: + // name_of_field {key: value key2: value2} + mutating func startMessageField() { + append(staticText: " {\n") + indentString.append(contentsOf: tab) + } + + mutating func endMessageField() { + indentString.removeLast(tabSize) + indent() + append(staticText: "}\n") + } + + mutating func startArray() { + data.append(asciiOpenSquareBracket) + } + + mutating func arraySeparator() { + append(staticText: ", ") + } + + mutating func endArray() { + data.append(asciiCloseSquareBracket) + } + + mutating func putEnumValue(value: E) { + if let name = value.name { + data.append(contentsOf: name.utf8Buffer) + } else { + appendInt(value: Int64(value.rawValue)) + } + } + + mutating func putFloatValue(value: Float) { + if value.isNaN { + append(staticText: "nan") + } else if !value.isFinite { + if value < 0 { + append(staticText: "-inf") + } else { + append(staticText: "inf") + } + } else { + data.append(contentsOf: value.debugDescription.utf8) + } + } + + mutating func putDoubleValue(value: Double) { + if value.isNaN { + append(staticText: "nan") + } else if !value.isFinite { + if value < 0 { + append(staticText: "-inf") + } else { + append(staticText: "inf") + } + } else { + data.append(contentsOf: value.debugDescription.utf8) + } + } + + private mutating func appendUInt(value: UInt64) { + if value >= 1000 { + appendUInt(value: value / 1000) + } + if value >= 100 { + data.append(asciiZero + UInt8((value / 100) % 10)) + } + if value >= 10 { + data.append(asciiZero + UInt8((value / 10) % 10)) + } + data.append(asciiZero + UInt8(value % 10)) + } + private mutating func appendInt(value: Int64) { + if value < 0 { + data.append(asciiMinus) + // This is the twos-complement negation of value, + // computed in a way that won't overflow a 64-bit + // signed integer. + appendUInt(value: 1 + ~UInt64(bitPattern: value)) + } else { + appendUInt(value: UInt64(bitPattern: value)) + } + } + + mutating func putInt64(value: Int64) { + appendInt(value: value) + } + + mutating func putUInt64(value: UInt64) { + appendUInt(value: value) + } + + mutating func appendUIntHex(value: UInt64, digits: Int) { + if digits == 0 { + append(staticText: "0x") + } else { + appendUIntHex(value: value >> 4, digits: digits - 1) + let d = UInt8(truncatingIfNeeded: value % 16) + data.append(d < 10 ? asciiZero + d : asciiUpperA + d - 10) + } + } + + mutating func putUInt64Hex(value: UInt64, digits: Int) { + appendUIntHex(value: value, digits: digits) + } + + mutating func putBoolValue(value: Bool) { + append(staticText: value ? "true" : "false") + } + + mutating func putStringValue(value: String) { + data.append(asciiDoubleQuote) + for c in value.unicodeScalars { + switch c.value { + // Special two-byte escapes + case 8: + append(staticText: "\\b") + case 9: + append(staticText: "\\t") + case 10: + append(staticText: "\\n") + case 11: + append(staticText: "\\v") + case 12: + append(staticText: "\\f") + case 13: + append(staticText: "\\r") + case 34: + append(staticText: "\\\"") + case 92: + append(staticText: "\\\\") + case 0...31, 127: // Octal form for C0 control chars + data.append(asciiBackslash) + data.append(asciiZero + UInt8(c.value / 64)) + data.append(asciiZero + UInt8(c.value / 8 % 8)) + data.append(asciiZero + UInt8(c.value % 8)) + case 0...127: // ASCII + data.append(UInt8(truncatingIfNeeded: c.value)) + case 0x80...0x7ff: + data.append(0xc0 + UInt8(c.value / 64)) + data.append(0x80 + UInt8(c.value % 64)) + case 0x800...0xffff: + data.append(0xe0 + UInt8(truncatingIfNeeded: c.value >> 12)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f)) + default: + data.append(0xf0 + UInt8(truncatingIfNeeded: c.value >> 18)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 12) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f)) + data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f)) + } + } + data.append(asciiDoubleQuote) + } + + mutating func putBytesValue(value: Data) { + data.append(asciiDoubleQuote) + value.withUnsafeBytes { (body: UnsafeRawBufferPointer) in + if let p = body.baseAddress, body.count > 0 { + for i in 0.. [UInt8] { + var bytes = [UInt8]() + if let protoName = nameMap?.names(for: fieldNumber)?.proto { + bytes.append(contentsOf: protoName.utf8Buffer) + } else if let protoName = nameResolver[fieldNumber] { + let buff = UnsafeBufferPointer(start: protoName.utf8Start, count: protoName.utf8CodeUnitCount) + bytes.append(contentsOf: buff) + } else if let extensionName = extensions?[fieldNumber]?.protobufExtension.fieldName { + bytes.append(UInt8(ascii: "[")) + bytes.append(contentsOf: extensionName.utf8) + bytes.append(UInt8(ascii: "]")) + } else { + bytes.append(contentsOf: fieldNumber.description.utf8) + } + return bytes + } + + private mutating func emitFieldName(lookingUp fieldNumber: Int) { + if let protoName = nameMap?.names(for: fieldNumber)?.proto { + encoder.emitFieldName(name: protoName.utf8Buffer) + } else if let protoName = nameResolver[fieldNumber] { + encoder.emitFieldName(name: protoName) + } else if let extensionName = extensions?[fieldNumber]?.protobufExtension.fieldName { + encoder.emitExtensionFieldName(name: extensionName) + } else { + encoder.emitFieldNumber(number: fieldNumber) + } + } + + mutating func visitUnknown(bytes: Data) throws { + if options.printUnknownFields { + try bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) -> () in + if let baseAddress = body.baseAddress, body.count > 0 { + // All fields will be directly handled, so there is no need for + // the unknown field buffering/collection (when scannings to see + // if something is a message, this would be extremely wasteful). + var binaryOptions = BinaryDecodingOptions() + binaryOptions.discardUnknownFields = true + var decoder = BinaryDecoder(forReadingFrom: baseAddress, + count: body.count, + options: binaryOptions) + try visitUnknown(decoder: &decoder) + } + } + } + } + + /// Helper for printing out unknowns. + /// + /// The implementation tries to be "helpful" and if a length delimited field + /// appears to be a submessage, it prints it as such. However, that opens the + /// door to someone sending a message with an unknown field that is a stack + /// bomb, i.e. - it causes this code to recurse, exhausing the stack and + /// thus opening up an attack vector. To keep this "help", but avoid the + /// attack, a limit is placed on how many times it will recurse before just + /// treating the length delimted fields as bytes and not trying to decode + /// them. + private mutating func visitUnknown( + decoder: inout BinaryDecoder, + recursionBudget: Int = 10 + ) throws { + // This stack serves to avoid recursion for groups within groups within + // groups..., this avoid the stack attack that the message detection + // hits. No limit is placed on this because there is no stack risk with + // recursion, and because if a limit was hit, there is no other way to + // encode the group (the message field can just print as length + // delimited, groups don't have an option like that). + var groupFieldNumberStack: [Int] = [] + + while let tag = try decoder.getTag() { + switch tag.wireFormat { + case .varint: + encoder.emitFieldNumber(number: tag.fieldNumber) + var value: UInt64 = 0 + encoder.startRegularField() + try decoder.decodeSingularUInt64Field(value: &value) + encoder.putUInt64(value: value) + encoder.endRegularField() + case .fixed64: + encoder.emitFieldNumber(number: tag.fieldNumber) + var value: UInt64 = 0 + encoder.startRegularField() + try decoder.decodeSingularFixed64Field(value: &value) + encoder.putUInt64Hex(value: value, digits: 16) + encoder.endRegularField() + case .lengthDelimited: + encoder.emitFieldNumber(number: tag.fieldNumber) + var bytes = Data() + try decoder.decodeSingularBytesField(value: &bytes) + bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) -> () in + if let baseAddress = body.baseAddress, body.count > 0 { + var encodeAsBytes: Bool + if (recursionBudget > 0) { + do { + // Walk all the fields to test if it looks like a message + var testDecoder = BinaryDecoder(forReadingFrom: baseAddress, + count: body.count, + parent: decoder) + while let _ = try testDecoder.nextFieldNumber() { + } + // No error? Output the message body. + encodeAsBytes = false + var subDecoder = BinaryDecoder(forReadingFrom: baseAddress, + count: bytes.count, + parent: decoder) + encoder.startMessageField() + try visitUnknown(decoder: &subDecoder, + recursionBudget: recursionBudget - 1) + encoder.endMessageField() + } catch { + encodeAsBytes = true + } + } else { + encodeAsBytes = true + } + if (encodeAsBytes) { + encoder.startRegularField() + encoder.putBytesValue(value: bytes) + encoder.endRegularField() + } + } + } + case .startGroup: + encoder.emitFieldNumber(number: tag.fieldNumber) + encoder.startMessageField() + groupFieldNumberStack.append(tag.fieldNumber) + case .endGroup: + let groupFieldNumber = groupFieldNumberStack.popLast() + // Unknown data is scanned and verified by the + // binary parser, so this can never fail. + assert(tag.fieldNumber == groupFieldNumber) + encoder.endMessageField() + case .fixed32: + encoder.emitFieldNumber(number: tag.fieldNumber) + var value: UInt32 = 0 + encoder.startRegularField() + try decoder.decodeSingularFixed32Field(value: &value) + encoder.putUInt64Hex(value: UInt64(value), digits: 8) + encoder.endRegularField() + } + } + + // Unknown data is scanned and verified by the binary parser, so this can + // never fail. + assert(groupFieldNumberStack.isEmpty) + } + + // Visitor.swift defines default versions for other singular field types + // that simply widen and dispatch to one of the following. Since Text format + // does not distinguish e.g., Fixed64 vs. UInt64, this is sufficient. + + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putFloatValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putDoubleValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putInt64(value: value) + encoder.endRegularField() + } + + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putUInt64(value: value) + encoder.endRegularField() + } + + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putBoolValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putStringValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putBytesValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularEnumField(value: E, fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + encoder.putEnumValue(value: value) + encoder.endRegularField() + } + + mutating func visitSingularMessageField(value: M, + fieldNumber: Int) throws { + emitFieldName(lookingUp: fieldNumber) + + // Cache old encoder state + let oldNameMap = self.nameMap + let oldNameResolver = self.nameResolver + let oldExtensions = self.extensions + // Update encoding state for new message + self.nameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap + self.nameResolver = [:] + self.extensions = (value as? ExtensibleMessage)?._protobuf_extensionFieldValues + // Encode submessage + encoder.startMessageField() + if let any = value as? Google_Protobuf_Any { + any.textTraverse(visitor: &self) + } else { + try! value.traverse(visitor: &self) + } + encoder.endMessageField() + // Restore state before returning + self.extensions = oldExtensions + self.nameResolver = oldNameResolver + self.nameMap = oldNameMap + } + + // Emit the full "verbose" form of an Any. This writes the typeURL + // as a field name in `[...]` followed by the fields of the + // contained message. + internal mutating func visitAnyVerbose(value: Message, typeURL: String) { + encoder.emitExtensionFieldName(name: typeURL) + encoder.startMessageField() + var visitor = TextFormatEncodingVisitor(message: value, encoder: encoder, options: options) + if let any = value as? Google_Protobuf_Any { + any.textTraverse(visitor: &visitor) + } else { + try! value.traverse(visitor: &visitor) + } + encoder = visitor.encoder + encoder.endMessageField() + } + + // Write a single special field called "#json". This + // is used for Any objects with undecoded JSON contents. + internal mutating func visitAnyJSONDataField(value: Data) { + encoder.indent() + encoder.append(staticText: "#json: ") + encoder.putBytesValue(value: value) + encoder.append(staticText: "\n") + } + + // The default implementations in Visitor.swift provide the correct + // results, but we get significantly better performance by only doing + // the name lookup once for the array, rather than once for each element: + + mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putFloatValue(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putDoubleValue(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putInt64(value: Int64(v)) + encoder.endRegularField() + } + } + + mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putInt64(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putUInt64(value: UInt64(v)) + encoder.endRegularField() + } + } + + mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putUInt64(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber) + } + mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber) + } + mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putBoolValue(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putStringValue(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putBytesValue(value: v) + encoder.endRegularField() + } + } + + mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { + assert(!value.isEmpty) + let fieldName = formatFieldName(lookingUp: fieldNumber) + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startRegularField() + encoder.putEnumValue(value: v) + encoder.endRegularField() + } + } + + // Messages and groups + mutating func visitRepeatedMessageField(value: [M], + fieldNumber: Int) throws { + assert(!value.isEmpty) + // Look up field name against outer message encoding state + let fieldName = formatFieldName(lookingUp: fieldNumber) + // Cache old encoder state + let oldNameMap = self.nameMap + let oldNameResolver = self.nameResolver + let oldExtensions = self.extensions + // Update encoding state for new message type + self.nameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap + self.nameResolver = [:] + self.extensions = (value as? ExtensibleMessage)?._protobuf_extensionFieldValues + // Iterate and encode each message + for v in value { + encoder.emitFieldName(name: fieldName) + encoder.startMessageField() + if let any = v as? Google_Protobuf_Any { + any.textTraverse(visitor: &self) + } else { + try! v.traverse(visitor: &self) + } + encoder.endMessageField() + } + // Restore state + self.extensions = oldExtensions + self.nameResolver = oldNameResolver + self.nameMap = oldNameMap + } + + // Google's C++ implementation of Text format supports two formats + // for repeated numeric fields: "short" format writes the list as a + // single field with values enclosed in `[...]`, "long" format + // writes a separate field name/value for each item. They provide + // an option for callers to select which output version they prefer. + + // Since this distinction mirrors the difference in Protobuf Binary + // between "packed" and "non-packed", I've chosen to use the short + // format for packed fields and the long version for repeated + // fields. This provides a clear visual distinction between these + // fields (including proto3's default use of packed) without + // introducing the baggage of a separate option. + + private mutating func _visitPacked( + value: [T], fieldNumber: Int, + encode: (T, inout TextFormatEncoder) -> () + ) throws { + assert(!value.isEmpty) + emitFieldName(lookingUp: fieldNumber) + encoder.startRegularField() + var firstItem = true + encoder.startArray() + for v in value { + if !firstItem { + encoder.arraySeparator() + } + encode(v, &encoder) + firstItem = false + } + encoder.endArray() + encoder.endRegularField() + } + + mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: Float, encoder: inout TextFormatEncoder) in + encoder.putFloatValue(value: v) + } + } + + mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: Double, encoder: inout TextFormatEncoder) in + encoder.putDoubleValue(value: v) + } + } + + mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: Int32, encoder: inout TextFormatEncoder) in + encoder.putInt64(value: Int64(v)) + } + } + + mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: Int64, encoder: inout TextFormatEncoder) in + encoder.putInt64(value: v) + } + } + + mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: UInt32, encoder: inout TextFormatEncoder) in + encoder.putUInt64(value: UInt64(v)) + } + } + + mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: UInt64, encoder: inout TextFormatEncoder) in + encoder.putUInt64(value: v) + } + } + + mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws { + try visitPackedInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws { + try visitPackedInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + try visitPackedUInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + try visitPackedUInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + try visitPackedInt32Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + try visitPackedInt64Field(value: value, fieldNumber: fieldNumber) + } + + mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: Bool, encoder: inout TextFormatEncoder) in + encoder.putBoolValue(value: v) + } + } + + mutating func visitPackedEnumField(value: [E], fieldNumber: Int) throws { + try _visitPacked(value: value, fieldNumber: fieldNumber) { + (v: E, encoder: inout TextFormatEncoder) in + encoder.putEnumValue(value: v) + } + } + + /// Helper to encapsulate the common structure of iterating over a map + /// and encoding the keys and values. + private mutating func _visitMap( + map: Dictionary, + fieldNumber: Int, + isOrderedBefore: (K, K) -> Bool, + coder: (inout TextFormatEncodingVisitor, K, V) throws -> () + ) throws { + for (k,v) in map.sorted(by: { isOrderedBefore( $0.0, $1.0) }) { + emitFieldName(lookingUp: fieldNumber) + encoder.startMessageField() + var visitor = TextFormatEncodingVisitor(nameMap: nil, nameResolver: mapNameResolver, extensions: nil, encoder: encoder, options: options) + try coder(&visitor, k, v) + encoder = visitor.encoder + encoder.endMessageField() + } + } + + mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int + ) throws { + try _visitMap(map: value, fieldNumber: fieldNumber, isOrderedBefore: KeyType._lessThan) { + (visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in + try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor) + try ValueType.visitSingular(value: value, fieldNumber: 2, with: &visitor) + } + } + + mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int + ) throws where ValueType.RawValue == Int { + try _visitMap(map: value, fieldNumber: fieldNumber, isOrderedBefore: KeyType._lessThan) { + (visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in + try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor) + try visitor.visitSingularEnumField(value: value, fieldNumber: 2) + } + } + + mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int + ) throws { + try _visitMap(map: value, fieldNumber: fieldNumber, isOrderedBefore: KeyType._lessThan) { + (visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in + try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor) + try visitor.visitSingularMessageField(value: value, fieldNumber: 2) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatScanner.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatScanner.swift new file mode 100644 index 00000000..e2bbbf6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TextFormatScanner.swift @@ -0,0 +1,1248 @@ +// Sources/SwiftProtobuf/TextFormatScanner.swift - Text format decoding +// +// Copyright (c) 2014 - 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Test format decoding engine. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +private let asciiBell = UInt8(7) +private let asciiBackspace = UInt8(8) +private let asciiTab = UInt8(9) +private let asciiNewLine = UInt8(10) +private let asciiVerticalTab = UInt8(11) +private let asciiFormFeed = UInt8(12) +private let asciiCarriageReturn = UInt8(13) +private let asciiZero = UInt8(ascii: "0") +private let asciiOne = UInt8(ascii: "1") +private let asciiThree = UInt8(ascii: "3") +private let asciiSeven = UInt8(ascii: "7") +private let asciiNine = UInt8(ascii: "9") +private let asciiColon = UInt8(ascii: ":") +private let asciiPeriod = UInt8(ascii: ".") +private let asciiPlus = UInt8(ascii: "+") +private let asciiComma = UInt8(ascii: ",") +private let asciiSemicolon = UInt8(ascii: ";") +private let asciiDoubleQuote = UInt8(ascii: "\"") +private let asciiSingleQuote = UInt8(ascii: "\'") +private let asciiBackslash = UInt8(ascii: "\\") +private let asciiForwardSlash = UInt8(ascii: "/") +private let asciiHash = UInt8(ascii: "#") +private let asciiUnderscore = UInt8(ascii: "_") +private let asciiQuestionMark = UInt8(ascii: "?") +private let asciiSpace = UInt8(ascii: " ") +private let asciiOpenSquareBracket = UInt8(ascii: "[") +private let asciiCloseSquareBracket = UInt8(ascii: "]") +private let asciiOpenCurlyBracket = UInt8(ascii: "{") +private let asciiCloseCurlyBracket = UInt8(ascii: "}") +private let asciiOpenAngleBracket = UInt8(ascii: "<") +private let asciiCloseAngleBracket = UInt8(ascii: ">") +private let asciiMinus = UInt8(ascii: "-") +private let asciiLowerA = UInt8(ascii: "a") +private let asciiUpperA = UInt8(ascii: "A") +private let asciiLowerB = UInt8(ascii: "b") +private let asciiLowerE = UInt8(ascii: "e") +private let asciiUpperE = UInt8(ascii: "E") +private let asciiLowerF = UInt8(ascii: "f") +private let asciiUpperF = UInt8(ascii: "F") +private let asciiLowerI = UInt8(ascii: "i") +private let asciiLowerL = UInt8(ascii: "l") +private let asciiLowerN = UInt8(ascii: "n") +private let asciiLowerR = UInt8(ascii: "r") +private let asciiLowerS = UInt8(ascii: "s") +private let asciiLowerT = UInt8(ascii: "t") +private let asciiUpperT = UInt8(ascii: "T") +private let asciiLowerU = UInt8(ascii: "u") +private let asciiUpperU = UInt8(ascii: "U") +private let asciiLowerV = UInt8(ascii: "v") +private let asciiLowerX = UInt8(ascii: "x") +private let asciiLowerY = UInt8(ascii: "y") +private let asciiLowerZ = UInt8(ascii: "z") +private let asciiUpperZ = UInt8(ascii: "Z") + +private func fromHexDigit(_ c: UInt8) -> UInt8? { + if c >= asciiZero && c <= asciiNine { + return c - asciiZero + } + if c >= asciiUpperA && c <= asciiUpperF { + return c - asciiUpperA + UInt8(10) + } + if c >= asciiLowerA && c <= asciiLowerF { + return c - asciiLowerA + UInt8(10) + } + return nil +} + +private func uint32FromHexDigit(_ c: UInt8) -> UInt32? { + guard let u8 = fromHexDigit(c) else { + return nil + } + return UInt32(u8) +} + +// Protobuf Text encoding assumes that you're working directly +// in UTF-8. So this implementation converts the string to UTF8, +// then decodes it into a sequence of bytes, then converts +// it back into a string. +private func decodeString(_ s: String) -> String? { + + // Helper to read 4 hex digits as a UInt32 + func read4HexDigits(_ i: inout String.UTF8View.Iterator) -> UInt32? { + if let digit1 = i.next(), + let d1 = uint32FromHexDigit(digit1), + let digit2 = i.next(), + let d2 = uint32FromHexDigit(digit2), + let digit3 = i.next(), + let d3 = uint32FromHexDigit(digit3), + let digit4 = i.next(), + let d4 = uint32FromHexDigit(digit4) { + return (d1 << 12) + (d2 << 8) + (d3 << 4) + d4 + } + return nil + } + + var out = [UInt8]() + var bytes = s.utf8.makeIterator() + while let byte = bytes.next() { + switch byte { + case asciiBackslash: // backslash + if let escaped = bytes.next() { + switch escaped { + case asciiZero...asciiSeven: // 0...7 + // C standard allows 1, 2, or 3 octal digits. + let savedPosition = bytes + let digit1 = escaped + let digit1Value = digit1 - asciiZero + if let digit2 = bytes.next(), + digit2 >= asciiZero && digit2 <= asciiSeven { + let digit2Value = digit2 - asciiZero + let innerSavedPosition = bytes + if let digit3 = bytes.next(), + digit3 >= asciiZero && digit3 <= asciiSeven { + let digit3Value = digit3 - asciiZero + // The max octal digit is actually \377, but looking at the C++ + // protobuf code in strutil.cc:UnescapeCEscapeSequences(), it + // decodes with rollover, so just duplicate that behavior for + // consistency between languages. + let n = digit1Value &* 64 &+ digit2Value &* 8 &+ digit3Value + out.append(n) + } else { + let n = digit1Value * 8 + digit2Value + out.append(n) + bytes = innerSavedPosition + } + } else { + let n = digit1Value + out.append(n) + bytes = savedPosition + } + case asciiLowerU, asciiUpperU: // "u" + // \u - 4 hex digits, \U 8 hex digits: + guard let first = read4HexDigits(&bytes) else { return nil } + var codePoint = first + if escaped == asciiUpperU { + guard let second = read4HexDigits(&bytes) else { return nil } + codePoint = (codePoint << 16) + second + } + switch codePoint { + case 0...0x7f: + // 1 byte encoding + out.append(UInt8(truncatingIfNeeded: codePoint)) + case 0x80...0x7ff: + // 2 byte encoding + out.append(0xC0 + UInt8(truncatingIfNeeded: codePoint >> 6)) + out.append(0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F)) + case 0x800...0xffff: + // 3 byte encoding + out.append(0xE0 + UInt8(truncatingIfNeeded: codePoint >> 12)) + out.append(0x80 + UInt8(truncatingIfNeeded: (codePoint >> 6) & 0x3F)) + out.append(0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F)) + case 0x10000...0x10FFFF: + // 4 byte encoding + out.append(0xF0 + UInt8(truncatingIfNeeded: codePoint >> 18)) + out.append(0x80 + UInt8(truncatingIfNeeded: (codePoint >> 12) & 0x3F)) + out.append(0x80 + UInt8(truncatingIfNeeded: (codePoint >> 6) & 0x3F)) + out.append(0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F)) + default: + return nil + } + case asciiLowerX: // "x" + // Unlike C/C++, protobuf only allows 1 or 2 digits here: + if let byte = bytes.next(), let digit = fromHexDigit(byte) { + var n = digit + let savedPosition = bytes + if let byte = bytes.next(), let digit = fromHexDigit(byte) { + n = n &* 16 + digit + } else { + // No second digit; reset the iterator + bytes = savedPosition + } + out.append(n) + } else { + return nil // Hex escape must have at least 1 digit + } + case asciiLowerA: // \a + out.append(asciiBell) + case asciiLowerB: // \b + out.append(asciiBackspace) + case asciiLowerF: // \f + out.append(asciiFormFeed) + case asciiLowerN: // \n + out.append(asciiNewLine) + case asciiLowerR: // \r + out.append(asciiCarriageReturn) + case asciiLowerT: // \t + out.append(asciiTab) + case asciiLowerV: // \v + out.append(asciiVerticalTab) + case asciiDoubleQuote, + asciiSingleQuote, + asciiQuestionMark, + asciiBackslash: // " ' ? \ + out.append(escaped) + default: + return nil // Unrecognized escape + } + } else { + return nil // Input ends with backslash + } + default: + out.append(byte) + } + } + // There has got to be an easier way to convert a [UInt8] into a String. + return out.withUnsafeBufferPointer { ptr in + if let addr = ptr.baseAddress { + return utf8ToString(bytes: addr, count: ptr.count) + } else { + return String() + } + } +} + +/// +/// TextFormatScanner has no public members. +/// +internal struct TextFormatScanner { + internal var extensions: ExtensionMap? + private var p: UnsafeRawPointer + private var end: UnsafeRawPointer + private var doubleParser = DoubleParser() + + private let options: TextFormatDecodingOptions + internal var recursionBudget: Int + + internal var complete: Bool { + mutating get { + return p == end + } + } + + internal init( + utf8Pointer: UnsafeRawPointer, + count: Int, + options: TextFormatDecodingOptions, + extensions: ExtensionMap? = nil + ) { + p = utf8Pointer + end = p + count + self.extensions = extensions + self.options = options + // Since the root message doesn't start with a `skipObjectStart`, the + // budget starts with one less depth to cover that top message. + recursionBudget = options.messageDepthLimit - 1 + skipWhitespace() + } + + private mutating func incrementRecursionDepth() throws { + recursionBudget -= 1 + if recursionBudget < 0 { + throw TextFormatDecodingError.messageDepthLimit + } + } + + private mutating func decrementRecursionDepth() { + recursionBudget += 1 + // This should never happen, if it does, something is probably + // corrupting memory, and simply throwing doesn't make much sense. + if recursionBudget > options.messageDepthLimit { + fatalError("Somehow TextFormatDecoding unwound more objects than it started") + } + } + + /// Skip whitespace + private mutating func skipWhitespace() { + while p != end { + let u = p[0] + switch u { + case asciiSpace, + asciiTab, + asciiNewLine, + asciiCarriageReturn: // space, tab, NL, CR + p += 1 + case asciiHash: // # comment + p += 1 + while p != end { + // Skip until end of line + let c = p[0] + p += 1 + if c == asciiNewLine || c == asciiCarriageReturn { + break + } + } + default: + return + } + } + } + + /// Return a buffer containing the raw UTF8 for an identifier. + /// Assumes that you already know the current byte is a valid + /// start of identifier. + private mutating func parseUTF8Identifier() -> UnsafeRawBufferPointer { + let start = p + loop: while p != end { + let c = p[0] + switch c { + case asciiLowerA...asciiLowerZ, + asciiUpperA...asciiUpperZ, + asciiZero...asciiNine, + asciiUnderscore: + p += 1 + default: + break loop + } + } + let s = UnsafeRawBufferPointer(start: start, count: p - start) + skipWhitespace() + return s + } + + /// Return a String containing the next identifier. + private mutating func parseIdentifier() -> String { + let buff = parseUTF8Identifier() + let s = utf8ToString(bytes: buff.baseAddress!, count: buff.count) + // Force-unwrap is OK: we never have invalid UTF8 at this point. + return s! + } + + /// Parse the rest of an [extension_field_name] in the input, assuming the + /// initial "[" character has already been read (and is in the prefix) + /// This is also used for AnyURL, so we include "/", "." + private mutating func parseExtensionKey() -> String? { + let start = p + if p == end { + return nil + } + let c = p[0] + switch c { + case asciiLowerA...asciiLowerZ, asciiUpperA...asciiUpperZ: + p += 1 + default: + return nil + } + while p != end { + let c = p[0] + switch c { + case asciiLowerA...asciiLowerZ, + asciiUpperA...asciiUpperZ, + asciiZero...asciiNine, + asciiUnderscore, + asciiPeriod, + asciiForwardSlash: + p += 1 + case asciiCloseSquareBracket: // ] + return utf8ToString(bytes: start, count: p - start) + default: + return nil + } + } + return nil + } + + /// Scan a string that encodes a byte field, return a count of + /// the number of bytes that should be decoded from it + private mutating func validateAndCountBytesFromString(terminator: UInt8, sawBackslash: inout Bool) throws -> Int { + var count = 0 + let start = p + sawBackslash = false + while p != end { + let byte = p[0] + p += 1 + if byte == terminator { + p = start + return count + } + switch byte { + case asciiNewLine, asciiCarriageReturn: + // Can't have a newline in the middle of a bytes string. + throw TextFormatDecodingError.malformedText + case asciiBackslash: // "\\" + sawBackslash = true + if p != end { + let escaped = p[0] + p += 1 + switch escaped { + case asciiZero...asciiSeven: // '0'...'7' + // C standard allows 1, 2, or 3 octal digits. + if p != end, p[0] >= asciiZero, p[0] <= asciiSeven { + p += 1 + if p != end, p[0] >= asciiZero, p[0] <= asciiSeven { + if escaped > asciiThree { + // Out of range octal: three digits and first digit is greater than 3 + throw TextFormatDecodingError.malformedText + } + p += 1 + } + } + count += 1 + case asciiLowerU, asciiUpperU: // 'u' or 'U' unicode escape + let numDigits = (escaped == asciiLowerU) ? 4 : 8 + guard (end - p) >= numDigits else { + throw TextFormatDecodingError.malformedText // unicode escape must 4/8 digits + } + var codePoint: UInt32 = 0 + for i in 0.. 0 { + while p[0] != terminator { + let byte = p[0] + p += 1 + switch byte { + case asciiBackslash: // "\\" + let escaped = p[0] + p += 1 + switch escaped { + case asciiZero...asciiSeven: // '0'...'7' + // C standard allows 1, 2, or 3 octal digits. + let digit1Value = escaped - asciiZero + let digit2 = p[0] + if digit2 >= asciiZero, digit2 <= asciiSeven { + p += 1 + let digit2Value = digit2 - asciiZero + let digit3 = p[0] + if digit3 >= asciiZero, digit3 <= asciiSeven { + p += 1 + let digit3Value = digit3 - asciiZero + out[0] = digit1Value &* 64 + digit2Value * 8 + digit3Value + out += 1 + } else { + out[0] = digit1Value * 8 + digit2Value + out += 1 + } + } else { + out[0] = digit1Value + out += 1 + } + case asciiLowerU, asciiUpperU: + let numDigits = (escaped == asciiLowerU) ? 4 : 8 + var codePoint: UInt32 = 0 + for i in 0..> 6) + out[1] = 0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F) + out += 2 + case 0x800...0xffff: + // 3 byte encoding + out[0] = 0xE0 + UInt8(truncatingIfNeeded: codePoint >> 12) + out[1] = 0x80 + UInt8(truncatingIfNeeded: (codePoint >> 6) & 0x3F) + out[2] = 0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F) + out += 3 + case 0x10000...0x10FFFF: + // 4 byte encoding + out[0] = 0xF0 + UInt8(truncatingIfNeeded: codePoint >> 18) + out[1] = 0x80 + UInt8(truncatingIfNeeded: (codePoint >> 12) & 0x3F) + out[2] = 0x80 + UInt8(truncatingIfNeeded: (codePoint >> 6) & 0x3F) + out[3] = 0x80 + UInt8(truncatingIfNeeded: codePoint & 0x3F) + out += 4 + default: + preconditionFailure() // Already validated, can't happen + } + case asciiLowerX: // 'x' hexadecimal escape + // We already validated, so we know there's at least one digit: + var n = fromHexDigit(p[0])! + p += 1 + if let digit = fromHexDigit(p[0]) { + n = n &* 16 &+ digit + p += 1 + } + out[0] = n + out += 1 + case asciiLowerA: // \a ("alert") + out[0] = asciiBell + out += 1 + case asciiLowerB: // \b + out[0] = asciiBackspace + out += 1 + case asciiLowerF: // \f + out[0] = asciiFormFeed + out += 1 + case asciiLowerN: // \n + out[0] = asciiNewLine + out += 1 + case asciiLowerR: // \r + out[0] = asciiCarriageReturn + out += 1 + case asciiLowerT: // \t + out[0] = asciiTab + out += 1 + case asciiLowerV: // \v + out[0] = asciiVerticalTab + out += 1 + default: + out[0] = escaped + out += 1 + } + default: + out[0] = byte + out += 1 + } + } + p += 1 // Consume terminator + } + } + } + + /// Assumes the leading quote has already been consumed + private mutating func parseStringSegment(terminator: UInt8) -> String? { + let start = p + var sawBackslash = false + while p != end { + let c = p[0] + if c == terminator { + let s = utf8ToString(bytes: start, count: p - start) + p += 1 + skipWhitespace() + if let s = s, sawBackslash { + return decodeString(s) + } else { + return s + } + } + p += 1 + if c == asciiBackslash { // \ + if p == end { + return nil + } + sawBackslash = true + p += 1 + } + if c == asciiNewLine || c == asciiCarriageReturn { + // Can't have a newline in the middle of a raw string. + return nil + } + } + return nil // Unterminated quoted string + } + + internal mutating func nextUInt() throws -> UInt64 { + if p == end { + throw TextFormatDecodingError.malformedNumber + } + let c = p[0] + p += 1 + if c == asciiZero { // leading '0' precedes octal or hex + if p == end { + // The TextFormat ended with a field value of zero. + return 0 + } + if p[0] == asciiLowerX { // 'x' => hex + p += 1 + var n: UInt64 = 0 + while p != end { + let digit = p[0] + let val: UInt64 + switch digit { + case asciiZero...asciiNine: // 0...9 + val = UInt64(digit - asciiZero) + case asciiLowerA...asciiLowerF: // a...f + val = UInt64(digit - asciiLowerA + 10) + case asciiUpperA...asciiUpperF: + val = UInt64(digit - asciiUpperA + 10) + case asciiLowerU: // trailing 'u' + p += 1 + skipWhitespace() + return n + default: + skipWhitespace() + return n + } + if n > UInt64.max / 16 { + throw TextFormatDecodingError.malformedNumber + } + p += 1 + n = n * 16 + val + } + skipWhitespace() + return n + } else { // octal + var n: UInt64 = 0 + while p != end { + let digit = p[0] + if digit == asciiLowerU { // trailing 'u' + p += 1 + skipWhitespace() + return n + } + if digit < asciiZero || digit > asciiSeven { + skipWhitespace() + return n // not octal digit + } + let val = UInt64(digit - asciiZero) + if n > UInt64.max / 8 { + throw TextFormatDecodingError.malformedNumber + } + p += 1 + n = n * 8 + val + } + skipWhitespace() + return n + } + } else if c > asciiZero && c <= asciiNine { // 1...9 + var n = UInt64(c - asciiZero) + while p != end { + let digit = p[0] + if digit == asciiLowerU { // trailing 'u' + p += 1 + skipWhitespace() + return n + } + if digit < asciiZero || digit > asciiNine { + skipWhitespace() + return n // not a digit + } + let val = UInt64(digit - asciiZero) + if n > UInt64.max / 10 || n * 10 > UInt64.max - val { + throw TextFormatDecodingError.malformedNumber + } + p += 1 + n = n * 10 + val + } + skipWhitespace() + return n + } + throw TextFormatDecodingError.malformedNumber + } + + internal mutating func nextSInt() throws -> Int64 { + if p == end { + throw TextFormatDecodingError.malformedNumber + } + let c = p[0] + if c == asciiMinus { // - + p += 1 + if p == end { + throw TextFormatDecodingError.malformedNumber + } + // character after '-' must be digit + let digit = p[0] + if digit < asciiZero || digit > asciiNine { + throw TextFormatDecodingError.malformedNumber + } + let n = try nextUInt() + let limit: UInt64 = 0x8000000000000000 // -Int64.min + if n >= limit { + if n > limit { + // Too large negative number + throw TextFormatDecodingError.malformedNumber + } else { + return Int64.min // Special case for Int64.min + } + } + return -Int64(bitPattern: n) + } else { + let n = try nextUInt() + if n > UInt64(bitPattern: Int64.max) { + throw TextFormatDecodingError.malformedNumber + } + return Int64(bitPattern: n) + } + } + + internal mutating func nextStringValue() throws -> String { + var result: String + skipWhitespace() + if p == end { + throw TextFormatDecodingError.malformedText + } + let c = p[0] + if c != asciiSingleQuote && c != asciiDoubleQuote { + throw TextFormatDecodingError.malformedText + } + p += 1 + if let s = parseStringSegment(terminator: c) { + result = s + } else { + throw TextFormatDecodingError.malformedText + } + + while true { + if p == end { + return result + } + let c = p[0] + if c != asciiSingleQuote && c != asciiDoubleQuote { + return result + } + p += 1 + if let s = parseStringSegment(terminator: c) { + result.append(s) + } else { + throw TextFormatDecodingError.malformedText + } + } + } + + /// Protobuf Text Format allows a single bytes field to + /// contain multiple quoted strings. The values + /// are separately decoded and then concatenated: + /// field1: "bytes" 'more bytes' + /// "and even more bytes" + internal mutating func nextBytesValue() throws -> Data { + // Get the first string's contents + var result: Data + skipWhitespace() + if p == end { + throw TextFormatDecodingError.malformedText + } + let c = p[0] + if c != asciiSingleQuote && c != asciiDoubleQuote { + throw TextFormatDecodingError.malformedText + } + p += 1 + var sawBackslash = false + let n = try validateAndCountBytesFromString(terminator: c, sawBackslash: &sawBackslash) + if sawBackslash { + result = Data(count: n) + parseBytesFromString(terminator: c, into: &result) + } else { + result = Data(bytes: p, count: n) + p += n + 1 // Skip string body + close quote + } + + // If there are more strings, decode them + // and append to the result: + while true { + skipWhitespace() + if p == end { + return result + } + let c = p[0] + if c != asciiSingleQuote && c != asciiDoubleQuote { + return result + } + p += 1 + var sawBackslash = false + let n = try validateAndCountBytesFromString(terminator: c, sawBackslash: &sawBackslash) + if sawBackslash { + var b = Data(count: n) + parseBytesFromString(terminator: c, into: &b) + result.append(b) + } else { + result.append(Data(bytes: p, count: n)) + p += n + 1 // Skip string body + close quote + } + } + } + + // Tries to identify a sequence of UTF8 characters + // that represent a numeric floating-point value. + private mutating func tryParseFloatString() -> Double? { + guard p != end else {return nil} + let start = p + var c = p[0] + if c == asciiMinus { + p += 1 + guard p != end else {p = start; return nil} + c = p[0] + } + switch c { + case asciiZero: // '0' as first character is not allowed followed by digit + p += 1 + guard p != end else {break} + c = p[0] + if c >= asciiZero && c <= asciiNine { + p = start + return nil + } + case asciiPeriod: // '.' as first char only if followed by digit + p += 1 + guard p != end else {p = start; return nil} + c = p[0] + if c < asciiZero || c > asciiNine { + p = start + return nil + } + case asciiOne...asciiNine: + break + default: + p = start + return nil + } + loop: while p != end { + let c = p[0] + switch c { + case asciiZero...asciiNine, + asciiPeriod, + asciiPlus, + asciiMinus, + asciiLowerE, + asciiUpperE: // 0...9, ., +, -, e, E + p += 1 + case asciiLowerF: // f + // proto1 allowed floats to be suffixed with 'f' + let d = doubleParser.utf8ToDouble(bytes: UnsafeRawBufferPointer(start: start, count: p - start)) + // Just skip the 'f' + p += 1 + skipWhitespace() + return d + default: + break loop + } + } + let d = doubleParser.utf8ToDouble(bytes: UnsafeRawBufferPointer(start: start, count: p - start)) + skipWhitespace() + return d + } + + // Skip specified characters if they all match + private mutating func skipOptionalCharacters(bytes: [UInt8]) { + let start = p + for b in bytes { + if p == end || p[0] != b { + p = start + return + } + p += 1 + } + } + + // Skip following keyword if it matches (case-insensitively) + // the given keyword (specified as a series of bytes). + private mutating func skipOptionalKeyword(bytes: [UInt8]) -> Bool { + let start = p + for b in bytes { + if p == end { + p = start + return false + } + var c = p[0] + if c >= asciiUpperA && c <= asciiUpperZ { + // Convert to lower case + // (Protobuf text keywords are case insensitive) + c += asciiLowerA - asciiUpperA + } + if c != b { + p = start + return false + } + p += 1 + } + if p == end { + return true + } + let c = p[0] + if ((c >= asciiUpperA && c <= asciiUpperZ) + || (c >= asciiLowerA && c <= asciiLowerZ)) { + p = start + return false + } + skipWhitespace() + return true + } + + // If the next token is the identifier "nan", return true. + private mutating func skipOptionalNaN() -> Bool { + return skipOptionalKeyword(bytes: + [asciiLowerN, asciiLowerA, asciiLowerN]) + } + + // If the next token is a recognized spelling of "infinity", + // return Float.infinity or -Float.infinity + private mutating func skipOptionalInfinity() -> Float? { + if p == end { + return nil + } + let c = p[0] + let negated: Bool + if c == asciiMinus { + negated = true + p += 1 + } else { + negated = false + } + let inf = [asciiLowerI, asciiLowerN, asciiLowerF] + let infinity = [asciiLowerI, asciiLowerN, asciiLowerF, asciiLowerI, + asciiLowerN, asciiLowerI, asciiLowerT, asciiLowerY] + if (skipOptionalKeyword(bytes: inf) + || skipOptionalKeyword(bytes: infinity)) { + return negated ? -Float.infinity : Float.infinity + } + return nil + } + + internal mutating func nextFloat() throws -> Float { + if let d = tryParseFloatString() { + return Float(d) + } + if skipOptionalNaN() { + return Float.nan + } + if let inf = skipOptionalInfinity() { + return inf + } + throw TextFormatDecodingError.malformedNumber + } + + internal mutating func nextDouble() throws -> Double { + if let d = tryParseFloatString() { + return d + } + if skipOptionalNaN() { + return Double.nan + } + if let inf = skipOptionalInfinity() { + return Double(inf) + } + throw TextFormatDecodingError.malformedNumber + } + + internal mutating func nextBool() throws -> Bool { + skipWhitespace() + if p == end { + throw TextFormatDecodingError.malformedText + } + let c = p[0] + p += 1 + let result: Bool + switch c { + case asciiZero: + result = false + case asciiOne: + result = true + case asciiLowerF, asciiUpperF: + if p != end { + let alse = [asciiLowerA, asciiLowerL, asciiLowerS, asciiLowerE] + skipOptionalCharacters(bytes: alse) + } + result = false + case asciiLowerT, asciiUpperT: + if p != end { + let rue = [asciiLowerR, asciiLowerU, asciiLowerE] + skipOptionalCharacters(bytes: rue) + } + result = true + default: + throw TextFormatDecodingError.malformedText + } + if p == end { + return result + } + switch p[0] { + case asciiSpace, + asciiTab, + asciiNewLine, + asciiCarriageReturn, + asciiHash, + asciiComma, + asciiSemicolon, + asciiCloseSquareBracket, + asciiCloseCurlyBracket, + asciiCloseAngleBracket: + skipWhitespace() + return result + default: + throw TextFormatDecodingError.malformedText + } + } + + internal mutating func nextOptionalEnumName() throws -> UnsafeRawBufferPointer? { + skipWhitespace() + if p == end { + throw TextFormatDecodingError.malformedText + } + switch p[0] { + case asciiLowerA...asciiLowerZ, asciiUpperA...asciiUpperZ: + return parseUTF8Identifier() + default: + return nil + } + } + + /// Any URLs are syntactically (almost) identical to extension + /// keys, so we share the code for those. + internal mutating func nextOptionalAnyURL() throws -> String? { + return try nextOptionalExtensionKey() + } + + /// Returns next extension key or nil if end-of-input or + /// if next token is not an extension key. + /// + /// Throws an error if the next token starts with '[' but + /// cannot be parsed as an extension key. + /// + /// Note: This accepts / characters to support Any URL parsing. + /// Technically, Any URLs can contain / characters and extension + /// key names cannot. But in practice, accepting / chracters for + /// extension keys works fine, since the result just gets rejected + /// when the key is looked up. + internal mutating func nextOptionalExtensionKey() throws -> String? { + skipWhitespace() + if p == end { + return nil + } + if p[0] == asciiOpenSquareBracket { // [ + p += 1 + if let s = parseExtensionKey() { + if p == end || p[0] != asciiCloseSquareBracket { + throw TextFormatDecodingError.malformedText + } + // Skip ] + p += 1 + skipWhitespace() + return s + } else { + throw TextFormatDecodingError.malformedText + } + } + return nil + } + + /// Returns text of next regular key or nil if end-of-input. + /// This considers an extension key [keyname] to be an + /// error, so call nextOptionalExtensionKey first if you + /// want to handle extension keys. + /// + /// This is only used by map parsing; we should be able to + /// rework that to use nextFieldNumber instead. + internal mutating func nextKey() throws -> String? { + skipWhitespace() + if p == end { + return nil + } + let c = p[0] + switch c { + case asciiOpenSquareBracket: // [ + throw TextFormatDecodingError.malformedText + case asciiLowerA...asciiLowerZ, + asciiUpperA...asciiUpperZ, + asciiOne...asciiNine: // a...z, A...Z, 1...9 + return parseIdentifier() + default: + throw TextFormatDecodingError.malformedText + } + } + + /// Parse a field name, look it up, and return the corresponding + /// field number. + /// + /// returns nil at end-of-input + /// + /// Throws if field name cannot be parsed or if field name is + /// unknown. + /// + /// This function accounts for as much as 2/3 of the total run + /// time of the entire parse. + internal mutating func nextFieldNumber(names: _NameMap) throws -> Int? { + if p == end { + return nil + } + let c = p[0] + switch c { + case asciiLowerA...asciiLowerZ, + asciiUpperA...asciiUpperZ: // a...z, A...Z + let key = parseUTF8Identifier() + if let fieldNumber = names.number(forProtoName: key) { + return fieldNumber + } else { + throw TextFormatDecodingError.unknownField + } + case asciiOne...asciiNine: // 1-9 (field numbers are 123, not 0123) + var fieldNum = Int(c) - Int(asciiZero) + p += 1 + while p != end { + let c = p[0] + if c >= asciiZero && c <= asciiNine { + fieldNum = fieldNum &* 10 &+ (Int(c) - Int(asciiZero)) + } else { + break + } + p += 1 + } + skipWhitespace() + if names.names(for: fieldNum) != nil { + return fieldNum + } else { + // It was a number that isn't a known field. + // The C++ version (TextFormat::Parser::ParserImpl::ConsumeField()), + // supports an option to file or skip the field's value (this is true + // of unknown names or numbers). + throw TextFormatDecodingError.unknownField + } + default: + break + } + throw TextFormatDecodingError.malformedText + } + + private mutating func skipRequiredCharacter(_ c: UInt8) throws { + skipWhitespace() + if p != end && p[0] == c { + p += 1 + skipWhitespace() + } else { + throw TextFormatDecodingError.malformedText + } + } + + internal mutating func skipRequiredComma() throws { + try skipRequiredCharacter(asciiComma) + } + + internal mutating func skipRequiredColon() throws { + try skipRequiredCharacter(asciiColon) + } + + private mutating func skipOptionalCharacter(_ c: UInt8) -> Bool { + if p != end && p[0] == c { + p += 1 + skipWhitespace() + return true + } + return false + } + + internal mutating func skipOptionalColon() -> Bool { + return skipOptionalCharacter(asciiColon) + } + + internal mutating func skipOptionalEndArray() -> Bool { + return skipOptionalCharacter(asciiCloseSquareBracket) + } + + internal mutating func skipOptionalBeginArray() -> Bool { + return skipOptionalCharacter(asciiOpenSquareBracket) + } + + internal mutating func skipOptionalObjectEnd(_ c: UInt8) -> Bool { + let result = skipOptionalCharacter(c) + if result { + decrementRecursionDepth() + } + return result + } + + internal mutating func skipOptionalSeparator() { + if p != end { + let c = p[0] + if c == asciiComma || c == asciiSemicolon { // comma or semicolon + p += 1 + skipWhitespace() + } + } + } + + /// Returns the character that should end this field. + /// E.g., if object starts with "{", returns "}" + internal mutating func skipObjectStart() throws -> UInt8 { + try incrementRecursionDepth() + if p != end { + let c = p[0] + p += 1 + skipWhitespace() + switch c { + case asciiOpenCurlyBracket: // { + return asciiCloseCurlyBracket // } + case asciiOpenAngleBracket: // < + return asciiCloseAngleBracket // > + default: + break + } + } + throw TextFormatDecodingError.malformedText + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TimeUtils.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TimeUtils.swift new file mode 100644 index 00000000..a7d142b4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/TimeUtils.swift @@ -0,0 +1,65 @@ +// Sources/SwiftProtobuf/TimeUtils.swift - Generally useful time/calendar functions +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Generally useful time/calendar functions and constants +/// +// ----------------------------------------------------------------------------- + +let minutesPerDay: Int32 = 1440 +let minutesPerHour: Int32 = 60 +let secondsPerDay: Int32 = 86400 +let secondsPerHour: Int32 = 3600 +let secondsPerMinute: Int32 = 60 +let nanosPerSecond: Int32 = 1000000000 + +internal func timeOfDayFromSecondsSince1970(seconds: Int64) -> (hh: Int32, mm: Int32, ss: Int32) { + let secondsSinceMidnight = Int32(mod(seconds, Int64(secondsPerDay))) + let ss = mod(secondsSinceMidnight, secondsPerMinute) + let mm = mod(div(secondsSinceMidnight, secondsPerMinute), minutesPerHour) + let hh = Int32(div(secondsSinceMidnight, secondsPerHour)) + + return (hh: hh, mm: mm, ss: ss) +} + +internal func julianDayNumberFromSecondsSince1970(seconds: Int64) -> Int64 { + // January 1, 1970 is Julian Day Number 2440588. + // See http://aa.usno.navy.mil/faq/docs/JD_Formula.php + return div(seconds + 2440588 * Int64(secondsPerDay), Int64(secondsPerDay)) +} + +internal func gregorianDateFromSecondsSince1970(seconds: Int64) -> (YY: Int32, MM: Int32, DD: Int32) { + // The following implements Richards' algorithm (see the Wikipedia article + // for "Julian day"). + // If you touch this code, please test it exhaustively by playing with + // Test_Timestamp.testJSON_range. + + let JJ = julianDayNumberFromSecondsSince1970(seconds: seconds) + let f = JJ + 1401 + div(div(4 * JJ + 274277, 146097) * 3, 4) - 38 + let e = 4 * f + 3 + let g = Int64(div(mod(e, 1461), 4)) + let h = 5 * g + 2 + let DD = div(mod(h, 153), 5) + 1 + let MM = mod(div(h, 153) + 2, 12) + 1 + let YY = div(e, 1461) - 4716 + div(12 + 2 - MM, 12) + + return (YY: Int32(YY), MM: Int32(MM), DD: Int32(DD)) +} + +internal func nanosToString(nanos: Int32) -> String { + if nanos == 0 { + return "" + } else if nanos % 1000000 == 0 { + return ".\(threeDigit(abs(nanos) / 1000000))" + } else if nanos % 1000 == 0 { + return ".\(sixDigit(abs(nanos) / 1000))" + } else { + return ".\(nineDigit(abs(nanos)))" + } +} \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnknownStorage.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnknownStorage.swift new file mode 100644 index 00000000..7829733c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnknownStorage.swift @@ -0,0 +1,48 @@ +// Sources/SwiftProtobuf/UnknownStorage.swift - Handling unknown fields +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Proto2 binary coding requires storing and recoding of unknown fields. +/// This simple support class handles that requirement. A property of this type +/// is compiled into every proto2 message. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +// TODO: `UnknownStorage` should be `Sendable` but we cannot do so yet without possibly breaking compatibility. + +/// Contains any unknown fields in a decoded message; that is, fields that were +/// sent on the wire but were not recognized by the generated message +/// implementation or were valid field numbers but with mismatching wire +/// formats (for example, a field encoded as a varint when a fixed32 integer +/// was expected). +public struct UnknownStorage: Equatable { + /// The raw protocol buffer binary-encoded bytes that represent the unknown + /// fields of a decoded message. + public private(set) var data = Data() + +#if !swift(>=4.1) + public static func ==(lhs: UnknownStorage, rhs: UnknownStorage) -> Bool { + return lhs.data == rhs.data + } +#endif + + public init() {} + + internal mutating func append(protobufData: Data) { + data.append(protobufData) + } + + public func traverse(visitor: inout V) throws { + if !data.isEmpty { + try visitor.visitUnknown(bytes: data) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift new file mode 100644 index 00000000..64f3b818 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift @@ -0,0 +1,37 @@ +// Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift - Shims for UnsafeBufferPointer +// +// Copyright (c) 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Shims for UnsafeBufferPointer +/// +// ----------------------------------------------------------------------------- + + +extension UnsafeMutableBufferPointer { + #if !swift(>=4.2) + internal static func allocate(capacity: Int) -> UnsafeMutableBufferPointer { + let pointer = UnsafeMutablePointer.allocate(capacity: capacity) + return UnsafeMutableBufferPointer(start: pointer, count: capacity) + } + #endif + + #if !swift(>=4.1) + internal func deallocate() { + self.baseAddress?.deallocate(capacity: self.count) + } + #endif +} + +extension UnsafeMutableRawBufferPointer { + #if !swift(>=4.1) + internal func copyMemory(from source: C) where C.Element == UInt8 { + self.copyBytes(from: source) + } + #endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift new file mode 100644 index 00000000..9818bced --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift @@ -0,0 +1,45 @@ +// Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift - Shims for UnsafeRawPointer and friends +// +// Copyright (c) 2019 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Shims for UnsafeRawPointer and friends. +/// +// ----------------------------------------------------------------------------- + + +extension UnsafeRawPointer { + /// A shim subscript for UnsafeRawPointer aiming to maintain code consistency. + /// + /// We can remove this shim when we rewrite the code to use buffer pointers. + internal subscript(_ offset: Int) -> UInt8 { + get { + return self.load(fromByteOffset: offset, as: UInt8.self) + } + } +} + +extension UnsafeMutableRawPointer { + /// A shim subscript for UnsafeMutableRawPointer aiming to maintain code consistency. + /// + /// We can remove this shim when we rewrite the code to use buffer pointers. + internal subscript(_ offset: Int) -> UInt8 { + get { + return self.load(fromByteOffset: offset, as: UInt8.self) + } + set { + self.storeBytes(of: newValue, toByteOffset: offset, as: UInt8.self) + } + } + + #if !swift(>=4.1) + internal mutating func copyMemory(from source: UnsafeRawPointer, byteCount: Int) { + self.copyBytes(from: source, count: byteCount) + } + #endif +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Varint.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Varint.swift new file mode 100644 index 00000000..d928d938 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Varint.swift @@ -0,0 +1,108 @@ +// Sources/SwiftProtobuf/Varint.swift - Varint encoding/decoding helpers +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Helper functions to varint-encode and decode integers. +/// +// ----------------------------------------------------------------------------- + + +/// Contains helper methods to varint-encode and decode integers. +internal enum Varint { + + /// Computes the number of bytes that would be needed to store a 32-bit varint. + /// + /// - Parameter value: The number whose varint size should be calculated. + /// - Returns: The size, in bytes, of the 32-bit varint. + static func encodedSize(of value: UInt32) -> Int { + if (value & (~0 << 7)) == 0 { + return 1 + } + if (value & (~0 << 14)) == 0 { + return 2 + } + if (value & (~0 << 21)) == 0 { + return 3 + } + if (value & (~0 << 28)) == 0 { + return 4 + } + return 5 + } + + /// Computes the number of bytes that would be needed to store a signed 32-bit varint, if it were + /// treated as an unsigned integer with the same bit pattern. + /// + /// - Parameter value: The number whose varint size should be calculated. + /// - Returns: The size, in bytes, of the 32-bit varint. + static func encodedSize(of value: Int32) -> Int { + if value >= 0 { + return encodedSize(of: UInt32(bitPattern: value)) + } else { + // Must sign-extend. + return encodedSize(of: Int64(value)) + } + } + + /// Computes the number of bytes that would be needed to store a 64-bit varint. + /// + /// - Parameter value: The number whose varint size should be calculated. + /// - Returns: The size, in bytes, of the 64-bit varint. + static func encodedSize(of value: Int64) -> Int { + // Handle two common special cases up front. + if (value & (~0 << 7)) == 0 { + return 1 + } + if value < 0 { + return 10 + } + + // Divide and conquer the remaining eight cases. + var value = value + var n = 2 + + if (value & (~0 << 35)) != 0 { + n += 4 + value >>= 28 + } + if (value & (~0 << 21)) != 0 { + n += 2 + value >>= 14 + } + if (value & (~0 << 14)) != 0 { + n += 1 + } + return n + } + + /// Computes the number of bytes that would be needed to store an unsigned 64-bit varint, if it + /// were treated as a signed integer witht he same bit pattern. + /// + /// - Parameter value: The number whose varint size should be calculated. + /// - Returns: The size, in bytes, of the 64-bit varint. + static func encodedSize(of value: UInt64) -> Int { + return encodedSize(of: Int64(bitPattern: value)) + } + + /// Counts the number of distinct varints in a packed byte buffer. + static func countVarintsInBuffer(start: UnsafeRawPointer, count: Int) -> Int { + // We don't need to decode all the varints to count how many there + // are. Just observe that every varint has exactly one byte with + // value < 128. So we just count those... + var n = 0 + var ints = 0 + while n < count { + if start.load(fromByteOffset: n, as: UInt8.self) < 128 { + ints += 1 + } + n += 1 + } + return ints + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Version.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Version.swift new file mode 100644 index 00000000..7e8dcec8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Version.swift @@ -0,0 +1,28 @@ +// Sources/SwiftProtobuf/Version.swift - Runtime Version info +// +// Copyright (c) 2014 - 2017 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// A interface for exposing the version of the runtime. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +// Expose version information about the library. +public struct Version { + /// Major version. + public static let major = 1 + /// Minor version. + public static let minor = 20 + /// Revision number. + public static let revision = 3 + + /// String form of the version number. + public static let versionString = "\(major).\(minor).\(revision)" +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Visitor.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Visitor.swift new file mode 100644 index 00000000..b41c7c94 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/Visitor.swift @@ -0,0 +1,725 @@ +// Sources/SwiftProtobuf/Visitor.swift - Basic serialization machinery +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Protocol for traversing the object tree. +/// +/// This is used by: +/// = Protobuf serialization +/// = JSON serialization (with some twists to account for specialty JSON +/// encodings) +/// = Protobuf text serialization +/// = Hashable computation +/// +/// Conceptually, serializers create visitor objects that are +/// then passed recursively to every message and field via generated +/// 'traverse' methods. The details get a little involved due to +/// the need to allow particular messages to override particular +/// behaviors for specific encodings, but the general idea is quite simple. +/// +// ----------------------------------------------------------------------------- + +import Foundation + +/// This is the key interface used by the generated `traverse()` methods +/// used for serialization. It is implemented by each serialization protocol: +/// Protobuf Binary, Protobuf Text, JSON, and the Hash encoder. +public protocol Visitor { + + /// Called for each non-repeated float field + /// + /// A default implementation is provided that just widens the value + /// and calls `visitSingularDoubleField` + mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws + + /// Called for each non-repeated double field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws + + /// Called for each non-repeated int32 field + /// + /// A default implementation is provided that just widens the value + /// and calls `visitSingularInt64Field` + mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws + + /// Called for each non-repeated int64 field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws + + /// Called for each non-repeated uint32 field + /// + /// A default implementation is provided that just widens the value + /// and calls `visitSingularUInt64Field` + mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws + + /// Called for each non-repeated uint64 field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws + + /// Called for each non-repeated sint32 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularInt32Field` + mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws + + /// Called for each non-repeated sint64 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularInt64Field` + mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws + + /// Called for each non-repeated fixed32 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularUInt32Field` + mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws + + /// Called for each non-repeated fixed64 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularUInt64Field` + mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws + + /// Called for each non-repeated sfixed32 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularInt32Field` + mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws + + /// Called for each non-repeated sfixed64 field + /// + /// A default implementation is provided that just forwards to + /// `visitSingularInt64Field` + mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws + + /// Called for each non-repeated bool field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws + + /// Called for each non-repeated string field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularStringField(value: String, fieldNumber: Int) throws + + /// Called for each non-repeated bytes field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws + + /// Called for each non-repeated enum field + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularEnumField(value: E, fieldNumber: Int) throws + + /// Called for each non-repeated nested message field. + /// + /// There is no default implementation. This must be implemented. + mutating func visitSingularMessageField(value: M, fieldNumber: Int) throws + + /// Called for each non-repeated proto2 group field. + /// + /// A default implementation is provided that simply forwards to + /// `visitSingularMessageField`. Implementors who need to handle groups + /// differently than nested messages can override this and provide distinct + /// implementations. + mutating func visitSingularGroupField(value: G, fieldNumber: Int) throws + + // Called for each non-packed repeated float field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularFloatField` once for each item in the array. + mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws + + // Called for each non-packed repeated double field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularDoubleField` once for each item in the array. + mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws + + // Called for each non-packed repeated int32 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularInt32Field` once for each item in the array. + mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each non-packed repeated int64 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularInt64Field` once for each item in the array. + mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each non-packed repeated uint32 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularUInt32Field` once for each item in the array. + mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws + + // Called for each non-packed repeated uint64 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularUInt64Field` once for each item in the array. + mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws + + // Called for each non-packed repeated sint32 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularSInt32Field` once for each item in the array. + mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each non-packed repeated sint64 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularSInt64Field` once for each item in the array. + mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each non-packed repeated fixed32 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularFixed32Field` once for each item in the array. + mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws + + // Called for each non-packed repeated fixed64 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularFixed64Field` once for each item in the array. + mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws + + // Called for each non-packed repeated sfixed32 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularSFixed32Field` once for each item in the array. + mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each non-packed repeated sfixed64 field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularSFixed64Field` once for each item in the array. + mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each non-packed repeated bool field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularBoolField` once for each item in the array. + mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws + + // Called for each non-packed repeated string field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularStringField` once for each item in the array. + mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws + + // Called for each non-packed repeated bytes field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularBytesField` once for each item in the array. + mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws + + /// Called for each repeated, unpacked enum field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularEnumField` once for each item in the array. + mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws + + /// Called for each repeated nested message field. The method is called once + /// with the complete array of values for the field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularMessageField` once for each item in the array. + mutating func visitRepeatedMessageField(value: [M], + fieldNumber: Int) throws + + /// Called for each repeated proto2 group field. + /// + /// A default implementation is provided that simply calls + /// `visitSingularGroupField` once for each item in the array. + mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws + + // Called for each packed, repeated float field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws + + // Called for each packed, repeated double field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws + + // Called for each packed, repeated int32 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each packed, repeated int64 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each packed, repeated uint32 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws + + // Called for each packed, repeated uint64 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws + + // Called for each packed, repeated sint32 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each packed, repeated sint64 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each packed, repeated fixed32 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws + + // Called for each packed, repeated fixed64 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws + + // Called for each packed, repeated sfixed32 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws + + // Called for each packed, repeated sfixed64 field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws + + // Called for each packed, repeated bool field. + /// + /// This is called once with the complete array of values for + /// the field. + /// + /// There is a default implementation that forwards to the non-packed + /// function. + mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws + + /// Called for each repeated, packed enum field. + /// The method is called once with the complete array of values for + /// the field. + /// + /// A default implementation is provided that simply forwards to + /// `visitRepeatedEnumField`. Implementors who need to handle packed fields + /// differently than unpacked fields can override this and provide distinct + /// implementations. + mutating func visitPackedEnumField(value: [E], fieldNumber: Int) throws + + /// Called for each map field with primitive values. The method is + /// called once with the complete dictionary of keys/values for the + /// field. + /// + /// There is no default implementation. This must be implemented. + mutating func visitMapField( + fieldType: _ProtobufMap.Type, + value: _ProtobufMap.BaseType, + fieldNumber: Int) throws + + /// Called for each map field with enum values. The method is called + /// once with the complete dictionary of keys/values for the field. + /// + /// There is no default implementation. This must be implemented. + mutating func visitMapField( + fieldType: _ProtobufEnumMap.Type, + value: _ProtobufEnumMap.BaseType, + fieldNumber: Int) throws where ValueType.RawValue == Int + + /// Called for each map field with message values. The method is + /// called once with the complete dictionary of keys/values for the + /// field. + /// + /// There is no default implementation. This must be implemented. + mutating func visitMapField( + fieldType: _ProtobufMessageMap.Type, + value: _ProtobufMessageMap.BaseType, + fieldNumber: Int) throws + + /// Called for each extension range. + mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws + + /// Called for each extension range. + mutating func visitExtensionFieldsAsMessageSet( + fields: ExtensionFieldValueSet, + start: Int, + end: Int) throws + + /// Called with the raw bytes that represent any unknown fields. + mutating func visitUnknown(bytes: Data) throws +} + +/// Forwarding default implementations of some visitor methods, for convenience. +extension Visitor { + + // Default definitions of numeric serializations. + // + // The 32-bit versions widen and delegate to 64-bit versions. + // The specialized integer codings delegate to standard Int/UInt. + // + // These "just work" for Hash and Text formats. Most of these work + // for JSON (32-bit integers are overridden to suppress quoting), + // and a few even work for Protobuf Binary (thanks to varint coding + // which erases the size difference between 32-bit and 64-bit ints). + + public mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws { + try visitSingularDoubleField(value: Double(value), fieldNumber: fieldNumber) + } + public mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt64Field(value: Int64(value), fieldNumber: fieldNumber) + } + public mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: UInt64(value), fieldNumber: fieldNumber) + } + public mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt32Field(value: value, fieldNumber: fieldNumber) + } + public mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularInt64Field(value: value, fieldNumber: fieldNumber) + } + public mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws { + try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber) + } + public mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws { + try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber) + } + public mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws { + try visitSingularInt32Field(value: value, fieldNumber: fieldNumber) + } + public mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws { + try visitSingularInt64Field(value: value, fieldNumber: fieldNumber) + } + + // Default definitions of repeated serializations that just iterate and + // invoke the singular encoding. These "just work" for Protobuf Binary (encoder + // and size visitor), Protobuf Text, and Hash visitors. JSON format stores + // repeated values differently from singular, so overrides these. + + public mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularFloatField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularDoubleField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularInt32Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularInt64Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularUInt32Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularUInt64Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularSInt32Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularSInt64Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularFixed32Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularFixed64Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularSFixed32Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularSFixed64Field(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularBoolField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularStringField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularBytesField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularEnumField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedMessageField(value: [M], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularMessageField(value: v, fieldNumber: fieldNumber) + } + } + + public mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws { + assert(!value.isEmpty) + for v in value { + try visitSingularGroupField(value: v, fieldNumber: fieldNumber) + } + } + + // Default definitions of packed serialization just defer to the + // repeated implementation. This works for Hash and JSON visitors + // (which do not distinguish packed vs. non-packed) but are + // overridden by Protobuf Binary and Text. + + public mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedFloatField(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedDoubleField(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedInt32Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedInt64Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedUInt32Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedUInt64Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedInt32Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitPackedInt64Field(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedBoolField(value: value, fieldNumber: fieldNumber) + } + + public mutating func visitPackedEnumField(value: [E], + fieldNumber: Int) throws { + assert(!value.isEmpty) + try visitRepeatedEnumField(value: value, fieldNumber: fieldNumber) + } + + // Default handling for Groups is to treat them just like messages. + // This works for Text and Hash, but is overridden by Protobuf Binary + // format (which has a different encoding for groups) and JSON + // (which explicitly ignores all groups). + + public mutating func visitSingularGroupField(value: G, + fieldNumber: Int) throws { + try visitSingularMessageField(value: value, fieldNumber: fieldNumber) + } + + // Default handling of Extensions as a MessageSet to handing them just + // as plain extensions. Formats that what custom behavior can override + // it. + + public mutating func visitExtensionFieldsAsMessageSet( + fields: ExtensionFieldValueSet, + start: Int, + end: Int) throws { + try visitExtensionFields(fields: fields, start: start, end: end) + } + + // Default handling for Extensions is to forward the traverse to + // the ExtensionFieldValueSet. Formats that don't care about extensions + // can override to avoid it. + + /// Called for each extension range. + public mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws { + try fields.traverse(visitor: &self, start: start, end: end) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/WireFormat.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/WireFormat.swift new file mode 100644 index 00000000..d1e67ac4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/WireFormat.swift @@ -0,0 +1,70 @@ +// Sources/SwiftProtobuf/WireFormat.swift - Describes proto wire formats +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Types related to binary wire formats of encoded values. +/// +// ----------------------------------------------------------------------------- + +/// Denotes the wire format by which a value is encoded in binary form. +internal enum WireFormat: UInt8 { + case varint = 0 + case fixed64 = 1 + case lengthDelimited = 2 + case startGroup = 3 + case endGroup = 4 + case fixed32 = 5 +} + +extension WireFormat { + /// Information about the "MessageSet" format. Used when a Message has + /// the message_set_wire_format option enabled. + /// + /// Writing in MessageSet form means instead of writing the Extesions + /// normally as a simple fields, each gets written wrapped in a group: + /// repeated group Item = 1 { + /// required int32 type_id = 2; + /// required bytes message = 3; + /// } + /// Where the field number is the type_id, and the message is serilaized + /// into the bytes. + /// + /// The handling of unknown fields is ill defined. In proto1, they were + /// dropped. In the C++ for proto2, since it stores them in the unknowns + /// storage, if preserves any that are length delimited data (since that's + /// how the message also goes out). While the C++ is parsing, where the + /// unknowns fall in the flow of the group, sorta decides what happens. + /// Since it is ill defined, currently SwiftProtobuf will reflect out + /// anything set in the unknownStorage. During parsing, unknowns on the + /// message are preserved, but unknowns within the group are dropped (like + /// map items). Any extension in the MessageSet that isn't in the Regisry + /// being used at parse time will remain in a group and go into the + /// Messages's unknown fields (this way it reflects back out correctly). + internal enum MessageSet { + + enum FieldNumbers { + static let item = 1; + static let typeId = 2; + static let message = 3; + } + + enum Tags { + static let itemStart = FieldTag(fieldNumber: FieldNumbers.item, wireFormat: .startGroup) + static let itemEnd = FieldTag(fieldNumber: FieldNumbers.item, wireFormat: .endGroup) + static let typeId = FieldTag(fieldNumber: FieldNumbers.typeId, wireFormat: .varint) + static let message = FieldTag(fieldNumber: FieldNumbers.message, wireFormat: .lengthDelimited) + } + + // The size of all the tags needed to write out an Extension in MessageSet format. + static let itemTagsEncodedSize = + Tags.itemStart.encodedSize + Tags.itemEnd.encodedSize + + Tags.typeId.encodedSize + + Tags.message.encodedSize + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ZigZag.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ZigZag.swift new file mode 100644 index 00000000..e5a534bb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/ZigZag.swift @@ -0,0 +1,66 @@ +// Sources/SwiftProtobuf/ZigZag.swift - ZigZag encoding/decoding helpers +// +// Copyright (c) 2014 - 2016 Apple Inc. and the project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See LICENSE.txt for license information: +// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt +// +// ----------------------------------------------------------------------------- +/// +/// Helper functions to ZigZag encode and decode signed integers. +/// +// ----------------------------------------------------------------------------- + + +/// Contains helper methods to ZigZag encode and decode signed integers. +internal enum ZigZag { + + /// Return a 32-bit ZigZag-encoded value. + /// + /// ZigZag encodes signed integers into values that can be efficiently encoded with varint. + /// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always + /// taking 10 bytes on the wire.) + /// + /// - Parameter value: A signed 32-bit integer. + /// - Returns: An unsigned 32-bit integer representing the ZigZag-encoded value. + static func encoded(_ value: Int32) -> UInt32 { + return UInt32(bitPattern: (value << 1) ^ (value >> 31)) + } + + /// Return a 64-bit ZigZag-encoded value. + /// + /// ZigZag encodes signed integers into values that can be efficiently encoded with varint. + /// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always + /// taking 10 bytes on the wire.) + /// + /// - Parameter value: A signed 64-bit integer. + /// - Returns: An unsigned 64-bit integer representing the ZigZag-encoded value. + static func encoded(_ value: Int64) -> UInt64 { + return UInt64(bitPattern: (value << 1) ^ (value >> 63)) + } + + /// Return a 32-bit ZigZag-decoded value. + /// + /// ZigZag enocdes signed integers into values that can be efficiently encoded with varint. + /// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always + /// taking 10 bytes on the wire.) + /// + /// - Parameter value: An unsigned 32-bit ZagZag-encoded integer. + /// - Returns: The signed 32-bit decoded value. + static func decoded(_ value: UInt32) -> Int32 { + return Int32(value >> 1) ^ -Int32(value & 1) + } + + /// Return a 64-bit ZigZag-decoded value. + /// + /// ZigZag enocdes signed integers into values that can be efficiently encoded with varint. + /// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always + /// taking 10 bytes on the wire.) + /// + /// - Parameter value: An unsigned 64-bit ZigZag-encoded integer. + /// - Returns: The signed 64-bit decoded value. + static func decoded(_ value: UInt64) -> Int64 { + return Int64(value >> 1) ^ -Int64(value & 1) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/any.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/any.pb.swift new file mode 100644 index 00000000..62814280 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/any.pb.swift @@ -0,0 +1,245 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/any.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// `Any` contains an arbitrary serialized protocol buffer message along with a +/// URL that describes the type of the serialized message. +/// +/// Protobuf library provides support to pack/unpack Any values in the form +/// of utility functions or additional generated methods of the Any type. +/// +/// Example 1: Pack and unpack a message in C++. +/// +/// Foo foo = ...; +/// Any any; +/// any.PackFrom(foo); +/// ... +/// if (any.UnpackTo(&foo)) { +/// ... +/// } +/// +/// Example 2: Pack and unpack a message in Java. +/// +/// Foo foo = ...; +/// Any any = Any.pack(foo); +/// ... +/// if (any.is(Foo.class)) { +/// foo = any.unpack(Foo.class); +/// } +/// +/// Example 3: Pack and unpack a message in Python. +/// +/// foo = Foo(...) +/// any = Any() +/// any.Pack(foo) +/// ... +/// if any.Is(Foo.DESCRIPTOR): +/// any.Unpack(foo) +/// ... +/// +/// Example 4: Pack and unpack a message in Go +/// +/// foo := &pb.Foo{...} +/// any, err := anypb.New(foo) +/// if err != nil { +/// ... +/// } +/// ... +/// foo := &pb.Foo{} +/// if err := any.UnmarshalTo(foo); err != nil { +/// ... +/// } +/// +/// The pack methods provided by protobuf library will by default use +/// 'type.googleapis.com/full.type.name' as the type URL and the unpack +/// methods only use the fully qualified type name after the last '/' +/// in the type URL, for example "foo.bar.com/x/y.z" will yield type +/// name "y.z". +/// +/// +/// JSON +/// +/// The JSON representation of an `Any` value uses the regular +/// representation of the deserialized, embedded message, with an +/// additional field `@type` which contains the type URL. Example: +/// +/// package google.profile; +/// message Person { +/// string first_name = 1; +/// string last_name = 2; +/// } +/// +/// { +/// "@type": "type.googleapis.com/google.profile.Person", +/// "firstName": , +/// "lastName": +/// } +/// +/// If the embedded message type is well-known and has a custom JSON +/// representation, that representation will be embedded adding a field +/// `value` which holds the custom JSON in addition to the `@type` +/// field. Example (for message [google.protobuf.Duration][]): +/// +/// { +/// "@type": "type.googleapis.com/google.protobuf.Duration", +/// "value": "1.212s" +/// } +public struct Google_Protobuf_Any { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// A URL/resource name that uniquely identifies the type of the serialized + /// protocol buffer message. This string must contain at least + /// one "/" character. The last segment of the URL's path must represent + /// the fully qualified name of the type (as in + /// `path/google.protobuf.Duration`). The name should be in a canonical form + /// (e.g., leading "." is not accepted). + /// + /// In practice, teams usually precompile into the binary all types that they + /// expect it to use in the context of Any. However, for URLs which use the + /// scheme `http`, `https`, or no scheme, one can optionally set up a type + /// server that maps type URLs to message definitions as follows: + /// + /// * If no scheme is provided, `https` is assumed. + /// * An HTTP GET on the URL must yield a [google.protobuf.Type][] + /// value in binary format, or produce an error. + /// * Applications are allowed to cache lookup results based on the + /// URL, or have them precompiled into a binary to avoid any + /// lookup. Therefore, binary compatibility needs to be preserved + /// on changes to types. (Use versioned type names to manage + /// breaking changes.) + /// + /// Note: this functionality is not currently available in the official + /// protobuf release, and it is not used for type URLs beginning with + /// type.googleapis.com. + /// + /// Schemes other than `http`, `https` (or the empty scheme) might be + /// used with implementation specific semantics. + public var typeURL: String { + get {return _storage._typeURL} + set {_uniqueStorage()._typeURL = newValue} + } + + /// Must be a valid serialized protocol buffer of the above specified type. + public var value: Data { + get {return _storage._value} + set {_uniqueStorage()._value = newValue} + } + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + internal var _storage = _StorageClass.defaultInstance +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Any: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Any: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Any" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "type_url"), + 2: .same(proto: "value"), + ] + + typealias _StorageClass = AnyMessageStorage + + internal mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &_storage._typeURL) }() + case 2: try { try decoder.decodeSingularBytesField(value: &_storage._value) }() + default: break + } + } + } + } + + public func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + try _storage.preTraverse() + if !_storage._typeURL.isEmpty { + try visitor.visitSingularStringField(value: _storage._typeURL, fieldNumber: 1) + } + if !_storage._value.isEmpty { + try visitor.visitSingularBytesField(value: _storage._value, fieldNumber: 2) + } + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Any, rhs: Google_Protobuf_Any) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = lhs._storage.isEqualTo(other: rhs._storage) + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/api.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/api.pb.swift new file mode 100644 index 00000000..619d39c3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/api.pb.swift @@ -0,0 +1,434 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/api.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Api is a light-weight descriptor for an API Interface. +/// +/// Interfaces are also described as "protocol buffer services" in some contexts, +/// such as by the "service" keyword in a .proto file, but they are different +/// from API Services, which represent a concrete implementation of an interface +/// as opposed to simply a description of methods and bindings. They are also +/// sometimes simply referred to as "APIs" in other contexts, such as the name of +/// this message itself. See https://cloud.google.com/apis/design/glossary for +/// detailed terminology. +public struct Google_Protobuf_Api { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The fully qualified name of this interface, including package name + /// followed by the interface's simple name. + public var name: String = String() + + /// The methods of this interface, in unspecified order. + public var methods: [Google_Protobuf_Method] = [] + + /// Any metadata attached to the interface. + public var options: [Google_Protobuf_Option] = [] + + /// A version string for this interface. If specified, must have the form + /// `major-version.minor-version`, as in `1.10`. If the minor version is + /// omitted, it defaults to zero. If the entire version field is empty, the + /// major version is derived from the package name, as outlined below. If the + /// field is not empty, the version in the package name will be verified to be + /// consistent with what is provided here. + /// + /// The versioning schema uses [semantic + /// versioning](http://semver.org) where the major version number + /// indicates a breaking change and the minor version an additive, + /// non-breaking change. Both version numbers are signals to users + /// what to expect from different versions, and should be carefully + /// chosen based on the product plan. + /// + /// The major version is also reflected in the package name of the + /// interface, which must end in `v`, as in + /// `google.feature.v1`. For major versions 0 and 1, the suffix can + /// be omitted. Zero major versions must only be used for + /// experimental, non-GA interfaces. + public var version: String = String() + + /// Source context for the protocol buffer service represented by this + /// message. + public var sourceContext: Google_Protobuf_SourceContext { + get {return _sourceContext ?? Google_Protobuf_SourceContext()} + set {_sourceContext = newValue} + } + /// Returns true if `sourceContext` has been explicitly set. + public var hasSourceContext: Bool {return self._sourceContext != nil} + /// Clears the value of `sourceContext`. Subsequent reads from it will return its default value. + public mutating func clearSourceContext() {self._sourceContext = nil} + + /// Included interfaces. See [Mixin][]. + public var mixins: [Google_Protobuf_Mixin] = [] + + /// The source syntax of the service. + public var syntax: Google_Protobuf_Syntax = .proto2 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil +} + +/// Method represents a method of an API interface. +public struct Google_Protobuf_Method { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The simple name of this method. + public var name: String = String() + + /// A URL of the input message type. + public var requestTypeURL: String = String() + + /// If true, the request is streamed. + public var requestStreaming: Bool = false + + /// The URL of the output message type. + public var responseTypeURL: String = String() + + /// If true, the response is streamed. + public var responseStreaming: Bool = false + + /// Any metadata attached to the method. + public var options: [Google_Protobuf_Option] = [] + + /// The source syntax of this method. + public var syntax: Google_Protobuf_Syntax = .proto2 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Declares an API Interface to be included in this interface. The including +/// interface must redeclare all the methods from the included interface, but +/// documentation and options are inherited as follows: +/// +/// - If after comment and whitespace stripping, the documentation +/// string of the redeclared method is empty, it will be inherited +/// from the original method. +/// +/// - Each annotation belonging to the service config (http, +/// visibility) which is not set in the redeclared method will be +/// inherited. +/// +/// - If an http annotation is inherited, the path pattern will be +/// modified as follows. Any version prefix will be replaced by the +/// version of the including interface plus the [root][] path if +/// specified. +/// +/// Example of a simple mixin: +/// +/// package google.acl.v1; +/// service AccessControl { +/// // Get the underlying ACL object. +/// rpc GetAcl(GetAclRequest) returns (Acl) { +/// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +/// } +/// } +/// +/// package google.storage.v2; +/// service Storage { +/// rpc GetAcl(GetAclRequest) returns (Acl); +/// +/// // Get a data record. +/// rpc GetData(GetDataRequest) returns (Data) { +/// option (google.api.http).get = "/v2/{resource=**}"; +/// } +/// } +/// +/// Example of a mixin configuration: +/// +/// apis: +/// - name: google.storage.v2.Storage +/// mixins: +/// - name: google.acl.v1.AccessControl +/// +/// The mixin construct implies that all methods in `AccessControl` are +/// also declared with same name and request/response types in +/// `Storage`. A documentation generator or annotation processor will +/// see the effective `Storage.GetAcl` method after inheriting +/// documentation and annotations as follows: +/// +/// service Storage { +/// // Get the underlying ACL object. +/// rpc GetAcl(GetAclRequest) returns (Acl) { +/// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +/// } +/// ... +/// } +/// +/// Note how the version in the path pattern changed from `v1` to `v2`. +/// +/// If the `root` field in the mixin is specified, it should be a +/// relative path under which inherited HTTP paths are placed. Example: +/// +/// apis: +/// - name: google.storage.v2.Storage +/// mixins: +/// - name: google.acl.v1.AccessControl +/// root: acls +/// +/// This implies the following inherited HTTP annotation: +/// +/// service Storage { +/// // Get the underlying ACL object. +/// rpc GetAcl(GetAclRequest) returns (Acl) { +/// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +/// } +/// ... +/// } +public struct Google_Protobuf_Mixin { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The fully qualified name of the interface which is included. + public var name: String = String() + + /// If non-empty specifies a path under which inherited HTTP paths + /// are rooted. + public var root: String = String() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Api: @unchecked Sendable {} +extension Google_Protobuf_Method: @unchecked Sendable {} +extension Google_Protobuf_Mixin: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Api: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Api" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "methods"), + 3: .same(proto: "options"), + 4: .same(proto: "version"), + 5: .standard(proto: "source_context"), + 6: .same(proto: "mixins"), + 7: .same(proto: "syntax"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.methods) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.version) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.mixins) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.syntax) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.methods.isEmpty { + try visitor.visitRepeatedMessageField(value: self.methods, fieldNumber: 2) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3) + } + if !self.version.isEmpty { + try visitor.visitSingularStringField(value: self.version, fieldNumber: 4) + } + try { if let v = self._sourceContext { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + if !self.mixins.isEmpty { + try visitor.visitRepeatedMessageField(value: self.mixins, fieldNumber: 6) + } + if self.syntax != .proto2 { + try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 7) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Api, rhs: Google_Protobuf_Api) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.methods != rhs.methods {return false} + if lhs.options != rhs.options {return false} + if lhs.version != rhs.version {return false} + if lhs._sourceContext != rhs._sourceContext {return false} + if lhs.mixins != rhs.mixins {return false} + if lhs.syntax != rhs.syntax {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Method: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Method" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .standard(proto: "request_type_url"), + 3: .standard(proto: "request_streaming"), + 4: .standard(proto: "response_type_url"), + 5: .standard(proto: "response_streaming"), + 6: .same(proto: "options"), + 7: .same(proto: "syntax"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.requestTypeURL) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.requestStreaming) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.responseTypeURL) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.responseStreaming) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.syntax) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.requestTypeURL.isEmpty { + try visitor.visitSingularStringField(value: self.requestTypeURL, fieldNumber: 2) + } + if self.requestStreaming != false { + try visitor.visitSingularBoolField(value: self.requestStreaming, fieldNumber: 3) + } + if !self.responseTypeURL.isEmpty { + try visitor.visitSingularStringField(value: self.responseTypeURL, fieldNumber: 4) + } + if self.responseStreaming != false { + try visitor.visitSingularBoolField(value: self.responseStreaming, fieldNumber: 5) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 6) + } + if self.syntax != .proto2 { + try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 7) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Method, rhs: Google_Protobuf_Method) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.requestTypeURL != rhs.requestTypeURL {return false} + if lhs.requestStreaming != rhs.requestStreaming {return false} + if lhs.responseTypeURL != rhs.responseTypeURL {return false} + if lhs.responseStreaming != rhs.responseStreaming {return false} + if lhs.options != rhs.options {return false} + if lhs.syntax != rhs.syntax {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Mixin: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Mixin" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "root"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.root) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.root.isEmpty { + try visitor.visitSingularStringField(value: self.root, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Mixin, rhs: Google_Protobuf_Mixin) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.root != rhs.root {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/descriptor.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/descriptor.pb.swift new file mode 100644 index 00000000..113d703d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/descriptor.pb.swift @@ -0,0 +1,4070 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/descriptor.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// The protocol compiler can output a FileDescriptorSet containing the .proto +/// files it parses. +public struct Google_Protobuf_FileDescriptorSet { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var file: [Google_Protobuf_FileDescriptorProto] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Describes a complete .proto file. +public struct Google_Protobuf_FileDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// file name, relative to root of source tree + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + /// e.g. "foo", "foo.bar", etc. + public var package: String { + get {return _package ?? String()} + set {_package = newValue} + } + /// Returns true if `package` has been explicitly set. + public var hasPackage: Bool {return self._package != nil} + /// Clears the value of `package`. Subsequent reads from it will return its default value. + public mutating func clearPackage() {self._package = nil} + + /// Names of files imported by this file. + public var dependency: [String] = [] + + /// Indexes of the public imported files in the dependency list above. + public var publicDependency: [Int32] = [] + + /// Indexes of the weak imported files in the dependency list. + /// For Google-internal migration only. Do not use. + public var weakDependency: [Int32] = [] + + /// All top-level definitions in this file. + public var messageType: [Google_Protobuf_DescriptorProto] = [] + + public var enumType: [Google_Protobuf_EnumDescriptorProto] = [] + + public var service: [Google_Protobuf_ServiceDescriptorProto] = [] + + public var `extension`: [Google_Protobuf_FieldDescriptorProto] = [] + + public var options: Google_Protobuf_FileOptions { + get {return _options ?? Google_Protobuf_FileOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + /// This field contains optional information about the original source code. + /// You may safely remove this entire field without harming runtime + /// functionality of the descriptors -- the information is needed only by + /// development tools. + public var sourceCodeInfo: Google_Protobuf_SourceCodeInfo { + get {return _sourceCodeInfo ?? Google_Protobuf_SourceCodeInfo()} + set {_sourceCodeInfo = newValue} + } + /// Returns true if `sourceCodeInfo` has been explicitly set. + public var hasSourceCodeInfo: Bool {return self._sourceCodeInfo != nil} + /// Clears the value of `sourceCodeInfo`. Subsequent reads from it will return its default value. + public mutating func clearSourceCodeInfo() {self._sourceCodeInfo = nil} + + /// The syntax of the proto file. + /// The supported values are "proto2", "proto3", and "editions". + /// + /// If `edition` is present, this value must be "editions". + public var syntax: String { + get {return _syntax ?? String()} + set {_syntax = newValue} + } + /// Returns true if `syntax` has been explicitly set. + public var hasSyntax: Bool {return self._syntax != nil} + /// Clears the value of `syntax`. Subsequent reads from it will return its default value. + public mutating func clearSyntax() {self._syntax = nil} + + /// The edition of the proto file, which is an opaque string. + public var edition: String { + get {return _edition ?? String()} + set {_edition = newValue} + } + /// Returns true if `edition` has been explicitly set. + public var hasEdition: Bool {return self._edition != nil} + /// Clears the value of `edition`. Subsequent reads from it will return its default value. + public mutating func clearEdition() {self._edition = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _package: String? = nil + fileprivate var _options: Google_Protobuf_FileOptions? = nil + fileprivate var _sourceCodeInfo: Google_Protobuf_SourceCodeInfo? = nil + fileprivate var _syntax: String? = nil + fileprivate var _edition: String? = nil +} + +/// Describes a message type. +public struct Google_Protobuf_DescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + public var field: [Google_Protobuf_FieldDescriptorProto] = [] + + public var `extension`: [Google_Protobuf_FieldDescriptorProto] = [] + + public var nestedType: [Google_Protobuf_DescriptorProto] = [] + + public var enumType: [Google_Protobuf_EnumDescriptorProto] = [] + + public var extensionRange: [Google_Protobuf_DescriptorProto.ExtensionRange] = [] + + public var oneofDecl: [Google_Protobuf_OneofDescriptorProto] = [] + + public var options: Google_Protobuf_MessageOptions { + get {return _options ?? Google_Protobuf_MessageOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + public var reservedRange: [Google_Protobuf_DescriptorProto.ReservedRange] = [] + + /// Reserved field names, which may not be used by fields in the same message. + /// A given name may only be reserved once. + public var reservedName: [String] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct ExtensionRange { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Inclusive. + public var start: Int32 { + get {return _start ?? 0} + set {_start = newValue} + } + /// Returns true if `start` has been explicitly set. + public var hasStart: Bool {return self._start != nil} + /// Clears the value of `start`. Subsequent reads from it will return its default value. + public mutating func clearStart() {self._start = nil} + + /// Exclusive. + public var end: Int32 { + get {return _end ?? 0} + set {_end = newValue} + } + /// Returns true if `end` has been explicitly set. + public var hasEnd: Bool {return self._end != nil} + /// Clears the value of `end`. Subsequent reads from it will return its default value. + public mutating func clearEnd() {self._end = nil} + + public var options: Google_Protobuf_ExtensionRangeOptions { + get {return _options ?? Google_Protobuf_ExtensionRangeOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _start: Int32? = nil + fileprivate var _end: Int32? = nil + fileprivate var _options: Google_Protobuf_ExtensionRangeOptions? = nil + } + + /// Range of reserved tag numbers. Reserved tag numbers may not be used by + /// fields or extension ranges in the same message. Reserved ranges may + /// not overlap. + public struct ReservedRange { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Inclusive. + public var start: Int32 { + get {return _start ?? 0} + set {_start = newValue} + } + /// Returns true if `start` has been explicitly set. + public var hasStart: Bool {return self._start != nil} + /// Clears the value of `start`. Subsequent reads from it will return its default value. + public mutating func clearStart() {self._start = nil} + + /// Exclusive. + public var end: Int32 { + get {return _end ?? 0} + set {_end = newValue} + } + /// Returns true if `end` has been explicitly set. + public var hasEnd: Bool {return self._end != nil} + /// Clears the value of `end`. Subsequent reads from it will return its default value. + public mutating func clearEnd() {self._end = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _start: Int32? = nil + fileprivate var _end: Int32? = nil + } + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _options: Google_Protobuf_MessageOptions? = nil +} + +public struct Google_Protobuf_ExtensionRangeOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() +} + +/// Describes a field within a message. +public struct Google_Protobuf_FieldDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _storage._name ?? String()} + set {_uniqueStorage()._name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return _storage._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {_uniqueStorage()._name = nil} + + public var number: Int32 { + get {return _storage._number ?? 0} + set {_uniqueStorage()._number = newValue} + } + /// Returns true if `number` has been explicitly set. + public var hasNumber: Bool {return _storage._number != nil} + /// Clears the value of `number`. Subsequent reads from it will return its default value. + public mutating func clearNumber() {_uniqueStorage()._number = nil} + + public var label: Google_Protobuf_FieldDescriptorProto.Label { + get {return _storage._label ?? .optional} + set {_uniqueStorage()._label = newValue} + } + /// Returns true if `label` has been explicitly set. + public var hasLabel: Bool {return _storage._label != nil} + /// Clears the value of `label`. Subsequent reads from it will return its default value. + public mutating func clearLabel() {_uniqueStorage()._label = nil} + + /// If type_name is set, this need not be set. If both this and type_name + /// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + public var type: Google_Protobuf_FieldDescriptorProto.TypeEnum { + get {return _storage._type ?? .double} + set {_uniqueStorage()._type = newValue} + } + /// Returns true if `type` has been explicitly set. + public var hasType: Bool {return _storage._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + public mutating func clearType() {_uniqueStorage()._type = nil} + + /// For message and enum types, this is the name of the type. If the name + /// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + /// rules are used to find the type (i.e. first the nested types within this + /// message are searched, then within the parent, on up to the root + /// namespace). + public var typeName: String { + get {return _storage._typeName ?? String()} + set {_uniqueStorage()._typeName = newValue} + } + /// Returns true if `typeName` has been explicitly set. + public var hasTypeName: Bool {return _storage._typeName != nil} + /// Clears the value of `typeName`. Subsequent reads from it will return its default value. + public mutating func clearTypeName() {_uniqueStorage()._typeName = nil} + + /// For extensions, this is the name of the type being extended. It is + /// resolved in the same manner as type_name. + public var extendee: String { + get {return _storage._extendee ?? String()} + set {_uniqueStorage()._extendee = newValue} + } + /// Returns true if `extendee` has been explicitly set. + public var hasExtendee: Bool {return _storage._extendee != nil} + /// Clears the value of `extendee`. Subsequent reads from it will return its default value. + public mutating func clearExtendee() {_uniqueStorage()._extendee = nil} + + /// For numeric types, contains the original text representation of the value. + /// For booleans, "true" or "false". + /// For strings, contains the default text contents (not escaped in any way). + /// For bytes, contains the C escaped value. All bytes >= 128 are escaped. + public var defaultValue: String { + get {return _storage._defaultValue ?? String()} + set {_uniqueStorage()._defaultValue = newValue} + } + /// Returns true if `defaultValue` has been explicitly set. + public var hasDefaultValue: Bool {return _storage._defaultValue != nil} + /// Clears the value of `defaultValue`. Subsequent reads from it will return its default value. + public mutating func clearDefaultValue() {_uniqueStorage()._defaultValue = nil} + + /// If set, gives the index of a oneof in the containing type's oneof_decl + /// list. This field is a member of that oneof. + public var oneofIndex: Int32 { + get {return _storage._oneofIndex ?? 0} + set {_uniqueStorage()._oneofIndex = newValue} + } + /// Returns true if `oneofIndex` has been explicitly set. + public var hasOneofIndex: Bool {return _storage._oneofIndex != nil} + /// Clears the value of `oneofIndex`. Subsequent reads from it will return its default value. + public mutating func clearOneofIndex() {_uniqueStorage()._oneofIndex = nil} + + /// JSON name of this field. The value is set by protocol compiler. If the + /// user has set a "json_name" option on this field, that option's value + /// will be used. Otherwise, it's deduced from the field's name by converting + /// it to camelCase. + public var jsonName: String { + get {return _storage._jsonName ?? String()} + set {_uniqueStorage()._jsonName = newValue} + } + /// Returns true if `jsonName` has been explicitly set. + public var hasJsonName: Bool {return _storage._jsonName != nil} + /// Clears the value of `jsonName`. Subsequent reads from it will return its default value. + public mutating func clearJsonName() {_uniqueStorage()._jsonName = nil} + + public var options: Google_Protobuf_FieldOptions { + get {return _storage._options ?? Google_Protobuf_FieldOptions()} + set {_uniqueStorage()._options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return _storage._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {_uniqueStorage()._options = nil} + + /// If true, this is a proto3 "optional". When a proto3 field is optional, it + /// tracks presence regardless of field type. + /// + /// When proto3_optional is true, this field must be belong to a oneof to + /// signal to old proto3 clients that presence is tracked for this field. This + /// oneof is known as a "synthetic" oneof, and this field must be its sole + /// member (each proto3 optional field gets its own synthetic oneof). Synthetic + /// oneofs exist in the descriptor only, and do not generate any API. Synthetic + /// oneofs must be ordered after all "real" oneofs. + /// + /// For message fields, proto3_optional doesn't create any semantic change, + /// since non-repeated message fields always track presence. However it still + /// indicates the semantic detail of whether the user wrote "optional" or not. + /// This can be useful for round-tripping the .proto file. For consistency we + /// give message fields a synthetic oneof also, even though it is not required + /// to track presence. This is especially important because the parser can't + /// tell if a field is a message or an enum, so it must always create a + /// synthetic oneof. + /// + /// Proto2 optional fields do not set this flag, because they already indicate + /// optional with `LABEL_OPTIONAL`. + public var proto3Optional: Bool { + get {return _storage._proto3Optional ?? false} + set {_uniqueStorage()._proto3Optional = newValue} + } + /// Returns true if `proto3Optional` has been explicitly set. + public var hasProto3Optional: Bool {return _storage._proto3Optional != nil} + /// Clears the value of `proto3Optional`. Subsequent reads from it will return its default value. + public mutating func clearProto3Optional() {_uniqueStorage()._proto3Optional = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public enum TypeEnum: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// 0 is reserved for errors. + /// Order is weird for historical reasons. + case double // = 1 + case float // = 2 + + /// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + /// negative values are likely. + case int64 // = 3 + case uint64 // = 4 + + /// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + /// negative values are likely. + case int32 // = 5 + case fixed64 // = 6 + case fixed32 // = 7 + case bool // = 8 + case string // = 9 + + /// Tag-delimited aggregate. + /// Group type is deprecated and not supported in proto3. However, Proto3 + /// implementations should still be able to parse the group wire format and + /// treat group fields as unknown fields. + case group // = 10 + + /// Length-delimited aggregate. + case message // = 11 + + /// New in version 2. + case bytes // = 12 + case uint32 // = 13 + case `enum` // = 14 + case sfixed32 // = 15 + case sfixed64 // = 16 + + /// Uses ZigZag encoding. + case sint32 // = 17 + + /// Uses ZigZag encoding. + case sint64 // = 18 + + public init() { + self = .double + } + + public init?(rawValue: Int) { + switch rawValue { + case 1: self = .double + case 2: self = .float + case 3: self = .int64 + case 4: self = .uint64 + case 5: self = .int32 + case 6: self = .fixed64 + case 7: self = .fixed32 + case 8: self = .bool + case 9: self = .string + case 10: self = .group + case 11: self = .message + case 12: self = .bytes + case 13: self = .uint32 + case 14: self = .enum + case 15: self = .sfixed32 + case 16: self = .sfixed64 + case 17: self = .sint32 + case 18: self = .sint64 + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .double: return 1 + case .float: return 2 + case .int64: return 3 + case .uint64: return 4 + case .int32: return 5 + case .fixed64: return 6 + case .fixed32: return 7 + case .bool: return 8 + case .string: return 9 + case .group: return 10 + case .message: return 11 + case .bytes: return 12 + case .uint32: return 13 + case .enum: return 14 + case .sfixed32: return 15 + case .sfixed64: return 16 + case .sint32: return 17 + case .sint64: return 18 + } + } + + } + + public enum Label: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// 0 is reserved for errors + case `optional` // = 1 + case `required` // = 2 + case repeated // = 3 + + public init() { + self = .optional + } + + public init?(rawValue: Int) { + switch rawValue { + case 1: self = .optional + case 2: self = .required + case 3: self = .repeated + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .optional: return 1 + case .required: return 2 + case .repeated: return 3 + } + } + + } + + public init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=4.2) + +extension Google_Protobuf_FieldDescriptorProto.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +extension Google_Protobuf_FieldDescriptorProto.Label: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// Describes a oneof. +public struct Google_Protobuf_OneofDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + public var options: Google_Protobuf_OneofOptions { + get {return _options ?? Google_Protobuf_OneofOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _options: Google_Protobuf_OneofOptions? = nil +} + +/// Describes an enum type. +public struct Google_Protobuf_EnumDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + public var value: [Google_Protobuf_EnumValueDescriptorProto] = [] + + public var options: Google_Protobuf_EnumOptions { + get {return _options ?? Google_Protobuf_EnumOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + /// Range of reserved numeric values. Reserved numeric values may not be used + /// by enum values in the same enum declaration. Reserved ranges may not + /// overlap. + public var reservedRange: [Google_Protobuf_EnumDescriptorProto.EnumReservedRange] = [] + + /// Reserved enum value names, which may not be reused. A given name may only + /// be reserved once. + public var reservedName: [String] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Range of reserved numeric values. Reserved values may not be used by + /// entries in the same enum. Reserved ranges may not overlap. + /// + /// Note that this is distinct from DescriptorProto.ReservedRange in that it + /// is inclusive such that it can appropriately represent the entire int32 + /// domain. + public struct EnumReservedRange { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Inclusive. + public var start: Int32 { + get {return _start ?? 0} + set {_start = newValue} + } + /// Returns true if `start` has been explicitly set. + public var hasStart: Bool {return self._start != nil} + /// Clears the value of `start`. Subsequent reads from it will return its default value. + public mutating func clearStart() {self._start = nil} + + /// Inclusive. + public var end: Int32 { + get {return _end ?? 0} + set {_end = newValue} + } + /// Returns true if `end` has been explicitly set. + public var hasEnd: Bool {return self._end != nil} + /// Clears the value of `end`. Subsequent reads from it will return its default value. + public mutating func clearEnd() {self._end = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _start: Int32? = nil + fileprivate var _end: Int32? = nil + } + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _options: Google_Protobuf_EnumOptions? = nil +} + +/// Describes a value within an enum. +public struct Google_Protobuf_EnumValueDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + public var number: Int32 { + get {return _number ?? 0} + set {_number = newValue} + } + /// Returns true if `number` has been explicitly set. + public var hasNumber: Bool {return self._number != nil} + /// Clears the value of `number`. Subsequent reads from it will return its default value. + public mutating func clearNumber() {self._number = nil} + + public var options: Google_Protobuf_EnumValueOptions { + get {return _options ?? Google_Protobuf_EnumValueOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _number: Int32? = nil + fileprivate var _options: Google_Protobuf_EnumValueOptions? = nil +} + +/// Describes a service. +public struct Google_Protobuf_ServiceDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + public var method: [Google_Protobuf_MethodDescriptorProto] = [] + + public var options: Google_Protobuf_ServiceOptions { + get {return _options ?? Google_Protobuf_ServiceOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _options: Google_Protobuf_ServiceOptions? = nil +} + +/// Describes a method of a service. +public struct Google_Protobuf_MethodDescriptorProto { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + public var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + public mutating func clearName() {self._name = nil} + + /// Input and output type names. These are resolved in the same way as + /// FieldDescriptorProto.type_name, but must refer to a message type. + public var inputType: String { + get {return _inputType ?? String()} + set {_inputType = newValue} + } + /// Returns true if `inputType` has been explicitly set. + public var hasInputType: Bool {return self._inputType != nil} + /// Clears the value of `inputType`. Subsequent reads from it will return its default value. + public mutating func clearInputType() {self._inputType = nil} + + public var outputType: String { + get {return _outputType ?? String()} + set {_outputType = newValue} + } + /// Returns true if `outputType` has been explicitly set. + public var hasOutputType: Bool {return self._outputType != nil} + /// Clears the value of `outputType`. Subsequent reads from it will return its default value. + public mutating func clearOutputType() {self._outputType = nil} + + public var options: Google_Protobuf_MethodOptions { + get {return _options ?? Google_Protobuf_MethodOptions()} + set {_options = newValue} + } + /// Returns true if `options` has been explicitly set. + public var hasOptions: Bool {return self._options != nil} + /// Clears the value of `options`. Subsequent reads from it will return its default value. + public mutating func clearOptions() {self._options = nil} + + /// Identifies if client streams multiple client messages + public var clientStreaming: Bool { + get {return _clientStreaming ?? false} + set {_clientStreaming = newValue} + } + /// Returns true if `clientStreaming` has been explicitly set. + public var hasClientStreaming: Bool {return self._clientStreaming != nil} + /// Clears the value of `clientStreaming`. Subsequent reads from it will return its default value. + public mutating func clearClientStreaming() {self._clientStreaming = nil} + + /// Identifies if server streams multiple server messages + public var serverStreaming: Bool { + get {return _serverStreaming ?? false} + set {_serverStreaming = newValue} + } + /// Returns true if `serverStreaming` has been explicitly set. + public var hasServerStreaming: Bool {return self._serverStreaming != nil} + /// Clears the value of `serverStreaming`. Subsequent reads from it will return its default value. + public mutating func clearServerStreaming() {self._serverStreaming = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _name: String? = nil + fileprivate var _inputType: String? = nil + fileprivate var _outputType: String? = nil + fileprivate var _options: Google_Protobuf_MethodOptions? = nil + fileprivate var _clientStreaming: Bool? = nil + fileprivate var _serverStreaming: Bool? = nil +} + +public struct Google_Protobuf_FileOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Sets the Java package where classes generated from this .proto will be + /// placed. By default, the proto package is used, but this is often + /// inappropriate because proto packages do not normally start with backwards + /// domain names. + public var javaPackage: String { + get {return _storage._javaPackage ?? String()} + set {_uniqueStorage()._javaPackage = newValue} + } + /// Returns true if `javaPackage` has been explicitly set. + public var hasJavaPackage: Bool {return _storage._javaPackage != nil} + /// Clears the value of `javaPackage`. Subsequent reads from it will return its default value. + public mutating func clearJavaPackage() {_uniqueStorage()._javaPackage = nil} + + /// Controls the name of the wrapper Java class generated for the .proto file. + /// That class will always contain the .proto file's getDescriptor() method as + /// well as any top-level extensions defined in the .proto file. + /// If java_multiple_files is disabled, then all the other classes from the + /// .proto file will be nested inside the single wrapper outer class. + public var javaOuterClassname: String { + get {return _storage._javaOuterClassname ?? String()} + set {_uniqueStorage()._javaOuterClassname = newValue} + } + /// Returns true if `javaOuterClassname` has been explicitly set. + public var hasJavaOuterClassname: Bool {return _storage._javaOuterClassname != nil} + /// Clears the value of `javaOuterClassname`. Subsequent reads from it will return its default value. + public mutating func clearJavaOuterClassname() {_uniqueStorage()._javaOuterClassname = nil} + + /// If enabled, then the Java code generator will generate a separate .java + /// file for each top-level message, enum, and service defined in the .proto + /// file. Thus, these types will *not* be nested inside the wrapper class + /// named by java_outer_classname. However, the wrapper class will still be + /// generated to contain the file's getDescriptor() method as well as any + /// top-level extensions defined in the file. + public var javaMultipleFiles: Bool { + get {return _storage._javaMultipleFiles ?? false} + set {_uniqueStorage()._javaMultipleFiles = newValue} + } + /// Returns true if `javaMultipleFiles` has been explicitly set. + public var hasJavaMultipleFiles: Bool {return _storage._javaMultipleFiles != nil} + /// Clears the value of `javaMultipleFiles`. Subsequent reads from it will return its default value. + public mutating func clearJavaMultipleFiles() {_uniqueStorage()._javaMultipleFiles = nil} + + /// This option does nothing. + public var javaGenerateEqualsAndHash: Bool { + get {return _storage._javaGenerateEqualsAndHash ?? false} + set {_uniqueStorage()._javaGenerateEqualsAndHash = newValue} + } + /// Returns true if `javaGenerateEqualsAndHash` has been explicitly set. + public var hasJavaGenerateEqualsAndHash: Bool {return _storage._javaGenerateEqualsAndHash != nil} + /// Clears the value of `javaGenerateEqualsAndHash`. Subsequent reads from it will return its default value. + public mutating func clearJavaGenerateEqualsAndHash() {_uniqueStorage()._javaGenerateEqualsAndHash = nil} + + /// If set true, then the Java2 code generator will generate code that + /// throws an exception whenever an attempt is made to assign a non-UTF-8 + /// byte sequence to a string field. + /// Message reflection will do the same. + /// However, an extension field still accepts non-UTF-8 byte sequences. + /// This option has no effect on when used with the lite runtime. + public var javaStringCheckUtf8: Bool { + get {return _storage._javaStringCheckUtf8 ?? false} + set {_uniqueStorage()._javaStringCheckUtf8 = newValue} + } + /// Returns true if `javaStringCheckUtf8` has been explicitly set. + public var hasJavaStringCheckUtf8: Bool {return _storage._javaStringCheckUtf8 != nil} + /// Clears the value of `javaStringCheckUtf8`. Subsequent reads from it will return its default value. + public mutating func clearJavaStringCheckUtf8() {_uniqueStorage()._javaStringCheckUtf8 = nil} + + public var optimizeFor: Google_Protobuf_FileOptions.OptimizeMode { + get {return _storage._optimizeFor ?? .speed} + set {_uniqueStorage()._optimizeFor = newValue} + } + /// Returns true if `optimizeFor` has been explicitly set. + public var hasOptimizeFor: Bool {return _storage._optimizeFor != nil} + /// Clears the value of `optimizeFor`. Subsequent reads from it will return its default value. + public mutating func clearOptimizeFor() {_uniqueStorage()._optimizeFor = nil} + + /// Sets the Go package where structs generated from this .proto will be + /// placed. If omitted, the Go package will be derived from the following: + /// - The basename of the package import path, if provided. + /// - Otherwise, the package statement in the .proto file, if present. + /// - Otherwise, the basename of the .proto file, without extension. + public var goPackage: String { + get {return _storage._goPackage ?? String()} + set {_uniqueStorage()._goPackage = newValue} + } + /// Returns true if `goPackage` has been explicitly set. + public var hasGoPackage: Bool {return _storage._goPackage != nil} + /// Clears the value of `goPackage`. Subsequent reads from it will return its default value. + public mutating func clearGoPackage() {_uniqueStorage()._goPackage = nil} + + /// Should generic services be generated in each language? "Generic" services + /// are not specific to any particular RPC system. They are generated by the + /// main code generators in each language (without additional plugins). + /// Generic services were the only kind of service generation supported by + /// early versions of google.protobuf. + /// + /// Generic services are now considered deprecated in favor of using plugins + /// that generate code specific to your particular RPC system. Therefore, + /// these default to false. Old code which depends on generic services should + /// explicitly set them to true. + public var ccGenericServices: Bool { + get {return _storage._ccGenericServices ?? false} + set {_uniqueStorage()._ccGenericServices = newValue} + } + /// Returns true if `ccGenericServices` has been explicitly set. + public var hasCcGenericServices: Bool {return _storage._ccGenericServices != nil} + /// Clears the value of `ccGenericServices`. Subsequent reads from it will return its default value. + public mutating func clearCcGenericServices() {_uniqueStorage()._ccGenericServices = nil} + + public var javaGenericServices: Bool { + get {return _storage._javaGenericServices ?? false} + set {_uniqueStorage()._javaGenericServices = newValue} + } + /// Returns true if `javaGenericServices` has been explicitly set. + public var hasJavaGenericServices: Bool {return _storage._javaGenericServices != nil} + /// Clears the value of `javaGenericServices`. Subsequent reads from it will return its default value. + public mutating func clearJavaGenericServices() {_uniqueStorage()._javaGenericServices = nil} + + public var pyGenericServices: Bool { + get {return _storage._pyGenericServices ?? false} + set {_uniqueStorage()._pyGenericServices = newValue} + } + /// Returns true if `pyGenericServices` has been explicitly set. + public var hasPyGenericServices: Bool {return _storage._pyGenericServices != nil} + /// Clears the value of `pyGenericServices`. Subsequent reads from it will return its default value. + public mutating func clearPyGenericServices() {_uniqueStorage()._pyGenericServices = nil} + + public var phpGenericServices: Bool { + get {return _storage._phpGenericServices ?? false} + set {_uniqueStorage()._phpGenericServices = newValue} + } + /// Returns true if `phpGenericServices` has been explicitly set. + public var hasPhpGenericServices: Bool {return _storage._phpGenericServices != nil} + /// Clears the value of `phpGenericServices`. Subsequent reads from it will return its default value. + public mutating func clearPhpGenericServices() {_uniqueStorage()._phpGenericServices = nil} + + /// Is this file deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for everything in the file, or it will be completely ignored; in the very + /// least, this is a formalization for deprecating files. + public var deprecated: Bool { + get {return _storage._deprecated ?? false} + set {_uniqueStorage()._deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return _storage._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {_uniqueStorage()._deprecated = nil} + + /// Enables the use of arenas for the proto messages in this file. This applies + /// only to generated classes for C++. + public var ccEnableArenas: Bool { + get {return _storage._ccEnableArenas ?? true} + set {_uniqueStorage()._ccEnableArenas = newValue} + } + /// Returns true if `ccEnableArenas` has been explicitly set. + public var hasCcEnableArenas: Bool {return _storage._ccEnableArenas != nil} + /// Clears the value of `ccEnableArenas`. Subsequent reads from it will return its default value. + public mutating func clearCcEnableArenas() {_uniqueStorage()._ccEnableArenas = nil} + + /// Sets the objective c class prefix which is prepended to all objective c + /// generated classes from this .proto. There is no default. + public var objcClassPrefix: String { + get {return _storage._objcClassPrefix ?? String()} + set {_uniqueStorage()._objcClassPrefix = newValue} + } + /// Returns true if `objcClassPrefix` has been explicitly set. + public var hasObjcClassPrefix: Bool {return _storage._objcClassPrefix != nil} + /// Clears the value of `objcClassPrefix`. Subsequent reads from it will return its default value. + public mutating func clearObjcClassPrefix() {_uniqueStorage()._objcClassPrefix = nil} + + /// Namespace for generated classes; defaults to the package. + public var csharpNamespace: String { + get {return _storage._csharpNamespace ?? String()} + set {_uniqueStorage()._csharpNamespace = newValue} + } + /// Returns true if `csharpNamespace` has been explicitly set. + public var hasCsharpNamespace: Bool {return _storage._csharpNamespace != nil} + /// Clears the value of `csharpNamespace`. Subsequent reads from it will return its default value. + public mutating func clearCsharpNamespace() {_uniqueStorage()._csharpNamespace = nil} + + /// By default Swift generators will take the proto package and CamelCase it + /// replacing '.' with underscore and use that to prefix the types/symbols + /// defined. When this options is provided, they will use this value instead + /// to prefix the types/symbols defined. + public var swiftPrefix: String { + get {return _storage._swiftPrefix ?? String()} + set {_uniqueStorage()._swiftPrefix = newValue} + } + /// Returns true if `swiftPrefix` has been explicitly set. + public var hasSwiftPrefix: Bool {return _storage._swiftPrefix != nil} + /// Clears the value of `swiftPrefix`. Subsequent reads from it will return its default value. + public mutating func clearSwiftPrefix() {_uniqueStorage()._swiftPrefix = nil} + + /// Sets the php class prefix which is prepended to all php generated classes + /// from this .proto. Default is empty. + public var phpClassPrefix: String { + get {return _storage._phpClassPrefix ?? String()} + set {_uniqueStorage()._phpClassPrefix = newValue} + } + /// Returns true if `phpClassPrefix` has been explicitly set. + public var hasPhpClassPrefix: Bool {return _storage._phpClassPrefix != nil} + /// Clears the value of `phpClassPrefix`. Subsequent reads from it will return its default value. + public mutating func clearPhpClassPrefix() {_uniqueStorage()._phpClassPrefix = nil} + + /// Use this option to change the namespace of php generated classes. Default + /// is empty. When this option is empty, the package name will be used for + /// determining the namespace. + public var phpNamespace: String { + get {return _storage._phpNamespace ?? String()} + set {_uniqueStorage()._phpNamespace = newValue} + } + /// Returns true if `phpNamespace` has been explicitly set. + public var hasPhpNamespace: Bool {return _storage._phpNamespace != nil} + /// Clears the value of `phpNamespace`. Subsequent reads from it will return its default value. + public mutating func clearPhpNamespace() {_uniqueStorage()._phpNamespace = nil} + + /// Use this option to change the namespace of php generated metadata classes. + /// Default is empty. When this option is empty, the proto file name will be + /// used for determining the namespace. + public var phpMetadataNamespace: String { + get {return _storage._phpMetadataNamespace ?? String()} + set {_uniqueStorage()._phpMetadataNamespace = newValue} + } + /// Returns true if `phpMetadataNamespace` has been explicitly set. + public var hasPhpMetadataNamespace: Bool {return _storage._phpMetadataNamespace != nil} + /// Clears the value of `phpMetadataNamespace`. Subsequent reads from it will return its default value. + public mutating func clearPhpMetadataNamespace() {_uniqueStorage()._phpMetadataNamespace = nil} + + /// Use this option to change the package of ruby generated classes. Default + /// is empty. When this option is not set, the package name will be used for + /// determining the ruby package. + public var rubyPackage: String { + get {return _storage._rubyPackage ?? String()} + set {_uniqueStorage()._rubyPackage = newValue} + } + /// Returns true if `rubyPackage` has been explicitly set. + public var hasRubyPackage: Bool {return _storage._rubyPackage != nil} + /// Clears the value of `rubyPackage`. Subsequent reads from it will return its default value. + public mutating func clearRubyPackage() {_uniqueStorage()._rubyPackage = nil} + + /// The parser stores options it doesn't recognize here. + /// See the documentation for the "Options" section above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] { + get {return _storage._uninterpretedOption} + set {_uniqueStorage()._uninterpretedOption = newValue} + } + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Generated classes can be optimized for speed or code size. + public enum OptimizeMode: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Generate complete code for parsing, serialization, + case speed // = 1 + + /// etc. + case codeSize // = 2 + + /// Generate code using MessageLite and the lite runtime. + case liteRuntime // = 3 + + public init() { + self = .speed + } + + public init?(rawValue: Int) { + switch rawValue { + case 1: self = .speed + case 2: self = .codeSize + case 3: self = .liteRuntime + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .speed: return 1 + case .codeSize: return 2 + case .liteRuntime: return 3 + } + } + + } + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=4.2) + +extension Google_Protobuf_FileOptions.OptimizeMode: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +public struct Google_Protobuf_MessageOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Set true to use the old proto1 MessageSet wire format for extensions. + /// This is provided for backwards-compatibility with the MessageSet wire + /// format. You should not use this for any other reason: It's less + /// efficient, has fewer features, and is more complicated. + /// + /// The message must be defined exactly as follows: + /// message Foo { + /// option message_set_wire_format = true; + /// extensions 4 to max; + /// } + /// Note that the message cannot have any defined fields; MessageSets only + /// have extensions. + /// + /// All extensions of your type must be singular messages; e.g. they cannot + /// be int32s, enums, or repeated messages. + /// + /// Because this is an option, the above two restrictions are not enforced by + /// the protocol compiler. + public var messageSetWireFormat: Bool { + get {return _messageSetWireFormat ?? false} + set {_messageSetWireFormat = newValue} + } + /// Returns true if `messageSetWireFormat` has been explicitly set. + public var hasMessageSetWireFormat: Bool {return self._messageSetWireFormat != nil} + /// Clears the value of `messageSetWireFormat`. Subsequent reads from it will return its default value. + public mutating func clearMessageSetWireFormat() {self._messageSetWireFormat = nil} + + /// Disables the generation of the standard "descriptor()" accessor, which can + /// conflict with a field of the same name. This is meant to make migration + /// from proto1 easier; new code should avoid fields named "descriptor". + public var noStandardDescriptorAccessor: Bool { + get {return _noStandardDescriptorAccessor ?? false} + set {_noStandardDescriptorAccessor = newValue} + } + /// Returns true if `noStandardDescriptorAccessor` has been explicitly set. + public var hasNoStandardDescriptorAccessor: Bool {return self._noStandardDescriptorAccessor != nil} + /// Clears the value of `noStandardDescriptorAccessor`. Subsequent reads from it will return its default value. + public mutating func clearNoStandardDescriptorAccessor() {self._noStandardDescriptorAccessor = nil} + + /// Is this message deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for the message, or it will be completely ignored; in the very least, + /// this is a formalization for deprecating messages. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + /// NOTE: Do not set the option in .proto files. Always use the maps syntax + /// instead. The option should only be implicitly set by the proto compiler + /// parser. + /// + /// Whether the message is an automatically generated map entry type for the + /// maps field. + /// + /// For maps fields: + /// map map_field = 1; + /// The parsed descriptor looks like: + /// message MapFieldEntry { + /// option map_entry = true; + /// optional KeyType key = 1; + /// optional ValueType value = 2; + /// } + /// repeated MapFieldEntry map_field = 1; + /// + /// Implementations may choose not to generate the map_entry=true message, but + /// use a native map in the target language to hold the keys and values. + /// The reflection APIs in such implementations still need to work as + /// if the field is a repeated message field. + public var mapEntry: Bool { + get {return _mapEntry ?? false} + set {_mapEntry = newValue} + } + /// Returns true if `mapEntry` has been explicitly set. + public var hasMapEntry: Bool {return self._mapEntry != nil} + /// Clears the value of `mapEntry`. Subsequent reads from it will return its default value. + public mutating func clearMapEntry() {self._mapEntry = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _messageSetWireFormat: Bool? = nil + fileprivate var _noStandardDescriptorAccessor: Bool? = nil + fileprivate var _deprecated: Bool? = nil + fileprivate var _mapEntry: Bool? = nil +} + +public struct Google_Protobuf_FieldOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The ctype option instructs the C++ code generator to use a different + /// representation of the field than it normally would. See the specific + /// options below. This option is not yet implemented in the open source + /// release -- sorry, we'll try to include it in a future version! + public var ctype: Google_Protobuf_FieldOptions.CType { + get {return _ctype ?? .string} + set {_ctype = newValue} + } + /// Returns true if `ctype` has been explicitly set. + public var hasCtype: Bool {return self._ctype != nil} + /// Clears the value of `ctype`. Subsequent reads from it will return its default value. + public mutating func clearCtype() {self._ctype = nil} + + /// The packed option can be enabled for repeated primitive fields to enable + /// a more efficient representation on the wire. Rather than repeatedly + /// writing the tag and type for each element, the entire array is encoded as + /// a single length-delimited blob. In proto3, only explicit setting it to + /// false will avoid using packed encoding. + public var packed: Bool { + get {return _packed ?? false} + set {_packed = newValue} + } + /// Returns true if `packed` has been explicitly set. + public var hasPacked: Bool {return self._packed != nil} + /// Clears the value of `packed`. Subsequent reads from it will return its default value. + public mutating func clearPacked() {self._packed = nil} + + /// The jstype option determines the JavaScript type used for values of the + /// field. The option is permitted only for 64 bit integral and fixed types + /// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + /// is represented as JavaScript string, which avoids loss of precision that + /// can happen when a large value is converted to a floating point JavaScript. + /// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + /// use the JavaScript "number" type. The behavior of the default option + /// JS_NORMAL is implementation dependent. + /// + /// This option is an enum to permit additional types to be added, e.g. + /// goog.math.Integer. + public var jstype: Google_Protobuf_FieldOptions.JSType { + get {return _jstype ?? .jsNormal} + set {_jstype = newValue} + } + /// Returns true if `jstype` has been explicitly set. + public var hasJstype: Bool {return self._jstype != nil} + /// Clears the value of `jstype`. Subsequent reads from it will return its default value. + public mutating func clearJstype() {self._jstype = nil} + + /// Should this field be parsed lazily? Lazy applies only to message-type + /// fields. It means that when the outer message is initially parsed, the + /// inner message's contents will not be parsed but instead stored in encoded + /// form. The inner message will actually be parsed when it is first accessed. + /// + /// This is only a hint. Implementations are free to choose whether to use + /// eager or lazy parsing regardless of the value of this option. However, + /// setting this option true suggests that the protocol author believes that + /// using lazy parsing on this field is worth the additional bookkeeping + /// overhead typically needed to implement it. + /// + /// This option does not affect the public interface of any generated code; + /// all method signatures remain the same. Furthermore, thread-safety of the + /// interface is not affected by this option; const methods remain safe to + /// call from multiple threads concurrently, while non-const methods continue + /// to require exclusive access. + /// + /// + /// Note that implementations may choose not to check required fields within + /// a lazy sub-message. That is, calling IsInitialized() on the outer message + /// may return true even if the inner message has missing required fields. + /// This is necessary because otherwise the inner message would have to be + /// parsed in order to perform the check, defeating the purpose of lazy + /// parsing. An implementation which chooses not to check required fields + /// must be consistent about it. That is, for any particular sub-message, the + /// implementation must either *always* check its required fields, or *never* + /// check its required fields, regardless of whether or not the message has + /// been parsed. + /// + /// As of May 2022, lazy verifies the contents of the byte stream during + /// parsing. An invalid byte stream will cause the overall parsing to fail. + public var lazy: Bool { + get {return _lazy ?? false} + set {_lazy = newValue} + } + /// Returns true if `lazy` has been explicitly set. + public var hasLazy: Bool {return self._lazy != nil} + /// Clears the value of `lazy`. Subsequent reads from it will return its default value. + public mutating func clearLazy() {self._lazy = nil} + + /// unverified_lazy does no correctness checks on the byte stream. This should + /// only be used where lazy with verification is prohibitive for performance + /// reasons. + public var unverifiedLazy: Bool { + get {return _unverifiedLazy ?? false} + set {_unverifiedLazy = newValue} + } + /// Returns true if `unverifiedLazy` has been explicitly set. + public var hasUnverifiedLazy: Bool {return self._unverifiedLazy != nil} + /// Clears the value of `unverifiedLazy`. Subsequent reads from it will return its default value. + public mutating func clearUnverifiedLazy() {self._unverifiedLazy = nil} + + /// Is this field deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for accessors, or it will be completely ignored; in the very least, this + /// is a formalization for deprecating fields. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + /// For Google-internal migration only. Do not use. + public var weak: Bool { + get {return _weak ?? false} + set {_weak = newValue} + } + /// Returns true if `weak` has been explicitly set. + public var hasWeak: Bool {return self._weak != nil} + /// Clears the value of `weak`. Subsequent reads from it will return its default value. + public mutating func clearWeak() {self._weak = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public enum CType: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Default mode. + case string // = 0 + case cord // = 1 + case stringPiece // = 2 + + public init() { + self = .string + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .string + case 1: self = .cord + case 2: self = .stringPiece + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .string: return 0 + case .cord: return 1 + case .stringPiece: return 2 + } + } + + } + + public enum JSType: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Use the default type. + case jsNormal // = 0 + + /// Use JavaScript strings. + case jsString // = 1 + + /// Use JavaScript numbers. + case jsNumber // = 2 + + public init() { + self = .jsNormal + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .jsNormal + case 1: self = .jsString + case 2: self = .jsNumber + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .jsNormal: return 0 + case .jsString: return 1 + case .jsNumber: return 2 + } + } + + } + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _ctype: Google_Protobuf_FieldOptions.CType? = nil + fileprivate var _packed: Bool? = nil + fileprivate var _jstype: Google_Protobuf_FieldOptions.JSType? = nil + fileprivate var _lazy: Bool? = nil + fileprivate var _unverifiedLazy: Bool? = nil + fileprivate var _deprecated: Bool? = nil + fileprivate var _weak: Bool? = nil +} + +#if swift(>=4.2) + +extension Google_Protobuf_FieldOptions.CType: CaseIterable { + // Support synthesized by the compiler. +} + +extension Google_Protobuf_FieldOptions.JSType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +public struct Google_Protobuf_OneofOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() +} + +public struct Google_Protobuf_EnumOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Set this option to true to allow mapping different tag names to the same + /// value. + public var allowAlias: Bool { + get {return _allowAlias ?? false} + set {_allowAlias = newValue} + } + /// Returns true if `allowAlias` has been explicitly set. + public var hasAllowAlias: Bool {return self._allowAlias != nil} + /// Clears the value of `allowAlias`. Subsequent reads from it will return its default value. + public mutating func clearAllowAlias() {self._allowAlias = nil} + + /// Is this enum deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for the enum, or it will be completely ignored; in the very least, this + /// is a formalization for deprecating enums. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _allowAlias: Bool? = nil + fileprivate var _deprecated: Bool? = nil +} + +public struct Google_Protobuf_EnumValueOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Is this enum value deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for the enum value, or it will be completely ignored; in the very least, + /// this is a formalization for deprecating enum values. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _deprecated: Bool? = nil +} + +public struct Google_Protobuf_ServiceOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Is this service deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for the service, or it will be completely ignored; in the very least, + /// this is a formalization for deprecating services. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _deprecated: Bool? = nil +} + +public struct Google_Protobuf_MethodOptions: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Is this method deprecated? + /// Depending on the target platform, this can emit Deprecated annotations + /// for the method, or it will be completely ignored; in the very least, + /// this is a formalization for deprecating methods. + public var deprecated: Bool { + get {return _deprecated ?? false} + set {_deprecated = newValue} + } + /// Returns true if `deprecated` has been explicitly set. + public var hasDeprecated: Bool {return self._deprecated != nil} + /// Clears the value of `deprecated`. Subsequent reads from it will return its default value. + public mutating func clearDeprecated() {self._deprecated = nil} + + public var idempotencyLevel: Google_Protobuf_MethodOptions.IdempotencyLevel { + get {return _idempotencyLevel ?? .idempotencyUnknown} + set {_idempotencyLevel = newValue} + } + /// Returns true if `idempotencyLevel` has been explicitly set. + public var hasIdempotencyLevel: Bool {return self._idempotencyLevel != nil} + /// Clears the value of `idempotencyLevel`. Subsequent reads from it will return its default value. + public mutating func clearIdempotencyLevel() {self._idempotencyLevel = nil} + + /// The parser stores options it doesn't recognize here. See above. + public var uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + /// or neither? HTTP based RPC implementation may choose GET verb for safe + /// methods, and PUT verb for idempotent methods instead of the default POST. + public enum IdempotencyLevel: SwiftProtobuf.Enum { + public typealias RawValue = Int + case idempotencyUnknown // = 0 + + /// implies idempotent + case noSideEffects // = 1 + + /// idempotent, but may have side effects + case idempotent // = 2 + + public init() { + self = .idempotencyUnknown + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .idempotencyUnknown + case 1: self = .noSideEffects + case 2: self = .idempotent + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .idempotencyUnknown: return 0 + case .noSideEffects: return 1 + case .idempotent: return 2 + } + } + + } + + public init() {} + + public var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _deprecated: Bool? = nil + fileprivate var _idempotencyLevel: Google_Protobuf_MethodOptions.IdempotencyLevel? = nil +} + +#if swift(>=4.2) + +extension Google_Protobuf_MethodOptions.IdempotencyLevel: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A message representing a option the parser does not recognize. This only +/// appears in options protos created by the compiler::Parser class. +/// DescriptorPool resolves these when building Descriptor objects. Therefore, +/// options protos in descriptor objects (e.g. returned by Descriptor::options(), +/// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +/// in them. +public struct Google_Protobuf_UninterpretedOption { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var name: [Google_Protobuf_UninterpretedOption.NamePart] = [] + + /// The value of the uninterpreted option, in whatever type the tokenizer + /// identified it as during parsing. Exactly one of these should be set. + public var identifierValue: String { + get {return _identifierValue ?? String()} + set {_identifierValue = newValue} + } + /// Returns true if `identifierValue` has been explicitly set. + public var hasIdentifierValue: Bool {return self._identifierValue != nil} + /// Clears the value of `identifierValue`. Subsequent reads from it will return its default value. + public mutating func clearIdentifierValue() {self._identifierValue = nil} + + public var positiveIntValue: UInt64 { + get {return _positiveIntValue ?? 0} + set {_positiveIntValue = newValue} + } + /// Returns true if `positiveIntValue` has been explicitly set. + public var hasPositiveIntValue: Bool {return self._positiveIntValue != nil} + /// Clears the value of `positiveIntValue`. Subsequent reads from it will return its default value. + public mutating func clearPositiveIntValue() {self._positiveIntValue = nil} + + public var negativeIntValue: Int64 { + get {return _negativeIntValue ?? 0} + set {_negativeIntValue = newValue} + } + /// Returns true if `negativeIntValue` has been explicitly set. + public var hasNegativeIntValue: Bool {return self._negativeIntValue != nil} + /// Clears the value of `negativeIntValue`. Subsequent reads from it will return its default value. + public mutating func clearNegativeIntValue() {self._negativeIntValue = nil} + + public var doubleValue: Double { + get {return _doubleValue ?? 0} + set {_doubleValue = newValue} + } + /// Returns true if `doubleValue` has been explicitly set. + public var hasDoubleValue: Bool {return self._doubleValue != nil} + /// Clears the value of `doubleValue`. Subsequent reads from it will return its default value. + public mutating func clearDoubleValue() {self._doubleValue = nil} + + public var stringValue: Data { + get {return _stringValue ?? Data()} + set {_stringValue = newValue} + } + /// Returns true if `stringValue` has been explicitly set. + public var hasStringValue: Bool {return self._stringValue != nil} + /// Clears the value of `stringValue`. Subsequent reads from it will return its default value. + public mutating func clearStringValue() {self._stringValue = nil} + + public var aggregateValue: String { + get {return _aggregateValue ?? String()} + set {_aggregateValue = newValue} + } + /// Returns true if `aggregateValue` has been explicitly set. + public var hasAggregateValue: Bool {return self._aggregateValue != nil} + /// Clears the value of `aggregateValue`. Subsequent reads from it will return its default value. + public mutating func clearAggregateValue() {self._aggregateValue = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// The name of the uninterpreted option. Each string represents a segment in + /// a dot-separated name. is_extension is true iff a segment represents an + /// extension (denoted with parentheses in options specs in .proto files). + /// E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents + /// "foo.(bar.baz).moo". + public struct NamePart { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var namePart: String { + get {return _namePart ?? String()} + set {_namePart = newValue} + } + /// Returns true if `namePart` has been explicitly set. + public var hasNamePart: Bool {return self._namePart != nil} + /// Clears the value of `namePart`. Subsequent reads from it will return its default value. + public mutating func clearNamePart() {self._namePart = nil} + + public var isExtension: Bool { + get {return _isExtension ?? false} + set {_isExtension = newValue} + } + /// Returns true if `isExtension` has been explicitly set. + public var hasIsExtension: Bool {return self._isExtension != nil} + /// Clears the value of `isExtension`. Subsequent reads from it will return its default value. + public mutating func clearIsExtension() {self._isExtension = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _namePart: String? = nil + fileprivate var _isExtension: Bool? = nil + } + + public init() {} + + fileprivate var _identifierValue: String? = nil + fileprivate var _positiveIntValue: UInt64? = nil + fileprivate var _negativeIntValue: Int64? = nil + fileprivate var _doubleValue: Double? = nil + fileprivate var _stringValue: Data? = nil + fileprivate var _aggregateValue: String? = nil +} + +/// Encapsulates information about the original source file from which a +/// FileDescriptorProto was generated. +public struct Google_Protobuf_SourceCodeInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// A Location identifies a piece of source code in a .proto file which + /// corresponds to a particular definition. This information is intended + /// to be useful to IDEs, code indexers, documentation generators, and similar + /// tools. + /// + /// For example, say we have a file like: + /// message Foo { + /// optional string foo = 1; + /// } + /// Let's look at just the field definition: + /// optional string foo = 1; + /// ^ ^^ ^^ ^ ^^^ + /// a bc de f ghi + /// We have the following locations: + /// span path represents + /// [a,i) [ 4, 0, 2, 0 ] The whole field definition. + /// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + /// [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + /// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + /// [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + /// + /// Notes: + /// - A location may refer to a repeated field itself (i.e. not to any + /// particular index within it). This is used whenever a set of elements are + /// logically enclosed in a single code segment. For example, an entire + /// extend block (possibly containing multiple extension definitions) will + /// have an outer location whose path refers to the "extensions" repeated + /// field without an index. + /// - Multiple locations may have the same path. This happens when a single + /// logical declaration is spread out across multiple places. The most + /// obvious example is the "extend" block again -- there may be multiple + /// extend blocks in the same scope, each of which will have the same path. + /// - A location's span is not always a subset of its parent's span. For + /// example, the "extendee" of an extension declaration appears at the + /// beginning of the "extend" block and is shared by all extensions within + /// the block. + /// - Just because a location's span is a subset of some other location's span + /// does not mean that it is a descendant. For example, a "group" defines + /// both a type and a field in a single declaration. Thus, the locations + /// corresponding to the type and field and their components will overlap. + /// - Code which tries to interpret locations should probably be designed to + /// ignore those that it doesn't understand, as more types of locations could + /// be recorded in the future. + public var location: [Google_Protobuf_SourceCodeInfo.Location] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct Location { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Identifies which part of the FileDescriptorProto was defined at this + /// location. + /// + /// Each element is a field number or an index. They form a path from + /// the root FileDescriptorProto to the place where the definition occurs. + /// For example, this path: + /// [ 4, 3, 2, 7, 1 ] + /// refers to: + /// file.message_type(3) // 4, 3 + /// .field(7) // 2, 7 + /// .name() // 1 + /// This is because FileDescriptorProto.message_type has field number 4: + /// repeated DescriptorProto message_type = 4; + /// and DescriptorProto.field has field number 2: + /// repeated FieldDescriptorProto field = 2; + /// and FieldDescriptorProto.name has field number 1: + /// optional string name = 1; + /// + /// Thus, the above path gives the location of a field name. If we removed + /// the last element: + /// [ 4, 3, 2, 7 ] + /// this path refers to the whole field declaration (from the beginning + /// of the label to the terminating semicolon). + public var path: [Int32] = [] + + /// Always has exactly three or four elements: start line, start column, + /// end line (optional, otherwise assumed same as start line), end column. + /// These are packed into a single field for efficiency. Note that line + /// and column numbers are zero-based -- typically you will want to add + /// 1 to each before displaying to a user. + public var span: [Int32] = [] + + /// If this SourceCodeInfo represents a complete declaration, these are any + /// comments appearing before and after the declaration which appear to be + /// attached to the declaration. + /// + /// A series of line comments appearing on consecutive lines, with no other + /// tokens appearing on those lines, will be treated as a single comment. + /// + /// leading_detached_comments will keep paragraphs of comments that appear + /// before (but not connected to) the current element. Each paragraph, + /// separated by empty lines, will be one comment element in the repeated + /// field. + /// + /// Only the comment content is provided; comment markers (e.g. //) are + /// stripped out. For block comments, leading whitespace and an asterisk + /// will be stripped from the beginning of each line other than the first. + /// Newlines are included in the output. + /// + /// Examples: + /// + /// optional int32 foo = 1; // Comment attached to foo. + /// // Comment attached to bar. + /// optional int32 bar = 2; + /// + /// optional string baz = 3; + /// // Comment attached to baz. + /// // Another line attached to baz. + /// + /// // Comment attached to moo. + /// // + /// // Another line attached to moo. + /// optional double moo = 4; + /// + /// // Detached comment for corge. This is not leading or trailing comments + /// // to moo or corge because there are blank lines separating it from + /// // both. + /// + /// // Detached comment for corge paragraph 2. + /// + /// optional string corge = 5; + /// /* Block comment attached + /// * to corge. Leading asterisks + /// * will be removed. */ + /// /* Block comment attached to + /// * grault. */ + /// optional int32 grault = 6; + /// + /// // ignored detached comments. + public var leadingComments: String { + get {return _leadingComments ?? String()} + set {_leadingComments = newValue} + } + /// Returns true if `leadingComments` has been explicitly set. + public var hasLeadingComments: Bool {return self._leadingComments != nil} + /// Clears the value of `leadingComments`. Subsequent reads from it will return its default value. + public mutating func clearLeadingComments() {self._leadingComments = nil} + + public var trailingComments: String { + get {return _trailingComments ?? String()} + set {_trailingComments = newValue} + } + /// Returns true if `trailingComments` has been explicitly set. + public var hasTrailingComments: Bool {return self._trailingComments != nil} + /// Clears the value of `trailingComments`. Subsequent reads from it will return its default value. + public mutating func clearTrailingComments() {self._trailingComments = nil} + + public var leadingDetachedComments: [String] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _leadingComments: String? = nil + fileprivate var _trailingComments: String? = nil + } + + public init() {} +} + +/// Describes the relationship between generated code and its original source +/// file. A GeneratedCodeInfo message is associated with only one generated +/// source file, but may contain references to different source .proto files. +public struct Google_Protobuf_GeneratedCodeInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// An Annotation connects some span of text in generated code to an element + /// of its generating .proto file. + public var annotation: [Google_Protobuf_GeneratedCodeInfo.Annotation] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public struct Annotation { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Identifies the element in the original source .proto file. This field + /// is formatted the same as SourceCodeInfo.Location.path. + public var path: [Int32] = [] + + /// Identifies the filesystem path to the original source .proto. + public var sourceFile: String { + get {return _sourceFile ?? String()} + set {_sourceFile = newValue} + } + /// Returns true if `sourceFile` has been explicitly set. + public var hasSourceFile: Bool {return self._sourceFile != nil} + /// Clears the value of `sourceFile`. Subsequent reads from it will return its default value. + public mutating func clearSourceFile() {self._sourceFile = nil} + + /// Identifies the starting offset in bytes in the generated code + /// that relates to the identified object. + public var begin: Int32 { + get {return _begin ?? 0} + set {_begin = newValue} + } + /// Returns true if `begin` has been explicitly set. + public var hasBegin: Bool {return self._begin != nil} + /// Clears the value of `begin`. Subsequent reads from it will return its default value. + public mutating func clearBegin() {self._begin = nil} + + /// Identifies the ending offset in bytes in the generated code that + /// relates to the identified object. The end offset should be one past + /// the last relevant byte (so the length of the text = end - begin). + public var end: Int32 { + get {return _end ?? 0} + set {_end = newValue} + } + /// Returns true if `end` has been explicitly set. + public var hasEnd: Bool {return self._end != nil} + /// Clears the value of `end`. Subsequent reads from it will return its default value. + public mutating func clearEnd() {self._end = nil} + + public var semantic: Google_Protobuf_GeneratedCodeInfo.Annotation.Semantic { + get {return _semantic ?? .none} + set {_semantic = newValue} + } + /// Returns true if `semantic` has been explicitly set. + public var hasSemantic: Bool {return self._semantic != nil} + /// Clears the value of `semantic`. Subsequent reads from it will return its default value. + public mutating func clearSemantic() {self._semantic = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Represents the identified object's effect on the element in the original + /// .proto file. + public enum Semantic: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// There is no effect or the effect is indescribable. + case none // = 0 + + /// The element is set or otherwise mutated. + case set // = 1 + + /// An alias to the element is returned. + case alias // = 2 + + public init() { + self = .none + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .none + case 1: self = .set + case 2: self = .alias + default: return nil + } + } + + public var rawValue: Int { + switch self { + case .none: return 0 + case .set: return 1 + case .alias: return 2 + } + } + + } + + public init() {} + + fileprivate var _sourceFile: String? = nil + fileprivate var _begin: Int32? = nil + fileprivate var _end: Int32? = nil + fileprivate var _semantic: Google_Protobuf_GeneratedCodeInfo.Annotation.Semantic? = nil + } + + public init() {} +} + +#if swift(>=4.2) + +extension Google_Protobuf_GeneratedCodeInfo.Annotation.Semantic: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_FileDescriptorSet: @unchecked Sendable {} +extension Google_Protobuf_FileDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_DescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_DescriptorProto.ExtensionRange: @unchecked Sendable {} +extension Google_Protobuf_DescriptorProto.ReservedRange: @unchecked Sendable {} +extension Google_Protobuf_ExtensionRangeOptions: @unchecked Sendable {} +extension Google_Protobuf_FieldDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_FieldDescriptorProto.TypeEnum: @unchecked Sendable {} +extension Google_Protobuf_FieldDescriptorProto.Label: @unchecked Sendable {} +extension Google_Protobuf_OneofDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_EnumDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_EnumDescriptorProto.EnumReservedRange: @unchecked Sendable {} +extension Google_Protobuf_EnumValueDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_ServiceDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_MethodDescriptorProto: @unchecked Sendable {} +extension Google_Protobuf_FileOptions: @unchecked Sendable {} +extension Google_Protobuf_FileOptions.OptimizeMode: @unchecked Sendable {} +extension Google_Protobuf_MessageOptions: @unchecked Sendable {} +extension Google_Protobuf_FieldOptions: @unchecked Sendable {} +extension Google_Protobuf_FieldOptions.CType: @unchecked Sendable {} +extension Google_Protobuf_FieldOptions.JSType: @unchecked Sendable {} +extension Google_Protobuf_OneofOptions: @unchecked Sendable {} +extension Google_Protobuf_EnumOptions: @unchecked Sendable {} +extension Google_Protobuf_EnumValueOptions: @unchecked Sendable {} +extension Google_Protobuf_ServiceOptions: @unchecked Sendable {} +extension Google_Protobuf_MethodOptions: @unchecked Sendable {} +extension Google_Protobuf_MethodOptions.IdempotencyLevel: @unchecked Sendable {} +extension Google_Protobuf_UninterpretedOption: @unchecked Sendable {} +extension Google_Protobuf_UninterpretedOption.NamePart: @unchecked Sendable {} +extension Google_Protobuf_SourceCodeInfo: @unchecked Sendable {} +extension Google_Protobuf_SourceCodeInfo.Location: @unchecked Sendable {} +extension Google_Protobuf_GeneratedCodeInfo: @unchecked Sendable {} +extension Google_Protobuf_GeneratedCodeInfo.Annotation: @unchecked Sendable {} +extension Google_Protobuf_GeneratedCodeInfo.Annotation.Semantic: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_FileDescriptorSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FileDescriptorSet" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "file"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.file) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.file) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.file.isEmpty { + try visitor.visitRepeatedMessageField(value: self.file, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FileDescriptorSet, rhs: Google_Protobuf_FileDescriptorSet) -> Bool { + if lhs.file != rhs.file {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_FileDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FileDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "package"), + 3: .same(proto: "dependency"), + 10: .standard(proto: "public_dependency"), + 11: .standard(proto: "weak_dependency"), + 4: .standard(proto: "message_type"), + 5: .standard(proto: "enum_type"), + 6: .same(proto: "service"), + 7: .same(proto: "extension"), + 8: .same(proto: "options"), + 9: .standard(proto: "source_code_info"), + 12: .same(proto: "syntax"), + 13: .same(proto: "edition"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.messageType) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.enumType) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.service) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.`extension`) {return false} + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._package) }() + case 3: try { try decoder.decodeRepeatedStringField(value: &self.dependency) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.messageType) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.enumType) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.service) }() + case 7: try { try decoder.decodeRepeatedMessageField(value: &self.`extension`) }() + case 8: try { try decoder.decodeSingularMessageField(value: &self._options) }() + case 9: try { try decoder.decodeSingularMessageField(value: &self._sourceCodeInfo) }() + case 10: try { try decoder.decodeRepeatedInt32Field(value: &self.publicDependency) }() + case 11: try { try decoder.decodeRepeatedInt32Field(value: &self.weakDependency) }() + case 12: try { try decoder.decodeSingularStringField(value: &self._syntax) }() + case 13: try { try decoder.decodeSingularStringField(value: &self._edition) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._package { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + if !self.dependency.isEmpty { + try visitor.visitRepeatedStringField(value: self.dependency, fieldNumber: 3) + } + if !self.messageType.isEmpty { + try visitor.visitRepeatedMessageField(value: self.messageType, fieldNumber: 4) + } + if !self.enumType.isEmpty { + try visitor.visitRepeatedMessageField(value: self.enumType, fieldNumber: 5) + } + if !self.service.isEmpty { + try visitor.visitRepeatedMessageField(value: self.service, fieldNumber: 6) + } + if !self.`extension`.isEmpty { + try visitor.visitRepeatedMessageField(value: self.`extension`, fieldNumber: 7) + } + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() + try { if let v = self._sourceCodeInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + } }() + if !self.publicDependency.isEmpty { + try visitor.visitRepeatedInt32Field(value: self.publicDependency, fieldNumber: 10) + } + if !self.weakDependency.isEmpty { + try visitor.visitRepeatedInt32Field(value: self.weakDependency, fieldNumber: 11) + } + try { if let v = self._syntax { + try visitor.visitSingularStringField(value: v, fieldNumber: 12) + } }() + try { if let v = self._edition { + try visitor.visitSingularStringField(value: v, fieldNumber: 13) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FileDescriptorProto, rhs: Google_Protobuf_FileDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs._package != rhs._package {return false} + if lhs.dependency != rhs.dependency {return false} + if lhs.publicDependency != rhs.publicDependency {return false} + if lhs.weakDependency != rhs.weakDependency {return false} + if lhs.messageType != rhs.messageType {return false} + if lhs.enumType != rhs.enumType {return false} + if lhs.service != rhs.service {return false} + if lhs.`extension` != rhs.`extension` {return false} + if lhs._options != rhs._options {return false} + if lhs._sourceCodeInfo != rhs._sourceCodeInfo {return false} + if lhs._syntax != rhs._syntax {return false} + if lhs._edition != rhs._edition {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_DescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".DescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "field"), + 6: .same(proto: "extension"), + 3: .standard(proto: "nested_type"), + 4: .standard(proto: "enum_type"), + 5: .standard(proto: "extension_range"), + 8: .standard(proto: "oneof_decl"), + 7: .same(proto: "options"), + 9: .standard(proto: "reserved_range"), + 10: .standard(proto: "reserved_name"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.field) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.`extension`) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.nestedType) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.enumType) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.extensionRange) {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.oneofDecl) {return false} + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.field) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.nestedType) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.enumType) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.extensionRange) }() + case 6: try { try decoder.decodeRepeatedMessageField(value: &self.`extension`) }() + case 7: try { try decoder.decodeSingularMessageField(value: &self._options) }() + case 8: try { try decoder.decodeRepeatedMessageField(value: &self.oneofDecl) }() + case 9: try { try decoder.decodeRepeatedMessageField(value: &self.reservedRange) }() + case 10: try { try decoder.decodeRepeatedStringField(value: &self.reservedName) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + if !self.field.isEmpty { + try visitor.visitRepeatedMessageField(value: self.field, fieldNumber: 2) + } + if !self.nestedType.isEmpty { + try visitor.visitRepeatedMessageField(value: self.nestedType, fieldNumber: 3) + } + if !self.enumType.isEmpty { + try visitor.visitRepeatedMessageField(value: self.enumType, fieldNumber: 4) + } + if !self.extensionRange.isEmpty { + try visitor.visitRepeatedMessageField(value: self.extensionRange, fieldNumber: 5) + } + if !self.`extension`.isEmpty { + try visitor.visitRepeatedMessageField(value: self.`extension`, fieldNumber: 6) + } + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + if !self.oneofDecl.isEmpty { + try visitor.visitRepeatedMessageField(value: self.oneofDecl, fieldNumber: 8) + } + if !self.reservedRange.isEmpty { + try visitor.visitRepeatedMessageField(value: self.reservedRange, fieldNumber: 9) + } + if !self.reservedName.isEmpty { + try visitor.visitRepeatedStringField(value: self.reservedName, fieldNumber: 10) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_DescriptorProto, rhs: Google_Protobuf_DescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs.field != rhs.field {return false} + if lhs.`extension` != rhs.`extension` {return false} + if lhs.nestedType != rhs.nestedType {return false} + if lhs.enumType != rhs.enumType {return false} + if lhs.extensionRange != rhs.extensionRange {return false} + if lhs.oneofDecl != rhs.oneofDecl {return false} + if lhs._options != rhs._options {return false} + if lhs.reservedRange != rhs.reservedRange {return false} + if lhs.reservedName != rhs.reservedName {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_DescriptorProto.ExtensionRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_DescriptorProto.protoMessageName + ".ExtensionRange" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "start"), + 2: .same(proto: "end"), + 3: .same(proto: "options"), + ] + + public var isInitialized: Bool { + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._start) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._end) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._options) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._start { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._end { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_DescriptorProto.ExtensionRange, rhs: Google_Protobuf_DescriptorProto.ExtensionRange) -> Bool { + if lhs._start != rhs._start {return false} + if lhs._end != rhs._end {return false} + if lhs._options != rhs._options {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_DescriptorProto.ReservedRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_DescriptorProto.protoMessageName + ".ReservedRange" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "start"), + 2: .same(proto: "end"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._start) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._end) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._start { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._end { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_DescriptorProto.ReservedRange, rhs: Google_Protobuf_DescriptorProto.ReservedRange) -> Bool { + if lhs._start != rhs._start {return false} + if lhs._end != rhs._end {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_ExtensionRangeOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ExtensionRangeOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_ExtensionRangeOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_ExtensionRangeOptions, rhs: Google_Protobuf_ExtensionRangeOptions) -> Bool { + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_FieldDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FieldDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 3: .same(proto: "number"), + 4: .same(proto: "label"), + 5: .same(proto: "type"), + 6: .standard(proto: "type_name"), + 2: .same(proto: "extendee"), + 7: .standard(proto: "default_value"), + 9: .standard(proto: "oneof_index"), + 10: .standard(proto: "json_name"), + 8: .same(proto: "options"), + 17: .standard(proto: "proto3_optional"), + ] + + fileprivate class _StorageClass { + var _name: String? = nil + var _number: Int32? = nil + var _label: Google_Protobuf_FieldDescriptorProto.Label? = nil + var _type: Google_Protobuf_FieldDescriptorProto.TypeEnum? = nil + var _typeName: String? = nil + var _extendee: String? = nil + var _defaultValue: String? = nil + var _oneofIndex: Int32? = nil + var _jsonName: String? = nil + var _options: Google_Protobuf_FieldOptions? = nil + var _proto3Optional: Bool? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _name = source._name + _number = source._number + _label = source._label + _type = source._type + _typeName = source._typeName + _extendee = source._extendee + _defaultValue = source._defaultValue + _oneofIndex = source._oneofIndex + _jsonName = source._jsonName + _options = source._options + _proto3Optional = source._proto3Optional + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public var isInitialized: Bool { + return withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if let v = _storage._options, !v.isInitialized {return false} + return true + } + } + + public mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &_storage._name) }() + case 2: try { try decoder.decodeSingularStringField(value: &_storage._extendee) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &_storage._number) }() + case 4: try { try decoder.decodeSingularEnumField(value: &_storage._label) }() + case 5: try { try decoder.decodeSingularEnumField(value: &_storage._type) }() + case 6: try { try decoder.decodeSingularStringField(value: &_storage._typeName) }() + case 7: try { try decoder.decodeSingularStringField(value: &_storage._defaultValue) }() + case 8: try { try decoder.decodeSingularMessageField(value: &_storage._options) }() + case 9: try { try decoder.decodeSingularInt32Field(value: &_storage._oneofIndex) }() + case 10: try { try decoder.decodeSingularStringField(value: &_storage._jsonName) }() + case 17: try { try decoder.decodeSingularBoolField(value: &_storage._proto3Optional) }() + default: break + } + } + } + } + + public func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._extendee { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = _storage._number { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) + } }() + try { if let v = _storage._label { + try visitor.visitSingularEnumField(value: v, fieldNumber: 4) + } }() + try { if let v = _storage._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 5) + } }() + try { if let v = _storage._typeName { + try visitor.visitSingularStringField(value: v, fieldNumber: 6) + } }() + try { if let v = _storage._defaultValue { + try visitor.visitSingularStringField(value: v, fieldNumber: 7) + } }() + try { if let v = _storage._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() + try { if let v = _storage._oneofIndex { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 9) + } }() + try { if let v = _storage._jsonName { + try visitor.visitSingularStringField(value: v, fieldNumber: 10) + } }() + try { if let v = _storage._proto3Optional { + try visitor.visitSingularBoolField(value: v, fieldNumber: 17) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FieldDescriptorProto, rhs: Google_Protobuf_FieldDescriptorProto) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._name != rhs_storage._name {return false} + if _storage._number != rhs_storage._number {return false} + if _storage._label != rhs_storage._label {return false} + if _storage._type != rhs_storage._type {return false} + if _storage._typeName != rhs_storage._typeName {return false} + if _storage._extendee != rhs_storage._extendee {return false} + if _storage._defaultValue != rhs_storage._defaultValue {return false} + if _storage._oneofIndex != rhs_storage._oneofIndex {return false} + if _storage._jsonName != rhs_storage._jsonName {return false} + if _storage._options != rhs_storage._options {return false} + if _storage._proto3Optional != rhs_storage._proto3Optional {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_FieldDescriptorProto.TypeEnum: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "TYPE_DOUBLE"), + 2: .same(proto: "TYPE_FLOAT"), + 3: .same(proto: "TYPE_INT64"), + 4: .same(proto: "TYPE_UINT64"), + 5: .same(proto: "TYPE_INT32"), + 6: .same(proto: "TYPE_FIXED64"), + 7: .same(proto: "TYPE_FIXED32"), + 8: .same(proto: "TYPE_BOOL"), + 9: .same(proto: "TYPE_STRING"), + 10: .same(proto: "TYPE_GROUP"), + 11: .same(proto: "TYPE_MESSAGE"), + 12: .same(proto: "TYPE_BYTES"), + 13: .same(proto: "TYPE_UINT32"), + 14: .same(proto: "TYPE_ENUM"), + 15: .same(proto: "TYPE_SFIXED32"), + 16: .same(proto: "TYPE_SFIXED64"), + 17: .same(proto: "TYPE_SINT32"), + 18: .same(proto: "TYPE_SINT64"), + ] +} + +extension Google_Protobuf_FieldDescriptorProto.Label: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "LABEL_OPTIONAL"), + 2: .same(proto: "LABEL_REQUIRED"), + 3: .same(proto: "LABEL_REPEATED"), + ] +} + +extension Google_Protobuf_OneofDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".OneofDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "options"), + ] + + public var isInitialized: Bool { + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._options) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_OneofDescriptorProto, rhs: Google_Protobuf_OneofDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs._options != rhs._options {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_EnumDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EnumDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "value"), + 3: .same(proto: "options"), + 4: .standard(proto: "reserved_range"), + 5: .standard(proto: "reserved_name"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.value) {return false} + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.value) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._options) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.reservedRange) }() + case 5: try { try decoder.decodeRepeatedStringField(value: &self.reservedName) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + if !self.value.isEmpty { + try visitor.visitRepeatedMessageField(value: self.value, fieldNumber: 2) + } + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + if !self.reservedRange.isEmpty { + try visitor.visitRepeatedMessageField(value: self.reservedRange, fieldNumber: 4) + } + if !self.reservedName.isEmpty { + try visitor.visitRepeatedStringField(value: self.reservedName, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumDescriptorProto, rhs: Google_Protobuf_EnumDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs.value != rhs.value {return false} + if lhs._options != rhs._options {return false} + if lhs.reservedRange != rhs.reservedRange {return false} + if lhs.reservedName != rhs.reservedName {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_EnumDescriptorProto.EnumReservedRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_EnumDescriptorProto.protoMessageName + ".EnumReservedRange" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "start"), + 2: .same(proto: "end"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._start) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._end) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._start { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._end { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumDescriptorProto.EnumReservedRange, rhs: Google_Protobuf_EnumDescriptorProto.EnumReservedRange) -> Bool { + if lhs._start != rhs._start {return false} + if lhs._end != rhs._end {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_EnumValueDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EnumValueDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "number"), + 3: .same(proto: "options"), + ] + + public var isInitialized: Bool { + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._number) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._options) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._number { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumValueDescriptorProto, rhs: Google_Protobuf_EnumValueDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs._number != rhs._number {return false} + if lhs._options != rhs._options {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_ServiceDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ServiceDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "method"), + 3: .same(proto: "options"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.method) {return false} + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.method) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._options) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + if !self.method.isEmpty { + try visitor.visitRepeatedMessageField(value: self.method, fieldNumber: 2) + } + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_ServiceDescriptorProto, rhs: Google_Protobuf_ServiceDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs.method != rhs.method {return false} + if lhs._options != rhs._options {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_MethodDescriptorProto: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".MethodDescriptorProto" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .standard(proto: "input_type"), + 3: .standard(proto: "output_type"), + 4: .same(proto: "options"), + 5: .standard(proto: "client_streaming"), + 6: .standard(proto: "server_streaming"), + ] + + public var isInitialized: Bool { + if let v = self._options, !v.isInitialized {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._inputType) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._outputType) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._options) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self._clientStreaming) }() + case 6: try { try decoder.decodeSingularBoolField(value: &self._serverStreaming) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._inputType { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._outputType { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + try { if let v = self._options { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try { if let v = self._clientStreaming { + try visitor.visitSingularBoolField(value: v, fieldNumber: 5) + } }() + try { if let v = self._serverStreaming { + try visitor.visitSingularBoolField(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_MethodDescriptorProto, rhs: Google_Protobuf_MethodDescriptorProto) -> Bool { + if lhs._name != rhs._name {return false} + if lhs._inputType != rhs._inputType {return false} + if lhs._outputType != rhs._outputType {return false} + if lhs._options != rhs._options {return false} + if lhs._clientStreaming != rhs._clientStreaming {return false} + if lhs._serverStreaming != rhs._serverStreaming {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_FileOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FileOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "java_package"), + 8: .standard(proto: "java_outer_classname"), + 10: .standard(proto: "java_multiple_files"), + 20: .standard(proto: "java_generate_equals_and_hash"), + 27: .standard(proto: "java_string_check_utf8"), + 9: .standard(proto: "optimize_for"), + 11: .standard(proto: "go_package"), + 16: .standard(proto: "cc_generic_services"), + 17: .standard(proto: "java_generic_services"), + 18: .standard(proto: "py_generic_services"), + 42: .standard(proto: "php_generic_services"), + 23: .same(proto: "deprecated"), + 31: .standard(proto: "cc_enable_arenas"), + 36: .standard(proto: "objc_class_prefix"), + 37: .standard(proto: "csharp_namespace"), + 39: .standard(proto: "swift_prefix"), + 40: .standard(proto: "php_class_prefix"), + 41: .standard(proto: "php_namespace"), + 44: .standard(proto: "php_metadata_namespace"), + 45: .standard(proto: "ruby_package"), + 999: .standard(proto: "uninterpreted_option"), + ] + + fileprivate class _StorageClass { + var _javaPackage: String? = nil + var _javaOuterClassname: String? = nil + var _javaMultipleFiles: Bool? = nil + var _javaGenerateEqualsAndHash: Bool? = nil + var _javaStringCheckUtf8: Bool? = nil + var _optimizeFor: Google_Protobuf_FileOptions.OptimizeMode? = nil + var _goPackage: String? = nil + var _ccGenericServices: Bool? = nil + var _javaGenericServices: Bool? = nil + var _pyGenericServices: Bool? = nil + var _phpGenericServices: Bool? = nil + var _deprecated: Bool? = nil + var _ccEnableArenas: Bool? = nil + var _objcClassPrefix: String? = nil + var _csharpNamespace: String? = nil + var _swiftPrefix: String? = nil + var _phpClassPrefix: String? = nil + var _phpNamespace: String? = nil + var _phpMetadataNamespace: String? = nil + var _rubyPackage: String? = nil + var _uninterpretedOption: [Google_Protobuf_UninterpretedOption] = [] + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _javaPackage = source._javaPackage + _javaOuterClassname = source._javaOuterClassname + _javaMultipleFiles = source._javaMultipleFiles + _javaGenerateEqualsAndHash = source._javaGenerateEqualsAndHash + _javaStringCheckUtf8 = source._javaStringCheckUtf8 + _optimizeFor = source._optimizeFor + _goPackage = source._goPackage + _ccGenericServices = source._ccGenericServices + _javaGenericServices = source._javaGenericServices + _pyGenericServices = source._pyGenericServices + _phpGenericServices = source._phpGenericServices + _deprecated = source._deprecated + _ccEnableArenas = source._ccEnableArenas + _objcClassPrefix = source._objcClassPrefix + _csharpNamespace = source._csharpNamespace + _swiftPrefix = source._swiftPrefix + _phpClassPrefix = source._phpClassPrefix + _phpNamespace = source._phpNamespace + _phpMetadataNamespace = source._phpMetadataNamespace + _rubyPackage = source._rubyPackage + _uninterpretedOption = source._uninterpretedOption + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + return withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if !SwiftProtobuf.Internal.areAllInitialized(_storage._uninterpretedOption) {return false} + return true + } + } + + public mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &_storage._javaPackage) }() + case 8: try { try decoder.decodeSingularStringField(value: &_storage._javaOuterClassname) }() + case 9: try { try decoder.decodeSingularEnumField(value: &_storage._optimizeFor) }() + case 10: try { try decoder.decodeSingularBoolField(value: &_storage._javaMultipleFiles) }() + case 11: try { try decoder.decodeSingularStringField(value: &_storage._goPackage) }() + case 16: try { try decoder.decodeSingularBoolField(value: &_storage._ccGenericServices) }() + case 17: try { try decoder.decodeSingularBoolField(value: &_storage._javaGenericServices) }() + case 18: try { try decoder.decodeSingularBoolField(value: &_storage._pyGenericServices) }() + case 20: try { try decoder.decodeSingularBoolField(value: &_storage._javaGenerateEqualsAndHash) }() + case 23: try { try decoder.decodeSingularBoolField(value: &_storage._deprecated) }() + case 27: try { try decoder.decodeSingularBoolField(value: &_storage._javaStringCheckUtf8) }() + case 31: try { try decoder.decodeSingularBoolField(value: &_storage._ccEnableArenas) }() + case 36: try { try decoder.decodeSingularStringField(value: &_storage._objcClassPrefix) }() + case 37: try { try decoder.decodeSingularStringField(value: &_storage._csharpNamespace) }() + case 39: try { try decoder.decodeSingularStringField(value: &_storage._swiftPrefix) }() + case 40: try { try decoder.decodeSingularStringField(value: &_storage._phpClassPrefix) }() + case 41: try { try decoder.decodeSingularStringField(value: &_storage._phpNamespace) }() + case 42: try { try decoder.decodeSingularBoolField(value: &_storage._phpGenericServices) }() + case 44: try { try decoder.decodeSingularStringField(value: &_storage._phpMetadataNamespace) }() + case 45: try { try decoder.decodeSingularStringField(value: &_storage._rubyPackage) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &_storage._uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_FileOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + } + + public func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._javaPackage { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._javaOuterClassname { + try visitor.visitSingularStringField(value: v, fieldNumber: 8) + } }() + try { if let v = _storage._optimizeFor { + try visitor.visitSingularEnumField(value: v, fieldNumber: 9) + } }() + try { if let v = _storage._javaMultipleFiles { + try visitor.visitSingularBoolField(value: v, fieldNumber: 10) + } }() + try { if let v = _storage._goPackage { + try visitor.visitSingularStringField(value: v, fieldNumber: 11) + } }() + try { if let v = _storage._ccGenericServices { + try visitor.visitSingularBoolField(value: v, fieldNumber: 16) + } }() + try { if let v = _storage._javaGenericServices { + try visitor.visitSingularBoolField(value: v, fieldNumber: 17) + } }() + try { if let v = _storage._pyGenericServices { + try visitor.visitSingularBoolField(value: v, fieldNumber: 18) + } }() + try { if let v = _storage._javaGenerateEqualsAndHash { + try visitor.visitSingularBoolField(value: v, fieldNumber: 20) + } }() + try { if let v = _storage._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 23) + } }() + try { if let v = _storage._javaStringCheckUtf8 { + try visitor.visitSingularBoolField(value: v, fieldNumber: 27) + } }() + try { if let v = _storage._ccEnableArenas { + try visitor.visitSingularBoolField(value: v, fieldNumber: 31) + } }() + try { if let v = _storage._objcClassPrefix { + try visitor.visitSingularStringField(value: v, fieldNumber: 36) + } }() + try { if let v = _storage._csharpNamespace { + try visitor.visitSingularStringField(value: v, fieldNumber: 37) + } }() + try { if let v = _storage._swiftPrefix { + try visitor.visitSingularStringField(value: v, fieldNumber: 39) + } }() + try { if let v = _storage._phpClassPrefix { + try visitor.visitSingularStringField(value: v, fieldNumber: 40) + } }() + try { if let v = _storage._phpNamespace { + try visitor.visitSingularStringField(value: v, fieldNumber: 41) + } }() + try { if let v = _storage._phpGenericServices { + try visitor.visitSingularBoolField(value: v, fieldNumber: 42) + } }() + try { if let v = _storage._phpMetadataNamespace { + try visitor.visitSingularStringField(value: v, fieldNumber: 44) + } }() + try { if let v = _storage._rubyPackage { + try visitor.visitSingularStringField(value: v, fieldNumber: 45) + } }() + if !_storage._uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FileOptions, rhs: Google_Protobuf_FileOptions) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._javaPackage != rhs_storage._javaPackage {return false} + if _storage._javaOuterClassname != rhs_storage._javaOuterClassname {return false} + if _storage._javaMultipleFiles != rhs_storage._javaMultipleFiles {return false} + if _storage._javaGenerateEqualsAndHash != rhs_storage._javaGenerateEqualsAndHash {return false} + if _storage._javaStringCheckUtf8 != rhs_storage._javaStringCheckUtf8 {return false} + if _storage._optimizeFor != rhs_storage._optimizeFor {return false} + if _storage._goPackage != rhs_storage._goPackage {return false} + if _storage._ccGenericServices != rhs_storage._ccGenericServices {return false} + if _storage._javaGenericServices != rhs_storage._javaGenericServices {return false} + if _storage._pyGenericServices != rhs_storage._pyGenericServices {return false} + if _storage._phpGenericServices != rhs_storage._phpGenericServices {return false} + if _storage._deprecated != rhs_storage._deprecated {return false} + if _storage._ccEnableArenas != rhs_storage._ccEnableArenas {return false} + if _storage._objcClassPrefix != rhs_storage._objcClassPrefix {return false} + if _storage._csharpNamespace != rhs_storage._csharpNamespace {return false} + if _storage._swiftPrefix != rhs_storage._swiftPrefix {return false} + if _storage._phpClassPrefix != rhs_storage._phpClassPrefix {return false} + if _storage._phpNamespace != rhs_storage._phpNamespace {return false} + if _storage._phpMetadataNamespace != rhs_storage._phpMetadataNamespace {return false} + if _storage._rubyPackage != rhs_storage._rubyPackage {return false} + if _storage._uninterpretedOption != rhs_storage._uninterpretedOption {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_FileOptions.OptimizeMode: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "SPEED"), + 2: .same(proto: "CODE_SIZE"), + 3: .same(proto: "LITE_RUNTIME"), + ] +} + +extension Google_Protobuf_MessageOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".MessageOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "message_set_wire_format"), + 2: .standard(proto: "no_standard_descriptor_accessor"), + 3: .same(proto: "deprecated"), + 7: .standard(proto: "map_entry"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self._messageSetWireFormat) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._noStandardDescriptorAccessor) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 7: try { try decoder.decodeSingularBoolField(value: &self._mapEntry) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_MessageOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._messageSetWireFormat { + try visitor.visitSingularBoolField(value: v, fieldNumber: 1) + } }() + try { if let v = self._noStandardDescriptorAccessor { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 3) + } }() + try { if let v = self._mapEntry { + try visitor.visitSingularBoolField(value: v, fieldNumber: 7) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_MessageOptions, rhs: Google_Protobuf_MessageOptions) -> Bool { + if lhs._messageSetWireFormat != rhs._messageSetWireFormat {return false} + if lhs._noStandardDescriptorAccessor != rhs._noStandardDescriptorAccessor {return false} + if lhs._deprecated != rhs._deprecated {return false} + if lhs._mapEntry != rhs._mapEntry {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_FieldOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FieldOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ctype"), + 2: .same(proto: "packed"), + 6: .same(proto: "jstype"), + 5: .same(proto: "lazy"), + 15: .standard(proto: "unverified_lazy"), + 3: .same(proto: "deprecated"), + 10: .same(proto: "weak"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._ctype) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._packed) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self._lazy) }() + case 6: try { try decoder.decodeSingularEnumField(value: &self._jstype) }() + case 10: try { try decoder.decodeSingularBoolField(value: &self._weak) }() + case 15: try { try decoder.decodeSingularBoolField(value: &self._unverifiedLazy) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_FieldOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ctype { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._packed { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 3) + } }() + try { if let v = self._lazy { + try visitor.visitSingularBoolField(value: v, fieldNumber: 5) + } }() + try { if let v = self._jstype { + try visitor.visitSingularEnumField(value: v, fieldNumber: 6) + } }() + try { if let v = self._weak { + try visitor.visitSingularBoolField(value: v, fieldNumber: 10) + } }() + try { if let v = self._unverifiedLazy { + try visitor.visitSingularBoolField(value: v, fieldNumber: 15) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FieldOptions, rhs: Google_Protobuf_FieldOptions) -> Bool { + if lhs._ctype != rhs._ctype {return false} + if lhs._packed != rhs._packed {return false} + if lhs._jstype != rhs._jstype {return false} + if lhs._lazy != rhs._lazy {return false} + if lhs._unverifiedLazy != rhs._unverifiedLazy {return false} + if lhs._deprecated != rhs._deprecated {return false} + if lhs._weak != rhs._weak {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_FieldOptions.CType: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "STRING"), + 1: .same(proto: "CORD"), + 2: .same(proto: "STRING_PIECE"), + ] +} + +extension Google_Protobuf_FieldOptions.JSType: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "JS_NORMAL"), + 1: .same(proto: "JS_STRING"), + 2: .same(proto: "JS_NUMBER"), + ] +} + +extension Google_Protobuf_OneofOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".OneofOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_OneofOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_OneofOptions, rhs: Google_Protobuf_OneofOptions) -> Bool { + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_EnumOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EnumOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 2: .standard(proto: "allow_alias"), + 3: .same(proto: "deprecated"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 2: try { try decoder.decodeSingularBoolField(value: &self._allowAlias) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_EnumOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._allowAlias { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 3) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumOptions, rhs: Google_Protobuf_EnumOptions) -> Bool { + if lhs._allowAlias != rhs._allowAlias {return false} + if lhs._deprecated != rhs._deprecated {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_EnumValueOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EnumValueOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "deprecated"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_EnumValueOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 1) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumValueOptions, rhs: Google_Protobuf_EnumValueOptions) -> Bool { + if lhs._deprecated != rhs._deprecated {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_ServiceOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ServiceOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 33: .same(proto: "deprecated"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 33: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_ServiceOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 33) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_ServiceOptions, rhs: Google_Protobuf_ServiceOptions) -> Bool { + if lhs._deprecated != rhs._deprecated {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_MethodOptions: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".MethodOptions" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 33: .same(proto: "deprecated"), + 34: .standard(proto: "idempotency_level"), + 999: .standard(proto: "uninterpreted_option"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + if !SwiftProtobuf.Internal.areAllInitialized(self.uninterpretedOption) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 33: try { try decoder.decodeSingularBoolField(value: &self._deprecated) }() + case 34: try { try decoder.decodeSingularEnumField(value: &self._idempotencyLevel) }() + case 999: try { try decoder.decodeRepeatedMessageField(value: &self.uninterpretedOption) }() + case 1000..<536870912: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: Google_Protobuf_MethodOptions.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._deprecated { + try visitor.visitSingularBoolField(value: v, fieldNumber: 33) + } }() + try { if let v = self._idempotencyLevel { + try visitor.visitSingularEnumField(value: v, fieldNumber: 34) + } }() + if !self.uninterpretedOption.isEmpty { + try visitor.visitRepeatedMessageField(value: self.uninterpretedOption, fieldNumber: 999) + } + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1000, end: 536870912) + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_MethodOptions, rhs: Google_Protobuf_MethodOptions) -> Bool { + if lhs._deprecated != rhs._deprecated {return false} + if lhs._idempotencyLevel != rhs._idempotencyLevel {return false} + if lhs.uninterpretedOption != rhs.uninterpretedOption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension Google_Protobuf_MethodOptions.IdempotencyLevel: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "IDEMPOTENCY_UNKNOWN"), + 1: .same(proto: "NO_SIDE_EFFECTS"), + 2: .same(proto: "IDEMPOTENT"), + ] +} + +extension Google_Protobuf_UninterpretedOption: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".UninterpretedOption" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 2: .same(proto: "name"), + 3: .standard(proto: "identifier_value"), + 4: .standard(proto: "positive_int_value"), + 5: .standard(proto: "negative_int_value"), + 6: .standard(proto: "double_value"), + 7: .standard(proto: "string_value"), + 8: .standard(proto: "aggregate_value"), + ] + + public var isInitialized: Bool { + if !SwiftProtobuf.Internal.areAllInitialized(self.name) {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.name) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._identifierValue) }() + case 4: try { try decoder.decodeSingularUInt64Field(value: &self._positiveIntValue) }() + case 5: try { try decoder.decodeSingularInt64Field(value: &self._negativeIntValue) }() + case 6: try { try decoder.decodeSingularDoubleField(value: &self._doubleValue) }() + case 7: try { try decoder.decodeSingularBytesField(value: &self._stringValue) }() + case 8: try { try decoder.decodeSingularStringField(value: &self._aggregateValue) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitRepeatedMessageField(value: self.name, fieldNumber: 2) + } + try { if let v = self._identifierValue { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + try { if let v = self._positiveIntValue { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._negativeIntValue { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) + } }() + try { if let v = self._doubleValue { + try visitor.visitSingularDoubleField(value: v, fieldNumber: 6) + } }() + try { if let v = self._stringValue { + try visitor.visitSingularBytesField(value: v, fieldNumber: 7) + } }() + try { if let v = self._aggregateValue { + try visitor.visitSingularStringField(value: v, fieldNumber: 8) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_UninterpretedOption, rhs: Google_Protobuf_UninterpretedOption) -> Bool { + if lhs.name != rhs.name {return false} + if lhs._identifierValue != rhs._identifierValue {return false} + if lhs._positiveIntValue != rhs._positiveIntValue {return false} + if lhs._negativeIntValue != rhs._negativeIntValue {return false} + if lhs._doubleValue != rhs._doubleValue {return false} + if lhs._stringValue != rhs._stringValue {return false} + if lhs._aggregateValue != rhs._aggregateValue {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_UninterpretedOption.NamePart: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_UninterpretedOption.protoMessageName + ".NamePart" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "name_part"), + 2: .standard(proto: "is_extension"), + ] + + public var isInitialized: Bool { + if self._namePart == nil {return false} + if self._isExtension == nil {return false} + return true + } + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._namePart) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._isExtension) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._namePart { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._isExtension { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_UninterpretedOption.NamePart, rhs: Google_Protobuf_UninterpretedOption.NamePart) -> Bool { + if lhs._namePart != rhs._namePart {return false} + if lhs._isExtension != rhs._isExtension {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_SourceCodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SourceCodeInfo" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "location"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.location) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.location.isEmpty { + try visitor.visitRepeatedMessageField(value: self.location, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_SourceCodeInfo, rhs: Google_Protobuf_SourceCodeInfo) -> Bool { + if lhs.location != rhs.location {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_SourceCodeInfo.Location: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_SourceCodeInfo.protoMessageName + ".Location" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "path"), + 2: .same(proto: "span"), + 3: .standard(proto: "leading_comments"), + 4: .standard(proto: "trailing_comments"), + 6: .standard(proto: "leading_detached_comments"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.path) }() + case 2: try { try decoder.decodeRepeatedInt32Field(value: &self.span) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._leadingComments) }() + case 4: try { try decoder.decodeSingularStringField(value: &self._trailingComments) }() + case 6: try { try decoder.decodeRepeatedStringField(value: &self.leadingDetachedComments) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.path.isEmpty { + try visitor.visitPackedInt32Field(value: self.path, fieldNumber: 1) + } + if !self.span.isEmpty { + try visitor.visitPackedInt32Field(value: self.span, fieldNumber: 2) + } + try { if let v = self._leadingComments { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + try { if let v = self._trailingComments { + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + } }() + if !self.leadingDetachedComments.isEmpty { + try visitor.visitRepeatedStringField(value: self.leadingDetachedComments, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_SourceCodeInfo.Location, rhs: Google_Protobuf_SourceCodeInfo.Location) -> Bool { + if lhs.path != rhs.path {return false} + if lhs.span != rhs.span {return false} + if lhs._leadingComments != rhs._leadingComments {return false} + if lhs._trailingComments != rhs._trailingComments {return false} + if lhs.leadingDetachedComments != rhs.leadingDetachedComments {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_GeneratedCodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".GeneratedCodeInfo" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "annotation"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.annotation) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.annotation.isEmpty { + try visitor.visitRepeatedMessageField(value: self.annotation, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_GeneratedCodeInfo, rhs: Google_Protobuf_GeneratedCodeInfo) -> Bool { + if lhs.annotation != rhs.annotation {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_GeneratedCodeInfo.Annotation: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = Google_Protobuf_GeneratedCodeInfo.protoMessageName + ".Annotation" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "path"), + 2: .standard(proto: "source_file"), + 3: .same(proto: "begin"), + 4: .same(proto: "end"), + 5: .same(proto: "semantic"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.path) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._sourceFile) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self._begin) }() + case 4: try { try decoder.decodeSingularInt32Field(value: &self._end) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self._semantic) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.path.isEmpty { + try visitor.visitPackedInt32Field(value: self.path, fieldNumber: 1) + } + try { if let v = self._sourceFile { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._begin { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) + } }() + try { if let v = self._end { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._semantic { + try visitor.visitSingularEnumField(value: v, fieldNumber: 5) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_GeneratedCodeInfo.Annotation, rhs: Google_Protobuf_GeneratedCodeInfo.Annotation) -> Bool { + if lhs.path != rhs.path {return false} + if lhs._sourceFile != rhs._sourceFile {return false} + if lhs._begin != rhs._begin {return false} + if lhs._end != rhs._end {return false} + if lhs._semantic != rhs._semantic {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_GeneratedCodeInfo.Annotation.Semantic: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "NONE"), + 1: .same(proto: "SET"), + 2: .same(proto: "ALIAS"), + ] +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/duration.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/duration.pb.swift new file mode 100644 index 00000000..bbde204b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/duration.pb.swift @@ -0,0 +1,177 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/duration.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// A Duration represents a signed, fixed-length span of time represented +/// as a count of seconds and fractions of seconds at nanosecond +/// resolution. It is independent of any calendar and concepts like "day" +/// or "month". It is related to Timestamp in that the difference between +/// two Timestamp values is a Duration and it can be added or subtracted +/// from a Timestamp. Range is approximately +-10,000 years. +/// +/// # Examples +/// +/// Example 1: Compute Duration from two Timestamps in pseudo code. +/// +/// Timestamp start = ...; +/// Timestamp end = ...; +/// Duration duration = ...; +/// +/// duration.seconds = end.seconds - start.seconds; +/// duration.nanos = end.nanos - start.nanos; +/// +/// if (duration.seconds < 0 && duration.nanos > 0) { +/// duration.seconds += 1; +/// duration.nanos -= 1000000000; +/// } else if (duration.seconds > 0 && duration.nanos < 0) { +/// duration.seconds -= 1; +/// duration.nanos += 1000000000; +/// } +/// +/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +/// +/// Timestamp start = ...; +/// Duration duration = ...; +/// Timestamp end = ...; +/// +/// end.seconds = start.seconds + duration.seconds; +/// end.nanos = start.nanos + duration.nanos; +/// +/// if (end.nanos < 0) { +/// end.seconds -= 1; +/// end.nanos += 1000000000; +/// } else if (end.nanos >= 1000000000) { +/// end.seconds += 1; +/// end.nanos -= 1000000000; +/// } +/// +/// Example 3: Compute Duration from datetime.timedelta in Python. +/// +/// td = datetime.timedelta(days=3, minutes=10) +/// duration = Duration() +/// duration.FromTimedelta(td) +/// +/// # JSON Mapping +/// +/// In JSON format, the Duration type is encoded as a string rather than an +/// object, where the string ends in the suffix "s" (indicating seconds) and +/// is preceded by the number of seconds, with nanoseconds expressed as +/// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +/// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +/// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +/// microsecond should be expressed in JSON format as "3.000001s". +public struct Google_Protobuf_Duration { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Signed seconds of the span of time. Must be from -315,576,000,000 + /// to +315,576,000,000 inclusive. Note: these bounds are computed from: + /// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + public var seconds: Int64 = 0 + + /// Signed fractions of a second at nanosecond resolution of the span + /// of time. Durations less than one second are represented with a 0 + /// `seconds` field and a positive or negative `nanos` field. For durations + /// of one second or more, a non-zero value for the `nanos` field must be + /// of the same sign as the `seconds` field. Must be from -999,999,999 + /// to +999,999,999 inclusive. + public var nanos: Int32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Duration: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Duration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Duration" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "seconds"), + 2: .same(proto: "nanos"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt64Field(value: &self.seconds) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.nanos) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.seconds != 0 { + try visitor.visitSingularInt64Field(value: self.seconds, fieldNumber: 1) + } + if self.nanos != 0 { + try visitor.visitSingularInt32Field(value: self.nanos, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Duration, rhs: Google_Protobuf_Duration) -> Bool { + if lhs.seconds != rhs.seconds {return false} + if lhs.nanos != rhs.nanos {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/empty.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/empty.pb.swift new file mode 100644 index 00000000..0eff5267 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/empty.pb.swift @@ -0,0 +1,94 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/empty.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// A generic empty message that you can re-use to avoid defining duplicated +/// empty messages in your APIs. A typical example is to use it as the request +/// or the response type of an API method. For instance: +/// +/// service Foo { +/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +/// } +public struct Google_Protobuf_Empty { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Empty: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Empty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Empty" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Empty, rhs: Google_Protobuf_Empty) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/field_mask.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/field_mask.pb.swift new file mode 100644 index 00000000..31128db4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/field_mask.pb.swift @@ -0,0 +1,302 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/field_mask.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// `FieldMask` represents a set of symbolic field paths, for example: +/// +/// paths: "f.a" +/// paths: "f.b.d" +/// +/// Here `f` represents a field in some root message, `a` and `b` +/// fields in the message found in `f`, and `d` a field found in the +/// message in `f.b`. +/// +/// Field masks are used to specify a subset of fields that should be +/// returned by a get operation or modified by an update operation. +/// Field masks also have a custom JSON encoding (see below). +/// +/// # Field Masks in Projections +/// +/// When used in the context of a projection, a response message or +/// sub-message is filtered by the API to only contain those fields as +/// specified in the mask. For example, if the mask in the previous +/// example is applied to a response message as follows: +/// +/// f { +/// a : 22 +/// b { +/// d : 1 +/// x : 2 +/// } +/// y : 13 +/// } +/// z: 8 +/// +/// The result will not contain specific values for fields x,y and z +/// (their value will be set to the default, and omitted in proto text +/// output): +/// +/// +/// f { +/// a : 22 +/// b { +/// d : 1 +/// } +/// } +/// +/// A repeated field is not allowed except at the last position of a +/// paths string. +/// +/// If a FieldMask object is not present in a get operation, the +/// operation applies to all fields (as if a FieldMask of all fields +/// had been specified). +/// +/// Note that a field mask does not necessarily apply to the +/// top-level response message. In case of a REST get operation, the +/// field mask applies directly to the response, but in case of a REST +/// list operation, the mask instead applies to each individual message +/// in the returned resource list. In case of a REST custom method, +/// other definitions may be used. Where the mask applies will be +/// clearly documented together with its declaration in the API. In +/// any case, the effect on the returned resource/resources is required +/// behavior for APIs. +/// +/// # Field Masks in Update Operations +/// +/// A field mask in update operations specifies which fields of the +/// targeted resource are going to be updated. The API is required +/// to only change the values of the fields as specified in the mask +/// and leave the others untouched. If a resource is passed in to +/// describe the updated values, the API ignores the values of all +/// fields not covered by the mask. +/// +/// If a repeated field is specified for an update operation, new values will +/// be appended to the existing repeated field in the target resource. Note that +/// a repeated field is only allowed in the last position of a `paths` string. +/// +/// If a sub-message is specified in the last position of the field mask for an +/// update operation, then new value will be merged into the existing sub-message +/// in the target resource. +/// +/// For example, given the target message: +/// +/// f { +/// b { +/// d: 1 +/// x: 2 +/// } +/// c: [1] +/// } +/// +/// And an update message: +/// +/// f { +/// b { +/// d: 10 +/// } +/// c: [2] +/// } +/// +/// then if the field mask is: +/// +/// paths: ["f.b", "f.c"] +/// +/// then the result will be: +/// +/// f { +/// b { +/// d: 10 +/// x: 2 +/// } +/// c: [1, 2] +/// } +/// +/// An implementation may provide options to override this default behavior for +/// repeated and message fields. +/// +/// In order to reset a field's value to the default, the field must +/// be in the mask and set to the default value in the provided resource. +/// Hence, in order to reset all fields of a resource, provide a default +/// instance of the resource and set all fields in the mask, or do +/// not provide a mask as described below. +/// +/// If a field mask is not present on update, the operation applies to +/// all fields (as if a field mask of all fields has been specified). +/// Note that in the presence of schema evolution, this may mean that +/// fields the client does not know and has therefore not filled into +/// the request will be reset to their default. If this is unwanted +/// behavior, a specific service may require a client to always specify +/// a field mask, producing an error if not. +/// +/// As with get operations, the location of the resource which +/// describes the updated values in the request message depends on the +/// operation kind. In any case, the effect of the field mask is +/// required to be honored by the API. +/// +/// ## Considerations for HTTP REST +/// +/// The HTTP kind of an update operation which uses a field mask must +/// be set to PATCH instead of PUT in order to satisfy HTTP semantics +/// (PUT must only be used for full updates). +/// +/// # JSON Encoding of Field Masks +/// +/// In JSON, a field mask is encoded as a single string where paths are +/// separated by a comma. Fields name in each path are converted +/// to/from lower-camel naming conventions. +/// +/// As an example, consider the following message declarations: +/// +/// message Profile { +/// User user = 1; +/// Photo photo = 2; +/// } +/// message User { +/// string display_name = 1; +/// string address = 2; +/// } +/// +/// In proto a field mask for `Profile` may look as such: +/// +/// mask { +/// paths: "user.display_name" +/// paths: "photo" +/// } +/// +/// In JSON, the same mask is represented as below: +/// +/// { +/// mask: "user.displayName,photo" +/// } +/// +/// # Field Masks and Oneof Fields +/// +/// Field masks treat fields in oneofs just as regular fields. Consider the +/// following message: +/// +/// message SampleMessage { +/// oneof test_oneof { +/// string name = 4; +/// SubMessage sub_message = 9; +/// } +/// } +/// +/// The field mask can be: +/// +/// mask { +/// paths: "name" +/// } +/// +/// Or: +/// +/// mask { +/// paths: "sub_message" +/// } +/// +/// Note that oneof type names ("test_oneof" in this case) cannot be used in +/// paths. +/// +/// ## Field Mask Verification +/// +/// The implementation of any API method which has a FieldMask type field in the +/// request should verify the included field paths, and return an +/// `INVALID_ARGUMENT` error if any path is unmappable. +public struct Google_Protobuf_FieldMask { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The set of field mask paths. + public var paths: [String] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_FieldMask: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_FieldMask: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FieldMask" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "paths"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedStringField(value: &self.paths) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.paths.isEmpty { + try visitor.visitRepeatedStringField(value: self.paths, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FieldMask, rhs: Google_Protobuf_FieldMask) -> Bool { + if lhs.paths != rhs.paths {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/source_context.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/source_context.pb.swift new file mode 100644 index 00000000..f7070bb4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/source_context.pb.swift @@ -0,0 +1,106 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/source_context.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// `SourceContext` represents information about the source of a +/// protobuf element, like the file in which it is defined. +public struct Google_Protobuf_SourceContext { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The path-qualified name of the .proto file that contained the associated + /// protobuf element. For example: `"google/protobuf/source_context.proto"`. + public var fileName: String = String() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_SourceContext: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_SourceContext: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".SourceContext" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "file_name"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.fileName) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.fileName.isEmpty { + try visitor.visitSingularStringField(value: self.fileName, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_SourceContext, rhs: Google_Protobuf_SourceContext) -> Bool { + if lhs.fileName != rhs.fileName {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/struct.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/struct.pb.swift new file mode 100644 index 00000000..b6049b2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/struct.pb.swift @@ -0,0 +1,457 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/struct.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// `NullValue` is a singleton enumeration to represent the null value for the +/// `Value` type union. +/// +/// The JSON representation for `NullValue` is JSON `null`. +public enum Google_Protobuf_NullValue: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Null value. + case nullValue // = 0 + case UNRECOGNIZED(Int) + + public init() { + self = .nullValue + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .nullValue + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .nullValue: return 0 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Google_Protobuf_NullValue: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static var allCases: [Google_Protobuf_NullValue] = [ + .nullValue, + ] +} + +#endif // swift(>=4.2) + +/// `Struct` represents a structured data value, consisting of fields +/// which map to dynamically typed values. In some languages, `Struct` +/// might be supported by a native representation. For example, in +/// scripting languages like JS a struct is represented as an +/// object. The details of that representation are described together +/// with the proto support for the language. +/// +/// The JSON representation for `Struct` is JSON object. +public struct Google_Protobuf_Struct { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Unordered map of dynamically typed values. + public var fields: Dictionary = [:] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// `Value` represents a dynamically typed value which can be either +/// null, a number, a string, a boolean, a recursive struct value, or a +/// list of values. A producer of value is expected to set one of these +/// variants. Absence of any variant indicates an error. +/// +/// The JSON representation for `Value` is JSON value. +public struct Google_Protobuf_Value { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The kind of value. + public var kind: Google_Protobuf_Value.OneOf_Kind? = nil + + /// Represents a null value. + public var nullValue: Google_Protobuf_NullValue { + get { + if case .nullValue(let v)? = kind {return v} + return .nullValue + } + set {kind = .nullValue(newValue)} + } + + /// Represents a double value. + public var numberValue: Double { + get { + if case .numberValue(let v)? = kind {return v} + return 0 + } + set {kind = .numberValue(newValue)} + } + + /// Represents a string value. + public var stringValue: String { + get { + if case .stringValue(let v)? = kind {return v} + return String() + } + set {kind = .stringValue(newValue)} + } + + /// Represents a boolean value. + public var boolValue: Bool { + get { + if case .boolValue(let v)? = kind {return v} + return false + } + set {kind = .boolValue(newValue)} + } + + /// Represents a structured value. + public var structValue: Google_Protobuf_Struct { + get { + if case .structValue(let v)? = kind {return v} + return Google_Protobuf_Struct() + } + set {kind = .structValue(newValue)} + } + + /// Represents a repeated `Value`. + public var listValue: Google_Protobuf_ListValue { + get { + if case .listValue(let v)? = kind {return v} + return Google_Protobuf_ListValue() + } + set {kind = .listValue(newValue)} + } + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// The kind of value. + public enum OneOf_Kind: Equatable { + /// Represents a null value. + case nullValue(Google_Protobuf_NullValue) + /// Represents a double value. + case numberValue(Double) + /// Represents a string value. + case stringValue(String) + /// Represents a boolean value. + case boolValue(Bool) + /// Represents a structured value. + case structValue(Google_Protobuf_Struct) + /// Represents a repeated `Value`. + case listValue(Google_Protobuf_ListValue) + + #if !swift(>=4.1) + public static func ==(lhs: Google_Protobuf_Value.OneOf_Kind, rhs: Google_Protobuf_Value.OneOf_Kind) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.nullValue, .nullValue): return { + guard case .nullValue(let l) = lhs, case .nullValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.numberValue, .numberValue): return { + guard case .numberValue(let l) = lhs, case .numberValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.stringValue, .stringValue): return { + guard case .stringValue(let l) = lhs, case .stringValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.boolValue, .boolValue): return { + guard case .boolValue(let l) = lhs, case .boolValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.structValue, .structValue): return { + guard case .structValue(let l) = lhs, case .structValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.listValue, .listValue): return { + guard case .listValue(let l) = lhs, case .listValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + public init() {} +} + +/// `ListValue` is a wrapper around a repeated field of values. +/// +/// The JSON representation for `ListValue` is JSON array. +public struct Google_Protobuf_ListValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Repeated field of dynamically typed values. + public var values: [Google_Protobuf_Value] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_NullValue: @unchecked Sendable {} +extension Google_Protobuf_Struct: @unchecked Sendable {} +extension Google_Protobuf_Value: @unchecked Sendable {} +extension Google_Protobuf_Value.OneOf_Kind: @unchecked Sendable {} +extension Google_Protobuf_ListValue: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_NullValue: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "NULL_VALUE"), + ] +} + +extension Google_Protobuf_Struct: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Struct" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "fields"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMessageMap.self, value: &self.fields) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.fields.isEmpty { + try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMessageMap.self, value: self.fields, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Struct, rhs: Google_Protobuf_Struct) -> Bool { + if lhs.fields != rhs.fields {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Value" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "null_value"), + 2: .standard(proto: "number_value"), + 3: .standard(proto: "string_value"), + 4: .standard(proto: "bool_value"), + 5: .standard(proto: "struct_value"), + 6: .standard(proto: "list_value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { + var v: Google_Protobuf_NullValue? + try decoder.decodeSingularEnumField(value: &v) + if let v = v { + if self.kind != nil {try decoder.handleConflictingOneOf()} + self.kind = .nullValue(v) + } + }() + case 2: try { + var v: Double? + try decoder.decodeSingularDoubleField(value: &v) + if let v = v { + if self.kind != nil {try decoder.handleConflictingOneOf()} + self.kind = .numberValue(v) + } + }() + case 3: try { + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v { + if self.kind != nil {try decoder.handleConflictingOneOf()} + self.kind = .stringValue(v) + } + }() + case 4: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.kind != nil {try decoder.handleConflictingOneOf()} + self.kind = .boolValue(v) + } + }() + case 5: try { + var v: Google_Protobuf_Struct? + var hadOneofValue = false + if let current = self.kind { + hadOneofValue = true + if case .structValue(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.kind = .structValue(v) + } + }() + case 6: try { + var v: Google_Protobuf_ListValue? + var hadOneofValue = false + if let current = self.kind { + hadOneofValue = true + if case .listValue(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.kind = .listValue(v) + } + }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + switch self.kind { + case .nullValue?: try { + guard case .nullValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + }() + case .numberValue?: try { + guard case .numberValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularDoubleField(value: v, fieldNumber: 2) + }() + case .stringValue?: try { + guard case .stringValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + }() + case .boolValue?: try { + guard case .boolValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 4) + }() + case .structValue?: try { + guard case .structValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .listValue?: try { + guard case .listValue(let v)? = self.kind else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Value, rhs: Google_Protobuf_Value) -> Bool { + if lhs.kind != rhs.kind {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_ListValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".ListValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "values"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.values) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.values.isEmpty { + try visitor.visitRepeatedMessageField(value: self.values, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_ListValue, rhs: Google_Protobuf_ListValue) -> Bool { + if lhs.values != rhs.values {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/timestamp.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/timestamp.pb.swift new file mode 100644 index 00000000..1562c0ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/timestamp.pb.swift @@ -0,0 +1,208 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/timestamp.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// A Timestamp represents a point in time independent of any time zone or local +/// calendar, encoded as a count of seconds and fractions of seconds at +/// nanosecond resolution. The count is relative to an epoch at UTC midnight on +/// January 1, 1970, in the proleptic Gregorian calendar which extends the +/// Gregorian calendar backwards to year one. +/// +/// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +/// second table is needed for interpretation, using a [24-hour linear +/// smear](https://developers.google.com/time/smear). +/// +/// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +/// restricting to that range, we ensure that we can convert to and from [RFC +/// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +/// +/// # Examples +/// +/// Example 1: Compute Timestamp from POSIX `time()`. +/// +/// Timestamp timestamp; +/// timestamp.set_seconds(time(NULL)); +/// timestamp.set_nanos(0); +/// +/// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +/// +/// struct timeval tv; +/// gettimeofday(&tv, NULL); +/// +/// Timestamp timestamp; +/// timestamp.set_seconds(tv.tv_sec); +/// timestamp.set_nanos(tv.tv_usec * 1000); +/// +/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +/// +/// FILETIME ft; +/// GetSystemTimeAsFileTime(&ft); +/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +/// +/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +/// Timestamp timestamp; +/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +/// +/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +/// +/// long millis = System.currentTimeMillis(); +/// +/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +/// .setNanos((int) ((millis % 1000) * 1000000)).build(); +/// +/// +/// Example 5: Compute Timestamp from Java `Instant.now()`. +/// +/// Instant now = Instant.now(); +/// +/// Timestamp timestamp = +/// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +/// .setNanos(now.getNano()).build(); +/// +/// +/// Example 6: Compute Timestamp from current time in Python. +/// +/// timestamp = Timestamp() +/// timestamp.GetCurrentTime() +/// +/// # JSON Mapping +/// +/// In JSON format, the Timestamp type is encoded as a string in the +/// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +/// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +/// where {year} is always expressed using four digits while {month}, {day}, +/// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +/// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +/// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +/// is required. A proto3 JSON serializer should always use UTC (as indicated by +/// "Z") when printing the Timestamp type and a proto3 JSON parser should be +/// able to accept both UTC and other timezones (as indicated by an offset). +/// +/// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +/// 01:30 UTC on January 15, 2017. +/// +/// In JavaScript, one can convert a Date object to this format using the +/// standard +/// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +/// method. In Python, a standard `datetime.datetime` object can be converted +/// to this format using +/// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +/// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +/// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +/// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +/// ) to obtain a formatter capable of generating timestamps in this format. +public struct Google_Protobuf_Timestamp { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Represents seconds of UTC time since Unix epoch + /// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + /// 9999-12-31T23:59:59Z inclusive. + public var seconds: Int64 = 0 + + /// Non-negative fractions of a second at nanosecond resolution. Negative + /// second values with fractions must still have non-negative nanos values + /// that count forward in time. Must be from 0 to 999,999,999 + /// inclusive. + public var nanos: Int32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Timestamp: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Timestamp: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Timestamp" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "seconds"), + 2: .same(proto: "nanos"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt64Field(value: &self.seconds) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.nanos) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.seconds != 0 { + try visitor.visitSingularInt64Field(value: self.seconds, fieldNumber: 1) + } + if self.nanos != 0 { + try visitor.visitSingularInt32Field(value: self.nanos, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Timestamp, rhs: Google_Protobuf_Timestamp) -> Bool { + if lhs.seconds != rhs.seconds {return false} + if lhs.nanos != rhs.nanos {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/type.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/type.pb.swift new file mode 100644 index 00000000..d781272b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/type.pb.swift @@ -0,0 +1,817 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/type.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// The syntax in which a protocol buffer element is defined. +public enum Google_Protobuf_Syntax: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Syntax `proto2`. + case proto2 // = 0 + + /// Syntax `proto3`. + case proto3 // = 1 + case UNRECOGNIZED(Int) + + public init() { + self = .proto2 + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .proto2 + case 1: self = .proto3 + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .proto2: return 0 + case .proto3: return 1 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Google_Protobuf_Syntax: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static var allCases: [Google_Protobuf_Syntax] = [ + .proto2, + .proto3, + ] +} + +#endif // swift(>=4.2) + +/// A protocol buffer message type. +public struct Google_Protobuf_Type { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The fully qualified message name. + public var name: String = String() + + /// The list of fields. + public var fields: [Google_Protobuf_Field] = [] + + /// The list of types appearing in `oneof` definitions in this type. + public var oneofs: [String] = [] + + /// The protocol buffer options. + public var options: [Google_Protobuf_Option] = [] + + /// The source context. + public var sourceContext: Google_Protobuf_SourceContext { + get {return _sourceContext ?? Google_Protobuf_SourceContext()} + set {_sourceContext = newValue} + } + /// Returns true if `sourceContext` has been explicitly set. + public var hasSourceContext: Bool {return self._sourceContext != nil} + /// Clears the value of `sourceContext`. Subsequent reads from it will return its default value. + public mutating func clearSourceContext() {self._sourceContext = nil} + + /// The source syntax. + public var syntax: Google_Protobuf_Syntax = .proto2 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil +} + +/// A single field of a message type. +public struct Google_Protobuf_Field { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The field type. + public var kind: Google_Protobuf_Field.Kind = .typeUnknown + + /// The field cardinality. + public var cardinality: Google_Protobuf_Field.Cardinality = .unknown + + /// The field number. + public var number: Int32 = 0 + + /// The field name. + public var name: String = String() + + /// The field type URL, without the scheme, for message or enumeration + /// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + public var typeURL: String = String() + + /// The index of the field type in `Type.oneofs`, for message or enumeration + /// types. The first type has index 1; zero means the type is not in the list. + public var oneofIndex: Int32 = 0 + + /// Whether to use alternative packed wire representation. + public var packed: Bool = false + + /// The protocol buffer options. + public var options: [Google_Protobuf_Option] = [] + + /// The field JSON name. + public var jsonName: String = String() + + /// The string value of the default value of this field. Proto2 syntax only. + public var defaultValue: String = String() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Basic field types. + public enum Kind: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// Field type unknown. + case typeUnknown // = 0 + + /// Field type double. + case typeDouble // = 1 + + /// Field type float. + case typeFloat // = 2 + + /// Field type int64. + case typeInt64 // = 3 + + /// Field type uint64. + case typeUint64 // = 4 + + /// Field type int32. + case typeInt32 // = 5 + + /// Field type fixed64. + case typeFixed64 // = 6 + + /// Field type fixed32. + case typeFixed32 // = 7 + + /// Field type bool. + case typeBool // = 8 + + /// Field type string. + case typeString // = 9 + + /// Field type group. Proto2 syntax only, and deprecated. + case typeGroup // = 10 + + /// Field type message. + case typeMessage // = 11 + + /// Field type bytes. + case typeBytes // = 12 + + /// Field type uint32. + case typeUint32 // = 13 + + /// Field type enum. + case typeEnum // = 14 + + /// Field type sfixed32. + case typeSfixed32 // = 15 + + /// Field type sfixed64. + case typeSfixed64 // = 16 + + /// Field type sint32. + case typeSint32 // = 17 + + /// Field type sint64. + case typeSint64 // = 18 + case UNRECOGNIZED(Int) + + public init() { + self = .typeUnknown + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .typeUnknown + case 1: self = .typeDouble + case 2: self = .typeFloat + case 3: self = .typeInt64 + case 4: self = .typeUint64 + case 5: self = .typeInt32 + case 6: self = .typeFixed64 + case 7: self = .typeFixed32 + case 8: self = .typeBool + case 9: self = .typeString + case 10: self = .typeGroup + case 11: self = .typeMessage + case 12: self = .typeBytes + case 13: self = .typeUint32 + case 14: self = .typeEnum + case 15: self = .typeSfixed32 + case 16: self = .typeSfixed64 + case 17: self = .typeSint32 + case 18: self = .typeSint64 + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .typeUnknown: return 0 + case .typeDouble: return 1 + case .typeFloat: return 2 + case .typeInt64: return 3 + case .typeUint64: return 4 + case .typeInt32: return 5 + case .typeFixed64: return 6 + case .typeFixed32: return 7 + case .typeBool: return 8 + case .typeString: return 9 + case .typeGroup: return 10 + case .typeMessage: return 11 + case .typeBytes: return 12 + case .typeUint32: return 13 + case .typeEnum: return 14 + case .typeSfixed32: return 15 + case .typeSfixed64: return 16 + case .typeSint32: return 17 + case .typeSint64: return 18 + case .UNRECOGNIZED(let i): return i + } + } + + } + + /// Whether a field is optional, required, or repeated. + public enum Cardinality: SwiftProtobuf.Enum { + public typealias RawValue = Int + + /// For fields with unknown cardinality. + case unknown // = 0 + + /// For optional fields. + case `optional` // = 1 + + /// For required fields. Proto2 syntax only. + case `required` // = 2 + + /// For repeated fields. + case repeated // = 3 + case UNRECOGNIZED(Int) + + public init() { + self = .unknown + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .optional + case 2: self = .required + case 3: self = .repeated + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .unknown: return 0 + case .optional: return 1 + case .required: return 2 + case .repeated: return 3 + case .UNRECOGNIZED(let i): return i + } + } + + } + + public init() {} +} + +#if swift(>=4.2) + +extension Google_Protobuf_Field.Kind: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static var allCases: [Google_Protobuf_Field.Kind] = [ + .typeUnknown, + .typeDouble, + .typeFloat, + .typeInt64, + .typeUint64, + .typeInt32, + .typeFixed64, + .typeFixed32, + .typeBool, + .typeString, + .typeGroup, + .typeMessage, + .typeBytes, + .typeUint32, + .typeEnum, + .typeSfixed32, + .typeSfixed64, + .typeSint32, + .typeSint64, + ] +} + +extension Google_Protobuf_Field.Cardinality: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static var allCases: [Google_Protobuf_Field.Cardinality] = [ + .unknown, + .optional, + .required, + .repeated, + ] +} + +#endif // swift(>=4.2) + +/// Enum type definition. +public struct Google_Protobuf_Enum { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Enum type name. + public var name: String = String() + + /// Enum value definitions. + public var enumvalue: [Google_Protobuf_EnumValue] = [] + + /// Protocol buffer options. + public var options: [Google_Protobuf_Option] = [] + + /// The source context. + public var sourceContext: Google_Protobuf_SourceContext { + get {return _sourceContext ?? Google_Protobuf_SourceContext()} + set {_sourceContext = newValue} + } + /// Returns true if `sourceContext` has been explicitly set. + public var hasSourceContext: Bool {return self._sourceContext != nil} + /// Clears the value of `sourceContext`. Subsequent reads from it will return its default value. + public mutating func clearSourceContext() {self._sourceContext = nil} + + /// The source syntax. + public var syntax: Google_Protobuf_Syntax = .proto2 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil +} + +/// Enum value definition. +public struct Google_Protobuf_EnumValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Enum value name. + public var name: String = String() + + /// Enum value number. + public var number: Int32 = 0 + + /// Protocol buffer options. + public var options: [Google_Protobuf_Option] = [] + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// A protocol buffer option, which can be attached to a message, field, +/// enumeration, etc. +public struct Google_Protobuf_Option { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The option's name. For protobuf built-in options (options defined in + /// descriptor.proto), this is the short name. For example, `"map_entry"`. + /// For custom options, it should be the fully-qualified name. For example, + /// `"google.api.http"`. + public var name: String = String() + + /// The option's value packed in an Any message. If the value is a primitive, + /// the corresponding wrapper type defined in google/protobuf/wrappers.proto + /// should be used. If the value is an enum, it should be stored as an int32 + /// value using the google.protobuf.Int32Value type. + public var value: Google_Protobuf_Any { + get {return _value ?? Google_Protobuf_Any()} + set {_value = newValue} + } + /// Returns true if `value` has been explicitly set. + public var hasValue: Bool {return self._value != nil} + /// Clears the value of `value`. Subsequent reads from it will return its default value. + public mutating func clearValue() {self._value = nil} + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} + + fileprivate var _value: Google_Protobuf_Any? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_Syntax: @unchecked Sendable {} +extension Google_Protobuf_Type: @unchecked Sendable {} +extension Google_Protobuf_Field: @unchecked Sendable {} +extension Google_Protobuf_Field.Kind: @unchecked Sendable {} +extension Google_Protobuf_Field.Cardinality: @unchecked Sendable {} +extension Google_Protobuf_Enum: @unchecked Sendable {} +extension Google_Protobuf_EnumValue: @unchecked Sendable {} +extension Google_Protobuf_Option: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_Syntax: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "SYNTAX_PROTO2"), + 1: .same(proto: "SYNTAX_PROTO3"), + ] +} + +extension Google_Protobuf_Type: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Type" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "fields"), + 3: .same(proto: "oneofs"), + 4: .same(proto: "options"), + 5: .standard(proto: "source_context"), + 6: .same(proto: "syntax"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.fields) }() + case 3: try { try decoder.decodeRepeatedStringField(value: &self.oneofs) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }() + case 6: try { try decoder.decodeSingularEnumField(value: &self.syntax) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.fields.isEmpty { + try visitor.visitRepeatedMessageField(value: self.fields, fieldNumber: 2) + } + if !self.oneofs.isEmpty { + try visitor.visitRepeatedStringField(value: self.oneofs, fieldNumber: 3) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 4) + } + try { if let v = self._sourceContext { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + if self.syntax != .proto2 { + try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Type, rhs: Google_Protobuf_Type) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.fields != rhs.fields {return false} + if lhs.oneofs != rhs.oneofs {return false} + if lhs.options != rhs.options {return false} + if lhs._sourceContext != rhs._sourceContext {return false} + if lhs.syntax != rhs.syntax {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Field: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Field" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "kind"), + 2: .same(proto: "cardinality"), + 3: .same(proto: "number"), + 4: .same(proto: "name"), + 6: .standard(proto: "type_url"), + 7: .standard(proto: "oneof_index"), + 8: .same(proto: "packed"), + 9: .same(proto: "options"), + 10: .standard(proto: "json_name"), + 11: .standard(proto: "default_value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.kind) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.cardinality) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self.number) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 6: try { try decoder.decodeSingularStringField(value: &self.typeURL) }() + case 7: try { try decoder.decodeSingularInt32Field(value: &self.oneofIndex) }() + case 8: try { try decoder.decodeSingularBoolField(value: &self.packed) }() + case 9: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + case 10: try { try decoder.decodeSingularStringField(value: &self.jsonName) }() + case 11: try { try decoder.decodeSingularStringField(value: &self.defaultValue) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.kind != .typeUnknown { + try visitor.visitSingularEnumField(value: self.kind, fieldNumber: 1) + } + if self.cardinality != .unknown { + try visitor.visitSingularEnumField(value: self.cardinality, fieldNumber: 2) + } + if self.number != 0 { + try visitor.visitSingularInt32Field(value: self.number, fieldNumber: 3) + } + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 4) + } + if !self.typeURL.isEmpty { + try visitor.visitSingularStringField(value: self.typeURL, fieldNumber: 6) + } + if self.oneofIndex != 0 { + try visitor.visitSingularInt32Field(value: self.oneofIndex, fieldNumber: 7) + } + if self.packed != false { + try visitor.visitSingularBoolField(value: self.packed, fieldNumber: 8) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 9) + } + if !self.jsonName.isEmpty { + try visitor.visitSingularStringField(value: self.jsonName, fieldNumber: 10) + } + if !self.defaultValue.isEmpty { + try visitor.visitSingularStringField(value: self.defaultValue, fieldNumber: 11) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Field, rhs: Google_Protobuf_Field) -> Bool { + if lhs.kind != rhs.kind {return false} + if lhs.cardinality != rhs.cardinality {return false} + if lhs.number != rhs.number {return false} + if lhs.name != rhs.name {return false} + if lhs.typeURL != rhs.typeURL {return false} + if lhs.oneofIndex != rhs.oneofIndex {return false} + if lhs.packed != rhs.packed {return false} + if lhs.options != rhs.options {return false} + if lhs.jsonName != rhs.jsonName {return false} + if lhs.defaultValue != rhs.defaultValue {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Field.Kind: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "TYPE_UNKNOWN"), + 1: .same(proto: "TYPE_DOUBLE"), + 2: .same(proto: "TYPE_FLOAT"), + 3: .same(proto: "TYPE_INT64"), + 4: .same(proto: "TYPE_UINT64"), + 5: .same(proto: "TYPE_INT32"), + 6: .same(proto: "TYPE_FIXED64"), + 7: .same(proto: "TYPE_FIXED32"), + 8: .same(proto: "TYPE_BOOL"), + 9: .same(proto: "TYPE_STRING"), + 10: .same(proto: "TYPE_GROUP"), + 11: .same(proto: "TYPE_MESSAGE"), + 12: .same(proto: "TYPE_BYTES"), + 13: .same(proto: "TYPE_UINT32"), + 14: .same(proto: "TYPE_ENUM"), + 15: .same(proto: "TYPE_SFIXED32"), + 16: .same(proto: "TYPE_SFIXED64"), + 17: .same(proto: "TYPE_SINT32"), + 18: .same(proto: "TYPE_SINT64"), + ] +} + +extension Google_Protobuf_Field.Cardinality: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "CARDINALITY_UNKNOWN"), + 1: .same(proto: "CARDINALITY_OPTIONAL"), + 2: .same(proto: "CARDINALITY_REQUIRED"), + 3: .same(proto: "CARDINALITY_REPEATED"), + ] +} + +extension Google_Protobuf_Enum: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Enum" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "enumvalue"), + 3: .same(proto: "options"), + 4: .standard(proto: "source_context"), + 5: .same(proto: "syntax"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.enumvalue) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self.syntax) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if !self.enumvalue.isEmpty { + try visitor.visitRepeatedMessageField(value: self.enumvalue, fieldNumber: 2) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3) + } + try { if let v = self._sourceContext { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + if self.syntax != .proto2 { + try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Enum, rhs: Google_Protobuf_Enum) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.enumvalue != rhs.enumvalue {return false} + if lhs.options != rhs.options {return false} + if lhs._sourceContext != rhs._sourceContext {return false} + if lhs.syntax != rhs.syntax {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_EnumValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".EnumValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "number"), + 3: .same(proto: "options"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.number) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + if self.number != 0 { + try visitor.visitSingularInt32Field(value: self.number, fieldNumber: 2) + } + if !self.options.isEmpty { + try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_EnumValue, rhs: Google_Protobuf_EnumValue) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.number != rhs.number {return false} + if lhs.options != rhs.options {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Option: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Option" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + try { if let v = self._value { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Option, rhs: Google_Protobuf_Option) -> Bool { + if lhs.name != rhs.name {return false} + if lhs._value != rhs._value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/wrappers.pb.swift b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/wrappers.pb.swift new file mode 100644 index 00000000..312fc3a2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftProtobuf/Sources/SwiftProtobuf/wrappers.pb.swift @@ -0,0 +1,508 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: google/protobuf/wrappers.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +import Foundation + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Wrapper message for `double`. +/// +/// The JSON representation for `DoubleValue` is JSON number. +public struct Google_Protobuf_DoubleValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The double value. + public var value: Double = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `float`. +/// +/// The JSON representation for `FloatValue` is JSON number. +public struct Google_Protobuf_FloatValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The float value. + public var value: Float = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `int64`. +/// +/// The JSON representation for `Int64Value` is JSON string. +public struct Google_Protobuf_Int64Value { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The int64 value. + public var value: Int64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `uint64`. +/// +/// The JSON representation for `UInt64Value` is JSON string. +public struct Google_Protobuf_UInt64Value { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The uint64 value. + public var value: UInt64 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `int32`. +/// +/// The JSON representation for `Int32Value` is JSON number. +public struct Google_Protobuf_Int32Value { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The int32 value. + public var value: Int32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `uint32`. +/// +/// The JSON representation for `UInt32Value` is JSON number. +public struct Google_Protobuf_UInt32Value { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The uint32 value. + public var value: UInt32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `bool`. +/// +/// The JSON representation for `BoolValue` is JSON `true` and `false`. +public struct Google_Protobuf_BoolValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The bool value. + public var value: Bool = false + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `string`. +/// +/// The JSON representation for `StringValue` is JSON string. +public struct Google_Protobuf_StringValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The string value. + public var value: String = String() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +/// Wrapper message for `bytes`. +/// +/// The JSON representation for `BytesValue` is JSON string. +public struct Google_Protobuf_BytesValue { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The bytes value. + public var value: Data = Data() + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Google_Protobuf_DoubleValue: @unchecked Sendable {} +extension Google_Protobuf_FloatValue: @unchecked Sendable {} +extension Google_Protobuf_Int64Value: @unchecked Sendable {} +extension Google_Protobuf_UInt64Value: @unchecked Sendable {} +extension Google_Protobuf_Int32Value: @unchecked Sendable {} +extension Google_Protobuf_UInt32Value: @unchecked Sendable {} +extension Google_Protobuf_BoolValue: @unchecked Sendable {} +extension Google_Protobuf_StringValue: @unchecked Sendable {} +extension Google_Protobuf_BytesValue: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "google.protobuf" + +extension Google_Protobuf_DoubleValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".DoubleValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularDoubleField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularDoubleField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_DoubleValue, rhs: Google_Protobuf_DoubleValue) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_FloatValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".FloatValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularFloatField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularFloatField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_FloatValue, rhs: Google_Protobuf_FloatValue) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Int64Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Int64Value" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt64Field(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularInt64Field(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Int64Value, rhs: Google_Protobuf_Int64Value) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_UInt64Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".UInt64Value" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularUInt64Field(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_UInt64Value, rhs: Google_Protobuf_UInt64Value) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_Int32Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Int32Value" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularInt32Field(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_Int32Value, rhs: Google_Protobuf_Int32Value) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_UInt32Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".UInt32Value" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != 0 { + try visitor.visitSingularUInt32Field(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_UInt32Value, rhs: Google_Protobuf_UInt32Value) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_BoolValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BoolValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.value != false { + try visitor.visitSingularBoolField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_BoolValue, rhs: Google_Protobuf_BoolValue) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_StringValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".StringValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.value.isEmpty { + try visitor.visitSingularStringField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_StringValue, rhs: Google_Protobuf_StringValue) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Google_Protobuf_BytesValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".BytesValue" + public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "value"), + ] + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if !self.value.isEmpty { + try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Google_Protobuf_BytesValue, rhs: Google_Protobuf_BytesValue) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/LICENSE b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/LICENSE new file mode 100644 index 00000000..68e3fd74 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Ruoyu Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/README.md b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/README.md new file mode 100644 index 00000000..24654150 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/README.md @@ -0,0 +1,560 @@ +# SwiftyJSON + +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ![CocoaPods](https://img.shields.io/cocoapods/v/SwiftyJSON.svg) ![Platform](https://img.shields.io/badge/platforms-iOS%208.0%20%7C%20macOS%2010.10%20%7C%20tvOS%209.0%20%7C%20watchOS%203.0-F28D00.svg) [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com) + +SwiftyJSON makes it easy to deal with JSON data in Swift. + +Platform | Build Status +---------| --------------| +*OS | [![Travis CI](https://travis-ci.org/SwiftyJSON/SwiftyJSON.svg?branch=master)](https://travis-ci.org/SwiftyJSON/SwiftyJSON) | +[Linux](https://github.com/IBM-Swift/SwiftyJSON) | [![Build Status](https://travis-ci.org/IBM-Swift/SwiftyJSON.svg?branch=master)](https://travis-ci.org/IBM-Swift/SwiftyJSON) | + + +1. [Why is the typical JSON handling in Swift NOT good](#why-is-the-typical-json-handling-in-swift-not-good) +2. [Requirements](#requirements) +3. [Integration](#integration) +4. [Usage](#usage) + - [Initialization](#initialization) + - [Subscript](#subscript) + - [Loop](#loop) + - [Error](#error) + - [Optional getter](#optional-getter) + - [Non-optional getter](#non-optional-getter) + - [Setter](#setter) + - [Raw object](#raw-object) + - [Literal convertibles](#literal-convertibles) + - [Merging](#merging) +5. [Work with Alamofire](#work-with-alamofire) +6. [Work with Moya](#work-with-moya) +7. [SwiftyJSON Model Generator](#swiftyjson-model-generator) + + +## Why is the typical JSON handling in Swift NOT good? + +Swift is very strict about types. But although explicit typing is good for saving us from mistakes, it becomes painful when dealing with JSON and other areas that are, by nature, implicit about types. + +Take the Twitter API for example. Say we want to retrieve a user's "name" value of some tweet in Swift (according to [Twitter's API](https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline)). + +The code would look like this: + +```swift +if let statusesArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], + let user = statusesArray[0]["user"] as? [String: Any], + let username = user["name"] as? String { + // Finally we got the username +} +``` + +It's not good. + +Even if we use optional chaining, it would be messy: + +```swift +if let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], + let username = (JSONObject[0]["user"] as? [String: Any])?["name"] as? String { + // There's our username +} +``` + +An unreadable mess--for something that should really be simple! + +With SwiftyJSON all you have to do is: + +```swift +let json = JSON(data: dataFromNetworking) +if let userName = json[0]["user"]["name"].string { + //Now you got your value +} +``` + +And don't worry about the Optional Wrapping thing. It's done for you automatically. + +```swift +let json = JSON(data: dataFromNetworking) +let result = json[999999]["wrong_key"]["wrong_name"] +if let userName = result.string { + //Calm down, take it easy, the ".string" property still produces the correct Optional String type with safety +} else { + //Print the error + print(result.error) +} +``` + +## Requirements + +- iOS 8.0+ | macOS 10.10+ | tvOS 9.0+ | watchOS 2.0+ +- Xcode 8 + +## Integration + +#### CocoaPods (iOS 8+, OS X 10.9+) + +You can use [CocoaPods](http://cocoapods.org/) to install `SwiftyJSON` by adding it to your `Podfile`: + +```ruby +platform :ios, '8.0' +use_frameworks! + +target 'MyApp' do + pod 'SwiftyJSON', '~> 4.0' +end +``` + +#### Carthage (iOS 8+, OS X 10.9+) + +You can use [Carthage](https://github.com/Carthage/Carthage) to install `SwiftyJSON` by adding it to your `Cartfile`: + +``` +github "SwiftyJSON/SwiftyJSON" ~> 4.0 +``` + +If you use Carthage to build your dependencies, make sure you have added `SwiftyJSON.framework` to the "Linked Frameworks and Libraries" section of your target, and have included them in your Carthage framework copying build phase. + +#### Swift Package Manager + +You can use [The Swift Package Manager](https://swift.org/package-manager) to install `SwiftyJSON` by adding the proper description to your `Package.swift` file: + +```swift +// swift-tools-version:4.0 +import PackageDescription + +let package = Package( + name: "YOUR_PROJECT_NAME", + dependencies: [ + .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"), + ] +) +``` +Then run `swift build` whenever you get prepared. + +#### Manually (iOS 7+, OS X 10.9+) + +To use this library in your project manually you may: + +1. for Projects, just drag SwiftyJSON.swift to the project tree +2. for Workspaces, include the whole SwiftyJSON.xcodeproj + +## Usage + +#### Initialization + +```swift +import SwiftyJSON +``` + +```swift +let json = JSON(data: dataFromNetworking) +``` +Or + +```swift +let json = JSON(jsonObject) +``` +Or + +```swift +if let dataFromString = jsonString.data(using: .utf8, allowLossyConversion: false) { + let json = JSON(data: dataFromString) +} +``` + +#### Subscript + +```swift +// Getting a double from a JSON Array +let name = json[0].double +``` + +```swift +// Getting an array of string from a JSON Array +let arrayNames = json["users"].arrayValue.map {$0["name"].stringValue} +``` + +```swift +// Getting a string from a JSON Dictionary +let name = json["name"].stringValue +``` + +```swift +// Getting a string using a path to the element +let path: [JSONSubscriptType] = [1,"list",2,"name"] +let name = json[path].string +// Just the same +let name = json[1]["list"][2]["name"].string +// Alternatively +let name = json[1,"list",2,"name"].string +``` + +```swift +// With a hard way +let name = json[].string +``` + +```swift +// With a custom way +let keys:[JSONSubscriptType] = [1,"list",2,"name"] +let name = json[keys].string +``` + +#### Loop + +```swift +// If json is .Dictionary +for (key,subJson):(String, JSON) in json { + // Do something you want +} +``` + +*The first element is always a String, even if the JSON is an Array* + +```swift +// If json is .Array +// The `index` is 0.. = json["list"].arrayValue +``` + +```swift +// If not a Dictionary or nil, return [:] +let user: Dictionary = json["user"].dictionaryValue +``` + +#### Setter + +```swift +json["name"] = JSON("new-name") +json[0] = JSON(1) +``` + +```swift +json["id"].int = 1234567890 +json["coordinate"].double = 8766.766 +json["name"].string = "Jack" +json.arrayObject = [1,2,3,4] +json.dictionaryObject = ["name":"Jack", "age":25] +``` + +#### Raw object + +```swift +let rawObject: Any = json.object +``` + +```swift +let rawValue: Any = json.rawValue +``` + +```swift +//convert the JSON to raw NSData +do { + let rawData = try json.rawData() + //Do something you want +} catch { + print("Error \(error)") +} +``` + +```swift +//convert the JSON to a raw String +if let rawString = json.rawString() { + //Do something you want +} else { + print("json.rawString is nil") +} +``` + +#### Existence + +```swift +// shows you whether value specified in JSON or not +if json["name"].exists() +``` + +#### Literal convertibles + +For more info about literal convertibles: [Swift Literal Convertibles](http://nshipster.com/swift-literal-convertible/) + +```swift +// StringLiteralConvertible +let json: JSON = "I'm a json" +``` + +```swift +/ /IntegerLiteralConvertible +let json: JSON = 12345 +``` + +```swift +// BooleanLiteralConvertible +let json: JSON = true +``` + +```swift +// FloatLiteralConvertible +let json: JSON = 2.8765 +``` + +```swift +// DictionaryLiteralConvertible +let json: JSON = ["I":"am", "a":"json"] +``` + +```swift +// ArrayLiteralConvertible +let json: JSON = ["I", "am", "a", "json"] +``` + +```swift +// With subscript in array +var json: JSON = [1,2,3] +json[0] = 100 +json[1] = 200 +json[2] = 300 +json[999] = 300 // Don't worry, nothing will happen +``` + +```swift +// With subscript in dictionary +var json: JSON = ["name": "Jack", "age": 25] +json["name"] = "Mike" +json["age"] = "25" // It's OK to set String +json["address"] = "L.A." // Add the "address": "L.A." in json +``` + +```swift +// Array & Dictionary +var json: JSON = ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]] +json["list"][3]["what"] = "that" +json["list",3,"what"] = "that" +let path: [JSONSubscriptType] = ["list",3,"what"] +json[path] = "that" +``` + +```swift +// With other JSON objects +let user: JSON = ["username" : "Steve", "password": "supersecurepassword"] +let auth: JSON = [ + "user": user.object, // use user.object instead of just user + "apikey": "supersecretapitoken" +] +``` + +#### Merging + +It is possible to merge one JSON into another JSON. Merging a JSON into another JSON adds all non existing values to the original JSON which are only present in the `other` JSON. + +If both JSONs contain a value for the same key, _mostly_ this value gets overwritten in the original JSON, but there are two cases where it provides some special treatment: + +- In case of both values being a `JSON.Type.array` the values form the array found in the `other` JSON getting appended to the original JSON's array value. +- In case of both values being a `JSON.Type.dictionary` both JSON-values are getting merged the same way the encapsulating JSON is merged. + +In a case where two fields in a JSON have different types, the value will get always overwritten. + +There are two different fashions for merging: `merge` modifies the original JSON, whereas `merged` works non-destructively on a copy. + +```swift +let original: JSON = [ + "first_name": "John", + "age": 20, + "skills": ["Coding", "Reading"], + "address": [ + "street": "Front St", + "zip": "12345", + ] +] + +let update: JSON = [ + "last_name": "Doe", + "age": 21, + "skills": ["Writing"], + "address": [ + "zip": "12342", + "city": "New York City" + ] +] + +let updated = original.merge(with: update) +// [ +// "first_name": "John", +// "last_name": "Doe", +// "age": 21, +// "skills": ["Coding", "Reading", "Writing"], +// "address": [ +// "street": "Front St", +// "zip": "12342", +// "city": "New York City" +// ] +// ] +``` + +## String representation +There are two options available: +- use the default Swift one +- use a custom one that will handle optionals well and represent `nil` as `"null"`: +```swift +let dict = ["1":2, "2":"two", "3": nil] as [String: Any?] +let json = JSON(dict) +let representation = json.rawString(options: [.castNilToNSNull: true]) +// representation is "{\"1\":2,\"2\":\"two\",\"3\":null}", which represents {"1":2,"2":"two","3":null} +``` + +## Work with [Alamofire](https://github.com/Alamofire/Alamofire) + +SwiftyJSON nicely wraps the result of the Alamofire JSON response handler: + +```swift +Alamofire.request(url, method: .get).validate().responseJSON { response in + switch response.result { + case .success(let value): + let json = JSON(value) + print("JSON: \(json)") + case .failure(let error): + print(error) + } +} +``` + +We also provide an extension of Alamofire for serializing NSData to SwiftyJSON's JSON. + +See: [Alamofire-SwiftyJSON](https://github.com/SwiftyJSON/Alamofire-SwiftyJSON) + + +## Work with [Moya](https://github.com/Moya/Moya) + +SwiftyJSON parse data to JSON: + +```swift +let provider = MoyaProvider() +provider.request(.showProducts) { result in + switch result { + case let .success(moyaResponse): + let data = moyaResponse.data + let json = JSON(data: data) // convert network data to json + print(json) + case let .failure(error): + print("error: \(error)") + } +} + +``` + +## SwiftyJSON Model Generator +Tools to generate SwiftyJSON Models +* [JSON Cafe](http://www.jsoncafe.com/) +* [JSON Export](https://github.com/Ahmed-Ali/JSONExport) diff --git a/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/Source/SwiftyJSON/SwiftyJSON.swift b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/Source/SwiftyJSON/SwiftyJSON.swift new file mode 100644 index 00000000..f7a3f085 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/SwiftyJSON/Source/SwiftyJSON/SwiftyJSON.swift @@ -0,0 +1,1401 @@ +// SwiftyJSON.swift +// +// Copyright (c) 2014 - 2017 Ruoyu Fu, Pinglin Tang +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// MARK: - Error +// swiftlint:disable line_length +public enum SwiftyJSONError: Int, Swift.Error { + case unsupportedType = 999 + case indexOutOfBounds = 900 + case elementTooDeep = 902 + case wrongType = 901 + case notExist = 500 + case invalidJSON = 490 +} + +extension SwiftyJSONError: CustomNSError { + + /// return the error domain of SwiftyJSONError + public static var errorDomain: String { return "com.swiftyjson.SwiftyJSON" } + + /// return the error code of SwiftyJSONError + public var errorCode: Int { return self.rawValue } + + /// return the userInfo of SwiftyJSONError + public var errorUserInfo: [String: Any] { + switch self { + case .unsupportedType: + return [NSLocalizedDescriptionKey: "It is an unsupported type."] + case .indexOutOfBounds: + return [NSLocalizedDescriptionKey: "Array Index is out of bounds."] + case .wrongType: + return [NSLocalizedDescriptionKey: "Couldn't merge, because the JSONs differ in type on top level."] + case .notExist: + return [NSLocalizedDescriptionKey: "Dictionary key does not exist."] + case .invalidJSON: + return [NSLocalizedDescriptionKey: "JSON is invalid."] + case .elementTooDeep: + return [NSLocalizedDescriptionKey: "Element too deep. Increase maxObjectDepth and make sure there is no reference loop."] + } + } +} + +// MARK: - JSON Type + +/** +JSON's type definitions. + +See http://www.json.org +*/ +public enum Type: Int { + case number + case string + case bool + case array + case dictionary + case null + case unknown +} + +// MARK: - JSON Base + +public struct JSON { + + /** + Creates a JSON using the data. + + - parameter data: The NSData used to convert to json.Top level object in data is an NSArray or NSDictionary + - parameter opt: The JSON serialization reading options. `[]` by default. + + - returns: The created JSON + */ + public init(data: Data, options opt: JSONSerialization.ReadingOptions = []) throws { + let object: Any = try JSONSerialization.jsonObject(with: data, options: opt) + self.init(jsonObject: object) + } + + /** + Creates a JSON object + - note: this does not parse a `String` into JSON, instead use `init(parseJSON: String)` + + - parameter object: the object + + - returns: the created JSON object + */ + public init(_ object: Any) { + switch object { + case let object as Data: + do { + try self.init(data: object) + } catch { + self.init(jsonObject: NSNull()) + } + default: + self.init(jsonObject: object) + } + } + + /** + Parses the JSON string into a JSON object + + - parameter json: the JSON string + + - returns: the created JSON object + */ + public init(parseJSON jsonString: String) { + if let data = jsonString.data(using: .utf8) { + self.init(data) + } else { + self.init(NSNull()) + } + } + + /** + Creates a JSON using the object. + + - parameter jsonObject: The object must have the following properties: All objects are NSString/String, NSNumber/Int/Float/Double/Bool, NSArray/Array, NSDictionary/Dictionary, or NSNull; All dictionary keys are NSStrings/String; NSNumbers are not NaN or infinity. + + - returns: The created JSON + */ + fileprivate init(jsonObject: Any) { + object = jsonObject + } + + /** + Merges another JSON into this JSON, whereas primitive values which are not present in this JSON are getting added, + present values getting overwritten, array values getting appended and nested JSONs getting merged the same way. + + - parameter other: The JSON which gets merged into this JSON + + - throws `ErrorWrongType` if the other JSONs differs in type on the top level. + */ + public mutating func merge(with other: JSON) throws { + try self.merge(with: other, typecheck: true) + } + + /** + Merges another JSON into this JSON and returns a new JSON, whereas primitive values which are not present in this JSON are getting added, + present values getting overwritten, array values getting appended and nested JSONS getting merged the same way. + + - parameter other: The JSON which gets merged into this JSON + + - throws `ErrorWrongType` if the other JSONs differs in type on the top level. + + - returns: New merged JSON + */ + public func merged(with other: JSON) throws -> JSON { + var merged = self + try merged.merge(with: other, typecheck: true) + return merged + } + + /** + Private woker function which does the actual merging + Typecheck is set to true for the first recursion level to prevent total override of the source JSON + */ + fileprivate mutating func merge(with other: JSON, typecheck: Bool) throws { + if type == other.type { + switch type { + case .dictionary: + for (key, _) in other { + try self[key].merge(with: other[key], typecheck: false) + } + case .array: + self = JSON(arrayValue + other.arrayValue) + default: + self = other + } + } else { + if typecheck { + throw SwiftyJSONError.wrongType + } else { + self = other + } + } + } + + /// Private object + fileprivate var rawArray: [Any] = [] + fileprivate var rawDictionary: [String: Any] = [:] + fileprivate var rawString: String = "" + fileprivate var rawNumber: NSNumber = 0 + fileprivate var rawNull: NSNull = NSNull() + fileprivate var rawBool: Bool = false + + /// JSON type, fileprivate setter + public fileprivate(set) var type: Type = .null + + /// Error in JSON, fileprivate setter + public fileprivate(set) var error: SwiftyJSONError? + + /// Object in JSON + public var object: Any { + get { + switch type { + case .array: return rawArray + case .dictionary: return rawDictionary + case .string: return rawString + case .number: return rawNumber + case .bool: return rawBool + default: return rawNull + } + } + set { + error = nil + switch unwrap(newValue) { + case let number as NSNumber: + if number.isBool { + type = .bool + rawBool = number.boolValue + } else { + type = .number + rawNumber = number + } + case let string as String: + type = .string + rawString = string + case _ as NSNull: + type = .null + case nil: + type = .null + case let array as [Any]: + type = .array + rawArray = array + case let dictionary as [String: Any]: + type = .dictionary + rawDictionary = dictionary + default: + type = .unknown + error = SwiftyJSONError.unsupportedType + } + } + } + + /// The static null JSON + @available(*, unavailable, renamed:"null") + public static var nullJSON: JSON { return null } + public static var null: JSON { return JSON(NSNull()) } +} + +/// Private method to unwarp an object recursively +private func unwrap(_ object: Any) -> Any { + switch object { + case let json as JSON: + return unwrap(json.object) + case let array as [Any]: + return array.map(unwrap) + case let dictionary as [String: Any]: + var d = dictionary + dictionary.forEach { pair in + d[pair.key] = unwrap(pair.value) + } + return d + default: + return object + } +} + +public enum Index: Comparable { + case array(Int) + case dictionary(DictionaryIndex) + case null + + static public func == (lhs: Index, rhs: Index) -> Bool { + switch (lhs, rhs) { + case (.array(let left), .array(let right)): return left == right + case (.dictionary(let left), .dictionary(let right)): return left == right + case (.null, .null): return true + default: return false + } + } + + static public func < (lhs: Index, rhs: Index) -> Bool { + switch (lhs, rhs) { + case (.array(let left), .array(let right)): return left < right + case (.dictionary(let left), .dictionary(let right)): return left < right + default: return false + } + } +} + +public typealias JSONIndex = Index +public typealias JSONRawIndex = Index + +extension JSON: Swift.Collection { + + public typealias Index = JSONRawIndex + + public var startIndex: Index { + switch type { + case .array: return .array(rawArray.startIndex) + case .dictionary: return .dictionary(rawDictionary.startIndex) + default: return .null + } + } + + public var endIndex: Index { + switch type { + case .array: return .array(rawArray.endIndex) + case .dictionary: return .dictionary(rawDictionary.endIndex) + default: return .null + } + } + + public func index(after i: Index) -> Index { + switch i { + case .array(let idx): return .array(rawArray.index(after: idx)) + case .dictionary(let idx): return .dictionary(rawDictionary.index(after: idx)) + default: return .null + } + } + + public subscript (position: Index) -> (String, JSON) { + switch position { + case .array(let idx): return (String(idx), JSON(rawArray[idx])) + case .dictionary(let idx): return (rawDictionary[idx].key, JSON(rawDictionary[idx].value)) + default: return ("", JSON.null) + } + } +} + +// MARK: - Subscript + +/** + * To mark both String and Int can be used in subscript. + */ +public enum JSONKey { + case index(Int) + case key(String) +} + +public protocol JSONSubscriptType { + var jsonKey: JSONKey { get } +} + +extension Int: JSONSubscriptType { + public var jsonKey: JSONKey { + return JSONKey.index(self) + } +} + +extension String: JSONSubscriptType { + public var jsonKey: JSONKey { + return JSONKey.key(self) + } +} + +extension JSON { + + /// If `type` is `.array`, return json whose object is `array[index]`, otherwise return null json with error. + fileprivate subscript(index index: Int) -> JSON { + get { + if type != .array { + var r = JSON.null + r.error = self.error ?? SwiftyJSONError.wrongType + return r + } else if rawArray.indices.contains(index) { + return JSON(rawArray[index]) + } else { + var r = JSON.null + r.error = SwiftyJSONError.indexOutOfBounds + return r + } + } + set { + if type == .array && + rawArray.indices.contains(index) && + newValue.error == nil { + rawArray[index] = newValue.object + } + } + } + + /// If `type` is `.dictionary`, return json whose object is `dictionary[key]` , otherwise return null json with error. + fileprivate subscript(key key: String) -> JSON { + get { + var r = JSON.null + if type == .dictionary { + if let o = rawDictionary[key] { + r = JSON(o) + } else { + r.error = SwiftyJSONError.notExist + } + } else { + r.error = self.error ?? SwiftyJSONError.wrongType + } + return r + } + set { + if type == .dictionary && newValue.error == nil { + rawDictionary[key] = newValue.object + } + } + } + + /// If `sub` is `Int`, return `subscript(index:)`; If `sub` is `String`, return `subscript(key:)`. + fileprivate subscript(sub sub: JSONSubscriptType) -> JSON { + get { + switch sub.jsonKey { + case .index(let index): return self[index: index] + case .key(let key): return self[key: key] + } + } + set { + switch sub.jsonKey { + case .index(let index): self[index: index] = newValue + case .key(let key): self[key: key] = newValue + } + } + } + + /** + Find a json in the complex data structures by using array of Int and/or String as path. + + Example: + + ``` + let json = JSON[data] + let path = [9,"list","person","name"] + let name = json[path] + ``` + + The same as: let name = json[9]["list"]["person"]["name"] + + - parameter path: The target json's path. + + - returns: Return a json found by the path or a null json with error + */ + public subscript(path: [JSONSubscriptType]) -> JSON { + get { + return path.reduce(self) { $0[sub: $1] } + } + set { + switch path.count { + case 0: return + case 1: self[sub:path[0]].object = newValue.object + default: + var aPath = path + aPath.remove(at: 0) + var nextJSON = self[sub: path[0]] + nextJSON[aPath] = newValue + self[sub: path[0]] = nextJSON + } + } + } + + /** + Find a json in the complex data structures by using array of Int and/or String as path. + + - parameter path: The target json's path. Example: + + let name = json[9,"list","person","name"] + + The same as: let name = json[9]["list"]["person"]["name"] + + - returns: Return a json found by the path or a null json with error + */ + public subscript(path: JSONSubscriptType...) -> JSON { + get { + return self[path] + } + set { + self[path] = newValue + } + } +} + +// MARK: - LiteralConvertible + +extension JSON: Swift.ExpressibleByStringLiteral { + + public init(stringLiteral value: StringLiteralType) { + self.init(value) + } + + public init(extendedGraphemeClusterLiteral value: StringLiteralType) { + self.init(value) + } + + public init(unicodeScalarLiteral value: StringLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByIntegerLiteral { + + public init(integerLiteral value: IntegerLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByBooleanLiteral { + + public init(booleanLiteral value: BooleanLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByFloatLiteral { + + public init(floatLiteral value: FloatLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByDictionaryLiteral { + public init(dictionaryLiteral elements: (String, Any)...) { + let dictionary = elements.reduce(into: [String: Any](), { $0[$1.0] = $1.1}) + self.init(dictionary) + } +} + +extension JSON: Swift.ExpressibleByArrayLiteral { + + public init(arrayLiteral elements: Any...) { + self.init(elements) + } +} + +// MARK: - Raw + +extension JSON: Swift.RawRepresentable { + + public init?(rawValue: Any) { + if JSON(rawValue).type == .unknown { + return nil + } else { + self.init(rawValue) + } + } + + public var rawValue: Any { + return object + } + + public func rawData(options opt: JSONSerialization.WritingOptions = JSONSerialization.WritingOptions(rawValue: 0)) throws -> Data { + guard JSONSerialization.isValidJSONObject(object) else { + throw SwiftyJSONError.invalidJSON + } + + return try JSONSerialization.data(withJSONObject: object, options: opt) + } + + public func rawString(_ encoding: String.Encoding = .utf8, options opt: JSONSerialization.WritingOptions = .prettyPrinted) -> String? { + do { + return try _rawString(encoding, options: [.jsonSerialization: opt]) + } catch { + print("Could not serialize object to JSON because:", error.localizedDescription) + return nil + } + } + + public func rawString(_ options: [writingOptionsKeys: Any]) -> String? { + let encoding = options[.encoding] as? String.Encoding ?? String.Encoding.utf8 + let maxObjectDepth = options[.maxObjextDepth] as? Int ?? 10 + do { + return try _rawString(encoding, options: options, maxObjectDepth: maxObjectDepth) + } catch { + print("Could not serialize object to JSON because:", error.localizedDescription) + return nil + } + } + + fileprivate func _rawString(_ encoding: String.Encoding = .utf8, options: [writingOptionsKeys: Any], maxObjectDepth: Int = 10) throws -> String? { + guard maxObjectDepth > 0 else { throw SwiftyJSONError.invalidJSON } + switch type { + case .dictionary: + do { + if !(options[.castNilToNSNull] as? Bool ?? false) { + let jsonOption = options[.jsonSerialization] as? JSONSerialization.WritingOptions ?? JSONSerialization.WritingOptions.prettyPrinted + let data = try rawData(options: jsonOption) + return String(data: data, encoding: encoding) + } + + guard let dict = object as? [String: Any?] else { + return nil + } + let body = try dict.keys.map { key throws -> String in + guard let value = dict[key] else { + return "\"\(key)\": null" + } + guard let unwrappedValue = value else { + return "\"\(key)\": null" + } + + let nestedValue = JSON(unwrappedValue) + guard let nestedString = try nestedValue._rawString(encoding, options: options, maxObjectDepth: maxObjectDepth - 1) else { + throw SwiftyJSONError.elementTooDeep + } + if nestedValue.type == .string { + return "\"\(key)\": \"\(nestedString.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "\"", with: "\\\""))\"" + } else { + return "\"\(key)\": \(nestedString)" + } + } + + return "{\(body.joined(separator: ","))}" + } catch _ { + return nil + } + case .array: + do { + if !(options[.castNilToNSNull] as? Bool ?? false) { + let jsonOption = options[.jsonSerialization] as? JSONSerialization.WritingOptions ?? JSONSerialization.WritingOptions.prettyPrinted + let data = try rawData(options: jsonOption) + return String(data: data, encoding: encoding) + } + + guard let array = object as? [Any?] else { + return nil + } + let body = try array.map { value throws -> String in + guard let unwrappedValue = value else { + return "null" + } + + let nestedValue = JSON(unwrappedValue) + guard let nestedString = try nestedValue._rawString(encoding, options: options, maxObjectDepth: maxObjectDepth - 1) else { + throw SwiftyJSONError.invalidJSON + } + if nestedValue.type == .string { + return "\"\(nestedString.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "\"", with: "\\\""))\"" + } else { + return nestedString + } + } + + return "[\(body.joined(separator: ","))]" + } catch _ { + return nil + } + case .string: return rawString + case .number: return rawNumber.stringValue + case .bool: return rawBool.description + case .null: return "null" + default: return nil + } + } +} + +// MARK: - Printable, DebugPrintable + +extension JSON: Swift.CustomStringConvertible, Swift.CustomDebugStringConvertible { + + public var description: String { + return rawString(options: .prettyPrinted) ?? "unknown" + } + + public var debugDescription: String { + return description + } +} + +// MARK: - Array + +extension JSON { + + //Optional [JSON] + public var array: [JSON]? { + return type == .array ? rawArray.map { JSON($0) } : nil + } + + //Non-optional [JSON] + public var arrayValue: [JSON] { + return self.array ?? [] + } + + //Optional [Any] + public var arrayObject: [Any]? { + get { + switch type { + case .array: return rawArray + default: return nil + } + } + set { + self.object = newValue ?? NSNull() + } + } +} + +// MARK: - Dictionary + +extension JSON { + + //Optional [String : JSON] + public var dictionary: [String: JSON]? { + if type == .dictionary { + var d = [String: JSON](minimumCapacity: rawDictionary.count) + rawDictionary.forEach { pair in + d[pair.key] = JSON(pair.value) + } + return d + } else { + return nil + } + } + + //Non-optional [String : JSON] + public var dictionaryValue: [String: JSON] { + return dictionary ?? [:] + } + + //Optional [String : Any] + + public var dictionaryObject: [String: Any]? { + get { + switch type { + case .dictionary: return rawDictionary + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } +} + +// MARK: - Bool + +extension JSON { // : Swift.Bool + + //Optional bool + public var bool: Bool? { + get { + switch type { + case .bool: return rawBool + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional bool + public var boolValue: Bool { + get { + switch type { + case .bool: return rawBool + case .number: return rawNumber.boolValue + case .string: return ["true", "y", "t", "yes", "1"].contains { rawString.caseInsensitiveCompare($0) == .orderedSame } + default: return false + } + } + set { + object = newValue + } + } +} + +// MARK: - String + +extension JSON { + + //Optional string + public var string: String? { + get { + switch type { + case .string: return object as? String + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional string + public var stringValue: String { + get { + switch type { + case .string: return object as? String ?? "" + case .number: return rawNumber.stringValue + case .bool: return (object as? Bool).map { String($0) } ?? "" + default: return "" + } + } + set { + object = newValue + } + } +} + +// MARK: - Number + +extension JSON { + + //Optional number + public var number: NSNumber? { + get { + switch type { + case .number: return rawNumber + case .bool: return NSNumber(value: rawBool ? 1 : 0) + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional number + public var numberValue: NSNumber { + get { + switch type { + case .string: + let decimal = NSDecimalNumber(string: object as? String) + return decimal == .notANumber ? .zero : decimal + case .number: return object as? NSNumber ?? NSNumber(value: 0) + case .bool: return NSNumber(value: rawBool ? 1 : 0) + default: return NSNumber(value: 0.0) + } + } + set { + object = newValue + } + } +} + +// MARK: - Null + +extension JSON { + + public var null: NSNull? { + set { + object = NSNull() + } + get { + switch type { + case .null: return rawNull + default: return nil + } + } + } + public func exists() -> Bool { + if let errorValue = error, (400...1000).contains(errorValue.errorCode) { + return false + } + return true + } +} + +// MARK: - URL + +extension JSON { + + //Optional URL + public var url: URL? { + get { + switch type { + case .string: + // Check for existing percent escapes first to prevent double-escaping of % character + if rawString.range(of: "%[0-9A-Fa-f]{2}", options: .regularExpression, range: nil, locale: nil) != nil { + return Foundation.URL(string: rawString) + } else if let encodedString_ = rawString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) { + // We have to use `Foundation.URL` otherwise it conflicts with the variable name. + return Foundation.URL(string: encodedString_) + } else { + return nil + } + default: + return nil + } + } + set { + object = newValue?.absoluteString ?? NSNull() + } + } +} + +// MARK: - Int, Double, Float, Int8, Int16, Int32, Int64 + +extension JSON { + + public var double: Double? { + get { + return number?.doubleValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var doubleValue: Double { + get { + return numberValue.doubleValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var float: Float? { + get { + return number?.floatValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var floatValue: Float { + get { + return numberValue.floatValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var int: Int? { + get { + return number?.intValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var intValue: Int { + get { + return numberValue.intValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt: UInt? { + get { + return number?.uintValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uIntValue: UInt { + get { + return numberValue.uintValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var int8: Int8? { + get { + return number?.int8Value + } + set { + if let newValue = newValue { + object = NSNumber(value: Int(newValue)) + } else { + object = NSNull() + } + } + } + + public var int8Value: Int8 { + get { + return numberValue.int8Value + } + set { + object = NSNumber(value: Int(newValue)) + } + } + + public var uInt8: UInt8? { + get { + return number?.uint8Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt8Value: UInt8 { + get { + return numberValue.uint8Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int16: Int16? { + get { + return number?.int16Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int16Value: Int16 { + get { + return numberValue.int16Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt16: UInt16? { + get { + return number?.uint16Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt16Value: UInt16 { + get { + return numberValue.uint16Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int32: Int32? { + get { + return number?.int32Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int32Value: Int32 { + get { + return numberValue.int32Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt32: UInt32? { + get { + return number?.uint32Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt32Value: UInt32 { + get { + return numberValue.uint32Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int64: Int64? { + get { + return number?.int64Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int64Value: Int64 { + get { + return numberValue.int64Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt64: UInt64? { + get { + return number?.uint64Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt64Value: UInt64 { + get { + return numberValue.uint64Value + } + set { + object = NSNumber(value: newValue) + } + } +} + +// MARK: - Comparable + +extension JSON: Swift.Comparable {} + +public func == (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber == rhs.rawNumber + case (.string, .string): return lhs.rawString == rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func <= (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber <= rhs.rawNumber + case (.string, .string): return lhs.rawString <= rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func >= (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber >= rhs.rawNumber + case (.string, .string): return lhs.rawString >= rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func > (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber > rhs.rawNumber + case (.string, .string): return lhs.rawString > rhs.rawString + default: return false + } +} + +public func < (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber < rhs.rawNumber + case (.string, .string): return lhs.rawString < rhs.rawString + default: return false + } +} + +private let trueNumber = NSNumber(value: true) +private let falseNumber = NSNumber(value: false) +private let trueObjCType = String(cString: trueNumber.objCType) +private let falseObjCType = String(cString: falseNumber.objCType) + +// MARK: - NSNumber: Comparable + +extension NSNumber { + fileprivate var isBool: Bool { + let objCType = String(cString: self.objCType) + if (self.compare(trueNumber) == .orderedSame && objCType == trueObjCType) || (self.compare(falseNumber) == .orderedSame && objCType == falseObjCType) { + return true + } else { + return false + } + } +} + +func == (lhs: NSNumber, rhs: NSNumber) -> Bool { + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == .orderedSame + } +} + +func != (lhs: NSNumber, rhs: NSNumber) -> Bool { + return !(lhs == rhs) +} + +func < (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == .orderedAscending + } +} + +func > (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == ComparisonResult.orderedDescending + } +} + +func <= (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) != .orderedDescending + } +} + +func >= (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) != .orderedAscending + } +} + +public enum writingOptionsKeys { + case jsonSerialization + case castNilToNSNull + case maxObjextDepth + case encoding +} + +// MARK: - JSON: Codable +extension JSON: Codable { + private static var codableTypes: [Codable.Type] { + return [ + Bool.self, + Int.self, + Int8.self, + Int16.self, + Int32.self, + Int64.self, + UInt.self, + UInt8.self, + UInt16.self, + UInt32.self, + UInt64.self, + Double.self, + String.self, + [JSON].self, + [String: JSON].self + ] + } + public init(from decoder: Decoder) throws { + var object: Any? + + if let container = try? decoder.singleValueContainer(), !container.decodeNil() { + for type in JSON.codableTypes { + if object != nil { + break + } + // try to decode value + switch type { + case let boolType as Bool.Type: + object = try? container.decode(boolType) + case let intType as Int.Type: + object = try? container.decode(intType) + case let int8Type as Int8.Type: + object = try? container.decode(int8Type) + case let int32Type as Int32.Type: + object = try? container.decode(int32Type) + case let int64Type as Int64.Type: + object = try? container.decode(int64Type) + case let uintType as UInt.Type: + object = try? container.decode(uintType) + case let uint8Type as UInt8.Type: + object = try? container.decode(uint8Type) + case let uint16Type as UInt16.Type: + object = try? container.decode(uint16Type) + case let uint32Type as UInt32.Type: + object = try? container.decode(uint32Type) + case let uint64Type as UInt64.Type: + object = try? container.decode(uint64Type) + case let doubleType as Double.Type: + object = try? container.decode(doubleType) + case let stringType as String.Type: + object = try? container.decode(stringType) + case let jsonValueArrayType as [JSON].Type: + object = try? container.decode(jsonValueArrayType) + case let jsonValueDictType as [String: JSON].Type: + object = try? container.decode(jsonValueDictType) + default: + break + } + } + } + self.init(object ?? NSNull()) + } + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + if object is NSNull { + try container.encodeNil() + return + } + switch object { + case let intValue as Int: + try container.encode(intValue) + case let int8Value as Int8: + try container.encode(int8Value) + case let int32Value as Int32: + try container.encode(int32Value) + case let int64Value as Int64: + try container.encode(int64Value) + case let uintValue as UInt: + try container.encode(uintValue) + case let uint8Value as UInt8: + try container.encode(uint8Value) + case let uint16Value as UInt16: + try container.encode(uint16Value) + case let uint32Value as UInt32: + try container.encode(uint32Value) + case let uint64Value as UInt64: + try container.encode(uint64Value) + case let doubleValue as Double: + try container.encode(doubleValue) + case let boolValue as Bool: + try container.encode(boolValue) + case let stringValue as String: + try container.encode(stringValue) + case is [Any]: + let jsonValueArray = array ?? [] + try container.encode(jsonValueArray) + case is [String: Any]: + let jsonValueDictValue = dictionary ?? [:] + try container.encode(jsonValueDictValue) + default: + break + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-Info.plist new file mode 100644 index 00000000..82c355f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 5.2.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-dummy.m new file mode 100644 index 00000000..7367f860 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_BigInt : NSObject +@end +@implementation PodsDummy_BigInt +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-umbrella.h new file mode 100644 index 00000000..e3d2506e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double BigIntVersionNumber; +FOUNDATION_EXPORT const unsigned char BigIntVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.debug.xcconfig new file mode 100644 index 00000000..3900220c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BigInt +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BigInt +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.modulemap new file mode 100644 index 00000000..48a38d1c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.modulemap @@ -0,0 +1,6 @@ +framework module BigInt { + umbrella header "BigInt-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.release.xcconfig new file mode 100644 index 00000000..3900220c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BigInt/BigInt.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BigInt +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BigInt +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-Info.plist new file mode 100644 index 00000000..324eeb2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.5.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-dummy.m new file mode 100644 index 00000000..b60ed62b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_BloctoSDK : NSObject +@end +@implementation PodsDummy_BloctoSDK +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-umbrella.h new file mode 100644 index 00000000..3db64f5e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double BloctoSDKVersionNumber; +FOUNDATION_EXPORT const unsigned char BloctoSDKVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.debug.xcconfig new file mode 100644 index 00000000..b3b6d3a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "FlowSDK" -framework "Foundation" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BloctoSDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.modulemap new file mode 100644 index 00000000..da6bc949 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.modulemap @@ -0,0 +1,6 @@ +framework module BloctoSDK { + umbrella header "BloctoSDK-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.release.xcconfig new file mode 100644 index 00000000..b3b6d3a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/BloctoSDK/BloctoSDK.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "FlowSDK" -framework "Foundation" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/BloctoSDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-Info.plist new file mode 100644 index 00000000..7cfa2845 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.8.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-dummy.m new file mode 100644 index 00000000..07f9bd31 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CGRPCZlibp : NSObject +@end +@implementation PodsDummy_CGRPCZlibp +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-umbrella.h new file mode 100644 index 00000000..abd637ac --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CGRPCZlib.h" + +FOUNDATION_EXPORT double CGRPCZlibVersionNumber; +FOUNDATION_EXPORT const unsigned char CGRPCZlibVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.debug.xcconfig new file mode 100644 index 00000000..d1396868 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CGRPCZlibp +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.modulemap new file mode 100644 index 00000000..92dbc70c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.modulemap @@ -0,0 +1,6 @@ +framework module CGRPCZlib { + umbrella header "CGRPCZlibp-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.release.xcconfig new file mode 100644 index 00000000..d1396868 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CGRPCZlibp/CGRPCZlibp.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CGRPCZlibp +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-dummy.m new file mode 100644 index 00000000..737bbece --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOAtomics : NSObject +@end +@implementation PodsDummy_CNIOAtomics +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-umbrella.h new file mode 100644 index 00000000..4fac048e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics-umbrella.h @@ -0,0 +1,18 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOAtomics.h" +#import "cpp_magic.h" + +FOUNDATION_EXPORT double CNIOAtomicsVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOAtomicsVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.debug.xcconfig new file mode 100644 index 00000000..3237f1f2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOAtomics +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.modulemap new file mode 100644 index 00000000..f4891d8e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.modulemap @@ -0,0 +1,6 @@ +framework module CNIOAtomics { + umbrella header "CNIOAtomics-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.release.xcconfig new file mode 100644 index 00000000..3237f1f2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOAtomics/CNIOAtomics.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOAtomics +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-Info.plist new file mode 100644 index 00000000..a3b6f508 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.19.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-dummy.m new file mode 100644 index 00000000..86ac201e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOBoringSSL : NSObject +@end +@implementation PodsDummy_CNIOBoringSSL +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-umbrella.h new file mode 100644 index 00000000..40783ab9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL-umbrella.h @@ -0,0 +1,98 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOBoringSSL.h" +#import "CNIOBoringSSL_aead.h" +#import "CNIOBoringSSL_aes.h" +#import "CNIOBoringSSL_arm_arch.h" +#import "CNIOBoringSSL_asn1.h" +#import "CNIOBoringSSL_asn1t.h" +#import "CNIOBoringSSL_asn1_mac.h" +#import "CNIOBoringSSL_base.h" +#import "CNIOBoringSSL_base64.h" +#import "CNIOBoringSSL_bio.h" +#import "CNIOBoringSSL_blake2.h" +#import "CNIOBoringSSL_blowfish.h" +#import "CNIOBoringSSL_bn.h" +#import "CNIOBoringSSL_boringssl_prefix_symbols.h" +#import "CNIOBoringSSL_boringssl_prefix_symbols_asm.h" +#import "CNIOBoringSSL_buf.h" +#import "CNIOBoringSSL_buffer.h" +#import "CNIOBoringSSL_bytestring.h" +#import "CNIOBoringSSL_cast.h" +#import "CNIOBoringSSL_chacha.h" +#import "CNIOBoringSSL_cipher.h" +#import "CNIOBoringSSL_cmac.h" +#import "CNIOBoringSSL_conf.h" +#import "CNIOBoringSSL_cpu.h" +#import "CNIOBoringSSL_crypto.h" +#import "CNIOBoringSSL_curve25519.h" +#import "CNIOBoringSSL_des.h" +#import "CNIOBoringSSL_dh.h" +#import "CNIOBoringSSL_digest.h" +#import "CNIOBoringSSL_dsa.h" +#import "CNIOBoringSSL_dtls1.h" +#import "CNIOBoringSSL_ec.h" +#import "CNIOBoringSSL_ecdh.h" +#import "CNIOBoringSSL_ecdsa.h" +#import "CNIOBoringSSL_ec_key.h" +#import "CNIOBoringSSL_engine.h" +#import "CNIOBoringSSL_err.h" +#import "CNIOBoringSSL_evp.h" +#import "CNIOBoringSSL_evp_errors.h" +#import "CNIOBoringSSL_ex_data.h" +#import "CNIOBoringSSL_e_os2.h" +#import "CNIOBoringSSL_hkdf.h" +#import "CNIOBoringSSL_hmac.h" +#import "CNIOBoringSSL_hpke.h" +#import "CNIOBoringSSL_hrss.h" +#import "CNIOBoringSSL_is_boringssl.h" +#import "CNIOBoringSSL_lhash.h" +#import "CNIOBoringSSL_md4.h" +#import "CNIOBoringSSL_md5.h" +#import "CNIOBoringSSL_mem.h" +#import "CNIOBoringSSL_nid.h" +#import "CNIOBoringSSL_obj.h" +#import "CNIOBoringSSL_objects.h" +#import "CNIOBoringSSL_obj_mac.h" +#import "CNIOBoringSSL_opensslconf.h" +#import "CNIOBoringSSL_opensslv.h" +#import "CNIOBoringSSL_ossl_typ.h" +#import "CNIOBoringSSL_pem.h" +#import "CNIOBoringSSL_pkcs12.h" +#import "CNIOBoringSSL_pkcs7.h" +#import "CNIOBoringSSL_pkcs8.h" +#import "CNIOBoringSSL_poly1305.h" +#import "CNIOBoringSSL_pool.h" +#import "CNIOBoringSSL_rand.h" +#import "CNIOBoringSSL_rc4.h" +#import "CNIOBoringSSL_ripemd.h" +#import "CNIOBoringSSL_rsa.h" +#import "CNIOBoringSSL_safestack.h" +#import "CNIOBoringSSL_sha.h" +#import "CNIOBoringSSL_siphash.h" +#import "CNIOBoringSSL_span.h" +#import "CNIOBoringSSL_srtp.h" +#import "CNIOBoringSSL_ssl.h" +#import "CNIOBoringSSL_ssl3.h" +#import "CNIOBoringSSL_stack.h" +#import "CNIOBoringSSL_thread.h" +#import "CNIOBoringSSL_tls1.h" +#import "CNIOBoringSSL_trust_token.h" +#import "CNIOBoringSSL_type_check.h" +#import "CNIOBoringSSL_x509.h" +#import "CNIOBoringSSL_x509v3.h" +#import "CNIOBoringSSL_x509_vfy.h" + +FOUNDATION_EXPORT double CNIOBoringSSLVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOBoringSSLVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.debug.xcconfig new file mode 100644 index 00000000..5cd55ff4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) Sources/CNIOBoringSSL/include +OTHER_LDFLAGS = $(inherited) -l"c++" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOBoringSSL +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.modulemap new file mode 100644 index 00000000..0ff5f66b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.modulemap @@ -0,0 +1,6 @@ +framework module CNIOBoringSSL { + umbrella header "CNIOBoringSSL-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.release.xcconfig new file mode 100644 index 00000000..5cd55ff4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSL/CNIOBoringSSL.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) Sources/CNIOBoringSSL/include +OTHER_LDFLAGS = $(inherited) -l"c++" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOBoringSSL +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-Info.plist new file mode 100644 index 00000000..a3b6f508 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.19.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-dummy.m new file mode 100644 index 00000000..3ec68a77 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOBoringSSLShims : NSObject +@end +@implementation PodsDummy_CNIOBoringSSLShims +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-umbrella.h new file mode 100644 index 00000000..eae2b1a4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOBoringSSLShims.h" + +FOUNDATION_EXPORT double CNIOBoringSSLShimsVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOBoringSSLShimsVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.debug.xcconfig new file mode 100644 index 00000000..dc3eb839 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) Sources/CNIOBoringSSLShims/include +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "CNIOBoringSSL" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOBoringSSLShims +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.modulemap new file mode 100644 index 00000000..7f83ecdd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.modulemap @@ -0,0 +1,6 @@ +framework module CNIOBoringSSLShims { + umbrella header "CNIOBoringSSLShims-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.release.xcconfig new file mode 100644 index 00000000..dc3eb839 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOBoringSSLShims/CNIOBoringSSLShims.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) Sources/CNIOBoringSSLShims/include +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "CNIOBoringSSL" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOBoringSSLShims +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-dummy.m new file mode 100644 index 00000000..ead34311 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIODarwin : NSObject +@end +@implementation PodsDummy_CNIODarwin +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-umbrella.h new file mode 100644 index 00000000..1728b117 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIODarwin.h" + +FOUNDATION_EXPORT double CNIODarwinVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIODarwinVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.debug.xcconfig new file mode 100644 index 00000000..3cba2047 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIODarwin +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.modulemap new file mode 100644 index 00000000..df1843e6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.modulemap @@ -0,0 +1,6 @@ +framework module CNIODarwin { + umbrella header "CNIODarwin-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.release.xcconfig new file mode 100644 index 00000000..3cba2047 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIODarwin/CNIODarwin.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIODarwin +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-dummy.m new file mode 100644 index 00000000..6c6c8916 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOHTTPParser : NSObject +@end +@implementation PodsDummy_CNIOHTTPParser +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-umbrella.h new file mode 100644 index 00000000..7527c1dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser-umbrella.h @@ -0,0 +1,18 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOHTTPParser.h" +#import "c_nio_http_parser.h" + +FOUNDATION_EXPORT double CNIOHTTPParserVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOHTTPParserVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.debug.xcconfig new file mode 100644 index 00000000..4b941c54 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOHTTPParser +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.modulemap new file mode 100644 index 00000000..ee7bc9ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.modulemap @@ -0,0 +1,6 @@ +framework module CNIOHTTPParser { + umbrella header "CNIOHTTPParser-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.release.xcconfig new file mode 100644 index 00000000..4b941c54 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOHTTPParser/CNIOHTTPParser.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOHTTPParser +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-dummy.m new file mode 100644 index 00000000..249b3cfb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOLinux : NSObject +@end +@implementation PodsDummy_CNIOLinux +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-umbrella.h new file mode 100644 index 00000000..c06a7079 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux-umbrella.h @@ -0,0 +1,18 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOLinux.h" +#import "liburing_nio.h" + +FOUNDATION_EXPORT double CNIOLinuxVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOLinuxVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.debug.xcconfig new file mode 100644 index 00000000..c148af66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOLinux +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.modulemap new file mode 100644 index 00000000..d96c7c91 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.modulemap @@ -0,0 +1,6 @@ +framework module CNIOLinux { + umbrella header "CNIOLinux-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.release.xcconfig new file mode 100644 index 00000000..c148af66 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOLinux/CNIOLinux.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOLinux +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-dummy.m new file mode 100644 index 00000000..777e1173 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CNIOWindows : NSObject +@end +@implementation PodsDummy_CNIOWindows +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-umbrella.h new file mode 100644 index 00000000..4cc53b44 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CNIOWindows.h" + +FOUNDATION_EXPORT double CNIOWindowsVersionNumber; +FOUNDATION_EXPORT const unsigned char CNIOWindowsVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.debug.xcconfig new file mode 100644 index 00000000..94e470ab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.debug.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOWindows +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.modulemap new file mode 100644 index 00000000..0f85d685 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.modulemap @@ -0,0 +1,6 @@ +framework module CNIOWindows { + umbrella header "CNIOWindows-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.release.xcconfig new file mode 100644 index 00000000..94e470ab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CNIOWindows/CNIOWindows.release.xcconfig @@ -0,0 +1,11 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CNIOWindows +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-Info.plist new file mode 100644 index 00000000..324eeb2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.5.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-dummy.m new file mode 100644 index 00000000..0b6150d6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Cadence : NSObject +@end +@implementation PodsDummy_Cadence +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-umbrella.h new file mode 100644 index 00000000..088908cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double CadenceVersionNumber; +FOUNDATION_EXPORT const unsigned char CadenceVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.debug.xcconfig new file mode 100644 index 00000000..77837ebb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Cadence +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BigInt" -framework "CryptoSwift" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Cadence +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.modulemap new file mode 100644 index 00000000..1c40e60d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.modulemap @@ -0,0 +1,6 @@ +framework module Cadence { + umbrella header "Cadence-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.release.xcconfig new file mode 100644 index 00000000..77837ebb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Cadence/Cadence.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Cadence +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BigInt" -framework "CryptoSwift" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Cadence +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-Info.plist new file mode 100644 index 00000000..b53fe91e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.5.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-dummy.m new file mode 100644 index 00000000..657061bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_CryptoSwift : NSObject +@end +@implementation PodsDummy_CryptoSwift +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-umbrella.h new file mode 100644 index 00000000..e93efa88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double CryptoSwiftVersionNumber; +FOUNDATION_EXPORT const unsigned char CryptoSwiftVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.debug.xcconfig new file mode 100644 index 00000000..548e9978 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CryptoSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.modulemap new file mode 100644 index 00000000..f090f6a3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.modulemap @@ -0,0 +1,6 @@ +framework module CryptoSwift { + umbrella header "CryptoSwift-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.release.xcconfig new file mode 100644 index 00000000..548e9978 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/CryptoSwift/CryptoSwift.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/CryptoSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-Info.plist new file mode 100644 index 00000000..c26f36f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-dummy.m new file mode 100644 index 00000000..56dd6da0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_DynamicBlurView : NSObject +@end +@implementation PodsDummy_DynamicBlurView +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-umbrella.h new file mode 100644 index 00000000..9268b717 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "DynamicBlurView.h" + +FOUNDATION_EXPORT double DynamicBlurViewVersionNumber; +FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.debug.xcconfig new file mode 100644 index 00000000..ebb74598 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/DynamicBlurView +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.modulemap new file mode 100644 index 00000000..b654e768 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.modulemap @@ -0,0 +1,6 @@ +framework module DynamicBlurView { + umbrella header "DynamicBlurView-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.release.xcconfig new file mode 100644 index 00000000..ebb74598 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/DynamicBlurView/DynamicBlurView.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/DynamicBlurView +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-Info.plist new file mode 100644 index 00000000..2ae1777f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.3.3 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-dummy.m new file mode 100644 index 00000000..70d16774 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FCL_SDK : NSObject +@end +@implementation PodsDummy_FCL_SDK +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-umbrella.h new file mode 100644 index 00000000..130cf24e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double FCL_SDKVersionNumber; +FOUNDATION_EXPORT const unsigned char FCL_SDKVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.debug.xcconfig new file mode 100644 index 00000000..baaa3147 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BloctoSDK" -framework "Foundation" -framework "SwiftyJSON" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FCL-SDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.modulemap new file mode 100644 index 00000000..ed3cda90 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.modulemap @@ -0,0 +1,6 @@ +framework module FCL_SDK { + umbrella header "FCL-SDK-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.release.xcconfig new file mode 100644 index 00000000..baaa3147 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FCL-SDK/FCL-SDK.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BloctoSDK" -framework "Foundation" -framework "SwiftyJSON" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FCL-SDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-Info.plist new file mode 100644 index 00000000..324eeb2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.5.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-dummy.m new file mode 100644 index 00000000..8d282d10 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FlowSDK : NSObject +@end +@implementation PodsDummy_FlowSDK +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-umbrella.h new file mode 100644 index 00000000..6251443f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double FlowSDKVersionNumber; +FOUNDATION_EXPORT const unsigned char FlowSDKVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.debug.xcconfig new file mode 100644 index 00000000..e231a263 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BigInt" -framework "Cadence" -framework "CryptoSwift" -framework "GRPC" -framework "secp256k1Swift" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FlowSDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.modulemap new file mode 100644 index 00000000..589d1b1e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.modulemap @@ -0,0 +1,6 @@ +framework module FlowSDK { + umbrella header "FlowSDK-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.release.xcconfig new file mode 100644 index 00000000..e231a263 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/FlowSDK/FlowSDK.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "BigInt" -framework "Cadence" -framework "CryptoSwift" -framework "GRPC" -framework "secp256k1Swift" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FlowSDK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-Info.plist new file mode 100644 index 00000000..7b6b52a4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.4.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-dummy.m new file mode 100644 index 00000000..40d643a2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Logging : NSObject +@end +@implementation PodsDummy_Logging +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-umbrella.h new file mode 100644 index 00000000..276b50e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double LoggingVersionNumber; +FOUNDATION_EXPORT const unsigned char LoggingVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.debug.xcconfig new file mode 100644 index 00000000..16f2464e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Logging +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Logging +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.modulemap new file mode 100644 index 00000000..ba5c55fe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.modulemap @@ -0,0 +1,6 @@ +framework module Logging { + umbrella header "Logging-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.release.xcconfig new file mode 100644 index 00000000..16f2464e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Logging/Logging.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Logging +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Logging +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-Info.plist new file mode 100644 index 00000000..62cf7b2f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.9.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-dummy.m new file mode 100644 index 00000000..dd444285 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_MercariQRScanner : NSObject +@end +@implementation PodsDummy_MercariQRScanner +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-umbrella.h new file mode 100644 index 00000000..82f3c0e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double MercariQRScannerVersionNumber; +FOUNDATION_EXPORT const unsigned char MercariQRScannerVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.debug.xcconfig new file mode 100644 index 00000000..92bf216c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/MercariQRScanner +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.modulemap new file mode 100644 index 00000000..aa7eecad --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.modulemap @@ -0,0 +1,6 @@ +framework module MercariQRScanner { + umbrella header "MercariQRScanner-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.release.xcconfig new file mode 100644 index 00000000..92bf216c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/MercariQRScanner/MercariQRScanner.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/MercariQRScanner +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-Info.plist new file mode 100644 index 00000000..2243fe6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.markdown b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.markdown new file mode 100644 index 00000000..49aedabb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.markdown @@ -0,0 +1,5854 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## BigInt + + +Copyright (c) 2016-2017 Károly Lőrentey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## BloctoSDK + +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## CGRPCZlibp + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOAtomics + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOBoringSSL + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOBoringSSLShims + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIODarwin + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOHTTPParser + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOLinux + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOWindows + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## Cadence + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CryptoSwift + +Copyright (C) 2014-2017 Marcin Krzyżanowski +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + + +## DynamicBlurView + +The MIT License (MIT) + +Copyright (c) 2015 Kyohei Ito + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + +## FCL-SDK + +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## FlowSDK + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## Logging + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## MercariQRScanner + +MIT License + +Copyright (c) 2019 Mercari, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## PopupDialog + +Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +Author - Martin Wildfeuer (http://www.mwfire.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## SDWebImage + +Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + +## SVProgressHUD + +MIT License + +Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## SwiftNIO + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOConcurrencyHelpers + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOCore + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOEmbedded + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOExtras + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOFoundationCompat + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHPACK + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHTTP1 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHTTP2 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOPosix + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOSSL + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOTLS + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOTransportServices + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftProtobuf + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + +## SwiftyJSON + +The MIT License (MIT) + +Copyright (c) 2017 Ruoyu Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## _NIODataStructures + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## gRPC-Swiftp + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## secp256k1Swift + +MIT License + +Copyright (c) 2020 GigaBitcoin LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## secp256k1Wrapper + +Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.plist new file mode 100644 index 00000000..3dc723b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-acknowledgements.plist @@ -0,0 +1,6114 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + +Copyright (c) 2016-2017 Károly Lőrentey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + BigInt + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2022 portto <dev@portto.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + BloctoSDK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CGRPCZlibp + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOAtomics + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOBoringSSL + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOBoringSSLShims + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIODarwin + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOHTTPParser + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOLinux + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOWindows + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + Cadence + Type + PSGroupSpecifier + + + FooterText + Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin.krzyzanowski@gmail.com> +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + + License + Attribution + Title + CryptoSwift + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Kyohei Ito + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + License + MIT + Title + DynamicBlurView + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2022 portto <dev@portto.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + FCL-SDK + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + FlowSDK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + Logging + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2019 Mercari, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + MercariQRScanner + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +Author - Martin Wildfeuer (http://www.mwfire.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + PopupDialog + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + License + MIT + Title + SDWebImage + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + SVProgressHUD + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIO + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOConcurrencyHelpers + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOCore + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOEmbedded + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOExtras + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOFoundationCompat + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHPACK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHTTP1 + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHTTP2 + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOPosix + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOSSL + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOTLS + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOTransportServices + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + License + Apache 2.0 + Title + SwiftProtobuf + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2017 Ruoyu Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + SwiftyJSON + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + _NIODataStructures + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + gRPC-Swiftp + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2020 GigaBitcoin LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + secp256k1Swift + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + secp256k1Wrapper + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-dummy.m new file mode 100644 index 00000000..4e7ea805 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_fanex_fanexUITests : NSObject +@end +@implementation PodsDummy_Pods_fanex_fanexUITests +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-input-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 00000000..1e518a09 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,40 @@ +${PODS_ROOT}/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh +${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework +${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework +${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework +${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework +${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework +${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework +${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework +${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework +${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework +${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework +${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework +${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework +${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework +${BUILT_PRODUCTS_DIR}/Logging/Logging.framework +${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework +${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework +${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework +${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework +${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework +${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework +${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework +${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework +${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework +${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework +${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-output-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 00000000..377e9076 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,39 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BloctoSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CGRPCZlib.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOAtomics.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSLShims.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIODarwin.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOHTTPParser.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOLinux.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOWindows.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cadence.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FCL_SDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FlowSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Logging.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MercariQRScanner.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIO.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOConcurrencyHelpers.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOEmbedded.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOExtras.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOFoundationCompat.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHPACK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP1.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP2.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOPosix.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTLS.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTransportServices.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/_NIODataStructures.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPC.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Swift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-input-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-input-files.xcfilelist new file mode 100644 index 00000000..1e518a09 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,40 @@ +${PODS_ROOT}/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh +${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework +${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework +${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework +${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework +${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework +${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework +${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework +${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework +${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework +${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework +${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework +${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework +${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework +${BUILT_PRODUCTS_DIR}/Logging/Logging.framework +${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework +${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework +${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework +${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework +${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework +${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework +${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework +${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework +${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework +${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework +${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-output-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-output-files.xcfilelist new file mode 100644 index 00000000..377e9076 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,39 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BloctoSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CGRPCZlib.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOAtomics.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSLShims.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIODarwin.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOHTTPParser.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOLinux.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOWindows.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cadence.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FCL_SDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FlowSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Logging.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MercariQRScanner.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIO.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOConcurrencyHelpers.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOEmbedded.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOExtras.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOFoundationCompat.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHPACK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP1.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP2.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOPosix.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTLS.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTransportServices.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/_NIODataStructures.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPC.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Swift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh new file mode 100755 index 00000000..30d07b97 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh @@ -0,0 +1,262 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework" + install_framework "${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Logging/Logging.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework" + install_framework "${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework" + install_framework "${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework" + install_framework "${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Logging/Logging.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework" + install_framework "${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework" + install_framework "${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-umbrella.h new file mode 100644 index 00000000..9fbaa9ea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_fanex_fanexUITestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_fanex_fanexUITestsVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.debug.xcconfig new file mode 100644 index 00000000..cf010933 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.debug.xcconfig @@ -0,0 +1,18 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.modulemap new file mode 100644 index 00000000..52a67af0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_fanex_fanexUITests { + umbrella header "Pods-fanex-fanexUITests-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.release.xcconfig new file mode 100644 index 00000000..cf010933 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.release.xcconfig @@ -0,0 +1,18 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-Info.plist new file mode 100644 index 00000000..2243fe6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.markdown b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.markdown new file mode 100644 index 00000000..49aedabb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.markdown @@ -0,0 +1,5854 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## BigInt + + +Copyright (c) 2016-2017 Károly Lőrentey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## BloctoSDK + +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## CGRPCZlibp + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOAtomics + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOBoringSSL + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOBoringSSLShims + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIODarwin + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOHTTPParser + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOLinux + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CNIOWindows + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## Cadence + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## CryptoSwift + +Copyright (C) 2014-2017 Marcin Krzyżanowski +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + + +## DynamicBlurView + +The MIT License (MIT) + +Copyright (c) 2015 Kyohei Ito + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + +## FCL-SDK + +Copyright (c) 2022 portto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## FlowSDK + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## Logging + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## MercariQRScanner + +MIT License + +Copyright (c) 2019 Mercari, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## PopupDialog + +Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +Author - Martin Wildfeuer (http://www.mwfire.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## SDWebImage + +Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + +## SVProgressHUD + +MIT License + +Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## SwiftNIO + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOConcurrencyHelpers + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOCore + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOEmbedded + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOExtras + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOFoundationCompat + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHPACK + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHTTP1 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOHTTP2 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOPosix + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOSSL + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOTLS + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftNIOTransportServices + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## SwiftProtobuf + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + +## SwiftyJSON + +The MIT License (MIT) + +Copyright (c) 2017 Ruoyu Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## _NIODataStructures + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## gRPC-Swiftp + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## secp256k1Swift + +MIT License + +Copyright (c) 2020 GigaBitcoin LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## secp256k1Wrapper + +Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.plist new file mode 100644 index 00000000..3dc723b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-acknowledgements.plist @@ -0,0 +1,6114 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + +Copyright (c) 2016-2017 Károly Lőrentey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + BigInt + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2022 portto <dev@portto.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + BloctoSDK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CGRPCZlibp + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOAtomics + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOBoringSSL + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOBoringSSLShims + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIODarwin + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOHTTPParser + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOLinux + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + CNIOWindows + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + Cadence + Type + PSGroupSpecifier + + + FooterText + Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin.krzyzanowski@gmail.com> +This software is provided 'as-is', without any express or implied warranty. + +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. +- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +- This notice may not be removed or altered from any source or binary distribution. +- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).' + + License + Attribution + Title + CryptoSwift + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Kyohei Ito + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + License + MIT + Title + DynamicBlurView + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2022 portto <dev@portto.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + FCL-SDK + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + FlowSDK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + Logging + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2019 Mercari, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + MercariQRScanner + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk) +Author - Martin Wildfeuer (http://www.mwfire.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + PopupDialog + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2009-2020 Olivier Poitrey rs@dailymotion.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + License + MIT + Title + SDWebImage + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2011-2018 Sam Vermette, Tobias Tiemerding and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + SVProgressHUD + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIO + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOConcurrencyHelpers + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOCore + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOEmbedded + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOExtras + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOFoundationCompat + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHPACK + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHTTP1 + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOHTTP2 + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOPosix + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOSSL + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOTLS + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + SwiftNIOTransportServices + Type + PSGroupSpecifier + + + FooterText + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + License + Apache 2.0 + Title + SwiftProtobuf + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2017 Ruoyu Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + SwiftyJSON + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + _NIODataStructures + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + License + Apache 2.0 + Title + gRPC-Swiftp + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2020 GigaBitcoin LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + secp256k1Swift + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + secp256k1Wrapper + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-dummy.m new file mode 100644 index 00000000..3913e05b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_fanex : NSObject +@end +@implementation PodsDummy_Pods_fanex +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-input-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 00000000..c087e94a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,40 @@ +${PODS_ROOT}/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh +${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework +${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework +${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework +${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework +${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework +${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework +${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework +${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework +${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework +${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework +${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework +${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework +${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework +${BUILT_PRODUCTS_DIR}/Logging/Logging.framework +${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework +${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework +${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework +${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework +${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework +${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework +${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework +${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework +${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework +${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework +${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-output-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 00000000..377e9076 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,39 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BloctoSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CGRPCZlib.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOAtomics.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSLShims.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIODarwin.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOHTTPParser.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOLinux.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOWindows.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cadence.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FCL_SDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FlowSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Logging.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MercariQRScanner.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIO.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOConcurrencyHelpers.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOEmbedded.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOExtras.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOFoundationCompat.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHPACK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP1.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP2.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOPosix.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTLS.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTransportServices.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/_NIODataStructures.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPC.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Swift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-input-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-input-files.xcfilelist new file mode 100644 index 00000000..c087e94a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,40 @@ +${PODS_ROOT}/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh +${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework +${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework +${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework +${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework +${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework +${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework +${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework +${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework +${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework +${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework +${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework +${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework +${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework +${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework +${BUILT_PRODUCTS_DIR}/Logging/Logging.framework +${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework +${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework +${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework +${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework +${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework +${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework +${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework +${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework +${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework +${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework +${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework +${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-output-files.xcfilelist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-output-files.xcfilelist new file mode 100644 index 00000000..377e9076 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,39 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BloctoSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CGRPCZlib.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOAtomics.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOBoringSSLShims.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIODarwin.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOHTTPParser.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOLinux.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNIOWindows.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cadence.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FCL_SDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FlowSDK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Logging.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MercariQRScanner.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIO.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOConcurrencyHelpers.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOEmbedded.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOExtras.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOFoundationCompat.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHPACK.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP1.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOHTTP2.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOPosix.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOSSL.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTLS.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NIOTransportServices.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/_NIODataStructures.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRPC.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Swift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1Wrapper.framework \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh new file mode 100755 index 00000000..30d07b97 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh @@ -0,0 +1,262 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework" + install_framework "${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Logging/Logging.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework" + install_framework "${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework" + install_framework "${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework" + install_framework "${BUILT_PRODUCTS_DIR}/BloctoSDK/BloctoSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CGRPCZlibp/CGRPCZlib.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOAtomics/CNIOAtomics.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIODarwin/CNIODarwin.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOLinux/CNIOLinux.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CNIOWindows/CNIOWindows.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Cadence/Cadence.framework" + install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FCL-SDK/FCL_SDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FlowSDK/FlowSDK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Logging/Logging.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MercariQRScanner/MercariQRScanner.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIO/NIO.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOCore/NIOCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOExtras/NIOExtras.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHPACK/NIOHPACK.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOPosix/NIOPosix.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOSSL/NIOSSL.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTLS/NIOTLS.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework" + install_framework "${BUILT_PRODUCTS_DIR}/_NIODataStructures/_NIODataStructures.framework" + install_framework "${BUILT_PRODUCTS_DIR}/gRPC-Swiftp/GRPC.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Swift/secp256k1Swift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-umbrella.h new file mode 100644 index 00000000..ecf7a4dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_fanexVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_fanexVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.debug.xcconfig new file mode 100644 index 00000000..fb5301b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.debug.xcconfig @@ -0,0 +1,18 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.modulemap new file mode 100644 index 00000000..29a62838 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.modulemap @@ -0,0 +1,6 @@ +framework module Pods_fanex { + umbrella header "Pods-fanex-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.release.xcconfig new file mode 100644 index 00000000..fb5301b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanex/Pods-fanex.release.xcconfig @@ -0,0 +1,18 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-Info.plist new file mode 100644 index 00000000..2243fe6e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.markdown b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.markdown new file mode 100644 index 00000000..102af753 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.plist new file mode 100644 index 00000000..7acbad1e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-dummy.m new file mode 100644 index 00000000..65d3e513 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_fanexTests : NSObject +@end +@implementation PodsDummy_Pods_fanexTests +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-umbrella.h new file mode 100644 index 00000000..e532a96c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_fanexTestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_fanexTestsVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.debug.xcconfig new file mode 100644 index 00000000..4b952638 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.modulemap new file mode 100644 index 00000000..52427ea0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_fanexTests { + umbrella header "Pods-fanexTests-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.release.xcconfig new file mode 100644 index 00000000..4b952638 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/Pods-fanexTests/Pods-fanexTests.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES +CLANG_CXX_LANGUAGE_STANDARD = c++14 +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BigInt/BigInt.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/BloctoSDK/BloctoSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp/CGRPCZlib.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics/CNIOAtomics.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL/CNIOBoringSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims/CNIOBoringSSLShims.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin/CNIODarwin.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser/CNIOHTTPParser.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux/CNIOLinux.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows/CNIOWindows.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cadence/Cadence.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView/DynamicBlurView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FCL-SDK/FCL_SDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FlowSDK/FlowSDK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logging/Logging.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MercariQRScanner/MercariQRScanner.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog/PopupDialog.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD/SVProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO/NIO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers/NIOConcurrencyHelpers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore/NIOCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded/NIOEmbedded.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras/NIOExtras.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat/NIOFoundationCompat.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK/NIOHPACK.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1/NIOHTTP1.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2/NIOHTTP2.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix/NIOPosix.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL/NIOSSL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS/NIOTLS.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices/NIOTransportServices.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures/_NIODataStructures.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp/GRPC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift/secp256k1Swift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper/secp256k1Wrapper.framework/Headers" Sources/CNIOBoringSSL/include Sources/CNIOBoringSSLShims/include $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "Accelerate" -framework "BigInt" -framework "BloctoSDK" -framework "CGRPCZlib" -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "Cadence" -framework "CryptoSwift" -framework "DynamicBlurView" -framework "FCL_SDK" -framework "FlowSDK" -framework "Foundation" -framework "GRPC" -framework "ImageIO" -framework "Logging" -framework "MercariQRScanner" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOExtras" -framework "NIOFoundationCompat" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOHTTP2" -framework "NIOPosix" -framework "NIOSSL" -framework "NIOTLS" -framework "NIOTransportServices" -framework "PopupDialog" -framework "QuartzCore" -framework "SDWebImage" -framework "SVProgressHUD" -framework "SwiftProtobuf" -framework "SwiftyJSON" -framework "UIKit" -framework "_NIODataStructures" -framework "secp256k1Swift" -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-Info.plist new file mode 100644 index 00000000..d60f138d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.1.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-dummy.m new file mode 100644 index 00000000..47365c26 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_PopupDialog : NSObject +@end +@implementation PodsDummy_PopupDialog +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-umbrella.h new file mode 100644 index 00000000..8e51a468 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double PopupDialogVersionNumber; +FOUNDATION_EXPORT const unsigned char PopupDialogVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.debug.xcconfig new file mode 100644 index 00000000..b4cfb65d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "DynamicBlurView" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PopupDialog +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.modulemap new file mode 100644 index 00000000..07041a2e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.modulemap @@ -0,0 +1,6 @@ +framework module PopupDialog { + umbrella header "PopupDialog-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.release.xcconfig new file mode 100644 index 00000000..b4cfb65d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/PopupDialog/PopupDialog.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PopupDialog +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DynamicBlurView" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "DynamicBlurView" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PopupDialog +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-Info.plist new file mode 100644 index 00000000..ae0b0d15 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 5.12.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-dummy.m new file mode 100644 index 00000000..86d2b5f6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SDWebImage : NSObject +@end +@implementation PodsDummy_SDWebImage +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-umbrella.h new file mode 100644 index 00000000..716e1836 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage-umbrella.h @@ -0,0 +1,75 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "NSButton+WebCache.h" +#import "NSData+ImageContentType.h" +#import "NSImage+Compatibility.h" +#import "SDAnimatedImage.h" +#import "SDAnimatedImagePlayer.h" +#import "SDAnimatedImageRep.h" +#import "SDAnimatedImageView+WebCache.h" +#import "SDAnimatedImageView.h" +#import "SDDiskCache.h" +#import "SDGraphicsImageRenderer.h" +#import "SDImageAPNGCoder.h" +#import "SDImageAWebPCoder.h" +#import "SDImageCache.h" +#import "SDImageCacheConfig.h" +#import "SDImageCacheDefine.h" +#import "SDImageCachesManager.h" +#import "SDImageCoder.h" +#import "SDImageCoderHelper.h" +#import "SDImageCodersManager.h" +#import "SDImageFrame.h" +#import "SDImageGIFCoder.h" +#import "SDImageGraphics.h" +#import "SDImageHEICCoder.h" +#import "SDImageIOAnimatedCoder.h" +#import "SDImageIOCoder.h" +#import "SDImageLoader.h" +#import "SDImageLoadersManager.h" +#import "SDImageTransformer.h" +#import "SDMemoryCache.h" +#import "SDWebImageCacheKeyFilter.h" +#import "SDWebImageCacheSerializer.h" +#import "SDWebImageCompat.h" +#import "SDWebImageDefine.h" +#import "SDWebImageDownloader.h" +#import "SDWebImageDownloaderConfig.h" +#import "SDWebImageDownloaderDecryptor.h" +#import "SDWebImageDownloaderOperation.h" +#import "SDWebImageDownloaderRequestModifier.h" +#import "SDWebImageDownloaderResponseModifier.h" +#import "SDWebImageError.h" +#import "SDWebImageIndicator.h" +#import "SDWebImageManager.h" +#import "SDWebImageOperation.h" +#import "SDWebImageOptionsProcessor.h" +#import "SDWebImagePrefetcher.h" +#import "SDWebImageTransition.h" +#import "UIButton+WebCache.h" +#import "UIImage+ExtendedCacheData.h" +#import "UIImage+ForceDecode.h" +#import "UIImage+GIF.h" +#import "UIImage+MemoryCacheCost.h" +#import "UIImage+Metadata.h" +#import "UIImage+MultiFormat.h" +#import "UIImage+Transform.h" +#import "UIImageView+HighlightedWebCache.h" +#import "UIImageView+WebCache.h" +#import "UIView+WebCache.h" +#import "UIView+WebCacheOperation.h" +#import "SDWebImage.h" + +FOUNDATION_EXPORT double SDWebImageVersionNumber; +FOUNDATION_EXPORT const unsigned char SDWebImageVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig new file mode 100644 index 00000000..7653e010 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage +DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "ImageIO" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SUPPORTS_MACCATALYST = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.modulemap new file mode 100644 index 00000000..91545be6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.modulemap @@ -0,0 +1,6 @@ +framework module SDWebImage { + umbrella header "SDWebImage-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig new file mode 100644 index 00000000..7653e010 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage +DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "ImageIO" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SUPPORTS_MACCATALYST = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist new file mode 100644 index 00000000..ce4ba6f8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.2.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-dummy.m new file mode 100644 index 00000000..696032a7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SVProgressHUD : NSObject +@end +@implementation PodsDummy_SVProgressHUD +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-umbrella.h new file mode 100644 index 00000000..bff1d78b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD-umbrella.h @@ -0,0 +1,20 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "SVIndefiniteAnimatedView.h" +#import "SVProgressAnimatedView.h" +#import "SVProgressHUD.h" +#import "SVRadialGradientLayer.h" + +FOUNDATION_EXPORT double SVProgressHUDVersionNumber; +FOUNDATION_EXPORT const unsigned char SVProgressHUDVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig new file mode 100644 index 00000000..821dee86 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "QuartzCore" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVProgressHUD +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.modulemap new file mode 100644 index 00000000..2eaf140a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.modulemap @@ -0,0 +1,6 @@ +framework module SVProgressHUD { + umbrella header "SVProgressHUD-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig new file mode 100644 index 00000000..821dee86 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SVProgressHUD/SVProgressHUD.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVProgressHUD +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "QuartzCore" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVProgressHUD +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-dummy.m new file mode 100644 index 00000000..79adf722 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIO : NSObject +@end +@implementation PodsDummy_SwiftNIO +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-umbrella.h new file mode 100644 index 00000000..111cef00 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.debug.xcconfig new file mode 100644 index 00000000..d895370e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIO +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.modulemap new file mode 100644 index 00000000..2a7305d1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.modulemap @@ -0,0 +1,6 @@ +framework module NIO { + umbrella header "SwiftNIO-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.release.xcconfig new file mode 100644 index 00000000..d895370e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIO/SwiftNIO.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIO +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-dummy.m new file mode 100644 index 00000000..67da8337 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOConcurrencyHelpers : NSObject +@end +@implementation PodsDummy_SwiftNIOConcurrencyHelpers +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-umbrella.h new file mode 100644 index 00000000..9e518460 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOConcurrencyHelpersVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOConcurrencyHelpersVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.debug.xcconfig new file mode 100644 index 00000000..ea1f9398 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOConcurrencyHelpers +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.modulemap new file mode 100644 index 00000000..d80cd90c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.modulemap @@ -0,0 +1,6 @@ +framework module NIOConcurrencyHelpers { + umbrella header "SwiftNIOConcurrencyHelpers-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.release.xcconfig new file mode 100644 index 00000000..ea1f9398 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOConcurrencyHelpers/SwiftNIOConcurrencyHelpers.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOConcurrencyHelpers +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-dummy.m new file mode 100644 index 00000000..10b1bec1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOCore : NSObject +@end +@implementation PodsDummy_SwiftNIOCore +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-umbrella.h new file mode 100644 index 00000000..72446fd7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOCoreVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOCoreVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.debug.xcconfig new file mode 100644 index 00000000..79823201 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOLinux" -framework "NIOConcurrencyHelpers" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.modulemap new file mode 100644 index 00000000..9908c996 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.modulemap @@ -0,0 +1,6 @@ +framework module NIOCore { + umbrella header "SwiftNIOCore-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.release.xcconfig new file mode 100644 index 00000000..79823201 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOCore/SwiftNIOCore.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOLinux" -framework "NIOConcurrencyHelpers" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-dummy.m new file mode 100644 index 00000000..31ba3e5f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOEmbedded : NSObject +@end +@implementation PodsDummy_SwiftNIOEmbedded +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-umbrella.h new file mode 100644 index 00000000..eefb2f52 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOEmbeddedVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOEmbeddedVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.debug.xcconfig new file mode 100644 index 00000000..fb4e003e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOLinux" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOEmbedded +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.modulemap new file mode 100644 index 00000000..2a21b56a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.modulemap @@ -0,0 +1,6 @@ +framework module NIOEmbedded { + umbrella header "SwiftNIOEmbedded-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.release.xcconfig new file mode 100644 index 00000000..fb4e003e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOEmbedded/SwiftNIOEmbedded.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOLinux" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOEmbedded +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-Info.plist new file mode 100644 index 00000000..2fc1d2bb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.11.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-dummy.m new file mode 100644 index 00000000..c6811d7d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOExtras : NSObject +@end +@implementation PodsDummy_SwiftNIOExtras +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-umbrella.h new file mode 100644 index 00000000..ebbf1e9d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOExtrasVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOExtrasVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.debug.xcconfig new file mode 100644 index 00000000..078b9e45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOExtras +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.modulemap new file mode 100644 index 00000000..c20758dd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.modulemap @@ -0,0 +1,6 @@ +framework module NIOExtras { + umbrella header "SwiftNIOExtras-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.release.xcconfig new file mode 100644 index 00000000..078b9e45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOExtras/SwiftNIOExtras.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOExtras +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-dummy.m new file mode 100644 index 00000000..ecb4ffb1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOFoundationCompat : NSObject +@end +@implementation PodsDummy_SwiftNIOFoundationCompat +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-umbrella.h new file mode 100644 index 00000000..282629d0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOFoundationCompatVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOFoundationCompatVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.debug.xcconfig new file mode 100644 index 00000000..718b15a1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOFoundationCompat +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.modulemap new file mode 100644 index 00000000..ec29d79c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.modulemap @@ -0,0 +1,6 @@ +framework module NIOFoundationCompat { + umbrella header "SwiftNIOFoundationCompat-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.release.xcconfig new file mode 100644 index 00000000..718b15a1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOFoundationCompat/SwiftNIOFoundationCompat.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOFoundationCompat +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-Info.plist new file mode 100644 index 00000000..da1bc00d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.22.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-dummy.m new file mode 100644 index 00000000..ca1cd146 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOHPACK : NSObject +@end +@implementation PodsDummy_SwiftNIOHPACK +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-umbrella.h new file mode 100644 index 00000000..f2adb045 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOHPACKVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOHPACKVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.debug.xcconfig new file mode 100644 index 00000000..54715437 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOHTTP1" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHPACK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.modulemap new file mode 100644 index 00000000..961cc552 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.modulemap @@ -0,0 +1,6 @@ +framework module NIOHPACK { + umbrella header "SwiftNIOHPACK-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.release.xcconfig new file mode 100644 index 00000000..54715437 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHPACK/SwiftNIOHPACK.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOHTTP1" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHPACK +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-dummy.m new file mode 100644 index 00000000..eeaa5b26 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOHTTP1 : NSObject +@end +@implementation PodsDummy_SwiftNIOHTTP1 +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-umbrella.h new file mode 100644 index 00000000..93429160 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOHTTP1VersionNumber; +FOUNDATION_EXPORT const unsigned char NIOHTTP1VersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.debug.xcconfig new file mode 100644 index 00000000..0ea6b688 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1 +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHTTP1 +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.modulemap new file mode 100644 index 00000000..424957b5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.modulemap @@ -0,0 +1,6 @@ +framework module NIOHTTP1 { + umbrella header "SwiftNIOHTTP1-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.release.xcconfig new file mode 100644 index 00000000..0ea6b688 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP1/SwiftNIOHTTP1.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1 +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHTTP1 +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-Info.plist new file mode 100644 index 00000000..da1bc00d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.22.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-dummy.m new file mode 100644 index 00000000..58277517 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOHTTP2 : NSObject +@end +@implementation PodsDummy_SwiftNIOHTTP2 +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-umbrella.h new file mode 100644 index 00000000..96f4c7b6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOHTTP2VersionNumber; +FOUNDATION_EXPORT const unsigned char NIOHTTP2VersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.debug.xcconfig new file mode 100644 index 00000000..b2806bc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2 +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHTTP2 +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.modulemap new file mode 100644 index 00000000..63fcc40b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.modulemap @@ -0,0 +1,6 @@ +framework module NIOHTTP2 { + umbrella header "SwiftNIOHTTP2-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.release.xcconfig new file mode 100644 index 00000000..b2806bc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOHTTP2/SwiftNIOHTTP2.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2 +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOHTTPParser" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOHPACK" -framework "NIOHTTP1" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOHTTP2 +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-dummy.m new file mode 100644 index 00000000..06e9b3a8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOPosix : NSObject +@end +@implementation PodsDummy_SwiftNIOPosix +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-umbrella.h new file mode 100644 index 00000000..b1fdec65 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOPosixVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOPosixVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.debug.xcconfig new file mode 100644 index 00000000..5963b092 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOPosix +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.modulemap new file mode 100644 index 00000000..312c65bf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.modulemap @@ -0,0 +1,6 @@ +framework module NIOPosix { + umbrella header "SwiftNIOPosix-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.release.xcconfig new file mode 100644 index 00000000..5963b092 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOPosix/SwiftNIOPosix.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOPosix +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-Info.plist new file mode 100644 index 00000000..a3b6f508 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.19.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-dummy.m new file mode 100644 index 00000000..599c65c0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOSSL : NSObject +@end +@implementation PodsDummy_SwiftNIOSSL +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-umbrella.h new file mode 100644 index 00000000..a0ff8996 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOSSLVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOSSLVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.debug.xcconfig new file mode 100644 index 00000000..1c4573f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOSSL +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.modulemap new file mode 100644 index 00000000..8c29eb13 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.modulemap @@ -0,0 +1,6 @@ +framework module NIOSSL { + umbrella header "SwiftNIOSSL-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.release.xcconfig new file mode 100644 index 00000000..1c4573f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOSSL/SwiftNIOSSL.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIOBoringSSL" -framework "CNIOBoringSSLShims" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -Xcc -Wno-error=non-modular-include-in-framework-module +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOSSL +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-dummy.m new file mode 100644 index 00000000..85b02936 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOTLS : NSObject +@end +@implementation PodsDummy_SwiftNIOTLS +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-umbrella.h new file mode 100644 index 00000000..06bd533d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOTLSVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOTLSVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.debug.xcconfig new file mode 100644 index 00000000..cc30b5c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOTLS +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.modulemap new file mode 100644 index 00000000..1bf72281 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.modulemap @@ -0,0 +1,6 @@ +framework module NIOTLS { + umbrella header "SwiftNIOTLS-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.release.xcconfig new file mode 100644 index 00000000..cc30b5c1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTLS/SwiftNIOTLS.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOPosix" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOTLS +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-Info.plist new file mode 100644 index 00000000..fa6f4533 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.12.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-dummy.m new file mode 100644 index 00000000..4da7ad9c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftNIOTransportServices : NSObject +@end +@implementation PodsDummy_SwiftNIOTransportServices +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-umbrella.h new file mode 100644 index 00000000..1d21ba3c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double NIOTransportServicesVersionNumber; +FOUNDATION_EXPORT const unsigned char NIOTransportServicesVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.debug.xcconfig new file mode 100644 index 00000000..a2a688fb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOFoundationCompat" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOTransportServices +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.modulemap new file mode 100644 index 00000000..038e57ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.modulemap @@ -0,0 +1,6 @@ +framework module NIOTransportServices { + umbrella header "SwiftNIOTransportServices-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.release.xcconfig new file mode 100644 index 00000000..a2a688fb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftNIOTransportServices/SwiftNIOTransportServices.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CNIOAtomics" -framework "CNIODarwin" -framework "CNIOLinux" -framework "CNIOWindows" -framework "NIO" -framework "NIOConcurrencyHelpers" -framework "NIOCore" -framework "NIOEmbedded" -framework "NIOFoundationCompat" -framework "NIOPosix" -framework "NIOTLS" -framework "_NIODataStructures" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftNIOTransportServices +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-Info.plist new file mode 100644 index 00000000..158355b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.20.3 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-dummy.m new file mode 100644 index 00000000..95f025a7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftProtobuf : NSObject +@end +@implementation PodsDummy_SwiftProtobuf +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-umbrella.h new file mode 100644 index 00000000..60829180 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double SwiftProtobufVersionNumber; +FOUNDATION_EXPORT const unsigned char SwiftProtobufVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.debug.xcconfig new file mode 100644 index 00000000..fc81198f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftProtobuf +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.modulemap new file mode 100644 index 00000000..a88eceb4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.modulemap @@ -0,0 +1,6 @@ +framework module SwiftProtobuf { + umbrella header "SwiftProtobuf-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.release.xcconfig new file mode 100644 index 00000000..fc81198f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftProtobuf/SwiftProtobuf.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftProtobuf +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-Info.plist new file mode 100644 index 00000000..8d87a1ae --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 5.0.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-dummy.m new file mode 100644 index 00000000..3159becd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SwiftyJSON : NSObject +@end +@implementation PodsDummy_SwiftyJSON +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-umbrella.h new file mode 100644 index 00000000..b627dec1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double SwiftyJSONVersionNumber; +FOUNDATION_EXPORT const unsigned char SwiftyJSONVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.debug.xcconfig new file mode 100644 index 00000000..c9f18d86 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyJSON +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.modulemap new file mode 100644 index 00000000..6f41751d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.modulemap @@ -0,0 +1,6 @@ +framework module SwiftyJSON { + umbrella header "SwiftyJSON-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.release.xcconfig new file mode 100644 index 00000000..c9f18d86 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/SwiftyJSON/SwiftyJSON.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyJSON +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-Info.plist new file mode 100644 index 00000000..f133f7ed --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.40.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-dummy.m new file mode 100644 index 00000000..d9a5197d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy__NIODataStructures : NSObject +@end +@implementation PodsDummy__NIODataStructures +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-umbrella.h new file mode 100644 index 00000000..605b541b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double _NIODataStructuresVersionNumber; +FOUNDATION_EXPORT const unsigned char _NIODataStructuresVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.debug.xcconfig new file mode 100644 index 00000000..1a2868b3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/_NIODataStructures +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.modulemap new file mode 100644 index 00000000..42492651 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.modulemap @@ -0,0 +1,6 @@ +framework module _NIODataStructures { + umbrella header "_NIODataStructures-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.release.xcconfig new file mode 100644 index 00000000..1a2868b3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/_NIODataStructures/_NIODataStructures.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/_NIODataStructures +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-Info.plist new file mode 100644 index 00000000..7cfa2845 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.8.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-dummy.m new file mode 100644 index 00000000..af900752 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_gRPC_Swiftp : NSObject +@end +@implementation PodsDummy_gRPC_Swiftp +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-umbrella.h new file mode 100644 index 00000000..cb471641 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double GRPCVersionNumber; +FOUNDATION_EXPORT const unsigned char GRPCVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.debug.xcconfig new file mode 100644 index 00000000..f1f85507 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CGRPCZlib" -framework "Logging" -framework "NIO" -framework "NIOExtras" -framework "NIOHTTP2" -framework "NIOSSL" -framework "NIOTransportServices" -framework "SwiftProtobuf" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/gRPC-Swiftp +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.modulemap new file mode 100644 index 00000000..fbc2afab --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.modulemap @@ -0,0 +1,6 @@ +framework module GRPC { + umbrella header "gRPC-Swiftp-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.release.xcconfig new file mode 100644 index 00000000..f1f85507 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/gRPC-Swiftp/gRPC-Swiftp.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Swiftp +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CGRPCZlibp" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOAtomics" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSL" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOBoringSSLShims" "${PODS_CONFIGURATION_BUILD_DIR}/CNIODarwin" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOHTTPParser" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOLinux" "${PODS_CONFIGURATION_BUILD_DIR}/CNIOWindows" "${PODS_CONFIGURATION_BUILD_DIR}/Logging" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIO" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOConcurrencyHelpers" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOCore" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOEmbedded" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOExtras" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOFoundationCompat" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHPACK" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP1" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOHTTP2" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOPosix" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOSSL" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTLS" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftNIOTransportServices" "${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf" "${PODS_CONFIGURATION_BUILD_DIR}/_NIODataStructures" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "CGRPCZlib" -framework "Logging" -framework "NIO" -framework "NIOExtras" -framework "NIOHTTP2" -framework "NIOSSL" -framework "NIOTransportServices" -framework "SwiftProtobuf" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/gRPC-Swiftp +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-Info.plist new file mode 100644 index 00000000..94cd6124 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.7.4 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-dummy.m new file mode 100644 index 00000000..3bd72ec5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_secp256k1Swift : NSObject +@end +@implementation PodsDummy_secp256k1Swift +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-umbrella.h new file mode 100644 index 00000000..61225634 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double secp256k1SwiftVersionNumber; +FOUNDATION_EXPORT const unsigned char secp256k1SwiftVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.debug.xcconfig new file mode 100644 index 00000000..bf76ef07 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/secp256k1Swift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.modulemap new file mode 100644 index 00000000..bf8401e0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.modulemap @@ -0,0 +1,6 @@ +framework module secp256k1Swift { + umbrella header "secp256k1Swift-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.release.xcconfig new file mode 100644 index 00000000..bf76ef07 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Swift/secp256k1Swift.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Swift +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "secp256k1Wrapper" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/secp256k1Swift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-Info.plist b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-Info.plist new file mode 100644 index 00000000..a42f96ec --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.0.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-dummy.m b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-dummy.m new file mode 100644 index 00000000..9f08ca60 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_secp256k1Wrapper : NSObject +@end +@implementation PodsDummy_secp256k1Wrapper +@end diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-prefix.pch b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-umbrella.h b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-umbrella.h new file mode 100644 index 00000000..dbfaf7c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper-umbrella.h @@ -0,0 +1,23 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "secp256k1.h" +#import "secp256k1_ecdh.h" +#import "secp256k1_extrakeys.h" +#import "secp256k1_preallocated.h" +#import "secp256k1_recovery.h" +#import "secp256k1_schnorrsig.h" +#import "utility.h" + +FOUNDATION_EXPORT double secp256k1WrapperVersionNumber; +FOUNDATION_EXPORT const unsigned char secp256k1WrapperVersionString[]; + diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.debug.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.debug.xcconfig new file mode 100644 index 00000000..cc7e73b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/secp256k1Wrapper +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.modulemap b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.modulemap new file mode 100644 index 00000000..63b28e9d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.modulemap @@ -0,0 +1,6 @@ +framework module secp256k1Wrapper { + umbrella header "secp256k1Wrapper-umbrella.h" + + export * + module * { export * } +} diff --git a/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.release.xcconfig b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.release.xcconfig new file mode 100644 index 00000000..cc7e73b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/Target Support Files/secp256k1Wrapper/secp256k1Wrapper.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/secp256k1Wrapper +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) $(SRCROOT)/secp256k1Wrapper $(SRCROOT)/secp256k1Wrapper/src $(SRCROOT)/secp256k1Wrapper/include +OTHER_CFLAGS = $(inherited) -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-shorten-64-to-32 -Wno-conditional-uninitialized -Wno-unused-function -Wno-long-long -Wno-overlength-strings -O3 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/secp256k1Wrapper +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/LICENSE.txt b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/README.md b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/README.md new file mode 100644 index 00000000..4909d067 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/README.md @@ -0,0 +1,378 @@ +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# SwiftNIO + +SwiftNIO is a cross-platform asynchronous event-driven network application framework +for rapid development of maintainable high performance protocol servers & clients. + +It's like [Netty](https://netty.io), but written for Swift. + +### Repository organization + +The SwiftNIO project is split across multiple repositories: + +Repository | NIO 2 (Swift 5.4+) +--- | --- +[https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` +[https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` +[https://github.com/apple/swift-nio-http2][repo-nio-http2]
HTTP/2 support | `from: "1.0.0"` +[https://github.com/apple/swift-nio-extras][repo-nio-extras]
useful additions around SwiftNIO | `from: "1.0.0"` +[https://github.com/apple/swift-nio-transport-services][repo-nio-transport-services]
first-class support for macOS, iOS, tvOS, and watchOS | `from: "1.0.0"` +[https://github.com/apple/swift-nio-ssh][repo-nio-ssh]
SSH support | `.upToNextMinor(from: "0.2.0")` + +NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +Within this repository we have a number of products that provide different functionality. This package contains the following products: + +- `NIO`. This is an umbrella module exporting `NIOCore`, `NIOEmbedded` and `NIOPosix`. +- `NIOCore`. This provides the core abstractions and types for using SwiftNIO (see ["Conceptual Overview"](#conceptual-overview) for more details). Most NIO extension projects that provide things like new [`EventLoop`s][el] and [`Channel`s][c] or new protocol implementations should only need to depend on `NIOCore`. +- `NIOPosix`. This provides the primary [`EventLoopGroup`], [`EventLoop`][el], and [`Channel`s][c] for use on POSIX-based systems. This is our high performance core I/O layer. In general, this should only be imported by projects that plan to do some actual I/O, such as high-level protocol implementations or applications. +- `NIOEmbedded`. This provides [`EmbeddedChannel`][ec] and [`EmbeddedEventLoop`][eel], implementations of the `NIOCore` abstractions that provide fine-grained control over their execution. These are most often used for testing, but can also be used to drive protocol implementations in a way that is decoupled from networking altogether. +- `NIOConcurrencyHelpers`. This provides a few low-level concurrency primitives that are used by NIO implementations, such as locks and atomics. +- `NIOFoundationCompat`. This extends a number of NIO types for better interoperation with Foundation data types. If you are working with Foundation data types such as `Data`, you should import this. +- `NIOTLS`. This provides a few common abstraction types for working with multiple TLS implementations. Note that this doesn't provide TLS itself: please investigate [swift-nio-ssl][repo-nio-ssl] and [swift-nio-transport-services][repo-nio-transport-services] for concrete implementations. +- `NIOHTTP1`. This provides a low-level HTTP/1.1 protocol implementation. +- `NIOWebSocket`. This provides a low-level WebSocket protocol implementation. +- `NIOTestUtils`. This provides a number of helpers for testing projects that use SwiftNIO. + +### Protocol Implementations + +Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the [SSWG](https://swift.org/server)'s incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO. + +#### Low-level protocol implementations + +Low-level protocol implementations are often a collection of [`ChannelHandler`][ch]s that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP/1 | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOHTTP1`](https://apple.github.io/swift-nio/docs/current/NIOHTTP1/index.html) | official NIO project +HTTP/2 | ✅| ✅ | [apple/swift-nio-http2](https://github.com/apple/swift-nio-http2) | [`NIOHTTP2`](https://apple.github.io/swift-nio-http2/docs/current/NIOHTTP2/index.html) | official NIO project +WebSocket | ✅| ✅ | [apple/swift-nio](https://github.com/apple/swift-nio) | [`NIOWebSocket`](https://apple.github.io/swift-nio/docs/current/NIOWebSocket/index.html) | official NIO project +TLS | ✅ | ✅ | [apple/swift-nio-ssl](https://github.com/apple/swift-nio-ssl) | [`NIOSSL`](https://apple.github.io/swift-nio-ssl/docs/current/NIOSSL/index.html) | official NIO project +SSH | ✅ | ✅ | [apple/swift-nio-ssh][repo-nio-ssh] | _n/a_ | official NIO project + + +#### High-level implementations + +High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's [`ChannelPipeline`][cp] and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem. + +Protocol | Client | Server | Repository | Module | Comment +--- | --- | --- | --- | --- | --- +HTTP | ✅| ❌ | [swift-server/async-http-client](https://github.com/swift-server/async-http-client) | `AsyncHTTPClient` | SSWG community project +gRPC | ✅| ✅ | [grpc/grpc-swift](https://github.com/grpc/grpc-swift) | `GRPC` | also offers a low-level API; SSWG community project +APNS | ✅ | ❌ | [kylebrowning/APNSwift](https://github.com/kylebrowning/APNSwift) | `APNSwift` | SSWG community project +PostgreSQL | ✅ | ❌ | [vapor/postgres-nio](https://github.com/vapor/postgres-nio) | `PostgresNIO` | SSWG community project +Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-redi-stack) | `RediStack` | SSWG community project + +### Supported Versions + +### SwiftNIO 2 +This is the current version of SwiftNIO and will be supported for the foreseeable future. + +The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. + +### SwiftNIO 1 +SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. + +If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the [migration guide](docs/migration-guide-NIO1-to-NIO2.md) we prepared for you. + +The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0. + +### Supported Platforms + +SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions: + +* Ubuntu 18.04+ +* macOS 10.9+, iOS 7+; (macOS 10.14+, iOS 12+, tvOS 12+ or watchOS 6+ with [swift-nio-transport-services][repo-nio-transport-services]) + +### Compatibility + +SwiftNIO follows [SemVer 2.0.0](https://semver.org/#semantic-versioning-200) with a separate document declaring [SwiftNIO's Public API](docs/public-api.md). + +What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. +In SwiftPM that can be easily done specifying for example `from: "2.0.0"` meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. +SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. + + + +## Conceptual Overview + +SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers. + +To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting. + +SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support. + +The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README. + +### Basic Architecture + +The basic building blocks of SwiftNIO are the following 8 types of objects: + +- [`EventLoopGroup`][elg], a protocol, provided by `NIOCore`. +- [`EventLoop`][el], a protocol, provided by `NIOCore`. +- [`Channel`][c], a protocol, provided by `NIOCore`. +- [`ChannelHandler`][ch], a protocol, provided by `NIOCore`. +- `Bootstrap`, several related structures, provided by `NIOCore`. +- [`ByteBuffer`][bb], a struct, provided by `NIOCore`. +- [`EventLoopFuture`][elf], a generic class, provided by `NIOCore`. +- [`EventLoopPromise`][elp], a generic struct, provided by `NIOCore`. + +All SwiftNIO applications are ultimately constructed of these various components. + +#### EventLoops and EventLoopGroups + +The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events. + +Event loops are gathered together into event loop *groups*. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops. + +In SwiftNIO today there is one [`EventLoopGroup`][elg] implementation, and two [`EventLoop`][el] implementations. For production applications there is the [`MultiThreadedEventLoopGroup`][mtelg], an [`EventLoopGroup`][elg] that creates a number of threads (using the POSIX [`pthreads`][pthreads] library) and places one `SelectableEventLoop` on each one. The `SelectableEventLoop` is an event loop that uses a selector (either [`kqueue`][kqueue] or [`epoll`][epoll] depending on the target system) to manage I/O events from file descriptors and to dispatch work. These [`EventLoop`s][el] and [`EventLoopGroup`s][elg] are provided by the `NIOPosix` module. Additionally, there is the [`EmbeddedEventLoop`][eel], which is a dummy event loop that is used primarily for testing purposes, provided by the `NIOEmbedded` module. + +[`EventLoop`][el]s have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an [`EventLoop`][el]. [`EventLoop`][el] objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications. + +#### Channels, Channel Handlers, Channel Pipelines, and Channel Contexts + +While [`EventLoop`][el]s are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create [`EventLoopPromise`][elp]s and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are [`Channel`][c]s and [`ChannelHandler`][ch]s. + +Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single [`Channel`][c]. The [`Channel`][c] owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the [`Channel`][c] that owns that file descriptor. + +[`Channel`][c]s by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the [`Channel`][c] is the [`ChannelPipeline`][cp]. + +A [`ChannelPipeline`][cp] is a sequence of objects, called [`ChannelHandler`][ch]s, that process events on a [`Channel`][c]. The [`ChannelHandler`][ch]s process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name [`ChannelPipeline`][cp]. + +All [`ChannelHandler`][ch]s are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes. + +Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events. + +In general, [`ChannelHandler`][ch]s are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation. + +[`ChannelHandler`][ch]s are able to keep track of where they are in a [`ChannelPipeline`][cp] by using a [`ChannelHandlerContext`][chc]. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a [`ChannelHandler`][ch] to emit events while it remains in a pipeline. + +SwiftNIO ships with many [`ChannelHandler`][ch]s built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in [`ChannelHandler`][ch]s, as it helps avoid problems with context switching. + +Additionally, SwiftNIO ships with a few [`Channel`][c] implementations. In particular, it ships with `ServerSocketChannel`, a [`Channel`][c] for sockets that accept inbound connections; `SocketChannel`, a [`Channel`][c] for TCP connections; and `DatagramChannel`, a [`Channel`][c] for UDP sockets. All of these are provided by the `NIOPosix` module. It also provides[`EmbeddedChannel`][ec], a [`Channel`][c] primarily used for testing, provided by the `NIOEmbedded` module. + +##### A Note on Blocking + +One of the important notes about [`ChannelPipeline`][cp]s is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler [`ChannelHandler`][ch]s in the knowledge that they will not require synchronization. + +However, this is achieved by dispatching all code on the [`ChannelPipeline`][cp] on the same thread as the [`EventLoop`][el]. This means that, as a general rule, [`ChannelHandler`][ch]s **must not** call blocking code without dispatching it to a background thread. If a [`ChannelHandler`][ch] blocks for any reason, all [`Channel`][c]s attached to the parent [`EventLoop`][el] will be unable to progress until the blocking call completes. + +This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline. + +#### Bootstrap + +While it is possible to configure and register [`Channel`][c]s with [`EventLoop`][el]s directly, it is generally more useful to have a higher-level abstraction to handle this work. + +For this reason, SwiftNIO ships a number of `Bootstrap` objects whose purpose is to streamline the creation of channels. Some `Bootstrap` objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts. + +Currently SwiftNIO ships with three `Bootstrap` objects in the `NIOPosix` module: [`ServerBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ServerBootstrap.html), for bootstrapping listening channels; [`ClientBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/ClientBootstrap.html), for bootstrapping client TCP channels; and [`DatagramBootstrap`](https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/DatagramBootstrap.html) for bootstrapping UDP channels. + +#### ByteBuffer + +The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform. + +For this reason, SwiftNIO provides [`ByteBuffer`][bb], a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications. This type is provided by the `NIOCore` module. + +[`ByteBuffer`][bb] provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems. + +In general, it is highly recommended that you use the [`ByteBuffer`][bb] in its safe mode at all times. + +For more details on the API of [`ByteBuffer`][bb], please see our API documentation, linked below. + +#### Promises and Futures + +One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides [`EventLoopPromise`][elp] and [`EventLoopFuture`][elf] to manage operations that complete *asynchronously*. These types are provided by the `NIOCore` module. + +An [`EventLoopFuture`][elf] is essentially a container for the return value of a function that will be populated *at some time in the future*. Each [`EventLoopFuture`][elf] has a corresponding [`EventLoopPromise`][elp], which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled. + +If you had to poll the future to detect when it completed that would be quite inefficient, so [`EventLoopFuture`][elf] is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The [`EventLoopFuture`][elf] will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around [`EventLoopFuture`][elf] callbacks. + +Another important topic for consideration is the difference between how the promise passed to `close` works as opposed to `closeFuture` on a [`Channel`][c]. For example, the promise passed into `close` will succeed after the [`Channel`][c] is closed down but before the [`ChannelPipeline`][cp] is completely cleared out. This will allow you to take action on the [`ChannelPipeline`][cp] before it is completely cleared out, if needed. If it is desired to wait for the [`Channel`][c] to close down and the [`ChannelPipeline`][cp] to be cleared out without any further action, then the better option would be to wait for the `closeFuture` to succeed. + +There are several functions for applying callbacks to [`EventLoopFuture`][elf], depending on how and when you want them to execute. Details of these functions is left to the API documentation. + +### Design Philosophy + +SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly. + +Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly. + +The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree! + +## Documentation + + - [API documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html) + +## Example Usage + +There are currently several example projects that demonstrate how to use SwiftNIO. + +- **chat client** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatClient +- **chat server** https://github.com/apple/swift-nio/tree/main/Sources/NIOChatServer +- **echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoClient +- **echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOEchoServer +- **UDP echo client** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoClient +- **UDP echo server** https://github.com/apple/swift-nio/tree/main/Sources/NIOUDPEchoServer +- **HTTP client** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Client +- **HTTP server** https://github.com/apple/swift-nio/tree/main/Sources/NIOHTTP1Server +- **WebSocket client** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketClient +- **WebSocket server** https://github.com/apple/swift-nio/tree/main/Sources/NIOWebSocketServer + +To build & run them, run following command, replace TARGET_NAME with the folder name under `./Sources` + +```bash +swift run TARGET_NAME +``` + +For example, to run NIOHTTP1Server, run following command: + +```bash +swift run NIOHTTP1Server +``` + +## Getting Started + +SwiftNIO primarily uses [SwiftPM](https://swift.org/package-manager/) as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a `dependencies` clause to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") +] +``` + +and then adding the appropriate SwiftNIO module(s) to your target dependencies. +The syntax for adding target dependencies differs slightly between Swift +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +`NIOHTTP1` modules, specify the following dependencies: + +#### Swift 5.4 and newer (`swift-tools-version:5.4`) + + dependencies: [.product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "NIOHTTP1", package: "swift-nio")] + +### Using Xcode Package support + +If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your +Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter +`https://github.com/apple/swift-nio.git` and click Next twice. Finally, select the targets you are planning to use (for +example `NIOCore`, `NIOHTTP1`, and `NIOFoundationCompat`) and click finish. Now will be able to `import NIOCore` (as well as all +the other targets you have selected) in your project. + +To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server: + +```bash +swift build +swift test +swift run NIOEchoServer +``` + +To verify that it is working, you can use another shell to attempt to connect to it: + +```bash +echo "Hello SwiftNIO" | nc localhost 9999 +``` + +If all goes well, you'll see the message echoed back to you. + +To work on SwiftNIO in Xcode 11+, you can just open the `Package.swift` +file in Xcode and use Xcode's support for SwiftPM Packages. + +If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project: + +```bash +swift package generate-xcodeproj +``` + +### An alternative: using `docker-compose` + +Alternatively, you may want to develop or test with `docker-compose`. + +First make sure you have [Docker](https://www.docker.com/community-edition) installed, next run the following commands: + +- `docker-compose -f docker/docker-compose.yaml run test` + + Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests + +- `docker-compose -f docker/docker-compose.yaml up echo` + + Will create a base image, compile SwiftNIO, and run a sample `NIOEchoServer` on + `localhost:9999`. Test it by `echo Hello SwiftNIO | nc localhost 9999`. + +- `docker-compose -f docker/docker-compose.yaml up http` + + Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on + `localhost:8888`. Test it by `curl http://localhost:8888` + +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` + + Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + + +## Developing SwiftNIO + +*Note*: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package. + +For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see `CONTRIBUTING.md` in this repository. + +### Prerequisites + +SwiftNIO's `main` branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only. + +To be able to compile and run SwiftNIO and the integration tests, you need to +have a few prerequisites installed on your system. + +#### macOS + +- Xcode 11.4 or newer, Xcode 12 recommended. + +### Linux + +- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- netcat (for integration tests only) +- lsof (for integration tests only) +- shasum (for integration tests only) + +#### Ubuntu 18.04 + +``` +# install swift tarball from https://swift.org/downloads +apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl +``` + + +### Fedora 28+ + +``` +dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum +``` + +[ch]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/ChannelHandler.html +[c]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/Channel.html +[chc]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelHandlerContext.html +[ec]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedChannel.html +[el]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoop.html +[eel]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EmbeddedEventLoop.html +[elg]: https://apple.github.io/swift-nio/docs/current/NIOCore/Protocols/EventLoopGroup.html +[bb]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/ByteBuffer.html +[elf]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/EventLoopFuture.html +[elp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Structs/EventLoopPromise.html +[cp]: https://apple.github.io/swift-nio/docs/current/NIOCore/Classes/ChannelPipeline.html +[mtelg]: https://apple.github.io/swift-nio/docs/current/NIOPosix/Classes/MultiThreadedEventLoopGroup.html +[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads +[kqueue]: https://en.wikipedia.org/wiki/Kqueue +[epoll]: https://en.wikipedia.org/wiki/Epoll +[repo-nio]: https://github.com/apple/swift-nio +[repo-nio-extras]: https://github.com/apple/swift-nio-extras +[repo-nio-http2]: https://github.com/apple/swift-nio-http2 +[repo-nio-ssl]: https://github.com/apple/swift-nio-ssl +[repo-nio-transport-services]: https://github.com/apple/swift-nio-transport-services +[repo-nio-ssh]: https://github.com/apple/swift-nio-ssh + +### Speeding up testing +It's possible to run the test suite in parallel, it can save significant time if you have a larger multi-core machine, just add `--parallel` when running the tests. This can speed up the run time of the test suite by 30x or more. + +``` +swift test --parallel +``` diff --git a/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/Heap.swift b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/Heap.swift new file mode 100644 index 00000000..05fd41b7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/Heap.swift @@ -0,0 +1,263 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin.C +#elseif os(Linux) || os(FreeBSD) || os(Android) +import Glibc +#endif + +@usableFromInline +internal struct Heap { + @usableFromInline + internal private(set) var storage: Array + + @inlinable + internal init() { + self.storage = [] + } + + @inlinable + internal func comparator(_ lhs: Element, _ rhs: Element) -> Bool { + // This heap is always a min-heap. + return lhs < rhs + } + + // named `PARENT` in CLRS + @inlinable + internal func parentIndex(_ i: Int) -> Int { + return (i-1) / 2 + } + + // named `LEFT` in CLRS + @inlinable + internal func leftIndex(_ i: Int) -> Int { + return 2*i + 1 + } + + // named `RIGHT` in CLRS + @inlinable + internal func rightIndex(_ i: Int) -> Int { + return 2*i + 2 + } + + // named `MAX-HEAPIFY` in CLRS + /* private but */ @inlinable + mutating func _heapify(_ index: Int) { + let left = self.leftIndex(index) + let right = self.rightIndex(index) + + var root: Int + if left <= (self.storage.count - 1) && self.comparator(storage[left], storage[index]) { + root = left + } else { + root = index + } + + if right <= (self.storage.count - 1) && self.comparator(storage[right], storage[root]) { + root = right + } + + if root != index { + self.storage.swapAt(index, root) + self._heapify(root) + } + } + + // named `HEAP-INCREASE-KEY` in CRLS + /* private but */ @inlinable + mutating func _heapRootify(index: Int, key: Element) { + var index = index + if self.comparator(storage[index], key) { + fatalError("New key must be closer to the root than current key") + } + + self.storage[index] = key + while index > 0 && self.comparator(self.storage[index], self.storage[self.parentIndex(index)]) { + self.storage.swapAt(index, self.parentIndex(index)) + index = self.parentIndex(index) + } + } + + @inlinable + internal mutating func append(_ value: Element) { + var i = self.storage.count + self.storage.append(value) + while i > 0 && self.comparator(self.storage[i], self.storage[self.parentIndex(i)]) { + self.storage.swapAt(i, self.parentIndex(i)) + i = self.parentIndex(i) + } + } + + @discardableResult + @inlinable + internal mutating func removeRoot() -> Element? { + return self._remove(index: 0) + } + + @discardableResult + @inlinable + internal mutating func remove(value: Element) -> Bool { + if let idx = self.storage.firstIndex(of: value) { + self._remove(index: idx) + return true + } else { + return false + } + } + + @inlinable + internal mutating func removeFirst(where shouldBeRemoved: (Element) throws -> Bool) rethrows { + guard self.storage.count > 0 else { + return + } + + guard let index = try self.storage.firstIndex(where: shouldBeRemoved) else { + return + } + + self._remove(index: index) + } + + @discardableResult + /* private but */ @inlinable + mutating func _remove(index: Int) -> Element? { + guard self.storage.count > 0 else { + return nil + } + let element = self.storage[index] + if self.storage.count == 1 || self.storage[index] == self.storage[self.storage.count - 1] { + self.storage.removeLast() + } else if !self.comparator(self.storage[index], self.storage[self.storage.count - 1]) { + self._heapRootify(index: index, key: self.storage[self.storage.count - 1]) + self.storage.removeLast() + } else { + self.storage[index] = self.storage[self.storage.count - 1] + self.storage.removeLast() + self._heapify(index) + } + return element + } +} + +extension Heap: CustomDebugStringConvertible { + @inlinable + var debugDescription: String { + guard self.storage.count > 0 else { + return "" + } + let descriptions = self.storage.map { String(describing: $0) } + let maxLen: Int = descriptions.map { $0.count }.max()! // storage checked non-empty above + let paddedDescs = descriptions.map { (desc: String) -> String in + var desc = desc + while desc.count < maxLen { + if desc.count % 2 == 0 { + desc = " \(desc)" + } else { + desc = "\(desc) " + } + } + return desc + } + + var all = "\n" + let spacing = String(repeating: " ", count: maxLen) + func subtreeWidths(rootIndex: Int) -> (Int, Int) { + let lcIdx = self.leftIndex(rootIndex) + let rcIdx = self.rightIndex(rootIndex) + var leftSpace = 0 + var rightSpace = 0 + if lcIdx < self.storage.count { + let sws = subtreeWidths(rootIndex: lcIdx) + leftSpace += sws.0 + sws.1 + maxLen + } + if rcIdx < self.storage.count { + let sws = subtreeWidths(rootIndex: rcIdx) + rightSpace += sws.0 + sws.1 + maxLen + } + return (leftSpace, rightSpace) + } + for (index, desc) in paddedDescs.enumerated() { + let (leftWidth, rightWidth) = subtreeWidths(rootIndex: index) + all += String(repeating: " ", count: leftWidth) + all += desc + all += String(repeating: " ", count: rightWidth) + + func height(index: Int) -> Int { + return Int(log2(Double(index + 1))) + } + let myHeight = height(index: index) + let nextHeight = height(index: index + 1) + if myHeight != nextHeight { + all += "\n" + } else { + all += spacing + } + } + all += "\n" + return all + } +} + +@usableFromInline +struct HeapIterator: IteratorProtocol { + /* private but */ @usableFromInline + var _heap: Heap + + @inlinable + init(heap: Heap) { + self._heap = heap + } + + @inlinable + mutating func next() -> Element? { + return self._heap.removeRoot() + } +} + +extension Heap: Sequence { + @inlinable + var startIndex: Int { + return self.storage.startIndex + } + + @inlinable + var endIndex: Int { + return self.storage.endIndex + } + + @inlinable + var underestimatedCount: Int { + return self.storage.count + } + + @inlinable + func makeIterator() -> HeapIterator { + return HeapIterator(heap: self) + } + + @inlinable + subscript(position: Int) -> Element { + return self.storage[position] + } + + @inlinable + func index(after i: Int) -> Int { + return i + 1 + } + + @inlinable + var count: Int { + return self.storage.count + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/PriorityQueue.swift b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/PriorityQueue.swift new file mode 100644 index 00000000..0f1a0587 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/_NIODataStructures/Sources/_NIODataStructures/PriorityQueue.swift @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public struct PriorityQueue { + @usableFromInline + internal var _heap: Heap + + @inlinable + public init() { + self._heap = Heap() + } + + @inlinable + public mutating func remove(_ key: Element) { + self._heap.remove(value: key) + } + + @inlinable + public mutating func removeFirst(where shouldBeRemoved: (Element) throws -> Bool) rethrows { + try self._heap.removeFirst(where: shouldBeRemoved) + } + + @inlinable + public mutating func push(_ key: Element) { + self._heap.append(key) + } + + @inlinable + public func peek() -> Element? { + return self._heap.storage.first + } + + @inlinable + public var isEmpty: Bool { + return self._heap.storage.isEmpty + } + + @inlinable + @discardableResult + public mutating func pop() -> Element? { + return self._heap.removeRoot() + } + + @inlinable + public mutating func clear() { + self._heap = Heap() + } +} + +extension PriorityQueue: Equatable { + @inlinable + public static func ==(lhs: PriorityQueue, rhs: PriorityQueue) -> Bool { + return lhs.count == rhs.count && lhs.elementsEqual(rhs) + } +} + +extension PriorityQueue: Sequence { + public struct Iterator: IteratorProtocol { + + /* private but */ @usableFromInline + var _queue: PriorityQueue + + /* fileprivate but */ @inlinable + public init(queue: PriorityQueue) { + self._queue = queue + } + + @inlinable + public mutating func next() -> Element? { + return self._queue.pop() + } + } + + @inlinable + public func makeIterator() -> Iterator { + return Iterator(queue: self) + } +} + +extension PriorityQueue { + @inlinable + public var count: Int { + return self._heap.count + } +} + +extension PriorityQueue: CustomStringConvertible { + @inlinable + public var description: String { + return "PriorityQueue(count: \(self.count)): \(Array(self))" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/LICENSE b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/README.md b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/README.md new file mode 100644 index 00000000..04083746 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/README.md @@ -0,0 +1,166 @@ +[![CI](https://img.shields.io/github/workflow/status/grpc/grpc-swift/CI?event=push)](https://github.com/grpc/grpc-swift/actions/workflows/ci.yaml) +[![Latest Version](https://img.shields.io/github/v/release/grpc/grpc-swift?include_prereleases&sort=semver)](https://img.shields.io/github/v/release/grpc/grpc-swift?include_prereleases&sort=semver) +[![sswg:graduated|104x20](https://img.shields.io/badge/sswg-graduated-green.svg)](https://github.com/swift-server/sswg/blob/main/process/incubation.md#graduated-level) + +# gRPC Swift + +This repository contains a gRPC Swift API and code generator. + +It is intended for use with Apple's [SwiftProtobuf][swift-protobuf] support for +Protocol Buffers. Both projects contain code generation plugins for `protoc`, +Google's Protocol Buffer compiler, and both contain libraries of supporting code +that is needed to build and run the generated code. + +APIs and generated code is provided for both gRPC clients and servers, and can +be built either with Xcode or the Swift Package Manager. Support is provided for +all four gRPC API styles (Unary, Server Streaming, Client Streaming, and +Bidirectional Streaming) and connections can be made either over secure (TLS) or +insecure channels. + +## Versions + +gRPC Swift has recently been rewritten on top of [SwiftNIO][swift-nio] as +opposed to the core library provided by the [gRPC project][grpc]. + +Version | Implementation | Branch | `protoc` Plugin | Support +--------|----------------|------------------------|-------------------------|----------------------------------------- +1.x | SwiftNIO | [`main`][branch-new] | `protoc-gen-grpc-swift` | Actively developed and supported +0.x | gRPC C library | [`cgrpc`][branch-old] | `protoc-gen-swiftgrpc` | No longer developed; security fixes only + +The remainder of this README refers to the 1.x version of gRPC Swift. + + +## Supported Platforms + +gRPC Swift's platform support is identical to the [platform support of Swift +NIO][swift-nio-platforms]. + +The earliest supported Swift version for gRPC Swift 1.8.x and newer is 5.4. +For 1.7.x and earlier the oldest supported Swift version is 5.2. + +Versions of clients and services which are use Swift's Concurrency support +are available from gRPC Swift 1.8.0 and require Swift 5.6 and newer. + +## Getting gRPC Swift + +There are two parts to gRPC Swift: the gRPC library and an API code generator. + +### Getting the gRPC library + +#### Swift Package Manager + +The Swift Package Manager is the preferred way to get gRPC Swift. Simply add the +package dependency to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0") +] +``` + +...and depend on `"GRPC"` in the necessary targets: + +```swift +.target( + name: ..., + dependencies: [.product(name: "GRPC", package: "grpc-swift")] +] +``` + +##### Xcode + +From Xcode 11 it is possible to [add Swift Package dependencies to Xcode +projects][xcode-spm] and link targets to products of those packages; this is the +easiest way to integrate gRPC Swift with an existing `xcodeproj`. + +##### Manual Integration + +Alternatively, gRPC Swift can be manually integrated into a project: + +1. Build an Xcode project: `swift package generate-xcodeproj`, +1. Add the generated project to your own project, and +1. Add a build dependency on `GRPC`. + +### Getting the `protoc` Plugins + +Binary releases of `protoc`, the Protocol Buffer Compiler, are available on +[GitHub][protobuf-releases]. + +To build the plugins, run `make plugins` in the main directory. This uses the +Swift Package Manager to build both of the necessary plugins: +`protoc-gen-swift`, which generates Protocol Buffer support code and +`protoc-gen-grpc-swift`, which generates gRPC interface code. + +To install these plugins, just copy the two executables (`protoc-gen-swift` and +`protoc-gen-grpc-swift`) that show up in the main directory into a directory +that is part of your `PATH` environment variable. Alternatively the full path to +the plugins can be specified when using `protoc`. + +#### Homebrew + +The plugins are available from [homebrew](https://brew.sh) and can be installed with: +```bash + $ brew install swift-protobuf grpc-swift +``` + +## Examples + +gRPC Swift has a number of tutorials and examples available. They are split +across two directories: + +- [`/Sources/Examples`][examples-in-source] contains examples which do not + require additional dependencies and may be built using the Swift Package + Manager. +- [`/Examples`][examples-out-of-source] contains examples which rely on + external dependencies or may not be built by the Swift Package Manager (such + as an iOS app). + +Some of the examples are accompanied by tutorials, including: +- A [quick start guide][docs-quickstart] for creating and running your first + gRPC service. +- A [basic tutorial][docs-tutorial] covering the creation and implementation of + a gRPC service using all four call types as well as the code required to setup + and run a server and make calls to it using a generated client. +- An [interceptors][docs-interceptors-tutorial] tutorial covering how to create + and use interceptors with gRPC Swift. + +## Documentation + +The `docs` directory contains documentation, including: + +- Options for the `protoc` plugin in [`docs/plugin.md`][docs-plugin] +- How to configure TLS in [`docs/tls.md`][docs-tls] +- How to configure keepalive in [`docs/keepalive.md`][docs-keepalive] +- Support for Apple Platforms and NIO Transport Services in + [`docs/apple-platforms.md`][docs-apple] + +## Security + +Please see [SECURITY.md](SECURITY.md). + +## License + +gRPC Swift is released under the same license as [gRPC][grpc], repeated in +[LICENSE](LICENSE). + +## Contributing + +Please get involved! See our [guidelines for contributing](CONTRIBUTING.md). + +[docs-apple]: ./docs/apple-platforms.md +[docs-plugin]: ./docs/plugin.md +[docs-quickstart]: ./docs/quick-start.md +[docs-tls]: ./docs/tls.md +[docs-keepalive]: ./docs/keepalive.md +[docs-tutorial]: ./docs/basic-tutorial.md +[docs-interceptors-tutorial]: ./docs/interceptors-tutorial.md +[grpc]: https://github.com/grpc/grpc +[protobuf-releases]: https://github.com/protocolbuffers/protobuf/releases +[swift-nio-platforms]: https://github.com/apple/swift-nio#supported-platforms +[swift-nio]: https://github.com/apple/swift-nio +[swift-protobuf]: https://github.com/apple/swift-protobuf +[xcode-spm]: https://help.apple.com/xcode/mac/current/#/devb83d64851 +[branch-new]: https://github.com/grpc/grpc-swift/tree/main +[branch-old]: https://github.com/grpc/grpc-swift/tree/cgrpc +[examples-out-of-source]: https://github.com/grpc/grpc-swift/tree/main/Examples +[examples-in-source]: https://github.com/grpc/grpc-swift/tree/main/Sources/Examples diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Array+BoundsCheck.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Array+BoundsCheck.swift new file mode 100644 index 00000000..19c0fd44 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Array+BoundsCheck.swift @@ -0,0 +1,25 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extension Array { + internal subscript(checked index: Index) -> Element? { + if self.indices.contains(index) { + return self[index] + } else { + return nil + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Actions.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Actions.swift new file mode 100644 index 00000000..8c75f0e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Actions.swift @@ -0,0 +1,97 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + @usableFromInline + enum HandleMetadataAction: Hashable { + /// Invoke the user handler. + case invokeHandler + /// Cancel the RPC, the metadata was not expected. + case cancel + } + + @usableFromInline + enum HandleMessageAction: Hashable { + /// Forward the message to the interceptors, via the interceptor state machine. + case forward + /// Cancel the RPC, the message was not expected. + case cancel + } + + /// The same as 'HandleMessageAction. + @usableFromInline + typealias HandleEndAction = HandleMessageAction + + @usableFromInline + enum SendMessageAction: Equatable { + /// Intercept the message, but first intercept the headers if they are non-nil. Must go via + /// the interceptor state machine first. + case intercept(headers: HPACKHeaders?) + /// Drop the message. + case drop + } + + @usableFromInline + enum SendStatusAction: Equatable { + /// Intercept the status, providing the given trailers. + case intercept(requestHeaders: HPACKHeaders, trailers: HPACKHeaders) + /// Drop the status. + case drop + } + + @usableFromInline + enum CancelAction: Hashable { + /// Cancel and nil out the handler 'bits'. + case cancelAndNilOutHandlerComponents + /// Don't do anything. + case none + } + + /// Tracks whether response metadata has been written. + @usableFromInline + internal enum ResponseMetadata { + case notWritten(HPACKHeaders) + case written + + /// Update the metadata. It must not have been written yet. + @inlinable + mutating func update(_ metadata: HPACKHeaders) { + switch self { + case .notWritten: + self = .notWritten(metadata) + case .written: + assertionFailure("Metadata must not be set after it has been sent") + } + } + + /// Returns the metadata if it has not been written and moves the state to + /// `written`. Returns `nil` if it has already been written. + @inlinable + mutating func getIfNotWritten() -> HPACKHeaders? { + switch self { + case let .notWritten(metadata): + self = .written + return metadata + case .written: + return nil + } + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Draining.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Draining.swift new file mode 100644 index 00000000..857beda7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Draining.swift @@ -0,0 +1,110 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + /// In the 'Draining' state the user handler has been invoked and the request stream has been + /// closed (i.e. we have seen 'end' but it has not necessarily been consumed by the user handler). + /// We can transition to a new state either by sending the end of the response stream or by + /// cancelling. + @usableFromInline + internal struct Draining { + @usableFromInline + typealias NextStateAndOutput = + ServerHandlerStateMachine.NextStateAndOutput< + ServerHandlerStateMachine.Draining.NextState, + Output + > + + /// The response headers. + @usableFromInline + internal private(set) var responseHeaders: ResponseMetadata + /// The response trailers. + @usableFromInline + internal private(set) var responseTrailers: ResponseMetadata + /// The request headers. + @usableFromInline + internal let requestHeaders: HPACKHeaders + + @inlinable + init(from state: ServerHandlerStateMachine.Handling) { + self.responseHeaders = state.responseHeaders + self.responseTrailers = state.responseTrailers + self.requestHeaders = state.requestHeaders + } + + @inlinable + mutating func setResponseHeaders( + _ metadata: HPACKHeaders + ) -> Self.NextStateAndOutput { + self.responseHeaders.update(metadata) + return .init(nextState: .draining(self)) + } + + @inlinable + mutating func setResponseTrailers( + _ metadata: HPACKHeaders + ) -> Self.NextStateAndOutput { + self.responseTrailers.update(metadata) + return .init(nextState: .draining(self)) + } + + @inlinable + mutating func handleMetadata() -> Self.NextStateAndOutput { + // We're already draining, i.e. the inbound stream is closed, cancel the RPC. + return .init(nextState: .draining(self), output: .cancel) + } + + @inlinable + mutating func handleMessage() -> Self.NextStateAndOutput { + // We're already draining, i.e. the inbound stream is closed, cancel the RPC. + return .init(nextState: .draining(self), output: .cancel) + } + + @inlinable + mutating func handleEnd() -> Self.NextStateAndOutput { + // We're already draining, i.e. the inbound stream is closed, cancel the RPC. + return .init(nextState: .draining(self), output: .cancel) + } + + @inlinable + mutating func sendMessage() -> Self.NextStateAndOutput { + let headers = self.responseHeaders.getIfNotWritten() + return .init(nextState: .draining(self), output: .intercept(headers: headers)) + } + + @inlinable + mutating func sendStatus() -> Self.NextStateAndOutput { + return .init( + nextState: .finished(from: self), + output: .intercept( + requestHeaders: self.requestHeaders, + // If trailers had been written we'd already be in the finished state so + // the force unwrap is okay here. + trailers: self.responseTrailers.getIfNotWritten()! + ) + ) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + return .init(nextState: .finished(from: self), output: .cancelAndNilOutHandlerComponents) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Finished.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Finished.swift new file mode 100644 index 00000000..c9637a1f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Finished.swift @@ -0,0 +1,81 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + @usableFromInline + internal struct Finished { + @usableFromInline + typealias NextStateAndOutput = ServerHandlerStateMachine.NextStateAndOutput< + ServerHandlerStateMachine.Finished.NextState, + Output + > + + @inlinable + internal init(from state: ServerHandlerStateMachine.Idle) {} + @inlinable + internal init(from state: ServerHandlerStateMachine.Handling) {} + @inlinable + internal init(from state: ServerHandlerStateMachine.Draining) {} + + @inlinable + mutating func setResponseHeaders( + _ headers: HPACKHeaders + ) -> Self.NextStateAndOutput { + return .init(nextState: .finished(self)) + } + + @inlinable + mutating func setResponseTrailers( + _ metadata: HPACKHeaders + ) -> Self.NextStateAndOutput { + return .init(nextState: .finished(self)) + } + + @inlinable + mutating func handleMetadata() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .cancel) + } + + @inlinable + mutating func handleMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .cancel) + } + + @inlinable + mutating func handleEnd() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .cancel) + } + + @inlinable + mutating func sendMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func sendStatus() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .cancelAndNilOutHandlerComponents) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Handling.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Handling.swift new file mode 100644 index 00000000..a05787d8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Handling.swift @@ -0,0 +1,113 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + /// In the 'Handling' state the user handler has been invoked and the request stream is open (but + /// the request metadata has already been seen). We can transition to a new state either by + /// receiving the end of the request stream or by closing the response stream. Cancelling also + /// moves us to the finished state. + @usableFromInline + internal struct Handling { + @usableFromInline + typealias NextStateAndOutput = ServerHandlerStateMachine.NextStateAndOutput< + ServerHandlerStateMachine.Handling.NextState, + Output + > + + /// The response headers. + @usableFromInline + internal private(set) var responseHeaders: ResponseMetadata + /// The response trailers. + @usableFromInline + internal private(set) var responseTrailers: ResponseMetadata + /// The request headers. + @usableFromInline + internal let requestHeaders: HPACKHeaders + + /// Transition from the 'Idle' state. + @inlinable + init(from state: ServerHandlerStateMachine.Idle, requestHeaders: HPACKHeaders) { + self.responseHeaders = .notWritten([:]) + self.responseTrailers = .notWritten([:]) + self.requestHeaders = requestHeaders + } + + @inlinable + mutating func setResponseHeaders( + _ metadata: HPACKHeaders + ) -> Self.NextStateAndOutput { + self.responseHeaders.update(metadata) + return .init(nextState: .handling(self)) + } + + @inlinable + mutating func setResponseTrailers( + _ metadata: HPACKHeaders + ) -> Self.NextStateAndOutput { + self.responseTrailers.update(metadata) + return .init(nextState: .handling(self)) + } + + @inlinable + mutating func handleMetadata() -> Self.NextStateAndOutput { + // We are in the 'Handling' state because we received metadata. If we receive it again we + // should cancel the RPC. + return .init(nextState: .handling(self), output: .cancel) + } + + @inlinable + mutating func handleMessage() -> Self.NextStateAndOutput { + // We can always forward a message since receiving the end of the request stream causes a + // transition to the 'draining' state. + return .init(nextState: .handling(self), output: .forward) + } + + @inlinable + mutating func handleEnd() -> Self.NextStateAndOutput { + // The request stream is finished: move to the draining state so the user handler can finish + // executing. + return .init(nextState: .draining(from: self), output: .forward) + } + + @inlinable + mutating func sendMessage() -> Self.NextStateAndOutput { + let headers = self.responseHeaders.getIfNotWritten() + return .init(nextState: .handling(self), output: .intercept(headers: headers)) + } + + @inlinable + mutating func sendStatus() -> Self.NextStateAndOutput { + return .init( + nextState: .finished(from: self), + output: .intercept( + requestHeaders: self.requestHeaders, + // If trailers had been written we'd already be in the finished state so + // the force unwrap is okay here. + trailers: self.responseTrailers.getIfNotWritten()! + ) + ) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + return .init(nextState: .finished(from: self), output: .cancelAndNilOutHandlerComponents) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Idle.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Idle.swift new file mode 100644 index 00000000..fa51bcd4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine+Idle.swift @@ -0,0 +1,81 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + /// In the 'Idle' state nothing has happened. To advance we must either receive metadata (i.e. + /// the request headers) and invoke the handler, or we are cancelled. + @usableFromInline + internal struct Idle { + @usableFromInline + typealias NextStateAndOutput = ServerHandlerStateMachine.NextStateAndOutput< + ServerHandlerStateMachine.Idle.NextState, + Output + > + + /// The state of the inbound stream, i.e. the request stream. + @usableFromInline + internal private(set) var inboundState: ServerInterceptorStateMachine.InboundStreamState + + @inlinable + init() { + self.inboundState = .idle + } + + @inlinable + mutating func handleMetadata() -> Self.NextStateAndOutput { + let action: HandleMetadataAction + + switch self.inboundState.receiveMetadata() { + case .accept: + // We tell the caller to invoke the handler immediately: they should then call + // 'handlerInvoked' on the state machine which will cause a transition to the next state. + action = .invokeHandler + case .reject: + action = .cancel + } + + return .init(nextState: .idle(self), output: action) + } + + @inlinable + mutating func handleMessage() -> Self.NextStateAndOutput { + // We can't receive a message before the metadata, doing so is a protocol violation. + return .init(nextState: .idle(self), output: .cancel) + } + + @inlinable + mutating func handleEnd() -> Self.NextStateAndOutput { + // Receiving 'end' before we start is odd but okay, just cancel. + return .init(nextState: .idle(self), output: .cancel) + } + + @inlinable + mutating func handlerInvoked(requestHeaders: HPACKHeaders) -> Self.NextStateAndOutput { + // The handler was invoked as a result of receiving metadata. Move to the next state. + return .init(nextState: .handling(from: self, requestHeaders: requestHeaders)) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + // There's no handler to cancel. Move straight to finished. + return .init(nextState: .finished(from: self), output: .none) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine.swift new file mode 100644 index 00000000..f0ab4fa7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerHandlerStateMachine/ServerHandlerStateMachine.swift @@ -0,0 +1,362 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal struct ServerHandlerStateMachine { + @usableFromInline + internal private(set) var state: Self.State + + @inlinable + init() { + self.state = .idle(.init()) + } + + @inlinable + mutating func setResponseHeaders(_ headers: HPACKHeaders) { + switch self.state { + case var .handling(handling): + let nextStateAndOutput = handling.setResponseHeaders(headers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.setResponseHeaders(headers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.setResponseHeaders(headers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case .idle: + preconditionFailure() + } + } + + @inlinable + mutating func setResponseTrailers(_ trailers: HPACKHeaders) { + switch self.state { + case var .handling(handling): + let nextStateAndOutput = handling.setResponseTrailers(trailers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.setResponseTrailers(trailers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.setResponseTrailers(trailers) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case .idle: + preconditionFailure() + } + } + + @inlinable + mutating func handleMetadata() -> HandleMetadataAction { + switch self.state { + case var .idle(idle): + let nextStateAndOutput = idle.handleMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .handling(handling): + let nextStateAndOutput = handling.handleMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.handleMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.handleMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func handleMessage() -> HandleMessageAction { + switch self.state { + case var .idle(idle): + let nextStateAndOutput = idle.handleMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .handling(handling): + let nextStateAndOutput = handling.handleMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.handleMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.handleMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func handleEnd() -> HandleEndAction { + switch self.state { + case var .idle(idle): + let nextStateAndOutput = idle.handleEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .handling(handling): + let nextStateAndOutput = handling.handleEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.handleEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.handleEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func sendMessage() -> SendMessageAction { + switch self.state { + case var .handling(handling): + let nextStateAndOutput = handling.sendMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.sendMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.sendMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case .idle: + preconditionFailure() + } + } + + @inlinable + mutating func sendStatus() -> SendStatusAction { + switch self.state { + case var .handling(handling): + let nextStateAndOutput = handling.sendStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.sendStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.sendStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case .idle: + preconditionFailure() + } + } + + @inlinable + mutating func cancel() -> CancelAction { + switch self.state { + case var .idle(idle): + let nextStateAndOutput = idle.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .handling(handling): + let nextStateAndOutput = handling.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .draining(draining): + let nextStateAndOutput = draining.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func handlerInvoked(requestHeaders: HPACKHeaders) { + switch self.state { + case var .idle(idle): + let nextStateAndOutput = idle.handlerInvoked(requestHeaders: requestHeaders) + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case .handling: + preconditionFailure() + case .draining: + preconditionFailure() + case .finished: + preconditionFailure() + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + /// The possible states the state machine may be in. + @usableFromInline + internal enum State { + case idle(ServerHandlerStateMachine.Idle) + case handling(ServerHandlerStateMachine.Handling) + case draining(ServerHandlerStateMachine.Draining) + case finished(ServerHandlerStateMachine.Finished) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine { + /// The next state to transition to and any output which may be produced as a + /// result of a substate handling an action. + @usableFromInline + internal struct NextStateAndOutput { + @usableFromInline + internal var nextState: NextState + @usableFromInline + internal var output: Output + + @inlinable + internal init(nextState: NextState, output: Output) { + self.nextState = nextState + self.output = output + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine.NextStateAndOutput where Output == Void { + @inlinable + internal init(nextState: NextState) { + self.nextState = nextState + self.output = () + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine.Idle { + /// States which can be reached directly from 'Idle'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerHandlerStateMachine.State + + @inlinable + internal init(_state: ServerHandlerStateMachine.State) { + self.state = _state + } + + @inlinable + internal static func idle(_ state: ServerHandlerStateMachine.Idle) -> Self { + return Self(_state: .idle(state)) + } + + @inlinable + internal static func handling( + from: ServerHandlerStateMachine.Idle, + requestHeaders: HPACKHeaders + ) -> Self { + return Self(_state: .handling(.init(from: from, requestHeaders: requestHeaders))) + } + + @inlinable + internal static func finished(from: ServerHandlerStateMachine.Idle) -> Self { + return Self(_state: .finished(.init(from: from))) + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine.Handling { + /// States which can be reached directly from 'Handling'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerHandlerStateMachine.State + + @inlinable + internal init(_state: ServerHandlerStateMachine.State) { + self.state = _state + } + + @inlinable + internal static func handling(_ state: ServerHandlerStateMachine.Handling) -> Self { + return Self(_state: .handling(state)) + } + + @inlinable + internal static func draining(from: ServerHandlerStateMachine.Handling) -> Self { + return Self(_state: .draining(.init(from: from))) + } + + @inlinable + internal static func finished(from: ServerHandlerStateMachine.Handling) -> Self { + return Self(_state: .finished(.init(from: from))) + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine.Draining { + /// States which can be reached directly from 'Draining'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerHandlerStateMachine.State + + @inlinable + internal init(_state: ServerHandlerStateMachine.State) { + self.state = _state + } + + @inlinable + internal static func draining(_ state: ServerHandlerStateMachine.Draining) -> Self { + return Self(_state: .draining(state)) + } + + @inlinable + internal static func finished(from: ServerHandlerStateMachine.Draining) -> Self { + return Self(_state: .finished(.init(from: from))) + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerHandlerStateMachine.Finished { + /// States which can be reached directly from 'Finished'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerHandlerStateMachine.State + + @inlinable + init(_state: ServerHandlerStateMachine.State) { + self.state = _state + } + + @inlinable + internal static func finished(_ state: ServerHandlerStateMachine.Finished) -> Self { + return Self(_state: .finished(state)) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Actions.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Actions.swift new file mode 100644 index 00000000..dd323105 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Actions.swift @@ -0,0 +1,68 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +extension ServerInterceptorStateMachine { + @usableFromInline + enum InterceptAction: Hashable { + /// Forward the message to the interceptor pipeline. + case intercept + /// Cancel the call. + case cancel + /// Drop the message. + case drop + + @inlinable + init(from streamFilter: ServerInterceptorStateMachine.StreamFilter) { + switch streamFilter { + case .accept: + self = .intercept + case .reject: + self = .cancel + } + } + } + + @usableFromInline + enum InterceptedAction: Hashable { + /// Forward the message to the network or user handler. + case forward + /// Cancel the call. + case cancel + /// Drop the message. + case drop + + @inlinable + init(from streamFilter: ServerInterceptorStateMachine.StreamFilter) { + switch streamFilter { + case .accept: + self = .forward + case .reject: + self = .cancel + } + } + } + + @usableFromInline + enum CancelAction: Hashable { + /// Write a status then nil out the interceptor pipeline. + case sendStatusThenNilOutInterceptorPipeline + /// Nil out the interceptor pipeline. + case nilOutInterceptorPipeline + /// Do nothing. + case none + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Finished.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Finished.swift new file mode 100644 index 00000000..483240d5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Finished.swift @@ -0,0 +1,94 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +extension ServerInterceptorStateMachine { + /// The 'Finished' state is, as the name suggests, a terminal state. Nothing can happen in this + /// state. + @usableFromInline + struct Finished { + @usableFromInline + typealias NextStateAndOutput = + ServerInterceptorStateMachine.NextStateAndOutput + + init(from state: ServerInterceptorStateMachine.Intercepting) {} + + @inlinable + mutating func interceptRequestMetadata() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptRequestMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptRequestEnd() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedRequestMetadata() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedRequestMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedRequestEnd() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptResponseMetadata() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptResponseMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptResponseStatus() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedResponseMetadata() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedResponseMessage() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func interceptedResponseStatus() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .drop) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + return .init(nextState: .finished(self), output: .nilOutInterceptorPipeline) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Intercepting.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Intercepting.swift new file mode 100644 index 00000000..0d0a19e9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine+Intercepting.swift @@ -0,0 +1,141 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +extension ServerInterceptorStateMachine { + /// The 'Intercepting' state is responsible for validating that appropriate message parts are + /// forwarded to the interceptor pipeline and that messages parts which have been emitted from the + /// interceptors are valid to forward to either the network or the user handler (as interceptors + /// may emit new message parts). + /// + /// We only transition to the next state on `cancel` (which happens at the end of every RPC). + @usableFromInline + struct Intercepting { + @usableFromInline + typealias NextStateAndOutput = + ServerInterceptorStateMachine.NextStateAndOutput + + /// From the network into the interceptors. + @usableFromInline + internal private(set) var requestStreamIn: InboundStreamState + /// From the interceptors out to the handler. + @usableFromInline + internal private(set) var requestStreamOut: InboundStreamState + + /// From the handler into the interceptors. + @usableFromInline + internal private(set) var responseStreamIn: OutboundStreamState + /// From the interceptors out to the network. + @usableFromInline + internal private(set) var responseStreamOut: OutboundStreamState + + @usableFromInline + init() { + self.requestStreamIn = .idle + self.requestStreamOut = .idle + self.responseStreamIn = .idle + self.responseStreamOut = .idle + } + + @inlinable + mutating func interceptRequestMetadata() -> Self.NextStateAndOutput { + let filter = self.requestStreamIn.receiveMetadata() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptRequestMessage() -> Self.NextStateAndOutput { + let filter = self.requestStreamIn.receiveMessage() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptRequestEnd() -> Self.NextStateAndOutput { + let filter = self.requestStreamIn.receiveEnd() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedRequestMetadata() -> Self.NextStateAndOutput { + let filter = self.requestStreamOut.receiveMetadata() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedRequestMessage() -> Self.NextStateAndOutput { + let filter = self.requestStreamOut.receiveMessage() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedRequestEnd() -> Self.NextStateAndOutput { + let filter = self.requestStreamOut.receiveEnd() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptResponseMetadata() -> Self.NextStateAndOutput { + let filter = self.responseStreamIn.sendMetadata() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptResponseMessage() -> Self.NextStateAndOutput { + let filter = self.responseStreamIn.sendMessage() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptResponseStatus() -> Self.NextStateAndOutput { + let filter = self.responseStreamIn.sendEnd() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedResponseMetadata() -> Self.NextStateAndOutput { + let filter = self.responseStreamOut.sendMetadata() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedResponseMessage() -> Self.NextStateAndOutput { + let filter = self.responseStreamOut.sendMessage() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func interceptedResponseStatus() -> Self.NextStateAndOutput { + let filter = self.responseStreamOut.sendEnd() + return .init(nextState: .intercepting(self), output: .init(from: filter)) + } + + @inlinable + mutating func cancel() -> Self.NextStateAndOutput { + let output: CancelAction + + // Check the state of the response stream. If we haven't sent a status then we should emit + // one first. It may not reach the other side but we should try. + switch self.responseStreamOut { + case .idle, .writingMessages: + output = .sendStatusThenNilOutInterceptorPipeline + case .done: + output = .nilOutInterceptorPipeline + } + + return .init(nextState: .finished(from: self), output: output) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine.swift new file mode 100644 index 00000000..8863bc6b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/ServerInterceptorStateMachine.swift @@ -0,0 +1,286 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +@usableFromInline +internal struct ServerInterceptorStateMachine { + @usableFromInline + internal private(set) var state: Self.State + + @inlinable + init() { + self.state = .intercepting(.init()) + } + + @inlinable + mutating func interceptRequestMetadata() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptRequestMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptRequestMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptRequestMessage() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptRequestMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptRequestMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptRequestEnd() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptRequestEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptRequestEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedRequestMetadata() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedRequestMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedRequestMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedRequestMessage() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedRequestMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedRequestMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedRequestEnd() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedRequestEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedRequestEnd() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptResponseMetadata() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptResponseMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptResponseMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptResponseMessage() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptResponseMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptResponseMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptResponseStatus() -> InterceptAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptResponseStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptResponseStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedResponseMetadata() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedResponseMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedResponseMetadata() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedResponseMessage() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedResponseMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedResponseMessage() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func interceptedResponseStatus() -> InterceptedAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.interceptedResponseStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.interceptedResponseStatus() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } + + @inlinable + mutating func cancel() -> CancelAction { + switch self.state { + case var .intercepting(intercepting): + let nextStateAndOutput = intercepting.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + case var .finished(finished): + let nextStateAndOutput = finished.cancel() + self.state = nextStateAndOutput.nextState.state + return nextStateAndOutput.output + } + } +} + +extension ServerInterceptorStateMachine { + /// The possible states the state machine may be in. + @usableFromInline + internal enum State { + case intercepting(ServerInterceptorStateMachine.Intercepting) + case finished(ServerInterceptorStateMachine.Finished) + } +} + +extension ServerInterceptorStateMachine { + /// The next state to transition to and any output which may be produced as a + /// result of a substate handling an action. + @usableFromInline + internal struct NextStateAndOutput { + @usableFromInline + internal var nextState: NextState + @usableFromInline + internal var output: Output + + @inlinable + internal init(nextState: NextState, output: Output) { + self.nextState = nextState + self.output = output + } + } +} + +extension ServerInterceptorStateMachine.NextStateAndOutput where Output == Void { + internal init(nextState: NextState) { + self.nextState = nextState + self.output = () + } +} + +extension ServerInterceptorStateMachine.Intercepting { + /// States which can be reached directly from 'Intercepting'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerInterceptorStateMachine.State + + @inlinable + init(_state: ServerInterceptorStateMachine.State) { + self.state = _state + } + + @usableFromInline + internal static func intercepting(_ state: ServerInterceptorStateMachine.Intercepting) -> Self { + return Self(_state: .intercepting(state)) + } + + @usableFromInline + internal static func finished(from: ServerInterceptorStateMachine.Intercepting) -> Self { + return Self(_state: .finished(.init(from: from))) + } + } +} + +extension ServerInterceptorStateMachine.Finished { + /// States which can be reached directly from 'Finished'. + @usableFromInline + internal struct NextState { + @usableFromInline + let state: ServerInterceptorStateMachine.State + + @inlinable + internal init(_state: ServerInterceptorStateMachine.State) { + self.state = _state + } + + @usableFromInline + internal static func finished(_ state: ServerInterceptorStateMachine.Finished) -> Self { + return Self(_state: .finished(state)) + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/StreamState.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/StreamState.swift new file mode 100644 index 00000000..2ba68620 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncServerHandler/ServerInterceptorStateMachine/StreamState.swift @@ -0,0 +1,102 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +extension ServerInterceptorStateMachine { + @usableFromInline + internal enum StreamFilter: Hashable { + case accept + case reject + } + + @usableFromInline + internal enum InboundStreamState: Hashable { + case idle + case receivingMessages + case done + + @inlinable + mutating func receiveMetadata() -> StreamFilter { + switch self { + case .idle: + self = .receivingMessages + return .accept + case .receivingMessages, .done: + return .reject + } + } + + @inlinable + func receiveMessage() -> StreamFilter { + switch self { + case .receivingMessages: + return .accept + case .idle, .done: + return .reject + } + } + + @inlinable + mutating func receiveEnd() -> StreamFilter { + switch self { + case .idle, .receivingMessages: + self = .done + return .accept + case .done: + return .reject + } + } + } + + @usableFromInline + internal enum OutboundStreamState: Hashable { + case idle + case writingMessages + case done + + @inlinable + mutating func sendMetadata() -> StreamFilter { + switch self { + case .idle: + self = .writingMessages + return .accept + case .writingMessages, .done: + return .reject + } + } + + @inlinable + func sendMessage() -> StreamFilter { + switch self { + case .writingMessages: + return .accept + case .idle, .done: + return .reject + } + } + + @inlinable + mutating func sendEnd() -> StreamFilter { + switch self { + case .idle, .writingMessages: + self = .done + return .accept + case .done: + return .reject + } + } + } +} +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncWriter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncWriter.swift new file mode 100644 index 00000000..aba4c9de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/AsyncWriter.swift @@ -0,0 +1,332 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOCore + +/// An asynchronous writer which forwards messages to a delegate. +/// +/// Forwarding of messages to the delegate may be paused and resumed by controlling the writability +/// of the writer. This may be controlled by calls to ``toggleWritability()``. When the writer is +/// paused (by becoming unwritable) calls to ``write(_:)`` may suspend. When the writer is resumed +/// (by becoming writable) any calls which are suspended may be resumed. +/// +/// The writer must also be "finished" with a final value: as for writing, calls to ``finish(_:)`` +/// may suspend if the writer has been paused. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal final actor AsyncWriter: Sendable { + @usableFromInline + internal typealias Element = Delegate.Element + + @usableFromInline + internal typealias End = Delegate.End + + /// A value pending a write. + @usableFromInline + internal struct _Pending: Sendable { + @usableFromInline + var value: Value + + @usableFromInline + var continuation: CheckedContinuation + + @inlinable + internal init(_ value: Value, continuation: CheckedContinuation) { + self.value = value + self.continuation = continuation + } + } + + @usableFromInline + typealias PendingElement = _Pending + + @usableFromInline + typealias PendingEnd = _Pending + + @usableFromInline + internal enum _CompletionState: Sendable { + /// Finish hasn't been called yet. May move to `pending` or `completed`. + case incomplete + /// Finish has been called but the writer is paused. May move to `completed`. + case pending(PendingEnd) + /// The completion message has been sent to the delegate. This is a terminal state. + case completed + + /// Move from `pending` to `completed` and return the `PendingCompletion`. Returns `nil` if + /// the state was not `pending`. + @inlinable + mutating func completeIfPending() -> PendingEnd? { + switch self { + case let .pending(pending): + self = .completed + return pending + case .incomplete, .completed: + return nil + } + } + + @usableFromInline + var isPendingOrCompleted: Bool { + switch self { + case .incomplete: + return false + case .pending, .completed: + return true + } + } + } + + /// The maximum number of pending elements. `pendingElements` must not grow beyond this limit. + @usableFromInline + internal let _maxPendingElements: Int + + /// The maximum number of writes to the delegate made in `resume` before yielding to allow other + /// values to be queued. + @usableFromInline + internal let _maxWritesBeforeYield: Int + + /// Elements and continuations which have been buffered but are awaiting consumption by the + /// delegate. + @usableFromInline + internal var _pendingElements: CircularBuffer + + /// The completion state of the writer. + @usableFromInline + internal var _completionState: _CompletionState + + /// Whether the writer is paused. + @usableFromInline + internal var _isPaused: Bool + + /// The delegate to process elements. By convention we call the delegate before resuming any + /// continuation. + @usableFromInline + internal let _delegate: Delegate + + @inlinable + internal init( + maxPendingElements: Int = 16, + maxWritesBeforeYield: Int = 5, + isWritable: Bool = true, + delegate: Delegate + ) { + self._maxPendingElements = maxPendingElements + self._maxWritesBeforeYield = maxWritesBeforeYield + self._pendingElements = CircularBuffer(initialCapacity: maxPendingElements) + self._completionState = .incomplete + self._isPaused = !isWritable + self._delegate = delegate + } + + deinit { + switch self._completionState { + case .completed: + () + case .incomplete, .pending: + assertionFailure("writer has not completed is pending completion") + } + } + + /// As ``toggleWritability()`` but executed asynchronously. + @usableFromInline + internal nonisolated func toggleWritabilityAsynchronously() { + Task { + await self.toggleWritability() + } + } + + /// Toggles whether the writer is writable or not. The writer is initially writable. + /// + /// If the writer becomes writable then it may resume writes to the delegate. If it becomes + /// unwritable then calls to `write` may suspend until the writability changes again. + /// + /// This API does not offer explicit control over the writability state so the caller must ensure + /// calls to this function correspond with changes in writability. The reason for this is that the + /// underlying type is an `actor` and updating its state is therefore asynchronous. However, + /// this functions is not called from an asynchronous context so it is not possible to `await` + /// state updates to complete. Instead, changing the state is via a `nonisolated` function on + /// the `actor` which spawns a new task. If this or a similar API allowed the writability to be + /// explicitly set then calls to that API are not guaranteed to be ordered which may lead to + /// deadlock. + @usableFromInline + internal func toggleWritability() async { + if self._isPaused { + self._isPaused = false + await self.resumeWriting() + } else { + self._isPaused = true + } + } + + private func resumeWriting() async { + var writes = 0 + + while !self._isPaused { + if let pendingElement = self._pendingElements.popFirst() { + self._delegate.write(pendingElement.value) + pendingElement.continuation.resume() + } else if let pendingCompletion = self._completionState.completeIfPending() { + self._delegate.writeEnd(pendingCompletion.value) + pendingCompletion.continuation.resume() + } else { + break + } + + // `writes` will never exceed `maxWritesBeforeYield` so unchecked arithmetic is okay here. + writes &+= 1 + if writes == self._maxWritesBeforeYield { + writes = 0 + // We yield every so often to let the delegate (i.e. 'NIO.Channel') catch up since it may + // decide it is no longer writable. + await Task.yield() + } + } + } + + /// As ``cancel()`` but executed asynchronously. + @usableFromInline + internal nonisolated func cancelAsynchronously(withError error: Error) { + Task { + await self.cancel(withError: error) + } + } + + /// Cancel all pending writes. + /// + /// Any pending writes will be dropped and their continuations will be resumed with + /// a `CancellationError`. Any writes after cancellation has completed will also fail. + @usableFromInline + internal func cancel(withError error: Error) { + // If there's an end we should fail that last. + let pendingEnd: PendingEnd? + + // Mark our state as completed before resuming any continuations (any future writes should fail + // immediately). + switch self._completionState { + case .incomplete: + pendingEnd = nil + self._completionState = .completed + + case let .pending(pending): + pendingEnd = pending + self._completionState = .completed + + case .completed: + pendingEnd = nil + } + + while let pending = self._pendingElements.popFirst() { + pending.continuation.resume(throwing: error) + } + + pendingEnd?.continuation.resume(throwing: error) + } + + /// Write an `element`. + /// + /// The call may be suspend if the writer is paused. + /// + /// Throws: ``GRPCAsyncWriterError`` if the writer has already been finished or too many write tasks + /// have been suspended. + @inlinable + internal func write(_ element: Element) async throws { + // There are three outcomes of writing: + // - write the element directly (if the writer isn't paused and no writes are pending) + // - queue the element (the writer is paused or there are writes already pending) + // - error (the writer is complete or the queue is full). + return try await withTaskCancellationHandler { + if self._completionState.isPendingOrCompleted { + throw GRPCAsyncWriterError.alreadyFinished + } else if !self._isPaused, self._pendingElements.isEmpty { + self._delegate.write(element) + } else if self._pendingElements.count < self._maxPendingElements { + // The continuation will be resumed later. + try await withCheckedThrowingContinuation { continuation in + self._pendingElements.append(PendingElement(element, continuation: continuation)) + } + } else { + throw GRPCAsyncWriterError.tooManyPendingWrites + } + } onCancel: { + self.cancelAsynchronously(withError: CancellationError()) + } + } + + /// Write the final element + @inlinable + internal func finish(_ end: End) async throws { + return try await withTaskCancellationHandler { + if self._completionState.isPendingOrCompleted { + throw GRPCAsyncWriterError.alreadyFinished + } else if !self._isPaused, self._pendingElements.isEmpty { + self._completionState = .completed + self._delegate.writeEnd(end) + } else { + try await withCheckedThrowingContinuation { continuation in + // Either we're paused or there are pending writes which must be consumed first. + self._completionState = .pending(PendingEnd(end, continuation: continuation)) + } + } + } onCancel: { + self.cancelAsynchronously(withError: CancellationError()) + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncWriter where End == Void { + @inlinable + internal func finish() async throws { + try await self.finish(()) + } +} + +public struct GRPCAsyncWriterError: Error, Hashable { + private let wrapped: Wrapped + + @usableFromInline + internal enum Wrapped: Sendable { + case tooManyPendingWrites + case alreadyFinished + } + + @usableFromInline + internal init(_ wrapped: Wrapped) { + self.wrapped = wrapped + } + + /// There are too many writes pending. This may occur when too many Tasks are writing + /// concurrently. + public static let tooManyPendingWrites = Self(.tooManyPendingWrites) + + /// The writer has already finished. This may occur when the RPC completes prematurely, or when + /// a user calls finish more than once. + public static let alreadyFinished = Self(.alreadyFinished) +} + +@usableFromInline +internal protocol AsyncWriterDelegate: AnyObject, Sendable { + associatedtype Element: Sendable + associatedtype End: Sendable + + @inlinable + func write(_ element: Element) + + @inlinable + func writeEnd(_ end: End) +} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/Call+AsyncRequestStreamWriter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/Call+AsyncRequestStreamWriter.swift new file mode 100644 index 00000000..98d791f1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/Call+AsyncRequestStreamWriter.swift @@ -0,0 +1,34 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension Call where Request: Sendable, Response: Sendable { + internal func makeRequestStreamWriter() -> GRPCAsyncRequestStreamWriter { + let delegate = GRPCAsyncRequestStreamWriter.Delegate( + compressionEnabled: self.options.messageEncoding.enabledForRequests + ) { request, metadata in + self.send(.message(request, metadata), promise: nil) + } finish: { + self.send(.end, promise: nil) + } + + // Start as not-writable; writability will be toggled when the stream comes up. + return GRPCAsyncRequestStreamWriter(asyncWriter: .init(isWritable: false, delegate: delegate)) + } +} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/CancellationError+GRPCStatusTransformable.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/CancellationError+GRPCStatusTransformable.swift new file mode 100644 index 00000000..3539860f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/CancellationError+GRPCStatusTransformable.swift @@ -0,0 +1,26 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if compiler(>=5.6) + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension CancellationError: GRPCStatusTransformable { + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .unavailable, message: nil) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncBidirectionalStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncBidirectionalStreamingCall.swift new file mode 100644 index 00000000..139beb93 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncBidirectionalStreamingCall.swift @@ -0,0 +1,162 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import NIOHPACK + +/// Async-await variant of BidirectionalStreamingCall. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncBidirectionalStreamingCall: Sendable { + private let call: Call + private let responseParts: StreamingResponseParts + private let responseSource: PassthroughMessageSource + + /// A request stream writer for sending messages to the server. + public let requestStream: GRPCAsyncRequestStreamWriter + + /// The stream of responses from the server. + public let responseStream: GRPCAsyncResponseStream + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel() { + self.call.cancel(promise: nil) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + /// + /// - Important: The initial metadata will only be available when the first response has been + /// received. However, it is not necessary for the response to have been consumed before reading + /// this property. + public var initialMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.initialMetadata.get() + } + } + + /// The trailing metadata returned from the server. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var trailingMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.trailingMetadata.get() + } + } + + /// The final status of the the RPC. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var status: GRPCStatus { + get async { + // force-try acceptable because any error is encapsulated in a successful GRPCStatus future. + try! await self.responseParts.status.get() + } + } + + private init(call: Call) { + self.call = call + self.responseParts = StreamingResponseParts(on: call.eventLoop) { _ in } + self.responseSource = PassthroughMessageSource() + self.responseStream = .init(PassthroughMessageSequence(consuming: self.responseSource)) + self.requestStream = call.makeRequestStreamWriter() + } + + /// We expose this as the only non-private initializer so that the caller + /// knows that invocation is part of initialisation. + internal static func makeAndInvoke(call: Call) -> Self { + let asyncCall = Self(call: call) + + asyncCall.call.invokeStreamingRequests( + onStart: { + asyncCall.requestStream.asyncWriter.toggleWritabilityAsynchronously() + }, + onError: { error in + asyncCall.responseParts.handleError(error) + asyncCall.responseSource.finish(throwing: error) + asyncCall.requestStream.asyncWriter.cancelAsynchronously(withError: error) + }, + onResponsePart: AsyncCall.makeResponsePartHandler( + responseParts: asyncCall.responseParts, + responseSource: asyncCall.responseSource, + requestStream: asyncCall.requestStream + ) + ) + + return asyncCall + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +internal enum AsyncCall { + internal static func makeResponsePartHandler( + responseParts: StreamingResponseParts, + responseSource: PassthroughMessageSource, + requestStream: GRPCAsyncRequestStreamWriter?, + requestType: Request.Type = Request.self + ) -> (GRPCClientResponsePart) -> Void { + return { responsePart in + // Handle the metadata, trailers and status. + responseParts.handle(responsePart) + + // Handle the response messages and status. + switch responsePart { + case .metadata: + () + + case let .message(response): + // TODO: when we support backpressure we will need to stop ignoring the return value. + _ = responseSource.yield(response) + + case let .end(status, _): + if status.isOk { + responseSource.finish() + } else { + responseSource.finish(throwing: status) + } + + requestStream?.asyncWriter.cancelAsynchronously(withError: status) + } + } + } + + internal static func makeResponsePartHandler( + responseParts: UnaryResponseParts, + requestStream: GRPCAsyncRequestStreamWriter?, + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> (GRPCClientResponsePart) -> Void { + return { responsePart in + // Handle (most of) all parts. + responseParts.handle(responsePart) + + // Handle the status. + switch responsePart { + case .metadata, .message: + () + case let .end(status, _): + requestStream?.asyncWriter.cancelAsynchronously(withError: status) + } + } + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncClientStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncClientStreamingCall.swift new file mode 100644 index 00000000..df4b5b06 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncClientStreamingCall.swift @@ -0,0 +1,105 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import NIOHPACK + +/// Async-await variant of `ClientStreamingCall`. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncClientStreamingCall: Sendable { + private let call: Call + private let responseParts: UnaryResponseParts + + /// A request stream writer for sending messages to the server. + public let requestStream: GRPCAsyncRequestStreamWriter + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel() { + self.call.cancel(promise: nil) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + /// + /// - Important: The initial metadata will only be available when the response has been received. + public var initialMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.initialMetadata.get() + } + } + + /// The response returned by the server. + public var response: Response { + get async throws { + try await self.responseParts.response.get() + } + } + + /// The trailing metadata returned from the server. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var trailingMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.trailingMetadata.get() + } + } + + /// The final status of the the RPC. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var status: GRPCStatus { + get async { + // force-try acceptable because any error is encapsulated in a successful GRPCStatus future. + try! await self.responseParts.status.get() + } + } + + private init(call: Call) { + self.call = call + self.responseParts = UnaryResponseParts(on: call.eventLoop) + self.requestStream = call.makeRequestStreamWriter() + } + + /// We expose this as the only non-private initializer so that the caller + /// knows that invocation is part of initialisation. + internal static func makeAndInvoke(call: Call) -> Self { + let asyncCall = Self(call: call) + + asyncCall.call.invokeStreamingRequests( + onStart: { + asyncCall.requestStream.asyncWriter.toggleWritabilityAsynchronously() + }, + onError: { error in + asyncCall.responseParts.handleError(error) + asyncCall.requestStream.asyncWriter.cancelAsynchronously(withError: error) + }, + onResponsePart: AsyncCall.makeResponsePartHandler( + responseParts: asyncCall.responseParts, + requestStream: asyncCall.requestStream + ) + ) + + return asyncCall + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStream.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStream.swift new file mode 100644 index 00000000..25df9899 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStream.swift @@ -0,0 +1,60 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if compiler(>=5.6) + +/// This is currently a wrapper around AsyncThrowingStream because we want to be +/// able to swap out the implementation for something else in the future. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncRequestStream: AsyncSequence { + @usableFromInline + internal typealias _WrappedStream = PassthroughMessageSequence + + @usableFromInline + internal let _stream: _WrappedStream + + @inlinable + internal init(_ stream: _WrappedStream) { + self._stream = stream + } + + @inlinable + public func makeAsyncIterator() -> Iterator { + Self.AsyncIterator(self._stream) + } + + public struct Iterator: AsyncIteratorProtocol { + @usableFromInline + internal var iterator: _WrappedStream.AsyncIterator + + @usableFromInline + internal init(_ stream: _WrappedStream) { + self.iterator = stream.makeAsyncIterator() + } + + @inlinable + public mutating func next() async throws -> Element? { + try await self.iterator.next() + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncRequestStream: Sendable where Element: Sendable {} +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncRequestStream.Iterator: Sendable where Element: Sendable {} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStreamWriter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStreamWriter.swift new file mode 100644 index 00000000..073fa9d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncRequestStreamWriter.swift @@ -0,0 +1,127 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +/// An object allowing the holder -- a client -- to send requests on an RPC. +/// +/// Requests may be sent using ``send(_:compression:)``. After all requests have been sent +/// the user is responsible for closing the request stream by calling ``finish()``. +/// +/// ``` +/// // Send a request on the request stream, use the compression setting configured for the RPC. +/// try await stream.send(request) +/// +/// // Send a request and explicitly disable compression. +/// try await stream.send(request, compression: .disabled) +/// +/// // Finish the stream to indicate that no more messages will be sent. +/// try await stream.finish() +/// ``` +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncRequestStreamWriter: Sendable { + @usableFromInline + internal let asyncWriter: AsyncWriter> + + @inlinable + internal init(asyncWriter: AsyncWriter>) { + self.asyncWriter = asyncWriter + } + + /// Send a single request. + /// + /// To ensure requests are delivered in order callers should `await` the result of this call + /// before sending another request. Callers who do not need this guarantee do not have to `await` + /// the completion of this call and may send messages concurrently from multiple ``Task``s. + /// However, it is important to note that no more than 16 writes may be pending at any one time + /// and attempting to exceed this will result in an ``GRPCAsyncWriterError.tooManyPendingWrites`` + /// error being thrown. + /// + /// Callers must call ``finish()`` when they have no more requests left to send. + /// + /// - Parameters: + /// - request: The request to send. + /// - compression: Whether the request should be compressed or not. Ignored if compression was + /// not enabled for the RPC. + /// - Throws: ``GRPCAsyncWriterError`` if there are too many pending writes or the request stream + /// has already been finished. + @inlinable + public func send( + _ request: Request, + compression: Compression = .deferToCallDefault + ) async throws { + try await self.asyncWriter.write((request, compression)) + } + + /// Finish the request stream for the RPC. This must be called when there are no more requests to + /// be sent. + /// + /// - Throws: ``GRPCAsyncWriterError`` if the request stream has already been finished. + public func finish() async throws { + try await self.asyncWriter.finish() + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncRequestStreamWriter { + /// A delegate for the writer which writes messages to an underlying receiver.` + @usableFromInline + internal final class Delegate: AsyncWriterDelegate, Sendable { + @usableFromInline + internal typealias Element = (Request, Compression) + + @usableFromInline + internal typealias End = Void + + @usableFromInline + internal let _compressionEnabled: Bool + + @usableFromInline + internal let _send: @Sendable (Request, MessageMetadata) -> Void + + @usableFromInline + internal let _finish: @Sendable () -> Void + + @inlinable + internal init( + compressionEnabled: Bool, + send: @Sendable @escaping (Request, MessageMetadata) -> Void, + finish: @Sendable @escaping () -> Void + ) { + self._compressionEnabled = compressionEnabled + self._send = send + self._finish = finish + } + + @inlinable + internal func write(_ element: (Request, Compression)) { + let (request, compression) = element + let compress = compression.isEnabled(callDefault: self._compressionEnabled) + + // TODO: be smarter about inserting flushes. + // + // We currently always flush after every write which may trigger more syscalls than necessary. + let metadata = MessageMetadata(compress: compress, flush: true) + self._send(request, metadata) + } + + @inlinable + internal func writeEnd(_ end: Void) { + self._finish() + } + } +} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStream.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStream.swift new file mode 100644 index 00000000..b1918952 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStream.swift @@ -0,0 +1,58 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +/// This is currently a wrapper around AsyncThrowingStream because we want to be +/// able to swap out the implementation for something else in the future. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncResponseStream: AsyncSequence { + @usableFromInline + internal typealias WrappedStream = PassthroughMessageSequence + + @usableFromInline + internal let stream: WrappedStream + + @inlinable + internal init(_ stream: WrappedStream) { + self.stream = stream + } + + public func makeAsyncIterator() -> Iterator { + Self.AsyncIterator(self.stream) + } + + public struct Iterator: AsyncIteratorProtocol { + @usableFromInline + internal var iterator: WrappedStream.AsyncIterator + + fileprivate init(_ stream: WrappedStream) { + self.iterator = stream.makeAsyncIterator() + } + + @inlinable + public mutating func next() async throws -> Element? { + if Task.isCancelled { throw GRPCStatus(code: .cancelled) } + return try await self.iterator.next() + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncResponseStream: Sendable {} +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncResponseStream.Iterator: Sendable {} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStreamWriter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStreamWriter.swift new file mode 100644 index 00000000..1c662e24 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncResponseStreamWriter.swift @@ -0,0 +1,93 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if compiler(>=5.6) + +/// Writer for server-streaming RPC handlers to provide responses. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncResponseStreamWriter: Sendable { + @usableFromInline + internal typealias Element = (Response, Compression) + + @usableFromInline + internal typealias Delegate = AsyncResponseStreamWriterDelegate + + @usableFromInline + internal let asyncWriter: AsyncWriter + + @inlinable + internal init(wrapping asyncWriter: AsyncWriter) { + self.asyncWriter = asyncWriter + } + + @inlinable + public func send( + _ response: Response, + compression: Compression = .deferToCallDefault + ) async throws { + try await self.asyncWriter.write((response, compression)) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal final class AsyncResponseStreamWriterDelegate: AsyncWriterDelegate { + @usableFromInline + internal typealias Element = (Response, Compression) + + @usableFromInline + internal typealias End = GRPCStatus + + @usableFromInline + internal let _send: @Sendable (Response, Compression) -> Void + + @usableFromInline + internal let _finish: @Sendable (GRPCStatus) -> Void + + // Create a new AsyncResponseStreamWriterDelegate. + // + // - Important: the `send` and `finish` closures must be thread-safe. + @inlinable + internal init( + send: @escaping @Sendable (Response, Compression) -> Void, + finish: @escaping @Sendable (GRPCStatus) -> Void + ) { + self._send = send + self._finish = finish + } + + @inlinable + internal func _send( + _ response: Response, + compression: Compression = .deferToCallDefault + ) { + self._send(response, compression) + } + + // MARK: - AsyncWriterDelegate conformance. + + @inlinable + internal func write(_ element: (Response, Compression)) { + self._send(element.0, compression: element.1) + } + + @inlinable + internal func writeEnd(_ end: GRPCStatus) { + self._finish(end) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerCallContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerCallContext.swift new file mode 100644 index 00000000..7531355e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerCallContext.swift @@ -0,0 +1,119 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +@preconcurrency import Logging +import NIOConcurrencyHelpers +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncServerCallContext: Sendable { + @usableFromInline + let contextProvider: AsyncServerCallContextProvider + + /// Details of the request, including request headers and a logger. + public var request: Request + + /// A response context which may be used to set response headers and trailers. + public var response: Response { + Response(contextProvider: self.contextProvider) + } + + /// Access the `UserInfo` dictionary which is shared with the interceptor contexts for this RPC. + /// + /// - Important: While `UserInfo` has value-semantics, this function accesses a reference + /// wrapped `UserInfo`. The contexts passed to interceptors provide the same reference. As such + /// this may be used as a mechanism to pass information between interceptors and service + /// providers. + public func withUserInfo( + _ body: @Sendable @escaping (UserInfo) throws -> Result + ) async throws -> Result { + return try await self.contextProvider.withUserInfo(body) + } + + /// Modify the `UserInfo` dictionary which is shared with the interceptor contexts for this RPC. + /// + /// - Important: While `UserInfo` has value-semantics, this function accesses a reference + /// wrapped `UserInfo`. The contexts passed to interceptors provide the same reference. As such + /// this may be used as a mechanism to pass information between interceptors and service + /// providers. + public func withMutableUserInfo( + _ modify: @Sendable @escaping (inout UserInfo) -> Result + ) async throws -> Result { + return try await self.contextProvider.withMutableUserInfo(modify) + } + + @inlinable + internal init( + headers: HPACKHeaders, + logger: Logger, + contextProvider: AsyncServerCallContextProvider + ) { + self.request = Request(headers: headers, logger: logger) + self.contextProvider = contextProvider + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncServerCallContext { + public struct Request: Sendable { + /// The request headers received from the client at the start of the RPC. + public var headers: HPACKHeaders + + /// A logger. + public var logger: Logger + + @usableFromInline + init(headers: HPACKHeaders, logger: Logger) { + self.headers = headers + self.logger = logger + } + } + + public struct Response: Sendable { + private let contextProvider: AsyncServerCallContextProvider + + /// Set the metadata to return at the start of the RPC. + /// + /// - Important: If this is required it should be updated _before_ the first response is sent + /// via the response stream writer. Updates must not be made after the first response has + /// been sent. + public func setHeaders(_ headers: HPACKHeaders) async throws { + try await self.contextProvider.setResponseHeaders(headers) + } + + /// Set the metadata to return at the end of the RPC. + /// + /// If this is required it must be updated before returning from the handler. + public func setTrailers(_ trailers: HPACKHeaders) async throws { + try await self.contextProvider.setResponseTrailers(trailers) + } + + /// Whether compression should be enabled for responses, defaulting to `true`. Note that for + /// this value to take effect compression must have been enabled on the server and a compression + /// algorithm must have been negotiated with the client. + public func compressResponses(_ compress: Bool) async throws { + try await self.contextProvider.setResponseCompression(compress) + } + + @usableFromInline + internal init(contextProvider: AsyncServerCallContextProvider) { + self.contextProvider = contextProvider + } + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerHandler.swift new file mode 100644 index 00000000..d5c82ee6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerHandler.swift @@ -0,0 +1,839 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import Logging +import NIOCore +import NIOHPACK + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer, + Request: Sendable, + Response: Sendable +>: GRPCServerHandlerProtocol where Serializer.Input == Response, Deserializer.Output == Request { + @usableFromInline + internal let _handler: AsyncServerHandler + + public func receiveMetadata(_ metadata: HPACKHeaders) { + self._handler.receiveMetadata(metadata) + } + + public func receiveMessage(_ bytes: ByteBuffer) { + self._handler.receiveMessage(bytes) + } + + public func receiveEnd() { + self._handler.receiveEnd() + } + + public func receiveError(_ error: Error) { + self._handler.receiveError(error) + } + + public func finish() { + self._handler.finish() + } +} + +// MARK: - RPC Adapters + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCAsyncServerHandler { + public typealias Request = Deserializer.Output + public typealias Response = Serializer.Input + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + wrapping unary: @escaping @Sendable (Request, GRPCAsyncServerCallContext) async throws + -> Response + ) { + self._handler = .init( + context: context, + requestDeserializer: requestDeserializer, + responseSerializer: responseSerializer, + callType: .unary, + interceptors: interceptors, + userHandler: { requestStream, responseStreamWriter, context in + var iterator = requestStream.makeAsyncIterator() + guard let request = try await iterator.next(), try await iterator.next() == nil else { + throw GRPCError.ProtocolViolation("Unary RPC expects exactly one request") + } + let response = try await unary(request, context) + try await responseStreamWriter.send(response) + } + ) + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + wrapping clientStreaming: @escaping @Sendable ( + GRPCAsyncRequestStream, + GRPCAsyncServerCallContext + ) async throws -> Response + ) { + self._handler = .init( + context: context, + requestDeserializer: requestDeserializer, + responseSerializer: responseSerializer, + callType: .clientStreaming, + interceptors: interceptors, + userHandler: { requestStream, responseStreamWriter, context in + let response = try await clientStreaming(requestStream, context) + try await responseStreamWriter.send(response) + } + ) + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + wrapping serverStreaming: @escaping @Sendable ( + Request, + GRPCAsyncResponseStreamWriter, + GRPCAsyncServerCallContext + ) async throws -> Void + ) { + self._handler = .init( + context: context, + requestDeserializer: requestDeserializer, + responseSerializer: responseSerializer, + callType: .serverStreaming, + interceptors: interceptors, + userHandler: { requestStream, responseStreamWriter, context in + var iterator = requestStream.makeAsyncIterator() + guard let request = try await iterator.next(), try await iterator.next() == nil else { + throw GRPCError.ProtocolViolation("Server-streaming RPC expects exactly one request") + } + try await serverStreaming(request, responseStreamWriter, context) + } + ) + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + wrapping bidirectional: @escaping @Sendable ( + GRPCAsyncRequestStream, + GRPCAsyncResponseStreamWriter, + GRPCAsyncServerCallContext + ) async throws -> Void + ) { + self._handler = .init( + context: context, + requestDeserializer: requestDeserializer, + responseSerializer: responseSerializer, + callType: .bidirectionalStreaming, + interceptors: interceptors, + userHandler: bidirectional + ) + } +} + +// MARK: - Server Handler + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal final class AsyncServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer, + Request: Sendable, + Response: Sendable +>: GRPCServerHandlerProtocol where Serializer.Input == Response, Deserializer.Output == Request { + /// A response serializer. + @usableFromInline + internal let serializer: Serializer + + /// A request deserializer. + @usableFromInline + internal let deserializer: Deserializer + + /// The event loop that this handler executes on. + @usableFromInline + internal let eventLoop: EventLoop + + /// A `ByteBuffer` allocator provided by the underlying `Channel`. + @usableFromInline + internal let allocator: ByteBufferAllocator + + /// A user-provided error delegate which, if provided, is used to transform errors and potentially + /// pack errors into trailers. + @usableFromInline + internal let errorDelegate: ServerErrorDelegate? + + /// A logger. + @usableFromInline + internal let logger: Logger + + /// A reference to the user info. This is shared with the interceptor pipeline and may be accessed + /// from the async call context. `UserInfo` is _not_ `Sendable` and must always be accessed from + /// an appropriate event loop. + @usableFromInline + internal let userInfoRef: Ref + + /// Whether compression is enabled on the server and an algorithm has been negotiated with + /// the client + @usableFromInline + internal let compressionEnabledOnRPC: Bool + + /// Whether the RPC method would like to compress responses (if possible). Defaults to true. + @usableFromInline + internal var compressResponsesIfPossible: Bool + + /// A state machine for the interceptor pipeline. + @usableFromInline + internal private(set) var interceptorStateMachine: ServerInterceptorStateMachine + /// The interceptor pipeline. + @usableFromInline + internal private(set) var interceptors: Optional> + /// An object for writing intercepted responses to the channel. + @usableFromInline + internal private(set) var responseWriter: Optional + + /// A state machine for the user implemented function. + @usableFromInline + internal private(set) var handlerStateMachine: ServerHandlerStateMachine + /// A bag of components used by the user handler. + @usableFromInline + internal private(set) var handlerComponents: Optional + >> + + /// The user provided function to execute. + @usableFromInline + internal let userHandler: @Sendable ( + GRPCAsyncRequestStream, + GRPCAsyncResponseStreamWriter, + GRPCAsyncServerCallContext + ) async throws -> Void + + @inlinable + internal init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + callType: GRPCCallType, + interceptors: [ServerInterceptor], + userHandler: @escaping @Sendable ( + GRPCAsyncRequestStream, + GRPCAsyncResponseStreamWriter, + GRPCAsyncServerCallContext + ) async throws -> Void + ) { + self.serializer = responseSerializer + self.deserializer = requestDeserializer + self.eventLoop = context.eventLoop + self.allocator = context.allocator + self.responseWriter = context.responseWriter + self.errorDelegate = context.errorDelegate + self.compressionEnabledOnRPC = context.encoding.isEnabled + self.compressResponsesIfPossible = true + self.logger = context.logger + + self.userInfoRef = Ref(UserInfo()) + self.handlerStateMachine = .init() + self.handlerComponents = nil + + self.userHandler = userHandler + + self.interceptorStateMachine = .init() + self.interceptors = nil + self.interceptors = ServerInterceptorPipeline( + logger: context.logger, + eventLoop: context.eventLoop, + path: context.path, + callType: callType, + remoteAddress: context.remoteAddress, + userInfoRef: self.userInfoRef, + interceptors: interceptors, + onRequestPart: self.receiveInterceptedPart(_:), + onResponsePart: self.sendInterceptedPart(_:promise:) + ) + } + + // MARK: - GRPCServerHandlerProtocol conformance + + @inlinable + internal func receiveMetadata(_ headers: HPACKHeaders) { + switch self.interceptorStateMachine.interceptRequestMetadata() { + case .intercept: + self.interceptors?.receive(.metadata(headers)) + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + @inlinable + internal func receiveMessage(_ bytes: ByteBuffer) { + let request: Request + + do { + request = try self.deserializer.deserialize(byteBuffer: bytes) + } catch { + return self.cancel(error: error) + } + + switch self.interceptorStateMachine.interceptRequestMessage() { + case .intercept: + self.interceptors?.receive(.message(request)) + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + @inlinable + internal func receiveEnd() { + switch self.interceptorStateMachine.interceptRequestEnd() { + case .intercept: + self.interceptors?.receive(.end) + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + @inlinable + internal func receiveError(_ error: Error) { + self.cancel(error: error) + } + + @inlinable + internal func finish() { + self.cancel(error: nil) + } + + @usableFromInline + internal func cancel(error: Error?) { + self.eventLoop.assertInEventLoop() + + switch self.handlerStateMachine.cancel() { + case .cancelAndNilOutHandlerComponents: + // Cancel handler related things (task, response writer). + self.handlerComponents?.cancel() + self.handlerComponents = nil + + // We don't distinguish between having sent the status or not; we just tell the interceptor + // state machine that we want to send a response status. It will inform us whether to + // generate and send one or not. + switch self.interceptorStateMachine.interceptedResponseStatus() { + case .forward: + let error = error ?? GRPCStatus.processingError + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.errorDelegate + ) + self.responseWriter?.sendEnd(status: status, trailers: trailers, promise: nil) + case .drop, .cancel: + () + } + + case .none: + () + } + + switch self.interceptorStateMachine.cancel() { + case .sendStatusThenNilOutInterceptorPipeline: + self.responseWriter?.sendEnd(status: .processingError, trailers: [:], promise: nil) + fallthrough + case .nilOutInterceptorPipeline: + self.interceptors = nil + self.responseWriter = nil + case .none: + () + } + } + + // MARK: - Interceptors to User Function + + @inlinable + internal func receiveInterceptedPart(_ part: GRPCServerRequestPart) { + switch part { + case let .metadata(headers): + self.receiveInterceptedMetadata(headers) + case let .message(message): + self.receiveInterceptedMessage(message) + case .end: + self.receiveInterceptedEnd() + } + } + + @inlinable + internal func receiveInterceptedMetadata(_ headers: HPACKHeaders) { + switch self.interceptorStateMachine.interceptedRequestMetadata() { + case .forward: + () // continue + case .cancel: + return self.cancel(error: nil) + case .drop: + return + } + + switch self.handlerStateMachine.handleMetadata() { + case .invokeHandler: + // We're going to invoke the handler. We need to create a handful of things in order to do + // that: + // + // - A context which allows the handler to set response headers/trailers and provides them + // with a logger amongst other things. + // - A request source; we push request messages into this which the handler consumes via + // an async sequence. + // - An async writer and delegate. The delegate calls us back with responses. The writer is + // passed to the handler. + // + // All of these components are held in a bundle ("handler components") outside of the state + // machine. We release these when we eventually call cancel (either when we `self.cancel()` + // as a result of an error or when `self.finish()` is called). + let handlerContext = GRPCAsyncServerCallContext( + headers: headers, + logger: self.logger, + contextProvider: self + ) + + let requestSource = PassthroughMessageSource() + + let writerDelegate = AsyncResponseStreamWriterDelegate( + send: self.interceptResponseMessage(_:compression:), + finish: self.interceptResponseStatus(_:) + ) + let writer = AsyncWriter(delegate: writerDelegate) + + // The user handler has two exit modes: + // 1. It completes successfully (the async user function completes without throwing), or + // 2. It throws an error. + // + // On the happy path the 'ok' status is queued up on the async writer. On the error path + // the writer queue is drained and promise below is completed. When the promise is failed + // it processes the error (possibly via a delegate) and sends back an appropriate status. + // We require separate paths as the failure path needs to execute on the event loop to process + // the error. + let promise = self.eventLoop.makePromise(of: Void.self) + // The success path is taken care of by the Task. + promise.futureResult.whenFailure { error in + self.userHandlerThrewError(error) + } + + // Update our state before invoke the handler. + self.handlerStateMachine.handlerInvoked(requestHeaders: headers) + self.handlerComponents = ServerHandlerComponents( + requestSource: requestSource, + responseWriter: writer, + task: promise.completeWithTask { + // We don't have a task cancellation handler here: we do it in `self.cancel()`. + try await self.invokeUserHandler( + requestStreamSource: requestSource, + responseStreamWriter: writer, + callContext: handlerContext + ) + } + ) + + case .cancel: + self.cancel(error: nil) + } + } + + @Sendable + @usableFromInline + internal func invokeUserHandler( + requestStreamSource: PassthroughMessageSource, + responseStreamWriter: AsyncWriter>, + callContext: GRPCAsyncServerCallContext + ) async throws { + defer { + // It's possible the user handler completed before the end of the request stream. We + // explicitly finish it to drop any unconsumed inbound messages. + requestStreamSource.finish() + } + + do { + let requestStream = GRPCAsyncRequestStream(.init(consuming: requestStreamSource)) + let responseStream = GRPCAsyncResponseStreamWriter(wrapping: responseStreamWriter) + try await self.userHandler(requestStream, responseStream, callContext) + + // Done successfully. Queue up and send back an 'ok' status. + try await responseStreamWriter.finish(.ok) + } catch { + // Drop pending writes as we're on the error path. + await responseStreamWriter.cancel(withError: error) + + if let thrownStatus = error as? GRPCStatus, thrownStatus.isOk { + throw GRPCStatus(code: .unknown, message: "Handler threw error with status code 'ok'.") + } else { + throw error + } + } + } + + @usableFromInline + internal func userHandlerThrewError(_ error: Error) { + self.eventLoop.assertInEventLoop() + + switch self.handlerStateMachine.sendStatus() { + case let .intercept(requestHeaders, trailers): + let (status, processedTrailers) = ServerErrorProcessor.processObserverError( + error, + headers: requestHeaders, + trailers: trailers, + delegate: self.errorDelegate + ) + + switch self.interceptorStateMachine.interceptResponseStatus() { + case .intercept: + self.interceptors?.send(.end(status, processedTrailers), promise: nil) + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + + case .drop: + () + } + } + + @inlinable + internal func receiveInterceptedMessage(_ request: Request) { + switch self.interceptorStateMachine.interceptedRequestMessage() { + case .forward: + switch self.handlerStateMachine.handleMessage() { + case .forward: + self.handlerComponents?.requestSource.yield(request) + case .cancel: + self.cancel(error: nil) + } + + case .cancel: + self.cancel(error: nil) + + case .drop: + () + } + } + + @inlinable + internal func receiveInterceptedEnd() { + switch self.interceptorStateMachine.interceptedRequestEnd() { + case .forward: + switch self.handlerStateMachine.handleEnd() { + case .forward: + self.handlerComponents?.requestSource.finish() + case .cancel: + self.cancel(error: nil) + } + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + // MARK: - User Function To Interceptors + + @inlinable + internal func _interceptResponseMessage(_ response: Response, compression: Compression) { + self.eventLoop.assertInEventLoop() + + switch self.handlerStateMachine.sendMessage() { + case let .intercept(.some(headers)): + switch self.interceptorStateMachine.interceptResponseMetadata() { + case .intercept: + self.interceptors?.send(.metadata(headers), promise: nil) + case .cancel: + return self.cancel(error: nil) + case .drop: + () + } + // Fall through to the next case to send the response message. + fallthrough + + case .intercept(.none): + switch self.interceptorStateMachine.interceptResponseMessage() { + case .intercept: + let senderWantsCompression = compression.isEnabled( + callDefault: self.compressResponsesIfPossible + ) + + let compress = self.compressionEnabledOnRPC && senderWantsCompression + + let metadata = MessageMetadata(compress: compress, flush: true) + self.interceptors?.send(.message(response, metadata), promise: nil) + case .cancel: + return self.cancel(error: nil) + case .drop: + () + } + + case .drop: + () + } + } + + @Sendable + @inlinable + internal func interceptResponseMessage(_ response: Response, compression: Compression) { + if self.eventLoop.inEventLoop { + self._interceptResponseMessage(response, compression: compression) + } else { + self.eventLoop.execute { + self._interceptResponseMessage(response, compression: compression) + } + } + } + + @inlinable + internal func _interceptResponseStatus(_ status: GRPCStatus) { + self.eventLoop.assertInEventLoop() + + switch self.handlerStateMachine.sendStatus() { + case let .intercept(_, trailers): + switch self.interceptorStateMachine.interceptResponseStatus() { + case .intercept: + self.interceptors?.send(.end(status, trailers), promise: nil) + case .cancel: + return self.cancel(error: nil) + case .drop: + () + } + + case .drop: + () + } + } + + @Sendable + @inlinable + internal func interceptResponseStatus(_ status: GRPCStatus) { + if self.eventLoop.inEventLoop { + self._interceptResponseStatus(status) + } else { + self.eventLoop.execute { + self._interceptResponseStatus(status) + } + } + } + + @inlinable + internal func sendInterceptedPart( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch part { + case let .metadata(headers): + self.sendInterceptedMetadata(headers, promise: promise) + + case let .message(message, metadata): + do { + let bytes = try self.serializer.serialize(message, allocator: ByteBufferAllocator()) + self.sendInterceptedResponse(bytes, metadata: metadata, promise: promise) + } catch { + promise?.fail(error) + self.cancel(error: error) + } + + case let .end(status, trailers): + self.sendInterceptedStatus(status, metadata: trailers, promise: promise) + } + } + + @inlinable + internal func sendInterceptedMetadata( + _ metadata: HPACKHeaders, + promise: EventLoopPromise? + ) { + switch self.interceptorStateMachine.interceptedResponseMetadata() { + case .forward: + if let responseWriter = self.responseWriter { + responseWriter.sendMetadata(metadata, flush: false, promise: promise) + } else if let promise = promise { + promise.fail(GRPCStatus.processingError) + } + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + @inlinable + internal func sendInterceptedResponse( + _ bytes: ByteBuffer, + metadata: MessageMetadata, + promise: EventLoopPromise? + ) { + switch self.interceptorStateMachine.interceptedResponseMessage() { + case .forward: + if let responseWriter = self.responseWriter { + responseWriter.sendMessage(bytes, metadata: metadata, promise: promise) + } else if let promise = promise { + promise.fail(GRPCStatus.processingError) + } + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } + + @inlinable + internal func sendInterceptedStatus( + _ status: GRPCStatus, + metadata: HPACKHeaders, + promise: EventLoopPromise? + ) { + switch self.interceptorStateMachine.interceptedResponseStatus() { + case .forward: + if let responseWriter = self.responseWriter { + responseWriter.sendEnd(status: status, trailers: metadata, promise: promise) + } else if let promise = promise { + promise.fail(GRPCStatus.processingError) + } + case .cancel: + self.cancel(error: nil) + case .drop: + () + } + } +} + +// Sendability is unchecked as all mutable state is accessed/modified from an appropriate event +// loop. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncServerHandler: @unchecked Sendable {} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncServerHandler: AsyncServerCallContextProvider { + @usableFromInline + internal func setResponseHeaders(_ headers: HPACKHeaders) async throws { + let completed = self.eventLoop.submit { + self.handlerStateMachine.setResponseHeaders(headers) + } + try await completed.get() + } + + @usableFromInline + internal func setResponseTrailers(_ headers: HPACKHeaders) async throws { + let completed = self.eventLoop.submit { + self.handlerStateMachine.setResponseTrailers(headers) + } + try await completed.get() + } + + @usableFromInline + internal func setResponseCompression(_ enabled: Bool) async throws { + let completed = self.eventLoop.submit { + self.compressResponsesIfPossible = enabled + } + try await completed.get() + } + + @usableFromInline + func withUserInfo( + _ modify: @Sendable @escaping (UserInfo) throws -> Result + ) async throws -> Result { + let result = self.eventLoop.submit { + try modify(self.userInfoRef.value) + } + return try await result.get() + } + + @usableFromInline + func withMutableUserInfo( + _ modify: @Sendable @escaping (inout UserInfo) throws -> Result + ) async throws -> Result { + let result = self.eventLoop.submit { + try modify(&self.userInfoRef.value) + } + return try await result.get() + } +} + +/// This protocol exists so that the generic server handler can be erased from the +/// `GRPCAsyncServerCallContext`. +/// +/// It provides methods which update context on the async handler by first executing onto the +/// correct event loop. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +protocol AsyncServerCallContextProvider: Sendable { + func setResponseHeaders(_ headers: HPACKHeaders) async throws + func setResponseTrailers(_ trailers: HPACKHeaders) async throws + func setResponseCompression(_ enabled: Bool) async throws + + func withUserInfo( + _ modify: @Sendable @escaping (UserInfo) throws -> Result + ) async throws -> Result + + func withMutableUserInfo( + _ modify: @Sendable @escaping (inout UserInfo) throws -> Result + ) async throws -> Result +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal struct ServerHandlerComponents { + @usableFromInline + internal let task: Task + @usableFromInline + internal let responseWriter: AsyncWriter + @usableFromInline + internal let requestSource: PassthroughMessageSource + + @inlinable + init( + requestSource: PassthroughMessageSource, + responseWriter: AsyncWriter, + task: Task + ) { + self.task = task + self.responseWriter = responseWriter + self.requestSource = requestSource + } + + func cancel() { + // Cancel the request and response streams. + // + // The user handler is encouraged to check for cancellation, however, we should assume + // they do not. Cancelling the request source stops any more requests from being delivered + // to the request stream, and cancelling the writer will ensure no more responses are + // written. This should reduce how long the user handler runs for as it can no longer do + // anything useful. + self.requestSource.finish(throwing: CancellationError()) + self.responseWriter.cancelAsynchronously(withError: CancellationError()) + self.task.cancel() + } +} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerStreamingCall.swift new file mode 100644 index 00000000..53e88dea --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncServerStreamingCall.swift @@ -0,0 +1,108 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import NIOHPACK + +/// Async-await variant of `ServerStreamingCall`. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncServerStreamingCall { + private let call: Call + private let responseParts: StreamingResponseParts + private let responseSource: PassthroughMessageSource + + /// The stream of responses from the server. + public let responseStream: GRPCAsyncResponseStream + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel() { + self.call.cancel(promise: nil) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + /// + /// - Important: The initial metadata will only be available when the first response has been + /// received. However, it is not necessary for the response to have been consumed before reading + /// this property. + public var initialMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.initialMetadata.get() + } + } + + /// The trailing metadata returned from the server. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var trailingMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.trailingMetadata.get() + } + } + + /// The final status of the the RPC. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var status: GRPCStatus { + get async { + // force-try acceptable because any error is encapsulated in a successful GRPCStatus future. + try! await self.responseParts.status.get() + } + } + + private init(call: Call) { + self.call = call + // We ignore messages in the closure and instead feed them into the response source when we + // invoke the `call`. + self.responseParts = StreamingResponseParts(on: call.eventLoop) { _ in } + self.responseSource = PassthroughMessageSource() + self.responseStream = .init(PassthroughMessageSequence(consuming: self.responseSource)) + } + + /// We expose this as the only non-private initializer so that the caller + /// knows that invocation is part of initialisation. + internal static func makeAndInvoke( + call: Call, + _ request: Request + ) -> Self { + let asyncCall = Self(call: call) + + asyncCall.call.invokeUnaryRequest( + request, + onStart: {}, + onError: { error in + asyncCall.responseParts.handleError(error) + asyncCall.responseSource.finish(throwing: error) + }, + onResponsePart: AsyncCall.makeResponsePartHandler( + responseParts: asyncCall.responseParts, + responseSource: asyncCall.responseSource, + requestStream: nil, + requestType: Request.self + ) + ) + + return asyncCall + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncUnaryCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncUnaryCall.swift new file mode 100644 index 00000000..b30bb9db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCAsyncUnaryCall.swift @@ -0,0 +1,103 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import NIOHPACK + +/// A unary gRPC call. The request is sent on initialization. +/// +/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore +/// has reference semantics. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public struct GRPCAsyncUnaryCall: Sendable { + private let call: Call + private let responseParts: UnaryResponseParts + + /// The options used to make the RPC. + public var options: CallOptions { + self.call.options + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel() { + self.call.cancel(promise: nil) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + /// + /// - Important: The initial metadata will only be available when the response has been received. + public var initialMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.initialMetadata.get() + } + } + + /// The response message returned from the service if the call is successful. This may be throw + /// if the call encounters an error. + /// + /// Callers should rely on the `status` of the call for the canonical outcome. + public var response: Response { + get async throws { + try await self.responseParts.response.get() + } + } + + /// The trailing metadata returned from the server. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var trailingMetadata: HPACKHeaders { + get async throws { + try await self.responseParts.trailingMetadata.get() + } + } + + /// The final status of the the RPC. + /// + /// - Important: Awaiting this property will suspend until the responses have been consumed. + public var status: GRPCStatus { + get async { + // force-try acceptable because any error is encapsulated in a successful GRPCStatus future. + try! await self.responseParts.status.get() + } + } + + private init( + call: Call, + _ request: Request + ) { + self.call = call + self.responseParts = UnaryResponseParts(on: call.eventLoop) + self.call.invokeUnaryRequest( + request, + onStart: {}, + onError: self.responseParts.handleError(_:), + onResponsePart: self.responseParts.handle(_:) + ) + } + + /// We expose this as the only non-private initializer so that the caller + /// knows that invocation is part of initialisation. + internal static func makeAndInvoke( + call: Call, + _ request: Request + ) -> Self { + Self(call: call, request) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCChannel+AsyncAwaitSupport.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCChannel+AsyncAwaitSupport.swift new file mode 100644 index 00000000..8e781246 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCChannel+AsyncAwaitSupport.swift @@ -0,0 +1,227 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import SwiftProtobuf + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCChannel { + /// Make a unary gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncUnaryCall< + Request: Message & Sendable, + Response: Message & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncUnaryCall { + return GRPCAsyncUnaryCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .unary, + callOptions: callOptions, + interceptors: interceptors + ), + request + ) + } + + /// Make a unary gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncUnaryCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncUnaryCall { + return GRPCAsyncUnaryCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .unary, + callOptions: callOptions, + interceptors: interceptors + ), + request + ) + } + + /// Makes a client-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncClientStreamingCall< + Request: Message & Sendable, + Response: Message & Sendable + >( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncClientStreamingCall { + return GRPCAsyncClientStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .clientStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + } + + /// Makes a client-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncClientStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncClientStreamingCall { + return GRPCAsyncClientStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .clientStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + } + + /// Make a server-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncServerStreamingCall< + Request: Message & Sendable, + Response: Message & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncServerStreamingCall { + return GRPCAsyncServerStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .serverStreaming, + callOptions: callOptions, + interceptors: interceptors + ), + request + ) + } + + /// Make a server-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncServerStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncServerStreamingCall { + return GRPCAsyncServerStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .serverStreaming, + callOptions: callOptions, + interceptors: [] + ), + request + ) + } + + /// Makes a bidirectional-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncBidirectionalStreamingCall< + Request: Message & Sendable, + Response: Message & Sendable + >( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncBidirectionalStreamingCall { + return GRPCAsyncBidirectionalStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .bidirectionalStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + } + + /// Makes a bidirectional-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + internal func makeAsyncBidirectionalStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> GRPCAsyncBidirectionalStreamingCall { + return GRPCAsyncBidirectionalStreamingCall.makeAndInvoke( + call: self.makeCall( + path: path, + type: .bidirectionalStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCClient+AsyncAwaitSupport.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCClient+AsyncAwaitSupport.swift new file mode 100644 index 00000000..423174f1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCClient+AsyncAwaitSupport.swift @@ -0,0 +1,485 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +import SwiftProtobuf + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCClient { + public func makeAsyncUnaryCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncUnaryCall { + return self.channel.makeAsyncUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncUnaryCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncUnaryCall { + return self.channel.makeAsyncUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncServerStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncServerStreamingCall { + return self.channel.makeAsyncServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncServerStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncServerStreamingCall { + return self.channel.makeAsyncServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncClientStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncClientStreamingCall { + return self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncClientStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncClientStreamingCall { + return self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncBidirectionalStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncBidirectionalStreamingCall { + return self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeAsyncBidirectionalStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncBidirectionalStreamingCall { + return self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } +} + +// MARK: - "Simple, but safe" wrappers. + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCClient { + public func performAsyncUnaryCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) async throws -> Response { + let call = self.channel.makeAsyncUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + + return try await withTaskCancellationHandler { + try await call.response + } onCancel: { + call.cancel() + } + } + + public func performAsyncUnaryCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) async throws -> Response { + let call = self.channel.makeAsyncUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + + return try await withTaskCancellationHandler { + try await call.response + } onCancel: { + call.cancel() + } + } + + public func performAsyncServerStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream { + return self.channel.makeAsyncServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ).responseStream + } + + public func performAsyncServerStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream { + return self.channel.makeAsyncServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ).responseStream + } + + public func performAsyncClientStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable, + RequestStream: AsyncSequence & Sendable + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) async throws -> Response where RequestStream.Element == Request { + let call = self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return try await self.perform(call, with: requests) + } + + public func performAsyncClientStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable, + RequestStream: AsyncSequence & Sendable + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) async throws -> Response where RequestStream.Element == Request { + let call = self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return try await self.perform(call, with: requests) + } + + public func performAsyncClientStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable, + RequestStream: Sequence + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) async throws -> Response where RequestStream.Element == Request { + let call = self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return try await self.perform(call, with: AsyncStream(wrapping: requests)) + } + + public func performAsyncClientStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable, + RequestStream: Sequence + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) async throws -> Response where RequestStream.Element == Request { + let call = self.channel.makeAsyncClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return try await self.perform(call, with: AsyncStream(wrapping: requests)) + } + + public func performAsyncBidirectionalStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable, + RequestStream: AsyncSequence & Sendable + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream + where RequestStream.Element == Request { + let call = self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return self.perform(call, with: requests) + } + + public func performAsyncBidirectionalStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable, + RequestStream: AsyncSequence & Sendable + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream + where RequestStream.Element == Request { + let call = self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return self.perform(call, with: requests) + } + + public func performAsyncBidirectionalStreamingCall< + Request: SwiftProtobuf.Message & Sendable, + Response: SwiftProtobuf.Message & Sendable, + RequestStream: Sequence + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream where RequestStream.Element == Request { + let call = self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return self.perform(call, with: AsyncStream(wrapping: requests)) + } + + public func performAsyncBidirectionalStreamingCall< + Request: GRPCPayload & Sendable, + Response: GRPCPayload & Sendable, + RequestStream: Sequence + >( + path: String, + requests: RequestStream, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> GRPCAsyncResponseStream where RequestStream.Element == Request { + let call = self.channel.makeAsyncBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + return self.perform(call, with: AsyncStream(wrapping: requests)) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension GRPCClient { + @inlinable + internal func perform< + Request: Sendable, + Response: Sendable, + RequestStream: AsyncSequence & Sendable + >( + _ call: GRPCAsyncClientStreamingCall, + with requests: RequestStream + ) async throws -> Response where RequestStream.Element == Request { + return try await withTaskCancellationHandler { + Task { + do { + // `AsyncSequence`s are encouraged to co-operatively check for cancellation, and we will + // cancel the call `onCancel` anyway, so there's no need to check here too. + for try await request in requests { + try await call.requestStream.send(request) + } + try await call.requestStream.finish() + } catch { + // If we throw then cancel the call. We will rely on the response throwing an appropriate + // error below. + call.cancel() + } + } + + return try await call.response + } onCancel: { + call.cancel() + } + } + + @inlinable + internal func perform< + Request: Sendable, + Response: Sendable, + RequestStream: AsyncSequence & Sendable + >( + _ call: GRPCAsyncBidirectionalStreamingCall, + with requests: RequestStream + ) -> GRPCAsyncResponseStream where RequestStream.Element == Request { + Task { + do { + try await withTaskCancellationHandler { + // `AsyncSequence`s are encouraged to co-operatively check for cancellation, and we will + // cancel the call `onCancel` anyway, so there's no need to check here too. + for try await request in requests { + try await call.requestStream.send(request) + } + try await call.requestStream.finish() + } onCancel: { + call.cancel() + } + } catch { + call.cancel() + } + } + + return call.responseStream + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension AsyncStream { + /// Create an `AsyncStream` from a regular (non-async) `Sequence`. + /// + /// - Note: This is just here to avoid duplicating the above two `perform(_:with:)` functions + /// for `Sequence`. + fileprivate init(wrapping sequence: T) where T: Sequence, T.Element == Element { + self.init { continuation in + var iterator = sequence.makeIterator() + while let value = iterator.next() { + continuation.yield(value) + } + continuation.finish() + } + } +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCSendable.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCSendable.swift new file mode 100644 index 00000000..d0f0906d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/GRPCSendable.swift @@ -0,0 +1,37 @@ +/* + * Copyright 2022, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import NIOCore + +#if compiler(>=5.6) +public typealias GRPCSendable = Swift.Sendable +#else +public typealias GRPCSendable = Any +#endif // compiler(>=5.6) + +#if compiler(>=5.6) +@preconcurrency +public protocol GRPCPreconcurrencySendable: Sendable {} +#else +public protocol GRPCPreconcurrencySendable {} +#endif // compiler(>=5.6) + +#if compiler(>=5.6) +@preconcurrency public typealias GRPCChannelInitializer = @Sendable (Channel) + -> EventLoopFuture +#else +public typealias GRPCChannelInitializer = (Channel) -> EventLoopFuture +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSequence.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSequence.swift new file mode 100644 index 00000000..3bbfa582 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSequence.swift @@ -0,0 +1,64 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) + +/// An ``AsyncSequence`` adapter for a ``PassthroughMessageSource``.` +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal struct PassthroughMessageSequence: AsyncSequence { + @usableFromInline + internal typealias Element = Element + + @usableFromInline + internal typealias AsyncIterator = Iterator + + /// The source of messages in the sequence. + @usableFromInline + internal let _source: PassthroughMessageSource + + @usableFromInline + internal func makeAsyncIterator() -> Iterator { + return Iterator(storage: self._source) + } + + @usableFromInline + internal init(consuming source: PassthroughMessageSource) { + self._source = source + } + + @usableFromInline + internal struct Iterator: AsyncIteratorProtocol { + @usableFromInline + internal let _storage: PassthroughMessageSource + + fileprivate init(storage: PassthroughMessageSource) { + self._storage = storage + } + + @inlinable + internal func next() async throws -> Element? { + // The storage handles co-operative cancellation, so we don't bother checking here. + return try await self._storage.consumeNextElement() + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension PassthroughMessageSequence: Sendable {} +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension PassthroughMessageSequence.Iterator: Sendable {} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSource.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSource.swift new file mode 100644 index 00000000..6a077360 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/AsyncAwaitSupport/PassthroughMessageSource.swift @@ -0,0 +1,176 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if compiler(>=5.6) +import NIOConcurrencyHelpers +import NIOCore + +/// The source of messages for a ``PassthroughMessageSequence``.` +/// +/// Values may be provided to the source with calls to ``yield(_:)`` which returns whether the value +/// was accepted (and how many values are yet to be consumed) -- or dropped. +/// +/// The backing storage has an unbounded capacity and callers should use the number of unconsumed +/// values returned from ``yield(_:)`` as an indication of when to stop providing values. +/// +/// The source must be finished exactly once by calling ``finish()`` or ``finish(throwing:)`` to +/// indicate that the sequence should end with an error. +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +@usableFromInline +internal final class PassthroughMessageSource { + @usableFromInline + internal typealias _ContinuationResult = Result + + /// All state in this class must be accessed via the lock. + /// + /// - Important: We use a `class` with a lock rather than an `actor` as we must guarantee that + /// calls to ``yield(_:)`` are not reordered. + @usableFromInline + internal let _lock: Lock + + /// A queue of elements which may be consumed as soon as there is demand. + @usableFromInline + internal var _continuationResults: CircularBuffer<_ContinuationResult> + + /// A continuation which will be resumed in the future. The continuation must be `nil` + /// if ``continuationResults`` is not empty. + @usableFromInline + internal var _continuation: Optional> + + /// True if a terminal continuation result (`.success(nil)` or `.failure()`) has been seen. + /// No more values may be enqueued to `continuationResults` if this is `true`. + @usableFromInline + internal var _isTerminated: Bool + + @usableFromInline + internal init(initialBufferCapacity: Int = 16) { + self._lock = Lock() + self._continuationResults = CircularBuffer(initialCapacity: initialBufferCapacity) + self._continuation = nil + self._isTerminated = false + } + + // MARK: - Append / Yield + + @usableFromInline + internal enum YieldResult: Hashable { + /// The value was accepted. The `queueDepth` indicates how many elements are waiting to be + /// consumed. + /// + /// If `queueDepth` is zero then the value was consumed immediately. + case accepted(queueDepth: Int) + + /// The value was dropped because the source has already been finished. + case dropped + } + + @inlinable + @discardableResult + internal func yield(_ element: Element) -> YieldResult { + let continuationResult: _ContinuationResult = .success(element) + return self._yield(continuationResult, isTerminator: false) + } + + @inlinable + @discardableResult + internal func finish(throwing error: Failure? = nil) -> YieldResult { + let continuationResult: _ContinuationResult = error.map { .failure($0) } ?? .success(nil) + return self._yield(continuationResult, isTerminator: true) + } + + @usableFromInline + internal enum _YieldResult { + /// The sequence has already been terminated; drop the element. + case alreadyTerminated + /// The element was added to the queue to be consumed later. + case queued(Int) + /// Demand for an element already existed: complete the continuation with the result being + /// yielded. + case resume(CheckedContinuation) + } + + @inlinable + internal func _yield( + _ continuationResult: _ContinuationResult, isTerminator: Bool + ) -> YieldResult { + let result: _YieldResult = self._lock.withLock { + if self._isTerminated { + return .alreadyTerminated + } else { + self._isTerminated = isTerminator + } + + if let continuation = self._continuation { + self._continuation = nil + return .resume(continuation) + } else { + self._continuationResults.append(continuationResult) + return .queued(self._continuationResults.count) + } + } + + let yieldResult: YieldResult + switch result { + case let .queued(size): + yieldResult = .accepted(queueDepth: size) + case let .resume(continuation): + // If we resume a continuation then the queue must be empty + yieldResult = .accepted(queueDepth: 0) + continuation.resume(with: continuationResult) + case .alreadyTerminated: + yieldResult = .dropped + } + + return yieldResult + } + + // MARK: - Next + + @inlinable + internal func consumeNextElement() async throws -> Element? { + self._lock.lock() + if let nextResult = self._continuationResults.popFirst() { + self._lock.unlock() + return try nextResult.get() + } else if self._isTerminated { + self._lock.unlock() + return nil + } + + // Slow path; we need a continuation. + return try await withTaskCancellationHandler { + try await withCheckedThrowingContinuation { continuation in + // Nothing buffered and not terminated yet: save the continuation for later. + precondition(self._continuation == nil) + self._continuation = continuation + self._lock.unlock() + } + } onCancel: { + let continuation: CheckedContinuation? = self._lock.withLock { + let cont = self._continuation + self._continuation = nil + return cont + } + + continuation?.resume(throwing: CancellationError()) + } + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +// @unchecked is ok: mutable state is accessed/modified via a lock. +extension PassthroughMessageSource: @unchecked Sendable {} + +#endif // compiler(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/BidirectionalStreamingServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/BidirectionalStreamingServerHandler.swift new file mode 100644 index 00000000..11081d7d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/BidirectionalStreamingServerHandler.swift @@ -0,0 +1,378 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +public final class BidirectionalStreamingServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +>: GRPCServerHandlerProtocol { + public typealias Request = Deserializer.Output + public typealias Response = Serializer.Input + + /// A response serializer. + @usableFromInline + internal let serializer: Serializer + + /// A request deserializer. + @usableFromInline + internal let deserializer: Deserializer + + /// A pipeline of user provided interceptors. + @usableFromInline + internal var interceptors: ServerInterceptorPipeline! + + /// Stream events which have arrived before the stream observer future has been resolved. + @usableFromInline + internal var requestBuffer: CircularBuffer> = CircularBuffer() + + /// The context required in order create the function. + @usableFromInline + internal let context: CallHandlerContext + + /// A reference to a `UserInfo`. + @usableFromInline + internal let userInfoRef: Ref + + /// The user provided function to execute. + @usableFromInline + internal let observerFactory: (_StreamingResponseCallContext) + -> EventLoopFuture<(StreamEvent) -> Void> + + /// The state of the handler. + @usableFromInline + internal var state: State = .idle + + @usableFromInline + internal enum State { + // No headers have been received. + case idle + // Headers have been received, a context has been created and the user code has been called to + // make a stream observer with. The observer is yet to see any messages. + case creatingObserver(_StreamingResponseCallContext) + // The observer future has resolved and the observer may have seen messages. + case observing((StreamEvent) -> Void, _StreamingResponseCallContext) + // The observer has completed by completing the status promise. + case completed + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + observerFactory: @escaping (StreamingResponseCallContext) + -> EventLoopFuture<(StreamEvent) -> Void> + ) { + self.serializer = responseSerializer + self.deserializer = requestDeserializer + self.context = context + self.observerFactory = observerFactory + + let userInfoRef = Ref(UserInfo()) + self.userInfoRef = userInfoRef + self.interceptors = ServerInterceptorPipeline( + logger: context.logger, + eventLoop: context.eventLoop, + path: context.path, + callType: .bidirectionalStreaming, + remoteAddress: context.remoteAddress, + userInfoRef: userInfoRef, + interceptors: interceptors, + onRequestPart: self.receiveInterceptedPart(_:), + onResponsePart: self.sendInterceptedPart(_:promise:) + ) + } + + // MARK: - Public API: gRPC to Handler + + @inlinable + public func receiveMetadata(_ headers: HPACKHeaders) { + self.interceptors.receive(.metadata(headers)) + } + + @inlinable + public func receiveMessage(_ bytes: ByteBuffer) { + do { + let message = try self.deserializer.deserialize(byteBuffer: bytes) + self.interceptors.receive(.message(message)) + } catch { + self.handleError(error) + } + } + + @inlinable + public func receiveEnd() { + self.interceptors.receive(.end) + } + + @inlinable + public func receiveError(_ error: Error) { + self.handleError(error) + self.finish() + } + + @inlinable + public func finish() { + switch self.state { + case .idle: + self.interceptors = nil + self.state = .completed + + case let .creatingObserver(context), + let .observing(_, context): + context.statusPromise.fail(GRPCStatus(code: .unavailable, message: nil)) + + case .completed: + self.interceptors = nil + } + } + + // MARK: - Interceptors to User Function + + @inlinable + internal func receiveInterceptedPart(_ part: GRPCServerRequestPart) { + switch part { + case let .metadata(headers): + self.receiveInterceptedMetadata(headers) + case let .message(message): + self.receiveInterceptedMessage(message) + case .end: + self.receiveInterceptedEnd() + } + } + + @inlinable + internal func receiveInterceptedMetadata(_ headers: HPACKHeaders) { + switch self.state { + case .idle: + // Make a context to invoke the observer block factory with. + let context = _StreamingResponseCallContext( + eventLoop: self.context.eventLoop, + headers: headers, + logger: self.context.logger, + userInfoRef: self.userInfoRef, + compressionIsEnabled: self.context.encoding.isEnabled, + closeFuture: self.context.closeFuture, + sendResponse: self.interceptResponse(_:metadata:promise:) + ) + + // Move to the next state. + self.state = .creatingObserver(context) + + // Send response headers back via the interceptors. + self.interceptors.send(.metadata([:]), promise: nil) + + // Register callbacks on the status future. + context.statusPromise.futureResult.whenComplete(self.userFunctionStatusResolved(_:)) + + // Make an observer block and register a completion block. + self.observerFactory(context).whenComplete(self.userFunctionResolvedWithResult(_:)) + + case .creatingObserver, .observing: + self.handleError(GRPCError.ProtocolViolation("Multiple header blocks received on RPC")) + + case .completed: + // We may receive headers from the interceptor pipeline if we have already finished (i.e. due + // to an error or otherwise) and an interceptor doing some async work later emitting headers. + // Dropping them is fine. + () + } + } + + @inlinable + internal func receiveInterceptedMessage(_ request: Request) { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("Message received before headers")) + case .creatingObserver: + self.requestBuffer.append(.message(request)) + case let .observing(observer, _): + observer(.message(request)) + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + @inlinable + internal func receiveInterceptedEnd() { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("End of stream received before headers")) + case .creatingObserver: + self.requestBuffer.append(.end) + case let .observing(observer, _): + observer(.end) + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + // MARK: - User Function To Interceptors + + @inlinable + internal func userFunctionResolvedWithResult( + _ result: Result<(StreamEvent) -> Void, Error> + ) { + switch self.state { + case .idle, .observing: + // The observer block can't resolve if it hasn't been created ('idle') and it can't be + // resolved more than once ('observing'). + preconditionFailure() + + case let .creatingObserver(context): + switch result { + case let .success(observer): + // We have an observer block now; unbuffer any requests. + self.state = .observing(observer, context) + while let request = self.requestBuffer.popFirst() { + observer(request) + } + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + // We've already completed. That's fine. + () + } + } + + @inlinable + internal func interceptResponse( + _ response: Response, + metadata: MessageMetadata, + promise: EventLoopPromise? + ) { + switch self.state { + case .idle: + // The observer block can't end responses if it doesn't exist! + preconditionFailure() + + case .creatingObserver, .observing: + // The user has access to the response context before returning a future observer, + // so 'creatingObserver' is valid here (if a little strange). + self.interceptors.send(.message(response, metadata), promise: promise) + + case .completed: + promise?.fail(GRPCError.AlreadyComplete()) + } + } + + @inlinable + internal func userFunctionStatusResolved(_ result: Result) { + switch self.state { + case .idle: + // The promise can't fail before we create it. + preconditionFailure() + + // Making is possible, the user can complete the status before returning a stream handler. + case let .creatingObserver(context), let .observing(_, context): + switch result { + case let .success(status): + // We're sending end back, we're done. + self.state = .completed + self.interceptors.send(.end(status, context.trailers), promise: nil) + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + () + } + } + + @inlinable + internal func handleError(_ error: Error, thrownFromHandler isHandlerError: Bool = false) { + switch self.state { + case .idle: + assert(!isHandlerError) + self.state = .completed + // We don't have a promise to fail. Just send back end. + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + self.interceptors.send(.end(status, trailers), promise: nil) + + case let .creatingObserver(context), + let .observing(_, context): + // We don't have a promise to fail. Just send back end. + self.state = .completed + + let status: GRPCStatus + let trailers: HPACKHeaders + + if isHandlerError { + (status, trailers) = ServerErrorProcessor.processObserverError( + error, + headers: context.headers, + trailers: context.trailers, + delegate: self.context.errorDelegate + ) + } else { + (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + } + + self.interceptors.send(.end(status, trailers), promise: nil) + // We're already in the 'completed' state so failing the promise will be a no-op in the + // callback to 'userHandlerCompleted' (but we also need to avoid leaking the promise.) + context.statusPromise.fail(error) + + case .completed: + () + } + } + + @inlinable + internal func sendInterceptedPart( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch part { + case let .metadata(headers): + self.context.responseWriter.sendMetadata(headers, flush: true, promise: promise) + + case let .message(message, metadata): + do { + let bytes = try self.serializer.serialize(message, allocator: ByteBufferAllocator()) + self.context.responseWriter.sendMessage(bytes, metadata: metadata, promise: promise) + } catch { + // Serialization failed: fail the promise and send end. + promise?.fail(error) + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + // Loop back via the interceptors. + self.interceptors.send(.end(status, trailers), promise: nil) + } + + case let .end(status, trailers): + self.context.responseWriter.sendEnd(status: status, trailers: trailers, promise: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ClientStreamingServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ClientStreamingServerHandler.swift new file mode 100644 index 00000000..9e2345eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ClientStreamingServerHandler.swift @@ -0,0 +1,364 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +public final class ClientStreamingServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +>: GRPCServerHandlerProtocol { + public typealias Request = Deserializer.Output + public typealias Response = Serializer.Input + + /// A response serializer. + @usableFromInline + internal let serializer: Serializer + + /// A request deserializer. + @usableFromInline + internal let deserializer: Deserializer + + /// A pipeline of user provided interceptors. + @usableFromInline + internal var interceptors: ServerInterceptorPipeline! + + /// Stream events which have arrived before the stream observer future has been resolved. + @usableFromInline + internal var requestBuffer: CircularBuffer> = CircularBuffer() + + /// The context required in order create the function. + @usableFromInline + internal let context: CallHandlerContext + + /// A reference to a `UserInfo`. + @usableFromInline + internal let userInfoRef: Ref + + /// The user provided function to execute. + @usableFromInline + internal let handlerFactory: (UnaryResponseCallContext) + -> EventLoopFuture<(StreamEvent) -> Void> + + /// The state of the handler. + @usableFromInline + internal var state: State = .idle + + @usableFromInline + internal enum State { + // Nothing has happened yet. + case idle + // Headers have been received, a context has been created and the user code has been called to + // make an observer with. The observer future hasn't completed yet and, as such, the observer + // is yet to see any events. + case creatingObserver(UnaryResponseCallContext) + // The observer future has succeeded, messages may have been delivered to it. + case observing((StreamEvent) -> Void, UnaryResponseCallContext) + // The observer has completed by completing the status promise. + case completed + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + observerFactory: @escaping (UnaryResponseCallContext) + -> EventLoopFuture<(StreamEvent) -> Void> + ) { + self.serializer = responseSerializer + self.deserializer = requestDeserializer + self.context = context + self.handlerFactory = observerFactory + + let userInfoRef = Ref(UserInfo()) + self.userInfoRef = userInfoRef + self.interceptors = ServerInterceptorPipeline( + logger: context.logger, + eventLoop: context.eventLoop, + path: context.path, + callType: .clientStreaming, + remoteAddress: context.remoteAddress, + userInfoRef: userInfoRef, + interceptors: interceptors, + onRequestPart: self.receiveInterceptedPart(_:), + onResponsePart: self.sendInterceptedPart(_:promise:) + ) + } + + // MARK: Public API; gRPC to Handler + + @inlinable + public func receiveMetadata(_ headers: HPACKHeaders) { + self.interceptors.receive(.metadata(headers)) + } + + @inlinable + public func receiveMessage(_ bytes: ByteBuffer) { + do { + let message = try self.deserializer.deserialize(byteBuffer: bytes) + self.interceptors.receive(.message(message)) + } catch { + self.handleError(error) + } + } + + @inlinable + public func receiveEnd() { + self.interceptors.receive(.end) + } + + @inlinable + public func receiveError(_ error: Error) { + self.handleError(error) + self.finish() + } + + @inlinable + public func finish() { + switch self.state { + case .idle: + self.interceptors = nil + self.state = .completed + + case let .creatingObserver(context), + let .observing(_, context): + context.responsePromise.fail(GRPCStatus(code: .unavailable, message: nil)) + + case .completed: + self.interceptors = nil + } + } + + // MARK: Interceptors to User Function + + @inlinable + internal func receiveInterceptedPart(_ part: GRPCServerRequestPart) { + switch part { + case let .metadata(headers): + self.receiveInterceptedMetadata(headers) + case let .message(message): + self.receiveInterceptedMessage(message) + case .end: + self.receiveInterceptedEnd() + } + } + + @inlinable + internal func receiveInterceptedMetadata(_ headers: HPACKHeaders) { + switch self.state { + case .idle: + // Make a context to invoke the observer block factory with. + let context = UnaryResponseCallContext( + eventLoop: self.context.eventLoop, + headers: headers, + logger: self.context.logger, + userInfoRef: self.userInfoRef, + closeFuture: self.context.closeFuture + ) + + // Move to the next state. + self.state = .creatingObserver(context) + + // Register a callback on the response future. + context.responsePromise.futureResult.whenComplete(self.userFunctionCompletedWithResult(_:)) + + // Make an observer block and register a completion block. + self.handlerFactory(context).whenComplete(self.userFunctionResolved(_:)) + + // Send response headers back via the interceptors. + self.interceptors.send(.metadata([:]), promise: nil) + + case .creatingObserver, .observing: + self.handleError(GRPCError.ProtocolViolation("Multiple header blocks received")) + + case .completed: + // We may receive headers from the interceptor pipeline if we have already finished (i.e. due + // to an error or otherwise) and an interceptor doing some async work later emitting headers. + // Dropping them is fine. + () + } + } + + @inlinable + internal func receiveInterceptedMessage(_ request: Request) { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("Message received before headers")) + case .creatingObserver: + self.requestBuffer.append(.message(request)) + case let .observing(observer, _): + observer(.message(request)) + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + @inlinable + internal func receiveInterceptedEnd() { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("end received before headers")) + case .creatingObserver: + self.requestBuffer.append(.end) + case let .observing(observer, _): + observer(.end) + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + // MARK: User Function to Interceptors + + @inlinable + internal func userFunctionResolved(_ result: Result<(StreamEvent) -> Void, Error>) { + switch self.state { + case .idle, .observing: + // The observer block can't resolve if it hasn't been created ('idle') and it can't be + // resolved more than once ('created'). + preconditionFailure() + + case let .creatingObserver(context): + switch result { + case let .success(observer): + // We have an observer block now; unbuffer any requests. + self.state = .observing(observer, context) + while let request = self.requestBuffer.popFirst() { + observer(request) + } + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + // We've already completed. That's fine. + () + } + } + + @inlinable + internal func userFunctionCompletedWithResult(_ result: Result) { + switch self.state { + case .idle: + // Invalid state: the user function can only complete if it exists.. + preconditionFailure() + + case let .creatingObserver(context), + let .observing(_, context): + switch result { + case let .success(response): + // Complete when we send end. + self.state = .completed + + // Compression depends on whether it's enabled on the server and the setting in the caller + // context. + let compress = self.context.encoding.isEnabled && context.compressionEnabled + let metadata = MessageMetadata(compress: compress, flush: false) + self.interceptors.send(.message(response, metadata), promise: nil) + self.interceptors.send(.end(context.responseStatus, context.trailers), promise: nil) + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + // We've already completed. Ignore this. + () + } + } + + @inlinable + internal func handleError(_ error: Error, thrownFromHandler isHandlerError: Bool = false) { + switch self.state { + case .idle: + assert(!isHandlerError) + self.state = .completed + // We don't have a promise to fail. Just send back end. + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + self.interceptors.send(.end(status, trailers), promise: nil) + + case let .creatingObserver(context), + let .observing(_, context): + // We don't have a promise to fail. Just send back end. + self.state = .completed + + let status: GRPCStatus + let trailers: HPACKHeaders + + if isHandlerError { + (status, trailers) = ServerErrorProcessor.processObserverError( + error, + headers: context.headers, + trailers: context.trailers, + delegate: self.context.errorDelegate + ) + } else { + (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + } + + self.interceptors.send(.end(status, trailers), promise: nil) + // We're already in the 'completed' state so failing the promise will be a no-op in the + // callback to 'userFunctionCompletedWithResult' (but we also need to avoid leaking the + // promise.) + context.responsePromise.fail(error) + + case .completed: + () + } + } + + // MARK: Interceptor Glue + + @inlinable + internal func sendInterceptedPart( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch part { + case let .metadata(headers): + self.context.responseWriter.sendMetadata(headers, flush: true, promise: promise) + + case let .message(message, metadata): + do { + let bytes = try self.serializer.serialize(message, allocator: ByteBufferAllocator()) + self.context.responseWriter.sendMessage(bytes, metadata: metadata, promise: promise) + } catch { + // Serialization failed: fail the promise and send end. + promise?.fail(error) + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + // Loop back via the interceptors. + self.interceptors.send(.end(status, trailers), promise: nil) + } + + case let .end(status, trailers): + self.context.responseWriter.sendEnd(status: status, trailers: trailers, promise: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerHandlerProtocol.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerHandlerProtocol.swift new file mode 100644 index 00000000..631b2bdf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerHandlerProtocol.swift @@ -0,0 +1,70 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +/// This protocol lays out the inbound interface between the gRPC module and generated server code. +/// On receiving a new RPC, gRPC will ask all available service providers for an instance of this +/// protocol in order to handle the RPC. +/// +/// See also: `CallHandlerProvider.handle(method:context:)` +public protocol GRPCServerHandlerProtocol { + /// Called when request headers have been received at the start of an RPC. + /// - Parameter metadata: The request headers. + func receiveMetadata(_ metadata: HPACKHeaders) + + /// Called when request message has been received. + /// - Parameter bytes: The bytes of the serialized request. + func receiveMessage(_ bytes: ByteBuffer) + + /// Called at the end of the request stream. + func receiveEnd() + + /// Called when an error has been encountered. The handler should be torn down on receiving an + /// error. + /// - Parameter error: The error which has been encountered. + func receiveError(_ error: Error) + + /// Called when the RPC handler should be torn down. + func finish() +} + +/// This protocol defines the outbound interface between the gRPC module and generated server code. +/// It is used by server handlers in order to send responses back to gRPC. +@usableFromInline +internal protocol GRPCServerResponseWriter { + /// Send the initial response metadata. + /// - Parameters: + /// - metadata: The user-provided metadata to send to the client. + /// - flush: Whether a flush should be emitted after writing the metadata. + /// - promise: A promise to complete once the metadata has been handled. + func sendMetadata(_ metadata: HPACKHeaders, flush: Bool, promise: EventLoopPromise?) + + /// Send the serialized bytes of a response message. + /// - Parameters: + /// - bytes: The serialized bytes to send to the client. + /// - metadata: Metadata associated with sending the response, such as whether it should be + /// compressed. + /// - promise: A promise to complete once the message as been handled. + func sendMessage(_ bytes: ByteBuffer, metadata: MessageMetadata, promise: EventLoopPromise?) + + /// Ends the response stream. + /// - Parameters: + /// - status: The final status of the RPC. + /// - trailers: Any user-provided trailers to send back to the client with the status. + /// - promise: A promise to complete once the status and trailers have been handled. + func sendEnd(status: GRPCStatus, trailers: HPACKHeaders, promise: EventLoopPromise?) +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerStreamingServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerStreamingServerHandler.swift new file mode 100644 index 00000000..8526e638 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/ServerStreamingServerHandler.swift @@ -0,0 +1,350 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +public final class ServerStreamingServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +>: GRPCServerHandlerProtocol { + public typealias Request = Deserializer.Output + public typealias Response = Serializer.Input + + /// A response serializer. + @usableFromInline + internal let serializer: Serializer + + /// A request deserializer. + @usableFromInline + internal let deserializer: Deserializer + + /// A pipeline of user provided interceptors. + @usableFromInline + internal var interceptors: ServerInterceptorPipeline! + + /// The context required in order create the function. + @usableFromInline + internal let context: CallHandlerContext + + /// A reference to a `UserInfo`. + @usableFromInline + internal let userInfoRef: Ref + + /// The user provided function to execute. + @usableFromInline + internal let userFunction: (Request, StreamingResponseCallContext) + -> EventLoopFuture + + /// The state of the handler. + @usableFromInline + internal var state: State = .idle + + @usableFromInline + internal enum State { + // Initial state. Nothing has happened yet. + case idle + // Headers have been received and now we're holding a context with which to invoke the user + // function when we receive a message. + case createdContext(_StreamingResponseCallContext) + // The user function has been invoked, we're waiting for the status promise to be completed. + case invokedFunction(_StreamingResponseCallContext) + // The function has completed or we are no longer proceeding with execution (because of an error + // or unexpected closure). + case completed + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + userFunction: @escaping (Request, StreamingResponseCallContext) + -> EventLoopFuture + ) { + self.serializer = responseSerializer + self.deserializer = requestDeserializer + self.context = context + self.userFunction = userFunction + + let userInfoRef = Ref(UserInfo()) + self.userInfoRef = userInfoRef + self.interceptors = ServerInterceptorPipeline( + logger: context.logger, + eventLoop: context.eventLoop, + path: context.path, + callType: .serverStreaming, + remoteAddress: context.remoteAddress, + userInfoRef: userInfoRef, + interceptors: interceptors, + onRequestPart: self.receiveInterceptedPart(_:), + onResponsePart: self.sendInterceptedPart(_:promise:) + ) + } + + // MARK: Public API; gRPC to Handler + + @inlinable + public func receiveMetadata(_ headers: HPACKHeaders) { + self.interceptors.receive(.metadata(headers)) + } + + @inlinable + public func receiveMessage(_ bytes: ByteBuffer) { + do { + let message = try self.deserializer.deserialize(byteBuffer: bytes) + self.interceptors.receive(.message(message)) + } catch { + self.handleError(error) + } + } + + @inlinable + public func receiveEnd() { + self.interceptors.receive(.end) + } + + @inlinable + public func receiveError(_ error: Error) { + self.handleError(error) + self.finish() + } + + @inlinable + public func finish() { + switch self.state { + case .idle: + self.interceptors = nil + self.state = .completed + + case let .createdContext(context), + let .invokedFunction(context): + context.statusPromise.fail(GRPCStatus(code: .unavailable, message: nil)) + + case .completed: + self.interceptors = nil + } + } + + // MARK: - Interceptors to User Function + + @inlinable + internal func receiveInterceptedPart(_ part: GRPCServerRequestPart) { + switch part { + case let .metadata(headers): + self.receiveInterceptedMetadata(headers) + case let .message(message): + self.receiveInterceptedMessage(message) + case .end: + self.receiveInterceptedEnd() + } + } + + @inlinable + internal func receiveInterceptedMetadata(_ headers: HPACKHeaders) { + switch self.state { + case .idle: + // Make a context to invoke the observer block factory with. + let context = _StreamingResponseCallContext( + eventLoop: self.context.eventLoop, + headers: headers, + logger: self.context.logger, + userInfoRef: self.userInfoRef, + compressionIsEnabled: self.context.encoding.isEnabled, + closeFuture: self.context.closeFuture, + sendResponse: self.interceptResponse(_:metadata:promise:) + ) + + // Move to the next state. + self.state = .createdContext(context) + + // Register a callback on the status future. + context.statusPromise.futureResult.whenComplete(self.userFunctionCompletedWithResult(_:)) + + // Send response headers back via the interceptors. + self.interceptors.send(.metadata([:]), promise: nil) + + case .createdContext, .invokedFunction: + self.handleError(GRPCError.InvalidState("Protocol violation: already received headers")) + + case .completed: + // We may receive headers from the interceptor pipeline if we have already finished (i.e. due + // to an error or otherwise) and an interceptor doing some async work later emitting headers. + // Dropping them is fine. + () + } + } + + @inlinable + internal func receiveInterceptedMessage(_ request: Request) { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("Message received before headers")) + + case let .createdContext(context): + self.state = .invokedFunction(context) + // Complete the status promise with the function outcome. + context.statusPromise.completeWith(self.userFunction(request, context)) + + case .invokedFunction: + let error = GRPCError.ProtocolViolation("Multiple messages received on server streaming RPC") + self.handleError(error) + + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + @inlinable + internal func receiveInterceptedEnd() { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("End received before headers")) + + case .createdContext: + self.handleError(GRPCError.ProtocolViolation("End received before message")) + + case .invokedFunction, .completed: + () + } + } + + // MARK: - User Function To Interceptors + + @inlinable + internal func interceptResponse( + _ response: Response, + metadata: MessageMetadata, + promise: EventLoopPromise? + ) { + switch self.state { + case .idle: + // The observer block can't send responses if it doesn't exist. + preconditionFailure() + + case .createdContext, .invokedFunction: + // The user has access to the response context before returning a future observer, + // so 'createdContext' is valid here (if a little strange). + self.interceptors.send(.message(response, metadata), promise: promise) + + case .completed: + promise?.fail(GRPCError.AlreadyComplete()) + } + } + + @inlinable + internal func userFunctionCompletedWithResult(_ result: Result) { + switch self.state { + case .idle: + // Invalid state: the user function can only completed if it was created. + preconditionFailure() + + case let .createdContext(context), + let .invokedFunction(context): + + switch result { + case let .success(status): + // We're sending end back, we're done. + self.state = .completed + self.interceptors.send(.end(status, context.trailers), promise: nil) + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + // We've already completed. Ignore this. + () + } + } + + @inlinable + internal func sendInterceptedPart( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch part { + case let .metadata(headers): + self.context.responseWriter.sendMetadata(headers, flush: true, promise: promise) + + case let .message(message, metadata): + do { + let bytes = try self.serializer.serialize(message, allocator: self.context.allocator) + self.context.responseWriter.sendMessage(bytes, metadata: metadata, promise: promise) + } catch { + // Serialization failed: fail the promise and send end. + promise?.fail(error) + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + // Loop back via the interceptors. + self.interceptors.send(.end(status, trailers), promise: nil) + } + + case let .end(status, trailers): + self.context.responseWriter.sendEnd(status: status, trailers: trailers, promise: promise) + } + } + + @inlinable + internal func handleError(_ error: Error, thrownFromHandler isHandlerError: Bool = false) { + switch self.state { + case .idle: + assert(!isHandlerError) + self.state = .completed + // We don't have a promise to fail. Just send back end. + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + self.interceptors.send(.end(status, trailers), promise: nil) + + case let .createdContext(context), + let .invokedFunction(context): + // We don't have a promise to fail. Just send back end. + self.state = .completed + + let status: GRPCStatus + let trailers: HPACKHeaders + + if isHandlerError { + (status, trailers) = ServerErrorProcessor.processObserverError( + error, + headers: context.headers, + trailers: context.trailers, + delegate: self.context.errorDelegate + ) + } else { + (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + } + + self.interceptors.send(.end(status, trailers), promise: nil) + // We're already in the 'completed' state so failing the promise will be a no-op in the + // callback to 'userFunctionCompletedWithResult' (but we also need to avoid leaking the + // promise.) + context.statusPromise.fail(error) + + case .completed: + () + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/UnaryServerHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/UnaryServerHandler.swift new file mode 100644 index 00000000..6da422ee --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallHandlers/UnaryServerHandler.swift @@ -0,0 +1,334 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +public final class UnaryServerHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +>: GRPCServerHandlerProtocol { + public typealias Request = Deserializer.Output + public typealias Response = Serializer.Input + + /// A response serializer. + @usableFromInline + internal let serializer: Serializer + + /// A request deserializer. + @usableFromInline + internal let deserializer: Deserializer + + /// A pipeline of user provided interceptors. + @usableFromInline + internal var interceptors: ServerInterceptorPipeline! + + /// The context required in order create the function. + @usableFromInline + internal let context: CallHandlerContext + + /// A reference to a `UserInfo`. + @usableFromInline + internal let userInfoRef: Ref + + /// The user provided function to execute. + @usableFromInline + internal let userFunction: (Request, StatusOnlyCallContext) -> EventLoopFuture + + /// The state of the function invocation. + @usableFromInline + internal var state: State = .idle + + @usableFromInline + internal enum State { + // Initial state. Nothing has happened yet. + case idle + // Headers have been received and now we're holding a context with which to invoke the user + // function when we receive a message. + case createdContext(UnaryResponseCallContext) + // The user function has been invoked, we're waiting for the response. + case invokedFunction(UnaryResponseCallContext) + // The function has completed or we are no longer proceeding with execution (because of an error + // or unexpected closure). + case completed + } + + @inlinable + public init( + context: CallHandlerContext, + requestDeserializer: Deserializer, + responseSerializer: Serializer, + interceptors: [ServerInterceptor], + userFunction: @escaping (Request, StatusOnlyCallContext) -> EventLoopFuture + ) { + self.userFunction = userFunction + self.serializer = responseSerializer + self.deserializer = requestDeserializer + self.context = context + + let userInfoRef = Ref(UserInfo()) + self.userInfoRef = userInfoRef + self.interceptors = ServerInterceptorPipeline( + logger: context.logger, + eventLoop: context.eventLoop, + path: context.path, + callType: .unary, + remoteAddress: context.remoteAddress, + userInfoRef: userInfoRef, + interceptors: interceptors, + onRequestPart: self.receiveInterceptedPart(_:), + onResponsePart: self.sendInterceptedPart(_:promise:) + ) + } + + // MARK: - Public API: gRPC to Interceptors + + @inlinable + public func receiveMetadata(_ metadata: HPACKHeaders) { + self.interceptors.receive(.metadata(metadata)) + } + + @inlinable + public func receiveMessage(_ bytes: ByteBuffer) { + do { + let message = try self.deserializer.deserialize(byteBuffer: bytes) + self.interceptors.receive(.message(message)) + } catch { + self.handleError(error) + } + } + + @inlinable + public func receiveEnd() { + self.interceptors.receive(.end) + } + + @inlinable + public func receiveError(_ error: Error) { + self.handleError(error) + self.finish() + } + + @inlinable + public func finish() { + switch self.state { + case .idle: + self.interceptors = nil + self.state = .completed + + case let .createdContext(context), + let .invokedFunction(context): + context.responsePromise.fail(GRPCStatus(code: .unavailable, message: nil)) + + case .completed: + self.interceptors = nil + } + } + + // MARK: - Interceptors to User Function + + @inlinable + internal func receiveInterceptedPart(_ part: GRPCServerRequestPart) { + switch part { + case let .metadata(headers): + self.receiveInterceptedMetadata(headers) + case let .message(message): + self.receiveInterceptedMessage(message) + case .end: + self.receiveInterceptedEnd() + } + } + + @inlinable + internal func receiveInterceptedMetadata(_ headers: HPACKHeaders) { + switch self.state { + case .idle: + // Make a context to invoke the user function with. + let context = UnaryResponseCallContext( + eventLoop: self.context.eventLoop, + headers: headers, + logger: self.context.logger, + userInfoRef: self.userInfoRef, + closeFuture: self.context.closeFuture + ) + + // Move to the next state. + self.state = .createdContext(context) + + // Register a callback on the response future. The user function will complete this promise. + context.responsePromise.futureResult.whenComplete(self.userFunctionCompletedWithResult(_:)) + + // Send back response headers. + self.interceptors.send(.metadata([:]), promise: nil) + + case .createdContext, .invokedFunction: + self.handleError(GRPCError.ProtocolViolation("Multiple header blocks received on RPC")) + + case .completed: + // We may receive headers from the interceptor pipeline if we have already finished (i.e. due + // to an error or otherwise) and an interceptor doing some async work later emitting headers. + // Dropping them is fine. + () + } + } + + @inlinable + internal func receiveInterceptedMessage(_ request: Request) { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("Message received before headers")) + + case let .createdContext(context): + // Happy path: execute the function; complete the promise with the result. + self.state = .invokedFunction(context) + context.responsePromise.completeWith(self.userFunction(request, context)) + + case .invokedFunction: + // The function's already been invoked with a message. + self.handleError(GRPCError.ProtocolViolation("Multiple messages received on unary RPC")) + + case .completed: + // We received a message but we're already done: this may happen if we terminate the RPC + // due to a channel error, for example. + () + } + } + + @inlinable + internal func receiveInterceptedEnd() { + switch self.state { + case .idle: + self.handleError(GRPCError.ProtocolViolation("End received before headers")) + + case .createdContext: + self.handleError(GRPCError.ProtocolViolation("End received before message")) + + case .invokedFunction, .completed: + () + } + } + + // MARK: - User Function To Interceptors + + @inlinable + internal func userFunctionCompletedWithResult(_ result: Result) { + switch self.state { + case .idle: + // Invalid state: the user function can only complete if it was executed. + preconditionFailure() + + // 'created' is allowed here: we may have to (and tear down) after receiving headers + // but before receiving a message. + case let .createdContext(context), + let .invokedFunction(context): + + switch result { + case let .success(response): + // Complete, as we're sending 'end'. + self.state = .completed + + // Compression depends on whether it's enabled on the server and the setting in the caller + // context. + let compress = self.context.encoding.isEnabled && context.compressionEnabled + let metadata = MessageMetadata(compress: compress, flush: false) + self.interceptors.send(.message(response, metadata), promise: nil) + self.interceptors.send(.end(context.responseStatus, context.trailers), promise: nil) + + case let .failure(error): + self.handleError(error, thrownFromHandler: true) + } + + case .completed: + // We've already failed. Ignore this. + () + } + } + + @inlinable + internal func sendInterceptedPart( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch part { + case let .metadata(headers): + // We can delay this flush until the end of the RPC. + self.context.responseWriter.sendMetadata(headers, flush: false, promise: promise) + + case let .message(message, metadata): + do { + let bytes = try self.serializer.serialize(message, allocator: self.context.allocator) + self.context.responseWriter.sendMessage(bytes, metadata: metadata, promise: promise) + } catch { + // Serialization failed: fail the promise and send end. + promise?.fail(error) + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + // Loop back via the interceptors. + self.interceptors.send(.end(status, trailers), promise: nil) + } + + case let .end(status, trailers): + self.context.responseWriter.sendEnd(status: status, trailers: trailers, promise: promise) + } + } + + @inlinable + internal func handleError(_ error: Error, thrownFromHandler isHandlerError: Bool = false) { + switch self.state { + case .idle: + assert(!isHandlerError) + self.state = .completed + // We don't have a promise to fail. Just send back end. + let (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + self.interceptors.send(.end(status, trailers), promise: nil) + + case let .createdContext(context), + let .invokedFunction(context): + // We don't have a promise to fail. Just send back end. + self.state = .completed + + let status: GRPCStatus + let trailers: HPACKHeaders + + if isHandlerError { + (status, trailers) = ServerErrorProcessor.processObserverError( + error, + headers: context.headers, + trailers: context.trailers, + delegate: self.context.errorDelegate + ) + } else { + (status, trailers) = ServerErrorProcessor.processLibraryError( + error, + delegate: self.context.errorDelegate + ) + } + + self.interceptors.send(.end(status, trailers), promise: nil) + // We're already in the 'completed' state so failing the promise will be a no-op in the + // callback to 'userFunctionCompletedWithResult' (but we also need to avoid leaking the + // promise.) + context.responsePromise.fail(error) + + case .completed: + () + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallOptions.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallOptions.swift new file mode 100644 index 00000000..86d55501 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/CallOptions.swift @@ -0,0 +1,220 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import struct Foundation.UUID + +#if swift(>=5.6) +@preconcurrency import Logging +@preconcurrency import NIOCore +#else +import Logging +import NIOCore +#endif // swift(>=5.6) + +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 + +/// Options to use for GRPC calls. +public struct CallOptions: GRPCSendable { + /// Additional metadata to send to the service. + public var customMetadata: HPACKHeaders + + /// The time limit for the RPC. + /// + /// - Note: timeouts are treated as deadlines as soon as an RPC has been invoked. + public var timeLimit: TimeLimit + + /// The compression used for requests, and the compression algorithms to advertise as acceptable + /// for the remote peer to use for encoding responses. + /// + /// Compression may also be disabled at the message-level for streaming requests (i.e. client + /// streaming and bidirectional streaming RPCs) by setting `compression` to `.disabled` in + /// `sendMessage(_:compression)`, `sendMessage(_:compression:promise)`, + /// `sendMessages(_:compression)` or `sendMessages(_:compression:promise)`. + /// + /// Note that enabling `compression` via the `sendMessage` or `sendMessages` methods only applies + /// if encoding has been specified in these options. + public var messageEncoding: ClientMessageEncoding + + /// Whether the call is cacheable. + public var cacheable: Bool + + /// How IDs should be provided for requests. Defaults to `.autogenerated`. + /// + /// The request ID is used for logging and will be added to the headers of a call if + /// `requestIDHeader` is specified. + /// + /// - Important: When setting `CallOptions` at the client level, `.userDefined` should __not__ be + /// used otherwise each request will have the same ID. + public var requestIDProvider: RequestIDProvider + + /// The name of the header to use when adding a request ID to a call, e.g. "x-request-id". If the + /// value is `nil` (the default) then no additional header will be added. + /// + /// Setting this value will add a request ID to the headers of the call these options are used + /// with. The request ID will be provided by `requestIDProvider` and will also be used in log + /// messages associated with the call. + public var requestIDHeader: String? + + /// A preference for the `EventLoop` that the call is executed on. + /// + /// The `EventLoop` resulting from the preference will be used to create any `EventLoopFuture`s + /// associated with the call, such as the `response` for calls with a single response (i.e. unary + /// and client streaming). For calls which stream responses (server streaming and bidirectional + /// streaming) the response handler is executed on this event loop. + /// + /// Note that the underlying connection is not guaranteed to run on the same event loop. + public var eventLoopPreference: EventLoopPreference + + /// A logger used for the call. Defaults to a no-op logger. + /// + /// If a `requestIDProvider` exists then a request ID will automatically attached to the logger's + /// metadata using the 'grpc-request-id' key. + public var logger: Logger + + public init( + customMetadata: HPACKHeaders = HPACKHeaders(), + timeLimit: TimeLimit = .none, + messageEncoding: ClientMessageEncoding = .disabled, + requestIDProvider: RequestIDProvider = .autogenerated, + requestIDHeader: String? = nil, + cacheable: Bool = false, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + ) { + self.init( + customMetadata: customMetadata, + timeLimit: timeLimit, + messageEncoding: messageEncoding, + requestIDProvider: requestIDProvider, + requestIDHeader: requestIDHeader, + eventLoopPreference: .indifferent, + cacheable: cacheable, + logger: logger + ) + } + + public init( + customMetadata: HPACKHeaders = HPACKHeaders(), + timeLimit: TimeLimit = .none, + messageEncoding: ClientMessageEncoding = .disabled, + requestIDProvider: RequestIDProvider = .autogenerated, + requestIDHeader: String? = nil, + eventLoopPreference: EventLoopPreference, + cacheable: Bool = false, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + ) { + self.customMetadata = customMetadata + self.messageEncoding = messageEncoding + self.requestIDProvider = requestIDProvider + self.requestIDHeader = requestIDHeader + self.cacheable = cacheable + self.timeLimit = timeLimit + self.logger = logger + self.eventLoopPreference = eventLoopPreference + } +} + +extension CallOptions { + public struct RequestIDProvider: GRPCSendable { + #if swift(>=5.6) + public typealias RequestIDGenerator = @Sendable () -> String + #else + public typealias RequestIDGenerator = () -> String + #endif // swift(>=5.6) + + private enum RequestIDSource: GRPCSendable { + case none + case `static`(String) + case generated(RequestIDGenerator) + } + + private var source: RequestIDSource + private init(_ source: RequestIDSource) { + self.source = source + } + + @usableFromInline + internal func requestID() -> String? { + switch self.source { + case .none: + return nil + case let .static(requestID): + return requestID + case let .generated(generator): + return generator() + } + } + + /// No request IDs are generated. + public static let none = RequestIDProvider(.none) + + /// Generate a new request ID for each RPC. + public static let autogenerated = RequestIDProvider(.generated({ UUID().uuidString })) + + /// Specify an ID to be used. + /// + /// - Important: this should only be used when `CallOptions` are passed directly to the call. + /// If it is used for the default options on a client then all calls with have the same ID. + public static func userDefined(_ requestID: String) -> RequestIDProvider { + return RequestIDProvider(.static(requestID)) + } + + /// Provide a factory to generate request IDs. + public static func generated( + _ requestIDFactory: @escaping RequestIDGenerator + ) -> RequestIDProvider { + return RequestIDProvider(.generated(requestIDFactory)) + } + } +} + +extension CallOptions { + public struct EventLoopPreference: GRPCSendable { + /// No preference. The framework will assign an `EventLoop`. + public static let indifferent = EventLoopPreference(.indifferent) + + /// Use the provided `EventLoop` for the call. + public static func exact(_ eventLoop: EventLoop) -> EventLoopPreference { + return EventLoopPreference(.exact(eventLoop)) + } + + @usableFromInline + internal enum Preference: GRPCSendable { + case indifferent + case exact(EventLoop) + } + + @usableFromInline + internal var _preference: Preference + + @inlinable + internal init(_ preference: Preference) { + self._preference = preference + } + } +} + +extension CallOptions.EventLoopPreference { + @inlinable + internal var exact: EventLoop? { + switch self._preference { + case let .exact(eventLoop): + return eventLoop + case .indifferent: + return nil + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/BidirectionalStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/BidirectionalStreamingCall.swift new file mode 100644 index 00000000..e14c8939 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/BidirectionalStreamingCall.swift @@ -0,0 +1,140 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +/// A bidirectional-streaming gRPC call. Each response is passed to the provided observer block. +/// +/// Messages should be sent via the `sendMessage` and `sendMessages` methods; the stream of messages +/// must be terminated by calling `sendEnd` to indicate the final message has been sent. +/// +/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore +/// has reference semantics. +public struct BidirectionalStreamingCall< + RequestPayload, + ResponsePayload +>: StreamingRequestClientCall { + private let call: Call + private let responseParts: StreamingResponseParts + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// The path used to make the RPC. + public var path: String { + return self.call.path + } + + /// The `Channel` used to transport messages for this RPC. + public var subchannel: EventLoopFuture { + return self.call.channel + } + + /// The `EventLoop` this call is running on. + public var eventLoop: EventLoop { + return self.call.eventLoop + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel(promise: EventLoopPromise?) { + self.call.cancel(promise: promise) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + public var initialMetadata: EventLoopFuture { + return self.responseParts.initialMetadata + } + + /// The trailing metadata returned from the server. + public var trailingMetadata: EventLoopFuture { + return self.responseParts.trailingMetadata + } + + /// The final status of the the RPC. + public var status: EventLoopFuture { + return self.responseParts.status + } + + internal init( + call: Call, + callback: @escaping (ResponsePayload) -> Void + ) { + self.call = call + self.responseParts = StreamingResponseParts(on: call.eventLoop, callback) + } + + internal func invoke() { + self.call.invokeStreamingRequests( + onStart: {}, + onError: self.responseParts.handleError(_:), + onResponsePart: self.responseParts.handle(_:) + ) + } + + // MARK: - Requests + + /// Sends a message to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or + /// `sendEnd(promise:)`. + /// + /// - Parameters: + /// - message: The message to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to fulfill with the outcome of the send operation. + public func sendMessage( + _ message: RequestPayload, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) { + let compress = self.call.compress(compression) + self.call.send(.message(message, .init(compress: compress, flush: true)), promise: promise) + } + + /// Sends a sequence of messages to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or + /// `sendEnd(promise:)`. + /// + /// - Parameters: + /// - messages: The sequence of messages to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to fulfill with the outcome of the send operation. It will only succeed + /// if all messages were written successfully. + public func sendMessages( + _ messages: S, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) where S: Sequence, S.Element == RequestPayload { + self.call.sendMessages(messages, compression: compression, promise: promise) + } + + /// Terminates a stream of messages sent to the service. + /// + /// - Important: This should only ever be called once. + /// - Parameter promise: A promise to be fulfilled when the end has been sent. + public func sendEnd(promise: EventLoopPromise?) { + self.call.send(.end, promise: promise) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/Call.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/Call.swift new file mode 100644 index 00000000..81897c2a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/Call.swift @@ -0,0 +1,446 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 +import protocol SwiftProtobuf.Message + +/// An object representing a single RPC from the perspective of a client. It allows the caller to +/// send request parts, request a cancellation, and receive response parts in a provided callback. +/// +/// The call object sits atop an interceptor pipeline (see `ClientInterceptor`) which allows for +/// request and response streams to be arbitrarily transformed or observed. Requests sent via this +/// call will traverse the pipeline before reaching the network, and responses received will +/// traverse the pipeline having been received from the network. +/// +/// This object is a lower-level API than the equivalent wrapped calls (such as `UnaryCall` and +/// `BidirectionalStreamingCall`). The caller is therefore required to do more in order to use this +/// object correctly. Callers must call `invoke(_:)` to start the call and ensure that the correct +/// number of request parts are sent in the correct order (exactly one `metadata`, followed +/// by at most one `message` for unary and server streaming calls, and any number of `message` parts +/// for client streaming and bidirectional streaming calls. All call types must terminate their +/// request stream by sending one `end` message. +/// +/// Callers are not able to create `Call` objects directly, rather they must be created via an +/// object conforming to `GRPCChannel` such as `ClientConnection`. +public final class Call { + @usableFromInline + internal enum State { + /// Idle, waiting to be invoked. + case idle(ClientTransportFactory) + + /// Invoked, we have a transport on which to send requests. The transport may be closed if the + /// RPC has already completed. + case invoked(ClientTransport) + } + + /// The current state of the call. + @usableFromInline + internal var _state: State + + /// User provided interceptors for the call. + @usableFromInline + internal let _interceptors: [ClientInterceptor] + + /// Whether compression is enabled on the call. + private var isCompressionEnabled: Bool { + return self.options.messageEncoding.enabledForRequests + } + + /// The `EventLoop` the call is being invoked on. + public let eventLoop: EventLoop + + /// The path of the RPC, usually generated from a service definition, e.g. "/echo.Echo/Get". + public let path: String + + /// The type of the RPC, e.g. unary, bidirectional streaming. + public let type: GRPCCallType + + /// Options used to invoke the call. + public let options: CallOptions + + /// A promise for the underlying `Channel`. We only allocate this if the user asks for + /// the `Channel` and we haven't invoked the transport yet. It's a bit unfortunate. + private var channelPromise: EventLoopPromise? + + /// Returns a future for the underlying `Channel`. + internal var channel: EventLoopFuture { + if self.eventLoop.inEventLoop { + return self._channel() + } else { + return self.eventLoop.flatSubmit { + return self._channel() + } + } + } + + // Calls can't be constructed directly: users must make them using a `GRPCChannel`. + @inlinable + internal init( + path: String, + type: GRPCCallType, + eventLoop: EventLoop, + options: CallOptions, + interceptors: [ClientInterceptor], + transportFactory: ClientTransportFactory + ) { + self.path = path + self.type = type + self.options = options + self._state = .idle(transportFactory) + self.eventLoop = eventLoop + self._interceptors = interceptors + } + + /// Starts the call and provides a callback which is invoked on every response part received from + /// the server. + /// + /// This must be called prior to `send(_:promise:)` or `cancel(promise:)`. + /// + /// - Parameters: + /// - onError: A callback invoked when an error is received. + /// - onResponsePart: A callback which is invoked on every response part. + /// - Important: This function should only be called once. Subsequent calls will be ignored. + @inlinable + public func invoke( + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.options.logger.debug("starting rpc", metadata: ["path": "\(self.path)"], source: "GRPC") + + if self.eventLoop.inEventLoop { + self._invoke(onStart: {}, onError: onError, onResponsePart: onResponsePart) + } else { + self.eventLoop.execute { + self._invoke(onStart: {}, onError: onError, onResponsePart: onResponsePart) + } + } + } + + /// Send a request part on the RPC. + /// - Parameters: + /// - part: The request part to send. + /// - promise: A promise which will be completed when the request part has been handled. + /// - Note: Sending will always fail if `invoke(_:)` has not been called. + @inlinable + public func send(_ part: GRPCClientRequestPart, promise: EventLoopPromise?) { + if self.eventLoop.inEventLoop { + self._send(part, promise: promise) + } else { + self.eventLoop.execute { + self._send(part, promise: promise) + } + } + } + + /// Attempt to cancel the RPC. + /// - Parameter promise: A promise which will be completed once the cancellation request has been + /// dealt with. + /// - Note: Cancellation will always fail if `invoke(_:)` has not been called. + public func cancel(promise: EventLoopPromise?) { + if self.eventLoop.inEventLoop { + self._cancel(promise: promise) + } else { + self.eventLoop.execute { + self._cancel(promise: promise) + } + } + } +} + +extension Call { + /// Send a request part on the RPC. + /// - Parameter part: The request part to send. + /// - Returns: A future which will be resolved when the request has been handled. + /// - Note: Sending will always fail if `invoke(_:)` has not been called. + @inlinable + public func send(_ part: GRPCClientRequestPart) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.send(part, promise: promise) + return promise.futureResult + } + + /// Attempt to cancel the RPC. + /// - Note: Cancellation will always fail if `invoke(_:)` has not been called. + /// - Returns: A future which will be resolved when the cancellation request has been cancelled. + public func cancel() -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.cancel(promise: promise) + return promise.futureResult + } +} + +extension Call { + internal func compress(_ compression: Compression) -> Bool { + return compression.isEnabled(callDefault: self.isCompressionEnabled) + } + + internal func sendMessages( + _ messages: Messages, + compression: Compression, + promise: EventLoopPromise? + ) where Messages: Sequence, Messages.Element == Request { + if self.eventLoop.inEventLoop { + if let promise = promise { + self._sendMessages(messages, compression: compression, promise: promise) + } else { + self._sendMessages(messages, compression: compression) + } + } else { + self.eventLoop.execute { + if let promise = promise { + self._sendMessages(messages, compression: compression, promise: promise) + } else { + self._sendMessages(messages, compression: compression) + } + } + } + } + + // Provide a few convenience methods we need from the wrapped call objects. + private func _sendMessages( + _ messages: Messages, + compression: Compression + ) where Messages: Sequence, Messages.Element == Request { + self.eventLoop.assertInEventLoop() + let compress = self.compress(compression) + + var iterator = messages.makeIterator() + var maybeNext = iterator.next() + while let current = maybeNext { + let next = iterator.next() + // If there's no next message, then we'll flush. + let flush = next == nil + self._send(.message(current, .init(compress: compress, flush: flush)), promise: nil) + maybeNext = next + } + } + + private func _sendMessages( + _ messages: Messages, + compression: Compression, + promise: EventLoopPromise + ) where Messages: Sequence, Messages.Element == Request { + self.eventLoop.assertInEventLoop() + let compress = self.compress(compression) + + var iterator = messages.makeIterator() + var maybeNext = iterator.next() + while let current = maybeNext { + let next = iterator.next() + let isLast = next == nil + + // We're already on the event loop, use the `_` send. + if isLast { + // Only flush and attach the promise to the last message. + self._send(.message(current, .init(compress: compress, flush: true)), promise: promise) + } else { + self._send(.message(current, .init(compress: compress, flush: false)), promise: nil) + } + + maybeNext = next + } + } +} + +extension Call { + /// Invoke the RPC with this response part handler. + /// - Important: This *must* to be called from the `eventLoop`. + @usableFromInline + internal func _invoke( + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.eventLoop.assertInEventLoop() + + switch self._state { + case let .idle(factory): + let transport = factory.makeConfiguredTransport( + to: self.path, + for: self.type, + withOptions: self.options, + onEventLoop: self.eventLoop, + interceptedBy: self._interceptors, + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + self._state = .invoked(transport) + + case .invoked: + // We can't be invoked twice. Just ignore this. + () + } + } + + /// Send a request part on the transport. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func _send(_ part: GRPCClientRequestPart, promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + switch self._state { + case .idle: + promise?.fail(GRPCError.InvalidState("Call must be invoked before sending request parts")) + + case let .invoked(transport): + transport.send(part, promise: promise) + } + } + + /// Attempt to cancel the call. + /// - Important: This *must* to be called from the `eventLoop`. + private func _cancel(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + + switch self._state { + case .idle: + promise?.succeed(()) + self.channelPromise?.fail(GRPCStatus(code: .cancelled)) + + case let .invoked(transport): + transport.cancel(promise: promise) + } + } + + /// Get the underlying `Channel` for this call. + /// - Important: This *must* to be called from the `eventLoop`. + private func _channel() -> EventLoopFuture { + self.eventLoop.assertInEventLoop() + + switch (self.channelPromise, self._state) { + case let (.some(promise), .idle), + let (.some(promise), .invoked): + // We already have a promise, just use that. + return promise.futureResult + + case (.none, .idle): + // We need to allocate a promise and ask the transport for the channel later. + let promise = self.eventLoop.makePromise(of: Channel.self) + self.channelPromise = promise + return promise.futureResult + + case let (.none, .invoked(transport)): + // Just ask the transport. + return transport.getChannel() + } + } +} + +extension Call { + // These helpers are for our wrapping call objects (`UnaryCall`, etc.). + + /// Invokes the call and sends a single request. Sends the metadata, request and closes the + /// request stream. + /// - Parameters: + /// - request: The request to send. + /// - onError: A callback invoked when an error is received. + /// - onResponsePart: A callback invoked for each response part received. + @inlinable + internal func invokeUnaryRequest( + _ request: Request, + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + if self.eventLoop.inEventLoop { + self._invokeUnaryRequest( + request: request, + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + } else { + self.eventLoop.execute { + self._invokeUnaryRequest( + request: request, + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + } + } + } + + /// Invokes the call for streaming requests and sends the initial call metadata. Callers can send + /// additional messages and end the stream by calling `send(_:promise:)`. + /// - Parameters: + /// - onError: A callback invoked when an error is received. + /// - onResponsePart: A callback invoked for each response part received. + @inlinable + internal func invokeStreamingRequests( + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + if self.eventLoop.inEventLoop { + self._invokeStreamingRequests( + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + } else { + self.eventLoop.execute { + self._invokeStreamingRequests( + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + } + } + } + + /// On-`EventLoop` implementation of `invokeUnaryRequest(request:_:)`. + @usableFromInline + internal func _invokeUnaryRequest( + request: Request, + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.eventLoop.assertInEventLoop() + assert(self.type == .unary || self.type == .serverStreaming) + + self._invoke(onStart: onStart, onError: onError, onResponsePart: onResponsePart) + self._send(.metadata(self.options.customMetadata), promise: nil) + self._send( + .message(request, .init(compress: self.isCompressionEnabled, flush: false)), + promise: nil + ) + self._send(.end, promise: nil) + } + + /// On-`EventLoop` implementation of `invokeStreamingRequests(_:)`. + @usableFromInline + internal func _invokeStreamingRequests( + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.eventLoop.assertInEventLoop() + assert(self.type == .clientStreaming || self.type == .bidirectionalStreaming) + + self._invoke(onStart: onStart, onError: onError, onResponsePart: onResponsePart) + self._send(.metadata(self.options.customMetadata), promise: nil) + } +} + +#if compiler(>=5.6) +// @unchecked is ok: all mutable state is accessed/modified from the appropriate event loop. +extension Call: @unchecked Sendable where Request: Sendable, Response: Sendable {} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/CallDetails.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/CallDetails.swift new file mode 100644 index 00000000..53df0259 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/CallDetails.swift @@ -0,0 +1,34 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@usableFromInline +internal struct CallDetails { + /// The type of the RPC, e.g. unary. + internal var type: GRPCCallType + + /// The path of the RPC used for the ":path" pseudo header, e.g. "/echo.Echo/Get" + internal var path: String + + /// The host, used for the ":authority" pseudo header. + internal var authority: String + + /// Value used for the ":scheme" pseudo header, e.g. "https". + internal var scheme: String + + /// Call options provided by the user. + @usableFromInline + internal var options: CallOptions +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientCall.swift new file mode 100644 index 00000000..2ec01b75 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientCall.swift @@ -0,0 +1,171 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 +import SwiftProtobuf + +/// Base protocol for a client call to a gRPC service. +public protocol ClientCall { + /// The type of the request message for the call. + associatedtype RequestPayload + /// The type of the response message for the call. + associatedtype ResponsePayload + + /// The event loop this call is running on. + var eventLoop: EventLoop { get } + + /// The options used to make the RPC. + var options: CallOptions { get } + + /// HTTP/2 stream that requests and responses are sent and received on. + var subchannel: EventLoopFuture { get } + + /// Initial response metadata. + var initialMetadata: EventLoopFuture { get } + + /// Status of this call which may be populated by the server or client. + /// + /// The client may populate the status if, for example, it was not possible to connect to the service. + /// + /// Note: despite `GRPCStatus` conforming to `Error`, the value will be __always__ delivered as a __success__ + /// result even if the status represents a __negative__ outcome. This future will __never__ be fulfilled + /// with an error. + var status: EventLoopFuture { get } + + /// Trailing response metadata. + var trailingMetadata: EventLoopFuture { get } + + /// Cancel the current call. + /// + /// Closes the HTTP/2 stream once it becomes available. Additional writes to the channel will be ignored. + /// Any unfulfilled promises will be failed with a cancelled status (excepting `status` which will be + /// succeeded, if not already succeeded). + func cancel(promise: EventLoopPromise?) +} + +extension ClientCall { + func cancel() -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.cancel(promise: promise) + return promise.futureResult + } +} + +/// A `ClientCall` with request streaming; i.e. client-streaming and bidirectional-streaming. +public protocol StreamingRequestClientCall: ClientCall { + /// Sends a message to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or `sendEnd(promise:)`. + /// + /// - Parameters: + /// - message: The message to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - Returns: A future which will be fullfilled when the message has been sent. + func sendMessage(_ message: RequestPayload, compression: Compression) -> EventLoopFuture + + /// Sends a message to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or `sendEnd(promise:)`. + /// + /// - Parameters: + /// - message: The message to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to be fulfilled when the message has been sent. + func sendMessage( + _ message: RequestPayload, + compression: Compression, + promise: EventLoopPromise? + ) + + /// Sends a sequence of messages to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or `sendEnd(promise:)`. + /// + /// - Parameters: + /// - messages: The sequence of messages to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + func sendMessages(_ messages: S, compression: Compression) -> EventLoopFuture + where S.Element == RequestPayload + + /// Sends a sequence of messages to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or `sendEnd(promise:)`. + /// + /// - Parameters: + /// - messages: The sequence of messages to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to be fulfilled when all messages have been sent successfully. + func sendMessages( + _ messages: S, + compression: Compression, + promise: EventLoopPromise? + ) where S.Element == RequestPayload + + /// Terminates a stream of messages sent to the service. + /// + /// - Important: This should only ever be called once. + /// - Returns: A future which will be fulfilled when the end has been sent. + func sendEnd() -> EventLoopFuture + + /// Terminates a stream of messages sent to the service. + /// + /// - Important: This should only ever be called once. + /// - Parameter promise: A promise to be fulfilled when the end has been sent. + func sendEnd(promise: EventLoopPromise?) +} + +extension StreamingRequestClientCall { + public func sendMessage( + _ message: RequestPayload, + compression: Compression = .deferToCallDefault + ) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.sendMessage(message, compression: compression, promise: promise) + return promise.futureResult + } + + public func sendMessages( + _ messages: S, + compression: Compression = .deferToCallDefault + ) -> EventLoopFuture + where S.Element == RequestPayload { + let promise = self.eventLoop.makePromise(of: Void.self) + self.sendMessages(messages, compression: compression, promise: promise) + return promise.futureResult + } + + public func sendEnd() -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.sendEnd(promise: promise) + return promise.futureResult + } +} + +/// A `ClientCall` with a unary response; i.e. unary and client-streaming. +public protocol UnaryResponseClientCall: ClientCall { + /// The response message returned from the service if the call is successful. This may be failed + /// if the call encounters an error. + /// + /// Callers should rely on the `status` of the call for the canonical outcome. + var response: EventLoopFuture { get } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientStreamingCall.swift new file mode 100644 index 00000000..03bd534c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ClientStreamingCall.swift @@ -0,0 +1,140 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +/// A client-streaming gRPC call. +/// +/// Messages should be sent via the `sendMessage` and `sendMessages` methods; the stream of messages +/// must be terminated by calling `sendEnd` to indicate the final message has been sent. +/// +/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore +/// has reference semantics. +public struct ClientStreamingCall: StreamingRequestClientCall, + UnaryResponseClientCall { + private let call: Call + private let responseParts: UnaryResponseParts + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// The path used to make the RPC. + public var path: String { + return self.call.path + } + + /// The `Channel` used to transport messages for this RPC. + public var subchannel: EventLoopFuture { + return self.call.channel + } + + /// The `EventLoop` this call is running on. + public var eventLoop: EventLoop { + return self.call.eventLoop + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel(promise: EventLoopPromise?) { + self.call.cancel(promise: promise) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + public var initialMetadata: EventLoopFuture { + return self.responseParts.initialMetadata + } + + /// The response returned by the server. + public var response: EventLoopFuture { + return self.responseParts.response + } + + /// The trailing metadata returned from the server. + public var trailingMetadata: EventLoopFuture { + return self.responseParts.trailingMetadata + } + + /// The final status of the the RPC. + public var status: EventLoopFuture { + return self.responseParts.status + } + + internal init(call: Call) { + self.call = call + self.responseParts = UnaryResponseParts(on: call.eventLoop) + } + + internal func invoke() { + self.call.invokeStreamingRequests( + onStart: {}, + onError: self.responseParts.handleError(_:), + onResponsePart: self.responseParts.handle(_:) + ) + } + + // MARK: - Request + + /// Sends a message to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or + /// `sendEnd(promise:)`. + /// + /// - Parameters: + /// - message: The message to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to fulfill with the outcome of the send operation. + public func sendMessage( + _ message: RequestPayload, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) { + let compress = self.call.compress(compression) + self.call.send(.message(message, .init(compress: compress, flush: true)), promise: promise) + } + + /// Sends a sequence of messages to the service. + /// + /// - Important: Callers must terminate the stream of messages by calling `sendEnd()` or + /// `sendEnd(promise:)`. + /// + /// - Parameters: + /// - messages: The sequence of messages to send. + /// - compression: Whether compression should be used for this message. Ignored if compression + /// was not enabled for the RPC. + /// - promise: A promise to fulfill with the outcome of the send operation. It will only succeed + /// if all messages were written successfully. + public func sendMessages( + _ messages: S, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) where S: Sequence, S.Element == RequestPayload { + self.call.sendMessages(messages, compression: compression, promise: promise) + } + + /// Terminates a stream of messages sent to the service. + /// + /// - Important: This should only ever be called once. + /// - Parameter promise: A promise to be fulfilled when the end has been sent. + public func sendEnd(promise: EventLoopPromise?) { + self.call.send(.end, promise: promise) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/LazyEventLoopPromise.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/LazyEventLoopPromise.swift new file mode 100644 index 00000000..6abbac63 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/LazyEventLoopPromise.swift @@ -0,0 +1,108 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOConcurrencyHelpers +import NIOCore + +extension EventLoop { + internal func makeLazyPromise(of: Value.Type = Value.self) -> LazyEventLoopPromise { + return LazyEventLoopPromise(on: self) + } +} + +/// A `LazyEventLoopPromise` is similar to an `EventLoopPromise` except that the underlying +/// `EventLoopPromise` promise is only created if it is required. That is, when the future result +/// has been requested and the promise has not yet been completed. +/// +/// Note that all methods **must** be called from its `eventLoop`. +internal struct LazyEventLoopPromise { + private enum State { + // No future has been requested, no result has been delivered. + case idle + + // No future has been requested, but this result have been delivered. + case resolvedResult(Result) + + // A future has been request; the promise may or may not contain a result. + case unresolvedPromise(EventLoopPromise) + + // A future was requested, it's also been resolved. + case resolvedFuture(EventLoopFuture) + } + + private var state: State + private let eventLoop: EventLoop + + fileprivate init(on eventLoop: EventLoop) { + self.state = .idle + self.eventLoop = eventLoop + } + + /// Get the future result of this promise. + internal mutating func getFutureResult() -> EventLoopFuture { + self.eventLoop.preconditionInEventLoop() + + switch self.state { + case .idle: + let promise = self.eventLoop.makePromise(of: Value.self) + self.state = .unresolvedPromise(promise) + return promise.futureResult + + case let .resolvedResult(result): + let future: EventLoopFuture + switch result { + case let .success(value): + future = self.eventLoop.makeSucceededFuture(value) + case let .failure(error): + future = self.eventLoop.makeFailedFuture(error) + } + self.state = .resolvedFuture(future) + return future + + case let .unresolvedPromise(promise): + return promise.futureResult + + case let .resolvedFuture(future): + return future + } + } + + /// Succeed the promise with the given value. + internal mutating func succeed(_ value: Value) { + self.completeWith(.success(value)) + } + + /// Fail the promise with the given error. + internal mutating func fail(_ error: Error) { + self.completeWith(.failure(error)) + } + + /// Complete the promise with the given result. + internal mutating func completeWith(_ result: Result) { + self.eventLoop.preconditionInEventLoop() + + switch self.state { + case .idle: + self.state = .resolvedResult(result) + + case let .unresolvedPromise(promise): + promise.completeWith(result) + self.state = .resolvedFuture(promise.futureResult) + + case .resolvedResult, .resolvedFuture: + () + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponseContainers.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponseContainers.swift new file mode 100644 index 00000000..9169a8a5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponseContainers.swift @@ -0,0 +1,208 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +/// A bucket of promises for a unary-response RPC. +internal class UnaryResponseParts { + /// The `EventLoop` we expect to receive these response parts on. + private let eventLoop: EventLoop + + /// A promise for the `Response` message. + private let responsePromise: EventLoopPromise + + /// Lazy promises for the status, initial-, and trailing-metadata. + private var initialMetadataPromise: LazyEventLoopPromise + private var trailingMetadataPromise: LazyEventLoopPromise + private var statusPromise: LazyEventLoopPromise + + internal var response: EventLoopFuture { + return self.responsePromise.futureResult + } + + internal var initialMetadata: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.initialMetadataPromise.getFutureResult() + } + } + + internal var trailingMetadata: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.trailingMetadataPromise.getFutureResult() + } + } + + internal var status: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.statusPromise.getFutureResult() + } + } + + internal init(on eventLoop: EventLoop) { + self.eventLoop = eventLoop + self.responsePromise = eventLoop.makePromise() + self.initialMetadataPromise = eventLoop.makeLazyPromise() + self.trailingMetadataPromise = eventLoop.makeLazyPromise() + self.statusPromise = eventLoop.makeLazyPromise() + } + + /// Handle the response part, completing any promises as necessary. + /// - Important: This *must* be called on `eventLoop`. + internal func handle(_ part: GRPCClientResponsePart) { + self.eventLoop.assertInEventLoop() + + switch part { + case let .metadata(metadata): + self.initialMetadataPromise.succeed(metadata) + + case let .message(response): + self.responsePromise.succeed(response) + + case let .end(status, trailers): + // In case of a "Trailers-Only" RPC (i.e. just the trailers and status), fail the initial + // metadata and status. + self.initialMetadataPromise.fail(status) + self.responsePromise.fail(status) + + self.trailingMetadataPromise.succeed(trailers) + self.statusPromise.succeed(status) + } + } + + internal func handleError(_ error: Error) { + let withoutContext = error.removingContext() + let status = withoutContext.makeGRPCStatus() + self.initialMetadataPromise.fail(withoutContext) + self.responsePromise.fail(withoutContext) + self.trailingMetadataPromise.fail(withoutContext) + self.statusPromise.succeed(status) + } +} + +/// A bucket of promises for a streaming-response RPC. +internal class StreamingResponseParts { + /// The `EventLoop` we expect to receive these response parts on. + private let eventLoop: EventLoop + + /// A callback for response messages. + private var responseCallback: Optional<(Response) -> Void> + + /// Lazy promises for the status, initial-, and trailing-metadata. + private var initialMetadataPromise: LazyEventLoopPromise + private var trailingMetadataPromise: LazyEventLoopPromise + private var statusPromise: LazyEventLoopPromise + + internal var initialMetadata: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.initialMetadataPromise.getFutureResult() + } + } + + internal var trailingMetadata: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.trailingMetadataPromise.getFutureResult() + } + } + + internal var status: EventLoopFuture { + return self.eventLoop.executeOrFlatSubmit { + return self.statusPromise.getFutureResult() + } + } + + internal init(on eventLoop: EventLoop, _ responseCallback: @escaping (Response) -> Void) { + self.eventLoop = eventLoop + self.responseCallback = responseCallback + self.initialMetadataPromise = eventLoop.makeLazyPromise() + self.trailingMetadataPromise = eventLoop.makeLazyPromise() + self.statusPromise = eventLoop.makeLazyPromise() + } + + internal func handle(_ part: GRPCClientResponsePart) { + self.eventLoop.assertInEventLoop() + + switch part { + case let .metadata(metadata): + self.initialMetadataPromise.succeed(metadata) + + case let .message(response): + self.responseCallback?(response) + + case let .end(status, trailers): + // Once the stream has finished, we must release the callback, to make sure don't + // break potential retain cycles (the callback may reference other object's that in + // turn reference `StreamingResponseParts`). + self.responseCallback = nil + self.initialMetadataPromise.fail(status) + self.trailingMetadataPromise.succeed(trailers) + self.statusPromise.succeed(status) + } + } + + internal func handleError(_ error: Error) { + self.eventLoop.assertInEventLoop() + + // Once the stream has finished, we must release the callback, to make sure don't + // break potential retain cycles (the callback may reference other object's that in + // turn reference `StreamingResponseParts`). + self.responseCallback = nil + let withoutContext = error.removingContext() + let status = withoutContext.makeGRPCStatus() + self.initialMetadataPromise.fail(withoutContext) + self.trailingMetadataPromise.fail(withoutContext) + self.statusPromise.succeed(status) + } +} + +extension EventLoop { + fileprivate func executeOrFlatSubmit( + _ body: @escaping () -> EventLoopFuture + ) -> EventLoopFuture { + if self.inEventLoop { + return body() + } else { + return self.flatSubmit { + return body() + } + } + } +} + +extension Error { + fileprivate func removingContext() -> Error { + if let withContext = self as? GRPCError.WithContext { + return withContext.error + } else { + return self + } + } + + fileprivate func makeGRPCStatus() -> GRPCStatus { + if let withContext = self as? GRPCError.WithContext { + return withContext.error.makeGRPCStatus() + } else if let transformable = self as? GRPCStatusTransformable { + return transformable.makeGRPCStatus() + } else { + return GRPCStatus(code: .unknown, message: String(describing: self)) + } + } +} + +#if compiler(>=5.6) +// @unchecked is ok: all mutable state is accessed/modified from an appropriate event loop. +extension UnaryResponseParts: @unchecked Sendable where Response: Sendable {} +extension StreamingResponseParts: @unchecked Sendable where Response: Sendable {} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponsePartContainer.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponsePartContainer.swift new file mode 100644 index 00000000..9014a601 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ResponsePartContainer.swift @@ -0,0 +1,69 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHPACK + +/// A container for RPC response parts. +internal struct ResponsePartContainer { + /// The type of handler for response message part. + enum ResponseHandler { + case unary(EventLoopPromise) + case stream((Response) -> Void) + } + + var lazyInitialMetadataPromise: LazyEventLoopPromise + + /// A handler for response messages. + let responseHandler: ResponseHandler + + /// A promise for the trailing metadata. + var lazyTrailingMetadataPromise: LazyEventLoopPromise + + /// A promise for the call status. + var lazyStatusPromise: LazyEventLoopPromise + + /// Fail all promises - except for the status promise - with the given error status. Succeed the + /// status promise. + mutating func fail(with error: Error, status: GRPCStatus) { + self.lazyInitialMetadataPromise.fail(error) + + switch self.responseHandler { + case let .unary(response): + response.fail(error) + case .stream: + () + } + self.lazyTrailingMetadataPromise.fail(error) + // We always succeed the status. + self.lazyStatusPromise.succeed(status) + } + + /// Make a response container for a unary response. + init(eventLoop: EventLoop, unaryResponsePromise: EventLoopPromise) { + self.lazyInitialMetadataPromise = eventLoop.makeLazyPromise() + self.lazyTrailingMetadataPromise = eventLoop.makeLazyPromise() + self.lazyStatusPromise = eventLoop.makeLazyPromise() + self.responseHandler = .unary(unaryResponsePromise) + } + + /// Make a response container for a response which is streamed. + init(eventLoop: EventLoop, streamingResponseHandler: @escaping (Response) -> Void) { + self.lazyInitialMetadataPromise = eventLoop.makeLazyPromise() + self.lazyTrailingMetadataPromise = eventLoop.makeLazyPromise() + self.lazyStatusPromise = eventLoop.makeLazyPromise() + self.responseHandler = .stream(streamingResponseHandler) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ServerStreamingCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ServerStreamingCall.swift new file mode 100644 index 00000000..67b93226 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/ServerStreamingCall.swift @@ -0,0 +1,88 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +/// A server-streaming gRPC call. The request is sent on initialization, each response is passed to +/// the provided observer block. +/// +/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore +/// has reference semantics. +public struct ServerStreamingCall: ClientCall { + private let call: Call + private let responseParts: StreamingResponseParts + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// The path used to make the RPC. + public var path: String { + return self.call.path + } + + /// The `Channel` used to transport messages for this RPC. + public var subchannel: EventLoopFuture { + return self.call.channel + } + + /// The `EventLoop` this call is running on. + public var eventLoop: EventLoop { + return self.call.eventLoop + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel(promise: EventLoopPromise?) { + self.call.cancel(promise: promise) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + public var initialMetadata: EventLoopFuture { + return self.responseParts.initialMetadata + } + + /// The trailing metadata returned from the server. + public var trailingMetadata: EventLoopFuture { + return self.responseParts.trailingMetadata + } + + /// The final status of the the RPC. + public var status: EventLoopFuture { + return self.responseParts.status + } + + internal init( + call: Call, + callback: @escaping (ResponsePayload) -> Void + ) { + self.call = call + self.responseParts = StreamingResponseParts(on: call.eventLoop, callback) + } + + internal func invoke(_ request: RequestPayload) { + self.call.invokeUnaryRequest( + request, + onStart: {}, + onError: self.responseParts.handleError(_:), + onResponsePart: self.responseParts.handle(_:) + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/UnaryCall.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/UnaryCall.swift new file mode 100644 index 00000000..5cb7a712 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientCalls/UnaryCall.swift @@ -0,0 +1,92 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 +import SwiftProtobuf + +/// A unary gRPC call. The request is sent on initialization. +/// +/// Note: while this object is a `struct`, its implementation delegates to `Call`. It therefore +/// has reference semantics. +public struct UnaryCall: UnaryResponseClientCall { + private let call: Call + private let responseParts: UnaryResponseParts + + /// The options used to make the RPC. + public var options: CallOptions { + return self.call.options + } + + /// The path used to make the RPC. + public var path: String { + return self.call.path + } + + /// The `Channel` used to transport messages for this RPC. + public var subchannel: EventLoopFuture { + return self.call.channel + } + + /// The `EventLoop` this call is running on. + public var eventLoop: EventLoop { + return self.call.eventLoop + } + + /// Cancel this RPC if it hasn't already completed. + public func cancel(promise: EventLoopPromise?) { + self.call.cancel(promise: promise) + } + + // MARK: - Response Parts + + /// The initial metadata returned from the server. + public var initialMetadata: EventLoopFuture { + return self.responseParts.initialMetadata + } + + /// The response returned by the server. + public var response: EventLoopFuture { + return self.responseParts.response + } + + /// The trailing metadata returned from the server. + public var trailingMetadata: EventLoopFuture { + return self.responseParts.trailingMetadata + } + + /// The final status of the the RPC. + public var status: EventLoopFuture { + return self.responseParts.status + } + + internal init(call: Call) { + self.call = call + self.responseParts = UnaryResponseParts(on: call.eventLoop) + } + + internal func invoke(_ request: RequestPayload) { + self.call.invokeUnaryRequest( + request, + onStart: {}, + onError: self.responseParts.handleError(_:), + onResponsePart: self.responseParts.handle(_:) + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnection.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnection.swift new file mode 100644 index 00000000..a376a46d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnection.swift @@ -0,0 +1,671 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if swift(>=5.6) +@preconcurrency import Foundation +@preconcurrency import Logging +@preconcurrency import NIOCore +#else +import Foundation +import Logging +import NIOCore +#endif // swift(>=5.6) + +import NIOHPACK +import NIOHTTP2 +#if canImport(NIOSSL) +import NIOSSL +#endif +import NIOTLS +import NIOTransportServices +import SwiftProtobuf + +/// Provides a single, managed connection to a server which is guaranteed to always use the same +/// `EventLoop`. +/// +/// The connection to the server is provided by a single channel which will attempt to reconnect to +/// the server if the connection is dropped. When either the client or server detects that the +/// connection has become idle -- that is, there are no outstanding RPCs and the idle timeout has +/// passed (5 minutes, by default) -- the underlying channel will be closed. The client will not +/// idle the connection if any RPC exists, even if there has been no activity on the RPC for the +/// idle timeout. Long-lived, low activity RPCs may benefit from configuring keepalive (see +/// `ClientConnectionKeepalive`) which periodically pings the server to ensure that the connection +/// is not dropped. If the connection is idle a new channel will be created on-demand when the next +/// RPC is made. +/// +/// The state of the connection can be observed using a `ConnectivityStateDelegate`. +/// +/// Since the connection is managed, and may potentially spend long periods of time waiting for a +/// connection to come up (cellular connections, for example), different behaviors may be used when +/// starting a call. The different behaviors are detailed in the `CallStartBehavior` documentation. +/// +/// ### Channel Pipeline +/// +/// The `NIO.ChannelPipeline` for the connection is configured as such: +/// +/// ┌──────────────────────────┐ +/// │ DelegatingErrorHandler │ +/// └──────────▲───────────────┘ +/// HTTP2Frame│ +/// │ ⠇ ⠇ ⠇ ⠇ +/// │ ┌┴─▼┐ ┌┴─▼┐ +/// │ │ | │ | HTTP/2 streams +/// │ └▲─┬┘ └▲─┬┘ +/// │ │ │ │ │ HTTP2Frame +/// ┌─┴────────────────┴─▼───┴─▼┐ +/// │ HTTP2StreamMultiplexer | +/// └─▲───────────────────────┬─┘ +/// HTTP2Frame│ │HTTP2Frame +/// ┌─┴───────────────────────▼─┐ +/// │ GRPCIdleHandler │ +/// └─▲───────────────────────┬─┘ +/// HTTP2Frame│ │HTTP2Frame +/// ┌─┴───────────────────────▼─┐ +/// │ NIOHTTP2Handler │ +/// └─▲───────────────────────┬─┘ +/// ByteBuffer│ │ByteBuffer +/// ┌─┴───────────────────────▼─┐ +/// │ NIOSSLHandler │ +/// └─▲───────────────────────┬─┘ +/// ByteBuffer│ │ByteBuffer +/// │ ▼ +/// +/// The 'GRPCIdleHandler' intercepts HTTP/2 frames and various events and is responsible for +/// informing and controlling the state of the connection (idling and keepalive). The HTTP/2 streams +/// are used to handle individual RPCs. +public final class ClientConnection: GRPCSendable { + private let connectionManager: ConnectionManager + + /// HTTP multiplexer from the underlying channel handling gRPC calls. + internal func getMultiplexer() -> EventLoopFuture { + return self.connectionManager.getHTTP2Multiplexer() + } + + /// The configuration for this client. + internal let configuration: Configuration + + /// The scheme of the URI for each RPC, i.e. 'http' or 'https'. + internal let scheme: String + + /// The authority of the URI for each RPC. + internal let authority: String + + /// A monitor for the connectivity state. + public let connectivity: ConnectivityStateMonitor + + /// The `EventLoop` this connection is using. + public var eventLoop: EventLoop { + return self.connectionManager.eventLoop + } + + /// Creates a new connection from the given configuration. Prefer using + /// `ClientConnection.secure(group:)` to build a connection secured with TLS or + /// `ClientConnection.insecure(group:)` to build a plaintext connection. + /// + /// - Important: Users should prefer using `ClientConnection.secure(group:)` to build a connection + /// with TLS, or `ClientConnection.insecure(group:)` to build a connection without TLS. + public init(configuration: Configuration) { + self.configuration = configuration + self.scheme = configuration.tlsConfiguration == nil ? "http" : "https" + self.authority = configuration.tlsConfiguration?.hostnameOverride ?? configuration.target.host + + let monitor = ConnectivityStateMonitor( + delegate: configuration.connectivityStateDelegate, + queue: configuration.connectivityStateDelegateQueue + ) + + self.connectivity = monitor + self.connectionManager = ConnectionManager( + configuration: configuration, + connectivityDelegate: monitor, + logger: configuration.backgroundActivityLogger + ) + } + + /// Close the channel, and any connections associated with it. Any ongoing RPCs may fail. + /// + /// - Returns: Returns a future which will be resolved when shutdown has completed. + public func close() -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.close(promise: promise) + return promise.futureResult + } + + /// Close the channel, and any connections associated with it. Any ongoing RPCs may fail. + /// + /// - Parameter promise: A promise which will be completed when shutdown has completed. + public func close(promise: EventLoopPromise) { + self.connectionManager.shutdown(mode: .forceful, promise: promise) + } + + /// Attempt to gracefully shutdown the channel. New RPCs will be failed immediately and existing + /// RPCs may continue to run until they complete. + /// + /// - Parameters: + /// - deadline: A point in time by which the graceful shutdown must have completed. If the + /// deadline passes and RPCs are still active then the connection will be closed forcefully + /// and any remaining in-flight RPCs may be failed. + /// - promise: A promise which will be completed when shutdown has completed. + public func closeGracefully(deadline: NIODeadline, promise: EventLoopPromise) { + return self.connectionManager.shutdown(mode: .graceful(deadline), promise: promise) + } + + /// Populates the logger in `options` and appends a request ID header to the metadata, if + /// configured. + /// - Parameter options: The options containing the logger to populate. + private func populateLogger(in options: inout CallOptions) { + // Get connection metadata. + self.connectionManager.appendMetadata(to: &options.logger) + + // Attach a request ID. + let requestID = options.requestIDProvider.requestID() + if let requestID = requestID { + options.logger[metadataKey: MetadataKey.requestID] = "\(requestID)" + // Add the request ID header too. + if let requestIDHeader = options.requestIDHeader { + options.customMetadata.add(name: requestIDHeader, value: requestID) + } + } + } +} + +extension ClientConnection: GRPCChannel { + public func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + var options = callOptions + self.populateLogger(in: &options) + let multiplexer = self.getMultiplexer() + let eventLoop = callOptions.eventLoopPreference.exact ?? multiplexer.eventLoop + + // This should be on the same event loop as the multiplexer (i.e. the event loop of the + // underlying `Channel`. + let channel = multiplexer.eventLoop.makePromise(of: Channel.self) + multiplexer.whenComplete { + ClientConnection.makeStreamChannel(using: $0, promise: channel) + } + + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: options, + interceptors: interceptors, + transportFactory: .http2( + channel: channel.futureResult, + authority: self.authority, + scheme: self.scheme, + maximumReceiveMessageLength: self.configuration.maximumReceiveMessageLength, + errorDelegate: self.configuration.errorDelegate + ) + ) + } + + public func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + var options = callOptions + self.populateLogger(in: &options) + let multiplexer = self.getMultiplexer() + let eventLoop = callOptions.eventLoopPreference.exact ?? multiplexer.eventLoop + + // This should be on the same event loop as the multiplexer (i.e. the event loop of the + // underlying `Channel`. + let channel = multiplexer.eventLoop.makePromise(of: Channel.self) + multiplexer.whenComplete { + ClientConnection.makeStreamChannel(using: $0, promise: channel) + } + + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: options, + interceptors: interceptors, + transportFactory: .http2( + channel: channel.futureResult, + authority: self.authority, + scheme: self.scheme, + maximumReceiveMessageLength: self.configuration.maximumReceiveMessageLength, + errorDelegate: self.configuration.errorDelegate + ) + ) + } + + private static func makeStreamChannel( + using result: Result, + promise: EventLoopPromise + ) { + switch result { + case let .success(multiplexer): + multiplexer.createStreamChannel(promise: promise) { + $0.eventLoop.makeSucceededVoidFuture() + } + case let .failure(error): + promise.fail(error) + } + } +} + +// MARK: - Configuration structures + +/// A target to connect to. +public struct ConnectionTarget: GRPCSendable { + internal enum Wrapped { + case hostAndPort(String, Int) + case unixDomainSocket(String) + case socketAddress(SocketAddress) + case connectedSocket(NIOBSDSocket.Handle) + } + + internal var wrapped: Wrapped + private init(_ wrapped: Wrapped) { + self.wrapped = wrapped + } + + /// The host and port. The port is 443 by default. + public static func host(_ host: String, port: Int = 443) -> ConnectionTarget { + return ConnectionTarget(.hostAndPort(host, port)) + } + + /// The host and port. + public static func hostAndPort(_ host: String, _ port: Int) -> ConnectionTarget { + return ConnectionTarget(.hostAndPort(host, port)) + } + + /// The path of a Unix domain socket. + public static func unixDomainSocket(_ path: String) -> ConnectionTarget { + return ConnectionTarget(.unixDomainSocket(path)) + } + + /// A NIO socket address. + public static func socketAddress(_ address: SocketAddress) -> ConnectionTarget { + return ConnectionTarget(.socketAddress(address)) + } + + /// A connected NIO socket. + public static func connectedSocket(_ socket: NIOBSDSocket.Handle) -> ConnectionTarget { + return ConnectionTarget(.connectedSocket(socket)) + } + + @usableFromInline + var host: String { + switch self.wrapped { + case let .hostAndPort(host, _): + return host + case let .socketAddress(.v4(address)): + return address.host + case let .socketAddress(.v6(address)): + return address.host + case .unixDomainSocket, .socketAddress(.unixDomainSocket), .connectedSocket: + return "localhost" + } + } +} + +/// The connectivity behavior to use when starting an RPC. +public struct CallStartBehavior: Hashable, GRPCSendable { + internal enum Behavior: Hashable, GRPCSendable { + case waitsForConnectivity + case fastFailure + } + + internal var wrapped: Behavior + private init(_ wrapped: Behavior) { + self.wrapped = wrapped + } + + /// Waits for connectivity (that is, the 'ready' connectivity state) before attempting to start + /// an RPC. Doing so may involve multiple connection attempts. + /// + /// This is the preferred, and default, behaviour. + public static let waitsForConnectivity = CallStartBehavior(.waitsForConnectivity) + + /// The 'fast failure' behaviour is intended for cases where users would rather their RPC failed + /// quickly rather than waiting for an active connection. The behaviour depends on the current + /// connectivity state: + /// + /// - Idle: a connection attempt will be started and the RPC will fail if that attempt fails. + /// - Connecting: a connection attempt is already in progress, the RPC will fail if that attempt + /// fails. + /// - Ready: a connection is already active: the RPC will be started using that connection. + /// - Transient failure: the last connection or connection attempt failed and gRPC is waiting to + /// connect again. The RPC will fail immediately. + /// - Shutdown: the connection is shutdown, the RPC will fail immediately. + public static let fastFailure = CallStartBehavior(.fastFailure) +} + +extension ClientConnection { + /// Configuration for a `ClientConnection`. Users should prefer using one of the + /// `ClientConnection` builders: `ClientConnection.secure(_:)` or `ClientConnection.insecure(_:)`. + public struct Configuration: GRPCSendable { + /// The target to connect to. + public var target: ConnectionTarget + + /// The event loop group to run the connection on. + public var eventLoopGroup: EventLoopGroup + + /// An error delegate which is called when errors are caught. Provided delegates **must not + /// maintain a strong reference to this `ClientConnection`**. Doing so will cause a retain + /// cycle. Defaults to `LoggingClientErrorDelegate`. + public var errorDelegate: ClientErrorDelegate? = LoggingClientErrorDelegate.shared + + /// A delegate which is called when the connectivity state is changed. Defaults to `nil`. + public var connectivityStateDelegate: ConnectivityStateDelegate? + + /// The `DispatchQueue` on which to call the connectivity state delegate. If a delegate is + /// provided but the queue is `nil` then one will be created by gRPC. Defaults to `nil`. + public var connectivityStateDelegateQueue: DispatchQueue? + + #if canImport(NIOSSL) + /// TLS configuration for this connection. `nil` if TLS is not desired. + /// + /// - Important: `tls` is deprecated; use `tlsConfiguration` or one of + /// the `ClientConnection.withTLS` builder functions. + @available(*, deprecated, renamed: "tlsConfiguration") + public var tls: TLS? { + get { + return self.tlsConfiguration?.asDeprecatedClientConfiguration + } + set { + self.tlsConfiguration = newValue.map { .init(transforming: $0) } + } + } + #endif // canImport(NIOSSL) + + /// TLS configuration for this connection. `nil` if TLS is not desired. + public var tlsConfiguration: GRPCTLSConfiguration? + + /// The connection backoff configuration. If no connection retrying is required then this should + /// be `nil`. + public var connectionBackoff: ConnectionBackoff? = ConnectionBackoff() + + /// The connection keepalive configuration. + public var connectionKeepalive = ClientConnectionKeepalive() + + /// The amount of time to wait before closing the connection. The idle timeout will start only + /// if there are no RPCs in progress and will be cancelled as soon as any RPCs start. + /// + /// If a connection becomes idle, starting a new RPC will automatically create a new connection. + /// + /// Defaults to 30 minutes. + public var connectionIdleTimeout: TimeAmount = .minutes(30) + + /// The behavior used to determine when an RPC should start. That is, whether it should wait for + /// an active connection or fail quickly if no connection is currently available. + /// + /// Defaults to `waitsForConnectivity`. + public var callStartBehavior: CallStartBehavior = .waitsForConnectivity + + /// The HTTP/2 flow control target window size. Defaults to 8MB. Values are clamped between + /// 1 and 2^31-1 inclusive. + public var httpTargetWindowSize = 8 * 1024 * 1024 { + didSet { + self.httpTargetWindowSize = self.httpTargetWindowSize.clamped(to: 1 ... Int(Int32.max)) + } + } + + /// The HTTP/2 max frame size. Defaults to 16384. Value is clamped between 2^14 and 2^24-1 + /// octets inclusive (the minimum and maximum allowable values - HTTP/2 RFC 7540 4.2). + public var httpMaxFrameSize: Int = 16384 { + didSet { + self.httpMaxFrameSize = self.httpMaxFrameSize.clamped(to: 16384 ... 16_777_215) + } + } + + /// The HTTP protocol used for this connection. + public var httpProtocol: HTTP2FramePayloadToHTTP1ClientCodec.HTTPProtocol { + return self.tlsConfiguration == nil ? .http : .https + } + + /// The maximum size in bytes of a message which may be received from a server. Defaults to 4MB. + public var maximumReceiveMessageLength: Int = 4 * 1024 * 1024 { + willSet { + precondition(newValue >= 0, "maximumReceiveMessageLength must be positive") + } + } + + /// A logger for background information (such as connectivity state). A separate logger for + /// requests may be provided in the `CallOptions`. + /// + /// Defaults to a no-op logger. + public var backgroundActivityLogger = Logger( + label: "io.grpc", + factory: { _ in SwiftLogNoOpLogHandler() } + ) + + /// A channel initializer which will be run after gRPC has initialized each channel. This may be + /// used to add additional handlers to the pipeline and is intended for debugging. + /// + /// - Warning: The initializer closure may be invoked *multiple times*. + public var debugChannelInitializer: GRPCChannelInitializer? + + #if canImport(NIOSSL) + /// Create a `Configuration` with some pre-defined defaults. Prefer using + /// `ClientConnection.secure(group:)` to build a connection secured with TLS or + /// `ClientConnection.insecure(group:)` to build a plaintext connection. + /// + /// - Parameter target: The target to connect to. + /// - Parameter eventLoopGroup: The event loop group to run the connection on. + /// - Parameter errorDelegate: The error delegate, defaulting to a delegate which will log only + /// on debug builds. + /// - Parameter connectivityStateDelegate: A connectivity state delegate, defaulting to `nil`. + /// - Parameter connectivityStateDelegateQueue: A `DispatchQueue` on which to call the + /// `connectivityStateDelegate`. + /// - Parameter tls: TLS configuration, defaulting to `nil`. + /// - Parameter connectionBackoff: The connection backoff configuration to use. + /// - Parameter connectionKeepalive: The keepalive configuration to use. + /// - Parameter connectionIdleTimeout: The amount of time to wait before closing the connection, defaulting to 30 minutes. + /// - Parameter callStartBehavior: The behavior used to determine when a call should start in + /// relation to its underlying connection. Defaults to `waitsForConnectivity`. + /// - Parameter httpTargetWindowSize: The HTTP/2 flow control target window size. + /// - Parameter backgroundActivityLogger: A logger for background information (such as + /// connectivity state). Defaults to a no-op logger. + /// - Parameter debugChannelInitializer: A channel initializer will be called after gRPC has + /// initialized the channel. Defaults to `nil`. + @available(*, deprecated, renamed: "default(target:eventLoopGroup:)") + public init( + target: ConnectionTarget, + eventLoopGroup: EventLoopGroup, + errorDelegate: ClientErrorDelegate? = LoggingClientErrorDelegate(), + connectivityStateDelegate: ConnectivityStateDelegate? = nil, + connectivityStateDelegateQueue: DispatchQueue? = nil, + tls: Configuration.TLS? = nil, + connectionBackoff: ConnectionBackoff? = ConnectionBackoff(), + connectionKeepalive: ClientConnectionKeepalive = ClientConnectionKeepalive(), + connectionIdleTimeout: TimeAmount = .minutes(30), + callStartBehavior: CallStartBehavior = .waitsForConnectivity, + httpTargetWindowSize: Int = 8 * 1024 * 1024, + backgroundActivityLogger: Logger = Logger( + label: "io.grpc", + factory: { _ in SwiftLogNoOpLogHandler() } + ), + debugChannelInitializer: GRPCChannelInitializer? = nil + ) { + self.target = target + self.eventLoopGroup = eventLoopGroup + self.errorDelegate = errorDelegate + self.connectivityStateDelegate = connectivityStateDelegate + self.connectivityStateDelegateQueue = connectivityStateDelegateQueue + self.tlsConfiguration = tls.map { GRPCTLSConfiguration(transforming: $0) } + self.connectionBackoff = connectionBackoff + self.connectionKeepalive = connectionKeepalive + self.connectionIdleTimeout = connectionIdleTimeout + self.callStartBehavior = callStartBehavior + self.httpTargetWindowSize = httpTargetWindowSize + self.backgroundActivityLogger = backgroundActivityLogger + self.debugChannelInitializer = debugChannelInitializer + } + #endif // canImport(NIOSSL) + + private init(eventLoopGroup: EventLoopGroup, target: ConnectionTarget) { + self.eventLoopGroup = eventLoopGroup + self.target = target + } + + /// Make a new configuration using default values. + /// + /// - Parameters: + /// - target: The target to connect to. + /// - eventLoopGroup: The `EventLoopGroup` providing an `EventLoop` for the connection to + /// run on. + /// - Returns: A configuration with default values set. + public static func `default`( + target: ConnectionTarget, + eventLoopGroup: EventLoopGroup + ) -> Configuration { + return .init(eventLoopGroup: eventLoopGroup, target: target) + } + } +} + +// MARK: - Configuration helpers/extensions + +extension ClientBootstrapProtocol { + /// Connect to the given connection target. + /// + /// - Parameter target: The target to connect to. + func connect(to target: ConnectionTarget) -> EventLoopFuture { + switch target.wrapped { + case let .hostAndPort(host, port): + return self.connect(host: host, port: port) + + case let .unixDomainSocket(path): + return self.connect(unixDomainSocketPath: path) + + case let .socketAddress(address): + return self.connect(to: address) + case let .connectedSocket(socket): + return self.withConnectedSocket(socket) + } + } +} + +#if canImport(NIOSSL) +extension ChannelPipeline.SynchronousOperations { + internal func configureNIOSSLForGRPCClient( + sslContext: Result, + serverHostname: String?, + customVerificationCallback: NIOSSLCustomVerificationCallback?, + logger: Logger + ) throws { + let sslContext = try sslContext.get() + let sslClientHandler: NIOSSLClientHandler + + if let customVerificationCallback = customVerificationCallback { + sslClientHandler = try NIOSSLClientHandler( + context: sslContext, + serverHostname: serverHostname, + customVerificationCallback: customVerificationCallback + ) + } else { + sslClientHandler = try NIOSSLClientHandler( + context: sslContext, + serverHostname: serverHostname + ) + } + + try self.addHandler(sslClientHandler) + try self.addHandler(TLSVerificationHandler(logger: logger)) + } +} +#endif // canImport(NIOSSL) + +extension ChannelPipeline.SynchronousOperations { + internal func configureHTTP2AndGRPCHandlersForGRPCClient( + channel: Channel, + connectionManager: ConnectionManager, + connectionKeepalive: ClientConnectionKeepalive, + connectionIdleTimeout: TimeAmount, + httpTargetWindowSize: Int, + httpMaxFrameSize: Int, + errorDelegate: ClientErrorDelegate?, + logger: Logger + ) throws { + let initialSettings = [ + // As per the default settings for swift-nio-http2: + HTTP2Setting(parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize), + // We never expect (or allow) server initiated streams. + HTTP2Setting(parameter: .maxConcurrentStreams, value: 0), + // As configured by the user. + HTTP2Setting(parameter: .maxFrameSize, value: httpMaxFrameSize), + HTTP2Setting(parameter: .initialWindowSize, value: httpTargetWindowSize), + ] + + // We could use 'configureHTTP2Pipeline' here, but we need to add a few handlers between the + // two HTTP/2 handlers so we'll do it manually instead. + try self.addHandler(NIOHTTP2Handler(mode: .client, initialSettings: initialSettings)) + + let h2Multiplexer = HTTP2StreamMultiplexer( + mode: .client, + channel: channel, + targetWindowSize: httpTargetWindowSize, + inboundStreamInitializer: nil + ) + + // The multiplexer is passed through the idle handler so it is only reported on + // successful channel activation - with happy eyeballs multiple pipelines can + // be constructed so it's not safe to report just yet. + try self.addHandler(GRPCIdleHandler( + connectionManager: connectionManager, + multiplexer: h2Multiplexer, + idleTimeout: connectionIdleTimeout, + keepalive: connectionKeepalive, + logger: logger + )) + + try self.addHandler(h2Multiplexer) + try self.addHandler(DelegatingErrorHandler(logger: logger, delegate: errorDelegate)) + } +} + +extension Channel { + func configureGRPCClient( + errorDelegate: ClientErrorDelegate?, + logger: Logger + ) -> EventLoopFuture { + return self.configureHTTP2Pipeline(mode: .client, inboundStreamInitializer: nil).flatMap { _ in + self.pipeline.addHandler(DelegatingErrorHandler(logger: logger, delegate: errorDelegate)) + } + } +} + +extension TimeAmount { + /// Creates a new `TimeAmount` from the given time interval in seconds. + /// + /// - Parameter timeInterval: The amount of time in seconds + static func seconds(timeInterval: TimeInterval) -> TimeAmount { + return .nanoseconds(Int64(timeInterval * 1_000_000_000)) + } +} + +extension String { + var isIPAddress: Bool { + // We need some scratch space to let inet_pton write into. + var ipv4Addr = in_addr() + var ipv6Addr = in6_addr() + + return self.withCString { ptr in + inet_pton(AF_INET, ptr, &ipv4Addr) == 1 || + inet_pton(AF_INET6, ptr, &ipv6Addr) == 1 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnectionConfiguration+NIOSSL.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnectionConfiguration+NIOSSL.swift new file mode 100644 index 00000000..6de8b4e8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientConnectionConfiguration+NIOSSL.swift @@ -0,0 +1,133 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOSSL + +extension ClientConnection.Configuration { + /// TLS configuration for a `ClientConnection`. + /// + /// Note that this configuration is a subset of `NIOSSL.TLSConfiguration` where certain options + /// are removed from the user's control to ensure the configuration complies with the gRPC + /// specification. + @available(*, deprecated, renamed: "GRPCTLSConfiguration") + public struct TLS { + public private(set) var configuration: TLSConfiguration + + /// Value to use for TLS SNI extension; this must not be an address. + public var hostnameOverride: String? + + /// The certificates to offer during negotiation. If not present, no certificates will be offered. + public var certificateChain: [NIOSSLCertificateSource] { + get { + return self.configuration.certificateChain + } + set { + self.configuration.certificateChain = newValue + } + } + + /// The private key associated with the leaf certificate. + public var privateKey: NIOSSLPrivateKeySource? { + get { + return self.configuration.privateKey + } + set { + self.configuration.privateKey = newValue + } + } + + /// The trust roots to use to validate certificates. This only needs to be provided if you + /// intend to validate certificates. + public var trustRoots: NIOSSLTrustRoots? { + get { + return self.configuration.trustRoots + } + set { + self.configuration.trustRoots = newValue + } + } + + /// Whether to verify remote certificates. + public var certificateVerification: CertificateVerification { + get { + return self.configuration.certificateVerification + } + set { + self.configuration.certificateVerification = newValue + } + } + + /// A custom verification callback that allows completely overriding the certificate verification logic for this connection. + public var customVerificationCallback: NIOSSLCustomVerificationCallback? + + /// TLS Configuration with suitable defaults for clients. + /// + /// This is a wrapper around `NIOSSL.TLSConfiguration` to restrict input to values which comply + /// with the gRPC protocol. + /// + /// - Parameter certificateChain: The certificate to offer during negotiation, defaults to an + /// empty array. + /// - Parameter privateKey: The private key associated with the leaf certificate. This defaults + /// to `nil`. + /// - Parameter trustRoots: The trust roots to validate certificates, this defaults to using a + /// root provided by the platform. + /// - Parameter certificateVerification: Whether to verify the remote certificate. Defaults to + /// `.fullVerification`. + /// - Parameter hostnameOverride: Value to use for TLS SNI extension; this must not be an IP + /// address, defaults to `nil`. + /// - Parameter customVerificationCallback: A callback to provide to override the certificate verification logic, + /// defaults to `nil`. + public init( + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + trustRoots: NIOSSLTrustRoots = .default, + certificateVerification: CertificateVerification = .fullVerification, + hostnameOverride: String? = nil, + customVerificationCallback: NIOSSLCustomVerificationCallback? = nil + ) { + var configuration = TLSConfiguration.makeClientConfiguration() + configuration.minimumTLSVersion = .tlsv12 + configuration.certificateVerification = certificateVerification + configuration.trustRoots = trustRoots + configuration.certificateChain = certificateChain + configuration.privateKey = privateKey + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.client + + self.configuration = configuration + self.hostnameOverride = hostnameOverride + self.customVerificationCallback = customVerificationCallback + } + + /// Creates a TLS Configuration using the given `NIOSSL.TLSConfiguration`. + /// + /// - Note: If no ALPN tokens are set in `configuration.applicationProtocols` then "grpc-exp" + /// and "h2" will be used. + /// - Parameters: + /// - configuration: The `NIOSSL.TLSConfiguration` to base this configuration on. + /// - hostnameOverride: The hostname override to use for the TLS SNI extension. + public init(configuration: TLSConfiguration, hostnameOverride: String? = nil) { + self.configuration = configuration + self.hostnameOverride = hostnameOverride + + // Set the ALPN tokens if none were set. + if self.configuration.applicationProtocols.isEmpty { + self.configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.client + } + } + } +} + +#endif // canImport(NIOSSL) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientErrorDelegate.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientErrorDelegate.swift new file mode 100644 index 00000000..4054c447 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ClientErrorDelegate.swift @@ -0,0 +1,61 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging + +/// Delegate called when errors are caught by the client on individual HTTP/2 streams and errors in +/// the underlying HTTP/2 connection. +/// +/// The intended use of this protocol is with `ClientConnection`. In order to avoid retain +/// cycles, classes implementing this delegate **must not** maintain a strong reference to the +/// `ClientConnection`. +public protocol ClientErrorDelegate: AnyObject, GRPCPreconcurrencySendable { + /// Called when the client catches an error. + /// + /// - Parameters: + /// - error: The error which was caught. + /// - logger: A logger with relevant metadata for the RPC or connection the error relates to. + /// - file: The file where the error was raised. + /// - line: The line within the file where the error was raised. + func didCatchError(_ error: Error, logger: Logger, file: StaticString, line: Int) +} + +extension ClientErrorDelegate { + /// Calls `didCatchError(_:logger:file:line:)` with appropriate context placeholders when no + /// context is available. + internal func didCatchErrorWithoutContext(_ error: Error, logger: Logger) { + self.didCatchError(error, logger: logger, file: "", line: 0) + } +} + +/// A `ClientErrorDelegate` which logs errors. +public final class LoggingClientErrorDelegate: ClientErrorDelegate { + /// A shared instance of this class. + public static let shared = LoggingClientErrorDelegate() + + public init() {} + + public func didCatchError(_ error: Error, logger: Logger, file: StaticString, line: Int) { + logger.error( + "grpc client error", + metadata: [MetadataKey.error: "\(error)"], + source: "GRPC", + file: "\(file)", + function: "", + line: UInt(line) + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/CompressionAlgorithm.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/CompressionAlgorithm.swift new file mode 100644 index 00000000..2b7a5659 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/CompressionAlgorithm.swift @@ -0,0 +1,53 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// Supported message compression algorithms. +/// +/// These algorithms are indicated in the "grpc-encoding" header. As such, a lack of "grpc-encoding" +/// header indicates that there is no message compression. +public struct CompressionAlgorithm: Equatable, GRPCSendable { + /// Identity compression; "no" compression but indicated via the "grpc-encoding" header. + public static let identity = CompressionAlgorithm(.identity) + public static let deflate = CompressionAlgorithm(.deflate) + public static let gzip = CompressionAlgorithm(.gzip) + + // The order here is important: most compression to least. + public static let all: [CompressionAlgorithm] = [.gzip, .deflate, .identity] + + /// The name of the compression algorithm. + public var name: String { + return self.algorithm.rawValue + } + + internal enum Algorithm: String { + case identity + case deflate + case gzip + } + + internal let algorithm: Algorithm + + private init(_ algorithm: Algorithm) { + self.algorithm = algorithm + } + + internal init?(rawValue: String) { + guard let algorithm = Algorithm(rawValue: rawValue) else { + return nil + } + self.algorithm = algorithm + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/DecompressionLimit.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/DecompressionLimit.swift new file mode 100644 index 00000000..b206e7e1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/DecompressionLimit.swift @@ -0,0 +1,55 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public struct DecompressionLimit: Equatable, GRPCSendable { + private enum Limit: Equatable, GRPCSendable { + case ratio(Int) + case absolute(Int) + } + + private let limit: Limit + + /// Limits decompressed payloads to be no larger than the product of the compressed size + /// and `ratio`. + /// + /// - Parameter ratio: The decompression ratio. + /// - Precondition: `ratio` must be greater than zero. + public static func ratio(_ ratio: Int) -> DecompressionLimit { + precondition(ratio > 0, "ratio must be greater than zero") + return DecompressionLimit(limit: .ratio(ratio)) + } + + /// Limits decompressed payloads to be no larger than the given `size`. + /// + /// - Parameter size: The absolute size limit of decompressed payloads. + /// - Precondition: `size` must not be negative. + public static func absolute(_ size: Int) -> DecompressionLimit { + precondition(size >= 0, "absolute size must be non-negative") + return DecompressionLimit(limit: .absolute(size)) + } +} + +extension DecompressionLimit { + /// The largest allowed decompressed size for this limit. + func maximumDecompressedSize(compressedSize: Int) -> Int { + switch self.limit { + case let .ratio(ratio): + return ratio * compressedSize + case let .absolute(size): + return size + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/MessageEncoding.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/MessageEncoding.swift new file mode 100644 index 00000000..b3fdf4d3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/MessageEncoding.swift @@ -0,0 +1,162 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// Whether compression should be enabled for the message. +public struct Compression: Hashable, GRPCSendable { + @usableFromInline + internal enum _Wrapped: Hashable, GRPCSendable { + case enabled + case disabled + case deferToCallDefault + } + + @usableFromInline + internal var _wrapped: _Wrapped + + private init(_ wrapped: _Wrapped) { + self._wrapped = wrapped + } + + /// Enable compression. Note that this will be ignored if compression has not been enabled or is + /// not supported on the call. + public static let enabled = Compression(.enabled) + + /// Disable compression. + public static let disabled = Compression(.disabled) + + /// Defer to the call (the `CallOptions` for the client, and the context for the server) to + /// determine whether compression should be used for the message. + public static let deferToCallDefault = Compression(.deferToCallDefault) +} + +extension Compression { + @inlinable + internal func isEnabled(callDefault: Bool) -> Bool { + switch self._wrapped { + case .enabled: + return callDefault + case .disabled: + return false + case .deferToCallDefault: + return callDefault + } + } +} + +/// Whether compression is enabled or disabled for a client. +public enum ClientMessageEncoding: GRPCSendable { + /// Compression is enabled with the given configuration. + case enabled(Configuration) + /// Compression is disabled. + case disabled +} + +extension ClientMessageEncoding { + internal var enabledForRequests: Bool { + switch self { + case let .enabled(configuration): + return configuration.outbound != nil + case .disabled: + return false + } + } +} + +extension ClientMessageEncoding { + public struct Configuration: GRPCSendable { + public init( + forRequests outbound: CompressionAlgorithm?, + acceptableForResponses inbound: [CompressionAlgorithm] = CompressionAlgorithm.all, + decompressionLimit: DecompressionLimit + ) { + self.outbound = outbound + self.inbound = inbound + self.decompressionLimit = decompressionLimit + } + + /// The compression algorithm used for outbound messages. + public var outbound: CompressionAlgorithm? + + /// The set of compression algorithms advertised to the remote peer that they may use. + public var inbound: [CompressionAlgorithm] + + /// The decompression limit acceptable for responses. RPCs which receive a message whose + /// decompressed size exceeds the limit will be cancelled. + public var decompressionLimit: DecompressionLimit + + /// Accept all supported compression on responses, do not compress requests. + public static func responsesOnly( + acceptable: [CompressionAlgorithm] = CompressionAlgorithm.all, + decompressionLimit: DecompressionLimit + ) -> Configuration { + return Configuration( + forRequests: .identity, + acceptableForResponses: acceptable, + decompressionLimit: decompressionLimit + ) + } + + internal var acceptEncodingHeader: String { + return self.inbound.map { $0.name }.joined(separator: ",") + } + } +} + +/// Whether compression is enabled or disabled on the server. +public enum ServerMessageEncoding { + /// Compression is supported with this configuration. + case enabled(Configuration) + /// Compression is not enabled. However, 'identity' compression is still supported. + case disabled + + @usableFromInline + internal var isEnabled: Bool { + switch self { + case .enabled: + return true + case .disabled: + return false + } + } +} + +extension ServerMessageEncoding { + public struct Configuration { + /// The set of compression algorithms advertised that we will accept from clients for requests. + /// Note that clients may send us messages compressed with algorithms not included in this list; + /// if we support it then we still accept the message. + /// + /// All cases of `CompressionAlgorithm` are supported. + public var enabledAlgorithms: [CompressionAlgorithm] + + /// The decompression limit acceptable for requests. RPCs which receive a message whose + /// decompressed size exceeds the limit will be cancelled. + public var decompressionLimit: DecompressionLimit + + /// Create a configuration for server message encoding. + /// + /// - Parameters: + /// - enabledAlgorithms: The list of algorithms which are enabled. + /// - decompressionLimit: Decompression limit acceptable for requests. + public init( + enabledAlgorithms: [CompressionAlgorithm] = CompressionAlgorithm.all, + decompressionLimit: DecompressionLimit + ) { + self.enabledAlgorithms = enabledAlgorithms + self.decompressionLimit = decompressionLimit + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/Zlib.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/Zlib.swift new file mode 100644 index 00000000..d5d1dc8c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Compression/Zlib.swift @@ -0,0 +1,521 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import CGRPCZlib +import struct Foundation.Data +import NIOCore + +/// Provides minimally configurable wrappers around zlib's compression and decompression +/// functionality. +/// +/// See also: https://www.zlib.net/manual.html +enum Zlib { + // MARK: Deflate (compression) + + /// Creates a new compressor for the given compression format. + /// + /// This compressor is only suitable for compressing whole messages at a time. Callers + /// must `reset()` the compressor between subsequent calls to `deflate`. + /// + /// - Parameter format:The expected compression type. + class Deflate { + private var stream: ZStream + private let format: CompressionFormat + + init(format: CompressionFormat) { + self.stream = ZStream() + self.format = format + self.initialize() + } + + deinit { + self.end() + } + + /// Compresses the data in `input` into the `output` buffer. + /// + /// - Parameter input: The complete data to be compressed. + /// - Parameter output: The `ByteBuffer` into which the compressed message should be written. + /// - Returns: The number of bytes written into the `output` buffer. + func deflate(_ input: inout ByteBuffer, into output: inout ByteBuffer) throws -> Int { + // Note: This is only valid because we always use Z_FINISH to flush. + // + // From the documentation: + // Note that it is possible for the compressed size to be larger than the value returned + // by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used. + let upperBound = CGRPCZlib_deflateBound(&self.stream.zstream, UInt(input.readableBytes)) + + return try input.readWithUnsafeMutableReadableBytes { inputPointer -> (Int, Int) in + + self.stream.nextInputBuffer = CGRPCZlib_castVoidToBytefPointer(inputPointer.baseAddress!) + self.stream.availableInputBytes = inputPointer.count + + defer { + self.stream.nextInputBuffer = nil + self.stream.availableInputBytes = 0 + } + + let writtenBytes = try output + .writeWithUnsafeMutableBytes(minimumWritableBytes: Int(upperBound)) { outputPointer in + try self.stream.deflate( + outputBuffer: CGRPCZlib_castVoidToBytefPointer(outputPointer.baseAddress!), + outputBufferSize: outputPointer.count + ) + } + + let bytesRead = inputPointer.count - self.stream.availableInputBytes + return (bytesRead, writtenBytes) + } + } + + /// Resets compression state. This must be called after each call to `deflate` if more + /// messages are to be compressed by this instance. + func reset() { + let rc = CGRPCZlib_deflateReset(&self.stream.zstream) + + // Possible return codes: + // - Z_OK + // - Z_STREAM_ERROR: the source stream state was inconsistent. + // + // If we're in an inconsistent state we can just replace the stream and initialize it. + switch rc { + case Z_OK: + () + + case Z_STREAM_ERROR: + self.end() + self.stream = ZStream() + self.initialize() + + default: + preconditionFailure("deflateReset: unexpected return code rc=\(rc)") + } + } + + /// Initialize the `z_stream` used for deflate. + private func initialize() { + let rc = CGRPCZlib_deflateInit2( + &self.stream.zstream, + Z_DEFAULT_COMPRESSION, // compression level + Z_DEFLATED, // compression method (this must be Z_DEFLATED) + self.format.windowBits, // window size, i.e. deflate/gzip + 8, // memory level (this is the default value in the docs) + Z_DEFAULT_STRATEGY // compression strategy + ) + + // Possible return codes: + // - Z_OK + // - Z_MEM_ERROR: not enough memory + // - Z_STREAM_ERROR: a parameter was invalid + // + // If we can't allocate memory then we can't progress anyway, and we control the parameters + // so not throwing an error here is okay. + assert(rc == Z_OK, "deflateInit2 error: rc=\(rc) \(self.stream.lastErrorMessage ?? "")") + } + + /// Calls `deflateEnd` on the underlying `z_stream` to deallocate resources allocated by zlib. + private func end() { + _ = CGRPCZlib_deflateEnd(&self.stream.zstream) + + // Possible return codes: + // - Z_OK + // - Z_STREAM_ERROR: the source stream state was inconsistent. + // + // Since we're going away there's no reason to fail here. + } + } + + // MARK: Inflate (decompression) + + /// Creates a new decompressor for the given compression format. + /// + /// This decompressor is only suitable for decompressing whole messages at a time. Callers + /// must `reset()` the decompressor between subsequent calls to `inflate`. + /// + /// - Parameter format:The expected compression type. + class Inflate { + enum InflationState { + /// Inflation is in progress. + case inflating(InflatingState) + + /// Inflation completed successfully. + case inflated + + init(compressedSize: Int, limit: DecompressionLimit) { + self = .inflating(InflatingState(compressedSize: compressedSize, limit: limit)) + } + + /// Update the state with the result of `Zlib.ZStream.inflate(outputBuffer:outputBufferSize:)`. + mutating func update(with result: Zlib.ZStream.InflateResult) throws { + switch (result.outcome, self) { + case var (.outputBufferTooSmall, .inflating(state)): + guard state.outputBufferSize < state.maxDecompressedSize else { + // We hit the decompression limit and last time we clamped our output buffer size; we + // can't use a larger buffer without exceeding the limit. + throw GRPCError.DecompressionLimitExceeded(compressedSize: state.compressedSize) + .captureContext() + } + state.increaseOutputBufferSize() + self = .inflating(state) + + case let (.complete, .inflating(state)): + // Since we request a _minimum_ output buffer size from `ByteBuffer` it's possible that + // the decompressed size exceeded the decompression limit. + guard result.totalBytesWritten <= state.maxDecompressedSize else { + throw GRPCError.DecompressionLimitExceeded(compressedSize: state.compressedSize) + .captureContext() + } + self = .inflated + + case (.complete, .inflated), + (.outputBufferTooSmall, .inflated): + preconditionFailure("invalid outcome '\(result.outcome)'; inflation is already complete") + } + } + } + + struct InflatingState { + /// The compressed size of the data to inflate. + let compressedSize: Int + + /// The maximum size the decompressed data may be, according to the user-defined + /// decompression limit. + let maxDecompressedSize: Int + + /// The minimum size requested for the output buffer. + private(set) var outputBufferSize: Int + + init(compressedSize: Int, limit: DecompressionLimit) { + self.compressedSize = compressedSize + self.maxDecompressedSize = limit.maximumDecompressedSize(compressedSize: compressedSize) + self.outputBufferSize = compressedSize + self.increaseOutputBufferSize() + } + + /// Increase the output buffer size without exceeding `maxDecompressedSize`. + mutating func increaseOutputBufferSize() { + let nextOutputBufferSize = 2 * self.outputBufferSize + + if nextOutputBufferSize > self.maxDecompressedSize { + self.outputBufferSize = self.maxDecompressedSize + } else { + self.outputBufferSize = nextOutputBufferSize + } + } + } + + private var stream: ZStream + private let format: CompressionFormat + private let limit: DecompressionLimit + + init(format: CompressionFormat, limit: DecompressionLimit) { + self.stream = ZStream() + self.format = format + self.limit = limit + self.initialize() + } + + deinit { + self.end() + } + + /// Resets decompression state. This must be called after each call to `inflate` if more + /// messages are to be decompressed by this instance. + func reset() { + let rc = CGRPCZlib_inflateReset(&self.stream.zstream) + + // Possible return codes: + // - Z_OK + // - Z_STREAM_ERROR: the source stream state was inconsistent. + // + // If we're in an inconsistent state we can just replace the stream and initialize it. + switch rc { + case Z_OK: + () + + case Z_STREAM_ERROR: + self.end() + self.stream = ZStream() + self.initialize() + + default: + preconditionFailure("inflateReset: unexpected return code rc=\(rc)") + } + } + + /// Inflate the readable bytes from the `input` buffer into the `output` buffer. + /// + /// - Parameters: + /// - input: The buffer read compressed bytes from. + /// - output: The buffer to write the decompressed bytes into. + /// - Returns: The number of bytes written into `output`. + @discardableResult + func inflate(_ input: inout ByteBuffer, into output: inout ByteBuffer) throws -> Int { + return try input.readWithUnsafeMutableReadableBytes { inputPointer -> (Int, Int) in + // Setup the input buffer. + self.stream.availableInputBytes = inputPointer.count + self.stream.nextInputBuffer = CGRPCZlib_castVoidToBytefPointer(inputPointer.baseAddress!) + + defer { + self.stream.availableInputBytes = 0 + self.stream.nextInputBuffer = nil + } + + var bytesWritten = 0 + var state = InflationState(compressedSize: inputPointer.count, limit: self.limit) + while case let .inflating(inflationState) = state { + // Each call to inflate writes into the buffer, so we need to take the writer index into + // account here. + let writerIndex = output.writerIndex + let minimumWritableBytes = inflationState.outputBufferSize - writerIndex + bytesWritten = try output + .writeWithUnsafeMutableBytes(minimumWritableBytes: minimumWritableBytes) { outputPointer in + let inflateResult = try self.stream.inflate( + outputBuffer: CGRPCZlib_castVoidToBytefPointer(outputPointer.baseAddress!), + outputBufferSize: outputPointer.count + ) + + try state.update(with: inflateResult) + return inflateResult.bytesWritten + } + } + + let bytesRead = inputPointer.count - self.stream.availableInputBytes + return (bytesRead, bytesWritten) + } + } + + private func initialize() { + let rc = CGRPCZlib_inflateInit2(&self.stream.zstream, self.format.windowBits) + + // Possible return codes: + // - Z_OK + // - Z_MEM_ERROR: not enough memory + // + // If we can't allocate memory then we can't progress anyway so not throwing an error here is + // okay. + precondition(rc == Z_OK, "inflateInit2 error: rc=\(rc) \(self.stream.lastErrorMessage ?? "")") + } + + func end() { + _ = CGRPCZlib_inflateEnd(&self.stream.zstream) + + // Possible return codes: + // - Z_OK + // - Z_STREAM_ERROR: the source stream state was inconsistent. + // + // Since we're going away there's no reason to fail here. + } + } + + // MARK: ZStream + + /// This wraps a zlib `z_stream` to provide more Swift-like access to the underlying C-struct. + struct ZStream { + var zstream: z_stream + + init() { + self.zstream = z_stream() + + self.zstream.next_in = nil + self.zstream.avail_in = 0 + + self.zstream.next_out = nil + self.zstream.avail_out = 0 + + self.zstream.zalloc = nil + self.zstream.zfree = nil + self.zstream.opaque = nil + } + + /// Number of bytes available to read `self.nextInputBuffer`. See also: `z_stream.avail_in`. + var availableInputBytes: Int { + get { + return Int(self.zstream.avail_in) + } + set { + self.zstream.avail_in = UInt32(newValue) + } + } + + /// The next input buffer that zlib should read from. See also: `z_stream.next_in`. + var nextInputBuffer: UnsafeMutablePointer! { + get { + return self.zstream.next_in + } + set { + self.zstream.next_in = newValue + } + } + + /// The remaining writable space in `nextOutputBuffer`. See also: `z_stream.avail_out`. + var availableOutputBytes: Int { + get { + return Int(self.zstream.avail_out) + } + set { + return self.zstream.avail_out = UInt32(newValue) + } + } + + /// The next output buffer where zlib should write bytes to. See also: `z_stream.next_out`. + var nextOutputBuffer: UnsafeMutablePointer! { + get { + return self.zstream.next_out + } + set { + self.zstream.next_out = newValue + } + } + + /// The total number of bytes written to the output buffer. See also: `z_stream.total_out`. + var totalOutputBytes: Int { + return Int(self.zstream.total_out) + } + + /// The last error message that zlib wrote. No message is guaranteed on error, however, `nil` is + /// guaranteed if there is no error. See also `z_stream.msg`. + var lastErrorMessage: String? { + guard let bytes = self.zstream.msg else { + return nil + } + return String(cString: bytes) + } + + enum InflateOutcome { + /// The data was successfully inflated. + case complete + + /// A larger output buffer is required. + case outputBufferTooSmall + } + + struct InflateResult { + var bytesWritten: Int + var totalBytesWritten: Int + var outcome: InflateOutcome + } + + /// Decompress the stream into the given output buffer. + /// + /// - Parameter outputBuffer: The buffer into which to write the decompressed data. + /// - Parameter outputBufferSize: The space available in `outputBuffer`. + /// - Returns: The result of the `inflate`, whether it was successful or whether a larger + /// output buffer is required. + mutating func inflate( + outputBuffer: UnsafeMutablePointer, + outputBufferSize: Int + ) throws -> InflateResult { + self.nextOutputBuffer = outputBuffer + self.availableOutputBytes = outputBufferSize + + defer { + self.nextOutputBuffer = nil + self.availableOutputBytes = 0 + } + + let rc = CGRPCZlib_inflate(&self.zstream, Z_FINISH) + let outcome: InflateOutcome + + // Possible return codes: + // - Z_OK: some progress has been made + // - Z_STREAM_END: the end of the compressed data has been reached and all uncompressed output + // has been produced + // - Z_NEED_DICT: a preset dictionary is needed at this point + // - Z_DATA_ERROR: the input data was corrupted + // - Z_STREAM_ERROR: the stream structure was inconsistent + // - Z_MEM_ERROR there was not enough memory + // - Z_BUF_ERROR if no progress was possible or if there was not enough room in the output + // buffer when Z_FINISH is used. + // + // Note that Z_OK is not okay here since we always flush with Z_FINISH and therefore + // use Z_STREAM_END as our success criteria. + + switch rc { + case Z_STREAM_END: + outcome = .complete + + case Z_BUF_ERROR: + outcome = .outputBufferTooSmall + + default: + throw GRPCError.ZlibCompressionFailure(code: rc, message: self.lastErrorMessage) + .captureContext() + } + + return InflateResult( + bytesWritten: outputBufferSize - self.availableOutputBytes, + totalBytesWritten: self.totalOutputBytes, + outcome: outcome + ) + } + + /// Compresses the `inputBuffer` into the `outputBuffer`. + /// + /// `outputBuffer` must be large enough to store the compressed data, `deflateBound()` provides + /// an upper bound for this value. + /// + /// - Parameter outputBuffer: The buffer into which to write the compressed data. + /// - Parameter outputBufferSize: The space available in `outputBuffer`. + /// - Returns: The number of bytes written into the `outputBuffer`. + mutating func deflate( + outputBuffer: UnsafeMutablePointer, + outputBufferSize: Int + ) throws -> Int { + self.nextOutputBuffer = outputBuffer + self.availableOutputBytes = outputBufferSize + + defer { + self.nextOutputBuffer = nil + self.availableOutputBytes = 0 + } + + let rc = CGRPCZlib_deflate(&self.zstream, Z_FINISH) + + // Possible return codes: + // - Z_OK: some progress has been made + // - Z_STREAM_END: all input has been consumed and all output has been produced (only when + // flush is set to Z_FINISH) + // - Z_STREAM_ERROR: the stream state was inconsistent + // - Z_BUF_ERROR: no progress is possible + // + // The documentation notes that Z_BUF_ERROR is not fatal, and deflate() can be called again + // with more input and more output space to continue compressing. However, we + // call `deflateBound()` before `deflate()` which guarantees that the output size will not be + // larger than the value returned by `deflateBound()` if `Z_FINISH` flush is used. As such, + // the only acceptable outcome is `Z_STREAM_END`. + guard rc == Z_STREAM_END else { + throw GRPCError.ZlibCompressionFailure(code: rc, message: self.lastErrorMessage) + .captureContext() + } + + return outputBufferSize - self.availableOutputBytes + } + } + + enum CompressionFormat { + case deflate + case gzip + + var windowBits: Int32 { + switch self { + case .deflate: + return 15 + case .gzip: + return 31 + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionBackoff.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionBackoff.swift new file mode 100644 index 00000000..fda68103 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionBackoff.swift @@ -0,0 +1,173 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation + +/// Provides backoff timeouts for making a connection. +/// +/// This algorithm and defaults are determined by the gRPC connection backoff +/// [documentation](https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md). +public struct ConnectionBackoff: Sequence, GRPCSendable { + public typealias Iterator = ConnectionBackoffIterator + + /// The initial backoff in seconds. + public var initialBackoff: TimeInterval + + /// The maximum backoff in seconds. Note that the backoff is _before_ jitter has been applied, + /// this means that in practice the maximum backoff can be larger than this value. + public var maximumBackoff: TimeInterval + + /// The backoff multiplier. + public var multiplier: Double + + /// Backoff jitter; should be between 0 and 1. + public var jitter: Double + + /// The minimum amount of time in seconds to try connecting. + public var minimumConnectionTimeout: TimeInterval + + /// A limit on the number of times to attempt reconnection. + public var retries: Retries + + public struct Retries: Hashable, GRPCSendable { + fileprivate enum Limit: Hashable, GRPCSendable { + case limited(Int) + case unlimited + } + + fileprivate var limit: Limit + private init(_ limit: Limit) { + self.limit = limit + } + + /// An unlimited number of retry attempts. + public static let unlimited = Retries(.unlimited) + + /// No retry attempts will be made. + public static let none = Retries(.limited(0)) + + /// A limited number of retry attempts. `limit` must be positive. Note that a limit of zero is + /// identical to `.none`. + public static func upTo(_ limit: Int) -> Retries { + precondition(limit >= 0) + return Retries(.limited(limit)) + } + } + + /// Creates a `ConnectionBackoff`. + /// + /// - Parameters: + /// - initialBackoff: Initial backoff in seconds, defaults to 1.0. + /// - maximumBackoff: Maximum backoff in seconds (prior to adding jitter), defaults to 120.0. + /// - multiplier: Backoff multiplier, defaults to 1.6. + /// - jitter: Backoff jitter, defaults to 0.2. + /// - minimumConnectionTimeout: Minimum connection timeout in seconds, defaults to 20.0. + /// - retries: A limit on the number of times to retry establishing a connection. + /// Defaults to `.unlimited`. + public init( + initialBackoff: TimeInterval = 1.0, + maximumBackoff: TimeInterval = 120.0, + multiplier: Double = 1.6, + jitter: Double = 0.2, + minimumConnectionTimeout: TimeInterval = 20.0, + retries: Retries = .unlimited + ) { + self.initialBackoff = initialBackoff + self.maximumBackoff = maximumBackoff + self.multiplier = multiplier + self.jitter = jitter + self.minimumConnectionTimeout = minimumConnectionTimeout + self.retries = retries + } + + public func makeIterator() -> ConnectionBackoff.Iterator { + return Iterator(connectionBackoff: self) + } +} + +/// An iterator for `ConnectionBackoff`. +public class ConnectionBackoffIterator: IteratorProtocol { + public typealias Element = (timeout: TimeInterval, backoff: TimeInterval) + + /// Creates a new connection backoff iterator with the given configuration. + public init(connectionBackoff: ConnectionBackoff) { + self.connectionBackoff = connectionBackoff + self.unjitteredBackoff = connectionBackoff.initialBackoff + + // Since the first backoff is `initialBackoff` it must be generated here instead of + // by `makeNextElement`. + let backoff = min(connectionBackoff.initialBackoff, connectionBackoff.maximumBackoff) + self.initialElement = self.makeElement(backoff: backoff) + } + + /// The configuration being used. + private var connectionBackoff: ConnectionBackoff + + /// The backoff in seconds, without jitter. + private var unjitteredBackoff: TimeInterval + + /// The first element to return. Since the first backoff is defined as `initialBackoff` we can't + /// compute it on-the-fly. + private var initialElement: Element? + + /// Returns the next pair of connection timeout and backoff (in that order) to use should the + /// connection attempt fail. + public func next() -> Element? { + // Should we make another element? + switch self.connectionBackoff.retries.limit { + // Always make a new element. + case .unlimited: + () + + // Use up one from our remaining limit. + case let .limited(limit) where limit > 0: + self.connectionBackoff.retries.limit = .limited(limit - 1) + + // limit must be <= 0, no new element. + case .limited: + return nil + } + + if let initial = self.initialElement { + self.initialElement = nil + return initial + } else { + return self.makeNextElement() + } + } + + /// Produces the next element to return. + private func makeNextElement() -> Element { + let unjittered = self.unjitteredBackoff * self.connectionBackoff.multiplier + self.unjitteredBackoff = min(unjittered, self.connectionBackoff.maximumBackoff) + + let backoff = self.jittered(value: self.unjitteredBackoff) + return self.makeElement(backoff: backoff) + } + + /// Make a timeout-backoff pair from the given backoff. The timeout is the `max` of the backoff + /// and `connectionBackoff.minimumConnectionTimeout`. + private func makeElement(backoff: TimeInterval) -> Element { + let timeout = max(backoff, self.connectionBackoff.minimumConnectionTimeout) + return (timeout, backoff) + } + + /// Adds 'jitter' to the given value. + private func jittered(value: TimeInterval) -> TimeInterval { + let lower = -self.connectionBackoff.jitter * value + let upper = self.connectionBackoff.jitter * value + return value + TimeInterval.random(in: lower ... upper) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionKeepalive.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionKeepalive.swift new file mode 100644 index 00000000..07a630f0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionKeepalive.swift @@ -0,0 +1,108 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if swift(>=5.6) +@preconcurrency import NIOCore +#else +import NIOCore +#endif // swift(>=5.6) + +/// Provides keepalive pings. +/// +/// The defaults are determined by the gRPC keepalive +/// [documentation] (https://github.com/grpc/grpc/blob/master/doc/keepalive.md). +public struct ClientConnectionKeepalive: Hashable, GRPCSendable { + /// The amount of time to wait before sending a keepalive ping. + public var interval: TimeAmount + + /// The amount of time to wait for an acknowledgment. + /// If it does not receive an acknowledgment within this time, it will close the connection + /// This value must be less than `interval` + public var timeout: TimeAmount + + /// Send keepalive pings even if there are no calls in flight. + public var permitWithoutCalls: Bool + + /// Maximum number of pings that can be sent when there is no data/header frame to be sent. + public var maximumPingsWithoutData: UInt + + /// If there are no data/header frames being received: + /// The minimum amount of time to wait between successive pings. + public var minimumSentPingIntervalWithoutData: TimeAmount + + public init( + interval: TimeAmount = .nanoseconds(Int64.max), + timeout: TimeAmount = .seconds(20), + permitWithoutCalls: Bool = false, + maximumPingsWithoutData: UInt = 2, + minimumSentPingIntervalWithoutData: TimeAmount = .minutes(5) + ) { + precondition(timeout < interval, "`timeout` must be less than `interval`") + self.interval = interval + self.timeout = timeout + self.permitWithoutCalls = permitWithoutCalls + self.maximumPingsWithoutData = maximumPingsWithoutData + self.minimumSentPingIntervalWithoutData = minimumSentPingIntervalWithoutData + } +} + +public struct ServerConnectionKeepalive: Hashable { + /// The amount of time to wait before sending a keepalive ping. + public var interval: TimeAmount + + /// The amount of time to wait for an acknowledgment. + /// If it does not receive an acknowledgment within this time, it will close the connection + /// This value must be less than `interval` + public var timeout: TimeAmount + + /// Send keepalive pings even if there are no calls in flight. + public var permitWithoutCalls: Bool + + /// Maximum number of pings that can be sent when there is no data/header frame to be sent. + public var maximumPingsWithoutData: UInt + + /// If there are no data/header frames being received: + /// The minimum amount of time to wait between successive pings. + public var minimumSentPingIntervalWithoutData: TimeAmount + + /// If there are no data/header frames being sent: + /// The minimum amount of time expected between receiving successive pings. + /// If the time between successive pings is less than this value, then the ping will be considered a bad ping from the peer. + /// Such a ping counts as a "ping strike". + public var minimumReceivedPingIntervalWithoutData: TimeAmount + + /// Maximum number of bad pings that the server will tolerate before sending an HTTP2 GOAWAY frame and closing the connection. + /// Setting it to `0` allows the server to accept any number of bad pings. + public var maximumPingStrikes: UInt + + public init( + interval: TimeAmount = .hours(2), + timeout: TimeAmount = .seconds(20), + permitWithoutCalls: Bool = false, + maximumPingsWithoutData: UInt = 2, + minimumSentPingIntervalWithoutData: TimeAmount = .minutes(5), + minimumReceivedPingIntervalWithoutData: TimeAmount = .minutes(5), + maximumPingStrikes: UInt = 2 + ) { + precondition(timeout < interval, "`timeout` must be less than `interval`") + self.interval = interval + self.timeout = timeout + self.permitWithoutCalls = permitWithoutCalls + self.maximumPingsWithoutData = maximumPingsWithoutData + self.minimumSentPingIntervalWithoutData = minimumSentPingIntervalWithoutData + self.minimumReceivedPingIntervalWithoutData = minimumReceivedPingIntervalWithoutData + self.maximumPingStrikes = maximumPingStrikes + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager+Delegates.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager+Delegates.swift new file mode 100644 index 00000000..c05b51f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager+Delegates.swift @@ -0,0 +1,94 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal protocol ConnectionManagerConnectivityDelegate { + /// The state of the connection changed. + /// + /// - Parameters: + /// - connectionManager: The connection manager reporting the change of state. + /// - oldState: The previous `ConnectivityState`. + /// - newState: The current `ConnectivityState`. + func connectionStateDidChange( + _ connectionManager: ConnectionManager, + from oldState: _ConnectivityState, + to newState: _ConnectivityState + ) + + /// The connection is quiescing. + /// + /// - Parameters: + /// - connectionManager: The connection manager whose connection is quiescing. + func connectionIsQuiescing(_ connectionManager: ConnectionManager) +} + +internal protocol ConnectionManagerHTTP2Delegate { + /// An HTTP/2 stream was closed. + /// + /// - Parameters: + /// - connectionManager: The connection manager reporting the closed stream. + func streamClosed(_ connectionManager: ConnectionManager) + + /// The connection received a SETTINGS frame containing SETTINGS_MAX_CONCURRENT_STREAMS. + /// + /// - Parameters: + /// - connectionManager: The connection manager which received the settings update. + /// - maxConcurrentStreams: The value of SETTINGS_MAX_CONCURRENT_STREAMS. + func receivedSettingsMaxConcurrentStreams( + _ connectionManager: ConnectionManager, + maxConcurrentStreams: Int + ) +} + +// This mirrors `ConnectivityState` (which is public API) but adds `Error` as associated data +// to a few cases. +internal enum _ConnectivityState: GRPCSendable { + case idle(Error?) + case connecting + case ready + case transientFailure(Error) + case shutdown + + /// Returns whether this state is the same as the other state (ignoring any associated data). + internal func isSameState(as other: _ConnectivityState) -> Bool { + switch (self, other) { + case (.idle, .idle), + (.connecting, .connecting), + (.ready, .ready), + (.transientFailure, .transientFailure), + (.shutdown, .shutdown): + return true + default: + return false + } + } +} + +extension ConnectivityState { + internal init(_ state: _ConnectivityState) { + switch state { + case .idle: + self = .idle + case .connecting: + self = .connecting + case .ready: + self = .ready + case .transientFailure: + self = .transientFailure + case .shutdown: + self = .shutdown + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager.swift new file mode 100644 index 00000000..899321df --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManager.swift @@ -0,0 +1,1025 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOConcurrencyHelpers +import NIOCore +import NIOHTTP2 + +#if compiler(>=5.6) +// Unchecked because mutable state is always accessed and modified on a particular event loop. +// APIs which _may_ be called from different threads execute onto the correct event loop first. +// APIs which _must_ be called from an exact event loop have preconditions checking that the correct +// event loop is being used. +extension ConnectionManager: @unchecked Sendable {} +#endif // compiler(>=5.6) + +@usableFromInline +internal final class ConnectionManager { + internal enum Reconnect { + case none + case after(TimeInterval) + } + + internal struct ConnectingState { + var backoffIterator: ConnectionBackoffIterator? + var reconnect: Reconnect + + var candidate: EventLoopFuture + var readyChannelMuxPromise: EventLoopPromise + var candidateMuxPromise: EventLoopPromise + } + + internal struct ConnectedState { + var backoffIterator: ConnectionBackoffIterator? + var reconnect: Reconnect + var candidate: Channel + var readyChannelMuxPromise: EventLoopPromise + var multiplexer: HTTP2StreamMultiplexer + var error: Error? + + init(from state: ConnectingState, candidate: Channel, multiplexer: HTTP2StreamMultiplexer) { + self.backoffIterator = state.backoffIterator + self.reconnect = state.reconnect + self.candidate = candidate + self.readyChannelMuxPromise = state.readyChannelMuxPromise + self.multiplexer = multiplexer + } + } + + internal struct ReadyState { + var channel: Channel + var multiplexer: HTTP2StreamMultiplexer + var error: Error? + + init(from state: ConnectedState) { + self.channel = state.candidate + self.multiplexer = state.multiplexer + } + } + + internal struct TransientFailureState { + var backoffIterator: ConnectionBackoffIterator? + var readyChannelMuxPromise: EventLoopPromise + var scheduled: Scheduled + var reason: Error + + init(from state: ConnectingState, scheduled: Scheduled, reason: Error) { + self.backoffIterator = state.backoffIterator + self.readyChannelMuxPromise = state.readyChannelMuxPromise + self.scheduled = scheduled + self.reason = reason + } + + init(from state: ConnectedState, scheduled: Scheduled) { + self.backoffIterator = state.backoffIterator + self.readyChannelMuxPromise = state.readyChannelMuxPromise + self.scheduled = scheduled + self.reason = state.error ?? GRPCStatus( + code: .unavailable, + message: "Unexpected connection drop" + ) + } + + init( + from state: ReadyState, + scheduled: Scheduled, + backoffIterator: ConnectionBackoffIterator? + ) { + self.backoffIterator = backoffIterator + self.readyChannelMuxPromise = state.channel.eventLoop.makePromise() + self.scheduled = scheduled + self.reason = state.error ?? GRPCStatus( + code: .unavailable, + message: "Unexpected connection drop" + ) + } + } + + internal struct ShutdownState { + var closeFuture: EventLoopFuture + /// The reason we are shutdown. Any requests for a `Channel` in this state will be failed with + /// this error. + var reason: Error + + init(closeFuture: EventLoopFuture, reason: Error) { + self.closeFuture = closeFuture + self.reason = reason + } + + static func shutdownByUser(closeFuture: EventLoopFuture) -> ShutdownState { + return ShutdownState( + closeFuture: closeFuture, + reason: GRPCStatus(code: .unavailable, message: "Connection was shutdown by the user") + ) + } + } + + internal enum State { + /// No `Channel` is required. + /// + /// Valid next states: + /// - `connecting` + /// - `shutdown` + case idle(lastError: Error?) + + /// We're actively trying to establish a connection. + /// + /// Valid next states: + /// - `active` + /// - `transientFailure` (if our attempt fails and we're going to try again) + /// - `shutdown` + case connecting(ConnectingState) + + /// We've established a `Channel`, it might not be suitable (TLS handshake may fail, etc.). + /// Our signal to be 'ready' is the initial HTTP/2 SETTINGS frame. + /// + /// Valid next states: + /// - `ready` + /// - `transientFailure` (if we our handshake fails or other error happens and we can attempt + /// to re-establish the connection) + /// - `shutdown` + case active(ConnectedState) + + /// We have an active `Channel` which has seen the initial HTTP/2 SETTINGS frame. We can use + /// the channel for making RPCs. + /// + /// Valid next states: + /// - `idle` (we're not serving any RPCs, we can drop the connection for now) + /// - `transientFailure` (we encountered an error and will re-establish the connection) + /// - `shutdown` + case ready(ReadyState) + + /// A `Channel` is desired, we'll attempt to create one in the future. + /// + /// Valid next states: + /// - `connecting` + /// - `shutdown` + case transientFailure(TransientFailureState) + + /// We never want another `Channel`: this state is terminal. + case shutdown(ShutdownState) + + fileprivate var label: String { + switch self { + case .idle: + return "idle" + case .connecting: + return "connecting" + case .active: + return "active" + case .ready: + return "ready" + case .transientFailure: + return "transientFailure" + case .shutdown: + return "shutdown" + } + } + } + + /// The last 'external' state we are in, a subset of the internal state. + private var externalState: _ConnectivityState = .idle(nil) + + /// Update the external state, potentially notifying a delegate about the change. + private func updateExternalState(to nextState: _ConnectivityState) { + if !self.externalState.isSameState(as: nextState) { + let oldState = self.externalState + self.externalState = nextState + self.connectivityDelegate?.connectionStateDidChange(self, from: oldState, to: nextState) + } + } + + /// Our current state. + private var state: State { + didSet { + switch self.state { + case let .idle(error): + self.updateExternalState(to: .idle(error)) + self.updateConnectionID() + + case .connecting: + self.updateExternalState(to: .connecting) + + // This is an internal state. + case .active: + () + + case .ready: + self.updateExternalState(to: .ready) + + case let .transientFailure(state): + self.updateExternalState(to: .transientFailure(state.reason)) + self.updateConnectionID() + + case .shutdown: + self.updateExternalState(to: .shutdown) + } + } + } + + /// Returns whether the state is 'idle'. + private var isIdle: Bool { + self.eventLoop.assertInEventLoop() + switch self.state { + case .idle: + return true + case .connecting, .transientFailure, .active, .ready, .shutdown: + return false + } + } + + /// Returns the `HTTP2StreamMultiplexer` from the 'ready' state or `nil` if it is not available. + private var multiplexer: HTTP2StreamMultiplexer? { + self.eventLoop.assertInEventLoop() + switch self.state { + case let .ready(state): + return state.multiplexer + + case .idle, .connecting, .transientFailure, .active, .shutdown: + return nil + } + } + + /// The `EventLoop` that the managed connection will run on. + internal let eventLoop: EventLoop + + /// A delegate for connectivity changes. Executed on the `EventLoop`. + private var connectivityDelegate: ConnectionManagerConnectivityDelegate? + + /// A delegate for HTTP/2 connection changes. Executed on the `EventLoop`. + private var http2Delegate: ConnectionManagerHTTP2Delegate? + + /// An `EventLoopFuture` provider. + private let channelProvider: ConnectionManagerChannelProvider + + /// The behavior for starting a call, i.e. how patient is the caller when asking for a + /// multiplexer. + private let callStartBehavior: CallStartBehavior.Behavior + + /// The configuration to use when backing off between connection attempts, if reconnection + /// attempts should be made at all. + private let connectionBackoff: ConnectionBackoff? + + /// A logger. + internal var logger: Logger + + private let connectionID: String + private var channelNumber: UInt64 + private var channelNumberLock = Lock() + + private var _connectionIDAndNumber: String { + return "\(self.connectionID)/\(self.channelNumber)" + } + + private var connectionIDAndNumber: String { + return self.channelNumberLock.withLock { + return self._connectionIDAndNumber + } + } + + private func updateConnectionID() { + self.channelNumberLock.withLockVoid { + self.channelNumber &+= 1 + self.logger[metadataKey: MetadataKey.connectionID] = "\(self._connectionIDAndNumber)" + } + } + + internal func appendMetadata(to logger: inout Logger) { + logger[metadataKey: MetadataKey.connectionID] = "\(self.connectionIDAndNumber)" + } + + internal convenience init( + configuration: ClientConnection.Configuration, + channelProvider: ConnectionManagerChannelProvider? = nil, + connectivityDelegate: ConnectionManagerConnectivityDelegate?, + logger: Logger + ) { + self.init( + eventLoop: configuration.eventLoopGroup.next(), + channelProvider: channelProvider ?? DefaultChannelProvider(configuration: configuration), + callStartBehavior: configuration.callStartBehavior.wrapped, + connectionBackoff: configuration.connectionBackoff, + connectivityDelegate: connectivityDelegate, + http2Delegate: nil, + logger: logger + ) + } + + internal init( + eventLoop: EventLoop, + channelProvider: ConnectionManagerChannelProvider, + callStartBehavior: CallStartBehavior.Behavior, + connectionBackoff: ConnectionBackoff?, + connectivityDelegate: ConnectionManagerConnectivityDelegate?, + http2Delegate: ConnectionManagerHTTP2Delegate?, + logger: Logger + ) { + // Setup the logger. + var logger = logger + let connectionID = UUID().uuidString + let channelNumber: UInt64 = 0 + logger[metadataKey: MetadataKey.connectionID] = "\(connectionID)/\(channelNumber)" + + self.eventLoop = eventLoop + self.state = .idle(lastError: nil) + + self.channelProvider = channelProvider + self.callStartBehavior = callStartBehavior + self.connectionBackoff = connectionBackoff + self.connectivityDelegate = connectivityDelegate + self.http2Delegate = http2Delegate + + self.connectionID = connectionID + self.channelNumber = channelNumber + self.logger = logger + } + + /// Get the multiplexer from the underlying channel handling gRPC calls. + /// if the `ConnectionManager` was configured to be `fastFailure` this will have + /// one chance to connect - if not reconnections are managed here. + internal func getHTTP2Multiplexer() -> EventLoopFuture { + func getHTTP2Multiplexer0() -> EventLoopFuture { + switch self.callStartBehavior { + case .waitsForConnectivity: + return self.getHTTP2MultiplexerPatient() + case .fastFailure: + return self.getHTTP2MultiplexerOptimistic() + } + } + + if self.eventLoop.inEventLoop { + return getHTTP2Multiplexer0() + } else { + return self.eventLoop.flatSubmit { + getHTTP2Multiplexer0() + } + } + } + + /// Returns a future for the multiplexer which succeeded when the channel is connected. + /// Reconnects are handled if necessary. + private func getHTTP2MultiplexerPatient() -> EventLoopFuture { + let multiplexer: EventLoopFuture + + switch self.state { + case .idle: + self.startConnecting() + // We started connecting so we must transition to the `connecting` state. + guard case let .connecting(connecting) = self.state else { + self.invalidState() + } + multiplexer = connecting.readyChannelMuxPromise.futureResult + + case let .connecting(state): + multiplexer = state.readyChannelMuxPromise.futureResult + + case let .active(state): + multiplexer = state.readyChannelMuxPromise.futureResult + + case let .ready(state): + multiplexer = self.eventLoop.makeSucceededFuture(state.multiplexer) + + case let .transientFailure(state): + multiplexer = state.readyChannelMuxPromise.futureResult + + case let .shutdown(state): + multiplexer = self.eventLoop.makeFailedFuture(state.reason) + } + + self.logger.debug("vending multiplexer future", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + + return multiplexer + } + + /// Returns a future for the current HTTP/2 stream multiplexer, or future HTTP/2 stream multiplexer from the current connection + /// attempt, or if the state is 'idle' returns the future for the next connection attempt. + /// + /// Note: if the state is 'transientFailure' or 'shutdown' then a failed future will be returned. + private func getHTTP2MultiplexerOptimistic() -> EventLoopFuture { + // `getHTTP2Multiplexer` makes sure we're on the event loop but let's just be sure. + self.eventLoop.preconditionInEventLoop() + + let muxFuture: EventLoopFuture = { () in + switch self.state { + case .idle: + self.startConnecting() + // We started connecting so we must transition to the `connecting` state. + guard case let .connecting(connecting) = self.state else { + self.invalidState() + } + return connecting.candidateMuxPromise.futureResult + case let .connecting(state): + return state.candidateMuxPromise.futureResult + case let .active(active): + return self.eventLoop.makeSucceededFuture(active.multiplexer) + case let .ready(ready): + return self.eventLoop.makeSucceededFuture(ready.multiplexer) + case let .transientFailure(state): + return self.eventLoop.makeFailedFuture(state.reason) + case let .shutdown(state): + return self.eventLoop.makeFailedFuture(state.reason) + } + }() + + self.logger.debug("vending fast-failing multiplexer future", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + return muxFuture + } + + @usableFromInline + internal enum ShutdownMode { + /// Closes the underlying channel without waiting for existing RPCs to complete. + case forceful + /// Allows running RPCs to run their course before closing the underlying channel. No new + /// streams may be created. + case graceful(NIODeadline) + } + + /// Shutdown the underlying connection. + /// + /// - Note: Initiating a `forceful` shutdown after a `graceful` shutdown has no effect. + internal func shutdown(mode: ShutdownMode) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.shutdown(mode: mode, promise: promise) + return promise.futureResult + } + + /// Shutdown the underlying connection. + /// + /// - Note: Initiating a `forceful` shutdown after a `graceful` shutdown has no effect. + internal func shutdown(mode: ShutdownMode, promise: EventLoopPromise) { + if self.eventLoop.inEventLoop { + self._shutdown(mode: mode, promise: promise) + } else { + self.eventLoop.execute { + self._shutdown(mode: mode, promise: promise) + } + } + } + + private func _shutdown(mode: ShutdownMode, promise: EventLoopPromise) { + self.logger.debug("shutting down connection", metadata: [ + "connectivity_state": "\(self.state.label)", + "shutdown.mode": "\(mode)", + ]) + + switch self.state { + // We don't have a channel and we don't want one, easy! + case .idle: + let shutdown: ShutdownState = .shutdownByUser(closeFuture: promise.futureResult) + self.state = .shutdown(shutdown) + promise.succeed(()) + + // We're mid-connection: the application doesn't have any 'ready' channels so we'll succeed + // the shutdown future and deal with any fallout from the connecting channel without the + // application knowing. + case let .connecting(state): + let shutdown: ShutdownState = .shutdownByUser(closeFuture: promise.futureResult) + self.state = .shutdown(shutdown) + + // Fail the ready channel mux promise: we're shutting down so even if we manage to successfully + // connect the application shouldn't have access to the channel or multiplexer. + state.readyChannelMuxPromise.fail(GRPCStatus(code: .unavailable, message: nil)) + state.candidateMuxPromise.fail(GRPCStatus(code: .unavailable, message: nil)) + + // Complete the shutdown promise when the connection attempt has completed. + state.candidate.whenComplete { + switch $0 { + case let .success(channel): + // In case we do successfully connect, close immediately. + channel.close(mode: .all, promise: nil) + promise.completeWith(channel.closeFuture.recoveringFromUncleanShutdown()) + + case .failure: + // We failed to connect, that's fine we still shutdown successfully. + promise.succeed(()) + } + } + + // We have an active channel but the application doesn't know about it yet. We'll do the same + // as for `.connecting`. + case let .active(state): + let shutdown: ShutdownState = .shutdownByUser(closeFuture: promise.futureResult) + self.state = .shutdown(shutdown) + + // Fail the ready channel mux promise: we're shutting down so even if we manage to successfully + // connect the application shouldn't have access to the channel or multiplexer. + state.readyChannelMuxPromise.fail(GRPCStatus(code: .unavailable, message: nil)) + // We have a channel, close it. We only create streams in the ready state so there's no need + // to quiesce here. + state.candidate.close(mode: .all, promise: nil) + promise.completeWith(state.candidate.closeFuture.recoveringFromUncleanShutdown()) + + // The channel is up and running: the application could be using it. We can close it and + // return the `closeFuture`. + case let .ready(state): + let shutdown: ShutdownState = .shutdownByUser(closeFuture: promise.futureResult) + self.state = .shutdown(shutdown) + + switch mode { + case .forceful: + // We have a channel, close it. + state.channel.close(mode: .all, promise: nil) + + case let .graceful(deadline): + // If we don't close by the deadline forcibly close the channel. + let scheduledForceClose = state.channel.eventLoop.scheduleTask(deadline: deadline) { + self.logger.info("shutdown timer expired, forcibly closing connection") + state.channel.close(mode: .all, promise: nil) + } + + // Cancel the force close if we close normally first. + state.channel.closeFuture.whenComplete { _ in + scheduledForceClose.cancel() + } + + // Tell the channel to quiesce. It will be picked up by the idle handler which will close + // the channel when all streams have been closed. + state.channel.pipeline.fireUserInboundEventTriggered(ChannelShouldQuiesceEvent()) + } + + // Complete the promise when we eventually close. + promise.completeWith(state.channel.closeFuture.recoveringFromUncleanShutdown()) + + // Like `.connecting` and `.active` the application does not have a `.ready` channel. We'll + // do the same but also cancel any scheduled connection attempts and deal with any fallout + // if we cancelled too late. + case let .transientFailure(state): + let shutdown: ShutdownState = .shutdownByUser(closeFuture: promise.futureResult) + self.state = .shutdown(shutdown) + + // Stop the creation of a new channel, if we can. If we can't then the task to + // `startConnecting()` will see our new `shutdown` state and ignore the request to connect. + state.scheduled.cancel() + + // Fail the ready channel mux promise: we're shutting down so even if we manage to successfully + // connect the application shouldn't should have access to the channel. + state.readyChannelMuxPromise.fail(shutdown.reason) + + // No active channel, so complete the shutdown promise now. + promise.succeed(()) + + // We're already shutdown; there's nothing to do. + case let .shutdown(state): + promise.completeWith(state.closeFuture) + } + } + + // MARK: - State changes from the channel handler. + + /// The channel caught an error. Hold on to it until the channel becomes inactive, it may provide + /// some context. + internal func channelError(_ error: Error) { + self.eventLoop.preconditionInEventLoop() + + switch self.state { + // Hitting an error in idle is a surprise, but not really something we do anything about. Either the + // error is channel fatal, in which case we'll see channelInactive soon (acceptable), or it's not, + // and future I/O will either fail fast or work. In either case, all we do is log this and move on. + case .idle: + self.logger.warning("ignoring unexpected error in idle", metadata: [ + MetadataKey.error: "\(error)", + ]) + + case .connecting: + self.connectionFailed(withError: error) + + case var .active(state): + state.error = error + self.state = .active(state) + + case var .ready(state): + state.error = error + self.state = .ready(state) + + // If we've already in one of these states, then additional errors aren't helpful to us. + case .transientFailure, .shutdown: + () + } + } + + /// The connecting channel became `active`. Must be called on the `EventLoop`. + internal func channelActive(channel: Channel, multiplexer: HTTP2StreamMultiplexer) { + self.eventLoop.preconditionInEventLoop() + self.logger.debug("activating connection", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + + switch self.state { + case let .connecting(connecting): + let connected = ConnectedState(from: connecting, candidate: channel, multiplexer: multiplexer) + self.state = .active(connected) + // Optimistic connections are happy this this level of setup. + connecting.candidateMuxPromise.succeed(multiplexer) + + // Application called shutdown before the channel become active; we should close it. + case .shutdown: + channel.close(mode: .all, promise: nil) + + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .idle: + self.invalidState() + + case .active: + self.invalidState() + + case .ready: + self.invalidState() + + case .transientFailure: + self.invalidState() + } + } + + /// An established channel (i.e. `active` or `ready`) has become inactive: should we reconnect? + /// Must be called on the `EventLoop`. + internal func channelInactive() { + self.eventLoop.preconditionInEventLoop() + self.logger.debug("deactivating connection", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + + switch self.state { + // The channel is `active` but not `ready`. Should we try again? + case let .active(active): + switch active.reconnect { + // No, shutdown instead. + case .none: + self.logger.debug("shutting down connection") + + let error = GRPCStatus( + code: .unavailable, + message: "The connection was dropped and connection re-establishment is disabled" + ) + + let shutdownState = ShutdownState( + closeFuture: self.eventLoop.makeSucceededFuture(()), + reason: error + ) + + self.state = .shutdown(shutdownState) + active.readyChannelMuxPromise.fail(error) + + // Yes, after some time. + case let .after(delay): + let scheduled = self.eventLoop.scheduleTask(in: .seconds(timeInterval: delay)) { + self.startConnecting() + } + self.logger.debug("scheduling connection attempt", metadata: ["delay_secs": "\(delay)"]) + self.state = .transientFailure(TransientFailureState(from: active, scheduled: scheduled)) + } + + // The channel was ready and working fine but something went wrong. Should we try to replace + // the channel? + case let .ready(ready): + // No, no backoff is configured. + if self.connectionBackoff == nil { + self.logger.debug("shutting down connection, no reconnect configured/remaining") + self.state = .shutdown( + ShutdownState( + closeFuture: ready.channel.closeFuture, + reason: GRPCStatus( + code: .unavailable, + message: "The connection was dropped and a reconnect was not configured" + ) + ) + ) + } else { + // Yes, start connecting now. We should go via `transientFailure`, however. + let scheduled = self.eventLoop.scheduleTask(in: .nanoseconds(0)) { + self.startConnecting() + } + self.logger.debug("scheduling connection attempt", metadata: ["delay": "0"]) + let backoffIterator = self.connectionBackoff?.makeIterator() + self.state = .transientFailure(TransientFailureState( + from: ready, + scheduled: scheduled, + backoffIterator: backoffIterator + )) + } + + // This is fine: we expect the channel to become inactive after becoming idle. + case .idle: + () + + // We're already shutdown, that's fine. + case .shutdown: + () + + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .connecting: + self.invalidState() + + case .transientFailure: + self.invalidState() + } + } + + /// The channel has become ready, that is, it has seen the initial HTTP/2 SETTINGS frame. Must be + /// called on the `EventLoop`. + internal func ready() { + self.eventLoop.preconditionInEventLoop() + self.logger.debug("connection ready", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + + switch self.state { + case let .active(connected): + self.state = .ready(ReadyState(from: connected)) + connected.readyChannelMuxPromise.succeed(connected.multiplexer) + + case .shutdown: + () + + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .idle: + self.invalidState() + + case .transientFailure: + self.invalidState() + + case .connecting: + self.invalidState() + + case .ready: + self.invalidState() + } + } + + /// No active RPCs are happening on 'ready' channel: close the channel for now. Must be called on + /// the `EventLoop`. + internal func idle() { + self.eventLoop.preconditionInEventLoop() + self.logger.debug("idling connection", metadata: [ + "connectivity_state": "\(self.state.label)", + ]) + + switch self.state { + case let .active(state): + // This state is reachable if the keepalive timer fires before we reach the ready state. + self.state = .idle(lastError: state.error) + state.readyChannelMuxPromise + .fail(GRPCStatus(code: .unavailable, message: "Idled before reaching ready state")) + + case let .ready(state): + self.state = .idle(lastError: state.error) + + case .shutdown: + // This is expected when the connection is closed by the user: when the channel becomes + // inactive and there are no outstanding RPCs, 'idle()' will be called instead of + // 'channelInactive()'. + () + + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .idle: + self.invalidState() + + case .connecting: + self.invalidState() + + case .transientFailure: + self.invalidState() + } + } + + internal func streamClosed() { + self.eventLoop.assertInEventLoop() + self.http2Delegate?.streamClosed(self) + } + + internal func maxConcurrentStreamsChanged(_ maxConcurrentStreams: Int) { + self.eventLoop.assertInEventLoop() + self.http2Delegate?.receivedSettingsMaxConcurrentStreams( + self, maxConcurrentStreams: maxConcurrentStreams + ) + } + + /// The connection has started quiescing: notify the connectivity monitor of this. + internal func beginQuiescing() { + self.eventLoop.assertInEventLoop() + self.connectivityDelegate?.connectionIsQuiescing(self) + } +} + +extension ConnectionManager { + // A connection attempt failed; we never established a connection. + private func connectionFailed(withError error: Error) { + self.eventLoop.preconditionInEventLoop() + + switch self.state { + case let .connecting(connecting): + // Should we reconnect? + switch connecting.reconnect { + // No, shutdown. + case .none: + self.logger.debug("shutting down connection, no reconnect configured/remaining") + self.state = .shutdown( + ShutdownState(closeFuture: self.eventLoop.makeSucceededFuture(()), reason: error) + ) + connecting.readyChannelMuxPromise.fail(error) + connecting.candidateMuxPromise.fail(error) + + // Yes, after a delay. + case let .after(delay): + self.logger.debug("scheduling connection attempt", metadata: ["delay": "\(delay)"]) + let scheduled = self.eventLoop.scheduleTask(in: .seconds(timeInterval: delay)) { + self.startConnecting() + } + self.state = .transientFailure( + TransientFailureState(from: connecting, scheduled: scheduled, reason: error) + ) + // Candidate mux users are not willing to wait. + connecting.candidateMuxPromise.fail(error) + } + + // The application must have called shutdown while we were trying to establish a connection + // which was doomed to fail anyway. That's fine, we can ignore this. + case .shutdown: + () + + // We can't fail to connect if we aren't trying. + // + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .idle: + self.invalidState() + + case .active: + self.invalidState() + + case .ready: + self.invalidState() + + case .transientFailure: + self.invalidState() + } + } +} + +extension ConnectionManager { + // Start establishing a connection: we can only do this from the `idle` and `transientFailure` + // states. Must be called on the `EventLoop`. + private func startConnecting() { + self.eventLoop.assertInEventLoop() + switch self.state { + case .idle: + let iterator = self.connectionBackoff?.makeIterator() + self.startConnecting( + backoffIterator: iterator, + muxPromise: self.eventLoop.makePromise() + ) + + case let .transientFailure(pending): + self.startConnecting( + backoffIterator: pending.backoffIterator, + muxPromise: pending.readyChannelMuxPromise + ) + + // We shutdown before a scheduled connection attempt had started. + case .shutdown: + () + + // These cases are purposefully separated: some crash reporting services provide stack traces + // which don't include the precondition failure message (which contain the invalid state we were + // in). Keeping the cases separate allows us work out the state from the line number. + case .connecting: + self.invalidState() + + case .active: + self.invalidState() + + case .ready: + self.invalidState() + } + } + + private func startConnecting( + backoffIterator: ConnectionBackoffIterator?, + muxPromise: EventLoopPromise + ) { + let timeoutAndBackoff = backoffIterator?.next() + + // We're already on the event loop: submit the connect so it starts after we've made the + // state change to `.connecting`. + self.eventLoop.assertInEventLoop() + + let candidate: EventLoopFuture = self.eventLoop.flatSubmit { + let channel: EventLoopFuture = self.channelProvider.makeChannel( + managedBy: self, + onEventLoop: self.eventLoop, + connectTimeout: timeoutAndBackoff.map { .seconds(timeInterval: $0.timeout) }, + logger: self.logger + ) + + channel.whenFailure { error in + self.connectionFailed(withError: error) + } + + return channel + } + + // Should we reconnect if the candidate channel fails? + let reconnect: Reconnect = timeoutAndBackoff.map { .after($0.backoff) } ?? .none + let connecting = ConnectingState( + backoffIterator: backoffIterator, + reconnect: reconnect, + candidate: candidate, + readyChannelMuxPromise: muxPromise, + candidateMuxPromise: self.eventLoop.makePromise() + ) + + self.state = .connecting(connecting) + } +} + +extension ConnectionManager { + /// Returns a synchronous view of the connection manager; each operation requires the caller to be + /// executing on the same `EventLoop` as the connection manager. + internal var sync: Sync { + return Sync(self) + } + + internal struct Sync { + private let manager: ConnectionManager + + fileprivate init(_ manager: ConnectionManager) { + self.manager = manager + } + + /// A delegate for connectivity changes. + internal var connectivityDelegate: ConnectionManagerConnectivityDelegate? { + get { + self.manager.eventLoop.assertInEventLoop() + return self.manager.connectivityDelegate + } + nonmutating set { + self.manager.eventLoop.assertInEventLoop() + self.manager.connectivityDelegate = newValue + } + } + + /// A delegate for HTTP/2 connection changes. + internal var http2Delegate: ConnectionManagerHTTP2Delegate? { + get { + self.manager.eventLoop.assertInEventLoop() + return self.manager.http2Delegate + } + nonmutating set { + self.manager.eventLoop.assertInEventLoop() + self.manager.http2Delegate = newValue + } + } + + /// Returns `true` if the connection is in the idle state. + internal var isIdle: Bool { + return self.manager.isIdle + } + + /// Returns the `multiplexer` from a connection in the `ready` state or `nil` if it is any + /// other state. + internal var multiplexer: HTTP2StreamMultiplexer? { + return self.manager.multiplexer + } + + // Start establishing a connection. Must only be called when `isIdle` is `true`. + internal func startConnecting() { + self.manager.startConnecting() + } + } +} + +extension ConnectionManager { + private func invalidState( + function: StaticString = #function, + file: StaticString = #file, + line: UInt = #line + ) -> Never { + preconditionFailure("Invalid state \(self.state) for \(function)", file: file, line: line) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManagerChannelProvider.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManagerChannelProvider.swift new file mode 100644 index 00000000..aaa6cf56 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionManagerChannelProvider.swift @@ -0,0 +1,225 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOPosix +#if canImport(NIOSSL) +import NIOSSL +#endif +import NIOTransportServices + +@usableFromInline +internal protocol ConnectionManagerChannelProvider { + /// Make an `EventLoopFuture`. + /// + /// - Parameters: + /// - connectionManager: The `ConnectionManager` requesting the `Channel`. + /// - eventLoop: The `EventLoop` to use for the`Channel`. + /// - connectTimeout: Optional connection timeout when starting the connection. + /// - logger: A logger. + func makeChannel( + managedBy connectionManager: ConnectionManager, + onEventLoop eventLoop: EventLoop, + connectTimeout: TimeAmount?, + logger: Logger + ) -> EventLoopFuture +} + +@usableFromInline +internal struct DefaultChannelProvider: ConnectionManagerChannelProvider { + @usableFromInline + enum TLSMode { + #if canImport(NIOSSL) + case configureWithNIOSSL(Result) + #endif // canImport(NIOSSL) + case configureWithNetworkFramework + case disabled + } + + @usableFromInline + internal var connectionTarget: ConnectionTarget + @usableFromInline + internal var connectionKeepalive: ClientConnectionKeepalive + @usableFromInline + internal var connectionIdleTimeout: TimeAmount + + @usableFromInline + internal var tlsMode: TLSMode + @usableFromInline + internal var tlsConfiguration: GRPCTLSConfiguration? + + @usableFromInline + internal var httpTargetWindowSize: Int + @usableFromInline + internal var httpMaxFrameSize: Int + + @usableFromInline + internal var errorDelegate: Optional + @usableFromInline + internal var debugChannelInitializer: Optional<(Channel) -> EventLoopFuture> + + @inlinable + internal init( + connectionTarget: ConnectionTarget, + connectionKeepalive: ClientConnectionKeepalive, + connectionIdleTimeout: TimeAmount, + tlsMode: TLSMode, + tlsConfiguration: GRPCTLSConfiguration?, + httpTargetWindowSize: Int, + httpMaxFrameSize: Int, + errorDelegate: ClientErrorDelegate?, + debugChannelInitializer: ((Channel) -> EventLoopFuture)? + ) { + self.connectionTarget = connectionTarget + self.connectionKeepalive = connectionKeepalive + self.connectionIdleTimeout = connectionIdleTimeout + + self.tlsMode = tlsMode + self.tlsConfiguration = tlsConfiguration + + self.httpTargetWindowSize = httpTargetWindowSize + self.httpMaxFrameSize = httpMaxFrameSize + + self.errorDelegate = errorDelegate + self.debugChannelInitializer = debugChannelInitializer + } + + internal init(configuration: ClientConnection.Configuration) { + // Making a `NIOSSLContext` is expensive and we should only do it (at most) once per TLS + // configuration. We do it now and store it in our `tlsMode` and surface any error during + // channel creation (we're limited by our API in when we can throw any error). + let tlsMode: TLSMode + + if let tlsConfiguration = configuration.tlsConfiguration { + if tlsConfiguration.isNetworkFrameworkTLSBackend { + tlsMode = .configureWithNetworkFramework + } else { + #if canImport(NIOSSL) + // The '!' is okay here, we have a `tlsConfiguration` (so we must be using TLS) and we know + // it's not backed by Network.framework, so it must be backed by NIOSSL. + tlsMode = .configureWithNIOSSL(Result { try tlsConfiguration.makeNIOSSLContext()! }) + #else + // TLS is configured, and we aren't using a Network.framework TLS backend, so we must be + // using NIOSSL, so we must be able to import it. + fatalError() + #endif // canImport(NIOSSL) + } + } else { + tlsMode = .disabled + } + + self.init( + connectionTarget: configuration.target, + connectionKeepalive: configuration.connectionKeepalive, + connectionIdleTimeout: configuration.connectionIdleTimeout, + tlsMode: tlsMode, + tlsConfiguration: configuration.tlsConfiguration, + httpTargetWindowSize: configuration.httpTargetWindowSize, + httpMaxFrameSize: configuration.httpMaxFrameSize, + errorDelegate: configuration.errorDelegate, + debugChannelInitializer: configuration.debugChannelInitializer + ) + } + + private var serverHostname: String? { + let hostname = self.tlsConfiguration?.hostnameOverride ?? self.connectionTarget.host + return hostname.isIPAddress ? nil : hostname + } + + private var hasTLS: Bool { + return self.tlsConfiguration != nil + } + + private func requiresZeroLengthWorkaround(eventLoop: EventLoop) -> Bool { + return PlatformSupport.requiresZeroLengthWriteWorkaround(group: eventLoop, hasTLS: self.hasTLS) + } + + @usableFromInline + internal func makeChannel( + managedBy connectionManager: ConnectionManager, + onEventLoop eventLoop: EventLoop, + connectTimeout: TimeAmount?, + logger: Logger + ) -> EventLoopFuture { + let hostname = self.serverHostname + let needsZeroLengthWriteWorkaround = self.requiresZeroLengthWorkaround(eventLoop: eventLoop) + + var bootstrap = PlatformSupport.makeClientBootstrap( + group: eventLoop, + tlsConfiguration: self.tlsConfiguration, + logger: logger + ) + + bootstrap = bootstrap + .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1) + .channelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + .channelInitializer { channel in + let sync = channel.pipeline.syncOperations + + do { + if needsZeroLengthWriteWorkaround { + try sync.addHandler(NIOFilterEmptyWritesHandler()) + } + + // We have a NIOSSL context to apply. If we're using TLS from NIOTS then the bootstrap + // will already have the TLS options applied. + switch self.tlsMode { + #if canImport(NIOSSL) + case let .configureWithNIOSSL(sslContext): + try sync.configureNIOSSLForGRPCClient( + sslContext: sslContext, + serverHostname: hostname, + customVerificationCallback: self.tlsConfiguration?.nioSSLCustomVerificationCallback, + logger: logger + ) + #endif // canImport(NIOSSL) + + // Network.framework TLS configuration is applied when creating the bootstrap so is a + // no-op here. + case .configureWithNetworkFramework, + .disabled: + () + } + + try sync.configureHTTP2AndGRPCHandlersForGRPCClient( + channel: channel, + connectionManager: connectionManager, + connectionKeepalive: self.connectionKeepalive, + connectionIdleTimeout: self.connectionIdleTimeout, + httpTargetWindowSize: self.httpTargetWindowSize, + httpMaxFrameSize: self.httpMaxFrameSize, + errorDelegate: self.errorDelegate, + logger: logger + ) + } catch { + return channel.eventLoop.makeFailedFuture(error) + } + + // Run the debug initializer, if there is one. + if let debugInitializer = self.debugChannelInitializer { + return debugInitializer(channel) + } else { + return channel.eventLoop.makeSucceededVoidFuture() + } + } + + if let connectTimeout = connectTimeout { + _ = bootstrap.connectTimeout(connectTimeout) + } + + return bootstrap.connect(to: self.connectionTarget) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionManagerID.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionManagerID.swift new file mode 100644 index 00000000..f5c78700 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionManagerID.swift @@ -0,0 +1,38 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@usableFromInline +internal struct ConnectionManagerID: Hashable, CustomStringConvertible { + @usableFromInline + internal let _id: ObjectIdentifier + + @usableFromInline + internal init(_ manager: ConnectionManager) { + self._id = ObjectIdentifier(manager) + } + + @usableFromInline + internal var description: String { + return String(describing: self._id) + } +} + +extension ConnectionManager { + @usableFromInline + internal var id: ConnectionManagerID { + return ConnectionManagerID(self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+PerConnectionState.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+PerConnectionState.swift new file mode 100644 index 00000000..c9be9edd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+PerConnectionState.swift @@ -0,0 +1,129 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOHTTP2 + +extension ConnectionPool { + @usableFromInline + internal struct PerConnectionState { + /// The connection manager for this connection. + @usableFromInline + internal var manager: ConnectionManager + + /// Stream availability for this connection, `nil` if the connection is not available. + @usableFromInline + internal var _availability: StreamAvailability? + + @usableFromInline + internal struct StreamAvailability { + @usableFromInline + var multiplexer: HTTP2StreamMultiplexer + /// Maximum number of available streams. + @usableFromInline + var maxAvailable: Int + /// Number of streams reserved. + @usableFromInline + var reserved: Int = 0 + /// Number of available streams. + @usableFromInline + var available: Int { + return self.maxAvailable - self.reserved + } + + /// Increment the reserved streams and return the multiplexer. + @usableFromInline + mutating func reserve() -> HTTP2StreamMultiplexer { + self.reserved += 1 + return self.multiplexer + } + + /// Decrement the reserved streams by one. + @usableFromInline + mutating func `return`() { + self.reserved -= 1 + assert(self.reserved >= 0) + } + } + + @usableFromInline + init(manager: ConnectionManager) { + self.manager = manager + self._availability = nil + } + + /// The number of reserved streams. + @usableFromInline + internal var reservedStreams: Int { + return self._availability?.reserved ?? 0 + } + + /// The number of streams available to reserve. If this value is greater than zero then it is + /// safe to call `reserveStream()` and force unwrap the result. + @usableFromInline + internal var availableStreams: Int { + return self._availability?.available ?? 0 + } + + /// The maximum number of concurrent streams which may be available for the connection, if it + /// is ready. + @usableFromInline + internal var maxAvailableStreams: Int? { + return self._availability?.maxAvailable + } + + /// Reserve a stream and return the stream multiplexer. Returns `nil` if it is not possible + /// to reserve a stream. + /// + /// The result may be safely unwrapped if `self.availableStreams > 0` when reserving a stream. + @usableFromInline + internal mutating func reserveStream() -> HTTP2StreamMultiplexer? { + return self._availability?.reserve() + } + + /// Return a reserved stream to the connection. + @usableFromInline + internal mutating func returnStream() { + self._availability?.return() + } + + /// Update the maximum concurrent streams available on the connection, marking it as available + /// if it was not already. + /// + /// Returns the previous value for max concurrent streams if the connection was ready. + @usableFromInline + internal mutating func updateMaxConcurrentStreams(_ maxConcurrentStreams: Int) -> Int? { + if var availability = self._availability { + var oldValue = maxConcurrentStreams + swap(&availability.maxAvailable, &oldValue) + self._availability = availability + return oldValue + } else { + self._availability = self.manager.sync.multiplexer.map { + StreamAvailability(multiplexer: $0, maxAvailable: maxConcurrentStreams) + } + return nil + } + } + + /// Mark the connection as unavailable returning the number of reserved streams. + @usableFromInline + internal mutating func unavailable() -> Int { + defer { + self._availability = nil + } + return self._availability?.reserved ?? 0 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+Waiter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+Waiter.swift new file mode 100644 index 00000000..b4b386f8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool+Waiter.swift @@ -0,0 +1,117 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHTTP2 + +extension ConnectionPool { + @usableFromInline + internal final class Waiter { + /// A promise to complete with the initialized channel. + @usableFromInline + internal let _promise: EventLoopPromise + + @usableFromInline + internal var _channelFuture: EventLoopFuture { + return self._promise.futureResult + } + + /// The channel initializer. + @usableFromInline + internal let _channelInitializer: (Channel) -> EventLoopFuture + + /// The deadline at which the timeout is scheduled. + @usableFromInline + internal let _deadline: NIODeadline + + /// A scheduled task which fails the stream promise should the pool not provide + /// a stream in time. + @usableFromInline + internal var _scheduledTimeout: Scheduled? + + /// An identifier for this waiter. + @usableFromInline + internal var id: ID { + return ID(self) + } + + @usableFromInline + internal init( + deadline: NIODeadline, + promise: EventLoopPromise, + channelInitializer: @escaping (Channel) -> EventLoopFuture + ) { + self._deadline = deadline + self._promise = promise + self._channelInitializer = channelInitializer + self._scheduledTimeout = nil + } + + /// Schedule a timeout for this waiter. This task will be cancelled when the waiter is + /// succeeded or failed. + /// + /// - Parameters: + /// - eventLoop: The `EventLoop` to run the timeout task on. + /// - body: The closure to execute when the timeout is fired. + @usableFromInline + internal func scheduleTimeout( + on eventLoop: EventLoop, + execute body: @escaping () -> Void + ) { + assert(self._scheduledTimeout == nil) + self._scheduledTimeout = eventLoop.scheduleTask(deadline: self._deadline, body) + } + + /// Returns a boolean value indicating whether the deadline for this waiter occurs after the + /// given deadline. + @usableFromInline + internal func deadlineIsAfter(_ other: NIODeadline) -> Bool { + return self._deadline > other + } + + /// Succeed the waiter with the given multiplexer. + @usableFromInline + internal func succeed(with multiplexer: HTTP2StreamMultiplexer) { + self._scheduledTimeout?.cancel() + self._scheduledTimeout = nil + multiplexer.createStreamChannel(promise: self._promise, self._channelInitializer) + } + + /// Fail the waiter with `error`. + @usableFromInline + internal func fail(_ error: Error) { + self._scheduledTimeout?.cancel() + self._scheduledTimeout = nil + self._promise.fail(error) + } + + /// The ID of a waiter. + @usableFromInline + internal struct ID: Hashable, CustomStringConvertible { + @usableFromInline + internal let _id: ObjectIdentifier + + @usableFromInline + internal init(_ waiter: Waiter) { + self._id = ObjectIdentifier(waiter) + } + + @usableFromInline + internal var description: String { + return String(describing: self._id) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool.swift new file mode 100644 index 00000000..0056500d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/ConnectionPool.swift @@ -0,0 +1,776 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOConcurrencyHelpers +import NIOCore +import NIOHTTP2 + +@usableFromInline +internal final class ConnectionPool { + /// The event loop all connections in this pool are running on. + @usableFromInline + internal let eventLoop: EventLoop + + @usableFromInline + internal enum State { + case active + case shuttingDown(EventLoopFuture) + case shutdown + } + + /// The state of the connection pool. + @usableFromInline + internal var _state: State = .active + + /// The most recent connection error we have observed. + /// + /// This error is used to provide additional context to failed waiters. A waiter may, for example, + /// timeout because the pool is busy, or because no connection can be established because of an + /// underlying connection error. In the latter case it's useful for the caller to know why the + /// connection is failing at the RPC layer. + /// + /// This value is cleared when a connection becomes 'available'. That is, when we receive an + /// http/2 SETTINGS frame. + /// + /// This value is set whenever an underlying connection transitions to the transient failure state + /// or to the idle state and has an associated error. + @usableFromInline + internal var _mostRecentError: Error? = nil + + /// Connection managers and their stream availability state keyed by the ID of the connection + /// manager. + /// + /// Connections are accessed by their ID for connection state changes (infrequent) and when + /// streams are closed (frequent). However when choosing which connection to succeed a waiter + /// with (frequent) requires the connections to be ordered by their availability. A dictionary + /// might not be the most efficient data structure (a queue prioritised by stream availability may + /// be a better choice given the number of connections is likely to be very low in practice). + @usableFromInline + internal var _connections: [ConnectionManagerID: PerConnectionState] + + /// The threshold which if exceeded when creating a stream determines whether the pool will + /// start connecting an idle connection (if one exists). + /// + /// The 'load' is calculated as the ratio of demand for streams (the sum of the number of waiters + /// and the number of reserved streams) and the total number of streams which non-idle connections + /// could support (this includes the streams that a connection in the connecting state could + /// support). + @usableFromInline + internal let reservationLoadThreshold: Double + + /// The assumed value for the maximum number of concurrent streams a connection can support. We + /// assume a connection will support this many streams until we know better. + @usableFromInline + internal let assumedMaxConcurrentStreams: Int + + /// A queue of waiters which may or may not get a stream in the future. + @usableFromInline + internal var waiters: CircularBuffer + + /// The maximum number of waiters allowed, the size of `waiters` must not exceed this value. If + /// there are this many waiters in the queue then the next waiter will be failed immediately. + @usableFromInline + internal let maxWaiters: Int + + /// Configuration for backoff between subsequence connection attempts. + @usableFromInline + internal let connectionBackoff: ConnectionBackoff + + /// Provides a channel factory to the `ConnectionManager`. + @usableFromInline + internal let channelProvider: ConnectionManagerChannelProvider + + /// The object to notify about changes to stream reservations; in practice this is usually + /// the `PoolManager`. + @usableFromInline + internal let streamLender: StreamLender + + /// A logger which always sets "GRPC" as its source. + @usableFromInline + internal let logger: GRPCLogger + + /// Returns `NIODeadline` representing 'now'. This is useful for testing. + @usableFromInline + internal let now: () -> NIODeadline + + /// Logging metadata keys. + @usableFromInline + internal enum Metadata { + /// The ID of this pool. + @usableFromInline + static let id = "pool.id" + /// The number of stream reservations (i.e. number of open streams + number of waiters). + @usableFromInline + static let reservationsCount = "pool.reservations.count" + /// The number of streams this pool can support with non-idle connections at this time. + @usableFromInline + static let reservationsCapacity = "pool.reservations.capacity" + /// The current reservation load (i.e. reservation count / reservation capacity) + @usableFromInline + static let reservationsLoad = "pool.reservations.load" + /// The reservation load threshold, above which a new connection will be created (if possible). + @usableFromInline + static let reservationsLoadThreshold = "pool.reservations.loadThreshold" + /// The current number of waiters in the pool. + @usableFromInline + static let waitersCount = "pool.waiters.count" + /// The maximum number of waiters the pool is configured to allow. + @usableFromInline + static let waitersMax = "pool.waiters.max" + /// The number of waiters which were successfully serviced. + @usableFromInline + static let waitersServiced = "pool.waiters.serviced" + /// The ID of waiter. + @usableFromInline + static let waiterID = "pool.waiter.id" + } + + @usableFromInline + init( + eventLoop: EventLoop, + maxWaiters: Int, + reservationLoadThreshold: Double, + assumedMaxConcurrentStreams: Int, + connectionBackoff: ConnectionBackoff, + channelProvider: ConnectionManagerChannelProvider, + streamLender: StreamLender, + logger: GRPCLogger, + now: @escaping () -> NIODeadline = NIODeadline.now + ) { + precondition( + (0.0 ... 1.0).contains(reservationLoadThreshold), + "reservationLoadThreshold must be within the range 0.0 ... 1.0" + ) + self.reservationLoadThreshold = reservationLoadThreshold + self.assumedMaxConcurrentStreams = assumedMaxConcurrentStreams + + self._connections = [:] + self.maxWaiters = maxWaiters + self.waiters = CircularBuffer(initialCapacity: 16) + + self.eventLoop = eventLoop + self.connectionBackoff = connectionBackoff + self.channelProvider = channelProvider + self.streamLender = streamLender + self.logger = logger + self.now = now + } + + /// Initialize the connection pool. + /// + /// - Parameter connections: The number of connections to add to the pool. + internal func initialize(connections: Int) { + assert(self._connections.isEmpty) + self._connections.reserveCapacity(connections) + while self._connections.count < connections { + self.addConnectionToPool() + } + } + + /// Make and add a new connection to the pool. + private func addConnectionToPool() { + let manager = ConnectionManager( + eventLoop: self.eventLoop, + channelProvider: self.channelProvider, + callStartBehavior: .waitsForConnectivity, + connectionBackoff: self.connectionBackoff, + connectivityDelegate: self, + http2Delegate: self, + logger: self.logger.unwrapped + ) + self._connections[manager.id] = PerConnectionState(manager: manager) + } + + // MARK: - Called from the pool manager + + /// Make and initialize an HTTP/2 stream `Channel`. + /// + /// - Parameters: + /// - deadline: The point in time by which the `promise` must have been resolved. + /// - promise: A promise for a `Channel`. + /// - logger: A request logger. + /// - initializer: A closure to initialize the `Channel` with. + @inlinable + internal func makeStream( + deadline: NIODeadline, + promise: EventLoopPromise, + logger: GRPCLogger, + initializer: @escaping (Channel) -> EventLoopFuture + ) { + if self.eventLoop.inEventLoop { + self._makeStream( + deadline: deadline, + promise: promise, + logger: logger, + initializer: initializer + ) + } else { + self.eventLoop.execute { + self._makeStream( + deadline: deadline, + promise: promise, + logger: logger, + initializer: initializer + ) + } + } + } + + /// See `makeStream(deadline:promise:logger:initializer:)`. + @inlinable + internal func makeStream( + deadline: NIODeadline, + logger: GRPCLogger, + initializer: @escaping (Channel) -> EventLoopFuture + ) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Channel.self) + self.makeStream(deadline: deadline, promise: promise, logger: logger, initializer: initializer) + return promise.futureResult + } + + /// Shutdown the connection pool. + /// + /// Existing waiters will be failed and all underlying connections will be shutdown. Subsequent + /// calls to `makeStream` will be failed immediately. + /// + /// - Parameter mode: The mode to use when shutting down. + /// - Returns: A future indicated when shutdown has been completed. + internal func shutdown(mode: ConnectionManager.ShutdownMode) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + + if self.eventLoop.inEventLoop { + self._shutdown(mode: mode, promise: promise) + } else { + self.eventLoop.execute { + self._shutdown(mode: mode, promise: promise) + } + } + + return promise.futureResult + } + + /// See `makeStream(deadline:promise:logger:initializer:)`. + /// + /// - Important: Must be called on the pool's `EventLoop`. + @inlinable + internal func _makeStream( + deadline: NIODeadline, + promise: EventLoopPromise, + logger: GRPCLogger, + initializer: @escaping (Channel) -> EventLoopFuture + ) { + self.eventLoop.assertInEventLoop() + + guard case .active = self._state else { + // Fail the promise right away if we're shutting down or already shut down. + promise.fail(ConnectionPoolError.shutdown) + return + } + + // Try to make a stream on an existing connection. + let streamCreated = self._tryMakeStream(promise: promise, initializer: initializer) + + if !streamCreated { + // No stream was created, wait for one. + self._enqueueWaiter( + deadline: deadline, + promise: promise, + logger: logger, + initializer: initializer + ) + } + } + + /// Try to find an existing connection on which we can make a stream. + /// + /// - Parameters: + /// - promise: A promise to succeed if we can make a stream. + /// - initializer: A closure to initialize the stream with. + /// - Returns: A boolean value indicating whether the stream was created or not. + @inlinable + internal func _tryMakeStream( + promise: EventLoopPromise, + initializer: @escaping (Channel) -> EventLoopFuture + ) -> Bool { + // We shouldn't jump the queue. + guard self.waiters.isEmpty else { + return false + } + + // Reserve a stream, if we can. + guard let multiplexer = self._reserveStreamFromMostAvailableConnection() else { + return false + } + + multiplexer.createStreamChannel(promise: promise, initializer) + + // Has reserving another stream tipped us over the limit for needing another connection? + if self._shouldBringUpAnotherConnection() { + self._startConnectingIdleConnection() + } + + return true + } + + /// Enqueue a waiter to be provided with a stream at some point in the future. + /// + /// - Parameters: + /// - deadline: The point in time by which the promise should have been completed. + /// - promise: The promise to complete with the `Channel`. + /// - logger: A logger. + /// - initializer: A closure to initialize the `Channel` with. + @inlinable + internal func _enqueueWaiter( + deadline: NIODeadline, + promise: EventLoopPromise, + logger: GRPCLogger, + initializer: @escaping (Channel) -> EventLoopFuture + ) { + // Don't overwhelm the pool with too many waiters. + guard self.waiters.count < self.maxWaiters else { + logger.trace("connection pool has too many waiters", metadata: [ + Metadata.waitersMax: "\(self.maxWaiters)", + ]) + promise.fail(ConnectionPoolError.tooManyWaiters(connectionError: self._mostRecentError)) + return + } + + let waiter = Waiter(deadline: deadline, promise: promise, channelInitializer: initializer) + + // Fail the waiter and punt it from the queue when it times out. It's okay that we schedule the + // timeout before appending it to the waiters, it wont run until the next event loop tick at the + // earliest (even if the deadline has already passed). + waiter.scheduleTimeout(on: self.eventLoop) { + waiter.fail(ConnectionPoolError.deadlineExceeded(connectionError: self._mostRecentError)) + + if let index = self.waiters.firstIndex(where: { $0.id == waiter.id }) { + self.waiters.remove(at: index) + + logger.trace("timed out waiting for a connection", metadata: [ + Metadata.waiterID: "\(waiter.id)", + Metadata.waitersCount: "\(self.waiters.count)", + ]) + } + } + + // request logger + logger.debug("waiting for a connection to become available", metadata: [ + Metadata.waiterID: "\(waiter.id)", + Metadata.waitersCount: "\(self.waiters.count)", + ]) + + self.waiters.append(waiter) + + // pool logger + self.logger.trace("enqueued connection waiter", metadata: [ + Metadata.waitersCount: "\(self.waiters.count)", + ]) + + if self._shouldBringUpAnotherConnection() { + self._startConnectingIdleConnection() + } + } + + /// Compute the current demand and capacity for streams. + /// + /// The 'demand' for streams is the number of reserved streams and the number of waiters. The + /// capacity for streams is the product of max concurrent streams and the number of non-idle + /// connections. + /// + /// - Returns: A tuple of the demand and capacity for streams. + @usableFromInline + internal func _computeStreamDemandAndCapacity() -> (demand: Int, capacity: Int) { + let demand = self.sync.reservedStreams + self.sync.waiters + + // TODO: make this cheaper by storing and incrementally updating the number of idle connections + let capacity = self._connections.values.reduce(0) { sum, state in + if state.manager.sync.isIdle { + // Idle connection, no capacity. + return sum + } else if let knownMaxAvailableStreams = state.maxAvailableStreams { + // A known value of max concurrent streams, i.e. the connection is active. + return sum + knownMaxAvailableStreams + } else { + // Not idle and no known value, the connection must be connecting so use our assumed value. + return sum + self.assumedMaxConcurrentStreams + } + } + + return (demand, capacity) + } + + /// Returns whether the pool should start connecting an idle connection (if one exists). + @usableFromInline + internal func _shouldBringUpAnotherConnection() -> Bool { + let (demand, capacity) = self._computeStreamDemandAndCapacity() + + // Infinite -- i.e. all connections are idle or no connections exist -- is okay here as it + // will always be greater than the threshold and a new connection will be spun up. + let load = Double(demand) / Double(capacity) + let loadExceedsThreshold = load >= self.reservationLoadThreshold + + if loadExceedsThreshold { + self.logger.debug( + "stream reservation load factor greater than or equal to threshold, bringing up additional connection if available", + metadata: [ + Metadata.reservationsCount: "\(demand)", + Metadata.reservationsCapacity: "\(capacity)", + Metadata.reservationsLoad: "\(load)", + Metadata.reservationsLoadThreshold: "\(self.reservationLoadThreshold)", + ] + ) + } + + return loadExceedsThreshold + } + + /// Starts connecting an idle connection, if one exists. + @usableFromInline + internal func _startConnectingIdleConnection() { + if let index = self._connections.values.firstIndex(where: { $0.manager.sync.isIdle }) { + self._connections.values[index].manager.sync.startConnecting() + } + } + + /// Returns the index in `self.connections.values` of the connection with the most available + /// streams. Returns `self.connections.endIndex` if no connection has at least one stream + /// available. + /// + /// - Note: this is linear in the number of connections. + @usableFromInline + internal func _mostAvailableConnectionIndex( + ) -> Dictionary.Index { + var index = self._connections.values.startIndex + var selectedIndex = self._connections.values.endIndex + var mostAvailableStreams = 0 + + while index != self._connections.values.endIndex { + let availableStreams = self._connections.values[index].availableStreams + if availableStreams > mostAvailableStreams { + mostAvailableStreams = availableStreams + selectedIndex = index + } + + self._connections.values.formIndex(after: &index) + } + + return selectedIndex + } + + /// Reserves a stream from the connection with the most available streams, if one exists. + /// + /// - Returns: The `HTTP2StreamMultiplexer` from the connection the stream was reserved from, + /// or `nil` if no stream could be reserved. + @usableFromInline + internal func _reserveStreamFromMostAvailableConnection() -> HTTP2StreamMultiplexer? { + let index = self._mostAvailableConnectionIndex() + + if index != self._connections.endIndex { + // '!' is okay here; the most available connection must have at least one stream available + // to reserve. + return self._connections.values[index].reserveStream()! + } else { + return nil + } + } + + /// See `shutdown(mode:)`. + /// + /// - Parameter promise: A `promise` to complete when the pool has been shutdown. + @usableFromInline + internal func _shutdown(mode: ConnectionManager.ShutdownMode, promise: EventLoopPromise) { + self.eventLoop.assertInEventLoop() + + switch self._state { + case .active: + self.logger.debug("shutting down connection pool") + + // We're shutting down now and when that's done we'll be fully shutdown. + self._state = .shuttingDown(promise.futureResult) + promise.futureResult.whenComplete { _ in + self._state = .shutdown + self.logger.trace("finished shutting down connection pool") + } + + // Shutdown all the connections and remove them from the pool. + let connections = self._connections + self._connections.removeAll() + + let allShutdown = connections.values.map { + $0.manager.shutdown(mode: mode) + } + + // Fail the outstanding waiters. + while let waiter = self.waiters.popFirst() { + waiter.fail(ConnectionPoolError.shutdown) + } + + // Cascade the result of the shutdown into the promise. + EventLoopFuture.andAllSucceed(allShutdown, promise: promise) + + case let .shuttingDown(future): + // We're already shutting down, cascade the result. + promise.completeWith(future) + + case .shutdown: + // Already shutdown, fine. + promise.succeed(()) + } + } +} + +extension ConnectionPool: ConnectionManagerConnectivityDelegate { + // We're interested in a few different situations here: + // + // 1. The connection was usable ('ready') and is no longer usable (either it became idle or + // encountered an error. If this happens we need to notify any connections of the change as + // they may no longer be used for new RPCs. + // 2. The connection was not usable but moved to a different unusable state. If this happens and + // we know the cause of the state transition (i.e. the error) then we need to update our most + // recent error with the error. This information is used when failing waiters to provide some + // context as to why they may be failing. + func connectionStateDidChange( + _ manager: ConnectionManager, + from oldState: _ConnectivityState, + to newState: _ConnectivityState + ) { + switch (oldState, newState) { + case let (.ready, .transientFailure(error)), + let (.ready, .idle(.some(error))): + self.updateMostRecentError(error) + self.connectionUnavailable(manager.id) + + case (.ready, .idle(.none)), + (.ready, .shutdown): + self.connectionUnavailable(manager.id) + + case let (_, .transientFailure(error)), + let (_, .idle(.some(error))): + self.updateMostRecentError(error) + + default: + () + } + } + + func connectionIsQuiescing(_ manager: ConnectionManager) { + self.eventLoop.assertInEventLoop() + guard let removed = self._connections.removeValue(forKey: manager.id) else { + return + } + + // Drop any delegates. We're no longer interested in these events. + removed.manager.sync.connectivityDelegate = nil + removed.manager.sync.http2Delegate = nil + + // Replace the connection with a new idle one. + self.addConnectionToPool() + + // Since we're removing this connection from the pool, the pool manager can ignore any streams + // reserved against this connection. + // + // Note: we don't need to adjust the number of available streams as the number of connections + // hasn't changed. + self.streamLender.returnStreams(removed.reservedStreams, to: self) + } + + private func updateMostRecentError(_ error: Error) { + self.eventLoop.assertInEventLoop() + // Update the last known error if there is one. We will use it to provide some context to + // waiters which may fail. + self._mostRecentError = error + } + + /// A connection has become unavailable. + private func connectionUnavailable(_ id: ConnectionManagerID) { + self.eventLoop.assertInEventLoop() + // The connection is no longer available: any streams which haven't been closed will be counted + // as a dropped reservation, we need to tell the pool manager about them. + if let droppedReservations = self._connections[id]?.unavailable(), droppedReservations > 0 { + self.streamLender.returnStreams(droppedReservations, to: self) + } + } +} + +extension ConnectionPool: ConnectionManagerHTTP2Delegate { + internal func streamClosed(_ manager: ConnectionManager) { + self.eventLoop.assertInEventLoop() + + // Return the stream the connection and to the pool manager. + self._connections[manager.id]?.returnStream() + self.streamLender.returnStreams(1, to: self) + + // A stream was returned: we may be able to service a waiter now. + self.tryServiceWaiters() + } + + internal func receivedSettingsMaxConcurrentStreams( + _ manager: ConnectionManager, + maxConcurrentStreams: Int + ) { + self.eventLoop.assertInEventLoop() + + // If we received a SETTINGS update then a connection is okay: drop the last known error. + self._mostRecentError = nil + + let previous = self._connections[manager.id]?.updateMaxConcurrentStreams(maxConcurrentStreams) + let delta: Int + + if let previousValue = previous { + // There was a previous value of max concurrent streams, i.e. a change in value for an + // existing connection. + delta = maxConcurrentStreams - previousValue + } else { + // There was no previous value so this must be a new connection. We'll compare against our + // assumed default. + delta = maxConcurrentStreams - self.assumedMaxConcurrentStreams + } + + if delta != 0 { + self.streamLender.changeStreamCapacity(by: delta, for: self) + } + + // We always check, even if `delta` isn't greater than zero as this might be a new connection. + self.tryServiceWaiters() + } +} + +extension ConnectionPool { + // MARK: - Waiters + + /// Try to service as many waiters as possible. + /// + /// This an expensive operation, in the worst case it will be `O(W ⨉ N)` where `W` is the number + /// of waiters and `N` is the number of connections. + private func tryServiceWaiters() { + if self.waiters.isEmpty { return } + + self.logger.trace("servicing waiters", metadata: [ + Metadata.waitersCount: "\(self.waiters.count)", + ]) + + let now = self.now() + var serviced = 0 + + while !self.waiters.isEmpty { + if self.waiters.first!.deadlineIsAfter(now) { + if let multiplexer = self._reserveStreamFromMostAvailableConnection() { + // The waiter's deadline is in the future, and we have a suitable connection. Remove and + // succeed the waiter. + let waiter = self.waiters.removeFirst() + serviced &+= 1 + waiter.succeed(with: multiplexer) + } else { + // There are waiters but no available connections, we're done. + break + } + } else { + // The waiter's deadline has already expired, there's no point completing it. Remove it and + // let its scheduled timeout fail the promise. + self.waiters.removeFirst() + } + } + + self.logger.trace("done servicing waiters", metadata: [ + Metadata.waitersCount: "\(self.waiters.count)", + Metadata.waitersServiced: "\(serviced)", + ]) + } +} + +extension ConnectionPool { + /// Synchronous operations for the pool, mostly used by tests. + internal struct Sync { + private let pool: ConnectionPool + + fileprivate init(_ pool: ConnectionPool) { + self.pool = pool + } + + /// The number of outstanding connection waiters. + internal var waiters: Int { + self.pool.eventLoop.assertInEventLoop() + return self.pool.waiters.count + } + + /// The number of connection currently in the pool (in any state). + internal var connections: Int { + self.pool.eventLoop.assertInEventLoop() + return self.pool._connections.count + } + + /// The number of idle connections in the pool. + internal var idleConnections: Int { + self.pool.eventLoop.assertInEventLoop() + return self.pool._connections.values.reduce(0) { $0 &+ ($1.manager.sync.isIdle ? 1 : 0) } + } + + /// The number of streams currently available to reserve across all connections in the pool. + internal var availableStreams: Int { + self.pool.eventLoop.assertInEventLoop() + return self.pool._connections.values.reduce(0) { $0 + $1.availableStreams } + } + + /// The number of streams which have been reserved across all connections in the pool. + internal var reservedStreams: Int { + self.pool.eventLoop.assertInEventLoop() + return self.pool._connections.values.reduce(0) { $0 + $1.reservedStreams } + } + } + + internal var sync: Sync { + return Sync(self) + } +} + +@usableFromInline +internal enum ConnectionPoolError: Error { + /// The pool is shutdown or shutting down. + case shutdown + + /// There are too many waiters in the pool. + case tooManyWaiters(connectionError: Error?) + + /// The deadline for creating a stream has passed. + case deadlineExceeded(connectionError: Error?) +} + +extension ConnectionPoolError: GRPCStatusTransformable { + @usableFromInline + internal func makeGRPCStatus() -> GRPCStatus { + switch self { + case .shutdown: + return GRPCStatus( + code: .unavailable, + message: "The connection pool is shutdown" + ) + + case let .tooManyWaiters(error): + return GRPCStatus( + code: .resourceExhausted, + message: "The connection pool has no capacity for new RPCs or RPC waiters", + cause: error + ) + + case let .deadlineExceeded(error): + return GRPCStatus( + code: .deadlineExceeded, + message: "Timed out waiting for an HTTP/2 stream from the connection pool", + cause: error + ) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/GRPCChannelPool.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/GRPCChannelPool.swift new file mode 100644 index 00000000..6338e6b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/GRPCChannelPool.swift @@ -0,0 +1,289 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if swift(>=5.6) +@preconcurrency import Logging +@preconcurrency import NIOCore +#else +import Logging +import NIOCore +#endif // swift(>=5.6) +import NIOPosix + +public enum GRPCChannelPool { + /// Make a new ``GRPCChannel`` on which calls may be made to gRPC services. + /// + /// The channel is backed by one connection pool per event loop, each of which may make multiple + /// connections to the given target. The size of the connection pool, and therefore the maximum + /// number of connections it may create at a given time is determined by the number of event loops + /// in the provided `EventLoopGroup` and the value of + /// ``GRPCChannelPool/Configuration/ConnectionPool-swift.struct/connectionsPerEventLoop``. + /// + /// The event loop and therefore connection chosen for a call is determined by + /// ``CallOptions/eventLoopPreference-swift.property``. If the `indifferent` preference is used + /// then the least-used event loop is chosen and a connection on that event loop will be selected. + /// If an `exact` preference is used then a connection on that event loop will be chosen provided + /// the given event loop belongs to the `EventLoopGroup` used to create this ``GRPCChannel``. + /// + /// Each connection in the pool is initially idle, and no connections will be established until + /// a call is made. The pool also closes connections after they have been inactive (i.e. are not + /// being used for calls) for some period of time. This is determined by + /// ``GRPCChannelPool/Configuration/idleTimeout``. + /// + /// > Important: The values of `transportSecurity` and `eventLoopGroup` **must** be compatible. + /// > + /// > For ``GRPCChannelPool/Configuration/TransportSecurity-swift.struct/tls(_:)`` the allowed + /// > `EventLoopGroup`s depends on the value of ``GRPCTLSConfiguration``. If a TLS configuration + /// > is known ahead of time, ``PlatformSupport/makeEventLoopGroup(compatibleWith:loopCount:)`` + /// > may be used to construct a compatible `EventLoopGroup`. + /// > + /// > If the `EventLoopGroup` is known ahead of time then a default TLS configuration may be + /// > constructed with ``GRPCTLSConfiguration/makeClientDefault(compatibleWith:)``. + /// > + /// > For ``GRPCChannelPool/Configuration/TransportSecurity-swift.struct/plaintext`` transport + /// > security both `MultiThreadedEventLoopGroup` and `NIOTSEventLoopGroup` (and `EventLoop`s + /// > from either) may be used. + /// + /// - Parameters: + /// - target: The target to connect to. + /// - transportSecurity: Transport layer security for connections. + /// - eventLoopGroup: The `EventLoopGroup` to run connections on. + /// - configure: A closure which may be used to modify defaulted configuration before + /// constructing the ``GRPCChannel``. + /// - Throws: If it is not possible to construct an SSL context. This will never happen when + /// using the ``GRPCChannelPool/Configuration/TransportSecurity-swift.struct/plaintext`` + /// transport security. + /// - Returns: A ``GRPCChannel``. + @inlinable + public static func with( + target: ConnectionTarget, + transportSecurity: GRPCChannelPool.Configuration.TransportSecurity, + eventLoopGroup: EventLoopGroup, + _ configure: (inout GRPCChannelPool.Configuration) -> Void = { _ in } + ) throws -> GRPCChannel { + let configuration = GRPCChannelPool.Configuration.with( + target: target, + transportSecurity: transportSecurity, + eventLoopGroup: eventLoopGroup, + configure + ) + + return try PooledChannel(configuration: configuration) + } + + /// See ``GRPCChannelPool/with(target:transportSecurity:eventLoopGroup:_:)``. + public static func with( + configuration: GRPCChannelPool.Configuration + ) throws -> GRPCChannel { + return try PooledChannel(configuration: configuration) + } +} + +extension GRPCChannelPool { + public struct Configuration: GRPCSendable { + @inlinable + internal init( + target: ConnectionTarget, + transportSecurity: TransportSecurity, + eventLoopGroup: EventLoopGroup + ) { + self.target = target + self.transportSecurity = transportSecurity + self.eventLoopGroup = eventLoopGroup + } + + // Note: we use `configure` blocks to avoid having to add new initializers when properties are + // added to the configuration while allowing the configuration to be constructed as a constant. + + /// Construct and configure a ``GRPCChannelPool/Configuration``. + /// + /// - Parameters: + /// - target: The target to connect to. + /// - transportSecurity: Transport layer security for connections. Note that the value of + /// `eventLoopGroup` must be compatible with the value + /// - eventLoopGroup: The `EventLoopGroup` to run connections on. + /// - configure: A closure which may be used to modify defaulted configuration. + @inlinable + public static func with( + target: ConnectionTarget, + transportSecurity: TransportSecurity, + eventLoopGroup: EventLoopGroup, + _ configure: (inout Configuration) -> Void = { _ in } + ) -> Configuration { + var configuration = Configuration( + target: target, + transportSecurity: transportSecurity, + eventLoopGroup: eventLoopGroup + ) + configure(&configuration) + return configuration + } + + /// The target to connect to. + public var target: ConnectionTarget + + /// Connection security. + public var transportSecurity: TransportSecurity + + /// The `EventLoopGroup` used by the connection pool. + public var eventLoopGroup: EventLoopGroup + + /// Connection pool configuration. + public var connectionPool: ConnectionPool = .defaults + + /// HTTP/2 configuration. + public var http2: HTTP2 = .defaults + + /// The connection backoff configuration. + public var connectionBackoff = ConnectionBackoff() + + /// The amount of time to wait before closing the connection. The idle timeout will start only + /// if there are no RPCs in progress and will be cancelled as soon as any RPCs start. + /// + /// If a connection becomes idle, starting a new RPC will automatically create a new connection. + public var idleTimeout = TimeAmount.minutes(30) + + /// The connection keepalive configuration. + public var keepalive = ClientConnectionKeepalive() + + /// The maximum size in bytes of a message which may be received from a server. Defaults to 4MB. + /// + /// Any received messages whose size exceeds this limit will cause RPCs to fail with + /// a `.resourceExhausted` status code. + public var maximumReceiveMessageLength: Int = 4 * 1024 * 1024 { + willSet { + precondition(newValue >= 0, "maximumReceiveMessageLength must be positive") + } + } + + /// A channel initializer which will be run after gRPC has initialized each `NIOCore.Channel`. + /// This may be used to add additional handlers to the pipeline and is intended for debugging. + /// + /// - Warning: The initializer closure may be invoked *multiple times*. + public var debugChannelInitializer: GRPCChannelInitializer? + + /// An error delegate which is called when errors are caught. + public var errorDelegate: ClientErrorDelegate? + + /// A logger used for background activity, such as connection state changes. + public var backgroundActivityLogger = Logger( + label: "io.grpc", + factory: { _ in + return SwiftLogNoOpLogHandler() + } + ) + } +} + +extension GRPCChannelPool.Configuration { + public struct TransportSecurity: GRPCSendable { + private init(_ configuration: GRPCTLSConfiguration?) { + self.tlsConfiguration = configuration + } + + /// The TLS configuration used. A `nil` value means that no TLS will be used and + /// communication at the transport layer will be plaintext. + public var tlsConfiguration: Optional + + /// Secure the transport layer with TLS. + /// + /// The TLS backend used depends on the value of `configuration`. See ``GRPCTLSConfiguration`` + /// for more details. + /// + /// > Important: the value of `configuration` **must** be compatible with + /// > ``GRPCChannelPool/Configuration/eventLoopGroup``. See the documentation of + /// > ``GRPCChannelPool/with(target:transportSecurity:eventLoopGroup:_:)`` for more details. + public static func tls(_ configuration: GRPCTLSConfiguration) -> TransportSecurity { + return TransportSecurity(configuration) + } + + /// Insecure plaintext communication. + public static let plaintext = TransportSecurity(nil) + } +} + +extension GRPCChannelPool.Configuration { + public struct HTTP2: Hashable, GRPCSendable { + private static let allowedTargetWindowSizes = (1 ... Int(Int32.max)) + private static let allowedMaxFrameSizes = (1 << 14) ... ((1 << 24) - 1) + + /// Default HTTP/2 configuration. + public static let defaults = HTTP2() + + @inlinable + public static func with(_ configure: (inout HTTP2) -> Void) -> HTTP2 { + var configuration = Self.defaults + configure(&configuration) + return configuration + } + + /// The HTTP/2 max frame size. Defaults to 8MB. Values are clamped between 2^14 and 2^24-1 + /// octets inclusive (RFC 7540 § 4.2). + public var targetWindowSize = 8 * 1024 * 1024 { + didSet { + self.targetWindowSize = self.targetWindowSize.clamped(to: Self.allowedTargetWindowSizes) + } + } + + /// The HTTP/2 max frame size. Defaults to 16384. Value is clamped between 2^14 and 2^24-1 + /// octets inclusive (the minimum and maximum allowable values - HTTP/2 RFC 7540 4.2). + public var maxFrameSize: Int = 16384 { + didSet { + self.maxFrameSize = self.maxFrameSize.clamped(to: Self.allowedMaxFrameSizes) + } + } + } +} + +extension GRPCChannelPool.Configuration { + public struct ConnectionPool: Hashable, GRPCSendable { + /// Default connection pool configuration. + public static let defaults = ConnectionPool() + + @inlinable + public static func with(_ configure: (inout ConnectionPool) -> Void) -> ConnectionPool { + var configuration = Self.defaults + configure(&configuration) + return configuration + } + + /// The maximum number of connections per `EventLoop` that may be created at a given time. + /// + /// Defaults to 1. + public var connectionsPerEventLoop: Int = 1 + + /// The maximum number of callers which may be waiting for a stream at any given time on a + /// given `EventLoop`. + /// + /// Any requests for a stream which would cause this limit to be exceeded will be failed + /// immediately. + /// + /// Defaults to 100. + public var maxWaitersPerEventLoop: Int = 100 + + /// The maximum amount of time a caller is willing to wait for a stream for before timing out. + /// + /// Defaults to 30 seconds. + public var maxWaitTime: TimeAmount = .seconds(30) + + /// The threshold which, if exceeded, when creating a stream determines whether the pool will + /// establish another connection (if doing so will not violate ``connectionsPerEventLoop``). + /// + /// The 'load' is calculated as the ratio of demand for streams (the sum of the number of + /// waiters and the number of reserved streams) and the total number of streams which each + /// thread _could support. + public var reservationLoadThreshold: Double = 0.9 + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManager.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManager.swift new file mode 100644 index 00000000..961f377e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManager.swift @@ -0,0 +1,368 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOConcurrencyHelpers +import NIOCore + +#if compiler(>=5.6) +// Unchecked because all mutable state is protected by a lock. +extension PooledChannel: @unchecked Sendable {} +#endif // compiler(>=5.6) + +@usableFromInline +internal final class PoolManager { + /// Configuration used for each connection pool. + @usableFromInline + internal struct PerPoolConfiguration { + /// The maximum number of connections per pool. + @usableFromInline + var maxConnections: Int + + /// The maximum number of waiters per pool. + @usableFromInline + var maxWaiters: Int + + /// A load threshold in the range `0.0 ... 1.0` beyond which another connection will be started + /// (assuming there is a connection available to start). + @usableFromInline + var loadThreshold: Double + + /// The assumed value of HTTP/2 'SETTINGS_MAX_CONCURRENT_STREAMS'. + @usableFromInline + var assumedMaxConcurrentStreams: Int + + /// The assumed maximum number of streams concurrently available in the pool. + @usableFromInline + var assumedStreamCapacity: Int { + return self.maxConnections * self.assumedMaxConcurrentStreams + } + + @usableFromInline + var connectionBackoff: ConnectionBackoff + + /// A `Channel` provider. + @usableFromInline + var channelProvider: DefaultChannelProvider + + @usableFromInline + internal init( + maxConnections: Int, + maxWaiters: Int, + loadThreshold: Double, + assumedMaxConcurrentStreams: Int = 100, + connectionBackoff: ConnectionBackoff, + channelProvider: DefaultChannelProvider + ) { + self.maxConnections = maxConnections + self.maxWaiters = maxWaiters + self.loadThreshold = loadThreshold + self.assumedMaxConcurrentStreams = assumedMaxConcurrentStreams + self.connectionBackoff = connectionBackoff + self.channelProvider = channelProvider + } + } + + /// Logging metadata keys + private enum Metadata { + /// The ID of the pool manager. + static let id = "poolmanager.id" + /// The number of managed connection pools. + static let poolCount = "poolmanager.pools.count" + /// The maximum number of connections per pool. + static let connectionsPerPool = "poolmanager.pools.conns_per_pool" + /// The maximum number of waiters per pool. + static let waitersPerPool = "poolmanager.pools.waiters_per_pool" + } + + /// The current state of the pool manager, `lock` must be held when accessing or + /// modifying `state`. + @usableFromInline + internal var _state: PoolManagerStateMachine + + @usableFromInline + internal var _pools: [ConnectionPool] + + @usableFromInline + internal let lock = Lock() + + /// The `EventLoopGroup` providing `EventLoop`s for connection pools. Once initialized the manager + /// will hold as many pools as there are loops in this `EventLoopGroup`. + @usableFromInline + internal let group: EventLoopGroup + + /// Make a new pool manager and initialize it. + /// + /// The pool manager manages one connection pool per event loop in the provided `EventLoopGroup`. + /// Each connection pool is configured using the `perPoolConfiguration`. + /// + /// - Parameters: + /// - group: The `EventLoopGroup` providing `EventLoop`s to connections managed by the pool + /// manager. + /// - perPoolConfiguration: Configuration used by each connection pool managed by the manager. + /// - logger: A logger. + /// - Returns: An initialized pool manager. + @usableFromInline + internal static func makeInitializedPoolManager( + using group: EventLoopGroup, + perPoolConfiguration: PerPoolConfiguration, + logger: GRPCLogger + ) -> PoolManager { + let manager = PoolManager(privateButUsableFromInline_group: group) + manager.initialize(perPoolConfiguration: perPoolConfiguration, logger: logger) + return manager + } + + @usableFromInline + internal init(privateButUsableFromInline_group group: EventLoopGroup) { + self._state = PoolManagerStateMachine(.inactive) + self._pools = [] + self.group = group + + // The pool relies on the identity of each `EventLoop` in the `EventLoopGroup` being unique. In + // practice this is unlikely to happen unless a custom `EventLoopGroup` is constructed, because + // of that we'll only check when running in debug mode. + debugOnly { + let eventLoopIDs = group.makeIterator().map { ObjectIdentifier($0) } + let uniqueEventLoopIDs = Set(eventLoopIDs) + assert( + eventLoopIDs.count == uniqueEventLoopIDs.count, + "'group' contains non-unique event loops" + ) + } + } + + deinit { + self.lock.withLockVoid { + assert( + self._state.isShutdownOrShuttingDown, + "The pool manager (\(ObjectIdentifier(self))) must be shutdown before going out of scope." + ) + } + } + + /// Initialize the pool manager, create and initialize one connection pool per event loop in the + /// pools `EventLoopGroup`. + /// + /// - Important: Must only be called once. + /// - Parameters: + /// - configuration: The configuration used for each connection pool. + /// - logger: A logger. + private func initialize( + perPoolConfiguration configuration: PerPoolConfiguration, + logger: GRPCLogger + ) { + var logger = logger + logger[metadataKey: Metadata.id] = "\(ObjectIdentifier(self))" + + let pools = self.makePools(perPoolConfiguration: configuration, logger: logger) + + logger.debug("initializing connection pool manager", metadata: [ + Metadata.poolCount: "\(pools.count)", + Metadata.connectionsPerPool: "\(configuration.maxConnections)", + Metadata.waitersPerPool: "\(configuration.maxWaiters)", + ]) + + // The assumed maximum number of streams concurrently available in each pool. + let assumedCapacity = configuration.assumedStreamCapacity + + // The state machine stores the per-pool state keyed by the pools `EventLoopID` and tells the + // pool manager about which pool to use/operate via the pools index in `self.pools`. + let poolKeys = pools.indices.map { index in + return ConnectionPoolKey( + index: ConnectionPoolIndex(index), + eventLoopID: pools[index].eventLoop.id + ) + } + + self.lock.withLockVoid { + assert(self._pools.isEmpty) + self._pools = pools + + // We'll blow up if we've already been initialized, that's fine, we don't allow callers to + // call `initialize` directly. + self._state.activatePools(keyedBy: poolKeys, assumingPerPoolCapacity: assumedCapacity) + } + + for pool in pools { + pool.initialize(connections: configuration.maxConnections) + } + } + + /// Make one pool per `EventLoop` in the pool's `EventLoopGroup`. + /// - Parameters: + /// - configuration: The configuration to make each pool with. + /// - logger: A logger. + /// - Returns: An array of `ConnectionPool`s. + private func makePools( + perPoolConfiguration configuration: PerPoolConfiguration, + logger: GRPCLogger + ) -> [ConnectionPool] { + let eventLoops = self.group.makeIterator() + return eventLoops.map { eventLoop in + // We're creating a retain cycle here as each pool will reference the manager and the per-pool + // state will hold the pool which will in turn be held by the pool manager. That's okay: when + // the pool is shutdown the per-pool state and in turn each connection pool will be dropped. + // and we'll break the cycle. + return ConnectionPool( + eventLoop: eventLoop, + maxWaiters: configuration.maxWaiters, + reservationLoadThreshold: configuration.loadThreshold, + assumedMaxConcurrentStreams: configuration.assumedMaxConcurrentStreams, + connectionBackoff: configuration.connectionBackoff, + channelProvider: configuration.channelProvider, + streamLender: self, + logger: logger + ) + } + } + + // MARK: Stream Creation + + /// A future for a `Channel` from a managed connection pool. The `eventLoop` indicates the loop + /// that the `Channel` is running on and therefore which event loop the RPC will use for its + /// transport. + @usableFromInline + internal struct PooledStreamChannel { + @inlinable + internal init(futureResult: EventLoopFuture) { + self.futureResult = futureResult + } + + /// The future `Channel`. + @usableFromInline + var futureResult: EventLoopFuture + + /// The `EventLoop` that the `Channel` is using. + @usableFromInline + var eventLoop: EventLoop { + return self.futureResult.eventLoop + } + } + + /// Make a stream and initialize it. + /// + /// - Parameters: + /// - preferredEventLoop: The `EventLoop` that the stream should be created on, if possible. If + /// a pool exists running this `EventLoop` then it will be chosen over all other pools, + /// irregardless of the load on the pool. If no pool exists on the preferred `EventLoop` or + /// no preference is given then the pool with the most streams available will be selected. + /// The `EventLoop` of the selected pool will be the same as the `EventLoop` of + /// the `EventLoopFuture` returned from this call. + /// - deadline: The point in time by which the stream must have been selected. If this deadline + /// is passed then the returned `EventLoopFuture` will be failed. + /// - logger: A logger. + /// - initializer: A closure to initialize the `Channel` with. + /// - Returns: A `PoolStreamChannel` indicating the future channel and `EventLoop` as that the + /// `Channel` is using. The future will be failed if the pool manager has been shutdown, + /// the deadline has passed before a stream was created or if the selected connection pool + /// is unable to create a stream (if there is too much demand on that pool, for example). + @inlinable + internal func makeStream( + preferredEventLoop: EventLoop?, + deadline: NIODeadline, + logger: GRPCLogger, + streamInitializer initializer: @escaping (Channel) -> EventLoopFuture + ) -> PooledStreamChannel { + let preferredEventLoopID = preferredEventLoop.map { EventLoopID($0) } + let reservedPool = self.lock.withLock { + return self._state.reserveStream(preferringPoolWithEventLoopID: preferredEventLoopID).map { + return self._pools[$0.value] + } + } + + switch reservedPool { + case let .success(pool): + let channel = pool.makeStream(deadline: deadline, logger: logger, initializer: initializer) + return PooledStreamChannel(futureResult: channel) + + case let .failure(error): + let eventLoop = preferredEventLoop ?? self.group.next() + return PooledStreamChannel(futureResult: eventLoop.makeFailedFuture(error)) + } + } + + // MARK: Shutdown + + /// Shutdown the pool manager and all connection pools it manages. + @usableFromInline + internal func shutdown(mode: ConnectionManager.ShutdownMode, promise: EventLoopPromise) { + let (action, pools): (PoolManagerStateMachine.ShutdownAction, [ConnectionPool]?) = self.lock + .withLock { + let action = self._state.shutdown(promise: promise) + + switch action { + case .shutdownPools: + // Clear out the pools; we need to shut them down. + let pools = self._pools + self._pools.removeAll(keepingCapacity: true) + return (action, pools) + + case .alreadyShutdown, .alreadyShuttingDown: + return (action, nil) + } + } + + switch (action, pools) { + case let (.shutdownPools, .some(pools)): + promise.futureResult.whenComplete { _ in self.shutdownComplete() } + EventLoopFuture.andAllSucceed(pools.map { $0.shutdown(mode: mode) }, promise: promise) + + case let (.alreadyShuttingDown(future), .none): + promise.completeWith(future) + + case (.alreadyShutdown, .none): + promise.succeed(()) + + case (.shutdownPools, .none), + (.alreadyShuttingDown, .some), + (.alreadyShutdown, .some): + preconditionFailure() + } + } + + private func shutdownComplete() { + self.lock.withLockVoid { + self._state.shutdownComplete() + } + } +} + +// MARK: - Connection Pool to Pool Manager + +extension PoolManager: StreamLender { + @usableFromInline + internal func returnStreams(_ count: Int, to pool: ConnectionPool) { + self.lock.withLockVoid { + self._state.returnStreams(count, toPoolOnEventLoopWithID: pool.eventLoop.id) + } + } + + @usableFromInline + internal func changeStreamCapacity(by delta: Int, for pool: ConnectionPool) { + self.lock.withLockVoid { + self._state.changeStreamCapacity(by: delta, forPoolOnEventLoopWithID: pool.eventLoop.id) + } + } +} + +@usableFromInline +internal enum PoolManagerError: Error { + /// The pool manager has not been initialized yet. + case notInitialized + + /// The pool manager has been shutdown or is in the process of shutting down. + case shutdown +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine+PerPoolState.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine+PerPoolState.swift new file mode 100644 index 00000000..011038ad --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine+PerPoolState.swift @@ -0,0 +1,107 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +extension PoolManagerStateMachine.ActiveState { + @usableFromInline + internal struct PerPoolState { + /// The index of the connection pool associated with this state. + @usableFromInline + internal var poolIndex: PoolManager.ConnectionPoolIndex + + /// The number of streams reserved in the pool. + @usableFromInline + internal private(set) var reservedStreams: Int + + /// The total number of streams which may be available in the pool. + @usableFromInline + internal var maxAvailableStreams: Int + + /// The number of available streams. + @usableFromInline + internal var availableStreams: Int { + return self.maxAvailableStreams - self.reservedStreams + } + + @usableFromInline + init(poolIndex: PoolManager.ConnectionPoolIndex, assumedMaxAvailableStreams: Int) { + self.poolIndex = poolIndex + self.reservedStreams = 0 + self.maxAvailableStreams = assumedMaxAvailableStreams + } + + /// Reserve a stream and return the pool. + @usableFromInline + internal mutating func reserveStream() -> PoolManager.ConnectionPoolIndex { + self.reservedStreams += 1 + return self.poolIndex + } + + /// Return a reserved stream. + @usableFromInline + internal mutating func returnReservedStreams(_ count: Int) { + self.reservedStreams -= count + assert(self.reservedStreams >= 0) + } + } +} + +extension PoolManager { + @usableFromInline + internal struct ConnectionPoolIndex: Hashable { + @usableFromInline + var value: Int + + @usableFromInline + init(_ value: Int) { + self.value = value + } + } + + @usableFromInline + internal struct ConnectionPoolKey: Hashable { + /// The index of the connection pool. + @usableFromInline + var index: ConnectionPoolIndex + + /// The ID of the`EventLoop` the connection pool uses. + @usableFromInline + var eventLoopID: EventLoopID + } +} + +@usableFromInline +internal struct EventLoopID: Hashable, CustomStringConvertible { + @usableFromInline + internal let _id: ObjectIdentifier + + @usableFromInline + internal init(_ eventLoop: EventLoop) { + self._id = ObjectIdentifier(eventLoop) + } + + @usableFromInline + internal var description: String { + return String(describing: self._id) + } +} + +extension EventLoop { + @usableFromInline + internal var id: EventLoopID { + return EventLoopID(self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine.swift new file mode 100644 index 00000000..62a2c7e5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PoolManagerStateMachine.swift @@ -0,0 +1,266 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +@usableFromInline +internal struct PoolManagerStateMachine { + /// The current state. + @usableFromInline + internal var state: State + + @usableFromInline + internal init(_ state: State) { + self.state = state + } + + @usableFromInline + internal enum State { + case inactive + case active(ActiveState) + case shuttingDown(EventLoopFuture) + case shutdown + case _modifying + } + + @usableFromInline + internal struct ActiveState { + @usableFromInline + internal var pools: [EventLoopID: PerPoolState] + + @usableFromInline + internal init( + poolKeys: [PoolManager.ConnectionPoolKey], + assumedMaxAvailableStreamsPerPool: Int + ) { + self.pools = Dictionary(uniqueKeysWithValues: poolKeys.map { key in + let value = PerPoolState( + poolIndex: key.index, + assumedMaxAvailableStreams: assumedMaxAvailableStreamsPerPool + ) + return (key.eventLoopID, value) + }) + } + } + + /// Temporarily sets `self.state` to `._modifying` before calling the provided closure and setting + /// `self.state` to the `State` modified by the closure. + @inlinable + internal mutating func modifyingState(_ modify: (inout State) -> Result) -> Result { + var state = State._modifying + swap(&self.state, &state) + defer { + self.state = state + } + return modify(&state) + } + + /// Returns whether the pool is shutdown or in the process of shutting down. + @usableFromInline + internal var isShutdownOrShuttingDown: Bool { + switch self.state { + case .shuttingDown, .shutdown: + return true + case .inactive, .active: + return false + case ._modifying: + preconditionFailure() + } + } + + /// Activate the pool manager by providing an array of connection pools. + /// + /// - Parameters: + /// - keys: The index and `EventLoopID` of the pools. + /// - capacity: The *assumed* maximum number of streams concurrently available to a pool (that + /// is, the product of the assumed value of max concurrent streams and the number of + /// connections per pool). + @usableFromInline + internal mutating func activatePools( + keyedBy keys: [PoolManager.ConnectionPoolKey], + assumingPerPoolCapacity capacity: Int + ) { + self.modifyingState { state in + switch state { + case .inactive: + state = .active(.init(poolKeys: keys, assumedMaxAvailableStreamsPerPool: capacity)) + + case .active, .shuttingDown, .shutdown, ._modifying: + preconditionFailure() + } + } + } + + /// Select and reserve a stream from a connection pool. + @inlinable + mutating func reserveStream( + preferringPoolWithEventLoopID eventLoopID: EventLoopID? + ) -> Result { + return self.modifyingState { state in + switch state { + case var .active(active): + let connectionPoolIndex: PoolManager.ConnectionPoolIndex + + if let index = eventLoopID.flatMap({ eventLoopID in + active.reserveStreamFromPool(onEventLoopWithID: eventLoopID) + }) { + connectionPoolIndex = index + } else { + // Nothing on the preferred event loop; fallback to the pool with the most available + // streams. + connectionPoolIndex = active.reserveStreamFromPoolWithMostAvailableStreams() + } + + state = .active(active) + return .success(connectionPoolIndex) + + case .inactive: + return .failure(.notInitialized) + + case .shuttingDown, .shutdown: + return .failure(.shutdown) + + case ._modifying: + preconditionFailure() + } + } + } + + /// Return streams to the given pool. + mutating func returnStreams(_ count: Int, toPoolOnEventLoopWithID eventLoopID: EventLoopID) { + self.modifyingState { state in + switch state { + case var .active(active): + active.returnStreams(count, toPoolOnEventLoopWithID: eventLoopID) + state = .active(active) + + case .shuttingDown, .shutdown: + () + + case .inactive, ._modifying: + // If the manager is inactive there are no pools which can return streams. + preconditionFailure() + } + } + } + + /// Update the capacity for the given pool. + mutating func changeStreamCapacity( + by delta: Int, + forPoolOnEventLoopWithID eventLoopID: EventLoopID + ) { + self.modifyingState { state in + switch state { + case var .active(active): + active.increaseMaxAvailableStreams(by: delta, forPoolOnEventLoopWithID: eventLoopID) + state = .active(active) + + case .shuttingDown, .shutdown: + () + + case .inactive, ._modifying: + // If the manager is inactive there are no pools which can update their capacity. + preconditionFailure() + } + } + } + + enum ShutdownAction { + case shutdownPools + case alreadyShutdown + case alreadyShuttingDown(EventLoopFuture) + } + + mutating func shutdown(promise: EventLoopPromise) -> ShutdownAction { + self.modifyingState { state in + switch state { + case .inactive: + state = .shutdown + return .alreadyShutdown + + case .active: + state = .shuttingDown(promise.futureResult) + return .shutdownPools + + case let .shuttingDown(future): + return .alreadyShuttingDown(future) + + case .shutdown: + return .alreadyShutdown + + case ._modifying: + preconditionFailure() + } + } + } + + mutating func shutdownComplete() { + self.modifyingState { state in + switch state { + case .shuttingDown: + state = .shutdown + + case .inactive, .active, .shutdown, ._modifying: + preconditionFailure() + } + } + } +} + +extension PoolManagerStateMachine.ActiveState { + @usableFromInline + mutating func reserveStreamFromPool( + onEventLoopWithID eventLoopID: EventLoopID + ) -> PoolManager.ConnectionPoolIndex? { + return self.pools[eventLoopID]?.reserveStream() + } + + @usableFromInline + mutating func reserveStreamFromPoolWithMostAvailableStreams() -> PoolManager.ConnectionPoolIndex { + // We don't allow pools to be empty (while active). + assert(!self.pools.isEmpty) + + var mostAvailableStreams = Int.min + var mostAvailableIndex = self.pools.values.startIndex + var index = mostAvailableIndex + + while index != self.pools.values.endIndex { + let availableStreams = self.pools.values[index].availableStreams + + if availableStreams > mostAvailableStreams { + mostAvailableIndex = index + mostAvailableStreams = availableStreams + } + + self.pools.values.formIndex(after: &index) + } + + return self.pools.values[mostAvailableIndex].reserveStream() + } + + mutating func returnStreams( + _ count: Int, + toPoolOnEventLoopWithID eventLoopID: EventLoopID + ) { + self.pools[eventLoopID]?.returnReservedStreams(count) + } + + mutating func increaseMaxAvailableStreams( + by delta: Int, + forPoolOnEventLoopWithID eventLoopID: EventLoopID + ) { + self.pools[eventLoopID]?.maxAvailableStreams += delta + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PooledChannel.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PooledChannel.swift new file mode 100644 index 00000000..d3a40717 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/PooledChannel.swift @@ -0,0 +1,215 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHTTP2 +#if canImport(NIOSSL) +import NIOSSL +#endif +import SwiftProtobuf + +@usableFromInline +internal final class PooledChannel: GRPCChannel { + @usableFromInline + internal let _configuration: GRPCChannelPool.Configuration + @usableFromInline + internal let _pool: PoolManager + @usableFromInline + internal let _authority: String + @usableFromInline + internal let _scheme: String + + @inlinable + internal init(configuration: GRPCChannelPool.Configuration) throws { + self._configuration = configuration + self._authority = configuration.target.host + + let tlsMode: DefaultChannelProvider.TLSMode + let scheme: String + + if let tlsConfiguration = configuration.transportSecurity.tlsConfiguration { + scheme = "https" + #if canImport(NIOSSL) + if let sslContext = try tlsConfiguration.makeNIOSSLContext() { + tlsMode = .configureWithNIOSSL(.success(sslContext)) + } else { + #if canImport(Network) + // - TLS is configured + // - NIOSSL is available but we aren't using it + // - Network.framework is available, we MUST be using that. + tlsMode = .configureWithNetworkFramework + #else + // - TLS is configured + // - NIOSSL is available but we aren't using it + // - Network.framework is not available + // NIOSSL or Network.framework must be available as TLS is configured. + fatalError() + #endif + } + #elseif canImport(Network) + // - TLS is configured + // - NIOSSL is not available + // - Network.framework is available, we MUST be using that. + tlsMode = .configureWithNetworkFramework + #else + // - TLS is configured + // - NIOSSL is not available + // - Network.framework is not available + // NIOSSL or Network.framework must be available as TLS is configured. + fatalError() + #endif // canImport(NIOSSL) + } else { + scheme = "http" + tlsMode = .disabled + } + + self._scheme = scheme + + let provider = DefaultChannelProvider( + connectionTarget: configuration.target, + connectionKeepalive: configuration.keepalive, + connectionIdleTimeout: configuration.idleTimeout, + tlsMode: tlsMode, + tlsConfiguration: configuration.transportSecurity.tlsConfiguration, + httpTargetWindowSize: configuration.http2.targetWindowSize, + httpMaxFrameSize: configuration.http2.targetWindowSize, + errorDelegate: configuration.errorDelegate, + debugChannelInitializer: configuration.debugChannelInitializer + ) + + self._pool = PoolManager.makeInitializedPoolManager( + using: configuration.eventLoopGroup, + perPoolConfiguration: .init( + maxConnections: configuration.connectionPool.connectionsPerEventLoop, + maxWaiters: configuration.connectionPool.maxWaitersPerEventLoop, + loadThreshold: configuration.connectionPool.reservationLoadThreshold, + assumedMaxConcurrentStreams: 100, + connectionBackoff: configuration.connectionBackoff, + channelProvider: provider + ), + logger: configuration.backgroundActivityLogger.wrapped + ) + } + + @inlinable + internal func _makeStreamChannel( + callOptions: CallOptions + ) -> (EventLoopFuture, EventLoop) { + let preferredEventLoop = callOptions.eventLoopPreference.exact + let connectionWaitDeadline = NIODeadline.now() + self._configuration.connectionPool.maxWaitTime + let deadline = min(callOptions.timeLimit.makeDeadline(), connectionWaitDeadline) + + let streamChannel = self._pool.makeStream( + preferredEventLoop: preferredEventLoop, + deadline: deadline, + logger: GRPCLogger(wrapping: callOptions.logger) + ) { channel in + return channel.eventLoop.makeSucceededVoidFuture() + } + + return (streamChannel.futureResult, preferredEventLoop ?? streamChannel.eventLoop) + } + + // MARK: GRPCChannel conformance + + @inlinable + internal func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call where Request: Message, Response: Message { + var callOptions = callOptions + if let requestID = callOptions.requestIDProvider.requestID() { + callOptions.applyRequestID(requestID) + } + + let (stream, eventLoop) = self._makeStreamChannel(callOptions: callOptions) + + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: callOptions, + interceptors: interceptors, + transportFactory: .http2( + channel: stream, + authority: self._authority, + scheme: self._scheme, + maximumReceiveMessageLength: self._configuration.maximumReceiveMessageLength, + errorDelegate: self._configuration.errorDelegate + ) + ) + } + + @inlinable + internal func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call where Request: GRPCPayload, Response: GRPCPayload { + var callOptions = callOptions + if let requestID = callOptions.requestIDProvider.requestID() { + callOptions.applyRequestID(requestID) + } + + let (stream, eventLoop) = self._makeStreamChannel(callOptions: callOptions) + + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: callOptions, + interceptors: interceptors, + transportFactory: .http2( + channel: stream, + authority: self._authority, + scheme: self._scheme, + maximumReceiveMessageLength: self._configuration.maximumReceiveMessageLength, + errorDelegate: self._configuration.errorDelegate + ) + ) + } + + @inlinable + internal func close(promise: EventLoopPromise) { + self._pool.shutdown(mode: .forceful, promise: promise) + } + + @inlinable + internal func close() -> EventLoopFuture { + let promise = self._configuration.eventLoopGroup.next().makePromise(of: Void.self) + self.close(promise: promise) + return promise.futureResult + } + + @usableFromInline + internal func closeGracefully(deadline: NIODeadline, promise: EventLoopPromise) { + self._pool.shutdown(mode: .graceful(deadline), promise: promise) + } +} + +extension CallOptions { + @usableFromInline + mutating func applyRequestID(_ requestID: String) { + self.logger[metadataKey: MetadataKey.requestID] = "\(requestID)" + // Add the request ID header too. + if let requestIDHeader = self.requestIDHeader { + self.customMetadata.add(name: requestIDHeader, value: requestID) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/StreamLender.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/StreamLender.swift new file mode 100644 index 00000000..cdd507f7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectionPool/StreamLender.swift @@ -0,0 +1,24 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@usableFromInline +internal protocol StreamLender { + /// `count` streams are being returned to the given `pool`. + func returnStreams(_ count: Int, to pool: ConnectionPool) + + /// Update the total number of streams which may be available at given time for `pool` by `delta`. + func changeStreamCapacity(by delta: Int, for pool: ConnectionPool) +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectivityState.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectivityState.swift new file mode 100644 index 00000000..2098a369 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ConnectivityState.swift @@ -0,0 +1,161 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOConcurrencyHelpers +import NIOCore + +/// The connectivity state of a client connection. Note that this is heavily lifted from the gRPC +/// documentation: https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md. +public enum ConnectivityState: GRPCSendable { + /// This is the state where the channel has not yet been created. + case idle + + /// The channel is trying to establish a connection and is waiting to make progress on one of the + /// steps involved in name resolution, TCP connection establishment or TLS handshake. + case connecting + + /// The channel has successfully established a connection all the way through TLS handshake (or + /// equivalent) and protocol-level (HTTP/2, etc) handshaking. + case ready + + /// There has been some transient failure (such as a TCP 3-way handshake timing out or a socket + /// error). Channels in this state will eventually switch to the `.connecting` state and try to + /// establish a connection again. Since retries are done with exponential backoff, channels that + /// fail to connect will start out spending very little time in this state but as the attempts + /// fail repeatedly, the channel will spend increasingly large amounts of time in this state. + case transientFailure + + /// This channel has started shutting down. Any new RPCs should fail immediately. Pending RPCs + /// may continue running till the application cancels them. Channels may enter this state either + /// because the application explicitly requested a shutdown or if a non-recoverable error has + /// happened during attempts to connect. Channels that have entered this state will never leave + /// this state. + case shutdown +} + +public protocol ConnectivityStateDelegate: AnyObject, GRPCPreconcurrencySendable { + /// Called when a change in `ConnectivityState` has occurred. + /// + /// - Parameter oldState: The old connectivity state. + /// - Parameter newState: The new connectivity state. + func connectivityStateDidChange(from oldState: ConnectivityState, to newState: ConnectivityState) + + /// Called when the connection has started quiescing, that is, the connection is going away but + /// existing RPCs may continue to run. + /// + /// - Important: When this is called no new RPCs may be created until the connectivity state + /// changes to 'idle' (the connection successfully quiesced) or 'transientFailure' (the + /// connection was closed before quiescing completed). Starting RPCs before these state changes + /// will lead to a connection error and the immediate failure of any outstanding RPCs. + func connectionStartedQuiescing() +} + +extension ConnectivityStateDelegate { + public func connectionStartedQuiescing() {} +} + +#if compiler(>=5.6) +// Unchecked because all mutable state is protected by locks. +extension ConnectivityStateMonitor: @unchecked Sendable {} +#endif // compiler(>=5.6) + +public class ConnectivityStateMonitor { + private let stateLock = Lock() + private var _state: ConnectivityState = .idle + + private let delegateLock = Lock() + private var _delegate: ConnectivityStateDelegate? + private let delegateCallbackQueue: DispatchQueue + + /// Creates a new connectivity state monitor. + /// + /// - Parameter delegate: A delegate to call when the connectivity state changes. + /// - Parameter queue: The `DispatchQueue` on which the delegate will be called. + init(delegate: ConnectivityStateDelegate?, queue: DispatchQueue?) { + self._delegate = delegate + self.delegateCallbackQueue = DispatchQueue(label: "io.grpc.connectivity", target: queue) + } + + /// The current state of connectivity. + public var state: ConnectivityState { + return self.stateLock.withLock { + self._state + } + } + + /// A delegate to call when the connectivity state changes. + public var delegate: ConnectivityStateDelegate? { + get { + return self.delegateLock.withLock { + return self._delegate + } + } + set { + self.delegateLock.withLockVoid { + self._delegate = newValue + } + } + } + + internal func updateState(to newValue: ConnectivityState, logger: Logger) { + let change: (ConnectivityState, ConnectivityState)? = self.stateLock.withLock { + let oldValue = self._state + + if oldValue != newValue { + self._state = newValue + return (oldValue, newValue) + } else { + return nil + } + } + + if let (oldState, newState) = change { + logger.debug("connectivity state change", metadata: [ + "old_state": "\(oldState)", + "new_state": "\(newState)", + ]) + + self.delegateCallbackQueue.async { + if let delegate = self.delegate { + delegate.connectivityStateDidChange(from: oldState, to: newState) + } + } + } + } + + internal func beginQuiescing() { + self.delegateCallbackQueue.async { + if let delegate = self.delegate { + delegate.connectionStartedQuiescing() + } + } + } +} + +extension ConnectivityStateMonitor: ConnectionManagerConnectivityDelegate { + internal func connectionStateDidChange( + _ connectionManager: ConnectionManager, + from oldState: _ConnectivityState, + to newState: _ConnectivityState + ) { + self.updateState(to: ConnectivityState(newState), logger: connectionManager.logger) + } + + internal func connectionIsQuiescing(_ connectionManager: ConnectionManager) { + self.beginQuiescing() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DebugOnly.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DebugOnly.swift new file mode 100644 index 00000000..22a631fe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DebugOnly.swift @@ -0,0 +1,19 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal func debugOnly(_ body: () -> Void) { + assert({ body(); return true }()) +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DelegatingErrorHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DelegatingErrorHandler.swift new file mode 100644 index 00000000..b89562eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/DelegatingErrorHandler.swift @@ -0,0 +1,63 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore + +/// A channel handler which allows caught errors to be passed to a `ClientErrorDelegate`. This +/// handler is intended to be used in the client channel pipeline after the HTTP/2 stream +/// multiplexer to handle errors which occur on the underlying connection. +internal final class DelegatingErrorHandler: ChannelInboundHandler { + typealias InboundIn = Any + + private var logger: Logger + private let delegate: ClientErrorDelegate? + + internal init(logger: Logger, delegate: ClientErrorDelegate?) { + self.logger = logger + self.delegate = delegate + } + + internal func channelActive(context: ChannelHandlerContext) { + self.logger.addIPAddressMetadata(local: context.localAddress, remote: context.remoteAddress) + context.fireChannelActive() + } + + internal func errorCaught(context: ChannelHandlerContext, error: Error) { + // We can ignore unclean shutdown since gRPC is self-terminated and therefore not prone to + // truncation attacks. + // + // Without this we would unnecessarily log when we're communicating with peers which don't + // send `close_notify`. + if error.isNIOSSLUncleanShutdown { + return + } + + if let delegate = self.delegate { + if let context = error as? GRPCError.WithContext { + delegate.didCatchError( + context.error, + logger: self.logger, + file: context.file, + line: context.line + ) + } else { + delegate.didCatchErrorWithoutContext(error, logger: self.logger) + } + } + context.close(promise: nil) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Error+NIOSSL.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Error+NIOSSL.swift new file mode 100644 index 00000000..b796d6fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Error+NIOSSL.swift @@ -0,0 +1,32 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOSSL +#endif + +extension Error { + internal var isNIOSSLUncleanShutdown: Bool { + #if canImport(NIOSSL) + if let sslError = self as? NIOSSLError { + return sslError == .uncleanShutdown + } else { + return false + } + #else + return false + #endif + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/EventLoopFuture+RecoverFromUncleanShutdown.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/EventLoopFuture+RecoverFromUncleanShutdown.swift new file mode 100644 index 00000000..335988a9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/EventLoopFuture+RecoverFromUncleanShutdown.swift @@ -0,0 +1,30 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +extension EventLoopFuture where Value == Void { + internal func recoveringFromUncleanShutdown() -> EventLoopFuture { + // We can ignore unclean shutdown since gRPC is self-terminated and therefore not prone to + // truncation attacks. + return self.flatMapErrorThrowing { error in + if error.isNIOSSLUncleanShutdown { + return () + } else { + throw error + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/FakeChannel.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/FakeChannel.swift new file mode 100644 index 00000000..46ce88be --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/FakeChannel.swift @@ -0,0 +1,183 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOEmbedded +import SwiftProtobuf + +#if compiler(>=5.6) +// This type is deprecated, but we need to '@unchecked Sendable' to avoid warnings in our own code. +@available(swift, deprecated: 5.6) +extension FakeChannel: @unchecked Sendable {} +#endif // compiler(>=5.6) + +/// A fake channel for use with generated test clients. +/// +/// The `FakeChannel` provides factories for calls which avoid most of the gRPC stack and don't do +/// real networking. Each call relies on either a `FakeUnaryResponse` or a `FakeStreamingResponse` +/// to get responses or errors. The fake response of each type should be registered with the channel +/// prior to making a call via `makeFakeUnaryResponse` or `makeFakeStreamingResponse` respectively. +/// +/// Users will typically not be required to interact with the channel directly, instead they should +/// do so via a generated test client. +@available( + swift, + deprecated: 5.6, + message: "GRPCChannel implementations must be Sendable but this implementation is not. Using a client and server on localhost is the recommended alternative." +) +public class FakeChannel: GRPCChannel { + /// Fake response streams keyed by their path. + private var responseStreams: [String: CircularBuffer] + + /// A logger. + public let logger: Logger + + public init(logger: Logger = Logger(label: "io.grpc", factory: { _ in + SwiftLogNoOpLogHandler() + })) { + self.responseStreams = [:] + self.logger = logger + } + + /// Make and store a fake unary response for the given path. Users should prefer making a response + /// stream for their RPC directly via the appropriate method on their generated test client. + public func makeFakeUnaryResponse( + path: String, + requestHandler: @escaping (FakeRequestPart) -> Void + ) -> FakeUnaryResponse { + let proxy = FakeUnaryResponse(requestHandler: requestHandler) + self.responseStreams[path, default: []].append(proxy) + return proxy + } + + /// Make and store a fake streaming response for the given path. Users should prefer making a + /// response stream for their RPC directly via the appropriate method on their generated test + /// client. + public func makeFakeStreamingResponse( + path: String, + requestHandler: @escaping (FakeRequestPart) -> Void + ) -> FakeStreamingResponse { + let proxy = FakeStreamingResponse(requestHandler: requestHandler) + self.responseStreams[path, default: []].append(proxy) + return proxy + } + + /// Returns true if there are fake responses enqueued for the given path. + public func hasFakeResponseEnqueued(forPath path: String) -> Bool { + guard let noStreamsForPath = self.responseStreams[path]?.isEmpty else { + return false + } + return !noStreamsForPath + } + + public func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + return self._makeCall( + path: path, + type: type, + callOptions: callOptions, + interceptors: interceptors + ) + } + + public func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + return self._makeCall( + path: path, + type: type, + callOptions: callOptions, + interceptors: interceptors + ) + } + + private func _makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + let stream: _FakeResponseStream? = self.dequeueResponseStream(forPath: path) + let eventLoop = stream?.channel.eventLoop ?? EmbeddedEventLoop() + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: callOptions, + interceptors: interceptors, + transportFactory: .fake(stream) + ) + } + + private func _makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call { + let stream: _FakeResponseStream? = self.dequeueResponseStream(forPath: path) + let eventLoop = stream?.channel.eventLoop ?? EmbeddedEventLoop() + return Call( + path: path, + type: type, + eventLoop: eventLoop, + options: callOptions, + interceptors: interceptors, + transportFactory: .fake(stream) + ) + } + + public func close() -> EventLoopFuture { + // We don't have anything to close. + return EmbeddedEventLoop().makeSucceededFuture(()) + } +} + +@available(swift, deprecated: 5.6) +extension FakeChannel { + /// Dequeue a proxy for the given path and casts it to the given type, if one exists. + private func dequeueResponseStream( + forPath path: String, + as: Stream.Type = Stream.self + ) -> Stream? { + guard var streams = self.responseStreams[path], !streams.isEmpty else { + return nil + } + + // This is fine: we know we're non-empty. + let first = streams.removeFirst() + self.responseStreams.updateValue(streams, forKey: path) + + return first as? Stream + } + + private func makeRequestHead(path: String, callOptions: CallOptions) -> _GRPCRequestHead { + return _GRPCRequestHead( + scheme: "http", + path: path, + host: "localhost", + options: callOptions, + requestID: nil + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NIOSSL.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NIOSSL.swift new file mode 100644 index 00000000..ca53cc1f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NIOSSL.swift @@ -0,0 +1,99 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOCore +import NIOSSL + +extension ClientConnection { + /// Returns a `ClientConnection` builder configured with TLS. + @available( + *, deprecated, + message: "Use one of 'usingPlatformAppropriateTLS(for:)', 'usingTLSBackedByNIOSSL(on:)' or 'usingTLSBackedByNetworkFramework(on:)' or 'usingTLS(on:with:)'" + ) + public static func secure(group: EventLoopGroup) -> ClientConnection.Builder.Secure { + return ClientConnection.usingTLSBackedByNIOSSL(on: group) + } + + /// Returns a `ClientConnection` builder configured with the 'NIOSSL' TLS backend. + /// + /// This builder may use either a `MultiThreadedEventLoopGroup` or a `NIOTSEventLoopGroup` (or an + /// `EventLoop` from either group). + /// + /// - Parameter group: The `EventLoopGroup` use for the connection. + /// - Returns: A builder for a connection using the NIOSSL TLS backend. + public static func usingTLSBackedByNIOSSL( + on group: EventLoopGroup + ) -> ClientConnection.Builder.Secure { + return Builder.Secure(group: group, tlsConfiguration: .makeClientConfigurationBackedByNIOSSL()) + } +} + +// MARK: - NIOSSL TLS backend options + +extension ClientConnection.Builder.Secure { + /// Sets the sources of certificates to offer during negotiation. No certificates are offered + /// during negotiation by default. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(certificateChain: [NIOSSLCertificate]) -> Self { + self.tls.updateNIOCertificateChain(to: certificateChain) + return self + } + + /// Sets the private key associated with the leaf certificate. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(privateKey: NIOSSLPrivateKey) -> Self { + self.tls.updateNIOPrivateKey(to: privateKey) + return self + } + + /// Sets the trust roots to use to validate certificates. This only needs to be provided if you + /// intend to validate certificates. Defaults to the system provided trust store (`.default`) if + /// not set. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(trustRoots: NIOSSLTrustRoots) -> Self { + self.tls.updateNIOTrustRoots(to: trustRoots) + return self + } + + /// Whether to verify remote certificates. Defaults to `.fullVerification` if not otherwise + /// configured. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(certificateVerification: CertificateVerification) -> Self { + self.tls.updateNIOCertificateVerification(to: certificateVerification) + return self + } + + /// A custom verification callback that allows completely overriding the certificate verification logic. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLSCustomVerificationCallback( + _ callback: @escaping NIOSSLCustomVerificationCallback + ) -> Self { + self.tls.updateNIOCustomVerificationCallback(to: callback) + return self + } +} + +#endif // canImport(NIOSSL) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NWTLS.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NWTLS.swift new file mode 100644 index 00000000..6a7a7a39 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/ClientConnection+NWTLS.swift @@ -0,0 +1,70 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(Security) +#if canImport(Network) +import NIOCore +import Security + +extension ClientConnection { + /// Returns a `ClientConnection` builder configured with the Network.framework TLS backend. + /// + /// This builder must use a `NIOTSEventLoopGroup` (or an `EventLoop` from a + /// `NIOTSEventLoopGroup`). + /// + /// - Parameter group: The `EventLoopGroup` use for the connection. + /// - Returns: A builder for a connection using the Network.framework TLS backend. + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func usingTLSBackedByNetworkFramework( + on group: EventLoopGroup + ) -> ClientConnection.Builder.Secure { + precondition( + PlatformSupport.isTransportServicesEventLoopGroup(group), + "'\(#function)' requires 'group' to be a 'NIOTransportServices.NIOTSEventLoopGroup' or 'NIOTransportServices.QoSEventLoop' (but was '\(type(of: group))'" + ) + return Builder.Secure( + group: group, + tlsConfiguration: .makeClientConfigurationBackedByNetworkFramework() + ) + } +} + +extension ClientConnection.Builder.Secure { + /// Update the local identity. + /// + /// - Note: May only be used with the 'Network.framework' TLS backend. + @discardableResult + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public func withTLS(localIdentity: SecIdentity) -> Self { + self.tls.updateNetworkLocalIdentity(to: localIdentity) + return self + } + + /// Update the callback used to verify a trust object during a TLS handshake. + /// + /// - Note: May only be used with the 'Network.framework' TLS backend. + @discardableResult + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public func withTLSHandshakeVerificationCallback( + on queue: DispatchQueue, + verificationCallback callback: @escaping sec_protocol_verify_t + ) -> Self { + self.tls.updateNetworkVerifyCallbackWithQueue(callback: callback, queue: queue) + return self + } +} + +#endif // canImport(Network) +#endif // canImport(Security) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannel.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannel.swift new file mode 100644 index 00000000..3760434b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannel.swift @@ -0,0 +1,304 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHTTP2 +import SwiftProtobuf + +public protocol GRPCChannel: GRPCPreconcurrencySendable { + /// Makes a gRPC call on the channel with requests and responses conforming to + /// `SwiftProtobuf.Message`. + /// + /// Note: this is a lower-level construct that any of `UnaryCall`, `ClientStreamingCall`, + /// `ServerStreamingCall` or `BidirectionalStreamingCall` and does not have an API to protect + /// users against protocol violations (such as sending to requests on a unary call). + /// + /// After making the `Call`, users must `invoke` the call with a callback which is invoked + /// for each response part (or error) received. Any call to `send(_:promise:)` prior to calling + /// `invoke` will fail and not be sent. Users are also responsible for closing the request stream + /// by sending the `.end` request part. + /// + /// - Parameters: + /// - path: The path of the RPC, e.g. "/echo.Echo/get". + /// - type: The type of the RPC, e.g. `.unary`. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call + + /// Makes a gRPC call on the channel with requests and responses conforming to `GRPCPayload`. + /// + /// Note: this is a lower-level construct that any of `UnaryCall`, `ClientStreamingCall`, + /// `ServerStreamingCall` or `BidirectionalStreamingCall` and does not have an API to protect + /// users against protocol violations (such as sending to requests on a unary call). + /// + /// After making the `Call`, users must `invoke` the call with a callback which is invoked + /// for each response part (or error) received. Any call to `send(_:promise:)` prior to calling + /// `invoke` will fail and not be sent. Users are also responsible for closing the request stream + /// by sending the `.end` request part. + /// + /// - Parameters: + /// - path: The path of the RPC, e.g. "/echo.Echo/get". + /// - type: The type of the RPC, e.g. `.unary`. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + func makeCall( + path: String, + type: GRPCCallType, + callOptions: CallOptions, + interceptors: [ClientInterceptor] + ) -> Call + + /// Close the channel, and any connections associated with it. Any ongoing RPCs may fail. + /// + /// - Returns: Returns a future which will be resolved when shutdown has completed. + func close() -> EventLoopFuture + + /// Close the channel, and any connections associated with it. Any ongoing RPCs may fail. + /// + /// - Parameter promise: A promise which will be completed when shutdown has completed. + func close(promise: EventLoopPromise) + + /// Attempt to gracefully shutdown the channel. New RPCs will be failed immediately and existing + /// RPCs may continue to run until they complete. + /// + /// - Parameters: + /// - deadline: A point in time by which the graceful shutdown must have completed. If the + /// deadline passes and RPCs are still active then the connection will be closed forcefully + /// and any remaining in-flight RPCs may be failed. + /// - promise: A promise which will be completed when shutdown has completed. + func closeGracefully(deadline: NIODeadline, promise: EventLoopPromise) +} + +// Default implementations to avoid breaking API. Implementations provided by GRPC override these. +extension GRPCChannel { + public func close(promise: EventLoopPromise) { + promise.completeWith(self.close()) + } + + public func closeGracefully(deadline: NIODeadline, promise: EventLoopPromise) { + promise.completeWith(self.close()) + } +} + +extension GRPCChannel { + /// Make a unary gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + public func makeUnaryCall( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> UnaryCall { + let unary: UnaryCall = UnaryCall( + call: self.makeCall( + path: path, + type: .unary, + callOptions: callOptions, + interceptors: interceptors + ) + ) + unary.invoke(request) + return unary + } + + /// Make a unary gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + public func makeUnaryCall( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> UnaryCall { + let rpc: UnaryCall = UnaryCall( + call: self.makeCall( + path: path, + type: .unary, + callOptions: callOptions, + interceptors: interceptors + ) + ) + rpc.invoke(request) + return rpc + } + + /// Makes a client-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + public func makeClientStreamingCall( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> ClientStreamingCall { + let rpc: ClientStreamingCall = ClientStreamingCall( + call: self.makeCall( + path: path, + type: .clientStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + rpc.invoke() + return rpc + } + + /// Makes a client-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + public func makeClientStreamingCall( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [] + ) -> ClientStreamingCall { + let rpc: ClientStreamingCall = ClientStreamingCall( + call: self.makeCall( + path: path, + type: .clientStreaming, + callOptions: callOptions, + interceptors: interceptors + ) + ) + rpc.invoke() + return rpc + } + + /// Make a server-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + /// - handler: Response handler; called for every response received from the server. + public func makeServerStreamingCall( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [], + handler: @escaping (Response) -> Void + ) -> ServerStreamingCall { + let rpc: ServerStreamingCall = ServerStreamingCall( + call: self.makeCall( + path: path, + type: .serverStreaming, + callOptions: callOptions, + interceptors: interceptors + ), + callback: handler + ) + rpc.invoke(request) + return rpc + } + + /// Make a server-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - request: The request to send. + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + /// - handler: Response handler; called for every response received from the server. + public func makeServerStreamingCall( + path: String, + request: Request, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [], + handler: @escaping (Response) -> Void + ) -> ServerStreamingCall { + let rpc: ServerStreamingCall = ServerStreamingCall( + call: self.makeCall( + path: path, + type: .serverStreaming, + callOptions: callOptions, + interceptors: [] + ), + callback: handler + ) + rpc.invoke(request) + return rpc + } + + /// Makes a bidirectional-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + /// - handler: Response handler; called for every response received from the server. + public func makeBidirectionalStreamingCall( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [], + handler: @escaping (Response) -> Void + ) -> BidirectionalStreamingCall { + let rpc: BidirectionalStreamingCall = BidirectionalStreamingCall( + call: self.makeCall( + path: path, + type: .bidirectionalStreaming, + callOptions: callOptions, + interceptors: interceptors + ), + callback: handler + ) + rpc.invoke() + return rpc + } + + /// Makes a bidirectional-streaming gRPC call. + /// + /// - Parameters: + /// - path: Path of the RPC, e.g. "/echo.Echo/Get" + /// - callOptions: Options for the RPC. + /// - interceptors: A list of interceptors to intercept the request and response stream with. + /// - handler: Response handler; called for every response received from the server. + public func makeBidirectionalStreamingCall( + path: String, + callOptions: CallOptions, + interceptors: [ClientInterceptor] = [], + handler: @escaping (Response) -> Void + ) -> BidirectionalStreamingCall { + let rpc: BidirectionalStreamingCall = BidirectionalStreamingCall( + call: self.makeCall( + path: path, + type: .bidirectionalStreaming, + callOptions: callOptions, + interceptors: interceptors + ), + callback: handler + ) + rpc.invoke() + return rpc + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannelBuilder.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannelBuilder.swift new file mode 100644 index 00000000..714171e9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCChannel/GRPCChannelBuilder.swift @@ -0,0 +1,331 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Dispatch +import Logging +import NIOCore + +extension ClientConnection { + /// Returns an insecure `ClientConnection` builder which is *not configured with TLS*. + public static func insecure(group: EventLoopGroup) -> ClientConnection.Builder { + return Builder(group: group) + } + + /// Returns a `ClientConnection` builder configured with a TLS backend appropriate for the + /// given `EventLoopGroup`. + /// + /// gRPC Swift offers two TLS 'backends'. The 'NIOSSL' backend is available on Darwin and Linux + /// platforms and delegates to SwiftNIO SSL. On recent Darwin platforms (macOS 10.14+, iOS 12+, + /// tvOS 12+, and watchOS 6+) the 'Network.framework' backend is available. The two backends have + /// a number of incompatible configuration options and users are responsible for selecting the + /// appropriate APIs. The TLS configuration options on the builder document which backends they + /// support. + /// + /// TLS backends must also be used with an appropriate `EventLoopGroup` implementation. The + /// 'NIOSSL' backend may be used either a `MultiThreadedEventLoopGroup` or a + /// `NIOTSEventLoopGroup`. The 'Network.framework' backend may only be used with a + /// `NIOTSEventLoopGroup`. + /// + /// This function returns a builder using the `NIOSSL` backend if a `MultiThreadedEventLoopGroup` + /// is supplied and a 'Network.framework' backend if a `NIOTSEventLoopGroup` is used. + public static func usingPlatformAppropriateTLS( + for group: EventLoopGroup + ) -> ClientConnection.Builder.Secure { + let networkPreference = NetworkPreference.userDefined(.matchingEventLoopGroup(group)) + return Builder.Secure( + group: group, + tlsConfiguration: .makeClientDefault(for: networkPreference) + ) + } + + /// Returns a `ClientConnection` builder configured with the TLS backend appropriate for the + /// provided configuration and `EventLoopGroup`. + /// + /// - Important: The caller is responsible for ensuring the provided `configuration` may be used + /// the the `group`. + public static func usingTLS( + with configuration: GRPCTLSConfiguration, + on group: EventLoopGroup + ) -> ClientConnection.Builder.Secure { + return Builder.Secure(group: group, tlsConfiguration: configuration) + } +} + +extension ClientConnection { + public class Builder { + private var configuration: ClientConnection.Configuration + private var maybeTLS: GRPCTLSConfiguration? { return nil } + + private var connectionBackoff = ConnectionBackoff() + private var connectionBackoffIsEnabled = true + + fileprivate init(group: EventLoopGroup) { + // This is okay: the configuration is only consumed on a call to `connect` which sets the host + // and port. + self.configuration = .default(target: .hostAndPort("", .max), eventLoopGroup: group) + } + + public func connect(host: String, port: Int) -> ClientConnection { + // Finish setting up the configuration. + self.configuration.target = .hostAndPort(host, port) + self.configuration.connectionBackoff = + self.connectionBackoffIsEnabled ? self.connectionBackoff : nil + self.configuration.tlsConfiguration = self.maybeTLS + return ClientConnection(configuration: self.configuration) + } + + public func withConnectedSocket(_ socket: NIOBSDSocket.Handle) -> ClientConnection { + precondition( + !PlatformSupport.isTransportServicesEventLoopGroup(self.configuration.eventLoopGroup), + "'\(#function)' requires 'group' to not be a 'NIOTransportServices.NIOTSEventLoopGroup' or 'NIOTransportServices.QoSEventLoop' (but was '\(type(of: self.configuration.eventLoopGroup))'" + ) + self.configuration.target = .connectedSocket(socket) + self.configuration.connectionBackoff = + self.connectionBackoffIsEnabled ? self.connectionBackoff : nil + self.configuration.tlsConfiguration = self.maybeTLS + return ClientConnection(configuration: self.configuration) + } + } +} + +extension ClientConnection.Builder { + public class Secure: ClientConnection.Builder { + internal var tls: GRPCTLSConfiguration + override internal var maybeTLS: GRPCTLSConfiguration? { + return self.tls + } + + internal init(group: EventLoopGroup, tlsConfiguration: GRPCTLSConfiguration) { + group.preconditionCompatible(with: tlsConfiguration) + self.tls = tlsConfiguration + super.init(group: group) + } + + /// Connect to `host` on port 443. + public func connect(host: String) -> ClientConnection { + return self.connect(host: host, port: 443) + } + } +} + +extension ClientConnection.Builder { + /// Sets the initial connection backoff. That is, the initial time to wait before re-attempting to + /// establish a connection. Jitter will *not* be applied to the initial backoff. Defaults to + /// 1 second if not set. + @discardableResult + public func withConnectionBackoff(initial amount: TimeAmount) -> Self { + self.connectionBackoff.initialBackoff = .seconds(from: amount) + return self + } + + /// Set the maximum connection backoff. That is, the maximum amount of time to wait before + /// re-attempting to establish a connection. Note that this time amount represents the maximum + /// backoff *before* jitter is applied. Defaults to 120 seconds if not set. + @discardableResult + public func withConnectionBackoff(maximum amount: TimeAmount) -> Self { + self.connectionBackoff.maximumBackoff = .seconds(from: amount) + return self + } + + /// Backoff is 'jittered' to randomise the amount of time to wait before re-attempting to + /// establish a connection. The jittered backoff will be no more than `jitter ⨯ unjitteredBackoff` + /// from `unjitteredBackoff`. Defaults to 0.2 if not set. + /// + /// - Precondition: `0 <= jitter <= 1` + @discardableResult + public func withConnectionBackoff(jitter: Double) -> Self { + self.connectionBackoff.jitter = jitter + return self + } + + /// The multiplier for scaling the unjittered backoff between attempts to establish a connection. + /// Defaults to 1.6 if not set. + @discardableResult + public func withConnectionBackoff(multiplier: Double) -> Self { + self.connectionBackoff.multiplier = multiplier + return self + } + + /// The minimum timeout to use when attempting to establishing a connection. The connection + /// timeout for each attempt is the larger of the jittered backoff and the minimum connection + /// timeout. Defaults to 20 seconds if not set. + @discardableResult + public func withConnectionTimeout(minimum amount: TimeAmount) -> Self { + self.connectionBackoff.minimumConnectionTimeout = .seconds(from: amount) + return self + } + + /// Sets the initial and maximum backoff to given amount. Disables jitter and sets the backoff + /// multiplier to 1.0. + @discardableResult + public func withConnectionBackoff(fixed amount: TimeAmount) -> Self { + let seconds = Double.seconds(from: amount) + self.connectionBackoff.initialBackoff = seconds + self.connectionBackoff.maximumBackoff = seconds + self.connectionBackoff.multiplier = 1.0 + self.connectionBackoff.jitter = 0.0 + return self + } + + /// Sets the limit on the number of times to attempt to re-establish a connection. Defaults + /// to `.unlimited` if not set. + @discardableResult + public func withConnectionBackoff(retries: ConnectionBackoff.Retries) -> Self { + self.connectionBackoff.retries = retries + return self + } + + /// Sets whether the connection should be re-established automatically if it is dropped. Defaults + /// to `true` if not set. + @discardableResult + public func withConnectionReestablishment(enabled: Bool) -> Self { + self.connectionBackoffIsEnabled = enabled + return self + } + + /// Sets a custom configuration for keepalive + /// The defaults for client and server are determined by the gRPC keepalive + /// [documentation] (https://github.com/grpc/grpc/blob/master/doc/keepalive.md). + @discardableResult + public func withKeepalive(_ keepalive: ClientConnectionKeepalive) -> Self { + self.configuration.connectionKeepalive = keepalive + return self + } + + /// The amount of time to wait before closing the connection. The idle timeout will start only + /// if there are no RPCs in progress and will be cancelled as soon as any RPCs start. If a + /// connection becomes idle, starting a new RPC will automatically create a new connection. + /// Defaults to 30 minutes if not set. + @discardableResult + public func withConnectionIdleTimeout(_ timeout: TimeAmount) -> Self { + self.configuration.connectionIdleTimeout = timeout + return self + } + + /// The behavior used to determine when an RPC should start. That is, whether it should wait for + /// an active connection or fail quickly if no connection is currently available. Calls will + /// use `.waitsForConnectivity` by default. + @discardableResult + public func withCallStartBehavior(_ behavior: CallStartBehavior) -> Self { + self.configuration.callStartBehavior = behavior + return self + } +} + +extension ClientConnection.Builder { + /// Sets the client error delegate. + @discardableResult + public func withErrorDelegate(_ delegate: ClientErrorDelegate?) -> Self { + self.configuration.errorDelegate = delegate + return self + } +} + +extension ClientConnection.Builder { + /// Sets the client connectivity state delegate and the `DispatchQueue` on which the delegate + /// should be called. If no `queue` is provided then gRPC will create a `DispatchQueue` on which + /// to run the delegate. + @discardableResult + public func withConnectivityStateDelegate( + _ delegate: ConnectivityStateDelegate?, + executingOn queue: DispatchQueue? = nil + ) -> Self { + self.configuration.connectivityStateDelegate = delegate + self.configuration.connectivityStateDelegateQueue = queue + return self + } +} + +// MARK: - Common TLS options + +extension ClientConnection.Builder.Secure { + /// Sets a server hostname override to be used for the TLS Server Name Indication (SNI) extension. + /// The hostname from `connect(host:port)` is for TLS SNI if this value is not set and hostname + /// verification is enabled. + /// + /// - Note: May be used with the 'NIOSSL' and 'Network.framework' TLS backend. + /// - Note: `serverHostnameOverride` may not be `nil` when using the 'Network.framework' backend. + @discardableResult + public func withTLS(serverHostnameOverride: String?) -> Self { + self.tls.hostnameOverride = serverHostnameOverride + return self + } +} + +extension ClientConnection.Builder { + /// Sets the HTTP/2 flow control target window size. Defaults to 8MB if not explicitly set. + /// Values are clamped between 1 and 2^31-1 inclusive. + @discardableResult + public func withHTTPTargetWindowSize(_ httpTargetWindowSize: Int) -> Self { + self.configuration.httpTargetWindowSize = httpTargetWindowSize + return self + } + + /// Sets the maximum size of an HTTP/2 frame in bytes which the client is willing to receive from + /// the server. Defaults to 16384. Value are clamped between 2^14 and 2^24-1 octets inclusive + /// (the minimum and maximum permitted values per RFC 7540 § 4.2). + /// + /// Raising this value may lower CPU usage for large message at the cost of increasing head of + /// line blocking for small messages. + @discardableResult + public func withHTTPMaxFrameSize(_ httpMaxFrameSize: Int) -> Self { + self.configuration.httpMaxFrameSize = httpMaxFrameSize + return self + } +} + +extension ClientConnection.Builder { + /// Sets the maximum message size the client is permitted to receive in bytes. + /// + /// - Precondition: `limit` must not be negative. + @discardableResult + public func withMaximumReceiveMessageLength(_ limit: Int) -> Self { + self.configuration.maximumReceiveMessageLength = limit + return self + } +} + +extension ClientConnection.Builder { + /// Sets a logger to be used for background activity such as connection state changes. Defaults + /// to a no-op logger if not explicitly set. + /// + /// Note that individual RPCs will use the logger from `CallOptions`, not the logger specified + /// here. + @discardableResult + public func withBackgroundActivityLogger(_ logger: Logger) -> Self { + self.configuration.backgroundActivityLogger = logger + return self + } +} + +extension ClientConnection.Builder { + /// A channel initializer which will be run after gRPC has initialized each channel. This may be + /// used to add additional handlers to the pipeline and is intended for debugging. + /// + /// - Warning: The initializer closure may be invoked *multiple times*. + @discardableResult + public func withDebugChannelInitializer( + _ debugChannelInitializer: @escaping GRPCChannelInitializer + ) -> Self { + self.configuration.debugChannelInitializer = debugChannelInitializer + return self + } +} + +extension Double { + fileprivate static func seconds(from amount: TimeAmount) -> Double { + return Double(amount.nanoseconds) / 1_000_000_000 + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClient.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClient.swift new file mode 100644 index 00000000..726c67ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClient.swift @@ -0,0 +1,238 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOConcurrencyHelpers +import NIOCore +import NIOHTTP2 +import SwiftProtobuf + +/// A gRPC client. +public protocol GRPCClient: GRPCPreconcurrencySendable { + /// The gRPC channel over which RPCs are sent and received. Note that this is distinct + /// from `NIO.Channel`. + var channel: GRPCChannel { get } + + /// The call options to use should the user not provide per-call options. + var defaultCallOptions: CallOptions { get set } +} + +// MARK: Convenience methods + +extension GRPCClient { + public func makeUnaryCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> UnaryCall { + return self.channel.makeUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeUnaryCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self + ) -> UnaryCall { + return self.channel.makeUnaryCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeServerStreamingCall< + Request: SwiftProtobuf.Message, + Response: SwiftProtobuf.Message + >( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self, + handler: @escaping (Response) -> Void + ) -> ServerStreamingCall { + return self.channel.makeServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors, + handler: handler + ) + } + + public func makeServerStreamingCall( + path: String, + request: Request, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + responseType: Response.Type = Response.self, + handler: @escaping (Response) -> Void + ) -> ServerStreamingCall { + return self.channel.makeServerStreamingCall( + path: path, + request: request, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors, + handler: handler + ) + } + + public func makeClientStreamingCall< + Request: SwiftProtobuf.Message, + Response: SwiftProtobuf.Message + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> ClientStreamingCall { + return self.channel.makeClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeClientStreamingCall( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> ClientStreamingCall { + return self.channel.makeClientStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors + ) + } + + public func makeBidirectionalStreamingCall< + Request: SwiftProtobuf.Message, + Response: SwiftProtobuf.Message + >( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self, + handler: @escaping (Response) -> Void + ) -> BidirectionalStreamingCall { + return self.channel.makeBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors, + handler: handler + ) + } + + public func makeBidirectionalStreamingCall( + path: String, + callOptions: CallOptions? = nil, + interceptors: [ClientInterceptor] = [], + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self, + handler: @escaping (Response) -> Void + ) -> BidirectionalStreamingCall { + return self.channel.makeBidirectionalStreamingCall( + path: path, + callOptions: callOptions ?? self.defaultCallOptions, + interceptors: interceptors, + handler: handler + ) + } +} + +/// A client which has no generated stubs and may be used to create gRPC calls manually. +/// See `GRPCClient` for details. +/// +/// Example: +/// +/// ``` +/// let client = AnyServiceClient(channel: channel) +/// let rpc: UnaryCall = client.makeUnaryCall( +/// path: "/serviceName/methodName", +/// request: .with { ... }, +/// } +/// ``` +@available(*, deprecated, renamed: "GRPCAnyServiceClient") +public final class AnyServiceClient: GRPCClient { + private let lock = Lock() + private var _defaultCallOptions: CallOptions + + /// The gRPC channel over which RPCs are sent and received. + public let channel: GRPCChannel + + /// The default options passed to each RPC unless passed for each RPC. + public var defaultCallOptions: CallOptions { + get { return self.lock.withLock { self._defaultCallOptions } } + set { self.lock.withLockVoid { self._defaultCallOptions = newValue } } + } + + /// Creates a client which may be used to call any service. + /// + /// - Parameters: + /// - connection: `ClientConnection` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { + self.channel = channel + self._defaultCallOptions = defaultCallOptions + } +} + +#if swift(>=5.6) +// Unchecked because mutable state is protected by a lock. +@available(*, deprecated, renamed: "GRPCAnyServiceClient") +extension AnyServiceClient: @unchecked GRPCSendable {} +#endif // swift(>=5.6) + +/// A client which has no generated stubs and may be used to create gRPC calls manually. +/// See `GRPCClient` for details. +/// +/// Example: +/// +/// ``` +/// let client = GRPCAnyServiceClient(channel: channel) +/// let rpc: UnaryCall = client.makeUnaryCall( +/// path: "/serviceName/methodName", +/// request: .with { ... }, +/// } +/// ``` +public struct GRPCAnyServiceClient: GRPCClient { + public let channel: GRPCChannel + + /// The default options passed to each RPC unless passed for each RPC. + public var defaultCallOptions: CallOptions + + /// Creates a client which may be used to call any service. + /// + /// - Parameters: + /// - connection: `ClientConnection` to the service host. + /// - defaultCallOptions: Options to use for each service call if the user doesn't provide them. + public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) { + self.channel = channel + self.defaultCallOptions = defaultCallOptions + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientChannelHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientChannelHandler.swift new file mode 100644 index 00000000..483dce7d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientChannelHandler.swift @@ -0,0 +1,595 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 +import SwiftProtobuf + +/// A gRPC client request message part. +/// +/// - Important: This is **NOT** part of the public API. It is declared as +/// `public` because it is used within performance tests. +public enum _GRPCClientRequestPart { + /// The 'head' of the request, that is, information about the initiation of the RPC. + case head(_GRPCRequestHead) + + /// A deserialized request message to send to the server. + case message(_MessageContext) + + /// Indicates that the client does not intend to send any further messages. + case end +} + +/// As `_GRPCClientRequestPart` but messages are serialized. +/// - Important: This is **NOT** part of the public API. +public typealias _RawGRPCClientRequestPart = _GRPCClientRequestPart + +/// A gRPC client response message part. +/// +/// - Important: This is **NOT** part of the public API. +public enum _GRPCClientResponsePart { + /// Metadata received as the server acknowledges the RPC. + case initialMetadata(HPACKHeaders) + + /// A deserialized response message received from the server. + case message(_MessageContext) + + /// The metadata received at the end of the RPC. + case trailingMetadata(HPACKHeaders) + + /// The final status of the RPC. + case status(GRPCStatus) +} + +/// As `_GRPCClientResponsePart` but messages are serialized. +/// - Important: This is **NOT** part of the public API. +public typealias _RawGRPCClientResponsePart = _GRPCClientResponsePart + +/// - Important: This is **NOT** part of the public API. It is declared as +/// `public` because it is used within performance tests. +public struct _GRPCRequestHead { + private final class _Storage { + var method: String + var scheme: String + var path: String + var host: String + var deadline: NIODeadline + var encoding: ClientMessageEncoding + + init( + method: String, + scheme: String, + path: String, + host: String, + deadline: NIODeadline, + encoding: ClientMessageEncoding + ) { + self.method = method + self.scheme = scheme + self.path = path + self.host = host + self.deadline = deadline + self.encoding = encoding + } + + func copy() -> _Storage { + return .init( + method: self.method, + scheme: self.scheme, + path: self.path, + host: self.host, + deadline: self.deadline, + encoding: self.encoding + ) + } + } + + private var _storage: _Storage + // Don't put this in storage: it would CoW for every mutation. + internal var customMetadata: HPACKHeaders + + internal var method: String { + get { + return self._storage.method + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.method = newValue + } + } + + internal var scheme: String { + get { + return self._storage.scheme + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.scheme = newValue + } + } + + internal var path: String { + get { + return self._storage.path + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.path = newValue + } + } + + internal var host: String { + get { + return self._storage.host + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.host = newValue + } + } + + internal var deadline: NIODeadline { + get { + return self._storage.deadline + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.deadline = newValue + } + } + + internal var encoding: ClientMessageEncoding { + get { + return self._storage.encoding + } + set { + if !isKnownUniquelyReferenced(&self._storage) { + self._storage = self._storage.copy() + } + self._storage.encoding = newValue + } + } + + public init( + method: String, + scheme: String, + path: String, + host: String, + deadline: NIODeadline, + customMetadata: HPACKHeaders, + encoding: ClientMessageEncoding + ) { + self._storage = .init( + method: method, + scheme: scheme, + path: path, + host: host, + deadline: deadline, + encoding: encoding + ) + self.customMetadata = customMetadata + } +} + +extension _GRPCRequestHead { + internal init( + scheme: String, + path: String, + host: String, + options: CallOptions, + requestID: String? + ) { + let metadata: HPACKHeaders + if let requestID = requestID, let requestIDHeader = options.requestIDHeader { + var customMetadata = options.customMetadata + customMetadata.add(name: requestIDHeader, value: requestID) + metadata = customMetadata + } else { + metadata = options.customMetadata + } + + self = _GRPCRequestHead( + method: options.cacheable ? "GET" : "POST", + scheme: scheme, + path: path, + host: host, + deadline: options.timeLimit.makeDeadline(), + customMetadata: metadata, + encoding: options.messageEncoding + ) + } +} + +/// The type of gRPC call. +public enum GRPCCallType: Hashable, GRPCSendable { + /// Unary: a single request and a single response. + case unary + + /// Client streaming: many requests and a single response. + case clientStreaming + + /// Server streaming: a single request and many responses. + case serverStreaming + + /// Bidirectional streaming: many request and many responses. + case bidirectionalStreaming + + public var isStreamingRequests: Bool { + switch self { + case .clientStreaming, .bidirectionalStreaming: + return true + case .unary, .serverStreaming: + return false + } + } + + public var isStreamingResponses: Bool { + switch self { + case .serverStreaming, .bidirectionalStreaming: + return true + case .unary, .clientStreaming: + return false + } + } +} + +// MARK: - GRPCClientChannelHandler + +/// A channel handler for gRPC clients which translates HTTP/2 frames into gRPC messages. +/// +/// This channel handler should typically be used in conjunction with another handler which +/// reads the parsed `GRPCClientResponsePart` messages and surfaces them to the caller +/// in some fashion. Note that for unary and client streaming RPCs this handler will only emit at +/// most one response message. +/// +/// This handler relies heavily on the `GRPCClientStateMachine` to manage the state of the request +/// and response streams, which share a single HTTP/2 stream for transport. +/// +/// Typical usage of this handler is with a `HTTP2StreamMultiplexer` from SwiftNIO HTTP2: +/// +/// ``` +/// let multiplexer: HTTP2StreamMultiplexer = // ... +/// multiplexer.createStreamChannel(promise: nil) { (channel, streamID) in +/// let clientChannelHandler = GRPCClientChannelHandler( +/// streamID: streamID, +/// callType: callType, +/// logger: logger +/// ) +/// return channel.pipeline.addHandler(clientChannelHandler) +/// } +/// ``` +internal final class GRPCClientChannelHandler { + private let logger: GRPCLogger + private var stateMachine: GRPCClientStateMachine + private let maximumReceiveMessageLength: Int + + /// Creates a new gRPC channel handler for clients to translate HTTP/2 frames to gRPC messages. + /// + /// - Parameters: + /// - callType: Type of RPC call being made. + /// - maximumReceiveMessageLength: Maximum allowed length in bytes of a received message. + /// - logger: Logger. + internal init( + callType: GRPCCallType, + maximumReceiveMessageLength: Int, + logger: GRPCLogger + ) { + self.logger = logger + self.maximumReceiveMessageLength = maximumReceiveMessageLength + switch callType { + case .unary: + self.stateMachine = .init(requestArity: .one, responseArity: .one) + case .clientStreaming: + self.stateMachine = .init(requestArity: .many, responseArity: .one) + case .serverStreaming: + self.stateMachine = .init(requestArity: .one, responseArity: .many) + case .bidirectionalStreaming: + self.stateMachine = .init(requestArity: .many, responseArity: .many) + } + } +} + +// MARK: - GRPCClientChannelHandler: Inbound + +extension GRPCClientChannelHandler: ChannelInboundHandler { + internal typealias InboundIn = HTTP2Frame.FramePayload + internal typealias InboundOut = _RawGRPCClientResponsePart + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let payload = self.unwrapInboundIn(data) + switch payload { + case let .headers(content): + self.readHeaders(content: content, context: context) + + case let .data(content): + self.readData(content: content, context: context) + + // We don't need to handle other frame type, just drop them instead. + default: + // TODO: synthesise a more precise `GRPCStatus` from RST_STREAM frames in accordance + // with: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#errors + break + } + } + + /// Read the content from an HTTP/2 HEADERS frame received from the server. + /// + /// We can receive headers in two cases: + /// - when the RPC is being acknowledged, and + /// - when the RPC is being terminated. + /// + /// It is also possible for the RPC to be acknowledged and terminated at the same time, the + /// specification refers to this as a "Trailers-Only" response. + /// + /// - Parameter content: Content of the headers frame. + /// - Parameter context: Channel handler context. + private func readHeaders( + content: HTTP2Frame.FramePayload.Headers, + context: ChannelHandlerContext + ) { + self.logger.trace("received HTTP2 frame", metadata: [ + MetadataKey.h2Payload: "HEADERS", + MetadataKey.h2Headers: "\(content.headers)", + MetadataKey.h2EndStream: "\(content.endStream)", + ]) + + // In the case of a "Trailers-Only" response there's no guarantee that end-of-stream will be set + // on the headers frame: end stream may be sent on an empty data frame as well. If the headers + // contain a gRPC status code then they must be for a "Trailers-Only" response. + if content.endStream || content.headers.contains(name: GRPCHeaderName.statusCode) { + // We have the headers, pass them to the next handler: + context.fireChannelRead(self.wrapInboundOut(.trailingMetadata(content.headers))) + + // Are they valid headers? + let result = self.stateMachine.receiveEndOfResponseStream(content.headers) + .mapError { error -> GRPCError.WithContext in + // The headers aren't valid so let's figure out a reasonable error to forward: + switch error { + case let .invalidContentType(contentType): + return GRPCError.InvalidContentType(contentType).captureContext() + case let .invalidHTTPStatus(status): + return GRPCError.InvalidHTTPStatus(status).captureContext() + case let .invalidHTTPStatusWithGRPCStatus(status): + return GRPCError.InvalidHTTPStatusWithGRPCStatus(status).captureContext() + case .invalidState: + return GRPCError.InvalidState("parsing end-of-stream trailers").captureContext() + } + } + + // Okay, what should we tell the next handler? + switch result { + case let .success(status): + context.fireChannelRead(self.wrapInboundOut(.status(status))) + case let .failure(error): + context.fireErrorCaught(error) + } + } else { + // "Normal" response headers, but are they valid? + let result = self.stateMachine.receiveResponseHeaders(content.headers) + .mapError { error -> GRPCError.WithContext in + // The headers aren't valid so let's figure out a reasonable error to forward: + switch error { + case let .invalidContentType(contentType): + return GRPCError.InvalidContentType(contentType).captureContext() + case let .invalidHTTPStatus(status): + return GRPCError.InvalidHTTPStatus(status).captureContext() + case .unsupportedMessageEncoding: + return GRPCError.CompressionUnsupported().captureContext() + case .invalidState: + return GRPCError.InvalidState("parsing headers").captureContext() + } + } + + // Okay, what should we tell the next handler? + switch result { + case .success: + context.fireChannelRead(self.wrapInboundOut(.initialMetadata(content.headers))) + case let .failure(error): + context.fireErrorCaught(error) + } + } + } + + /// Reads the content from an HTTP/2 DATA frame received from the server and buffers the bytes + /// necessary to deserialize a message (or messages). + /// + /// - Parameter content: Content of the data frame. + /// - Parameter context: Channel handler context. + private func readData(content: HTTP2Frame.FramePayload.Data, context: ChannelHandlerContext) { + // Note: this is replicated from NIO's HTTP2ToHTTP1ClientCodec. + guard case var .byteBuffer(buffer) = content.data else { + preconditionFailure("Received DATA frame with non-ByteBuffer IOData") + } + + self.logger.trace("received HTTP2 frame", metadata: [ + MetadataKey.h2Payload: "DATA", + MetadataKey.h2DataBytes: "\(content.data.readableBytes)", + MetadataKey.h2EndStream: "\(content.endStream)", + ]) + + self.consumeBytes(from: &buffer, context: context) + + // End stream is set; we don't usually expect this but can handle it in some situations. + if content.endStream, let status = self.stateMachine.receiveEndOfResponseStream() { + self.logger.warning("Unexpected end stream set on DATA frame") + context.fireChannelRead(self.wrapInboundOut(.status(status))) + } + } + + private func consumeBytes(from buffer: inout ByteBuffer, context: ChannelHandlerContext) { + // Do we have bytes to read? If there are no bytes to read then we can't do anything. This may + // happen if the end-of-stream flag is not set on the trailing headers frame (i.e. the one + // containing the gRPC status code) and an additional empty data frame is sent with the + // end-of-stream flag set. + guard buffer.readableBytes > 0 else { + return + } + + // Feed the buffer into the state machine. + let result = self.stateMachine.receiveResponseBuffer( + &buffer, + maxMessageLength: self.maximumReceiveMessageLength + ).mapError { error -> GRPCError.WithContext in + switch error { + case .cardinalityViolation: + return GRPCError.StreamCardinalityViolation.response.captureContext() + case .deserializationFailed, .leftOverBytes: + return GRPCError.DeserializationFailure().captureContext() + case let .decompressionLimitExceeded(compressedSize): + return GRPCError.DecompressionLimitExceeded(compressedSize: compressedSize) + .captureContext() + case let .lengthExceedsLimit(underlyingError): + return underlyingError.captureContext() + case .invalidState: + return GRPCError.InvalidState("parsing data as a response message").captureContext() + } + } + + // Did we get any messages? + switch result { + case let .success(messages): + // Awesome: we got some messages. The state machine guarantees we only get at most a single + // message for unary and client-streaming RPCs. + for message in messages { + // Note: `compressed: false` is currently just a placeholder. This is fine since the message + // context is not currently exposed to the user. If we implement interceptors for the client + // and decide to surface this information then we'll need to extract that information from + // the message reader. + context.fireChannelRead(self.wrapInboundOut(.message(.init(message, compressed: false)))) + } + case let .failure(error): + context.fireErrorCaught(error) + } + } +} + +// MARK: - GRPCClientChannelHandler: Outbound + +extension GRPCClientChannelHandler: ChannelOutboundHandler { + internal typealias OutboundIn = _RawGRPCClientRequestPart + internal typealias OutboundOut = HTTP2Frame.FramePayload + + internal func write( + context: ChannelHandlerContext, + data: NIOAny, + promise: EventLoopPromise? + ) { + switch self.unwrapOutboundIn(data) { + case let .head(requestHead): + // Feed the request into the state machine: + switch self.stateMachine.sendRequestHeaders(requestHead: requestHead) { + case let .success(headers): + // We're clear to write some headers. Create an appropriate frame and write it. + let framePayload = HTTP2Frame.FramePayload.headers(.init(headers: headers)) + self.logger.trace("writing HTTP2 frame", metadata: [ + MetadataKey.h2Payload: "HEADERS", + MetadataKey.h2Headers: "\(headers)", + MetadataKey.h2EndStream: "false", + ]) + context.write(self.wrapOutboundOut(framePayload), promise: promise) + + case let .failure(sendRequestHeadersError): + switch sendRequestHeadersError { + case .invalidState: + // This is bad: we need to trigger an error and close the channel. + promise?.fail(sendRequestHeadersError) + context.fireErrorCaught(GRPCError.InvalidState("unable to initiate RPC").captureContext()) + } + } + + case let .message(request): + // Feed the request message into the state machine: + let result = self.stateMachine.sendRequest( + request.message, + compressed: request.compressed, + allocator: context.channel.allocator + ) + switch result { + case let .success(buffer): + // We're clear to send a message; wrap it up in an HTTP/2 frame. + let framePayload = HTTP2Frame.FramePayload.data(.init(data: .byteBuffer(buffer))) + self.logger.trace("writing HTTP2 frame", metadata: [ + MetadataKey.h2Payload: "DATA", + MetadataKey.h2DataBytes: "\(buffer.readableBytes)", + MetadataKey.h2EndStream: "false", + ]) + context.write(self.wrapOutboundOut(framePayload), promise: promise) + + case let .failure(writeError): + switch writeError { + case .cardinalityViolation: + // This is fine: we can ignore the request. The RPC can continue as if nothing went wrong. + promise?.fail(writeError) + + case .serializationFailed: + // This is bad: we need to trigger an error and close the channel. + promise?.fail(writeError) + context.fireErrorCaught(GRPCError.SerializationFailure().captureContext()) + + case .invalidState: + promise?.fail(writeError) + context + .fireErrorCaught(GRPCError.InvalidState("unable to write message").captureContext()) + } + } + + case .end: + // Okay: can we close the request stream? + switch self.stateMachine.sendEndOfRequestStream() { + case .success: + // We can. Send an empty DATA frame with end-stream set. + let empty = context.channel.allocator.buffer(capacity: 0) + let framePayload = HTTP2Frame.FramePayload + .data(.init(data: .byteBuffer(empty), endStream: true)) + self.logger.trace("writing HTTP2 frame", metadata: [ + MetadataKey.h2Payload: "DATA", + MetadataKey.h2DataBytes: "0", + MetadataKey.h2EndStream: "true", + ]) + context.write(self.wrapOutboundOut(framePayload), promise: promise) + + case let .failure(error): + // Why can't we close the request stream? + switch error { + case .alreadyClosed: + // This is fine: we can just ignore it. The RPC can continue as if nothing went wrong. + promise?.fail(error) + + case .invalidState: + // This is bad: we need to trigger an error and close the channel. + promise?.fail(error) + context + .fireErrorCaught( + GRPCError.InvalidState("unable to close request stream") + .captureContext() + ) + } + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientStateMachine.swift new file mode 100644 index 00000000..c7f02865 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCClientStateMachine.swift @@ -0,0 +1,757 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import SwiftProtobuf + +enum ReceiveResponseHeadError: Error, Equatable { + /// The 'content-type' header was missing or the value is not supported by this implementation. + case invalidContentType(String?) + + /// The HTTP response status from the server was not 200 OK. + case invalidHTTPStatus(String?) + + /// The encoding used by the server is not supported. + case unsupportedMessageEncoding(String) + + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} + +enum ReceiveEndOfResponseStreamError: Error, Equatable { + /// The 'content-type' header was missing or the value is not supported by this implementation. + case invalidContentType(String?) + + /// The HTTP response status from the server was not 200 OK. + case invalidHTTPStatus(String?) + + /// The HTTP response status from the server was not 200 OK but the "grpc-status" header contained + /// a valid value. + case invalidHTTPStatusWithGRPCStatus(GRPCStatus) + + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} + +enum SendRequestHeadersError: Error { + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} + +enum SendEndOfRequestStreamError: Error { + /// The request stream has already been closed. This may happen if the RPC was cancelled, timed + /// out, the server terminated the RPC, or the user explicitly closed the stream multiple times. + case alreadyClosed + + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} + +/// A state machine for a single gRPC call from the perspective of a client. +/// +/// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md +struct GRPCClientStateMachine { + /// The combined state of the request (client) and response (server) streams for an RPC call. + /// + /// The following states are not possible: + /// - `.clientIdleServerActive`: The client must initiate the call before the server moves + /// from the idle state. + /// - `.clientIdleServerClosed`: The client must initiate the call before the server moves from + /// the idle state. + /// - `.clientActiveServerClosed`: The client may not stream if the server is closed. + /// + /// Note: when a peer (client or server) state is "active" it means that messages _may_ be sent or + /// received. That is, the headers for the stream have been processed by the state machine and + /// end-of-stream has not yet been processed. A stream may expect any number of messages (i.e. up + /// to one for a unary call and many for a streaming call). + enum State { + /// Initial state. Neither request stream nor response stream have been initiated. Holds the + /// pending write state for the request stream and arity for the response stream, respectively. + /// + /// Valid transitions: + /// - `clientActiveServerIdle`: if the client initiates the RPC, + /// - `clientClosedServerClosed`: if the client terminates the RPC. + case clientIdleServerIdle(pendingWriteState: PendingWriteState, readArity: MessageArity) + + /// The client has initiated an RPC and has not received initial metadata from the server. Holds + /// the writing state for request stream and arity for the response stream. + /// + /// Valid transitions: + /// - `clientActiveServerActive`: if the server acknowledges the RPC initiation, + /// - `clientClosedServerIdle`: if the client closes the request stream, + /// - `clientClosedServerClosed`: if the client terminates the RPC or the server terminates the + /// RPC with a "trailers-only" response. + case clientActiveServerIdle(writeState: WriteState, pendingReadState: PendingReadState) + + /// The client has indicated to the server that it has finished sending requests. The server + /// has not yet sent response headers for the RPC. Holds the response stream arity. + /// + /// Valid transitions: + /// - `clientClosedServerActive`: if the server acknowledges the RPC initiation, + /// - `clientClosedServerClosed`: if the client terminates the RPC or the server terminates the + /// RPC with a "trailers-only" response. + case clientClosedServerIdle(pendingReadState: PendingReadState) + + /// The client has initiated the RPC and the server has acknowledged it. Messages may have been + /// sent and/or received. Holds the request stream write state and response stream read state. + /// + /// Valid transitions: + /// - `clientClosedServerActive`: if the client closes the request stream, + /// - `clientClosedServerClosed`: if the client or server terminates the RPC. + case clientActiveServerActive(writeState: WriteState, readState: ReadState) + + /// The client has indicated to the server that it has finished sending requests. The server + /// has acknowledged the RPC. Holds the response stream read state. + /// + /// Valid transitions: + /// - `clientClosedServerClosed`: if the client or server terminate the RPC. + case clientClosedServerActive(readState: ReadState) + + /// The RPC has terminated. There are no valid transitions from this state. + case clientClosedServerClosed + + /// This isn't a real state. See `withStateAvoidingCoWs`. + case modifying + } + + /// The current state of the state machine. + internal private(set) var state: State + + /// The default user-agent string. + private static let userAgent = "grpc-swift-nio/\(Version.versionString)" + + /// Creates a state machine representing a gRPC client's request and response stream state. + /// + /// - Parameter requestArity: The expected number of messages on the request stream. + /// - Parameter responseArity: The expected number of messages on the response stream. + init(requestArity: MessageArity, responseArity: MessageArity) { + self.state = .clientIdleServerIdle( + pendingWriteState: .init(arity: requestArity, contentType: .protobuf), + readArity: responseArity + ) + } + + /// Creates a state machine representing a gRPC client's request and response stream state. + /// + /// - Parameter state: The initial state of the state machine. + init(state: State) { + self.state = state + } + + /// Initiates an RPC. + /// + /// The only valid state transition is: + /// - `.clientIdleServerIdle` → `.clientActiveServerIdle` + /// + /// All other states will result in an `.invalidState` error. + /// + /// On success the state will transition to `.clientActiveServerIdle`. + /// + /// - Parameter requestHead: The client request head for the RPC. + mutating func sendRequestHeaders( + requestHead: _GRPCRequestHead + ) -> Result { + return self.withStateAvoidingCoWs { state in + state.sendRequestHeaders(requestHead: requestHead) + } + } + + /// Formats a request to send to the server. + /// + /// The client must be streaming in order for this to return successfully. Therefore the valid + /// state transitions are: + /// - `.clientActiveServerIdle` → `.clientActiveServerIdle` + /// - `.clientActiveServerActive` → `.clientActiveServerActive` + /// + /// The client should not attempt to send requests once the request stream is closed, that is + /// from one of the following states: + /// - `.clientClosedServerIdle` + /// - `.clientClosedServerActive` + /// - `.clientClosedServerClosed` + /// Doing so will result in a `.cardinalityViolation`. + /// + /// Sending a message when both peers are idle (in the `.clientIdleServerIdle` state) will result + /// in a `.invalidState` error. + /// + /// - Parameter message: The serialized request to send to the server. + /// - Parameter compressed: Whether the request should be compressed. + /// - Parameter allocator: A `ByteBufferAllocator` to allocate the buffer into which the encoded + /// request will be written. + mutating func sendRequest( + _ message: ByteBuffer, + compressed: Bool, + allocator: ByteBufferAllocator + ) -> Result { + return self.withStateAvoidingCoWs { state in + state.sendRequest(message, compressed: compressed, allocator: allocator) + } + } + + /// Closes the request stream. + /// + /// The client must be streaming requests in order to terminate the request stream. Valid + /// states transitions are: + /// - `.clientActiveServerIdle` → `.clientClosedServerIdle` + /// - `.clientActiveServerActive` → `.clientClosedServerActive` + /// + /// The client should not attempt to close the request stream if it is already closed, that is + /// from one of the following states: + /// - `.clientClosedServerIdle` + /// - `.clientClosedServerActive` + /// - `.clientClosedServerClosed` + /// Doing so will result in an `.alreadyClosed` error. + /// + /// Closing the request stream when both peers are idle (in the `.clientIdleServerIdle` state) + /// will result in a `.invalidState` error. + mutating func sendEndOfRequestStream() -> Result { + return self.withStateAvoidingCoWs { state in + state.sendEndOfRequestStream() + } + } + + /// Receive an acknowledgement of the RPC from the server. This **must not** be a "Trailers-Only" + /// response. + /// + /// The server must be idle in order to receive response headers. The valid state transitions are: + /// - `.clientActiveServerIdle` → `.clientActiveServerActive` + /// - `.clientClosedServerIdle` → `.clientClosedServerActive` + /// + /// The response head will be parsed and validated against the gRPC specification. The following + /// errors may be returned: + /// - `.invalidHTTPStatus` if the status was not "200", + /// - `.invalidContentType` if the "content-type" header does not start with "application/grpc", + /// - `.unsupportedMessageEncoding` if the "grpc-encoding" header is not supported. + /// + /// It is not possible to receive response headers from the following states: + /// - `.clientIdleServerIdle` + /// - `.clientActiveServerActive` + /// - `.clientClosedServerActive` + /// - `.clientClosedServerClosed` + /// Doing so will result in a `.invalidState` error. + /// + /// - Parameter headers: The headers received from the server. + mutating func receiveResponseHeaders( + _ headers: HPACKHeaders + ) -> Result { + return self.withStateAvoidingCoWs { state in + state.receiveResponseHeaders(headers) + } + } + + /// Read a response buffer from the server and return any decoded messages. + /// + /// If the response stream has an expected count of `.one` then this function is guaranteed to + /// produce *at most* one `Response` in the `Result`. + /// + /// To receive a response buffer the server must be streaming. Valid states are: + /// - `.clientClosedServerActive` → `.clientClosedServerActive` + /// - `.clientActiveServerActive` → `.clientActiveServerActive` + /// + /// This function will read all of the bytes in the `buffer` and attempt to produce as many + /// messages as possible. This may lead to a number of errors: + /// - `.cardinalityViolation` if more than one message is received when the state reader is + /// expects at most one. + /// - `.leftOverBytes` if bytes remain in the buffer after reading one message when at most one + /// message is expected. + /// - `.deserializationFailed` if the message could not be deserialized. + /// + /// It is not possible to receive response headers from the following states: + /// - `.clientIdleServerIdle` + /// - `.clientClosedServerActive` + /// - `.clientActiveServerActive` + /// - `.clientClosedServerClosed` + /// Doing so will result in a `.invalidState` error. + /// + /// - Parameter buffer: A buffer of bytes received from the server. + mutating func receiveResponseBuffer( + _ buffer: inout ByteBuffer, + maxMessageLength: Int + ) -> Result<[ByteBuffer], MessageReadError> { + return self.withStateAvoidingCoWs { state in + state.receiveResponseBuffer(&buffer, maxMessageLength: maxMessageLength) + } + } + + /// Receive the end of the response stream from the server and parse the results into + /// a `GRPCStatus`. + /// + /// To close the response stream the server must be streaming or idle (since the server may choose + /// to 'fast fail' the RPC). Valid states are: + /// - `.clientActiveServerIdle` → `.clientClosedServerClosed` + /// - `.clientActiveServerActive` → `.clientClosedServerClosed` + /// - `.clientClosedServerIdle` → `.clientClosedServerClosed` + /// - `.clientClosedServerActive` → `.clientClosedServerClosed` + /// + /// It is not possible to receive an end-of-stream if the RPC has not been initiated or has + /// already been terminated. That is, in one of the following states: + /// - `.clientIdleServerIdle` + /// - `.clientClosedServerClosed` + /// Doing so will result in a `.invalidState` error. + /// + /// - Parameter trailers: The trailers to parse. + mutating func receiveEndOfResponseStream( + _ trailers: HPACKHeaders + ) -> Result { + return self.withStateAvoidingCoWs { state in + state.receiveEndOfResponseStream(trailers) + } + } + + /// Receive a DATA frame with the end stream flag set. Determines whether it is safe for the + /// caller to ignore the end stream flag or whether a synthesised status should be forwarded. + /// + /// Receiving a DATA frame with the end stream flag set is unexpected: the specification dictates + /// that an RPC should be ended by the server sending the client a HEADERS frame with end stream + /// set. However, we will tolerate end stream on a DATA frame if we believe the RPC has already + /// completed (i.e. we are in the 'clientClosedServerClosed' state). In cases where we don't + /// expect end of stream on a DATA frame we will emit a status with a message explaining + /// the protocol violation. + mutating func receiveEndOfResponseStream() -> GRPCStatus? { + return self.withStateAvoidingCoWs { state in + state.receiveEndOfResponseStream() + } + } + + /// Temporarily sets `self.state` to `.modifying` before calling the provided block and setting + /// `self.state` to the `State` modified by the block. + /// + /// Since we hold state as associated data on our `State` enum, any modification to that state + /// will trigger a copy on write for its heap allocated data. Temporarily setting the `self.state` + /// to `.modifying` allows us to avoid an extra reference to any heap allocated data and therefore + /// avoid a copy on write. + @inline(__always) + private mutating func withStateAvoidingCoWs( + _ body: (inout State) -> ResultType + ) -> ResultType { + var state = State.modifying + swap(&self.state, &state) + defer { + swap(&self.state, &state) + } + return body(&state) + } +} + +extension GRPCClientStateMachine.State { + /// See `GRPCClientStateMachine.sendRequestHeaders(requestHead:)`. + mutating func sendRequestHeaders( + requestHead: _GRPCRequestHead + ) -> Result { + let result: Result + + switch self { + case let .clientIdleServerIdle(pendingWriteState, responseArity): + let headers = self.makeRequestHeaders( + method: requestHead.method, + scheme: requestHead.scheme, + host: requestHead.host, + path: requestHead.path, + timeout: GRPCTimeout(deadline: requestHead.deadline), + customMetadata: requestHead.customMetadata, + compression: requestHead.encoding + ) + result = .success(headers) + + self = .clientActiveServerIdle( + writeState: pendingWriteState.makeWriteState(messageEncoding: requestHead.encoding), + pendingReadState: .init(arity: responseArity, messageEncoding: requestHead.encoding) + ) + + case .clientActiveServerIdle, + .clientClosedServerIdle, + .clientClosedServerActive, + .clientActiveServerActive, + .clientClosedServerClosed: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.sendRequest(_:allocator:)`. + mutating func sendRequest( + _ message: ByteBuffer, + compressed: Bool, + allocator: ByteBufferAllocator + ) -> Result { + let result: Result + + switch self { + case .clientActiveServerIdle(var writeState, let pendingReadState): + result = writeState.write(message, compressed: compressed, allocator: allocator) + self = .clientActiveServerIdle(writeState: writeState, pendingReadState: pendingReadState) + + case .clientActiveServerActive(var writeState, let readState): + result = writeState.write(message, compressed: compressed, allocator: allocator) + self = .clientActiveServerActive(writeState: writeState, readState: readState) + + case .clientClosedServerIdle, + .clientClosedServerActive, + .clientClosedServerClosed: + result = .failure(.cardinalityViolation) + + case .clientIdleServerIdle: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.sendEndOfRequestStream()`. + mutating func sendEndOfRequestStream() -> Result { + let result: Result + + switch self { + case let .clientActiveServerIdle(_, pendingReadState): + result = .success(()) + self = .clientClosedServerIdle(pendingReadState: pendingReadState) + + case let .clientActiveServerActive(_, readState): + result = .success(()) + self = .clientClosedServerActive(readState: readState) + + case .clientClosedServerIdle, + .clientClosedServerActive, + .clientClosedServerClosed: + result = .failure(.alreadyClosed) + + case .clientIdleServerIdle: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.receiveResponseHeaders(_:)`. + mutating func receiveResponseHeaders( + _ headers: HPACKHeaders + ) -> Result { + let result: Result + + switch self { + case let .clientActiveServerIdle(writeState, pendingReadState): + result = self.parseResponseHeaders(headers, pendingReadState: pendingReadState) + .map { readState in + self = .clientActiveServerActive(writeState: writeState, readState: readState) + } + + case let .clientClosedServerIdle(pendingReadState): + result = self.parseResponseHeaders(headers, pendingReadState: pendingReadState) + .map { readState in + self = .clientClosedServerActive(readState: readState) + } + + case .clientIdleServerIdle, + .clientClosedServerActive, + .clientActiveServerActive, + .clientClosedServerClosed: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.receiveResponseBuffer(_:)`. + mutating func receiveResponseBuffer( + _ buffer: inout ByteBuffer, + maxMessageLength: Int + ) -> Result<[ByteBuffer], MessageReadError> { + let result: Result<[ByteBuffer], MessageReadError> + + switch self { + case var .clientClosedServerActive(readState): + result = readState.readMessages(&buffer, maxLength: maxMessageLength) + self = .clientClosedServerActive(readState: readState) + + case .clientActiveServerActive(let writeState, var readState): + result = readState.readMessages(&buffer, maxLength: maxMessageLength) + self = .clientActiveServerActive(writeState: writeState, readState: readState) + + case .clientIdleServerIdle, + .clientActiveServerIdle, + .clientClosedServerIdle, + .clientClosedServerClosed: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.receiveEndOfResponseStream(_:)`. + mutating func receiveEndOfResponseStream( + _ trailers: HPACKHeaders + ) -> Result { + let result: Result + + switch self { + case .clientActiveServerIdle, + .clientClosedServerIdle: + result = self.parseTrailersOnly(trailers).map { status in + self = .clientClosedServerClosed + return status + } + + case .clientActiveServerActive, + .clientClosedServerActive: + result = .success(self.parseTrailers(trailers)) + self = .clientClosedServerClosed + + case .clientIdleServerIdle, + .clientClosedServerClosed: + result = .failure(.invalidState) + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return result + } + + /// See `GRPCClientStateMachine.receiveEndOfResponseStream()`. + mutating func receiveEndOfResponseStream() -> GRPCStatus? { + let status: GRPCStatus? + + switch self { + case .clientIdleServerIdle: + // Can't see end stream before writing on it. + preconditionFailure() + + case .clientActiveServerIdle, + .clientActiveServerActive, + .clientClosedServerIdle, + .clientClosedServerActive: + self = .clientClosedServerClosed + status = .init( + code: .internalError, + message: "Protocol violation: received DATA frame with end stream set" + ) + + case .clientClosedServerClosed: + // We've already closed. Ignore this. + status = nil + + case .modifying: + preconditionFailure("State left as 'modifying'") + } + + return status + } + + /// Makes the request headers (`Request-Headers` in the specification) used to initiate an RPC + /// call. + /// + /// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests + /// + /// - Parameter host: The host serving the RPC. + /// - Parameter options: Any options related to the call. + /// - Parameter requestID: A request ID associated with the call. An additional header will be + /// added using this value if `options.requestIDHeader` is specified. + private func makeRequestHeaders( + method: String, + scheme: String, + host: String, + path: String, + timeout: GRPCTimeout, + customMetadata: HPACKHeaders, + compression: ClientMessageEncoding + ) -> HPACKHeaders { + var headers = HPACKHeaders() + // The 10 is: + // - 6 which are required and added just below, and + // - 4 which are possibly added, depending on conditions. + headers.reserveCapacity(10 + customMetadata.count) + + // Add the required headers. + headers.add(name: ":method", value: method) + headers.add(name: ":path", value: path) + headers.add(name: ":authority", value: host) + headers.add(name: ":scheme", value: scheme) + headers.add(name: "content-type", value: "application/grpc") + // Used to detect incompatible proxies, part of the gRPC specification. + headers.add(name: "te", value: "trailers") + + switch compression { + case let .enabled(configuration): + // Request encoding. + if let outbound = configuration.outbound { + headers.add(name: GRPCHeaderName.encoding, value: outbound.name) + } + + // Response encoding. + if !configuration.inbound.isEmpty { + headers.add(name: GRPCHeaderName.acceptEncoding, value: configuration.acceptEncodingHeader) + } + + case .disabled: + () + } + + // Add the timeout header, if a timeout was specified. + if timeout != .infinite { + headers.add(name: GRPCHeaderName.timeout, value: String(describing: timeout)) + } + + // Add user-defined custom metadata: this should come after the call definition headers. + // TODO: make header normalization user-configurable. + headers.add(contentsOf: customMetadata.lazy.map { name, value, indexing in + (name.lowercased(), value, indexing) + }) + + // Add default user-agent value, if `customMetadata` didn't contain user-agent + if !customMetadata.contains(name: "user-agent") { + headers.add(name: "user-agent", value: GRPCClientStateMachine.userAgent) + } + + return headers + } + + /// Parses the response headers ("Response-Headers" in the specification) from the server into + /// a `ReadState`. + /// + /// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses + /// + /// - Parameter headers: The headers to parse. + private func parseResponseHeaders( + _ headers: HPACKHeaders, + pendingReadState: PendingReadState + ) -> Result { + // From: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses + // + // "Implementations should expect broken deployments to send non-200 HTTP status codes in + // responses as well as a variety of non-GRPC content-types and to omit Status & Status-Message. + // Implementations must synthesize a Status & Status-Message to propagate to the application + // layer when this occurs." + let statusHeader = headers.first(name: ":status") + let responseStatus = statusHeader + .flatMap(Int.init) + .map { code in + HTTPResponseStatus(statusCode: code) + } ?? .preconditionFailed + + guard responseStatus == .ok else { + return .failure(.invalidHTTPStatus(statusHeader)) + } + + let contentTypeHeader = headers.first(name: "content-type") + guard contentTypeHeader.flatMap(ContentType.init) != nil else { + return .failure(.invalidContentType(contentTypeHeader)) + } + + let result: Result + + // What compression mechanism is the server using, if any? + if let encodingHeader = headers.first(name: GRPCHeaderName.encoding) { + // Note: the server is allowed to encode messages using an algorithm which wasn't included in + // the 'grpc-accept-encoding' header. If the client still supports that algorithm (despite not + // permitting the server to use it) then it must still decode that message. Ideally we should + // log a message here if that was the case but we don't hold that information. + if let compression = CompressionAlgorithm(rawValue: encodingHeader) { + result = .success(pendingReadState.makeReadState(compression: compression)) + } else { + // The algorithm isn't one we support. + result = .failure(.unsupportedMessageEncoding(encodingHeader)) + } + } else { + // No compression was specified, this is fine. + result = .success(pendingReadState.makeReadState(compression: nil)) + } + + return result + } + + /// Parses the response trailers ("Trailers" in the specification) from the server into + /// a `GRPCStatus`. + /// + /// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses + /// + /// - Parameter trailers: Trailers to parse. + private func parseTrailers(_ trailers: HPACKHeaders) -> GRPCStatus { + // Extract the "Status" and "Status-Message" + let code = self.readStatusCode(from: trailers) ?? .unknown + let message = self.readStatusMessage(from: trailers) + return .init(code: code, message: message) + } + + private func readStatusCode(from trailers: HPACKHeaders) -> GRPCStatus.Code? { + return trailers.first(name: GRPCHeaderName.statusCode) + .flatMap(Int.init) + .flatMap(GRPCStatus.Code.init) + } + + private func readStatusMessage(from trailers: HPACKHeaders) -> String? { + return trailers.first(name: GRPCHeaderName.statusMessage) + .map(GRPCStatusMessageMarshaller.unmarshall) + } + + /// Parses a "Trailers-Only" response from the server into a `GRPCStatus`. + /// + /// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses + /// + /// - Parameter trailers: Trailers to parse. + private func parseTrailersOnly( + _ trailers: HPACKHeaders + ) -> Result { + // We need to check whether we have a valid HTTP status in the headers, if we don't then we also + // need to check whether we have a gRPC status as it should take preference over a synthesising + // one from the ":status". + // + // See: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + let statusHeader = trailers.first(name: ":status") + guard let status = statusHeader.flatMap(Int.init).map({ HTTPResponseStatus(statusCode: $0) }) + else { + return .failure(.invalidHTTPStatus(statusHeader)) + } + + guard status == .ok else { + if let code = self.readStatusCode(from: trailers) { + let message = self.readStatusMessage(from: trailers) + return .failure(.invalidHTTPStatusWithGRPCStatus(.init(code: code, message: message))) + } else { + return .failure(.invalidHTTPStatus(statusHeader)) + } + } + + // Only validate the content-type header if it's present. This is a small deviation from the + // spec as the content-type is meant to be sent in "Trailers-Only" responses. However, if it's + // missing then we should avoid the error and propagate the status code and message sent by + // the server instead. + if let contentTypeHeader = trailers.first(name: "content-type"), + ContentType(value: contentTypeHeader) == nil { + return .failure(.invalidContentType(contentTypeHeader)) + } + + // We've verified the status and content type are okay: parse the trailers. + return .success(self.parseTrailers(trailers)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCContentType.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCContentType.swift new file mode 100644 index 00000000..2f522c1a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCContentType.swift @@ -0,0 +1,59 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// See: +// - https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md +// - https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md +internal enum ContentType { + case protobuf + case webProtobuf + case webTextProtobuf + + init?(value: String) { + switch value { + case "application/grpc", + "application/grpc+proto": + self = .protobuf + + case "application/grpc-web", + "application/grpc-web+proto": + self = .webProtobuf + + case "application/grpc-web-text", + "application/grpc-web-text+proto": + self = .webTextProtobuf + + default: + return nil + } + } + + var canonicalValue: String { + switch self { + case .protobuf: + // This is more widely supported than "application/grpc+proto" + return "application/grpc" + + case .webProtobuf: + return "application/grpc-web+proto" + + case .webTextProtobuf: + return "application/grpc-web-text+proto" + } + } + + static let commonPrefix = "application/grpc" +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCError.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCError.swift new file mode 100644 index 00000000..5c247bfe --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCError.swift @@ -0,0 +1,362 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// An error thrown by the gRPC library. +/// +/// Implementation details: this is a case-less `enum` with an inner-class per error type. This +/// allows for additional error classes to be added as a SemVer minor change. +/// +/// Unfortunately it is not possible to use a private inner `enum` with static property 'cases' on +/// the outer type to mirror each case of the inner `enum` as many of the errors require associated +/// values (pattern matching is not possible). +public enum GRPCError { + /// The RPC is not implemented on the server. + public struct RPCNotImplemented: GRPCErrorProtocol { + /// The path of the RPC which was called, e.g. '/echo.Echo/Get'. + public var rpc: String + + public init(rpc: String) { + self.rpc = rpc + } + + public var description: String { + return "RPC '\(self.rpc)' is not implemented" + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .unimplemented, message: self.description) + } + } + + /// The RPC was cancelled by the client. + public struct RPCCancelledByClient: GRPCErrorProtocol { + public let description: String = "RPC was cancelled by the client" + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .cancelled, message: self.description, cause: self) + } + } + + /// The RPC did not complete before the timeout. + public struct RPCTimedOut: GRPCErrorProtocol { + /// The time limit which was exceeded by the RPC. + public var timeLimit: TimeLimit + + public init(_ timeLimit: TimeLimit) { + self.timeLimit = timeLimit + } + + public var description: String { + return "RPC timed out before completing" + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .deadlineExceeded, message: self.description, cause: self) + } + } + + /// A message was not able to be serialized. + public struct SerializationFailure: GRPCErrorProtocol { + public let description = "Message serialization failed" + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// A message was not able to be deserialized. + public struct DeserializationFailure: GRPCErrorProtocol { + public let description = "Message deserialization failed" + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// The length of the received payload was longer than is permitted. + public struct PayloadLengthLimitExceeded: GRPCErrorProtocol { + public let description: String + + public init(actualLength length: Int, limit: Int) { + self.description = "Payload length exceeds limit (\(length) > \(limit))" + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .resourceExhausted, message: self.description, cause: self) + } + } + + /// It was not possible to compress or decompress a message with zlib. + public struct ZlibCompressionFailure: GRPCErrorProtocol { + var code: Int32 + var message: String? + + public init(code: Int32, message: String?) { + self.code = code + self.message = message + } + + public var description: String { + if let message = self.message { + return "Zlib error: \(self.code) \(message)" + } else { + return "Zlib error: \(self.code)" + } + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// The decompression limit was exceeded while decompressing a message. + public struct DecompressionLimitExceeded: GRPCErrorProtocol { + /// The size of the compressed payload whose decompressed size exceeded the decompression limit. + public let compressedSize: Int + + public init(compressedSize: Int) { + self.compressedSize = compressedSize + } + + public var description: String { + return "Decompression limit exceeded with \(self.compressedSize) compressed bytes" + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .resourceExhausted, message: nil, cause: self) + } + } + + /// It was not possible to decode a base64 message (gRPC-Web only). + public struct Base64DecodeError: GRPCErrorProtocol { + public let description = "Base64 message decoding failed" + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// The compression mechanism used was not supported. + public struct CompressionUnsupported: GRPCErrorProtocol { + public let description = "The compression used is not supported" + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .unimplemented, message: self.description, cause: self) + } + } + + /// Too many, or too few, messages were sent over the given stream. + public struct StreamCardinalityViolation: GRPCErrorProtocol { + /// The stream on which there was a cardinality violation. + public let description: String + + /// A request stream cardinality violation. + public static let request = StreamCardinalityViolation("Request stream cardinality violation") + + /// A response stream cardinality violation. + public static let response = StreamCardinalityViolation("Response stream cardinality violation") + + private init(_ description: String) { + self.description = description + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// The 'content-type' HTTP/2 header was missing or not valid. + public struct InvalidContentType: GRPCErrorProtocol { + /// The value of the 'content-type' header, if it was present. + public var contentType: String? + + public init(_ contentType: String?) { + self.contentType = contentType + } + + public var description: String { + if let contentType = self.contentType { + return "Invalid 'content-type' header: '\(contentType)'" + } else { + return "Missing 'content-type' header" + } + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.description, cause: self) + } + } + + /// The ':status' HTTP/2 header was not "200". + public struct InvalidHTTPStatus: GRPCErrorProtocol { + /// The HTTP/2 ':status' header, if it was present. + public var status: String? + + public init(_ status: String?) { + self.status = status + } + + public var description: String { + if let status = status { + return "Invalid HTTP response status: \(status)" + } else { + return "Missing HTTP ':status' header" + } + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus( + code: .init(httpStatus: self.status), + message: self.description, + cause: self + ) + } + } + + /// The ':status' HTTP/2 header was not "200" but the 'grpc-status' header was present and valid. + public struct InvalidHTTPStatusWithGRPCStatus: GRPCErrorProtocol { + public var status: GRPCStatus + + public init(_ status: GRPCStatus) { + self.status = status + } + + public var description: String { + return "Invalid HTTP response status, but gRPC status was present" + } + + public func makeGRPCStatus() -> GRPCStatus { + return self.status + } + } + + /// Action was taken after the RPC had already completed. + public struct AlreadyComplete: GRPCErrorProtocol { + public var description: String { + return "The RPC has already completed" + } + + public init() {} + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .unavailable, message: self.description, cause: self) + } + } + + /// An invalid state has been reached; something has gone very wrong. + public struct InvalidState: GRPCErrorProtocol { + public var message: String + + public init(_ message: String) { + self.message = "Invalid state: \(message)" + } + + public var description: String { + return self.message + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.message, cause: self) + } + } + + public struct ProtocolViolation: GRPCErrorProtocol { + public var message: String + + public init(_ message: String) { + self.message = "Protocol violation: \(message)" + } + + public var description: String { + return self.message + } + + public func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus(code: .internalError, message: self.message, cause: self) + } + } +} + +extension GRPCError { + struct WithContext: Error, GRPCStatusTransformable { + var error: GRPCStatusTransformable + var file: StaticString + var line: Int + var function: StaticString + + init( + _ error: GRPCStatusTransformable, + file: StaticString = #file, + line: Int = #line, + function: StaticString = #function + ) { + self.error = error + self.file = file + self.line = line + self.function = function + } + + func makeGRPCStatus() -> GRPCStatus { + return self.error.makeGRPCStatus() + } + } +} + +/// Requirements for `GRPCError` types. +public protocol GRPCErrorProtocol: GRPCStatusTransformable, Equatable, CustomStringConvertible {} + +extension GRPCErrorProtocol { + /// Creates a `GRPCError.WithContext` containing a `GRPCError` and the location of the call site. + internal func captureContext( + file: StaticString = #file, + line: Int = #line, + function: StaticString = #function + ) -> GRPCError.WithContext { + return GRPCError.WithContext(self, file: file, line: line, function: function) + } +} + +extension GRPCStatus.Code { + /// The gRPC status code associated with the given HTTP status code. This should only be used if + /// the RPC did not return a 'grpc-status' trailer. + internal init(httpStatus: String?) { + /// See: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + switch httpStatus { + case "400": + self = .internalError + case "401": + self = .unauthenticated + case "403": + self = .permissionDenied + case "404": + self = .unimplemented + case "429", "502", "503", "504": + self = .unavailable + default: + self = .unknown + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCHeaderName.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCHeaderName.swift new file mode 100644 index 00000000..b6d34b31 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCHeaderName.swift @@ -0,0 +1,24 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal enum GRPCHeaderName { + static let timeout = "grpc-timeout" + static let encoding = "grpc-encoding" + static let acceptEncoding = "grpc-accept-encoding" + static let statusCode = "grpc-status" + static let statusMessage = "grpc-message" + static let contentType = "content-type" +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandler.swift new file mode 100644 index 00000000..adddb12e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandler.swift @@ -0,0 +1,326 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHTTP2 + +internal final class GRPCIdleHandler: ChannelInboundHandler { + typealias InboundIn = HTTP2Frame + typealias OutboundOut = HTTP2Frame + + /// The amount of time to wait before closing the channel when there are no active streams. + private let idleTimeout: TimeAmount + + /// The ping handler. + private var pingHandler: PingHandler + + /// The scheduled task which will close the connection after the keep-alive timeout has expired. + private var scheduledClose: Scheduled? + + /// The scheduled task which will ping. + private var scheduledPing: RepeatedTask? + + /// The mode we're operating in. + private let mode: Mode + + private var context: ChannelHandlerContext? + + /// The mode of operation: the client tracks additional connection state in the connection + /// manager. + internal enum Mode { + case client(ConnectionManager, HTTP2StreamMultiplexer) + case server + + var connectionManager: ConnectionManager? { + switch self { + case let .client(manager, _): + return manager + case .server: + return nil + } + } + } + + /// The current state. + private var stateMachine: GRPCIdleHandlerStateMachine + + init( + connectionManager: ConnectionManager, + multiplexer: HTTP2StreamMultiplexer, + idleTimeout: TimeAmount, + keepalive configuration: ClientConnectionKeepalive, + logger: Logger + ) { + self.mode = .client(connectionManager, multiplexer) + self.idleTimeout = idleTimeout + self.stateMachine = .init(role: .client, logger: logger) + self.pingHandler = PingHandler( + pingCode: 5, + interval: configuration.interval, + timeout: configuration.timeout, + permitWithoutCalls: configuration.permitWithoutCalls, + maximumPingsWithoutData: configuration.maximumPingsWithoutData, + minimumSentPingIntervalWithoutData: configuration.minimumSentPingIntervalWithoutData + ) + } + + init( + idleTimeout: TimeAmount, + keepalive configuration: ServerConnectionKeepalive, + logger: Logger + ) { + self.mode = .server + self.stateMachine = .init(role: .server, logger: logger) + self.idleTimeout = idleTimeout + self.pingHandler = PingHandler( + pingCode: 10, + interval: configuration.interval, + timeout: configuration.timeout, + permitWithoutCalls: configuration.permitWithoutCalls, + maximumPingsWithoutData: configuration.maximumPingsWithoutData, + minimumSentPingIntervalWithoutData: configuration.minimumSentPingIntervalWithoutData, + minimumReceivedPingIntervalWithoutData: configuration.minimumReceivedPingIntervalWithoutData, + maximumPingStrikes: configuration.maximumPingStrikes + ) + } + + private func sendGoAway(lastStreamID streamID: HTTP2StreamID) { + guard let context = self.context else { + return + } + + let frame = HTTP2Frame( + streamID: .rootStream, + payload: .goAway(lastStreamID: streamID, errorCode: .noError, opaqueData: nil) + ) + + context.writeAndFlush(self.wrapOutboundOut(frame), promise: nil) + } + + private func perform(operations: GRPCIdleHandlerStateMachine.Operations) { + // Prod the connection manager. + if let event = operations.connectionManagerEvent, let manager = self.mode.connectionManager { + switch event { + case .idle: + manager.idle() + case .inactive: + manager.channelInactive() + case .ready: + manager.ready() + case .quiescing: + manager.beginQuiescing() + } + } + + // Max concurrent streams changed. + if let manager = self.mode.connectionManager, + let maxConcurrentStreams = operations.maxConcurrentStreamsChange { + manager.maxConcurrentStreamsChanged(maxConcurrentStreams) + } + + // Handle idle timeout creation/cancellation. + if let idleTask = operations.idleTask { + switch idleTask { + case let .cancel(task): + task.cancel() + + case .schedule: + if self.idleTimeout != .nanoseconds(.max), let context = self.context { + let task = context.eventLoop.scheduleTask(in: self.idleTimeout) { + self.idleTimeoutFired() + } + self.perform(operations: self.stateMachine.scheduledIdleTimeoutTask(task)) + } + } + } + + // Send a GOAWAY frame. + if let streamID = operations.sendGoAwayWithLastPeerInitiatedStreamID { + let goAwayFrame = HTTP2Frame( + streamID: .rootStream, + payload: .goAway(lastStreamID: streamID, errorCode: .noError, opaqueData: nil) + ) + + self.context?.write(self.wrapOutboundOut(goAwayFrame), promise: nil) + + // We emit a ping after some GOAWAY frames. + if operations.shouldPingAfterGoAway { + let pingFrame = HTTP2Frame( + streamID: .rootStream, + payload: .ping(self.pingHandler.pingDataGoAway, ack: false) + ) + self.context?.write(self.wrapOutboundOut(pingFrame), promise: nil) + } + + self.context?.flush() + } + + // Close the channel, if necessary. + if operations.shouldCloseChannel, let context = self.context { + // Close on the next event-loop tick so we don't drop any events which are + // currently being processed. + context.eventLoop.execute { + context.close(mode: .all, promise: nil) + } + } + } + + private func handlePingAction(_ action: PingHandler.Action) { + switch action { + case .none: + () + + case .cancelScheduledTimeout: + self.scheduledClose?.cancel() + self.scheduledClose = nil + + case let .schedulePing(delay, timeout): + self.schedulePing(in: delay, timeout: timeout) + + case let .reply(framePayload): + let frame = HTTP2Frame(streamID: .rootStream, payload: framePayload) + self.context?.writeAndFlush(self.wrapOutboundOut(frame), promise: nil) + + case .ratchetDownLastSeenStreamID: + self.perform(operations: self.stateMachine.ratchetDownGoAwayStreamID()) + } + } + + private func schedulePing(in delay: TimeAmount, timeout: TimeAmount) { + guard delay != .nanoseconds(.max) else { + return + } + + self.scheduledPing = self.context?.eventLoop.scheduleRepeatedTask( + initialDelay: delay, + delay: delay + ) { _ in + self.handlePingAction(self.pingHandler.pingFired()) + // `timeout` is less than `interval`, guaranteeing that the close task + // will be fired before a new ping is triggered. + assert(timeout < delay, "`timeout` must be less than `interval`") + self.scheduleClose(in: timeout) + } + } + + private func scheduleClose(in timeout: TimeAmount) { + self.scheduledClose = self.context?.eventLoop.scheduleTask(in: timeout) { + self.perform(operations: self.stateMachine.shutdownNow()) + } + } + + private func idleTimeoutFired() { + self.perform(operations: self.stateMachine.idleTimeoutTaskFired()) + } + + func handlerAdded(context: ChannelHandlerContext) { + self.context = context + } + + func handlerRemoved(context: ChannelHandlerContext) { + self.context = nil + } + + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if let created = event as? NIOHTTP2StreamCreatedEvent { + self.perform(operations: self.stateMachine.streamCreated(withID: created.streamID)) + self.handlePingAction(self.pingHandler.streamCreated()) + context.fireUserInboundEventTriggered(event) + } else if let closed = event as? StreamClosedEvent { + self.perform(operations: self.stateMachine.streamClosed(withID: closed.streamID)) + self.handlePingAction(self.pingHandler.streamClosed()) + self.mode.connectionManager?.streamClosed() + context.fireUserInboundEventTriggered(event) + } else if event is ChannelShouldQuiesceEvent { + self.perform(operations: self.stateMachine.initiateGracefulShutdown()) + // Swallow this event. + } else { + context.fireUserInboundEventTriggered(event) + } + } + + func errorCaught(context: ChannelHandlerContext, error: Error) { + // No state machine action here. + self.mode.connectionManager?.channelError(error) + context.fireErrorCaught(error) + } + + func channelActive(context: ChannelHandlerContext) { + self.stateMachine.logger.addIPAddressMetadata( + local: context.localAddress, + remote: context.remoteAddress + ) + + // No state machine action here. + switch self.mode { + case let .client(connectionManager, multiplexer): + connectionManager.channelActive(channel: context.channel, multiplexer: multiplexer) + case .server: + () + } + context.fireChannelActive() + } + + func channelInactive(context: ChannelHandlerContext) { + self.perform(operations: self.stateMachine.channelInactive()) + self.scheduledPing?.cancel() + self.scheduledClose?.cancel() + self.scheduledPing = nil + self.scheduledClose = nil + context.fireChannelInactive() + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let frame = self.unwrapInboundIn(data) + + switch frame.payload { + case .goAway: + self.perform(operations: self.stateMachine.receiveGoAway()) + case let .settings(.settings(settings)): + self.perform(operations: self.stateMachine.receiveSettings(settings)) + case let .ping(data, ack): + self.handlePingAction(self.pingHandler.read(pingData: data, ack: ack)) + default: + // We're not interested in other events. + () + } + + context.fireChannelRead(data) + } +} + +extension HTTP2SettingsParameter { + internal var loggingMetadataKey: String { + switch self { + case .headerTableSize: + return "h2_settings_header_table_size" + case .enablePush: + return "h2_settings_enable_push" + case .maxConcurrentStreams: + return "h2_settings_max_concurrent_streams" + case .initialWindowSize: + return "h2_settings_initial_window_size" + case .maxFrameSize: + return "h2_settings_max_frame_size" + case .maxHeaderListSize: + return "h2_settings_max_header_list_size" + case .enableConnectProtocol: + return "h2_settings_enable_connect_protocol" + default: + return String(describing: self) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandlerStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandlerStateMachine.swift new file mode 100644 index 00000000..5a52c14a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCIdleHandlerStateMachine.swift @@ -0,0 +1,703 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHTTP2 + +/// Holds state for the 'GRPCIdleHandler', this isn't really just the idleness of the connection, +/// it also holds state relevant to quiescing the connection as well as logging some HTTP/2 specific +/// information (like stream creation/close events and changes to settings which can be useful when +/// debugging live systems). Much of this information around the connection state is also used to +/// inform the client connection manager since that's strongly tied to various channel and HTTP/2 +/// events. +struct GRPCIdleHandlerStateMachine { + /// Our role in the connection. + enum Role { + case server + case client + } + + /// The 'operating' state of the connection. This is the primary state we expect to be in: the + /// connection is up and running and there are expected to be active RPCs, although this is by no + /// means a requirement. Some of the situations in which there may be no active RPCs are: + /// + /// 1. Before the connection is 'ready' (that is, seen the first SETTINGS frame), + /// 2. After the connection has dropped to zero active streams and before the idle timeout task + /// has been scheduled. + /// 3. When the connection has zero active streams and the connection was configured without an + /// idle timeout. + fileprivate struct Operating: CanOpenStreams, CanCloseStreams { + /// Our role in the connection. + var role: Role + + /// The number of open stream. + var openStreams: Int + + /// The last stream ID initiated by the remote peer. + var lastPeerInitiatedStreamID: HTTP2StreamID + + /// The maximum number of concurrent streams we are allowed to operate. + var maxConcurrentStreams: Int + + /// We keep track of whether we've seen a SETTINGS frame. We expect to see one after the + /// connection preface (RFC 7540 § 3.5). This is primarily for the benefit of the client which + /// determines a connection to be 'ready' once it has seen the first SETTINGS frame. We also + /// won't set an idle timeout until this becomes true. + var hasSeenSettings: Bool + + fileprivate init(role: Role) { + self.role = role + self.openStreams = 0 + self.lastPeerInitiatedStreamID = .rootStream + // Assumed until we know better. + self.maxConcurrentStreams = 100 + self.hasSeenSettings = false + } + + fileprivate init(fromWaitingToIdle state: WaitingToIdle) { + self.role = state.role + self.openStreams = 0 + self.lastPeerInitiatedStreamID = state.lastPeerInitiatedStreamID + self.maxConcurrentStreams = state.maxConcurrentStreams + // We won't transition to 'WaitingToIdle' unless we've seen a SETTINGS frame. + self.hasSeenSettings = true + } + } + + /// The waiting-to-idle state is used when the connection has become 'ready', has no active + /// RPCs and an idle timeout task has been scheduled. In this state, the connection will be closed + /// once the idle is fired. The task will be cancelled on the creation of a stream. + fileprivate struct WaitingToIdle { + /// Our role in the connection. + var role: Role + + /// The last stream ID initiated by the remote peer. + var lastPeerInitiatedStreamID: HTTP2StreamID + + /// The maximum number of concurrent streams we are allowed to operate. + var maxConcurrentStreams: Int + + /// A task which, when fired, will idle the connection. + var idleTask: Scheduled + + fileprivate init(fromOperating state: Operating, idleTask: Scheduled) { + // We won't transition to this state unless we've seen a SETTINGS frame. + assert(state.hasSeenSettings) + + self.role = state.role + self.lastPeerInitiatedStreamID = state.lastPeerInitiatedStreamID + self.maxConcurrentStreams = state.maxConcurrentStreams + self.idleTask = idleTask + } + } + + /// The quiescing state is entered only from the operating state. It may be entered if we receive + /// a GOAWAY frame (the remote peer initiated the quiescing) or we initiate graceful shutdown + /// locally. + fileprivate struct Quiescing: TracksOpenStreams, CanCloseStreams { + /// Our role in the connection. + var role: Role + + /// The number of open stream. + var openStreams: Int + + /// The last stream ID initiated by the remote peer. + var lastPeerInitiatedStreamID: HTTP2StreamID + + /// The maximum number of concurrent streams we are allowed to operate. + var maxConcurrentStreams: Int + + /// Whether this peer initiated shutting down. + var initiatedByUs: Bool + + fileprivate init(fromOperating state: Operating, initiatedByUs: Bool) { + // If we didn't initiate shutdown, the remote peer must have done so by sending a GOAWAY frame + // in which case we must have seen a SETTINGS frame. + assert(initiatedByUs || state.hasSeenSettings) + self.role = state.role + self.initiatedByUs = initiatedByUs + self.openStreams = state.openStreams + self.lastPeerInitiatedStreamID = state.lastPeerInitiatedStreamID + self.maxConcurrentStreams = state.maxConcurrentStreams + } + } + + /// The closing state is entered when one of the previous states initiates a connection closure. + /// From this state the only possible transition is to the closed state. + fileprivate struct Closing { + /// Our role in the connection. + var role: Role + + /// Should the client connection manager receive an idle event when we close? (If not then it + /// will attempt to establish a new connection immediately.) + var shouldIdle: Bool + + fileprivate init(fromOperating state: Operating) { + self.role = state.role + // Idle if there are no open streams and we've seen the first SETTINGS frame. + self.shouldIdle = !state.hasOpenStreams && state.hasSeenSettings + } + + fileprivate init(fromQuiescing state: Quiescing) { + self.role = state.role + // If we initiated the quiescing then we shouldn't go idle (we want to shutdown instead). + self.shouldIdle = !state.initiatedByUs + } + + fileprivate init(fromWaitingToIdle state: WaitingToIdle, shouldIdle: Bool = true) { + self.role = state.role + self.shouldIdle = shouldIdle + } + } + + fileprivate enum State { + case operating(Operating) + case waitingToIdle(WaitingToIdle) + case quiescing(Quiescing) + case closing(Closing) + case closed + } + + /// The set of operations that should be performed as a result of interaction with the state + /// machine. + struct Operations { + /// An event to notify the connection manager about. + private(set) var connectionManagerEvent: ConnectionManagerEvent? + + /// The value of HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS changed. + private(set) var maxConcurrentStreamsChange: Int? + + /// An idle task, either scheduling or cancelling an idle timeout. + private(set) var idleTask: IdleTask? + + /// Send a GOAWAY frame with the last peer initiated stream ID set to this value. + private(set) var sendGoAwayWithLastPeerInitiatedStreamID: HTTP2StreamID? + + /// Whether the channel should be closed. + private(set) var shouldCloseChannel: Bool + + /// Whether a ping should be sent after a GOAWAY frame. + private(set) var shouldPingAfterGoAway: Bool + + fileprivate static let none = Operations() + + fileprivate mutating func sendGoAwayFrame( + lastPeerInitiatedStreamID streamID: HTTP2StreamID, + followWithPing: Bool = false + ) { + self.sendGoAwayWithLastPeerInitiatedStreamID = streamID + self.shouldPingAfterGoAway = followWithPing + } + + fileprivate mutating func cancelIdleTask(_ task: Scheduled) { + self.idleTask = .cancel(task) + } + + fileprivate mutating func scheduleIdleTask() { + self.idleTask = .schedule + } + + fileprivate mutating func closeChannel() { + self.shouldCloseChannel = true + } + + fileprivate mutating func notifyConnectionManager(about event: ConnectionManagerEvent) { + self.connectionManagerEvent = event + } + + fileprivate mutating func maxConcurrentStreamsChanged(_ newValue: Int) { + self.maxConcurrentStreamsChange = newValue + } + + private init() { + self.connectionManagerEvent = nil + self.idleTask = nil + self.sendGoAwayWithLastPeerInitiatedStreamID = nil + self.shouldCloseChannel = false + self.shouldPingAfterGoAway = false + } + } + + /// An event to notify the 'ConnectionManager' about. + enum ConnectionManagerEvent { + case inactive + case idle + case ready + case quiescing + } + + enum IdleTask { + case schedule + case cancel(Scheduled) + } + + /// The current state. + private var state: State + + /// A logger. + internal var logger: Logger + + /// Create a new state machine. + init(role: Role, logger: Logger) { + self.state = .operating(.init(role: role)) + self.logger = logger + } + + // MARK: Stream Events + + /// An HTTP/2 stream was created. + mutating func streamCreated(withID streamID: HTTP2StreamID) -> Operations { + var operations: Operations = .none + + switch self.state { + case var .operating(state): + // Create the stream. + state.streamCreated(streamID, logger: self.logger) + self.state = .operating(state) + + case let .waitingToIdle(state): + var operating = Operating(fromWaitingToIdle: state) + operating.streamCreated(streamID, logger: self.logger) + self.state = .operating(operating) + operations.cancelIdleTask(state.idleTask) + + case var .quiescing(state): + state.lastPeerInitiatedStreamID = streamID + state.openStreams += 1 + self.state = .quiescing(state) + + case .closing, .closed: + () + } + + return operations + } + + /// An HTTP/2 stream was closed. + mutating func streamClosed(withID streamID: HTTP2StreamID) -> Operations { + var operations: Operations = .none + + switch self.state { + case var .operating(state): + state.streamClosed(streamID, logger: self.logger) + + if state.hasSeenSettings, !state.hasOpenStreams { + operations.scheduleIdleTask() + } + + self.state = .operating(state) + + case .waitingToIdle: + // If we're waiting to idle then there can't be any streams open which can be closed. + preconditionFailure() + + case var .quiescing(state): + state.streamClosed(streamID, logger: self.logger) + + if state.hasOpenStreams { + self.state = .quiescing(state) + } else { + self.state = .closing(.init(fromQuiescing: state)) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + } + + case .closing, .closed: + () + } + + return operations + } + + // MARK: - Idle Events + + /// The given task was scheduled to idle the connection. + mutating func scheduledIdleTimeoutTask(_ task: Scheduled) -> Operations { + var operations: Operations = .none + + switch self.state { + case let .operating(state): + if state.hasOpenStreams { + operations.cancelIdleTask(task) + } else { + self.state = .waitingToIdle(.init(fromOperating: state, idleTask: task)) + } + + case .waitingToIdle: + // There's already an idle task. + preconditionFailure() + + case .quiescing, .closing, .closed: + operations.cancelIdleTask(task) + } + + return operations + } + + /// The idle timeout task fired, the connection should be idled. + mutating func idleTimeoutTaskFired() -> Operations { + var operations: Operations = .none + + switch self.state { + case let .waitingToIdle(state): + self.state = .closing(.init(fromWaitingToIdle: state)) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + + // We're either operating on streams, streams are going away, or the connection is going away + // so we don't need to idle the connection. + case .operating, .quiescing, .closing, .closed: + () + } + + return operations + } + + // MARK: - Shutdown Events + + /// Close the connection, this can be caused as a result of a keepalive timeout (i.e. the server + /// has become unresponsive), we'll bin this connection as a result. + mutating func shutdownNow() -> Operations { + var operations = Operations.none + + switch self.state { + case let .operating(state): + var closing = Closing(fromOperating: state) + closing.shouldIdle = false + self.state = .closing(closing) + operations.closeChannel() + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + + case let .waitingToIdle(state): + // Don't idle. + self.state = .closing(Closing(fromWaitingToIdle: state, shouldIdle: false)) + operations.closeChannel() + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.cancelIdleTask(state.idleTask) + + case let .quiescing(state): + self.state = .closing(Closing(fromQuiescing: state)) + // We've already sent a GOAWAY frame if we're in this state, just close. + operations.closeChannel() + + case .closing, .closed: + () + } + + return operations + } + + /// Initiate a graceful shutdown of this connection, that is, begin quiescing. + mutating func initiateGracefulShutdown() -> Operations { + var operations: Operations = .none + + switch self.state { + case let .operating(state): + if state.hasOpenStreams { + // There are open streams: send a GOAWAY frame and wait for the stream count to reach zero. + // + // It's okay if we haven't seen a SETTINGS frame at this point; we've initiated the shutdown + // so making a connection is ready isn't necessary. + operations.notifyConnectionManager(about: .quiescing) + + // TODO: we should ratchet down the last initiated stream after 1-RTT. + // + // As a client we will just stop initiating streams. + if state.role == .server { + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + } + + self.state = .quiescing(.init(fromOperating: state, initiatedByUs: true)) + } else { + // No open streams: send a GOAWAY frame and close the channel. + self.state = .closing(.init(fromOperating: state)) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + } + + case let .waitingToIdle(state): + // There can't be any open streams, but we have a few loose ends to clear up: we need to + // cancel the idle timeout, send a GOAWAY frame and then close. We don't want to idle from the + // closing state: we want to shutdown instead. + self.state = .closing(.init(fromWaitingToIdle: state, shouldIdle: false)) + operations.cancelIdleTask(state.idleTask) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + + case var .quiescing(state): + // We're already quiescing: either the remote initiated it or we're initiating it more than + // once. Set ourselves as the initiator to ensure we don't idle when we eventually close, this + // is important for the client: if the server initiated this then we establish a new + // connection when we close, unless we also initiated shutdown. + state.initiatedByUs = true + self.state = .quiescing(state) + + case var .closing(state): + // We've already called 'close()', make sure we don't go idle. + state.shouldIdle = false + self.state = .closing(state) + + case .closed: + () + } + + return operations + } + + /// We've received a GOAWAY frame from the remote peer. Either the remote peer wants to close the + /// connection or they're responding to us shutting down the connection. + mutating func receiveGoAway() -> Operations { + var operations: Operations = .none + + switch self.state { + case let .operating(state): + // A SETTINGS frame MUST follow the connection preface. (RFC 7540 § 3.5) + assert(state.hasSeenSettings) + + if state.hasOpenStreams { + operations.notifyConnectionManager(about: .quiescing) + switch state.role { + case .client: + // The server sent us a GOAWAY we'll just stop opening new streams and will send a GOAWAY + // frame before we close later. + () + case .server: + // Client sent us a GOAWAY frame; we'll let the streams drain and then close. We'll tell + // the client that we're going away and send them a ping. When we receive the pong we will + // send another GOAWAY frame with a lower stream ID. In this case, the pong acts as an ack + // for the GOAWAY. + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: .maxID, followWithPing: true) + } + self.state = .quiescing(.init(fromOperating: state, initiatedByUs: false)) + } else { + // No open streams, we can close as well. + self.state = .closing(.init(fromOperating: state)) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + } + + case let .waitingToIdle(state): + // There can't be any open streams, but we have a few loose ends to clear up: we need to + // cancel the idle timeout, send a GOAWAY frame and then close. + self.state = .closing(.init(fromWaitingToIdle: state)) + operations.cancelIdleTask(state.idleTask) + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: state.lastPeerInitiatedStreamID) + operations.closeChannel() + + case .quiescing: + // We're already quiescing, this changes nothing. + () + + case .closing, .closed: + // We're already closing/closed (so must have emitted a GOAWAY frame already). Ignore this. + () + } + + return operations + } + + mutating func ratchetDownGoAwayStreamID() -> Operations { + var operations: Operations = .none + + switch self.state { + case let .quiescing(state): + let streamID = state.lastPeerInitiatedStreamID + operations.sendGoAwayFrame(lastPeerInitiatedStreamID: streamID) + case .operating, .waitingToIdle, .closing, .closed: + // We can only need to ratchet down the stream ID if we're already quiescing. + () + } + + return operations + } + + mutating func receiveSettings(_ settings: HTTP2Settings) -> Operations { + // Log the change in settings. + self.logger.debug( + "HTTP2 settings update", + metadata: Dictionary(settings.map { + ("\($0.parameter.loggingMetadataKey)", "\($0.value)") + }, uniquingKeysWith: { a, _ in a }) + ) + + var operations: Operations = .none + + switch self.state { + case var .operating(state): + let hasSeenSettingsPreviously = state.hasSeenSettings + + // If we hadn't previously seen settings then we need to notify the client connection manager + // that we're now ready. + if !hasSeenSettingsPreviously { + operations.notifyConnectionManager(about: .ready) + state.hasSeenSettings = true + + // Now that we know the connection is ready, we may want to start an idle timeout as well. + if !state.hasOpenStreams { + operations.scheduleIdleTask() + } + } + + // Update max concurrent streams. + if let maxStreams = settings.last(where: { $0.parameter == .maxConcurrentStreams })?.value { + operations.maxConcurrentStreamsChanged(maxStreams) + state.maxConcurrentStreams = maxStreams + } else if !hasSeenSettingsPreviously { + // We hadn't seen settings before now and max concurrent streams wasn't set we should assume + // the default and emit an update. + operations.maxConcurrentStreamsChanged(100) + state.maxConcurrentStreams = 100 + } + + self.state = .operating(state) + + case var .waitingToIdle(state): + // Update max concurrent streams. + if let maxStreams = settings.last(where: { $0.parameter == .maxConcurrentStreams })?.value { + operations.maxConcurrentStreamsChanged(maxStreams) + state.maxConcurrentStreams = maxStreams + } + self.state = .waitingToIdle(state) + + case .quiescing, .closing, .closed: + () + } + + return operations + } + + // MARK: - Channel Events + + // (Other channel events aren't included here as they don't impact the state machine.) + + /// 'channelActive' was called in the idle handler holding this state machine. + mutating func channelInactive() -> Operations { + var operations: Operations = .none + + switch self.state { + case let .operating(state): + self.state = .closed + + // We unexpectedly became inactive. + if !state.hasSeenSettings || state.hasOpenStreams { + // Haven't seen settings, or we've seen settings and there are open streams. + operations.notifyConnectionManager(about: .inactive) + } else { + // Have seen settings and there are no open streams. + operations.notifyConnectionManager(about: .idle) + } + + case let .waitingToIdle(state): + self.state = .closed + + // We were going to idle anyway. + operations.notifyConnectionManager(about: .idle) + operations.cancelIdleTask(state.idleTask) + + case let .quiescing(state): + self.state = .closed + + if state.initiatedByUs || state.hasOpenStreams { + operations.notifyConnectionManager(about: .inactive) + } else { + operations.notifyConnectionManager(about: .idle) + } + + case let .closing(state): + self.state = .closed + + if state.shouldIdle { + operations.notifyConnectionManager(about: .idle) + } else { + operations.notifyConnectionManager(about: .inactive) + } + + case .closed: + () + } + + return operations + } +} + +// MARK: - Helper Protocols + +private protocol TracksOpenStreams { + /// The number of open streams. + var openStreams: Int { get set } +} + +extension TracksOpenStreams { + /// Whether any streams are open. + fileprivate var hasOpenStreams: Bool { + return self.openStreams != 0 + } +} + +private protocol CanOpenStreams: TracksOpenStreams { + /// The role of this peer in the connection. + var role: GRPCIdleHandlerStateMachine.Role { get } + + /// The ID of the stream most recently initiated by the remote peer. + var lastPeerInitiatedStreamID: HTTP2StreamID { get set } + + /// The maximum number of concurrent streams. + var maxConcurrentStreams: Int { get set } + + mutating func streamCreated(_ streamID: HTTP2StreamID, logger: Logger) +} + +extension CanOpenStreams { + fileprivate mutating func streamCreated(_ streamID: HTTP2StreamID, logger: Logger) { + self.openStreams += 1 + + switch self.role { + case .client where streamID.isServerInitiated: + self.lastPeerInitiatedStreamID = streamID + case .server where streamID.isClientInitiated: + self.lastPeerInitiatedStreamID = streamID + default: + () + } + + logger.debug("HTTP2 stream created", metadata: [ + MetadataKey.h2StreamID: "\(streamID)", + MetadataKey.h2ActiveStreams: "\(self.openStreams)", + ]) + + if self.openStreams == self.maxConcurrentStreams { + logger.warning("HTTP2 max concurrent stream limit reached", metadata: [ + MetadataKey.h2ActiveStreams: "\(self.openStreams)", + ]) + } + } +} + +private protocol CanCloseStreams: TracksOpenStreams { + /// Notes that a stream has closed. + mutating func streamClosed(_ streamID: HTTP2StreamID, logger: Logger) +} + +extension CanCloseStreams { + fileprivate mutating func streamClosed(_ streamID: HTTP2StreamID, logger: Logger) { + self.openStreams -= 1 + + logger.debug("HTTP2 stream closed", metadata: [ + MetadataKey.h2StreamID: "\(streamID)", + MetadataKey.h2ActiveStreams: "\(self.openStreams)", + ]) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCKeepaliveHandlers.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCKeepaliveHandlers.swift new file mode 100644 index 00000000..d22d182a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCKeepaliveHandlers.swift @@ -0,0 +1,255 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHTTP2 + +struct PingHandler { + /// Opaque ping data used for keep-alive pings. + private let pingData: HTTP2PingData + + /// Opaque ping data used for a ping sent after a GOAWAY frame. + internal let pingDataGoAway: HTTP2PingData + + /// The amount of time to wait before sending a keepalive ping. + private let interval: TimeAmount + + /// The amount of time to wait for an acknowledgment. + /// If it does not receive an acknowledgment within this time, it will close the connection + private let timeout: TimeAmount + + /// Send keepalive pings even if there are no calls in flight. + private let permitWithoutCalls: Bool + + /// Maximum number of pings that can be sent when there is no data/header frame to be sent. + private let maximumPingsWithoutData: UInt + + /// If there are no data/header frames being received: + /// The minimum amount of time to wait between successive pings. + private let minimumSentPingIntervalWithoutData: TimeAmount + + /// If there are no data/header frames being sent: + /// The minimum amount of time expected between receiving successive pings. + /// If the time between successive pings is less than this value, then the ping will be considered a bad ping from the peer. + /// Such a ping counts as a "ping strike". + /// Ping strikes are only applicable to server handler + private let minimumReceivedPingIntervalWithoutData: TimeAmount? + + /// Maximum number of bad pings that the server will tolerate before sending an HTTP2 GOAWAY frame and closing the connection. + /// Setting it to `0` allows the server to accept any number of bad pings. + /// Ping strikes are only applicable to server handler + private let maximumPingStrikes: UInt? + + /// When the handler started pinging + private var startedAt: NIODeadline? + + /// When the last ping was received + private var lastReceivedPingDate: NIODeadline? + + /// When the last ping was sent + private var lastSentPingDate: NIODeadline? + + /// The number of pings sent on the transport without any data + private var sentPingsWithoutData = 0 + + /// Number of strikes + private var pingStrikes: UInt = 0 + + /// The scheduled task which will close the connection. + private var scheduledClose: Scheduled? + + /// Number of active streams + private var activeStreams = 0 { + didSet { + if self.activeStreams > 0 { + self.sentPingsWithoutData = 0 + } + } + } + + private static let goAwayFrame = HTTP2Frame.FramePayload.goAway( + lastStreamID: .rootStream, + errorCode: .enhanceYourCalm, + opaqueData: nil + ) + + // For testing only + var _testingOnlyNow: NIODeadline? + + enum Action { + case none + case schedulePing(delay: TimeAmount, timeout: TimeAmount) + case cancelScheduledTimeout + case reply(HTTP2Frame.FramePayload) + case ratchetDownLastSeenStreamID + } + + init( + pingCode: UInt64, + interval: TimeAmount, + timeout: TimeAmount, + permitWithoutCalls: Bool, + maximumPingsWithoutData: UInt, + minimumSentPingIntervalWithoutData: TimeAmount, + minimumReceivedPingIntervalWithoutData: TimeAmount? = nil, + maximumPingStrikes: UInt? = nil + ) { + self.pingData = HTTP2PingData(withInteger: pingCode) + self.pingDataGoAway = HTTP2PingData(withInteger: ~pingCode) + self.interval = interval + self.timeout = timeout + self.permitWithoutCalls = permitWithoutCalls + self.maximumPingsWithoutData = maximumPingsWithoutData + self.minimumSentPingIntervalWithoutData = minimumSentPingIntervalWithoutData + self.minimumReceivedPingIntervalWithoutData = minimumReceivedPingIntervalWithoutData + self.maximumPingStrikes = maximumPingStrikes + } + + mutating func streamCreated() -> Action { + self.activeStreams += 1 + + if self.startedAt == nil { + self.startedAt = self.now() + return .schedulePing(delay: self.interval, timeout: self.timeout) + } else { + return .none + } + } + + mutating func streamClosed() -> Action { + self.activeStreams -= 1 + return .none + } + + mutating func read(pingData: HTTP2PingData, ack: Bool) -> Action { + if ack { + return self.handlePong(pingData) + } else { + return self.handlePing(pingData) + } + } + + private func handlePong(_ pingData: HTTP2PingData) -> Action { + if pingData == self.pingData { + return .cancelScheduledTimeout + } else if pingData == self.pingDataGoAway { + // We received a pong for a ping we sent to trail a GOAWAY frame: this means we can now + // send another GOAWAY frame with a (possibly) lower stream ID. + return .ratchetDownLastSeenStreamID + } else { + return .none + } + } + + private mutating func handlePing(_ pingData: HTTP2PingData) -> Action { + // Do we support ping strikes (only servers support ping strikes)? + if let maximumPingStrikes = self.maximumPingStrikes { + // Is this a ping strike? + if self.isPingStrike { + self.pingStrikes += 1 + + // A maximum ping strike of zero indicates that we tolerate any number of strikes. + if maximumPingStrikes != 0, self.pingStrikes > maximumPingStrikes { + return .reply(PingHandler.goAwayFrame) + } else { + return .none + } + } else { + // This is a valid ping, reset our strike count and reply with a pong. + self.pingStrikes = 0 + self.lastReceivedPingDate = self.now() + return .reply(self.generatePingFrame(data: pingData, ack: true)) + } + } else { + // We don't support ping strikes. We'll just reply with a pong. + // + // Note: we don't need to update `pingStrikes` or `lastReceivedPingDate` as we don't + // support ping strikes. + return .reply(self.generatePingFrame(data: pingData, ack: true)) + } + } + + mutating func pingFired() -> Action { + if self.shouldBlockPing { + return .none + } else { + return .reply(self.generatePingFrame(data: self.pingData, ack: false)) + } + } + + private mutating func generatePingFrame( + data: HTTP2PingData, + ack: Bool + ) -> HTTP2Frame.FramePayload { + if self.activeStreams == 0 { + self.sentPingsWithoutData += 1 + } + + self.lastSentPingDate = self.now() + return HTTP2Frame.FramePayload.ping(data, ack: ack) + } + + /// Returns true if, on receipt of a ping, the ping should be regarded as a ping strike. + /// + /// A ping is considered a 'strike' if: + /// - There are no active streams. + /// - We allow pings to be sent when there are no active streams (i.e. `self.permitWithoutCalls`). + /// - The time since the last ping we received is less than the minimum allowed interval. + /// + /// - Precondition: Ping strikes are supported (i.e. `self.maximumPingStrikes != nil`) + private var isPingStrike: Bool { + assert( + self.maximumPingStrikes != nil, + "Ping strikes are not supported but we're checking for one" + ) + guard self.activeStreams == 0, self.permitWithoutCalls, + let lastReceivedPingDate = self.lastReceivedPingDate, + let minimumReceivedPingIntervalWithoutData = self.minimumReceivedPingIntervalWithoutData + else { + return false + } + + return self.now() - lastReceivedPingDate < minimumReceivedPingIntervalWithoutData + } + + private var shouldBlockPing: Bool { + // There is no active call on the transport and pings should not be sent + guard self.activeStreams > 0 || self.permitWithoutCalls else { + return true + } + + // There is no active call on the transport but pings should be sent + if self.activeStreams == 0, self.permitWithoutCalls { + // The number of pings already sent on the transport without any data has already exceeded the limit + if self.sentPingsWithoutData > self.maximumPingsWithoutData { + return true + } + + // The time elapsed since the previous ping is less than the minimum required + if let lastSentPingDate = self.lastSentPingDate, + self.now() - lastSentPingDate < self.minimumSentPingIntervalWithoutData { + return true + } + + return false + } + + return false + } + + private func now() -> NIODeadline { + return self._testingOnlyNow ?? .now() + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCLogger.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCLogger.swift new file mode 100644 index 00000000..7d46109a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCLogger.swift @@ -0,0 +1,129 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +/// Wraps `Logger` to always provide the source as "GRPC". +/// +/// See https://github.com/apple/swift-log/issues/145 for rationale. +@usableFromInline +internal struct GRPCLogger { + @usableFromInline + internal var logger: Logger + + internal var unwrapped: Logger { + return self.logger + } + + @inlinable + internal init(wrapping logger: Logger) { + self.logger = logger + } + + internal subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? { + get { + return self.logger[metadataKey: metadataKey] + } + set { + self.logger[metadataKey: metadataKey] = newValue + } + } + + @usableFromInline + internal func trace( + _ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + file: String = #file, + function: String = #function, + line: UInt = #line + ) { + self.logger.trace( + message(), + metadata: metadata(), + source: "GRPC", + file: file, + function: function, + line: line + ) + } + + @usableFromInline + internal func debug( + _ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + file: String = #file, + function: String = #function, + line: UInt = #line + ) { + self.logger.debug( + message(), + metadata: metadata(), + source: "GRPC", + file: file, + function: function, + line: line + ) + } + + @usableFromInline + internal func notice( + _ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + file: String = #file, + function: String = #function, + line: UInt = #line + ) { + self.logger.notice( + message(), + metadata: metadata(), + source: "GRPC", + file: file, + function: function, + line: line + ) + } + + @usableFromInline + internal func warning( + _ message: @autoclosure () -> Logger.Message, + metadata: @autoclosure () -> Logger.Metadata? = nil, + file: String = #file, + function: String = #function, + line: UInt = #line + ) { + self.logger.warning( + message(), + metadata: metadata(), + source: "GRPC", + file: file, + function: function, + line: line + ) + } +} + +extension GRPCLogger { + internal mutating func addIPAddressMetadata(local: SocketAddress?, remote: SocketAddress?) { + self.logger.addIPAddressMetadata(local: local, remote: remote) + } +} + +extension Logger { + @inlinable + internal var wrapped: GRPCLogger { + return GRPCLogger(wrapping: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCPayload.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCPayload.swift new file mode 100644 index 00000000..c356e16f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCPayload.swift @@ -0,0 +1,33 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +/// A data type which may be serialized into and out from a `ByteBuffer` in order to be sent between +/// gRPC peers. +public protocol GRPCPayload { + /// Initializes a new payload by deserializing the bytes from the given `ByteBuffer`. + /// + /// - Parameter serializedByteBuffer: A buffer containing the serialized bytes of this payload. + /// - Throws: If the payload could not be deserialized from the buffer. + init(serializedByteBuffer: inout ByteBuffer) throws + + /// Serializes the payload into the given `ByteBuffer`. + /// + /// - Parameter buffer: The buffer to write the serialized payload into. + /// - Throws: If the payload could not be serialized. + /// - Important: Implementers must *NOT* clear or read bytes from `buffer`. + func serialize(into buffer: inout ByteBuffer) throws +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerPipelineConfigurator.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerPipelineConfigurator.swift new file mode 100644 index 00000000..47c231d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerPipelineConfigurator.swift @@ -0,0 +1,425 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 +import NIOTLS + +/// Configures a server pipeline for gRPC with the appropriate handlers depending on the HTTP +/// version used for transport. +/// +/// If TLS is enabled then the handler listens for an 'TLSUserEvent.handshakeCompleted' event and +/// configures the pipeline appropriately for the protocol negotiated via ALPN. If TLS is not +/// configured then the HTTP version is determined by parsing the inbound byte stream. +final class GRPCServerPipelineConfigurator: ChannelInboundHandler, RemovableChannelHandler { + internal typealias InboundIn = ByteBuffer + internal typealias InboundOut = ByteBuffer + + /// The server configuration. + private let configuration: Server.Configuration + + /// Reads which we're holding on to before the pipeline is configured. + private var bufferedReads = CircularBuffer() + + /// The current state. + private var state: State + + private enum ALPN { + /// ALPN is expected. It may or may not be required, however. + case expected(required: Bool) + + /// ALPN was expected but not required and no protocol was negotiated in the handshake. We may + /// now fall back to parsing bytes on the connection. + case expectedButFallingBack + + /// ALPN is not expected; this is a cleartext connection. + case notExpected + } + + private enum State { + /// The pipeline isn't configured yet. + case notConfigured(alpn: ALPN) + /// We're configuring the pipeline. + case configuring + } + + init(configuration: Server.Configuration) { + if let tls = configuration.tlsConfiguration { + self.state = .notConfigured(alpn: .expected(required: tls.requireALPN)) + } else { + self.state = .notConfigured(alpn: .notExpected) + } + + self.configuration = configuration + } + + /// Makes a gRPC idle handler for the server.. + private func makeIdleHandler() -> GRPCIdleHandler { + return .init( + idleTimeout: self.configuration.connectionIdleTimeout, + keepalive: self.configuration.connectionKeepalive, + logger: self.configuration.logger + ) + } + + /// Makes an HTTP/2 handler. + private func makeHTTP2Handler() -> NIOHTTP2Handler { + return .init( + mode: .server, + initialSettings: [ + HTTP2Setting( + parameter: .maxConcurrentStreams, + value: self.configuration.httpMaxConcurrentStreams + ), + HTTP2Setting( + parameter: .maxHeaderListSize, + value: HPACKDecoder.defaultMaxHeaderListSize + ), + HTTP2Setting( + parameter: .maxFrameSize, + value: self.configuration.httpMaxFrameSize + ), + HTTP2Setting( + parameter: .initialWindowSize, + value: self.configuration.httpTargetWindowSize + ), + ] + ) + } + + /// Makes an HTTP/2 multiplexer suitable handling gRPC requests. + private func makeHTTP2Multiplexer(for channel: Channel) -> HTTP2StreamMultiplexer { + var logger = self.configuration.logger + + return .init( + mode: .server, + channel: channel, + targetWindowSize: self.configuration.httpTargetWindowSize + ) { stream in + // Sync options were added to the HTTP/2 stream channel in 1.17.0 (we require at least this) + // so this shouldn't be `nil`, but it's not a problem if it is. + let http2StreamID = try? stream.syncOptions?.getOption(HTTP2StreamChannelOptions.streamID) + let streamID = http2StreamID.map { streamID in + return String(Int(streamID)) + } ?? "" + + logger[metadataKey: MetadataKey.h2StreamID] = "\(streamID)" + + do { + // TODO: provide user configuration for header normalization. + let handler = self.makeHTTP2ToRawGRPCHandler(normalizeHeaders: true, logger: logger) + try stream.pipeline.syncOperations.addHandler(handler) + return stream.eventLoop.makeSucceededVoidFuture() + } catch { + return stream.eventLoop.makeFailedFuture(error) + } + } + } + + /// Makes an HTTP/2 to raw gRPC server handler. + private func makeHTTP2ToRawGRPCHandler( + normalizeHeaders: Bool, + logger: Logger + ) -> HTTP2ToRawGRPCServerCodec { + return HTTP2ToRawGRPCServerCodec( + servicesByName: self.configuration.serviceProvidersByName, + encoding: self.configuration.messageEncoding, + errorDelegate: self.configuration.errorDelegate, + normalizeHeaders: normalizeHeaders, + maximumReceiveMessageLength: self.configuration.maximumReceiveMessageLength, + logger: logger + ) + } + + /// The pipeline finished configuring. + private func configurationCompleted(result: Result, context: ChannelHandlerContext) { + switch result { + case .success: + context.pipeline.removeHandler(context: context, promise: nil) + case let .failure(error): + self.errorCaught(context: context, error: error) + } + } + + /// Configures the pipeline to handle gRPC requests on an HTTP/2 connection. + private func configureHTTP2(context: ChannelHandlerContext) { + // We're now configuring the pipeline. + self.state = .configuring + + // We could use 'Channel.configureHTTP2Pipeline', but then we'd have to find the right handlers + // to then insert our keepalive and idle handlers between. We can just add everything together. + let result: Result + + do { + // This is only ever called as a result of reading a user inbound event or reading inbound so + // we'll be on the right event loop and sync operations are fine. + let sync = context.pipeline.syncOperations + try sync.addHandler(self.makeHTTP2Handler()) + try sync.addHandler(self.makeIdleHandler()) + try sync.addHandler(self.makeHTTP2Multiplexer(for: context.channel)) + result = .success(()) + } catch { + result = .failure(error) + } + + self.configurationCompleted(result: result, context: context) + } + + /// Configures the pipeline to handle gRPC-Web requests on an HTTP/1 connection. + private func configureHTTP1(context: ChannelHandlerContext) { + // We're now configuring the pipeline. + self.state = .configuring + + let result: Result + do { + // This is only ever called as a result of reading a user inbound event or reading inbound so + // we'll be on the right event loop and sync operations are fine. + let sync = context.pipeline.syncOperations + try sync.configureHTTPServerPipeline(withErrorHandling: true) + try sync.addHandler(WebCORSHandler()) + let scheme = self.configuration.tlsConfiguration == nil ? "http" : "https" + try sync.addHandler(GRPCWebToHTTP2ServerCodec(scheme: scheme)) + // There's no need to normalize headers for HTTP/1. + try sync.addHandler( + self.makeHTTP2ToRawGRPCHandler(normalizeHeaders: false, logger: self.configuration.logger) + ) + result = .success(()) + } catch { + result = .failure(error) + } + + self.configurationCompleted(result: result, context: context) + } + + /// Attempts to determine the HTTP version from the buffer and then configure the pipeline + /// appropriately. Closes the connection if the HTTP version could not be determined. + private func determineHTTPVersionAndConfigurePipeline( + buffer: ByteBuffer, + context: ChannelHandlerContext + ) { + if HTTPVersionParser.prefixedWithHTTP2ConnectionPreface(buffer) { + self.configureHTTP2(context: context) + } else if HTTPVersionParser.prefixedWithHTTP1RequestLine(buffer) { + self.configureHTTP1(context: context) + } else { + self.configuration.logger.error("Unable to determine http version, closing") + context.close(mode: .all, promise: nil) + } + } + + /// Handles a 'TLSUserEvent.handshakeCompleted' event and configures the pipeline to handle gRPC + /// requests. + private func handleHandshakeCompletedEvent( + _ event: TLSUserEvent, + alpnIsRequired: Bool, + context: ChannelHandlerContext + ) { + switch event { + case let .handshakeCompleted(negotiatedProtocol): + self.configuration.logger.debug("TLS handshake completed", metadata: [ + "alpn": "\(negotiatedProtocol ?? "nil")", + ]) + + switch negotiatedProtocol { + case let .some(negotiated): + if GRPCApplicationProtocolIdentifier.isHTTP2Like(negotiated) { + self.configureHTTP2(context: context) + } else if GRPCApplicationProtocolIdentifier.isHTTP1(negotiated) { + self.configureHTTP1(context: context) + } else { + self.configuration.logger.warning("Unsupported ALPN identifier '\(negotiated)', closing") + context.close(mode: .all, promise: nil) + } + + case .none: + if alpnIsRequired { + self.configuration.logger.warning("No ALPN protocol negotiated, closing'") + context.close(mode: .all, promise: nil) + } else { + self.configuration.logger.warning("No ALPN protocol negotiated'") + // We're now falling back to parsing bytes. + self.state = .notConfigured(alpn: .expectedButFallingBack) + self.tryParsingBufferedData(context: context) + } + } + + case .shutdownCompleted: + // We don't care about this here. + () + } + } + + /// Try to parse the buffered data to determine whether or not HTTP/2 or HTTP/1 should be used. + private func tryParsingBufferedData(context: ChannelHandlerContext) { + guard let first = self.bufferedReads.first else { + // No data buffered yet. We'll try when we read. + return + } + + let buffer = self.unwrapInboundIn(first) + self.determineHTTPVersionAndConfigurePipeline(buffer: buffer, context: context) + } + + // MARK: - Channel Handler + + internal func errorCaught(context: ChannelHandlerContext, error: Error) { + if let delegate = self.configuration.errorDelegate { + let baseError: Error + + if let errorWithContext = error as? GRPCError.WithContext { + baseError = errorWithContext.error + } else { + baseError = error + } + + delegate.observeLibraryError(baseError) + } + + context.close(mode: .all, promise: nil) + } + + internal func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + switch self.state { + case let .notConfigured(alpn: .expected(required)): + if let event = event as? TLSUserEvent { + self.handleHandshakeCompletedEvent(event, alpnIsRequired: required, context: context) + } + + case .notConfigured(alpn: .expectedButFallingBack), + .notConfigured(alpn: .notExpected), + .configuring: + () + } + + context.fireUserInboundEventTriggered(event) + } + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + self.bufferedReads.append(data) + + switch self.state { + case .notConfigured(alpn: .notExpected), + .notConfigured(alpn: .expectedButFallingBack): + // If ALPN isn't expected, or we didn't negotiate via ALPN and we don't require it then we + // can try parsing the data we just buffered. + self.tryParsingBufferedData(context: context) + + case .notConfigured(alpn: .expected), + .configuring: + // We expect ALPN or we're being configured, just buffer the data, we'll forward it later. + () + } + + // Don't forward the reads: we'll do so when we have configured the pipeline. + } + + internal func removeHandler( + context: ChannelHandlerContext, + removalToken: ChannelHandlerContext.RemovalToken + ) { + // Forward any buffered reads. + while let read = self.bufferedReads.popFirst() { + context.fireChannelRead(read) + } + context.leavePipeline(removalToken: removalToken) + } +} + +// MARK: - HTTP Version Parser + +struct HTTPVersionParser { + /// HTTP/2 connection preface bytes. See RFC 7540 § 5.3. + private static let http2ClientMagic = [ + UInt8(ascii: "P"), + UInt8(ascii: "R"), + UInt8(ascii: "I"), + UInt8(ascii: " "), + UInt8(ascii: "*"), + UInt8(ascii: " "), + UInt8(ascii: "H"), + UInt8(ascii: "T"), + UInt8(ascii: "T"), + UInt8(ascii: "P"), + UInt8(ascii: "/"), + UInt8(ascii: "2"), + UInt8(ascii: "."), + UInt8(ascii: "0"), + UInt8(ascii: "\r"), + UInt8(ascii: "\n"), + UInt8(ascii: "\r"), + UInt8(ascii: "\n"), + UInt8(ascii: "S"), + UInt8(ascii: "M"), + UInt8(ascii: "\r"), + UInt8(ascii: "\n"), + UInt8(ascii: "\r"), + UInt8(ascii: "\n"), + ] + + /// Determines whether the bytes in the `ByteBuffer` are prefixed with the HTTP/2 client + /// connection preface. + static func prefixedWithHTTP2ConnectionPreface(_ buffer: ByteBuffer) -> Bool { + let view = buffer.readableBytesView + + guard view.count >= HTTPVersionParser.http2ClientMagic.count else { + // Not enough bytes. + return false + } + + let slice = view[view.startIndex ..< view.startIndex.advanced(by: self.http2ClientMagic.count)] + return slice.elementsEqual(HTTPVersionParser.http2ClientMagic) + } + + private static let http1_1 = [ + UInt8(ascii: "H"), + UInt8(ascii: "T"), + UInt8(ascii: "T"), + UInt8(ascii: "P"), + UInt8(ascii: "/"), + UInt8(ascii: "1"), + UInt8(ascii: "."), + UInt8(ascii: "1"), + ] + + /// Determines whether the bytes in the `ByteBuffer` are prefixed with an HTTP/1.1 request line. + static func prefixedWithHTTP1RequestLine(_ buffer: ByteBuffer) -> Bool { + var readableBytesView = buffer.readableBytesView + + // From RFC 2616 § 5.1: + // Request-Line = Method SP Request-URI SP HTTP-Version CRLF + + // Read off the Method and Request-URI (and spaces). + guard readableBytesView.trimPrefix(to: UInt8(ascii: " ")) != nil, + readableBytesView.trimPrefix(to: UInt8(ascii: " ")) != nil else { + return false + } + + // Read off the HTTP-Version and CR. + guard let versionView = readableBytesView.trimPrefix(to: UInt8(ascii: "\r")) else { + return false + } + + // Check that the LF followed the CR. + guard readableBytesView.first == UInt8(ascii: "\n") else { + return false + } + + // Now check the HTTP version. + return versionView.elementsEqual(HTTPVersionParser.http1_1) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerRequestRoutingHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerRequestRoutingHandler.swift new file mode 100644 index 00000000..b3e65ad3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCServerRequestRoutingHandler.swift @@ -0,0 +1,117 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 +import SwiftProtobuf + +/// Provides `GRPCServerHandlerProtocol` objects for the methods on a particular service name. +/// +/// Implemented by the generated code. +public protocol CallHandlerProvider: AnyObject { + /// The name of the service this object is providing methods for, including the package path. + /// + /// - Example: "io.grpc.Echo.EchoService" + var serviceName: Substring { get } + + /// Returns a call handler for the method with the given name, if this service provider implements + /// the given method. Returns `nil` if the method is not handled by this provider. + /// - Parameters: + /// - name: The name of the method to handle. + /// - context: An opaque context providing components to construct the handler with. + func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? +} + +// This is public because it will be passed into generated code, all members are `internal` because +// the context will get passed from generated code back into gRPC library code and all members should +// be considered an implementation detail to the user. +public struct CallHandlerContext { + @usableFromInline + internal var errorDelegate: ServerErrorDelegate? + @usableFromInline + internal var logger: Logger + @usableFromInline + internal var encoding: ServerMessageEncoding + @usableFromInline + internal var eventLoop: EventLoop + @usableFromInline + internal var path: String + @usableFromInline + internal var remoteAddress: SocketAddress? + @usableFromInline + internal var responseWriter: GRPCServerResponseWriter + @usableFromInline + internal var allocator: ByteBufferAllocator + @usableFromInline + internal var closeFuture: EventLoopFuture +} + +/// A call URI split into components. +struct CallPath { + /// The name of the service to call. + var service: String.UTF8View.SubSequence + /// The name of the method to call. + var method: String.UTF8View.SubSequence + + /// Character used to split the path into components. + private let pathSplitDelimiter = UInt8(ascii: "/") + + /// Split a path into service and method. + /// Split is done in UTF8 as this turns out to be approximately 10x faster than a simple split. + /// URI format: "/package.Servicename/MethodName" + init?(requestURI: String) { + var utf8View = requestURI.utf8[...] + // Check and remove the split character at the beginning. + guard let prefix = utf8View.trimPrefix(to: self.pathSplitDelimiter), prefix.isEmpty else { + return nil + } + guard let service = utf8View.trimPrefix(to: pathSplitDelimiter) else { + return nil + } + guard let method = utf8View.trimPrefix(to: pathSplitDelimiter) else { + return nil + } + + self.service = service + self.method = method + } +} + +extension Collection where Self == Self.SubSequence, Self.Element: Equatable { + /// Trims out the prefix up to `separator`, and returns it. + /// Sets self to the subsequence after the separator, and returns the subsequence before the separator. + /// If self is empty returns `nil` + /// - parameters: + /// - separator : The Element between the head which is returned and the rest which is left in self. + /// - returns: SubSequence containing everything between the beginning and the first occurrence of + /// `separator`. If `separator` is not found this will be the entire Collection. If the collection is empty + /// returns `nil` + mutating func trimPrefix(to separator: Element) -> SubSequence? { + guard !self.isEmpty else { + return nil + } + if let separatorIndex = self.firstIndex(of: separator) { + let indexAfterSeparator = self.index(after: separatorIndex) + defer { self = self[indexAfterSeparator...] } + return self[.. + fileprivate var cause: Optional + + fileprivate static func makeStorage(message: String?, cause: Error?) -> Storage { + if message == nil, cause == nil { + return Storage.none + } else { + return Storage(message: message, cause: cause) + } + } + } + + /// Whether the status is '.ok'. + public var isOk: Bool { + return self.code == .ok + } + + public init(code: Code, message: String?) { + self.init(code: code, message: message, cause: nil) + } + + public init(code: Code, message: String? = nil, cause: Error? = nil) { + self.code = code + self.storage = .makeStorage(message: message, cause: cause) + } + + // Frequently used "default" statuses. + + /// The default status to return for succeeded calls. + /// + /// - Important: This should *not* be used when checking whether a returned status has an 'ok' + /// status code. Use `GRPCStatus.isOk` or check the code directly. + public static let ok = GRPCStatus(code: .ok, message: nil) + /// "Internal server error" status. + public static let processingError = Self.processingError(cause: nil) + + public static func processingError(cause: Error?) -> GRPCStatus { + return GRPCStatus( + code: .internalError, + message: "unknown error processing request", + cause: cause + ) + } +} + +extension GRPCStatus: Equatable { + public static func == (lhs: GRPCStatus, rhs: GRPCStatus) -> Bool { + return lhs.code == rhs.code && lhs.message == rhs.message + } +} + +extension GRPCStatus: CustomStringConvertible { + public var description: String { + switch (self.message, self.cause) { + case let (.some(message), .some(cause)): + return "\(self.code): \(message), cause: \(cause)" + case let (.some(message), .none): + return "\(self.code): \(message)" + case let (.none, .some(cause)): + return "\(self.code), cause: \(cause)" + case (.none, .none): + return "\(self.code)" + } + } +} + +extension GRPCStatus { + internal var testingOnly_storageObjectIdentifier: ObjectIdentifier { + return ObjectIdentifier(self.storage) + } +} + +extension GRPCStatus { + /// Status codes for gRPC operations (replicated from `status_code_enum.h` in the + /// [gRPC core library](https://github.com/grpc/grpc)). + public struct Code: Hashable, CustomStringConvertible, GRPCSendable { + // `rawValue` must be an `Int` for API reasons and we don't need (or want) to store anything so + // wide, a `UInt8` is fine. + private let _rawValue: UInt8 + + public var rawValue: Int { + return Int(self._rawValue) + } + + public init?(rawValue: Int) { + switch rawValue { + case 0 ... 16: + self._rawValue = UInt8(truncatingIfNeeded: rawValue) + default: + return nil + } + } + + private init(_ code: UInt8) { + self._rawValue = code + } + + /// Not an error; returned on success. + public static let ok = Code(0) + + /// The operation was cancelled (typically by the caller). + public static let cancelled = Code(1) + + /// Unknown error. An example of where this error may be returned is if a + /// Status value received from another address space belongs to an error-space + /// that is not known in this address space. Also errors raised by APIs that + /// do not return enough error information may be converted to this error. + public static let unknown = Code(2) + + /// Client specified an invalid argument. Note that this differs from + /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are + /// problematic regardless of the state of the system (e.g., a malformed file + /// name). + public static let invalidArgument = Code(3) + + /// Deadline expired before operation could complete. For operations that + /// change the state of the system, this error may be returned even if the + /// operation has completed successfully. For example, a successful response + /// from a server could have been delayed long enough for the deadline to + /// expire. + public static let deadlineExceeded = Code(4) + + /// Some requested entity (e.g., file or directory) was not found. + public static let notFound = Code(5) + + /// Some entity that we attempted to create (e.g., file or directory) already + /// exists. + public static let alreadyExists = Code(6) + + /// The caller does not have permission to execute the specified operation. + /// PERMISSION_DENIED must not be used for rejections caused by exhausting + /// some resource (use RESOURCE_EXHAUSTED instead for those errors). + /// PERMISSION_DENIED must not be used if the caller can not be identified + /// (use UNAUTHENTICATED instead for those errors). + public static let permissionDenied = Code(7) + + /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the + /// entire file system is out of space. + public static let resourceExhausted = Code(8) + + /// Operation was rejected because the system is not in a state required for + /// the operation's execution. For example, directory to be deleted may be + /// non-empty, an rmdir operation is applied to a non-directory, etc. + /// + /// A litmus test that may help a service implementor in deciding + /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: + /// (a) Use UNAVAILABLE if the client can retry just the failing call. + /// (b) Use ABORTED if the client should retry at a higher-level + /// (e.g., restarting a read-modify-write sequence). + /// (c) Use FAILED_PRECONDITION if the client should not retry until + /// the system state has been explicitly fixed. E.g., if an "rmdir" + /// fails because the directory is non-empty, FAILED_PRECONDITION + /// should be returned since the client should not retry unless + /// they have first fixed up the directory by deleting files from it. + /// (d) Use FAILED_PRECONDITION if the client performs conditional + /// REST Get/Update/Delete on a resource and the resource on the + /// server does not match the condition. E.g., conflicting + /// read-modify-write on the same resource. + public static let failedPrecondition = Code(9) + + /// The operation was aborted, typically due to a concurrency issue like + /// sequencer check failures, transaction aborts, etc. + /// + /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, + /// and UNAVAILABLE. + public static let aborted = Code(10) + + /// Operation was attempted past the valid range. E.g., seeking or reading + /// past end of file. + /// + /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed + /// if the system state changes. For example, a 32-bit file system will + /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the + /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from + /// an offset past the current file size. + /// + /// There is a fair bit of overlap between FAILED_PRECONDITION and + /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) + /// when it applies so that callers who are iterating through a space can + /// easily look for an OUT_OF_RANGE error to detect when they are done. + public static let outOfRange = Code(11) + + /// Operation is not implemented or not supported/enabled in this service. + public static let unimplemented = Code(12) + + /// Internal errors. Means some invariants expected by underlying System has + /// been broken. If you see one of these errors, Something is very broken. + public static let internalError = Code(13) + + /// The service is currently unavailable. This is a most likely a transient + /// condition and may be corrected by retrying with a backoff. + /// + /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, + /// and UNAVAILABLE. + public static let unavailable = Code(14) + + /// Unrecoverable data loss or corruption. + public static let dataLoss = Code(15) + + /// The request does not have valid authentication credentials for the + /// operation. + public static let unauthenticated = Code(16) + + public var description: String { + switch self { + case .ok: + return "ok (\(self._rawValue))" + case .cancelled: + return "cancelled (\(self._rawValue))" + case .unknown: + return "unknown (\(self._rawValue))" + case .invalidArgument: + return "invalid argument (\(self._rawValue))" + case .deadlineExceeded: + return "deadline exceeded (\(self._rawValue))" + case .notFound: + return "not found (\(self._rawValue))" + case .alreadyExists: + return "already exists (\(self._rawValue))" + case .permissionDenied: + return "permission denied (\(self._rawValue))" + case .resourceExhausted: + return "resource exhausted (\(self._rawValue))" + case .failedPrecondition: + return "failed precondition (\(self._rawValue))" + case .aborted: + return "aborted (\(self._rawValue))" + case .outOfRange: + return "out of range (\(self._rawValue))" + case .unimplemented: + return "unimplemented (\(self._rawValue))" + case .internalError: + return "internal error (\(self._rawValue))" + case .unavailable: + return "unavailable (\(self._rawValue))" + case .dataLoss: + return "data loss (\(self._rawValue))" + case .unauthenticated: + return "unauthenticated (\(self._rawValue))" + default: + return String(describing: self._rawValue) + } + } + } +} + +#if compiler(>=5.6) +// `GRPCStatus` has CoW semantics so it is inherently `Sendable`. Rather than marking `GRPCStatus` +// as `@unchecked Sendable` we only mark `Storage` as such. +extension GRPCStatus.Storage: @unchecked Sendable {} +#endif // compiler(>=5.6) + +/// This protocol serves as a customisation point for error types so that gRPC calls may be +/// terminated with an appropriate status. +public protocol GRPCStatusTransformable: Error { + /// Make a `GRPCStatus` from the underlying error. + /// + /// - Returns: A `GRPCStatus` representing the underlying error. + func makeGRPCStatus() -> GRPCStatus +} + +extension GRPCStatus: GRPCStatusTransformable { + public func makeGRPCStatus() -> GRPCStatus { + return self + } +} + +extension NIOHTTP2Errors.StreamClosed: GRPCStatusTransformable { + public func makeGRPCStatus() -> GRPCStatus { + return .init(code: .unavailable, message: self.localizedDescription, cause: self) + } +} + +extension NIOHTTP2Errors.IOOnClosedConnection: GRPCStatusTransformable { + public func makeGRPCStatus() -> GRPCStatus { + return .init(code: .unavailable, message: "The connection is closed", cause: self) + } +} + +extension ChannelError: GRPCStatusTransformable { + public func makeGRPCStatus() -> GRPCStatus { + switch self { + case .inputClosed, .outputClosed, .ioOnClosedChannel: + return .init(code: .unavailable, message: "The connection is closed", cause: self) + + default: + var processingError = GRPCStatus.processingError + processingError.cause = self + return processingError + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusAndMetadata.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusAndMetadata.swift new file mode 100644 index 00000000..ec0806c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusAndMetadata.swift @@ -0,0 +1,32 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOHPACK +import NIOHTTP1 + +/// A simple struct holding a `GRPCStatus` and optionally trailers in the form of +/// `HPACKHeaders`. +public struct GRPCStatusAndTrailers: Equatable { + /// The status. + public var status: GRPCStatus + + /// The trailers. + public var trailers: HPACKHeaders? + + public init(status: GRPCStatus, trailers: HPACKHeaders? = nil) { + self.status = status + self.trailers = trailers + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusMessageMarshaller.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusMessageMarshaller.swift new file mode 100644 index 00000000..c9df18d7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCStatusMessageMarshaller.swift @@ -0,0 +1,206 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// swiftformat:disable:next enumNamespaces +public struct GRPCStatusMessageMarshaller { + /// Adds percent encoding to the given message. + /// + /// - Parameter message: Message to percent encode. + /// - Returns: Percent encoded string, or `nil` if it could not be encoded. + public static func marshall(_ message: String) -> String? { + return percentEncode(message) + } + + /// Removes percent encoding from the given message. + /// + /// - Parameter message: Message to remove encoding from. + /// - Returns: The string with percent encoding removed, or the input string if the encoding + /// could not be removed. + public static func unmarshall(_ message: String) -> String { + return removePercentEncoding(message) + } +} + +extension GRPCStatusMessageMarshaller { + /// Adds percent encoding to the given message. + /// + /// gRPC uses percent encoding as defined in RFC 3986 § 2.1 but with a different set of restricted + /// characters. The allowed characters are all visible printing characters except for (`%`, + /// `0x25`). That is: `0x20`-`0x24`, `0x26`-`0x7E`. + /// + /// - Parameter message: The message to encode. + /// - Returns: Percent encoded string, or `nil` if it could not be encoded. + private static func percentEncode(_ message: String) -> String? { + let utf8 = message.utf8 + + let encodedLength = self.percentEncodedLength(for: utf8) + // Fast-path: all characters are valid, nothing to encode. + if encodedLength == utf8.count { + return message + } + + var bytes: [UInt8] = [] + bytes.reserveCapacity(encodedLength) + + for char in message.utf8 { + switch char { + // See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses + case 0x20 ... 0x24, + 0x26 ... 0x7E: + bytes.append(char) + + default: + bytes.append(UInt8(ascii: "%")) + bytes.append(self.toHex(char >> 4)) + bytes.append(self.toHex(char & 0xF)) + } + } + + return String(bytes: bytes, encoding: .utf8) + } + + /// Returns the percent encoded length of the given `UTF8View`. + private static func percentEncodedLength(for view: String.UTF8View) -> Int { + var count = view.count + for byte in view { + switch byte { + case 0x20 ... 0x24, + 0x26 ... 0x7E: + () + + default: + count += 2 + } + } + return count + } + + /// Encode the given byte as hexadecimal. + /// + /// - Precondition: Only the four least significant bits may be set. + /// - Parameter nibble: The nibble to convert to hexadecimal. + private static func toHex(_ nibble: UInt8) -> UInt8 { + assert(nibble & 0xF == nibble) + + switch nibble { + case 0 ... 9: + return nibble &+ UInt8(ascii: "0") + default: + return nibble &+ (UInt8(ascii: "A") &- 10) + } + } + + /// Remove gRPC percent encoding from `message`. If any portion of the string could not be decoded + /// then the encoded message will be returned. + /// + /// - Parameter message: The message to remove percent encoding from. + /// - Returns: The decoded message. + private static func removePercentEncoding(_ message: String) -> String { + let utf8 = message.utf8 + + let decodedLength = self.percentDecodedLength(for: utf8) + // Fast-path: no decoding to do! Note that we may also have detected that the encoding is + // invalid, in which case we will return the encoded message: this is fine. + if decodedLength == utf8.count { + return message + } + + var chars: [UInt8] = [] + // We can't decode more characters than are already encoded. + chars.reserveCapacity(decodedLength) + + var currentIndex = utf8.startIndex + let endIndex = utf8.endIndex + + while currentIndex < endIndex { + let byte = utf8[currentIndex] + + switch byte { + case UInt8(ascii: "%"): + guard let (nextIndex, nextNextIndex) = utf8.nextTwoIndices(after: currentIndex), + let nextHex = fromHex(utf8[nextIndex]), + let nextNextHex = fromHex(utf8[nextNextIndex]) + else { + // If we can't decode the message, aborting and returning the encoded message is fine + // according to the spec. + return message + } + chars.append((nextHex << 4) | nextNextHex) + currentIndex = nextNextIndex + + default: + chars.append(byte) + } + + currentIndex = utf8.index(after: currentIndex) + } + + return String(decoding: chars, as: Unicode.UTF8.self) + } + + /// Returns the expected length of the decoded `UTF8View`. + private static func percentDecodedLength(for view: String.UTF8View) -> Int { + var encoded = 0 + + for byte in view { + switch byte { + case UInt8(ascii: "%"): + // This can't overflow since it can't be larger than view.count. + encoded &+= 1 + + default: + () + } + } + + let notEncoded = view.count - (encoded * 3) + + guard notEncoded >= 0 else { + // We've received gibberish: more '%' than expected. gRPC allows for the status message to + // be left encoded should it be incorrectly encoded. We'll do exactly that by returning + // the number of bytes in the view which will causes us to take the fast-path exit. + return view.count + } + + return notEncoded + encoded + } + + private static func fromHex(_ byte: UInt8) -> UInt8? { + switch byte { + case UInt8(ascii: "0") ... UInt8(ascii: "9"): + return byte &- UInt8(ascii: "0") + case UInt8(ascii: "A") ... UInt8(ascii: "Z"): + return byte &- (UInt8(ascii: "A") &- 10) + case UInt8(ascii: "a") ... UInt8(ascii: "z"): + return byte &- (UInt8(ascii: "a") &- 10) + default: + return nil + } + } +} + +extension String.UTF8View { + /// Return the next two valid indices after the given index. The indices are considered valid if + /// they less than `endIndex`. + fileprivate func nextTwoIndices(after index: Index) -> (Index, Index)? { + let secondIndex = self.index(index, offsetBy: 2) + guard secondIndex < self.endIndex else { + return nil + } + + return (self.index(after: index), secondIndex) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTLSConfiguration.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTLSConfiguration.swift new file mode 100644 index 00000000..cf3a9f2d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTLSConfiguration.swift @@ -0,0 +1,659 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOSSL +#endif + +#if canImport(Network) +import Network +import NIOTransportServices +import Security +#endif + +/// TLS configuration. +/// +/// This structure allow configuring TLS for a wide range of TLS implementations. Some +/// options are removed from the user's control to ensure the configuration complies with +/// the gRPC specification. +public struct GRPCTLSConfiguration: GRPCSendable { + fileprivate enum Backend: GRPCSendable { + #if canImport(NIOSSL) + /// Configuration for NIOSSSL. + case nio(NIOConfiguration) + #endif + #if canImport(Network) + /// Configuration for Network.framework. + case network(NetworkConfiguration) + #endif + } + + /// The TLS backend. + private var backend: Backend + + #if canImport(NIOSSL) + fileprivate init(nio: NIOConfiguration) { + self.backend = .nio(nio) + } + #endif + + #if canImport(Network) + fileprivate init(network: NetworkConfiguration) { + self.backend = .network(network) + } + #endif + + /// Return the configuration for NIOSSL or `nil` if Network.framework is being used as the + /// TLS backend. + #if canImport(NIOSSL) + internal var nioConfiguration: NIOConfiguration? { + switch self.backend { + case let .nio(configuration): + return configuration + #if canImport(Network) + case .network: + return nil + #endif + } + } + #endif // canImport(NIOSSL) + + internal var isNetworkFrameworkTLSBackend: Bool { + switch self.backend { + #if canImport(NIOSSL) + case .nio: + return false + #endif + #if canImport(Network) + case .network: + return true + #endif + } + } + + /// The server hostname override as used by the TLS SNI extension. + /// + /// This value is ignored when the configuration is used for a server. + /// + /// - Note: when using the Network.framework backend, this value may not be set to `nil`. + internal var hostnameOverride: String? { + get { + switch self.backend { + #if canImport(NIOSSL) + case let .nio(config): + return config.hostnameOverride + #endif + + #if canImport(Network) + case let .network(config): + return config.hostnameOverride + #endif + } + } + + set { + switch self.backend { + #if canImport(NIOSSL) + case var .nio(config): + config.hostnameOverride = newValue + self.backend = .nio(config) + #endif + + #if canImport(Network) + case var .network(config): + if #available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) { + if let hostnameOverride = newValue { + config.updateHostnameOverride(to: hostnameOverride) + } else { + // We can't unset the value so error instead. + fatalError("Can't unset hostname override when using Network.framework TLS backend.") + // FIXME: lazily set the value on the backend when applying the options. + } + } else { + // We can only make the `.network` backend if we meet the above availability checks so + // this should be unreachable. + preconditionFailure() + } + self.backend = .network(config) + #endif + } + } + } + + /// Whether the configuration requires ALPN to be used. + /// + /// The Network.framework backend does not support this option and always requires ALPN. + internal var requireALPN: Bool { + get { + switch self.backend { + #if canImport(NIOSSL) + case let .nio(config): + return config.requireALPN + #endif + + #if canImport(Network) + case .network: + return true + #endif + } + } + set { + switch self.backend { + #if canImport(NIOSSL) + case var .nio(config): + config.requireALPN = newValue + self.backend = .nio(config) + #endif + + #if canImport(Network) + case .network: + () + #endif + } + } + } + + #if canImport(NIOSSL) + // Marked to silence the deprecation warning + @available(*, deprecated) + internal init(transforming deprecated: ClientConnection.Configuration.TLS) { + self.backend = .nio( + .init( + configuration: deprecated.configuration, + customVerificationCallback: deprecated.customVerificationCallback, + hostnameOverride: deprecated.hostnameOverride, + requireALPN: false // Not currently supported. + ) + ) + } + + // Marked to silence the deprecation warning + @available(*, deprecated) + internal init(transforming deprecated: Server.Configuration.TLS) { + self.backend = .nio( + .init(configuration: deprecated.configuration, requireALPN: deprecated.requireALPN) + ) + } + + @available(*, deprecated) + internal var asDeprecatedClientConfiguration: ClientConnection.Configuration.TLS? { + if case let .nio(config) = self.backend { + var tls = ClientConnection.Configuration.TLS( + configuration: config.configuration, + hostnameOverride: config.hostnameOverride + ) + tls.customVerificationCallback = config.customVerificationCallback + return tls + } + + return nil + } + + @available(*, deprecated) + internal var asDeprecatedServerConfiguration: Server.Configuration.TLS? { + if case let .nio(config) = self.backend { + return Server.Configuration.TLS(configuration: config.configuration) + } + return nil + } + #endif // canImport(NIOSSL) +} + +// MARK: - NIO Backend + +#if canImport(NIOSSL) +extension GRPCTLSConfiguration { + internal struct NIOConfiguration { + var configuration: TLSConfiguration + var customVerificationCallback: NIOSSLCustomVerificationCallback? + var hostnameOverride: String? + // The client doesn't support this yet (https://github.com/grpc/grpc-swift/issues/1042). + var requireALPN: Bool + } + + /// TLS Configuration with suitable defaults for clients, using `NIOSSL`. + /// + /// This is a wrapper around `NIOSSL.TLSConfiguration` to restrict input to values which comply + /// with the gRPC protocol. + /// + /// - Parameter certificateChain: The certificate to offer during negotiation, defaults to an + /// empty array. + /// - Parameter privateKey: The private key associated with the leaf certificate. This defaults + /// to `nil`. + /// - Parameter trustRoots: The trust roots to validate certificates, this defaults to using a + /// root provided by the platform. + /// - Parameter certificateVerification: Whether to verify the remote certificate. Defaults to + /// `.fullVerification`. + /// - Parameter hostnameOverride: Value to use for TLS SNI extension; this must not be an IP + /// address, defaults to `nil`. + /// - Parameter customVerificationCallback: A callback to provide to override the certificate verification logic, + /// defaults to `nil`. + public static func makeClientConfigurationBackedByNIOSSL( + certificateChain: [NIOSSLCertificateSource] = [], + privateKey: NIOSSLPrivateKeySource? = nil, + trustRoots: NIOSSLTrustRoots = .default, + certificateVerification: CertificateVerification = .fullVerification, + hostnameOverride: String? = nil, + customVerificationCallback: NIOSSLCustomVerificationCallback? = nil + ) -> GRPCTLSConfiguration { + var configuration = TLSConfiguration.makeClientConfiguration() + configuration.minimumTLSVersion = .tlsv12 + configuration.certificateVerification = certificateVerification + configuration.trustRoots = trustRoots + configuration.certificateChain = certificateChain + configuration.privateKey = privateKey + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.client + + return GRPCTLSConfiguration.makeClientConfigurationBackedByNIOSSL( + configuration: configuration, + hostnameOverride: hostnameOverride, + customVerificationCallback: customVerificationCallback + ) + } + + /// Creates a gRPC TLS Configuration using the given `NIOSSL.TLSConfiguration`. + /// + /// - Note: If no ALPN tokens are set in `configuration.applicationProtocols` then "grpc-exp" + /// and "h2" will be used. + /// - Parameters: + /// - configuration: The `NIOSSL.TLSConfiguration` to base this configuration on. + /// - hostnameOverride: The hostname override to use for the TLS SNI extension. + public static func makeClientConfigurationBackedByNIOSSL( + configuration: TLSConfiguration, + hostnameOverride: String? = nil, + customVerificationCallback: NIOSSLCustomVerificationCallback? = nil + ) -> GRPCTLSConfiguration { + var configuration = configuration + + // Set the ALPN tokens if none were set. + if configuration.applicationProtocols.isEmpty { + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.client + } + + let nioConfiguration = NIOConfiguration( + configuration: configuration, + customVerificationCallback: customVerificationCallback, + hostnameOverride: hostnameOverride, + requireALPN: false // We don't currently support this. + ) + + return GRPCTLSConfiguration(nio: nioConfiguration) + } + + /// TLS Configuration with suitable defaults for servers. + /// + /// This is a wrapper around `NIOSSL.TLSConfiguration` to restrict input to values which comply + /// with the gRPC protocol. + /// + /// - Parameter certificateChain: The certificate to offer during negotiation. + /// - Parameter privateKey: The private key associated with the leaf certificate. + /// - Parameter trustRoots: The trust roots to validate certificates, this defaults to using a + /// root provided by the platform. + /// - Parameter certificateVerification: Whether to verify the remote certificate. Defaults to + /// `.none`. + /// - Parameter requireALPN: Whether ALPN is required or not. + public static func makeServerConfigurationBackedByNIOSSL( + certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + trustRoots: NIOSSLTrustRoots = .default, + certificateVerification: CertificateVerification = .none, + requireALPN: Bool = true + ) -> GRPCTLSConfiguration { + var configuration = TLSConfiguration.makeServerConfiguration( + certificateChain: certificateChain, + privateKey: privateKey + ) + + configuration.minimumTLSVersion = .tlsv12 + configuration.certificateVerification = certificateVerification + configuration.trustRoots = trustRoots + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.server + + return GRPCTLSConfiguration.makeServerConfigurationBackedByNIOSSL( + configuration: configuration, + requireALPN: requireALPN + ) + } + + /// Creates a gRPC TLS Configuration suitable for servers using the given + /// `NIOSSL.TLSConfiguration`. + /// + /// - Note: If no ALPN tokens are set in `configuration.applicationProtocols` then "grpc-exp", + /// "h2", and "http/1.1" will be used. + /// - Parameters: + /// - configuration: The `NIOSSL.TLSConfiguration` to base this configuration on. + /// - requiresALPN: Whether the server enforces ALPN. Defaults to `true`. + public static func makeServerConfigurationBackedByNIOSSL( + configuration: TLSConfiguration, + requireALPN: Bool = true + ) -> GRPCTLSConfiguration { + var configuration = configuration + + // Set the ALPN tokens if none were set. + if configuration.applicationProtocols.isEmpty { + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.server + } + + let nioConfiguration = NIOConfiguration( + configuration: configuration, + customVerificationCallback: nil, + hostnameOverride: nil, + requireALPN: requireALPN + ) + + return GRPCTLSConfiguration(nio: nioConfiguration) + } + + @usableFromInline + internal func makeNIOSSLContext() throws -> NIOSSLContext? { + switch self.backend { + case let .nio(configuration): + return try NIOSSLContext(configuration: configuration.configuration) + #if canImport(Network) + case .network: + return nil + #endif + } + } + + internal var nioSSLCustomVerificationCallback: NIOSSLCustomVerificationCallback? { + switch self.backend { + case let .nio(configuration): + return configuration.customVerificationCallback + #if canImport(Network) + case .network: + return nil + #endif + } + } + + internal mutating func updateNIOCertificateChain(to certificateChain: [NIOSSLCertificate]) { + self.modifyingNIOConfiguration { + $0.configuration.certificateChain = certificateChain.map { .certificate($0) } + } + } + + internal mutating func updateNIOPrivateKey(to privateKey: NIOSSLPrivateKey) { + self.modifyingNIOConfiguration { + $0.configuration.privateKey = .privateKey(privateKey) + } + } + + internal mutating func updateNIOTrustRoots(to trustRoots: NIOSSLTrustRoots) { + self.modifyingNIOConfiguration { + $0.configuration.trustRoots = trustRoots + } + } + + internal mutating func updateNIOCertificateVerification( + to verification: CertificateVerification + ) { + self.modifyingNIOConfiguration { + $0.configuration.certificateVerification = verification + } + } + + internal mutating func updateNIOCustomVerificationCallback( + to callback: @escaping NIOSSLCustomVerificationCallback + ) { + self.modifyingNIOConfiguration { + $0.customVerificationCallback = callback + } + } + + private mutating func modifyingNIOConfiguration(_ modify: (inout NIOConfiguration) -> Void) { + switch self.backend { + case var .nio(configuration): + modify(&configuration) + self.backend = .nio(configuration) + #if canImport(Network) + case .network: + preconditionFailure() + #endif + } + } +} +#endif // canImport(NIOSSL) + +// MARK: - Network Backend + +#if canImport(Network) +extension GRPCTLSConfiguration { + internal struct NetworkConfiguration { + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal var options: NWProtocolTLS.Options { + get { + return self._options as! NWProtocolTLS.Options + } + set { + self._options = newValue + } + } + + /// Always a NWProtocolTLS.Options. + /// + /// This somewhat insane type-erasure is necessary because we need to availability-guard the NWProtocolTLS.Options + /// (it isn't available in older SDKs), but we cannot have stored properties guarded by availability in this way, only + /// computed ones. To that end, we have to erase the type and then un-erase it. This is fairly silly. + private var _options: Any + + // This is set privately via `updateHostnameOverride(to:)` because we require availability + // guards to update the value in the underlying `sec_protocol_options`. + internal private(set) var hostnameOverride: String? + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + init(options: NWProtocolTLS.Options, hostnameOverride: String?) { + self._options = options + self.hostnameOverride = hostnameOverride + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal mutating func updateHostnameOverride(to hostnameOverride: String) { + self.hostnameOverride = hostnameOverride + sec_protocol_options_set_tls_server_name( + self.options.securityProtocolOptions, + hostnameOverride + ) + } + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func makeClientConfigurationBackedByNetworkFramework( + identity: SecIdentity? = nil, + hostnameOverride: String? = nil, + verifyCallbackWithQueue: (sec_protocol_verify_t, DispatchQueue)? = nil + ) -> GRPCTLSConfiguration { + let options = NWProtocolTLS.Options() + + if let identity = identity { + sec_protocol_options_set_local_identity( + options.securityProtocolOptions, + sec_identity_create(identity)! + ) + } + + if let hostnameOverride = hostnameOverride { + sec_protocol_options_set_tls_server_name( + options.securityProtocolOptions, + hostnameOverride + ) + } + + if let verifyCallbackWithQueue = verifyCallbackWithQueue { + sec_protocol_options_set_verify_block( + options.securityProtocolOptions, + verifyCallbackWithQueue.0, + verifyCallbackWithQueue.1 + ) + } + + if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { + sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) + } else { + sec_protocol_options_set_tls_min_version(options.securityProtocolOptions, .tlsProtocol12) + } + + for `protocol` in GRPCApplicationProtocolIdentifier.client { + sec_protocol_options_add_tls_application_protocol( + options.securityProtocolOptions, + `protocol` + ) + } + + return .makeClientConfigurationBackedByNetworkFramework( + options: options, + hostnameOverride: hostnameOverride + ) + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func makeClientConfigurationBackedByNetworkFramework( + options: NWProtocolTLS.Options, + hostnameOverride: String? = nil + ) -> GRPCTLSConfiguration { + let network = NetworkConfiguration(options: options, hostnameOverride: hostnameOverride) + return GRPCTLSConfiguration(network: network) + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func makeServerConfigurationBackedByNetworkFramework( + identity: SecIdentity + ) -> GRPCTLSConfiguration { + let options = NWProtocolTLS.Options() + + sec_protocol_options_set_local_identity( + options.securityProtocolOptions, + sec_identity_create(identity)! + ) + + if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { + sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) + } else { + sec_protocol_options_set_tls_min_version(options.securityProtocolOptions, .tlsProtocol12) + } + + for `protocol` in GRPCApplicationProtocolIdentifier.server { + sec_protocol_options_add_tls_application_protocol( + options.securityProtocolOptions, + `protocol` + ) + } + + return GRPCTLSConfiguration.makeServerConfigurationBackedByNetworkFramework(options: options) + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func makeServerConfigurationBackedByNetworkFramework( + options: NWProtocolTLS.Options + ) -> GRPCTLSConfiguration { + let network = NetworkConfiguration(options: options, hostnameOverride: nil) + return GRPCTLSConfiguration(network: network) + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal mutating func updateNetworkLocalIdentity(to identity: SecIdentity) { + self.modifyingNetworkConfiguration { + sec_protocol_options_set_local_identity( + $0.options.securityProtocolOptions, + sec_identity_create(identity)! + ) + } + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal mutating func updateNetworkVerifyCallbackWithQueue( + callback: @escaping sec_protocol_verify_t, + queue: DispatchQueue + ) { + self.modifyingNetworkConfiguration { + sec_protocol_options_set_verify_block( + $0.options.securityProtocolOptions, + callback, + queue + ) + } + } + + private mutating func modifyingNetworkConfiguration( + _ modify: (inout NetworkConfiguration) -> Void + ) { + switch self.backend { + case var .network(_configuration): + modify(&_configuration) + self.backend = .network(_configuration) + #if canImport(NIOSSL) + case .nio: + preconditionFailure() + #endif // canImport(NIOSSL) + } + } +} +#endif + +#if canImport(Network) +extension GRPCTLSConfiguration { + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal func applyNetworkTLSOptions( + to bootstrap: NIOTSConnectionBootstrap + ) -> NIOTSConnectionBootstrap { + switch self.backend { + case let .network(_configuration): + return bootstrap.tlsOptions(_configuration.options) + + #if canImport(NIOSSL) + case .nio: + // We're using NIOSSL with Network.framework; that's okay and permitted for backwards + // compatibility. + return bootstrap + #endif // canImport(NIOSSL) + } + } + + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + internal func applyNetworkTLSOptions( + to bootstrap: NIOTSListenerBootstrap + ) -> NIOTSListenerBootstrap { + switch self.backend { + case let .network(_configuration): + return bootstrap.tlsOptions(_configuration.options) + + #if canImport(NIOSSL) + case .nio: + // We're using NIOSSL with Network.framework; that's okay and permitted for backwards + // compatibility. + return bootstrap + #endif // canImport(NIOSSL) + } + } +} + +@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) +extension NIOTSConnectionBootstrap { + internal func tlsOptions( + from _configuration: GRPCTLSConfiguration + ) -> NIOTSConnectionBootstrap { + return _configuration.applyNetworkTLSOptions(to: self) + } +} + +@available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) +extension NIOTSListenerBootstrap { + internal func tlsOptions( + from _configuration: GRPCTLSConfiguration + ) -> NIOTSListenerBootstrap { + return _configuration.applyNetworkTLSOptions(to: self) + } +} +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTimeout.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTimeout.swift new file mode 100644 index 00000000..fecb2228 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCTimeout.swift @@ -0,0 +1,155 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Dispatch +import NIOCore + +/// A timeout for a gRPC call. +/// +/// Timeouts must be positive and at most 8-digits long. +public struct GRPCTimeout: CustomStringConvertible, Equatable { + /// Creates an infinite timeout. This is a sentinel value which must __not__ be sent to a gRPC service. + public static let infinite = GRPCTimeout( + nanoseconds: Int64.max, + wireEncoding: "infinite" + ) + + /// The largest amount of any unit of time which may be represented by a gRPC timeout. + internal static let maxAmount: Int64 = 99_999_999 + + /// The wire encoding of this timeout as described in the gRPC protocol. + /// See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md. + public let wireEncoding: String + public let nanoseconds: Int64 + + public var description: String { + return self.wireEncoding + } + + /// Creates a timeout from the given deadline. + /// + /// - Parameter deadline: The deadline to create a timeout from. + internal init(deadline: NIODeadline, testingOnlyNow: NIODeadline? = nil) { + switch deadline { + case .distantFuture: + self = .infinite + default: + let timeAmountUntilDeadline = deadline - (testingOnlyNow ?? .now()) + self.init(rounding: timeAmountUntilDeadline.nanoseconds, unit: .nanoseconds) + } + } + + private init(nanoseconds: Int64, wireEncoding: String) { + self.nanoseconds = nanoseconds + self.wireEncoding = wireEncoding + } + + /// Creates a `GRPCTimeout`. + /// + /// - Precondition: The amount should be greater than or equal to zero and less than or equal + /// to `GRPCTimeout.maxAmount`. + internal init(amount: Int64, unit: GRPCTimeoutUnit) { + precondition(amount >= 0 && amount <= GRPCTimeout.maxAmount) + // See "Timeout" in https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests + + // If we overflow at this point, which is certainly possible if `amount` is sufficiently large + // and `unit` is `.hours`, clamp the nanosecond timeout to `Int64.max`. It's about 292 years so + // it should be long enough for the user not to notice the difference should the rpc time out. + let (partial, overflow) = amount.multipliedReportingOverflow(by: unit.asNanoseconds) + + self.init( + nanoseconds: overflow ? Int64.max : partial, + wireEncoding: "\(amount)\(unit.rawValue)" + ) + } + + /// Create a timeout by rounding up the timeout so that it may be represented in the gRPC + /// wire format. + internal init(rounding amount: Int64, unit: GRPCTimeoutUnit) { + var roundedAmount = amount + var roundedUnit = unit + + if roundedAmount <= 0 { + roundedAmount = 0 + } else { + while roundedAmount > GRPCTimeout.maxAmount { + switch roundedUnit { + case .nanoseconds: + roundedAmount = roundedAmount.quotientRoundedUp(dividingBy: 1000) + roundedUnit = .microseconds + case .microseconds: + roundedAmount = roundedAmount.quotientRoundedUp(dividingBy: 1000) + roundedUnit = .milliseconds + case .milliseconds: + roundedAmount = roundedAmount.quotientRoundedUp(dividingBy: 1000) + roundedUnit = .seconds + case .seconds: + roundedAmount = roundedAmount.quotientRoundedUp(dividingBy: 60) + roundedUnit = .minutes + case .minutes: + roundedAmount = roundedAmount.quotientRoundedUp(dividingBy: 60) + roundedUnit = .hours + case .hours: + roundedAmount = GRPCTimeout.maxAmount + roundedUnit = .hours + } + } + } + + self.init(amount: roundedAmount, unit: roundedUnit) + } +} + +extension Int64 { + /// Returns the quotient of this value when divided by `divisor` rounded up to the nearest + /// multiple of `divisor` if the remainder is non-zero. + /// + /// - Parameter divisor: The value to divide this value by. + fileprivate func quotientRoundedUp(dividingBy divisor: Int64) -> Int64 { + let (quotient, remainder) = self.quotientAndRemainder(dividingBy: divisor) + return quotient + (remainder != 0 ? 1 : 0) + } +} + +internal enum GRPCTimeoutUnit: String { + case hours = "H" + case minutes = "M" + case seconds = "S" + case milliseconds = "m" + case microseconds = "u" + case nanoseconds = "n" + + internal var asNanoseconds: Int64 { + switch self { + case .hours: + return 60 * 60 * 1000 * 1000 * 1000 + + case .minutes: + return 60 * 1000 * 1000 * 1000 + + case .seconds: + return 1000 * 1000 * 1000 + + case .milliseconds: + return 1000 * 1000 + + case .microseconds: + return 1000 + + case .nanoseconds: + return 1 + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCWebToHTTP2ServerCodec.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCWebToHTTP2ServerCodec.swift new file mode 100644 index 00000000..3c5136b8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/GRPCWebToHTTP2ServerCodec.swift @@ -0,0 +1,768 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import struct Foundation.Data +import NIOCore +import NIOHPACK +import NIOHTTP1 +import NIOHTTP2 + +/// A codec for translating between gRPC Web (as HTTP/1) and HTTP/2 frame payloads. +internal final class GRPCWebToHTTP2ServerCodec: ChannelDuplexHandler { + internal typealias InboundIn = HTTPServerRequestPart + internal typealias InboundOut = HTTP2Frame.FramePayload + + internal typealias OutboundIn = HTTP2Frame.FramePayload + internal typealias OutboundOut = HTTPServerResponsePart + + private var stateMachine: StateMachine + + /// Create a gRPC Web to server HTTP/2 codec. + /// + /// - Parameter scheme: The value of the ':scheme' pseudo header to insert when converting the + /// request headers. + init(scheme: String) { + self.stateMachine = StateMachine(scheme: scheme) + } + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let action = self.stateMachine.processInbound( + serverRequestPart: self.unwrapInboundIn(data), + allocator: context.channel.allocator + ) + self.act(on: action, context: context) + } + + internal func write( + context: ChannelHandlerContext, + data: NIOAny, + promise: EventLoopPromise? + ) { + let action = self.stateMachine.processOutbound( + framePayload: self.unwrapOutboundIn(data), + promise: promise, + allocator: context.channel.allocator + ) + self.act(on: action, context: context) + } + + /// Acts on an action returned by the state machine. + private func act(on action: StateMachine.Action, context: ChannelHandlerContext) { + switch action { + case .none: + () + + case let .fireChannelRead(payload): + context.fireChannelRead(self.wrapInboundOut(payload)) + + case let .write(write): + if let additionalPart = write.additionalPart { + context.write(self.wrapOutboundOut(write.part), promise: nil) + context.write(self.wrapOutboundOut(additionalPart), promise: write.promise) + } else { + context.write(self.wrapOutboundOut(write.part), promise: write.promise) + } + + if write.closeChannel { + context.close(mode: .all, promise: nil) + } + + case let .completePromise(promise, result): + promise?.completeWith(result) + } + } +} + +extension GRPCWebToHTTP2ServerCodec { + internal struct StateMachine { + /// The current state. + private var state: State + private let scheme: String + + internal init(scheme: String) { + self.state = .idle + self.scheme = scheme + } + + /// Process the inbound `HTTPServerRequestPart`. + internal mutating func processInbound( + serverRequestPart: HTTPServerRequestPart, + allocator: ByteBufferAllocator + ) -> Action { + return self.state.processInbound( + serverRequestPart: serverRequestPart, + scheme: self.scheme, + allocator: allocator + ) + } + + /// Process the outbound `HTTP2Frame.FramePayload`. + internal mutating func processOutbound( + framePayload: HTTP2Frame.FramePayload, + promise: EventLoopPromise?, + allocator: ByteBufferAllocator + ) -> Action { + return self.state.processOutbound( + framePayload: framePayload, + promise: promise, + allocator: allocator + ) + } + + /// An action to take as a result of interaction with the state machine. + internal enum Action { + case none + case fireChannelRead(HTTP2Frame.FramePayload) + case write(Write) + case completePromise(EventLoopPromise?, Result) + + internal struct Write { + internal var part: HTTPServerResponsePart + internal var additionalPart: HTTPServerResponsePart? + internal var promise: EventLoopPromise? + internal var closeChannel: Bool + + internal init( + part: HTTPServerResponsePart, + additionalPart: HTTPServerResponsePart? = nil, + promise: EventLoopPromise?, + closeChannel: Bool + ) { + self.part = part + self.additionalPart = additionalPart + self.promise = promise + self.closeChannel = closeChannel + } + } + } + + fileprivate enum State { + /// Idle; nothing has been received or sent. The only valid transition is to 'fullyOpen' when + /// receiving request headers. + case idle + + /// Received request headers. Waiting for the end of request and response streams. + case fullyOpen(InboundState, OutboundState) + + /// The server has closed the response stream, we may receive other request parts from the client. + case clientOpenServerClosed(InboundState) + + /// The client has sent everything, the server still needs to close the response stream. + case clientClosedServerOpen(OutboundState) + + /// Not a real state. + case _modifying + + private var isModifying: Bool { + switch self { + case ._modifying: + return true + case .idle, .fullyOpen, .clientClosedServerOpen, .clientOpenServerClosed: + return false + } + } + + private mutating func withStateAvoidingCoWs(_ body: (inout State) -> Action) -> Action { + self = ._modifying + defer { + assert(!self.isModifying) + } + return body(&self) + } + } + + fileprivate struct InboundState { + /// A `ByteBuffer` containing the base64 encoded bytes of the request stream if gRPC Web Text + /// is being used, `nil` otherwise. + var requestBuffer: ByteBuffer? + + init(isTextEncoded: Bool, allocator: ByteBufferAllocator) { + self.requestBuffer = isTextEncoded ? allocator.buffer(capacity: 0) : nil + } + } + + fileprivate struct OutboundState { + /// A `CircularBuffer` holding any response messages if gRPC Web Text is being used, `nil` + /// otherwise. + var responseBuffer: CircularBuffer? + + /// True if the response headers have been sent. + var responseHeadersSent: Bool + + /// True if the server should close the connection when this request is done. + var closeConnection: Bool + + init(isTextEncoded: Bool, closeConnection: Bool) { + self.responseHeadersSent = false + self.responseBuffer = isTextEncoded ? CircularBuffer() : nil + self.closeConnection = closeConnection + } + } + } +} + +extension GRPCWebToHTTP2ServerCodec.StateMachine.State { + fileprivate mutating func processInbound( + serverRequestPart: HTTPServerRequestPart, + scheme: String, + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch serverRequestPart { + case let .head(head): + return self.processRequestHead(head, scheme: scheme, allocator: allocator) + case var .body(buffer): + return self.processRequestBody(&buffer) + case .end: + return self.processRequestEnd(allocator: allocator) + } + } + + fileprivate mutating func processOutbound( + framePayload: HTTP2Frame.FramePayload, + promise: EventLoopPromise?, + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch framePayload { + case let .headers(payload): + return self.processResponseHeaders(payload, promise: promise, allocator: allocator) + + case let .data(payload): + return self.processResponseData(payload, promise: promise) + + case .priority, + .rstStream, + .settings, + .pushPromise, + .ping, + .goAway, + .windowUpdate, + .alternativeService, + .origin: + preconditionFailure("Unsupported frame payload") + } + } +} + +// MARK: - Inbound + +extension GRPCWebToHTTP2ServerCodec.StateMachine.State { + private mutating func processRequestHead( + _ head: HTTPRequestHead, + scheme: String, + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + return self.withStateAvoidingCoWs { state in + let normalized = HPACKHeaders(httpHeaders: head.headers, normalizeHTTPHeaders: true) + + // Regular headers need to come after the pseudo headers. Unfortunately, this means we need to + // allocate a second headers block to use the normalization provided by NIO HTTP/2. + // + // TODO: Use API provided by https://github.com/apple/swift-nio-http2/issues/254 to avoid the + // extra copy. + var headers = HPACKHeaders() + headers.reserveCapacity(normalized.count + 4) + headers.add(name: ":path", value: head.uri) + headers.add(name: ":method", value: head.method.rawValue) + headers.add(name: ":scheme", value: scheme) + if let host = head.headers.first(name: "host") { + headers.add(name: ":authority", value: host) + } + headers.add(contentsOf: normalized) + + // Check whether we're dealing with gRPC Web Text. No need to fully validate the content-type + // that will be done at the HTTP/2 level. + let contentType = headers.first(name: GRPCHeaderName.contentType).flatMap(ContentType.init) + let isWebText = contentType == .some(.webTextProtobuf) + + let closeConnection = head.headers[canonicalForm: "connection"].contains("close") + + state = .fullyOpen( + .init(isTextEncoded: isWebText, allocator: allocator), + .init(isTextEncoded: isWebText, closeConnection: closeConnection) + ) + return .fireChannelRead(.headers(.init(headers: headers))) + } + + case .fullyOpen, .clientOpenServerClosed, .clientClosedServerOpen: + preconditionFailure("Invalid state: already received request head") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private mutating func processRequestBody( + _ buffer: inout ByteBuffer + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case .fullyOpen(var inbound, let outbound): + return self.withStateAvoidingCoWs { state in + let action = inbound.processInboundData(buffer: &buffer) + state = .fullyOpen(inbound, outbound) + return action + } + + case var .clientOpenServerClosed(inbound): + // The server is already done, but it's not our place to drop the request. + return self.withStateAvoidingCoWs { state in + let action = inbound.processInboundData(buffer: &buffer) + state = .clientOpenServerClosed(inbound) + return action + } + + case .clientClosedServerOpen: + preconditionFailure("End of request stream already received") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private mutating func processRequestEnd( + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case let .fullyOpen(_, outbound): + return self.withStateAvoidingCoWs { state in + // We're done with inbound state. + state = .clientClosedServerOpen(outbound) + + // Send an empty DATA frame with the end stream flag set. + let empty = allocator.buffer(capacity: 0) + return .fireChannelRead(.data(.init(data: .byteBuffer(empty), endStream: true))) + } + + case .clientClosedServerOpen: + preconditionFailure("End of request stream already received") + + case .clientOpenServerClosed: + return self.withStateAvoidingCoWs { state in + // Both sides are closed now, back to idle. Don't forget to pass on the .end, as + // it's necessary to communicate to the other peers that the response is done. + state = .idle + + // Send an empty DATA frame with the end stream flag set. + let empty = allocator.buffer(capacity: 0) + return .fireChannelRead(.data(.init(data: .byteBuffer(empty), endStream: true))) + } + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } +} + +// MARK: - Outbound + +extension GRPCWebToHTTP2ServerCodec.StateMachine.State { + private mutating func processResponseTrailers( + _ trailers: HPACKHeaders, + promise: EventLoopPromise?, + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case .fullyOpen(let inbound, var outbound): + return self.withStateAvoidingCoWs { state in + // Double check these are trailers. + assert(outbound.responseHeadersSent) + + // We haven't seen the end of the request stream yet. + state = .clientOpenServerClosed(inbound) + + // Avoid CoW-ing the buffers. + let responseBuffers = outbound.responseBuffer + outbound.responseBuffer = nil + + return Self.processTrailers( + responseBuffers: responseBuffers, + trailers: trailers, + promise: promise, + allocator: allocator, + closeChannel: outbound.closeConnection + ) + } + + case var .clientClosedServerOpen(state): + return self.withStateAvoidingCoWs { nextState in + // Client is closed and now so is the server. + nextState = .idle + + // Avoid CoW-ing the buffers. + let responseBuffers = state.responseBuffer + state.responseBuffer = nil + + return Self.processTrailers( + responseBuffers: responseBuffers, + trailers: trailers, + promise: promise, + allocator: allocator, + closeChannel: state.closeConnection + ) + } + + case .clientOpenServerClosed: + preconditionFailure("Already seen end of response stream") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private static func processTrailers( + responseBuffers: CircularBuffer?, + trailers: HPACKHeaders, + promise: EventLoopPromise?, + allocator: ByteBufferAllocator, + closeChannel: Bool + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + if var responseBuffers = responseBuffers { + let buffer = GRPCWebToHTTP2ServerCodec.encodeResponsesAndTrailers( + &responseBuffers, + trailers: trailers, + allocator: allocator + ) + return .write( + .init( + part: .body(.byteBuffer(buffer)), + additionalPart: .end(nil), + promise: promise, + closeChannel: closeChannel + ) + ) + } else { + // No response buffer; plain gRPC Web. + let trailers = HTTPHeaders(hpackHeaders: trailers) + return .write(.init(part: .end(trailers), promise: promise, closeChannel: closeChannel)) + } + } + + private mutating func processResponseTrailersOnly( + _ trailers: HPACKHeaders, + promise: EventLoopPromise? + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case let .fullyOpen(inbound, outbound): + return self.withStateAvoidingCoWs { state in + // We still haven't seen the end of the request stream. + state = .clientOpenServerClosed(inbound) + + let head = GRPCWebToHTTP2ServerCodec.makeResponseHead( + hpackHeaders: trailers, + closeConnection: outbound.closeConnection + ) + + return .write( + .init( + part: .head(head), + additionalPart: .end(nil), + promise: promise, + closeChannel: outbound.closeConnection + ) + ) + } + + case let .clientClosedServerOpen(outbound): + return self.withStateAvoidingCoWs { state in + // We're done, back to idle. + state = .idle + + let head = GRPCWebToHTTP2ServerCodec.makeResponseHead( + hpackHeaders: trailers, + closeConnection: outbound.closeConnection + ) + + return .write( + .init( + part: .head(head), + additionalPart: .end(nil), + promise: promise, + closeChannel: outbound.closeConnection + ) + ) + } + + case .clientOpenServerClosed: + preconditionFailure("Already seen end of response stream") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private mutating func processResponseHeaders( + _ headers: HPACKHeaders, + promise: EventLoopPromise? + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case .fullyOpen(let inbound, var outbound): + return self.withStateAvoidingCoWs { state in + outbound.responseHeadersSent = true + state = .fullyOpen(inbound, outbound) + + let head = GRPCWebToHTTP2ServerCodec.makeResponseHead( + hpackHeaders: headers, + closeConnection: outbound.closeConnection + ) + return .write(.init(part: .head(head), promise: promise, closeChannel: false)) + } + + case var .clientClosedServerOpen(outbound): + return self.withStateAvoidingCoWs { state in + outbound.responseHeadersSent = true + state = .clientClosedServerOpen(outbound) + + let head = GRPCWebToHTTP2ServerCodec.makeResponseHead( + hpackHeaders: headers, + closeConnection: outbound.closeConnection + ) + return .write(.init(part: .head(head), promise: promise, closeChannel: false)) + } + + case .clientOpenServerClosed: + preconditionFailure("Already seen end of response stream") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private mutating func processResponseHeaders( + _ payload: HTTP2Frame.FramePayload.Headers, + promise: EventLoopPromise?, + allocator: ByteBufferAllocator + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case let .fullyOpen(_, outbound), + let .clientClosedServerOpen(outbound): + if outbound.responseHeadersSent { + // Headers have been sent, these must be trailers, so end stream must be set. + assert(payload.endStream) + return self.processResponseTrailers(payload.headers, promise: promise, allocator: allocator) + } else if payload.endStream { + // Headers haven't been sent yet and end stream is set: this is a trailers only response + // so we need to send 'end' as well. + return self.processResponseTrailersOnly(payload.headers, promise: promise) + } else { + return self.processResponseHeaders(payload.headers, promise: promise) + } + + case .clientOpenServerClosed: + // We've already sent end. + return .completePromise(promise, .failure(GRPCError.AlreadyComplete())) + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + private static func processResponseData( + _ payload: HTTP2Frame.FramePayload.Data, + promise: EventLoopPromise?, + state: inout GRPCWebToHTTP2ServerCodec.StateMachine.OutboundState + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + if state.responseBuffer == nil { + // Not gRPC Web Text; just write the body. + return .write(.init(part: .body(payload.data), promise: promise, closeChannel: false)) + } else { + switch payload.data { + case let .byteBuffer(buffer): + // '!' is fine, we checked above. + state.responseBuffer!.append(buffer) + + case .fileRegion: + preconditionFailure("Unexpected IOData.fileRegion") + } + + // The response is buffered, we can consider it dealt with. + return .completePromise(promise, .success(())) + } + } + + private mutating func processResponseData( + _ payload: HTTP2Frame.FramePayload.Data, + promise: EventLoopPromise? + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + switch self { + case .idle: + preconditionFailure("Invalid state: haven't received request head") + + case .fullyOpen(let inbound, var outbound): + return self.withStateAvoidingCoWs { state in + let action = Self.processResponseData(payload, promise: promise, state: &outbound) + state = .fullyOpen(inbound, outbound) + return action + } + + case var .clientClosedServerOpen(outbound): + return self.withStateAvoidingCoWs { state in + let action = Self.processResponseData(payload, promise: promise, state: &outbound) + state = .clientClosedServerOpen(outbound) + return action + } + + case .clientOpenServerClosed: + return .completePromise(promise, .failure(GRPCError.AlreadyComplete())) + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } +} + +// MARK: - Helpers + +extension GRPCWebToHTTP2ServerCodec { + private static func makeResponseHead( + hpackHeaders: HPACKHeaders, + closeConnection: Bool + ) -> HTTPResponseHead { + var headers = HTTPHeaders(hpackHeaders: hpackHeaders) + + if closeConnection { + headers.add(name: "connection", value: "close") + } + + // Grab the status, if this is missing we've messed up in another handler. + guard let statusCode = hpackHeaders.first(name: ":status").flatMap(Int.init) else { + preconditionFailure("Invalid state: missing ':status' pseudo header") + } + + return HTTPResponseHead( + version: .init(major: 1, minor: 1), + status: .init(statusCode: statusCode), + headers: headers + ) + } + + private static func formatTrailers( + _ trailers: HPACKHeaders, + allocator: ByteBufferAllocator + ) -> ByteBuffer { + // See: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md + let encodedTrailers = trailers.map { name, value, _ in + "\(name): \(value)" + }.joined(separator: "\r\n") + + var buffer = allocator.buffer(capacity: 5 + encodedTrailers.utf8.count) + // Uncompressed trailer byte. + buffer.writeInteger(UInt8(0x80)) + // Length. + buffer.writeInteger(UInt32(encodedTrailers.utf8.count)) + // Uncompressed trailers. + buffer.writeString(encodedTrailers) + + return buffer + } + + private static func encodeResponsesAndTrailers( + _ responses: inout CircularBuffer, + trailers: HPACKHeaders, + allocator: ByteBufferAllocator + ) -> ByteBuffer { + // We need to encode the trailers along with any responses we're holding. + responses.append(self.formatTrailers(trailers, allocator: allocator)) + + let capacity = responses.lazy.map { $0.readableBytes }.reduce(0, +) + // '!' is fine: responses isn't empty, we just appended the trailers. + var buffer = responses.popFirst()! + + // Accumulate all the buffers into a single 'Data'. Ideally we wouldn't copy back and forth + // but this is fine for now. + var accumulatedData = buffer.readData(length: buffer.readableBytes)! + accumulatedData.reserveCapacity(capacity) + while let buffer = responses.popFirst() { + accumulatedData.append(contentsOf: buffer.readableBytesView) + } + + // We can reuse the popped buffer. + let base64Encoded = accumulatedData.base64EncodedString() + buffer.clear(minimumCapacity: base64Encoded.utf8.count) + buffer.writeString(base64Encoded) + + return buffer + } +} + +extension GRPCWebToHTTP2ServerCodec.StateMachine.InboundState { + fileprivate mutating func processInboundData( + buffer: inout ByteBuffer + ) -> GRPCWebToHTTP2ServerCodec.StateMachine.Action { + if self.requestBuffer == nil { + // We're not dealing with gRPC Web Text: just forward the buffer. + return .fireChannelRead(.data(.init(data: .byteBuffer(buffer)))) + } + + if self.requestBuffer!.readableBytes == 0 { + self.requestBuffer = buffer + } else { + self.requestBuffer!.writeBuffer(&buffer) + } + + let readableBytes = self.requestBuffer!.readableBytes + // The length of base64 encoded data must be a multiple of 4. + let bytesToRead = readableBytes - (readableBytes % 4) + + let action: GRPCWebToHTTP2ServerCodec.StateMachine.Action + + if bytesToRead > 0, + let base64Encoded = self.requestBuffer!.readString(length: bytesToRead), + let base64Decoded = Data(base64Encoded: base64Encoded) { + // Recycle the input buffer and restore the request buffer. + buffer.clear() + buffer.writeContiguousBytes(base64Decoded) + action = .fireChannelRead(.data(.init(data: .byteBuffer(buffer)))) + } else { + action = .none + } + + return action + } +} + +extension HTTPHeaders { + fileprivate init(hpackHeaders headers: HPACKHeaders) { + self.init() + self.reserveCapacity(headers.count) + + // Pseudo-headers are at the start of the block, so drop them and then add the remaining. + let regularHeaders = headers.drop { name, _, _ in + name.utf8.first == .some(UInt8(ascii: ":")) + }.lazy.map { name, value, _ in + (name, value) + } + + self.add(contentsOf: regularHeaders) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCServerCodec.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCServerCodec.swift new file mode 100644 index 00000000..3fc8cc86 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCServerCodec.swift @@ -0,0 +1,349 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +internal final class HTTP2ToRawGRPCServerCodec: ChannelInboundHandler, GRPCServerResponseWriter { + typealias InboundIn = HTTP2Frame.FramePayload + typealias OutboundOut = HTTP2Frame.FramePayload + + private var logger: Logger + private var state: HTTP2ToRawGRPCStateMachine + private let errorDelegate: ServerErrorDelegate? + private var context: ChannelHandlerContext! + + private let servicesByName: [Substring: CallHandlerProvider] + private let encoding: ServerMessageEncoding + private let normalizeHeaders: Bool + private let maxReceiveMessageLength: Int + + /// The configuration state of the handler. + private var configurationState: Configuration = .notConfigured + + /// Whether we are currently reading data from the `Channel`. Should be set to `false` once a + /// burst of reading has completed. + private var isReading = false + + /// Indicates whether a flush event is pending. If a flush is received while `isReading` is `true` + /// then it is held until the read completes in order to elide unnecessary flushes. + private var flushPending = false + + private enum Configuration { + case notConfigured + case configured(GRPCServerHandlerProtocol) + + var isConfigured: Bool { + switch self { + case .configured: + return true + case .notConfigured: + return false + } + } + + mutating func tearDown() -> GRPCServerHandlerProtocol? { + switch self { + case .notConfigured: + return nil + case let .configured(handler): + self = .notConfigured + return handler + } + } + } + + init( + servicesByName: [Substring: CallHandlerProvider], + encoding: ServerMessageEncoding, + errorDelegate: ServerErrorDelegate?, + normalizeHeaders: Bool, + maximumReceiveMessageLength: Int, + logger: Logger + ) { + self.logger = logger + self.errorDelegate = errorDelegate + self.servicesByName = servicesByName + self.encoding = encoding + self.normalizeHeaders = normalizeHeaders + self.maxReceiveMessageLength = maximumReceiveMessageLength + self.state = HTTP2ToRawGRPCStateMachine() + } + + internal func handlerAdded(context: ChannelHandlerContext) { + self.context = context + } + + internal func handlerRemoved(context: ChannelHandlerContext) { + self.context = nil + self.configurationState = .notConfigured + } + + internal func errorCaught(context: ChannelHandlerContext, error: Error) { + switch self.configurationState { + case .notConfigured: + context.close(mode: .all, promise: nil) + case let .configured(hander): + hander.receiveError(error) + } + } + + internal func channelInactive(context: ChannelHandlerContext) { + if let handler = self.configurationState.tearDown() { + handler.finish() + } else { + context.fireChannelInactive() + } + } + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + self.isReading = true + let payload = self.unwrapInboundIn(data) + + switch payload { + case let .headers(payload): + let receiveHeaders = self.state.receive( + headers: payload.headers, + eventLoop: context.eventLoop, + errorDelegate: self.errorDelegate, + remoteAddress: context.channel.remoteAddress, + logger: self.logger, + allocator: context.channel.allocator, + responseWriter: self, + closeFuture: context.channel.closeFuture, + services: self.servicesByName, + encoding: self.encoding, + normalizeHeaders: self.normalizeHeaders + ) + + switch receiveHeaders { + case let .configure(handler): + assert(!self.configurationState.isConfigured) + self.configurationState = .configured(handler) + self.configured() + + case let .rejectRPC(trailers): + assert(!self.configurationState.isConfigured) + // We're not handling this request: write headers and end stream. + let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true)) + context.writeAndFlush(self.wrapOutboundOut(payload), promise: nil) + } + + case let .data(payload): + switch payload.data { + case var .byteBuffer(buffer): + let action = self.state.receive(buffer: &buffer, endStream: payload.endStream) + switch action { + case .tryReading: + self.tryReadingMessage() + + case .finishHandler: + let handler = self.configurationState.tearDown() + handler?.finish() + + case .nothing: + () + } + + case .fileRegion: + preconditionFailure("Unexpected IOData.fileRegion") + } + + // Ignored. + case .alternativeService, + .goAway, + .origin, + .ping, + .priority, + .pushPromise, + .rstStream, + .settings, + .windowUpdate: + () + } + } + + internal func channelReadComplete(context: ChannelHandlerContext) { + self.isReading = false + + if self.flushPending { + self.flushPending = false + context.flush() + } + + context.fireChannelReadComplete() + } + + /// Called when the pipeline has finished configuring. + private func configured() { + switch self.state.pipelineConfigured() { + case let .forwardHeaders(headers): + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveMetadata(headers) + } + + case let .forwardHeadersAndRead(headers): + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveMetadata(headers) + } + self.tryReadingMessage() + } + } + + /// Try to read a request message from the buffer. + private func tryReadingMessage() { + // This while loop exists to break the recursion in `.forwardMessageThenReadNextMessage`. + // Almost all cases return directly out of the loop. + while true { + let action = self.state.readNextRequest( + maxLength: self.maxReceiveMessageLength + ) + switch action { + case .none: + return + + case let .forwardMessage(buffer): + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveMessage(buffer) + } + + return + + case let .forwardMessageThenReadNextMessage(buffer): + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveMessage(buffer) + } + + continue + + case .forwardEnd: + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveEnd() + } + + return + + case let .errorCaught(error): + switch self.configurationState { + case .notConfigured: + preconditionFailure() + case let .configured(handler): + handler.receiveError(error) + } + + return + } + } + } + + internal func sendMetadata( + _ headers: HPACKHeaders, + flush: Bool, + promise: EventLoopPromise? + ) { + switch self.state.send(headers: headers) { + case let .success(headers): + let payload = HTTP2Frame.FramePayload.headers(.init(headers: headers)) + self.context.write(self.wrapOutboundOut(payload), promise: promise) + if flush { + self.markFlushPoint() + } + + case let .failure(error): + promise?.fail(error) + } + } + + internal func sendMessage( + _ buffer: ByteBuffer, + metadata: MessageMetadata, + promise: EventLoopPromise? + ) { + let writeBuffer = self.state.send( + buffer: buffer, + allocator: self.context.channel.allocator, + compress: metadata.compress + ) + + switch writeBuffer { + case let .success(buffer): + let payload = HTTP2Frame.FramePayload.data(.init(data: .byteBuffer(buffer))) + self.context.write(self.wrapOutboundOut(payload), promise: promise) + if metadata.flush { + self.markFlushPoint() + } + + case let .failure(error): + promise?.fail(error) + } + } + + internal func sendEnd( + status: GRPCStatus, + trailers: HPACKHeaders, + promise: EventLoopPromise? + ) { + switch self.state.send(status: status, trailers: trailers) { + case let .sendTrailers(trailers): + self.sendTrailers(trailers, promise: promise) + + case let .sendTrailersAndFinish(trailers): + self.sendTrailers(trailers, promise: promise) + + // 'finish' the handler. + let handler = self.configurationState.tearDown() + handler?.finish() + + case let .failure(error): + promise?.fail(error) + } + } + + private func sendTrailers(_ trailers: HPACKHeaders, promise: EventLoopPromise?) { + // Always end stream for status and trailers. + let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true)) + self.context.write(self.wrapOutboundOut(payload), promise: promise) + // We'll always flush on end. + self.markFlushPoint() + } + + /// Mark a flush as pending - to be emitted once the read completes - if we're currently reading, + /// or emit a flush now if we are not. + private func markFlushPoint() { + if self.isReading { + self.flushPending = true + } else { + self.flushPending = false + self.context.flush() + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift new file mode 100644 index 00000000..2d45e850 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift @@ -0,0 +1,1305 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +struct HTTP2ToRawGRPCStateMachine { + /// The current state. + private var state: State = .requestIdleResponseIdle + + /// Temporarily sets `self.state` to `._modifying` before calling the provided block and setting + /// `self.state` to the `State` modified by the block. + /// + /// Since we hold state as associated data on our `State` enum, any modification to that state + /// will trigger a copy on write for its heap allocated data. Temporarily setting the `self.state` + /// to `._modifying` allows us to avoid an extra reference to any heap allocated data and + /// therefore avoid a copy on write. + @inlinable + internal mutating func withStateAvoidingCoWs(_ body: (inout State) -> Action) -> Action { + var state: State = ._modifying + swap(&self.state, &state) + defer { + swap(&self.state, &state) + } + return body(&state) + } +} + +extension HTTP2ToRawGRPCStateMachine { + enum State { + // Both peers are idle. Nothing has happened to the stream. + case requestIdleResponseIdle + + // Received valid headers. Nothing has been sent in response. + case requestOpenResponseIdle(RequestOpenResponseIdleState) + + // Received valid headers and request(s). Response headers have been sent. + case requestOpenResponseOpen(RequestOpenResponseOpenState) + + // Received valid headers and request(s) but not end of the request stream. Response stream has + // been closed. + case requestOpenResponseClosed + + // The request stream is closed. Nothing has been sent in response. + case requestClosedResponseIdle(RequestClosedResponseIdleState) + + // The request stream is closed. Response headers have been sent. + case requestClosedResponseOpen(RequestClosedResponseOpenState) + + // Both streams are closed. This state is terminal. + case requestClosedResponseClosed + + // Not a real state. See 'withStateAvoidingCoWs'. + case _modifying + } + + struct RequestOpenResponseIdleState { + /// A length prefixed message reader for request messages. + var reader: LengthPrefixedMessageReader + + /// A length prefixed message writer for response messages. + var writer: LengthPrefixedMessageWriter + + /// The content type of the RPC. + var contentType: ContentType + + /// An accept encoding header to send in the response headers indicating the message encoding + /// that the server supports. + var acceptEncoding: String? + + /// A message encoding header to send in the response headers indicating the encoding which will + /// be used for responses. + var responseEncoding: String? + + /// Whether to normalize user-provided metadata. + var normalizeHeaders: Bool + + /// The pipeline configuration state. + var configurationState: ConfigurationState + } + + struct RequestClosedResponseIdleState { + /// A length prefixed message reader for request messages. + var reader: LengthPrefixedMessageReader + + /// A length prefixed message writer for response messages. + var writer: LengthPrefixedMessageWriter + + /// The content type of the RPC. + var contentType: ContentType + + /// An accept encoding header to send in the response headers indicating the message encoding + /// that the server supports. + var acceptEncoding: String? + + /// A message encoding header to send in the response headers indicating the encoding which will + /// be used for responses. + var responseEncoding: String? + + /// Whether to normalize user-provided metadata. + var normalizeHeaders: Bool + + /// The pipeline configuration state. + var configurationState: ConfigurationState + + init(from state: RequestOpenResponseIdleState) { + self.reader = state.reader + self.writer = state.writer + self.contentType = state.contentType + self.acceptEncoding = state.acceptEncoding + self.responseEncoding = state.responseEncoding + self.normalizeHeaders = state.normalizeHeaders + self.configurationState = state.configurationState + } + } + + struct RequestOpenResponseOpenState { + /// A length prefixed message reader for request messages. + var reader: LengthPrefixedMessageReader + + /// A length prefixed message writer for response messages. + var writer: LengthPrefixedMessageWriter + + /// Whether to normalize user-provided metadata. + var normalizeHeaders: Bool + + init(from state: RequestOpenResponseIdleState) { + self.reader = state.reader + self.writer = state.writer + self.normalizeHeaders = state.normalizeHeaders + } + } + + struct RequestClosedResponseOpenState { + /// A length prefixed message reader for request messages. + var reader: LengthPrefixedMessageReader + + /// A length prefixed message writer for response messages. + var writer: LengthPrefixedMessageWriter + + /// Whether to normalize user-provided metadata. + var normalizeHeaders: Bool + + init(from state: RequestOpenResponseOpenState) { + self.reader = state.reader + self.writer = state.writer + self.normalizeHeaders = state.normalizeHeaders + } + + init(from state: RequestClosedResponseIdleState) { + self.reader = state.reader + self.writer = state.writer + self.normalizeHeaders = state.normalizeHeaders + } + } + + /// The pipeline configuration state. + enum ConfigurationState { + /// The pipeline is being configured. Any message data will be buffered into an appropriate + /// message reader. + case configuring(HPACKHeaders) + + /// The pipeline is configured. + case configured + + /// Returns true if the configuration is in the `.configured` state. + var isConfigured: Bool { + switch self { + case .configuring: + return false + case .configured: + return true + } + } + + /// Configuration has completed. + mutating func configured() -> HPACKHeaders { + switch self { + case .configured: + preconditionFailure("Invalid state: already configured") + + case let .configuring(headers): + self = .configured + return headers + } + } + } +} + +extension HTTP2ToRawGRPCStateMachine { + enum PipelineConfiguredAction { + /// Forward the given headers. + case forwardHeaders(HPACKHeaders) + /// Forward the given headers and try reading the next message. + case forwardHeadersAndRead(HPACKHeaders) + } + + enum ReceiveHeadersAction { + /// Configure the RPC to use the given server handler. + case configure(GRPCServerHandlerProtocol) + /// Reject the RPC by writing out the given headers and setting end-stream. + case rejectRPC(HPACKHeaders) + } + + enum ReadNextMessageAction { + /// Do nothing. + case none + /// Forward the buffer. + case forwardMessage(ByteBuffer) + /// Forward the buffer and try reading the next message. + case forwardMessageThenReadNextMessage(ByteBuffer) + /// Forward the 'end' of stream request part. + case forwardEnd + /// Throw an error down the pipeline. + case errorCaught(Error) + } + + struct StateAndReceiveHeadersAction { + /// The next state. + var state: State + /// The action to take. + var action: ReceiveHeadersAction + } + + struct StateAndReceiveDataAction { + /// The next state. + var state: State + /// The action to take + var action: ReceiveDataAction + } + + enum ReceiveDataAction: Hashable { + /// Try to read the next message from the state machine. + case tryReading + /// Invoke 'finish' on the RPC handler. + case finishHandler + /// Do nothing. + case nothing + } + + enum SendEndAction { + /// Send trailers to the client. + case sendTrailers(HPACKHeaders) + /// Send trailers to the client and invoke 'finish' on the RPC handler. + case sendTrailersAndFinish(HPACKHeaders) + /// Fail any promise associated with this send. + case failure(Error) + } +} + +// MARK: Receive Headers + +// This is the only state in which we can receive headers. +extension HTTP2ToRawGRPCStateMachine.State { + private func _receive( + headers: HPACKHeaders, + eventLoop: EventLoop, + errorDelegate: ServerErrorDelegate?, + remoteAddress: SocketAddress?, + logger: Logger, + allocator: ByteBufferAllocator, + responseWriter: GRPCServerResponseWriter, + closeFuture: EventLoopFuture, + services: [Substring: CallHandlerProvider], + encoding: ServerMessageEncoding, + normalizeHeaders: Bool + ) -> HTTP2ToRawGRPCStateMachine.StateAndReceiveHeadersAction { + // Extract and validate the content type. If it's nil we need to close. + guard let contentType = self.extractContentType(from: headers) else { + return self.unsupportedContentType() + } + + // Now extract the request message encoding and setup an appropriate message reader. + // We may send back a list of acceptable request message encodings as well. + let reader: LengthPrefixedMessageReader + let acceptableRequestEncoding: String? + + switch self.extractRequestEncoding(from: headers, encoding: encoding) { + case let .valid(messageReader, acceptEncodingHeader): + reader = messageReader + acceptableRequestEncoding = acceptEncodingHeader + + case let .invalid(status, acceptableRequestEncoding): + return self.invalidRequestEncoding( + status: status, + acceptableRequestEncoding: acceptableRequestEncoding, + contentType: contentType + ) + } + + // Figure out which encoding we should use for responses. + let (writer, responseEncoding) = self.extractResponseEncoding(from: headers, encoding: encoding) + + // Parse the path, and create a call handler. + guard let path = headers.first(name: ":path") else { + return self.methodNotImplemented("", contentType: contentType) + } + + guard let callPath = CallPath(requestURI: path), + let service = services[Substring(callPath.service)] else { + return self.methodNotImplemented(path, contentType: contentType) + } + + // Create a call handler context, i.e. a bunch of 'stuff' we need to create the handler with, + // some of which is exposed to service providers. + let context = CallHandlerContext( + errorDelegate: errorDelegate, + logger: logger, + encoding: encoding, + eventLoop: eventLoop, + path: path, + remoteAddress: remoteAddress, + responseWriter: responseWriter, + allocator: allocator, + closeFuture: closeFuture + ) + + // We have a matching service, hopefully we have a provider for the method too. + let method = Substring(callPath.method) + + if let handler = service.handle(method: method, context: context) { + let nextState = HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState( + reader: reader, + writer: writer, + contentType: contentType, + acceptEncoding: acceptableRequestEncoding, + responseEncoding: responseEncoding, + normalizeHeaders: normalizeHeaders, + configurationState: .configuring(headers) + ) + + return .init( + state: .requestOpenResponseIdle(nextState), + action: .configure(handler) + ) + } else { + return self.methodNotImplemented(path, contentType: contentType) + } + } + + /// The 'content-type' is not supported; close with status code 415. + private func unsupportedContentType() -> HTTP2ToRawGRPCStateMachine.StateAndReceiveHeadersAction { + // From: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md + // + // If 'content-type' does not begin with "application/grpc", gRPC servers SHOULD respond + // with HTTP status of 415 (Unsupported Media Type). This will prevent other HTTP/2 + // clients from interpreting a gRPC error response, which uses status 200 (OK), as + // successful. + let trailers = HPACKHeaders([(":status", "415")]) + return .init( + state: .requestClosedResponseClosed, + action: .rejectRPC(trailers) + ) + } + + /// The RPC method is not implemented. Close with an appropriate status. + private func methodNotImplemented( + _ path: String, + contentType: ContentType + ) -> HTTP2ToRawGRPCStateMachine.StateAndReceiveHeadersAction { + let trailers = HTTP2ToRawGRPCStateMachine.makeResponseTrailersOnly( + for: GRPCStatus(code: .unimplemented, message: "'\(path)' is not implemented"), + contentType: contentType, + acceptableRequestEncoding: nil, + userProvidedHeaders: nil, + normalizeUserProvidedHeaders: false + ) + + return .init( + state: .requestClosedResponseClosed, + action: .rejectRPC(trailers) + ) + } + + /// The request encoding specified by the client is not supported. Close with an appropriate + /// status. + private func invalidRequestEncoding( + status: GRPCStatus, + acceptableRequestEncoding: String?, + contentType: ContentType + ) -> HTTP2ToRawGRPCStateMachine.StateAndReceiveHeadersAction { + let trailers = HTTP2ToRawGRPCStateMachine.makeResponseTrailersOnly( + for: status, + contentType: contentType, + acceptableRequestEncoding: acceptableRequestEncoding, + userProvidedHeaders: nil, + normalizeUserProvidedHeaders: false + ) + + return .init( + state: .requestClosedResponseClosed, + action: .rejectRPC(trailers) + ) + } + + /// Makes a 'GRPCStatus' and response trailers suitable for returning to the client when the + /// request message encoding is not supported. + /// + /// - Parameters: + /// - encoding: The unsupported request message encoding sent by the client. + /// - acceptable: The list if acceptable request message encoding the client may use. + /// - Returns: The status and trailers to return to the client. + private func makeStatusAndTrailersForUnsupportedEncoding( + _ encoding: String, + advertisedEncoding: [String] + ) -> (GRPCStatus, acceptEncoding: String?) { + let status: GRPCStatus + let acceptEncoding: String? + + if advertisedEncoding.isEmpty { + // No compression is supported; there's nothing to tell the client about. + status = GRPCStatus(code: .unimplemented, message: "compression is not supported") + acceptEncoding = nil + } else { + // Return a list of supported encodings which we advertise. (The list we advertise may be a + // subset of the encodings we support.) + acceptEncoding = advertisedEncoding.joined(separator: ",") + status = GRPCStatus( + code: .unimplemented, + message: "\(encoding) compression is not supported, supported algorithms are " + + "listed in '\(GRPCHeaderName.acceptEncoding)'" + ) + } + + return (status, acceptEncoding) + } + + /// Extract and validate the 'content-type' sent by the client. + /// - Parameter headers: The headers to extract the 'content-type' from + private func extractContentType(from headers: HPACKHeaders) -> ContentType? { + return headers.first(name: GRPCHeaderName.contentType).flatMap(ContentType.init) + } + + /// The result of validating the request encoding header. + private enum RequestEncodingValidation { + /// The encoding was valid. + case valid(messageReader: LengthPrefixedMessageReader, acceptEncoding: String?) + /// The encoding was invalid, the RPC should be terminated with this status. + case invalid(status: GRPCStatus, acceptEncoding: String?) + } + + /// Extract and validate the request message encoding header. + /// - Parameters: + /// - headers: The headers to extract the message encoding header from. + /// - Returns: `RequestEncodingValidation`, either a message reader suitable for decoding requests + /// and an accept encoding response header if the request encoding was valid, or a pair of + /// `GRPCStatus` and trailers to close the RPC with. + private func extractRequestEncoding( + from headers: HPACKHeaders, + encoding: ServerMessageEncoding + ) -> RequestEncodingValidation { + let encodings = headers[canonicalForm: GRPCHeaderName.encoding] + + // Fail if there's more than one encoding header. + if encodings.count > 1 { + let status = GRPCStatus( + code: .invalidArgument, + message: "'\(GRPCHeaderName.encoding)' must contain no more than one value but was '\(encodings.joined(separator: ", "))'" + ) + return .invalid(status: status, acceptEncoding: nil) + } + + let encodingHeader = encodings.first + let result: RequestEncodingValidation + + let validator = MessageEncodingHeaderValidator(encoding: encoding) + + switch validator.validate(requestEncoding: encodingHeader) { + case let .supported(algorithm, decompressionLimit, acceptEncoding): + // Request message encoding is valid and supported. + result = .valid( + messageReader: LengthPrefixedMessageReader( + compression: algorithm, + decompressionLimit: decompressionLimit + ), + acceptEncoding: acceptEncoding.isEmpty ? nil : acceptEncoding.joined(separator: ",") + ) + + case .noCompression: + // No message encoding header was present. This means no compression is being used. + result = .valid( + messageReader: LengthPrefixedMessageReader(), + acceptEncoding: nil + ) + + case let .unsupported(encoding, acceptable): + // Request encoding is not supported. + let (status, acceptEncoding) = self.makeStatusAndTrailersForUnsupportedEncoding( + encoding, + advertisedEncoding: acceptable + ) + result = .invalid(status: status, acceptEncoding: acceptEncoding) + } + + return result + } + + /// Extract a suitable message encoding for responses. + /// - Parameters: + /// - headers: The headers to extract the acceptable response message encoding from. + /// - configuration: The encoding configuration for the server. + /// - Returns: A message writer and the response encoding header to send back to the client. + private func extractResponseEncoding( + from headers: HPACKHeaders, + encoding: ServerMessageEncoding + ) -> (LengthPrefixedMessageWriter, String?) { + let writer: LengthPrefixedMessageWriter + let responseEncoding: String? + + switch encoding { + case let .enabled(configuration): + // Extract the encodings acceptable to the client for response messages. + let acceptableResponseEncoding = headers[canonicalForm: GRPCHeaderName.acceptEncoding] + + // Select the first algorithm that we support and have enabled. If we don't find one then we + // won't compress response messages. + let algorithm = acceptableResponseEncoding.lazy.compactMap { value in + CompressionAlgorithm(rawValue: value) + }.first { + configuration.enabledAlgorithms.contains($0) + } + + writer = LengthPrefixedMessageWriter(compression: algorithm) + responseEncoding = algorithm?.name + + case .disabled: + // The server doesn't have compression enabled. + writer = LengthPrefixedMessageWriter(compression: .none) + responseEncoding = nil + } + + return (writer, responseEncoding) + } +} + +// MARK: - Receive Data + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState { + mutating func receive( + buffer: inout ByteBuffer, + endStream: Bool + ) -> HTTP2ToRawGRPCStateMachine.StateAndReceiveDataAction { + // Append the bytes to the reader. + self.reader.append(buffer: &buffer) + + let state: HTTP2ToRawGRPCStateMachine.State + let action: HTTP2ToRawGRPCStateMachine.ReceiveDataAction + + switch (self.configurationState.isConfigured, endStream) { + case (true, true): + /// Configured and end stream: read from the buffer, end will be sent as a result of draining + /// the reader in the next state. + state = .requestClosedResponseIdle(.init(from: self)) + action = .tryReading + + case (true, false): + /// Configured but not end stream, just read from the buffer. + state = .requestOpenResponseIdle(self) + action = .tryReading + + case (false, true): + // Not configured yet, but end of stream. Request stream is now closed but there's no point + // reading yet. + state = .requestClosedResponseIdle(.init(from: self)) + action = .nothing + + case (false, false): + // Not configured yet, not end stream. No point reading a message yet since we don't have + // anywhere to deliver it. + state = .requestOpenResponseIdle(self) + action = .nothing + } + + return .init(state: state, action: action) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseOpenState { + mutating func receive( + buffer: inout ByteBuffer, + endStream: Bool + ) -> HTTP2ToRawGRPCStateMachine.StateAndReceiveDataAction { + self.reader.append(buffer: &buffer) + + let state: HTTP2ToRawGRPCStateMachine.State + + if endStream { + // End stream, so move to the closed state. Any end of request stream events events will + // happen as a result of reading from the closed state. + state = .requestClosedResponseOpen(.init(from: self)) + } else { + state = .requestOpenResponseOpen(self) + } + + return .init(state: state, action: .tryReading) + } +} + +// MARK: - Send Headers + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState { + func send(headers userProvidedHeaders: HPACKHeaders) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseHeaders( + contentType: self.contentType, + responseEncoding: self.responseEncoding, + acceptableRequestEncoding: self.acceptEncoding, + userProvidedHeaders: userProvidedHeaders, + normalizeUserProvidedHeaders: self.normalizeHeaders + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseIdleState { + func send(headers userProvidedHeaders: HPACKHeaders) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseHeaders( + contentType: self.contentType, + responseEncoding: self.responseEncoding, + acceptableRequestEncoding: self.acceptEncoding, + userProvidedHeaders: userProvidedHeaders, + normalizeUserProvidedHeaders: self.normalizeHeaders + ) + } +} + +// MARK: - Send Data + +extension HTTP2ToRawGRPCStateMachine { + static func writeGRPCFramedMessage( + _ buffer: ByteBuffer, + compress: Bool, + allocator: ByteBufferAllocator, + writer: LengthPrefixedMessageWriter + ) -> Result { + do { + let prefixed = try writer.write(buffer: buffer, allocator: allocator, compressed: compress) + return .success(prefixed) + } catch { + return .failure(error) + } + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseOpenState { + func send( + buffer: ByteBuffer, + allocator: ByteBufferAllocator, + compress: Bool + ) -> Result { + return HTTP2ToRawGRPCStateMachine.writeGRPCFramedMessage( + buffer, + compress: compress, + allocator: allocator, + writer: self.writer + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseOpenState { + func send( + buffer: ByteBuffer, + allocator: ByteBufferAllocator, + compress: Bool + ) -> Result { + return HTTP2ToRawGRPCStateMachine.writeGRPCFramedMessage( + buffer, + compress: compress, + allocator: allocator, + writer: self.writer + ) + } +} + +// MARK: - Send End + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState { + func send( + status: GRPCStatus, + trailers userProvidedTrailers: HPACKHeaders + ) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseTrailersOnly( + for: status, + contentType: self.contentType, + acceptableRequestEncoding: self.acceptEncoding, + userProvidedHeaders: userProvidedTrailers, + normalizeUserProvidedHeaders: self.normalizeHeaders + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseIdleState { + func send( + status: GRPCStatus, + trailers userProvidedTrailers: HPACKHeaders + ) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseTrailersOnly( + for: status, + contentType: self.contentType, + acceptableRequestEncoding: self.acceptEncoding, + userProvidedHeaders: userProvidedTrailers, + normalizeUserProvidedHeaders: self.normalizeHeaders + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseOpenState { + func send( + status: GRPCStatus, + trailers userProvidedTrailers: HPACKHeaders + ) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseTrailers( + for: status, + userProvidedHeaders: userProvidedTrailers, + normalizeUserProvidedHeaders: true + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseOpenState { + func send( + status: GRPCStatus, + trailers userProvidedTrailers: HPACKHeaders + ) -> HPACKHeaders { + return HTTP2ToRawGRPCStateMachine.makeResponseTrailers( + for: status, + userProvidedHeaders: userProvidedTrailers, + normalizeUserProvidedHeaders: true + ) + } +} + +// MARK: - Pipeline Configured + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState { + mutating func pipelineConfigured() -> HTTP2ToRawGRPCStateMachine.PipelineConfiguredAction { + let headers = self.configurationState.configured() + let action: HTTP2ToRawGRPCStateMachine.PipelineConfiguredAction + + // If there are unprocessed bytes then we need to read messages as well. + let hasUnprocessedBytes = self.reader.unprocessedBytes != 0 + + if hasUnprocessedBytes { + // If there are unprocessed bytes, we need to try to read after sending the metadata. + action = .forwardHeadersAndRead(headers) + } else { + // No unprocessed bytes; the reader is empty. Just send the metadata. + action = .forwardHeaders(headers) + } + + return action + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseIdleState { + mutating func pipelineConfigured() -> HTTP2ToRawGRPCStateMachine.PipelineConfiguredAction { + let headers = self.configurationState.configured() + // Since we're already closed, we need to forward the headers and start reading. + return .forwardHeadersAndRead(headers) + } +} + +// MARK: - Read Next Request + +extension HTTP2ToRawGRPCStateMachine { + static func read( + from reader: inout LengthPrefixedMessageReader, + requestStreamClosed: Bool, + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + do { + if let buffer = try reader.nextMessage(maxLength: maxLength) { + if reader.unprocessedBytes > 0 || requestStreamClosed { + // Either there are unprocessed bytes or the request stream is now closed: deliver the + // message and then try to read. The subsequent read may be another message or it may + // be end stream. + return .forwardMessageThenReadNextMessage(buffer) + } else { + // Nothing left to process and the stream isn't closed yet, just forward the message. + return .forwardMessage(buffer) + } + } else if requestStreamClosed { + return .forwardEnd + } else { + return .none + } + } catch { + return .errorCaught(error) + } + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseIdleState { + mutating func readNextRequest( + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + return HTTP2ToRawGRPCStateMachine.read( + from: &self.reader, + requestStreamClosed: false, + maxLength: maxLength + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestOpenResponseOpenState { + mutating func readNextRequest( + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + return HTTP2ToRawGRPCStateMachine.read( + from: &self.reader, + requestStreamClosed: false, + maxLength: maxLength + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseIdleState { + mutating func readNextRequest( + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + return HTTP2ToRawGRPCStateMachine.read( + from: &self.reader, + requestStreamClosed: true, + maxLength: maxLength + ) + } +} + +extension HTTP2ToRawGRPCStateMachine.RequestClosedResponseOpenState { + mutating func readNextRequest( + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + return HTTP2ToRawGRPCStateMachine.read( + from: &self.reader, + requestStreamClosed: true, + maxLength: maxLength + ) + } +} + +// MARK: - Top Level State Changes + +extension HTTP2ToRawGRPCStateMachine { + /// Receive request headers. + mutating func receive( + headers: HPACKHeaders, + eventLoop: EventLoop, + errorDelegate: ServerErrorDelegate?, + remoteAddress: SocketAddress?, + logger: Logger, + allocator: ByteBufferAllocator, + responseWriter: GRPCServerResponseWriter, + closeFuture: EventLoopFuture, + services: [Substring: CallHandlerProvider], + encoding: ServerMessageEncoding, + normalizeHeaders: Bool + ) -> ReceiveHeadersAction { + return self.withStateAvoidingCoWs { state in + state.receive( + headers: headers, + eventLoop: eventLoop, + errorDelegate: errorDelegate, + remoteAddress: remoteAddress, + logger: logger, + allocator: allocator, + responseWriter: responseWriter, + closeFuture: closeFuture, + services: services, + encoding: encoding, + normalizeHeaders: normalizeHeaders + ) + } + } + + /// Receive request buffer. + /// - Parameters: + /// - buffer: The received buffer. + /// - endStream: Whether end stream was set. + /// - Returns: Returns whether the caller should try to read a message from the buffer. + mutating func receive(buffer: inout ByteBuffer, endStream: Bool) -> ReceiveDataAction { + return self.withStateAvoidingCoWs { state in + state.receive(buffer: &buffer, endStream: endStream) + } + } + + /// Send response headers. + mutating func send(headers: HPACKHeaders) -> Result { + return self.withStateAvoidingCoWs { state in + state.send(headers: headers) + } + } + + /// Send a response buffer. + func send( + buffer: ByteBuffer, + allocator: ByteBufferAllocator, + compress: Bool + ) -> Result { + return self.state.send(buffer: buffer, allocator: allocator, compress: compress) + } + + /// Send status and trailers. + mutating func send( + status: GRPCStatus, + trailers: HPACKHeaders + ) -> HTTP2ToRawGRPCStateMachine.SendEndAction { + return self.withStateAvoidingCoWs { state in + state.send(status: status, trailers: trailers) + } + } + + /// The pipeline has been configured with a service provider. + mutating func pipelineConfigured() -> PipelineConfiguredAction { + return self.withStateAvoidingCoWs { state in + state.pipelineConfigured() + } + } + + /// Try to read a request message. + mutating func readNextRequest(maxLength: Int) -> ReadNextMessageAction { + return self.withStateAvoidingCoWs { state in + state.readNextRequest(maxLength: maxLength) + } + } +} + +extension HTTP2ToRawGRPCStateMachine.State { + mutating func pipelineConfigured() -> HTTP2ToRawGRPCStateMachine.PipelineConfiguredAction { + switch self { + case .requestIdleResponseIdle: + preconditionFailure("Invalid state: pipeline configured before receiving request headers") + + case var .requestOpenResponseIdle(state): + let action = state.pipelineConfigured() + self = .requestOpenResponseIdle(state) + return action + + case var .requestClosedResponseIdle(state): + let action = state.pipelineConfigured() + self = .requestClosedResponseIdle(state) + return action + + case .requestOpenResponseOpen, + .requestOpenResponseClosed, + .requestClosedResponseOpen, + .requestClosedResponseClosed: + preconditionFailure("Invalid state: response stream opened before pipeline was configured") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + mutating func receive( + headers: HPACKHeaders, + eventLoop: EventLoop, + errorDelegate: ServerErrorDelegate?, + remoteAddress: SocketAddress?, + logger: Logger, + allocator: ByteBufferAllocator, + responseWriter: GRPCServerResponseWriter, + closeFuture: EventLoopFuture, + services: [Substring: CallHandlerProvider], + encoding: ServerMessageEncoding, + normalizeHeaders: Bool + ) -> HTTP2ToRawGRPCStateMachine.ReceiveHeadersAction { + switch self { + // These are the only states in which we can receive headers. Everything else is invalid. + case .requestIdleResponseIdle, + .requestClosedResponseClosed: + let stateAndAction = self._receive( + headers: headers, + eventLoop: eventLoop, + errorDelegate: errorDelegate, + remoteAddress: remoteAddress, + logger: logger, + allocator: allocator, + responseWriter: responseWriter, + closeFuture: closeFuture, + services: services, + encoding: encoding, + normalizeHeaders: normalizeHeaders + ) + self = stateAndAction.state + return stateAndAction.action + + // We can't receive headers in any of these states. + case .requestOpenResponseIdle, + .requestOpenResponseOpen, + .requestOpenResponseClosed, + .requestClosedResponseIdle, + .requestClosedResponseOpen: + preconditionFailure("Invalid state: \(self)") + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + /// Receive a buffer from the client. + mutating func receive( + buffer: inout ByteBuffer, + endStream: Bool + ) -> HTTP2ToRawGRPCStateMachine.ReceiveDataAction { + switch self { + case .requestIdleResponseIdle: + /// This isn't allowed: we must receive the request headers first. + preconditionFailure("Invalid state") + + case var .requestOpenResponseIdle(state): + let stateAndAction = state.receive(buffer: &buffer, endStream: endStream) + self = stateAndAction.state + return stateAndAction.action + + case var .requestOpenResponseOpen(state): + let stateAndAction = state.receive(buffer: &buffer, endStream: endStream) + self = stateAndAction.state + return stateAndAction.action + + case .requestClosedResponseIdle, + .requestClosedResponseOpen: + preconditionFailure("Invalid state: the request stream is already closed") + + case .requestOpenResponseClosed: + if endStream { + // Server has finish responding and this is the end of the request stream; we're done for + // this RPC now, finish the handler. + self = .requestClosedResponseClosed + return .finishHandler + } else { + // Server has finished responding but this isn't the end of the request stream; ignore the + // input, we need to wait for end stream before tearing down the handler. + return .nothing + } + + case .requestClosedResponseClosed: + return .nothing + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + mutating func readNextRequest( + maxLength: Int + ) -> HTTP2ToRawGRPCStateMachine.ReadNextMessageAction { + switch self { + case .requestIdleResponseIdle: + preconditionFailure("Invalid state") + + case var .requestOpenResponseIdle(state): + let action = state.readNextRequest(maxLength: maxLength) + self = .requestOpenResponseIdle(state) + return action + + case var .requestOpenResponseOpen(state): + let action = state.readNextRequest(maxLength: maxLength) + self = .requestOpenResponseOpen(state) + return action + + case var .requestClosedResponseIdle(state): + let action = state.readNextRequest(maxLength: maxLength) + self = .requestClosedResponseIdle(state) + return action + + case var .requestClosedResponseOpen(state): + let action = state.readNextRequest(maxLength: maxLength) + self = .requestClosedResponseOpen(state) + return action + + case .requestOpenResponseClosed, + .requestClosedResponseClosed: + return .none + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + mutating func send(headers: HPACKHeaders) -> Result { + switch self { + case .requestIdleResponseIdle: + preconditionFailure("Invalid state: the request stream isn't open") + + case let .requestOpenResponseIdle(state): + let headers = state.send(headers: headers) + self = .requestOpenResponseOpen(.init(from: state)) + return .success(headers) + + case let .requestClosedResponseIdle(state): + let headers = state.send(headers: headers) + self = .requestClosedResponseOpen(.init(from: state)) + return .success(headers) + + case .requestOpenResponseOpen, + .requestOpenResponseClosed, + .requestClosedResponseOpen, + .requestClosedResponseClosed: + return .failure(GRPCError.AlreadyComplete()) + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + func send( + buffer: ByteBuffer, + allocator: ByteBufferAllocator, + compress: Bool + ) -> Result { + switch self { + case .requestIdleResponseIdle: + preconditionFailure("Invalid state: the request stream is still closed") + + case .requestOpenResponseIdle, + .requestClosedResponseIdle: + let error = GRPCError.InvalidState("Response headers must be sent before response message") + return .failure(error) + + case let .requestOpenResponseOpen(state): + return state.send( + buffer: buffer, + allocator: allocator, + compress: compress + ) + + case let .requestClosedResponseOpen(state): + return state.send( + buffer: buffer, + allocator: allocator, + compress: compress + ) + + case .requestOpenResponseClosed, + .requestClosedResponseClosed: + return .failure(GRPCError.AlreadyComplete()) + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } + + mutating func send( + status: GRPCStatus, + trailers: HPACKHeaders + ) -> HTTP2ToRawGRPCStateMachine.SendEndAction { + switch self { + case .requestIdleResponseIdle: + preconditionFailure("Invalid state: the request stream is still closed") + + case let .requestOpenResponseIdle(state): + self = .requestOpenResponseClosed + return .sendTrailers(state.send(status: status, trailers: trailers)) + + case let .requestClosedResponseIdle(state): + self = .requestClosedResponseClosed + return .sendTrailersAndFinish(state.send(status: status, trailers: trailers)) + + case let .requestOpenResponseOpen(state): + self = .requestOpenResponseClosed + return .sendTrailers(state.send(status: status, trailers: trailers)) + + case let .requestClosedResponseOpen(state): + self = .requestClosedResponseClosed + return .sendTrailersAndFinish(state.send(status: status, trailers: trailers)) + + case .requestOpenResponseClosed, + .requestClosedResponseClosed: + return .failure(GRPCError.AlreadyComplete()) + + case ._modifying: + preconditionFailure("Left in modifying state") + } + } +} + +// MARK: - Helpers + +extension HTTP2ToRawGRPCStateMachine { + static func makeResponseHeaders( + contentType: ContentType, + responseEncoding: String?, + acceptableRequestEncoding: String?, + userProvidedHeaders: HPACKHeaders, + normalizeUserProvidedHeaders: Bool + ) -> HPACKHeaders { + // 4 because ':status' and 'content-type' are required. We may send back 'grpc-encoding' and + // 'grpc-accept-encoding' as well. + let capacity = 4 + userProvidedHeaders.count + + var headers = HPACKHeaders() + headers.reserveCapacity(capacity) + + headers.add(name: ":status", value: "200") + headers.add(name: GRPCHeaderName.contentType, value: contentType.canonicalValue) + + if let responseEncoding = responseEncoding { + headers.add(name: GRPCHeaderName.encoding, value: responseEncoding) + } + + if let acceptEncoding = acceptableRequestEncoding { + headers.add(name: GRPCHeaderName.acceptEncoding, value: acceptEncoding) + } + + // Add user provided headers, normalizing if required. + headers.add(contentsOf: userProvidedHeaders, normalize: normalizeUserProvidedHeaders) + + return headers + } + + static func makeResponseTrailersOnly( + for status: GRPCStatus, + contentType: ContentType, + acceptableRequestEncoding: String?, + userProvidedHeaders: HPACKHeaders?, + normalizeUserProvidedHeaders: Bool + ) -> HPACKHeaders { + // 5 because ':status', 'content-type', 'grpc-status' are required. We may also send back + // 'grpc-message' and 'grpc-accept-encoding'. + let capacity = 5 + (userProvidedHeaders.map { $0.count } ?? 0) + + var headers = HPACKHeaders() + headers.reserveCapacity(capacity) + + // Add the required trailers. + headers.add(name: ":status", value: "200") + headers.add(name: GRPCHeaderName.contentType, value: contentType.canonicalValue) + headers.add(name: GRPCHeaderName.statusCode, value: String(describing: status.code.rawValue)) + + if let message = status.message.flatMap(GRPCStatusMessageMarshaller.marshall) { + headers.add(name: GRPCHeaderName.statusMessage, value: message) + } + + // We may include this if the requested encoding was not valid. + if let acceptEncoding = acceptableRequestEncoding { + headers.add(name: GRPCHeaderName.acceptEncoding, value: acceptEncoding) + } + + if let userProvided = userProvidedHeaders { + headers.add(contentsOf: userProvided, normalize: normalizeUserProvidedHeaders) + } + + return headers + } + + static func makeResponseTrailers( + for status: GRPCStatus, + userProvidedHeaders: HPACKHeaders, + normalizeUserProvidedHeaders: Bool + ) -> HPACKHeaders { + // Most RPCs should end with status code 'ok' (hopefully!), and if the user didn't provide any + // additional trailers, then we can use a pre-canned set of headers to avoid an extra + // allocation. + if status == .ok, userProvidedHeaders.isEmpty { + return Self.gRPCStatusOkTrailers + } + + // 2 because 'grpc-status' is required, we may also send back 'grpc-message'. + let capacity = 2 + userProvidedHeaders.count + + var trailers = HPACKHeaders() + trailers.reserveCapacity(capacity) + + // status code. + trailers.add(name: GRPCHeaderName.statusCode, value: String(describing: status.code.rawValue)) + + // status message, if present. + if let message = status.message.flatMap(GRPCStatusMessageMarshaller.marshall) { + trailers.add(name: GRPCHeaderName.statusMessage, value: message) + } + + // user provided trailers. + trailers.add(contentsOf: userProvidedHeaders, normalize: normalizeUserProvidedHeaders) + + return trailers + } + + private static let gRPCStatusOkTrailers: HPACKHeaders = [ + GRPCHeaderName.statusCode: String(describing: GRPCStatus.Code.ok.rawValue), + ] +} + +extension HPACKHeaders { + fileprivate mutating func add(contentsOf other: HPACKHeaders, normalize: Bool) { + if normalize { + self.add(contentsOf: other.lazy.map { name, value, indexable in + (name: name.lowercased(), value: value, indexable: indexable) + }) + } else { + self.add(contentsOf: other) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorContext.swift new file mode 100644 index 00000000..9efc9e7d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorContext.swift @@ -0,0 +1,114 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +public struct ClientInterceptorContext { + /// The interceptor this context is for. + @usableFromInline + internal let interceptor: ClientInterceptor + + /// The pipeline this context is associated with. + @usableFromInline + internal let _pipeline: ClientInterceptorPipeline + + /// The index of this context's interceptor within the pipeline. + @usableFromInline + internal let _index: Int + + /// The `EventLoop` this interceptor pipeline is being executed on. + public var eventLoop: EventLoop { + return self._pipeline.eventLoop + } + + /// A logger. + public var logger: Logger { + return self._pipeline.logger.unwrapped + } + + /// The type of the RPC, e.g. "unary". + public var type: GRPCCallType { + return self._pipeline.details.type + } + + /// The path of the RPC in the format "/Service/Method", e.g. "/echo.Echo/Get". + public var path: String { + return self._pipeline.details.path + } + + /// The options used to invoke the call. + public var options: CallOptions { + return self._pipeline.details.options + } + + /// Construct a `ClientInterceptorContext` for the interceptor at the given index within in + /// interceptor pipeline. + @inlinable + internal init( + for interceptor: ClientInterceptor, + atIndex index: Int, + in pipeline: ClientInterceptorPipeline + ) { + self.interceptor = interceptor + self._pipeline = pipeline + self._index = index + } + + /// Forwards the response part to the next inbound interceptor in the pipeline, if there is one. + /// + /// - Parameter part: The response part to forward. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func receive(_ part: GRPCClientResponsePart) { + self.eventLoop.assertInEventLoop() + self._pipeline.invokeReceive(part, fromContextAtIndex: self._index) + } + + /// Forwards the error to the next inbound interceptor in the pipeline, if there is one. + /// + /// - Parameter error: The error to forward. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func errorCaught(_ error: Error) { + self.eventLoop.assertInEventLoop() + self._pipeline.invokeErrorCaught(error, fromContextAtIndex: self._index) + } + + /// Forwards the request part to the next outbound interceptor in the pipeline, if there is one. + /// + /// - Parameters: + /// - part: The request part to forward. + /// - promise: The promise the complete when the part has been written. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func send( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise? + ) { + self.eventLoop.assertInEventLoop() + self._pipeline.invokeSend(part, promise: promise, fromContextAtIndex: self._index) + } + + /// Forwards a request to cancel the RPC to the next outbound interceptor in the pipeline. + /// + /// - Parameter promise: The promise to complete with the outcome of the cancellation request. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func cancel(promise: EventLoopPromise?) { + self.eventLoop.assertInEventLoop() + self._pipeline.invokeCancel(promise: promise, fromContextAtIndex: self._index) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorPipeline.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorPipeline.swift new file mode 100644 index 00000000..37de2a92 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorPipeline.swift @@ -0,0 +1,514 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +/// A pipeline for intercepting client request and response streams. +/// +/// The interceptor pipeline lies between the call object (`UnaryCall`, `ClientStreamingCall`, etc.) +/// and the transport used to send and receive messages from the server (a `NIO.Channel`). It holds +/// a collection of interceptors which may be used to observe or alter messages as the travel +/// through the pipeline. +/// +/// ``` +/// ┌───────────────────────────────────────────────────────────────────┐ +/// │ Call │ +/// └────────────────────────────────────────────────────────┬──────────┘ +/// │ send(_:promise) / +/// │ cancel(promise:) +/// ┌────────────────────────────────────────────────────────▼──────────┐ +/// │ InterceptorPipeline ╎ │ +/// │ ╎ │ +/// │ ┌──────────────────────────────────────────────────────▼────────┐ │ +/// │ │ Tail Interceptor (hands response parts to a callback) │ │ +/// │ └────────▲─────────────────────────────────────────────┬────────┘ │ +/// │ ┌────────┴─────────────────────────────────────────────▼────────┐ │ +/// │ │ Interceptor 1 │ │ +/// │ └────────▲─────────────────────────────────────────────┬────────┘ │ +/// │ ┌────────┴─────────────────────────────────────────────▼────────┐ │ +/// │ │ Interceptor 2 │ │ +/// │ └────────▲─────────────────────────────────────────────┬────────┘ │ +/// │ ╎ ╎ │ +/// │ ╎ (More interceptors) ╎ │ +/// │ ╎ ╎ │ +/// │ ┌────────┴─────────────────────────────────────────────▼────────┐ │ +/// │ │ Head Interceptor (interacts with transport) │ │ +/// │ └────────▲─────────────────────────────────────────────┬────────┘ │ +/// │ ╎ receive(_:) │ │ +/// └──────────▲─────────────────────────────────────────────┼──────────┘ +/// │ receive(_:) │ send(_:promise:) / +/// │ │ cancel(promise:) +/// ┌──────────┴─────────────────────────────────────────────▼──────────┐ +/// │ ClientTransport │ +/// │ (a NIO.ChannelHandler) │ +/// ``` +@usableFromInline +internal final class ClientInterceptorPipeline { + /// A logger. + @usableFromInline + internal var logger: GRPCLogger + + /// The `EventLoop` this RPC is being executed on. + @usableFromInline + internal let eventLoop: EventLoop + + /// The details of the call. + @usableFromInline + internal let details: CallDetails + + /// A task for closing the RPC in case of a timeout. + @usableFromInline + internal var _scheduledClose: Scheduled? + + @usableFromInline + internal let _errorDelegate: ClientErrorDelegate? + + @usableFromInline + internal private(set) var _onError: ((Error) -> Void)? + + @usableFromInline + internal private(set) var _onCancel: ((EventLoopPromise?) -> Void)? + + @usableFromInline + internal private(set) var _onRequestPart: + ((GRPCClientRequestPart, EventLoopPromise?) -> Void)? + + @usableFromInline + internal private(set) var _onResponsePart: ((GRPCClientResponsePart) -> Void)? + + /// The index after the last user interceptor context index. (i.e. `_userContexts.endIndex`). + @usableFromInline + internal let _headIndex: Int + + /// The index before the first user interceptor context index (always -1). + @usableFromInline + internal let _tailIndex: Int + + @usableFromInline + internal var _userContexts: [ClientInterceptorContext] + + /// Whether the interceptor pipeline is still open. It becomes closed after an 'end' response + /// part has traversed the pipeline. + @usableFromInline + internal var _isOpen = true + + /// The index of the next context on the inbound side of the context at the given index. + @inlinable + internal func _nextInboundIndex(after index: Int) -> Int { + // Unchecked arithmetic is okay here: our smallest inbound index is '_tailIndex' but we will + // never ask for the inbound index after the tail. + assert(self._indexIsValid(index)) + return index &- 1 + } + + /// The index of the next context on the outbound side of the context at the given index. + @inlinable + internal func _nextOutboundIndex(after index: Int) -> Int { + // Unchecked arithmetic is okay here: our greatest outbound index is '_headIndex' but we will + // never ask for the outbound index after the head. + assert(self._indexIsValid(index)) + return index &+ 1 + } + + /// Returns true of the index is in the range `_tailIndex ... _headIndex`. + @inlinable + internal func _indexIsValid(_ index: Int) -> Bool { + return index >= self._tailIndex && index <= self._headIndex + } + + @inlinable + internal init( + eventLoop: EventLoop, + details: CallDetails, + logger: GRPCLogger, + interceptors: [ClientInterceptor], + errorDelegate: ClientErrorDelegate?, + onError: @escaping (Error) -> Void, + onCancel: @escaping (EventLoopPromise?) -> Void, + onRequestPart: @escaping (GRPCClientRequestPart, EventLoopPromise?) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.eventLoop = eventLoop + self.details = details + self.logger = logger + + self._errorDelegate = errorDelegate + self._onError = onError + self._onCancel = onCancel + self._onRequestPart = onRequestPart + self._onResponsePart = onResponsePart + + // The tail is before the interceptors. + self._tailIndex = -1 + // The head is after the interceptors. + self._headIndex = interceptors.endIndex + + // Make some contexts. + self._userContexts = [] + self._userContexts.reserveCapacity(interceptors.count) + + for index in 0 ..< interceptors.count { + let context = ClientInterceptorContext(for: interceptors[index], atIndex: index, in: self) + self._userContexts.append(context) + } + + self._setupDeadline() + } + + /// Emit a response part message into the interceptor pipeline. + /// + /// This should be called by the transport layer when receiving a response part from the server. + /// + /// - Parameter part: The part to emit into the pipeline. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func receive(_ part: GRPCClientResponsePart) { + self.invokeReceive(part, fromContextAtIndex: self._headIndex) + } + + /// Invoke receive on the appropriate context when called from the context at the given index. + @inlinable + internal func invokeReceive( + _ part: GRPCClientResponsePart, + fromContextAtIndex index: Int + ) { + self._invokeReceive(part, onContextAtIndex: self._nextInboundIndex(after: index)) + } + + /// Invoke receive on the context at the given index, if doing so is safe. + @inlinable + internal func _invokeReceive( + _ part: GRPCClientResponsePart, + onContextAtIndex index: Int + ) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + return + } + + self._invokeReceive(part, onContextAtUncheckedIndex: index) + } + + /// Invoke receive on the context at the given index, assuming that the index is valid and the + /// pipeline is still open. + @inlinable + internal func _invokeReceive( + _ part: GRPCClientResponsePart, + onContextAtUncheckedIndex index: Int + ) { + switch index { + case self._headIndex: + self._invokeReceive(part, onContextAtUncheckedIndex: self._nextInboundIndex(after: index)) + + case self._tailIndex: + if part.isEnd { + // Update our state before handling the response part. + self._isOpen = false + self._onResponsePart?(part) + self.close() + } else { + self._onResponsePart?(part) + } + + default: + self._userContexts[index].invokeReceive(part) + } + } + + /// Emit an error into the interceptor pipeline. + /// + /// This should be called by the transport layer when receiving an error. + /// + /// - Parameter error: The error to emit. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func errorCaught(_ error: Error) { + self.invokeErrorCaught(error, fromContextAtIndex: self._headIndex) + } + + /// Invoke `errorCaught` on the appropriate context when called from the context at the given + /// index. + @inlinable + internal func invokeErrorCaught(_ error: Error, fromContextAtIndex index: Int) { + self._invokeErrorCaught(error, onContextAtIndex: self._nextInboundIndex(after: index)) + } + + /// Invoke `errorCaught` on the context at the given index if that index exists and the pipeline + /// is still open. + @inlinable + internal func _invokeErrorCaught(_ error: Error, onContextAtIndex index: Int) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + return + } + self._invokeErrorCaught(error, onContextAtUncheckedIndex: index) + } + + /// Invoke `errorCaught` on the context at the given index assuming the index exists and the + /// pipeline is still open. + @inlinable + internal func _invokeErrorCaught(_ error: Error, onContextAtUncheckedIndex index: Int) { + switch index { + case self._headIndex: + self._invokeErrorCaught(error, onContextAtIndex: self._nextInboundIndex(after: index)) + + case self._tailIndex: + self._errorCaught(error) + + default: + self._userContexts[index].invokeErrorCaught(error) + } + } + + /// Handles a caught error which has traversed the interceptor pipeline. + @usableFromInline + internal func _errorCaught(_ error: Error) { + // We're about to call out to an error handler: update our state first. + self._isOpen = false + var unwrappedError: Error + + // Unwrap the error, if possible. + if let errorContext = error as? GRPCError.WithContext { + unwrappedError = errorContext.error + self._errorDelegate?.didCatchError( + errorContext.error, + logger: self.logger.unwrapped, + file: errorContext.file, + line: errorContext.line + ) + } else { + unwrappedError = error + self._errorDelegate?.didCatchErrorWithoutContext(error, logger: self.logger.unwrapped) + } + + // Emit the unwrapped error. + self._onError?(unwrappedError) + + // Close the pipeline. + self.close() + } + + /// Writes a request message into the interceptor pipeline. + /// + /// This should be called by the call object to send requests parts to the transport. + /// + /// - Parameters: + /// - part: The request part to write. + /// - promise: A promise to complete when the request part has been successfully written. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func send(_ part: GRPCClientRequestPart, promise: EventLoopPromise?) { + self.invokeSend(part, promise: promise, fromContextAtIndex: self._tailIndex) + } + + /// Invoke send on the appropriate context when called from the context at the given index. + @inlinable + internal func invokeSend( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + fromContextAtIndex index: Int + ) { + self._invokeSend( + part, + promise: promise, + onContextAtIndex: self._nextOutboundIndex(after: index) + ) + } + + /// Invoke send on the context at the given index, if it exists and the pipeline is still open. + @inlinable + internal func _invokeSend( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + onContextAtIndex index: Int + ) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + promise?.fail(GRPCError.AlreadyComplete()) + return + } + self._invokeSend(part, promise: promise, onContextAtUncheckedIndex: index) + } + + /// Invoke send on the context at the given index assuming the index exists and the pipeline is + /// still open. + @inlinable + internal func _invokeSend( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + onContextAtUncheckedIndex index: Int + ) { + switch index { + case self._headIndex: + self._onRequestPart?(part, promise) + + case self._tailIndex: + self._invokeSend( + part, + promise: promise, + onContextAtUncheckedIndex: self._nextOutboundIndex(after: index) + ) + + default: + self._userContexts[index].invokeSend(part, promise: promise) + } + } + + /// Send a request to cancel the RPC through the interceptor pipeline. + /// + /// This should be called by the call object when attempting to cancel the RPC. + /// + /// - Parameter promise: A promise to complete when the cancellation request has been handled. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func cancel(promise: EventLoopPromise?) { + self.invokeCancel(promise: promise, fromContextAtIndex: self._tailIndex) + } + + /// Invoke `cancel` on the appropriate context when called from the context at the given index. + @inlinable + internal func invokeCancel(promise: EventLoopPromise?, fromContextAtIndex index: Int) { + self._invokeCancel(promise: promise, onContextAtIndex: self._nextOutboundIndex(after: index)) + } + + /// Invoke `cancel` on the context at the given index if the index is valid and the pipeline is + /// still open. + @inlinable + internal func _invokeCancel( + promise: EventLoopPromise?, + onContextAtIndex index: Int + ) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + promise?.fail(GRPCError.AlreadyComplete()) + return + } + self._invokeCancel(promise: promise, onContextAtUncheckedIndex: index) + } + + /// Invoke `cancel` on the context at the given index assuming the index is valid and the + /// pipeline is still open. + @inlinable + internal func _invokeCancel( + promise: EventLoopPromise?, + onContextAtUncheckedIndex index: Int + ) { + switch index { + case self._headIndex: + self._onCancel?(promise) + + case self._tailIndex: + self._invokeCancel( + promise: promise, + onContextAtUncheckedIndex: self._nextOutboundIndex(after: index) + ) + + default: + self._userContexts[index].invokeCancel(promise: promise) + } + } +} + +// MARK: - Lifecycle + +extension ClientInterceptorPipeline { + /// Closes the pipeline. This should be called once, by the tail interceptor, to indicate that + /// the RPC has completed. If this is not called, we will leak. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func close() { + self.eventLoop.assertInEventLoop() + self._isOpen = false + + // Cancel the timeout. + self._scheduledClose?.cancel() + self._scheduledClose = nil + + // Drop the contexts since they reference us. + self._userContexts.removeAll() + + // Cancel the transport. + self._onCancel?(nil) + + // `ClientTransport` holds a reference to us and references to itself via these callbacks. Break + // these references now by replacing the callbacks. + self._onError = nil + self._onCancel = nil + self._onRequestPart = nil + self._onResponsePart = nil + } + + /// Sets up a deadline for the pipeline. + @inlinable + internal func _setupDeadline() { + func setup() { + self.eventLoop.assertInEventLoop() + + let timeLimit = self.details.options.timeLimit + let deadline = timeLimit.makeDeadline() + + // There's no point scheduling this. + if deadline == .distantFuture { + return + } + + self._scheduledClose = self.eventLoop.scheduleTask(deadline: deadline) { + // When the error hits the tail we'll call 'close()', this will cancel the transport if + // necessary. + self.errorCaught(GRPCError.RPCTimedOut(timeLimit)) + } + } + + if self.eventLoop.inEventLoop { + setup() + } else { + self.eventLoop.execute { + setup() + } + } + } +} + +extension ClientInterceptorContext { + @inlinable + internal func invokeReceive(_ part: GRPCClientResponsePart) { + self.interceptor.receive(part, context: self) + } + + @inlinable + internal func invokeSend( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise? + ) { + self.interceptor.send(part, promise: promise, context: self) + } + + @inlinable + internal func invokeCancel(promise: EventLoopPromise?) { + self.interceptor.cancel(promise: promise, context: self) + } + + @inlinable + internal func invokeErrorCaught(_ error: Error) { + self.interceptor.errorCaught(error, context: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorProtocol.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorProtocol.swift new file mode 100644 index 00000000..968d15f1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptorProtocol.swift @@ -0,0 +1,46 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +internal protocol ClientInterceptorProtocol { + associatedtype Request + associatedtype Response + + /// Called when the interceptor has received a response part to handle. + func receive( + _ part: GRPCClientResponsePart, + context: ClientInterceptorContext + ) + + /// Called when the interceptor has received an error to handle. + func errorCaught( + _ error: Error, + context: ClientInterceptorContext + ) + + /// Called when the interceptor has received a request part to handle. + func send( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) + + /// Called when the interceptor has received a request to cancel the RPC. + func cancel( + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptors.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptors.swift new file mode 100644 index 00000000..b179528e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientInterceptors.swift @@ -0,0 +1,151 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +/// A base class for client interceptors. +/// +/// Interceptors allow request and response parts to be observed, mutated or dropped as necessary. +/// The default behaviour for this base class is to forward any events to the next interceptor. +/// +/// Interceptors may observe a number of different events: +/// - receiving response parts with `receive(_:context:)`, +/// - receiving errors with `errorCaught(_:context:)`, +/// - sending request parts with `send(_:promise:context:)`, and +/// - RPC cancellation with `cancel(context:)`. +/// +/// These events flow through a pipeline of interceptors for each RPC. Request parts sent from the +/// call object (e.g. `UnaryCall`, `BidirectionalStreamingCall`) will traverse the pipeline in the +/// outbound direction from its tail via `send(_:context:)` eventually reaching the head of the +/// pipeline where it will be sent sent to the server. +/// +/// Response parts, or errors, received from the transport fill be fired in the inbound direction +/// back through the interceptor pipeline via `receive(_:context:)` and `errorCaught(_:context:)`, +/// respectively. Note that the `end` response part and any error received are terminal: the +/// pipeline will be torn down once these parts reach the the tail and are a signal that the +/// interceptor should free up any resources it may be using. +/// +/// Each of the interceptor functions is provided with a `context` which exposes analogous functions +/// (`receive(_:)`, `errorCaught(_:)`, `send(_:promise:)`, and `cancel(promise:)`) which may be +/// called to forward events to the next interceptor in the appropriate direction. +/// +/// ### Thread Safety +/// +/// Functions on `context` are not thread safe and **must** be called on the `EventLoop` found on +/// the `context`. Since each interceptor is invoked on the same `EventLoop` this does not usually +/// require any extra attention. However, if work is done on a `DispatchQueue` or _other_ +/// `EventLoop` then implementers should ensure that they use `context` from the correct +/// `EventLoop`. +#if swift(>=5.6) +@preconcurrency open class ClientInterceptor: @unchecked Sendable { + public init() {} + + /// Called when the interceptor has received a response part to handle. + /// - Parameters: + /// - part: The response part which has been received from the server. + /// - context: An interceptor context which may be used to forward the response part. + open func receive( + _ part: GRPCClientResponsePart, + context: ClientInterceptorContext + ) { + context.receive(part) + } + + /// Called when the interceptor has received an error. + /// - Parameters: + /// - error: The error. + /// - context: An interceptor context which may be used to forward the error. + open func errorCaught( + _ error: Error, + context: ClientInterceptorContext + ) { + context.errorCaught(error) + } + + /// Called when the interceptor has received a request part to handle. + /// - Parameters: + /// - part: The request part which should be sent to the server. + /// - promise: A promise which should be completed when the response part has been handled. + /// - context: An interceptor context which may be used to forward the request part. + open func send( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) { + context.send(part, promise: promise) + } + + /// Called when the interceptor has received a request to cancel the RPC. + /// - Parameters: + /// - promise: A promise which should be cancellation request has been handled. + /// - context: An interceptor context which may be used to forward the cancellation request. + open func cancel( + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) { + context.cancel(promise: promise) + } +} +#else +open class ClientInterceptor { + public init() {} + + /// Called when the interceptor has received a response part to handle. + /// - Parameters: + /// - part: The response part which has been received from the server. + /// - context: An interceptor context which may be used to forward the response part. + open func receive( + _ part: GRPCClientResponsePart, + context: ClientInterceptorContext + ) { + context.receive(part) + } + + /// Called when the interceptor has received an error. + /// - Parameters: + /// - error: The error. + /// - context: An interceptor context which may be used to forward the error. + open func errorCaught( + _ error: Error, + context: ClientInterceptorContext + ) { + context.errorCaught(error) + } + + /// Called when the interceptor has received a request part to handle. + /// - Parameters: + /// - part: The request part which should be sent to the server. + /// - promise: A promise which should be completed when the response part has been handled. + /// - context: An interceptor context which may be used to forward the request part. + open func send( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) { + context.send(part, promise: promise) + } + + /// Called when the interceptor has received a request to cancel the RPC. + /// - Parameters: + /// - promise: A promise which should be cancellation request has been handled. + /// - context: An interceptor context which may be used to forward the cancellation request. + open func cancel( + promise: EventLoopPromise?, + context: ClientInterceptorContext + ) { + context.cancel(promise: promise) + } +} +#endif // swift(>=5.6) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransport.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransport.swift new file mode 100644 index 00000000..7bef9f9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransport.swift @@ -0,0 +1,1049 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP2 + +/// This class is the glue between a `NIO.Channel` and the `ClientInterceptorPipeline`. In fact +/// this object owns the interceptor pipeline and is also a `ChannelHandler`. The caller has very +/// little API to use on this class: they may configure the transport by adding it to a +/// `NIO.ChannelPipeline` with `configure(_:)`, send request parts via `send(_:promise:)` and +/// attempt to cancel the RPC with `cancel(promise:)`. Response parts – after traversing the +/// interceptor pipeline – are emitted to the `onResponsePart` callback supplied to the initializer. +/// +/// In most instances the glue code is simple: transformations are applied to the request and +/// response types used by the interceptor pipeline and the `NIO.Channel`. In addition, the +/// transport keeps track of the state of the call and the `Channel`, taking appropriate action +/// when these change. This includes buffering request parts from the interceptor pipeline until +/// the `NIO.Channel` becomes active. +/// +/// ### Thread Safety +/// +/// This class is not thread safe. All methods **must** be executed on the transport's `callEventLoop`. +@usableFromInline +internal final class ClientTransport { + /// The `EventLoop` the call is running on. State must be accessed from this event loop. + @usableFromInline + internal let callEventLoop: EventLoop + + /// The current state of the transport. + private var state: ClientTransportState = .idle + + /// A promise for the underlying `Channel`. We'll succeed this when we transition to `active` + /// and fail it when we transition to `closed`. + private var channelPromise: EventLoopPromise? + + // Note: initial capacity is 4 because it's a power of 2 and most calls are unary so will + // have 3 parts. + /// A buffer to store request parts and promises in before the channel has become active. + private var writeBuffer = MarkedCircularBuffer(initialCapacity: 4) + + /// The request serializer. + private let serializer: AnySerializer + + /// The response deserializer. + private let deserializer: AnyDeserializer + + /// A request part and a promise. + private struct RequestAndPromise { + var request: GRPCClientRequestPart + var promise: EventLoopPromise? + } + + /// Details about the call. + internal let callDetails: CallDetails + + /// A logger. + internal var logger: GRPCLogger + + /// Is the call streaming requests? + private var isStreamingRequests: Bool { + switch self.callDetails.type { + case .unary, .serverStreaming: + return false + case .clientStreaming, .bidirectionalStreaming: + return true + } + } + + // Our `NIO.Channel` will fire trailers and the `GRPCStatus` to us separately. It's more + // convenient to have both at the same time when intercepting response parts. We'll hold on to the + // trailers here and only forward them when we receive the status. + private var trailers: HPACKHeaders? + + /// The interceptor pipeline connected to this transport. The pipeline also holds references + /// to `self` which are dropped when the interceptor pipeline is closed. + @usableFromInline + internal var _pipeline: ClientInterceptorPipeline? + + /// The `NIO.Channel` used by the transport, if it is available. + private var channel: Channel? + + /// A callback which is invoked once when the stream channel becomes active. + private let onStart: () -> Void + + /// Our current state as logging metadata. + private var stateForLogging: Logger.MetadataValue { + if self.state.mayBuffer { + return "\(self.state) (\(self.writeBuffer.count) parts buffered)" + } else { + return "\(self.state)" + } + } + + internal init( + details: CallDetails, + eventLoop: EventLoop, + interceptors: [ClientInterceptor], + serializer: AnySerializer, + deserializer: AnyDeserializer, + errorDelegate: ClientErrorDelegate?, + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) { + self.callEventLoop = eventLoop + self.callDetails = details + self.onStart = onStart + let logger = GRPCLogger(wrapping: details.options.logger) + self.logger = logger + self.serializer = serializer + self.deserializer = deserializer + // The references to self held by the pipeline are dropped when it is closed. + self._pipeline = ClientInterceptorPipeline( + eventLoop: eventLoop, + details: details, + logger: logger, + interceptors: interceptors, + errorDelegate: errorDelegate, + onError: onError, + onCancel: self.cancelFromPipeline(promise:), + onRequestPart: self.sendFromPipeline(_:promise:), + onResponsePart: onResponsePart + ) + } + + // MARK: - Call Object API + + /// Configure the transport to communicate with the server. + /// - Parameter configurator: A callback to invoke in order to configure this transport. + /// - Important: This *must* to be called from the `callEventLoop`. + internal func configure(_ configurator: @escaping (ChannelHandler) -> EventLoopFuture) { + self.callEventLoop.assertInEventLoop() + if self.state.configureTransport() { + self.configure(using: configurator) + } + } + + /// Send a request part – via the interceptor pipeline – to the server. + /// - Parameters: + /// - part: The part to send. + /// - promise: A promise which will be completed when the request part has been handled. + /// - Important: This *must* to be called from the `callEventLoop`. + @inlinable + internal func send(_ part: GRPCClientRequestPart, promise: EventLoopPromise?) { + self.callEventLoop.assertInEventLoop() + if let pipeline = self._pipeline { + pipeline.send(part, promise: promise) + } else { + promise?.fail(GRPCError.AlreadyComplete()) + } + } + + /// Attempt to cancel the RPC notifying any interceptors. + /// - Parameter promise: A promise which will be completed when the cancellation attempt has + /// been handled. + internal func cancel(promise: EventLoopPromise?) { + self.callEventLoop.assertInEventLoop() + if let pipeline = self._pipeline { + pipeline.cancel(promise: promise) + } else { + promise?.fail(GRPCError.AlreadyComplete()) + } + } + + /// A request for the underlying `Channel`. + internal func getChannel() -> EventLoopFuture { + self.callEventLoop.assertInEventLoop() + + // Do we already have a promise? + if let promise = self.channelPromise { + return promise.futureResult + } else { + // Make and store the promise. + let promise = self.callEventLoop.makePromise(of: Channel.self) + self.channelPromise = promise + + // Ask the state machine if we can have it. + switch self.state.getChannel() { + case .succeed: + if let channel = self.channel { + promise.succeed(channel) + } + + case .fail: + promise.fail(GRPCError.AlreadyComplete()) + + case .doNothing: + () + } + + return promise.futureResult + } + } +} + +// MARK: - Pipeline API + +extension ClientTransport { + /// Sends a request part on the transport. Should only be called from the interceptor pipeline. + /// - Parameters: + /// - part: The request part to send. + /// - promise: A promise which will be completed when the part has been handled. + /// - Important: This *must* to be called from the `callEventLoop`. + private func sendFromPipeline( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise? + ) { + self.callEventLoop.assertInEventLoop() + switch self.state.send() { + case .writeToBuffer: + self.buffer(part, promise: promise) + + case .writeToChannel: + // Banging the channel is okay here: we'll only be told to 'writeToChannel' if we're in the + // correct state, the requirements of that state are having an active `Channel`. + self.writeToChannel( + self.channel!, + part: part, + promise: promise, + flush: self.shouldFlush(after: part) + ) + + case .alreadyComplete: + promise?.fail(GRPCError.AlreadyComplete()) + } + } + + /// Attempt to cancel the RPC. Should only be called from the interceptor pipeline. + /// - Parameter promise: A promise which will be completed when the cancellation has been handled. + /// - Important: This *must* to be called from the `callEventLoop`. + private func cancelFromPipeline(promise: EventLoopPromise?) { + self.callEventLoop.assertInEventLoop() + + if self.state.cancel() { + let error = GRPCError.RPCCancelledByClient() + let status = error.makeGRPCStatus() + self.forwardToInterceptors(.end(status, [:])) + self.failBufferedWrites(with: error) + self.channel?.close(mode: .all, promise: nil) + self.channelPromise?.fail(error) + promise?.succeed(()) + } else { + promise?.succeed(()) + } + } +} + +// MARK: - ChannelHandler API + +extension ClientTransport: ChannelInboundHandler { + @usableFromInline + typealias InboundIn = _RawGRPCClientResponsePart + + @usableFromInline + typealias OutboundOut = _RawGRPCClientRequestPart + + @usableFromInline + internal func handlerRemoved(context: ChannelHandlerContext) { + self.dropReferences() + } + + @usableFromInline + internal func handlerAdded(context: ChannelHandlerContext) { + if context.channel.isActive { + self.transportActivated(channel: context.channel) + } + } + + @usableFromInline + internal func errorCaught(context: ChannelHandlerContext, error: Error) { + self.handleError(error) + } + + @usableFromInline + internal func channelActive(context: ChannelHandlerContext) { + self.transportActivated(channel: context.channel) + } + + @usableFromInline + internal func channelInactive(context: ChannelHandlerContext) { + self.transportDeactivated() + } + + @usableFromInline + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + switch self.unwrapInboundIn(data) { + case let .initialMetadata(headers): + self.receiveFromChannel(initialMetadata: headers) + + case let .message(box): + self.receiveFromChannel(message: box.message) + + case let .trailingMetadata(trailers): + self.receiveFromChannel(trailingMetadata: trailers) + + case let .status(status): + self.receiveFromChannel(status: status) + } + + // (We're the end of the channel. No need to forward anything.) + } +} + +extension ClientTransport { + /// The `Channel` became active. Send out any buffered requests. + private func transportActivated(channel: Channel) { + if self.callEventLoop.inEventLoop { + self._transportActivated(channel: channel) + } else { + self.callEventLoop.execute { + self._transportActivated(channel: channel) + } + } + } + + /// On-loop implementation of `transportActivated(channel:)`. + private func _transportActivated(channel: Channel) { + self.callEventLoop.assertInEventLoop() + + switch self.state.activate() { + case .unbuffer: + self.logger.addIPAddressMetadata(local: channel.localAddress, remote: channel.remoteAddress) + self._pipeline?.logger = self.logger + self.logger.debug("activated stream channel") + self.channel = channel + self.onStart() + self.unbuffer() + + case .close: + channel.close(mode: .all, promise: nil) + + case .doNothing: + () + } + } + + /// The `Channel` became inactive. Fail any buffered writes and forward an error to the + /// interceptor pipeline if necessary. + private func transportDeactivated() { + if self.callEventLoop.inEventLoop { + self._transportDeactivated() + } else { + self.callEventLoop.execute { + self._transportDeactivated() + } + } + } + + /// On-loop implementation of `transportDeactivated()`. + private func _transportDeactivated() { + self.callEventLoop.assertInEventLoop() + switch self.state.deactivate() { + case .doNothing: + () + + case .tearDown: + let status = GRPCStatus(code: .unavailable, message: "Transport became inactive") + self.forwardErrorToInterceptors(status) + self.failBufferedWrites(with: status) + self.channelPromise?.fail(status) + + case .failChannelPromise: + self.channelPromise?.fail(GRPCError.AlreadyComplete()) + } + } + + /// Drops any references to the `Channel` and interceptor pipeline. + private func dropReferences() { + if self.callEventLoop.inEventLoop { + self.channel = nil + } else { + self.callEventLoop.execute { + self.channel = nil + } + } + } + + /// Handles an error caught in the pipeline or from elsewhere. The error may be forwarded to the + /// interceptor pipeline and any buffered writes will be failed. Any underlying `Channel` will + /// also be closed. + internal func handleError(_ error: Error) { + if self.callEventLoop.inEventLoop { + self._handleError(error) + } else { + self.callEventLoop.execute { + self._handleError(error) + } + } + } + + /// On-loop implementation of `handleError(_:)`. + private func _handleError(_ error: Error) { + self.callEventLoop.assertInEventLoop() + + switch self.state.handleError() { + case .doNothing: + () + + case .propagateError: + self.forwardErrorToInterceptors(error) + self.failBufferedWrites(with: error) + + case .propagateErrorAndClose: + self.forwardErrorToInterceptors(error) + self.failBufferedWrites(with: error) + self.channel?.close(mode: .all, promise: nil) + } + } + + /// Receive initial metadata from the `Channel`. + private func receiveFromChannel(initialMetadata headers: HPACKHeaders) { + if self.callEventLoop.inEventLoop { + self._receiveFromChannel(initialMetadata: headers) + } else { + self.callEventLoop.execute { + self._receiveFromChannel(initialMetadata: headers) + } + } + } + + /// On-loop implementation of `receiveFromChannel(initialMetadata:)`. + private func _receiveFromChannel(initialMetadata headers: HPACKHeaders) { + self.callEventLoop.assertInEventLoop() + if self.state.channelRead(isEnd: false) { + self.forwardToInterceptors(.metadata(headers)) + } + } + + /// Receive response message bytes from the `Channel`. + private func receiveFromChannel(message buffer: ByteBuffer) { + if self.callEventLoop.inEventLoop { + self._receiveFromChannel(message: buffer) + } else { + self.callEventLoop.execute { + self._receiveFromChannel(message: buffer) + } + } + } + + /// On-loop implementation of `receiveFromChannel(message:)`. + private func _receiveFromChannel(message buffer: ByteBuffer) { + self.callEventLoop.assertInEventLoop() + do { + let message = try self.deserializer.deserialize(byteBuffer: buffer) + if self.state.channelRead(isEnd: false) { + self.forwardToInterceptors(.message(message)) + } + } catch { + self.handleError(error) + } + } + + /// Receive trailing metadata from the `Channel`. + private func receiveFromChannel(trailingMetadata trailers: HPACKHeaders) { + // The `Channel` delivers trailers and `GRPCStatus` separately, we want to emit them together + // in the interceptor pipeline. + if self.callEventLoop.inEventLoop { + self.trailers = trailers + } else { + self.callEventLoop.execute { + self.trailers = trailers + } + } + } + + /// Receive the final status from the `Channel`. + private func receiveFromChannel(status: GRPCStatus) { + if self.callEventLoop.inEventLoop { + self._receiveFromChannel(status: status) + } else { + self.callEventLoop.execute { + self._receiveFromChannel(status: status) + } + } + } + + /// On-loop implementation of `receiveFromChannel(status:)`. + private func _receiveFromChannel(status: GRPCStatus) { + self.callEventLoop.assertInEventLoop() + if self.state.channelRead(isEnd: true) { + self.forwardToInterceptors(.end(status, self.trailers ?? [:])) + self.trailers = nil + } + } +} + +// MARK: - State Handling + +private enum ClientTransportState { + /// Idle. We're waiting for the RPC to be configured. + /// + /// Valid transitions: + /// - `awaitingTransport` (the transport is being configured) + /// - `closed` (the RPC cancels) + case idle + + /// Awaiting transport. The RPC has requested transport and we're waiting for that transport to + /// activate. We'll buffer any outbound messages from this state. Receiving messages from the + /// transport in this state is an error. + /// + /// Valid transitions: + /// - `activatingTransport` (the channel becomes active) + /// - `closing` (the RPC cancels) + /// - `closed` (the channel fails to become active) + case awaitingTransport + + /// The transport is active but we're unbuffering any requests to write on that transport. + /// We'll continue buffering in this state. Receiving messages from the transport in this state + /// is okay. + /// + /// Valid transitions: + /// - `active` (we finish unbuffering) + /// - `closing` (the RPC cancels, the channel encounters an error) + /// - `closed` (the channel becomes inactive) + case activatingTransport + + /// Fully active. An RPC is in progress and is communicating over an active transport. + /// + /// Valid transitions: + /// - `closing` (the RPC cancels, the channel encounters an error) + /// - `closed` (the channel becomes inactive) + case active + + /// Closing. Either the RPC was cancelled or any `Channel` associated with the transport hasn't + /// become inactive yet. + /// + /// Valid transitions: + /// - `closed` (the channel becomes inactive) + case closing + + /// We're closed. Any writes from the RPC will be failed. Any responses from the transport will + /// be ignored. + /// + /// Valid transitions: + /// - none: this state is terminal. + case closed + + /// Whether writes may be unbuffered in this state. + internal var isUnbuffering: Bool { + switch self { + case .activatingTransport: + return true + case .idle, .awaitingTransport, .active, .closing, .closed: + return false + } + } + + /// Whether this state allows writes to be buffered. (This is useful only to inform logging.) + internal var mayBuffer: Bool { + switch self { + case .idle, .activatingTransport, .awaitingTransport: + return true + case .active, .closing, .closed: + return false + } + } +} + +extension ClientTransportState { + /// The caller would like to configure the transport. Returns a boolean indicating whether we + /// should configure it or not. + mutating func configureTransport() -> Bool { + switch self { + // We're idle until we configure. Anything else is just a repeat request to configure. + case .idle: + self = .awaitingTransport + return true + + case .awaitingTransport, .activatingTransport, .active, .closing, .closed: + return false + } + } + + enum SendAction { + /// Write the request into the buffer. + case writeToBuffer + /// Write the request into the channel. + case writeToChannel + /// The RPC has already completed, fail any promise associated with the write. + case alreadyComplete + } + + /// The pipeline would like to send a request part to the transport. + mutating func send() -> SendAction { + switch self { + // We don't have any transport yet, just buffer the part. + case .idle, .awaitingTransport, .activatingTransport: + return .writeToBuffer + + // We have a `Channel`, we can pipe the write straight through. + case .active: + return .writeToChannel + + // The transport is going or has gone away. Fail the promise. + case .closing, .closed: + return .alreadyComplete + } + } + + enum UnbufferedAction { + /// Nothing needs to be done. + case doNothing + /// Succeed the channel promise associated with the transport. + case succeedChannelPromise + } + + /// We finished dealing with the buffered writes. + mutating func unbuffered() -> UnbufferedAction { + switch self { + // These can't happen since we only begin unbuffering when we transition to + // '.activatingTransport', which must come after these two states.. + case .idle, .awaitingTransport: + preconditionFailure("Requests can't be unbuffered before the transport is activated") + + // We dealt with any buffered writes. We can become active now. This is the only way to become + // active. + case .activatingTransport: + self = .active + return .succeedChannelPromise + + case .active: + preconditionFailure("Unbuffering completed but the transport is already active") + + // Something caused us to close while unbuffering, that's okay, we won't take any further + // action. + case .closing, .closed: + return .doNothing + } + } + + /// Cancel the RPC and associated `Channel`, if possible. Returns a boolean indicated whether + /// cancellation can go ahead (and also whether the channel should be torn down). + mutating func cancel() -> Bool { + switch self { + case .idle: + // No RPC has been started and we don't have a `Channel`. We need to tell the interceptor + // we're done, fail any writes, and then deal with the cancellation promise. + self = .closed + return true + + case .awaitingTransport: + // An RPC has started and we're waiting for the `Channel` to activate. We'll mark ourselves as + // closing. We don't need to explicitly close the `Channel`, this will happen as a result of + // the `Channel` becoming active (see `channelActive(context:)`). + self = .closing + return true + + case .activatingTransport: + // The RPC has started, the `Channel` is active and we're emptying our write buffer. We'll + // mark ourselves as closing: we'll error the interceptor pipeline, close the channel, fail + // any buffered writes and then complete the cancellation promise. + self = .closing + return true + + case .active: + // The RPC and channel are up and running. We'll fail the RPC and close the channel. + self = .closing + return true + + case .closing, .closed: + // We're already closing or closing. The cancellation is too late. + return false + } + } + + enum ActivateAction { + case unbuffer + case close + case doNothing + } + + /// `channelActive` was invoked on the transport by the `Channel`. + mutating func activate() -> ActivateAction { + // The channel has become active: what now? + switch self { + case .idle: + preconditionFailure("Can't activate an idle transport") + + case .awaitingTransport: + self = .activatingTransport + return .unbuffer + + case .activatingTransport, .active: + // Already activated. + return .doNothing + + case .closing: + // We remain in closing: we only transition to closed on 'channelInactive'. + return .close + + case .closed: + preconditionFailure("Invalid state: stream is already inactive") + } + } + + enum ChannelInactiveAction { + /// Tear down the transport; forward an error to the interceptors and fail any buffered writes. + case tearDown + /// Fail the 'Channel' promise, if one exists; the RPC is already complete. + case failChannelPromise + /// Do nothing. + case doNothing + } + + /// `channelInactive` was invoked on the transport by the `Channel`. + mutating func deactivate() -> ChannelInactiveAction { + switch self { + case .idle: + // We can't become inactive before we've requested a `Channel`. + preconditionFailure("Can't deactivate an idle transport") + + case .awaitingTransport, .activatingTransport, .active: + // We're activating the transport - i.e. offloading any buffered requests - and the channel + // became inactive. We haven't received an error (otherwise we'd be `closing`) so we should + // synthesize an error status to fail the RPC with. + self = .closed + return .tearDown + + case .closing: + // We were already closing, now we're fully closed. + self = .closed + return .failChannelPromise + + case .closed: + // We're already closed. + return .doNothing + } + } + + /// `channelRead` was invoked on the transport by the `Channel`. Returns a boolean value + /// indicating whether the part that was read should be forwarded to the interceptor pipeline. + mutating func channelRead(isEnd: Bool) -> Bool { + switch self { + case .idle, .awaitingTransport: + // If there's no `Channel` or the `Channel` isn't active, then we can't read anything. + preconditionFailure("Can't receive response part on idle transport") + + case .activatingTransport, .active: + // We have an active `Channel`, we can forward the request part but we may need to start + // closing if we see the status, since it indicates the call is terminating. + if isEnd { + self = .closing + } + return true + + case .closing, .closed: + // We closed early, ignore any reads. + return false + } + } + + enum HandleErrorAction { + /// Propagate the error to the interceptor pipeline and fail any buffered writes. + case propagateError + /// As above, but close the 'Channel' as well. + case propagateErrorAndClose + /// No action is required. + case doNothing + } + + /// An error was caught. + mutating func handleError() -> HandleErrorAction { + switch self { + case .idle: + // The `Channel` can't error if it doesn't exist. + preconditionFailure("Can't catch error on idle transport") + + case .awaitingTransport: + // We're waiting for the `Channel` to become active. We're toast now, so close, failing any + // buffered writes along the way. + self = .closing + return .propagateError + + case .activatingTransport, + .active: + // We're either fully active or unbuffering. Forward an error, fail any writes and then close. + self = .closing + return .propagateErrorAndClose + + case .closing, .closed: + // We're already closing/closed, we can ignore this. + return .doNothing + } + } + + enum GetChannelAction { + /// No action is required. + case doNothing + /// Succeed the Channel promise. + case succeed + /// Fail the 'Channel' promise, the RPC is already complete. + case fail + } + + /// The caller has asked for the underlying `Channel`. + mutating func getChannel() -> GetChannelAction { + switch self { + case .idle, .awaitingTransport, .activatingTransport: + // Do nothing, we'll complete the promise when we become active or closed. + return .doNothing + + case .active: + // We're already active, so there was no promise to succeed when we made this transition. We + // can complete it now. + return .succeed + + case .closing: + // We'll complete the promise when we transition to closed. + return .doNothing + + case .closed: + // We're already closed; there was no promise to fail when we made this transition. We can go + // ahead and fail it now though. + return .fail + } + } +} + +// MARK: - State Actions + +extension ClientTransport { + /// Configures this transport with the `configurator`. + private func configure(using configurator: (ChannelHandler) -> EventLoopFuture) { + configurator(self).whenFailure { error in + // We might be on a different EL, but `handleError` will sort that out for us, so no need to + // hop. + if error is GRPCStatus || error is GRPCStatusTransformable { + self.handleError(error) + } else { + // Fallback to something which will mark the RPC as 'unavailable'. + self.handleError(ConnectionFailure(reason: error)) + } + } + } + + /// Append a request part to the write buffer. + /// - Parameters: + /// - part: The request part to buffer. + /// - promise: A promise to complete when the request part has been sent. + private func buffer( + _ part: GRPCClientRequestPart, + promise: EventLoopPromise? + ) { + self.callEventLoop.assertInEventLoop() + self.logger.trace("buffering request part", metadata: [ + "request_part": "\(part.name)", + "call_state": self.stateForLogging, + ]) + self.writeBuffer.append(.init(request: part, promise: promise)) + } + + /// Writes any buffered request parts to the `Channel`. + private func unbuffer() { + self.callEventLoop.assertInEventLoop() + + guard let channel = self.channel else { + return + } + + // Save any flushing until we're done writing. + var shouldFlush = false + + self.logger.trace("unbuffering request parts", metadata: [ + "request_parts": "\(self.writeBuffer.count)", + ]) + + // Why the double loop? A promise completed as a result of the flush may enqueue more writes, + // or causes us to change state (i.e. we may have to close). If we didn't loop around then we + // may miss more buffered writes. + while self.state.isUnbuffering, !self.writeBuffer.isEmpty { + // Pull out as many writes as possible. + while let write = self.writeBuffer.popFirst() { + self.logger.trace("unbuffering request part", metadata: [ + "request_part": "\(write.request.name)", + ]) + + if !shouldFlush { + shouldFlush = self.shouldFlush(after: write.request) + } + + self.writeToChannel(channel, part: write.request, promise: write.promise, flush: false) + } + + // Okay, flush now. + if shouldFlush { + shouldFlush = false + channel.flush() + } + } + + if self.writeBuffer.isEmpty { + self.logger.trace("request buffer drained") + } else { + self.logger.notice("unbuffering aborted", metadata: ["call_state": self.stateForLogging]) + } + + // We're unbuffered. What now? + switch self.state.unbuffered() { + case .doNothing: + () + case .succeedChannelPromise: + self.channelPromise?.succeed(channel) + } + } + + /// Fails any promises that come with buffered writes with `error`. + /// - Parameter error: The `Error` to fail promises with. + private func failBufferedWrites(with error: Error) { + self.logger.trace("failing buffered writes", metadata: ["call_state": self.stateForLogging]) + + while let write = self.writeBuffer.popFirst() { + write.promise?.fail(error) + } + } + + /// Write a request part to the `Channel`. + /// - Parameters: + /// - channel: The `Channel` to write `part` to. + /// - part: The request part to write. + /// - promise: A promise to complete once the write has been completed. + /// - flush: Whether to flush the `Channel` after writing. + private func writeToChannel( + _ channel: Channel, + part: GRPCClientRequestPart, + promise: EventLoopPromise?, + flush: Bool + ) { + switch part { + case let .metadata(headers): + let head = self.makeRequestHead(with: headers) + channel.write(self.wrapOutboundOut(.head(head)), promise: promise) + + case let .message(request, metadata): + do { + let bytes = try self.serializer.serialize(request, allocator: channel.allocator) + let message = _MessageContext(bytes, compressed: metadata.compress) + channel.write(self.wrapOutboundOut(.message(message)), promise: promise) + } catch { + self.handleError(error) + } + + case .end: + channel.write(self.wrapOutboundOut(.end), promise: promise) + } + + if flush { + channel.flush() + } + } + + /// Forward the response part to the interceptor pipeline. + /// - Parameter part: The response part to forward. + private func forwardToInterceptors(_ part: GRPCClientResponsePart) { + self.callEventLoop.assertInEventLoop() + self._pipeline?.receive(part) + } + + /// Forward the error to the interceptor pipeline. + /// - Parameter error: The error to forward. + private func forwardErrorToInterceptors(_ error: Error) { + self.callEventLoop.assertInEventLoop() + self._pipeline?.errorCaught(error) + } +} + +// MARK: - Helpers + +extension ClientTransport { + /// Returns whether the `Channel` should be flushed after writing the given part to it. + private func shouldFlush(after part: GRPCClientRequestPart) -> Bool { + switch part { + case .metadata: + // If we're not streaming requests then we hold off on the flush until we see end. + return self.isStreamingRequests + + case let .message(_, metadata): + // Message flushing is determined by caller preference. + return metadata.flush + + case .end: + // Always flush at the end of the request stream. + return true + } + } + + /// Make a `_GRPCRequestHead` with the provided metadata. + private func makeRequestHead(with metadata: HPACKHeaders) -> _GRPCRequestHead { + return _GRPCRequestHead( + method: self.callDetails.options.cacheable ? "GET" : "POST", + scheme: self.callDetails.scheme, + path: self.callDetails.path, + host: self.callDetails.authority, + deadline: self.callDetails.options.timeLimit.makeDeadline(), + customMetadata: metadata, + encoding: self.callDetails.options.messageEncoding + ) + } +} + +extension GRPCClientRequestPart { + /// The name of the request part, used for logging. + fileprivate var name: String { + switch self { + case .metadata: + return "metadata" + case .message: + return "message" + case .end: + return "end" + } + } +} + +// A wrapper for connection errors: we need to be able to preserve the underlying error as +// well as extract a 'GRPCStatus' with code '.unavailable'. +internal struct ConnectionFailure: Error, GRPCStatusTransformable, CustomStringConvertible { + /// The reason the connection failed. + var reason: Error + + init(reason: Error) { + self.reason = reason + } + + var description: String { + return String(describing: self.reason) + } + + func makeGRPCStatus() -> GRPCStatus { + return GRPCStatus( + code: .unavailable, + message: String(describing: self.reason), + cause: self.reason + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransportFactory.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransportFactory.swift new file mode 100644 index 00000000..2010fbe9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ClientTransportFactory.swift @@ -0,0 +1,363 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHTTP2 +import protocol SwiftProtobuf.Message + +/// A `ClientTransport` factory for an RPC. +@usableFromInline +internal struct ClientTransportFactory { + /// The underlying transport factory. + private var factory: Factory + + @usableFromInline + internal enum Factory { + case http2(HTTP2ClientTransportFactory) + case fake(FakeClientTransportFactory) + } + + private init(_ http2: HTTP2ClientTransportFactory) { + self.factory = .http2(http2) + } + + private init(_ fake: FakeClientTransportFactory) { + self.factory = .fake(fake) + } + + /// Create a transport factory for HTTP/2 based transport with `SwiftProtobuf.Message` messages. + /// - Parameters: + /// - multiplexer: The multiplexer used to create an HTTP/2 stream for the RPC. + /// - host: The value of the ":authority" pseudo header. + /// - scheme: The value of the ":scheme" pseudo header. + /// - errorDelegate: A client error delegate. + /// - Returns: A factory for making and configuring HTTP/2 based transport. + @usableFromInline + internal static func http2( + channel: EventLoopFuture, + authority: String, + scheme: String, + maximumReceiveMessageLength: Int, + errorDelegate: ClientErrorDelegate? + ) -> ClientTransportFactory { + let http2 = HTTP2ClientTransportFactory( + streamChannel: channel, + scheme: scheme, + authority: authority, + serializer: ProtobufSerializer(), + deserializer: ProtobufDeserializer(), + maximumReceiveMessageLength: maximumReceiveMessageLength, + errorDelegate: errorDelegate + ) + return .init(http2) + } + + /// Create a transport factory for HTTP/2 based transport with `GRPCPayload` messages. + /// - Parameters: + /// - multiplexer: The multiplexer used to create an HTTP/2 stream for the RPC. + /// - host: The value of the ":authority" pseudo header. + /// - scheme: The value of the ":scheme" pseudo header. + /// - errorDelegate: A client error delegate. + /// - Returns: A factory for making and configuring HTTP/2 based transport. + @usableFromInline + internal static func http2( + channel: EventLoopFuture, + authority: String, + scheme: String, + maximumReceiveMessageLength: Int, + errorDelegate: ClientErrorDelegate? + ) -> ClientTransportFactory { + let http2 = HTTP2ClientTransportFactory( + streamChannel: channel, + scheme: scheme, + authority: authority, + serializer: AnySerializer(wrapping: GRPCPayloadSerializer()), + deserializer: AnyDeserializer(wrapping: GRPCPayloadDeserializer()), + maximumReceiveMessageLength: maximumReceiveMessageLength, + errorDelegate: errorDelegate + ) + return .init(http2) + } + + /// Make a factory for 'fake' transport. + /// - Parameter fakeResponse: The fake response stream. + /// - Returns: A factory for making and configuring fake transport. + @usableFromInline + internal static func fake( + _ fakeResponse: _FakeResponseStream? + ) -> ClientTransportFactory { + let factory = FakeClientTransportFactory( + fakeResponse, + requestSerializer: ProtobufSerializer(), + requestDeserializer: ProtobufDeserializer(), + responseSerializer: ProtobufSerializer(), + responseDeserializer: ProtobufDeserializer() + ) + return .init(factory) + } + + /// Make a factory for 'fake' transport. + /// - Parameter fakeResponse: The fake response stream. + /// - Returns: A factory for making and configuring fake transport. + @usableFromInline + internal static func fake( + _ fakeResponse: _FakeResponseStream? + ) -> ClientTransportFactory { + let factory = FakeClientTransportFactory( + fakeResponse, + requestSerializer: GRPCPayloadSerializer(), + requestDeserializer: GRPCPayloadDeserializer(), + responseSerializer: GRPCPayloadSerializer(), + responseDeserializer: GRPCPayloadDeserializer() + ) + return .init(factory) + } + + /// Makes a configured `ClientTransport`. + /// - Parameters: + /// - path: The path of the RPC, e.g. "/echo.Echo/Get". + /// - type: The type of RPC, e.g. `.unary`. + /// - options: Options for the RPC. + /// - interceptors: Interceptors to use for the RPC. + /// - onError: A callback invoked when an error is received. + /// - onResponsePart: A closure called for each response part received. + /// - Returns: A configured transport. + internal func makeConfiguredTransport( + to path: String, + for type: GRPCCallType, + withOptions options: CallOptions, + onEventLoop eventLoop: EventLoop, + interceptedBy interceptors: [ClientInterceptor], + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) -> ClientTransport { + switch self.factory { + case let .http2(factory): + let transport = factory.makeTransport( + to: path, + for: type, + withOptions: options, + onEventLoop: eventLoop, + interceptedBy: interceptors, + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + factory.configure(transport) + return transport + case let .fake(factory): + let transport = factory.makeTransport( + to: path, + for: type, + withOptions: options, + onEventLoop: eventLoop, + interceptedBy: interceptors, + onError: onError, + onResponsePart + ) + factory.configure(transport) + return transport + } + } +} + +@usableFromInline +internal struct HTTP2ClientTransportFactory { + /// The multiplexer providing an HTTP/2 stream for the call. + private var streamChannel: EventLoopFuture + + /// The ":authority" pseudo-header. + private var authority: String + + /// The ":scheme" pseudo-header. + private var scheme: String + + /// An error delegate. + private var errorDelegate: ClientErrorDelegate? + + /// The request serializer. + private let serializer: AnySerializer + + /// The response deserializer. + private let deserializer: AnyDeserializer + + /// Maximum allowed length of a received message. + private let maximumReceiveMessageLength: Int + + @usableFromInline + internal init( + streamChannel: EventLoopFuture, + scheme: String, + authority: String, + serializer: Serializer, + deserializer: Deserializer, + maximumReceiveMessageLength: Int, + errorDelegate: ClientErrorDelegate? + ) where Serializer.Input == Request, Deserializer.Output == Response { + self.streamChannel = streamChannel + self.scheme = scheme + self.authority = authority + self.serializer = AnySerializer(wrapping: serializer) + self.deserializer = AnyDeserializer(wrapping: deserializer) + self.maximumReceiveMessageLength = maximumReceiveMessageLength + self.errorDelegate = errorDelegate + } + + fileprivate func makeTransport( + to path: String, + for type: GRPCCallType, + withOptions options: CallOptions, + onEventLoop eventLoop: EventLoop, + interceptedBy interceptors: [ClientInterceptor], + onStart: @escaping () -> Void, + onError: @escaping (Error) -> Void, + onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) -> ClientTransport { + return ClientTransport( + details: self.makeCallDetails(type: type, path: path, options: options), + eventLoop: eventLoop, + interceptors: interceptors, + serializer: self.serializer, + deserializer: self.deserializer, + errorDelegate: self.errorDelegate, + onStart: onStart, + onError: onError, + onResponsePart: onResponsePart + ) + } + + fileprivate func configure(_ transport: ClientTransport) { + transport.configure { _ in + self.streamChannel.flatMapThrowing { channel in + // This initializer will always occur on the appropriate event loop, sync operations are + // fine here. + let syncOperations = channel.pipeline.syncOperations + + do { + let clientHandler = GRPCClientChannelHandler( + callType: transport.callDetails.type, + maximumReceiveMessageLength: self.maximumReceiveMessageLength, + logger: transport.logger + ) + try syncOperations.addHandler(clientHandler) + try syncOperations.addHandler(transport) + } + } + } + } + + private func makeCallDetails( + type: GRPCCallType, + path: String, + options: CallOptions + ) -> CallDetails { + return .init( + type: type, + path: path, + authority: self.authority, + scheme: self.scheme, + options: options + ) + } +} + +@usableFromInline +internal struct FakeClientTransportFactory { + /// The fake response stream for the call. This can be `nil` if the user did not correctly + /// configure their client. The result will be a transport which immediately fails. + private var fakeResponseStream: _FakeResponseStream? + + /// The request serializer. + private let requestSerializer: AnySerializer + + /// The response deserializer. + private let responseDeserializer: AnyDeserializer + + /// A codec for deserializing requests and serializing responses. + private let codec: ChannelHandler + + @usableFromInline + internal init< + RequestSerializer: MessageSerializer, + RequestDeserializer: MessageDeserializer, + ResponseSerializer: MessageSerializer, + ResponseDeserializer: MessageDeserializer + >( + _ fakeResponseStream: _FakeResponseStream?, + requestSerializer: RequestSerializer, + requestDeserializer: RequestDeserializer, + responseSerializer: ResponseSerializer, + responseDeserializer: ResponseDeserializer + ) where RequestSerializer.Input == Request, + RequestDeserializer.Output == Request, + ResponseSerializer.Input == Response, + ResponseDeserializer.Output == Response + { + self.fakeResponseStream = fakeResponseStream + self.requestSerializer = AnySerializer(wrapping: requestSerializer) + self.responseDeserializer = AnyDeserializer(wrapping: responseDeserializer) + self.codec = GRPCClientReverseCodecHandler( + serializer: responseSerializer, + deserializer: requestDeserializer + ) + } + + fileprivate func makeTransport( + to path: String, + for type: GRPCCallType, + withOptions options: CallOptions, + onEventLoop eventLoop: EventLoop, + interceptedBy interceptors: [ClientInterceptor], + onError: @escaping (Error) -> Void, + _ onResponsePart: @escaping (GRPCClientResponsePart) -> Void + ) -> ClientTransport { + return ClientTransport( + details: CallDetails( + type: type, + path: path, + authority: "localhost", + scheme: "http", + options: options + ), + eventLoop: eventLoop, + interceptors: interceptors, + serializer: self.requestSerializer, + deserializer: self.responseDeserializer, + errorDelegate: nil, + onStart: {}, + onError: onError, + onResponsePart: onResponsePart + ) + } + + fileprivate func configure(_ transport: ClientTransport) { + transport.configure { handler in + if let fakeResponse = self.fakeResponseStream { + return fakeResponse.channel.pipeline.addHandlers(self.codec, handler).always { result in + switch result { + case .success: + fakeResponse.activate() + case .failure: + () + } + } + } else { + return transport.callEventLoop + .makeFailedFuture(GRPCStatus(code: .unavailable, message: nil)) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/MessageParts.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/MessageParts.swift new file mode 100644 index 00000000..bc1403d8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/MessageParts.swift @@ -0,0 +1,101 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOHPACK + +public enum GRPCClientRequestPart { + /// User provided metadata sent at the start of the request stream. + case metadata(HPACKHeaders) + + /// A message to send to the server. + case message(Request, MessageMetadata) + + /// The end the request stream. + case end +} + +public enum GRPCClientResponsePart { + /// The metadata returned by the server at the start of the RPC. + case metadata(HPACKHeaders) + + /// A response message from the server. + case message(Response) + + /// The end of response stream sent by the server. + case end(GRPCStatus, HPACKHeaders) +} + +public enum GRPCServerRequestPart { + /// Metadata received from the client at the start of the RPC. + case metadata(HPACKHeaders) + + /// A request message sent by the client. + case message(Request) + + /// The end the request stream. + case end +} + +public enum GRPCServerResponsePart { + /// The metadata to send to the client at the start of the response stream. + case metadata(HPACKHeaders) + + /// A response message sent by the server. + case message(Response, MessageMetadata) + + /// The end of response stream sent by the server. + case end(GRPCStatus, HPACKHeaders) +} + +/// Metadata associated with a request or response message. +public struct MessageMetadata: Equatable, GRPCSendable { + /// Whether the message should be compressed. If compression has not been enabled on the RPC + /// then this setting is ignored. + public var compress: Bool + + /// Whether the underlying transported should be 'flushed' after writing this message. If a batch + /// of messages is to be sent then flushing only after the last message may improve + /// performance. + public var flush: Bool + + public init(compress: Bool, flush: Bool) { + self.compress = compress + self.flush = flush + } +} + +extension GRPCClientResponsePart { + @inlinable + internal var isEnd: Bool { + switch self { + case .end: + return true + case .metadata, .message: + return false + } + } +} + +extension GRPCServerResponsePart { + @inlinable + internal var isEnd: Bool { + switch self { + case .end: + return true + case .metadata, .message: + return false + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorContext.swift new file mode 100644 index 00000000..632bee45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorContext.swift @@ -0,0 +1,109 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +public struct ServerInterceptorContext { + /// The interceptor this context is for. + @usableFromInline + internal let interceptor: ServerInterceptor + + /// The pipeline this context is associated with. + @usableFromInline + internal let _pipeline: ServerInterceptorPipeline + + /// The index of this context's interceptor within the pipeline. + @usableFromInline + internal let _index: Int + + /// The `EventLoop` this interceptor pipeline is being executed on. + public var eventLoop: EventLoop { + return self._pipeline.eventLoop + } + + /// A logger. + public var logger: Logger { + return self._pipeline.logger + } + + /// The type of the RPC, e.g. "unary". + public var type: GRPCCallType { + return self._pipeline.type + } + + /// The path of the RPC in the format "/Service/Method", e.g. "/echo.Echo/Get". + public var path: String { + return self._pipeline.path + } + + /// The address of the remote peer. + public var remoteAddress: SocketAddress? { + return self._pipeline.remoteAddress + } + + /// A 'UserInfo' dictionary. + /// + /// - Important: While `UserInfo` has value-semantics, this property retrieves from, and sets a + /// reference wrapped `UserInfo`. The contexts passed to the service provider share the same + /// reference. As such this may be used as a mechanism to pass information between interceptors + /// and service providers. + /// - Important: `userInfo` *must* be accessed from the context's `eventLoop` in order to ensure + /// thread-safety. + public var userInfo: UserInfo { + get { + return self._pipeline.userInfoRef.value + } + nonmutating set { + self._pipeline.userInfoRef.value = newValue + } + } + + /// Construct a `ServerInterceptorContext` for the interceptor at the given index within the + /// interceptor pipeline. + @inlinable + internal init( + for interceptor: ServerInterceptor, + atIndex index: Int, + in pipeline: ServerInterceptorPipeline + ) { + self.interceptor = interceptor + self._pipeline = pipeline + self._index = index + } + + /// Forwards the request part to the next inbound interceptor in the pipeline, if there is one. + /// + /// - Parameter part: The request part to forward. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func receive(_ part: GRPCServerRequestPart) { + self._pipeline.invokeReceive(part, fromContextAtIndex: self._index) + } + + /// Forwards the response part to the next outbound interceptor in the pipeline, if there is one. + /// + /// - Parameters: + /// - part: The response part to forward. + /// - promise: The promise the complete when the part has been written. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + public func send( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + self._pipeline.invokeSend(part, promise: promise, fromContextAtIndex: self._index) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorPipeline.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorPipeline.swift new file mode 100644 index 00000000..82acb3bf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptorPipeline.swift @@ -0,0 +1,281 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +@usableFromInline +internal final class ServerInterceptorPipeline { + /// The `EventLoop` this RPC is being executed on. + @usableFromInline + internal let eventLoop: EventLoop + + /// The path of the RPC in the format "/Service/Method", e.g. "/echo.Echo/Get". + @usableFromInline + internal let path: String + + /// The type of the RPC, e.g. "unary". + @usableFromInline + internal let type: GRPCCallType + + /// The remote peer's address. + @usableFromInline + internal let remoteAddress: SocketAddress? + + /// A logger. + @usableFromInline + internal let logger: Logger + + /// A reference to a 'UserInfo'. + @usableFromInline + internal let userInfoRef: Ref + + /// Called when a response part has traversed the interceptor pipeline. + @usableFromInline + internal let _onResponsePart: (GRPCServerResponsePart, EventLoopPromise?) -> Void + + /// Called when a request part has traversed the interceptor pipeline. + @usableFromInline + internal let _onRequestPart: (GRPCServerRequestPart) -> Void + + /// The index before the first user interceptor context index. (always -1). + @usableFromInline + internal let _headIndex: Int + + /// The index after the last user interceptor context index (i.e. 'userContext.endIndex'). + @usableFromInline + internal let _tailIndex: Int + + /// Contexts for user provided interceptors. + @usableFromInline + internal var _userContexts: [ServerInterceptorContext] + + /// Whether the interceptor pipeline is still open. It becomes closed after an 'end' response + /// part has traversed the pipeline. + @usableFromInline + internal var _isOpen = true + + /// The index of the next context on the inbound side of the context at the given index. + @inlinable + internal func _nextInboundIndex(after index: Int) -> Int { + // Unchecked arithmetic is okay here: our greatest inbound index is '_tailIndex' but we will + // never ask for the inbound index after the tail. + assert(self._indexIsValid(index)) + return index &+ 1 + } + + /// The index of the next context on the outbound side of the context at the given index. + @inlinable + internal func _nextOutboundIndex(after index: Int) -> Int { + // Unchecked arithmetic is okay here: our lowest outbound index is '_headIndex' but we will + // never ask for the outbound index after the head. + assert(self._indexIsValid(index)) + return index &- 1 + } + + /// Returns true of the index is in the range `_headIndex ... _tailIndex`. + @inlinable + internal func _indexIsValid(_ index: Int) -> Bool { + return self._headIndex <= index && index <= self._tailIndex + } + + @inlinable + internal init( + logger: Logger, + eventLoop: EventLoop, + path: String, + callType: GRPCCallType, + remoteAddress: SocketAddress?, + userInfoRef: Ref, + interceptors: [ServerInterceptor], + onRequestPart: @escaping (GRPCServerRequestPart) -> Void, + onResponsePart: @escaping (GRPCServerResponsePart, EventLoopPromise?) -> Void + ) { + self.logger = logger + self.eventLoop = eventLoop + self.path = path + self.type = callType + self.remoteAddress = remoteAddress + self.userInfoRef = userInfoRef + + self._onResponsePart = onResponsePart + self._onRequestPart = onRequestPart + + // Head comes before user interceptors. + self._headIndex = -1 + // Tail comes just after. + self._tailIndex = interceptors.endIndex + + // Make some contexts. + self._userContexts = [] + self._userContexts.reserveCapacity(interceptors.count) + + for index in 0 ..< interceptors.count { + let context = ServerInterceptorContext(for: interceptors[index], atIndex: index, in: self) + self._userContexts.append(context) + } + } + + /// Emit a request part message into the interceptor pipeline. + /// + /// - Parameter part: The part to emit into the pipeline. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func receive(_ part: GRPCServerRequestPart) { + self.invokeReceive(part, fromContextAtIndex: self._headIndex) + } + + /// Invoke receive on the appropriate context when called from the context at the given index. + @inlinable + internal func invokeReceive( + _ part: GRPCServerRequestPart, + fromContextAtIndex index: Int + ) { + self._invokeReceive(part, onContextAtIndex: self._nextInboundIndex(after: index)) + } + + /// Invoke receive on the context at the given index, if doing so is safe. + @inlinable + internal func _invokeReceive( + _ part: GRPCServerRequestPart, + onContextAtIndex index: Int + ) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + return + } + + // We've checked the index. + self._invokeReceive(part, onContextAtUncheckedIndex: index) + } + + /// Invoke receive on the context at the given index, assuming that the index is valid and the + /// pipeline is still open. + @inlinable + internal func _invokeReceive( + _ part: GRPCServerRequestPart, + onContextAtUncheckedIndex index: Int + ) { + switch index { + case self._headIndex: + // The next inbound index must exist, either for the tail or a user interceptor. + self._invokeReceive( + part, + onContextAtUncheckedIndex: self._nextInboundIndex(after: self._headIndex) + ) + + case self._tailIndex: + self._onRequestPart(part) + + default: + self._userContexts[index].invokeReceive(part) + } + } + + /// Write a response message into the interceptor pipeline. + /// + /// - Parameters: + /// - part: The response part to sent. + /// - promise: A promise to complete when the response part has been successfully written. + /// - Important: This *must* to be called from the `eventLoop`. + @inlinable + internal func send(_ part: GRPCServerResponsePart, promise: EventLoopPromise?) { + self.invokeSend(part, promise: promise, fromContextAtIndex: self._tailIndex) + } + + /// Invoke send on the appropriate context when called from the context at the given index. + @inlinable + internal func invokeSend( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise?, + fromContextAtIndex index: Int + ) { + self._invokeSend( + part, + promise: promise, + onContextAtIndex: self._nextOutboundIndex(after: index) + ) + } + + /// Invoke send on the context at the given index, if doing so is safe. Fails the `promise` if it + /// is not safe to do so. + @inlinable + internal func _invokeSend( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise?, + onContextAtIndex index: Int + ) { + self.eventLoop.assertInEventLoop() + assert(self._indexIsValid(index)) + guard self._isOpen else { + promise?.fail(GRPCError.AlreadyComplete()) + return + } + + self._invokeSend(uncheckedIndex: index, part, promise: promise) + } + + /// Invoke send on the context at the given index, assuming that the index is valid and the + /// pipeline is still open. + @inlinable + internal func _invokeSend( + uncheckedIndex index: Int, + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + switch index { + case self._headIndex: + if part.isEnd { + self.close() + } + self._onResponsePart(part, promise) + + case self._tailIndex: + // The next outbound index must exist: it will be the head or a user interceptor. + self._invokeSend( + uncheckedIndex: self._nextOutboundIndex(after: self._tailIndex), + part, + promise: promise + ) + + default: + self._userContexts[index].invokeSend(part, promise: promise) + } + } + + @inlinable + internal func close() { + // We're no longer open. + self._isOpen = false + // Each context hold a ref to the pipeline; break the retain cycle. + self._userContexts.removeAll() + } +} + +extension ServerInterceptorContext { + @inlinable + internal func invokeReceive(_ part: GRPCServerRequestPart) { + self.interceptor.receive(part, context: self) + } + + @inlinable + internal func invokeSend( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise? + ) { + self.interceptor.send(part, promise: promise, context: self) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptors.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptors.swift new file mode 100644 index 00000000..4090b0bd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Interceptor/ServerInterceptors.swift @@ -0,0 +1,71 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +/// A base class for server interceptors. +/// +/// Interceptors allow request and response and response parts to be observed, mutated or dropped +/// as necessary. The default behaviour for this base class is to forward any events to the next +/// interceptor. +/// +/// Interceptors may observe two different types of event: +/// - receiving request parts with `receive(_:context:)`, +/// - sending response parts with `send(_:promise:context:)`. +/// +/// These events flow through a pipeline of interceptors for each RPC. Request parts will enter +/// the head of the interceptor pipeline once the request router has determined that there is a +/// service provider which is able to handle the request stream. Response parts from the service +/// provider enter the tail of the interceptor pipeline and will be sent to the client after +/// traversing the pipeline through to the head. +/// +/// Each of the interceptor functions is provided with a `context` which exposes analogous functions +/// (`receive(_:)` and `send(_:promise:)`) which may be called to forward events to the next +/// interceptor. +/// +/// ### Thread Safety +/// +/// Functions on `context` are not thread safe and **must** be called on the `EventLoop` found on +/// the `context`. Since each interceptor is invoked on the same `EventLoop` this does not usually +/// require any extra attention. However, if work is done on a `DispatchQueue` or _other_ +/// `EventLoop` then implementers should ensure that they use `context` from the correct +/// `EventLoop`. +open class ServerInterceptor { + public init() {} + + /// Called when the interceptor has received a request part to handle. + /// - Parameters: + /// - part: The request part which has been received from the client. + /// - context: An interceptor context which may be used to forward the response part. + open func receive( + _ part: GRPCServerRequestPart, + context: ServerInterceptorContext + ) { + context.receive(part) + } + + /// Called when the interceptor has received a response part to handle. + /// - Parameters: + /// - part: The request part which should be sent to the client. + /// - promise: A promise which should be completed when the response part has been written. + /// - context: An interceptor context which may be used to forward the request part. + open func send( + _ part: GRPCServerResponsePart, + promise: EventLoopPromise?, + context: ServerInterceptorContext + ) { + context.send(part, promise: promise) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/InterceptorContextList.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/InterceptorContextList.swift new file mode 100644 index 00000000..013ddf61 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/InterceptorContextList.swift @@ -0,0 +1,65 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// A non-empty list which is guaranteed to have a first and last element. +/// +/// This is required since we want to directly store the first and last elements: in some cases +/// `Array.first` and `Array.last` will allocate: unfortunately this currently happens to be the +/// case for the interceptor pipelines. Storing the `first` and `last` directly allows us to avoid +/// this. See also: https://bugs.swift.org/browse/SR-11262. +@usableFromInline +internal struct InterceptorContextList { + /// The first element, stored at `middle.startIndex - 1`. + @usableFromInline + internal var first: Element + + /// The last element, stored at the `middle.endIndex`. + @usableFromInline + internal var last: Element + + /// The other elements. + @usableFromInline + internal var _middle: [Element] + + /// The index of `first` + @usableFromInline + internal let firstIndex: Int + + /// The index of `last`. + @usableFromInline + internal let lastIndex: Int + + @usableFromInline + internal subscript(checked index: Int) -> Element? { + switch index { + case self.firstIndex: + return self.first + case self.lastIndex: + return self.last + default: + return self._middle[checked: index] + } + } + + @inlinable + internal init(first: Element, middle: [Element], last: Element) { + self.first = first + self._middle = middle + self.last = last + self.firstIndex = middle.startIndex - 1 + self.lastIndex = middle.endIndex + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageReader.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageReader.swift new file mode 100644 index 00000000..c3f49c47 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageReader.swift @@ -0,0 +1,225 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHTTP1 + +/// This class reads and decodes length-prefixed gRPC messages. +/// +/// Messages are expected to be in the following format: +/// - compression flag: 0/1 as a 1-byte unsigned integer, +/// - message length: length of the message as a 4-byte unsigned integer, +/// - message: `message_length` bytes. +/// +/// Messages may span multiple `ByteBuffer`s, and `ByteBuffer`s may contain multiple +/// length-prefixed messages. +/// +/// - SeeAlso: +/// [gRPC Protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) +internal struct LengthPrefixedMessageReader { + let compression: CompressionAlgorithm? + private let decompressor: Zlib.Inflate? + + init() { + self.compression = nil + self.decompressor = nil + } + + init(compression: CompressionAlgorithm, decompressionLimit: DecompressionLimit) { + self.compression = compression + + switch compression.algorithm { + case .identity: + self.decompressor = nil + case .deflate: + self.decompressor = Zlib.Inflate(format: .deflate, limit: decompressionLimit) + case .gzip: + self.decompressor = Zlib.Inflate(format: .gzip, limit: decompressionLimit) + } + } + + /// The result of trying to parse a message with the bytes we currently have. + /// + /// - needMoreData: More data is required to continue reading a message. + /// - continue: Continue reading a message. + /// - message: A message was read. + internal enum ParseResult { + case needMoreData + case `continue` + case message(ByteBuffer) + } + + /// The parsing state; what we expect to be reading next. + internal enum ParseState { + case expectingCompressedFlag + case expectingMessageLength(compressed: Bool) + case expectingMessage(Int, compressed: Bool) + } + + private var buffer: ByteBuffer! + private var state: ParseState = .expectingCompressedFlag + + /// Returns the number of unprocessed bytes. + internal var unprocessedBytes: Int { + return self.buffer.map { $0.readableBytes } ?? 0 + } + + /// Returns the number of bytes that have been consumed and not discarded. + internal var _consumedNonDiscardedBytes: Int { + return self.buffer.map { $0.readerIndex } ?? 0 + } + + /// Whether the reader is mid-way through reading a message. + internal var isReading: Bool { + switch self.state { + case .expectingCompressedFlag: + return false + case .expectingMessageLength, .expectingMessage: + return true + } + } + + /// Appends data to the buffer from which messages will be read. + internal mutating func append(buffer: inout ByteBuffer) { + guard buffer.readableBytes > 0 else { + return + } + + if self.buffer == nil { + self.buffer = buffer.slice() + // mark the bytes as "read" + buffer.moveReaderIndex(forwardBy: buffer.readableBytes) + } else { + switch self.state { + case let .expectingMessage(length, _): + // We need to reserve enough space for the message or the incoming buffer, whichever + // is larger. + let remainingMessageBytes = Int(length) - self.buffer.readableBytes + self.buffer + .reserveCapacity(minimumWritableBytes: max(remainingMessageBytes, buffer.readableBytes)) + + case .expectingCompressedFlag, + .expectingMessageLength: + // Just append the buffer; these parts are too small to make a meaningful difference. + () + } + + self.buffer.writeBuffer(&buffer) + } + } + + /// Reads bytes from the buffer until it is exhausted or a message has been read. + /// + /// - Returns: A buffer containing a message if one has been read, or `nil` if not enough + /// bytes have been consumed to return a message. + /// - Throws: Throws an error if the compression algorithm is not supported. + internal mutating func nextMessage(maxLength: Int) throws -> ByteBuffer? { + switch try self.processNextState(maxLength: maxLength) { + case .needMoreData: + self.nilBufferIfPossible() + return nil + + case .continue: + return try self.nextMessage(maxLength: maxLength) + + case let .message(message): + self.nilBufferIfPossible() + return message + } + } + + /// `nil`s out `buffer` if it exists and has no readable bytes. + /// + /// This allows the next call to `append` to avoid writing the contents of the appended buffer. + private mutating func nilBufferIfPossible() { + let readableBytes = self.buffer?.readableBytes ?? 0 + let readerIndex = self.buffer?.readerIndex ?? 0 + let capacity = self.buffer?.capacity ?? 0 + + if readableBytes == 0 { + self.buffer = nil + } else if readerIndex > 1024, readerIndex > (capacity / 2) { + // A rough-heuristic: if there is a kilobyte of read data, and there is more data that + // has been read than there is space in the rest of the buffer, we'll try to discard some + // read bytes here. We're trying to avoid doing this if there is loads of writable bytes that + // we'll have to shift. + self.buffer?.discardReadBytes() + } + } + + private mutating func processNextState(maxLength: Int) throws -> ParseResult { + guard self.buffer != nil else { + return .needMoreData + } + + switch self.state { + case .expectingCompressedFlag: + guard let compressionFlag: UInt8 = self.buffer.readInteger() else { + return .needMoreData + } + + let isCompressionEnabled = compressionFlag != 0 + // Compression is enabled, but not expected. + if isCompressionEnabled, self.compression == nil { + throw GRPCError.CompressionUnsupported().captureContext() + } + self.state = .expectingMessageLength(compressed: isCompressionEnabled) + + case let .expectingMessageLength(compressed): + guard let messageLength = self.buffer.readInteger(as: UInt32.self).map(Int.init) else { + return .needMoreData + } + + if messageLength > maxLength { + throw GRPCError.PayloadLengthLimitExceeded( + actualLength: messageLength, + limit: maxLength + ).captureContext() + } + + self.state = .expectingMessage(messageLength, compressed: compressed) + + case let .expectingMessage(length, compressed): + guard var message = self.buffer.readSlice(length: length) else { + return .needMoreData + } + + let result: ParseResult + + // TODO: If compression is enabled and we store the buffer slices then we can feed the slices + // into the decompressor. This should eliminate one buffer allocation (i.e. the buffer into + // which we currently accumulate the slices before decompressing it into a new buffer). + + // If compression is set but the algorithm is 'identity' then we will not get a decompressor + // here. + if compressed, let decompressor = self.decompressor { + var decompressed = ByteBufferAllocator().buffer(capacity: 0) + try decompressor.inflate(&message, into: &decompressed) + // Compression contexts should be reset between messages. + decompressor.reset() + result = .message(decompressed) + } else { + result = .message(message) + } + + self.state = .expectingCompressedFlag + return result + } + + return .continue + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageWriter.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageWriter.swift new file mode 100644 index 00000000..54efbf97 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LengthPrefixedMessageWriter.swift @@ -0,0 +1,195 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import NIOCore + +internal struct LengthPrefixedMessageWriter { + static let metadataLength = 5 + + /// The compression algorithm to use, if one should be used. + let compression: CompressionAlgorithm? + private let compressor: Zlib.Deflate? + + /// Whether the compression message flag should be set. + private var shouldSetCompressionFlag: Bool { + return self.compression != nil + } + + init(compression: CompressionAlgorithm? = nil) { + self.compression = compression + + switch self.compression?.algorithm { + case .none, .some(.identity): + self.compressor = nil + case .some(.deflate): + self.compressor = Zlib.Deflate(format: .deflate) + case .some(.gzip): + self.compressor = Zlib.Deflate(format: .gzip) + } + } + + private func compress( + buffer: ByteBuffer, + using compressor: Zlib.Deflate, + allocator: ByteBufferAllocator + ) throws -> ByteBuffer { + // The compressor will allocate the correct size. For now the leading 5 bytes will do. + var output = allocator.buffer(capacity: 5) + + // Set the compression byte. + output.writeInteger(UInt8(1)) + + // Set the length to zero; we'll write the actual value in a moment. + let payloadSizeIndex = output.writerIndex + output.writeInteger(UInt32(0)) + + let bytesWritten: Int + + do { + var buffer = buffer + bytesWritten = try compressor.deflate(&buffer, into: &output) + } catch { + throw error + } + + // Now fill in the message length. + output.writePayloadLength(UInt32(bytesWritten), at: payloadSizeIndex) + + // Finally, the compression context should be reset between messages. + compressor.reset() + + return output + } + + /// Writes the readable bytes of `buffer` as a gRPC length-prefixed message. + /// + /// - Parameters: + /// - buffer: The bytes to compress and length-prefix. + /// - allocator: A `ByteBufferAllocator`. + /// - compressed: Whether the bytes should be compressed. This is ignored if not compression + /// mechanism was configured on this writer. + /// - Returns: A buffer containing the length prefixed bytes. + func write( + buffer: ByteBuffer, + allocator: ByteBufferAllocator, + compressed: Bool = true + ) throws -> ByteBuffer { + if compressed, let compressor = self.compressor { + return try self.compress(buffer: buffer, using: compressor, allocator: allocator) + } else if buffer.readerIndex >= 5 { + // We're not compressing and we have enough bytes before the reader index that we can write + // over with the compression byte and length. + var buffer = buffer + + // Get the size of the message. + let messageSize = buffer.readableBytes + + // Move the reader index back 5 bytes. This is okay: we validated the `readerIndex` above. + buffer.moveReaderIndex(to: buffer.readerIndex - 5) + + // Fill in the compression byte and message length. + buffer.setInteger(UInt8(0), at: buffer.readerIndex) + buffer.setInteger(UInt32(messageSize), at: buffer.readerIndex + 1) + + // The message bytes are already in place, we're done. + return buffer + } else { + // We're not compressing and we don't have enough space before the message bytes passed in. + // We need a new buffer. + var lengthPrefixed = allocator.buffer(capacity: 5 + buffer.readableBytes) + + // Write the compression byte. + lengthPrefixed.writeInteger(UInt8(0)) + + // Write the message length. + lengthPrefixed.writeInteger(UInt32(buffer.readableBytes)) + + // Write the message. + var buffer = buffer + lengthPrefixed.writeBuffer(&buffer) + + return lengthPrefixed + } + } + + /// Writes the data into a `ByteBuffer` as a gRPC length-prefixed message. + /// + /// - Parameters: + /// - payload: The payload to serialize and write. + /// - buffer: The buffer to write the message into. + /// - Returns: A `ByteBuffer` containing a gRPC length-prefixed message. + /// - Precondition: `compression.supported` is `true`. + /// - Note: See `LengthPrefixedMessageReader` for more details on the format. + func write( + _ payload: GRPCPayload, + into buffer: inout ByteBuffer, + compressed: Bool = true + ) throws { + buffer.reserveCapacity(buffer.writerIndex + LengthPrefixedMessageWriter.metadataLength) + + if compressed, let compressor = self.compressor { + // Set the compression byte. + buffer.writeInteger(UInt8(1)) + + // Leave a gap for the length, we'll set it in a moment. + let payloadSizeIndex = buffer.writerIndex + buffer.moveWriterIndex(forwardBy: MemoryLayout.size) + + var messageBuf = ByteBufferAllocator().buffer(capacity: 0) + try payload.serialize(into: &messageBuf) + + // Compress the message. + let bytesWritten = try compressor.deflate(&messageBuf, into: &buffer) + + // Now fill in the message length. + buffer.writePayloadLength(UInt32(bytesWritten), at: payloadSizeIndex) + + // Finally, the compression context should be reset between messages. + compressor.reset() + } else { + // We could be using 'identity' compression, but since the result is the same we'll just + // say it isn't compressed. + buffer.writeInteger(UInt8(0)) + + // Leave a gap for the length, we'll set it in a moment. + let payloadSizeIndex = buffer.writerIndex + buffer.moveWriterIndex(forwardBy: MemoryLayout.size) + + let payloadPrefixedBytes = buffer.readableBytes + // Writes the payload into the buffer + try payload.serialize(into: &buffer) + + // Calculates the Written bytes with respect to the prefixed ones + let bytesWritten = buffer.readableBytes - payloadPrefixedBytes + + // Write the message length. + buffer.writePayloadLength(UInt32(bytesWritten), at: payloadSizeIndex) + } + } +} + +extension ByteBuffer { + @discardableResult + mutating func writePayloadLength(_ length: UInt32, at index: Int) -> Int { + let writerIndex = self.writerIndex + defer { + self.moveWriterIndex(to: writerIndex) + } + + self.moveWriterIndex(to: index) + return self.writeInteger(length) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Logger.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Logger.swift new file mode 100644 index 00000000..4b1e97e3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Logger.swift @@ -0,0 +1,45 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +/// Keys for `Logger` metadata. +enum MetadataKey { + static let requestID = "grpc_request_id" + static let connectionID = "grpc_connection_id" + + static let eventLoop = "event_loop" + + static let h2StreamID = "h2_stream_id" + static let h2ActiveStreams = "h2_active_streams" + static let h2EndStream = "h2_end_stream" + static let h2Payload = "h2_payload" + static let h2Headers = "h2_headers" + static let h2DataBytes = "h2_data_bytes" + + static let error = "error" +} + +extension Logger { + internal mutating func addIPAddressMetadata(local: SocketAddress?, remote: SocketAddress?) { + if let local = local?.ipAddress { + self[metadataKey: "grpc.conn.addr_local"] = "\(local)" + } + if let remote = remote?.ipAddress { + self[metadataKey: "grpc.conn.addr_remote"] = "\(remote)" + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LoggingServerErrorDelegate.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LoggingServerErrorDelegate.swift new file mode 100644 index 00000000..8c55178a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/LoggingServerErrorDelegate.swift @@ -0,0 +1,32 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging + +public class LoggingServerErrorDelegate: ServerErrorDelegate { + private let logger: Logger + + public init(logger: Logger) { + self.logger = logger + } + + public func observeLibraryError(_ error: Error) { + self.logger.error("library error", metadata: [MetadataKey.error: "\(error)"]) + } + + public func observeRequestHandlerError(_ error: Error) { + self.logger.error("request handler error", metadata: [MetadataKey.error: "\(error)"]) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/MessageEncodingHeaderValidator.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/MessageEncodingHeaderValidator.swift new file mode 100644 index 00000000..4c26ba59 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/MessageEncodingHeaderValidator.swift @@ -0,0 +1,92 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +struct MessageEncodingHeaderValidator { + var encoding: ServerMessageEncoding + + enum ValidationResult { + /// The requested compression is supported. + case supported( + algorithm: CompressionAlgorithm, + decompressionLimit: DecompressionLimit, + acceptEncoding: [String] + ) + + /// The `requestEncoding` is not supported; `acceptEncoding` contains all algorithms we do + /// support. + case unsupported(requestEncoding: String, acceptEncoding: [String]) + + /// No compression was requested. + case noCompression + } + + /// Validates the value of the 'grpc-encoding' header against compression algorithms supported and + /// advertised by this peer. + /// + /// - Parameter requestEncoding: The value of the 'grpc-encoding' header. + func validate(requestEncoding: String?) -> ValidationResult { + switch (self.encoding, requestEncoding) { + // Compression is enabled and the client sent a message encoding header. Do we support it? + case let (.enabled(configuration), .some(header)): + guard let algorithm = CompressionAlgorithm(rawValue: header) else { + return .unsupported( + requestEncoding: header, + acceptEncoding: configuration.enabledAlgorithms.map { $0.name } + ) + } + + if configuration.enabledAlgorithms.contains(algorithm) { + return .supported( + algorithm: algorithm, + decompressionLimit: configuration.decompressionLimit, + acceptEncoding: [] + ) + } else { + // From: https://github.com/grpc/grpc/blob/master/doc/compression.md + // + // Note that a peer MAY choose to not disclose all the encodings it supports. However, if + // it receives a message compressed in an undisclosed but supported encoding, it MUST + // include said encoding in the response's grpc-accept-encoding header. + return .supported( + algorithm: algorithm, + decompressionLimit: configuration.decompressionLimit, + acceptEncoding: configuration.enabledAlgorithms.map { $0.name } + CollectionOfOne(header) + ) + } + + // Compression is disabled and the client sent a message encoding header. We don't support this + // unless the header is "identity", which is no compression. Note this is different to the + // supported but not advertised case since we have explicitly not enabled compression. + case let (.disabled, .some(header)): + guard let algorithm = CompressionAlgorithm(rawValue: header) else { + return .unsupported( + requestEncoding: header, + acceptEncoding: [] + ) + } + + if algorithm == .identity { + return .noCompression + } else { + return .unsupported(requestEncoding: header, acceptEncoding: []) + } + + // The client didn't send a message encoding header. + case (_, .none): + return .noCompression + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/PlatformSupport.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/PlatformSupport.swift new file mode 100644 index 00000000..ed6635c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/PlatformSupport.swift @@ -0,0 +1,408 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOPosix +import NIOTransportServices + +/// How a network implementation should be chosen. +public struct NetworkPreference: Hashable { + private enum Wrapped: Hashable { + case best + case userDefined(NetworkImplementation) + } + + private var wrapped: Wrapped + private init(_ wrapped: Wrapped) { + self.wrapped = wrapped + } + + /// Use the best available, that is, Network.framework (and NIOTransportServices) when it is + /// available on Darwin platforms (macOS 10.14+, iOS 12.0+, tvOS 12.0+, watchOS 6.0+), and + /// falling back to the POSIX network model otherwise. + public static let best = NetworkPreference(.best) + + /// Use the given implementation. Doing so may require additional availability checks depending + /// on the implementation. + public static func userDefined(_ implementation: NetworkImplementation) -> NetworkPreference { + return NetworkPreference(.userDefined(implementation)) + } +} + +/// The network implementation to use: POSIX sockets or Network.framework. This also determines +/// which variant of NIO to use; NIO or NIOTransportServices, respectively. +public struct NetworkImplementation: Hashable { + fileprivate enum Wrapped: Hashable { + case networkFramework + case posix + } + + fileprivate var wrapped: Wrapped + private init(_ wrapped: Wrapped) { + self.wrapped = wrapped + } + + #if canImport(Network) + /// Network.framework (NIOTransportServices). + @available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) + public static let networkFramework = NetworkImplementation(.networkFramework) + #endif + + /// POSIX (NIO). + public static let posix = NetworkImplementation(.posix) + + internal static func matchingEventLoopGroup(_ group: EventLoopGroup) -> NetworkImplementation { + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + if PlatformSupport.isTransportServicesEventLoopGroup(group) { + return .networkFramework + } + } + #endif + return .posix + } +} + +extension NetworkPreference { + /// The network implementation, and by extension the NIO variant which will be used. + /// + /// Network.framework is available on macOS 10.14+, iOS 12.0+, tvOS 12.0+ and watchOS 6.0+. + /// + /// This isn't directly useful when implementing code which branches on the network preference + /// since that code will still need the appropriate availability check: + /// + /// - `@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)`, or + /// - `#available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)`. + public var implementation: NetworkImplementation { + switch self.wrapped { + case .best: + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + return .networkFramework + } else { + // Older platforms must use the POSIX loop. + return .posix + } + #else + return .posix + #endif + + case let .userDefined(implementation): + return implementation + } + } +} + +// MARK: - Generic Bootstraps + +// TODO: Revisit the handling of NIO/NIOTS once https://github.com/apple/swift-nio/issues/796 +// is addressed. + +/// This protocol is intended as a layer of abstraction over `ClientBootstrap` and +/// `NIOTSConnectionBootstrap`. +public protocol ClientBootstrapProtocol { + func connect(to: SocketAddress) -> EventLoopFuture + func connect(host: String, port: Int) -> EventLoopFuture + func connect(unixDomainSocketPath: String) -> EventLoopFuture + func withConnectedSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture + + func connectTimeout(_ timeout: TimeAmount) -> Self + func channelOption(_ option: T, value: T.Value) -> Self where T: ChannelOption + func channelInitializer(_ handler: @escaping (Channel) -> EventLoopFuture) -> Self +} + +extension ClientBootstrapProtocol { + public func withConnectedSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture { + preconditionFailure("withConnectedSocket(_:) is not implemented") + } +} + +extension ClientBootstrap: ClientBootstrapProtocol {} + +#if canImport(Network) +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSConnectionBootstrap: ClientBootstrapProtocol { + public func withConnectedSocket(_ socket: NIOBSDSocket.Handle) -> EventLoopFuture { + preconditionFailure("NIOTSConnectionBootstrap does not support withConnectedSocket(_:)") + } +} +#endif + +/// This protocol is intended as a layer of abstraction over `ServerBootstrap` and +/// `NIOTSListenerBootstrap`. +public protocol ServerBootstrapProtocol { + func bind(to: SocketAddress) -> EventLoopFuture + func bind(host: String, port: Int) -> EventLoopFuture + func bind(unixDomainSocketPath: String) -> EventLoopFuture + func withBoundSocket(_ connectedSocket: NIOBSDSocket.Handle) -> EventLoopFuture + + func serverChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self + func serverChannelOption(_ option: T, value: T.Value) -> Self where T: ChannelOption + + func childChannelInitializer(_ initializer: @escaping (Channel) -> EventLoopFuture) -> Self + func childChannelOption(_ option: T, value: T.Value) -> Self where T: ChannelOption +} + +extension ServerBootstrapProtocol { + public func withBoundSocket(_ connectedSocket: NIOBSDSocket.Handle) -> EventLoopFuture { + preconditionFailure("withBoundSocket(_:) is not implemented") + } +} + +extension ServerBootstrap: ServerBootstrapProtocol {} + +#if canImport(Network) +@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) +extension NIOTSListenerBootstrap: ServerBootstrapProtocol { + public func withBoundSocket(_ connectedSocket: NIOBSDSocket.Handle) -> EventLoopFuture { + preconditionFailure("NIOTSListenerBootstrap does not support withConnectedSocket(_:)") + } +} +#endif + +// MARK: - Bootstrap / EventLoopGroup helpers + +public enum PlatformSupport { + /// Makes a new event loop group based on the network preference. + /// + /// If `.best` is chosen and `Network.framework` is available then `NIOTSEventLoopGroup` will + /// be returned. A `MultiThreadedEventLoopGroup` will be returned otherwise. + /// + /// - Parameter loopCount: The number of event loops to create in the event loop group. + /// - Parameter networkPreference: Network preference; defaulting to `.best`. + public static func makeEventLoopGroup( + loopCount: Int, + networkPreference: NetworkPreference = .best, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + ) -> EventLoopGroup { + logger.debug("making EventLoopGroup for \(networkPreference) network preference") + switch networkPreference.implementation.wrapped { + case .networkFramework: + #if canImport(Network) + guard #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) else { + logger.critical("Network.framework can be imported but is not supported on this platform") + // This is gated by the availability of `.networkFramework` so should never happen. + fatalError(".networkFramework is being used on an unsupported platform") + } + logger.debug("created NIOTSEventLoopGroup for \(networkPreference) preference") + return NIOTSEventLoopGroup(loopCount: loopCount) + #else + fatalError(".networkFramework is being used on an unsupported platform") + #endif + case .posix: + logger.debug("created MultiThreadedEventLoopGroup for \(networkPreference) preference") + return MultiThreadedEventLoopGroup(numberOfThreads: loopCount) + } + } + + /// Makes a new client bootstrap using the given `EventLoopGroup`. + /// + /// If the `EventLoopGroup` is a `NIOTSEventLoopGroup` then the returned bootstrap will be a + /// `NIOTSConnectionBootstrap`, otherwise it will be a `ClientBootstrap`. + /// + /// - Parameter group: The `EventLoopGroup` to use. + public static func makeClientBootstrap( + group: EventLoopGroup, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + ) -> ClientBootstrapProtocol { + logger.debug("making client bootstrap with event loop group of type \(type(of: group))") + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + if isTransportServicesEventLoopGroup(group) { + logger.debug( + "Network.framework is available and the EventLoopGroup is compatible with NIOTS, creating a NIOTSConnectionBootstrap" + ) + return NIOTSConnectionBootstrap(group: group) + } else { + logger.debug( + "Network.framework is available but the EventLoopGroup is not compatible with NIOTS, falling back to ClientBootstrap" + ) + } + } + #endif + logger.debug("creating a ClientBootstrap") + return ClientBootstrap(group: group) + } + + internal static func isTransportServicesEventLoopGroup(_ group: EventLoopGroup) -> Bool { + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + return group is NIOTSEventLoopGroup || group is QoSEventLoop + } + #endif + return false + } + + internal static func makeClientBootstrap( + group: EventLoopGroup, + tlsConfiguration: GRPCTLSConfiguration?, + logger: Logger + ) -> ClientBootstrapProtocol { + let bootstrap = self.makeClientBootstrap(group: group, logger: logger) + + guard let tlsConfigruation = tlsConfiguration else { + return bootstrap + } + + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *), + let transportServicesBootstrap = bootstrap as? NIOTSConnectionBootstrap { + return transportServicesBootstrap.tlsOptions(from: tlsConfigruation) + } + #endif + + return bootstrap + } + + /// Makes a new server bootstrap using the given `EventLoopGroup`. + /// + /// If the `EventLoopGroup` is a `NIOTSEventLoopGroup` then the returned bootstrap will be a + /// `NIOTSListenerBootstrap`, otherwise it will be a `ServerBootstrap`. + /// + /// - Parameter group: The `EventLoopGroup` to use. + public static func makeServerBootstrap( + group: EventLoopGroup, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + ) -> ServerBootstrapProtocol { + logger.debug("making server bootstrap with event loop group of type \(type(of: group))") + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + if let tsGroup = group as? NIOTSEventLoopGroup { + logger + .debug( + "Network.framework is available and the group is correctly typed, creating a NIOTSListenerBootstrap" + ) + return NIOTSListenerBootstrap(group: tsGroup) + } else if let qosEventLoop = group as? QoSEventLoop { + logger + .debug( + "Network.framework is available and the group is correctly typed, creating a NIOTSListenerBootstrap" + ) + return NIOTSListenerBootstrap(group: qosEventLoop) + } + logger + .debug( + "Network.framework is available but the group is not typed for NIOTS, falling back to ServerBootstrap" + ) + } + #endif + logger.debug("creating a ServerBootstrap") + return ServerBootstrap(group: group) + } + + /// Determines whether we may need to work around an issue in Network.framework with zero-length writes. + /// + /// See https://github.com/apple/swift-nio-transport-services/pull/72 for more. + static func requiresZeroLengthWriteWorkaround(group: EventLoopGroup, hasTLS: Bool) -> Bool { + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + if group is NIOTSEventLoopGroup || group is QoSEventLoop { + // We need the zero-length write workaround on NIOTS when not using TLS. + return !hasTLS + } else { + return false + } + } else { + return false + } + #else + return false + #endif + } +} + +extension PlatformSupport { + /// Make an `EventLoopGroup` which is compatible with the given TLS configuration/ + /// + /// - Parameters: + /// - configuration: The configuration to make a compatible `EventLoopGroup` for. + /// - loopCount: The number of loops the `EventLoopGroup` should have. + /// - Returns: An `EventLoopGroup` compatible with the given `configuration`. + public static func makeEventLoopGroup( + compatibleWith configuration: GRPCTLSConfiguration, + loopCount: Int + ) -> EventLoopGroup { + #if canImport(Network) + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + if configuration.isNetworkFrameworkTLSBackend { + return NIOTSEventLoopGroup(loopCount: loopCount) + } + } + #endif + return MultiThreadedEventLoopGroup(numberOfThreads: loopCount) + } +} + +extension GRPCTLSConfiguration { + /// Provides a `GRPCTLSConfiguration` suitable for the given `EventLoopGroup`. + public static func makeClientDefault( + compatibleWith eventLoopGroup: EventLoopGroup + ) -> GRPCTLSConfiguration { + let networkImplementation: NetworkImplementation = .matchingEventLoopGroup(eventLoopGroup) + return GRPCTLSConfiguration.makeClientDefault(for: .userDefined(networkImplementation)) + } + + /// Provides a `GRPCTLSConfiguration` suitable for the given network preference. + public static func makeClientDefault( + for networkPreference: NetworkPreference + ) -> GRPCTLSConfiguration { + switch networkPreference.implementation.wrapped { + case .networkFramework: + #if canImport(Network) + guard #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) else { + // This is gated by the availability of `.networkFramework` so should never happen. + fatalError(".networkFramework is being used on an unsupported platform") + } + + return .makeClientConfigurationBackedByNetworkFramework() + #else + fatalError(".networkFramework is being used on an unsupported platform") + #endif + + case .posix: + #if canImport(NIOSSL) + return .makeClientConfigurationBackedByNIOSSL() + #else + fatalError("Default client TLS configuration for '.posix' requires NIOSSL") + #endif + } + } +} + +extension EventLoopGroup { + internal func isCompatible(with tlsConfiguration: GRPCTLSConfiguration) -> Bool { + let isTransportServicesGroup = PlatformSupport.isTransportServicesEventLoopGroup(self) + let isNetworkFrameworkTLSBackend = tlsConfiguration.isNetworkFrameworkTLSBackend + // If the group is from NIOTransportServices then we can use either the NIOSSL or the + // Network.framework TLS backend. + // + // If it isn't then we must not use the Network.Framework TLS backend. + return isTransportServicesGroup || !isNetworkFrameworkTLSBackend + } + + internal func preconditionCompatible( + with tlsConfiguration: GRPCTLSConfiguration, + file: StaticString = #file, + line: UInt = #line + ) { + precondition( + self.isCompatible(with: tlsConfiguration), + "Unsupported 'EventLoopGroup' and 'GRPCLSConfiguration' pairing (Network.framework backed TLS configurations MUST use an EventLoopGroup from NIOTransportServices)", + file: file, + line: line + ) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ReadWriteStates.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ReadWriteStates.swift new file mode 100644 index 00000000..27df2d4c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ReadWriteStates.swift @@ -0,0 +1,220 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import SwiftProtobuf + +/// Number of messages expected on a stream. +enum MessageArity { + case one + case many +} + +/// Encapsulates the state required to create a new write state. +struct PendingWriteState { + /// The number of messages we expect to write to the stream. + var arity: MessageArity + + /// The 'content-type' being written. + var contentType: ContentType + + func makeWriteState(messageEncoding: ClientMessageEncoding) -> WriteState { + let compression: CompressionAlgorithm? + switch messageEncoding { + case let .enabled(configuration): + compression = configuration.outbound + case .disabled: + compression = nil + } + + let writer = LengthPrefixedMessageWriter(compression: compression) + return .writing(self.arity, self.contentType, writer) + } +} + +/// The write state of a stream. +enum WriteState { + /// Writing may be attempted using the given writer. + case writing(MessageArity, ContentType, LengthPrefixedMessageWriter) + + /// Writing may not be attempted: either a write previously failed or it is not valid for any + /// more messages to be written. + case notWriting + + /// Writes a message into a buffer using the `writer` and `allocator`. + /// + /// - Parameter message: The `Message` to write. + /// - Parameter allocator: An allocator to provide a `ByteBuffer` into which the message will be + /// written. + mutating func write( + _ message: ByteBuffer, + compressed: Bool, + allocator: ByteBufferAllocator + ) -> Result { + switch self { + case .notWriting: + return .failure(.cardinalityViolation) + + case let .writing(writeArity, contentType, writer): + let buffer: ByteBuffer + + do { + buffer = try writer.write(buffer: message, allocator: allocator, compressed: compressed) + } catch { + self = .notWriting + return .failure(.serializationFailed) + } + + // If we only expect to write one message then we're no longer writable. + if case .one = writeArity { + self = .notWriting + } else { + self = .writing(writeArity, contentType, writer) + } + + return .success(buffer) + } + } +} + +enum MessageWriteError: Error { + /// Too many messages were written. + case cardinalityViolation + + /// Message serialization failed. + case serializationFailed + + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} + +/// Encapsulates the state required to create a new read state. +struct PendingReadState { + /// The number of messages we expect to read from the stream. + var arity: MessageArity + + /// The message encoding configuration, and whether it's enabled or not. + var messageEncoding: ClientMessageEncoding + + func makeReadState(compression: CompressionAlgorithm? = nil) -> ReadState { + let reader: LengthPrefixedMessageReader + switch (self.messageEncoding, compression) { + case let (.enabled(configuration), .some(compression)): + reader = LengthPrefixedMessageReader( + compression: compression, + decompressionLimit: configuration.decompressionLimit + ) + + case (.enabled, .none), + (.disabled, _): + reader = LengthPrefixedMessageReader() + } + return .reading(self.arity, reader) + } +} + +/// The read state of a stream. +enum ReadState { + /// Reading may be attempted using the given reader. + case reading(MessageArity, LengthPrefixedMessageReader) + + /// Reading may not be attempted: either a read previously failed or it is not valid for any + /// more messages to be read. + case notReading + + /// Consume the given `buffer` then attempt to read length-prefixed serialized messages. + /// + /// For an expected message count of `.one`, this function will produce **at most** 1 message. If + /// a message has been produced then subsequent calls will result in an error. + /// + /// - Parameter buffer: The buffer to read from. + mutating func readMessages( + _ buffer: inout ByteBuffer, + maxLength: Int + ) -> Result<[ByteBuffer], MessageReadError> { + switch self { + case .notReading: + return .failure(.cardinalityViolation) + + case .reading(let readArity, var reader): + reader.append(buffer: &buffer) + var messages: [ByteBuffer] = [] + + do { + while let serializedBytes = try reader.nextMessage(maxLength: maxLength) { + messages.append(serializedBytes) + } + } catch { + self = .notReading + if let grpcError = error as? GRPCError.WithContext { + if let compressionLimit = grpcError.error as? GRPCError.DecompressionLimitExceeded { + return .failure(.decompressionLimitExceeded(compressionLimit.compressedSize)) + } else if let lengthLimit = grpcError.error as? GRPCError.PayloadLengthLimitExceeded { + return .failure(.lengthExceedsLimit(lengthLimit)) + } + } + + return .failure(.deserializationFailed) + } + + // We need to validate the number of messages we decoded. Zero is fine because the payload may + // be split across frames. + switch (readArity, messages.count) { + // Always allowed: + case (.one, 0), + (.many, 0...): + self = .reading(readArity, reader) + return .success(messages) + + // Also allowed, assuming we have no leftover bytes: + case (.one, 1): + // We can't read more than one message on a unary stream. + self = .notReading + // We shouldn't have any bytes leftover after reading a single message and we also should not + // have partially read a message. + if reader.unprocessedBytes != 0 || reader.isReading { + return .failure(.leftOverBytes) + } else { + return .success(messages) + } + + // Anything else must be invalid. + default: + self = .notReading + return .failure(.cardinalityViolation) + } + } + } +} + +enum MessageReadError: Error, Equatable { + /// Too many messages were read. + case cardinalityViolation + + /// Enough messages were read but bytes there are left-over bytes. + case leftOverBytes + + /// Message deserialization failed. + case deserializationFailed + + /// The limit for decompression was exceeded. + case decompressionLimitExceeded(Int) + + /// The length of the message exceeded the permitted maximum length. + case lengthExceedsLimit(GRPCError.PayloadLengthLimitExceeded) + + /// An invalid state was encountered. This is a serious implementation error. + case invalidState +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Ref.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Ref.swift new file mode 100644 index 00000000..ab7fde89 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Ref.swift @@ -0,0 +1,26 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@usableFromInline +internal final class Ref { + @usableFromInline + internal var value: Value + + @inlinable + internal init(_ value: Value) { + self.value = value + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Serialization.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Serialization.swift new file mode 100644 index 00000000..4d851270 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Serialization.swift @@ -0,0 +1,155 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOFoundationCompat +import SwiftProtobuf + +public protocol MessageSerializer { + associatedtype Input + + /// Serializes `input` into a `ByteBuffer` allocated using the provided `allocator`. + /// + /// - Parameters: + /// - input: The element to serialize. + /// - allocator: A `ByteBufferAllocator`. + @inlinable + func serialize(_ input: Input, allocator: ByteBufferAllocator) throws -> ByteBuffer +} + +public protocol MessageDeserializer { + associatedtype Output + + /// Deserializes `byteBuffer` to produce a single `Output`. + /// + /// - Parameter byteBuffer: The `ByteBuffer` to deserialize. + @inlinable + func deserialize(byteBuffer: ByteBuffer) throws -> Output +} + +// MARK: Protobuf + +public struct ProtobufSerializer: MessageSerializer { + @inlinable + public init() {} + + @inlinable + public func serialize(_ message: Message, allocator: ByteBufferAllocator) throws -> ByteBuffer { + // Serialize the message. + let serialized = try message.serializedData() + + // Allocate enough space and an extra 5 leading bytes. This a minor optimisation win: the length + // prefixed message writer can re-use the leading 5 bytes without needing to allocate a new + // buffer and copy over the serialized message. + var buffer = allocator.buffer(capacity: serialized.count + 5) + buffer.writeRepeatingByte(0, count: 5) + buffer.moveReaderIndex(forwardBy: 5) + + // Now write the serialized message. + buffer.writeContiguousBytes(serialized) + + return buffer + } +} + +public struct ProtobufDeserializer: MessageDeserializer { + @inlinable + public init() {} + + @inlinable + public func deserialize(byteBuffer: ByteBuffer) throws -> Message { + var buffer = byteBuffer + // '!' is okay; we can always read 'readableBytes'. + let data = buffer.readData(length: buffer.readableBytes)! + return try Message(serializedData: data) + } +} + +// MARK: GRPCPayload + +public struct GRPCPayloadSerializer: MessageSerializer { + @inlinable + public init() {} + + @inlinable + public func serialize(_ message: Message, allocator: ByteBufferAllocator) throws -> ByteBuffer { + // Reserve 5 leading bytes. This a minor optimisation win: the length prefixed message writer + // can re-use the leading 5 bytes without needing to allocate a new buffer and copy over the + // serialized message. + var buffer = allocator.buffer(repeating: 0, count: 5) + + let readerIndex = buffer.readerIndex + let writerIndex = buffer.writerIndex + + // Serialize the payload into the buffer. + try message.serialize(into: &buffer) + + // Ensure 'serialize(into:)' didn't do anything strange. + assert(buffer.readerIndex == readerIndex, "serialize(into:) must not move the readerIndex") + assert( + buffer.writerIndex >= writerIndex, + "serialize(into:) must not move the writerIndex backwards" + ) + assert( + buffer.getBytes(at: readerIndex, length: 5) == Array(repeating: 0, count: 5), + "serialize(into:) must not write over existing written bytes" + ) + + // 'read' the first 5 bytes so that the buffer's readable bytes are only the bytes of the + // serialized message. + buffer.moveReaderIndex(forwardBy: 5) + + return buffer + } +} + +public struct GRPCPayloadDeserializer: MessageDeserializer { + @inlinable + public init() {} + + @inlinable + public func deserialize(byteBuffer: ByteBuffer) throws -> Message { + var buffer = byteBuffer + return try Message(serializedByteBuffer: &buffer) + } +} + +// MARK: - Any Serializer/Deserializer + +internal struct AnySerializer: MessageSerializer { + private let _serialize: (Input, ByteBufferAllocator) throws -> ByteBuffer + + init(wrapping other: Serializer) where Serializer.Input == Input { + self._serialize = other.serialize(_:allocator:) + } + + internal func serialize(_ input: Input, allocator: ByteBufferAllocator) throws -> ByteBuffer { + return try self._serialize(input, allocator) + } +} + +internal struct AnyDeserializer: MessageDeserializer { + private let _deserialize: (ByteBuffer) throws -> Output + + init( + wrapping other: Deserializer + ) where Deserializer.Output == Output { + self._deserialize = other.deserialize(byteBuffer:) + } + + internal func deserialize(byteBuffer: ByteBuffer) throws -> Output { + return try self._deserialize(byteBuffer) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server+NIOSSL.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server+NIOSSL.swift new file mode 100644 index 00000000..6c27900c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server+NIOSSL.swift @@ -0,0 +1,125 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOSSL + +extension Server.Configuration { + /// TLS configuration for a `Server`. + /// + /// Note that this configuration is a subset of `NIOSSL.TLSConfiguration` where certain options + /// are removed from the users control to ensure the configuration complies with the gRPC + /// specification. + @available(*, deprecated, renamed: "GRPCTLSConfiguration") + public struct TLS { + public private(set) var configuration: TLSConfiguration + + /// Whether ALPN is required. Disabling this option may be useful in cases where ALPN is not + /// supported. + public var requireALPN: Bool = true + + /// The certificates to offer during negotiation. If not present, no certificates will be + /// offered. + public var certificateChain: [NIOSSLCertificateSource] { + get { + return self.configuration.certificateChain + } + set { + self.configuration.certificateChain = newValue + } + } + + /// The private key associated with the leaf certificate. + public var privateKey: NIOSSLPrivateKeySource? { + get { + return self.configuration.privateKey + } + set { + self.configuration.privateKey = newValue + } + } + + /// The trust roots to use to validate certificates. This only needs to be provided if you + /// intend to validate certificates. + public var trustRoots: NIOSSLTrustRoots? { + get { + return self.configuration.trustRoots + } + set { + self.configuration.trustRoots = newValue + } + } + + /// Whether to verify remote certificates. + public var certificateVerification: CertificateVerification { + get { + return self.configuration.certificateVerification + } + set { + self.configuration.certificateVerification = newValue + } + } + + /// TLS Configuration with suitable defaults for servers. + /// + /// This is a wrapper around `NIOSSL.TLSConfiguration` to restrict input to values which comply + /// with the gRPC protocol. + /// + /// - Parameter certificateChain: The certificate to offer during negotiation. + /// - Parameter privateKey: The private key associated with the leaf certificate. + /// - Parameter trustRoots: The trust roots to validate certificates, this defaults to using a + /// root provided by the platform. + /// - Parameter certificateVerification: Whether to verify the remote certificate. Defaults to + /// `.none`. + /// - Parameter requireALPN: Whether ALPN is required or not. + public init( + certificateChain: [NIOSSLCertificateSource], + privateKey: NIOSSLPrivateKeySource, + trustRoots: NIOSSLTrustRoots = .default, + certificateVerification: CertificateVerification = .none, + requireALPN: Bool = true + ) { + var configuration = TLSConfiguration.makeServerConfiguration( + certificateChain: certificateChain, + privateKey: privateKey + ) + configuration.minimumTLSVersion = .tlsv12 + configuration.certificateVerification = certificateVerification + configuration.trustRoots = trustRoots + configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.server + + self.configuration = configuration + self.requireALPN = requireALPN + } + + /// Creates a TLS Configuration using the given `NIOSSL.TLSConfiguration`. + /// - Note: If no ALPN tokens are set in `configuration.applicationProtocols` then the tokens + /// "grpc-exp", "h2" and "http/1.1" will be used. + /// - Parameters: + /// - configuration: The `NIOSSL.TLSConfiguration` to base this configuration on. + /// - requireALPN: Whether ALPN is required. + public init(configuration: TLSConfiguration, requireALPN: Bool = true) { + self.configuration = configuration + self.requireALPN = requireALPN + + // Set the ALPN tokens if none were set. + if self.configuration.applicationProtocols.isEmpty { + self.configuration.applicationProtocols = GRPCApplicationProtocolIdentifier.server + } + } + } +} + +#endif // canImport(NIOSSL) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server.swift new file mode 100644 index 00000000..3a77509b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Server.swift @@ -0,0 +1,476 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOExtras +import NIOHTTP1 +import NIOHTTP2 +import NIOPosix +#if canImport(NIOSSL) +import NIOSSL +#endif +import NIOTransportServices +#if canImport(Network) +import Network +#endif + +/// Wrapper object to manage the lifecycle of a gRPC server. +/// +/// The pipeline is configured in three stages detailed below. Note: handlers marked with +/// a '*' are responsible for handling errors. +/// +/// 1. Initial stage, prior to pipeline configuration. +/// +/// ┌─────────────────────────────────┐ +/// │ GRPCServerPipelineConfigurator* │ +/// └────▲───────────────────────┬────┘ +/// ByteBuffer│ │ByteBuffer +/// ┌─┴───────────────────────▼─┐ +/// │ NIOSSLHandler │ +/// └─▲───────────────────────┬─┘ +/// ByteBuffer│ │ByteBuffer +/// │ ▼ +/// +/// The `NIOSSLHandler` is optional and depends on how the framework user has configured +/// their server. The `GRPCServerPipelineConfigurator` detects which HTTP version is being used +/// (via ALPN if TLS is used or by parsing the first bytes on the connection otherwise) and +/// configures the pipeline accordingly. +/// +/// 2. HTTP version detected. "HTTP Handlers" depends on the HTTP version determined by +/// `GRPCServerPipelineConfigurator`. In the case of HTTP/2: +/// +/// ┌─────────────────────────────────┐ +/// │ HTTP2StreamMultiplexer │ +/// └─▲─────────────────────────────┬─┘ +/// HTTP2Frame│ │HTTP2Frame +/// ┌─┴─────────────────────────────▼─┐ +/// │ HTTP2Handler │ +/// └─▲─────────────────────────────┬─┘ +/// ByteBuffer│ │ByteBuffer +/// ┌─┴─────────────────────────────▼─┐ +/// │ NIOSSLHandler │ +/// └─▲─────────────────────────────┬─┘ +/// ByteBuffer│ │ByteBuffer +/// │ ▼ +/// +/// The `HTTP2StreamMultiplexer` provides one `Channel` for each HTTP/2 stream (and thus each +/// RPC). +/// +/// 3. The frames for each stream channel are routed by the `HTTP2ToRawGRPCServerCodec` handler to +/// a handler containing the user-implemented logic provided by a `CallHandlerProvider`: +/// +/// ┌─────────────────────────────────┐ +/// │ BaseCallHandler* │ +/// └─▲─────────────────────────────┬─┘ +/// GRPCServerRequestPart│ │GRPCServerResponsePart +/// ┌─┴─────────────────────────────▼─┐ +/// │ HTTP2ToRawGRPCServerCodec │ +/// └─▲─────────────────────────────┬─┘ +/// HTTP2Frame.FramePayload│ │HTTP2Frame.FramePayload +/// │ ▼ +/// +public final class Server { + /// Makes and configures a `ServerBootstrap` using the provided configuration. + public class func makeBootstrap(configuration: Configuration) -> ServerBootstrapProtocol { + let bootstrap = PlatformSupport.makeServerBootstrap(group: configuration.eventLoopGroup) + + // Backlog is only available on `ServerBootstrap`. + if bootstrap is ServerBootstrap { + // Specify a backlog to avoid overloading the server. + _ = bootstrap.serverChannelOption(ChannelOptions.backlog, value: 256) + } + + #if canImport(NIOSSL) + // Making a `NIOSSLContext` is expensive, we should only do it once per TLS configuration so + // we'll do it now, before accepting connections. Unfortunately our API isn't throwing so we'll + // only surface any error when initializing a child channel. + // + // 'nil' means we're not using TLS, or we're using the Network.framework TLS backend. If we're + // using the Network.framework TLS backend we'll apply the settings just below. + let sslContext: Result? + + if let tlsConfiguration = configuration.tlsConfiguration { + do { + sslContext = try tlsConfiguration.makeNIOSSLContext().map { .success($0) } + } catch { + sslContext = .failure(error) + } + + } else { + // No TLS configuration, no SSL context. + sslContext = nil + } + #endif // canImport(NIOSSL) + + #if canImport(Network) + if let tlsConfiguration = configuration.tlsConfiguration { + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *), + let transportServicesBootstrap = bootstrap as? NIOTSListenerBootstrap { + _ = transportServicesBootstrap.tlsOptions(from: tlsConfiguration) + } + } + #endif // canImport(Network) + + return bootstrap + // Enable `SO_REUSEADDR` to avoid "address already in use" error. + .serverChannelOption( + ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), + value: 1 + ) + // Set the handlers that are applied to the accepted Channels + .childChannelInitializer { channel in + var configuration = configuration + configuration.logger[metadataKey: MetadataKey.connectionID] = "\(UUID().uuidString)" + configuration.logger.addIPAddressMetadata( + local: channel.localAddress, + remote: channel.remoteAddress + ) + + do { + let sync = channel.pipeline.syncOperations + #if canImport(NIOSSL) + if let sslContext = try sslContext?.get() { + try sync.addHandler(NIOSSLServerHandler(context: sslContext)) + } + #endif // canImport(NIOSSL) + + // Configures the pipeline based on whether the connection uses TLS or not. + try sync.addHandler(GRPCServerPipelineConfigurator(configuration: configuration)) + + // Work around the zero length write issue, if needed. + let requiresZeroLengthWorkaround = PlatformSupport.requiresZeroLengthWriteWorkaround( + group: configuration.eventLoopGroup, + hasTLS: configuration.tlsConfiguration != nil + ) + if requiresZeroLengthWorkaround, + #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) { + try sync.addHandler(NIOFilterEmptyWritesHandler()) + } + } catch { + return channel.eventLoop.makeFailedFuture(error) + } + + // Run the debug initializer, if there is one. + if let debugAcceptedChannelInitializer = configuration.debugChannelInitializer { + return debugAcceptedChannelInitializer(channel) + } else { + return channel.eventLoop.makeSucceededVoidFuture() + } + } + + // Enable TCP_NODELAY and SO_REUSEADDR for the accepted Channels + .childChannelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1) + .childChannelOption( + ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), + value: 1 + ) + } + + /// Starts a server with the given configuration. See `Server.Configuration` for the options + /// available to configure the server. + public static func start(configuration: Configuration) -> EventLoopFuture { + let quiescingHelper = ServerQuiescingHelper(group: configuration.eventLoopGroup) + + return self.makeBootstrap(configuration: configuration) + .serverChannelInitializer { channel in + channel.pipeline.addHandler(quiescingHelper.makeServerChannelHandler(channel: channel)) + } + .bind(to: configuration.target) + .map { channel in + Server( + channel: channel, + quiescingHelper: quiescingHelper, + errorDelegate: configuration.errorDelegate + ) + } + } + + public let channel: Channel + private let quiescingHelper: ServerQuiescingHelper + private var errorDelegate: ServerErrorDelegate? + + private init( + channel: Channel, + quiescingHelper: ServerQuiescingHelper, + errorDelegate: ServerErrorDelegate? + ) { + self.channel = channel + self.quiescingHelper = quiescingHelper + + // Maintain a strong reference to ensure it lives as long as the server. + self.errorDelegate = errorDelegate + + // If we have an error delegate, add a server channel error handler as well. We don't need to wait for the handler to + // be added. + if let errorDelegate = errorDelegate { + _ = channel.pipeline.addHandler(ServerChannelErrorHandler(errorDelegate: errorDelegate)) + } + + // nil out errorDelegate to avoid retain cycles. + self.onClose.whenComplete { _ in + self.errorDelegate = nil + } + } + + /// Fired when the server shuts down. + public var onClose: EventLoopFuture { + return self.channel.closeFuture + } + + /// Initiates a graceful shutdown. Existing RPCs may run to completion, any new RPCs or + /// connections will be rejected. + public func initiateGracefulShutdown(promise: EventLoopPromise?) { + self.quiescingHelper.initiateShutdown(promise: promise) + } + + /// Initiates a graceful shutdown. Existing RPCs may run to completion, any new RPCs or + /// connections will be rejected. + public func initiateGracefulShutdown() -> EventLoopFuture { + let promise = self.channel.eventLoop.makePromise(of: Void.self) + self.initiateGracefulShutdown(promise: promise) + return promise.futureResult + } + + /// Shutdown the server immediately. Active RPCs and connections will be terminated. + public func close(promise: EventLoopPromise?) { + self.channel.close(mode: .all, promise: promise) + } + + /// Shutdown the server immediately. Active RPCs and connections will be terminated. + public func close() -> EventLoopFuture { + return self.channel.close(mode: .all) + } +} + +public typealias BindTarget = ConnectionTarget + +extension Server { + /// The configuration for a server. + public struct Configuration { + /// The target to bind to. + public var target: BindTarget + /// The event loop group to run the connection on. + public var eventLoopGroup: EventLoopGroup + + /// Providers the server should use to handle gRPC requests. + public var serviceProviders: [CallHandlerProvider] { + get { + return Array(self.serviceProvidersByName.values) + } + set { + self + .serviceProvidersByName = Dictionary( + uniqueKeysWithValues: newValue + .map { ($0.serviceName, $0) } + ) + } + } + + /// An error delegate which is called when errors are caught. Provided delegates **must not + /// maintain a strong reference to this `Server`**. Doing so will cause a retain cycle. + public var errorDelegate: ServerErrorDelegate? + + #if canImport(NIOSSL) + /// TLS configuration for this connection. `nil` if TLS is not desired. + @available(*, deprecated, renamed: "tlsConfiguration") + public var tls: TLS? { + get { + return self.tlsConfiguration?.asDeprecatedServerConfiguration + } + set { + self.tlsConfiguration = newValue.map { GRPCTLSConfiguration(transforming: $0) } + } + } + #endif // canImport(NIOSSL) + + public var tlsConfiguration: GRPCTLSConfiguration? + + /// The connection keepalive configuration. + public var connectionKeepalive = ServerConnectionKeepalive() + + /// The amount of time to wait before closing connections. The idle timeout will start only + /// if there are no RPCs in progress and will be cancelled as soon as any RPCs start. + public var connectionIdleTimeout: TimeAmount = .nanoseconds(.max) + + /// The compression configuration for requests and responses. + /// + /// If compression is enabled for the server it may be disabled for responses on any RPC by + /// setting `compressionEnabled` to `false` on the context of the call. + /// + /// Compression may also be disabled at the message-level for streaming responses (i.e. server + /// streaming and bidirectional streaming RPCs) by passing setting `compression` to `.disabled` + /// in `sendResponse(_:compression)`. + /// + /// Defaults to `.disabled`. + public var messageEncoding: ServerMessageEncoding = .disabled + + /// The maximum size in bytes of a message which may be received from a client. Defaults to 4MB. + public var maximumReceiveMessageLength: Int = 4 * 1024 * 1024 { + willSet { + precondition(newValue >= 0, "maximumReceiveMessageLength must be positive") + } + } + + /// The HTTP/2 flow control target window size. Defaults to 8MB. Values are clamped between + /// 1 and 2^31-1 inclusive. + public var httpTargetWindowSize = 8 * 1024 * 1024 { + didSet { + self.httpTargetWindowSize = self.httpTargetWindowSize.clamped(to: 1 ... Int(Int32.max)) + } + } + + /// The HTTP/2 max number of concurrent streams. Defaults to 100. Must be non-negative. + public var httpMaxConcurrentStreams: Int = 100 { + willSet { + precondition(newValue >= 0, "httpMaxConcurrentStreams must be non-negative") + } + } + + /// The HTTP/2 max frame size. Defaults to 16384. Value is clamped between 2^14 and 2^24-1 + /// octets inclusive (the minimum and maximum allowable values - HTTP/2 RFC 7540 4.2). + public var httpMaxFrameSize: Int = 16384 { + didSet { + self.httpMaxFrameSize = self.httpMaxFrameSize.clamped(to: 16384 ... 16_777_215) + } + } + + /// The root server logger. Accepted connections will branch from this logger and RPCs on + /// each connection will use a logger branched from the connections logger. This logger is made + /// available to service providers via `context`. Defaults to a no-op logger. + public var logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }) + + /// A channel initializer which will be run after gRPC has initialized each accepted channel. + /// This may be used to add additional handlers to the pipeline and is intended for debugging. + /// This is analogous to `NIO.ServerBootstrap.childChannelInitializer`. + /// + /// - Warning: The initializer closure may be invoked *multiple times*. More precisely: it will + /// be invoked at most once per accepted connection. + public var debugChannelInitializer: ((Channel) -> EventLoopFuture)? + + /// A calculated private cache of the service providers by name. + /// + /// This is how gRPC consumes the service providers internally. Caching this as stored data avoids + /// the need to recalculate this dictionary each time we receive an rpc. + internal var serviceProvidersByName: [Substring: CallHandlerProvider] + + #if canImport(NIOSSL) + /// Create a `Configuration` with some pre-defined defaults. + /// + /// - Parameters: + /// - target: The target to bind to. + /// - eventLoopGroup: The event loop group to run the server on. + /// - serviceProviders: An array of `CallHandlerProvider`s which the server should use + /// to handle requests. + /// - errorDelegate: The error delegate, defaulting to a logging delegate. + /// - tls: TLS configuration, defaulting to `nil`. + /// - connectionKeepalive: The keepalive configuration to use. + /// - connectionIdleTimeout: The amount of time to wait before closing the connection, this is + /// indefinite by default. + /// - messageEncoding: Message compression configuration, defaulting to no compression. + /// - httpTargetWindowSize: The HTTP/2 flow control target window size. + /// - logger: A logger. Defaults to a no-op logger. + /// - debugChannelInitializer: A channel initializer which will be called for each connection + /// the server accepts after gRPC has initialized the channel. Defaults to `nil`. + @available(*, deprecated, renamed: "default(target:eventLoopGroup:serviceProviders:)") + public init( + target: BindTarget, + eventLoopGroup: EventLoopGroup, + serviceProviders: [CallHandlerProvider], + errorDelegate: ServerErrorDelegate? = nil, + tls: TLS? = nil, + connectionKeepalive: ServerConnectionKeepalive = ServerConnectionKeepalive(), + connectionIdleTimeout: TimeAmount = .nanoseconds(.max), + messageEncoding: ServerMessageEncoding = .disabled, + httpTargetWindowSize: Int = 8 * 1024 * 1024, + logger: Logger = Logger(label: "io.grpc", factory: { _ in SwiftLogNoOpLogHandler() }), + debugChannelInitializer: ((Channel) -> EventLoopFuture)? = nil + ) { + self.target = target + self.eventLoopGroup = eventLoopGroup + self + .serviceProvidersByName = Dictionary( + uniqueKeysWithValues: serviceProviders + .map { ($0.serviceName, $0) } + ) + self.errorDelegate = errorDelegate + self.tlsConfiguration = tls.map { GRPCTLSConfiguration(transforming: $0) } + self.connectionKeepalive = connectionKeepalive + self.connectionIdleTimeout = connectionIdleTimeout + self.messageEncoding = messageEncoding + self.httpTargetWindowSize = httpTargetWindowSize + self.logger = logger + self.debugChannelInitializer = debugChannelInitializer + } + #endif // canImport(NIOSSL) + + private init( + eventLoopGroup: EventLoopGroup, + target: BindTarget, + serviceProviders: [CallHandlerProvider] + ) { + self.eventLoopGroup = eventLoopGroup + self.target = target + self.serviceProvidersByName = Dictionary(uniqueKeysWithValues: serviceProviders.map { + ($0.serviceName, $0) + }) + } + + /// Make a new configuration using default values. + /// + /// - Parameters: + /// - target: The target to bind to. + /// - eventLoopGroup: The `EventLoopGroup` the server should run on. + /// - serviceProviders: An array of `CallHandlerProvider`s which the server should use + /// to handle requests. + /// - Returns: A configuration with default values set. + public static func `default`( + target: BindTarget, + eventLoopGroup: EventLoopGroup, + serviceProviders: [CallHandlerProvider] + ) -> Configuration { + return .init( + eventLoopGroup: eventLoopGroup, + target: target, + serviceProviders: serviceProviders + ) + } + } +} + +extension ServerBootstrapProtocol { + fileprivate func bind(to target: BindTarget) -> EventLoopFuture { + switch target.wrapped { + case let .hostAndPort(host, port): + return self.bind(host: host, port: port) + + case let .unixDomainSocket(path): + return self.bind(unixDomainSocketPath: path) + + case let .socketAddress(address): + return self.bind(to: address) + + case let .connectedSocket(socket): + return self.withBoundSocket(socket) + } + } +} + +extension Comparable { + internal func clamped(to range: ClosedRange) -> Self { + return min(max(self, range.lowerBound), range.upperBound) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder+NIOSSL.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder+NIOSSL.swift new file mode 100644 index 00000000..c71badbd --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder+NIOSSL.swift @@ -0,0 +1,79 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if canImport(NIOSSL) +import NIOCore +import NIOSSL + +extension Server { + /// Returns a `Server` builder configured with TLS. + @available( + *, deprecated, + message: "Use one of 'usingTLSBackedByNIOSSL(on:certificateChain:privateKey:)', 'usingTLSBackedByNetworkFramework(on:with:)' or 'usingTLS(with:on:)'" + ) + public static func secure( + group: EventLoopGroup, + certificateChain: [NIOSSLCertificate], + privateKey: NIOSSLPrivateKey + ) -> Builder.Secure { + return Server.usingTLSBackedByNIOSSL( + on: group, + certificateChain: certificateChain, + privateKey: privateKey + ) + } + + /// Returns a `Server` builder configured with the 'NIOSSL' TLS backend. + /// + /// This builder may use either a `MultiThreadedEventLoopGroup` or a `NIOTSEventLoopGroup` (or an + /// `EventLoop` from either group). + public static func usingTLSBackedByNIOSSL( + on group: EventLoopGroup, + certificateChain: [NIOSSLCertificate], + privateKey: NIOSSLPrivateKey + ) -> Builder.Secure { + return Builder.Secure( + group: group, + tlsConfiguration: .makeServerConfigurationBackedByNIOSSL( + certificateChain: certificateChain.map { .certificate($0) }, + privateKey: .privateKey(privateKey) + ) + ) + } +} + +extension Server.Builder.Secure { + /// Sets the trust roots to use to validate certificates. This only needs to be provided if you + /// intend to validate certificates. Defaults to the system provided trust store (`.default`) if + /// not set. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(trustRoots: NIOSSLTrustRoots) -> Self { + self.tls.updateNIOTrustRoots(to: trustRoots) + return self + } + + /// Sets whether certificates should be verified. Defaults to `.none` if not set. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(certificateVerification: CertificateVerification) -> Self { + self.tls.updateNIOCertificateVerification(to: certificateVerification) + return self + } +} + +#endif // canImport(NIOSSL) diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder.swift new file mode 100644 index 00000000..3082d48c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerBuilder.swift @@ -0,0 +1,232 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore + +#if canImport(Network) +import Security +#endif + +extension Server { + public class Builder { + private var configuration: Server.Configuration + private var maybeTLS: GRPCTLSConfiguration? { return nil } + + fileprivate init(group: EventLoopGroup) { + self.configuration = .default( + // This is okay: the configuration is only consumed on a call to `bind` which sets the host + // and port. + target: .hostAndPort("", .max), + eventLoopGroup: group, + serviceProviders: [] + ) + } + + public class Secure: Builder { + internal var tls: GRPCTLSConfiguration + override var maybeTLS: GRPCTLSConfiguration? { + return self.tls + } + + internal init(group: EventLoopGroup, tlsConfiguration: GRPCTLSConfiguration) { + group.preconditionCompatible(with: tlsConfiguration) + self.tls = tlsConfiguration + super.init(group: group) + } + } + + public func bind(host: String, port: Int) -> EventLoopFuture { + // Finish setting up the configuration. + self.configuration.target = .hostAndPort(host, port) + self.configuration.tlsConfiguration = self.maybeTLS + return Server.start(configuration: self.configuration) + } + + public func bind(unixDomainSocketPath path: String) -> EventLoopFuture { + self.configuration.target = .unixDomainSocket(path) + self.configuration.tlsConfiguration = self.maybeTLS + return Server.start(configuration: self.configuration) + } + } +} + +extension Server.Builder { + /// Sets the server error delegate. + @discardableResult + public func withErrorDelegate(_ delegate: ServerErrorDelegate?) -> Self { + self.configuration.errorDelegate = delegate + return self + } +} + +extension Server.Builder { + /// Sets the service providers that this server should offer. Note that calling this multiple + /// times will override any previously set providers. + @discardableResult + public func withServiceProviders(_ providers: [CallHandlerProvider]) -> Self { + self.configuration.serviceProviders = providers + return self + } +} + +extension Server.Builder { + @discardableResult + public func withKeepalive(_ keepalive: ServerConnectionKeepalive) -> Self { + self.configuration.connectionKeepalive = keepalive + return self + } +} + +extension Server.Builder { + /// The amount of time to wait before closing connections. The idle timeout will start only + /// if there are no RPCs in progress and will be cancelled as soon as any RPCs start. Unless a + /// an idle timeout it set connections will not be idled by default. + @discardableResult + public func withConnectionIdleTimeout(_ timeout: TimeAmount) -> Self { + self.configuration.connectionIdleTimeout = timeout + return self + } +} + +extension Server.Builder { + /// Sets the message compression configuration. Compression is disabled if this is not configured + /// and any RPCs using compression will not be accepted. + @discardableResult + public func withMessageCompression(_ encoding: ServerMessageEncoding) -> Self { + self.configuration.messageEncoding = encoding + return self + } + + /// Sets the maximum message size in bytes the server may receive. + /// + /// - Precondition: `limit` must not be negative. + @discardableResult + public func withMaximumReceiveMessageLength(_ limit: Int) -> Self { + self.configuration.maximumReceiveMessageLength = limit + return self + } +} + +extension Server.Builder.Secure { + /// Sets whether the server's TLS handshake requires a protocol to be negotiated via ALPN. This + /// defaults to `true` if not otherwise set. + /// + /// If this option is set to `false` and no protocol is negotiated via ALPN then the server will + /// parse the initial bytes on the connection to determine whether HTTP/2 or HTTP/1.1 (gRPC-Web) + /// is being used and configure the connection appropriately. + /// + /// - Note: May only be used with the 'NIOSSL' TLS backend. + @discardableResult + public func withTLS(requiringALPN: Bool) -> Self { + self.tls.requireALPN = requiringALPN + return self + } +} + +extension Server.Builder { + /// Sets the HTTP/2 flow control target window size. Defaults to 8MB if not explicitly set. + /// Values are clamped between 1 and 2^31-1 inclusive. + @discardableResult + public func withHTTPTargetWindowSize(_ httpTargetWindowSize: Int) -> Self { + self.configuration.httpTargetWindowSize = httpTargetWindowSize + return self + } + + /// Sets the maximum allowed number of concurrent HTTP/2 streams a client may open for a given + /// connection. Defaults to 100. + @discardableResult + public func withHTTPMaxConcurrentStreams(_ httpMaxConcurrentStreams: Int) -> Self { + self.configuration.httpMaxConcurrentStreams = httpMaxConcurrentStreams + return self + } + + /// Sets the HTTP/2 max frame size. Defaults to 16384. Value are clamped between 2^14 and 2^24-1 + /// octets inclusive (the minimum and maximum permitted values per RFC 7540 § 4.2). + /// + /// Raising this value may lower CPU usage for large message at the cost of increasing head of + /// line blocking for small messages. + @discardableResult + public func withHTTPMaxFrameSize(_ httpMaxFrameSize: Int) -> Self { + self.configuration.httpMaxFrameSize = httpMaxFrameSize + return self + } +} + +extension Server.Builder { + /// Sets the root server logger. Accepted connections will branch from this logger and RPCs on + /// each connection will use a logger branched from the connections logger. This logger is made + /// available to service providers via `context`. Defaults to a no-op logger. + @discardableResult + public func withLogger(_ logger: Logger) -> Self { + self.configuration.logger = logger + return self + } +} + +extension Server.Builder { + /// A channel initializer which will be run after gRPC has initialized each accepted channel. + /// This may be used to add additional handlers to the pipeline and is intended for debugging. + /// This is analogous to `NIO.ServerBootstrap.childChannelInitializer`. + /// + /// - Warning: The initializer closure may be invoked *multiple times*. More precisely: it will + /// be invoked at most once per accepted connection. + @discardableResult + public func withDebugChannelInitializer( + _ debugChannelInitializer: @escaping (Channel) -> EventLoopFuture + ) -> Self { + self.configuration.debugChannelInitializer = debugChannelInitializer + return self + } +} + +extension Server { + /// Returns an insecure `Server` builder which is *not configured with TLS*. + public static func insecure(group: EventLoopGroup) -> Builder { + return Builder(group: group) + } + + #if canImport(Network) + /// Returns a `Server` builder configured with the 'Network.framework' TLS backend. + /// + /// This builder must use a `NIOTSEventLoopGroup`. + @available(macOS 10.14, iOS 12.0, watchOS 6.0, tvOS 12.0, *) + public static func usingTLSBackedByNetworkFramework( + on group: EventLoopGroup, + with identity: SecIdentity + ) -> Builder.Secure { + precondition( + PlatformSupport.isTransportServicesEventLoopGroup(group), + "'usingTLSBackedByNetworkFramework(on:with:)' requires 'eventLoopGroup' to be a 'NIOTransportServices.NIOTSEventLoopGroup' or 'NIOTransportServices.QoSEventLoop' (but was '\(type(of: group))'" + ) + return Builder.Secure( + group: group, + tlsConfiguration: .makeServerConfigurationBackedByNetworkFramework(identity: identity) + ) + } + #endif + + /// Returns a `Server` builder configured with the TLS backend appropriate for the + /// provided `configuration` and `EventLoopGroup`. + /// + /// - Important: The caller is responsible for ensuring the provided `configuration` may be used + /// the the `group`. + public static func usingTLS( + with configuration: GRPCTLSConfiguration, + on group: EventLoopGroup + ) -> Builder.Secure { + return Builder.Secure(group: group, tlsConfiguration: configuration) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/ServerCallContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/ServerCallContext.swift new file mode 100644 index 00000000..e229836d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/ServerCallContext.swift @@ -0,0 +1,182 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import SwiftProtobuf + +/// Protocol declaring a minimum set of properties exposed by *all* types of call contexts. +public protocol ServerCallContext: AnyObject { + /// The event loop this call is served on. + var eventLoop: EventLoop { get } + + /// Request headers for this request. + var headers: HPACKHeaders { get } + + /// A 'UserInfo' dictionary which is shared with the interceptor contexts for this RPC. + var userInfo: UserInfo { get set } + + /// The logger used for this call. + var logger: Logger { get } + + /// Whether compression should be enabled for responses, defaulting to `true`. Note that for + /// this value to take effect compression must have been enabled on the server and a compression + /// algorithm must have been negotiated with the client. + var compressionEnabled: Bool { get set } + + /// A future which completes when the call closes. This may be used to register callbacks which + /// free up resources used by the RPC. + var closeFuture: EventLoopFuture { get } +} + +extension ServerCallContext { + // Default implementation to avoid breaking API. + public var closeFuture: EventLoopFuture { + return self.eventLoop.makeFailedFuture(GRPCStatus.closeFutureNotImplemented) + } +} + +extension GRPCStatus { + internal static let closeFutureNotImplemented = GRPCStatus( + code: .unimplemented, + message: "This context type has not implemented support for a 'closeFuture'" + ) +} + +/// Base class providing data provided to the framework user for all server calls. +open class ServerCallContextBase: ServerCallContext { + /// The event loop this call is served on. + public let eventLoop: EventLoop + + /// Request headers for this request. + public let headers: HPACKHeaders + + /// The logger used for this call. + public let logger: Logger + + /// Whether compression should be enabled for responses, defaulting to `true`. Note that for + /// this value to take effect compression must have been enabled on the server and a compression + /// algorithm must have been negotiated with the client. + /// + /// - Important: This *must* be accessed from the context's `eventLoop` in order to ensure + /// thread-safety. + public var compressionEnabled: Bool { + get { + self.eventLoop.assertInEventLoop() + return self._compressionEnabled + } + set { + self.eventLoop.assertInEventLoop() + self._compressionEnabled = newValue + } + } + + private var _compressionEnabled: Bool = true + + /// A `UserInfo` dictionary which is shared with the interceptor contexts for this RPC. + /// + /// - Important: While `UserInfo` has value-semantics, this property retrieves from, and sets a + /// reference wrapped `UserInfo`. The contexts passed to interceptors provide the same + /// reference. As such this may be used as a mechanism to pass information between interceptors + /// and service providers. + /// - Important: This *must* be accessed from the context's `eventLoop` in order to ensure + /// thread-safety. + public var userInfo: UserInfo { + get { + self.eventLoop.assertInEventLoop() + return self.userInfoRef.value + } + set { + self.eventLoop.assertInEventLoop() + self.userInfoRef.value = newValue + } + } + + /// A reference to an underlying `UserInfo`. We share this with the interceptors. + @usableFromInline + internal let userInfoRef: Ref + + /// Metadata to return at the end of the RPC. If this is required it should be updated before + /// the `responsePromise` or `statusPromise` is fulfilled. + /// + /// - Important: This *must* be accessed from the context's `eventLoop` in order to ensure + /// thread-safety. + public var trailers: HPACKHeaders { + get { + self.eventLoop.assertInEventLoop() + return self._trailers + } + set { + self.eventLoop.assertInEventLoop() + self._trailers = newValue + } + } + + private var _trailers: HPACKHeaders = [:] + + /// A future which completes when the call closes. This may be used to register callbacks which + /// free up resources used by the RPC. + public let closeFuture: EventLoopFuture + + @available(*, deprecated, renamed: "init(eventLoop:headers:logger:userInfo:closeFuture:)") + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo() + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: eventLoop.makeFailedFuture(GRPCStatus.closeFutureNotImplemented) + ) + } + + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo(), + closeFuture: EventLoopFuture + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: closeFuture + ) + } + + @inlinable + internal init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfoRef: Ref, + closeFuture: EventLoopFuture + ) { + self.eventLoop = eventLoop + self.headers = headers + self.userInfoRef = userInfoRef + self.logger = logger + self.closeFuture = closeFuture + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/StreamingResponseCallContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/StreamingResponseCallContext.swift new file mode 100644 index 00000000..614cc2c3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/StreamingResponseCallContext.swift @@ -0,0 +1,260 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import SwiftProtobuf + +/// An abstract base class for a context provided to handlers for RPCs which may return multiple +/// responses, i.e. server streaming and bidirectional streaming RPCs. +open class StreamingResponseCallContext: ServerCallContextBase { + /// A promise for the `GRPCStatus`, the end of the response stream. This must be completed by + /// bidirectional streaming RPC handlers to end the RPC. + /// + /// Note that while this is also present for server streaming RPCs, it is not necessary to + /// complete this promise: instead, an `EventLoopFuture` must be returned from the + /// handler. + public let statusPromise: EventLoopPromise + + @available(*, deprecated, renamed: "init(eventLoop:headers:logger:userInfo:closeFuture:)") + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo() + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: eventLoop.makeFailedFuture(GRPCStatus.closeFutureNotImplemented) + ) + } + + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo(), + closeFuture: EventLoopFuture + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: closeFuture + ) + } + + @inlinable + override internal init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfoRef: Ref, + closeFuture: EventLoopFuture + ) { + self.statusPromise = eventLoop.makePromise() + super.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: userInfoRef, + closeFuture: closeFuture + ) + } + + /// Send a response to the client. + /// + /// - Parameters: + /// - message: The message to send to the client. + /// - compression: Whether compression should be used for this response. If compression + /// is enabled in the call context, the value passed here takes precedence. Defaults to + /// deferring to the value set on the call context. + /// - promise: A promise to complete once the message has been sent. + open func sendResponse( + _ message: ResponsePayload, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) { + fatalError("needs to be overridden") + } + + /// Send a response to the client. + /// + /// - Parameters: + /// - message: The message to send to the client. + /// - compression: Whether compression should be used for this response. If compression + /// is enabled in the call context, the value passed here takes precedence. Defaults to + /// deferring to the value set on the call context. + open func sendResponse( + _ message: ResponsePayload, + compression: Compression = .deferToCallDefault + ) -> EventLoopFuture { + let promise = self.eventLoop.makePromise(of: Void.self) + self.sendResponse(message, compression: compression, promise: promise) + return promise.futureResult + } + + /// Sends a sequence of responses to the client. + /// - Parameters: + /// - messages: The messages to send to the client. + /// - compression: Whether compression should be used for this response. If compression + /// is enabled in the call context, the value passed here takes precedence. Defaults to + /// deferring to the value set on the call context. + /// - promise: A promise to complete once the messages have been sent. + open func sendResponses( + _ messages: Messages, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) where Messages.Element == ResponsePayload { + fatalError("needs to be overridden") + } + + /// Sends a sequence of responses to the client. + /// - Parameters: + /// - messages: The messages to send to the client. + /// - compression: Whether compression should be used for this response. If compression + /// is enabled in the call context, the value passed here takes precedence. Defaults to + /// deferring to the value set on the call context. + open func sendResponses( + _ messages: Messages, + compression: Compression = .deferToCallDefault + ) -> EventLoopFuture where Messages.Element == ResponsePayload { + let promise = self.eventLoop.makePromise(of: Void.self) + self.sendResponses(messages, compression: compression, promise: promise) + return promise.futureResult + } +} + +/// A concrete implementation of `StreamingResponseCallContext` used internally. +@usableFromInline +internal final class _StreamingResponseCallContext: + StreamingResponseCallContext { + @usableFromInline + internal let _sendResponse: (Response, MessageMetadata, EventLoopPromise?) -> Void + + @usableFromInline + internal let _compressionEnabledOnServer: Bool + + @inlinable + internal init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfoRef: Ref, + compressionIsEnabled: Bool, + closeFuture: EventLoopFuture, + sendResponse: @escaping (Response, MessageMetadata, EventLoopPromise?) -> Void + ) { + self._sendResponse = sendResponse + self._compressionEnabledOnServer = compressionIsEnabled + super.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: userInfoRef, + closeFuture: closeFuture + ) + } + + @inlinable + internal func shouldCompress(_ compression: Compression) -> Bool { + guard self._compressionEnabledOnServer else { + return false + } + return compression.isEnabled(callDefault: self.compressionEnabled) + } + + @inlinable + override func sendResponse( + _ message: Response, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) { + if self.eventLoop.inEventLoop { + let compress = self.shouldCompress(compression) + self._sendResponse(message, .init(compress: compress, flush: true), promise) + } else { + self.eventLoop.execute { + let compress = self.shouldCompress(compression) + self._sendResponse(message, .init(compress: compress, flush: true), promise) + } + } + } + + @inlinable + override func sendResponses( + _ messages: Messages, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) where Response == Messages.Element { + if self.eventLoop.inEventLoop { + self._sendResponses(messages, compression: compression, promise: promise) + } else { + self.eventLoop.execute { + self._sendResponses(messages, compression: compression, promise: promise) + } + } + } + + @inlinable + internal func _sendResponses( + _ messages: Messages, + compression: Compression, + promise: EventLoopPromise? + ) where Response == Messages.Element { + let compress = self.shouldCompress(compression) + var iterator = messages.makeIterator() + var next = iterator.next() + + while let current = next { + next = iterator.next() + // Attach the promise, if present, to the last message. + let isLast = next == nil + self._sendResponse(current, .init(compress: compress, flush: isLast), isLast ? promise : nil) + } + } +} + +/// Concrete implementation of `StreamingResponseCallContext` used for testing. +/// +/// Simply records all sent messages. +open class StreamingResponseCallContextTestStub: StreamingResponseCallContext { + open var recordedResponses: [ResponsePayload] = [] + + override open func sendResponse( + _ message: ResponsePayload, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) { + self.recordedResponses.append(message) + promise?.succeed(()) + } + + override open func sendResponses( + _ messages: Messages, + compression: Compression = .deferToCallDefault, + promise: EventLoopPromise? + ) where ResponsePayload == Messages.Element { + self.recordedResponses.append(contentsOf: messages) + promise?.succeed(()) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/UnaryResponseCallContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/UnaryResponseCallContext.swift new file mode 100644 index 00000000..252f2c46 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerCallContexts/UnaryResponseCallContext.swift @@ -0,0 +1,122 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import Logging +import NIOCore +import NIOHPACK +import NIOHTTP1 +import SwiftProtobuf + +/// A context provided to handlers for RPCs which return a single response, i.e. unary and client +/// streaming RPCs. +/// +/// For client streaming RPCs the handler must complete the `responsePromise` to return the response +/// to the client. Unary RPCs do complete the promise directly: they are provided an +/// `StatusOnlyCallContext` view of this context where the `responsePromise` is not exposed. Instead +/// they must return an `EventLoopFuture` from the method they are implementing. +open class UnaryResponseCallContext: ServerCallContextBase, StatusOnlyCallContext { + /// A promise for a single response message. This must be completed to send a response back to the + /// client. If the promise is failed, the failure value will be converted to `GRPCStatus` and + /// used as the final status for the RPC. + public let responsePromise: EventLoopPromise + + /// The status sent back to the client at the end of the RPC, providing the `responsePromise` was + /// completed successfully. + /// + /// - Important: This *must* be accessed from the context's `eventLoop` in order to ensure + /// thread-safety. + public var responseStatus: GRPCStatus { + get { + self.eventLoop.assertInEventLoop() + return self._responseStatus + } + set { + self.eventLoop.assertInEventLoop() + self._responseStatus = newValue + } + } + + private var _responseStatus: GRPCStatus = .ok + + @available(*, deprecated, renamed: "init(eventLoop:headers:logger:userInfo:closeFuture:)") + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo() + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: eventLoop.makeFailedFuture(GRPCStatus.closeFutureNotImplemented) + ) + } + + public convenience init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfo: UserInfo = UserInfo(), + closeFuture: EventLoopFuture + ) { + self.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: .init(userInfo), + closeFuture: closeFuture + ) + } + + @inlinable + override internal init( + eventLoop: EventLoop, + headers: HPACKHeaders, + logger: Logger, + userInfoRef: Ref, + closeFuture: EventLoopFuture + ) { + self.responsePromise = eventLoop.makePromise() + super.init( + eventLoop: eventLoop, + headers: headers, + logger: logger, + userInfoRef: userInfoRef, + closeFuture: closeFuture + ) + } +} + +/// Protocol variant of `UnaryResponseCallContext` that only exposes the `responseStatus` and `trailingMetadata` +/// fields, but not `responsePromise`. +/// +/// We can use a protocol (instead of an abstract base class) here because removing the generic +/// `responsePromise` field lets us avoid associated-type requirements on the protocol. +public protocol StatusOnlyCallContext: ServerCallContext { + /// The status sent back to the client at the end of the RPC, providing the `responsePromise` was + /// completed successfully. + var responseStatus: GRPCStatus { get set } + + /// Metadata to return at the end of the RPC. + var trailers: HPACKHeaders { get set } +} + +/// Concrete implementation of `UnaryResponseCallContext` used for testing. +/// +/// Only provided to make it clear in tests that no "real" implementation is used. +open class UnaryResponseCallContextTestStub: UnaryResponseCallContext {} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerChannelErrorHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerChannelErrorHandler.swift new file mode 100644 index 00000000..b37b7ece --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerChannelErrorHandler.swift @@ -0,0 +1,45 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +/// A handler that passes errors thrown into the server channel to the server error delegate. +/// +/// A NIO server bootstrap produces two kinds of channels. The first and most common is the "child" channel: +/// each of these corresponds to one connection, and has the connection state stored on it. The other kind is +/// the "server" channel. Each bootstrap produces only one of these, and it is the channel that owns the listening +/// socket. +/// +/// This channel handler is inserted into the server channel, and is responsible for passing any errors in that pipeline +/// to the server error delegate. If there is no error delegate, this handler is not inserted into the pipeline. +final class ServerChannelErrorHandler { + private let errorDelegate: ServerErrorDelegate + + init(errorDelegate: ServerErrorDelegate) { + self.errorDelegate = errorDelegate + } +} + +extension ServerChannelErrorHandler: ChannelInboundHandler { + typealias InboundIn = Any + typealias InboundOut = Any + + func errorCaught(context: ChannelHandlerContext, error: Error) { + // This handler does not treat errors as fatal to the listening socket, as it's possible they were transiently + // occurring in a single connection setup attempt. + self.errorDelegate.observeLibraryError(error) + context.fireErrorCaught(error) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorDelegate.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorDelegate.swift new file mode 100644 index 00000000..69f188d0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorDelegate.swift @@ -0,0 +1,83 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation +import NIOCore +import NIOHPACK +import NIOHTTP1 + +public protocol ServerErrorDelegate: AnyObject { + //! FIXME: Provide more context about where the error was thrown, i.e. using `GRPCError`. + /// Called when an error is thrown in the channel pipeline. + func observeLibraryError(_ error: Error) + + /// Transforms the given error (thrown somewhere inside the gRPC library) into a new error. + /// + /// This allows library users to transform errors which may be out of their control + /// into more meaningful `GRPCStatus` errors before they are sent to the user. + /// + /// - note: + /// Errors returned by this method are not passed to `observe` again. + /// + /// - note: + /// This defaults to returning `nil`. In that case, if the original error conforms to `GRPCStatusTransformable`, + /// that error's `asGRPCStatus()` result will be sent to the user. If that's not the case, either, + /// `GRPCStatus.processingError` is returned. + func transformLibraryError(_ error: Error) -> GRPCStatusAndTrailers? + + /// Called when a request's status or response promise is failed somewhere in the user-provided request handler code. + /// - Parameters: + /// - error: The original error the status/response promise was failed with. + /// - headers: The headers of the request whose status/response promise was failed. + func observeRequestHandlerError(_ error: Error, headers: HPACKHeaders) + + /// Transforms the given status or response promise failure into a new error. + /// + /// This allows library users to transform errors which happen during their handling of the request + /// into more meaningful `GRPCStatus` errors before they are sent to the user. + /// + /// - note: + /// Errors returned by this method are not passed to `observe` again. + /// + /// - note: + /// This defaults to returning `nil`. In that case, if the original error conforms to `GRPCStatusTransformable`, + /// that error's `asGRPCStatus()` result will be sent to the user. If that's not the case, either, + /// `GRPCStatus.processingError` is returned. + /// + /// - Parameters: + /// - error: The original error the status/response promise was failed with. + /// - headers: The headers of the request whose status/response promise was failed. + func transformRequestHandlerError( + _ error: Error, + headers: HPACKHeaders + ) -> GRPCStatusAndTrailers? +} + +extension ServerErrorDelegate { + public func observeLibraryError(_ error: Error) {} + + public func transformLibraryError(_ error: Error) -> GRPCStatusAndTrailers? { + return nil + } + + public func observeRequestHandlerError(_ error: Error, headers: HPACKHeaders) {} + + public func transformRequestHandlerError( + _ error: Error, + headers: HPACKHeaders + ) -> GRPCStatusAndTrailers? { + return nil + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorProcessor.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorProcessor.swift new file mode 100644 index 00000000..b0993ed6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/ServerErrorProcessor.swift @@ -0,0 +1,93 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOHPACK + +@usableFromInline +internal enum ServerErrorProcessor { + /// Processes a library error to form a `GRPCStatus` and trailers to send back to the client. + /// - Parameter error: The error to process. + /// - Returns: The status and trailers to send to the client. + @usableFromInline + internal static func processLibraryError( + _ error: Error, + delegate: ServerErrorDelegate? + ) -> (GRPCStatus, HPACKHeaders) { + // Observe the error if we have a delegate. + delegate?.observeLibraryError(error) + + // What status are we terminating this RPC with? + // - If we have a delegate, try transforming the error. If the delegate returns trailers, merge + // them with any on the call context. + // - If we don't have a delegate, then try to transform the error to a status. + // - Fallback to a generic error. + let status: GRPCStatus + let trailers: HPACKHeaders + + if let transformed = delegate?.transformLibraryError(error) { + status = transformed.status + trailers = transformed.trailers ?? [:] + } else if let grpcStatusTransformable = error as? GRPCStatusTransformable { + status = grpcStatusTransformable.makeGRPCStatus() + trailers = [:] + } else { + // Eh... well, we don't what status to use. Use a generic one. + status = .processingError(cause: error) + trailers = [:] + } + + return (status, trailers) + } + + /// Processes an error, transforming it into a 'GRPCStatus' and any trailers to send to the peer. + @usableFromInline + internal static func processObserverError( + _ error: Error, + headers: HPACKHeaders, + trailers: HPACKHeaders, + delegate: ServerErrorDelegate? + ) -> (GRPCStatus, HPACKHeaders) { + // Observe the error if we have a delegate. + delegate?.observeRequestHandlerError(error, headers: headers) + + // What status are we terminating this RPC with? + // - If we have a delegate, try transforming the error. If the delegate returns trailers, merge + // them with any on the call context. + // - If we don't have a delegate, then try to transform the error to a status. + // - Fallback to a generic error. + let status: GRPCStatus + let mergedTrailers: HPACKHeaders + + if let transformed = delegate?.transformRequestHandlerError(error, headers: headers) { + status = transformed.status + if var transformedTrailers = transformed.trailers { + // The delegate returned trailers: merge in those from the context as well. + transformedTrailers.add(contentsOf: trailers) + mergedTrailers = transformedTrailers + } else { + mergedTrailers = trailers + } + } else if let grpcStatusTransformable = error as? GRPCStatusTransformable { + status = grpcStatusTransformable.makeGRPCStatus() + mergedTrailers = trailers + } else { + // Eh... well, we don't what status to use. Use a generic one. + status = .processingError(cause: error) + mergedTrailers = trailers + } + + return (status, mergedTrailers) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Stopwatch.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Stopwatch.swift new file mode 100644 index 00000000..f3dff775 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Stopwatch.swift @@ -0,0 +1,38 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Foundation + +internal class Stopwatch { + private let dateProvider: () -> Date + private let start: Date + + init(provider: @escaping () -> Date = { Date() }) { + self.dateProvider = provider + self.start = provider() + } + + static func start() -> Stopwatch { + return Stopwatch() + } + + func elapsed() -> TimeInterval { + return self.dateProvider().timeIntervalSince(self.start) + } + + func elapsedMillis() -> Int64 { + return Int64(self.elapsed() * 1000) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/StreamEvent.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/StreamEvent.swift new file mode 100644 index 00000000..63922097 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/StreamEvent.swift @@ -0,0 +1,23 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import SwiftProtobuf + +/// An event that can occur on a client-streaming RPC. Provided to the event observer registered for that call. +public enum StreamEvent { + case message(Message) + case end + //! FIXME: Also support errors in this type, to propagate them to the event handler. +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TLSVerificationHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TLSVerificationHandler.swift new file mode 100644 index 00000000..c8b20044 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TLSVerificationHandler.swift @@ -0,0 +1,65 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOTLS + +/// Application protocol identifiers for ALPN. +internal enum GRPCApplicationProtocolIdentifier { + static let gRPC = "grpc-exp" + static let h2 = "h2" + static let http1_1 = "http/1.1" + + static let client = [gRPC, h2] + static let server = [gRPC, h2, http1_1] + + static func isHTTP2Like(_ value: String) -> Bool { + switch value { + case self.gRPC, self.h2: + return true + default: + return false + } + } + + static func isHTTP1(_ value: String) -> Bool { + return value == self.http1_1 + } +} + +internal class TLSVerificationHandler: ChannelInboundHandler, RemovableChannelHandler { + typealias InboundIn = Any + private let logger: Logger + + init(logger: Logger) { + self.logger = logger + } + + func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) { + if let tlsEvent = event as? TLSUserEvent { + switch tlsEvent { + case let .handshakeCompleted(negotiatedProtocol: .some(`protocol`)): + self.logger.debug("TLS handshake completed, negotiated protocol: \(`protocol`)") + case .handshakeCompleted(negotiatedProtocol: nil): + self.logger.debug("TLS handshake completed, no protocol negotiated") + case .shutdownCompleted: + () + } + } + + context.fireUserInboundEventTriggered(event) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TimeLimit.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TimeLimit.swift new file mode 100644 index 00000000..a44d3ff6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/TimeLimit.swift @@ -0,0 +1,125 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Dispatch +#if swift(>=5.6) +@preconcurrency import NIOCore +#else +import NIOCore +#endif // swift(>=5.6) + +/// A time limit for an RPC. +/// +/// RPCs may have a time limit imposed on them by a caller which may be timeout or deadline based. +/// If the RPC has not completed before the limit is reached then the call will be cancelled and +/// completed with a `.deadlineExceeded` status code. +/// +/// - Note: Servers may impose a time limit on an RPC independent of the client's time limit; RPCs +/// may therefore complete with `.deadlineExceeded` even if no time limit was set by the client. +public struct TimeLimit: Equatable, CustomStringConvertible, GRPCSendable { + // private but for shimming. + private enum Wrapped: Equatable, GRPCSendable { + case none + case timeout(TimeAmount) + case deadline(NIODeadline) + } + + // private but for shimming. + private var wrapped: Wrapped + + private init(_ wrapped: Wrapped) { + self.wrapped = wrapped + } + + /// No time limit, the RPC will not be automatically cancelled by the client. Note: some services + /// may impose a time limit on RPCs independent of the client's time limit. + public static let none = TimeLimit(.none) + + /// Create a timeout before which the RPC must have completed. Failure to complete before the + /// deadline will result in the RPC being cancelled. + /// + /// - Note: The timeout is started once the call has been invoked and the call may timeout waiting + /// for an active connection. + public static func timeout(_ timeout: TimeAmount) -> TimeLimit { + return TimeLimit(.timeout(timeout)) + } + + /// Create a point in time by which the RPC must have completed. Failure to complete before the + /// deadline will result in the RPC being cancelled. + public static func deadline(_ deadline: NIODeadline) -> TimeLimit { + return TimeLimit(.deadline(deadline)) + } + + /// Return the timeout, if one was set. + public var timeout: TimeAmount? { + switch self.wrapped { + case let .timeout(timeout): + return timeout + + case .none, .deadline: + return nil + } + } + + /// Return the deadline, if one was set. + public var deadline: NIODeadline? { + switch self.wrapped { + case let .deadline(deadline): + return deadline + + case .none, .timeout: + return nil + } + } +} + +extension TimeLimit { + /// Make a non-distant-future deadline from the give time limit. + @usableFromInline + internal func makeDeadline() -> NIODeadline { + switch self.wrapped { + case .none: + return .distantFuture + + case let .timeout(timeout) where timeout.nanoseconds == .max: + return .distantFuture + + case let .timeout(timeout): + return .now() + timeout + + case let .deadline(deadline): + return deadline + } + } + + public var description: String { + switch self.wrapped { + case .none: + return "none" + + case let .timeout(timeout) where timeout.nanoseconds == .max: + return "timeout=never" + + case let .timeout(timeout): + return "timeout=\(timeout.nanoseconds) nanoseconds" + + case let .deadline(deadline) where deadline == .distantFuture: + return "deadline=.distantFuture" + + case let .deadline(deadline): + return "deadline=\(deadline.uptimeNanoseconds) uptimeNanoseconds" + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/UserInfo.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/UserInfo.swift new file mode 100644 index 00000000..b388c27c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/UserInfo.swift @@ -0,0 +1,109 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// `UserInfo` is a dictionary for heterogeneously typed values with type safe access to the stored +/// values. +/// +/// `UserInfo` is shared between server interceptor contexts and server handlers, this is on a +/// per-RPC basis. `UserInfo` is *not* shared across a connection. +/// +/// Values are keyed by a type conforming to the `UserInfo.Key` protocol. The protocol requires an +/// `associatedtype`: the type of the value the key is paired with. A key can be created using a +/// caseless `enum`, for example: +/// +/// ``` +/// enum IDKey: UserInfo.Key { +/// typealias Value = Int +/// } +/// ``` +/// +/// Values can be set and retrieved from `UserInfo` by subscripting with the key: +/// +/// ``` +/// userInfo[IDKey.self] = 42 +/// let id = userInfo[IDKey.self] // id = 42 +/// +/// userInfo[IDKey.self] = nil +/// ``` +/// +/// More convenient access can be provided with helper extensions on `UserInfo`: +/// +/// ``` +/// extension UserInfo { +/// var id: IDKey.Value? { +/// get { self[IDKey.self] } +/// set { self[IDKey.self] = newValue } +/// } +/// } +/// ``` +public struct UserInfo: CustomStringConvertible { + private var storage: [AnyUserInfoKey: Any] + + /// A protocol for a key. + public typealias Key = UserInfoKey + + /// Create an empty 'UserInfo'. + public init() { + self.storage = [:] + } + + /// Allows values to be set and retrieved in a type safe way. + public subscript(key: Key.Type) -> Key.Value? { + get { + if let anyValue = self.storage[AnyUserInfoKey(key)] { + // The types must line up here. + return (anyValue as! Key.Value) + } else { + return nil + } + } + set { + self.storage[AnyUserInfoKey(key)] = newValue + } + } + + public var description: String { + return "[" + self.storage.map { key, value in + "\(key): \(value)" + }.joined(separator: ", ") + "]" + } + + /// A `UserInfoKey` wrapper. + private struct AnyUserInfoKey: Hashable, CustomStringConvertible { + private let keyType: Any.Type + + var description: String { + return String(describing: self.keyType.self) + } + + init(_ keyType: Key.Type) { + self.keyType = keyType + } + + static func == (lhs: AnyUserInfoKey, rhs: AnyUserInfoKey) -> Bool { + return ObjectIdentifier(lhs.keyType) == ObjectIdentifier(rhs.keyType) + } + + func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(self.keyType)) + } + } +} + +public protocol UserInfoKey { + /// The type of identified by this key. + associatedtype Value +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Version.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Version.swift new file mode 100644 index 00000000..7aaa183c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/Version.swift @@ -0,0 +1,29 @@ +/* + * Copyright 2021, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal enum Version { + /// The major version. + internal static let major = 1 + + /// The minor version. + internal static let minor = 8 + + /// The patch version. + internal static let patch = 2 + + /// The version string. + internal static let versionString = "\(major).\(minor).\(patch)" +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WebCORSHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WebCORSHandler.swift new file mode 100644 index 00000000..d851a295 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WebCORSHandler.swift @@ -0,0 +1,98 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOHTTP1 + +/// Handler that manages the CORS protocol for requests incoming from the browser. +internal class WebCORSHandler { + var requestMethod: HTTPMethod? +} + +extension WebCORSHandler: ChannelInboundHandler { + typealias InboundIn = HTTPServerRequestPart + typealias OutboundOut = HTTPServerResponsePart + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + // If the request is OPTIONS, the request is not propagated further. + switch self.unwrapInboundIn(data) { + case let .head(requestHead): + self.requestMethod = requestHead.method + if self.requestMethod == .OPTIONS { + var headers = HTTPHeaders() + headers.add(name: "Access-Control-Allow-Origin", value: "*") + headers.add(name: "Access-Control-Allow-Methods", value: "POST") + headers.add( + name: "Access-Control-Allow-Headers", + value: "content-type,x-grpc-web,x-user-agent" + ) + headers.add(name: "Access-Control-Max-Age", value: "86400") + context.write( + self.wrapOutboundOut(.head(HTTPResponseHead( + version: requestHead.version, + status: .ok, + headers: headers + ))), + promise: nil + ) + return + } + case .body: + if self.requestMethod == .OPTIONS { + // OPTIONS requests do not have a body, but still handle this case to be + // cautious. + return + } + + case .end: + if self.requestMethod == .OPTIONS { + context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil) + self.requestMethod = nil + return + } + } + // The OPTIONS request should be fully handled at this point. + context.fireChannelRead(data) + } +} + +extension WebCORSHandler: ChannelOutboundHandler { + typealias OutboundIn = HTTPServerResponsePart + + func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { + let responsePart = self.unwrapOutboundIn(data) + switch responsePart { + case let .head(responseHead): + var headers = responseHead.headers + // CORS requires all requests to have an Allow-Origin header. + headers.add(name: "Access-Control-Allow-Origin", value: "*") + //! FIXME: Check whether we can let browsers keep connections alive. It's not possible + // now as the channel has a state that can't be reused since the pipeline is modified to + // inject the gRPC call handler. + headers.add(name: "Connection", value: "close") + + context.write( + self.wrapOutboundOut(.head(HTTPResponseHead( + version: responseHead.version, + status: responseHead.status, + headers: headers + ))), + promise: promise + ) + default: + context.write(data, promise: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WriteCapturingHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WriteCapturingHandler.swift new file mode 100644 index 00000000..c8ed4e88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/WriteCapturingHandler.swift @@ -0,0 +1,61 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +/// A handler which redirects all writes into a callback until the `.end` part is seen, after which +/// all writes will be failed. +/// +/// This handler is intended for use with 'fake' response streams the 'FakeChannel'. +internal final class WriteCapturingHandler: ChannelOutboundHandler { + typealias OutboundIn = _GRPCClientRequestPart + typealias RequestHandler = (FakeRequestPart) -> Void + + private var state: State + private enum State { + case active(RequestHandler) + case inactive + } + + internal init(requestHandler: @escaping RequestHandler) { + self.state = .active(requestHandler) + } + + internal func write( + context: ChannelHandlerContext, + data: NIOAny, + promise: EventLoopPromise? + ) { + guard case let .active(handler) = self.state else { + promise?.fail(ChannelError.ioOnClosedChannel) + return + } + + switch self.unwrapOutboundIn(data) { + case let .head(requestHead): + handler(.metadata(requestHead.customMetadata)) + + case let .message(messageContext): + handler(.message(messageContext.message)) + + case .end: + handler(.end) + // We're done now. + self.state = .inactive + } + + promise?.succeed(()) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_EmbeddedThroughput.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_EmbeddedThroughput.swift new file mode 100644 index 00000000..f6e4ed82 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_EmbeddedThroughput.swift @@ -0,0 +1,66 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Logging +import NIOCore +import NIOEmbedded +import SwiftProtobuf + +extension EmbeddedChannel { + /// Configures an `EmbeddedChannel` for the `EmbeddedClientThroughput` benchmark. + /// + /// - Important: This is **not** part of the public API. + public func _configureForEmbeddedThroughputTest( + callType: GRPCCallType, + logger: Logger, + requestType: Request.Type = Request.self, + responseType: Response.Type = Response.self + ) -> EventLoopFuture { + return self.pipeline.addHandlers([ + GRPCClientChannelHandler( + callType: callType, + maximumReceiveMessageLength: .max, + logger: GRPCLogger(wrapping: logger) + ), + GRPCClientCodecHandler( + serializer: ProtobufSerializer(), + deserializer: ProtobufDeserializer() + ), + ]) + } + + public func _configureForEmbeddedServerTest( + servicesByName serviceProviders: [Substring: CallHandlerProvider], + encoding: ServerMessageEncoding, + normalizeHeaders: Bool, + logger: Logger + ) -> EventLoopFuture { + let codec = HTTP2ToRawGRPCServerCodec( + servicesByName: serviceProviders, + encoding: encoding, + errorDelegate: nil, + normalizeHeaders: normalizeHeaders, + maximumReceiveMessageLength: .max, + logger: logger + ) + return self.pipeline.addHandler(codec) + } + + public func _configureForServerFuzzing(configuration: Server.Configuration) throws { + let configurator = GRPCServerPipelineConfigurator(configuration: configuration) + // We're always on an `EmbeddedEventLoop`, this is fine. + try self.pipeline.syncOperations.addHandler(configurator) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_FakeResponseStream.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_FakeResponseStream.swift new file mode 100644 index 00000000..5a2f5b28 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_FakeResponseStream.swift @@ -0,0 +1,350 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore +import NIOEmbedded +import NIOHPACK + +public enum FakeRequestPart { + case metadata(HPACKHeaders) + case message(Request) + case end +} + +extension FakeRequestPart: Equatable where Request: Equatable {} + +/// Sending on a fake response stream would have resulted in a protocol violation (such as +/// sending initial metadata multiple times or sending messages after the stream has closed). +public struct FakeResponseProtocolViolation: Error, Hashable { + /// The reason that sending the message would have resulted in a protocol violation. + public var reason: String + + init(_ reason: String) { + self.reason = reason + } +} + +/// A fake response stream into which users may inject response parts for use in unit tests. +/// +/// Users may not interact with this class directly but may do so via one of its subclasses +/// `FakeUnaryResponse` and `FakeStreamingResponse`. +public class _FakeResponseStream { + private enum StreamEvent { + case responsePart(_GRPCClientResponsePart) + case error(Error) + } + + /// The channel to use for communication. + internal let channel: EmbeddedChannel + + /// A buffer to hold responses in before the proxy is activated. + private var responseBuffer: CircularBuffer + + /// The current state of the proxy. + private var activeState: ActiveState + + /// The state of sending response parts. + private var sendState: SendState + + private enum ActiveState { + case inactive + case active + } + + private enum SendState { + // Nothing has been sent; we can send initial metadata to become 'sending' or trailing metadata + // to start 'closing'. + case idle + + // We're sending messages. We can send more messages in this state or trailing metadata to + // transition to 'closing'. + case sending + + // We're closing: we've sent trailing metadata, we may only send a status now to close. + case closing + + // Closed, nothing more can be sent. + case closed + } + + internal init(requestHandler: @escaping (FakeRequestPart) -> Void) { + self.activeState = .inactive + self.sendState = .idle + self.responseBuffer = CircularBuffer() + self.channel = EmbeddedChannel(handler: WriteCapturingHandler(requestHandler: requestHandler)) + } + + /// Activate the test proxy; this should be called + internal func activate() { + switch self.activeState { + case .inactive: + // Activate the channel. This will allow any request parts to be sent. + self.channel.pipeline.fireChannelActive() + + // Unbuffer any response parts. + while !self.responseBuffer.isEmpty { + self.write(self.responseBuffer.removeFirst()) + } + + // Now we're active. + self.activeState = .active + + case .active: + () + } + } + + /// Write or buffer the response part, depending on the our current state. + internal func _sendResponsePart(_ part: _GRPCClientResponsePart) throws { + try self.send(.responsePart(part)) + } + + internal func _sendError(_ error: Error) throws { + try self.send(.error(error)) + } + + private func send(_ event: StreamEvent) throws { + switch self.validate(event) { + case .valid: + self.writeOrBuffer(event) + + case let .validIfSentAfter(extraPart): + self.writeOrBuffer(extraPart) + self.writeOrBuffer(event) + + case let .invalid(reason): + throw FakeResponseProtocolViolation(reason) + } + } + + /// Validate events the user wants to send on the stream. + private func validate(_ event: StreamEvent) -> Validation { + switch (event, self.sendState) { + case (.responsePart(.initialMetadata), .idle): + self.sendState = .sending + return .valid + + case (.responsePart(.initialMetadata), .sending), + (.responsePart(.initialMetadata), .closing), + (.responsePart(.initialMetadata), .closed): + // We can only send initial metadata from '.idle'. + return .invalid(reason: "Initial metadata has already been sent") + + case (.responsePart(.message), .idle): + // This is fine: we don't force the user to specify initial metadata so we send some on their + // behalf. + self.sendState = .sending + return .validIfSentAfter(.responsePart(.initialMetadata([:]))) + + case (.responsePart(.message), .sending): + return .valid + + case (.responsePart(.message), .closing), + (.responsePart(.message), .closed): + // We can't send messages once we're closing or closed. + return .invalid(reason: "Messages can't be sent after the stream has been closed") + + case (.responsePart(.trailingMetadata), .idle), + (.responsePart(.trailingMetadata), .sending): + self.sendState = .closing + return .valid + + case (.responsePart(.trailingMetadata), .closing), + (.responsePart(.trailingMetadata), .closed): + // We're already closing or closed. + return .invalid(reason: "Trailing metadata can't be sent after the stream has been closed") + + case (.responsePart(.status), .idle), + (.error, .idle), + (.responsePart(.status), .sending), + (.error, .sending), + (.responsePart(.status), .closed), + (.error, .closed): + // We can only error/close if we're closing (i.e. have already sent trailers which we enforce + // from the API in the subclasses). + return .invalid(reason: "Status/error can only be sent after trailing metadata has been sent") + + case (.responsePart(.status), .closing), + (.error, .closing): + self.sendState = .closed + return .valid + } + } + + private enum Validation { + /// Sending the part is valid. + case valid + + /// Sending the part, if it is sent after the given part. + case validIfSentAfter(_ part: StreamEvent) + + /// Sending the part would be a protocol violation. + case invalid(reason: String) + } + + private func writeOrBuffer(_ event: StreamEvent) { + switch self.activeState { + case .inactive: + self.responseBuffer.append(event) + + case .active: + self.write(event) + } + } + + private func write(_ part: StreamEvent) { + switch part { + case let .error(error): + self.channel.pipeline.fireErrorCaught(error) + + case let .responsePart(responsePart): + // We tolerate errors here: an error will be thrown if the write results in an error which + // isn't caught in the channel. Errors in the channel get funnelled into the transport held + // by the actual call object and handled there. + _ = try? self.channel.writeInbound(responsePart) + } + } +} + +// MARK: - Unary Response + +/// A fake unary response to be used with a generated test client. +/// +/// Users typically create fake responses via helper methods on their generated test clients +/// corresponding to the RPC which they intend to test. +/// +/// For unary responses users may call one of two functions for each RPC: +/// - `sendMessage(_:initialMetadata:trailingMetadata:status)`, or +/// - `sendError(status:trailingMetadata)` +/// +/// `sendMessage` sends a normal unary response with the provided message and allows the caller to +/// also specify initial metadata, trailing metadata and the status. Both metadata arguments are +/// empty by default and the status defaults to one with an 'ok' status code. +/// +/// `sendError` may be used to terminate an RPC without providing a response. As for `sendMessage`, +/// the `trailingMetadata` defaults to being empty. +public class FakeUnaryResponse: _FakeResponseStream { + override public init(requestHandler: @escaping (FakeRequestPart) -> Void = { _ in }) { + super.init(requestHandler: requestHandler) + } + + /// Send a response message to the client. + /// + /// - Parameters: + /// - response: The message to send. + /// - initialMetadata: The initial metadata to send. By default the metadata will be empty. + /// - trailingMetadata: The trailing metadata to send. By default the metadata will be empty. + /// - status: The status to send. By default this has an '.ok' status code. + /// - Throws: FakeResponseProtocolViolation if sending the message would violate the gRPC + /// protocol, e.g. sending messages after the RPC has ended. + public func sendMessage( + _ response: Response, + initialMetadata: HPACKHeaders = [:], + trailingMetadata: HPACKHeaders = [:], + status: GRPCStatus = .ok + ) throws { + try self._sendResponsePart(.initialMetadata(initialMetadata)) + try self._sendResponsePart(.message(.init(response, compressed: false))) + try self._sendResponsePart(.trailingMetadata(trailingMetadata)) + try self._sendResponsePart(.status(status)) + } + + /// Send an error to the client. + /// + /// - Parameters: + /// - error: The error to send. + /// - trailingMetadata: The trailing metadata to send. By default the metadata will be empty. + public func sendError(_ error: Error, trailingMetadata: HPACKHeaders = [:]) throws { + try self._sendResponsePart(.trailingMetadata(trailingMetadata)) + try self._sendError(error) + } +} + +// MARK: - Streaming Response + +/// A fake streaming response to be used with a generated test client. +/// +/// Users typically create fake responses via helper methods on their generated test clients +/// corresponding to the RPC which they intend to test. +/// +/// For streaming responses users have a number of methods available to them: +/// - `sendInitialMetadata(_:)` +/// - `sendMessage(_:)` +/// - `sendEnd(status:trailingMetadata:)` +/// - `sendError(_:trailingMetadata)` +/// +/// `sendInitialMetadata` may be called to send initial metadata to the client, however, it +/// must be called first in order for the metadata to be sent. If it is not called, empty +/// metadata will be sent automatically if necessary. +/// +/// `sendMessage` may be called to send a response message on the stream. This may be called +/// multiple times. Messages will be ignored if this is called after `sendEnd` or `sendError`. +/// +/// `sendEnd` indicates that the response stream has closed. It – or `sendError` - must be called +/// once. The `status` defaults to a value with the `ok` code and `trailingMetadata` is empty by +/// default. +/// +/// `sendError` may be called at any time to indicate an error on the response stream. +/// Like `sendEnd`, `trailingMetadata` is empty by default. +public class FakeStreamingResponse: _FakeResponseStream { + override public init(requestHandler: @escaping (FakeRequestPart) -> Void = { _ in }) { + super.init(requestHandler: requestHandler) + } + + /// Send initial metadata to the client. + /// + /// Note that calling this function is not required; empty initial metadata will be sent + /// automatically if necessary. + /// + /// - Parameter metadata: The metadata to send + /// - Throws: FakeResponseProtocolViolation if sending initial metadata would violate the gRPC + /// protocol, e.g. sending metadata too many times, or out of order. + public func sendInitialMetadata(_ metadata: HPACKHeaders) throws { + try self._sendResponsePart(.initialMetadata(metadata)) + } + + /// Send a response message to the client. + /// + /// - Parameter response: The response to send. + /// - Throws: FakeResponseProtocolViolation if sending the message would violate the gRPC + /// protocol, e.g. sending messages after the RPC has ended. + public func sendMessage(_ response: Response) throws { + try self._sendResponsePart(.message(.init(response, compressed: false))) + } + + /// Send the RPC status and trailing metadata to the client. + /// + /// - Parameters: + /// - status: The status to send. By default the status code will be '.ok'. + /// - trailingMetadata: The trailing metadata to send. Empty by default. + /// - Throws: FakeResponseProtocolViolation if ending the RPC would violate the gRPC + /// protocol, e.g. sending end after the RPC has already completed. + public func sendEnd(status: GRPCStatus = .ok, trailingMetadata: HPACKHeaders = [:]) throws { + try self._sendResponsePart(.trailingMetadata(trailingMetadata)) + try self._sendResponsePart(.status(status)) + } + + /// Send an error to the client. + /// + /// - Parameters: + /// - error: The error to send. + /// - trailingMetadata: The trailing metadata to send. By default the metadata will be empty. + /// - Throws: FakeResponseProtocolViolation if sending the error would violate the gRPC + /// protocol, e.g. erroring after the RPC has already completed. + public func sendError(_ error: Error, trailingMetadata: HPACKHeaders = [:]) throws { + try self._sendResponsePart(.trailingMetadata(trailingMetadata)) + try self._sendError(error) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_GRPCClientCodecHandler.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_GRPCClientCodecHandler.swift new file mode 100644 index 00000000..f1e1dd43 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_GRPCClientCodecHandler.swift @@ -0,0 +1,176 @@ +/* + * Copyright 2020, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import NIOCore + +internal class GRPCClientCodecHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +> { + /// The request serializer. + private let serializer: Serializer + + /// The response deserializer. + private let deserializer: Deserializer + + internal init(serializer: Serializer, deserializer: Deserializer) { + self.serializer = serializer + self.deserializer = deserializer + } +} + +extension GRPCClientCodecHandler: ChannelInboundHandler { + typealias InboundIn = _RawGRPCClientResponsePart + typealias InboundOut = _GRPCClientResponsePart + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + switch self.unwrapInboundIn(data) { + case let .initialMetadata(headers): + context.fireChannelRead(self.wrapInboundOut(.initialMetadata(headers))) + + case let .message(messageContext): + do { + let response = try self.deserializer.deserialize(byteBuffer: messageContext.message) + context + .fireChannelRead( + self + .wrapInboundOut(.message(.init(response, compressed: messageContext.compressed))) + ) + } catch { + context.fireErrorCaught(error) + } + + case let .trailingMetadata(trailers): + context.fireChannelRead(self.wrapInboundOut(.trailingMetadata(trailers))) + + case let .status(status): + context.fireChannelRead(self.wrapInboundOut(.status(status))) + } + } +} + +extension GRPCClientCodecHandler: ChannelOutboundHandler { + typealias OutboundIn = _GRPCClientRequestPart + typealias OutboundOut = _RawGRPCClientRequestPart + + internal func write( + context: ChannelHandlerContext, + data: NIOAny, + promise: EventLoopPromise? + ) { + switch self.unwrapOutboundIn(data) { + case let .head(head): + context.write(self.wrapOutboundOut(.head(head)), promise: promise) + + case let .message(message): + do { + let serialized = try self.serializer.serialize( + message.message, + allocator: context.channel.allocator + ) + context.write( + self.wrapOutboundOut(.message(.init(serialized, compressed: message.compressed))), + promise: promise + ) + } catch { + promise?.fail(error) + context.fireErrorCaught(error) + } + + case .end: + context.write(self.wrapOutboundOut(.end), promise: promise) + } + } +} + +// MARK: Reverse Codec + +internal class GRPCClientReverseCodecHandler< + Serializer: MessageSerializer, + Deserializer: MessageDeserializer +> { + /// The request serializer. + private let serializer: Serializer + + /// The response deserializer. + private let deserializer: Deserializer + + internal init(serializer: Serializer, deserializer: Deserializer) { + self.serializer = serializer + self.deserializer = deserializer + } +} + +extension GRPCClientReverseCodecHandler: ChannelInboundHandler { + typealias InboundIn = _GRPCClientResponsePart + typealias InboundOut = _RawGRPCClientResponsePart + + internal func channelRead(context: ChannelHandlerContext, data: NIOAny) { + switch self.unwrapInboundIn(data) { + case let .initialMetadata(headers): + context.fireChannelRead(self.wrapInboundOut(.initialMetadata(headers))) + + case let .message(messageContext): + do { + let response = try self.serializer.serialize( + messageContext.message, + allocator: context.channel.allocator + ) + context.fireChannelRead( + self.wrapInboundOut(.message(.init(response, compressed: messageContext.compressed))) + ) + } catch { + context.fireErrorCaught(error) + } + + case let .trailingMetadata(trailers): + context.fireChannelRead(self.wrapInboundOut(.trailingMetadata(trailers))) + + case let .status(status): + context.fireChannelRead(self.wrapInboundOut(.status(status))) + } + } +} + +extension GRPCClientReverseCodecHandler: ChannelOutboundHandler { + typealias OutboundIn = _RawGRPCClientRequestPart + typealias OutboundOut = _GRPCClientRequestPart + + internal func write( + context: ChannelHandlerContext, + data: NIOAny, + promise: EventLoopPromise? + ) { + switch self.unwrapOutboundIn(data) { + case let .head(head): + context.write(self.wrapOutboundOut(.head(head)), promise: promise) + + case let .message(message): + do { + let deserialized = try self.deserializer.deserialize(byteBuffer: message.message) + context.write( + self.wrapOutboundOut(.message(.init(deserialized, compressed: message.compressed))), + promise: promise + ) + } catch { + promise?.fail(error) + context.fireErrorCaught(error) + } + + case .end: + context.write(self.wrapOutboundOut(.end), promise: promise) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_MessageContext.swift b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_MessageContext.swift new file mode 100644 index 00000000..74b80e59 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/gRPC-Swiftp/Sources/GRPC/_MessageContext.swift @@ -0,0 +1,34 @@ +/* + * Copyright 2019, gRPC Authors 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// Provides a context for gRPC payloads. +/// +/// - Important: This is **NOT** part of the public API. +public final class _MessageContext { + /// The message being sent or received. + let message: Message + + /// Whether the message was, or should be compressed. + let compressed: Bool + + /// Constructs a box for a value. + /// + /// - Important: This is **NOT** part of the public API. + public init(_ message: Message, compressed: Bool) { + self.message = message + self.compressed = compressed + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/LICENSE b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/LICENSE new file mode 100644 index 00000000..38d91bf1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 GigaBitcoin LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/README.md b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/README.md new file mode 100644 index 00000000..78077a60 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/README.md @@ -0,0 +1,116 @@ +[![Build Status](https://app.bitrise.io/app/18c18db60fc4fddf/status.svg?token=nczB4mTPCrlTfDQnXH_8Pw&branch=main)](https://app.bitrise.io/app/18c18db60fc4fddf) [![Build Status](https://app.bitrise.io/app/f1bbbdfeff08cd5c/status.svg?token=ONB3exCALsB-_ayi6KsXFQ&branch=main)](https://app.bitrise.io/app/f1bbbdfeff08cd5c) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift) + +# 🔐 secp256k1.swift +Swift package with elliptic curve public key cryptography, ECDSA, Schnorr Signatures for Bitcoin and C bindings from [libsecp256k1](https://github.com/bitcoin-core/secp256k1). + + +# Objectives + +Long-term goals are: + - Lightweight ECDSA & Schnorr Signatures functionality + - Built for simple or advance usage with things like BIP340 + - Exposed C bindings to take full control of the secp256k1 implementation + - Familiar API design by modeling after [Swift Crypto](https://github.com/apple/swift-crypto) + - Automatic updates for Swift and libsecp256k1 + - Availability for Linux and Apple platform ecosystems + + +# Example Usage + +## ECDSA + +```swift +import secp256k1 + +// Private key +let privateBytes = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes +let privateKey = try! secp256k1.Signing.PrivateKey(rawRepresentation: privateBytes) + +// Public key +print(String(bytes: privateKey.publicKey.rawRepresentation)) + +// ECDSA +let messageData = "We're all Satoshi.".data(using: .utf8)! +let signature = try! privateKey.ecdsa.signature(for: messageData) + +// DER signature +print(try! signature.derRepresentation.base64EncodedString()) +``` + +## Schnorr + +```swift +let privateBytes = try! "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C9".bytes +let privateKey = try! secp256k1.Signing.PrivateKey(rawRepresentation: privateBytes) + +// Extra params for custom signing +var auxRand = try! "C87AA53824B4D7AE2EB035A2B5BBBCCC080E76CDC6D1692C4B0B62D798E6D906".bytes +var messageDigest = try! "7E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C".bytes + +// API allows for signing variable length messages +let signature = try! privateKey.schnorr.signature(message: &messageDigest, auxiliaryRand: &auxRand) +``` + +## Tweak + +```swift +let privateBytes = try! "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C9".bytes +let privateKey = try! secp256k1.Signing.PrivateKey(rawRepresentation: privateBytes) + +// Adding a tweak to the private key and public key +let tweak = try! "5f0da318c6e02f653a789950e55756ade9f194e1ec228d7f368de1bd821322b6".bytes +let tweakedPrivateKey = try! privateKey.tweak(tweak) +let tweakedPublicKeyKey = try! privateKey.publicKey.tweak(tweak) +``` + +## Elliptic Curve Diffie Hellman + +```swift +let privateKey = try! secp256k1.KeyAgreement.PrivateKey() +let publicKey = try! secp256k1.KeyAgreement.PrivateKey().publicKey + +// Create a shared secret with a private key from only a public key +let sharedSecret = try! privateKey.sharedSecretFromKeyAgreement(with: publicKey) +``` + +## Silent Payments + +```swift +let privateSign1 = try! secp256k1.Signing.PrivateKey() +let privateSign2 = try! secp256k1.Signing.PrivateKey() + +let privateKey1 = try! secp256k1.KeyAgreement.PrivateKey(rawRepresentation: privateSign1.rawRepresentation) +let privateKey2 = try! secp256k1.KeyAgreement.PrivateKey(rawRepresentation: privateSign2.rawRepresentation) + +let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey) +let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: privateKey1.publicKey) + +let sharedSecretSign1 = try! secp256k1.Signing.PrivateKey(rawRepresentation: sharedSecret1.bytes) +let sharedSecretSign2 = try! secp256k1.Signing.PrivateKey(rawRepresentation: sharedSecret2.bytes) + +// Payable Silent Payment public key +let xonlyTweak2 = try! sharedSecretSign2.publicKey.xonly.add(privateSign1.publicKey.xonly.bytes) + +// Spendable Silent Payment private key +let privateTweak1 = try! sharedSecretSign1.add(xonly: privateSign1.publicKey.xonly.bytes) +``` + + +# Getting Started + +This repository primarily uses Swift package manager as its build tool, so we recommend using that as well. If you want to depend on `secp256k1.swift` in your own project, simply add it as a dependencies' clause in your `Package.swift`: + +```swift +.package(url: "https://github.com/GigaBitcoin/secp256k1.swift.git", .upToNextMajor(from: "0.6.0")) +``` + +Try in a [playground](spi-playgrounds://open?dependencies=GigaBitcoin/secp256k1.swift) using the [SPI Playgrounds app](https://swiftpackageindex.com/try-in-a-playground) or 🏟 [Arena](https://github.com/finestructure/arena) + +```swift +arena GigaBitcoin/secp256k1.swift +``` + + +# Danger +These APIs should not be considered stable and may change at any time, libsecp256k1 is still experimental and has not been formally released. + diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Asymmetric.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Asymmetric.swift new file mode 100644 index 00000000..ad0de1d2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Asymmetric.swift @@ -0,0 +1,151 @@ +// +// Asymmetric.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation + +/// The secp256k1 Elliptic Curve. +public extension secp256k1 { + /// Signing operations on secp256k1 + enum Signing { + /// A Private Key for signing. + public struct PrivateKey: Equatable { + /// Generated secp256k1 Signing Key. + private let baseKey: PrivateKeyImplementation + + /// The secp256k1 private key object + var key: SecureBytes { + baseKey.key + } + + /// ECDSA Signing object. + public var ecdsa: secp256k1.Signing.ECDSASigner { + ECDSASigner(signingKey: baseKey) + } + + /// Schnorr Signing object. + public var schnorr: secp256k1.Signing.SchnorrSigner { + SchnorrSigner(signingKey: baseKey) + } + + /// The associated public key for verifying signatures done with this private key. + /// + /// - Returns: The associated public key + public var publicKey: PublicKey { + PublicKey(baseKey: baseKey.publicKey) + } + + /// A data representation of the private key + public var rawRepresentation: Data { + baseKey.rawRepresentation + } + + /// Creates a random secp256k1 private key for signing + public init(format: secp256k1.Format = .compressed) throws { + self.baseKey = try PrivateKeyImplementation(format: format) + } + + /// Creates a secp256k1 private key for signing from a data representation. + /// - Parameter data: A raw representation of the key. + /// - Throws: An error is thrown when the raw representation does not create a private key for signing. + public init(rawRepresentation data: D, format: secp256k1.Format = .compressed) throws { + self.baseKey = try PrivateKeyImplementation(rawRepresentation: data, format: format) + } + + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.key == rhs.key + } + } + + /// The corresponding public key. + public struct PublicKey { + /// Generated secp256k1 public key. + private let baseKey: PublicKeyImplementation + + /// The secp256k1 public key object + var bytes: [UInt8] { + baseKey.bytes + } + + /// A data representation of the public key + public var rawRepresentation: Data { + baseKey.rawRepresentation + } + + /// ECDSA Validating object. + public var ecdsa: secp256k1.Signing.ECDSAValidator { + ECDSAValidator(validatingKey: baseKey) + } + + /// Schnorr Validating object. + public var schnorr: secp256k1.Signing.SchnorrValidator { + SchnorrValidator(validatingKey: baseKey) + } + + /// The associated x-only public key for verifying Schnorr signatures. + /// + /// - Returns: The associated x-only public key + public var xonly: XonlyKey { + XonlyKey(baseKey: baseKey.xonly) + } + + /// A key format representation of the public key + public var format: secp256k1.Format { + baseKey.format + } + + /// Generates a secp256k1 public key. + /// - Parameter baseKey: generated secp256k1 public key. + fileprivate init(baseKey: PublicKeyImplementation) { + self.baseKey = baseKey + } + + /// Generates a secp256k1 public key from a raw representation. + /// - Parameter data: A raw representation of the key. + /// - Throws: An error is thrown when the raw representation does not create a public key. + public init(rawRepresentation data: D, xonly: D, keyParity: Int32, format: secp256k1.Format) { + self.baseKey = PublicKeyImplementation(rawRepresentation: data, xonly: xonly, keyParity: keyParity, format: format) + } + + /// Generates a secp256k1 public key from a raw representation. + /// - Parameter data: A raw representation of the key. + /// - Throws: An error is thrown when the raw representation does not create a public key. + public init(rawRepresentation data: [UInt8], format: secp256k1.Format) throws { + var keyParity: Int32 = 0 + let xonly = try XonlyKeyImplementation.generate(bytes: data, keyParity: &keyParity, format: format) + self.baseKey = PublicKeyImplementation(rawRepresentation: data, xonly: xonly, keyParity: keyParity, format: format) + } + } + + /// The corresponding x-only public key. + public struct XonlyKey { + /// Generated secp256k1 x-only public key. + private let baseKey: XonlyKeyImplementation + + /// The secp256k1 x-only public key object + public var bytes: [UInt8] { + baseKey.bytes + } + + /// A boolean that will be set to true if the point encoded by xonly is the + /// negation of the pubkey and set to false otherwise. + public var parity: Bool { + baseKey.keyParity.boolValue + } + + fileprivate init(baseKey: XonlyKeyImplementation) { + self.baseKey = baseKey + } + + public init(rawRepresentation data: D, keyParity: Int32) { + self.baseKey = XonlyKeyImplementation(rawRepresentation: data, keyParity: keyParity) + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/DH.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/DH.swift new file mode 100644 index 00000000..2ca00598 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/DH.swift @@ -0,0 +1,81 @@ +// +// DH.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation + +/// A Diffie-Hellman Key Agreement Key +protocol DiffieHellmanKeyAgreement { + /// The public key share type to perform the DH Key Agreement + associatedtype P + var publicKey: P { get } + + /// Performs a Diffie-Hellman Key Agreement + /// + /// - Parameter publicKeyShare: The public key share + /// - Returns: The resulting key agreement result + func sharedSecretFromKeyAgreement(with publicKeyShare: P) throws -> SharedSecret +} + +/// A Key Agreement Result +/// A SharedSecret has to go through a Key Derivation Function before being able to use by a symmetric key operation. +public struct SharedSecret: ContiguousBytes { + var ss: SecureBytes + + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + try ss.withUnsafeBytes(body) + } +} + +extension SharedSecret: Hashable { + public func hash(into hasher: inout Hasher) { + ss.withUnsafeBytes { hasher.combine(bytes: $0) } + } +} + +// We want to implement constant-time comparison for digests. +extension SharedSecret: CustomStringConvertible, Equatable { + public static func == (lhs: Self, rhs: Self) -> Bool { + safeCompare(lhs, rhs) + } + + public static func == (lhs: Self, rhs: D) -> Bool { + if rhs.regions.count != 1 { + let rhsContiguous = Data(rhs) + return safeCompare(lhs, rhsContiguous) + } else { + return safeCompare(lhs, rhs.regions.first!) + } + } + + public var description: String { + "\(Self.self): \(ss.hexString)" + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Digests.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Digests.swift new file mode 100644 index 00000000..7b64dd15 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Digests.swift @@ -0,0 +1,71 @@ +// +// Digests.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation + +// MARK: - SHA256Digest + DigestPrivate + +public struct SHA256Digest: Digest { + let bytes: (UInt64, UInt64, UInt64, UInt64) + + public static var byteCount: Int { + get { 32 } + + set { fatalError("Cannot set SHA256.byteCount") } + } + + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer( + start: $0.baseAddress, + count: Self.byteCount + ) + return try body(boundsCheckedPtr) + } + } + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + array.appendByte(bytes.1) + array.appendByte(bytes.2) + array.appendByte(bytes.3) + return array.prefix(upTo: Self.byteCount) + } + + public var description: String { + "\("SHA256") digest: \(toArray().hexString)" + } + + public func hash(into hasher: inout Hasher) { + withUnsafeBytes { hasher.combine(bytes: $0) } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDH.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDH.swift new file mode 100644 index 00000000..d8196317 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDH.swift @@ -0,0 +1,97 @@ +// +// ECDH.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +// MARK: - secp256k1 + KeyAgreement + +public extension secp256k1 { + enum KeyAgreement { + public struct PublicKey /*: NISTECPublicKey */ { + let baseKey: PublicKeyImplementation + + /// Creates a secp256k1 public key for key agreement from a collection of bytes. + /// - Parameters: + /// - data: A raw representation of the public key as a collection of contiguous bytes. + /// - xonly: A raw representation of the xonly key as a collection of contiguous bytes. + /// - format: the format of the public key object + public init(rawRepresentation data: D, xonly: D, keyParity: Int32, format: secp256k1.Format) { + self.baseKey = PublicKeyImplementation(rawRepresentation: data, xonly: xonly, keyParity: keyParity, format: format) + } + + /// Initializes a secp256k1 public key for key agreement. + /// - Parameter baseKey: generated secp256k1 public key. + init(baseKey: PublicKeyImplementation) { + self.baseKey = baseKey + } + + /// A data representation of the public key + public var rawRepresentation: Data { baseKey.rawRepresentation } + + /// Implementation public key object + var bytes: [UInt8] { baseKey.bytes } + } + + public struct PrivateKey /*: NISTECPrivateKey */ { + let baseKey: PrivateKeyImplementation + + /// Creates a random secp256k1 private key for key agreement. + public init(format: secp256k1.Format = .compressed) throws { + self.baseKey = try PrivateKeyImplementation(format: format) + } + + /// Creates a secp256k1 private key for key agreement from a collection of bytes. + /// - Parameter data: A raw representation of the key. + /// - Throws: An error is thrown when the raw representation does not create a private key for key agreement. + public init(rawRepresentation data: D, format: secp256k1.Format = .compressed) throws { + self.baseKey = try PrivateKeyImplementation(rawRepresentation: data, format: format) + } + + /// Initializes a secp256k1 private key for key agreement. + /// - Parameter baseKey: generated secp256k1 private key. + init(baseKey: PrivateKeyImplementation) { + self.baseKey = baseKey + } + + /// The associated public key for verifying signatures done with this private key. + public var publicKey: secp256k1.KeyAgreement.PublicKey { + PublicKey(baseKey: baseKey.publicKey) + } + + /// A data representation of the private key + public var rawRepresentation: Data { baseKey.rawRepresentation } + + /// Implementation public key object + var bytes: SecureBytes { baseKey.key } + } + } +} + +// MARK: - secp256k1 + DH + +extension secp256k1.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement { + /// Performs a key agreement with provided public key share. + /// + /// - Parameter publicKeyShare: The public key to perform the ECDH with. + /// - Returns: Returns a shared secret + /// - Throws: An error occurred while computing the shared secret + public func sharedSecretFromKeyAgreement(with publicKeyShare: secp256k1.KeyAgreement.PublicKey) throws -> SharedSecret { + var publicKey = secp256k1_pubkey() + var sharedSecret = [UInt8](repeating: 0, count: 32) + + guard secp256k1_ec_pubkey_parse(secp256k1.Context.raw, &publicKey, publicKeyShare.bytes, publicKeyShare.bytes.count).boolValue, + secp256k1_ecdh(secp256k1.Context.raw, &sharedSecret, &publicKey, baseKey.key.bytes, nil, nil).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return SharedSecret(ss: SecureBytes(bytes: sharedSecret)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDSA.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDSA.swift new file mode 100644 index 00000000..cf6a2660 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/ECDSA.swift @@ -0,0 +1,211 @@ +// +// ECDSA.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +typealias NISTECDSASignature = RawSignature & DERSignature + +protocol RawSignature { + init(rawRepresentation: D) throws + var rawRepresentation: Data { get } +} + +protocol DERSignature { + init(derRepresentation: D) throws + var derRepresentation: Data { get throws } +} + +protocol CompactSignature { + init(compactRepresentation: D) throws + var compactRepresentation: Data { get throws } +} + +// MARK: - secp256k1 + ECDSA Signature + +/// An ECDSA (Elliptic Curve Digital Signature Algorithm) Signature +public extension secp256k1.Signing { + struct ECDSASignature: ContiguousBytes, NISTECDSASignature, CompactSignature { + /// Returns the raw signature. + /// The raw signature format for ECDSA is r || s + public var rawRepresentation: Data + + /// Initializes ECDSASignature from the raw representation. + /// - Parameters: + /// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with the dataRepresentation count + public init(rawRepresentation: D) throws { + guard rawRepresentation.count == 4 * secp256k1.CurveDetails.coordinateByteCount else { + throw secp256k1Error.incorrectParameterSize + } + + self.rawRepresentation = Data(rawRepresentation) + } + + /// Initializes ECDSASignature from the raw representation. + /// - Parameters: + /// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with the dataRepresentation count + internal init(_ dataRepresentation: Data) throws { + guard dataRepresentation.count == 4 * secp256k1.CurveDetails.coordinateByteCount else { + throw secp256k1Error.incorrectParameterSize + } + + self.rawRepresentation = dataRepresentation + } + + /// Initializes ECDSASignature from the DER representation. + /// - Parameter derRepresentation: A DER representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with parsing the derRepresentation + public init(derRepresentation: D) throws { + let derSignatureBytes = Array(derRepresentation) + var signature = secp256k1_ecdsa_signature() + + guard secp256k1_ecdsa_signature_parse_der(secp256k1.Context.raw, &signature, derSignatureBytes, derSignatureBytes.count).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + self.rawRepresentation = signature.dataValue + } + + /// Initializes ECDSASignature from the Compact representation. + /// - Parameter derRepresentation: A Compact representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with parsing the derRepresentation + public init(compactRepresentation: D) throws { + var signature = secp256k1_ecdsa_signature() + + guard secp256k1_ecdsa_signature_parse_compact(secp256k1.Context.raw, &signature, Array(compactRepresentation)).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + self.rawRepresentation = signature.dataValue + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of the digest. + /// - Parameter body: A closure that takes a raw buffer pointer to the bytes of the digest and returns the digest. + /// - Throws: If there is a failure with underlying `withUnsafeBytes` + /// - Returns: The signature as returned from the body closure. + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + try rawRepresentation.withUnsafeBytes(body) + } + + /// Serialize an ECDSA signature in compact (64 byte) format. + /// - Throws: If there is a failure parsing signature + /// - Returns: a 64-byte data representation of the compact serialization + public var compactRepresentation: Data { + get throws { + let compactSignatureLength = 64 + var signature = secp256k1_ecdsa_signature() + var compactSignature = [UInt8](repeating: 0, count: compactSignatureLength) + + rawRepresentation.copyToUnsafeMutableBytes(of: &signature.data) + + guard secp256k1_ecdsa_signature_serialize_compact(secp256k1.Context.raw, &compactSignature, &signature).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return Data(bytes: &compactSignature, count: compactSignatureLength) + } + } + + /// A DER-encoded representation of the signature + /// - Throws: If there is a failure parsing signature + /// - Returns: a DER representation of the signature + public var derRepresentation: Data { + get throws { + var signature = secp256k1_ecdsa_signature() + var derSignatureLength = 80 + var derSignature = [UInt8](repeating: 0, count: derSignatureLength) + + rawRepresentation.copyToUnsafeMutableBytes(of: &signature.data) + + guard secp256k1_ecdsa_signature_serialize_der(secp256k1.Context.raw, &derSignature, &derSignatureLength, &signature).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return Data(bytes: &derSignature, count: derSignatureLength) + } + } + } +} + +// MARK: - secp256k1 + Signing Key + +public extension secp256k1.Signing { + struct ECDSASigner { + /// Generated secp256k1 Signing Key. + var signingKey: PrivateKeyImplementation + } +} + +extension secp256k1.Signing.ECDSASigner: DigestSigner, Signer { + /// Generates an ECDSA signature over the secp256k1 elliptic curve. + /// + /// - Parameter digest: The digest to sign. + /// - Returns: The ECDSA Signature. + /// - Throws: If there is a failure producing the signature + public func signature(for digest: D) throws -> secp256k1.Signing.ECDSASignature { + var signature = secp256k1_ecdsa_signature() + + guard secp256k1_ecdsa_sign(secp256k1.Context.raw, &signature, Array(digest), Array(signingKey.rawRepresentation), nil, nil).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return try secp256k1.Signing.ECDSASignature(signature.dataValue) + } + + /// Generates an ECDSA signature over the secp256k1 elliptic curve. + /// SHA256 is used as the hash function. + /// + /// - Parameter data: The data to sign. + /// - Returns: The ECDSA Signature. + /// - Throws: If there is a failure producing the signature. + public func signature(for data: D) throws -> secp256k1.Signing.ECDSASignature { + try signature(for: SHA256.hash(data: data)) + } +} + +// MARK: - secp256k1 + Validating Key + +public extension secp256k1.Signing { + struct ECDSAValidator { + /// Generated secp256k1 Validating Key. + var validatingKey: PublicKeyImplementation + } +} + +extension secp256k1.Signing.ECDSAValidator: DigestValidator, DataValidator { + /// Verifies an ECDSA signature over the secp256k1 elliptic curve. + /// + /// - Parameters: + /// - signature: The signature to verify + /// - digest: The digest that was signed. + /// - Returns: True if the signature is valid, false otherwise. + public func isValidSignature(_ signature: secp256k1.Signing.ECDSASignature, for digest: D) -> Bool { + var secp256k1Signature = secp256k1_ecdsa_signature() + var secp256k1PublicKey = secp256k1_pubkey() + + signature.rawRepresentation.copyToUnsafeMutableBytes(of: &secp256k1Signature.data) + + return secp256k1_ec_pubkey_parse(secp256k1.Context.raw, &secp256k1PublicKey, validatingKey.bytes, validatingKey.bytes.count).boolValue && + secp256k1_ecdsa_verify_with_handling_high_s(secp256k1.Context.raw, &secp256k1Signature, Array(digest), &secp256k1PublicKey).boolValue + } + + /// Verifies an ECDSA signature over the secp256k1 elliptic curve. + /// SHA256 is used as the hash function. + /// + /// - Parameters: + /// - signature: The signature to verify + /// - data: The data that was signed. + /// - Returns: True if the signature is valid, false otherwise. + public func isValidSignature(_ signature: secp256k1.Signing.ECDSASignature, for data: D) -> Bool { + isValidSignature(signature, for: SHA256.hash(data: data)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/EdDSA.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/EdDSA.swift new file mode 100644 index 00000000..c064aae5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/EdDSA.swift @@ -0,0 +1,42 @@ +// +// EdDSA.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation + +protocol DigestValidator { + associatedtype Signature + func isValidSignature(_ signature: Signature, for digest: D) -> Bool +} + +protocol DataValidator { + associatedtype Signature + func isValidSignature(_ signature: Signature, for signedData: D) -> Bool +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Errors.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Errors.swift new file mode 100644 index 00000000..0c123eb0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Errors.swift @@ -0,0 +1,21 @@ +// +// Errors.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation + +/// Errors thrown for secp256k1 +/// - incorrectKeySize: A key is being deserialized with an incorrect key size. +/// - incorrectParameterSize: The number of bytes passed for a given argument is incorrect. +/// - underlyingCryptoError: An unexpected error at a lower-level occurred. +public enum secp256k1Error: Error { + case incorrectKeySize + case incorrectParameterSize + case underlyingCryptoError +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/PrettyBytes.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/PrettyBytes.swift new file mode 100644 index 00000000..d63db088 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/PrettyBytes.swift @@ -0,0 +1,38 @@ +// +// PrettyBytes.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation + +extension MutableDataProtocol { + mutating func appendByte(_ byte: UInt64) { + withUnsafePointer(to: byte.littleEndian) { self.append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SHA256.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SHA256.swift new file mode 100644 index 00000000..f753a83c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SHA256.swift @@ -0,0 +1,49 @@ +// +// SHA256.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +public enum SHA256 { + /// Computes a digest of the data. + /// - Parameter data: The data to be hashed + /// - Returns: The computed digest + public static func hash(data: D) -> SHA256Digest { + let stringData = Array(data) + var output = [UInt8](repeating: 0, count: 32) + + secp256k1_swift_sha256(&output, stringData, stringData.count) + + return convert(output) + } + + /// Computes a digest of the data. + /// - Parameter data: The data to be hashed + /// - Returns: The computed digest + public static func taggedHash(tag: [UInt8], data: D) throws -> SHA256Digest { + let messageBytes = Array(data) + var output = [UInt8](repeating: 0, count: 32) + + guard secp256k1_tagged_sha256(secp256k1.Context.raw, &output, tag, tag.count, messageBytes, messageBytes.count).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return convert(output) + } + + private static func convert(_ output: [UInt8]) -> SHA256Digest { + let first = output[0..<8].withUnsafeBytes { $0.load(as: UInt64.self) } + let second = output[8..<16].withUnsafeBytes { $0.load(as: UInt64.self) } + let third = output[16..<24].withUnsafeBytes { $0.load(as: UInt64.self) } + let forth = output[24..<32].withUnsafeBytes { $0.load(as: UInt64.self) } + + return SHA256Digest(bytes: (first, second, third, forth)) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SafeCompare.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SafeCompare.swift new file mode 100644 index 00000000..e361079b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/SafeCompare.swift @@ -0,0 +1,48 @@ +// +// SafeCompare.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + @_exported import CryptoKit +#else + import Foundation + + /// A constant-time comparison function for any two collections of bytes. + internal func safeCompare(_ lhs: LHS, _ rhs: RHS) -> Bool { + let lBytes = lhs.bytes + let rBytes = rhs.bytes + + guard lBytes.count == rBytes.count else { + return false + } + + return zip(lBytes, rBytes).reduce(into: 0) { $0 |= $1.0 ^ $1.1 } == 0 + } + +#endif // Linux or !SwiftPM diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Schnorr.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Schnorr.swift new file mode 100644 index 00000000..a542beef --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Schnorr.swift @@ -0,0 +1,235 @@ +// +// Schnorr.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +extension secp256k1 { + @usableFromInline enum Schnorr { + /// Fixed number of bytes for Schnorr signature + /// + /// [BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#abstract) + @inlinable static var signatureByteCount: Int { 64 } + + @inlinable static var xonlyByteCount: Int { 32 } + + /// Tuple representation of ``SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC`` + /// + /// Only used at initialization and has no other function than making sure the object is initialized. + /// + /// [bitcoin-core/secp256k1](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L88) + @inlinable static var magic: (UInt8, UInt8, UInt8, UInt8) { (218, 111, 179, 140) } + } +} + +// MARK: - Schnorr Signatures + +/// A Schnorr (Schnorr Digital Signature Scheme) Signature +public extension secp256k1.Signing { + struct SchnorrSignature: ContiguousBytes, RawSignature { + /// Returns the raw signature in a fixed 64-byte format. + public var rawRepresentation: Data + + /// Initializes SchnorrSignature from the raw representation. + /// - Parameters: + /// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with the rawRepresentation count + public init(rawRepresentation: D) throws { + guard rawRepresentation.count == secp256k1.Schnorr.signatureByteCount else { + throw secp256k1Error.incorrectParameterSize + } + + self.rawRepresentation = Data(rawRepresentation) + } + + /// Initializes SchnorrSignature from the raw representation. + /// - Parameters: + /// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes. + /// - Throws: If there is a failure with the dataRepresentation count + internal init(_ dataRepresentation: Data) throws { + guard dataRepresentation.count == secp256k1.Schnorr.signatureByteCount else { + throw secp256k1Error.incorrectParameterSize + } + + self.rawRepresentation = dataRepresentation + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of the digest. + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the digest and returns the digest. + /// - Throws: If there is a failure with underlying `withUnsafeBytes` + /// - Returns: The signature as returned from the body closure. + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + try rawRepresentation.withUnsafeBytes(body) + } + } +} + +// MARK: - secp256k1 + Signing Key + +public extension secp256k1.Signing { + struct SchnorrSigner { + /// Generated secp256k1 Signing Key. + var signingKey: PrivateKeyImplementation + } +} + +extension secp256k1.Signing.SchnorrSigner: DigestSigner, Signer { + /// Generates an Schnorr signature from a hash of a variable length data object + /// + /// This function uses SHA256 to create a hash of the variable length the data argument to ensure only 32-byte messages are signed. + /// Strictly does _not_ follow BIP340. Read ``secp256k1_schnorrsig_sign`` documentation for more info. + /// + /// [bitcoin-core/secp256k1](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L95L118) + /// + /// - Parameters: + /// - data: The data object to hash and sign. + /// - Returns: The Schnorr Signature. + /// - Throws: If there is a failure producing the signature. + public func signature(for data: D) throws -> secp256k1.Signing.SchnorrSignature { + try signature(for: data, auxiliaryRand: SecureBytes(count: secp256k1.Schnorr.xonlyByteCount).bytes) + } + + /// Generates an Schnorr signature from the hash digest object + /// + /// This function is used when a hash digest has been created before invoking. + /// Enables BIP340 signatures assuming the hash digest used the `Tagged Hashes` scheme as defined in the proposal. + /// + /// [BIP340 Design](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design) + /// + /// - Parameters: + /// - digest: The digest to sign. + /// - Returns: The Schnorr Signature. + /// - Throws: If there is a failure producing the signature. + public func signature(for digest: D) throws -> secp256k1.Signing.SchnorrSignature { + try signature(for: digest, auxiliaryRand: SecureBytes(count: secp256k1.Schnorr.xonlyByteCount).bytes) + } + + /// Generates an Schnorr signature from a hash of a variable length data object + /// + /// This function uses SHA256 to create a hash of the variable length the data argument to ensure only 32-byte messages are signed. + /// Strictly does _not_ follow BIP340. Read ``secp256k1_schnorrsig_sign`` documentation for more info. + /// + /// [bitcoin-core/secp256k1](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L95L118) + /// + /// - Parameters: + /// - data: The data object to hash and sign. + /// - auxiliaryRand: Auxiliary randomness. + /// - Returns: The Schnorr Signature. + /// - Throws: If there is a failure producing the signature. + public func signature(for data: D, auxiliaryRand: [UInt8]) throws -> secp256k1.Signing.SchnorrSignature { + try signature(for: SHA256.hash(data: data), auxiliaryRand: auxiliaryRand) + } + + /// Generates an Schnorr signature from the hash digest object + /// + /// This function is used when a hash digest has been created before invoking. + /// Enables BIP340 signatures assuming the hash digest used the `Tagged Hashes` scheme as defined in the proposal. + /// + /// [BIP340 Design](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design) + /// + /// - Parameters: + /// - digest: The digest to sign. + /// - auxiliaryRand: Auxiliary randomness; BIP340 requires 32-bytes. + /// - Returns: The Schnorr Signature. + /// - Throws: If there is a failure producing the signature. + public func signature(for digest: D, auxiliaryRand: [UInt8]) throws -> secp256k1.Signing.SchnorrSignature { + var hashDataBytes = Array(digest).bytes + var randomBytes = auxiliaryRand + + return try signature(message: &hashDataBytes, auxiliaryRand: &randomBytes) + } + + /// Generates an Schnorr signature from a message object with a variable length of bytes + /// + /// This function provides the flexibility for creating a Schnorr signature without making assumptions about message object. + /// If ``auxiliaryRand`` is ``nil`` the ``secp256k1_nonce_function_bip340`` is used. + /// + /// [secp256k1_schnorrsig_extraparams](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L66L81) + /// + /// - Parameters: + /// - message: The message object to sign + /// - auxiliaryRand: Auxiliary randomness; BIP340 requires 32-bytes. + /// - Returns: The Schnorr Signature. + /// - Throws: If there is a failure creating the context or signature. + public func signature(message: inout [UInt8], auxiliaryRand: UnsafeMutableRawPointer?) throws -> secp256k1.Signing.SchnorrSignature { + var keypair = secp256k1_keypair() + var signature = [UInt8](repeating: 0, count: secp256k1.Schnorr.signatureByteCount) + var extraParams = secp256k1_schnorrsig_extraparams(magic: secp256k1.Schnorr.magic, noncefp: nil, ndata: auxiliaryRand) + + guard secp256k1_keypair_create(secp256k1.Context.raw, &keypair, signingKey.key.bytes).boolValue, + secp256k1_schnorrsig_sign_custom(secp256k1.Context.raw, &signature, &message, message.count, &keypair, &extraParams).boolValue + else { + throw secp256k1Error.underlyingCryptoError + } + + return try secp256k1.Signing.SchnorrSignature(Data(bytes: signature, count: secp256k1.Schnorr.signatureByteCount)) + } +} + +// MARK: - Schnorr + Validating Key + +public extension secp256k1.Signing { + struct SchnorrValidator { + /// Generated Schnorr Validating Key. + var validatingKey: PublicKeyImplementation + } +} + +extension secp256k1.Signing.SchnorrValidator: DigestValidator, DataValidator { + /// Verifies a Schnorr signature with a variable length data object + /// + /// This function uses SHA256 to create a hash of the variable length the data argument to ensure only 32-byte messages are verified. + /// Strictly does _not_ follow BIP340. Read ``secp256k1_schnorrsig_sign`` documentation for more info. + /// + /// [bitcoin-core/secp256k1](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L95L118) + /// + /// - Parameters: + /// - signature: The signature to verify + /// - data: The data that was signed. + /// - Returns: True if the signature is valid, false otherwise. + public func isValidSignature(_ signature: secp256k1.Signing.SchnorrSignature, for data: D) -> Bool { + isValidSignature(signature, for: SHA256.hash(data: data)) + } + + /// Verifies a Schnorr signature with a digest + /// + /// This function is used when a hash digest has been created before invoking. + /// Enables BIP340 signatures assuming the hash digest used the `Tagged Hashes` scheme as defined in the proposal. + /// + /// [BIP340 Design](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design) + /// + /// - Parameters: + /// - signature: The signature to verify. + /// - digest: The digest that was signed. + /// - Returns: True if the signature is valid, false otherwise. + public func isValidSignature(_ signature: secp256k1.Signing.SchnorrSignature, for digest: D) -> Bool { + var hashDataBytes = Array(digest).bytes + + return isValid(signature, for: &hashDataBytes) + } + + /// Verifies a Schnorr signature with a variable length message object + /// + /// This function provides flexibility for verifying a Schnorr signature without assumptions about message. + /// + /// [secp256k1_schnorrsig_verify](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_schnorrsig.h#L149L158) + /// + /// - Parameters: + /// - signature: The signature to verify. + /// - message: The message that was signed. + /// - Returns: True if the signature is valid, false otherwise. + public func isValid(_ signature: secp256k1.Signing.SchnorrSignature, for message: inout [UInt8]) -> Bool { + var pubKey = secp256k1_xonly_pubkey() + + return secp256k1_xonly_pubkey_parse(secp256k1.Context.raw, &pubKey, validatingKey.xonly.bytes).boolValue && + secp256k1_schnorrsig_verify(secp256k1.Context.raw, signature.rawRepresentation.bytes, message, message.count, &pubKey).boolValue + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Tweak.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Tweak.swift new file mode 100644 index 00000000..2e0f9b2a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Tweak.swift @@ -0,0 +1,138 @@ +// +// Tweak.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +public extension secp256k1.Signing.PrivateKey { + /// Create a new `PrivateKey` by adding tweak to the secret key. + /// - Parameter tweak: the 32-byte tweak object + /// - Returns: tweaked `PrivateKey` object + func add(_ tweak: [UInt8]) throws -> Self { + var privateBytes = key.bytes + + guard secp256k1_ec_seckey_tweak_add(secp256k1.Context.raw, &privateBytes, tweak).boolValue, + secp256k1_ec_seckey_verify(secp256k1.Context.raw, privateBytes).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return try Self(rawRepresentation: privateBytes) + } + + /// Create a new `PrivateKey` by adding tweak to the secret key. When tweaking x-only keys, + /// the implicit negations are handled when odd Y coordinates are reached. + /// [REF](https://github.com/bitcoin-core/secp256k1/issues/1021#issuecomment-983021759) + /// - Parameter tweak: the 32-byte tweak object + /// - Returns: tweaked `PrivateKey` object + func add(xonly tweak: [UInt8]) throws -> Self { + var keypair = secp256k1_keypair() + var privateBytes = [UInt8](repeating: 0, count: secp256k1.ByteDetails.count) + var xonly = secp256k1_xonly_pubkey() + var keyParity = Int32() + + guard secp256k1_keypair_create(secp256k1.Context.raw, &keypair, key.bytes).boolValue, + secp256k1_keypair_xonly_tweak_add(secp256k1.Context.raw, &keypair, tweak).boolValue, + secp256k1_keypair_sec(secp256k1.Context.raw, &privateBytes, &keypair).boolValue, + secp256k1_keypair_xonly_pub(secp256k1.Context.raw, &xonly, &keyParity, &keypair).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return try Self(rawRepresentation: privateBytes) + } + + /// Create a new `PrivateKey` by multiplying tweak to the secret key. + /// - Parameter tweak: the 32-byte tweak object + /// - Returns: tweaked `PrivateKey` object + func multiply(_ tweak: [UInt8]) throws -> Self { + var privateBytes = key.bytes + + guard secp256k1_ec_seckey_tweak_mul(secp256k1.Context.raw, &privateBytes, tweak).boolValue, + secp256k1_ec_seckey_verify(secp256k1.Context.raw, privateBytes).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return try Self(rawRepresentation: privateBytes) + } +} + +public extension secp256k1.Signing.PublicKey { + /// Create a new `PublicKey` by adding tweak to the public key. + /// - Parameters: + /// - tweak: the 32-byte tweak object + /// - format: the format of the tweaked `PublicKey` object + /// - Returns: tweaked `PublicKey` object + func add(_ tweak: [UInt8], format: secp256k1.Format = .compressed) throws -> Self { + var pubKey = secp256k1_pubkey() + var pubKeyLen = format.length + var pubKeyBytes = [UInt8](repeating: 0, count: pubKeyLen) + var xonlyKey = secp256k1_xonly_pubkey() + var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.Schnorr.xonlyByteCount) + var keyParity = Int32() + + guard secp256k1_ec_pubkey_parse(secp256k1.Context.raw, &pubKey, bytes, pubKeyLen).boolValue, + secp256k1_ec_pubkey_tweak_add(secp256k1.Context.raw, &pubKey, tweak).boolValue, + secp256k1_ec_pubkey_serialize(secp256k1.Context.raw, &pubKeyBytes, &pubKeyLen, &pubKey, format.rawValue).boolValue, + secp256k1_xonly_pubkey_from_pubkey(secp256k1.Context.raw, &xonlyKey, &keyParity, &pubKey).boolValue, + secp256k1_xonly_pubkey_serialize(secp256k1.Context.raw, &xonlyBytes, &xonlyKey).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return Self(rawRepresentation: pubKeyBytes, xonly: xonlyBytes, keyParity: keyParity, format: format) + } + + /// Create a new `PublicKey` by multiplying tweak to the public key. + /// - Parameters: + /// - tweak: the 32-byte tweak object + /// - format: the format of the tweaked `PublicKey` object + /// - Returns: tweaked `PublicKey` object + func multiply(_ tweak: [UInt8], format: secp256k1.Format = .compressed) throws -> Self { + var pubKey = secp256k1_pubkey() + var pubKeyLen = format.length + var pubKeyBytes = [UInt8](repeating: 0, count: pubKeyLen) + var xonlyKey = secp256k1_xonly_pubkey() + var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.Schnorr.xonlyByteCount) + var keyParity = Int32() + + guard secp256k1_ec_pubkey_parse(secp256k1.Context.raw, &pubKey, bytes, pubKeyLen).boolValue, + secp256k1_ec_pubkey_tweak_mul(secp256k1.Context.raw, &pubKey, tweak).boolValue, + secp256k1_ec_pubkey_serialize(secp256k1.Context.raw, &pubKeyBytes, &pubKeyLen, &pubKey, format.rawValue).boolValue, + secp256k1_xonly_pubkey_from_pubkey(secp256k1.Context.raw, &xonlyKey, &keyParity, &pubKey).boolValue, + secp256k1_xonly_pubkey_serialize(secp256k1.Context.raw, &xonlyBytes, &xonlyKey).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return Self(rawRepresentation: pubKeyBytes, xonly: xonlyBytes, keyParity: keyParity, format: format) + } +} + +public extension secp256k1.Signing.XonlyKey { + /// Create a new `XonlyKey` by adding tweak to the x-only public key. + /// - Parameters: + /// - tweak: the 32-byte tweak object + /// - format: the format of the tweaked `XonlyKey` object + /// - Returns: tweaked `PublicKey` object + func add(_ tweak: [UInt8]) throws -> Self { + var pubKey = secp256k1_pubkey() + var inXonlyPubKey = secp256k1_xonly_pubkey() + var outXonlyPubKey = secp256k1_xonly_pubkey() + var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.Schnorr.xonlyByteCount) + var keyParity = Int32() + + guard secp256k1_xonly_pubkey_parse(secp256k1.Context.raw, &inXonlyPubKey, bytes).boolValue, + secp256k1_xonly_pubkey_tweak_add(secp256k1.Context.raw, &pubKey, &inXonlyPubKey, tweak).boolValue, + secp256k1_xonly_pubkey_from_pubkey(secp256k1.Context.raw, &outXonlyPubKey, &keyParity, &pubKey).boolValue, + secp256k1_xonly_pubkey_serialize(secp256k1.Context.raw, &xonlyBytes, &outXonlyPubKey).boolValue, + secp256k1_xonly_pubkey_tweak_add_check(secp256k1.Context.raw, &xonlyBytes, keyParity, &inXonlyPubKey, tweak).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return Self(rawRepresentation: xonlyBytes, keyParity: keyParity) + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Utility.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Utility.swift new file mode 100644 index 00000000..781ec786 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Utility.swift @@ -0,0 +1,61 @@ +// +// Utility.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2022 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +public extension ContiguousBytes { + @inlinable var bytes: [UInt8] { + withUnsafeBytes { bytesPtr in Array(bytesPtr) } + } +} + +public extension Data { + @inlinable var bytes: [UInt8] { + withUnsafeBytes { bytesPtr in Array(bytesPtr) } + } + + func copyToUnsafeMutableBytes(of value: inout T) { + _ = Swift.withUnsafeMutableBytes(of: &value) { ptr in + ptr.copyBytes(from: self.prefix(ptr.count)) + } + } +} + +extension Int32 { + var boolValue: Bool { + Bool(truncating: NSNumber(value: self)) + } +} + +public extension secp256k1_ecdsa_signature { + var dataValue: Data { + var mutableSig = self + return Data(bytes: &mutableSig.data, count: MemoryLayout.size(ofValue: data)) + } +} + +public extension String { + /// Public initializer backed by the `BytesUtil.swift` DataProtocol extension property `hexString` + /// - Parameter bytes: byte array to initialize + init(bytes: T) { + self.init() + self = bytes.hexString + } + + /// Public convenience property backed by the `BytesUtil.swift` Array extension initializer + /// - Throws: `ByteHexEncodingErrors` for invalid string or hex value + var bytes: [UInt8] { + get throws { + // The `BytesUtil.swift` Array extension expects lowercase strings + try Array(hexString: lowercased()) + } + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Zeroization.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Zeroization.swift new file mode 100644 index 00000000..2e143148 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/Zeroization.swift @@ -0,0 +1,44 @@ +// +// Zeroization.swift +// GigaBitcoin/secp256k1.swift +// +// Modifications Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// +// +// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC +// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENSE FROM THE +// ORIGINAL WORK OF THE COMPANY Apple Inc. +// +// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT: +// +// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) + + import secp256k1_bindings + + public typealias errno_t = CInt + + @discardableResult + public func memset_s(_ s: UnsafeMutableRawPointer!, _ smax: Int, _ byte: CInt, _ n: Int) -> errno_t { + assert(smax == n, "memset_s invariant not met") + assert(byte == 0, "memset_s used to not zero anything") + secp256k1_swift_memczero(s, smax, 1) + return 0 + } +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/secp256k1.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/secp256k1.swift new file mode 100644 index 00000000..8a494d42 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/secp256k1Swift/secp256k1.swift @@ -0,0 +1,258 @@ +// +// secp256k1.swift +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +import Foundation +import secp256k1Wrapper + +/// The secp256k1 Elliptic Curve. +public enum secp256k1 {} + +/// Flags passed to secp256k1_context_create, secp256k1_context_preallocated_size, and secp256k1_context_preallocated_create. +public extension secp256k1 { + struct Context: OptionSet { + public let rawValue: UInt32 + public init(rawValue: UInt32) { self.rawValue = rawValue } + init(rawValue: Int32) { self.rawValue = UInt32(rawValue) } + public static let declassify = Context(rawValue: SECP256K1_CONTEXT_DECLASSIFY) + public static let none = Context(rawValue: SECP256K1_CONTEXT_NONE) + public static let sign = Context(rawValue: SECP256K1_CONTEXT_SIGN) + public static let verify = Context(rawValue: SECP256K1_CONTEXT_VERIFY) + + public static func create(_ context: Context = .none) throws -> OpaquePointer { + var randomBytes = SecureBytes(count: secp256k1.ByteDetails.count).bytes + guard let context = secp256k1_context_create(context.rawValue), + secp256k1_context_randomize(context, &randomBytes).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return context + } + + static let raw = try! secp256k1.Context.create() + } +} + +/// Flag to pass to secp256k1_ec_pubkey_serialize. +public extension secp256k1 { + enum Format: UInt32 { + case compressed, uncompressed + + public var length: Int { + switch self { + case .compressed: return 33 + case .uncompressed: return 65 + } + } + + public var rawValue: UInt32 { + let value: Int32 + + switch self { + case .compressed: value = SECP256K1_EC_COMPRESSED + case .uncompressed: value = SECP256K1_EC_UNCOMPRESSED + } + + return UInt32(value) + } + } +} + +extension secp256k1 { + @usableFromInline + enum CurveDetails { + @inlinable + static var coordinateByteCount: Int { + 16 + } + } + + @usableFromInline + enum ByteDetails { + @inlinable + static var count: Int { + 32 + } + } +} + +/// Implementations for signing, we use bindings to libsecp256k1 for these operations. + +/// Private key for signing implementation +@usableFromInline struct PrivateKeyImplementation { + /// Backing private key object + private var _privateBytes: SecureBytes + + /// Backing public key object + @usableFromInline let _publicBytes: [UInt8] + + /// Backing x-only public key object + @usableFromInline let _xonlyBytes: [UInt8] + + /// Backing public key format + @usableFromInline let _format: secp256k1.Format + + /// Backing key parity + @usableFromInline var _keyParity: Int32 + + /// Backing implementation for a public key object + @usableFromInline var publicKey: PublicKeyImplementation { + PublicKeyImplementation(_publicBytes, xonly: _xonlyBytes, keyParity: _keyParity, format: _format) + } + + /// Backing secp256k1 private key object + var key: SecureBytes { + _privateBytes + } + + /// A data representation of the backing private key + @usableFromInline var rawRepresentation: Data { + Data(_privateBytes) + } + + /// Backing initialization that creates a random secp256k1 private key for signing + @usableFromInline init(format: secp256k1.Format = .compressed) throws { + let privateKey = SecureBytes(count: secp256k1.ByteDetails.count) + // Verify Private Key here + self._keyParity = 0 + self._format = format + self._privateBytes = privateKey + self._publicBytes = try PublicKeyImplementation.generate(bytes: &_privateBytes, format: format) + self._xonlyBytes = try XonlyKeyImplementation.generate(bytes: _publicBytes, keyParity: &_keyParity, format: format) + } + + /// Backing initialization that creates a secp256k1 private key for signing from a data representation. + /// - Parameter data: A raw representation of the key. + /// - Throws: An error is thrown when the raw representation does not create a private key for signing. + init(rawRepresentation data: D, format: secp256k1.Format = .compressed) throws { + let privateKey = SecureBytes(bytes: data) + // Verify Private Key here + self._keyParity = 0 + self._format = format + self._privateBytes = privateKey + self._publicBytes = try PublicKeyImplementation.generate(bytes: &_privateBytes, format: format) + self._xonlyBytes = try XonlyKeyImplementation.generate(bytes: _publicBytes, keyParity: &_keyParity, format: format) + } +} + +/// Public key for signing implementation +@usableFromInline struct PublicKeyImplementation { + /// Implementation public key object + @usableFromInline let bytes: [UInt8] + + /// Backing x-only public key object + @usableFromInline let _xonlyBytes: [UInt8] + + /// Backing key parity object + @usableFromInline let _keyParity: Int32 + + /// Backing implementation for a public key object + @usableFromInline var xonly: XonlyKeyImplementation { + XonlyKeyImplementation(_xonlyBytes, keyParity: _keyParity) + } + + /// A data representation of the backing public key + @usableFromInline var rawRepresentation: Data { + Data(bytes) + } + + /// A key format representation of the backing public key + @usableFromInline let format: secp256k1.Format + + /// Backing initialization that generates a secp256k1 public key from a raw representation. + /// - Parameter data: A raw representation of the key. + @usableFromInline init(rawRepresentation data: D, xonly: D, keyParity: Int32, format: secp256k1.Format) { + self.bytes = data.bytes + self.format = format + self._xonlyBytes = xonly.bytes + self._keyParity = keyParity + } + + /// Backing initialization that sets the public key from a public key object. + /// - Parameter keyBytes: a public key object + @usableFromInline init(_ bytes: [UInt8], xonly: [UInt8], keyParity: Int32, format: secp256k1.Format) { + self.bytes = bytes + self.format = format + self._xonlyBytes = xonly + self._keyParity = keyParity + } + + /// Generates a secp256k1 public key from bytes representation. + /// - Parameter privateBytes: a private key object in bytes form + /// - Returns: a public key object + /// - Throws: An error is thrown when the bytes does not create a public key. + static func generate(bytes privateBytes: inout SecureBytes, format: secp256k1.Format) throws -> [UInt8] { + guard privateBytes.count == secp256k1.ByteDetails.count else { + throw secp256k1Error.incorrectKeySize + } + + var pubKeyLen = format.length + var pubKey = secp256k1_pubkey() + var pubBytes = [UInt8](repeating: 0, count: pubKeyLen) + + guard secp256k1_ec_seckey_verify(secp256k1.Context.raw, privateBytes.bytes).boolValue, + secp256k1_ec_pubkey_create(secp256k1.Context.raw, &pubKey, privateBytes.bytes).boolValue, + secp256k1_ec_pubkey_serialize(secp256k1.Context.raw, &pubBytes, &pubKeyLen, &pubKey, format.rawValue).boolValue + else { + throw secp256k1Error.underlyingCryptoError + } + + return pubBytes + } +} + +/// Public X-only public key for Schnorr implementation +@usableFromInline struct XonlyKeyImplementation { + /// Implementation x-only public key object + @usableFromInline let bytes: [UInt8] + + /// A data representation of the backing x-only public key + @usableFromInline var rawRepresentation: Data { + Data(bytes) + } + + /// Backing key parity object + @usableFromInline let keyParity: Int32 + + /// Backing initialization that generates a x-only public key from a raw representation. + /// - Parameter data: A raw representation of the key. + @usableFromInline init(rawRepresentation data: D, keyParity: Int32) { + self.bytes = data.bytes + self.keyParity = keyParity + } + + /// Backing initialization that sets the public key from a x-only public key object. + /// - Parameter bytes: a x-only public key in byte form + @usableFromInline init(_ bytes: [UInt8], keyParity: Int32) { + self.bytes = bytes + self.keyParity = keyParity + } + + /// Create a x-only public key from bytes representation. + /// - Parameter privateBytes: a private key object in byte form + /// - Returns: a public key object + /// - Throws: An error is thrown when the bytes does not create a public key. + static func generate(bytes publicBytes: [UInt8], keyParity: inout Int32, format: secp256k1.Format) throws -> [UInt8] { + guard publicBytes.count == format.length else { + throw secp256k1Error.incorrectKeySize + } + + var pubKey = secp256k1_pubkey() + var xonlyPubKey = secp256k1_xonly_pubkey() + var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.ByteDetails.count) + + guard secp256k1_ec_pubkey_parse(secp256k1.Context.raw, &pubKey, publicBytes, format.length).boolValue, + secp256k1_xonly_pubkey_from_pubkey(secp256k1.Context.raw, &xonlyPubKey, &keyParity, &pubKey).boolValue, + secp256k1_xonly_pubkey_serialize(secp256k1.Context.raw, &xonlyBytes, &xonlyPubKey).boolValue else { + throw secp256k1Error.underlyingCryptoError + } + + return xonlyBytes + } +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Digests/Digest.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Digests/Digest.swift new file mode 100644 index 00000000..49f947f8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Digests/Digest.swift @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +import Foundation + +/// A protocol defining requirements for digests +public protocol Digest: Hashable, ContiguousBytes, CustomStringConvertible, Sequence where Element == UInt8 { + static var byteCount: Int { get } +} + +protocol DigestPrivate: Digest { + init?(bufferPointer: UnsafeRawBufferPointer) +} + +extension DigestPrivate { + @inlinable + init?(bytes: [UInt8]) { + let some = bytes.withUnsafeBytes { bufferPointer in + return Self(bufferPointer: bufferPointer) + } + + if some != nil { + self = some! + } else { + return nil + } + } +} + +extension Digest { + public func makeIterator() -> Array.Iterator { + self.withUnsafeBytes({ (buffPtr) in + return Array(buffPtr).makeIterator() + }) + } +} + +// We want to implement constant-time comparison for digests. +extension Digest { + public static func == (lhs: Self, rhs: Self) -> Bool { + return safeCompare(lhs, rhs) + } + + public static func == (lhs: Self, rhs: D) -> Bool { + if rhs.regions.count != 1 { + let rhsContiguous = Data(rhs) + return safeCompare(lhs, rhsContiguous) + } else { + return safeCompare(lhs, rhs.regions.first!) + } + } + + public var description: String { + return "\(Self.self): \(Array(self).hexString)" + } +} +#endif // Linux or !SwiftPM diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Signatures/Signature.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Signatures/Signature.swift new file mode 100644 index 00000000..b9357af7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Signatures/Signature.swift @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +import Foundation + +protocol SignatureVerification { + func verifySignature(signature: Data, data: Data) throws -> Bool +} + +protocol DigestSigner { + associatedtype Signature + func signature(for digest: D) throws -> Signature +} + +protocol Signer { + associatedtype Signature + func signature(for data: D) throws -> Signature +} +#endif // Linux or !SwiftPM diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift new file mode 100644 index 00000000..2183f4b9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else + +extension UnsafeMutableRawBufferPointer { + func initializeWithRandomBytes(count: Int) { + guard count > 0 else { + return + } + + precondition(count <= self.count) + var rng = SystemRandomNumberGenerator() + + // We store bytes 64-bits at a time until we can't anymore. + var targetPtr = self + while targetPtr.count > 8 { + targetPtr.storeBytes(of: rng.next(), as: UInt64.self) + targetPtr = UnsafeMutableRawBufferPointer(rebasing: targetPtr[8...]) + } + + // Now we're down to having to store things an integer at a time. We do this by shifting and + // masking. + var remainingWord: UInt64 = rng.next() + while targetPtr.count > 0 { + targetPtr.storeBytes(of: UInt8(remainingWord & 0xFF), as: UInt8.self) + remainingWord >>= 8 + targetPtr = UnsafeMutableRawBufferPointer(rebasing: targetPtr[1...]) + } + } +} + +#endif // (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/SecureBytes.swift b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/SecureBytes.swift new file mode 100644 index 00000000..5c0805bc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Swift/Sources/swift-crypto/Sources/Crypto/Util/SecureBytes.swift @@ -0,0 +1,492 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.md for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +import Foundation + +struct SecureBytes { + @usableFromInline + var backing: Backing + + @inlinable + init() { + self = .init(count: 0) + } + + @usableFromInline + init(count: Int) { + self.backing = SecureBytes.Backing.create(randomBytes: count) + } + + init(bytes: D) { + self.backing = Backing.create(bytes: bytes) + } + + /// Allows initializing a SecureBytes object with a closure that will initialize the memory. + @usableFromInline + init(unsafeUninitializedCapacity: Int, initializingWith callback: (inout UnsafeMutableRawBufferPointer, inout Int) throws -> Void) rethrows { + self.backing = Backing.create(capacity: unsafeUninitializedCapacity) + try self.backing._withVeryUnsafeMutableBytes { veryUnsafePointer in + // As Array does, we want to truncate the initializing pointer to only have the requested size. + var veryUnsafePointer = UnsafeMutableRawBufferPointer(rebasing: veryUnsafePointer.prefix(unsafeUninitializedCapacity)) + var initializedCount = 0 + try callback(&veryUnsafePointer, &initializedCount) + + self.backing.count = initializedCount + } + } +} + +extension SecureBytes { + @inlinable + mutating func append(_ data: C) where C.Element == UInt8 { + let requiredCapacity = self.count + data.count + if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > self.backing.capacity { + let newBacking = Backing.create(capacity: requiredCapacity) + newBacking._appendBytes(self.backing, inRange: 0..= n { + return + } + + let newBacking = Backing.create(capacity: n) + newBacking._appendBytes(self.backing, inRange: 0.. Bool { + return safeCompare(lhs, rhs) + } +} + +// MARK: - Collection conformance +extension SecureBytes: Collection { + @usableFromInline + struct Index { + /* fileprivate but usableFromInline */ @usableFromInline var offset: Int + + /*@inlinable*/ @usableFromInline internal init(offset: Int) { + self.offset = offset + } + } + + @inlinable + var startIndex: Index { + return Index(offset: 0) + } + + @inlinable + var endIndex: Index { + return Index(offset: self.count) + } + + @inlinable + var count: Int { + return self.backing.count + } + + @inlinable + subscript(_ index: Index) -> UInt8 { + get { + return self.backing[offset: index.offset] + } + set { + self.backing[offset: index.offset] = newValue + } + } + + @inlinable + func index(after index: Index) -> Index { + return index.advanced(by: 1) + } +} + +// MARK: - BidirectionalCollection conformance +extension SecureBytes: BidirectionalCollection { + @inlinable + func index(before index: Index) -> Index { + return index.advanced(by: -1) + } +} + +// MARK: - RandomAccessCollection conformance +extension SecureBytes: RandomAccessCollection { } + +// MARK: - MutableCollection conformance +extension SecureBytes: MutableCollection { } + +// MARK: - RangeReplaceableCollection conformance +extension SecureBytes: RangeReplaceableCollection { + @inlinable + mutating func replaceSubrange(_ subrange: Range, with newElements: C) where C.Element == UInt8 { + let requiredCapacity = self.backing.count - subrange.count + newElements.count + + if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > self.backing.capacity { + // We have to allocate anyway, so let's use a nice straightforward copy. + let newBacking = Backing.create(capacity: requiredCapacity) + + let lowerSlice = 0..(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + return try self.backing.withUnsafeBytes(body) + } + + @inlinable + mutating func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + if !isKnownUniquelyReferenced(&self.backing) { + self.backing = Backing.create(copying: self.backing) + } + + return try self.backing.withUnsafeMutableBytes(body) + } +} + +// MARK: - DataProtocol conformance +extension SecureBytes: DataProtocol { + @inlinable + var regions: CollectionOfOne { + return CollectionOfOne(self) + } +} + +// MARK: - MutableDataProtocol conformance +extension SecureBytes: MutableDataProtocol { } + +// MARK: - Index conformances +extension SecureBytes.Index: Hashable { } + +extension SecureBytes.Index: Comparable { + static func <(lhs: SecureBytes.Index, rhs: SecureBytes.Index) -> Bool { + return lhs.offset < rhs.offset + } +} + +extension SecureBytes.Index: Strideable { + func advanced(by n: Int) -> SecureBytes.Index { + return SecureBytes.Index(offset: self.offset + n) + } + + func distance(to other: SecureBytes.Index) -> Int { + return other.offset - self.offset + } +} + +// MARK: - Heap allocated backing storage. +extension SecureBytes { + @usableFromInline + internal struct BackingHeader { + @usableFromInline + internal var count: Int + + @usableFromInline + internal var capacity: Int + } + + @usableFromInline + internal class Backing: ManagedBuffer { + @usableFromInline + class func create(capacity: Int) -> Backing { + let capacity = Int(UInt32(capacity).nextPowerOf2ClampedToMax()) + return Backing.create(minimumCapacity: capacity, makingHeaderWith: { _ in BackingHeader(count: 0, capacity: capacity) }) as! Backing + } + + @usableFromInline + class func create(copying original: Backing) -> Backing { + return Backing.create(bytes: original) + } + + @inlinable + class func create(bytes: D) -> Backing { + return bytes.withUnsafeBytes { bytesPtr in + let backing = Backing.create(capacity: bytesPtr.count) + backing._withVeryUnsafeMutableBytes { targetPtr in + targetPtr.copyMemory(from: bytesPtr) + } + backing.count = bytesPtr.count + precondition(backing.count <= backing.capacity) + return backing + } + } + + @usableFromInline + class func create(randomBytes: Int) -> Backing { + let backing = Backing.create(capacity: randomBytes) + backing._withVeryUnsafeMutableBytes { targetPtr in + assert(targetPtr.count >= randomBytes) + targetPtr.initializeWithRandomBytes(count: randomBytes) + } + backing.count = randomBytes + return backing + } + + deinit { + // We always clear the whole capacity, even if we don't think we used it all. + let bytesToClear = self.header.capacity + + _ = self.withUnsafeMutablePointerToElements { elementsPtr in + memset_s(elementsPtr, bytesToClear, 0, bytesToClear) + } + } + + @usableFromInline + var count: Int { + get { + return self.header.count + } + set { + self.header.count = newValue + } + } + + @usableFromInline + subscript(offset offset: Int) -> UInt8 { + get { + // precondition(offset >= 0 && offset < self.count) + return self.withUnsafeMutablePointerToElements { return ($0 + offset).pointee } + } + set { + // precondition(offset >= 0 && offset < self.count) + return self.withUnsafeMutablePointerToElements { ($0 + offset).pointee = newValue } + } + } + } +} + +extension SecureBytes.Backing { + func replaceSubrangeFittingWithinCapacity(_ subrange: Range, with newElements: C) where C.Element == UInt8 { + // This function is called when have a unique reference to the backing storage, and we have enough room to store these bytes without + // any problem. We have one pre-existing buffer made up of 4 regions: a prefix set of bytes that are + // before the range "subrange", a range of bytes to be replaced (R1), a suffix set of bytes that are after + // the range "subrange" but within the valid count, and then a region of uninitialized memory. We also have + // a new set of bytes, R2, that may be larger or smaller than R1, and could indeed be empty! + // + // ┌────────────────────────┬──────────────────┬──────────────────┬───────────────┐ + // │ Prefix │ R1 │ Suffix │ Uninitialized │ + // └────────────────────────┴──────────────────┴──────────────────┴───────────────┘ + // + // ┌─────────────────────────────────────┐ + // │ R2 │ + // └─────────────────────────────────────┘ + // + // The minimal number of steps we can take in the general case is two steps. We can't just copy R2 into the space + // for R1 and then move the suffix, as if R2 is larger than R1 we'll have thrown some suffix bytes away. So we have + // to move suffix first. What we do is take the bytes in suffix, and move them (via memmove). We can then copy + // R2 in, and feel confident that the space in memory is right. + precondition(self.count - subrange.count + newElements.count <= self.capacity, "Insufficient capacity") + + let moveDistance = newElements.count - subrange.count + let suffixRange = subrange.upperBound..(_ bytes: C) where C.Element == UInt8 { + let byteCount = bytes.count + + precondition(self.capacity - self.count - byteCount >= 0, "Insufficient space for byte copying, must have reallocated!") + + let lowerOffset = self.count + self._withVeryUnsafeMutableBytes { bytesPtr in + let innerPtrSlice = UnsafeMutableRawBufferPointer(rebasing: bytesPtr[lowerOffset...]) + innerPtrSlice.copyBytes(from: bytes) + } + self.count += byteCount + } + + /// Appends the bytes of a slice of another backing buffer to this storage, crashing if there + /// is not enough room. + /* private but inlinable */ func _appendBytes(_ backing: SecureBytes.Backing, inRange range: Range) { + precondition(range.lowerBound >= 0) + precondition(range.upperBound <= backing.capacity) + precondition(self.capacity - self.count - range.count >= 0, "Insufficient space for byte copying, must have reallocated!") + + backing.withUnsafeBytes { backingPtr in + let ptrSlice = UnsafeRawBufferPointer(rebasing: backingPtr[range]) + + let lowerOffset = self.count + self._withVeryUnsafeMutableBytes { bytesPtr in + let innerPtrSlice = UnsafeMutableRawBufferPointer(rebasing: bytesPtr[lowerOffset...]) + innerPtrSlice.copyMemory(from: ptrSlice) + } + self.count += ptrSlice.count + } + } + + /// Moves the range of bytes identified by the slice by the delta, crashing if the move would + /// place the bytes out of the storage. Note that this does not update the count: external code + /// must ensure that that happens. + @usableFromInline + /* private but usableFromInline */ func _moveBytes(range: Range, by delta: Int) { + // We have to check that the range is within the delta, as is the new location. + precondition(range.lowerBound >= 0) + precondition(range.upperBound <= self.capacity) + + let shiftedRange = (range.lowerBound + delta)..<(range.upperBound + delta) + precondition(shiftedRange.lowerBound > 0) + precondition(shiftedRange.upperBound <= self.capacity) + + self._withVeryUnsafeMutableBytes { backingPtr in + let source = UnsafeRawBufferPointer(rebasing: backingPtr[range]) + let dest = UnsafeMutableRawBufferPointer(rebasing: backingPtr[shiftedRange]) + dest.copyMemory(from: source) // copy memory uses memmove under the hood. + } + } + + // Copies some bytes into the buffer at the appropriate place. Does not update count: external code must do so. + @inlinable + /* private but inlinable */ func _copyBytes(_ bytes: C, at offset: Int) where C.Element == UInt8 { + precondition(offset >= 0) + precondition(offset + bytes.count <= self.capacity) + + let byteRange = offset..<(offset + bytes.count) + + self._withVeryUnsafeMutableBytes { backingPtr in + let dest = UnsafeMutableRawBufferPointer(rebasing: backingPtr[byteRange]) + dest.copyBytes(from: bytes) + } + } +} + +extension SecureBytes.Backing: ContiguousBytes { + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { + let count = self.count + + return try self.withUnsafeMutablePointerToElements { elementsPtr in + return try body(UnsafeRawBufferPointer(start: elementsPtr, count: count)) + } + } + + func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + let count = self.count + + return try self.withUnsafeMutablePointerToElements { elementsPtr in + return try body(UnsafeMutableRawBufferPointer(start: elementsPtr, count: count)) + } + } + + /// Very unsafe in the sense that this points to uninitialized memory. Used only for implementations within this file. + @inlinable + /* private but inlinable */ func _withVeryUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + let capacity = self.capacity + + return try self.withUnsafeMutablePointerToElements { elementsPtr in + return try body(UnsafeMutableRawBufferPointer(start: elementsPtr, count: capacity)) + } + } +} + +extension UInt32 { + /// Returns the next power of two unless that would overflow, in which case UInt32.max (on 64-bit systems) or + /// Int32.max (on 32-bit systems) is returned. The returned value is always safe to be cast to Int and passed + /// to malloc on all platforms. + func nextPowerOf2ClampedToMax() -> UInt32 { + guard self > 0 else { + return 1 + } + + var n = self + + #if arch(arm) || arch(i386) + // on 32-bit platforms we can't make use of a whole UInt32.max (as it doesn't fit in an Int) + let max = UInt32(Int.max) + #else + // on 64-bit platforms we're good + let max = UInt32.max + #endif + + n -= 1 + n |= n >> 1 + n |= n >> 2 + n |= n >> 4 + n |= n >> 8 + n |= n >> 16 + if n != max { + n += 1 + } + + return n + } +} + +extension Data { + /// A custom initializer for Data that attempts to share the same storage as the current SecureBytes instance. + /// This is our best-effort attempt to expose the data in an auto-zeroing fashion. Any mutating function called on + /// the constructed `Data` object will cause the bytes to be copied out: we can't avoid that. + init(_ secureBytes: SecureBytes) { + // We need to escape into unmanaged land here in order to keep the backing storage alive. + let unmanagedBacking = Unmanaged.passRetained(secureBytes.backing) + + // We can now exfiltrate the storage pointer: this particular layout will be locked forever. Please never do this + // yourself unless you're really sure! + self = secureBytes.withUnsafeBytes { + // We make a mutable copy of this pointer here because we know Data won't write through it. + return Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: $0.baseAddress!), count: $0.count, deallocator: .custom { (_: UnsafeMutableRawPointer, _: Int) in unmanagedBacking.release() }) + } + } + + /// A custom initializer for Data that attempts to share the same storage as the current SecureBytes instance. + /// This is our best-effort attempt to expose the data in an auto-zeroing fashion. Any mutating function called on the + /// constructed `Data` object will cause the bytes to be copied out: we can't avoid that. + init(_ secureByteSlice: Slice) { + // We have a trick here: we use the same function as the one above, but we use the indices of the slice to bind + // the scope of the pointer we pass to Data. + let base = secureByteSlice.base + let baseOffset = secureByteSlice.startIndex.offset + let endOffset = secureByteSlice.endIndex.offset + + // We need to escape into unmanaged land here in order to keep the backing storage alive. + let unmanagedBacking = Unmanaged.passRetained(base.backing) + + // We can now exfiltrate the storage pointer: this particular layout will be locked forever. Please never do this + // yourself unless you're really sure! + self = base.withUnsafeBytes { + // Slice the base pointer down to just the range we want. + let slicedPointer = UnsafeRawBufferPointer(rebasing: $0[baseOffset.. UInt8 { + return (value > 9) ? (charA + value - 10) : (char0 + value) +} + +private func htoi(_ value: UInt8) throws -> UInt8 { + switch value { + case char0...char0 + 9: + return value - char0 + case charA...charA + 5: + return value - charA + 10 + default: + throw ByteHexEncodingErrors.incorrectHexValue + } +} + +extension Array where Element == UInt8 { + init(hexString: String) throws { + self.init() + + guard hexString.count.isMultiple(of: 2), !hexString.isEmpty else { + throw ByteHexEncodingErrors.incorrectString + } + + let stringBytes: [UInt8] = Array(hexString.data(using: String.Encoding.utf8)!) + + for i in 0...((hexString.count / 2) - 1) { + let char1 = stringBytes[2 * i] + let char2 = stringBytes[2 * i + 1] + + try self.append(htoi(char1) << 4 + htoi(char2)) + } + } + +} + +extension DataProtocol { + var hexString: String { + get { + let hexLen = self.count * 2 + let ptr = UnsafeMutablePointer.allocate(capacity: hexLen) + var offset = 0 + + self.regions.forEach { (_) in + for i in self { + ptr[Int(offset * 2)] = itoh((i >> 4) & 0xF) + ptr[Int(offset * 2 + 1)] = itoh(i & 0xF) + offset += 1 + } + } + + return String(bytesNoCopy: ptr, length: hexLen, encoding: .utf8, freeWhenDone: true)! + } + } +} + +extension Data { + init(hexString: String) throws { + self.init() + + if hexString.count == 0 { + return + } + + if hexString.count % 2 != 0 { + throw ByteHexEncodingErrors.incorrectString + } + + let stringBytes: [UInt8] = Array(hexString.data(using: String.Encoding.utf8)!) + + for i in 0...((hexString.count / 2) - 1) { + let char1 = stringBytes[2 * i] + let char2 = stringBytes[2 * i + 1] + + try self.append(htoi(char1) << 4 + htoi(char2)) + } + } + +} diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/COPYING b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/COPYING new file mode 100644 index 00000000..4522a599 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/COPYING @@ -0,0 +1,19 @@ +Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/README.md b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/README.md new file mode 100644 index 00000000..f5db915e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/README.md @@ -0,0 +1,118 @@ +libsecp256k1 +============ + +[![Build Status](https://api.cirrus-ci.com/github/bitcoin-core/secp256k1.svg?branch=master)](https://cirrus-ci.com/github/bitcoin-core/secp256k1) + +Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1. + +This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose. + +Features: +* secp256k1 ECDSA signing/verification and key generation. +* Additive and multiplicative tweaking of secret/public keys. +* Serialization/parsing of secret keys, public keys, signatures. +* Constant time, constant memory access signing and public key generation. +* Derandomized ECDSA (via RFC6979 or with a caller provided function.) +* Very efficient implementation. +* Suitable for embedded systems. +* Optional module for public key recovery. +* Optional module for ECDH key exchange. +* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + +Implementation details +---------------------- + +* General + * No runtime heap allocation. + * Extensive testing infrastructure. + * Structured to facilitate review and analysis. + * Intended to be portable to any system with a C89 compiler and uint64_t support. + * No use of floating types. + * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") +* Field operations + * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). + * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). + * Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan). + * This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community. +* Scalar operations + * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. + * Using 4 64-bit limbs (relying on __int128 support in the compiler). + * Using 8 32-bit limbs. +* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman). +* Group operations + * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). + * Use addition between points in Jacobian and affine coordinates where possible. + * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. + * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. +* Point multiplication for verification (a*P + b*G). + * Use wNAF notation for point multiplicands. + * Use a much larger window for multiples of G, using precomputed multiples. + * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. + * Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. +* Point multiplication for signing + * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. + * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) + * Access the table with branch-free conditional moves so memory access is uniform. + * No data-dependent branches + * Optional runtime blinding which attempts to frustrate differential power analysis. + * The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally. + +Build steps +----------- + +libsecp256k1 is built using autotools: + + $ ./autogen.sh + $ ./configure + $ make + $ make check # run the test suite + $ sudo make install # optional + +To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. + +Usage examples +----------- + Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`. + * [ECDSA example](examples/ecdsa.c) + * [Schnorr signatures example](examples/schnorr.c) + * [Deriving a shared secret (ECDH) example](examples/ecdh.c) + To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`. + +Test coverage +----------- + +This library aims to have full coverage of the reachable lines and branches. + +To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary): + + $ ./configure --enable-coverage + +Run the tests: + + $ make check + +To create a report, `gcovr` is recommended, as it includes branch coverage reporting: + + $ gcovr --exclude 'src/bench*' --print-summary + +To create a HTML report with coloured and annotated source code: + + $ mkdir -p coverage + $ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html + +Benchmark +------------ +If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build. + +To print the benchmark result to the command line: + + $ ./bench_name + +To create a CSV file for the benchmark result : + + $ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv + +Reporting a vulnerability +------------ + +See [SECURITY.md](SECURITY.md) diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1.h new file mode 100644 index 00000000..e3cc12f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1.h @@ -0,0 +1,849 @@ +#ifndef SECP256K1_H +#define SECP256K1_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Unless explicitly stated all pointer arguments must not be NULL. + * + * The following rules specify the order of arguments in API calls: + * + * 1. Context pointers go first, followed by output arguments, combined + * output/input arguments, and finally input-only arguments. + * 2. Array lengths always immediately follow the argument whose length + * they describe, even if this violates rule 1. + * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated + * later go first. This means: signatures, public nonces, secret nonces, + * messages, public keys, secret keys, tweaks. + * 4. Arguments that are not data pointers go last, from more complex to less + * complex: function pointers, algorithm names, messages, void pointers, + * counts, flags, booleans. + * 5. Opaque data pointers follow the function pointer they are to be passed to. + */ + +/** Opaque data structure that holds context information (precomputed tables etc.). + * + * The purpose of context structures is to cache large precomputed data tables + * that are expensive to construct, and also to maintain the randomization data + * for blinding. + * + * Do not create a new context object for each operation, as construction is + * far slower than all other API calls (~100 times slower than an ECDSA + * verification). + * + * A constructed context can safely be used from multiple threads + * simultaneously, but API calls that take a non-const pointer to a context + * need exclusive access to it. In particular this is the case for + * secp256k1_context_destroy, secp256k1_context_preallocated_destroy, + * and secp256k1_context_randomize. + * + * Regarding randomization, either do it once at creation time (in which case + * you do not need any locking for the other calls), or use a read-write lock. + */ +typedef struct secp256k1_context_struct secp256k1_context; + +/** Opaque data structure that holds rewriteable "scratch space" + * + * The purpose of this structure is to replace dynamic memory allocations, + * because we target architectures where this may not be available. It is + * essentially a resizable (within specified parameters) block of bytes, + * which is initially created either by memory allocation or TODO as a pointer + * into some fixed rewritable space. + * + * Unlike the context object, this cannot safely be shared between threads + * without additional synchronization logic. + */ +typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space; + +/** Opaque data structure that holds a parsed and valid public key. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, + * use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To + * compare keys, use secp256k1_ec_pubkey_cmp. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_pubkey; + +/** Opaque data structured that holds a parsed ECDSA signature. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_parse_* functions. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_ecdsa_signature; + +/** A pointer to a function to deterministically generate a nonce. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. + * Out: nonce32: pointer to a 32-byte array to be filled by the function. + * In: msg32: the 32-byte message hash being verified (will not be NULL) + * key32: pointer to a 32-byte secret key (will not be NULL) + * algo16: pointer to a 16-byte array describing the signature + * algorithm (will be NULL for ECDSA for compatibility). + * data: Arbitrary data pointer that is passed through. + * attempt: how many iterations we have tried to find a nonce. + * This will almost always be 0, but different attempt values + * are required to result in a different nonce. + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the algorithm, the key and the attempt. + */ +typedef int (*secp256k1_nonce_function)( + unsigned char *nonce32, + const unsigned char *msg32, + const unsigned char *key32, + const unsigned char *algo16, + void *data, + unsigned int attempt +); + +# if !defined(SECP256K1_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define SECP256K1_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define SECP256K1_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if SECP256K1_GNUC_PREREQ(2,7) +# define SECP256K1_INLINE __inline__ +# elif (defined(_MSC_VER)) +# define SECP256K1_INLINE __inline +# else +# define SECP256K1_INLINE +# endif +# else +# define SECP256K1_INLINE inline +# endif + +/** When this header is used at build-time the SECP256K1_BUILD define needs to be set + * to correctly setup export attributes and nullness checks. This is normally done + * by secp256k1.c but to guard against this header being included before secp256k1.c + * has had a chance to set the define (e.g. via test harnesses that just includes + * secp256k1.c) we set SECP256K1_NO_BUILD when this header is processed without the + * BUILD define so this condition can be caught. + */ +#ifndef SECP256K1_BUILD +# define SECP256K1_NO_BUILD +#endif + +/** At secp256k1 build-time DLL_EXPORT is defined when building objects destined + * for a shared library, but not for those intended for static libraries. + */ + +#ifndef SECP256K1_API +# if defined(_WIN32) +# if defined(SECP256K1_BUILD) && defined(DLL_EXPORT) +# define SECP256K1_API __declspec(dllexport) +# else +# define SECP256K1_API +# endif +# elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) +# define SECP256K1_API __attribute__ ((visibility ("default"))) +# else +# define SECP256K1_API +# endif +#endif + +/**Warning attributes + * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out + * some paranoid null checks. */ +# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) +# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +# else +# define SECP256K1_WARN_UNUSED_RESULT +# endif +# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) +# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +# else +# define SECP256K1_ARG_NONNULL(_x) +# endif + +/** Attribute for marking functions, types, and variables as deprecated */ +#if !defined(SECP256K1_BUILD) && defined(__has_attribute) +# if __has_attribute(__deprecated__) +# define SECP256K1_DEPRECATED(_msg) __attribute__ ((__deprecated__(_msg))) +# else +# define SECP256K1_DEPRECATED(_msg) +# endif +#else +# define SECP256K1_DEPRECATED(_msg) +#endif + +/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ +#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) +#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) +#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) +/** The higher bits contain the actual data. Do not use directly. */ +#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) +#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) +#define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10) +#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) + +/** Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and + * secp256k1_context_preallocated_create. */ +#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) +#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) +#define SECP256K1_CONTEXT_DECLASSIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY) +#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) + +/** Flag to pass to secp256k1_ec_pubkey_serialize. */ +#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) +#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) + +/** Prefix byte used to tag various encoded curvepoints for specific purposes */ +#define SECP256K1_TAG_PUBKEY_EVEN 0x02 +#define SECP256K1_TAG_PUBKEY_ODD 0x03 +#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04 +#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 +#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 + +/** A simple secp256k1 context object with no precomputed tables. These are useful for + * type serialization/parsing functions which require a context object to maintain + * API consistency, but currently do not require expensive precomputations or dynamic + * allocations. + */ +SECP256K1_API extern const secp256k1_context *secp256k1_context_no_precomp; + +/** Create a secp256k1 context object (in dynamically allocated memory). + * + * This function uses malloc to allocate memory. It is guaranteed that malloc is + * called at most once for every call of this function. If you need to avoid dynamic + * memory allocation entirely, see the functions in secp256k1_preallocated.h. + * + * Returns: a newly created context object. + * In: flags: which parts of the context to initialize. + * + * See also secp256k1_context_randomize. + */ +SECP256K1_API secp256k1_context* secp256k1_context_create( + unsigned int flags +) SECP256K1_WARN_UNUSED_RESULT; + +/** Copy a secp256k1 context object (into dynamically allocated memory). + * + * This function uses malloc to allocate memory. It is guaranteed that malloc is + * called at most once for every call of this function. If you need to avoid dynamic + * memory allocation entirely, see the functions in secp256k1_preallocated.h. + * + * Returns: a newly created context object. + * Args: ctx: an existing context to copy + */ +SECP256K1_API secp256k1_context* secp256k1_context_clone( + const secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + +/** Destroy a secp256k1 context object (created in dynamically allocated memory). + * + * The context pointer may not be used afterwards. + * + * The context to destroy must have been created using secp256k1_context_create + * or secp256k1_context_clone. If the context has instead been created using + * secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone, the + * behaviour is undefined. In that case, secp256k1_context_preallocated_destroy must + * be used instead. + * + * Args: ctx: an existing context to destroy, constructed using + * secp256k1_context_create or secp256k1_context_clone + */ +SECP256K1_API void secp256k1_context_destroy( + secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1); + +/** Set a callback function to be called when an illegal argument is passed to + * an API call. It will only trigger for violations that are mentioned + * explicitly in the header. + * + * The philosophy is that these shouldn't be dealt with through a + * specific return value, as calling code should not have branches to deal with + * the case that this code itself is broken. + * + * On the other hand, during debug stage, one would want to be informed about + * such mistakes, and the default (crashing) may be inadvisable. + * When this callback is triggered, the API function called is guaranteed not + * to cause a crash, though its return value and output arguments are + * undefined. + * + * When this function has not been called (or called with fn==NULL), then the + * default handler will be used. The library provides a default handler which + * writes the message to stderr and calls abort. This default handler can be + * replaced at link time if the preprocessor macro + * USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build + * has been configured with --enable-external-default-callbacks. Then the + * following two symbols must be provided to link against: + * - void secp256k1_default_illegal_callback_fn(const char* message, void* data); + * - void secp256k1_default_error_callback_fn(const char* message, void* data); + * The library can call these default handlers even before a proper callback data + * pointer could have been set using secp256k1_context_set_illegal_callback or + * secp256k1_context_set_error_callback, e.g., when the creation of a context + * fails. In this case, the corresponding default handler will be called with + * the data pointer argument set to NULL. + * + * Args: ctx: an existing context object. + * In: fun: a pointer to a function to call when an illegal argument is + * passed to the API, taking a message and an opaque pointer. + * (NULL restores the default handler.) + * data: the opaque pointer to pass to fun above, must be NULL for the default handler. + * + * See also secp256k1_context_set_error_callback. + */ +SECP256K1_API void secp256k1_context_set_illegal_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data +) SECP256K1_ARG_NONNULL(1); + +/** Set a callback function to be called when an internal consistency check + * fails. The default is crashing. + * + * This can only trigger in case of a hardware failure, miscompilation, + * memory corruption, serious bug in the library, or other error would can + * otherwise result in undefined behaviour. It will not trigger due to mere + * incorrect usage of the API (see secp256k1_context_set_illegal_callback + * for that). After this callback returns, anything may happen, including + * crashing. + * + * Args: ctx: an existing context object. + * In: fun: a pointer to a function to call when an internal error occurs, + * taking a message and an opaque pointer (NULL restores the + * default handler, see secp256k1_context_set_illegal_callback + * for details). + * data: the opaque pointer to pass to fun above, must be NULL for the default handler. + * + * See also secp256k1_context_set_illegal_callback. + */ +SECP256K1_API void secp256k1_context_set_error_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data +) SECP256K1_ARG_NONNULL(1); + +/** Create a secp256k1 scratch space object. + * + * Returns: a newly created scratch space. + * Args: ctx: an existing context object. + * In: size: amount of memory to be available as scratch space. Some extra + * (<100 bytes) will be allocated for extra accounting. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create( + const secp256k1_context* ctx, + size_t size +) SECP256K1_ARG_NONNULL(1); + +/** Destroy a secp256k1 scratch space. + * + * The pointer may not be used afterwards. + * Args: ctx: a secp256k1 context object. + * scratch: space to destroy + */ +SECP256K1_API void secp256k1_scratch_space_destroy( + const secp256k1_context* ctx, + secp256k1_scratch_space* scratch +) SECP256K1_ARG_NONNULL(1); + +/** Parse a variable-length public key into the pubkey object. + * + * Returns: 1 if the public key was fully valid. + * 0 if the public key could not be parsed or is invalid. + * Args: ctx: a secp256k1 context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a + * parsed version of input. If not, its value is undefined. + * In: input: pointer to a serialized public key + * inputlen: length of the array pointed to by input + * + * This function supports parsing compressed (33 bytes, header byte 0x02 or + * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header + * byte 0x06 or 0x07) format public keys. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( + const secp256k1_context* ctx, + secp256k1_pubkey* pubkey, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a pubkey object into a serialized byte sequence. + * + * Returns: 1 always. + * Args: ctx: a secp256k1 context object. + * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if + * compressed==1) byte array to place the serialized key + * in. + * In/Out: outputlen: a pointer to an integer which is initially set to the + * size of output, and is overwritten with the written + * size. + * In: pubkey: a pointer to a secp256k1_pubkey containing an + * initialized public key. + * flags: SECP256K1_EC_COMPRESSED if serialization should be in + * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. + */ +SECP256K1_API int secp256k1_ec_pubkey_serialize( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_pubkey* pubkey, + unsigned int flags +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Compare two public keys using lexicographic (of compressed serialization) order + * + * Returns: <0 if the first public key is less than the second + * >0 if the first public key is greater than the second + * 0 if the two public keys are equal + * Args: ctx: a secp256k1 context object. + * In: pubkey1: first public key to compare + * pubkey2: second public key to compare + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp( + const secp256k1_context* ctx, + const secp256k1_pubkey* pubkey1, + const secp256k1_pubkey* pubkey2 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse an ECDSA signature in compact (64 bytes) format. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to the 64-byte array to parse + * + * The signature must consist of a 32-byte big endian R value, followed by a + * 32-byte big endian S value. If R or S fall outside of [0..order-1], the + * encoding is invalid. R and S with value 0 are allowed in the encoding. + * + * After the call, sig will always be initialized. If parsing failed or R or + * S are zero, the resulting sig value is guaranteed to fail validation for any + * message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input64 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse a DER ECDSA signature. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input: a pointer to the signature to be parsed + * inputlen: the length of the array pointed to be input + * + * This function will accept any valid DER encoded signature, even if the + * encoded numbers are out of range. + * + * After the call, sig will always be initialized. If parsing failed or the + * encoded numbers are out of range, signature validation with it is + * guaranteed to fail for every message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_der( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in DER format. + * + * Returns: 1 if enough space was available to serialize, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: output: a pointer to an array to store the DER serialization + * In/Out: outputlen: a pointer to a length integer. Initially, this integer + * should be set to the length of output. After the call + * it will be set to the length of the serialization (even + * if 0 was returned). + * In: sig: a pointer to an initialized signature object + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Serialize an ECDSA signature in compact (64 byte) format. + * + * Returns: 1 + * Args: ctx: a secp256k1 context object + * Out: output64: a pointer to a 64-byte array to store the compact serialization + * In: sig: a pointer to an initialized signature object + * + * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Verify an ECDSA signature. + * + * Returns: 1: correct signature + * 0: incorrect or unparseable signature + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig: the signature being verified. + * msghash32: the 32-byte message hash being verified. + * The verifier must make sure to apply a cryptographic + * hash function to the message by itself and not accept an + * msghash32 value directly. Otherwise, it would be easy to + * create a "valid" signature without knowledge of the + * secret key. See also + * https://bitcoin.stackexchange.com/a/81116/35586 for more + * background on this topic. + * pubkey: pointer to an initialized public key to verify with. + * + * To avoid accepting malleable signatures, only ECDSA signatures in lower-S + * form are accepted. + * + * If you need to accept ECDSA signatures from sources that do not obey this + * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to + * validation, but be aware that doing so results in malleable signatures. + * + * For details, see the comments for that function. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( + const secp256k1_context* ctx, + const secp256k1_ecdsa_signature *sig, + const unsigned char *msghash32, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify_with_handling_high_s( + const secp256k1_context* ctx, + const secp256k1_ecdsa_signature *sig, + const unsigned char *msghash32, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Convert a signature to a normalized lower-S form. + * + * Returns: 1 if sigin was not normalized, 0 if it already was. + * Args: ctx: a secp256k1 context object + * Out: sigout: a pointer to a signature to fill with the normalized form, + * or copy if the input was already normalized. (can be NULL if + * you're only interested in whether the input was already + * normalized). + * In: sigin: a pointer to a signature to check/normalize (can be identical to sigout) + * + * With ECDSA a third-party can forge a second distinct signature of the same + * message, given a single initial signature, but without knowing the key. This + * is done by negating the S value modulo the order of the curve, 'flipping' + * the sign of the random point R which is not included in the signature. + * + * Forgery of the same message isn't universally problematic, but in systems + * where message malleability or uniqueness of signatures is important this can + * cause issues. This forgery can be blocked by all verifiers forcing signers + * to use a normalized form. + * + * The lower-S form reduces the size of signatures slightly on average when + * variable length encodings (such as DER) are used and is cheap to verify, + * making it a good choice. Security of always using lower-S is assured because + * anyone can trivially modify a signature after the fact to enforce this + * property anyway. + * + * The lower S value is always between 0x1 and + * 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, + * inclusive. + * + * No other forms of ECDSA malleability are known and none seem likely, but + * there is no formal proof that ECDSA, even with this additional restriction, + * is free of other malleability. Commonly used serialization schemes will also + * accept various non-unique encodings, so care should be taken when this + * property is required for an application. + * + * The secp256k1_ecdsa_sign function will by default create signatures in the + * lower-S form, and secp256k1_ecdsa_verify will not accept others. In case + * signatures come from a system that cannot enforce this property, + * secp256k1_ecdsa_signature_normalize must be called before verification. + */ +SECP256K1_API int secp256k1_ecdsa_signature_normalize( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sigout, + const secp256k1_ecdsa_signature *sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); + +/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. + * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of + * extra entropy. + */ +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; + +/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; + +/** Create an ECDSA signature. + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the secret key was invalid. + * Args: ctx: pointer to a context object, initialized for signing. + * Out: sig: pointer to an array where the signature will be placed. + * In: msghash32: the 32-byte message hash being signed. + * seckey: pointer to a 32-byte secret key. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used. + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * secp256k1_nonce_function_default is used, then ndata must be a + * pointer to 32-bytes of additional data. + * + * The created signature is always in lower-S form. See + * secp256k1_ecdsa_signature_normalize for more details. + */ +SECP256K1_API int secp256k1_ecdsa_sign( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sig, + const unsigned char *msghash32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Verify an ECDSA secret key. + * + * A secret key is valid if it is not 0 and less than the secp256k1 curve order + * when interpreted as an integer (most significant byte first). The + * probability of choosing a 32-byte string uniformly at random which is an + * invalid secret key is negligible. + * + * Returns: 1: secret key is valid + * 0: secret key is invalid + * Args: ctx: pointer to a context object. + * In: seckey: pointer to a 32-byte secret key. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( + const secp256k1_context* ctx, + const unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Compute the public key for a secret key. + * + * Returns: 1: secret was valid, public key stores. + * 0: secret was invalid, try again. + * Args: ctx: pointer to a context object, initialized for signing. + * Out: pubkey: pointer to the created public key. + * In: seckey: pointer to a 32-byte secret key. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Negates a secret key in place. + * + * Returns: 0 if the given secret key is invalid according to + * secp256k1_ec_seckey_verify. 1 otherwise + * Args: ctx: pointer to a context object + * In/Out: seckey: pointer to the 32-byte secret key to be negated. If the + * secret key is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0 and + * seckey will be set to some unspecified value. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate( + const secp256k1_context* ctx, + unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate( + const secp256k1_context* ctx, + unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead"); + +/** Negates a public key in place. + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * In/Out: pubkey: pointer to the public key to be negated. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Tweak a secret key by adding tweak to it. + * + * Returns: 0 if the arguments are invalid or the resulting secret key would be + * invalid (only when the tweak is the negation of the secret key). 1 + * otherwise. + * Args: ctx: pointer to a context object. + * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is + * invalid according to secp256k1_ec_seckey_verify, this + * function returns 0. seckey will be set to some unspecified + * value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead"); + +/** Tweak a public key by adding tweak times the generator to it. + * + * Returns: 0 if the arguments are invalid or the resulting public key would be + * invalid (only when the tweak is the negation of the corresponding + * secret key). 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation. + * In/Out: pubkey: pointer to a public key object. pubkey will be set to an + * invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Tweak a secret key by multiplying it by a tweak. + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * Args: ctx: pointer to a context object. + * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is + * invalid according to secp256k1_ec_seckey_verify, this + * function returns 0. seckey will be set to some unspecified + * value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) + SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead"); + +/** Tweak a public key by multiplying it by a tweak value. + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation. + * In/Out: pubkey: pointer to a public key object. pubkey will be set to an + * invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to + * secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Updates the context randomization to protect against side-channel leakage. + * Returns: 1: randomization successfully updated or nothing to randomize + * 0: error + * Args: ctx: pointer to a context object. + * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) + * + * While secp256k1 code is written to be constant-time no matter what secret + * values are, it's possible that a future compiler may output code which isn't, + * and also that the CPU may not emit the same radio frequencies or draw the same + * amount power for all values. + * + * This function provides a seed which is combined into the blinding value: that + * blinding value is added before each multiplication (and removed afterwards) so + * that it does not affect function results, but shields against attacks which + * rely on any input-dependent behaviour. + * + * This function has currently an effect only on contexts initialized for signing + * because randomization is currently used only for signing. However, this is not + * guaranteed and may change in the future. It is safe to call this function on + * contexts not initialized for signing; then it will have no effect and return 1. + * + * You should call this after secp256k1_context_create or + * secp256k1_context_clone (and secp256k1_context_preallocated_create or + * secp256k1_context_clone, resp.), and you may call this repeatedly afterwards. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( + secp256k1_context* ctx, + const unsigned char *seed32 +) SECP256K1_ARG_NONNULL(1); + +/** Add a number of public keys together. + * + * Returns: 1: the sum of the public keys is valid. + * 0: the sum of the public keys is not valid. + * Args: ctx: pointer to a context object. + * Out: out: pointer to a public key object for placing the resulting public key. + * In: ins: pointer to array of pointers to public keys. + * n: the number of public keys to add together (must be at least 1). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( + const secp256k1_context* ctx, + secp256k1_pubkey *out, + const secp256k1_pubkey * const * ins, + size_t n +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Compute a tagged hash as defined in BIP-340. + * + * This is useful for creating a message hash and achieving domain separation + * through an application-specific tag. This function returns + * SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash + * implementations optimized for a specific tag can precompute the SHA256 state + * after hashing the tag hashes. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object + * Out: hash32: pointer to a 32-byte array to store the resulting hash + * In: tag: pointer to an array containing the tag + * taglen: length of the tag array + * msg: pointer to an array containing the message + * msglen: length of the message array + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256( + const secp256k1_context* ctx, + unsigned char *hash32, + const unsigned char *tag, + size_t taglen, + const unsigned char *msg, + size_t msglen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_ecdh.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_ecdh.h new file mode 100644 index 00000000..c8577984 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_ecdh.h @@ -0,0 +1,63 @@ +#ifndef SECP256K1_ECDH_H +#define SECP256K1_ECDH_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** A pointer to a function that hashes an EC point to obtain an ECDH secret + * + * Returns: 1 if the point was successfully hashed. + * 0 will cause secp256k1_ecdh to fail and return 0. + * Other return values are not allowed, and the behaviour of + * secp256k1_ecdh is undefined for other return values. + * Out: output: pointer to an array to be filled by the function + * In: x32: pointer to a 32-byte x coordinate + * y32: pointer to a 32-byte y coordinate + * data: arbitrary data pointer that is passed through + */ +typedef int (*secp256k1_ecdh_hash_function)( + unsigned char *output, + const unsigned char *x32, + const unsigned char *y32, + void *data +); + +/** An implementation of SHA256 hash function that applies to compressed public key. + * Populates the output parameter with 32 bytes. */ +SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256; + +/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256). + * Populates the output parameter with 32 bytes. */ +SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default; + +/** Compute an EC Diffie-Hellman secret in constant time + * + * Returns: 1: exponentiation was successful + * 0: scalar was invalid (zero or overflow) or hashfp returned 0 + * Args: ctx: pointer to a context object. + * Out: output: pointer to an array to be filled by hashfp. + * In: pubkey: a pointer to a secp256k1_pubkey containing an initialized public key. + * seckey: a 32-byte scalar with which to multiply the point. + * hashfp: pointer to a hash function. If NULL, + * secp256k1_ecdh_hash_function_sha256 is used + * (in which case, 32 bytes will be written to output). + * data: arbitrary data pointer that is passed through to hashfp + * (can be NULL for secp256k1_ecdh_hash_function_sha256). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( + const secp256k1_context* ctx, + unsigned char *output, + const secp256k1_pubkey *pubkey, + const unsigned char *seckey, + secp256k1_ecdh_hash_function hashfp, + void *data +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_ECDH_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_extrakeys.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_extrakeys.h new file mode 100644 index 00000000..09cbeaaa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_extrakeys.h @@ -0,0 +1,249 @@ +#ifndef SECP256K1_EXTRAKEYS_H +#define SECP256K1_EXTRAKEYS_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Opaque data structure that holds a parsed and valid "x-only" public key. + * An x-only pubkey encodes a point whose Y coordinate is even. It is + * serialized using only its X coordinate (32 bytes). See BIP-340 for more + * information about x-only pubkeys. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, use + * use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To + * compare keys, use secp256k1_xonly_pubkey_cmp. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_xonly_pubkey; + +/** Opaque data structure that holds a keypair consisting of a secret and a + * public key. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 96 bytes in size, and can be safely copied/moved. + */ +typedef struct { + unsigned char data[96]; +} secp256k1_keypair; + +/** Parse a 32-byte sequence into a xonly_pubkey object. + * + * Returns: 1 if the public key was fully valid. + * 0 if the public key could not be parsed or is invalid. + * + * Args: ctx: a secp256k1 context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a + * parsed version of input. If not, it's set to an invalid value. + * In: input32: pointer to a serialized xonly_pubkey. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse( + const secp256k1_context* ctx, + secp256k1_xonly_pubkey* pubkey, + const unsigned char *input32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an xonly_pubkey object into a 32-byte sequence. + * + * Returns: 1 always. + * + * Args: ctx: a secp256k1 context object. + * Out: output32: a pointer to a 32-byte array to place the serialized key in. + * In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key. + */ +SECP256K1_API int secp256k1_xonly_pubkey_serialize( + const secp256k1_context* ctx, + unsigned char *output32, + const secp256k1_xonly_pubkey* pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Compare two x-only public keys using lexicographic order + * + * Returns: <0 if the first public key is less than the second + * >0 if the first public key is greater than the second + * 0 if the two public keys are equal + * Args: ctx: a secp256k1 context object. + * In: pubkey1: first public key to compare + * pubkey2: second public key to compare + */ +SECP256K1_API int secp256k1_xonly_pubkey_cmp( + const secp256k1_context* ctx, + const secp256k1_xonly_pubkey* pk1, + const secp256k1_xonly_pubkey* pk2 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey. + * + * Returns: 1 always. + * + * Args: ctx: pointer to a context object. + * Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key. + * pk_parity: Ignored if NULL. Otherwise, pointer to an integer that + * will be set to 1 if the point encoded by xonly_pubkey is + * the negation of the pubkey and set to 0 otherwise. + * In: pubkey: pointer to a public key that is converted. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey( + const secp256k1_context* ctx, + secp256k1_xonly_pubkey *xonly_pubkey, + int *pk_parity, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Tweak an x-only public key by adding the generator multiplied with tweak32 + * to it. + * + * Note that the resulting point can not in general be represented by an x-only + * pubkey because it may have an odd Y coordinate. Instead, the output_pubkey + * is a normal secp256k1_pubkey. + * + * Returns: 0 if the arguments are invalid or the resulting public key would be + * invalid (only when the tweak is the negation of the corresponding + * secret key). 1 otherwise. + * + * Args: ctx: pointer to a context object initialized for verification. + * Out: output_pubkey: pointer to a public key to store the result. Will be set + * to an invalid value if this function returns 0. + * In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to. + * tweak32: pointer to a 32-byte tweak. If the tweak is invalid + * according to secp256k1_ec_seckey_verify, this function + * returns 0. For uniformly random 32-byte arrays the + * chance of being invalid is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add( + const secp256k1_context* ctx, + secp256k1_pubkey *output_pubkey, + const secp256k1_xonly_pubkey *internal_pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Checks that a tweaked pubkey is the result of calling + * secp256k1_xonly_pubkey_tweak_add with internal_pubkey and tweak32. + * + * The tweaked pubkey is represented by its 32-byte x-only serialization and + * its pk_parity, which can both be obtained by converting the result of + * tweak_add to a secp256k1_xonly_pubkey. + * + * Note that this alone does _not_ verify that the tweaked pubkey is a + * commitment. If the tweak is not chosen in a specific way, the tweaked pubkey + * can easily be the result of a different internal_pubkey and tweak. + * + * Returns: 0 if the arguments are invalid or the tweaked pubkey is not the + * result of tweaking the internal_pubkey with tweak32. 1 otherwise. + * Args: ctx: pointer to a context object initialized for verification. + * In: tweaked_pubkey32: pointer to a serialized xonly_pubkey. + * tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization + * is passed in as tweaked_pubkey32). This must match the + * pk_parity value that is returned when calling + * secp256k1_xonly_pubkey with the tweaked pubkey, or + * this function will fail. + * internal_pubkey: pointer to an x-only public key object to apply the tweak to. + * tweak32: pointer to a 32-byte tweak. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check( + const secp256k1_context* ctx, + const unsigned char *tweaked_pubkey32, + int tweaked_pk_parity, + const secp256k1_xonly_pubkey *internal_pubkey, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Compute the keypair for a secret key. + * + * Returns: 1: secret was valid, keypair is ready to use + * 0: secret was invalid, try again with a different secret + * Args: ctx: pointer to a context object, initialized for signing. + * Out: keypair: pointer to the created keypair. + * In: seckey: pointer to a 32-byte secret key. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create( + const secp256k1_context* ctx, + secp256k1_keypair *keypair, + const unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the secret key from a keypair. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: seckey: pointer to a 32-byte buffer for the secret key. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec( + const secp256k1_context* ctx, + unsigned char *seckey, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the public key from a keypair. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to + * the keypair public key. If not, it's set to an invalid value. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the x-only public key from a keypair. + * + * This is the same as calling secp256k1_keypair_pub and then + * secp256k1_xonly_pubkey_from_pubkey. + * + * Returns: 1 always. + * Args: ctx: pointer to a context object. + * Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set + * to the keypair public key after converting it to an + * xonly_pubkey. If not, it's set to an invalid value. + * pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the + * pk_parity argument of secp256k1_xonly_pubkey_from_pubkey. + * In: keypair: pointer to a keypair. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub( + const secp256k1_context* ctx, + secp256k1_xonly_pubkey *pubkey, + int *pk_parity, + const secp256k1_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Tweak a keypair by adding tweak32 to the secret key and updating the public + * key accordingly. + * + * Calling this function and then secp256k1_keypair_pub results in the same + * public key as calling secp256k1_keypair_xonly_pub and then + * secp256k1_xonly_pubkey_tweak_add. + * + * Returns: 0 if the arguments are invalid or the resulting keypair would be + * invalid (only when the tweak is the negation of the keypair's + * secret key). 1 otherwise. + * + * Args: ctx: pointer to a context object initialized for verification. + * In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to + * an invalid value if this function returns 0. + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according + * to secp256k1_ec_seckey_verify, this function returns 0. For + * uniformly random 32-byte arrays the chance of being invalid + * is negligible (around 1 in 2^128). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add( + const secp256k1_context* ctx, + secp256k1_keypair *keypair, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_EXTRAKEYS_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_preallocated.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_preallocated.h new file mode 100644 index 00000000..d2d9014f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_preallocated.h @@ -0,0 +1,128 @@ +#ifndef SECP256K1_PREALLOCATED_H +#define SECP256K1_PREALLOCATED_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The module provided by this header file is intended for settings in which it + * is not possible or desirable to rely on dynamic memory allocation. It provides + * functions for creating, cloning, and destroying secp256k1 context objects in a + * contiguous fixed-size block of memory provided by the caller. + * + * Context objects created by functions in this module can be used like contexts + * objects created by functions in secp256k1.h, i.e., they can be passed to any + * API function that expects a context object (see secp256k1.h for details). The + * only exception is that context objects created by functions in this module + * must be destroyed using secp256k1_context_preallocated_destroy (in this + * module) instead of secp256k1_context_destroy (in secp256k1.h). + * + * It is guaranteed that functions in this module will not call malloc or its + * friends realloc, calloc, and free. + */ + +/** Determine the memory size of a secp256k1 context object to be created in + * caller-provided memory. + * + * The purpose of this function is to determine how much memory must be provided + * to secp256k1_context_preallocated_create. + * + * Returns: the required size of the caller-provided memory block + * In: flags: which parts of the context to initialize. + */ +SECP256K1_API size_t secp256k1_context_preallocated_size( + unsigned int flags +) SECP256K1_WARN_UNUSED_RESULT; + +/** Create a secp256k1 context object in caller-provided memory. + * + * The caller must provide a pointer to a rewritable contiguous block of memory + * of size at least secp256k1_context_preallocated_size(flags) bytes, suitably + * aligned to hold an object of any type. + * + * The block of memory is exclusively owned by the created context object during + * the lifetime of this context object, which begins with the call to this + * function and ends when a call to secp256k1_context_preallocated_destroy + * (which destroys the context object again) returns. During the lifetime of the + * context object, the caller is obligated not to access this block of memory, + * i.e., the caller may not read or write the memory, e.g., by copying the memory + * contents to a different location or trying to create a second context object + * in the memory. In simpler words, the prealloc pointer (or any pointer derived + * from it) should not be used during the lifetime of the context object. + * + * Returns: a newly created context object. + * In: prealloc: a pointer to a rewritable contiguous block of memory of + * size at least secp256k1_context_preallocated_size(flags) + * bytes, as detailed above. + * flags: which parts of the context to initialize. + * + * See also secp256k1_context_randomize (in secp256k1.h) + * and secp256k1_context_preallocated_destroy. + */ +SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create( + void* prealloc, + unsigned int flags +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + +/** Determine the memory size of a secp256k1 context object to be copied into + * caller-provided memory. + * + * Returns: the required size of the caller-provided memory block. + * In: ctx: an existing context to copy. + */ +SECP256K1_API size_t secp256k1_context_preallocated_clone_size( + const secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + +/** Copy a secp256k1 context object into caller-provided memory. + * + * The caller must provide a pointer to a rewritable contiguous block of memory + * of size at least secp256k1_context_preallocated_size(flags) bytes, suitably + * aligned to hold an object of any type. + * + * The block of memory is exclusively owned by the created context object during + * the lifetime of this context object, see the description of + * secp256k1_context_preallocated_create for details. + * + * Returns: a newly created context object. + * Args: ctx: an existing context to copy. + * In: prealloc: a pointer to a rewritable contiguous block of memory of + * size at least secp256k1_context_preallocated_size(flags) + * bytes, as detailed above. + */ +SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone( + const secp256k1_context* ctx, + void* prealloc +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT; + +/** Destroy a secp256k1 context object that has been created in + * caller-provided memory. + * + * The context pointer may not be used afterwards. + * + * The context to destroy must have been created using + * secp256k1_context_preallocated_create or secp256k1_context_preallocated_clone. + * If the context has instead been created using secp256k1_context_create or + * secp256k1_context_clone, the behaviour is undefined. In that case, + * secp256k1_context_destroy must be used instead. + * + * If required, it is the responsibility of the caller to deallocate the block + * of memory properly after this function returns, e.g., by calling free on the + * preallocated pointer given to secp256k1_context_preallocated_create or + * secp256k1_context_preallocated_clone. + * + * Args: ctx: an existing context to destroy, constructed using + * secp256k1_context_preallocated_create or + * secp256k1_context_preallocated_clone. + */ +SECP256K1_API void secp256k1_context_preallocated_destroy( + secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PREALLOCATED_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_recovery.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_recovery.h new file mode 100644 index 00000000..0e2847db --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_recovery.h @@ -0,0 +1,113 @@ +#ifndef SECP256K1_RECOVERY_H +#define SECP256K1_RECOVERY_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Opaque data structured that holds a parsed ECDSA signature, + * supporting pubkey recovery. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 65 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_parse_* functions. + * + * Furthermore, it is guaranteed that identical signatures (including their + * recoverability) will have identical representation, so they can be + * memcmp'ed. + */ +typedef struct { + unsigned char data[65]; +} secp256k1_ecdsa_recoverable_signature; + +/** Parse a compact ECDSA signature (64 bytes + recovery id). + * + * Returns: 1 when the signature could be parsed, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to a 64-byte compact signature + * recid: the recovery id (0, 1, 2 or 3) + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature* sig, + const unsigned char *input64, + int recid +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Convert a recoverable signature into a normal signature. + * + * Returns: 1 + * Args: ctx: a secp256k1 context object. + * Out: sig: a pointer to a normal signature. + * In: sigin: a pointer to a recoverable signature. + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const secp256k1_ecdsa_recoverable_signature* sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in compact format (64 bytes + recovery id). + * + * Returns: 1 + * Args: ctx: a secp256k1 context object. + * Out: output64: a pointer to a 64-byte array of the compact signature. + * recid: a pointer to an integer to hold the recovery id. + * In: sig: a pointer to an initialized signature object. + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + int *recid, + const secp256k1_ecdsa_recoverable_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Create a recoverable ECDSA signature. + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the secret key was invalid. + * Args: ctx: pointer to a context object, initialized for signing. + * Out: sig: pointer to an array where the signature will be placed. + * In: msghash32: the 32-byte message hash being signed. + * seckey: pointer to a 32-byte secret key. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used. + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL for secp256k1_nonce_function_default). + */ +SECP256K1_API int secp256k1_ecdsa_sign_recoverable( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msghash32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Recover an ECDSA public key from a signature. + * + * Returns: 1: public key successfully recovered (which guarantees a correct signature). + * 0: otherwise. + * Args: ctx: pointer to a context object, initialized for verification. + * Out: pubkey: pointer to the recovered public key. + * In: sig: pointer to initialized signature that supports pubkey recovery. + * msghash32: the 32-byte message hash assumed to be signed. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msghash32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_RECOVERY_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_schnorrsig.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_schnorrsig.h new file mode 100644 index 00000000..5fedcb07 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/secp256k1_schnorrsig.h @@ -0,0 +1,182 @@ +#ifndef SECP256K1_SCHNORRSIG_H +#define SECP256K1_SCHNORRSIG_H + +#include "secp256k1.h" +#include "secp256k1_extrakeys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This module implements a variant of Schnorr signatures compliant with + * Bitcoin Improvement Proposal 340 "Schnorr Signatures for secp256k1" + * (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + */ + +/** A pointer to a function to deterministically generate a nonce. + * + * Same as secp256k1_nonce function with the exception of accepting an + * additional pubkey argument and not requiring an attempt argument. The pubkey + * argument can protect signature schemes with key-prefixed challenge hash + * inputs against reusing the nonce when signing with the wrong precomputed + * pubkey. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to + * return an error. + * Out: nonce32: pointer to a 32-byte array to be filled by the function + * In: msg: the message being verified. Is NULL if and only if msglen + * is 0. + * msglen: the length of the message + * key32: pointer to a 32-byte secret key (will not be NULL) + * xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32 + * (will not be NULL) + * algo: pointer to an array describing the signature + * algorithm (will not be NULL) + * algolen: the length of the algo array + * data: arbitrary data pointer that is passed through + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the key, the pubkey, the algorithm description, and data. + */ +typedef int (*secp256k1_nonce_function_hardened)( + unsigned char *nonce32, + const unsigned char *msg, + size_t msglen, + const unsigned char *key32, + const unsigned char *xonly_pk32, + const unsigned char *algo, + size_t algolen, + void *data +); + +/** An implementation of the nonce generation function as defined in Bitcoin + * Improvement Proposal 340 "Schnorr Signatures for secp256k1" + * (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + * + * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of + * auxiliary random data as defined in BIP-340. If the data pointer is NULL, + * the nonce derivation procedure follows BIP-340 by setting the auxiliary + * random data to zero. The algo argument must be non-NULL, otherwise the + * function will fail and return 0. The hash will be tagged with algo. + * Therefore, to create BIP-340 compliant signatures, algo must be set to + * "BIP0340/nonce" and algolen to 13. + */ +SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; + +/** Data structure that contains additional arguments for schnorrsig_sign_custom. + * + * A schnorrsig_extraparams structure object can be initialized correctly by + * setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT. + * + * Members: + * magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization + * and has no other function than making sure the object is + * initialized. + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_bip340 is used + * ndata: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * secp256k1_nonce_function_bip340 is used, then ndata must be a + * pointer to 32-byte auxiliary randomness as per BIP-340. + */ +typedef struct { + unsigned char magic[4]; + secp256k1_nonce_function_hardened noncefp; + void* ndata; +} secp256k1_schnorrsig_extraparams; + +#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c } +#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\ + SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\ + NULL,\ + NULL\ +} + +/** Create a Schnorr signature. + * + * Does _not_ strictly follow BIP-340 because it does not verify the resulting + * signature. Instead, you can manually use secp256k1_schnorrsig_verify and + * abort if it fails. + * + * This function only signs 32-byte messages. If you have messages of a + * different size (or the same size but without a context-specific tag + * prefix), it is recommended to create a 32-byte message hash with + * secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows + * providing an context-specific tag for domain separation. This prevents + * signatures from being valid in multiple contexts by accident. + * + * Returns 1 on success, 0 on failure. + * Args: ctx: pointer to a context object, initialized for signing. + * Out: sig64: pointer to a 64-byte array to store the serialized signature. + * In: msg32: the 32-byte message being signed. + * keypair: pointer to an initialized keypair. + * aux_rand32: 32 bytes of fresh randomness. While recommended to provide + * this, it is only supplemental to security and can be NULL. A + * NULL argument is treated the same as an all-zero one. See + * BIP-340 "Default Signing" for a full explanation of this + * argument and for guidance if randomness is expensive. + */ +SECP256K1_API int secp256k1_schnorrsig_sign32( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char *msg32, + const secp256k1_keypair *keypair, + const unsigned char *aux_rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in + * future versions. */ +SECP256K1_API int secp256k1_schnorrsig_sign( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char *msg32, + const secp256k1_keypair *keypair, + const unsigned char *aux_rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) + SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead"); + +/** Create a Schnorr signature with a more flexible API. + * + * Same arguments as secp256k1_schnorrsig_sign except that it allows signing + * variable length messages and accepts a pointer to an extraparams object that + * allows customizing signing by passing additional arguments. + * + * Creates the same signatures as schnorrsig_sign if msglen is 32 and the + * extraparams.ndata is the same as aux_rand32. + * + * In: msg: the message being signed. Can only be NULL if msglen is 0. + * msglen: length of the message + * extraparams: pointer to a extraparams object (can be NULL) + */ +SECP256K1_API int secp256k1_schnorrsig_sign_custom( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char *msg, + size_t msglen, + const secp256k1_keypair *keypair, + secp256k1_schnorrsig_extraparams *extraparams +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); + +/** Verify a Schnorr signature. + * + * Returns: 1: correct signature + * 0: incorrect signature + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig64: pointer to the 64-byte signature to verify. + * msg: the message being verified. Can only be NULL if msglen is 0. + * msglen: length of the message + * pubkey: pointer to an x-only public key to verify with (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify( + const secp256k1_context* ctx, + const unsigned char *sig64, + const unsigned char *msg, + size_t msglen, + const secp256k1_xonly_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_SCHNORRSIG_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/utility.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/utility.h new file mode 100644 index 00000000..cac6ff35 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/include/utility.h @@ -0,0 +1,13 @@ +#include "./secp256k1.h" + +/// Exposes secp256k1 memczero implementation to the bindings target +/// @param s pointer to an array to be zero'd by the function +/// @param len the length of the data to be zero'd +/// @param flag zero memory if flag == 1. Flag must be 0 or 1. Constant time. +void secp256k1_swift_memczero(void *s, size_t len, int flag); + +/// Exposes secp256k1 SHA256 implementation to the bindings target +/// @param output pointer to an array to be filled by the function +/// @param input a pointer to the data to be hashed +/// @param len the length of the data to be hashed +void secp256k1_swift_sha256(unsigned char *output, const unsigned char *input, size_t len); diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/assumptions.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/assumptions.h new file mode 100644 index 00000000..6dc527b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/assumptions.h @@ -0,0 +1,80 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ASSUMPTIONS_H +#define SECP256K1_ASSUMPTIONS_H + +#include + +#include "util.h" + +/* This library, like most software, relies on a number of compiler implementation defined (but not undefined) + behaviours. Although the behaviours we require are essentially universal we test them specifically here to + reduce the odds of experiencing an unwelcome surprise. +*/ + +struct secp256k1_assumption_checker { + /* This uses a trick to implement a static assertion in C89: a type with an array of negative size is not + allowed. */ + int dummy_array[( + /* Bytes are 8 bits. */ + (CHAR_BIT == 8) && + + /* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32 + without signed overflow, which would be undefined behaviour. */ + (UINT_MAX <= UINT32_MAX) && + + /* Conversions from unsigned to signed outside of the bounds of the signed type are + implementation-defined. Verify that they function as reinterpreting the lower + bits of the input in two's complement notation. Do this for conversions: + - from uint(N)_t to int(N)_t with negative result + - from uint(2N)_t to int(N)_t with negative result + - from int(2N)_t to int(N)_t with negative result + - from int(2N)_t to int(N)_t with positive result */ + + /* To int8_t. */ + ((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55) && + ((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33) && + ((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF) && + ((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34) && + + /* To int16_t. */ + ((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322) && + ((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C) && + ((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4) && + ((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678) && + + /* To int32_t. */ + ((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B) && + ((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE) && + ((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8) && + ((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789) && + + /* To int64_t. */ + ((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL) && +#if defined(SECP256K1_WIDEMUL_INT128) + ((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL) && + (((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL) && + (((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL) && + + /* To int128_t. */ + ((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL)) && +#endif + + /* Right shift on negative signed values is implementation defined. Verify that it + acts as a right shift in two's complement with sign extension (i.e duplicating + the top bit into newly added bits). */ + ((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA) && + ((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A) && + ((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48) && + ((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL) && +#if defined(SECP256K1_WIDEMUL_INT128) + ((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL)) && +#endif + 1) * 2 - 1]; +}; + +#endif /* SECP256K1_ASSUMPTIONS_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/basic-config.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/basic-config.h new file mode 100644 index 00000000..6f7693cb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/basic-config.h @@ -0,0 +1,17 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_BASIC_CONFIG_H +#define SECP256K1_BASIC_CONFIG_H + +#ifdef USE_BASIC_CONFIG + +#define ECMULT_WINDOW_SIZE 15 +#define ECMULT_GEN_PREC_BITS 4 + +#endif /* USE_BASIC_CONFIG */ + +#endif /* SECP256K1_BASIC_CONFIG_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/bench.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/bench.h new file mode 100644 index 00000000..aa275fe9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/bench.h @@ -0,0 +1,172 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_BENCH_H +#define SECP256K1_BENCH_H + +#include +#include +#include +#include "sys/time.h" + +static int64_t gettime_i64(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL; +} + +#define FP_EXP (6) +#define FP_MULT (1000000LL) + +/* Format fixed point number. */ +void print_number(const int64_t x) { + int64_t x_abs, y; + int c, i, rounding, g; /* g = integer part size, c = fractional part size */ + size_t ptr; + char buffer[30]; + + if (x == INT64_MIN) { + /* Prevent UB. */ + printf("ERR"); + return; + } + x_abs = x < 0 ? -x : x; + + /* Determine how many decimals we want to show (more than FP_EXP makes no + * sense). */ + y = x_abs; + c = 0; + while (y > 0LL && y < 100LL * FP_MULT && c < FP_EXP) { + y *= 10LL; + c++; + } + + /* Round to 'c' decimals. */ + y = x_abs; + rounding = 0; + for (i = c; i < FP_EXP; ++i) { + rounding = (y % 10) >= 5; + y /= 10; + } + y += rounding; + + /* Format and print the number. */ + ptr = sizeof(buffer) - 1; + buffer[ptr] = 0; + g = 0; + if (c != 0) { /* non zero fractional part */ + for (i = 0; i < c; ++i) { + buffer[--ptr] = '0' + (y % 10); + y /= 10; + } + } else if (c == 0) { /* fractional part is 0 */ + buffer[--ptr] = '0'; + } + buffer[--ptr] = '.'; + do { + buffer[--ptr] = '0' + (y % 10); + y /= 10; + g++; + } while (y != 0); + if (x < 0) { + buffer[--ptr] = '-'; + g++; + } + printf("%5.*s", g, &buffer[ptr]); /* Prints integer part */ + printf("%-*s", FP_EXP, &buffer[ptr + g]); /* Prints fractional part */ +} + +void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) { + int i; + int64_t min = INT64_MAX; + int64_t sum = 0; + int64_t max = 0; + for (i = 0; i < count; i++) { + int64_t begin, total; + if (setup != NULL) { + setup(data); + } + begin = gettime_i64(); + benchmark(data, iter); + total = gettime_i64() - begin; + if (teardown != NULL) { + teardown(data, iter); + } + if (total < min) { + min = total; + } + if (total > max) { + max = total; + } + sum += total; + } + /* ',' is used as a column delimiter */ + printf("%-30s, ", name); + print_number(min * FP_MULT / iter); + printf(" , "); + print_number(((sum * FP_MULT) / count) / iter); + printf(" , "); + print_number(max * FP_MULT / iter); + printf("\n"); +} + +int have_flag(int argc, char** argv, char *flag) { + char** argm = argv + argc; + argv++; + while (argv != argm) { + if (strcmp(*argv, flag) == 0) { + return 1; + } + argv++; + } + return 0; +} + +/* takes an array containing the arguments that the user is allowed to enter on the command-line + returns: + - 1 if the user entered an invalid argument + - 0 if all the user entered arguments are valid */ +int have_invalid_args(int argc, char** argv, char** valid_args, size_t n) { + size_t i; + int found_valid; + char** argm = argv + argc; + argv++; + + while (argv != argm) { + found_valid = 0; + for (i = 0; i < n; i++) { + if (strcmp(*argv, valid_args[i]) == 0) { + found_valid = 1; /* user entered a valid arg from the list */ + break; + } + } + if (found_valid == 0) { + return 1; /* invalid arg found */ + } + argv++; + } + return 0; +} + +int get_iters(int default_iters) { + char* env = getenv("SECP256K1_BENCH_ITERS"); + if (env) { + return strtol(env, NULL, 0); + } else { + return default_iters; + } +} + +void print_output_table_header_row(void) { + char* bench_str = "Benchmark"; /* left justified */ + char* min_str = " Min(us) "; /* center alignment */ + char* avg_str = " Avg(us) "; + char* max_str = " Max(us) "; + printf("%-30s,%-15s,%-15s,%-15s\n", bench_str, min_str, avg_str, max_str); + printf("\n"); +} + +#endif /* SECP256K1_BENCH_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa.h new file mode 100644 index 00000000..4441b083 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa.h @@ -0,0 +1,21 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECDSA_H +#define SECP256K1_ECDSA_H + +#include + +#include "scalar.h" +#include "group.h" +#include "ecmult.h" + +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); +static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); + +#endif /* SECP256K1_ECDSA_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa_impl.h new file mode 100644 index 00000000..90b4b22b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecdsa_impl.h @@ -0,0 +1,315 @@ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + + +#ifndef SECP256K1_ECDSA_IMPL_H +#define SECP256K1_ECDSA_IMPL_H + +#include "scalar.h" +#include "field.h" +#include "group.h" +#include "ecmult.h" +#include "ecmult_gen.h" +#include "ecdsa.h" + +/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 + * sage: for t in xrange(1023, -1, -1): + * .. p = 2**256 - 2**32 - t + * .. if p.is_prime(): + * .. print '%x'%p + * .. break + * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' + * sage: a = 0 + * sage: b = 7 + * sage: F = FiniteField (p) + * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) + * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' + */ +static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, + 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL +); + +/** Difference between field and order, values 'p' and 'n' values defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F + * sage: a = 0 + * sage: b = 7 + * sage: F = FiniteField (p) + * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) + * '14551231950b75fc4402da1722fc9baee' + */ +static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( + 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL +); + +static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const unsigned char *sigend) { + size_t lenleft; + unsigned char b1; + VERIFY_CHECK(len != NULL); + *len = 0; + if (*sigp >= sigend) { + return 0; + } + b1 = *((*sigp)++); + if (b1 == 0xFF) { + /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ + return 0; + } + if ((b1 & 0x80) == 0) { + /* X.690-0207 8.1.3.4 short form length octets */ + *len = b1; + return 1; + } + if (b1 == 0x80) { + /* Indefinite length is not allowed in DER. */ + return 0; + } + /* X.690-207 8.1.3.5 long form length octets */ + lenleft = b1 & 0x7F; /* lenleft is at least 1 */ + if (lenleft > (size_t)(sigend - *sigp)) { + return 0; + } + if (**sigp == 0) { + /* Not the shortest possible length encoding. */ + return 0; + } + if (lenleft > sizeof(size_t)) { + /* The resulting length would exceed the range of a size_t, so + * certainly longer than the passed array size. + */ + return 0; + } + while (lenleft > 0) { + *len = (*len << 8) | **sigp; + (*sigp)++; + lenleft--; + } + if (*len > (size_t)(sigend - *sigp)) { + /* Result exceeds the length of the passed array. */ + return 0; + } + if (*len < 128) { + /* Not the shortest possible length encoding. */ + return 0; + } + return 1; +} + +static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { + int overflow = 0; + unsigned char ra[32] = {0}; + size_t rlen; + + if (*sig == sigend || **sig != 0x02) { + /* Not a primitive integer (X.690-0207 8.3.1). */ + return 0; + } + (*sig)++; + if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) { + return 0; + } + if (rlen == 0 || rlen > (size_t)(sigend - *sig)) { + /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ + return 0; + } + if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { + /* Excessive 0x00 padding. */ + return 0; + } + if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { + /* Excessive 0xFF padding. */ + return 0; + } + if ((**sig & 0x80) == 0x80) { + /* Negative. */ + overflow = 1; + } + /* There is at most one leading zero byte: + * if there were two leading zero bytes, we would have failed and returned 0 + * because of excessive 0x00 padding already. */ + if (rlen > 0 && **sig == 0) { + /* Skip leading zero byte */ + rlen--; + (*sig)++; + } + if (rlen > 32) { + overflow = 1; + } + if (!overflow) { + if (rlen) memcpy(ra + 32 - rlen, *sig, rlen); + secp256k1_scalar_set_b32(r, ra, &overflow); + } + if (overflow) { + secp256k1_scalar_set_int(r, 0); + } + (*sig) += rlen; + return 1; +} + +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { + const unsigned char *sigend = sig + size; + size_t rlen; + if (sig == sigend || *(sig++) != 0x30) { + /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ + return 0; + } + if (secp256k1_der_read_len(&rlen, &sig, sigend) == 0) { + return 0; + } + if (rlen != (size_t)(sigend - sig)) { + /* Tuple exceeds bounds or garage after tuple. */ + return 0; + } + + if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { + return 0; + } + if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { + return 0; + } + + if (sig != sigend) { + /* Trailing garbage inside tuple. */ + return 0; + } + + return 1; +} + +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { + unsigned char r[33] = {0}, s[33] = {0}; + unsigned char *rp = r, *sp = s; + size_t lenR = 33, lenS = 33; + secp256k1_scalar_get_b32(&r[1], ar); + secp256k1_scalar_get_b32(&s[1], as); + while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } + while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } + if (*size < 6+lenS+lenR) { + *size = 6 + lenS + lenR; + return 0; + } + *size = 6 + lenS + lenR; + sig[0] = 0x30; + sig[1] = 4 + lenS + lenR; + sig[2] = 0x02; + sig[3] = lenR; + memcpy(sig+4, rp, lenR); + sig[4+lenR] = 0x02; + sig[5+lenR] = lenS; + memcpy(sig+lenR+6, sp, lenS); + return 1; +} + +static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { + unsigned char c[32]; + secp256k1_scalar sn, u1, u2; +#if !defined(EXHAUSTIVE_TEST_ORDER) + secp256k1_fe xr; +#endif + secp256k1_gej pubkeyj; + secp256k1_gej pr; + + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { + return 0; + } + + secp256k1_scalar_inverse_var(&sn, sigs); + secp256k1_scalar_mul(&u1, &sn, message); + secp256k1_scalar_mul(&u2, &sn, sigr); + secp256k1_gej_set_ge(&pubkeyj, pubkey); + secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); + if (secp256k1_gej_is_infinity(&pr)) { + return 0; + } + +#if defined(EXHAUSTIVE_TEST_ORDER) +{ + secp256k1_scalar computed_r; + secp256k1_ge pr_ge; + secp256k1_ge_set_gej(&pr_ge, &pr); + secp256k1_fe_normalize(&pr_ge.x); + + secp256k1_fe_get_b32(c, &pr_ge.x); + secp256k1_scalar_set_b32(&computed_r, c, NULL); + return secp256k1_scalar_eq(sigr, &computed_r); +} +#else + secp256k1_scalar_get_b32(c, sigr); + secp256k1_fe_set_b32(&xr, c); + + /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) + * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), + * compute the remainder modulo n, and compare it to xr. However: + * + * xr == X(pr) mod n + * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) + * [Since 2 * n > p, h can only be 0 or 1] + * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) + * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] + * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) + * [Multiplying both sides of the equations by pr.z^2 mod p] + * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) + * + * Thus, we can avoid the inversion, but we have to check both cases separately. + * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. + */ + if (secp256k1_gej_eq_x_var(&xr, &pr)) { + /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ + return 1; + } + if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { + /* xr + n >= p, so we can skip testing the second case. */ + return 0; + } + secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); + if (secp256k1_gej_eq_x_var(&xr, &pr)) { + /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ + return 1; + } + return 0; +#endif +} + +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { + unsigned char b[32]; + secp256k1_gej rp; + secp256k1_ge r; + secp256k1_scalar n; + int overflow = 0; + int high; + + secp256k1_ecmult_gen(ctx, &rp, nonce); + secp256k1_ge_set_gej(&r, &rp); + secp256k1_fe_normalize(&r.x); + secp256k1_fe_normalize(&r.y); + secp256k1_fe_get_b32(b, &r.x); + secp256k1_scalar_set_b32(sigr, b, &overflow); + if (recid) { + /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log + * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. + */ + *recid = (overflow << 1) | secp256k1_fe_is_odd(&r.y); + } + secp256k1_scalar_mul(&n, sigr, seckey); + secp256k1_scalar_add(&n, &n, message); + secp256k1_scalar_inverse(sigs, nonce); + secp256k1_scalar_mul(sigs, sigs, &n); + secp256k1_scalar_clear(&n); + secp256k1_gej_clear(&rp); + secp256k1_ge_clear(&r); + high = secp256k1_scalar_is_high(sigs); + secp256k1_scalar_cond_negate(sigs, high); + if (recid) { + *recid ^= high; + } + /* P.x = order is on the curve, so technically sig->r could end up being zero, which would be an invalid signature. + * This is cryptographically unreachable as hitting it requires finding the discrete log of P.x = N. + */ + return (int)(!secp256k1_scalar_is_zero(sigr)) & (int)(!secp256k1_scalar_is_zero(sigs)); +} + +#endif /* SECP256K1_ECDSA_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey.h new file mode 100644 index 00000000..d54d44c9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey.h @@ -0,0 +1,25 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECKEY_H +#define SECP256K1_ECKEY_H + +#include + +#include "group.h" +#include "scalar.h" +#include "ecmult.h" +#include "ecmult_gen.h" + +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); + +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak); + +#endif /* SECP256K1_ECKEY_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey_impl.h new file mode 100644 index 00000000..e0506d3e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/eckey_impl.h @@ -0,0 +1,96 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECKEY_IMPL_H +#define SECP256K1_ECKEY_IMPL_H + +#include "eckey.h" + +#include "scalar.h" +#include "field.h" +#include "group.h" +#include "ecmult_gen.h" + +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { + if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { + secp256k1_fe x; + return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); + } else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { + secp256k1_fe x, y; + if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { + return 0; + } + secp256k1_ge_set_xy(elem, &x, &y); + if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && + secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { + return 0; + } + return secp256k1_ge_is_valid_var(elem); + } else { + return 0; + } +} + +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { + if (secp256k1_ge_is_infinity(elem)) { + return 0; + } + secp256k1_fe_normalize_var(&elem->x); + secp256k1_fe_normalize_var(&elem->y); + secp256k1_fe_get_b32(&pub[1], &elem->x); + if (compressed) { + *size = 33; + pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; + } else { + *size = 65; + pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; + secp256k1_fe_get_b32(&pub[33], &elem->y); + } + return 1; +} + +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { + secp256k1_scalar_add(key, key, tweak); + return !secp256k1_scalar_is_zero(key); +} + +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_gej pt; + secp256k1_scalar one; + secp256k1_gej_set_ge(&pt, key); + secp256k1_scalar_set_int(&one, 1); + secp256k1_ecmult(&pt, &pt, &one, tweak); + + if (secp256k1_gej_is_infinity(&pt)) { + return 0; + } + secp256k1_ge_set_gej(key, &pt); + return 1; +} + +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { + int ret; + ret = !secp256k1_scalar_is_zero(tweak); + + secp256k1_scalar_mul(key, key, tweak); + return ret; +} + +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_scalar zero; + secp256k1_gej pt; + if (secp256k1_scalar_is_zero(tweak)) { + return 0; + } + + secp256k1_scalar_set_int(&zero, 0); + secp256k1_gej_set_ge(&pt, key); + secp256k1_ecmult(&pt, &pt, tweak, &zero); + secp256k1_ge_set_gej(key, &pt); + return 1; +} + +#endif /* SECP256K1_ECKEY_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult.h new file mode 100644 index 00000000..b47d8f49 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult.h @@ -0,0 +1,50 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_H +#define SECP256K1_ECMULT_H + +#include "group.h" +#include "scalar.h" +#include "scratch.h" + +/* Noone will ever need more than a window size of 24. The code might + * be correct for larger values of ECMULT_WINDOW_SIZE but this is not + * tested. + * + * The following limitations are known, and there are probably more: + * If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect + * because the size of the memory object that we allocate (in bytes) + * will not fit in a size_t. + * If WINDOW_G > 31 and int has 32 bits, then the code is incorrect + * because certain expressions will overflow. + */ +#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24 +# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24]. +#endif + +/** The number of entries a table with precomputed multiples needs to have. */ +#define ECMULT_TABLE_SIZE(w) (1L << ((w)-2)) + +/** Double multiply: R = na*A + ng*G */ +static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); + +typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); + +/** + * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. + * Chooses the right algorithm for a given number of points and scratch space + * size. Resets and overwrites the given scratch space. If the points do not + * fit in the scratch space the algorithm is repeatedly run with batches of + * points. If no scratch space is given then a simple algorithm is used that + * simply multiplies the points with the corresponding scalars and adds them up. + * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) + * 0 if there is not enough scratch space for a single point or + * callback returns 0 + */ +static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); + +#endif /* SECP256K1_ECMULT_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table.h new file mode 100644 index 00000000..665f87ff --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table.h @@ -0,0 +1,16 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H +#define SECP256K1_ECMULT_COMPUTE_TABLE_H + +/* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */ +static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen); + +/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */ +static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen); + +#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table_impl.h new file mode 100644 index 00000000..69d59ce5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_compute_table_impl.h @@ -0,0 +1,49 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H +#define SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H + +#include "ecmult_compute_table.h" +#include "group_impl.h" +#include "field_impl.h" +#include "ecmult.h" +#include "util.h" + +static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen) { + secp256k1_gej gj; + secp256k1_ge ge, dgen; + int j; + + gj = *gen; + secp256k1_ge_set_gej_var(&ge, &gj); + secp256k1_ge_to_storage(&table[0], &ge); + + secp256k1_gej_double_var(&gj, gen, NULL); + secp256k1_ge_set_gej_var(&dgen, &gj); + + for (j = 1; j < ECMULT_TABLE_SIZE(window_g); ++j) { + secp256k1_gej_set_ge(&gj, &ge); + secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL); + secp256k1_ge_set_gej_var(&ge, &gj); + secp256k1_ge_to_storage(&table[j], &ge); + } +} + +/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */ +static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen) { + secp256k1_gej gj; + int i; + + secp256k1_gej_set_ge(&gj, gen); + secp256k1_ecmult_compute_table(table, window_g, &gj); + for (i = 0; i < 128; ++i) { + secp256k1_gej_double_var(&gj, &gj, NULL); + } + secp256k1_ecmult_compute_table(table_128, window_g, &gj); +} + +#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const.h new file mode 100644 index 00000000..f891f3f3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const.h @@ -0,0 +1,21 @@ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_CONST_H +#define SECP256K1_ECMULT_CONST_H + +#include "scalar.h" +#include "group.h" + +/** + * Multiply: R = q*A (in constant-time) + * Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus + * one because we internally sometimes add 2 to the number during the WNAF conversion. + * A must not be infinity. + */ +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits); + +#endif /* SECP256K1_ECMULT_CONST_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const_impl.h new file mode 100644 index 00000000..12dbcc6c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_const_impl.h @@ -0,0 +1,231 @@ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_CONST_IMPL_H +#define SECP256K1_ECMULT_CONST_IMPL_H + +#include "scalar.h" +#include "group.h" +#include "ecmult_const.h" +#include "ecmult_impl.h" + +/** Fill a table 'pre' with precomputed odd multiples of a. + * + * The resulting point set is brought to a single constant Z denominator, stores the X and Y + * coordinates as ge_storage points in pre, and stores the global Z in globalz. + * It only operates on tables sized for WINDOW_A wnaf multiples. + */ +static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { + secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; + + secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), pre, zr, globalz, a); + secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A), pre, zr); +} + +/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ +#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ + int m = 0; \ + /* Extract the sign-bit for a constant time absolute-value. */ \ + int mask = (n) >> (sizeof(n) * CHAR_BIT - 1); \ + int abs_n = ((n) + mask) ^ mask; \ + int idx_n = abs_n >> 1; \ + secp256k1_fe neg_y; \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ + /* Unconditionally set r->x = (pre)[m].x. r->y = (pre)[m].y. because it's either the correct one \ + * or will get replaced in the later iterations, this is needed to make sure `r` is initialized. */ \ + (r)->x = (pre)[m].x; \ + (r)->y = (pre)[m].y; \ + for (m = 1; m < ECMULT_TABLE_SIZE(w); m++) { \ + /* This loop is used to avoid secret data in array indices. See + * the comment in ecmult_gen_impl.h for rationale. */ \ + secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ + secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ + } \ + (r)->infinity = 0; \ + secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ + secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ +} while(0) + +/** Convert a number to WNAF notation. + * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. + * It has the following guarantees: + * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) + * - each wnaf[i] is nonzero + * - the number of words set is always WNAF_SIZE(w) + 1 + * + * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar + * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) + * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlag Berlin Heidelberg 2003 + * + * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 + */ +static int secp256k1_wnaf_const(int *wnaf, const secp256k1_scalar *scalar, int w, int size) { + int global_sign; + int skew; + int word = 0; + + /* 1 2 3 */ + int u_last; + int u; + + int flip; + secp256k1_scalar s = *scalar; + + VERIFY_CHECK(w > 0); + VERIFY_CHECK(size > 0); + + /* Note that we cannot handle even numbers by negating them to be odd, as is + * done in other implementations, since if our scalars were specified to have + * width < 256 for performance reasons, their negations would have width 256 + * and we'd lose any performance benefit. Instead, we use a variation of a + * technique from Section 4.2 of the Okeya/Tagaki paper, which is to add 1 to the + * number we are encoding when it is even, returning a skew value indicating + * this, and having the caller compensate after doing the multiplication. + * + * In fact, we _do_ want to negate numbers to minimize their bit-lengths (and in + * particular, to ensure that the outputs from the endomorphism-split fit into + * 128 bits). If we negate, the parity of our number flips, affecting whether + * we want to add to the scalar to ensure that it's odd. */ + flip = secp256k1_scalar_is_high(&s); + skew = flip ^ secp256k1_scalar_is_even(&s); + secp256k1_scalar_cadd_bit(&s, 0, skew); + global_sign = secp256k1_scalar_cond_negate(&s, flip); + + /* 4 */ + u_last = secp256k1_scalar_shr_int(&s, w); + do { + int even; + + /* 4.1 4.4 */ + u = secp256k1_scalar_shr_int(&s, w); + /* 4.2 */ + even = ((u & 1) == 0); + /* In contrast to the original algorithm, u_last is always > 0 and + * therefore we do not need to check its sign. In particular, it's easy + * to see that u_last is never < 0 because u is never < 0. Moreover, + * u_last is never = 0 because u is never even after a loop + * iteration. The same holds analogously for the initial value of + * u_last (in the first loop iteration). */ + VERIFY_CHECK(u_last > 0); + VERIFY_CHECK((u_last & 1) == 1); + u += even; + u_last -= even * (1 << w); + + /* 4.3, adapted for global sign change */ + wnaf[word++] = u_last * global_sign; + + u_last = u; + } while (word * w < size); + wnaf[word] = u * global_sign; + + VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); + VERIFY_CHECK(word == WNAF_SIZE_BITS(size, w)); + return skew; +} + +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar, int size) { + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge tmpa; + secp256k1_fe Z; + + int skew_1; + secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; + int skew_lam; + secp256k1_scalar q_1, q_lam; + int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; + + int i; + + /* build wnaf representation for q. */ + int rsize = size; + if (size > 128) { + rsize = 128; + /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ + secp256k1_scalar_split_lambda(&q_1, &q_lam, scalar); + skew_1 = secp256k1_wnaf_const(wnaf_1, &q_1, WINDOW_A - 1, 128); + skew_lam = secp256k1_wnaf_const(wnaf_lam, &q_lam, WINDOW_A - 1, 128); + } else + { + skew_1 = secp256k1_wnaf_const(wnaf_1, scalar, WINDOW_A - 1, size); + skew_lam = 0; + } + + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + */ + VERIFY_CHECK(!a->infinity); + secp256k1_gej_set_ge(r, a); + secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_fe_normalize_weak(&pre_a[i].y); + } + if (size > 128) { + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); + } + + } + + /* first loop iteration (separated out so we can directly set r, rather + * than having it start at infinity, get doubled several times, then have + * its new value added to it) */ + i = wnaf_1[WNAF_SIZE_BITS(rsize, WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); + secp256k1_gej_set_ge(r, &tmpa); + if (size > 128) { + i = wnaf_lam[WNAF_SIZE_BITS(rsize, WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); + secp256k1_gej_add_ge(r, r, &tmpa); + } + /* remaining loop iterations */ + for (i = WNAF_SIZE_BITS(rsize, WINDOW_A - 1) - 1; i >= 0; i--) { + int n; + int j; + for (j = 0; j < WINDOW_A - 1; ++j) { + secp256k1_gej_double(r, r); + } + + n = wnaf_1[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); + if (size > 128) { + n = wnaf_lam[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); + } + } + + { + /* Correct for wNAF skew */ + secp256k1_gej tmpj; + + secp256k1_ge_neg(&tmpa, &pre_a[0]); + secp256k1_gej_add_ge(&tmpj, r, &tmpa); + secp256k1_gej_cmov(r, &tmpj, skew_1); + + if (size > 128) { + secp256k1_ge_neg(&tmpa, &pre_a_lam[0]); + secp256k1_gej_add_ge(&tmpj, r, &tmpa); + secp256k1_gej_cmov(r, &tmpj, skew_lam); + } + } + + secp256k1_fe_mul(&r->z, &r->z, &Z); +} + +#endif /* SECP256K1_ECMULT_CONST_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen.h new file mode 100644 index 00000000..f48f2664 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen.h @@ -0,0 +1,36 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_H +#define SECP256K1_ECMULT_GEN_H + +#include "scalar.h" +#include "group.h" + +#if ECMULT_GEN_PREC_BITS != 2 && ECMULT_GEN_PREC_BITS != 4 && ECMULT_GEN_PREC_BITS != 8 +# error "Set ECMULT_GEN_PREC_BITS to 2, 4 or 8." +#endif +#define ECMULT_GEN_PREC_G(bits) (1 << bits) +#define ECMULT_GEN_PREC_N(bits) (256 / bits) + +typedef struct { + /* Whether the context has been built. */ + int built; + + /* Blinding values used when computing (n-b)G + bG. */ + secp256k1_scalar blind; /* -b */ + secp256k1_gej initial; /* bG */ +} secp256k1_ecmult_gen_context; + +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); + +/** Multiply with the generator: R = a*G */ +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); + +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); + +#endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table.h new file mode 100644 index 00000000..e577158d --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table.h @@ -0,0 +1,14 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H +#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H + +#include "ecmult_gen.h" + +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits); + +#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table_impl.h new file mode 100644 index 00000000..ff6a2992 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_compute_table_impl.h @@ -0,0 +1,81 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H +#define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H + +#include "ecmult_gen_compute_table.h" +#include "group_impl.h" +#include "field_impl.h" +#include "ecmult_gen.h" +#include "util.h" + +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) { + int g = ECMULT_GEN_PREC_G(bits); + int n = ECMULT_GEN_PREC_N(bits); + + secp256k1_ge* prec = checked_malloc(&default_error_callback, n * g * sizeof(*prec)); + secp256k1_gej gj; + secp256k1_gej nums_gej; + int i, j; + + /* get the generator */ + secp256k1_gej_set_ge(&gj, gen); + + /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ + { + static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; + secp256k1_fe nums_x; + secp256k1_ge nums_ge; + int r; + r = secp256k1_fe_set_b32(&nums_x, nums_b32); + (void)r; + VERIFY_CHECK(r); + r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); + (void)r; + VERIFY_CHECK(r); + secp256k1_gej_set_ge(&nums_gej, &nums_ge); + /* Add G to make the bits in x uniformly distributed. */ + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, gen, NULL); + } + + /* compute prec. */ + { + secp256k1_gej gbase; + secp256k1_gej numsbase; + secp256k1_gej* precj = checked_malloc(&default_error_callback, n * g * sizeof(*precj)); /* Jacobian versions of prec. */ + gbase = gj; /* PREC_G^j * G */ + numsbase = nums_gej; /* 2^j * nums. */ + for (j = 0; j < n; j++) { + /* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */ + precj[j*g] = numsbase; + for (i = 1; i < g; i++) { + secp256k1_gej_add_var(&precj[j*g + i], &precj[j*g + i - 1], &gbase, NULL); + } + /* Multiply gbase by PREC_G. */ + for (i = 0; i < bits; i++) { + secp256k1_gej_double_var(&gbase, &gbase, NULL); + } + /* Multiply numbase by 2. */ + secp256k1_gej_double_var(&numsbase, &numsbase, NULL); + if (j == n - 2) { + /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ + secp256k1_gej_neg(&numsbase, &numsbase); + secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); + } + } + secp256k1_ge_set_all_gej_var(prec, precj, n * g); + free(precj); + } + for (j = 0; j < n; j++) { + for (i = 0; i < g; i++) { + secp256k1_ge_to_storage(&table[j*g + i], &prec[j*g + i]); + } + } + free(prec); +} + +#endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_impl.h new file mode 100644 index 00000000..2c8a503a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_gen_impl.h @@ -0,0 +1,132 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_ECMULT_GEN_IMPL_H +#define SECP256K1_ECMULT_GEN_IMPL_H + +#include "util.h" +#include "scalar.h" +#include "group.h" +#include "ecmult_gen.h" +#include "hash_impl.h" +#include "precomputed_ecmult_gen.h" + +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx) { + secp256k1_ecmult_gen_blind(ctx, NULL); + ctx->built = 1; +} + +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { + return ctx->built; +} + +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { + ctx->built = 0; + secp256k1_scalar_clear(&ctx->blind); + secp256k1_gej_clear(&ctx->initial); +} + +/* For accelerating the computation of a*G: + * To harden against timing attacks, use the following mechanism: + * * Break up the multiplicand into groups of PREC_BITS bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). + * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: + * * U_i = U * 2^i, for i=0 ... PREC_N-2 + * * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1 + * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0. + * For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is + * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1). + * None of the resulting prec group elements have a known scalar, and neither do any of + * the intermediate sums while computing a*G. + * The prec values are stored in secp256k1_ecmult_gen_prec_table[i][n_i] = n_i * (PREC_G)^i * G + U_i. + */ +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + int bits = ECMULT_GEN_PREC_BITS; + int g = ECMULT_GEN_PREC_G(bits); + int n = ECMULT_GEN_PREC_N(bits); + + secp256k1_ge add; + secp256k1_ge_storage adds; + secp256k1_scalar gnb; + int i, j, n_i; + + memset(&adds, 0, sizeof(adds)); + *r = ctx->initial; + /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ + secp256k1_scalar_add(&gnb, gn, &ctx->blind); + add.infinity = 0; + for (i = 0; i < n; i++) { + n_i = secp256k1_scalar_get_bits(&gnb, i * bits, bits); + for (j = 0; j < g; j++) { + /** This uses a conditional move to avoid any secret data in array indexes. + * _Any_ use of secret indexes has been demonstrated to result in timing + * sidechannels, even when the cache-line access patterns are uniform. + * See also: + * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe + * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and + * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, + * by Dag Arne Osvik, Adi Shamir, and Eran Tromer + * (https://www.tau.ac.il/~tromer/papers/cache.pdf) + */ + secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[i][j], j == n_i); + } + secp256k1_ge_from_storage(&add, &adds); + secp256k1_gej_add_ge(r, r, &add); + } + n_i = 0; + secp256k1_ge_clear(&add); + secp256k1_scalar_clear(&gnb); +} + +/* Setup blinding values for secp256k1_ecmult_gen. */ +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { + secp256k1_scalar b; + secp256k1_gej gb; + secp256k1_fe s; + unsigned char nonce32[32]; + secp256k1_rfc6979_hmac_sha256 rng; + int overflow; + unsigned char keydata[64] = {0}; + if (seed32 == NULL) { + /* When seed is NULL, reset the initial point and blinding value. */ + secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); + secp256k1_gej_neg(&ctx->initial, &ctx->initial); + secp256k1_scalar_set_int(&ctx->blind, 1); + } + /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ + secp256k1_scalar_get_b32(nonce32, &ctx->blind); + /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, + * and guards against weak or adversarial seeds. This is a simpler and safer interface than + * asking the caller for blinding values directly and expecting them to retry on failure. + */ + memcpy(keydata, nonce32, 32); + if (seed32 != NULL) { + memcpy(keydata + 32, seed32, 32); + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); + memset(keydata, 0, sizeof(keydata)); + /* Accept unobservably small non-uniformity. */ + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + overflow = !secp256k1_fe_set_b32(&s, nonce32); + overflow |= secp256k1_fe_is_zero(&s); + secp256k1_fe_cmov(&s, &secp256k1_fe_one, overflow); + /* Randomize the projection to defend against multiplier sidechannels. */ + secp256k1_gej_rescale(&ctx->initial, &s); + secp256k1_fe_clear(&s); + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_scalar_set_b32(&b, nonce32, NULL); + /* A blinding value of 0 works, but would undermine the projection hardening. */ + secp256k1_scalar_cmov(&b, &secp256k1_scalar_one, secp256k1_scalar_is_zero(&b)); + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + memset(nonce32, 0, 32); + secp256k1_ecmult_gen(ctx, &gb, &b); + secp256k1_scalar_negate(&b, &b); + ctx->blind = b; + ctx->initial = gb; + secp256k1_scalar_clear(&b); + secp256k1_gej_clear(&gb); +} + +#endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_impl.h new file mode 100644 index 00000000..bbc820c7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/ecmult_impl.h @@ -0,0 +1,859 @@ +/****************************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + ******************************************************************************/ + +#ifndef SECP256K1_ECMULT_IMPL_H +#define SECP256K1_ECMULT_IMPL_H + +#include +#include + +#include "util.h" +#include "group.h" +#include "scalar.h" +#include "ecmult.h" +#include "precomputed_ecmult.h" + +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to lower these values for exhaustive tests because + * the tables cannot have infinities in them (this breaks the + * affine-isomorphism stuff which tracks z-ratios) */ +# if EXHAUSTIVE_TEST_ORDER > 128 +# define WINDOW_A 5 +# elif EXHAUSTIVE_TEST_ORDER > 8 +# define WINDOW_A 4 +# else +# define WINDOW_A 2 +# endif +#else +/* optimal for 128-bit and 256-bit exponents. */ +# define WINDOW_A 5 +/** Larger values for ECMULT_WINDOW_SIZE result in possibly better + * performance at the cost of an exponentially larger precomputed + * table. The exact table size is + * (1 << (WINDOW_G - 2)) * sizeof(secp256k1_ge_storage) bytes, + * where sizeof(secp256k1_ge_storage) is typically 64 bytes but can + * be larger due to platform-specific padding and alignment. + * Two tables of this size are used (due to the endomorphism + * optimization). + */ +#endif + +#define WNAF_BITS 128 +#define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w)) +#define WNAF_SIZE(w) WNAF_SIZE_BITS(WNAF_BITS, w) + +/* The number of objects allocated on the scratch space for ecmult_multi algorithms */ +#define PIPPENGER_SCRATCH_OBJECTS 6 +#define STRAUSS_SCRATCH_OBJECTS 5 + +#define PIPPENGER_MAX_BUCKET_WINDOW 12 + +/* Minimum number of points for which pippenger_wnaf is faster than strauss wnaf */ +#define ECMULT_PIPPENGER_THRESHOLD 88 + +#define ECMULT_MAX_POINTS_PER_BATCH 5000000 + +/** Fill a table 'pre_a' with precomputed odd multiples of a. + * pre_a will contain [1*a,3*a,...,(2*n-1)*a], so it needs space for n group elements. + * zr needs space for n field elements. + * + * Although pre_a is an array of _ge rather than _gej, it actually represents elements + * in Jacobian coordinates with their z coordinates omitted. The omitted z-coordinates + * can be recovered using z and zr. Using the notation z(b) to represent the omitted + * z coordinate of b: + * - z(pre_a[n-1]) = 'z' + * - z(pre_a[i-1]) = z(pre_a[i]) / zr[i] for n > i > 0 + * + * Lastly the zr[0] value, which isn't used above, is set so that: + * - a.z = z(pre_a[0]) / zr[0] + */ +static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, secp256k1_fe *zr, secp256k1_fe *z, const secp256k1_gej *a) { + secp256k1_gej d, ai; + secp256k1_ge d_ge; + int i; + + VERIFY_CHECK(!a->infinity); + + secp256k1_gej_double_var(&d, a, NULL); + + /* + * Perform the additions using an isomorphic curve Y^2 = X^3 + 7*C^6 where C := d.z. + * The isomorphism, phi, maps a secp256k1 point (x, y) to the point (x*C^2, y*C^3) on the other curve. + * In Jacobian coordinates phi maps (x, y, z) to (x*C^2, y*C^3, z) or, equivalently to (x, y, z/C). + * + * phi(x, y, z) = (x*C^2, y*C^3, z) = (x, y, z/C) + * d_ge := phi(d) = (d.x, d.y, 1) + * ai := phi(a) = (a.x*C^2, a.y*C^3, a.z) + * + * The group addition functions work correctly on these isomorphic curves. + * In particular phi(d) is easy to represent in affine coordinates under this isomorphism. + * This lets us use the faster secp256k1_gej_add_ge_var group addition function that we wouldn't be able to use otherwise. + */ + secp256k1_ge_set_xy(&d_ge, &d.x, &d.y); + secp256k1_ge_set_gej_zinv(&pre_a[0], a, &d.z); + secp256k1_gej_set_ge(&ai, &pre_a[0]); + ai.z = a->z; + + /* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equvalent to a. + * Set zr[0] to C, which is the ratio between the omitted z(pre_a[0]) value and a.z. + */ + zr[0] = d.z; + + for (i = 1; i < n; i++) { + secp256k1_gej_add_ge_var(&ai, &ai, &d_ge, &zr[i]); + secp256k1_ge_set_xy(&pre_a[i], &ai.x, &ai.y); + } + + /* Multiply the last z-coordinate by C to undo the isomorphism. + * Since the z-coordinates of the pre_a values are implied by the zr array of z-coordinate ratios, + * undoing the isomorphism here undoes the isomorphism for all pre_a values. + */ + secp256k1_fe_mul(z, &ai.z, &d.z); +} + +#define SECP256K1_ECMULT_TABLE_VERIFY(n,w) \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); + +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) { + SECP256K1_ECMULT_TABLE_VERIFY(n,w) + if (n > 0) { + *r = pre[(n-1)/2]; + } else { + *r = pre[(-n-1)/2]; + secp256k1_fe_negate(&(r->y), &(r->y), 1); + } +} + +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) { + SECP256K1_ECMULT_TABLE_VERIFY(n,w) + if (n > 0) { + secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y); + } else { + secp256k1_ge_set_xy(r, &x[(-n-1)/2], &pre[(-n-1)/2].y); + secp256k1_fe_negate(&(r->y), &(r->y), 1); + } +} + +SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) { + SECP256K1_ECMULT_TABLE_VERIFY(n,w) + if (n > 0) { + secp256k1_ge_from_storage(r, &pre[(n-1)/2]); + } else { + secp256k1_ge_from_storage(r, &pre[(-n-1)/2]); + secp256k1_fe_negate(&(r->y), &(r->y), 1); + } +} + +/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), + * with the following guarantees: + * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) + * - two non-zero entries in wnaf are separated by at least w-1 zeroes. + * - the number of set values in wnaf is returned. This number is at most 256, and at most one more + * than the number of bits in the (absolute value) of the input. + */ +static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { + secp256k1_scalar s; + int last_set_bit = -1; + int bit = 0; + int sign = 1; + int carry = 0; + + VERIFY_CHECK(wnaf != NULL); + VERIFY_CHECK(0 <= len && len <= 256); + VERIFY_CHECK(a != NULL); + VERIFY_CHECK(2 <= w && w <= 31); + + memset(wnaf, 0, len * sizeof(wnaf[0])); + + s = *a; + if (secp256k1_scalar_get_bits(&s, 255, 1)) { + secp256k1_scalar_negate(&s, &s); + sign = -1; + } + + while (bit < len) { + int now; + int word; + if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { + bit++; + continue; + } + + now = w; + if (now > len - bit) { + now = len - bit; + } + + word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; + + carry = (word >> (w-1)) & 1; + word -= carry << w; + + wnaf[bit] = sign * word; + last_set_bit = bit; + + bit += now; + } +#ifdef VERIFY + CHECK(carry == 0); + while (bit < 256) { + CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); + } +#endif + return last_set_bit + 1; +} + +struct secp256k1_strauss_point_state { + int wnaf_na_1[129]; + int wnaf_na_lam[129]; + int bits_na_1; + int bits_na_lam; +}; + +struct secp256k1_strauss_state { + /* aux is used to hold z-ratios, and then used to hold pre_a[i].x * BETA values. */ + secp256k1_fe* aux; + secp256k1_ge* pre_a; + struct secp256k1_strauss_point_state* ps; +}; + +static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *state, secp256k1_gej *r, size_t num, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_ge tmpa; + secp256k1_fe Z; + /* Split G factors. */ + secp256k1_scalar ng_1, ng_128; + int wnaf_ng_1[129]; + int bits_ng_1 = 0; + int wnaf_ng_128[129]; + int bits_ng_128 = 0; + int i; + int bits = 0; + size_t np; + size_t no = 0; + + secp256k1_fe_set_int(&Z, 1); + for (np = 0; np < num; ++np) { + secp256k1_gej tmp; + secp256k1_scalar na_1, na_lam; + if (secp256k1_scalar_is_zero(&na[np]) || secp256k1_gej_is_infinity(&a[np])) { + continue; + } + /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ + secp256k1_scalar_split_lambda(&na_1, &na_lam, &na[np]); + + /* build wnaf representation for na_1 and na_lam. */ + state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_1, 129, &na_1, WINDOW_A); + state->ps[no].bits_na_lam = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_lam, 129, &na_lam, WINDOW_A); + VERIFY_CHECK(state->ps[no].bits_na_1 <= 129); + VERIFY_CHECK(state->ps[no].bits_na_lam <= 129); + if (state->ps[no].bits_na_1 > bits) { + bits = state->ps[no].bits_na_1; + } + if (state->ps[no].bits_na_lam > bits) { + bits = state->ps[no].bits_na_lam; + } + + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + * The exception is the precomputed G table points, which are actually + * affine. Compared to the base used for other points, they have a Z ratio + * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same + * isomorphism to efficiently add with a known Z inverse. + */ + tmp = a[np]; + if (no) { +#ifdef VERIFY + secp256k1_fe_normalize_var(&Z); +#endif + secp256k1_gej_rescale(&tmp, &Z); + } + secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), state->pre_a + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &Z, &tmp); + if (no) secp256k1_fe_mul(state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &(a[np].z)); + + ++no; + } + + /* Bring them to the same Z denominator. */ + secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux); + + for (np = 0; np < no; ++np) { + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_fe_mul(&state->aux[np * ECMULT_TABLE_SIZE(WINDOW_A) + i], &state->pre_a[np * ECMULT_TABLE_SIZE(WINDOW_A) + i].x, &secp256k1_const_beta); + } + } + + if (ng) { + /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ + secp256k1_scalar_split_128(&ng_1, &ng_128, ng); + + /* Build wnaf representation for ng_1 and ng_128 */ + bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); + bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); + if (bits_ng_1 > bits) { + bits = bits_ng_1; + } + if (bits_ng_128 > bits) { + bits = bits_ng_128; + } + } + + secp256k1_gej_set_infinity(r); + + for (i = bits - 1; i >= 0; i--) { + int n; + secp256k1_gej_double_var(r, r, NULL); + for (np = 0; np < no; ++np) { + if (i < state->ps[np].bits_na_1 && (n = state->ps[np].wnaf_na_1[i])) { + secp256k1_ecmult_table_get_ge(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); + } + if (i < state->ps[np].bits_na_lam && (n = state->ps[np].wnaf_na_lam[i])) { + secp256k1_ecmult_table_get_ge_lambda(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); + } + } + if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { + secp256k1_ecmult_table_get_ge_storage(&tmpa, secp256k1_pre_g, n, WINDOW_G); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); + } + if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { + secp256k1_ecmult_table_get_ge_storage(&tmpa, secp256k1_pre_g_128, n, WINDOW_G); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); + } + } + + if (!r->infinity) { + secp256k1_fe_mul(&r->z, &r->z, &Z); + } +} + +static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_fe aux[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + struct secp256k1_strauss_point_state ps[1]; + struct secp256k1_strauss_state state; + + state.aux = aux; + state.pre_a = pre_a; + state.ps = ps; + secp256k1_ecmult_strauss_wnaf(&state, r, 1, a, na, ng); +} + +static size_t secp256k1_strauss_scratch_size(size_t n_points) { + static const size_t point_size = (sizeof(secp256k1_ge) + sizeof(secp256k1_fe)) * ECMULT_TABLE_SIZE(WINDOW_A) + sizeof(struct secp256k1_strauss_point_state) + sizeof(secp256k1_gej) + sizeof(secp256k1_scalar); + return n_points*point_size; +} + +static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points, size_t cb_offset) { + secp256k1_gej* points; + secp256k1_scalar* scalars; + struct secp256k1_strauss_state state; + size_t i; + const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch); + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n_points == 0) { + return 1; + } + + /* We allocate STRAUSS_SCRATCH_OBJECTS objects on the scratch space. If these + * allocations change, make sure to update the STRAUSS_SCRATCH_OBJECTS + * constant and strauss_scratch_size accordingly. */ + points = (secp256k1_gej*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_gej)); + scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_scalar)); + state.aux = (secp256k1_fe*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_fe)); + state.pre_a = (secp256k1_ge*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_ge)); + state.ps = (struct secp256k1_strauss_point_state*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(struct secp256k1_strauss_point_state)); + + if (points == NULL || scalars == NULL || state.aux == NULL || state.pre_a == NULL || state.ps == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + + for (i = 0; i < n_points; i++) { + secp256k1_ge point; + if (!cb(&scalars[i], &point, i+cb_offset, cbdata)) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + secp256k1_gej_set_ge(&points[i], &point); + } + secp256k1_ecmult_strauss_wnaf(&state, r, n_points, points, scalars, inp_g_sc); + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 1; +} + +/* Wrapper for secp256k1_ecmult_multi_func interface */ +static int secp256k1_ecmult_strauss_batch_single(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { + return secp256k1_ecmult_strauss_batch(error_callback, scratch, r, inp_g_sc, cb, cbdata, n, 0); +} + +static size_t secp256k1_strauss_max_points(const secp256k1_callback* error_callback, secp256k1_scratch *scratch) { + return secp256k1_scratch_max_allocation(error_callback, scratch, STRAUSS_SCRATCH_OBJECTS) / secp256k1_strauss_scratch_size(1); +} + +/** Convert a number to WNAF notation. + * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. + * It has the following guarantees: + * - each wnaf[i] is either 0 or an odd integer between -(1 << w) and (1 << w) + * - the number of words set is always WNAF_SIZE(w) + * - the returned skew is 0 or 1 + */ +static int secp256k1_wnaf_fixed(int *wnaf, const secp256k1_scalar *s, int w) { + int skew = 0; + int pos; + int max_pos; + int last_w; + const secp256k1_scalar *work = s; + + if (secp256k1_scalar_is_zero(s)) { + for (pos = 0; pos < WNAF_SIZE(w); pos++) { + wnaf[pos] = 0; + } + return 0; + } + + if (secp256k1_scalar_is_even(s)) { + skew = 1; + } + + wnaf[0] = secp256k1_scalar_get_bits_var(work, 0, w) + skew; + /* Compute last window size. Relevant when window size doesn't divide the + * number of bits in the scalar */ + last_w = WNAF_BITS - (WNAF_SIZE(w) - 1) * w; + + /* Store the position of the first nonzero word in max_pos to allow + * skipping leading zeros when calculating the wnaf. */ + for (pos = WNAF_SIZE(w) - 1; pos > 0; pos--) { + int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); + if(val != 0) { + break; + } + wnaf[pos] = 0; + } + max_pos = pos; + pos = 1; + + while (pos <= max_pos) { + int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); + if ((val & 1) == 0) { + wnaf[pos - 1] -= (1 << w); + wnaf[pos] = (val + 1); + } else { + wnaf[pos] = val; + } + /* Set a coefficient to zero if it is 1 or -1 and the proceeding digit + * is strictly negative or strictly positive respectively. Only change + * coefficients at previous positions because above code assumes that + * wnaf[pos - 1] is odd. + */ + if (pos >= 2 && ((wnaf[pos - 1] == 1 && wnaf[pos - 2] < 0) || (wnaf[pos - 1] == -1 && wnaf[pos - 2] > 0))) { + if (wnaf[pos - 1] == 1) { + wnaf[pos - 2] += 1 << w; + } else { + wnaf[pos - 2] -= 1 << w; + } + wnaf[pos - 1] = 0; + } + ++pos; + } + + return skew; +} + +struct secp256k1_pippenger_point_state { + int skew_na; + size_t input_pos; +}; + +struct secp256k1_pippenger_state { + int *wnaf_na; + struct secp256k1_pippenger_point_state* ps; +}; + +/* + * pippenger_wnaf computes the result of a multi-point multiplication as + * follows: The scalars are brought into wnaf with n_wnaf elements each. Then + * for every i < n_wnaf, first each point is added to a "bucket" corresponding + * to the point's wnaf[i]. Second, the buckets are added together such that + * r += 1*bucket[0] + 3*bucket[1] + 5*bucket[2] + ... + */ +static int secp256k1_ecmult_pippenger_wnaf(secp256k1_gej *buckets, int bucket_window, struct secp256k1_pippenger_state *state, secp256k1_gej *r, const secp256k1_scalar *sc, const secp256k1_ge *pt, size_t num) { + size_t n_wnaf = WNAF_SIZE(bucket_window+1); + size_t np; + size_t no = 0; + int i; + int j; + + for (np = 0; np < num; ++np) { + if (secp256k1_scalar_is_zero(&sc[np]) || secp256k1_ge_is_infinity(&pt[np])) { + continue; + } + state->ps[no].input_pos = np; + state->ps[no].skew_na = secp256k1_wnaf_fixed(&state->wnaf_na[no*n_wnaf], &sc[np], bucket_window+1); + no++; + } + secp256k1_gej_set_infinity(r); + + if (no == 0) { + return 1; + } + + for (i = n_wnaf - 1; i >= 0; i--) { + secp256k1_gej running_sum; + + for(j = 0; j < ECMULT_TABLE_SIZE(bucket_window+2); j++) { + secp256k1_gej_set_infinity(&buckets[j]); + } + + for (np = 0; np < no; ++np) { + int n = state->wnaf_na[np*n_wnaf + i]; + struct secp256k1_pippenger_point_state point_state = state->ps[np]; + secp256k1_ge tmp; + int idx; + + if (i == 0) { + /* correct for wnaf skew */ + int skew = point_state.skew_na; + if (skew) { + secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); + secp256k1_gej_add_ge_var(&buckets[0], &buckets[0], &tmp, NULL); + } + } + if (n > 0) { + idx = (n - 1)/2; + secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &pt[point_state.input_pos], NULL); + } else if (n < 0) { + idx = -(n + 1)/2; + secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); + secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &tmp, NULL); + } + } + + for(j = 0; j < bucket_window; j++) { + secp256k1_gej_double_var(r, r, NULL); + } + + secp256k1_gej_set_infinity(&running_sum); + /* Accumulate the sum: bucket[0] + 3*bucket[1] + 5*bucket[2] + 7*bucket[3] + ... + * = bucket[0] + bucket[1] + bucket[2] + bucket[3] + ... + * + 2 * (bucket[1] + 2*bucket[2] + 3*bucket[3] + ...) + * using an intermediate running sum: + * running_sum = bucket[0] + bucket[1] + bucket[2] + ... + * + * The doubling is done implicitly by deferring the final window doubling (of 'r'). + */ + for(j = ECMULT_TABLE_SIZE(bucket_window+2) - 1; j > 0; j--) { + secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[j], NULL); + secp256k1_gej_add_var(r, r, &running_sum, NULL); + } + + secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[0], NULL); + secp256k1_gej_double_var(r, r, NULL); + secp256k1_gej_add_var(r, r, &running_sum, NULL); + } + return 1; +} + +/** + * Returns optimal bucket_window (number of bits of a scalar represented by a + * set of buckets) for a given number of points. + */ +static int secp256k1_pippenger_bucket_window(size_t n) { + if (n <= 1) { + return 1; + } else if (n <= 4) { + return 2; + } else if (n <= 20) { + return 3; + } else if (n <= 57) { + return 4; + } else if (n <= 136) { + return 5; + } else if (n <= 235) { + return 6; + } else if (n <= 1260) { + return 7; + } else if (n <= 4420) { + return 9; + } else if (n <= 7880) { + return 10; + } else if (n <= 16050) { + return 11; + } else { + return PIPPENGER_MAX_BUCKET_WINDOW; + } +} + +/** + * Returns the maximum optimal number of points for a bucket_window. + */ +static size_t secp256k1_pippenger_bucket_window_inv(int bucket_window) { + switch(bucket_window) { + case 1: return 1; + case 2: return 4; + case 3: return 20; + case 4: return 57; + case 5: return 136; + case 6: return 235; + case 7: return 1260; + case 8: return 1260; + case 9: return 4420; + case 10: return 7880; + case 11: return 16050; + case PIPPENGER_MAX_BUCKET_WINDOW: return SIZE_MAX; + } + return 0; +} + + +SECP256K1_INLINE static void secp256k1_ecmult_endo_split(secp256k1_scalar *s1, secp256k1_scalar *s2, secp256k1_ge *p1, secp256k1_ge *p2) { + secp256k1_scalar tmp = *s1; + secp256k1_scalar_split_lambda(s1, s2, &tmp); + secp256k1_ge_mul_lambda(p2, p1); + + if (secp256k1_scalar_is_high(s1)) { + secp256k1_scalar_negate(s1, s1); + secp256k1_ge_neg(p1, p1); + } + if (secp256k1_scalar_is_high(s2)) { + secp256k1_scalar_negate(s2, s2); + secp256k1_ge_neg(p2, p2); + } +} + +/** + * Returns the scratch size required for a given number of points (excluding + * base point G) without considering alignment. + */ +static size_t secp256k1_pippenger_scratch_size(size_t n_points, int bucket_window) { + size_t entries = 2*n_points + 2; + size_t entry_size = sizeof(secp256k1_ge) + sizeof(secp256k1_scalar) + sizeof(struct secp256k1_pippenger_point_state) + (WNAF_SIZE(bucket_window+1)+1)*sizeof(int); + return (sizeof(secp256k1_gej) << bucket_window) + sizeof(struct secp256k1_pippenger_state) + entries * entry_size; +} + +static int secp256k1_ecmult_pippenger_batch(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points, size_t cb_offset) { + const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch); + /* Use 2(n+1) with the endomorphism, when calculating batch + * sizes. The reason for +1 is that we add the G scalar to the list of + * other scalars. */ + size_t entries = 2*n_points + 2; + secp256k1_ge *points; + secp256k1_scalar *scalars; + secp256k1_gej *buckets; + struct secp256k1_pippenger_state *state_space; + size_t idx = 0; + size_t point_idx = 0; + int i, j; + int bucket_window; + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n_points == 0) { + return 1; + } + bucket_window = secp256k1_pippenger_bucket_window(n_points); + + /* We allocate PIPPENGER_SCRATCH_OBJECTS objects on the scratch space. If + * these allocations change, make sure to update the + * PIPPENGER_SCRATCH_OBJECTS constant and pippenger_scratch_size + * accordingly. */ + points = (secp256k1_ge *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*points)); + scalars = (secp256k1_scalar *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*scalars)); + state_space = (struct secp256k1_pippenger_state *) secp256k1_scratch_alloc(error_callback, scratch, sizeof(*state_space)); + if (points == NULL || scalars == NULL || state_space == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + state_space->ps = (struct secp256k1_pippenger_point_state *) secp256k1_scratch_alloc(error_callback, scratch, entries * sizeof(*state_space->ps)); + state_space->wnaf_na = (int *) secp256k1_scratch_alloc(error_callback, scratch, entries*(WNAF_SIZE(bucket_window+1)) * sizeof(int)); + buckets = (secp256k1_gej *) secp256k1_scratch_alloc(error_callback, scratch, (1<ps == NULL || state_space->wnaf_na == NULL || buckets == NULL) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + + if (inp_g_sc != NULL) { + scalars[0] = *inp_g_sc; + points[0] = secp256k1_ge_const_g; + idx++; + secp256k1_ecmult_endo_split(&scalars[0], &scalars[1], &points[0], &points[1]); + idx++; + } + + while (point_idx < n_points) { + if (!cb(&scalars[idx], &points[idx], point_idx + cb_offset, cbdata)) { + secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint); + return 0; + } + idx++; + secp256k1_ecmult_endo_split(&scalars[idx - 1], &scalars[idx], &points[idx - 1], &points[idx]); + idx++; + point_idx++; + } + + secp256k1_ecmult_pippenger_wnaf(buckets, bucket_window, state_space, r, scalars, points, idx); + + /* Clear data */ + for(i = 0; (size_t)i < idx; i++) { + secp256k1_scalar_clear(&scalars[i]); + state_space->ps[i].skew_na = 0; + for(j = 0; j < WNAF_SIZE(bucket_window+1); j++) { + state_space->wnaf_na[i * WNAF_SIZE(bucket_window+1) + j] = 0; + } + } + for(i = 0; i < 1< max_alloc) { + break; + } + space_for_points = max_alloc - space_overhead; + + n_points = space_for_points/entry_size; + n_points = n_points > max_points ? max_points : n_points; + if (n_points > res) { + res = n_points; + } + if (n_points < max_points) { + /* A larger bucket_window may support even more points. But if we + * would choose that then the caller couldn't safely use any number + * smaller than what this function returns */ + break; + } + } + return res; +} + +/* Computes ecmult_multi by simply multiplying and adding each point. Does not + * require a scratch space */ +static int secp256k1_ecmult_multi_simple_var(secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points) { + size_t point_idx; + secp256k1_scalar szero; + secp256k1_gej tmpj; + + secp256k1_scalar_set_int(&szero, 0); + secp256k1_gej_set_infinity(r); + secp256k1_gej_set_infinity(&tmpj); + /* r = inp_g_sc*G */ + secp256k1_ecmult(r, &tmpj, &szero, inp_g_sc); + for (point_idx = 0; point_idx < n_points; point_idx++) { + secp256k1_ge point; + secp256k1_gej pointj; + secp256k1_scalar scalar; + if (!cb(&scalar, &point, point_idx, cbdata)) { + return 0; + } + /* r += scalar*point */ + secp256k1_gej_set_ge(&pointj, &point); + secp256k1_ecmult(&tmpj, &pointj, &scalar, NULL); + secp256k1_gej_add_var(r, r, &tmpj, NULL); + } + return 1; +} + +/* Compute the number of batches and the batch size given the maximum batch size and the + * total number of points */ +static int secp256k1_ecmult_multi_batch_size_helper(size_t *n_batches, size_t *n_batch_points, size_t max_n_batch_points, size_t n) { + if (max_n_batch_points == 0) { + return 0; + } + if (max_n_batch_points > ECMULT_MAX_POINTS_PER_BATCH) { + max_n_batch_points = ECMULT_MAX_POINTS_PER_BATCH; + } + if (n == 0) { + *n_batches = 0; + *n_batch_points = 0; + return 1; + } + /* Compute ceil(n/max_n_batch_points) and ceil(n/n_batches) */ + *n_batches = 1 + (n - 1) / max_n_batch_points; + *n_batch_points = 1 + (n - 1) / *n_batches; + return 1; +} + +typedef int (*secp256k1_ecmult_multi_func)(const secp256k1_callback* error_callback, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t); +static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { + size_t i; + + int (*f)(const secp256k1_callback* error_callback, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t, size_t); + size_t n_batches; + size_t n_batch_points; + + secp256k1_gej_set_infinity(r); + if (inp_g_sc == NULL && n == 0) { + return 1; + } else if (n == 0) { + secp256k1_scalar szero; + secp256k1_scalar_set_int(&szero, 0); + secp256k1_ecmult(r, r, &szero, inp_g_sc); + return 1; + } + if (scratch == NULL) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + + /* Compute the batch sizes for Pippenger's algorithm given a scratch space. If it's greater than + * a threshold use Pippenger's algorithm. Otherwise use Strauss' algorithm. + * As a first step check if there's enough space for Pippenger's algo (which requires less space + * than Strauss' algo) and if not, use the simple algorithm. */ + if (!secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, secp256k1_pippenger_max_points(error_callback, scratch), n)) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD) { + f = secp256k1_ecmult_pippenger_batch; + } else { + if (!secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, secp256k1_strauss_max_points(error_callback, scratch), n)) { + return secp256k1_ecmult_multi_simple_var(r, inp_g_sc, cb, cbdata, n); + } + f = secp256k1_ecmult_strauss_batch; + } + for(i = 0; i < n_batches; i++) { + size_t nbp = n < n_batch_points ? n : n_batch_points; + size_t offset = n_batch_points*i; + secp256k1_gej tmp; + if (!f(error_callback, scratch, &tmp, i == 0 ? inp_g_sc : NULL, cb, cbdata, nbp, offset)) { + return 0; + } + secp256k1_gej_add_var(r, r, &tmp, NULL); + n -= nbp; + } + return 1; +} + +#endif /* SECP256K1_ECMULT_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field.h new file mode 100644 index 00000000..2584a494 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field.h @@ -0,0 +1,142 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_H +#define SECP256K1_FIELD_H + +/** Field element module. + * + * Field elements can be represented in several ways, but code accessing + * it (and implementations) need to take certain properties into account: + * - Each field element can be normalized or not. + * - Each field element has a magnitude, which represents how far away + * its representation is away from normalization. Normalized elements + * always have a magnitude of 0 or 1, but a magnitude of 1 doesn't + * imply normality. + */ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" + +#if defined(SECP256K1_WIDEMUL_INT128) +#include "field_5x52.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "field_10x26.h" +#else +#error "Please select wide multiplication implementation" +#endif + +static const secp256k1_fe secp256k1_fe_one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST( + 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, + 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul +); + +/** Normalize a field element. This brings the field element to a canonical representation, reduces + * its magnitude to 1, and reduces it modulo field size `p`. + */ +static void secp256k1_fe_normalize(secp256k1_fe *r); + +/** Weakly normalize a field element: reduce its magnitude to 1, but don't fully normalize. */ +static void secp256k1_fe_normalize_weak(secp256k1_fe *r); + +/** Normalize a field element, without constant-time guarantee. */ +static void secp256k1_fe_normalize_var(secp256k1_fe *r); + +/** Verify whether a field element represents zero i.e. would normalize to a zero value. */ +static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r); + +/** Verify whether a field element represents zero i.e. would normalize to a zero value, + * without constant-time guarantee. */ +static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r); + +/** Set a field element equal to a small (not greater than 0x7FFF), non-negative integer. + * Resulting field element is normalized; it has magnitude 0 if a == 0, and magnitude 1 otherwise. + */ +static void secp256k1_fe_set_int(secp256k1_fe *r, int a); + +/** Sets a field element equal to zero, initializing all fields. */ +static void secp256k1_fe_clear(secp256k1_fe *a); + +/** Verify whether a field element is zero. Requires the input to be normalized. */ +static int secp256k1_fe_is_zero(const secp256k1_fe *a); + +/** Check the "oddness" of a field element. Requires the input to be normalized. */ +static int secp256k1_fe_is_odd(const secp256k1_fe *a); + +/** Compare two field elements. Requires magnitude-1 inputs. */ +static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Same as secp256k1_fe_equal, but may be variable time. */ +static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Compare two field elements. Requires both inputs to be normalized */ +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); + +/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input + * as an argument. The magnitude of the output is one higher. */ +static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); + +/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that + * small integer. */ +static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); + +/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ +static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); + +/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. + * The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); + +/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. + * The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); + +/** If a has a square root, it is computed in r and 1 is returned. If a does not + * have a square root, the root of its negation is computed and 0 is returned. + * The input's magnitude can be at most 8. The output magnitude is 1 (but not + * guaranteed to be normalized). The result in r will always be a square + * itself. */ +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); + +/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be + * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); + +/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); + +/** Convert a field element to the storage type. */ +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); + +/** Convert a field element back from the storage type. */ +static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); + +/** Halves the value of a field element modulo the field prime. Constant-time. + * For an input magnitude 'm', the output magnitude is set to 'floor(m/2) + 1'. + * The output is not guaranteed to be normalized, regardless of the input. */ +static void secp256k1_fe_half(secp256k1_fe *r); + +/** Sets each limb of 'r' to its upper bound at magnitude 'm'. The output will also have its + * magnitude set to 'm' and is normalized if (and only if) 'm' is zero. */ +static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m); + +#endif /* SECP256K1_FIELD_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26.h new file mode 100644 index 00000000..9eb65607 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26.h @@ -0,0 +1,50 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H + +#include + +typedef struct { + /* X = sum(i=0..9, n[i]*2^(i*26)) mod p + * where p = 2^256 - 0x1000003D1 + */ + uint32_t n[10]; +#ifdef VERIFY + int magnitude; + int normalized; +#endif +} secp256k1_fe; + +/* Unpacks a constant into a overlapping multi-limbed FE element. */ +#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ + (d0) & 0x3FFFFFFUL, \ + (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ + (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ + (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ + (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ + (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ + (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ + (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ + (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ + (((uint32_t)d7) >> 10) \ +} + +#ifdef VERIFY +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} +#else +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} +#endif + +typedef struct { + uint32_t n[8]; +} secp256k1_fe_storage; + +#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} +#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] + +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26_impl.h new file mode 100644 index 00000000..21742bf6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_10x26_impl.h @@ -0,0 +1,1367 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H + +#include "util.h" +#include "field.h" +#include "modinv32_impl.h" + +/** See the comment at the top of field_5x52_impl.h for more details. + * + * Here, we represent field elements as 10 uint32_t's in base 2^26, least significant first, + * where limbs can contain >26 bits. + * A magnitude M means: + * - 2*M*(2^22-1) is the max (inclusive) of the most significant limb + * - 2*M*(2^26-1) is the max (inclusive) of the remaining limbs + */ + +#ifdef VERIFY +static void secp256k1_fe_verify(const secp256k1_fe *a) { + const uint32_t *d = a->n; + int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + r &= (d[0] <= 0x3FFFFFFUL * m); + r &= (d[1] <= 0x3FFFFFFUL * m); + r &= (d[2] <= 0x3FFFFFFUL * m); + r &= (d[3] <= 0x3FFFFFFUL * m); + r &= (d[4] <= 0x3FFFFFFUL * m); + r &= (d[5] <= 0x3FFFFFFUL * m); + r &= (d[6] <= 0x3FFFFFFUL * m); + r &= (d[7] <= 0x3FFFFFFUL * m); + r &= (d[8] <= 0x3FFFFFFUL * m); + r &= (d[9] <= 0x03FFFFFUL * m); + r &= (a->magnitude >= 0); + r &= (a->magnitude <= 32); + if (a->normalized) { + r &= (a->magnitude <= 1); + if (r && (d[9] == 0x03FFFFFUL)) { + uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; + if (mid == 0x3FFFFFFUL) { + r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); + } + } + } + VERIFY_CHECK(r == 1); +} +#endif + +static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m) { + VERIFY_CHECK(m >= 0); + VERIFY_CHECK(m <= 2048); + r->n[0] = 0x3FFFFFFUL * 2 * m; + r->n[1] = 0x3FFFFFFUL * 2 * m; + r->n[2] = 0x3FFFFFFUL * 2 * m; + r->n[3] = 0x3FFFFFFUL * 2 * m; + r->n[4] = 0x3FFFFFFUL * 2 * m; + r->n[5] = 0x3FFFFFFUL * 2 * m; + r->n[6] = 0x3FFFFFFUL * 2 * m; + r->n[7] = 0x3FFFFFFUL * 2 * m; + r->n[8] = 0x3FFFFFFUL * 2 * m; + r->n[9] = 0x03FFFFFUL * 2 * m; +#ifdef VERIFY + r->magnitude = m; + r->normalized = (m == 0); + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize(secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t m; + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) + & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); + + /* Apply the final reduction (for constant-time behaviour, we do it always) */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ + VERIFY_CHECK(t9 >> 22 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t9 &= 0x03FFFFFUL; + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_var(secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t m; + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) + & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); + + if (x) { + t0 += 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ + VERIFY_CHECK(t9 >> 22 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t9 &= 0x03FFFFFUL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint32_t z0, z1; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; + z0 |= t9; z1 &= t9 ^ 0x3C00000UL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + return (z0 == 0) | (z1 == 0x3FFFFFFUL); +} + +static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r) { + uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; + uint32_t z0, z1; + uint32_t x; + + t0 = r->n[0]; + t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + x = t9 >> 22; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + z0 = t0 & 0x3FFFFFFUL; + z1 = z0 ^ 0x3D0UL; + + /* Fast return path should catch the majority of cases */ + if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) { + return 0; + } + + t1 = r->n[1]; + t2 = r->n[2]; + t3 = r->n[3]; + t4 = r->n[4]; + t5 = r->n[5]; + t6 = r->n[6]; + t7 = r->n[7]; + t8 = r->n[8]; + + t9 &= 0x03FFFFFUL; + t1 += (x << 6); + + t1 += (t0 >> 26); + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; + z0 |= t9; z1 &= t9 ^ 0x3C00000UL; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + return (z0 == 0) | (z1 == 0x3FFFFFFUL); +} + +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { + VERIFY_CHECK(0 <= a && a <= 0x7FFF); + r->n[0] = a; + r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; +#ifdef VERIFY + r->magnitude = (a != 0); + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { + const uint32_t *t = a->n; +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; +} + +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return a->n[0] & 1; +} + +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { + int i; +#ifdef VERIFY + a->magnitude = 0; + a->normalized = 1; +#endif + for (i=0; i<10; i++) { + a->n[i] = 0; + } +} + +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { + int i; +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (i = 9; i >= 0; i--) { + if (a->n[i] > b->n[i]) { + return 1; + } + if (a->n[i] < b->n[i]) { + return -1; + } + } + return 0; +} + +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { + int ret; + r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); + r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); + r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); + r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); + r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); + r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); + r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); + r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); + r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); + r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); + + ret = !((r->n[9] == 0x3FFFFFUL) & ((r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL) & ((r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); +#ifdef VERIFY + r->magnitude = 1; + if (ret) { + r->normalized = 1; + secp256k1_fe_verify(r); + } else { + r->normalized = 0; + } +#endif + return ret; +} + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + r[0] = (a->n[9] >> 14) & 0xff; + r[1] = (a->n[9] >> 6) & 0xff; + r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); + r[3] = (a->n[8] >> 16) & 0xff; + r[4] = (a->n[8] >> 8) & 0xff; + r[5] = a->n[8] & 0xff; + r[6] = (a->n[7] >> 18) & 0xff; + r[7] = (a->n[7] >> 10) & 0xff; + r[8] = (a->n[7] >> 2) & 0xff; + r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); + r[10] = (a->n[6] >> 12) & 0xff; + r[11] = (a->n[6] >> 4) & 0xff; + r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); + r[13] = (a->n[5] >> 14) & 0xff; + r[14] = (a->n[5] >> 6) & 0xff; + r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); + r[16] = (a->n[4] >> 16) & 0xff; + r[17] = (a->n[4] >> 8) & 0xff; + r[18] = a->n[4] & 0xff; + r[19] = (a->n[3] >> 18) & 0xff; + r[20] = (a->n[3] >> 10) & 0xff; + r[21] = (a->n[3] >> 2) & 0xff; + r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); + r[23] = (a->n[2] >> 12) & 0xff; + r[24] = (a->n[2] >> 4) & 0xff; + r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); + r[26] = (a->n[1] >> 14) & 0xff; + r[27] = (a->n[1] >> 6) & 0xff; + r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); + r[29] = (a->n[0] >> 16) & 0xff; + r[30] = (a->n[0] >> 8) & 0xff; + r[31] = a->n[0] & 0xff; +} + +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= m); + secp256k1_fe_verify(a); + VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x3FFFFFFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); + VERIFY_CHECK(0x03FFFFFUL * 2 * (m + 1) >= 0x03FFFFFUL * 2 * m); +#endif + r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; + r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; + r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; + r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3]; + r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4]; + r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5]; + r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6]; + r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; + r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; + r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; +#ifdef VERIFY + r->magnitude = m + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { + r->n[0] *= a; + r->n[1] *= a; + r->n[2] *= a; + r->n[3] *= a; + r->n[4] *= a; + r->n[5] *= a; + r->n[6] *= a; + r->n[7] *= a; + r->n[8] *= a; + r->n[9] *= a; +#ifdef VERIFY + r->magnitude *= a; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { +#ifdef VERIFY + secp256k1_fe_verify(a); +#endif + r->n[0] += a->n[0]; + r->n[1] += a->n[1]; + r->n[2] += a->n[2]; + r->n[3] += a->n[3]; + r->n[4] += a->n[4]; + r->n[5] += a->n[5]; + r->n[6] += a->n[6]; + r->n[7] += a->n[7]; + r->n[8] += a->n[8]; + r->n[9] += a->n[9]; +#ifdef VERIFY + r->magnitude += a->magnitude; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +#if defined(USE_EXTERNAL_ASM) + +/* External assembler implementation */ +void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); +void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); + +#else + +#ifdef VERIFY +#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) +#else +#define VERIFY_BITS(x, n) do { } while(0) +#endif + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { + uint64_t c, d; + uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; + uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7; + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + + VERIFY_BITS(a[0], 30); + VERIFY_BITS(a[1], 30); + VERIFY_BITS(a[2], 30); + VERIFY_BITS(a[3], 30); + VERIFY_BITS(a[4], 30); + VERIFY_BITS(a[5], 30); + VERIFY_BITS(a[6], 30); + VERIFY_BITS(a[7], 30); + VERIFY_BITS(a[8], 30); + VERIFY_BITS(a[9], 26); + VERIFY_BITS(b[0], 30); + VERIFY_BITS(b[1], 30); + VERIFY_BITS(b[2], 30); + VERIFY_BITS(b[3], 30); + VERIFY_BITS(b[4], 30); + VERIFY_BITS(b[5], 30); + VERIFY_BITS(b[6], 30); + VERIFY_BITS(b[7], 30); + VERIFY_BITS(b[8], 30); + VERIFY_BITS(b[9], 26); + + /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. + * for 0 <= x <= 9, px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 9 <= x <= 18, px is a shorthand for sum(a[i]*b[x-i], i=(x-9)..9) + * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. + */ + + d = (uint64_t)a[0] * b[9] + + (uint64_t)a[1] * b[8] + + (uint64_t)a[2] * b[7] + + (uint64_t)a[3] * b[6] + + (uint64_t)a[4] * b[5] + + (uint64_t)a[5] * b[4] + + (uint64_t)a[6] * b[3] + + (uint64_t)a[7] * b[2] + + (uint64_t)a[8] * b[1] + + (uint64_t)a[9] * b[0]; + /* VERIFY_BITS(d, 64); */ + /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + t9 = d & M; d >>= 26; + VERIFY_BITS(t9, 26); + VERIFY_BITS(d, 38); + /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + + c = (uint64_t)a[0] * b[0]; + VERIFY_BITS(c, 60); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ + d += (uint64_t)a[1] * b[9] + + (uint64_t)a[2] * b[8] + + (uint64_t)a[3] * b[7] + + (uint64_t)a[4] * b[6] + + (uint64_t)a[5] * b[5] + + (uint64_t)a[6] * b[4] + + (uint64_t)a[7] * b[3] + + (uint64_t)a[8] * b[2] + + (uint64_t)a[9] * b[1]; + VERIFY_BITS(d, 63); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + u0 = d & M; d >>= 26; c += u0 * R0; + VERIFY_BITS(u0, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 61); + /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + t0 = c & M; c >>= 26; c += u0 * R1; + VERIFY_BITS(t0, 26); + VERIFY_BITS(c, 37); + /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + + c += (uint64_t)a[0] * b[1] + + (uint64_t)a[1] * b[0]; + VERIFY_BITS(c, 62); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ + d += (uint64_t)a[2] * b[9] + + (uint64_t)a[3] * b[8] + + (uint64_t)a[4] * b[7] + + (uint64_t)a[5] * b[6] + + (uint64_t)a[6] * b[5] + + (uint64_t)a[7] * b[4] + + (uint64_t)a[8] * b[3] + + (uint64_t)a[9] * b[2]; + VERIFY_BITS(d, 63); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + u1 = d & M; d >>= 26; c += u1 * R0; + VERIFY_BITS(u1, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + t1 = c & M; c >>= 26; c += u1 * R1; + VERIFY_BITS(t1, 26); + VERIFY_BITS(c, 38); + /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + + c += (uint64_t)a[0] * b[2] + + (uint64_t)a[1] * b[1] + + (uint64_t)a[2] * b[0]; + VERIFY_BITS(c, 62); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + d += (uint64_t)a[3] * b[9] + + (uint64_t)a[4] * b[8] + + (uint64_t)a[5] * b[7] + + (uint64_t)a[6] * b[6] + + (uint64_t)a[7] * b[5] + + (uint64_t)a[8] * b[4] + + (uint64_t)a[9] * b[3]; + VERIFY_BITS(d, 63); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + u2 = d & M; d >>= 26; c += u2 * R0; + VERIFY_BITS(u2, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + t2 = c & M; c >>= 26; c += u2 * R1; + VERIFY_BITS(t2, 26); + VERIFY_BITS(c, 38); + /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[3] + + (uint64_t)a[1] * b[2] + + (uint64_t)a[2] * b[1] + + (uint64_t)a[3] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + d += (uint64_t)a[4] * b[9] + + (uint64_t)a[5] * b[8] + + (uint64_t)a[6] * b[7] + + (uint64_t)a[7] * b[6] + + (uint64_t)a[8] * b[5] + + (uint64_t)a[9] * b[4]; + VERIFY_BITS(d, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + u3 = d & M; d >>= 26; c += u3 * R0; + VERIFY_BITS(u3, 26); + VERIFY_BITS(d, 37); + /* VERIFY_BITS(c, 64); */ + /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + t3 = c & M; c >>= 26; c += u3 * R1; + VERIFY_BITS(t3, 26); + VERIFY_BITS(c, 39); + /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[4] + + (uint64_t)a[1] * b[3] + + (uint64_t)a[2] * b[2] + + (uint64_t)a[3] * b[1] + + (uint64_t)a[4] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[5] * b[9] + + (uint64_t)a[6] * b[8] + + (uint64_t)a[7] * b[7] + + (uint64_t)a[8] * b[6] + + (uint64_t)a[9] * b[5]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + u4 = d & M; d >>= 26; c += u4 * R0; + VERIFY_BITS(u4, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + t4 = c & M; c >>= 26; c += u4 * R1; + VERIFY_BITS(t4, 26); + VERIFY_BITS(c, 39); + /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[5] + + (uint64_t)a[1] * b[4] + + (uint64_t)a[2] * b[3] + + (uint64_t)a[3] * b[2] + + (uint64_t)a[4] * b[1] + + (uint64_t)a[5] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[6] * b[9] + + (uint64_t)a[7] * b[8] + + (uint64_t)a[8] * b[7] + + (uint64_t)a[9] * b[6]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + u5 = d & M; d >>= 26; c += u5 * R0; + VERIFY_BITS(u5, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + t5 = c & M; c >>= 26; c += u5 * R1; + VERIFY_BITS(t5, 26); + VERIFY_BITS(c, 39); + /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[6] + + (uint64_t)a[1] * b[5] + + (uint64_t)a[2] * b[4] + + (uint64_t)a[3] * b[3] + + (uint64_t)a[4] * b[2] + + (uint64_t)a[5] * b[1] + + (uint64_t)a[6] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[7] * b[9] + + (uint64_t)a[8] * b[8] + + (uint64_t)a[9] * b[7]; + VERIFY_BITS(d, 61); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + u6 = d & M; d >>= 26; c += u6 * R0; + VERIFY_BITS(u6, 26); + VERIFY_BITS(d, 35); + /* VERIFY_BITS(c, 64); */ + /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + t6 = c & M; c >>= 26; c += u6 * R1; + VERIFY_BITS(t6, 26); + VERIFY_BITS(c, 39); + /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[7] + + (uint64_t)a[1] * b[6] + + (uint64_t)a[2] * b[5] + + (uint64_t)a[3] * b[4] + + (uint64_t)a[4] * b[3] + + (uint64_t)a[5] * b[2] + + (uint64_t)a[6] * b[1] + + (uint64_t)a[7] * b[0]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x8000007C00000007ULL); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[8] * b[9] + + (uint64_t)a[9] * b[8]; + VERIFY_BITS(d, 58); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + u7 = d & M; d >>= 26; c += u7 * R0; + VERIFY_BITS(u7, 26); + VERIFY_BITS(d, 32); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); + /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + t7 = c & M; c >>= 26; c += u7 * R1; + VERIFY_BITS(t7, 26); + VERIFY_BITS(c, 38); + /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[8] + + (uint64_t)a[1] * b[7] + + (uint64_t)a[2] * b[6] + + (uint64_t)a[3] * b[5] + + (uint64_t)a[4] * b[4] + + (uint64_t)a[5] * b[3] + + (uint64_t)a[6] * b[2] + + (uint64_t)a[7] * b[1] + + (uint64_t)a[8] * b[0]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000007B80000008ULL); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[9] * b[9]; + VERIFY_BITS(d, 57); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + u8 = d & M; d >>= 26; c += u8 * R0; + VERIFY_BITS(u8, 26); + VERIFY_BITS(d, 31); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[3] = t3; + VERIFY_BITS(r[3], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = t4; + VERIFY_BITS(r[4], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[5] = t5; + VERIFY_BITS(r[5], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[6] = t6; + VERIFY_BITS(r[6], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[7] = t7; + VERIFY_BITS(r[7], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[8] = c & M; c >>= 26; c += u8 * R1; + VERIFY_BITS(r[8], 26); + VERIFY_BITS(c, 39); + /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += d * R0 + t9; + VERIFY_BITS(c, 45); + /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); + VERIFY_BITS(r[9], 22); + VERIFY_BITS(c, 46); + /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + d = c * (R0 >> 4) + t0; + VERIFY_BITS(d, 56); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[0] = d & M; d >>= 26; + VERIFY_BITS(r[0], 26); + VERIFY_BITS(d, 30); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += c * (R1 >> 4) + t1; + VERIFY_BITS(d, 53); + VERIFY_CHECK(d <= 0x10000003FFFFBFULL); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[1] = d & M; d >>= 26; + VERIFY_BITS(r[1], 26); + VERIFY_BITS(d, 27); + VERIFY_CHECK(d <= 0x4000000ULL); + /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += t2; + VERIFY_BITS(d, 27); + /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = d; + VERIFY_BITS(r[2], 27); + /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { + uint64_t c, d; + uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; + uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7; + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + + VERIFY_BITS(a[0], 30); + VERIFY_BITS(a[1], 30); + VERIFY_BITS(a[2], 30); + VERIFY_BITS(a[3], 30); + VERIFY_BITS(a[4], 30); + VERIFY_BITS(a[5], 30); + VERIFY_BITS(a[6], 30); + VERIFY_BITS(a[7], 30); + VERIFY_BITS(a[8], 30); + VERIFY_BITS(a[9], 26); + + /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. + * px is a shorthand for sum(a[i]*a[x-i], i=0..x). + * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. + */ + + d = (uint64_t)(a[0]*2) * a[9] + + (uint64_t)(a[1]*2) * a[8] + + (uint64_t)(a[2]*2) * a[7] + + (uint64_t)(a[3]*2) * a[6] + + (uint64_t)(a[4]*2) * a[5]; + /* VERIFY_BITS(d, 64); */ + /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + t9 = d & M; d >>= 26; + VERIFY_BITS(t9, 26); + VERIFY_BITS(d, 38); + /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + + c = (uint64_t)a[0] * a[0]; + VERIFY_BITS(c, 60); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ + d += (uint64_t)(a[1]*2) * a[9] + + (uint64_t)(a[2]*2) * a[8] + + (uint64_t)(a[3]*2) * a[7] + + (uint64_t)(a[4]*2) * a[6] + + (uint64_t)a[5] * a[5]; + VERIFY_BITS(d, 63); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + u0 = d & M; d >>= 26; c += u0 * R0; + VERIFY_BITS(u0, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 61); + /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + t0 = c & M; c >>= 26; c += u0 * R1; + VERIFY_BITS(t0, 26); + VERIFY_BITS(c, 37); + /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + + c += (uint64_t)(a[0]*2) * a[1]; + VERIFY_BITS(c, 62); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ + d += (uint64_t)(a[2]*2) * a[9] + + (uint64_t)(a[3]*2) * a[8] + + (uint64_t)(a[4]*2) * a[7] + + (uint64_t)(a[5]*2) * a[6]; + VERIFY_BITS(d, 63); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + u1 = d & M; d >>= 26; c += u1 * R0; + VERIFY_BITS(u1, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + t1 = c & M; c >>= 26; c += u1 * R1; + VERIFY_BITS(t1, 26); + VERIFY_BITS(c, 38); + /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[2] + + (uint64_t)a[1] * a[1]; + VERIFY_BITS(c, 62); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + d += (uint64_t)(a[3]*2) * a[9] + + (uint64_t)(a[4]*2) * a[8] + + (uint64_t)(a[5]*2) * a[7] + + (uint64_t)a[6] * a[6]; + VERIFY_BITS(d, 63); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + u2 = d & M; d >>= 26; c += u2 * R0; + VERIFY_BITS(u2, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + t2 = c & M; c >>= 26; c += u2 * R1; + VERIFY_BITS(t2, 26); + VERIFY_BITS(c, 38); + /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[3] + + (uint64_t)(a[1]*2) * a[2]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + d += (uint64_t)(a[4]*2) * a[9] + + (uint64_t)(a[5]*2) * a[8] + + (uint64_t)(a[6]*2) * a[7]; + VERIFY_BITS(d, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + u3 = d & M; d >>= 26; c += u3 * R0; + VERIFY_BITS(u3, 26); + VERIFY_BITS(d, 37); + /* VERIFY_BITS(c, 64); */ + /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + t3 = c & M; c >>= 26; c += u3 * R1; + VERIFY_BITS(t3, 26); + VERIFY_BITS(c, 39); + /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[4] + + (uint64_t)(a[1]*2) * a[3] + + (uint64_t)a[2] * a[2]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[5]*2) * a[9] + + (uint64_t)(a[6]*2) * a[8] + + (uint64_t)a[7] * a[7]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + u4 = d & M; d >>= 26; c += u4 * R0; + VERIFY_BITS(u4, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + t4 = c & M; c >>= 26; c += u4 * R1; + VERIFY_BITS(t4, 26); + VERIFY_BITS(c, 39); + /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[5] + + (uint64_t)(a[1]*2) * a[4] + + (uint64_t)(a[2]*2) * a[3]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[6]*2) * a[9] + + (uint64_t)(a[7]*2) * a[8]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + u5 = d & M; d >>= 26; c += u5 * R0; + VERIFY_BITS(u5, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + t5 = c & M; c >>= 26; c += u5 * R1; + VERIFY_BITS(t5, 26); + VERIFY_BITS(c, 39); + /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[6] + + (uint64_t)(a[1]*2) * a[5] + + (uint64_t)(a[2]*2) * a[4] + + (uint64_t)a[3] * a[3]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[7]*2) * a[9] + + (uint64_t)a[8] * a[8]; + VERIFY_BITS(d, 61); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + u6 = d & M; d >>= 26; c += u6 * R0; + VERIFY_BITS(u6, 26); + VERIFY_BITS(d, 35); + /* VERIFY_BITS(c, 64); */ + /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + t6 = c & M; c >>= 26; c += u6 * R1; + VERIFY_BITS(t6, 26); + VERIFY_BITS(c, 39); + /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[7] + + (uint64_t)(a[1]*2) * a[6] + + (uint64_t)(a[2]*2) * a[5] + + (uint64_t)(a[3]*2) * a[4]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x8000007C00000007ULL); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[8]*2) * a[9]; + VERIFY_BITS(d, 58); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + u7 = d & M; d >>= 26; c += u7 * R0; + VERIFY_BITS(u7, 26); + VERIFY_BITS(d, 32); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); + /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + t7 = c & M; c >>= 26; c += u7 * R1; + VERIFY_BITS(t7, 26); + VERIFY_BITS(c, 38); + /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[8] + + (uint64_t)(a[1]*2) * a[7] + + (uint64_t)(a[2]*2) * a[6] + + (uint64_t)(a[3]*2) * a[5] + + (uint64_t)a[4] * a[4]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000007B80000008ULL); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[9] * a[9]; + VERIFY_BITS(d, 57); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + u8 = d & M; d >>= 26; c += u8 * R0; + VERIFY_BITS(u8, 26); + VERIFY_BITS(d, 31); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[3] = t3; + VERIFY_BITS(r[3], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = t4; + VERIFY_BITS(r[4], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[5] = t5; + VERIFY_BITS(r[5], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[6] = t6; + VERIFY_BITS(r[6], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[7] = t7; + VERIFY_BITS(r[7], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[8] = c & M; c >>= 26; c += u8 * R1; + VERIFY_BITS(r[8], 26); + VERIFY_BITS(c, 39); + /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += d * R0 + t9; + VERIFY_BITS(c, 45); + /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); + VERIFY_BITS(r[9], 22); + VERIFY_BITS(c, 46); + /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + d = c * (R0 >> 4) + t0; + VERIFY_BITS(d, 56); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[0] = d & M; d >>= 26; + VERIFY_BITS(r[0], 26); + VERIFY_BITS(d, 30); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += c * (R1 >> 4) + t1; + VERIFY_BITS(d, 53); + VERIFY_CHECK(d <= 0x10000003FFFFBFULL); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[1] = d & M; d >>= 26; + VERIFY_BITS(r[1], 26); + VERIFY_BITS(d, 27); + VERIFY_CHECK(d <= 0x4000000ULL); + /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += t2; + VERIFY_BITS(d, 27); + /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = d; + VERIFY_BITS(r[2], 27); + /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} +#endif + +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); + VERIFY_CHECK(r != b); + VERIFY_CHECK(a != b); +#endif + secp256k1_fe_mul_inner(r->n, a->n, b->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + secp256k1_fe_verify(a); +#endif + secp256k1_fe_sqr_inner(r->n, a->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { + uint32_t mask0, mask1; + VG_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); + r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); + r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); + r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); + r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); + r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); + r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); +#ifdef VERIFY + if (flag) { + r->magnitude = a->magnitude; + r->normalized = a->normalized; + } +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + uint32_t one = (uint32_t)1; + uint32_t mask = -(t0 & one) >> 6; + +#ifdef VERIFY + secp256k1_fe_verify(r); + VERIFY_CHECK(r->magnitude < 32); +#endif + + /* Bounds analysis (over the rationals). + * + * Let m = r->magnitude + * C = 0x3FFFFFFUL * 2 + * D = 0x03FFFFFUL * 2 + * + * Initial bounds: t0..t8 <= C * m + * t9 <= D * m + */ + + t0 += 0x3FFFC2FUL & mask; + t1 += 0x3FFFFBFUL & mask; + t2 += mask; + t3 += mask; + t4 += mask; + t5 += mask; + t6 += mask; + t7 += mask; + t8 += mask; + t9 += mask >> 4; + + VERIFY_CHECK((t0 & one) == 0); + + /* t0..t8: added <= C/2 + * t9: added <= D/2 + * + * Current bounds: t0..t8 <= C * (m + 1/2) + * t9 <= D * (m + 1/2) + */ + + r->n[0] = (t0 >> 1) + ((t1 & one) << 25); + r->n[1] = (t1 >> 1) + ((t2 & one) << 25); + r->n[2] = (t2 >> 1) + ((t3 & one) << 25); + r->n[3] = (t3 >> 1) + ((t4 & one) << 25); + r->n[4] = (t4 >> 1) + ((t5 & one) << 25); + r->n[5] = (t5 >> 1) + ((t6 & one) << 25); + r->n[6] = (t6 >> 1) + ((t7 & one) << 25); + r->n[7] = (t7 >> 1) + ((t8 & one) << 25); + r->n[8] = (t8 >> 1) + ((t9 & one) << 25); + r->n[9] = (t9 >> 1); + + /* t0..t8: shifted right and added <= C/4 + 1/2 + * t9: shifted right + * + * Current bounds: t0..t8 <= C * (m/2 + 1/2) + * t9 <= D * (m/2 + 1/4) + */ + +#ifdef VERIFY + /* Therefore the output magnitude (M) has to be set such that: + * t0..t8: C * M >= C * (m/2 + 1/2) + * t9: D * M >= D * (m/2 + 1/4) + * + * It suffices for all limbs that, for any input magnitude m: + * M >= m/2 + 1/2 + * + * and since we want the smallest such integer value for M: + * M == floor(m/2) + 1 + */ + r->magnitude = (r->magnitude >> 1) + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { + uint32_t mask0, mask1; + VG_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); + r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); + r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); + r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); + r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); +} + +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); +#endif + r->n[0] = a->n[0] | a->n[1] << 26; + r->n[1] = a->n[1] >> 6 | a->n[2] << 20; + r->n[2] = a->n[2] >> 12 | a->n[3] << 14; + r->n[3] = a->n[3] >> 18 | a->n[4] << 8; + r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28; + r->n[5] = a->n[6] >> 4 | a->n[7] << 22; + r->n[6] = a->n[7] >> 10 | a->n[8] << 16; + r->n[7] = a->n[8] >> 16 | a->n[9] << 10; +} + +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { + r->n[0] = a->n[0] & 0x3FFFFFFUL; + r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); + r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); + r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL); + r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL); + r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL; + r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL); + r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); + r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); + r->n[9] = a->n[7] >> 10; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_from_signed30(secp256k1_fe *r, const secp256k1_modinv32_signed30 *a) { + const uint32_t M26 = UINT32_MAX >> 6; + const uint32_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4], + a5 = a->v[5], a6 = a->v[6], a7 = a->v[7], a8 = a->v[8]; + + /* The output from secp256k1_modinv32{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^30). The modulus is < 2^256, so the top limb must be below 2^(256-30*8). + */ + VERIFY_CHECK(a0 >> 30 == 0); + VERIFY_CHECK(a1 >> 30 == 0); + VERIFY_CHECK(a2 >> 30 == 0); + VERIFY_CHECK(a3 >> 30 == 0); + VERIFY_CHECK(a4 >> 30 == 0); + VERIFY_CHECK(a5 >> 30 == 0); + VERIFY_CHECK(a6 >> 30 == 0); + VERIFY_CHECK(a7 >> 30 == 0); + VERIFY_CHECK(a8 >> 16 == 0); + + r->n[0] = a0 & M26; + r->n[1] = (a0 >> 26 | a1 << 4) & M26; + r->n[2] = (a1 >> 22 | a2 << 8) & M26; + r->n[3] = (a2 >> 18 | a3 << 12) & M26; + r->n[4] = (a3 >> 14 | a4 << 16) & M26; + r->n[5] = (a4 >> 10 | a5 << 20) & M26; + r->n[6] = (a5 >> 6 | a6 << 24) & M26; + r->n[7] = (a6 >> 2 ) & M26; + r->n[8] = (a6 >> 28 | a7 << 2) & M26; + r->n[9] = (a7 >> 24 | a8 << 6); + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_fe *a) { + const uint32_t M30 = UINT32_MAX >> 2; + const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4], + a5 = a->n[5], a6 = a->n[6], a7 = a->n[7], a8 = a->n[8], a9 = a->n[9]; + +#ifdef VERIFY + VERIFY_CHECK(a->normalized); +#endif + + r->v[0] = (a0 | a1 << 26) & M30; + r->v[1] = (a1 >> 4 | a2 << 22) & M30; + r->v[2] = (a2 >> 8 | a3 << 18) & M30; + r->v[3] = (a3 >> 12 | a4 << 14) & M30; + r->v[4] = (a4 >> 16 | a5 << 10) & M30; + r->v[5] = (a5 >> 20 | a6 << 6) & M30; + r->v[6] = (a6 >> 24 | a7 << 2 + | a8 << 28) & M30; + r->v[7] = (a8 >> 2 | a9 << 24) & M30; + r->v[8] = a9 >> 6; +} + +static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_fe = { + {{-0x3D1, -4, 0, 0, 0, 0, 0, 0, 65536}}, + 0x2DDACACFL +}; + +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv32_signed30 s; + + tmp = *x; + secp256k1_fe_normalize(&tmp); + secp256k1_fe_to_signed30(&s, &tmp); + secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed30(r, &s); + + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); +} + +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv32_signed30 s; + + tmp = *x; + secp256k1_fe_normalize_var(&tmp); + secp256k1_fe_to_signed30(&s, &tmp); + secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed30(r, &s); + + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); +} + +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52.h new file mode 100644 index 00000000..50ee3f9e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52.h @@ -0,0 +1,55 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H + +#include + +typedef struct { + /* X = sum(i=0..4, n[i]*2^(i*52)) mod p + * where p = 2^256 - 0x1000003D1 + */ + uint64_t n[5]; +#ifdef VERIFY + int magnitude; + int normalized; +#endif +} secp256k1_fe; + +/* Unpacks a constant into a overlapping multi-limbed FE element. */ +#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ + (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ + ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ + ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ + ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ + ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ +} + +#ifdef VERIFY +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} +#else +#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} +#endif + +typedef struct { + uint64_t n[4]; +} secp256k1_fe_storage; + +#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ + (d0) | (((uint64_t)(d1)) << 32), \ + (d2) | (((uint64_t)(d3)) << 32), \ + (d4) | (((uint64_t)(d5)) << 32), \ + (d6) | (((uint64_t)(d7)) << 32) \ +}} + +#define SECP256K1_FE_STORAGE_CONST_GET(d) \ + (uint32_t)(d.n[3] >> 32), (uint32_t)d.n[3], \ + (uint32_t)(d.n[2] >> 32), (uint32_t)d.n[2], \ + (uint32_t)(d.n[1] >> 32), (uint32_t)d.n[1], \ + (uint32_t)(d.n[0] >> 32), (uint32_t)d.n[0] + +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_asm_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_asm_impl.h new file mode 100644 index 00000000..a2118044 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_asm_impl.h @@ -0,0 +1,502 @@ +/*********************************************************************** + * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +/** + * Changelog: + * - March 2013, Diederik Huys: original version + * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm + * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly + */ + +#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H +#define SECP256K1_FIELD_INNER5X52_IMPL_H + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * r15:rcx = d + * r10-r14 = a0-a4 + * rbx = b + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + + /* d += a3 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rcx\n" + "movq %%rdx,%%r15\n" + /* d += a2 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d = a0 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c = a4 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* d += a4 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a0 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* t4 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a4 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* u0 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a1 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a4 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a2 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a1 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b2 (last use of %%r10 = a0) */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* d += a4 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rcx only) */ + "shrdq $52,%%r15,%%rcx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rcx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "b"(b), "D"(r) +: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * rcx:rbx = d + * r10-r14 = a0-a4 + * r15 = M (0xfffffffffffff) + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + "movq $0xfffffffffffff,%%r15\n" + + /* d = (a0*2) * a3 */ + "leaq (%%r10,%%r10,1),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rbx\n" + "movq %%rdx,%%rcx\n" + /* d += (a1*2) * a2 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c = a4 * a4 */ + "movq %%r14,%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* a4 *= 2 */ + "addq %%r14,%%r14\n" + /* d += a0 * a4 */ + "movq %%r10,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d+= (a1*2) * a3 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a2 * a2 */ + "movq %%r12,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* t4 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * a0 */ + "movq %%r10,%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a1 * a4 */ + "movq %%r11,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += (a2*2) * a3 */ + "leaq (%%r12,%%r12,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* u0 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* a0 *= 2 */ + "addq %%r10,%%r10\n" + /* c += a0 * a1 */ + "movq %%r10,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a2 * a4 */ + "movq %%r12,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a3 * a3 */ + "movq %%r13,%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a0 * a2 (last use of %%r10) */ + "movq %%r10,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* c += a1 * a1 */ + "movq %%r11,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a3 * a4 */ + "movq %%r13,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rbx only) */ + "shrdq $52,%%rcx,%%rbx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rbx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "D"(r) +: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} + +#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_impl.h new file mode 100644 index 00000000..6bd202f5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_impl.h @@ -0,0 +1,670 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" +#include "field.h" +#include "modinv64_impl.h" + +#if defined(USE_ASM_X86_64) +#include "field_5x52_asm_impl.h" +#else +#include "field_5x52_int128_impl.h" +#endif + +/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, + * represented as 5 uint64_t's in base 2^52, least significant first. Note that the limbs are allowed to + * contain >52 bits each. + * + * Each field element has a 'magnitude' associated with it. Internally, a magnitude M means: + * - 2*M*(2^48-1) is the max (inclusive) of the most significant limb + * - 2*M*(2^52-1) is the max (inclusive) of the remaining limbs + * + * Operations have different rules for propagating magnitude to their outputs. If an operation takes a + * magnitude M as a parameter, that means the magnitude of input field elements can be at most M (inclusive). + * + * Each field element also has a 'normalized' flag. A field element is normalized if its magnitude is either + * 0 or 1, and its value is already reduced modulo the order of the field. + */ + +#ifdef VERIFY +static void secp256k1_fe_verify(const secp256k1_fe *a) { + const uint64_t *d = a->n; + int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ + r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m); + r &= (a->magnitude >= 0); + r &= (a->magnitude <= 2048); + if (a->normalized) { + r &= (a->magnitude <= 1); + if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { + r &= (d[0] < 0xFFFFEFFFFFC2FULL); + } + } + VERIFY_CHECK(r == 1); +} +#endif + +static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m) { + VERIFY_CHECK(m >= 0); + VERIFY_CHECK(m <= 2048); + r->n[0] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * m; + r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * m; +#ifdef VERIFY + r->magnitude = m; + r->normalized = (m == 0); + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize(secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t m; + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) + & (t0 >= 0xFFFFEFFFFFC2FULL)); + + /* Apply the final reduction (for constant-time behaviour, we do it always) */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ + VERIFY_CHECK(t4 >> 48 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t4 &= 0x0FFFFFFFFFFFFULL; + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_var(secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t m; + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) + & (t0 >= 0xFFFFEFFFFFC2FULL)); + + if (x) { + t0 += 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ + VERIFY_CHECK(t4 >> 48 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t4 &= 0x0FFFFFFFFFFFFULL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static int secp256k1_fe_normalizes_to_zero(const secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + uint64_t z0, z1; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; + z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); +} + +static int secp256k1_fe_normalizes_to_zero_var(const secp256k1_fe *r) { + uint64_t t0, t1, t2, t3, t4; + uint64_t z0, z1; + uint64_t x; + + t0 = r->n[0]; + t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + x = t4 >> 48; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + + /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ + z0 = t0 & 0xFFFFFFFFFFFFFULL; + z1 = z0 ^ 0x1000003D0ULL; + + /* Fast return path should catch the majority of cases */ + if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) { + return 0; + } + + t1 = r->n[1]; + t2 = r->n[2]; + t3 = r->n[3]; + + t4 &= 0x0FFFFFFFFFFFFULL; + + t1 += (t0 >> 52); + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; + z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); +} + +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { + VERIFY_CHECK(0 <= a && a <= 0x7FFF); + r->n[0] = a; + r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; +#ifdef VERIFY + r->magnitude = (a != 0); + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { + const uint64_t *t = a->n; +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; +} + +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return a->n[0] & 1; +} + +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { + int i; +#ifdef VERIFY + a->magnitude = 0; + a->normalized = 1; +#endif + for (i=0; i<5; i++) { + a->n[i] = 0; + } +} + +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { + int i; +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (i = 4; i >= 0; i--) { + if (a->n[i] > b->n[i]) { + return 1; + } + if (a->n[i] < b->n[i]) { + return -1; + } + } + return 0; +} + +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { + int ret; + r->n[0] = (uint64_t)a[31] + | ((uint64_t)a[30] << 8) + | ((uint64_t)a[29] << 16) + | ((uint64_t)a[28] << 24) + | ((uint64_t)a[27] << 32) + | ((uint64_t)a[26] << 40) + | ((uint64_t)(a[25] & 0xF) << 48); + r->n[1] = (uint64_t)((a[25] >> 4) & 0xF) + | ((uint64_t)a[24] << 4) + | ((uint64_t)a[23] << 12) + | ((uint64_t)a[22] << 20) + | ((uint64_t)a[21] << 28) + | ((uint64_t)a[20] << 36) + | ((uint64_t)a[19] << 44); + r->n[2] = (uint64_t)a[18] + | ((uint64_t)a[17] << 8) + | ((uint64_t)a[16] << 16) + | ((uint64_t)a[15] << 24) + | ((uint64_t)a[14] << 32) + | ((uint64_t)a[13] << 40) + | ((uint64_t)(a[12] & 0xF) << 48); + r->n[3] = (uint64_t)((a[12] >> 4) & 0xF) + | ((uint64_t)a[11] << 4) + | ((uint64_t)a[10] << 12) + | ((uint64_t)a[9] << 20) + | ((uint64_t)a[8] << 28) + | ((uint64_t)a[7] << 36) + | ((uint64_t)a[6] << 44); + r->n[4] = (uint64_t)a[5] + | ((uint64_t)a[4] << 8) + | ((uint64_t)a[3] << 16) + | ((uint64_t)a[2] << 24) + | ((uint64_t)a[1] << 32) + | ((uint64_t)a[0] << 40); + ret = !((r->n[4] == 0x0FFFFFFFFFFFFULL) & ((r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL) & (r->n[0] >= 0xFFFFEFFFFFC2FULL)); +#ifdef VERIFY + r->magnitude = 1; + if (ret) { + r->normalized = 1; + secp256k1_fe_verify(r); + } else { + r->normalized = 0; + } +#endif + return ret; +} + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + r[0] = (a->n[4] >> 40) & 0xFF; + r[1] = (a->n[4] >> 32) & 0xFF; + r[2] = (a->n[4] >> 24) & 0xFF; + r[3] = (a->n[4] >> 16) & 0xFF; + r[4] = (a->n[4] >> 8) & 0xFF; + r[5] = a->n[4] & 0xFF; + r[6] = (a->n[3] >> 44) & 0xFF; + r[7] = (a->n[3] >> 36) & 0xFF; + r[8] = (a->n[3] >> 28) & 0xFF; + r[9] = (a->n[3] >> 20) & 0xFF; + r[10] = (a->n[3] >> 12) & 0xFF; + r[11] = (a->n[3] >> 4) & 0xFF; + r[12] = ((a->n[2] >> 48) & 0xF) | ((a->n[3] & 0xF) << 4); + r[13] = (a->n[2] >> 40) & 0xFF; + r[14] = (a->n[2] >> 32) & 0xFF; + r[15] = (a->n[2] >> 24) & 0xFF; + r[16] = (a->n[2] >> 16) & 0xFF; + r[17] = (a->n[2] >> 8) & 0xFF; + r[18] = a->n[2] & 0xFF; + r[19] = (a->n[1] >> 44) & 0xFF; + r[20] = (a->n[1] >> 36) & 0xFF; + r[21] = (a->n[1] >> 28) & 0xFF; + r[22] = (a->n[1] >> 20) & 0xFF; + r[23] = (a->n[1] >> 12) & 0xFF; + r[24] = (a->n[1] >> 4) & 0xFF; + r[25] = ((a->n[0] >> 48) & 0xF) | ((a->n[1] & 0xF) << 4); + r[26] = (a->n[0] >> 40) & 0xFF; + r[27] = (a->n[0] >> 32) & 0xFF; + r[28] = (a->n[0] >> 24) & 0xFF; + r[29] = (a->n[0] >> 16) & 0xFF; + r[30] = (a->n[0] >> 8) & 0xFF; + r[31] = a->n[0] & 0xFF; +} + +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= m); + secp256k1_fe_verify(a); + VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); + VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); + VERIFY_CHECK(0x0FFFFFFFFFFFFULL * 2 * (m + 1) >= 0x0FFFFFFFFFFFFULL * 2 * m); +#endif + r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0]; + r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1]; + r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2]; + r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3]; + r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; +#ifdef VERIFY + r->magnitude = m + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { + r->n[0] *= a; + r->n[1] *= a; + r->n[2] *= a; + r->n[3] *= a; + r->n[4] *= a; +#ifdef VERIFY + r->magnitude *= a; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { +#ifdef VERIFY + secp256k1_fe_verify(a); +#endif + r->n[0] += a->n[0]; + r->n[1] += a->n[1]; + r->n[2] += a->n[2]; + r->n[3] += a->n[3]; + r->n[4] += a->n[4]; +#ifdef VERIFY + r->magnitude += a->magnitude; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); + VERIFY_CHECK(r != b); + VERIFY_CHECK(a != b); +#endif + secp256k1_fe_mul_inner(r->n, a->n, b->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + secp256k1_fe_verify(a); +#endif + secp256k1_fe_sqr_inner(r->n, a->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { + uint64_t mask0, mask1; + VG_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = flag + ~((uint64_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); + r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); +#ifdef VERIFY + if (flag) { + r->magnitude = a->magnitude; + r->normalized = a->normalized; + } +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + uint64_t one = (uint64_t)1; + uint64_t mask = -(t0 & one) >> 12; + +#ifdef VERIFY + secp256k1_fe_verify(r); + VERIFY_CHECK(r->magnitude < 32); +#endif + + /* Bounds analysis (over the rationals). + * + * Let m = r->magnitude + * C = 0xFFFFFFFFFFFFFULL * 2 + * D = 0x0FFFFFFFFFFFFULL * 2 + * + * Initial bounds: t0..t3 <= C * m + * t4 <= D * m + */ + + t0 += 0xFFFFEFFFFFC2FULL & mask; + t1 += mask; + t2 += mask; + t3 += mask; + t4 += mask >> 4; + + VERIFY_CHECK((t0 & one) == 0); + + /* t0..t3: added <= C/2 + * t4: added <= D/2 + * + * Current bounds: t0..t3 <= C * (m + 1/2) + * t4 <= D * (m + 1/2) + */ + + r->n[0] = (t0 >> 1) + ((t1 & one) << 51); + r->n[1] = (t1 >> 1) + ((t2 & one) << 51); + r->n[2] = (t2 >> 1) + ((t3 & one) << 51); + r->n[3] = (t3 >> 1) + ((t4 & one) << 51); + r->n[4] = (t4 >> 1); + + /* t0..t3: shifted right and added <= C/4 + 1/2 + * t4: shifted right + * + * Current bounds: t0..t3 <= C * (m/2 + 1/2) + * t4 <= D * (m/2 + 1/4) + */ + +#ifdef VERIFY + /* Therefore the output magnitude (M) has to be set such that: + * t0..t3: C * M >= C * (m/2 + 1/2) + * t4: D * M >= D * (m/2 + 1/4) + * + * It suffices for all limbs that, for any input magnitude m: + * M >= m/2 + 1/2 + * + * and since we want the smallest such integer value for M: + * M == floor(m/2) + 1 + */ + r->magnitude = (r->magnitude >> 1) + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { + uint64_t mask0, mask1; + VG_CHECK_VERIFY(r->n, sizeof(r->n)); + mask0 = flag + ~((uint64_t)0); + mask1 = ~mask0; + r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); + r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); + r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); + r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); +} + +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); +#endif + r->n[0] = a->n[0] | a->n[1] << 52; + r->n[1] = a->n[1] >> 12 | a->n[2] << 40; + r->n[2] = a->n[2] >> 24 | a->n[3] << 28; + r->n[3] = a->n[3] >> 36 | a->n[4] << 16; +} + +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { + r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; + r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); + r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); + r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL); + r->n[4] = a->n[3] >> 16; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_from_signed62(secp256k1_fe *r, const secp256k1_modinv64_signed62 *a) { + const uint64_t M52 = UINT64_MAX >> 12; + const uint64_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4]; + + /* The output from secp256k1_modinv64{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^62). The modulus is < 2^256, so the top limb must be below 2^(256-62*4). + */ + VERIFY_CHECK(a0 >> 62 == 0); + VERIFY_CHECK(a1 >> 62 == 0); + VERIFY_CHECK(a2 >> 62 == 0); + VERIFY_CHECK(a3 >> 62 == 0); + VERIFY_CHECK(a4 >> 8 == 0); + + r->n[0] = a0 & M52; + r->n[1] = (a0 >> 52 | a1 << 10) & M52; + r->n[2] = (a1 >> 42 | a2 << 20) & M52; + r->n[3] = (a2 >> 32 | a3 << 30) & M52; + r->n[4] = (a3 >> 22 | a4 << 40); + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_fe *a) { + const uint64_t M62 = UINT64_MAX >> 2; + const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4]; + +#ifdef VERIFY + VERIFY_CHECK(a->normalized); +#endif + + r->v[0] = (a0 | a1 << 52) & M62; + r->v[1] = (a1 >> 10 | a2 << 42) & M62; + r->v[2] = (a2 >> 20 | a3 << 32) & M62; + r->v[3] = (a3 >> 30 | a4 << 22) & M62; + r->v[4] = a4 >> 40; +} + +static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_fe = { + {{-0x1000003D1LL, 0, 0, 0, 256}}, + 0x27C7F6E22DDACACFLL +}; + +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv64_signed62 s; + + tmp = *x; + secp256k1_fe_normalize(&tmp); + secp256k1_fe_to_signed62(&s, &tmp); + secp256k1_modinv64(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed62(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); +#endif +} + +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp; + secp256k1_modinv64_signed62 s; + + tmp = *x; + secp256k1_fe_normalize_var(&tmp); + secp256k1_fe_to_signed62(&s, &tmp); + secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_fe); + secp256k1_fe_from_signed62(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); +#endif +} + +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_int128_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_int128_impl.h new file mode 100644 index 00000000..0ed6118c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_5x52_int128_impl.h @@ -0,0 +1,278 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H +#define SECP256K1_FIELD_INNER5X52_IMPL_H + +#include + +#ifdef VERIFY +#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) +#else +#define VERIFY_BITS(x, n) do { } while(0) +#endif + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { + uint128_t c, d; + uint64_t t3, t4, tx, u0; + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + + VERIFY_BITS(a[0], 56); + VERIFY_BITS(a[1], 56); + VERIFY_BITS(a[2], 56); + VERIFY_BITS(a[3], 56); + VERIFY_BITS(a[4], 52); + VERIFY_BITS(b[0], 56); + VERIFY_BITS(b[1], 56); + VERIFY_BITS(b[2], 56); + VERIFY_BITS(b[3], 56); + VERIFY_BITS(b[4], 52); + VERIFY_CHECK(r != b); + VERIFY_CHECK(a != b); + + /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. + * for 0 <= x <= 4, px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * for 4 <= x <= 8, px is a shorthand for sum(a[i]*b[x-i], i=(x-4)..4) + * Note that [x 0 0 0 0 0] = [x*R]. + */ + + d = (uint128_t)a0 * b[3] + + (uint128_t)a1 * b[2] + + (uint128_t)a2 * b[1] + + (uint128_t)a3 * b[0]; + VERIFY_BITS(d, 114); + /* [d 0 0 0] = [p3 0 0 0] */ + c = (uint128_t)a4 * b[4]; + VERIFY_BITS(c, 112); + /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + d += (uint128_t)R * (uint64_t)c; c >>= 64; + VERIFY_BITS(d, 115); + VERIFY_BITS(c, 48); + /* [(c<<12) 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + t3 = d & M; d >>= 52; + VERIFY_BITS(t3, 52); + VERIFY_BITS(d, 63); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + + d += (uint128_t)a0 * b[4] + + (uint128_t)a1 * b[3] + + (uint128_t)a2 * b[2] + + (uint128_t)a3 * b[1] + + (uint128_t)a4 * b[0]; + VERIFY_BITS(d, 115); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + d += (uint128_t)(R << 12) * (uint64_t)c; + VERIFY_BITS(d, 116); + /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + t4 = d & M; d >>= 52; + VERIFY_BITS(t4, 52); + VERIFY_BITS(d, 64); + /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + tx = (t4 >> 48); t4 &= (M >> 4); + VERIFY_BITS(tx, 4); + VERIFY_BITS(t4, 48); + /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + + c = (uint128_t)a0 * b[0]; + VERIFY_BITS(c, 112); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ + d += (uint128_t)a1 * b[4] + + (uint128_t)a2 * b[3] + + (uint128_t)a3 * b[2] + + (uint128_t)a4 * b[1]; + VERIFY_BITS(d, 115); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = d & M; d >>= 52; + VERIFY_BITS(u0, 52); + VERIFY_BITS(d, 63); + /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = (u0 << 4) | tx; + VERIFY_BITS(u0, 56); + /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + c += (uint128_t)u0 * (R >> 4); + VERIFY_BITS(c, 115); + /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + r[0] = c & M; c >>= 52; + VERIFY_BITS(r[0], 52); + VERIFY_BITS(c, 61); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ + + c += (uint128_t)a0 * b[1] + + (uint128_t)a1 * b[0]; + VERIFY_BITS(c, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ + d += (uint128_t)a2 * b[4] + + (uint128_t)a3 * b[3] + + (uint128_t)a4 * b[2]; + VERIFY_BITS(d, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + r[1] = c & M; c >>= 52; + VERIFY_BITS(r[1], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + + c += (uint128_t)a0 * b[2] + + (uint128_t)a1 * b[1] + + (uint128_t)a2 * b[0]; + VERIFY_BITS(c, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint128_t)a3 * b[4] + + (uint128_t)a4 * b[3]; + VERIFY_BITS(d, 114); + /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += (uint128_t)R * (uint64_t)d; d >>= 64; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 50); + /* [(d<<12) 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[2] = c & M; c >>= 52; + VERIFY_BITS(r[2], 52); + VERIFY_BITS(c, 63); + /* [(d<<12) 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += (uint128_t)(R << 12) * (uint64_t)d + t3; + VERIFY_BITS(c, 100); + /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[3] = c & M; c >>= 52; + VERIFY_BITS(r[3], 52); + VERIFY_BITS(c, 48); + /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += t4; + VERIFY_BITS(c, 49); + /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = c; + VERIFY_BITS(r[4], 49); + /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { + uint128_t c, d; + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + int64_t t3, t4, tx, u0; + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + + VERIFY_BITS(a[0], 56); + VERIFY_BITS(a[1], 56); + VERIFY_BITS(a[2], 56); + VERIFY_BITS(a[3], 56); + VERIFY_BITS(a[4], 52); + + /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. + * px is a shorthand for sum(a[i]*a[x-i], i=0..x). + * Note that [x 0 0 0 0 0] = [x*R]. + */ + + d = (uint128_t)(a0*2) * a3 + + (uint128_t)(a1*2) * a2; + VERIFY_BITS(d, 114); + /* [d 0 0 0] = [p3 0 0 0] */ + c = (uint128_t)a4 * a4; + VERIFY_BITS(c, 112); + /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + d += (uint128_t)R * (uint64_t)c; c >>= 64; + VERIFY_BITS(d, 115); + VERIFY_BITS(c, 48); + /* [(c<<12) 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + t3 = d & M; d >>= 52; + VERIFY_BITS(t3, 52); + VERIFY_BITS(d, 63); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + + a4 *= 2; + d += (uint128_t)a0 * a4 + + (uint128_t)(a1*2) * a3 + + (uint128_t)a2 * a2; + VERIFY_BITS(d, 115); + /* [(c<<12) 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + d += (uint128_t)(R << 12) * (uint64_t)c; + VERIFY_BITS(d, 116); + /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + t4 = d & M; d >>= 52; + VERIFY_BITS(t4, 52); + VERIFY_BITS(d, 64); + /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + tx = (t4 >> 48); t4 &= (M >> 4); + VERIFY_BITS(tx, 4); + VERIFY_BITS(t4, 48); + /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + + c = (uint128_t)a0 * a0; + VERIFY_BITS(c, 112); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ + d += (uint128_t)a1 * a4 + + (uint128_t)(a2*2) * a3; + VERIFY_BITS(d, 114); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = d & M; d >>= 52; + VERIFY_BITS(u0, 52); + VERIFY_BITS(d, 62); + /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = (u0 << 4) | tx; + VERIFY_BITS(u0, 56); + /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + c += (uint128_t)u0 * (R >> 4); + VERIFY_BITS(c, 113); + /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + r[0] = c & M; c >>= 52; + VERIFY_BITS(r[0], 52); + VERIFY_BITS(c, 61); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ + + a0 *= 2; + c += (uint128_t)a0 * a1; + VERIFY_BITS(c, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ + d += (uint128_t)a2 * a4 + + (uint128_t)a3 * a3; + VERIFY_BITS(d, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + r[1] = c & M; c >>= 52; + VERIFY_BITS(r[1], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + + c += (uint128_t)a0 * a2 + + (uint128_t)a1 * a1; + VERIFY_BITS(c, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint128_t)a3 * a4; + VERIFY_BITS(d, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += (uint128_t)R * (uint64_t)d; d >>= 64; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 50); + /* [(d<<12) 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = c & M; c >>= 52; + VERIFY_BITS(r[2], 52); + VERIFY_BITS(c, 63); + /* [(d<<12) 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint128_t)(R << 12) * (uint64_t)d + t3; + VERIFY_BITS(c, 100); + /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[3] = c & M; c >>= 52; + VERIFY_BITS(r[3], 52); + VERIFY_BITS(c, 48); + /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += t4; + VERIFY_BITS(c, 49); + /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = c; + VERIFY_BITS(r[4], 49); + /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_impl.h new file mode 100644 index 00000000..0a4a04d9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/field_impl.h @@ -0,0 +1,138 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_FIELD_IMPL_H +#define SECP256K1_FIELD_IMPL_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" + +#if defined(SECP256K1_WIDEMUL_INT128) +#include "field_5x52_impl.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "field_10x26_impl.h" +#else +#error "Please select wide multiplication implementation" +#endif + +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero(&na); +} + +SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero_var(&na); +} + +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { + /** Given that p is congruent to 3 mod 4, we can compute the square root of + * a mod p as the (p+1)/4'th power of a. + * + * As (p+1)/4 is an even number, it will have the same result for a and for + * (-a). Only one of these two numbers actually has a square root however, + * so we test at the end by squaring and comparing to the input. + * Also because (p+1)/4 is an even number, the computed square root is + * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). + */ + secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; + int j; + + VERIFY_CHECK(r != a); + + /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in + * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: + * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + */ + + secp256k1_fe_sqr(&x2, a); + secp256k1_fe_mul(&x2, &x2, a); + + secp256k1_fe_sqr(&x3, &x2); + secp256k1_fe_mul(&x3, &x3, a); + + x6 = x3; + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x6, &x6); + } + secp256k1_fe_mul(&x6, &x6, &x3); + + x9 = x6; + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x9, &x9); + } + secp256k1_fe_mul(&x9, &x9, &x3); + + x11 = x9; + for (j=0; j<2; j++) { + secp256k1_fe_sqr(&x11, &x11); + } + secp256k1_fe_mul(&x11, &x11, &x2); + + x22 = x11; + for (j=0; j<11; j++) { + secp256k1_fe_sqr(&x22, &x22); + } + secp256k1_fe_mul(&x22, &x22, &x11); + + x44 = x22; + for (j=0; j<22; j++) { + secp256k1_fe_sqr(&x44, &x44); + } + secp256k1_fe_mul(&x44, &x44, &x22); + + x88 = x44; + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x88, &x88); + } + secp256k1_fe_mul(&x88, &x88, &x44); + + x176 = x88; + for (j=0; j<88; j++) { + secp256k1_fe_sqr(&x176, &x176); + } + secp256k1_fe_mul(&x176, &x176, &x88); + + x220 = x176; + for (j=0; j<44; j++) { + secp256k1_fe_sqr(&x220, &x220); + } + secp256k1_fe_mul(&x220, &x220, &x44); + + x223 = x220; + for (j=0; j<3; j++) { + secp256k1_fe_sqr(&x223, &x223); + } + secp256k1_fe_mul(&x223, &x223, &x3); + + /* The final result is then assembled using a sliding window over the blocks. */ + + t1 = x223; + for (j=0; j<23; j++) { + secp256k1_fe_sqr(&t1, &t1); + } + secp256k1_fe_mul(&t1, &t1, &x22); + for (j=0; j<6; j++) { + secp256k1_fe_sqr(&t1, &t1); + } + secp256k1_fe_mul(&t1, &t1, &x2); + secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_sqr(r, &t1); + + /* Check that a square root was actually calculated */ + + secp256k1_fe_sqr(&t1, r); + return secp256k1_fe_equal(&t1, a); +} + +#endif /* SECP256K1_FIELD_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group.h new file mode 100644 index 00000000..bb7dae1c --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group.h @@ -0,0 +1,164 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_GROUP_H +#define SECP256K1_GROUP_H + +#include "field.h" + +/** A group element in affine coordinates on the secp256k1 curve, + * or occasionally on an isomorphic curve of the form y^2 = x^3 + 7*t^6. + * Note: For exhaustive test mode, secp256k1 is replaced by a small subgroup of a different curve. + */ +typedef struct { + secp256k1_fe x; + secp256k1_fe y; + int infinity; /* whether this represents the point at infinity */ +} secp256k1_ge; + +#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} +#define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} + +/** A group element of the secp256k1 curve, in jacobian coordinates. + * Note: For exhastive test mode, sepc256k1 is replaced by a small subgroup of a different curve. + */ +typedef struct { + secp256k1_fe x; /* actual X: x/z^2 */ + secp256k1_fe y; /* actual Y: y/z^3 */ + secp256k1_fe z; + int infinity; /* whether this represents the point at infinity */ +} secp256k1_gej; + +#define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} +#define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} + +typedef struct { + secp256k1_fe_storage x; + secp256k1_fe_storage y; +} secp256k1_ge_storage; + +#define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} + +#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) + +/** Set a group element equal to the point with given X and Y coordinates */ +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); + +/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness + * for Y. Return value indicates whether the result is valid. */ +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); + +/** Check whether a group element is the point at infinity. */ +static int secp256k1_ge_is_infinity(const secp256k1_ge *a); + +/** Check whether a group element is valid (i.e., on the curve). */ +static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); + +/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); + +/** Set a group element equal to another which is given in jacobian coordinates. Constant time. */ +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); + +/** Set a group element equal to another which is given in jacobian coordinates. */ +static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a); + +/** Set a batch of group elements equal to the inputs given in jacobian coordinates */ +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len); + +/** Bring a batch of inputs to the same global z "denominator", based on ratios between + * (omitted) z coordinates of adjacent elements. + * + * Although the elements a[i] are _ge rather than _gej, they actually represent elements + * in Jacobian coordinates with their z coordinates omitted. + * + * Using the notation z(b) to represent the omitted z coordinate of b, the array zr of + * z coordinate ratios must satisfy zr[i] == z(a[i]) / z(a[i-1]) for 0 < 'i' < len. + * The zr[0] value is unused. + * + * This function adjusts the coordinates of 'a' in place so that for all 'i', z(a[i]) == z(a[len-1]). + * In other words, the initial value of z(a[len-1]) becomes the global z "denominator". Only the + * a[i].x and a[i].y coordinates are explicitly modified; the adjustment of the omitted z coordinate is + * implicit. + * + * The coordinates of the final element a[len-1] are not changed. + */ +static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr); + +/** Set a group element (affine) equal to the point at infinity. */ +static void secp256k1_ge_set_infinity(secp256k1_ge *r); + +/** Set a group element (jacobian) equal to the point at infinity. */ +static void secp256k1_gej_set_infinity(secp256k1_gej *r); + +/** Set a group element (jacobian) equal to another which is given in affine coordinates. */ +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); + +/** Compare the X coordinate of a group element (jacobian). */ +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); + +/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); + +/** Check whether a group element is the point at infinity. */ +static int secp256k1_gej_is_infinity(const secp256k1_gej *a); + +/** Set r equal to the double of a. Constant time. */ +static void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a); + +/** Set r equal to the double of a. If rzr is not-NULL this sets *rzr such that r->z == a->z * *rzr (where infinity means an implicit z = 0). */ +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); + +/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient + than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time + guarantee, and b is allowed to be infinity. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ +static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); + +/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); + +/** Clear a secp256k1_gej to prevent leaking sensitive information. */ +static void secp256k1_gej_clear(secp256k1_gej *r); + +/** Clear a secp256k1_ge to prevent leaking sensitive information. */ +static void secp256k1_ge_clear(secp256k1_ge *r); + +/** Convert a group element to the storage type. */ +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); + +/** Convert a group element back from the storage type. */ +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); + +/** Rescale a jacobian point by b which must be non-zero. Constant-time. */ +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); + +/** Determine if a point (which is assumed to be on the curve) is in the correct (sub)group of the curve. + * + * In normal mode, the used group is secp256k1, which has cofactor=1 meaning that every point on the curve is in the + * group, and this function returns always true. + * + * When compiling in exhaustive test mode, a slightly different curve equation is used, leading to a group with a + * (very) small subgroup, and that subgroup is what is used for all cryptographic operations. In that mode, this + * function checks whether a point that is on the curve is in fact also in that subgroup. + */ +static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge); + +#endif /* SECP256K1_GROUP_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group_impl.h new file mode 100644 index 00000000..63735ab6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/group_impl.h @@ -0,0 +1,698 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_GROUP_IMPL_H +#define SECP256K1_GROUP_IMPL_H + +#include "field.h" +#include "group.h" + +#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\ + 0xc3459c3d, 0x35326167, 0xcd86cce8, 0x07a2417f,\ + 0x5b8bd567, 0xde8538ee, 0x0d507b0c, 0xd128f5bb,\ + 0x8e467fec, 0xcd30000a, 0x6cc1184e, 0x25d382c2,\ + 0xa2f4494e, 0x2fbe9abc, 0x8b64abac, 0xd005fb24\ +) +#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\ + 0x226e653f, 0xc8df7744, 0x9bacbf12, 0x7d1dcbf9,\ + 0x87f05b2a, 0xe7edbd28, 0x1f564575, 0xc48dcf18,\ + 0xa13872c2, 0xe933bb17, 0x5d9ffd5b, 0xb5b6e10c,\ + 0x57fe3c00, 0xbaaaa15a, 0xe003ec3e, 0x9c269bae\ +) +/** Generator for secp256k1, value 'g' defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + */ +#define SECP256K1_G SECP256K1_GE_CONST(\ + 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,\ + 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,\ + 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,\ + 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL\ +) +/* These exhaustive group test orders and generators are chosen such that: + * - The field size is equal to that of secp256k1, so field code is the same. + * - The curve equation is of the form y^2=x^3+B for some constant B. + * - The subgroup has a generator 2*P, where P.x=1. + * - The subgroup has size less than 1000 to permit exhaustive testing. + * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y). + * + * These parameters are generated using sage/gen_exhaustive_groups.sage. + */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 13 +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13; + +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST( + 0x3d3486b2, 0x159a9ca5, 0xc75638be, 0xb23a69bc, + 0x946a45ab, 0x24801247, 0xb4ed2b8e, 0x26b6a417 +); +# elif EXHAUSTIVE_TEST_ORDER == 199 +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199; + +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST( + 0x2cca28fa, 0xfc614b80, 0x2a3db42b, 0x00ba00b1, + 0xbea8d943, 0xdace9ab2, 0x9536daea, 0x0074defb +); +# else +# error No known generator for the specified exhaustive test group order. +# endif +#else +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G; + +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 7); +#endif + +static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { + secp256k1_fe zi2; + secp256k1_fe zi3; + VERIFY_CHECK(!a->infinity); + secp256k1_fe_sqr(&zi2, zi); + secp256k1_fe_mul(&zi3, &zi2, zi); + secp256k1_fe_mul(&r->x, &a->x, &zi2); + secp256k1_fe_mul(&r->y, &a->y, &zi3); + r->infinity = a->infinity; +} + +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { + r->infinity = 0; + r->x = *x; + r->y = *y; +} + +static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { + return a->infinity; +} + +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { + *r = *a; + secp256k1_fe_normalize_weak(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; + r->infinity = a->infinity; + secp256k1_fe_inv(&a->z, &a->z); + secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_mul(&a->x, &a->x, &z2); + secp256k1_fe_mul(&a->y, &a->y, &z3); + secp256k1_fe_set_int(&a->z, 1); + r->x = a->x; + r->y = a->y; +} + +static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; + if (a->infinity) { + secp256k1_ge_set_infinity(r); + return; + } + secp256k1_fe_inv_var(&a->z, &a->z); + secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_mul(&a->x, &a->x, &z2); + secp256k1_fe_mul(&a->y, &a->y, &z3); + secp256k1_fe_set_int(&a->z, 1); + secp256k1_ge_set_xy(r, &a->x, &a->y); +} + +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) { + secp256k1_fe u; + size_t i; + size_t last_i = SIZE_MAX; + + for (i = 0; i < len; i++) { + if (a[i].infinity) { + secp256k1_ge_set_infinity(&r[i]); + } else { + /* Use destination's x coordinates as scratch space */ + if (last_i == SIZE_MAX) { + r[i].x = a[i].z; + } else { + secp256k1_fe_mul(&r[i].x, &r[last_i].x, &a[i].z); + } + last_i = i; + } + } + if (last_i == SIZE_MAX) { + return; + } + secp256k1_fe_inv_var(&u, &r[last_i].x); + + i = last_i; + while (i > 0) { + i--; + if (!a[i].infinity) { + secp256k1_fe_mul(&r[last_i].x, &r[i].x, &u); + secp256k1_fe_mul(&u, &u, &a[last_i].z); + last_i = i; + } + } + VERIFY_CHECK(!a[last_i].infinity); + r[last_i].x = u; + + for (i = 0; i < len; i++) { + if (!a[i].infinity) { + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x); + } + } +} + +static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr) { + size_t i = len - 1; + secp256k1_fe zs; + + if (len > 0) { + /* Ensure all y values are in weak normal form for fast negation of points */ + secp256k1_fe_normalize_weak(&a[i].y); + zs = zr[i]; + + /* Work our way backwards, using the z-ratios to scale the x/y values. */ + while (i > 0) { + secp256k1_gej tmpa; + if (i != len - 1) { + secp256k1_fe_mul(&zs, &zs, &zr[i]); + } + i--; + tmpa.x = a[i].x; + tmpa.y = a[i].y; + tmpa.infinity = 0; + secp256k1_ge_set_gej_zinv(&a[i], &tmpa, &zs); + } + } +} + +static void secp256k1_gej_set_infinity(secp256k1_gej *r) { + r->infinity = 1; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); +} + +static void secp256k1_ge_set_infinity(secp256k1_ge *r) { + r->infinity = 1; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); +} + +static void secp256k1_gej_clear(secp256k1_gej *r) { + r->infinity = 0; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); +} + +static void secp256k1_ge_clear(secp256k1_ge *r) { + r->infinity = 0; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); +} + +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { + secp256k1_fe x2, x3; + r->x = *x; + secp256k1_fe_sqr(&x2, x); + secp256k1_fe_mul(&x3, x, &x2); + r->infinity = 0; + secp256k1_fe_add(&x3, &secp256k1_fe_const_b); + if (!secp256k1_fe_sqrt(&r->y, &x3)) { + return 0; + } + secp256k1_fe_normalize_var(&r->y); + if (secp256k1_fe_is_odd(&r->y) != odd) { + secp256k1_fe_negate(&r->y, &r->y, 1); + } + return 1; + +} + +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { + r->infinity = a->infinity; + r->x = a->x; + r->y = a->y; + secp256k1_fe_set_int(&r->z, 1); +} + +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { + secp256k1_fe r, r2; + VERIFY_CHECK(!a->infinity); + secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); + r2 = a->x; secp256k1_fe_normalize_weak(&r2); + return secp256k1_fe_equal_var(&r, &r2); +} + +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { + r->infinity = a->infinity; + r->x = a->x; + r->y = a->y; + r->z = a->z; + secp256k1_fe_normalize_weak(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + +static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { + return a->infinity; +} + +static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { + secp256k1_fe y2, x3; + if (a->infinity) { + return 0; + } + /* y^2 = x^3 + 7 */ + secp256k1_fe_sqr(&y2, &a->y); + secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); + secp256k1_fe_add(&x3, &secp256k1_fe_const_b); + secp256k1_fe_normalize_weak(&x3); + return secp256k1_fe_equal_var(&y2, &x3); +} + +static SECP256K1_INLINE void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a) { + /* Operations: 3 mul, 4 sqr, 8 add/half/mul_int/negate */ + secp256k1_fe l, s, t; + + r->infinity = a->infinity; + + /* Formula used: + * L = (3/2) * X1^2 + * S = Y1^2 + * T = -X1*S + * X3 = L^2 + 2*T + * Y3 = -(L*(X3 + T) + S^2) + * Z3 = Y1*Z1 + */ + + secp256k1_fe_mul(&r->z, &a->z, &a->y); /* Z3 = Y1*Z1 (1) */ + secp256k1_fe_sqr(&s, &a->y); /* S = Y1^2 (1) */ + secp256k1_fe_sqr(&l, &a->x); /* L = X1^2 (1) */ + secp256k1_fe_mul_int(&l, 3); /* L = 3*X1^2 (3) */ + secp256k1_fe_half(&l); /* L = 3/2*X1^2 (2) */ + secp256k1_fe_negate(&t, &s, 1); /* T = -S (2) */ + secp256k1_fe_mul(&t, &t, &a->x); /* T = -X1*S (1) */ + secp256k1_fe_sqr(&r->x, &l); /* X3 = L^2 (1) */ + secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + T (2) */ + secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + 2*T (3) */ + secp256k1_fe_sqr(&s, &s); /* S' = S^2 (1) */ + secp256k1_fe_add(&t, &r->x); /* T' = X3 + T (4) */ + secp256k1_fe_mul(&r->y, &t, &l); /* Y3 = L*(X3 + T) (1) */ + secp256k1_fe_add(&r->y, &s); /* Y3 = L*(X3 + T) + S^2 (2) */ + secp256k1_fe_negate(&r->y, &r->y, 2); /* Y3 = -(L*(X3 + T) + S^2) (3) */ +} + +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { + /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, + * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have + * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + * + * Having said this, if this function receives a point on a sextic twist, e.g. by + * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, + * since -6 does have a cube root mod p. For this point, this function will not set + * the infinity flag even though the point doubles to infinity, and the result + * point will be gibberish (z = 0 but infinity = 0). + */ + if (a->infinity) { + secp256k1_gej_set_infinity(r); + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } + return; + } + + if (rzr != NULL) { + *rzr = a->y; + secp256k1_fe_normalize_weak(rzr); + } + + secp256k1_gej_double(r, a); +} + +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { + /* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t; + + if (a->infinity) { + VERIFY_CHECK(rzr == NULL); + *r = *b; + return; + } + if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } + *r = *a; + return; + } + + secp256k1_fe_sqr(&z22, &b->z); + secp256k1_fe_sqr(&z12, &a->z); + secp256k1_fe_mul(&u1, &a->x, &z22); + secp256k1_fe_mul(&u2, &b->x, &z12); + secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { + secp256k1_gej_double_var(r, a, rzr); + } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } + secp256k1_gej_set_infinity(r); + } + return; + } + + r->infinity = 0; + secp256k1_fe_mul(&t, &h, &b->z); + if (rzr != NULL) { + *rzr = t; + } + secp256k1_fe_mul(&r->z, &a->z, &t); + + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); + secp256k1_fe_mul(&t, &u1, &h2); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); + secp256k1_fe_add(&r->y, &h3); +} + +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { + /* 8 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t; + if (a->infinity) { + VERIFY_CHECK(rzr == NULL); + secp256k1_gej_set_ge(r, b); + return; + } + if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } + *r = *a; + return; + } + + secp256k1_fe_sqr(&z12, &a->z); + u1 = a->x; secp256k1_fe_normalize_weak(&u1); + secp256k1_fe_mul(&u2, &b->x, &z12); + s1 = a->y; secp256k1_fe_normalize_weak(&s1); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { + secp256k1_gej_double_var(r, a, rzr); + } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } + secp256k1_gej_set_infinity(r); + } + return; + } + + r->infinity = 0; + if (rzr != NULL) { + *rzr = h; + } + secp256k1_fe_mul(&r->z, &a->z, &h); + + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); + secp256k1_fe_mul(&t, &u1, &h2); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); + secp256k1_fe_add(&r->y, &h3); +} + +static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { + /* 9 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */ + secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t; + + if (a->infinity) { + secp256k1_fe bzinv2, bzinv3; + r->infinity = b->infinity; + secp256k1_fe_sqr(&bzinv2, bzinv); + secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv); + secp256k1_fe_mul(&r->x, &b->x, &bzinv2); + secp256k1_fe_mul(&r->y, &b->y, &bzinv3); + secp256k1_fe_set_int(&r->z, 1); + return; + } + if (b->infinity) { + *r = *a; + return; + } + + /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to + * secp256k1's isomorphism we can multiply the Z coordinates on both sides + * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1). + * This means that (rx,ry,rz) can be calculated as + * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz. + * The variable az below holds the modified Z coordinate for a, which is used + * for the computation of rx and ry, but not for rz. + */ + secp256k1_fe_mul(&az, &a->z, bzinv); + + secp256k1_fe_sqr(&z12, &az); + u1 = a->x; secp256k1_fe_normalize_weak(&u1); + secp256k1_fe_mul(&u2, &b->x, &z12); + s1 = a->y; secp256k1_fe_normalize_weak(&s1); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { + secp256k1_gej_double_var(r, a, NULL); + } else { + secp256k1_gej_set_infinity(r); + } + return; + } + + r->infinity = 0; + secp256k1_fe_mul(&r->z, &a->z, &h); + + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_negate(&h2, &h2, 1); + secp256k1_fe_mul(&h3, &h2, &h); + secp256k1_fe_mul(&t, &u1, &h2); + + secp256k1_fe_sqr(&r->x, &i); + secp256k1_fe_add(&r->x, &h3); + secp256k1_fe_add(&r->x, &t); + secp256k1_fe_add(&r->x, &t); + + secp256k1_fe_add(&t, &r->x); + secp256k1_fe_mul(&r->y, &t, &i); + secp256k1_fe_mul(&h3, &h3, &s1); + secp256k1_fe_add(&r->y, &h3); +} + + +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { + /* Operations: 7 mul, 5 sqr, 24 add/cmov/half/mul_int/negate/normalize_weak/normalizes_to_zero */ + secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; + secp256k1_fe m_alt, rr_alt; + int infinity, degenerate; + VERIFY_CHECK(!b->infinity); + VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); + + /** In: + * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks. + * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002. + * we find as solution for a unified addition/doubling formula: + * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation. + * x3 = lambda^2 - (x1 + x2) + * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2). + * + * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives: + * U1 = X1*Z2^2, U2 = X2*Z1^2 + * S1 = Y1*Z2^3, S2 = Y2*Z1^3 + * Z = Z1*Z2 + * T = U1+U2 + * M = S1+S2 + * Q = -T*M^2 + * R = T^2-U1*U2 + * X3 = R^2+Q + * Y3 = -(R*(2*X3+Q)+M^4)/2 + * Z3 = M*Z + * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) + * + * This formula has the benefit of being the same for both addition + * of distinct points and doubling. However, it breaks down in the + * case that either point is infinity, or that y1 = -y2. We handle + * these cases in the following ways: + * + * - If b is infinity we simply bail by means of a VERIFY_CHECK. + * + * - If a is infinity, we detect this, and at the end of the + * computation replace the result (which will be meaningless, + * but we compute to be constant-time) with b.x : b.y : 1. + * + * - If a = -b, we have y1 = -y2, which is a degenerate case. + * But here the answer is infinity, so we simply set the + * infinity flag of the result, overriding the computed values + * without even needing to cmov. + * + * - If y1 = -y2 but x1 != x2, which does occur thanks to certain + * properties of our curve (specifically, 1 has nontrivial cube + * roots in our field, and the curve equation has no x coefficient) + * then the answer is not infinity but also not given by the above + * equation. In this case, we cmov in place an alternate expression + * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these + * expressions for lambda are defined, they are equal, and can be + * obtained from each other by multiplication by (y1 + y2)/(y1 + y2) + * then substitution of x^3 + 7 for y^2 (using the curve equation). + * For all pairs of nonzero points (a, b) at least one is defined, + * so this covers everything. + */ + + secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ + u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ + secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ + s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ + secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ + secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ + t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ + m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ + secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ + secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ + secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ + secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ + /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" + * case that Z = z1z2 = 0, and this is special-cased later on). */ + degenerate = secp256k1_fe_normalizes_to_zero(&m) & + secp256k1_fe_normalizes_to_zero(&rr); + /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. + * This means either x1 == beta*x2 or beta*x1 == x2, where beta is + * a nontrivial cube root of one. In either case, an alternate + * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), + * so we set R/M equal to this. */ + rr_alt = s1; + secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ + secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ + + secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); + secp256k1_fe_cmov(&m_alt, &m, !degenerate); + /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. + * From here on out Ralt and Malt represent the numerator + * and denominator of lambda; R and M represent the explicit + * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ + secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ + secp256k1_fe_negate(&q, &t, 2); /* q = -T (3) */ + secp256k1_fe_mul(&q, &q, &n); /* q = Q = -T*Malt^2 (1) */ + /* These two lines use the observation that either M == Malt or M == 0, + * so M^3 * Malt is either Malt^4 (which is computed by squaring), or + * zero (which is "computed" by cmov). So the cost is one squaring + * versus two multiplications. */ + secp256k1_fe_sqr(&n, &n); + secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ + secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ + secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Z3 = Malt*Z (1) */ + infinity = secp256k1_fe_normalizes_to_zero(&r->z) & ~a->infinity; + secp256k1_fe_add(&t, &q); /* t = Ralt^2 + Q (2) */ + r->x = t; /* r->x = X3 = Ralt^2 + Q (2) */ + secp256k1_fe_mul_int(&t, 2); /* t = 2*X3 (4) */ + secp256k1_fe_add(&t, &q); /* t = 2*X3 + Q (5) */ + secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*X3 + Q) (1) */ + secp256k1_fe_add(&t, &n); /* t = Ralt*(2*X3 + Q) + M^3*Malt (3) */ + secp256k1_fe_negate(&r->y, &t, 3); /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (4) */ + secp256k1_fe_half(&r->y); /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 (3) */ + + /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ + secp256k1_fe_cmov(&r->x, &b->x, a->infinity); + secp256k1_fe_cmov(&r->y, &b->y, a->infinity); + secp256k1_fe_cmov(&r->z, &secp256k1_fe_one, a->infinity); + r->infinity = infinity; +} + +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { + /* Operations: 4 mul, 1 sqr */ + secp256k1_fe zz; + VERIFY_CHECK(!secp256k1_fe_is_zero(s)); + secp256k1_fe_sqr(&zz, s); + secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ + secp256k1_fe_mul(&r->y, &r->y, &zz); + secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */ + secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ +} + +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { + secp256k1_fe x, y; + VERIFY_CHECK(!a->infinity); + x = a->x; + secp256k1_fe_normalize(&x); + y = a->y; + secp256k1_fe_normalize(&y); + secp256k1_fe_to_storage(&r->x, &x); + secp256k1_fe_to_storage(&r->y, &y); +} + +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) { + secp256k1_fe_from_storage(&r->x, &a->x); + secp256k1_fe_from_storage(&r->y, &a->y); + r->infinity = 0; +} + +static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag) { + secp256k1_fe_cmov(&r->x, &a->x, flag); + secp256k1_fe_cmov(&r->y, &a->y, flag); + secp256k1_fe_cmov(&r->z, &a->z, flag); + + r->infinity ^= (r->infinity ^ a->infinity) & flag; +} + +static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { + secp256k1_fe_storage_cmov(&r->x, &a->x, flag); + secp256k1_fe_storage_cmov(&r->y, &a->y, flag); +} + +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { + *r = *a; + secp256k1_fe_mul(&r->x, &r->x, &secp256k1_const_beta); +} + +static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge) { +#ifdef EXHAUSTIVE_TEST_ORDER + secp256k1_gej out; + int i; + + /* A very simple EC multiplication ladder that avoids a dependency on ecmult. */ + secp256k1_gej_set_infinity(&out); + for (i = 0; i < 32; ++i) { + secp256k1_gej_double_var(&out, &out, NULL); + if ((((uint32_t)EXHAUSTIVE_TEST_ORDER) >> (31 - i)) & 1) { + secp256k1_gej_add_ge_var(&out, &out, ge, NULL); + } + } + return secp256k1_gej_is_infinity(&out); +#else + (void)ge; + /* The real secp256k1 group has cofactor 1, so the subgroup is the entire curve. */ + return 1; +#endif +} + +#endif /* SECP256K1_GROUP_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash.h new file mode 100644 index 00000000..4e0384cf --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash.h @@ -0,0 +1,41 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HASH_H +#define SECP256K1_HASH_H + +#include +#include + +typedef struct { + uint32_t s[8]; + unsigned char buf[64]; + uint64_t bytes; +} secp256k1_sha256; + +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); + +typedef struct { + secp256k1_sha256 inner, outer; +} secp256k1_hmac_sha256; + +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); + +typedef struct { + unsigned char v[32]; + unsigned char k[32]; + int retry; +} secp256k1_rfc6979_hmac_sha256; + +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); + +#endif /* SECP256K1_HASH_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash_impl.h new file mode 100644 index 00000000..0991fe78 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/hash_impl.h @@ -0,0 +1,290 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HASH_IMPL_H +#define SECP256K1_HASH_IMPL_H + +#include "hash.h" +#include "util.h" + +#include +#include +#include + +#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10)) +#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7)) +#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3)) +#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10)) + +#define Round(a,b,c,d,e,f,g,h,k,w) do { \ + uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \ + uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \ + (d) += t1; \ + (h) = t1 + t2; \ +} while(0) + +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) { + hash->s[0] = 0x6a09e667ul; + hash->s[1] = 0xbb67ae85ul; + hash->s[2] = 0x3c6ef372ul; + hash->s[3] = 0xa54ff53aul; + hash->s[4] = 0x510e527ful; + hash->s[5] = 0x9b05688cul; + hash->s[6] = 0x1f83d9abul; + hash->s[7] = 0x5be0cd19ul; + hash->bytes = 0; +} + +/** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ +static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* buf) { + uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = secp256k1_read_be32(&buf[0])); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = secp256k1_read_be32(&buf[4])); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = secp256k1_read_be32(&buf[8])); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = secp256k1_read_be32(&buf[12])); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = secp256k1_read_be32(&buf[16])); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = secp256k1_read_be32(&buf[20])); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = secp256k1_read_be32(&buf[24])); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = secp256k1_read_be32(&buf[28])); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = secp256k1_read_be32(&buf[32])); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = secp256k1_read_be32(&buf[36])); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = secp256k1_read_be32(&buf[40])); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = secp256k1_read_be32(&buf[44])); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = secp256k1_read_be32(&buf[48])); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = secp256k1_read_be32(&buf[52])); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = secp256k1_read_be32(&buf[56])); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = secp256k1_read_be32(&buf[60])); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); + + s[0] += a; + s[1] += b; + s[2] += c; + s[3] += d; + s[4] += e; + s[5] += f; + s[6] += g; + s[7] += h; +} + +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { + size_t bufsize = hash->bytes & 0x3F; + hash->bytes += len; + VERIFY_CHECK(hash->bytes >= len); + while (len >= 64 - bufsize) { + /* Fill the buffer, and process it. */ + size_t chunk_len = 64 - bufsize; + memcpy(hash->buf + bufsize, data, chunk_len); + data += chunk_len; + len -= chunk_len; + secp256k1_sha256_transform(hash->s, hash->buf); + bufsize = 0; + } + if (len) { + /* Fill the buffer with what remains. */ + memcpy(((unsigned char*)hash->buf) + bufsize, data, len); + } +} + +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { + static const unsigned char pad[64] = {0x80}; + unsigned char sizedesc[8]; + int i; + /* The maximum message size of SHA256 is 2^64-1 bits. */ + VERIFY_CHECK(hash->bytes < ((uint64_t)1 << 61)); + secp256k1_write_be32(&sizedesc[0], hash->bytes >> 29); + secp256k1_write_be32(&sizedesc[4], hash->bytes << 3); + secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); + secp256k1_sha256_write(hash, sizedesc, 8); + for (i = 0; i < 8; i++) { + secp256k1_write_be32(&out32[4*i], hash->s[i]); + hash->s[i] = 0; + } +} + +/* Initializes a sha256 struct and writes the 64 byte string + * SHA256(tag)||SHA256(tag) into it. */ +static void secp256k1_sha256_initialize_tagged(secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) { + unsigned char buf[32]; + secp256k1_sha256_initialize(hash); + secp256k1_sha256_write(hash, tag, taglen); + secp256k1_sha256_finalize(hash, buf); + + secp256k1_sha256_initialize(hash); + secp256k1_sha256_write(hash, buf, 32); + secp256k1_sha256_write(hash, buf, 32); +} + +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { + size_t n; + unsigned char rkey[64]; + if (keylen <= sizeof(rkey)) { + memcpy(rkey, key, keylen); + memset(rkey + keylen, 0, sizeof(rkey) - keylen); + } else { + secp256k1_sha256 sha256; + secp256k1_sha256_initialize(&sha256); + secp256k1_sha256_write(&sha256, key, keylen); + secp256k1_sha256_finalize(&sha256, rkey); + memset(rkey + 32, 0, 32); + } + + secp256k1_sha256_initialize(&hash->outer); + for (n = 0; n < sizeof(rkey); n++) { + rkey[n] ^= 0x5c; + } + secp256k1_sha256_write(&hash->outer, rkey, sizeof(rkey)); + + secp256k1_sha256_initialize(&hash->inner); + for (n = 0; n < sizeof(rkey); n++) { + rkey[n] ^= 0x5c ^ 0x36; + } + secp256k1_sha256_write(&hash->inner, rkey, sizeof(rkey)); + memset(rkey, 0, sizeof(rkey)); +} + +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { + secp256k1_sha256_write(&hash->inner, data, size); +} + +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { + unsigned char temp[32]; + secp256k1_sha256_finalize(&hash->inner, temp); + secp256k1_sha256_write(&hash->outer, temp, 32); + memset(temp, 0, 32); + secp256k1_sha256_finalize(&hash->outer, out32); +} + + +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { + secp256k1_hmac_sha256 hmac; + static const unsigned char zero[1] = {0x00}; + static const unsigned char one[1] = {0x01}; + + memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */ + memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ + + /* RFC6979 3.2.d. */ + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, zero, 1); + secp256k1_hmac_sha256_write(&hmac, key, keylen); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + + /* RFC6979 3.2.f. */ + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, one, 1); + secp256k1_hmac_sha256_write(&hmac, key, keylen); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + rng->retry = 0; +} + +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { + /* RFC6979 3.2.h. */ + static const unsigned char zero[1] = {0x00}; + if (rng->retry) { + secp256k1_hmac_sha256 hmac; + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_write(&hmac, zero, 1); + secp256k1_hmac_sha256_finalize(&hmac, rng->k); + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + } + + while (outlen > 0) { + secp256k1_hmac_sha256 hmac; + int now = outlen; + secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); + secp256k1_hmac_sha256_write(&hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(&hmac, rng->v); + if (now > 32) { + now = 32; + } + memcpy(out, rng->v, now); + out += now; + outlen -= now; + } + + rng->retry = 1; +} + +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { + memset(rng->k, 0, 32); + memset(rng->v, 0, 32); + rng->retry = 0; +} + +#undef Round +#undef sigma1 +#undef sigma0 +#undef Sigma1 +#undef Sigma0 +#undef Maj +#undef Ch + +#endif /* SECP256K1_HASH_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32.h new file mode 100644 index 00000000..0efdda9a --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32.h @@ -0,0 +1,42 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV32_H +#define SECP256K1_MODINV32_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" + +/* A signed 30-bit limb representation of integers. + * + * Its value is sum(v[i] * 2^(30*i), i=0..8). */ +typedef struct { + int32_t v[9]; +} secp256k1_modinv32_signed30; + +typedef struct { + /* The modulus in signed30 notation, must be odd and in [3, 2^256]. */ + secp256k1_modinv32_signed30 modulus; + + /* modulus^{-1} mod 2^30 */ + uint32_t modulus_inv30; +} secp256k1_modinv32_modinfo; + +/* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). + * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of + * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. + * + * On output, all of x's limbs will be in [0, 2^30). + */ +static void secp256k1_modinv32_var(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo); + +/* Same as secp256k1_modinv32_var, but constant time in x (not in the modulus). */ +static void secp256k1_modinv32(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo); + +#endif /* SECP256K1_MODINV32_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32_impl.h new file mode 100644 index 00000000..661c5fc0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv32_impl.h @@ -0,0 +1,587 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV32_IMPL_H +#define SECP256K1_MODINV32_IMPL_H + +#include "modinv32.h" + +#include "util.h" + +#include + +/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and + * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + * + * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an + * implementation for N=30, using 30-bit signed limbs represented as int32_t. + */ + +#ifdef VERIFY +static const secp256k1_modinv32_signed30 SECP256K1_SIGNED30_ONE = {{1}}; + +/* Compute a*factor and put it in r. All but the top limb in r will be in range [0,2^30). */ +static void secp256k1_modinv32_mul_30(secp256k1_modinv32_signed30 *r, const secp256k1_modinv32_signed30 *a, int alen, int32_t factor) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + int64_t c = 0; + int i; + for (i = 0; i < 8; ++i) { + if (i < alen) c += (int64_t)a->v[i] * factor; + r->v[i] = (int32_t)c & M30; c >>= 30; + } + if (8 < alen) c += (int64_t)a->v[8] * factor; + VERIFY_CHECK(c == (int32_t)c); + r->v[8] = (int32_t)c; +} + +/* Return -1 for ab*factor. A consists of alen limbs; b has 9. */ +static int secp256k1_modinv32_mul_cmp_30(const secp256k1_modinv32_signed30 *a, int alen, const secp256k1_modinv32_signed30 *b, int32_t factor) { + int i; + secp256k1_modinv32_signed30 am, bm; + secp256k1_modinv32_mul_30(&am, a, alen, 1); /* Normalize all but the top limb of a. */ + secp256k1_modinv32_mul_30(&bm, b, 9, factor); + for (i = 0; i < 8; ++i) { + /* Verify that all but the top limb of a and b are normalized. */ + VERIFY_CHECK(am.v[i] >> 30 == 0); + VERIFY_CHECK(bm.v[i] >> 30 == 0); + } + for (i = 8; i >= 0; --i) { + if (am.v[i] < bm.v[i]) return -1; + if (am.v[i] > bm.v[i]) return 1; + } + return 0; +} +#endif + +/* Take as input a signed30 number in range (-2*modulus,modulus), and add a multiple of the modulus + * to it to bring it to range [0,modulus). If sign < 0, the input will also be negated in the + * process. The input must have limbs in range (-2^30,2^30). The output will have limbs in range + * [0,2^30). */ +static void secp256k1_modinv32_normalize_30(secp256k1_modinv32_signed30 *r, int32_t sign, const secp256k1_modinv32_modinfo *modinfo) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + int32_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4], + r5 = r->v[5], r6 = r->v[6], r7 = r->v[7], r8 = r->v[8]; + int32_t cond_add, cond_negate; + +#ifdef VERIFY + /* Verify that all limbs are in range (-2^30,2^30). */ + int i; + for (i = 0; i < 9; ++i) { + VERIFY_CHECK(r->v[i] >= -M30); + VERIFY_CHECK(r->v[i] <= M30); + } + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, -2) > 0); /* r > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif + + /* In a first step, add the modulus if the input is negative, and then negate if requested. + * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input + * limbs are in range (-2^30,2^30), this cannot overflow an int32_t. Note that the right + * shifts below are signed sign-extending shifts (see assumptions.h for tests that that is + * indeed the behavior of the right shift operator). */ + cond_add = r8 >> 31; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + r5 += modinfo->modulus.v[5] & cond_add; + r6 += modinfo->modulus.v[6] & cond_add; + r7 += modinfo->modulus.v[7] & cond_add; + r8 += modinfo->modulus.v[8] & cond_add; + cond_negate = sign >> 31; + r0 = (r0 ^ cond_negate) - cond_negate; + r1 = (r1 ^ cond_negate) - cond_negate; + r2 = (r2 ^ cond_negate) - cond_negate; + r3 = (r3 ^ cond_negate) - cond_negate; + r4 = (r4 ^ cond_negate) - cond_negate; + r5 = (r5 ^ cond_negate) - cond_negate; + r6 = (r6 ^ cond_negate) - cond_negate; + r7 = (r7 ^ cond_negate) - cond_negate; + r8 = (r8 ^ cond_negate) - cond_negate; + /* Propagate the top bits, to bring limbs back to range (-2^30,2^30). */ + r1 += r0 >> 30; r0 &= M30; + r2 += r1 >> 30; r1 &= M30; + r3 += r2 >> 30; r2 &= M30; + r4 += r3 >> 30; r3 &= M30; + r5 += r4 >> 30; r4 &= M30; + r6 += r5 >> 30; r5 &= M30; + r7 += r6 >> 30; r6 &= M30; + r8 += r7 >> 30; r7 &= M30; + + /* In a second step add the modulus again if the result is still negative, bringing r to range + * [0,modulus). */ + cond_add = r8 >> 31; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + r5 += modinfo->modulus.v[5] & cond_add; + r6 += modinfo->modulus.v[6] & cond_add; + r7 += modinfo->modulus.v[7] & cond_add; + r8 += modinfo->modulus.v[8] & cond_add; + /* And propagate again. */ + r1 += r0 >> 30; r0 &= M30; + r2 += r1 >> 30; r1 &= M30; + r3 += r2 >> 30; r2 &= M30; + r4 += r3 >> 30; r3 &= M30; + r5 += r4 >> 30; r4 &= M30; + r6 += r5 >> 30; r5 &= M30; + r7 += r6 >> 30; r6 &= M30; + r8 += r7 >> 30; r7 &= M30; + + r->v[0] = r0; + r->v[1] = r1; + r->v[2] = r2; + r->v[3] = r3; + r->v[4] = r4; + r->v[5] = r5; + r->v[6] = r6; + r->v[7] = r7; + r->v[8] = r8; + +#ifdef VERIFY + VERIFY_CHECK(r0 >> 30 == 0); + VERIFY_CHECK(r1 >> 30 == 0); + VERIFY_CHECK(r2 >> 30 == 0); + VERIFY_CHECK(r3 >> 30 == 0); + VERIFY_CHECK(r4 >> 30 == 0); + VERIFY_CHECK(r5 >> 30 == 0); + VERIFY_CHECK(r6 >> 30 == 0); + VERIFY_CHECK(r7 >> 30 == 0); + VERIFY_CHECK(r8 >> 30 == 0); + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 0) >= 0); /* r >= 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(r, 9, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif +} + +/* Data type for transition matrices (see section 3 of explanation). + * + * t = [ u v ] + * [ q r ] + */ +typedef struct { + int32_t u, v, q, r; +} secp256k1_modinv32_trans2x2; + +/* Compute the transition matrix and zeta for 30 divsteps. + * + * Input: zeta: initial zeta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final zeta + * + * Implements the divsteps_n_matrix function from the explanation. + */ +static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_t g0, secp256k1_modinv32_trans2x2 *t) { + /* u,v,q,r are the elements of the transformation matrix being built up, + * starting with the identity matrix. Semantically they are signed integers + * in range [-2^30,2^30], but here represented as unsigned mod 2^32. This + * permits left shifting (which is UB for negative numbers). The range + * being inside [-2^31,2^31) means that casting to signed works correctly. + */ + uint32_t u = 1, v = 0, q = 0, r = 1; + uint32_t c1, c2, f = f0, g = g0, x, y, z; + int i; + + for (i = 0; i < 30; ++i) { + VERIFY_CHECK((f & 1) == 1); /* f must always be odd */ + VERIFY_CHECK((u * f0 + v * g0) == f << i); + VERIFY_CHECK((q * f0 + r * g0) == g << i); + /* Compute conditional masks for (zeta < 0) and for (g & 1). */ + c1 = zeta >> 31; + c2 = -(g & 1); + /* Compute x,y,z, conditionally negated versions of f,u,v. */ + x = (f ^ c1) - c1; + y = (u ^ c1) - c1; + z = (v ^ c1) - c1; + /* Conditionally add x,y,z to g,q,r. */ + g += x & c2; + q += y & c2; + r += z & c2; + /* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */ + c1 &= c2; + /* Conditionally change zeta into -zeta-2 or zeta-1. */ + zeta = (zeta ^ c1) - 1; + /* Conditionally add g,q,r to f,u,v. */ + f += g & c1; + u += q & c1; + v += r & c1; + /* Shifts */ + g >>= 1; + u <<= 1; + v <<= 1; + /* Bounds on zeta that follow from the bounds on iteration count (max 20*30 divsteps). */ + VERIFY_CHECK(zeta >= -601 && zeta <= 601); + } + /* Return data in t and return value. */ + t->u = (int32_t)u; + t->v = (int32_t)v; + t->q = (int32_t)q; + t->r = (int32_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 30 of them will have determinant 2^30. */ + VERIFY_CHECK((int64_t)t->u * t->r - (int64_t)t->v * t->q == ((int64_t)1) << 30); + return zeta; +} + +/* Compute the transition matrix and eta for 30 divsteps (variable time). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final eta + * + * Implements the divsteps_n_matrix_var function from the explanation. + */ +static int32_t secp256k1_modinv32_divsteps_30_var(int32_t eta, uint32_t f0, uint32_t g0, secp256k1_modinv32_trans2x2 *t) { + /* inv256[i] = -(2*i+1)^-1 (mod 256) */ + static const uint8_t inv256[128] = { + 0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59, + 0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31, + 0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89, + 0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61, + 0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9, + 0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91, + 0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9, + 0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1, + 0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19, + 0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1, + 0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01 + }; + + /* Transformation matrix; see comments in secp256k1_modinv32_divsteps_30. */ + uint32_t u = 1, v = 0, q = 0, r = 1; + uint32_t f = f0, g = g0, m; + uint16_t w; + int i = 30, limit, zeros; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz32_var(g | (UINT32_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* We're done once we've done 30 divsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (30 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (30 - i)); + /* Bounds on eta that follow from the bounds on iteration count (max 25*30 divsteps). */ + VERIFY_CHECK(eta >= -751 && eta <= 751); + /* If eta is negative, negate it and replace f,g with g,-f. */ + if (eta < 0) { + uint32_t tmp; + eta = -eta; + tmp = f; f = g; g = -tmp; + tmp = u; u = q; q = -tmp; + tmp = v; v = r; r = -tmp; + } + /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more + * than i can be cancelled out (as we'd be done before that point), and no more than eta+1 + * can be done as its sign will flip once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + /* m is a mask for the bottom min(limit, 8) bits (our table only supports 8 bits). */ + VERIFY_CHECK(limit > 0 && limit <= 30); + m = (UINT32_MAX >> (32 - limit)) & 255U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 8) bits. */ + w = (g * inv256[(f >> 1) & 127]) & m; + /* Do so. */ + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int32_t)u; + t->v = (int32_t)v; + t->q = (int32_t)q; + t->r = (int32_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 30 of them will have determinant 2^30. */ + VERIFY_CHECK((int64_t)t->u * t->r - (int64_t)t->v * t->q == ((int64_t)1) << 30); + return eta; +} + +/* Compute (t/2^30) * [d, e] mod modulus, where t is a transition matrix for 30 divsteps. + * + * On input and output, d and e are in range (-2*modulus,modulus). All output limbs will be in range + * (-2^30,2^30). + * + * This implements the update_de function from the explanation. + */ +static void secp256k1_modinv32_update_de_30(secp256k1_modinv32_signed30 *d, secp256k1_modinv32_signed30 *e, const secp256k1_modinv32_trans2x2 *t, const secp256k1_modinv32_modinfo* modinfo) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t di, ei, md, me, sd, se; + int64_t cd, ce; + int i; +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, 1) < 0); /* e < modulus */ + VERIFY_CHECK((labs(u) + labs(v)) >= 0); /* |u|+|v| doesn't overflow */ + VERIFY_CHECK((labs(q) + labs(r)) >= 0); /* |q|+|r| doesn't overflow */ + VERIFY_CHECK((labs(u) + labs(v)) <= M30 + 1); /* |u|+|v| <= 2^30 */ + VERIFY_CHECK((labs(q) + labs(r)) <= M30 + 1); /* |q|+|r| <= 2^30 */ +#endif + /* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */ + sd = d->v[8] >> 31; + se = e->v[8] >> 31; + md = (u & sd) + (v & se); + me = (q & sd) + (r & se); + /* Begin computing t*[d,e]. */ + di = d->v[0]; + ei = e->v[0]; + cd = (int64_t)u * di + (int64_t)v * ei; + ce = (int64_t)q * di + (int64_t)r * ei; + /* Correct md,me so that t*[d,e]+modulus*[md,me] has 30 zero bottom bits. */ + md -= (modinfo->modulus_inv30 * (uint32_t)cd + md) & M30; + me -= (modinfo->modulus_inv30 * (uint32_t)ce + me) & M30; + /* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */ + cd += (int64_t)modinfo->modulus.v[0] * md; + ce += (int64_t)modinfo->modulus.v[0] * me; + /* Verify that the low 30 bits of the computation are indeed zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cd & M30) == 0); cd >>= 30; + VERIFY_CHECK(((int32_t)ce & M30) == 0); ce >>= 30; + /* Now iteratively compute limb i=1..8 of t*[d,e]+modulus*[md,me], and store them in output + * limb i-1 (shifting down by 30 bits). */ + for (i = 1; i < 9; ++i) { + di = d->v[i]; + ei = e->v[i]; + cd += (int64_t)u * di + (int64_t)v * ei; + ce += (int64_t)q * di + (int64_t)r * ei; + cd += (int64_t)modinfo->modulus.v[i] * md; + ce += (int64_t)modinfo->modulus.v[i] * me; + d->v[i - 1] = (int32_t)cd & M30; cd >>= 30; + e->v[i - 1] = (int32_t)ce & M30; ce >>= 30; + } + /* What remains is limb 9 of t*[d,e]+modulus*[md,me]; store it as output limb 8. */ + d->v[8] = (int32_t)cd; + e->v[8] = (int32_t)ce; +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(d, 9, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(e, 9, &modinfo->modulus, 1) < 0); /* e < modulus */ +#endif +} + +/* Compute (t/2^30) * [f, g], where t is a transition matrix for 30 divsteps. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv32_update_fg_30(secp256k1_modinv32_signed30 *f, secp256k1_modinv32_signed30 *g, const secp256k1_modinv32_trans2x2 *t) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t fi, gi; + int64_t cf, cg; + int i; + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + cf = (int64_t)u * fi + (int64_t)v * gi; + cg = (int64_t)q * fi + (int64_t)r * gi; + /* Verify that the bottom 30 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cf & M30) == 0); cf >>= 30; + VERIFY_CHECK(((int32_t)cg & M30) == 0); cg >>= 30; + /* Now iteratively compute limb i=1..8 of t*[f,g], and store them in output limb i-1 (shifting + * down by 30 bits). */ + for (i = 1; i < 9; ++i) { + fi = f->v[i]; + gi = g->v[i]; + cf += (int64_t)u * fi + (int64_t)v * gi; + cg += (int64_t)q * fi + (int64_t)r * gi; + f->v[i - 1] = (int32_t)cf & M30; cf >>= 30; + g->v[i - 1] = (int32_t)cg & M30; cg >>= 30; + } + /* What remains is limb 9 of t*[f,g]; store it as output limb 8. */ + f->v[8] = (int32_t)cf; + g->v[8] = (int32_t)cg; +} + +/* Compute (t/2^30) * [f, g], where t is a transition matrix for 30 divsteps. + * + * Version that operates on a variable number of limbs in f and g. + * + * This implements the update_fg function from the explanation in modinv64_impl.h. + */ +static void secp256k1_modinv32_update_fg_30_var(int len, secp256k1_modinv32_signed30 *f, secp256k1_modinv32_signed30 *g, const secp256k1_modinv32_trans2x2 *t) { + const int32_t M30 = (int32_t)(UINT32_MAX >> 2); + const int32_t u = t->u, v = t->v, q = t->q, r = t->r; + int32_t fi, gi; + int64_t cf, cg; + int i; + VERIFY_CHECK(len > 0); + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + cf = (int64_t)u * fi + (int64_t)v * gi; + cg = (int64_t)q * fi + (int64_t)r * gi; + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int32_t)cf & M30) == 0); cf >>= 30; + VERIFY_CHECK(((int32_t)cg & M30) == 0); cg >>= 30; + /* Now iteratively compute limb i=1..len of t*[f,g], and store them in output limb i-1 (shifting + * down by 30 bits). */ + for (i = 1; i < len; ++i) { + fi = f->v[i]; + gi = g->v[i]; + cf += (int64_t)u * fi + (int64_t)v * gi; + cg += (int64_t)q * fi + (int64_t)r * gi; + f->v[i - 1] = (int32_t)cf & M30; cf >>= 30; + g->v[i - 1] = (int32_t)cg & M30; cg >>= 30; + } + /* What remains is limb (len) of t*[f,g]; store it as output limb (len-1). */ + f->v[len - 1] = (int32_t)cf; + g->v[len - 1] = (int32_t)cg; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (constant time in x). */ +static void secp256k1_modinv32(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, zeta=-1. */ + secp256k1_modinv32_signed30 d = {{0}}; + secp256k1_modinv32_signed30 e = {{1}}; + secp256k1_modinv32_signed30 f = modinfo->modulus; + secp256k1_modinv32_signed30 g = *x; + int i; + int32_t zeta = -1; /* zeta = -(delta+1/2); delta is initially 1/2. */ + + /* Do 20 iterations of 30 divsteps each = 600 divsteps. 590 suffices for 256-bit inputs. */ + for (i = 0; i < 20; ++i) { + /* Compute transition matrix and new zeta after 30 divsteps. */ + secp256k1_modinv32_trans2x2 t; + zeta = secp256k1_modinv32_divsteps_30(zeta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv32_update_de_30(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + secp256k1_modinv32_update_fg_30(&f, &g, &t); +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + } + + /* At this point sufficient iterations have been performed that g must have reached 0 + * and (if g was not originally 0) f must now equal +/- GCD of the initial f, g + * values i.e. +/- 1, and d now contains +/- the modular inverse. */ +#ifdef VERIFY + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, 9, &SECP256K1_SIGNED30_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and |f|=modulus) */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, 9, &SECP256K1_SIGNED30_ONE, -1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, 9, &SECP256K1_SIGNED30_ONE, 1) == 0 || + (secp256k1_modinv32_mul_cmp_30(x, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&d, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + (secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, 1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, 9, &modinfo->modulus, -1) == 0))); +#endif + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv32_normalize_30(&d, f.v[8], modinfo); + *x = d; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (variable time). */ +static void secp256k1_modinv32_var(secp256k1_modinv32_signed30 *x, const secp256k1_modinv32_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, eta=-1. */ + secp256k1_modinv32_signed30 d = {{0, 0, 0, 0, 0, 0, 0, 0, 0}}; + secp256k1_modinv32_signed30 e = {{1, 0, 0, 0, 0, 0, 0, 0, 0}}; + secp256k1_modinv32_signed30 f = modinfo->modulus; + secp256k1_modinv32_signed30 g = *x; +#ifdef VERIFY + int i = 0; +#endif + int j, len = 9; + int32_t eta = -1; /* eta = -delta; delta is initially 1 (faster for the variable-time code) */ + int32_t cond, fn, gn; + + /* Do iterations of 30 divsteps each until g=0. */ + while (1) { + /* Compute transition matrix and new eta after 30 divsteps. */ + secp256k1_modinv32_trans2x2 t; + eta = secp256k1_modinv32_divsteps_30_var(eta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv32_update_de_30(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + secp256k1_modinv32_update_fg_30_var(len, &f, &g, &t); + /* If the bottom limb of g is 0, there is a chance g=0. */ + if (g.v[0] == 0) { + cond = 0; + /* Check if all other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= g.v[j]; + } + /* If so, we're done. */ + if (cond == 0) break; + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0 or -1. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int32_t)len - 2) >> 31; + cond |= fn ^ (fn >> 31); + cond |= gn ^ (gn >> 31); + /* If so, reduce length, propagating the sign of f and g's top limb into the one below. */ + if (cond == 0) { + f.v[len - 2] |= (uint32_t)fn << 30; + g.v[len - 2] |= (uint32_t)gn << 30; + --len; + } +#ifdef VERIFY + VERIFY_CHECK(++i < 25); /* We should never need more than 25*30 = 750 divsteps */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + } + + /* At this point g is 0 and (if g was not originally 0) f must now equal +/- GCD of + * the initial f, g values i.e. +/- 1, and d now contains +/- the modular inverse. */ +#ifdef VERIFY + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&g, len, &SECP256K1_SIGNED30_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and |f|=modulus) */ + VERIFY_CHECK(secp256k1_modinv32_mul_cmp_30(&f, len, &SECP256K1_SIGNED30_ONE, -1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, len, &SECP256K1_SIGNED30_ONE, 1) == 0 || + (secp256k1_modinv32_mul_cmp_30(x, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + secp256k1_modinv32_mul_cmp_30(&d, 9, &SECP256K1_SIGNED30_ONE, 0) == 0 && + (secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, 1) == 0 || + secp256k1_modinv32_mul_cmp_30(&f, len, &modinfo->modulus, -1) == 0))); +#endif + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv32_normalize_30(&d, f.v[len - 1], modinfo); + *x = d; +} + +#endif /* SECP256K1_MODINV32_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64.h new file mode 100644 index 00000000..da506dfa --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64.h @@ -0,0 +1,46 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV64_H +#define SECP256K1_MODINV64_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" + +#ifndef SECP256K1_WIDEMUL_INT128 +#error "modinv64 requires 128-bit wide multiplication support" +#endif + +/* A signed 62-bit limb representation of integers. + * + * Its value is sum(v[i] * 2^(62*i), i=0..4). */ +typedef struct { + int64_t v[5]; +} secp256k1_modinv64_signed62; + +typedef struct { + /* The modulus in signed62 notation, must be odd and in [3, 2^256]. */ + secp256k1_modinv64_signed62 modulus; + + /* modulus^{-1} mod 2^62 */ + uint64_t modulus_inv62; +} secp256k1_modinv64_modinfo; + +/* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). + * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of + * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. + * + * On output, all of x's limbs will be in [0, 2^62). + */ +static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo); + +/* Same as secp256k1_modinv64_var, but constant time in x (not in the modulus). */ +static void secp256k1_modinv64(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo); + +#endif /* SECP256K1_MODINV64_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64_impl.h new file mode 100644 index 00000000..0743a9c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modinv64_impl.h @@ -0,0 +1,593 @@ +/*********************************************************************** + * Copyright (c) 2020 Peter Dettman * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODINV64_IMPL_H +#define SECP256K1_MODINV64_IMPL_H + +#include "modinv64.h" + +#include "util.h" + +/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and + * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + * + * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an + * implementation for N=62, using 62-bit signed limbs represented as int64_t. + */ + +#ifdef VERIFY +/* Helper function to compute the absolute value of an int64_t. + * (we don't use abs/labs/llabs as it depends on the int sizes). */ +static int64_t secp256k1_modinv64_abs(int64_t v) { + VERIFY_CHECK(v > INT64_MIN); + if (v < 0) return -v; + return v; +} + +static const secp256k1_modinv64_signed62 SECP256K1_SIGNED62_ONE = {{1}}; + +/* Compute a*factor and put it in r. All but the top limb in r will be in range [0,2^62). */ +static void secp256k1_modinv64_mul_62(secp256k1_modinv64_signed62 *r, const secp256k1_modinv64_signed62 *a, int alen, int64_t factor) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + int128_t c = 0; + int i; + for (i = 0; i < 4; ++i) { + if (i < alen) c += (int128_t)a->v[i] * factor; + r->v[i] = (int64_t)c & M62; c >>= 62; + } + if (4 < alen) c += (int128_t)a->v[4] * factor; + VERIFY_CHECK(c == (int64_t)c); + r->v[4] = (int64_t)c; +} + +/* Return -1 for ab*factor. A has alen limbs; b has 5. */ +static int secp256k1_modinv64_mul_cmp_62(const secp256k1_modinv64_signed62 *a, int alen, const secp256k1_modinv64_signed62 *b, int64_t factor) { + int i; + secp256k1_modinv64_signed62 am, bm; + secp256k1_modinv64_mul_62(&am, a, alen, 1); /* Normalize all but the top limb of a. */ + secp256k1_modinv64_mul_62(&bm, b, 5, factor); + for (i = 0; i < 4; ++i) { + /* Verify that all but the top limb of a and b are normalized. */ + VERIFY_CHECK(am.v[i] >> 62 == 0); + VERIFY_CHECK(bm.v[i] >> 62 == 0); + } + for (i = 4; i >= 0; --i) { + if (am.v[i] < bm.v[i]) return -1; + if (am.v[i] > bm.v[i]) return 1; + } + return 0; +} +#endif + +/* Take as input a signed62 number in range (-2*modulus,modulus), and add a multiple of the modulus + * to it to bring it to range [0,modulus). If sign < 0, the input will also be negated in the + * process. The input must have limbs in range (-2^62,2^62). The output will have limbs in range + * [0,2^62). */ +static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t sign, const secp256k1_modinv64_modinfo *modinfo) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4]; + int64_t cond_add, cond_negate; + +#ifdef VERIFY + /* Verify that all limbs are in range (-2^62,2^62). */ + int i; + for (i = 0; i < 5; ++i) { + VERIFY_CHECK(r->v[i] >= -M62); + VERIFY_CHECK(r->v[i] <= M62); + } + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, -2) > 0); /* r > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif + + /* In a first step, add the modulus if the input is negative, and then negate if requested. + * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input + * limbs are in range (-2^62,2^62), this cannot overflow an int64_t. Note that the right + * shifts below are signed sign-extending shifts (see assumptions.h for tests that that is + * indeed the behavior of the right shift operator). */ + cond_add = r4 >> 63; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + cond_negate = sign >> 63; + r0 = (r0 ^ cond_negate) - cond_negate; + r1 = (r1 ^ cond_negate) - cond_negate; + r2 = (r2 ^ cond_negate) - cond_negate; + r3 = (r3 ^ cond_negate) - cond_negate; + r4 = (r4 ^ cond_negate) - cond_negate; + /* Propagate the top bits, to bring limbs back to range (-2^62,2^62). */ + r1 += r0 >> 62; r0 &= M62; + r2 += r1 >> 62; r1 &= M62; + r3 += r2 >> 62; r2 &= M62; + r4 += r3 >> 62; r3 &= M62; + + /* In a second step add the modulus again if the result is still negative, bringing + * r to range [0,modulus). */ + cond_add = r4 >> 63; + r0 += modinfo->modulus.v[0] & cond_add; + r1 += modinfo->modulus.v[1] & cond_add; + r2 += modinfo->modulus.v[2] & cond_add; + r3 += modinfo->modulus.v[3] & cond_add; + r4 += modinfo->modulus.v[4] & cond_add; + /* And propagate again. */ + r1 += r0 >> 62; r0 &= M62; + r2 += r1 >> 62; r1 &= M62; + r3 += r2 >> 62; r2 &= M62; + r4 += r3 >> 62; r3 &= M62; + + r->v[0] = r0; + r->v[1] = r1; + r->v[2] = r2; + r->v[3] = r3; + r->v[4] = r4; + +#ifdef VERIFY + VERIFY_CHECK(r0 >> 62 == 0); + VERIFY_CHECK(r1 >> 62 == 0); + VERIFY_CHECK(r2 >> 62 == 0); + VERIFY_CHECK(r3 >> 62 == 0); + VERIFY_CHECK(r4 >> 62 == 0); + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 0) >= 0); /* r >= 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(r, 5, &modinfo->modulus, 1) < 0); /* r < modulus */ +#endif +} + +/* Data type for transition matrices (see section 3 of explanation). + * + * t = [ u v ] + * [ q r ] + */ +typedef struct { + int64_t u, v, q, r; +} secp256k1_modinv64_trans2x2; + +/* Compute the transition matrix and eta for 59 divsteps (where zeta=-(delta+1/2)). + * Note that the transformation matrix is scaled by 2^62 and not 2^59. + * + * Input: zeta: initial zeta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final zeta + * + * Implements the divsteps_n_matrix function from the explanation. + */ +static int64_t secp256k1_modinv64_divsteps_59(int64_t zeta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) { + /* u,v,q,r are the elements of the transformation matrix being built up, + * starting with the identity matrix times 8 (because the caller expects + * a result scaled by 2^62). Semantically they are signed integers + * in range [-2^62,2^62], but here represented as unsigned mod 2^64. This + * permits left shifting (which is UB for negative numbers). The range + * being inside [-2^63,2^63) means that casting to signed works correctly. + */ + uint64_t u = 8, v = 0, q = 0, r = 8; + uint64_t c1, c2, f = f0, g = g0, x, y, z; + int i; + + for (i = 3; i < 62; ++i) { + VERIFY_CHECK((f & 1) == 1); /* f must always be odd */ + VERIFY_CHECK((u * f0 + v * g0) == f << i); + VERIFY_CHECK((q * f0 + r * g0) == g << i); + /* Compute conditional masks for (zeta < 0) and for (g & 1). */ + c1 = zeta >> 63; + c2 = -(g & 1); + /* Compute x,y,z, conditionally negated versions of f,u,v. */ + x = (f ^ c1) - c1; + y = (u ^ c1) - c1; + z = (v ^ c1) - c1; + /* Conditionally add x,y,z to g,q,r. */ + g += x & c2; + q += y & c2; + r += z & c2; + /* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */ + c1 &= c2; + /* Conditionally change zeta into -zeta-2 or zeta-1. */ + zeta = (zeta ^ c1) - 1; + /* Conditionally add g,q,r to f,u,v. */ + f += g & c1; + u += q & c1; + v += r & c1; + /* Shifts */ + g >>= 1; + u <<= 1; + v <<= 1; + /* Bounds on zeta that follow from the bounds on iteration count (max 10*59 divsteps). */ + VERIFY_CHECK(zeta >= -591 && zeta <= 591); + } + /* Return data in t and return value. */ + t->u = (int64_t)u; + t->v = (int64_t)v; + t->q = (int64_t)q; + t->r = (int64_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 59 of them will have determinant 2^59. Multiplying with the initial + * 8*identity (which has determinant 2^6) means the overall outputs has determinant + * 2^65. */ + VERIFY_CHECK((int128_t)t->u * t->r - (int128_t)t->v * t->q == ((int128_t)1) << 65); + return zeta; +} + +/* Compute the transition matrix and eta for 62 divsteps (variable time, eta=-delta). + * + * Input: eta: initial eta + * f0: bottom limb of initial f + * g0: bottom limb of initial g + * Output: t: transition matrix + * Return: final eta + * + * Implements the divsteps_n_matrix_var function from the explanation. + */ +static int64_t secp256k1_modinv64_divsteps_62_var(int64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) { + /* Transformation matrix; see comments in secp256k1_modinv64_divsteps_62. */ + uint64_t u = 1, v = 0, q = 0, r = 1; + uint64_t f = f0, g = g0, m; + uint32_t w; + int i = 62, limit, zeros; + + for (;;) { + /* Use a sentinel bit to count zeros only up to i. */ + zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i)); + /* Perform zeros divsteps at once; they all just divide g by two. */ + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + /* We're done once we've done 62 divsteps. */ + if (i == 0) break; + VERIFY_CHECK((f & 1) == 1); + VERIFY_CHECK((g & 1) == 1); + VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i)); + VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i)); + /* Bounds on eta that follow from the bounds on iteration count (max 12*62 divsteps). */ + VERIFY_CHECK(eta >= -745 && eta <= 745); + /* If eta is negative, negate it and replace f,g with g,-f. */ + if (eta < 0) { + uint64_t tmp; + eta = -eta; + tmp = f; f = g; g = -tmp; + tmp = u; u = q; q = -tmp; + tmp = v; v = r; r = -tmp; + /* Use a formula to cancel out up to 6 bits of g. Also, no more than i can be cancelled + * out (as we'd be done before that point), and no more than eta+1 can be done as its + * will flip again once that happens. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 6) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 63U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 6) + * bits. */ + w = (f * g * (f * f - 2)) & m; + } else { + /* In this branch, use a simpler formula that only lets us cancel up to 4 bits of g, as + * eta tends to be smaller here. */ + limit = ((int)eta + 1) > i ? i : ((int)eta + 1); + VERIFY_CHECK(limit > 0 && limit <= 62); + /* m is a mask for the bottom min(limit, 4) bits. */ + m = (UINT64_MAX >> (64 - limit)) & 15U; + /* Find what multiple of f must be added to g to cancel its bottom min(limit, 4) + * bits. */ + w = f + (((f + 1) & 4) << 1); + w = (-w * g) & m; + } + g += f * w; + q += u * w; + r += v * w; + VERIFY_CHECK((g & m) == 0); + } + /* Return data in t and return value. */ + t->u = (int64_t)u; + t->v = (int64_t)v; + t->q = (int64_t)q; + t->r = (int64_t)r; + /* The determinant of t must be a power of two. This guarantees that multiplication with t + * does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which + * will be divided out again). As each divstep's individual matrix has determinant 2, the + * aggregate of 62 of them will have determinant 2^62. */ + VERIFY_CHECK((int128_t)t->u * t->r - (int128_t)t->v * t->q == ((int128_t)1) << 62); + return eta; +} + +/* Compute (t/2^62) * [d, e] mod modulus, where t is a transition matrix scaled by 2^62. + * + * On input and output, d and e are in range (-2*modulus,modulus). All output limbs will be in range + * (-2^62,2^62). + * + * This implements the update_de function from the explanation. + */ +static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp256k1_modinv64_signed62 *e, const secp256k1_modinv64_trans2x2 *t, const secp256k1_modinv64_modinfo* modinfo) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + const int64_t d0 = d->v[0], d1 = d->v[1], d2 = d->v[2], d3 = d->v[3], d4 = d->v[4]; + const int64_t e0 = e->v[0], e1 = e->v[1], e2 = e->v[2], e3 = e->v[3], e4 = e->v[4]; + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + int64_t md, me, sd, se; + int128_t cd, ce; +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, 1) < 0); /* e < modulus */ + VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) >= 0); /* |u|+|v| doesn't overflow */ + VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) >= 0); /* |q|+|r| doesn't overflow */ + VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) <= M62 + 1); /* |u|+|v| <= 2^62 */ + VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) <= M62 + 1); /* |q|+|r| <= 2^62 */ +#endif + /* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */ + sd = d4 >> 63; + se = e4 >> 63; + md = (u & sd) + (v & se); + me = (q & sd) + (r & se); + /* Begin computing t*[d,e]. */ + cd = (int128_t)u * d0 + (int128_t)v * e0; + ce = (int128_t)q * d0 + (int128_t)r * e0; + /* Correct md,me so that t*[d,e]+modulus*[md,me] has 62 zero bottom bits. */ + md -= (modinfo->modulus_inv62 * (uint64_t)cd + md) & M62; + me -= (modinfo->modulus_inv62 * (uint64_t)ce + me) & M62; + /* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */ + cd += (int128_t)modinfo->modulus.v[0] * md; + ce += (int128_t)modinfo->modulus.v[0] * me; + /* Verify that the low 62 bits of the computation are indeed zero, and then throw them away. */ + VERIFY_CHECK(((int64_t)cd & M62) == 0); cd >>= 62; + VERIFY_CHECK(((int64_t)ce & M62) == 0); ce >>= 62; + /* Compute limb 1 of t*[d,e]+modulus*[md,me], and store it as output limb 0 (= down shift). */ + cd += (int128_t)u * d1 + (int128_t)v * e1; + ce += (int128_t)q * d1 + (int128_t)r * e1; + if (modinfo->modulus.v[1]) { /* Optimize for the case where limb of modulus is zero. */ + cd += (int128_t)modinfo->modulus.v[1] * md; + ce += (int128_t)modinfo->modulus.v[1] * me; + } + d->v[0] = (int64_t)cd & M62; cd >>= 62; + e->v[0] = (int64_t)ce & M62; ce >>= 62; + /* Compute limb 2 of t*[d,e]+modulus*[md,me], and store it as output limb 1. */ + cd += (int128_t)u * d2 + (int128_t)v * e2; + ce += (int128_t)q * d2 + (int128_t)r * e2; + if (modinfo->modulus.v[2]) { /* Optimize for the case where limb of modulus is zero. */ + cd += (int128_t)modinfo->modulus.v[2] * md; + ce += (int128_t)modinfo->modulus.v[2] * me; + } + d->v[1] = (int64_t)cd & M62; cd >>= 62; + e->v[1] = (int64_t)ce & M62; ce >>= 62; + /* Compute limb 3 of t*[d,e]+modulus*[md,me], and store it as output limb 2. */ + cd += (int128_t)u * d3 + (int128_t)v * e3; + ce += (int128_t)q * d3 + (int128_t)r * e3; + if (modinfo->modulus.v[3]) { /* Optimize for the case where limb of modulus is zero. */ + cd += (int128_t)modinfo->modulus.v[3] * md; + ce += (int128_t)modinfo->modulus.v[3] * me; + } + d->v[2] = (int64_t)cd & M62; cd >>= 62; + e->v[2] = (int64_t)ce & M62; ce >>= 62; + /* Compute limb 4 of t*[d,e]+modulus*[md,me], and store it as output limb 3. */ + cd += (int128_t)u * d4 + (int128_t)v * e4; + ce += (int128_t)q * d4 + (int128_t)r * e4; + cd += (int128_t)modinfo->modulus.v[4] * md; + ce += (int128_t)modinfo->modulus.v[4] * me; + d->v[3] = (int64_t)cd & M62; cd >>= 62; + e->v[3] = (int64_t)ce & M62; ce >>= 62; + /* What remains is limb 5 of t*[d,e]+modulus*[md,me]; store it as output limb 4. */ + d->v[4] = (int64_t)cd; + e->v[4] = (int64_t)ce; +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, -2) > 0); /* d > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(d, 5, &modinfo->modulus, 1) < 0); /* d < modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, -2) > 0); /* e > -2*modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, 1) < 0); /* e < modulus */ +#endif +} + +/* Compute (t/2^62) * [f, g], where t is a transition matrix scaled by 2^62. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + const int64_t f0 = f->v[0], f1 = f->v[1], f2 = f->v[2], f3 = f->v[3], f4 = f->v[4]; + const int64_t g0 = g->v[0], g1 = g->v[1], g2 = g->v[2], g3 = g->v[3], g4 = g->v[4]; + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + int128_t cf, cg; + /* Start computing t*[f,g]. */ + cf = (int128_t)u * f0 + (int128_t)v * g0; + cg = (int128_t)q * f0 + (int128_t)r * g0; + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int64_t)cf & M62) == 0); cf >>= 62; + VERIFY_CHECK(((int64_t)cg & M62) == 0); cg >>= 62; + /* Compute limb 1 of t*[f,g], and store it as output limb 0 (= down shift). */ + cf += (int128_t)u * f1 + (int128_t)v * g1; + cg += (int128_t)q * f1 + (int128_t)r * g1; + f->v[0] = (int64_t)cf & M62; cf >>= 62; + g->v[0] = (int64_t)cg & M62; cg >>= 62; + /* Compute limb 2 of t*[f,g], and store it as output limb 1. */ + cf += (int128_t)u * f2 + (int128_t)v * g2; + cg += (int128_t)q * f2 + (int128_t)r * g2; + f->v[1] = (int64_t)cf & M62; cf >>= 62; + g->v[1] = (int64_t)cg & M62; cg >>= 62; + /* Compute limb 3 of t*[f,g], and store it as output limb 2. */ + cf += (int128_t)u * f3 + (int128_t)v * g3; + cg += (int128_t)q * f3 + (int128_t)r * g3; + f->v[2] = (int64_t)cf & M62; cf >>= 62; + g->v[2] = (int64_t)cg & M62; cg >>= 62; + /* Compute limb 4 of t*[f,g], and store it as output limb 3. */ + cf += (int128_t)u * f4 + (int128_t)v * g4; + cg += (int128_t)q * f4 + (int128_t)r * g4; + f->v[3] = (int64_t)cf & M62; cf >>= 62; + g->v[3] = (int64_t)cg & M62; cg >>= 62; + /* What remains is limb 5 of t*[f,g]; store it as output limb 4. */ + f->v[4] = (int64_t)cf; + g->v[4] = (int64_t)cg; +} + +/* Compute (t/2^62) * [f, g], where t is a transition matrix for 62 divsteps. + * + * Version that operates on a variable number of limbs in f and g. + * + * This implements the update_fg function from the explanation. + */ +static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) { + const int64_t M62 = (int64_t)(UINT64_MAX >> 2); + const int64_t u = t->u, v = t->v, q = t->q, r = t->r; + int64_t fi, gi; + int128_t cf, cg; + int i; + VERIFY_CHECK(len > 0); + /* Start computing t*[f,g]. */ + fi = f->v[0]; + gi = g->v[0]; + cf = (int128_t)u * fi + (int128_t)v * gi; + cg = (int128_t)q * fi + (int128_t)r * gi; + /* Verify that the bottom 62 bits of the result are zero, and then throw them away. */ + VERIFY_CHECK(((int64_t)cf & M62) == 0); cf >>= 62; + VERIFY_CHECK(((int64_t)cg & M62) == 0); cg >>= 62; + /* Now iteratively compute limb i=1..len of t*[f,g], and store them in output limb i-1 (shifting + * down by 62 bits). */ + for (i = 1; i < len; ++i) { + fi = f->v[i]; + gi = g->v[i]; + cf += (int128_t)u * fi + (int128_t)v * gi; + cg += (int128_t)q * fi + (int128_t)r * gi; + f->v[i - 1] = (int64_t)cf & M62; cf >>= 62; + g->v[i - 1] = (int64_t)cg & M62; cg >>= 62; + } + /* What remains is limb (len) of t*[f,g]; store it as output limb (len-1). */ + f->v[len - 1] = (int64_t)cf; + g->v[len - 1] = (int64_t)cg; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (constant time in x). */ +static void secp256k1_modinv64(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, zeta=-1. */ + secp256k1_modinv64_signed62 d = {{0, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 e = {{1, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 f = modinfo->modulus; + secp256k1_modinv64_signed62 g = *x; + int i; + int64_t zeta = -1; /* zeta = -(delta+1/2); delta starts at 1/2. */ + + /* Do 10 iterations of 59 divsteps each = 590 divsteps. This suffices for 256-bit inputs. */ + for (i = 0; i < 10; ++i) { + /* Compute transition matrix and new zeta after 59 divsteps. */ + secp256k1_modinv64_trans2x2 t; + zeta = secp256k1_modinv64_divsteps_59(zeta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv64_update_de_62(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + secp256k1_modinv64_update_fg_62(&f, &g, &t); +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + } + + /* At this point sufficient iterations have been performed that g must have reached 0 + * and (if g was not originally 0) f must now equal +/- GCD of the initial f, g + * values i.e. +/- 1, and d now contains +/- the modular inverse. */ +#ifdef VERIFY + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &SECP256K1_SIGNED62_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and |f|=modulus) */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, -1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, 1) == 0 || + (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + (secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, 1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->modulus, -1) == 0))); +#endif + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv64_normalize_62(&d, f.v[4], modinfo); + *x = d; +} + +/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (variable time). */ +static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo) { + /* Start with d=0, e=1, f=modulus, g=x, eta=-1. */ + secp256k1_modinv64_signed62 d = {{0, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 e = {{1, 0, 0, 0, 0}}; + secp256k1_modinv64_signed62 f = modinfo->modulus; + secp256k1_modinv64_signed62 g = *x; +#ifdef VERIFY + int i = 0; +#endif + int j, len = 5; + int64_t eta = -1; /* eta = -delta; delta is initially 1 */ + int64_t cond, fn, gn; + + /* Do iterations of 62 divsteps each until g=0. */ + while (1) { + /* Compute transition matrix and new eta after 62 divsteps. */ + secp256k1_modinv64_trans2x2 t; + eta = secp256k1_modinv64_divsteps_62_var(eta, f.v[0], g.v[0], &t); + /* Update d,e using that transition matrix. */ + secp256k1_modinv64_update_de_62(&d, &e, &t, modinfo); + /* Update f,g using that transition matrix. */ +#ifdef VERIFY + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + secp256k1_modinv64_update_fg_62_var(len, &f, &g, &t); + /* If the bottom limb of g is zero, there is a chance that g=0. */ + if (g.v[0] == 0) { + cond = 0; + /* Check if the other limbs are also 0. */ + for (j = 1; j < len; ++j) { + cond |= g.v[j]; + } + /* If so, we're done. */ + if (cond == 0) break; + } + + /* Determine if len>1 and limb (len-1) of both f and g is 0 or -1. */ + fn = f.v[len - 1]; + gn = g.v[len - 1]; + cond = ((int64_t)len - 2) >> 63; + cond |= fn ^ (fn >> 63); + cond |= gn ^ (gn >> 63); + /* If so, reduce length, propagating the sign of f and g's top limb into the one below. */ + if (cond == 0) { + f.v[len - 2] |= (uint64_t)fn << 62; + g.v[len - 2] |= (uint64_t)gn << 62; + --len; + } +#ifdef VERIFY + VERIFY_CHECK(++i < 12); /* We should never need more than 12*62 = 744 divsteps */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, -1) > 0); /* f > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) <= 0); /* f <= modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, -1) > 0); /* g > -modulus */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &modinfo->modulus, 1) < 0); /* g < modulus */ +#endif + } + + /* At this point g is 0 and (if g was not originally 0) f must now equal +/- GCD of + * the initial f, g values i.e. +/- 1, and d now contains +/- the modular inverse. */ +#ifdef VERIFY + /* g == 0 */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &SECP256K1_SIGNED62_ONE, 0) == 0); + /* |f| == 1, or (x == 0 and d == 0 and |f|=modulus) */ + VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, -1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, 1) == 0 || + (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 && + (secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, 1) == 0 || + secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->modulus, -1) == 0))); +#endif + + /* Optionally negate d, normalize to [0,modulus), and return it. */ + secp256k1_modinv64_normalize_62(&d, f.v[len - 1], modinfo); + *x = d; +} + +#endif /* SECP256K1_MODINV64_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/ecdh/main_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/ecdh/main_impl.h new file mode 100644 index 00000000..5408c9de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/ecdh/main_impl.h @@ -0,0 +1,71 @@ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDH_MAIN_H +#define SECP256K1_MODULE_ECDH_MAIN_H + +#include "../../../include/secp256k1_ecdh.h" +#include "../../ecmult_const_impl.h" + +static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { + unsigned char version = (y32[31] & 0x01) | 0x02; + secp256k1_sha256 sha; + (void)data; + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, &version, 1); + secp256k1_sha256_write(&sha, x32, 32); + secp256k1_sha256_finalize(&sha, output); + + return 1; +} + +const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; +const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; + +int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp, void *data) { + int ret = 0; + int overflow = 0; + secp256k1_gej res; + secp256k1_ge pt; + secp256k1_scalar s; + unsigned char x[32]; + unsigned char y[32]; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(point != NULL); + ARG_CHECK(scalar != NULL); + + if (hashfp == NULL) { + hashfp = secp256k1_ecdh_hash_function_default; + } + + secp256k1_pubkey_load(ctx, &pt, point); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + + overflow |= secp256k1_scalar_is_zero(&s); + secp256k1_scalar_cmov(&s, &secp256k1_scalar_one, overflow); + + secp256k1_ecmult_const(&res, &pt, &s, 256); + secp256k1_ge_set_gej(&pt, &res); + + /* Compute a hash of the point */ + secp256k1_fe_normalize(&pt.x); + secp256k1_fe_normalize(&pt.y); + secp256k1_fe_get_b32(x, &pt.x); + secp256k1_fe_get_b32(y, &pt.y); + + ret = hashfp(output, x, y, data); + + memset(x, 0, 32); + memset(y, 0, 32); + secp256k1_scalar_clear(&s); + + return !!ret & !overflow; +} + +#endif /* SECP256K1_MODULE_ECDH_MAIN_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/extrakeys/main_impl2.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/extrakeys/main_impl2.h new file mode 100644 index 00000000..e1003052 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/extrakeys/main_impl2.h @@ -0,0 +1,284 @@ +/*********************************************************************** + * Copyright (c) 2020 Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H +#define SECP256K1_MODULE_EXTRAKEYS_MAIN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_extrakeys.h" + +static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) { + return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey); +} + +static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge) { + secp256k1_pubkey_save((secp256k1_pubkey *) pubkey, ge); +} + +int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) { + secp256k1_ge pk; + secp256k1_fe x; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(input32 != NULL); + + if (!secp256k1_fe_set_b32(&x, input32)) { + return 0; + } + if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) { + return 0; + } + if (!secp256k1_ge_is_in_correct_subgroup(&pk)) { + return 0; + } + secp256k1_xonly_pubkey_save(pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) { + secp256k1_ge pk; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output32 != NULL); + memset(output32, 0, 32); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + secp256k1_fe_get_b32(output32, &pk.x); + return 1; +} + +int secp256k1_xonly_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_xonly_pubkey* pk0, const secp256k1_xonly_pubkey* pk1) { + unsigned char out[2][32]; + const secp256k1_xonly_pubkey* pk[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + pk[0] = pk0; pk[1] = pk1; + for (i = 0; i < 2; i++) { + /* If the public key is NULL or invalid, xonly_pubkey_serialize will + * call the illegal_callback and return 0. In that case we will + * serialize the key as all zeros which is less than any valid public + * key. This results in consistent comparisons even if NULL or invalid + * pubkeys are involved and prevents edge cases such as sorting + * algorithms that use this function and do not terminate as a + * result. */ + if (!secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) { + /* Note that xonly_pubkey_serialize should already set the output to + * zero in that case, but it's not guaranteed by the API, we can't + * test it and writing a VERIFY_CHECK is more complex than + * explicitly memsetting (again). */ + memset(out[i], 0, sizeof(out[i])); + } + } + return secp256k1_memcmp_var(out[0], out[1], sizeof(out[1])); +} + +/** Keeps a group element as is if it has an even Y and otherwise negates it. + * y_parity is set to 0 in the former case and to 1 in the latter case. + * Requires that the coordinates of r are normalized. */ +static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r) { + int y_parity = 0; + VERIFY_CHECK(!secp256k1_ge_is_infinity(r)); + + if (secp256k1_fe_is_odd(&r->y)) { + secp256k1_fe_negate(&r->y, &r->y, 1); + y_parity = 1; + } + return y_parity; +} + +int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context* ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) { + secp256k1_ge pk; + int tmp; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(xonly_pubkey != NULL); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + tmp = secp256k1_extrakeys_ge_even_y(&pk); + if (pk_parity != NULL) { + *pk_parity = tmp; + } + secp256k1_xonly_pubkey_save(xonly_pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { + secp256k1_ge pk; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output_pubkey != NULL); + memset(output_pubkey, 0, sizeof(*output_pubkey)); + ARG_CHECK(internal_pubkey != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) + || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { + return 0; + } + secp256k1_pubkey_save(output_pubkey, &pk); + return 1; +} + +int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context* ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { + secp256k1_ge pk; + unsigned char pk_expected32[32]; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(internal_pubkey != NULL); + ARG_CHECK(tweaked_pubkey32 != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey) + || !secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) { + return 0; + } + secp256k1_fe_normalize_var(&pk.x); + secp256k1_fe_normalize_var(&pk.y); + secp256k1_fe_get_b32(pk_expected32, &pk.x); + + return secp256k1_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0 + && secp256k1_fe_is_odd(&pk.y) == tweaked_pk_parity; +} + +static void secp256k1_keypair_save(secp256k1_keypair *keypair, const secp256k1_scalar *sk, secp256k1_ge *pk) { + secp256k1_scalar_get_b32(&keypair->data[0], sk); + secp256k1_pubkey_save((secp256k1_pubkey *)&keypair->data[32], pk); +} + + +static int secp256k1_keypair_seckey_load(const secp256k1_context* ctx, secp256k1_scalar *sk, const secp256k1_keypair *keypair) { + int ret; + + ret = secp256k1_scalar_set_b32_seckey(sk, &keypair->data[0]); + /* We can declassify ret here because sk is only zero if a keypair function + * failed (which zeroes the keypair) and its return value is ignored. */ + secp256k1_declassify(ctx, &ret, sizeof(ret)); + ARG_CHECK(ret); + return ret; +} + +/* Load a keypair into pk and sk (if non-NULL). This function declassifies pk + * and ARG_CHECKs that the keypair is not invalid. It always initializes sk and + * pk with dummy values. */ +static int secp256k1_keypair_load(const secp256k1_context* ctx, secp256k1_scalar *sk, secp256k1_ge *pk, const secp256k1_keypair *keypair) { + int ret; + const secp256k1_pubkey *pubkey = (const secp256k1_pubkey *)&keypair->data[32]; + + /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's + * invalid. */ + secp256k1_declassify(ctx, pubkey, sizeof(*pubkey)); + ret = secp256k1_pubkey_load(ctx, pk, pubkey); + if (sk != NULL) { + ret = ret && secp256k1_keypair_seckey_load(ctx, sk, keypair); + } + if (!ret) { + *pk = secp256k1_ge_const_g; + if (sk != NULL) { + *sk = secp256k1_scalar_one; + } + } + return ret; +} + +int secp256k1_keypair_create(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *seckey32) { + secp256k1_scalar sk; + secp256k1_ge pk; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(keypair != NULL); + memset(keypair, 0, sizeof(*keypair)); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey32 != NULL); + + ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32); + secp256k1_keypair_save(keypair, &sk, &pk); + secp256k1_memczero(keypair, sizeof(*keypair), !ret); + + secp256k1_scalar_clear(&sk); + return ret; +} + +int secp256k1_keypair_sec(const secp256k1_context* ctx, unsigned char *seckey, const secp256k1_keypair *keypair) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + memset(seckey, 0, 32); + ARG_CHECK(keypair != NULL); + + memcpy(seckey, &keypair->data[0], 32); + return 1; +} + +int secp256k1_keypair_pub(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_keypair *keypair) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(keypair != NULL); + + memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey)); + return 1; +} + +int secp256k1_keypair_xonly_pub(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, int *pk_parity, const secp256k1_keypair *keypair) { + secp256k1_ge pk; + int tmp; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(keypair != NULL); + + if (!secp256k1_keypair_load(ctx, NULL, &pk, keypair)) { + return 0; + } + tmp = secp256k1_extrakeys_ge_even_y(&pk); + if (pk_parity != NULL) { + *pk_parity = tmp; + } + secp256k1_xonly_pubkey_save(pubkey, &pk); + + return 1; +} + +int secp256k1_keypair_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) { + secp256k1_ge pk; + secp256k1_scalar sk; + int y_parity; + int ret; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(keypair != NULL); + ARG_CHECK(tweak32 != NULL); + + ret = secp256k1_keypair_load(ctx, &sk, &pk, keypair); + memset(keypair, 0, sizeof(*keypair)); + + y_parity = secp256k1_extrakeys_ge_even_y(&pk); + if (y_parity == 1) { + secp256k1_scalar_negate(&sk, &sk); + } + + ret &= secp256k1_ec_seckey_tweak_add_helper(&sk, tweak32); + ret &= secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32); + + secp256k1_declassify(ctx, &ret, sizeof(ret)); + if (ret) { + secp256k1_keypair_save(keypair, &sk, &pk); + } + + secp256k1_scalar_clear(&sk); + return ret; +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/recovery/main_impl3.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/recovery/main_impl3.h new file mode 100644 index 00000000..e7906eb6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/recovery/main_impl3.h @@ -0,0 +1,159 @@ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H +#define SECP256K1_MODULE_RECOVERY_MAIN_H + +#include "../../../include/secp256k1_recovery.h" + +static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } + *recid = sig->data[64]; +} + +static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } + sig->data[64] = recid; +} + +int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { + secp256k1_scalar r, s; + int ret = 1; + int overflow = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + ARG_CHECK(recid >= 0 && recid <= 3); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); + } else { + memset(sig, 0, sizeof(*sig)); + } + return ret; +} + +int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(recid != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { + secp256k1_scalar r, s; + int recid; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; +} + +static int secp256k1_ecdsa_sig_recover(const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { + unsigned char brx[32]; + secp256k1_fe fx; + secp256k1_ge x; + secp256k1_gej xj; + secp256k1_scalar rn, u1, u2; + secp256k1_gej qj; + int r; + + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { + return 0; + } + + secp256k1_scalar_get_b32(brx, sigr); + r = secp256k1_fe_set_b32(&fx, brx); + (void)r; + VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ + if (recid & 2) { + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { + return 0; + } + secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); + } + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { + return 0; + } + secp256k1_gej_set_ge(&xj, &x); + secp256k1_scalar_inverse_var(&rn, sigr); + secp256k1_scalar_mul(&u1, &rn, message); + secp256k1_scalar_negate(&u1, &u1); + secp256k1_scalar_mul(&u2, &rn, sigs); + secp256k1_ecmult(&qj, &xj, &u2, &u1); + secp256k1_ge_set_gej_var(pubkey, &qj); + return !secp256k1_gej_is_infinity(&qj); +} + +int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + int ret, recid; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, &recid, msghash32, seckey, noncefp, noncedata); + secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); + return ret; +} + +int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + int recid; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); + VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ + secp256k1_scalar_set_b32(&m, msghash32, NULL); + if (secp256k1_ecdsa_sig_recover(&r, &s, &q, &m, recid)) { + secp256k1_pubkey_save(pubkey, &q); + return 1; + } else { + memset(pubkey, 0, sizeof(*pubkey)); + return 0; + } +} + +#endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/schnorrsig/main_impl4.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/schnorrsig/main_impl4.h new file mode 100644 index 00000000..cd651591 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/modules/schnorrsig/main_impl4.h @@ -0,0 +1,267 @@ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H +#define SECP256K1_MODULE_SCHNORRSIG_MAIN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_schnorrsig.h" +#include "../../hash.h" + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */ +static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x46615b35ul; + sha->s[1] = 0xf4bfbff7ul; + sha->s[2] = 0x9f8dc671ul; + sha->s[3] = 0x83627ab3ul; + sha->s[4] = 0x60217180ul; + sha->s[5] = 0x57358661ul; + sha->s[6] = 0x21a29e54ul; + sha->s[7] = 0x68b07b4cul; + + sha->bytes = 64; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */ +static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x24dd3219ul; + sha->s[1] = 0x4eba7e70ul; + sha->s[2] = 0xca0fabb9ul; + sha->s[3] = 0x0fa3166dul; + sha->s[4] = 0x3afbe4b1ul; + sha->s[5] = 0x4c44df97ul; + sha->s[6] = 0x4aac2739ul; + sha->s[7] = 0x249e850aul; + + sha->bytes = 64; +} + +/* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340 + * by using the correct tagged hash function. */ +static const unsigned char bip340_algo[13] = "BIP0340/nonce"; + +static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC; + +static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + secp256k1_sha256 sha; + unsigned char masked_key[32]; + int i; + + if (algo == NULL) { + return 0; + } + + if (data != NULL) { + secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha); + secp256k1_sha256_write(&sha, data, 32); + secp256k1_sha256_finalize(&sha, masked_key); + for (i = 0; i < 32; i++) { + masked_key[i] ^= key32[i]; + } + } else { + /* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */ + static const unsigned char ZERO_MASK[32] = { + 84, 241, 105, 207, 201, 226, 229, 114, + 116, 128, 68, 31, 144, 186, 37, 196, + 136, 244, 97, 199, 11, 94, 165, 220, + 170, 247, 175, 105, 39, 10, 165, 20 + }; + for (i = 0; i < 32; i++) { + masked_key[i] = key32[i] ^ ZERO_MASK[i]; + } + } + + /* Tag the hash with algo which is important to avoid nonce reuse across + * algorithms. If this nonce function is used in BIP-340 signing as defined + * in the spec, an optimized tagging implementation is used. */ + if (algolen == sizeof(bip340_algo) + && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) { + secp256k1_nonce_function_bip340_sha256_tagged(&sha); + } else { + secp256k1_sha256_initialize_tagged(&sha, algo, algolen); + } + + /* Hash masked-key||pk||msg using the tagged hash as per the spec */ + secp256k1_sha256_write(&sha, masked_key, 32); + secp256k1_sha256_write(&sha, xonly_pk32, 32); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, nonce32); + return 1; +} + +const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340; + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */ +static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) { + secp256k1_sha256_initialize(sha); + sha->s[0] = 0x9cecba11ul; + sha->s[1] = 0x23925381ul; + sha->s[2] = 0x11679112ul; + sha->s[3] = 0xd1627e0ful; + sha->s[4] = 0x97c87550ul; + sha->s[5] = 0x003cc765ul; + sha->s[6] = 0x90f61164ul; + sha->s[7] = 0x33e9b66aul; + sha->bytes = 64; +} + +static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32) +{ + unsigned char buf[32]; + secp256k1_sha256 sha; + + /* tagged hash(r.x, pk.x, msg) */ + secp256k1_schnorrsig_sha256_tagged(&sha); + secp256k1_sha256_write(&sha, r32, 32); + secp256k1_sha256_write(&sha, pubkey32, 32); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, buf); + /* Set scalar e to the challenge hash modulo the curve order as per + * BIP340. */ + secp256k1_scalar_set_b32(e, buf, NULL); +} + +static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) { + secp256k1_scalar sk; + secp256k1_scalar e; + secp256k1_scalar k; + secp256k1_gej rj; + secp256k1_ge pk; + secp256k1_ge r; + unsigned char buf[32] = { 0 }; + unsigned char pk_buf[32]; + unsigned char seckey[32]; + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(msg != NULL || msglen == 0); + ARG_CHECK(keypair != NULL); + + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_bip340; + } + + ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair); + /* Because we are signing for a x-only pubkey, the secret key is negated + * before signing if the point corresponding to the secret key does not + * have an even Y. */ + if (secp256k1_fe_is_odd(&pk.y)) { + secp256k1_scalar_negate(&sk, &sk); + } + + secp256k1_scalar_get_b32(seckey, &sk); + secp256k1_fe_get_b32(pk_buf, &pk.x); + ret &= !!noncefp(buf, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata); + secp256k1_scalar_set_b32(&k, buf, NULL); + ret &= !secp256k1_scalar_is_zero(&k); + secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret); + + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k); + secp256k1_ge_set_gej(&r, &rj); + + /* We declassify r to allow using it as a branch point. This is fine + * because r is not a secret. */ + secp256k1_declassify(ctx, &r, sizeof(r)); + secp256k1_fe_normalize_var(&r.y); + if (secp256k1_fe_is_odd(&r.y)) { + secp256k1_scalar_negate(&k, &k); + } + secp256k1_fe_normalize_var(&r.x); + secp256k1_fe_get_b32(&sig64[0], &r.x); + + secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf); + secp256k1_scalar_mul(&e, &e, &sk); + secp256k1_scalar_add(&e, &e, &k); + secp256k1_scalar_get_b32(&sig64[32], &e); + + secp256k1_memczero(sig64, 64, !ret); + secp256k1_scalar_clear(&k); + secp256k1_scalar_clear(&sk); + memset(seckey, 0, sizeof(seckey)); + + return ret; +} + +int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) { + /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */ + return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32); +} + +int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) { + return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32); +} + +int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) { + secp256k1_nonce_function_hardened noncefp = NULL; + void *ndata = NULL; + VERIFY_CHECK(ctx != NULL); + + if (extraparams != NULL) { + ARG_CHECK(secp256k1_memcmp_var(extraparams->magic, + schnorrsig_extraparams_magic, + sizeof(extraparams->magic)) == 0); + noncefp = extraparams->noncefp; + ndata = extraparams->ndata; + } + return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata); +} + +int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) { + secp256k1_scalar s; + secp256k1_scalar e; + secp256k1_gej rj; + secp256k1_ge pk; + secp256k1_gej pkj; + secp256k1_fe rx; + secp256k1_ge r; + unsigned char buf[32]; + int overflow; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(msg != NULL || msglen == 0); + ARG_CHECK(pubkey != NULL); + + if (!secp256k1_fe_set_b32(&rx, &sig64[0])) { + return 0; + } + + secp256k1_scalar_set_b32(&s, &sig64[32], &overflow); + if (overflow) { + return 0; + } + + if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { + return 0; + } + + /* Compute e. */ + secp256k1_fe_get_b32(buf, &pk.x); + secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf); + + /* Compute rj = s*G + (-e)*pkj */ + secp256k1_scalar_negate(&e, &e); + secp256k1_gej_set_ge(&pkj, &pk); + secp256k1_ecmult(&rj, &pkj, &e, &s); + + secp256k1_ge_set_gej_var(&r, &rj); + if (secp256k1_ge_is_infinity(&r)) { + return 0; + } + + secp256k1_fe_normalize_var(&r.y); + return !secp256k1_fe_is_odd(&r.y) && + secp256k1_fe_equal_var(&rx, &r.x); +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.c b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.c new file mode 100644 index 00000000..3e67f37b --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.c @@ -0,0 +1,16460 @@ +/* This file was automatically generated by precompute_ecmult. */ +/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and + * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G. + */ +#if defined HAVE_CONFIG_H +# include "libsecp256k1-config.h" +#endif +#include "../include/secp256k1.h" +#include "group.h" +#include "ecmult.h" +#include "precomputed_ecmult.h" +#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u) +#if ECMULT_WINDOW_SIZE > 15 + #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting precomputed_ecmult.c before the build. +#endif +#ifdef EXHAUSTIVE_TEST_ORDER +# error Cannot compile precomputed_ecmult.c in exhaustive test mode +#endif /* EXHAUSTIVE_TEST_ORDER */ +#define WINDOW_G ECMULT_WINDOW_SIZE +const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)] = { + S(79be667e,f9dcbbac,55a06295,ce870b07,29bfcdb,2dce28d9,59f2815b,16f81798,483ada77,26a3c465,5da4fbfc,e1108a8,fd17b448,a6855419,9c47d08f,fb10d4b8) +#if WINDOW_G > 2 +,S(f9308a01,9258c310,49344f85,f89d5229,b531c845,836f99b0,8601f113,bce036f9,388f7b0f,632de814,fe337e6,2a37f356,6500a999,34c2231b,6cb9fd75,84b8e672) +#endif +#if WINDOW_G > 3 +,S(2f8bde4d,1a072093,55b4a725,a5c5128,e88b84bd,dc619ab7,cba8d569,b240efe4,d8ac2226,36e5e3d6,d4dba9dd,a6c9c426,f788271b,ab0d6840,dca87d3a,a6ac62d6) +,S(5cbdf064,6e5db4ea,a398f365,f2ea7a0e,3d419b7e,330e39c,e92bdded,cac4f9bc,6aebca40,ba255960,a3178d6d,861a54db,a813d0b8,13fde7b5,a5082628,87264da) +#endif +#if WINDOW_G > 4 +,S(acd484e2,f0c7f653,9ad178a,9f559abd,e0979697,4c57e714,c35f110d,fc27ccbe,cc338921,b0a7d9fd,64380971,763b61e9,add888a4,375f8e0f,5cc262a,c64f9c37) +,S(774ae7f8,58a9411e,5ef4246b,70c65aac,5649980b,e5c17891,bbec1789,5da008cb,d984a032,eb6b5e19,243dd56,d7b7b365,372db1e2,dff9d6a8,301d74c9,c953c61b) +,S(f28773c2,d975288b,c7d1d205,c3748651,b075fbc6,610e58cd,deeddf8f,19405aa8,ab0902e,8d880a89,758212eb,65cdaf47,3a1a06da,521fa91f,29b5cb52,db03ed81) +,S(d7924d4f,7d43ea96,5a465ae3,95ff411,31e5946f,3c85f79e,44adbcf8,e27e080e,581e2872,a86c72a6,83842ec2,28cc6def,ea40af2b,d896d3a5,c504dc9f,f6a26b58) +#endif +#if WINDOW_G > 5 +,S(defdea4c,db677750,a420fee8,7eacf21,eb9898ae,79b97687,66e4faa0,4a2d4a34,4211ab06,94635168,e997b0ea,d2a93dae,ced1f4a0,4a95c0f6,cfb199f6,9e56eb77) +,S(2b4ea0a7,97a443d2,93ef5cff,444f4979,f06acfeb,d7e86d27,74756561,38385b6c,85e89bc0,37945d93,b343083b,5a1c8613,1a01f60c,50269763,b570c854,e5c09b7a) +,S(352bbf4a,4cdd1256,4f93fa33,2ce33330,1d9ad402,71f81071,81340aef,25be59d5,321eb407,5348f534,d59c1825,9dda3e1f,4a1b3b2e,71b1039c,67bd3d8b,cf81998c) +,S(2fa2104d,6b38d11b,2300105,59879124,e42ab8df,eff5ff29,dc9cdadd,4ecacc3f,2de1068,295dd865,b6456933,5bd5dd80,181d70ec,fc882648,423ba76b,532b7d67) +,S(9248279b,9b4d68d,ab21a9b0,66edda83,263c3d84,e09572e2,69ca0cd7,f5453714,73016f7b,f234aade,5d1aa71b,dea2b1ff,3fc0de2a,887912ff,e54a32ce,97cb3402) +,S(daed4f2b,e3a8bf27,8e70132f,b0beb752,2f570e14,4bf615c0,7e996d44,3dee8729,a69dce4a,7d6c98e8,d4a1aca8,7ef8d700,3f83c230,f3afa726,ab40e522,90be1c55) +,S(c44d12c7,65d812e,8acf28d7,cbb19f90,11ecd9e9,fdf281b0,e6a3b5e8,7d22e7db,2119a460,ce326cdc,76c45926,c982fdac,e106e86,1edf61c5,a039063f,e0e6482) +,S(6a245bf6,dc698504,c89a20cf,ded60853,152b6953,36c28063,b61c65cb,d269e6b4,e022cf42,c2bd4a70,8b3f5126,f16a24ad,8b33ba48,d0423b6e,fd5e6348,100d8a82) +#endif +#if WINDOW_G > 6 +,S(1697ffa6,fd9de627,c077e3d2,fe541084,ce13300b,bec1146,f95ae57f,d0bd6a5,b9c398f1,86806f5d,27561506,e4557433,a2cf1500,9e498ae7,adee9d63,d01b2396) +,S(605bdb01,9981718b,986d0f07,e834cb0d,9deb8360,ffb7f61d,f982345e,f27a7479,2972d2d,e4f8d206,81a78d93,ec96fe23,c26bfae8,4fb14db4,3b01e1e9,56b8c49) +,S(62d14dab,4150bf49,7402fdc4,5a215e10,dcb01c35,4959b10c,fe31c7e9,d87ff33d,80fc06bd,8cc5b010,98088a19,50eed0db,1aa1329,67ab4722,35f56424,83b25eaf) +,S(80c60ad0,40f27da,de5b4b06,c408e56b,2c50e9f5,6b9b8b42,5e555c2f,86308b6f,1c38303f,1cc5c30f,26e66bad,7fe72f70,a65eed4c,be7024eb,1aa01f56,430bd57a) +,S(7a9375ad,6167ad54,aa74c634,8cc54d34,4cc5dc94,87d84704,9d5eabb0,fa03c8fb,d0e3fa9,eca87269,9559e0d,79269046,bdc59ea1,c70ce2b,2d499ec,224dc7f7) +,S(d528ecd9,b696b54c,907a9ed0,45447a79,bb408ec3,9b68df50,4bb51f45,9bc3ffc9,eecf4125,3136e5f9,9966f218,81fd656e,bc434540,5c520dbc,63465b5,21409933) +,S(49370a4,b5f43412,ea25f514,e8ecdad0,5266115e,4a7ecb13,87231808,f8b45963,758f3f41,afd6ed42,8b3081b0,512fd62a,54c3f3af,bb5b6764,b653052a,12949c9a) +,S(77f23093,6ee88cbb,d73df930,d64702ef,881d811e,e1498e2,f1c13eb1,fc345d74,958ef42a,7886b640,a08266e,9ba1b378,96c95330,d97077cb,be8eb3c7,671c60d6) +,S(f2dac991,cc4ce4b9,ea44887e,5c7c0bce,58c80074,ab9d4dba,eb28531b,7739f530,e0dedc9b,3b2f8dad,4da1f32d,ec2531df,9eb5fbeb,598e4fd,1a117dba,703a3c37) +,S(463b3d9f,662621fb,1b4be8fb,be252012,5a216cdf,c9dae3de,bcba4850,c690d45b,5ed430d7,8c296c35,43114306,dd8622d7,c622e27c,970a1de3,1cb377b0,1af7307e) +,S(f16f8042,44e46e2a,9232d4a,ff3b5997,6b98fac1,4328a2d1,a32496b4,9998f247,cedabd9b,82203f7e,13d206fc,df4e33d9,2a6c53c2,6e5cce26,d6579962,c4e31df6) +,S(caf75427,2dc84563,b0352b7a,14311af5,5d245315,ace27c65,369e15f7,151d41d1,cb474660,ef35f5f2,a41b643f,a5e46057,5f4fa9b7,962232a5,c32f9083,18a04476) +,S(2600ca4b,282cb986,f85d0f17,9979d8b,44a09c07,cb86d7c1,24497bc8,6f082120,4119b887,53c15bd6,a693b03f,cddbb45d,5ac6be74,ab5f0ef4,4b0be947,5a7e4b40) +,S(7635ca72,d7e8432c,338ec53c,d12220bc,1c48685,e24f7dc8,c602a774,6998e435,91b6496,9489d61,3d1d5e59,f78e6d7,4ecfc061,d57048ba,d9e76f30,2c5b9c61) +,S(754e3239,f325570c,dbbf4a87,deee8a66,b7f2b334,79d468fb,c1a50743,bf56cc18,673fb86,e5bda30f,b3cd0ed3,4ea49a0,23ee33d0,197a695d,c5d9809,3c536683) +,S(e3e6bd10,71a1e96a,ff57859c,82d570f0,33080066,1d1c952f,9fe26946,91d9b9e8,59c9e0bb,a394e76f,40c0aa58,379a3cb6,a5a22839,93e90c41,67002af4,920e37f5) +#endif +#if WINDOW_G > 7 +,S(186b483d,56a0338,26ae73d8,8f732985,c4ccb1f3,2ba35f4b,4cc47fdc,f04aa6eb,3b952d32,c67cf77e,2e17446e,204180ab,21fb8090,895138b4,a4a797f8,6e80888b) +,S(df9d70a6,b9876ce5,44c98561,f4be4f72,5442e6d2,b737d9c9,1a832172,4ce0963f,55eb2daf,d84d6ccd,5f862b78,5dc39d4a,b1572227,20ef9da2,17b8c45c,f2ba2417) +,S(5edd5cc2,3c51e87a,497ca815,d5dce0f8,ab52554f,849ed899,5de64c5f,34ce7143,efae9c8d,bc141306,61e8cec0,30c89ad0,c13c66c0,d17a2905,cdc706ab,7399a868) +,S(290798c2,b6476830,da12fe02,287e9e77,7aa3fba1,c355b17a,722d362f,84614fba,e38da76d,cd440621,988d00bc,f79af25d,5b29c094,db2a2314,6d003afd,41943e7a) +,S(af3c423a,95d9f5b3,54754ef,a150ac39,cd29552f,e3602573,62dfdece,f4053b45,f98a3fd8,31eb2b74,9a93b0e6,f35cfb40,c8cd5aa6,67a15581,bc2feded,498fd9c6) +,S(766dbb24,d134e745,cccaa28c,99bf2749,6bb66b2,6dcf98df,8d2fed50,d884249a,744b1152,eacbe5e3,8dcc8879,80da38b8,97584a65,fa06cedd,2c924f97,cbac5996) +,S(59dbf46f,8c94759b,a21277c3,3784f416,45f7b44f,6c596a58,ce92e666,191abe3e,c534ad44,175fbc30,f4ea6ce,648309a0,42ce739a,7919798c,d85e216c,4a307f6e) +,S(f13ada95,103c4537,305e691e,74e9a4a8,dd647e71,1a95e73c,b62dc601,8cfd87b8,e13817b4,4ee14de6,63bf4bc8,8341f32,6949e21a,6a75c257,778419b,daf5733d) +,S(7754b4fa,e8aced0,6d4167a2,c59cca4c,da1869c0,6ebadfb6,48855001,5a88522c,30e93e86,4e669d82,224b967c,3020b8fa,8d1e4e35,b6cbcc5,37a48b57,841163a2) +,S(948dcadf,5990e048,aa3874d4,6abef9d7,1858f95,de8041d2,a6828c99,e2262519,e491a425,37f6e597,d5d28a32,24b1bc25,df9154ef,bd2ef1d2,cbba2cae,5347d57e) +,S(79624144,50c76c16,89c7b48f,8202ec37,fb224cf5,ac0bfa15,70328a8a,3d7c77ab,100b610e,c4ffb476,d5c1fc1,33ef6f6b,12507a05,1f04ac57,60afa5b2,9db83437) +,S(35140878,34964b54,b15b1606,44d91548,5a169772,25b8847b,b0dd0851,37ec47ca,ef0afbb2,5620544,8e1652c4,8e8127fc,6039e77c,15c2378b,7e7d15a0,de293311) +,S(d3cc30ad,6b483e4b,c79ce2c9,dd8bc549,93e947eb,8df787b4,42943d3f,7b527eaf,8b378a22,d827278d,89c5e9be,8f9508ae,3c2ad462,90358630,afb34db0,4eede0a4) +,S(1624d847,80732860,ce1c78fc,bfefe08b,2b29823d,b913f649,3975ba0f,f4847610,68651cf9,b6da903e,914448c,6cd9d4ca,896878f5,282be4c8,cc06e2a4,4078575) +,S(733ce80d,a955a8a2,6902c956,33e62a98,5192474b,5af207da,6df7b4fd,5fc61cd4,f5435a2b,d2badf7d,485a4d8b,8db9fcce,3e1ef8e0,201e4578,c54673bc,1dc5ea1d) +,S(15d94412,54945064,cf1a1c33,bbd3b49f,8966c509,2171e699,ef258dfa,b81c045c,d56eb30b,69463e72,34f5137b,73b84177,434800ba,cebfc685,fc37bbe9,efe4070d) +,S(a1d0fcf2,ec9de675,b612136e,5ce70d27,1c21417c,9d2b8aaa,ac138599,d0717940,edd77f50,bcb5a3ca,b2e90737,309667f2,641462a5,4070f3d5,19212d39,c197a629) +,S(e22fbe15,c0af8ccc,5780c073,5f84dbe9,a790bade,e8245c06,c7ca3733,1cb36980,a855bab,ad5cd60c,88b430a6,9f53a1a7,a3828915,4964799b,e43d06d7,7d31da06) +,S(311091dd,9860e8e2,ee13473,c1155f5f,69635e39,4704eaa7,40094522,46cfa9b3,66db656f,87d1f04f,ffd1f047,88c06830,871ec5a6,4feee685,bd80f0b1,286d8374) +,S(34c1fd04,d301be89,b31c0442,d3e6ac24,883928b4,5a934078,1867d423,2ec2dbdf,9414685,e97b1b59,54bd46f7,30174136,d57f1cee,b487443d,c5321857,ba73abee) +,S(f219ea5d,6b54701c,1c14de5b,557eb42a,8d13f3ab,bcd08aff,cc2a5e6b,49b8d63,4cb95957,e83d40b0,f73af454,4cccf6b1,f4b08d3c,7b27fb8,d8c2962a,400766d1) +,S(d7b8740f,74a8fbaa,b1f683db,8f45de26,543a5490,bca62708,72369124,69a0b448,fa779681,28d9c92e,e1010f33,7ad4717e,ff15db5e,d3c049b3,411e0315,eaa4593b) +,S(32d31c22,2f8f6f0e,f86f7c98,d3a3335e,ad5bcd32,abdd9428,9fe4d309,1aa824bf,5f3032f5,892156e3,9ccd3d79,15b9e1da,2e6dac9e,6f26e961,118d14b8,462e1661) +,S(7461f371,914ab326,71045a15,5d9831ea,8793d77c,d59592c4,340f86cb,c18347b5,8ec0ba23,8b96bec0,cbdddcae,aa44254,2eee1ff5,c986ea6,b39847b3,cc092ff6) +,S(ee079adb,1df18600,74356a25,aa38206a,6d716b2c,3e67453d,287698ba,d7b2b2d6,8dc2412a,afe3be5c,4c5f37e0,ecc5f9f6,a446989a,f04c4e25,ebaac479,ec1c8c1e) +,S(16ec93e4,47ec83f0,467b1830,2ee620f7,e65de331,874c9dc7,2bfd8616,ba9da6b5,5e463115,e62fb40,d0e8c2a7,ca5804a3,9d58186a,50e49713,9626778e,25b0674d) +,S(eaa5f980,c245f6f0,38978290,afa70b6b,d8855897,f98b6aa4,85b96065,d537bd99,f65f5d3e,292c2e08,19a52839,1c994624,d784869d,7e6ea67f,b1804102,4edc07dc) +,S(78c9407,544ac132,692ee191,a024399,58ae0487,7151342e,a96c4b6b,35a49f51,f3e03191,69eb9b85,d5404795,539a5e68,fa1fbd58,3c064d24,62b675f1,94a3ddb4) +,S(494f4be2,19a1a770,16dcd838,431aea00,1cdc8ae,7a6fc688,726578d9,702857a5,42242a96,9283a5f3,39ba7f07,5e36ba2a,f925ce30,d767ed6e,55f4b031,880d562c) +,S(a598a803,da6d86c,6bc7f2f5,144ea549,d28211ea,58faa70e,bf4c1e66,5c1fe9b5,204b5d6f,84822c30,7e4b4a71,40737aec,23fc63b6,5b35f86a,10026dbd,2d864e6b) +,S(c4191636,5abb2b5d,9192f5f,2dbeafec,208f020f,12570a18,4dbadc3e,58595997,4f14351,d0087efa,49d245b3,28984989,d5caf945,f34bfc0,ed16e96b,58fa9913) +,S(841d6063,a586fa47,5a724604,da03bc5b,92a2e0d2,e0a36acf,e4c73a55,14742881,73867f5,9c0659e8,1904f9a1,c7543698,e62562d6,744c169c,e7a36de0,1a8d6154) +#endif +#if WINDOW_G > 8 +,S(5e95bb39,9a6971d3,76026947,f89bde2f,282b3381,928be4d,ed112ac4,d70e20d5,39f23f36,6809085b,eebfc711,81313775,a99c9aed,7d8ba38b,161384c7,46012865) +,S(36e4641a,53948fd4,76c39f8a,99fd974e,5ec07564,b5315d8b,f99471bc,a0ef2f66,d2424b1b,1abe4eb8,164227b0,85c9aa94,56ea1349,3fd563e0,6fd51cf5,694c78fc) +,S(336581e,a7bfbbb2,90c191a2,f507a41c,f5643842,170e914f,aeab27c2,c579f726,ead12168,595fe1be,99252129,b6e56b33,91f7ab14,10cd1e0e,f3dcdcab,d2fda224) +,S(8ab89816,dadfd6b6,a1f2634f,cf00ec84,3781025,ed6890c4,84974270,6bd43ede,6fdcef09,f2f6d0a0,44e654ae,f624136f,503d459c,3e898458,58a47a91,29cdd24e) +,S(1e33f1a7,46c9c577,8133344d,9299fcaa,20b0938e,8acff254,4bb40284,b8c5fb94,6066025,7dd11b3a,a9c8ed61,8d24edff,2306d320,f1d03010,e33a7d20,57f3b3b6) +,S(85b7c1dc,b3cec1b7,ee7f30de,d79dd20a,ed1f4cc,18cbcfcf,a410361f,d8f08f31,3d98a9cd,d026dd43,f39048f2,5a8847f4,fcafad18,95d7a633,c6fed3c3,5e999511) +,S(29df9fbd,8d9e4650,9275f4b1,25d6d45d,7fbe9a3b,878a7af8,72a28006,61ac5f51,b4c4fe9,9c775a60,6e2d8862,179139ff,da61dc86,1c019e55,cd2876eb,2a27d84b) +,S(a0b1cae0,6b0a847a,3fea6e67,1aaf8adf,dfe58ca2,f768105c,8082b2e4,49fce252,ae434102,edde0958,ec4b19d9,17a6a28e,6b72da18,34aff0e6,50f04950,3a296cf2) +,S(4e8ceaf,b9b3e9a1,36dc7ff6,7e840295,b499dfb3,b2133e4b,a113f2e4,c0e121e5,cf217411,8c8b6d7a,4b48f6d5,34ce5c79,422c086a,63460502,b827ce62,a326683c) +,S(d24a44e0,47e19b6f,5afb81c7,ca2f6908,a507668,9a010919,f42725c2,b789a33b,6fb8d559,1b466f8f,c63db50f,1c0f1c69,13f9968,87b8244d,2cdec417,afea8fa3) +,S(ea01606a,7a6c9cdd,249fdfcf,acb99584,1edd28,abbab77b,5104e98e,8e3b35d4,322af490,8c7312b0,cfbfe369,f7a7b3cd,b7d4494b,c2823700,cfd65218,8a3ea98d) +,S(af8addbf,2b661c8a,6c632865,5eb96651,252007d8,c5ea31be,4ad196de,8ce2131f,6749e67c,29b85f5,2a034eaf,d096836b,25208186,80e26ac8,f3dfbcdb,71749700) +,S(e3ae19,74566ca0,6cc516d4,7e0fb165,a674a3da,bcfca15e,722f0e34,50f45889,2aeabe7e,45315101,16217f07,bf4d0730,de97e48,74f81f53,3420a72e,eb0bd6a4) +,S(591ee355,313d9972,1cf6993f,fed1e3e3,1993ff3,ed258802,75ea8ce,d397e246,b0ea558a,113c30be,a60fc477,5460c790,1ff0b053,d25ca2bd,eee98f1a,4be5d196) +,S(11396d55,fda54c49,f19aa973,18d8da61,fa8584e4,7b084945,77cf032,55b52984,998c74a8,cd45ac01,289d5833,a7beb474,4ff536b0,1b257be4,c5767bea,93ea57a4) +,S(3c5d2a1b,a39c5a17,90000738,c9e0c40b,8dcdfd54,68754b64,5540157,e017aa7a,b2284279,995a34e2,f9d4de73,96fc18b8,f9b8b9f,dd270f66,61f79ca4,c81bd257) +,S(cc8704b8,a60a0def,a3a99a72,99f2e9c3,fbc395af,b04ac078,425ef8a1,793cc030,bdd46039,feed1788,1d1e0862,db347f8c,f395b74f,c4bcdc4e,940b74e3,ac1f1b13) +,S(c533e4f7,ea8555aa,cd9777ac,5cad29b9,7dd4defc,cc53ee7e,a204119b,2889b197,6f0a256b,c5efdf42,9a2fb624,2f1a43a2,d9b925bb,4a4b3a26,bb8e0f45,eb596096) +,S(c14f8f2,ccb27d6f,109f6d08,d03cc96a,69ba8c34,eec07bbc,f566d48e,33da6593,c359d692,3bb398f7,fd4473e1,6fe1c284,75b740dd,98075e6,c0e86491,13dc3a38) +,S(a6cbc304,6bc6a450,bac24789,fa17115a,4c9739ed,75f8f21c,e441f72e,b90e6ef,21ae7f4,680e889b,b130619e,2c0f95a3,60ceb573,c7060313,9862afd6,17fa9b9f) +,S(347d6d9a,2c48927,ebfb86c1,359b1caf,130a3c02,67d11ce6,344b39f9,9d43cc38,60ea7f61,a353524d,1c987f6e,cec92f08,6d565ab6,87870cb1,2689ff1e,31c74448) +,S(da6545d2,181db8d9,83f7dcb3,75ef5866,d47c67b1,bf31c8cf,855ef743,7b72656a,49b96715,ab6878a7,9e78f07c,e5680c5d,6673051b,4935bd89,7fea824b,77dc208a) +,S(c40747cc,9d012cb1,a13b8148,309c6de7,ec25d694,5d657146,b9d5994b,8feb1111,5ca56075,3be2a12f,c6de6caf,2cb48956,5db93615,6b9514e1,bb5e8303,7e0fa2d4) +,S(4e42c8ec,82c99798,ccf3a610,be870e78,338c7f71,3348bd34,c8203ef4,37f3502,7571d74e,e5e0fb92,a7a8b33a,7783341,a5492144,cc54bcc4,a944736,93606437) +,S(3775ab70,89bc6af8,23aba2e1,af70b236,d251cadb,c867432,87522a1b,3b0dedea,be52d107,bcfa09d8,bcb9736a,828cfa7f,ac8db17b,f7a76a2c,42ad9614,9018cf7) +,S(cee31cbf,7e34ec37,9d94fb81,4d3d775a,d954595d,1314ba88,46959e3e,82f74e26,8fd64a14,c06b589c,26b947ae,2bcf6bfa,149ef0b,e14ed4d8,f448a01,c43b1c6d) +,S(b4f9eaea,9b69176,19f6ea6a,4eb5464e,fddb58fd,45b1ebef,cdc1a01d,8b47986,39e5c992,5b5a54b0,7433a4f1,8c61726f,8bb131c0,12ca542e,b24a8ac0,7200682a) +,S(d4263dfc,3d2df923,a0179a48,966d30ce,84e2515a,fc3dccc1,b7790779,2ebcc60e,62dfaf07,a0f78feb,30e30d62,95853ce1,89e12776,ad6cf7f,ae164e12,2a208d54) +,S(48457524,820fa65a,4f8d35eb,6930857c,32acc0,a4a2de42,2233eeda,897612c4,25a748ab,367979d9,8733c38a,1fa1c2e7,dc6cc07d,b2d60a9a,e7a76aaa,49bd0f77) +,S(dfeeef18,81101f2c,b11644f3,a2afdfc2,45e1991,9152923f,367a1767,c11cceda,ecfb7056,cf1de042,f9420bab,396793c0,c390bde7,4b4bbdff,16a83ae0,9a9a7517) +,S(6d7ef6b1,7543f837,3c573f44,e1f38983,5d89bcbc,6062ced3,6c82df83,b8fae859,cd450ec3,35438986,dfefa10c,57fea9bc,c521a095,9b2d80bb,f74b190d,ca712d10) +,S(e75605d5,9102a5a2,684500d3,b991f2e3,f3c88b93,22554703,5af25af6,6e04541f,f5c54754,a8f71ee5,40b9b487,28473e31,4f729ac5,308b0693,8360990e,2bfad125) +,S(eb98660f,4c4dfaa0,6a2be453,d5020bc9,9a0c2e60,abe38845,7dd43fef,b1ed620c,6cb9a887,6d9cb852,609af3a,dd26cd20,a0a7cd8a,9411131c,e85f4410,99223e) +,S(13e87b02,7d8514d3,5939f2e6,892b1992,21545969,41888336,dc3563e3,b8dba942,fef5a3c6,8059a6de,c5d62411,4bf1e91a,ac2b9da5,68d6abeb,2570d556,46b8adf1) +,S(ee163026,e9fd6fe0,17c38f06,a5be6fc1,25424b37,1ce2708e,7bf44916,91e5764a,1acb250f,255dd61c,43d94ccc,670d0f58,f49ae3fa,15b96623,e5430da0,ad6c62b2) +,S(b268f5ef,9ad51e4d,78de3a75,c2dc89b,1e626d43,50586799,9932e5db,33af3d80,5f310d4b,3c99b9eb,b19f77d4,1c1dee01,8cf0d34f,d4191614,3e945a,1216e423) +,S(ff07f311,8a9df035,e9fad85e,b6c7bfe4,2b02f01c,a99ceea3,bf7ffdba,93c4750d,438136d6,3e858a3,a5c440c3,8eccbadd,c1d29421,14e2eddd,4740d098,ced1f0d8) +,S(8d8b9855,c7c052a3,4146fd20,ffb658be,a4b9f69e,d825ebe,c16e8c3c,e2b526a1,cdb559ee,dc2d79f9,26baf44f,b84ea4d4,4bcf50fe,e51d7ceb,30e2e7f4,63036758) +,S(52db0b53,84dfbf05,bfa9d472,d7ae26df,e4b851ce,ca91b1eb,a5426318,da32b63,c3b997d,50ee5d4,23ebaf66,a6db9f57,b3180c90,2875679d,e924b69d,84a7b375) +,S(e62f9490,d3d51da6,395efd24,e80919cc,7d0f29c3,f3fa48c6,fff543be,cbd43352,6d89ad7b,a4876b0b,22c2ca28,c682862,f342c859,1f1daf51,70e07bfd,9ccafa7d) +,S(7f30ea24,76b399b4,957509c8,8f77d019,1afa2ff5,cb7b14fd,6d8e7d65,aaab1193,ca5ef7d4,b231c94c,3b15389a,5f6311e9,daff7bb6,7b103e98,80ef4bff,637acaec) +,S(5098ff1e,1d9f14fb,46a210fa,da6c903f,ef0fb7b4,a1dd1d9a,c60a0361,800b7a00,9731141,d81fc8f8,84d37c6,e7542006,b3ee1b40,d60dfe53,62a5b132,fd17ddc0) +,S(32b78c7d,e9ee512a,72895be6,b9cbefa6,e2f3c4cc,ce445c96,b9f2c81e,2778ad58,ee1849f5,13df71e3,2efc3896,ee28260c,73bb8054,7ae2275b,a4972377,94c8753c) +,S(e2cb74fd,dc8e9fbc,d076eef2,a7c72b0c,e37d50f0,8269dfc0,74b58155,547a4f7,d3aa2ed7,1c9dd224,7a62df06,2736eb0b,addea9e3,6122d2be,8641abcb,5cc4a4) +,S(84384475,66d4d7be,dadc2994,96ab3574,26009a35,f235cb14,1be0d99c,d10ae3a8,c4e10209,16980a4d,a5d01ac5,e6ad3307,34ef0d79,6631c4f,2390426b,2edd791f) +,S(4162d488,b8940203,9b584c6f,c6c30887,587d9c4,6f660b87,8ab65c82,c711d67e,67163e90,3236289f,776f22c2,5fb8a3af,c1732f2b,84b4e95d,bda47ae5,a0852649) +,S(3fad3fa8,4caf0f34,f0f89bfd,2dcf54fc,175d767a,ec3e5068,4f3ba4a4,bf5f683d,cd1bc7c,b6cc407b,b2f0ca64,7c718a73,cf71872,e7d0d2a5,3fa20efc,dfe61826) +,S(674f2600,a3007a00,568c1a7c,e05d0816,c1fb84bf,1370798f,1c69532f,aeb1a86b,299d21f9,413f33b3,edf43b25,7004580b,70db57da,b182259,e09eecc6,9e0d38a5) +,S(d32f4da5,4ade74ab,b81b815a,d1fb3b26,3d82d6c6,92714bcf,f87d29bd,5ee9f08f,f9429e73,8b8e53b9,68e99016,c0597077,82e14f45,35359d58,2fc41691,b3eea87) +,S(30e4e670,43538555,6e593657,135845d3,6fbb6931,f72b08cb,1ed954f1,e3ce3ff6,462f9bce,61989863,84993501,13bbc9b1,a878d35,da70740d,c695a559,eb88db7b) +,S(be206200,3c51cc30,4682904,330e4dee,7f3dcd10,b01e580b,f1971b04,d4cad297,62188bc4,9d61e542,8573d48a,74e1c655,b1c61090,905682a0,d5558ed7,2dccb9bc) +,S(93144423,ace3451e,d29e0fb9,ac2af211,cb6e84a6,1df5993,c419859f,ff5df04a,7c10dfb1,64c3425f,5c71a3f9,d7992038,f1065224,f72bb9d1,d902a6d1,3037b47c) +,S(b015f804,4f5fcbdc,f21ca26d,6c34fb81,97829205,c7b7d2a7,cb66418c,157b112c,ab8c1e08,6d04e813,744a655b,2df8d5f8,3b3cdc6f,aa3088c1,d3aea145,4e3a1d5f) +,S(d5e9e1da,649d97d8,9e486811,7a465a3a,4f8a18de,57a140d3,6b3f2af3,41a21b52,4cb04437,f391ed73,111a13cc,1d4dd0db,1693465c,2240480d,8955e859,2f27447a) +,S(d3ae4104,7dd7ca06,5dbf8ed7,7b992439,983005cd,72e16d6f,996a5316,d36966bb,bd1aeb21,ad22ebb2,2a10f030,3417c6d9,64f8cdd7,df0aca61,4b10dc14,d125ac46) +,S(463e2763,d885f958,fc66cdd2,2800f0a4,87197d0a,82e377b4,9f80af87,c897b065,bfefacdb,e5d0fd7,df3a311a,94de062b,26b80c61,fbc97508,b7999267,1ef7ca7f) +,S(7985fdfd,127c0567,c6f53ec1,bb63ec31,58e597c4,bfe747c,83cddfc9,10641917,603c12da,f3d9862e,f2b25fe1,de289aed,24ed291e,ec67087,3a5bd56,7f32ed03) +,S(74a1ad6b,5f76e39d,b2dd2494,10eac7f9,9e74c59c,b83d2d0e,d5ff1543,da7703e9,cc6157ef,18c9c63c,d6193d83,631bbea0,93e0968,942e8c33,d5737fd7,90e0db08) +,S(30682a50,703375f6,2d41666,4ba19b7f,c9bab42c,72747463,a71d0896,b22f6da3,553e04f6,b018b4fa,6c8f39e7,f311d317,6290d0e0,f19ca73f,17714d99,77a22ff8) +,S(9e2158f0,d7c0d5f2,6c3791ef,efa79597,654e7a2b,2464f52b,1ee6c134,7769ef57,712fcdd,1b9053f0,9003a348,1fa7762e,9ffd7c8e,f35a3850,9e2fbf26,29008373) +,S(176e2698,9a43c9cf,eba4029c,202538c2,8172e566,e3c4fce7,322857f3,be327d66,ed8cc9d0,4b29eb87,7d270b48,78dc43c1,9aefd31f,4eee09ee,7b47834c,1fa4b1c3) +,S(75d46efe,a3771e6e,68abb89a,13ad747e,cf189239,3dfc4f1b,7004788c,50374da8,9852390a,99507679,fd0b86fd,2b39a868,d7efc221,51346e1a,3ca47265,86a6bed8) +,S(809a20c6,7d64900f,fb698c4c,825f6d5f,2310fb04,51c86934,5b7319f6,45605721,9e994980,d9917e22,b76b0619,27fa0414,3d096ccc,54963e6a,5ebfa5f3,f8e286c1) +,S(1b38903a,43f7f114,ed4500b4,eac7083f,defece1c,f29c6352,8d563446,f972c180,4036edc9,31a60ae8,89353f77,fd53de4a,2708b26b,6f5da72a,d3394119,daf408f9) +#endif +#if WINDOW_G > 9 +,S(90a80db6,eb294b9e,ab0b4e8d,dfa3efe7,263458ce,2d07566d,f4e6c588,68feef23,753c8b9f,9754f18d,87f21145,d9e2936b,5ee050b2,7bbd9681,442c76e9,2fcf91e6) +,S(c2c80f84,4b705998,12d62546,f60340e,3e6f3605,4a14546e,6dc25d47,376bea9b,86ca160d,68f4d4e7,18b495b8,91d3b1b5,73b871a7,2b4cf61,23abd448,3aa79c64) +,S(9cf60674,4cf4b5f3,fdf989d3,f19fb265,2d00cfe1,d5fcd692,a323ce11,a28e7553,8147cbf7,b973fcc1,5b57b6a3,cfad6863,edd0f30e,3c45b85d,c300c513,c247759d) +,S(57488fa2,8742c6b2,5a493fd6,60d936e,a6280b0c,742005ab,ce98f585,5ad82208,31b3ca45,5073bea5,58adbe56,c27b470b,af949ae6,50213921,dc287844,f1a29574) +,S(f1133cbe,6be8bbc8,dc8df2b8,d75963c2,d40ed616,c758cdc8,4edbc5eb,4899447d,57fc2447,2225b23f,5714626d,8d67d561,10bd3a60,dd7a1687,cbbb893,f652f50f) +,S(95083e75,3301bd78,7f8989c7,9065bb81,3f3d69bf,f3e42505,f4e0417,5bbe89c0,844adb5c,e7d10de9,4617c73c,a77040e4,ee4e92e0,156b3c70,cc593fa4,94b33482) +,S(1a908355,cbb75675,5e576ed2,9c99af63,8668c7b3,63c8d973,62100443,bc5c75c6,d765466c,6e556e35,2f778722,25627d80,a7353807,4b44ff27,57ad22e,2f2454a2) +,S(c5922f74,bd343d5,aa867308,fad97f9f,8a2d1f63,c5f31db4,f04df3be,f349b648,77b1f068,7cfcdbe8,812605e5,d8b752c,da811844,236a4c43,77f53c94,6e7bd648) +,S(64e1b196,9f910297,7691a404,31b0b672,55dcf31,163897d9,96434420,e6c95dc9,c16f60c7,c11fc3c9,eb27fa26,a9035b66,9bfb77d2,1cef371d,dce94e32,9222550c) +,S(33b2e76,687744ed,6c521bad,3333dd37,c602f8a7,549e9ce7,808fb7ea,7ce08de,e1bcfe7f,c8ed8ae9,5cf6c243,7fdd94bf,d742e8ca,a6de7811,4c25112a,86988efd) +,S(20f18f4c,866d8a1c,c2a31033,17b4ac31,89fbf30f,f294a75c,951473be,45e4f294,8d6857c9,d08ef7b4,fd888336,3d37bee7,fe8529f,7173f589,43fcae81,d2d0ea0e) +,S(4d1623c9,44c9c716,a0eb4c68,5e2a8b9d,2df34653,54643bef,d1444176,d7b69a8b,ddf1b9fe,8744ad03,f996bf6b,96ec3496,2b601bd5,ed952f78,54f58388,8917be80) +,S(a901b0db,e8ab292d,280d6b36,85894785,4faad0a4,dd0da7e2,d4ad0ff5,3db079e0,3f27e7e1,834f1a61,af6f04dc,61e7ae64,716bc5e0,a6b063b3,1d0e60e,47298a9d) +,S(7e0af071,30218ffd,50bd66f4,484645b1,2f42a24f,7c80889b,3031c9a6,ebfc9a70,50bc23f3,926cd0c4,9f53fbb2,35eb1e89,d579517,f5bdc3ab,2416db78,5aaedb3f) +,S(7ba8187e,1a7b25a2,c185d335,440a9038,b47f0528,546e9da4,ef82aab0,5aebf20d,6e6aee6c,9625370a,f866c25c,7ca5dd78,527efbc,e7d8b3a3,9ab24930,9a185187) +,S(8c050fc3,4d83b279,b6000816,e18fca38,9767b796,e926772,55b84a39,d93a6807,986314ef,75b68fb2,827c2965,4198139,5d699fcd,81cf23ce,7019bc41,35174870) +,S(53b7849a,78e4df86,25860583,a5249948,9d7201a2,cbf50620,2a7b8b1b,c99c2ec9,4e31ea12,ac607d07,5de4b22d,e1be2c52,e0a44d25,4728d2c5,44d2ddf9,e3e469c0) +,S(9bdf9e67,a5d0c995,6a075a01,fe762be,b6335004,31dee78e,febc527e,53313b33,94264621,a5960e0e,e24c2792,6f16cad2,907f2636,762e8d5a,17e94afd,8e9d2bb0) +,S(7caa72b3,7a8ab3bd,bac031a,47606f89,17d9f42c,6ec2d2fb,429fd990,4a381f34,5b5853ab,7ee5de8d,34e3d6be,b201094f,ff8fbd1e,682f7f1,ef87ddd6,5d7303c9) +,S(2ef29b9f,9827975,79c0295f,c3f48db7,925d62c7,5532493d,de16b97e,3993d81a,496c944d,d9875ba6,a537ef9,6bf4c714,a0afff24,387d95e8,9b42337a,33110753) +,S(df157cad,95b07875,573c1860,ae5d02c6,4029e952,ec354e6a,9e5c34be,97317ff8,f2eccac7,75922b50,899c979a,2b3cc30,b629e62e,85693ba4,70f6ee38,1284c162) +,S(dd55c150,a29ca526,b6182e64,3b9eb544,e651d236,b71920e7,b15a9870,16454b1d,44c757a5,42f4ea2e,b39605d4,268c2510,ac685aab,d77a8f5c,4d95e23f,4c2e9368) +,S(16886cf4,6ed42c79,19147763,63d3256,c4d5d393,87f01723,25b9e4b8,98227f27,7421a220,7ee73299,d46192fc,93ca03de,c824ed8d,e2f48367,ec538317,a17fffb) +,S(6ff180fc,daa30618,8e8b306,d6f0acff,27968c22,484ff45e,56aeaa7b,2b60732f,7d16d654,f0c2aff0,fc254dad,63761a2,6c8d4022,ea85b8cc,22f3ea1e,f69961a9) +,S(3ea4511,a00dc2a0,3eb4f51f,40ee677c,aa912b55,39f685c4,f8bcc8ea,dc395e36,6c9ed1f1,528b0215,93a39839,340ddb53,a2f2e36,5290c498,24b035c6,73c9259d) +,S(b82cd70,dc3de9ea,b38742d8,f32dfb8d,53e4150a,835e54b6,3c7cca20,f253081d,e8bcbfe,1f7f6e75,d32e2049,9329765f,2effc56,a922f268,60d4bc0a,add0e24d) +,S(fe2fc3e0,748745,84ee23bf,105a69a6,6d056f0,17327d49,b7b38b57,a196c77f,3e18941c,c3c6d297,cc9a32f6,95807b1c,7da8561d,e4fde71d,4f9bbdb6,e9bf3916) +,S(4b90176,cdaa3693,47e8778b,12db9d6e,e8b00114,46ea35ec,845dbf57,4bb7858b,f60547ab,6e9c5fd3,eca6e349,b85880c6,1fdad0fc,2f7ab155,295caaec,b973c154) +,S(35f38251,1d34600b,4b8c86a9,f0dbc9ed,defc4272,f59528a0,cd3ec10a,5944c6d2,29a835f6,ef7fa1e5,f6f37a80,cf96ca98,43762bb1,b12a0dae,ae83234b,d0b5ccd5) +,S(1d74b297,311b7ff,a1027e26,587d3f5b,e1d0e9ac,3f0111cd,f3cc2371,722cb94a,5c7bcf8b,57f114e0,b73bcfb8,10f5c60d,35dc99ae,9dc7f0e2,606cc1f7,28c2071e) +,S(50a094f3,9c6f956,b020737,b9ec722e,4f75d1b7,c41593e6,f934a68a,98450428,a286e222,dfe10cfd,9689eaba,6a81f044,89c86db6,869aa1b5,54a90f1e,83778eee) +,S(9b65bb81,2129157c,dfecf12e,275ec38c,282dbcd9,14b48105,99b0a6d6,27c63db7,c582db1a,3f0f2242,1913b2e9,51e98a78,660b4c40,ad08fd65,528593bc,18223188) +,S(8b4544fc,1fdfa06e,456c1115,a1dc831c,85e7f1c5,e620eca5,1c20802d,36a4bc6b,e3e77c41,288f2602,e722af7f,4b70e64d,e4116fb9,955b03b0,6ea8b19f,7a20350d) +,S(6c709880,b959eb7c,5179b29c,c5578fdc,6cb2ae13,ddcede29,d5f81d95,de0ab4aa,c9e33fae,bd8eba42,6736c0c7,6f3deaba,ee2b59c5,953fb43,c2dcc513,9e7c4bdc) +,S(77760b51,37ba6a71,95d891f7,94a087a0,76fc9d67,802b81e7,85b5677,3d537806,f5202cf5,aaeea58b,f4f58c7e,df4417be,1b87ffde,e68e77f0,d7e81abe,158e3a25) +,S(1a8bd783,6a0b0c82,e9a904a8,a8c91a67,e23cd4f8,efd625d0,df4c426e,7e163102,61fe64ca,b0952cae,3c574f28,2f74a87d,c2a96316,b7009f2e,4e9c5fcc,12285844) +,S(fe217db6,59079913,fb1e453e,d24d91d6,a3fb3099,e69471d7,53db5390,864abc30,5dcf9abb,a9625ed6,80b0f20f,b1f047d5,93a0c61c,53969253,8cdf6b03,4d730b58) +,S(2504d637,54afd5eb,c38f58b6,5ead696d,7e3abd7,48cb6c5f,212aed49,f5b33b91,79a6bf43,75f1469c,4f5321c6,c72fbbf4,ba7cec10,5675f437,b5e013ad,7b5d75d4) +,S(b06f702,f47b22d7,89a9bd3f,687105c3,6160abbf,5cc8976b,7fbddcaf,db197b5c,7669bbd4,19a4d491,f592a35b,6aa3dfe4,5bd2fe7f,d179c778,1cd5f918,d732f63d) +,S(803b203b,b31f9cf9,4034eeb9,31b54480,a6f3f99e,bd23d0ac,bc2128a6,d044e23,308abc8d,f271f759,59b20c5c,7fa62baf,bfc9ccbf,49b946a9,54e5381c,1728d1c7) +,S(266a9cb4,c5f5cead,bb50e5bd,a03a7312,e52de1de,8e95a8dc,d57289fe,302749a,9eea970b,a856b2fa,a3e82877,cc84ed4f,3dc0efba,1e7c3baa,8b386ffc,46e0ae7e) +,S(fd8a9d95,d80c7ad5,2599a7ab,98163df3,64c4c141,e9abea35,5d7360bc,f84eba94,a9fb1702,100953b3,59b2e268,8ae7fd33,a30377da,47bfda71,3e2d7d73,dfb1030c) +,S(a7322df3,9f28f23,59fc339a,8b2c80be,6e84acc5,b7b0b8f8,f2cb6f26,f9db0a7d,22f6fe9d,21749501,7fdb7f5b,2f12fa57,95f40e1,31714885,c12a2ea1,6edb6be6) +,S(82a8c10f,336a6649,63a104dd,bf7f0f18,bd4c461a,ea569ffc,82c3c7e4,cb052d36,737ceca2,c0ef7227,8b90501c,cb71b671,5e5c31d4,cd0478c1,18fe1287,95f1dd0c) +,S(9b50d1b6,8e3bf795,7cd12f,5a60c26,6c4ef2b7,5ba5c516,c54784a9,4f15d6df,2afc8d09,b79176d8,d003fd2a,4f18d526,403fff27,2d47e778,7376feb7,cbddd8fd) +,S(3f9083dd,c8b423fe,7de3a822,81d3056a,b8dcb9d7,ee82cb80,6718595f,bae08d32,cb13c152,fd511d91,a9e0ed90,afa021a0,81f77f6d,20cc1376,e2195ffc,f28fa758) +,S(c75c85c1,ee17c1a2,56eff6bd,592666cb,c9231706,59d50bfa,dbd1074e,f2167faf,1ab4eabe,5e09409d,75cca892,2647f48d,bd698a16,d4f7cc85,96daf169,40023a52) +,S(c5341fea,f8a0f5d3,b4d0cf0d,2f7aad7c,60ea8e2b,3d4b7fb9,5c68d576,98656045,95f9f4e9,7e5b9f,a48fa422,a26ab982,dc48a4d5,4d712398,6e6d3ab9,74e88915) +,S(83acda3e,2a8997e0,d52bd4c6,8705dd22,220852b7,752d67fd,8967a032,60c2d89b,dce1bae1,d655ba51,7f5b5580,99711757,a77cd3b,dd4b8e8e,330e9779,1bc31df0) +,S(5b819146,8b299074,5b9c4164,e29d594c,f1c0d571,6c5d3962,5bd279b3,25237b,cc3636a0,3fddddfa,bed88daa,b081f359,1c48d2ca,71ba34fc,f6989f4a,f7625d8e) +,S(64778122,214e38ef,f8041796,166104e7,32f5f664,d38d7721,9b89045e,2c3b0e6c,329cf049,7e15eec7,b8eafc4a,b8a7d1c,d8b63203,8d4aef81,974cf984,4611a32d) +,S(ed4d826a,fe5762f4,79509909,9aee8664,2b475a9d,6da1017c,43d0cb9f,1af12323,8c6f81be,3fafa5ee,c8296f92,8ac7919d,c4d88c9a,59442274,d0531b7b,f7e48e78) +,S(38b42924,419aecc3,acd6f551,346fd61a,4d82ac2b,55f7afe9,7a06eb40,cd109c4a,7f42c096,2feb2f73,b2b0965a,1f359a6a,de49d768,a2ce6b07,b5acb92b,73e05583) +,S(c3cad4a8,d8bb94a7,b434cf70,183e8615,bb2a8f62,24f216e3,446ac2e9,82138911,f649be27,8cad9764,20742ce3,82dce3a1,420e372e,f1b25b27,59a8ed38,7282765e) +,S(2d408ff4,d3d236fd,54fae40d,ce3ea9ec,d9212e57,36591a9e,55588e4a,54bd6538,d596adf0,e8692a06,bc6284bf,299bef6,85e2a171,585aa132,4b9a05b5,ce815b7) +,S(ee7adf6d,247f25fb,76e90cf8,13f888eb,d67423a3,a3c6fdae,bafb7eaa,7a33c854,e077184b,4ae8f705,6c10dd9e,f541689d,143f6871,789e1801,deaefc1d,527a8fb4) +,S(2f9457c8,a9ffaca1,3d91151d,c4c5e89d,dd5d37a3,7c9a864b,7c811f3e,1144b34,eb4c9848,9093d573,a295407e,1d6fc48a,787120ce,b3d3dcfb,b40634e0,e75e221d) +,S(d3f332b8,a0f11582,1ce3478c,efe18de3,60120483,ef531c27,7b30c46e,b7fec294,ea75b9b2,5d717861,d1af1c01,9c372941,c8968b90,ef134f9f,323215e1,bb0b2155) +,S(183408d3,38b05aad,3521fcd8,6ef36dd7,5f3ddb86,66b52f7e,9a4cdf1f,8e152b91,66998520,6edf4ac6,f39be21f,20c98824,210e204c,e4499809,5de35537,1641218c) +,S(283fec5d,b1145e53,ba8f1f0f,f9cf89a7,21faffd6,c2534686,3d395609,5f40374e,70b01237,74af550e,68e68e5f,65ca6e98,8846e03,cf39af77,8511be82,bc32fefe) +,S(ce7570a,4f943cfa,413bd249,d8e7dbfc,ebc73579,770fd6da,f54a0dfb,dd52fa62,e115b14b,ef4695cf,fb85bdf9,8ba3985c,bd5e5b89,83e05390,7c36f9ce,8b75d41d) +,S(7e9c4f19,c8f4ec3f,1269f648,cd919525,df790315,74cbeb15,37794a4c,838fd470,e9d9dbfe,8cf5f5cc,a855d6cc,bd11f480,60fafa8d,ad6bd3e9,c86df5ce,b0fa5270) +,S(e2a9bbe6,d5d5bfe,a7c7f919,df2309f9,ba04f4c,722a3ec2,3bf451b4,64cb001b,e4177ce1,c3cd6ac7,78925bd6,7e72cb77,d1925b91,d06a7f16,98411a47,86393fb0) +,S(504512a4,3e17ef50,e43bf37d,42a94990,f55e641b,1558c265,e7099002,75271012,954a5fd8,57ba3acf,2d4b1f41,e8e1f2cd,1f21c4b9,6899781b,742a49d2,e61ed18b) +,S(81d1f013,a6bb325f,4b2d1d51,ba72c721,859945d8,a17b3411,cd5cbe87,285f850d,2d5d2fb1,f0c30855,3b1fe249,298b2059,259d3d49,d4d7071a,dce4bcc5,dc937193) +,S(5b66c2df,c1d28266,18a87276,7e66c33d,d90dd514,14a3b87c,a733383d,1d895022,9bd0178e,38189569,2217267b,7407e987,27fcaeda,12d8cf54,49eb5472,d554e0ff) +,S(aeb5f70e,98ec5e38,dbd2d544,bdbff8ab,99b583d9,af58c597,afaf8688,20381186,618bd6b0,d25ca70d,f08b7692,9336e421,691b0973,f2f5a05,2e7adc17,3584427b) +,S(b289eff,e841943b,84761e3c,67a9c02a,557679ca,76ad753a,707a9821,2505052e,7a981f0,c21862a8,53b4f895,dc62482c,530ed738,5e5d1e33,cfb9d0f,e879992c) +,S(abae3945,8b12199e,6b0c8360,cfd28288,3f585917,e44e1200,f81bd356,f619291c,adb23bcd,b3d069c5,e83be30b,2469b068,b2a81b7,b667e934,233b75ef,b5753f28) +,S(4a9583a6,485b5a5a,81ac224a,518eb29d,1e0f658c,8d91b013,9419c809,55fbacaa,d8003c9e,e3c842f5,ede375a8,a7768db4,803ecf11,9b7b37de,cea15631,b4e8dbca) +,S(d52f630e,dba6f7cb,65fcf465,44ab0d9e,ea236ac1,460f17ae,3a210102,10ebc169,21155748,9fa93b88,3e5bea50,da005c53,68e21a0c,41bc83d9,145c13e1,370d26d0) +,S(bdc5237,82c75858,f5c50fc0,52e4c1e9,c74a2a63,35bca9bf,8d10e120,9add6a4d,abb1d9f8,74637668,e214efba,fbf529d3,12ff023b,c1d5723e,58540436,6834f189) +,S(44770a33,8bf0aab8,3bb64e47,6eb6167a,88156d16,8f13ce86,26ee0912,e59ad087,5b5930f1,2e9c40bc,b3393a89,5c2d6457,6a3abd23,b7291b99,c965c33d,ef60a55c) +,S(b15e7b32,2e404aee,319ac203,23e36672,6503108d,8ee8e1c8,3e32d924,515e1679,5246a819,bbfb291,5f82ed56,50796f50,5ced5c25,87347d57,a873ceaf,3d997e7a) +,S(a1ed7557,5225cd0,f2c50f75,8a1c1df9,665ae108,d5e04190,27bbd9ae,ddb00f22,3c83145d,ad9f8748,7b97e746,4850ed02,d71dbd04,93281a1,3d212776,6a791ee2) +,S(e8aaf361,6a1bc60f,d9bfc43c,2c60580f,479e9ec9,c23a37a2,3cf8afb3,1d918af5,6ce693b6,4a37c672,7e141041,ab9a0d58,9ab9c303,a5ac3d3e,c89b6f27,9e79827c) +,S(5dc6f8cd,2c855e63,52a4a4ef,6187a6d6,759c043,38a3db76,c5a3aa37,54c20a3,f602c342,8593a9a8,d671d1bc,7c1d8834,fe9f5f5,2e6a7f0f,bb870146,4e6f4838) +,S(63327311,67bed8af,68a063ef,22aa489c,f6563620,461af26a,5f1a07cb,6b42f3a6,b8f7c3b2,20701320,f20ca036,761d3e56,bf94a700,9a919f1a,3ea0cb81,b74424a6) +,S(8a40d925,9a393b38,2305c201,7e8654db,ad66e50a,d798a0d3,535230f9,48080263,afb6a74d,9849454e,dd7f703a,5c6616d1,43f9cbcc,9a9a5d6f,6a7b5d1f,9d9fcaff) +,S(e7147107,27c7420a,f517fd3f,9a05b7de,a6a02c8b,cc20b17d,cdfdeaf8,2078645a,da7d67cb,c1ede9d4,fedd5dcd,c96b04f9,a3561ba0,2581b055,eaa144eb,4217daca) +,S(6131291c,d95fb878,1e42a68,553952c2,9922bce8,91c026c0,cae1f69c,9661c82d,160e1c1c,13342fd4,59d4f989,8ae632b8,42b89479,13733b89,384fc104,2d30bf01) +,S(4bc4f845,b6764692,d0a9bfa8,1788809e,fc5e2aa9,da5003bf,b782bcf1,d1ca4951,87092dcb,b9c3d254,e3b055ff,3a76ec05,64c4a7c5,7fb1783c,efdc40fc,10b751f0) +,S(45a880a2,7bbee9df,29f9bff5,c985f364,52865b5d,582a201f,698e6eca,a2be67df,fe49a6a8,b5e46bf1,ef679714,dabd590e,a831d46b,8ee94eb6,13132ba3,7855fabb) +,S(6a826a38,317c0c86,64d6847a,220145d1,877e5495,b21500d3,f21f1a0d,4af4f2a4,4521954e,fcc98263,df2f14e0,e6e6b47a,f6b83f0b,bc20722c,15445f87,e05f4513) +,S(15356506,f255f7e9,6cc8aa1b,9dce572,8bd860de,7c6cc75f,613e8a34,366a23a9,cd15abbc,d744d485,d5e401f,1f89a5df,122f37b4,e362b4ce,e3e53b1c,110bf3) +,S(f3bc12ae,f53d9f5f,6b865178,2dac2ec,cacff3a5,cca6443a,2b5e1ca0,f2b89b91,cfd4d36b,eb2e11f2,41fd0f36,7a0737ad,303e915f,f247f131,368ca509,18e00957) +,S(7e3c8c6d,fa04a536,f7a26ef1,8b387649,22320bef,58453373,6f728297,335c0fd4,72ea16b5,32a7336d,3332400b,303c0236,b6a1294d,88ce7fe9,15571284,d1f7c189) +,S(198cbfcf,a0575fc2,c161c696,d85155fe,6943ab9b,d6e17223,d8844608,ad0369d8,d5e6268b,30952422,be59fe0e,fe7ba2e7,3215994,827a46c2,f2972b26,153cf7ae) +,S(1e056e89,b68cf35a,22183c08,9089b90d,5a147caa,780b1fd6,3aeb1350,afb0e5e8,b8241453,abc44c57,ddad6ff3,86d416f4,3e258a39,c6f8837,9f80472b,943f32b9) +,S(dc7ff974,8d827e7e,a6173b2f,1a646d47,d8108144,ce7f98fb,3fac729e,72faaa21,c1fdac5a,ef4c6f0f,fcb8e1c5,c4417c71,3e3d5f07,146daa1a,aaf2e7fe,e70c4914) +,S(71b95efc,c4981e07,5354bc1,1cdfbc48,36b2eff0,bf8f8ec2,9a99da1b,2fd28e79,fd5a3197,6fad6aee,c304752c,c3ebbc51,1f3695b0,9a737fa3,af42cc6,efd684cc) +,S(43854caf,29dc2bd6,c9f3e8ff,a25bba83,f6b96121,897044ae,6876883a,de542b3a,56365176,897632f,8dde3167,7a24f558,34c5c9a5,5c1cbf36,fd8b4480,3c9c6c81) +,S(2adfe17,90e9f9c,708c9b73,d5fd084,b6eff990,fb877961,45c2ecf2,d427b222,b5ce3160,5d6dd9c6,22cae425,ccd28912,c4439820,c06950cd,4c86d9b4,53abd7ed) +,S(a123452c,2b7eaf31,15b3a534,3b3ff31a,9f70c54,ae33c620,471e3e82,27a9d6f9,933d3483,78a71f44,3788194a,afc545e7,f53e37a6,f779f96e,8fa14ccd,ede3b4eb) +,S(9b89a3c2,ca995a81,86c15217,61348737,aab166ae,7decca60,3d06e32c,cec0a6ab,2a7d3701,a8724b12,bd7c4830,224ac083,cbea83d0,543b5414,80ba8c8a,e7731232) +,S(64dd7457,e7d9d739,8e2b9a0,dc45272b,384b0433,9ed8b2ed,c9079646,11e9e9b2,ea90f8aa,e214ee16,ed608a72,36699899,4e311dc7,780ef885,b29290c3,823c470e) +,S(59227431,be607c6b,d327fd71,4eb71c87,20abba42,1c7f550a,6b35767d,6fa2176c,cb7571c4,71c5527,65bd289e,a3cf3f38,796da2b1,2c953d0b,8705125c,4861d598) +,S(53d765cd,adb26e9e,1c80ddf1,99374363,843b7d08,a7237bdc,8c5106ef,795fe2c2,7bbbb198,eb39973b,76d87f81,94d45150,a66d4f3b,128a40be,c989a405,ad7c287b) +,S(e507de9e,c16b3bf3,523a989c,f5ff6c1,452ee90,9b66ffc1,6d7b519a,57bb66af,a2f2f02a,8272de6e,3dc8b395,8959ad2,51b6d3d0,4c81952,59a501e2,8ff7892a) +,S(16f48c6,eb84fb2,81903b8c,b9f60b7a,65601d76,e2a57983,5569c983,39b4a6f2,8613bb84,8398681d,66f1e75d,5b6ef44f,d827b629,f4956a4,41d8f503,dd32b289) +,S(650471ae,774265e3,270b5132,33d12d85,bb98e38,2a3b3af9,cab6339,e1446056,838e7793,34aa6fe6,cae90a62,d359c339,187b4032,15d97cda,4e62724a,a5a50306) +,S(15dea416,fa34584f,cc90e19d,69825fae,348d1ba1,fd7ac821,559aac2a,bc21dda8,1fcabf2,1e19ce68,ee12a3d2,84bd1304,10fa5f5,d45f9c15,d4070243,a8433047) +,S(b42b2495,4f1f70ed,3db90087,8357ba46,ee9d6a07,b4f7c751,dc5cba07,b05b46e2,e15723eb,e0bdbe6,d6f28d6d,a0443c63,4851f5b4,c551bec6,9f9196a0,969ed71) +,S(8e9e4f5,c6aeac31,1dab1125,dec9b460,6ab10b7e,8e250960,a17fc57f,c0230f83,ffb0e211,c79fbb79,78bd4e53,a05a267f,f1e32c34,d6287dee,64576d31,ab959ab2) +,S(87be7323,73bd4b73,8627fb63,bd4d50bf,d6f2bb81,f804b528,29549fe9,3fe1ac2e,f6a9186f,f147b9b5,ffc844b2,ec0e255a,1ae5537d,75624288,ce8421f8,7e94e1a4) +,S(43601d61,c8363874,85e9514a,b5c8924d,d2cfd466,af34ac95,2727e1,659d60f7,8791c000,7c09c94d,b328034b,88c5bbbc,11333536,6679eb09,9a5e75b5,83bc2c2a) +,S(341b1580,f83071c5,365f0bcb,ba66af96,6902e394,2a2560ac,a0daafa3,2ab49d0d,4b985b13,c5499026,7ff564d2,d4649c6f,7e8fdbe1,ba101d94,1c034e14,64877b20) +,S(175e7cb3,ce4a3a43,7c7181e2,c79fb154,33ac1aa8,e56492eb,57627171,f14dad95,31ce61a8,7834f52e,fcf8703f,93696f42,58130155,63ca5d9c,e92d8fc2,81135b0d) +,S(5ad430cc,64e61c61,e3b3c848,2ca3ecac,89c1e495,4c80ba98,249e45c1,307165ad,bea2a060,505c13bc,317ca083,c5a8b85c,9ead5f6e,1ac23fbe,ac7cecea,9251c791) +,S(41dce0d9,6dace318,988602df,7fa84c1,80f0ce3,dd7d09f2,8aefefa6,db8b837,74962c3f,ed9a6e9c,896635ea,855323b6,8850091,f84dee33,3cdff8d0,d2827928) +,S(a5ef4498,87104dda,103c1dc2,52067643,9aed2d5e,432fe5b,a23cc142,39961bcc,1cbcf83e,a363e0d9,3e6ecc32,8653ba7a,a165c526,765b09f0,696b0d61,f122db3a) +,S(4da26ece,9ad46003,38bdf68b,852a2cbe,18225f2e,2d6d5e62,6db57235,fb3a9d45,d10b5a63,7ab546bf,cc610e2d,1c3d61f4,61b0a806,e7ba29c7,3d3de909,e9fae659) +,S(6e621e6f,53d2408e,488d8eb1,6a19a4f7,e9d95585,11e69111,29dedc69,f98f4763,7b148ef2,73e1b131,341ad477,9342c7bc,7b945a2c,b52c448e,4bb5fd50,3cea1a19) +,S(ebaf5764,5bed7469,9b57ea75,8a395a90,66bae20a,8f082ab6,da4554d5,278be83b,5847f4e0,6c653033,5e29ea94,389ee3e6,d916314a,60126028,650ab9e0,bfcfbba7) +,S(c0f88a71,711b632d,24b55dbf,52b15d2,faa38ca1,1438c17a,6a6ff635,3310182f,2cbfad4d,16c07021,86611eec,408082fb,fb2e9898,141a5248,1c59e44e,cd0676ff) +,S(5d9b6c18,84b79498,c6244fbf,262922c6,dc1cddb7,3cf70ae0,1b5287b0,5b5c6350,328e831d,2f2b162c,4abe1644,bb54cc85,18db178c,5b6ae97e,5e85110c,7d7fdf1d) +,S(d1d1360f,37ed6e69,d4f214c6,323a53b7,e57d7595,55904016,654c49f0,4e02e21c,627eea93,c6c9b53f,94559414,40a8b100,6eba68d4,6c922b6a,1521f394,6dd15e4e) +,S(efc987cb,f1023af5,58acfa18,97b1b2b2,ace29a83,65674703,e4969ccb,ee411731,195a6a65,d3790bec,71642986,3bcef432,e38242fc,9f565dbb,e159bc42,f5740c69) +,S(f3026b97,163df3bd,61b88b78,73864480,968d1d7b,83ef6b01,31090faa,18284ff0,177c3a61,682363ab,bf281615,d59f06ff,5f87644c,84d670e9,a6c56ac1,b611509b) +,S(5d34ff5f,123b5b69,92ac92c6,8c9cff46,deeecf9,68ff830b,5622090d,682c5873,2d1a0b9c,8eaba065,43204df1,48eb1618,25443efa,80f8aff3,d49b6626,c5955ac8) +,S(cbf9ba17,94a95247,c39da065,84308cc8,e0ee591d,31a9b0bb,dac67280,468447f4,549b18c3,10feaea1,225fade,934112d3,4058101d,74f00538,1b82796a,d0461736) +,S(920975ba,9e2261b,bf5982a6,b57a7344,8e7747b8,368d7a53,79acacd4,c7dcd31f,e95e0508,81af550d,9221f5a,e9541031,6367d24b,d545bdcb,434e7638,acb46dbd) +,S(815b2ae4,6fdcb55d,926cdce8,2b4f25d0,39132312,3bc180ff,33fcf132,7eeca64,62f637c6,7d886374,8f1e2e26,865118b9,99285b87,55f25512,c968b4fe,49b8c971) +,S(1bb9a6c2,8e28d4ba,30ea8639,7a4d387e,27ca8025,da231926,de3c454,f7e0b16e,a0cbc016,5e32171c,8184265e,ac7e0147,206349d5,41035a94,f56efc49,dcd7ab93) +,S(6f0153fe,dffd83ea,b099d29d,dde278f1,9c05a4ba,78eb4c3d,34d337c6,da68bc22,a532d00d,35013f85,9f4041d3,aa231f2b,9fc49967,e0e2f82,4d5051f9,e7f0c626) +,S(3454f73b,3bee77a4,d00d384,71bf555a,ed23e5e6,c6dae855,2e9cb7a9,1b20258a,92c20846,cfdf1e8f,3fe5bcaa,6bdedc3,9926833a,3f40d28f,23a8f952,d8d18dde) +,S(367807c9,a3606b4e,1b8c2616,ad528030,1dfcf686,40eddf02,fc59317c,230e9a86,1f023f2f,a2bbece7,3dba14c,124095cb,fdc4f92f,281a14,8304a412,c16ecae6) +,S(8ec4fdc3,9891f6af,1374e06f,c44b815,1b82541,75fc4909,acba5941,201af62b,2dc6cae5,cac2d887,83dca0e5,3c798f8,fe067bcf,5fc29751,13756cf7,ef4e5f1b) +#endif +#if WINDOW_G > 10 +,S(5cc24a6d,4c5b24f9,14542f91,e5fa937f,ffa08551,51b8b842,8729b06a,9178a263,b1da8635,81531a1f,bfb38a4e,419fa1fe,ca8d55a8,3ddbcb98,da19d5cf,fb7da472) +,S(83905926,c03905c3,a9644a6c,da810dd2,92602a50,50c52a21,9134fc4d,e3599e9f,4293260f,e8af6792,a20b115e,aa837638,9094298b,21d9de16,cf20e0c5,7a46089a) +,S(944b097e,4721e9dd,f8204ac3,d3878fa,e8fa6c14,34ae4822,481b2985,6589b6c7,5fc47565,30e9b095,f8b79643,1e745b99,1525bd4c,4764e8e,e8af4b96,9bd6ddf6) +,S(ab0b4a3f,cfb7c134,e1caaf04,a63a7331,17327a1e,5fa90301,7b5ebbf,3423b73d,e1e79263,a5bbba8a,cd78c92c,faeccd3a,b84944d3,785c0781,3763bf1a,ce96c9da) +,S(57a344b5,220f2b0e,f7bf7fbf,5a2e4e7,1aa2c3d8,7bf090bc,f803dfee,fe8b85f,f82b7d0e,8ef9620,e48c9f13,53a72a95,a9e11a3c,1678cf10,576e639b,b1a7d04e) +,S(6e053e1a,800b7c4c,51f8c4c9,5cf0f4ff,3608e396,ec46188d,a1a9263f,c8d81ac5,86389e98,e3c823c9,e1b5384f,fce428c3,62e36579,7202fdba,dc3d8c49,395e7473) +,S(62d76406,1804717f,b30d4a7c,7567b545,48a289ec,7f083f1c,59deae25,ce485cb7,f1d6314b,661d1f8d,8531d57b,9470fb53,d1509b2d,a626a0fc,4cafc941,b668be84) +,S(e5db28f2,219fb2aa,830cf108,bd2449a,5c4d0800,82d34658,9e347f31,dd29250f,c296e646,32f97dd5,ba3b7012,ead44b6f,324fcfd2,f35f8b24,8e58fe68,888bd453) +,S(4725b3e9,a3d00de4,8a53177c,9fff831f,733ec89b,c2994ab2,3fe815f1,9b32729,ac3b7747,de38c00f,145fdb74,1482bb52,324127cd,2979ee12,d4a9e689,b9f8e778) +,S(d0d3afb6,492c72e7,394ed918,7013e347,b036b65e,a76e0569,bbe9e346,41d72b3e,2dd3a45b,94aafe07,53061caa,a28560,bd952b0b,2f63f13,96f42fb7,8e02fef3) +,S(7853e735,d717c857,97b85654,a24acff3,104143ed,cf4b4b4c,7869068f,c304632c,a873d9,e70fd14a,c2777a8f,b5a02922,bae3a31a,14938e69,cb535355,de1efadd) +,S(6db26b3,7d4fdc59,13a1a01a,14c92356,ee44e2c9,7f9d72ca,7789de33,8ee904a4,14fe2225,bf2ba0cc,28c1c409,e9849c4a,d8adf792,63869b68,54a28ae9,631941fb) +,S(b52f0869,bb98af3c,b2f7f5c,669fa43e,538e400f,63a9cce6,99aa2ef8,eb2848df,24566b24,55bc454a,e7b378cc,a0e57b6a,8b821c8c,a76fb858,bb616e17,8907be5a) +,S(8614dde1,1ee6af03,eb34a9e9,970fa7c3,234152c0,1384f7e4,c1e1f93a,197b448,2a1125a2,ac996870,2ba22b5a,d230c40e,4e5c7e55,d8ba6ba1,5e54d3cc,7b72f3cc) +,S(982a37ae,625f6e5b,78e71c18,f20bdd0,8b3308eb,59d0cab2,dbc20937,938c1cfa,671fe16f,a65128,591249e2,b5070bf,2a689e2b,dd6c57dc,18e5309a,b6a40d0c) +,S(6bea9305,26b4829c,ec99742f,c9231c00,627a09af,22ca9d9b,4081a2fd,4c3e703a,aec5402a,54517b4c,1f344d14,b1943e69,d7541f10,c45bd483,2b02b059,499a6cc1) +,S(b5724781,8694487e,7cc188b3,36d116b0,54016a99,20731920,ba7bd29,96583edb,5cbbd186,1f80a4bd,3d58262d,ebc58ffd,1d278fb3,b4d7fec6,208f6286,77845cdc) +,S(de1ade62,7ba00e91,786f4f53,18ac5392,4df5a534,704edbb6,2e0e9e2d,997c5412,7ef486c5,bf23bfb,fc6dc15a,41c0673f,a9d003e6,e1d09a8e,4bffee9d,ae2021e0) +,S(3738a57c,b1721c41,9f9e465d,fb80e1d7,33720398,bc01166d,d476d36f,3398c0a0,e1f25bb2,1662b16d,6d28a629,ad84385a,43df566c,52924bfd,11854a78,b70c22f5) +,S(4cae21c1,6b2a1239,a85575f1,2ddf6daa,1955feb8,b7502e37,6940006e,7a81885d,2affe855,388660d8,27671e89,c82832b2,25fa2c9b,29d559e2,37af565c,b4dc99c3) +,S(4c511a1f,ba8a0be3,6e37cf55,85bcc3a7,97bfa7ee,1baa6039,5732faf8,dcc2bd7b,ea69f794,5c6babff,23400fd4,a95d6833,abb27269,887c372d,8a6a45ca,b25651af) +,S(d811d8c4,323b4370,2607c25a,de936c0a,c2e4a44b,2ba51f83,20c5179e,745a7e29,6ff970a2,17bf47f8,da0aeab,cb490e3b,46c6df3f,69f9e93c,3c4dd94a,e7c05345) +,S(101eb5d3,b5e5aaff,e39bbafd,f13b5ffa,33db68ae,1fb09b0b,1cae25e6,16c43eee,9d6a5514,9867725a,607a1c96,eb03120c,a4970939,34e0cf4a,1631a63a,bac5ddb3) +,S(89eb1152,b8dde45f,e141f21f,62fead1,ecdc7f70,eff8f968,de21cf8b,72480519,f8a337c4,3181e3d5,69ec99d7,f2bc4770,cb6703a8,63fbd95b,41fdb07c,b697b447) +,S(53d633f3,f48ea44d,273d8f1e,455019a9,49d95eeb,68de70cd,bd1e964d,9ad0dc16,1b26ed76,964dcf1b,3f7fe6f3,2e6db7e6,8e8ff4ee,48fe63af,48ffd33b,cd1645fe) +,S(de106910,49891106,59a94d26,b9cedb64,6ce3db4b,8398ad1a,92f8f95f,d8d9be6a,87640b41,dbd99d16,578a3d06,d23d4088,8768a4e6,dcf83e7b,5b9d9133,5eb43d32) +,S(40ed1e6f,b9ee245,ac189a9a,7809da10,cc6daa7b,41a163ca,f761773c,6af5bea2,ffed1501,7298fb9a,78eb7bdf,1430ac04,82bae82e,a7197adb,50bcc1e1,fc217b2e) +,S(55faaaee,59a20b9a,3784d171,9ea529cc,1b7ab3a3,29f26dfa,a3b11bd6,67ba15c1,a9f8939b,52ac53e3,5ed4771d,8e47065c,d7f2805,a7e5475c,37353ddf,182f4a65) +,S(b51de64e,21cf88af,2180ca17,24956d10,a95ac607,f034fccb,a53bd02b,fa8af3fb,175d9b70,1c652ebf,46b99f1f,6e66c4a6,9b840019,a48b1ac4,878b386c,3b7f81e) +,S(5156b0dc,bcd91e82,4bb235be,9367cf40,7b8927e8,cd874171,556f997b,7b07b143,1d457c0f,a29d4c3f,e65ded19,1127016d,d40ada90,cbb0d8de,c2af4bf8,20cc91dc) +,S(3bf51d72,60b4973,161fac55,88e441a7,f1993c06,791b6bcd,e11d8e,96dd63d,7bc6b470,90a7afdb,fc63905d,df698499,73e1e4e2,af74f126,63eae8a4,f4722d49) +,S(d2971091,20088102,1154f4d3,ba6f2da1,22fa74c6,4faae05a,d76db7b0,9ad61fe5,7350ebaa,f2ccf3c8,f940cc14,151c23c2,bc33cb73,65528156,92648f6b,628e3fc8) +,S(c2ee47ca,8e17112f,a255a520,21ffd30b,6d7a3b7e,2341526c,559b60a9,c768013d,2e6e8b6b,d83b7f5b,1dc8e83b,edb3b23a,80d9ff08,2029831a,45305016,2bece448) +,S(559998d6,9ddcce0d,9e0da39e,96cc4c00,c5ef444b,561dbaaa,e475adbd,3e70b6cf,c49c2a00,95aeee5b,8deb5e8c,db4d21e4,cf0f3173,1af2fac5,25c534c2,34ffb328) +,S(4b4b02c3,e4c8badd,e45305c3,9721a98d,7c1955dd,90dcb2f9,e9d54901,6bbaf363,a0b67b7e,be8f59b3,c25d546e,3dc304d,d22a6a64,615bcfb9,25b685e3,18d43468) +,S(fbafe7fd,7836b427,51cf897c,5d42897c,7650ade8,ee1ed01f,e0d7dd2c,aac549c5,2f511943,52d07e51,7b7841f5,8eda5225,229a7e28,9a453aeb,5e70110e,12668436) +,S(ccd306f9,c65b8a0,7884e620,b73ac4e6,81b21bd0,2a4b219f,954de1b6,7076c06c,823fa47f,a7b0b50c,907056dc,73e04574,3f68a7,5a4c8566,8ab5f5b1,5657510b) +,S(bafbd838,995a691d,3b5a870a,7847452d,9124155d,d89a9980,820b8d56,18195a3b,8df4c9fa,c94829ee,fb0e7f52,1020b5b0,4f05f4d5,839c8687,4e893e7d,8ad92a3) +,S(d125cc3a,8073156e,a166af8,ff940a64,713d8f37,b86919fb,157cc380,224f458f,a030e8b6,ac4e37a7,df01054a,ea23a78e,1bb7a22e,f26052a3,a034ecbc,bc35abde) +,S(7d491f28,1b5ddaba,ef2c6433,be22e42d,f2d1bbfd,8a7e8866,8cbf278e,cb8187c2,ca18161d,70360966,ca381ea3,f760b2fe,28b040c7,ebc82af9,bea27ba6,f4dfe8ed) +,S(31ccda33,9f29123a,86c2995c,6a9f4979,6d70a595,5079b961,6015f07b,cdf8c39e,aeb27d0b,edf61fac,99528a9f,f060d1f2,376626b0,bc807a19,561c2e4f,e8b49f65) +,S(79e64c7,f45f9189,6c92073e,71b76fb1,e5ec912f,de11ba7,d7439f4a,297807ba,57d93436,b354963c,5891abe3,825d89b4,d17685bc,c9632e7e,fe85ded7,5823c921) +,S(d6232edf,fccb3868,71ef057b,60bda43f,69f422d2,debce06c,78a31f6a,8c42274e,13daefa0,b2e2e09d,36f472f2,29b5f7d1,58a18f63,ac3dc4d6,d62cc7d7,ec0ef826) +,S(21c0f298,b2d6e3a5,3738fc00,c8289458,722d78d2,48a33ea6,a7ebb667,446e368e,867553ec,17d2fd95,b895eede,15da569e,cbb3f25a,e5f334a2,b20660df,df062383) +,S(1d1a3d01,dcbf799,d551621c,54f74720,eaa2311c,3fd9b1d0,f4f2caee,4c3196c8,d5a7a115,9900f90c,879b1a30,13945d8c,5453bf1c,7e5e33d,6f8faeae,439734eb) +,S(57488680,8fa99ede,ca97d1,8582a151,62e26d5c,7753a561,4f4bb1dc,28e76735,debda859,7117ede0,dcc0ecc5,4ec1a494,b3bbee34,95db2b1e,ebaa1db9,2fc17c6f) +,S(b6dd34d3,4ce1dffa,4e1e820c,4c8bde9f,607194d3,1c1ce07c,9f6fadc8,9791715a,8bf48868,e405d533,2adc0ec9,49bc7cf,1487e554,3a043200,71786521,8a39cc9d) +,S(90f9ded5,69088772,ca2bc887,1522df9b,5821df6c,9e20b160,f3504bd,4a91d0de,d17e64a,dd534a6e,fdd0af26,b4494339,f76b3c1b,126397f9,a2beba76,eaf902ac) +,S(c55f34e8,58d19353,9106e4a0,c3002873,db07b239,9b10299d,260acc65,6b2cfa59,7d9f38d4,74b5a22e,72949f7f,e2cefb34,9a8fe1fb,c16b8dda,11f162de,30e50f5b) +,S(6ae44192,d38981c5,9b3f8452,c4a2b627,f39c16d2,b6f52575,c5f1722,56b8ecad,9bbba8dd,7c49204a,9edc4b91,e38e4973,fa61de1c,eda6ad61,603d9715,7f0b099d) +,S(33a7d639,423e1b36,6a93ad99,eab6444c,bd0c251f,6cd8b79a,e0344eef,6fdcffbc,c26112cc,6dca2a,fa52684f,c9ed22d3,2f067891,d5bac2c0,2bb86e3b,9411c61e) +,S(48471331,eac48670,28fa6642,a76ca6c5,3380c1d9,f52a4b2,ea640d47,f159af0a,b4ea8546,93fde01c,fb903a31,18bb61f5,c5047b94,705a714d,5b586d47,a0142704) +,S(565ac39,9ae731c0,4cffaab7,43d24b71,72defd79,beb8ce86,d46012a5,c2587917,deb56aa5,d45031ea,fc411fec,e09a9646,14664989,fd4f40d7,79c02981,98bbab48) +,S(964838b5,3b6c2b7d,6a8d017d,c5a32fc,99549094,6dcbf773,eaa7085c,98314c0b,2daf9f3c,ec44034f,c8a71ee0,ee76bd77,ac6fdc9e,fa042a2f,6caf9c5e,fd130b97) +,S(bc00da90,7b8d078b,9d83522d,ae548b14,6f9bff0d,2ef887c,4aae2f1e,c4eb88d5,6bd0fd11,f9e2db73,65f21dd1,34cb29f6,fef4d7f,b419abef,eafe15a4,20ddb152) +,S(1a59f855,f89f0c,f13dd8ae,9f5e550c,a2082bb3,27fb111d,75455ab,dba7bea4,7ea2fb40,d460adff,c9e25c53,a65c508,e77e6e76,e2e435c2,150c870a,7600c823) +,S(7a3b611b,d3bffc6a,d4508162,45695024,452706a3,279a6fda,d88598a5,4eccc764,16e09589,68066e52,c873d6ef,e549d3aa,83d30bd6,a1d730d3,68aa1ad2,32233145) +,S(2fed5577,9cbe0a5a,786fa95b,5c56e27a,a0a1cc28,51112bef,4cd5e1b7,15d6d91,7eeacc27,b2297fb5,63d691fa,36dc650a,f66fd3e6,6fe5e637,9959d46e,2d4bddfa) +,S(267ad217,952edf65,673efaea,6bebb44b,18326dd,f1b36d02,f0154a0d,774a9558,77593cc0,7e9d5e5e,688a7b33,bf54a01,703cc9b7,a0485e6d,907515bb,11a13fef) +,S(eb6ed62c,239b99c8,6978ccec,a5f32145,e0d341b,ca7eab10,6fa05ee1,7f6687e8,ad899e22,50f6a8e8,ce29b225,83ad8755,2a6e6ab8,9061d33b,6629fbfc,52c0a241) +,S(ca5cf17c,e03d214f,b4ef33c,41686c4f,5087a59b,f88ca7b1,891094d,430a9e5b,17e44eeb,473f75ba,cffae683,c8ea0299,e1935180,7257803e,f9963ad3,d0989ce9) +,S(4c7bc29c,acf0642e,63f035ec,a93e6b6c,c82f21cf,46623a2f,e4c7215e,51e82f7c,7c55e76e,8756796c,143f64e7,e40a402b,eb537be4,f1f5322,e59d2be2,82776875) +,S(57cab8e9,b42289f0,503e5013,acf4dd7,79783184,2389fd20,80b61bc3,671058e3,78225318,6671273d,a7b0b884,e72e9bee,2b048c45,9430d2ca,7c398aaa,9fd9e2bc) +,S(3c2bf23d,f1120c34,de813a82,a56843f5,abf3d272,ed2e6c27,53ff6310,9bc4823e,1759db63,88aed233,ce0c5b47,ec9dcb88,76740928,e12fe9d0,d08eb759,2d3f1990) +,S(c010a9ac,83e0742a,d3348dc,3dcfddd2,34170aa2,28d36856,d8581b1a,eab38d2,634c97ed,644a68f,e1f1da1f,190cf920,2b2dc810,446b78ea,9cd27684,3c76aafd) +,S(a4abd9ee,548ba468,e4cb632,b3d9c8a9,4f1b773f,ba3a9660,5504593a,92071994,3a14266a,ba263297,fc6ab00a,8403565d,c9390b48,ebffcb61,11b5e8ef,c8f87182) +,S(dc02c852,efc115f1,c5c08540,deceffe5,d68b82e5,99b78711,5a7a333d,e8dda172,e4e6593a,8e1ae842,ca7f4eae,d8cccaa2,8a35f8dc,cb8549ba,2367faf5,5f6c29c6) +,S(ee4769e8,223822ff,c28a5a4b,5f29fd7c,a54fc81,72175cac,1b6db5a2,91ec57c8,fca2c6bc,4076c8eb,a0978b9a,2b0158c4,33890514,28094619,38413fe6,c020385f) +,S(f3006c1d,34910c0f,d435a6de,cf088c38,2cf990cf,3124f2ab,b11d2727,d93ef066,7629f5,aa367f51,a29ebaf1,235cf267,f8016a6c,88dfcd9b,82d36904,c949eae2) +,S(7cfb203d,7bf5669,129f0a3e,325c3fd6,b1b9c804,4932f0f3,794b9357,1e7313b7,4f76b9fd,24339c38,c88c4217,387b016d,e4ae08fe,67182d39,82a45bb4,e82bc60f) +,S(cca3ce0,36e00993,9d30be8,e70455ad,efeabe71,83aeb206,a324d0eb,32312c0a,9674ae58,fe947c6d,34c63725,2058c88c,91b437dd,98da58b2,efd7e8d,1615b9e5) +,S(9fb64148,81cd5c27,82da071c,1f98d71,d9815fd2,2389d212,c66ace66,ab0d9c8,4c25454,1a513742,5f75e515,c04f1c73,d11d5047,9c76b09b,ce23c13e,d1813251) +,S(1dbbebf,3e3d459,10d39de2,32560b4d,eb5d2ad8,6aa1542,c2c070b6,51558b25,ec68e71c,2e94e490,4194753f,d7484ca1,940eae51,69831876,877b9ce7,2d0b9db1) +,S(7751d219,92f47421,7742856b,4c84d41,5a890ee9,24185e21,5a210a3f,a46bb5f7,2915a9c5,b770c86c,edd32749,3f698c17,6371f6a1,4cac5a22,73a3c648,1b237fef) +,S(39a849a0,5b189c3e,20782983,ecf664b1,e7b89c96,4e11d737,70797fca,ecf36a2d,d3e6f8f1,6191db06,be2274d1,56685895,48e69253,54f41114,f43b5ed1,13690c5) +,S(67e56125,b29ced20,f9f95522,d412d67c,80e3d628,b8bfddea,768117cb,e79b25bb,608dfc15,7e3c23f4,4aa0fd88,3d02d293,3c83edcf,66ea57f,9167b712,8d03da21) +,S(a51aeda,2f7d59d,d31eec20,e95839f6,ecdd01ef,529327bb,5cb229b7,b78f1525,704967df,93fb862b,3d38b18f,4c6818ab,6621c7d0,80d92cdd,1f0092c0,d7847903) +,S(c980693e,73a1cb46,f5eb71b7,73b00389,f8bcb36f,fb489e7a,aae64c23,6ac1745d,bf3b808e,fe6b7efb,771853e5,6fbba6e8,b3b21fef,706bd4,274cc058,b6fae474) +,S(c78df930,bcf54c1c,28e27aab,2975e9f3,94167bd2,948d4713,6b17a374,a1391a9,9a424f36,6d3a79be,55bb5e9a,283be1e0,163bfe22,1bc65e5e,318f0de,304d9ae7) +,S(9a75f7bc,c6d2f3a9,e6168ebc,8f7f1e50,a998b1e4,e67316e5,fb242fc4,6d284089,cb478e6,dff8b9aa,3ad06c6e,8fc7e35a,39bf6ec3,787977bf,d40f3159,bf169e01) +,S(76b2131a,db0bb3e7,db48277d,95ce73e4,7eba1e7c,b6f801c0,d20b71a3,8b6e6224,32e3cda,ef60e55b,a9e36e6,cd287737,196c5af8,120c47b2,f79d2492,9979263a) +,S(21898361,4ec5971d,f55f96c9,3da89483,cdcc4c46,deb8de68,f32a42b3,5c1384e1,2c396c50,44a4953a,b22a2d22,47769741,c5eda54a,d9c9ac97,d6486b5f,126dac3e) +,S(ac0b0a49,4e9d180d,101dbe1c,a528fecb,a08449a6,cf5d82a9,aa14f875,e3db8adc,26d1d412,25a1b583,2dd53b9c,56a6a8e8,371dd19f,31462dd9,b2aefe3e,70412554) +,S(f869b58c,851a65f,bd6d3329,75f596a2,9d1a78cd,bbf04a1b,6dca6c27,30e04625,40dee344,fc6f5c72,c18b1603,e149949c,a0cfb31b,b8b91b09,c3cbabb0,c6a5bff0) +,S(f74f02db,2406250f,8984a5f2,273c63ed,a640a43a,8e7d72aa,ecf78d6e,b9544c3a,882e3a6d,cacc1e92,8a3c1a61,85f2bcf1,5e364f7a,1eeeaaea,1c0af593,cf86185b) +,S(c0613eb6,1d6755eb,2ebc9284,a0aa69d2,88c39050,4b7e869f,f3d943aa,67ea65d,72f61ae5,27b5c82e,4afa8966,55d9289d,29931c1b,f0d36c09,fe4213c5,27848cba) +,S(eb66ff98,60ba08a6,3c0fd8c4,7117aeb0,ae0dbf63,524307a7,eb739f08,f31285db,c3142ca,54bcf2ae,8b05dfb9,4e40f4ba,7d3662f3,774e616,55c7515a,87ddc5d5) +,S(3a7108e6,a1256061,fc25d58b,ca534602,e41c6b15,156c15b8,71a516f0,ec4a861d,daae2d02,41cabb2,191b5be,c17e7e88,957bfcd7,66df1226,a183064e,3c4393a6) +,S(d17e3a58,c83169d1,33ee7371,7b205f2c,ea1a2ff3,4e744958,949e9403,b8f89d5f,98c35f7d,69e5d98b,920ffafa,6d15d349,2d75fcb9,81ca5022,5ac7ff32,618b1a20) +,S(d6e32892,cefbb8ed,14350cbf,2618e2fe,98caf6d4,f7679385,fff36bab,bf6541c,7175462e,be0f5ec0,7872b55,356f2498,976196bc,edbe021e,8081ebd,b2636298) +,S(318d49ff,60e900ae,6e8e2182,f38ec006,82ddc8ae,93aa6291,86d5ddf8,affef75,6e97ec27,dd7d614d,c1ed4fd8,fdf6aa70,8dcc3eb,be288831,a9888166,66333b2) +,S(fd6f9e30,1772db8b,a68ea5ae,b585abbd,c075e72b,68d6f67c,5a2f8144,98cf6346,dadd16e7,64775bd5,ca5c5f51,35843556,d7608230,aaff4125,4d4eab38,1d28d2c0) +,S(8fe25b38,a2c74761,a90ed08d,4bce768c,f074282a,e9560d31,566ae43a,182ddd36,6ee1e84a,77c6ab78,a2cda1b3,2fbdfe2e,51d66843,271d15c7,3f8e1a82,1e4c23a2) +,S(37cf0ed2,88ed8fef,4ae17bcf,f6bfb815,3e12bab2,a46d7e5d,2e6feb99,9793bef8,92e7a57,18eb0751,c99254f4,ddb5c278,e17a417b,21793339,119a146d,bbe3e0d3) +,S(688c2061,6b9d0c8,76deb812,b60000e8,eca0e04f,531ed1e0,9158442,7bf403c,bab4b2ba,41ba4d53,df512e76,32200bdc,11d8583,f2ceb5bd,a8b7eb14,5ccc01fe) +,S(4b4caaaa,f5399535,d822371d,63965216,d1b53584,d89a84e9,d868395a,70b3d804,3ddd27af,cd18049a,3b01d043,7761e4ea,652fbd91,115c470a,e4c7bd40,51ee73d2) +,S(6f5acbc4,4135da60,758ed9a5,18b39b5f,47cca398,24e20e56,1444dd52,e2fa1d2e,5dc9d46,e5f6d94d,48af2efc,2f197a2,f729f1d7,335fa569,524d37c,4acd58c4) +,S(79d2d449,3dffcb91,6fda527b,f8b6b622,661d6f23,738288c6,ce94313d,c267fc42,b2683bf1,3fa8f7fc,be302823,dfbc9153,8d902791,d5d6dde1,d2805f37,a0c08db) +,S(33a8e87e,246b7b9c,9c77a6b0,7cc67d41,f3915dbc,2180118,c0800b33,f9f95524,baa8244c,584fd05f,2655e36b,e2e5c459,207d30ef,dcdb2294,70b34333,9d16ff8f) +,S(9a169132,f3887df8,20561a7a,e4bd5461,3235ddb2,fba7a19,3f4daaba,79868e95,686fc317,995446c4,42945216,1a96595a,a233b100,e5f8bbc0,71990229,44630bcd) +,S(790b74f4,8405ce3f,9abdc7e9,439f2f5,c859989e,2ca5e6fc,29046104,8783ac42,8961c913,562385ca,990593a3,77111a5d,1dc6762b,b1a928a6,6ebb304b,8a24a701) +,S(e2a3d0cf,ae1fc2d9,87caaeb6,9f32fcd6,95471785,f524e438,b5487aa3,72f9e49c,9cc24205,ecf2708c,357edb54,308ce452,11f7dc03,98fb48db,4982d337,14c93046) +,S(cb30c43,5992c195,76d372b1,96f2ae68,cfd2653e,63e3ba7a,2b3c21ec,960bcbea,f65735b9,708338c9,acc9cba1,4b491b8a,fb683058,266a483d,4987cdd3,89ccd0b4) +,S(1faedc95,d6310bee,6298ffb1,6fb3e6a3,296ca66b,7c995d2d,fe924381,10e8b46a,35039e3f,8201e904,e5378d03,2bd8b766,26d9f0ce,4425d2ce,e7bbd24f,b8725089) +,S(a646cf5a,2be8c1d1,3f05410c,ed51b3f5,8e93ea53,1e28bf31,8f6c750b,52b3e8f9,58c58ecb,7727a920,b47a7e78,e1e51d11,e427d7e4,465429bd,a01f4650,a4c102bb) +,S(32734727,18537d38,e9b8c397,a5cc322d,1c77c0c6,15eded39,dcebc020,debe2205,c2debc89,58c3f60b,d4c7b072,d475a7d5,c1ea784b,c3e532bb,72c02490,9a42d65) +,S(16a1a718,855a212,c068c095,d930a270,9906dd22,e7db3f4d,4ce2f393,d572827e,d389d64b,b30ba9eb,6ce80335,cbe8f7dd,b1ef3016,a8b74660,2196b724,d115605c) +,S(b4bf4d14,5de25571,33694b86,76166e90,eeb1ebf8,4a7402e9,a61af4cf,23687596,49db20a4,d82397e5,6318640a,6b605e96,37d38961,a58ae3db,fac2fc11,bbd11242) +,S(d4ed67a9,ccf4665e,418a0de0,8d9380cb,fc311413,e90a964b,bf367b9b,b892630,8ff7e57c,e79a0883,1fe8a972,92493764,7472b77,61b055fa,37105d18,b51df131) +,S(8ad256f1,9f413ef2,eae906f,c1c2ca4,44d5dfdc,f916d366,b32f1f47,f54fe70d,bdeeeb41,8d2c4dc5,82547f65,91c97219,34778f5e,d25eff4,94e243ed,a6d34da7) +,S(8dd3e2fa,fe55b5f1,f13723e0,1a5587b9,c67d22ee,21f1f62f,7f62a15,31f17f8e,aa23d2a4,7d6b717e,55d7c6b6,5d9c46c6,8f2db41c,ba66960b,4b4bf93f,5fc88cb0) +,S(44fd9e28,2a8e30af,ac34db01,a7b0e939,3c13917,554d9a67,8e577a5d,4b3d0f6,cb079061,353319b3,a1669d59,295bdbe2,18927d06,ccb1290e,4840cc16,911a61d0) +,S(5d249a02,4464ed65,831d2aa9,c9645f46,2db7c9f4,e5a46477,746b1a71,88b7aa42,2bff7386,527d6b5c,2c595f80,e08b4d20,23bb8dfb,f294da12,b54f8b14,77281d0) +,S(d98eb458,1edcd51d,465e123c,d891c481,ddd18b54,b9408ca,85ac47c8,e10fb23,15bfd3be,d3756ac6,f2f1f9e6,f254c9b,2b153717,1b265081,6a2cc21b,78b4dcf2) +,S(2f12c369,19a2aeb6,2132134d,2e85150f,6edb486e,9d672eb5,876804d6,44db6082,c0111edd,3b4d28c4,edd264b8,dc2bd0e3,20834dc7,bda82dd0,827133c5,7f8cf73b) +,S(4d949684,7099c9f8,421d35df,ebce57aa,71326034,8f07e3e6,f03017c3,144b4624,9afb5a57,d71369c7,28db308f,b8b07da0,b91f954d,b182eadb,126b1fff,ddb673da) +,S(cf1db910,5e95f1c8,e360b39a,752ab17e,fca8f24,d9ddc8b2,a9768700,e2af2466,e7c99f66,c49c8674,a6c1b94b,4b964019,5e645ca7,b3d2e004,ad8dc73,f647ca5f) +,S(e71eb425,7d2ffa8a,b79d63a2,42c67585,d4b1747f,5b27f22,a9ee4284,6aa62b85,a906aeec,f901a376,7d721f45,da53e342,3bc0a779,870e33c3,d10f6426,6a2c8865) +,S(bcd987d3,b2575f4,3bc5c3e1,b4a299bf,21c58b6c,a27ebb21,8f9882ab,30559887,403804c9,4339ae27,2bafd894,e63a4eb4,690c1b4c,9289db00,761e9b3a,1d483f65) +,S(b74d5cf7,48af7162,395d2d5e,8a69f740,7a2bebba,69564042,ea9c7e34,b1f8cab0,b5c5fddb,332bfb59,835e9a23,4afa4543,5728dfaa,7dcfca3e,a3c57deb,e849b336) +,S(46f3def5,9835c9ae,1a7b3b13,a920bea9,e9bc12ee,633b3edc,57251b72,3560837d,587b2e1f,2e8eb9cb,37aa6977,870214ec,818fb71c,1035eeca,91d53e68,150ce67b) +,S(8d3418fd,eb3f0968,de51f4d7,cbb60299,a50ceba4,1915d8b6,5774cfb7,7667d572,cee79910,16a28462,aa9da7c0,f67b4c7,e8b3dd38,f4b2203,9d05115a,ac661db8) +,S(98cb0f09,4510695d,78a0a672,eb67253a,30f4327b,7864fbcf,529cf212,ad6f7c10,25952dac,4e1b5035,9b47e9b5,52852d1f,300fde75,a6bd532f,9fd56af,2a0ab333) +,S(96045e4c,ca075fc,4a5383f3,f03de105,a34c7c4c,b030ceff,b58b98e1,2b39a3cf,f527b8fd,92234151,ba11f24f,7bd5dfed,6ebd03e3,a5048c6e,8f2d5231,7201bafe) +,S(f262e891,42addef8,cba26a9c,ad779761,c3f4b3e5,5990a93e,703bf56a,99cc6030,275cc764,86c86a90,f597dd6,7092ecff,5382c7b7,33939ca1,d1f3218d,6f0b594b) +,S(cd79c02,ee175336,5f9f7900,be51bb2b,ad75ef81,3c6c5634,7cc717db,156d17fe,b5ebe8ff,b30de5bd,a5326044,16abbae1,4ff9198e,b491794a,c4500031,947a985d) +,S(28b4bf22,5b1d40dd,e0122e03,e630830a,d9ba4629,cc51c9d2,80a225f9,48f858f4,24756189,98bb414d,4a534c6b,e300297b,aadf4ffc,b10e6795,4ea36e25,2cf3cac0) +,S(f018f206,7dd55df3,9c53344b,c6128a5f,cc765c36,c7b0bea0,16c8465c,c6ed2ff7,d9fc5ab2,cd619d4a,c66c1cd2,251504cc,cda34a76,86c5661a,960a00f8,e4aa7e66) +,S(496968cf,8086d02,9a5dd5c7,4f47cbda,7f661ef1,488b3942,18ed886c,424a7a13,d7d8df98,442060e0,f17a363,579c6600,360b5124,2774e2df,c8d4b787,1e1874e7) +,S(242d4c59,e9113b77,68e48574,93600da7,b984355c,a1d07949,8921016b,22efedab,470dcfd7,b0c8c2ed,63a28074,a505573b,42f50920,6b0ae577,27a8b796,7a0f42b1) +,S(b6b804cc,1a1a59d3,84c4afac,c5e5050f,466280bc,d5ab1586,1d20f4dd,1385e8c7,2f789346,2a636a9,9ba2a1d2,32829f41,39b57967,bb26d0c,898798bb,6521d439) +,S(dc30a3d0,7ecc5fdd,38b8048a,f281024b,46904b2d,2a4c51ca,d1b49b7,1d918a4e,326409b0,70550e97,58f53698,7936a54a,b701f7b6,78a7d10f,ebb511a6,c18cc917) +,S(e1fe434d,345bf330,83abb628,f4f44ac,5fb22934,977813c2,c015f2b,43d3fab8,1b251ca5,2af897ac,4c08df48,ce3d1607,d3b31b2c,2dcd7f7a,59a95b07,774c4d83) +,S(a8ed88da,e08ac5e2,afbe4a40,ee775645,82c2f513,cfd72060,bd1fd5d1,76fb8d08,f4fb60b0,74419630,fbaf5b53,717b2a6f,5cc2d98f,1d29481b,77b1f9f3,84175729) +,S(b52cf828,de1e9cd7,c95c083e,ec50d228,8e770713,a0e2543f,76fa5790,2c7c6481,635a3953,46fbbf,903dc729,d3e3b52b,43eebdc5,3748ed83,3c95eaf7,1b75790f) +,S(702079ae,f76d9bfd,ccb957a9,4aad93fc,b1297c54,d634978e,4dc78292,161d5e83,4983c08b,f2d81c52,d3b3a202,e0c6ddb9,32a43a45,c4b95f82,c8c10642,5a783b52) +,S(4638d4d1,8e9de1ce,ef4fe8cb,db4378e2,3ed3dcb9,513cc9a0,dd73ee2e,be57bbf5,561ee032,45cc3066,968853f7,51fa36be,cb50740,a5951e87,cf77ef20,cb27e110) +,S(eeb34eb7,5facadde,d561dc5e,e3d0a039,d98e4880,910439cb,ecfb22d9,3b386bfc,f2b23cff,5ebdc8c,558db8c,1c311a94,e9d8f63a,d1cf4af4,c21c2349,a6e57c4c) +,S(7f2c6e5,becf3213,c1d07df0,cfbe8e39,f70a8c64,3df7575e,5c56859e,c52c45ca,950499c0,19719dae,fda0424,8d851e52,cf9d66ee,b211d89a,77be40de,22b6c89d) +,S(6ec76722,1ec5d27c,f7e11064,d4f8b016,3cea090f,6a950f81,85623303,23e53647,9b03c757,9704e839,c8eec7d0,f063c4fd,d0aa7ba0,5ad75254,984b1703,ae69a3d6) +,S(98f6f69d,320d5eca,1f184b0,378f67cd,b44a707a,c5b2af54,99e9f8a4,524dea7e,26ef6b3d,7b037663,979333fe,56bc33a,ca54a3dd,78c9244d,79ef5426,f2b69a02) +,S(cf1ef445,58b82c76,5d77ac99,8c0170c9,2d308668,2d9ed7af,2961cf05,5b47e390,8bcc1d05,fb880ec7,8762d8f3,f5afefe8,f4345bd8,36397d23,befdf446,498511c3) +,S(10e01651,efa26f2e,f88cc5c1,594f378,9ab62b82,5a0875aa,37c280a1,8c6f07e8,2e6a15e1,1f776335,30fb2cdb,788aaa98,83105da3,7e28c0a,8fad503e,b9779df2) +,S(b94e2fe0,41ce209b,6efd77d7,44983130,af90945,120b9a58,5427966,e93eee4a,8f7abf1,103e92f5,5dcb1dde,746df10d,a86bfb8d,2776a0f0,1d07142d,c9bca443) +,S(cf9e7d02,c671a9ea,145d233e,244d8af6,6d71cc34,e17f2ccc,1225d2b3,16d41154,82eeb8a1,f0b966f,bbc3858a,3878f969,a853e2bb,e1b60c4e,e13eff85,d2d2ca7) +,S(da3a3c29,94ad3b91,319d18eb,dcf4b934,df8e4f2b,e052f436,6d539aff,4bd48bb2,28f9d653,c4042478,831ccfe7,bec86663,5e0d32ed,f6db4f54,25669a91,d1dc0193) +,S(ab812818,2b80378b,d914c9fc,d2831f30,a0a095c9,d0e52450,d4ba27b0,f1eec101,5abc582,274876d6,3dce366a,fbb1d80a,2286dc2a,dc0c078f,1424d45e,26666b3) +,S(ea5b82a2,bf02caa5,d5d64391,c0965c53,f0edd967,f8df94ab,831408f7,e5c4977a,81fe8299,f320837,acddd504,7b888e6,2518d53e,897dacac,5d28bce8,ff3d9339) +,S(50605c0b,ab201d7d,3dd618b,e3da2d29,318aeac1,7df58d2c,a95b8fbc,fbe70fa2,e50b1e,7b5693,c4ecc160,d928cd6e,d4c978fc,6c2a68af,c03f397d,72a60383) +,S(f76c50b6,6d7dcace,f45409d8,854f79b6,51356661,108b7168,31b58b25,ea1191dd,7d055b74,b0195140,bc0e2e93,a97f07b3,a3040148,7720df86,d3bd1810,6df3cc72) +,S(de5053ba,d716047c,cc2367db,272e4e11,41312690,2bd79b32,f6d3d959,93260e7d,1c54a2d3,9c34b0db,deb61b5,b5f46033,b1e4c581,5113bf3,d3f38de1,c97cc7e2) +,S(ad3e719f,180e946b,1b98a332,bde18e54,437f1a24,949d712,1aff7c8d,fa06499d,b458d7f1,390fa4d7,d2473863,abedc063,ef310adf,7ca2f2c8,82bcad3e,2f1b554) +,S(270a0234,5560af6b,6310c867,332f8b79,839a3ae7,6e2666ec,b46c840c,c36bae4b,8daab84b,92157d16,ca0f160,99877a1,ef7ef072,1bdb5bc6,89d16a19,4ebedeaf) +,S(eb5ed17e,3027c9c4,c87ffdb2,94a84ff7,25ba2b5b,2bf72d30,f98334ee,68624621,39fffcb3,8f74d471,9be8d1a2,14c61ad3,df4a91bf,d599c3ae,3b54b4ec,860a942) +,S(b9c11df2,8a0b98cc,623f4e80,75acd469,fb1f6621,a7572d6a,7bac135c,2ce0a5dd,5bfa8a78,d42b95ef,327eb0c3,692b3ba9,5eb506a2,4e2fca1e,391ec545,40a76278) +,S(eed17043,80abe259,fe661106,6eda0408,f60f1399,3c49a21c,a8a6310c,ebe74b5c,6dcb6276,cbe37b91,162a243f,57afcd9a,8cc2c661,652c324a,567d5db7,22a0d750) +,S(8e4b0f6f,5f5b9cf4,68e5524a,4adf62b6,8c68e310,5ee374c2,5265000c,53aa97a7,d1f880ae,c18d0191,b74578c1,6d0418f6,c7e59f2d,157c0d56,e25137ec,c1b7f74a) +,S(77ae21bd,fc6596b9,ae85ce9c,93112b1d,a7f393da,1238d76e,90cf59c8,caa5ebbe,f4484581,1e3266cd,f4625390,e729154f,51694717,3206ef9b,9106c547,ff4a21d1) +,S(1d379ca8,71c02ef4,59a8bd35,f5066265,92922533,f0503999,e16d6b07,dbd2346f,c0550b9a,72899a7b,42197cfe,d195c704,a6333d5e,178d91c1,d50b772,4140cad0) +,S(625017f3,28fc16ae,99367199,5f02772a,5c7ea721,7d47c296,cbad670c,3fef1ccc,1b44e253,af3b214f,edbeb4ac,50110df6,d7056d06,617c2bf3,6189a74d,64450603) +,S(c7a4fe49,6bdc3509,3ae3f508,d43877e8,d1019d16,740a5eb7,8eaa72b8,638412d,1b5b12a8,95fb7130,e8792406,74b8f735,6730938b,675996fb,a30a9744,960febef) +,S(cff9f83c,e8f9c4ef,3e80102c,bc48c409,b65c6166,b74f052f,a5628348,b2441d3f,4cc418f8,2180207e,fc846a41,ed6973f2,814ceb07,a8bd252e,338e32cd,e352ee6f) +,S(84027710,45b8c295,c938ae98,a9ea11dc,2fd23ae5,7ade6ef8,2c604721,66700541,72946592,d3c11404,881b972c,eba81d4f,f3f80dcd,40b15da5,f56e0723,841e4f99) +,S(f7ab1330,e00cb9ec,61a346b,d8f5522d,5e304a4e,a94f84af,b5c70614,d2e0d2c,5d4ac851,89350a54,af58def4,6f3f3d69,2ef0f6a3,9dd4ef86,6bb1101b,df5e6144) +,S(a7c84e19,2303b778,8c1a4d5b,786c9829,d0da4ddc,c13f692c,7851884c,6fd4e618,56e32e5b,8fc2db2f,21d64bad,35e3f115,65928533,a829d744,939ba456,bb1774fe) +,S(b8b0c884,a680dac0,363bc55a,fa677a72,c65f4139,7f5cdcc,f199d80d,ac98c43a,43e4188a,c92606c1,cd6bec5b,a4edb045,6569f87a,625db932,d0f8e71e,516b8127) +,S(816ec443,d0576135,5a3bc33c,1db4a179,c5bef98e,943af8dd,ac250482,a65e0df6,89a7b2c9,e9f3588d,990f6fa1,96e366b6,54f9a30,1218a2a9,c9b87c48,55f0b360) +,S(8ded2103,823d07d5,33fba24f,7fccc47c,b101960f,3b717fd2,af39d49a,a91e28a0,3f03ed1f,be1a661e,f43ef9f7,d753eaad,e3e1a391,2a682ad4,fb19526c,c0011728) +,S(b1c4b39c,e874d478,bfbdf9e3,ce8c3165,ff4f7c4,bee20c87,4849aeaa,d0d6260b,38af8b61,30701881,fbbfe724,5396adc9,32c25b84,dfbc4dbd,a54bd236,c04b4fde) +,S(7d5bce3b,e5953eb3,a17f657c,fabc8209,f011bcf2,7e10b90d,e75dad9,fab2c971,7380d686,5f5fd782,b0708b3b,62c39e49,864b2ba7,4066167c,bbcede2a,b0f84787) +,S(2af5111a,422af2cd,14e7717f,bc7171c4,96af178,8b229497,a54d2b87,4c00f285,4468bf1b,ee43f100,7e800b68,b7b3b243,2f3445c5,c8aca59f,7534beae,bb771f41) +,S(b46e29c0,6dc8ddef,f8bdfb65,f4043b61,fe010dae,a2d0955d,c81a7b49,637af766,62777495,ae16314f,d7d0cef8,24a27a9f,748c5c9b,9c51645,9c1ec9dd,9d7b59f5) +,S(105786d3,f44ea40f,71eb3bd5,339cd514,aef6d8fa,5923b4a5,89b219c,fba6b1ea,2a4ea7da,c87522cb,7d92c450,8e86d0b9,39fad024,9fc2cf15,1ba005cd,b743d0bc) +,S(1f3c0c81,be856e30,18934573,892ceb22,d2d2d8ef,f08b7857,5c624f48,16adb23f,7321690,de24499c,f52f4840,89c4d7b4,11158d52,d32731c9,faaea567,8bf6072b) +,S(16dcbae3,a95a95fa,912484f,f833ba0e,e437876b,f16f9c9f,5abf46aa,468bd2b3,56727c07,247b12d6,c1ade473,3c691700,30e5582a,cde14034,3449f241,59ffa44d) +,S(114be56c,d6723c8f,924ff3c0,f5edabc6,e42314a6,49edbfff,1c794438,dae70726,984dd72,855cdeae,7c580046,b32cfa7a,45b61b75,944735e1,d5fd9065,268ac521) +,S(8d0cb2e6,1f98472,e169dbac,7f5babff,51766b3a,8d74e17d,747b7eac,d903fdaf,d1593bf5,b9e793f7,25cea368,2ceabb11,f06b36ab,899e160a,f1f736a,80bc9b92) +,S(5b420754,188c82e4,db72f3a2,c8049691,34e3b43e,484b45ca,ab4727f5,31714db3,4a89307d,27d7f360,7acd1643,719be148,1c7eed5c,77598883,8bf6cc13,a4723d9f) +,S(91e3761d,95761d96,8d856a72,800fe0b5,9f01c62e,1cc446ed,18c1b58f,88cbf74b,b5ab61e3,96f88376,28f3389e,9999ef55,b73a58c0,d33debc7,25812530,2b96c772) +,S(31380b83,dc77e5f2,9c2f5548,abe052a,16e0f1f,2d8aad3,5b05d29c,5c1a4655,23ccafae,cc84ea72,3c434342,b839cd0a,b42173bc,1aa1db20,1073fe26,6593403d) +,S(ae40198c,bcd54264,904b44c7,c9019553,8f3f3727,a0c9639a,764cda80,b21edd27,3a57f08,ffecccfc,cd9a0e7c,827d98a2,ffceea9a,6c39d200,5cfae623,34eeba8f) +,S(f4729787,abeac0f1,249b1d3a,c19bb025,5764a854,727b415f,73e24c88,a8a981c8,e31161a5,68d81328,c7f9783f,de146d07,b51aae15,bfe719d,ab4e9e,ae65d172) +,S(f92f02b8,34148934,f7059b61,7e84d0a6,f52d3b8c,a7d7b69,ce4c8175,7ed5884a,faed7ef8,82733020,888eb530,5c6dea4b,cacd208f,fbb66b7,6f3cf41,a8864080) +,S(a2bed8aa,e93bd682,be8cc4d,d1f84fc2,9efe4022,b2b0dec4,9ed3ce17,7cc93363,287ab9c9,62126fb7,e0340f29,9edeb89e,7bf235b3,b3f08213,d630c9df,198ada1d) +,S(5a42cfcd,3d1811d1,99b09dc8,9308134,cf6219e2,e029598e,899418f9,b7af4724,95ce721c,39929d76,b0ea83b1,80bf25c2,e301413d,60fb8717,2e0ee8f0,593f8423) +,S(1d27ab05,67e8bf19,323f1eca,44175085,2e768a6b,a1436789,40ba2b94,5b0e530f,18439939,496d29a1,58a532be,76b04932,a23e3ddd,d51a1b07,c6c33e6a,11e1afa8) +,S(592bf859,22c05bf4,4b42fcf6,e4cdf3fd,bbbf8088,b7263d31,9bc74914,6eab4326,84cbd8c3,8dccf0ef,de3946f3,ba2eac25,3aaab976,8f7f601e,7d95bc74,4c7f65) +,S(66730a70,5ae3dab8,bfc01f4a,deeadc41,d4df156,d03c4fcf,1dd9e16f,9359d5,c04c7cc4,4ea1d8b2,273b9170,19b9efb3,6e8f422c,4863f718,582f57a0,778273ee) +,S(3d002600,532420ac,9fb246d,84e48560,1ce6897b,979491ae,7c5914e,dbb7fe83,5bd73264,2f16d4e7,7bcc4855,72494523,c221fa1d,321c552a,53241dd7,94c7d98e) +,S(d42ae36,2b5dd22f,d2089d37,d22e2c2a,750395ad,710aa1c0,61ed4275,43a24487,84439e00,1571e1ea,53bcc24b,a11b6f7c,ded0a649,b2a12fc9,c2a618fe,cb39ada7) +,S(37c761ca,486fabfd,b306d,c18e9074,409e101e,5bdd1670,edef1253,aa253743,e53840e3,1110db1,89ec241a,e7b2cb89,29669da9,5c07f3d0,6277f667,b90cad12) +,S(4e672ef8,bbafbc8e,eb819f37,15ac0d6c,2afa9781,a197345b,2889ed0a,f3b0e788,9c10f0db,bb16d807,4680133f,e62e0eab,130cb0b9,51937852,4afcf4c,38814061) +,S(c1f2943b,23c07929,e9c635ae,66f62949,8e1df12,f35aba68,ed8791d6,8fd51fec,3376b6c8,93ad5ec5,991f7ef9,6a6b1105,2f2262c6,680045fd,fc4d4bfe,ea64ae75) +,S(3df2461e,739cd984,72cf10cd,f663e651,351e826d,7afdcffc,e17602ae,c0370be6,5e48fcb3,3ed9c0ec,3594eeb0,81adaaa,bd5ec5a5,7eeaf01f,c9f00d02,c692cb06) +,S(d4d3d528,f98b92d5,f4c4ecfb,ab60fd85,50f12327,5b63b3fd,5518c1f3,d62a82b7,64496d50,85435de6,991a838e,d984bc09,2554053b,54b05a2e,490d2ce,da7d5b76) +,S(ecd8399b,4aa3368f,1a7a4113,63ff03a7,ad644847,e225108,b3ee7d02,1209236b,2e1209fb,a7921c29,e351e61,73c02cb5,c629d88f,4ca51af,30f37123,75355213) +,S(d5990be5,7e6a0da9,333354a,fb344d59,416d1a70,785cdae3,8c332e09,cdf78722,b2a2cd8b,73f76f3d,1079198d,34441008,278f73c8,93979ece,eefc5911,7ba17814) +,S(7598ab65,1d8ced00,af3d5978,661d801e,b57e9089,287bd74f,85ef042a,90374b1b,589fc426,9466b1ff,b9c0cbd4,b022e9ee,7edaae87,8f4cc240,b60db60d,6c28f04f) +,S(fd071417,b12d2d31,852048b7,61c5301b,be088cfd,98ebce7d,7e0922cf,41f694e7,2d9c53f1,ee63b93,2adf679d,96b548d8,d47d8f74,58ef8b45,9664da23,be32c363) +,S(5a5b4990,e290868a,d1d571ac,8e9347f2,b1e513bf,cbc2b8d1,5e56ce01,2b72ca0e,c76852f5,7159524,541569f6,3c4c9c7d,424285e7,e83145d5,e5161998,efebf968) +,S(93deec24,3cd4f146,42f5a415,f6ea6f36,25c90081,5f3d20f5,9728c056,fde7f2bd,88f919be,b9993a16,61f78145,f54149f4,6abfa859,1907736d,d5e85f25,bf2dc7cb) +,S(9224d17b,a65ad967,969104c9,3068d439,9c9bec7e,7613a602,f5c9917e,46df82b6,346c98e3,2bc2a4e8,c7689e54,eeb1064c,1b5691fb,cf5a4710,55cefbcf,18a32f65) +,S(851acc91,24ddff9c,14cf054b,87347a71,cfc91637,6e559189,f055143,3b79c38e,d959bdf0,58d21cc3,430527e8,cc49dc56,2dd20bf1,30f0e13a,55cc69cc,1e116f35) +,S(ff6c1303,b7c111c5,87e01ef,44829510,eff0a612,931f9212,2b71075f,2cea4d96,24f09bbf,7bcf50aa,ca239be,b925505e,7e99d0ff,5a959574,5370eea1,7b4841f6) +,S(f23bd9f0,55e7bd1d,433fb51e,c8b6ecb6,fd5014f,4f4ca9d0,6a4bc636,435fdac0,9652b458,9d269ad9,68ee7012,aee47447,25ba917d,f120bda6,9d2194ee,a56d7b60) +,S(9d622c56,ea6d5d19,7b823e60,1bbd4af0,1fe070f9,391bb564,2a05527a,49f46ff7,8061bb94,d6485fe,d9fbd557,66db3dca,c648c7c4,2e025494,e6c3a91c,fd5c609e) +,S(9494efe4,cff5d5e7,6394b67c,407b9961,2915afde,56933b80,370d0adf,2f020c13,ab0c7e38,c85ee1cc,27964b2,de42372f,fd86ecb8,fd3f0a81,84f5af38,58a7e4ea) +,S(a8e4d7ba,ffbc52fc,a8cb6c,2938a01c,e028c259,97403268,dbe1600a,952e1a86,8d5b83d,dc3022c,4f79723,c6f16722,cc7eeeb9,c964496f,c9f67c29,351a0bed) +,S(83841f64,938e460f,eff191ad,4d72d7a5,203c01af,1519cdf1,f17c3bb5,e4927ac5,f5868f2,c2e87249,21373397,40415c4a,ecb1f30d,b204fe41,80e01d79,eb536800) +,S(ee8974d9,5ef03f8a,860dcba6,7b597fb2,af2a2df6,950aeacb,d623c883,20612f6,5cf10d74,3085dd7,cc695145,3f9f763d,6596abfa,eb7cf216,34ee07f8,a4f141ac) +,S(68e88d8c,23616ca3,b136e5fa,3427628d,a92dde6b,2691d857,b2d01a60,b6579606,5a9090,3766d6eb,c58c5d60,9b6a5675,e5ec7b73,86a17c41,2574d179,a0fd5450) +,S(fe34dd8a,c62ec8b6,20dbea79,44ccca40,cfe6ab5a,ce3b2e7c,50ac589a,9522345b,88cf0055,adf1e122,535611d7,bd3e00a7,30c9edd5,898d25bf,f0abb9bf,6bd6c8c0) +,S(423a7a9c,c0f81489,aaa62479,c1317368,9989366,fd18bff7,f6a5f235,8251bc1f,c926b3dd,519241d,2e776ea,16112e41,259ce896,472ce71f,de4261bd,29c678ee) +,S(7fa60bf9,7cbf54ff,e61bb840,b2e08d91,ffb0eb4,727c0e73,ed4f157,ad0b98f4,d5b1aadf,84d387b8,fddc7b26,a7f736a6,7e296fed,7978e81f,6e7b3b09,e94d733) +,S(9e53cb0e,f1eddebc,77edf8a6,6917f915,8294815d,eef898c,f1e77433,60153a66,5358daf2,60fea2a1,b9a4c6f1,b8bebe09,4983499c,fe5577a2,ed8f817f,46b41ccf) +,S(adf93641,c616c677,99b44ad5,354332c0,1404718e,8ec91e96,31e69552,3ad6f119,da3c66af,e4cfb3df,f55f6761,5c6ac42a,8dc17241,5ad38619,dfe2a13b,7e42ff9e) +,S(701e3ec,485db367,b0687ddb,2be15f4b,5b6242c4,396f6f0c,9726ecb6,474e4ca8,1098fa76,13dce1c5,29f7fea,30740377,691aa3cf,3d13cf94,6f2d8191,2d3b9e83) +,S(d8fc5ba5,d3ecaa05,9e9a7e04,2c52500a,d513645e,6149e84,aac0d910,f8ccfefc,72724b4d,eec94da,7494b4d9,83a2df06,df96ee83,e578d920,c2597089,7b4b3d8a) +,S(7bc88f9a,8279ffb7,658a186,faaa5f0c,c900cb9d,4a33b8dc,c9eea83e,ff71398e,cdcd21df,e5ed8151,1a2d8c77,e08b76f7,4939d39f,1f5581b0,aa956066,fa14a7c) +,S(8578d531,bc79e1f,6e219bc7,7f2172a3,e5fb92a5,efbf9919,f46ea11,6f5ef0e5,fcd1b2ac,39c262c6,94eef5e0,52338f9c,cac2d04d,ed17c290,768759cd,13b7d550) +,S(98bc22d7,3ea2661b,545eb5f4,37e1cc0a,d4124020,44bb9093,5cdde758,a8020a62,143c7dde,d33ba5b,c2ac8d83,cc462f94,2607bff2,a1aa32d9,f32e14c2,82232226) +,S(7fcf821e,95d2176d,d088106c,a5bf0855,9980f265,ea3c401a,aca44b0a,d5e8ee10,27c341ae,87e7afee,f8af4598,e8e27cab,c127b054,1b389cfb,266ec9d2,fe400284) +,S(898a39b9,d440ef05,f87e195b,6a334f93,67acd67a,1fc76ca8,316292ea,216a5f1,eb642fbb,fe3274e5,2fd1cae9,744fabfa,c0db80e6,2bd4f7c3,fc2ca43b,18ce52ef) +,S(3ee974a2,8918c216,a962480,1f18bf9a,87d6a627,83323e3c,bf138bf4,3f2192a4,f5b386df,ac71eb35,499d5b2a,960fd20e,fde39fc,10dd5c63,dc50b55b,cd660d9c) +,S(bdd10d2f,de76df34,9ab753ee,d06c1251,9766bbf4,2fb610a5,7ddc3f36,4047c14a,504532ed,34f97eb9,b8b27664,ab440032,2b8b47f6,9c403bbd,6bc74330,16923dec) +,S(2c179437,39784124,4ff9a4a0,eb9ff292,477a5148,c4176b23,c000a1ce,3bedd63d,a367b584,4f9b7b2b,a82fccca,b9a12a8c,2c1ca5f7,3e630173,e37e600f,f2fcfb6) +,S(282ef30e,f2d61d13,6f71e6df,6ee97ebd,a83036a3,2d3cd841,36289798,b3e71580,90b0cd33,c350ea2e,54c25264,7a3fc91f,5b4f9dc3,1f58e86f,c47825dc,e3d0f43a) +,S(a42b4d55,42acfa7c,b54ab3d5,ee0bebd,85bf6ea,db138ef7,1ea38c73,899eff23,17e38880,f10b9927,764c4997,326b0b9f,63d0e03a,fd2f0bd,b1ff3cca,1f566bb7) +,S(b23acc64,c5b00c8f,4b580d47,49589559,a06fcea5,75f3d38b,1a02251e,ff7ef00e,66bb180a,7eaa64d8,4bfe6a17,d457f5e7,73964ac,ff908729,3bc540aa,1cb6464f) +,S(942dce6,96aeb063,4681ce7a,407516e9,89df029c,ecc77023,411a628f,75885ea7,e208be8a,88be7b3f,6b6b06ce,a3aafb45,c439f0ba,d517a784,ba13f80b,707caf14) +,S(b8a6a2b9,52194ec0,8238e4db,e71eb948,23e64a94,e10ea0e1,610465ab,88392d16,f8029f31,b8e5ee3f,77a758ae,343be258,34c7bef4,c1b555c7,4cb63d51,cba5fec1) +,S(a36d3369,a1ee05f7,b1fdb083,ea614cb6,f15feac4,17a416d9,cc83fc2,868fc20,e4abd7f9,fe40f27d,5b7b7651,6a9fd714,aacd2ae0,5f0a1f10,e94327e3,76f0af52) +,S(4ea30108,3d711ae6,ffccc89b,9d6fd4d5,6f03bd68,f4508cc0,ebef5e43,88dda1d,81e9997a,8b1c5949,6554bcf,154166d3,40f9ea5f,ce55ec83,eed793d5,5ca3e513) +,S(20228716,1c1c89c7,64742e62,e427b712,fee118f,406a175e,ce2f424e,2affdc55,7837965e,cf26a7f3,428d2864,41e1d09a,91eaff0c,5ecd2c28,bc817766,67fa35b1) +,S(d3c072fc,8e4bf160,5790d429,61206123,95be9092,f166784c,f5adb7e8,6070d20c,72688262,594c75bb,bb55c0fa,af7991c8,f412e0eb,afd1c0c,f5bcab82,d8daf31a) +,S(294dac7c,e307fa7c,cf0e8f34,28a354d2,94003dbd,ca763dad,3e6df60e,530ec82,479fc222,a7bcaa62,aee807c4,ba6309e6,cfbcc783,afd49ecc,fb9b45f,cf84673d) +,S(3956ca5c,c09fe8d9,e4042a8d,67b276fe,225de609,ea24575c,7075d9ac,4e732fae,1c965fe7,a8219052,9d25ee0c,e1fd62f3,7196431d,7bd78302,e287a26a,2eeaa23e) +,S(24d2e396,da144b48,e736eb06,84940175,4f4109d6,6d87a9e6,97ee82bf,91fb3def,bb79e772,24b02fcf,dd1e3c9c,edbad212,ea875c75,1fe7c81e,76d7d0d9,a372236e) +,S(638d4042,f16e5c07,fcbf9619,dd9c2f91,18852889,3e12cd3a,b49e2b9b,99a2aa5e,d0d97842,4f0010a4,df9eb8b,8e5d8147,f618da43,74b8a4db,222e4ab2,b32b3d92) +,S(f91ad5b,a99972ba,bb323a1f,d3032e1d,94202d88,63680c5c,d7d67828,8f0d866c,60b66d45,a693175a,3a38bb4f,efb32dac,1cb558e1,b0d13571,e24a14d5,9452bdc0) +,S(3154137d,779c25f1,4ff1fb88,a6d0370b,9e6af48d,88e7fc39,c6417272,eaa69b7c,eb3bd91e,9c09178a,398e112a,9264484e,c1980c19,b1993b13,560d39fb,92295f7a) +,S(f8821e1f,dfdf9fc8,1e3acb3c,1d1d7a65,f710be2d,94a19355,721cb93,61549597,bb507868,c1e05282,51b635b9,dcf28e5a,c5770c05,c7afc2a3,f4b4c45b,7d8993ec) +,S(8409463a,521404a5,a2d8aa90,50e3ad8,ec5d6faf,870333b0,6dd4f63e,8354a655,cc99452b,85092ca5,39cc1b66,83b7ab37,1b8a6525,269a1ecf,91b857be,e1db3bd4) +,S(96802411,12d370b5,6da22eb5,35745d9e,314380e5,68229e09,f7241066,3bc471,ddac2d37,7f03c201,ffa0419d,6596d103,27d6c703,13bb492f,f495f946,285d8f38) +,S(9d1abaec,9f5715a1,5c762824,4170951e,f85e87f,68ca5393,d3f9fc3f,a23a69c8,f21ee700,50dbb61c,238c89e6,29423538,71b010e7,98867bdd,149ad28b,3f28cadf) +,S(1fb96691,8db3af46,c37234b6,a4b04371,9886d6a0,5859ba32,f72742d6,141f7ae6,8bc13ecc,207efd91,f7f4c442,6e9a425a,a17b5578,20404eca,b09d5582,d41f7379) +,S(22d9e364,b9274dab,98bcb23,e0428e8a,416d54f0,5a781281,ee221db6,9e1ec7b8,5dc23258,f93d7db5,e5799195,b74e9519,4c300a91,28f924c1,c1e4865e,2d8407d) +,S(625fa450,aed083fb,30166766,d5874131,adb168c0,247cbff8,3987297b,f873e45d,720a8104,473dc904,65585ed2,1a0244f0,fbb5a286,5b8e5117,5a21f644,8776bb7b) +,S(24acb1c1,9b6dfc25,defb01c2,e2681ae8,2deacc0f,f21ae8ff,1f82f37,a6a2147f,f729d335,210e8061,8a8abdcd,b71aabe1,93f50ada,dfaf7d52,783991dd,d3ca5d4b) +,S(d2856803,a99d30d4,f3a328e3,bbf7db3b,6c6d1896,ba5b339f,33c1302c,f75ab555,9649994d,64705b87,62c98bbf,1b41b725,2b814a89,3e780fdf,5689c9da,692d6ff) +,S(80529e65,9d196884,b15e95ef,871e5fd8,8fb5298f,3bc7831b,50a0bc98,4cb5fe0a,868b3e4f,9ae4bea8,efde50bf,c5a5b268,b74b4a8,74e86de6,e9ae476f,10b3b778) +,S(7f9199aa,3b8201ed,5d288e49,49c43277,e0bb316,953f1dde,d0674d7e,8728e183,1aba673,d0372029,546c174a,3a72268c,ee9d7e41,dd97de2f,fcbe1f9f,1a5288b9) +,S(7d32c885,8e959f6,48c4674c,dcccb191,29b4566d,644d2fb7,6d0c8966,2c29ecbc,d90e94ec,b50bfee8,c951afb8,e65c7386,875ea99e,31f553e8,66e00342,6d39698) +,S(f2b961c0,9291ecc8,576ce67e,bbd1bf01,1f1727ff,ad9eb74c,bf8819e3,2d1abfbf,ebfe5849,5a1e6a36,46c38220,8656f638,ed0aec0a,d40c0524,1707102,3126f795) +,S(d9a0c689,95283291,972d6a72,897181b2,6b4ae317,4e98a676,f75bbfbf,81be876e,d36ae886,a0acbc9a,d1564d97,4d3f0309,e9039b93,bb350d92,2b7f8c7a,c6bfa042) +,S(c7a36324,6aeb7c8c,991b2aa7,10abdf5c,fff29912,30b3a69f,be2dd481,7c7c3e0a,1298fdd7,e448d2d,79986302,6b4b2d49,2b32148,d6d1e5f8,15f5b0c0,5c9e21f) +#endif +#if WINDOW_G > 11 +,S(635cd7a0,5064d3bc,66535a0,4dbf563a,640d2464,c7fe0ac4,8304214f,e4985a86,e40265,913e77f6,46735cfc,af9e2f30,e8d5f047,f3281a4c,e0453e27,e9e3ae1f) +,S(5da624f,38edea25,37f5b632,695b481a,eca54bb7,2169cadc,c5b91e10,989ee5f5,d3ea6dba,a1080300,fffaeeb2,43a5256e,48c28822,37b16505,a220d771,ca721779) +,S(aa4f64a2,b19775ec,92c1f687,1fe4b6d5,ce05278c,2976c80e,fe19284f,e87d4d5e,f39f117e,95fce0fb,6976e949,9583a66c,224ea028,8396518e,293793dc,3ed4f240) +,S(9b6518ea,99ff1b42,22a93f26,62e05551,d60969ec,ebe378c1,477b5c36,427e0641,2e9f1655,8650fb3b,43aea9dd,30532ff9,bebdf7c5,1d421656,27b7487d,8f93165a) +,S(6c9b9aa2,b5972e0f,a1e01138,1ddcbeb8,6547f47f,fb101159,4b193d00,ae97b562,af09d91c,8d4c71d2,be523d0f,9d205bda,a6e78eb2,67476d3b,1624a038,6275e27d) +,S(a2a1c880,3cdc95c5,5e636541,c7112a0,cf80aec6,a37e5f71,f5366612,db467cbe,c4cf570f,3638f040,ffe5410d,50d4b175,802e2e1a,c422fc2,73eb9b2d,4e23fc09) +,S(63d3750,c961ccd6,34a5af10,48897366,13102bae,20f2c8a9,ca8437e5,ab650427,87415332,74b39a76,72de90dc,698742a1,f21125f0,71393fa0,6d670045,8e339248) +,S(8d070e66,e4428255,a53e8fb,5845d14c,bcc97dbf,19b6930e,1f5160b2,52bdd04a,4bc98c82,4f2b4f04,c9884099,f173cd22,48cdef90,ceef4bb2,497da8dd,99487ecd) +,S(f1fe56a7,2e5f008b,b5014395,cc1658f,e3f3d4df,7b361456,175bfd2b,4a91c8bd,be5ffebe,e57a7da5,d01e302a,d3688567,a19caa5f,fe8a57b2,be2c866e,f5f275f2) +,S(802c9adb,d2eb969e,9ba71a95,675bcc7,b412399d,5aecd635,7476a1fe,73554b21,42132026,f547ce69,66e6527d,370f9c0e,cc3344c9,be1047ef,b7422e13,6772bc5e) +,S(95b1b6c0,9d6ced22,f0a5cd,abc7a594,9d24cda4,f178a745,c718204b,1493db56,bc143681,53033d16,ac8ce5e9,a6cf240d,27b2331d,36cb23dd,f69009d4,b6adb01d) +,S(eaed529,1f94eae,183b2aa4,e17022f1,7b79a06e,d76b169d,2d6483a6,a6ede35d,53d5b276,91c5899c,ddac1efa,3ad6baf0,bc6e377c,99ac7f8f,9cb27fb9,5dd559b3) +,S(77c44fe5,9f6f448c,72eb485b,6ef3f7f3,906d690e,367beabe,ac7b7359,9c27d770,bcd75022,6c440f80,2ccf0360,4e3d6b38,e6629c9f,facc49d3,83322eeb,fb1102fd) +,S(e863b2e2,f00f0a46,b6752002,cd936a88,11b6279,5411944e,fadae5fb,e40a0306,b5c79ba3,6da29f17,5b9caff,631e8ead,c2ed937d,66008358,b36fe044,67243a5f) +,S(226f5bef,93df71d0,b2feedda,4ada3098,3883adb4,f3dcedec,2721e72e,eef8f191,a09204b5,2bcebc14,8a0a08fb,e8458618,f966078b,d75ccfbc,c13233ce,741707c3) +,S(aa222fb0,8c1e7c53,9f3a82b3,9c6f08de,c33beda4,aff7c46e,3a4e9036,83467184,41105cf,21cafd39,821a7c3a,a6dff931,c1653d29,906b5d4a,c5dd6431,7c1c3765) +,S(1879c2cd,26ef4ed3,dc5220bb,397b1501,f94482cc,1236da82,239754f1,e1fec96a,912d5f35,75eade14,91fb1609,21d63042,4fc68951,cb73d351,464725b7,71f0d67d) +,S(be39e4a4,e7eed88b,f4a4cfc5,970d4b7e,6df6211e,bdc2bb76,7657ecb1,ac9902e0,d8b1e4f1,13fca7b7,6306d9a2,b4cf5a49,32ae54a4,5615c899,f94cc476,7e27cb4e) +,S(1ea72fce,33378c3d,d0302836,86c3f8a8,1c2912e4,7cf44631,d3fbdc2f,752d5786,e20f4558,fe1cdd14,ccff261a,fe506b78,cb6e2b0,807fc7c9,aed0b888,3748906e) +,S(56e33dd,67bff57d,e8c638e6,f32bc396,2d0ca011,b74db242,3ac662fa,da036806,4039c0cc,165e7130,9317d4e,41de57bf,50d78ecf,3e14ee2e,fbb3b93f,c393f461) +,S(51981691,a5f1d8df,1cafb95a,738b9e3e,d036ce54,f10a7447,c470cc2,e80f37ad,9fb9047,67cf2a99,766e3c2,6e97f045,d03fabdc,471ef664,d31aa662,c5972261) +,S(ef3a5685,77a59783,6b0be7f9,5f927996,b90db9b9,bcd57f30,16ec5979,98869dbd,51cfe457,ff22749e,949782c6,ae1f4783,fabe1136,4bb524d3,72ac3d8c,1b7c5e07) +,S(efc652a1,8c3a85ba,7ee9e0b1,6e3c6433,79a66882,5304a22,523c060d,af196415,8a656c14,cef91af3,1db2498,f5987083,8fcee71c,98c09d49,737447b3,54f7b2a5) +,S(cdda1fef,f4d5ce2c,d9802198,389880f1,8adc7962,c04a95de,f07370a1,884bbf82,8bc26ffc,b0c9dc05,d799174b,4a478162,4417f9ab,8536235a,e55c9b0,49e31d6c) +,S(6f3f3985,3454aa13,134b76d7,77dedd40,d46bb6ac,dc3a3a3f,93886847,b96cf0d4,a8ba499c,4f7ca1b5,ae7e5192,ea408344,b6e32491,e5649637,e4eec5c9,2cadba81) +,S(e52d11af,91abfb83,ea842065,ed8d804f,a2a3627d,85149ee8,61cd5df,e54b13e4,59f3106d,619e5672,cb21f6ed,4e73285d,2e132a3d,e3ed069,46838e12,a9cfff97) +,S(89fec736,f0de1cb6,45654d13,b32b3cab,8fb91869,c30e2ac0,66c0cfa3,9e7256ff,f9417ae8,4d3e1a6d,b6ab938d,9dfde62d,73e708db,b58f5ded,46b455ae,7e44274) +,S(5140f56,91b10553,ce86ce73,3028749f,52261520,a8903f75,31bdac09,22b70b29,91a1962b,9e02c23d,61f4ce,21c0ce90,ad0acf0b,fa250afd,dd67d72,aa2dc024) +,S(3c16130,93109917,1075e199,ed32f94b,579d0eb,85520d09,c0f90fc8,7d267b5c,d50d04df,e4040db9,3aa0010,7693ac01,e9f156ca,5e800e51,a5f7d36b,78ac64c3) +,S(fd87690e,63a50237,258b8a58,f0240552,a2d0b952,911d1fa8,be13eeb8,9be8bac9,406dc1ac,ccb968f5,6fa3ee35,247fc66b,b40f04e3,ac512474,58e4fea4,8a1b9225) +,S(8e4d1de,17e78f3,2ce8ad59,973b328e,99005ce0,6a8d9347,ebc7434b,d5a12a81,c6348f3e,744ca65d,744c843b,4bbf0d8a,992bafa8,8c31b6da,42919401,b1a2a8ae) +,S(382c7bcf,ea62c678,173b6eeb,ba58caaa,f4988104,1677bff6,ea739a0c,6c7743c2,190a5da,77e64243,53df7f27,e01c0f6a,67e9addc,afcd3523,7cf5539a,69c5eb7d) +,S(f56a8b4e,74b84807,539fa471,bea50795,25b0dac9,53bf5d29,e87d90d5,f914ed0f,5456d908,da57e612,3ab881c6,56a6ea24,8f9f201c,13915a48,c50151fb,c096db8b) +,S(908e9ffb,6a5e557a,1fef8ea2,b16b80c4,3af3652c,55f12a04,4ecfdb06,17965b80,beae28c9,d1b14cf0,f8182ca0,7ebc3137,b9c01094,ed6b6043,562de75a,878bc2ce) +,S(a6c30718,433381fd,16b22533,52934eb,3fad254b,99d41e78,7ef2e6e9,bec86ef4,47a9a286,a60d5102,4d129e4,e0309c72,9e266f82,5ee26f4,4bf90057,623fb818) +,S(948bad86,6c3e2c26,2d46163,52be20ae,30a652e3,4a299361,4766eb7,98b3e903,30d30622,ad478a2b,99c43b0f,915de0c,4321da4a,76a18d33,95b4c484,d9c35164) +,S(d6c92b9d,cb8a17ae,77788125,18782d36,9d536edc,f96d2c9f,c9e84d2,1cf6a3f2,dd9367a0,93518377,97b0ae88,1aec5d4b,ed68624,8ec2207b,9e0104af,2ade09b9) +,S(f9ff3d7b,7d8b13d6,46c641ca,64df802f,7b082209,a75ae328,54cef0fd,65566abd,ac58619e,1f192095,f7223022,43d811d1,b9269d28,a18711c8,c84e5960,32deec98) +,S(3dae1dba,3a70e0f7,209a920,42837ed5,7f4e767f,834d14e1,c3528f6e,92c8d5e0,7ae2468d,6ea1f2cf,e1fcdfad,3ffe87c9,5c7816d9,ea99332e,8b4d055,280f797f) +,S(27045105,6fcc937c,9cbffe13,f2aaeb0,8ffd227e,dbbc7ca,d0b4b01d,19b49937,11766a54,6c24fdfe,220d3724,661d6c75,bbd801f5,c4286ad4,d08a698f,1ffa4397) +,S(f9d95ff9,6c3260ee,cd434075,262fba81,2024c556,649c4865,bb90d65e,20defd22,37cbf7fd,8f741411,80a632ba,8304730b,a89d54a,1a5b1dda,24b026bc,17a13c2d) +,S(4e8df18,f90f67e9,fed8c6d5,b66cfbe6,ff0a86bb,db990214,48ab57c5,c5a7021f,7e69f8c5,ccf56413,453a2b1b,3b34843c,e9badfd,3a83729e,a2293fda,f2a621f5) +,S(8c2a4d2a,710a7fb2,1ba78383,63c66458,ab3d32bd,3be35821,c8a5b779,d2ffef9f,d532447d,27e42583,46171515,71bd6577,f82d8f91,ff39d205,caa5aac6,365511d6) +,S(28b7f3a0,19749cce,6fc677af,a8fae72e,c10e811e,d4b04e19,63143cef,87654b75,30471eb,3245ab39,1597c881,e71f4a1d,e241ba31,a678fe39,2ced5a63,845ec782) +,S(cb474d0f,fcb8e72c,257b5acb,999ec8e,d89f6494,cf4b008,8f6d7db,59be416b,ff7cd0ce,fc293cbb,8ab9a950,8759f856,9a0e59b3,effc00c7,e3a3051a,a16622fd) +,S(c33e6982,5dbebc40,265567fb,ede2a4a5,1a180034,2e9963f5,bd57b35f,4055b36c,22ff3ff5,7ce265ce,253b5061,599ab066,82c0cb5,91a51e0d,b798ec2c,c546be18) +,S(84bfc106,44d37123,71a441a8,4444a9ab,257e0745,b3d0ca0e,ee341838,19bd2237,7cbe56d5,7b7af706,c33d13ff,b3e4197b,afd7f421,1ece235a,e1c2187b,289ef6f1) +,S(9c312ec,d53b244e,fd40f003,f7e0835f,6063028a,5b0488dc,73599653,f97b713a,11bcbd0f,58fc77ef,854d0b16,188b4e8,59698ba5,fee41fe6,165449b1,4eb76d14) +,S(5c06af59,a22d6f2d,cd83bf4,e3bbcf21,d474f61a,e01d0433,2d0a82dc,af15cefc,476b4be9,f1c265fd,a8c6d70d,6c669aaf,41fbefb1,425e2be2,9048165a,4322aae8) +,S(777259c6,81a3ed43,b4c0eb54,7af39ebb,f44f0d71,c84602bf,2d6d45b3,f1b6bdcf,8a9d3753,5481858a,eec44851,4c834667,d6742b9c,f563ebba,22fde187,fb3bf754) +,S(b370601e,ae1fc1d3,14e4328b,4d0244de,174b8c4,766283c,e3820c50,41266842,8ef05079,2174c3b0,752a9abc,8d980ee3,eda7b5aa,4042a932,3e136834,bc125ac0) +,S(5af94ac0,7f8d6492,a472ad40,67097206,78086856,b01528bf,8248ac8e,dafe6584,8a54c7ce,57eade51,1d5f32ef,cef5f56c,b40dffd7,8cfe5655,2a9c3966,e62daf1a) +,S(8fe3c19c,e2e87055,385d4f23,c5832f37,4f84b41f,3f945945,81acb8e7,5b0586c6,f923099f,d16f44c3,a4314d49,1af193c9,2f5e2017,156f860,674f5ac,91728c28) +,S(d580961d,2642bd1e,5f9211b3,9b65eb5,e531d17f,a37bafc3,b5f288fc,13ac9a71,500c0554,337e8b43,36e50a6e,b12fa86,d9678cdc,5b38f650,e4f897e9,1b4185cb) +,S(255dced,529fa623,49e46033,86790c32,234e7967,5a9c5405,256cfbf1,4295e82b,7eeda9c4,7f3e1c7b,fc3253d3,faa46317,5dfba7cd,94f6cb10,c8f4b4a,7d799815) +,S(4b7ebfa7,9240451f,ab8476a4,ae48e55f,1a27c338,a8dd8458,bdbe422,ec891557,dfb260e9,f89135f6,fca23cf,ad7ed812,c12622d7,e4285284,8c63d83e,85b59085) +,S(919d0780,9e6092a9,a3b5819e,c67719d,3119569d,3bd14c7d,8f47f555,1f2fbf28,ca0b6af8,76d70f2c,ecbb2fa5,98d6118,c204d3d4,a30e24fd,cbcaf283,843d8094) +,S(466867a9,de89a944,5bed73bd,5ae342a4,9b8c896b,59eebf42,393dd536,8c70ee78,2a5d9707,b3e15823,79bd6ca,e8b7ed09,9cbb9f93,4ee96029,385d5678,aae042e1) +,S(71274d08,c8784517,8921526f,cf71258d,fc740d5b,be655f3c,d985cba2,c1db3f7b,e0af0130,a5be1434,f8d652bc,4406177b,3cdd2ca6,6abe7f56,d848def,fb4b25e0) +,S(a46e9048,2d25241d,13c693c1,f4e6068f,b6e8256d,1fb3111f,a0ae0e37,7ebe2bcd,7567700c,f22aab69,8126e7ac,961726ad,fdd708bf,d5ae5111,40f921be,94474eda) +,S(f7590b91,f2431126,85873b0f,77be6851,10ea918b,a26d3b5b,aec02bfa,a5e84abd,481848f8,594c94d0,c9b5d6cc,858dcbc8,2d25128d,5ea28e2e,ded935a4,62708999) +,S(2d7aa8e5,1282e1da,dad39d64,398f0790,4f966edf,aff5e3bc,9a22edde,428c2edf,12b2133c,42032099,eb33ea24,f1755f9d,a30b4da1,708cdfb5,7635b61a,335d9d79) +,S(91313f40,3302c47f,d9f113a5,581f135c,82280927,5f658607,99550fa9,7236d0e3,f8b6ec07,5e7804bf,461daee9,1f21285b,aa9e96c2,2e0cff27,c323f627,90838a77) +,S(da248119,9d385a7,8468e86e,1b146fbd,e0be031c,3a19d0de,2f44a1d5,6c6743cb,c07c897b,5f76f6ee,f2c62511,19b37c47,5d418b6,1d2cda66,6d39ef67,40348cbf) +,S(95e36a24,b1bc2e3,fb5e6082,de9ed432,760ec3f9,6f01dbd6,2e820268,dde82220,be6990d7,3abc4a3a,8f03b209,dcb4202b,52a74a87,1e1e3d01,7665e9d1,1ce1cb63) +,S(8b05b060,3abd75b0,c57489e4,51f811e1,afe54a87,15045cdf,4888333f,3ebc6e8b,1d10f881,45db40fb,889e2ddc,e81bda7c,27f5b615,acd6179d,bb30f4fe,7f40fb39) +,S(ffabca3b,764a327a,750bbb2b,a1cb8329,d43ec0b7,dcd8f728,55a9d30c,f3020f54,93970a65,c90ba260,5b2fb393,a4e994b4,c791965c,b60a1302,cf585443,6dd0f05a) +,S(b3a85aef,ef35e4a9,8f0f05fa,9752998a,d3514868,b133e7c0,a18fb053,b866c72,30115ee1,c21e5b9e,3d6b36c,54e700e8,9ee78c7,e88a2752,38f46d1f,5b6005e2) +,S(a4f1fd5f,4c233cf2,b9c5659,f666d51,5b78fc32,ebcb52d5,d155250c,c95b7ab5,91d19f85,726a1258,444419fe,c5219c7,33754325,89d92d52,c363d61c,81faa0da) +,S(97b84b4b,7baecf13,94bf3923,2b58b5ed,9eb14637,d29b3c98,bec3e624,15bbb0a,497db4af,be8e7b3a,13493d73,ca92b4b6,5eac7f30,d86dbbf4,8b86f495,2d162435) +,S(2ceba0d9,203e3666,75e78e96,51b5b57b,a9de5f82,3cc8569a,1c274d19,946312b3,d4c2fe86,f042cfde,41f0a88a,6d77c188,b7805db6,c6ab440a,488a75c3,8ed2b437) +,S(ab8b1930,6cddaca2,8be57b78,b4836998,912391cb,c6a41e10,e91b86a2,3f2b7009,fdbbabdc,79fba1ae,9d8472a1,7a648206,7abed651,36892a03,35128650,374172cf) +,S(2763029,1ff140b1,57eac2b5,9938f26b,c149705d,aa2dacd,6bb0d305,1a15b394,c2b6b32a,38dcb9e2,f4640838,c52f5ca0,55359479,86ecd875,a91504ac,49374ee6) +,S(22d1edbd,1cc1514c,7f91d793,3e9dd124,9e703fd0,8c65ed8e,6cc79eb5,cafc78c5,7453e7ee,a53ae741,13024fca,208a3816,a93942c1,2378ff7a,5e65678,c0a85efe) +,S(70d869c0,c5729e94,270fa559,bdb3fb8,b6146527,5ecedb7c,c8e7c9bd,acffe222,4bfcad32,8ce78fb4,617baec8,48c2c3a8,f8d41474,9c131657,115dcbb8,f6ec30c5) +,S(a25b45de,da8d5782,64f60dcc,da97bd28,ed9039c0,6bb7c97d,d4a24eb8,791b1647,8fd84983,fd2ad956,32376555,4c43a664,f306f11e,2f030c7d,fe1c68d8,aa43db8f) +,S(823fcd6c,9b237c0d,5aa38336,6737066f,3e77fa14,b975a5cf,39ca8a74,3b1024b8,e691a44d,29a4f2dd,e99c2ba3,bb6d4345,d1433e4b,d1c65d72,198f16b5,4424dde0) +,S(39a5a63,8244aef6,432b1247,d394d305,ee594bd2,6ed2433a,3a96c4ce,5a158d0c,147ced39,dd8b8494,d57ff37e,a24cb108,ee4b9f43,50c556cd,32df8b27,626a8023) +,S(8f9febb5,b85bb2dc,74aaf7b,81b27796,2a18f6bb,4879f5f8,de94aa56,b3206487,48daebd6,d4175a00,e37dbde,c2b57b3d,dc7474f2,ab6a093c,32a86acb,f610c2a2) +,S(fc16fb14,2f500856,4509158a,5f6b4e35,6a08db53,36e9d3f8,4f7a03d,9143f60c,8e9326f2,7e02b73a,10f4ada5,9db85fe7,4027584e,6b32aeaf,58bcf804,dc1f7a36) +,S(7db09ea7,17446f6e,9115d8f0,987eba83,eaecae01,f4201d78,8e292486,85c5a281,b4469cee,426d455d,f736b2ad,c12fd17e,79fd2167,c5a6f864,2733e327,c215742b) +,S(d45d1bf5,28baef1c,3ea56fda,b1f8d3c6,3df7caf5,c7ecb0b8,564fbc94,a4d9a57e,91e26984,64830e89,1cd21d3d,81ad7000,ad0c84d1,3c05a191,c1a172e1,16aeccc1) +,S(3faf0b75,1b6f85d8,550a9ffa,a7a26bb1,6a4d9c99,ae97678a,d43a1a91,75f03901,8a5d062a,a4e43cf6,5caaa39f,6386311c,be775d14,3b8d9368,b555c436,1844328f) +,S(54608cbe,8e08a472,79cc5e39,c65e1ec0,1eefdba3,3b127107,4926b06c,76efd121,a7695bc,40def81e,48ec5f91,cc98fc2b,9bdc2776,71d05afd,cb789e20,c540f038) +,S(559a0d89,50dfcd4,364e6955,23b56972,e8a201da,4e196d46,64dd580d,909823ec,7bf8e1ad,d6528b90,cedb8d5c,87f5953,5641e32b,6a6a7b4,c46e8052,e8dc71c3) +,S(166e8858,b5e2b9f2,b1648c34,41e5fc28,bb305ea9,b0679c3,1a996b94,acf467a8,9c9b306d,ff82fb42,acd8a6b9,108f9994,dc1b7c37,dd0c9d2a,f64205a3,92e5bdb2) +,S(40e29e8c,e66e83ba,a94ec5fc,3ae438ee,e5284f94,c5efe5a8,d41da738,38fe1941,7c71f71c,c01e7868,1cf154e2,73a23d0b,84ae684f,b0e709c3,9551884d,39acb2dc) +,S(6829c8f9,eb659ce6,7f87fc76,4661b400,6aeb8b3d,bf674408,1a844380,72d4ee7e,1d35530a,8332dc05,54e82522,5e9ff30b,6647fcb3,304fd908,ea506945,ca22913b) +,S(4a3fe05a,322e9fd3,93393b13,6e2af237,e25a2540,42d10e7a,dbb35d41,13658196,859a41f8,d4527641,a93c40d9,ef0ab175,78dbdc45,7edeaea1,f147018c,7901574c) +,S(de5817c9,a675eb2e,c1567ad5,a6467cc2,9e9ddec2,177f382,25a5e101,9aa44f94,4050ebd0,5413311c,df17e625,6d4bf102,71b45e17,4c8fcaf5,ec36567a,ccf723a4) +,S(fde29245,4f07f411,abdf1a2,6f3d8f38,daa7b9b3,1b51fe7a,155da5eb,5662a108,f2a4e6d3,7b39e929,ccf347a3,ac6c719f,f09d1756,e407371e,d98dfdc8,b727808a) +,S(f28d3cfb,6eb98ba1,76fc536d,6a772861,b0917415,d08c22e8,a43a90ed,eff42436,4508be2b,b328250d,e043dc82,d8894aa4,1971fe8c,42e6cb61,e9d02735,1279d1bf) +,S(c7655c30,4d1cb5b7,d0992afb,119a6df7,7bb65496,420f78c7,117b951,7f16e3ee,898162c2,cdb730dc,4b986b1c,b0de79c1,a348b0be,51b9070d,2e427e2d,e71dfdfd) +,S(e57d97c7,2fa3ee66,71d67936,eb62f4d8,53ffba74,f2158d0d,7ae3eca0,7b4b147,b1e3012c,a3d92975,91ab80b9,a668ca13,1ed42660,47c34958,c07c720f,e1fecd64) +,S(eada8642,155025bf,c0644f92,fe014ccb,6cd3d37b,76686a44,bccdf8c1,e22b0c01,89035d7d,71d71bb0,117c37c5,540f82a5,7152aac,af79fe91,6aed7d2,9dfeeed) +,S(3e76267e,3f172198,9f9d7e8e,11fa3ff,62dbf8f9,77503e27,5567ec84,e60d0e25,a1835790,9631c6db,a453001e,c7e3973a,416f8bc7,e2fe0871,82d8a236,6e1160b6) +,S(a11d97d8,9c262f35,2279e69,2d66be7e,5de7235,18e6750c,6972d250,91a3df70,d18df8a3,dd6fb016,df2e48fe,ab889165,44768d77,e9488b71,fd31c6db,d52a69dd) +,S(b16e3f75,cefec06e,edd54bf8,dae7cc29,a5ab5208,fd58d787,922f4221,f5f20651,57fbfeb4,5a6e32ed,74fc1989,16909891,233ae90,c539b81d,a758761a,a6d0eb2d) +,S(37de800a,3f73ea6e,9eb564c2,faf147a4,837339b3,44a33d9f,beb25784,c74628b2,59339259,9da55803,196b7e5,3596aad7,e33fc96c,fa2ae0a0,2f41ec13,e6254050) +,S(6f68412d,65b3abaf,6fcb781d,8b6e6baa,4ae57fb0,9325a1f1,9beec438,cbd68055,884fd59d,406171bc,b31042,21abb5d,27dc1433,ef49af08,ec031543,2f8d3bcc) +,S(91479a9e,6bc5e261,24cf0ce2,b52f070f,980f1f9a,f60bca79,572902d6,cb6e4366,2304f70a,22de4435,99f6025d,4b13be27,47932524,112f64a,ef935d1a,9c2f5288) +,S(8ba6b0df,36ac8708,8c1e7c1e,4177dcc9,4cceabc7,4a6c7701,8358c194,4d19bd8a,e96b720e,e9d515e2,922abe8a,177ac755,989dff1b,789a85ba,ad17f859,62ab9ed4) +,S(ab152195,871f3fcc,58f59a8c,a35514f0,f11b8a69,54e4ec9e,f4aacb7b,29d567cc,c1ddad48,623ebda1,42899ad1,75f88ff1,965ec1ca,651b419c,3c8ea037,f267fb4) +,S(7eb23f48,5eb92bd0,1c0e6448,e19adc22,6ca45c46,d4d5c756,e552ce7d,551600c5,953e9b12,4278b939,7b3de07,63e30c55,a300ef97,a8587328,b3dc27b1,a7c57ac5) +,S(b23f4c2b,a4b2700d,c7520a92,25890491,e0212fb7,eeb1f0a,2f624905,4e21ee17,a38b6772,9e95b3af,2cc7d5a5,c10386c2,8a2c287e,6349f811,457ae0dd,8b598530) +,S(85d2e723,387e55b6,a2c1a02b,96cfad64,67a6c12e,b75424a9,a10ab77,2769c2a4,727abdac,223898af,1b077fb,7d481434,ded380cf,21a131d0,db845150,c8e4d303) +,S(27c1715e,8dba4cc,41383d59,e669f66a,54ae6901,88a794be,9fd8da6c,9b09273d,2767ca54,306e6ca2,3517d884,1e7f30f3,e16e22c5,cf2bbf9d,998d5cd4,b5b1a266) +,S(e70b8cd3,7f9a5e8e,9e0c4fb5,6f85a6ab,42cf4042,4080350f,4465cf8b,95eed89,2e3d8c58,94788d1b,9734e93c,7508cad,faacdf06,319854fe,5ec4b0fe,6b0cb31a) +,S(e23dd455,24058396,98c81a39,f3f076ae,93932c61,d0e7f65e,e2c2013c,dde956b9,6c53cbd0,cd8ab8,bf5cef85,a8aa0b64,52b57e79,cb53315b,1dcdb68b,78cf77c9) +,S(5e923f81,ccc49813,11a09f2c,47677cbb,9aaf0832,10c683b7,d7a07399,4d919c9f,604d7112,e64cad06,fe0e64a8,af7054fe,7059667c,fb5159f7,738b97f4,38306873) +,S(23d9f253,1a9fa278,e02b71d7,113fde6b,1380e543,633286a5,60037ab7,70142507,55dc8247,b6eb6119,a6ef49f6,bb4e85e3,a9fd201,4f696564,42d3372b,fe44a9ac) +,S(eeb23095,ad2551ef,15dbb281,5ef6d252,886c79ef,12c7318a,50f5d89,d73b8f24,d1a71b94,b9810ce8,eb0c3896,3e7cfb90,56a80f82,9d384eac,67d9859b,11ba1ddb) +,S(64a6de7b,57bdf7e2,54beee53,6efeea9b,899a8436,e421e3c0,e7a2682b,54b7c21b,6427936e,2e344fca,c402e2d,2902fc6f,181ad190,e3f0d537,cf40c96f,27b4755b) +,S(9e4676ce,d76daf3f,1c1aad5e,51e700b8,8207fd45,3cec846d,779f02c2,cc270073,5685c781,1d7610ad,4655019,5d8a844b,6ffc4acc,eb458c38,d9d74f4b,cbdc9e42) +,S(95ee1228,80616ba1,76e0ee23,14428c7b,1d83c635,6ec843e5,d134b359,8d645473,7be34c64,41914c07,58081278,9b254c71,49a60d13,c6ee3a3,7d12e29e,a3bf4054) +,S(e53ffeef,d92081a2,f91df506,6453cbdf,d0b1089a,c598da9,94fe4c03,fc6516ad,560f02c1,4a600d02,a2e70b28,5164618f,5dcd1b67,ac071929,ecc1d891,e4c59c2f) +,S(9c332744,7c75488c,5a14f1ad,fa3d9974,90d4eb10,63afba83,fafcc3ea,62a7b68,9cc759fb,9a7fc3b,4d0ff7d2,24d0cc54,cacfb78f,5590eb8a,d689b6ee,19791c63) +,S(e826d500,2f4315ff,77eb22b0,c8b74142,f1d1037e,81e3c58e,4ea39430,973d3c45,3a466e58,82f971f4,3ab9316d,fc7d53a4,e8ab16e0,2ae75045,5d8d1999,bc8b65de) +,S(ced4df0e,af93b5c4,8dcf196c,6e9b16bc,dd38a87b,3fd67512,d387b388,115e13c7,fe08a63b,dd149dca,b4f2c930,99cd11e1,8c754271,cedd597e,910462c6,d68b74cc) +,S(b056ed27,88ea50df,2b220182,df38f54f,8065e36d,e0218b27,ee8c5416,db7eb33d,97338375,cef457f9,ebe43aa8,28e9a1e9,8d514d9f,fc300a6b,a1a83db,dacf6409) +,S(35dec74,2fef94a,7fe60b66,7341f6a3,eba030c0,4061d156,1c9ee288,5b7830df,2599121,39c810fd,e7f02fe6,eb6e9221,3eb8be6e,4d8f045c,aba1f058,789b933e) +,S(3f23cc8,7733213f,d2e15cb9,942af44f,d7981e97,37c5af1f,81addfb,324e020b,24e8ccc0,d43ccde3,4e392455,dcdec100,7ffc0c61,3b5f865a,c8afc051,756e8f83) +,S(9ba96c76,c0805cea,d7ecfa43,dba0d86f,c8471dcc,8bce9bc1,e06537ef,2bbabbdb,c1a3c433,1c2ae04d,be2f8e3a,8f4f07b1,622d9820,607ee3ae,e93bc37,f943def3) +,S(83c1479a,31475395,8d510396,5decc9ce,1d414f41,610e2ac5,c2e887d7,d16a3815,84d4d018,1354cd46,e5f39bbf,f9fffbba,c123d470,d07c292c,7f085740,289b5b7a) +,S(bacf627a,2db11d88,76e6714a,2857db8,a8d7010d,7b349ab1,fcb5ebc7,efe0a32d,a287dc0d,a44c448e,68b777b7,36ace20a,14b3e586,bab7ef5e,d57ae303,e8c83129) +,S(73063c55,30129f79,10bfd2d3,a0147167,4ca888d1,d64d24d4,619c5cff,2776ebd7,d57941d9,44ccf8c8,2fab0362,b14986c5,9d71906c,d28584ea,368c4bb2,2c159489) +,S(4ee8632,df55ad15,12ba4ce3,4ddb403e,a3f51a12,d445a011,4d08a00b,3b5d6637,c29f7199,dc30275a,39ff01a3,19723d19,91687901,9616fd81,88ae6c45,92b14820) +,S(fc46e66d,68bbd41f,98b18a16,a23efaca,8f5345ef,b567786c,cd42afe7,d7e7ef28,8b42a2df,abf8849d,53daf38a,4a4c28b9,a0238231,ec8f69d5,d702715,a643c18a) +,S(a71ad1b0,158d7978,7eece5e,2a3907b1,3f9b6b98,aefc7963,8a9de618,b3a7dc13,6fd7e86d,a956c464,e538a864,41b9b7d2,ccfc5c44,e80a66ea,4375e6a1,ef08bf90) +,S(602185f3,6075a67f,d7bb9957,60c6af59,61a7c553,d51d828d,ed37768,f1860a3a,90d312db,706b835e,647a027c,e7a89d39,2265cd4,dd52e802,165c32bd,4d10b2e7) +,S(db0fca83,76729191,b9d9976d,37dc62c3,36b4437f,943706b5,98e7b7df,607a77ca,23dedd6e,8eba7ebf,e0c9f0b3,2a1802fa,78699a68,99507dd9,c4f4841d,82efc29d) +,S(6919b861,598d4f09,2a159909,fff8de82,237d0aec,339d884,7618f257,a4a54939,ab9f82fe,1fa53aa3,b85c0784,59a4e191,27a1a214,392c3ff2,f3e1cbdb,6f34b90c) +,S(f4a7d2e9,f1f51ba7,c3cf0a5d,5d53a00e,877ec118,f7e39e39,299efb2e,8074bd59,9f050900,6aa6ace2,da4e6380,cbce7983,c9bea9d,99741be0,ef17e190,2c5bd257) +,S(8a5d7210,d4f1de13,1091ae23,2fffbd96,3927317e,54197656,366b2e35,cd453da3,9aff8a1b,5b71da0e,a6558a05,a9306adb,4cae1004,e532aa98,abcd1644,b0580a54) +,S(99eb23dc,e40d7159,b0a0406b,ea04b87a,2c9195c2,2afd79f3,f938018e,b8e86f16,2ef21938,a66efdec,7ff6cdda,a79fcabf,b1f17fde,9e80db37,82b47d41,64ecff66) +,S(3bf16e84,1a874418,ac7f0d0b,9abbe781,611ad0e4,7acbe904,a99ba65a,b4d37472,1d3cb9f4,e1948cb2,fc88c0f1,9277437c,7d1138b2,8aef4355,1fb35121,a3e714ad) +,S(a3ef83ff,19eb394e,b87c133,36388a86,561811ce,5449895a,f459fe4f,e7f01f3e,1955dd39,8bdcaccb,cdc7ddb4,711d08e1,9d687ccd,d335a4a1,45d13a4,8178cbab) +,S(26816f51,da9b4e81,3edc024c,223dd6b4,5a344d11,f5ade552,63ef17e,70b1af90,46278e1d,1d6b67a3,57280967,6604e897,65611b7f,bbccfd30,22007a60,294aabd6) +,S(5e1653c0,d640f148,ecbb14f6,97940b0f,1d47dcc9,48e7525a,909e8444,afdea823,9b8b81ed,e7cb8350,ecfaef22,92bdc528,8e499cc9,6feedc86,cd45cccf,4cb092c7) +,S(1bd88e45,b0d3694,56348c23,125b12b6,b7725d6f,addc08f2,47fe9dbd,e828de9e,182939e3,2d8bddda,577dae7c,a1d40164,9f6faf68,69808fe2,98dba2f,b8a95db0) +,S(4b03fe06,3adc4e40,315e754f,bebb7802,b80ab716,d4201fbd,31b12c5f,d9b73c02,a864d0a8,e2c5e519,ced537,e03f98e3,a5623c31,ea4a430e,73e8cf54,1c80fb06) +,S(e20a515,7818f33,1ed927f1,3c46f3b5,2146860f,d085e68c,5884f1e8,45d35f61,a1c12002,1a79d6c5,89e466c4,3fd48f66,a924e9a0,a3d20db0,484875e6,96bcf328) +,S(e3d11a4e,74a1e1cd,8be24d87,4885e1eb,4aaecea1,c802ba73,2db925c7,f81e37be,8f1ec01e,a1ef01f,63806787,b8831d4b,22b0a9c,7b44bc7f,73d2a3b6,861645f5) +,S(8a233215,57fe0dbe,e8e92b58,4729b163,da71fa32,f400617,d1e2a081,3e37f6e5,af5e471a,bb8c7505,aea1ed74,bd7798cb,267dbd29,61c35f5e,93889056,aecce950) +,S(3bbc0a2c,b43f4683,151070e0,7015cd6,997e8dfa,99685cbe,99f9a76d,6851d20d,9a1dfb8e,a5f14c40,b9968e88,b6083111,fd140843,96fa8278,bb0e351b,7cb4f97d) +,S(8c04d781,82d83ab,e8c59dac,9407b4b9,65380f38,39431184,811e133c,911d1deb,4d74e493,fdb22316,fcf21340,88039534,c0a3e098,7198ceab,4a65260b,4c0a3db4) +,S(467d4d0e,72312cde,df0aa7c4,62e03644,1ed9f915,c9e7e8c8,5770a4d6,d6a0291f,83db40a9,d7c2954a,30c624dd,f11d565a,f117e240,183a81fc,d4dda1d,70a1ce32) +,S(b62f60cd,8e55a101,ab060186,941cbd52,ce73ae2d,e19ac195,d55f498c,45a3dc8c,59da48b0,7c6d2562,eeb0ed09,158cd20b,4a5108b8,fbf6fcef,428cc301,b314ef41) +,S(6b5d6210,f98aee61,df36d7f1,9546efe9,166e88cc,6492183,379dd1b5,cb9e681f,dbfb1748,59c88a6b,72c8afca,830045c2,7c6de87a,c47228e7,7f246e6f,698a0d76) +,S(88744d04,e8c7842b,68d2cc9e,f58977cc,548768db,48d3c286,49ecd0a,22300c97,84573aa5,1ea3c51e,5a0b0e42,5c7c90b6,149d2993,91085bc0,393f58a2,8fb9c38c) +,S(fdf2c824,40f2ac58,19b06571,216ad938,d0218ba5,be4d3d4b,ada80e32,c32e37c8,c2abc4b5,9e961ffb,e48c6f20,58602dfd,9172031a,740668b5,5876d5aa,5d538f74) +,S(4d2fdf64,1f5a883b,322273bd,24755405,15178ce0,9b4ce8a9,36648957,ef777559,22ba1d01,210bf31c,6421b89b,9b3217ae,b2837f01,c344a9fa,bed0b385,4aa41b11) +,S(ec7cbca1,e743bfdf,81af3fae,a5c64a8f,5a54dccc,2afca269,9c461592,34ddc633,9f193da9,ea76a050,7b528c05,e5a10107,dc5263e4,98fcee29,5f57816e,4eab0917) +,S(ff2fa113,771998b8,b801e779,3cb804c,da9cd6df,9d371943,c7fabbc0,44b44fdf,962127f2,1ac57670,c79d966d,b8cd6f0a,2aec6824,22cac54,23746bcb,2df6093c) +,S(6d1b406b,2dfb02d2,34ec21be,c436d6af,4fd418c9,29f175ee,6475e77a,8a57580,b8945668,9dba8e2f,8f0693d6,d3e7b602,f157efe5,38b9ef07,b2dea23d,bce895eb) +,S(4abb9dfb,449e00ce,46476727,dc6b96,317bff7,74c21df5,87bef539,644d7963,6086f2b7,c016c69b,2ad80786,89af1c98,4d6dbba8,7545d8e4,9c2c58bd,f86e6407) +,S(db0c51cc,634a4096,374b0b89,5584a3ca,2fb3bea4,fd0ee236,1f8db63a,650fcee6,7ec0bd2b,aea1ae18,4bd16fd3,97b0e64d,5d28257f,85836486,367fe33c,c5b6e6a0) +,S(ae6f6dbc,d0664919,a65e02ed,646de704,6996a382,21aa8e74,4954d22c,37fdb287,abe70eae,f8ae7404,11931379,19f9102e,c5bbb2f5,f5fefd1b,b76fb6a1,c3f2f201) +,S(aea3eb97,cb321f30,bd0771a9,17fc9770,f4079a62,fac51fda,63dd3ac8,d35f6227,b6a53416,398515c5,e9133704,a287dfdf,878145a1,4416b525,6f1ae46,6abf39b6) +,S(90c9f8cf,711d50de,81f7234e,f6c13af8,39355c06,3e891ded,51bca1c,852233be,8d95778,18f19649,f2d3d452,81358783,17d2c32e,aa01551e,d7fe21c8,3421bff5) +,S(5ad7ece5,ab1d0344,5528dcde,34b48efe,fd954aab,920260e2,1495ed8c,86d976e0,2df2163b,2c3c63ab,bef274e9,3c46b6e0,62ac9444,b17843d8,70014b03,f78569b0) +,S(b6ba2e2c,8e942ef0,16e6d3ee,13ab0cac,1d80ae7d,588a831c,b7844e8e,3bd28d9a,41180a35,f923dfdf,501b6b06,7d241160,a2ebf453,d00b501d,855ddb7,1bef7fb4) +,S(7e409bc9,bba26c7d,fabdd450,bc84589c,799555a9,c6809cc4,13a4c674,7ff5f37d,c518961,9cc5afe2,e41c4260,481d8fdf,6066b034,19fe030c,e423dee7,79c9e6b1) +,S(9486cd14,70b2f2ee,28d01060,6c7c4c22,2c72636a,a50b64e0,3008516e,de4f602c,886ccb8c,fc5b006f,df931785,f732367e,c062e9a3,49f452ce,aacfb74b,deb467af) +,S(e7c11d7b,c8b07205,1e1af6d8,745ba05e,94b1ee9c,5482d83b,1af9ed8b,21338d2a,fdc4d293,828cab1e,fc9062aa,192f35a9,6ad4683d,797fcf79,c74852de,d75c8e50) +,S(dfe627b,ff315cb0,1b1b67b2,776ded35,19b1a85d,8e802217,c98000f0,93d50bcd,993c55eb,bb65087b,6fdd2480,c9d68e6b,ea0f69d1,b95efc28,5f32a8ee,55f9e773) +,S(a0f0cc17,fd00a2cb,5fc7c981,860f02f3,eb31c26d,54841dde,189eac65,a446f516,bfae884c,31d58a3b,f11077a7,d3edd37e,14bbe4ea,bd30fa74,ff5c295e,4b3b8969) +,S(c1dbb6bc,bc14286e,d6eef926,c946b52b,d37e7f53,91fe1dd9,dd7b72ba,a3e37338,67b02d87,bd336882,f4b6fdc8,1a3a88d7,aa5e2735,139e1bd0,e793e6a6,12df7bf0) +,S(20b9065b,c7d495c4,c92cb1f0,6eedf5ef,7025511,10343eeb,e82505bc,bb4bebb2,a6987316,5c231d92,bd21a4f9,60242d9,4fec71a7,4b24fbd,55d51246,10756835) +,S(7bedfdd0,c4d8c38,dda9544d,38fc8786,55ab9a66,4f8dbf2e,3c54810,eda69190,9994f0b0,d4f52de,6ead0049,172fee05,365556e5,3c9d4591,690715a6,f8af77a1) +,S(26762eaf,997983f6,ac63815b,720e97cb,5adcadd2,419d368,df4d385e,6b5918e0,81f5448c,e11b4dbc,24be2e9,be5620fd,25f0c0d6,76aae549,2792188d,5a27e6be) +,S(7148cae7,ee18e152,c3354ff5,dda86e13,ea14f175,92d0d3d9,a944f4cd,f387bb79,bdb35fa,f6f86e90,41465efe,dac6bc0e,ffd42a0b,eee83365,93dcb4de,2310b18d) +,S(27e45dd9,33ae2c33,a69ae00b,156845b5,bb4d8f06,593c2723,5038ce17,87bdbc90,a2bce33f,a93579a3,f8d9c75c,9271a2b1,7dfe36a0,590f2db1,f7cabfd6,51801ac9) +,S(af0c7215,5b28ae8c,2a2d79c7,d81e603c,d0539c11,fed2aa98,fa2bf2b2,d7d6b7d7,ae6bdfcf,a25109c0,b80bfc,71cfac3e,3b5b26e1,e4f2c856,40d2c69a,a7ac41f9) +,S(7b63c408,d4f8d34f,314e609b,21e8e372,de0f5a19,1accabec,7ecfe02a,63cbabf4,aa08009a,78fa96bd,8ceb6f65,e88859b6,236925d0,bccba7c,e0db29be,94f16327) +,S(ab768853,14f3e88b,d63cffb6,8f4f3232,4f4b4801,41aeff93,94d58f9b,85c6890c,1a71c833,d6d96bc1,c33610e,d7ff1481,c9ff9841,157c59e0,5d3a036f,cf7f192c) +,S(641437f0,7ad75112,f8375487,cc0ed859,ccd308da,4b25e5a9,953e351c,9e3bd32e,3c58f7e6,b255346a,f50f1ba8,3f008662,7d2ec950,84c326b0,ccc3a388,81a9b131) +,S(f532fd2d,600ed478,c1dcceaf,fd01ae87,60f7ecc8,7739580b,9b4a7649,67a082cb,7393514c,71117d7f,7cdbb4d6,c803c9f3,221847ad,697c945e,440bcfa1,1285fa96) +,S(33679959,2c4bab44,d89e6f60,8f882938,db73dbd4,75f0dc3e,e1fbd075,b1c7631,4c1f8004,6fe89cf3,6d078251,5ff57cde,17125d62,5cf675aa,1fd70163,49694fbc) +,S(e184c16d,2a34ca57,b06b5396,28cac285,6f18b7e0,32970a5b,e2221a07,be56c9cb,7dffc17b,51ef9c4d,f16ab068,8c66df57,d646cd34,46b509c7,7f85e03d,e2c5bf73) +,S(f8a97d16,2fb49d55,bb8de990,9a20c1e3,4f6ce6d6,efb8c68f,e26c884,6415d419,3cd3cc53,4dbfca01,9492e161,61f2e86c,5f20a83a,866874a7,ded4c2e4,42061146) +,S(9eb6aa2f,6c6ad821,d46dd612,38d3dc53,28cfc406,ad71964e,b32de0ea,12475781,14501a83,79d32e09,3664ce34,1a419b28,53dfe3e8,fbc204af,cb33e347,6c45c299) +,S(ebc2566a,68e68955,e1e42740,323fd401,7c40315f,ceba7642,5f887a3c,3602668a,75e8109,96ff56e2,655f9f85,ae9ec9a5,fab3bdc1,42ef063a,a06931e4,d4c7ea39) +,S(55646438,a966ce5c,2fa5b29d,ba4840cb,ab9c5e4b,4074a9fd,674b7eb2,f52bc392,34631a86,76034a89,cfc3f68a,45cd52e6,2987d80c,e9a8e28f,a37020f,981c8d66) +,S(b87f8309,befb81f3,313257b8,c7dd914c,82eff5d,6729f2e7,eceb0337,7b16575e,bea66832,59e4002d,6fbdf03f,b80bec1b,eda5e1c2,cc55c630,deedb7fd,a96ea298) +,S(45957585,b440d63e,acf598b2,16e435e,24b6cf15,2892c8d7,953471df,70a0a93e,f4cb6260,776a4f4f,23ac366a,565067fb,b29739fc,233493a0,b3eaaea,c4b71427) +,S(2c90f64c,8d9c42bb,1824c821,8f9cc057,3fe8d648,b960ee11,1487bbe4,9648ca87,829bcd57,ac643cb6,9f000a9,f22fcf57,69bebf7d,6b1d8ab4,da21be41,d3c25a8a) +,S(eb327ac7,779c9abd,9546a3fc,c7731729,2e753912,2ba9f7be,36db0548,144b5efe,21ac2c85,8d2fcd38,8c32c594,d6e74803,2cbbf365,238565a0,8c439190,518c9435) +,S(95ec7e2,272ccca7,aa2b07fd,d37d0f08,daa35418,1ae30e6a,dba0cb1d,2c6d007d,733786ef,59df6050,552ac913,c10b8890,2d589e7e,4f740f33,75f78fc5,2ba12b5f) +,S(4b7a6698,8b4fa080,f27c845d,7ff17371,91104a29,2c6195f5,fc367c69,fc0cbbd1,8b043bd0,a3605612,87b38fd4,d99b29e4,8e52494d,8241207c,9284581b,63a85b8f) +,S(89b2c58b,6df581df,352ab28a,619027c0,a9233792,fc6525e7,47dabd31,a342e6b2,300b1b34,d459e65b,e265edea,203b74bc,9b053feb,888e81f4,10045a10,d7f53a2b) +,S(41099b5d,9f6a28d0,e4a7ff0d,b75ec487,1c926327,89f0c800,7ada8114,9bc43cf1,2a0aba96,2e2b92b6,e949253b,e06588d1,3e07919a,3594b26,995c15b7,7a62cae5) +,S(bcb0fc64,9ec508c3,507396b2,9a663555,8825ea9c,1389c817,af7fd616,7229be4,168c7992,cf3bf5ab,6c3a12ae,922e647,13664db9,2d7bfe5c,2c746933,3a07d606) +,S(7a3fc958,5a6256af,9e314ca7,55a8096,9cd3b3d6,f70349a5,ec719cd,ed8b762e,fe8b280c,29cd0716,35288526,b7179d90,dadecd78,39128f22,17d445cb,d3df1346) +,S(377093e1,b968a35e,e0f229e1,e656da9a,7583c1e6,d06fe1,c89e3f06,61a8176a,e7c0860d,f6c9f461,7e6a4dd0,b8c0d800,6aba8e88,20aeb82,e6e0f8a0,c2c601d9) +,S(c5eff3da,f4a5cccc,f1f27a93,361301a1,919b1dd2,5a98ea37,5ba63f14,4aafecd8,34e11634,26f983dc,18c8a02c,2222c2fd,a94129f,4e3f1d67,f424964c,dcb97a1c) +,S(fc7919,eb560d33,44230f72,8368afcb,3c0fa6f1,52ec54e9,84ea9ccb,e63ffb27,1c7d3782,af766ff9,bc1cb838,8e4a7dd0,a04bc4ce,adad3fa9,4132842a,9859a6b3) +,S(2783d7fb,49386d72,54434cd6,edc6f46f,b3118322,43d381c6,287d8b24,861ca5bd,a3aaf271,b806ac0,e3c45026,28f89c79,e4c68574,81710111,a9316e38,c7fa5c70) +,S(7407a478,68d4e0d0,f77f8949,5e5bbf95,88f54a6f,fd35d229,8ad4b30f,2d8a02f3,1250d562,96e18cb0,aa5b393e,a933297e,debf3d94,59ac1ce,24cc11b5,87fdec9c) +,S(c2d2cce3,2940ecda,77ac108e,71544079,c5899fa4,f8461df6,cc54dd21,a861a321,f0beb1fa,40bb8071,928b05e3,ecc8545b,a919eaa,e830db72,9e6de85b,f05a1909) +,S(8cf6b189,c5051956,6a94e1f5,ab5e9530,d459a935,4cb13eb,349fac3e,ade8a56f,bf6a9d70,32e52886,ce6d06d3,b22d47a8,327aa788,1621338c,1606054b,cfcf9c96) +,S(d6b07586,ed9f8471,f96ac5f,53277d1e,2deeaa2b,7fd09d51,ece6766d,29a94968,dab4d4b4,ce5655cf,4aef0d0d,5e3fa292,2f79041e,d2e23c9c,75be83f5,f09c5326) +,S(a720b733,60a03edf,f33a0921,90795834,9e661d33,44da800f,b857227b,ef4d647,1f213c6a,721c2d82,6037e3a5,a0f4867f,13d79dff,bd44f5b1,1bb5c0b5,4884ea63) +,S(558a5698,3b03c6c6,717db862,e59dd075,b39f9ba2,ca01b0ac,95a69cec,1f3a5ff7,7e07c752,db21b68b,21738458,a045fc60,fe3ae869,887fd557,92ecc6c7,d4ffb1a4) +,S(b927dfc3,278668a8,c5329941,f11d0e0a,a7c2d9d7,f8d6c263,9cab5550,10e14ca4,3ce83725,9954227b,b420e35f,77705225,72f4d854,999af552,4b8795c2,b723388c) +,S(2b70d499,1085aff5,88e23ed5,ab55a374,3c35f71c,651c0165,13f98ecc,4f0e6da8,df413b4d,aa1e5c9c,a2398469,7d82762f,a701413,1cae25cd,1a94f02a,506a8b06) +,S(b8836cdc,f72f6e00,99a9181d,94ba77e9,e1368e54,a62e1144,1421f2ef,2daefe56,9ad452f,e31f26d,cad7014b,68ceaeb6,1beecaa,5394c359,afa52209,e50427ce) +,S(252b297b,65f0e23a,9788b48,f33809a,ec66b445,cd90db00,4dcb6a80,c4af93a7,8cc4e0c4,3c346211,736a3bcf,c24a58bf,9f77c7d0,c53350e8,6cb0de2,60916838) +,S(9f3d30ca,1c15cc66,8efd5fa0,3d6b7bdb,d34f2704,cd729892,aad9171c,debe6330,448b6434,f95ee7a,bc056974,f1476171,353d9b98,4e22057b,38662327,b23211b0) +,S(8225e16e,5bc9add9,ff8a771b,5bc7bce1,653b545e,4e54b9e6,6e2d2985,2fd35e49,6254c5e3,aaefa2c1,6ca4e1de,87f09d94,df836b9d,d100612c,7174aa75,7d0570fa) +,S(a7dcee48,4d6e99b1,b72a80b7,4de255b1,74f4767,4d3c5799,4669ca6,aad02ebe,1d6f0cfa,76a2901f,4861f541,bef7a948,78586178,8c7c42a4,2db583ba,1c170a7) +,S(a91445a8,5d4ce90e,98d3372f,d2c664b8,9a6baa2b,a396fd1e,210e315e,809976b4,adc4c68b,99b072b1,b51d1512,cd94007c,72deacf9,4e7c5449,f1d83876,78b1d100) +,S(7462c9ce,907c9655,75c41096,3510e00f,6f6ea6ad,886cdc79,ed685ee2,2a7ce1f1,4ffa41c5,f02c2299,c42df5ac,79cc4140,47a854e8,332f8f2a,e67ffa20,bb71c7df) +,S(d42895f3,dea495bd,af8e36bb,6a79f234,dfd85544,965a8506,5d38ca86,28cd4f40,2fedeb18,13a11c42,e7869b20,7bb8486c,9821710f,a80d9bbd,59c92ae0,b50d9cf5) +,S(ef9b6b62,ce85588a,f13434b2,7ef53d12,e8291e6d,76a65669,c29d99a1,4d388adc,159f5fcf,9af0c962,ed907955,e91407ca,80261255,45b6938a,db18aee0,9bbf912f) +,S(4003f1a0,bc659daf,df5fb7bd,bc96afff,92877c7e,2a693f39,2afb06c8,fdbc9f32,ebffcaa1,7458f0b0,28ff1dcb,74be865d,7faeafa6,c2707cc9,ea685eb5,7961fef9) +,S(4390488b,6b03d851,648786f0,7486f5cd,aa9ae1d9,4867de,bed7036a,6ac09a8b,78329de5,a10db56b,1c35b88a,21ddf393,452001c1,29a0bd6e,5dd76a63,8682f07a) +,S(ae6da0d2,9ea3fb66,b6006c56,5dff8b41,6074ee16,f9ff86b9,60574067,abfadea1,74caaa63,dd012a63,e76f0916,f370614e,29e3f01e,b88b49c0,5ca33234,c11cdac7) +,S(78f879df,98614721,b7c65652,4e806f6,35942e0,950514fb,2fad8a86,bbcfc72a,4194e58c,478ae80b,fab661b7,ffb85cc7,2318aad3,88d61c68,a755296d,38281ac6) +,S(80684365,4f41b0c6,d6cd51cc,838355dc,352e028,7b1c1d1d,edd2f96e,5fc97e01,8b0c223f,13c61b4e,1e141a0d,35f29a7,7546bc7e,3b1e5c45,262033eb,92b62461) +,S(29509d9f,4fd975f4,6efd1169,1d97d0aa,f83b5934,9c797010,5cb3908,4b87466c,1477eb75,69a0af96,c9cfccbe,135e3c86,a33de585,2ead38da,8a0eba6a,6d0da81) +,S(191d1443,3d9c722f,c1532fe,33c63a9c,4e3d5741,6ebf799c,2d8ffeae,df1dfa4a,5bd00409,b6b571ad,745ecf83,91884eed,a5e3c7b6,65ec9706,eae4b4dd,703a2cd8) +,S(2843d42e,d2738168,5eed65af,eea82bf2,a50f0e1e,3db201e1,ebf8b159,1b0155a8,807cea66,c0fa9f53,b47e6e2c,232cb225,77edafb8,99a6f98,ff87d091,bbc63ee8) +,S(5568b7b0,9656d36f,5347514b,8e8212f8,e96ed02d,4516c018,4d653bd1,2bc8f644,5b44eba6,54836dc4,3fbda30d,7ea36406,4960459b,a4128911,8b2d8638,50e60d87) +,S(5b84e0e0,809e44a6,9e8d81ab,595b32f8,4a7dd421,c073fd6e,5f38ec5e,b145e803,1a65a2d0,fa791ced,72fa1522,ae431155,7e6109c0,fe934243,cb43d3ef,ad13d398) +,S(ef42c56b,dd241071,47e1519a,18d32910,675ba842,92cc8ede,900a64ea,bedfa672,70151747,33359977,611e0c25,4addbf6b,26a618a2,31474e3c,c9e7bcd3,8bff75ac) +,S(48dff2dc,b50d4a56,4be6ed00,3b1415b4,adc653ec,87eae94c,92b7c129,5656eb63,a9be97fb,53afecf6,f0bc59e9,8bfad542,fa29e63d,f701f6b5,f0f66081,8d643928) +,S(672e90f5,246ad174,10c9a2df,c22b098c,d1923bd4,19fdc337,f881e4fb,4ae938d4,73fd3380,1fda6db6,883e678b,31e5f09e,f331b624,5617ec9e,97aa28b9,a1781f19) +,S(59cdb9b1,71fb819c,909e094a,95dc15de,dbfe5521,4a7cb723,ee7cb761,4b315cde,55ac212,670b4a63,ecf3f8e7,3082009d,7f2d38d9,e490ca18,7a6db01b,e88351a2) +,S(5ce38d0a,357a58ab,134db879,b99994c4,6b827f82,8e1ce8f0,43108de,ad2ddb18,5e816202,d9c1d86e,c2f84b33,ddbcc51b,94748c67,1089c9c1,745a14d9,3b97f716) +,S(c982196a,7466fbbb,b0e27a94,b6af926,c1a74d5a,d07128c8,2824a11b,5398afda,7a91f9ea,e64438af,b9ce6448,a1c133db,2d8fb925,4e4546b6,f001637d,50901f55) +,S(383cb084,79e61bec,dca81d29,7796d00f,60bfbcc2,83c83d31,725f5329,839ec818,26e26fa2,49008933,8bde0498,15f34d9,bbc3426,ad8644ff,db1a190f,79dec91e) +,S(e6945731,2ad4f14a,71917b52,448011df,28b88c9b,6ac84550,248ca4fd,102f612b,30ed2082,51fc701e,5ebeddda,c9eb0b44,c81cc86f,9706889c,1b1c3386,4d76f53d) +,S(2d0071ba,8f799352,212168d2,1262a729,250809f2,24fa58a7,f283c4c6,bb9976f7,cdca6901,4e4873f1,16945544,800079d,ccc118f1,a5709b03,c872b017,5f1dfd8b) +,S(c82b9457,65b74fbf,91cf35f0,679877b9,da35c2b0,8437d789,8d748f22,1e927e,2e504dd1,bb06bfc,7e057dae,9aac8f07,b57a0f2a,39b1533d,9313d9f2,45fd6a2) +,S(9c1a4c2e,7eac21a9,fed135ed,e737dd19,2654eda2,fb3a4227,63cb6328,75bbf0a6,f3134b6c,12f71c58,226c9128,9b7b5a06,80eb6646,e9da2e60,20008efe,10e9197f) +,S(971d3d9b,bc693222,ed8bd645,e80b7cf9,9b170a36,2d57753b,6a2ac27e,8d6c9b28,d63d49a,e296dc2c,6c4a73af,7fc5e86d,e2039433,f3858980,80a36f7f,91d22e2e) +,S(f5493a73,86bc1151,23f29f2a,e0619e05,660a317a,bf5ac23f,a67802fa,8b917d2b,e6adbccb,8b780530,2b305157,b427b8b5,38455e02,80133e23,9642306e,65e0f1d7) +,S(831f123e,500e0a0a,e497a321,5ebde2ad,763244fd,40b386da,dde05537,99b6e014,35616862,2ff588ac,552fa508,ceef5ef9,ac04af0a,9db6b950,f44719c8,cb221d6c) +,S(9b8ce06d,18474c,3394c334,2ef385d6,7a338c22,98e92975,f1728c87,897cfb35,76940220,b8dc3e04,7cda50c4,c1f53747,7ce8757,a4a3731d,712cea05,42a40d72) +,S(f70a916b,a98d2bc9,60172410,42bf3e14,14f06cad,dffa7cb,1e8137a7,3fc5b855,f1b8c1f4,70d7896f,f39a3fbe,997a88f3,b5426d84,43c4023f,ff98fffb,280275a2) +,S(2d2ab7bb,c44e7fe4,ab283661,2f621d05,a64d6909,fd94e599,92d52afa,c0763d56,53450e00,2a6991c8,68fe044e,8b61c2d3,c5fec8af,3605728a,e57d32cc,c55328e8) +,S(8178deb8,c516978c,ea25423f,3a913157,321ff7c5,5d8058f3,dc9b9d46,f4d10005,16a71b2b,46c9d303,f4ae6a28,235249bd,f9c00146,a26b6bfb,5983bfb6,8d6ff4bc) +,S(b470bb76,d012ba7e,67ef9c32,add59940,1f700ca,16003011,26e6a692,36b56a64,f7d093e0,7d179861,871f36f1,58d26987,1775f082,a2fbfa69,27cc2272,614fd95c) +,S(164f2aba,837cac12,19b48eb3,30f02141,d3a89921,1cdb3f78,fe17133f,e2de29ce,3bc05608,95f7d034,4a9ec79e,b821c06,c2837c50,66925197,2c076374,871d28dc) +,S(c77a3a04,2a86d2e,f512268b,35cbb89d,e6a210ea,883e2283,ec59fec5,12e725f4,2ebcd56b,edf1a07f,e587e592,8ed602b3,6d1db4e2,5b49e914,8dc9eedc,131cfba2) +,S(e2defa1,f714cf71,557a3f1d,71c6abe8,11df5504,da38e9f,60ad335,3b11349,5ed64303,7a53bbc7,2f41912e,a657d944,c5107da,3b9ab54b,d88b545a,e045f229) +,S(ee2d12cb,b4cd9e4c,163fca1e,5a4330af,35280ce9,cc1d57b2,d2112443,b6313e3c,e28b1dc1,a4377c65,838ecafa,bfffb696,4057fb6f,dd4baf08,49f9223a,ee153262) +,S(4392c96,73e6deca,f3c39c34,f5be7c3d,a2109b45,2271467c,78f256d6,7d9e28bd,7fe4c183,ae352533,b049edd5,343a6bb4,747d63d7,d0f406fd,5902a886,110c50) +,S(5972e2ee,167374ad,93a655f1,6008f49a,f5586b2,f81197a6,712ff31c,a0d6960,6d70fc55,d0a57c74,8a2e485a,d903bd72,779343fc,7c090847,bc3dec1a,6f7c71d6) +,S(a85d800a,fc2c0315,889f1faa,29e5766a,a180f31a,400e3c19,85589af0,302c78aa,7429d7f4,903c76a0,a4437b41,92865b7a,ff5aca7a,52dd32a5,8f8b00d,b97ec85e) +,S(c9836b0f,d594fcc,9a89e85d,7d506386,ccee3f38,72759cdc,9548569f,a5f1c245,9f0b1926,93b7fed6,2f1a7d06,fd716727,bed1c2c5,9bb431ed,943b7082,d094fac0) +,S(ca2184fd,b2b84654,d0348e5f,6d963193,75f2c441,ae64622b,588cae7f,d202bd3b,d1222820,3d657aac,493dbb2,fe9729b9,e2563cc8,1f671626,83c4f0fd,726a4de9) +,S(9e0515c6,3c9b9664,8762704,80605d56,b5dea0cc,c7a4c66b,44a2e605,36941fd8,29de3224,a2eb2d86,afef789e,2dba061e,95f0b762,117ede50,6d4b21c9,54be831a) +,S(42042c25,33203a7f,c22cf7a,fa5f3d79,8a3447da,51d66f60,53a8f000,af5dc1cc,f075a67a,6d6c3872,315420d5,bc13d13,c54f3c1d,61f73d9d,ff688da7,f5e6c05a) +,S(6645a1bd,4eab02be,45884ffd,288955fe,3f5a68ca,9ae431bc,cd3967c7,12295b96,231f79f9,1d264ed4,28ed4b30,f0e92c4c,bf902865,24050b67,30cccd12,bb84cfad) +,S(4e281e6d,2c316e88,231482ab,1587de37,6898f3a8,870f475f,30bd1ee8,d4b32f9f,f48cadc8,1c119edd,e5f78062,cddc3416,c3f708d5,f37e4910,11ef7581,c065602c) +,S(77236414,96e41e9f,f13c7ffb,c7a66203,4fbaf7d3,e432ce02,fcd54ef0,4aaf5136,222e0174,d6cc01e,fb4b4bf2,9000f697,98bec7a0,657f328c,80083074,242dd218) +,S(3f2b704c,8d467859,ada6070c,b1221840,18ab009f,f7b5ebdd,af31d977,dd45860,a47167a5,146aeb5e,8c38dd21,5d61a2df,e2b6ab8b,fd05ea9f,b59faea8,3b4dd88a) +,S(794ec130,d243d811,2ebb70f0,35f983db,84b3acd0,ae4c5b51,640b9e92,ecad4146,49edecbe,95c25c7c,eeca537f,937aef5c,658f2dd5,d8c0de71,c80777aa,d07be84d) +,S(750ff9ec,e363e12b,79b04cf4,a7b1c0b1,49c554cd,6e9fe3ba,808c9614,95a96aa3,5a28269d,d1c5a3ed,f4e70f14,9a060b42,2d4474bf,1e4c6dfb,2de1502f,7a1d59a9) +,S(d65c05d7,df6668ec,b96c9ec1,fd129462,263b082c,9b7f4169,6335fb2a,b66272cf,d7728c5,1c10d42d,242cc5b7,fc77fdad,7e48be06,6b2f7c37,891ba4f0,de188839) +,S(d3804cb6,8cb2e9e9,b5b9d270,db9a172,aecffe39,72a3d2f6,1225bef5,595190c3,11fb350c,9568648b,30af4131,46053428,2879023e,6ff0d613,482c2471,b5e30d5e) +,S(f762de26,35c6349f,6cc95c61,9ecf8d37,6a938241,1106db3d,b34e9e84,70351bf6,dc67f9e0,c8a50f9e,e753352d,a99112e4,ccfe22d,3e88410b,1cadc0ba,bc9fd814) +,S(ab18b4bf,a827ff4b,17ee163e,d17e3927,d7dcecee,ba87ce7d,ac5e5767,53b87a71,6db83bd5,73e40926,c882bc09,c4d07f72,29706d1c,d2b1ded5,b57ea9b9,2b0da919) +,S(f754c248,fec21ae8,da343a87,459622a,b12478ad,8f63ad8b,f5c66695,198c95e,2cfb76a2,5f9c8776,b848d8e6,7f544774,e056ca7a,32bbae52,93b27992,6052b1bd) +,S(f8d9473e,3c3f0798,f893ecdb,716bca16,103516c3,1341c8e2,c2462d4f,9a46c51c,55f0065f,a422fe3a,26b314da,c7547835,5c53bd3b,e11b4686,9e05be92,d7924e02) +,S(8639942,d294cbc8,9a75fa22,5b29fda9,2f7c5ab4,bfbc4395,352d050d,754eb741,3913ea2a,445de35a,36d79abd,db3ed7cf,741da883,4cb81c29,6779d8a9,e7d11e4d) +,S(2a588c6c,706a388b,f1719230,b5a71b4a,6857282,83aec61,794d1a78,bb95d5c2,af25ed77,1a56f6d9,6407f07e,a7e11f97,61f458ae,bfbb1b00,96842c4b,6cc47592) +,S(137bd1ee,8931b9a8,b26dba4a,d9a5edb0,a5459717,22e1fe3,37ee8d54,20a0cb6,cde9fb7b,8197c77d,273e9f0e,e87d76a1,eaea105e,21154b7f,f5848a30,17ceea62) +,S(46580345,c686313c,97152371,13af2c2a,f9b5fea,a1e0bb48,d21bbe32,d2de2bbf,75bc5d7b,b6329ffb,2bfbc79d,b66f4c2a,7edade8e,a16bb051,a3a8ee9,ec92ef64) +,S(4a149252,afaf5acd,982fc491,c26af545,2ef93d6,1b282a85,56d5ef64,391bd233,fbc100bc,10b55b60,96656ea3,863f5d4b,bb9e83fc,5a25e59a,3b53d78f,60cfe285) +,S(894ebda6,fc0bcf8f,e025131,3475d64b,95bdf089,7d9753fa,ad0f92f2,15a01f18,b25f3150,155772cf,c69d0251,97d37ae0,1e4ede02,e2994377,9fae26cf,5f5ec056) +,S(e70d8a93,a91b891,30def1b2,bfd720ac,2deedca6,f9e5a85a,3c2a6eae,45eb032e,bd3aee53,a3b0ff6b,45fb96ea,4911cb02,fe102681,878a1b0a,693fdf11,4cd9f9cc) +,S(7cb1fdc3,e5ccb1dd,4a16765b,f9546b6a,1189883f,135d447e,eb245fbb,4eb36852,90ee0d6,becf5ff7,b80edbe1,75dbf258,d1889008,a8fed4e0,1968e2ca,8fca582d) +,S(51278ad8,331da17,8fc90a21,432b9058,b39f57d0,31210685,bf9bfbc2,87b9bfc1,5aaf547,f39ce678,8c3ad759,b25db3e5,7bc1f9e1,f75bc040,536ddce9,d3a66b6f) +,S(f0eeaa1f,c52b3068,48b56308,22fcf0f3,fee5008,54e276ce,e9fe9904,54f59cdd,90ff89b,944d70bd,eb5e5e01,6afbeb30,d51cf7fa,81182e63,ab3bb2c9,f2124f02) +,S(36fc9bf2,8bf90fd2,613670c2,27b51c00,df5b4caf,252b5df6,648ddb6b,3aeea71,887c3876,f1ac6c28,606c8161,4ddbbbe7,d975ecc6,9fd9075e,13d0e3a3,e7836683) +,S(6e31e26b,cf9436c,e14d2d04,1c29f62e,135c549d,5e65bacd,ba4df2a8,9b91b68b,2389684,9e63bdaa,b5f7d9f7,7a778b31,94c1af87,d09a9a85,85896188,acd0e7ae) +,S(c5044649,a4b1c2bf,ac6a8a1c,ead33aa0,3da9fad8,4f742eac,35792672,1d98e864,6d2602d2,83e696bb,717d1327,cc1143b,45fdc84d,b8d400af,537b201d,a7a1027b) +,S(a933e71,f13c44d5,bda8e963,b5a007bb,b9b2e84c,c45211e6,eca804ec,6a99ca28,931bf3bc,ec45e2f6,e6571207,31d42fdc,c3ce0279,542114f5,c1c0f659,f6200faa) +,S(9003f61d,840c2d62,1ba98884,e117038b,b8559d0,b132a1aa,83adf65d,f8e4a58b,50c75124,f72b3952,9feb7ece,cba26854,1388a1ac,73631532,b67f56dc,e8d30895) +,S(fc807c18,3cb370cc,8638abdf,c17281a6,914e21a9,e9f3e2c5,33fb7c37,caa0a886,3ac79d3e,75ac1d5b,a9af7263,9d564256,1ccf6fd0,6b8d2cde,e9d24a1b,e8af00ba) +,S(3d072ae4,aca4ac23,b43b608f,150bcd4b,cd780dae,7e4073c1,86293cce,dfee9cbd,6d9e443,f721c9f8,a98fc563,8d7627,f9c60414,67da3857,92fd55d2,7e65d9b6) +,S(d0cb8594,7061b4a7,d2bc5eed,522faf8b,ba6e26bc,7acb1d3d,106aabd9,a7f80dc0,fbfd0f26,e9d0dcc1,a0107b82,d1a9876b,8d7562f1,41f0892c,9b739e47,7b012e0a) +,S(e4edc0ab,6416c644,1e59f46c,c7221cc0,267aadac,242cee32,41a6d25b,635bc9fd,f41c3ae9,cea7b4c4,4834482,980807d1,c496fd4e,bb06964,b84c1fc3,4fcdc71e) +,S(6233b50b,2d3d9101,8f5a83c8,84be0f5e,ffb80641,1b0b5271,557d32ab,dd7eb4b2,8dfaad24,ffdd2ac2,5770f21e,328588b1,34a3a2b,dda40399,7911ef19,855dbcc5) +,S(6ca00162,e27265e2,27b4e544,7e981f6b,c427e65e,bde295df,9434b7dc,52a19ab5,d33f5f63,a8f227e0,a43fe297,babb3a07,223e8916,e153a5c,e0f57e65,1154cce1) +,S(c01205aa,5d2a8d5d,c0d328ae,7ce7cb16,d6c9d992,8b6105b3,cd68666e,36fefcfc,b65e5f99,c4f48095,e1bd6f6f,6af8ba7e,cf2988ab,ffa9bb45,3ad01859,e831d3e) +,S(e3965393,e6268cb,61d6fb19,58050f39,7b8a597,4a6c4abb,4e0b78d2,dae0e155,1f78ad46,2ed6e1d9,18004892,85383b2c,3f971fa5,cda0c828,a2f289bf,80731737) +,S(27bfd0f3,702a9d43,50c1a6,9fd990fd,3dc03af8,50bd84f8,1248222,6cb099ce,22e16b60,e8caaebd,19b0c0bc,e40be7c0,c49fd3f0,d9094f39,fec1b1c,bc643de8) +,S(8210fbc0,23319565,9eec1777,12997a89,2a37172c,6f75e3c6,cbf080a0,6f96a2f0,1ddd7792,101166cb,bb11d552,85e1eeb3,bfacbb25,6d1a5097,16dea91e,46afee8d) +,S(15cc66b6,5fcbbd80,df15298a,25e2ff80,ae4d5065,f8befab0,89cd21a7,4e347b5e,944b47e9,35748296,deb324c9,f5616d28,7b225b34,488fb34b,6ddacd32,7937c97) +,S(eb7b7aa2,45960169,1ea1a482,a9e6c35e,c7bb08fc,726c2c4b,ff801ae0,94c97976,4d2e9570,cc187791,fcbd20e9,3f0656a,f5596f4e,104c3f2,27c23f82,2ed1b1f6) +,S(4598fafc,ed29e844,c22436e0,996a8469,18e7c106,b40a5ea1,5fb0e7df,5e9ba12c,e73d96b6,d292ea2c,39779dfe,7f716609,978a8555,e5b09629,7dce228f,f35e6093) +,S(49835a86,3612e594,572a2591,76f90e18,e57d4dfc,1910c705,8e37eeb3,1a8600f7,3b7613a,fbd2cc1,cc23b147,e0e80d36,464c08a2,e488d7b9,8250ed37,dfcfa531) +,S(3a6d6fed,1fcc8067,32a3177b,4dbdc33,3cbfe0b7,d19305b9,965916f7,ce335351,cc3f3d8a,314d617f,148a6706,d7f10641,11eb2b56,1bd1dd0d,f2986925,5a6624ea) +,S(21208586,6860fe30,ce92d2ef,b2035b74,f672a024,ee7baa78,fb0d6c7b,3ad7a9f5,aaf145be,51b1ec,3fee8be1,1f6e9d73,96ff0ce3,41f25d7c,e1074a09,78bebbb7) +,S(f819132a,c9bb2f09,663d609c,51cb11b9,833ac082,6ceffcc8,67cda04d,266e4e06,b1fde638,ec6a305c,aaffd1a0,6404aeec,c52f48ef,7646abb3,7e227239,4c891de5) +,S(536c05d8,8786640c,43734d72,aed62d9,168385a1,213c4428,423a9437,c2ec009d,7f4be100,d827de18,68bc2b43,c83a08c5,fd84ddee,1fa9ef13,4b489325,db6df0d5) +,S(4328123e,c4c6db76,37ee3ed3,42c8a859,9de2fb1,a39a24bd,650b73ba,a1df722b,81c002ea,1277753,e6a22fa7,1b4f86f5,4ee11f10,f5d5b15,94c9d7e9,63a40857) +,S(f3e156fe,f8529951,86a9e536,f985c1,6a85fc32,d50e9a08,1550da68,112a5f17,91ffd66b,56ff0e6f,65d67e83,c362b853,a2f441ce,7418d091,5d5dd09a,b48892d2) +,S(32ba7359,84e13f42,d2e8a716,a54c40ac,6645a1af,eaf030e6,8242a8d8,8b456cc9,67ffcf1e,1c32b150,a82ab317,8ef24c93,f055765c,9e7e6200,f868b183,bcb4c6f5) +,S(cb9c2b3a,43d105e,518674cf,64d8b4aa,9c868b93,18abbddd,ccabc0ac,59829311,1fc67ef2,233f076b,ded3ac47,99c859d1,834bea5f,bd2bd5db,242607ee,842b691f) +,S(e14f2858,b7bf7070,32349695,e09bcd3b,5effa957,abc19e85,6efa31bd,2e9234f0,3e04e49d,d3f3fd39,883cbc25,80d5ff06,cf8cbf0d,4a895761,f3cd15e4,dce08bdb) +,S(156beb7b,1c27b8e3,cc78113,c97ff026,74810dec,58409e01,d7b7388,87550d82,c711730a,80216ec8,352adf2f,d5939991,3a8e92c6,c16c17b,16e27a91,90bc5371) +,S(de5ea7e6,b9b46864,4b80e495,9a2ddaa1,a24a3399,f8039355,7b798b5b,2c55d600,8901a027,e6a823d2,dc0a9d24,e182cd52,b9b1de67,22b7f7d5,3a03c615,8cd48ee8) +,S(8eddd368,8bfaed46,25b7312e,7b2bf0ec,aea07414,a1281ade,b79b9e3f,ec17c3c7,2db43af9,26171d34,d5ca48a8,9223e57b,59b885b1,5c4f7231,6d8edb6c,7955da7b) +,S(5c971b6a,665ad1de,8fa489ae,22237ed9,87872e0f,ef95eb85,fb2ad3d7,f0b1d4e3,4d71f598,37c2af6f,af32ff7,42ba01d9,aa8d4d7b,302d39a6,c4fc693a,5f8b1f66) +,S(edfb253c,28212b6a,d5b66589,a2a8f1cd,bd3586ef,34254768,85cfb70a,46b9e228,3e5b6608,b7e81f69,b8cb26b8,4f306292,594e42e0,25134c1d,7f7b2a24,b2616c00) +,S(4395f24a,e127772c,db163dd4,e22574bb,d2373cc6,b2c67384,737c56b7,dd525c13,bac6e725,4c800c2c,64896913,df739574,676581dc,1b4447a,819be64c,10103526) +,S(81100ad5,73a766b7,f8913b64,b5f5a87f,8c782353,5f62a3eb,182f0ff1,946866f5,52cac16e,325b0899,9d068f7d,51dd9d5,c6afb8ba,9870a9c9,d28b4170,e9a00c73) +,S(fd3a0551,41168146,6ae358c3,aa14216d,dee3a05e,e5ddee40,7f72347b,eb95120f,2af2f30d,45ceb12a,b89b7b88,b7e04b20,11a3c607,58ce7250,e4c7bcd3,da8ee5b7) +,S(17a55b58,a7eceefa,3ff05b6d,fa17d6c2,76d1a032,abd198fa,4e3fc3ef,e6435ff9,d7273958,a3ad67c1,fdcee72,e71f0536,418f35a4,57e06240,bc99bf71,b9574d4f) +,S(870cb7b8,e2ca5ea0,8c5c73ae,e15e8b22,793fd005,5ed7003b,c49b4089,3b789b6d,c33c8b40,7b701caf,26d7a9bc,e22644a9,4badbec,ad509cc6,a7b0ee04,1be67aa3) +,S(f951c5fc,dc46ef00,adc53c89,a50ca0a7,ffbf7c36,d80e4897,5452cc1b,4e71f8a7,6ae2f821,7849cc24,30864d7d,24df9e59,c1705b92,5792e648,75120738,c792c95f) +,S(aeb8077f,3b92c676,ae11bb06,a18ada3f,6cbd832a,1637ed61,31e4902c,96a0caf1,29f41d1d,f5d4a430,94e75fb9,8bf317ff,6c8a6d7d,b37ccfd,e0232e1e,afcc1e35) +,S(d46f4d97,5d2f2e58,6d18a7e,5d8587c3,8482b78b,595de60c,b9d2035f,313b78f9,95d781aa,3bdc1176,396154ef,31fee42,f704e199,4316e33c,1053491a,e86392f0) +,S(6afb44,4b4bd89f,2e21b54a,c49b9ec3,af810b97,73c76eaf,4f3a5f1c,7a29b201,3502901f,d7d3b4ce,134ed90d,1388ab37,64db460d,bed334e,af061822,6ebf932f) +,S(5f02e582,a38b1703,a7bf6086,9587af5d,e6634954,cfaf8394,932f7ed,ebd86976,a0487cde,92f3a796,b24b06bf,740b8fe2,ccfa5d0c,a2b68a7d,ef46a005,2d7afec2) +,S(26427482,60432ced,5a07b885,f354667f,ad70eb75,9c556e33,c6652d3a,a0599fe,119238fe,2560382f,d76ea737,9340453b,a63867cf,6e044c62,949f858e,b828ce85) +,S(6b2a3e5a,d327adda,52b19a7d,d5e837ed,4f03a5a7,e1e5b7ff,2cd66660,469f91dc,2f9f4526,6b482fa,f336560,1da9e945,354ed265,e8d7e57a,22f04bce,8a54c6d9) +,S(2588b88b,7e214fba,ab10934d,def13e8a,e5fbaf77,d7497dc4,fcc0345c,435daa79,3e5cf90b,d3ba6d4c,8d7f142c,ef1a51da,61ca644f,acba35e1,51ebc114,c5435bbf) +,S(d9484146,92852eef,fa8178b4,a01404a,e4e3d846,c20c3fcb,cff5cff9,de551a93,d5b0fd7f,e628c427,434a1219,6ad99862,13ea0abd,969864cc,dbb8258b,96a6d5a4) +,S(5cf81fdc,3a2f2087,cb64b1c,9b6f4754,5ccc1e78,67cee5eb,9fe9c4ea,3b0de2ff,e0b0ab1c,f6bb8e5d,f7ddc700,5ec73471,e7ff3125,daf113,1b78fb8c,15bc0d7d) +,S(41b4ef7e,b719fdb5,704b3f17,4132c694,f8ed2471,1677a320,3b866660,dbe879a7,a6fe65b1,cbae2235,cda8b459,eeac19a4,9f44c2aa,1c8a881a,e12093b8,3621c85f) +,S(43ed572c,41f691e2,a8dd1691,86404ec8,7a4c0a3f,406f3bdc,5c2709a9,bb117af7,b7b9e1b8,90b40334,6bacbbab,7be4d477,90a2b093,dafbac3,fd4d2073,fa481da3) +,S(4e010a19,223086a6,314bb526,2f1955e,81722b41,e85fae42,1c338e46,1b397de3,f0d3f11c,3475ed8,44876e7b,3bd0bb8c,283b44e3,70c46ec4,a6159a27,eba65fa2) +,S(b3609cbb,7fc86bcc,4dbc385e,81edcd84,45e15d2a,7d355e22,41dd442f,ee11f36b,8607e5ac,a3df34ff,804017dc,977bba88,c308911a,aa1698e2,e6190c8,dc9c5f68) +,S(445e60b2,543fbd3,7bd68cdf,6db1125e,d1bdd6b6,b27249d1,df96e43e,df965b4e,a5fa458a,8c4ab47a,bebfdc7c,f922e713,c65f8b52,287a65b0,b5dcf0b,c7715fd1) +,S(709f8227,9264c99f,86b59a7b,ef14c189,be875b49,e00cb64c,f9dbb643,10f50fc9,168027f0,cd28d2be,8a69064b,468e4de5,3d4903ff,faaaf628,83f15031,58960d10) +,S(62aa200d,cbd1240b,a252e725,a333f21c,8a2e9d5e,fbf18cdb,e1567ff9,29fb4ba3,19aafd6c,7017bdbc,4b906b46,843e41ac,1ec3282b,12dee1b7,b18e3f28,9e0a1347) +,S(2ba73958,8ed54646,fa9f2389,802e2ab9,e123987f,c881ae11,f38f10ac,b882c09e,f37daa1c,9c0a98ae,f86cc45d,34801353,d8f8a193,77518423,721f3e12,375a25a6) +,S(8672b9cc,e8fbb69a,ae5c0f54,9b59dfe1,e266e9e0,3592a397,7314e6f,79005de8,20d8476a,efb61c79,adcaac68,fbf9eae,c411e875,a66b5aa3,99a97a86,9b05af65) +,S(334cb002,84202999,79fdbac1,5ee5c17,1f32bee6,133300ed,a26571e8,bdab6ab5,8827d99f,3da7878f,46b45bfd,579c5cb8,e4e972b6,49d6438d,96e5a188,5aa574d4) +,S(32b30e07,d260ec07,354cad6a,2f64f81c,e9f25f4e,47bf1afe,602f229a,35ac6d4d,71ffcf0d,64ee9078,6f290418,1126c44e,5c5e3688,f3063941,85660874,3c3c0427) +,S(e5099658,7a4b4e63,43e401ff,299e9bfb,3b5ce402,5c38fa05,761e600,a39a8451,7b0382a8,65429a86,94eacccf,5c6b3380,683a3916,70fc7241,f132c465,b3bb2ece) +,S(b3872c4c,2bf539bc,e0aea035,3b3d786d,ca684121,29db66ab,d316e930,e5d6477d,7ce04af,e4c8c86f,3b37ed1f,a9dd4161,59391c71,22d0f4f9,2424d090,901e285) +,S(d2b56fdf,9156e3ab,2e414d96,49f4c418,6095e74,a2df8908,f3b406de,9935d07b,443c2c1b,67668c56,a84b4925,946a8e5f,b06a33af,371552aa,adc3b500,efe3b23f) +,S(f69867e,1074c765,923f32e1,ec9f41b3,4e8288fd,62b0a081,15db15a9,f37fbacb,fd6c6e25,2a11a516,9ce04c6e,d719c22b,68709be7,6fdd0e58,cd0505c6,413fca16) +,S(bc1830b4,a9ab11c1,ad8778c8,688fccec,cae23898,555b6579,62670d8a,b9e64988,b6244089,f3c46133,1979a0fa,f3d0c8f2,8e95cdcb,12db9ea5,b6d95ac4,c22e3c81) +,S(fabaae21,dc729fda,98c4bbe8,3cd5fb92,126cfa1e,a21f43b7,445e4b47,f38dbafc,1b569775,64465832,c73513b3,ed6aed9f,177ce1ba,b2c09fbc,c4c33600,582d8cdc) +,S(93386101,4d5d4c3d,f912497e,a248d8e3,bcd3fc03,216dd57b,5473d96d,791f8bd4,3d8fc96a,c141163c,4ff3add5,44a6ad71,9e57f22b,8e806d95,1d630fa3,6c936725) +,S(c5312d5f,85c42820,59546b8e,ec6b186e,da0a4324,d30147f2,94a83fe,a6fd07f8,f8ae6e2a,79ba0756,523be12c,8d544734,332898e8,b35b651b,edaf806c,45d2992f) +,S(a08f2496,52c52f40,6db75c4d,da022f41,b73b1128,11aa7388,558480b5,f203b057,a396c7de,9ab5e1d9,5e9aa925,1ecfe3ca,191d7a25,37c4cccc,845dc745,2f3eb2e5) +,S(93d5330f,e8df6fa6,a74b34f,a251a6,a036e0b5,89b8a05b,c525e4bd,40f634df,ca15faea,10f424e5,5d6774f7,7c87da28,c4df567,7d153a08,f5ac560b,71838756) +,S(4622bcc,dfcab72b,e850a994,1f652110,5c35b813,f05a4f6,17055f92,aab51fa2,d960702d,31eeb256,d25cd245,695b53c8,e883d2a4,60965a8c,d29b41e9,d7ca2d4f) +,S(a326036c,7dd885d9,94ba5872,8138c30d,fb6c83e,d17c8d88,7aee086,e0ef9fe5,b465ce69,3719a155,31caafcd,e7689a17,456a6ce1,c75e5a53,4893cd67,32cb9bf7) +,S(2354417e,19637e79,71b0c887,bfa5c553,f3d5e7a9,84a6c946,b1d20b5a,7eef77a5,815a9721,b6ead3cb,b254fbf9,9f34f409,ea740053,3cf4ed4d,2169f48b,29f4bd4b) +,S(9d346d6d,fc53174f,5cda746b,23810d7,3a407819,ddd5df9f,2b07cc8b,b7ce6fca,9b6cc06b,64293e5c,a55a8ff9,f1e90551,4a199b03,df08e9b9,8512b357,9776c806) +,S(73c82b8e,c643a7b7,f95f000a,debe210f,bba638b4,5508564,bb5a3330,fd48dd01,fff15699,a0885c61,fe35f61b,84cb2bda,7d2acf5c,df0d6f07,5fff1369,805b614) +,S(902469d5,a0b2d5d1,cf931672,88506b95,f2d29bf,6ca291af,c9b39cbf,fc798ac8,356d011,d71c769d,342378bf,fcafe4ff,cd78addb,abe8b0d4,fa63de89,1fc3ade4) +,S(e670a0fb,3a0c86f0,53523afb,819b8944,dc4013e9,fd500371,b1efe23e,1f110637,869136b,cd13dcb2,157db5a3,d07e59ef,272557e0,9dcb250a,9bf659df,260b31b8) +,S(f3fef06d,526581e6,b0f68e27,cfb9cc9,b57f11e5,849545fc,b9ad3d5b,8a05c395,32b2e997,144420ec,c4c45176,efa5fbbd,570752d1,4b092f4,ff375544,19b8f553) +,S(72a37663,3958d844,560fc28a,8cc19d88,f942c09c,471d2cac,70ca5d39,396a05bd,de9b1b0e,6e121070,f684b3b8,402e8d8d,729ce846,d2f7ba8,503f4548,735ee1ad) +,S(38b78ad9,c43b7def,4119c3a8,190cde68,4172894f,a84cdae2,2b637bd8,805300b0,a181567,6c4f5f51,87204f17,5bff32e9,de7cc69,dc851c84,23de74a8,b3d01e6f) +,S(db968ac8,1d2e7c53,6c66fac9,e194fb23,540e2e89,8cbd3af,68e158ff,2b34752e,4d5c57ab,79d9972b,ac6b4af0,a6347271,4179e8e,fd14c769,a24e5a73,aab48a0a) +,S(2ace1679,2d3a4d83,71114f28,c1ed35b2,505dd4f9,97c72435,a145d367,a8aad318,5314312a,246874e4,cec63b87,f685f6d1,405b0ef,a1ae3539,cc88e73f,3626f625) +,S(32d80e69,c390ded,db8a4600,862727c4,bb1fda18,2563277e,852f93af,3dbae108,3c7d96f,ea89d06a,6d3cb3f8,181f7cdb,bc1c3e12,3d9f1d08,cbd557a9,60dc7c07) +,S(3ef49e8a,e7fe6b40,628e61a2,945db3cb,f1bf050d,e525d521,d8e8a408,76ee3908,4381c75c,62f45fb2,4d431b54,d63115af,3ff72d27,58c3c92b,d3d1de08,1a123f2) +,S(853808d5,cdb82cd0,39b517d4,1c88d7b0,e280ee6,59e5c640,5aa27542,3c9722da,c1677c44,9b2a9626,698a652f,81722242,3ed18d03,92d4200f,b4dc229f,5f7e8f5e) +,S(572fd483,490c05fe,857520bd,8861fccb,306ee4f3,29adef49,58c1db78,1fc8584f,82acc906,10392302,cf0107c0,6b3b6194,d38e9155,b31ebca0,be300036,3413f4a5) +,S(b1cbabb2,9aa8ca31,75aa9a2d,d4d956e4,fa771344,d4592481,38c93583,376e1386,888cc0f1,7f9afdf0,6ba1de03,41409c1,265cb2f6,c015fc,bc58d2dd,66292ec9) +,S(f856cb92,42393134,7580a65a,149a6e81,2c5c960d,670701a1,6ddbbb98,2f6bab20,c33511ba,192c00e9,991f580f,65c111df,77d9d6c2,d5d63869,c5595011,48536674) +,S(e1601cd4,773e129e,2c042887,b56bbb3b,9eed92fb,6c128e23,fffc3a7,ee73920e,180748c8,a38c7796,ee247c71,49ba1fcc,a78648c,a0508ec9,6f4a016f,301054ca) +,S(98ee20d4,5ffb6177,5ca206a5,b0cbf1d8,e8b37cab,97489534,a98928e3,367c7e72,2df4ace1,ea42db51,68ab5e6e,88fc405d,854b70e0,4521bc30,6978e465,6273c610) +,S(4796ca57,acde905a,31dcfe95,bedd1e13,5417bc41,f5acc246,ec0ad4ee,ddfe179f,7413f522,395a3802,b37637e5,9564c239,5bc565a3,463f815f,8ff962a1,f0a367a8) +,S(b367c864,38adb0b8,d5b627fd,56c7df9f,cfd55536,9abbdd40,6c68bdd,1a341200,c0364744,b99e816,7982f365,72268702,b4986cf5,c9c5749d,fd22499e,2e8fba51) +,S(db36884b,723ddecf,7e2244c0,20de844,e740760a,4f27d386,a747f4a7,88914d29,8ae487cc,2a743a3c,2a1e0750,7def0f2b,fef90e24,fda0e3b4,e5f3333,7d79e023) +,S(65971818,f71c212b,a8e45821,31eef4f9,76b4732e,6c6c3123,ccf5c6a0,99a316c4,415f6791,353350d3,3b087f39,13761119,526a2831,c70375db,4cd07754,e13604db) +,S(f2f4eb3a,13a8f4b2,42182a63,97eb6cd9,9053903f,961a1338,fcbccac7,60ebd65a,a575d67b,667e94d7,20adc8b7,4eab8ebc,18811b3f,3a3bcb6e,7950cafe,8ef9ca8) +,S(a24e7a0d,a058f0c6,3328fa51,fd3c927f,884b3f77,cc068a47,e8c6b4d3,1d113a49,be8db830,79aca569,9eb2fe3f,829719d5,bcee615,645e4c81,a9a7212f,450ef78b) +,S(e59a3ccb,77e11797,7db6cc32,5ebd5981,42212da7,48f0a4b8,981db72,41efad5a,a8e07545,fdda2668,cc0a10a2,2389a2d8,d6903416,a4a05299,9d4c2d4e,4a800d9) +,S(3191b263,a3c70be5,bec721f9,3dabe9c9,fc6c1a75,aaa94e9f,daf6060,fe4b8f32,339192cc,1c7a9bc7,2a9a87c4,ea3cbab0,c7af7b27,53e74491,717b1f99,5df38a96) +,S(63dd5fc6,4f9ddb0,8fd47e27,5e839b20,12f408e5,3c139463,8b97874f,9187023a,1af048b4,2e8b7e6,d456cccf,d12ef7ef,67e0910,4162239b,84f35cbc,8504bd9a) +,S(a92e457,cd8312ec,cb87229b,7f751c4b,2e1d8640,c2b8e5c1,2d3dbf4b,671bcf13,d7aedb56,5447eb5d,18449241,3a07d672,be46ab4f,3d5b4b3f,551f292e,5ffba768) +,S(1ee6b970,b9e09d22,2b20f02,14f00bb4,4789f55e,585f35ba,6c0dd6f8,39b10495,7c910fec,eff9eef5,d1a3c8a0,46252885,9dcf73bb,d4a0b2be,3f8d10e0,dc9e9462) +,S(b19c23b9,c2ac1957,5328d7c,43d04870,1abe9e97,30285ceb,e4fd1659,8f06a76a,79a811be,c07c8b70,6f380f8c,fe369e45,c605607c,d08c8a49,2745b283,37a38398) +,S(3c20db9f,9ed35fc2,7c0888f5,e266a455,4f3fbf98,b8b2a016,b1e9aef3,14f49a5,bb3ac294,3f29e63a,f610815a,4a1e5a12,9327c1b5,ccf489ea,7d8950e3,5bfbc4d5) +,S(fd1ccdba,b4746e9e,44eb5904,d338244,efa29ffc,8ce8014,f6b922c5,2eea4389,e1065546,52146f90,fa52439f,c43ce4eb,73961a52,10f6c040,97a82032,9a8df06e) +,S(e30fd18e,abdeb8a6,ef252dc7,3c2b0d75,83641a29,8db37ab5,1e2da099,9b64020c,49663672,1824f481,962bcab8,6716eb41,8e195d29,6afe9704,cfbc24c1,28dce88b) +,S(4bc1f789,26ddf930,e1aea784,83a9dc09,5cd72300,5540548,e6e217e7,515bda37,966b32b6,95dc1b00,8dcbfa2e,734bd9ab,36d8a26c,2a52c471,63a4cfcd,d200ca69) +,S(23d3e27b,9c864b8b,40f0f7d2,6ece9bc4,9004f98e,d46b539a,affffea1,54f036d4,be4617eb,f680a27c,cc4143d6,ac150d51,b3dfefbb,2892a6c7,1b36c794,8ac0b05d) +,S(28adcbd0,14cd3b70,f46e0a89,477b5cc0,4a513091,cb6c1aab,56de4894,3e6009c0,7c49a838,75204cca,38f250b4,608cfe4c,25040dc7,3ded4fda,f4a92cce,fce31601) +,S(776084b8,a86f0823,a5044ab8,70d84f60,ea52ec7b,a545ea0c,c86f219f,1ca29d08,60bbbecb,1048d250,b410bc38,49e567db,def17272,58570b2c,d0834532,581c60db) +,S(45df2e0f,fd32ef48,95d9667b,c6044951,e3db94b9,ed6af5fb,d4fe1e7d,228f2350,a732464b,1a8cfe06,69e4076e,d4164b98,4de155cb,68bb3994,73fd7918,63eaf095) +,S(6904976b,46a5fd1f,a74bff80,c493a2fc,8ae9bbe8,783cfebe,7f69f0e1,be7dd7ea,19d071b8,df9d1436,6241a22,1a00b340,30f1df45,5e66fcfd,5ad621ae,ca2c3e64) +,S(849d8728,f977d075,a8de805c,8e80980f,e01def35,1ee80f0b,ef528e85,29aef659,d84955c4,6c886283,b9d7adad,bc069d0d,8042dd9a,ec7246ff,edf31594,ae5bf428) +,S(e3d64b4c,234506e6,e7facec,8d7534ac,54588dc7,ea685281,e27c6746,472d58eb,4a32ad3c,cf822a84,74447baf,68aea598,11a9c839,4c9970ef,bc61f363,ae5a36eb) +,S(f41c7928,57d15a31,19b6f132,3b67639a,889877aa,e9213ece,c787d53,5463bbaa,73cfcd0e,c84c55,4d007594,152d9ddc,630c458e,7ea456d0,7cc60503,794d9328) +,S(e1d21747,47ab84c,e47a4a02,caed939f,e0cba1c,41e7b21d,67f52fd7,79186079,17b0b628,aa4bc0a3,ed9728a3,e24a8101,fb26da66,9ac92f63,af81aafe,7db2b668) +,S(a8a0018a,f8f86795,3189da2d,d52b4db0,5d7ddb4b,8d290c80,95a8e7dc,d86ef1d8,8bb9606c,84b88a1e,df980c7e,9360823e,25b927d7,9cab4c17,fc8aba7d,6826518b) +,S(7383c671,6ee05e44,daba57c0,50ebda60,e4e0c0e1,3df338f4,cd8d627f,736fffed,3bdcb946,5f164a74,638cb973,fc77daaf,38eafd48,9521cba0,4ad896c,8e89f0e0) +,S(61fa7e1c,8bc8ac97,96be6431,20858063,1ca36af4,520cc1e,858f90b,ad372dfd,3f0d6768,36c3e694,32287909,c8841de0,a5f646b0,94b0c207,8d634486,c3eba33d) +,S(86029e2b,ca0ac601,99092def,cf4882a8,b4f14349,43bf116d,3cb310a3,b2c4a740,b8be906e,cd9056f0,f3261cff,d12216c8,ef5f1553,dd708480,15463b7d,241c2f7c) +,S(e172f7e5,912aa487,589d6c4c,d0d6b9ab,48c4a6b0,5fc5f90e,2f6474c0,4fad95cc,edbd23c1,2b0a0ed3,b899920c,e8b64d7d,d7bfd79,5009c290,ea0673dc,8acc401) +,S(7986ba8d,322efc24,8b7b22ab,f838de93,2d931c78,cd6a8616,d1f37dbe,32873494,693eab22,4c750592,319b7544,d29fe0c,2420a5d3,d3b7e01e,e6ebc968,12a13634) +,S(ba594138,4a727673,7600a6d8,8d36b133,400bb5d3,6a8a9d46,3e8c65c,e1e00383,746f4e28,bc1b812b,227fc953,531058bf,d9c68545,2f6219bd,86799dbf,3c2ce557) +,S(45ff41c9,92d6b117,c86eeb77,bb17789f,6bf96cd7,2cf0c6b9,802af869,20476c8f,9324f5bf,6422e3ae,2010c9e1,27167d8,4f522e86,87fc95cb,ec3d6972,2002b59f) +,S(bad79e35,487a4da0,7171c282,e8666ed4,d00bada4,d9576a7d,9a93ecc3,c16ed68f,19397a2e,efb184a4,31a02e12,91db0cd4,5b153517,9038a920,7a6d50dc,787b57d2) +,S(ddfe2107,2d8875ec,60c4d583,59755bfc,22cf890d,d3665b79,cfa403bc,9e3c8a41,c62bd917,491d0a8a,9215674c,28c28872,8dbe0d3f,87c10d90,ce22b608,473f62e7) +,S(925f6a53,c07f923f,968ccadf,bef9d95c,d7594269,a3d9fa64,b1180edb,667eb299,1080e8ff,1f918e6,6f08b26b,7f9cee48,58f00038,b8ca50b7,b2939960,b1e7809c) +,S(c28e49dd,a75f0283,38e5d2c7,d1f03af0,12768bd0,6b0e0d0d,87878ba8,2720dd80,670f8989,c941a49b,cc512c5b,4987e167,ec5ae6b4,d7f68a98,331845ab,5d0db12b) +,S(7a9053e,95035be8,8188c196,d5e8e05a,b21dae48,d59406f3,7b9f86ca,2c837cbb,40ee088e,8e7694b7,994774e7,9d097d76,6de026f6,f7fbe352,e7f2bd0f,443a7e1c) +,S(33af78ea,bfbb00c5,4d88ef81,e9661b16,e0b32c85,a1b61b95,6c6a79fd,e036aa2,713e7aaf,537a796,c4d79644,c855d0b,15331988,5ef4629,d8048c69,d3cfd3c0) +,S(c588d014,5a3f3d33,29695573,96d674c3,1326dfa4,797d63d,f9a0c720,49583bd0,b5c0cfd1,6c67cdad,ababaa8f,cfd2cd76,7f747024,8caf60d7,37531c66,ac53cdfa) +,S(96b3d5ed,b93742c6,7c48ef12,c649341b,97223f22,1f0edd5a,2f2ab523,8038d29e,db475caa,38a3a05d,3719a2e6,4ce7b4ed,bf25fe57,4b28d6aa,9961ec0c,b0e44c4e) +,S(412f4b6e,3d894ee6,fb0cb00b,14662a9c,1eea3a42,5a286782,a62da77f,5644f0c7,a84ef636,ab9bc805,bffde813,93874429,a8503e89,8c03f1d6,f139af86,f6a676fe) +,S(25f0a785,c7b43028,52f1421d,a32c418d,32fdfdc4,89c39049,3794e1fa,e4563252,efeb090d,457190b5,89c953a3,aebef406,da716af5,1dc6e334,a0226883,6004e4bc) +,S(50fd4ab7,f367faf4,acb4403a,49ea3e7f,f02fed58,4327acfd,e0bd58a4,ed741c6f,78abc1a7,3c9dcd48,6520cb52,adb1c3a,2d08abcf,a079607e,a56307c6,3d46dd5f) +,S(157583d4,cfaf7f79,33b8fa66,430f107e,c357621f,4b94f313,bbcfbed1,46a477a,9aa6b235,ce8cd1fe,60cd4355,c46d4859,fe35ed8d,659d2aaf,fc09cdea,297e8db5) +,S(3c44bb62,5d262603,e44affc1,65b35976,f2edcedf,8be6b494,f4b3bc4a,5b3300be,88b1c561,67973ab8,5ecd4594,90598152,1ef0e8c7,1ff707b9,79ec2bf,3cbc2535) +,S(31d4264d,e1606b97,f2f71d19,33f23cc4,8fc5d9c6,e087dd93,5ee25b8f,ba298958,460609c0,a3aa1d26,2865180c,98555b98,c8e41db6,2e62b2c4,4ae01190,718251cb) +,S(1f551f0a,8ff14724,60ab206d,3dc1834b,352d1d1d,80a8fb78,a87247ae,5d03ad2f,24253c06,a4c8b148,db944f81,802bee34,fcb97ab6,50957b32,eccea33e,c116a6e3) +,S(de2c4e1d,27f08407,31334311,9ff5a8c4,206a1f73,2aaec3a8,7aab6bb5,c1cf333e,dc813ba1,40fecd3a,31ff4a8e,41fa498d,9226ca2a,cb2d5a71,c5a5cfe2,8195170d) +,S(6fdc5db2,adf54ac8,132c4a22,c382c2f0,c1f54bd1,8aed5620,a54bc4c1,18a95612,db3fa4e5,f318e94d,c0c11053,61d21643,cf60b0ca,a6dc4d26,944e8915,970e221e) +,S(c7eb76c6,ea0e1c51,a3aea6f4,dd7eba10,bb76650d,85df0fc,7fd77b73,53680603,5ae1c1d7,b788092a,3c41c3d,7bc32ef2,a4f4a39,a82b53e0,e6f47712,df5bf655) +,S(c81505a2,b7e78b5b,64ce048e,6312bfba,1a52c7b7,8219d857,b4813a98,c8aa89ed,46db2842,6d6ce211,5e1e49be,459f033d,c222be7f,96b247fa,87d5dfc0,df096806) +,S(cad75255,15f9c3d5,8705ff0d,83ac3508,f7dec312,bdc71c9,a17eb9e,78503bf8,32b36a02,76cfdb97,ecd2ddc7,638e4d61,6231be5,25b6b4c5,2d19c12c,6e6bd719) +,S(94d22144,e22b7e30,56eca8a4,7d6b15d8,f17f3c65,82533fab,c70e900d,be4cdd25,12c0760d,5fef2f85,d89dfbbd,bd0124cb,828bf72d,79b4ae5f,6121a84d,47d93bf9) +,S(325c5c23,ef00601f,ddf52040,7721bde2,13cba19f,c0f2e225,3b112b8b,916731a3,59d3cb98,c09c1643,993f3dd3,64c7d29,5cb38cb2,45d8f70e,9628e5ee,d62498e0) +,S(9c907089,544b8316,4a251516,81bdfda6,7d187438,3e7f4a7c,da96d861,91ee2318,f639dee7,e7010630,364539eb,5c225059,547117de,9fbe4911,d9718e6f,8372d20d) +,S(34f14807,ede9c06c,4cb2a1d8,97a4fb81,ec5544dc,eac1bfc0,f32f9835,302b7a82,78437a8c,ec6aa228,f5f18813,a68bde68,3c54c367,5d6be482,8d01f2a4,96d9c57) +,S(9498d30b,3f080828,e03d459a,fcb81fdd,490b47ff,c344d75,3887b600,1639788b,7a5c8305,b97abe3e,b241627d,c5187a9c,677865b3,567cfd2e,ce136852,e42522f7) +,S(eba08f6f,efd36e37,aa53ec32,d3cef88e,5d4f36ff,ebb978c8,76d452f5,7754f226,fe0e66b5,43aa54ca,7afeade9,b38cbe0b,39e17178,4d029470,608c7e38,bd2015c1) +,S(555d4bc2,bd21729,f6119b77,ae8c9bce,c8ef49bd,992cde50,4c794484,7240091b,cccebdb8,69521e33,2ca86941,593eb4a7,6c9052ff,a54f8315,d30119cc,7f437b54) +,S(33729b9c,19da3474,42f33833,d1723d45,3f3060ec,c692d823,679f087b,ffe8872,a94b6a4f,283af604,eb885405,6bfb8044,fac2f007,d7ebc800,b4abd64c,5c34fc30) +,S(2a1a889f,afe64678,647b060a,73ab92cf,78124ee0,d44c7c32,d8ae15e0,df1dc11,626f963d,3bf11f8e,686ba46b,e6dbbf0e,75aba0d0,7ef91218,98605ff3,fc8b75d8) +,S(4702854c,a303e6fc,ffc62f70,258bb2f5,639148b3,4e3927ff,f2dbcb0b,7c197d6f,7da261b2,8513257c,d1475c2d,e059372e,2da76eb3,f3b2c51,95c44447,d71e1156) +,S(7002edc5,a0cc23a0,65015cae,6e49e7b,51d90cfd,7da04e03,4857c596,cd319c5b,6f2845bd,6b7aa58,7ad2d2ae,19fd6115,78c47b56,84fc6975,db63e230,c3db73bb) +,S(273294d4,483d610d,b2169f05,71d5450f,f4cc5bc8,725d8ae6,7c1adf0b,6f48d485,99b241a2,ffec9e0,a039a003,18239aa2,a71e3cc1,1cfbb6d3,7268874b,67d942b1) +,S(1beccf82,3055b440,fad26a53,5a852a5d,710c72a,c4d28e83,b0335e8f,e98c9a69,f3ab566,ac0eee20,7c8ce0a4,d471eac,2c5db716,5e24b489,e2fde03f,7b8aecfc) +,S(dbe4eecf,4f033d53,5d949cae,c8fe672c,a1902323,77892197,fae8e192,53128160,b3f50bc7,927f0e5b,56241c72,24960fc5,896fc806,1c0a8a1f,5fd3d47c,d5aa566f) +,S(6643fc75,bed80c69,4591887a,5dc573ff,caf7f484,b0ae2631,133ecf4a,39bd1e20,4701285,f7ac7c93,bac1875f,dc4a26e3,8ec1e69c,293c3b7a,1f8b5c5f,878d58e5) +,S(99f90bde,cf1dcd5e,7158280,53f820e7,ef19d936,bca63f14,516342fe,5422a21,a04dfd30,6dfc615b,5390a86,8bebead6,5cfd7719,33f91e2a,180d2d79,b99cd4fd) +,S(54e7ce48,3184b7fe,45fb4e35,192b5678,bcf71f7e,49c033e,aad1dd32,86e33433,cac2833b,65ba9cb7,83a8b85c,b7f4e4e2,4d4f8546,3c6a2c3c,4decec88,14c0e8ef) +,S(cf864a4f,fb60993e,444f4e7b,8f4a9973,4705aa16,295627d3,1f7686b8,4bf02e08,7a98d20f,b736eb4d,465db874,ce98bdf1,6b8a1951,7744aa51,af276c7c,db6f1bde) +,S(6ff160d6,516fff91,5ae2cd45,7a98afe2,a2569345,60a7f26,c9e07212,6d59d1ae,5d1f1355,bf1410ac,e4f8b415,350f9c75,7db5d5ed,1f34de,aff5c197,b4eedc4a) +,S(9adba62,aefd2690,1d77f2a2,c6287da9,a56fe35b,3702da46,f231fe4c,9f5dfcc9,ba58ec45,cb4a359b,7126af,fd2c4bdd,2e708d43,41d96e7e,4825f153,abb04161) +,S(204ea41e,bbdcdc48,cd4ea945,72c10dfe,b5d90060,e9dcf5d6,52c0e2aa,14a2402d,7b2889ac,a1952f3c,b2c5db8a,9924a6fa,fb0b9e32,3ec09809,789f780b,ac36ae38) +,S(f7d6c669,364d3114,225a6826,c20d26ba,a4b4f190,e842696a,82aace97,5fc8ba22,15abb177,b42538c5,67d160,cb3c761b,1ff47cf4,4b0cbd16,36f67a5c,879d3470) +,S(7bc4d30a,87dd28c7,8b066e00,c02bd221,e50a7e64,45b57f0d,cb466f27,7d352587,f4ed4854,2e7e0164,da66e0c9,fcb04a1e,6efbc9c1,206b552e,c68cab96,d0c294d4) +,S(55442584,b046bee6,c245dfb9,59f20629,c200eb21,b42509d7,8564943b,1e316ef1,2e2aa971,c8111ed9,6666353a,103f2e4e,a29c4162,d19da280,905031a9,48580d82) +,S(8e7df8c0,de88903e,71224c97,3a8ca65a,923f872,841f2dcc,bcd69e64,b1dce1eb,e4153083,9ae86d51,e7147873,f1fba8db,c31205e2,34c94662,52ae43c1,25d2a0cc) +,S(672321dc,69d8aa18,25569d06,65fae079,b84a9bc9,35bda491,5d546f51,c651de8f,8ad6430b,8708897d,be809ab1,803a6eee,f977b1f1,6b34c188,d333d6f6,e7ef005f) +,S(f4e2bbc1,43e99b00,52032718,285d7698,1b8beb9a,f693dbfc,2d20f472,89ac3abc,e54990f5,dc330eab,2e722b7f,70cd426f,6d80e93e,205eba89,7eabf0b1,5d651a2a) +,S(5aa3aa5f,c6d2258c,907c7275,805c160a,72694f46,6b5fdad8,9134f1,d39ffff,22d72170,617eafa5,b843e82b,5f670cc2,3146aa98,cb07644a,7f4c0600,48ea9531) +,S(34752ff9,d2bf499a,c6b3acbd,1b78633c,9e9a31ea,45c34383,be3eb008,7be2e7ef,b53ea374,2cf3d886,51f7d076,3f67c8bb,39d73ca9,8306bedd,91a6db47,2c1104f8) +,S(d6502624,2ea44f7,d9b4c9b,5069e1c5,88977062,db2bad6b,51735366,27047327,52f5c99a,f2f2a8be,c034db3f,b573757e,d8014321,86db2c28,8c7151fc,4ab16f2d) +,S(52b3aec6,553d025f,d164a0e0,b1f39abd,915d4a9,ed5db2ac,b4593c30,11f4cc9,51547402,1c17b2bb,9d401683,931b25d7,77af18bc,e0e7bba2,432a7717,f4e2f8c9) +,S(8cbb677e,f7979224,12728418,68b79c12,eaa0ec6e,ba4f9b17,4d99547e,827ef9ca,a32809b8,b07e1312,b6a40ec6,411b60be,92974f98,bfedce19,ae590f98,40183f2) +,S(d8f55de0,e2eef17d,e94b1564,d74734b9,3f89f2d6,c317a248,7f1724e3,d531d47b,e9fd46f5,da576370,e0416f71,f271e64c,fa7dc64c,5e086930,523e92c,9ab7d770) +,S(fa6fc9bb,faa2b31f,f9d57301,4777169f,a4ddb8ed,ed4bab79,d0f4cf62,356b6fdb,b6ff57cd,dfdd790c,7aefd1e4,d4b111d8,43a2adcf,9f781b33,1b4420e0,f57d494) +,S(239f028c,e748edd9,69f752d9,abad0498,f9359017,653e6ae6,bb93f09d,61b58e9a,17dffeb7,8831f6ba,7ba463b7,bb7b142d,d55c8aa2,91bdaf7c,644e8ec,14f8b516) +,S(2ef6cbfb,728d976f,99c71db0,5389bba4,ecad3c14,8f2597bd,99af8f74,965e4f3b,19a27ba7,a382078c,3f1ebe8c,1d93a37b,deeef542,cf174273,b411b60f,79b0fd00) +,S(972d732b,9af8315e,88f042f1,3377871e,1a429247,d8537436,98b975d9,33064a0e,308153ba,ba4c3b87,40a380fe,e4bcbba2,a5c2ae3f,25fde1d4,f40af4db,aa4fd28b) +,S(3d378b34,ba4998f1,833aa295,185414be,e788bced,af422ed3,3c4f2747,6e062a4c,46a4559c,9217f919,80887b50,29f75c01,3c3d5238,d3758170,93eda1a8,f2c4c8a3) +,S(fbb2003b,1fc1b3aa,fd32b289,abe3b362,b13d70f2,7d6451e3,76bf882d,395c3087,97c866a5,c462362a,4ceb96bb,9c17db03,f28e5b1d,4e418a81,653a315c,4dfdabd) +,S(28fa94e,8eeab1fa,bd27a9,258e26c4,295efdb7,afb5a47e,6e14de8f,877a0471,f7619d0a,f2eee8f3,c0c7b5e2,8ce9d0f,62221919,4d1762a5,5145a909,9d23276) +,S(4708a285,7eb9c115,71627ede,6fa8fe29,4be27233,8798f25,c12cca0e,f9308ae9,f35f9964,2e773990,b2e0ab60,1a92cf56,85403466,87a8c35,50e36b91,ca4fa449) +,S(93408097,6ff4b874,d88903dc,b3ceed6e,a82427cb,36b62c6a,6364f2f8,9848a62f,e25a6962,d4e26764,9ab2d4fe,a0babf7,daf64d48,98bc60ae,ff3cfb63,e95f3c6f) +,S(f4a42ba0,818201ca,e3195da9,3a566623,9e0d24dd,256cbcac,3959dbc,720ddf9a,8fd26fcc,be3eff0,75d194af,e7391285,10bd4c8e,7230f96a,60fd27e0,a000f86) +,S(c5ada616,e65bcd40,cf39ef6,197e0a97,791cacef,b41b0991,9c51b166,e3a6240c,e4c65d68,fe41c62d,c85b0b32,39106ae9,cc26787a,60d351a0,4a7008a7,f96eb8c3) +,S(7c193ec3,d3f1d91b,cbd7c62e,5061a5a5,e8b1fa48,561102ba,ca2ae100,80c640e7,cc7cf895,511408f3,e400ff31,8a53685,3b8e068,1d4b333a,26b59cad,97873ccd) +,S(77542543,8e7cf128,32165629,3e6a1c19,22b76355,1ec716f1,d96002b0,ad1bd3c3,3747169d,212c37be,1906eec2,8860af9,edf7d932,c187c4,debbf800,8bd2137f) +,S(92dd5399,fa75e786,fa5c0f7f,90abd1a8,bb48ff43,e54dac5a,3b9990f6,27d90992,5cb1be8e,f93783e0,c2e5c824,ac6c5348,ee493231,9932e9a4,6e54921,3f11b7ba) +,S(c1770828,468eeb90,10b55053,2a532fe0,4f66e7a7,b7a1cb37,6eb6ddef,d693157d,da5643d,a0147d47,fd29e262,f61ae4a2,70e5e9a,77a76bc2,d2e7d24a,819a2e11) +,S(1372e116,e90ae522,4649a534,111392fd,a8baabe5,be8a8ad5,33cfddcc,af6378c8,5efbd4a2,695775bb,dc38c2aa,f8da6f45,1d0a1cf3,2bc584d6,e9b2b6e5,c8346af9) +,S(2bbdf21e,9fa1a2b2,bcd52009,7f30929d,5e2b7fa,e1038c00,8f32d86a,65dda936,51b78998,6008bddc,616c0dcd,2a883361,1806ebcc,5843b64c,b0ba02c9,339d45ec) +,S(36694ca4,d0495ed7,78230d49,e6f21217,9b63cc7c,26ee3f7f,6a7438bd,753005e1,2e49e3f3,bbdcb133,3ff1e17d,b18d5267,a87f48b6,95b5f907,5f5aa0d1,70bc0af8) +,S(243d84b1,dc9ce143,a6913bf8,d13c4aaf,6fbc1373,6bb8a7e8,5e648958,32013b8,39317ad,b6bec71d,ffe3c2dc,6dec5e10,21a3dd83,2dffeb91,108abd5b,6e7f28bf) +,S(1d888387,5255f3f6,838eab82,1a12a8fe,ba6dfde,f190585d,e039542b,2d91ec92,a9d38be2,e919f815,5d633538,d2f0aef3,9ccabdad,dbd912bc,46c2037f,3324b489) +,S(39a21f75,4c0d3376,f7560e2a,a743751d,5512d628,7a480955,6456f9ac,b1be3765,3cf324a5,2a7fd79e,3bc188c4,d55bb449,ef4950b1,3a4531bd,e0b2ea9d,4035e005) +,S(a10ff60c,d8e25df2,a1d394a9,52c67f6d,18ab0a1f,a56569e9,48d9278e,b42e21c8,b45f2d63,3ce82ef8,1dc0c0bd,4f891473,89fd2b35,f02cb237,bfd4f502,df9e991) +,S(bc269792,d5042f7,1051f7a6,46b971f9,bb801acd,dc24a2b2,5bbc459e,b7bcbcb1,b70445fc,1c032061,61b01530,c9205d7e,c7fab6de,1d83f1f4,78b35bd7,71235665) +,S(3d7279fe,fd5a3682,a82a7f95,d1db4442,5f0ef448,f6bccda9,9a61c240,9037cb95,df5226ca,e6365b7e,22b42cca,2ba2494d,9a2ea193,cd92162,2de6602f,70159740) +,S(e0c56d30,ef92af00,b936c2bd,951b3d51,bc439ad0,e4216e2f,d552c2d5,e8dbe588,c2bd177d,2a75c44,40dbd186,27669a0f,f35189c7,a4873e0f,6484b3b,68555fee) +,S(9bf960e5,2b7bbf52,fd839830,634baf1c,f0d6e332,4272bc15,d9999ae2,7873315b,b28719d,20e01dcc,b0016cb1,6a453739,551862f7,d9cc81c9,6662387,1d8d0405) +,S(20df196b,e60ba71a,e617a6b1,44757e0e,87fffb45,d447d9dc,d5480a0,34351198,9c722d43,c0d071b,a07d4953,9ad0abaa,f12ba358,42fee0ae,9960ce1f,26eb07d8) +,S(843c136,208b40b,9459693d,8154980,455a5f71,23b5f633,a26661d,ca9bac17,d5b5bd8d,9095fc40,d2d1820d,31dba542,d0c74f23,86770ede,c9b4df46,f2f12078) +,S(9109b4df,702c1ea0,dea4ee0c,ab46d6ef,708a3fcb,72f9dc03,e05bc722,408d11a0,75baa2c1,8be5801c,b5315195,4c2c3024,7348e9c7,913bb242,cf4ecc8b,96dc507a) +,S(f10cd1f5,c960a9bb,12adff03,c203c59d,8e51552e,3727edb2,329eef3c,5991113c,a84ac8e1,6f65daa6,16574689,8fee662c,9d2e03c6,4796151b,8f3f0bf1,5e8c465a) +,S(9f07713c,ffd3602f,ad077b69,a8a5f539,ae0d6d0,df58ba07,1eafe6ad,10e747a8,adfcc873,42b59083,cdc3d735,782f8ec1,cbb4ea3a,57970afe,58cd5e5c,8fee867b) +,S(6d1d9d0e,32905734,13b2b870,fff8978c,5ce9ec6c,b120d9f3,64063342,cd95801a,650be4a8,95d3b602,4d745f7c,23bbdce3,25a3f597,922e50ef,ba154f8c,6831018f) +,S(497185a5,6b3acc94,7a27791c,7e1fb149,5c649f99,dc767fa7,12820cc6,6cdcbd82,7d511b7c,11dae1b1,7e4078b2,fe7565a0,f33ce5bf,74181c3d,f5b6a951,fe6568c) +,S(fff738f9,848eeb9c,4ddb8bc7,52cd87c1,9a35f7be,14a470a2,c3154ff3,100a743f,106b8a55,cd913c97,76837cdc,f45c58a0,211b979a,17085df5,7bdff373,2f2c38ec) +,S(320391a4,8d3546cb,4466876a,37d60015,41899ef4,5dfc8e38,ccb9021b,981b4830,46f63030,b4559411,e742f303,25707b4b,23fa2d7d,e633800f,9c71205,6651b102) +,S(be44ce40,a925e88d,26937f7f,b7631f18,55879106,122813f9,adf16e00,5d85fe9e,1755ade7,d22e6dc6,7e6806d4,bf44b6e2,ca6948ca,9a418893,24db0266,2b6e1dc4) +,S(8d3f06b1,58ddd609,f83b0531,466fc2a3,da6aa80b,433a92dd,eeb20435,cf33ddae,2d554a99,efde513b,b8b6e5f4,dbd2e942,f1d0a641,98c3df2c,4c74705d,4b37af63) +,S(f814a79c,f258f553,255c1cb3,a054fcc0,d0c71d74,742b6627,210ea846,91596729,119fc95,be48b4b2,23c80c42,fd1f3d45,271ce8a,edeb82dc,31813f75,a32d867d) +,S(95e8fd46,1c37f1db,5da62bfb,ee2ad305,d77e57fb,ef917ec8,109e6425,e942fb60,ddc28b1e,dfdbcda1,aa5ace31,60b458b9,d3d5b1fe,306b4d09,a030302a,8e2db93) +,S(c06543fc,47e18816,bc720604,cfc20826,6f4e5cc0,f436e149,e2dab0e8,a7981e77,22070465,f3a4a7c2,1134819a,c194cc9d,28185431,17ec634e,e6634831,97021441) +,S(4983d95b,3716aefa,4a14d116,bded84e1,fd5b050,bd6001ca,a2b97086,b4d5c68e,1373426d,a2efcd14,333d47bc,ebd3befc,f5e609a6,6fac1b02,80cdae2c,7f0a279) +,S(a2bd5cc6,92e84b97,3ba2cd09,25e0850f,ad8054ed,e6b73ef6,1fdcc958,3eafe6ab,cca6e78a,f9141b1e,6159011b,99f8024d,33d8d797,9795aa4e,4f0b2767,e6a5ce2b) +,S(61c99231,a18f4e73,95076281,b367d084,b8f85226,3117ab60,bf698d4f,6b6d741a,82314b97,9e7f1d30,64861609,a08c019,af886db0,67d49929,9d340814,6e6cbfe5) +,S(4a5acfef,32c55299,3a7114fc,7913321a,d4072a2f,6c6bcdb7,3ed60bfd,6ab34304,7295a29,c06859b2,69bf9f29,64b26dbf,1323e89,4affa4da,9f61b056,9a0c03c9) +,S(e0467755,866f494c,2b36dcb6,c65ecac6,604e5013,4216ad48,7d4f5b68,bb7f4023,dead03c5,974dfa1b,f532f955,826189ad,ae945975,28ece029,d9e5a42c,30b336b3) +,S(686fdf05,c9265fdf,5b54ca74,b5b1e231,c4e8be60,20844596,40dc0d2b,bb215ea7,f4d43e1c,edf9b974,aef950e,bff3677b,c93723f2,c5901710,b6561e53,d57ea7da) +,S(12476985,f9b20c,ea62b7d7,b0d96d2f,e2bcd924,d1f15cb9,fce5ecbb,8bd21253,d3437cb3,9e904fc6,43a7b356,b4389c0b,3f1950f2,43dd7842,e32de16d,2b522004) +,S(656bdcec,9a87c9b2,e5b32291,9f657b,b5eb1e1e,d2fa724e,45388026,2ad17b1b,c7748d0c,47b6e4f7,f63f704b,3fdc08ff,cdfc830,d17c1d11,6aa3dce2,f92fa64d) +,S(5b7f710e,f721612,ca79b24,483ced12,7a3d403e,60ebc04c,3aebeb96,b483e4b5,1b5157a7,f0688aee,634196e8,de5a9eec,11db4b72,bd96b86b,698f7284,bfb08080) +,S(bfca66d0,552ba6f5,5795bf18,40f90d85,2545213d,81d2cdea,bc8d3d04,a1e6b4da,4910b0cc,290d4257,c04c4638,30cb3a10,223043a0,bddd8690,84b6dd1a,f1754e75) +,S(663fa68f,b79dcbbe,4798f8ef,2057bd14,1447c11b,cec70924,7f566032,88496f16,3ace2efa,1f3bbd23,d885598a,91d1f420,a42597a2,ab30f951,f2b27aa6,83c41786) +,S(27cce333,8a3db8f2,1fef2f86,ede68a25,7c1675ae,80cf004,6085f1de,495c4321,7156bd8c,8babe472,eb144a00,263d4fdf,7aefa69f,da2a9c29,4b16a82b,24d373ae) +,S(d49c06c4,52ec5c09,be27940e,13c575ef,b727be4b,1c0e8ce3,5aa5bc4d,64bd9560,2c653518,b298100a,72a66469,f9a03635,5d7ad789,546df3c2,f5175238,e78d18b0) +,S(6960807e,bd028026,d3cecd25,140d3bd6,3d7bf4fd,10afd129,cfa017f7,544ad08a,a785044f,28befae7,2b7cb546,5bda6bdf,6f9a6383,aa9abf4c,f7baeac0,920e7c7c) +,S(8382bf36,54b63a71,a3b75abe,ba57dbae,fc9263c5,5a54faa1,edeb5325,3df8faa1,e05eb9dc,c319cb53,4461da26,9627661e,dc9bef3d,945766dc,b6d0fcf1,849b011) +,S(803b9379,30ec876e,78c8cca9,fa932f22,b7e7059a,f605379a,cc45a3d1,4ab0bffb,7db2341c,5202d1c2,c6fec7d0,b7869471,cb90d1dd,17cd1152,b52af046,55e5790f) +,S(cb4db129,ab6ae9f,11165ff4,f73fab02,cb78fb0e,89647e08,f998ba11,d2c5292c,ccaef9a,1776384b,b5a80ad6,5bb366fe,745c2408,d754ee9e,f6154188,d7d1c9c2) +,S(fab28757,50e9f672,3838be8a,fc070fc7,8fd6af7b,84c9579a,a8152acd,ecd115a2,d59fe028,89cd562d,5397d3b8,3ae85303,764ee931,d9c6e495,6c311490,c0b3f065) +,S(dd879eba,f870ee3d,f6e3f03,60833e12,fbdf844c,d6a5b76c,19802485,6649bbc1,e7bb04c3,a99a5c11,dd7a324c,1d5696c8,b041a12a,c6a538f7,3094716c,9943c55a) +,S(7aa4afbe,29b06a1e,da9319d5,72572b13,1df68f74,1b5f8d8e,d00ccc04,80f8016e,15f79a9f,b77b8587,7f02e3c1,3202b972,423fd00d,937c0d2d,c9d94b17,53fe7130) +#endif +#if WINDOW_G > 12 +,S(9145f3f5,876a3265,5d7fee64,f2d6e660,c34354e9,1571d68b,a19e4cc5,8c39f890,45e0a95d,cf369fd0,5bc9ba7f,da108d6f,37650c1d,5766b6c9,98ecda28,b285d8ff) +,S(5450b752,36fb010d,1ef37afa,2077f3dc,a5a7f6c8,91a21317,13df740f,4511ac9e,a7c7ed57,62bef86d,4de1084d,3ded2d7b,13ff563a,67109ef0,8b6f0180,fe6ba175) +,S(ba6c0d72,5e48de2c,cb8256d6,7417d075,bbf2766f,d13501b8,4c32cf88,c0666a0f,cd2a9132,7137299f,50eda669,3a599032,bdecd64b,91bcc640,5ed186f3,e525e442) +,S(b94821ff,1feeebb4,6fd1006b,798fbdf5,d25a649d,aad58b05,53adb7b3,9605c921,21589ba0,79bb92a2,c7c3d950,c574afcd,f45ccfae,eec4365a,72dc58ab,f9077c05) +,S(46436446,497f7c76,b70e0d7a,5a963cc8,432f14de,93d61f81,98f8879f,da0681d,29344a4e,90c4d810,10da8aab,5ea25e5f,48c367e5,b3ec9239,8a3e608d,49c83a5f) +,S(bd8e5ac6,a2e210be,4959185b,7bcb0cf1,bd3be917,5baa0d08,2bb0b38,e4c1ae1d,6b381be4,6dcc9755,da7773a5,eec888a6,69c6f71a,7c3ec0a9,4edf08aa,2db1fa19) +,S(c27c1e1a,c428a7a5,f4c3405,58ace76d,7fb64593,b3942319,74cd18ff,99f22493,fc95d661,c12f7b3a,1cb1884c,fa9f5994,25108af3,c05e04a4,9544f919,c59cf57c) +,S(a1765561,837e4ca5,5268168e,ed90466c,44c17c01,4040fc02,9e53af22,77eb30d5,8a2dede2,b8d488bf,cd655d0b,30e6e2f7,3032c775,d0fa15ae,cfc8b66c,b6c28eb5) +,S(2bf6930d,35cacc91,87e9279f,678ba368,e9eea737,8300ef93,b03e98c1,81ddbea9,8a2d4d43,3aaa8bb0,3ffee538,38ca8e16,d0f3f930,c35d0db4,6e2fa069,e625209d) +,S(766a7725,9cc5aefd,90f005f4,d6755924,a36d085a,3a5856a,6a066a70,6877c8d7,db3fac97,4fd9e2e7,f05bfad1,5e938ef0,90b46d04,bf40bdc4,171c1e33,48049190) +,S(d25a60cd,953f21d4,5fcc333c,97329da,134196e3,9a913242,88792ff9,18461268,89bf2be8,bd04835f,dbb874e7,12352980,a07ad598,9035270f,397f24ce,790c7863) +,S(c7b28e9e,8b7125b2,6721f467,b665eafd,9bf56986,8ca180b3,60dfe429,cad95d68,ac28d58,b3a7b61a,71f947ed,8bca4768,9ec7bf34,7646a167,b37c3aa7,9e95c398) +,S(e2a5208a,c61f8c29,ada2d7a7,4cfce985,20c29160,f1f7a97,ce8b34dd,7c59bc24,de8ba14,49708a04,ccb4483b,4e90e383,a152ce27,777fce4a,880d9f5b,3dc70830) +,S(e1e8e4cd,2e8df95,d3b2b152,a540967d,6976e001,88287ca5,3e844adf,12e205b1,a5dbc6f9,cdc7547b,cb3f0091,8233723e,d34aa97,f546a491,a77d8cef,43bfc9e2) +,S(b20f0a51,4a684e55,2b228480,3f3b1c2a,3c3143b3,b895f75b,ea454bf0,9d2b6512,bc3db380,676d0d14,9c0b0c3,1941a07c,f7c95585,cd44ec31,e0edda96,e80d02c9) +,S(b71a6923,b1adbf77,94cd9d8d,407ac96f,9582cbc9,b9748949,9cfa696a,c29d3ec,75182389,9d59558f,b93113c8,d38c72d2,7b6d75ee,7679fb1c,89bfce1a,64b4f151) +,S(ca47adac,68ba38d1,8ccef76c,7565788,a82f415f,d9dda65,2004d5c6,a7d3bb3f,bd598ab,1b783382,44035385,e165fd5a,ccd8454c,3969d378,42fad050,4a8701df) +,S(5fade148,aceee9ee,9fb4eeec,edd5e4c9,4fb989c4,d99f65ee,a45f99d0,2d40e441,ba6fca3a,e82e5581,ac5104ca,c8dd2c00,15afd1cb,3943f1cb,5e61dd4c,d73831f0) +,S(767dc9d2,14fccf00,900ba01,a1cf30fa,e834c851,e633849e,8adada63,fe5f84e9,8c650911,aca30e56,2d6b97a5,2fd7cbfd,1a5bcd1,9ae197d6,9ee3215e,64404639) +,S(27f8f961,445e2a20,5daa7648,fc3c06d9,523544d7,477e686b,91d7178b,7e4f06d9,39110b27,82cd7be9,75596bce,6b79e5de,37933242,21be8172,427cdfd,82a73a60) +,S(8de0485b,343b5e4b,ada4070b,f79dde48,8a1b2889,839735bc,6a403165,3f3de668,90305767,6f43e0f7,d7d1c1a4,4c59124a,12fbba72,8302e143,1c2cfae2,ed5729d) +,S(5e43db6c,8770e8ae,8ab8d318,8e700c28,5b6af8a1,eec95fe1,b68e5cc5,952df0ff,6882628d,d85fbcfe,3a2a1091,15e59c78,9aeebb3d,37075f90,ae02a439,506c7aa6) +,S(7db2baab,4bf4300d,e7caf4e3,52df1423,6102863c,edfeb7a0,89311f42,59a4ed54,387561a2,fbbb44be,303fbbcd,685909cd,e553a84c,a3d4c0cb,d33026fe,178e8a84) +,S(96da8525,39106887,d1fdf9e8,232db3e4,cdbefdcc,abb90bbe,fc04d10d,b996c6f1,65271a31,49127341,9fb5d651,3dc33287,45948c92,b7fcc509,4023d300,9bf9edcc) +,S(84eff1cb,14eb1284,f5ba51fa,838b485e,64cd4c0f,acb97b00,81ba7848,add50613,926c9c8,a6540a8d,7b1e602b,6ce818c7,609f4511,32f284fc,7f578c52,a6febd9e) +,S(1eb96371,8e2a2a0f,f5ee6000,7bf94a00,416e6a92,25d59705,7fe19941,e2adfbbe,4870aad8,9635ddfa,dc3d4011,500639aa,d3cf0523,cff0dbb0,9c9f6a1,3005b855) +,S(2994a36a,6ea3f307,1bda8696,baf193df,c75fd4a1,f7683fd8,d454dcb8,77bdc098,e465e8ee,a7273d4c,d786bd0b,e96fd3e8,9969bf03,1b76aeb3,fc82c4c4,bf856766) +,S(25e7fb70,f3d357a2,c29b115b,5e2d97d9,d2b68fcb,b7f2fc00,237758d5,9d26c414,4959a370,a3bb895e,bf530fa0,13a86ab8,206b7330,efaca631,fed26773,f356c4f2) +,S(fc387f98,80bf6bbe,19f0481a,2d66bc5b,c3945c52,588860ea,dfd5893,347c0623,89d7b80e,83caf032,9c9d07af,734604aa,7ba33274,c1081ff,16e663eb,b49d67c4) +,S(c50af368,c25fc9fe,10220fa8,2f177720,ef5c00b4,85fa99,e2f03294,fe01e1d4,c3777b26,41983094,912b80d,9e94af7b,27d9f10f,978c931b,a4294cb6,b97579fb) +,S(a0f9d109,d524d9ba,a2e00362,941a5f20,d7015c48,554f5bea,7c97617e,10041f94,28c51c02,daa5e108,3e77ff2,c64560e1,2eae923a,3a699f1,daf3c62a,710e9ad0) +,S(41d12627,58b708,58727138,908004b3,2138bc23,cbcdfa28,5da862a3,48316de1,6277029,153bcec9,5c95f451,3d515d90,341d90a4,90eb2999,d29df4f0,7c1b9673) +,S(944c58ce,fe6cf543,d93afb77,e33adb3a,5774448c,d61d621c,fb80f856,6e99ca87,c071ec1c,9b7fc717,ca91c557,66bcb222,3294958a,b7d7b056,e7473170,284d66b5) +,S(3307ab12,e06d71ce,9c029bf1,88eebb58,9a27be59,17290635,f2babebf,be437145,889c3cb9,28cf9091,4748dd9b,f89e9809,4a6966d0,97d854c3,c6b6a949,c861d213) +,S(42baf011,1eb2224e,4ca03abd,24307b6,72b74572,2db6a8ac,dee1b7f3,45cb9ae6,bf32e128,d608dea2,4b564bec,38d22c5e,879515d2,7379cb11,25695faa,2e12ee06) +,S(856baabb,be7b4bd0,49fbe898,110d1175,166c69c0,a2bc86bf,e734c854,c402c621,24a323c9,b6d31fd3,cd424161,be229e89,1f825197,9ed4721b,943d7418,4912ac0c) +,S(38dbc18e,d998143d,874c224e,de83834d,95aeeadc,805cac1c,3216d830,d24a9cd4,273ec126,f7e85778,ea38e2ea,a90ab5c5,271c6eee,7f934a03,570891e5,167eae4a) +,S(359dc85b,ffcd2329,3166bb20,c8374af1,5e24c065,a5f48d92,c981eb81,4988dc59,de5dedf7,deef588b,90237d06,e437bdfe,c4a05703,f77b584a,e58162fa,bfbf39c6) +,S(e1068065,e2e91c88,3de2f73a,6a5f3da7,1d872a74,9d7f283b,b1ca35b7,c63666ea,810c3a52,b5df0851,87928afa,a7685035,a7e155fa,c8dd4523,c5ed1f01,73752cd9) +,S(50767f71,37e7c9a6,6e317183,cddfdfc,b564956d,cbd5f3c7,fd8506d,dbb19d83,e1c2dd5f,5e9d5fed,807d24dd,3f2e0ae2,393b6167,563db9fa,5e338664,a0d4fff8) +,S(44cecbf0,cdf88355,f1216d0d,efcea137,5e01275f,f53d8a72,5a0b5980,e6e65864,469568e,5094e9b9,ee290550,e67bc636,e8e3f022,f15c8d2e,25c3ad6,f51cd40e) +,S(1830c8ea,43cbb07e,fa2fe597,6afca2bb,87ed8a92,602e05e8,86ce3447,96aa18b3,df551328,e064aee7,67f56203,7fa31c11,3c8ce2fa,b5445d65,8bf1dd84,2f1da49d) +,S(58d54b7a,473a7ab2,51c33417,a41f4ee4,708245ea,c4f8eb79,9bf90aa4,bd9326c6,a191f338,15e2e07c,ca4c331b,fb1cb2ca,a1692093,faf5e789,1ce45a2e,c49b2a85) +,S(f0dce604,9507812e,603af104,42fc9861,70a18b6e,44e81af7,ba192b55,12c6792c,c221a221,b5e86ed6,23e48df5,5cf0f560,4cc60eb4,c54d95ce,3ada7b09,bbb966e4) +,S(42fb09e5,72c0302b,286aaa04,644b26ae,e4b958cf,ae5293d4,d7ba505,59dd2ab5,79c10573,a00e6888,fbc7ec76,983e7d17,f46e1ba8,27494099,43781bd5,19f2299f) +,S(7adf1551,ddae0c9a,8628db25,e0dad10c,935465bc,88b005de,ea2d0412,f3502ecb,657c0ba2,143cea92,c9ef5c3,69d110a1,2e031e67,9d945a9b,b3c5886f,29acfd20) +,S(dd5a48b9,56fdf6a6,d6271310,afc2f5bd,3a7bfdc9,28125345,4dffd91c,282c7a5a,7390d037,2e067f36,fab52107,29590464,2ac6b0cd,91a161e3,85df7cc1,7ca52657) +,S(631850b5,15374594,be1c783b,104d2ce0,13ac763b,1d36301d,2936c2d8,8a1466fe,2490ce1e,a9b67e44,a9241416,c5729ace,2016d202,b77efa85,78bf3228,c590882e) +,S(332e39e4,d6732229,aed85cd5,83a3ccc4,24466869,bdc6a8e0,741b0e06,f3a0bca5,90840f03,60db52ae,a58b1b4,74ad65c,b66ac30d,f4d465aa,60244d48,5d7578e7) +,S(de019556,f0c7e1c1,6567224e,826532f1,d72c0eb2,91e70980,de7513a4,362f0c97,39a3d79d,1cc98840,4162227a,66382529,d75fa5bd,64977e47,9af0aed8,68411ea3) +,S(4c44c0c8,e675da80,c6ffbf2,61b82e46,4f81b76c,a3f902a6,8094a2cb,24ed859f,59e1ee88,1ecc45de,d8ff2800,243ab8ac,c5497897,1a3a2246,63b2b593,e45ac34) +,S(e60339b8,481e19e,5c1f4d1a,85ddcec6,a4e0dcbe,113e7d28,2793654f,309286a2,9a1eeacc,a607941f,b51c7998,ed2a5a98,bc58e3f9,4737f72d,1b08a706,a49d9d59) +,S(10f42ee3,e7292f3,9f4bc472,708ffec5,c6ad955,c5285be0,d44d02c3,d8a25e66,6f365f0,53ebe28f,db9d5f2b,c967cf14,183e130d,f01a5106,34a975c,ec916a25) +,S(7e0931ca,d1286687,7d2fb0f3,1c58d74b,703af3ae,593a9548,b6d53d86,6729c445,5e4b9fc,75eab41d,663caf7e,8056f4c8,a9c34af9,22773ffb,f5a12174,1f6b0b0b) +,S(36313f7e,f9613c6c,ff14cd1a,78362f7d,b7f1acc0,db278f1c,6a011435,57963f22,1e6946ab,2a94231,4ac6627f,5494205c,33960a91,ba663a69,8641bab4,43d7edc2) +,S(223eeed8,8eedc265,b2e18a63,ceaa2e9e,83f9ba59,2fc8f3bb,55cec574,2869fe01,72122173,4ae29bfc,f3632cc8,92d72d10,5593f7b8,d687e5ff,eff21095,c1bbd71c) +,S(b6bd5ec9,33302c5e,3fb9b32,18795a11,60dbb2bc,f9a9b5fc,31b7a5a6,28b3ec20,fb9f87f2,98a8e5fe,b15f051d,63b48bac,34f373f3,9b42a42c,d0f1d2d9,c99dd495) +,S(a365a760,3b1c24fb,157f69ce,8fd57ae,5a802dbf,3b8f92c9,8f0a8b01,4ce24668,73e6422b,7746abda,2a38cc7,298180e6,578005b4,1b0d3760,6f2bec3f,5c0a89f9) +,S(e86f8fac,43e436f6,f4adba30,9d446a07,e24bac1e,d379e13a,a235ca1e,d7cebe6e,1e7bb4ef,aa75a9bd,713a592c,42a01134,930b7402,77cc1cd4,a913d6db,f4a166af) +,S(f5a57dfa,d2b25571,dad09304,cfde1da2,5cab3e2,e85895cc,9933e868,eb9bd5ac,d265de5e,8fc90e41,d518dad2,68997a24,8eb90906,becba9b0,c768c5e9,877c1ff6) +,S(e1dcd17a,7259374,7e6fd8ca,b2464a9d,6656607c,a2bf10f1,45c45947,75f76c7b,efa2c310,23f86d2,6489feb6,1232bd44,dff819ce,6b95678a,130de640,4af9a20e) +,S(83f8abdd,84996ad,1be74b80,a05da9ab,cb3774fd,cca40c3b,afd386cd,cfa801ff,267ebd64,329fb10e,56ee792d,966868d8,1c85ff37,6aa24287,3d37c63a,4bc3f63d) +,S(54cc9d79,6ca85a90,27487c71,6511485b,ca324b1a,f34fe454,ea9ba54b,4f259fae,18c39071,ef0b861d,7d016e9e,deb6e83a,3c6ce8c1,517ce0f2,e201da0b,fab2da2a) +,S(9d12a52a,e0091654,e2875ac1,b11f8744,1c3f65ac,940e6a51,6351c219,31402ba4,5ffbb334,276219af,418d17f3,9f5fad63,c6d7e42d,d53f6e52,bbee2f01,38e81d2e) +,S(659bfdb7,66821a91,cd030917,ff21aea4,488007f0,b7ef3824,4f23b665,e6496998,2ad708bc,4506e85a,341ef96b,78bc247f,d7321a8e,bc21f9db,8444e7ca,254784e0) +,S(e2cc4e33,d4a08374,4866a253,81549a6a,76ba1b4f,57312413,d601296e,5eb4670b,528b2b25,347e7f34,7b79780e,a64c3718,80497f0b,a3b28e18,79714089,a4672476) +,S(529c0b9c,9e21c36c,9b2164c0,fa505601,e8dbbac4,cfcac131,e248e103,e6edec68,7fa44821,72a0ca01,33669e6a,bd2e0386,6cb74f5f,9cbb7e4,96770129,567125f4) +,S(289d6baf,be6a7d1c,154d6532,a80fb65b,3d89e57b,eb2f1dda,654d3553,683b63a1,801f4863,d3ce8d61,60e2c62c,55267877,db149ff0,c3cdbb53,38893168,7d005400) +,S(d16a84c9,e3b36660,7c005bb3,425ab432,2eab9b58,58d1899e,51f2ecf0,790f14a1,2c6f5dab,10715328,f9ffc5ea,4ad6e0f1,46ec79cf,19cb2313,79bb5198,5156dd07) +,S(d03cac39,4fdabfbf,440a6893,e410dab2,a7062df3,ecbe1aff,d30703b1,6b6348f1,152313ce,f530b317,70d85c08,7de95b1b,5dc4a86d,38e4040a,e5d1ba34,449d19f9) +,S(b66b3c6c,a673c4a9,77ca7d85,1f969858,d4c4b604,bc497101,c89207b5,a863379b,54ba2563,771c6aac,482c63cb,7156961c,4b00faff,187f0560,9a470b06,31624da4) +,S(be684644,11c47cd7,dfd3127f,4e7d7308,2a43fb68,79c5e86,236e4516,a98c8c45,79290f83,c61d368c,2e395aae,b9cc50e9,7d78ddc2,fdee9f19,a15fae85,826733da) +,S(478ac3a0,9f34f463,4d61de70,9ee01878,4ca421f,91d20e0c,5c62bfb7,afcbde9b,f752f3b2,ccbc1096,1ae7526f,5574b5f6,e4bc7d4b,f77edc34,f6e37655,7b0988bf) +,S(745f355a,f2ed71a9,9d4d7de9,c9bd4a13,7271a2a0,c077c796,e7064179,8f3dcfc8,18ea61f4,6b0c87f0,9ed05816,c31e1992,d4fe8826,630c5f6e,67242063,86e288b9) +,S(54e7bd6f,9878a8b0,909aede5,9286427c,a3157a8e,38ab94b2,18db520e,86760ce0,d7b7d80d,c1eab448,d1f3c638,675dc0b4,e04bdba5,340d3f2d,dc1d24f3,dfb8e49) +,S(ff56afb6,55eb431e,f3c6f5c7,fcc6febf,99b018ae,3dc95208,27e4a01f,a07d510e,9bfabdb8,42d7b1c7,9f4388b4,49a28d6,ec723210,ea27509,655e9b44,2591e371) +,S(c2bcc099,ed298fc8,679d0250,6d8ea790,ea511b41,5ff3ebe3,82d39d21,fe9cda72,6c7bf2c4,35ecf773,5b6c31a5,82fd38c4,825de4f0,58efb070,aa1ecb58,530f971f) +,S(2383f144,9811331e,6c54b9a1,19c681fe,c8549e36,890b80f5,99a80187,8e2ec4e,13ab411f,d846b6b5,938a999a,704470f0,d8fff03e,9dd35cb1,44860a0e,3533a1f9) +,S(2f2271c0,d4fa1d8b,f8a44584,ba4f5266,9953f72,89de16b8,17d6bf0c,6e096048,646ef05d,b40e50e8,b6f32c22,63ef553f,a957173d,a6f14ab5,7cd60b60,2fb42fc4) +,S(b7b49b1b,f067a27,eedbe55c,bb011eeb,809e7ada,ada5d08,9bf1f26a,25e951c7,fec760ac,a8160525,ad6ec95c,7cb0329,4a9b7f20,45907331,5b2dee2c,7f7c33ed) +,S(36c8e1ca,d9933e5c,971866eb,12daf81e,7765d4cb,9f0af557,94181aa5,e5409223,895eb6d0,a0252282,d71cc730,9116ea95,22f2e35f,52498853,e291932a,dc8b8fdf) +,S(3cbe9127,63283592,13173e01,8cc2b0e0,fa5b8a11,5684cd6a,6ee7bde3,bc1ed523,7b2d3dc9,22f96c9b,9970aa9d,c75f1e15,c5149ab3,d0993055,e4df30cf,ce44dc81) +,S(76e94d41,c4639419,23448d38,8b239e6,fe0aec99,314ed16,4e67e97b,6247213c,8ee4a6c3,2f010749,103460bf,d75fa38f,f9efe4e4,bf283cb5,a3bc186b,21fa1278) +,S(493925cb,12c0e7e7,a15749e0,7fe9dba,5b265d27,8eec0c08,506f3433,4b1851ec,70900c6b,3960a465,6cab318f,9f730a66,e4a2400e,d819da9a,1f5b16bc,4c62b193) +,S(b37fdaba,d1a1393d,79820eb4,a4823d38,3873306a,a9f5e6b7,51173aed,c43cdcbf,8506f0de,57fad139,e20df67b,e30a75a7,dfd325f2,9e35652f,28fec608,f27030a) +,S(4451960c,48e95c49,32b0c90e,9f90724,8f2b7023,9c6c703,3c29f4a5,b0a5e8c1,83553a18,d9ce9f66,961c9e1a,47766a4e,28bc404f,bef524de,53b1b687,d4d7490c) +,S(9b0ac1a8,697c69b9,80cab20e,b3f98718,7857721b,c869c704,caf63b80,dfea3449,210e4c53,bf1bbf3f,71e32a58,22809853,61b61723,72e845d,65b5661d,fa7e60e9) +,S(e6697355,ccae4f7e,122d62de,1c00dcc5,32eca4fa,7dbd1ceb,e92684b4,781e0851,1f122cff,dbe5ef3c,944353f7,18806a82,9d3ded91,427bdda1,736ba236,e9bdc3cb) +,S(ffa890f1,1a1aa4ca,1f26f86,1288bac7,ad480a4e,1cc47f2a,fe39f260,f167201e,1688dfc4,1716fc3d,473c4149,77d0ee8c,ac569cda,b01ab5d,69d449ca,85439cb4) +,S(9088d4f2,6ce238cf,63eb09b1,5c04a04c,c41fcc57,946c6c14,cd3b1b4f,54b6bf47,9e380417,bc61004e,3d5c9943,b3d359db,2ae4ec81,2b70e909,bfe265d5,e4d2c2b9) +,S(a3395dda,c1e760e0,fe7f7e5f,e3296bc2,99949ca2,2c034707,67c08ffc,d9576a91,4f8a879a,54036d17,16f07016,23dfcfba,3141850c,de003870,6ee940e7,452393d3) +,S(11e54d64,54aac1e0,58cef234,51f686a9,1a77300d,75330ecb,d208678b,2b8ad651,749b2960,5a8419f9,c5521dfe,f552a24d,aaa53f45,908d2679,6e08b396,c9c020f2) +,S(c8f13cdf,7b41e822,ab6d5a70,7c701d29,98f5f0da,8e4c9746,75e808fc,64327f30,489a69df,17c09c1c,dec329d6,a1f34f60,445d7aad,d609d94d,44168947,c3199404) +,S(9175e6dc,cf674838,a94c628c,3e1a9dc2,9487f394,8a25e50c,d463cf6e,92d84442,8705713f,ed377125,51e37e51,78ca7a7,c13e193b,1b83c729,8cb08186,8fde1c22) +,S(8eed492f,b6d5f0e9,ee78f6b8,953ac0a0,5df8b9ec,db17a09d,22863bf4,3620099b,23a45742,17672e98,d9cf8b94,62439ec8,82e1acfd,40db9d9,9ece889d,1e0ff1bf) +,S(cb95ce23,dbac06ef,79793f54,3105f5d7,5cde90bc,651b7756,bebfa367,d5c2dd9,9612a6ba,c023b0c0,73b5ed99,271ddeb4,57d22d74,f7ecea4f,c618be5e,164a9a48) +,S(667218c8,bbd3ff37,d42a8ebf,8b5a7791,d8fdd493,9ce447c9,15dac906,67a3c980,dd401179,9e19afdd,46b44aab,1055b554,452a21e7,6750f2a,ce98083c,8cec26c0) +,S(884799c6,ded4851,ce53e855,dc429698,c7627b5,a0ed3852,19b59af8,32f76e5f,238d75ed,84e6408c,79cd2d37,152cde78,22e34377,fccf05ac,3afda662,c21c4a6b) +,S(8d98f36b,5fc0082c,597a05ba,e24ea6d2,2cc8bb90,3a6bf96a,256eeead,6911d143,26e8ad1a,fc902a6d,505b2fcf,80168177,de7df931,b1dc1516,f2ad7b38,e0ab3cd3) +,S(ba9062ca,c0ddc6d3,27f2cbc2,8d2efb1f,d1db2388,c86741ae,7403f4b8,3fd70ad2,473b335b,3036e754,d9d71ccd,53814455,674539fd,7b73d9f7,8f24bb0a,668b38c2) +,S(4a2d36d7,3bf0e609,7a69be67,55621051,7453ca53,11e288f0,1ff1dc03,acdca29,ff691e7,a90331cd,44e83ac6,c298f5fa,9d694a81,48db01d8,595a4386,b2ca8f83) +,S(e868f28f,d99c4b16,b64fb0d9,32c325c8,6b365136,e0055c4f,cd362e1d,cf37d0c4,ad3346c1,83401034,8e8e0440,e889109a,40e5fa11,37d94bca,2742adec,4cd4a9eb) +,S(6c5e8689,830a6ca5,12d77e56,62239833,ea77e696,da40feea,99da3519,2babbf3b,c29e05f1,5fd00b60,7bdc333d,d753647f,56b9830d,46a597c1,2bee9465,ad779540) +,S(b3a172a5,6ebf2dff,aeb91cc8,6b9d5a91,c317adc6,250ae210,e1a25bec,1c046344,28f6dd79,9ae40d6d,bd31fff9,9a4c2fa,f06401c0,de7a5d11,9fc5faf8,3b4ac3d5) +,S(198f05d2,e2f9d779,a50aed67,39468a8c,ac4a22ec,71a3ab80,91a94e2,100d8f47,cc6a183f,c9813173,caee3baa,f3fcb223,39708968,360c02b3,cbf899e0,b7cd0414) +,S(78b2178f,a943a791,4bc7703a,e850b07b,41ae77db,79fc39d8,9f0f50aa,b077f48e,85fd3e34,f2cbb092,8bb89004,e1801be1,d78fceec,c29eabeb,11b9cb15,625274e7) +,S(6f70df00,1d4c5175,f997a795,170e28a4,23828ef9,d5f72dcc,cec43fb8,d9943f3e,26315213,b77183e4,5979c34b,e730e2a6,956a66c2,a8dfbee5,f0f1eedc,ce8315ce) +,S(ab813144,3c946d29,d05509e3,b45b5926,e3964b2d,1cd0fbd0,9cfc359d,b5a9dccc,aebdf315,c1273af,a0c5e587,6c6c6132,16b7710b,3f505062,6336ca9,4f5c5ac) +,S(e72b3791,dd751127,23723e62,77e5e6ed,6b94569e,ba3321a2,a3e883e,5473ad3,131b3074,2dbcaaa0,fd3109ab,5e3a2847,9c2091ac,8830b19f,d4df4c82,9b28a3d8) +,S(ca5a3296,ecdd5e50,38fdf77a,fcc507da,bb525d7c,56b50c74,61928432,ce3ded63,8bdb6794,b7e177ba,9027258e,42b365bc,5a14209d,2bdce54b,3f865fc6,ffc4ab9e) +,S(eaa3be9f,26ae8cff,cedbe59d,cc03b202,e7d2e815,a7269819,c881a700,e31a9222,1b5a2cd7,a367d34c,60ef8026,51df2d3b,36ac2816,7cd7eacc,735e45c1,9524ec1c) +,S(ebba882d,3ab4ff6a,e162076d,56791554,35a011e6,74872206,582b03de,e8e97728,94222a05,3d8dd2cd,cdaf2ac7,69ed8c65,8a004c58,7bdfd0ed,355be474,65be16ac) +,S(ca0d97ea,537a5dd1,147cb784,eda20601,ba88e0d1,68e8df44,6d8923c8,353aba86,874ac858,89eb86f1,88ebb979,a4490e65,96c97892,874b5b68,167ca99,f68fba1f) +,S(51de2965,34807454,7e798f98,c5fc19c5,84a90a0b,e1dda24,7718cfb3,ebb797e1,81374e3a,ad04e6b9,55c1952b,fcdf9a7,ace0ee4b,99e487bf,87ceff58,3f7c54d) +,S(69d611f,3136be2,cce39bd,a1d48fb6,87b52135,365b8df5,151c6ec8,c1387509,75e2d820,563b64ca,c4d127e1,a5c29720,fb84c0aa,6b271fa7,e9da2c22,3195bde0) +,S(31163083,558660f,23220456,1dcde218,6fa4a4c0,de450a9c,b2f57de1,3a8aa135,25d6d496,b1341688,3008c636,ae1d8b76,29e14207,e5fbb817,539ddbf6,ff46eae2) +,S(84e342aa,efa9cd4d,4d82e5b4,4d0ad9a9,11f4623d,8684c274,cc3cd561,2c7ac334,fb90dbff,260f9997,c84f0a32,4fe5d2f6,f552affb,50aed654,fb8f660,2a92a70e) +,S(95efc402,969db115,22446814,3d4e3aa0,fa812aac,8867a5bc,64d66692,67bf6562,315bcc31,6149252c,56f3f00d,445255fa,e4567d9f,d77ab4b3,e82c1359,9f371883) +,S(5223623c,f87e9da0,bd289993,a55bb9be,55b40149,bb501507,e3d5c9e8,d78d07fe,6bfd0a21,dd2df437,9b1c16,b0076f88,832e921,db3cbdef,fa5808fc,ac613b56) +,S(f212d199,a6b707e,61d87ab3,109e1178,ea180f19,66b0a55d,f5f4cb97,c0cb0a4f,3280446c,7edbb64e,e47c3142,7c0ea113,7f511422,19ec3824,12f6b069,a0f7c84b) +,S(6b55063f,f25d76f8,2154431b,20058f96,e1e19ce2,210e1b50,835cf58c,31cfe8c9,5427dd62,36450762,46e99707,6f60ffed,558a82a3,dd7e31c6,492088da,9069f8bf) +,S(2539e5cf,a09690c0,12ae0c12,9e6f8b27,c9388d41,a82e1e96,47219d57,9b23045,94cb83f6,1e26a4dc,d1b93000,e5113347,31d804b4,a259e24a,77c457ad,d9021ac3) +,S(aa9b6ad3,4aaf1c30,71aed31e,8f28c3f7,9106421e,f0e53fb6,297fae54,a47d51d,dc0958e4,9fe4ae00,98b4e7db,10ab4d99,58cbd87e,ca443d3e,d1c9de77,83544c47) +,S(a850a313,aad224fb,f5ed6e63,5a3f6b0f,e08964e5,e9ca262f,780532f6,13487ad,7e476ad5,4cbc55c2,3b9708ca,eef3479,d9a5e570,26f15a4c,43b83363,ed4ccbe7) +,S(314fec33,f4fd0c96,d04889fa,b18e29d2,5da44132,6477b28c,7418d4ae,5fa09c1a,a2c9513,a98ffb7,9b5dd4f5,49534fdc,d9b4b8d3,1aa6a4a9,76b7b94f,ebd25f42) +,S(6e7dc3c8,9ec57e79,ae1581ae,1afbdcef,183998b8,cf52dc85,329afa35,4f3d0963,6b636805,6d5a8e9f,9651e3a8,2598ab1b,8f057830,fccac964,a83515f8,9d9f87d8) +,S(596df693,fc4ba2d5,20497a50,7d1841c4,38b6cfc0,58c274ad,9557d400,573337c5,6609ede9,1c97b09b,3a171723,e9ec5cfe,74b75c33,d5ccb3c6,bd03fd04,b37f4ff5) +,S(235f8dd4,10de7800,58550e8e,77bd42d4,ee3ba259,97bcb4ee,13cf0a12,14e8afb7,bf6e0ccd,b8e8e136,800f8d59,510a4455,53b72c33,824b71bd,189e158b,6cfa6712) +,S(a9d8ba97,b259e91f,125fbb28,c80e81f0,3f03906a,ef692279,4c9cc23,13db8b47,e668b954,19b580f2,67472afe,221f5895,5e6ce6f6,45ba737b,f14754ac,ec048656) +,S(53b44dc6,4f74c170,142bc629,51349b88,c4e2cc35,b7d9a7f4,827b07e8,4a288e5c,4aff13e1,404562c4,d8f006ea,dfee7b5a,32216187,d8c96c7e,5896e157,97075d4) +,S(76e6e038,a6baf9f7,1acb56ca,1494486a,a9187279,486f62f,947b5a02,580af1a0,51a5d110,66884076,44c18348,be045910,3b57e0d7,2266ffd4,465e6b4d,e1f0f0fa) +,S(7761ff19,2fc70129,10eda284,dde864bc,1c45b4c7,1bec7870,2bcf53bf,9bc1e6b5,80980f70,a82f7196,61f7e1fd,fc3e7d37,e0bb75cb,b1ab47c1,d947dac4,296e11b2) +,S(8199c9d6,1224f51f,e6dcdc33,3869d860,95c0bd8e,210d2d7f,8fed2804,a89aadf9,be89724f,5cbd2384,ae9bbd73,f030dc74,a158ee7d,2a9d292d,daae3057,4b1ec89b) +,S(15c279fc,760a2556,bbd62680,3bd779d8,8bd4dcb,e508b3b7,99d27405,91c55c0e,fd5038bf,ed80c963,4915d352,bca040fd,ea0b9b0,67215dee,3373e4d3,53390c39) +,S(fb3f8d06,b2804047,6f7b46a3,ecc2e7ed,9724ace4,14831a8,3c111615,f8a39b46,f9250cb6,ff851b61,3b3fd70c,63c1bd72,3177ed50,ac991185,4fbfb3cf,6bd2154e) +,S(39b2b547,3c964125,da2723e3,97c3fde,f9faf415,db0b389b,5eac9a6e,ba012edb,8ac1c2a5,a586f413,bd68aedf,1f65f231,6bce7bae,ddf9564,2882f2,1bfb7547) +,S(42d5dffa,e476151a,1d3f6d0b,bb24e8cd,bf72d73e,ac87e848,20cff44a,47f1552b,631d9645,d941c001,627ebe3a,f403bcf6,663f6e46,17d86ee2,922fadb4,b8847ee4) +,S(84dc96c6,24ecabf0,a5edd071,1e922d9a,630a0bd2,6d9c6158,e311fb7a,e6e0bd8f,40af318a,16b7324d,2acff10a,8bd2fc25,c795cc71,c0aa5a8,2cc8eae3,ef8703c6) +,S(636e760a,797bceee,11b812af,37bf7cbb,4663ba02,c36d93bf,1873983,4bbf505e,ed5c5e4b,6cc8cf76,436dab98,104b9458,69924f40,57d92ff,d74f703a,65f724d2) +,S(137fd025,4bb5ee78,669ca6f4,ae278064,7d32bc0f,f6175090,d4ff7580,98d06ae4,282d6aa2,25eaaaa0,e9b186a3,36e92e7,e07ec23d,e9ce4bc8,8fb7f09,328d0fd4) +,S(218ab848,39e49256,b55bc7a5,cb250fc0,df781f60,17abcb61,1b6734d2,12459e92,7eb14f56,b53fb0dc,430c49c8,d32f39f0,1a7212fc,701ca444,c994b3ce,4d0e1599) +,S(6b3f7ba0,106f22f8,df69e3a7,8f137605,1b2f0a99,ebb4f4fb,61915495,5f8eda65,c5788c4,4c946bef,86d9a4ab,481e8873,6c831000,5d36d3b7,aaafb7b7,2330d299) +,S(9b414ecb,a2de1195,196fdf19,62eb5b86,131ad1ca,f7fefd08,c5de31fd,d9e8ceca,38e6f31f,9550df40,80db0626,9da9f4e6,51e94e85,95e74797,639225e,a725a637) +,S(436b07a1,857425e1,86933af0,d1d444d6,156a4a8e,f3f2df8e,cbaf661b,26940653,94a52f35,f124ebde,ca642713,724fcc63,c6822dd1,bce4c53a,ce155b31,443f2d44) +,S(cc0a9338,9b25f82,33419bd1,87b5e290,b8d76f28,2099b4d1,fff32cd5,128fbc6b,cc7e86d,ec7ac7a9,448cb627,875500e0,e713ad7a,430ee9ec,220bfe87,6e3f458e) +,S(5a1b316e,aaf877af,cc7b1907,eaf8dcab,7ea684ea,72fbf888,8f21fe83,c3a19858,4af0339a,da08846a,6b6b3466,da69412e,74411094,22dbc450,cf7424ce,cd81e7e1) +,S(faf89165,74444bb2,1fe1e411,40398b25,ac4a5725,2f9ff274,e7d409,6d6c53ee,cfa7795f,af75547f,5dcb6426,3b16c9c5,d87984ac,81083cb3,99714f6c,99a43100) +,S(39e5fd8a,ca141623,1840c68c,6c6cb028,c94cd22d,49619e33,aa9e4dea,d174f248,f8121f65,7083da65,74013e78,88f66276,a8d3686,528aa105,61d10a6f,8c3c1ff1) +,S(20a135ec,147d0cf2,ccd3cddf,6fbe1356,a64b8ed4,219bc0e9,25743098,325cbc1,b17514ab,ea1a3725,4c101fd2,675d30a9,fa1d170a,811f06a7,15622ae6,ee82c013) +,S(a181a1b8,af48f73f,a13d69e2,ac75b13b,9903ca11,8a8851fa,b461c2b4,2c72320a,c96c8467,3f487e62,3d72c432,ad5887a0,a66fbd3a,c43aa5a,219c84b2,97a6df20) +,S(395fc031,720a5da2,faf5d76a,9516de8d,eb462695,5eb87fc2,752462c7,7db3ee4f,4aebc86b,53783895,ab4e14e7,c3ec449c,962ac869,9b340523,1288bf41,c759ad6a) +,S(a36de9ec,f6df2b96,87d632a6,1bb6337d,3fffce5,71b9fd17,4246b33d,1b64fa6f,784e4c4f,a133d140,1b212e14,77deb40d,620fe29f,d0f05ea9,cdbdc862,651999f4) +,S(8cb5a899,ecee4430,f7381820,4535f57,e55a3ab8,3dbdc359,d04746e2,9840ba8c,12a7282a,e9c3a3c1,2c1df0ec,c3d28b4d,731dedb1,ef02cb2c,b92da5de,17ff59a) +,S(de441e1,4d9c9ba1,90e37201,22fd1fbc,4cee72d8,b26b1f29,9c450b66,60b60985,add1a30e,d12ddd33,d4f740d4,427fbeb6,2927b3c6,75032110,508e2114,271b63e) +,S(88e38b56,b5e5544a,f2f3c1b,7128d118,520646c3,97295067,4078207a,9b9fbab7,8833208e,d44e9656,e5bac529,cbdaf184,dc8ea020,a2d8f4b7,8101d8e6,1000e5e3) +,S(a4f0f992,f5616420,b9ffa3d1,58d2d729,3ee217c9,60f5266c,6c5f3374,f4640a7,da6741a8,437a86bc,40ec9188,a1af42fd,b131a8e,81289e71,3d80e201,f82e6ddb) +,S(5f00a8cf,f2d1aaae,604a40be,e451d8d2,86899fbf,37f96ad7,efe52407,1c5c945b,135fc8b6,9ea76d6e,39d1549f,b4692d5b,b48ead3,ae6c662a,424b63d2,b59deb12) +,S(59351a0e,bfd6fca2,ee04c799,838ddb8f,9d168967,a9e6cda0,b416ce31,88f99218,6e01a267,3184f4a8,28e27b6d,4291e7c8,fc4159d,73a465b6,4fe3d4e9,d50fdb34) +,S(175ee35,f5c533b3,de87387a,5f263d0c,6705ef73,e77f39f7,2c796f91,2cb1aecf,a3792715,4540e426,1e0d40fc,4c5fbd60,5fca3b63,3cd7b506,a80d0280,b9d9513f) +,S(75189b41,597b18ac,9ab6362f,a7905ad4,5655951d,fad033b0,2047dfbb,f347b8fe,f536fd21,ffa10ea,57c023de,256a59ed,aa246842,845afed5,b0177b77,21b2527e) +,S(91af9ec3,2522d65c,70bd2a31,57efd23a,43885573,6b5a1c72,49a414,a19bd4ae,312007c3,8462b858,6b44898e,d0b4419b,31c9cc19,a2ca6d6e,6436bb08,741a32de) +,S(ddb2fc8d,41fad5d0,5d109443,2f283c5c,732273a4,1a14db04,712a1d84,a4565c27,4f7e30c5,2cec6f4,201673a0,9893d092,8f6ac9b6,d7f2da38,d63ba2fa,d69c1d0a) +,S(9ce65d22,d7240dc3,50144936,ea412539,ad40a907,f2b04f96,f7ddc1df,f63641a6,af93e587,7f25bc64,2460b425,76062f54,c3037e43,80542340,cf927609,79d97c8c) +,S(7dc0d0d4,1fedec58,91c3932e,b0bf492d,5489f1b0,1e7f95f5,4936d76f,776e9a2b,d55a279e,760c3c13,bfa1c7a4,93831a14,1e9bbcf5,a535934f,a5269995,b107c47a) +,S(d01215c,b6b4d728,9dd8d351,f3e4aa7e,f190d40f,3281c8c1,63d03a95,4c0e5ead,ef98344b,ccbd7eee,723ce7fe,641854d,c68be6c6,99eea25,48b2c881,b0fdc662) +,S(d4d1c31,a9faef8f,5991b0d2,9bdff3d4,bb6498c6,2933eaf3,e1d06767,8d7cb92f,98f3a848,ac6b91fa,85bccd42,f2185e46,715faedb,a4f6590a,4df5f862,ae6a4831) +,S(cc659ecf,42abf24c,3da2d83c,84b1e32,3d718f0c,41a1b5a4,9fad2f24,c6080839,7bbdfd55,4d843399,b6edf249,ae795758,c7aef094,3f84ccbb,f0f2761a,c81f963c) +,S(19ba1567,d5cff385,9d074e94,478bef34,f0eb4775,6708d04e,594d1641,71ea4b04,34ea281b,d536b02e,da858311,4e59c110,30555c91,c8b90ed5,d4f53485,4a820f9a) +,S(3f0f02e3,1a6e5907,631960e5,fd52d2da,e825d8e7,529586a5,437798f5,d7bbc30f,b93e27c3,3aecd4da,59079ddc,be2cd6a5,62a3bf29,7b40519a,3509061,e3e63c3b) +,S(9884c48f,35f63fd9,5a9dd895,b0f382b4,8d0fb096,e5fab23e,df07924,149ab12,5688c266,7070437c,3d5e321f,58b6f41b,e011545e,989feaa0,13f241fb,4180eb44) +,S(940f2a93,79bc9c55,3082e85a,c2f83e5a,bb4a6fe0,2b23cb47,4489bb7c,c46c7b4d,b4b82380,77ba9d8f,51e7c735,cbc6a784,2aa7429d,2cae2284,700c0e2c,7f21fd9d) +,S(a9a7699c,e5353d9f,41afeccb,b5343ea4,5f4beb03,42f9001c,e0742eb,58b782f0,3c759eaa,b3e18cf1,a4341f77,8a601ac9,b0536fbc,5fb498b4,c7ca9597,9587c994) +,S(a21e348a,9cdb00,56e36cc2,82d0112a,93f4da1d,23f274af,b1522263,b218913,141543fa,652f9506,6ecb8e28,a701e663,c70b1873,b1e778da,588c1f4c,7ebe89ed) +,S(d6d54d95,1121e118,52b298d6,18ce738,e8142906,306a5ca4,1f048fb3,5a5fd383,897dccb8,de891fe2,304fe9d0,38d8eed2,8f76c8f3,535a2912,41253445,828a7a83) +,S(7e0a635d,c937eafb,488c7f7b,5efb12fa,6232b464,a3a47ebe,21cc0f1d,c31e6cda,d2d1d4a,75525e1d,2ce5b34e,3adcbf36,74489c86,ced61e82,2d63ac63,8de921e2) +,S(4ce2080f,66a21c68,428870e8,36b3fae9,55bafa14,fac200d3,afea00b8,d451a659,29e1fa26,565b02fd,318d0f3e,f0df93ae,f0ca1b92,73e31b1d,891f055f,6c7da4c4) +,S(dab86b87,b633bf65,59cd5caf,1b89e815,e6d4b7b4,d8f58f7f,c091f542,712bad2e,8e49b109,d79a55f3,8d8159d7,f55bd930,4506a634,7e57bbdf,8fd15eb3,53c85b5e) +,S(c6a14ac2,90fa32e4,e8b5386e,a7672d39,ba16224a,152897a5,6ae29001,b365aca9,42aadcd6,dcc588fe,2421967a,42ff615e,45cd5f2d,fa258164,b2c0eac7,735dbc67) +,S(2599fa40,880b108f,28f24400,4f3458f6,63510bac,c8a1041d,e694e214,ea450a27,54792ad,4ae1cdf4,6a7a973a,1a02bfd2,a424c46e,548c13e6,951d94c8,7ba57a01) +,S(f6ab0cb4,a6afa8f7,aaed8fe9,e79ec43d,31265533,6fa4553b,bf3d7476,8ed9f9ff,4ea12589,c4ba0090,48c1a476,1907fcd6,82e913bc,57af13f9,73fd9746,845026ef) +,S(f51bd48b,ab8f020e,2d97ecdb,d3ff4da7,72738ff2,bc71dbeb,dfdd48b2,707f1dfc,6b168ba0,947f47fa,8a7fe7bc,e7ef90f9,b361c752,248bde43,8c93f3f,4a697c40) +,S(b601f114,6c9ca90c,af798f2b,1d0bf7d2,a50b286,53521362,5c898f0a,4a2a3443,a6ca3041,36b6b675,5f317a11,59f0f110,6877fed0,fcc167ed,f0cf2391,c61f87dd) +,S(792dd67a,e5957c04,76f0511f,c5b7191,5be6a158,f2871ccb,37e90651,f85f974b,9b7f5cb9,bec59f69,3a44774d,d2f463e1,1a4c1c5c,84ac3bcb,94175809,4b1dd44b) +,S(7d884669,33b6f4ad,b3700eb4,f02514ac,4c29c420,33c34377,93101302,8bb093f9,2fc8c35e,674500db,5287ead3,5e46c306,2ebeb5f8,a5134885,a2f9461f,b5e2cb3b) +,S(9c76eb91,6d0f860b,21b82038,77089435,ead4bc41,df82c249,10edb80,692a5351,72badbf3,38800156,1e235a6d,a8c7769f,e51d1e0,d6de06b0,d9998290,f5c88b62) +,S(a49b5638,3d8a93e1,55e52a2a,a1e47c33,8fef18d8,2dafc24e,cf5bb0f3,1fd807f9,1bc271b3,9bf34c4c,ee4b0760,bc934646,9dc392e6,1fce976d,bee58e8d,901d3ae0) +,S(4d3135a,675bb0b0,ca9d5cc9,68f1c72e,a704c9fe,77aea9e0,a4d6247c,dc634460,ae5d7cbe,72f5f4bc,f2f1ffea,cf02b13a,cb74bcef,68cced38,395a76ee,280cfc4e) +,S(59572fbe,17dd6e38,fc0421b9,b42f192c,eff95583,a9204e37,11f33089,9e53f588,57134640,a8cb3f9e,6a1ab805,1d60a047,a01c8f2f,9b72782a,39c45421,de1c7c24) +,S(73cccc6d,49b4780e,caaa1c61,228d2e9a,a5fff08,f5605a5,cb5ea1e6,712d9511,463a8d74,f986c8f1,1c12ea8b,59b158d3,6a52c06d,6a85b08e,dbb2cd4f,e3752cf4) +,S(b6c8ebfd,db620aa9,476f7280,e8fdcf6e,ae3885f1,87683d1e,e503c2a3,8c4c1e46,9a6faed9,f0210048,be575c2a,c8194a5e,76a25d55,f3215dde,b4091060,e7d39802) +,S(b4162e0f,92de5493,da996c53,93067de3,b9cc4a8d,4c21df7e,b507fc9c,4c5e392e,ccce10d0,c9211d36,46397873,3060d982,eecf2217,7b8ed120,a4052561,6a3b385b) +,S(46bf2566,ca4235d7,abe91955,2a0b8d40,a581008d,6544d9b7,a2a469d7,8d2b33a2,6f66fd6b,b8278841,92d82e39,cd0bc9d5,285b5cf0,2171ef1,b77c87f,c6785040) +,S(78446da4,e869a9cf,8badfcd1,b89c135d,b5422a68,2a9ef6b7,419a914e,3d59ab2f,4215b131,db7e46c1,9e03c051,f33bebde,3f5f31bf,2d428983,27d2b586,5a8c9ce3) +,S(86886a05,511080cd,42bdc762,95eb8edb,fa2b01ca,5cbd1d1f,4bebf001,5605f3b7,c71b69f3,5579c0dc,7078854a,83add404,f9b753ed,597a77d7,67507e77,f7914466) +,S(a02e675e,37f8fc43,fd38675a,744406e0,36d5fafc,b28a7371,e16d94bc,83713388,d6f9a541,835c80d4,eae16251,277e9eac,4ee66bd5,a1899c36,de3173de,fc41239e) +,S(a16b6aa8,432c6ced,cd110096,697bc04c,9b299777,ee287f14,ea4cc889,8492bf26,5c11a70,ef9e42ac,d0ed644,6ea7e14e,1e734da1,89ef1ace,d2fd7241,4e0db298) +,S(66a3f2fe,775fe5e5,d0ba1205,f7b81fca,12d7fc2b,f8685c5c,97114b98,e0f45b5a,5059bd14,a49ad49d,550daad0,30b4eb21,e626e2,95ed01c8,c1823050,5e5e3eaf) +,S(9a47a3ce,bf9a04c6,755c6321,61150ba,a1f09460,ea855785,96213784,5314b3a1,22da5ece,8f387e6a,f37c7045,b9296927,efd3a3f2,2b95eacb,c6cefc0e,ec40a80a) +,S(1c014014,9027b9a1,e3ce3c28,8f18fa87,12b25a53,49f9ac6f,97af6273,5b6628c5,672190fc,d048d3d6,b78bc34f,f160f978,87b49934,5753bd35,3a456c96,e448a4f) +,S(c2d9670a,1de5e876,5ac965cd,497e0765,8d137400,9e4ea31d,57effe5,2e8d84cc,ff818647,a6ddfbb1,3ab56b58,52956d08,b97a2e8c,f852379,cc7a7271,f13ccdf1) +,S(1a9fec47,16fd6a69,70ce094c,4141d68f,d21339e5,5396a691,e01b1e5,c996ec1d,e38eb2eb,6c8373fe,94f7639b,595de291,d29b8738,11f5d40c,24006d8b,93f8557e) +,S(b7df52ed,15e91a6d,40e9e500,6b1ab26c,53a51466,98d63bae,77856afb,1d8c464,ea60f1bf,d915fd8f,99d0706f,ff180d51,705c360d,a5fdac1,162ec530,b6e21254) +,S(2f95cca,bd092e2f,bdc86a53,40353350,918ba7f8,8488b9d1,295f9959,d7db6b5f,31456814,fe6ced86,59ea9c3d,f09bf38d,d5b0f893,8db1ea7b,5234648d,a1693ad2) +,S(763926c8,64dfe4db,6a1a432c,a37e4022,3b6ae1a3,7def3fea,883a6612,bd8a7c1c,f34d5b72,4378d10e,bb4b3e63,d80f1f98,a3e741e5,b9e4fa41,bd3f0a5,c361bd1f) +,S(2e43be7a,12916cf6,f312a513,fcb6c98b,708ce2dd,18dc4ebf,72a807c9,c8a31b0d,db919224,ce1b7e57,16e57b6c,ed514cd0,a3a9dc09,8cb59c5,971e99d0,dc24acfa) +,S(7d65e48f,1a867d28,76731984,afc6873c,2d1acdfb,13a5adf9,a56960c1,cd4a5561,9c73b955,f0957ad2,ff0e2d4b,caf795d8,bc992436,be7e69da,7b97ccbe,d983ebfc) +,S(1c6becc0,3131b772,cae166f0,4d715390,6b132c87,c5c76b7c,10b94a71,7819d725,2c3c64ff,94998533,97dd26c,dafdf608,41b84a22,cfb4906e,318c4d24,b23280ad) +,S(f5042a5d,5d118102,32ac83c7,d7edf079,aff339b0,7e9d20f8,198b2a64,13347675,19c10fbc,e644fc6d,2f238802,a045052,b2723f57,5a8bdd20,b597dffd,79a3e4c8) +,S(7c387866,c2c0353e,6e00c887,240e084f,e0ee9f0,2de12539,b4833588,bd4be300,ccc66f94,587fc58d,42fc49c6,d074800f,56f08855,6caf4ab4,c37b43,ef2b8f79) +,S(ece8ad23,d33adc2b,6ce38194,58ba2ede,104b35d1,1691f4e0,b7b206e4,eab3c140,eec976c0,7fa1d3f5,f3c245a1,2c9b728f,1c7e672f,53665e7c,5c6a408f,7c0c0a88) +,S(822b0926,a274dc38,c9eefecc,7d021774,b951cf19,3e2cbc56,a1baf58f,19d12b9d,48bcb10a,f9cac375,8314d2c4,9fcf0512,3638f008,510fe63f,1be0c2de,44118313) +,S(d26a3a03,6ef5f428,fa058d25,7ce62fe3,401dfe47,80c468a8,5cd2e77b,f85b8c3,98c39762,3a644329,7d5c6759,a308c2db,62f1bbcf,9bae4ba0,10fb1175,126a6fa7) +,S(7febb81d,8aa0cbbd,3002ab6,ca247d1d,24c8fcdf,bb1664be,b5b3c346,93019090,ee625bcb,12ca6da7,544ca6c0,2a84b9bf,966dc923,d8b23b44,6cfa4604,a6c3ec26) +,S(839e44e7,2d43b6bb,e6f63a75,cc3644ba,b7aa002a,6de2c087,33df2b0e,51d3473c,8368f635,26f41422,a563806,d775bf68,2d876d98,542b3da4,3e591e31,340fb9a9) +,S(52e947da,1c96e07c,9e2c84f3,23f2eed9,7e049b97,86d21135,ea958eac,db0d7afe,6bcfdec9,e0c70d3d,39de19a9,9fa72ba,bdbbe50e,dc44897d,9fa670e6,d473a831) +,S(72ec5426,5e4a743,1d7f6dd7,1c8e9e4c,c8b22074,cfcb00ce,db18c6b4,c67f3603,ddb9360b,7f9def94,f5ea6d71,51eed4ba,49455cf8,15bc9023,6156d4fa,786b5ee5) +,S(370a3f15,59a55689,16bf9ba,f2863d11,2ac051e9,d6a90f36,af39add3,1406c849,854cbda6,8517cee6,95ab5d3,20b1067b,ee80d993,235d1dda,ba3a0ec6,1f005840) +,S(12e57888,60d2fbdb,cb3af527,577ef6a1,41d1cf0c,f719ac6a,714f9a39,9bef5dc2,f5af7aca,5dd8126f,7dbb79ea,d5a4b475,a094969c,64adc821,ab46c5c1,86bd9ea2) +,S(b494abcd,b2fa5de,17b1abad,757bf9d2,8b7905c8,aca0a5bd,fe2ad8c3,30a2b722,c397ffd6,dad8619d,9ff8d8ae,e401a4f8,cbacf710,c6409adf,bf991d72,9294cb87) +,S(2957692d,900d0b94,b208245c,f71bdcb,118ea6e4,499dea83,1064605e,8ab9d89c,a3c55447,9284afea,37e94,fc24d50,f129342b,7ebbaa91,857d655a,40444a7b) +,S(61101879,f325e072,bca13642,dc14a5e7,1969aed3,2e49ccda,39cbf723,a1bd20eb,4e199c82,4816e4bb,d5b67269,e9d8eb0b,e5c2483e,d66757a9,c1d59847,e443b3) +,S(9eea48b2,99f3474f,8aa8c648,c2721fbe,c65f6ad4,990ab4e4,29a9c41a,ba55ab18,13954697,35ced1bc,7e857049,7f2b5a1f,b6802892,fbee0654,c1d7d89c,1f234443) +,S(dbb054d7,8ba7b707,ca475982,6a36808d,3fff42b6,31f1bc5c,c9df403b,518bd97a,396ef6c0,96343a55,dd404885,427e781f,a55a1f8,1ab95d4a,89d87975,611b923a) +,S(dba95bd5,7fdd2ef4,9dbcc0ea,35c14dc9,b2f62541,5b08e75c,d70f3caa,b61bbcf1,2af0965e,b7a17e46,18b6dba8,415159ba,b8f76ac,ae9384cc,64a90e32,d20a3d) +,S(6c312c9,7979bb0f,e72d8feb,c3c755db,bf1a132,722f6ef5,297beafb,8ad0e5be,36366388,db74739d,df78d5ea,3d8fab54,6c435961,71f78643,8be00718,8202c6ea) +,S(65eb7057,a494bc8f,549b8638,e18cd717,ad987030,aa3161e5,b9fe31b6,dc8825cd,458202a1,67f285e0,9196b4ac,f87068e2,160b7b42,2095bc92,7656694c,2fa80312) +,S(a0696917,b0e868da,ed5db7cb,d2aebd1e,c1117426,d842c0d6,b567e2b9,4effa7f6,c874d20d,a1bb4dc8,f01cb828,be8bda8b,c797ec3e,37feb0f5,ba55675c,41ecba78) +,S(4191bb82,19372a13,2dd37830,1086b64d,10874479,1d3b7879,3b27c65,782cced2,c74907c9,8ce4d218,d1ee52bf,82e130bc,49335279,2497b4a,34892fca,67dc3f2c) +,S(75f37d33,721293ee,5923b9b2,b95c958f,945e3f2,909c38f,3c3e7f5c,79b218c3,ac041f8e,c6b222a7,a2f28e18,1cf11aa2,a7d2fda1,1f402a33,9afdeace,a5928be7) +,S(cbc3173a,b58b2f29,20b3bef,6f18a84a,6004d1f7,1dd6c65,78571afb,96fb154e,c413a0b7,6f264414,2d3c166d,e9577ee1,b8f36ec9,618e8892,26de4de0,f9fd5c37) +,S(64e56b09,a139fa59,69688832,419cd1bd,64f212f4,5bf4cdd9,2a5e4370,dae226cc,a9194eee,f2429016,4b41eb3d,b429415,d10915a8,62a02fa7,671bc19e,50fbbbe) +,S(e33795c5,e2886cf2,9a22c2fb,8e02f913,34e13350,9cfc14f,73bcfb49,355285a6,7890fd21,f33d48c7,24e580cb,7b4bb065,f7c575d0,c6cdf5e1,5c2d6423,1afb304) +,S(7975e6b,7a73d0a0,d1543d2c,76c79233,6e6a0994,35eb7699,8f25ce75,a6b0b6dc,10b160ae,c68993ed,d5e48d5f,7562bc24,8f16eb10,a27f7115,121ce2f,f63eb06f) +,S(6d0d13cb,f9c13967,92e093d0,801f441b,c1ca4484,92ce3ce0,2ad71cdd,d1580f6f,17ae4238,84caf022,bbddcfe3,37a44309,4bdb25d4,71da56f1,bae4bf2c,ebb45746) +,S(2195f14a,23af2b59,c9fd3f90,42608037,60d39867,3fbd0856,a974a20,1bdf0154,fc05b38c,9a44ef01,f4db3a10,b500a372,5ff1aa58,86ff6111,da53ee14,f8136a8d) +,S(47679c73,60acf8b9,d1b54e16,7d1dd1a2,1f558288,3844fc4d,ac2a7fdf,8b713628,82a02225,f3b8e81d,e4d4bbde,94f7cd97,7ca0180a,ff3a4751,a93f6ca,17803ea7) +,S(b0bd02f5,1636a69b,23ffe514,cc2166bf,8cb4ff2e,2f7c8655,ac9aa7c9,de30831a,73fad62,48bacbc5,2a7ffc51,fbeba3d8,f4843b3f,ba6c8814,48add0d0,8fd5f518) +,S(dfaeffd6,bfe9f81f,ed3f81af,adbec5b8,aab5f15,23cb7452,c689b01,a3660158,3f54d105,c3ef4814,e6ca4bf9,ccb5b54f,30c4bf80,10d7b24d,f3b5f3da,c9240583) +,S(eb016abb,da661e49,8f53d2e7,96fd6be4,80dffae3,eb7e4ba7,46ae06b,f40d42ed,310d6dbb,aa7659a9,6cd4d50a,dc2e5e85,10f005ed,6d29d1f5,18bf83a2,7af895be) +,S(989e1bc4,3c0880b3,6d35b5eb,137f8e61,7263784c,d2f35173,e517afb0,c99fb2ed,4c4ceb5f,110cccc5,3a35963d,11df77d8,999b3bb4,c2cd92fe,b53b7476,9dfaa1d8) +,S(beb0170,be4a7bbf,1f65bd40,776d5efc,dd801d6f,909250bb,fbee1198,c2033811,1356b98a,1d329a38,57a99820,26d3ce6c,f52349d,fcc59644,ff4dcc13,8486461f) +,S(2d90bc1,986f9a4d,6f75e596,96c4296a,ea9bc55d,5b60d12e,337cb42a,ffc0b145,7d57cf64,734d1997,bf84b721,e67eafb6,b377ccbe,d2ef3b5b,48dc9f06,f71a0c4c) +,S(6b7a6a54,c9608062,de196848,dc3673bd,59fd53f3,fee72481,e829ca77,789f51bf,6a9ee208,157b8a69,f0879f30,c58afbe3,dd4dc42b,43cbf21a,5795224e,6c09af23) +,S(c99244c7,32cbdfe7,68df8fa8,7b7e7eeb,16faf0e8,8870fa8b,f4abcb68,368e8393,20ad1b55,53ba2ad2,40563453,b2dae2e8,58cc9b8c,c6a49951,bc0c0fc2,875620ae) +,S(553fc07b,402a8dc5,5f1cf4fc,609a01fd,350fef26,9c1f93f6,d2871f94,70f01b6b,3b518c75,39616def,fa7cd0dc,7d7d53ab,9b310217,7e470290,9c199137,34e5a824) +,S(c5930378,6ed8a7c,b3cdfc80,a34c85bb,721fa927,9492e369,a4e4bec0,c0fe2f69,3699e469,8a3e9129,3796dea6,213fd702,d7580e67,9f446300,1e1c7a53,3717c149) +,S(cb6f1118,f4d59964,b8f4613d,8c349d74,8cda0e7f,f1d11c6a,79dbecc8,911e7eb5,62b0ae88,98b0d5cf,723cc88f,48257c47,ca0fe3d,7de676f4,cf4835c8,fdde20ee) +,S(da2cab8f,8c26668d,d9722ae6,1decb99c,78b5d48c,966889a9,46fc522a,31a26db9,6a03377e,234f949,4a614cb7,c93b131,1808496b,12485ad8,fc21e1a7,6d0c7e98) +,S(fc6a4d42,3f9be3c7,fe337411,f03eef,fa595b83,9a6eca82,b228d5e6,b43b7d86,6c089544,eb8fbe1a,3dc78fdd,ac253fa8,27dfbd6e,269196f5,bb476865,a298beff) +,S(73c9a91a,b9c6e0d0,773258e8,3ca9460c,3d09fb49,9426fe09,db73756d,e3dee882,8b314327,efc0508a,d5a90259,c9ed876b,52040a10,45d06224,78cd635f,e571d2b3) +,S(a69f061,45b8cd1c,343e6127,14b80996,2bc02848,ae976762,933744ca,3b4516d3,87518d90,b4503741,ec16caf0,18615e27,96b6d91b,47f649ae,a86da209,d70ebe3d) +,S(1cbe4a25,70df40b7,1cddfb2a,c15ba441,376a430f,446a2572,fc95235f,28ed9691,12554ecc,f262e1aa,cf2a2d10,ab3953ee,c8ac69f3,99c5380b,6ef5d202,5613de85) +,S(8dea49c7,406dccfb,4305ac85,ba08b191,4ee2f11a,8827852f,d13c837d,b788e27d,c73d61a8,3b517c3e,bab8b15a,b7a0506c,2b6071e5,697b4056,d902957b,cfe9d9b0) +,S(de926377,b175cc3b,1ecab5af,81d38d6a,5e4b717d,55bc94f,6e4c43a4,86d0ade5,29d5f3e7,9169d974,d4289115,d8d4b8b1,6be387ac,e60d1cb9,73c387d5,17d0e11f) +,S(6e76eaa7,aeb37ab4,ab455a2f,3d525140,f6e8a9cc,5eb18fa3,8a9a25b0,d3b41497,7e3cc5a,78909d15,bbffb936,a47aabd9,44c40a3c,d690908a,89f193e4,95e066fa) +,S(37131ecf,22d57f0d,a662b03f,c9891f99,4678539d,37f5ff8f,9eed0f8,bc607574,c03b2d21,69d42968,f611d596,e173d4b9,281323aa,6abae6ac,c177a1c9,1249f3b3) +,S(72088814,82c89957,28e76633,bcdf0ebb,65155c8f,4979a4e7,66713f37,4a5d8152,6783c59f,8c0adc8b,da8e26f8,1990a00c,588a7974,b48aee92,d2a762e5,c974eedc) +,S(1b8263df,baca44b2,a7fa7a7a,dbf9d3ce,d4567fcd,144d9e8a,db712365,d3241864,1fc7e3e,24f01143,1944b98d,b2dac036,edf36680,80196785,783a41be,d788606d) +,S(7a372de,27ca7f2b,8199714d,bd583edf,ea41bae0,5a1313df,f1a8c260,cef5fd43,a0e3216b,b32c5785,b5c60f22,f5e4ed5,a5d3ab64,ba0eb2e2,916f1b9,b6281142) +,S(71815daa,55254491,c8bb9432,755ac1f0,c30f22fd,79d4232a,72bec0ea,8cd02300,8b341392,8de15c16,5fafcc68,84ebe3c0,3ade0918,4c463804,876f1600,c76471b4) +,S(1a54b7a,d3cfcc64,b62d866a,9f2056e,5535d4c,12c89c78,5d1c5c53,ff654d2b,b7c77ae3,9f4b87bd,22c77395,a91ec307,e9f5aef9,dd2892e8,41d8390b,47a12f19) +,S(85cb4457,1fc973e5,dcb0b695,3d75a2ec,22cd2820,74039987,7262b7ed,999c44a6,efdd1df3,bd13fe66,c0d4ef02,8e142093,58037a7a,bd06ed53,280d3318,9d0f6aa5) +,S(98e8649c,64a010c9,424b305a,2407a36a,cd72df8e,138df962,c35bdf75,fcfd4e4e,a804c569,34395d7c,549f7770,4c3faed1,624a8cf6,fcce08ef,cd3aa486,d5a6c60b) +,S(1eac47e6,a297e5a8,8f433895,874fac8b,5019a164,69c6a881,7e500b94,74a5a72b,8b7daa6b,784ddeae,f380bb1f,fe64b9ed,43a10a2,95c30325,f519e4ae,da11105) +,S(f079ac65,91f27363,17e9e0ab,6a723e25,e29950c7,a02a66bc,96c4ae68,44f42f5,ea87d1bf,c99f4374,4acc3ca0,214a1ef7,490186d0,3d924562,24981469,c432dfc5) +,S(d6d09d79,bf1f30e0,f011c3ad,a077b1d8,fa0d94e8,8683186e,ba471caa,32539643,8770bc64,fac8f541,f730494d,cdad2d48,ef510037,466bc049,876f5cc9,7caa8adf) +,S(376e4bd9,f8963368,7059565,68313f89,d6416ca6,b1e4e91e,3aff3ba0,b8351f65,ba436de5,67248f1d,5e99e8b9,6447cb28,497deea,47fae95b,78a5378d,e65f13f1) +,S(270f3a18,4b42c799,a2193dae,c96f834c,b17cb53,bba1610c,6578c741,b9f20d7,ccceb12b,9ab98bbb,a0fb0d0,1673377e,3a7054a9,f4a3b000,21b67328,57e7e5bc) +,S(ae271b64,1a1e5348,29e47a8a,93b496d0,b055d2b7,fa98ade2,f505a5d,ec1a599,14e9552f,39b481f2,522a9a23,f87afa9d,5847908a,53c1581e,45dfb244,7fc2bdd3) +,S(569eacfb,177d8a74,a9288ad6,4ee5390e,db36a93a,943fd6a2,5ec869b5,a7f28c8c,1cf62c32,9127642b,99a7508a,a6f4f136,bfda9af5,45f52844,cb9c71b,5f732f7c) +,S(77c7f27f,fdc4e7ba,a326a246,89790f8c,41bfb5ed,6d365e46,f277cf81,5f15b558,4d3440dc,138be5d9,566a6828,852c2ec0,e0f970eb,4501a43,25af933b,821c3007) +,S(d66292db,f1730306,a87f67e9,b044fef9,7d46761e,7b8301ed,132ed7d8,94adbb25,ceef7755,8ceca4ed,92145f23,8bfcb32b,3d36db14,6fc50209,cb0e58f6,2c8b83c5) +,S(1c42832e,12ea6f44,b77927ef,7ebb1f3,8769e3bb,f5507a49,25e8565e,a77ed0d6,8b9383a4,b31b4f5d,a717917d,9e1e41da,786a62a3,327be11e,280e538a,9c29d5ee) +,S(63e57eff,942262a8,cc362911,fb98cf30,60832435,3cd394cc,5d6abf77,b21f7968,9e3c1e2d,fb9083f2,4c344e7d,322ea530,146062e2,a25fb6b0,4502ea35,59b009be) +,S(be233fa1,86f38a5c,72c88e59,19094ea8,cf3ed3a9,b4ea3f9b,2a51489,97b83c90,402eb2b3,362fadb2,6e389ef9,edc537bd,40bd48ea,6296956f,efd19d0d,eddba564) +,S(636ddb80,4e7c74fa,9c5f4d06,5a730fce,f2cc6956,4a24b579,aaa0c3f1,61844b78,6a4a3569,583212c6,22feb59,897eac8a,6aa31ffb,916262e7,deef47eb,e6a2496c) +,S(d251c1d1,7250d87f,f7b5af1e,ee2f2566,215ae7c2,b6e69e60,5bdd6c2c,dee1c5e7,245accf5,7df52fa8,cab5c986,2b96658c,5de60d06,c84584cb,f554b518,7fb4ae78) +,S(405d4cb8,c62f133b,7051cbe0,54b06f42,9055f917,3ba8248c,c3bdc744,198ed407,8463df10,a8963cb4,298e8031,bd2bc3ed,523553fc,60746720,1a9abba7,305deb54) +,S(97f05aee,9ab33a07,e14a0314,4fda5be4,ab329394,1ce8f003,546ed8e3,9be983b8,59e62a26,7fd9138b,c4c70b15,533782cb,d321f120,1e3d1a7c,3be4ad5b,eb849261) +,S(3388161,18e125c0,6a9060f2,6b9ad691,c99fdf8d,4309553d,ea160749,eb91ac8,583e918b,5b8e1a68,c053af0d,245a9902,a571788f,dbdc0c88,7281767d,9404384b) +,S(ddd20c46,6bbe6a25,9f706b1a,ddc3b607,8cf65366,3369fc31,dc8f7fd3,3d17a9f9,b2df7b29,b4ea9868,bbaadcf4,6621ccf1,7833e159,acb43daa,7cf78e89,c1de5a99) +,S(923c6d2f,71ae0ee5,596c26bc,31389cbc,eecd0712,e8df91cf,dfe00172,3bdfc9f7,6fdb28ad,27c41243,6a41ae96,99a03d40,5ff2ed87,3207f082,414a4370,34be948) +,S(6d42a6bd,28d57e87,66a12461,b8a7d111,a448876c,149071a7,fde9df18,dca09e65,4df07ab8,1dbe97c,3585554d,f0226234,dcdd2826,747f2775,640bed6b,95fd28bf) +,S(7fd42961,59f9f259,d3c3610d,8539ece1,70efe104,31c9a3f0,4b9630ec,21d761ae,fd695441,b8ce2bf5,1037d00c,4d50e640,e85b6001,6d5d26dc,787f1df1,25d7e280) +,S(48c1050b,128d97df,e7900a01,70559990,944045dd,f408d8a7,5b59bb25,ea6770b5,8f7ceda0,4b6e319c,1cc61b31,53538a09,d450e49f,8863061e,f9b017c1,6cf66559) +,S(54462d9d,a12d62dc,96abaa1b,4883c67c,b3214c40,de5a4a09,689658f7,dee2a686,7673ad6f,916011d7,fd33bb5,eee819e,6a3f0016,d51ae37,bcfec2e,59ccd957) +,S(698534c4,e4e11d89,82a5a46e,44b771f0,95c5fe47,54d7a261,44373982,1e6435e8,36d602ac,b2720c71,8d619a8a,5e7d6873,9faba099,f71c1137,6a8f41d4,e1cbba18) +,S(4493f759,51c681c3,bb376b0d,7c88ecd9,d0bc2a21,26fd341a,d8c4832a,be77ecc,e553e21d,d4d99aad,97f15857,4bfd54be,df7143f4,e829c12a,39109892,c120351e) +,S(b054daa9,330080e1,89784cf5,f917c024,6c06325e,687e6ec8,cf8be248,ccf8313b,51f04715,5c9ce55a,c755f2a4,602420d,4ed52a5a,1dee9a83,b0688b1d,b767d866) +,S(4b4272a4,fa996b1f,9ffe6796,e6519db2,c1f8cfc9,606fbc57,1fe03713,c029583e,9526f2d0,dce7c53d,5cb36f8c,fcbc517b,cecde833,4384d10c,f5fc80a6,ff0edb83) +,S(d61eb681,c69de82e,caed8e64,7d1a3948,6cf63f83,f1f04bff,46a04aa3,63e29604,9b5a92fb,156d7b8f,37c6d9a4,30ae28eb,f62fdf5d,5bf441df,aa386259,721f08b8) +,S(bf8f002,57f979c0,9f973c8f,3dc15eb8,8349e340,efd8d57d,5763e4e0,c2bf507f,561d862f,1041e670,fdc265a8,36d363a3,43346739,f4f177d9,f66414a0,820614fe) +,S(63b254e2,a7a6fad6,4d9ca03f,7293a86f,b471fd45,51ec72d5,eb03e289,774cb498,f4145111,3a4ce922,dc7b3819,a2de49cd,f5be7d53,6befd880,837bbe7,51948c8b) +,S(bae6facd,e1da6ed8,63491f33,c4c9efe7,50fdd908,6b93c09a,e0418a29,d3968725,7c7dc955,e483176,f6bdf74c,6654e6a2,e4ca46c5,2526349b,b4d66090,6ea30533) +,S(f56285f8,ea15aa08,f3ed8139,59c660b0,d30a6317,5380429b,59584623,aceb34af,110033c1,a202194a,40703c9d,ea2dcb9a,d9a0f6da,7b99b8ee,31eb1ce9,55a9eb9) +,S(876c7c95,3de3d451,edb9191c,60e8e36a,eafbad2,198ec6a5,40d72633,8151d87a,95efff74,72ce0c6c,4010d17,7e52a859,cf55011d,1005bd27,df54e25e,972279b8) +,S(e956c7ed,77c7bd5,68096902,4ab1c758,a024d86d,ba3f30e3,fbfd83ac,940a6d30,1b5dfca6,f0d19ab7,7a57a9da,259a564a,5aa5759,ce6826b,45c71771,7aad9da) +,S(f53fde61,abdb4543,1456e9c0,65048cd7,ab743b5a,81a468bd,8fe2ffaa,99dd3f16,1d28b539,47ea22b5,178e86b,ab3561bd,a65ac78e,e0e2a6bc,1a26b64e,d790222f) +,S(b91a8681,52eb435d,475b9103,936a7c62,5e49b0b4,f7bcc3b5,f5d36449,c8043ad9,c758d17,56939bc0,61696f3d,11dd1bd5,722dc90d,1e8be88b,b3430062,a13aaa75) +,S(5a87bc70,23e32927,db4c55d0,abc97536,61f5adcb,b24c2897,b16f08cf,8d8f8cc7,9ceaae4b,aa6a0d5c,46d2120,fbff74b4,9d1ac32d,88a89b2c,3d2aa6e0,6f731e54) +,S(ac0b1b43,e54eb354,3bca80b9,efc5cdb1,215622a8,66b66e80,de979f79,71ceb034,a891575e,5731e152,17bc2b87,197da9b5,439477fb,d2bf07f6,9bd13f3,f4638d8d) +,S(d3c41ebc,2017cd82,76f4d6f3,f6ba2370,e84f1949,df3abdc1,45073467,e85ca915,52ab1d52,8be55945,1f6b1e91,610fcf35,bc1e9576,3ba3ece6,9da5e4d,8cdcf7b7) +,S(68cffc57,f4c82cc6,f7900d00,fe1b0f36,ab842e4f,49ee9063,4d1ebe95,47923b02,729955bf,aac10741,c3fda281,c18a306b,367ba904,baed26b2,6fe6a485,9ab1d8e2) +,S(7e0f58e1,246299ee,e08566b3,35324a66,579dc765,343f874c,d30f2553,8c177d9c,39652583,587293f0,809af7b,5d366740,86b9015,6a05928d,cd340196,8821447c) +,S(c72abbdb,d1816498,eb53d4bf,1b325fd6,5dc45086,73257bbb,97a15eb8,e4c9b542,3c8fafa5,5df5f3d2,88441ed3,e46cd318,841a068c,b681b782,88e77afb,2b25a7b9) +,S(74747f5d,3eb09144,1f64d76c,ef690378,943654ca,73fe15a1,b720abb5,d2363d0d,12c6724,bc7e8f7,321f993a,5caf0547,bf54c1a6,41f959b9,746fad7c,1c443649) +,S(f2a702d1,ab1de7c4,34cb5d71,dad689a9,29db862c,d1fb06e1,212ffc8f,91b67067,5b91e2c,c730ac9a,cb7452bc,7fb4dcfb,1d5ec11a,bd146429,62c7bd16,37afd854) +,S(a92d4f08,14e76b46,5fda87b6,201c46e8,c2535b3d,4be91e1b,530b5634,d00d9340,4d829a8f,3c02fb40,569fd9bf,e754dad8,38d96dbc,2350f0be,6f4ba065,5cd0277) +,S(79e30cb1,ac06c3b3,f90ea320,60a80fba,df5ea142,84a15746,2aaf917a,26f205a1,ad220a0a,81459495,5ac8a79e,d0cba974,7f17364a,9f6168d5,3521f276,c8d5c82f) +,S(6d55dc53,d412577f,463252b,e240fa32,88c8d6a3,babd6ff3,20231b6,8c9401d1,83a41c96,aa3b32c0,59155345,2679f056,c98e17c8,a0a5e154,d732fd3,7b006eb3) +,S(cf9c9f1f,604eb909,b37ea5eb,4cb8a0c2,11ef14e2,d3e2f48,7c83b56a,49b3f20a,2b90b9f6,4e649988,77260b5b,ecb441de,da24eaf9,df56ff93,dd3d1c8b,a247dff8) +,S(60d4299f,29ed994a,b3367780,9ef6fcac,e30f435b,ba9a8346,a2fd925e,186b35dd,df69b88,b8aab4c5,8ff86ddd,2d8e424b,40d51a4,9d189437,37b23695,4760331e) +,S(d93a6edd,1b674a60,6b6bbb85,4114a3bf,7de3be59,82cd2122,887c5376,d9493540,87da37d7,dc79197b,c0159006,4f921ae7,acfdb08c,447ed230,423c51bf,f9e5f7ff) +,S(cf8c3d37,7e108d98,b72bb6b3,1cb7b5f5,fd5869da,1a06fc60,25d9191a,bd652962,6f5cd02,bb96ad02,db42b034,321b3cae,fc54271a,879edc93,afc9c8b1,34128fbb) +,S(6ca99247,4637ecf9,827ab65a,c7b9ca0c,715b9048,f24c42a6,90847e68,8cdf29eb,51378da5,fefa454e,d96a446e,dab57c3e,8bb6160d,d015c1f6,d93983e4,feb55439) +,S(6f7d2c04,3cb813d5,dea67758,cacf2e3f,3cc3064d,7b9f08c5,58ed686d,28d17afd,4794e278,13ecec48,33f9106c,17c5e161,b590a5f2,ac293c8,c65a6cc6,5233bc6f) +,S(f8aee0d0,bc9883f,ab6a82b0,184e9199,e818d01a,7d99f475,d2ca8a24,e924f3e1,acf9cb2b,69135df0,9426bfa,c6b1b3de,44f1055e,5cd21b8a,b526f34a,839442b5) +,S(8b00fcbf,c1a203f4,4bf123fc,7f4c91c1,a85c8ea,e9187f9d,22242b46,ce781c,61e9e58a,3e81e690,ec026428,ee5442a,a8de699,dadfbcac,478985cc,89d35bc9) +,S(fbacbb07,8e84a2b2,c201ebbc,1cc3212c,a7278523,e984bc1a,b0eb7fa1,39d6dd4d,2c6c9dd6,f5eb0899,797df675,ccbbaa25,4e557d5f,d16c6083,3aa84a7e,4c3a0f52) +,S(1556875c,2f32f053,8d28f993,53ba2804,5ba601bb,3df8a175,bfa33dac,ac5c0611,53623050,c3da9464,8e9fb540,5888e387,d2eb783a,10e45cf8,ebaafe84,a4e240b7) +,S(b602b095,7f5b5e98,ce3e690e,c683f803,49a8ced0,5985f79e,2e972bb0,2d93d77,78868390,ddd6b821,e30046ac,b1bb7b31,ff358838,af5b89d9,60d39b4e,85435227) +,S(2a110165,23a5244e,89d66f8,a06f0553,7a846216,75fe4377,24f51501,da2dd17a,24d3b525,e1ca62e9,b02de498,30737f3a,b881d078,7d2c2bff,938c53a1,b8825159) +,S(7314759,1148f9a9,ce326a8e,4f43d2d9,a13edb92,56fc9d38,35a35da6,457efce0,b195cc94,80d0aa04,d3ac7cfa,45766472,1ad5adf0,3060b790,c7fb0ff7,77b2d8b3) +,S(a36e4fe4,c7e23d7,16362979,c5a9d8e0,525d864,37d96e3d,b2f45edd,b36206fc,56ace785,a428db4,a8a70de8,708339a4,346699f,697a6707,c745635e,66844751) +,S(97864be7,a2c54118,5d61b61d,5a2494f4,85b877d7,e8864402,3444d778,f43cac9a,43332a78,a85b8391,551dcd90,e93e71c,3a6c5428,71b980ab,138eda2,b9f2ff69) +,S(34a52dbf,2449eea6,da2c92c8,45dcd47f,daa7ca41,5ff02458,b74eb996,8519893e,add41829,900f26c9,f7ba8d55,21f3bb23,b3545a35,699d41b9,4270547f,e303ece4) +,S(e250aba9,94eea617,5fb7b2b4,8631f5bb,d8bdbbb,799f6fcf,5afde8a6,2ff3d629,803f34f5,9db0fa86,bcb6fae,689530fa,2e92c4ec,bff1757,409bd836,8143b0ea) +,S(18356a6d,b5946e2,1149347a,4558e116,7953042e,e3b2a372,869ae29,b871ae00,56ef0971,6b176f81,e1f98ec8,dca127c4,ba6de23,ba8c1f08,f19e9abb,995385cb) +,S(35a8ebf5,e5306084,365ef3f,30c29e56,ca5932d6,f73d688e,ed3cf2a9,10205533,9eae5d95,42954de,23d41032,5ada759e,20d30fd5,c2d058c4,53a18520,7f259958) +,S(37e06f5,25ea8fe9,ea862b92,53a965f,7b3dbe90,9ca487bd,a705041f,e6a4e1b9,83919fd3,5e489bea,23f13b60,41a19940,3f2f6568,fdcf60d7,3f57fb6,1fceb97c) +,S(abbbe697,ac6c002f,11062947,6e4a6ffd,48316646,718d8713,1a4dec19,5e131c27,b2c926cb,9d5122ff,7f8d8a24,a20eaf4e,fd704944,9aa48300,92971572,b12f9dcb) +,S(4df36acb,1484dcc3,f7c29c8b,78915315,5a1a3636,aeaca043,68a585a4,69b05878,fe16fe6f,c08af026,3fc417fb,19564534,aa059f4b,b7fced09,d4fc20de,6a41c41d) +,S(5ff14ee3,10256a0a,889570e5,ebdaf6af,c8f49c60,dc7c4731,23a7d29b,e799d0d7,96ff1538,55eb2fac,8f2a923e,ead9851a,95382d6c,56cfd0d8,9891d2bc,f7e65d7b) +,S(16a12c52,c1d422f4,791281a1,b7ab7186,a24dbac8,36af6810,4f62dea2,855d119a,7a6ef272,f67356de,46996cb3,8bbaaba9,d36a4bf4,60e3b2a,b3a81723,24c17478) +,S(8f4c9c33,83688920,a48b3d15,4fd567e4,5fcdbac,bea44eda,60600ffa,a1489ef5,2bb5bc4d,e06444c7,b2bc0082,d629e2e5,a4b0abd4,8cbb9b4e,37d564ca,db885717) +,S(498bf39b,7547010,854ca399,e50399ca,19236d2f,d05f5777,6abd6d2a,aab83310,8e2debff,cb58e36,bcc7beb5,8a45d4ba,b5edcd46,2c355d0c,4dde51a6,6afd691c) +,S(78147e0a,2978d396,b22247d1,74958336,2ba51d90,11e89c11,71e6e136,eefb5996,a66b7b0c,a73b661b,e71bf0fb,2eb4410c,4c75bff5,b8b05fd4,1d830d27,ff85989) +,S(351298d9,fb236c7e,5477aea1,d2df0048,47e112a2,e16adf66,3f4d77dd,828d4927,6c9c91af,8b6f23a9,d15c3884,e618ae51,241094d4,5878ff20,67f2ac81,dcfe00f9) +,S(fb5ffc0c,88fb609c,24cffc14,848549ad,c1814668,9e5f8a67,a342bcbe,16399d10,a995e13f,9ced94cb,90feff32,8e92e978,88cf5791,c885ca09,46f46e5f,b8229ab3) +,S(8352b7c4,4cc09c5d,717bd197,40dcaaa0,89565e94,77cd76b3,6c7a4fa0,4832097b,9507c998,fa25d9,758ca78,6774ae68,f91c8fab,694c5e23,6f8af6c7,7d0fe6bc) +,S(1be65c0f,273a2746,d6d014d7,6bb1c595,5d5ed1db,62ad940b,d8204115,85919f4a,dac98f30,2a38f839,a3d470a8,3ef83ae8,f044e93c,80b23552,da3da359,5c09a3f2) +,S(7107f3a5,2f4be227,eeb65037,ae800f64,8de14d89,ebf743a7,ed65f98c,b58418e,bfcf1c09,bd1af327,d14e429d,18eeae45,927b2df2,aa15ce60,69f6a74a,69fca7a4) +,S(117284b,e8edae5b,1ce54a13,3b1f9d98,983389cc,a4ccff,9dd04973,97312e3e,91e48c1e,724fed49,8bf51999,4c84d0b8,84e3af77,86e61539,638b45c3,8212b03d) +,S(a08d86de,b1ff9ab4,651f1cd0,d89b6714,41c243b6,c7e655de,d31b44a7,b00de54e,4d0fe7f6,344d39d1,57764fee,f74cc949,a72ed8d4,c2dbc12c,ec2629c,830f0d2f) +,S(9c44c1ce,df67418a,eef2cbf3,68d48a08,98cfc633,de711550,3f78ecb5,a4e8c25f,3cda2020,86d3f096,31da959b,9f9870c3,de3d3c6d,e4c1b35f,81f64dbe,31e743fa) +,S(d933e475,5215c065,bab118da,6f24d714,f8597949,a52ae319,250338b2,2339f149,5fb0f28e,313af04d,de3abfa6,4981287,e277e39,d2f19dcb,547d6fc,88baec45) +,S(7fe1f197,ddd0532c,a2010528,9f243bc6,4c2f9e53,65aad5ff,63c0f1d3,188a42cb,813b133f,a1869218,ee361828,6561e75d,a9ec6bac,6ba2ac7c,d3f5678f,fe472af7) +,S(e3568521,89612102,7ad0789c,72dc6d57,7ba412ae,b3d7551a,96aab952,c507f79c,7645c505,8e2ca8ac,ae5fe225,eddf4d45,7d820114,cd5e69a8,4966465a,423e3a30) +,S(c56afd46,8a5644a2,abebcefc,3b6a9da0,c667a183,b822780d,146ecf82,b6ebece4,9e41c655,a80e2844,89fc587c,b686549a,2915ba14,1c691e75,cc635f9,54f1a8d4) +,S(b242eb39,60e6a8f0,73b6042e,1095f0e1,440f9f8f,d1abed56,ad1f26,a1589345,944da76d,f063f0a0,3602decb,696f2a34,378579ad,e8469ca4,bb5041e5,876dfde0) +,S(3a52fd66,6d2e2e2e,888a43f2,fce68703,78f835a6,b5c3bd42,af57b107,323bb827,12e51177,a7b37a46,2755cea0,18f4f29e,96c7d6,d0e434cc,4874da99,a7af91c7) +,S(b77d5615,c8831ad1,147072d2,598a8c6b,4a71c0fe,967a6cf,70877aea,24d28f53,25d5b7cf,a068a665,deadf83d,5f793605,f5cff2c3,36a8d176,d18c634,9ebf3132) +,S(e4420c3b,61e435a8,53784728,8426aa27,f23d224f,4ff7a14d,79898369,c08530dc,422b04b4,857984b9,9bebd74e,1588ad96,9b3c67a9,89b119a7,f7cd2c84,ecca8572) +,S(888bfdbf,c6ab299e,3ba0fadd,a614fb01,236e3c44,98ad07ce,cae08105,630aaaea,86e7253d,58cfe580,628fb94a,a1a8f40b,7ada97c9,d8713453,f06f4773,3770eb3c) +,S(f74d258b,f7d78b30,ddbde398,a1398164,d850f2d,48616cce,8ef4c436,10ef419c,d13d49af,1e6dadfc,94332213,cbb12d32,5d60eb6,d48cec9d,fcaa7ff2,53029204) +,S(a8b33e90,98d60483,a7009786,11b92257,65cea0d4,b7ac0ae0,67914110,5cda6df0,58cc238c,c08d957b,1172598e,96ff4762,1182b6c0,652c9ddc,650f3b51,3521c553) +,S(5af8b154,7477fad9,8e5dbbe3,d4a1a15e,7a4a6cb6,5ae13cb8,9699470a,1a3ef1ff,525ed201,d0c61832,36c8fac1,366e8173,3c0a8c15,b6ef7672,cc84b1a3,7d6f25bf) +,S(155c454,6d4c5c4a,21d14383,3df8662a,fa71e665,ab7ff0bc,8119f29e,3bec21c,20e99f67,2f641185,cdceaefe,8fd7247f,63842282,edeff6d0,378966bf,50411aae) +,S(53918586,ee182d66,e7c22aea,5a663770,c8fd7f0c,6738d473,1010660c,7425a56e,c7fea092,3052ec1d,7e2564a1,e70b8924,cdbf727a,7212052f,abc58d9d,1856152e) +,S(f7964dd9,a0fab716,74804abb,a7740f4d,cc52d7f2,8d5acd4f,67998bba,3bad6414,6a989f64,aba0f60c,e7bdc5c2,aec11de6,d469a122,f1bbfccb,31cac834,89f62c59) +,S(741c8c8a,f514f2de,7880a909,b327c6ee,ffd72ee2,b5b1658e,72059edb,cd663183,f35d276d,e5de1460,dc53532d,48afe736,e40b6b31,fb6fdb49,1224544,a487b2ae) +,S(de8c69bf,6cc2a28a,fc6ea9f1,26ef4f22,606e55f1,312177e9,b2ef8835,8b47945a,8de62853,6900d614,780e2fec,b4ff7066,70d84742,3b1c852c,8b85ca4b,40a48a02) +,S(81e16f39,619bb41c,d8a523b2,d3dd0135,d6a8d5fd,9a8446af,cd058ea3,6f57c537,6786fc73,7cd2ecca,d146de9b,951deec4,375c434d,7dbac32f,2395c265,bbf4b31e) +,S(459e9589,d079b22e,8c5625b8,a725b30a,e70f7f04,8ab21a20,f0123aae,7a6f988d,a56ede93,5b71a292,c4ad26ac,cc3506cc,915de21a,4557512e,e767e8c4,33f38e08) +,S(b079d755,4faba7ff,20818806,a70b4ead,f2e5bb51,d1abb758,2284f385,868ebddd,495ddc2d,552f174b,210f6577,3e434fa9,20b6c0c4,574601dc,fcf5b701,fe74dffe) +,S(75391bbb,5983fb21,41580de1,dd5b10b4,bb30af17,3f05c100,569abd2c,674f288b,57c7a6ba,c9154ab9,eb66032f,2135a52a,b319f534,d1f1c80d,b58a4af7,de958d67) +,S(71436957,f2848f75,fc461069,e4fc691f,5bda94f7,32fcbe7d,5a89e136,41524db4,1287f852,ef4fadd5,65a2813c,51b93c81,95658a5a,5cef224f,e92511db,df3f0007) +,S(b9038b33,fa75d097,dcc74c9,e25970ec,94ad076b,7279f785,3b7c98f1,41543f9c,a28c3169,69295ed0,3fbc1bf4,8e39c8d6,af59cef3,d6f66660,73470ab0,dbcf838e) +,S(b2c63c28,a9fbd900,fbc664e6,36dbe0cb,f259bdb9,d67c34b0,83b8af17,a5f86196,a8f050fc,69c63c4,67308421,89510ca5,b7920723,6f5c12b0,ee7103ee,cd49ebdd) +,S(cdd2a5be,a32b2195,f4a7edfa,dfb7c785,d06bf346,f38e928a,5c92cc7a,2417f39c,ab66e78,ac421c36,3203ee7,22b380ae,2133864c,83829f04,d2daddd6,b7fa621b) +,S(825d0864,b079a737,acef03a8,28838ec5,a27d740c,724f9c39,780cfa61,9f3db80f,bf3ee8b7,749e44a6,7f27e427,fe05eba5,c2154fad,bc2e2b43,a877219b,461071d3) +,S(37b79e3c,bf6bf402,c96930a8,79f4ce3d,d0c36477,f0b0e218,608b890f,bf5e24c7,d97142c7,cec5630b,a090ff4c,9213c2f0,c32a5bb2,f7b0ee29,2045ad03,10f66f1d) +,S(fba64ad0,678ea75d,409105bf,5b452ebf,89560b0e,fbb079d8,aed22c33,552b6135,e665362d,e4e637a8,a85dd844,1a806ad7,5c628f19,7d6dbe3b,df63c0b2,d1f938c) +,S(76787b8e,77ed36f,9d84897d,e84c476f,d3bd490d,184327a8,59ea3f97,ecd9cf72,cf79f14,1a3f38c3,cc126011,d1d78dfc,e3ba228b,33d64158,210cd942,3980a9b3) +,S(26babdd0,ffb3a334,85e6ba1c,5661a551,f16a129e,42f9fe8a,3691a50d,157b31,1b3a4ae2,b1cf1a46,fb666e33,a20370b2,e66a6c71,27edc8ee,e4c4072d,8c2c530d) +,S(15aedbb7,7a2fa1e9,7a6aa864,7729f28,7ca4d3f2,36046008,c1b031d6,9f76307a,3342a142,bf8b2360,6a574643,9c05f36b,f9408878,5354c788,a6dcfd96,ff073649) +,S(98ece0a3,9bb7cd4f,df4d5767,c6ef4cc1,c2b072a0,dfde5fb3,de100f57,466fe467,c4e924a8,218c93e7,eb829d0f,839556c6,1e679d29,6a0a6bba,6f4f463e,ab227e28) +,S(7d867505,fc213eed,4cdffafa,b067bb71,8a48cda2,fb323304,1989b6a8,3ff373a9,5df51ff0,3c212078,197c417e,f4a4014c,96e167f8,8cea0c1b,9199ef75,7c97d47c) +,S(f24f19d7,43578e1f,be3ece8b,7b00d5e2,bf269a48,9d76d17f,410b73a2,95b3001f,644a43ff,55448b66,7b048bbb,b34f4c79,16d2b547,5148020d,53e53627,623631f) +,S(93853304,5c22296e,1e911281,ed4bea22,1fd1061d,2039a27b,923dd3bc,800efd59,22988cf6,cd2d15,f799bbf,e4cc905e,2607da21,e9fad162,8c2fe699,8beb7040) +,S(f090c705,39834f16,253b14ee,8e4d2685,b91ff4ec,9897df0d,af1531c9,46319743,c1171885,1d30271d,a8a08391,f53a02b6,28c59c8c,9af3ad2a,bf158341,280bd522) +,S(e8fc8ec,ab5bf3b7,4a0234ae,b2a8eafc,df9bb08,a90078e6,7fb6cd3e,fea78c6e,b08165,34ce9bb7,46efcd71,362e0a75,a8397c0b,490e75c2,9b007b28,26ddabe5) +,S(46258cd1,87cb43e7,3003cef6,94af37e3,c7426dba,c8033aa0,9b0a0d71,9f126785,846141a7,5f060822,764dd82e,2c369821,75576ebf,7082c6d4,601ad237,55ad4fc4) +,S(e7f38b3b,db3887ef,529d27c3,f433410b,94109bf3,45f9b7a1,e65bee6a,cca3e430,f52440f1,5eaec702,90adec0c,b07e8ac,ab1fafb7,adbc8f81,9fac349,2acd589f) +,S(2d29e833,1472798d,75fd5b75,1f569da,fa9a0167,f73fc62e,da5b03a5,2f537aec,52d3dd1a,b117b9fa,a17c58cf,c0593603,d9e2f55f,5a230001,d18976e9,792d2be6) +,S(a3b2ec9c,abf7a7b7,77fb44c9,c7552dd8,f47609a4,6f943c7c,8ac97d1c,3891ffb6,6ce38c70,f091381f,53093385,22a5ad66,4d528061,5b01b417,d559cbbf,3cfc19de) +,S(afcb3c1e,7582a56c,e6504dd,ab3d1a8e,6cefe762,58543015,a21f65d3,3100f473,6baf1f9d,fbeb8499,8a6afc61,8e193103,67edbd87,57b2c4a3,8e5a76c6,8b171af8) +,S(88b2f212,dc899567,bf62bbea,9466a8c2,6650f74a,490b86ec,cdd35625,d90e2ac8,73fd757b,def6153f,d7f6d4f5,da1723e2,6ecd6c42,d994a08e,7e458a64,d18c30a5) +,S(bfdea9f,4ca32916,651c971d,7da6a2a7,395c5945,5c4940d4,93d991be,1dadef3c,82747044,7ef3f684,4200adea,5b8077cc,4166bc65,1f6d4a17,578b64d8,21bc20d8) +,S(5d45cb81,aa765d69,ca52e386,9491ecf0,e8fdf6a6,3d64e65b,5213647e,e4973ae5,a4a4a32b,51a76d77,773517e7,c103a7dc,fdab36fe,3cafa2bd,b17f82b1,2fd019db) +,S(f3a503ce,e14e9994,aa34fa53,1c43e5db,6d6fe092,45d2f3ae,87d06753,7ae7109d,2b1714c0,a24d50b4,20722daa,d1951b63,568aa5ba,7325785,ac555e55,f3ec49e8) +,S(94c3a76d,6f812ed2,454c225e,ab8e6b8a,4261953,37d1d2d9,b666ade3,88cbeeb5,bb89cee6,aa406746,dd4893b9,5bf1818a,3d1351fa,d66e104c,bc8d63a1,efa953e3) +,S(23dbfe81,5232403,39d5a662,51fda5bd,b9a2d3d1,181dea3c,c0c908c8,f0f4c050,caef3a71,229f10ef,488f8385,c79ed0e4,b5c16899,d40ab679,4e45b84b,4deae6b2) +,S(3907e3d1,20ef8619,c11dc69d,c57935f5,d2dcbeca,1b4bbb88,e4629ec6,acbbf1d2,438f96b7,d74e2b9d,cc17b0a6,c936844,e6aad1bc,58a20055,ba298446,1415e853) +,S(c140b19,3eeb04fd,80aa6a37,3407f591,651c944b,33788b71,e6f05e1,672b7d9c,949bfd15,59e24543,9d5fef6b,70763b63,899450ef,430d2e64,1f7077b9,29e44072) +,S(977cf05b,c96a39c8,1dd2fe26,930f75e4,2563c3b6,b06e28d1,740a547e,f2ea56c,3802e3a,8508164c,36e95e23,46ca468b,7e15878,36a9edc0,e70c0e6b,9aa10d52) +,S(1069c0d6,3995e0d4,cad51e5a,9e4e57f6,795a7bb3,9ee3c376,1e827b20,d8a034e3,e1aa1487,9c0e4c65,581d89c4,7abb5e48,47963aac,788fe804,1d2c194c,5a7fe33b) +,S(ff78c680,c3414181,ff3ab10c,74e2a755,42419af5,3527a45b,ba3825b3,c93e3682,eeb70adb,f05390f3,76b2382e,20b2dbed,86c8c574,df2f256e,1fc4a376,24d3615e) +,S(5ec9eb03,3acd3d6a,9c04c3ff,5838a6a0,2b0cb26b,d5c37d05,9056afd9,86bcddc7,92a287f6,eed0df0,17c0bed1,ed9445c3,e39d92b4,8c3a9c8b,9ae26749,732aff03) +,S(eaa206ba,792dd34b,7ee67e14,d8dbc7e8,bef0a54d,a7dc7ee9,339d8ec8,471b37d1,5577e65e,be719ca0,7fef2530,c40c1617,55e00d21,1d78e5e2,695107c6,8d1ee92e) +,S(26d062f5,6034012a,3d76789d,455cefa2,689ef08e,d3d87f54,af952afd,ceb3ed7,5eff1dac,ef6f5877,99c340c5,f0d1f6dd,dbe6faa2,5ace9109,4e7b5836,d1323424) +,S(800d415a,e50db62a,4f49e449,d11eda8e,1a2413f9,c341bbd1,492f2271,1e602d48,569cad6d,5d19b5d,2299ec5c,fd12d9f3,d5c8cb0e,756036fb,dc5957f5,7c02eb50) +,S(6c01a352,bc16dc19,973aaca5,f1a21676,e1531fbe,f8586bb,9853c627,9c9a1c90,833dd742,c9596a0f,2767226a,b2548139,a39a17d2,d64d6765,4c073b18,f8cc04e7) +,S(3accc922,f1b3ff0c,504e7c4d,4738d1ad,f0b914b8,d08ef8e8,a54e431,37742c26,aa9cd483,27d60b34,304dee26,c52b2979,52a2d118,82e10b17,86a09acb,3cb0ad7) +,S(a0df5c72,828b73f2,a380f75,3f8e6352,f8d978c1,ee6ebedf,2ec70ff1,d0f8ec72,b230adbe,f1e0bd13,1e622689,379e7232,b1327db6,eb0ee306,80d7a89f,a4ac6670) +,S(9d5f0d94,9776ec98,607a8dbb,d54865c6,d4bbc970,d3ff85a4,49d57b97,33b52c73,ff08efba,f4893add,54b8a056,ff60d345,ad7faf15,7d11acf2,2cea0f2,afc1a8) +,S(def5d92d,9ea1822e,dea5b293,58a51ec8,228f54b5,a6738917,fb7f2108,6dd3d84e,b6c740d,b94aebc3,138d3ad0,202bff37,9d5bc20a,d7c0307a,479599ee,8b3129) +,S(fa90b105,cdc8d74e,3f87136c,f4d075f,643fb0f1,ba6eb832,73642e65,84df33de,3e6b28c3,73f58eba,49e9e852,f0f0e244,3a180d92,52624c27,3c079dea,50bba36d) +,S(8212e821,ff2f7b90,c01c8461,3d4d9df9,ce077cb2,9706a349,575b8cd1,a3d0eb52,d59c05db,2fa3e756,fda56e8f,33540639,d24bb5ed,2c8aeb5b,8f8e43ff,703185f0) +,S(ee340cc8,1d1f71d7,4b1a641e,101d15e5,24f155b7,2afb4e49,f9cd8b20,ec61220d,915d833f,25355fd7,f1efa796,4a8e8b04,86f8141e,f5811438,f0083382,ae286f37) +,S(2c535525,dd2e3d83,740b257f,bb7223e2,302b5009,7f8366b5,aa26f65,442afee1,1cd4514e,f945b668,4f38f966,2f3b5402,92d43a79,7f73f947,67272713,b61cf765) +,S(df7763cf,8b57a288,cf4a9083,a2a5f977,404b9e1d,6e814f2b,aae9ad45,fa67d94d,4f7dc336,31fdb48c,612276bd,d388ee9d,bf05295c,1a92709c,b4fc33ac,b1580ce2) +,S(3514c240,d6d0f218,11374b92,8cd6d063,8ff99b8f,4d5e4da1,8fd126a0,ecdcee60,2a0d1f4a,1a1baf80,3c98421c,7777ed1a,ac17abb2,720975ce,e530a5c6,4197fca2) +,S(3de75d9,e58bcb81,94dde551,ab541d54,237a1b58,d935f60a,b54bd3c,6ae40a27,9ada14db,be2db058,c6bad8c4,86f25037,3ec422da,fdd5bddc,455b2b8d,25d97c75) +,S(a728ce0b,1804355b,c5c144f8,1d5eb1c2,90ad3d52,f502c5dd,ae28a08a,6de0420f,4387cca8,f72b51a0,cfb4893f,a85491fd,42cce3b9,ec3344f7,ac93d001,47ddad3d) +,S(ec3c9a8a,5b844c0,947b22e0,2503a815,1d8234ab,aa94032e,16c1d874,5551c39b,7b08bcef,45f0fa93,660845ca,44edfae8,c8ac51ce,e836b043,3825e410,8ebd7fa6) +,S(b0173d56,24945acb,3bab7e6c,617532cf,e619e7cc,e9872e93,26a8ec55,a24761db,78d27b5f,3e9a0761,d0feff12,198dcb11,72a81df3,1320f10d,44591ae3,5f1b381) +,S(d9eb3bf3,cd43dc8b,977c3890,ed3a4b8f,4e04bd11,f95963a7,970d9600,40cd73f6,98196b5c,c42e808a,3f1db718,98c50048,510b9e4,c9b69c41,e7f5b2fd,63b23044) +,S(fbda51af,8a40230a,c7602606,21f92b38,29bbf1b0,1c027f10,7ca54c08,65a84e74,64833994,aa453bd5,4c8729e4,e9010fcb,8fd427ba,3bbe7c71,e812513b,fcd6ccf5) +,S(ae4b9a7,51be1966,f564661,61262faf,472b14c5,f0532cf8,8af872f,ba583f9d,8b2c248b,aa9d7e5a,6f0c6eed,9ad3ab5f,e2bd4078,da4fa281,f4b672e4,9695ee5e) +,S(58040152,6088026,1668c6a2,e462845c,f29764e0,31edf6dd,a40b6e0c,4ccf6ff5,d2f96ae6,4a83c04d,a072f9a4,e39976d8,a2e5f88f,fed070cd,5fb1a701,db329485) +,S(4c28d686,57380f81,639abbd9,fafcf47f,cf477e26,1c46a03b,57ca7326,4c7e029e,694b8a9c,4fa75e14,56a67e8,acfac16,3122a941,150da022,59fb024e,ced8a70) +,S(de205ab3,9e005587,f23b51a7,3d806f81,6984fc77,7179a6b9,465a92c,ff25c9a4,ed84325e,12efc1c2,db42cf1f,eacc12c,48f68e42,9aec9135,5af5c327,c5273d83) +,S(5ea82868,c2cb0a7,4b658dd5,721e6571,b968f589,6d22a5f1,b3ec6b69,594273f4,88d10eb0,8db264f8,13adecce,636f6c58,e1828539,1e538ad,6e2237d2,384a9499) +,S(189cf7c8,64497416,420bd98a,3e3db4e7,c3b0dd46,d7b9bc9c,37f2d036,324998ba,bb3409ce,d46dff28,36601b1c,f7dd606d,7422118d,723f7da2,4d25802,1edaa083) +,S(70a17187,38f50d43,8868026,58100245,3c3c41d7,8ee5e14d,3cf536f9,bc82789f,15c95120,e112537e,41f33870,18f09d1e,101dc445,a9f36296,2b9462d7,bc27c1d6) +,S(578ac0ff,622adb6e,8c20eed,f3011085,8e4271aa,46833865,cff46b9b,fb3a368,f711a1dd,f5f3172d,2b9b2f7d,9d50818a,6b0ceaf5,1d67e15f,1f01ca5b,bbd7f851) +,S(dc9fbc03,476aa747,d64738ba,ddce8a5b,5887f177,fa6cdaea,3e3b05e2,8d840071,c0f6752c,8087dd25,f8d94a19,d294e550,8bd26774,cf4e7ab9,515f0a4e,89eee1b4) +,S(9749acff,a348cd5f,2e84dec0,b3d73151,4bb817dc,4596d78f,e0295215,47b0294d,df667dea,35e54810,daeec20b,e0e7d203,d89856c9,94501167,23de84e0,5781a1c6) +,S(e39fbdcf,2fd2730d,c3359f21,fa815478,ae8e7a98,d6b132e8,e92d343e,32657d85,bafe9881,70a78596,76a6ae3e,364885a2,62441578,8c31c283,20a06b0b,e5b5e01c) +,S(6009014e,27f13712,c00bda4,dc913516,e04b692a,ea32b89,e0fab8bf,91402c09,34910894,f6bd1cd2,cb796f58,8ddba661,eb4006a8,6cec32e5,7086099d,42359f6b) +,S(bf04f247,d02e46d8,2fb9bec4,f76b3eef,b644c92d,43622162,d419488e,87f2f773,d646f4e8,bb3c2e4c,f19ab00,4674e354,302e125b,c1ed684d,32b1cebc,7c2172f6) +,S(9609f7ec,b122b353,85871efd,915c6d99,3e5468ab,c30e9acf,f5b4dfaa,31e5e3c3,106bc52e,b933f0b8,71578ac7,74e2ad89,ebb4d9f9,eeb95592,5d6b50dd,988f9a27) +,S(b690cc3a,e1ebe25,a07440fb,5cbdf56f,f5ae581d,4dec7366,8da2ad62,bab9abe,83cd0023,fd3a3ddb,2cda9603,2b6c1657,35e5f9f6,249a535f,b9666a97,e049dbd1) +,S(72da508c,ed507744,1aa2bc11,4a9098d8,2c947948,395bf38d,6cd00977,91d326d4,165baa93,3433ea2b,e978036,4fec922e,e5d743db,b8117e09,5eafb467,3f668457) +,S(e0fd116e,540a3009,2954322f,5125a72d,1133201b,985d1017,29b1c9b7,a9851c37,c6bc7276,48aa707e,549e899d,630d3155,a516a06b,777997ac,8509045e,e5b88a92) +,S(9d4b8bea,85d4e412,ee0d6389,e883f9db,297f01c,d0695c13,abe2b682,94c10af1,5e2280d7,3f7c0832,d9ae62fd,6a884973,5bb66ebb,e68a38d3,8a95258a,97556181) +,S(eef84395,aa4b6e04,ddc56123,cd5eb31d,69f1255,1c216d25,5057a2d4,388e08ff,45098aa4,34e14364,40d8b26c,73179c48,87797e6d,59963928,b1d6b61,d62d2376) +,S(66fe5c7d,56e38e48,6134371e,76ef427,b4652daf,6e60cde7,39aa1165,c90d7654,2d72926b,b6edc93b,7e40ad43,3cbb6c4d,96d4c384,966ca582,a108a84d,c11a2fba) +,S(5135f9cc,1818caec,cc55a304,aa983c98,82f9e1c2,939f27af,dc2c6df2,c08ea2ed,5a526dd2,7dfe1750,4f8baf4e,115ae1b4,2619b5e1,47986954,27ca3621,e03f22d6) +,S(1a37c089,af7f4a9c,2ffa2bc,c22a3e29,82e3318a,ce1ae29c,3fdf9b62,3e6487ca,d389c033,8522230b,a96b33d2,373672cf,509b0312,35d2ec18,3c955ff0,3d2464a5) +,S(49f7a5ff,15daaf40,913c68df,c9016f95,ed1edb22,22fb1576,e4a11848,47a248a0,f9b55b01,3d637bc9,e9794246,fa6bbef4,d5ebec82,1a5d7f61,1a18c7a7,b9abd8fd) +,S(8247845e,5d9ef839,207f0f1e,26eb0470,3b87f835,ac3af130,253aaf88,1e641ed7,577d790c,1a23984e,7f1b1947,4cb42ad7,b4409c8f,23f391de,3e2440a9,e53c5f1e) +,S(8295984e,cd160241,ace92ef6,10853e8e,57b7823e,25eea4fb,8f118593,d90e0749,635321a6,6798d5f7,39a450e7,67b1c38a,2c5dac96,780c83c1,4c38dbc8,c0ac8353) +,S(d4c32bf6,d8fcf5ff,be0ba34e,770c68b5,fb5db412,b1341537,7b2e9c80,3dd75461,b3c73602,e23845b3,2c44272b,4eda70b9,a1a71e51,66d13353,74153f66,4485f93d) +,S(1a08e32d,4a968e6,a44703af,6b526a32,3babe7ca,6882cd84,9fd3f769,6cc897ff,46ed98bd,b77bed4a,25c2e19b,e2b14a8d,3fdc8209,70344b39,9a6b2a8e,afad4141) +,S(8559be0e,96723f04,4b05965,da8c9777,6b40e1ee,ce49de82,e7cfdc34,354f4af7,63e24b88,854e20d1,2c3f049b,2dd0906a,ba4db6de,aba42dc0,5af03dd4,91333ef6) +,S(e0e0b223,fc7a478a,849c0ee3,f2ef2a6,edd0f08d,e8ccc8c5,5e28bdc6,5e211e8,ca38832c,3aaffac1,206d38e1,25b8847a,6609a5e,d1288d1a,511d6037,9fca60fc) +,S(a237be98,2d8ed250,75801eaa,5917582c,265c3424,5679b4e2,34539ce,68e40a19,f4cd227,976a3780,454d5de4,7026d668,dc1bfc32,9003c87c,f48982a5,5a231318) +,S(28a84882,1eb08d07,f03fe770,5a16f2bc,5edbd0d6,b4367ef2,474f9b60,1205ccf2,9067d3e9,e7d77628,ba0526b1,71d23da9,162551bd,f00fa301,eecb5fc3,f856a17c) +,S(142fe8d5,42bd6b5d,325b8fdc,3820de5b,cc83e2ee,13d59d16,f4c69adc,98c1d5e8,2973f278,32533b9,559d1421,38d7fa60,1b66d106,1bf9c453,9c8310a1,dc75b150) +,S(5b3b611c,5d20649d,19bb00a,11b4b928,8f3d5ffb,700fb6b9,9c97b012,98ad87d2,849059c8,cde0e12,cdfa7621,9ed70bb4,192ead87,5a22c58f,8ebcb58a,f2519182) +,S(248a2249,5d4905a3,f61f74c3,5f35f6f5,2edbdc63,9454cf6b,192c7ce,50beb8af,b5a6f3ff,b707c108,1cd97b24,38867a1d,61eaf73e,9b89b5c3,b1136ac7,bbfd4c83) +,S(8a474a2a,292b50e9,d4d1fa99,a229023e,31ea2093,2d3a5d2,875384d3,dbff075c,7745285c,7d5341b1,e5c39289,16cf8fd2,45b5f045,d30d5dc8,721d6b65,ef804dd9) +,S(3fa01255,7fc042ea,67cbe4ea,86637313,826d10d2,48d5bb22,8ca8d113,5015ffec,10b9d325,f59b4b8e,ecbdca5a,58c48e18,162d436c,a3228b25,e3f75f27,26a937b3) +,S(b77b5c0e,7b94f1a4,dd88f007,1af049b3,6b778d5f,c8a828c0,46ac2195,9fd65648,31246bc0,6722bbea,8c9d5722,26edd609,e2b65d2e,9df6c21a,d54cb157,faaeccc5) +,S(2635f482,67e82b97,6c2ccad7,89bd4bb4,5671846e,d5d1d8e0,8f2c41ff,8535b44a,7edc804e,956091fb,667f9e4d,47b7353d,d2ce39c,b53234d,afb6d5a7,a72b8def) +,S(2306b52d,ae0952c9,c6b6f39b,6d1ea36b,ed0012da,18d77238,4a4e0866,361b474d,438250b8,8d7b8f6b,9a63688b,b2cefcf4,bd767472,bcd21221,582b56cf,325486c0) +,S(caa866b8,dde8284,8f586f9e,ed5a1d1f,aa5604ee,a8c0016e,248d897b,a9f74b4c,2818f140,349f78c4,572834ce,b805a424,e33746a7,d58fb8f2,9954a55f,dc09c341) +,S(818def5a,a0793d50,5f5e9cc4,29c01ed3,fb5e577b,b25277cb,b74c70fe,88bb1641,da9eee80,f7621031,80e2d54d,796367d1,f48ea2b4,93a1445f,bddb3ee2,ee4f276d) +,S(2c62cdfa,568d412f,cd764ed0,1bcac5bb,c36e11c3,5a295bf0,8b12df92,447bf736,e8b8e025,58117062,705ef985,9aba6418,ee73eabf,195325a8,f82c051a,3ec31979) +,S(28ab54d9,9db06e8c,d4a2f7cd,517d049,4e477f1a,b6eb3416,59bce807,e1f04adb,993b5319,a5cb9602,be656276,bf3e7d84,4fb00304,1ecbfb08,72aa29e6,7494541c) +,S(493e7c16,2254a40c,54b4eca4,223a8241,d6c2abf5,f15ebbb6,3ea4814c,512b6061,56387f7b,588d9d4c,fee36b59,7ae8f21e,5fcf817b,f097ec89,7def80ba,3ceed628) +,S(672e11be,e7439165,4fe118dd,a2c5d389,8922a68e,222c9bce,902d2062,b9c51d4f,3555134a,2382a9d,b4bcfbca,45e9d62b,db6bbfa,bfce7c5f,c5102dc3,23dc36e1) +,S(8f8d0f6e,e3b86889,8de86c06,b59f8e5c,27524b2c,2959e701,38b2c3,8eda550a,e7def281,9e27abc5,9940fed6,687bcb3b,f364296c,26bf1fd4,5d417103,49212f34) +,S(da8c5783,4a11f0a5,797cf4c7,9179f30b,118f2802,1205d495,e8213fb5,78b293e3,6ecfe35c,6f663975,86bb1c3,ab5dc518,7c7a0ce1,b6338d28,a2c01df3,89c35f91) +,S(4953e0f5,3b1965ff,3efec2d6,fa99ba0c,fbce09b3,83e20ef4,2657faa1,49681955,c210c78d,9d1635b2,3e468324,7980766,3c28fa97,18d0ca39,fc09b541,975541c6) +,S(5491fdaf,48a0e1e1,be21f7fd,be910bd6,5cd3e0c8,16da38db,6c742042,3775f293,65273688,5d1c5338,a3be9b29,9b51f4f3,9c82de96,318643e,3d34ecd2,fc7ffae7) +,S(b9c4afa8,42363b9,fb583885,8f17d1b6,b0a8529,43c907f0,af3ec9b5,abc168d1,ebd3106b,1b75ebed,5d013aa1,eca7d8d5,e24d511b,6d4178e,514fe156,4b550d9a) +,S(918da36c,444847a1,b5f9826d,eab809d5,d6802e73,3abca386,24237683,92d2bd62,6e6237af,d7cc87e6,15e14113,ab38989e,889d5e6e,6166eeca,abf1ddc,8a53e218) +,S(777d2994,da1f514a,800240e,59b743cc,748eb42f,4572ac93,a2e42e37,1d3392a,6193d7,e9eb3195,2cab96f4,14e1d24f,9d92505a,9d21f864,5e6dd3a3,8a9680c6) +,S(108e6ea0,9a08c5c5,e27b8b3e,af24ef55,3988c650,34ef954c,4d17f232,5723bf3d,1a8b974b,86db6bb4,7c314ebf,f811937a,b8a0dd76,e824dbe2,88fde1bf,fc13b2eb) +,S(36d9dadb,65a54d49,1198a486,8deae1fd,3c2dcef4,4a682839,b5dac54a,456bf185,25e84356,d93b5d86,25eec306,565bef19,1edd9bf8,347dcd8d,785024b,2147bbf7) +,S(3e0ebab1,43ece776,729d8a9e,302726ce,aab89654,23292fe3,ab2e71d3,66531fa7,6e7b2608,556d6236,8948f32b,2fb04b34,8e38eae1,3d9abd5c,691383d9,958d41cd) +,S(923dc76a,f315f31a,a1de9521,a13ee9ab,ab08ab42,157f483,2babdb5c,18fa3728,7a8f17b6,7439857b,3141bfca,6d89e649,7facf685,6331003e,f6bee07c,ed3ae47) +,S(f87fff32,2dfeae3,4ce9cb81,51ce2e17,6bee02a9,37baac6d,e85c4ea0,3d6a6618,74e49037,aa726e0a,357ace25,603cdbfe,7c14a4cc,2e1e4e13,c7176121,585a03e0) +,S(1388065d,dd7f69a0,11dec106,b539f7e9,e00b5aff,7568820,e33f9c1,18881ed,acab1d8f,140661dd,422f72a5,5ab4242c,65d1a932,23fe732c,92b32317,4d13408e) +,S(e5476b1e,a99b6a08,83731542,7a3751b8,3d685b34,acc5201e,59e9b623,ac4b6941,57d5b2f1,c4dd795a,323c794c,aa8fa754,bc86dd67,3cc8577b,b418b2e9,5f3b4e21) +,S(f938ff60,f1e8ebea,4c229d89,4c98418e,90c14981,4ed7909c,3dd47cb0,15cd1f15,d7172212,1a0cc646,a0576e29,372bfbd6,37fe2c5,b6ed6821,4da50318,eebb13e1) +,S(b31bd410,7c4a5108,1795544d,5854f9bd,180b494f,a08878ad,8ad5a3bd,98a30aa3,94261097,6bd58962,5e941aff,a007eab3,d33828f0,e12b31c1,8fb6f5c0,50519e82) +,S(b3ed87ba,83210d01,1a2df141,b9a6c6d3,33abd692,55da3af7,b4447d03,f4c1cb2f,949dd379,29c757e1,a970273c,b6341e66,b90be71b,347e747a,be0914aa,4dd632b3) +,S(60e6c240,1ea790d8,4bb95e78,731bca08,89a57c0e,38b87f46,668ee16d,31221e17,f247bf35,c722098f,2a5c800a,571eaf0,36738704,4050d98c,c03bd146,ca9465c2) +,S(2ae806b0,4cc8d047,e7dd8d37,713cd71,eaf3e16a,f74c3b87,994afaf1,c3750a80,a8d978ac,b29771b5,1a87fafe,605ca0ee,6facf6a2,41aa135a,e38de4eb,b2e2e954) +,S(9af178a4,bbba2d29,e7a0bb15,51f6f3a9,d2384386,3779f439,58a424c2,29bb5c47,c1031fba,a0238857,a487ac85,72fbb3d1,4052a4ba,adcdf259,78101a21,ae79abd3) +,S(9dd6a721,e9cb27af,2e7da097,c9e8a250,fd78a531,330ecb2c,3a116d99,6008f523,e6837b7d,647309c9,4712adb1,4bc65787,fc4e975d,f4e82173,57dc9d3f,e7f36080) +,S(cf5f16be,d7a1a1e5,3b3e3f1d,e44efbb7,fcb717b6,9a28bf0f,e31a1da,a5e91c52,9549ebd5,4d87207b,c63912c9,99920cf4,b0c80a0d,8a69d4b1,4852834a,c4487497) +,S(c6794890,810954d0,782466a3,c52a0149,de577cfb,3a2001af,d45e905e,dfa64722,4a4fdf51,deb64031,bfca5fbd,5c827829,8621b625,1be69187,fcc2460d,f75ca468) +,S(a25fffcb,bee9e0ff,1659c1ea,41406aa,b03b4920,fe1a63e4,442d5241,30599713,176b9e06,5a821189,ac3fc28a,fb72a1ba,40fab791,4de987e2,1236f244,bf41486a) +,S(6079a722,fd5d923b,16acfafc,7248e329,128cab6a,cae9e5ec,dca49774,e0c5bf71,c09972de,99ca5a45,c4f6f1d9,10337efe,23f5292,bd5ecc45,df0f7aeb,d18c4bcc) +,S(188cb43d,9d4078e7,18fffc42,8b16723e,f64b950f,cab7582c,8139dcb9,2b66b403,a038fa37,ec9ea240,9a2879,9556916d,fcc8c2f3,358ab14c,140f7f1a,23af5404) +,S(e310fc40,cb575c68,f5792506,65567ec8,c445ca34,68cfd02c,d781b27e,f819bb30,31328a65,5ba312ee,5e901def,66e7b946,e0c18336,a0f1784d,df66b89e,2abe625e) +,S(dd86485d,1c8245dd,d940bdeb,1f462cc8,f15693df,246c3c8e,52b574bf,77dea4ac,cd6bb7c2,56c9a270,4c690175,ba298a09,8963a8b4,7e743b48,33fc09c6,9966ce2) +,S(1b7ed20c,f81567b8,6f7dc67c,ab69e197,dba77399,9b36097b,de85d02a,7019aef,f814e92a,d1cb4386,550d89b5,9a4bc378,df428d54,d314d531,be6fc35e,f0e3d1bb) +,S(a15587b,2d528338,ed146a03,670b3f1d,9b41cd0c,a0645897,a0f719a7,b5ded284,2aefe34b,5aba1a4e,e30d225c,c4023ee7,12fc1522,ad6b452b,fe6ea727,122e925d) +,S(57bb9f9,c99da691,98cfcf20,9a0940ce,8d19463,9e4d1054,484953e,936a5484,63d0fba8,d90226e8,2c7be5e4,1d77bf0f,700dc57b,d8d3079e,9a6a47c8,331660e4) +,S(224295b3,7fa1b4a0,d7d7f7a1,2113b21,291f84fb,8fa4b746,bab925d5,93bd262c,d60ac40,b1e4b0da,7563eb74,c222660a,46ed388e,c4517ddc,ea2962b9,38195796) +,S(2434eae6,a34ec53e,7c031b2,9e74354e,d6101ca0,f228055e,53b39a6b,5453b0e3,2ff5ed61,d57a04bb,138f3956,33a20e60,8b04f775,6476d0ed,6ce7a382,743ce23d) +,S(448de592,907c1113,bdb04c64,9fb22b05,ef2e6ab6,36d0a03b,700a5871,89885ce9,d7aacffd,6ab35068,debe6dea,25b02930,63af8b10,d4592880,3d0421cc,a879eabc) +,S(8405cf73,5aef7674,7feb92e7,1aa3ba0,defc0a1c,c1da698f,7c2a3718,6393dd76,5795d006,49cd10a0,4a661c78,3f4a8711,89c9ef2f,ba86853f,c7955258,e6c407f2) +,S(698974c1,e5c1487d,fe9349aa,371eb86,9318accd,72c66d5,581211cd,6e08efc9,37c2238c,dc8f4bf5,1f76536c,2ab9af61,bcec872a,bb84ce15,90bc1c0f,ef84509c) +,S(8a37857a,be3cabc6,7197781d,f315f78b,e6548c61,1b846d8d,ce2e5732,643fee05,29882f68,9154cd0,7e455e4d,9e3866d4,5e28e99b,21dde0b7,8b87698b,4cf674ed) +,S(a871b34f,5cdd39fe,13104c96,87a8a717,25ec8cdf,fa60846,793bce03,2397eaef,84f96417,9de103c0,9f7e2dc6,86c9213c,642312de,8de6cc5d,f3ffd7a2,c387cb28) +,S(49bcafb8,9f78a7f5,a8857905,e99e74ac,9ec66ec7,aeab8fb4,fd964ce6,8286f44a,e7db8ccb,5641ab74,a791d2ca,7bd193ea,71124a61,2716d94f,4eae407c,ed9eff6f) +,S(d5c7d92f,2f05c9e5,8f586289,dffe8499,40d9b84b,79feb686,c3f71300,f68b6df6,a68b2a5c,219ea38e,a04b272c,e1cf42bb,6fcb2b2b,fce36043,4f1802af,1d51c08e) +,S(2ac2fe3c,fea4cd7b,9c74a249,cb0c8ed0,6a825cbe,2826c56c,fe4a8db5,3b286696,7d90a659,b008a51e,ca2f6031,c6ca6078,505bb46c,f00a3834,a67e7804,b60f43f) +,S(7c09acbc,62827ecf,4f63a85f,5a0eda7a,5b0069ef,b03b51d9,2f61c5aa,10a39234,e07d2539,c29128c5,685f8641,45fdc318,854b56f2,962b001,5a96c688,69624836) +,S(e886dd56,7e1b42e7,69941ae7,13b2fad3,3bb4ff02,34a27a7f,2c496bbf,6ffbf9f0,d4b2277b,abeef80f,371c097f,df4e5de,5a4666f3,c630b010,81d1172d,c667a877) +,S(edf65cc8,e83983,c5a178f0,ff60bb1b,8ca8a6e5,85344464,73a199d,59c2dc,a2426713,f0c5309f,84a4710a,2de1cdfb,118a4db,1070d23a,92c76244,89ab2d5e) +,S(29c12f04,b78a6ebb,9356dbbe,5b152323,435ad7bb,a3d2d036,a746af6e,d26d17f8,8399275,bf6211aa,78ea211f,39ec451a,b3336d27,fa059935,8b7fcece,216eae4a) +,S(d5db8b8c,280e9914,f0a034ac,3e0f9fcf,169f2046,4a618789,994f8a79,6663c3e2,41163c3a,85a0039,f5e5635a,819941f7,98f27078,aa65ecbb,eb60d577,c263412b) +,S(990a4fa5,630eb00d,958e57ac,8bb4f7fe,10e1055a,c547d165,7000a17c,d9135f8d,f25ee025,491fa289,446a0364,68c71217,eb252414,f8fcf291,2ecb23d7,4bc9653b) +,S(d784ecf0,1c7849dc,ec901c3b,3315cf53,4e3049ec,c68d71b7,41637b57,9e9c0935,5de98d22,cc382aed,d8c82a84,1ec6fd46,30672008,8567dde,6b2d64fb,6b4205ce) +,S(6576cd0,58850cbb,aaf53b67,bdf3c19d,9b4d38e5,19c99338,3204cd35,6ce38193,a329993e,92d1e56e,31c1fbeb,27648fe3,d984960e,30bf3420,658f74c6,5710eaca) +,S(957788e5,f675c0c6,4649a808,1c4549ff,20ccb177,3d26e4d8,bb94844e,bc35efce,7ea4431c,dc4bee37,d95c3948,615e17cf,1d32906,9bc10a8c,515aa0e,521d9b5b) +,S(8af7ca80,5053b537,ec501abd,78c13ff0,da5549f3,b045096b,1452c05,e39e4a2e,25e86225,aac042e4,cfb235e6,da40543,6a436206,e9d67fb8,e1b5836a,2d7e8402) +,S(49bf0393,e16e634e,202ff642,ad79c179,e6eb7456,637b2ba2,623937d0,e215236c,8590613f,401de0d4,1cc0ce1e,e9a13441,41e5f80c,179ac722,d603e697,a431a85d) +,S(c82e2a25,2572863,527b6858,18c9b6dd,df3653ed,a264b5af,dc5ebd19,d4192063,3b86f800,cd87c1bd,3d70af04,47f9e939,c2717ff7,376f91c7,b2675e3e,39a6de8c) +,S(9ce43920,2b9a8f7c,3aefc9c3,fe4d227d,42ec1355,158b2041,a3712dfd,d8eedbf3,dbbb5b05,859aedd3,faef15d5,9a939ff9,53a54bb3,dc2ee6e2,6d5a20c9,ff5b52f6) +,S(e07009e,49de05ca,52d20221,3ecab4b8,baa707ad,96ef24a,168bdb6b,16fe6227,6a35b0bf,e752ba26,81b865b0,ade8d4eb,2583833c,a1523b2e,4178f9ce,6cbc33c9) +,S(eb4dcdb4,7e09af61,e4694814,79612715,d588615f,f4c23fab,65015bd,821da888,63e38168,584602fa,1e06536a,d4c8115c,86305c,41040083,4a55d153,e9661b8f) +,S(be5f8681,2bf20113,1d257015,dd29dacf,a2c65907,26078f7b,f864f339,10e49db6,d0f420e4,56174aff,5995a92d,a73fa511,43c4f1b8,c40e9f30,8f04011d,956d9da7) +,S(3b32dc39,10e75f9d,98fa1318,edd7e8ef,db214a5c,b31d5ed7,4a61f881,355b99a8,1a12de86,19c2e9e5,9fddf756,e752e54b,6e4e0aac,572fbc42,18baf1a2,a3a18bc5) +,S(95ac5dce,5c06e885,65d2922e,a3f386b7,dde10735,169729d0,a3c3e7a4,86e04db1,1a22cd87,ab1b1821,e3c49e85,616b7b49,680edb77,251969fd,e77b5b27,3ef39838) +,S(6e4ed0fb,a4b0f13e,335d1b74,a5ed295e,7dad591e,a8dc5cc,d301836d,7ce708eb,9056166a,c61c4e09,ed988e6e,59cd9ab0,16a2ef99,e99c1a54,ac37f152,a34b931) +,S(8b7c3394,208e0ee1,374925e1,7827d849,ea8d9a79,91d2d859,898eba2c,23a42e10,b6ab9237,96720bcc,910e6440,75ef3ff,2c8bebf6,2f21ad0d,3abeb2,7043d193) +,S(fda7b47,f6690d73,884965b9,8b6f5dca,dd48ab4d,8f96edcc,8e20584b,b0f871c6,9b402435,a272cc6d,28b487e8,b54b473c,30929222,55e47560,e18b8e6b,ca926c5d) +,S(f15da0f5,395a5a1a,ef8beb53,4c0e9aa3,6e63018b,cc91a55d,ad6106a3,3dbcb217,28cf69ea,bb3b0151,917571ac,48609723,80be252f,bcf98f6d,db6ebf76,578a8f1c) +,S(c6e266dd,2c7817e0,c92378e6,38709a97,d9a208b8,7fa832f4,abfd881b,bcaf9253,2af100c1,fa9bb3a3,c8e95e3,5d0bef58,5ffa7adc,93232082,84291ee7,cb769626) +,S(4bf8aa02,fdd201e,488c21a8,33925687,7f5a727a,4fdab13f,d133d08,b6e28753,58812658,ad9c4d59,a15c6bd7,9e6c622,d8fe5f05,95cbdd88,f39be9d3,cd5fc8b8) +,S(aa985f28,6dd485a,5589fc39,da77fb95,5cda673,db61e48b,972fc129,7cd0a6d3,abb0f897,2f1163b3,29a5a92d,a1ff02e0,7c277710,10e24a04,e1e5f60d,1e4b75b2) +,S(8174d101,ec13a1cf,4eb9f88d,88c14121,6c2fa04b,ced197c,8e1732ec,61c41c9d,c6765dc2,31b02e7f,eaf7a662,5a639b00,c6e5d94b,1a791bbb,46f6a758,8fd79aa7) +,S(f9f64ea9,d6039297,b728fe09,85a9a3a2,92573aac,fdbe6cbb,8702f04f,6df3d876,4146c7c1,406067d0,160950f2,1172e879,188069fb,d87eef9b,1a67d2c9,9a4ca01a) +,S(3e643a70,5a6885eb,3d34454a,2a5de925,f8067cbc,1ca92951,d8865ecc,a8f1b3b4,2deca704,5525534e,de9d54d1,d777a996,8b5e5882,7162ef11,b0fe08b7,e2fb0355) +,S(444df411,fcc3ac07,7e95d200,d6f76d03,caae45d2,b87a882e,4c0966f3,376c63c5,b4566598,643d964a,a7cd1a4d,f2decf3d,ec520c93,ac6e32bc,64350aa5,5416cc23) +,S(12a2f61f,58be35fe,314a7beb,1a6810a4,19cdaa6a,8424d465,bbb7a87a,646946a0,9a7bdf44,94c2cc8f,f1953946,1a69fbca,48410b31,95d79069,8dfd535d,290ba47d) +,S(bdd72692,462573c7,3d48af94,b687bd22,511b2b7a,93f48793,3d52b2b7,e264cb9f,56e6c4e,b794fab0,bd5ac992,3f7469aa,858e6df7,dc40f4ed,955c0df7,a2123874) +,S(e1bd5558,77c3f55d,12b4f156,ea4da9ef,c974bd29,d7d043d6,ec7fe56,a4066bdd,8dcd9b99,fbe7436a,2382bea5,6c5a32f7,789cbf1b,1c44433f,f5a95075,c3233170) +,S(a7c68de4,781c8294,bea46609,f4a1f550,fc064eb8,b071985d,804351d2,60132ad9,a08278b6,3d9efeb5,1062b240,d45989ba,6f6bbf9b,ebfa0766,8428862b,adb42c32) +,S(4f3a8769,b4c6e369,cbdeb90f,5137d07a,5fa0d66,3d8ca79a,56b3c70d,2a9aa855,f6c051c,5f701e15,348ed9f2,c4707584,b9d6db2c,b62bf93e,35b6486e,ea6ea169) +,S(deaabc1c,8089ebfd,841cac66,d8a6bb58,36fd047f,cb435a8d,74463dde,f444f232,fb7cc4ba,49c26e7a,a826e654,7c8a6d64,ccd14a49,62a6d4f9,f50c293,c228e8a1) +,S(c411af61,547b1b38,12551e1f,4ef2b32e,fd7f33ab,7cfce378,8b5b8f93,319c0695,d2bee7d7,3d50f82a,e9266d21,2fcfbb76,294ace4e,f6222ab4,797bbf88,558cb66b) +,S(d0ff6a94,485bdda8,d0c28494,5b9dddc4,4a35f101,d0a89637,8210bdea,909ec5e7,ab3f60fd,2923a8f2,d02b7e83,d8f953c4,cb1910ff,83a92a65,e2121f22,364f620f) +,S(a0d05cc,9555ed92,2851baea,35ad6cb1,6f2744,b3fe424,98235aa7,1f08c0f1,843b1105,237158a7,bd7e67c,a20b2705,50afe2ad,318077dc,4714c7c9,d6339948) +,S(bea08445,eb295fba,5c83ef6,7d909978,7d599642,893fb9d0,568e5920,1e3f5d32,2a81a7ff,b3f7f453,d78bb2bb,41d12ed1,e26594d6,bd4f5cc7,908f322a,6cce10e3) +,S(e8ebcc4c,431be689,9eb5aea6,f6ab9700,551c3098,c5acece3,e822c7de,e6f0d5f0,ef99a461,760ae4f5,8fbd511f,59a2ae79,6d65db64,eaa0d61e,97d0a3b,31fa902e) +,S(4948606c,dd73dc44,ecf1db77,c796d8b6,806bab5,85877cd1,d9630bce,966e8fd2,3c67333f,786c8c67,841630aa,639446a8,cb8c13ed,f3db9123,bc64b925,beb95f80) +,S(4f259b32,40d9efba,4e3e40cc,a66cd494,fb5a19a6,5b5c8a16,5c18792e,9ea778c2,fdd88087,78c26999,c4a00605,49f4ea2c,b1590f7f,4748cefb,1b68eaae,4d17446d) +,S(f303a493,e14d7f52,f276e2b4,3e118eeb,1e7e918d,e7aa7f33,7e350fa4,7adfcc29,c49fa46d,befe53f,5f5bc49d,aa6ad265,453f7977,c5fe4163,cfa1bd4b,69141b57) +,S(e00c4b17,f4c0800e,c1b11859,c40a560d,58b9fdfc,29df5a41,ea4b2f53,c1df595d,62441a66,c3ec4d29,d18d0d95,7b4ccd18,a72a1003,d34832fb,8c81fb75,9763b99d) +,S(484b8486,1af6af52,a47603bd,2b754be7,ca16bef2,21581171,4cfb2301,db72ce70,36f84ff5,a0ac79a3,fe696865,2a0a6759,cf72e5c5,8c76359,d477e72c,4d32fbc7) +,S(88be58ea,d8b51f44,a1be6a8a,7cbc149b,ca07fece,11a7adab,210467b8,4cd93f14,94c10caf,7037fbc1,71cd6cd6,a0697b19,8ebbebf4,9f00c67d,4d46ebca,92687fdc) +,S(abf6ceaf,9fddd7ef,44a75e11,b10119b7,7372a3d4,7c163b77,384de944,47da781b,5cadb30c,6320c67a,e9dfe2f3,b9bb4ef5,41718392,81c4a59a,7960eccc,6795d290) +,S(e8c26522,9ef665b2,67fcf10a,17c6c3cd,4e221e0d,95663deb,74f8384e,b89d173a,9a69fbad,f9b050ef,d231965b,30d91646,bec7ba26,9fcd0934,35ae11f,ca2aeeb3) +,S(66652bd8,bf72ecb9,5e670a24,e8683155,e031f3ea,91fff58d,f60fa4ff,d9c6c23e,4844ec08,3f182b73,22c2fbb6,6f6630a6,5fa6901,52dcfb3b,4b65a3a9,30be994e) +,S(207880c2,d8421040,dc8202c4,45bf6d58,75cac841,532aaf0b,adf252dd,4c2c0964,2b1819d7,3eb24de1,ae4ef316,7c92a7b1,a562d93,80fdc54,e916d1f0,c1860cfd) +,S(46b9bde4,53d0692e,ec933485,ed0dff68,7e8f262c,7d9270cc,763fd959,2013f581,58af9be6,3ae599c0,f499b0d6,3085b7d5,394cc786,9f2fe225,6ecabd2c,a14f9bf7) +,S(5d9b2574,dbebe5d0,9756e2f,29af3aa,a2fa2555,d629a78b,82b1d679,75ea3e11,ed9f40ac,aa6ac68f,cee3dd50,7629758f,f3a64190,1658f0f0,2b87b645,ee59263) +,S(ecb5ad82,8b986425,9a76a649,1774338b,dc598fd7,77cfec52,d086c172,6e590e4f,2b78936,73c6d87e,a954b5bf,52f8212f,65d33ea7,ccc4b4e3,1d98df2,c9887886) +,S(b32b64c1,5e711b8a,1d174725,de55c,ddd62e99,fc90e96e,8f3ca532,3924ea67,af5d61d3,6dceadf2,34a7a94d,e7e4be1a,4d81b84d,e0fe16a5,403b0c24,a6ac2083) +,S(5137f71b,71582334,a6d57aa1,5cf6ab3c,8b7f6842,a800b4ab,1c308fc5,820cd364,f7ea5fec,c9b17dab,c6a248d,49757711,e4a3b38,95658381,efa652a4,4df1eab4) +,S(b9bb0e1a,390b5889,3e113a89,801c3f5c,25f94e65,63161539,e7c56297,ce9ea866,d8db3c90,3c3d35fb,ae4e14ec,e81e4e31,247f60a8,2539880e,6b66951f,8324a11) +,S(3f091967,6da40ec2,4691c21,1c42f47b,88cc1192,ec1827d3,17beb468,924fe9af,f1b44826,3e882c1f,18ae6a81,238d0724,ba4c04bd,d3fcd395,8775df5c,16bb8de9) +,S(b5fa25f1,dad4600e,8d55e7af,c70a1b2c,3767da47,d625ced8,d55ac88,d893b4fe,7575f661,f2ba296c,7ed3a190,8a49d099,83e49503,ba17a70e,1d6939b2,8ad22347) +,S(a0371ce2,dc6a025b,78db797e,90373069,e4ca06ea,6b1cc018,3d4c6f7d,680d17b0,92b5a8a8,9a5005ce,e851c521,4599b774,24f0ff74,5c4af6bc,6937c432,e859919d) +,S(5aae6e90,a49107,78863967,d7d42020,cd0a9828,da25ac8c,7b19942a,1ee2f210,ed9cc20,82a54f3f,fd7218f7,b79ec399,7e82fdc4,cd783957,5760e4f7,b7ee8fd7) +,S(54e7daec,f4a9b6f4,b100f964,850deb65,64efddb2,e6ce7b05,3fed2a28,1a0841a0,d9ada32a,54773a81,d5a857ad,8b34d96,70d46785,70943dae,cc83deca,97c9c63d) +,S(e9b29910,d8bcef46,b48d8be0,c7649b84,383ed752,391ecd7a,bdb454c8,8fbf44e8,eb268094,f669e91f,a5173965,50e4c40b,d7a26792,9a8df3de,b84c703c,261d6b69) +,S(43f95222,f254a513,1977c589,577d1d9d,3f537a1c,9fe14ef6,384e1779,da546a97,d7d3c653,43345c47,f245b305,b662a2df,eef80b3,97b3f5e1,4b0eceb5,71cb18cc) +,S(9fb45fd5,3999fb92,830bc090,216ae485,6723385c,7224b1d,cc91294b,a6c3b103,5b47081b,dbfd82d3,90d7bf7f,39a494bb,6731b506,b827213a,277f7ac9,febdf451) +,S(dd92282b,835529cd,3295919b,2eb466f5,9ca840e,20ad87f2,3cbc824b,b71dcce9,ec45f6e7,bc59d668,b1ef4a29,d1e23bcd,f3796268,3b58fb7a,d58a9e1c,5f726371) +,S(7482f012,9fbdd7,bf99def4,f3de23c5,fe29036f,c1ad5c38,686c05da,dc16348d,a43c4a0d,5497f6f0,bf2b2a20,b65bad11,73fc0dba,c24e65f8,db1663a6,b840abd1) +,S(fa4cfd95,97fd6278,1dd2f587,a5b03195,537fca30,f7a9a377,a69a6869,70ebd9a5,4568b6c9,9ddbf778,bd31d269,be18a8fd,e2a35031,a30505c,1b8ebe1d,c7ae823a) +,S(51e0d3da,e7763e8e,81905e1b,4f1ffebe,2f1078d3,27944c53,d9b7d110,3fa60b9e,118da0c4,ab572fac,cf9f20b9,2108ed0,1da673a5,2395f3f7,bfa2ff2a,36da6740) +,S(7d8e567c,c0552335,38c3b857,289e96f4,502fc674,f40ebf86,c482a668,dbc9530,76c3fc46,c6446a,4b9fe552,ba8b2614,7484581c,585c8ad7,600c2ea6,8eb37571) +,S(d924c6d3,b400196f,dd1f216f,dfa18c79,1c316d67,9ef4c0ed,8d12b94a,cd1dfb1f,ec33cee,881c04b8,b11eb3f2,88dd9b92,90b9d119,26c692e5,9d82aa80,4febcea8) +,S(8dcb330b,6f629c8,d18d28b9,7a99d82b,3965cb1a,bf953b8f,33074457,5e93c0db,3d8a2d19,8323902d,1b129b57,313f81a8,b58b7340,f6f7c97a,b6d74f37,a46857a3) +,S(dd1c4a3b,94b06378,8cf86797,ddaeb671,57910f1d,35a32e80,d3f749f6,bea5d2b5,efbec0c7,5a69583d,643e5be9,ab78cb78,3d2afebc,73d7c64c,869bede,b3230777) +,S(2b03de34,1dfad7f7,395f6ec4,84d292c1,ec0275f2,bc762dab,7658a885,37f5e772,3235e8fb,3818582c,55bd48bb,49f78e5e,803d7d1,ae49bbdf,97166a76,c3c0d0e3) +,S(3a795b0f,ba145bc9,7e7a80ef,a6b77132,677f06bd,4c3e7f39,47978c83,1428dde2,f4125b9d,df038a26,37cbc9e1,eed40aec,81af644e,a3f1352b,526df579,44914691) +,S(ecf813b,a133d6cb,9c46c081,b0a851db,121f5c21,788d1e59,ef8c0588,684fcbbf,69e0daf2,a7b7b473,7f2becd0,789529c2,597e3915,ebe12093,ecd7738,13e53560) +,S(637c4982,c14163e4,1037191d,d4e09d3f,74383245,5368cc33,57669186,d6217d5a,da5a2ab8,fd83d2e3,25baaa5c,a378318,f6fb3747,5ac64b77,a74da573,deecb410) +,S(19fe73a2,d8875b57,dcff5fac,20530da0,54255658,1251f7c6,b198b3e3,71b90e87,3b03ac18,2ccc2518,c367a77a,1fe5e8b9,a3264681,28fc1ad3,5a39f7a0,d8151ca0) +,S(16ea62a,d4cdc00,9d151b3,b6680b0,c68b4cbd,f144c234,71d55b7f,3bb7ebb2,8cac4a1c,53672e59,338612a8,995980c1,35f02060,2e3b9f6a,8fffce9d,e53fa629) +,S(6b9d68b5,454c6d21,678e5413,279f9a28,e1eed485,fbf512e8,49f35394,22a40970,b63f5044,98ebe37d,af9e6969,da888eb7,907f8565,4b05d472,fa4b1b27,ae365482) +,S(1fa20c8c,8f0812c,2e7dc948,afb7ec92,32c3c27d,23165d05,868dd127,b5ed3e6,c5257f4d,82133642,7df68606,2c229fea,6cd16857,280a60cf,ed84deb6,29838076) +,S(73a83c92,7daeb4de,1cf1df6b,31d8f536,af15bb38,be506263,e8e8a6a1,bf6acc86,a08acbe4,cd6c30b,82b4e24d,e8c9b891,26a21dab,e4df40ab,2fb7ad6a,82eb8adc) +,S(3a995664,924e2dee,ca278cf9,3ce265e2,85ba90ce,fd2a55a4,8e1761ee,7588bdbe,f3221adc,99eb33d3,52465d93,91caf18e,d011a1bd,3b7cf39,dd48d45c,44cbbb0e) +,S(7c65ee19,b032f5cc,1d45cd9b,9c160e86,5ca516fa,b4f88596,5e07f269,3d429c26,47c7faf9,e3df277,d31076ae,4be2224d,8cc54a5e,3743e287,ff9572a4,23704c5) +,S(c010694c,6750dbbd,bd953118,dccb8d03,2f05e6d9,65db8fb0,3dc00b22,e4d397dc,3b4914c6,dd6c5441,59dfde10,a196f132,5a5e6101,52d41be2,39583b80,6c8e730c) +,S(e255848e,d28d8b6d,6f95a12b,92136131,a33dcb2c,a723fae7,5e317cf6,62519d57,62f7d5aa,1757dad7,98207dcd,18183b24,377c9ac0,1e106fe4,d36d9264,3fcfb7b6) +,S(f31418e5,73232992,3a878dfb,f1de30d1,a9669da7,76effc45,bd1a56d0,2c236ed9,e62ab884,dce0d946,55e34c8a,630b5aef,16a1eff6,1f889552,af7234b8,ae56b84c) +,S(9adb945,b876313b,ac9c290d,47c1e6aa,1f3f3c9a,e8c67770,61512c2b,bd703181,b21fc142,b4632616,4820b82b,edddf2b2,51531d0e,df0f0f86,50f74d1e,9f0908fd) +,S(c4682b2b,9d4a63a1,855132e9,b35b390b,ca04b846,b83bf36,1726c3c5,808da322,f25a906a,7100ba32,1b659762,23e36f04,14e9075a,835ce5a2,6eeb5d03,d35f6972) +,S(ebb0fd6d,60f49c47,8167c405,597c765e,559159f3,ae04003d,a99a1066,ea80d63a,eb37d160,667ac862,1da2ffcf,28b431c8,c4202f67,706f4350,afdc868e,6aa0b0f7) +,S(78f12d20,70d8bcb4,267cbb,bff637f1,65ffb098,95f5734e,3551bcbc,9a5597a,42976ab3,36621756,1bb574d2,c87d99cb,7419a3e3,39973740,7de17090,2bbb78f8) +,S(3dffc4a,f6214b63,9839fbc2,b949621a,35ae41bb,e7679eee,5798afbe,85919f69,58174b6b,1b4021ae,22dd15a4,29d97502,a13480fe,902860e9,36fead8,57f2c456) +,S(410c9393,a4ed42ca,2115198f,4db76eb8,bd16bf0d,324528bf,55d5d745,b55a15cc,404ff4b1,df71b89b,c14c2cf9,bca25176,83c2981a,731fc3d7,59faa0a,5ed58306) +,S(6b4d5156,87d6b079,3df36632,6fe6977c,b93e6569,66797196,6c16c495,be4e3649,647a4894,bbac207f,5d2a0315,2db1760c,1a25560a,95511c81,5d6c11a5,e969f4e3) +,S(58ffad7a,e87d5986,f0bccfd8,5005d9c1,6f0d8724,6be4dfd9,4a771c5b,a5f34247,ad8b7ad8,f9ab15fa,f50d6f93,ec8629c3,b33fba6b,ee36ace5,e505cf00,f0069817) +,S(e6d3e41d,1835fade,af27738,23e883b4,adb95669,72892c72,b310eacf,a6a757fd,a136c88c,b580ece7,cef03e42,5dbdb8ef,d6395cab,b427ae61,45a0ef0,21359c15) +,S(fc47c62b,43aaa030,ac104479,21bc1026,3b561b42,a2d32a5,573ae947,d953b35,5d318d1d,65fc7806,732b5810,40a1f511,62723626,b393b29,50230600,246224f0) +,S(ceae2867,cbcb37bb,8e78da9,3553866,d0a1b8a2,933cb1ca,36bacb7c,6fdb251b,48bf2c7e,c163aa95,79417b37,343727b7,956cc629,3a188c16,d4c2d1dd,abb3dfd) +,S(abb12378,c84735b5,c23408d8,2516d887,9195fb74,c8972d78,daa8243e,1befeab0,5a0bf64b,da5a465,d9d0be91,3c8a56d9,ce901c36,67041a02,abb591b3,3f66698e) +,S(d7781e39,8330c7c9,2185302b,e116316,1a576ce9,43a4824f,274ea700,3159eeaf,6341a432,4e07c5c7,3ee7398d,d1be3d7d,261aed99,96f6f310,fbb464af,d06651a) +,S(a6918dcd,46ec2045,72d71646,d2a21df1,6f3ad133,dfd41a6d,be5b7684,7e4c760c,c0e51aba,378d498d,9a70e4b5,3521397c,1d6c7cfb,2f6634e5,1f056e7d,932fa9c) +,S(413a4ee4,fbb5de60,392b340a,65fd9706,7785e2e0,248d2770,6ef044ca,83d1a204,a0362506,c18a8f34,3bebc668,d1b08fd1,6595a674,51db27c3,43af172f,8a3dd197) +,S(e1a7bc24,de8b0920,f6c4aa08,2fbd1126,87fd8766,237311a8,9681581c,5e04001c,3e3ba9fd,d0a2873d,149aeea2,61a55c65,3a3d90b1,efa8e49b,29bab100,1a6bed16) +,S(ff9292a0,a147ccc4,b5ae077f,8a337e05,ab1dde9b,1795942d,8a9a0fc3,dd333a75,e50f027c,5f7a3463,7654b412,25ad5dfe,b555ea2b,8305c7a4,3b6f5b78,7a23a166) +,S(eae56623,437c9dd3,9dc7a36b,45c2d3,afe849c6,1980140d,900039d4,4ccb9c0c,f1b8c9e9,92847436,dcab5a9b,22fe7e78,55e62e40,372d77be,39f68974,dd32e043) +,S(7dd20cbe,3467a3df,e1eda0f3,48c39e5,7f9c6004,bcc89227,3d002cb5,54bd5282,ec4d2f23,f035d2d5,4cf4c3f8,31772a46,ee922582,8ddfd4c6,4eb6a689,7c1485d0) +,S(359811cc,5acf1291,547b8870,33bda3c3,e4e245eb,db0dbfc7,3a02da3f,12a877eb,ed2f5087,8b97a3de,6ff916f,511c3a27,7702d1be,2b683a59,bb6acd98,e908a792) +,S(fb33e89c,f2bcca4e,4ead57ea,1a24d1b,5a6c76ca,bc605a2,c031102e,49a71c24,c75e02f5,ca602705,7ab5b958,42a9272f,d7fca940,c26e980e,192861d,2f1c9f45) +,S(a1cd33e,5eed74a0,1534f836,b05a5129,b7b2970e,f293b606,9d1ebb56,e5f687aa,f90d1ab9,ccfc345,3b2b60cc,1e4380e9,bdefc37a,896a1abc,c9978d08,1ec4a6b0) +,S(461696b9,3643b7a,bfb383cf,ced8ac92,5d9f169e,1db30999,b8553504,c4213614,674f5c77,5f300fa0,c8f40a85,9aebffd3,ee91c4ce,695998d6,de0d59a,3033bc72) +,S(6c6aaa22,1b589f6b,ccc885ae,93f7e8aa,1fd5cdf2,27471727,f390d5bd,e14ab025,a77c5e03,40e1b90d,1ad64483,fb50fa76,aeb84417,88ca415c,9f8d2cbb,aa077538) +,S(c918d391,927f3310,d032c7ee,6e729e6d,792eff1a,72acc268,3874fcd7,4e61c38b,58fd746c,346048f8,eda1bed0,e5b6cb58,fce24a72,6e27f965,74243c80,780dfb5b) +,S(48679e16,1ca0a3f5,e4ac2654,213c494d,9240c3f0,33fbe2c2,142ec589,6dea5918,556f93fe,300cafe3,e93a2966,767840e3,b2a19fe7,9cf204a9,a30d1f1e,3e1d1a41) +,S(c68c05a9,e46b6440,a72d6eed,eaac085a,5e945659,ac46a584,69968a30,c6e7b858,b8b4b5dc,35d4ff80,be3d64a1,d036a117,c768746a,4d2bf2b6,1b126460,15de450d) +,S(d133ef10,6358489f,8f976dc4,b6c54699,21e3dfe3,6f326dc9,f0538757,9d444e6a,2c66abc4,db690d2c,272b0f57,afd66a6e,327ec3eb,e32b45be,cbf3c502,baf968cb) +,S(53544f59,8d759dea,b10766dc,48a7e2da,61ca0a60,a201d193,92dad05b,3df976ae,449a205e,61cb7aef,204e3f0,3a199ad7,993d711,537e17e8,79a42bfe,2869cd47) +,S(3108a074,fda5133,39e26385,14b6b7c0,9254c65d,ee374a62,2fe34acb,83b8b331,42edc90d,54263fea,8b1a473d,ac2f2244,d6fc05d1,f59e115b,5d930132,268b6243) +,S(1666c40d,52c1c04,d9e95099,aeb55861,2ee58ac0,6b22f962,154cd8ca,7cb4b23c,5065bb41,ae046638,aab55923,e0752954,abafc247,d201e84f,b6c444b1,93a82fb9) +,S(c96d07eb,d3eee6a8,f001290d,f76b2d82,ed80fa90,bbd5ead5,3a572457,ee47722e,d3d69c04,447fb7e9,a3416af1,798b749d,13ba06e4,78a432c8,d00dc2cc,7e20baf3) +,S(a9ffc39,b11b5b05,78769a9e,8ce7542c,647fa7bd,7b2c3479,fce84d91,1d81b49d,bec21248,82e928f7,e98894dc,25840712,80a64449,38e53747,375d2122,68bcbee7) +,S(52ca128c,cd4c9380,8e55d3f5,29320fd3,e825787f,1a600f27,37fc5fbb,f7af0632,846e8a80,95a98cb7,b4ebab01,4d9dbfb9,37ffa493,83676ec3,70f42cde,3135f7c4) +,S(ff92aac1,77fd9927,7b8abc41,e49f7c94,698525,2329b9ae,8e0fa34e,a9407c20,af0d8cdd,5aaf5273,ebbbf2a9,b7230373,dafd9a93,42a47331,a3379f45,8ffdcfb5) +,S(a692a73e,d3c10a3c,38163c97,314d02fa,5fb653b1,d729ff09,a541d01b,27991e0c,722f55a,3e5bd3e8,d863d00,6b82415a,aa05c949,9a537809,cff9be69,e468b905) +,S(d9e59c3f,7a629a93,e32fc4cd,2c98d480,6b813ba6,315ce4e2,e2fc7fed,4120aefd,24ce2594,23073119,4f5bf658,909a47fd,3234be39,13aa8d30,eb08e14f,af0214bb) +,S(74e5270f,7771b109,64991ef7,9abcf05b,4dde8d5a,605ab587,14b8e534,4a0f6ff,2ad861a3,a4a83f09,687a285f,1356b1e3,71ced066,69154887,14bb0461,b3b1670f) +,S(b9169230,1c43f7e7,61a85615,7957c3a2,744668a4,8587ff58,7a201f59,31d4420c,bd36065b,c1268280,4cd818e0,c6515a5b,659ea423,f5b23e5b,ebe1f74e,5819536f) +,S(37faf253,864568da,972d7211,505b7fb2,cd01fdc9,5953bcd8,79239d90,364d51ee,b69ae2ce,749db3e7,e6aea736,a3bc961,d8c12523,6f7be823,65749ead,3bc15f85) +,S(e194114c,4a1c138b,34882477,f0dcd065,1c379f98,c198614b,43b087bb,a20cf8d2,7a3afb4b,b90ae22e,3b182cf0,6514a998,889f2ad3,d71d4d67,89e3758a,e898a93b) +,S(2ce2db01,d3fb451,7388e4b3,c81588d1,1c8b13ef,917333c,ca054379,fa17ddaa,9232da9d,af0e76a9,85e1529a,ed1a5568,74285cb3,8010c922,e2c30d77,367bbbc0) +,S(c292ec48,4bdb7045,3dce2e82,1fea7688,bd66c6e,59635f49,98618f9f,3d6f051f,210a74f0,6b81e69c,4d0af49b,fd153247,12b77736,126f4887,2b119ec8,97b57d6d) +,S(15bcc9c0,97618aef,697b423c,cd83ad3e,933db83,d77b42ad,3e132036,a5acfeee,e9fc7ef1,1bb996fd,bfb3c490,14912ca1,a1bb98a9,e9611c,1a83a806,b88a7a33) +,S(46119caf,50f13bd7,97be45fe,55f2d298,848639c6,99d5b113,fd24cb24,6e1e7785,6a203f91,f4c56eb9,7762cf8f,9ef932b4,ba301501,5aeb1215,b1327a93,842ea3b) +,S(f3a17794,3e4df182,a9549a3d,2da1f9fd,cf141094,5e6b3a64,9d9df885,b6f9ecf4,b34eb7cc,5e82ad39,fc2b6619,859f8328,444a1dff,c82ee115,c80cec10,6ecf7e8f) +,S(cef90a74,84a7f468,db9cbd45,f5b9a0c5,fa98bdfa,50297d67,536075c6,b7913fe4,d090eead,2a43fbc2,86702946,52507875,fb79a555,e5c55737,30fa40a2,6a301815) +,S(21d8a214,987aa938,ec4b88b2,4bfa5661,26c528b6,b9060b06,833c6ed2,a35702ce,c354340d,5b65a23b,c628167c,8a2830,f736dfe9,a501fc8e,94b66f26,d84579e4) +,S(6b18ff27,9049be4a,62a04f6c,f82dbd24,e19196fa,46e0761d,5d139518,3a1ca53e,ef806f0c,52c01367,8f81e9b2,6698fa32,6343f0d7,2522f8d8,6cacfdb2,c5ffa3b7) +,S(7d8ef4f2,452cc04,d5332afb,ea3e673c,bab07c36,c081a0ee,850ae31d,cb466e6f,32461667,55a2ceef,273367d0,df10f6c9,d224da47,f19117bc,137a6244,2cfa0c0d) +,S(c7de1821,55d15649,f5bb6327,65ac74a2,3413560,b1d31afd,6994b488,20d12cab,d9965856,c5fb2c0f,c93b8659,5c3240d8,7fbe0136,11d7e844,48252ce7,96eaa23a) +,S(4cecb33a,915e2c3b,189eb6ee,45fa4eb3,eddeff09,729945c6,f893bd,4381b294,cf17f112,b5e61cb8,44625035,7b700cd7,3534d6e1,3310b6ff,d1bbbd8e,1ea3aeb1) +,S(826cf464,bfce606b,b4c3ab5d,4cf00fe4,1c9bc72b,285c8c10,204aa658,66255749,6ba3b431,527d285b,5156fabf,b150aa2f,6d7ca564,b18011cb,b878e235,7b6849c4) +,S(c812dac6,f497d245,5192ba92,2d6fc10d,de51d608,d82e828e,b2187e7,648f8f62,d02e8c7,73630680,8126ee1a,efaf53fc,2be94dd8,7773e8f6,1ba6b4ab,b08b317e) +,S(5269550e,bd967f47,e45eaa8b,c9f14ebb,aa45926b,6e38cd1e,3c6d5d3f,e0ff8851,a1597d20,26e3eced,443422ff,cd1b3fd1,b45963d0,3086a95a,38b8661f,99a7455b) +,S(7fcfcb29,80e652cf,bc42721f,cdc40ba8,c7c2ae6d,54a51e9b,af1afee7,e84d7676,abf72d90,4a408e34,ec6bcbaa,ac8f19d6,a4d044f5,66a9cce9,f95debf8,882cfcdd) +,S(85f01aa0,4597e104,848e18a2,132a6a07,3d5f25eb,8baa857c,79dc4b6,64a9f451,f7463ceb,8a058187,7bbb71ab,35bcf456,5398cec1,cb4e0132,4b4ec47,e5f081af) +,S(95b4a1a,7dcd860f,ac3fee1d,10febeec,dc1a5fbc,224035fd,a01f8dff,92885628,2a0cdf9c,5bd94467,efa9dfa6,94c6ee3e,1f80bced,23738d97,f70406ec,bef7f772) +,S(4f624a6,24dddd0b,b254b38c,e37753d8,8cd95cac,ec4709f0,49b90ecd,7f6c51c5,874a9a83,2efecd9,2a20dcd,8ccfd454,668de4eb,1b976bd0,70ce584b,c77a4fa5) +,S(39e06912,e18b537b,ce440f58,545e9c6e,a2914d85,698d4043,437dd66d,7506b48d,eff20e0a,16e93096,abc80153,c128aa12,f06c6d,4695bef1,8db7a167,6f352e0) +,S(52edc132,66d67831,74ff4f59,cadb979,4c1d41b6,5efb9310,7a717b46,78f1ace9,e569e202,c6781e3f,e32c0bf4,9684d7d3,cb07cf55,8f46927c,3af6bbc1,c4d402d1) +,S(e3764b48,964b8107,3e287f07,c915fc8d,e4e9458d,6f2a8d3a,1dfa43f3,4328465f,bde2a64b,fb13e0ba,351b460f,6d0d7574,5b7261aa,53a79b6c,3ad5c8f3,4cfdb023) +,S(80efe507,7c77698e,3ec38768,ef81732b,e1c81aad,9c42cebe,75627eff,bcf513e6,690c671b,c54391e9,695e6059,953d3d9e,a9df2e17,5aed4bc3,483f104a,388b709) +,S(484ac7d5,ebcc497,a2f2bcac,87cd23ef,19b0bf7e,93f8e728,5173f70f,c908b641,1d9570e6,f3b17236,9f2b8551,653f3271,5bc8c995,14c2aeb6,1b44ea5e,90ef371e) +,S(9c989e3f,bf1fbdd8,4dfca53e,4415cdfa,adf26c26,3801ff65,36b8fb5f,77e3d124,a34ae61f,5755163b,964b3b80,28fee3ac,2993c442,d7f16dd4,c79aab0c,88212a38) +,S(8b8fb0f,601afe7f,6456570f,19e37f80,32846dd2,97b0d8e0,9308c57d,75a5066b,7858afe,ffc4e6c9,b2e32f10,fd67a1,d6166c72,26f03b3c,240b29e0,e848c9e7) +,S(e37d0e74,ee1d79a,981baa79,e0a5d807,bce0953a,211c00ef,451d9d60,7ee78177,d28a1285,2ad25f4,df1b5625,bfe59875,a07d0593,aab4ee6f,4bd23ebf,b09f8f9c) +,S(80c8577e,9a003683,ad658e75,47657b1f,281052d5,54cd0e19,4b2a9e70,1325c147,b3fd0cd,7ca3a2ea,ec7ba8a0,d7297347,fe2baf99,bcfbbfe4,32a6346f,564d945c) +,S(e7045d6d,34121e5,536f7902,67ae01a9,50f6ba8d,2d05349a,ddeb3833,3ea8c6a1,7306a8db,326994df,e15571d9,c2a5dd24,60b37c2f,e97559e4,e7d88ab8,8a181fba) +,S(55d2da4b,850a47fb,6b3af0b1,3c03889a,d87554f7,cb346980,4f2978c8,652e0d71,6ac0f982,c861d0f6,cd20b7b4,f22eee5d,189a56d,5cc46780,72361e79,dfe16e7c) +,S(ce562e09,55a22f7f,c83a5ff2,11500c03,a1e86d1c,404019f5,5bd1cdb0,b1a38d2f,91de004d,b4aac47b,c6b0a165,edc5f82e,47407032,6f1ced31,4bd6d96b,521bb865) +,S(74e00e1f,596af05,7f91bd64,53107f1d,cd0eb8,6b93b6fe,cc7592e3,7854773b,11ca88a3,38e52a53,eb311867,b10a146d,6fa9f015,11791374,e13fb749,d8e1d217) +,S(ae8f0b6b,c194f6c9,1d83e400,ac92ed97,68214d39,95868530,a2e99f9e,2104eb48,e973fc42,dc0a930,36127de9,eb57cbf8,d4aa8f73,14646362,c855ceec,d7ce4cf2) +,S(40a8c06c,8df83675,e108e0c0,565f33d3,7854e722,6f76b674,1582fdcd,ef891ae7,16ba7850,b5116afd,3d29e0b0,40faabed,b8ff9c09,83af624e,a100555d,887bf7ed) +,S(61ea9e54,5c57f6fa,a2ab410f,861f1fff,926795b0,4d240e48,7f6df1bc,6df83b33,c69ec12a,e0b217c3,72e1791f,7d4529f2,b9063e67,38a8c03c,49071581,da79ed15) +,S(1c889cd4,440caaa4,fcdf55f7,2145fc17,d73e25ec,264831cc,30a0cb5e,c1d37632,41b5246,131fa67c,7314a223,7db5e4b0,574f5b86,11560166,ee55bc94,22d72fdf) +,S(ff295890,791d87e7,982a99d3,ab50bfa5,c58e0d06,25392abb,4ab166a1,8e49525d,a09664de,19951364,19649baf,88806fbe,c370879f,efbe4a58,e619a01a,19454570) +,S(5eb2eabf,cfca1fd0,7c939e5,b8f890cd,74e399ae,d9bdf785,7bca8767,84e95f99,4c42e970,1c9a783c,201aff12,16265d8,1f46f25,fe110f63,31fb8fb,f72c9871) +,S(43e5508c,dbccc93b,5b3f8ce1,7a071c1b,3b17bf4d,8153f61f,cfc7b6b4,f6cbaf91,b5ed8f78,438ba71e,509ec388,d09a5307,c853bb73,db240638,15a07343,9bdfdcfc) +,S(f5d16930,23cb20df,c8607261,cafe533c,eb513f87,7f6e2c99,5b0c0f75,fdb56f53,e539b168,1528332,f7fc4bf8,73e2965c,2557dd40,6eb2c8f4,92ce0dc2,126ece68) +,S(db9d66d1,5dc5a918,46180a62,d662a2eb,72313c6f,ba511eb6,c7fe0c0f,78aba2a1,c96de8a3,61f0dc5a,9e2762d9,2257857c,3cfb46b5,81c3f0b1,f89a20f2,a1517227) +,S(e760d3d8,46fd63bc,4f565bfe,7bf5133b,56ffce08,27b99ab6,833a64b8,868ecdf2,60ee6685,8be2eb4,1821cc82,54062e01,2c1c1e12,285c8381,e60e5d4,12f102ce) +,S(2bdb2299,caca7ab,d22533e7,12e37004,e3a956b0,31da4d99,1351d790,5c33e026,64675cdf,c2738105,dac3e877,e27d00e7,80193286,24cbbf82,a784713f,b6e44731) +,S(1cce0bfd,5992134,b7813773,9fd6c844,7be48d20,e001bbbf,c3c87b9a,8166bee4,2d4a8ee5,1ed7fe30,c3a1253c,4cd9e83e,b5eeb73e,c166f4cc,42788bbd,cad37057) +,S(6d6be3c3,7f5dae7b,ff5b5bd8,ec6b8c65,ec8405c5,bb6575bd,6ebf89a5,77641075,4fd3cc1f,5c6fd3bc,6011507f,7c4eaf4b,24d1938d,35159b80,39246ccf,ac9c2c7f) +,S(d82c180,d96e781d,783fb1ca,8758fa1d,b3c67f2f,143e836c,c6007d8b,bdb22351,3802f669,952aada8,93b3e9a9,74a43218,37415af6,7964b1e1,51a7b8e2,7ad0c7d9) +,S(4ec61edd,7e03fd34,f91dfed1,b546f1b8,fbf9fcee,8c73e343,b228ce18,3db3cd71,e1199709,b5b2e2ec,8af90340,de9ec3c6,db7d948f,aa941cff,b1984856,b03ba9a9) +,S(31aad469,73aea11b,a54744d7,bead13ee,a8df7a8f,8e735643,add781e9,e17a034b,64676f41,3e49f606,3f68bdf5,7ced7486,a94680f8,e60e2913,f13b674f,84b37adb) +,S(a9842189,2fccdb8e,f6515903,b589ea62,1f946bd,97e2931a,5eb1ce4d,4d173e02,50be76ac,3b2dd7a3,a3370e13,3cd6fb37,7ea266d,a566049,abe488a4,89a3908b) +,S(822b54f3,3ec00433,7a6cfa09,277540ce,fee79b08,a50695e3,f8fe0ece,b7bef099,393623c6,20d3f604,7343ddce,d8805bf0,7405d336,fda8c712,8d044851,236bf7f6) +,S(100f6b55,fe3d7000,c5f8de14,ebfc5d7e,15793d10,e99dea3d,33adf25c,15065e0b,d1bb44f7,58c4dde2,7c928267,6d6c1114,a352ffd0,dcec8e51,9b2cd74a,4eecb4c2) +,S(ca5d8318,6a09c227,481aa6ec,d195d094,6a54257c,5adb71bb,2d4e8836,d6142f7f,d890847f,b9747a0a,f3ba0c38,84ae057f,878d8d31,fc73933d,e014f4d9,2677b42d) +,S(e91c25f4,2234d20e,2931a352,f98ff610,e8ffe53f,101b56ca,fa5da12e,24bfbf14,b1ec15e5,441ec52b,c71740f6,d60e99a7,7a26bcf5,143ceb41,872b4a22,964dbb86) +,S(57a8c8dc,310902d8,8569b290,22e99ae7,acb54547,2ccf7065,9e9d42c,1ae34445,85224541,442e09d,f4e92db5,64866aee,50e7cc3f,b8c20acc,b9c6161e,30ab1fb7) +,S(232b8c67,2502d16d,badd0d41,28c02b6f,55a8531d,a6fe87d9,581045b0,7104500f,38110a0e,9e7d8587,227c476f,6549492f,4f5255d9,e618cf39,9a7a40f5,85f93fb9) +,S(7d0be68a,d71f69b3,4f5d4876,319f7e7a,750d5c7,e3dc876,187627fe,77004fec,3e72a050,7d0af3e6,1d6f5402,8a5b971e,a12b1d18,2ca45e67,ca09efcd,45124633) +,S(4dd85f0b,77c2a271,c95fa436,90c43485,b70b02c4,9a46cd83,6ba7a2d2,7af93292,843642e5,c9554d98,48ab6ff8,5dada7a0,f139e64d,2081978e,8c9e3bf5,1c11d597) +,S(537a93f5,88f02004,70b531a1,74ba9a7a,3eb2e5c1,eb767214,9e264e2f,712e52f8,b0d9b3a0,dc009266,8e25f06,71895af3,94efa1f9,78257ebb,3f839b61,340e161f) +,S(13faf471,325b1e57,98ce60a4,6f82bfd1,ab346590,82588ae8,b972b331,9ee48684,a6720384,e84eb529,e22f2585,79b2201a,dce7ba18,845b8bfa,49a21ade,7634f743) +,S(691e24ed,5861b344,e015dbea,809dede7,ca17c482,22d9e06b,e1be4405,cfe8acb8,e3564adc,c197b0f,cc520d90,9d9c6347,5ad00294,3d0f3f96,6f49b76b,91c529ab) +,S(36543b91,aaaea850,15aa394f,fb334923,b754b3f8,9047f73f,423c15dc,7d3d7ea2,73b4693,b79b800e,8e48c838,9218094b,9dff44fe,5a1fafd5,2d68a2f1,bbbe5799) +,S(ff25abe0,394180cb,1e045045,5320ea80,e007bb0,fe3bc8a2,24f20b07,8433f05b,a512b109,26dfe650,e6dbd678,ad9db412,938f69e0,8aee6c2,f903631e,530b7e51) +,S(1dec07b,5faafdaf,51051f57,cd0247ac,cc607bc1,70c53222,72d389a1,7d87e443,7e77e937,382b2bc0,5a2207a9,2598dad4,d870ce67,d0e138d3,bb35094b,9fa9a325) +,S(2f10f776,f62f8632,ea20147e,d14e0919,485ab78d,fc636236,29c2994,9f413c32,3b2c5fc6,e760462e,b9d8c8b,5aa6b1f6,35c23668,33e7ef5a,d25269ec,68d2184a) +,S(7974f394,e61c2cdb,acf09681,4bcafb4a,ade31943,cc180188,31160022,dabd73ca,e1b34da0,3bc1aa66,87df854e,813ba451,2be4cde8,310e4056,73c83600,89e98309) +,S(54c5f39,3c5cc416,56577469,84aa3695,32af1ede,3a51b14,436748cf,1701c332,3dc67b49,49769cc5,22b0626a,eeab6ba,ddbde8ac,ef78a0cd,800c1b6a,5043e4e) +,S(199aa296,f047c7eb,1d8a972a,318585ae,8092e905,e555915d,81c1a3b,425f3783,f5823679,64d17a96,b4ca7946,dfd3a266,585154e1,cee02e2,b87e8fc7,eb46c262) +,S(d15d39d6,fb616dfa,6c292a3b,a1fc58e7,cbcdf0be,7976be87,9a7f088a,9bb7f299,4c8ae97c,4e37f837,bdbd4912,f43bfc79,679dd418,b57d061,f705ba60,2bd7a900) +,S(76d65134,880e7dfc,81a332c6,a04b82bd,bff26eca,9a5aedf5,a6f6683f,364ef58b,b71ae708,bbd22d83,a1ec9048,6975b9a2,7b4aa5bc,5bf1246a,6464406b,401507e7) +,S(1eb4d2a5,d4dffe36,30ae9ead,792ffa9b,452ef0e1,94c06a02,a0308143,dcae51b7,88d978c1,e6ab8e79,9a286af4,58cb3eda,7cc94b67,589b144c,9a55cdbd,6ff47b0b) +,S(dee03251,35708790,361c3451,6710623d,e474bdd2,4513562f,95512f0c,dddf571d,d22dbcfd,cbf6d809,2c68a28d,c118ffec,496d9623,b20667c3,7fc487a,1690f565) +,S(2eb0272d,c98ac6bd,ff68f0d5,5f13f509,bf1dbd9d,f36385ae,ef02356e,56d4760a,f80d4355,4aaf4eba,27aa1832,90573687,5c69ad44,7211f746,111ca02b,26a04277) +,S(eaf62e69,7509672d,8ff6ff7f,c7788822,b75853ea,27636b5,c39b0321,ab0eabf3,442e56aa,1c8fe22d,71b88b96,90733f1c,8614e160,35070095,6effdedb,2e0a3b7c) +,S(2059070a,13d96fd9,6bdc442c,236ef463,cbc70185,b8799d3b,15ef72ae,4592858,bc9042e8,3f259ae8,f6221d7f,46ae56d8,f426fbfe,901b94a2,80da34bd,14961ec8) +,S(ff2ef7fd,9e7f3e7e,6f7b4cee,a44ec281,4b8b4a44,208c462a,f925d27,ad2f52fe,6ace74fb,fa6f72b4,8156cb52,a67f5137,956a447,6b69fe3b,233ce4f3,df0a5e24) +,S(e3e5cef6,fc4553fb,d337a7b0,4357ff1d,d8fd0de6,4df17bf6,20f7f9d8,9d14d83,acddfda1,baa7b60f,d0d1863f,769a475f,e667b6fe,8a047365,1b84f44d,238f0460) +,S(97a8726a,41c02880,e9942341,a66b9c21,a0c64577,bde3c54e,c11119cd,bf57a6c3,b5f37cae,27023d07,78cc5c7,26d845e1,fe160aff,3459d164,681cc38d,8b67b4e8) +,S(ab01e6e9,4862f943,8639484a,119eadb4,12fd9002,1d7781c4,1b020450,9dcc81e6,6ae50c32,101b5c3a,51fab05,2ed79e5,48853cf4,15a30043,6b11ee05,7483b14b) +,S(c464410,da2dcf6b,2e6ba5a,c8d8479e,58ed9a4c,a8c2b0d,5a2ea15f,7673668f,3698c590,62392c7d,e597f333,cd3ce45b,eadee944,5209d361,adbbc386,b499945) +,S(17eacc68,5f721f3e,2013b0e6,76c10795,ee49d524,26edbd86,48f098f4,17867534,cc3116e9,cb19f49,bbf7214b,b3ab76fb,fec0f856,e994a01b,d6b63ece,189ef300) +,S(c040dd40,2908ef17,539b77bd,5befd53d,3ed2e8bc,d7d3608f,2b114dea,d4c00d73,7a6384ae,55ec2580,4d1403d8,45113dce,b2053ecb,6ce0d3d7,427835b4,15279c00) +,S(a5963498,3658f70c,2ec25fed,6659a290,41bf2ba2,ba92db93,41b03e39,2ebddb42,dc114caf,260ec4a7,a8e8bf4,1695785d,1ce7c2d2,82359600,a950ade4,d79f4872) +,S(44fe22d4,51dcf63f,c7e33d09,533836c7,66382372,339de279,9897cea1,1b29aa0d,1718c4e7,3d4bd434,929e9ffa,e2496f79,4f3bf80f,ae805a9e,53b577cc,4c4279b3) +,S(8bd718aa,1358c15e,fa3b246d,e244bfd8,4fc6b5f3,ed5ec91c,ff466a11,2c71647b,172f1a88,ba6c11f0,1b7deb8d,e4002793,65a0a3c8,443b2fa5,f406dfe8,4bd737fa) +,S(8ebdcc25,bbe6aa23,809aa53c,3ff3a7a5,d7ad4cd5,5dcf3cfc,d9ff8ce1,738680d1,5c563b26,af86adfa,c3728c,f886d83c,5be64766,78ac5872,cd798875,45e5641a) +,S(5cf54e1f,688faabc,99742fb8,be896cfa,b469e5d2,feb72f4e,9dbc67e0,e91713d2,d82d6590,d06330d8,2f86393e,190155b3,4920e8a8,86324b18,5694786b,e4fd09c5) +,S(6c0d96e4,3f01a1a7,2ec16ff4,e04571ed,387185c1,4c8a2f8c,db4c187a,85845f1a,f399a14b,763ec2ec,f3415c1b,b9bb6f70,abcf013a,3117ddd6,e55a96a6,b0798c08) +,S(eae928fe,fb6a2fdc,d05f1515,5726a133,9a15ef0b,ea716ad6,90d32dc3,92b74046,bdf87ad9,f086339d,cbfda797,8d6ed40e,f6fd4626,60d6db09,84ecc577,14c76bc) +,S(e5e5e30c,bbe72fde,d9f0dbbd,e08dda,b61d5cb3,1aa688f0,d572008e,447b3a21,9fb4adb8,f80b6e67,47c6ec03,d5171ce8,5de65682,a105435c,5610065a,85b248ae) +,S(711212ac,c9e26bb7,c5ace176,26b300bc,78df6b0c,a79a0b79,7dbcca,138223ee,dc68858,4ef44ddd,9e6b343b,c4c73fe3,6b873239,18e11cbb,dc3aa72a,ef027757) +,S(3b52ebb3,531aa4f6,ddbb9ea3,fb5e5784,c4cf11b2,a4c67d50,6b6340f0,21c5e22c,3da3eebd,dc0046a1,3facf02e,46818640,b698c8a6,3c5fb9de,55a9996b,b190938a) +,S(30f28481,110345e2,7dee7292,fe1c7a56,45294a17,e96cadf9,1eb76bdc,cf56b78b,70c610fc,26ece34b,f047864d,25116fac,3c149164,a1deb08,8e6d702b,77abb049) +,S(4a844a8,12c55b6,4e4d37b6,1ca4a1f1,5cfef527,699d5ab5,edf1564d,e930ff58,49874548,508de6e4,dbbe6bd3,8d0a9ff6,5826f9c0,63274cd3,f3189d59,683dfa3c) +,S(a5ca561e,a7c8484a,642e0fd9,a999e14c,5ce2b5d,edc51026,4519e6c6,7868b06f,cc917942,a5e2eeea,ac09b00e,affa7f6b,7abe386a,241de5a4,7a7c43a3,85afa7ed) +,S(f61b7ed3,1e16c456,c3851a68,e10f614a,1fa547c6,456e57ef,3c1f8ee4,dfd6e72c,cb26d0b7,fc401865,91f5fbdb,4d17bfa6,a0c5a811,4d099a54,734a3280,5f622f2b) +,S(f8e4d462,889700c4,b52859f9,e766fbe6,55976866,a22207fc,aee56185,15f678b2,30bb039f,c1b16fb0,aa09c271,bfbb76b1,6791e95,9dd51ae,6f01aa4e,bac77554) +,S(89cafc1a,5d25915,b2f6f71,71814a2f,d5d97a06,a717a91c,a392909d,332ab653,1a24a0ab,b4e4858,d29c0055,714f34e1,5eac02da,60e87ce1,6fe2f144,257ab76e) +,S(d285370b,d04f5dcf,caa01dca,7a2ad510,33c5b555,6aea60bb,4a48d97d,477c4f20,d4b427b7,32e885d0,13a2adf8,ec705145,c61386b2,c6981b41,6c44d202,4693b9d4) +,S(3c532f2,d9bdbfb3,219dc90d,17aba269,fd335066,e1fd4974,9026f66a,4df217c0,86fd5e7c,a6c97fd0,2c33c7b4,28413977,2791a6f9,f8c80576,75b3e306,66ac5d59) +,S(24d1950b,fc35706a,21b17a16,53037226,2984453e,37e26924,b730314c,cc8ac1ee,4d22a45d,6a31a90,bb247c68,59ae9a75,b05bb9e0,8b57ded8,4b9c1ea9,c9f918ac) +,S(cc6ab0f3,6227b1ab,149f8ace,ea036fc2,d8505341,ab67d44,59582b36,4e7615a9,f9ad93cc,40b1258,67c806b1,20fa6f21,bac918af,54a0f7d7,107680a3,83761cb8) +,S(de24a954,f36e94b6,ca816bcf,f730b99d,6320f20d,9b141cde,f08ff71b,25318cf,3e34b1d9,1ac24a49,b982d235,44afd62f,8475c35e,a48394d9,67904a41,db899933) +,S(77ab04c3,4900aba9,d83a12c,7953cfbd,5f8243db,48fab618,f83ff252,5a1ffec7,6265ac27,3bcd77ff,496265af,75a8db31,231c871a,30a32bd,ae873efe,bcac2f00) +,S(a47af706,5f4699e5,e0079885,d19580a2,51ff8dee,1dab741e,ce84ad51,16e78209,393cbbfd,f1b1f78b,a563f7cb,3465ab97,5b786088,3daffabf,bb8f34b9,7a257440) +,S(a9f5f9fd,c55c7b7,4dd170fb,d0322026,93d709e1,d52a37ea,8a545e9e,9cd7016d,98717925,4badf22e,8fd847b2,e9e80ab2,54f0d327,f6b6162b,8734b105,f1d5e0e1) +,S(d57e9ebc,96b938a2,8fa200c4,e586e7e1,ba866864,a947b71,6cc7cd63,4e18ec38,9aa0d2ef,68239110,5b4c8b7c,b412df87,25de16ea,f28596a3,62a6aac,d1b6bd36) +,S(7463a8d8,fb4dc14d,5618e66c,aa85d73a,e27ccc1c,ab820611,9f506829,faa58e9,82fd6ab2,275af504,aa0645a2,8438db86,ae7990c4,b4c389f,569aad0,68d4829f) +,S(2e7a708a,29c44831,9a02d03e,4eb331b1,3927ae64,534db2fc,a3c6e7cf,d53bf412,84f3f199,73500cdc,aeae0073,f39b3b2b,ebdf6824,ec018160,fd2e3b3d,4b1e11d1) +,S(8707b0bf,540bc058,faf2f3c2,e8ba304e,180d094b,b7fa8dda,414d30c4,d9dd5e03,70b61175,fb791033,50c6bd25,aa0594d7,18db5ee9,9667c25d,fbb49c20,f100b915) +,S(3fdb370c,3ce6cd02,886070a7,28e66749,22f67dce,1b6c08b9,613aa2d6,53ca842d,163518f2,474a0344,a5c4c5ec,10b1efef,5d3a5ef9,94010063,17a486b0,c8e0dafc) +,S(c37da302,412cd549,a01411e7,6f58d4b,33077960,94b31af,2a283d89,48472f62,aa08f287,16c642f4,8702d1da,aa0a82bd,ca849000,b8ad1d26,801c6fe1,3a21f92a) +,S(3eba0550,381ab0f9,251f923b,5c7a339,60ade9ec,2b0b47cf,25726fc7,a5e08a1c,1427b0eb,b681dd3a,88639652,5afc4e00,492a1ad9,a0c5a396,55741a5f,cf0fa7d9) +,S(96723ea1,8ce5d5d4,bf64628f,7754fa0e,e43f20a7,85356e01,94eaf8e6,bb50cee8,5ad09fbb,b9bbbf10,e86eef51,2d448aed,6cf51b5b,b28c8e8a,713066a5,81f49bdd) +,S(d7645211,7ecfb6cd,3a09d346,55d5c58,ab822892,67910f13,29f8d604,a3663748,ab7cc104,d20fde08,2c889dbe,2baaa9cf,bf2c9b10,c225da46,eebb8031,c28540f7) +,S(1f6b23dc,7e0ab136,20d907af,ad4bc944,8c866065,b4ac7e43,4dca8906,d0ada5e6,8c37b25d,6bc639da,ad092040,5daa9eb1,56041440,e48f6602,398ec256,763e247c) +,S(46ff04bb,aa06a168,79479e64,bc0e8ed7,6abb5a12,8afd1f9d,9bd80d50,75459945,b1104ec2,6af2ba0e,39133bb9,e47a61ab,e7e9d229,41d71764,91ef9da4,f51bcd4a) +,S(ca1b3c25,38888069,3b076e54,58bb0451,3bcdffb3,d824af86,f3f4a883,2a597ce2,f02916fb,dd1b6dc4,76109d11,bd9e81ed,dfc9d6f5,79847622,51bfe2,a1e0285a) +,S(c961e9a,adb69ec4,8efec7fe,dcdbdfb0,5fad1277,2b801763,ee747a10,99ece6b4,469a6c33,e0b253e5,270bb70a,d16c4b70,56bb9b3c,35f0a2a9,84e2f269,9d8fb6e4) +,S(3a2ea279,1418cc94,d3f81708,9d44e777,7b3132f5,b9b67393,ea4f28bf,939d99dc,15805143,c035d921,be217dc7,18d13e2e,b981bf8e,6525f88,31a96c65,6bf164be) +,S(416dcdf,b3a1f0be,1a3fd6ad,52fb1c03,4e24d48c,cf34d189,e7dedea6,b65a7a4a,76909ec2,bbc93359,ac177781,2132db31,47e90a0a,3c6ca35b,ebadd113,60c204c3) +,S(b397c245,9aefc175,8ba5177,2d4b3ed3,2ed9d1c4,85d2a2b1,7318545b,93c63eb3,a106a360,30763676,ab418ffc,692043ee,22813574,e3117a7e,4471ccb6,f5e71748) +,S(75c5589b,efd61646,329dbb75,5e809b2a,c1bdb8c0,d29a3065,32ef3909,d40637df,26f3e1e5,1492105c,90ea19dd,81fce6bb,95e60295,a1fe347d,cba27adf,a3e6f631) +,S(2eeecd12,a3517432,17d5158c,439a9046,e4b0dc80,119e58b6,620e6f08,969135a5,e1deebd0,48c58ed3,1b53d753,9c4c5791,13606467,14147707,806f491d,2daaba4c) +,S(a981f091,5d39d650,66b1d52e,5addda67,8cab860a,c75ac124,aa100593,9cbe65d1,4cb09fcb,7ab60293,2d98b23c,96e5109,88d4f149,4f334e7b,66c60040,7d3ed069) +,S(1a19fae3,a7e81d02,a1260c9,a759e79e,545cd869,2666b31a,9aa4c0a0,9bd4ef62,2807d657,8af25c69,e29bf7bf,d877dc7b,79714df0,68ae0707,89c5b72a,b0937902) +,S(cff8696c,1ee7d196,d76f139,2662e776,9b0f4314,99d30567,1952813d,2420c61a,8497e013,8a399690,25c04b1a,136bb816,3581f122,b62b70c1,47fc52c5,e6d16df8) +,S(6817a420,4a8b3479,caaa9582,4d48eb04,9669115a,9e5a5cd6,6cc905e2,1e27ce8c,9585468b,c3377a5c,98725465,35c8385e,8182a0c2,763226fd,95e72937,7b3052ad) +,S(9ceffc84,6e0ecc26,af13eb99,579478f3,7d114b19,59253233,bcd33d6c,8dd9d58e,e01aca1a,5cf8fa1b,67c4d4a,fef1c7ec,51060234,3ea64426,856d0aa8,fa5d2582) +,S(6a6e1dc6,f203f7fd,d9796589,2301e5fb,995a3731,8c410543,835f0edc,d3456c49,2a072b98,98b93e9e,b05f9ad8,6a97546d,83b579bf,6efd3482,f93baca1,3784496b) +,S(7e7bae1a,588d761b,5158b4f0,fb9186e8,8ba3a521,89ac36d2,4dd31d7c,d2a9129b,5198f63b,37995cc7,289e60e5,7d0f8738,17e6bbbc,d40d29d,cc4856fa,ab3dbdd6) +,S(13fc3a8,63deab2b,ed54966f,fa85e553,ffa15863,ee12f9f8,5dc5b35,6bd253,e31c3245,91275056,ffca59e7,6e76a957,a8b77c82,702e5d58,b3b5b577,73821459) +,S(ffe28deb,3f39d917,f6b6dbed,ae89ea4b,e5650326,d148ccb,becbc6d1,16e9c167,8d8a52b3,b878444d,e5385760,4e02b3fd,383c4be1,128c5b2c,262aaed6,9dbb988a) +,S(28ed423,9bf26de7,d0379a88,30fa0ecc,481c4354,1dcbc3cd,44483b0f,5cc57be,192122e2,ea018e67,4520d860,b4b8d859,2d560872,19bd0ac3,7bc0405b,10ce126e) +,S(7bf3827c,7be8c484,52acc00,eee769da,5aa4ca38,2f806d72,76c72c8b,bf8a708,925f3eee,e505529b,45c601fa,1d71d706,24a75d07,1ad29172,6bb243e8,a559eebe) +,S(cf1a7e99,21a01c3,f8ede862,71f7b6bd,2acb5aab,330a17a4,a7be1380,6fce7000,21365a83,7b3ba611,16a3e740,33a3463,5f1e70a3,f38a878a,7c3a155d,59d3d673) +,S(e779ea37,d1517cc4,e36c812,1bd0a986,af3bdd67,52626944,afcbcae9,11bb29c7,32c635ac,4b19775a,a04e2c6c,29c6f42,6472bb6d,45c1bf81,e8ac8015,d78a8a2f) +,S(10309d2b,76b54210,1599785d,6c381d52,f9697728,8e0182a1,638b7f68,f26c2a92,21edf83,4c859870,efb9b37,7f931316,f3abceac,c19b6a1a,438d020,658265a9) +,S(79927b09,701e46d4,2eb2240d,e9132036,f2b6b311,a7140701,813e721a,533a27f9,fb7c6513,a81886c1,a4c75640,36136104,8a0f47ee,b8d2b905,3b3d84ed,3b58920f) +,S(743b4e33,77da3429,9f593e68,3ce24e3f,85b1de0,4a3dd37e,fdd8c73,1528849e,37900069,b5ee63ec,7b3f178c,aae73281,fbba7de6,849e14f1,8164d6b6,742f3216) +,S(d73cd2e1,ce1bb7f,1aacd9b4,9951fe6a,e46064fb,a73acbf,49868605,c4f04da,e6a762e4,4cc6e71f,f5887fcd,6a33ff1c,cae7f84e,2f22a096,14b7f4ad,b253dde8) +,S(3e1c00d3,f563246b,3ff318a1,77b3ebf1,ba632481,47c073e8,ed32d697,95f6fa68,df2b60cf,87d5c129,1036aecb,80e381d,18ce2e00,c23fcef6,b4a72f0d,2d0776d3) +,S(96e07f90,92da1653,e5cf10e6,87526db4,ed90c2e4,c629b221,a32fdc6c,d968053c,d65c1c3b,b8a2ea6b,9ee20ea5,bfad3b9a,1f8517fe,2e5e3616,4ab20787,4dc2bd66) +,S(6d230440,26b1ee02,531cc124,b2e0796a,d27a7652,33862854,d8e177aa,afe1debb,f3a8f995,faa14689,50fbde47,1e4ec008,e3dc6228,a8cfd2c2,5983bc09,ed79bbd3) +,S(8dda9f5c,1f949dc0,314e43c4,9e716138,ad7d4511,a4b06d9d,c76fcef1,e5707781,d0563faa,7585b0a5,12b674f5,db737435,ad9d9bef,ae5ba77,5c78a582,6801310d) +,S(5070613f,98667363,f5eda369,fffda417,b4bf17fa,b4c276c4,e5aa357b,bbde97cd,b20eff,4fe77ea3,4185751f,9b16db86,eb40e47e,486a4817,8a0cf09b,dc34ebc2) +,S(3a4a70f0,bfab1456,b9b8838e,ac1aa188,4986d74,6a9b3a8e,fc792eb0,af16bce7,e4524a93,19168eda,a1832980,c04e8423,843b3e89,82381e24,8bdf5a3c,adc4f3e5) +,S(2cdcf892,183159a9,da9a82f5,4630773e,db5fba99,3bcdda38,b5291230,aab33532,c88ea6ea,c9113f32,85e299e7,42abce8d,fd95692,32292044,e0a35870,757677b9) +,S(1a85928d,f8f15f61,12e0cd6,f33199ea,2b7fed02,98c203d,781a2dde,28955c99,1b3986b2,821c76a3,fe13a6b0,30725c29,534a124,51ebe945,5682ce39,74db4299) +,S(86d14da1,d6b03065,a1520663,41b9f010,dde01966,3e622c1a,6b66b84f,1da1d388,679514ec,764f5cc9,e884a6f9,f38042cd,cfe5683e,1f6e5055,fd1380c2,8399b2de) +,S(e41f754f,bdfc879,43334341,5a5078e3,30045999,7c245441,565d0357,16201cc2,dd059641,c21d191e,dfef119f,492ee9b4,743f5e0,bb3cee47,dcbb0fdd,790e8e8e) +,S(b7ec9268,45b5bec4,79668d8f,4e444643,2946e17a,8338e2fc,756996d3,4475cae4,ab4a18b,b7539e90,10e210f5,779476b4,d945e350,978ec2cb,7cc62e71,4fdda53b) +,S(240fd9dc,f1eade19,1662554a,a25850b,bf3ecfbc,83249d4,56b769d4,b7518912,af03fa5e,e0ba3908,853a3a62,eaa6a804,5318a897,31352207,76a06b08,d104515b) +,S(353c4ec,ee7d3114,979e39d2,88cc3faa,2b88aadf,8f1cc129,a5c57237,875bb769,9fa7ec40,90af4e12,e940118b,ad70ab8e,28e607b8,5ae33cf0,2a0da4fc,d12d147e) +,S(f4eed58a,a8556688,11606ae1,1628fd1b,89340988,cbe0482d,39e80376,2bd933de,4278cf64,fe74e070,d071969c,a8ceb40d,18b40bfa,52d7feb9,1606f0f8,df3b3d44) +,S(698ffae2,e2d02660,434c17d5,b5552d4,b284f0a,736bc0fa,1a1290e,266ef1ce,1966cc8d,7845b74,1da7e53a,496fc12f,8bd50cff,b0bd143f,ab608198,e1ffc970) +,S(b53b596d,5c88c140,d6e0587d,417c8945,22d884a0,4fb596b,5957121a,65314098,ddff60b9,9befe76,c87de485,76c32eec,25deeb70,4cc19a56,77197ae8,8f2c745a) +,S(97604b21,d4393bf9,d6e4cba6,7e9f2768,79151865,9f626d65,52712fb7,1a13066a,e7aef384,e1cf7f7c,65c5b0d1,7357f266,7d871c54,fa027616,36062623,4a8d17f8) +,S(7a35c9ba,6edaee60,312b234c,1062f7bd,3b38760e,da1d47ed,b63484e9,51bb8623,33897a7b,a4546761,6ae92b58,6ef704a0,769f3a57,86ef8245,7ebd6a42,4d84a5b1) +,S(86d40c75,f989115d,ca26e0cc,9263010e,c9638b17,86707e01,b6a20d95,d1e2804,759bd762,4ffd8c1e,e71dcc8,a846b5c9,dddf2842,c4170410,c0f38742,ec315ca3) +,S(603bff47,9a4bb79f,663ddea4,93b90e5d,fc77f6e9,b2a401ce,3e8deb31,609badb7,62879fc,65281aaa,6aeeefff,cd33a02f,358c86dd,dc03720e,e1e23998,9da4f4b4) +,S(5c8b8f3,c7dc7a7d,721e0bbf,8a75a36c,fa13ebdc,14987d7b,5dee68b1,32203ed,6b601f38,2bc4c6bd,7d9d304d,88fcd6e5,3faa43ca,141bd90c,e7749340,ce08e7d3) +,S(313c1ec5,a91694c2,41e7a55f,f83b7378,25a6f27e,90090505,a7963ce8,7544fb05,9c3153ff,9a4365fa,fb644699,bc4462c5,1ed858e,24752e59,82566037,103c6384) +,S(51aca51,4616aefb,30268cb2,968e0fa0,150b4bd5,a79746bf,98b01543,a9d923bd,7c51f9b4,73a7747,bfd63ca4,f4e2b361,a0a66ec4,31df41cc,203457a7,4ee028b4) +,S(4ae8d399,27ea0648,4936d3f9,2bbe97a9,353071d6,7743ca12,2ab7b6c3,2619677d,f9dc519b,c251bce8,38ea332b,9110538,f350f5e,4352e7c9,19e677d4,3c8a47a3) +,S(6bd1c95d,3f9cb5a0,8c1a054a,884d4bbf,b100c289,c4af257b,aa0784de,a256dcca,7936283b,de39b12f,6f71fc40,1b07de78,80192357,a8887e71,39654ef8,6b803b5b) +,S(e2278a29,4642caad,ae370a62,e07fbbcb,5737f700,9ef9e8ce,19bdd283,aa49480e,43122fcd,f3943ce7,35b570b7,ed82f61d,87bc8b5,83d64f77,b36f143b,4837dd01) +,S(68537cd5,9f9469fd,d104bb01,93335830,8d24fb2c,b22471f,feef4ac4,fe96c644,765360ef,41107a51,dbf99ff3,26e3b19c,4003ab45,979de4a7,32063c81,8400050e) +,S(5ec9ffc6,69c99f9f,8f8a0735,fc088824,70be08ef,3f81bb54,b1290a07,765af330,abb54008,e76f8716,78c3229,56b47c0,1f4f1cdc,dd1cbb38,1a421397,1163b222) +,S(4e00188e,5d4930fb,a9471aba,465154a1,1a330f6,15cae31d,b2399874,704dfae9,7e76f30,282436aa,73f656dd,35b40209,5ed3fe29,d2086bba,57fbb81d,4d317868) +,S(4ae347a4,d480152e,ffd39ede,b4c2f3fb,a2659ce4,bd3b6e3c,8aaddfd5,f15ed984,383e2f46,d44cfdf,4fab8ba7,ba72c635,65bb6ac1,f35c7307,ca2c5c3,62d4e523) +,S(32cade24,a8d3ac0e,f96d90fc,86509a5e,35fd09c4,d8f7719c,603ce1b8,9c6665ef,87273873,5c63b137,5b63c5aa,6ca89f9a,266939f2,e0c936af,55c10d0a,fb8bea36) +,S(8e4ef195,60147576,6ace6891,f87c22f,20c703c3,d4f7204f,5f422444,51cfcbee,2fa72e3,89d97c1b,79eda0af,c00fbcfe,cd5b9d0c,c949c666,459706e,6ed47af) +,S(35fd575c,4adc03f6,c4d54991,18607a01,559d7316,9efc2509,aae7e7ff,a4a2c30a,f9a5779d,274881e7,cb700926,dcd10ac7,dbf3eecd,9c948aa1,3474add1,ca48e000) +,S(932e4c50,7fd02595,148929a5,2c4126c7,efc12f5f,5f5db287,3c635fed,c90a9cf6,ce6bca21,bbaca19c,29f6b1b2,4d1982c0,9e84effb,cdbf1f28,75f61ef9,ba8ba783) +,S(cad8de44,22a051c1,be36a37f,2f459707,55d3e2ad,35debfb2,11a45d73,49fbea11,48b0df1d,4f6669f2,80a41c90,34f86f11,308eebd7,8a9fd3e0,53323a66,f01c347a) +,S(9fc7d304,c847fae7,d016aa64,6cb36383,1919ffc8,fceb757b,462fbe90,6c9594d6,dd17c0e1,3bc6a187,cda9dd38,a7afdca4,1963676c,e4d4bc9e,516e3a45,d9860ff) +,S(41ba6cdf,10d4a05d,c6865453,894debb8,8300e4f7,4c17c0b4,c8935761,988b5849,7eb62b15,8c3f0965,e571e278,b2833321,ece57e84,cf153ac5,9309841f,e47ad4c5) +,S(1ff9fe5a,aef36ae6,a2d74248,cefb8693,d5bbf30d,f057e884,b227ba44,11c7377b,6ba24b6c,585c0038,49c9cf41,fcb55f09,50690850,5be64692,16520575,f1e74278) +,S(299d7c44,d706d29,e6d9d070,4856c272,6d134814,1f8f7ebd,893f38c6,cbf5d660,e4a74f3,4d0374e0,ca9b4887,76de9acc,62f7d1ff,9b494040,fc85eea,2d03ff32) +,S(a0333ed9,ec1c987,6e318ceb,83d6e93a,b607c2d,cea512d6,9f7b2bfd,72e3a67d,da7dd365,5f51769d,35b37393,21fe7b50,19f83e3b,b6b8941e,d685919,fba0539e) +,S(5a4412a2,2e52a330,534093d0,ba96865f,2821cf01,564ea0d2,e75b84fa,404251e0,6a4788e0,7e6c570e,8390bc0a,b06d293b,3675ab27,54eb700c,7cd4078d,8f0e4313) +,S(d772ec4c,3b141dc6,e534ea6,a69f9b65,783351d,c2fe7cdc,3e823cf6,32b7b0b5,bd93400d,1036487e,7090979d,ddab3821,c9ccd92f,db89bcfd,da929be6,689ac0df) +,S(949782d2,c7694c3b,ffb3e1cd,6e40f807,d4452fa4,eca1321c,d04a2367,6df89336,e7c5e67f,b8ba22b5,4372e5db,bcd63c55,9f4e2c14,c97bc930,b68d459c,bad436dc) +,S(7ee7d5f5,75e6f59f,3e0a9e4d,4c49c71f,6d9ca0c8,6177470e,2334f616,a457e6de,4462da9c,76123e66,c9074add,76fa310a,9cbbbe02,d6a07d01,97e732ee,d7d9f3ee) +,S(7a4b630a,e08d47b5,b785ba7c,15417951,8a554847,bb8320b,50faebb7,b13f843e,ca24e44f,b86801e9,7163a524,db4980de,69a3b219,7f9e5dc,6b5d7076,9d937c00) +,S(d2d90a42,428ac40a,40aa5503,2bb623c1,3a18eef3,2994f793,9c31c6cb,1aa82b96,75852e33,2367d59f,30039e06,40b1e0e1,394a3b6e,582dfb66,7464d5a3,f234972a) +,S(d92499ab,6206dfb3,da1b5606,62ed4f2f,a4809b5c,48349b91,340e0b16,e95d13e0,423544ed,26a4fe1a,8f940074,993aba60,fa4dfc64,be002941,11f29b2a,b271be38) +,S(ec0c1ec2,58875e66,d24e2d31,5b7ff87a,bba6f2be,6c6bf4dc,8d5830f5,c5d09a23,e526a7f1,648abd18,1c49a237,e608bf79,8b798c98,75804d7a,ee8ba416,28591421) +,S(69380968,835b5989,885b4805,290ea050,3a6ae508,17798c2e,f30e1009,6bba8863,71bea39d,80f0ba63,45297137,a14d07c7,7522df75,8192f345,a6170f5e,2f11e5f4) +,S(d66b1da1,9fd1637e,44cfe8d2,e1ff2fed,15a40a5d,f596c62b,ebbadc8d,fca9ab23,68cf64eb,bd2b4bb7,1ca17c4e,607b3315,5cc5d91d,26583b68,78a69476,586b9946) +,S(9dd98ca2,c6fa62cb,92750d70,c9931641,5036475c,a6b59695,a510dc88,3298c95f,55a88bb8,53b99cd6,f8d278b7,e63b31db,40750905,d98ffc81,87a0e07d,acfbe821) +,S(1b66bc2c,842cf1bb,ea4ecccd,c1e2d71,4efd848c,db7a9b92,5b9a9ade,d141bfa2,fe0b4701,55fe82b8,af43d88b,68423cb6,402b3501,8831ca89,ddb9a70,83673bea) +,S(b280dc4,8a9231de,d396a61c,2922e003,c7d2d5c9,f0e8312,c1c075ca,c8eb688a,81b745a6,a2f8be66,b32cb3ad,62babaf0,498c8261,531cfff7,da9ce306,d2738a74) +,S(7bc5951c,9eb3ba1c,828125ad,510e2e92,413e906c,f015680f,8cf1cdc5,f18a6b5d,41b905d8,480ba8bd,b8a6fc7f,49adc6d4,fbda2f0,ee229a1c,d43af5a6,98352a07) +,S(69ff74d1,2318548d,76a53095,25ca8695,11647908,dc4f2ea3,4ed2c53b,f6eabfc1,f3a3e628,8eb99f78,12eaca1e,b3adf5fd,1d617397,dcc95bde,d4be775,afde2419) +,S(5fe6dd3f,1f6d3a5,9fa8f8cd,de7f689a,ffa46098,aa0f03b9,2c552e1a,c84af209,9eeae901,acb8d022,4ed197a9,15510eaf,f356cc16,274a1aac,d6dbc74f,60dbfb55) +,S(469e9122,cb0475db,7469fafe,9c53f911,d3b52bc7,8cce23b1,21d22e59,c505f5f0,fe7487a8,38b2ba6b,f5a5825f,a4d22c26,80d8a580,9db637e,cb84e2fc,1058d812) +,S(1f4a3ebf,6b62923,b2df816e,8b30f8e4,72a5e718,70c1cc1c,6d63b4d,9160e6ab,98da1295,7602ae19,89938bd4,298a67d,1ebeebde,88706d39,b77c6a61,4dc89e2f) +,S(d8ea95fe,1c12ff0c,cec226ac,26f510a0,4117222d,d0fa4773,c2f78ebd,53b86b0f,155bef9e,dde6f293,b88bebb3,ce92c249,f154b59b,a01d7f5b,25fef472,8c6288d9) +,S(1ad8a3c7,97b38071,2214b2cf,87045300,2bb36f5d,dc7f2527,1797bd4f,1227cac6,680a77aa,3755237f,15418957,6fcf51ed,58398c5d,4d56a1c,cfa3c05f,4857814c) +,S(ffea7104,5d1d26e,d942646,9f0b0f88,355540b2,c32aa92a,3fdec318,24fa7d66,eca244e2,2d8da06c,44ec8db7,5702edd4,81f67af,2ca64ed4,cb5d04c2,2434eac8) +,S(4ac55ba3,f7fc8898,54a141c8,cfd6f675,d3abe9ba,55d90f3f,c1764ac8,b959d8ab,9c7b2b91,f135fb7b,fd252d14,118b104b,714821b4,1bd879ce,15bbc93b,f8be2bd2) +,S(5f814467,7aa9a4ce,f29de0eb,865b8a02,bc7061a9,ca525536,fe27af50,bb718ac4,bda965dc,4062b26f,e6434071,6301fb02,2b8cb894,73e39b36,69acf101,90d9c042) +,S(f372cb04,37917498,4b29f213,5981f32,da5f96a4,d1acb903,88beb154,75dd88bb,82d68f5c,1e62d500,1a0a0ea0,7694194c,7ceda2ec,e32c4efc,b2a0ab46,1a367d89) +,S(fb12bc5,45760478,36313375,3fbfa4b2,878ec6f2,243e2692,7a3c5320,bb59b128,3f820118,67dae1b5,bb5ac0cb,a24ca681,96193077,fd7bfe17,a926be5c,4953aef5) +,S(3d9759ac,918a4a34,f4307560,17a9747f,4adafea1,b0a92447,316ff819,60c0ea07,cd9dbcf,6d6a330a,b671d5dd,aa96497c,caa317a6,77bebecc,6fca559a,56018aaa) +,S(eae0aab3,699c521c,3fb49be4,669bc7dd,9f476fdf,58e42909,84455c82,fe3e00ce,badce8dd,450ee7c2,99b77b56,25e808a3,62c7ef1e,11e30bdd,9777fae1,4f17259e) +,S(fed252ee,c2c0ceaa,57625d0e,925ee5d3,43718a7d,24ca3384,55e0abed,451eb851,66bbb6ae,56ceefcc,21d66b27,70756f64,dd07211c,5cf0bb4c,457a5a8a,e82c648f) +,S(da639ebd,22ac3c1,417fb04d,3bab0b22,2362af2f,9d3013c9,bc08793a,2d7f9dbd,83f27620,55f1e9f2,fa74ed0d,536bbe54,3627aaea,3e7a031c,10aa7b4e,822466d5) +,S(524d24de,d77345af,4d4d3ac6,7c71df91,32ced2a6,acae682c,e097cfc2,7eab90dd,e4cf5cf7,c6927c5c,31b6f55c,90fe7cff,2d010a00,887b3b01,b2f7a074,fab7f5c2) +,S(7dac2ed5,fb52b60c,35c7cde0,c28617b4,28672da4,5fbc21c4,b24c5268,54ae4f94,cc6acc7a,e9168866,70b5c4a2,bd2466c2,f6cc11b6,d282b09e,a578ee0f,e7794038) +,S(5f46b64d,da61f59f,6b99d10d,e9291a,887e5d9c,a3893ea6,f7c51cbe,e56083ae,6043d055,da252655,506dcfb9,c5572929,9bfa6ba,7e1b582e,5ee1f3d9,e283a8ae) +,S(8863ec33,b6a25f21,6e641ec2,b8c5df0f,48ef0fc2,38a7f635,175961a1,7de14aa3,9d6618f3,1e52581c,2f829277,7490655b,45b2a583,da0ff7a1,17dcb12b,eb42541) +,S(85403446,3ac459ce,6d8184c7,ef26f91f,b377f3f7,3e92ea03,a1bd6a68,33a2f9f4,2d1f1296,8ac56499,b252a5b1,8313fe35,8f7719f2,3b0c9430,438f7278,c5b399cb) +,S(bf6b3f6,217e412b,fe651dbc,362266b4,6a325d27,5eb7f201,379cadd6,5e223c7f,a1160954,c14aa455,fb041e7d,ceee3ded,ebfad90d,6af1beaf,a9b1aef,97ba748b) +,S(4b20202d,3c186135,4aa079ea,409aa4cf,860ca219,8ba1bffc,77124e5a,bed9e59d,9f684503,c107c0b0,ba5d858f,2f11d904,7703eb45,510602ba,b555e8a9,f5b8873) +,S(4087f880,6d679a4b,3a24f533,127b5931,99c050f2,627cbe28,2686a5aa,6421dd2,4838ad84,b3d9d488,33c8c883,698f5a59,69880041,589f921b,5a5707d2,bd88e8b9) +,S(15a79287,cb2e7406,a2db91e0,5a4fc34,53877504,c790eac7,66d9131a,fe97b79c,9f4ef322,76572e3,d3fce497,c2c6160f,1bd597cf,b96a83fa,df2a41a6,b94a238a) +,S(1c4fa063,c0524bc4,ff233d61,bcb3d40a,404fb10a,7e222812,2739b343,e3bcecbe,2a8561ec,a2d82eeb,97209e9e,bd730b2b,d39c90b2,bf4d0353,3aa8c73d,62d48bd6) +,S(a0708ba7,43c1b2c5,267936c1,85312f2a,bb50b8a6,d4886c26,56d163b5,adf2a636,958f45f1,916988cc,6c9b8155,12e1d2c,7dc66a62,359a4324,5845e94d,371a20ea) +,S(d7960b4d,f01a42e6,e109d71f,2e33ffd,9b79754,b129a858,c213793c,e8acad7d,8caf19aa,5a841d2b,61c3d0e1,dc65730a,33566193,63118707,d81c1e19,dbdeb920) +,S(7a03dc6b,f8ba70d5,96e25ba3,8fca1b32,a7c4506e,6e8a3789,daac3240,bf8ba611,70f19e22,292d6856,5a63e378,b773e170,48a3681,d096b881,fcb84a4f,7f7d9028) +,S(53a9a662,a8fa3411,c3989850,c6c83aa5,da516ca0,726fddba,c2f38f25,c7443b97,5deac250,6179c31b,f313279e,844d1e5e,2adcfdc5,b803036e,140ff59e,3945e25) +,S(86b946b6,3dbb0d86,ffe69af6,3c1bbaa9,b7ee99b2,876836f2,a450d9c,feb2cdf7,44407783,d3d0e2a6,cb18ea1b,a1e4f133,7cbc39c0,19997a62,ed74b598,f74b1fa) +,S(ce81cf5,cb884b46,f6956726,20d2423f,6b28c8ff,ba71d9ba,bef152e6,ef752d8e,75afd973,8120644c,349bf924,c04c1aaa,979177ff,2890c926,2d0b5404,5ea9248c) +,S(41106e41,3a464d2d,9f86cb9e,47d57d47,7b791d43,133a2b8f,bc6ce92d,e1172ed9,e2ca44c2,30e920b8,5601a2,773a0f88,2ce4e42a,7379b374,d2ec6fa1,f76741c6) +,S(e9c1f2a0,4e830a12,e546541e,c7ac6f6b,bca3f1ca,2052c152,4e141b4a,20b49777,51df3843,8dd12c2,29973fcd,516712c8,5ca73721,f5d50308,86b91f9b,32a58124) +,S(8bb9e12d,c5e8ff3e,4ba25775,f1552e3b,9be21f27,4250d511,fce5cf15,e73bbf2c,8a822b7a,273c3730,1c24fcf5,c19c4de,b4d0968a,bc23962f,91ef11a8,d00d1152) +,S(b0058ef1,da227791,e4694c3e,ef66e031,697f3f3e,297d139,9ad597a7,acb6bd0f,7f5bab4a,5793814,d8c0bee6,8ffe8025,e5deb644,7d2ba978,c805b2f0,be205a2a) +,S(1dedd42d,8df5fdd6,52e02b78,4dfcab0,6dfc3557,4b8725c8,db95368c,ac2522a5,3055a449,23730d25,18ff4a8f,983b61b8,24b918de,f357654f,5b46559e,b6bca540) +,S(761a5248,c6794ba9,3f45b0b5,12bc39db,e471813d,9d5c5f7d,a46f2ef4,380ea544,185ded30,c4f5ceac,5e18d0a3,95ba8ed6,9f703408,5fad1fc5,c60d10b0,832c1292) +,S(f1d5b60,e515d0cc,8dc20982,a13c1b5b,a1749687,501a4f2f,fefab898,e3aa5caf,55fd766c,395fd8c2,173a9e4,8eb63f07,ee6f9ab7,54994708,e42ed9cf,78a0d91d) +,S(569cb44c,9b7900aa,576ba0bf,61c4455a,fb09ff4b,c30242d7,fba993fd,bb37425f,dfdeb8d2,ff1ae3d4,1e78f646,ac7dda3d,c1131de8,e2566d0,d3340272,cc350b1) +,S(3e59b69a,d99839e8,51947a78,7d8f850b,9c2dda11,7dcd0776,d22c787c,ba1851eb,732cd2a4,8bfeb030,6bdd9358,37ec4f27,7050745e,b2c9f6d4,34cd8834,592e20b3) +,S(a46d6621,7b45682,98250240,3fc0886d,81acec57,32c3087b,e6ea4c4,95296967,140cccf4,29a5b062,24097a73,f9a8208d,46147884,e6127464,51acef,b9763d33) +,S(b920e59c,f25c53ba,7c00c427,d1575c9c,4ad70efe,daeb7927,74d16c46,5079ab1c,606160f1,d4ba888d,1d5435a6,1656b937,9201ec5f,37f585c9,d43197c1,f045b67f) +,S(12cf1ae1,e7d837b9,eafda1ef,db270db6,3b88b6d9,8d05c713,896e06b7,f8bfa8c5,e0d66613,181b934b,9f23d7b,e9cfd8b3,c4c1d66d,485075d9,1e8cca69,39c99c0f) +,S(6aad27ae,a4eaca2,e60620e5,a328154e,eb93a900,be13a302,87ff39d3,8dc0ec1f,932155c5,caa21539,e27e8cd2,dc57fd7a,d4681474,342c0811,2fe626bb,94a1f46a) +,S(134cd94e,7cb166be,82b48916,6c06c1b8,8d168bf9,21f75c36,ce9343ec,acf870a0,42a673c5,e956fd45,e82a51cf,ff09a399,2f7c8fe7,e73d14c0,fab88c3b,9453236) +,S(d5dcd58c,7b7cc786,8c42971f,a1c85cee,429b1d18,dca68e2c,56d9f5b5,5a3989ee,e0ca4130,ef1bcae4,ecda0529,7a338bc7,45bedd0a,f0bb75c5,e316624e,21208100) +,S(951d6534,c344908b,905fa4cd,b691f33b,3e3567bd,1538a861,f66ac9d0,e0d8c8e,eef35922,eb847928,6681a990,345255f6,95a5f691,9a7d79f9,d575f306,ed7046f1) +,S(cedba44b,25f7964d,76d84c9c,9b521156,690af0ba,966ede27,b33665cf,c1cdd0fc,806a9049,cb8e9af1,d187b6b6,493316b6,187e7124,91a8f7d9,4c21b79a,87c79e7e) +,S(4ff03660,d1306bee,29abd39d,32beca15,d1c7d2d1,14492a20,49c6f4aa,d8a10b54,c2c75e69,8fd89951,e36e8bc8,be71f689,4990f25d,d2ff1893,d99e2773,6d1e574) +,S(c08bd508,8dbd6465,e87b7702,dfb7200,c78061a2,683b9824,389042ce,ce2e0ca7,562019d6,1343497a,b1640884,23a9f171,1db329b6,8c63e78,41793255,f88d7307) +,S(48dfdcaa,6fd2ceb2,3b85cdd2,28bac318,955bdda8,274a1e3a,7afd5db,4bf9857d,2a46622e,896167ba,5154e76f,ce429554,af60f4b5,1431d171,d55ffa2,ea0287ce) +,S(40420900,d81af883,cbf76b47,17025382,802c1479,a33a3cee,bbfacff3,16a1f236,866044e0,dbbcb53b,308f50fa,2b54255c,7831e96e,f19e1b4b,e4168d1b,7b85e3f7) +,S(96a3747b,23b667c7,70ec2018,4e99208e,ec1e3142,3b1156f,8b12f37e,322bdc42,67b0b3c8,df8c4647,3310b04b,ad325d6f,dc7545f4,a4a07af7,98c7cd86,3cf22ab2) +,S(cf07017d,e4037969,24361f0c,b151484b,f1db3e91,a8d16784,5039132b,c8460182,b7a1b107,62f29e30,d0f6e762,f6940638,e2eb60c9,e65ad067,99b1bb39,3797939d) +,S(12b5b8b2,5b0bb6f7,ad1b90de,d75fdd5b,93507aa3,dd7276dc,805cf5a,218beb15,5d3d4767,8cefa19b,80ed6368,d40ca199,5a5bc165,b3609ae,e89b56ed,b78933da) +,S(879b449c,e866e6d9,3998b9ac,e18b6f19,77ecd299,bd9b727d,cd99c37a,13a46765,b0c480eb,758cfb12,acf50c4e,91a8d9e5,f0c45215,f03e6bae,c6c13a83,63781c63) +,S(2ec48783,e9d3a01d,d1fa401d,d3fef249,e502280c,cb36d21d,d2b7b90a,cc7dead,fb029124,78f9e2ca,1a5e6150,5eb469a2,83fd8f81,6798703,ca2f0c7e,85a67fce) +,S(79cca258,27bedb07,39fe8fcd,2145956a,5b7878fb,bd873a83,aee22093,437c3ce7,ff488a93,d82e8750,14cb7c48,3eb74b30,bee990b2,2c1915a8,d3381cea,9cac467e) +,S(c444a4ca,3d2b8b7a,826b9eed,40616aa6,8e146a80,d49a9cd9,3e93cdd5,5adbd207,4d1368a9,63d504c2,541ae338,1ded0684,ac00ad0f,b8fc3231,9d1fc273,92d0f18) +,S(3ee47c50,cc0e44b2,5864e205,835e8d6,dbed328a,60493c26,7ee5529b,cff3e7a8,fa555339,56ea87b,c3249640,145e243c,b6229a30,3d1b91f,84e1ca9e,90a5f095) +,S(e963c987,3036bb7f,422251a2,9f9b0f47,8e69e2d9,2d1920a8,1c012d7d,c809980c,ff95bb0,779bbf2f,1242bfa4,880b173e,140f92d6,c7f8e5e6,18027a3c,55c52fd6) +,S(aaf6075b,b6a1b8b9,afe4b747,a46fa394,23738e50,e686c8bd,3f711cc6,548fc07d,4cdb0aec,6d11ca1c,1e85bd16,2eb411ea,53ab326e,bbdf898b,1bbd5219,aaf2b0cb) +,S(691e4817,d8e9756d,8e174a18,d5d708aa,842b44d5,ea921298,6e4c7585,4157ac0f,9eaeba0b,3bfa7ad7,80d0eb15,72f92873,4bb9a8df,29f508c2,d1ff4076,a0c0c222) +,S(c3e6fdbb,45af4a48,941c9d4c,583dad8c,c77dbfb3,1caf3fd8,1d9e087f,e744996a,ca998d1e,65ab29b8,fee07bfd,1ac4e979,b869474,b5498a73,e642bc9,608366f2) +,S(edbd6320,a55d25cf,21f2630b,e7c5c996,923eadf8,333d386,8cec00b3,940701f,d65192e7,afcef5e4,c88cd12b,fe28f94a,5e3d3d50,f6b2c3e3,f7a14243,4de4889e) +,S(c959ed83,a80ae0b8,ac2fd249,43c37412,b29684ed,9d4d85da,d7cb4c34,ea95d336,80c1dabb,8dccf252,ad8b0e97,25970c1,4de5f58e,12f7e5f,8b59a2e1,a72b168b) +,S(778cc574,471004e9,d88c9022,4d2d5cfa,2c5bc6ed,da64a312,74e3df83,3eed9237,eea23d31,6b2a1c02,7b92e502,db921d9d,675720fe,51cc3609,46b2dc93,92916c17) +,S(a1f87438,8c3656af,43f299f8,1d98d2c0,173e7e46,d3fbed9a,5c2afc96,63b42055,10bc8443,820d6c5,b3150e79,b9936785,5d874afe,dc72a84e,abb987a7,d56f4afc) +,S(c8ad7f0b,2d5f8b8a,cd9a1839,c3d043ee,8f7fa583,7540f6a3,d002091f,68224a5d,3018b580,eebe5b9a,2d1507cf,18a7fe4a,2a1cd4b5,1157dec3,8e65f191,c7aebf8b) +,S(c25d5264,b93fd7b,b7e4e426,1ae767f7,1ecf3840,a2a7ad20,bea810db,4820055f,fa15c8c7,6e3f2b0f,a29fffbc,eb48ed32,bf331aec,3a147524,c349e8e2,465ad684) +,S(d0b972eb,7e4cbfad,baf224dc,cb2d873b,28316877,88b5f2f2,ccc62bf5,e978f92b,ef5d3ca1,606a5852,aafbcb4c,f23e787a,75610b31,8420bf56,e94e420d,f7ab8e3b) +,S(f8b44c83,58564479,6448791a,b98132b6,d393e851,bbc294ab,56c8042b,1b0a2d07,c28242bf,42040be,e9851362,fc8e764e,2dbe0c01,d5bb0ed0,b8e1edfe,e870a27c) +,S(e7cb8901,6f72aade,39410adc,12fd1234,5d942419,51a6d36,8acb7c83,da5666b7,de367522,46b6d9d7,efd4ee6c,53a1656f,f0c87e80,cb0f8f63,95341c35,d6b21697) +,S(8b2128f,14e3f4aa,92e89478,64c5eaf5,f40f93e4,95cce167,fb2c7424,c279d87f,e7ed384a,f469b4b1,1812068,a830303e,699926d5,b8304c11,cbeb0e49,cf5d246) +,S(f34db5db,3cbcd586,38b6a5f3,ab5b31f4,1f3f631d,785e8317,658408f5,93b4afb,dfce7372,bb2c8466,fa31a1c7,4ffc1ac4,5bf11263,4c98ef2d,56e30fd5,c3dd3d9) +,S(c3689e09,a445d685,daca48ea,bca533b9,10b4fee4,dd251c86,a965d5c2,ecaabdb8,7804d05a,6a263fbb,c33efbe4,f4075d1f,d62e187e,3a5917a1,55c1f22f,1679e3f4) +,S(7ff995ec,f776a10d,7a66d62,6095892f,f1e47d4a,2b47ca78,d708a0cb,3f005cbc,edcdc774,5f17e430,cdca4d11,56d08288,e3911d0,e92999f5,cd5c5eac,ca6ea90d) +,S(3662a262,62234bf9,69b18351,2423ebb5,db78bd6,1cfca8e4,1c0253ec,427d4d27,88a62042,f07e69c,f40f671,ccaca36b,d550ef9b,79b4999f,c41cabac,1c2e1b09) +,S(2c127c2e,6d9c42e,970e66ee,24a07388,b6b4ebe9,1614b951,1763b414,3f54e8d1,a4773eb8,dacbadfa,afa26c8f,f4adae30,856be023,6022d93a,aae59c9d,fdd6629) +,S(c420ffa6,116f161f,fd94863a,9fe30b7e,b7dfcb0b,8cf9acb3,7f6d6515,4ac17802,e6cc469c,25c68f6c,8499e9cf,95eda8c1,7fd76d97,2ee8fbc0,79b143b,e50a028c) +,S(77896743,220343dd,58c2f06f,d3217468,34d386a7,e7fc969b,50c77847,eae3de0d,4350d59e,4408dcd9,710bcd7d,629e92a8,cd906759,627921f8,57054a4d,21fd9369) +,S(cf7ea42c,1a14dcb4,3334f9b,636ff0f7,7147688f,19133c83,dc127139,349f5827,b9c02c80,166bf9dd,139c2846,895e4aa6,ad1a689,66460a29,f8e951dd,d99e6d9d) +,S(d1793439,ab1fabdd,ada8ab1b,33c9f96e,417b1c84,7f753630,9d815fa5,a673a91f,ac13d659,3b5941b2,3b19f6f7,f9a67d0f,b429add2,5a40d05f,9bc0d1cf,ced3b3e0) +,S(bb1568d6,727dde70,c52f5863,133dc9e,54722577,4a74026b,e9864f02,9e92b420,b5654756,268d74c6,cc6adf80,ceee29c0,9e137d2b,e15aafe7,b170c95,22af3992) +,S(732912d7,83e8a5a3,a7468177,231ba93f,ce07c42d,778dc205,35cdea7a,db877dcc,d34b8388,1b128d23,e68ffd7c,29c7a945,1664f5d3,fed3dbab,6f78c8e,77df80a2) +,S(c74f0f71,fb8532e8,2c3e1865,1684d3b7,4927b6dd,22504afa,9084688c,7297074c,9da5ea61,c0bd178e,8bfe5a92,dd040c6e,35984bd4,1102806a,53a9f1a7,bd006ac1) +,S(bd4fa939,8bda5a0c,5a4e9e49,43060d9b,1785a613,3c970aac,91fcbc68,9e3283b0,631d4fed,b6614b49,459be1ca,ccbac0d6,e79cfdbb,f14de95c,5d2a5cda,30e433a) +,S(9fa65462,733f13d3,2483e0c8,15cb6bd3,e9bc2d79,7b89ba72,f2465c64,a341cc8f,7051fc5b,afc5b18d,748ada32,c4a27151,443505fc,2f14f130,10fa02e2,6a12db04) +,S(eaea6f7d,ab3dbf1e,816434a9,ddbe53bf,715168fe,2c1ebd4a,6cd40744,c35e31aa,b96962c2,4f202b96,c2080619,ff4ba905,a594b9b0,1f709e6a,76a1a7ab,9784d61d) +,S(b3df7ab6,3b947504,f33e6d5b,7b8e2553,9a117c8a,497f8751,6b97bfc5,3b17a2fc,72df7500,a35ae6ce,d6fa6265,1a759dd,f11f00ea,9152a5b5,ec51bbc4,9d758b9b) +,S(ef875ecc,46da48ae,45619be9,950e294f,4341df09,726417fa,3a8d1ac6,c3281bbf,7ab9e204,af4c05b6,d6d0eb6e,8306c987,51ced2c2,b9e8dbc2,8a642bb3,7f1c72f5) +,S(74c3c446,576a8a3a,5082f234,afca508b,3d748757,4cbf14e7,fc26f36c,70024fdc,73d57916,4ddb6fa8,72dd2afb,f9d8a307,b6ccac9c,94a4eae8,8c4fe8e1,dc136506) +,S(959c4b2c,409f2e3e,6c020493,33ba2f18,c06b7182,5a664e1a,cf33846d,cf39274,17cab35c,7401629f,b73cd398,dc5bedd,d319919f,1a3995d9,45f42f68,2c9aad47) +,S(404f0dd6,94195313,1953b53c,67fdfab7,f67c24bc,92fb4d69,a9479a9b,6c9175fb,857c75e7,f40a48d3,ab156085,1d42b037,7e7d3e79,86efd570,147917bd,f24d87b3) +,S(3e040511,233b0f5a,53df4d5a,b0854137,2db4ecef,170b566,807c4923,6ce82075,f9337271,dd443843,77a35ebf,56753b22,1fda08e0,1b790e02,b9603827,600df3d3) +,S(942ea853,10dfdc3e,1f7993e7,47bdac04,ecc8692b,94847bd3,e044cdf2,2cd77e6e,bbf2f7c8,e688b6e9,b4510bbe,58c41b1d,f33e9afa,5428ce51,e02e624b,9ea155e5) +,S(1e577a74,9883a5fb,85593809,7d0180a1,dce21791,e10b2c0a,3fe6cea1,cd03b532,a147662f,856f5e15,dba53000,7278e878,7b575612,d5dcd790,19417ec3,ac41c003) +,S(ebc9d95a,8a237b64,212e9dfa,607fe4a3,7a05fbfe,7c5594c8,ae472c4f,6ffeaa5a,39406dc0,e311a47c,cf15fb45,8f8b48d3,8fec2fd8,6b4afc05,b1747957,e7f1162a) +,S(c78eaf60,1afdfc20,2123d228,8496189,b9081637,1fb2c475,2773faf0,63cac063,95325b1,e0c22dc5,df6e84c5,16d396f9,bacb42cf,6c1fe9c7,6df83b3f,3eb42de7) +,S(b5918719,a1d504d2,b44a3d0e,117c2798,4f2e536a,3571db8,752685cf,df6d34a0,9b01e8cb,585cb7c8,fa29828a,ac899050,16beacb2,5e62ea35,6d54e9a6,18184abe) +,S(8706a73e,b59fc9d1,92907dfd,cc6f75b6,454f1045,4a5e9584,bdac978e,8e0042cd,8b1b5f56,6f1f78d6,f528405a,2b6a87e8,4265e2dd,1e34c1ce,7109286d,5bdc3a49) +,S(93e9256e,4ddb4bfb,6f4a9289,6e2ad04,793e5642,3a22230a,e645529d,712d6ca,83b242db,d9b3dfec,3640ea62,f0e3989b,d874f247,90a75cd6,9756a8ed,6eafdcea) +,S(2dad49af,8702f39b,cb353956,a1d5601b,a24fffbf,58ab527f,e9ac6ff9,ea2ac295,b5af68b8,e6040762,55c0704e,2cace8c0,ed403611,40dc02fe,2773a625,27e4675b) +,S(5ffc1899,4da42fa4,54962719,5ebe332c,86a2c364,f43b14f7,59710c54,4f6950a0,22eac0a8,79815faa,220e6141,9db053cd,4542ad2f,9ba9f63f,4331ad5,c2c9bb88) +,S(71be09bb,1832a799,c4e21bb8,a2bb5ad0,324c639c,e6e62b6e,69fa60bf,d41c51ba,c5227fc5,719a5b8f,28c40767,b54eb249,950588dc,c15e1656,e4ff238d,54dda472) +,S(4f94305,f92799f0,a64a3cb3,7df2bac4,56d661d6,44568277,bac0ed6,6a587212,4c48691f,bd8683d6,b94ddc7c,ad8d1d7e,6baf796d,6d00f344,511fc13,13c054ab) +,S(55ef868b,6fc2923e,e624fc09,65f61852,b3aeb38c,e2c6b3bc,54b86b3a,60f0ab81,ec198aea,ab16b4cc,5354d0ad,c66051fb,76cff6df,22dc1a0e,72ce6e79,1622efab) +,S(26ad5590,46e19dbf,e60953e,d40a3958,a357f6bc,23642279,cbcc355,74fdab68,af6fc5ef,906721c0,553c6a74,60bc6894,e5bb77e7,4dbc25e2,184fb3f0,fa795508) +,S(739fb43a,b1b07155,39c0b0ae,43901bf2,bc051a69,8ee8d503,84fcc1f0,ec37312a,c1223704,3c882226,2d4abe33,1de6ab4d,ff90d6b8,4c0b59e7,a193e763,6c6b7e28) +,S(2144649d,508cf5da,a7b422f8,22e9125f,d5a10965,a9d32c6c,c299bad4,6616771d,1153178c,e33c445,f03ef96b,35067ceb,76ddeaca,d9ddba1a,74acd229,d01ca76e) +,S(62cc463c,16ee8e8f,16ea8517,5508278d,4d5577e3,556d3580,ec8d90e3,bbb97072,cd294843,e299c500,846a6c91,c913395b,56b48efa,2f9ab3fc,b81863fe,8a6a891e) +,S(1196301,33edf190,d14fdb00,640f74cc,4317e1dd,b9dff1c9,707eac33,53ef9c21,f16ab4e5,e3a3ee6d,74385187,6da07034,caa4f519,6106a0c8,3136d21,5420494c) +,S(b250bf86,3fdaf93f,28f15bae,d9555287,777d4e34,2673c16,2b4a6319,2289adcd,295c05be,de343d28,87d3543f,6b40d5f9,da1e06ef,39fad6f8,28ad5ac1,39b3d2c1) +,S(93a40bbc,ae584739,9f10945a,72c199b1,27ef008,14e87e69,6f4f46f6,483e7c6c,81ed70c0,29809674,f5f289a4,5926864b,f088e2e0,af66173,89fe8cbc,aa858a09) +,S(b9e6761b,4e909d75,b17e76b3,4e9825e0,19ff7ddd,4faa9f90,eff8c0c0,f60978cc,640c1503,5fb91270,8881b70f,bf2c8575,65c75e3b,c98d211b,76279090,7b5aa117) +,S(4dc22812,fe3d9ba4,687e260c,f5b2dc08,ae454751,b022b9be,ebf4360d,10cfec24,9c35ef4a,56858135,552e986d,a4d68056,27f0822e,43031c43,5b2df5f,7f9a90d1) +,S(431276b3,1127f9c2,406b94ba,683d2d3b,e198e225,23663540,9348286c,4c9deadf,2265ed84,c7f1df86,4b46280d,ddc8cbee,c26d39c8,ddd5b743,13938c4a,e01efb3e) +,S(75c5b6c3,c99058f4,2b4b81d7,6cfaa917,328f1736,b8788360,aa810acb,3683632a,549f009f,def17b7f,70a309ef,49a890f1,4a5aaa1b,a80f0464,affdb5c5,a8f719d) +,S(3c900027,205af742,976b1a37,7a4801df,26d4d4e9,12ea757c,815ef99d,cea827d7,e28cff3,37eca7de,2387fa7c,339dab2,7a2446,fe7184c,83c578b1,8649cc0) +,S(5660f31a,3676b95f,9fa8ab0,d5c23f30,c89637bd,3a8ea97f,3a87aeab,3310d9ff,d6069cd6,6bc4ca0a,7d892ff3,e4d9aff3,955bb76c,2ba3f839,efbd786c,b11c568b) +,S(2b8b68a4,1b45dc86,7f7979ce,5b71d778,e6733cd4,79af6f61,8cd786ff,5f3babe9,7c831244,d5441b33,c20923f6,3ad9a093,840f89c4,6c1421ab,40ac52c5,8de4097a) +,S(8635004d,b817bcdc,4b357886,96b3fca0,1d369d4b,303e9290,44229cea,89c18610,2472da40,2bd46e6b,e2f84cc0,5158da1c,7e9f3512,1fc4b00c,4c3ec329,6eb909e2) +,S(6c991a6b,6eeb4f97,9b7afbde,46e1eccd,b0d39d03,dc64fb69,3a56a234,88cb28d0,1e5df74f,c2cd6350,50277188,d3eb4473,e0b753e,4cd41372,2bc119ef,65c95620) +,S(acdac19d,4283cc91,b9698ed7,e92288b8,554569a4,962ffa0c,a52a197e,9f41570c,fa536d87,523c8541,f530c6bf,e71742ba,451d41a6,f97d9afe,ea03a520,c6d7b66e) +,S(b1496ba3,f696cbb9,548b107c,3d28a7cb,85bba7f0,aeb50abb,a3e2a596,465fc6c0,77fb6cd5,727a4a6e,e0fc8f8e,ae807827,487740bb,ff5cc57a,8572ef3d,c86318ad) +,S(3fd97db5,6098e9ca,fccab31,d6d128e6,c2c9f878,adb07ec9,4d854034,d9b09126,1bd77c36,1494e374,fc45127,38b246f7,24e37d4b,27e14a2,2c0401f3,222b4578) +,S(5e8df855,f2a468ed,5476d5c4,409c7cfa,eb174cff,ad793338,8982ae2e,c2aefce9,52e73a82,3bb8ca88,a0977184,38701841,d50da8ec,c46f357a,17eb8cb1,36a6845f) +,S(99f106eb,1417cb69,e95e6fb0,a0fb932c,62021a1d,b940c661,3f814086,c64672bd,9e7fb038,e1e70011,6a926e6,a1c27fe5,e484d843,d184d533,7e9825ff,f7a6501d) +,S(686fc498,5526d87f,fd11d686,4ff0e208,68bb14fd,4a5c71f7,ac43063a,7e51ef8c,1d28f532,d793af85,bc96dd6b,2e0f23fe,4137dc5f,5b3d6244,22f60919,44588e5b) +,S(cfa5df56,cc450bca,914f3a85,b370f864,e4c83600,560bfb20,93df96bc,bff6b83d,cefb9a46,bab7ffc9,1b1d96c7,48f81706,61cf56f0,264e203f,78b05f3b,8d37604b) +,S(991b6b4c,3fbb9693,f7641eed,534e7cbe,8937606a,962a83e8,b39089e4,713e404e,3ffeba6b,be556688,d3b8a0a2,f4b92b8a,98dab79,d5847c71,13bb60ee,be3f8d3e) +,S(d104c5d3,b9b0121c,58a1fa14,f226c513,2955c4e3,56938bcd,6891bb92,13c8c0d7,8c8399a,814d7cfd,32cea21,85c77738,91ddb00,a091196a,3d90d056,b0caa6e9) +,S(76192853,a45c3648,749c9a40,719424eb,415a06f7,c74b31bc,ad93194b,e355dfce,31139287,3cbb5012,d7ebc934,52613c62,b5517b37,91475ecf,84ef3745,324ad2fc) +,S(173304a8,509c1f4,c05b1de5,c51093b2,10c7f9b9,81a7d6c8,8059fb1a,e5070725,43bfbd98,c8e08394,543db2e9,c692297a,800cdc8b,398c13d5,f9e21f89,341d353e) +,S(aca057e1,d28c5514,107f5b6a,9e46fc95,9eaccaa8,b14d4c4,6b7ae515,bda104a,e17f1717,70bd76ff,18095be9,a4b72b8c,cb00e6cd,23f6d702,4dcba433,e6bf6ce8) +,S(fb202550,e0098fb1,c30a7385,900a7dc3,85b2945f,60e6eb04,b7e8489d,3476dbaa,1aaf8420,3f72c68d,bd3bc98c,77f473cf,cedda922,dfc3c996,45e4f565,ef9a0f28) +,S(e95b710c,a0227ab8,e5b66c66,c2958be3,af1aa298,422c501c,8f879bc,e11ae7ac,e645f4e1,ab5cf4b7,da909022,cedd01f8,c745a968,d9ca30a2,c5525d50,9f97cf19) +,S(6db4525c,3589bff9,605cf203,cced45ff,ab136c6c,ce77ea15,14766f3d,e844770a,e6b7f403,f5f7584b,2331d295,82c0698b,799cd7bb,3c59c903,eb5d6848,72658c81) +,S(8893aa9e,49daeae7,15fc2959,e4db9c45,1690438a,6964a2c8,fbe73133,35085eb3,70fbd83e,ae803f3b,6377a4b0,265f62c9,bd15cec5,baec8c10,d01c7094,e5987cdd) +,S(be57f6cf,ac6e8cda,871e3ece,8aa78bc9,2cd9e2c4,8f3adfd5,6e39414d,8e0207a0,78170872,99abf89c,fdcd141d,899aa7ba,8893eedd,36bb3aa1,58120f2b,ee93d5f2) +,S(77fa6d2,85a01129,c5e05ddd,8d02b5d4,a2f69bf4,5a9e7562,6718cb54,20b34925,315bb23c,13a3d218,ce886288,ec0edfeb,37a2da99,e017b97,ce04db45,326455cc) +,S(2fed7bfe,8414dc33,62c834ca,767ffb0e,61094ad,978ddd00,b2ea09b8,d1f4dc03,14e5e8f7,aa0b3d31,565e434f,11c61b,63332a60,b6c4cff2,a6de2c5,98117e01) +,S(9f4c2cd0,5a871ba1,fcb43df2,bf03ee3f,7f8af242,ce8ee6a1,1aeac89,b4d66c6,eb421f52,f2427887,8ff8a2ab,dc384e23,d0fd7df5,fc341acf,83bc5940,be922920) +,S(53c0e0b6,824a04cc,b7203ef6,e37383f0,15f0a48b,bbc1d3ce,7c8fa7ca,5dbea647,6a9b598d,9246ca1a,539729f9,be809397,13c59d5e,105a8e91,836fd3a1,4d618cf9) +,S(dbc0cc82,d7906b84,b6b7bba5,433d68eb,bb20fdbf,7b4eefd5,c0a3ad8a,ad17d714,5ebc1f86,23ff2c3a,6f81b090,4e5e6338,8aee42e2,85306e37,a4fc7676,2dcd7211) +,S(7862af32,a3c08e04,7b1a8cbb,8131d55e,ca93a478,40c52165,af20aa6d,248f5f0b,bb5f6607,6b10353c,8a367a64,587b3bf9,7e8c272e,8da92684,f1efdc33,8bfc15d8) +,S(d3571fc,800158b7,6ed2bad8,15c93b1,f8238fc9,b8753752,4e44c0ca,931049ee,162dc9e8,3e6630aa,9d0872fa,915af449,70a9e6f9,526bf15f,4d26bc74,82a44bc3) +,S(a851c894,cebbc758,642b98e5,5df3584f,b9f531da,88faea26,e908b0b7,88589d9b,74702d5c,adfac1ef,71df3898,3ae433ad,1e1af1f9,b5fae0e1,151258e3,b375b422) +,S(a92e43f4,12effaa,e0978a08,cdb2e885,2d9af1f9,1f0931e,972016ce,da58012d,d8f5a09d,5560170e,b35d7bd1,28252096,535c687b,23bc13c6,bb903b95,d02fb668) +,S(75cafe44,8b4369c8,42e658c6,4760ecda,bb29e129,d283c24c,9007fb5,f3cff6bb,ca0e12e2,43c73553,1e2affab,51d4738a,db1ea5a2,fba215f5,3c9477b1,b55dc39) +,S(ab0066,4db959ec,2f17a233,78023b5a,c48c4177,7b6e6b56,a2148453,8c41d006,8cf9e2fc,35545169,f46762fb,940758ad,e3d3387d,eb72e9b7,b5d37175,9f5d8b31) +,S(27510ef8,2e4b2134,180855bf,469d1f0,f89b9afd,573f2781,4a1bea50,9db7ecb7,20fe00e8,86b54c06,1fe07355,5be99fd3,b0a1b20c,dec68aeb,90055c34,acfb87e1) +,S(773ff5a8,d388277b,7921405c,99c9c207,f4a6c2ee,3b59ac1d,7452c8ca,4db16d3a,cf45e631,f51cc65b,afc806bd,87318e3a,f75caf,3e734284,8d7435be,f8a52f8e) +,S(2f8f2c98,e69ebfc3,b7277e35,9da1a8ef,4293fc37,2e24386f,e14cc455,1ef45746,f85d23ec,c4dcaba0,23c3e406,604aaae8,8150a6c8,feea2c36,42ccad40,9968ec06) +,S(1878acda,ab8dd0e2,a0884952,26356ce5,74575678,64da41c0,61a83de9,6277f67f,412c868d,64e092c,ade96f05,bfa48af3,ecbcc128,e6d09bb,9684565a,d5477020) +,S(8cf281a,eac4e4e2,7ec4f3cd,d1373f62,c5a17b0f,49cf69c4,cad8c4bc,4f5618c1,2f17f995,29c9ea27,cda3911e,de33029a,7dbf09db,64ffa625,cd9fd86f,29ed5973) +,S(3a597c9f,f165369e,5d90d191,3dc2aefe,a0957936,717f1ec3,9ea20698,d08939f9,8c2203b2,90c9a2de,5b464b0,988e07,a7b48c86,f5891926,da462b4e,b00a14d4) +,S(cbe3205,96f10ff,5de9c861,55290393,b9ceec90,bbac68ac,5054facb,950ca15e,446cb06a,b76aba12,c32b4855,716001cb,9bf7c72c,ade16bd0,5472b947,4fee27f4) +,S(4313c9cf,8224e70,18413b09,e6544731,1cde7100,5ee60bd5,3a8db041,56fed594,dfaf359d,d3045a8c,b181021f,9a025208,e80bbd4,abc4a331,7ab9d735,1b329a96) +,S(cead2b51,f8d8adec,2d89651b,2da5ffa5,1f5cbfab,19fb7688,2bdf0faa,bf73c60e,ab2a2480,6992f0e8,c73e7932,2bf144ae,6dd3bda7,ed2d221b,f8451ca4,56a25897) +,S(9ce75c8d,848762f,645164b8,45ee6eee,98e34dad,9f8be0e5,2d8f27ae,4a7b79a0,e0556d4f,e11ba906,6b97c04c,8b742a26,9f627559,b9163571,d0a29dbc,9aa30a05) +,S(6024489c,621de255,f92106bf,8c23847b,10214b83,1d653a9,6ba00889,326741d7,950eb24,80a90200,ec932621,6b82e5e,abf63e08,6626faa9,b1fd8e2e,104ea858) +,S(d3c746f0,108f6bcd,406c2638,c07255fd,1f55e1a3,c6845e11,546d22ed,5f08e51d,d124dbe5,d349c739,e641a776,c57ef3db,35ed4e1a,6ffc165e,25d0bcce,438dfab6) +,S(a1eb5f5c,d85dc222,f97b9e11,e08594dd,a69c69f9,bcfa4c63,52cf2717,136514b8,46ed3d35,a393e017,76247ddd,7dda3ba0,ff5e3f76,30253b68,750a7c,f8a15fff) +,S(2b24a357,fa3ac2cb,faa5f1c6,1c14147c,e4406556,b82c7639,721f7561,485a8736,d67219bd,707aad55,1a8fd7ae,d5721d45,ad192a5f,5d0b643c,18330cd,1bd73ade) +,S(9901a1ab,9dc60159,63cc9cfb,42ecb41a,ab6a623e,62e9f306,126a4f6c,fd87b2ec,8f766594,17cd7f2,fff7a3df,6cb414e7,eb5950c1,ee265730,633ccd8f,f0339317) +,S(311e8445,5890e2f1,e1d8e600,37d58c83,28a2a4e1,b21c3763,4aeb9965,8477e8da,cf593f67,6cc75762,a1b0dd00,f6703bc1,e017e927,1e61c829,a0459056,ecce030c) +,S(905f72e3,97140f6e,298ad8b8,c8faf66f,122d27e4,6fee88b3,67a8ecc7,9e83bb77,c03f155d,bde9c265,d90b94fc,1b5b253a,2d98528a,a12e19b4,698714a6,f1b65257) +,S(61df77a5,d5940001,2fcc2f02,199cbb4c,39eafd33,27dc85e,4a3f55b,a339350c,27c88b7d,de9b3f,73b0603f,2d6e40f5,f3664020,8d6dc05f,684626a2,d9049161) +,S(e1f8e199,886d4b1d,5dd6af90,6eec06c7,de36dd4,ef026129,5bc42bac,5df18c28,502c12e9,b956eaf1,2865bc4b,ae7e6348,56a98db5,4c65a5e2,9ecf8ab7,51ca45a8) +,S(ade2f5b8,3804a21c,7dfe6a7,7044cf96,9180e154,79a4aac1,9b686076,fbb8565a,d0d65e1d,7c8168c,308985d6,f5d267e5,98a9e6f6,45715eee,3751bc26,ef066aca) +,S(c55820bb,154f972,ac345dd5,c62880b8,9f7f6b85,a1755b88,ea5821de,6f268187,911b0fea,1e6ca659,263b698c,8a17488d,4dc35f5a,d817e7a2,1241e56b,cc613086) +,S(ea20966e,321020f4,53964352,b8ccc2d2,1285888c,152ddd08,9f7039c6,6c7778b5,c942f591,cdc81e52,6abdc9bd,643429c1,66f5476c,dde18d39,59e29f26,9f4fc18c) +,S(3c57552d,9c2dfe5a,67301bbd,3e1ef84a,220c908a,8e80c707,9f9f4df4,607e2bf5,d49fa0ff,bc4a6397,3e71a0a1,7265ff65,6fd34754,ed508522,b9f0200b,e71f39e3) +,S(f188ccc6,e1043ec0,59e8e133,94ada165,a3fd5c0b,cf7f071f,eb5a0951,9bd4e1c3,5f1f371f,e53e79d0,2d6fb190,8207649b,db045c41,a2fe1cf,94486053,7bfdbe4) +,S(a0145fd2,7e72232e,8055a146,aa7bfb49,447112a2,d1ca53ca,d4835e42,c11c8c6a,7bc018a0,e5e70ccc,c4bb675,f0709cb0,ceb874bf,22c7ecc5,243e49c,3de679cc) +,S(53400de8,c221153,1fb85706,b558185,c17b7bd8,b17416bd,9c93df80,f16ff48e,e1228e47,3ba565f1,e50840b6,a36ea970,2df87320,8a66a44c,89cd33da,41a6cc6f) +,S(82115d2d,9d37e3,50ce3482,1d59af85,cc8960b4,52b99904,8c6c6674,ce64b1ac,98deaa09,659a0c24,4aadab0,3b9d1881,bffc1b3d,e9226f05,e75fb9ef,b61eb048) +,S(273d8c18,53d86f1c,c49e6e9d,450dce26,8669cb7c,3083968,1fc17894,59fe7c3c,6c5531aa,8ad026c8,174c25a2,51efbadb,14974e1f,7f7f88af,2e16d101,c2ea00) +,S(616e16,a7e38191,70e33f4f,bf428fcc,41e68ccb,5b059bfe,4036751b,ba5ee319,7dbcad21,182a3efd,b99173f5,cca99374,7c7dc3c7,3e8af2ea,ba84b0e4,f506748a) +,S(6761896a,76a39812,1f773402,d033f210,dc566610,275f6774,52c37c01,60b82812,7fdd01cf,1b40939f,8091184c,8e2c8ce5,11848df1,a23607eb,e760782e,67302c9b) +,S(77f7abaa,e97605da,12535bd9,e177b6b0,bd6eb020,92345fe6,dd4a6d4f,89e508b9,fb04996c,cc7b830d,fcf5fd19,bb7c9332,dbf20fa,10d61231,889e4b65,cc7f0b9e) +,S(c12f6717,3a2e2bba,3da97378,501f9cf1,bc4b4a8a,67b0c5a4,a0d8caa3,98bce311,de930986,44d31401,510012aa,3b6cb541,97cd133,6e583853,a330319f,779a47a8) +,S(6553a2de,19c7552c,8db9d268,ddf3a034,4afe8ffa,a76bb304,ee77ef95,c18e66aa,91a72010,7c180bb7,2af4dbb7,752d374d,69f95bce,c9bbb7f5,37377060,70edb93c) +,S(f54b4be,353f4185,22e2e936,3400caa9,bba98023,e6a3d3ee,c1fc5046,b7b834e3,96be786c,bdd5f1f0,a835afde,219745ab,ab6f78b4,577d3a5,1246437c,8e96f17e) +,S(c2d317c2,a0fa6522,bbc806e,45b4dc8b,f86be37c,4b677c64,c0d5b4b4,eadbb2a,c5710969,bd68cabb,718cb16d,fc9994a7,100f078d,4a3aeaf5,8e8eb35e,d313ab6a) +,S(52a567c6,a5b8a64f,dc74b9c9,57f5d472,cc43e143,4136fcce,fe1ff313,1b89f384,332631bf,a314298a,dd45f7d6,b8192956,d7de27e9,7d835d48,5c16f7a2,9c9e8f53) +,S(f7dc086c,891a4412,88543527,831247bd,3530f0f1,99b4c5e9,8d24a207,1dba4e20,734ed712,452e59ae,b0ef5f75,10485860,da055003,ff1067e7,b82de345,b74444aa) +,S(954f9fa9,7bb6dbc0,cbed8d8c,de6f8f75,b3f2ae51,e512cd3e,90520d8b,22ec06c6,b65b43bb,8bd9660f,4bdb3017,bb4f8214,5426f614,8f04378b,f65c39db,185dd9bb) +,S(20e69b98,41416588,20b66947,f775cd96,6def2dbe,416b545e,8188db14,2604e87e,e6514659,bd12b9b,35ae45a3,d43f6023,dcce04d,87df1f51,caa67f89,28632539) +,S(5cde5b82,2dc42f04,44187fb5,33029577,71bed484,2ab39dc3,709e7c57,c72ed1c,a0f7bad8,64e405b5,94416e7,53fd6137,cea3dcbe,7625fe41,b4929299,a9a0ea9f) +,S(b586cb4c,6ba6b0dc,2aafd03f,49d4d6e8,45b20460,5de71c34,6e73b131,fb26421f,ced613e7,c26ea3b2,a31de623,506afb86,6767b469,98bb116d,2b4ac9ab,58948744) +,S(7d3f6170,35803a82,c8e13dbf,a8d601c5,4e192a54,377e4a8b,2a2a5de6,90ba6ede,138e810e,62f413c2,fb56477,80c0bcbd,77eaf84b,e78e900f,1969f4d5,2ec6cb15) +,S(e7a314be,fc4af863,e7fe6713,5304ab81,c9fa32dd,80fa9b41,d8577ec2,8f7eb925,cd978600,f0e04acf,fa99b6d0,7da970c1,13ec94ce,c50808fb,91a44f4,80f3eb1f) +,S(179c3be4,9f41902e,e21cd8e8,10f0dfc8,ba5fc0ad,9e454231,ec090263,d3c6a577,75f9f60e,fb9b9aa0,29eb03f5,a50b7e4e,64021689,a4e889dc,5b9ff0cb,4c9cf184) +,S(10a55871,464bc182,b957808e,25754fa5,8d76269,5cf8c6f,e50610b0,91e6401f,d36493b9,6d2bda2c,e305c679,f906ba9e,99a787f2,aa8cb8b3,29516a3,41b56ff4) +,S(4a903722,5e858c84,15508d45,b31ec7f6,585827a2,f3a9c99f,96af3e9a,e88e555e,da4d45a7,fb9e44d0,cc52463f,20fcde14,31c9a477,d02c464c,70c7d132,3247d145) +,S(6d109d8c,2505808f,7b4052d6,b170ec80,c68373bb,e02f2b62,1cd29773,a96acb3e,c8dea0de,511f6e40,5141088e,cb023bff,200c870b,9cb952ad,c5038b28,eadc9a57) +,S(9c219898,6d202467,c055c734,73557505,6105b3e,2874dbf2,8f7f0c39,66e1af88,8637496c,8eddff12,f9dd4146,36565e0f,efddf5cd,52d48455,ec9fb2d,8dd0914a) +#endif +#if WINDOW_G > 13 +,S(22ca5039,e660f60,1036dd75,2bb973b,dcd104b5,dcb8f2e7,4de8edc6,c292b03a,86fd4471,1ef6b81e,4416449a,708fa0c9,cb6731ba,c403e58e,da5e915f,646b11e8) +,S(cfc18f02,cc004640,f2116fdd,1f6ca202,2e39be25,df75e27c,80bde842,e6b6f938,d62b58df,4f79d0e5,97ba2923,f708cbe5,c09236a4,d9d01398,6451d684,6290df7d) +,S(3388bcc2,3425458e,991f46ca,6235c50a,57490556,becbaf25,9d3c14f9,9a80a087,7d4aa2f8,6f65783,1c22316,6958fbf3,6c3dca5,d4ac413b,3102e13e,a645c016) +,S(d26bd013,1b8c12de,3dd8fefc,136d9f95,44ac963d,4cbcbaa8,2ba941e,f0b46a19,66f89ea3,31b6795c,6b694872,4cab492a,d045a7d,a6780653,cb10ac25,b68d3a99) +,S(dcd3370c,db67e8f2,163960ed,fef5f66b,465a03d4,d447f5ca,1d99d29e,57d1fdb9,8b93747a,320abf87,2cf8d448,393bf732,8a9eb4bd,9b64ded9,922616a7,347084ef) +,S(74074d05,e602ad56,337105af,59c63819,21d449bb,3fe0806f,80589f3f,4f8d8e7a,1a4d4bd4,adee80ad,44fd515,a1dd5236,bf0dd8f6,c44782cf,e19b8414,b03d574d) +,S(a89cc81,f3a23ebb,6a8df438,a78092a9,97120394,d6bb4dd,732373a8,2f05c174,4b6f83dd,676df063,4e5ddc9f,db979dec,326a9ce7,5707fd77,873a9644,a3c4fda4) +,S(8f1a10ba,fa913f0e,1902ae36,b07f964a,6443c540,b60ace03,7dda380f,6616424c,1028d644,45c177c3,24416ad4,e740f31d,14e3a462,d5a0326e,86998555,5de5525f) +,S(ad8fda79,14f9a236,a7957268,ada499ad,9154a2f8,478fa6d6,f4c74048,89e27b51,9ca1d2ab,1f7da6c6,f76deffc,5c3c933,703b74f0,26063834,6174e4be,320e82ae) +,S(6c6e990a,797b2970,4408cc24,6f238e2f,2192700f,e4fb3c87,4d15e32c,fd67fbe7,1ffc1798,f355659,9fa5b32c,c040da31,39811b87,93d4d9e1,be83061a,3f91dac1) +,S(202b13ea,31ad2abd,9635351d,e09f237b,9f86f75c,a340a47c,edc1f9a3,25118969,c52fb505,a14e37f4,d5111184,ebc81873,868a4521,700004c0,fe3cc535,181bcba0) +,S(5355f0a1,25142fa,b0dc7c7c,f9855953,34053c6,12326f5f,d2284291,d7b748a5,75bbe36a,553501f6,c1c8ff9d,e60ee3ef,9cddd36a,781c518f,4b1ccf17,7e281949) +,S(b8852d78,eacbdec9,d1cf1664,4a83aec2,79a39ab1,34706235,f913aeac,c29829d7,763bab50,52b3c61f,ae42735d,2e89ec3b,8d51eed0,f729e0fa,eb431613,df183156) +,S(cab2e44b,294df78e,1c17d4d6,a09ecd0d,696d18e8,b0f188b,eecced5b,7057ae2,f351b09a,501a499a,ced49607,c55b506e,de28bfad,5b20ed5,4059a068,19ff2f43) +,S(1400b9c9,9c6d555a,2bd2355e,b54b756b,b16f9f36,b9b86658,9d46853c,57056b31,8b290816,62f41167,a0a6993b,3d4211df,5709b91f,96f24436,e569c32a,dfa077a8) +,S(52ae372e,973e9c1c,687ae7a9,a111446b,b3d31b19,5588d8a5,fbec6e6,bfd9141e,f982b40d,e6d0e42d,b9638721,a4590db4,1f87cfcc,d8ece56b,71ebfe0d,82351ccb) +,S(3d14ffbd,40824625,be241e14,850dc030,1139b708,b937f2e0,fe5f65db,61899c24,b10a64fa,477ee047,4d9cf16b,8d2213a2,799882ef,d3766872,981fc761,88a1dfb7) +,S(c6f52adf,54e0c197,a8bbc270,d4c987b,e7ab3fd1,a95fe46e,82415ecd,baa48930,7524c06f,b53873b4,9050281c,99fa44b,b9ef9193,2adeba8f,77e5afd9,3856811d) +,S(90089264,bdc47cb6,7a3c838a,4c79c1c0,5f2d1dd8,6d18f55,9fe60a3e,c944c1aa,18963846,d70b3226,6a9d582c,c430e4b6,ca140bcb,91de7064,eea0fb39,d2ee04de) +,S(e27c24ea,478b37c1,6275b2d4,ce8212a5,2db74166,96f3c6eb,c1bf7091,efda0662,27ec5279,c3a267cb,fad532bb,5031791b,bb99f4da,fc3b7b7d,8537cf09,12783de3) +,S(ca5daa12,9cf1d6eb,70025d85,7955d3bf,2549b8ee,6064092b,917eff84,c40a3eb2,682d4905,500f6f7d,33e7c7c2,7d420b4b,7c4aa5f2,77b89e9e,f6a84259,de7a9811) +,S(9069ec0f,2b2ac688,46623fb5,c89d1424,6c98ac5b,4250c170,4871699e,fc877f55,cc500ec4,eff83712,16c0617e,e2407dfe,a6c3c3a8,c8b80266,975d3a56,e71fb05e) +,S(5fe1feeb,bd5ee1b,6ba742d3,c5e8aba0,536393c,592650f,b8cb1391,c3bda16c,db11b327,1ac64ed,3425ba06,8072f76f,ea02ae6a,4375daf5,3bf942b7,9865a34b) +,S(a4a91a5,f168f883,49035b6c,f90e4e0a,6bf2602a,85e0ccb8,31866c4a,ac1b2c34,5bfeea8,fe36ed1d,18af2ff8,e2b898aa,ff7265a9,c08f4857,ce082030,7f837596) +,S(f4135f36,f0c35b52,4a870505,4eaabe4d,43f5366e,d3c7d9e3,5f06f746,fa884849,1c6707f1,b8b6c078,b4d9d0ea,43075d75,ba1a5d30,c3a9c52d,d55fc4b2,650c526b) +,S(d5a8998a,9363fbae,d2b44992,883e84b8,14a504d,92b41e0f,dcc3a9f3,94380203,96016b03,6fddc805,8bb8ae7c,6d46cd7f,2f20c5af,a62abd4b,bf9b3da,ea60e9fb) +,S(8804ca34,4b30dbd,a07fb62,210c1938,d50297e7,9910dfa8,cc38b9be,4bf3d176,5b64bee5,79927c63,7788c55f,f3871631,eb65db50,b11cac91,24caede7,57d37b0d) +,S(8691c1fc,440c21b6,bc48e78e,78bda5a5,c947c74,7d098e74,ac5dbf6,2b811021,fd8ec1c5,35f51181,556c330a,f02a7110,682f4539,f66c1c09,3d48bca,d7b1787e) +,S(445fc1f6,343be2e1,fdebfe3f,894e9293,c3ee5fab,b0ed01eb,58a40637,ef093229,857f17fe,6737f853,d04aa1b7,3eded13b,c3c087f3,48da90af,32907bdb,7d85b605) +,S(5c397fde,a657d1b0,b2e3aaf9,5b88c4d6,af1a5555,a1dcf966,7d1c5001,a76493b4,9ce74820,7b6f3c75,2d736aee,6a9fc54f,ce5cb52c,f487fd32,de79a06f,df0aff0a) +,S(9b5565cb,28d7e028,361d2bc5,bdfe1912,d9f53584,372d30c1,d7e36fa4,c7fc1b7e,7d5cfa8d,2de2a832,58a57f05,4e3f6c6d,a23af075,d98b062d,82799b11,63879eea) +,S(afbdec63,1bbf870d,3971b165,71bb195a,a5229a9f,1012bb4b,89654da3,c9194f1d,cfcba749,b9492525,f9874ad1,bbb0a267,83fe5714,1f54316a,773c2453,8f27e296) +,S(7712abcb,ca3a5347,5cbc6160,5e9e9ec7,a7cc11c6,2c4b3f4d,e01d688,acad916b,7b91c9bc,eb12555,ad2b43af,8c3bd332,b57cbbfd,1ffefead,c68f0a2,6a4b82fb) +,S(3c452346,f2935e41,2e5fe506,fdf5066b,11b43a11,66e75c9f,7a2d38b,1ca2b7e2,fd3f6de1,27f96829,3af532f8,d4811fd9,e02038a,352b6696,2c608c7f,f59cd800) +,S(bd8582f,b4dbda3f,c7da53d6,70c994b8,e04eda44,ddf0b054,7d182db0,aa48b7be,799e2769,c18268bb,8c16b282,ee7d0828,ef0dc4b7,9767033a,d6de8c63,45285c68) +,S(c41010a7,8dd9dd40,62bfb71c,1691338f,befe03ea,d99eb719,74dce6cf,b2c84112,5008c39d,e71ebc22,3b1c5dbc,f824a63c,f270f807,3143e08d,29b162da,42a2ff83) +,S(e89e807e,6cf4ba27,6586a6,a509bc8f,f786bc5d,dedb5f4a,1b6253cc,2521d311,aadecb79,7c4948de,9379fcfc,4c040029,2228f9c1,c099117a,ad6d9949,f2fea2cc) +,S(363df1b3,be2dbf90,64137919,51218c34,84091f73,866f3fdb,dca1b90f,dcb08577,aefd04e,5634e36c,49621493,f7e76f20,f9ea5b64,6309a605,7e3bdf0f,75848bae) +,S(5c8d1638,83d2824e,48121322,85cc44bb,ca8fe33a,34d5c3be,cd4a3c8b,c78ea16e,f66f91d9,c7ce66c0,89500591,49f7525a,355347df,8f31a685,872aebae,1ac0456f) +,S(10ac6676,83583ed,d837789e,ed9254da,4181dd58,be75dff4,8085e87,eacbe126,6d3eaade,23f3e7bb,7465acb,c6b25af,72e0dba0,1815ea1a,1f57ebe,bb17d22d) +,S(1e79a1ea,7bb65540,44567796,2208ea3e,974c4c0f,9b61f7da,8dba697a,8c153048,b63e3d79,20a34888,68987406,4a8008eb,e07d35be,33a055dd,394ef2a5,f0787fc4) +,S(db0d1c73,97b0a23f,508df2ab,b00ff13e,11699118,11d6476a,7bebcd09,53fa9a5b,1c9d0877,3ca74f1e,d1972431,2b5c8eef,2f85fd41,6629cdc9,d0b9e328,4900dfe8) +,S(e1fdd7b3,481ece8d,266bdc22,92e775bf,96904223,e620f622,3a03ed,cb385f27,3cfab39f,28953ff7,d6dee65,83fdc6a7,d9b31f93,e2103e6d,9e4066a,970a4c77) +,S(96797134,2b69bb8f,3d6701c9,22130c8f,9ed85fe5,bf189880,3b2df11a,a223ffd3,2d43343f,630b6f9f,7c4b6d93,cd29a3e6,632c0dc6,c095794e,5997e47,e631d31) +,S(dfb40218,6e27d494,c69d2a0f,399dd480,ec0a776d,9a99fba8,cba81417,d9c33efc,332d91dc,e9f93273,15e45bcb,79603050,9bd8501c,17820f48,61f7b12b,5d37796e) +,S(6b65c5eb,ed13dca4,51608da7,b5c1a331,171de004,7fbe35e5,189b8468,c27681ec,afd0ee8,e0aebc0b,2f246b51,f6fd4f85,3e71fc4d,f5bb9f43,e2679c8e,89a34f62) +,S(bc1c3da1,60b03965,e26396aa,5d426df3,21e5c22,fdfcd004,80a390f5,28c4b619,fd657174,65e4fea9,ad7862c,422c11b,86ad94cd,35acbbc8,76ed464,aca31640) +,S(589b1d17,96d6ca35,53f8a6a8,cbc587e1,9026406,c2c6f8e2,de613dfa,8c05913a,e655d5ec,ac254f46,e279365d,e3bba2a4,3c7b6469,da45ec87,9742cbae,503fb3e0) +,S(9e726385,6d1e6c2a,94dc2ef5,c92d94bd,6ada63cf,cea75677,6125bf98,78ae4ed5,8c238df5,1e5b38f8,b628a48e,dc7aa2b,a83bc40,43c91896,69f5341,60e304dd) +,S(12269d78,14e0f74f,ba40c551,b2080e00,4f9bd3af,255218d5,7eab5dbd,c6764263,f0f70bd,6584975c,106febcd,bbd16920,daee58c7,c22dda70,4a95f864,e385b3d6) +,S(d3212f2f,cc509014,e0c48cdd,6273effc,5c73fdbf,1676faa3,15e9173b,573088a6,39af39f1,673f51f,362618c8,49c6934c,ff59b6ea,853fafc0,9db64084,4832df82) +,S(c535f72b,9bcc0bad,44014e72,4f649623,4ef288fd,9f42adcc,dae45a20,84250052,3f79985b,6fb7631b,62814a17,f7ce829a,88447302,293000a7,4655c7ee,4a271022) +,S(4f5b7126,9b169fa5,8602bb18,60ed0df7,271e3912,ec0d7c12,1c80fad3,93399605,b60fc104,7f2a58ea,9102c6cd,b97c932a,576f63f2,6204fb5,dbe41363,cdcfd0a7) +,S(cb459b3b,244c38b1,af2c2863,e0029c14,ec70e7d,737a7851,de9c8f1b,b7d5d065,7b67b15d,3c0376c8,2f646241,1e890b3a,a888bd15,692c90ea,53a74a4f,1957fbd0) +,S(787d61c7,ebde0c5,18f121bb,7f434196,d389f563,d1a46597,ea72a1fa,4e19054e,5baf56f2,5fcf8cb8,c271cf39,6b3d150b,f42e9ebb,d72b54ba,4b93bcbe,ae72a658) +,S(c38afc2a,31d0b0c9,4b77d97c,bd639082,3373538a,602352ba,cc93b6eb,c5f6115c,b925dfca,b138fcc2,4b9a26a4,c645f8d5,875e098b,d2e58469,d842688,43ee529f) +,S(37661e3b,8e606e95,b9dc6ad5,e5b9b25f,39a5dd0b,8ab7a82a,d6ec879a,ff406d0a,ab735e5d,430d8fce,1317e07b,d6cf9441,60d8bc39,132382a4,df1b1638,a7e9b977) +,S(e5127851,b8c22b47,c3d8e934,8dc0c677,88ea5ad9,f64e6062,abd68a16,51e256ba,5847f77e,349eb7,90b4b7dc,5537ffa,5b1e7d4d,b87044b3,f947f387,270405c6) +,S(f3c7f45d,a6b8a8a1,3713e7cb,7380fe06,127a3698,520bb41,955647b9,ad7382e9,2acf9a11,eb1b9d31,f71decd0,90093677,4b469301,719d4a51,ddfe5fbd,f63e7c87) +,S(86de4047,e8d5b252,523733a1,848a990a,79125f95,3bb0e4de,ff4b2f0,84d745ba,71e6a472,dac005d,2b284cf7,d5de92d3,56921105,1a9ee007,4279a746,71bc969a) +,S(c6115c30,72259d66,d960cd96,3f3aa16a,3029d9ca,c0c5ec63,5e2875c2,f3f57504,18d690d0,b33fdd78,d797f56c,23c821a1,ced02401,3443c770,50d12850,9f7a712f) +,S(cb545099,8b43473b,91838cbd,76929b05,8bfae0f1,e2bfbc6a,c61d3674,42f53c5b,4119d74d,79e34f08,cd7684b4,f9b9df55,c00ba8ba,7bfb4ddf,de38db78,91572bbf) +,S(d0dce704,b9362bb4,fb1771e2,660a98a2,a333b73,c6d09372,5a752f28,52922d2a,f92c3b70,7947ce0d,f1f3891a,259cc2ee,124d3f54,a4c518ff,de5a3915,96e37e47) +,S(db93e238,e5aa5986,38eab857,655cc53,d4270259,e7d73a96,249a19bf,216b20a4,8d19dc8b,670e8eb6,50b4f60c,d26ef657,3ab17895,c62fc94c,815d7eb5,fbbcc7c5) +,S(c387c37f,d8cebef8,29e07e54,b0796129,4d6c6cfc,bbf11835,ba85d4ef,68c3f486,852580d9,ae7eb300,6ca0f7d7,f12d7fe7,c8e3ae0d,b6258897,994fe78e,11ddeda9) +,S(ebb58d34,f04de551,37c01b5b,192bb4b6,4d3b22dd,23ad9092,f943749c,7606c232,1b979d05,9c99f9d4,db1d3e82,905abc9b,d92ae72c,509c912b,c59488fc,ddd1ae16) +,S(7891cc66,acfda29b,765810b1,730cad13,2f13178a,fbf238d8,2525ce42,96e38e6b,22193729,20188c6c,462987ad,7ecaec3,a21ff6e7,db00adb9,72facf65,367caaf1) +,S(c0b02542,e4bc1e8d,2c2578a5,3793fd8c,acec800,c0a311f4,72c50de3,5814d081,24bdc71,f5917c0,1ae6bb5,71c09197,76b1a884,ebffd673,13698bc1,b57f8371) +,S(ea15d574,b8704507,f12fd9a3,e40ea603,c2000cf4,4eb3d4b2,f07a36b5,c426d2dd,b6596d4f,4d8ca39f,4e0faf58,ab7e3894,c5cdc16c,589a524b,6ca25a51,8a30944e) +,S(77d387df,c35a6af7,b88d5726,a249d34e,70877698,1358c672,6e51b779,cf9604de,e5daeecd,2d70a962,d2d3c235,14fa2b1d,45916506,de017249,93fcd9a4,f08b4a87) +,S(a92742cb,7d1a24fb,c1a4dc2f,9d6fefbb,1064f9d4,c3152db8,3296a9dc,9dccd7ec,665a9cf9,8cdaf0a4,ec346df6,823f3c6,66d4f163,b3e7225a,d9d18e42,31679f76) +,S(253e54f7,9f0c393d,5d34053d,37b55304,f62de9da,29e0eb6f,36cb105f,a6316a46,54e168cd,ed78ec0c,32a9417a,c5b27ef0,67c8577f,8fe0bfd7,b2ae33eb,ce7155e0) +,S(d13048e0,e9c38720,6179586f,9e38029a,55fc01c7,b33d8443,4ee45cc0,3fbf2,7c4466db,94502477,85490689,7b251c39,af257840,b9bc61e3,64075080,84743f37) +,S(e9234110,387c2122,2887d079,7bdbc9aa,a632b237,2a5632c8,8e604653,70a284a2,2b98b08c,4ca3521b,4ffb3afe,66f98ed9,839a2651,f740f63a,e80b0cfb,6f6523c4) +,S(302e03a7,ab6978ef,73891a5a,7bb25764,7428341c,94f8a713,32ba9dad,83a29be5,4abe0adb,210c35be,b2ee850d,2e56bb3f,e8430db,644082ee,a98a2f83,5710120b) +,S(53701389,44400f30,dca0571e,eb0f8c7a,4fea8bdc,31d68859,8d7cd156,11665368,ca345664,39c1f221,a5731bbe,5a9a36e1,a712e2db,f16a6d19,71b1a74f,eaa97cbe) +,S(8c0e8186,645d7cb8,fad2b6f7,a5a2d399,656aaadd,5423cff4,9579529a,f28383cd,2ef275ea,14c44981,9307319d,18fbb482,63c6d24e,c94e18ff,cdcd7757,4c48d27f) +,S(64a70831,26baa3c9,a11615c4,5ff8ca99,adddc512,c697901d,afc43d7a,5fad8af5,ba43c48b,59a65f6a,c3a45c35,4bb17968,148efe4a,288f742c,43253e70,aafe29d5) +,S(fdbd066e,82ff8e24,b2f785e2,e166245f,63559acf,b4f56680,51db47aa,5d438e06,60dadcf,a19ed8c2,376a5d38,28b9499e,875731d5,b2417def,144e2a84,12973d63) +,S(b287ccb8,1ff90731,19ddba01,d9461512,82cf15cf,2dcb3e0a,f1b26f41,eead174f,6ff15339,7a9a0bee,4b38a463,5db66ed2,36d1beab,c0039bd1,acfbdc09,fb74e090) +,S(18047a48,b65234a4,fa5f2188,8b3032fb,3b3f8457,1bdec3c,962d5cd7,fd068116,13627669,18198832,306c5444,6cea5681,80134209,101a117b,1f34e15a,624574b) +,S(f1d3b54f,be4e2ce5,88a2dd32,8a41e136,6b74ffe9,5bd4aaae,ce7e7a8,235f914,37c25d41,300e817e,b4ae1471,e8486232,c0c21165,97efe33b,e86d6277,a8a3981a) +,S(9b0da9e9,5046dfab,7ff509a6,10ad56d,9770da36,c5e22a83,9ce3a36d,853bec4a,27d60345,30c25a36,e80bbc3f,f43829cf,df757c19,1a2924d9,6da77503,38135faa) +,S(d0833bd9,5155d18b,be55d40,3717568e,2d3e4d24,f2eb65f9,f13d8d65,d899c5cc,e509aec3,b5044ab5,11fb1e4c,56db7146,ffeefb82,ec4e9de1,3c473bc9,964741e8) +,S(8c41627c,185f17e4,28a01b40,27980e6b,ed62ad62,17c9f8a6,26c329e2,2fc37117,75ca226c,3316a552,37e8a1e7,483f73ee,a36da441,c732dca7,7d95b7b9,3a3662f7) +,S(371f0105,e43aaa30,5cc7099e,9a13b97c,2d75c26e,5b50b11e,7cc6283b,27728d27,c969dbe7,d0976d68,8cc64312,4538ead,b1194426,cedf149b,293b80c,6ab3ce99) +,S(5102f59a,4238a358,f8b4d3a1,85d864c2,d94aeb83,7a8f3e03,541ffbdc,2ccb1710,9e14c4f9,adb63c3f,4cd30606,cd41cabd,bbffdc3,89e996ce,91522093,85ef1445) +,S(ca21b6c,fd40403c,78353c7,836162f0,a7f57eaf,bd4a8cc2,6df2baa7,1ff08beb,108a3c46,47eba55b,3fd9f2ef,751edb0f,d6b68482,1424bffe,e6ae3e58,1f7f12f9) +,S(d9cd44b3,ff40d19c,e8368bc8,200e3dc9,7ec3642c,acc40769,7c94e68a,31d775d9,b6b6fb6c,683ef701,d4cf7101,79de4af,fd7c4a1b,5babf3cb,85c95eb,485f0901) +,S(9a1354b2,cbcb6888,bb564426,71bd4904,510da508,3fcc61e1,4fbdf44,15a10360,3f5f5291,707c48b4,4da3a2a8,93e24037,bc4927f3,81dd9b9b,710e8b82,874f953a) +,S(c5e55e0f,271a81c4,ae7deb0b,ceb0fdbe,20fc60c5,38692941,bd50ab9d,ad0fdf79,138a0f35,eab49301,7a53e7c,c62ae93a,85ed9e7d,708a00ae,cb10776f,fdc83a63) +,S(5ebc2f64,7f66bd3d,2290e4dc,6cc5f662,7c67ea72,599d2c6,9a004aed,9060f919,68f7dbce,df2085e2,27cf7920,65369637,3ec1e860,b10c8f1e,56e996d6,854659c) +,S(4f28eb9c,7d060dd0,5051a5a7,9a79c960,161d7081,d3a58b2d,a421075c,cf966e03,ec378861,5434741,bb2aeb8e,4a2afe78,44849f3d,2cf12a6c,2eff3e05,d267fafc) +,S(f50e20d1,ce113e09,850c7a9a,10b347c9,9fa039ee,57ec85c0,efe15b4a,1a83fe8f,4db7c231,90df41a2,8218595f,61407f20,cee46478,27d54aa9,4db9bfc3,fae975be) +,S(cce6b2d0,1adeab95,dd78cdf2,b55882bc,79de945c,d4249e76,ab2841a3,abeff5ef,1d690674,1312140a,fdf764bb,560b1bd5,bab1dbaf,9fa26bd5,604427e5,34626e52) +,S(55a65174,fb10557d,2ecc7312,15afcec1,e4830be5,2d34bbbf,bc80ed6e,9f2d8475,c69795f1,de1e537a,970dd412,65493806,3f0623d4,e7353eec,611c8917,278012c0) +,S(78221cfa,7b4db3dc,7e22779e,97ac8d46,d0c1d819,76594ab0,267ed28a,6127f290,8ddcd5ed,fd8e8c62,4883a158,2eab5652,ace0660c,2e358b66,3ad53e90,cbc46a54) +,S(9b985039,441ee434,ed4da39d,6010782c,9006cce2,8f92ff96,2b2d6fa,986ed178,e1cf85c8,7b537b2b,78bf67d2,2d9388c2,8a50dae1,73f003bb,85fe5f9c,12c6cfa4) +,S(9aa2ffb1,4a9e48de,57db9d78,d9b6757a,6c27e7b0,291dc4f3,8ae9f204,f7edf20,771c7be3,78e0f794,fe0066ef,8592952d,8f80d7d5,2772ca11,5ff8b7f6,377d1040) +,S(d1059083,66a0b463,17c510cb,40922a0c,949de251,6d80ec02,1e359a89,c6937e1f,84053a25,c9ea4414,a897155c,c45e0da,e5e6f2f,aec780ac,99c41545,fac8630e) +,S(1f3ecacf,7456984a,fedc2d81,2a81f7f,1ac58ad9,c70ba7c2,3e7a2ff1,f9c5d066,c6add8fa,2bfd24f1,73f4539e,f21681f8,15f1f362,e0f98d94,cd435d80,71a23e54) +,S(a312c709,a16d0cad,25551ece,86c8f947,5e504d06,eb3524fe,569cdca0,da2c4371,865ecc2a,ea04c5da,2089ea2c,66b5bb84,8c1fc29,ac7bf969,c778039,b3ae7b03) +,S(f21c4675,e829ba78,fbcf6410,9c2eed38,8c3493db,1017d69d,953f32f6,744197af,fd2c673e,43377caf,5db0ee06,1a37b03d,43d9373,482d3ef2,b37f74ad,98b2f57) +,S(116174ea,2a029a02,fbcb2eb6,1851ab31,f4836933,a73bd426,8feed7c0,18865692,2123d027,e1cead9d,b5fca2a2,d6f5d1d5,25cf3855,44b64352,ee772d4d,d70aaefd) +,S(358e77d0,919e4c6c,f64a2117,357e72d6,2334fcd0,f5e7e60a,962335fa,73f9d663,7ef8d620,6f99f403,10781985,988ac7cf,dcf5cdaf,a086a0cb,8b5b6eb6,7837bc08) +,S(509f7e0d,9e81f146,39157e20,3165faac,8056deb3,a813460d,b86c6daa,baa33fa9,55148e1a,340eb6c4,e6a8645f,93f1ad3b,fd12165f,c3bff090,a095b8d2,a0db6ea9) +,S(358e325c,185f0e26,1e9e30c4,9346f21c,a15c95bd,438020b9,ad9c7e6a,d2a4ed09,5fcc074,c97715b2,812ef690,3b3d6185,54aa11bd,34789b3d,97f9b65f,2d18c4b8) +,S(1e1c712d,bc00af2d,37f37e4e,a2589e02,e314c310,47890d26,8d36be3,dda2fc4c,4898f9a,e3136bbe,36798cf5,ad30b38b,974e7e75,42d4c14,5bfb1f6a,490655dc) +,S(a6516f9a,aa3f79b0,ff3b794d,c80a9590,64e31720,7361b918,bd797b57,23ffcd1d,c5934c6b,59f3b830,53f77b07,47c7c312,812373dc,ebdbcf9b,ed550300,3a54f5d4) +,S(e46b48d8,8b1e1b84,b9fab824,3044469,50cb5633,da599b79,295011b8,b1098155,43e9ba24,4a339976,e342e551,25974350,3e7c8a80,cd950a80,a5d79365,b0c94f51) +,S(ca7a5099,97a9c2e0,625105b,1df9e714,e1cc2d40,1227400,e583370d,3f65aa0b,dd8ca4e4,d2eecd1a,20d994fc,ef7cb0ef,19c61844,cd2ce039,b7a1eafe,66e1f071) +,S(326b5ec0,d29b576f,111352d4,b7786c40,8486599e,ec01ed0d,a390d586,96313f08,f4a3f171,a4ac654b,e7aa6063,3d5b2a0d,c2d5d3a0,3da4d264,95e828a8,1011d384) +,S(b762982,54f5c75a,a557038d,bfe9bad9,7c5bf8ee,e512fe2b,39293228,e70d306d,8b808f9f,b36e3e86,2c75bb2d,d7de8be,cc85c75,398496fb,f92db3db,143606c5) +,S(8bd624e1,2b1d36ff,dde50a09,6f1a811b,ae66f1a5,790654f5,ef79a21b,872286ca,6687ea2e,f4538961,b6731c74,744234af,8bf6a2a2,170544d0,fe9b8057,ad1f02df) +,S(ed25eac7,2a9f9290,bd414cc,cf846c65,509d1c33,d5573da4,2d78d25d,5de48a9,556fa9ed,2710fd03,b6d1583c,682cd7bd,8705a9d0,1f73a8b9,8f3a1eb5,d89eaa) +,S(f1943b6c,9ed76a84,9c67bc94,c755fb30,e8facc1,de280060,df4b9e7,8bc02bf,98c7ba08,85dc4e0f,6acbb646,42cb876f,a3156232,df1f84b0,4818ca56,882a40a7) +,S(c5b60b14,2de3ab8f,b0c24276,dcedae7b,83422821,6ac8ef39,1d351832,a5e9e5d3,ce86e4da,1174e609,f55e10d9,14d4a5e,33259578,e07c1260,e912acdf,9eb5cd69) +,S(b06638e,706cfe63,3359647b,253f99e1,c7778200,c168d4f5,92e2c409,493755ab,e6401fab,1b4d5229,136e2493,39f95357,e16dd37b,87e7f69d,3e88a383,cb44bbd5) +,S(cef8c1b5,486dacfd,29650ea5,432fa563,f0ec5fe4,6814bcd8,9f539b7d,264b14cf,80cc2c1,8d0b0be3,939ea,761d7281,5ed4fd2a,b252d66c,9316aac1,1a5a2fcf) +,S(f616904d,f868f2a1,5fcdccac,4198b1c1,62defb40,269754f3,8e546da2,4b85d7ce,fb971012,344024c9,f0bb93e0,b73b31cf,de8b4d37,aaeae3e4,7f62633a,7b8255b3) +,S(97386144,bc7e4a7b,33a51697,902fef4d,1613d8e5,ed80a599,a59f62c3,f98632e3,bd12d584,58429939,2dd834a9,5431af27,8e56065,ba79bb6a,5a806d36,cfc16b4) +,S(946f130c,7a70fa00,f403a56f,6656b279,1eb08ddc,561311b,551ce437,bb0200c8,acd698f6,a5037e60,7f5a923f,3af05784,186d9794,a7bf7105,7a66949,e1945b8d) +,S(ee0cf184,72c453b0,c38c064,fc0d2589,d5f1afc3,3423687d,91740bdc,c3929230,d817775a,7fecd397,e954db12,fca24990,8c773c28,b36e991f,79c78264,9fff8dc8) +,S(f335f7fe,9542a587,9d48b4f,4ab1287f,ef007289,4d93bc21,23463a77,7d535d7b,336e49a3,2465d29,35389c06,d8eafb4d,7639dae9,a6b19bf7,45518502,e3350283) +,S(55bf8179,4fb37f8d,dcc200d7,b76a9040,b1326d6c,559d7f06,f0eb0e0f,c97e7739,ca33cf00,79155cc1,e902ade6,f7d703ed,3053f6a4,f49d0866,32e930a2,afe69bfc) +,S(dffccf81,6143da46,5ee2195f,abb6d943,1033b901,2fe0c623,49b7d6f6,29de29b0,9bfdf3f6,e1dc4ae7,dc29fc06,f85e1588,c04bc39d,5fded90b,bfe75b9c,74f0aff7) +,S(b9748c94,25fc6fa2,fe5c1395,b556bb12,c435bc11,2e8f577f,3c5e7d82,3539dec3,f5238bb2,b995d23b,5e96b233,6d5141ec,f76d31bc,63aa96e3,dfaca8a8,c94007a2) +,S(92c43c54,e951b157,38f29e33,5f52ad9a,2c5349e5,fa6a39a3,fb615878,ae97f7ca,7c7a6b73,dedd1bca,308924fc,6364b62a,bdc4ae79,d68a62bf,71bb0195,612b4a17) +,S(b1937ea,25995e55,ee1ef139,d7a58923,5677afe9,f4726d96,40b66b0,d21eb272,d0f95a57,544ac7cf,e6c3e0ca,5e44494c,5585c503,a8ea9919,5a993180,cf043dd6) +,S(2c1cd64d,bd7ee24b,2bc5a6b7,2009b788,e2a5047a,8d10dfc9,4a46d807,c133f457,fe8a63df,ce7d7a4b,e7c31a1f,5e68826,7a9449fa,9e9ce30c,fd8684b7,660aabe3) +,S(4ff10a78,be6ea8a2,b6830649,b0a403d6,6d544368,6cc854ed,447f53fc,45004834,b3cb30c3,56d50596,2e81cf5b,f4e2db0d,e43384d7,28f5d8bd,b362d287,e58765d8) +,S(33f55b66,6c90665a,b60a7c2a,c714591,f877e8c8,517344d,9da03558,f43d28de,399848ab,6aa95ed5,8ae0ea80,c93931a2,af146754,385edce0,8c2a4f64,2d5163f6) +,S(b9712359,5a7237eb,18b7cc15,ff2d6be,408da66d,5885a636,20887ab,340d3e04,a283a3bd,643ac5a4,1b3f0ab8,fc693146,dd125f88,fa87cead,817788b3,be72363a) +,S(d20f9067,6efa9435,f602c1e9,fff7338f,5a4204a5,4d984dcc,f0ba5fc1,60a1035b,ac3a3c7a,452003f8,7244406c,ea315175,ca1af26f,6645486f,3faae77b,8f404139) +,S(322d6ea3,157c9f0d,444b2d0b,d072e192,81d8b3e0,3ee2ef5,4e294b53,fef41f2d,838147f1,9dc12dde,676a9e67,6a638c42,6e096df6,ea62ba97,ec359b4d,f92936b3) +,S(95925c08,68341b6,b7564ea7,bae00b0d,1d2bfacb,94aae4cf,8f29ed9e,fa0c26d5,c63edb9,13152232,c255557b,2207c2ec,edf14cfc,bdd246d0,2b46f7f8,76b92130) +,S(7592aab5,d43618dd,a13fba71,e3993cd7,517a712d,3da49664,c06ee1bd,3d1f70af,554ee877,af74284d,5ac0aef1,ccfa8ab2,7a9222ae,977a1b45,7d79d386,16eaa410) +,S(ed9d298b,e13eb71f,8631ad31,1b391680,8062574a,6053f503,671d9a59,1209e0eb,97a9abc0,dab8886d,9a07caa3,f40d87d,7b479efc,d500eb6f,e54ba1b8,9d85c3cb) +,S(cdfef636,a5900bc3,bd28daf3,308d469b,78ae69a2,ffc39fcb,9f8e4942,fa355fad,f8338fcc,54c0ef4e,a46a1c25,591607aa,f4f6c7c5,378f2d51,79f80e46,520db6d7) +,S(f638cf22,ca3bd6a,ca7a8fc4,26d9f5db,dbc0943d,6a587584,8ca52e6a,7949db49,56a267dd,8309eab7,90b49003,9d595141,653a7926,9fd1f732,f3691e0a,41675295) +,S(4340fef2,9b1e43f5,3c76cab,163920b3,7a66163a,bc942e1e,6387a2b1,8f14bd1c,2d5a782d,6889d353,c6c908f0,b6f7a9dd,59ff2f15,8bbb9eb6,ad62bc2b,832210a0) +,S(78af8680,5e3db13,cd2c01f,beeb826c,1aa83296,c6ed1a30,bf2822f1,a9b80991,19c7ca36,37a6ce91,2680d95b,6b94f835,ec458cdd,86206a2a,49d41af6,248c3725) +,S(d87e590f,e6a4bef7,54a831c0,13b3d561,72064279,38b96d49,58a2ae11,c9c41ef4,3928a93a,c9b43489,f1fff97f,f8ed4ebf,53b97aa1,b50896b3,e30b40b9,be1d1dc6) +,S(b59d19f3,69c547e9,4155cfd0,a0b9076e,85ea8569,195b8a7f,630a8446,ddc54c32,b8f5588a,ffe7abe0,e2b83d55,28162c5f,2d50827e,c44a4357,f81ff085,da661865) +,S(34f643da,7cd59b00,3aa64cd,81c143ab,662726bd,5eaf543a,6d83d30c,60f3ee78,41574cf2,91a7f573,5a0bd29b,3ee5a36,91906c1e,3fa47b22,d5204446,f4501ee8) +,S(56ef37d0,583e9de4,33f78757,dc31c968,fd007bf5,6b05db4e,cac395d6,233dbbf3,a140e01a,b5c898f9,10ae2807,53ba14ea,ba8cb5df,b9e9629a,92c14b9a,df5c9286) +,S(1e43f34,815b568b,1139ca5c,b3a5dd42,fc54dd76,78454fc8,7e3dd00a,edc957d7,5cc38274,ac96ee20,78a82d9e,64dc2bdc,8e947afa,d043302c,85d724f7,7e334cc8) +,S(ce79e49,35d2db7c,d9a9046d,3d81b7dd,f8b06c82,98f78eab,ad93062f,c339a952,fc2f6eee,1b90626a,5ad8c494,3bc3cf5b,8765c8f5,fdc05dc7,fffa08a1,b84f9686) +,S(b4144804,ca862c26,70cc3365,e1a00cf8,f6766cc3,4b3dce2c,76c40c31,86fe4fd9,e4368a1f,ca9b6e00,a3f752f0,3a00fd4,29cbdaab,5e2a04b8,7175b9ad,51b2219c) +,S(eaa29724,7406f824,8e79cf65,ced49d39,5416341e,c1bc46a7,b71d422,1f4fd39f,68e7f81b,e3b75cc3,de4d9932,85e21842,d0d4b6cf,38a1d46,248dd28b,a97c14a6) +,S(4e2d10ff,1f7288bc,3b8c6caa,3dcbfc72,eb7371c9,f42c6999,e7a2ec50,30f5b6a5,68da3c5c,df2a4fb0,a93515ca,3e417d00,6ba793f5,eb678f82,be88200f,a5a8774) +,S(834f21e1,114dec96,2a8a4b45,c67c2894,7d073b94,457c1adc,e009dda2,230659f1,e9fa61b6,edb5a0a0,2f7acb27,d04a67c3,39263adb,6320ca6e,f78ac7fb,25adc89c) +,S(a84b44ac,a0a64455,a97268d7,cd3d68fd,c43caed9,f9bdc381,ece7139e,30c7d0c7,2f903f3b,74e702bb,d2fbde43,f919af7b,d1267879,3882cd6d,a05af259,bbf6b74) +,S(21219e06,98bcb977,47b1df66,f9e0fa6e,600cbe7c,bb432cbd,d413481f,241d6789,7a4388d3,c8961874,a897d968,8b5d3266,2e6970be,324bb736,aefd1892,70954055) +,S(fa514e1f,93bfccf6,88b4bbdb,e4f49879,7b946549,82a27562,6867b22f,9baeafd4,ccd48215,52572b4a,9e087b51,8c930e09,2c2f6156,c26a730a,478f257d,a4f91b74) +,S(b60afbf1,643099f0,c0533a4a,99bd8c2d,2204d4f5,3f2fdffa,4cafa02c,79451ffb,fed8f90,1a029926,cd4b3bd2,76bda6e9,d321e006,3eef3f43,886eef8b,4b21294b) +,S(f29cf9a3,196ce34a,86efcca6,554694e8,17c2b765,39c6cdef,c74850e8,a7ed76cd,5130863a,f7c333cf,b37f1bf6,2db5bacc,994b2977,9951e8f6,2471129f,88c9c5f7) +,S(9cd9e23a,cb00bfc5,1a3af34b,3e23f1d,d8fe314a,322254ed,563b9275,c5084e4d,ecf0235c,c66ea710,151d6c1a,17b31705,4f31bd4c,f8d2a77d,4d36fc4e,1298e1d5) +,S(56f889b0,2cfa048a,f96d99a6,be56a282,18ed6691,ab2b25bf,f3d3b6f5,f6e5d65c,352b20ea,4a2372af,f674f824,8dc8fca1,bb8ecc29,ea0c8d92,1b7ea07b,241fe4bc) +,S(de32beb7,f8fad8fc,16d69a7d,d3def556,8e2366e5,246bfdea,16c936ab,5dff2a08,d731f11c,93a71c22,46c2bd06,fe265fab,eaa216cc,b0de1acb,a7c004d4,249e145f) +,S(85ec7dc1,dc1729d8,c03dfa58,fefaacdb,7d12dc3a,f984a693,968895e,2a6ba256,523038af,8e9aabcb,f98c73b5,afba31dd,89e4b9f2,ba1a841b,194b0b45,9a4a747c) +,S(f7948995,60528ec1,ed7f5efe,42db8bf6,e223280e,2b26d4ab,e23a5caf,41e2e141,9f7594e2,96ed1f98,86837e9f,da8d6d9e,58871e56,16cdd2fc,dd6fcb7b,80c6ff98) +,S(588d6fd3,b4208825,3d76e8ee,f01a93be,866bd53a,e228c137,62199ce0,f3454f10,a5fc9653,3e41208b,ba3f29ad,e31b7e32,6320b81,ad0ded2c,6d922a4b,b42af573) +,S(186fe08d,bbe5c8a7,56f87d4e,8976777b,b01db294,e834659c,bf423de,1ccc7443,d99ded39,a46f7820,3437a93a,435fd0ca,29f12e26,a6449bdc,a256f99e,9bdfbdc0) +,S(e549cb08,3055abf3,3b7eac38,cee13336,2af22e98,2f576bb,5a06d5de,59bd3d25,cdf37f20,e7b51483,6641c7f7,afc35ae5,5ababde4,34a945fd,4fe0325c,7d332381) +,S(a4e42afb,fd7f5158,5c86108f,cfe84b58,b930df79,f53a86e1,8ac93389,224422b,e9f8e1b,3963102,b58d6177,f915d7ac,541e551c,bbea3e2f,1ea47960,ce1e30) +,S(5f7ed844,42022f42,6b09e9cf,b7750fa4,4755fba9,7199fd4e,d09efdca,d803dadb,91d5ded,d06a8eb0,9c9592fc,c9096f1c,e852d9c3,9bfcdadd,ccbe1bdd,2b76ffad) +,S(3fac4743,32f064e1,b33fa22,3f67bd15,91dcf7f9,afa38f1,868e180e,c2938d66,45744e67,6b203799,3386d10a,b11730bb,eebf270f,9ea65920,6f93da61,e2aabe5c) +,S(5fb983ff,f058d214,2e4d13df,97d8e784,d4b10e0f,6a18c6b1,90e64bdf,fb7a7aa9,33394601,8dc540cd,eb73f73,a9733d74,ec581181,8a6d58e8,3460f1a6,8ddabd6f) +,S(baf35c3,fa939a2,db15eec1,ab083664,9c6e941e,19d3e0e0,43e0f5e6,df41f88a,42583cd3,e53fa1bc,4eebdc3f,e3b8b069,9de41445,54fed966,214108d2,f68e9201) +,S(97641f5a,a51e7ff0,f1d86183,a3fb3d60,4266c4d9,acdb9f9a,c704a05,809a8602,134ffa32,aa9fbdbe,d8d82fc9,1cfa78f,1ab169fd,459da39b,5b0d3287,ad9517dd) +,S(96a3711e,acdaf6dc,5adaa8fb,4be05c37,f59febca,1a876a5e,e23c6b55,2727292e,8fb0cfb9,681ebb7b,5e1fce0e,67ad5d81,34be9123,56100e96,b82ecd3f,a5da4392) +,S(ae64428b,8e540c6d,28d38892,6136320a,9f9f16b0,3e9d5e2a,14faadef,4f154b0a,db202e5e,b9bf73cd,b9ed5193,b0ff59e7,cc68aded,6fe6c2e4,d5b79493,fc118aeb) +,S(2c5932df,65c0c2c1,14b532cf,15b48433,e16424ff,ba87438d,42229075,6cc984fb,161ef8c4,b908a056,d395deec,38b9ff4d,1c643628,2ceb1e47,f59a2c24,c7d29130) +,S(76e21c78,6937ba69,18252d56,3ebfcbfe,2415389d,bc692071,f9c48f55,7aecca3e,de7786fe,9db47d61,e3b61d0d,49309fe9,ca634d28,8d71aa77,a3fa4efd,4533c8e6) +,S(7170dcef,ca8a138d,1d20b346,6afc6a46,99df363,fc964a36,eaa70805,b267900f,196bfd39,476f1455,98f89f7b,f870f8f8,440562e4,623fb203,3b36d5d,d8c0bb8d) +,S(98eddeb0,75bdd245,aa1fb466,ed1e89f7,61a95662,e35836f2,e6907c5b,691b6ccd,af3fb5f6,b59124b8,c9c2ddc2,108a3a2c,bdbcdc99,ab296814,731a841f,570c91be) +,S(bf42f806,59ae606f,a5e36fc5,c58379c1,8dd1c34e,fa98e67,68bf6da8,ba8e8849,d343fb70,6e4adb94,46f49578,26bae8c4,ca74a0d1,21cee98f,26be68f8,7555b8af) +,S(40c1c4a5,891e8dc6,29075c36,56249fc2,c42fd65c,8c338a0,d82df955,4662e1cd,667223d0,e68ef6c3,7195d819,2bcc12b3,f2025327,3a05703a,e5aa10e9,cc689ec3) +,S(162dd310,c8e3fe4,8384cf1b,1a0a2d6f,bfd3ef3c,5492fc92,b921133e,8f883dc1,1f2311d5,c82f02b9,f7197685,cf490e1c,3d0ebf4e,86ea0e21,a653c8e0,db5cff0) +,S(ff0f8146,89eaae3c,f3f302e5,1089ec58,5d63c4fd,5157bb3d,bdfc7e40,cc6331cb,4dc1fdb9,4eb529e3,bae54973,778d1daa,f8814cdf,5a3b0c2d,ac2b5647,551bf2e) +,S(143ae674,b011b557,2f472b22,44c6d9ab,14b3e641,54f4a033,c3ea3917,4607b78e,1528d582,faefba2,6018820c,a03dfd7,ca20298a,e199c99f,db9cb421,3601c35c) +,S(f3adce28,8fffd45f,96fa0efd,32974d98,4115a80e,cd6b86f3,5e17b017,8d9009a3,20202f00,96329bb0,69a0915e,494a586b,805580a4,eabd4ba7,2d20665b,4916a20e) +,S(d2270829,e2730d0e,2c8e6bc6,fa4c2247,4904ad22,f44fb2f8,5ad07558,c4d8cccf,d5a6b4ac,9d5bf669,5989741d,f262e412,27c66c7a,ae067a93,c6302f5e,8879a3bc) +,S(26d17eb6,7d9bf2a8,45c57a94,82bb2f3d,8347538a,65c9f567,56ecadf4,352964a6,954af3d4,7d67c345,bcfc4a52,a49aa70,b8703d1a,fcd21c6b,7f7719c1,e2068fb2) +,S(e4437f8b,e104c899,5cd1618c,e5ee7d10,36a52d99,31346476,bf68f21,e7fac74b,d6c156d5,b8256e6c,1a820dbe,3b56fc8c,f9b015bd,b81c756e,27b70db8,d995cb81) +,S(8932e04e,96db6079,662b63ed,29b5a39d,ac5bb51c,d1ec70,851474ef,a2d3c1d4,5437e77f,e030225d,53f5166,8c3551c9,fc912a0d,a3bd336e,c0587544,77e58541) +,S(fe776976,465b86c0,5b2003c7,36c8141c,933ed0e4,5c6dfd0,c7c82517,16617b26,b279dc5f,d576d506,d302b0af,359ddd50,94364d3e,255102aa,472e6d9c,c52aac39) +,S(6c60a4ff,b2a29224,5c84ecbe,1633817d,f69eb73c,a6b9f72c,b86fc91c,535b45f1,278dee6f,814bcc1c,70301a51,f9c7853,6489af2b,d23d6223,1b55cd29,2a2a0a2c) +,S(3132e58f,625f902a,98d556c5,ec9e8617,a955beb4,6e9c2a81,e121e473,9c9af04d,a5880964,a2443c5e,14db9220,446904c5,cf0a957c,945c5006,9438d869,45a9e461) +,S(b05cee36,361a9bf6,eb9003fd,c8d38587,640e180a,9de822dc,57e5012e,34903f6f,fb473886,29519a28,b745ce16,d625d85d,26fe21a2,30d798c5,305d8e82,545c9a5a) +,S(e202120f,5659e580,7a14e68d,e3aad7cc,23cd2f6c,abd86739,3a05f16,12005e83,49928b05,b66af992,d937cb4d,c05fbaf2,a70e8fac,7c081544,849d55e,fada136) +,S(57a91d89,2e5409e0,b07e68f0,450614cb,9a9bf0cd,8c5b3459,2f198633,c7a796b,47905cce,59018fa8,baa612c3,124b1192,1dbf7706,c5d8d16b,bd5c1e9f,8498e7fc) +,S(e092c40a,3ba465c2,d59e7c5,8265ddde,91c0468d,67428ee1,dd153b64,a5a7e8da,83f4e2b4,bdfc4248,2d4ab1d3,13b097f7,baa51411,134eb042,feb26f71,5bffd39b) +,S(73a3306e,7baa4fc4,a081a9c2,c335d3df,7c1ee84f,f5a46554,f78a6009,1de0ab38,1f68c8f9,2022c326,e37a7043,9552191a,3d93f684,3af0a235,bce893d,eda1f938) +,S(7c7a79f8,6e904961,73552caf,4a1401db,e99883c5,a39e493a,6a6eabbe,5f3a4434,85ceb252,e4883931,96c8ce8a,c0b596cc,a2670981,2c293554,15e17f8e,26e869bb) +,S(6a9df561,ce4ff772,b37054fa,e513657f,19f03086,eda93918,623a1c47,84a37788,bcf0274a,d9b3bf58,331ba398,a6611fed,fe719867,106eadb4,2b25b623,fdb65280) +,S(fe7bb24d,47b3adff,1c545d2d,ad2c6aff,81934cb5,bf2299ee,f3f8c53b,ff91c950,7fe65f86,9d2623c,930c27d6,f0a292cf,a881738b,4af0c5b,efde5c40,8a574e7f) +,S(26d1d2f2,7944b77c,290ba60e,17d05347,82ce2b64,ae815453,1da42907,30407d3d,ec3c5024,3106000b,d0b2372,53581384,51b768d1,d5aa206f,4d1055b4,b4f0f495) +,S(f00e51f9,38f91573,4ac563ff,8ea44de3,fb85cf4d,8f034806,e6c096d,8e73e2b8,7b7bffed,3a39a491,d3ab6a13,6fd88e0a,5854081d,21380c70,3c596771,a22c727b) +,S(73e15472,f42f8750,93abe811,a4d4bca8,8bd179d1,4e3e3b30,9e011e27,37cfc4d8,392ef4ae,58321768,1106426c,9b00b4a9,c53c826b,84bcda34,b5d0609,f85b9231) +,S(ed4667a9,aff30464,c851d86e,479df8e4,d29d2348,edaf8333,a7faf560,a9568092,77367875,6892d42d,469a9ab5,ff577e0,6d9f4fda,679882e4,3dadc7e6,3d49bb0c) +,S(d6ec16ab,10811cbd,dcc346a2,64dbfe0f,51066f2c,79034d74,af5b0ef2,541dde26,981f1cab,7ac7be22,9a91b733,6c0b89bf,4763b01e,4a1b715e,f4857e9e,4ad0527e) +,S(284ef47e,691931ac,8241d92d,2ee5b717,3f762ef2,bd1f48e6,8dca4b53,ab4c593f,ab739ee1,e6a7be47,83e1288,7ffe1b6b,b53a4d2e,3bfad3e1,c7ac5415,1bcf5e82) +,S(530f9e7,5a267d0a,fc3ba53a,c49018ef,44b490bc,835774f6,c6cc3f87,8d505c3,630c481e,44e5e9cb,cf6d7fba,8f7fded4,bee9fa70,4b88a8d3,6e2b3bc3,4e85e3f1) +,S(66a9b4fd,81d0165b,6737a4b3,8025d2da,ef9c4d20,3c49a2bc,1ba4d59c,eaa905f8,2770c44e,6a4dead9,7dd7311c,195d3051,12c86bca,257955f1,21b7b1cd,4e525e8c) +,S(25812e7e,dca47b64,9b18d739,7474de25,39bb7898,96ddb94f,60192135,23a289be,4bba3d83,72aa76e,6ba76f7f,18cb8644,788d3ab8,b58d0e5c,795c6213,6f17e2da) +,S(3c81be70,af162448,170f88b5,8fbf587e,df1a0e8a,3576cfd7,24acba77,dfb29608,ab16e48e,da59f480,7a0b5250,7102e9ba,ed9dc9fa,e0de8700,27bd5ff4,2aee13d4) +,S(ab626dcd,a5142933,ece82c8d,125aada8,39626e90,85c57525,2fb24f76,e0d6e39d,8add774b,34fa4b1b,d571f2a3,4d8ebfc2,bb7be73d,dab73cf,e7eedc01,764abff6) +,S(47f25106,120720ff,8cad6532,1a3e2873,aaaaed57,98e3933d,e1ccfe0b,f36bd85d,f6d472e,729512e4,ecb74ea3,f96583ac,cb44e013,ecd0bc60,c38b16f9,20585b60) +,S(6fd30299,f7398f1b,3c538d59,71b8bb0,e1640926,752d0842,36148b9f,23c26b1b,3b8d6166,a79ce235,1a2e9c4d,c5c89ff5,7810bef0,277f3d33,372e05bb,ba6799da) +,S(dd5b07c,784e1cd6,58c51ab7,45c4a09d,49db1287,dd7871e3,f449bd66,4a02e040,b26dad8a,62a491b8,dcced2a7,c0feed9b,6a04597c,d8a0f857,a4731078,d68d8659) +,S(3cf5836,104b4227,aa275e5f,16b84bca,15b61a8a,700b56b7,dff2adf2,167fcdad,1cc6f65a,2cb579fd,f6812340,88018dc9,445af726,2db43b5c,e9e49e4a,ce00c9fb) +,S(683b5455,8b9421c,c3aea163,d74c043d,d4cd804d,23857f41,3e01d28d,4919bb58,1bbe4576,2cd5c056,8add6943,8111cfed,691e2369,55022da,17cfddbe,79a11f0a) +,S(d78661b7,897a40dc,5f42f7ec,4202ae53,e83ff0e0,d73ce7d2,19503279,e43b724c,465299b0,e3f478ec,fc3db82a,61d5f290,aeead2fe,d0ec4a02,6652b29d,cad20b21) +,S(1258c664,fc15e794,e64dbb87,b4eebf1b,32e89e7d,50ec114a,1afa5506,19e15a21,327c4a92,81a73880,70d1a7de,c2a0e5c7,28c5997,bbc21571,94b0521a,141be0b1) +,S(f2d04fb5,1cffe2bd,c6e43cdf,ae7314c5,387f4dd2,4bf7fbb1,a6ccd627,86e8be00,89af3f8d,435f2152,8d32ee47,a86a2ae1,78d3a7da,c27ceb37,93250a8c,27061c9e) +,S(b67bbec1,4ab23ad8,e52cc402,def0083b,d21551a1,92a9df6b,b335481e,3f0dfb08,d6ca6bd1,93838993,5284528,56587554,3757cc13,fee01fe6,698b30f8,10a64a23) +,S(1baef1b9,fa401fd6,a053ce90,f2d661b8,8a466584,83a8489d,90d48312,2b79235e,28a19a14,a2f7817d,922b3872,cba558ad,bc1a69c6,c0b65ee8,3352494,a31699d7) +,S(6c0f066b,23623a48,b2b6a746,801baa85,f58de56c,e5287c79,c3c10ff1,b851aa8e,ec837256,84cb0f8,e528bd94,e1c86327,2347a479,2059f357,4ccdbb93,15ff0868) +,S(fbd5bb09,65bb9d22,bea6d6cb,7aebcf28,a0c815d6,18b79c0d,94913dd9,f63619d7,3303574d,5e605e5b,fe298f77,e20f3f6c,60ccc063,37a29c7e,6612dfca,3f00b924) +,S(2246042a,c4b22334,af6c81ac,8106bd1a,f8bd5f2,8dad88fe,7e568fa0,b35b1739,1da0d8eb,9c10116f,ce29bd9,61f92e36,9e538282,345a4f79,7cdabc70,5aff6e7c) +,S(470a914f,2fff2d37,835b3caf,542cf50b,9606cf6d,fd294c51,5632d9f3,4182bc4a,6b3805a8,d2c74856,a5be3cc9,e9c6a8eb,4398c606,81ce12db,b3a58660,1d426e) +,S(4e03f50b,ffb6d933,4282153b,a3f909d0,44bb7a11,50300c1e,cc8027b0,321b4be0,596c58ae,963e71ec,f1fe8f9c,b4de8cbc,9149b125,31e83e0,95f6e5a,b08c504c) +,S(5a6c4fea,b806bb76,191567e9,139dde28,188a26b4,a1803b7,d999278,fc57455e,6e81d07c,6505366b,c28ea476,a718e5f7,353d73c4,2f551459,d59a7d7,82e6ce49) +,S(ed73c9b2,9adf52e2,1280bb1b,ef63dd4d,74f4e09d,1be56c3,a246dc37,9b29bd5f,e9917b6,19ebe0ac,c7d1fa5b,7c4b7c52,e272ad9f,2df62161,59dc87b3,f913828b) +,S(68c6145b,38cbf9ed,4af10608,503ca13f,710dd34c,2386fa99,bdf93b69,c01c04bd,c963585e,607d9eac,5016f884,df535a9e,e7cb74d2,2e0c1e9d,e928d7ca,3fedc73a) +,S(1b651863,927317bc,1dc6094c,3f5c91cc,92269a12,59879b6,a8439a77,b0454126,31c6125f,8ac3d09b,d8c1fe92,c31bf13,c42b1915,e7147cf9,1371dc01,e8f5009f) +,S(45593ccc,dadbde3d,456b74f7,a3b705de,7229ff20,90a0df0d,38166d4e,6a09c52c,13d6657d,89fd0205,3c2b9a31,1ee964cd,e14634dd,20d85866,a43a4ea9,bc0bd737) +,S(1409c06e,d6f2fa2f,cd532983,d28c2109,e4dd7c1a,4ce77960,566d3eb4,37927da5,dc05f98d,4206fdba,e3b69836,e694b71e,fbeda304,537bc623,90edcad1,460984e4) +,S(d9e08c6b,c307b056,d4323921,5426febe,5d6e5cc8,4eb73707,4e2f00dc,e85f4580,a23c1647,c6b47a43,a3ab52ad,da32605d,172f4de4,201834f9,15d5a4b6,292c632d) +,S(7df319f3,d3c2b6b7,3533a916,64d5fa26,5ac0f18b,bbd5e8ee,1aa15dba,bd62fb32,9120f6af,e023bb98,1d6d8d96,31de0814,a9bd169b,a91af0b7,9c3db58d,2bc9f8c0) +,S(1a94e587,38b9fd1f,93146232,e2165798,11d74244,9bad3711,a373445,6986d7a5,332a27b3,17eee7ae,fb4604b,197f2db2,fc32549,ad86765a,74820428,abe4352e) +,S(dfa2cb4d,6db266db,2a82ef8d,fc0cf871,4aefff41,895ff691,fa0781f9,1b619a47,c5e5dbab,3a28a6c1,8cf20fef,4cba62f9,d2a1a0f7,6ea7056e,45acfe4c,49ad8b19) +,S(c2201007,be6bf76b,5e82c135,2a6e053b,acf4e2eb,c10a417b,f35e4c79,3a876730,92408aec,b9ae4d74,3af97c15,9c387343,9a735de8,90d1abe7,c8d14dd,fbefa581) +,S(d45632d2,ab087f0f,9d0d4d85,26730742,2f25c794,efa3815e,33e8285a,1bd7edc3,b7ce3697,c4994fa8,2479e99f,9c9e4b1d,814e7258,da7ba569,5543d6ef,8d5ff44f) +,S(8cef362b,cdc292b4,885f34ca,923a171a,df6c25b8,f6b7cded,c9003b71,cf5df93f,b3910f34,ed8b7fa2,bfa4f1c1,9d41d99a,d702e13b,5dab6bdf,2608186d,d09aaf5e) +,S(247f7be1,874c2831,17d60431,8184878d,3a415ae5,59595bfc,7f17583b,3cbf9838,90e235e6,a779b4fc,f9521da,65f65091,efd513e8,df338464,2f8a7cc8,f1f30eb8) +,S(b8c0cef1,c8703adf,411dd0b0,acaa2b82,f2609348,e36aac56,b0148ad8,981cf568,a0419411,47019aa1,4b8e74a8,1d49a97b,45e7aaa4,54c0f916,a33472ae,1275f14) +,S(8e55776e,6e1c791,2aa6b43a,4dd1bd17,a35ab0d,aad792c0,ab51bd86,8208cf09,dfe4ccc3,a025abbf,c2d12bc,6d462e6a,cec7307f,6daa9c01,2c8a7ad8,70822d56) +,S(f1cf6d3,fc9d9824,4e122790,de390241,db813b70,c48b667c,5f05846a,c3ad1ad,4925c6ab,3952d1b2,35ef1ec7,7ae7a84d,75006993,b173a6f6,c8b969af,c3984799) +,S(b49dbf88,dce5ee49,2b4495ab,9db762c3,81164147,cacbc00a,9e56670a,edb9ea31,c0f92f17,ab5797c7,758d703e,fd288a46,8971f7c2,de8923fe,b8b7acfa,ffa9ef2a) +,S(d6afe2ad,257b57ed,15573c50,a25f7dcc,399e2643,9e64acab,9a8c9f75,d8ca362,5df236b8,6919b56b,17140249,16282b11,38d355a3,561c5b42,b47ac6f3,8d35749d) +,S(bb0284c5,f23365fa,5972a439,fcee4b4b,45b48a9e,6844a44b,53e12004,1ae8e89f,684bcc0d,e09e5932,79018fb2,aed55329,53221dca,6f14f493,6ae76099,ba265300) +,S(57e95714,8a409697,1b8be621,98a04177,c4779627,ab5a77e4,6e82d847,e64467ec,714bd1b1,14ce2580,7c6d3a8,f12a5375,fd8e7cd2,5e854c12,6bb519f2,cd443f13) +,S(b0c82f60,b33c3b47,523ef2a3,de804521,a1e14478,eb637757,d17526d9,1e713094,cfc8d1b9,d763f52e,6522f70a,c93f7fd9,23d163d6,5a82b2ee,ac1af994,a2cea63c) +,S(2ba76170,404785bd,5932c185,c6d98ed0,667d8324,ff7f85a3,5c24a4bd,553e1ee3,1810790,74262af5,607167d6,b55164d1,e56aef19,f3e2f307,205d5603,eeea35b9) +,S(5bd54e13,d508b920,fb1d15c8,27e0ca59,3eb1c85,a7228895,b5c9235c,6ed3e88c,d65d35fd,5607e193,ea70ab1e,4ac7d822,878017ac,ef3bd6fc,2b1933af,660cf0c9) +,S(b0bbc2d2,753bd89a,b2bf1664,e6cf212c,a590d65f,5664e694,7ccdf977,3ea8d09a,9057b6c1,a1078bab,a1419065,4cc67052,7225741,1f34d47e,47f09bdc,8f993c23) +,S(c1701203,3cca38ac,ddc0fe41,95452129,b38b4630,20e8c459,224e9dc6,cd3133a8,c495d87b,1cfb6f67,46c07188,86c08616,624f78b5,ebf4fb14,fb6b636a,f5557e9a) +,S(1e0bd20e,5f1e49ff,32287961,7fbc28c4,7c9fa4dd,d93532ea,74930a24,5fa21bda,2d407400,e98f15d,e5da681b,2472fa11,b2a5869c,66be1cd5,7038e160,43dd6177) +,S(5cfc223f,ec4c6618,ff12a974,8533a70,f39defa3,bc05f88b,3a1b158,317ec15f,7d928bd4,89e3719e,6386ec22,6c738b09,eb4468f7,b6718cf9,3da33544,aff21411) +,S(f506560a,bebd668e,57e514e,bad47a84,5da345ce,50ac0e88,1cccc2c,81efa67d,e2ff0bf7,c9c2a99a,bc3580ad,17f64a26,63111fd8,15bdcd63,9d9a7d3a,ca0fc7e9) +,S(8448fe98,ec887485,45a46e4c,449d0168,1d00dcae,5bf96ef8,306e7bd8,26c54f45,d0f07229,17500322,2dda8271,33481376,85b20045,f69d656a,66aeedab,ea6f0407) +,S(c9a6857f,db037c2e,36d5ca71,32942f34,2480cf28,a98644f5,6bc455ba,97cffc55,a69e08b9,8f678e61,6c0b8326,ced6f97d,f742d974,b68cd1c6,b798e367,8faa149f) +,S(b5d13f5,c611eb3b,c82f7db2,d89ab19f,b8fc286d,8e4699d5,3dc664d,bac4011d,27eb1650,7cdc0fdf,5b92493f,f2487d0a,ef2692d8,9c702bb6,259808b1,324b7adc) +,S(bf9ec5f3,2e0ed4ac,c001b887,18c29c6e,90218471,d7f1afad,75abb34e,da35ce44,13846488,892b4065,b79224ed,368c47a4,a1734f68,7386546b,dd837a80,467ef2d1) +,S(2c3812be,4d3b1c13,aed1f6bd,1ca6f5b8,893c5a87,ad6a8f2e,d6d92ac1,3a526e19,366b82f1,45d551e0,b7bcf877,db340bcb,1b11edad,1466baf3,24a94cef,3433aece) +,S(77bdef28,dc8ef6c8,7fcd0a13,c08a26e5,9fd17253,8d8bd3a6,f21c5c86,ca33f572,da66b0c7,bf3bd49b,ec1fec,aa580a51,6977ba8a,83f957ef,8167f69,ea3c3a1b) +,S(bc4a799d,3185877b,cd86503e,3f34c606,8693bac0,654eeb15,4effd116,8b71afe5,53fcd7f8,99a8190e,a7159c99,e261525b,f59abf6b,d331be66,4f7f7757,7255569e) +,S(301fd884,733dce05,6190e4c7,d0375078,6fccdb6f,2e13f9dc,e275c188,2efcd040,79e4f9d5,185b9f51,fd835cef,64be607c,312c910c,e25cb73,5de2c88a,51e25cb6) +,S(241b4a9b,be5e7e54,214d0bda,13719c42,133f8377,e50db2f3,87b6018a,814adb70,c66edc08,fa4fd22e,1f76bca2,7fcc00cb,a8ce2100,248b3959,3c164847,b410bdb0) +,S(be6f1639,68191289,3c5c1351,d633d51d,dcd28c16,f3294981,56ea1602,d8c79585,6f674a7e,1a65539e,a7f8a966,8f5fe5e6,1ade5da0,a543335a,5f7a71e5,fbafff21) +,S(c8b5008f,79c69e2a,7e209ef6,a2d14b9,b3f7bfba,b7fcb285,e237cb31,3dd3a283,1dc79348,6c3cf7e0,bc36dd7,46efcb36,3cea15ca,a63008f5,2d83ec0a,6bb54bb9) +,S(5014af9e,aad5ed62,4e997ec3,a796ad1e,b038edac,77cf27d4,eeda7ff4,c06c0998,e01d786f,b8faa1c5,2d44a77a,987b4b6d,91143953,34977151,1a488602,3189dd7d) +,S(6ffefde6,2c40643e,da2d4f28,4f28fcdd,b0845ec0,8d882d2b,45dadd8c,a7bb989a,8e2b183c,782d3a9e,2229e4bd,9a2becbd,ff0a5480,6a6f4471,7fb6fe5c,8411cc0e) +,S(ac762bbf,190e1374,d32a7e5d,b4c0c36,ad0140f,c1e92290,4aaff1f1,487d463f,ccd79f18,31016b40,a381bfec,5db6b12f,bc34d850,ed81aa7e,435a513e,5f3adefe) +,S(973496d6,3ec05c75,93244e7,b737b1db,d791a5cd,e828f342,7968eae0,e811cb24,4b2c9bc0,44e3351,f637ff52,5c3f34f3,d7420b65,2f57bb7a,bf573e67,25647533) +,S(a9d89166,5f77bc30,74357753,9ea39e36,c39ce300,6fa03429,1a799b34,84a15d32,d09c3a17,fdedb8fc,f4f9ce98,20635a50,56dd884f,ccfaa96b,8d0813b8,4b80e213) +,S(108a8ffd,aa2b544d,8b8a7419,f2421bae,cbab636f,60d6ef76,9eca9a20,a0c5710b,ad3e9fc,ab04ad58,a265776a,75f0e389,cebbb273,9df328d7,b125665c,d4e0249d) +,S(ef969d7b,c8843c57,bfc0ac6d,f5e4495f,9543878d,95120a36,de8c5bed,727c5fb5,5ab81bb2,26738036,b145d81a,1deaada5,d1d4d653,7b80b02a,fc1cf85c,361f16fb) +,S(ab825bc2,4d505453,f12dafb2,8f70b245,d74200f2,410f5162,b0ba3096,43c39b62,789e7df2,23774415,da7e31da,277a81c9,708098b8,d455594c,6f9cb065,b1281a1d) +,S(4984a4e5,2c173c02,ec79198c,f8496972,eeed4e39,9933bac0,59856bb0,48bf2622,4596b67b,79be2e61,a0887a9c,2cc3ccf6,f199e924,3991f434,8e7cf897,acc5df3f) +,S(285c6ff4,93c1be13,f4f60d0d,8aa7cb24,4bf0f76a,23f3efbc,cfa4a132,625f7272,39dfe9a5,cf9cef28,d5cfd998,49db9b23,c4caace5,e8a27c12,12d7b3d9,d3ed49d3) +,S(1e14b1d1,7e721971,e9266717,13100aa9,9bc6e506,c278ac7b,348b708f,843db340,63a239d,d705f627,347fe464,c4d4143c,394d7dfc,5f79ea11,64d05f04,4ce41cee) +,S(b8f73b9,ed71cd1e,f61dcf30,9cd48587,3b1394c0,4cf318fc,10140bb5,be17c8aa,8af5dae0,bd66ec85,2ff4823a,a1be65ed,745676a,5ac42ec5,827107e6,776f665c) +,S(7e0c7297,e878fcf6,cb636776,d15afd0,49c995d3,1cd49d15,e624bf6e,8714540a,df5795f7,4c512043,f48b7568,bb271a00,ffd59530,a0280e5,8aaaf0fd,aeddd658) +,S(9f0ed1d,465bed9f,a2b51133,fcddfe48,10999011,b754acba,de5fd027,6b798545,7005ec9c,73bb0e00,64badde0,12aa99d9,d85b6c38,e63256e9,21799990,14a8459f) +,S(2d556f5e,b5c5af0,160608d,80e23cef,cc8e4000,b1e35b12,5a0a51aa,9c8e12bf,7600144,25bc3baf,1dc7f6fc,1fd86f41,d24d4488,f80ab8a9,4e4422ca,15f12000) +,S(2617667d,7637e02c,b479524,d9c7dcc1,2cc14ce5,4149928e,e8d81bcc,835ed3f2,521573ba,2cd809eb,8f5496be,478ca639,7a2c4e16,1b299ba,bc6ae419,4780884b) +,S(6247916c,5b519a64,7b76e10f,8810a3f3,4cae40cf,ed05a492,ba1b061f,d9aac10,ffd02570,535ba978,906a193c,500da1d4,602b0969,c3e9f4ca,f2d33026,eee7f098) +,S(c40b27e0,8ed50a88,60017e78,ececfb9,ea14c64a,95137db4,fa55d4cf,9a3c52af,2415cb8c,7d025b84,fd9d1e97,7105aa54,c4149fb8,30ea801b,a86f1acd,e07b6493) +,S(ba5aec8a,54a3a56f,cd1bf17b,ceba9c4f,ad7103ab,f0666974,8b66578d,3e0de12,348dab11,abecc4bf,3c7474d2,8ea5ba60,a705de60,39f9b70d,c49d58b0,6d57ffbd) +,S(ba14e658,f8dd294e,1331262c,ffb3f31a,c1e9e504,e55c7f67,5c002248,94076268,ced74905,fc43e55e,c70cb36c,66dd9a10,c221b0e3,a326e365,9b96de4a,c81aa1dd) +,S(3375af69,8880c7fa,29e718cb,4139ab30,f9c1d00e,a1c22d4,cfbdfa16,a7f4aff4,cfa8b491,a83be5b1,b66fa0b8,5e26c68e,8d27db79,ce55d726,ddde67ee,ce295a27) +,S(68d2614b,306cfdfa,e9fa109a,2c4b276f,5b9a8ee2,f7d502d5,efc94aa4,bd9f01fe,148c36bc,f04365ed,7ddf54e8,4d40fb59,ef9e1d48,8408c8f3,661386c8,5f48550e) +,S(93facea5,597703b0,ad2990d7,1d63387b,900ece6b,6c3677b,7fc47b7f,1c533edd,3c801bfa,8fa114e8,b5c19985,39a1f6c1,c20bbe44,d8ee7179,7454797c,942ad5f4) +,S(f11dd4a6,72f73118,95775ae1,76c90b2a,5a0a61f1,6ca205d6,eef6c275,75054277,bc06a16d,2ef2ac0f,7ea2083c,ac18d0d0,6c307d45,51e0a0e8,3f59b568,b9556ef6) +,S(42ebcc5d,710ba454,fd29a94e,f83c8004,b71fe85,9725c010,f10ca39c,864204f7,f8aa84eb,643101ed,4c7d5cdb,271d067c,e633c17c,dc698e40,279064d2,d65f223b) +,S(d40877dc,d96d5a94,87b6fbc,e89d19a0,549e96da,13f1fb2e,67e9e3e1,85c80e52,be9bb9b3,85f20fcb,8e57b59a,ffc01442,c0be8306,f5d9087c,837e234c,5e789444) +,S(c18b2c98,cd2110ab,888ec934,239240a7,aa40c1bb,ab8d7e39,8fa74358,2562931f,d9621034,9147d74c,75df18cd,1066c40b,b83f189c,937c01cb,24c2ce97,155773f8) +,S(154d6b22,1a44f841,1cf4fa0c,4bb4debf,6fe94658,c648f9e4,d14f88e3,e05c0bd1,df0bc307,c705332f,328bbb6a,dd94e63f,7c1074f3,ebc55976,de552a59,5875559a) +,S(a38259e5,629f93b1,a397d228,59842dbc,24485d59,c3ab86e0,a9326a35,e1a26f15,69b5accc,2fe52a63,b3874932,e8a79b8c,1713274f,f435d892,367bb9ea,91f783fb) +,S(9d729eee,e91e3493,9925a7d5,2eeded18,14827029,6f822013,d4db2a3c,763fcd19,6d832154,3cc8621,166f731f,2d874fb0,9cadc09e,4e330339,657aa2f0,e3e89a1f) +,S(2674f008,86307c7e,576cede7,944a9f9b,46398c93,8a0f8b39,b25701b3,67751e3a,3e9eb42,6ac9d1ef,837638d0,7b0f1f4e,e31bdec7,a9d22fa2,12a666b8,193f83cf) +,S(b2a06d5e,adb1b856,dd28e9fd,bb626c0f,b7c1642c,6f70c2c2,743f3451,4e237f41,5d4caf8b,8673b268,227baed4,481ad60b,de579a98,4d005f5f,f3bcead6,3bf664d3) +,S(20b27d64,d61debdc,ec3e4ec9,2040f05d,2b278c0f,1415ba60,f0bf23e1,222d713d,481d85e7,ff5c2df3,5cd26488,6056750e,c8c5c809,bb3afffb,41e447b7,a4e516a3) +,S(4f4a610c,450eaa25,f60d7c15,20c551f7,5270930f,45a7c51b,fc7cd5c5,3ce3f2e5,df1e8e11,db416228,672d8d8e,f9d68ed,e824234e,fd7de39c,2b32fd90,3a47f328) +,S(9b375ed8,504358,25570b4b,e359bc07,bc06c989,14659e9e,776fba36,a8aceaa9,3d056593,385c0069,915de5b1,f59c3483,22683440,86dcdf26,d1e6ae22,35e90927) +,S(43640804,5d432c87,31f865e7,2390b7ff,c13aff87,37fcfba4,60c0192,2ec9d1be,e2338eaf,6fc73fe1,e3df2aac,54bb4fbe,5aff2a92,5b8b16eb,2346b220,6070cbeb) +,S(a6e59c4f,24461172,4161f35c,fbe88d4e,59287f2e,f2b9ea39,4c476127,f41e0b66,75c70747,f5dd75f9,41cfa470,c4cf718a,57a8ae2b,2e7ab277,5f5ec5fe,7d9f334d) +,S(ff639617,ae7351fd,977bf1e8,46a6d33a,5293a959,74b296ed,7c9a007b,25322d51,e6123dab,fa2355f7,653f81ff,ee798353,e21dca71,ef40639f,79d73116,53dac457) +,S(77914840,1710d8e6,8a37cbc,5ad5e284,c254dfee,1c8b043,5f8ddbe9,4ef4faf3,d97f44e9,9ef3d4c7,4075dc3,894d2a6a,623be446,32c98eca,a54b8ed8,e0611414) +,S(f68910aa,29254aa,10551c00,adc135c4,947cf1fc,6dd8ee5,d42579fb,79484aad,40bdfbdb,33a56d63,ad587ea,fc9784de,69f9f5c4,3f5c7c94,1b9b59e4,c052c1fc) +,S(15be8f81,473d4cef,719c7501,1d560d84,f2d4d8d2,def1d696,29f62464,1b6e0fd3,7e66f926,fc991b41,c451ead0,6d93267,64b85ea8,849047bb,1d28eeee,70fd9a2a) +,S(e113d5a,2e22302e,f4327297,7c41c8b,d0c5c26f,9a0bd9db,9091abdd,8a84e9ca,2e4862d8,34c6dc45,17a6b70b,2f1b2c5b,b54941d1,cb803530,26a257ca,f5574dc0) +,S(96b10770,485bba67,7f620d9d,ec0d1be2,2c94dab0,57d6d595,aa78dfe7,47bea688,e060aaae,222726a,c1a1bd58,fc779d9a,ff854ac2,4a4996a5,2259e9f1,bbdbf30b) +,S(81742f00,5555954e,17e5e899,d2cfd8c,57f6f7c7,5a38e183,de878934,2405545d,a1763fc2,e5f705f2,e6f2fbb0,73578fb0,a8d742c6,8f92236e,df1ee03d,2ed2fc0e) +,S(17c19f13,96988f62,77cb72ea,f90d37bb,86bc7a0b,e16c1c17,fcc481ff,bb78a480,cb1290d5,210164eb,621c2642,ae3e51b9,3f430e60,718f9fd9,c5ec3bb6,53c78833) +,S(7b0f06,e8746ec9,c6648b2b,bb861548,bfeee507,63c01c3f,40319beb,a2497a3c,c6949378,84297d8e,308b318f,1caa0c7b,1634b758,9d6e8c6a,2fdb778e,d6a70020) +,S(715c2b06,2414183f,9a67d8c2,8a89b754,55a80517,cb1b8134,5f56e91,12c5e8b3,f89b89c8,9a795dc7,1e2d4cca,7f84b4d5,23167f03,97787b33,9205773f,2520370b) +,S(e0d0ce00,f974fc78,76777662,efe5dbf5,57aed09,dd89a4c7,8f1f40dc,8f74d3b6,acc5be65,ed704847,94bc7f05,c4c5511f,c253befe,7cb3c0d3,e85704e2,e3e3eb56) +,S(37553289,76fbb8b7,9a5aaf75,ecd9d2a1,bdba9a87,5bad6222,e770ab1f,d26432a2,6dbbe233,1b7e064b,d80bc7d0,12b2a088,1087e7c,2c5c1d77,eb016108,c2ced92d) +,S(2e95c3ef,51ea9036,8683f6b0,8b2afb04,f46ca651,2abdc699,446ab3a0,6fe3d3ff,905ea87,b1d8dfe0,48463b94,c61dbc62,1556c66,b2b498,39cb40c3,299b554a) +,S(25310e1e,721f3245,7f35c67f,b73553f6,6467580d,b5916cf4,fe7d75a,c4ff8eb5,9c5e52f9,be42eeb5,425a359b,87dcab1d,46ecd662,c17eb041,16b5430,786b4ace) +,S(25932b1b,2b24fc2d,d7877911,7d7cb506,27a23b7d,7faf53b0,cf707f51,b7830b7b,7e8e23b4,acdb26b0,1d7969a6,ddf3a2ae,2215e206,109cf3e,4e32d91,df536765) +,S(7d232af6,251f7667,ba69ba44,397f5b8a,892e135e,b09b684e,22b16a44,73c5ed3e,a3e8f638,c8a589b5,8cfdea61,d9824f1c,131b9045,9509b92c,1cd26571,a6d8356e) +,S(4d56caa0,1b65ea87,ba3e05b0,a4495606,6afc8645,4847633,cb9e9755,c8c720f9,14c34678,36e65197,ca3f1ada,936f0348,7c1eaee1,977ae08f,50f41771,77537330) +,S(71abd165,ca6ff8bb,775c81f4,2c722ed7,2615b503,3727dc2c,122efbd9,c500a88b,79ba2467,7284f86,2fb1c46a,e11ac4b9,a5969352,64224eb9,c39ab884,492620f1) +,S(8462fccc,c3810519,cc449634,5c5d9e56,30215e74,c41179f4,2002e906,56a48965,535a966,cd7fb998,bc548a7e,29fc4640,f0eb75a7,5c3c05cb,64d09048,a7787d4b) +,S(f68eac93,fed751d0,b578b5c,665684a8,b9c2b104,6fe45ae3,286e9351,36c09826,98e0c32b,98b0a8a2,8f119ff2,fa50e54b,66f7d8d5,732a1831,7334fc45,fd48bff5) +,S(61447250,9a8d935,9c0e4014,f6ff569a,43467dc7,e4940b16,15f442b2,d9f72041,fb7177f,c7f57ee7,deea7108,dfbea888,fa58f209,2aeb2d2e,b2f33141,7ac8f807) +,S(ea69ee11,4ffa1bd2,e2259a26,e2d88cf1,c9846ac9,379a1497,fc28ecc5,4b15614f,589b81b5,1dd6d750,91014108,3dd6cf3d,63183d1b,809b62c9,b17b768c,5ce4e2de) +,S(34727b24,3404de96,641a1ce0,d7ff150b,38e6aa15,c51fab78,1464c660,4e5d5263,9198326b,cf56ca77,35b9baad,dc0069d3,1920bff2,d5bbf804,435289d4,d827d4f2) +,S(952452ae,613778dc,29e2d275,6e98b4f0,eeebf4d9,526cead9,52f8d0d9,9e217461,c08b3a28,c195fb5a,f9a50eb1,1b1411b,c17f6582,dc14b5ff,797175b,2ad486a8) +,S(fbca3f18,dc4a8bc7,7e9afeba,66610306,401b8342,bde2dbfd,2d4a156a,e78e49ff,2b829d6d,6027b2de,eda0db7b,c76b924f,4cf75573,bb9329b6,c7b7e443,f94129c9) +,S(c7ddf11d,7ddc643a,957dff64,a08a4a70,5302bfff,b940882b,57bc4c15,5bd8c141,e9ca11f1,ac93b018,3fe8146,839be79b,b3711ee1,8a3daa88,89d55669,6e708e20) +,S(71043a30,86e3063e,b831f7e4,4e682181,1b3f2353,9cb6efa2,cd0ee4a6,70ce31b8,4db3f338,ef9fd273,4aa9cc92,55e2984d,9334c164,5320b411,ebcb7cb4,89322c9d) +,S(6de4ea40,15347cbb,d9349d36,80fa375c,5d70f044,799134c3,dbb6a776,48602585,3b76588,65ab52db,eea8d839,47025cf2,458a3243,38c73d70,f1d77df2,7f960418) +,S(29faa79f,467cecb7,ea17e23b,6f7ba03d,db9a0cc0,e1fa6215,bc425696,ba4fecbe,e5aa691f,c42fbc29,c1f027d0,46bdf106,64a2245e,d2ff1154,e50ffa1b,48f34838) +,S(ff880bfc,25ae5b22,78e5f15a,2bf8f5b,d750f8b8,74910f79,c8c42f93,16aafc99,9535f70a,728f79,37825bd8,1bb502db,60e7a166,bc8a0b10,5eeeee82,3a5747df) +,S(b781b6a0,3837f6f5,8520c566,352e8c09,60eff0b2,42524eee,f6a6bd2f,a4a2a378,acd7b7d4,6c683dd9,43722ee7,3c12b69d,cbf8389e,62755e4f,c44fffbf,4cdbbb62) +,S(6d976593,e8bac5d0,da732c64,82e4ac2b,b3f19062,59045990,ee540a3b,467406db,30c353e4,af6d8161,6c0bb9c0,f2a4aaed,6cbc1825,9a8b9658,3bd7e9c1,2f2a8b6b) +,S(18ed676a,4dd3e0db,46212112,9fad1e13,683ec782,2a6d9401,5d0866bd,6cdc3032,c86b06e1,5dbfa82a,5f7b9762,65e03670,6f9a6e7,7ee319bb,8ef26b16,a51bd5) +,S(3138e38,e9440ffc,c2cbce4d,aefd4b8d,d1e859d3,b951d18c,eb3540ca,db5ce2a1,df8ab1b2,a11a8667,dd660a13,490c6e6f,fef4bc40,94efa9a3,430e28c9,6895c241) +,S(757df4ac,2025c9aa,b8ab1e76,149a9762,163ce608,f4903c3a,91571cf,e8b00c95,ff0af5fe,ab36c5d8,47d15ab7,65000765,c56bd7cb,4d0fd8c4,a37d4ecc,dfa03430) +,S(8a697a52,7156589b,d13319a0,81e3b2f2,ce09de8,450b95cc,9aa70409,884c27e1,9eeb93c,b6029e9e,37f2815a,d332d5d9,5a5edde6,bbf03ca1,3df09f86,ad51f39d) +,S(b0bb6987,36f9e0b1,6cfc2198,e37a84d5,d35eb89b,d4f4c0b1,650d60e3,e58c721b,33d5b200,ce25b501,6f09808f,b38e82d,b855615,2f48c1eb,b3b6363b,ed6e00dc) +,S(1ca0edde,5dde4634,2637882a,d2f8ff7,ef6d6f5e,906ae2d8,d9f1b545,c837efed,19efb5ae,4cff683d,a7d5d4c0,f5eb9f3e,4c4d3a4f,ac58ee41,acb9ebda,a82863bc) +,S(780e5b0e,b9a4e57d,66a84931,1e1b765,d59ad11a,de4e921e,d90fc422,4d474aa7,5ebd9ccc,58cc5f21,2da579f4,c79aa3a4,1d8f34ff,418516a3,d339320c,133ab811) +,S(f7e92ce9,39808505,2d2af620,cdf210a7,30ec079a,54bf1468,edf686da,34eb4c9d,2c559dcf,e113a961,58fd54c0,32f14ada,57c23496,7a88b585,7b1f7ab9,78f93666) +,S(3c3afa20,75bb20a7,8f9ff809,20d80d61,3a5688a4,269336f5,4bc7da5c,4a89f938,7ef38308,1dd235d6,e563a9f5,46435f22,3bd836d9,3f1d132b,978f3f9c,7b888c8d) +,S(71d6f01d,ee60f9b5,75dec59e,7e56123,89fb9edc,3019115,af4fb155,f22097ee,e1ccc245,4a31a35c,52854091,fb414321,38da4fd2,eaf1680,2ef0470e,1c80bfee) +,S(9726660f,5705ec80,908a77b2,8e6257de,b107fc31,c58ab6ea,1f5f75b9,38c4fa2d,94cc07ae,3102d1e9,6118c213,b6db0c65,d3636fe7,8ea40c6,90c86949,b48cd4c1) +,S(ace5d0c7,54b2a1af,691a1a2,97e8b632,297fad12,ec1fc4b8,7fd02ac2,b2802719,924f9f24,8d3e725c,eba491f0,5f188d6a,7fc843ca,d24d0858,1f4c9485,8b9f85eb) +,S(fa51306b,34800ff0,ccd778f2,838a4a2a,8200eafd,622e98b8,8fa566b3,85943f64,b60ee616,6b144873,a1cee030,fc92b50d,4b67757,ad34d5c8,5f05c871,4296e293) +,S(85df9018,329d25a6,79c097ee,458eafcc,b716a59,611730f1,7c19d584,2dbea60a,c555d5b6,46d211c,e99ad7c0,9e787774,b7bc64c6,f2f6980a,e62e8911,897ab0fa) +,S(2f77c00d,c2024467,ab461b52,ae634a99,337ff5f4,780637f3,efb989ce,24af5e3a,c7f4a678,ebcbfabd,870c52b0,be7efba6,c5d28e7,aef2b253,3f0e7fa,905e3e39) +,S(52d8a23a,720050d6,ff6a499,7b802bf5,1f238df5,b0ef6001,58fc48c2,228bb34e,98ae81a7,861b8e1a,162d29b5,1c30c786,cebb1812,c91780f2,ccd302db,803d9136) +,S(a7f3e479,eaca0049,22fb8320,47555b5c,701daf22,407462fd,37b0edb1,7212b211,80f6190c,8c4ca7c1,7ba68498,d1bac039,3e33767c,c476fae8,e926500b,9fbdaada) +,S(31ef3150,e67bd326,61bbf4d7,942382af,73db5799,8f4880,ea04607c,a2356103,7db8f5d6,655d28d1,93b50bb5,14b16ed5,bc03c46a,e3d2c954,631834b1,a8a9a8ee) +,S(ee82f155,469c0299,39ad1ee3,52edea30,599b0cd3,868131fc,eabee245,3b8b058d,fd0c0d4e,2d77c2c4,2add9ed6,cadb898c,32de9398,f0394400,eed2ff30,5092b10c) +,S(dec7c7a,bfcedd6f,a9f7d45,8a071575,27354990,b456873e,206d1f7e,556b4586,af841ab4,cad597f4,186f0912,b79fe320,2c7626c7,b85cb276,73c18010,747200c4) +,S(c28e3370,48cd6fe9,7591ba40,5519bd80,2bf34f12,ee48762e,526b34d1,f4d2369d,e00abdd,da456731,7f486dba,6976ba13,b8640f52,39325a64,7d50eb17,f0636e8b) +,S(47157ca9,2c275f65,c29e9d,b0f23531,37027731,1cf05a93,7145123,df222195,648b17fa,c911fd25,af87e9ed,441cc874,9fefeb72,b34f8dc4,f430e0ce,89cbef6e) +,S(84d11702,745c53ce,d81b5503,79ff1947,9a0a9253,a7ab3868,f5471a64,6ca73241,4f16b6a2,c3c087a,4efb1353,644e64cd,fc593ec1,d8d656b6,2c0e0bc2,25f858c5) +,S(3bba3022,196060b8,6b2b2f28,ea8811c7,c74e8128,8e91adcc,b7fbe2d7,97d63fc9,7f34054a,f0945373,a77c5aa1,2ea4f54c,879d3f98,b6e7ef3a,9d73d2a2,a734e286) +,S(85637f4,7a2c6143,2437485a,b3d40e70,b9f74606,aa8538f4,425e8a06,98651c6b,bc6a95d5,6fb42b1e,67b07576,83a5036,f76e8531,a30d0096,c3500ad9,93396054) +,S(25302e98,5e75019a,21ed1605,dd3c543e,e8021a42,a40a967d,8ea6ed31,4dbbd123,849ccbe0,23097591,d46f9b4b,a13713f9,c0220639,11fdd0f3,267a4d8e,66797a83) +,S(e59a30bf,88e393e3,c08d73da,ba720ae3,485fde0f,b6b85f8e,4117f5e4,f43bea40,6fd7824f,e222cb37,1a0fa6bd,33e4bf83,83ebbb64,87872fb4,42284498,6197dfd5) +,S(c5902df6,97981a60,589e9bc3,b935de2e,de05331d,2c1365bd,a83f8183,f6247e4e,c67eb14f,5af551ef,1ab5ecb5,8feb7ce1,21d0736e,b93dac91,f865ac7d,2d75fe3c) +,S(df8bdac7,fe27127e,c679a9b4,74e3c809,b8b6409c,2e6c4c1b,277ab4e6,d5e66ad,3ff26fe4,9f0b3896,54d802ed,72eb4708,2738256f,c0266dc7,645b1027,717d43e1) +,S(1d55404e,9c7cb8ca,c39c7c02,b810d5f0,9eff9125,9166cf3,f1e8cf76,2c65a82c,c1787023,f6a1c8a3,5c499f64,a2fc4d23,e5a760ea,9a04707,c24bb9bd,b2a7632f) +,S(35f390c9,b035fdfb,68506073,d585e450,2d040e96,67a1b4ef,804ee088,df43b44,6a85cd88,86aad8b7,7dc36fec,50eb9754,4c3cad2a,da43d038,3c55da38,bff512a2) +,S(fbb0840d,ee888fa6,f26d7005,b2449cfd,1d22786e,d43d06d5,88f744c4,c5e059b0,6460514f,d89a70f2,3a4ffa21,9f651bae,203b05f4,bd3d45a6,508d2b25,cdb8d3bf) +,S(24056cf0,1c2275dc,44608ac4,66931e91,61fa0ae1,3353cac9,ce481271,a34d78d7,43ebd3c6,7e7381d1,bf03088f,434a5275,965a3fa0,d86a51bf,7dda1b63,cbc7751f) +,S(3b1043df,e8447c78,8e07c938,cd72f6b3,54f9f745,d7e71297,e7791972,70f9cd78,28e028c4,abf0d511,126c29d4,b2b185c7,b67ba361,e16c50c,34af129a,5e40d6fc) +,S(aef909d1,41793638,80d75b23,6635805c,8088b08f,5c577a81,a5bedd20,69a040e6,cbb4c6f,de26b6c,5d0c2b43,df40a3fa,93350cc0,1c497382,d8a1bb7c,8600dc51) +,S(c8d494f7,386331cb,6ff59aef,5f229bc7,913367b8,10f407ac,2c9f9d3,ca833f28,cb2c76f9,4b6285d4,d39afdac,bd3ef114,c7b85027,8d62da67,e70aa74b,b10de4d2) +,S(25afcff7,af14ca32,3dc74443,71de7b5f,c1b52e17,6fe5f3f5,f4f39139,34f75b28,d867a4a4,7f9d7e97,6cb1f57f,8d505a66,5010cdfb,4af4b781,75271722,6942b789) +,S(2436c86,f773930d,872c220d,c8bd72e5,d407682d,7708e2f8,19ad9632,3d32e2c7,6e396dea,92af663c,c44de690,24e1407f,20a95887,37f01662,bc89cdea,88ab67a5) +,S(61ceebd5,9e5733c7,910bcb86,e19159ee,57638bb8,7f3cc56b,d0f4d25,147f349d,2a850545,e9b0ed08,fb63082e,741a30ea,7d85218f,86282aef,3e74b15c,f2fadb9e) +,S(5a1133b5,d45d0071,42b91a73,79e2a46f,dcbfee6,e102d16d,d77e817e,b4b6c187,2ffd96ae,afd6d9c4,3c9c0517,133a4b7d,34c1c2e8,f398f81f,f6f0305,28d492e1) +,S(b74a3849,8b701b41,29eb5abe,8dcb13b9,fff0f191,314dd293,9c38d0f,4563c8ac,9d844e57,e50a20fd,864d6f7c,5a677855,689be528,f8431186,ffa96679,9cb9014f) +,S(c35c9cd0,4afb20b4,3fd1c337,5a952ad4,8e9a806c,a64aa4b7,52fcb204,5f89d26c,b041c6aa,4a83efcb,dee79d84,19e195b2,48c765c3,f069d5a4,b7e87792,79a9c65a) +,S(9a85aa58,753868b3,f04b2af4,479141d7,11703dde,e5b6e5e8,fea8ad37,d0b82b96,465c70ab,aa16f03b,d24b8075,233ec626,4e062041,3bf485f2,551d9952,7bd75d27) +,S(3ec71bcc,e051f3e5,12d83c14,cbd23f49,b3e825a3,cfa4c61b,d12eb057,5c86fe14,f198c21d,e2daa56a,55294c5a,b033f1aa,45caba3a,9a950007,db35f05e,e9915bdc) +,S(ee1cbe22,939e1ede,9010e23,535bf33f,6b09e579,3737db45,aea48f00,b359ae63,bf604026,d4444df6,27f7d297,1dab6a91,acecb6d9,de53228d,47178017,921b90a5) +,S(ebcbf3e1,71de3a62,ef47677d,1ff4d027,5a8cd92b,bc889ee7,8dcf0c99,6746073e,878d63c7,bc9c7224,914a3f3,2dadeb9,95c6d890,a3823f98,5c3f574,9ef6ebe8) +,S(e4e92ee4,ce72ef15,b87c57d5,259520d9,b6066430,c090dae5,6e81b2fd,ab9db797,3faac465,4a03a753,559f47db,f5877452,6d21838c,9c1f8217,ebef6965,655f944c) +,S(fc1ce758,8e292b03,7b4ef743,12eb1f67,cf275fc6,7c1e3d63,5bc42dd0,deac1cc1,176b79bf,44f7d9af,7f7c791e,8cafcb7a,495bc392,c23899b4,2fe7963d,e65186d7) +,S(f1f5bfff,179e6a6c,692a86b2,1c95ef85,49482b3a,b97a491f,9e9c7056,ba94fc56,389257a8,a2cd3bc3,fb4f0620,5c2aae70,67041512,10c62093,13a2584f,8a39e143) +,S(980e7414,61c3e001,ba6bfef8,d175a141,2c7aaa2e,748c3323,ac744fd6,ab793eb9,6e37ddae,29e05e83,b3cdde28,d4286005,34cbb33a,636c4259,c7fa7625,1b31826c) +,S(f519cff7,686a5257,71986dc,7e6c1955,adb7faa6,a6f7a07f,66a257ed,a1b1c179,3e803eb0,8c765c98,7941d008,a93b8503,174ed4ed,1c31e97f,9eeb8f2,a55a807) +,S(2dd8d9ea,3851fea9,1ba9bafd,bcc5cc0,9011d939,10edceee,144e2755,ba8f8061,6147f1af,d4224689,37cd058b,4ef52618,7adfdea9,ce970dc1,365fe04d,1da52ae3) +,S(860c4262,9483537,47ac0c41,5aa00f63,2854f88c,d7d09b35,edefd780,1454a4ae,a2a7a22a,7d826d25,8e7dfc56,1eef0d85,d15378a2,80535cef,95ce6e2e,d73392f4) +,S(e76b20ec,17d82c3d,987d4ea,20535209,e0697f90,2c964b28,ae97ad0b,aed732a6,c97844b6,85f6613b,fdb7cec9,cc47f701,32bc1137,d997f8f4,ad182492,67f54bf0) +,S(26731d0d,12fba582,636862b1,62a417b7,718ec9cd,e3d047a6,50455efd,910ab88,3c10efb3,b464a61,6e2023b,b0736d6e,8d298609,47ba5714,3b1a71fc,9b542192) +,S(50cb4878,52db811a,87fe46f5,ed014db0,3fc4570e,8b2d8ea8,9865df9d,a224dcde,bb8488a8,7937ae89,88f572a0,c100e450,c69db48d,303d06f9,5d54bd83,8b39621d) +,S(fb69453b,1d67ffdb,670f9fb9,2b3fae5f,64b0c4d,cb28ba0e,7ebeeb21,ffb02a60,b0fdef36,92d881b6,3ebb1387,984120f8,d1ba17af,477364ca,41e303ee,a4fd2c39) +,S(a8f1280b,4b720226,19faec4f,ea3f784d,3f4061a,56dbbb99,38c7706d,8bb249b4,ebb3b571,ac505913,4572e501,4be7be33,a97e12b9,bc1fd9d4,484703f4,6e39b8cc) +,S(4292ce09,df305790,f17cb3be,30996016,420f83c1,bc19abb8,78b49027,6eacaa98,1b14d94c,bf2b1d1d,82cf1873,3461b76c,f32c8d5b,6746e2f9,aa2aa248,1c745d36) +,S(ac241177,f16f747f,b796750,49c83f8f,8e1a062c,9796b05b,8c5a5587,a4c9464f,dd057503,8261d044,ec84eb03,73065687,266b695c,ef5cb41d,1cba3b5d,9176cf58) +,S(692eca73,26bf2da5,7fd9d640,acf7f846,78e75c9b,86b18e7d,d7fd2545,751823d3,17d6d462,548ea78a,18557320,289d61da,14c3850,4ff03347,8f17fdd3,71c8e97f) +,S(d01b1a44,55ef5011,e4ecf946,ec02e6f5,d0e129d4,d2f59889,e823cc5b,6f10e216,84a4d89e,55e33edd,d54f38f2,1649f5fd,807879e3,388df988,34556ae6,57f91a0f) +,S(1eba61f2,96a788d8,9273a67,18f2a0cf,fb0798c2,393330f1,2f890bc7,9bfc1e9b,89f298cb,e8471046,2df0a6a6,b6c4b6af,505da2c0,9ee13266,bc47cd5d,2ddc9661) +,S(26dff8da,94603121,4649fe1f,721edcc1,a2300ca,b1a6d548,9c9b68d7,415980ea,d8264a21,55e1bbdf,c3b65862,efb9548f,3c4a0a5f,97f5b713,9d3da15c,90004e60) +,S(4e642b51,425e1822,1275f64f,283e9eb1,a3116adc,a6e25047,cee3bc0f,323fe676,f28b7d65,9125468c,4951db0a,bc35d4dd,65b9c5a0,ed27d742,47a68a23,89eafbb2) +,S(354aff5c,ee9a27db,37e7c97b,4cea476b,b4f3700c,e9c26b21,e94d2e1a,78f448a2,8d6907d1,624b79e5,6392d008,2f6a794e,99b4c4d1,6ca78dd5,97709c86,2930fcdb) +,S(5286d074,949369fe,8f69f020,c0b65f75,e76995ee,5f49b9dc,d570b956,8ffbdc3d,255ef2e5,3dd2c40c,1e462a45,27e6ee00,e0a23d3e,b16b05e2,2781de6,879703ab) +,S(b84a8346,c86e2299,9acc8ff9,1a893592,6bddeeb8,6fde121c,266d5f60,3268add7,31179a8c,79f40238,e1b80c87,81e46597,29f5c8d3,d8bea0a3,f65b403b,ef20789f) +,S(1e7bd5e6,63fc9a50,2258b9f1,14fc51c3,1b9dfc27,9022c67e,fde7872,dd12bb94,6287a9b4,555b146,7d250f11,e77ee8b5,7accefe,6d91cb6b,927611f2,c2c1b84) +,S(7ee68a21,37289ebe,7a5cfde6,be672ca6,9d28acc4,54d6b8da,9c96b2ad,37d2bc81,3ec34064,a6c3ca,f2a8aeee,9b24e023,3d7dcbe,b7acddcc,8a53db84,c570c83e) +,S(29d4b10c,f4be3bfa,a9d07fdd,da6ba7ae,f3adef75,67c3c33f,8d4d914c,f8ce570e,b6a74385,96a4f40a,40d03c25,2c7070da,2ec79e08,dbef71f2,422392ce,1058bf4c) +,S(7907c5d9,5c5cd647,e312a43b,42c3f053,50218f10,da6279c9,895516d7,328c359e,6c65a9e1,ec062a1b,f2abca52,fdeeac18,26888378,58f985d4,c8f1c987,64d6a625) +,S(cc436eae,ce11bbc3,36014fe7,bc68fcfa,e5bc2c55,c53430ad,fc994b8d,959d31b1,16160de7,d6ffbf64,d644e608,96052985,6b2bd539,66d7edb3,a50c924b,fa9706a2) +,S(cf023d5d,278d4201,ae659d55,6239dfa2,1b5fb30b,14adbea,7351b620,150ec1f0,d6007395,ffcec07a,6e71c26e,7575cdb4,34c473b7,57d4574,9e5154e4,d4990741) +,S(1a2a093,f718c59b,d4d35b73,2c547b61,12b6a257,e807a38d,71b04125,e7746a21,2674b542,652fa39a,1a2cadcc,3924796e,16c0f8b0,5d83f919,f8b93547,98fd4c95) +,S(534ed420,4b8ac51,7518fdff,224ffae,f712e4c7,6a84215,fac925b7,eeb799d7,35e5852,3ea6199f,b9fe497f,576dfae8,fa30782f,d24cd439,c0708118,dbd82155) +,S(8d31e4ad,9e6f30ae,6c78ff18,8f4b0457,e9ba646b,3a26138c,f11d84c1,4a00d08e,f0dbefc1,909396c1,3a1e36a4,844b2a87,e4b0b1cd,4b30e996,47839bcd,4dd5feb2) +,S(81748452,267405a,bf664379,16ff7f73,c418439f,86b73159,54c15fd2,2d2b3412,13d1209b,435b50b,1409389,9961f5ae,9f6f95fd,280beba7,cb3f3f5d,a0f19bbc) +,S(bca87f72,e604e885,64552b,edf380ca,45842270,57efe12a,6cc23847,658aaa3,ee508af5,28b77125,72c123c6,276ba23f,af26538d,5752d84b,54ee82ba,df9e3d0e) +,S(de2baa9,a19652f6,c0c0365c,d6e78cb9,d527e546,1240fc52,e8c59183,7fcd3fb2,aeb418ef,466c32fd,4cb5f2be,571672dd,86573941,a9cf9bd,73377aca,1ed38905) +,S(7b8ce1e9,14df7919,b54a0591,c077135e,556f6cab,c7665e5a,c0004390,22acca9e,a60a3ff3,9cd8ad49,c100b72,4338a54,d06a96a9,f3fdc7c2,fb8ae598,c0b40628) +,S(cd71c179,13fe7443,19bc80f8,205d7617,4d6d44fd,a6ac3d1b,402279b,eca50e75,9f1e73bf,cf3438d0,1f01d1a9,3f633929,ae385812,528ad211,967bf38c,71419064) +,S(42cad02e,32dc8dc3,4ba36161,d0816af1,619b70e,117da444,f4f1e454,73ca8fe4,97cb2134,5a259cff,8870823d,fe11031a,79e59d7e,dd2593c6,65128a8c,36e75568) +,S(98a89130,4f0652c6,2986644a,62a1dfab,48331756,c8b9e1f6,d473c03c,b98ff8c7,c130f2ce,cc506903,9ca49b3e,534ad484,b277e0ad,7b2a8733,98864000,e9a824e8) +,S(23c45c76,84762aa,7bfd39ff,284403b0,d7a4a128,6bd7b455,22c09d2e,df8a4328,f4ab7317,95c46f47,c3d46dc7,cb0d43de,d57cb274,ff0c350a,f0d79548,bb303cde) +,S(8b700037,d584c4f2,f65416f2,dbd37c35,9e6a7b83,108dad34,3a6c4d0c,6a21d856,8371ec03,9ed0066d,4e8e7d86,69169f9a,5a172cf6,c324c2b,ecdfc76a,c365ca35) +,S(da6164a8,d0fb4111,ca1d78f2,83e8180,4f4ae8,50ae8596,cdb97d9a,a30f8a7b,f9a8463,717e4f17,a77caf4e,10c11101,1cc0b5a1,c788307f,c7aba482,2a9a342d) +,S(49f37d65,a9d1a54d,1929b9c2,6db7d7e,c45924e2,9e6010fa,2202d47d,eb5fd6b7,f9b9b785,28f62629,7bd0dbba,9340c142,1e64895,b1befa94,ca677de7,686aa51e) +,S(8755f088,e26859a0,1a56b78,ba1898ab,12d80837,308677cc,b38e9c53,e36efa10,5d67013d,1eec7a88,215b4768,f55f83f6,434906a9,f2f6a9a9,de5df75f,6ef7e478) +,S(35321796,b7aba6dd,873550fc,5a35e081,a4e6d134,a127c534,69ff777,c609045c,47ff0f43,efa93f4e,f197a680,4f1e1133,c5c8301c,b49de8ba,6fe10167,f0a1e832) +,S(3abedd2b,644bd2bb,e77ab5ea,2823b42,83479fec,df2b3421,56fe9ace,612559b3,4269b08e,6c13b818,131824ba,11e3369a,87bbccfa,330e408f,17985b21,e5e32b06) +,S(e30112a2,2c23462a,a803dc53,e3277d7,c14b62cc,92787f77,5be98ffc,7c956de8,d0c7e3d0,dbb10e8b,7a9f4e0f,f93e7581,99d90f6d,d869368a,8d2ad369,4898da40) +,S(6250858,439c4b4f,30d47f6c,b9259103,bcdf497b,f09d3762,f1073f5b,973cd06b,3437f5e4,84ce4258,5584407a,fb0e4383,87e4c930,2fcc902e,cd26b721,5075328e) +,S(77ad4485,b8c94cfa,4e904bc3,90e93e3f,66838d50,fb16e09b,dcb39ad6,88f826ea,4dbc505a,9798879e,137c8444,750ec3c3,34c2ecb5,485bab73,6b0b9bbf,806001d4) +,S(5dcd3e92,e413601d,b9dce337,7a8e67e4,3852b8cf,ac41066c,ad579199,3ac0b7db,acccd081,35efb43a,306760ed,ec278f7f,36996ed0,d6367f85,417754cb,a4e997c9) +,S(3a26663b,adce051f,c41d2e6b,9b931851,e65ca385,15f59737,fc8c27f5,caff788d,2d647eab,af01d846,70110e,7272cb4,9b9db0b8,88a8113,bab5f89b,90abc2bb) +,S(f57cceb9,51dc98fc,712fe9c2,c024031f,4e3b0f02,5067ac4,b8bb0096,e4b1aec0,696093eb,7a8aebed,a751455,782f99fb,ddb2c66d,438a7bca,9c4df301,b7a1ea25) +,S(a89a4778,bca06e14,bdbd46c,948ccd36,df47c83a,2dbba9b0,93589406,be9b4a0c,f4224dd6,9d08262d,22b98e2e,4e781e6e,939d69ed,d59f30d1,d23f9ea1,6ef366cf) +,S(64738381,84fe8247,2b463f4c,7ff04a6f,6a3be92f,ba295d72,adf065b8,10b962a9,bcd100c0,d09f6e93,4fe9d58d,d58004d0,9ba164fa,324010bb,c973709a,2ce32de) +,S(4a683a38,21261e28,2e0196ba,d9f8727a,f7bcaa4c,afd5e686,6c7cffaa,3adc7774,b5aba4d0,ec3d9aa4,39b37f0b,15f40fed,913af371,b1b94f20,2cc93378,954ff3b0) +,S(1025e16e,fdaeccd4,436cfd9e,b8ee1614,53fee046,e420296f,53cc2e5a,bb5cb3c7,f806b96b,67ce92a3,e159b807,58f38f73,704e4d8,3bd611c2,25314400,f0c48f3b) +,S(6149d809,675a5353,6fe2217b,7f6777c7,60039cb3,5a0840e4,552e2ac6,db6650d2,e4ae636c,9a9808aa,4f49b03f,bd12f786,c72f07f2,9e397a11,68154505,b1a96ca9) +,S(ba24112,43888342,54ee8327,4bb03dd3,2fff3edb,4d607047,d8c141d4,c3fec47f,8a6bf123,29c3fcdd,38e6a18d,ed28c8a1,3717e997,9d0c366d,aa640dd,bad5c35e) +,S(c20df096,3c7cac7e,9dbaa259,538af550,35c00550,94ad4993,2190688e,7856a961,491e995d,16cf7ae9,85b8dd8d,6a5890b8,fb4f2c42,aea7c33b,ad84835f,b245d40a) +,S(6f53d8ca,4dbb4d72,d9ef3dcb,93dd2ec1,aac9f38b,1b4cb2a5,c76449d,4faf0c50,6784a02d,f449beb7,24156de2,486753c0,77bbecc3,27caee12,f7888687,4e7ae24a) +,S(e57e78bd,71a08f60,51c8a046,184757eb,6364ae0f,8eca86b3,51317712,737bdda3,a0623c7e,8a535f66,57116c82,da77554e,31a1d263,28ec0e8f,116976d0,f4385342) +,S(f52f6f29,aad496ab,9e0abd0e,a7cb53a7,7853e8e1,a6e5ffff,285e97c4,f7ab099a,3df7c1fc,6d5c5e81,8b5de4b7,66f2995d,c361511c,198a68e0,b7196204,559d55a3) +,S(da74f5fb,5c0a6d09,6fb26268,b33d9c86,ec5cf08d,8bd65fe2,59f836a7,3efb0dc3,7e50e989,de5e2847,7e31c816,42a51edd,8d0ea031,35423f3e,ffea07a9,48a62c47) +,S(2a2c9aa8,7bd45217,f341d35,9a9d2de8,35d14414,cfd3eed8,a2337a64,e051f4ff,bf9efdeb,99335f68,a01fd7e5,d8aec9f9,49688221,59d18bf8,a466c6ef,9648a1ce) +,S(2a3440b1,91dc5314,c6d0da7d,b07e2cf3,7d13bcef,1ebfd23b,492ad632,92022266,bdec24f5,c993a020,2f2fda24,e8707947,e4c1e9f2,2c34efc6,dd1e62d3,e2ae2b40) +,S(a3a9bd74,3d1d36ad,fad36e8b,d5544500,e0accea,d53d081c,28740109,e10942a2,cc33decf,f8cae7d8,dedab1fc,ea1b4c16,2cb71104,ff75c16b,66db334f,ec794ca0) +,S(5b83d48f,70a2f212,93dc724,77f4d87f,80db7eac,2b08d70d,308953d1,88804950,f78c0488,a10c66c2,e11368d7,690fcc4d,982ecdb4,7ed539c3,30d4b14,4248b545) +,S(dd5b46a5,6e3e4a22,39e210,a871db8e,d901ab96,3c6fec29,4140d77b,be9736a,d9b76eba,ebdd45ac,35c52268,ccd35df8,9e7136ef,879848ce,ae647c13,d421d46b) +,S(2f74db5a,25486127,6236bc5b,22214097,d1ff781f,3798f64,62cc6dcb,3f61a6d3,b6d635ed,256f6d2f,a91b868e,a3014db3,64647147,ac89248e,ca983c09,53149c1c) +,S(32adc0c4,1f7c939a,58640b8b,fde1c8ba,119bff26,dfe4b0be,c5058ddf,23ab2e09,cf317248,7f0bb297,d7d7772d,2a01d917,40beed83,3a35a293,66bbb0dd,3946ae3f) +,S(4fe53ca7,172da8,272a152e,d74c07ed,4e336cb5,85cb2ae9,36f9f301,87c6cdce,81f6d1c4,bd711c16,21cc2986,916578c6,baf42870,58b84843,27e46e98,81e3a8ce) +,S(601934f5,577fa2a6,702f316e,b4dfed9a,3b08dc06,5d3e58ae,63f8548d,9fb2569f,6df7d882,4360fd7f,b5f96f68,93b1f1de,55e19690,f6acf954,362074d0,30f714cc) +,S(79da708,8ff4806c,64492ee5,2e9dda2f,e1bec3c6,79fa3129,8173c0f7,aa79d321,2b1eca29,76f2884a,35167e8a,bd2055af,44be734b,b0e0847f,f90abe8b,17f9a47) +,S(602b8209,c39f299c,bc208b51,ca8bf691,5b8d4fc8,d8399186,7e589dce,79262974,f8b6cda,5d7ca83,6aac43f9,4791a5d8,a5ed1f05,af90f5f2,267cd9da,567f5555) +,S(57a4f368,868a8a6d,572991e4,84e66481,ff14c05,c0fa0232,75251151,fe0e53d1,d6cc87c,5bc29b83,368e1786,9e964f2f,53d52ea3,aa3e5a9e,fa1fa578,123a0c6d) +,S(4f9b48f0,ae9df110,70c4c5ae,2b012cd6,4599063e,5bd32b54,43548b78,6a06db2a,d5a7a0fe,3cafc78f,66f563eb,f6fe42ae,980cd621,bf18aa15,7bdeded7,dd5ea016) +,S(e46a5308,4b11349f,44661589,38bb663d,e1910aad,35de0708,5a053b5f,6c5e7375,da46da88,9583632d,fbf923be,9f07ace2,cb8c3d2b,fa6bfc47,9e1a7d32,e1183ce9) +,S(3643d766,b94b161e,323e64de,3c925040,d62f2ad6,2b60a674,15c8b962,1c071ea,faf69af1,1f2b9e05,db29dcff,a020f6d4,80835d4f,83d35a96,7aff1b5b,9f16fa98) +,S(96769694,c026152,1bbe1b48,544e05dc,e6bea57b,7fa31478,f6ff1b1b,bf497dca,4eb5a6fd,7d0dae14,9673b033,bd97c08f,8210fd12,c759293c,40782702,b3e30b03) +,S(2e41def,2c479931,89be0ff4,b4110e28,7f80fda6,f4134ef6,5c867e66,59a24d07,26a14d7b,b8388b12,a3ba1f50,e56ffb3a,69bde3c1,17441f52,158531d,c874c313) +,S(f39d941a,f6eafe0e,9a44fbf7,71eb63e4,db94cbf0,854a837d,b7f284c5,ac03c29b,1ffed770,dac4d12,2241f8b5,507e04b0,72cd5934,c03b0183,d8b62e73,8cbd7b73) +,S(90900d34,4576beea,911f8dc,c2d90625,1cdac045,28017d1c,59576449,50136419,60d38bbb,2a338102,da044498,a2b2c5c,1457cee6,eb34d666,b0c0956a,48161ad6) +,S(3a5e4627,1007f4a6,2e744226,f1d2b782,44a523e3,97b6509e,e3e1a513,d8ac2e06,50f01fc1,74cfc3f,256dee2,fa415f35,bcdfcfe,57b79d90,f75226ba,e8202449) +,S(f66ea256,f6d711e4,1ea5492e,f6f6e46a,b13ac258,a8f0eb87,a06b6c3f,13e24355,fb8a1c47,980ea6c,87ec2401,4c0f6d2a,8f32a2a0,6f3fd0b5,7fa00307,26243841) +,S(cada0520,19a16ccc,fbb6d4ed,6c7436d0,c946a485,ab3362a8,5c62580b,d3038fa0,e249940a,34804324,ac706963,91ae7393,421de971,af0f203,2b5f2d21,7d32ae6) +,S(d16f5b5e,820b7295,96bd5192,9dd830b2,ce208413,5c2db712,2c4e75fa,cb759cf1,70edb084,cfbebcd7,ddd36380,75e05147,6ecdd585,e228749c,e61e3784,6a448ed8) +,S(bbccce8d,dc6bae0d,cb6e5149,8c666f31,3dc31ac9,d4d949a4,84751134,d5f71535,4da772fc,63ff92be,5271b479,68e7bbf5,c8941f68,989fa6e,a23ce5ad,23f91eed) +,S(515f28f5,cd8b75c4,325e940d,6821eba,e7d5d2f8,e836b291,5f606152,ed4243fe,a13143cc,f5d2b8fe,14a09f46,68229258,e1855a82,6f7db2a2,4ba2f1c4,63668b47) +,S(bd2f46ae,a78c462d,8691ed6f,9d381278,68d356b5,b8fd7f79,df6ed845,21233837,8f645ed3,f3cc803f,7eb32f70,ed7d6fe2,84ddd9ae,62ab8324,b92bd7c8,79c4af11) +,S(8576f13c,c3d32122,69e10b51,2011a450,4f8d7d3,92e0f133,47d7d65d,f9e37dfa,fbbf2048,3fa0e131,2309eb8c,19eede8b,86ff9028,45b66195,8d19d903,f68b1a4f) +,S(70be1e91,8fdf4e47,d73f262a,bf2361fd,763a83f2,d31cf41a,23b8c9f3,8309db4a,82f80575,e4246ef4,c13fa48,8892943b,a1897ac9,dc3ef188,29f3f708,428bc573) +,S(bb8a093d,1d586b53,9bf54a46,1a353af9,173529a,12312361,c8064e91,4b41180f,460e0ed7,8456a251,cd68d66b,ccf5de7e,28707540,d221d65e,72334d85,af478269) +,S(7817ae4f,34d9194c,f4b30628,7071fa1e,7b976a84,754c1860,6dc4a124,bc5c2e69,25f4ec56,c4e3b1b5,bc6ed346,e4f8b340,6afe1c0c,f84ad7b,481be5dd,2cd55cbc) +,S(85c760dc,411f59fa,6feed8e2,a0e5bb5f,e72af5f1,2734c9a5,bccfed11,bf66abcc,92583db0,b57c9c71,bf0f1248,23a67e5b,89a8910e,6500e8ad,10666b26,cbcb8cc4) +,S(20d80d35,4d9d762f,f2c739e3,b1e7377b,d9ee7123,47ea979a,d4c81abc,5d5086c3,6e191d7b,8017a675,e8123b7f,1f1351b5,ef6ed6b,1b225cf7,48941df7,62f0efe5) +,S(3306922d,43f2c4b0,65f6d9c8,d1289804,ec26cefc,97090fde,86dc3e0,fdba5657,98a8cc9f,c93dd7ac,7079f76e,fa1c4065,86f0e941,9f87cd88,1b865c30,13c7efc4) +,S(b35c7597,54d37f12,440f7703,39223681,8a1b9aac,b085fc1,8acde6c7,3b2fb001,484b90,69b08485,95c58ffb,df5968e,2ea789b4,6f93d660,a7af6b75,13cd649d) +,S(9bd41b53,7f8bc303,6cc9d010,45922b1a,5c647f8,e90fd587,86ef0975,474e1f33,590afbf6,55ece125,da486bfe,1ff389a5,8b866776,8d2013ae,c25d03bc,bf0274ac) +,S(2a3a672c,a9b3aef0,bce89703,a38e0dcb,6950d93a,7359420e,5278f160,541ded42,4c3a94b6,13f3383d,b908ebef,6b62bab2,c95f850c,f88aea5f,c6af3b89,c2693d8e) +,S(31ba6af2,a2d94f8,d4df3800,353806dc,c8db945f,16dc5bf6,93794382,58f74d3d,ad19dd02,b290eb1c,ba5d915e,f60344c5,fc1e6a82,c5427f4a,236238cc,2329df5a) +,S(fa2199bd,74b014f0,5df0f9b8,ebf44a98,587c0251,e9c49bb0,5bb12952,bc869720,4328917d,6efdf5f4,b0f5c483,860e1e9b,41ab6ee,b1f5631a,66d2d213,b163f45e) +,S(417b9046,c7f53c0f,5ccf2847,692ab63d,8aaac02,e3bfd99f,30a469a9,8be22d52,78c15e65,5f309788,dff6eae6,91706e00,7aede9a8,3bdb08e0,d495d6a4,863b82c0) +,S(56ac91f2,47d51fd8,8a0e6eca,67a69ffa,6158f498,1714964,f33e43d5,6f18bc2a,351b7d5c,9e1b1a4b,717c518b,37b81c64,429beeae,26e7a740,c54b1a66,dd0680c7) +,S(aeba32f8,83307ef3,152d835a,a0babec9,e164ae70,10c90250,68507d65,37215f8a,8d747d39,35cf5f2e,6ff16557,7ccef843,7ce7e3c6,a41cc40f,dcde2ae8,582c4e21) +,S(42c7b219,9af00c97,693d6bcc,256ed047,79ee10eb,e4dbe63,d47d681d,21db5813,a15fb708,1fb1c7cb,2ce44a4d,f8958432,a5fd875d,1fcf7c75,c3c4865b,b219378f) +,S(4337b297,ecf365a8,88bfe19d,1bcd5fe,25e0dba2,9c39e2c,36ca116d,a24e5d98,49c723ab,c6541edb,cbc83348,5e06db73,28d1ef8b,c9cd9722,915415bb,2242b7ad) +,S(18998c76,1481932c,e968af0c,eb84b250,aeefbf25,27e4ef84,a2519a1d,b7f857bf,455ebc85,64518443,5cac9ae7,7f3289d0,91133054,d0bf9ba3,9b7c8128,26c97fa2) +,S(64c76320,fa24572a,590516f,1bfd8b4f,87767b64,1e65588e,69cb895b,6a49b2b,a39a2a5,c4795095,a03ae76f,86825ec1,78366c8a,8799d395,d39fe8cf,74b9603f) +,S(41657405,e35eb87c,a5ba5f2d,3c6f12a6,dea917a3,3b3b44e1,ebbd3bf4,812b0ad7,8e2169ae,36f1452b,4577fe78,7adccb53,4d0ed75c,2096b491,6b68dd6f,95ff815d) +,S(aa200fa3,768a4b89,16e110c8,f4a6315,7bfd4a11,2c10cb6,8b76e30d,c0391f6e,567bd959,28b21555,dfec898b,d7d198a8,c49b79d4,6905afde,7fb3534e,a584695b) +,S(7aa78328,841d2f54,b843ba48,c8c9c623,eb529bd6,9e584966,555f9bba,77131599,6b4a2715,e4b8478b,24da7e7a,64e2f6f1,32711246,29a583ba,1bb44af3,69f698ed) +,S(94b1a7bd,6a2767ff,459234f,c78fbbbe,48446b4f,64bbdfdf,dae34475,396969a1,8f3065ef,2273a871,dd29320a,8b9aa41e,e77e2178,e8b8854f,df1e88cf,991cc33d) +,S(6b957ba7,1bfeebf5,294c8cb2,7681e0c0,5407df71,37a34710,35fd98ce,d526573a,67e4808d,3fc1853c,5e5cd4ff,6efb5092,35c6df0e,c0a5f7f4,583fdb88,7a2724a0) +,S(8b274330,ea34100,3be93892,ab1fcb2b,f9a6dfb6,80bd9cb2,b8aa6916,43717f7f,54fa2abb,77855883,e627f828,49c71389,4ed141aa,9c9cda3,c99afaf1,7998db90) +,S(d3f64f9b,67362339,491274de,77ac665f,3b686372,499a12e7,5d145e26,7b58db05,c06116c8,52bd15f4,145284f4,3899faa8,9bea5850,4018310e,5c82a050,c9a52449) +,S(198926f8,ce0e4329,1bb9280,390f795e,870d071e,801b4d4b,c4aeb555,f237ba79,76125bd9,5b8d07e7,5e27658f,a0dcf10f,5d6c10d0,4548dd76,a833f206,d2b3d34e) +,S(1bbd4d,595152f8,39746cfb,6ddc2584,ee4358fc,6f878309,9adca58b,cf01a13f,18f534de,cceac5ea,7083cdfe,3de5ebdf,ebdc70fc,4f0856e0,b587e9fc,df8d7733) +,S(88737f45,b2639272,37cb551f,52022693,52457f,21db398c,1312e275,f5a3132a,79a5672c,2895e1e8,4b1a7b22,21ba0c5e,e3e61cfe,c95aa029,b2a179d,e0c496ed) +,S(cbf3e18b,1f277773,34cca35e,8fe1cfa9,2d68497e,46e7a252,4e14bf,cccb1e83,db00c395,65bd456c,3c9d242a,5f24748c,7b91f770,926ba9a4,1ff5c94,86bc3f99) +,S(8070ef0c,f186efae,5f9c8846,72a93a98,8ab65b20,2720893c,40b1a641,c7022f70,da9805b0,46946a05,46824cf5,a87fd838,cc85c853,a745d8ca,a249d881,127bd9e5) +,S(acaf984b,8fa45dbb,e84c5064,8b6fe23,5c57dcb6,21243e21,90286980,c3f71eab,46f4ec16,8259fa2e,f144dfb0,bbae2907,801b8c1d,f17dd0b5,d1db3bd1,2ceb278e) +,S(2893a05,91f9ecea,735e8a32,a57e3d25,e8916252,52a44099,4eeda971,fbfdc965,6ea29941,91e4b123,12b5186,efb7d255,372aa6c2,aaf12a1,8c3b15a0,7bcfbb6a) +,S(64974631,68f0cb60,9c926e28,5ed12df0,cfccab0a,58f11b39,dc05b644,c2be951d,ea74181b,2fa885e2,4344bb21,9f2509c7,d432b5a9,c178b406,160489a,31eafb7c) +,S(b938443e,513394c8,b2d4f7c2,9811039,918621c,5d3a86e2,d1bf0e88,ba1faeef,af47f2a8,c7d98642,50784f38,45ff9414,c52473c8,9b669be0,96387daf,c353fc85) +,S(bd1ee245,ad10f50e,9f8fd4a7,876346b9,24f4758c,cf69bb8d,42f6dac5,9d2a5320,776e2e3e,69d88d5,c26477ac,74ffe92c,134ce443,64b39518,af787348,e0039605) +,S(cb7ec68,805e855f,17e7dc05,4279d8fb,6d8e1320,67a486a9,7d49df43,c660650f,f50790b2,84c04103,11f302eb,71525fd,b12d7339,6d259b5a,91ce4fd8,229e903c) +,S(ef07cf7e,affbb5a,29e22a1c,7c84cda7,1968c615,fbde2a15,e1c1211b,ab30cf83,98f4a6c9,422630d4,103fc2fe,e4c80f2c,2ca5565e,25859979,815c425c,70ef574f) +,S(4ffc1948,4d7fcc59,ccce4ca0,d11400f1,13dc5064,8626781,4eec26ad,3e7b8fc6,be9ebe07,98ff3d83,cb5ac107,5dc87f12,d94b65e3,937ee669,61b4e587,7fb75aa9) +,S(cbdd5373,339ed493,b8cdf0ef,ac6371b0,fad1ad6b,2da4db63,b4ed68bc,61d18396,527de487,c3212d47,1f538b6f,f709c130,3784a7d7,c803e5fa,c77bfa1a,d6bdb13f) +,S(ea035b2b,d8a1d7e9,db7f6b06,5e003f99,4e650aa0,e3035fed,65e7bf5b,c67cb5d2,aecb4370,2219f488,86772e91,afe81c6b,2cd57e96,2a3b0edd,dbc64608,8c3761c4) +,S(de1a4fd6,c1d6240a,d6e9dda6,b2d43fda,911648f6,901ed0cd,99ba8ef5,99f8db89,effc94d1,61c0ff41,d1ca6085,371e2e62,f85f90b1,542d2cd,3a4223ea,884da03e) +,S(2e644141,e8d87ed6,e1215787,8bcffebc,d75e118a,f00fb7f0,e58cf5b7,e6a076ed,4aa858dd,f2ba62d8,6b8a7011,26d22c2,b45c240d,f65f85b7,320e80ff,cb34b8d2) +,S(3844386a,90d6b878,90fb78ad,8f2d28e,47ff8879,2d275c3e,956883b3,71b73a33,f7f5df12,1a8149c0,75f6bde1,2ca8ee89,ff284557,f17cd57c,714fd474,b365cd18) +,S(e1fe9b32,1b91d362,2b618cd8,9ae8203d,bde185e0,bab2fae8,ff7e96f0,74358e42,c590fe90,1797132e,a25eff10,f2bf2a76,cef4f064,acaba1d5,f8537b4a,ddf3e1c4) +,S(560a00da,2f57d821,b6a0144d,45898af0,aefbbded,a1e08a49,9cc727c4,b27a3c0b,64874e4e,39db1377,3bcb79ff,983b152e,5db86d63,4dbbeeaa,a8b0112a,e795e208) +,S(9f33fba7,7ec8de2a,c1b16424,856e2814,1afe9b1d,bd0cd1dc,e5cbb2f2,f379094d,97cb8cd8,1838e2a7,26034f19,b5decd61,d972abd9,bffe3848,92fb0a9c,26fe94b0) +,S(98822fa8,24057512,48f9da04,2a0cfb15,e46ee253,e06a1226,da75047e,72d7a1b9,3e9eea35,7bc54ac,da547561,1f9590f3,db975d4c,ce7c4cc2,a553df14,feb19285) +,S(b814d1ac,4b757268,6ad88327,32f0f84b,bc72875e,7e21707c,c4086a06,ac1dbd88,b6364488,3749a122,401b8ab3,c4a7b8a8,c03462ff,18d69c36,cf145299,f18a98) +,S(246484c4,1e42113c,cd39f7b7,eed9dfcf,b39cf842,85c28cd8,6233c1a2,bd043e97,f35025b0,2e31bdd8,41d36f7,9d0b75e6,80f431eb,44a50502,3877f5d0,eb9552d3) +,S(9f330365,7b41b2ec,d87fff0e,4284e4c3,bbe8c524,91d358e,847afb98,ff51db91,4b9a7bcb,221c8870,de176a43,d4f7cce5,adf519c1,75613dad,317f4337,72d5e70d) +,S(c2e78e9b,3c75433c,5f5623a,8f5a4dc2,b0e71951,4b16161c,225b9bca,9d529d25,1e75c8f1,938376ca,c6387b20,9b24a2e3,e794362a,d62441b9,50588a3c,ab9079bb) +,S(89340ec4,b6e81b7c,855c9636,b548aeae,2125c40d,2907f86,7ce5e6ba,a7695391,f739a94e,263e796d,df1cc2c1,3e2bc10,2b2a9c9d,55248671,575c3ea3,792c72c6) +,S(9204ff15,f1443cc2,78facd4,8d38a6c3,5d66a93d,8fd8e2da,a7e2bbe2,d6629d22,2b9de875,456b50e9,6205020e,c293ff3c,13120555,82727253,be10263a,7559c019) +,S(f156da10,41122fd7,ce6b518d,c325f5de,61fad9e4,a7bd684d,7abc495e,ebff04d6,c73294ab,f4f2adfe,dcbaa78d,2031a5d9,7f2c404d,739f5703,76e46a0e,1b631d4) +,S(771a2d78,37d6413a,13099861,6050c362,2c379a55,26506265,9fa7da02,3280fa75,8b6bc39f,5cfe1f5b,82bef0b0,f6c8dd1b,e4270304,d5bc70f6,6b600b26,5d4c9aca) +,S(14cd58e0,36bb2c59,f63b52b1,f40e51cd,aec29f0e,b1cc0401,8e512366,85a18f69,79c254fd,ed354641,744c7262,39ea4e8f,ea15b19e,746b372e,f270c8d9,9c5e2006) +,S(e5f54077,1060072,5800bff1,390a67de,cd539cc9,52b6b43c,22bff27b,1a8633f1,d6e1c6c3,9baa86c7,5838e691,f9af8a06,80274da9,b0f54b5f,4c3b2028,8d666367) +,S(b0eaaf42,9c072037,fbfd14ba,79693d93,6791344b,3d37c3d7,5b8eaf8a,e7429197,d72661e,4a171b65,4f124d9b,d0201710,bc237382,6a2f0341,51051716,9b7af26d) +,S(e022d70b,44edaed,35957383,284e4ea0,5380f92e,cf62ce88,3c2e11e6,604d67c2,423c55d4,3ba0ed0d,1455228a,3153e9c2,7aed89b,2c3ddc71,52d2b11c,91ab4143) +,S(92a2d73e,b2eaaaf2,65a70f07,b949511b,af1a3eda,9e5d8651,349a665a,4bc5ab5f,4492d419,4794d254,9a089fff,53a32631,5f1703c,5ac34049,92d68121,e00fa973) +,S(43409686,de50a9c,cf35ac44,47a9ceeb,b12f102e,3ee6003e,c96235a9,8db9cb30,2f781040,952e1017,8e4e38ad,bd9c6c8b,c8e1e898,7f316cb0,37d2cddc,4e10bba9) +,S(d349dd1b,643f8d4,1b83aa5a,d735dc4e,94542643,3888a4e1,aaaa0ade,2394cd12,67f2f057,1da2b6ac,295c71c9,ea00efe9,cf082257,ece35bc6,72adece,433249a5) +,S(9a909a95,7fb87ebb,35f6834d,272d8ce7,babad39d,8f8323d9,c6813781,66dd10e6,ce3ead1a,32771a28,7f624835,2a2f6001,c12f16d9,f7093cec,86386572,a2ddbca1) +,S(f38b1e18,df2a2a64,9a3be25d,3686b5fb,1d77f971,1214d452,a67bccf0,ac07fa0b,5c9e9a,7f71b201,ba11ced5,9c0a4623,419a20d8,c488f9d4,591671ef,71e65ea6) +,S(42360fca,26b8d095,df52738b,c2762ed2,7b909784,c12b79a6,a86e06c8,31535a67,6b6f4ce5,e43ec003,be88bc43,2bddc453,db93aec1,657f6f66,5dec1912,468345e4) +,S(e3d7198d,a7c5e3b9,997993ea,a32377b1,b87325c0,5a002a94,53404c36,303f4a1e,72437218,ece6148c,df742be8,35fabfe4,a05f19cf,3205e65f,5c813781,2053ef4d) +,S(39412945,a8301110,6b54f625,8191529e,2f93db5,bd68db48,d6bc6d9,687cb59b,b8db822c,60f5c319,18b05784,40a958b4,e08b0a80,a1015d9f,d2826506,f250f08d) +,S(4d275f7,7e0ee98e,76b857c7,ed9368ce,d93dc914,d54ad4f4,21d2c097,cd241fc2,ecb803d4,9b502911,f619d361,f952ab13,935448e8,90cc2f05,277e48ab,a39d7473) +,S(29364876,c1db9cbd,a3efcd5b,6599ed59,160b145,3c8a9e03,c013f807,869556ce,2bdb4af4,cc44950c,84f56237,95941f7e,43ffb56a,77df186c,2dc31910,f23f6ede) +,S(7531f4a9,63dccdf7,ab83ef10,d3ba1333,6febcf41,f4b21e55,d380ee6d,e4878034,4753da9f,91d56bc2,1e9628ca,2d6269b1,e1dcb1bb,87c55e,9c44034a,1ba36ae8) +,S(8266d626,3d12feca,440dce7a,4bdf8ac1,6050ca28,5bc16777,a3d9450c,5c286e08,2500f2bf,fb8a4eb6,6a5e7e36,399f633c,96d908e2,5cda4877,5455df2c,afe2328b) +,S(66480001,4f339f15,8c39b26e,84389f87,6d5e62aa,59cb63d6,9eaa86d1,4bc589e9,a0699b3f,e3eb5a37,9f078526,375ac319,f145ffc1,da8a42f5,96c7016c,4ad92e2a) +,S(f8efcc85,8b9c0fba,605921b5,e6c89343,f641e2b8,e1f45134,86b77ab6,4cc70d49,ba97202f,7086f0d9,af5a0ae3,35d9a3c,5f4de2e2,79278834,f8b1d875,50a9d607) +,S(a5c1227d,254324a3,b1ec627c,93abfb3d,6f2485b0,1d8e2e73,6c542e09,9c992540,c9189db4,8a163bb5,6d99bed7,f38a7f7a,64cfef45,cf977da5,a1d16dbc,86ecc7cc) +,S(271b2619,a5b253df,fbb655d,7702dec5,6c85bb00,9260d893,8e050606,b8bbaf3,58ccf3fc,22cb8f27,dcdbd174,6abe5591,72bca7e5,d5af3bd8,d86c9a49,3ecd2ce5) +,S(c9e1382b,20c79741,d81800c,e721d4f2,1202ba30,92cac36a,d90c1dfd,570ae16,7eb1fcab,2a47cea0,3a92f707,d799749,6f7a0dfb,f9a43f6,90d213b8,1231e5b2) +,S(574b25,65232a04,1d58cb75,12b48945,45897e6a,8bd47dec,b1e0941e,309f2,bbfb86a9,567d74bf,93fbf2cc,6a9c9dd3,474db8fa,c2b5fb72,38b3af8,fe4615a9) +,S(9efe86ac,a6305eda,4b520e00,4dff6c56,1135e7ec,6953d2b4,a988d508,63046c38,4f92a291,32cb0818,af7cbe67,ec3b4d8a,7afa4f79,91a9ae42,551ad831,aae9af70) +,S(82ea48a0,ff76fa17,374bf4c3,d0918e6a,df26cafa,33d87284,13aa2dcb,d813f254,6a029539,9bb555aa,39de1ca1,417a8950,49b4c2d6,26ddf8e4,a7086b1d,bf2ac9f2) +,S(c289483e,817bb06c,31352a24,ba60adfb,e3af2feb,de329f4f,5fbde755,bdd2baaa,3b7ee90d,8b4aecef,62b6854a,1feb595f,9c49945e,c19685c0,4b13a1ce,1c780a53) +,S(6bde46cb,b5580d58,ea68deb3,1b0587b6,1698660,d78a8300,1c740b4,96e12cc4,3188a6a7,c1cd166a,4894ce75,c79d076,a41cc5c,d142ed91,e096eb32,e9293292) +,S(d1d2a3ae,2844615e,57f0a11d,66fd7571,176738f,a066cbdf,4519ac1f,65827cf4,7c0cfff7,c01c196,8b7697d7,c51562eb,8271f936,5c7daee7,f963122,67f603db) +,S(b74c0c87,4d195557,3b551c85,2abf9a5c,e276b088,cfaa0be8,f6515ed7,ba27370a,f0cb0e,380c571e,fe5e307b,ec4ed8c2,6f0c325e,114d71b5,51e0f1f7,45a662ab) +,S(a9a71b9a,9f126c3f,a17c3041,2317e118,84950077,baee298f,47d42609,f9015874,c05f3ffd,b31bf0cb,7fa4be1d,f634cecf,f1b1137f,551220f0,8f34c2a6,a42e0586) +,S(d6de1153,a161f27,ddb51416,2b3f823b,2b1b99fa,3fa21c25,9b02274a,80dbc68c,6c620863,659785a5,eec15d25,9acbdefc,714fab61,4e766215,348c80bd,bc59764a) +,S(dcaa1dbc,3acdca5c,51f8c22f,359487fa,73a7dc36,2a796df,11292a74,776b73f1,dc4131fc,c22c607b,4833719b,1715179,b4b4d49a,958c7514,7c8c4a8f,cc85159) +,S(135537a0,c4be13,1c3aa93c,677094d5,5f3a1300,95499d21,2206a244,5ab6c,7ef69f1f,d2d3df67,335f0d1d,dd52370b,8f3ebcf,e3483330,48c2f045,64fb0f69) +,S(28f1d817,c23262e6,4cd572bb,e3fd99ae,751dd6e5,5e9e804a,fb3fe9d8,39de93ac,24f5861,987e3da4,2dae0e89,67c835ac,8f5dfe8b,d41e5cb0,97029b48,39e2cb7e) +,S(f7c4ef83,6e8fb7fb,8eb31155,c08102df,e0779b87,9ad641e2,5f8ce135,44294289,7f9a781,db339621,d6150f09,16eb9682,16470d23,6957a0d1,3629964f,1f6bce2c) +,S(f1f5ae5e,1ddc9b35,18b66f7e,25a735d4,ddc8d018,5112faed,a8da8f66,1a28b3e6,9dbff12c,97924d80,50a4a8df,24fe7a8f,5c5c3486,3edb7cb4,1c6d9ddf,b9ad4288) +,S(95f83173,d170ce9c,1ca0dbc7,4578b639,257c10a1,eb65827d,c2afbd73,8b654f,63a83ebc,8294a88,413c3c91,c6918a31,7d5ab83b,7bee35b8,b75d1cbc,3412487) +,S(f4ada65c,9f095e11,eb88c8e3,77d60553,96474935,91be3a7d,f8c83c09,6a3ff750,e7683f28,a38545b2,e6cbc87c,3dbcc4a5,2ede1676,1b0dd78d,3ac51a5c,ad861ed3) +,S(41afac96,f714db3b,1b7bcd59,1dc7bc24,40b82756,d9394fd0,3afe7ae4,299e5fd2,9c2e9c6a,3292ff12,426e98ae,ac654a44,61c52d00,5da7af20,474e9a47,499fedc) +,S(37f30b1b,2cb81c9b,61941fe9,cca35f0d,e1b8dffd,c42f3ffd,ccaa16e,e8487405,92bf7a85,e3401d51,d9fdd08e,1086b649,8086bb3c,a4c9a2bb,61b1d54d,8cb88a0f) +,S(2f577166,646e7eaa,21531202,2ce0c8eb,605a2199,454c205b,9d760716,584fb3ce,f0d7326f,e43dcead,5ae0dc68,4d04b969,af32e8da,ed624ee0,98567dff,3d5f446) +,S(8abbc780,92c5512b,5eba0af9,4affdbf8,3c2e24ff,bf9fe7d,fd57e5ba,64b5150a,58f5998f,c2ec19a,a495b974,ffeccf6d,bb87dec,49152327,91a167d7,f6896b75) +,S(e41ace8f,a01376b3,27c73fe4,7e57cfc,f6da7cf5,c2810aed,219dd065,c147571c,b590aada,3c2a714c,322d0459,272f98e5,715d4545,196127a3,7d8a94bf,776844a2) +,S(300c9877,8b6355ee,ddd80f7f,4124789d,7c0c84fc,9d9ebb5a,be714cd9,890f1d88,dac2ba62,c5718731,c8f5c7a,4e1a7b80,68c5076c,834dd385,20f5e93b,e39c9002) +,S(69e339d2,19d40f84,25a072c1,f7876c3f,dcdb6623,26ca1b5c,87681707,12e24c61,8d439150,59a44700,2157e849,9b535921,4cd47280,937405a1,bad0b86d,38babc50) +,S(e56493df,8e47a99f,8ab3ccf6,41fab7b4,cddd779f,51fc746d,a2fdd484,cbbdb909,68dba20a,559e14fe,d0806036,d41c18b5,9745319d,758c1145,b6e49ca3,e3f5ee59) +,S(37a91c57,8998511c,d39c11e5,86e00eb0,f76532de,574d9c61,1a34d38d,e7f50587,e3a188af,d2d8a24,735975dc,9da895,feac2710,ab9d381e,e5d1dc43,b3145f18) +,S(c5f059fb,5cc262e1,12c629c7,194d783a,6224016f,65e4d24a,86c52742,dee88c1f,1c85bf52,1a96a95a,5177792d,590b46d5,8c090705,1efa0623,ab15578f,b38c890a) +,S(566edecc,d605ceb1,a298c59d,78401acf,c6323c63,f2845827,62678924,9b8716a1,ee0d1373,5adf6f20,789f85b9,32d332ff,8c40b3af,c02010a1,5ad062d4,5a44cc90) +,S(327e7033,c6ef4f87,52e33d,bccb4642,3e6cf4e2,c3ebb4c8,db69ccde,db2c7c7b,fc49092b,2be0f29b,4aa3e266,709aeb1c,12266239,f7bd9263,4aae16e9,53e8db36) +,S(989a7f69,3ac0ac86,55f29704,ea6caff6,84ef5ae2,8c5f5e1a,1eae7009,97778024,573d127b,3396458e,74bb5bd4,4acfea64,e8eb1fd7,3b0b292b,d1b7b642,80dadfd0) +,S(9ca7672f,14f27f54,ed1cec4b,74f49a57,7ce313fa,4a665976,9c22cc61,b30fc94,f920c4d7,31d52a4a,30803f81,82df8d30,6ab14104,eeec11dc,d2d6ca0f,3904e4a1) +,S(db100645,654fe8e1,95831687,17e2721a,6097850,ed2ef0cd,e1d5555e,7847f5f5,2b2c3ece,a9c90ecf,34fcdf89,5f76c8b6,619287ce,e745014c,96281928,31056567) +,S(4e2a0c9e,82743b42,5e6110a8,f3bff14e,418a34fa,65269c07,bb94d00c,d53295a9,512ac2e3,e00bb04b,6b4b9059,a3ac69c,8a34e5ec,8dfa14b3,d98b2c4e,3cccca7a) +,S(c12b3f70,24ea8acb,5136f98,185fb1cc,60c71a77,2943b68d,7334352f,66ac77f6,b799f99b,6f4b76f0,1f09f5a7,bfbe2526,d67a195,83327323,9c07bddf,2544803) +,S(64e5a2e,daf34e1d,ebd7c0cf,616413ff,d6c09b82,bfa783fe,aa755464,8ffd7e58,e020e09,66f032e2,e905d611,adf0926e,7509a2a4,b51844ff,72651f34,3c2f4a50) +,S(2b0b8b55,fa734380,f6ad1857,e03f02dd,3d66ec57,2cfb3b9f,ef040895,3f0a838a,ac897251,a9146597,8e0b45ba,e1c880a4,147ce01c,3408e476,5bd9013d,9e73a61a) +,S(ae0e3d30,a2026133,d3a54529,965a9679,6523e8b4,1efd4c5b,d6778930,2a88525e,fb6918ff,85632d24,250be67b,339ab260,c80c087d,da1efee9,7ec5dfb5,38f80552) +,S(2ff9c711,4dfea166,ffae46cb,1f44c3,3bfa1530,edf23454,a83de862,8fe00dd9,53f667a,4441817,a3e38351,78195c5d,acb0d707,bd20e759,9b5e82c4,6f318783) +,S(cc027014,88b959c6,c043f60c,c42b1449,9e2614e4,c19f5726,3edb116a,4e7bf695,eab3f590,9b22f677,666ce655,149a5f07,7b5325c,2036dfe2,e572e64a,5bb6007a) +,S(1801efd1,3c8035a6,5efe3b47,68495d27,f9dbf45a,f019d455,84d68be8,28a945d5,dff2d19e,fcb5968e,f4ef49d5,9a82f8b,f44a5abc,e0b68568,1acbda1b,fa59c4fe) +,S(6da2a9d5,7b60962,357c09de,4c7ababd,5b698fe3,6e747f8b,e6ab78fc,3cdd7cbf,1e274e70,4aeb8ae2,295ac9f9,b37c0af1,71310b82,99acc378,d505bdcc,e275060c) +,S(7e8fc96f,6a9215dd,3bf9e8a6,ea944ff0,c7dfe23a,1a99f44c,832a11ad,bafc82e4,e9a4fbe1,e0c26ca7,f739ed00,c63f3886,57d09503,a808ed51,ddc872e3,b1342bff) +,S(a6362f3a,77d6d6f7,fe266ab3,78707641,9f53e133,718ccf27,559bb448,7e0caf64,c01622da,3fc2385c,60a5cd86,66f751b,e29d8539,f473cd70,8784d61,d2cc787e) +,S(51865222,28b47493,a3da19b4,7076c1a9,8582bd55,37c25557,44970075,9b37d2b3,f0f0b979,68638d9d,93fca65b,f40cb8ce,826558b8,52451ad1,7d0afbd0,44287be1) +,S(a2a0909b,a9f1b9c3,8c714ff4,f71995ab,4d80212,9e8ee8e6,7e8bc3d1,81d472ce,4123900b,d45ec7bf,71bfdf98,ec453392,8b364d1e,cd925a6a,1e8f5c5e,ec40068d) +,S(da518122,454e7f36,a63f5ac2,a1bf979e,f1357bea,f9f0c921,2b031f87,b83aef2d,bf877efd,d415e80,c828c5e,1b9dd8b9,6cb7f3f8,b9a0cb32,b6bd8f37,686da722) +,S(41c40c54,1a983125,e59aa572,910c5aa4,8a698306,d483f82e,6cbd7506,3947a87d,76dabb65,6b89910a,bba9f129,ffbdf5e7,ef840033,c30f4c81,4e86f101,a3bfc57f) +,S(c49fde83,87f2e464,6847c980,acc50d88,28745e4c,88a41318,709099cc,9aaddbfd,a65bc512,dfd07bd3,79cbaf9e,628be7f8,c7ddb4ee,6611fa94,bbb48c7e,ae7227e1) +,S(85b17d61,b6ee743d,4df21940,6d7b7426,3a6c6b88,e8c51071,7a1f0183,e0fceae,22b9e8a2,74c71feb,5046ce02,2f4bffbb,ebddc53e,704f6be8,92d3092e,55868fef) +,S(c8e1d37f,e6d677f1,3e752189,505639ee,3914afc2,c8d4e43e,883f5c54,f117964f,b0cacd18,d08f5a91,af46ba55,91f99497,ee4a7ab4,36ab48e4,f88ad5ab,39bfc21e) +,S(dfec0030,7d25888c,5a7d6f83,33112995,1a30baa0,b97add9,866078a7,e483836b,4e5a8a06,bf2e9447,ef466416,82af8e44,f407ca0b,6fb97809,56e13a90,bafaa00d) +,S(eac6c438,7c18d8c6,eed7618d,c9d3076e,c842ff6e,5f4d4b20,92594d7f,7f0be9d6,19d69bbf,fc0c1b82,ba71802a,c0feebbd,77a86a67,d734a163,4e823a6b,2265b8d1) +,S(9ff38c4e,4dcddec,a4824db7,97f6ac80,69432c15,9cbc99b7,4d642011,b3424cde,f72fa660,b7c1bbfe,df45b0c9,3cc84b81,266bd041,b94f54f9,1d26221b,51619ebc) +,S(5e78593f,3a5a3293,5f9e4f8c,4fe28555,9153f69d,d44b2c1c,146fc644,a5313f36,9d9d5844,dc63bdd1,b2d95b70,5d63c97,58cbc5a6,1b2d114b,89da9b9a,8afd9c47) +,S(a107c7a4,89284b6f,b01ba38b,3e221c2,ad31a48,77af9b32,d22c8544,71009ae4,66072d4,6be46591,ee386cd5,bc0f9f2b,653b580b,c515d4c4,a0fc369a,27d9f6b5) +,S(241f1d0,308d9845,fe2445ba,67929976,ff98e88e,cc23a8f4,190ce5fa,41b02af1,886697ec,d413a88d,fa15723a,daf91d32,9c881ee,c5ac9c74,366b7ea8,a7e194a9) +,S(319ee8d2,627f906e,83d5c6d2,6eac3b42,34186016,8b9a9283,c8790c6b,e48a72fa,59e496ed,a67816e0,3409f849,1cb458c5,76034453,65fb281,9d0cc427,3e9eaa57) +,S(1866811a,fdf9bd,937f4f7e,96985759,e0100866,192878e1,a2614625,bfca4822,215e0465,e85f9c88,2783a131,6b65fa7c,585f0319,1a642501,72e51269,d5b7ae19) +,S(7effbed7,b949000,5db429fb,8cf64099,3989675a,f7394ce6,9ff2f769,53992f26,6efbb5ba,28f26d4b,5256affa,cbf2dc0b,616d8b6a,c6cd2aa7,a1d09ac8,40c7c749) +,S(d8c72bd0,e59315f2,1fee45c1,937952b2,665c8d66,70f14bf0,957a4d25,2b168867,64c02d62,fdd40a6f,d11e2cc3,a73fc60a,8a2da31b,2c99ae6e,5a946c61,be56fbcd) +,S(710ec622,ce64f381,43b96bbc,b0b0d691,87bbfd51,fab4d47a,bcf18308,18d0db4b,edfd1086,526c3af0,c2e9b961,890f531d,3d275c36,beabb0c5,4963314e,4534d994) +,S(9427964b,9aeaedd4,9c168e76,38086ddb,70574f27,9e4c3348,68e4c595,30d51ca6,110b41cf,2a6b0067,eb3b312e,928583d9,e0026bea,684c57af,7300a611,5c4e2dd8) +,S(aef79435,a8b3ed9c,9eb515c0,6db62165,c5a2e816,5eaa4a5c,46a59b39,8f55565f,6616e8f2,1274c425,c50cb93d,8942aab3,3653511,3c3552a0,118b17a4,5584b91d) +,S(3ebdd832,3546063a,68f40193,59d72f26,f49f0ce,4a5af994,a4ac67f3,3074b5a3,12367d4,b29549ee,d0eba318,f395d712,db7962f2,c8e2d9be,ed895006,78460238) +,S(a38d9e5e,c52b0871,d0bc6bc3,b673c848,19af86e2,534d60dd,729b405e,426aeff2,ebe46771,d9ae6c5d,13895538,3c8de4d5,f6d13428,8ac36a1c,b01c75e9,f32cad02) +,S(e7d29f82,619cbb19,90c407f7,b452cb8e,334369a1,16901b0f,9f4ec342,48a7d624,7595ced4,618b5160,6b8ce230,45d7616f,15b6ce14,aa8eee07,42bec5b5,9fc4e614) +,S(ec869eb0,279227b9,4ae333e2,6018f00c,7523de5c,e3e8c4ed,f81cefcf,4043ceae,a421aa55,2c89c841,a48bdd26,4e67d82b,ca3fe577,64101556,ec6ba7dc,711ac92b) +,S(4549d908,e44a8c8b,6fc5c057,144a352a,6f07523c,e026fae7,c070ff35,c6ec5e71,71d8e320,7707e04,10208c19,e2c8dc79,64b48600,1a6d640f,44c1138b,7ab5dd7a) +,S(51bb6e9e,fef7b8c9,b0a4f381,3e1406b3,2cc7a53d,165b385f,f98144b0,a5b070b2,65282be9,dd794fd0,8a31de11,d46df7cd,5268eedc,aadf3bef,de5956b5,a467044e) +,S(7cdc3297,4c7caa82,44203afc,d48e625e,aa2027d4,d91613e4,5a83eba0,696d001f,b92b9943,3b1a55b3,b78027a7,a289e5a2,6060a411,6c2cca36,19253490,83519565) +,S(3ca9c6be,b8e989b6,a67722f6,d817a6be,aa478fba,10146fc9,3099575,609c9314,5502ed7f,f4b81bc3,8386bba3,4124ca30,74c6e0da,bd148e4d,6bb7f096,ceca2c0f) +,S(aa2abe6c,45edcada,f01bc1c8,38ed5e63,90e1a229,cc920436,864111e8,ad354d0c,1b8229c6,6f91304a,24c61251,f1ba2b26,95bb3da8,87154d47,c44dc9f2,f824f6cd) +,S(b52cae3d,f28c9d59,319f226d,ef73b60f,75466aad,fbe6f75a,2ab6936d,8e3bc7ee,ebee735e,22c091d,cc873848,8a7c958a,421e0759,2e17fa3a,4462db88,8bcfe220) +,S(c1085703,62a6dcb6,13da6283,23496169,635469c3,47b65661,838d9053,3821ef54,fe6442c8,c1e6a8eb,2dc2cac1,40ad4c7c,44511cdd,82b79cde,c38cf9b3,4ceaf517) +,S(f09e9d1c,fcaf127f,59d45476,56422907,83477fcd,2fa6c768,d5a3965d,af08c11d,f01a722,1f44fb15,bf428fc9,c5d7efd9,a5b2e663,cfecc9a2,7e8f964e,8bc15d10) +,S(602462ef,1e473ebe,d88b3b17,9d71b597,fd3e805f,e03d341a,36c277f,495c4527,f91db461,71411dce,aaad9f23,53f2159e,fed2a9b1,eb9d2ce2,844e1f6d,63a079c3) +,S(273a881e,8e0d99fa,104ae355,8126a20d,6b828d13,96bbc70,720197fe,9bb582d,5bb26c58,14a7b914,cd3b2f72,7f76b6c0,d1b40775,79a2c3da,29534a1a,684b0d5d) +,S(7c1df346,616cb72,b42f4172,36fc98f9,e8cd0504,1da47d9f,566c8df2,e80cd54d,ad3e7e0d,d602b9be,45ba8d45,6bc12558,73153c2e,c16773b9,390ad630,4fc41dd7) +,S(796e2634,657ff114,7394551f,3ce800b7,9ad644b0,539786d3,c62c6551,3d942f94,b65bbe38,ed587111,c480eb9,c30081a4,1e8ec66a,8400db11,bb1cc7c2,a14f1c60) +,S(5e2761fa,9985f68a,a469953a,2a6642c8,62b0565b,602fc206,193bded6,1a302bd1,5ba09b70,9db24f5d,2f47c07,51367d0,3715c9da,b7d430b4,713dbac5,7253e274) +,S(46458c92,fd341a0f,eb1ab038,5a246b40,5c004c22,98db90e6,164126c5,4fabe794,859d68b,345341b8,58afc324,263f1ca6,9d018fae,eecf33ea,f02a3dd8,d7446725) +,S(fc481830,bf817c1c,ffc9ddc3,d6f4e624,a410e134,cbfb952c,5c7379a5,81153265,a188b228,bd3d7da1,44a48e89,fd9db4ab,8dfe385f,ace8e169,a43a2787,59322551) +,S(42d9767d,9771a550,3c702742,ce2aedbf,3a780466,804ad901,7792610d,5eed03e6,df69432e,9764f337,3a2c782b,e02d2433,d2e0f568,d0dd83ec,e89ea1c2,5ad50417) +,S(37122c49,993ab297,72e60222,615ed912,462deefd,d28e04dc,dc72f4e1,b9477148,627ff4f0,924cfbc3,aa0422cc,36402b8e,410b3ede,a552408e,f1d3820c,5996e39d) +,S(9c548182,94bafcbe,743e52cc,a76e1ead,3619a557,a5cb8bb7,3140ea1a,5c6896c3,5fcc472e,b88e8528,ec71dafb,f70504c2,ec0478b3,209494c5,b53bf05,b38f7fcc) +,S(7b9d7ad7,aa5b1f69,75c4e025,17123608,a59277f,d63f2a07,7ae69b80,f65a2db9,6cde1ee8,714aa229,d01c14d6,f514ecae,c4a7f15c,a756812f,abfd61fd,d7d1bf8) +,S(af5ddaf2,c985560a,d656d948,e41e082e,6990e950,6c77d53e,171cdea,58a9a102,e348451b,72896ff3,c4839ff7,6ce16b59,1f685348,eff943f5,fd4581f9,eca5b505) +,S(42667f18,e957bd19,5fab366,2e0d1565,d26394b4,14e2a9a3,95becb69,2111293d,288dd2b2,69e9bb63,4e7fb16c,1fe25797,3c0076b1,aecaa2a2,e57020d5,66bbc7a5) +,S(5e9c7a1d,50ab8326,74c2a5a6,f32665ce,9be97161,5e59b618,587541b7,40b276d7,92283461,1f39af42,34292c61,2c70744a,ec466418,ee08b5b1,a298456d,5fa11f17) +,S(98c60ffa,f486b582,2b4d9ac9,7b320b97,8b52b506,8b46bc48,9a2a4f28,dfed8b2a,a1c26113,c2534955,812f42fa,306edbe5,70416d84,aedc132b,5807b29b,745280f9) +,S(92bfa982,1ed52cd9,3c286e71,f350e5a7,f309481f,d866516c,f0a7599d,c385babc,a3fc9796,c71ab4b1,b7a54e73,8dfe24f7,6f527692,9516bcb8,2fae9ed,b2c1ddb4) +,S(9be27408,bd8eb59f,ace413e8,402b0c37,7b7798b9,3bb18c4,ec197382,fa5b865f,11085580,19646a39,68eed2c8,1bb92dde,def3ec29,5024c027,f54e8bfd,a67a2f61) +,S(27cd6a6c,b7bab059,6b791ce3,8c0918bf,7751bc59,db9e5827,5b1b9c46,976350bc,890d5167,8fce2ac5,f13761df,68651e7,2f41d04d,4feb4011,a16f80ee,83faeda8) +,S(e896e14d,aaf96139,4c8f6597,a0c66463,5f22be3c,96f30e1f,5d8881ce,f468f2eb,beb004b0,512c1ab1,dc4d971a,fd88baca,efea7e84,dadd2726,bb9f2b3,b196030b) +,S(24e2d269,ac485401,634b3779,efab2c0f,a9dd2389,850bb3da,54ec0d67,e53f8ec0,de702ec2,642bd4c2,3bca2ca,663a05a3,f5beda5b,e41fa460,8929aa58,219e525) +,S(97a627c9,48c1c9e4,5d50159b,4b121a50,9b5c4d01,de0a7db9,5a9d9c09,681d1676,19bd095b,55399c29,fcad4303,7f5d5c21,8d5f3cf9,a7c90b9f,fef7ee92,6f3203d9) +,S(a70d8251,e604ec5f,777234c7,f9d3c850,33ed6760,1fa0814b,40bd5370,7195b08f,df28d907,74e23de3,f152c016,ac710d43,85325a89,6a859f4e,e126d50,acbccc4f) +,S(2d676c43,4b276472,ce01a007,13d78b17,27743a97,36f3412e,a7c8c15a,fa42f42b,be28cde4,6ef5d32,403b8f94,1082b684,52fa703c,339498ea,24c08ff,c9fa7312) +,S(f66c25e1,75167275,5db857cf,cf27c036,46c89d29,b4a0d729,28fd42b4,b29cf5,3ee23ad4,22c4a884,4c049150,cd9c18ca,8d2a0231,bad69b6e,5926de9,c7193201) +,S(dba47c4b,9d39d87e,ef44f81d,24e8e005,ce6e77ad,8e4fdc6c,29393d7d,2427060,2d5c6492,e53d000f,977eedd,4dc3b5c5,5240f28b,9fcfb597,338edbbb,3d8d7622) +,S(a17601d9,4f627dc5,5895aeda,e91da3b6,94788f65,f083b01b,bfdf8815,27e10f0f,74089fc8,cfea1b15,afb025bd,99905b3a,baded5b,45e30890,fa3d8403,360a1183) +,S(dd70309f,b84afe90,7e261a12,5fb7ac8d,1c24c6c3,54eb83d5,188f3a13,4d80e141,32014ac0,ac93a77f,9d35b786,2c88ddde,4bdfd566,f6555868,2a836535,44bed563) +,S(79fd503d,e746baf9,701253f0,4c6a2f3,cadefb93,920c83f7,83b57768,87037afd,3c5cb658,63180931,3fa20c26,647a523e,86a4e600,8e8b17f,1e0d690d,eca61b93) +,S(d1aaf37d,77c7d63b,1f4eb896,16a29a4a,1e72658a,93560956,6b92c122,ba0ff6a0,e535b7ae,5cfbba07,2bdf0e0b,bf435bdc,c7cac39d,9d9ae32e,cfd13945,3ca93bec) +,S(68ff1b82,b351d94b,9b6b74fc,2cda4345,fe525d58,d6599644,5c752757,aad93c4f,abbb0ef1,c422ac08,d06194aa,c5d93bdd,9186e374,8518192b,79818f3a,b465a13c) +,S(22785c97,18063e5d,5db73bc,f4ca6487,14393ea2,62ece24a,5c41c059,9610552d,9c08026a,d7a7a80c,24c5e75c,8a75cd6e,1933e64a,25cb98c4,157181aa,ae1d8774) +,S(626cb5e7,563fb757,5f066258,3fc21762,e2678063,a77d8580,8891f244,4f5ffebf,8369ff6,72c3c3f2,43516184,5a9851c1,953a6da2,5662e11c,ce170cbc,668498b4) +,S(a99f0ef4,d6f46105,80ffa430,b88a4f28,61c8c4e4,b6fadac5,5e668f5a,80d12d2a,972adf29,39db0083,77802c40,6ae2aef6,4e2f064a,f8304d3e,28fff33e,b1053d06) +,S(b243ce27,2ff0b2db,cb80a3fb,dfbe94ab,784afe3c,cab3fe61,1931de9,c7f02645,db2ead19,fbb8c820,c7233df8,fea51836,3e85b858,4622be9f,41a0448e,360b7559) +,S(c74e3c9d,685cb62c,6a71b21a,a1dff5,43efb264,543222f3,f8bdf570,4363deb3,987d8261,fbf23d05,a38358ef,c4efb61a,5cd550b6,1e833ed4,38734486,edc4b2ec) +,S(ff2f64a7,fc984d4b,d1c885f3,4c096e9d,d34710c2,43dc3047,8886ef0d,ddf71c47,14c06258,fd5e2fdf,1eec9125,7690c0d7,9eac60d,785f2497,65e1a85a,a06e906d) +,S(7d92c4e1,3f4cab24,d36e8a8b,140f743a,6819b514,f6a19bad,ec162141,bb712085,606b5762,2ec7d7d2,a9b19330,9da686b8,3e0dc920,e6be33d1,b726f416,81b698c8) +,S(3a43d4d,9ef45289,89c9487c,77951602,4ce0cc20,ffbcd518,a0bd2546,fe13b6c,5f24d325,5768905e,6ba28d61,e6b126a8,eedad2a1,53499912,dfba3fc0,d9deb36e) +,S(8e72f02,80105e4d,15cc67e7,371d0c5e,6e59fd05,b3c66308,67342a6c,eea25f8f,94ddc51,58fdb86d,f09870da,47b79b03,1eada5ad,9bbdd509,9ea1d9de,96b368e) +,S(b89cfc23,6dc02762,ca77f9d1,8343f12e,ab8789b0,e5872d6b,fd9d013c,ccef54dd,9c9a7285,45a5996b,4a6ce6f9,df860d11,c3ad135c,f1f7437d,2ba7b904,411141cd) +,S(e85ee008,979868b4,bb190b53,5624b3b5,6744a43e,2c473ebb,c64e4910,41ccb59b,d3afe70f,9edec50c,227e3b3d,7eddd1d,e1c9a8b,f842d723,a8075a52,12cbd6a2) +,S(d8dd6bf2,774d6d15,93cc8e16,d5134066,f7f90651,39915b3b,fb0d5d93,b6cb97b5,5a203094,5f734f3f,11431862,b85e9f8b,25f7e6d1,91512b2c,6d256f4a,535e26f4) +,S(77e081c5,328fbdeb,45fbd554,5d133d84,33968ef,98d36aec,3e6385a2,76aa94e8,2ce853f7,ca25f2f8,45a6291a,3e080504,ba597fb7,91a21669,c0cb6be1,14c2959a) +,S(510786ea,e8a49682,6820b82f,549f07a2,b5b9203d,b1ad18c4,fb9c479f,67c904ab,dc130385,4e4dc69f,f63e21ae,71dc8674,b39382c1,eab1d8a8,fbd96867,af9cd96b) +,S(2fbafeb3,fbdad5b6,4c121056,e080d0c2,1169e433,3abc0dda,bb642789,a242639d,a85d82f,d9e6a14d,e599ef0a,11d3eb39,5ff199c9,5ea5f1c9,2f3f8a7c,14405cd3) +,S(200dbfeb,6e6e463c,1f3fbbc2,6b5f00c6,aec80809,1e28eae6,73b2b5e4,7b12ae0a,4852a219,bdaa3d97,83e1f071,15491827,83212776,fcd1b44a,c59dc01c,bba95ecf) +,S(27b140f6,259f7dc,93d46b6,e52cdb85,3ec22572,54218ab4,1acff2be,24b8a3d9,3ceed09f,70cbadba,d40054c4,f130e312,28bb5d63,71a74f7b,c85aa7ff,c0583387) +,S(fe4941ee,535c5311,8222ec35,14c2b02c,e175cca,d728ca0f,cd1d64ab,e95b7e71,e9cdc9ae,286d651b,d89cb442,2a64ada3,748e0ade,585cb70e,d357004e,e51f56f6) +,S(317d209b,4cae94bd,36f443d7,65be2f17,ce47ced,59935d88,5a03925e,75ff1cdf,c191495,68fe571c,ff945af,4b6a801e,c942a5df,78a62864,5434a5eb,8a262d72) +,S(f951a777,764e30e4,7705f8ab,150e9ab,df32e80b,593cecea,d9f9a143,cc93f9ea,efb951d6,25f2223e,e6ccc6b8,b12cddde,6ac2613b,11ae3052,65570f15,23afd925) +,S(71adf0eb,f5fd8e8b,f0f229a9,ffe496aa,4f251af6,6e5a284d,3091f344,3389c8ef,13f47463,293a5536,674dfdf7,2dc73add,98ed5672,e7676425,39ce655f,6b6969f4) +,S(2ea0406,58c0e80d,499cff39,ad463412,c3fbab1e,81f6eea5,911c45,236be75,be52c74,6073721,f09743d2,9a0a4e3,d82c08ed,feee2234,29163bc8,954f923f) +,S(42352390,4b3e80c2,750c4222,33f0b1f3,a373442d,96278935,d9b7e51,b6182aea,7f582349,b27b5166,30c8e48b,a9603224,fe09e8f,814fa966,395fed67,d9221d91) +,S(524d3c82,a92b285b,96064bf8,e9abe0b5,7702a29e,dc08ce53,771fab9e,fa7dda91,a47a0217,fdc6b2dc,d4b68e05,331bfd5c,366a8477,d3ed894,ec747240,f0f29c3a) +,S(f6ee1e08,5ce04de6,6aaeb5f5,f232329c,fc83caf,d16bcc48,776bae16,c056f7e8,3328b26a,7e2bd49a,aa193977,4947d7b4,ccbc955d,18b27c75,c2f6ac6d,bccea4d9) +,S(9c2f7d2b,b88f1417,722b5d11,95077d20,2ea84e6f,9bd93dae,3134d16b,17273978,1089f003,66c8b435,ce73c592,7c5e56bd,d338a4ca,ee5307da,a571be3c,2dab2a3a) +,S(593a1eb6,730fb6e5,1fd24f15,253ae1e7,5897b7b,48efe28f,9b9813c6,ca99cc3c,fcfb7820,fbd22d91,bc03a630,f74e519,9e35c1a,a3b1cace,40433001,7744f079) +,S(62ba10c3,83a7bacc,bcc4bc60,37f87a5e,8ec0eaff,de5a39f4,ef352b1,51f957e3,c267a1b0,dc84a161,a565fa19,aa0a2501,9fd01e0e,d7a660be,c2a7e9fc,cc7bdd45) +,S(1de2ac10,deae62a1,63f641fe,3a4a9da,39e12390,14a77c6a,6d73c619,5f731f64,60f43c95,b6d7969d,427b5ad,782214fc,a512b75f,a6f50006,d7141a89,dbc8d2b2) +,S(f11a5552,709083c8,83d08612,31772f18,c48e9271,6acbaa6d,a43416c2,fd4e1d3,a6d0ad64,7cf48c41,b6ce397b,38d5b3b0,2be51554,da2f3f4c,df593514,a2d742f4) +,S(f4454640,d75697e5,21d5cc01,fca5c7f5,3dbad43f,116c243d,2aeae96d,7cdc33fc,42972cef,46fe7704,5d6d7053,1a74ec87,6b25996b,c4cf66cf,b3784f79,66549102) +,S(2bfaf073,97be067c,1b7c20fa,3b319fad,10905b8d,8ecdad4,cad2ec8d,a1b8780a,ed526499,ea97c967,3d28bdee,9970f4fb,9077deb1,5f823cd5,775cc526,4e590285) +,S(fc1abc81,2b5fed90,bde3ca16,3422f73a,6df6e058,8ed69222,cfec54f7,4cf5f73b,db1c6edb,471cfcbe,468481dc,4b1cd1c4,7ac68f6f,4fe9dd8f,af0d1136,972b975f) +,S(d838c2ac,82e02f9b,a376f92d,293c02ad,b717d65f,be31cc76,12476e6f,4c506a8d,d87a3067,388f8e0,3c176f6c,a7eab123,532dd1cb,3e0f6ae2,51d7b31a,35189377) +,S(4b3a82ff,7295749,a259d54c,a9a5e539,32c53ff1,33a1c4b9,2f697e06,b13ee38c,44372b41,a788456d,3f66a0c4,6c815210,bf60734b,e570a290,32db3075,ba8d6265) +,S(d77cbbf3,6731ad4e,325eaf6a,9bd52f70,8e79d290,e379c2f2,b8d6ad3,fce411aa,ee466d25,f07813c7,91a81237,748bda9a,51f4266,4a385b50,5259bf84,ff8372f0) +,S(3867f6b2,58920b82,6eca75dc,953ac307,bed1872c,c0f1c6ec,84efc6d2,eeea1483,cc6a6adc,e6078097,a013ff18,dca9c5c9,254d70f4,68ac1cf4,b8267135,af88aee3) +,S(7b008875,e85fc84f,618ea7df,f20f7f17,2123fe98,c07b5279,930b52ef,cc1b0a9a,3f3b30bb,8dbc9169,a5c55a1c,4150772e,331f7834,b50bb904,a8c56600,bf075f90) +,S(ba5b44d9,16304a49,87579560,4d4b796,907e9b7a,4da49a5,ba7a1d77,8e34ef3a,16b49baa,48219e3b,9bae124f,dcd4de,4d47ea76,3ed39e13,f874c75b,cf333661) +,S(691eafe2,7fe4120d,852b3a23,b5bfa646,910fe521,355a3594,342d629c,e2b8d9df,43a06097,42184dca,7c294fd6,a5227dbd,bd71ea1d,c4bca878,1887f9f8,b6c71d85) +,S(13a6cbb,c9f5a86f,35173e38,a45dca65,551377d7,c37542d8,44006e48,54a54123,ecf3809c,9a964d9e,ffdcc2e6,2e8faf9e,8a43d38f,3023c4b8,84d18948,8488620) +,S(33fd2af3,fb595cd2,93d731e9,1b4f0e5a,da665420,2dcc36ce,b712e8d5,e6f10e45,e26a307a,a8bdda4,4b981bf9,808cfa3a,80ca5331,b3a94c31,f6331e60,98ed2cf) +,S(75954033,59e47f78,76b3ba57,5a758493,b0033298,22f4e44c,15cbe58b,34b774f6,7ee9a040,70b8568d,b0a99855,3442c000,b6e6651c,a7ad1253,f8e703de,5e0458a9) +,S(79199fb0,c3b17e68,4e815e7e,8414bef4,b3dd3665,10d032f3,6505da59,6f5b9480,95bca973,f358c9cf,ef3aacba,54a055b8,abaab383,4191a1b5,54ac3ee,53d9a0ab) +,S(9705f4e7,962ece0b,2e7ed64e,a33fd40,6edd0bc1,ac8997b5,d6d70000,a51aa352,4d4ce757,ad4547a8,a126193d,8921d6d8,58f40855,f71ab99d,b2bdd728,499ff347) +,S(881af067,b841ab5f,30560b98,3376674d,cadeeb75,b8b16e12,df7da3ce,312fd777,ccc13fd4,512ef05d,7c10f62d,8b144b1d,7588be3d,1a3a3701,9accdec9,3483b84f) +,S(fe8f7a44,33c2c9d8,f42e14cd,97ad0794,41bfc3b7,2fd412fb,1f6d5f5c,10e99621,e5b576ee,cf34374,96dc4ee3,a846c79b,4c8babf3,cc46a657,2a93fdd4,b6b3b2a9) +,S(ff43c8da,18e08b38,3f92f832,3c34e83,84f40064,9e0506cb,91893abc,5c4d798f,a575a059,23a9da02,c0c9dde1,981dbd86,f5a75433,a4bb2fd5,2427db01,7ddf2e7f) +,S(4715056,b97f4e21,13485242,74bb1b33,d8f9d841,73678a42,ed3c6fd5,28db276b,b4c0d146,3521f1d9,fe8cd71e,fb98aa28,73a18bee,66fae12f,cabfa201,854302b2) +,S(85c9d808,c5f51d5a,c2a51394,cb83e7ee,acd85eeb,31a88814,9744871c,271fff51,2a7c3bf,23829b88,66991454,d6ec7f5e,185050d,1982deb8,b4992bbe,5b666a7d) +,S(c02b94ef,8b1e368e,3cb4b25,903445cf,f46b60c7,6d6d2f24,529997f9,7d70dac9,bbb97d29,bcff81e4,8d417825,ade1d28b,10fadba2,acf961d6,80a343c1,e725f3a0) +,S(4b1593bd,28e26f7e,431ac439,3d353a1e,fcb8b63,fee7adb3,e29472a8,38241df6,8a67a728,f4966855,26225b11,3ac9d858,3f184f8b,3ccc8ef0,d6e4e34e,f2fdcc56) +,S(f640755b,ba51dee3,ad650555,9d52869b,7a8e7f6e,4b9dcdd2,31d1cd4f,26a64dd4,7387f800,a53e290b,d4c29f6e,ec24ac07,91e0e3c8,55d14882,a48d0539,6e87e1c8) +,S(949346a9,436836c6,3df6f42c,d708cef8,16d0a522,914a606e,2276979,7789515b,a903932d,952a0201,ef65c847,b8754174,31dd41d3,ede5c073,31383b9,a8e2b356) +,S(1824099e,c769edfc,2390b1f6,698c22f2,cdcc9783,c5cbe45c,de46008a,67f91a60,f8405fa,81e04dd5,6ce051f3,bfa088e2,804a8780,37892ae0,adf42767,311bd1e2) +,S(e6b46fd8,e4633d92,8805f34c,ce95f3dc,683aa792,139c62f9,2ec8acd1,d601d341,533db813,f3fea63a,528faf4a,7cbf58d8,d6c0bea4,c28391d1,6391d300,cc1d824a) +,S(63799b30,dc19b18d,d48d150d,3d4139d3,a04c6252,f176015d,60a436cf,ff992b93,26205112,5ebf4dee,d00e72f5,ff064178,7f485cb,2ba35507,3c3cdb0d,16dcc41b) +,S(8cd02f5a,b1d5a02d,e85b88d3,ae370b0f,7fac5324,9f1fd676,670a29f1,2ead7338,358b42ac,ceb689d6,612cb70f,bc9bba7,511d56ee,c4390627,8e2f0961,bcc0d8e4) +,S(d5e167e6,d48bd1dd,e95aba41,bf33b065,f7612766,4a0a8991,d3ea1a9e,ddf82fab,6cc23982,d653cdf4,fc4ec9cb,3cd86ae2,aaf45f62,38257d70,849c2686,ae71d1f7) +,S(c4073500,6987f2df,1334f09d,97f00c19,d72b1942,5864b0cf,4ff19dcf,7c9bfdba,f6566846,6b461326,a9b366bf,30378f82,b760ff0a,ca568ca8,2bf0c9d3,ff7ff262) +,S(9df1e71,9c501bfb,8a21db2,a838318e,29a7c2c0,fb2deb91,1840c7aa,f0c4fde2,cd628cae,6d0e0c02,b0315ae5,4901e703,e977c75b,43defea5,80a5325c,fad00fc0) +,S(95176429,df73c309,23108ee,6922c597,1c91c249,ad7165b,7d08b84d,2a4c696c,3ecffc49,3b62dbcc,82208470,375c929,1994fbb7,240740cb,dd8086cb,e9c0fbe4) +,S(708c48e8,692b0d35,e13a7e0e,94be8fb6,f57fe187,34f5556d,a318f600,c5628c6e,9534e302,deee1d1f,27e0432e,9f6a2f00,5af7e601,3f7da9bf,e1cde320,a105a664) +,S(2775e17a,b82dc739,b5d62079,4b26be15,46275ec0,9d32622b,2991cca1,4e5b4c09,3aa6ee7c,80e8359f,deeb52c2,8da1328f,338ab228,8744d52e,8a9b7908,1b1ccddc) +,S(47c1aac2,39c4f31,cf334959,b8fb48a0,44da6b34,3c383270,be19229c,30192da,5dad651c,5ba6c21d,845cd402,59a051c4,e5813f5a,21228355,1fde158b,600d7cc0) +,S(f80f445a,4b864c96,1bb2bf5,9cfa25f1,eef459d4,fa28ac70,d77daa1b,b8bad15e,a383de04,6b8c6996,6d0b9da6,ce9f88e5,83cd57f4,a5f12c88,63f7ff70,b374ff16) +,S(2924e7b9,1ad33619,a8df436d,578b7172,b2208125,9f2d5bf6,f9cb903e,bd4d2f66,b8642169,e2319f54,348e4f3f,e15d1f06,afa41255,ad62ceff,a768bdb8,48841875) +,S(37d6087b,91a64ed2,8341854e,3a2b9ac4,4310785e,77e32e2a,f13405f3,76dc4d83,35a23917,e068bccb,a823092f,32e6fcdd,a3ac9f09,2c251b1f,9bdb9971,3df25003) +,S(d748a96d,c79f1be0,6b43691c,bcf84b4f,e000d2ce,8294cfd8,391dcb92,10f4fab2,75b4ade0,65da902e,ce57e5c0,4b817228,975c0927,aafb76c8,223c4da6,f05bf51c) +,S(d05d2a25,eb5084ff,262361ea,33b6fb97,9492414e,c255fa8f,a0233d06,e42cc30c,14bbbeee,cecdc8f3,85b51429,8aa03d9,ba57a198,5ba98f4e,75efab60,69a6f2d2) +,S(69ba995b,d137edbe,5aff3906,764eca9c,b4684bf5,e8a8c302,78c89d97,483ff793,2b1cf451,b6226596,9833e864,91c5db95,a79ad96c,701580b2,46de1936,5bb63e32) +,S(7f01e9a1,5d0ecf28,fde0342f,f506104b,3a50aff2,f1ec997d,9a82ff71,54419461,1c3c9594,a6b8d375,361e25d1,fedcab63,d2704065,a83470e5,e03dcc43,ad12dc68) +,S(719232fd,193b9041,fd201bc4,7184e4cc,f2413d03,f0f8619d,813a409e,56e48cc6,161fc718,7dccb053,5337ff60,9eae05ab,12fb55a0,65f82d1e,68b19d3c,ae29a953) +,S(15b84120,155f7310,3386009a,57bd28bf,9a63bcfa,46c8bd08,2f53dc86,76e78c27,47dd637e,c9017e2f,e9804e0c,840aca4f,188171a0,ea9fb605,1402c503,31737816) +,S(ff429d97,bd380047,7db52ed4,eba69914,4a95ce2,7414da2c,74c074,bbfec567,7b3a6fbd,6e635bab,34973f62,4df77c03,6708c00a,cbcb8f25,69a5aa01,d57b3048) +,S(ccd705b,16be74c,cf1f476d,12c77e81,37917404,b2611ed8,858b1e55,d50a6ee3,8741ade7,5cc7b252,4dd55e17,897f78d6,946cb4c,31ad9f1f,737affc3,40e87c01) +,S(65b61a5e,24b3c57f,91678e81,8300ecaa,94e4b406,8d499534,d54c37d5,bb65b27,90d75e28,aab97b82,f1b86fda,2ae0851e,f65ac4c7,a5c664fd,79c16a76,75ed0c40) +,S(671529df,8f4073d9,43f82bdd,758fb8e5,4ffe0487,c1a38cf1,73c1419f,7ba06ef0,c46d9f2d,1f23349a,dd1121e1,d51ebe4,454fd141,c7076950,4d854cfd,14fede59) +,S(2af8a76,e7a1697,7af8e70,30bbd2c0,73da3fdd,4c6735b6,8e823cff,901b0440,55565be7,9ada7153,c7165976,91ee33cd,7c34f5ad,d65f543f,72ffd026,26c3c1cb) +,S(acd81d6f,c5ffbb87,4fcb3b1f,b7cc730a,4def3fd5,ef59fc4,2fb9472a,6f575707,8e319a8e,c8b8ea9e,11ef47eb,5071b696,b87c0ec9,63e851cc,e0929646,1d181a3) +,S(ab77e7d5,3ab9e8bc,2052d0bb,360aa7f2,ae062ca9,9b91441b,d60ce8db,80ffb912,5f92b6d9,cb0ab95b,9eb992e5,e1d70412,aca90998,b5d6ed8f,dfa4c752,2df96b5a) +,S(798b8195,1a6a8c7e,f8beda09,b06a2303,1d7efaf3,7b663265,e0188ab3,78124046,9592da1b,baea430,3644a7e5,4e67476f,d91382b5,f1181de7,a1bf9d44,e02b1bf6) +,S(f2486aae,c3be77d,8dddea22,488aeb4c,9dbff93a,24ff6f29,ed6d528b,9777b096,8e2b2d50,fe75c847,7c50327f,e36afb0b,d8409b62,8d83a8cc,41325aa8,4829126b) +,S(222e3d09,3b8aea8b,e0f64ee3,3aeeee72,d16ca088,264f4333,f9397488,146d2d54,eff500f,bfe6bbc4,1c2dd16e,8a0ebd79,37ba1f78,ccb098a4,351b539d,cacdcaa9) +,S(6768d3fe,7ca93476,245a18ee,ab53e002,4f99241d,9c321bd0,165b7d04,c121c1c9,402c9d73,c9b99722,2319ff1d,9e1c778,c4dc825,d030a43,823aee8b,90272877) +,S(6eb6740f,b2f0880c,eff25697,bfd7815d,b0b62884,cf8c8ef2,5137f098,f22dda79,cf7e8531,c12f5713,c302061c,1f42e6ac,79c4b695,e458db68,5209f03f,1485c86f) +,S(7101f348,4eb05a7e,aa0f385f,367b6a7e,5ede8959,71729ac2,950006aa,965fe51b,8d1fb913,a040fb75,778fff9f,c71afc2c,2605595a,1e44944b,e264f893,10d5c3f3) +,S(75a9e45c,acc6a25e,3fe4b25f,12030362,a0de03ea,cefba87a,11c8e6d3,e886579,52a85995,e91986d9,26a02cf3,1001fd82,854c49f9,55683f7a,dbe7c02b,cff69c6e) +,S(31194d92,bad76572,98bffc54,27f99ade,ceac14f7,830ac1b2,954d6730,3737dcbc,99e81c45,f5318eee,9d2449fa,33cc5bc6,8c556ebc,dac2ef19,a2d1ff3f,5fdd2832) +,S(904fa3fe,76fd6f43,86ac6138,70b4cce3,c1d743c3,8457d23c,522958ac,bd505af,94273262,1adf4633,79e929e4,54c70595,8dae9bfb,3957a304,5c8aae41,a7c1763b) +,S(1d1861f3,1a828b32,3699aede,f3fa265b,40de142,78a7df26,b5fa93ff,a4a8e0fd,b9657781,f13ffeb2,8e1306e3,b84bb965,3ffc30c2,63a65f61,1995f44d,d899f7dc) +,S(3bd33def,6de1a5d5,e5ef0289,e8565dce,aac95922,8443c09b,73ce545e,6819ad64,993f0109,eb560bd4,97436627,9a70e9bf,8bc9851d,f52441c2,97535ed5,d4f9c810) +,S(ca1b7d45,2a39aed2,a7f27b24,8e5a07c7,e4c257eb,7150e61c,7bec7f6c,58958634,ab11fe1b,c0357c37,b7da9804,39fb5481,179c0f7,442af2c7,298facda,3c4afcff) +,S(273a95ca,dee8386b,53ff29a3,6ce7d9ac,df145f7d,5f928f61,da6d57d1,8671aa58,88a6359d,bb06537d,1a6c6d83,24065284,315a031c,73c53ac2,adb14f95,1a5bbe2b) +,S(7ea4c0fc,a139bbac,553ad79c,d3921c01,c06923f5,29446279,d0f910f9,ac5561e6,bd049d47,45830e2,f31e7982,2639f198,2eb71c37,71aed93a,54dfa0bb,296dec96) +,S(71f1801c,a2babe5,d4793240,15ccc684,d3823f68,fcd12ce8,bc49607,9607d336,41ed07d0,8384e54,209b7de3,7e8fe7a6,14430c0e,439dca6c,f5ae6ddb,1ff1b4b1) +,S(b2838873,652ba1ee,ae8aec51,55541a3d,7000ffd9,6279cf2a,1c90582d,21cd8828,47ff155,73f5e3a5,245faf65,86afcc31,ee4d19f2,a1efc79d,2a0b4811,d27dce5e) +,S(34ca8da7,22634bc1,6873fbdc,c089224b,d9f8164a,6bf0acb5,b68d898e,b55a3e21,d8afb760,36a9c91c,7769055,d85a3ff7,1f041a90,5192df4b,73f9100c,e5c5d986) +,S(212cb397,d97341af,ca0cf5b2,ef6d796b,4b76eb87,89c3915a,a0e72337,4b19cc8f,f06e2cec,5f29f06f,97685f50,1126c50d,ff17e273,2f78de64,875c35d6,42f170a1) +,S(bc0367f6,43bd13dc,32582dfd,e7893f69,d5f29d2f,ce4b42e9,ffa8091c,6ca6228a,9bec6c89,d1251f06,4aff3e44,ab59ac32,c1764179,7b96f73f,527ff429,74556e78) +,S(8fcb1423,5d8e8894,5ab169bb,4d198e4a,5e489e33,cdeb69d8,dec100f1,a9bd5672,fa1cb396,bab390b2,60302a46,b4408427,c45ae320,5b1d1f5f,e52db790,e7fc057c) +,S(70ad8505,6675ec20,cbc43e80,11df60f4,d4917e84,cca25044,e15c2fa,e51e64ae,f4a51356,af9fa7c9,a5e62475,df5b713a,b63d68e0,cbef44e8,c004fa61,1d5a800d) +,S(ada7af47,48074168,86e6df81,f9718c06,bcf6e6d9,846fa880,3ede1f6c,b9695842,f66d51f,50f427d4,dc748bbe,771d952,98369c91,c41dd,575b76db,988a582f) +,S(f1b87d8d,7323ebb1,1bb8108f,9d34f8e9,bf1e977b,a527c52c,7f045d8b,1102eeee,bd95703,51ebe7a0,9ede5842,47b755b3,7e2aa0e7,7e380b7,9bddf768,b4346556) +,S(93659d5a,d55264ea,c900c301,cfed7b83,1fbf7c51,766cc833,cc591356,492a0553,b69389e9,646d0165,afa137df,1c1d02a3,519ff65d,8856c89c,cf46de05,c0154beb) +,S(e9d2bc49,2a9b4ffd,c482f54a,415beeec,409a62e5,d1781f48,b1738f7d,8ed4ffe2,893e4652,2dccbf80,ddde313,f4f25383,8d639208,36150631,60830408,44305df5) +,S(1424160a,7bf1ad91,18103eea,372da6a5,825e0bc1,a8760744,229e2af7,906cb210,c94da226,96a75d71,1e6f1d0e,10b23e96,4f1519e9,1f63743f,209ef8a1,3996af23) +,S(7f902712,402e4bd4,aabe434a,eb5fa7e9,8686d058,e6f26300,c458cee8,9c9efd87,bc00460b,2aefb418,b16cdcdd,c88446a7,1b8b018c,15261602,669188ac,62f95fb5) +,S(d327ce7c,66cb0f53,e86e5f16,c8dc2936,2a133f6a,38147c01,255c61f5,6f72745c,4dc1498a,c3cb39c1,6908b85,b8c52dca,618cc6d4,1c6f95f8,353758a3,86bea436) +,S(f044eb19,c9d81106,13803b,e8bbfc31,137dffce,547bfd1a,d5396ad,e32db3b3,5ad4428d,9c4c3e66,7f8551ce,ab282cfe,8128a8de,ffccfaf7,c102b9df,7e526f2a) +,S(7a6c5237,b95d19be,af46a81e,bdd54403,d135bbb7,f3c03d55,f67c5cbc,e18daf4,62a2e8b8,47fceb5c,484fc6e7,4ff68fed,bd492c66,8a70c1d7,cce2922,a204385b) +,S(59c7fcdc,b069c0b7,bb772afa,f5c20846,ffae949b,47589bb5,80495bc1,b59f82f0,82ec588c,6657566b,71ba4d79,ac8e2c7a,c09b3652,f24d46ec,3358eeba,126c38ad) +,S(f8cf3c21,1ed4558c,c40d3dc6,dbb85e54,81d99fdb,cdf27ae0,ea01bd4,6b6543d7,bd8049d0,1c3df630,8951f5db,dcce3043,5506a5c3,e0a8bb20,54de9dc,87a9778b) +,S(3855d764,b2389d4f,1ff47189,33aca82a,4d2dd23f,cfd13764,2782ce71,524504bc,82c4ea25,4af2abd0,2724ec34,6aae3aa3,b14a71ee,df13df95,9446c0bc,759ef72d) +,S(77644b31,1de4f0d8,d30b1d73,35553dab,6d3e0e6d,af7e6ffa,48cddd1a,52de5431,645e17ce,c0a0735,737730f9,92bb7431,7581c930,695829b4,cdbf5214,f45916b4) +,S(a4d4af43,afd6afbc,b2a511da,a6537abd,56bfc0cf,76659d34,56530663,d9ca138d,be6c9fd0,dd2df31b,b907f073,7d63df34,88b5db5f,3d5ff747,a25a2beb,73bb09dd) +,S(417ffa3f,e673a081,f72c3d64,5e64bc61,2da352ca,fb66d1aa,aa8fc060,74a75be5,9ab8be2f,90849474,809472af,d5a7490e,cfd9ca4a,7f738be1,de093e0,68c50151) +,S(78175154,93115041,6cbd772c,c74212c4,4f19eb04,95e88622,f75ee838,caef73cd,37d4d5c8,ffec3650,26381b91,d7cb18de,fdaf2cb0,a5d94ac2,dd7bf7fd,34d0d3e6) +,S(365c560c,3acc28ea,f560c66c,7e76625a,3c2ee7a4,8f62ef0f,736253fa,b1b5121,25cbc6fa,96c0f15e,38b03f88,338f8dd1,6990aa15,dcec58d6,4517d37c,5b74868f) +,S(c945ad25,1010023e,9126b6cb,3a19a925,6c6757fd,d88cf808,a94fa182,8f5bac7c,c9a8e90c,b4ac43bc,ef08ae3d,fc66f6db,99df4abb,2679de5b,174df92a,d654e2bb) +,S(4aad85ac,45e6d57d,73822387,632863de,ac8c3fb7,b7d3beec,629c0e1e,2c2e0213,38eee8e1,9e81bf64,9641c192,de53a071,29c03689,376f6595,2130b63c,fd6a2708) +,S(2bc10248,b0f6596,adcf9f66,3f624461,907e37ea,7d35367f,24b9f69a,26a291df,e0ac3ed3,3016b37a,91a780f6,b90b7743,24ad0c30,50812b2f,4f35426f,4311c79) +,S(cdc05991,abd28f93,e81a2c0,9a04e1fa,eca89400,81fcfcff,eb91c8d3,93ddfde2,dfda4ac4,4458e2b0,3feb9852,d1a8822f,8bf90a4e,bc79ab32,afc9a1b7,580193a5) +,S(5a24eff0,af2dc429,ff4ea857,f8aab10,31d285ae,9c8beb7d,793bf9d,db46a047,179db914,59739160,897f40dd,b7af0b8,a98b6f61,6aef7327,b53b6005,9c4c8f9a) +,S(16c1e53f,51603ca9,374aae6b,57d15fdb,e7c1d2b0,b0545467,636fe2ac,7838183a,bf858ef0,56e09bbf,5d8af50c,7e0fdc90,8d1f6c1a,570594b,a5368976,63a183e3) +,S(792f1eea,71b92f9a,d893a116,ac177801,a2f2405b,1c6846eb,c3a6559,eb01ccf4,bc062f0c,c610ef39,311ecf87,a7866b9c,52c0df0b,be1e0129,3ccd0b7a,2832a79d) +,S(1b399c40,f057719c,f544dc51,51137fe3,917dabac,f0804dd7,335ba65d,a57378e1,4d6794d3,b6e8a085,41de872c,1dd333a2,bfdd0712,aa846f6d,380a775c,600b425f) +,S(138b313e,b9c45ced,e0cd8219,b888c51f,9f8cd278,abe16ede,c210bffa,ba238e4f,a199a357,cbc8042f,4b6d4951,2f0acd26,13f0f76d,cd6dbf7f,d9e8723c,e6ac56d6) +,S(3e06c311,9c765664,d0068b24,cf4ae1a4,8f401811,17c93122,84ffc24d,eb542338,63a65596,e5607f1b,6a9c4596,39a90d06,93b08ab3,2807b696,498e7557,673624f) +,S(3f32f9b,49c88932,574e5455,c179e9de,80f0f6de,ed1ed25f,8a3de8b4,bbf8bd2e,a2d2bb1a,5fc96f89,ef490257,bf42a9dc,91f49ce,e2b86472,8551fa6b,6a589f17) +,S(89adc417,ffccc50f,a129602b,f5b1b82a,2c4f5efb,e3382b04,1fe77299,46414ec5,4ce7e75c,291b751d,155c291,5aa619ef,6c3daa28,25da8bc8,e2c7ef54,8c253215) +,S(f33fbd62,6bec8c9f,6597d486,2f54f65,e9f208fa,7c1d619,a13feaae,5ce4e9b5,c8f0602b,ebb9f152,87fe2eda,3050b032,a6f43c8b,7726825e,df02b424,51593774) +,S(eccc8ab,7b90e2f7,e45f7703,a0e97406,117fa04f,4512071d,568e3e64,a4a7d6b8,8456f705,a9c4a0d8,f2f3c233,3c8bb367,fcc8a645,f1fc560,48e1699a,58a1b6f4) +,S(f6962b33,a7ad862e,58181c75,42743ed0,e6e31d5,4df1fdfc,a4e3e95a,157de915,af3d47fb,48515ceb,f9f7e8ad,2a0159aa,55c155a,83359cf2,9ee3202,ea9e6605) +,S(3f1f3c6,7996fb10,65ed5df0,2095926a,5c45d2f2,38ff59e8,42b9d234,daace24d,d585c9e4,f0a29f0a,28e3c30b,22228dab,73750706,5690811f,1104bd4a,6d0ea28e) +,S(fcae019,36290e43,d8bf93c1,6ad2cd5e,dc33592d,4081b0e3,4aedd451,6e6e589c,8e98579e,cc42a444,2dc710d8,8cd09996,c8acb958,b9702c24,3a207ba1,471165cc) +,S(548f27ba,355229d,23b7922b,5fc8efad,abc4247d,baa312c6,d89570ab,151f522c,e5597d8,bbb47cd7,c8cba774,ff37c81e,b7b63c63,39b9600a,cb77f1b8,86ab6fa9) +,S(e2f64914,e8bf347e,d465cf1e,f086b7be,49797db8,611803ab,6e439bbd,5c146fa0,8e69e76f,7c641e4f,15248257,77aef9b,88b27a94,72d565d1,d2ed7463,fc6ae76e) +,S(8c532a0,2d970c0f,1d8f9762,2298b40d,c7d362c8,f38cd122,2cdbeaba,2c13db1d,90f8a2e9,428d66d,9e8ffc9f,bcb7606f,568251b6,2dec2768,1b6ffa8,7062bd0e) +,S(64646efe,e3c51972,f6af7e0c,8052aec4,6fc0ed97,af566f6d,3c323218,62291a23,9e29e150,f6ca370b,36a76ee7,171f2ddb,a10eb88a,986ffc50,d6c8f4f7,287a69fe) +,S(6e8ba4da,1df8dff7,cbff69a,6ef65c9,329199bf,9a67d1b5,1eb1e1f3,473be659,ae7562c8,959441a7,35ff2188,3e537bd7,eb5a34a2,7e144a06,f674679,815d852a) +,S(8c21abc8,f7812c0f,6de0d7e1,cadbf1f6,c94c871c,d5b8e9ca,e76c1f33,2b6bcaef,5a7c9cc3,13be03e2,5410ed03,7e0cefe9,5a36d6fe,68ff46b2,663a0ca9,747ed53e) +,S(ce0e383a,7c487e14,26636ff7,657a28f0,10ce5102,1eb89fea,3426b269,2f9f6353,3f95a465,d43f7804,2804e9da,4c73c8ec,97fcb9f6,fdace280,532c0c0d,6232e03a) +,S(7e33097f,51477c4f,f4459848,34673fc2,8078b6c7,c01cb700,80a37ee,1d698eb8,c1275bc0,7317c679,d881d274,e49065a2,e282b7e6,970065ad,141c1ca5,ca2d75a7) +,S(ef4d9cd6,b1487e61,fb31cf42,9eff2731,d686eb66,cfb3f867,9317b0e4,116837a6,c4f6beb4,280ddd5a,24f6461a,6ea1eba2,3bd2ff58,7ff612ec,d118b76a,3d63be1f) +,S(f3edc145,2ee49324,f7890bcb,9a5f8ba3,ce53f4a2,df0c94b9,92c573b2,f3716290,995446ab,fbc9b27a,8db301f0,87c2ae93,5c390565,491c0dbf,552a9820,d3fb2f2d) +,S(c1f62251,7398e914,d6134160,318d20c6,87d17427,2bc62c92,bd170ca8,2bcaa975,1c85ae27,36735b76,d5328d59,3292f718,f6d6da52,1c75cab,fcb06720,87769e99) +,S(a7e81df9,605f0881,d4856153,3e310715,b206c601,9a55b889,7141321e,463dea8e,3ae220fd,1f361be0,f0b70dbb,a7df796a,eb23deb,5c5440ad,aa16fef9,7cae8a4f) +,S(1b69bf29,8f5df296,7a3ac028,87d4ae5e,f46af5ac,5a8cf326,2fe7282b,e46a536b,c9c624aa,2d99a71,ea375c68,419b38a2,d7e9d7fd,8880dc60,28c24f2e,a846a91f) +,S(cddfef74,31763b9,8df15cb9,6b3b3127,b31c9987,fd17251d,b56122ed,dbbb44bb,972fef4,2e935aa3,4c679ce2,6a32a38c,225f0867,8f780b65,854459e7,f24869f5) +,S(32fe1cef,2c8a5163,66b47d30,9ef01e20,ee07f235,e7c0129c,fcb70fff,60e957ff,9e861731,bd376124,8b33babe,c354ea,3d13b2c7,c45b436f,e754edf2,4fb4588e) +,S(a382fbe9,f4914119,d31d0ccf,6afb61fe,4a759657,26556908,505225b8,79c24b0d,aa300360,39a1bfdc,273e0287,c7c222fe,cdde6318,c9838a55,5136cda8,d2111857) +,S(b53b5439,9ae330ea,e13e2467,7c0344d,59e305a7,96a228bc,6d6914ec,1a80ef88,99809053,8dfc6c5d,748f43cc,8ba8a8e2,969d8d1c,47551a36,8f30ee30,d5fadc7a) +,S(621b5253,f11cfec3,fb4bbfed,98b0ad9c,710fe2af,6aedb8d,f521d0da,fb64169a,2a234dc4,8b716af6,22dd025b,63e05c5f,3b93005c,13614bb3,abe0dbe9,260378aa) +,S(83332b6c,cc9c3c7f,3163f442,80f5758c,1e5979fa,b9a500be,d5b315e0,f9435b04,85360612,258c1f1c,bda41025,c402dd84,60c77df6,8762d2d4,16aa16af,dcd30ea0) +,S(27c8d8e3,91202622,2f72d926,da01b10e,fd54e21a,7a4746b6,68aa868f,dbf6538a,88768e3f,b8f2484d,56c9fe83,fde0fff7,4d0c0a81,213ac090,e90d2b42,22d6eb91) +,S(f349c70b,bcd82005,2fd2e05a,c42556ef,6ee768d4,f08b7a91,55d1ebfe,60067e5,6d595c19,4011d050,c7c3c4e9,e7aea90a,93fdc5b0,71d6c9fb,9f621a4e,750c6604) +,S(4966567a,b2029966,62b1368b,ac3f89e1,a0183b20,173a7156,edb827a7,13b24f90,6ef89436,c2bb3bb0,94910ee7,6c083e35,a097b859,16658947,1f59c33,37e21ab) +,S(4909501b,491da13f,78645b84,9bc63fea,75611b76,5ff6eb6,9a7414bf,913e0886,2c20c6b6,f2ee070d,c1dd4c95,6822ac5c,38b1acf7,5e093f17,c54b65aa,81014df8) +,S(1ed2e667,f5a2d140,18cd3ee4,f4163f7,bd5f898e,ee3dda72,bf84e356,10cddb76,bb4970c5,64fa4cea,e204babd,d869e36e,934810ef,68a22794,f9919e3,26db8e7d) +,S(c47bab41,a0bc37f,addf9c8c,7de86d68,c15d1a0d,85257d57,2a1d60d,4612f17b,e52acb1,36f47de1,1128091a,1a3cc3e0,e84ce767,cf8395cb,b09eea81,a2db09e3) +,S(e21068c1,4993cfc4,35490b52,5ece7657,f70825f3,dd2138c1,8f5ec6a0,c67a7394,cd610137,d48f8d9b,2bf99755,35fab6fb,65360fc,9db04a12,43027083,c732da) +,S(635f547d,47a72f5e,b069e144,6508a46,bd6a6f,11eefb87,da07e4f4,3ffaf917,8ea0a9f2,3da273b4,f324c8ed,81cb0bf0,21fecb57,54eaa642,21736923,2be64128) +,S(24632c0a,8648b4b1,fff2f79a,b3f8e64d,3837b6ae,9329eaa8,48565f02,45bdb47b,9c6d0788,c9e155d3,3c260360,862ab236,177ff875,a3823179,8146e442,f66e0426) +,S(43748dc3,cfb229d4,8549cc56,ecbcb01b,146541e1,5d2c3b5e,d59fbf7a,6b7bf503,9975a1ed,23a09906,3b87ea7f,2ccd88fc,b20607e,1aded9a9,265f34c1,45fb9c5c) +,S(8f848323,b8c41d68,31603b40,69be1dda,bb8750d0,11527a58,4bffdca,c3ae3ac0,77a8ac87,128260c2,86f5805a,b17e5a45,be81f83a,2a575c6e,2c88288a,c2d1b37f) +,S(29ebc368,b54d846d,bb5e8be4,81c19c80,2d8907db,c54412cc,6e2952ba,2948422c,e6b793a2,81d59d90,53aeb2d6,f79cbd1a,426f79a1,6860310a,ec72fe26,37c7e845) +,S(9414cbc4,ccf4012c,8c0cbe21,eb714953,d84bc602,9f8e4810,5ba79967,23ed345,ad1eeb92,89e4a109,2d132790,ece35cbd,da45bb64,bb6ae72b,39b9eb80,d57fdeee) +,S(1bd8565b,769d0024,613ab814,90f214c8,bea90a5,db1e75d4,11ec3dc7,288f756e,c050a46c,fc781e91,b79cfcb0,2abdae50,b69c2cd7,dcc56b13,1df2175d,c1d375d8) +,S(4f7584c,35ad66be,3d409154,eb8ded67,14ed0ae3,288593f2,76cec90b,629cb01,f4be9248,232a120e,11ccf1b3,e9c5a17e,1520fee1,8f1da048,fb01eb3c,17712bb0) +,S(5b0009de,7e85b317,ab127401,fd2f3ced,cffd1684,c4772b35,2b9c783e,1dd9f13b,f4585704,f531c34e,3377cb7c,e672c78d,cb8839be,ecfe048d,bb412328,b973ba64) +,S(c66f31c3,79396f01,2ea5fdbc,4222df38,37f85353,3f3ed9c3,ad13bcac,63b32815,7d7b808,4ae5e9cb,c123ca86,1b505242,4113ee84,bbac5ca3,ea1cd3da,6eb22668) +,S(33097f5d,c8b09934,26ba51b3,ee99e696,3d7ba455,e91a7af1,a57c85e6,5e63abd6,fbd26b3b,200c189d,c8b9e120,61869766,987401ed,66e4ed80,63835922,c270d7c4) +,S(1ace5245,a3b7ec60,b9a922d5,ffbbe43d,aa71cf0b,84e395f8,c37dd2a9,c85ffff4,72c0ed67,94708f9b,f29c51cb,b6cbb69c,6ad3f4d,10d62987,1c444da1,bb25084f) +,S(bc197b9e,4cce4c2c,bfb22524,93f9202c,6ed54e32,cd52f512,692a5af3,6b0c4471,d5137663,5182065d,a4d6be56,cec50889,3cad9b95,4d5d17df,adb084fb,dd673f70) +,S(66997931,334bdbed,174cfa73,3ecad896,13c6f500,b79a7fab,76ad0bc8,dcc7df70,fdbd3301,948e198e,ee3e7d3a,504ac560,ab00afdf,26940331,d49bd2c,6599435a) +,S(3ba86cdf,b38d82f9,7c20b962,103f79a,5637422f,370b08b3,89083cc3,1a6eb4bf,acec9811,76debb13,9bd7f981,9b476e1b,5377e32a,bdecafee,33dd6ad2,3258dfc8) +,S(f62432f,9db971d8,4c3acdbd,c2d915d6,6395199f,76e81243,fed930db,ef1603cd,ee89cf3d,177b4cc6,e5856acd,5de8757e,82269f4e,eb11a444,c2e0c797,4a7b5f28) +,S(84b41bdc,6a6dea46,ad6e650,5b280a1,b6d81250,794e0b1d,688aeea9,c067bbaf,9f78703c,b535b4bb,2b88cdf7,b5f0f0cb,e452fe6e,5cd0f2b2,ab8c2439,9fc00e7c) +,S(8e2dfea9,3ea64a14,e28f4883,98b8d455,48c52ac,a5399f88,28a42c1a,c89d4c67,fec01549,cda53605,335df10d,d8ed04eb,e09d7474,f69deff7,5935a499,f2781271) +,S(c3bc6dae,5401ac1d,3fd75e36,4cbc2fa1,dbd2f6a2,40e912f1,18b27759,9b105e0b,170fdcf5,5b739326,fd234506,303700b1,9c5dba48,b6f0cc34,a650c3f,3b63d6b4) +,S(33093e93,1b1e52e7,ac5a289e,27ff810,c2defced,e935795d,a10ecc89,a3c14691,7fbba584,5bd55ebd,a67dc842,1ae10fb9,2114f0b,d68bc47a,7ee87a7f,70deec38) +,S(21b35438,b6d1a3ce,6c765e,dc78dd89,3f121132,ecbcc208,a36fe734,d8141ef9,f6115a5,ed237dc8,f61a82b3,66fb508d,e2d516be,3b166a7f,2566bf06,eae300d0) +,S(ced66583,aa1bed17,30248edf,28e9e4fb,ade70821,1c2e48de,3782fc6,d3892df3,4f43ad36,f29da03b,f0fe634e,3c441c42,c3a81835,2407f1b6,cb38e738,18fdec96) +,S(c5a74420,f541a8ae,b0673122,29fbccaf,37f6eb7c,ccf2bec0,23a8573b,ee6f71f8,ae634c02,44263d36,c00a6e25,d25fa592,1612a535,4934d709,6c864865,60adb259) +,S(304a048b,f30f6b4b,2a725521,15b15ea4,8311c51f,c4cd212e,f0a4bac1,48b9de9e,8f935900,3d6ebf0d,129cb5dc,8a953fab,11ceeb85,b2123fec,154b065e,63bb3cd) +,S(ff96b5ae,7eba0af5,ac9875e,97811e91,6ecb66f1,3bb06519,72ebfbcd,5b9c2048,24af2186,bca71cea,e58a0b1d,b56aed1b,3de89cc8,70fd4e3c,31919e2f,6352a887) +,S(5909ce1c,df732eed,4147243,76fdb3ce,8b6d38b9,4a0b35d0,50bdce27,b1b701a3,2e44944,665e761,825cf223,90383a3f,7d3731bb,bf7792b0,37fc05e0,b224dfdf) +,S(ff6b771f,86d66610,6fa032b7,92844548,8ef9974,caf05ad7,cfb6b30e,abd1d527,6abd2a9c,9393e91c,ff77e055,7e9f6a86,9fcd0bae,3544bf50,b25f0427,908ba4b3) +,S(943ccf04,94dd1fad,1efda48a,12d9ace7,be919685,7e7fc5f4,befd7d23,3a1aa8d9,4f08b4cc,2dd93f8b,3751a23f,ca7e4f10,6014e01c,58791c52,3d01134c,1a0a7bd6) +,S(a79a7a7,a89e1cdc,908e0968,bf26c341,47a4638b,1d9cb5b3,ee6c49f7,405f172c,cb53d967,14b5be3a,e5497f34,ec0325b3,ebadcb76,b9838cd1,b3cee90f,f3bb8ceb) +,S(28ff2efc,71176efa,a861667c,d173f78a,4f548b36,aa33db2f,a50c0515,1c7b89dd,475b3707,db4ba15f,1485e165,68d7dbdf,8e67cdb3,37d79988,dc6e2249,d6fe4941) +,S(85b2c332,16a86885,c0704fa2,55b4ca00,223e897a,f0ae7557,f8687eb3,b1012968,a1f58d45,ba664056,efbcbe7a,f0ef479e,1f2bcbe7,98d055c5,7045d735,d657ea11) +,S(e9fc2d09,eefb32de,4068e2ad,d7bd3692,7a02b3e0,d354dd47,c2a70c9a,5cbb8778,ee009aa5,1216d068,3ee219b,bf53ccf4,f249d7ec,bd8c9cdf,80d0ec5a,5b65c312) +,S(da2dcb50,afd510d3,26e38af9,5a22850a,a1cc88d0,620fed65,763042f9,a0005d9e,1eef47b1,c3700963,5e16af23,f1308de9,ae0eab9a,b16c9443,6d501ebe,133eaeab) +,S(20daa29c,c6b166eb,ce717402,70873566,327891d3,ff7b6f08,b9b7da3c,1eb352e0,2ff6982c,ecd6fa4d,ec1d6692,92c3a326,a30cb526,4dc27a4,299dd3f7,7ae8a3fb) +,S(e16b08dd,2ae5be13,67547a53,496f9f4e,3aab8440,6cc34bdd,71b2ebf7,53674d9b,b70f724b,d9522b1c,8e43d60d,6357b5ba,48a1afc8,b7136c1d,9317a1d9,1ba06846) +,S(888a2daf,2d69db34,ff9485e,b06d44,c59670ec,3c68475,80753567,e56b93d3,ddbe4fa7,792e0b82,ac4753f0,5b271aba,8e804384,b7949a9e,9ba79fb6,31d4e3f5) +,S(747768e2,9090fdd5,2c22e308,131f97b2,ee6d8e0c,bf43d704,d50d60c7,616abd12,eaa75f40,8d1ce0b4,bb52879e,5ee7ff36,27b26645,c8ce3840,99dbac60,9cb61058) +,S(8569f2ac,1c7d131a,8d337cc8,87c00c1f,80897a58,f9131143,5a17d79c,fd8d6eda,504f0b44,252d06e8,2f8e700a,746a3393,85e43baa,a4e5da8e,dda7ed6d,83eacf71) +,S(4f15f3f9,a67221dc,4fca1d68,429b874,c4418df8,be480591,e57d6841,e11860c9,982c0d56,1783a9c1,a16bda10,87d29061,3f1154bc,4cc62a82,b795c54,a496b7ed) +,S(21e51a20,1f226e1e,3ebd56ce,6f7258d6,4e4f9db,aa425943,9e1bf7c0,144a92ce,4c47a801,b6a5a4ad,25c1486f,ec9bd0aa,428f3167,45136359,18d47079,75aac869) +,S(fac7e42e,8865ec0c,d0b4c4f9,dff6bf8b,e0f28336,395bdf2e,d5e2a118,9c0211a0,36812d9c,8337199e,fb1fece1,1997307a,ce656fb7,3bad65c6,41e6bba2,c4dd695e) +,S(a147839e,c91bc77e,cc568671,442d29ee,57f0f42d,7b9cb469,91064549,1a26d225,f404350e,bf7267f1,86120257,fa29fc1a,fc0d064e,2f14eeda,b730770a,c85bc5a4) +,S(d1212cf9,e5086804,44883c1f,4158f3e3,44a7900f,716ade2b,df19e41c,18636b8c,720b851,7b91665,128183a0,f3235c6a,2f9c21c8,e8c6ec0,5553acb0,27fc0964) +,S(13d5f334,a7ab2578,977c125,1a07d7a,2e4852ca,8927ce7,2dd9fe90,8b948975,973869e2,d1d0abb5,1ce31db1,ae8c3816,ff998753,479fe82a,7d87b6eb,798773ca) +,S(1f066961,6dae9e8e,76a9bec3,26bc2136,5ec754a5,34c787e6,b9abdfb0,e463507d,da48070e,b4ea111f,881f9fc1,2993a9bf,c6f99974,b3353ce,b5bd1cd1,c75b262d) +,S(729e187,38681dc3,c4ad9a49,59f975f5,907b15d0,114e029,8d4aad5f,69150269,dbf2ed8e,c60ea01b,6de0022c,8b035a7e,c1901c82,9e8d83f2,4560659f,8d455442) +,S(e92fcbe9,61353477,4d42435f,de190c26,8e3692ee,c2042fa0,2ee21687,1dfda12a,a75b5c0e,3f5280d6,41e36957,5e6ec5cf,585b1451,1f01da84,fb852cc8,2d64f2ff) +,S(85c2e61a,c69f8d39,e9c4dfbf,93f6b904,1ad35bcd,7f2b5c1c,789812d4,c8da36df,ca6d9187,694429e1,a5ca50b3,332ab11a,575264db,bf297752,f38fabb3,c0b53f45) +,S(10d17632,c33cc6b4,f5c2791,b5ae4f00,3adf9958,879c24f,10f147e1,bd1bc05c,e15ee734,f1ddec6f,45dbae00,88e4c5c0,be8464f,31205718,a8b2c929,939a687d) +,S(a6942345,25938972,f39820bd,27ea0bbc,92511dd6,827476f0,28fec86b,e25d609a,e06b3616,870f73f4,93f6d1b6,6256cb48,af49ee6c,b5296bd,ea73083,4f11d6e9) +,S(b4a7d8ed,2b3dae3f,43eba052,45b6c4c7,c401a675,6bb0d906,4f66d88,df94d8ac,ffc81c63,1a2cdb5a,fd7def11,9d07af35,74dcb04,e10a5ecf,d2b0a46d,90963456) +,S(5aebe21d,aebd3c57,285cb660,d9aa55d3,f84fb2ff,584f1266,3031e2ab,dda6fd17,22ea513,6a51b532,d178c40,cd5c8453,8f5994ef,7b35cff6,d9dcd999,daf1abe8) +,S(ac684664,194388d5,b796d64c,b4563aa6,69388d0d,83861c51,278316e7,2c8c7f87,cb9426d8,2dc90b01,97bf114,3f693e93,4d710988,26586e5f,f8913ab3,9ef41ac1) +,S(6f94bd49,f89e621,874c58c2,f27ce8a9,76ad2764,1627e835,6b82157c,24955250,d24330ce,4a54dc7c,5c7d9cf6,8f8622f5,e3633a85,8ec0d2ec,d8df3f9,bc7c5614) +,S(3f96c8c,e149947a,6d9ec5c,9ac5ff44,775e068a,785a2fa9,d0940905,a008f137,a91dcfaf,7111a506,3cf613d4,e360c9fc,9b7d9e40,30e00ce2,b120eacc,805f3f40) +,S(d805b05c,dfd675d3,b862a4c1,74909974,405a5b61,9b2a73c8,f3470959,779c707d,a68b544c,c7279f2d,e3a2abdb,fbb7fcb1,84366ef1,3cc3a66,b6d8cec8,3c3b6865) +,S(d2293c0b,d4189cb6,6be0efa7,874abe9b,59142233,6f2f71d4,808be34e,79df0e4,5fbc3248,87c54960,b9bfe70a,5cea3871,7f24f79a,3fe0d313,18cc068f,212682b1) +,S(931f090b,e22623fe,7ad49d26,e76b3c5d,e3f107fb,556f9657,facad9c,5b209d5f,cc255e79,d2a89899,865daf74,81aea395,848f57c0,1850c144,d5ad1a17,4b1cc087) +,S(118a6283,6707ff6b,c8ea72f6,285403a4,6e4e690a,db340987,a0359732,39e5ddc9,91f00fe5,e65a9058,36f9d447,d96af84,b6f5a18d,85c127ad,72221980,f7ff818b) +,S(81096ceb,5b6cb49a,d014ba42,d1d49e1,b811ca2d,2e6614be,1891c6a4,1f6a985a,da051c5,f8f9f3e5,78050a3c,1354b674,3f494860,6b04b8f5,b4dfe970,b7607e5d) +,S(9a80a438,5ff45ed6,2dd3559e,783eb47c,351b7e43,6ddc468b,9f410989,300cae06,845d1f99,21b69c5b,4628aee8,b0c55398,bee65659,e3e41cad,30e57bf8,b804b6d0) +,S(6a3168f3,b89955b9,7fac1d59,61e95fea,2143954d,fbbb6090,81c2408f,46747906,5b5f1f88,6778f108,3ae44a3f,82c901b6,12c741e,811d5403,c483c572,8cccc005) +,S(9a03ab11,78d165ba,23bd4298,58bc8ed7,797710fe,f4f8d8a7,3db0a90f,e1214af8,70888ce7,e61e4bf4,91512f2b,fa556f51,59a5550a,1d50a65c,a652b5bc,89e85665) +,S(8c90c18d,78b8d9e1,59a61575,48c14971,296c8c41,991dce25,e7878ef6,f4ea2f5d,2a5428cf,de628e51,a1644a5e,5dbb7227,2b97c0f9,b6909a68,2814882,cb1ca074) +,S(2e9bab7f,3062024d,84f7a5da,a02c9ed0,93327923,339fdd43,b68d6dd3,508a8957,c9af80b7,3f3803c9,f21e21f1,9523b2df,ea7e4f8c,9a376aca,4a147530,d2a43345) +,S(2734bf2e,718ecfef,64a95e7c,1fbe6a37,e2129898,343af84d,b5c17671,9a466322,f530098a,9f115f0c,e36a0ce3,4697312c,7d0a1e4b,df8a3ca8,f0a63631,e684216e) +,S(ab9ecaf9,500e4a4e,6e81b997,579b5214,4af3257b,8c8f40d5,e21c2a51,d56aab58,f7d38746,8e081844,9bd5e9d1,938a8859,d0aaede7,5743dbc3,ff30d51c,3de0f047) +,S(ae25f546,a4c09ef2,e5a9cd3e,85baa880,292b4d4d,4e8440c0,1696435a,cb1af368,46a2b3b3,7373840f,b739a9f2,2953c6c4,80bd59f2,11013d59,e051055e,f7f3da84) +,S(54285da6,4ef21cda,f597efaa,884fc00f,4e35abb2,bec04ace,54a83dc1,c12e6142,483beb2,144d7b5b,a47c2dc2,9225dd5c,b962a849,d46ff6e,5220b6c3,20cdbc3d) +,S(bece8434,4bc231f,60ad542e,d6a7857c,35a627ee,a2914874,c8deb661,37dca65e,a229fb80,2f9e72f,8e477fb8,de081254,fe1c93ad,a4d3b4f8,e9c2f4eb,3e2f6a95) +,S(3d55747,b148b857,472fe5af,1e820bbf,89994a2d,ae6c326b,26fd9cb4,fb5e81d1,dedeca5a,e86728a4,f635bc4f,1b2b162f,c9ea7dfb,efd5852d,b90001cf,bde465df) +,S(13c68219,d1633c73,59f6361a,88bf6a72,1846b520,33475715,fbc97dcf,75cde5d4,ce8a3cc2,39fc7f20,96abfe7c,52d79e9f,bddf0ce2,ab2b6e55,935413f9,37f83af4) +,S(e9e40ae1,a8041a47,274c481a,dab52f18,36690a29,be837433,43650126,d5b0a6ac,c19958b7,9c9839b8,1371f314,749147cd,9a22fa22,a55da9a9,577646f2,38c6bb7f) +,S(2e3b4553,7460a1a5,f7353a53,78db61c9,13af4371,9a268eea,6321b4c8,a1493068,f7ba5e56,104966c8,4959d3e2,290e5501,5ccf5cf2,b6fb5bb6,e0452c5d,cba54dcf) +,S(9855bc82,b9214b00,67eaa40e,bf670dce,6a59f3dc,4cca491e,db1f0f48,b4c62b8,a7d93f6e,3be6c73c,e9e37d6b,5b071603,87184e21,38478009,8d4c1c80,ccfcf435) +,S(37f820a9,b9342913,6d44bee2,69cf27df,67486bc5,233b8866,982f8476,15253979,fdcaea9d,aa629d37,7f345a5a,37c566a5,50dd893b,9d7ba88b,2a568a28,7870ca15) +,S(e82d2c98,a92a3b0c,690f6ba2,8070c59e,3e0cd0a2,a384d3b0,3cba9d1f,ded41a98,31e73a32,32d85b36,14833d34,4c7d502d,d09d7ecd,614b060,95c86be0,c8501460) +,S(bd492fc3,6dd4c906,6a071182,7eaece3b,ad46901e,b400bf3a,24b93799,9a923419,caada3c5,1e1fd5a4,6676dbd0,a7fd4049,8b93da93,bcd25af5,fdc6a0c9,1dd7798) +,S(6c8b46da,42d1ec4f,3ca2c4dc,15a69c80,cd8f0d99,7bdf3964,1cded32b,8629577a,d3ad4f62,729e42e0,f72ef596,5bcbc239,cbeb988e,e62b30a9,7f124004,c718c956) +,S(78b1e9e6,799bd3dd,854a25d3,4d356b4f,effee71a,ad0c8f05,ea9ebcc0,f8f5dd62,31503ed6,a26788dc,c07d7005,7a300665,d726ce2b,702e65c1,dd25f892,3931145d) +,S(f2ed02a6,63c5523e,3c68cda6,bfa4ab6b,cb53fa5c,15f0375,c8974eea,5aebdccf,3bde5c3,afdc0320,e3b92241,3220ad32,937720a8,d1477b67,773e725a,3cf36382) +,S(7e43f643,a45800bf,7e54d83,5ff6ba20,f67ab101,5d1aaa60,cde0967d,42caffd3,1f456eda,f473399,b57fbb37,807b5269,58600d12,b556879a,76e21459,5798d68a) +,S(df15e177,5eb73697,aa4c0a62,4b4d2ce9,7ccde2ca,66555d07,6430b656,61319be8,496cdc,f1543818,c2173dfb,8a60ee2d,8397cca,b16e4e53,b35079cf,b27311ad) +,S(edf1d706,295bb20,12dc1648,7940e84b,6707a3fb,91a14fce,ef37f669,c782e2ae,e3a0f2f6,fcd76c97,b20b2dd6,8e888eaf,9ed8f598,f08e4d7d,239a8964,fe019a2e) +,S(c15022b2,6b15821f,3be3c313,73d0464d,fd92cecd,6ba87c2d,9b18fb5c,16f8f6c0,78cd2370,d94e2842,e07961e6,92e9fa04,65d57f25,a80feda9,327581bd,ce136c2e) +,S(bd4df6b,b6ae15e0,109886a2,8a8f8c90,c6cc2bcb,b52dd105,e277da7e,c76001d9,499659b2,b0b4cb96,5b8e5029,96ced2e3,a6f6fadc,da01b875,72f8727d,8ef1446f) +,S(dfcec232,873894ce,525f9b4f,162f180e,1e2d6eb4,c846bed4,b2109700,8fbc0b76,afbc761b,f4c88e71,9c318f05,9a10ab3c,5a477ec5,33243b95,3f8ef006,69b4f92e) +,S(b0076c4d,e3c94fae,23659b00,5b8b41fc,b8473935,764e48e1,a9eb1fef,f5c94e54,e1eb3255,3c55a687,6f42ee5e,44830a09,fe17fda1,b84e8551,f3ea2308,f9c7d4f) +,S(9a1fe9c,17c4255c,c11e9fe3,3d66787a,fe9ebb0,99be88be,94b4c3f0,da2d0c11,e6aef709,99a8e739,6e23e1aa,c7ad1cab,25f6fd6e,62df02b0,96af568d,e88e8379) +,S(1d89a934,126bbc15,d9b99b88,b6c65106,e1d8b16e,799630f2,2576e9e4,15212899,b7e32256,92db0722,e9a79ef,7d95c509,37d64644,ed36cfd7,56780d59,a6f8f4eb) +,S(c60f5c68,b67b3796,3c462d4f,7530edfa,34546956,21bc80a6,ac2be433,700c7fa4,88f8b071,97fff0e3,a19b5a67,60dc92d3,b5507b53,5cec02c6,53f75a60,bf8a7e08) +,S(52cd2b6f,d9b2699,1b76499a,d301be43,6205761c,f768eec9,e6b7d6c2,52d9d949,d127cc66,1fa33508,a0d11a3e,ac782b26,26356382,f547e4aa,13802138,30ec835) +,S(1e44499e,a639835f,f384f107,fd16bb19,c21fbea5,cf4e3be9,20a34024,6d05dda9,41c6a8e9,a9042f9,950d12db,74fd0f21,8f8adf23,e961488d,27412c2,f2d1f53) +,S(139144f0,a56394ba,d1e53bae,360136eb,984ecc56,56a05cb1,c6727543,fc6861de,70394737,ff37e9b2,1bf174ab,6c042bb8,964f3d01,6ea1edc1,25ed3b4,2ed0742a) +,S(934ca02a,2454df18,61fcb954,6634e685,34fe75c8,b6db6eb7,5a2a74f8,654a2280,779e9784,266cfca0,b83caee,74fd24f1,6865ce3a,6be78be4,375fa15c,db195761) +,S(a64f047d,9e1c2459,77da8c32,9d35ecd4,af913baa,2d4b679a,7acd326d,886a3be6,e11e830f,f3b4ed6d,102145e3,b24759de,3210f309,8ec57581,e6014818,79112b2b) +,S(e1c688bd,cd629088,8d8820cc,df15fe8f,cfcf45c4,b8bd434e,2a15428e,818757e1,bc10c6e1,71e7c8e0,13b8e00,e77bb745,a34e7d1a,15267600,d130f6f2,18c77f7d) +,S(b1a30c95,123170f2,d9456de6,827afcc9,ba2bded,d955354,c6deeaac,68137358,9c76a0ab,c16c1caf,d3844346,9040373e,a678797e,dfa1b298,5a17d410,b04071f5) +,S(24cc27b5,fbb0291c,3468ba23,58f5e253,4c7cf99f,699af4d0,d6892bea,e6166e85,eaf369af,2516ba42,673c52e3,ff0768fe,d51aabce,2312b8dd,d7aa1ed8,cf9f71d5) +,S(8bb4017a,6166d1e2,f7fe8921,cbd31cee,bacab577,84da8a92,217aab2d,948f6a57,c899740e,6c476986,356e34fc,7182996d,a09cad72,93d78c8a,5c30d56b,88dc331) +,S(55d8b7dd,d82fdd96,e0ec17dc,20b303fd,e6dafef5,a527368b,ec99a33,60497f6f,fd624511,78bd66f,4361709e,44e72e9f,f4f29230,d1fff657,bbf84762,b7b8beca) +,S(82aa2def,5a5531af,519cbfe6,105dbde3,109d4626,ec47a845,5dbe2852,34c94df3,61160bea,9f83a2e5,8c2df91,925fbb25,8d1e60fa,6a147c4,ebc0ee38,cd811511) +,S(36c1277c,c6df7ff8,47c2cfbf,3cfa9198,804b03b0,c28e1636,ad3438cf,2cf6f7f4,2304fba2,74f81c74,5455d821,ea58e047,a7bb3b60,e32f020,aee5a2a5,16fe4833) +,S(f376fdcc,5b44cad7,e16c9e86,c00b366,d57b8925,fa49b18c,eb8856a,e0cd9119,2d6acd32,e4dee81f,489e3ef,11acfc8d,c3d0e7ac,bdf5c6ac,74fe7aa0,50a028cb) +,S(ea4e10dc,5372e9f5,d96e8ecb,907d3a89,97150b6c,39ecfd1c,c7aaacca,5dc5030b,b0896ea3,93b626bf,c2f486d2,9fdeb897,36d6be60,144fc3f9,5206666c,36d96ff5) +,S(74f392b4,b2664a17,9d3f0a2c,71b144b8,a376ea19,f1a9d91a,d181ca3,a6fdeb08,9bd4db21,428d588f,64ecef67,99b46735,c9523036,406d2636,c6eee083,e09e1fc0) +,S(3a36c842,59ba7774,a41a17da,f0e4c821,11c13a6b,58b82774,ca6962ef,cd4855eb,6ddad1ad,9ede928c,d65720c7,15ef39e5,f35e46ba,45d8ff48,2f095d2b,e0fa5e3c) +,S(9d77b2ad,5636a44f,16e73981,46b17ea9,7635ef18,8f32764d,eae50d2a,5c98c019,532dd027,a775861a,b9392b8a,cb2db097,eb5936cd,9d2f7234,f30c371a,22ee3eef) +,S(2e7402e9,450e2f80,e05168a0,f0c5f1bc,deb6117,ee46ac1b,39aae7e7,bea3c4ab,41e8f36b,5606fe2b,8ed6b3fe,f8821013,cf85721c,f242eb60,34b82afa,cd82fc3b) +,S(aeb2cb25,4ed0b5bd,81b33d35,e8f00a5c,6a6806f1,5314b320,de0c376e,533ebe6f,6b8116f5,2d7bfa2c,b3028249,fc83f317,5d761c0f,76833d0b,142c4d6a,29b9d59c) +,S(c86224bd,55d62c97,a00adabe,3a797929,4cca663a,ba3a3655,fbbcc3f4,5cca7895,a319a3b7,104f7935,36693adf,a6009db4,1d857353,fa950c21,844323bb,cd1cc214) +,S(1d1164cc,2c576a0d,d7b5a28b,cfdce6f4,d53ddde0,534b3a66,aaccfbba,3eefe561,b85890de,aa25d897,fccba694,7c470e45,ec600989,243ea91c,4670a,b44995a7) +,S(2b54fab4,13b915b5,ce76620a,5c493ccf,5e7f0f41,8bcd793b,92f26118,a440e3c8,8aff8d25,56fead8d,7e9bdfef,bddddf37,7a61ce4b,2effcdb,30ad0016,4f9bf5d1) +,S(1f1f2a24,a4e72a1f,609428ac,853e46d7,a9718c25,f2df9887,9a3aa60,5729b340,450dca4,f4920bba,bcf94f39,26871032,b631120,4b217170,991df216,2c421cbd) +,S(412f658e,e6777e4d,24e5682c,5007e057,83fbc559,f22f3200,f185ee52,c8ebd4e5,c2e0b64a,9d9394fe,b930b3d7,afa64cb1,c8399e3,27690e32,887b789b,6571c8f4) +,S(8495dcb5,567791de,976fec9a,367e250d,95102ef9,f92c11fb,f561f854,4cf4912b,65f809c5,7d3d824e,f5e63f19,153bda4f,542e511f,464e11c5,e2a9c32a,2a152443) +,S(f8e7bdc0,d841c95e,3a945b8b,c85ca4c7,b4a18a9,7a5646ee,1bb4ff08,5956cfde,cd0ac83,f93a3679,37c9d28c,24b9fc08,6d6660d6,15df5011,1b4edd5d,f0ed6d42) +,S(8324625a,4e4c1071,24876751,7df28ad4,8c8c5648,76e4a131,64f2f730,62854c94,761b1960,49922825,609c7ec3,70626025,de65e2cb,240b8356,1f5cc230,1f9bfaeb) +,S(8b1c49ff,99f87e22,af4b6bef,d353df1e,16a8e160,3023f2cf,213ed859,13ca04d4,cd4513d1,e178865,2d1cff72,822de250,6abbf975,7e2774c0,2ca1bde3,23ad6c23) +,S(e2ad61a1,20d24d80,8c830e89,d630b466,59deacf2,87aeb790,bcaacb82,96f4f138,51cd19dc,fc1c4867,daad2940,5acdc7ca,91849769,6003321a,bf5dbc6f,b2186291) +,S(e8dcd7e,a9a9a6f3,16a6aa91,53105601,e10356ce,7f4793ba,9eae3ad0,34c197a4,c835bad7,91f3aaf5,d32e2a99,e71c4add,95f69892,6a68695c,2e61ca85,38ea6b5e) +,S(f0b748e3,5875b8ef,361bba69,cfb05c4,d8643f95,9b207556,e46908e9,bcf81233,6a264e51,5d163a7b,678765f6,c29ca61,c1c0aeab,a9ff423e,91e9401b,2dd6e908) +,S(900de96f,9975a16,766dd305,bffe2423,e6eef8ae,93ebd796,2ce97d53,39af3a87,894ab2ec,d9c058a3,a331bf65,dbe69a49,f33f8e9b,12121439,650aa700,4d164478) +,S(8cbe7930,d2ea2342,730e306,7e9ecf95,ce7fbda1,e6d34645,a6e214a0,ed88aa53,867b156b,f875a67d,ae27f2c8,e232c934,85092c70,ec071ac9,919ddd85,70186b83) +,S(a0cbb1c9,5b35d243,945a65c0,fc5706d4,e79237df,c13583e6,9a292fec,9a25e68d,b6d7e9d1,3cd61a45,f81c8a55,40dc06e1,3c6d7024,5e850a40,55ba4eb1,82047e4f) +,S(148aac72,a3fa8cb5,aa6d3bbe,5e987fc,d8050c3d,63b47f4c,832a4488,262463cf,7f29de49,a6e24485,5aa45f6d,36f2e2bb,72749f91,8258c0b2,92a33322,677e4a61) +,S(3b9fed07,3a1afd6d,e6ecaf7e,fa20e2e6,c28616fa,25a218ce,fb07cf33,66f3977f,f0a85b3c,5084c964,a1f0c936,e96ad3e3,4fa9e7a1,348ed0fe,ac7003c,12c65fc9) +,S(7de45ced,5228bfd9,557b443c,30fa431a,7c9cbcea,dfbfe0fe,cc565ac7,ce3537aa,515ddd37,69107033,bcb794f3,ac55062d,78e0118a,60c98fc1,1999cdde,fa2686f0) +,S(9cc1a35a,534f562,98010274,74f3a857,c17cf99c,eba1d5aa,251e61b2,55913dd2,c092cda8,f30fa4f9,96115da3,7bf8e12f,c653e243,af2bc7cc,c691684c,3e433ae5) +,S(d82f1968,759b3b9c,c76ad729,828a7283,10fc71fb,22258562,920b690,7ab52ec6,54cd0a05,26983b0c,73808f8c,ae1c9d81,1b372082,dcac3306,c470af50,8818c607) +,S(16e6a947,3d95a95,c31bffc,c291b60d,1f9c548,85e5a498,24195ead,b87b7586,19e29938,581b6b8c,2e50d365,5a957c04,80ff4c8e,4ed73276,f882c558,dbd8aafd) +,S(d07e7af3,ee4f24,e46b4670,477c3463,ad57a74e,57a17197,ff098e52,3b5cd237,fff34e0f,43c91656,69b1019b,ef618888,d4d175de,b6f20b1b,c696f24c,135d0e20) +,S(2bf644e5,6dc027fc,63a118a3,43faa4e9,8ffe42b9,c983014,50a1f4d9,e5665380,bef5c175,77be1fc5,f8f66fb7,a06b55f7,eb84ca5f,66ea4477,c924f925,5a262ec5) +,S(518f0d37,db1db93,48c80101,442597c6,7a88107e,5e25fa3a,b97ed524,fc5cb045,dca8750e,a4e9ed01,66f113a1,44974250,6eb9f3f4,df8ab741,8dba0397,694d7294) +,S(bd48eb6,c50774a1,2be9893f,8c21f624,57bf54ba,8799928e,9a9c725d,6f0554c7,200a6da8,cd8f0300,6774bad9,769f738,dd58f350,632742d2,e2cfa787,f570f6e1) +,S(ccc8d93a,871169e3,69336622,b64fa1c0,800c5b45,e3c0b130,2aa99e34,db1517e2,40ee7e4,d45e6478,efa11f1b,c4548668,88837309,4809f056,11efd6c3,6d01d845) +,S(86f6392c,75877992,311d2e9a,27be9ea7,27e8d01c,fc27dab,8f4527f1,dbf6bd1a,7ee29611,b647aa2a,3d2b1304,c49ee690,57150518,fd46add3,e7caf34d,10f7922) +,S(e034f4e5,927b0fa6,c3794105,338751f9,9bb5a381,6da1dc1b,bfc41d83,b7d7fdfd,dc9f02cb,838242e4,13282b05,cbedcab9,e902567b,b279fb6f,f2248e75,41a5f89d) +,S(8fc36a16,a9dbf00,5ee3a66a,b825510,75eadfef,b86e1062,837b49cc,6ab51045,c7ee2c40,9605981d,217d9957,a004a4be,66a88527,9ec9f74a,70594999,23d200a6) +,S(d7bb40bc,54077d96,d6489b71,e65dcfe3,997130de,b517d12d,9c10adc8,e73278e0,e2096366,2f64bae4,5aa0706b,d96b5cb6,5897c0be,3a8a9b46,8ce9074a,a68b0a4b) +,S(d7357685,8054c714,1147d2d6,c265ce40,3c882681,157b07e0,b8be0a88,63bd2ac5,94f8754b,2fc94239,c254099e,9cd5804d,d2ce03a5,380c59c2,4f42ebe5,85a9932b) +,S(5b6f8aae,d9353ffa,71da7e99,bd3fe165,3e720ffd,657dc2b6,669ae0da,858f8392,4eeafd05,369c6eed,fa6f85ec,34e245f3,e4966840,30253c10,6e74f473,418f9089) +,S(39444d12,67cc29e4,384b4f4,9c4f4886,ab4076a0,19a0fb39,f7b72c4e,42222000,65c2502a,af90ee2d,8de48adf,35388eb9,329f3057,1b77d0ba,50ea01a1,ca83d771) +,S(53de00db,f1efb0a3,c159c4a7,dbc9888e,16ebad95,cec2d003,a18488b,1b0752c7,328ecbd9,99475dfa,752d6228,5e7bc51a,87dc6166,4d14a6d3,3a556322,5e2fbda) +,S(48a3baf,9b4f7213,e280eef0,d5fb6033,194d1bce,eb48d9e3,d4814a4c,bd5ead39,3b4ac9c9,e04a3852,bbc6f7fb,cc94b20f,7e749eed,44a9a9ce,7099a8bb,28334186) +,S(f00d7630,503c1ced,3c418237,27e22d7,acccf406,fa16eb6e,b524707e,5b3ac541,9a1ddd3f,ec177626,b1254605,df8ed593,c9e2bcff,db7d0404,f47571b7,31ca95b5) +,S(e1ff1994,3ce7eb59,e570858,2e8c21a0,c4f8eec8,40815ee8,9a482658,8941eaac,528e5572,746e72e6,ce61b53d,78aa57e9,dbf27e3e,bc36c3dd,3b4972,d7353b7e) +,S(e4f13c20,c48e750e,e15a665,275c27be,23b3aa04,5915ac55,2562bef0,7459bd49,bebc7ece,c6e51f99,a2e6b9d6,a7b1bbb3,63901053,362a9ebc,a2d21cc7,6e87ca30) +,S(e36e8cf3,824b66e8,7083d371,60cf2719,598c6c04,ac693ea4,d2dd5c83,886f5f20,4ea0e193,8afe57df,3db74910,481a54dc,f5be9fe8,64f249f6,c88d0cbd,a086c60b) +,S(51e1f319,3286d2fb,29cb4a06,84d7c547,797ff5dc,fde9572a,63dd1e0d,2646365f,ac470e3c,6f30ecc6,31a90d7e,6c4c3d43,b8640ced,b9465cb2,ace2cc87,52370e3a) +,S(8e82daa9,c40d4e72,605dadd6,45bc26dc,22277f41,56d2a248,29bcf79c,d5a5fae0,7f8155fd,be9057b2,2b191dd7,233e291b,b01b961e,32a124d7,33ad99b8,167c53ee) +,S(79e56744,273c7aa4,34ffd5e9,525fa788,38bea674,64e2a595,9881b359,3e2c41e3,625089a3,c50defb9,f00ec764,b47122d7,eb786a20,f278bc33,e806e7cb,f385ecab) +,S(a97e00e2,d19c1957,51deb891,84e24a22,af7fe156,f2f1e068,79ded3f6,62743f79,881d7ebd,8bcb2c49,354726bb,c44ff91e,f3f5835d,ea73b282,944a5097,cd8284a0) +,S(3bf10546,7bbf5c3,14e1c3fb,40542378,9bc52fbe,8fb38aa8,f4a70727,b338542,e789586c,fad5b7ff,6dc68e5f,ef840e05,9a87ba51,e58462b6,39042c64,24f6367) +,S(80296c77,58791dff,39b4ee87,ecf3406a,49cce0cf,8437fb2e,1f4880b,55d9cc5d,3b06be11,3c7f781f,ce28753b,708bc514,902e4834,bdb09284,846c4ddb,90152dcb) +,S(48e2cb7a,a3eedbfd,f6a9cc12,359c4ff1,b7b0fe4e,87e57023,59896506,20ba52fe,dc78417a,fa909bbc,594411ba,87f72ee0,a0a45631,3cff4aac,7ad564b0,9ee8ed1b) +,S(dc91351f,cb775488,286b482a,a187d79c,31a3db2e,99730b6b,7b4805a9,73403d46,ed720e0d,2d13192e,8c180ecd,5e09fa5f,fc52e35c,4e509b2f,fa93ff96,f7adb1a3) +,S(5d37c139,48ceb4fa,9cd05b15,1fb344e9,3a2b2653,5b052b9f,1797319,e990a670,f790933c,2590ba48,7a832ad,6b940634,b62e16d2,7c9e748a,1856d53a,1974cb01) +,S(98bcbab0,f8d69b22,6fd7eece,a848ff4,15c8e325,ad9e8157,708eca17,77070aa2,7671e3b3,db715487,e6affd61,5218a7ef,a08aa949,9bb10206,e2de58d,ea150212) +,S(60e2c1cb,3de9486e,fa594384,d5903340,12ce308d,2247a18,8fa5c112,3f35b1c5,6de7031b,9767c66f,5c3c11a3,853bf722,4d58d086,b68e08fa,63942f2f,9369d1bb) +,S(814716c5,aa8256b7,50bf2f70,2e2f9bcd,aaf513bb,329eb467,d873ea72,304885c7,eca644ee,8fa96189,13fba31e,23533de9,eb7efac9,a0fcb58,6300a42d,c7d297ee) +,S(25789f3f,1db412ef,af60f7b,636686d5,9fb71586,200e8e3b,e6d934fb,72f8de77,e5222798,99d1e21b,5734a6f7,7881a686,863bc03b,8c58cce9,633c8302,2c7de0ac) +,S(5382f40c,98bff8e5,646a87fd,f3fcb6a6,27f2a91e,780a1527,ef18cdf2,a0f1bdcd,231d01de,e41ca3a1,da068ce1,39d97a16,39c027d8,38c7879d,9a1e85c6,4a32b502) +,S(448cfd20,9db2fadf,fcaab14d,8f57dd01,67d9ecb3,f18e9dc6,e573238b,a11d1f2b,bad8e2e5,5a4f56c2,435e8d18,14d2824b,2ba1bb67,9520587,5a11c315,9166fea6) +,S(d917ca4b,fe6335f,5012b69d,5444bbf9,f6c4893d,eb612ab5,667afbe8,2e5653d,3fde9a4b,e6a49756,27950f1f,f17ce5f0,aeabc055,3102c33a,4bb85bae,f32bad17) +,S(c7ee9f5,17a883ad,733de053,be3ef583,1dd974e6,a4e8570,db35f24e,91ba8f72,8db7738d,26d367bf,657d2a31,c6a08ce2,e06a7e4d,2df39f3a,2bffd062,79bba44) +,S(83f0a19d,983ed6de,7a2b173,77c843bc,819a77b8,a32acaed,b7085e0,94d9a30b,d2ab3e96,67be4473,d8748b63,6113be60,880acd47,6d574e00,c37f4875,2cafe6a7) +,S(f3f8aa6a,61687c40,98fb56bd,e74d83dd,59674079,7c52f2e,2b299277,2313989d,3a690c9d,98503a3,2d201ff9,a896365c,caa1b54c,36857a21,ad63994f,41a109fb) +,S(4c1a11ca,a30bd6c7,d95d6e8b,3ebcb4e7,914fdd40,4384716a,283ee1ff,5032249e,e7e718c9,4653ef40,d214c604,e65339d0,6598f17c,37f82880,9b7e5215,b9424da0) +,S(2941b952,3419a018,53f3bdb0,420f3182,529ebbc8,5a1c8f6c,1d922c19,3ee5477d,377f226c,29ca66a0,aaa05baa,7f6c1ede,80482b51,8982763,864392dd,3e628413) +,S(9d04d07,aad49af8,65bb3eb1,8c7078ac,4b5f25ef,e18572c3,3842161d,8591a6a1,f572968d,ec2ca89f,b45ae02d,119644b6,779eb0ca,1d48f724,f8512ba2,2c83cd34) +,S(4401f767,c3c3a101,b99a983c,9a622824,d660c50,177bfef4,a2646b06,43d26e20,7952faf7,8e1b114e,16429309,1d0669e6,999f8bde,ee980c0b,b7d669de,86d4e342) +,S(94b6f427,fc4017d3,b328665b,acc863a8,ab8a1c4,7b283fa6,8d7b7f0c,1bbba31f,1336067d,35f0d2d4,6ec8199e,99dd07a9,9cbe7725,a9981868,e09a0217,df40d85a) +,S(41621ba2,92c79bbd,463b87cd,de75574b,f2fba59f,92025445,7389b4a2,4de7288f,355337d5,b6f30b78,81389951,fe67b943,3bc70a07,b294d11b,717ca2e1,a2cd3188) +,S(b0838415,6256c1d3,55900dde,6126818b,8a9b27ba,ab14d73f,c33c399e,fda3594e,2aaf9190,55b162e2,91cc5371,b6a4285f,843ef8d1,5069ec7d,c5d68475,c5a954a5) +,S(cc99a14f,ef418fea,5de9f437,7ccc1426,7d910f13,e8448fb,8ba92746,6c0dc9bd,2e30b64,7c01c12d,d42f164b,ac0c9bf2,22f7b3d9,2cffd7f5,c77aebb7,18536f28) +,S(8d2bb24a,dbec1858,d565d59c,1d805d8e,7b21d6b5,b967dd50,a2f420dd,5764e37,cdc6d730,e78daeba,712537c7,8a09322,fc371d0d,6a5645ef,e7014bf8,999f712f) +,S(63cee6de,f18cf4a,e6ca1871,7750e328,dbb94c6f,27422192,3b233a3,e50f7c9b,81230dad,ad2d233a,1b631b8f,7a885828,ce005031,e1365436,7ca34173,1efdfeb8) +,S(62084e9c,1dc6dd03,9a68d5cb,fba19dda,b2e4d07f,b8f46114,926a59e6,92755a0c,6dbeb4f4,62fb1af0,dc273a,aa827e0a,cc9c7f1a,fbcdf02c,c4bd98b7,5061a26) +,S(110c0eba,f65b6280,14e368ec,17072acc,3f34a937,7df79238,c2773625,5d8dd827,1a4ba716,6f236258,961d5865,b020b83b,c3c3e74,2dafaba9,649ff85b,2ae75c6d) +,S(d848a51e,50fb234b,a807306c,fab97405,baa50a5d,23cd12b6,8927c9e6,f1c87e00,9db9be62,88fb00c8,4cae4b1c,c99449ed,51fdb49f,3cb7aadc,16a72b6f,a96a4fd8) +,S(42311893,a2706ab4,52547f3b,3901b9ee,a8cf2660,581b0023,96bc9a7c,e14c2b5a,750f86db,9ba6222c,199c2a9f,77609a47,d6129a1c,e9ef4d70,daad3d2c,ae4165bc) +,S(4439c4ee,471adc41,32f45496,77ca1e32,6b252f1e,5f17f741,9fdaec0e,3834d37f,bd75c32c,22c5c3de,62f16ab6,6f86f93b,617c9565,b3859195,81a00ee5,75897e87) +,S(4dfce3da,b19231da,648b0bbd,8c52fdb6,e02e9e79,9806fbbf,36bacafe,c113b053,de8c5f1f,4b727fba,440a1c3e,147cc1a2,9d647c59,42feb42f,69d45a2a,13042c3a) +,S(3bba2b2e,e8e72736,f54f9158,281f6c14,9d0ba6f3,ec6d89ef,cddeff9b,8117dc9d,ff087274,77897e56,e5e93f94,7af6ca0f,6f9a2186,a6a60d2b,af690a30,da16ab24) +,S(a2fede43,37bc6b2,482d92ff,f55ab0c,e239a00f,4fbb0595,27f7d67d,8317deae,2a791508,43beffd7,ef08e195,d0ce022c,f780116,2f1852da,98c3638d,45869ed4) +,S(221c4e2f,f503eb4c,4a1aa8e6,77370085,b3d64d09,8430a185,2cb1cc3e,304bc0a3,c3c37b1b,f954e79,c124fd70,ad3f8765,a70a7929,4a262de1,99e11dd1,95b7ae41) +,S(a0c32f80,f7e4ba05,caf945b,49b91306,f909c8bd,559e4bfc,a58ef3c5,14740ed0,d3eb8f01,46ab4700,41de4cfb,dced45c9,966aa1c6,38a42c90,41ba1891,36f9562a) +,S(762e7a18,b4fe627f,1e1ca7,57740811,bf33395,cc962aa1,dff79be4,18da85c6,a0df0f46,50461c0f,4f8a743c,3455b842,5875f795,4af56b93,dce93234,c4f51ec5) +,S(2f02d935,cd95caf3,d56cfbe4,4337b1f,78389f34,1146f561,b8d632c4,b93a29f0,173470d8,23f190b4,f8008872,b23f1a32,9c45441,c12fe87b,e74e927,18f44569) +,S(c9f877d7,2eb816df,1c5adbd5,9fc98a39,c5877d6e,24ef1612,314e6392,e7eab212,14ce9917,88cf7eec,5a5a52b5,8fcaa9f5,88bb0052,754b3ad1,b0858e4,6a067c4c) +,S(cc4dff69,18a05cb7,a6f296df,6cbf5d0e,d6dd1c23,ae76c5df,239d2179,a0baa172,1cd438b1,b8471750,261b0650,663b4a56,e4dda0ba,b5390cd5,b7869448,654a4dc6) +,S(faaac74b,3ed2713a,29c10219,a78acd51,ca015a8a,65646a5b,cccec828,efcbfaa1,adcad43b,dcc2ec0d,bd65c46b,7fe79549,b2e74cc9,13fbcecb,f8bf661a,7d30d934) +,S(171356c9,30fa9bd0,da1444b7,35be6c0e,8a0025f2,3d1a2480,dd0aefc4,44fdbf46,770e9edc,991efb9d,ab44361e,d2398e54,62e2464d,2ee2a14e,b2e149bb,9c9bce3f) +,S(933f56a,e0473763,d2d491af,55f9fb19,c055017a,7a81b43,b641007b,e5680214,66059c47,481cdb63,481ea647,f494e541,ad1d70ff,93b1eba9,f85a9cab,a0ea76ad) +,S(a300f22,b182ad37,d7e44691,bc9c9c9,8a397f76,1ec1acf6,64ac1fe0,5bbb6b34,bd6f2ffc,a90974b9,460de269,4722f215,684abe44,6228b500,7b42bab4,5433593d) +,S(fc5e57ed,6e901355,f97c1d62,dee4d630,878b79b5,528e3fd6,85d6e3ec,af8fe1ea,1122127a,6c21cbb9,e598b1b5,68507bee,bc7c8549,345c9d49,8c4a9b2b,2f5bab01) +,S(5a2f40e2,7a64811f,bd4721c1,99019523,899e956,ea340bff,f3f452fb,5231ef3d,6b2bf95d,12578c79,74a06d26,39d71c31,d8c4a53a,6279886c,20a122d3,2093d547) +,S(59783333,df0b99c5,be76610d,67d7ef62,fb15757d,8dd1f310,6f9179b5,64f2084f,f2a9ea80,dd3d170c,813f4623,ba7583eb,7d309d97,c34f4c4f,a7676694,7e5b7f5a) +,S(cf61124,6b513fc8,73f72bb3,87a29c2d,a1c8bed7,4ca7ca08,1546db1f,37672d95,d23c3c76,697f0443,9ed1d1a5,661fb0fe,1e182cf4,2e07c787,3eff7abc,2f8c70ee) +,S(edd14f05,133a1480,e26eb7eb,8063f8eb,1cb871c9,606957ba,ac14b173,2ffe7d52,d682f280,d295d528,4c1b3aa8,445c274e,ee603308,ca4792a,61b5f8d6,34b1b70a) +,S(f9b0fce9,cdc8af3,8b26e790,2c95926c,33cb8d30,a5de80d1,75fd95c7,fc1a1713,ec7e8df6,f3d163d7,181083cd,c8cf4a89,df958b8b,d6fce2b5,d4752240,f2a3e6ac) +,S(ae906599,54187f57,89306981,7417c566,d9ea4315,f07094e4,e46bfd24,1746a3b7,2241bdad,c09d3313,e9d006ff,2a04709d,17335573,5be5b10,6775457f,231a129b) +,S(55f0f800,76492f7b,f5e134cd,e581ae3b,f68fe9f3,44107540,c54b350e,47d956e9,22a0891d,e68488a1,dfbb4b8a,35fe9835,e258dcb5,c70ccb98,2c8a48cb,c33956ff) +,S(90c8ab06,86fb40e2,31923bb1,df86647c,6cb7e3c4,c451d0c1,b871994c,19663bbb,dc748cd9,570eeb2d,c6fbb2c5,c417979,cb30d718,94c8e463,e3b7be3f,fcc80ab4) +,S(cbf47c2d,6b21ebb9,fb268e73,56ea849d,3e476d6b,ac09eb60,4bb2e27c,84a4c694,f0288fe6,8042894a,39abf8bb,e5962421,416ed9df,dab081cf,16e86fba,7abb2873) +,S(7c30885f,c18b68b2,8fff758,2148d738,d8f1bfb2,46543b16,37e9fce9,7d11fe80,3e2d1cb9,31a11c15,b26c6d37,8c886e10,52c06718,a63e621c,7ea51c76,3c013f2f) +,S(ad614919,d1bcba0,dd2a9da9,de9207db,e137c772,37f333e6,4f11433b,f66d7753,fcaea18b,3512a188,9d604619,2ba759b4,190b72d7,ec53d0b,aad9e01e,d239753d) +,S(8df7041b,af8c9c15,70ab50a8,1ed335b4,a7bc4171,a3939715,a295ca7c,4e5e29a2,e892e43,82677bdd,f3566b24,c7ddc6dc,e12eabc3,84a19a13,99b64ba4,bdce02e7) +,S(9f4c1e57,61c8520e,9a751891,ac1bb5f6,217f4e77,7dd88fbf,2a127804,2cfdadd6,fda210ad,c6cee889,c35831e,b3e12c7a,ed4b6963,9f3d4860,9d9b960f,4e7d0f50) +,S(a436f4dd,23ac70a2,c093bacf,91de3093,174de618,7525947c,2ee8ccab,a515acbf,c0e9d9d9,2a615b9a,9439a450,927bc128,5879e8b3,7d460ec,9fe57eff,7e19afb9) +,S(a38eed16,699743d9,16d8627c,5039695c,37497c67,c59547d5,67bdfa20,b86f1930,6e3e3ed6,effc3b5a,c9b5b5fe,3f26c91d,3be89bb1,48414c18,bb0e5454,49d9d7fd) +,S(5f4590d2,d4043a1,faf659e3,36b0f24c,b6f1de5,88e92586,83361eba,e2fbf3d6,250c0a73,42ceec0,3ec1af11,764e7ff6,ccc833b7,240466,15890be0,55197db) +,S(7565860d,c6ebb900,68ed16ff,8f7282a3,d52beac7,73cebc55,1be51f44,34cf56c0,4b56ecbe,526ed458,5428ad7d,e9d7f3eb,9b84687f,e01e1346,c32461f0,bae24c26) +,S(3e7c7fce,3a56ef01,cabad50f,2003a5a,77292742,be80b5de,c537b50f,95a9320c,98cd94b7,926e7111,f3778904,599fa9d9,d5dc342c,c495b914,a32d2722,93dbfaf1) +,S(131eb457,14cecf84,abf1aaf5,ec4c62ab,2ac91a0f,6af57552,2eb07274,b7cda208,a93aed4f,f0512604,46c61393,faec55aa,9b017a13,60d13031,27bfd897,e320839e) +,S(371bc601,e46963d7,388bff6,9c4b5f42,a98e68e0,2db3e6f1,637dd24e,a2a11ec8,e2fbeef1,932fa241,a9785238,c1b89269,21bbc7f1,3aa6bdd3,7b39d94a,49f84622) +,S(4770db04,92ca73e8,a0136bc2,2c45185,b4d45934,e4430237,1bcf5045,cae47d6d,e1af748c,25b1d906,ab77e080,d21df4bf,99a92f7b,4b1d790a,f1aeef36,2d41ec22) +,S(b31a8643,5af5db57,759dbae1,67ce3af5,e8e2ae34,20786fe0,da82812c,9594bfff,3793425e,860dc99a,a96a85a2,585b06a4,f5aaabd0,551fe0cf,3c743be3,c09aa4a2) +,S(e05eec52,84a2501,fddfe6dd,1619c374,a94121bd,7d1c99bf,9b2e665,bd3631f4,c0115f17,2122f806,99a24ea4,bd742425,4d883d77,6d269ed4,f6cc5626,ffb8e622) +,S(e55ddc84,ee407d3,45b84305,d97d3f57,e57810ef,bff3b35c,e4d8a325,2973d5c8,71f77bb5,b0fa6141,7e43e425,78ebb13c,abb87a6a,fa0cd1a1,26e8936,427ee677) +,S(ed7b6ab1,a5c8a9aa,284bf3ea,5501d33e,1aabbe76,f26a9f0e,d46dd23e,decd788f,2280bb54,19d1a620,18454a4b,cdfd82fb,824027d8,c51770d3,77233e01,1d0db63e) +,S(d4e331fc,3da4d8ae,e13a3329,acd4ee69,ce5cb71e,224f2001,f9606714,8090e79a,895141aa,2f63cd30,9f4a6b42,d6a88112,77821e51,6d08c52,1ae8e158,655e10d6) +,S(4f0ada0e,a8ec1ffe,6682545a,bd8152c7,2654718e,120d3d54,d648b487,896d4417,a603b9ac,6026ab46,47f5acf5,5a9fbaf7,20aaff54,56c88cd4,dc5ec7f5,935aa591) +,S(a2d13541,b08eeee2,4f086a9d,20df7528,a884cc05,4106b1b7,543eae3e,fdca84,5ac0b166,294d6b91,527a5249,7fd605ca,4bb67c35,85e002d1,74503b7f,5c803a45) +,S(4c1d520,14a0459,2b8887fd,afa945ff,cbfc4722,2ce008f,64fe8123,b5b6c8a4,243c4280,17b7918e,57d06597,f348efd4,ebcebff4,3950a608,3bb3e334,50ed738d) +,S(5f9e5a6,7d13e9b4,cc35b8e6,b2305cb0,fc2f5b7d,ff32ac55,1a5970a9,2bc54390,74808637,96965f7d,bc45833c,e8bedf00,85eb0cb7,26f3276b,30d9543b,7395ff6f) +,S(d76c6f80,95381b17,80ad28a8,80e29ab4,4447c297,34a4d286,98534bca,8954575,44b6c3f8,6b30e01a,61205178,90e429de,aa8273f1,277bc498,59c87300,a561b27b) +,S(7577729f,f78775af,703a9eae,b5864a18,6ad19f1d,dac658,e7a8a05b,d9df3344,6b519916,cceaaa53,92d2f822,98e7ecf3,3fa7c5b1,2e705345,32ec3f99,2f0afec9) +,S(50378f2b,457f04ba,d0b19425,86ada992,78700c8b,36bba67,fca916c5,8edc17db,cbd1451c,26bdcd49,1adbf40b,ac5338cf,26957364,f82fcad0,5fea3c2f,76273fc1) +,S(3748dc68,64365160,26384ba0,ec078ff2,7606eb44,e3d62b50,b9138be8,cc9ba86c,6c04e414,f624ae9c,ddd005a0,4e01828d,6e7bfb81,d350d271,96583c99,6611d709) +,S(b23a59be,8ea8d561,fbdeaea4,49eac729,3402f342,d05fd404,7f9c5d1c,57eea53b,bea47c68,f2d35b82,ce3c359c,83f5fa1a,95d40eff,702ed9c4,2fef0e84,406dfb9b) +,S(e4b451e8,7b42a5be,5c5f443,5701d2bb,9538fc06,925ccb49,ebfd71c1,16a64770,2af84669,9a790749,48efa86b,2b79b985,4cb261a6,8a9081e9,e1467b77,2f156da4) +,S(864ac6ec,65b8b086,346e671e,8651ddf9,de74a215,64f3da12,42ff7548,96dff165,f35738a7,7ab48555,91ca5103,c8d2bebd,b2cbf902,dfa93188,d68eb600,271a8730) +,S(b7d04a3d,a6a863d9,b7809022,56643864,fd36c5d7,9a056ac4,ecb27257,f02ecab0,cc40634c,6ba5dc23,e59e4e3b,fe6a07c0,1519abbe,7530f1a1,5ec7ef70,6f83b0c1) +,S(ddfc1af9,b51eddd8,2020de0c,4a8377cf,bd6e2531,ebc844c,7ca8fca2,714c1a0e,cf77c8c,1742c4e8,b22d9f54,a25daab9,c30f23f4,da3e1ad9,57b9660e,3ffe3951) +,S(78fcfe69,d5bb91e3,a13de26a,614d8479,e00c828f,8868fc30,ea75b47c,d51fcbe3,9ec67963,6b7053ba,b0cb231a,ac28143a,98021b48,4340f060,66da6e72,47f2d47d) +,S(dcd918de,16961d71,8222b4f8,19e76ecb,138c9884,7833a8fc,d4204dda,1115863f,abc3d8ba,c8d808cf,ca12318d,d13c2932,3ff7fb0d,813a5ed2,f5e52aba,cb23bb04) +,S(39ce2ef0,5de08106,93294eef,537bc212,e6f64fa2,96ccd2b2,94a0806c,c6c3177e,25eaf4cb,b7697a3,97a0ca92,6f3a266a,bbb5dda,78943492,39fd29db,78730556) +,S(495e4db6,43d4e89e,df50e937,e97ac4ba,1464514f,d3a46b5a,bae6a53d,3157a04,7d327e18,b2960d69,ebe4251c,f8c416b4,f84bb81b,a20ce6d4,6e6b1c57,e6ec1701) +,S(91c17e8c,b6357c0c,1c36dde5,29f9e6f7,a6cb6e97,f5b67dbe,fcaf5b96,637c33c1,2fe52097,fedb8ac2,efde2692,20f586af,f07b76e0,f685ce85,c965ec1b,a54c39ba) +,S(e3c4f480,3dffed44,6291f11e,cc5c9590,1c28749b,d6ae18d4,c0371221,d5ecfdbc,5a2e7102,571e27ce,974ad71d,acef8b28,4e7fb827,5453e40c,65b2be92,cbdc62d8) +,S(b3ee17f5,a0e81e7b,48814377,af9dcbb8,59ae7bea,5680f33a,cc15d8ed,75c25073,135a3c0c,9a6d2825,a6035afe,139ede23,b46332d5,5739ecb,6d092e7d,6cbfe86d) +,S(e4cca844,2bc91bed,342628e1,f6492335,7ca6e8d9,5e5b5732,29866066,eae76b75,dd55a555,39b5670f,f70b42b0,f319ac72,409f74e2,31d9cec,ecc8d90e,516f76b9) +,S(ab39cfc1,81c96089,998c02a4,64eae7ae,e517e4ea,962b6359,b5ebfbf7,da223b2c,def6dc57,b4dcbbe2,e6dcfec1,8281a189,72ba3b50,f996096,a22e4ea9,77d2fc4) +,S(22a32663,9e6e0469,fe4cad40,964f081a,677572d1,94b3ae01,f8e45c84,dfab402a,1c9c9d95,bd4e0ef0,5acf6148,44c98fcc,db44cf50,5d42af26,1b855f98,40d2b437) +,S(2bc788cc,eff94bf0,307c5ead,4fbc4dea,db269da1,7790a903,7c2fcc24,21f9cae9,172f3461,648c5520,44081c43,a8c78c3c,ccecb248,9d60d384,aa703e4e,24bc4b41) +,S(b930dbd2,a6720601,35a75bb8,8bbe69e8,3872c636,9fbcfe4,c622a300,2052729,9983f03,a872e8b8,2830e7f9,a7438b39,ff3f6836,3334debd,83940ff5,ae06f366) +,S(b435738a,2aa9ea40,702db448,da6f186f,29bcd03e,872a3466,f33b2e39,7514e3d3,5828d246,2d3c671f,85617e55,bcc34905,1678cb8e,f61c74e,92c54473,9098636b) +,S(c91f2e81,3acc9baf,2c52df27,d4180dd6,ee1fe67f,9db6223b,532dffb9,3072bd25,1c9c57d6,96c12f13,13afa0c2,b377e1e2,b027350f,bd24f455,69c15f07,85b73c0c) +,S(bb0946c2,8099ba93,8f28068f,416d9003,bad0d06,f8c7d31d,2b995f00,5c8d36c8,8e3878d9,3b575fe9,78fe1a62,1e978f28,1560421f,7782c164,8673906b,ed76da4a) +,S(485e3aa1,2e823374,cd506521,a707f367,5298dbf7,cb44f398,c31a06a4,8f085c8d,a12c8af5,7079b2b1,5a339d4c,302fc262,af0153e0,dfb4f878,a4b60017,86ca9a61) +,S(850f9448,d3282256,940da03f,e8a96eaa,f21d02a,78867db3,e8a9fb9a,713e844d,4551e4fe,3201ba2c,a74df3a,f58a820d,3a67836,a5a8d82,59ab2442,3bfccb7b) +,S(a74816b3,f66c1fe4,9f8e51b1,8eaf51d9,449cd4c0,54b6dc43,682c853b,be39884,4e7d5fb2,47ed7ea1,45af0cfd,c4cc1059,396626e4,80ec804f,15ecef7e,b372f7fc) +,S(2af5c56f,c71da217,79abcc1,73412016,e1eb702d,6b98af77,85ead6b7,7b20136d,7f3110a2,c6a82623,b2c49e95,a31a6b8e,783911d9,b532932,1b651541,86b706bd) +,S(9291ec91,a61adf1e,90d63135,fae60edb,1a313714,97260903,9684fee4,339b5834,d530506b,e8b0dbb3,fc09649f,1832de93,feef42bc,ade2de09,bac1dd17,bdd03884) +,S(160ad3c3,659a7816,4e9cb47,4e18ff6b,a8581fd1,823ce8e1,14444292,cc605b54,1618464d,5f28d719,a61f939e,b1eb91d9,a59f2c1,818dbb58,b6e1f426,a4d141fe) +,S(352599bb,8640920c,2d85a5d7,673dad8d,ea4280f8,6358a572,b4071934,60ba9d58,a78a591b,e8064f2b,22d7707a,d3c95cac,aa2ac3d8,638d564a,50f7d1c2,8b538d0c) +,S(ec20efbd,9a8c634d,92f7a728,1e9e15d5,adb37ce1,2236bf33,4d12c4fb,7b6ba527,acdb29bc,2a5a3115,3919315e,27af9d8a,e8c54792,fd5421e2,a9a57b3b,d51b70d) +,S(40d1e4da,8bdac6ec,55ee847d,c59781e9,bbd38785,1863c64c,5cfad460,e2dbebc3,c630581c,b7c92e68,a67c7d5b,dba3ec18,4e3755ff,27fb53ac,d3a2655a,316e9ab0) +,S(fbe12740,2faadf2e,2b1ac1c3,98b66df4,81674c2d,f0ffb512,7dbba444,e7d08c7,d00edcd7,f97914d0,3ac87182,14491698,f3dfee34,e6e8587c,52f2f7b8,b7f412d6) +,S(d781b5a7,47d191fb,8850fbd8,fb1e123,4070d9d6,2643008b,b0cd930d,c191eb03,a4aa95a2,5c74ab55,f95f2924,519b2911,9762ef30,248db792,d906b18f,346afa11) +,S(6472fc42,d926bc7c,115045d0,395b5e9,22790c39,ee520529,44a446f0,9ccf02cd,512014,a92593de,e2264e37,633c842b,45d1ab5,e2ad068,63db7894,4605a99d) +,S(eee180c2,e09601e8,6a517a93,54607a2c,5fa6cf26,4c80ffd2,c5715ed6,395e0c21,c8cba798,221d6fc5,b4fdaff7,f785ca3,49490af1,ae655711,e0649669,7483e7ea) +,S(900b262d,a172ad41,15bec071,c5763077,9103bed4,db500ab4,fad4b750,45ada2d6,316457f2,bbadfe91,3f418e7f,b3fa34d4,82c4c1d8,516755aa,371423e0,51e2cbaf) +,S(7e93db87,4e1e5070,772d3371,b9ef29d1,5d5e03b1,e66bce20,420801a2,13a34c9e,cdeaa624,750032a6,f5faa0fe,e00cdc10,63f3ec47,b5bfb56a,bc2c2339,e38465a8) +,S(461fb424,65f3a55d,e66761b8,44abfe3a,d172877a,3edb1f5,da98c82f,89a379ca,768261fd,ba032718,f5501dad,c05e41c1,1f584aa6,6b8e732b,7f15285b,18e815d9) +,S(1d9f581a,f0f61a0f,e5d0f0cc,91ba4f93,6de28aa6,5f35059e,997de778,9419e09f,7fe9c98c,7d59dc56,160302e1,89676f54,3f02db1d,622251f8,adf369b4,891bf6cd) +,S(8cd70b52,904b2aa7,240f7a70,e4efe379,66386dff,3ccdf62b,e2343821,767542c6,b3c3d03f,4c7e0b1f,f08bb2,f72bc6ba,e9e293d,886541f1,ff86bec9,b5ddc2f2) +,S(a0b547ea,9c08865b,99a5b8b3,800daefd,99097b23,4e442a2e,819aa628,eb4a5261,607ef115,e585100d,c003cb4e,1a27eb60,fd9d1e18,f2d23a22,80cddd89,f2ca2952) +,S(ea8a60f6,547038e3,683a649c,27e81ab4,192406f5,5fdbd775,78dd6360,4344d289,98afcac0,b05ad5ea,8fcb9f3e,3bc22f16,881b5fcf,5060c691,ac10f746,79822fb0) +,S(e6051a9d,882f9ef,77d488fe,55bb7829,48bce506,91350755,1a8cd4a,14b0a711,1c9cdabe,9d9eb555,cb9257b8,a60af75c,c1ec0c82,4d933498,ffaa14f6,2e920fce) +,S(600876c9,c50fd337,6ce5efb,c07e0e5b,165338c5,4f8eaa4b,39a525e9,88765674,401a671e,f52b21f3,83df5da0,aa0b215b,b044202e,606a746a,213796e4,dbea4189) +,S(3b045b9c,5ef6fdd0,9b3efe12,169e0414,3c0eca56,5b7e0185,274f1e97,f6b2ff40,aa5773ac,b21107c4,2a8085d0,5d6914c3,a135a47b,cb136dfa,d20e6813,62780a28) +,S(dce98d32,ee0b55e0,4d67807f,ded9cef5,f9504b1d,e552a2dc,643ee7f4,b1f0f1b6,d03ac27c,9e992497,cbb746d6,7acf5427,aba058e2,801df1b8,d435a1de,1f3fb086) +,S(365b1148,6e8a60fe,8a91c07a,93686787,dd5aea7f,22fa1449,58be984c,e378fd76,2c7f5217,319e5d50,4c5ecbbc,bdbb8ec1,b36e2767,54f405c3,f852b761,ef01c9c0) +,S(2e37935a,4dc465ed,ee8dc3ca,d4ede356,3c3720e8,57c986cb,b9c73b2e,ab6b5806,bd0873f1,5278f46d,802dc7f9,d7f81a4a,839cb690,10c6d522,c0e3945d,4bce346b) +,S(49b68e1,93745ad7,b60ddf92,70d71958,81cd8585,6e47b0bb,fbae94,f1647568,ca1d4bf0,13e43ef,53bcb2d0,5f4b85be,1dc82d31,f4a7795,755693c0,72819dc1) +,S(6df53d6c,c79c5a88,2c2b6f66,e9ede075,6c8cc6ba,3e60620c,b8130fcc,fa744564,48c3d6ed,3b2b7c59,2472f291,41a61495,4597f77c,afb576e1,729804d1,26431344) +,S(d99f8f06,9104e3b9,26163672,767145a2,2f9467c1,c8e32b8b,d28e170d,bf4865a1,ccfc46b0,55aa5d93,64e67c4e,2c06cb18,c2b43333,e4111479,fd1bfe50,52543d7f) +,S(77727c17,ebbf8338,ba807572,8558a059,e23af7fd,c68c342a,538ead93,e59930d1,a037dc7e,2cde1802,fe3bc65,75f50ca4,ede75194,133e7083,66de0338,40c629ea) +,S(1d40ead8,563a4ff7,c14c84cf,ad1339ac,36ae3789,99ec2663,77e0ca2f,6be22604,8497b443,b093917f,ee65a5ac,1c4dfb87,3a6b0c2d,a968d713,a711ec12,20d1face) +,S(2a39f41,adf5ab33,71a27c20,51840d37,e3226999,17a3d0ef,40590710,406bfae0,cdaf7a8,58e99fb8,23a36b04,8e844c18,8dd1a49e,c70488ed,155f2ac6,905c27c5) +,S(aaae4b1,d8b08cc4,8971cc92,fd974a21,66f5ea92,b6ce215e,28137088,19c684e0,9237995,c10a348a,84fd5cd5,5151e33,c63739d1,3a425bde,a34d78e9,e3cd8f0c) +,S(a5b0c042,591a53b6,334939d2,9ac2c9e2,11315a54,831ef440,965fdafc,e6477d40,ac3e7cfd,5d1f0248,b362b206,b3c7dd60,bc9904c8,d2a416d7,e117a5cc,4a62ca6) +,S(c1b7164,e6166a96,a8f643b4,7f094be4,3c16e3b5,3ebf5a1,2782e41f,27c63f0b,8469161a,4ffaf1ff,5b50ba81,1de3ac79,e34810bf,73ed1207,fcc0f01e,75663a98) +,S(98fd825,4b7963f0,4d8e0f2c,8eb26dd0,342e605d,8fdf28b4,57b98e14,adca63bc,e297a80d,213f6664,77f9dba6,5cbcb99d,2dc14325,be12098f,22061115,b1a192d6) +,S(f1f08649,71b6ed49,2d34127d,8c2e6f19,48c464cd,816acdc1,63eb3aad,594c3281,26ae2a0,f9e04fa9,13b8954d,85602e6f,506a0de5,2fdec31a,346338ab,f31f5c) +,S(ff470cd,c324d2ac,a63441ea,c0506fb5,b63af83a,61a23a91,17240e23,930dd197,e601f66b,b18e77e8,4607a772,a1efa73b,30734b4b,8fd31eba,5a5260d2,5627788f) +,S(90eabc6d,968aa196,b5808127,baabbaa8,ad0f82b9,332ed6dc,d04442df,bc6c63a6,d6df0f67,ffb23cd7,2dffc4be,44476b2b,2faed3e3,dcdc30f9,4c1fa4ee,bb5038f1) +,S(e217b126,acc507a1,b41e0826,b300363e,bc0a43b6,feaf3866,ecd4b8bb,cc7e11af,7eb28def,83db33d5,8b8eb733,2b27a386,921e3a5f,b0321ecd,a8d1fc6e,49e98f30) +,S(2a196fd5,82b85d5e,1772bc21,84d8aad2,b5d008ee,c795628d,20de68a9,fce1d184,994b4657,ee9ee3d4,fdf8dc8c,cad2ff1f,68526c67,89d82230,c3399f6,62201303) +,S(bc9e3bc8,3a6eca7e,8a9897c8,1118f7be,ca770cbd,7e66c2e6,1321d026,7ade4342,9d7ef7e2,d544a561,ab899291,75f35d24,e2b07661,2f84b0a3,f346542d,714f3f4b) +,S(ff2813f3,842a9f84,fea9e367,6f12f209,7e76b8ed,e691ccdf,6f6512aa,b2f198b3,206e3bd6,66d0c161,ac6de438,809f485,b8b6682a,f402bf76,18a484a2,c3fe1949) +,S(6e7599df,2d38d63e,be142321,769d7ca,34a50bbe,4e0adbaf,6c7479b8,d1af05f7,233dcf1d,4b0e4d88,4a9ed56e,b6b4946b,25614345,ecd182cd,5556faa5,e3654c8d) +,S(1edd9cd5,6c82eb28,14d844d1,a9e5c167,8397662e,b576f9f9,ba250719,33666146,a00f4a85,b2ee83e,949b5cb0,4d16820e,39d48ddc,95dd965f,e24251be,3df43f4c) +,S(2723de06,1f794cd7,76a4a090,738a81ea,818a2f73,92d7ab07,18d79fb6,407324af,35c7a9be,f9810c50,3c53429e,344ab888,38daad72,77cd0e78,3db1c1fe,c6bbf41f) +,S(4c4fb244,4cb54def,6d9659ee,b43c13c2,3874ec2b,a7c6b53a,f469ca26,ab9a213d,bbd2eafe,56447a9f,feb9ad15,349b338f,d4a1aed8,5a356472,82751e5,5b8efa3d) +,S(736359f7,347995a8,8e306977,1fb3fbcd,12847ed2,8e4e612f,25095720,667593e3,23bb37ed,4bce0512,35a215ca,6b8f9868,e303fda4,80d655f9,72c95bf9,12bd3741) +,S(15cb9594,ee936bd1,4b981394,60879bee,6f33b0f7,c0ccb293,825794d9,85f595be,aaad772a,2ec81ab6,13775e9,edb274ef,e2e133e6,5e58949a,c7f25429,fb1bb152) +,S(3b5489ab,97e5cf1e,84a90eb8,20b8772a,df574777,a61f0a9b,41e6c567,6be78fa4,145d13c8,e9674a17,ccecad63,f113d64a,d59a1eb,bbb10cf9,e7134cf6,562219be) +,S(78d1b99a,a6f9d385,b09bec7b,b59ce26b,23323e4c,3a259c56,68417597,a29dd2f5,1c8d11f8,e883b210,cf54369c,e9f6a280,a6b890ce,15b4a0ef,3cd8837b,7e16a122) +,S(385e4e8c,5ceffbbd,3a813e3f,938912e,d2fd2d18,2be81210,70cd15fb,39661e85,f4a1c414,9f5cfbc5,213ceb21,c1cc08ca,c9b168e2,58cdec70,36e2dacb,ab68069c) +,S(310f8c70,d8e46c6e,48930df3,c53e9292,a7c87230,292d6b1f,c28d9711,951aec6a,6fe319d3,c92c07b2,56715154,d5d7046f,59d92d5f,6dcedefd,b0386f5c,3417146f) +,S(764f3c30,23d1d50a,e170b80d,48d58923,c1f91a96,42210912,94066585,d7c70bbb,bd92fb1a,becdb4a0,ed941146,878c99cf,c3ee9eb8,c8f2b8e4,b547cb40,e3dca724) +,S(3d5d23ba,b357a37f,1bd3c86f,84010b8a,b37a8075,3c47b1ab,36f7ef72,a3e68126,2bbd1841,bdcf0265,838893c5,f5f9c0dd,7ccbb461,93068e0,8211595d,6b34255b) +,S(a70431ad,cdfc7b8b,febd2aff,d6759e94,6d4ddd7d,50f50dc0,87e256b8,2a7f8a1e,3ca4362b,9362b2ea,c33d77e8,befeccb8,23163921,86ff5f20,384247f5,9147f593) +,S(2a388212,2c1b2ecf,3c800432,7c5dd403,2263e9da,245dc697,bf7d63e6,300e8a7d,ac96d188,53b87bf0,3dc5f2fa,fa9b73a9,a339c0d9,a7245175,fd72c822,12f6ff78) +,S(e99c59a4,ae3022e,b50bc545,f57e3013,56b49bff,33069a9a,b4d17c0a,424b5451,29b24b79,fe55fab7,6c3737b5,61505916,b4fe1a98,20837349,baf445d6,2e9bada0) +,S(a0a42ed1,bd5ac5ed,f63f1a3c,3c3fe2d3,c0be26d6,b0da384b,f19c034e,83306d4,c39ff3d2,d4442374,7a293e28,8c320ee8,8aad0879,672679e4,e5bcf611,5ca0bbc3) +,S(b952e5d6,9ba9f063,f1d1670e,1419730f,5cc17e87,b6f0b01,c0b86ebb,c09e0053,c1e8099f,a230b8da,6e71c9b5,bbf250ae,273a4f9a,f53cd0ca,fe8f0c7,2dc46ae0) +,S(3aee273a,130f5f4e,463892b4,512621c9,be83c18c,655d5a2e,620f83fe,95a4e904,edf475c6,921fb6dc,f2c3c6a0,b93f9470,9237b035,9e8c9131,eb7eeb0f,bf0af7e7) +,S(96ddcdc,dc65af06,acb10d91,b87827fc,aa2f9e65,d28d0449,65ce255d,ba66ceac,2e6d0368,17fd4024,c830d4fe,310bbc23,9e2bf37e,60203584,215f852e,d100ab39) +,S(fd50f406,c757ec9d,b10e111c,32941fa1,e0d07ae7,9e3584d5,af45fae4,d30334a3,71b77494,d49c068f,c7db1d36,4f8db288,ed9ccb0e,c6137348,324f4bcf,d53fde6f) +,S(6f2d8268,11954523,614915c,9568ab9b,bd061112,bca3ba77,d3c64f91,6ba097d1,abe41199,849ca7c4,d317fe72,2a5647a2,97261d68,d025f5af,e880ef78,34787a87) +,S(d88c0db7,6dffb62a,27683d2c,e832a312,9c5099db,e2623c9d,3f064247,21cc1400,5134f15a,df6d7e92,5d81726d,f08732b6,ba5aa289,431bb4ea,542e6352,8dcec51f) +,S(a8de9ae4,ddde3f28,ead01363,2202fe4c,b6c0fd4a,a71d5562,d95f557e,747105fe,179e946b,5a71b614,90bc39a5,17dc752a,53682043,6efa907e,383e3da,a3be8803) +,S(626c6827,f7dc3d40,9daa4811,80e65b0d,799c94ef,e48077ae,6eb250aa,8fcd45ac,3d659db,87cf7b28,32e4a2db,8db88e5e,b30b7ea1,7819c00,fcec5d63,31bf2f32) +,S(28a3a2c,f00efa47,db4b2ef6,9f56cf02,1666ebef,b5220495,5b5484f4,2ca77d02,8dd00ed,fc9870ed,99ce90fb,927086c7,fc16837,9794db01,f7799b16,8393c82b) +,S(df0b029f,27c46405,245d0dc2,f178a48e,c3b67275,7fb92bd5,dbb29370,c1545786,f133ed05,c7e159a8,810a5ad4,e1019f15,757b474b,fea1679c,6ccd18a4,2a1099a) +,S(dc6f57af,9c1e0be5,2d2162a4,e8a6b63a,c549783,4c7c2c8b,421bbc5f,dc1a49ef,6f586aaf,e610fe5c,962ee20d,9b389bab,66fca44a,1c19379e,9e97e104,10f1a0c4) +,S(db796ea2,e0d2c690,19adcc0f,a81c1d93,8162472e,a0e3eac4,bf13b398,b255cd15,2e60c6a7,32e1fb44,641e0766,2191e28e,79375420,43bdb3e2,9474313c,7d05ac88) +,S(569b669e,72ea98fd,a5ba3efc,e74f88ce,881fe269,30b063ca,59fe369,35633a2d,badd8eaf,2551f872,5db3f740,6eb5e376,220b6a6f,ff4f8ca2,f76b7755,f8ca0c8c) +,S(36132420,1f9a33bb,d4b6b6f0,e2d175c6,ec795111,85fd2451,421ac333,78468ae4,f47b56ce,f7bc7366,6eeba135,14756486,62a58e17,d955dee,2821618f,fb3c4314) +,S(cdeb2037,1e4d2014,918fa243,182db0ff,855a0783,c92fd5b1,b604ed33,494a469c,7d3c7718,6829381d,2fd0098b,c84ee506,970a7ed5,5518b393,a83c6f79,d8dfa7d8) +,S(6035cfa9,d750c5ec,d3b721,ade88fff,ff6c4d74,f8db7755,c8717cfc,171598ef,fe1798da,160b2436,412dcde6,5482d202,9bb129d7,d58c9cb7,49f9fdb6,7dd675a) +,S(b1f52e97,e49998e4,e0e75b0c,47178f4,bb250b5d,97d92ac1,8dc9e41a,3b79c0f7,d83f3d65,4e4cfd8c,5f24370c,a2651c5f,de484cf8,1024f33d,8087a50a,d3df795f) +,S(aa799b53,4c73da0,9f011395,dd5f709b,f1a5e056,42536477,d7862b21,6df1b641,3a327047,b5e95b64,593f6887,9f38aa86,dd592007,cbbe7338,a003d2d3,33248646) +,S(da4a1964,45bdf4fc,479e56b6,6d339a45,262d629b,dd8c63c1,8d35e9bb,a445aa03,7b3a5eda,25cc63a4,66cff29,634d5eca,353376e7,26c2c6d5,63f3f92c,b69cb70d) +,S(c300b4ad,c2346d0d,433eba80,f0eef071,7e620d46,a07b384c,231e733f,a1b8d656,32083bb9,48d27ac7,f36aa439,a100b95a,f73448da,454de356,6f4a8771,e3cdba42) +,S(c559a528,67937244,d639bf7b,90df2b2,ed64a907,e20cebe7,6a358b2b,94359f04,9fcac1aa,5c08c983,20d671b5,63f4434a,806d78da,15964474,d2470cd,49bf5977) +,S(39b10147,a46dbf4,f074bca9,a83c10b1,b0911ceb,d3e795fa,9b96333b,dfe83540,ad35dcc8,c3b22743,4daaa313,cd6334e0,168da417,d162855e,64294196,2d308278) +,S(39c9cab7,d2dec601,7f840597,19994c9,4129ab2e,a2779d6b,34774a04,2f7d6d42,c73ebd6b,835a8a13,354cdd45,37ddfb3e,72ca72b4,c8049362,3afdce9e,43781845) +,S(1a625998,8a30b462,adec6097,2e218ec3,f8f81c4d,44131466,fc7b5eee,eec679ed,739beabb,1a97c9b,bf6776e6,2e213bd7,3651a39d,ba042037,bf5f8cdd,334114ab) +,S(396ed910,cd35c308,d412761e,bf283a98,85f33ecc,3ef643bf,3f422dfa,ea4c4308,721cdda6,a08a614a,4dc48cf8,442a46b1,3945e158,83671b7f,556d19e1,144dfe57) +,S(a50e06e8,a2e8ccfd,94aee96a,b0bd831c,83e15340,25e3abec,af7b7af3,9b299a47,593205b2,59a18063,fe5a4575,e8e085e1,4521fc1a,3ab5e14f,3fcd64fe,2bbeba52) +,S(4a9f8023,17b0d1c0,e62c8bcf,7393fa34,dbe15cd6,46e8f4a3,dc3f26b7,11c3e1de,40eff6d,915fff,cdb30c24,434e8928,239867c3,962655ac,2894bea9,f7c6bb71) +,S(8ce5e20d,9decb7e6,10b18562,e2ffbb88,7f323262,55ed9f05,5d2da2fc,8d608b73,eb69b6c,f363e164,e92371,b592727a,63f024b2,aa7011b5,4f1f698e,1ac720de) +,S(f32695d7,9b53e9e5,1f2525e2,8a5540ed,84143ed6,3700be0a,36726f9b,b483f24b,e8d36488,eea2055f,6592ca1f,6fe23493,1d81bd16,1c61523e,f1ee1907,c08471c8) +,S(3826fd86,3bf6592e,5b51ad14,6e02089,d9274881,25d25959,4856de1d,d6c34d07,ea86f1e6,a29035c7,43e82058,a7ff9f82,20da001,a8901e97,26583b1c,ffe4cc83) +,S(7b1afcd3,2e32b0f5,1ba09868,4ec72762,ae8611a8,98e87ddd,dc6410a,40ccd551,deba6ef7,79e10931,8036ee3,9bb6d0a8,a3ce0eb0,bc5620ef,c70828d3,d2e37884) +,S(3eb1fdfe,d2c27587,540d39b1,b66a36d1,8dedddcc,7f7f7b63,348460c1,35a91bd4,b8aeaaca,536ae794,619506cc,a812a67a,642c5345,8cfcf7b9,eb898f96,d26b36cb) +,S(9d61dac8,aae9fc5f,532290cb,683eea2e,b71b4d9e,901b7c45,c214beb5,9b56da8f,2e7caca4,2ea1b22e,7024fc3e,e267ce99,280a8f1e,78a2a271,7938762b,3a446036) +,S(2db372dc,3167faa8,e8e1e37a,85ed5546,e91a43ef,fddba39b,e38d0eae,3e11c7d8,16ab6f61,bc1abd6a,16e79697,fb59f0e8,84f00534,b7196380,9b06e10b,59707ffe) +,S(98f7cef9,f7a2b538,538e83cc,9ad3132a,5b03dd67,f7fc4030,2ff023d2,8805dc80,3b40f823,2813e6c6,bd56df89,1e96a175,468bedd3,f9518dd8,d658105f,aeb98943) +,S(eeab2e6c,c8ab0d24,d5df5852,8a89db42,c48f0861,4d488c7a,363cd195,edb62548,607c41ed,65d3328d,72be2503,f5edf14,523a7f74,402822cc,1709927,c82649da) +,S(955feeff,b2161c70,3469a9d6,c5fb31b7,b7cb5ed1,ada6b537,6d935705,b3db942a,a9195a48,a561c342,779c984,6a710059,283fcd0a,682cb5a3,fdf48ee4,15c0864b) +,S(219a4d2d,70d2ee9e,d3c8f541,1cdac36f,4db23bdd,a981a5c9,d44ce5ac,dccd85a7,67441968,43008ec1,71284aef,2c64f7dd,3dbfdda9,5c6c8e4,70a564f5,c4ef53b4) +,S(4976290d,7794b161,2e2f5cbd,282c1036,d594571,722e28a5,ed542972,f91ddb23,4cfd95f1,60fc5655,2fc8354b,446dc510,23571c24,56f57aec,79004616,ce17ebc4) +,S(472d53e0,268ead1d,bbbb99ed,599f5676,1866e0b3,c14d4a4b,5c44d722,b072b1c1,e9b9c009,6115d4d4,a8ed42e3,1d967b89,e4dfe82b,ec642db8,e31693ec,c2831232) +,S(2a6f5b7e,7a4db95c,af875d61,75a6e1b0,3f3462fb,c0dd5d50,da3327b4,70ab18ef,91b247a3,92aadc19,7d9f5b78,f0b013ce,c9f3724e,a2f37347,9ade7e03,8659d506) +,S(dc1815a3,bf48d81b,b5e5e654,fe0c8c3c,7431a62b,9d1065ba,17df9c45,23146c19,fe20729a,311550f0,e47e2af7,4747effa,d837c5f7,b08c8f36,d0fbdf2f,d594be8f) +,S(8e7953ec,ad8feeb8,97a95db4,f03ffb98,a8b47ecf,3e68bc4f,1df0b6e6,98397776,5dadf2ef,81b21cc4,26c40a39,51f31462,12f7c6fc,dabb5157,893b1637,c141ac5d) +,S(a4d91e6b,49d5724b,9e899fe1,c6686c89,faf96a05,6e666a74,72ee44cc,119b41a5,abd68615,e296498,f5abb820,cbdcfc26,fef10b2a,ba72e474,14ae9de1,960a4893) +,S(b97081a4,f3e426b9,d3a66dd6,8e0e442,754c4922,acae141d,d0294843,6b00eee9,558f6c83,99214bb4,baa9cb64,11550b12,2c8c2f77,8e28a4f1,ea61ed6c,b8f153da) +,S(6882b6ed,82279bce,70a73c6e,f6412c54,b873a5a6,b634a25e,a8c34210,fb825848,c6fdeee9,c8233e39,2ea79c61,6689e8a3,1e3a3b09,21f2b5ae,d6b9e14b,9ff21b3b) +,S(9c542731,1c715709,cabbf11f,a4fdeb3d,1a0dba80,ad50d1a4,62c7ee1a,44717fe8,aa041b10,78163458,c446bd40,ca77f760,ef4b6471,c4f2058d,7ea42975,d1f2b045) +,S(73a14da6,776b5c12,e838779d,e3be58de,4a5ed917,3b195d9,3577330c,780cd32c,c4068ffd,e98ec4d5,a7467bb7,e8bf2c89,ceb58574,cccb3a78,b0ce4a70,7ad2c49c) +,S(6488a286,27d26c4d,bade9d26,1e6ddb7e,8748d835,d9def8eb,fdc6c576,b6af91b5,27f8b1f0,b0501191,8af0916a,945bb07f,3c7f0695,5ada697,b5c601bd,3d6d8ff3) +,S(96546e7a,5b544c98,db9ee2ef,47dcfbce,cca1d38e,1978f71b,d8c9d4d0,5151046c,d04fe32f,8fe9ecff,220f07d2,2095c982,3b10f772,b261189e,84160ca7,5f4309d) +,S(ba046f56,4598b143,a02cdb90,972022ed,e769986c,82d28066,761463ed,8cfecdf8,fc6e23ab,d42457c1,5407d37c,d3d9daa,3e57bc0d,778dd68,53603232,3e27250f) +,S(39554751,e633ca7d,df6d82ed,86a8204,5e76557f,b13ca7df,310b80af,5ad0e4ec,a456ba84,f040f20e,977df5e9,5faa3f67,cdb2ba3c,2fb9bb4f,89486b02,a06d3b1c) +,S(c5f550e7,5fef9fd7,d96c924,11046c3d,ba56b8d7,e1b17c,d46a68a4,989c22aa,548582e0,3aeab617,556a987a,cee7d0fb,8d65ea42,dc8f2cc2,173c3636,27ac3fa9) +,S(2ccc1610,a48d8db3,9a80b2a0,ee063a43,26d4ba75,79b2727e,b999aacd,6e5fa050,de6dd7db,2114002c,8dcb17b,179e5843,fa205d69,4928eb70,a073f97f,f8348c84) +,S(93b07ce7,3e941c84,1e4089ff,2d8e6464,3ae59cf8,fe6e92c5,add89e10,f7084b3f,a6c0476,c5a7267e,54ec362d,3629a1ae,533efcfe,e18d3634,cb5a80e4,4018fa63) +,S(453c01f0,55c14679,5e3aeec8,26859b16,b0ec2707,61cbba3e,438c0566,5a91e7e9,f28eaec9,b9d3c8a2,2ef73843,6088425b,e14ac99,e52e73d9,8745bc49,a56766b2) +,S(3c6df1fd,ac078c28,a0a148fa,d15595b8,c1d09a4c,4a96794,6f8d6465,e80f12f1,4619a84d,4eaa134b,a06a6821,2e7ed292,d443db5c,150b54f,6dfcf267,82a5b58d) +,S(1b7f6968,39959785,30542989,59020dbf,f12054f9,2705efd6,dcc583,11b98630,279dc63e,e3e8fa8c,fbd731c9,b88ec6f0,67ee9e15,d0c14a37,372d9c20,c645c25) +,S(e1b7b953,9d49d0b9,9b90a642,74d2276c,6256f2f6,9cd03006,97ad842f,bffccc19,2b23b96f,51dc6569,8504628b,19e81534,f2acfedb,27f93316,fd0dd8d0,d5f9500f) +,S(404cf0c5,6fbf4233,4bd5f79b,ba97464f,9ce5525f,a56212bf,4bc817c8,af54f911,b5920609,88300588,5c61a6e0,75e3657a,23c04b5,79897c0f,2e22ca64,1f1ef662) +,S(43f1d986,da626bd8,efee817f,a09a3440,e7819aec,17ea971f,43fe2ec9,caae0c1,c5fa5ace,ce891aa,d2811f51,8175179f,3e93f438,2b3ab583,e51a200b,2a74f9ad) +,S(a18845c6,b3209951,16a183b8,1b762112,7bbcaae8,b67ee8fc,d23ecaf6,c5b9c1f,980ed5d9,d7e07e6b,2cfc5350,e818671b,8f54e7f1,5cebbb02,dfcc2951,bbef1f44) +,S(4d9c7eb,af99824,605cc17b,e03c929c,254c38ad,c026d5aa,2a304920,e7ac01ed,c64c5b35,bb0dce53,2273cf00,f3360f74,97065bb9,9fa9b1c9,70d41c19,53e781d3) +,S(e18d22f2,fbc3db09,bcd31783,3e8aa605,55953ef7,4c64814,edaeadc8,97e7c25d,cc258a81,71152072,24f7989d,fcaa8700,f15b8b2,85700b59,53ef2a22,efc7e07e) +,S(160575f9,f220904f,8d2ec9a6,c1417e8,35083aa7,9bc37d5a,3c8bdbe5,2a47879d,1e56b4a6,127e978d,41191c60,ad439fed,2c38704b,309d34ce,d655f93,5279a5e5) +,S(3b651bc7,57b1d626,4d6b7ebd,d3c5355b,4c3c9f6a,a1437e53,f9aa0372,5192d514,977a8774,95990312,ff1d8ec,5dc8a49e,5feb285a,8a1e2e4,19e56186,80231c3f) +,S(9085bdef,56facc02,76025015,498ab286,a9660e96,1fd6bb0c,d9579a8f,16ba532a,fd05d108,a557559c,5e7f791d,90e80e7b,68364c16,8f6b93b8,c55510f1,7ae9fe89) +,S(4224306d,f64a3862,fd33aab8,c1f0ace8,67cf1b25,76e1cc21,fef45448,e40569ec,8740b667,5279bc1d,ce887c2d,c59e42e4,63e72395,ff967249,8bd13d58,f60661bc) +,S(b7376697,4a512e31,a6f806b3,5bc55ee6,e0e2b2c0,ff5a0918,2f83ca35,dc22935c,d350c820,2676fade,ee4152a2,48fd5cbd,890b3e03,9d688462,51c2a082,85420103) +,S(73ba4f8e,d3b5d4d0,a7c505ab,1c1a7486,bb82e068,cba81574,557424da,4d0eb97a,93af3914,552dc360,549b4a2d,863d3f9,3a58ba9b,72541215,adca4bfe,26188271) +,S(285a014e,174724d9,8f0576c4,5694b052,ae93540,6bce1bef,524be03,6fd3d8ea,6fdad1d8,d2ce7757,e6ff5213,f91d4db7,9d406765,968ce8ca,b393e7c8,6a9af7dc) +,S(b0934dd7,27bfb54b,a2a5cea7,c6f8c0ab,84c2fd78,eca0d180,963869de,c28e768f,dcaf0d11,56029f31,4bebbb26,edb09913,484c94f7,d14d71bf,2bc709d8,f0b982c6) +,S(3b627add,8b69a9dc,b751c8bc,cef15d0a,ffcb49cf,357bb65e,c45c8c0f,5b681561,bda1980,9e380b7,2da13364,9d27cff7,693cd2bb,a77215e1,536296fc,dc46d19d) +,S(7e48fdec,1f2289df,a052e3f9,a4766daa,e4593876,5c8aa7c9,a62a369,52cb5ac2,e87af87a,ac116885,66e1e10c,5bedb49d,68449b8e,612939ac,61e384b9,bd8cb5f2) +,S(4031f08a,5de33bba,b6a2c267,feec2e40,d094d890,caa1008b,181ce43e,263ffd9d,cfdc4fd9,9737a5f0,9a789beb,91dfef45,a8f23be3,11b946b5,8a79b7f0,51b0be07) +,S(ba652b7c,61dddbb5,bf6e656f,4d441cc0,ec00a22c,7b900b1d,d5407ebf,931ed764,87fcb392,d1228156,a330b5d8,d3c67e00,1d207095,9a590088,a3b44d07,29556) +,S(fb936572,d1017653,ac7dd95d,2d8c30f3,62c967b9,ba0d3b1b,ffdc1ed0,6590e72d,adfa37af,db6b6a31,a779965,9958be2e,94038246,6b4a4587,b0879882,4836d8ed) +,S(294473cb,5e7c0852,f7c6fdb7,8861129d,b97ff328,19685148,99198870,b03bae7b,bd905536,f991867a,78a09f95,1bd5b4a0,78463e5a,6c767617,246eec38,7d90c86a) +,S(2fc0f44f,73a633fd,91737ced,1683b74c,7687dc8c,6d3a4c09,44a6c873,c5bc574e,29917cee,ffa063f9,4e949991,2ae373eb,ac572f50,9a451184,15e07354,1d22ad1f) +,S(811fb251,882c5a7e,f59d34f2,c8ed8a31,8da210dc,83bb8c40,b9ac0251,116d569e,74df6547,2cb55afa,4ee04ad3,f940de6a,d480e407,5c3cc00,ad291918,d8a0c55d) +,S(45a9e17c,c1d6cf09,1f451894,ad4e7e53,c47996c5,82fdc57b,a9e7e614,b7fc5d07,5169dc4f,2661f5,fb2d1920,89832b7,4e19196d,c37fdbbb,16d1caad,7b069be1) +,S(d577f7fc,45cda7ad,4743d96a,ab5c7bd4,abd06538,b78c0102,645d09ae,b5588e67,55172b71,7ea257df,ced1db61,88c78cea,765e2c2c,30bfd25e,52107128,303be07a) +,S(a6429a95,8098aa6e,39b71e08,d4b0cefe,4fb22d8b,777a59c0,650e11b1,9b06e44f,af494e62,5587055d,cac440f5,786240ab,36ab1825,f2c3a7dc,f6aa64b1,947dd2ed) +,S(f77c304,b89314b4,258b1c80,cf478ee8,50bca37a,63e20679,7396967,a39a743d,c487a176,29d914be,60845213,60f40f19,1c32f414,558e2c72,7e78637f,8dc1c7ee) +,S(41c6f2f6,15981247,71ff0a82,e1ededea,cd76ea2f,fb2f9f5d,ef766165,96d1c988,58a0f544,146c1a07,5ff9ed4f,f9b687c6,3642770e,45dbf1d3,407b52a9,5accb68) +,S(c8724ec8,c13d37af,9eaaacb,35765e3f,7ac2d2d7,1fdb5916,cdf66ed3,2eb968d0,70ecf721,42103e6d,e7d4bbf2,42bd9a6e,6ade66ed,a7862989,5ecd255e,44d81221) +,S(e2888c46,dd58e36,be2204a2,b75fab66,3b139e4a,e070c650,653ba9f3,ff1fbbf2,715910da,e1393b8a,b7d88879,720bd601,bc158498,9522108c,3312b353,2342509e) +,S(f1f4c384,d72d80b8,6b5999c9,aaa66f99,f56cf736,11ea9ec1,c14ac36f,66d834dd,b5543bc2,480142c8,ebb8527a,3c9aa786,2198388a,696b3c44,835e7375,24cc7e3f) +,S(487477f5,832fb7db,768d412,6edd7f5a,17aec3a6,3419de73,f61812b4,31940a5b,90322dde,4203fa98,bc44e3dc,32a6d56a,284f556,36db7c54,c5f78d5e,1b2608a7) +,S(a726963a,583167e2,4b8f957e,b3ee9f5,c55df02,9fe1229b,ff8af037,14ca75af,8fd7a984,d68929c0,81154d15,6b6541ff,4a636925,53a5a32d,99f6516d,c08f7449) +,S(d4c20db4,cf80eb1c,9d93a231,e699a68c,baa763c2,e2013033,8762ac5b,8b99e97c,ba1c77ba,2555a50c,84aa2071,39190a35,f5abc50e,589287a,426c6f9f,6ceca01f) +,S(7cf9c53,89ae702b,bedb5a55,ad8d0f36,5159ba1d,ac56fafa,fa59efe2,3a748168,ece3b324,338c7bbc,a2cec347,c31348ef,489bee0a,6ea4296f,6ec38502,b72336b8) +,S(920108e3,c1ebd4af,3979f9c3,326806f,eec92833,b4dbaf49,6992541b,44b73e55,3e22b133,d8adc483,4f03f348,eba48e65,6cf8f478,524f5395,ba92e200,95f466fc) +,S(1566af8a,98c48762,9b361337,2ad32a53,fc760538,49566a8a,4feb69c4,26479e90,2848c566,4bd72be4,c797db98,62fe1c7b,da5d3ba,eb3f7926,daba8516,da997796) +,S(a4db5e71,2eb8ceb,c7d7a704,12b0a8b1,d2f6d9be,271ef044,c0f76abc,af61723c,663e16e0,75a73ddd,f604bc0a,27a9407b,272f5f2a,f2b9f6a5,6958c8ca,c42e8ca4) +,S(d0c9cf53,8bbdb8f9,625d110,6c79cf1b,33d90e77,60778c13,8493bca7,8d53e5fb,b6ecce0e,8b9fd407,cc0a2125,b8bd30c,9975ad88,7dc1bd9,68379063,8a1d9a60) +,S(765fba92,480f57bd,70596d67,bcf3a389,4a58d514,54e3a04c,e657ce78,ffd8391f,5cb1dbba,1035350e,5a3b552e,3f41ab4c,50879bbd,5f3ae3db,af6ec902,1e18302f) +,S(9f9da9e8,e846702b,4aaa7b9b,68b652f8,9bd3f88e,5af4a503,2c51ee6f,8bfb4a5e,5dbd499d,7ecf17b0,eb17320c,a0688aca,1d8da08d,d2c0684d,edfa2d7f,5696a0f6) +,S(af86c83b,db95894b,72fb1a16,61aef5f0,ad949c9c,b465a5bf,b1192022,13fdd3f4,ec06827d,55410119,603d2b25,cc41c26f,4a7bb9,b1b88e55,123f3c12,d799e117) +,S(fbb48993,2fccbc8d,772b3fc,c80be33b,64c8e3b2,2ccbb09c,d94fa350,fd587e77,f9cdd24,279333da,b3451abd,634075a6,58598ad4,257bbe04,81111b6c,d8c0b858) +,S(40ecb1a3,ad97c2af,62b15eca,e2adc9c0,621f36f8,90a9269b,ae6edc1e,7ed60684,ff9ec194,fa3a617d,920e3e2b,32301fb9,9a41f4b3,ed9845f2,88daa005,3558b32e) +,S(31f892f1,c762b42,fcbd9014,bfe0238f,39873c30,c7d3b691,9736009c,18878f52,d9bd5005,f31f7345,53131066,ef6b92c1,5cd610b8,f7d4fff7,be536734,95718c95) +,S(ba122529,e9f6051e,2d94d150,c5d7739f,921f8193,8cab68f3,1c696fc8,24886c5c,c33c071f,7e9bd539,1b0577d3,37ac9c20,7c02859c,c396bc20,d9c7249a,856b1ed1) +,S(35316412,9a26d311,c993ecbc,5b9a0263,ef45d993,d58158c5,30c215f,2924cf03,86a620d9,521623bb,9ce3e2d9,c5b6385b,f92ef06f,91834e3f,6a9c6d35,7a3a9742) +,S(3024770b,e4134aa6,35ece92c,a4ec7f9c,4a4aa7ac,7851b3eb,f9718a21,52c8e462,1fcfafbd,72147afe,16dc1579,ce7384e4,ab3f8faa,f818d225,bbceb050,ffc8c8ee) +,S(f5ba313d,a40ee86c,5b6dbf16,9941d8e2,533c1ba6,4dd0871a,672d01c8,6bda6564,10a910d,b9697907,c96e95ec,15557649,8f965282,437f58c7,2944bbad,b800647d) +,S(685e17e2,972ccd05,34f7f426,b18c9518,e485a23e,132c18eb,b33b59c5,7264e2f1,96545b38,be84aac1,a77a3f47,51156daf,470fd42d,dea0fa0c,b930144e,b9f291c6) +,S(e01285fd,facc9822,a59e1bca,7e91c07d,fdd481dc,61d268e0,504f65d1,9bf119eb,ae82153a,2479daba,ef83615b,a7202b99,40bf5b5e,41c65063,f77d6e5,9dc39909) +,S(c61e4586,327710ec,784d6720,93201e4,93798a93,7635f220,b5421cb0,55839601,e461fbf5,aa5b64e7,a1e3e016,3ba555ca,5d42fcf1,7433c26d,cdeb8cb2,746c04ea) +,S(1c427acb,4e5890b6,e24d8ca2,513b61d9,3106fc34,90029af3,be87d65f,1fd192d4,1d96e025,1518528b,9bb04fa6,ec3430a1,84935ad5,ee8ae3e9,c9cec0c4,36cf29d0) +,S(5e577bfd,6d51897b,4b6ddb3b,a7d470b8,5a932619,b5982f54,431df6f1,f12fd8e7,c1a17292,9734c19d,3a836e90,8a5a7fd0,123cb044,c7ad1ff9,203d4d79,211c6eb4) +,S(cc78b333,1f968a40,bafaefc8,dfbcadf2,adc6ae76,6d3ea8a6,8173b40a,28237b30,5b7691b2,a5bc068,ff1ef04b,41238cb4,dfc2ce7c,9436f8aa,14eb0a40,45857d42) +,S(3855c437,487b44f2,9e5dc288,faf3ecea,c445372a,95adc16a,b1830a4,ec919fb6,df2e1e9a,48cbfa28,54fbcd5b,308bdbd5,ed1949f5,e1a39519,11c287c8,289359d2) +,S(c05233b4,a83356f,c5ffcf6b,97db3d6c,dc62cb21,b7de7c92,8f158466,b9d16b19,b1bda39,ce78847,3fa0eac6,51e8de54,956616f5,16233275,25ee3bf7,9e54f500) +,S(6c064d3c,f34226a7,d9a00024,5901f355,b736c1e,6561810b,455e7dec,99dfffb,160d9442,d25ec1a1,f80f8fd2,a1c5c42e,aa544477,28d242e9,925824cd,609eb9a7) +,S(9658eb89,70bb1aa5,1b61a93a,de6a7d,b3e20772,4789d009,bf37ba9d,8b714cf2,cd4ba4af,f7da8f8b,7821a903,f40d89e0,96be8949,997d5ff7,a58301ea,92c51cc2) +,S(6e023910,a5546f70,91f2b0c4,c3f996f7,5cf1f969,a71c31b8,7a3e7ea6,4bb4f0c8,f6ed65d7,90ec734d,d9ed8cfc,7d8921b8,7faa9b36,651c3589,99b9addb,34c459c5) +,S(3a35ac98,e9700499,f903528e,330537f,9262901b,d60c7a14,1e68f899,54c7ff6e,913d9516,da631c30,5394ac0c,9eda3824,1f247ff8,a7644eb6,c4d38da1,972069ed) +,S(d089fa51,15dfaa45,a8b6def3,b1948be,2317c66f,249763db,7350e57,76af212,4e6ae973,f326fac4,77a5120c,f3ffa113,a18e5dac,4a190f6a,b12fdc83,18a6da9c) +,S(e733c52f,2aa62ab4,748ea0f2,33d9531c,5b9cd9d5,f790b6ab,45bb2c2,d8cf2ef,701155c9,3c677293,acb23ab2,8d7ff753,36ac4885,70c52d89,fb80ddf1,d582a291) +,S(4b6f7b7d,c006684f,e64aa6f2,42babf86,1eb4770b,b8195b9b,e8caf763,e7f14c7a,6c58b780,ac757b33,c1805d8,a53a04c9,7bfaea05,d8f21d5a,2b0645eb,2194e00d) +,S(1b520402,cd1fac0a,c4d7aeb,8c552e73,44ff51c2,3b4778b4,81126e5f,e267f79d,8ee0d00,56649304,a0c4ee94,39add4d8,30b252f1,93d93c1,9e8ec375,37db1a39) +,S(8936e6d5,d7f1ed85,fc2da4c6,38a885e6,3400cc3f,43d864f5,bf9af2be,b97139b1,29812a20,b4b932a3,770cdc8a,6fd32625,8879f217,a5bd7c47,78d2b041,829b402b) +,S(6808ae7f,4813554d,aa36c043,a55d9171,aebd396f,5ba1a1ee,c4f11045,c96b518f,6afcae6e,88728ddc,578e85fd,5f41575c,f581b983,7c749c22,31b993a5,9c425810) +,S(586c6694,44c73f66,1211bba7,601d8009,93e23293,55a9b10f,2367924a,35a2cd1c,74b0901f,f6eba3cb,408f5507,d37cb7c7,873537dd,ef0671c8,862012ac,fe5416c7) +,S(789c825d,deadf1e0,4c788453,e918541e,b183aa5,99ccc66b,7897be8,1ff89e11,8106aa6f,641bb13c,6be7480b,89f98a9b,e40cc357,ffe9903c,b8f78938,e46cb5ab) +,S(d7ab80bb,fd26faa6,620d0ddf,97f64bca,e520426e,e1d8e076,acd7cfbe,a9419797,26af9f72,a6d1b103,aef4a85f,5139d14e,6e50a58b,9f32eefb,c7184537,90c5a823) +,S(18f712d4,4daf1ab8,4612b311,b1ebc418,bddf0f33,ca02b315,4c256d2f,36f67f7f,c40b1950,f92fd4ce,edb3c3f4,34ff7bf8,6b06d8d3,215d3ee9,f2d9bda6,77d25bc) +,S(8873276d,9f6d188f,78e2a7cb,f998bcc6,fc399d32,21de85b3,eb9e6ea6,c7e5a06e,297e8137,8ee9b9e8,ee820a3a,7e566178,dac97743,c04b6b4e,54a7081,e7c9e1a6) +,S(101b8101,5bd217eb,c08f57cd,fdf431cc,30fadd66,4df79157,1452ca66,c688e0ad,fa6c1b2f,ad203831,185816d4,a8f8dc9,4c7542b4,6c94dab3,39b73718,5d179e6a) +,S(77b3c157,76c31460,11e520a8,cb2071fb,abe3b3ca,2984bb6c,d81d4c53,7f42dd57,8d0bceb1,dab601b7,1c084c9b,443ef5ac,40cce5d,14f0c244,92589905,fc4a645a) +,S(151f2d52,56ac60b6,ff7aca33,8ba66f12,fbe2c189,33c805d3,ecf6a6a0,fddaec7a,d2aacd77,10cd4bf9,917038d6,49e94235,c4833c88,9cd57ea6,74ece9f0,764f62d6) +,S(dd75cf27,f41e417b,46338dbe,24b46df8,9508811c,111bd1a2,29a3809,171d32c7,e328b855,a3389b80,4ab03c33,cc91d86c,ee22170c,d8fb53dd,46c32224,19b67be5) +,S(faa1feb,bdd1d9c4,9de366ab,3f661b1e,6a3f6b76,335b428a,494d7eee,791d7a83,df361d4f,8fce02ab,8c248ee5,61e46555,948bb29d,81a569c4,13b5713d,b825d572) +,S(3cc10dbe,5bc2bb31,fddee65b,66789594,a4cadadf,8c6a7545,671dafed,4d8f8be5,802d45ef,8c66ad6f,e692a3a,9d42c974,7101120a,ea42510d,bc08e657,7039c2df) +,S(9544e725,325dec1c,914dee7f,752802e1,856cc485,35e3a1e,af576bec,a7b93ba2,cec7dba6,81513c04,ebf39b03,717338cc,aaf137dd,e5087686,aad83115,deeeeb49) +,S(94a0fbdc,d5d06236,7b17ff8b,4dcdf6c1,54eec66e,2779deac,38be37c,9f83a964,f25f34fd,5ef06c81,b7223e16,9a42e2e3,fea74213,5a2a30e5,76f29ef4,cfefe82a) +,S(989e29b2,c3fc7e2f,695fbd4b,f217ba43,14f67c3b,9f77633,100e84b3,c6b579c7,608a6d28,cd00297,2b4f3e9,917daaf9,ed003a43,1c22771,17250efd,b621c888) +,S(c38c5fc4,4295a59d,3b0e979b,5934ac2,49b4bd5c,e94097f1,c81064bf,73494a5,16240bf6,d354b36a,648e471a,e0ebc167,1d1dbc71,7cbeeecb,7600462d,61d1e2fb) +,S(de9cf667,35c4046c,58b41d8c,5c658efa,7dc656b,7ad877e1,546c138f,fa7a63b,2fc2824f,ba9162e3,e2372927,5448010b,ecc19de7,d9b94cb7,57586de3,506639ac) +,S(24cfd37,e56708b5,79d84b3,88c33c9f,f1dd9e08,4675a3c4,c8c440c0,f6c06522,1cbcc8ea,9820157,b4b4d289,55ac8672,1aee676a,cdb7df00,7383ac79,c42af897) +,S(9d6e3108,6ad8b9b6,2f4414a9,5e091e9d,2b275d8f,62641ed7,26421639,e87cc121,b924700a,6792a67d,4dab59ad,5a743cf0,43c46ab4,de751bca,757979b6,ead3abe0) +,S(52a89ae,28b28395,739c21e5,38ed38df,74aea22d,d2765d38,673be080,8609354d,c183ed57,9b65830b,d37cccd2,76b2f61,469b06d5,987b5708,89c5b1e,d8334e51) +,S(2ffd3272,491d1807,243f5d31,d727caf5,cda3bf8c,2c172550,46bd3420,da27571d,812e8fbd,6f38b334,a31e48be,6deaef58,599934b5,d3419d52,131cc9a6,535b6ad5) +,S(5d60c609,4269a43a,35e51b66,db193b16,65df689c,270662f2,eba959c5,9c973fca,f591324f,d1afd619,2b31bb7e,3f40cd40,6d3b9285,969c448a,3aff1f48,850efadc) +,S(23e0c40a,bfe53353,f4426340,e1c1b560,4c86daf9,85784d0a,e6da6b4b,3d12ff75,e90844b5,fc86092a,91baf68,280ca144,f19d5a79,9bacf827,f9921511,28191d9d) +,S(945818ab,5d4a1c12,ca6f20d7,7f37da80,50e67d79,30bd2bb1,155885ce,7c6094f6,b5f2c1d0,e2f9ae6d,aa669c96,9ededb60,32ca8163,fafcbb6f,9a11cd56,4a695e03) +,S(d1f4db7d,2586bf6a,187a469c,a0cd7bcd,5043be5d,6206d24b,c41ecd8f,d8724c8c,64054f82,77c4774b,bd480ce9,b2929c66,b1525eab,1c6f365,a1ca5ace,12206839) +,S(4f5c4d4f,24586e9c,1a85f2d5,b42a3d11,158b4f2a,5cf75e18,60f7f4ec,ec14a18d,57576e71,6d547960,6953be2b,e7ffbec2,1e48bb9e,970fb350,986b4a31,b0efdbe5) +,S(c13b605b,dcb31443,d8a3cf5c,5e4f903d,3f8edfc5,1e9a118,c3840cb9,4998150a,8dce2eaf,99f1fbf5,2e62a8ea,948b01c0,6c368e49,f41922b5,2f603cb2,16cb8435) +,S(1937b32a,b66f254e,4964a5b5,a1ceeb5b,a3df2466,e2669753,39174cd0,2429cbb6,9712b0a0,6f1b075c,bbceabb0,53fffb1b,181e079,813e022b,b5701738,ef2e385) +,S(e4a5333f,2f1772f3,84ef386,c3be1f58,d757bbdb,7ad2c4d7,47e61b07,419ba2e4,e84f7da7,2ec2e4b9,389b717,8bc15642,132571cc,9bc14c7c,5af14a7a,cb6b6f56) +,S(2f8a38b0,a3f42a8c,5080a0cf,5cc1085d,d57a8341,ae154dcf,fc7fdb4b,5606cca6,8764c6a5,2c301db6,56408d9c,4eed6294,2fa2a72e,1b1264f1,134f38c6,8e4681c1) +,S(3d2bdc2,c51c2d77,b6c585b6,3ceab5fe,acd14599,b841870b,8735712a,81a55ff7,33f749ad,bbe263df,a99a808f,f0476e44,92246036,a3e8b5e9,496b8dcd,b6d3e9e0) +,S(fc87f808,d6764ce3,376b9acf,62bfa3e2,1ecec215,22dbdb3e,6e5f3cc1,efab7d3a,ce75eb03,c1f4f937,70815dd8,750a4ac1,c0343024,ce1bc581,717cb971,2835176a) +,S(7f81b85c,62dee11e,be8885dc,cc98485,32354952,1c7e6cb4,374270bf,5b1e68d5,b7adef7d,6a84db61,c15ba062,d96cf739,1750aa4a,ed5c97f3,ad70d2a7,6a9c4558) +,S(d618d43f,7afd3ae5,e8dd8f47,f62ef91e,33cc8f89,3c21688c,8268b903,e1fd5557,6180817b,c8ab9b0,82b21267,9900c7e4,42ce9e8d,fc8c3fb4,fc5bcaa6,e0cd34b8) +,S(ba5a4c4f,f2379b06,daff540f,c8383b9b,694430bc,df76c931,ccf94cb,896e4940,3a221d1a,b138e6f,4ed309b2,4f2e9333,25299de5,534a528d,b91075a8,fd07b1f2) +,S(c69189b6,bee3746,88359141,5b35bac3,80136395,c83098ab,cec29fa3,18cfdf56,a185dbc2,b862da3a,cdc232fa,7e3407b1,9795e61e,29b7a79c,5828bd49,d739268c) +,S(51f67d44,32fb401,ab863423,b99d403a,70dffd86,87e5ad71,bcd3732c,1cefae12,88b17485,a2c404a3,2bcae68a,3cbf2166,403e23f,8a64df5c,a8eb2d94,61e10e59) +,S(cdacfe09,e5585f8d,4346fb69,a94b8b65,6001e117,ed3cca36,fa8bee6d,eb7c4bd5,ddf1bc5a,993131d0,15812176,206699d7,af5fc403,59455ece,fdb84492,6e028542) +,S(8129e771,e1fce476,9c701d70,cce90888,481eaaa1,d1661be3,19f33c93,8bf0e769,3eb5713d,a864bc56,39ed8b6f,974966af,8a4db189,b5446d70,d40a816,f045c6e2) +,S(b97062ef,6d415bc0,f302fc0f,8aa730d4,f39c14aa,f82889ad,a68132bf,5abce3ab,8ad70688,cd76c93c,fd8dfdd3,8522247c,6644c9e5,51116829,490f313,d53db3a6) +,S(19c3c98b,4e811b5f,ea5d6af8,c4e86be6,50de67ec,5154bca4,22a6a14f,4f0bd913,bc523f96,48bdc993,30e1b5c7,385097cb,c18b9d5e,924767bd,d5d746fa,a190a109) +,S(b9ef34c7,3616ee74,b1ebe43f,889118e2,ad7697b,efe63559,67a9b3c2,b5b42b9c,12f1cddd,d55b1ac1,b89be271,5e623952,e8dc05aa,3570e254,3b70ea68,5b661bea) +,S(7718e34f,58e2cdb5,80f9c39a,96d84dc7,59dd2a3e,bdebaca8,6e8edb97,f503c34a,a6d105fb,dc0841b8,12dcd8f9,6c4bd17d,cf5e3728,8e0e3093,13567b10,3e96df7) +,S(dab3884b,8e6de737,63bba89b,8d35a369,e259c1b1,8afb6ed6,21fcc871,c77e8dba,f44b6f29,c59a2d42,2babd4b5,edb4a009,c9316e09,2aef953e,e503a278,14a11577) +,S(cb3d0e10,1139782d,e5e6a897,8b5be6df,a6736751,e847ca18,76aedab1,e67f4366,27fe888d,d227943e,67969b33,be48f1d9,572aff67,69c150cf,189f9709,bd57d3ea) +,S(eb1b1ff8,55619d41,8d193db,bf62b4b7,656ea564,6ea2e79f,cca7fb3b,e8c3c6a0,c27fa0c7,5b73d5c1,d7113741,40384565,d36ae93a,49b327a5,cedd03c9,62282ea4) +,S(5d5079e6,bc40f11,f75a1117,3ab6bdc,bee8f9f3,d2e57aeb,58709786,1c39c5dd,14ae112b,a40db9d5,dd65829b,4be7bdf9,4d8435de,1872bab,80581221,446e46d0) +,S(1060ef7,6beb6af0,6d28acd2,6b214bb1,b708098d,e0300502,384fcc0a,a1a7b38e,ce40f39f,f6c6c642,9585464d,aa2183d7,34252c05,5207e2e2,75d0ec48,c3bdf9a3) +,S(9651c463,c001f731,8947c271,ac274529,e7bcc894,70d63e1a,fd723873,aa170695,4e362e7f,e8ff06da,73d6d17f,e8b63c99,3b16ba7a,5a9b154d,21837fb0,e654eaf7) +,S(5c422b76,592821b4,2f6822cd,cb428b19,895cda4c,d224400e,e0928f27,1f363dcc,2fdb4f4f,9e4c77ca,3448258f,f6c07f5,4cb6b4d8,15281484,44e5fcf6,492b9400) +,S(db147d2b,5d98250d,73a3ce51,9452cc4a,ab3868a6,cd4f43d2,b7224d93,a9faba2c,73254380,ad3c6acd,fa343227,a7299684,9fdebffe,64c4925,8a391a7a,50ed0de) +,S(9a6763a0,f97abfd1,65223767,8881e899,e1beca26,ed84d384,a41d16cb,e5454b4c,bb51407d,b6aa5817,32f1a3d5,51082908,e7952f75,92c8bcb2,737a01d3,3890306a) +,S(36fe7933,e9108af4,f4e5c889,ef94f584,7b45a9e,8c520000,7db6a00,e5daea8,d024a5ba,ecdd5a21,c8c3a0f4,a71e15c3,1943c7bb,66b459e2,7fc85bb4,25227ee5) +,S(40dae663,f04f7e68,ce782fb,87529681,44c749ea,5b7386af,c445568a,3bc784e7,49a463fd,ac6bcdd0,2458c85,423cf252,cea2ab47,44b16bb9,47811176,5755050b) +,S(ba1616d,c8fff3b0,8e8c6d10,b15afd9d,da55faba,79fa8a75,42c5c9cb,adc5b8d1,ef096c42,a6233c66,1965a3ac,eca095b2,7710455e,5f0e1019,7641ab25,b0a786ff) +,S(30486f67,23a54952,4d68c948,dbc71273,d69b4a05,5fb9e7d,a702d027,619c4a66,38ca4d4d,279ec9c0,85ea6369,5470a4b9,fd6acc6d,9a049ab6,5743ecba,c2444c76) +,S(1b83ee94,95ead1d5,80f67174,dec2a026,d6accd93,9a89d970,90f25bc8,d9e6932a,196d448,fb5e4851,e1b73d6d,a2e7d0eb,3d263034,9c2b3e0e,34584bc1,d6e20196) +,S(4ea9dc2e,edfa5a11,2fa76671,5c1579d9,328b6132,14ee64f,2e30f10c,b7517396,7414efc9,6ef83e29,5883f0b1,4019b41c,d4a192d9,d06cac9c,21e8f0f5,b06e50c2) +,S(4166c19d,bee9ad08,83b217aa,3b657436,87677792,d5cb9b31,1a097fcd,2eb033da,62c5065c,5fae6aa6,932b4d29,ab375ac6,b80e113f,d38d81f8,abc236eb,7eed541c) +,S(b17567eb,b112f54a,69c511a8,7d3d2f96,bbbc6686,af8e3f31,a2bbe0a,85a74899,f6676341,3788be54,ae3fc693,4b8936df,a6936721,c671cbb1,bdbfd72d,4c9f52c2) +,S(cd2b6515,2ab97f34,89d81fd,f3513131,a6df0685,5022102,12c2b8a9,be8095a5,cfe7952f,9ca41935,15ee40c7,2d44d023,22afff84,b8700bb4,5f492e31,e78f6a53) +,S(375603c4,9f33140a,3241a72,907ac0c7,2086c979,3aeaf74a,44732097,3618229f,7bb740f6,6322a773,e11ddb46,300975db,de08ba13,84480699,6681637b,eb85e837) +,S(102067d4,390a3dd9,6d83c176,f341dde9,7e10955d,2e001632,978f202e,efbb7432,7cf6cfd5,4d28ccc3,a7019f11,b6ba9df6,1d8b7eef,7e70722d,afa81a2f,839ba83e) +,S(47617e73,e3fbc53b,a703042c,f8b48fad,374ef42f,e8c2dd54,4fb7625c,de63081d,1fa4f423,c92a95b,b2c40f07,f43caaff,50cbae67,87c3e2a0,e4782f39,c1d439e8) +,S(2c431baf,57f75062,9f57aac0,8e28a060,46b814bd,318d74ca,82e1174e,f880f84,ddb9e7bc,68574b32,c1004108,9853f41e,62755a52,ac58badb,b8ee58c6,f209de50) +,S(91963643,8143b6e4,19b86b1f,79b708ab,3f4df44b,d774b41,338570dd,8343d599,9034ee17,7171a0d2,9fb91d68,26b87bbc,21be334,90f44049,69622a8b,76312f0d) +,S(bf28c201,af656c7b,838d42db,95683b06,2871859,2b016ddd,a4a4f7f7,c4b7754e,bbd4f04,dda510d2,a8a66c2f,46ab0681,ce6ffb5a,ac320e20,c50b6df3,a345d109) +,S(fcac7386,21825f4,4e1d531b,f598e40b,1aa4262c,a5aeb5a1,babb4f35,9518b137,3b196b7a,957bbea1,f3f2d1e4,1ba37eef,7dcca7fe,87e7c593,6ffff685,52e67b64) +,S(9cfea1df,caaee192,141f0278,e467f809,8ad89cc9,b47ed982,3029c1dd,726e9331,72d81e4e,7f30ee05,8fd0b646,95086e30,96a071c1,5b75df47,b10146b,18db211d) +,S(548d3f42,123553c7,965c7f21,f2802c30,455c5151,99b98e20,1e966f34,6a1334da,612ea25,cebb03d2,89538eeb,15b94686,8c0afb1,311278a,42694a0e,956418ae) +,S(e5be619a,ccf84c26,9b5c545,e8c4990e,ebd46756,c628de22,a6c8bdd6,74295bc0,640864a5,7d841af7,ad83aa74,fa858b91,89e246cf,9b361837,a742e2a0,71b08bf3) +,S(b560933e,3400ed4a,eea8f733,d2368c8f,a260460d,f734e209,e194e9ae,a1ac668f,5438f93d,31337853,9feab182,6cf17bbc,ac0975f4,de29a886,1b1c0c02,2c5f9da3) +,S(21dd9a97,baca3e79,77ecf7d,d74433fd,dedf2d96,8c3153c0,2c652aa2,1ccf60b1,de6e60e0,e048b0b7,b699bbd7,cda0c0c9,b851c4cd,34f4b8d9,17c07cd0,2684797e) +,S(5cfa560c,6d39439b,4c9b0a52,f9bda301,2f147874,48c9ff37,bcaf2900,fd934bbd,c7927a63,cc1959b,f3556998,ce936f29,29d5a5d3,3f0dda32,35affab9,a5b11b06) +,S(4a3b95bb,5adcd41,5036204b,394fcc95,6377afe7,b4902f49,461c4b6,866d4fc6,d59e3ee2,f1bd1e4c,c089179a,4db9387d,8d6be47b,df708023,2a0d00af,a8e84f2f) +,S(cc49a313,b4c69c9,13c06b7b,add06f17,404edb0a,dcdb3d4a,81c4b765,35f4671f,4bd722ec,c35e525e,af36c194,3d375592,ba483715,2c7a91b2,4dd57a89,687bc278) +,S(9d75085a,7426a69d,9ccf4f90,d8b4ee0,e07fdac0,18df3d37,40b264cc,d4146d98,5991253,de04b32d,4772f44,de49467d,ce174ae9,3f941ae6,a4f6e3c2,2cc4b0a9) +,S(dfd064df,737bdadd,2eb12cf5,d9f1e192,caa87c0e,fad20d18,b95b0d06,83210fb8,519f883d,a5bf8d33,50b1d2b,89012fd5,9f317299,3eae1226,13d81b92,9103805a) +,S(2b50a35c,d2356c35,d609013e,a66318bc,1cf20582,685c12e3,bf618102,807eaf9a,7d0b51d,303aeefe,b81f5a77,d9b5829e,fdf4241e,435380f6,ce74abab,1dc76335) +,S(e26e8f4b,2cf175e7,c76e2a59,459cd45e,f3202f3,3027f0c3,70481fa8,685abbc7,4c82e7ba,aa0d5161,53076702,997c34dd,716e5fe2,460eac0f,194f72fc,3ac2013a) +,S(5903db7d,54f4d857,6a584057,ce78dc07,1fd90e51,f825c959,b46d3483,5d0f87fb,c55e2fd3,e9ce119e,47c00332,9d18d6f7,febf9440,a18de0f3,81608011,1e9e99c8) +,S(4bbb0ecd,342a82d,c8b881e9,635241b6,1040e6ee,28b98204,fde953d4,4d25e9c1,12eb090,f3445b7,52abee8d,604e8784,82e97e9,b44d2335,8211a8c8,2cb0ef04) +,S(4a2455a,ae87bf97,c6e6eb38,fd3279e2,7029967d,41b9575b,647550f9,4bc4e8d2,5a340ac4,ffe3bee6,2d52bea1,e276178f,9af3422,f9c61c47,4a595550,73936074) +,S(f086d68d,c8ca19aa,54c329c4,c07b530f,94470abd,dce244ad,1decaf87,53477623,911c49d3,84a16af1,65be4161,cc4869ab,4d9e8ba2,808afd80,20d30971,b4bdbd08) +,S(4f1b177e,83b76c4e,24a53f91,2095f1b5,d4b7cdf7,29788cb4,c989f921,b7ba856c,a5568c4e,b060909a,fc3dc2ff,5bb9534b,99debb69,dc0b811,e1044705,7d80eaf2) +,S(eba87899,29a7e45a,23d2fcbc,884778d,c4fb5ae7,fa67954c,76534303,97db5823,e6f8c729,b3570917,9fc46b4,7f03af9e,801b26a6,1724aafe,e730217a,2dcbf68f) +,S(df117b13,34c9a5a7,92d58084,4444559f,130ee539,89cc6e7d,87723b63,a82282c2,dd87ca57,8eea3c51,2aec5492,ea55111c,1a2fc55d,4e2335a8,c9be5641,516f7120) +,S(d775543b,3e68ab88,36eaa1b,df5f6a06,1f5768e4,baa01a68,621321c6,e6ee82c5,70221b05,47c97398,3cee7a26,c4197f9c,27a2bf46,10506e18,493a9ee,1881436e) +,S(a7f10dd5,5a231ae5,abc5c611,68cd58ca,5e006f7f,fdf064c7,1482febf,4578515d,492a33a7,b66b9694,e225eb38,d1d99399,b2c24af2,d69c31e,b4797a9e,703c13b0) +,S(c79545ef,3119abd9,11336c86,c6b74846,801c6b3,812da05b,5d36e9c,620120ec,24c8fcdb,95b6eae4,51473f8e,f7dea06c,738a33c4,f1214382,bd7204dd,d3c28718) +,S(98bab5e,744f888f,5f843ba2,9e2104a3,afa14dd6,6a2206ec,8e783e0c,52c2cb11,83b5699f,e5e87ed8,c51d929b,8146bcd6,a7abaed4,636afcbe,b2c30d2,bcb94df6) +,S(6dce2828,7b6fa44a,c8213053,d39dfff5,60d84a84,ac264110,547752ef,dcac586e,1e1eb62a,b9d60cc4,5ab2fa8d,d065d1a4,c79be399,53578a5c,adcfc629,e237ed66) +,S(e386a59,287a73c9,306b091b,5b24ad8f,db06a9dd,8f6f0c1,b7fb0ace,623dfa83,4a7e73da,663b64a5,e624ce89,9e16fcd5,c0d3b221,42284ed6,852960a9,d05b34e6) +,S(8fdff782,e62fbe31,98c283fc,9b9543ac,cea0a318,2626d180,4beaa27,ea4fe4d5,fef8f471,9fe0d95b,673ed650,8107e887,a4f5301f,4317c708,c5222d2a,ac086675) +,S(4c9093ae,7842b148,1bbb8b8,4ea564e9,36ed1cc4,35c89089,a10e0442,292eaa37,2d683334,93d245fa,e5ac0903,fe9356f7,8642362b,f85a7426,ea2950a0,a65298dd) +,S(cc0634c5,5c5c52a9,d92b80f9,be072a35,56318c6,fd76cf2f,e866d5ba,33103a1b,750b7d41,b13cb69e,6d236eb0,87fc8600,4004aa77,1b699e88,7e8f0b08,d07f0b32) +,S(9749a673,41fa7ac5,8bd33f5f,9cca4ad9,1d53c7ec,cff76656,9a56f71e,3b918255,b685f1c1,9dc7d6,7692a2aa,fe37d9da,5e68fd69,cfa58d87,ec6ced8,68916068) +,S(b04abcef,b57862f2,5a57fdc,b7da0b1b,a25bd253,72bd91bc,9e0377b4,697d8e75,50479a64,66ad4be3,489b5869,d8b9bbe,62dcb8af,da8e7d42,78b5014a,19e168f6) +,S(d11f7de8,5481fbed,f1a3b395,785f00d6,295059b7,c8049768,22624e85,45c78902,1d163368,be0c1290,1a7369d8,11266982,b48928cb,448039c3,17333658,6f5c3416) +,S(a21c65f4,65c4c7a4,93225af,73b63cb2,fd615160,b29b2b90,970b880b,5756fd4b,69a26b89,394de60e,7dde3476,7048a295,57f1e3e2,5f7a586c,7666aa30,9345ecfe) +,S(53c626fb,b080360e,9243d399,9a58ced0,36ccda8b,186c76a4,fdeefee1,6a497a1f,ad926008,62a7ff1e,519106fb,933616a8,8264d7a,c40476bb,eda7e1b7,742ac9b7) +,S(cf67b587,1b2a3ad8,d0364fcc,8741f10a,11d96933,11b72870,60116c4e,74e6ff0e,2c963b7c,10ccd74e,f68ac068,cce1e30a,7be6537f,259abcae,6d36d29d,22b68422) +,S(50216d8,8cc8700,29da89a4,b34cde0d,36428829,de9f58d7,31ecd6a6,c90b4bc7,920c1df0,96bc4891,8defce32,2a512d5a,36f65d7e,65525e0c,123d9fa7,49e38b21) +,S(1d845594,f4686fbb,7b0cc62d,af790aff,3d6000bd,e26ec1a2,67766c3d,93d1aef3,eae11ba6,bd9dda02,ef134035,1847dc6c,92450b36,cd6a9734,25c09f9f,3134d260) +,S(11ad4f50,b6c5b97d,767d590,859e2ab5,2e7750a5,6f7e70c3,d5c52bb7,9e4785e1,2c2bba36,8725d9c5,2152496,f14cfa71,1826e846,fbf7e7ac,4e263db5,a8023b94) +,S(3568d27c,d72373e1,29a4a519,86082a1f,f76ee425,969d6e3d,12b242b0,bd49388c,e36dfa9,6d094047,16e35668,10a8e57,8eff108d,839cf3da,f04c76d5,8754fdb3) +,S(3772ab35,45e09d0c,5d2abb91,97007742,46310f72,bdc0b8ab,afaa2c17,f17801d7,25229a8c,eae0c746,2d7a50cd,a8b012e0,775693af,8edb7260,5340042,a78884e) +,S(8151b24f,72c4701a,e4624779,c8b93ad2,44f3b299,d1ee131f,a13054e5,c29274f2,58938307,25ffd619,de73fca0,50c28d77,73420724,4d2e4c99,86ed5512,b8bb6429) +,S(46a4855a,d4101f8c,60c59705,e537080,1b57a81d,9227f4c8,69234946,5d539c9a,8fa66dcf,21117195,e2c117ae,e2f20bb,9517ad24,5fea8864,beed3e68,89e36b59) +,S(b81bd54,3e654f3d,eec15001,c38bd2a4,efa7c45f,4ece2d4f,fd893c6,15803d16,15c3f7aa,31299a76,34431622,8f93b6a3,2b3947fe,5a894c4a,75d2ba01,4e9d3e75) +,S(3e169a1c,f2a0324d,2478c054,94d58801,423f10f2,4cfc9fab,a5cd5cad,12e7706,20405bdd,d814ac7c,53469075,a700b4bf,4d454b,fca920f9,86923562,19389135) +,S(74283e4a,b161b33f,f67a1b8,cde619bf,557f39b8,5443efdf,534bdd2d,4da65956,22296be2,89785c04,6773ad2b,c881744d,380c1717,1c77b159,bfee3689,d0b3df3a) +,S(62715786,cb76bc9f,b65da0a2,3b7954e6,1a617fb4,de828092,bde3da39,ea6b756e,3c27bbe3,8829a150,3b563337,bf995110,eec54d58,21e1f17d,34a5fd90,52c2db32) +,S(96200105,db23b893,84336bc9,d5596740,2c93aee2,ca35df73,9c55a000,6f7c8aae,3192968d,400a2604,c80307c5,d9865f49,ea41cdd8,e3fd3b19,a2bdfa17,84a6ba26) +,S(bd477798,bd2691b0,8cc52fb5,cbf8b2c5,31787535,541b5c31,3aad9696,b71d13fb,be2b51c9,a4ab0033,c21dae50,c4e7b2b,51978b39,4a66d50b,6be7e140,abddfc3b) +,S(fa149388,e46ff849,bb5490e8,3aac6788,70da101a,f52dab05,9039c305,475289e7,8455577f,a8d85674,3b32080a,dcd26a1e,c75af3d1,c184d5e3,7f22030b,8867b2a7) +,S(4228db83,af1ffb1,d4bbfae7,3781a70a,8ab50d3c,47200e86,ff436ae0,3391ba90,45db1d0a,b0e6f0a1,801560b6,419bd2e3,2413ddc9,4b4ad637,d4071d8c,b7a270a7) +,S(a97ab279,fe0df5a0,3d494c02,eb69c686,1dc3a39a,fca2bd49,f4161ff3,817c85c,5006c8bf,f128de17,3d72f99f,7cd6deec,5d4b7441,6b1ca290,e535c8d,c59bec7d) +,S(c0d46c57,6bdcc661,4e1a3a1c,c19fba37,9f27dc45,5135eb63,f8d44666,904c668f,396b60a3,b28b250,2c97d7cc,f93c7609,3d19172f,47fffa71,f190936d,cb215f58) +,S(73c5d7e0,4599fa7d,e09b8c2c,25c5bca2,b7ae4c6,e1b88e63,6de3363f,b1a8dbbd,1d9ed08d,558bd642,9e986b0,c431d67,9229adf,6fa8dea3,faf17da2,747bc617) +,S(370481d,a2ef4843,8d897c6e,f1a01750,b4788c65,62ad3ab7,bbf3c89e,e24827a7,a88b3876,c2051901,1d84acc3,3000f0f1,ccf794b4,5385aaaa,190e435c,760fa7b1) +,S(2dcbe303,3006f0a4,99dbb7d8,d34790be,f2b68cbf,649b9d54,eda8819d,637807ec,b82b46e3,c7ab329e,b915de2d,f3fa28d6,92cf43d,584f9bda,5d6f58f7,1a90c1e1) +,S(f45f3ca9,16db45c5,de35d957,c24f7a59,44052b64,f8f423c9,8a442f6,17bb4b7,79ddf02f,b3154d6c,da1d6a79,5c64de61,5b4a0ff7,810bbfc1,dad68e60,229b5a96) +,S(500caa8b,cad0567a,465c99bc,c4802553,ee17346b,e3a9ae93,4fe7e95d,e787605e,40847ed0,75dfc8d6,ae19dccf,73ddd256,4e1beea4,7f822a58,f0570c62,f238370a) +,S(30562986,a23962c5,5b746191,e23b893b,7bcd8b87,6fa85557,c525eec4,d64c3aff,2d5abe,41c45383,1b60c034,7bb55464,e19d8d98,8a5d5fe9,37337507,80577a53) +,S(f687d51a,32526b72,9ed3f690,be1e6205,ec72382b,6a30478f,63a18e0e,b48e422e,efce1b35,19c94f7a,fc54da2e,d36b15bc,f197e2ce,a0c2d680,211e12ab,7d515704) +,S(104a63f0,d385351c,c9ce207e,500ae7eb,22199ea7,dea65018,472884cf,a1ca505d,69c21887,50b20b3c,5af1600a,a2a2edc,a6de0be9,33d2e67c,e05ac4a8,30239cc5) +,S(50966099,4b7b8ca1,abf963e2,ff4d295a,eb3d59bd,43029c03,5e6ac9a3,ea80fc6e,d48589cd,40d019b1,81211674,854aea3e,56be56a7,bc8ae519,72963adf,327287b1) +,S(3106d6e7,94e5e135,1d788e85,eb0f2c7c,7ac22e9f,d1c86a0d,d22cf88f,54513c95,c05e593c,4568cc2,992849d8,4006ae18,4ad2888c,82ce8dfa,dbf984bd,2fa2bca0) +,S(4c967d1c,9977bdce,84f76ac7,13b9e5cf,d1081b43,de681235,e7914f6e,2059fdce,866470b2,a3e99b74,15c2cb09,83a5c7dc,fcc10d02,a28e90ee,206be515,e88968cd) +,S(96319099,ae8d7741,1d8bbb7f,bf58f62d,b4027b02,ff5e32b2,e4aff910,3a781a52,6c110074,daf2849,a3b148f8,dbba2f0b,d776eb4d,b787ced4,22edc5f5,67947389) +,S(7c93bb23,87a36cea,9dd7406d,95af56f2,b972242b,759728b3,bdf30fa3,58247ee7,21e4de98,33487c86,6da01e16,895a0e24,17cb34f6,e3d64e01,8f7c4d99,9e989942) +,S(c65e4a03,88de1618,6d9db143,387a3229,c764dabb,7c6ddcdd,c3ba9195,7f1e074,d586d143,8005b28,cea25a45,7c45c1fa,2137bc2,fd78417b,daa499bb,cfca658b) +,S(d895a924,90c28692,bcda380c,71d8d1b8,381b1fb1,a8108f35,4d9a17d8,64d674d5,d30bda25,a63013f,79ef5728,dbbcd259,c7cf2ba2,b00af73d,9804f758,7fde17f5) +,S(90467c3a,5b36b9bb,faffa164,63d1f70,c892e23a,3c7f1132,27bff1e1,5fdef988,4ec70191,40247d9b,3cfccb41,ba22ad76,20522577,1e33d568,946c8081,ea9b15a7) +,S(5cd03d63,d0e025a,7af268f7,8f53efc7,b4d38e5d,58da5981,abcad74,3e294c7e,c3729f6e,5517d41c,ab1510cf,ee4e0e48,f168e043,34dd8781,1a10b70f,b42dfb3e) +,S(5130c49c,652bc5ce,a3dd7629,bf362294,8bf69c02,f9806988,fc700a25,c7e964b,7e46e219,4bc9dbd3,99f98c7,b7a44313,a027ef23,1abe336b,7381c215,6f2cf563) +,S(95899c2a,33b8d4e9,13947306,6b924812,261a3155,e5a7ddbc,c5447796,8edd34da,8967be99,84240292,9ea7277b,5be0d045,bac79fb4,93a08a41,d4dc5991,da6b7cb3) +,S(3928013,8cb3e93f,7c4650c8,8184dfcf,6e55d238,2e75e604,9dd6e40e,f489745f,70b25e98,b897f3a1,c89bd6d4,72f2555a,56bdf04,6fb43799,58709471,f8006a52) +,S(a47e1331,b5fdbedc,e490497c,bff1088d,ba72070d,3cfc7997,fa388fc3,2f80b451,ca54b8be,fff00465,4086c75b,da3ccb9c,6244746,522124ec,ec22666e,a9576b19) +,S(cc1a608e,16c57528,3cbbb134,4083cfd3,f1b325cb,b48df6c8,2d50bed1,e0cfb96a,5b8aca44,67d9b224,413b0c98,78e09213,591b8f87,b024bab5,55120a83,38cc6734) +,S(d8354bc7,591ebaeb,7ae4d1df,2db3bde3,b7438d1d,69b5991a,5d70f6c2,c3fc3cea,efc89693,6765f03f,29422703,97591bed,7d95afc7,29807a31,fe266f08,9eab5ad3) +,S(6ac1c963,ceb2740b,212ef42e,6da07647,481ee21c,4e3fdd6f,f2ae3da2,8ddef8aa,4fc8817,1b6d5ae2,45453c94,f5f2031c,c52140d7,a110d9f,b1bbf3e8,e5164281) +,S(be130f59,b52e4148,f9c47469,778fb36e,74d4da3d,a00f5c4,dddd2e47,6f18b42d,16dcd9e2,f739a58a,22a7d76,1c1cdf61,c5b9f8b9,46449516,9398dc1,fbc47069) +,S(685db8cc,39864a55,68b56e59,96265bb1,24ee71f9,1f9f4f3f,fc3c79e6,c063bd2f,730a7141,8e5b2f7c,2d333b8e,5be3021,22b396bf,9a75f493,37bae5c,86b50f29) +,S(39f41ff3,89f74c1a,e25e564,b9bc189b,f31f9af,cf0ee4ea,aad66ee6,55d743ae,fbea0f6d,e25d4fee,53f0aad0,9338f739,26fdaeb2,edf9d8d8,8e1e520d,d66c8622) +,S(d7a69574,41bc9639,994737b3,d483bc0f,c29b1b62,cbf59f28,b12b208c,4c20ed1f,ce44e2da,cdf8158e,9c07ca25,1b9a3d06,91eea29f,41f824ce,ef2d631b,65ba8cb) +,S(85bad160,9139cbb7,2be86793,42b37884,22f5981c,5fdf30ba,4914395e,c1eaec9a,99fcd461,29e576b2,b25c57e8,8e3fe3ea,362055c7,843838db,4196a485,cf14dfec) +,S(2380bac4,d428a159,23c2ffbe,8f17da09,74d986fe,4210b72d,51a1eb80,23ea49e5,f4af7313,fde4c7f5,e45e38bf,c4d44bbb,3ca1015b,d209065e,5a6ab074,5ed6f54b) +,S(c0561359,b7d61dd0,e359108d,f221202b,97c1acfb,894f4e9e,46fc29fd,364f9cf2,3c377d80,1c72a9f6,2cfea5ff,350ceb32,75b16103,cecf492e,2901327,d27d83dd) +,S(72c499c1,b8f4f2a,eb9181d3,9bba5b2,76481c04,a588fc6,4ed438c4,920c2a06,6c994c8e,60825314,2a34867b,1f82bc1a,f05ff8ff,b3045e7a,72d01243,b2b1ce53) +,S(8de84cbe,2b66209,f8f8e2f3,f06feb45,66e02c9c,b5df26f8,84e20454,ffcf477d,c7f2f680,c4d07d88,69348e98,6a3b7ac2,ac9e8542,a019f379,6410b993,742a34a6) +,S(dbfec9d8,6581d762,e5ac8048,886b9d2e,9a2d02ee,63c5f442,7d02d12e,401710f2,6e611ff9,827bb1ac,a885acb5,906648d9,b46496a8,98a13c90,48868d,c0daafea) +,S(9dd651f8,6099edd1,b3d0ade7,82aae6b3,9588dc2a,291577f9,f2456f23,d1d0453d,4f6db617,f0d7860e,18be81a,dfb6d773,cd3f905f,98611845,5f5a0b05,ee715ebd) +,S(2fd8161a,c869de35,e777a885,ee608f96,356445f2,fa2f33d1,926260bf,9bd66a15,1d2c21e9,674c2d92,b64163eb,12de6347,98c6e7a2,9787daa,7c6b4c80,fd307f25) +,S(3f25bf89,24f505b2,3f1538ce,4940edf4,8b6d8765,f88778a8,495e8a84,a29dc391,70253583,e7e0782,18ab0252,52c613b8,34438254,9dc57c30,afd47297,2c8164f2) +,S(3c0f0359,d5f72344,f8f3d2fe,28458f30,467dc770,b55eab47,ff2e1ee2,6c773f0b,49583a39,459f19c4,5ac50d78,74626524,b9c25030,e45f2c7b,12729ca8,1edb33c7) +,S(56380666,ec1b5df2,36045855,fa0dd93c,87e38d70,fb170dd7,3be5c308,36b73a15,700690f0,b210ac6a,9aa91252,c8af8f60,b5cbbf93,8291fb11,7bce1f0a,759921a7) +,S(71ca710b,b9a5f7f,ec6b228a,af3fc47e,25f90201,fbe3c673,8bc6d2fa,9c9298bd,7dd2528d,c0750899,b1891287,170159ae,c759bca3,51e243f8,fcc9efe3,2f9abc89) +,S(78ddec3c,c938850e,7c2ec20f,98e1be3c,6ed87fae,827c9102,5112d0b3,5d264575,19072951,766a4050,c8585048,d6f19e60,22b9c163,f1799ddf,d486dedb,3d680321) +,S(9aaebafd,8852857e,8c670950,93dac29a,5813249,ed03e67f,3226ab3c,7b4ed70b,8c6a2acc,b541bd51,65e13bc,a3c4d2f3,2457bdcc,406ba71c,7b9cecd3,4705fffb) +,S(586eca74,941180fd,da16c7b2,8b9bf139,a3096a6a,20ab9bcc,6d12be5b,db2f79e2,b3b1d12,361609e5,afc5a7f8,26a21ea,ac4bfde,56016ad5,bfde6f93,a3488d71) +,S(1857bc3e,dbe4de2c,86fed7d4,cc3ee63,c0e0b6b1,36acf97e,e3638183,8d50ddf8,ea5e807b,e7a588cd,ec759c67,3584675a,8a7fbdb7,cc5a1835,119a4f64,8c275363) +,S(aa4cc744,7572c62,22a6cd,bcb8813b,64206796,27f5f7ba,863d8566,78e5b01a,ba969ac9,d259244a,9a3b7f9b,b3821a61,a4a97b8d,af7e08bf,f39f099f,8fa2f836) +,S(4588ec09,59174367,6885fad0,a43d85cf,d6f736b,cb276179,e794da35,204f36aa,fb835e7e,cdc681c6,ee1c89d1,dcbae3b,a9511692,a54c9c37,2f86f4b,cc7c62e) +,S(867acd03,7a3e5f86,99e33f22,72f7b1fc,25ce6622,5020a4e,ca3b3111,e880653c,e9112ac7,57d3f905,3249ba3c,ff64640e,639cd94e,5d6cf946,d8d7f3ad,25764646) +,S(5e0a4169,e4f81dc2,28ae4663,9ae3bd4,b527814f,4616fc13,318fd5db,26df370b,5bd335a8,fc23934e,bee2e32c,3bacad4c,c38cd624,8cb34ca9,e58f8add,3140d001) +,S(90053469,39df2418,1b5b2e57,82a82f15,542a55a3,adfe8263,663b4fff,b101c0f6,4ff0d589,973985f6,858f3837,89c3a5e1,74460778,3a1b1476,e3f1ea51,37e3d991) +,S(a99439a5,53df33ba,6a32f33,d90b1500,4e2db077,22a73561,8f4c3b0d,63cec63f,198e0929,f11fc777,ea9cd8a2,e4e6987e,6f9c1fc5,f703ce7e,7e6423db,39656cd4) +,S(51f2a136,1381ba14,c8fab71d,f82aa2e7,1c7789b1,b78c355,a0e2fdf1,5f085282,fd5f129f,ca15fea4,d6f23bbe,43197a3e,6e2b7b26,84934ea5,a97197cf,eb2d16a2) +,S(3a91f81c,8b064b2c,99509777,864c5b4f,bed208b8,f541f68e,82053158,2ea91d3a,9d59003a,d4ae39e1,95077329,e585a8e8,a542b594,b6010404,8573a01,23a513c9) +,S(71e99d50,aa22fa17,3f026dee,e728c114,5e491e84,e140b462,1056af19,9736c5c8,ff3e4f77,68588846,7c662729,1d947e77,699806e3,9bb0bb26,53f67ec4,176a4995) +,S(ad149e93,3a0344f7,3fb53286,ace2f3cc,46f7450e,e859980e,6d392001,7c8aaa39,7dbf4798,85a4f354,b4f14060,39a83789,65a5ab3f,f1157e3f,2a4f6fae,909e81bd) +,S(44f0a37f,5ad78f6c,4a40ca20,7969105e,86e79ed7,7ebbcc32,1a247f91,751ccb01,f404d867,911eb3fb,efb1e559,66b5128,70836d9a,12891905,af649555,c353044a) +,S(4f77dcc3,de8de08c,4c0a4a8b,29717868,50f5c0e3,b271ec1d,c0d38a61,b30ad5d,73c7424f,8ae80ee9,2118aa5a,b0aa65b3,58dc7300,806ef2fa,55836a39,4df57c69) +,S(794a108b,102a0923,6366efd3,8ef658c1,6d6d5c24,e5e2dc0d,38d71371,e6005555,871965ef,efd79050,69acf0fd,c1f84798,7c9e304b,5fdcbf75,1a6f6737,ce46ba2c) +,S(f1988561,234b863a,df5bd49f,5a0b1252,a72e297c,ea3083a8,22da48d7,14e8e594,7adba507,d0ab51a1,8c036612,dfda3f8f,abd2f573,d31aa03f,ca6eb361,a83fc418) +,S(48bed556,c07c99e0,71249b8f,7790aaee,f3fd27db,f82d1c75,491a18bd,cc3f4a80,9dae5280,21be418d,1b4dd08c,be5dbca8,46cf0122,d4943543,8561e555,66316e94) +,S(bbfef3fb,e53779d3,8f376fef,974bac74,ec8449bf,c2dc8a1f,3bfcb33f,943ab9c1,bea5b772,ee798aff,c610e849,5be0ea8c,ed462563,848030b0,8006c6cd,e312551b) +,S(42af3415,27b3cd52,3806b04b,ecc175c4,156839af,eebc212e,b74bd6,95b7f06,686e5fe5,ebf16ff6,2376d096,188de980,f91a5518,25bfa137,e7b46df,59dcef4f) +,S(3c56d78b,74ae87c4,6efea376,d58b7d5e,30749726,40c24d69,38ade127,71ce10e6,ce97decc,f9d1e215,d363b36b,6ca2bc6c,39fed00b,511bf883,50732752,48d54a41) +,S(4b122599,1944ef0a,ae6404a9,e48f69ce,67b52a1c,da4f291d,33afdb09,b789b61a,5c8be350,27a3f992,5377932c,b6d92bc0,62b1bc80,78e4611b,f3ebbe66,b6089571) +,S(9e42867,c02c9314,a3658f18,14d8c59d,71674955,2b00be9a,cd37350d,18d49db5,5d26d035,1ff90d73,d783155d,afe20cf0,39f65b1e,6d8d5d0d,831977c7,17a8c761) +,S(9643390c,5a95345,2a027d0d,47bf6fa8,306ab31e,5dbd8b94,402db973,275359ae,b354d7f7,1019e9c1,d23560d0,50fbd4bb,abbf492d,f595c0ce,a699721a,b27a3933) +,S(8b4916fb,86f77deb,505374f9,1f15782,1b6f7884,feae9f77,bacf5620,7e126b69,9a83c0,6d86db13,55c3d59,cbc87fae,ce6d2af3,64f9c213,816cb326,28be1fd4) +,S(d29df4b,109782c4,1f5ee9ab,b8488f7c,11de8efe,9552eff3,7ba3cf0c,d0054b9f,1bf06237,ea242c4f,bbe08f6,a79b6808,d1a5a444,1989fd1c,98a60981,40ca07a8) +,S(2aaf397b,a5405044,539167d0,55113acb,d4a20265,206ddede,203b8ea7,21dbd41d,374e32c7,1132bbac,91e4b4a8,aa32f308,13a81c2,4f7b3c66,63d8821e,9ef73081) +,S(2239b3d2,23eace6b,8ebd287c,8b6a398c,1ca58a94,5d8b7b81,7b1133f9,cf57ef48,fda880b7,4b54a8b2,8af4b26,78e03f28,f01d70fb,3e4ebbda,94ccbd43,e2b4cd46) +,S(8b3287bc,f47e72df,7edc9178,51edb145,b88ee233,9f254f62,e86ec624,a7c7e365,54a06bc0,9f60d54e,5f900868,c0c3d37c,db6d9969,1eb605be,321f0f20,9fecabb) +,S(d9accea3,3e3cfee9,10d7e1ff,3e87539d,ace742c7,24d6d36d,d8d981ca,984f7993,6adc974a,a901e5d2,d8cf5a05,a20bd02d,62947f81,5425e690,565638a8,427dc88b) +,S(d7fc57f8,34c348bd,e6692b50,474ee038,4af245da,40b8f6b3,8df2ae5,a8b3206d,b253e4b,41fd9fea,9b28e04b,a6db0324,231edb1,1f9af406,e38d2b30,244e2d19) +,S(25808fe0,ec4a1409,36b34e16,595021e2,b815f660,7a23d505,9ad5b5c3,14d9588a,d0664ad5,b1d46ef8,8c8a1eef,bb9df1ff,a75bc16c,e8bbcec6,6f4798f7,c58e7b96) +,S(e4474780,113955d6,72152fa5,70da35a7,59e67a76,29a39ecc,3226ea13,99927914,493cc170,aa2f0486,da6834d3,3566c78e,ad4eb3d2,837ef5ea,c1adf3f9,43793bee) +,S(c5040dbe,2af9d706,76ddd900,d00f1046,44e2b985,82d46f11,47602b91,126311ad,840aab11,a2316171,cc9b6466,778a9ce5,a7cabc1b,1077586b,91a8d280,324ddb15) +,S(23391baa,316d33eb,3a7ca123,6c47d4e4,8116cd4f,93bda3a8,12a228eb,437d9f14,1d81341d,9e6d76fc,1ca69af,f6d8d119,bc97c79,c7cb8b7f,1ebb54f5,cb7efd4d) +,S(13211756,3de3ba72,2fc6682c,beb39494,8aeb8fd8,c0b95eb9,45eab34f,bc39ac38,9b772721,8a4b0823,7c961431,e26cbfb9,aa527905,41b753df,89eb9ad8,8d74f006) +,S(3b8bb898,b27a2fc7,a1cf896b,bb5cd7e1,708b943b,afee896d,2ff77a95,ba789708,d81e541c,668003e5,5a1e13e9,6a1635de,7fdcbf79,c34068c9,248100c8,9d36c1cb) +,S(e1d70a2c,9af5c4ba,c505e4f5,5c0040ff,d94f162c,815a2e21,c7ce899f,e0217b4d,b25630d6,d20e0e4b,3686d66d,e2b1e53d,eb063b99,e79c212c,2fd3cfec,97a4532e) +,S(1b1e3823,a51778fa,d38f0c56,e2b36dff,a7e681c8,30fb41b5,ff1aaa7b,d912de1c,f2e99a90,a951201d,ce725855,6bf7fd27,bebe1626,8328116c,d593ff32,2584d4c1) +,S(1e31d838,94f56191,2c134817,55e467e1,8745a91c,d903102,e48f7282,21bda7a1,11dcef88,35dae18f,3c02c6d9,7f80896e,477a7b27,41203aee,5048c94c,7cd610ce) +,S(cb9ac34,795cbc99,bf67a7ff,2bc3b497,311f687a,51b5028c,422b0301,8ab7100e,5e5f0621,c804b35c,e01e95e9,a8dc13f7,e5ff32dd,8a44f320,74e44836,3cd0db1d) +,S(afc34ac4,67dad38,a0e326fa,1a656c48,24dcb884,f00a20ce,56c73835,b4e11c1b,c8b1c404,3f6d647a,382ef031,a02c10cb,77a033ae,bfc6dde1,d7508136,28bdcb96) +,S(3a6fc160,ca85aba1,619430bc,ba14e12,3330f636,7a78273e,603f85fb,e270aa81,594a2b72,86dbb390,945a7a48,3707bc32,cb72cfc9,19c241bb,61774dba,222bc0a) +,S(a840f695,657c9c3a,3f64f56e,af18debd,bdc1e4a8,e3eaee43,46b19601,433ce7d4,8a8a7ac0,ca41e2df,461eae96,bc00131b,1a77b824,7273269d,7a41f49f,ea126fbc) +,S(c044e01,70ec6914,c39d08c3,4a293268,65cd7762,d6e0f3e5,5f69d80a,e80a39d6,7bd63082,7ae51516,25ee0b5e,c2f97b37,6dd5fd7b,9205852a,92dbf922,3a0b4657) +,S(cb90135b,352b969b,45eb5c6,7cfdd288,2bf9271a,41da4b2a,a89dde94,eaa00b3a,14cbeca0,762d9b11,fe4b6d26,7277a8f7,b4dac82c,52634b49,2a84b616,2d79be93) +,S(fa7bc437,a24dab0f,21c7c063,3aa4a8ff,c8216676,75ea6963,c58c84d0,b182a0e,e24267c6,d7300c6b,6dd09326,c49359e0,fdf72114,401f244b,383eee54,d1a5aa35) +,S(e6354cdd,3f503d25,37b2bef9,91533ad8,35e95657,3bc8afcd,d0c1c05e,57b3299a,d6c17b70,6291c8a1,989955b9,ae9ef9c7,cdc2b6f3,f5cada0a,3c4d0b86,859ead7f) +,S(9da36530,7e815e3,df0dce9d,50d7d812,132ec23d,2bf0453b,483af1f,bb45cce8,bb374566,98a28ace,a86a1b10,2909ae91,3bbc4b23,22f4d09e,bd298e51,d067a8dc) +,S(dc457a1e,1a19cdc7,6ed1c3b,a416a886,13b25788,22d691ba,76319b8a,38c9d4db,39f93f66,de5a650d,d49919fa,294638a7,85e25bd8,f8285776,dfce813f,bbdc3b58) +,S(b2377b1f,1b1a0e98,5ff57bc6,64ca456f,ec216c6e,b7b389a9,62b9d82a,ccf0374d,383a5580,d723509c,bf114e74,b3eb9746,7a040fc0,6232adb5,dac199ac,77578c1a) +,S(8b1a6446,755d3a85,3851fabe,b95c24d8,2a5a86ce,5e5df65,78051124,acfc7e50,42b885d4,cb632a67,51a88aef,192a5bfd,ed1cd461,438cb623,1caf3346,9655cf75) +,S(9408819c,bacf1a0c,9e5f1416,23a907a7,c3a7efa2,30a15b3e,7d5a6ff2,5103f5b1,a9758ec9,d6f84f73,fd107451,f0ab79a2,1df08c30,cbb2456b,d6c68cb,c506f98) +,S(8bfef047,7b3f8cb,99d7c933,a884da4e,9ce6d473,c243d3ee,9c319870,b06ce25c,8bbcbd87,d06af17,550d17ee,83017c58,627f1d84,e8a07e37,ca73c12c,f7e5c498) +,S(2a857f0,c12202e1,1dcb84b8,adf582f9,8eff647f,c3803cc0,dc1d294b,414bdb61,9bac456d,a7fd9318,244af8c6,48ea23aa,62c8ae1d,af7fa9af,e430efec,46db6548) +,S(937b8c5a,90485ed3,d06b224,2ff53e6b,b94b1ee6,a493c835,25e3acb6,5d5cb5ec,d37b136f,f9fb374a,50f5a311,ae366ca6,c9c3d867,e9b7e788,da3b2766,a7ccd808) +,S(5f544d53,e2bfd6be,d9150ff3,6a1e5c5,22b24933,489201a0,65a0e0a0,3a43c77a,ba9c20e2,8c47cd98,1752c413,70ced32,8f4c847e,20165562,c3137e0b,12990f51) +,S(67b63388,90bf8baf,a5b64fa7,eb9fa4c9,e3249cfa,81a55cbd,9c297e7a,a7c807b9,dc185675,2d94b811,42b54577,edf808a5,d871ec1,6c8ba567,62061dbe,ae7625e6) +,S(587a9dd5,99cb448f,9f92ffa3,d6328032,b76604d8,386a2e2f,bd324628,98439442,496998e9,a893faa7,a49e73ca,2dbbf533,488aa687,51ffbdee,6b6d6dcd,dbae9870) +,S(36fb7b1e,c576ff9f,81077312,35d18612,18dfe51a,58642a56,8f80294a,63c29b38,34a45ac9,b82cb1bf,2c96fc1a,67de8a63,5c1a1589,61baf8e8,a2f01572,1566c4aa) +,S(87b71c8c,a0afecd2,dd8f49c5,109ff434,ab8a273d,4e4efcae,f775624c,71f4ba95,8519151f,51122588,76527c56,e1e6d9c8,5b3626a1,bd6ad0b8,1bc382cc,525676f9) +,S(acf65cf2,805c370b,a3bed962,c3ba3b0c,56c98,b81a696c,f433a0e7,a463e040,f093929b,f45be16a,f962762b,52f57ef2,dc7b0e23,cd68e3d6,63b3b402,15692d5b) +,S(e092bfed,8b010c85,b91f1674,1cdfb1d,e3e045ba,81297f44,8990475f,2147acf1,e0bb9842,ecc8683d,e4016072,86070da9,8c4d18af,8bdda91b,65770a98,77902c37) +,S(9bdfd7b9,8260bcbf,17812735,c70501db,ba386b7f,28ece691,97c871ca,610a52ae,9bc65398,3f8c4cce,731e01ba,a5f509f4,887d9a78,40620d9a,ffbcfdeb,5e371eeb) +,S(3db22321,d9311589,5c85587a,9095421c,afc8a80d,86a4240e,9a4a2f82,8643545f,42af30b8,2c57868d,e0f23c9a,fb19947e,fdd6bb45,4efc68bf,ddbf7349,8fb78eae) +,S(e9d3f14,a6a77ffc,f86decbd,c5e43fa3,c3757a64,22d37da6,25627961,622b3e5f,83ac0bed,1e2a714c,c6ed0764,da92cc17,fd18ee84,36d667f0,2f90f818,30e67de7) +,S(412486e4,f29b4887,e1448af,ad59599,b31b9085,8682580f,891d51e,9842f2a4,c31c5931,8c0d6790,c2fbbb03,9c2e761c,bc5577b,53161a8f,80d397f,de7ee3d) +,S(e9deec71,41ed506f,e2dafbe0,c9ab75f9,609f8422,a4b2da26,7c529d92,36b4ddaa,8728544,d8463bc2,d846029e,5d2a0a40,8dfb767f,9adb79eb,2209478f,6d94a21d) +,S(5a0a2292,553c46a0,823a1761,2b8925e1,bbf01c2c,5bcb7173,5f0fd6ff,b264218a,3097cdf0,adda0f10,a261f897,6447ff9c,12de696,8f05009c,e90d1575,e55dbae2) +,S(49cb2a37,8b681ad1,ba1dc23d,8d12f186,563a40f9,ce0ffd00,5bade11a,4928d1f,f235e2af,c0f65fa0,ff15a938,ad804a3c,fbecc5b6,e276bbd6,32a06959,3d6732d6) +,S(d4d71cb6,36881177,b05ad510,a621cd44,3dd1afd4,84d177cc,f99abdb9,1615feb3,3ad65378,de3eb9b1,606f385f,a950d533,5316c363,fb076c02,ac7f12f0,7562645b) +,S(591b2e1,4bdd6e00,64f798c3,14e86cc5,529c99b8,3f47d148,b7e3e642,35bfab2f,4f686266,fd2a4c66,4d6bbaf1,2a368d59,12a51789,5d783aec,a986a568,a8fa59b0) +,S(ee503c85,c984bc49,3d7b63c2,92eac9de,be253400,f4988086,970be236,47356876,bd828abb,6f9e89cc,741704e9,614d6711,39449bb3,a7ebdccb,976c573c,4bdaa47e) +,S(2f9b4fa7,2e5a1fc,ca36a3f9,8987c3af,756e78c9,77fd5697,758c95b3,14b3f89e,9668615b,3d5b3c74,4ea2e1ce,e909d9c3,956657f2,1a65fcf3,3f0ea150,1ca4a15d) +,S(18b6d06a,a34124f8,5f92b204,e2a010aa,a1f4aebc,6e13a62,34eb1c92,7afd46c3,66cc31b9,bdf600b0,7e624bf,a3e079f3,258b0ba5,5437264f,b460481d,1f4bef4e) +,S(3bc07963,bf758dd8,fff37d0f,30db6eb,67662a4d,65395688,1cc30340,ddb44ba0,60e11ef2,68209a1c,2df9a3c2,276db6f8,8e6dc1ec,b74548a3,57d770c1,ad057e5d) +,S(bf585d6,5b325423,afd49af3,c9fa68a,91498b5a,f0ee9e3d,d089b288,53a46a8,2f8944e9,ea484b9a,51256e2c,fa9e5396,4c000c1,3451cc05,94bcf6ad,e38e66a6) +,S(887c0a2e,be7a0257,5d5b59a9,11f40ef8,f0cf1438,d7f05a7f,64e9c133,cfb69294,45f334c8,4f9bc66f,50fde594,94175491,9c37c30d,d20f6a58,40271e71,60aec5c9) +,S(9dad7af9,a73325c,59a17700,fc3dc6bc,3718e79f,804a2116,1bf9a36,622f7d4f,2b7c225e,99c6a94,c7e326ec,b89eb8dd,40644bad,1893136,6442985a,e6159525) +,S(847e4f95,72bd29f7,4f3e9a2e,d73cdfcf,63bcb61c,9caf8694,7cb84594,a7dd551b,ba6ed282,e0a92c62,fa86286d,370cb344,f6f1182,a101c4b8,1ea89a15,b393ee16) +,S(25213205,df1c3600,4673c4b4,49256c70,b5d8c62c,cdd3d580,2684af47,f047a593,36dc81de,5af4709,fae2a47a,8a205647,95aabfec,42a79f3c,54763d67,ef096837) +,S(75228cd8,4866df7a,4713a25e,f2fb29fc,95ebfd70,5d73229a,b170cbce,1058e87a,fba4879b,cc02d3f4,fd25f056,c0854415,68a47355,929bb812,a7dbb30b,c012fe6d) +,S(74945539,22867c08,6d02fb07,c0424890,981a1337,42c63fe4,b6adadbb,59b68568,7d774917,8df8b19c,8af0bf0b,5247e751,3e3b8d04,46465180,341ebb54,1d1af3e2) +,S(69db7f53,2899e39c,fa0cbadf,c29946f2,71d28ce3,57f47f7a,609e0fcb,ffc9b04f,cb0243bb,103255da,ad423ffe,e1d50f9f,26da7cdd,764a11f0,a6694b63,199feabc) +,S(727ecdc1,fb4a0dbe,fd2fc37,8902f922,ec4aedf5,53dae225,1d173c29,2929f8c7,ae5bb2ed,13778d60,66446ee5,e5754db2,bfc4f7c1,64bc035c,224d495e,651f453b) +,S(903ced8f,ec2544b,e207f5c9,e2c7f2bd,91213873,5eebc382,b129e334,7ef25b72,2117ca29,ee13d31,5e89bf33,afa8b7db,ff75c795,6be40c8b,b2e41cd5,943190a6) +,S(c4d467ef,5149e117,3638a5ad,6fd36373,1c8906f0,80336ca3,3a6bbb99,1a03f33b,ea5b5b24,4c536bcf,ce3d437e,abf2fcec,431ad80c,ff975b63,bf398163,629b5c7) +,S(16b577a6,5f6d09f7,b23b2b7a,dd80a2f1,cff7a8a6,c36bfcf9,d325e37c,ea37326f,66ba8e2,14674e5e,228a6576,a52a791,84d98be1,db1a2dcb,e9073934,d09f15c1) +,S(ad4bcaf2,e480adfc,e1e45384,6bd7ddf7,67fceedb,d2bf1f5a,6768531d,9b63412f,51fa0360,47810f59,11b1b3a4,525ee72c,c4c891b7,56737f4a,a61a380,e9e741ac) +,S(b249eb38,52d2e787,4a52d776,d1bcb399,51ca65de,dd9e9dd5,87d73362,c33b571a,3e260824,14e4ece8,83cd84e,b177096c,62dd7706,a79c31d9,b1103232,53a66258) +,S(634192c7,696a01ae,81310d3a,59d2c53b,74dd0560,7e3be9db,ccfd1ec4,bde14a65,455b4850,e366e077,d86dcd70,9c787b18,4fd4cce4,4b92954a,dcbe5222,57b0e00f) +,S(ffbecbf5,d433f80,49e159cc,c14b198a,acc3c5ed,fbb1ace6,fd295dcc,4a2f5099,422e7aba,1ec66cf4,36489acf,9c03ba33,dd68d368,8a48685c,aaa1de52,440be3c0) +,S(65b4c4dc,1067e823,9cf4f1a9,d0632da,b6a8c83b,509a75ad,8c133dd1,5c1868af,f7cf5d9d,d7654618,5183f8ae,7f42a03,20c67817,9d5226d8,40dac1e5,f94d260e) +,S(d380ecce,9d603502,d518dbed,405b8d0c,8de48dbb,35d5b559,24c1a560,9bf9c67e,1ae84480,fd18ab10,9eb0ac15,265c609f,8b241b4d,a80b13ae,50c35f8f,db64c128) +,S(17189d28,b5ce1bbe,d78a1d96,15dd1a50,3fce43f7,19d042df,63484ff4,ce44511c,fbca28f4,7c7b3e39,4121b948,ba561289,85c53298,8db2fbb5,7596a473,a782350d) +,S(fbe332c2,e2a8b07d,a85ae4e6,1925bf3d,be685e4,fafcdee7,3f558382,80c2e84d,aa917342,5e187da0,e3f8c6d7,79b42cbe,b11c43e0,6b594eb3,e1a5797,ea4e29ca) +,S(8b9e8a87,8b5e725f,8b4bd518,22e9cd21,2100d1f5,cdaaf210,2d7963b,a0bc834f,331fb31c,c28f56bd,5ff1d6ad,80b65702,b2e873dc,4552c563,bed77a08,cc3ed659) +,S(97e92411,a3c0bcad,17a798ac,eca61ac2,34e1a68a,b668aa3b,d730cc8e,8de111ca,b0f170a4,bac15e17,2e75fb75,93c21a41,4794976,bafc7eb,7cdc4bf1,6947f48f) +,S(20358813,33a13c6e,cc8c76f8,2c279577,49aa3c1f,d4d51691,9cd23b25,d044eea8,480afaa4,8c86af0a,ece2f951,7df0f344,259fc4f1,4d9a5c0,ee73c891,780c7f29) +,S(caa1eccb,1575740a,90155103,9849befe,617579e6,22b7c343,a665beb7,a67dbcff,aa695bf9,f1c972ff,b6fd3451,1bf042d9,1aee5113,9c1ea577,e0bd52e0,a4e0a20b) +,S(8e7c2ba2,36f7a8e,fdaa212a,7fd6b883,f331049e,6e8f2bbd,138a3adb,c2620719,bd03702f,1434fb3f,5846c4e2,e779f8c0,d9b6e031,1feced02,20a618f8,2eec105c) +,S(e07dc033,6dcd04c1,fcfebf09,40c07783,88fbad11,8e4eb3b2,4dd637c7,baace975,b13bd0a0,e5eecb0,762ccf31,1bd53156,ef6f9268,50044195,10d6616a,b32a2c2c) +,S(6606c825,2679af01,9d8a904,4db0b28c,95aba791,d1c33072,97afa2df,bb8ce0cb,7505e59c,a9807993,5710de77,747868fb,10fe6c57,36ba2054,6477cac8,8e1d3cc) +,S(9fbf4cdc,ec48226c,b45450f,b0de5dae,2b31f935,2b99e0b5,22ab9935,1de6f061,f2e4d0a2,3da020e8,60a0d58a,2362b7dc,e9c5b646,7034ec91,a7dfa601,1ef850dd) +,S(e06d697,5195ffc2,988b0403,e977d32c,b7cc8167,e800db1b,976f6186,286916bc,8015370a,27d3d221,7af80e04,a49003ea,68302bb,c1a5c83,63244c0b,c30bb8bb) +,S(adcd67ab,21d2aac,65112fd4,e6e16cd7,ff792577,e9785a6b,cf4a3f0a,9293a6e2,6527b620,29062aaa,5058608,f5cc3bad,8e4f40d4,9b5be93d,faa5c2b,57fd7fb8) +,S(1d9069ea,b43a64cb,1187e963,d96809b3,5a447317,68910e13,3e0bf7a2,e1f2bd38,ab03dede,854b8fe9,4ad2f9a6,8ef5415c,fc78c28f,a4ec33bb,f15df31a,91e29108) +,S(f1f6b776,b8ec892f,148168ae,8ce83f4b,603206f7,2a38140e,3a422e67,a20a768,892ba036,3413da21,17d9b11a,7bb25cd9,e7136a7d,82a7f45d,14abfcb2,b9bff25a) +,S(a884f94a,ce79f4cd,f3a8d1b,f8a2dc3b,c21d1c23,433a7fb0,401c5df,1efab379,5f53356c,6e45248c,ec282fbe,ef03ddf7,c611affa,5d0d3082,dd630f80,dea05c96) +,S(b1988430,197a8800,e1016564,b48d4f7,1fb2be08,35e9efe9,81a80f10,e61da9ff,d5c7864d,ea7d12d2,5be7ace5,86e141a0,e515a41,5ec70bdf,44a68d8e,4dd849b9) +,S(15b73aa7,529d5b84,bd5c1db8,2b6c93aa,46985aae,942f6d4d,1094434e,d27fedb,297e32a2,bc8ad13c,42011259,b1ca3d40,632ac6de,f2fca262,75dabc8,ee721f89) +,S(339a76e0,443c1fb1,65992630,116e523f,8e35cc7a,16cd0f3f,57f7782c,7d97d40f,8990652e,fecd784c,33e75620,13b52e6f,914f0f6b,c413aa22,9e5bd773,cdfe9659) +,S(bef26cff,fb80ddab,9458312e,9b09044b,b1c535e1,84f4e51b,f64b5183,b67adfef,3818929a,ef076a83,58f20518,c5b310f5,2c6943f2,1675bbb5,ba1bde45,9d37490b) +,S(cdc56c81,8dafc273,4f4dae10,84f91b08,3dd40d86,23125894,c71d9243,8b2427e,f4b309d,e9c828b5,44542569,45579f91,b4376935,3f586c71,f07107f0,1f503cca) +,S(3ddefe81,b1f38479,ec9be80a,1961c5fb,a09312a6,2a775911,cd65200e,7d75bc6d,75d83edd,1eb9b479,4effae4e,ba8007d2,7c7e2d51,a9e95d3,a1e58358,56df055d) +,S(da7c6776,99032cbc,4c2bae12,59212cf2,a18879d2,63aaf99e,76339041,10576826,2e7a6d88,360ac45b,9871f779,9e80698e,4314cc3c,3f1cb1d0,c07ae9f3,38553f08) +,S(2611b435,e0bc20c5,88cfaa80,17f4555a,b8aba4c4,ae1c0385,9dfaa911,aa80d927,eb58f81a,e51dc504,465ff8c1,c0529fac,e47549d2,429e5b41,7ce0cad3,7d4508d4) +,S(b0fbe548,36f07c4a,a715aa08,806b71d6,b8f4c09,6945a7bc,3defec7b,67962961,cc60a224,66e7744d,c58668f,ede30ca2,1c1749b0,45ee50de,2a881a53,83e5abe0) +,S(1a03336f,dc51ee75,facb7688,b4603c86,77d371eb,5ededa9e,b50bb49e,c9020581,3fcf1b03,9c0edf8,99855fc3,6acfdbc7,bd507145,9be7e18c,e9f715e4,98daa7d7) +,S(763a1215,c8349155,aa849b20,f2f68a36,cf72892,49e4d3c3,810ee72f,78c159ed,37826a1c,cf30e1ed,a1795fba,d1f2f227,7b68d5c6,9ffd390b,d7dde5e6,58482684) +,S(7fc7b4c2,30183e37,dce0a586,a6f0188c,f7e664d8,5fa05eff,63f2c27d,cada4edd,fd7a780e,6ea89a06,f0649343,abe7bcf,6338d2fa,fe457f50,ac415c91,2bed6a8f) +,S(222807c9,b0686f55,d9eb7d7,412588f,dc543bfc,f016c8d7,74726135,dc65ddd8,b9670902,456c22ef,cb36d155,319393da,9a34b2b4,301c898b,43d957b0,a56cc2ab) +,S(79d8eb36,98d8d06e,6ca33f69,ca04d3c6,db636346,abfd603,ed0189f0,fc5fda77,bffc97e1,1b0234a9,8dd1d460,e19db522,931fd49e,26d7ab28,f1326517,23d955f1) +,S(a2366618,8e72e1b6,d5ab7713,decf6e3,1f801a6a,ac88ddc5,d464d127,ebadd34b,ef23da36,f3e71913,2774cd1c,d150ffb0,70e99ac8,5193faeb,b1736abe,77d60ed1) +,S(b6bad04d,dde6816d,9123e8e7,43fa46a5,b1fcbdb3,fa1f13be,480fc1bb,49dd9612,585fae09,a290b273,a68b7f34,645b80b1,850c6507,d959b546,7f1b0100,b6a4e511) +,S(2bf21c25,3353e715,283113db,8bb5018d,33fcbd58,f3d6face,b491e1d2,f4c3dfbd,e3a033a7,4e8a4d5b,c8c49121,43a47b07,b9fec4d8,a0d5b3ef,569c44c9,cf8d896e) +,S(64c27a41,e978e35d,63f3a90,e71091f4,41e9ad26,6a05edda,358dddd2,5d842744,fcbb625e,8fda695,988aac9e,cfe67c16,bed76802,3b527d27,521c1339,3dae32d1) +,S(620a1ef6,fdfe5b5e,9a4ef435,63cd7c8,af62acad,a02fb399,b7542d2b,6481a58d,b0b79e3c,550393a6,fa07f105,c547e203,a45fa7c5,ec825ae5,7bec305a,ddb8054f) +,S(1523f131,7cef7154,347ef68b,424ee0c6,15e71251,a06bf8a1,ecd74675,307b95cd,c72554cc,1d8ad664,dc1fe67a,3f11e5b4,a55806c5,53dc2612,bf5516ff,f0743b1d) +,S(d765303c,a9c8794,c00d4d8c,2cd73fcd,b43f763c,b753700,f66d7294,4eea0cfd,bafcaca5,204dd77a,a3a17b73,da3064dc,35b4cd22,ae01a623,781603d2,57bc267b) +,S(a75eb61a,fafce965,65198759,c25cbc41,ffbbf87b,61839a8e,a17f04ad,64c468b6,99802893,240f48aa,53c49b18,1a6d50e7,a8eba321,64d587b8,41497d9,65869873) +,S(7fa41b4c,d0bb91b6,c25813c7,1241e691,e7053f7d,beb0bcfa,4084e06b,bce59f2a,a0941779,755a695f,8317e7e2,f6a2c57,9431e22c,4aa09f,7e583b1c,e184aec7) +,S(816c0db7,2240f12a,d8deb440,8ae2276f,3bfa1bfb,d820bd6f,cc5ccff6,16e4dbf5,2a52c93d,d91ee658,9449dd4b,bf70255e,e57acbd0,a981ac9f,67c16604,3f7e52d0) +,S(33f635f1,317f1425,51390ac7,346905e0,ddbb3d87,b0c1780f,bb7dc950,c23414f8,7435a155,84eb1988,b974d570,bbc2b2c1,15123580,2bf93bd,b626a543,e54bfbcb) +,S(d2943ad7,4b0bb03,35307185,fbc438a7,bdfe11e,7b5e0eb3,e94bec46,a251999c,2dca8fcf,19aaa314,ebde41de,fff6e9fc,b6097d6b,3bfec06f,19aa4941,676d577e) +,S(26aa1fbf,c54375a6,fec54390,b5e44a0c,fb524b65,c10d1516,b0112525,9dfb1da6,49eceaa6,4c575ce,337d0b6,ee7e8198,83973c6f,abfa2f,d4b24e03,99a91b02) +,S(780aec1a,f866a030,5ca6d7da,1948f2f6,ab18717d,e82300cd,65eb58cf,a7d28d20,da650041,e45a0e1e,a9075b6d,107b6f7a,414b3a02,18aaf929,92cf2978,bc08b91a) +,S(1dcff259,8e59dd4a,3e515853,b3cc41e5,ef98113f,29ff7b3d,5eed6d50,2cb88b67,d7978630,7c6871e4,5654307a,e3836e07,aed86cbe,a9ab92f2,8c680172,1ab77271) +,S(b19af4a2,77321937,93e367eb,5ece1c63,8f336f3a,9cdb4b01,e2488ee4,373ff70d,a3ea8839,a5105a2d,4277f27a,26a8ee73,b9e73fcd,d54f641d,c214d5f7,9c821dec) +,S(1c8c1f29,548a9df6,f28b6126,b9324972,35f24e2d,a488e066,acf782f6,b4f6755e,1a79ab52,6a1e1aec,5ccc7e2a,3196a07e,78108b23,a86630c9,1795ef96,11ff432d) +,S(b6ff8dda,1ad6c3c2,3c8a10b7,b4313968,e4d70075,12c421d4,f0b1153e,bd5716ce,4d3869c6,b7b74167,ca0d21e4,edb3e01c,af8dbec2,aa87a32d,7c9306f9,a5ce61b8) +,S(dceff4ac,f61ba84a,81821932,9fa0ad60,ec08cf9d,830e6ccb,375488ce,d0f47b5c,949aece1,92bc61b4,883d5508,aa4a4aa8,fb1b8db0,385613b1,736a6eb5,c137d6f9) +,S(5561e7a7,b709689c,97c4aa18,9a3ce841,843ccf98,be851c8b,131eeb37,dca5ebef,4b108c17,f298be36,430e6b7f,26b414a2,33b924a6,e65dd5a7,9a1f15b,a99a14da) +,S(4d989577,89b01595,8e5d5bb,2e064e9d,9c56a254,5b3c8802,7ca0c997,a395a257,aaebaf33,ac950756,c5b200c9,f5b009c4,506964ce,5b706675,7951f221,40b6e0d0) +,S(82b58e6e,6373c4b,30ad55a9,d66cc804,e9da512f,bf4af668,1246a12f,e33bfc8e,8378122d,98dc1e37,2c33b5c2,1ff4c429,d6d7577d,2ff353d3,87cc0478,1a5ffb38) +,S(f49fa88a,a773784b,fe57d880,9efac44f,714c3d75,3669463a,d1199be8,2c6cdf3,41aff6c0,2164a411,c8be7281,493483be,aa9855b0,49820772,b96aa39f,9a18b3f4) +,S(67d485db,ac8445a1,8c1b97a7,8c1852a5,ce910f0,d78b073,969c58ce,c0efd78c,71dda92a,24ff2b31,5fcaa5a8,28bf07d9,596f49b9,cf19f4be,44e6f320,84981e97) +,S(9145f6f2,c19038c3,cff99883,b5a71760,30a46f7e,8b5d350a,db2a9610,4704d4cd,9d9179e7,852ac5fe,1d4664d5,4d778b3b,6c8e422b,b6e78add,56700dbe,6a22b0bc) +,S(492d5247,efc2f5f1,1cf3848c,e0719abd,53674089,808de4b3,5503e23f,46b2631b,374b0762,7812c898,7ed68877,c995a4d4,9f021d0b,29270863,d50b8c40,808fd750) +,S(5b8ddfb8,bb811678,9298d231,72bdb9c5,25c6610b,46187549,a381ca6,17dd1dec,b47d3764,fce3218d,17d0dee0,133d4f3b,c7ae170c,3e8831ce,a92a3531,7b1f7568) +,S(88db73ba,25a61641,af5e603c,cd54c6d4,63c6feb,da11ec5c,6a35d30f,e406c65,39b06f7b,1c1dd7b7,884c67a,e295f8c0,9b8b5be1,c14456b,4027bf1b,4800a753) +,S(3495cc9a,a23c1eb4,2cd85070,bb095563,2a7037bd,e330f721,fb38091a,9c382451,7feabb21,6f3982df,74429957,3c7557bf,b82ff4f,462fc64d,d9b3e10f,b69799ef) +,S(e8a5cea6,970e10c7,93f75666,9d2309b1,a4f7b52,c19db4f1,cd69a652,c445d7a2,daacdabf,bd5259bb,96d2dbf3,668e8c16,fab47624,294d9982,b961f0ea,32402b96) +,S(6e8c78a,e81a7ade,3989c483,7d9efe50,51af33f2,b2b2ee32,b5700b43,67931f9a,e5664504,751b41a1,45b5412c,be10a782,7d1d5193,30dd69ca,47be2975,2c291d35) +,S(b8f520a3,10c5b2f,8291722b,1e3a92ec,b9551db7,744dd208,ab4d1709,310a539e,65901c3a,b6712ded,8f66451e,1915113f,a96d3d1e,d9074790,9e291d00,970f3d75) +,S(a0538458,64459815,888bd917,3a2c16fc,ae0deaa7,cb804adf,e49dec0b,b2d8005a,27882f00,23dcc9fb,890dab73,f98925d3,e712608b,3d6069c8,ca58ca6d,de0d7a67) +,S(41280416,aa7f0924,1ed8b631,fc2959be,2117cf03,9c12f600,1faf8a05,15222144,c2fef80d,fd8e8433,ee55c363,c43f7e06,613f354e,32aef8e1,808817b1,af7f58e4) +,S(c4b8ff36,cbf83d10,51d130b7,e3d613b2,8b536f0e,b050a41a,7dd8f8aa,18c7a1ee,87d3c44c,8867337b,466ba76b,47512399,f6cf6c14,ad4977fc,276d67ec,5e7b4d47) +,S(40eb693a,7cb938e3,a6b85010,6b7cd257,1de630b9,86da02a9,3b7a7f5a,a0a51ac1,27b875e0,14d3417d,cbc3b770,c4cb8805,c7ede7a4,efa9f89f,a51e36c3,af6d8d18) +,S(f7491902,54e30180,75365d67,5f2ddf24,ac0c9d84,df371fb8,6e94a9bd,7f81dad4,6a271b36,c549080f,dc9bf1b5,ad275d62,68af0cc7,2ec68c7c,17ac24cd,5c5a6e46) +,S(cf13261d,e4ce19da,14e6996c,97a23f8e,f16388ac,c364f2e3,6a053254,849f287e,5568858d,be1a7447,f7e4ab51,bb872a78,8218c483,c771ab7c,4a0a968,73adac10) +,S(9c6bda62,9dd087df,d5516606,62226847,94cfd517,72c72a81,7263c761,ad3e8cb3,2c77dc7b,9c7fca7e,bb35628e,d62ffc79,9e5fbcc5,e25bb0be,5b1b67a,10c0eb3) +,S(d8d1035f,64439dec,20ecc9a5,5b314959,c1526d7b,d15b1922,bb7ab7e5,b9d26bf3,ab7e34d6,ccfdfea3,f607f697,b941bbf7,b922a436,b9cb4314,3eb1b948,ccdbbe30) +,S(c6f40a23,b8227a60,de32e104,7080f087,7d53aea5,b00a22a9,39cbc228,d1c1d424,e16bc58f,cf4b8c5c,9106f1f4,b8b2374a,63a3136b,e5a8c64d,7fe6bd0b,c1d80345) +,S(3a69da22,9477d3a5,7147c2de,cce22de1,d1e007cd,61d22509,49400b8f,63a43536,c79c4fd5,c4ba6062,c7cc95e1,c9b79cfa,46b98cd7,389cbc39,25cc2fbe,49a0e284) +,S(1b5fb8e5,492fc48a,46b7f6fc,a658f218,814c3d82,90aa339b,7bc7b794,325fc9d,a6290b12,4c9e0819,2b6f49f4,c4935b01,d2ca4235,8efea982,1646fbe7,dc7fff39) +,S(fdba0f02,b004b4ea,dc9e1c37,d1a7fa7e,8a755922,31f054c7,47bbe8ec,349a3845,42da61c9,e96471c2,6fedefd7,e30c43c9,6c3c09d,d72d662a,e2b82022,391646fe) +,S(c39391bf,cb7b9662,be7279f7,6338988,7c166343,2faf1760,f38f0cb3,a35140df,ea14e034,53dc82cc,484b8b3f,ff79d81b,449f9f81,d7a52d66,4c5b563c,9af556e1) +,S(254ff13d,c716cb2a,1ac0e36c,c6cb20c4,19aedd0a,2219321,675e1744,859cbcb,2644cf3,916d26af,9e36bfe3,247f5be8,896e02cf,83eb3701,c400ad2b,92e35921) +,S(24e4aa60,e9b464ad,a2c8974e,98568026,1769d35d,aa7c8c5b,71c9f57,28930474,9df7c2d1,82a94fe0,80a2244b,ccc9406f,6ed37c38,d9cbaaf7,8d973538,e8479f8e) +,S(7ad9bbad,f906685c,3efd81b3,8599fc02,fb19a4c1,8bff1ef8,702c4f6,d17543a6,9878b970,9c4018a4,f713ac8f,d8a533dc,da45e243,44926df0,133aad64,c5246f95) +,S(97d8fcd9,383a8717,e0c9eb2d,f7dfbaa8,c6e08339,be5fa2b5,1d12565,62d8ae53,1879ca4c,f5784f86,7f8363e1,5d85afa7,b1f114ca,7f8f474c,4a2c028f,7c6a777) +,S(3e0fc785,5a08c32e,1e14d1a9,2c56ffac,2af1acef,505ed72c,b8771ddd,8afe7572,6d79b7fc,fd1e8894,f0844fc9,da30b555,bb1768f3,df15a0b5,884e5b09,6e149390) +,S(d9da17db,b132d864,1da3a9b5,389d6f5e,fda483e7,fc7577ec,55b7ecfb,65602562,80e471e4,5feb0d70,2ee7f9e6,3f8f23b0,33a4f35e,8a0841a7,b67f8c63,c623b70b) +,S(1848f766,afcd1e34,82935daa,7b71212b,f38e2853,9d6fb9ec,a3d9809b,6fca18f3,ca9a7882,645d54f2,49d35df6,3748ed94,5f9196f4,a93d4b7d,ee70f44d,b6f5884) +,S(ed3744ae,9a7dac76,5ad65b2d,4fc2d15f,1a9d0047,f72c6be0,a849ca04,497a9f2f,3cf76d2e,d4e5c6f7,e4b23d03,23c477ef,2fdc5248,7066ef36,b763444f,6ab5fb5b) +,S(c4607b73,edf3545a,b10a3a65,e0312707,91212acc,a86226b7,b1ccfefe,5f3676d7,31ad465b,8595f783,d5c0cd03,6230e3dd,2628ac9c,45dc6d77,28c42093,3d7eb3ec) +,S(1c0962ed,2aaf69d7,8b20af04,93a3fa50,bfb9ad1b,64eb0699,641e4b0a,bc0e96f0,49f11af6,e088e3a2,a429c5b0,a87a7f6a,591b5a60,a397c123,2d56a4a,adaede44) +,S(6a0476c,9a41959e,98dc6ca,fb7b4381,82250e1a,ae62445b,1f09a098,ddc19454,56842c97,8ae3c4c9,2c266cd3,7c8e3514,ab4288b9,ccc7e33f,be552ec6,f511c7e1) +,S(24da0f6,53a30aa0,a6b14999,329f03c6,cdb59a80,e9ca68f6,b9367830,a0191f1c,83e79080,aa78bcf5,b810683a,f061c614,cdbd3b69,9e200b53,d1a2c757,2c138235) +,S(6c3483,22479d07,f5871901,3264402,a078728f,227c75f,6f33743f,9a1a7764,a377af74,4a125408,6bf128d8,45bda458,be779210,f0d85bff,eb192c0b,a0dcc4c6) +,S(212aabbb,4d14cb26,b26cf249,882b36e1,1cdc26f4,a1494905,15478f99,d5c43baf,e9140a0a,81d1582b,98eed57d,7ba8e584,11c22ea3,fc265148,ca1d6050,3847e281) +,S(a27478f1,2afca20a,8d46824e,5b0ba272,f26ee0c4,24a951ed,f371425a,b343b10e,51e74b86,a7fc97aa,5a3bdecb,67818d7a,70ad0ba3,7c7cd759,8ec80a4b,bc4036a3) +,S(e1c1269a,7171f9eb,a2e2fa7e,8f55e0e2,b9b8a507,e8cdbfe5,716f711a,572e293,41cfa170,8953242,f98d8e24,2e827684,5562c4a7,6d034848,e639335c,32afba46) +,S(204d544c,19418e19,bb328e1,ecc0fbd8,62f0f78b,24208780,4d5827c0,f5e09efb,c66098e3,1f5d1587,10a3799c,b4f980c0,18cf4ed4,534e49f0,6d057059,93d52fb7) +,S(16eddf0a,11a6f2f2,df230de2,f78b4cf0,980138b2,3ab196ee,361486c5,7a5172ad,e3db358f,ed8ab3c1,9204a792,6102c420,1327bdb4,fb81718b,b39a0ce2,b5992684) +,S(7c9f7831,2298d96b,65e6b7c1,2315379,3df7001a,79cb080e,af6829d3,2b8995f1,2037cc3c,90e3a0f1,b242018f,c53cb32e,b2481dd1,bbb700e4,a6019546,edf51e5c) +,S(129c2d46,1dbeb8f6,c1b913a5,b2d69602,63aee7e9,530c6dee,21168b16,6198fb1c,29ffeeb9,61c027f9,a2a14b72,a287d566,7bbd80bf,7cea0dc1,747ac25f,55137964) +,S(8be2e565,30d4932e,f6d1f9da,a3225b52,de204927,e0633b12,570a049c,1f6175aa,364b4e87,1a130cd1,40007056,e3c0951f,fabfe4bd,6a687404,23cc1800,505510c8) +,S(40b43f08,42ae9c67,ab0ceb62,453b4c41,42a6e12e,5f880c5e,27c90997,6252fa6c,6d1ac6c5,de1b2e5b,b225e46f,2c5a2d2c,248f11fe,d123ecca,4432a04b,cea2068f) +,S(47e2238a,2f34df3,cf1caa55,93c49db5,4c2cba9b,e3724f17,87473a0,5ac669df,4d04cfa2,3ee255f,eca104a3,60a52f7c,acfc6127,608dd908,9399be82,9cf31f3a) +,S(17286c55,3a45c6da,b4843323,84c565d7,b3de474b,5df8ed60,7c7a5c9e,e1cfc35a,6172d347,75a45151,60b104b2,79543107,5b194d24,793340cf,6d8723c9,6320007f) +,S(3451af9d,3c1492ca,d090bd34,45632ac5,a3e96c9,4d9ed258,b7fb2042,8dd7bb31,dd493383,21236e06,e7284fd7,84c1a3b0,7687c513,927cc79a,cc5f8b41,b14974d6) +,S(b00aa481,eccc5e7f,cb5bee2d,a6e0ac44,ed9afa3a,5b2a9619,d23d0252,14e5ce2,687b486,1f0032ce,f42ceb7,441f81fa,10d732a9,e7e76242,4a2ca8fb,e88866a1) +,S(53ec8e9c,c75bc91f,f248a239,34d735b2,ef706d4,c0761e2f,a8a55c7e,a0b23311,1b11dfc0,63c4b1ed,1b5104e0,15d5c5a8,c352f54b,9fd82768,8b5104f6,45d45919) +,S(1ecde1b3,9c072c9a,3b3eddd8,d71e3383,2fc80d78,7abb70a4,cdc9186c,a5efab66,4f5aec7,5a799762,b70cecb1,82049cd0,239f0c30,948a25f3,daae0bc,ae6dd626) +,S(1fe2fc3,702b558c,7ab9b479,fa08efa5,1e90239d,677052e6,5afc8754,9bb1394e,f6b586ae,3a395d3a,c216df2b,66d48fe6,11a64c0c,8a7db26d,30fbd720,c6845c2c) +,S(b53d0b2f,b8ac2ad5,582ba0c2,f031c7b,76e64cc5,28a5b9ba,872718b1,e06d5dec,8984e589,51ab87aa,64bb034c,17d23252,4101577,9476887b,351f034e,92e3a289) +,S(54e516,3bc2366,673fe5d8,1f335d81,a06ca310,a2116ea7,bc0ade12,8f37cf95,f471c826,9deb2c2b,f1b7206d,6e817355,9236607a,4b9930b4,c5b3a781,7312bd4a) +,S(e7efb772,a1d423a2,d39e2224,4c8bab91,3b8087ac,65d51f59,8c4db283,67b29a7b,f2dfb586,31d08b0,bf2b47f4,17f6a18f,704a39a0,a152e3bd,587e45c7,93a9b6e7) +,S(5ec59daa,e8a263a8,2afb4309,79ef0321,b163f2a,dc083e67,3446b98,d0b519fe,2eab4cc3,6a3deae5,30dc6aab,94e5584f,a8a5316f,5c05b04e,84215ea8,79ef82b9) +,S(427b5cd9,20589dfb,dae975c8,efc1f098,1119f69,c40d1216,58ccb903,d4bb62f5,d055e6e3,b8794842,4162803c,35fca878,6500b5a3,6871b18,d9846866,56d1213d) +,S(54954b15,fc594f3d,8f422c7,9dd42cb8,2cc30dd8,c0d10736,554844ef,9d05bcad,86a7cc65,73569c20,2aff8e04,21a00e4a,9c6b88f5,ebcc3975,64b4734c,f735373a) +,S(ff6f8f8d,23670fbf,2a1aa7b3,39568653,573eb480,67a2a1f0,1b55a1e6,b1f32559,7a53f1a6,c7cabc57,d731552f,9fd9447,36cd33f4,3f8f57cd,2d4ac1dc,1ac7e218) +,S(74d725e9,9021c210,e82d852f,41e0cb8a,3bba8efb,8a01552b,8420c265,958a2381,4ee69646,aa9f70bb,883d6ca4,e1016dd9,92f18de6,26ca27c,aeb5854,f5bb2bb0) +,S(e9439f7e,fc0342c9,c2d68fbb,c58d85d9,feca0570,d77448d7,6d3c3251,e49c845b,27da0d98,1b7e257a,eee90b45,9d0d7065,566667e7,a9287592,2031be02,3e233916) +,S(9684a48d,81a60856,6dd26622,b3ffd133,5facb32,9f2c4f1e,2c055cb0,a5c0b911,92038ad2,50adfbaa,5d587c31,f5e7b4e7,294bbd25,e7af1816,1be3532b,f24e68b2) +,S(1d003af9,469e26e,c7f0f121,4dc58728,9e4cf837,5f9d19b4,16277c97,1a0e7609,99c7c3a5,30822c72,b31dad8,146d2604,ed795f1a,7c37e139,c84afe9e,f71e5123) +,S(f96468f8,73cfaab7,76c32fa5,89f72c09,d680abf,c601642d,1c649ca,e197a149,1ffb4bc4,8495d31,b24a7ff3,353857e3,b6708186,c18936e9,9793e4d4,fa083b1d) +,S(b6ad4106,e30294d2,bcac86a2,131150bf,d93c14f6,51ec65f5,32904412,b3f89d32,19a366a6,74279641,d055201c,c4c42b43,4fa40792,90c1c3ee,5db2a4e6,38d228ce) +,S(875472f7,190bf305,9120fec3,ebb69fb2,2d47828,6cb1c108,a977e7cf,e45b9b9a,1adeffc5,f5dc59ad,e15d163a,95f8049f,a172d8e,30544562,50a7898,55a97c21) +,S(5445a9fa,f4245414,e64f7ae2,a1cb1b1f,54bb6fd5,af4a7407,4d9eeb05,9a27a670,496c5207,7da2e082,3e48978c,a3fb7a1d,3bdf07ea,61fde94c,e87741c4,e9418018) +,S(dae18625,704bac88,51f35026,7856830f,74d3a8f9,7c1f662b,f4c4cc3d,7814d138,abc059fd,7ba90619,83988ee6,35ec835f,c20f62fb,c68e2bff,373bda91,3be6f87) +,S(8a088f12,e8523de5,c7ce659c,107e1929,3d009b81,1fe94d02,deeca893,9d9845c9,4251212a,fb8ebb76,5d2d703c,bc18b208,41f8df47,fc5e44ba,ef7b0f76,7e29114a) +,S(d78f46a8,8f3b08d1,334ed25c,78f57910,716755cf,2bceaf6e,c25b52e4,d7af6d01,eb1855f2,29cb2010,f20b3f01,9cbf1b2d,929046d3,242446ee,5c9526ef,5b06f44d) +,S(1e0b4312,78ae0e27,5e55c4ca,cfefcdd6,f589809c,6faaefa8,3ec0d5c5,f99b034b,f38c53c5,544d3ab4,2ebd74ed,b8348503,fb523fae,9d73657,8bba2881,904918a7) +,S(f03155b2,9edb119c,f411f14,4a588f34,ab02d7f7,c415638,cd534465,ed7cbbd1,72d153e3,ff4fff14,b41d07cd,31960565,31736749,7f9c6495,599d3f06,b8e85813) +,S(f61fd68,3edc7fb4,d14c84fe,3416654b,8df66578,6d0bab41,53a96e39,e5de4c8e,952db567,cf0913b1,885d6884,d260fe4e,e11fc139,f58da12f,d38472e3,d42e5f92) +,S(78310e7a,29e437b2,5cb00e3b,13a4d86e,1ede6d8,4b1f344d,7ee9c7f7,e017dd77,26ff358a,4d5629e0,4c20f700,97c202d4,7030bd3f,43134a51,a7d101b6,e182f2d2) +,S(63ae8c4d,6b7329cb,a61509c2,d0b61ebf,4e6ac94b,c8a096b9,7a4027e1,1f781a3a,a8e954cf,bf407857,d19629cb,338a93a1,af16c929,ef8b96ce,2e483e95,dcd14f88) +,S(948d592a,594b354e,e2d03961,6338574c,ae662f26,ff79afa9,16579725,7cca739,37ff98e2,5ea0396e,89d3992f,773bd6d5,ce02758a,4ee25557,edc867b,2f1876c) +,S(653cf16f,a3140368,50b04de1,8bfee880,660a4161,4dc67a55,398e2d34,46100f45,acaaaede,5ff1e552,6766741a,ee43105b,ea4d3419,3e615c36,49c1db35,125a9202) +,S(46fb6882,8a5edc8b,f24fd1ee,e6a7789,141e1888,64508d2a,f3c511ff,8e8cc782,9d4ae53f,d52ce9bd,6ac9ff4a,e82c2e36,f4d26698,47ec90cf,ef383e01,37fd8887) +,S(5f11a0c7,23ea2a71,7c1face2,b4b0f28a,4ca44208,7a2ae0ea,e24c2005,7138c0ed,5ecaec84,ad97612f,ba7925dd,f126e4e6,3906eacf,6f991d5,bb273316,b80c8452) +,S(b9f49e1c,929bef7a,6d6b6b3b,deb10890,dbf2ba3b,3eba62c0,320bdc84,c2a9039f,98729e76,7e4f8b7b,bd0ecc1c,534aa030,6e1b684c,6f42d15c,2bf6820c,b501e558) +,S(ec8a102,e7d2905f,f273eea7,6c9a4608,965dc2b0,3631d2dc,63c38e72,15ade2c3,d8c899e7,242d96cb,49383686,8f671612,706ffe5c,368ccb6d,be5a3edc,f74371c0) +,S(107f02b3,c351805a,6c92a3c7,742a5259,582c5b0,39cf6daf,cdace604,2be236c6,517236bf,1ab47601,57d74685,8dc724a7,c5c2d55e,82c4a3e,685f389c,a99bfb9f) +,S(f0fb14a1,a5c1c016,d7b8c1fe,a8317872,b10d637a,daf6f6cf,b9860653,56298971,e1d9ed14,d33e65d,4258e87c,7280001c,c40b89ff,b3164337,92fbc547,964540d1) +,S(a5371adb,ea784ede,f6cce83c,ebde068,78a1c80a,ff83b47a,333f9b35,44489459,f5780572,127f5d74,773acbe7,b2a22cbc,7e3d09bc,ccd13edd,48ece3f2,c8129224) +,S(3c031e5e,1b0ba576,13c10971,5fa7d92e,2bbbb817,9603d3b9,99e4fadf,be17300d,d275a3fb,392036dd,474e65a2,cd7b6cc4,79cb40d7,1c363e6b,bf9c272e,ae9c83f3) +,S(87b5899e,685db530,a0969a68,9392080d,f8a1b9ae,523ce18b,2171c69c,5a5318f,6ae3204,e3f0afa5,a2d40b01,a42e84d1,1b1166fa,f99cec08,1f5af48f,fda775d4) +,S(d9f077dd,c002c16d,f9d8eedb,56b7e7b1,ea00d04e,3fe838dd,2ae40501,9b8bf74,6518d51e,503118e2,53cfc486,f70cb9ee,11c27302,ee5512f2,78f21265,af3ffeaf) +,S(9c09ab63,8d15acc9,609ce305,32277f63,7558a492,aefb98e,c9bc721c,f8921af7,b2cac58d,535abc10,8bed6ab3,165225f1,bf2f84a,9fbdf3d9,1caa4b79,e0f6fc) +,S(6ed1ef8b,4c2d9232,5cf8948a,5c369a24,52ab250d,ed0e48ae,1676dc73,9a8a7fc0,c1b7a08c,2cfe5154,fca74136,863da75a,5c6423bc,1c904585,f54ac87e,f6742008) +,S(882e8d70,154b7f6c,279f71c1,e2ba6087,cfc458a9,3079d8f1,3fbd3be2,506928d1,8949b22e,97c41872,9094ac62,e67ac1f2,8b31565,edbb3d1d,9b23a73a,6fe64131) +,S(708472a0,24c86ea0,7119d0af,b2509814,516840e9,fc23246a,a6da139f,b37aba52,9809b7a5,1d551532,a5b378d6,594a3665,3a8b057b,80cd530d,b7a53fbb,128fe5ac) +,S(3a44fad5,9a8b708,4ada1250,d8d08353,769d573d,71a225eb,d87a8cc3,af9fac3e,f29f4551,1250d0d0,a1974bf8,46124813,f9186e45,2d3c5c85,cb0c69fb,4b7f20cd) +,S(a3519dd8,e09e1bd4,160564c0,41c23362,36ba4c84,5899f90a,fcc370b3,cdfb9f30,64cff159,7c910711,d0199faa,6c74d08e,7150088e,34fce674,72dd3ec6,1b881d7e) +,S(5af16ce3,765f5c96,4eb3513f,19d99ff2,bea1affa,d68f829,1c4f0767,5cfcf1dc,864eb5,3bd711ed,4a842db6,b0164a78,511ff7b8,a87aa3dc,1f2402eb,a3815daa) +,S(1ff9a522,19cae5c2,5de1ec08,2641040,18848bd1,37a5949b,4021c2d0,563d54a8,546d634c,122276e1,b5cfb919,a5374309,8f85d7dc,149b14d4,791c83b0,1718e031) +,S(d7a6dcad,72a51ed8,f84926eb,cfab368c,7f02fcdc,aa66482a,c6b6dd6f,43d3e938,9a273cd6,3ea6ac86,5a68f378,e4466ae9,8598a058,6c97278,bde63b22,14e41c96) +,S(154f63e5,5bdccc7d,a696dfb5,2b6cd4c6,3c874b93,1f221282,3f4a8d19,1f32d797,e98f9722,17bca1c8,ea7269b0,d2aa6bc6,f0f29d7d,b340c67a,2df59135,77f76fae) +,S(f6ade08b,8513615c,ccd29095,c21bbdea,dbdbb7da,87ce9991,c27ec758,4c399bf1,98c81be0,19fccaba,131af074,b28a6311,3fc1c5ca,1318e96a,f037ad33,8f234ad1) +,S(9661cec0,3b2715f6,c6d29048,65fec2bc,b786b3f6,943a883a,3e51cb2c,c747637e,eaa1f7d9,9b34104b,74a8056a,9ec739f,cb9c3735,95f0b254,7fe75620,4f5358bf) +,S(e0a5323a,27d608c7,34c03465,f03705c3,480520cc,f5ac777f,53d498b4,655d19a1,1f727d78,a8b8c562,ebc60679,8462975f,63d88eb5,8e7cbaee,836bd629,260cc606) +,S(bab82efd,4646f2,f281980d,5250c6af,8206e95,dece4118,c24ce31d,282f6409,2a60b1dc,26a20126,8df8375a,5656c55f,cafbdbbb,46b7977d,137cd584,8d1fb82a) +,S(389e1399,ebbe958b,1806e9b3,ee51baef,2d7edd20,79e6a2c2,21e814ad,e1eb2631,6c158633,1f3cfe45,9e71fb4d,112a624c,e48adabd,435e6fd5,2c9459f6,ce9ae2be) +,S(b78179ca,c0dc553d,19f08174,7fa4511d,87d8961,1ba44045,8c307727,729d4515,7020be98,c496a50,6e4caa5a,94577d71,ce0a80c9,bb974c97,a6892351,e83e0de2) +,S(867ecd3d,d170f9a7,123d13fc,fd90058e,baa6a6f4,12ecadc9,f1e14d55,ff104306,3c0db3e1,bb91ee23,8fb27689,79f2b543,d698c5e2,fde48dc9,e2535e4a,946759bb) +,S(be71654c,26a1025d,41fd4d08,384b2ccb,db25bb2b,c15704e5,697be2f6,d4eecd38,316ed20f,c37a2dc7,a0af8d18,e4da0efd,2dcdaee4,44b2c1df,cdfaf6af,49406afa) +,S(5a8e1cb0,24d62685,e755b9a2,ad1e0165,41690544,7963dfda,6b6deba9,76e9079c,4c793173,743330de,7a8f4351,68dde95e,3889db2a,91de0a27,d088a222,f11ebba7) +,S(3bfad00b,2347bd0c,f13a761a,d0630453,bb884d0f,ae3d31f8,57216412,b82e6131,ef33c560,94157fec,3f7fe8e6,36d48183,71e3cbab,6f5b0518,96ebdb42,aa545f61) +,S(2447ede,684dce09,c896c2d2,b5c68cb7,60e02635,3b4f2dc7,428191ef,5d2c1961,ad38a82f,e80f860b,62b39e55,44438242,5ad6cb54,d6e7f377,62427f30,1ef7bfcb) +,S(a5eae321,eeb4b9f8,e8807e49,ba8de764,e7685f07,417c5239,9d857d4,8bcf985d,2acf8aa9,f5c1b7d3,2ad5f523,39e65595,17881d,48a7696e,ed3b1023,ab4def1d) +,S(97de995c,5337d938,3cca5b97,3ab05e8f,dc035e11,5c435251,7e575a,e890b13c,4fb2d969,2e308a29,34c3fb4d,c4dcef50,9202505b,cd891f79,e8f91210,e069e6dd) +,S(b8caf25f,a864918a,f803dad8,d0abdf95,25b70f44,546b1f3c,c6b1726c,4438f479,7c51b5fa,c0f56eb3,6ffa8c5a,76c074a,c30e2f36,b069ed79,23663da,c9c05c9) +,S(b5bc868c,1b96e2a1,b24f3001,af140107,b2cade8a,5b1f3443,44521764,ad07b2e6,8d6cfe29,4e929f33,d5aaa456,f545c33b,672a8c07,b214a6f2,38bba367,4938d639) +,S(5f51587c,242a3b22,10db666b,f2414c28,32ea2662,1f13f6e9,784a8a1,373ff602,2c3b260f,ebf20a4e,b853950f,99ccbb9f,1b39418a,66adb427,f5886944,8b46c858) +,S(1d0be0f9,5009a2b5,12a52e17,e044f3f7,4f08e695,60d0dfeb,822b4674,7a2bcfde,c3a82bc3,dbd81877,3783181c,f7b81ddb,a742c3b2,4f866538,9335ce4d,8f3a159b) +,S(3ef0ec28,b8003331,a6621bcd,6ce30ed2,9e0e62d5,b492592c,cecaf4bc,8d22fb8a,fe2c84ad,77d40e86,c92a03da,e43cc7f7,512fd363,98db0133,7d929ba7,a144b16d) +,S(84c29a24,a4ec04da,c76bef42,732a3648,f62f12b0,e7f0ead3,2ef9649,b7555fc5,e7620ebb,283a54a7,10eb454c,f22e49fb,929ec453,38e457ec,b18a7f0a,794f970e) +,S(6bba6634,e75d5fe9,21f40f4e,5f1c177b,a309cd73,107f1e9,28331573,eacf43a8,33ffe08c,42168243,1f086b44,12209c56,5b47fdea,54671a97,9d86be36,fb421582) +,S(13b67af0,51b0c01b,c49a6046,d9e5b6ea,488f6298,9559dbfa,47cf1674,6def0150,d0e8914b,1c1bf0b,5337cc35,d84acacb,a54add59,2321509e,e29f1d93,a0237608) +,S(161221bf,b5dcb62a,ebeabc94,6ccc4a26,fdf779cb,63640720,2c5cf13e,93af9300,d3fde2c5,dd9d6df8,70a66bd3,2b5213c,d1a212db,61aec7b7,2a49b7e9,2cf83b2c) +,S(30c5360c,c62f5846,3af60277,2b52201,7eda1fbf,866dc3d3,9a590bf8,e2eb508b,c8e91af5,9b9a2b,8837dbe8,edeac615,6c30e8c0,1b7679f0,1aab4a81,cac44efe) +,S(c0659a7f,dd9151f5,ea67f38b,7249727e,640364f0,87371007,a38b800b,ec3576,a6f648cb,6fa131c3,5458b5a7,77440361,8c57faae,1ca33ded,648f1601,a5cf47e3) +,S(3215224d,b795a892,446472a,8e1ab1cb,7d50fe95,a6844be,43e2787f,2679386,25750662,97f28d86,690c7eb5,92cffc5f,faba831b,efc3e38c,c5e501f9,358a9bf0) +,S(257654e2,a87a7048,3bd15445,da5c554f,fe776264,998975b3,b19a68a1,a1871145,fcb9319d,c67f14f,9d7fc4ee,fca05b18,9efe2430,96691043,9c28c88d,32636ec5) +,S(a4786a01,e504f154,f3d7926e,6e6908a8,17c8a66d,6db33e80,ce98b17,82f1b49,576e4d42,fc2e4f9f,e81a2967,8b7cfa7a,7f86e8e2,662afbfd,b028612,d323a2fc) +,S(5140f7a9,260c9856,4493ae62,a8af369c,90b484f7,e82e1e38,3c5a59a6,62db1e71,4e5172c2,b0879dfb,63a6aa92,cebf9153,94ddcdc0,985261fe,2f64714d,350bae86) +,S(f559d60c,f0f50b7,9c7d6d90,18a579d7,b781fe13,5210d342,31e6cf32,4ca66dfc,12d9ceae,8e5852a5,ca95fb56,abda8e42,5f1f05dc,ca29e08e,2052bab0,8d4eed15) +,S(88907ff5,fa2d01b,c970e0be,53a05354,a4fb73df,9a337857,cc869a1,b0547e7c,f5853b56,cc1211b6,427145f2,6fca6aaa,5b26401b,c00db73d,ab9157b9,7fa3d2f5) +,S(cc1e4bf6,4541506d,8e91fba3,1e1d8ffb,c8ac82f2,4def27ec,fe4b3ea6,e58c45ca,7617497d,a875183c,684585a6,306956d,1efcf1db,2753fb77,5902a63f,38d27592) +,S(7ee2c437,ef744210,5b6a6f9e,f1edde01,6c39557c,93454dd4,eca10daa,cbca99d5,21754734,5eeff5d9,f30503f6,9515da57,3e6d7b70,dbdee5b1,8274968f,6f3772d6) +,S(72feea2,39f9b4a9,a3f3af3e,f6bf420c,3605ba4b,b42da90f,6539e05e,33e2465c,a036ff,df7adedd,c8c2ad9a,d029428c,85482cd1,6b0cd20a,36d2aed9,e9f553cc) +,S(363da33e,94a0dd00,669b627c,4d7a3a6f,c8a0cbae,2641707c,938c8f5e,99914a,9bda9a77,ef1307a4,e236099,c1506f47,a2f936dc,d478b59c,3d0e98c0,7af58bd9) +,S(76540864,c8394290,9af4a48b,bbe05fdf,93af0f8d,1ec9b6e1,a7e91860,f2c133fe,f06923d7,738ceb02,2213a236,daf3d6f1,b3cc98f5,a5ed4845,83ce5c3e,54a3ecc2) +,S(573f0821,7a318a9f,8bd945c1,62e9a4a2,51e38189,34709606,c94cb401,f2b239c4,7e78e4f2,7de69e4b,948b105f,ec3ebd14,496cc128,d7c73fbe,7ca1d53a,b746bef5) +,S(8537981,89234b93,b5009656,f57e5ed6,f90d2184,819a5467,213a934e,22b01f5f,c94a79e8,cc990998,e1c69bbe,89ccefa2,9281fc0e,c99fa820,ed26f01f,62e475f8) +,S(53388512,29890336,3b1ccd4c,1cf0ed85,6f00a30c,78004512,57f6132c,edeb6041,d56e2a52,f856d1b9,a4f8feac,dbc9a844,dd22f55,469bf722,fd78b44b,6983334e) +,S(41ede48a,750ef7b6,5c49f913,afb98961,c5cb478c,39c4c85,2f33aaae,b0e4796d,d74c7bf9,4b6c4680,18892ea7,f04b53c9,4bdfe9c,d1a4c65b,8de2409c,32559de4) +,S(97e931f3,6596f736,992eece4,eed6a9df,fe762139,3acffeef,b6dd3b53,e5f08148,3da89933,53b9c52a,9e76ce7,7404fba4,39a24614,b62d42c0,9b660e2a,14dd5f1b) +,S(4caf4eea,3ca8b104,39847633,5252b37b,5c55b664,cc4979a5,4db00937,b222579d,c266732,a93bdc0,7cf88580,771d58a3,45a19100,4c0d1464,62171cd6,291607bb) +,S(857c1e90,5b3483c3,3ab24ee4,e51e3839,b52960f8,21a8706b,b7ea7c84,9e7b1ca4,8d6e9d0c,7a578771,b358380c,4a2e6bc5,1c6b09fd,e9b40c01,be5915ba,fe69dd80) +,S(410ef70b,e0dbf7ad,a68fc124,8dcba3cb,10ec39a4,9686b22c,1e7ed2c1,bcb5a182,d26e9ea3,331a56f5,cef074ae,e0b4a5c0,e6925d79,808ffdb3,b7cb9423,247f9e94) +,S(8caf87a8,c831eb10,817e5ec3,7aa431a,89dff6f9,a7e63f7a,30710419,5751029f,3f0bd6e1,c8dda6c3,c8e65ba0,7c3a4649,13aad207,3c5da058,bfe90872,67c8890a) +,S(eedee2cf,e92d2483,54a6a8a3,9d314fb1,b35ca18b,ffb9b779,8c16d5fa,fef10e8e,cb515ab0,21f0befe,4b31181f,3f9ce1dc,9fcd12c9,6793d624,c1eb35aa,e514c4c3) +,S(8cbf7ac7,1e77b7f7,7bad6a4e,9116db52,48bb2a75,744d4312,f02eecaf,2aebcee1,765c4b31,f67b26b5,3d17f97c,30d09636,b6f6697f,db6b799,169a2c05,779b7320) +,S(70cd45b4,cd449aaf,34ff0627,f0e01122,715dc6cb,98642dfc,c19fc672,54995db2,82e59456,761497b1,84320eac,3ada16c6,ee184ad9,10b60c41,20f0c538,2f535c8e) +,S(cfe217f9,783fcfd9,1e79d558,e37bec3f,50e5146,e0f442ea,702fdfb,6c7c45d5,537cbd0e,86453fbf,c57d70d8,78c7c3ac,da225186,17bb4dfc,7b6f7079,95c419d5) +,S(9826c0df,6486bb8e,2bf3d4f7,4cfafa71,ccabd2cb,12bf317e,651790f,48579d52,3dbf3586,f86d6253,d3749c05,2fc36d16,ae3bb457,8d4eeda7,34f172dd,b9c57342) +,S(ea18fcef,381b4bc2,c6b3fa3e,3744e9c4,a13e13df,576c8e74,d0f4f596,e28a02c4,c3e6bf9d,2bc445d7,87103c7f,e595a30a,41c9aa4,c41d1874,d7ffe69f,ee09f397) +,S(6de2c465,c09d5a54,61c618be,c9c16ffa,21b82e5d,673033a0,e88cf90c,fe6d8f4a,367acbd2,8950882b,428a8199,d3b21f5b,e1c4ccb0,3280bf5d,28b65cf2,bc4ee2ba) +,S(d6286e13,ee10c7d4,5ae50f80,3d1a5417,cecc9c68,9efd2847,6ffa73f,1a183f4e,7ab92bb7,55204e89,c7e3ca41,1c829e41,e965ab93,57db88ad,37f13e93,6aa56f56) +,S(7526e6fa,ea67460a,25525962,fdb6f209,73f0c861,ef3c364d,fce83df7,23c3bf58,2c76a8e0,d5a8611b,d3274411,cb323751,25a21fac,12e35ae8,f008f48c,18e3a674) +,S(fccaaada,56d64a3d,6d1d5d89,719f51f6,e737c803,893e8b2a,b785070f,8879308d,8262c566,3facf792,efd750ef,a969fab9,a2ee95d3,fe6e7d7d,8685c6a8,479362d1) +,S(b60d13b8,eb8a5f43,cc448379,7a397847,bd6d91a8,b3a6888a,fef4b115,59b57fe3,abf73ebe,5d2b8585,76104acb,ec885f1f,8405b053,3755b8ae,94ecf838,60ebaa54) +,S(332d4b0f,4a0dd872,ffd6d2c1,4379f925,4250fd66,dfaa2d90,127e6ce8,c377f8be,37f3143,47c2350b,f4333d7d,9e0b17eb,110dfacd,d87ce354,b7887cf3,1bc6232b) +,S(e99b2ee6,2ce6d633,1e0e880,37bd138e,5d021620,b555b94e,52def87b,4cc5788f,c9ea06fe,dabcca9f,6df1df26,8bb3e550,e2858dc2,b91a7c6d,2c048416,4e5546bc) +,S(89ead438,2a977aee,7fe692a1,d7199bdc,5af24191,e80573b1,dfb056dc,49c54353,b572ddce,db2d776c,2a967f70,6b7010ad,7fec43b,ebe5f19c,2de0f9af,d9994ece) +,S(cdad98e,529b413f,b46f6fa,98c74058,4777baff,b090d488,59587b4e,d598268f,d405a95e,543e639,470f10db,821f8786,ceabc281,788b0cac,3efee830,bfed034e) +,S(5096ef41,1cc1332b,e67f69ad,3cc3140a,c269849d,5e0f4f5b,e41290e4,86ee2cc3,7f33869f,ccd4b06b,ed61f312,30a7b3f1,49ef34a6,f2d46bb4,18c45343,73f8268a) +,S(bc0bea70,a0966734,8607253a,2c8be987,8c4d59ed,638ecdbb,8b9f60e2,a4a5be61,e19111ac,3c2b4e0b,4a86129,e6c4c275,54d1ff0,29ddf320,873e20cd,16873b78) +,S(2d166569,ac8f5a08,e0674d3,8aa7d747,b024bb8a,5c8407a7,dc451403,87223ec1,48af1b38,62216a5f,12a7d92d,4eec4e59,445c1587,e22238f7,3dd1bd77,e19a597a) +,S(b8cbcfae,bb8b1150,ddce37b3,26ec77b5,2947cddf,e3cf1d40,f27e8b7f,8145ba30,d5234cab,8b2ad2dc,8630ec02,2868a1e8,ffc2c3fb,cd5f5a05,62b6fddb,34823ca4) +,S(fb396092,563f12f4,ddddb9c0,f1ac19d9,fb2e3ebe,608eea22,7a9aaec6,dc960ee7,65e565df,fda1a394,3d27f661,c2eb01e9,646e88bb,6943953,58c9e62e,c9823c45) +,S(1c6e9d76,b8dcdfa,90625150,db2274b2,f8da06ee,21000225,80affa54,a414b297,706b450d,9ab0b0,5466edcb,bbed8b10,85679fb9,78d74057,607bc2ef,a5666255) +,S(2e043dc1,46ecff0e,6e566b13,d985cecb,77f55a0d,555e0277,dc660351,b9fca1c3,1c4f1ca,f75ceaf0,a051103b,90a7abf,665da500,2aac4e14,28a71e45,726d8398) +,S(5ae17b0c,a1bf8e90,e663ee12,d97d7855,9549f9ee,2d89592c,b4b0bc9a,585f482f,bb0df734,931700bc,73c6966c,1e8e5a77,a71806ad,88d731c7,16f236bc,b4fc8111) +,S(fa8bf342,6a24c3e5,d3c11c46,e75eda94,fca910df,c906a71c,1b08f468,a7caafc4,ca69817c,db07fbd9,e35e6c84,65b3cf05,4e2884f9,e57c0043,5dcada4c,2f5954e2) +,S(2cdff1c1,846dd7f7,b9df67ae,a3f4394d,1e1031b5,de7083cb,f905afb,991a88a4,4bbd724f,3827e42b,7d0530fe,de304711,6ea0d88f,8e564d3b,507ff3e2,ef76f39e) +,S(6fadbc00,55ca49ec,afdf82b2,96504f89,c5bb8291,ca942df9,5f5b3322,9d3b6905,f7671184,33a8326,a56f9472,8c411917,911a3053,f593e868,c06f57ef,54b7df62) +,S(c514695a,2f26aa40,dceb15f5,5d5ea8d2,6f4a1e06,12591fca,2f5a00e4,b8dd0841,5056ba08,2e78b06a,90937567,73fc4ef1,652905b1,16d8fa6e,8005283a,b113266c) +,S(83dcb8d4,93474f85,54c368dd,3e188c11,aad758ee,fdd1f064,66c11e16,cb7ff933,104e5b3d,4e57192,7c67a029,e119e79f,d6ed6fb,e61e288,e9f8bd84,630a53c7) +,S(bc65cf8a,cf9a0b26,43b69089,565f9a9,5f9ae882,2e2b1127,a8bcabb1,fcc8a93f,fdf9716b,a31ddd06,a080ac90,f6699b78,23ff28c1,155a79c3,ae9c292a,14fb2143) +,S(48778fa9,520b12a4,12d74b47,65ad37a2,695e37d6,4070d53c,1e09cbd2,4c9f140b,cdc64805,bec15940,387b4c02,bc51b469,446dd3c5,b2e35b39,fbeca21d,769c373e) +,S(9db2c42c,6a735886,8edc8831,2ed6873f,28077bb5,32d186e8,41f67ddf,a301dc25,e01cb235,ec9db45e,e1193e06,46a325b0,aa0ac5d4,786d0ac8,56990262,bfb3a0dc) +,S(cbcff58f,62bf025a,43a1ef44,256b27ff,37c6c8f,2496d2ae,fb280734,9cf8da6b,4fd99ed5,2da32753,3a9251f,e1e136bd,28f5331b,c1101da2,818de6e5,3bb1896d) +,S(9d520b97,87e68c45,817a12a2,93b1df96,70cbcf3,91788270,93367253,6f4f3639,615e115d,2b539895,d91885ca,a325625,41fec07,9d8fb6bb,22d9ecef,b6bc0f14) +,S(c648ddc4,57c2bc,bc23d182,8cc6d6e,4b0bfd3d,f83b2e7b,3ef6a341,9225dbbd,ac9a863,38dd1966,9bb47e99,e67a3d9d,ec16fe61,dc17ecaf,209a7fbc,518ab3d8) +,S(ae11f835,ea96f767,afde3f1e,79221dee,b80ead29,7b45e29a,7e596461,e82137dc,20453bec,b65a62f2,8996e1b5,f1953acb,4c5dfee5,4e5f9a15,c2a2178e,4c452596) +,S(a35549ad,56f8a64d,d23b9293,d8ef5128,699f6fe,365c0fec,29280d0,a364d46f,c84041cb,a38c9981,3015ffce,17ffece0,8f55a292,3c64868,f11cd6e1,bfbbe75) +,S(75877029,af5575e1,8dbfaef,37dac89a,2aad8308,d473a64,9c347097,e35f8077,843b0497,d19851bb,ed243762,177cc69,603cd674,216cd65b,2e5a85cf,5fc2b8b6) +,S(44ee3168,ca7ffd50,c467b1f6,83e532c1,ae00b9e9,f2eb1ca,917607fb,32d4ea99,10a20ea8,120b5a13,beda9f9a,9110eef,22564e3,9b96c141,1e73eb7f,c92c3270) +,S(9a013c89,8dafaf0b,90678f92,f3bb98c9,461e4595,42cb07d6,477b6f66,7a5337d4,11f8485a,c96623a4,e6c9b773,f5cd9fcb,fec396f1,ff53205e,8774ba1f,da3c2a73) +,S(b45e28a1,44d54182,20819a61,5f50b349,3fa12d17,2b8b5bea,83e73d69,b6b47d5c,d987db83,ccdacd21,dfff1dec,43997253,fb1c2092,95bcae4,5b76c306,92c29f4b) +,S(9e7d6a53,49845888,a8865d07,310192f8,9a659205,1d2a603,cdc03d35,a641a0c9,ca1774ed,ace29fa7,f57e5690,b4d1c0b2,ce5f1fbc,b21fb323,3c001498,54f462d9) +,S(113a1429,be1b613c,567b306d,5805c163,e433a940,8ef14b01,b9afea43,54991f47,225ee5fa,6d26cbb8,49191ec1,a51e385c,321e801,9152a3c7,50014567,7b928697) +,S(32ec8dd1,2cf85df,931e2597,f6b005e9,6d6eb0a6,d0dd7964,77655d71,418d9181,fd718dd0,78b3e4a5,9bef7f4d,9c430764,3423bc05,e1aa22ab,dd7bbb,aff9d8b9) +,S(ada43267,f2cedae4,5e1a5f1,46151f89,b145db70,ef477865,b1218e91,72e9246e,d148bee0,4d1f4d29,f9f15c57,8b047469,16e39686,c2b2ca54,1f3e0d4b,247cf82c) +,S(818a0abe,debd74a6,91fe662b,edba1a52,65f5ca07,2017c6bb,bf7b9847,95bf0cbe,e7b2d06a,1872c73,6988da9b,ce273b7b,ac0f03b,90903bc8,da719ce3,89c0a53) +,S(2f49eb55,ef77da10,804c1a1b,f596f09e,ae76026d,f2d12f14,d80be810,7d0b3c94,6a225810,2f1118,eb689aa1,e6d4ced1,1a79036b,802caffa,5694e383,3e038b83) +,S(7fe54d70,54cb025f,6bef8029,bedbd15e,bf66d5c7,986c678b,a5cc5353,7afaf74a,fdc617ec,72ac6632,6d16afb6,69188554,a47a82fd,db757695,2296c10,b4ad89b0) +,S(84f59366,2b8284a0,c9db8675,db9c55d7,411ec9ba,deec1319,56aa3f75,8eed2689,836e65d9,6bef6ed7,825119c4,c4511c89,48042592,f41eddfe,4de98e83,acd0d88) +,S(c90aa830,1a84820d,e06eb6b7,1ccc9bfc,a46b1612,5e2b5f52,da0a6fb5,4185ee1b,ea86d7c0,b285d82,9331e05c,d99c58a1,cc213449,d9226efb,16135237,f90dc8df) +,S(ffb4d576,abae49be,69f047ef,636142a9,8669b2ad,9cfdcadd,c057d96e,192ef100,3740cd14,b2d5e018,33a700e4,c80f6a8d,3d95966d,a5238120,80a9101b,b7ec6c7a) +,S(408a8d89,67ad6bcc,eb7ebb61,89afefff,12c24b5d,2c33ca3c,8b78fca,cd403de0,3b761fa6,378cc42e,a28fb66f,f1d8171d,4acd3557,fd6313a2,cdcbce47,e1caecf3) +,S(580a33f6,153109db,fdde27e3,f1b0ab04,6c80c04f,18326712,3e3482e8,7c53b787,bb8073c3,fddc81e0,e99ac5ae,69702ff6,f70a33a3,5639add8,1d353c0,e428431a) +,S(2d310a94,7054ccca,c46b1100,88349ad1,4c7860db,38c698c2,505e789f,8344130f,1ea2069c,3c6ec90e,9c11be0a,913d90e,2df1875a,2e26aa9a,5d28dc81,3e3db697) +,S(2874282b,e7b11cad,3f22f2e3,ab835aed,5d82b424,24697b32,985231f8,6a7aa450,286332d,b2e1b922,222e3860,e41d90ba,cf39ce03,21f26b74,cfa23171,f0415c42) +,S(af9e779f,f77bf3a0,10af5e41,82b77981,6940f85b,9530eea4,8b36e401,eb6231cf,9d3d4350,dbaf15c9,269d958b,86d6b88f,4deb7083,ab1ff389,c13f7541,98e84c67) +,S(445edb8d,515ca735,26fd2757,73b2778c,bc93ad8c,a661b35,4471d035,688c1ef3,94917a3c,fde762f8,3b774361,1f36a13e,e94b759a,455382f5,55d64f25,7090dc49) +,S(e010c20a,370d5306,f89993c,f7ec34d1,3e76feba,2b6612aa,dc75012,701811b4,cb45172d,280d9be0,52d57a21,4cb3cc47,798a6426,f215e3ce,e3af64ff,106fd8af) +,S(d34277ca,4625c7e5,b1134080,cfb44cd2,ef548b3b,67bb73f9,eed42352,ae5af8f9,a35f5779,7a628f7e,bb37bd60,9e3f44ee,c391909a,ce27ab44,1ece58c8,d7e4a4df) +,S(be0b9399,3bd54241,b684977f,ea4733e3,d96182c3,c9fb1c5d,d665eeca,cb1d628d,37904353,744ed26a,df76272,8ec41898,13218b0f,5fb09da,dbf5be84,fb7fdb8) +,S(308295f1,ed4a21e9,1ed9f48f,d6b42829,edd9bd34,e812f09d,c3b2c319,fd8f3980,6835c34d,5c360e1a,49a14c31,4ee4cca3,797d434,897c4181,a8ba5d7e,aeac0230) +,S(66cfeb51,61aa879d,fd791604,e10f5fa5,c2e07a5e,66a37b41,2b88db32,dc495b1a,a0e07a9b,f8a2fc01,3e229602,b483bc26,5ffba9c5,fb6ebfe3,f9ff9c9b,3252a1e1) +,S(f42b8fb,849cea70,4cfb3d9d,334a4a11,bf7b3aef,9b55f648,ec885a2d,6fe39ba4,b60621e2,a36d4aff,9f75db65,dd381ae1,f5b0fb4a,bc9f19a7,36d160a,61e8b22f) +,S(429c1785,22906323,2ecfdc46,2666f8f4,c57b7fda,608cc8e3,85a31254,bfab034f,e190ba59,1a868f57,40bbfcb0,481aa04e,50b3969e,abc941f1,8e69816b,2962af35) +,S(c8939d7c,94789a0c,b95e4237,fb378ee4,9895b985,6fc67d7d,fafdf7b8,debf611,143aff62,6e94617,c36d05e2,3062d2d4,47feb77e,9b15e2b0,4370f81f,1cad3682) +,S(5e4155bf,56303243,24e15ae4,142ad81e,2b82aeb7,8dc3ccfb,1d36f3cc,4398ef94,6801f527,2325a3b9,a9f3807f,216d7425,b9083364,203f3b75,ed6f4ff5,eb5da55a) +,S(1196b198,53f093be,7bbfa851,a7114e23,eb01c530,6078965b,5e9dbd3f,8d1b573,794cf0,54bfee20,d80dea44,d183db44,fe79dced,fef0a97e,5c557fd2,bc628795) +,S(d818d920,74bb737b,7db8fcd0,168030e3,39803e5f,6b76ba1d,ea836ed2,c73a6094,6ac7dbb5,1f63118a,80cd2aac,fb5f086e,ff15d51b,fb4ccafe,9d96f179,176e504) +,S(c0276b4b,f5ccabe9,ed9a433e,eae5c989,7039042d,b273ed88,51db464f,b06c6204,489270ae,6349ac81,d481a582,a8581520,972593d4,9b3facc5,fd52efca,24f4756b) +,S(94b2a1c,ca23cd30,eb9b300b,43d0b24a,b898906,1c4d8a7a,d3343d7,cdd83307,47c5ed56,b709bdca,5b960801,58338b9e,e6e74683,99a50640,6075302f,9e481df1) +,S(f2aee379,df2bf54e,e4a1c385,c28fb64,9f157d2b,d345995a,66868876,ae7d5108,ae766bae,9c90a1f9,c9079d35,1676eefb,19a7bf8f,bd56a311,13f2dd56,35c8ef08) +,S(fc8fe44f,3dbdc4b2,afa9cd04,3601c6a9,e81e4da0,456ce222,8306bb85,ba9833ad,6a321b78,a98f52d7,64330a52,ea5082b9,2b07655e,ce8c5094,ce307538,6d56fe15) +,S(d38cdd79,19a4f3cb,fbdaa3eb,e2ddc10d,7444d04b,5830eb7c,5b8b464e,4c255c14,6a0f1ef1,823a2fdb,94a311fe,cdaebe7,e1904095,1ddaae6f,1a565551,2c8c15fa) +,S(ac02e6f6,13d8690,d0c71943,a26b5e9f,916ea119,d7773f4c,14247538,9a4b41f,eadc499e,436b4eab,bed9c5e7,68fd2f67,72659819,437708f3,99531ba6,c05ea2b1) +,S(3948b1a,c36bd462,ac7b5cd0,7076f9ce,dc6d1a75,1ff65177,d7d9b701,d06419c8,ca91fceb,a01c03c7,ab141ea7,1cceb61f,72d5d18e,77964bd2,732bb95d,191765ba) +,S(4c7dbc8d,21d600da,6dd4c0c2,cffd8842,ea9e73d0,5dbcb554,35e31971,7e706e9a,86a77f44,b87b7abd,29c2f412,97f7e859,6db46ebd,8cdb442d,35dc17f5,278230fe) +,S(75228daa,b3825e2d,9f8c2f7,a0743b0d,b7dec731,d9df5e06,98ee11e4,8244f623,963c2987,e122f107,dba37bdf,ed282ea4,75e33665,260a5aa4,51021a88,780a1676) +,S(aa3a86b3,2ed2161f,8f6ea92c,71b7a47a,b584a73f,102c0147,632d2c2b,e80a579,b8fe249d,2b4ec64f,dd345d3,210244d7,f7e517ff,7722c2ab,bc4601ad,ae4e6cb7) +,S(702b912d,9828039d,a58b992f,7d6f3af9,4c03227d,3d3c368a,bcfd3164,193f22f7,25892c49,3a32cd78,130a4e14,c714cc7e,b576ccba,396ad36f,71de5c42,c6bac387) +,S(4ca10c88,6d44bfa6,2a221dfc,10c57011,269f703b,8f6f3567,829d3b5c,9c90ba75,3323eab2,9282e358,d4de6f27,72d77db3,95b04a22,7f0374b9,dac3ecfb,4ffde3e7) +,S(1619ea36,30da6972,2caa436,2c174efc,f3601c35,2e946d34,2da56738,92b9c325,22ad140e,13b8679e,a6d88dd6,148ded7b,a1c12697,91c7ede4,b98a72f9,f0e881e) +,S(21dfdc38,18debfb4,9cd409a8,a302f8ac,64d589ba,b65074c6,365bd398,d34d3032,bbbe7ec2,e835204,a786ddcd,bb6026e6,106d193e,21725c45,79eb17ce,784099a9) +,S(60fbe5dd,802f1ab2,cbae99aa,12cce0ef,36a472e,bbb1bd1,c0ddbd40,85069fe1,ea83b59,2dd304d6,82fd07a6,85408f0b,99feb1b2,b78b1316,7f9be524,a7349dc3) +,S(c804b465,fdcdc5bb,a848ee97,559405d3,dd7c2479,4dc4866a,e29676cc,1e147f96,aa4a2eb7,1fd82b70,ebebf43a,9b828e4f,fb10cca2,cf9bb522,3a7eeef2,5badc5a2) +,S(77a6e3e5,51373b55,dc51b338,3c32f6c0,5c74cfbb,3192fb7b,d96d9d3d,d50336d9,21d2326e,86efac71,48e075c1,ffcd573,5de35d6e,3856f2b6,7d358b6b,c6f047f) +,S(86ddc187,4a72eed2,666706ff,26a4ec65,a89d82cf,64e3d8c9,4731d62d,d5f7a5a,51f7cc40,ce45a123,a9217816,ba3e6dcb,40507b5e,4cde95c,443ce5ab,4f0cc29c) +,S(cf49d0f8,db8eeac4,6c108675,a155e327,8c80d5ef,84ea28ce,4a596f3f,c7d3beca,6ffdc741,ebae75c3,ed82dcd6,a6191d68,7cdd64a5,c3146d41,235b96df,420086fc) +,S(1d75ef89,57eb6722,2d60e872,1e126cec,c9f5c851,5fe18381,518cb54,b75875f4,82c5dfdd,9288561d,dbe4ae2f,5fa1d429,c2076625,7765b3e3,7b99dc66,b78dbdb4) +,S(bea4b735,f62e6122,9d8d9466,69503348,5bb5b7e3,c6ddb6dc,a292ca89,e7ad0689,90e3278a,8ea9e10,e7d9a451,7b7c01f2,7cda5836,f52a011c,d8e20ad3,7a08901) +,S(e85b0ade,a90e5170,18d0aaa2,75d5989e,577f5cf0,b3acb728,1af396a9,6169f2bb,d42970cd,3ca175c6,3916fec5,757b7f5a,30ef1269,d4083358,667f599,e650aaa8) +,S(d97592dd,24050526,e41ed550,fcf7cc2c,82ca5584,c0228f5e,3ffe42d8,a3928934,eac6c169,6bf01c3b,759a3852,a0236f4e,4de0db45,26f2d26a,2174dc4e,fe2d102e) +,S(e023ea4,50b620e2,378e60a9,a8c65778,fd772575,5aeb53eb,edd35ee1,666e00e7,4e4ed850,6dbdcf89,b060f0e7,8915f506,6bdd544c,e37e1e30,6a966353,6894797e) +,S(615b5c95,5cd4fd6e,a581b9f7,e6a857be,a7c0ec2d,c302dc9c,c8304ec2,d935e5a,c221c766,2602325b,bcd845bf,f5d754d9,46fc8074,f36a78d3,6e421b14,fd5f4d46) +,S(b1dfa434,2e12021,b9ce34d6,1391bdb,fa2a0d85,a004985b,c2cc7358,96ec13a7,fa3d115a,8162f828,1dbb7e9b,6f818b4,13c2a5cc,58993ead,d103ef59,9748438e) +,S(b64b601f,afbe47fd,ac675b83,5e4ecdc8,68c7e1ab,32598974,36ba3c9c,bbeada7c,af78c039,d2315746,feb60662,462dbc9a,652ae90d,573487d8,5ea52374,e9dbe68d) +,S(5429d346,fda1d9c8,6c5027d4,e94d7565,b0981f23,52715336,4a0f3264,6bb579cf,5b8ce197,dfecd92e,390754dd,2d74636e,162d6659,51464f37,ac696a32,995b1880) +,S(890694f2,56d6718,b040bb78,1041749c,20e21669,f3787f94,ff954b16,2a6f005b,d966934a,890dbbfc,bb90d7b2,26afd0f8,7bf505b7,31b94df3,5df1c141,2d753341) +,S(3ae75292,cd0526b7,fa6987a0,5fe060c8,269b5d1e,44a2867c,cb92c2b6,743cc117,10959cc1,5a74a82d,8f7d5416,a33256bc,f004eee9,87b82871,d22a2dd5,f2416a94) +,S(9d745a9b,ff717d55,5a353fd5,f1b9fa1d,347bbade,8a4abce9,3bb5dc7f,299b0707,cef338ae,d513c60c,7304f615,ae734de6,10461cff,ade0f69b,bac28e6,7ede8134) +,S(699e9c2c,8130c939,105ce7f4,f922c060,abf1b896,648509f0,aaab9519,d144f166,882b490e,1fb9f944,95d14583,83809d69,bfb7da29,97d244a4,38da39ed,7c3a19cd) +,S(e3a01cc1,dc520509,a91ea704,bcbfe298,ae79b4a5,4f433550,3884a1a7,85591f87,f3c641f3,68d19d57,fca87e54,6ddaf495,2480a891,37490b96,6617fd4,1edcc64e) +,S(5d150dc3,d9df375d,46dd2362,34498514,cc7ccee6,fd8ff5f1,ee5ee38d,6ac433d1,2c091250,d2e2ea0e,7d80263f,18401092,399a83fe,bfadc061,a32316eb,52ab0316) +,S(49fb9761,bb12ba3f,644aea5b,5e011f80,ec477880,58a6eb16,c100c5c2,e0996a66,7134220f,b7208914,58499caf,21654c5c,d9086b1b,92978370,89cfd06,d655e23c) +,S(34c55eb3,a4512dfb,de799021,1adcddc0,bdea055a,1f4f7b13,d530c945,2a44738e,258cc688,beff401f,9a910e26,d0c979e5,fdbb695,323321f2,ba39a4c5,4f98fd16) +,S(7068fcf0,7c3efe00,4ff7b82c,2af0c9cb,9b1c39f2,30dc602a,b2508d42,30a3a98c,e48730d8,844578c5,2e7657bf,202b5df5,2fe50679,7e2e1d77,aaab197a,e37ef1fc) +,S(e1d8910,a987aaa1,12ba1f95,ae8e346e,f49e5254,a2b01909,f73b874f,6b355a1e,8ad0311b,cc4947d8,999c2c14,9fd5c59d,d4a56a20,a0b90235,d7bab907,fe3cdb8) +,S(92509b88,ba8631b,16c6b2d,c60df45c,6bdf06d8,ed4dbd57,c10ac3cb,72d2caf2,3ea47a31,633b6299,a9f95651,b95f1411,ee6f0f33,35ddb8c3,3978af58,746a3ccf) +,S(90fd402a,e8d505e9,96aec994,db7d29a5,6446471e,34dc7512,6a356ac,1a66a519,68c0ff7,bcdc36e0,ada31816,ec4f0e67,9a6dc658,46aaaa62,e1958ba5,bada3b6b) +,S(b380ecb,7d9bca8e,1e35b0dd,d412b128,4cbc77f,c66c5f5,eb390d9f,a9400704,fd2a2092,77d9b783,9df69a7,229d55cd,18fa71db,e1f5f8a7,d78f450c,846a01a4) +,S(40e2e041,aecbb6cf,6f866140,b6149257,f3d029ef,ccf2a752,d3ef7b0,32b83f0c,122710a5,3c83888f,54e26679,417f2329,e1eda641,8e525326,704744c6,bc2291f0) +,S(8e609fc4,3f4e30c9,3893a38e,9aeacceb,7d254eb9,f77b49c8,c99c20a8,aaa03583,947c4c6e,9a821504,7f259a86,b1d70378,837fb57b,e0d696d,66a3dc3,7ac1a3e8) +,S(b871c5b2,2bfe9fd1,6898d00,1af89a8f,8d9c9324,52fce0bb,2ecc0835,f435f5ce,e302e5a3,ecbd0ee9,9f87226b,6f038003,507fe8ee,60b64,cd656f26,8f1d3078) +,S(526daa7e,39e891a,bb524170,96fff4d5,c6f80f57,cce87f83,2ac07cd5,50841682,69f04499,4fb7130e,758fd397,5ad40f68,c477bc9c,cc5c5f43,c5f5a554,b3d210df) +,S(c15c244a,514e3057,ce67cc07,3fb66fa1,5c031f51,8add9ba2,edc12f94,861ad25a,db1021ac,ecc3c897,8de34780,bbc9a8fc,16449ddf,5cb05b90,1ba39598,72846c50) +,S(37e20b19,466a038d,b3b63873,50dd3dc5,d3494876,cdb7f344,3e234173,eac1d388,b80a24,546541e2,ecabcfa2,7db57aba,5ea5bb79,f69ecf25,2d68ef63,fc3b89f0) +,S(6d091f28,feae0142,b311cd81,f57958a5,6a0da5c9,7ff5eab,c598e4fb,564ea528,48bc97f0,4d7ea6c1,38189719,6c85dd22,6e9d9f7c,5a8ba74c,27c29063,fdd07906) +,S(3bdbd416,a76efb56,ed01664f,b819dbfe,d3e545cd,3edd48d3,5ca635e0,bb54fd71,a6954d72,3ed7253f,ef301621,91fbad8f,9a63a893,82b98d26,a6bf36f5,2ceb0639) +,S(cd4e36a9,f111b55f,8c05d41a,4bc33ef0,c4109540,d9871237,4018b2e4,7e9d61ce,478dfa16,52632e69,6ef95ec,452df807,abded9bc,264e6dda,df0c6215,454e3e57) +,S(f23cc4a,9c59c0e,3bf21413,170ac67e,24845771,2e77f1c6,272a9f11,2df24efd,e933bc72,99b6effd,5cf58fc0,72f7a466,dc71cdce,74a3d3da,9ed5e7dc,577fa4b2) +,S(d98c6585,8c97eb35,b6846840,cb6db623,d7a349,435d4989,31a695ad,ed3c33e0,443fea24,ffe8825d,eb6c953c,70627395,ba13781a,164f2eb2,a85b862d,e3114990) +,S(2269daa6,c055dae1,b6d2b9d1,6c74a9bd,65325ddc,a249085f,a946e66b,6c744225,159d01f9,a61f0456,b08f0fe6,a42efdcd,30e14ff3,bb47fdee,2352dc9b,f5bfb3dd) +,S(335044fd,8eea8792,8de3880a,546b01ad,eb4d75b4,23ae7ba4,87740c03,167c48d5,69e503f5,26266bbc,63b0f2bb,757b3be8,cfe1d9c,e63d8226,8187a309,ceda1cc1) +,S(ee7a263d,86f9a83e,54cee87b,7bcae75,a601da9b,637aba50,46bc5f9a,3ff6c512,9fdd3192,203268e9,2388ac1c,840e7635,22271483,161f8f60,42d82909,41373d56) +,S(529b33b3,36f1631b,6c7b6111,ef44a888,bf95f344,766a2d97,6c5e5d5a,53f44245,12856106,93da6f4a,2fabc1a0,3280249f,6f29f9ee,9ccd7000,4cf0a857,ea061099) +,S(f2b3346d,a6cee9f5,1a933718,2d655a88,6a251353,8ebd243d,d3e3cd65,abdf1849,d41df628,be7703fe,9e866526,2f6278d3,55aaefcb,324df2e1,f483b0f7,77b77da3) +,S(535e9dbc,f03d98c6,70d03d04,5d638c7d,1db7a12a,22f3837b,3f559b70,4582befa,2c233228,bad897c5,bd4fa98d,67f8384a,62ea4761,4f64e4e7,40bc1f65,9e358392) +,S(c131688b,70da6ac6,5ee3172d,dff34624,b019bf78,85033970,8253b4a0,b299a7f1,fef187b6,e0e748d9,69a11d82,e9f996f8,d6e1aff,8b84d20,7dd78519,dce5f3cc) +,S(75dc84d3,f7ab7985,10ceddf3,da6bf832,a984d00c,98726a64,5dc71b21,754d3ba9,f5d9edf3,5e110491,2cc5e4d2,82eeaa53,84f62deb,1dc2a183,af5b232a,e3841c50) +,S(591dc7bc,9136c38e,ae727310,25c5fd52,82c6dad7,6f98c648,78847ed4,f32a36c5,fccfa4c4,f81cd382,e003aabb,4cb6c5e8,8d4875b7,21d44233,95397268,d7a421a0) +,S(83a59c89,2a8392ba,e7548fad,b87acf7a,d2c78db6,4c588f0f,b14753ce,12712596,7d00ac1a,33b12065,d67c598,8822ff3c,46f090e3,15cf919b,e3e5030c,e7c5873b) +,S(e9b0dfa5,8c52b2f4,a9c1b8c3,76391eff,6608f968,ec45bfc7,6ca93e2c,ba6f6f83,6449b28d,5846de0d,27489124,feb3f3fb,5c1f0839,a7809be2,e5cb5def,2e0a7c8d) +,S(16cd2f9,67b090c3,d151c002,d3a3d25c,c76adf50,d55a6f81,b1b9a650,b72bc03b,c592601e,2fe77090,39ccc091,bd78458b,a23db74f,848ee06f,50ffe4c6,8ad63a7b) +,S(f347d3fd,1bcde363,69e3d9e2,44d6e5f5,d80b8dba,7b1866b6,f584a38a,3aff1cbe,1c435ab9,ae38a13,98dcfc6d,64125e8,c7349f81,1584fa97,66dc4d24,7e87977a) +,S(5b190d87,d644854c,90c49f11,34921545,f349edd2,b4e9926d,534374cf,da428b1b,8a4eacc3,63efd6bb,5c93ab25,65d2c157,9c1d3176,b2713ea8,56bc97be,fa5401f3) +,S(a7786cb2,d7314ce8,f21e9665,bccacad,c49e78f3,7772c3ab,105f67d6,1c30834f,4fc7acd4,18982e3f,2fb1f911,cb70bfc0,6c4ea71b,a05f6371,46e96bd4,a9441953) +,S(d3654f53,e9071a18,8c5faedd,c0ef3616,abf74d26,f073ddcf,545a01fb,2fbf33cb,a56f20c7,213c0394,5978502f,c4a716f3,77c7a3d9,26c3cde1,880f103b,432f4383) +,S(e1138a87,400acbda,69d8ac3,bb6db4cd,27d03176,ee88994,2039a93,7822399c,f29a8fbf,dd3f6d46,5c640de6,b6853e40,1803cd95,f5e012c,9ce967d5,13a162c1) +,S(d29eb63c,91c0f4e5,b3c49c6,9c9ca952,5714730e,76bb87e7,374ac995,86317708,4ad93702,4e9180a5,9d22ab4a,c856de6a,d9d38c9f,1cb3fdd9,d73aff61,fea5f1a1) +,S(a9d403ba,a6717fd7,6577da1,d8b8ecb3,d2124b30,d18df147,ca48b482,26ee49f8,1eedfe7a,8c5ee1ee,50937bca,d9591144,56f1e49e,db74133f,f45176b7,26d5323b) +,S(ff7b58e8,dbb6055a,eeac6bfd,112d89c9,8d8f3763,98e41e39,ca076bd0,9ef57528,4e4e39d1,ad7a51e7,d6cb57c,836c0685,8e39f1f5,bd41aee6,cf5d250a,fc381121) +,S(43c50a9d,f7839f61,e1b6db23,4e2f146e,1672ea1d,566f5613,1e7bafd1,bd362979,f20fda98,81541a8b,a83e908f,69e05218,1e215885,f60cfbd6,1ada74ea,83f449ae) +,S(f608a9b7,1c91298,75662ae1,6be6d043,5803a9d5,29d3be53,9843f227,174ac30c,5ef364fa,e919dd42,1bad3243,413bb565,d788d266,d7b508f2,83c486a,327ad5bf) +,S(c913e029,dd1ef043,f9bc48d0,c267657,3cc11722,5cdad56,8d013327,445a117e,97573f0b,9c31cbb3,7bdcf07c,13526a04,32a38f18,43e26d8b,ace85a50,19a83049) +,S(aae0c49d,b17e7bc1,66c0c58a,cca847f,61318bb1,3482f63c,ce7dc55c,82a7d728,41170bf3,f68c3dac,22051aae,658cdc0e,810396ff,9d5d9251,6a7e6377,5c6be0b8) +,S(f2805f1f,45a0b622,59b9b15e,3de4a05d,e306c8b5,ebc5ac96,d35aa388,ebc846c8,f5d72739,6ba37244,57725cdd,912fa38,b36e201c,26409dc9,9789d087,6b8d1267) +,S(6969e4e6,e150d12e,4a230e59,37d865a0,f7d2323a,781270d8,7b0a7a90,fa4f39,c71c33d6,d323ed0c,3e77ebe0,8595dc9f,e030a0db,aae16f88,8dab7187,5e14de3a) +,S(aec2bf0,7a0e257a,be4fbdb8,e872dfbe,2aa0643a,411943e3,e4cef039,8d988f3e,d8e9f557,e686c380,c84bc528,fff0a830,bcc3b6a2,724d9df6,ef21d545,c8c931d0) +,S(9c6ff99a,13dfc35c,a502890b,69d91dd5,198f561c,790bf322,6bb243bd,4926f710,2aef920c,84a4f5ad,9d88f541,1ff46839,2f7f4e63,3422b11e,9b683403,f7ef849d) +,S(fa43745b,37a5e238,df0246d6,7eede652,ade75aec,b5dd8aef,afb8e6e0,96d7f1c2,df9d5aa4,2a3c6540,3793c8f3,fef939ee,48aba7f8,59fe9ead,dc44e82d,a98689b1) +,S(694a3288,6c4e26c7,eb3b84d0,9e777f96,ce3b74e,58658741,27643dda,a78d46b9,a54d6c6d,7645e5,6e8909be,922cc5a,a700d932,cb1318b0,1446a9e1,8bdfe67a) +,S(65499597,5be06b28,b4c339a2,b126210d,930fe920,7cc72be4,3d4ad17a,c08f38a0,bdee23bb,467fdce3,2d2cd92c,e81e3f5b,d29fe8b0,8b35abe1,c684443f,72f7900c) +,S(3791c8f6,75bb14e4,b7d4f084,483aec44,ea38eb2,9b108137,400099b0,799f0bd,2dc8f74a,da5e5eb6,f3b96ddb,cbee5ee5,8b2a3f45,c31cb16d,15a4e918,eef7bc76) +,S(d5e41065,eaf890e9,e9046936,acf6a43,59795c7a,1939d8ed,42941a8c,6ef31364,191ec4c8,a559fd4e,7abbb6b8,f2e4c32c,bd2f30cb,d06ff6d,21f156cb,f65bbcad) +,S(16ce2280,fa0b404d,28a29acb,62058b99,e504e6f2,eaaa3ae8,b77ad650,2c970dec,3d4683f4,486addb9,e54bc252,74e590c,b6eaec5e,7f96e9b8,8174b81d,56efb09b) +,S(a6b0ab30,6cdfb1f3,90e5b447,816841b7,e08f997e,d7d47016,bf3b501,c6107d07,2a62842f,b67e2794,92ed337f,d72abc9b,94e96e4,a10f658d,9cb9a4b6,a80abf7a) +,S(d7ca6d38,760b320b,21cb779c,d709f376,52b9d08a,8ff6ad90,21e00628,56033583,d6c05f72,866d59b9,6b91b6cb,b1401619,5e2d1cfa,9982db04,6d672fff,849e7bb5) +,S(78ab0563,2d3f707e,738cb134,7121c73f,e162405d,61a0bef3,75f6cb45,f5609d33,fe1a390c,10c7cb4f,297a4b42,4baa5c50,350eba49,55fb74f2,1094ec5f,ee75a6b0) +,S(c053553a,5b9fe803,65fc5a9,60e48fd9,218e2128,28935879,bd1072c5,180d6f04,e02da774,214dab04,e11c45cf,57be2802,7d0d28dc,51cc08a4,7528869a,3e719192) +,S(bf85d713,e2a995c3,ef98d403,30fc1fb3,5faf8e95,81385b4e,b65d5ebd,23f02d03,a5d45947,58d7b0e1,a8542a6f,21ddd207,dcb68e96,88284bbd,6b940748,b3e59b18) +,S(fb73b6c9,2be578b8,fe2ee0d,eb0aeec0,13816905,9e55031d,69a4d0f1,1bd280a,72ce7893,9bf5a55f,d4430bd2,55bde818,e15bbc98,37e3dcf3,e31d22c5,9614cd16) +,S(56496e5a,ed338dc9,201b04f7,8f4b6c2c,d9928135,83360dfc,1e2f370c,1628aa79,81dbf48a,824fca70,12315d3f,a56d5150,92ffa54,d1300725,86c8a476,be8c2db1) +,S(d698e395,9e81f098,485edcc6,2f2a421a,aecc0a79,58c9f6df,7905c931,b7a2130c,5903debc,e61eaa39,dac01a8e,3e970a39,79408bbe,1d0ffba4,5ce78c9c,79563d27) +,S(84b32e40,86709450,b32ade00,d3404b34,7fad8d7b,9387d931,780764e4,c566ff80,4c80d078,56cc4296,2b7941e3,195c5350,9bb5b0e4,325c24,4aa3a581,bb1cfdc8) +,S(7129c799,2a3689b4,c1873a45,f1ed3327,6528e243,28f30cf0,5ac38a61,8db2ed6,362b4fe8,482125a5,d4d15456,79009aa8,44f86619,cf3fca68,ce38995a,660810e4) +,S(93164c87,fa48b6ea,6b6cac08,8c991c34,5f8cad7e,f68c5b98,78139d28,d180d824,a3ac0d5c,c91cf0f9,cb97771,d16396ab,bd183221,c8d36a87,2785e847,b5d9e26b) +,S(4f90e8e2,37c4937c,a384c7b1,f929f329,94744d5e,8b89ad94,808ed9b0,9f305a68,cde776e0,2b6b484b,83f417c,fceed07a,ce725e00,343c4e70,14748f08,992430b8) +,S(4d9603bc,9f40716a,e6913fae,253eccd3,4442f6a1,3c058ed6,a10f91b6,75f716a1,92b679fc,278ce355,97165827,aa6fb450,9c52a412,284aa493,c6654ee4,3924add6) +,S(8b6f651f,91c54143,12c94f3b,c1632e13,f90cd718,67f906a5,aed13c4c,4ab17203,88c159a4,b80f2556,bb4e2b78,c126c40d,9ded995,bac6ac13,bf83655,210c7066) +,S(6f58b852,cab98347,e86448f0,78d49916,1909e1eb,60556ee9,8cdc20bd,b25ec256,3a4c05f,233d9305,e6abd30d,da0cebea,1681dab2,ad805cd3,2fa7023c,98239885) +,S(6be7f6a8,4021411c,acb710da,3ffafa32,8bb6ca91,59a91008,6cb98071,100c44bd,bf64a6f9,d461dfb4,581c8d59,b5fc1191,86f339ff,320e968b,b5810145,4836bee9) +,S(b2fcd0b,b8ea9e66,f2cfdbe1,3ecff9aa,99661f0f,2ac1844a,b3983d2c,ae102d39,a046989,bb3b8fa3,eb2cbba,d3a7e810,27c38cb0,ea33ec74,1444e8ce,7182bb86) +,S(a1d6ed0e,ab559b29,edf7770b,50cc5913,3916826b,6d99ef12,91bf744a,79a6fd96,bb91657e,c9255ae,173bf93b,51848094,2f17df30,ac6b391,df2237b4,c04ab69b) +,S(28f6570d,ed7130d7,35366201,e9ab639d,440da5e7,e1c9701b,d08a811e,912a9575,39191f60,119c59b2,3e91a7c7,fbf4c2c,e2216e5e,955db62e,dece6adc,f2d2884a) +,S(14c8ced,dbb83de4,218b089d,101d7b6c,31cfce22,49637853,b9c804f,90271fa3,48052d2,a5d02e71,135cba3d,24c7894b,de1293d,44a2f84d,7a8fece4,ea9a41fc) +,S(eaff9f05,fec737d3,d2a28fa1,bc8450a7,a75f563b,9221bca9,eda2f8fa,e12d489b,d6d4419b,5c9873d,7d3349fa,520f463a,2ad9f348,1a111c3d,d3fb70a9,23b8c139) +,S(e8ee4c6e,b42a3712,85b52457,52e7fc3c,ce0757e0,96932a43,d92bed15,14b35e95,d86bd4c,27ef1831,f107ff4e,6246cb7c,ee55abfc,cbc5de2d,5f230a2b,6a3b748a) +,S(98c61909,8213b06,6b70759,1c88a51a,d5e90922,6778386,a0776e6a,ee41e7e4,eb3d2e2c,f98bb904,42e90e2d,38ce4c53,fd72da8,1a37fefb,fc241aef,f65d4c8c) +,S(d4f66b81,f5d62986,c57a0dbb,c38bcb5d,89319806,4e28e17d,946cf7f3,f946dd29,c1930f8d,eedf1a00,cb7c5579,d814b5b8,2a12298e,530bb32,867821fb,7b7a5fc2) +,S(14d73ce7,5f8919b,55d54369,69866f0d,a13dd4c2,ad447c4e,b9879060,1411087f,69b94622,b9cb0d3c,5d106df2,caf4208b,b71c48f2,629d467d,16ee06c6,93ededf8) +,S(57efc935,59c7a0c,6ac51105,8a50a8d5,5646ab40,8a711711,5bc34c20,23da3aec,fca9329a,60b855c1,74bfba0d,92ae5529,27f959f0,5332cc4b,26272c02,b5c5dfd1) +,S(91f13a86,63da80d,a90b9458,55a9f3e4,171213f5,3683873d,cb6372fd,95b3677f,7405e0d8,6734f110,c329a7ae,92055639,e0332ece,134156d0,3cab4efb,419a90ea) +,S(dcc84d0b,46145e25,a83dfd64,b40dc5c2,c3322716,d1337767,5f9d6aff,a1607592,e46a4cf4,8e4dfeac,8df1526,f53246a,51b95161,a7030adc,8bba8ba8,1d2d6c66) +,S(28ab06ac,d5a6f432,116011e,6bf3c6a0,df0bfa1f,df16adb0,54250174,3348676c,51272a1c,967f49da,e9d1d6b7,a4ffcfef,cc31f42b,e0da52d4,27e56b63,97b0cb9a) +,S(7c01b21,f8d1dfdf,d3f2adb4,5915c636,d9c2a92,320c2d00,beff0f45,21d8b240,b4a48fcc,99906d81,fc6f78fd,aaa96b3d,6e7ffd62,d36d1aed,f76fa25c,542c8b48) +,S(f94eeb78,30f8e95f,2a362423,9c0e8fb,a0d3279b,e0cb5f5b,428a99ac,d14d98f1,c96d5b64,69676b9c,a5dc91be,8bb4a93f,7157221d,9513cd23,5cfe3ca,43649527) +,S(ea4674e4,7788cda4,bde0dd8,5f5e32d3,9a6d6477,30e9045b,d406f5f8,11ec35ca,769bf79,a9b9122,3070032b,a18bd769,fb622a61,424e9a0f,e1a46230,a75a235a) +,S(da5a7419,7f8f8685,1317260,682bfe28,19b7b38d,376745d1,7283c250,1fb40112,a60b5eec,5871e18,1325ef5f,5d6373bc,b5a19f41,2107290c,eb663e3b,95c37a39) +,S(c1017fa5,52560fda,18c6820,ded7b76d,a75ebcec,23b8fb6c,22ff72f2,26e9d41d,e947b19d,af2647f9,167da3b8,dff05897,9b5dc1da,6782929b,1b078114,349fed39) +,S(be7c0e1,4e814476,78a15238,b5809a75,1b964658,19bf0b16,4b3e914b,29216a7f,a30ebe97,f64219a6,f0b072b1,5d648e81,880840b,8a36204e,4f1627a0,feb392e) +,S(6758eec1,a4d6c0fd,cc118405,62fff82c,59e0fff2,cf80414f,cb53b139,97007cea,4653bc66,20fcd852,422c8898,862631e8,a0149bba,d0b9cedc,b4fe3eaf,7cb316b3) +,S(9cbb51d3,f88f4d99,9d80cf05,9e8735b3,11014de,69acddae,70d850dc,405b6116,dfa2e748,cad75b52,800e0ed5,17efc4d2,47c6381,9190a3d6,e2510bb,25902360) +,S(63a5aae7,b170792f,17350229,eaa5ad18,65328bd5,3421cdea,3d6e1510,d8bf0bc3,1125afd0,f25d5f49,f7e6250a,ed3634c2,12a261d7,8ce58ea1,95afb883,52da1010) +,S(adf96249,3e5f0328,ebae11fb,243da21,4e036d24,1da62430,b0fe2c89,b2f10657,509834ba,fcd8ddb3,2d018b16,d17d4b5f,219a29de,8a03f7f7,84f34b57,9b1ea1e) +,S(a0d8f5b,7fb44a15,93583364,e04d7225,bfdfa549,c2b25f32,f00765d9,e34d472f,61eab66,f84c2687,949da99f,3d97fe3d,630b6c22,f9f7c48d,d539b122,ef998ab2) +,S(b98308ea,9596a2db,adcdbf81,56d8025e,7a3ee0d2,5b27c33e,f686690b,ae61fc1,cdb4e317,7566a4ce,b4cc582a,3cfd259,445bae6e,586786f5,1250cd05,27ddbd37) +,S(e1a64f1d,37e3d6cc,119eefe3,793ba303,cf3969c8,db4abf63,7f0232af,70b98134,588d7ad8,885dd2f5,ec4d2084,b3f581b5,ddbd3567,8f4ecfc2,f955ced4,1c3231da) +,S(fbd5dfed,e8543aa6,e72253a1,bd711911,318929ee,7af14eca,49c2276a,65fdaaed,317cef0a,432c3516,3c405d51,65b8c310,f234891a,dbd0d6f2,f76cfbf0,193b78bc) +,S(fac4b7f3,b0a39510,84f1a882,2f7b6f20,30b87c4d,c0178a2a,e3077ce6,84da6bc2,7029b920,9e9522fc,160a5c54,a628fdd4,386ce0d1,55f19fae,390b2995,bc867d75) +,S(ca8643de,834fcf50,802c0296,41b5fc7d,3c29fc51,5c75c53e,e64a8185,43ef7c2b,907a6c27,111e296e,2436fd4d,ad9d9fa,f8ecea31,cee714c3,b26fa964,afcf17f9) +,S(71873649,d700ea1,7ea26b19,efe4b48b,a4a73b22,bc54066b,1202c96c,f3315f1f,f6cd8447,4bb374b7,753fc614,de5cf429,51512748,2042215a,bd82c11d,87ded2fd) +,S(67e738ff,21c3c732,26e57482,677c63f0,175b768f,776cbe6f,15ac3c53,48c5e3d7,14e5140f,2343dd72,577a5064,47cf6093,ebd2854,5d1326bf,ac79350e,eaf2bdb2) +,S(514b3f31,f875253f,205339f6,434ee17f,6c5a5c42,662ce934,280f55f1,9a198893,4eb33993,a2fbec70,4cd1c538,ce7cde4d,a61c0fc2,dca9669f,e469807e,4ae9a090) +,S(426acfa6,eab03e75,6ab30a41,418a0392,ca53c216,f84b3586,f9858501,8bc2dab3,c3d63eab,21cc10c5,c0a06682,d0573bb6,d34944d1,749da74,acb59aad,f1083926) +,S(b946bb46,68c05737,ffdcbee,94597c85,b8ad4a72,c58205ca,d420e8f7,a2d7a09c,cc700ed4,12633826,567e63a5,e65bc603,969ea13a,49feeb2c,dc723bad,1e3401b9) +,S(e6a844b3,f6c8b45f,511d7d3c,ccd75df4,1d1e38f8,fb28adcd,80335b95,d98e33ac,7f24789,3939890c,74a3268e,e1f717ab,6c4aa109,cc9257e2,c0b176c2,ec58cce2) +,S(43e62bbf,d9e052e8,c1636b41,5524b98c,493e903f,2313dcd,117d140f,96458001,f481853d,a90d528,30999300,dcff31d,ebee23bb,49ecbcec,8e147799,a63b352d) +,S(c44ef40e,3427476d,42e23e1c,41ddb9bd,e555a844,9125aad9,e94f44b8,8047f817,bedd4313,e43ee593,f2818e14,776f4ae2,38f664b2,db84c9d2,498b9ea3,8e236fac) +,S(a1b35313,dcc11895,c096f93f,5f8e4997,7f58f2fa,afd9b7e8,d408bde0,53212385,bd7eb25a,bf0d50c3,7309f9cf,5093d817,135a9ec0,20262c55,bdc8e8a7,a3079f5) +,S(48a6f3f9,fd6201c9,a37f2f0c,735bd98e,1382229a,d1589c91,b6748a92,1b5e964e,1b545155,3d41a8a0,64862c81,fa9d5966,2c73e039,53a5dc91,9712c50c,5b4481b4) +,S(8e01f574,651db06e,8a19181d,c8eecf1b,75f050cd,c5b2354d,b06285d9,a4061e9f,9d156ea0,9800e7d5,b6c6e90a,2eecada,7d7ba964,ba1f0cae,256fbfb2,275e108b) +,S(4bc0f8db,9e6db576,3eb68b19,5a79f8e6,28e375f3,1694a58f,43da4dca,fa05345d,c6a70789,a1e6b164,bba380e8,126a4a69,6338053b,6a32d9d9,8d0f215c,43a5b555) +,S(966fd0cb,5f5edead,d6230a66,50b7dab8,f4c7ee8d,b00ce55f,32d54a23,ba97a768,9d644e43,bb4f9b65,f5819a1d,ee0a16b8,1e8929c,a9e544e1,6546cf79,811a994b) +,S(6ab519ad,49522ea6,592dc7c7,4438e337,20d50eb8,862467f8,2962c510,857b0d8a,c5ba3a34,2b7250a2,62b67ec3,554c21ee,e82653a0,378ee0da,8a809151,a3ae44d) +,S(f8b0b8e4,3e5060f5,39bd0a0c,d076e163,e55f18a4,25327856,d526d6ef,aa76c62f,743de052,a65853fa,58cf29c8,62839aa1,7d5c95ba,43673ad1,fe1ecf6f,d4d48ba4) +,S(c4509ef8,579d8ff0,ab585c0e,5223d5fa,967e9763,9d15b0e1,6587a125,3ed18bad,7b91f7e8,ee979a58,5a36d8d3,574b8ae7,81199dc0,86f11cf9,7fe58e4f,1db08362) +,S(9a00135a,6ff450f8,e2207c53,894c0e4c,4cef732,cfab43c3,aacb00fd,ab42379f,393ec748,3684c5b1,4760902a,28cabb90,b481596e,8b847d59,4dfb8ff8,1fa9975d) +,S(3d775bdf,173f8d7c,de90c17c,25d3dee2,a484d331,4e525e3e,aa4a405b,6f488601,7e6b08bc,a560f6a,5bf287f5,59d74e25,38a4025b,89972046,b3de98c7,b30e51d4) +,S(cebafd3e,a60118b4,513380a8,d10a29a,a95e5002,d703d7b8,f5d0e983,7b03b529,19477ab6,46f59f61,ff603594,e33ba046,5f6d8b1b,f55290c0,fd61534a,87b74b4e) +,S(ae8a3cac,1ff3e3e1,ef01ac16,2e49b237,7ecbc963,f58adde1,58cb1987,cfa731b2,5a4b0675,2052b749,733f6af9,e8dc773a,ee26fd2b,114a7ac2,baca1e9e,51531efe) +,S(d74d38bb,8bd47123,5c118ede,e477ac4d,fd39b635,d0fbeb28,30843753,ade3b38e,f3e505b6,f17a2839,7a985084,31ba6de2,1ec0a0fd,3936dc32,5d66bb37,7cb54451) +,S(f4287675,7780785c,d14dc1be,fe075d1d,4d4f0b33,b0ce9db2,49595b14,f6beb2a8,a3df2231,eefc62dd,c658bf6d,a361ad6f,950f34d5,3ff25536,4eb1e1d8,60514b38) +,S(e91d576b,da19ad62,76bcaaa8,69cb2099,e6277688,3ca1d454,50dc9401,46378e94,b57e2038,c8da2cb9,9ac313db,83265d8c,20e7918,37e75db8,7acca971,3840779c) +,S(269944e8,7d77e176,3791b53d,af2aaa43,e035e1dd,f3c7daec,7e830cfe,38c66ea2,cb011764,34bdc7fb,528ca43,9b323c9,56764145,7b7eeea7,39ace76c,193707f6) +,S(ed41e68a,8f0b3681,1aa61c68,57bb1765,fb099317,2ff6ea5e,e94e01fb,644a3d1,f2cc907b,880cbe04,26ba1e44,83d95800,71c918e0,8cc085dc,1dd0deb8,c508231c) +,S(6947664a,96cfcba5,e2e36e4f,53a33d69,538192f1,3322113a,b0b79642,dfec0de,6481d1bc,5b65b6fb,a91b76c4,d6ade333,25610195,decf5dc7,7f95dc2f,a38fb6cd) +,S(aa3e187c,e22b63df,6a80a42b,ba9265b0,4379012c,70e8ef66,8ea85c57,1e27fb03,a638dd6b,98109fd1,96ffcab7,3010543,e8732f48,e5cdb29c,38fa91ff,8d011be) +,S(5de4e1,a4bef94d,b4a9fbab,6543fd6e,bfd5ea37,9124e1c5,eff9be18,f84a944b,21c4a282,693be294,b699513,f7744761,58f8aed1,a7ec7442,9679ba9e,7957e2d6) +,S(6533dcc7,2c87b477,81c96c79,3af0af22,fdd18fee,a33a30a0,9646c2b4,287a7ce5,7f03e5f2,3d82f9bb,ce9589fc,23442174,482748cf,a3aeccd3,f8c37058,837ccc51) +,S(139e5f3c,129e584a,bda008ab,85343531,c5109f23,a70b9871,a5ebb00a,64fdf354,497b7e57,41fb8eaf,a53182ee,98352b62,6bf011e4,826ac9de,6190a2f7,773f0a98) +,S(493fe9cc,f7e1e950,83cea991,8d8f2561,3ce57b81,81915f0c,7c779aee,8161f7c3,e69763fd,62fce1d0,454aff6a,6a3bb448,639ab615,8bcc2f40,88cbe4c1,67020cd5) +,S(ed675fdb,d8dd70b8,641ac2fb,4903ca77,900e3c15,766ec8a7,446e6b36,52a064a9,a61bb379,85cef5b4,6e0669b4,b0188ae,23ccffb2,5ce777fd,1f26f313,68416de9) +,S(173670a8,9a769e3a,797c14e3,15393d52,b6d48444,3861cb83,136b0ca9,9a260a4d,4dd43921,c1ba4d2e,95ea1b28,e4908410,d140b3f7,7dd82bc6,d683da27,c7bd4904) +,S(d5a5e3a0,8f87e154,6f11e05a,c106e80,a1da933d,2cca528c,df9e1f09,635d1610,7c6c55e0,daf3c092,8d0a9c6f,2c1ffb0d,aa20df74,20a35167,2552914e,5d175352) +,S(54f5e9a0,4ab321c,692f2e2b,94d6697d,a0a99932,74ee4ebe,4175a338,daf6fa2a,58cf13d1,75fa6e47,34aeb761,4f828dda,58a7d9ca,855ff42b,5cbd66d8,89f2de21) +,S(d6682898,154de995,62e5544a,442622b2,fd9a632d,94445d4c,9e8725bc,7febe6da,98091e3b,9ba3b857,50e02c50,a7971aa3,b2d5045,f760c1eb,d1371dc6,3190f206) +,S(253019b9,2af2c4c4,8d9f6e1a,82decd36,610becff,18c908ca,fef49bf6,cdc2da08,617d335a,d9509d74,e5eebdce,810872e2,3ffbdd3b,da53aa5a,495b86ba,397c680a) +,S(56f64ca,461bebde,560d2bcf,ac08f292,ced72574,50e44f16,bab67cd5,104da6cb,5b2085cf,dc278328,a992bca8,f2ee8142,757cb553,b903a3ee,bd83bf3d,593aee44) +,S(f39c9571,1e153a9a,f0e5c192,87e3ee38,5a31a1e9,bef312f6,4dded245,8f553420,4cc94ac1,1c206b9f,7879df90,8498c132,e742ef62,48bdfa97,4b882930,e3b0b1cc) +,S(437eaa8,cbdf873c,32d3dad,95c5aae5,b2f3034a,5de0c536,8c8ddd62,c13128b5,27d8ea0e,b00310bb,59424599,3d60da59,2f8d1b2d,df0c1fcc,721e3080,993c59c6) +,S(ade1a589,3f5d6798,4490ae62,11c57534,3f13e7a6,14ef71f,a79eb4b,a880e9b2,bd49c17c,537e6a3b,ac7404d8,c3c1b429,e801882b,7f241304,9022e262,3791c715) +,S(936275d5,c3091a5a,b9f57d97,7a4e1b6c,a87ef978,c7ad198f,d16e2d93,3ac1224e,6852690a,d8bd84c5,eab75d96,c6e224d0,ed598851,b17b857e,5aa01207,df6b9f32) +,S(29e55fd,3e8fd5cd,e046db20,5c80b9d3,e294971d,76b5e8c,c33fb5a7,6b9b786e,769e57a,7eb934b9,4578312f,720ce44,2bbf3e2a,d61a6f57,af6cde49,8c010a0d) +,S(df8362a7,350185ff,198b5275,45e16f78,3ae37804,7647c584,168b159b,809051ef,afcb3446,fbd4a3bd,e826b604,84b16c3b,735ece80,ee48da26,3a6cae0b,62af6bab) +,S(5f443123,9a35fe0,f9566037,96cc619d,b9a01e83,96cf433c,25415ece,58a427e,385c2812,fc0aabc5,29272b60,56aa9c17,37d81c72,48fafc90,6fd7d4c2,b0901ac0) +,S(c19c4215,53c6037c,525b77a3,1693fc4c,8c5323ff,5d3dd63f,4b7e3448,15dd2de5,9f76ea8a,879177e1,27116189,6d9e6b20,a19d2255,92c99822,159c8ec1,a93900a4) +,S(8abf3a1d,d1e02332,ead62fdb,36394246,14d19d92,a82113f1,d62a1423,af2d45ac,325a967f,dcf5ec3f,75e7a984,ecc2d9f2,defc2941,6dd507ec,7de1b598,a7e36dde) +,S(c8bfdf90,b93161e6,c4d4a58f,a71ea84a,57c1dd76,c0607b94,33fa3cdd,f759ae7a,23dc38a3,d172fb63,ed47efd3,c3e5aa3c,fd7990cf,1535ce5,b51944f3,270b20f9) +,S(976666c,35c55997,a759e7ab,85f90d7a,a26ccc40,5b77b8b4,43c7e86e,2d2c78d,6d342c3e,44facf25,bf2db2e4,e20cceef,92c52cfe,b4370f89,60551614,381ed0ff) +,S(e7790ba7,7737e4e1,c7bb8e8a,5bd89c3a,1fd65b6c,feb2273a,1c12a8cd,f963252b,2635e20,1534b58f,70e754ea,db28998d,f7138ff2,a9e92e1a,810259dc,ffbdba42) +,S(42cb817f,6bfcec83,f60e3ecd,5b986ac3,b471cec9,975f3efe,37577d81,4576fb0d,ed35e128,b2f9bd90,f2162050,a5737909,144a8596,5075fcce,2708a4de,c45cf49a) +,S(a0886870,1a239333,ffc60397,ae11f145,31902428,a4fd58f0,2450e0f,412f3cbb,c8486f37,1ad6e034,8e51995,b4887ebb,fc6002c9,9cc00ad6,d8a81f99,1883af52) +,S(a40cca41,9f101b8b,40fd8e8,b364a52e,e6a9642c,22661aab,3486f25,732c4bb3,f421b69,3ec096f0,2d1e611d,f0701cc3,b0655b9b,95009285,babb150a,9445a910) +,S(90aef978,bbb0472c,5a75b70b,c9f5755e,c532940f,141a350f,efe604a4,35beb721,f9f05c70,737cf6e4,ca88cde9,2e478ea5,93f58510,9479d187,a5f87e11,e14bbf0d) +,S(ffc23a81,a0f61f39,600292f6,8db9acb6,d73ae433,bb827f1a,7bc6997,ac3407c3,b76a0612,bce5e139,277c7463,d47cce0,4f313b37,a0746803,6865f284,574d4b66) +,S(d3ca7b94,40bdf990,4262bc16,298425a6,742c852e,df99ded,2ab0ff50,20a112a5,9daecbac,ca7e825c,4f44281f,9813ce2c,5ef191b7,341fa2cb,1f9780ff,de4d637a) +,S(2a53a2bb,720ab31c,2a6b7589,ce0e1ac7,469b21ac,d55eeb41,b23b3cca,51bb9f06,11aff933,ffde9646,7a4d0f52,220d06ec,27f7810d,ba44b256,c21a57e3,d451f84e) +,S(487e5356,80c40287,a6fd2f77,bb8f5cbf,22b2fc71,7fb7487d,5a08474,ada1ac96,53bd7fd5,46070d63,77b65326,d5130445,29c9625,520c3a73,1e990d0d,5aa849c8) +,S(3e5a5fcf,291da0c1,fc332cfd,62f4b629,cf23c0b4,8209fa29,63de5b99,667b3e16,86987f2c,43389a1f,4b028df,773bb130,8b33d7ef,7f55dc97,b060ded0,fab86825) +,S(4f90afc5,15a847c2,2c42493d,22dd5704,601840fb,57086b8e,d5f7d779,e3e256f,46e31958,ac2e6892,335f6b08,9ac0d3c2,4ef93994,2b585e33,226ded0f,aab831be) +,S(be07392b,40be3ea7,a6a73807,121be982,c2ff4b38,a4585a17,82c585c1,e23601fc,3a158457,657c9e8e,7bd775b8,1dbe2109,43172771,e66ec38d,a57a8216,f1f258db) +,S(86c274e5,2140375f,222f9e6d,47c24e06,ecc2f741,51b5a603,e0563412,fa1108ed,4a02fab9,4065d590,32eb90b6,4c98987d,2703f276,f92c03a2,aa009692,40a96ef8) +,S(4fd3a6b,e7923898,127b3056,1dac13fe,287277aa,21127626,2678e04f,3573cf97,6498a1a1,63cfecb6,c6cf4b4b,43bc7e96,f07ebea2,3b4380d2,38c0342d,f11173e4) +,S(cfa435ca,5423bdd7,8aafe78d,1fccfd07,cd2a5f86,ba81918c,b68c7695,dd117c94,bf4c891c,2dff79e,35b77854,66845389,c399b53b,4a9f4cef,d7d68357,10ce1fe8) +,S(aa5acb1b,79533cc5,9b29e927,77469afd,414119e6,1f3c90c1,cdf93e2c,3e1d446c,b0df29b7,8713c001,fb6d3854,e183767e,8b11bf10,9c75dbc2,6bb408f4,22a498ab) +,S(1b93c2ec,c21bf558,ddbfa1c4,41bca52f,435c09f5,4d06d175,6353e0a1,545c3d15,56c455ff,718190e6,5ace8a5f,d5c6d263,f72e67b1,a20dcc4a,eb53fb4a,33195ed2) +,S(1744cbf0,2566d20b,f639438b,55f72b0d,c8480092,246410ac,d8551498,2fb91760,7e77a7a2,32b0b5c5,9d1d5da5,7a7d2570,68dc0f8,4bda1f6c,683f5229,df4c66f5) +,S(a0be98a5,ed448c02,8c2f8ffc,607b316,1b9cb9a7,a2291bed,d24a8407,ff02582b,e7cc2c6a,2393525,b4d44462,cf6ac8f,76b86981,ddd369a2,274c1971,11da6ea) +,S(e0e593f5,dab5f7a9,562b2591,d8d75ea3,8b2f2b19,cdc8fe71,14891006,7b845882,9088c762,15e35db5,b3bc2614,1a42ce2c,b5464dc6,49f469c7,e785f5c2,cad67334) +,S(7824d895,a4982eab,d6f1b928,de7b0d65,ffe5796c,5e492b40,8b9fc879,c29290f5,ae175c68,8e428528,38a2d8bb,fc232c60,d6bcf117,57cdad44,8a4af01a,bcc7ee88) +,S(49d2e57e,e0b611dc,214e4a2c,d019ae2d,2aa51393,e976cb5c,4211cf10,f9d96e66,ffa0c4ca,88011f72,779b7919,829bb9fb,11c81e4f,a78154d2,5cfa3cb2,bd5b770a) +,S(da605f6b,8f701a85,86012e8f,83898aea,eeb3de32,e9c7bee8,be2139cf,c75ead00,5ba0c12c,e98a1c1a,89f0ca5e,a93f50fa,5a24307c,6751f633,d699e5ce,9411d246) +,S(aeeaabeb,cde94e6d,5a1de2bd,1d9c380a,9307be3c,1c32e785,652ffd9c,bac16ff2,30094755,8510ecde,500a52b,f107093f,b62e491a,c2596460,6641abaf,d50bf840) +,S(62f1892b,35f3fe64,b1ad1e1f,4305f9e8,66ca0a0b,e5cb778c,b0e1feb1,a10c40b7,1a44205e,e600bf4a,2e287f09,c5bedbf,f1f89052,2d14a883,8e1813a7,3f5780d) +,S(c2091ec5,46772d69,28ebe9f5,50a68083,3a567b33,dae25e94,4ac4d589,96979382,599a765b,d2e89d31,735fa722,a1fe1946,eb610c69,2d5a82b2,3828502d,cad4b31e) +,S(bfd7c15b,19519235,700e1b23,79fe7c22,e50a2455,5f83dba5,97d00fdf,1b242367,ac6de7de,545ec735,ea127213,fafd287,f4cddac4,8d6fe694,372bd46,bc66b17b) +,S(d4d4e784,3cabfdf7,903d8507,3831da81,9581629f,74f3cfd1,16b5f635,132ddc7f,1e49611d,582cbacb,fce65a28,44755cb1,d1cd6d4e,2b8f082d,219742d4,61758a6) +,S(1e575009,c378b34d,f3b434a4,95dd8c31,4945b4f8,df617d02,cddc11c8,8f908fdc,5ce37fa2,810c95a1,2697458c,b8f209cc,10bf2123,3ffa8565,5bd8587f,cf6cdb7) +,S(b5a66a2e,ac237eb8,a1f5e690,ffdf65e5,c9268c6d,37104ee1,108f95c3,b9408fd0,99005ac0,aaa4f6ea,60842ba8,68668c6f,f8cc3280,307630de,3c43ef28,cbf72798) +,S(1da39d35,2599593c,66c90b06,3baeaf8d,66bc3a30,21e3f6e6,cfc3ee6,7f26fe0d,9272a05e,b6b0151b,5470d076,c01c3000,f7e58aa7,8fc7fe48,9f285b85,c941311f) +,S(7f3b10b6,b10000a7,652862d7,21f428fe,4e900c5a,f3844500,2b374434,b5a971b2,b94a2fe0,7907ee33,113bd4c9,256fa08,8c4a4f74,df3c3a9e,1f5d205c,a2ecd385) +,S(426107c6,61850f9b,f6beb61a,e200c2da,e5dc368a,3f5d18cb,baf84cbd,7a4eb2e0,e1fa7c78,a9e6ed0f,8d713488,bd3afea4,857cece,8e8e54f5,40f8c70c,67e511af) +,S(555e2656,708fc4c4,312093c2,1489cfa9,d6c94099,680f53e2,fa374a43,45be9697,f5efb7,1e3bb76a,22566e06,c674ba11,a7822422,c6f44cb0,2f2e2be,284db6e7) +,S(7170b17b,5736e07c,262a927e,725b709d,3360625,4642a8b3,af8fdb12,917dd290,ef437ea3,f8998813,b5ad86e6,9a77ce0b,98b2c6a6,b6df5608,627ae735,30973b1) +,S(1ca8ab3e,66fefd13,49e329d0,72a44f1,eb4de646,c8930172,aaaec311,5a5c2180,6fc641c9,2a87d776,81dda2a0,f4984ed2,c70103a1,5531b274,fd20efa6,3b0a3c49) +,S(8352546a,f6d42e82,bf150c1e,41c1a72b,85f057d3,487b4797,7d5e4f8d,c05366b8,76be5ab2,7ca25b12,a888d7e7,21c2b1c9,ac92b0e6,ea0c484b,1383a835,86c5fdb1) +,S(2f112f7b,1730b9d5,63f988ea,765c48ef,353123a1,4d92e44c,3e988459,9c904cd7,eb348e97,f6487d5a,32f70b16,d2ad1740,27d7a8bd,41a031bb,743a6825,2e34a44f) +,S(e84023c,164dc6c7,1d72494a,d410a5e4,2eb6fd09,16a70f1d,5192508f,3ea5648a,634f3585,29be0328,89b2f510,622816bd,225aa031,ab145b8a,48a6fc80,1ef4462d) +,S(951c4d17,45daf527,b803929,114d57f4,4da40342,31c669af,d6e40127,8e28fc6b,f9083b11,a8b30fbb,2c696f60,8ae82627,b9592ef1,c72fc921,bb2ae4ad,5a27f0a7) +,S(adaa9457,f60b9f3e,e0a5548c,51f945b9,78845841,51ae87fd,689b892f,8ccb19f4,834657f9,2145fefb,8df9b047,55674997,f899b951,40ce5830,2e468588,1761caa6) +,S(649296b3,9800a3b,516ef3d8,52d7fba4,597f3e35,1d303397,7495fdee,619e6ef7,44ce9c90,10215167,fdc5f078,e2edfebc,5c8b441d,d88cf853,5c78533e,d61df105) +,S(2c1d7e97,908575bf,38afe2ba,7875f1d6,9f1e9db6,b11f92ce,4bc94d3f,6006266f,9eb250bc,30abd08,bbbb4e4b,bc09cb03,8c6c8ec1,fd1a6ff5,ba23726,da2cf7f) +,S(b130ff8b,ed4ebc32,78293b10,52fa197,b44adaa7,d1bbd74f,f6d56f9,744647ec,4a0a45e9,b785c7f6,76fd0a95,66e4228,136f60b,dcc1806,212590ff,eea5eb33) +,S(4f2a5997,62ecb2d9,31ae9c74,ccd71cc,29bf684a,d68f0117,32a0cd50,cb0e6231,debf8db4,5cfc7083,fa700dde,7309edc0,fc44216,cf7bc237,377c0bf5,7ccf17de) +,S(97f9e9a1,7fbe6e25,e41419a1,8a5a24da,a178c0b,a99e30d1,cab0d2de,7a23c0b,1ab1226b,cceb480,fb4fdc8,70fb5386,6cb622bb,e71d3c0a,4ddda232,57559128) +,S(e17f3fe5,e9f5d17e,40182067,3b710940,bfd486f1,ad3ef4c,bb93b47d,9d9d8cb,f1126a52,615d3a8a,6b360b26,305124af,44ad7d62,e03ed96b,59c2903b,b5272f58) +,S(1a39f846,7d638182,900c3e94,538a0fe3,3ae66853,aac36688,7a5a8bb6,7b2fa2de,ae7c1399,5a625a4e,42b4dc01,9d7c7501,18492f3f,bb4567bf,28ddef5b,82903aa5) +,S(8a5ddc61,27f6fa44,90a93e52,f4faffb8,baa60581,5142be68,cd18692e,b42f5320,5eb62325,853dddf1,a42559eb,bd5dfcc0,328e69a5,fc787389,74c80d1a,896b0d8e) +,S(117dbfb5,74b7d6fc,d47dc17d,56f5b5da,b864906f,f08d190f,7afe1f9c,fe38c299,4acd2151,30b7144e,437bc923,302640a8,c504712f,6b903b26,bd5db8dd,5d90196b) +,S(b0c31228,431c7eb5,7310706d,950a2a60,eec84ec7,418199f3,f2985a39,8a70a537,a7de9b34,792876ff,e98c3237,260d8237,85e47c,438fe419,a1048b00,b064ff78) +,S(7c210cb9,f493275a,e17e6d5b,517606be,736cbc86,5a5897e0,8d1d1f03,f243946f,17b07523,a8bd185c,ea4a92d8,7af1f1dc,920a7fac,30faedb1,c38e3529,1759c63a) +,S(172e5167,578bed44,6397b519,2b0eca17,177b14b2,f4570aa1,38771610,6ed6e650,9c15752e,4776b805,d63de803,83c73ad3,9d3ba817,c1f88cee,1737cd85,33830ba7) +,S(161afc40,df25fda1,3637317,3dad8046,c95a6ef3,aa9c19ca,47e9ce2a,20030686,5e6fd083,c1265f76,b4b9c819,3a45e0e8,9926f160,b6257759,ab90d6f0,126089ce) +,S(b991f2a8,e18aed33,4d769cf8,b6e39144,2d194e90,ee1518d9,459d3ec3,8a16a85f,1d2ba9a6,b89f71c8,ea169d3e,923d2c1,7e6e590e,21b28e8b,1a0d0cd6,1bcab7b0) +,S(dae0689f,5a6cee77,f796f488,1fb3647c,7d623348,7d5ab502,6f1ca30d,44ca8afc,ee67b670,f730bae2,a15e6964,33be5b95,43ccc1b0,314cdfa8,c6cc8873,c39c329c) +,S(47a58ccd,75f89c15,46a17ba1,4629fb5b,d72805a4,16a12e61,aeafd8ec,8a7e4e41,c15e7fed,1bbb810e,b4be60bb,61fc1f0a,a4bc43b9,73d94767,9b954f3c,29fdd889) +,S(f7ae2fd0,2e3b6ee3,30c0697c,94ef65b6,d7582f69,5c509698,cef09b44,6b040e3c,ade9f8aa,c527139b,c54d8e6d,ddd41ac9,5eb49565,79934ea3,6a9dd8ad,d419ca03) +,S(155f9ea8,9be2ae20,8d7e9c21,4c244a58,ae61cf24,5d5f8dc8,b6c448d9,7c12989d,1204f5f3,840cd19a,fda04abe,6cbf4490,cf5ea60f,4cd17680,8c1ce9d3,65b009ff) +,S(a83cc9c3,933b5f14,fa5348a0,e0d3ee39,e35057b9,13c5a51,89a61663,1e9d74f6,40aa66d7,fad68476,1e2a9c78,e1fbe478,52b91d11,a283e1db,e30d4baf,f072a74a) +,S(ca4951cf,c07b5c23,298a20e0,fa44b554,d7acefbd,bf2a6cce,11fc3ea5,67b5f5df,186a8bd7,6700cafa,c79791a6,b28c799a,35aac545,78586050,b8012c4f,9f4afc2) +,S(cf92dde6,1bad101f,5e71f2a0,dbc2438d,d6760ba5,b84791a9,ae0ce712,9eb6787c,a7d351b7,f3e31e6b,cbcc1f05,329458e2,6c9d8a9d,1137d595,28f53e23,5c3bcbd8) +,S(b1ab0b3e,cfd8283a,3b79df9b,e83e8b37,b06154a9,6e2a687d,8f51985,129c1179,cdb7f2f3,4bab534a,41f4cd97,b812900c,99e97395,3837f058,12d5d0d6,e9506bbf) +,S(a1743329,9cd4c9e8,4fb99295,f3febad9,197296a2,98b30354,24e9524a,e1789ce,40994ef4,4cf53577,6f078088,adcfa6d7,5bee11a4,4f2f3fc4,4282f5d7,f77e1afe) +,S(241b486,4efcac7c,3c7b946a,61a55317,38b31846,607f1e0b,d0a1a2b,d9c0573b,5cce8848,eec61cd3,325f3ba8,fbca403c,2f980159,bad3997c,832f5c98,1fa0d574) +,S(81f88209,64997984,699559ad,f799ab0b,e3efd354,d258137e,d753e3e4,de91b387,8f9fedb8,5bfd7061,1b9e5caa,5f3cc8da,43bda599,afa29967,a32c71e6,aa26d15c) +,S(49d64231,bd2c2145,200793d6,4a2ec254,c22da96b,655706fe,8fbf5d49,464e5a5b,faec8eda,b0d72cad,81df8121,671c6dd9,bf986440,3f1a702b,548d4333,c751e825) +,S(74c14c32,4fad3a41,1c7e1f15,9b740980,6daea24d,9476e938,7e77db6d,66e0ae4,af795203,1fbee5cb,f031a2cb,946e6b65,3ee0165d,abdb89fd,5aa73880,e0641a41) +,S(88bc209c,7342d94c,be3f4215,81383c6c,930f9c19,d09d91b2,a984b6d7,12a1e7c3,acb7d745,76dd8723,89a88866,e287610d,b817ebe6,1581aa23,46ac994c,4c5b3e08) +,S(486c8c68,c81ca88c,df7b93c8,5a1525f4,9bee242,676aae77,c1bd85ce,2a6eb3f8,e0fec94b,35fa97c,d5e64870,6f5e6849,d6249004,fb33e34e,c1add26f,4fe52d54) +,S(4a1efa11,6c588e23,7b5e30fb,5d0ddf37,ba39043d,6e5faf14,e28ceb90,4a681a3,bb196737,3c907165,a8937dd3,1bce476f,65f2acc1,41bd8d53,8fcfbf1a,997b64f4) +,S(d7745c06,c69609ed,db17f30,8efe7bb4,2632e85b,7f7f792f,8da44294,78eb28d2,7575a75,4d1b2bd5,5fc46e11,b1addb1a,5371f007,f702a97c,ad13f082,39b96a73) +,S(bd752f2e,a3db27c6,a6a08ced,df74a87c,dc333d50,fd9995f4,9ca7afa4,2be68def,378f8aaf,67478d20,ba4725ed,26d50c62,ef5c576d,da9c24d7,91dec38b,a5e9491a) +,S(ef588333,15a3c7eb,c6602bff,ace00d5c,55eb304c,7f3301f9,4be457b0,1f224d21,56eb3aab,6253dfbe,3d9a95f7,e843751d,eb52e054,cb5a523f,f46a0c12,b517abd) +,S(2c1de374,7355825d,a09beea4,f42df241,6b495ce,7edf1f1f,c1dc6043,5253727a,98593660,9082f5d8,8f9986bd,f77672a8,5ff92cd0,28d2c588,73a3b1d3,87a150c2) +,S(49f8d71b,23e60140,f50c9001,6f39b2e8,b78e2a22,a88f2535,324ff50f,280daf99,f66bb665,4807e7dc,330ec339,3f6fde20,308111c8,1fe42546,22b93a86,b58b04ec) +,S(365c9f85,754b61ca,2b2a30f9,954f3a52,d18fdf78,db593ceb,6df617ab,189f37be,c43fefe6,aca56bcb,ffa6aced,60a32794,7681b601,22369a3a,f1405a41,5132825e) +,S(1cf2cfe9,e89668ed,c1a446c4,da311cf2,7e2cb53e,1984a310,8e24e8bf,21f1b5af,71e56dac,43c53094,7b78f104,1a685f23,aebc7b12,e2caf803,6731ef5a,20c966b7) +,S(f3303479,62660226,f391c26f,a7e87796,219694f8,e01cbd52,25dce636,b48ca3ec,7dea0bf4,c110e945,dbb59ab8,74f83a42,afa585c8,56a93002,6f48f8fa,62762827) +,S(b689244c,4bc16c88,398664f9,2297ea0,8756a969,1ae7adf0,587c3253,e4b27154,9b488748,1357368c,c97f89a9,b4a75a0,bd7483ae,5c700364,c27d19a8,e450c856) +,S(bf34fcd2,d6b4371c,fef2f874,5e4be021,a78b4302,240d4517,f3eb1140,638cbe41,ce6888d2,7e326eae,8e772914,e1b43bc0,1ef6a238,27f67546,5464e195,5f97ac02) +,S(c2097a6d,231bc796,ce85a594,44c00250,d51ffe63,c45b9cd1,10ed4821,118d74fe,58b06413,fc4ac173,e1e3a85a,ca674885,d1f92b3e,5b99f72b,1350b6a0,bfe4ac87) +,S(874a6222,3d8804f3,a11b1de,3c647aea,e3e81798,40db2618,4d46a330,417afa81,4132a5f6,7986e622,976b181d,5c98f356,b31668e0,ef70f8f,6b13a0ed,af80b429) +,S(ac7c6e8a,1a05d592,8142227a,b0c3ed46,1f28463c,ccaa3b85,b9784e0a,f5bc605c,1a59a195,581e3397,eba60a0a,963f5c71,c107a9db,68794da4,a08b14b3,118a2186) +,S(3f13e2d8,d825a3f6,8875c01,a1715a5f,44bc12b8,2f254a65,575b163a,3333342c,baff6882,fb2c2611,ffef76a6,8b5e2293,6a2e6ecf,d7ba6724,3393fa1c,5825e3b7) +,S(1ebeb354,515e7f39,dc3e2631,51d0630d,aa7e400f,4c9f7cec,4d5f95ec,bfa8fe2d,a2e35cef,c2cdcf,384a2473,c185f3a4,c70724b9,84c72dac,a6ca11f7,ae5c85cf) +,S(c2dcdb65,b211e765,e6c59218,d12b45d8,b47d8f9c,e22b99a0,d2d19a1d,de02b2ab,e0aa5b9c,a960117a,7289326e,9259f886,8722e032,c96b5237,b146f50e,24f3be50) +,S(495d69f7,e2a9d144,8e2ed8a9,c038f6c6,7f360b8,270c9b85,841e8791,64bc0d45,5fb3fe2a,1dabce7b,83b4465d,74fac6f7,c48584be,134283e7,bdf59e0,957088d2) +,S(ceac4569,2139e4f9,701be43d,8da3f515,270a9477,bad5969d,2037ac87,3453bab2,bd1fd9d8,15f4e872,b602f2bd,9604b6b2,f385ea40,d5520b3b,ca32c160,44908070) +,S(7ed1d0b9,3196b8c0,1cd284cb,c0a206af,4e6dba1a,d6cd406,82f55897,9407e0d,e95a3ac9,6ba60be6,22f4ee73,2d75a9c5,11018ec0,d840ce0a,f1bca18a,1d2801c5) +,S(72fb366,4f42cec8,940fd436,5ba7cc97,ac5fe4b2,131250fb,a24b7178,a1040b04,c182b1a,93a211f5,f5de5c9b,4b52ce90,63d551dc,a21ee9bc,dbba2653,c47dce41) +,S(dd06cd8c,9ca91e45,d6720043,d3e6d857,4690192d,59154309,2160f04,6008beea,cdc17327,6eebea3b,f9fa8a7e,e83ebd81,4189705b,900b3ce2,72b85dc6,c41e7ecd) +,S(80f6129,e90a7f0f,1e650439,8bfedb10,3c708c43,2e2c743,da8a9a99,3978cd13,74d97812,145feff4,a3ef594f,85b644a6,d95a3082,3828c00f,e7226d4f,39deb82a) +,S(56af34da,f56b508a,eee970af,bafb9dd2,b48f83c,4c051b24,f5bc27e7,105995b6,d41dfe52,9e788e19,89105a4c,c219dcd3,decca65a,dcc5f34d,8a3ab0de,d1ae68bf) +,S(820225ba,795565b4,c45e29c,4689d91c,148cf693,a1a1c1f6,ca33c44e,4e3f91ee,3622ae5b,c89b9c2e,66bf5a3,17826928,11a0f4f1,4b387334,b24028be,ba4b7db4) +,S(7925fdbf,cfcc202a,895a1b7c,a8c7f09f,ad388db1,5652b703,3bf232be,a2ea57d2,46f7ef01,c9cb7dc9,1559cf5e,c6d3f5f2,1ebcc21c,a8414d0a,9dc37309,4e90525c) +,S(4b224b6a,f38ae731,5b316eb,8dbd2b1e,6638794a,9bff79f6,1027f60d,5d81808,3143ea08,b1633002,bbb2ad2e,11ffe5b4,b6dc6888,1fc669d4,23ff9cb1,595c3dac) +,S(2c0767fa,4135f4eb,602a1a36,e6ce488e,2c1bdd64,aa4113cd,28daf20c,687380ee,ddc3effc,e78d3061,7cc2da71,1373de0,6a65d2b,1050b89a,5f71be3b,fbc16a7) +,S(83837d3e,e7179a84,ef6ed2d9,41a9f835,37b5a2c2,5d511ef1,982d9bba,50a7ae7c,62201e16,60957b4c,a86f1a49,5a6027b5,fe2294f2,7946c8d8,556024b6,e3b66dbe) +,S(cf075b34,e560f057,53a8e011,835bf1da,25e50d9e,1d70dd9b,da427109,5895387a,c73209d0,330ff4d2,38e19f6f,33df38d7,2b11d8dd,180d6a14,4b07184,a2127018) +,S(d583f8ff,9b1875d1,ef468030,e3ebb7,9d06ba2c,1008329d,cb01b883,7c8931a4,f8cfcf1c,3f092ba,6bfcfcc6,9596b508,aaac7c9c,333ba58c,d55be53c,6fae3292) +,S(551fe9b6,21d2389b,fc185372,342edb1b,27568bb2,da1fe220,3431b792,43eaefaa,6c76904a,e48563cc,c6aff505,7f31119f,ff48e5fe,971223d8,c3badd02,563c24e0) +,S(1bb778fc,74062f24,b0962be7,bce7c990,51f06394,bc8e6da9,a9d63f6e,d16a80b2,2754f53d,2f4ed167,3d2700b6,8ff036fa,60e9352f,1dd7bbdb,14be1740,61d88318) +,S(a150af7,1261582f,8949f1a9,3ff8d539,aa0744c4,e97cfbe6,e4a3fe10,e7e364aa,e22a1afe,a68671c2,f9e12471,56e1bf47,100737ed,5f96fab9,9e0df721,eaea4773) +,S(c94ec3df,727fdf91,d7963a03,8e93d68,835ed2bc,2578780b,7242e15a,e72e2a9e,a476a0e9,7bda53c5,46312b35,f0fad09e,11b2810,b3f570d5,a934d21,7152009c) +,S(3366b9db,ebe13231,7c542739,4235a72a,f186bda1,784c7f25,5f8b65f7,f146875a,5ea2478,95f52889,42321383,5439195e,6b620619,20171862,eea32726,1345d3cf) +,S(616c8e6c,e52265ec,cb85ef36,5092b2bb,58bec6be,444c2373,974c38e5,e0e8ba25,4d3d5543,3d6e258c,d8b286f4,5f41249a,724a9890,2f1ef3ca,ba049bf1,cdaa0970) +,S(74df2177,2e38e84e,8b81d86e,f45dc4a7,2617b3a6,32094b1d,432291f,6a651827,4c32baf,30f09527,fc4abc6f,9c9b9a57,2a9ccf1c,6a1b360c,48746d8c,22e01334) +,S(1814a1bf,76b74532,979966d1,5ef42faa,532f8dd9,bee0cce5,d68fc500,21accbd1,5f5df5ff,da9d439,b2205ad2,5fa93b9b,7af1746e,9b2eef3,154bfbad,acd46bdc) +,S(28911e94,98ff7526,badf2287,8e85fbdb,5f444d66,c422a975,c7476c02,b98625cc,5a341cf3,5cf26006,9d869542,fb221ba6,eac150bb,e3809ada,5e4c903c,1e638537) +,S(d5acff71,e82a455c,3a1ce292,689e8686,f441ce1b,e644e79a,bd6d0efe,29270865,aac6d48f,1b46e970,a044971a,ad13f033,ca8cde96,958d870e,dc7d80,1d26d5e8) +,S(5cf51c1b,2210d85,9d765e17,32109514,8f03fc57,51004b6a,91f098e2,e2711596,1eeb19e0,610df459,2c31e58e,aa2a2148,17fe9ee,a3995838,f395bdcf,26d5c3b3) +#endif +#if WINDOW_G > 14 +,S(21456873,b58e3687,52c75800,8d3bcae,9efaf1f5,c5727842,25e3d854,8fd421cb,a2f2d10,c85e8a0f,4a136ad0,5df991ce,7d3c5585,a263d5cf,da50a4f4,3db76cb0) +,S(c10de5c0,51ae2d73,28ac06ca,cca840b4,ed7ab204,21c6122f,1d68fe7f,7893d38d,ee30e086,a891484,2ad4041,f9ab9c57,cff1a315,f0642d31,b31c2914,faac99e0) +,S(be778032,f12c1b77,9bba3d9e,d290ca90,30ac7050,bdd77a2,7eac09be,eea65c0b,8657348b,a1e27a63,1dd2a54b,e2d5270f,4cca817a,219c5378,4d4f73ba,2c932e63) +,S(a05e7551,f8f090c1,bfc8ffcf,fbf7fd57,9d033163,67d5ee64,b85c4f69,33d0ff6b,8eba561a,f42d43c4,99e1fafd,43b49698,a8f3babc,c9c94c4c,4822cbed,a741b309) +,S(6e4d47f6,b17501b8,f3b220d3,83cf5f11,a395c0a,f0023988,c4e7b8b0,ef66ed23,e01c4330,16e3e6a9,535f1d40,905e9b3f,8be9f05c,b53e6143,e81091f5,4b76b57d) +,S(f626750e,b7eacac1,7cf24afd,43345019,c6c32292,c72503ad,d4125d40,67b7e66e,d669f903,67f407d4,5307578c,ee91fa01,f030bb9c,b66c7111,34b91757,1c993f4d) +,S(437acc60,c555f7c4,778595af,db4676a2,1fc8b3cf,2c8538f,cecbae12,811511f1,985fd2c0,7385fba8,4cf25a1f,46cd2c3e,de8dd359,1c6d20ac,584b4a8d,8a65dd67) +,S(8d50555c,6245e43c,a619fb76,ce45441e,dc585c7c,4fb2f33e,1c07965e,d4e35f5c,ea828c37,331ad0aa,44d168ce,c328a9f1,c7deaa35,47ee4757,c776fc46,439ea5d2) +,S(87f5f6ae,580ebfe7,1b2c19c8,cfe770ce,cf8d4223,62718914,eb853f1b,7f4cbaec,eb61df09,12e06f58,ed6d85da,7240dd72,aad00c3c,6a3a9c11,1f378664,cf359386) +,S(c1cfcacc,b95e6577,4e2a7d12,3cb0071b,3325c27c,5d58beb6,781a30d,ff6306d3,fa9ba55,cd95e721,12d98a19,8e3769ef,8cebb355,dde5b62e,e6f3b8e8,52a3e81d) +,S(d68bf50c,89f25969,a765af90,854bdb89,d67acdf8,f1e16bff,64868338,8b88e311,b62d1866,55835dcf,8064e13d,aca1e896,2157576,a02e178c,78d27c99,9cce81a9) +,S(b8d7c25b,8c20438e,702197cd,a3bfc05d,c6577717,c9b6a527,15ef84a0,2c0df867,316b527d,4be0e62a,2015f15a,17a412fb,72ebbffd,b02e53ab,6e5e9791,b771b45c) +,S(d98b3403,a299106c,9c6fd52a,8abd9ee5,cea9ab0f,17a15b4,7eafc809,c34e356f,bebcd24a,9300c739,9bb3af8c,12fa813c,78c6838,dbfa00a7,4ab09669,4df9700c) +,S(dcd15a1a,7cccd53e,db08c2b2,c6367126,de55cc46,a4eaf5d3,335ccff2,1238bbdc,7de57d26,bf74764d,bcc7e15b,72ec272c,58061f47,cc0715ec,48bcc032,60e63a81) +,S(2f6a844e,e758e3cc,8f299e01,ba5753a9,d35e6c51,6a87a683,8f5ce28a,fca17c62,5c29172f,f907c0ef,95e78768,2625c8ff,27e26eb2,cd86df92,b9371203,8b332e73) +,S(e63add7a,e511eed6,93f62498,17f89221,c7a3a909,253faef9,23f37a64,9e2a2f67,c392df22,5ffa1438,c3d10c6f,813c3956,4f94367d,6fa26c63,1d562049,99a77e0a) +,S(f9955ec9,20fc68b6,cfcd163f,34bd033f,4ed7dc8c,30da7f16,e41adb,908c9b7b,4dfc49e4,ab583975,90bdfae8,56ce97af,91c92f60,a17df9fe,9ee923b9,9fe2cf14) +,S(d974d713,bce1db76,c5ea1143,b63ace02,5a2362ae,fe6b84b0,ebb0c49f,22341d7c,991181fa,3ae5f188,38a94047,9ea9e4dc,e8ff9366,78583189,bc340d2b,40481577) +,S(4f0af691,424d441c,698dfa3e,c3e56bea,e2c52fa3,bfd9ca45,763d7805,33a3037e,caac2486,81590630,b0c67160,89db929d,26a4e15e,b06aa9a5,2e19c92f,a9f9817e) +,S(ef6300a0,70060df2,3f9818c1,6ff4d315,fb1c7d4d,fef41e85,c96760d1,3cea49e7,a0622360,2def9738,d87803e8,6405bc00,88afa82e,39666246,10f5d935,993334fd) +,S(fef30954,1cd2a90e,1d473ae3,699ea7cc,ef69fe75,54f7d710,33b1f23,c9e96886,c2479c48,59423c87,5d76f6b1,5c671ed5,c9489af7,79266341,4ca68675,cab64fec) +,S(457cdf17,b1230409,c3d35a88,390f1bef,859994df,3ba21d2e,ba5f826b,6dcb4fc6,5aff71af,708863df,3074c236,446ddd33,5695c0c1,a45bc482,e0787788,a0e4ede3) +,S(a66e86f,fe0e9cfc,686ab0fa,11b641f4,28499f3,450d69a0,dbce1895,6181ea39,de0cb1e5,ca720556,7c6756ce,868df6b,5174887a,61afd354,653e759d,b3e3ec64) +,S(ddad5a09,c37f0de6,67eab59b,fa2cb47f,b79bf6f5,b8b0403b,f689acfa,627f1014,8aed1b91,c9e567b1,9806082c,79ec433e,1a152279,69df00bd,239fd8f3,f8e8d385) +,S(45c5156b,f1439eaf,16a43b39,5c0a393f,a674e17f,76f96d53,9aa6c99b,49042c42,c9bcc2ed,c5b5c8c4,b17d633c,90d45b9e,1583898e,41bb9d90,1d1b5097,57f5f516) +,S(c83b3c9b,564906dd,60049c3e,9f6ed0fa,b848366c,3b93650b,7923e9ab,8172a8d7,5709dd74,1326ab97,8853304c,a02315f1,1f0bed5e,bffab6f,467816b4,4c60a332) +,S(a857354,dd08dc83,ce7b0324,7594e4c6,99692c95,9a4887e5,344cd0a8,7970174e,becb7001,ddafd72f,1f845579,ca8d56d7,2145c8a9,be816924,957ba324,3c396691) +,S(8bba6b47,88259a19,578adb4b,6f7f51f8,d09eb70,ea790d62,abb2ed45,84f94f33,afa42da3,8526a485,60919f12,d30549e7,1d19608a,81f4cf6e,8e49cb00,2492b143) +,S(bb4d27eb,412e73ca,d2697d6c,46a143ca,e4420ec9,30440025,47aefb71,c99a53d0,9ec07a19,842a1e5c,9cf9f76b,55ad98d1,9485e683,b6b6700b,c905e190,bd9da19) +,S(af6f6827,d197688,f00dd3f5,ded1849c,11fc2abd,f90fc7f2,18b33776,e5753277,f9227693,c9405a2b,10e9b725,aac7ed35,eef4281b,ca04e,bd75b143,89323646) +,S(40453814,445cc67b,e7a4b71a,55e0b993,2b8b3477,f093df6b,f27f55a2,8bad2e1b,ec71d7d5,4e823687,d01d7558,6de9a1a3,7edc927f,e221941f,46051747,a69baab4) +,S(f35a6c29,bd596f0d,93cabc3d,c07b5f68,300f6ab,8ecde5d5,da8299d,112c7bcf,73fe2c46,e1b13112,718526f9,7a39f1f0,3d47ced1,84a2e4cf,1e32c168,1c470121) +,S(ecc7ce7e,bbe5da1a,596bf41c,4d19b51,b77f7019,bc431aba,e5ecea57,b095fa93,1ab89d03,9e7c6ddc,7751c9bc,4eb84ed1,b077cc8e,dc828ffa,37426609,e089c8aa) +,S(559820d6,bb3e47e,f68f48fe,1259da06,cd0b380,1f6bedb7,970c079b,7e373bd9,2373137a,a4d88574,151540cd,ab8cbdbc,5831fb7c,4b901c27,8c9a593,172a64e0) +,S(9c9b7e18,4e76bd16,856addae,9352590e,310d653d,809ec800,415f3c64,149be4a0,182cd167,55eedfc3,21d71199,7543b26b,d08047d7,c9363e23,20bb9516,da37a146) +,S(88e4e3d2,2cc3e6f6,19e62ffa,c7a4aff,63b16733,202e5410,52cedde6,9cda2733,ec6e32aa,498a7a30,e1c47136,5671d356,bf174630,d1b984ec,d9453e24,d275e067) +,S(7f2f8043,8e7d7fcf,593e337,a91b06ad,3ad1c461,fcee7bd5,82df516d,cb1c198f,2cb484f7,5a4472b3,230369f0,79f5e654,8dfdce60,98c4e561,a1310224,13dc1d80) +,S(fe0c5945,c5e67d74,ed498120,dae194cf,33a3fe5b,ef0f1ac,2c64c292,59827d7c,4ebff1a1,7d59c8c,469fad0c,79ef819a,8a897ce4,c0fa1121,741c03f6,cab0f659) +,S(ac0662e0,1be37c28,be457bc9,4af19e72,34a9d3e0,8667c009,ec58ee79,7e539642,b3adc375,bdc81a76,8385c9e7,2ecec61e,9b2b21d2,55f65450,c5956187,837f3767) +,S(15e0f7bc,d74e77a,af933c13,6cdc5b1a,1622de61,251090a8,f8509b05,d7dd527e,4d51a063,1fb81f2,fa1ef534,5fa306c1,a0c64f94,66961cc8,b574b06e,646767ea) +,S(e4119d0f,b79bd8c,e1687abd,4ad63790,814f9972,50fac9a4,f1b52d71,93ce282c,cabde097,8f9a566e,32ab229e,63bdfbd3,89f01378,c7d27b0b,f101cc3b,36bf3fe6) +,S(27a5b030,2005a21,5d89c0b3,4e4ee323,5e94742c,262a89b9,29e286c0,ab8e3c24,4548d58c,3792f7fb,18238cfc,993fdb26,f755379c,e0ed1b0,4df26132,8f987a02) +,S(a18ec59f,7621c8a0,59bcad5a,12d3f536,142d5c94,4c7a54d8,b9206132,d993e08,abd8204e,867035ac,8cde70cc,f7daa29b,d47b888e,1faa9be9,b20744e6,ec5a43a) +,S(9bcc19a6,71b787cb,9da72c91,8d7b2264,b9497ab6,313de85d,c3efbeaa,2f492219,4bea790f,67b8100b,9ad9a301,61e3bd9e,583daec8,b77f4628,568ed554,70894bbc) +,S(7ccb2731,cc3eb3a3,36d36af7,f44a0a64,e23aa0b1,12ba0e6a,11280c5e,1ab36205,8d60552,1813ede4,dcfcbe46,c75c5aef,7ec40c69,99cf301b,28b0e875,3031c6af) +,S(94107245,fa13427a,7d21f7c7,cfe0c4e3,2943821f,da0f77b4,23fde091,ba596939,89846c62,7868b1c7,4c546492,dd4821d0,cfe15fae,36896af4,547deea9,295ccf84) +,S(959bf7d3,989d3460,5f4b8f3c,cd12ed86,cd0a2a93,a8d4e1fa,aeb5d6bf,24f1115d,7cc703f3,5417d7b2,b7229626,558be68c,66a915fd,7cc52829,dc98c81e,c0162b7f) +,S(8e92173,ff2de4bd,f468e2cb,fbf6264c,5fff8f23,2fb57e1d,2a07ee75,3b45e7ac,2655133c,8833040e,4ef4c98c,e5c75818,be781f42,cc0b7314,7baa3ef7,99cc017d) +,S(4acbd2e6,98f349cc,42998c5c,53de7b6,3dc29b1,c2b8a569,48cd3489,190f0255,8837f8d4,15b3551,4544878e,1a71922a,ba4a0790,22c74b60,325c6f49,a411b978) +,S(f79cfd2e,b63f6be3,bf0f12d1,fea3524b,1188959a,425f5e38,fa569648,df433fce,9e412cf1,698805e2,a92114de,5694a925,17c31f49,ddca7e0d,b2d83d80,74d92b2b) +,S(41910c81,78f7a61d,7957c065,5d7e2596,a0e6d5e9,a0a9cf23,28f23569,5d818c76,26b318c7,e8a880ec,94c59a6b,d6f1cad,84031d0,e62ded95,1e265ba8,c3603367) +,S(5a864466,9fd276ac,ad8782d3,51bc27b4,9445835b,75f70a80,2ef42a0b,4885cfe3,b2510d98,60be4e66,edb8c935,3c8ff8d,2e008c37,6dd271b0,1f77276b,f3a5a48b) +,S(5e3974b8,1b87348e,e3ae5c83,2dc56d1,85004b16,90445b74,1b8e262b,ecfe0e01,63f644bc,397a1809,a4d57ba8,f18f0372,cd4fd083,1c3d3449,1ef2a654,46275568) +,S(154e9c88,589ff342,6fe2eb5e,dd6e1db,e253498b,2c0b3e0,52e84211,caf9cc4e,3a897093,df7d31c3,754f84c2,68b0594e,85cfd4a7,c2731fce,e01cc3bc,2bbc383e) +,S(b95aa134,e48967f1,bd3a7a48,d89d550e,3c3c3c6b,3c73de48,f2e6fba1,81c93faa,b6f2d3b8,8d0821b0,6b1134d7,ddc898fc,e84898fc,4719f8aa,e3570daf,168b03e8) +,S(316564c4,ff00502c,f159db79,62984516,4d6d24c9,1f20ba73,66669808,95e58b92,6110a6d5,39ddc,d4185b72,cc576b7d,a4577e80,3dd47a92,d4bf346d,ec5905f5) +,S(222b179c,29ff89ee,d6f2a0d2,d38c6246,33237c5f,7803d8c5,e4315f93,6a9bd225,8bddc333,6eeb3cee,a0c3ac01,e7caf4f2,f44a50f2,587e3e31,7046c85b,a57cb6f4) +,S(10347fab,33fb4ee5,6cbf75ac,6cb768dd,f51f9b0c,5498466a,6679439a,32048904,a351f45e,30f32caf,e10d99f6,9e9e4be,c3f4aa22,5388984,bc45bb78,c0c5148e) +,S(7048c0f3,1e600042,4544e9f6,e26783d7,baeb411b,a2c29c7a,5aed8953,bf831629,4683ad69,1d9f14a3,f67131bc,55d28c61,1b78b2aa,329668fa,8fc41736,c95840f7) +,S(a65f7371,b35de05a,78b71171,40ea9e02,7b777785,13fdcc3b,484ad9a0,4bcfa1a3,41d1268a,77b31744,5a270f73,956bbcfa,3f291770,d248d1e3,364b4aba,72b961c6) +,S(dfa35552,8518d1da,ee31f04a,2673d053,11db4eee,cdc81f15,bce79c64,3267a315,19ed047b,4fa52430,18863cd1,d8ade0d7,dad60ecf,10b767ab,52f5cef5,9eea9a8a) +,S(663ec2a0,80564f1f,943a25b7,2f60d3a4,17b62130,3015e17c,85782460,c601a48d,fce25852,5a4dbb52,4057f8fb,a4393116,ebcffea5,5ae3459d,3d8b19b6,a0387232) +,S(cc714eaf,26f9960a,b2cb139b,d2fa0928,7a309c9b,ea852537,e10b6333,2912431a,c1c5c0c,48c98ea9,b57eb13c,fa64146e,67a95569,b45b8643,7752b037,9269d070) +,S(a6ceed6a,bb8f1ac6,13799527,38a19b35,ece44537,e74e9185,a4ce3939,c14f8e77,c0090ebe,d410f2e0,2e56b4b6,adfd5495,488c2930,2c5e7a61,3926880a,88beedae) +,S(e0b0c34c,8d4f77f1,dd09ea34,8b0ec683,cb5ca777,6720546e,27ffcf55,a5e5bded,ed4adb20,ab5da65c,2d1d5d68,9ad63ebd,90170904,65f7ad03,1bf3d811,f407d09f) +,S(2362ff0b,9a2d0f7f,d779a83,8b26da93,65730d32,bc4411ef,fc4fd182,d9e486a6,d3eb4ee4,42bd6157,557e4e9a,dcc9c103,892ca05f,5c5af804,f736ecee,d8a6fc3e) +,S(2f1636ab,a1516634,a00a464b,aa30c507,af25e83,3f7f6fdd,ccf0706e,d5fb57a0,a664c955,c24a54ee,d56f1aaf,fc853c2f,6a81c53f,1ee36c48,46b26452,fcbcc054) +,S(243a8fff,6230829c,73368eed,fb4d62f5,bf478b4f,1752400a,91ac177f,70c303ac,29318b21,9f371dfe,4048c4b1,2f5317cc,b2e9c44f,ed72b537,a2f56d06,65229235) +,S(b17182a8,5f442a65,839230ca,5cc8f67e,835e54b,e0296c6d,e2b62298,74ae804e,11a4fbcb,9f6f8775,9d131a81,939e0125,7f7b4fca,e36ea644,4da3cc16,a161e5aa) +,S(5c9abfd1,9cae1a47,bebdd324,d11cf758,a1224471,6e83795,e42ff5f5,a8142a6f,38a38db6,f64d9d07,4a08a909,28768bdd,adbdd858,79ec847d,28c94dd3,a122e0d) +,S(44a8a4f2,ec3dd02c,226ae0af,d73a12b9,726e03c3,2a41099e,b70cdce2,767e390c,b7e18dd1,e6adcd88,1d1dbead,e1c83ed0,1f1d7b2e,50246539,b6bc2811,d63233b7) +,S(8e477766,c4de01c2,5cc17218,7f3cb6f0,dbc8eb54,fa888911,33131b7c,219e6e13,ba8f447f,10286c86,d1330c82,2647a999,b4b60e56,4131986,a6c05128,a480d83) +,S(c5f862ce,dd253879,8100eea2,92e860fa,321d7709,596a4dfd,6faf6345,82fcd3ae,81ab1260,684fd3d8,1b47c5d4,d5f0c319,93ae7db4,fed1a781,61d9d9d4,50ff831e) +,S(a674db01,836fe328,8566d977,753ebc2e,d55f0116,5ebf0349,51caecd6,ebf899db,12ae8327,737f7db3,56e26fb4,1ab306e0,2294136d,71206f43,78300b95,60f580f) +,S(b0cf999e,f11dea14,3e6b6254,aedf30aa,ba1e8e92,96c500f5,481eee45,a0e15adb,e4970d00,e02adc6a,be5e2433,7e017dab,17a61de1,d977ee99,969591,91a5563a) +,S(b3615f09,29f9b2a0,6a4c68ef,c844ae5,54959ffd,f03f9266,f918f16a,b517380b,31a7675b,83677cc6,ca87c525,27fbba60,d06ea317,fefb17a4,7d7a4242,3595f1d4) +,S(7be97bde,b271f807,96930353,b82c3cd2,c6cce373,198572c7,d289511d,7cf262a1,1af89a8b,cfa4a399,bce5bc21,e26c97d0,5126f8c3,211d8051,626c4f2e,c6f128b6) +,S(692e447d,df9c77f0,2db1d34,101bc355,519d40b1,3fff2cbc,aafeb555,29473d4d,d21950ec,fb7bb723,4e4e48c1,98b93a10,8a85bb5d,5228116e,da6f5cfd,8968fda) +,S(61b6fe3a,21b0bbd2,dfccad11,5123db4a,98058bbd,4f8a61b5,e416b03d,b1414243,75d3dabe,f3e2266d,65d408ef,af6b32da,7591f08c,7fe7de,ff20b9d6,7a3a8a8c) +,S(fe0f9f,aa49555,2afe97f,8462869e,e8a584ac,3c3fba4b,886208f9,fe260ec2,a9c0fd7b,cfa239a0,299afa47,e2861197,f382a331,7607e129,967bb22d,3ae3077) +,S(7f7c9a0,a240180d,c645e77e,c628bff8,fff90d48,c85d2fdb,faaf76d9,b93e26a2,1b12ec74,f801fbe3,ddeeb37b,c940c605,84b0ef14,85e9d888,f3f81c05,607d1222) +,S(3e444ef3,b77b49c2,75aa0524,77da59d5,a68dc6ee,6288e2ce,140512,92e54c60,e211ba3c,6860a898,9e1ee04c,ea9ddf52,25ed88a2,c6ecd9fe,3c2fd500,88367b7) +,S(4844747d,d33f7e4d,39aee79f,138b5fd9,223b4e51,c86e4894,c917a3d4,746d824,68cd147,2560b5d1,6b9bf538,b7f1e193,d2f220f9,ed9f742b,d36a003c,28e2357c) +,S(f0211c1c,8f87fb96,bd591255,6a799865,7382380d,6b5b020d,9095f482,4e8f531d,649112c5,9cf7a8cf,7f9d920a,6b6d1102,d92441f1,1bde7561,9cda8eb4,a26d7493) +,S(918118dc,15520a31,c715adcb,3e02ca4a,4d77c92e,310ef057,3f9c7a4b,d5d2d54d,37d2c580,337de379,925506ab,c6b7d9,4a61584f,4cb2179d,560d3a7b,406873af) +,S(78734d5d,833a5d24,5546e5bf,9d3e5ce5,61f818c4,a4c90fab,c8ae4630,a2c307f4,4b150c27,e054fdad,73506310,80eb5308,b39c6861,23b851ba,aa2349f2,c26b5981) +,S(ee988075,34a02de2,9fda41b1,c821c41d,3ddd5d85,9c5a4ce0,d14ad743,25943f13,ba7fda65,4389494b,40a9fbbb,4b72739b,6f85effe,245b895c,b8c7e423,8d6b7973) +,S(4a821b26,bd1326a8,26be6fec,b90229f7,d7a37a2a,c49e97a2,5bddabef,e854e509,8a645892,37ea07bd,929aee46,6fad63bb,5612de36,cb951200,b9faaec8,b11bfdd8) +,S(23658500,fe8b5ddb,93dd3b50,a46f9914,d04af9d2,2a786be5,9c0fa7be,7c3eb2bf,840e5cca,f9f3e8bf,fe51c1d0,a84de234,d7122cef,fa1f0ed8,9f1701ff,d17c40d3) +,S(71dccb97,7f8e77f5,a03c8e8d,e4b2a30,11d01e13,549949ff,42af13cf,d7ecf208,b70ad10a,5f03ad94,dc8d91dc,e7797eca,6ace74cb,4715bf6d,2b628bd5,f767f34f) +,S(6174a230,e15b2584,7a25217b,9d95f07a,e183f2e4,74d0503e,108994cd,69d20e6b,18cda952,ccd68c2a,5d78060c,6849fb21,e2379b48,425003c0,6f148a34,bf876efb) +,S(57cfc1ee,38d905d2,897dee9d,105fd4b6,90967618,2a2a5d3d,70781cc,9134bb97,bf6b5fa6,4de9110e,7d26e67f,65cd2765,fcedc182,1627243d,a85bc955,2bdcac33) +,S(26605be2,e03705ea,7f199cad,d4d6e711,9805453d,6d4feea5,ec2ae3f8,cdba59c,ced5f775,b62bddf,5935acd,9786847c,e7825da1,5807b117,7459f51b,72fe5774) +,S(6d89e2a6,9ff96c49,a3110a5e,7e17421c,4ca2d07e,6e807a3a,98d79954,7fde2457,4835767c,8f96da1e,78f1788,d9764dea,e4e4a0cd,238ff35d,851ee7d0,9c915df3) +,S(e3607608,338f4229,d77c51fa,cef2697e,f6010c8d,5138e0c6,2b724ad5,6ae79a74,da6a0617,a42d6ccb,44155f27,7c56c58d,42d6037,d234f1ee,ffd720d9,2ae23373) +,S(c8cf20c0,c12de1ba,1ad4dd44,46f76533,7cfefc3e,213c426a,e0cd25ee,2e8bea9a,ef7285a5,ea7393a0,cd78ea31,ef74f605,3d3312ba,f17bf6a0,77b919b2,33227ed2) +,S(f3d2870,fe782b7e,26a1a4f,9c7c3ba9,30e0ee0d,df6593f1,9bf11509,1fa63477,e470c266,ae26fadc,b2780985,9b9d60ca,fcbd9de3,5dfdfb67,9f4fd450,4ed6f3fc) +,S(702a6778,bdf2f3bc,4ee954d8,1e7acda3,1df7127e,a7920e59,a7028253,9019c6c9,2ce19ef9,10d773d0,cc32a503,83f9e968,ca3e407c,c1dfb652,377d08dd,1dca5b96) +,S(ea85cddf,4f79d7d2,a5db06ff,f1c1e3b0,87b0242e,1d7de713,53d8f73e,1bc83888,3806d40d,ccd867c2,2d166056,77d2d64f,d7433dd4,b1e83e25,91860599,2e66fb83) +,S(d0631e8b,30ef6467,de6af60e,61b99112,1949b324,786ff1c2,fe633249,a832aec5,deaf31e3,703df166,b0f92ee4,eff1cc02,684911dd,40054bed,4b21d4da,17f4c05c) +,S(b56cb88b,617a7104,c205e089,b83320c0,5dce438a,50411e5a,d342e9,8b258a3b,757edc72,52d76fbc,24a5515e,417625ae,11db0072,24c02fe1,1e249064,b5127800) +,S(e91ffec8,bc3fa3bf,b0a600b6,89db92ea,7c3ad411,d025a42,95570596,f44702a8,38fd56ef,1f7b476b,2e36aff7,73e190b8,61ec6370,f6ae524,d5dea16d,cc4833c1) +,S(4cd9e6c4,8bf7b1ea,9f855b14,fc904ad4,5e3bb71a,5745b449,e1ab3165,3bdf53b1,b5a075d5,ca9060b7,7d3a00c3,6fbc6404,88df6846,c712afdb,1115798,f382b4e9) +,S(abb07ce9,c4b711ab,d01a12ba,45f0040d,e3ff5a4,e59140d7,cf4ff289,42b5cde0,a8a0e68,350a88b2,397a162f,fc969d28,ed937f60,4704dcf5,2faf755b,d21f503b) +,S(95fac51a,c9deb5d2,b794423,a71cd282,b0604afa,bb3160ec,557a8b74,c578f18b,da99fcf2,abf21cca,c6f4e89b,de2a6e9e,ad199cb4,b97f4122,4f68bb47,b7caead8) +,S(2ecd3e62,b79b4f69,609f33f,2042b56,bad2a9a4,18e2852e,9e8f0d41,1fba8ab9,ef964275,95061068,478e11ec,942b6a2d,99e5b557,830ed0c2,c4291305,41104046) +,S(437d446a,d139d88a,b5437f06,6fdf8acf,7b538798,6baf9551,a414fd4f,101a6440,6c532bb3,38a34a07,28d3273f,e9d9c70,aa79c484,6cb337ed,b41f6029,1e2caa13) +,S(63149b01,94b4955c,1b7e9d51,24e7e7d0,4bb5d902,7e86e63d,f3add9c4,8ab2a44c,c867234b,b4ed27d0,dcdf544,be060a12,4c460c5,7a9312b1,46d2bb61,fdfa6c1a) +,S(78e509ae,99e6469c,41c44dd6,868ee402,8fda1cf8,2c83be01,9fdf912c,1e638bfa,ff3b584c,5ffcb1af,4980e2b3,ace00f12,3be630be,cd91d045,4e031120,245e92be) +,S(cb1d5bf3,f97b2bc4,bb33babc,72de78ea,34cd0a0c,e841cb55,7b3dbc98,61e1544d,e619e8a,dac79a61,eb46add0,96bbcbe1,31d33a6e,b6c99220,123dc9ac,3f27df60) +,S(3247eaa3,9ed5b604,d3038127,9661f350,53ddad8b,8e29d0fa,5c27ed6f,551cf374,1d29a713,d7dd351d,87175b49,afab518b,f268ce81,7fa39ccb,f08b3c58,de1e5378) +,S(d493ab52,8d6c627e,aa3dbd3c,8d809ba9,8a9fe920,307a0c66,2917f8cf,f68b3941,30e4336d,e1621a2f,fe7247ff,157a37c1,edc4f83b,e9fbd84c,af4f96b,8997c7ad) +,S(8dfac8d8,b65eec8a,a65f96b5,571830d9,22469450,42fb2baa,f76a4db2,ea5258c6,c204e9c0,72f643a4,1f53d8fa,dc66e3f0,fdf0d000,c27a5492,6323b2bf,b376af16) +,S(331ca867,1098b530,1b1e6f12,d231793c,de67de5c,640f0a1b,fbfe485e,5d2adff9,b52fb89,3a466c80,ae61d534,cb03fde5,95078592,1da21e0a,a8103d7c,c2e3d8f3) +,S(f34a338b,bb05db6d,55beb49e,526c9d49,fd515792,f407397d,3b520fda,3ffcf26d,6a6921c,4831df6d,91e7cafe,869c4274,faada27d,9d09175e,e86a0b9e,dd70910a) +,S(56d97dfb,284c7417,2e08fb73,3a2d0305,ff774495,2f229bed,cd36e7ff,6058e75f,3775df48,aeaafe14,a8005434,dfc19538,2d10ca90,d05bcba8,edddb2ce,4a4ed7d1) +,S(70e668b0,e854cd8d,d3469cc8,ffab1709,2d9341c4,4831196d,72d9673b,43dfbf7a,60567ba3,5546cd93,f2c356e3,927dc89a,c43fdf50,5e33ca9b,52552587,c905e311) +,S(675af615,9fb50100,56ebed3f,4c9784d1,17538d58,afc5ec75,fa93ee00,29d32390,c501aa90,4f9dfa9d,78107844,983e17b4,34872e3a,a94e37fb,6677186c,fa1abdc1) +,S(99f8e5cc,86ac5587,81a67270,3059442,88b19703,551474a9,9d433d6f,37672d90,30148ff0,9fa33b4f,f4410d57,9afcb705,c1146663,bdbd0fbc,8434f4f8,eacb09dd) +,S(8dcec207,3d74b9bb,bd47f52c,394b263b,e71881af,363bcd80,9adc345c,b9ce9892,d8bc1ef1,79ac54e2,68a685a4,db35e3cb,5b6774d8,e8d6b738,f4d65b66,86782a5d) +,S(d83f7e8d,adf27d5a,f8502d8,3ab81001,a2219805,d942cbfc,76db2764,c4235773,48472e1b,2609f81a,8b12326b,1b19b422,763b0ed9,d6fd67,51751c2f,8aa46c2) +,S(e6f8bcf5,d9ea8209,cb46ab60,643555e0,d0569f3a,dc62ac76,edc09a43,e02fea2a,7974cbc9,5a9dde1f,34560043,7b628eac,3641498e,612c19d9,9a79ae4c,cbde2d82) +,S(d2f30716,e4c1a665,a37d0606,3987d0c5,c19c072b,f1cca8ae,cd0e4d8,6a9e8c1a,e26e6d9,9fbd198a,ab83d0aa,ea53228b,539efd37,ee7ee791,365cabd3,8850eb29) +,S(d7a891eb,551ae5ac,baf366b8,65755a56,edc7bbce,7304a806,2729655c,f7f61cf8,8a7d915c,3a9a1500,616205eb,798915fd,9b33d7b0,6671e9ab,cf02b5f4,667173ab) +,S(5bb03484,f02ef87a,fa07f852,e3ec0664,67ffdc38,39fa28db,de0da07,2fc31246,e0515751,c377266e,ff95f755,f9c9373d,226ccb66,3678e8ef,176af5f,2fea3504) +,S(58716b31,48a0cac1,2024760,60d3734d,ab066ad8,c0f8d8ed,cf5824ea,83e111ce,71ae487,701d16a9,c1d2ab68,1ec7c8b5,8367a4f0,179dfc18,6778579c,553cf608) +,S(4a344869,db8d561d,96944c8,94a3c196,8d649fcc,bd430c7d,4a66ef0c,dc2ca550,285433f1,ff0e7dba,5bae081c,1b33c762,6f30224e,dcacfe66,46787818,da0f810a) +,S(3ecc369b,e7789b92,cf1448ee,28c0448e,ebc5d277,a8bdb5bc,a22d3151,5e246f7c,a5532e1,47848951,cf11e065,3f0627c4,6530436a,5f3773f2,b02c9bea,c1b60e78) +,S(28a5d794,21db38dc,8d7c8cf9,d120a3c9,97eea170,f0f6ed43,7222bf4e,27f170be,88cb09e5,ea40b566,39cce9ee,1245384d,2f02f983,3b3116b7,31ae5576,daed7cf9) +,S(4f54f945,b3afc07,c38e1aae,16dafcbb,b7c5097e,4895a789,e70e0993,cbc905f,6ba69303,24adb3b1,2fc1f8c7,8ea58729,5115adad,52bb1138,7281b9b2,997fa597) +,S(f490bc4a,20f1ecbe,ac2dbbd0,56f2bb77,d258a914,9b0732a,f29aef2f,7ec25f47,aec6fa89,74c124a6,576475a,60931a6b,533d0da6,4e621fe9,c298f03c,a894336) +,S(73b2f8d0,e91e2516,d2ebe348,85b973d,4a0c7919,1ac857b4,74f713d7,348d343d,9dd7a951,efdaa060,19ec71b,e41b294,d047ab97,d0cef4ce,25a607f2,f11bbc26) +,S(d911f5e9,977489d2,847aeb66,8c3cdc6a,ffbc7b5f,4a5aff62,1761ee01,567c5647,3ee4afd0,2ef6d3af,a2b16d34,b59444a4,2c70b3d,4db17788,ad3aac57,184e02da) +,S(87b695f1,5c5d7852,88218586,96bca8c1,9c5a6f3e,f23786d1,fe010fd,d063b0c3,21b54a,46ee82fa,bb5ffe0,e3137892,31623502,9a8e0505,645a9ec9,29984895) +,S(39de5a90,4ba6989e,5d16dda,a7ff67b2,15e08f3f,b593d7a8,4b6babe2,ca25c658,eaf5e6c4,1e1e2fc8,c1581f6,211bc8cb,34dcc08d,58f570a6,e6719626,7124c019) +,S(18c1f673,ca19f805,c426162f,11e7eaea,c675974b,6b4cf0f5,9eb03288,83bb0af1,ad1690ae,65783091,27f602fb,93652b59,d7507414,e76d9b3a,82fef166,68b7aecc) +,S(8d70ebda,893e8d03,d15fbd68,67528b7d,308ddee7,b2620698,15e7f3c7,332d42a1,254be26e,d9e9009f,e4aceb8a,b97020a9,9196a9be,60777fb3,a9d1243c,66df1707) +,S(c32fa0af,ab39b1c0,c96852cf,8e2382e3,93e5b59d,2e83ed50,d5307a0,14ea330,381e8afb,85d47c3d,dc5da037,d6bd82aa,ff2324ef,ab0e48d5,5da3fcca,bf0ee3da) +,S(c350235f,e5ad084a,1aaaee80,d156b302,d34ec03,360a7c0d,3a883cb5,19f4b27,e5ea7c5d,3184e9,b62fc3a9,6c8bb9ae,72535fc0,497f1b58,67bbae06,672a1f79) +,S(8ef5e1f4,8d905df,dbbba4b2,d4b22162,db839ba5,b28c755d,46bc2f00,e25e20d5,6300d9e3,11971dd8,a3e88192,84f3a228,9986270,45b901a1,80f831b2,4153103b) +,S(9b3783f9,c638a6fc,166aa2a3,3a40d95f,35a4e7a6,c8cb5fb5,1e596b9a,f285279c,41b2dd9,c3abce77,fcf798a9,159f36c8,94b55ac6,7c917de8,75b18cd4,e70dcaf0) +,S(c262215d,720180ac,669f0bb6,885dceb1,2c941730,93e561c2,660a4a1e,cdf0a244,7fea7ed7,f654741c,c67b12b9,f115aa40,ce427cb3,8c6498f3,8bd291a9,d73e9f2d) +,S(bb72f723,f0a16f09,7716272b,b905a111,c290c229,94f400dc,c6a24814,f41816f9,52a83ee6,53214a5,3ed2b13b,a367324e,e5606fc2,e3dc05ae,7ce0cf05,ccd6c36a) +,S(d896a5a9,a833d66,51b17632,70b03d36,eb423236,bf3b2b7b,6b2ba97a,f9282a03,e8a823f,ecec375e,280e0d50,49625dc2,1f48e269,77ab5eb1,b467d3e8,a0fccb37) +,S(198cb33d,9a2b790a,2d6fa355,58733bc7,f64cad76,e3921dbd,8d7a1f,8db52b64,c7e93702,ad7df0a4,94fba344,8a8157bc,eba10ee2,8f66f000,7e7f7655,8e6b4a74) +,S(4354e475,81d63d84,df19bd08,d98b2315,67a55550,477e1c53,cd425854,e67cd81a,a612c262,74d79c46,89734884,5b87ef50,29d0f87b,4a06e4a2,8ab36bee,ae6a6ce3) +,S(d956c71c,1c8b110e,19f96ffe,5709f2b2,83a095ad,977878fe,287de35f,283b2606,7c029c97,9a807375,bb589c12,a20ce37c,75178be2,5d5af713,f4fd4070,429c8d0) +,S(2c04b299,1775ae36,ed7d5b1b,d9b0e65e,fb2bff8,ab99dc97,2cd860fe,19b1789d,8b3f3b00,6d63c81a,86f225a,bd8e658d,c9c4c1d6,6787678b,6fa4a692,bc7f78e6) +,S(c7897c17,debd6456,a81f8d96,c0ea580b,db5daffb,5fc8e8e8,9c8612b3,7b229f7,f7334550,d20a1a21,c422f73e,d23fb159,2fb3d9b7,ca61d7b,6e124fa4,147ea63c) +,S(3b37b93e,ff554f0c,7e7f36b1,864ecb73,7b33a93f,6ff31d6,9ea18aab,a9487505,50ccac12,e071f469,3f5e5339,462a0cb8,66bde539,5842ff44,620f7acc,aff09a71) +,S(4584ea49,8a2785e0,b12c86d5,2b839212,f21b2e33,3b64bb0a,9713674e,66216547,2851de5a,b67354cd,6610dd4c,91aaf4ce,b75c4c97,26d524d7,69ae0ba7,997ad79c) +,S(c0c971d9,f5644eac,851ae8a1,d87b4f09,a802ae07,32d9b5a2,d9589051,f139963c,83e07a5a,2b7614c,c064b4f,815b8a76,6df7eeb6,449fdd50,5c43faaf,b0bd075f) +,S(370e8fd0,858c6fbc,f479deed,f35fef5e,80cd2338,90d4b227,1867ea90,6cd15b5f,ef382477,fd2dec6a,fce439ba,9b341a21,17d6ecf4,c8c8d63f,b5775094,6cedcaab) +,S(ad402a30,99c5d5dd,c7ad9631,b592d5a5,862e8d3b,5ed47dfa,c288193d,69366625,b8c0d468,5d0eadfb,9f7e4ce6,11c61f5,7098da29,aaed61f7,6a50961b,b45b7c5) +,S(ec16de3f,32ea8f58,c1dc93da,d1cabecb,5ca33ce2,e3fa3bfe,bf0ee989,f3ebf5f9,aeec3532,c5391ce6,1e23bea4,5b7b5847,2c36cb8a,6c5f1363,e457c003,b18824fd) +,S(5a51f9d5,f5c48520,dbd826b9,49f62f67,c299a228,259e09cb,b3bd6fe2,f4b0e60b,3c498d86,225a83a1,f506eb62,a2e530f9,511c56a2,eeed77a4,18ddec4f,4404b9f5) +,S(9696865f,64523eaa,456ea65c,40ca6e0b,12c6e6a0,211cf8dc,20963f03,7980b684,8f879d8b,491f11a4,1f0025f7,b35dc8e7,c71e420d,7d7d9001,bf5da111,9ad6c2c7) +,S(80c43c8f,6325cc30,8065d4c8,6e3d7bec,6ed85f74,412f6127,4fc3ae49,b1e185a5,31dfbe69,a48f1f39,a0cca355,f3d68f28,cbf3e14f,7d47cfc7,d9e82e25,19bdc292) +,S(54940550,ec4a6ca7,561946c0,65769b4d,d4683f1d,11dfda66,4aa2f8cb,8f1ab2d7,f41aef26,64466fa,ecc076ed,cd383d3f,132b4fe7,5a17f16c,c394b6ec,e4079378) +,S(a9787f8,42b3549a,9a3bea8e,4182555,99addeb6,416118bd,901afd9d,ad4c134,4efc4f67,65c7cf5,ccc2336a,e9eb14c5,a1361067,7632ce89,68033d57,4bc686b0) +,S(fa83e81d,63b85491,92e800e9,7a422ca8,35c03bb1,5579bc05,bdb4367,198a24da,779940b2,ad301a1e,205c0504,fe3ea104,cef6a459,e0479849,90fc94a6,871954eb) +,S(ae9a8d1c,a8a560e4,8a373666,544a7b9c,84bf0475,9de1a63e,4a20b55a,2f25c132,b9b0bd66,4c46edfb,ca2a0bb3,a94ff043,c00c1441,9f1df886,2aaadc02,e25017dc) +,S(a2f47145,296dd22b,3a6f5185,47ab0957,4d3487b6,8786f87,6758cbe3,5f4c0ae7,2ec4171c,15e7a82a,f6ace24a,60176f7b,6239561f,3c369a9e,efc80d52,3fd216e8) +,S(1bdcf82f,a7dd441d,91332a11,35f50be8,4d275358,f95df300,25187f2f,9828f219,99f12980,92a3ecf3,dbeb290a,67d72aae,6acd9cfc,c21918e8,9ff7ad4e,548d3510) +,S(b73c91e1,ae33767b,11bd329,361fdae6,36642d92,6c2792b6,e19b6e3f,947a5be7,b6502357,11ffe955,be5798d1,467eafdc,94df5911,29d2aaa9,b747a2ec,befa9d7) +,S(b23b4ad2,e983e556,e941a35b,b84846a4,40cd25b6,82487f37,a3a30eef,eef15d1,7010f10,88749d1c,f95e52dc,eae1a379,b87762fb,55593d32,a65ef0fe,dcba2485) +,S(e3aad2b8,96fe34ef,9d775743,6e70a70c,b3bb0c6b,8436e616,a23174ca,985fd8f7,5d6edc38,89beb099,dd191564,eaa83c14,3ef0b74d,7789590c,d6083704,61c6676f) +,S(2f22a14a,f69e6257,b909e3a9,50aab3ea,dc09c281,ec52e47,8c578f49,68910244,4ab723e2,43c71baf,d2aead8a,479a1a2e,fd2aba74,800b5eff,56ca46d0,532e81d7) +,S(93806026,554bae5e,9b91f534,f864b79c,81e581f7,bdf3b2ef,dd007e32,dd6872f0,800f8162,a6836801,d052871f,6892ba33,b2f60f82,89a658ea,a8af25fb,f9d9c444) +,S(8895d121,ad1f2be2,3c578faa,1e33656a,e9403ddb,a1f1aea6,1cc7bd03,817a46d9,4f7577d2,420d0d0d,7cc9ed68,ba3645b8,f9466f59,570ddf16,ba168de2,8cfec881) +,S(1838c15c,3bcf1189,546a9e3d,69fb8a73,de39c862,f5faa4bf,423e1dbd,29046ccf,49484789,1b67ea0e,2e7f7eba,4a596d66,b3ed9842,3ffc54b0,e9292a4e,bd6f5487) +,S(111e8eab,d9cb3ec,5eb63cd4,14ecf59e,3a3f0d56,70959226,ec8f203d,947204b0,4ab9b3bf,dc853571,2c0db9e1,5fc2832e,4560e420,af96b043,e587d1de,d996e38a) +,S(80369d1,ec5ab7c6,492db1f9,aa2fa368,ec083d86,75d6c1,e7262e73,a612e493,cbb28c30,db7f7d03,6b8dda93,7e0c4e18,6a09f1ee,2407e55,7f6dc54b,a8c0553) +,S(903c9034,dbd3f982,41351979,c9306a8,42b88892,48cace15,c3e3a8bd,aafe1ffe,d55adb43,d0142740,71499c92,e9b851d8,e6ece26f,f82ceaff,ba63a003,14960f38) +,S(d6490ce4,74bd1e80,82c99e87,a0510a2a,c2c2772b,1921cda7,dcdcd5e8,6ecaacc,85a1fcc6,de4b93b8,b2314da6,31d7abdc,f96b22e4,b44a5545,f274f941,454e98f4) +,S(12f2342f,aa8b19a8,bb0e080b,2ed3487a,14ddd1b4,83e0bfa4,9ea08484,157d5306,eee0b9e4,30a51a3a,49da893e,50360ba1,21660b4d,ebd3ad8f,82805416,10f4b7fd) +,S(3bf1ef66,57bdcbba,a9d9a23,36c75429,c4df4a86,1d71a767,2d7e956a,deff234f,fa98467e,83dd1ca2,2a85cd8f,f12be1f,53d5a939,352f4046,a626a208,601ef6b5) +,S(d0d0f8b7,9a04ac8e,b6e010fa,3608926f,3b5bd886,f84c361a,8e1d9dd4,b01ff717,9bb32b90,6d7de56,c75bd202,b9353128,b6440fb,42dae8e6,74ade0c8,fc96386d) +,S(19507738,80caa9c1,f042f8b5,d1594a12,161635b5,a83e4675,35ffe51a,fcf631fc,9280d033,f7a8efc3,ff22f501,6a6ddfd2,f78159bf,1f13be4c,f758b150,21126ba) +,S(f4f50c3c,eb750a04,95973b47,53b96ec7,22cef833,f4ee7459,a51f884a,f9a251cd,41f554fa,d3d521e9,65fb0768,66caeac7,d9f5c6eb,ba7ba7b1,d1d38c9d,c06d85ce) +,S(8b669c9e,22452528,57e20692,2726f045,e97b8cf2,1154fb74,e199f49d,11951b84,550c47fa,c46060df,4d893afa,9f08713f,cc8e719f,a369e90b,fa8846df,7938c65b) +,S(941cb4b0,31edf346,64dd5e7,92ca135a,1d6cc6f,55341322,66644493,aee5fe32,cfa91a79,29b3b47,d73b8ae6,77cf64eb,cacf9408,3cdc76f1,79e25631,d574ff68) +,S(557e36b1,27307c56,72232c6f,6e92e4f6,f5da9d22,1567b464,8e79d97b,bf589023,ab741e35,109a0313,e7adee7a,2cec2c10,79d18d72,6c27f1c6,5a808b98,8e99b523) +,S(d8081ed,9e7cf1cb,e1ff07c0,b8ef3f9c,c7eac02f,1cf1c6ff,833f4b74,b2a33269,efa297d7,10fb71c8,43e358f3,e04ac308,53027f00,eea43d03,9b87c3ca,2b0fdd2e) +,S(b5e4fdf0,7a443146,263f6539,f6c8d991,7486da78,95b4ba7,fb4c9f14,78324d44,a3ef979f,93ec1a0d,602950d2,ddc400c8,4f018643,229cfba8,7cd9e3,f2fe657b) +,S(1a573259,a5100c21,d75efcc4,41d5a834,a81d96b,f4149731,eed4ae67,508bffcc,8a993dcf,49f94f6b,bc71766,9d37ebfc,614a45f4,1d70a1ca,f4da8834,5711223d) +,S(33d9f9f6,c9ba653b,f9c52166,c29e9c06,2cb7700d,ea2f40cd,28520bf,237b4558,dc80f57c,fc0e73ab,bdfc4a8f,f7e8f4c0,3353e889,bd54cf84,6361c1a9,af5a0a79) +,S(e4ca84fe,307c9237,4d39b2bb,b017b5b9,e478b26b,95236b8d,5bdfb220,f44419d,c0cfc7d8,92271c95,7ef235f7,2f310c7c,7d0ac297,97d42ffc,ba37061c,83775507) +,S(8f1f2d2d,cccb07a2,a8716b77,8c74f3fe,22990d36,b951e6dd,92f5896f,51bc23aa,9eaa792b,426d3400,31a862ca,b805d0da,ed9a4c73,591c204f,c5179b17,22aef870) +,S(20f7f6da,86eb5ae6,6a1b7818,43fd7fe4,c458e3e7,bfb590c8,76afb601,257b2ee0,6dfcd6c3,93e7e9dd,32c7e826,42f90d69,ff1e1ffe,18988de2,bc1cb9ba,db246fbc) +,S(3a3df365,8d65d718,2dc05797,8bc48fe1,5c5eb6d8,6bb241e5,9e178ca3,9cf9a010,ffb89791,7435e8c5,4865bc79,52fb7bd4,1578af51,6f611c54,1f7cfd5,651b293) +,S(7aa435,7dbbc5b9,a01b5f94,6b0240a1,36daa942,1ae1a1c9,b50f66c1,c7f15e48,4640c8d1,ace8f69,6b08ba1f,9a46d04c,f75c5914,3339d5a,181a7dfd,bfc92c0f) +,S(198e4848,8176664d,40fc14c7,acca9eb9,aa22599b,b2370959,5856d78b,5e932e94,fb9dcfdf,b27d062e,8ea5246,275d80e5,6fc7cb09,e81bf066,dfca888a,8df1de6e) +,S(25da8876,d3215051,75694915,c25056e1,2c1329b7,7795b7ec,1d4b66f9,3c911cc9,b8cf4a83,db78787a,6d80a157,c7c205f1,3664a71d,a6e78db5,b52b012b,930c4583) +,S(893d2e9c,3b6fa8e2,136994e6,14121842,bb82e577,89826ccb,eef51fab,de32c0b,d7cb9b4a,1d49b34b,f3f743f2,10c32a25,cf8df45d,8552a7f2,1268e270,ee6fed67) +,S(dde2e8a2,988fd777,4959457a,5c14384f,c8248d1b,a32c7ce1,a727af27,7b217688,1fe0272,137e4c9b,1c6df618,41a240a7,be3b5de1,7b93fa24,ccc055f0,e7972b1) +,S(52a73b51,5326198c,81bd988a,3033e1db,abd9ee27,9a91a434,e7a76813,453e27c1,c23130f,c4b8990f,ee308443,1cbeff25,62963b1a,4a5acb4b,a1319b4e,d77c745b) +,S(1b5afdc6,4598bfee,4ef31904,f0d06796,17b0149d,ac19e7ef,a1d4f19b,c5385490,fcc0c62,47d96d4e,430ae0e9,c19dfa2a,3719e66c,ce25a2cf,d7428d4,4c91e96e) +,S(76da558b,d533e761,4d97b7bc,5a1a98d2,af043ce1,1f2b323,185377da,c0e0abf0,f8dfecd7,94b3d069,ec22f01d,8418bd90,27c3dfc0,62beb597,e352bb70,271d3cee) +,S(17f01b77,d2417d97,e3c14f10,18af67be,c12c31a3,58521f6d,203f101b,227cdbc0,fe16d66f,a194c800,e3c14bb3,f1df0a2e,3ec319a8,66c69d9b,3b492d96,327bba04) +,S(6010e0a1,2cacb745,6e3a8f73,d5219a87,cc14dae6,54be7265,ffbf70c8,c4d5433,7d5f0faa,579afe50,2541a2de,4d525bd4,e7b950fe,2b2dcdb8,d67d3d9a,7b11da54) +,S(91e938c8,3f319320,baa876fa,23773a7b,d0fb81f9,bf9d99bd,13180560,bfdfad6f,b662f401,7a4fa2ff,6603864d,77a6b930,181372f2,5fd6a67e,12a1df6b,f75509ee) +,S(de2ef2ee,633355c3,3d259357,efca96a0,5b669f13,b515e64a,c0bc467f,2abd665e,d3d6254c,5c30daf4,64843190,7c2a8c1a,51baeb23,13605a58,b88c9a78,a6147c73) +,S(186151f0,dc37e48b,3178bdaf,900e7bab,49cf251f,7a2a1b8a,76da8750,2dee93a6,2a240dc,acbbfc19,876c3680,fdbd7ee5,d1085b79,96317e4f,db73d5a1,9f097f8b) +,S(6f19619f,ace0c63c,4dda566a,9a1e78f,a9568db1,1c46f3e9,771756b2,7d8a5c1e,4716efed,7166e06,722a744a,af89d145,4ddd2f0,f7652862,cc38eb3a,2beb1925) +,S(a0e450d6,fb8a6da7,e8f6e62f,7a08c2c7,277a832b,4e5c6dd1,8cbed37c,37db23a2,775223c6,3f81b2be,1bdf0831,9ed65ab8,d3e11c56,38830851,d55a8893,730979d0) +,S(6337ffcc,64f5d358,d90fad1b,646d8d7,46e2fb7a,2a6cc378,9b55ec52,3824de5,98286287,578bfd97,4c161a01,55f9a2ef,707858e2,a32c3fc7,319416f8,5a6e5427) +,S(914a8565,cc1bcf80,19e1eef2,87c9467c,bc42faaf,726d4399,6485efe4,6f99e32f,846c42d3,b1dd8c20,3a744f5,560396e9,b9a92380,2fccffba,c6ee22c7,65bffde8) +,S(dd79a02e,2460ef86,cb4e9ba8,3ee7e231,e99b3303,1d4a6d7d,6dee8b1f,b0050daf,d6a75b67,ba13f76b,172ae0e7,d63b20be,db3e54f9,e54a96d2,aebc326a,131ea271) +,S(b2776e23,3e759f8e,38c52394,d50fe177,c6842acb,f238eb56,c7638549,174c1b2,e18c89b2,dbb6453f,7b610518,8bf090c,f0410e51,97885d52,b50b2507,ffe4dc81) +,S(e0716c4c,c5e84f7c,282adc42,f294a36b,56bb26a2,58cef4bc,c36a7f53,1d5283e1,1442ddf1,57491db5,1692c7ea,5c92976b,8a2488b6,6aa6f38f,7a62946b,a24fc5bf) +,S(2b10c9f1,bfdd659d,9d1e073b,faaa4b13,2a08b678,f757ef39,a137e53c,b291df70,7d22ac48,f4e0aa71,8cf7882a,57a46746,94e0f456,f2cc3aca,30a3f8d4,2b240dab) +,S(fa762181,26a4813e,e97f2718,c6eed96d,da9f6912,ac463af6,a52f3aff,f80f07e4,8c8a04b,f38e2599,4cfd8905,27ace017,e57e3f8d,d378b205,2e767954,80dd5701) +,S(6b893eef,bea81e30,7ece156a,e79abc26,d9f0ca5a,b2dbde11,bb0d8192,f138e58e,510a308b,9fc47167,f72bbc4,f92eebb9,88a6512a,b1679102,f9016b0b,d82c559d) +,S(6cd9b970,332f421d,1aba33e4,75f26a4c,5c5fec37,4a549ac6,d8c10fa6,cbc40032,b57dbee6,68bef693,67188a54,52e3b4d2,cf1c8c25,8e36bc09,432b4f4a,dcc24086) +,S(ba4847ad,40530fc5,f77ea79e,ef7a1c0b,821b5285,5ec4ab8e,d238ce46,48a09fa6,627ba437,8e0f2044,20e61431,5f3d110f,2da9cbe6,2025bbdc,5bc1cede,c36030c9) +,S(92837329,4f59a142,ba84f897,7acf2e7d,9df06a27,74ad88d8,98689900,3750c513,4e938012,b6e55d6b,6f7871ae,c34511c8,40912a1,1a32012f,3bdd27b7,90f86c37) +,S(470c19f7,9aeb9a7a,142ba010,10ea4929,3de57e25,68658d45,42b5a626,864600b9,2e99dcc4,b93d9a36,7544b842,ef4a3085,2e24bc41,e98ff2a2,d9aede05,da703225) +,S(2496996d,c38e4bbc,851f9bd,f9a21b42,5fc7ce2f,2b06993e,97604a0e,db555c34,b6e02a63,f0e2e54e,1cfb9d28,7607bae5,8a68ae6e,a8300ee1,c1170f0a,9e567323) +,S(92366ed3,23ded4df,f4029e42,685c51fb,a8a916d1,999c42c0,a90feb44,4112a78c,88dc8af5,f6d1d14c,5c09d216,8af0e752,3fad76a1,5b311021,7ead491c,12b63191) +,S(ff9760e1,ce161564,22c4962,4962d89c,37e66e64,cd7f8e94,4125fd00,c05974a8,8ca4457c,a5e52e23,d70639c,a9a26f3,12312451,8f0de070,86d385b6,777a63a8) +,S(50d1d5ad,79f919b3,d23c16b1,428d971,5deb186f,2b92b64e,7a1ea1fa,dfca4981,ddb07de,d4ad81b3,cfefe726,33521be1,c7418c5e,aa759440,20dfe92e,b4653ce4) +,S(4934f753,29844b23,80183df0,254d1c7d,342d7d27,9fa5e804,68dbee16,4e9c2c6e,a4f8aba6,7a488a33,40e8e943,14f7eed,5cc25487,5acbaedb,afecfc2d,5405609a) +,S(d7b99142,9cbdf755,5cadf030,7b2c4a91,c0d25710,a0553511,eac6afb4,c544ff81,17bf03a6,83b1a0f2,366b944c,aabe57d4,eac4d86f,bfabd006,66693983,e0241420) +,S(834b036c,145d6905,58199bc1,e7a7bfc2,4831417b,530b0b97,8cc1fc16,af00b966,4a45a9eb,299f24a0,1c520751,2cbee44c,bfb75d0d,14a7eb08,b1668b58,ae58c47d) +,S(d7a8c30b,fd7b8aaa,78dd23bb,86ef2624,5a363857,6ed69739,25ea9d9,194bfb3a,7b5f9ce6,380abb91,6e041388,13baaf24,229ece27,3541f4ca,2883ad77,9e501fa6) +,S(ea4c7ed2,7ced8b13,4a2ccb2d,3828d29f,f80c4825,e5607597,3faace04,d2fb7763,a8454c9c,be19ec44,8a3234ea,97b8fbb,b256a148,11ba0ede,becd8641,42684d14) +,S(a2cb70b,f80d9f6d,696ceaf8,fe8052bd,e59215a9,99d4b92c,ce806a19,71d555c,997bd94c,e5cb12ff,886c1cac,bd21c3c,e2f144f0,3af644a2,c2aaba2c,825f75b5) +,S(89a91f5,c7c8700,175ab017,8c4104f4,a927af06,f269645,36cb78d0,19f8b8f2,6a2f8ebf,e1258b4e,31bf9a5c,31c51a3f,1cb58aea,6e18582,3e87920c,3df8e7e9) +,S(27d7191a,71ecb0eb,71b43dfd,5840079c,bd368c0,5ce62fdf,2967dcca,78f5a6d6,11120002,d0d0fa9c,8db51506,4e1fcc2d,92d8fa9c,8b454294,bfd01c64,889d5e6) +,S(cefb996a,d36deffd,c3c7ddbb,11a5013b,70baa98c,1057adfb,185b4c9,62f3384a,c93cab46,7523b0d2,baef4425,c9ff048e,c586d4c8,69c69cff,3ab9d72e,e3d80f83) +,S(5a8ff765,84746f42,4e06b557,77986825,e91312c4,4f79003d,c1b381cd,4fe5ce8f,3946177c,3c741458,7bdb9506,85ad0c73,b422a8b2,5cc3ad3a,cd486e76,99a42f08) +,S(b179dac7,d2f400bc,bb039f32,91e813e6,f9a7331,80a1a5d0,db51aafb,af582fb6,89a70304,d70cbb61,ffb3a499,1815cb17,458404fe,e43f09bf,d630d480,5978b1dc) +,S(6e14a53f,ab32be84,4eb14242,a3b6a86e,e178cd7,51dbb7a2,b14cb763,ab2fe6de,a22ed4a6,d98c59d8,ca85e111,cce0efcc,60e20df9,6b06615d,69aa3cfb,206494b9) +,S(12ac42bf,d8f919d8,c79a8138,1aae69ef,b789a573,f58332b5,79694dfd,27e7ff20,4ebc3b7e,4b0136f5,19a8df5f,baa7ff59,17f4f632,f85ab1f2,ce502fee,bb3a3a87) +,S(87bf22af,5e9dc061,eabb01c4,eaa867c3,4656599e,da744da7,774fa8d9,aad68630,d34f530d,fbea0d52,9d2d64d1,323fa44a,d80cbe01,fa2806e5,ff069e6b,fc0ce729) +,S(33fe6bd7,ebe2b197,76251415,8bf866cf,b6d3ad5e,1f68519b,edb513fe,6076c96f,c5970cce,f44aa84e,f95a56eb,588b7a8e,d9164f5f,5a2eed83,1f70d308,2320e9e1) +,S(5fc2f44c,fc0f7ab9,9f03b67a,d7b6ee99,d73fa9cb,d74eb5ba,6d931d9e,26ba51af,8b1fbfe9,de201400,6c07da02,4bbcf53e,13bb9f2b,ff3dd6d9,5135a6fd,5842f0f0) +,S(38fb5cfb,e4f348cc,1fa7f9b2,ea600daa,e8330aca,53308f09,b6a7d8b8,5ca8a88b,ac1bf91b,7f53e824,d845c0f6,9534291f,cec2808f,95acf58e,4afba07c,fc735be9) +,S(3ec2457f,fc848504,6f74912b,5c58b270,1be6eeb6,f88da0b3,c5cc4454,48750875,b63209d2,641c65bb,7105af10,61d7513e,409f153e,5d1b5073,232eacc6,f76dde22) +,S(32fe812,e67ef62c,687d248f,e75ef399,48fe8ae4,a01ae10d,ed65264b,fb5050fb,d9c85369,db22ddeb,baf7682f,53642962,cfec2afd,3a20de77,588e7473,18044f6f) +,S(97d7c69b,2aa0277d,2b20e9c7,bb1066a2,be6f443f,d0a428b6,d78c5fc9,6ff71b57,f84ba781,70837aa1,f75936cb,fc50c444,c40c9fa3,22d90088,ac6889f7,e7c0f861) +,S(3621a4af,4d698e4b,60e7f497,6e0c10e9,ca32834f,ff917aa0,6aff912b,2ad80cd,22cfd248,a17886a,ae5d0e11,53621e9b,46289acc,ecd8155,a1bd6372,120c4da7) +,S(ae79a6e5,848b1dc6,cb64958e,87b737c1,858442b3,63d4a2,e9f04561,7d73f8c7,c147238c,59885f2d,dc5dec63,de421eb1,c5a19438,ed0600b3,4c77f4e0,e7aa557a) +,S(36eec623,700e51e7,723a632a,55370ddd,d6b1f917,6ea39a2e,54a2a1ac,52598c35,29698c0e,56b4e2b5,5389dd9c,3d8b509a,e0b87f99,4872d865,3fc74269,7f5bb7c) +,S(50f70061,804dbeab,cf2ab4a9,87ebde2,1f5496c9,a4cd28a,4dd9da7b,310e876f,77e27710,edf831db,6ba9e64c,545f03a7,eb390842,8d9cfa3,3d0e1c87,61371706) +,S(c2ad6b2d,e84bf60,7fe77b8f,a9fe26ff,bb5e1906,1494e469,8da44a33,25843844,17b92ad9,d3938fef,7a17f543,a169a7ad,8ee65dce,36eeedfb,5e3c0c8e,a1b24fc3) +,S(a53504f,e2286269,427fd2fc,fcb64827,bdefdfd9,feb89d50,12651d2d,c60ae99e,6b9d73e7,e046d11d,ce78b114,8aea837f,770d8267,6642dac8,f3b3c035,c10eab45) +,S(5410db61,40a77b31,9f19c969,34a8364a,4881ab60,ad76a6c9,34f317c1,1b658dec,ac45bb6e,2e5fe23d,57297370,cd04ffdd,dd89a9,15a1e9ad,15d7f9e7,6d8b3aeb) +,S(882cbd69,fbd3e262,5093385e,ab82fc9e,7597c38e,45fa5df7,f98c94a9,3bf25467,2083f00,b25b28b7,f92b040d,a4294dc0,8a3d97e3,d951e724,da0e692a,5737a87a) +,S(3141e0d1,22b4c136,f7793c73,9c48f308,c5ec8043,19db116d,64eb14f5,aee83942,9c2d06cc,d765c6c3,cee09b70,247f8806,227d0178,13becbb6,96c5a344,b68b33b1) +,S(1b2f3686,5a63df41,65caea4e,305d8d66,1de6ccc1,c2a28cf5,2373527e,27cecfc,1239d8c8,d60fdcb9,fcf3f5d4,63305037,6d47fd97,4cd6bc64,99e0e951,2d2209a9) +,S(725168cd,9fd59e41,14918b77,6ea96fc9,6315b4f0,86672dac,1eaf59a5,e61ed25f,946f03a9,84a6735d,e72acb38,dfd21905,fa2358a5,e66e7b0a,2f8836a1,8f5d73c3) +,S(4207faa5,c9dc9622,9644df1b,a099a84d,654ec6d2,aa69efcd,a4a31a3c,61f2e1d4,ea72a92,836d1597,5275c18a,900c0e7d,d0502610,d97b6f79,1f6a28c2,1b3ddfd7) +,S(53900d38,a4740830,a6129a11,9dc90f6d,30f32847,708d48d4,20b77764,ff5b9cc7,66822ed6,ed941eb2,20aefe94,4325daa7,a619dfed,5c76bf75,1fc25342,8178d3fa) +,S(d0204932,a3fb8d33,9779851c,d69f6adf,be1a9957,59fcfce1,b8d4f047,e4e4dd2,8ded18ff,bbfc663a,9c658ae9,286f82e0,9ee9381b,3291f5c9,efabf0d5,fae318f) +,S(3ed8ce15,2d34e621,94b8b16d,55605766,41fb2673,14a08c91,d916fa14,f21abde5,48490fe3,9769c60e,38996370,27b57df7,230060c,2505f414,5a1c7f1,4ba16660) +,S(b7d57614,9b5e2ce5,edef3c30,b8cce79e,6f122c70,351d04fc,ed2b67c7,f5cb2aed,7c8fc1c6,bd42b25d,d45e37c2,5cb06f0a,bd2f7051,4a50e6e1,2a67c0b5,b199eda1) +,S(2489e06c,c8f0bfed,9d5ea722,c07ca795,e9ab40e5,45b036e0,f0c11f28,53c0d35c,dff65f5c,20766078,9737f1fd,5af05ce8,3b8edf91,37002b19,f5e1599a,e76c48bd) +,S(9b2140e5,509817c4,465e6689,a3bdadcf,b79c1803,883d493d,4e4e99cd,55f30a29,86374501,705fabc6,62e8c869,a22d2813,f7106006,ee09b6bd,b582b690,50186688) +,S(48d6fff7,d5c37c30,11c9e63b,b3342f92,776060a6,dd179e3a,e2c6bb69,d2f88b3e,783353e,adb6daec,536d37dc,76ae3ff,8dce14d9,65d21d3b,7a17515d,7d3341aa) +,S(35d46a17,b6951355,a055e253,42b4244d,8ce65459,c630f2fd,4708687b,e6a49e7d,13bc21d5,7cc2954,62927cf8,bc31ef3b,5407021a,62c5253a,5950e8eb,b9c735d7) +,S(17ba438,24168f06,274b2f5a,d080fda2,3c0dc34b,f77e81c3,c4413cd2,f594575d,e8b34f9,1ef09f92,7b5d9e51,662216a1,30ef8f87,2e0febe,3f5cce8b,318fc77a) +,S(2a09e4bb,4f6d6b40,f59d0299,93eeea7c,755eb00a,5eba0477,3fc0c796,aee68a07,cbe72772,e5d8b761,15ed6f92,f20028b7,cd06aea6,74e10667,899e78a3,df403f0e) +,S(f3838250,e9a03da6,87139583,2bc6b35c,2d427b60,4cb7d25b,149b6816,235b0e4c,164b211a,60562190,d415bcc3,87d1a147,66e45f14,dfbeda44,833ce45f,b815598e) +,S(b307de85,c4c2e8,4e076d19,647bd205,8c1a3c96,a0261481,322e73f9,f4a2e94f,5af7f6f5,ae7f65cb,b62f021,608473e6,b68d032b,4835540a,f265049a,e506b2d8) +,S(ff92c7ba,5f89d3d4,5273688,907ab9bb,794e5622,f8f300fc,804934d3,b5820e00,3b2e2d1c,420fafaa,e53c9da4,957e22b2,bc76ccbd,99f323d,763fa1ef,f92ea71a) +,S(49630ee0,a8ddf91d,ea678a3e,1dcb623c,688b7c3b,9e39196c,b578d30e,196e63b0,4c1aa073,d1375475,11d81776,e2e59404,aa08db5f,95b80e56,c39613be,fc2bfcdb) +,S(d41ead31,f2fac884,e762ccac,85825cbc,6ab2f8df,a069b2f3,fce3c6f3,d5c95a33,f15e3e23,e19baea5,677390cb,acf97180,86876f96,50fac740,9b6e62f8,b6d40652) +,S(5e62e95d,27ba07d0,781ad685,75a7a11d,df9f2776,48cb5cb0,869ba586,6ff02869,291717d,1a1ff532,e92f0311,881fe2d1,6c8844a,6f5ad7f3,b1ced51,e5088302) +,S(dbdd4f57,1f6d01cc,8a1025ce,3b92ce3d,56d396d9,635e456a,fd856239,27b53bd5,b929d5dd,816bcdd7,78abd34b,c15f2fb9,deff3f9a,aa44de0b,9f7b46d8,b8d70373) +,S(63a8349e,1a891037,9a74a60,babb68a1,4c8cda6f,c2cbc0e2,1a5aca7a,fff7a19f,38858c42,9cfb1e49,5fc90633,ce07abf5,b7c4a4fa,22b955ef,e2c137df,143ec70b) +,S(1805ec70,2cbb1e4a,5da4841e,9e24afcf,b84a3e45,dd6c39a6,cdb6a661,d5c6b1af,193be01d,d3f28479,e352f164,de99d21d,1b3fe8c4,b0af8587,8f21c858,cdadc27) +,S(2d6ff24d,fcfeddca,ab3b19ec,b6a79793,7f5c5d3d,373b9df0,6ec68549,6d075423,b8bbca01,551b2b3e,f6ec3a37,ff020f3b,6b1f5456,69bd8b90,f8a55216,3fb48fb6) +,S(3aa21099,52cf0464,4bfe5de8,69cb2d4a,19d3c4c4,661d6782,967dad8d,cc353a24,68252574,69dd7940,fbdd26a2,483149f0,f71a4b12,fd25b063,73765c52,d45985af) +,S(d6422a71,443b0e37,cbc06f90,4ba1f62d,c2351b7f,e4e0b909,5fc227a1,7f8f551c,ca92a69d,2c9aa758,46c2518,f1ae03c0,d7138170,447b55d9,37108604,f71b9feb) +,S(51e297bc,46529246,a36f8460,f285d713,b1e9ed67,2027eb35,37806d5c,7e756177,5d56e447,63bde166,b456531d,94be0d,7057081b,edbbb89c,be8c4732,13eb0ad9) +,S(378a552f,c061e796,c9ddd101,63851ea0,663f09f1,3fdf852b,ddbafd7b,bf6c258a,6396c9f2,a26b62c6,f33b73fd,98824958,8cbc7c10,e679bd4e,ea0f4ab1,dbf38f72) +,S(bd85fb00,1db4f2fe,95c61f1e,825e65c3,80761832,37be8a86,a20f6fc0,7a586daa,52c21cd8,9bf874ab,7d7e0f4c,d0095d7,6e8c737b,e2ba9d1,a21fb795,d968f61f) +,S(fe68e6ec,3c8e681c,e7230a92,e8762f0,af3e206f,f3b0afe8,be61ab34,2ca076b3,f8683d06,af0c88f6,93a0a6b3,1200cd25,ea2c7e9d,2b8048f8,b983474b,b1dc20fc) +,S(83e55d38,bbe2daa9,f8147b1e,674be115,d919445f,70d2b3a6,cb917a4a,9ff284d1,92d6c7f6,dbbcdee5,8b11a244,34cbe7c,9f9fc0dd,c93f6fa8,b6354a06,5bf90ab7) +,S(fc9cbaca,ed0e1df5,e9d8120,6bb55f26,67e114e7,30347030,8b333554,d0735ad0,d41fc02f,2d4b3f74,f4e9ec00,7a879540,54d12fc9,3d53242c,a45bd38,c75deb9e) +,S(7adf7a3d,12268d0f,c2568d5b,ee296d61,fafcd739,f081e5a1,7b39fe7,40132b05,51aeb855,a84f377b,899392c8,a7daa18b,70ec2a94,7929c93c,67ed8217,41adaa21) +,S(e9631ea3,7da9e68f,eb61f9c5,6eb91bb0,2fdb4d58,d99874c5,2c4af40f,9716aa0c,51d5a6ea,1a5fffae,39c598f0,158272ec,bdb48c4d,faa93da3,89af20a7,d2a1b8d3) +,S(e892f70d,15639bdd,ab70739e,83ab9f04,963e1dff,e2bd81eb,e075173e,6bdd116,2e78cfa8,30b68c55,68f635f1,b260d823,55f38ed3,f5f43c33,b178be12,dc006b4b) +,S(6f3ef2e1,e8d4fd02,2533f4d7,410778c6,ccd9a7be,aaeb3c8d,d9f01699,89598def,c4388130,c278f8f2,7a9947ed,4948f8e4,febe81bb,88bf873d,2d565b4e,3481b86) +,S(cf24cd64,84b07e12,37640f0e,da7e776e,3d4db192,6da8e929,19b36383,15de412e,a353cd6f,a796c46c,49f34c72,64d36df8,6d53f556,a36f430f,7f3f6ac9,3527ca7f) +,S(a2e98e5,36d517d6,528d6353,8bc2be93,4eeae1c1,cd8dcec7,a60080d3,fed33749,205e752c,49a09b0c,8804cba0,62b28ec4,6d9e8f37,9cbcacd4,a7cc9049,47bfb296) +,S(e5ef194,498445cb,718f7c77,6aecd0f1,949a4a49,73e32ce9,a4915867,dc27139c,fc774f2e,1e51f03e,71e637a4,158a0013,5aef5a18,b15ef0b1,e5696338,82bb513b) +,S(311b36a7,1a1d13b8,29c78813,6a989c0e,1b7039d4,d75110b6,ba97f000,749a8d06,2f441c15,6b80f4d,51dce0d9,bceca566,2f3fdd9b,965a0d84,55f6d154,3a661f7f) +,S(324420fb,a5076214,9be852e5,ffb88d20,d1120e1d,2eb9c132,32bdb13f,403a5f6c,378f5d4,1dc1011d,1fd338d,b6073df8,903fb4c1,e17b2122,bdad5eaa,496965b) +,S(7cf4998f,5095c102,a0db72bf,9935ca91,eac814c5,4120eb0a,262f246e,ede142d4,73e6db13,d6db9486,fc870698,7be096f7,7440dd35,67064888,e61dfeea,e98c1fb3) +,S(d6fe26df,d501241b,f8c5e74f,e30714da,7d690be0,91cfbe14,68ed6bbe,23598f7a,102c4907,60fed9b7,239c0443,d01f2742,fed0a0f0,fd7ab9f6,9fb1c58d,c5752fe7) +,S(805ee58e,66ab8020,c9c32afd,4c7fe30e,960f4c3,ae51e94e,da9e5242,af09c6f,19154d86,59fb1837,3d0adf6,daedcfc8,3937af0b,ef9a7d15,f990f60a,c5457617) +,S(491717b1,f22f93ba,d0a3cce4,fac57160,8ad7a746,ba73d375,1713e605,8bcd8450,9c38b3e5,4c89d38a,2307546f,f46bbd68,d4e4ad08,cc45bcc1,575fd120,acdacaff) +,S(a8e23e38,27c54d4f,ae2589ba,cf3c4e1,93f97e59,b11506f2,2016fbe,a9fc2522,ffaa8b74,22b50822,dadd781f,d31b5a31,eb384c50,2fa0bc2,89252665,1c602f3e) +,S(9fee31c6,88b0f7f7,78a39786,a84567e8,34da7ffb,350cfdc8,95d65c4a,afdf69c4,2116e31c,2a0d25f6,48a3ab47,1c897484,d71dd9e5,c678af4a,292a6388,d9e45e94) +,S(6256ced3,f08f1812,ca7ad618,383f1542,baa2bb06,332d4c1f,72d862c2,318854e9,9ae0bbd9,d2fd51d2,9347aa62,12b6c0ca,be530b55,bfd8cf18,6732be1e,c66ced06) +,S(ca1cf364,a5e1f47e,cd0ab0e7,52e785fd,935b8c37,964c5654,2cfb3249,a136d669,17412d75,2f350795,30db27a1,7394c362,45fa376e,d20583fe,b9f7a7a1,2c3b67f3) +,S(19004a4b,28e5352c,7c74def,cf129ca1,cb5c7dc1,5099b37f,dfdb0d5d,1e694400,68ed1edb,9ac650b2,965a4034,2812a692,23b3cf6f,24ab0a05,2e1b8eba,f7335020) +,S(c605e97f,27199d86,18fca176,54e44c9c,8dd20994,aeae0466,dbdbbf0e,ffd1b3c0,606955ce,33ff7b6a,cc6de4bc,4ef80b34,bdf6ea17,b29dada,4ee54f06,f61e9d22) +,S(3e89970f,15e79b51,fba90202,a16da6ec,3d3d5d53,72218d72,bbed0626,31affdfe,5d9e27d0,bdefa8cb,b02ca682,a062ccb0,61a8fc47,b2cc72a3,9b687b45,5f83182e) +,S(c077c861,575ab0d2,944f8e65,8a9dbe54,9fc1172c,6b7b7428,476af472,e625d5cc,c01e7abf,6a3abe2,d2aa2457,76068afd,9ba78fb4,fa39e531,8155597a,90fededc) +,S(8567c87d,c12f1479,5f351d1c,807604c6,636c670e,11edb286,92552ab,382ddaa5,71f0be2a,12ebee63,8a63e848,fc4d8116,e2dcbf99,ecdb15ae,1f4ec6c,84f359ff) +,S(9f1b7785,7421626f,87978ee1,780d0,1e9d0b28,df34c2ad,15332b8a,d94d8dfd,6df504cf,66144d9d,ed530e2a,1436a4df,634a84c6,9de752d8,42e076c9,1f129b8e) +,S(f45c2c6a,2754fc31,c5770e3d,38b19e72,47b0dd1e,5ade8ed1,f2f3219,ea7accce,ee07ec18,8190ce54,e736ffd2,912075a1,128d24d9,b178a7ee,72aeb6e4,9b593f4f) +,S(51a5441a,f3446fb4,cc63ece6,c9650a87,2fa5567c,4918f5b4,ec8668c4,ddba6e0d,413186bb,adad4943,6abc46e9,280a1571,a97ed7f2,a839cad2,935675b9,d167a54a) +,S(adee3e1a,e9a2ab1b,da34fd5f,afd3b3e4,f51255f3,5dbd94c6,8efb994d,afdeeade,f330f0cb,973fd732,eda39ebb,82dcc589,4c148165,428adfa3,b4ff865,1ea83e24) +,S(a8946504,eb084214,d0153ac9,c3437fe7,3ff5696,16e01672,413a62ee,27c97db5,3dd63d46,f74a56c7,2cd5d45b,5bd6f2a8,d913300f,b4ce536a,e504d4b1,b2e311dd) +,S(e34ce586,990e48c5,febc2fd4,70770cf0,4c81c782,3702cb5f,289be0,f4a97205,d1774a35,cdd7cc54,dc68827e,f7c723d7,5c167982,c314dc62,bba17478,611f5854) +,S(7a8a5d9c,edbc4c76,1fdf2958,8289bea,d524edd4,f7cad978,deaeca8a,de47435,559d473f,3a9a7ee3,4ee0a1d0,4acdffc5,6766db36,94fbf08a,5ccef8cf,31e25b6) +,S(848cd57c,62c67249,d84710a1,5c7abc27,93fcba46,497a6b0e,b23c2ad,f8acaac8,a48424a9,59922131,31a763ed,30369b72,b331d9f0,cf46f8a2,a15515ed,6726f735) +,S(6afbce14,1f2d2c4a,c52e7e05,5ba6ea60,7612a590,d74a2a5c,1344cd5b,c49f2f03,910d69d1,cce10aca,bb1593be,2d4d4d28,9745f97a,29fb78a2,a1eb6f0c,a58e4b61) +,S(61f3727d,718644a9,2e08ab04,814c4446,c5dfae82,c26540cb,44fbd310,a5315a11,56665e3,ee6edadd,a154563b,11fdc203,fe4365d1,ac36879f,a30778c2,badab836) +,S(582962de,e00668e7,91741dda,8e86ddb7,b8ff7773,ac1ea51d,1aac139e,a810f3d1,6bd353b2,e004d66,f1e90cc0,7c68a0a5,b532e709,75a7bc58,7a6b1c67,71022f6c) +,S(5c4426f9,f6071fde,a9304e6a,4a2374a2,e2591225,28b62d20,5fc3016,c471b636,ff6e8c71,fccddb0b,5cff9e2a,10c606e7,c571245e,8f5bb5f7,77e0a7d9,733560a1) +,S(ee02633f,c6b41f01,c3c24c33,719db7fd,a9e04b1f,7070395f,e8898a0,efbf6af3,ecdab00c,83cb3465,1d48a696,6a8e4f03,ebecfba6,f73a66ec,4d62a668,48f14798) +,S(fab36b80,e5bba465,63c9078b,b727e0af,c9bb0af0,2e394f9f,2c90e0e,fe9fb816,75173a7f,f5599da0,ab84519,c7c25be4,1f10172f,fea39762,8e7dab7a,3ecbcfa0) +,S(68a89a2,62015a57,5f882215,48c6d3a7,b4ad1f92,f5665980,367107a9,f4cc37a,43ea7b7a,79397dea,c8354436,d53e7731,c94773d1,5b067063,b108c559,c05bc46f) +,S(fa6e2972,87a0e97c,35454378,4a76fb0b,56106727,136474d8,a3edf8b4,e03f95f4,1e80751f,9c127fff,ce28ae,8ce5afe2,eea1c566,fb0a9f20,8030cc96,e1197725) +,S(25474cb7,805d22f8,7a641116,34628321,f086d1a0,40404c47,ebee913c,e9e02a6,2b3aac5c,85ce9672,61757c61,d6a72dd,4ff81e00,87f0b8a4,999b927c,7b069609) +,S(6f7051ef,10fc1485,a9c80ae0,8683397d,c0af15b5,f78fec70,fe4c456f,f33b6689,625086ce,ab7a9173,d9c370c4,c336c63d,2aa85ac7,b8391993,7ffe4118,f6a7b849) +,S(f4720462,2f579de0,701f1e90,558c74b4,ab634664,197c03ed,a85b0fe4,50df4951,c66a490f,f9b588c9,2d17b80f,7f66e5fc,a65187b6,d965e81b,c16039f4,477fdb54) +,S(3b718764,7e722fa3,de42fca9,e3ba181e,de982728,5b8b006b,d51a58e5,ed898c8,bf872047,f3cd3ea,d7a439b,9d4f7776,7175f940,d6cae8fc,930aece7,e1b92202) +,S(5255ba09,df1e199,4c99bf21,709849a1,cd7c4f58,a283e344,6b98872d,a416c40f,a1099eee,e3ad10d9,6bce7a58,839fcaee,1b43e0fb,29ac0300,4e0eb15c,63d1f604) +,S(f4b64a08,16dfe224,595d3a15,8173df8a,7d941a4e,968ac02c,bf87d9d8,93954805,e5585209,2d0cf600,b8b2342a,8371894,f422e3b6,68ec4078,2379a60e,944228ee) +,S(236d83ad,b789d7df,5fde69cd,86d45d5c,f20c5867,b7f2b398,b9373960,b22b29ab,9758044,d3e06295,e33bebaa,befc5776,5db45475,b3aab963,5fea8dd6,77a478cc) +,S(42071659,65af2fda,c9e87319,6dd0c723,e7d61bf9,b71e5e70,667c9858,6371f3f2,fddfce02,588c1d4a,b744301c,6117e504,8f9c2636,5ccafafc,8a6e19a1,ea7b1b37) +,S(7d0c2917,aaa71cf2,e79f1041,5e5e583,ff01b24b,65f1f409,240f794b,d346a452,1e857dbc,c86c1032,e748d8e7,c8f5839d,57295223,22e6bdb6,187b00f1,f489576e) +,S(f0609605,d6e39141,e5e4f0e0,6bb6d55b,9ea2ced0,6a58d4e1,7c46a3df,18257255,e6d54c0b,10826de6,e95553ac,e4689fa4,cb03b959,65472e65,a085988b,d045374c) +,S(86e66299,819b0807,af30c89,228447f3,71fad56b,75f238b5,30bef3e0,b1123204,de635715,b1997f4e,c367bcf2,8f8def4,7a7a2069,3a555b5,396dbe4d,19b1e8ff) +,S(7710dc40,f72bb934,f5f9328a,1284efbf,fad3518a,70c2a0a4,55028bb3,a8b87e9f,d2ebdd39,7dd91ec3,7ffcd8d1,a9b412c1,78f6d228,5e099162,76f9e8f4,a6a28e02) +,S(3d377c80,25607e9a,fd512e8e,7c37a2f2,8d316701,dff7f318,eb24cc34,348d935f,20d2d95a,e8503a11,de19db36,5bb62213,6cd55735,966c25cb,2a56f07f,19cb2664) +,S(812a4ad0,d004003e,fb190ea9,336659d9,7b7d6df0,29f29f97,bc9c8d68,f284a696,6303a024,b2d95d18,f04fa94c,df3d0749,60ed45df,584e16ca,d60a0843,551f94e7) +,S(51cb80b1,9c0dc55a,888421e2,411baddf,6c0eb167,ed9bd04d,294623ed,1bb61dad,d14f756b,f905da5b,6466bc6b,26685501,1fc90892,93633c74,479afacb,c34559f5) +,S(837afe72,82af09de,108711a7,998dd45c,36654f3d,a3cb392d,c46bee0a,b43cfc8d,88b0ae50,5c30a2b5,72c0f69,8e7ecfea,87ea1253,ec133fe7,fb2aff9f,6adc2e15) +,S(ab967cb8,463da438,ad360a8b,3e066669,231fbd,cd590904,fe827ecd,dff3cca7,d82043ef,c614db53,8d06f6d9,9fae98e1,ee6f5065,31b05822,ed2141f3,25ebe544) +,S(5a0b6177,50d828ab,fbf4fbca,576ff8ff,5bd19330,bd357eaa,a5564e39,c718eb49,f6e8d743,e528429c,2cacc478,368d7226,823a45bf,358d9128,9da334b8,5a1b4426) +,S(351b4334,83fae045,ce964f04,f63af62a,6964e0b3,5c1444ca,68d09edc,9a43c9ea,f571f442,7b308ac4,83bfdb4e,87987455,a2a49f77,73220511,dfedc616,20bc18a) +,S(fe64fb54,727ce446,c00dc3cd,5de496e8,2d5a0e9,b13a9a7b,99a96a49,2d0d288d,452c4c9,aee35675,33ce8cbb,e444590e,f5756f14,33865ba0,efd00c4d,26db7d8d) +,S(9403ea3c,773544f4,4eae3cb8,91457ac,89b11f1b,66c3c397,aea8d816,ccab1d49,46ec1e05,d13b40a5,f21ce743,b2ac9756,8ba98b2,8fe1443b,3b0c9cc8,f8a49deb) +,S(e81a5512,2af7093b,b361ab58,534df80f,dac734d,7a863ad1,b080d691,c4396dde,fb33ea54,fbc0c05,f9854f1c,49cfabe,90e259ce,9aafae3,353e8f51,594d49f8) +,S(b7511df8,fccf50c8,192dc3cc,bd79985b,15eaa528,89c4d01a,e21767e3,96bec9ee,c937db57,ddcf0997,aec742e9,cd522c10,d4a52b27,b50104e7,b59c441e,3d0fad4a) +,S(5625f122,4406dbff,a818d98,1e88b5d4,80039f5b,415acc20,ae69ae7a,704dead4,aed9f73d,5265c976,760d094c,e9ced8dd,722122cd,e0b1b34,a8296fb1,dccacfe7) +,S(1b89696,dca54369,27bcf0a5,de32ff1e,e79f6ea5,6f6ffeaa,bce6190e,bc7e2c8a,52bdf0c7,52cc3e5b,1cb9b5df,adccaca7,929046b,bb67daf3,10ba793d,9369b358) +,S(4ef2516d,796d1c0d,9baa8491,7c2db149,e7b89f61,a8f8fb95,e14116bd,473d730d,9a0063bd,6e25255a,70479159,d3089a75,834e54a0,a28c5c61,ea3c33a8,7ab20969) +,S(b36c8db5,51fabcb0,c3fa59e5,9faefed0,1a53b4d,5470ce15,937c889a,a93faecc,1be63f1e,7f85bfe7,2e782cd8,22776567,e3b58794,5f37e2d6,b137da7d,42c8cc10) +,S(7db8ebbb,88c7c04b,fed18b7e,1830df41,490028a2,2918098a,9b34b8eb,c110457b,73fe3f91,f0f8a43c,490f4cbb,f8bab5b,9a6569b9,22a69e9,93ab910c,520fa9c2) +,S(47bb0b5c,c207ef1a,db28a389,7606661d,e5d4c740,3b2858f3,209b7dc0,cac3021f,150e2ce4,44f541ff,7883cf31,79befa4f,5df9c3e1,9da098f2,1d73c37d,1ca48b16) +,S(7803d64,d7622ab8,70a8b927,74e012c6,ab97fad8,4bedfc7b,ac4ce6a,74dad4e6,2662e4c6,1a60a1ff,5485bb34,c1d41d29,3a09a69f,7fe8a049,95245e2a,7770cbe0) +,S(61a64d4a,9a801549,4fa670f8,85988b67,7d317b9f,9b75e3eb,fc6d734e,fe3d3aa4,ff25af65,16e639b2,b6b0dd56,c0e12610,b1b00c3f,d8c59cf1,3fbb1b74,6282d91d) +,S(f2de8cdc,ce609b80,af8b34ca,1c1166c4,3ae0ab9b,e742b510,2ecdd5d,2e94307,d624709e,79346b3e,81b98871,84bf252,949c7f21,861fe6f6,666ef5e7,18ec5be8) +,S(8c740f9f,386f5a0a,228ea52,18a43461,142f744f,87511e9,67080dd0,f3c65d2a,a641bdc8,ae1d4051,a15b1083,27581bf0,22e92b26,a5bbd186,86fb4e59,79f7cd06) +,S(b15a4b19,17448b75,df927416,2795eb5f,60cdb4f0,e657afa9,989e5133,646ae240,e09f731a,226189fb,429c76cf,1ed9fe62,2c148475,92f26b50,c2c45344,ddc73370) +,S(44a65d90,26bbdbc9,89b0dbfb,aa645860,d7a15652,5286a9e8,c67b5a3c,e2dde08b,f2f23e44,bb6cd570,f58ec2b7,b90eb66c,30775109,81279b50,2fc90762,3f12b52b) +,S(60bc8123,92f1e7a2,4eafd5f8,ca0d8fe9,c5880133,209f17d8,6b95cdb2,c9df479a,4d39ae61,cf4368ef,279231ca,b72be100,cfee501a,da7c873c,3db18742,82076a98) +,S(ad5b9079,36391697,61edf9bb,6ed7ae2b,f7e852d4,bae22afd,655a5ed5,754f3618,bdb40449,723089b,ad8221c0,8a46824e,cefe4899,d5e073fd,8606524e,a81a35e3) +,S(c8166cf6,97edc986,6f824df3,82a515f,68ef5d13,dba7e0d,43e85727,c6e15911,86804e47,8118c092,3ab97ef1,ab9dac34,2bc48c7e,3fe24e6c,fbaa74a2,2390f4d6) +,S(3e0a96a,94dcdcb2,9f0df535,970146d9,7f0fd71d,7a4196ed,cd626903,aafbff06,5f6eda99,4651016b,86d28c9b,39efdb4a,b8ad08a8,5c87b230,eaf7ba70,6062a8ce) +,S(e72351db,dcab669a,f1df2767,f5e5f05,ca80608e,29ac5f09,b1ff76ad,43178a5a,552249f7,7a8b3462,c9a268f0,fee20713,5cc14ccb,15914be9,2cd16d99,b2520af1) +,S(a08e1278,71ec784c,4f80099b,5d83c5f0,91978e38,7b0b37e1,f4622c15,80fea335,48e6aef5,349f25d7,40ffc9c2,5de543c8,7e0553f0,54990aef,fec51f0a,9b3585a) +,S(ffb6f3d7,92596141,f7d15157,d1a42bb9,e9b51e21,61a8e297,5aa05688,ba67617d,aea9ba56,8aa7cd30,b9940c75,29cc1e7a,dd60a5b6,8911498b,9fff470,bc4453df) +,S(9c644072,318933ab,4d1459b1,d684c066,d3df3371,d7659a82,fd396bdc,a9fc9e,a115ce28,5a7d9bed,a2a962db,5041cace,9d3b2a3a,12149b05,ddbae7de,30cf52c3) +,S(5cd3475d,8a6fee1f,a6e3800e,911de939,a7568762,4f0a6e69,26ea6160,4ddec04,20063702,1d1d525a,f250876c,c4b49590,9ca8b39d,74603979,8c8b4b39,fa07c17f) +,S(28519616,c035ec81,4e851ef5,191e0545,5f0bbb57,12fcacf3,2b36de77,1c351f88,42ed56f5,5c51953a,6a367398,815963e2,64363681,f9a0723e,7b622784,5cc939c1) +,S(a4e11f70,b3554f05,d0634209,86549001,53d2ed50,1f09f787,99b83308,4dc894b,331b9d59,4260e0fe,381176a7,1873a66d,a7a3b9f6,2a930e0f,696f68c8,6939755d) +,S(c5d7c22d,7a8cc553,7ed85a85,46adde7e,ebddff6a,f7e8a6c9,96f50df4,248a4ddc,dd4749ec,bc029503,1106812a,cee59bb7,acf41451,45883a71,3256912f,be9ee03b) +,S(b56ad6a5,c6fab0,934257f2,9e266052,cdba0bc7,8c8aded9,f0e08490,71770c7e,6aaa84a8,99a4f8f6,3ca8dee1,6df7c090,264e644,de1e58e0,49f99fb5,fd5f4c34) +,S(16c4dbde,37e8df54,aff88810,678f4707,310f29b6,e9e5fba0,384220b8,4f0dec11,4fbdd92d,56a3f76,56b4dcfd,8be6b589,eb02c645,8a247c9d,264fb65e,c84a3a3b) +,S(15e63d71,f02f6bd8,1899f95b,d3051871,84b68d93,6a2ac10a,d29c39c8,d5ba9748,20204657,ae0e1078,6df04a71,938055c,ae208105,ef1beeff,663d8cc1,df478ed8) +,S(3c07006b,8a1e1fe6,fcbc3a6f,fbb7a780,a0008ed,513c9967,853a8cd2,5827dcc9,b2fe428,d4c8d974,72066ca5,ddf32e99,18b5e79a,e81fd6c5,e00b8142,566ce904) +,S(c7f2ddf3,b3dcfa04,91846f0f,2341b1c7,81ce2cd6,ec20acf9,a304fa5a,7dbe73ab,595d0b02,faae2b6c,f6e84bfe,1183ab9e,dcfd6c9f,411d7125,dafbf9d6,60ec5d01) +,S(4c239c01,c05d9c11,3d25dad3,3d14ab28,f94742d6,8c9c748f,1773b739,445bb643,dab0d447,de6a8c79,6809563b,e77c89e7,956f6c9b,ed930d18,f25696a2,e436ebf4) +,S(9e1a100a,c44c33ca,543ae407,f98fef31,28bd1755,6a16e5a7,c1390792,187fac5,540a4e2e,9864a32e,3eedd96a,bb08fe11,b499a551,497e0c83,cdba140,3b303821) +,S(c3b4d7e1,bf3485e4,d028e424,81608ab3,9fe37649,de75733d,78f725f3,63255d18,8f8b00c0,2210cd63,c04f07a1,e10b1a50,f05ad863,b8cbbbff,9b73c84e,c59b5ab6) +,S(dc226233,8dadc96e,5feebb65,b290ceca,f8f5bcf3,e1794f9f,6ade4eaa,b89f3372,25bebe7,cae8b7e8,d755862f,dbb929cb,872e1c88,6b7d03cd,b32303a3,b8b5ab9d) +,S(184b11c0,a52865a4,5f530101,24cb353,dfbc2d26,bdb3af35,d5f029e,6bfe53c9,237a79d,b53bcada,f0a96804,d8072832,4f59f03e,1dc7a76d,ac5fcd01,3838b110) +,S(4ab97ea3,943e8157,3cfaa8ca,680252f6,577ff2a,a93178e1,e1a3dcee,242b460c,b8a6293d,f316c9f1,5fb8850a,87bce47,27d2a38a,d1f5f63a,39d08c92,e9d6d242) +,S(a531936,799791f3,cfc8bc58,4a2967ea,66328c66,98ebad8b,5e5fe8ad,8cd025b,c24d6ae0,8fac8028,a3e0e079,426b94ee,2ca7c845,8efffe1,58f6cb2b,c9046c3) +,S(37cc3686,a6e75e4c,8d7375a9,f291ccaa,937c833,f9e16d77,2591e74c,787b1f7f,557c1bb0,a7c7ed52,93e44cd3,75b04a47,7788181b,b20dc1f1,f6704c10,5a8e399c) +,S(94fab00a,9418e31a,9a229706,112f9386,d537bff,f5f0c4f1,b241c475,4d7336ed,14bced66,1c6eb134,7684cf29,6a303e0f,fa5abc38,ad569011,c09cbfb7,8316540d) +,S(14b851dc,c6b4382f,ca64791c,74a3faf5,adbefe65,b36de8f3,74e12e6f,e3c20e1a,6353d0b,ceff99b8,53557d0f,a893df50,598e0335,249f96c9,4e7a46a,3c02ce1f) +,S(d08e3027,5e05da0c,22991340,8317ec6c,e4362dfc,45b946aa,41e6b541,92c7589a,9553748,22228787,2ae61975,d0969373,8cb346dc,15d07e23,68800ab4,deb5d463) +,S(365ab0ab,6d51bff8,d4bb479e,a666e110,9a838863,2a5f8cbc,b3241bcd,5ba88ed8,bca2f90,ef0d4145,90cf9add,2a9d6793,d678f981,1ad851b,b2f54b6e,6bd093d3) +,S(879e8da9,e1363822,b113e70a,b8072081,f0e34a99,49d698ed,a0f55b4,6704089c,d5091dc9,d33861e3,daec5550,1f52378b,65b25a74,27a04483,c862e0a2,dc1038da) +,S(17006515,8ceda656,b23941e6,33ab3ab,ebb527f9,52ea9876,a8341600,24dc10e7,39a7ce82,b0afdbb6,33e74517,5fef5165,cd44c8c9,d81be0c4,56ee0251,6410b0f2) +,S(574a4f4f,67e294f8,2055793d,e94bf7f8,aa7106a7,f7ef0f2c,3bcbf2a7,352f017e,eac4aaa8,f4b4cf2d,ed8c328a,99b24623,16ee6e08,8805f1ce,783c4cc9,eff7baf3) +,S(4ab81205,32603ea2,9f88ba75,f2f0c4ae,330bb5e8,7f371806,de04f87e,69d5e6b2,1f1967ff,cd42f9fd,1f892f43,f8ea945c,c0135544,acb8010b,8285403d,5e621456) +,S(9a4e968,82b11f0b,5e431867,80dd208a,ba25b3fd,1350ed84,f34f2b43,f03c4378,15653ab8,375c04c3,d7488006,1acf13d9,c5d669f7,bbf70490,44dba189,372f611b) +,S(267b8cc8,3ed6ef12,47a93f07,b4f1195,2fb1de83,6c3e3fa6,782b5e82,80cbd8b8,19bc5752,1a41c7a2,a9dc29b5,cafc66d,7e2016a3,334b4be0,e2811ee2,4ab8599c) +,S(69a8b170,876bb1aa,2faca2d0,a4ed8c02,44d2cfee,a849293f,5ffb4243,256a1017,f77d7a37,5315381d,97ce835c,296593b2,80c395db,a5311a6c,c7fc2c98,d314b4fe) +,S(88aad570,3a4365c2,96946510,5a3a7fdb,6e1f3e66,618c3fbb,ee4c4e13,f333b1ca,10ded35e,c15df656,fabfc4df,a1140b09,196d10af,e1e99b3d,7e1113ef,f7fb8670) +,S(50709e9b,8620f7f7,7b8b6c69,1360062b,cfbea4ef,6448917b,471c3485,55691440,3946b364,3cb1bd81,818b828c,77c771d3,833a1d4d,dc509705,2e5db99d,6cde2137) +,S(1ac1d530,7cf465b9,8f1140ea,bbe7a939,df8155a1,bd656168,55ae128e,bd3959e1,eb02a759,82bfa30,1f9fe87c,75b9dd8b,fe2d64d,7ea89836,1aafe22d,448b418a) +,S(126a8f88,e7f59ac7,3226f2c8,8851773e,873f1ea7,a87342fe,da5d9795,3a1dc956,1ce623ab,abb29b2b,b9fcbde6,a6a6f12b,ec68bfd7,aa98733d,f2452860,bf9349f5) +,S(592fe608,92c09243,20fb32dc,39e7a42b,1f5125ad,1e7d6790,9978ac10,5471427,c4d6ed82,4d33f52c,d975d34f,b9df5698,968a0c57,9b44bd19,8a67fee,9935d310) +,S(babab912,e526a92e,d903a942,ae8ad2a8,930ea5c6,17cbf913,7c074060,6462f0bf,76c7ced2,4318c1b6,c7295d9b,52bbd4b6,707a4170,d020e7dc,1c7b5e92,aee7a4c8) +,S(6554e9c9,bdb1757b,408164ad,1cafdaff,4642a3bb,cf64e785,42c324c7,5be1a903,439d023e,f6c63252,311cf494,4c46a8cc,a3d684a1,d66556e5,dc488d40,e5ddd500) +,S(79ad3f8f,4c429721,281a9b17,d9c05463,f26bdfd9,c856451a,1050b3f7,805304f2,3be5cb37,da868333,4f9a4def,aa8711a0,adb6721f,d4b2bd38,5ad7298e,940dbb87) +,S(fe559c8b,e982e801,7427d308,e50e4d94,d7094aa0,635e553c,c591181b,c9593015,9186fd9,c9fbecaf,f4747597,22b34b72,49fb72f9,f02a67a7,627c1562,ae80485f) +,S(d2b4bcca,38d1b073,5248b4a,7f43f277,8e03f46c,8d7f3a33,ad2dd9f1,70ce0af0,fe0bfaed,846a3f80,10fca999,d0c3b0d0,b54e2fd8,7a0bf751,ba40f560,9eb952e6) +,S(f6b9ecb9,631c784c,8b33a7f6,3fd0903d,baec116b,3dfd2414,4865b297,5c290faa,95fa4ed7,e67b828b,4c685850,4b003928,8ad9e27c,da175b4c,81730fc4,5b063355) +,S(3e70eafc,653ef528,aa12ce46,59c90ee4,32979f0e,9df260fa,b9063f3,d30de2ee,e240ec33,b224a5db,3761796d,2c1285d8,9cff64b0,7c36a184,996cdca4,839a0a65) +,S(dcc76f61,46d05c0d,67bdb161,dc395c83,663ebd48,6bbc6e62,f3576335,a8ee0c59,e451ed85,a9ae624d,4617f11d,67552eef,7279811,6767a29,59708e,3c21208d) +,S(3bb03660,430c43f7,e3b68acf,fe692b,5ed6703c,c808d7a7,503b3536,381180fe,c84c669b,2822cee3,627d4ff7,7c01c9c2,57c57e80,f35e4fdd,eab84a6f,b96fa1ba) +,S(5e266477,dd106005,6a59fc2f,df36b540,e051bd56,c9120b9a,41471c46,b1c5c60f,d6a7ff4a,ee4abbe,cee617,1ad01373,d7916899,5370031f,66f62229,1057e6d9) +,S(c1c13157,56ce83c7,93ca3a0e,12dfc0f7,270a0bf5,38177522,8850863d,37e5e537,750dae34,9090f275,5487778,5a126ea0,f3c2c0b,e3cb9241,326a863d,3179af7e) +,S(c03ae6f7,96692287,4cd10b76,d06ac08b,578511cd,c502762a,cf14eac6,4f1a913a,b3ba2ed0,6cd40752,dc97e450,10699cba,90f38f65,cc4623b5,44d7a57f,250640e1) +,S(5938d249,4edde81e,6fd50332,d81342eb,6cd0d938,f1f02ae,562d1305,cc665bf7,b585c184,1e17e6fa,9924361f,8d06b172,89782433,1d65b3c1,7f2a109c,8be27b13) +,S(e3457146,bf3f5667,e0621ccb,500854b7,a08836b1,e4315d4e,6479b3af,e5c2bcac,3de9142a,5c495249,14d3619,a92dc5e9,f20e4603,5cbe2c8a,95a8e683,bb287fc3) +,S(4187afe,4918d05b,74a969cb,14f54b70,95387e68,c043a581,7dcd1d80,4ca917a3,4e1c19eb,b38f0a15,36afd31d,bda30d09,3c776545,f2d8d823,bc3eae61,35585569) +,S(60cabe6e,ffbc3735,dcc19c15,1abfdf4b,cf082768,e62a1176,f056c4be,ff04640c,7b0fbd84,ee9d787,2896b9c7,19448412,c68a1ef4,e5c6cff2,51ea823f,76d6c4df) +,S(fc6883a1,231355da,115af629,4f06eef7,83447185,edc19e62,b53f3156,e0f540a9,73805d95,d8b2e4f9,d0fb36c7,9f09780f,c315c1b,724c5de6,98d96861,c521a6c3) +,S(90f37677,e738ee2b,3abc9d42,54085349,9cd02836,474624c3,9513950b,c325b66b,90884e24,a4171613,da7fc192,f1bc913b,31bda925,38fc0501,6a55af21,e08bb960) +,S(55e68c72,f76925a8,52d38e8,172e6340,3966f148,2a212131,cfca2497,ca40db3,ebd22c3a,1388485a,e4b48b4a,8b69b98b,755084f7,9f9018e,36769d5,d78cb7e7) +,S(c74f257e,e1bd81f4,fcf512a1,f866b9a2,19586a3c,62e7abc1,112b5946,d5b90e8e,aebcdd14,5555164a,bfa127ab,9f352034,f31a19a1,d36cda02,f51a88ed,9662f44a) +,S(bc63fc6e,d1963da3,7fa064be,f7a371a1,fb471ded,5bf084d,946a6eac,fdbb8d36,a26a6ee7,e178a31c,4ca535e8,e3d1dfc4,dadee69e,140a37cc,a306546c,26a75a2c) +,S(9d11ff44,5e331ca6,fa99f29a,78f5e769,44fbebc3,e3b45a6c,d46ad17,74a1f29d,2f007088,110e9ec,66e5f134,b6d61ae8,70b14741,e9b6259b,ff06753b,fcbfbccb) +,S(5aa47205,f01abec,79b52b1a,2625b773,659166f8,1e300d9f,46bbcdd8,532599e2,f56747f5,c7431031,5b630fe9,b162fa49,26757780,c6ba59e3,6e91c29e,c82fd357) +,S(14dafde6,c8818744,2059563d,1e2cc095,f4bf18e0,f7e41b9e,97a74089,f678ce60,6f6a348a,a4f72e60,9a44b01c,b688ea96,cdc7c3f5,e559ed8e,d9a1c7bf,cf1747b9) +,S(ad8cb71f,1a3739c,afc8a4e1,ea77bd9,f5703d4a,55812381,c5a04847,e85e9950,238d1945,cd5d6094,dee8c6f9,41a19b48,d1eb88,5c986dc4,b8f3908a,508d46d1) +,S(e88df4e2,8b7cb050,aa81792e,ad108c4a,d95e735,6443dc11,f77d70b0,5968de2d,9541f907,f29d79ef,83c25f29,fdfbf819,49f21604,adb5a5df,e939afe7,511cdcd9) +,S(d6b6549e,1ef4fecc,ab56860f,c7a8a549,a354d9d5,63b9d459,9bbfcd71,7631c879,df7a0e04,18a86774,ba87bbe6,132028e2,927985e3,b1319c83,4e1a400c,7b0ae231) +,S(d919b999,faaa7cba,99c79a2c,febbdc68,6d94e07b,3edf8350,6e9a729b,f0f834d0,4b19faba,9b6041f3,9d33a21d,285fbf7d,638f3a07,63e2b15f,df102131,49b94ed4) +,S(b89d011c,57cfd499,fffd2d1,8734f604,83df00a5,6efd43a8,35d5983d,573d902,977f7c06,ed8cb0d4,980c3160,b152a7c9,294d489,2c90fb88,1da40f39,adfe2825) +,S(264873d1,cf9f6f35,d6bbff5,a2405f40,a5568a80,2fa35069,ce422c61,d9f2146f,36b8e9c6,e73044dd,b9b9753e,c682db1b,550d8310,7e3ea3ce,e8ecf031,500b3c31) +,S(d4c388e0,950d24ad,6cc1dfef,a3735bf,bd9e729d,99fafc8f,e4fb5266,8816dde1,3d583de6,27789a58,fd4afbe1,af3f931f,5d12df61,7f5adfaf,95830cb5,4b13743f) +,S(80a2e2fa,40aed900,a7a55f84,d4965f0,2c5632b6,1317e801,b83ec659,cc06e35,9e61e863,69c8a367,72d6a4b4,c2b7bd89,405fad38,4f99514b,485974d3,2342f47) +,S(e36eb1d7,72d5d498,3cdbeed9,b64fa04,1da7f1bd,e324f1b,a734323e,9f5331ea,6c879df5,4a96d33e,6a66895b,f4d12fef,46d5fe48,8d62f073,238fdbbf,d94126d) +,S(7852402c,a08ff966,44a4c1a9,3f7186c1,43f0e1fa,203b5991,d3fda009,1e0a4e76,a9b15d95,3ce9b219,a53da27e,e1b03aee,5431e26c,f035fa1a,a067f1d2,d36d5402) +,S(5d33032f,f7bf3996,14a08ee3,a5b67ff4,850f37b5,eed88e4a,675b020b,90cc4ac,ff5c96f0,5ba73287,f3279907,ebd0fb7,9e0b4866,c32f6fbc,2541d8c5,cbe12112) +,S(138d3701,98eb6569,17b3fc46,c2a3a1c2,3f7c95d9,d355d51e,c85b6062,4675030d,94314f22,6581dec4,3518cd7,61150f31,51ccd59f,3ecf79af,482c4dde,8a24e28e) +,S(3f6ddeb3,4756ed69,de83946,b48281b,c2b60882,d0cd721c,5d76c5d9,ff898c2,be8b8841,12fbfe09,9af67a96,8f4bdcdb,db4469d2,34d64d96,99c6a575,518c48d2) +,S(74676fc7,cf3bce8f,c0c4a774,89b320c4,736b9ed6,171d0b42,17a1433,eeee384e,fce3cf3f,630452a8,1cf3fb72,63c1b5,b66df4fb,864d4b39,7e66c69f,2913c54b) +,S(e0d1a049,cd49ee87,d71ebd9a,95eef0a0,b1d7450f,617841b,590eab0f,3e883eca,99e00118,42e6a78a,d4c3ec3f,f7a61bea,a1a5f8ec,2f4e9066,978e96d0,cbaef51c) +,S(531b455c,c6051fc5,f0f3190e,9523aa5d,2d0485d4,3901600a,aaf207dc,7d2b1fdd,b95f8c0a,b0e63acc,542df948,4b112b2e,e49f53fa,7f3e1dd0,307d9161,7c0f313d) +,S(b86ba09a,2b05e91c,c23db107,9b34807a,778749c0,ed725437,69ff6c17,316e7db7,a91c815f,f8a3b2b7,e5d44357,20e3a513,32cf405f,7501ca3f,b1aa1f59,a01c10ab) +,S(b63b43c5,af63f2ac,3f6e004b,c790404f,a146ea97,94b1bcfb,c4d0544f,2ca3f33,31654108,481b7dac,cbd48e8,c20de95,11406381,ef38fe6f,950b4321,4b145093) +,S(63a09087,e237e0c9,686f2a79,af977ba7,26d77118,29c8ed91,4f99dc43,90c64d08,7771ce4,a5e7d43f,e12b5e8b,c819506d,3b85f52c,fdb0f9c2,92c22bad,790d3b93) +,S(77640a42,4ebd84f7,71734050,7ba400cb,9e8462a6,a91fd0a0,b8f152a5,f5f7868b,516688cc,f422e660,15afa46,b5889331,3cf2d622,d6c829b5,f1d11386,bce41640) +,S(963ae02d,62739bbf,e75965f3,d1b7786d,c3dc6fc,5667aebb,5544db3,157f8a17,b3a109d1,b56570cf,2a5e5056,fd9feb05,2e8f53c4,f2ced1a5,27c3311d,87ba9dfb) +,S(81324144,454cb304,36f365d1,c78ea5f8,9a73706,acc49d5f,125fa282,c28ebad5,77a71aa5,54c0da45,31ed307c,c7fdad32,ab82a4b7,2f2a5154,cc405a2a,fddd3cc3) +,S(eadb105,e80bf2d7,cba9b468,6f6b88ad,34008c85,a7ac4d53,d3fff09d,dcd566b4,199ebce5,872f9dd7,6c14821,622fd343,2b7b6437,3484fe84,714b137e,fa782bee) +,S(a030450b,52b387b3,35cfe8ec,683fe625,884ad73e,2fc1c728,c8d9629e,dd2024ed,895545be,a9009f2c,dcb20441,33f2fad7,ac704ab4,9435fffe,b92836f5,57a114fd) +,S(57e8022d,816255a5,f4d577dd,867d65bc,7d7fdfe9,ed8f993e,d9b30531,fa36888b,9b0b7929,3cef66be,c21b6fca,140e6fe7,9b9f2e8d,48555338,868b6c78,d300233b) +,S(74c14e1a,d52761b1,7206b61f,fdff526,f7008f94,b3707a5d,e5c2a600,97b0dd29,18778822,89711679,c5e41fb0,41b1a806,9b12b709,b526ca1c,44839d5e,3b51e72f) +,S(5a9ce7b6,6368077a,73c09869,38656705,c017faa9,2d9cd40c,69d8e57e,63f8e229,f716b144,cebe2907,928f4618,821af2fc,9de249c9,5ac61bd5,99a550d5,e97363d0) +,S(f0fe4fd9,99c66687,3ab4c904,b9b7c0d2,7f033a0c,7e6c1b6b,4488097b,cdb49fdd,1f4643f0,6f700657,90aa51b5,911b4866,c286128e,de489dc2,8e2d6b64,972738e9) +,S(e86c729d,19347238,a9e97433,355530c8,7b701aa7,d710d26e,6b15ebe7,4796857c,d6260d35,466dbe3f,58d2aab2,1c8d76df,18271247,9715bacb,2a76bb95,5b75730d) +,S(b4e3a39c,8fcb0dc,5a23610b,bbb564a6,765c0135,1a8b666e,d680291f,c97df351,3f1eef0a,7a235130,b5236a2f,f8c9d2a5,fe5f1cbe,22326ba0,54557513,82ec651d) +,S(a9c8482d,a54adc98,4db2d7ac,8fac659b,51c1237,eaf1d524,9bcfcf1c,4ae601b5,446ec925,fc148900,8ef10348,ee167a63,a10686f0,7a01772c,10f7592a,2a544a9) +,S(17adc7b2,c36b1ff9,ea40b398,53246d71,bb973bd8,b469f7dd,fce49aa5,e77b8c06,fc3111a3,8dfc5219,7f41ea77,1682bd8,618f9825,bb2f842f,c7de15bb,224bf573) +,S(328e9a6c,e7397c45,617aefee,130cb6a1,dd26e727,efcfc30c,3d8f415c,187d23b5,6320e80f,e4a57574,1fed0624,c0f956f1,d5b30914,b5da88d5,f63e17e5,64f8b927) +,S(22188680,f765065c,360c52d2,851f3081,b2d3eb5,4201dad0,60b536bb,a45a1a41,b1107c8d,430df246,3b3e91fd,904883b5,cb877b,c10b6f,397a0cf1,c4b6eb35) +,S(620f5772,5919db4d,53b8f89c,5669fc6a,5a3f3846,c31faee1,1e93e53f,b1d20bc7,7d739bc7,4becbd29,2784be81,294185fe,db047d4c,c16c764b,678f9d00,6d27feb7) +,S(49b1228b,b624c71b,2c23e334,b098e84e,d3d8fca0,56303057,49dd39bf,5296666c,3f316e5e,ca9c1aa1,fd5d23a2,613e756f,8ac5e819,8ac16650,a9dff05a,1c8d76d7) +,S(97ca98cb,fedaeddd,b13b86cc,4b6bd7d2,140fde57,dae7b847,c51b118e,e3d6b8c5,1b95c9f,1d6c808f,397c3ec2,a2a2b220,6fdf546e,8c70ac2a,78086ad5,ebe28142) +,S(a679e7e7,3df904aa,e80270b4,d5d57dfe,f5ae819,f240369,b773fa3c,609a1ed0,93201a4b,17286928,be5fdfef,473565be,879cad73,24124c6d,6e1614b5,4e6e5124) +,S(fe17af2f,70887958,1b9b176,4d45d76a,afac0afc,ff50ac8d,9179e53a,c5e3777f,f59728d8,67c3ab63,6d387352,a029b5d2,e9f2d531,7a508894,9a0f6515,f5c4d61f) +,S(f7601ed6,fd64cf22,57cc15e8,e554dc8a,e19e4f4d,ad3fb3ea,a7e819f1,98b3946b,a3292ed3,ff088c22,e9a62b85,4ec87dbf,394cd681,501184c0,b841656b,def0fa3) +,S(3dec302f,cad72c11,54c6b588,ad7f77b2,9368557e,77a723ba,6dcf9357,82d9d917,6484365f,537611ff,49f157f8,6c4bbf07,25094f7f,d8db9a2c,b318ab4e,632cbfce) +,S(a847783e,46ccf334,d7b15f1e,d3aa7dd8,c5b3ef4a,7ced2501,c26d1dd9,4358adbd,7c56f1f3,323a500a,a3496729,ace84a91,6bc6dddf,90435a09,8ca51f6f,5fe5fa99) +,S(dac6ee37,3c655763,b01c5012,fe01518,c3ac1b52,543cfd7e,9ca24d6f,42e4bcfd,6b861af2,f2a82f0,d4c458f2,2d264d82,54f16f46,87e31cce,7199f061,bdbc941f) +,S(27dc7253,90de6a8f,6cd9918a,e3b2f33a,8ca4307d,ca4acf6b,f9c5d0ad,f01b4dd,2a0798f6,7e583426,cca8ab26,e6742692,ee790f21,cb3560af,271b0a09,eb9f8b31) +,S(1c6a5d3d,10983673,5e27dd2e,ff04adfc,7bae277a,870eb4c6,d6379467,de2dea5b,92658db0,8b6b85d8,5c20ad21,f3ad33c3,8de02319,4bc54d0e,4d758093,b4e8695a) +,S(cab35e2c,b731cb9a,402f77ee,44565fa,d6623951,be9deb97,88da09cd,d5abb56e,37bdbec3,638594e2,59018bb,9145c4e7,dfb55b13,bda50c6a,c33e975e,6c5d96a6) +,S(97e4cfd,9e1ec85e,cc49cb90,ada87b99,bcaf8160,9b04417a,70fa66e9,78bf54b6,7423ded2,bc56ddb8,11db577d,f1863fe7,dc758999,55989e4a,d344ed4d,5faa9ecf) +,S(f2a9b193,6f63e9f1,8333cc3b,745fb2ab,7b3749a6,c59e7d6c,42e387b1,1e9d86fe,3c6b6bf9,1c2c4a,859538c9,db95a2c7,abbf8c37,b6e172b3,cc2be8f0,f18b5484) +,S(49024a25,11bdedd9,6c84aeb0,707b5b70,f027afb5,8b4053e5,234a9312,771160c0,22ab8282,914e69ad,8d573e7b,841e9eec,2fdfb939,c76ff330,fb2fa5b4,14a4523d) +,S(781c9886,4bf29760,c44e1f98,9a5266e0,4d25c6c5,f941e2b5,cf92b958,99ecaebb,994a771d,eac92f91,58ecbeae,6227d2b0,4c09df72,c5ee4439,509f0b2f,6e361509) +,S(8f7e703a,ae008b13,590ccda8,b70d2cfc,4c98480e,2a5032bd,dbd5edeb,aefb7f8b,54226771,863fa87f,ec101303,9238da1c,74f9f446,26b50f07,f35d6b59,bb7ff81c) +,S(ecb2e955,ed796695,3eb1ee21,564125e6,e860935b,20fb99da,91556cd4,e5e57bbc,75103469,9b958e18,638f4e00,654d6eae,f5631483,4c890ebb,7e2d93e6,9f4d8bf7) +,S(971cd7f2,9ce90bff,4c46eef1,9df001f7,afa6af09,b553e8c7,792f4ae4,d3f82cf9,d4180c19,7a579e31,f27874df,f29cd17,98e5740a,36380349,6f7dd211,59bda50c) +,S(7ad3b286,3952489d,42cc8394,413545bd,90fc63d9,8558323c,feb8e7e2,50ececf5,5c566bdb,5efc3683,2b22aac3,c0b81f6f,bf656c11,5514ac9d,8a223071,168f139d) +,S(c905b52c,ad0e0281,a90eead3,3939c836,ebd591b9,26787a4,2983804d,e658aae8,df2a40ca,f95aa72a,181f3424,98024f72,f1b9e46a,3816cf3f,ba5ac699,5b996fc1) +,S(e2517e6c,84856497,8ac94585,5c80bdf5,7c074b6e,fdb01cea,e93c17dc,ae4b3ff3,373ede93,2f369807,56afd100,e2f65794,69247690,61a597da,80d10fb6,bbadd3a8) +,S(4d52a8e7,2f3cd95,2e25c8,175e82b2,726a8d95,b735c8d8,a0f1805b,6d94ad78,248b7174,61287611,8000136,dc92b841,de63ef18,a7c9ff71,a10a662,af76ff17) +,S(58e5b42b,e614cca8,e131cbea,24b3debc,9d9390af,469df700,35a01957,3307ac,be4a397e,7809c9eb,2113246e,7812c403,4d42d8d0,c353d841,3001280f,db6bc220) +,S(3f177142,a6e6eb65,ca5e1609,cc89df40,3e3c74c9,e5b291cc,49fb0d8f,eff86ecc,2a445bb0,b648487d,3b962bfe,dc74e4da,d1d98845,cea5f4c8,d2f0c4a8,2bc4c514) +,S(3389c700,9b2b0c6d,a25a9610,4660a164,172a4c21,d0ddaada,c6902bd1,c9f04b38,413344db,77b83806,80647da0,d6086ea4,d1b8394a,a0047a9d,4c21c667,ade67a90) +,S(ecf3f933,4b2b656e,24ea0b14,7528c490,c3a566ea,c4c51885,d3ee94f5,7370b218,3c07fab9,b6404f24,77e4605c,345d3a93,adf9a06b,649206a4,b369712f,7388af0) +,S(a090739b,58310867,5e460a26,7e29f228,effc954a,137f358c,12be2fb5,8011b2bf,a3563d1b,7f242a1f,7ff5e505,280c3898,13251c4a,d9392d82,d3b12a07,e22271f3) +,S(a251cd29,357e5300,5a8600e5,bb9d56f4,c8251f6b,46b4d99d,5dca7b2a,31f8201f,51764fe4,596059a3,b1eb06de,56c6e21b,d58e7194,8e1b6e65,51e53333,5f9721b9) +,S(1f9aafb3,eb39814d,7173b85e,b027ad41,be210c3e,e5c857d3,56288b3f,3b05c5a6,d34526cd,16e7d3fb,76ecdfc8,c11b1bc6,38762bda,b03c1c07,94565cbc,df41febb) +,S(dbd4b724,1fa4769b,db161472,1179fdf2,6df4372c,d3b0c4d5,1e37fce5,317e7e42,7e9bca3b,bda0e211,5f2e69cb,8fcfc333,fc1b8b85,70123816,802b22c4,9634219a) +,S(9ce40b75,7a257205,fdf51545,7d6f9691,7e54a5dd,32b76230,4ec50c2d,3b89b06b,9b128748,851dbe81,255f60f8,1e5e9de4,6b20a545,afec40f0,38beb9a3,f7402e88) +,S(12f6c70f,46efbb73,2150f775,5f597fd9,2a527a33,7039def6,5533cfb,18df3406,7d9f18a2,4988ea,a41a1364,2a1555c2,bc9bfce0,dd62ba87,fa628b84,850e92b5) +,S(3132e530,9b169a3b,7401651a,351f7fce,43471b19,7ded3d1d,cb0b768c,5620fc5d,3e377f54,92c99dab,84f4e45a,7cba38e,9b589fa7,77dfb334,849310ce,53294287) +,S(87160125,8a8a69ed,d52986a9,25a54ed9,51f561cb,8ee9e1ca,6c58b826,495b9977,c5484596,8ebfc8c9,5f317681,78379b88,2e9c2548,b3c579eb,f6da5186,5d51f36d) +,S(82674b33,ef500391,2dfd5f2c,26722df8,19fd265b,3b6e4cbe,239bea50,298653f6,bb6d0457,2adf23db,86b07019,f2f59fa7,ebb4fd2a,ac36ff16,6b22e92c,3952245) +,S(2efc1011,28432933,56af99ba,ea2628de,a518fe02,c5b0eddb,3688c8ea,39d4b07f,d54a087e,bef0923b,6244b21b,f260eccf,e7d590b5,cf98be51,856347da,ea48779a) +,S(f2164194,5de0542c,de90f1c,4be955cd,98f6bb14,ff30ab44,92691985,882fad46,a87f6725,e89afd3d,6f24db13,39fafd45,5f578c9a,104f6509,c83d0694,ef795dda) +,S(72d2c60c,6f9bf0e5,5de82932,88c298b1,4d851deb,6ba7421e,ad22f3d4,2b47ee88,29626eaa,712e6d76,d85b9f7a,7a17461e,132c9bb7,a2943379,c5eee30b,1ffeb1d8) +,S(9bc6dede,ebdbd843,a5534fc4,71212480,ecfba4d,96acfbf7,25e980bb,8a509773,24ef23cf,e1580173,797ffe5e,baff2fc4,3cbd3161,e87e32bf,463333db,5ca904ef) +,S(20ea6c3f,51565fc2,bd5b8eb8,1ccd20fc,f3aafee0,9ccc9de0,733df6ed,8caa9c81,78328fb1,ff260b0f,cea69e1b,77b35679,d6663513,8f136c59,127ec2c7,d9668dd4) +,S(aaa2ee28,a4724d91,f37044a1,3b264ea6,9dd9123a,b3b7b300,999564d1,73057339,250b6164,2ade568b,8a56ae82,4488e740,b9a65f7e,a2b95f3b,4b11b6a3,1b49fddd) +,S(a1e54535,4a8976a9,33c04366,f0361775,824383e5,2c3aff3a,357788b,38014ab1,a6a306b9,b0a7d3c3,d6530094,9efb038f,a0a2cd1d,79bd495a,487a95f6,ef2b7a7) +,S(f2b0c76,18fc3ca9,f9ec5d65,2f39b6e0,158598b3,cb90b20a,53fdaf97,ac58f7d7,1d63cacc,7e8e46ab,47ce7e4a,e5a3336b,8d3d9bf0,f05bc428,f6f769fc,7ec6cd15) +,S(91843b8a,90a43571,4d7500de,fff102a2,fdb53914,2bab12bd,d3f23576,75a9d62e,3cc6365c,7dc3813a,d51cb2a3,d86491c2,c4e38f2b,10a33181,374bb0c7,ac90237e) +,S(f73b2226,8122a4e1,a440f891,14fd8d72,19cad2c2,9798cd0e,3631eeaf,6b125a92,bc14e84f,ed149aa8,ac261f96,6b192168,26f5a2b7,cfb997c8,3f293101,e758aae5) +,S(e87cfcb7,1f2b1c9e,8506b0e5,c56b14a6,52201397,1bb4c53c,855f1de,45644ff3,7e3399af,b4a9f70e,63907a29,c02e4d58,b2e76517,e4f2f2cf,a3d2fdff,808d5b08) +,S(b9657f0a,6de5cebe,47151293,de1fc3fa,b2745a18,bd5c4b8c,62282f26,84404f21,89590e9f,a787f41f,79a0b8b7,682bc353,1ad60107,771233d9,ec303830,e8e8dad4) +,S(b62d02b9,de395843,eb69e8bb,4d974590,7c8d3b26,cd4b13a5,6b4a0e27,44f449d5,173cb5ee,60d3999c,7e795607,bdadf8b9,acf9282a,d7a68ee5,6a204eff,ce5fe751) +,S(b6998e3c,31e9cca5,251a9d89,1aeb5384,fa86c92,74a0f027,8f2dc67,34b5f8fe,7658a71a,fe032a5b,ccb80a1b,1516faf1,5a3e8638,6f74b2b9,b6d17cea,61c3ac5a) +,S(864d4c66,4db88b56,6471852b,eacce0b3,52b55404,46444cbc,afad4f17,204a0170,7001969a,fb35a3ad,fc553e00,b6faeb21,c8fb1af6,135e86c7,f7e91397,a826346a) +,S(22a0ec9d,ecf7a2d4,6f550ff1,5a8f1c8f,6efeff9d,3ff65d47,97512980,216c025e,9d60fca8,97662f4e,947c962b,48522cda,c7ba956c,5a23c3b9,67f46073,af0980cd) +,S(f1be1f63,769f74f2,947eb25a,194171a3,9f9096af,cd454ad3,35809b17,d7e69fb4,b78b3a16,b734c528,c1911d95,895bf873,fcab1440,b62211c,25aa247c,161af243) +,S(7b196c23,1a7650a5,9db8faa7,39b7ffea,488b3623,a0bd7a2c,48b51c97,f5726c76,56e84642,2c430157,bfab8821,9112124d,6bb968e9,3ddd6b77,7ee08228,9a7e1241) +,S(6ad31b05,5a1f1a65,f4e554eb,31e3e048,8570032f,8af2891f,4436c640,9420849a,edeafdae,d10bf173,5de8ffe8,41871909,79f6377b,4cb566f6,3386534d,89bde755) +,S(fb0f3da3,a44c0921,85d90b80,1e7f5aad,6c85d5d0,b9cc4575,ad95ab34,4fa6aa7f,7857f22d,6f9356b7,96020384,919e26de,b9abd707,4dc6db0d,768f630d,b3589b18) +,S(c39b4ddb,edb892fb,2394e875,7c7815e2,f487f81b,45c60749,1c314350,c929d96,530f0c07,68e66dde,e10f0d95,bd66c07c,ba10f165,dade7bb3,77f8b7ad,ac4a673f) +,S(c50b3ae6,d14b11b9,a74dffeb,a5bfb9cb,73652cdf,a2bee6dd,6cc3c912,c312e537,85ac82f8,e3aad88f,9af29cb7,ba66f8a5,8c340d03,a1f32654,2071ba6e,99705377) +,S(a763e636,4e4959d8,9d3047,bff6fbb1,912d99f0,c092fe62,947d4385,2427ec02,bd799a82,a3cea8e1,db94946d,c7d32236,13b008b,da8eca4,921c985c,c022622f) +,S(2abdc992,b2ba838,1da0c2c6,2b35d3c4,ec1a1e39,516b6afe,81fdc7c9,cf3715cd,8115c826,d214c36,36a8fcca,37e89dcf,4be7f34a,2cce7357,3a6c42ea,9e084a66) +,S(2cb83bfa,ef83ab3e,53216500,944b2db0,e8cdb6a2,caad1eec,c9e14c33,a16a07ec,5b1b1199,6e84c17c,13c070a7,99dc0975,3d374018,6f9ce89a,bced7539,7121ec7) +,S(2687de95,b368b07a,7808ebf,e45fde24,d66fdc81,a02744cb,3e96e847,f0a3ca41,5728b8fa,aec73963,236ca282,d1a8946a,b2a26f28,a239590f,9d38bdda,d05a846b) +,S(b143029e,7f32bd1b,a381fe82,8da79713,b53550e,f3cf867,4ef1e952,d4dff9d,a44a622f,ff5fb466,83b69803,c6ea5c16,8d86c673,3ed94058,81aff0a,2a8edfd2) +,S(4c54d53f,cefac583,6fcf3b87,7202afc4,ccd68695,567c7fe7,6068546f,aa9070d,7f42728d,78193fd5,946f3787,6ab124f9,b1045ae7,45df58bc,cab6f59f,a27c6f18) +,S(6b625111,556e3ff5,db9cd8f3,7f610b3d,718220b,e459f546,47314b04,b2ba9d6e,b3ae66ca,fc58bb7,5a057767,8bf806b2,c204b90a,fd114ae8,4ed51378,53b30a78) +,S(b3fb12d6,e16e4279,5fcdc1ee,23d42f9c,198debdd,56217af,5b76989a,271b473f,d38adb77,4ce1d0b5,e41b65c,7c973a27,10c5621f,594e6f70,d235f5e,a4a89386) +,S(9c7c908,6976b590,ba9c80a5,fe12c5f5,ce6bbdb3,5a4058a,3cc59899,82073ae4,399687af,4d3e221f,6168ded6,31644c35,e41606e,94583429,34693221,9322da67) +,S(28cdf6d0,f0374a35,4dd169a9,1c3beef,fc88dea0,4922f841,401ffe91,8bfbddb2,2b8f1d3a,6f001d60,95aab0d9,d6248cef,cf3b97a4,850d1a43,ad2bbb3e,d2ea4518) +,S(1974b196,a25b6446,2ceda38d,d99662b9,7dcd0d7d,15299c00,9b8d14b7,f139e7af,c685622d,96fd6379,6bfc3f2b,6eacd54f,83281ef3,50d2fed0,2507a157,9fcdb74d) +,S(3beafb9f,4cfa3570,3d3346f1,afa48acc,25909889,a60b76c0,6e7774c2,acfe4367,6c8c09ea,7233ce1f,cacc82fc,9c1dd357,51021b92,fb86d6ca,3749bd58,6dfa369f) +,S(b5cf157c,4586fdda,16a111c3,9a500daf,b1aefb07,e32f78ac,a23664b,cef3be73,1d273f45,58e7c2ed,6f46ed71,e297dac3,59489934,b10afdc2,cf0f4270,ad6fd53e) +,S(9bd52baf,cde37895,9439aba4,b1fd4080,84441657,c2b1b36,c45446a6,7b661d6c,87f63761,6dba07e5,96d71dba,f86df28d,c506a123,c6f082ff,47886a93,da068ebc) +,S(20cfa2f5,b391d687,b89cad8a,a4c5ac8d,8624d4c1,ebc94cd5,d47999fd,3278febc,1bd4a896,4641d8cc,f6926323,8b1be2c0,49141736,ee780ba,d2110f27,a674239f) +,S(e54db30e,e18cff40,56473478,2c61d437,c79adc23,51739315,ba845adf,c7e8b6cc,ef631e42,9529a407,cb3f832f,6aee6fb,a26b125c,fd28f43,b9f07e4e,ad8b0632) +,S(588f13bc,3dd3b927,7508ca9a,82ffe280,fabd5cb3,1413e848,2a2aa4d1,78a290b0,95c81a4a,44e6af9,5d8f6fbc,ba3884d6,d6a54057,1835184e,50f5db88,d08517b6) +,S(1927e8dc,ddc7ed4e,62a32a82,bd4a0977,fe24a571,10b1acf3,78826484,de7e757c,e0a9674f,76122a18,dc6004a7,ebd1da86,f98e896,5585518f,bc5f91d0,4699719b) +,S(7b82c663,aa2201cd,71dd7c2f,b8303264,8639f9a7,9de52706,e2deb38b,85dfcc36,90dd6e59,e98c611f,a7162fdf,8fc503ce,71b0ad1,dd150698,e4c21916,d5ded962) +,S(a15fa4f5,97086036,9e9c3946,5f16a458,c7b36ec6,6ad384db,7803ce19,555a2bbf,bd406283,43e40d18,25a02557,6bbf752,35e34400,dfabf022,6cf2bd3d,8fe80901) +,S(2b6199ea,7c42b7b4,2230da51,a895ba86,83950dd9,d4d5ecef,80512976,a0df55af,26ecea05,16faa497,3fb9865,16415ebd,93ce4a6b,e4b5cf11,3507d3e6,6a70b692) +,S(35ad2f4b,b5ba61de,364e8198,f5404ecd,4cdbf26d,7072dbed,d9892804,364b43f4,5481372f,7d1af5e,9e60cb02,ae8512a,6bcee9c,eab1344c,6ac5898b,aeca2e94) +,S(f4eeca4e,2ab38839,8a459df5,b94cf98c,68017522,353aaa98,bc606bf7,5008c6a3,e016b7f9,aba6e910,6a647662,1e7a5b7,12ab97f6,498f451c,21902e0b,9b6c2c2) +,S(6c488180,aeb6c444,78ef24de,21a47431,b2e26d9c,bbf059a5,84631829,a75ec053,ccf084c9,38491cfb,8cf0349f,fe80a315,71bbe0cd,dad9a7d,a4434cbc,9160baae) +,S(a52e5bcd,2214d405,57360828,10ebe384,a94f79a6,579a8966,6f1ef7cb,bc80f4e,c28bb594,e15c47df,9bf4ef2,2666fe4b,d916dd9b,e62b60d3,49c2ba11,506fb79d) +,S(c55414db,3374563e,5c79d9b1,1103ad01,7b7c04b2,3afb5431,8c469cb,49ea9754,f54a4335,7bbaf088,4d18bd70,6f3d69a2,44f4d527,a6dccf5e,52f468e3,752a998a) +,S(b7771609,335ac0ee,1e82539,3fd3cfad,5cb4b06c,98a05bb9,95966e4b,6fc1f24e,f305d878,33f95e99,ff6a3b4a,2b77ffa2,4cddd5af,d253ebcd,d60abb1,438e0745) +,S(da220e1c,c66af350,10736e75,483e2573,91f6d2e1,d355d05b,8471cbcd,4b64832d,bd028d5,5db1c54b,86f6f123,bbabe6b0,f3e52e02,ca48d92d,464311a,aaad3cea) +,S(1a680b36,991edb40,ada892dc,6c102b0b,186bce17,280f9850,ca50eae4,6951ac7a,f03d7958,b0789cc1,43d61fc5,11b70f9f,1ef17239,dd6a057f,ca394f62,225ed9f6) +,S(af8ca10d,b1975668,b8071ea9,5d474b5e,424d461a,e98b5ab7,bc240cc6,44da9c57,e74ea4ca,59f926fd,89bb2bac,61790ee0,50d746af,5e30019c,5b53130b,9cb9786) +,S(e6014570,2ad63dd0,5d98c576,c3d5158d,162857f,7b83045e,d91865ac,bb347922,52931836,4a9fe323,40f13c0e,15c955fe,f718ec64,4b45b141,33fa2edb,c65baa18) +,S(56eedaf1,fec96ae,c2f1e051,9a1c4a76,dc0ccd67,1781cfbf,7804d215,626dd5de,adb8a791,b73aebc9,c6406e2f,83e611b6,286761d1,a6c759c1,de85658c,a4788923) +,S(43c5272d,a3dc8c2f,edb0f5bc,a5bd5f40,fea4bd48,9f367675,cb578690,636fe0ad,52c62fe5,1cc2dbbc,57de501b,839cad13,b94c9e12,12b1cf30,d8463605,f7871c43) +,S(66e76528,7cd0ebb1,9d9e0d76,aaab4230,1aa87367,c3a3f96a,101c6125,84f816da,39a4d3ef,8d263217,3a3a8c3e,d9c1b460,e240cdc6,9c9cbaf9,89535604,a2f28edf) +,S(1a274502,31f1b5c4,9df7564b,f311a7bc,d5123e75,2471c243,65c0e142,d3b292d4,5eb550b4,ffcb5e1e,c695f22c,dafada32,1e967ac3,7e1fc20b,e0e695c4,324c1131) +,S(36f1c3b2,ab6a692b,5d3b1e10,f53b43c7,7d5c4e76,90e089dd,9e70eac2,773c3620,5553cea3,8e56a7dc,384458b,84c419cf,2d493246,1f75f16f,2d1a547a,6fdf0289) +,S(1ff0f8e7,8318fcb0,2b23a1d3,61015c67,6b1a446e,784bbdcb,c088b241,3da40369,39db7b2c,6923a1a2,379b58ee,cb91ad5,554ed5c5,60d5ddba,225c0074,e9fa4415) +,S(c5d7b7f5,d6dddac5,2a2021e8,437f771c,216bfb43,24c57ba2,e8b43a0b,dfd17e8a,78fc37a3,9586cdd2,f1145cd6,f9beda83,43e8ee5c,854c256d,419fdb4,1c9d2bc0) +,S(4af5a3c8,cf107e16,fdf3522c,47fff7c7,b2fcff70,c6c8b36b,7d66a3e0,4b107250,b1b6e5cf,de869937,45ae8632,c5e2860c,76a5f481,ac24ac86,ad135136,e9ff4e04) +,S(37b59d45,86fff48f,67ff3ea3,f31f721c,3daee8f1,a2ff960e,3f77b793,3e35b50,73a7d048,2c93b9eb,4c2f6359,3ce61497,ed455970,9b2ad7af,2d0f834d,6f070d98) +,S(6e9dd180,d5b7c41c,5f529439,e46534ae,b80bd802,b8b12e0c,ccf532ad,a99e663d,e981b043,e936da7f,ecef09e7,cd118646,5bdeaa64,45a00a59,1139eb9e,5628004e) +,S(fde9062a,9f7e13dd,39117543,be4aa5a8,fa10b810,a2285661,720b4586,68acc236,fa39cd20,a5eee1cf,3727df99,32c5289a,96b1409a,5721b9bf,1ad8f42,ee35069b) +,S(d7ef4012,ecc74538,16c392d0,4d1ffdac,76a30992,4c1489e5,159149bd,84847835,b2f5e699,9883a21b,edda98cc,ccc1ee2f,258fe291,c508cee7,39619659,e18c9720) +,S(8355ef2c,f0e37956,56b77adb,5f700f75,47e2c14a,b5f6a0ef,8716c99b,a919612d,d75dc6c2,fdf0260c,6682b16b,42d022f2,f03bdd1b,1e6ef520,da295465,a1988eee) +,S(cd49e795,63655bfc,87bbba18,b72a0c50,52568a26,53bc0543,3661f3e2,2ff159ba,ab28dd46,696b7414,1365316a,c8cd8dc3,2c2f5e01,6ae34302,d103cac7,4e37d25c) +,S(8f93b20f,28f89a46,1afdf08d,7550964a,dfa8df2e,ba2c00e9,9d351b84,2d6e0b78,92ffb09,812b6970,7746493c,c833bdde,6849a2b6,ee7778b8,2b41adcd,62b5620e) +,S(a7b3fa74,4621cc50,f6719d0d,5fd3f2d9,6acd3163,4dad1114,3ece3db5,d114ab2,948a3716,9394841d,68e5b64d,2f86798b,d78c8530,bb8d4d61,f82b5f51,ed0f56c6) +,S(e16b540,d62e3237,361ba514,a11f2ccd,ff72ae57,b37e58c5,d4c3c49d,2cc8fb7a,67efad5f,f02c36ac,a0c0ab0f,ee5e5135,fa7bb3c4,51472d37,abd0711c,6618a7ff) +,S(589645ff,5c3dc06,9d2ff542,5278a51c,c4fff14c,3de96036,b773497f,8940d240,1ea7ba1a,95f65259,c30ce21c,a95b3b95,83d11b10,3c8e633f,6dacbd2a,fbe44116) +,S(d551239e,3448ccc8,9a83b8dc,41396df7,d3db0c3d,f79490be,9d44636e,f5f0d0d6,779118ae,a8db8a05,f2231b5d,923e9d97,5e69a462,5c2ad551,5a8e7777,b1b25899) +,S(c45a22f2,9f611893,d8577d7c,9c1cd46d,82f41b48,a7c18628,ddb609e5,abc434f7,515624f8,5776268b,5a5c74fd,8d87f8e3,3e47648e,2eb8c2e8,27e9b57f,7fee5a1e) +,S(fb8e4546,639d9571,90f2840a,2f72ba12,a72063fd,85f160e7,18477d01,26132b85,3cead630,f8bf75c9,31d19cd9,6f4f3718,1efc4854,b937ac31,c3e0dc6e,363db575) +,S(ec51e7e1,6cbc70cf,1f053860,fd21e120,98b652f8,df9eb31c,74eb787e,87e5ca5d,bd5afa95,6996b7b,357b475,fa7a326c,d6c2505d,1ebf6fa6,feaa27c2,c2685867) +,S(52c497f6,f8b9189d,30fc42cd,9c2a44d4,2d4f70ad,815ccf05,4f50571b,2570bea5,35f54d97,a45e2712,b0f9a720,38adbb27,a31cfefe,c065ba9f,883d36c5,c070e9fa) +,S(2fd360f,1680b7b6,5f49f64d,5a648e8c,97e4a756,fe88e107,91fce9b6,295cfc85,7a88eccf,c4d82e86,72780c6,e1c34bb7,51a6029e,dea0cb77,3d29a85,b0689f5) +,S(7b328546,25307c85,f9ad0c31,ce2c31dc,e746931a,57ec42ac,16231165,74f63d78,6862d363,4360e404,9693dc03,772f4840,4a30f167,993c8f1b,56244c0b,af6e29ec) +,S(af76b473,4cf5f641,25124792,fb558b97,df60d67e,41c2b104,ba27ff35,e3be96c9,21e6d4c6,c1e0d3a0,69520227,c4cf2ef2,8204d85e,26f4ebc4,5d6f81cf,10defdb2) +,S(5b1237e0,54c98238,df2ccb28,a5b42b64,cabac24d,1126c8ea,5520ed69,ac449521,de7ac1bd,4994cce1,8800ac0d,5499c33d,bdde3096,1a0c9028,58de0325,b91ffc36) +,S(b81bcaa2,25743a49,36fec95e,13c8c20f,f818ee5a,6bda3850,870492bb,b3380d5b,6ea959d5,483ea6f3,5b3a4a5c,1987673,a8196c98,d8efe8d0,3aed5884,dcb391ce) +,S(5f6ca7cd,1054051d,3d8a2a83,73be30f3,516b305c,feffe073,ea2773fd,77eeab3c,89287d8,22775f53,61c931ab,bbc43d38,380488fe,5e35124c,2daa5441,3b36c126) +,S(ffb3a36a,8345f9ca,30369f21,f04dc9f9,d5f0282c,d0e1d68b,f5ca1cc0,c05ca91e,21ddcc3e,f5a94fd,8046295f,c0629b61,b1e8fea9,364fe659,d298e0b1,be5a6c17) +,S(51902e3d,8801dff4,e6bfe7e8,8f600d75,42eef0f6,e186df29,3a8c691c,d57b36f6,48a27fbb,cf9dd38,a1ab966b,f635fbeb,35bc3fcc,52f0cae0,d9a3ad5b,2654eaf1) +,S(f1a68a75,8f0f8937,e14a48d7,15c4cda0,679d9b9,12682182,493cd9df,c3ccb345,db85d3bb,b8431e56,d21e8c1f,4eb1c750,225bb222,38da0bc0,30e5da0b,d4f4a985) +,S(81d88ea8,4969d53e,fd0aaaf4,248a3558,f37059da,a4b3d32,da538bf,ca1a4d15,840fe961,11756d96,5c8cea1,32067ccf,31ac66bf,e1086f16,afccdbed,f16a2d33) +,S(b5830ab6,2e236cbe,345044f3,af940029,39b00b52,e779ce10,b02c446c,84163e95,d8720333,b210a391,499f38e,134a0989,254faef5,126750c0,ec2a5850,e1d4a821) +,S(b50caed0,a4e9e41f,f03d16ee,1848d92d,d4e6b76e,4e2332f3,793e8650,20bc4d11,39195ffa,13745502,eed8801c,40f36e2b,d9b636bd,11d62388,8ebab8a6,41d3ab54) +,S(6190402a,3750824a,149945fa,df942c0b,3622acc,b2ee1304,f260593,8de5c333,290f4d4a,73a1c72d,c5ff4228,41e2949d,966da112,5278d082,ab779e8e,d4cb179d) +,S(8966488f,4e991a1e,e34552be,c6246b2d,b9486442,47fda545,f8083b7a,b0435060,7daa3ab7,87283446,a7900c83,b726b849,f7dad684,6326148a,aeeb6233,738c6c4f) +,S(edfa388c,fd246c1c,6bb7bd9e,6d9d335f,9cbd7018,ff2a750b,4ba976d9,dd922b5,c74e1113,f10e6954,6848e4f4,11a5afe4,bbf7dfd5,d252e66,5789627b,b81ce714) +,S(304740e5,1b99d9ae,97de2a55,8dc1abc8,60bb8b5d,a52f6208,af8e28f8,89904951,8ab409b2,3606089e,4a111377,c8a94e5e,75ecf098,4f62aa63,faaf7e18,f93a37d0) +,S(d4ca8aa5,e31028a9,37d77295,96b011aa,c26f58cf,3a7ff671,99aa7f30,3e00bc30,5ecc09b3,bcd9afcd,309280d2,617cbfb7,e4a9350,b4ef79ee,1e46a8c9,56d46fb1) +,S(4110ec3b,ae03a061,59910aac,4f2e4bd7,77d5e055,4eb6920d,aac4b835,2d7cfb4b,c1237e1b,d6f1cf1b,6fb0f248,9e3712ae,5557e4b2,f72ea7a2,2c482e6c,d84eba92) +,S(f7c55f97,3e9df72c,c9da8e04,b1926688,1d53f810,fef5e664,99b81f44,e4f9800,4b45e93f,e02c3993,95238c80,b65533d5,ebd01cbf,1b3dbf44,4d550cbc,4652fa89) +,S(2de3290f,56fbee3e,15def5a0,5d65436b,9d722e3b,a435f269,a5ee0231,857cbd29,f80d2ac2,356ac72,f3106b47,5cbf3701,bf924e3,48e93c9b,f3327b55,bc203828) +,S(c8e3d2b8,21922146,1862d5d3,319c2abc,7dfd568c,59df4367,eb975a95,6e22fda8,d6ec1b9c,e758a8c6,47e718a3,ee8ae232,c416d763,d2887e19,54ae4c30,30404f20) +,S(50c1a147,c117d907,fc831f72,9be19b3e,e93733e3,aa3bf402,e64760e2,edc82065,acebcfda,80706b53,116e4cc8,cdede6d,5aa1b7ec,62ffc942,572f729d,47396289) +,S(7bab8930,55114c0b,e4f7637d,ad165491,c21d6970,c8036375,1387012a,7b785528,6e31589e,2ecb13e,b7bca5ee,39e3bca,fd2e5645,6574a642,131d6178,901c0d97) +,S(dc94ff4,44a12ca9,5180904e,58802ed3,d1be43d9,8396360,e9e932e5,622d257f,ee2a426e,4da3dbf9,8a6d5ad7,9a5437ce,6fdbede1,25e836fa,697685b5,989c86e2) +,S(efb2b411,e66f8e8e,186b0fd0,c572381b,e9edc68a,903e95f3,759a11b6,b6a9dc40,4a7af79c,a1383f20,55bd080b,f410f554,24a21ae5,7b57b63c,bea36486,6c30dbd1) +,S(2f37ff22,26a0c4b8,77a36da6,7a423f59,497a26ca,8066a651,c13573c4,4954599f,f9d1c91,2b74f663,56798637,9de41a46,683a7cb7,61ac6e3a,86d65094,d1e07a8e) +,S(63aa61b2,e24fa178,95688d95,442844cd,7e68edcd,98eb3496,ea071c4,5b46abd,9423daf8,b6c241f8,785b76ab,a40803b0,97da461d,cf6579d4,4308c9a5,e63ac4e5) +,S(58618e22,93c52375,4db8187,34e355ae,27b73f7c,4469d7d9,115623f4,e8e20900,8531be34,22616853,c2c095aa,138819b0,bccd7c51,1380c64c,65ba2500,ae18794f) +,S(61418bdd,2619e7c8,f32c8cc5,34097cc7,4a9a0c57,a38db50b,ad828a60,f658fc0b,acec4e21,774d283b,db9a8a11,115d20be,20cbfcd8,2d67b10a,3d57dba7,74537c48) +,S(79ed2dcc,dd4bd25,67dad04a,b32c9273,39a9c592,95a69b09,be7965a8,c779b2fd,64860dc5,d17e409b,4feef8ea,8a7d7350,3eec186,1fa15f8b,f5576a9a,39f65283) +,S(a20434a4,c51da2a4,c7a6699,84f41ef4,67bd4de8,a628fbe1,385693ee,6b6d8a52,e2a00a0,d00aa33b,b49743ae,6f9c824,d2fe1f7a,f51f7720,cfb0d800,94279dd1) +,S(d8c0bf47,530ff603,c140503e,84fdf6d1,ed908b98,cd27136d,ecb2c4ce,da9f8c61,19e02399,bd898b4c,b9987fb3,4262df35,9b32cca,430e7cd3,aea9d20f,530610aa) +,S(29f06c46,a20b5387,aeb6e490,ef9a7bda,ce16fc2c,8e8eb202,b75973ea,8dc4f3c0,2220f678,daae0cd6,8514c091,a1dd7060,b21c2630,138b5e32,e0d57d79,b7b06d7c) +,S(b18aa504,d9cda828,e67d4f55,ac51c961,e9603d0c,ff737c16,42f1c8b3,fe81aeb9,1f6d7e83,480a9290,789c016b,b62e6e8c,adb4b500,fac710a5,7969bff2,89578ba8) +,S(e7591f42,e649f9f4,477c9cb,bc8559e1,f01eeec5,e9f3a0b4,8d9bf515,6d2044c,24c8777d,5e7c3f7b,2c6fe0e1,cd0e3845,45bef898,aff192ab,c4e719d8,ae466385) +,S(65992fef,50a1983e,bca478b,419ae258,77ce7a52,339ecbe9,2394dba3,8ba72081,32491cbf,baa7f8a,9cf21a4e,57ffa85b,eaba7653,d46d9f95,b4e25212,7bf76781) +,S(771b52ad,e47d035c,ddbb1012,bb89aa9e,b774e0bc,aded4998,86e1e358,ccabf9be,1a897dc8,420a076c,5a723f30,206db0bc,e9760b09,1f698952,1c4edc17,f2dcb202) +,S(a7d5c532,bcaa8ed6,6846046f,d1570837,111281c0,795d3e50,16cd8108,5721d644,13ccc5ee,4bab0d34,2f740ae9,e538d50e,900aa30c,bfe99e54,c69cecc,f18f6aff) +,S(fb504652,a55d01c8,b45ed7,6c71d,9067026b,27e9ceed,c38bf6fc,aee16d50,a150b6fa,f37b0c6e,ce4ebbef,22277b37,44933fd7,a135a25e,5ba8f7b6,1a6b7d0c) +,S(6242a221,115863a3,73bea0fd,39974dea,3c33b794,68e04087,8ebd8bf3,ca09f1d,b806de29,fe9eddde,1556c09e,973fa20d,c4ff916a,3d22504e,19e33169,f6f903e2) +,S(30382a2a,fefc7110,77af1a7a,d8a4a4bd,622635bb,73e50bab,c58116af,d1e8f3cd,d7ff3c80,9845a620,d53299ee,98cf3c6c,499ade93,84791af5,d6618866,3b6b74c7) +,S(b69ab576,13d1527e,990d747a,bab1582c,af995b34,6b25ed1f,df3490c,5549f36c,cf896a0e,4878bc0b,ffa3a750,f83dd329,ade24fa3,76acdba6,dfdc294,768e3f41) +,S(36f6c331,4071ed0d,b2be8f45,fe19be0f,9b37a675,a56679e8,bb49925,9339257c,d593ff7e,a32103e4,9cbf2995,21ad3da1,5b1b44f9,d6c95418,9c794291,b1e6769e) +,S(fc312428,7a9ab1b8,3efce7f8,17f707ae,320dbe77,e5937cd1,513bbbbb,90ed9995,11bce5f0,91dd9ef8,42a46aee,6f3a1d,7cc23da7,381a5f24,4b5a2638,45b2bb0e) +,S(b0de8720,58e1165f,ae1207ec,5ec0888,5f14bab9,35a2fe6b,1f7212f9,7b4913b4,5bab24ac,2589b8a8,c5e102,26a907ac,391289ed,23fba10,b2acdb74,a142b395) +,S(699828ec,db84587e,31ad233d,c27ce5de,a8f4e03e,2c450706,d625e387,12c0af3d,db1d9e5b,9a74caf5,855aef9b,6b8d0c18,c98c27b8,ce0d8a67,c6bd8467,261f726b) +,S(8d133509,d51edc48,97830f8b,3f8a6688,7a16834a,5ea31602,1649e219,cf899cac,9d188e67,2940f23a,39ac6ae4,fa532478,9c5df2d6,57f8b4e4,eca17e02,5560f08e) +,S(9cd47f8c,a9d3ebaa,d94dab36,4412ac4,a74a4b18,bb516538,10da1df3,9efc7582,de1e5cb0,fd5e7a20,322636d1,883b1ce9,71bd0565,a0eb60fa,559b552b,34b42e1e) +,S(1fef4107,648ca126,d5c4fe59,1f190f21,57274d0d,d9c57fdb,ffe2c348,35d36ddd,abf8fe20,87ca3feb,d8150e5e,c66c5d07,45731121,9b759430,4465bb14,55f992ab) +,S(e372b12e,8d3fed92,9e01babb,1a6517c9,ecb54d3e,6d0524ec,42ce57f8,5351d32f,43e910a,32447627,e2d9d5ef,53cb9c0,ab60333c,b07e72d1,c2c6644c,83e7d8a2) +,S(37c346cd,ae9d76e5,7ba2f30f,d05c33fa,3e6058af,642fb1c1,1810b4a0,b97e2dd5,9939c619,e1e49ec2,bf716714,1c23e135,157c7e4e,949e4fcc,b7dac7b9,7d4932d0) +,S(14e337ac,39f0c1d,98333716,a6e596eb,ad0d0688,b815c7a0,c182b546,88e5c3bf,fe45e34e,bfb94cff,a72b6312,a422562c,8ba782e2,16d5ee31,6425651e,e67d3d22) +,S(25517b3f,79da61ae,dd50cd1b,69b1ee36,fce0a44b,feb572e2,e6eb4aef,d751146d,7d2a017d,b9089d13,9a072803,dba874f0,f169ea36,95786e13,7fcd36d8,8b28a213) +,S(7d5957a6,92fd532,b9991383,cae895f2,8554e6c7,83ae3bcf,e72e3678,3475cb46,fa4b9b07,2bc725f8,e35b01b9,590ec1d8,f205f6c1,3203e91d,d9d39954,922d7f65) +,S(77eaf892,c4f9e0d,f63e33a5,1c088e0b,323ddff5,6f854475,b143b458,3e0e2f81,93d0f67d,51abf50,ea260593,96effe6,7f985caa,a9d68250,224e7193,414105f5) +,S(812c11a8,2851f474,e5a0a175,fb527539,7f1c73e7,6a766cd8,7147c9c4,4c970ec4,f9e22a19,a35179de,30379c37,a616d226,666311d9,4ad62b6d,59fcc579,cd024af8) +,S(b633f071,57c5a0a3,7ff5f626,17de24dc,14b3bcd8,4eb43385,e5a59be5,1c371fab,93e70e48,68ab5a3b,e29dab87,8a50e2c3,a09edb5,bf5b47d9,a09ccf59,53b67673) +,S(5e78caf1,9a2031a2,d92e1ba2,1f43f91b,10a98672,5d23ef95,1bdc1f83,cbb16343,b438317e,9446b88e,92206d81,883d5f3f,6497ec33,d144cfc,3a7dba41,db53cbc1) +,S(dd082ebf,88d49fed,50b76df,8e64d3a4,a1d4bbb4,fcdee50,c3ad6d0d,a91e4ec3,9efe99d2,f15d46bd,26d67bc5,ccc122ed,bf5034d9,28bcc946,e4714784,5edb6244) +,S(1ba1e135,62c06b5,63db5c49,7ed46ee5,73399a56,15fbfb1,4e080815,874e6a2e,f298d5df,43111fb,2f050cfe,2a06b3,c9a1fa02,d409dbe8,a225a3e,bec2d8be) +,S(49477847,a590a536,e7370341,5380459,843da9c1,78a1d176,f2f0133d,6ca214f3,3d1b8f64,a1d94169,2baeef3,86b4740c,4eaa84a9,15e4d03,2bd7bfd9,f5d5bad7) +,S(c4336d6a,4fbc288a,2c69fcc9,691fc8e0,e277fb98,e34b7a66,bf29d2d4,32c1339d,64ca0adc,72f0ff2a,f150f01,ea243a51,e91da8e7,480e0553,c7bb268a,22fbd383) +,S(a510cb67,9970c117,49e4e9d9,acdb97c6,d8712ca2,7961ca45,ddc9669d,9e02207,afa065b1,46b75ee2,ff7ada4f,ac7b863c,f4937cfd,15ca2ff9,c0901c7d,faac88b7) +,S(7cd63347,59eec80b,666237b2,abdd6c6f,e5e24a60,9305165,b5bb1a04,2898cc7d,abf7dab,f9e12893,a8040b13,afe16524,1d749660,93cf2da,157e2a78,e89cc758) +,S(e0786f8d,6f339bdc,9ff47416,4070bc08,c864d0d2,6d507762,19c2ee87,61cb7959,892cfd2e,62f4c352,b296a508,455a1dee,8dcec943,f5109add,9d38437e,87ec58c9) +,S(d81f740b,123cfd5,9c5ceb73,47668148,995ca21c,a3ca1b8c,b48e20db,32f6b55d,3af34294,c83c41df,7d5f821c,68e71e34,4656be14,f09d1858,7a204244,6f74f4ff) +,S(f4ba0503,6ffc1812,efbf3fe3,81423d91,38eca2,a67a0f4c,2d0474e6,5db9efc0,b2b3c3b4,4af46f2d,e53b1e8a,adb83d59,4c32b6ca,a7113207,b7993bef,dcdf78b) +,S(aa6f03ed,50640e0d,72fa4de7,ec3964ab,82e7758f,5e6c16d7,78c18296,e3b1a527,322223f7,ecf473a8,36bcfd41,e50f871d,715f9729,93df1359,80794587,59d9767f) +,S(f2d48f68,23984bd9,e8e87772,28da095,4ca134a0,6b43e0d1,1a8843d7,1fd0232,f0b7d9e5,982d0f6f,5ef74bc6,78ee504b,6202f52e,8db7c069,e179d175,c6f760e4) +,S(70e9ec90,7db14601,9741a4d5,ba604187,a7313b7b,500864b5,383b3763,be303979,63f9ef9d,eea1d1bf,a84e0d19,c8f15665,60b4f1dc,839aef5d,b6fbef7e,d6dc6a4a) +,S(23cfe5f9,7198efd3,f34f657d,158f092a,29748586,29983927,9c58944b,146cdf1f,3b8fdd8d,cd82a757,44152552,35de0cae,c39e20e5,f82c7b6a,2afde8f4,1c6afab6) +,S(b1e2b9d6,4c14d667,4de9a6a7,5499cfb,12b30a92,b9bf7578,f8fdbb55,b6d414de,1e91c321,24341a58,e2c6d65f,18f3f735,f9f98d2d,76d124a2,c694db84,37cd0483) +,S(5092db9e,5bde4edd,f385c67f,357e43a7,c8fc8e09,f5c07c14,25bb405b,7e52d1fb,cbad30f3,f96767f9,553c9be3,2adbae2e,1f27f9d5,3fbb2f99,a361056c,ddf52858) +,S(59d39b90,2143ace3,3a1a1e54,a5cd83e9,6cf56f65,4a91f524,af8c8e19,e25496a5,be21c89c,baaffe09,4f2114be,72ff26a8,22db9a1b,818d96a2,bafa797a,3af056a5) +,S(89cc95d8,cf45bab6,9b3f86f7,9e1fa71a,34fa83cd,3d4dfd16,1c9df1b5,817edc16,5eff0aef,63fc853a,f8b65e8,8a45740e,6c78aade,4bcfeca4,c7413ad6,714eef84) +,S(6c2b8809,79398e60,87c756c,443fb032,f2adf5f0,17bf9ac6,44d164b7,d2aeed3f,bc46cb71,c9ed9f46,b34a22cc,e1332cbd,44318165,85407951,580e4b26,270f3eca) +,S(767ca583,c950f7bb,e3aaa6db,b6aa9867,792e0b8a,6930ab97,5c46d09c,30e14a6e,bb90634f,87133104,1c7eeaa0,4a09887a,e5946daf,e88828a,68761cb6,21412d49) +,S(cf742ea0,35c4d9a6,40fd0686,a460ab96,e2015d0,2c15fc8f,333ecb7b,8af4b08d,2bb94f28,bd69b51e,de993065,fd61fbad,c65fc62,90059a8b,d29948da,20b704e5) +,S(84d5d76a,a5a6ec84,52f024ea,b365290d,9c3b6be8,f33a93ea,b0a0ac4e,e6271059,f5565742,f1a47a88,8d0bb802,b002ea6e,f5acea8,864e2f64,fbfb1565,dda51952) +,S(8f5752a,8fbdc1a6,201b6e0b,7bd5db3,cda2eafe,f18cd6d,559724b9,56767d32,d63c0fad,de72b753,6d0c8606,88e0a82b,9f9e35d4,b1db7be7,efa9040b,82298008) +,S(20578def,f94e3597,50ee95bc,61ca76db,f8fc059f,e25e42c5,bf887d49,665d1871,5fc52a36,c95c6edf,46bd5c38,60e151b3,9f123e9b,c58b2079,cd165c1d,e6f33d3c) +,S(30f2b825,739fdf4c,5af0ca08,47f50323,d3ad6eb0,413b052e,525f837c,38f97a4e,d698b076,4417357c,a49b4306,7d73206f,d3d97036,26ab15d4,f11c56bf,4bc820ff) +,S(2350eca0,b4d0c460,12024be,6d458444,b37b20cb,50042830,182b5e41,d564e26b,5909eee2,e3999d60,4cbe0832,58012001,30a344c5,f72ff127,35e66cdd,904623d7) +,S(ea660cfc,45971e57,852d382a,ae8cc6b,1887fe68,dc1b84bf,31f4409,89f89b2d,52297e86,dfec0730,81a280f,9451623f,9e69c320,6f3c205a,f07e56a2,54cd5837) +,S(9cded450,2a7da3bb,77e06ae3,ef398954,7687d21e,df522f3a,cb6b4fd9,d3d49beb,7b13f455,35a49049,277abc34,3cc6f0a,336242e8,7b69815a,e27122e1,d7838a8) +,S(ac8705f2,cf8dcd77,d409a962,f98a6abf,198dd238,3a5eb258,6b0d2def,81daa172,892fa835,a0af6cf9,dd5bf158,44b22cf8,2af258c0,519955dc,ee4966c7,bd5e995c) +,S(fa026b1b,d5e5fe3c,d6b144bc,6b22f7e7,5512ca6c,9525f62,fc7fb4ea,bcd2282c,4ec40de5,7ffc1768,edb20cae,d3a11380,fcc32f45,f410ad9b,8b674d95,6614aad0) +,S(a928eb73,28285c79,5717dc0b,ccb5280f,92f9a4be,5a0b0ed7,67e58eaa,8b9097db,af57cb66,61a9d08f,4d4e9e25,aeeea2dd,e4c88767,c4e177b,37a87ba4,c2bb772e) +,S(bfc9197f,80fded3,c601a0f,1c8c1d77,cbccaab,1c8357ee,4fb67875,cbbc8261,6a721e0,241ef436,69cd386b,d07fa2e8,900527eb,ec3c0025,24bb457e,1bc7aa28) +,S(ae0de043,b332bb4f,91395870,4f3a41f,65e0f3d9,ff77c1d5,ec3add49,6087d5db,34d697f5,dbef1bdb,f581127d,bcd2755,a5a6b32d,73164665,ef84f6bc,145c2afd) +,S(4433db73,29d75b3f,7df0e229,538b7a33,e41183ad,7a7a5e3e,ccf5863d,6bbb692c,3a66630,a03ab85,9f23ae3c,a0a38717,d82ac240,d271b3a6,ccde1407,d0dfdfa1) +,S(bc7380bb,128a6f8a,5cdb971c,31ad12e2,ba593acf,718f5468,285b7f14,69ca2b90,a17af518,9a7b0445,cb37e797,a281c84f,8cf8ecaf,c661e601,4ecc2467,18f1d8e4) +,S(bb53297b,18d2d785,a4756437,70b387d3,ab0fe62,8b78c09f,bb6cc226,79bc92ab,5c34b9b7,cfb3737,bb515ee8,fcff8592,1fe8f30c,e97d21b7,47a4b084,22b0c811) +,S(1accc1c3,f46945d5,7b46b1fa,15291ae4,2f0a616f,df23f1c3,3f0dcf97,53851fb6,bb434ef5,e30fb9fc,15e99b15,b5f9d766,9681be30,d2b0a6f5,a4946268,158d5369) +,S(2fd61a9a,b99c588d,fbe74fde,e8ce95cd,1c0ee9a6,da7ae59,910485bb,9a3ed9c6,2c214840,e2bd764f,74f9db81,43ddd549,3d322dd2,b25790a8,a681c97e,2fda07c3) +,S(4bfd09f1,4cb492a5,7b9ef3ca,d245a0ab,c4bd97ef,12bf7204,8ecfee47,660f7161,57102f3a,ecc42742,657032bd,aa36526c,e67f2589,2775fdb7,e8b029d8,1cc7ec9c) +,S(f60eb13a,8e6485ea,fe653e74,de1c1376,2df7ba0d,4ff0c65f,24bb1c0d,74cea3fe,c5830078,5b74cc82,80128896,f275fca4,9be94edc,744f8535,128ba7a0,5c1d9552) +,S(2b4c7864,9f568eb1,ce1be63d,aaaba4e9,7c31349f,aa353371,6e9123f6,4c57b041,b5dc9c1a,b39325f9,3ead6f35,66c30479,5f817ca1,b3c37258,554c4fb2,51a0ca39) +,S(7fb057e8,5f559f11,b5d41538,6a25a77a,aeb904c5,d1be33cc,bece20ad,57715ac4,2352db61,6fad3f10,a2decdef,5a7fc369,5c8462b3,7d2d5ae8,bde17311,ac6b4ad3) +,S(a49bc870,bfd62cf1,1dd1bd23,9499157d,247ac61a,a9b34210,65d4d029,56f71a0a,b639709,88ffd1ae,ed1b62b1,83ba629e,f5f0c088,f8a9016,d7fa9157,46642e3b) +,S(30b1f21,f8dd3f40,697878a9,fa0b9fbe,d51c1ddd,165bd5f,ed9d1fd6,49ae913f,d5a55164,4628de36,25895fa1,471e0f5,77326d14,132d8ffa,37e0277d,a928532) +,S(8a015768,8aefcd7d,13cb3b98,373a8823,aad11a4e,718a6ea8,5fdb8a9a,6edfd879,e7d92909,4d198910,44c00be,69f267f3,84aca1db,642648d8,34a5b9fe,518e1363) +,S(810ee87e,45d8a5ee,c0e3fd0a,cb771d2a,5a3116be,f4dd7d5f,bfac0dd9,fe072778,92abfc24,9500ba0a,9cfa1725,da4c37b6,cf081f5c,c6cb6a8a,3af889ab,ddd2b7f1) +,S(a0eaaed7,687f6a94,398656fb,3fb15f49,6522c3dc,c19e04b4,598ac4a5,6408d1d9,792a67cd,677ae878,eae040e1,6378cc36,9583b513,bca68fa1,cca3cbdc,37aa61d5) +,S(ca438737,ffa6f30d,9aa695fb,3d29db01,f805f480,ddf1b227,3a0515b9,5f8eba97,56238731,ff5314f4,af6a3835,b30ae83d,feaf0db,dd4449e0,5736efba,8a8cd51b) +,S(b252f5e5,4b67554c,ba3d481d,66a2f223,a633b5e7,f335e357,29928264,e744279c,c6296730,5007e2c9,3fbdb25d,a33a9fa7,411218c2,87b937c5,dfcf8f45,472533a0) +,S(f61b57a2,237befe8,2f1545cb,131acb03,3015a5ee,f0cb77d8,c73add0d,ec0083f7,9b1e0c93,b326a265,eabf096f,f8eedfd5,9f765b51,5007c5cc,d0d3b569,838f381) +,S(30df434c,1051cc43,4ca35671,3957f964,af406830,38ce82a9,5cdf2c7b,55c50f7c,883bc89b,f54c490b,3be0d434,fffb6b,7e829be1,55280401,eaf44bee,7c445424) +,S(fd0ab148,727eb712,adee1fe3,4e3d0fe4,99bf8307,fbe18e4e,d20d5236,f7ac25e7,f5f38f32,df094903,b3219b02,8413cfc0,e56b8ed5,6ad80e5b,aaa00f4e,3877377c) +,S(b4a8fcf2,b406becb,6111c030,ae375f12,79de175,7f2f3b90,13e7ac55,12de747f,d1634039,59a6600a,fa05b1cc,3c459fa4,f1a5fd4c,27ee5382,c5f01e4d,a0259889) +,S(a6c10f0b,33d1518c,8f8b7055,b139aa84,c96e9998,8e8a256c,5883bb44,10687c72,8f0dfa52,ccaec6c6,789941f3,cab90b55,4d4f587f,bb6f3354,b5f7158c,758e4f9b) +,S(7188fb46,e244a5a2,6e38cf13,bf2e3c4a,ff5bdcdf,8d9f78ae,88213692,d866f5c9,8cb07d12,ec743540,3be09b19,4cfb2f1f,c4a85d27,d940cad1,15ab53ea,4b8e0d88) +,S(fe4f9f00,308670fc,48e45208,4063fa94,a6cf7141,d75a6ef7,4f92b474,5bf692ea,5dc45ab4,77f80594,4355698b,e95bc582,efea563a,970217e5,2bd28ede,d7e8cbdd) +,S(93f3b5df,43006183,47c7bc14,3eb046a3,842614ad,78d3cfc9,a6b665e,3327b7cd,ffe5f378,7ac36947,d635d156,7a28fa5d,45c0b5e1,70508cc2,7fd621b4,47b63b53) +,S(dd350a89,e0c3128b,54a3955c,bf802ff7,3a565760,39e1e068,e783ad00,36c13604,45cdb508,3c33c35,fcdbb29a,efddcc63,c4cf3fe7,c08a15d,8b2cd4ae,dec2c3e9) +,S(4f164801,17c1d338,7738b728,96442b9d,66f44eec,e3eeb7ff,ffa87d24,4226e44f,750e6348,490d0ecd,3be07303,5a8e653c,1b1f7c30,d89e27dd,4efedc9d,755b89ee) +,S(b7c62749,aaf79754,de281314,acb4b2f0,271f2a35,fd187307,20349a3c,a4b577a3,f100956e,ddc307db,56542c1,d2c8f176,e0636ba,b04877cf,3dad451d,edcb0df4) +,S(fa5c1278,1dd929a0,2ae4755c,70531cd6,c309261,36ef51ed,7d57c117,c1c8a885,57c5280a,5f08f0c9,393aab6f,eba0ae81,a32f8c6e,2a76c780,a871170a,e37856f4) +,S(e16d6dee,7830b0d,e6cc5e4,9b1cfb7b,50b7d89,57fa4e6c,42ce9925,2e6a29b6,cd5955da,4c1ba840,a3c98d1,7dea8d8c,f4a3d2c0,1e0cf164,2cdc35ee,87fea835) +,S(a2c659f0,a0ef6147,ba84ff26,ca81443c,ac8ba9be,f6fb32f9,50653384,a5db0213,5176a4b1,88b5bbef,3680e875,437e4209,d2fd2462,77c5f84,4a0eaf5,e9d8c129) +,S(7d507179,6a7c037,77fcf84e,62e6eac5,456f88fe,76e71301,76fe458c,8f301a68,14018264,59d3f62,6788fba3,1505c83a,4161674,21dbc2a9,dc14e1a,f45a50a8) +,S(642721c9,20d9b3e6,72db8d82,34ad60f4,bc74684f,11f2ef1a,8171d02e,b9eb1f12,fdde8b98,8aac7393,be2366b5,6e853c7,b72034fb,2cb176ee,770063dc,42b63d48) +,S(65fc35bd,2f604eae,48a1b68e,1d66cac3,627b1498,247d8376,47082702,293c97d,d01018e4,85dba402,17ac631a,9b88d240,de32ac74,79c7d47a,9f5d9188,f8ac01d7) +,S(65c8b230,2e51129a,b81de5f5,22217f06,f5d5360f,af191c56,8f395a33,2b04375a,3201b7ec,117fceb2,b225f137,877ef481,2be4d6b4,52d1c855,f73adb0f,e99b2943) +,S(b82aa6a2,86fb19a,d2eeaac8,9019782b,d0d6009a,8fa07a02,a0d6295,ea8637f0,426f8d72,ec1b08d2,72671566,1f77f470,f334e4fd,3370d96f,b0acca8f,2df99398) +,S(a3222e7a,c6c27f2,8b24b33d,ac78d873,1ce060dc,be055100,862e71dc,e6671a18,6f2c2a1c,4b80534f,8ea53777,71760fb6,5148d47e,ca097fd2,b7bb2f53,bb07ce22) +,S(281ffed7,48a4022b,c663d08b,5681733d,f1343818,d68c8b63,9f4405db,ad7020e2,b5f18609,d8e5c6e7,990808ec,b4fa7d2d,7d4cd106,b7ad2c6a,e356f239,9a535eea) +,S(c520ea8b,a481c220,bab0f218,72ccfcd5,d7014d8c,fe55d1ef,743af305,c0277d5e,e23eaf34,33e4369f,30d371d6,e396b0dc,a065506a,c4159967,fec4475c,8f6bf78b) +,S(54d39ed1,114ec02d,8005d7a0,82178175,78f827c2,1b55a95f,330a7af9,34727958,4aecf190,229c49c9,31862a57,9131aeed,5518cda9,4695e8ac,7ebf7667,d9afb23e) +,S(756b9bf0,1da8d7f6,1627cb2c,b3ce3ba,a9b6450,c2d24596,feae8bd1,2ef67a23,51c47b15,b2ac96c3,5d7b7dc2,d8c57ee9,69b347ff,dadb04e9,cbfd6889,a0ef70b7) +,S(eef22145,6ff200f,ddced960,f422588e,333a437e,d68c04ca,9758d77e,a938ac54,21587cf5,8b8ffb72,6d29aed2,3c984a4f,25df40b0,abc9b7cf,2c07436,ab7e09e2) +,S(b841b560,c0af44a,35bc9320,3c05cb32,250fcca3,f83dafe,30d1dbe6,61aa3d1,e7956525,3d07a89b,2335e2ce,9e11fb89,96e2c146,271189b3,461cf944,2ceee2d7) +,S(14b98f62,5849b798,48f32547,efccc33c,3ead6cd1,a290f03e,618acc2c,1ce065e1,4e7a2415,805a4486,476221f1,ce8234e6,5b81ee60,e1ce5eb6,b6a2e041,ac885e00) +,S(fb0aafb7,68c19f64,17e417b6,f1c22dfc,737bc74,fe8b23e7,4dc1c1c9,aad7ae44,88b83e23,631c58d,c3729cf5,54343721,e9ec7dc4,a889b85e,31cb302f,f2a6ab3b) +,S(885497ab,e34d1745,a3e2ff8b,bdea904,eeacf100,324540c6,86de137a,9756468f,63f3f160,bd266c3a,7c49b13f,c5b06403,d0614b79,17c49824,bf507257,2ac0b948) +,S(52dc7bd7,17e4d8e,8b634439,f6f06b8f,7121a0e0,cfebe7a8,3031668b,9832b8b3,90679373,9bbce1e3,5c48f41e,942d9f15,9161e9ab,273a2217,d9e857c4,3bdd0a5c) +,S(e6ed2c69,a8bd7af3,35591f4e,4dfba7ac,d82e87ee,e2b3bd28,f0f87f02,3abaa7c0,dfec6118,7396bd5,e32ba2e7,a8fc912f,1e54e078,6f2ee222,35adcd22,8feca28) +,S(9e2171a2,c1025129,1757e26f,ba979e5d,6b68c2b4,975c7289,2afe7898,cafc46eb,3dd062bd,210bfc4d,d30cf01c,51d810b5,cf1b8ee3,d3baf490,6bf5d381,b87c9a56) +,S(ef4b8648,3bf209f3,b1c2e166,a32cda39,44b21282,db8acb94,6ef62122,63bc44cb,903d1088,ccc0ba47,b5ac3252,33ef9b55,924e61ba,7ca80bd8,1925b269,3998920b) +,S(64ec6d14,7ecb6e44,6331907b,b9006b2b,fa4fb854,20ab9aba,f1026bc3,4ccdc4b5,583cad3,b41bbfec,d0817207,dd312cdc,26c0411,b888ce5c,c6ee025,baafac63) +,S(128cb9de,125429dd,e5b9b33c,ef9f34a3,e7b38ba,f22dbcdf,8e169894,3f7ae5a9,a10a01dd,33f5a4eb,66091348,c4dbd90d,62879ff6,7559229a,e53c2896,8fb4584b) +,S(a7d2e7db,ca0890ee,e07c4bbb,399a0120,e71fc284,c5b7c96b,4889fbb6,db95dbbe,b8caef70,404a19dc,15670cae,b19d5b74,e70b7492,50390b12,5f559b11,feda83de) +,S(298b17c0,b8beadff,5e6eafb8,ad7d756,8e961468,d8e12c94,78ff3870,dc722450,a0542f35,c7b95774,b1c10f75,3e9da029,ec7a54a6,97bcd9fb,46c98d26,91ac1a43) +,S(31a39bcd,a3d10e9f,6b46e1e,c30b41aa,557ba664,9b12db64,a13557d7,5c592d1d,814f1a6,15382d4,e57b8d41,351fd782,ce7dd9d7,86aa9bbb,c5b1ca7c,207ab12a) +,S(3317f1a8,1afa54f6,ffa6df13,bd3f818d,e9a29bed,7c119b6d,fa31560d,31d81cfd,aa8eb746,4e9acaea,19a42509,a23a281c,e9917788,6d3de977,4398c57,8867e095) +,S(85511857,80eab56a,274cad22,966ca547,3027d3c,3cdd7e25,7d8ed8cd,a5c6ef30,b13de0f4,45d71bd7,db0327eb,15438e9e,84fefc1a,464d8a2b,bcb8c6b9,f59f93dd) +,S(fdbffe5,7e378262,c32bc4b1,e84ae01e,a2d6dd76,28e10b04,9adf6a3e,ef106e83,f19d0c4f,1411ba50,35d3ef23,153f306f,d40b22c6,69e92ea9,22bd7d5f,83a98ad) +,S(7562779e,6aae0c51,52acc7ee,43bed76c,831ba008,82d89c9c,e29a5f3b,8855b3c8,c83c1662,7cb9e1d9,126e07b3,354b82a8,a0cd49eb,3936c14a,8d8d64ed,2a4e217e) +,S(130b292c,10d5b336,4635d43a,fb6d6e02,d5acec2,c2033525,ed72c030,e82a4a08,d534b710,e1201276,6f6fce50,ed6efec7,3e0c3e75,50e0bf36,d5d625b5,4855fed5) +,S(19fecb77,bcfc0db3,e595fe22,e96f1212,b3ed032d,183be5e0,ed4c1b8b,d0501bb3,6b0fafde,2f0636e7,2b4ea946,a0e5c27e,4e5dfb5f,e8b8a1d1,b36bdee5,75d02e81) +,S(ffc668c7,9c6f9fd2,f5c56104,aac1286f,cd4a390d,ca586af2,c348458f,b4130f77,fd7b748,d15f10b6,4eaf4946,34fb4ddc,439919a1,1155e40f,24f3eb2f,482445f4) +,S(b9797c7b,d4112aa4,8abbc827,fae12fd9,6d19f3c7,81626e21,5c26ddcd,b2d4552,ddb0aa81,3113288f,1fd2505b,d23f2a9b,a1ba0a38,dcbbfbcb,46da78bc,5c705327) +,S(9388c9f6,5bda9c81,62ec04ec,5345ff80,da4afe34,7281f768,4d8daa1c,cc3d7869,23ef5140,3f926d0a,d2ebbe6e,48858850,aa98149c,89490e99,65dafeb3,c82644fb) +,S(44cf864,6c2d2f30,e62f63fd,8e145786,80c1d5b8,a27fd496,a8e34bab,5f88270,9784e329,a434b442,fef9af66,b23ea917,edc0f6ca,8d28a992,bf6944ff,26c5cd25) +,S(ebe08589,930001bd,ecb83ca4,45c4a9fb,fd61b229,60ba9848,2e0fd520,1af5a0a9,ce2d31fe,3c271048,24ed891a,910e2cd2,2b99b39b,480ad812,a5d6860f,71ec817d) +,S(176d14f2,5491c2f1,c1d4fc87,a8f59aef,f560bbd9,41872f6f,2a1a6adc,7620f1d7,42c1e0f3,8a3379b0,c5de8a01,11b846b4,35db7783,caa9b84,8084a985,f0e123a4) +,S(74e96d3a,972baa6f,8ad6876c,9494f451,a12adecb,681c4d55,57eb58a6,de920fc0,c2cd92a9,994ad5,f4700561,e8b57201,96e61a5e,b4cb4a55,66959bf1,35a07f83) +,S(6751dff8,5079fa45,7f5df468,624c4a85,db970586,889cd80f,d4514bbe,8de42d60,7cc20505,deeb3f91,3d78a265,cb301c68,49cd5a53,dc029af5,c0db1876,762ba3b0) +,S(f9c63056,24d8cffd,abce64ac,65dd3a09,ebd344a5,5404d08f,b4140a4d,8489628d,49ad5449,bf1b6def,74283afd,2f315f77,3de82cda,d4c9de21,7995a2ff,c44e934e) +,S(69e8c4f7,3f757235,d0e4f39a,f2595cde,f7ff4d20,dd2d45c9,78f32d19,921b6672,8ffc35fd,8a6d541b,3f7135f5,643efb00,14f275ba,d929671,df610748,6f763f55) +,S(3d03e571,ed2aa88a,3309f014,caddfd64,26ae84a2,a526fe35,f30ceb8a,4e645e22,db95c744,6bf115d9,4af9074a,6b274725,adbcbfa6,77f9ce48,535003ad,dd37bc6a) +,S(e5b764c3,dc73619e,51a2afa,fb2292ad,db2b7b0d,e12b46b7,f14b66ce,f8aea7bc,41fbe1bf,41838b6e,9a57fcbc,b3e2e3c8,60170122,29a5ffe1,7394139f,5e8edf2c) +,S(adabcca6,b4252849,76596462,36b17b0f,9d1b4e9d,279af84a,c02f556c,e0f4c385,7d12959,9b411665,dd23b676,57229f84,ae46773a,e13284ab,1cb608d2,ccedafd5) +,S(963094f7,7ea2a7d0,3115e201,45dc6f6a,7318f8b9,a55ab015,8096db54,48e341e7,36bb26ce,3852ba30,dcb1a8ee,ec834f4d,d5342ab9,f7bbe85d,7addce07,62cb22aa) +,S(30ca6324,b4f34e1a,4c3dbe4f,d6dc6b13,a8ebcb35,2f632fc1,5725bff5,f260c508,5c04aa15,8dae7205,3bb608db,1b9245cf,fc57c10f,d015e80f,7afc7532,632eaaea) +,S(8356d1c4,55479df3,adbca347,fdb73f89,6027471b,e528da9a,d9e6a968,8dfba744,c325c86c,cd603953,8f610b03,21b6147a,371314cd,2c41df91,745e579d,8564a177) +,S(996ca7b0,4ae2dde7,b5ee87d8,c077bf97,9a63ce83,cfb84349,c7d231b3,1e15bfd7,cd1d1b48,d75f9736,68b91101,8ade913c,19a1d785,65adcf71,6c805863,fa6c1f17) +,S(8a15dbd3,5cc16f77,b22a87b4,4f93e5e5,810f0503,56e47d53,95769128,a2047738,cf96df1,9ecb6da4,3895641e,4fbd4f27,f00f58ce,cd34d38d,e258fa78,410a1f7f) +,S(23c1e11c,be9f6a93,6c5f8abb,6cc501a1,ca38b03e,f00b31a,79057156,f382ad7c,1d996782,9f709951,2c9728ac,68c16db,1889bcbb,7df432b7,f430ebe6,56b1e050) +,S(d937ad87,70737b1f,d52bfb7f,86e207f1,9e4bed5a,43b165fc,981685e6,24b8e84c,202913d6,1eb467fc,b488fffe,5914f853,73aaac20,1acde09,ef975cc8,a05fd181) +,S(6457f59b,2c744ca7,89537c59,6485abe9,7835368b,47de3667,4740ecff,72e5596d,30b6ffac,65e34e88,43681e64,f041870b,c85b3b5c,86c032b1,e290848d,ad2f7a5f) +,S(7101d56d,813abe1f,c50aa99a,bc7b2363,9532d79d,facc17c9,f2a5b4ff,50edf82e,62a0b9d2,bcab5b18,9075f6f0,e648a4f6,fa66741c,389a4196,a4c5ead7,cbef14d8) +,S(2dd4cb3e,5cb59cbe,b961af3f,d1154fbf,c21916f1,d5331ce4,c8a32ad6,8f7ad818,397dde68,7b1f6b5d,38e457ae,2f5fb332,74917949,801151e5,3d4fe19,9a34289a) +,S(509c6fcc,ae22b09d,b8f3d191,434e584c,9d17dc76,c268560f,2290d81d,53ed66dc,cbf69e20,c3f9ada3,41e32dfc,581f0ba,f015413d,735d33a6,260e0cfa,7a4e4d05) +,S(71babe5a,9458bf5e,112b23a5,3f87007b,66ddd721,32a45a34,2a9c521a,c2029aae,55ac872,a0275be6,4f569901,d84dca32,ea13e2c6,cbe608ac,de228185,34e031a3) +,S(f5f2144a,46fe975f,82b91da3,a98ebcb,6d5769a3,4e5fc50f,3ca640fa,152fa7fd,2fc05c22,2b20b895,5503f23e,627558b0,e023988d,f02993f8,f495750d,db6344fe) +,S(d6f274fa,fdfcf64,25972a56,640e53b8,15c4d213,8e4a72a0,b8ab3394,2955e416,738e267b,2fe0d9,5774afdc,7c4f559b,7bfe2824,ea6b7a49,d3220eb0,460ca733) +,S(81a12fcf,cc6acf7b,89f30fc,8f61e2cd,7882f664,55923993,2b8d3f9b,1d6e11e7,a8dbc6c1,cdca67b0,64b285c4,e2f69242,cf55f06c,5eb28868,d9bab656,eaf9116a) +,S(57019cc4,941f6f5,9ed34305,92f35a83,39a495ee,fb3e311a,fcef9001,cb8123be,a3d632f2,54083f5d,6f2857b6,9556205f,59578908,9d8d8fd2,4d10bf1a,e6d2e635) +,S(4205a71f,504362cd,576c4d84,c8b65252,3d4227fb,d6aa28a7,e7fc3d70,d1387c80,781bfe55,7fecdfff,c54d1c1f,e147792c,5ea7a1dd,7224954e,e110cc6e,18ab452b) +,S(1c42ad3d,f90472e9,e5c041da,52476ea0,896a2032,ccff22a8,fd7bbab1,4c3961f3,a5072a70,be702dae,f9f93148,4bdfaa00,1e2f2ad6,7d79f46b,5717147,17c5499c) +,S(6c9225cb,668ecf25,1f7862ad,999516c0,145faa37,b4fe92eb,561104f8,f1dc2997,8c12c1a1,e372baa1,4e9b1443,d3530548,d7d1d05b,fa354c7,f47ecab3,23993a31) +,S(72a0fd2d,eced2a05,6885dc81,fb61e881,b09104f3,8650a872,44e40471,ed189992,d9c67490,43bb493d,9aea4a1b,3a50da8a,e1c48523,9a480442,32406d2a,68487e6e) +,S(b1d531af,8faa24b5,69945ec8,1448915b,a46fd13a,f7fecb8e,16cd5d03,52c6c2ab,b3ba6cf4,bd36bee,66deba09,35bb85e0,b9ff7e62,5b5c793b,543a091b,dc83292b) +,S(da79daea,d6ea65e1,4e8747b8,b4546560,a9e5a99e,eb572f17,f2ebcf3f,9a307a86,f5b3c430,e0f2d4aa,2f278088,2d683c48,d84f926f,6feea88b,10e06930,6567a290) +,S(1fe7fb5c,99a69a75,a2276ca8,92f67da4,951bbb4f,ee4df8b4,a54c9833,d0d33869,e2b2b4c6,fe0f63f,d97fa179,331e9bb,55786006,f0425e98,71452aa8,361f177a) +,S(fcdb7de9,4eacf36a,9d662371,edd2b535,af33de37,1985ff49,6ce5293b,9d2ac00a,e332723c,7a9708e8,5172e56a,c4291760,baa17e83,72c98dbe,83a186de,77c2aa06) +,S(daeaa6cb,19bdb4b7,78077495,a9cead03,3be16d2,97e742c6,97ac18ed,e5b514c6,4545ca53,bde3c1ff,6bf32604,ef037da,93134215,7057ab10,cf6af451,e7753f4c) +,S(83e4b4c9,1a923321,196fffb9,b45d089e,7fa1f6b0,5ff45a6f,d099f7ec,fe283088,926c28cc,bf405fb1,17c5f168,20216226,4c89cda2,cf669937,2739ea05,279325d5) +,S(cd7f2b53,8363914b,2e83f1e1,c9bced9,32a682fa,cd72b46a,eda578c0,640089bc,ddf6dc27,a5281d3,b4d66af6,8fc80f5b,16cbb7b6,ebfff06c,6902d38d,4632ed2e) +,S(6f3f5a27,b19dbfc0,238bccc8,a9adcf95,adef6480,fd4ca405,454509b2,97a40928,36a56db2,abf62faa,b2255d86,d8a46aec,361fd2a8,65740c31,babb2e2,c551a85e) +,S(f7aa5c92,a523b86b,c27cf714,51f7dcec,fa18ef3a,9e839c41,a8b20c4e,30ba3b77,fa7d3ce9,8009f23d,f5eae927,acf1b28d,5ce4a2f8,8a92da7d,fcc1acb1,3c8cadc5) +,S(4adaaf95,5bfa6a94,b518f7f5,b0ebbdca,493798f6,72293e4b,36d5fdfd,5f641b89,ce675ffa,cff579c0,61e63c2f,36e77f3d,5c2571b3,aa99d3c2,74086b22,a862577c) +,S(2d737aac,3600371c,f6b638e8,8a29884c,978b783,cb843922,bd449e95,814db692,205d944f,13b21441,76d8276d,74da68e5,142aac9f,ba632568,79753c01,e54cf4f) +,S(7cb5d365,10ef241d,ac378fc,ebad8738,e8f2e6ad,6d838731,e5c82bb9,169d51d4,33b088df,5a572e8e,1010886a,d01b68f1,9f345770,81a465ba,8c5c784f,225f6510) +,S(9872a376,e530e254,8b623b6,b9dbd6d4,d123f2f7,30579f47,4d910831,7c714c0c,3de01ddb,3145d81e,6ac002ec,70086f74,6eb2bdee,6295f5fd,9d2cf8b6,1b222e58) +,S(8242fc8b,2e848618,ba0f26c2,6acac090,8eb21b4f,41a08b76,beb35f85,3b8c2f33,58b94d44,3379ea4f,829fc809,ce2632cd,78d8675e,45a29c58,e29fda43,785f2e9) +,S(88800a95,cf1682df,4e5bcde3,a96de21c,3353751c,5300dfa0,d0f802d6,7b60eeeb,2a35b86a,4e213e9e,c53dfe04,d91afb48,25bc8794,a1574ac4,53e81ff,4b6e453f) +,S(3c8e2755,9611937c,b7e2b2cf,8a87fa5a,e5c696df,fc6703b7,e1e65ac9,111ad87c,c54d129a,be0c774d,dd415707,bfabafdb,daedd1bb,2ea9cff3,bcfae0e4,55c916e) +,S(281af73e,a1f092c5,535557f9,3b5a8c94,54165f8,76650801,856bf926,19f06cb8,deaa8495,30951f12,ea157714,3caab5fd,d30f0dce,ac9b80bc,fcdb3477,dc01ea1c) +,S(6b353e5,3202f63c,69bce96,30535f11,1939fa,849dedb,92ad21c4,89f5174d,bd961eed,c16f285f,2eccfa69,d37a6d63,be5fad00,4858c80e,6fc4dfb4,2717acc4) +,S(68c184f1,a06685de,fd20f36c,82b5446,7446d5d9,8fc9c312,4852bb02,f35ed91d,486a3d16,7d94c66a,31f9e134,1652f658,76d49379,f3e3429f,e9f2da30,84f56532) +,S(5e884531,fa011576,3d36e1ad,74b22e23,f765db14,8b8e965c,80f7c9bb,7d561bf0,34c4f03,b137b627,3fbdb6e4,8ac09ef9,bc3c8ccc,e720853c,61ae58da,ee3a0cca) +,S(10c13f0f,313e5ad8,ea61ba5f,ed509aef,5ddd3016,c3339eec,ffc8f9d8,6f131118,28f6ad5b,324e44ae,64ee65c1,b86710a2,91a8e71,c33adbcf,a84f18fb,144dd67c) +,S(aa99d8b3,1031d4e9,8c078a68,7254968a,9141c710,cd8e4842,5a384bf8,414f5c5f,ee6eccfc,1dbdd5a,c9080cc1,ffedbc6e,64fcf847,ab9c0ce,fa91c4fe,d1de44bb) +,S(f087945d,a464e66c,4c73b58c,5034f057,b96ebe34,f5128397,cfadd7be,22ac6100,c5485411,d78fb395,3f229109,45aac354,1a2b2acd,1d95c38a,f51f36dc,d3cd92b2) +,S(2e4d8752,ac21c22f,e4d465e,3d2f5ad8,d9168080,b2b44930,e5de75a0,d9bf91ad,92f394c5,963c0817,500d5a98,2eccdeac,aa55043e,27a9a035,1a6ce245,a8d048bc) +,S(68b59755,44feb608,15a6ae70,9c2647b1,5c7fe073,aa6af8e6,202b9782,83daffac,b3745e92,fd86bfef,ab9d3d26,cdaf57c1,2a329889,cf646b6f,d6cf869a,f727e0c) +,S(15f5f668,e9576897,a287f131,bcbe1216,84f7a108,3c28c09a,afa77074,63dba49b,133e33fe,9bf06bb0,3b814938,7a099da4,77a3e758,82fb19a4,463ab360,bfbc368f) +,S(f2bf3cc8,ea752c11,db2ff594,d3f9b085,1dc9dff5,7999aa39,b5af2a29,30d50491,6e01a801,c5b7e4a0,a16af1ff,b011bc12,cb0483dc,6127fe52,c992b07a,9fd77635) +,S(1b04817f,46dae06c,120f8088,b3cd09e,267d4ed2,db14881b,bc32b5d6,345dc54e,31634e28,56f61b80,56a414e3,94a34ced,200bb172,e9a9aa07,6a224329,61f55ecb) +,S(693f066a,bca2046,ffb860f6,5e769ca2,3d1f46a3,6c09273d,afe5eb89,d2da45c5,719dd749,5c1b1938,a92af84d,eef309e6,ff1978b7,9adadb96,c58caf2b,625fff9) +,S(3fb25a02,bb232d18,c798f688,b16193ae,cb2eb9f5,e124c999,225f0720,63417008,90db4fbe,fdbf8a26,ff9b4afd,355e3771,c7c95891,68e2abea,264aba44,ad74707c) +,S(4c878f4e,6ebfed8e,e12a0a6d,17298b70,79d9de5c,6a7b5359,5ddefe4c,db82a79c,837592e6,927938cf,dc82252b,2cbfd9f6,cbff1950,405b4511,f2c21fdf,a3f72715) +,S(5ccaf6f4,2b75e152,49263cb9,5fdb34a8,770e8828,98a1a0cf,5407c48b,b9ad4ba0,70851419,379e5e2f,dca9613a,a9f92fd3,8ad8904e,e0ce0048,b2510943,ba8ee24) +,S(455907ae,713d1ec9,3792d488,7d9857bf,a02bc2ce,abd2c599,cf576f09,f7d09d11,1fc9ee5b,90a039f8,eb3200e2,ee58022,3f0cc699,60221d67,86f0deba,f13ca6b9) +,S(6f7acd2b,3683482f,c2c2d55b,eb62a89a,37578a34,417bcabf,ba7c56b7,bec14f0b,6049db59,b6210e55,b06401d6,17247d91,64e84e2c,b8de91a4,d4998c15,6f46d621) +,S(100f00d4,eee4ccf5,ea2558bf,92bec83b,223fa214,ad692ae3,b0a2ac93,c546d558,fe055fdc,1ae02552,1557db5b,96a62c92,556f918c,ca908708,46ffa1bc,8192b65e) +,S(8650c359,664c9f15,935dd776,bc6fbcc8,d9cb02d4,c22428e2,aee3e3cc,6e9d0c6f,89dba800,919866cc,8c16895f,785fc9cf,2661f78a,9e065472,652b71ce,d5ec8732) +,S(22b6df12,b3932756,713e2ee8,2d296c64,5d10364e,cca1ff94,9b477fa4,9a2ce5ac,ac58a22f,42769cf1,e2e23308,b3b5f139,4d329323,4bbd6053,4817ab5c,624e995b) +,S(ce87a23a,1554ae1b,9579ae96,863128cb,926a0cce,e51f17db,75155607,754b5992,4bb953b8,9d590216,e326f23e,66768c0d,17626262,6fecf80f,97435b50,d5dbd503) +,S(e3ae6365,29e3fe6b,cd1c89da,d72b17d4,8bf05c1b,c487ad41,d3b97838,a2cbc19c,4634e222,316b6ee6,c7616cfd,cddaee07,7fb2cd0d,26dd9f81,9d0ba43,313b3f4a) +,S(2825cc59,3a0678fb,e0d37d42,df72037b,6be96e98,18c52c49,fd426d75,324bd620,ea0079c9,2ef91a7c,dc587343,7b454763,f2fd4adf,561cd023,8379c8cb,1d281f6e) +,S(a6b2a170,fb23ae2f,943408ef,60fcb145,106735c,8876238,5d0fdd9b,75a2c46,1ab40091,e000012,60837529,58e3134,5f260890,d1bf6930,ddccedb1,dce20255) +,S(99a36f38,759f0a70,d719e3d5,b741a40f,daef1ad2,bcc65293,3992f134,39ff339f,a36d4b07,a7258053,61430332,6be79a,61ce8eb6,97944c6d,8bbf433b,a565bb66) +,S(e511e0a,de5a9be1,1b8513e,a5706258,6de09e2b,e2df739f,d647fd33,7890d36e,c6cc03ed,e9e50830,bd5579c5,9d6db693,dfa5c057,b1c214da,e4064804,9cd7ed70) +,S(bc9de66d,a406288c,a8a94e96,5ca16dfd,379608c2,63222a24,e3fc1116,20a82125,ac471a7e,579cfeaa,fdfdb5ff,9cccd4e,dca4202b,1b0149ab,ba9f6c09,aa219626) +,S(e98cd505,bd593bc1,496b1203,436f6038,ebe3fa4f,361ce4a6,54315402,a74c3a4c,1350c197,1c7979ca,7464c4d2,39b24a55,a1e50812,aaf92479,d566fffc,9135d977) +,S(47c0c788,2490ca53,37cc668c,5a549bde,dac661cc,f77534ed,d11f7ddc,9e0f37ac,ece10949,be122263,26819032,a2d952c3,60b27e2,7e527673,e8fcef08,a8f27685) +,S(e8224d65,35ea98a5,e3fd8833,7bd167cc,776f89ee,7d0ccfdc,46a15fed,93bee5e3,44b260e0,e0b1e1e9,383041cb,1dd985e7,22edb214,ae58f784,f174ba84,ef51c59e) +,S(c195ee35,5880dd77,67e01659,ecaf07b4,571e324b,b8a1a4fb,75265af2,3ea74709,95c39cef,f781f53f,31bde05b,d0289313,4e478b2d,1c55e741,aef8035a,2ecd4226) +,S(60d989b9,c9cccc66,139bbfed,e2902a95,fb9ca9a8,6c2e863f,21eceb4a,7d73c4bb,8295928a,a48ec1fb,775ea29d,9da1ceab,47e82f3f,1e6ef7fb,c7505e26,92bb51d8) +,S(a33b33f6,9db29609,8cfd34,caefd3e8,c3c0d863,ab695b06,b47d102e,f827fe62,669d9d96,842ee809,2cc31cfe,baab0f1f,4007c3e9,e7e41be3,7a08d221,1c6bc905) +,S(bd25afea,d9b8c833,fe332a2a,a9f3b627,d8328152,8fe1422c,5da90163,4b971584,35bb66e7,35326f67,63f4f38a,c18f8412,26da97da,c9e66902,f28904eb,b49cd78) +,S(4d7e208a,4264b565,d8563cd7,80773012,581e8688,a62921f2,d6a334c3,25625279,6729dd4f,b45ecd25,2c5cb033,dcb2f520,dc928ca5,71026fdd,b42943e8,b5da9988) +,S(5dd46f97,fc740db3,ec56348d,ed73fbbb,c440e3f3,33c64a3,a37b7a73,7f0e987d,7e2d9ee6,9e1c07a4,b764cac,aef3d780,e2d43288,2863f76e,35ff4cc6,832ede1a) +,S(4631992d,d72c02d2,2073222a,d35917f9,2770198b,ad13a847,8d3c9ca0,6ac91a3f,e28ce87b,35a69d5,c43b685a,e59d5f9d,ccf187bb,62517a92,90992b39,86d9e1eb) +,S(9153ad32,32177422,e03b6739,d5654209,7fe04d22,28b1e873,f02e990f,8936d1e3,8eb9f3c6,b54726b0,b4e867e0,5ab2fbca,e76d2e20,ce07983d,6edbd5fe,ebd0cc8d) +,S(939a7349,28fd798b,5036e2e9,60360387,b9c080a8,982d4530,78415667,848c2eff,30d2a2d9,5890d023,7d117cde,2eb3c532,e419770a,8783a7dc,dfe40674,709776f1) +,S(8e67bb29,9f11e01,b50be7fc,bee1f73a,5b335f5e,5ece8619,9a514156,dc243f3f,7fd0cb92,d6f9cd8f,bee9d337,90a4492,b8a7fa02,a0914c48,1f8becf5,d9a9d7da) +,S(a2cab3c2,537d8fec,b2f891a8,1da2f523,de4f869d,3c812806,855013c,73485ab2,765d058,c681af53,36ccbc8e,88d2391,b4894b18,15441342,4c4e73ac,1a8e0d71) +,S(9b39be40,976c13c2,faad320b,9338f985,b0718123,d2fb543,b65473a5,3bc2fce0,10f8234d,455fa7df,d09d76ee,41035515,9b560db,7b92988e,a42f9e9c,f7baabeb) +,S(35011530,6f2975be,73e7685,6456c94d,700e9b1c,4685639e,4f60efd6,9e513692,5992efac,9dcc0a58,ac6e00e3,54e44582,7e2d66c7,248e4b86,f8c216fe,a9e44270) +,S(df5a5b75,d96ddb93,9a341f58,7e1f997,3cb9e799,b04ccdfb,9907b57a,7b005d1f,3fd070b9,8d759043,8a53c302,b7ac0dbf,594094ad,7101d500,1cd5d687,e80066f0) +,S(91f14eda,a0db8441,10fa531e,eac54762,d52ca420,bb872327,6b383587,d40fa761,86cbd213,358d1f70,c3f6ac7e,913daf0a,47a80f8c,bd72445d,fcbef37,d0d71e69) +,S(53ddba06,46853311,9fe95719,15a9efe0,bc7fcf80,59d638e0,be6c1aa4,c5f21ffb,e59de2f6,5e583ab,5ac86c77,fc298301,70a18b68,a1979074,c21c0d8e,4a562567) +,S(56599462,4ad07c16,607afcd,76e86218,b15b50b6,9df84695,e60a15f0,3d7bcc49,c6d36636,ef58556f,9b688db0,eecb6bd4,5a7b30e,a9748732,68be57d8,542c966a) +,S(76fd5413,fdee9cb9,7f92fefa,5efa27e9,9aab744,e1e15029,241e35bc,743307a3,bb23f425,9aeb64e3,8ae82c3,b4691bf9,3b4a719e,a8ce076b,d0345a2f,d02a6d05) +,S(511ff159,2127502d,7499b988,7a3b3bd6,1242518,58bb62e3,dc1638be,89204a0e,21da5ba4,34b7819e,53b51e46,29f5fb77,e739ae5,97af55fa,aa09500a,dbd502f6) +,S(8e948cec,51635ab9,5a057404,39ff17c5,ae2e05e4,523bf2a2,3df28fd9,86de6b15,e16aa2ac,6c3d34b,9535b795,29a82b67,34bfa260,4a74ebe8,86110d73,ba564375) +,S(ebda8670,9277fecf,9b8507d9,40da6c74,210c8c7e,ddcff0d6,e3b52ded,3bf57095,3ca95e8e,112c8137,fe8c5088,bf041674,fb657260,70625890,1fdc5626,7655d654) +,S(eb5ffc4f,559f7ad,2469f48,1c730925,1ebf3863,357dbe72,41a29205,5b667682,b1f72d74,a5a16ef1,d55804ce,76974f46,61a49210,8a1a36f8,a59484da,a9bcbb96) +,S(2a93ae8a,d15c82ed,19fd2161,4a7a65a4,cf562432,623bf7f8,6c765548,b02fb57,5a949ca6,60a1430,9d4baa6,9be69b34,848e9874,62471d74,54c4817b,336584e0) +,S(9ac4a3e9,f1c8d115,138bd299,b6fb9132,c5d64a92,1fd94adc,82eb4ae,fa64704e,47f0eecf,a9eea827,ff339f3,48e67e8f,da9f00e1,a6b9086b,6f5441c3,7ae1d335) +,S(add254af,39d99d6d,355510d7,4f8985ad,3d8ec1e0,1e8d0210,27e80049,f555d65f,5b147a1,fc4bdeae,6c2f1224,b35e9e61,ad0799db,53597ef2,a23a8f3a,344dc526) +,S(d374d326,52cd006e,3b27b8d0,3ab47d44,bfb1c5d4,48adc992,5f63235b,c34aa128,3cc6ee09,c04d4cb0,aae8b1e6,6018640e,d0964fb7,148181ab,e9fd0374,642ad9a3) +,S(fa7632b4,78e5389d,cbf380d,8efbf6b1,d4bef9a1,70aa3517,e4c2005a,71a283f,ef2bcbb0,4b20be5,d4bda0f4,26dd0baa,31037d2b,7b530e2c,24105c3d,c817ce89) +,S(68ea197e,76af6950,1633ff9e,c825a817,80c7405d,ba513f96,6106632f,ea73ede5,633a5f90,587d4ea1,72129820,2ccefb30,c14a052a,6c0ca723,65e2f91d,53b3ff4) +,S(8874397e,1813f0c7,6946a84f,b05a0f44,224bb110,8aee722e,736e807b,b045b73a,ced2e2ec,85ae00e0,2952f55d,3626b613,641d2a8e,84b4c9ae,36177bb6,9ef80d9e) +,S(2ffe42bd,89256069,2e460701,b94208d4,85915043,8a85f71f,32246b8,5dea7594,6e7e4050,a35f1570,f8cc40c0,862e9cb5,59e744bd,8788646e,b0dad904,8b2777d8) +,S(c6d3a6f8,c997cfe,779a9a30,79de4bae,c19c226a,21f166d2,71ab4da2,cbc6defe,a8f8a618,3f6c8b2b,1486e60c,337725c9,9a9adc07,7dbb6581,e5b0119e,ca10f418) +,S(9b51cd75,442203ca,c4b8aba6,e9829b73,abe29f96,92b8dee8,500e1a90,9ea9767f,ed0ee32d,6042b6dc,dc818dbb,8cb00619,6bfeb2d7,88f35626,789cabb6,5d159c51) +,S(952c518f,775c8bc4,dbd7629c,8dcf8807,1b208033,8aee2ffa,eabad5d0,be6eaa1d,8a3b10a3,d9343d39,e7bef8c1,193f5cbd,717efa3b,cd2491f0,2dc1aa17,2e5b629b) +,S(49a18372,63eb11af,77a2e33d,2743393a,7eb269aa,f64589fc,8f81507e,55e8ee4d,7feb4a59,64b781b9,640d60f9,4e7eb291,6025d190,95945aab,7ac7771b,6f96cff8) +,S(cf974d8f,46aceb5e,a8c04e55,703b5a43,ac577e84,cb174abd,88198e1c,12708c9d,c50cf6d2,afd79d3,ce275e91,26bdaf0c,f46c1eb,536d0753,9dcf6c2d,d79afc35) +,S(461a831e,8beb6da0,df92dcdf,2697d551,cbf8f903,138d13f2,ec9b7fa,4a7d4763,e5fd85fa,c251705c,27d4e870,64af33b2,ff99b19,14496d96,6fa18916,faf40e01) +,S(eef4eb8a,9eba3f2e,b27e3aca,6cce7335,49f2656a,c26f1921,60c05bb8,fc3f1165,58f74526,a812ddc3,713217f6,fa4be02b,7062d042,2dbf5625,abd1f422,58b54c36) +,S(d674ace8,a7e8ae,d4bd4b7f,235b9f4c,41ef4355,4d9e6e44,3b6a26a2,d16f798f,8a25a7f7,896c0dd9,b1639f99,5c4b3df1,a3536104,b7d59348,c2c56c0b,bb21c609) +,S(a8eb465a,8a2869cd,6419af81,b3ad1355,1508727c,2b2494a4,93b5ffe6,2c1375,f1a27219,f59f29c,bb93bdc0,6157618a,454075ab,b95184e6,a4601ef4,eb2c8a1f) +,S(ccbd9d,6253fae3,f7d2527b,17854e21,58581e95,11a1f11b,55e3e04e,7326e6db,51ddefc2,5d9083ce,e9999e91,cde32f70,344ec937,d6aa5272,3dd62496,c4b0485b) +,S(524bc1e1,5c75e8f0,6718d2c6,da0f6599,c8b5d83,7cb9b48d,615e8e46,49dc6659,f6c91d14,72a50c31,1bb202b2,3d76f224,b55af957,c7bf3c19,69d175a1,d36ed19) +,S(520e667b,a0604a23,dde663ea,1a29971e,7e753301,9b2217af,296b02f9,de1df35d,9c2a2c52,290b6927,ac566ea8,4caa31ef,cb19b65f,29b4833f,5f4eae8c,f12b38bc) +,S(156282cc,65317dc1,3323aae2,d5d83e8,b7113d59,a50e54d8,dc54c1a1,ffc85d23,840cca23,67da3c5a,15b6427,72f0cd7e,675bb8b7,fb5dd58e,8cda9fcf,cb21606c) +,S(15afddb0,5adcc8d8,f1322a7d,f451fee9,873d4b8b,78b0c1e8,1d99f002,84aca6a,15465563,a129272c,b5e25bc3,ac76c52e,b4e115b7,b216a40c,145c4699,175cec9b) +,S(9eec4fea,e9508445,4bd275e3,f8d0d6d2,9040ae95,c8268f55,918d5f3f,2f75865,b7a873a7,5fb4ef70,3d62a723,81df2ded,102726ac,81685725,424a7733,8307ed7d) +,S(3aa7be96,660652c4,de1c82f5,cce1a864,c37725ba,848180bd,52e4dead,1a33f60c,f323d266,3e5d14dd,18fbab76,271f6c8f,32d7de0a,42724fde,f6ed3582,c886c402) +,S(bae9e070,a8e5a976,8347368,c32b4287,c7a6a20c,b491bebe,fc6acc71,aeeecea7,b5791703,f98ae848,1a9c66ab,878f7c27,d37a3e0,133b4e36,82ccb2af,b518e8ef) +,S(7b12ed88,be061d1f,7dab874b,17602bb0,ef5ccefa,54f9ff40,e753312c,335f5f86,70930f8,c465292b,b02ded5,59a235e6,c4c83480,9eb94442,8440846c,377498d6) +,S(9eb22b3c,8faad620,ba002990,4a5d8d1e,8cb4a054,179e3310,73f4ae8c,def4e1f7,6d58b972,ee88dfd9,4e429a2,4f6961a7,d085f00e,8d6f8d14,ff2066e7,df68bc34) +,S(bb2aa6cc,d8402cb8,e7a9a6f,a755c66,366c659e,bd2e5c85,7fa486e8,aa86b857,443e7128,674c040c,b0316d9b,3908bcd3,298e727c,c805bc8e,ca58894a,d51f4130) +,S(c58704a9,fc3bb18b,c460c4e1,f17a880e,c0dce45b,e2caf759,72f55061,d59d30d9,75216472,aee1c9c,280aef07,7208fe42,136b495c,f80d8a79,e8309272,c6c4d6a7) +,S(b7d7c721,70af0b6a,489c41a6,e817da2b,ce59f30c,88a82b11,83a6af8b,174c70eb,59481a78,52f3726,3a02ef48,dfb366ce,7bf170b0,af3c2000,2c1053e6,5dae1ef8) +,S(b1386833,25f5450b,f4f68dc9,93d72fa1,1e636a3e,8b881ac2,f237cc44,42f3461,64d18f1b,87f9463,10627931,cb003c09,981c4a94,969a0df1,7f717830,4daa6cd6) +,S(7e27af99,500cb8d4,d812a82d,29ca369,5e543231,8432c9f5,96f5b76d,c6d1bd8c,25a477c5,a275daad,10973822,40961da7,5385a367,6dff887c,42bd904d,8e885997) +,S(62e04f6f,d953c744,aeca984c,bad13c91,f4e09c1a,d5441603,2bfbc277,5ebbfdc1,4f1f609,db0befd5,fe781afa,d21efe44,846f9f78,9ed9f99d,f3291eec,3cf3fc89) +,S(b08a1f84,a3cbc3fa,f952247e,6d8d8d9b,1ba3ab01,ba03ef8e,836b94ec,dfe2e2c4,5027889d,e524fd0b,e6ada02f,4f33d1a3,4d0c3822,f0ca6651,ecebaa37,3c54692b) +,S(d417933b,c7a8f68a,9e023d64,498b5117,850f8885,b6254256,f9a12a47,538d5bd6,7ad14679,21349d14,10e35750,167282ee,9a6f6044,b6c9d71a,633f4475,5b432ed7) +,S(575909cb,46a36dc1,c270267a,10a62f31,941fb7bf,3699aa43,1a3bc770,fa37d5de,c12ef954,c937d6a7,bda47e2e,67d9ebb4,9434cda,e1571ec9,f604c41e,b49d6189) +,S(5298ad25,cc5a6bf4,d88b693a,d32a61fd,efd763f0,e4008ca0,eee17730,4365de57,75f821d1,66b60185,41cf7653,9a0cc41,597b8b78,10fd1fed,f0da4542,3a26d5f1) +,S(5aab0fa4,b0beb77,d5d2a8fc,c95d516f,1dfdc402,3e3d36b1,4ecb206e,ee8c5ff,7a4659c7,7c062356,c51ee28d,fd0cea92,a1f36d5a,b78a3ae,8b48ac9c,7fc63fca) +,S(482fc791,7c739041,41b69e59,62b0b815,8a9bfa00,f203afa6,46973980,9b250a23,89b117bd,485ac6ef,4de8eae0,a9e96edd,a3615285,e33282b7,bf0b6a6d,e11a9c8c) +,S(a576ceef,40728a7b,b63756f7,f3095c75,ff2ef84,c7933d02,b9dd8a0b,a6046653,b4c707dd,9d880fd6,d7a1ea13,87dcb6a8,e2433e21,8ef3a7f5,e348d2b3,f9a9796a) +,S(3c9d7c33,f8c62b35,fe977359,f290dbd,c2b46fb0,a2fe126c,d06e0422,54d1527f,cf92e34,3ce9f624,84c04c9f,d97569d6,67065598,9418d858,aa7368d5,bd6a2df1) +,S(56bdd1e7,363c52b8,2198cbe8,62ed6d7c,7b96d184,7da44036,2401368e,b2c83b89,505d385b,747c9545,6669809a,a9da035c,364e7971,7cd89417,3d1d5d58,298a1869) +,S(99e0696d,ed30d242,bff69e9f,ff4ec88d,eaa3de35,34dc7f35,c2bb7df5,9f8b440e,2cd1fc77,3bd071b4,c9695f25,458be688,f662f7ee,ae8f313d,9c373172,6185acc) +,S(7d5cb46c,81f4a4ec,f1e5d913,1772277e,d17de7ca,7a4b277a,d6b135e4,dbe61916,cc854503,d73e8034,7a6ad7e7,f5bab321,b130d7d,3d938423,9e0656d9,74971849) +,S(45cb6ec8,9dda9aed,5242347c,a20377bf,c93ebbd,50e48ea8,159530f4,4f4a250a,411a2ade,aaaf43e7,240bb0f7,cde77d8f,846bc700,4721f6c7,4d313fbe,70ae38c2) +,S(a7e23331,bf08ecce,2dda8c2e,a6c3c4ce,9bbbe3a4,4d40068c,e39e94fc,edea42e1,d1f12d24,144bb258,dcda7060,5348c1d,85faf076,fdd3611b,ecf6c34e,843788e6) +,S(d81aa0fc,b0a8fafe,d4c67dcd,6fddd414,80cd5548,cbd6aa58,35e5896b,18797f12,92af7ad3,89320814,bbe53ab,4cb5bd26,3df11ad1,8d2ef235,ae9ba163,74495d8a) +,S(8d379fd1,fc0acf5b,c96d03e,b73b340,5a7326ec,82882235,918a380b,c3e2669,f8c6063a,eefc0e2c,ef94d8d,ac4e5b5,ccccdf25,663d993f,7f9a0172,6756564e) +,S(5e20f600,6f533af1,8f3b6e65,17aaa2a1,2876b79,c99ca059,c2791a1f,1e466e8d,b23fb129,57640a9d,d38bf206,7649216f,50b913b8,69d241c2,baedd5e9,dafac9d3) +,S(1a0a4f54,80d37257,c62d1b0c,18dda7ce,f2b64754,be9a3d77,b3d80ca9,215026df,2f76696f,f4001927,9ceb5652,44d4a60a,9e353266,42bc2138,1191a51d,7661ca1) +,S(be868184,dc2e91fa,b11833b6,f78577f7,8c190220,a2b46551,53cc8ea0,73a217e7,6ffa3f78,1c64c118,68abc331,beb8c284,2919d593,12bad699,53edd222,2b98a31e) +,S(a4650db1,917b10d9,1fffa809,d9f9cdaf,f07faeb3,8f0ecda6,9c80e0e0,fd27592a,d5a6fdf5,647e26c4,1d7b9c78,7880c76a,b0cbc23f,d4c1840b,78717b34,2ade1422) +,S(944b1701,4a7c7eaa,754c9e03,d56516d9,e21e254e,9a871683,7a14f19a,9ebaa517,ee198337,3822c796,3ae7df88,24687dda,eea01e83,c82e66fd,baa746ac,485a6dae) +,S(f9e76020,cb9087d3,a60ba7ef,7ed5e552,3e5a3645,f61f9ee7,27d630b7,98d37ede,28371db3,433bcf49,f6d77711,d7ed9101,f5e478de,49c58103,b021457b,7a0b526f) +,S(7ac0c7bc,e17509a3,e4dc004b,d18c322e,600aeb83,8fe2045f,6da348ec,6f178b41,8b5cbafc,33469334,4886f60d,ee7626e5,36e9a977,60c0dd18,7bab7e45,6b264956) +,S(1d7ef98c,c8520f5,2310ad12,107351f1,966b651b,4b2a39a1,7a47f658,857e3bde,2b78bf4b,7be6f1ec,61cb235,a26e252c,71d91f58,69752719,8125712,55d47664) +,S(fc57f5ea,b40add8,f00c2da6,c7d24540,1b24b6b1,f102836b,4041009e,2fc6d5f0,11d3e017,bbc33913,b7861dff,bc11bca5,5aea26dd,f956d21d,2f333755,ef823af1) +,S(340c47cd,3b473c01,80526815,64e77f7,6ec29eb4,b6603985,d6ef7b64,29e2f289,994d98c9,c1de0dad,d27f3386,eeb7da40,6144e060,ef4db403,ee8a76cb,8e21bf89) +,S(81b13929,f08e9a23,69127ba,3e6e839b,8e9cd05,b19a9bf5,2292148a,26bc47f9,b6c33861,ae8fe20c,7a6c7830,4dd03fc1,a281ea57,59661e74,7f9e904,e4261226) +,S(6f325fba,15a463ba,4a61e2e6,82655af2,72603643,8a48075,f76c9882,4d7e252a,1f205971,70f9f48d,5421b73e,97bb6260,cd2235e4,6f611e9e,99b7f8ae,cf435d45) +,S(4b388e91,fadb26f9,b23b015b,398c8666,91521b8b,484d4510,b3c162d5,834bc109,ade8365,9d59c363,3191c3b,20e395cd,13ddabe7,1933045b,cfd8e941,f2096d25) +,S(2d1c0ab2,83c80dfb,ead3e083,76024910,c1d97acd,6c8be069,252bfd94,ac1a0db6,c4856c74,e5ef2e6a,17ebc35e,3b310f6f,8e7b043b,abfff733,aa3ed9f8,5a391c98) +,S(4c77a1b5,b88ffcce,1f98fd89,251c0085,9d4197f7,d45bee5d,edfded14,a97e5b87,48b8135c,b067c292,6c316424,2392fb06,f698b6d6,e98b2ffb,bcdb028f,4d85e5bb) +,S(d39cd5fb,11cabce0,e31f6fac,10cce3c1,c0bdbcc7,294119e0,2b433b0c,20e3a4ee,487695cc,8a8ec5fa,aafdfe25,3aa7d635,8d44e82f,77328e8e,4541f7bd,f629bb5d) +,S(238a05a5,519ff4e6,29b0f86f,9d259eee,4e620685,a2f0509a,cc9fb1eb,4e89f5f,6772f6b7,816018af,ec95717d,a6be2d05,3d740ec1,80241798,117ed39f,91f3beb1) +,S(c146bf13,72816407,b5f8532d,91210d59,a8a6db2e,54fcfd3b,fe910365,99f7ed14,e952ca9a,f88779c7,eea67194,3df6fad9,72b717a2,19d1eca6,33106f97,2dfdf0b3) +,S(4cd9154,861edfa7,c29378aa,1a7d6d0,83b134a7,572383ef,3010f34e,19d40bea,9ad99f1c,b5841c57,5f7db959,362542fc,40b0cbec,58d16ce1,54c5944b,6ff2aabb) +,S(d35f2995,2478be06,e86b342b,fd2d2cc5,ede30ee8,509da11,504bbffd,5884765d,a0f66db4,a21462ee,e51e226e,2d20d896,2c4edb1c,babc45b2,645968a9,c7810fb4) +,S(caf9c953,ef1f57e6,905bfec0,2fd64fca,92ded9a1,9435ad1c,a672cb7b,117c6fa,23b01776,7662984f,9c2f9e43,756ed3a1,3a574960,558db4ec,8670122f,472d0ccd) +,S(4bd40ba0,21d2beec,ec7317ac,df3b719c,179ec012,1274a198,d0ebd9d5,165bbfaf,9a5751dc,d7885a78,20d8ccfd,1db3e3d,aaa2bd65,b7b6fb2a,2d7b2902,c629d81f) +,S(560928ae,7b15a63,62eb4444,d4c0e069,1ae43323,77a2de40,83f056b2,70259814,ae97006e,fa5986b6,5da4ddbc,2bcea172,f12945d9,b6f5184,4027085d,bf644794) +,S(7870209,38e53dac,8e250835,9e41e313,25b09faf,95b03a8d,c25e83ae,f8255301,49fd164a,915e0af1,a66af8ff,d215d1d3,92e4996e,5ef68f8f,51a4b895,145bbd90) +,S(7aa3742a,6c82c90a,7e6c1b04,a41e4643,47925d,66f4e7c9,ab2aff17,e64932fb,7317dd5c,f2cb9b3d,5cc0fd6a,c433d1be,d1dc8345,b26e10b9,a2b8cbff,ce2db0c6) +,S(7a400535,be3b134d,4572e0bf,75c13098,dccc0f04,1c10068d,31e2b0b9,149c2e08,c00fd102,309626e5,a2f97ef4,e0374a3e,de0a7ed2,e45aede1,40521086,5d10466e) +,S(f4d71adb,438460c7,9003e150,c4143557,ffe30efa,eed122f,dd97c572,e1dbbbb7,e73588e0,fbae054c,140c0474,348b7ce2,92a1976f,e8c940e3,62c29ea4,31bb719a) +,S(34b68d32,810bd1ae,51d0c82e,ef99752e,8206aa04,8c5c30,7c3e9a25,b2d68b94,4d044a,6781875,6aeb8982,61bff840,a3ab951f,bf60cd03,e8befb25,97203c7e) +,S(f83b78af,f18f22b1,f2081707,3dbb9c79,4f180b0d,8871a1af,94d16d29,5c71f1c2,93ea5b8,c7847ea0,2cd5b783,5021d37c,dbbd395e,fe6eff8d,866e333e,9d6083e) +,S(a4a0d5aa,f521e1bc,2e818063,f4575f1c,99bd2447,80eaf848,2737b297,b2deaffb,3906373f,2111a47b,102b0294,f9fe1a4a,7ea9a9e9,aa2d9595,68ff8419,9f1abd97) +,S(cc211da7,28671182,1f0bca25,b9703fdd,ac9d0277,7e1829b4,4d9921d7,998011ff,c0cc46fd,5519211f,3a4cfa43,d84e5b3,bfb316de,39a5f4,9a50b1b1,8dcef321) +,S(8a07ed5b,e0397b5a,8c33ef,108df270,4b385c45,c8296593,1ed3e391,17b2f531,432023e3,8fc1a637,fb5a92f5,9911932d,f5cd23f7,eb16ef68,c8c573fc,86e8c1a9) +,S(8add7841,86b68399,b08a0bf2,a92a3987,36fca803,3807b564,f97af438,ac70d49b,758cdffc,ef477c3a,fb3028a3,2866d860,c65aa2ef,7b3d6261,9664ace3,658add34) +,S(ec6b9f2a,a1cdedaf,306b8a5a,b021e430,e9931126,a1c505d4,a10e71ec,3cc60453,8139b262,40e2c1ca,8ec89808,2a37d7a9,b78a7e5f,6330ed32,f9786cb3,c4ddb722) +,S(22ce2541,dd8a47ae,227dfec0,95ac361b,88ae2cd2,c9547344,f551f6bb,cada196a,68ce4f4,a677a0f9,60aaf4a4,f8e83a24,ebfbf46c,6ce2a470,255d2ede,c4431581) +,S(ee7dd0d0,3e5b6d8c,ae78caaf,27b902fe,4136201c,12a49551,bf208c0b,f88bd33b,aff0eef0,609bbf68,7ce2aef,9f48f87e,67aedd82,e5342159,3809cf5c,da4ac004) +,S(f7f9a352,ca18b2f4,3aa18c00,9ae0eb31,17679db8,d9fd7e5a,41b77e85,b54140cd,afd30383,ccd2a6f7,ae76b953,5bc80330,4419d38e,73e12d1e,dc407ef2,f3b50326) +,S(7793ef5f,8e57e872,ea9fbb18,bd710ab9,6ea4f646,134d3308,930cbf62,e73f0e1c,8d5b3b79,3573090f,a4a7e7e5,c38fd987,e889bc3e,720e05b2,43e856f6,32ae7cc5) +,S(db743211,ba814bf,e6371ddf,d03ba554,b558548a,a90e81b8,e1421321,656065a8,8236f24d,965a9003,84b382e8,d772d7e9,2dee2ce6,c3cb3388,3ea627d5,4a5170c4) +,S(48c22865,6e51199f,6306a6f1,7dac1e6a,13f82d42,61de0f0a,9158ba98,715d3cf9,19a2a4dc,35d2bd03,5bc5daa2,5526598a,8eac11c3,52e5fe70,be726531,747035ef) +,S(70a28bf4,ce75b491,582b48d5,9a5069b,9dcc1e49,c41702d,ee5d688e,6e643a59,7183750e,2995f655,1b58d5e7,21a5f33b,69045934,27f27f34,f8ebf62e,74e49de2) +,S(a90d8505,596b3d01,a5e8dad0,fe652cb2,4a008a7a,61ba3cc6,8401a7a5,5c2e3132,f98af047,6e925c87,e13bb7db,f992b81b,1be564b6,8589cf2d,b79e4800,3ff7b0d9) +,S(88647576,8e960c09,6aec9832,448decac,6574491c,df737dca,dcc42b84,d7e775bb,ad94bcbb,7309f483,19077724,2582f5cf,a39ead6,a4050afd,89a49ecd,7a9090bd) +,S(c505d2cc,ef72aef5,8130f472,2ab3b2c2,3a6864ab,bcfffd5a,725a6df3,fae02112,dcb82329,cc51dc7a,54e7104,462997c,3d135d6d,5c82463f,45e875f5,8738652c) +,S(24a1d4be,c709cf8c,8b8927a8,8bcfb11,43b0d579,10e0900d,68fbb682,d4e14df9,9ccab057,8440f6a2,edaa4f41,28f427de,adce5584,692b79d,624e8724,572a043f) +,S(48c44581,51df1654,fa78370a,6975e59e,576eeb40,e94f636e,72aeb37e,8fbdc4bb,f48e8dfa,bb085834,43a7b495,ced76171,348e92b0,41b9620d,3cd5a84a,d9ee4eb4) +,S(42a7838,d33d0b15,b4409534,18024a33,e93ccad,946b50cc,a543ea1f,1bb457da,dc2f0e6,4f30e973,cdf6289d,d8f6455d,51c2da02,bc4e1d13,6668250c,e4dd791f) +,S(80988f4f,c2dfcb86,f1f65196,d93a6cfd,5c664e1b,5f8875d2,61e7c4f7,b2ea31e4,1e695c33,b526d582,6210e694,49c4673a,8697e1d4,a197c9bc,a3ecafda,2a7d5b93) +,S(a0ae003c,65d7f1c7,b65cf828,124701b3,876d0be,587c2589,9a618c4e,7b79d480,d7f4ec52,bccd57a,9515e80f,2c79be42,a6b53ca6,253ee13d,ca33c917,ff2ddf02) +,S(392f57a0,ebe08b06,cb4946ff,3c1df6c7,c5cdd97,b9cb2190,dbd4678,cdbab3bb,1be9f9db,dfca7981,b3dbbb1f,daf50e6b,c5662fa8,1b8a58f9,9953eebc,d1d0be1c) +,S(cd904f6a,3d8c4ebf,6ebc4e5a,e536c544,4a04e278,389d771f,d5e7566a,fc592d3d,e3e10f61,a15399c5,f3f29626,af323cd4,3d6572fa,bad4f02d,cf76c0f4,9785919f) +,S(27a4480c,df5782bf,52ddb140,ea5a908b,38dc1ec6,a570580d,2b72b922,e7eb05d9,bd96ddd8,1a6aca1f,88847632,5a6d48c8,4d61e76e,b4d0d957,15d39f80,faa42f3f) +,S(6673ae66,3511292f,fa4dd8cd,bc0f7b36,613c56d2,775602ff,a8cf9302,4329f5a5,d8b4ffd8,8ca2530b,18d85762,529d056,e8048cdc,51730082,2d24cf42,e4053141) +,S(3dbae13,5c395043,d5b88161,4dde355d,5a669076,98c36b23,ac4c24bf,80e34f2a,b7d46059,3154fad7,eaa37c3a,291c6c67,16df2944,4274b044,a9f12ac0,a34139db) +,S(f2db4c09,1c3c606c,9784f6af,7dbfb26c,2b18bae3,b22f13bf,4188d761,6cbc1371,8c84e295,f57a9722,260d5816,c5d57719,c6fe2a12,3ba20a48,189bee04,ac252f32) +,S(918e415d,92e768e9,f5a875a8,aafa7dd6,66109cd5,8fb6044d,d2c8640b,f6b966a7,b53400ce,9ee9f6c6,9cc35b5a,3e04eec3,dc89c931,e545068e,ed4a818e,42073e71) +,S(5eda3e22,bbb8c368,82d46c19,2068b3e9,a65624ae,31feba8b,df725d5e,47bc3437,1cc2c541,ce3ad8fb,ac3cfabd,a492c03,87099e1,659cbf88,bc8f27aa,f9a2fe26) +,S(7df83e06,9cf09a92,5405e0d4,3cf0c7bf,52a8e603,d286e26f,f273e218,b455e61c,9eba2975,7f61b054,29c9e915,a092a591,ac1d6044,8a63a8f1,313f4018,1650f4bd) +,S(b778c25,d78b0bc4,68dcdc80,5de93809,1c3c36c5,b5f9569,a9394b5d,c7afb162,901a4ecf,b4821145,c7d9e56b,75e43ab9,cb7ef8fb,1d384a4e,27033e9f,90b80fc) +,S(dd4965e,f6fb759,104f7877,307e2a6a,f837ab6,8c19aa40,6fbea75e,e8a7adc3,45e92312,b5c77585,3c4b95ca,6b4c1740,a70b57c9,97124883,2c53d291,4b0fd4d8) +,S(ac971379,7dffd8d8,2e33f927,48ca063f,f1c8ccf2,5b88fb6,bf80946f,1dc9dede,6ce10e3b,ee4db87d,40e8de66,fb5263db,2a578d6d,be100fef,d6e28bd6,7377bc26) +,S(6046fab5,37fb413b,29797312,5a6049b5,5c085194,4b058264,c39926ed,fe85c6,dcdf9ed1,cbe469ca,2976333,5a159e42,af6f0d32,664ffb5e,173986d3,a277180d) +,S(a0d94b05,8e3b4d30,7f3b3f09,ba5ba28,d0285a3a,22cd577a,1d949b8,bd23f1ae,37fcdfb2,e3027e07,ea77f28,447ea13,93971c67,974304b5,dbb7621,2ad2db10) +,S(da15b971,1b974ef9,14433ca5,71175233,693cab3a,dfd5f6e8,cf034254,6f73dcd,e08c7f62,90f87fc5,4e2f4ec5,a5a93d19,f4484868,3b5ae9d3,810b0615,c7e79402) +,S(b26ba5d2,72a744f5,562cd745,a3f3f143,32980458,60be4e97,d737fbb9,b3b0d544,3d308307,9830f281,14de6c5a,f3876446,507558e2,95353dcb,738deabd,80c0ff20) +,S(fa26c55b,bac04fff,ccee0610,ba9b60a2,4042aa08,7a564ffa,b891e087,7a2185f5,5b5a62eb,1ff579b9,ee4c5d6e,ceeb57ec,e9881b47,dbfc24f4,3b9a18d1,4addf4ab) +,S(5ada4a59,4802163d,4da685d9,b7479f,4b70b489,5ddac7a3,b06a1c4e,a5f46dbe,2ec25e70,871b4958,81f6b0e5,cf821b91,febe83db,a52fe2f8,1a2e4e82,165c7e3f) +,S(a57751d8,895282ac,bef2384b,db4817a3,539899b1,e7fe7a62,2596ad18,5dcf878f,651eee9c,12ecaf92,9eccf109,635680a,a7499537,f2054e2f,69b0f062,c820784) +,S(3f17f0f2,6a540098,d18f8d88,ad323e9e,e300b029,b7b8101f,6aac6ece,8d375f3c,9c0713,79e35319,7f1e76d,55616e5f,8e573a54,b6bfa56e,5dacd2aa,e2e0deeb) +,S(eabdf476,d2e9d76d,775388c,da759930,4e1ebd59,b3a7e491,e3c9c62a,4d0968ba,f4bfd5b5,e0e8ab41,a04c4cd7,763b243f,b82f56ae,9f08a6ef,bc365f3d,fa227c4a) +,S(c5b76ae8,dabb664d,fc1fd499,36399e3f,c2b7366e,a21cba10,dc7eec7c,5c93e0d3,ef30249,19bc03a,c24c8544,9467728a,c160edc5,7c901e64,b947f298,9bb1242) +,S(7161dbf8,6b1080bd,bd6aa47e,dcdf8a77,17b7e281,c692e9d8,739caf9a,f3f23d6,3c30b786,b095288a,4522749a,3d32a35,5a8bc694,cc9cf7ea,989675e9,a1688e8c) +,S(ed6a7b49,9b74e62e,53183b15,6867d41,3ce902a8,4b71fdc4,fa414f8f,249c2ce,793d0356,1bca65c6,be127ce5,a1034b9,86285fe1,f52075e8,1a9b5bcf,87348c4f) +,S(fe6e1abc,3ee3be4e,22456f4c,bf93810f,282f0fec,96ab5cc8,2b35b08,54492bad,96c76282,3adc2cea,1563c02b,fdb25b55,eb15e769,90a7ed7a,3fb8aabe,47bb077c) +,S(979e7ab1,96e66818,b67bf79,31232826,713648bb,ad956add,ed594cdf,8aec2937,696a9505,e3c473a7,2df68f96,13c2e494,406782a4,f92a8fd6,5017a83e,d7912491) +,S(9f947cb3,f859f2af,11a63400,800c18de,b8813c1a,b396ebd6,a1d5bf4a,9689160a,8efeced6,7f1e6fdc,191ac965,5002a02c,386a20b3,eb2aa1be,7fc12008,b8bead1) +,S(71790030,58caecb5,dcd2e281,b42eb59e,57de1e6e,b77f6bad,7d2d1897,6a512eb4,abff54d0,e20347bb,c10a79c4,127f5f7d,868176a7,4e34077a,8ede1d54,7e339483) +,S(d786ec15,c140af46,841b7eb7,de5fc9a3,c0636885,3950bab9,ffdbad01,d836b8b0,fc90191b,63616a44,72efb2ac,a7d84da3,4892af1e,25bca0e2,d41268c8,d381d062) +,S(2d553f03,31eb83ca,edf2508e,67054734,d929367b,ffdd5b7c,dd78dc6a,2e724534,9abcef4e,ee588e28,fa1dee0a,b8c426c1,67d37cde,f8aae9e4,248c036b,baa1af70) +,S(326b36b,eab4d932,c40182f0,fde043ff,d6b84b16,72fe1dc7,3bc7e518,6ef68062,9d86868e,2e871ce5,c3488624,bec901d1,47b91bf9,a3154cab,6445870e,d51e8f1d) +,S(f7a6a26f,4e3583bb,9552556a,5d248735,7ea4af7d,ad1f7a92,717d19ab,34dfa11,7ace27e1,dab2dea9,704c01ce,50ea3de,529d864d,9a5fc11f,fbc0e8c7,81778b2b) +,S(8ca708ea,c072334,42eae4e9,eb0c7b45,83e153ba,84ed7a0d,3ece41f9,4df6cd15,33f41d25,e446c47b,68ce1bc7,d1dd1740,fc701538,3ac90e05,1dc89a9f,dc97592b) +,S(4fca2ed9,e1948697,208a87f9,a890cc96,4aa9e5e5,7c7274b1,deea92bb,586875da,98a9303,4df7185a,df9f557b,b7def9a6,41e7ad5,a3f24051,435673ff,12f0580) +,S(466da0aa,97c68c05,21b8fda0,fc70d74,bb586eb3,da7eab4b,6c104404,d9234d37,5834296,f94f5b54,beddc0e,3d7f6004,659952b7,90a6341a,de99ff26,5530e5e6) +,S(ae22ae10,d016b54c,c0b5423b,3f4c332e,3180ff23,c279078b,864e8e07,77e26a5e,ee21d64b,d6043d56,de3346dc,f93e2c40,b9a51498,b4d7df61,d476d339,7a2d0c8d) +,S(58cd60cc,ea7e0896,2f65a353,5d45ad06,517fea5,575c5511,277103d9,fabb5167,175a68a9,850b4026,bc7b5684,e859c808,edb5f3,7acebc47,9ba489d5,5aa9774b) +,S(4be8a0cf,7ce26101,49cd90a8,68f4049c,43054aa5,68bfb2a1,a5bfa386,9b2b485,a3bab0f3,e3bec469,f779404b,d025ca14,79e3f6ca,9d496f8f,8ce4aa6f,b7e3b404) +,S(428599d9,398a2c59,58c5f74f,1226605f,3c5c8e74,ad8f9bc2,d62b8d9f,d679d3c3,12a1b04f,add5d70,bdc5e15e,d6347f7f,6785c425,61f14ae6,275cf050,3a1bd5a7) +,S(134ba4d9,c35a6601,7e9d525a,879700a9,fb9209a3,f43a651f,daf71f3a,85a77d3,21c112f7,6a9b9b21,e2e3a7c2,8cf500bf,f48aaf1c,48e0e13e,f15618b9,ca62287d) +,S(d53cf8f3,cc5e5739,bc9f9144,a44e7b7b,bb8f2c36,b50844ca,9b2d9cf0,cd0616d2,799c23b6,c57aac44,90d71450,4388cfa4,689393ab,6f30a347,4503400e,c568e03f) +,S(a1e22cfd,e8d12f17,eea1eca4,ea0b520b,6598c036,d1bf837c,e23bc300,a384e5a7,cfbb52a6,e1fb6a65,77cd0377,8bc965b2,a3df592f,f73c34d2,a91b8008,74ecc295) +,S(72bf047f,a0da1391,78b97ea,7b317168,ed0576fd,71f49409,39a8daa5,2a02ead8,f8d93088,cb3457e,7828ba9c,bd8492e4,9eb2bf0e,2e23bfb0,4591e9bb,5273f462) +,S(c5373038,4b951abb,3bcd1f4f,98d983bd,cb5b36a,42719531,c4d1797,2e9bce59,d921f353,a9f7309,6dc16028,f9e1b562,f406bf49,54d78bf9,f2b4c8b9,2db26a82) +,S(ab20d194,e2a6c4a1,5705d3d,19300810,89342b15,e9fc6224,7be58805,a8682a5e,44dc39d1,8342502d,cafafe40,33c4893a,2dddddd8,ad7b238a,efca50cb,5d5b3186) +,S(1432ddfb,108ee664,2eaa9c97,585f47b7,b92a5ae5,39a38093,b8f3153c,e971c8f9,5362084b,5482e375,1662aa95,dd3b9a6e,65235aca,b0ce1eae,f5153951,1391e269) +,S(f199ede,4a69d778,61e107c9,376bdee5,6430e279,28c74d75,66e65589,be8c433c,5e7f6fb7,1b68a535,f407a9ee,2e42f65e,9835bcc7,2c34b8e7,712e5332,a65e9ac6) +,S(b24dbf51,47452b5b,ad94bf4b,493120ab,61ce2ea4,37b3ad71,62e568a,1d595d1a,b3af5a90,8d063602,6b3869d0,c9f31793,61afd6c3,8db99cb9,77b14e0c,46427518) +,S(d7fc29eb,b681e025,992d9ef7,295db58b,40f36c64,d1be10e8,c8e66858,d4d0d9aa,c587764,ca84b3c7,2f95eba,eb62494f,ce391202,90c42b9,e8b2105d,ed972595) +,S(5c71e90,d5f00ee6,e033f0c9,c1ac495b,d148a31d,143a8e3,59a99c7d,faa3cc9c,4acc164,ea3071b7,a4830a27,24135c49,562ea631,9dc4455f,808f1282,4e3bbbb3) +,S(4c9904a9,a33f7e33,9a3d85ac,c12b21ad,11f7d7f2,76e46620,76878593,9d11eaad,2387a445,b0967403,86ce4634,62dd101f,95650365,ac02ef1d,2417321a,3fac1df9) +,S(58f457ec,12d22482,2a91b78e,26f7d8f8,5fa39d90,59fb833c,bce4b1f2,5c9720f7,90808a70,79d4970c,b2b70ae,390844a,2f0283ee,eae05a5c,7d2dcdde,be656f2d) +,S(9867259c,51414805,3be6a73c,de522d91,a8d8b359,9f9bd39b,9c9575a3,90405bdd,9904fa47,34973bc1,77a3d0dd,f0edc0bd,cbd77b36,357734c0,a0feff89,4895f3b4) +,S(663b4991,913148b6,631d16fc,27471938,20a7ace4,ee85c335,17b60cca,b5e12b5b,1b295a18,16b92c5f,15b88bbc,177dc011,f6ef0760,15b5ea47,9bca876,ae072070) +,S(5e3ff13f,bed18235,fe28dcc0,72f09cfd,41394cd,a9a3aa52,5286cddc,e56acf05,c1488c2c,903bff6a,411697f4,44e6e72,6ed9c0bc,5aa87cbc,ed8f8802,6998fc7f) +,S(54c8aa07,2f1fc5a6,ade56cef,d7c6aae4,846f6855,34912868,b84b195f,78bbe14b,ef11dea9,5cb01680,e7205f1c,62aa5242,2c0db969,9b2a0202,966873f3,1fdff34c) +,S(bc69e00d,4118d8af,baef7647,6e435883,2ae9864b,f154368c,e2ccdadd,c58cfd9c,148aea9b,2babfe00,3a6592f4,d3788893,5be42ac8,a50f68d7,ba2cd738,47dd9c52) +,S(50ccf184,c0213602,af114924,fe100f78,1f0d0cc5,beafb671,9dedea00,c7c3ebe2,b6559878,d7c33082,4588dd33,3054c4d,2da86b8,ff23fa9d,6413920c,d876e36b) +,S(c24ca0a4,8ff2cbb6,235ef33b,42ba032,386d5475,3cdda799,e9bc53c0,5c299aee,8555bb16,bf4d7bb7,5c0cbdc8,8594454,bfc819de,72c3954e,76b65780,2be28fe4) +,S(cebc8853,3f6c3a01,58dfab12,ef52b4e0,a7473d1d,209b3585,bc94a13f,a83abf17,42fe28d4,136bf80a,7149a0b,7ddce53c,45e23c0e,7be85fcb,73c0e66,2c4c0593) +,S(7d921a84,65b11feb,7a755a4c,5d96b6b2,f17e07a,95db112d,48c03bd,18f61422,f0ccffdf,7f04e350,13ae7f36,411dea5a,ef69f220,790c37d7,354ce5e,83925f4) +,S(b6909fe5,6824e868,f4cbdd10,d3d00ca,23e5b4,35c78aac,c78a9a1e,321d178c,3d513c55,136d61b0,73dec253,e1ed817,782d9f76,b536d3f7,c3b0d1f,d06e6c1) +,S(5a3df3e8,c78c0fc,56971dea,ced3a6ea,e1ef668e,2485bcb3,d4e24408,7f53cb74,960721cf,316278bb,56bcdd1d,9f3385fe,8feea6b0,661bdf1d,44771067,661aaacf) +,S(dc65c06,50cc30e4,d759fa93,d4d0ab65,5cb16591,289206d8,7a988290,20c22f9e,be39ae0e,a41a81d0,2175dfd5,5e004e19,fa925a99,2166d862,296899e,2532b6a6) +,S(f659d02f,f2d4bc82,9f816525,24019a88,6ad539da,3f38b083,5d8265cc,bf3a67ed,bc9c7a81,9036c702,338c57ef,26134647,2a22b8cc,5543f4b4,4a4f7d4d,d4339573) +,S(b89bbc05,420a8a65,aa03441e,da1c54da,9ca84f11,e85a393d,47cc54b9,78b8e5c0,5f3a2fba,4cef4457,ca6befe2,7dd3f9af,a5d8b6de,86679eb4,c877c7b4,cf03c08f) +,S(b9bbb789,690b53e6,e42266bb,853cfbbb,f6788b58,b325097,a55470e3,d4cbc3cb,1f984f38,78427212,cbfc8a93,8c1f0d87,59792ca7,17635c75,71b2c4f1,29e35c2e) +,S(d8ae91cf,8a99ef6d,2ca0c15e,3132974,33cd46cc,55a2c8f3,9f909e96,7d50006c,4fe4696a,79d2f269,9fecfce8,8375cc1,81c2c2e5,4109f380,3377a020,5496d733) +,S(35dc2c70,181aea7b,ccf6a15d,1f708c87,cc8bc5af,93671c97,35867367,549357bf,6f27dad,a9abbe5e,5e59141b,78a2e6dc,5b5433ef,dc8c9cde,a6269c2a,68346f87) +,S(a4c042b7,d54b67b5,877442e7,2e81de4a,7edbe667,f00838f2,34f567a7,9e3791af,a8c6f7b1,6b23a9cb,64732852,c9734547,69ef3e4b,9165ebf0,a1dc4967,36c73242) +,S(d6ab68a3,353b6c65,3836b66a,8c39f2d0,892cf856,90ebb56,a5e8e4c9,e669da34,4847a9d5,f39ea1e0,ce392c8f,9e63e88f,8f3feb9d,7b2a05c7,23a932d4,b07e38e4) +,S(e161c34e,644eb3f4,fa217d33,dd3129b9,c2b85ad6,40b56e56,e20982d1,c5483d43,ceafd0af,a8cf7a25,be092307,22c30e41,b6ea151c,d027326e,5152aba8,d9a50749) +,S(94959a2,fdc2650c,b4b0219b,83ac99c7,c477132,eeab585c,1fb262e7,6cca22f,6243f3b6,ba7d4f26,24f7b7d5,8e070b2d,64610aad,b281b4a3,b93b030c,ac0cdab9) +,S(491129ee,3130c2,f262c4d0,a1bfede9,e470c3cc,8e80774f,52ea023,67e2e3de,c1e61e2,a5310866,762a0cf0,ebbae0f,738b9527,46001aed,a991e0ee,d95f0db5) +,S(e2967539,b0b29fee,a668eebe,eb8e47c0,1ed84950,a1f9fda8,6884a421,5ab6f265,c304cf3b,b7faabe8,cfeab6b1,b88d3d41,7e950963,745c2479,85211d50,888346dd) +,S(d90a380f,5283132e,7d6760ca,f2b28576,49445507,b8e8872b,d0e1d5f,56a15af5,97fa0739,7a1357c5,e24d0a3e,ce608332,107e41f7,c65d3c6b,98ed66c3,af30a4ed) +,S(cb917a08,153599e3,e531b1ac,63fb8e71,fcce572a,29fde1b,17de843,a99ea2b5,701c08a4,a9da11c9,3b4be64a,6832af1c,900ad3c1,4b4dbe70,c62e3e08,55b41b6d) +,S(e6ee53e2,98efb026,bce900e7,8d31f3c4,539108bf,d4c5139,16417f8b,49199a0a,bedd41e4,751f657e,8cfc65c3,2a82f981,4b223e62,95ec36cd,da5125eb,da736429) +,S(5f777c41,f4e3441e,75c66f28,852e7815,59d0f3fe,b8b05b59,b6966fa0,de84df2a,7fcc66b8,127d26d8,e0ff69cb,b80acf44,bae5546,edc9bc52,90b73da3,447a2731) +,S(16d312a8,1295ab9d,c08f9fbd,61e6445b,5ef1dc51,fce19d,89f04e7c,66ba2e07,6c555fca,2a1d2f4a,24ced2bb,c3966f4e,1bfc1912,eca39067,503df586,41a4d4b7) +,S(660d3993,fa887e1e,8b05d80b,96e2b70c,341c3ba3,351d2562,5792acaf,3859de3e,87b06f5d,4c6f854a,8714eb3a,55454346,f931c21c,c77da23c,2d069d33,7dcf12c) +,S(9d45e660,879b6e8,b8007a8,ba7fe7f0,c7090cf6,9c733bf9,43f4eef9,965a1ae2,c81a3fd3,9b6b83ba,d163c763,f3010359,ac050e64,a47167ae,2ca41345,c7d95662) +,S(c95d92f8,c81d15fa,a68f645a,c1ebebd8,57c6942e,e75ba13a,3a4eb9b0,c45c43ba,2f55ceb6,c1de7877,7b322a91,7f3e48d9,480b80f,d49e362c,99f8104b,a20f392d) +,S(95d445ff,e8cf8240,fc4e9856,9d41164f,50e9ebcc,1fd3bf19,d4309de3,34b4c97d,7c391704,a75cffe2,f8971ddb,417e8158,f97a3688,6841f02a,c4b699b8,df6c0d32) +,S(40f028ca,907d6521,df1f052f,ba5268f9,a60e705,bdf94328,17881b44,1500170d,4eae26bf,37d04379,126ce777,b1fe1115,8c34d077,bba66994,78ede7e,244cc8c6) +,S(dab90c34,e7460068,d80d2be2,2bd81f9e,667bbd96,4e30c23d,3eaa7a75,a61e862d,cafa2892,5128bf3a,4821cd14,8503ca8a,86f06388,d21df6ee,af92d514,e66c5f1b) +,S(6df2280e,381ef8cf,922505d6,7646c1af,105f91c0,59e8e7a5,3ae2e7e6,cb456be,d94a020e,7776b713,b31aff5f,d72be6c,f29bfe46,16ea3d29,95913db4,698ae3ca) +,S(a13d83d1,3c60cf65,cefc8692,f5d339b,2873582e,938373cf,3e4df54e,ae32ffd2,8f511212,a65d8963,d7df7ed6,27d87fd9,208f83a,1a4dd14f,ab0593d6,38ac71d0) +,S(ad4c1ec8,39950ae4,a7fa551e,5aa637a2,e5d40bfb,3fab696f,ea886a4f,40bf2167,fea9b599,202841d0,c3afbf08,ef1da210,cdd92a4e,6cad485c,a0d5275e,8a5dacfb) +,S(64188be9,af657254,1314e661,848970f6,35a0b6be,7e594824,6dcf36d8,66840610,58880b5f,c3df9b6a,45b49ee6,b90f6b5f,f3fc440c,37855167,a30ac013,3d48e53) +,S(9b71366d,a66b165c,6495e4fb,46ecdc15,84a193ca,d65ad8b3,7a01a3b2,cf2e43f6,d7315165,ecec296c,4b71a860,f3b2f0dd,fb9447ed,5c59a458,8b81f679,34321301) +,S(4a3c5006,74814f95,9e9c7726,595658ff,84e369af,636f6aff,ab579bb8,5583d395,1b495757,1a302c2a,d1cbe53c,2ba34a6d,66bf1aa1,8bddad33,679e4890,5f9a21e9) +,S(e4305e5f,72c43558,79a749b3,d563d4d1,dca704c9,c8867d01,ef503cf8,97c90034,ee563dca,4d31945f,c536a318,e9297d28,81954b37,af992722,9e4e0e9,1c16244d) +,S(3aea4eb8,ee74c9d5,2259f37a,da33ae1c,78f5dd8,d97511b0,2e0a0201,82840a8a,8fc58135,757b8c0a,a8f2c2ab,ec9d9152,20ad2046,f429667c,c4586765,10e93e87) +,S(58e8e94d,e9f85066,7cc4c61d,acd212f4,77454942,33deb015,858e500e,9530228d,5a95aa24,fb782a4a,e64e155e,eac2b644,cd614315,9b46db6c,9bb4fe4d,5e5fd690) +,S(6642c782,7e1df912,ff54dbf7,41fa1567,3e9c3aae,5e7630c6,9cb74b60,c070af1c,ff338a86,34a404c0,cb26af9f,59df36a9,e1a848e1,ac178b25,c37ac177,db45e947) +,S(c5c69fa4,65c79a50,a98996ee,cae55474,5c544a3,ea838a42,e12a733e,9181b30a,6e805461,5a424a9a,1fc229b8,7e594211,697386ef,189d1ad6,ac75eaa2,5727253b) +,S(f4faf099,fb16a1e0,e5f64428,5317d91,a31daeed,fbb6a6ec,b70a213f,ee95217d,ebfd8445,42fee872,1f721f3,11ef28e,30618bd1,bdd097c1,ca573285,5b079734) +,S(773b3e69,fda8abed,fa61ef37,57101756,9d9d2a6a,ebb4fc5d,d9049d56,9c66b76d,1bc051c6,302a383c,dc0756b5,114dfc69,1dd2180a,88a4ea9b,6acebccb,a59f27ca) +,S(bcf80e7,b2b54cf7,971fae7b,db8b3826,85acc1b0,f987f352,d9b0b3c7,ac78142a,20620b00,8c010ad9,7a98f093,8d9a381,f9935d5d,4bc9b060,af2ee6ab,151eedce) +,S(865dff30,47f31564,99337316,ea20223c,5967e034,83d92d54,7486fddb,fda959d2,2b655c9e,37697f10,5535b736,a31b2c6,7f5726eb,602f1438,f808ff62,4bac074f) +,S(e48e0e18,101eef40,f351067e,63d2b34f,4fce76c,d204d6f8,85d2664d,fbc92d3c,594061c,8d3f4748,bff85cdb,f70a4035,5ad826f3,46d44aa6,7eca3196,e433bb65) +,S(9807e350,7a03e134,9bca9101,cacca5d1,a564b647,8c906619,61ba503c,5ee15bdb,301e68f2,d584b1fe,3eeee7c5,85cb4d0a,26621bda,229589cc,2704dfa1,1cb8d927) +,S(95f94e75,8602dcd4,60ded52a,c9d7ab40,1fdf1405,b271acb4,133a86be,cfe5027,f08d34eb,e9cf1b1e,78e1fbec,452e1ab0,412c642e,1328b2dc,f5e08b08,38aa3c51) +,S(7ffa20eb,ebbad406,deec68c6,9bdb7b0c,7615a56f,5c62a646,a57535e1,68a82a31,230241b2,3dde374f,7a039eb5,5181e954,f0472056,79edc688,7c4ca6b8,778333e4) +,S(1dc7e0b1,487fbb33,d1ecdf84,7bdbfef5,f7df9f31,d07ff024,be063a51,53eb5498,ebcf72da,18a1a55a,5aec4aa8,efe09407,263a7b36,f09552e,22cbceba,7a3cf980) +,S(a8052e02,e39d9981,2ac6c4e6,2cef526b,9cb29843,127f2227,50a8021f,4ced5cd8,9011f0b4,9dad7e5c,11222b64,c5d8c9fb,297d9afd,c683f545,849d833d,f2697220) +,S(3edfc4d7,f1f699c2,8e8ac2e7,5cd93e69,fff31607,d99a8195,30603437,f9bfb20d,f901260d,68c6dfe8,aef8879f,ea1ba009,a1e1d931,fa6ba39a,ce1e2673,ba759311) +,S(fdf8ae7d,c10d01f1,c39bee75,3be3307b,53307caa,4af0e8dd,9de7d696,45ce527d,2425a3f8,c6147073,3a44d3eb,eff3d8cd,61e5fd55,ffdac357,d7906600,153a8dd6) +,S(1cd5ba80,fcfc77c3,d06e230e,e7ad8ff4,f9ee6c60,a71d37b8,3718d8b3,15d5a4e0,f90ac118,30b963ab,fc64492b,415db7e3,47eba55e,d2c5a64f,578a13ea,b4435cbd) +,S(3cdb43ea,b7afc936,24b80269,18319fa0,e75de21a,c0587af3,541e492f,1510257b,49b6411a,c74a2eb3,ac2ec784,feface51,8d5a5bd6,e76d694,bf5ab8f5,c146abfe) +,S(165b6f5b,9b1e6d08,14e44cc7,c7969297,bba7c659,58dc3274,7e7c4148,e30c09da,e715e411,2e6cb67d,cb8e1ad,997691f3,bd6119c1,3a5f0329,1ea3928e,35c04551) +,S(d4c1190d,da3c01cf,6c75fa06,7b4dd1ee,e645a0cc,8b034f4b,24580661,8ced0bff,c837ed81,b6a0e5fc,6a02d6d5,f837db1a,20eee55b,41ff531b,9bb642d0,52c42bfa) +,S(f7359bd0,bf7db6b0,48f1a040,a0163fba,285780e7,909ab689,7963168a,a7de9c29,8c71bc3e,95ac0f52,54db6192,5c6f9112,759635fa,95846be4,6a28573e,2b25562b) +,S(4d54a2f6,dbebbee3,8950627e,8cf2c65,6ca071e7,86687f3b,a0a77178,be14c55d,6579dace,73dd14c,695fd781,218786ee,bad84445,ccd910d3,43aa2478,f5576671) +,S(f70b532c,e7203208,d6440bf8,55e1293f,cc6ebd75,96a04b27,9fc056e1,2ee32dee,e9d18f7,126ed56b,4a657104,2441bc08,1778736b,91062c9f,cac28cbf,b8737be1) +,S(bbf3ff3e,577aaf34,157e32db,d977b907,e62b16b5,1ae0abd4,f14e71fc,cca11357,cc1a78ff,44af7c2c,cdf17423,9b3aec17,b660ff2e,fc07953,2d9f9d6e,55d3abf7) +,S(53bb2321,b36d1dad,226ceb24,f55d4292,be245444,b2349611,5a649560,59729700,a5db4fb9,46c4a2db,b1a634cc,4032b7b,cf23f7d1,717a0ee9,6c02f131,24f834b6) +,S(3b863ec5,5e4ff2cd,d32cbc81,6e645009,da444255,9bf96267,2cd012e1,15372186,914682bd,d6a052bc,25cb4d41,e9bb28ed,76e9aa55,3f5aaf25,75140e04,eca69fbd) +,S(4cc4a750,d641c574,5c68a48b,953ee51a,258239b2,fda1f5e0,80831417,7b837946,cd6f665f,6f32246a,1cc8fa61,4da2783c,f4c7b92c,4f42749e,b6bd4a8d,8a84c54c) +,S(6f9b5d79,efddf08d,26183b4c,d6001d6b,fdad9e8b,dc5853,f3a8c47e,7e6f9e96,b81148f2,1e50152a,8cd7727c,ad14862a,37fd186e,2054d4c4,a4cdbfba,a9076991) +,S(9e13d0e0,44cd3fc1,1c7596f2,9946313c,918caa65,bcb6387d,361eec31,ebaa6977,c5f55650,7691bc2a,b2c9e4b8,512f7282,24276490,257288c5,2387fee5,54bc9c0d) +,S(a4441292,d0e0db3,2a4f33c4,8bbc5fbf,d40650c8,d9f5c4f4,88a1f69a,d71571bb,a23ef48d,38abc24c,608dd688,d524bed,a3709a5b,3567ef3b,e43f0240,796b7ad2) +,S(def598a5,c4828c5,16b7076b,9682aa82,4e74ab42,e4d4692d,17c8f289,67f3cbb4,e6b4bf28,6dba0803,e4a97a1e,be55a088,10660466,3d7726e9,300109ee,a1d62a49) +,S(8e991fb7,372df8d7,7b09436d,c9424a8,5a14888b,583b3c58,6d2a19e6,91e75b67,1780f6e9,b8379b0f,ebb1328a,69a96878,9f58b45d,8e3ff218,81d753f4,8ed6c43d) +,S(bae09288,e10351fe,fa0b0971,400ac3d1,a7eed65a,b11d1ba4,8a1c6240,bb981114,dfc2979e,dcc2de8c,abd9abd2,27cf7351,4079d950,aba60e3b,f4c775ac,72c30f4f) +,S(4d09ae3c,b484fe27,411d4142,e41de523,2c54c42,b387c7c2,cf42a23e,e7611fc1,b94fa116,27eaf5ab,8fb7fc25,1345eb28,8f5249e5,ec65e056,d60e1294,41481375) +,S(32f57ac4,3cb29fb,f8a00d8b,c95da8e8,3f0f541d,ed6c9e78,8af17a14,6a2704bd,2a969b58,9a3f9a5c,26b51ab6,1a5717bf,c06eb438,85e4f4a,84b903b2,da5bbf09) +,S(595503ae,e179f59e,bfc581b8,7ac18e1d,55b4c794,87d90d62,492d3ea1,1ec57579,1f25d8ba,e38c0a69,50a17836,a842b418,b0f7c317,9486fb16,9ba11b23,d315ada0) +,S(5555fae0,6f1563af,238184c9,304e26ef,f8b2121,394e6856,79de6792,31a56842,6840bd14,faf202c6,60650541,48bb87,df27b979,4ec0da66,9ded6830,b0623980) +,S(714321ed,2f0432f8,a05c33d1,84619de5,f81fb8db,95ab3121,c24fc998,ab9b9ca4,4470cdaa,7067de2a,e6678cd0,6d613e19,35b1edf3,bf278205,da69ee8d,6086c2a7) +,S(d41b84d5,9a0085b,86e88fc1,499151da,b0b9a574,92b01df6,36cc2288,313bb592,c04c54d2,57fe5ba,691f6023,bd72edaa,20e71a97,1a760bf5,3c990a39,f5ef7c23) +,S(ae34a065,b42f5158,e6a5b91b,9ff54b0e,6d5bc906,f6d18c3a,82865e,e9038f34,bf2c90fa,30639811,2ca2ed02,b7ad090d,8bc990db,b6140a05,afcdc80c,bae8490f) +,S(9b3c2682,3050a52,a164ab,f4504ca4,7750c889,b6465f95,658ba7b1,c279139f,ee36938d,8a675824,51ca289a,55265606,cb9ae4fc,8cd274aa,41db5ea9,9a5b4299) +,S(27dc9a57,999ed109,c3dff978,58d44ab2,73987af7,b617e9c,766331d5,c06e0dfe,4e97536e,67e363c8,add07030,d59061,33a726de,38dec51,e5a20009,61ee0fe1) +,S(c3415e9f,9c823521,bad3090f,f2c48e8c,647e438d,70397e5f,7d7a6f2,b7d7d4b4,8c3bb607,c746147c,d5efbef,7e27d236,c4063116,89794cc0,40c235b4,6af412d4) +,S(f47e44dc,90c8bd2f,150d9dd3,e4922395,14990fa1,f2fc361b,a24f853a,b37e33a0,f4282a26,bf5f358f,2dac4956,8bcc15a0,d7eddeee,b43e6fd1,8f35d5e5,4295ddb4) +,S(3cfa945e,6044ec2a,da895f9,9dc24575,deee57e,df8b1a10,a2d2ece1,9951a812,d0ab59a7,46ac6edc,69307a0d,caa00aa9,e7b73897,b89185fa,9dc3899,ae7e3664) +,S(29df8149,9d83bd0f,8fe61eb8,8f0abe0,96a75e5a,2cb0a0a9,76d8d27b,6533a4ed,7eefc80b,63f927c2,e905a56,62d5ed34,e9bde8ff,4402491f,19215c9d,494e62d4) +,S(eea85a80,566d13bd,da65f553,b2077607,c8b9184,6a5a8096,f57afe93,ada9fff4,b5389645,fd772da0,1cf3b535,6ec40279,cf76d812,11f20a16,71d7ecfc,441d71bb) +,S(e1a69e64,4434db7a,54550d44,adc43682,c128c560,3907615b,9282cf1e,e2b74f82,bd434a85,984a6e64,441134e6,d1f1a3a3,adeab658,c29af8b5,4bc42667,634d20ee) +,S(2d99f69f,a7e9f3f6,6a53eea4,381a4c80,ed17e8e1,4507d7f,4a80ef25,293c5fba,25a6aff9,a23a406e,9e34ad6a,21627acc,96b6ceb0,7896382c,833b8fe4,8e603e0a) +,S(d2482127,1554a14a,7283dc8,1ca70179,42a35cfa,c8659b2b,db78c426,51807cb8,a252027f,3fac319f,c767652e,469421b8,d34decd9,c9042d58,f8aa0ab,70e5ceac) +,S(bd030cbc,5f0de61,ef194eac,38f7443c,d231f75a,a0b568c5,416c5b8b,917545d,ad0833b1,4f1e23a,76c0626e,71129455,60fe62d7,4b3a1b95,69e4887e,c0661e78) +,S(afb44b49,ef00b1e9,59c7a864,19d2a4db,71d9bb0c,4e1746,9550d39c,9a37a161,eee390a9,530a5baa,5350019a,f756185,8038c2ee,7f78c365,dd6f62f0,f0589aa5) +,S(9e584f1b,e06ea4d6,5f8dd96f,206cf4b,88aec6b9,ccf06779,53acf110,99e2165c,6994ce27,46b0eab3,d8608ef9,33b61339,d3e589b,c2acb7bd,aba3af72,b082fd24) +,S(d2265b51,b4f7f4ce,1d0966,e7012f9,76433dfe,444b2351,9505b29c,d520c6df,44414498,df439478,328b330b,6f8c6876,682b6a32,b5d01355,2494286e,a635bf65) +,S(fcd56867,58c797c8,3aa1f1d8,a9ba34a8,8e624aeb,666507fe,706b310f,3342264b,680e0b98,455f0e64,94622fa9,e36f76d4,863a9fdb,a3df93af,c688c45d,fdc5967b) +,S(bb9a0c0c,74db0525,370e8235,9d733aa3,494afc03,fb61a1b,7c2536ed,9903fd91,239929a2,1c0ed586,b9bc8f03,af422994,f81619c6,b2fe637f,a511c07c,d9421603) +,S(2358b078,1989d6b5,666d9158,2fc640b1,13d52e61,ea2147cf,a0a103e1,5ae80db0,73f84f47,a78fe2c6,e4d01d7e,3dc10065,e052401f,64796358,c784d59f,742cc8f5) +,S(ddb3409,ce3184a6,d9d7b4c2,cbdf32ef,ebea1be3,595ba19c,42933882,237dae94,59215423,3760cdf0,513442bd,2fbef84b,9c8c0fb1,ef16fa31,783d4dcc,50f24f24) +,S(f99aaa8d,8d42ce59,86ee8ffe,d4dc8a48,81810a6f,cdfa9519,46f00857,4ab1c3c7,d0f29fd1,32bd65d,7f9820b6,830a3e42,8664f9e3,9cb25729,1adc36db,4e177187) +,S(83042093,46ced0d5,a33f491a,c98aae7d,51f17ea4,1e5722cd,29c47f15,49c183aa,1f680d05,ca015018,664dc767,4de0305c,b09efffe,e7b164c8,c733d2ed,18c15d8f) +,S(339f95d5,5e293243,ec10b3a9,a8dba385,dcaa23a1,bb424bbe,4c894deb,c61cc881,3a4ec84d,67831768,e9ad1d9d,db82f785,52883fd8,b0b63bf8,38495a4c,455d5865) +,S(f94de87d,1123f6b6,97d4536f,7bb6a995,ff158060,b7d72b9b,3c9d74c7,1afb6009,f123cea4,bd4859b7,a852270a,17c76c06,e6050a26,9c035bf3,6c505fc4,1fa81066) +,S(71341ad1,bbebbb4a,17a7701d,30dcbf7e,2a70b901,5f6c5ff9,9fb614c3,d3338fca,6ab14a0,4b4956d4,a687acaf,30d7997e,cf70df2c,b49356fc,5b86453c,5ef6d55) +,S(79b8571c,f52ee30a,4d3632d4,965cc6f4,cc6ea06e,fe1cb7a6,ca2c9c9f,1e835bfd,259c0c7c,b8fa8345,57febdba,2183042e,78f8cfaf,24a41dd8,2eb0ad3c,426683fa) +,S(f3ce9dd9,d879e70e,21737426,dbbb27c9,7af84307,6855bf4d,af141d55,5006e402,302a436c,f8be3a4f,dd70a9d1,8f63cc8b,ecd3ba1,ddc9aa3d,f4285239,61e7553d) +,S(4a66f7b1,52a8cafa,78d0e98c,2f8361b9,a0bbad47,d23b24f,5184477b,e90d6318,7555fd5e,87676154,8f7afd4a,33511daf,b3bc4a72,c9f54d4,92327a2c,c235c02f) +,S(cd3b4037,5cd6da61,ff432898,fc592175,c90fbc31,373489ee,c988f280,3459bba7,b0e86ab2,2f2d8d97,5f68a7ab,3ffa3be,511390df,5b647608,fb07f29d,3155728d) +,S(e96f166b,84d98bc5,41ea8885,f7a48612,227bc907,795782c5,d0e2325d,96cb44a0,18ac220b,8def89a1,e3bcc2f2,7a66c0ab,3ee27c3b,882dc16f,e2571963,92b94310) +,S(87adb3fc,7fe6b07f,795bb7d7,ab8383eb,a3f91564,ce89d267,599657b6,9d793838,68677cee,bc7b3d09,efd0f118,d392d0f,d2d5f2bf,f2b50230,e127acb4,97f5c886) +,S(fdaa2f5c,ad1da3c6,3d241a7a,b4365e63,8eede0f8,229a8187,6cd76a3a,7020c545,5b04616a,a1a84785,c4315dda,da6289bf,e57cb9e2,80c42395,a1b13d69,dfb2ddfa) +,S(7eafa986,1a94fc8f,d263cd4a,1e481e1e,8bc1a385,c4ab748,8715b032,3bcdb52d,d655b395,607bb0b,c9092364,803798d8,17a4bdc9,a30e2844,94be8322,42af9949) +,S(a7fe4656,98538c32,844337ea,bc90fb49,feaf2fcb,8b86da6c,d173bf9a,70e62a53,cfb26d1d,689a9075,55057ab0,d4261e2c,acbf30d6,cdd09f95,9cf1830e,5d635aad) +,S(8bcc3b82,d543f365,478fe32f,dc9860f0,10d51f74,b7b5344b,ca6b868d,3c11264e,6bcc32,f7ff3e48,fa1775da,44b64848,f52329d7,d8bb0a09,338b799d,7452b4af) +,S(faf9aa3e,f1ccd659,2feb2add,a1b58ed8,27511b39,bb981cee,4fbe47db,5cab2917,854b88e3,50a6e9a1,fc7e9e45,f3fdb69c,8111c654,877cd620,fd82ee18,ba2d195b) +,S(77012901,ea269067,4d8b4397,e8976f98,e33b1709,c81624a0,7916da35,af75cb29,b63695d7,cc896358,e119eb98,7dc0f67e,22a70c5b,5e6e2072,e61ef62f,9333bc4) +,S(127602ed,f5f1a04b,813e2b6b,2c27f50f,803b70b7,b9525b7d,902f348e,c03591a4,1f791f7d,2427532,968f7a08,f94df6be,a95b7e6c,5490fa9b,5eb5a3f3,207455ce) +,S(17e82c3a,3731a73b,36501eaa,fde3ee8d,ca9f2573,dae1e4fc,594cee8f,e1d19179,8af04092,79792fe2,273e3f0c,e642f3fe,edf1ffed,59c5826d,a7fb2716,ed365a3e) +,S(3c34e27d,5d5737b7,78e968a7,fe8e4113,f802bd30,1e0367ea,41fc8b5c,14b0dd84,67bfc61f,bbd062ce,6224e883,9092a962,eb3105a3,b6634dcd,d59c61da,906a4ce0) +,S(b7a35907,c7b55a8f,7173a5da,c73e306d,64ee0f6c,cf4f5c76,3416bd4d,4f5359f4,d111c21c,e5a8674e,3a64adbd,4f56b1c3,61350b,44a552fb,19186b8f,95ed534e) +,S(6c7d4836,62c28812,7b904cc8,969ff925,8d9fafae,e88f6d3a,e6e4d771,bf8ee7b2,b593dc47,3c29694f,95b00169,286e3981,afeae4b3,dd7a788d,f32a14fb,6e6a8e7a) +,S(dfc406d7,625719b9,4f709993,c5d15062,4c725ef8,eecb2308,bfeec0b3,6050bf4b,651c0d2a,fb29eab7,d4740b5e,1fc2c069,54ced865,7a6bb980,2de8d873,a451717e) +,S(1631fa0f,4e9fdf51,a2842994,da94f835,52b5bb40,348c706b,54079073,665c6bfa,de202803,9a8d1ba5,b133ff28,6df237d2,a8d73343,a08e7c2c,4560954b,eda5ade7) +,S(fc52b3a8,8f712053,2c7667f9,62146d40,eaa3e924,327d959c,a49b74a7,da11e5f6,7bf890f3,daf8f9d9,49e800de,8a3f5458,5aa46e2f,25535cdc,18170391,e2101daf) +,S(6b7036e5,c5993c6,8a744776,abb0b5b3,31a886b4,93e49d41,bc7d93b2,28566fd8,6ebe771,42a56189,f272b6e8,8f70f356,ed1a3d37,ea2d5e4c,998e47c1,319e2ec7) +,S(b13dc5ee,7333e3a,4b13628f,7ef96ae9,4faee9d7,3a46297f,f1e357f6,e7a57a48,4f30b474,99c66456,33f5b521,9164a890,d8cdb78f,8c7ee211,1bd37fc2,d41bb2bc) +,S(1888e944,6fe20426,d4fd677c,5cf1043b,605e93a2,c8532623,b5951e22,34de08ae,9e1f4fed,d5de001b,378ad1a9,98e31f00,30af9674,c383f287,50172e03,ea0b0f81) +,S(2495b334,9884d5f3,166f8fdb,7ff81f9,9042383d,def7cab6,3c2775ad,226189f8,846850e0,2a1cc051,eea77bbf,d5f44499,673f40c1,190e379a,9b37201c,51a06e9c) +,S(e4c0e483,f21102eb,7dd2a78b,5a605b8c,410bafcd,f2ee4bdd,fcfe1374,ab32d17,b53fd34,568f5edd,a6a3abaa,2d2c3a4a,bbeef0f6,c37bec1b,fcf012c3,dac15b9f) +,S(8f9bfd7a,2e798812,eb927fc2,b0ad5eaf,81a0a30f,a97efbee,a1d6d9ef,19348a5f,1eec535d,1bee520a,13a8410b,6f3824cf,7c9d5a82,8208d2ae,dc89fa13,8bb7c2b3) +,S(1d95c760,f3fc2eff,df51cf0c,4b708538,efb56675,eba3ff8d,4f6abe65,d3f167cd,c2bb1122,5016ffe5,6859da47,4b777703,49e4e655,5da3d9a1,6dacbdd2,d42ab0a0) +,S(9df72bbf,fbcdc42e,adb71d69,1791f073,7f945e8,bfbf4e2c,68c5e3f6,5f6955f,24d47aa0,1626b0ac,ce77827,fd7daff,7424d4c7,1d76ad3e,b66d22b2,6f7d1df9) +,S(2df6ef96,7c0e1a41,2bb48bdb,f2cdf8f4,22829abb,4b7a42e,95bd9cbe,8b7f860f,bace2e70,7915069a,bdecd097,9d133cad,bcfedbaa,7eb9891e,ad3380e,9ca99401) +,S(82bf2a99,624e408,188da19,59599de0,eb947438,fcd45784,9a731a1c,15796028,3b6c668a,e5b8f394,3ee713c,a8fbfde5,8ef0f9fd,84054a9d,b626e274,37e611aa) +,S(60260fff,1f213916,9261edeb,5f1d2d0c,a143ca69,400b2776,21793c11,fbc89d41,bec4bfeb,9d09f8d5,cdb11e3c,f65c6a7f,d4aa87f4,e41d7f4,69717a64,5dcf9945) +,S(6391ed61,80cc46fc,33481faf,d21151f3,cb678e3f,4d667748,1a24a01a,c5e9180,c48495fb,fa5962b,44bfbc4f,491b89a6,a8588fe,91677b19,b872dea8,8e34026c) +,S(20807816,758361aa,d5f62d25,8e3951c6,da518890,26507a7b,c0ceb7f6,a96c141c,8526d53b,61c8427b,eb141d91,7a338fe9,f7789a60,cc1a4a62,15dc754d,a73903a9) +,S(1ecceb4f,8acc649a,dbff29c0,fbc62c11,498c7cb3,7d29ed15,e0ebdf03,e994b67d,1c701af7,a9f3d870,81efb798,2382bed6,5d56b8d3,f050bfdf,6da32b10,a18fd4d4) +,S(be82742,dcafe3ca,f646cf01,80202cb4,7086e0f8,ccea3c11,dcccd9de,aeae688d,236d1fd2,5e05d6ab,8651d88e,33d18a3b,caa66c06,b2b68c50,f6158717,f23b4866) +,S(15252ce2,3f666836,dfb47b60,1e642abf,6e56ff2b,5d58fc97,ab09f29e,1b4ec3a9,9a6b2658,f52dfc45,32e6b482,fe909e47,ba7b4442,3be4d474,a524df32,d6149913) +,S(b0429186,21f94599,f7032b4c,1b53bc6a,9259f142,27922f42,fe774772,4b0ee9e7,e73c32d9,ede68eab,e77d681,dd4cbd9e,a356fdf3,bf066f33,6ff2c367,59bed08b) +,S(5fe0917c,1bca66f6,f34bdf1f,dad88a5,b3dc5f5e,2e0227e6,5f3a79c8,9e66c888,885dfcee,c0947b01,71dbaf65,52c09ab4,c0414f8c,7373ec5,e3080521,401ed575) +,S(455985e6,44d9b679,85980752,a13a3f94,94bf9cc,8e6f10ba,fc7a70c2,27ce272c,47eadad3,15e88a99,9d3f5ce7,792ebc10,2fc68f18,cdfa1df,564601f6,3b26c22b) +,S(3562aca3,2291c1cc,ed072a4a,85fbf82f,6b3299f5,2626154,2b41840a,1c868d4,ab4b2656,11db5875,10c48284,7f72c75e,f822f46c,2e7760e2,a46070eb,5db7100c) +,S(54225801,f82406ae,74416373,7408e94d,d3990eb0,60581c47,b453a859,cf63042c,43834935,a6a7acb4,9c086391,24e80fde,72c0a876,1c13a340,1a4e48a5,d96f6a2e) +,S(3c253039,fc8278b2,8135e21,700af1e4,dad4263e,ddc867cf,a3532499,c2c1e48e,ee01ce7c,f8c56c74,1b4b3593,b0cb90a5,9c59cbe6,9a48235d,1295c1d1,ac657081) +,S(8adead1,d898eca7,9e043f71,aa735a32,763f75f6,f6ba7a70,bc47a284,4b580972,7a370bda,412df63d,5590b3da,80365c71,1267cf8c,e3fdd1bb,91ddb981,d213bcd) +,S(8361e522,34c8d62b,9051a95,8af3f090,4f15ee35,4b69a560,7155ea4f,69548037,ca2c329f,8cb65e8a,eb6488f2,2131c525,29df97bf,c8847c87,47145767,7f82c954) +,S(97d65162,d96feb36,e8f00221,52c92c06,2e97087c,703a9dd7,7241216,2262807,15a260bd,bd591c7b,91bdcbb4,c2684545,4706f039,8fef8de,9173e7fc,a3f31f44) +,S(2609f072,5ec8e5ed,4ec86128,dcee3baf,9e62bc24,aedbaaa1,eed8dd31,c9c07503,d51fcfc2,55398507,7e471397,ece94d92,e26375d2,2bddc0b0,d1b780a9,65caf2c3) +,S(820e8f01,5b4ec57,b884dd3e,6a740d90,68fce86a,a4833636,4b65ba6e,9e272357,bfc87d52,eaf352bb,91f071ab,6e986308,4f197671,298eb614,93152f54,345ce5db) +,S(2116bb76,7a56312e,71ac58f5,ff2a7071,1be5b711,1e9e56d9,aa098af4,b991db0,2ebd4fc2,abd618d7,d1798739,7e9b8eaf,8276086c,2a5066e7,e7525603,fbb4c40d) +,S(e43f029f,97f4370d,65826870,3f29422e,7b81112,61364972,e26892f,77eed56f,4e265fe8,40524def,23b7ed34,54c6618e,ec70d3b1,92ff30d2,1b9b6fc,b1f7164c) +,S(9b4ca445,5cada269,2a77f7e8,9aa3082f,ace4de3,898408eb,6a7d1cb0,8ac15c14,1446e397,d1c3fd20,283f43a8,4679e728,64f05251,b1d3bead,58aca70c,4c0fcc29) +,S(e2abb09,c0566f51,7947f99b,2d6fc4a5,637310b5,5f9d9014,84decbb6,ca22cbfe,f334bda6,a1d9cfa8,2b18f8f7,e90b8426,ae13e20d,8834e061,ab1671fe,4f4665f5) +,S(3579fd9,9cdf0be0,2d7e8587,2e213ed3,3a424650,5608d66f,8f936ae7,72511e28,dd93278e,ce754f69,4b3f09d5,a3c32c99,2c5f2e04,cce0a517,de750a38,ccd88abf) +,S(f307f2fd,d0f6c0b3,12841e5e,1e17b966,47d7ca93,4ba4970f,4f9c0c0c,3ccb071f,4829a5bd,40555e18,bf80ae66,b9742249,32679acc,d0e46003,e079e2e3,d20d248f) +,S(a462e750,9e718317,dbc72b9b,fce5909a,bdd2fc36,d56a525,97d3adc1,fe4b98a1,2f9ee390,13b70415,d2e6de97,7aba55ab,1f7c6f2a,a5a7b541,a7101a62,f2799836) +,S(72ec447a,245624d1,1e1270ea,1c4c060d,c6501f11,70c69f4b,229bb98c,e7c47804,cc32a876,33bb7d62,e660ba5,59cc1804,10a51cc9,dc48a9ae,fc3d8225,35fb8ff2) +,S(b97345ad,2a7eedfe,71ae185,11a3e2d6,c431e628,363e01a5,21622c17,e92b32a3,2ba1cb4a,abe0aaa9,619ea819,4e5c0222,3bea32fa,e4ee3378,ba798472,19670e2f) +,S(f417f269,de287f06,8a74a330,14331059,73ee691d,a7f5aa1c,4e00a100,1e2ccd56,1bb297c9,5b3fb72a,3263f126,719a82a6,b8bf415c,e81f6838,2c8b3a9b,42917584) +,S(cdf7b5d5,f7632248,be1bcc1b,61f56491,e81cfe76,1ee897c6,fcebdf4d,109b9b41,118f3f6,32f18892,d37a2aba,1c8d22f6,587ad56e,eacef09,b9202005,75ab7b11) +,S(3540c9dd,992dc4e4,9aba8fbe,8f28950a,24921b05,e1bae568,2714aa6a,95eebb81,841d9499,7bd92dff,53ee3c86,eafc5f6c,6ffac94d,3161ae86,2182caab,8d5a9268) +,S(70f4ef3,37a5519f,466cfdc7,ae779588,74c9a9a1,9a558550,8fafe6fb,d61decfc,413476f7,78f5d377,31aa712b,5c866100,bcc2a33f,ae1a078e,c5e5cbc8,4b7bac5e) +,S(d08990b7,ad5c205a,e5be2700,63bcf8a7,e13c2a,73dbf321,b0d9cdca,a1648da6,b0aa7acc,f47376c,115b0226,1494162e,d425b496,a2392aa9,254655f2,4db6cf48) +,S(53d6c5ec,f59c49fa,d970611d,b8423bbb,e2f5aecb,d4575877,d903d95e,eb88e455,6a954f77,532c80c4,42f2bf65,8e9d763,617c802f,369f1a62,34927e55,ac549f56) +,S(af7216c1,e51fbfb4,a5ec1e93,717f7375,9f15dbaa,86706ca3,6636f499,416ce194,4ed49771,f858a8c2,bad65a31,b5ea5a53,8841553b,accdced4,8c41e2f6,984470f0) +,S(c560d2be,2f2fa6d7,3f5224e,36acdead,8d91eee3,b99a219,a762adfd,a5e79d07,30d4b54d,a96fcda2,2187a2bc,1562d59e,24ab55ce,f9cbfbb8,570cd89,4d436343) +,S(30b40200,c728bdf7,510db9f7,a8a63792,ff70a9f8,c6262e89,4ef902b7,eb30fb8e,8c98fdbf,29f8c5c1,ce6d7d4d,61a2907,ab57b4ea,a25888b9,e8ce751d,6a19a88c) +,S(d7239e30,814ef236,5193c19e,dc91fcbc,955dab78,45b4f3ac,be994264,2a434e1a,454dc941,4500f4a0,f93f751e,1e2d4c25,8c0f10e1,b4f0c6f,3be39b0d,e5170dc9) +,S(60e511c7,7c8d7496,a3f262f6,376d3958,dfdc4645,73aa303e,a6e6672d,b1c21b36,bf86ea8b,c8a37a4e,c5ee1a60,d6e1888a,ac90530d,eadf40c5,b4f61a38,2ea1e340) +,S(55cd8f35,5a242219,3b64633c,27b1c1fb,7ffeed51,c815e1fb,ebaecfb2,3883d739,b6508643,7e53ad24,1fdf4dac,871e58f3,b5abb87a,d4920057,3c37a1c4,b2bd4b3) +,S(73cdc2fd,468a2d21,72a9e0ea,3d4a04c5,ab5fb13e,2e2ff2e0,8af5d70d,ac9bd41b,682e525d,1263abaf,f070bb47,6f754da9,f6c74d,27f319d8,5d9d2882,6d06fd04) +,S(e5f30676,3c9f620,1c5ada9f,6d01201f,97e36fc7,5bb10a12,4cf69cee,619f07fd,611f0f16,39aaac35,5e311a18,a5dd65ca,70e1a52f,452bed2b,3382ac03,dd50546b) +,S(c2c21323,b156ca78,5e53c41d,10bc235b,8e32e4c8,ee377fc2,42d089a0,d2a27d84,6b9f3faf,64331dda,d25d603c,d8f334c8,5cefcf5d,3bf640ac,96fe3bf7,71ce9cf5) +,S(599ff1d4,806aa8c8,b1440a92,9e2383bc,efd9b16d,899289a4,a335dd06,7e63d9,459cb346,7c387470,1b86aa34,c47b8214,7f48a0d2,7b9098bd,2b53d7d8,93e25316) +,S(f02ddd62,a2456e7,b4a90bca,1cb01e98,8b0a09e,62c90154,42db0f52,b635b006,a5666540,6cad4d01,aab99686,90a7ad3,b1ce936,957c317e,57bdb763,b8867583) +,S(f332b89d,1977afdc,aaf681a5,19bca58d,59852f74,78572346,b688d55a,d55a34b,988afdb1,afa1041a,51ed913d,d780b21,5dc90b8a,b5ae857d,73df2883,50ca78d4) +,S(d6fa4679,4fd4d05b,d6b7bdae,22a970f,8c3c3628,ea0d2656,55c0ebf5,2f1b3a73,d9f47018,86512ff9,9c4691a1,60b62e2,616f5c8a,fa2151cb,fd6dcd80,308ad947) +,S(2a13e09f,5c00016b,d974d62f,2c7c7ce9,e46fb142,e7334f5d,98fa2428,e26b25f7,f300cba4,26636d5f,7f8fcb2,bee6e5dd,b9697cdc,9f9c0636,b02b3fa1,820ca235) +,S(c6480cb1,c1bd41ff,e57cbf57,ea854158,36284048,e79dbb51,44a59027,13d13ba0,fee7ee1b,1652e63d,ad49736,8505b302,f135df7d,4a2f8720,74631646,244cd43b) +,S(559613e,8111c9e8,25fa96,aeaf4b2a,4019ea61,4c67446d,76305484,c9a4d7f7,cee9f4eb,2680a723,9187d407,f39390c6,4fed596c,b40f58a3,aa6c96e5,c8c9c2af) +,S(3a95b2b1,e6d19b19,84dcd59,501c33c2,4ca50b59,d410d99d,b9b6da4d,b1dc85ec,7a802198,a5c61542,81669bc0,640a8f40,6815d25,3bf8090,3ed894be,a1b09c72) +,S(5ae541d,b816522a,5d347339,713e92f5,25a637dc,75c9d9b1,5d834f2d,b265c2,e98a115e,f76b2102,7953f65f,cbbfd29b,a79b43ff,8cd6813a,b65174d2,b03027f7) +,S(88b5506a,72d681bc,d34eb118,3d6a7fc3,77e7f496,6d4c65da,bfa60a18,210ec487,c29638a6,ad91272b,3525ab40,1ebcd1ce,ecebab3e,b506cfec,e7e9df0c,6ee40501) +,S(2942de16,93ce8b88,e7e45657,daf88b2a,2118fb7c,9d2296ed,a1725ec2,f7d408a5,778f43,8b4f088e,fb99cb1,819fe6e7,55b0641,8d8679c9,d684faa5,16970f5) +,S(25c22037,e5a46e15,4adfcc47,480a088f,fb53410c,dea814f8,a4f2c387,df2afd0a,45cfaef5,5c5d3742,3380be3c,c38e6785,c85a90be,7cc92fa7,a390bca6,d3e7b3c1) +,S(b1f78a73,d0b935c9,80cd8ab3,b8237e3a,df5a40bd,5f875f7f,bcb13bfb,cc45839a,466141e5,d465c35e,37f80e57,c4923c84,c3a3ba98,549cc8f2,db6e0dde,915293b2) +,S(39405322,a57a4846,d8b42bb2,58f851cb,5570295d,71ded6cf,b803852a,8b4d8304,c81047d5,92fab5a8,c6139ffe,6887d966,e809d2bb,ee3a10b4,5adc5587,ffb302b3) +,S(7faa8352,31e2c6d5,b331ada,5e175954,6142b131,5347196f,bbc5759b,dd6add0,8779b0c9,2c176b72,5355bfb5,ccf5f739,5fc82ae9,48896a38,1be85e58,c48d154d) +,S(b786c145,61fe4677,54e14766,56d33daf,adddce8,e86e09db,ea93f1a,2ff0c3c0,4c5c35f5,99bb9637,75b4d61c,b30da8ad,a4e83a56,2cf7d2a1,fc22f06a,fff92aa8) +,S(ea4b9a9a,b4b509da,d1e70ebf,6604d624,8b6b63d1,c905720a,648e208a,993ce4fb,f5ab8356,ce28ccb,b6f1368b,344e15dd,372d732a,d8953864,21ce415e,6f0a92c) +,S(c986010d,6339bf7d,2ae3e9a6,c977b9a,a2033a42,14a1e9b3,e700abd5,428e2491,4156f13b,a68ebc80,ad12efe2,d5a0469a,a41adc0b,1dceb765,f651b4b6,b652a85d) +,S(385b81d6,e023164a,3662209f,5d694910,22e84b5b,7034e8ea,346941b9,c04df428,9d12b15e,c1868f27,362662eb,cb3c9bc3,1626ef22,36c2d75c,65e82c75,7ff81a2d) +,S(82196a55,104624b7,6710b4b,864b738d,36ebcfec,55226aca,990474b2,58aa978a,48dbd01c,5af9b1fa,21d88b0f,f6b994a8,38d47755,5ad85171,1a4e3d0e,14ab1914) +,S(dcfbdad8,34d74f6f,9df6c143,abd6dbd4,57f954ef,6323ff77,3a19c367,8d6616c,698d3051,8f8d7ffd,b45f0bde,c32c22e,2cb97acc,a8aa0aa9,c16d8789,a128c3a2) +,S(343b04d9,babecad6,5479cf60,e43350d9,8c56f989,69eeca59,5a5e97d,89c25489,14d00978,2729ea38,a79765af,ce78ff5f,16ada59e,9d275274,e6e0778a,facc25ee) +,S(25af2270,88a6beb,7c76a80c,9e87a412,ed166a71,d65d5722,a082e57f,8ac7bb77,d01d89c7,39508a84,5ea64e03,697c2867,5b14bbc,fb484f94,a530e57a,cf19ead9) +,S(1292823c,1759fa5e,48d0724e,67c93df2,c8ce9fef,9124c5b5,8a477aa4,dd3f5e32,c481025f,ece1bed9,26ecd3e0,3cd7eddc,3cc31836,a12855d1,639a85df,7c69650e) +,S(ed92246a,5a5cb2a2,1618deb0,794ea013,20560b42,273638cf,afc901d6,2ff0bb6e,3675cd33,825e611b,8802c746,9cd82b97,b659e31e,c31ceee6,681a35d6,2d5097c) +,S(8174e89c,9b3666aa,69ed3bda,6c73c572,ff3384e9,60863f87,b7d346bf,afd553df,154d75ce,caff95ba,4b5b7b7e,9ea99dff,499a522b,f0252691,cb6b92bd,98182d0) +,S(54169816,f0440f73,1f14de95,e7ab32b6,702c0183,62794ac9,e55ad632,95c4484d,12e541c3,ee64efd3,b5b8781e,bcc5e273,3544653c,d8b55d51,fa3f887e,d8f42465) +,S(c654d2a5,e31ce452,739f9cfd,b2784d37,eb974a4,fda45fad,13a2aea2,f7fdee9,47c9d2e5,24e7391a,f645ed92,cb04a0e5,6aef0362,9b57d593,edc85b1c,686ca4b1) +,S(59724a3f,eb1a1cd3,7fd6a5c,57c3d055,28fbdf48,5102e709,7ac35912,3f9c2ed0,4df18ea4,c0de4053,6bc5a6be,2df794c3,2db2a9cc,19367473,d88829a5,8603010) +,S(d99168a1,3fbeee0b,6aec4b7b,a0060649,1c4ca151,1cadddb9,2ab3478a,325b1073,c2b0876f,528de53a,f2f695b9,b8225fe0,4660a447,c9e9bd9e,4ba5e52f,beb0ce6) +,S(769c1b07,c26b402a,9a4b60f0,5bb0b318,d20f65b4,e941f525,43a15697,5a8f876b,7880299,413ffe86,94a76f26,9acde007,6e64a753,94701bf0,84324215,debf3d69) +,S(6074f53c,ddf9467e,b9fcc4f7,ea4b18ff,777abd8,895c9eb9,71195a9d,57b1b1ac,de1aa32d,e5488e69,eae8a06c,3c89422,a26f819f,af3cd9cc,762d7fa6,1fda3094) +,S(1f9ea27f,3e9e789b,1cde3fff,94bf8046,f5399046,867a2f37,2da59221,e85c655,c47b5ce1,3d399032,89449260,7db3f7a2,52a74084,20ab1846,fa378674,1e7bf7dc) +,S(c2551e26,5d3978ce,49cee376,ac86a0ec,7ba10804,bd894019,e79f51eb,ec9830c3,23dc4415,10635bfc,2af8f85e,c4cc59de,fed9e9e4,198304f7,e57a1f42,736871b1) +,S(2ca9e4d8,3358ea8a,40bc15b7,8c06169d,ed7a5abd,47147972,45078e94,75264d20,f3324029,9fe328b7,ecd14a11,6fd82bf6,5d925532,85a176a9,b7ec892c,ebb2cd94) +,S(e0db4052,8e3eafca,1f514b26,8b673afd,277c5aa9,e2dbe85a,74478d6a,f2ec1f94,f868c782,40dd75ba,3c6809d2,d62f80f1,ab7fead3,c67a90d4,ecc242c1,687376a7) +,S(d34cd3a5,764d99f3,16a260c,9659955,fda3cd9c,cb305f73,d3aaa61,27d422f3,3f3b80ef,74bec102,2e442e69,8fd4e28e,514d3a9,5011ba18,1299793b,b760da72) +,S(588dadd0,79d2280f,37dbeb16,3e05a70f,48ec61c7,cf3e6455,f3ea312d,4ab2e075,731a5c9d,f803c2fd,b22de461,d51af493,5874b745,4ab8417a,940383b2,9404fa3d) +,S(1731c955,931905d1,ccad3bc6,133f5d9c,9fbb10c5,e800be80,643ed02d,6d7477b1,d7e89b3,1f18ac07,6c7b7380,64d2449d,2d9beac,728ffa8f,6d8a7498,d43baf1d) +,S(e2f990d7,6818c0c6,e73d066d,5644e9e9,29f495ef,507b18cc,594871a5,88e45b46,2ca12307,fb565d0,7c60b6c3,e92c9757,45777970,1733c0ad,2b299a20,8f50925) +,S(b92872d8,a146c0da,ec576be7,35a22896,5242cc61,ba37313d,31b0e5ff,21a2273d,8178dd34,e552e97,fff949e9,b101b44d,35d6b57e,79c0e78d,f91ff3f,2817daf1) +,S(b980d2e,9440c3c3,be5cf393,6eb9634e,923cbde7,bbf2a07a,d7a97287,7d6caf11,51b7d51a,8685bf75,c6d376d,441dcd69,cac67b77,762f6ad6,97a9649b,f3d3719a) +,S(db2f9a64,3c3e3706,e9b5aaa4,5ebf08f2,ee9e967c,205a49c1,7dc76b8f,b20a3a52,d05d486f,ab967e27,b9e8c175,e93df203,4657dd,750ad788,1bcc4897,b80f3d40) +,S(5d5985f8,910be82c,538d70d8,9614ec3f,bc9e1f91,9a19950b,a8fc99d9,203d92b5,3efd77d1,27e43849,a710d1e5,7b18b681,c1acb293,2244fa7a,30f360ea,88565e35) +,S(fac2a758,a063dd8b,46b41933,9c70d2ed,3807bdca,69d3b36e,6369f8b1,23200866,8294340d,6154afa2,d7b730b1,301f5ab,322bdcf8,6fb5676,78fc47cf,b15809e3) +,S(cb92092a,d45ab0b8,559846b0,d02a0c67,a13edc86,7d0cce5d,fcc09e63,d1b6cbde,d2593de2,6371136e,390bd52a,c9811334,e13fddd4,e9b86b1d,942cacf5,4615b287) +,S(d715f4a3,66a4a770,bec8abea,49ab6c7e,99e9473b,73e479c,14011843,9470c844,40aff69e,ec6da9bc,38ec119,df4482ff,3bc2b67d,31284db1,8c757990,de6cd0d6) +,S(77312617,4a395a4e,f7bad07d,f2f38843,22293a17,ebf09f20,4732e7f1,2c418417,602cca39,d6352365,420c5ce2,9d2282cc,5d8919b5,e0669b09,22384b69,7bd48a7f) +,S(a7c4b675,f529ba17,e9f1ef44,c88a8066,66131845,dd98da82,4cb04f24,518a4071,d88edc2a,1eb0cd48,57283e3,f8658d8,2da27a7c,7ec16129,78fbb484,41ef438a) +,S(6362f575,d459b970,db814a7f,9a142605,f26f577c,4357be2d,dc16793,64906f7b,fbc9f007,bd08b6ef,cd49c1f7,1e199fa5,ede01123,5d9b015d,515bf7a9,7192f8c2) +,S(6cfc45f8,515813d5,dacdcbd4,c34c155d,c66b0298,8b8a8702,73a5342a,9249b623,f85c980e,394ea0b6,39bdc5a5,ed185de1,7b1f44cf,b7e51c7b,b9f56b3,496b5ee) +,S(d76c0b83,b8a8a8bc,4e8985da,f6f1535b,9ff3b4fe,e13eed4b,39d6426c,87cec8f6,15ddc103,bc6c4f43,6f7e23a4,78e47166,e3f4156b,5ad2d581,7f3a7ade,7d80dcae) +,S(c4f98324,57330d12,e4e26735,464f24a9,a93dcf75,9194fcd8,a2d12ce2,bce0449,e24a6f24,f9a09aa6,f58f29aa,f4e24a0f,864410cd,80280432,d82cd9a4,ea2ac2b9) +,S(e86da865,238fcc7e,d8c2721f,89c2619f,a2caccd8,5e05a21d,8d23a095,634cc439,85b35268,31871eb4,3323caec,13de6de7,94ddc6e7,5d44835b,7443137d,25ee2194) +,S(a6398918,6969469a,939e774,eabbce54,109b833e,b3dfb566,876cf50e,bdc7613a,c48430c3,fa8c730b,dccb53,451b5a38,888f2e85,1f510ca7,64360c9c,b72b6eb7) +,S(6986ef9e,88c8dae7,ecc8184e,a4c5d131,32a87ad2,ff8367ee,63fa0ecd,b7a2972e,e9acba9a,896e1eb5,bc1d2625,983fd2c4,13f54b47,3056a893,7197f940,92eb4bf0) +,S(47bf849a,e428bdde,ceb221ab,e0ea2fd8,c0a5bd39,175aab96,c2fddc57,e809527d,401a7ba5,1999aead,4dfa6ce0,fbad17e8,e7187e52,806a58a6,7033f653,67aa7c02) +,S(c0c02bb0,92af6a5b,73582a14,89067933,8b31318a,f2d5b142,d58833b4,cf07fbe4,a19dff69,5ead3a33,d8f9f7a6,76b8287f,4bf6b23c,6761b084,12d86508,830f8990) +,S(f2185913,405156ab,22baf16e,644063da,b3ba25ab,f191efee,1ff028e2,f7d175e0,814c64f9,9a4250be,2265cf8e,47c8276b,9e5245cf,16ec98b6,b789dd26,be894f3d) +,S(40d840cd,ac4060f6,de850df7,c37462b9,b4d5892f,a1e74f35,89ab3955,a5d941f8,9892b0dc,ff43a872,6974705e,3a3fd077,c2b91a2c,1c6ee153,7b728359,d3217833) +,S(6f6b79e7,9006fe48,5546c3e8,52a33dd1,cfb63f3,96b44d1b,af1fb112,93271b35,f5aa0beb,50a628b7,b5348817,8344527e,d1ecf0ff,a0766a78,faea2361,e8fde7eb) +,S(4edf60c8,c0488128,29e7bac8,7b03ce49,c8df0f1e,6a3e02e2,ea8ad097,f66163d7,9861393e,fcec430c,c00ccd49,3d4e2d2a,a45e1034,fd9a81e4,b015bd5d,56f16dea) +,S(7ab0c44f,f6a444c4,e0feb1c5,a6650c37,26249caa,38f53e62,b6bf225d,bb1e008,e7f9af86,a2839ce0,80c6ee9b,d86529eb,7a7abaed,aa6aa4e7,207e67e1,a500e5f0) +,S(6a90e50d,3dd2f382,1dde8714,57012b3,5c1103b5,80ee4982,f9bb78d4,2541f8b1,5ccd34c1,8455aa76,4cfe6c9d,61507ca3,cb613bf1,4b9eae3f,8391e1a0,9dec03f1) +,S(289d4d81,cccf40af,a61ef56c,242ef8a2,c9883267,54139e1,dbf018ad,5d251df8,f3fead19,c49de6b4,32869220,7e60408e,dcdfad25,26e6e555,9b022941,592081cc) +,S(a1ee466b,c561919,2e82a316,ac3b7514,b109f442,1c93fbeb,234f5862,d37ade3c,db12d4b7,246e8ee5,55dde2b4,9b5c42e7,408eff9c,a853af00,5a6f6c7,73aff21c) +,S(ab30a856,403a1622,14be9837,2ebaa8cf,8d946074,abfddf2b,8e65e2aa,51554329,7a6b7f22,a6ea52be,8c0c8002,29613020,a247c026,86eaf960,7fc56cb7,d696c56f) +,S(17c5f1b8,8e3e4e08,dab8a5c9,2a679c05,688a7437,df6336e8,7b0d22d5,ed56e5b1,96068e6c,72fa9b39,5993913b,305caf70,3186404e,17131b5a,24e14273,a83dccc9) +,S(a76fbdb4,b99e31ba,c434462a,64c0557,8e961a53,dacb9bd7,68400b8a,823190ec,52e31883,5ac1a3fa,e269a4d3,17bab065,7e890844,c3fe96c6,d04fa015,89c89f14) +,S(17b8bb76,10476261,ebd75e4f,299f1805,5c88f36d,ae65cc57,3c959820,25bb794d,1bd9a52e,585a40d2,67db59c6,b9b1bc59,4b8d5344,29b5d4b0,82bb1c9b,b54e0392) +,S(65aa92ba,8fa51cbb,3954b93d,68cfdfa4,d64d97c0,9e099b1b,d1ba853f,18500b37,a2b12d21,b7a1ffd1,af48e4fc,e80c6fc2,e624783c,7b0cdce7,9f01ae7a,5fc96e14) +,S(3450bcca,5d3b30b0,3743f0d2,6b61ea09,de6ef7cf,eed44b3a,c58641ab,93ad7867,4fca3307,5328a298,d310d447,4806f297,3b09d885,9fa3b949,11817d8,39be66ad) +,S(484bf072,134849c7,695ba73e,5f25a8bf,74a183f2,bfe35ad7,34b53878,a2036be4,a5295452,a0830b3e,3c45043,43fe950b,3289d402,73d3bd49,6c0cd7c9,156a1d6a) +,S(2cdf1bc8,920ec641,63fbc8fc,c72fe5c2,dfcb87ec,15725e04,163e1ac5,1b7ec763,c680476a,28f054a9,ac3a073d,67ceecf1,c8262ed,4bc462bc,44798e88,d0e48e54) +,S(59c3c60,8031a214,d3e6be15,c644265c,b6f3526c,2b37d840,86532c24,52359bf9,2248b28e,922e0468,fd98856a,41ca37ec,2fc7bcf9,a13c7a9d,b4135e28,5cdc1bf5) +,S(4f20493a,a7a1e558,a44e54e3,b81c889c,d45b6384,9b8448d4,20a34a31,c7c451ef,bc1adcc0,d00384e7,93c2433a,a76f1f08,b8b23170,6e285d56,3155dc19,d5aaaf1) +,S(bed9949f,dec9813,5bcf76b4,83117fca,57525221,8a6a52c6,a44f2468,29d48ff3,6ab35499,8cad07f6,250dec89,a0840192,b62777df,6e241a4e,325b0c4c,bdad23ba) +,S(1cf32b2c,46deaef6,fbc892ae,4f05653a,3cb69d0d,821a7125,3c2eed77,4e75f767,caa6268b,b8574b47,840b3626,74f4a479,5a2c6478,c440aa4c,36d88a2d,ebacc8f6) +,S(9d3f7c5e,5e0947cb,d9bef5a2,dc1a3e9e,ac22d6a5,9071d0eb,5f270100,3e66dc96,6ad63f62,22f3a787,9544c330,4c3ff653,2a00a764,5ddce01e,c4ac4933,a5c7aedf) +,S(a5a927a3,f03dcbc,b3d069ec,156a6ba3,474f48cd,4828f54c,a673e10d,265eab6c,b5e360fb,39f65847,b63eb29c,a8b403d3,272d9ef1,8127d3f3,7650d13a,9a5736c4) +,S(48de778b,7bf72a21,871ea379,c02b8887,5da9688,37faeaa9,93e68eea,926db673,d25cb808,7a7c13b,fbe8b1d5,522ac2db,6c44526c,13ca0327,586d6a5c,1aaca91a) +,S(a029831,66e7cb1a,fff65515,48faf447,cee8ab2c,d4937269,db002cbe,b8f1d1ef,ef34ec5,42554e97,1ae8897,b049097e,3430c99,d8e93c50,94377c07,a5619ea) +,S(6ed75b96,c4e976cf,75cf0b72,df83c043,5b15d2c3,f8fb319a,94a4d97f,1394df6f,9b63c36c,1e31becb,e1a5a6e2,1abb99d0,d5c39694,cec00fd0,ffc27b53,309bf6eb) +,S(9372c1d1,6997f792,688a55f0,8f246cb0,f206ce31,d0f416c0,c81cbdd6,8487aa5f,ff97433b,be60eaf6,6f19c182,e8a8bbbf,b24cdcb3,7aabf79d,5dac9f13,9c5033b4) +,S(269c7d84,b42f90b2,f39b4db7,5ea0724f,fa6a1a5,4c66a1bd,a21e4254,6f243bf6,8f6f8b36,e278c6fc,bb0c9918,7325f1b9,75ec3add,69708be1,b4703c5d,53d8f8f5) +,S(62f9cd79,921ec46c,d470a12a,9619ad4e,3bed051c,14f47071,e55f9da7,d103793c,92211db,6c846f43,2867b9ee,3b1ff00a,a08f179c,13aa7475,d64d0731,23a69e4a) +,S(fa432dcd,e7e3b40d,a127d65a,e0955d58,a009d81b,46b48745,c4e24597,4e589a8e,a8dee557,cae7e50,d96555ce,c56255b7,c64d10b7,6639b3bf,8d60aea7,58716f68) +,S(a424d18d,c6861074,40f42e5e,f2bfc95,f4c8f94f,e3adf681,79086502,fd9d80a4,cb30797e,1d973012,d488f54,6033b1b3,d6b50c8a,39badf8,fcc12bfb,3a1c4d0f) +,S(c2a6369e,e2857d2e,fce4ab31,49556c08,3ac6af90,6be418e5,ddc5677c,f2f7ec8d,a7097ae2,9fea3774,11ce3f81,b6b3356c,9a2abb69,986ad81f,46b13f8e,a0e7f0a1) +,S(f5eac1a2,3dc91862,d8022931,3be5c7a5,364c0880,23c0650e,53e22f42,2f91ec98,7dd62b80,3ad606c3,3d8d9bd6,cb397ab8,1cbd688f,8375a405,23bb7315,a3f48c24) +,S(dd94fec9,3bf7ec6f,cfa0ced9,df31a1c,131c39d7,e110b5e7,b988c59c,dd594fec,cb858565,6a32e03e,2eb84732,4bdfe2e6,3601148f,7bc7e56d,22cf9aa4,54f063f4) +,S(d3dfdaab,8f9db2d8,edd3db27,d96be5d0,678e9088,5448222c,5b3171da,38fbd501,6b210554,df32021f,35170e13,42e2da18,72be61e9,481a4b74,ec470ed0,b942025c) +,S(47ff9918,3e452838,f63eb828,a239d95b,62f8a746,8acd0b43,6c149985,2afbe3f9,33b7b8a3,a5b51b15,fadc1f9,baec6b8a,88e0da56,5a54bea6,1b2d728f,eabbdc48) +,S(1e99e92b,aae56401,1cc10c94,dac071a9,27565a17,2d6d4a20,224e1b49,c007660,914b98dd,a92484e5,a43d7de4,7bbf57cb,2346d852,f743fdd9,15dcedca,4393aa21) +,S(e150364e,d95ca778,70fb3367,64f9f417,70bb672f,7e794416,13678dd3,65d84fc8,23ddee4,30d7b565,cf545837,58df61fc,502bf86b,a4cbc1cb,7630a9bf,e339ab85) +,S(44dbe753,dd822ae3,f3ef4939,a1d96a98,33e697f8,c4979191,c64114f6,71e8fbb8,b909bdb1,e6e55571,b03517a3,c2345b49,a5793d21,15fac018,2afbefe9,c726c8d5) +,S(fb843458,725d557d,b1a17ad0,427b4d98,6ba189e5,d6da81a8,81867259,6d9d2858,18f1c9ea,bd8e71cc,72e2dcbc,532b101,c7381475,46c24790,d010a6cc,32d4eb10) +,S(48f43c41,b63bbb05,57f8d71,edc739a9,57baed23,efe9c814,848c54e8,54159144,cb75c418,d5557cfd,b29d4807,3f193343,6eafc209,bdf9685a,72f57b98,6676b193) +,S(5520f175,9be037bd,cb5af2a9,a0bdbcc4,9e1531c0,32fd17a4,66f59b38,6d7de1b7,45b933b4,cf256aa3,c6513a2,8a4eff90,7691a34d,e6cc2e7b,a0b83f8e,a7ed4e52) +,S(83936718,1d7d065d,5c15e246,ce8391a4,bec58c71,7f82419a,ed6547c,63f081a9,4c903568,f5ce9a54,65fa845f,985f24d7,6e66cbe,3ce256fc,1703b4b0,5dd636c3) +,S(66a82c47,e756062f,6586ece,86911ac2,23b84c9a,e53e5307,4e22bfbd,3eae6b30,ab2051c,4c231a40,c6da6ac3,5ee32b9,b7eeea17,222cb1d5,a3abf9b6,512db8ec) +,S(974ce35a,9d5a4ef5,84d252dc,3c365423,1335c52a,e3daefa2,8ff9b75,56bf3b46,8c82a9a9,c49d167,4f3995c2,90ae06ac,fa0a5c14,b1c5f41e,c1e449d9,5effb2c0) +,S(1139c2f3,60cb8a4c,e020bb8c,3d19bce2,1c6802e8,5fb3df33,8fc9ffbc,8fc231b6,59adaa14,7980b3e4,73801b73,9f1e0248,2e9f1e17,65df2ec0,183d9f81,d57723d6) +,S(c1bd3793,3b03d95a,b17c10bf,c5167556,4294e38c,740fa3ef,9b356be6,71883b94,c68bd82f,5e926a59,95a83f1f,1a8c2f4,5966b073,91ee74a5,ae2ed99,106c6dca) +,S(c7778ce7,ce668003,86db9263,cddcf608,aff769e4,b4755858,20554ecc,8407bbf2,92509200,9c57f224,8f9b4e71,532c698c,88b91b77,4a3907ae,1ef30c51,78d807c3) +,S(14aa1177,51626b67,8f32418f,1855cc34,52d4ec13,d2d900d8,8a22432c,70ec022b,6151fdf4,f4372a2f,e803478c,da340678,c18a0a7c,d540b0bb,4168f9da,2edd6d81) +,S(a53443b1,b6065cb6,abb18c84,1f171b3c,7152b34,293a7ad1,2e8599fd,f1398cd6,3a07e076,35254aaf,eb30efea,328e3ffc,3a7d280d,5cb2c8ae,9e70b412,38fe704d) +,S(35c3e3ab,ba4c946b,1eafff67,a9831588,d6631e18,9507eca7,66e22449,f8d294fa,94973920,58f6830a,4e5f413e,4d7d442c,4348328a,5115fdc6,ae5ab638,339e313e) +,S(1aabc2db,5ac6df10,1d097db6,26e3623b,295ae6c9,941e3717,ca849065,512a7fa,2d2781c7,b42ce42f,b40b737e,9100ea24,ecfdf58,fd724244,dd67d84f,4a6cb097) +,S(383103b5,5a4beefc,89dd082e,f0e14211,9bacc5fe,8acde710,7429241e,f16820ca,2000fe09,2b820a28,f065924,7823d6b5,18756044,1856dc46,a9fca8c3,84913398) +,S(2cb0f0b6,35022212,88b8be63,a0ed5d71,bc6b89ca,4b2fb4f8,54123124,49445107,9a9eacc7,cea4c27f,ac63a2be,96884112,435d5f6a,bf4ad519,461017c6,1c87b2a4) +,S(ae63a05f,306e6980,f439afe1,b34c7b3c,1453e110,e477e3a8,d7e9ad3e,fe2af088,6facce76,d579afb1,cded78a4,1dc64c79,b6e90279,d8c5f07b,fc2b0a3c,7243b309) +,S(83207533,78d5c6ee,ae26aee8,4f2a0833,a65a94ef,53a477b3,c8708ac0,35dbc24b,d8306300,4caf8d6,7fdcd09b,267a2d5c,b0e83e97,60fc4d8d,2b07e2bb,c2b387e5) +,S(f38888f9,3337633c,9873d501,8b9fbfc2,ad135870,89f6becb,528ea063,a817af28,8beb556d,8e5342f0,6fe06215,891e6091,f8b940fd,b6eebc08,ded95ea0,99985ecd) +,S(c15cc888,7d13a93e,c2411ea1,6f21e86e,4fabe47a,55a94a6c,aff7681e,d47ba1a4,5bcf5b68,91f3e01a,3754fed3,f70e5052,e33fb62a,753c5f3a,532112e7,f7f58f55) +,S(9b3b0b21,1befb305,b02d035a,1e7cad04,3b8ce04,f9315bd6,5067a73,f2680030,75828df7,eeec11f2,e0dab801,5c75213d,cd93cc84,7e873e19,b7d03eab,e368f989) +,S(2028eed7,50cc8973,c1ca2f28,a30c05c7,73e2a05a,db916825,60d41cea,3b4d0a18,40efea34,b941571e,98a0878f,a13c4efe,1e3410d8,d5166661,115cfd55,53bd0d71) +,S(ca697e9f,8954a7cf,593068b9,1078486b,c8c9a71c,d1f7a890,a0a3e0ec,e48521e0,4268dc9,28ef996b,56af66b4,2f410831,b9f8c6a0,2658d706,975a7624,6468322c) +,S(26c2615c,ebe251a8,a78b00d8,1733aa70,f8f9a97f,85c2fcb5,d9287e34,b786d4d3,ecd17c3b,e1b3232e,bde8f859,39f5158e,f8c340ef,cec4e758,cd54eb7b,df4df77f) +,S(7296b5f2,c4ac6a83,c180cc55,2fc79a84,691c50df,8e56ca8c,731ac368,2d8737f,d4410073,1f98235e,cd75e26f,d251bf8f,f93ee806,52446208,c9643fc1,1b938aaa) +,S(465d9610,c3f6c8e7,366ff5e3,9e1e17be,53ab9eb9,f299be2d,3d9dfe6f,fc601a5e,741cfef2,cd41ca9,4b847ad6,93f29e2c,7e0bef4e,6244dfd9,8e3bcbeb,8c3ae7c) +,S(d3264c87,fe435796,b4d40631,a0a64a34,570e36a9,809d98a3,7ffec23d,9f3775e4,e6fa5190,b66bd281,538787c7,40bdaad6,f37a1eb3,90b19c3d,cbc65b19,9bad22ad) +,S(d925ed62,5551d49d,151dd55b,2cde29d8,fa5dfa21,e9454c17,a834f090,7d744640,e398cb93,1c9fc1ea,d9912968,b335015d,162a04fd,c17049da,80a7ad4a,b3b21451) +,S(2f8339f7,72cc9ff5,c59ace6f,d38a13d8,21562e0,a0d5dc2b,a2c074a4,f697413f,d09d6be4,3678836c,e110e805,68a2fbb0,b87d1657,d568d7d0,e4ba1237,dbb4fa4a) +,S(f954909d,f67de727,72437ad4,d3229c50,8440d23a,9215394d,d09c7232,fa5cd0a3,6656c1b9,8e726305,644994b1,eed6234a,834f74d9,2fe16ec2,c945478e,ec53fafe) +,S(962b9348,d9b64aec,7ae38297,e80a5f80,ee1ea253,6964742,99c5196f,cd58f33e,10601c5,87838f02,5b6735c1,b711141d,ed04ed16,2fdc5bb,4dc593fe,9b804145) +,S(b70436c8,4c6e25a5,34c3c2c3,34f13350,7050b552,72a04032,84a744a8,6336efd7,1b9911f4,72a19b13,e8bad704,ad3fc911,3223a5ae,4939138f,86422536,da1009d2) +,S(8989063e,49605ac9,78705f40,cb916505,615cc465,40c4760c,db302cc7,a9e4c6a,e76c05d8,5b32b5f1,9913472a,be4322e9,ff5149e6,e224da9d,dde930c9,948ce8ca) +,S(9e2c1711,29d01e44,25e4d5a,802f4c5,84eaa0a2,2aa8fe0b,bc0aecc3,15fb00ae,b1385087,ff34618a,d126ce7c,dac3a7f5,1f0fec09,2a7a9601,b65c2786,c733fe81) +,S(3a88a3cc,164795e9,cc668d88,d9ffb6d3,52f90edd,c6b0aa5f,dba493e7,273731f7,95f0b3f8,2fc2c9c8,a25b337e,af92ca08,e17ef68,ae5abcd1,43bbf5ce,d68a1fd) +,S(f5cc5ffc,ad18ea3b,c15ed2e7,d0ee8e9a,141bcd7f,8e6fbe1f,81be287e,e7281725,ec049ad7,6ae3bc58,9a60bb7c,ae79dea4,b512fe66,bd812ec6,91fb3182,27d9a288) +,S(c8af958a,201a29a,bf880688,89c211c6,da59b59f,ffcc02db,9010bd6,65b7ccd7,3755194c,76d6e0a9,3f2424fa,f26a512d,f0605393,ecb5216e,d5f1d452,99b247f0) +,S(16f10ca2,a11493a1,361c80df,40066683,93c02635,78f11f2e,d9153dd5,5d6019d7,b9fbc23c,39323b8f,6fcfbfbc,b1a4b81f,e7eb1bb7,2855f46f,5379c68a,dc4680dc) +,S(1b218d55,81d012c,5e804030,ed342308,29675ecb,e1608d75,1ac1fb26,434744dc,8ac73d03,b888545d,dd8d0321,afe66cdb,e8dd7c6d,f1fbc3d,74f7ca46,c551f357) +,S(d16f309a,820828d5,e2d30f78,2f055428,fc8e7bb9,dcedf9c6,34640c19,7562685c,1f27768f,9a2c63f1,cda9f0f4,132f41ba,dd48a03e,5e387abc,d6c73a51,2d1b23f6) +,S(75c161ae,1b38e93e,b623305,e2566957,a277e515,44c2fe13,e02ccb8c,c72886bf,384bd613,39e4e389,5cddf7e5,b0cce8d5,35c03c29,118624c7,32b75a23,a9befea6) +,S(3327a22a,c4891ceb,2a704a19,e60d04fc,64cbb0d1,dbd5a1c7,bcb2f4b9,8a1d0d2e,1ef62067,d81d66,8a7960ea,a63832eb,5c6fe33d,3ed99147,b7f68eec,cf81551d) +,S(8c9fcb52,65eb08d2,90cc1f6c,9c3d70f0,2b553119,2a0c96c5,f59231ed,370c4036,c986a64d,f3972c00,5618cae9,4a84e74f,2566fe4f,aaa0e2b4,d3f52e9b,4acee6bb) +,S(2465bc60,19bab7e0,72bfeefd,9d974124,19bf47c3,24477dd6,c83ea3a9,e9a3f353,675034ba,c62cc0f3,afbf5027,23127859,280e2b2b,91aab521,9b48a36a,d5bcf77f) +,S(3eaaad77,af1f4e6d,a267bce9,e7095672,c44deecc,a71ec3b8,c86d8774,ad06805f,8a3277fa,6247ad67,e6aab22f,a7e7375c,b95eea16,a055ca8b,32615122,30033ff7) +,S(21734e43,c3ab4ef3,55d36330,adc76a02,7fef2658,92c29ea1,a26972fe,48c3528c,e1d82d68,612ba50f,cba70f17,3cfc17a5,d2d380c8,d62322d9,e6e93d3e,475ea6cd) +,S(d21f30a1,19f86a54,2c7d74ba,20796cbf,dc6644fa,2327392b,3aaf9f9f,ada97235,22d5e9ae,2940960f,6722d2bb,c077d9ac,aa12b5f8,b9a404a,e28224d5,5b604f6b) +,S(41741846,c3c6355b,69e39c98,fcedb9b0,73a5b526,75ef5388,819fbf5f,ce1d00aa,3978dffd,d11f4f53,ae1f5aa6,a04153d1,e9ad984d,8feffa10,9ab57fe3,f58145f7) +,S(cca0a89e,6612524b,a9c318a6,879ef971,d346e29a,4cca7c2b,4619a1a3,1f567163,8ed2e1b3,587cb5cf,37e18db,e9a95ca5,17795137,a8215cd5,293aefd4,92b74dd9) +,S(dd3be3cf,83feca12,c3dbd1af,a9166d2f,138efa4a,297c742b,778da203,dfff3728,b0a156d2,93dc289b,94abc958,f17cbdf5,94f04cba,15b71ed0,197e239,8b56976c) +,S(6c535f98,868e9ec3,31135e87,b80aae3b,a0609455,8d426bdd,3dd400e0,344a3cd2,30bb8bb3,4ccc439f,c343d3cd,ceabc511,3efd9087,d17004fc,37f70d98,94e3c04a) +,S(338bec98,1bbaacd8,8b82a53d,d1ec2ea8,aaf7fcfc,e5f502c0,a13b95b1,d5fd9000,dcda1b41,ca43c103,f0c6b294,5f9e94be,be971eb3,12f18197,b4dc795b,1efe13d3) +,S(b70accd5,24961804,40dbb087,c3c11f33,f27c7e9,886aed80,b89b121e,8d51ada9,6272d04b,3ec35419,be43ecf,72824127,ae4fd87b,640a5a4d,8e8ea05b,5f3f9b6b) +,S(dbf05f1e,b489594a,146de62e,c9423699,a7aa2d19,93919b0a,2a26b53a,a0f1a033,9608352e,a1abfc2f,47c42ed3,8f1d2ee4,bb28ce2,9dc98325,eb137acc,36924d65) +,S(56e94226,a4237f18,c57b5ffc,cfe795cc,b11522e1,fc47d549,6dfad2a7,2f109783,f137a96c,7965b8d3,2eaadbce,d86abe0c,5ee79de0,9b94bf60,8d72a4d8,8cafb542) +,S(c206cc19,28af717e,63e6e7be,781ea37e,d7dd1766,f1553fa3,2acc34ea,c1157bfe,78963ba6,f03b670d,602fdb93,d71dafc5,bb5ec7,b541b9e3,a84d42ac,1a444e29) +,S(8b579cc3,6455002c,372bf1c3,21012fbc,c29e102a,9acb149c,93c651ef,e3dee157,9fa8c521,e2f911c5,3438015f,48134dfd,66fa5acd,8916902,c1aadb94,7ceab096) +,S(3ddca5bc,e582f08f,ded36cce,395f4672,9fbfe7a2,c9aa3479,7fd2e332,352daca8,d77a9165,e281ae70,f1e9a265,630acb60,bcb79f30,9cd926b3,550b6c9b,644e5e6f) +,S(ee7c92d3,d81c3d1c,6384c771,b609de3e,e4979ce8,84df6312,fff84a0a,bd5e662,f131dacc,28415d22,729f2b70,934ef8e,3033b7b,c5a38dd9,1a11e4b1,7843978d) +,S(b9f80abf,ab86d596,521bf2d9,cf500e15,adedade8,b51fd8fe,c1d8de53,f4191222,82548186,bb97991f,1f28a93,804cd0a6,378355b,f7c7ed41,4cd585ed,af0afdab) +,S(1ab67bc1,50fcd943,f0b3419f,e5de2969,fb4428a0,b90981d1,a3893c6,18aeeae9,56fb8eb4,4671006a,805e161e,6e3f2bb6,b0199659,667967cd,3c72ba65,97a2c39c) +,S(17425974,39a91dd3,72c09b53,68d9821b,2acba5bf,a5440118,ddb5c494,fa0a807c,1b73d3d8,5eaad3c9,b37f7451,2a7ddd17,97e10e71,b640a820,181757a7,6cd27cba) +,S(72b080f4,d8e812fe,b485361b,59213f59,cd708e6f,d2f7ee71,27af3d87,971633a9,5b9c6a0f,d7a6f32e,f26a4584,542c15fd,e3504935,baa7b48a,d67848b9,67229f32) +,S(94e5f999,b8927b65,a2f4d318,8e3f2fee,229e42b9,ae3e6b46,9f7ea373,d3f11beb,aa27336,204738d3,b2a306d0,4c6efad0,2ae3a431,1da988f2,c6c1decd,b1fb3c92) +,S(2f59f652,2f045980,833c45cf,ef8f3a37,d65ed946,9b3beaac,2167eff8,142e8a03,9101d9d0,60f1a770,9f604eae,4b4243c4,6096c041,2f861106,dc4b8d1a,d9f9b170) +,S(95a443a7,22a88b70,32194130,a349a952,67b89786,e33938c9,7bef7fdb,d211b54d,3d80619,399c0975,a67ea7b8,9a5f6427,ac454278,42f54932,cbf71711,3ae460e7) +,S(c8430fa0,2ce95d35,96eef42c,69f68502,100a29c3,6ddd1f46,daca1e14,4f382d0c,f26c4baa,4a6d9711,e6de2b92,5042c6e3,cadfe60b,93d4f385,d759ec72,5a32bc21) +,S(67504cc3,ffaedcd0,c5a2704f,af1aa41b,4cf489d3,5c23b6d1,4529f4f5,c49afa03,b3858859,b3749792,4d01676c,d96fc03b,37be7b82,aee57e64,a44ba433,2fd936c0) +,S(d4fd8a19,6a56052f,71e8d51,ee3db667,7465ea90,f8449939,be9d1814,86fdb56f,7fc64dee,2bf744a5,ba155865,fb722e11,f3087010,b566182e,8a39f718,922953dc) +,S(12810eca,7f3087,944d3dd2,69baabcd,491113de,99b36ed0,65520569,484fa7ad,f25d02ff,81ed030f,1e67e002,6680a3df,3f27edd7,76155966,6f043f85,f82c9e4a) +,S(b347e0a4,102d2954,cf3ebf6b,7c0e5f88,6a823cb4,c134897e,3169b081,8bd35f4,78494910,3eaf28be,b2d9732,f88dc9a4,66a8b5fd,cc50a2b2,8b347436,2e05cc93) +,S(54cf5638,7972ba75,48dcd07f,1bcc47eb,5d99c95c,a18de15e,9d2ac40f,1435b27,48558294,410d7ed9,9fb008c2,32cc6ae5,33bffa9f,3f02f0a,76b1f390,9e78e507) +,S(e75c0831,ab9569f6,4844f67c,3650f691,e1f84366,46a28613,653c354a,3107cdb,5e2da0f6,83cf019a,82e44f84,e7bde49c,5d477f34,fcbfc3dc,2a9a2a4e,3ead0a1a) +,S(f9eb5462,7d88b64,5899b177,99257d92,4570b3fa,59fca83e,1e302f38,5c524693,dd187873,9fe69020,970609f8,ca1ff56c,3aeac075,43e6cc5b,bcf75af0,2932d516) +,S(8890093c,5bbdd22d,69c91acc,5608e19b,59d2b105,b75e054c,8e873b88,59865997,1f18b0bd,e9b546a,9a2955ad,492290c1,a041b61c,7b534e1a,bcd4db3,b5148bee) +,S(76b95d04,88c9bb7d,2cb28589,f7f3f9a,e2ae24a8,33adf557,76bc3132,4bb80168,590b3022,81649af7,bb2cb0cf,fa0e90ee,13b97294,1a7a8748,bc9ce53,88744e53) +,S(8b3526c5,afd2a987,f8a04949,bb5695da,8b073b93,d8418878,28f9d49,2a6ff4f7,387954e7,60f2ce55,17213bf9,c987a9e7,f9b9b05e,c4677911,22e7a28e,777ab4f4) +,S(2aaaa06e,244684c2,571785e,a77a76f4,2c4bca21,14fb290,ef66d150,74ff2658,49e3135a,3e8ed289,4dcf61d5,7e4cce47,815ecfe2,5bb1d8a,a5d067a7,924fcab4) +,S(981b94b,be061268,c02db0f1,fbc330b7,351d6229,b645e4d4,3d908be4,241795af,c294f8d0,7b6c70e1,c18ce6da,b3d28c4,d53f3e9d,1f8d9ba9,de18cd39,51c8ff5a) +,S(53721e95,737d09b1,49eb185a,1663999d,23429e88,51ab849,a671c0,d86efa3f,d36f27f1,9f812f8c,c9d770a4,1655ef57,efc1f126,ecfea4ac,dd5bd42b,13e20a54) +,S(9ab129e9,a4d92118,3ebf686d,97286d1c,9608003e,67b026ee,d3d06a8a,e21c0bcf,4683a375,85be92d3,331732b7,8e12f452,480a9569,4c309907,2bbb9427,602ab016) +,S(330ed8c3,3c3647e,7b80f38,f3a1865b,d33abc8,ecd4d0d3,390e8ab1,a20d1c0c,5e3db6e9,33d6d0d9,43cb4202,f9ed135d,ced588f,8742556c,2012989e,768dc770) +,S(66c40c78,6933308b,9397f3c0,3c4263f0,357d0f8,a6a9eb06,725c4c15,c226d57a,697777c7,13cf3b5a,ca964377,fb124f87,81743794,afbb1966,4b126a86,9f90bb6b) +,S(36ce2c7a,9c7f1267,c081c9b4,296a191b,951415eb,12e95b02,e5f5d3da,47809b23,ffad6d8a,e00096f3,878f54df,5cf714b9,6646b5f0,9cce0d06,ea38c558,140223e) +,S(73fefc2e,ca71a95d,2e9d5d0d,464a7408,e38e21e,4450ce8c,51ec9d6d,79b43f52,cd47ba4d,6c2ed98a,c369ccf1,a3d65e05,758f7f70,1ca87a02,5baab12f,5b765a20) +,S(cac2c00,567cd06b,d4e98e04,e911f7b8,7d4fcc19,28a5b58c,635fcb96,bc7c0a8f,fde04dd0,3235a3c8,9b304c97,7889506a,c3ef937a,e1dfce4d,ce29a1cd,dd385090) +,S(f6eb390,2654aad1,1c69c028,2d1449a3,4198e774,3d329c3e,85a8af7d,f6219e1,6403deda,8911378f,7defebc1,ef7a4ee6,20802e76,499993e,15b22e42,3e492d0c) +,S(91a7da19,ecc1a979,7d5dd222,edd74bd5,af76d200,30cc27bc,41304ef4,578d8773,a32b1a26,e77631f9,6a3dfe17,ddf16ef2,f38f4026,4d3fb882,dfb34cf1,5fee2f1f) +,S(90c3942a,7b00bc3f,7b852097,ed4590af,cef6fbe,783fd717,9fdc4955,a4fed12a,aa7d174a,8d9f1292,b8e4d9d0,19dd336e,da305ccc,ab69659f,90011b69,85366751) +,S(717c0973,ee959e19,6d11939c,acabeb83,607f9367,83dbfe6b,911f30a3,c51af3a4,f93d840e,88497801,223992dc,24dc976e,dc0b442f,2f845650,4903c9d8,338c1ce2) +,S(831f9794,c88cc5b2,2d202130,3731371d,a0ab67f3,c080cfa4,d958e6db,aa85d140,46ed65d2,1c8b5565,14e83074,e84267d8,43f47154,8774533d,cc11e6aa,cc655895) +,S(f6c7e9f6,69447c19,843ff209,72c47cf9,5341e0f9,d2d5f14e,c9b17abe,20eacdab,1bc7e847,a9f2824b,5895edf,cde746d4,5ef0fb67,b7db1637,e62d2d40,e046650f) +,S(c0ce97e7,ccec223f,947c0db2,62fe3865,9e06fc77,99a41581,7ec36642,9d5f120a,dc281020,af95986,dfafdfc6,ce122d33,e797197e,c24c09d,7e6f04a1,c5b4793f) +,S(e1eae094,f68fad14,5d905240,e79abdef,562ac20e,d52f3503,db34b2db,d2f72d43,71e4754f,ca9df5ef,b3b86c88,7e3eba7a,33554a83,cd68ebed,f6dcdea7,fecc6486) +,S(acaa286,bfd582c2,c938ee36,23a20db7,5cb6f0d4,95419f33,b0b35f2,59841bad,c3eea949,18a16138,caecb54e,ac03b6c9,282006f7,14d4b024,2bad29e9,aea7f667) +,S(87f6893c,137f60ad,22a5d543,2dc2cb2f,f2e05fac,d643839,38936c2d,206afc82,f6bc3092,1de852d4,4894d318,aaff9243,a9a521e,501ca78f,c7baa82a,3a118ed4) +,S(9df94d49,e9508ab5,63ea1,16cc4502,aeed0bb,7b1db426,c6695da5,8da1f59d,51786cb4,a7caea66,39546ae7,5826dcb2,5abc5a76,402fbe9,b32432cc,aa48adc1) +,S(8a902a14,5ecfe343,503f46c9,71693677,80499405,5df02c32,9446a373,e34777e3,fdfaf856,f777d30c,24ce54f9,d503fc8e,a3cdef47,e292ec5f,f98d6449,a69b3f0a) +,S(ad6128cb,8d9903d4,23558eb2,23fa580d,e31c454c,d3985ac2,6a2854c,733c05c9,9b69c9e1,564c9271,5562d4cb,fc040495,6ca539c9,691e2f02,5f41151,ca6667e2) +,S(c2a2ff9f,6d064f4d,551cae44,f726a8cc,b14c9742,96725620,1d01581e,5375e57b,ae53fd93,fc405150,3d6cf2bd,bb51720e,7555cb24,ef7ee8bb,9ca306a0,59563e65) +,S(56c0fc7d,c2ae8f26,4e132fb9,3a52a634,2b80dd38,f329fe9d,1871e2c1,6529996b,5d012467,cd511264,82399d80,c7f8d248,d9267251,e4d18aef,ccb9bbcf,d854414f) +,S(2131bb4c,5014e751,ef0690bd,562ad29c,d8db4461,9eda575c,9f0f75c2,da4e0f32,7bbb234f,7a83afa6,47599f05,8ab8f5d2,83f1f02a,8f8d5292,15c7cdc4,71f03fef) +,S(e8adbaa7,bb0542a9,9b9f7598,59637f1a,cb734257,13247db4,540b8268,6c14a462,72de1317,fb5ed43d,ec57ebf3,dbec4eca,bef50923,a4743359,72aee4b3,c03190f6) +,S(827e8e05,2a084162,19c8894f,ec6f31c1,a7902792,a1e8cdce,6fa5f732,4b428417,d46d9c86,4fb85e09,81bd40b,b6c3a563,8a74c222,6e7c8299,3ef6b408,4aaff5b1) +,S(3dca9759,338dc06a,8e81218,4c14c82d,3fffc50a,6d0125d1,1af0523e,d14fd699,e6c98f39,b3fd3ca7,66ac5444,be93fe24,3085a38,7b484f28,da571afd,4b8ba210) +,S(3ceb28d2,e59d3692,63432323,c36bd680,f531697d,c33245aa,bc7c5838,52bb8eb1,d2456980,96a36ca1,7301778f,d1661743,f43ed9af,3968e4e7,55ab39a1,6ded2d19) +,S(47ce6c4d,c1dc8371,de44ee1c,828e4b3c,6ba040c6,8dab0802,417ecc31,1e7d79ce,2d6b7bc7,c43e478,6df00ca9,75268b3,39f0ad68,7b0c70c9,ca857913,485419e6) +,S(ad6387f,fde71126,d0784af6,fc8a1ca7,be9bfee6,176245cc,2a18c9c1,c17f156,3233a7a,d7d50605,8cb63aa9,becf9eb2,bf8fa88c,afb2ce9d,a9236736,803dda1a) +,S(8c9c591f,e2afc468,4b64d9c,44b92627,e70babb1,aa9f7f00,6dd5b0ba,4ae794b5,5ed4c9cf,30c7d1f1,ab31e9eb,8d20fd16,77b67152,44db075c,c9de1b49,58607617) +,S(2d601d55,1b07c8bd,10db6a9f,516882b3,1525d819,9df56324,cef2c40c,6753ef7e,d32e4bd8,eeb642a4,38a9493a,87824f86,6731bcf1,6c4b1f42,240f07fe,ff075a2e) +,S(2c67af99,3de02d6c,b9db16fb,7fa99fd3,6e32aff3,69e855b3,581af5bd,cf8f81bc,69fc1c49,501a76b6,e21abdc0,27aca6b,a062dc11,5cfdeebc,b8b98ea,ae35d935) +,S(a904b9b9,a0abbb60,4be04958,74b0bf72,5c1c21fc,1ad75b9f,99ed5d60,d1beaa3c,a2cc5370,58dcb26,6677e730,449cafa1,c0135179,4afa24e5,47b10479,a2590069) +,S(bafa5456,e50152d3,115d40f,b9571d79,7ae8fa48,97801c13,238d8b98,b919302d,8108653b,f4f9bb59,de7e26d8,55f72103,20eeb48e,9f127778,5f05ed34,3e63ac43) +,S(fce057b,560e9da2,7621d46f,bb709275,4a6793fa,eedfcd7f,9a782aae,e35cd9a1,c59891ce,d7c19c5e,7a841620,8d0d819,c8634bbd,2466ed60,214a726a,dbefd784) +,S(b8dd80d9,6b6229fd,d13dac50,23f53657,3b353efa,45016033,58a9bcfc,ab61fe7f,a72beda2,c2cefe01,eaf1ceea,714b538d,8b052eac,3df84158,dd3530f8,9c5bcd25) +,S(c676cd53,7366b97d,9a056e87,2bec47df,e2c35e88,947275b0,53212536,a6231c5,9d5fe80f,763e202e,6919c760,bc96c732,844c4c18,7e7a3a1a,a0760c29,80c076af) +,S(626a28b9,c897481,19d6c4b0,bab6e81b,9d6747cc,6c49521e,6f032f50,36c9fa87,f8373b3c,748231d,b8aaf580,90898566,27b112f5,6697b18b,3cd6a73a,16f2203a) +,S(d72eae41,548363f7,cf5b5b9e,ab73076d,650f7616,e7584fd5,1a5ff2a8,ce1959b0,c867515b,46c9973b,53498582,5bebdc1a,54181a33,74b507e1,f0aa21d0,7a6c0e0f) +,S(6e34489a,4ca57c6b,f3b8a98,dac3b2a2,995a7bd,f90acac3,b81d56d7,678920ea,efe88e16,e60cdf2c,3e6a07a0,ad323e7,ff9e731b,26f9cac7,87bf43f1,b3401169) +,S(a8214f4f,1ab2d150,b66eb9e6,f64ea4f4,6ae08909,9248663d,8491cd2e,90a56ae7,5d252b54,ec694068,a0944f8d,4e0ead5f,2cf0982f,3981240,5165b5a7,e4d628fb) +,S(76591c34,fdb90d13,14c5f85,e76e18c3,aff3aceb,4385011c,d4a74bc,b36f775d,f13c54f9,c32fcde6,94d29b12,f2a8d8fb,a99d19be,80ed9a8f,903b33c1,ae52a447) +,S(17d22fdc,c48ec732,afd7bf62,7fd09d22,d2989437,a8ce1950,3acc99f,ef2c0cf9,3bf80fed,48c4c2f2,f25ccee1,9a717067,976f108e,b1cee625,1fb6257d,f1788384) +,S(2ffd19a7,f46bc028,9b11d7d8,2b391091,e08202cd,95c7a4f6,fc351713,d3645b6a,807ee1d7,af310183,fa9edc73,4c098b90,5b0d4021,6c19b797,1429725a,5763d01b) +,S(63496320,c4eaa16d,ca4ed516,bcbae7cb,124af3ef,10969329,dfec9a92,22f143ab,3ce522ae,ffd08245,d5dd6ce0,17ea6915,aece97b9,9314d61e,2d4e9fbb,5b92406e) +,S(685a372c,ead446b,6f8797c6,dbbdf442,e337a200,1b09c03a,84dd523f,674c1e31,9436ad88,7c61bd79,d0a73f9d,1d06ca0b,37f19511,9d9f9f10,6a6d6d97,f0654d96) +,S(d1aa115d,ebf2ca79,61b1a13a,9f8f2f38,8367280b,c36f6208,15cab71,d235b866,9dffc173,6590390d,a2f3239c,f85ac4c5,3e842aa1,3ba035ac,2824a269,c7c2a487) +,S(d12c58f,5e20c6de,34a27270,d29ed5ce,c2a36ac0,8f2a1b1b,69cdf2a5,d501bc3c,cf7bd006,5bedb875,bef1861a,335457ad,66042a17,c9249006,60ee461c,db0a7de6) +,S(95d9af48,d2d3ad22,4ca83889,2d7f14a0,bb4770d0,42ecca6c,d71b9278,79e69898,39e47d1f,6acf9570,5755c560,22a8faa2,e961b25e,c5ca36e6,3a5ecf5a,e54a48d1) +,S(6e4dac4d,1b6d8404,e84152ad,f5d49de8,d269c9dd,1c66136c,65b8f78,5cffec16,62d1dd58,22c06f57,f2ccefca,31c318d1,175a3c60,2aad99f2,e5c63e2b,c8e33afd) +,S(d026e847,3e8eec4b,d9ffb21d,49c13900,34a9a66d,5423174a,40c8b4b3,4f6fe060,682d65fa,cbb29cc0,91a290e9,305e4615,5a5d472e,16d37c7f,e06a9a40,f578c58d) +,S(683bda54,87643e28,8799658,baee6ec4,73ca9c66,4a76c302,b26f5762,877e766a,d3d80b37,117d6b18,c04174aa,2aba0774,43fbb78a,2649eb38,e5798935,75fa237a) +,S(fe2f54a1,830a0d86,ba30acd7,d208f6c7,22e2deda,4e554a5a,533e8e07,dfc76f8f,6a6f032b,5bb03b33,3b28e6bb,30b2b04,305e0aac,cf53e2b,53f215ac,2f1ab8e4) +,S(2486b52c,511b2499,7ef5d49f,8098f596,568fbd0b,756334b5,d5f01852,191d677,ef82dd7f,9dd36f42,55b75292,40af86da,bbbdeccd,6ebb3197,11fb3432,236f5ccc) +,S(c6fe27cc,79f316ca,5a59acd5,911963e3,bd6ae911,c50bfa1a,f2ae8b6d,69ff8ef,70aa6fed,ba4c57ee,5b3b33ec,ab6efe75,e05b8b43,41c3a7b9,bca5053c,40292101) +,S(be4ff208,8334d043,2d35c9f3,806e516d,fae58bbc,d2f69565,ec461006,99af2be2,49de6b17,c8636af4,25ed00f4,228ecdb0,4208d18e,b5c9c194,d6714550,26396adc) +,S(c5789253,316faa6c,2f87f888,a8fa4312,42618ebb,37a5184e,29abf20a,e6b4aea4,77647e3a,e083159f,afe92726,6c60f666,12e4fd31,ace116a5,11678291,185df958) +,S(27d2c091,b2212a3c,b2a827d0,951a4bea,6994953a,cbfff146,cac83f20,f164ffd7,e9fb5899,d757055d,f0e273ef,c38cf691,e958c6e3,943aae43,85f77a14,8189eb92) +,S(94d45ebc,ce92d10a,3294114d,743db35a,8e2ddb7b,7f5bee72,7d093c89,15d98d45,802386db,bd731bbc,5dc793e4,88fcf20d,15be9024,b94d1d19,edf99ea5,ab1c0acd) +,S(46739c9f,6245639b,692a68bb,8587499c,43184d0c,f0ff467,7b264985,b4a2fb62,9f8f41d7,2eb951ff,17d4517a,3fe7dfed,556aeec6,be518188,8c39a57c,913f7da4) +,S(5c9f57b1,baacb2f,67f1bdb5,3fc85aa9,3293a2d9,d85d1f2f,f62ff40e,d26e8c30,6bcc8a89,7ebf12b7,2f397b5d,ba072f3,c91f413f,df14e441,ae2a2155,887c1527) +,S(9ccb3d34,4c813c15,e9b85517,95ddb04d,c3c790a3,a1ae051b,60202b56,b735f3fe,e24525a9,fa784ee6,2576fa15,6ad350b9,eb5802f6,e5d5bbbc,7f4217e8,73f85916) +,S(f0826eec,162f343e,4cd7e135,df33219b,507876ef,5d29fa13,d8fa2326,3e7ca425,649c1d78,6547e29b,d266f2b3,cb70b823,8e71d198,6791fb09,a19ee4fc,1823e02f) +,S(8b672a2e,1b76096c,80b87519,10b6a09e,1b7204e3,ec139cea,46aabe84,4302dfa7,33f05056,ab88de5,e036f8e8,5bcd51f5,423ef431,4faa1015,7eacfd8a,9db71787) +,S(93cb8f71,9db52708,986fcbc6,26679315,fe79d119,9f8abffc,5c02f375,8e5a50e7,ed7d055d,91843e32,4193d866,81551f5b,36b484d1,f0dd5fec,f59e51ba,57b93bed) +,S(da506843,86019984,4004a723,7ae11605,a7132e86,55145d8f,ce9e0e50,feef7d5d,260f6393,886e1b8a,93986894,a4a98fa2,61771a46,16d04ebe,baf8bc48,29816d53) +,S(2d469c5f,26610e4,6bfe1cc9,43cfe267,e1bd0a22,e451aeb3,e74f17b,b9ec2f76,1d702b5f,fe2101cd,f5a5cdc8,4d4a4890,6720ac6f,ca626979,d942c218,163474a2) +,S(1ea83777,5513ab9,cadd3b53,66cd9049,da1b01c5,d347f7b1,c8a74f6f,658cd621,b9e312c7,2dee3d7e,d6e67596,70c65bca,5bec92a,2eb82fab,a122ffde,5b1c7f5) +,S(70bb25c7,9589530e,f129166f,cac1d5d0,81083ed5,fc5b9b99,e744585a,1d6b6816,63234c19,dad2914,3e99ff95,a906a5f7,a48b3e87,2d45436c,8d987baf,a93b3588) +,S(fd9989c8,f68537ea,a3248b19,ae721256,ba8d0d2f,d825980f,f89bb158,a700f0a0,eb76c5d4,93e52d45,5d27a12f,fcdba859,664bb048,1686e67c,e79e40c2,e0160c97) +,S(f1c32c17,8b36e837,b058e9ab,ed3c65a7,e2c76397,4936a524,838a480d,b3089b7,dd4101fb,92488a78,480cb6af,6cf73dec,5aac619f,3bb42594,c3dbef4e,cc7a3a11) +,S(842d8101,ed396c79,b5b19779,c245dbdb,b1ecba7,9ad77d5d,f78fedce,f9d83f33,6fe77300,9117a404,f4b28ef2,57441145,c5afc6ae,2e655ecd,2497486a,fb1ebc16) +,S(6e9e1a2e,847fb133,cc92a79f,767a5ea8,cac887a3,16903a98,f3ea86ad,3e8cf24f,d71de5dc,12be0a35,b996d880,8442fdfe,4a6cd810,7fe29548,da99783d,9049ce3d) +,S(f6739fd0,1f5429d,27c216fb,2b02d871,7028366f,7af115d1,e154f87a,812b5e37,15186c87,f776c8a0,3532b554,1e1b583a,5a465334,45bcf93e,dcf539b,21663c95) +,S(c3acbd98,43bbbd8c,68f153d8,553a81c2,81dbc584,42edb9d0,e51d056f,2b80e2f2,8397a220,483081ec,ea7de090,5d063412,1dfbcc32,ce70379e,c58b33b3,20f39d25) +,S(aa9c8bec,c845e691,a4c3daaf,a9bf687c,ad733290,32abe151,a26c2a27,1fb94732,b82dd0fb,c53fa616,74b684f9,7da10e8b,77f1f7e7,388007d6,656988df,e18df322) +,S(3df35629,654d5b70,db9547b7,5373efd7,e1781dac,da11607f,e4f3c903,5493c8a7,56fbe92b,25cbc615,96f2cd4,10290da,239ec3d9,360b3561,4199b006,c2d2b54) +,S(bcc8b337,98973e00,771a1955,89165cff,83870f8b,a897b8da,84c1bfb7,57168bb9,483a7f4a,70c8250f,62105842,310ed427,168382a2,5d687290,d54e65c4,c83bb16) +,S(bd2b07e,a84da89e,bf5e39f4,d3f03df8,658061fd,8f78d5cb,99f488a3,e992b870,33ae1dde,77c5b467,f5b3da9b,c71a6557,b0cb3aaf,892d0e76,d9f34b40,1fe60c9d) +,S(2c55718b,87b4facb,8ba9a6d,287a2db7,1b5a03cd,c7d933d4,c6014232,ec35d05a,aab1de0a,d8e3f72a,ae822bdf,f3ff70bc,bc5aa56f,1dcc5352,d1f81614,f3f461dd) +,S(eb837dc3,b2e346c2,aba58441,8c84b20,d144f93f,841180f0,860f7280,a7ee23e,6a342fb8,38a63813,e279d1c6,94b2ed26,79c3dd21,652d5678,5f47aed1,5230137b) +,S(827719c6,9b097381,da18519,ecefa193,9a9eba18,189092f4,89bde77d,33046fb1,e73b0e1d,76e40777,4ee6fbf5,2bafe516,f6d94fa7,c7dd1eee,b3c36f7f,6429dd3c) +,S(2b0da4f1,23095370,1f1b9444,847ab289,5cbfecb5,800f2d7c,16e7a56b,c6988d2,fa8b4d9e,5da41962,68e10a3a,7d69b1ca,7963d4d8,cbb5fc1c,83239212,dbc340fc) +,S(95744eb5,13436e2e,877fb0a5,20d5f1e2,1e1ab59e,15bbaf46,206550f8,d5563134,5fb1c034,62040ef2,28adad1e,83fc2c74,57344c38,7b7ffde0,d247bd35,6b5ed1af) +,S(4c805d94,78793e63,4833e90d,d19822a0,ab7d263b,1ab67654,bb77358c,67b327c8,863cb8f0,dbca3c1e,4011928,e5827619,53df792d,449f8980,bd10cef4,472ab56b) +,S(fac22633,3ffa2cc8,93c434b,46fb0cbb,cdee765f,e848cb50,b1dd6e70,272e0ec3,6a6b07ed,46f9b9c0,86e970b1,d2323fa5,d7d66b0e,3ad3077e,da5766ca,ac5b500e) +,S(b9d6af71,c59f0fed,ca4ecc31,25aaa645,f78d43eb,79c22034,1034de56,f59ec4ef,5509e17e,3d7ea457,c428e10a,7e9d8bd6,69f0fdc1,165169bd,a2101d8f,6f4041b8) +,S(57a68137,90725717,2dcd8c46,3a9b274,69c5ef27,2ae2be60,b10b96e8,e6b47537,9f294700,1c04c06f,2e2e5aca,cf4b9549,265db1f5,74b2328,ef4469b0,1c2bcb98) +,S(58ee2a22,9aba401a,637c4d34,2b1ef408,d9f47c53,6133fcc1,de030d00,25e2f53c,d361b0e5,5ef24c74,94cb9e65,cd273e9e,73da6e50,f452f8b1,7d30eadf,32ceabc0) +,S(b8bae4e3,f2e22824,7ac9cd8c,a68632e5,1bb13d4d,735fabb7,305a8169,31b0e34d,ae8ed4e8,6ac41b60,60ca3423,fe6bffcf,a7f215a4,7076f270,a2d1017b,887b8002) +,S(a81d5e0,f11549c1,373b4c02,a61c8908,dd109f4e,7f0cd250,a667508b,aea3feab,8c6cd790,4cb4bc0f,7e56d928,ac362cdb,f096841b,dee9dd48,429c52e7,23511bc1) +,S(fea67ebf,f8f092fb,dbb3110b,77d6981,efaab5c4,97a23c3,42afe294,64f4746b,1dc947e2,94b0fd7f,952a6d5e,1f5ddc9,5f0acde4,de8db93e,41f37ec8,965d4310) +,S(4db2ae8e,6b8e674f,2d79e1a2,fb7c7d10,921c9280,d8eff92a,df1a2b02,4485bffc,8ed56cea,38c2a96f,b6e0ecf3,22b745cb,35c43313,9b3dd28d,9189a9c8,9f2c055d) +,S(be31fba,3995348a,78303047,24ff117a,48dcf5e8,72356d03,ac059306,fc5ae314,8bf72f6b,70189284,ecf86059,affb4a2b,c7b5f923,d7c34429,6f401490,5a94061d) +,S(e8d716d7,18078be7,78535c20,4f9cb681,e8f49ac1,85baf865,e7b78e19,58ee703,2c79f768,c6d3bb3d,b0923d19,74647e8a,966ce69f,d06a8fe7,5601e51,61f49f85) +,S(20ae34f7,f3497d67,6b0496fa,1a68178a,f4fdd57d,15131ab9,c60bedbb,1a840070,21fc951a,2b29ab95,994cd404,b3da37f7,d21fa790,820339df,84f17b50,3572edce) +,S(73db09f1,3c8e7bb4,48629f24,83d56f1d,a207617f,454edbd9,d51ce59f,b7ae1ec9,1e4e5175,efe03956,cce3f160,791595ad,35bea993,139e8967,f591b973,785dc29f) +,S(14f5ae1f,af20b6af,9953fe91,db5bc192,31f302e6,cc03a265,d661b25f,8f07cb18,b790b1d5,ef6ad5ef,97ddb309,354756e,138f4db3,208a873c,17cff3a3,13a8be2) +,S(94ec6992,d2531cdf,3a1002cd,efb12e68,868be66,b704dc26,3dd422b9,9cc379ec,d2c4e479,ce9e0227,4d9175dd,e2a42639,67ed377e,d0416101,7e41e8bc,8adf7fe3) +,S(f73b5edf,c8d60e77,328279af,ae99381f,4ce0de22,17a4edd6,4c228b4,84816527,86758bc6,f44e1204,68555e71,786f7d50,da7f9c72,665a7475,e77c32e9,dcb13419) +,S(94b51939,45a518e7,c602570f,863902b4,385c8e76,c335cae1,b80e1d0c,e118b573,7c285008,4d398cfa,24c5cc6d,879868f4,d8eb60ad,ffc77214,5debabc1,3f154ea2) +,S(26acc055,2fa90d45,1dd6f2a3,9bd46a9b,99b0f66f,3e6e72c3,16e09e52,f7b265b,997dd988,5d5b15a1,957e1cc0,a45518fb,b0e1f847,d58fe9de,9be95273,cbe61b00) +,S(e8a5ac01,959edc90,2050922f,af51365b,ecebc967,8e57cac,420faa6d,4e2fce98,2c2998c6,fdd97d15,fd0cd228,e9975064,f2576316,6e61a45e,ae532481,9dd96227) +,S(d903bdf2,5ce9e855,60f63d72,512626fc,fee11c4e,304d249e,e13a4b69,60f95019,1027435d,bab3c246,c93897bf,ef7779f8,9a165595,a7c9c536,176fec9,1adb645f) +,S(eea105c6,fc04a751,cdc27e40,25f0d50a,99f8d01e,1110a505,eb95206,922e50fc,b93db8cd,b914dd8f,2b57b907,4df41e9a,d8cca9e9,c3a9754b,e8473446,ef3a6c68) +,S(801b116a,1fc2c2d8,fc8b412f,e9b1b7eb,b19f4e96,16b420ce,16f1b4b8,dad235f0,53def02d,8a6deddc,250de95b,d6a96d27,1c197d36,e137e640,4123501c,15fbaa9d) +,S(db3b8667,1b0dc54,436520fa,c8d437cb,7a4c23b6,bb3c3cbf,dd34b605,af406939,36562d35,a298b620,f7a06498,b1032f4a,33cc3b3,ee185e0e,aa8d3e4f,3ec5c481) +,S(7bb26eab,8b808402,a9fb3fa3,8f0e2f6a,7d82d7c7,eef75cec,43594713,dbc17706,f4f86283,713738b2,a9209e49,f82ae1bd,9bcc908e,b9565546,3a8a5dd,8d0c4b9c) +,S(e89fe301,8d87bdae,20fee2ec,7a3f6cd6,cf932d20,a026e1bb,a82f9c63,a47b97d9,92a7e80e,e7657ad7,c72f471,8f0c28ba,acfc748d,a6090026,1191912d,32b8a498) +,S(c9a10a8b,14d1845d,be6eb6a8,65cd2ce3,a4d0be4d,fad24912,b01fed8f,8bc812da,5852b791,85afd22a,6f9ab486,91340dfc,e9979cf0,bc9732b3,637434a2,25001d71) +,S(257df2e8,cf535cb7,954b52dd,7e3ee08d,24cd4415,d1075dba,8f75bf74,74afad3f,f72d1e76,d4da3c0e,5b41fa82,28639f2a,f4e114c4,94073ddc,3e8fb2aa,f82596b7) +,S(3c64aa9e,548a430f,a815bd54,713ed69d,bc32a0a1,30ae7ca4,1541ff21,a5314886,8377911,7426e30b,dbf84c57,b110cc3f,df5acc95,7313cbc9,86e895d,6e0ec912) +,S(cd509f83,3b65a7f9,671b9239,c5e71323,f183e956,2c2c115b,751046a2,33424ee9,579243a,c7fbd433,81cbd0fc,4330d087,cfe0c41e,449ef82e,12def6d9,8977338f) +,S(27adfe4,febc3501,3ca7a0a0,b5f7e525,3768df69,9d236f63,9ab80782,c2d426f0,97cb4e7b,73b065a2,499a1675,88fc116,be5606f,80619d42,ddb63286,4d20521) +,S(ef5bb148,98dd6802,6f25c363,16a34acc,c6131851,a4efe8af,219fcbf4,13a45207,49f30d08,291e60f0,975c93ec,403d2a14,3742aaeb,3777cb9,87ff38ec,b51967af) +,S(58df8d45,955e923,ec7fc327,f8081ec3,7ca6e261,7fdf7785,6eed51dc,95057034,cdfca79c,92dfe719,2ec63f6f,f93d211b,d7cdcf69,4deac173,d3393fd3,7655a310) +,S(2a4ca8d3,fff5ac47,bce452f0,1587a769,443e66c0,164558b6,301a6a2b,d3d44270,ed73b405,521274a2,3abe589d,c5ecd607,b6467691,f81e3c9e,6a2096db,2ec82366) +,S(84bafd1c,7c6072cd,fce244c4,8ea004ad,9b8e1765,bb8796d9,118d6dcf,a5ac58ce,86ab8db1,7c26c921,604a3c3f,f0155a2d,14bd7274,16f9e319,efb68f50,2b636c00) +,S(c3785528,7cc4e3df,f5e95951,c5bc5964,28705a12,10927e89,890726a2,ce00b657,302ebd13,5643eb43,f0bd14c3,65e385a4,c9a177f,96595054,3c3d96db,69ee8f79) +,S(c3aa3cae,efa22927,56c72aa,53507474,50f7a64e,2df1bf64,333d0402,5dc87d25,c2eed94d,ff9c5cac,248f77bb,9e189302,286db019,64214d71,1a199119,4818ac4e) +,S(443b9c8c,7d8c4f7e,de7168fd,666e79,5da85e6d,6c0f6448,7d349de7,66acff4f,2d4f1d59,b0d1688c,9fff0f2,f80e3434,db72d76e,6ff886f0,63dd63fd,e192b01e) +,S(2afe7ea8,688081e5,ee8a4ae9,87aec6d2,ede5ec3b,ca887bbc,1461709c,bfc6e5d9,5c319df3,2556ffc2,56194b7d,eb46dcee,59208922,1e55c384,2a03ddd8,78add90b) +,S(c62004ce,4d82ee0c,e2edb82c,e0ca98fd,413bbf44,55b96624,a86aa252,c346af6c,b68e4fb6,88f78331,bc2218f7,6a5e43f1,cac49fe3,4c5302cc,d6a3f1a3,258564c9) +,S(f759c4c6,e0bd72a3,9aabbb17,fc62c900,d57e0b5d,ab9ecce6,8f439025,2b17cd1e,6dfaaff8,5f9f3990,ad2c55f1,3c74e3aa,aa0f10b2,90def714,229cd3da,d5d18d98) +,S(b527a6a9,d27d0a1d,5adfc1c1,35308e5b,9a805638,132f61d7,e5e60709,ac3a9d9,e387f69,62ad151a,d920c82a,739af00f,628865ad,4ca42405,efd87e89,55b91042) +,S(ba23656a,6b0a5c57,f9a00d6a,9e6a331e,cf0c8097,3675f41c,7f0172fb,caf4eb02,b48ac68f,1a108de9,18d76d4,95a811c2,b7614aac,3c5f6b18,f28de8cc,7bd4041b) +,S(ad94ec6,fa161fd1,60dea3b3,2c63a480,9f7bbb91,49de206d,8cc61306,dbd18aa8,5240858c,ec88a022,7c1c12a7,862b4d18,e5acb344,5d66bf85,79ff9fc,ba866a4e) +,S(db4cc48a,de1bff28,c8987eb4,d00e1c5c,4c49fa6f,125d213d,bd814c34,cb81adc2,ffd64cf7,3c62c097,a2cb3b84,c62bc32c,54fce797,74479146,7b9a2cb5,d6f821dc) +,S(27d276df,fa39d889,beb0b586,42a0e479,8057760f,c392d052,6751f2bf,d0c75aed,c670b966,575401a2,a790440b,e5e5db56,2914aa74,e8304e3a,407aadc5,c87e12d8) +,S(7663e9d8,e34b525,b336587,eba3678f,488f95f0,6e9a6848,d2e72d35,36b569da,472b1c5a,8ee189f0,7a06addb,e6a8d90c,dcb87039,aa35e896,79143547,34e2786d) +,S(b2c81e15,1c1f8ef6,51ea1810,97eaa280,7e3b4a96,fbe210eb,b49554ad,6e0c0c4f,2d914319,f5ff59f8,c7038de7,dc70d1fd,6c4434ca,e5c0451f,4fa99f46,55bf8e4c) +,S(25131e21,9406fae4,ab96326c,7bf22892,1f18aa90,c52f46fe,b23f90ac,59ca570f,2e8a380c,eed5d51,6c190251,4937aa0b,1f39d3e4,42ab2537,e9e8d9aa,396e4c20) +,S(c2694b68,8e33025c,fb9929a8,c7ccd1c4,7fc5811b,9658ecb0,f41e4558,5d9a0c3e,c443d593,e68abc49,cbaa92b1,757ab2ab,c30671d8,4699a5c4,85a30b05,6b1ca701) +,S(8d528cc5,17a371bd,9605d8f4,e7f030fd,8a82d489,5bfffb9e,fb11f63b,be534fd7,ef2f16fe,64ceab2a,d261bd1b,314ebc65,4b4127b8,643466a8,f367b991,d28795d) +,S(409e69c7,62f856a2,4b6e80aa,baec8496,33b75c21,8943dbd,7280bf,e917b032,7f049016,62884d22,dfbda29a,c8061b7e,b82eb94c,13d7efcb,77531f8f,980babdd) +,S(82c9b4b0,2451fde7,8ae877c,ed9af540,1ec0e258,119e27d4,1938f71d,ebae71c8,212d6e4,99b91fd6,372db1a9,4ce3fd9,c5443b7e,fb37a566,f0c5f54b,fd8edae8) +,S(6c9fd728,37a39ae7,1f0b5852,e5c09d7d,cde66ec,e8f19a2f,2ab46fdd,d17c7f88,430d3385,aac729f3,8ef5ed,922e709a,73df8e70,eb9cdb83,c41e5958,272e8687) +,S(9f012582,e527901f,ad1f350e,1a64702a,ca1f6670,e693bea8,fc3eb0fc,2c090329,a2fa07ae,c15e9457,b2c75e50,56c79a6e,a4c8f431,d3c720f0,60f7b5b6,da6e3dfb) +,S(6a1a49b0,7b2b61d6,474834e9,953aa455,63910582,57db16bb,406b600d,bb01300,d4b93b7f,66ace505,cbbc2326,ddfa2fa4,ebab145c,ffbdc2c0,606e2ffa,9dbb41f4) +,S(981d0638,a585970d,4b12e577,95e76c26,1e10d65c,c5a94f19,43560d10,472fc9c8,f9babd66,3d02e030,1fc0ed0f,75cdaf94,fafc18ad,2cc68db6,d2eff7ca,e6c013bb) +,S(7edb47d2,b6295063,6cdda3d7,169b4296,3616b6dd,79e2e148,609a7722,476e564d,179a20ac,a6deb286,76fd466f,be78c3b6,789d31b4,91622149,4d7d634,d4bba999) +,S(51867800,4bd8a43,8f180cdd,efa17ff6,e16e29e1,e5fc4ef3,f5fb9bd0,bbf14ae3,306cc2c8,60ae5871,8632f94,c9acb7,321ba1f3,5092a0b5,72c33b9a,cd8cc956) +,S(bade1926,d8b0d136,69e056ea,ea46b2c8,2bf0f0f9,a25bc481,8a40ca8e,201500aa,7ac76679,c9807217,ee802773,dde582b5,6f0a4b66,f6e21764,285a6a81,4d584502) +,S(87815e7c,d1e5e88e,eb882b23,955de59a,d63f14fd,457a8d96,4b47a611,b3e40043,ca82343d,8e2eff9e,314ababb,15cd03c9,6fe6660c,421af876,63500d49,ade0d492) +,S(77d815d8,886cbf43,c1b4ce94,253e93ef,767bacc2,42ba7c1f,bfb7ffa5,308d855a,a8bb3f95,37ef9a77,ad7e282f,8ae05ab1,8131e59b,46a67c3c,7e85ca00,a2d3e1fb) +,S(49079a0a,7d9d9add,3a17ea11,747c8baa,d0922a7a,e766e5e3,fb80ae0f,dbb7d6a9,162b4e23,58f03e01,b4e09264,8cd0657c,f2cdcf54,f6c25d5e,fe7330ce,421e0093) +,S(28d61211,c183ccc,2b08168,5a4487d1,57bc0714,d3ffb16e,96bf0768,ff8075da,3da98c13,a2d1b07,2ddda165,3fb68a21,aad4a9fe,b4536dc1,507dd78b,7e51e0a8) +,S(40c34a4b,6196561a,d4591c49,df51b8e0,4106e545,26092e88,72018720,41448080,7a6e7478,3ce7d82f,b83f15e0,b74ae6d4,435593a1,67da6f57,f2e285fa,8c107e4f) +,S(88754e6a,e12e77ec,21e64cc2,bfaee207,f5c882df,80c8b15e,983fb1aa,99037c2d,5ae10e7c,e7464c69,472ce85f,5183a836,6ed5b3a9,1fb1af7b,d5078c76,2512f37c) +,S(8bb7094f,ed62beba,d628ef9a,84a0679d,7e0d2b45,a655fa3b,68d9a6ef,b24c738d,9f5370da,993a3811,48ad4da6,2d7845ce,4cc81766,f26189c,2199ca73,4312d102) +,S(79814e63,7bf2cfc1,cad39a36,b06fcc4,f7e865b3,ab2de1f0,c786f9f6,40dd80ea,aae4d149,f1e44635,e4800962,f533eb38,5f067114,3bfb87ab,9e68e27c,b56df226) +,S(d493573f,93018d4b,8599b54f,848c3afb,816e098b,8e218e2e,6304baf6,c726513,383c7ff9,b3ab6472,ecb80f72,2f70feac,7ff26989,bcb6f984,628d5eb6,a409b9ce) +,S(59599fc8,7d6a7532,5ce8f205,204596bc,4cec40b2,f3eae8ca,4530053d,1b7c731a,7a8d91e5,5d989961,889949a4,bbb71e17,84055697,b396a011,eeb33889,88f0681d) +,S(4a834ec4,da3c9afb,c62fec5e,898aa2c9,5a835e60,ef199346,3e4bf255,e32df096,8736155,ecbec836,e8d51d79,9176a5c6,6672aec9,548aa63,b7f5524f,6b20cf73) +,S(2142b447,f2707c37,45e877dc,8039161f,d222c69b,9236592c,c1b3f56a,d30a975,9a48f0a7,1ebfef1e,615a7d5,a9decf8c,70764133,88b0e57e,da554257,256e41d0) +,S(c3831b8a,eb58dd77,e21762c5,f2e88035,63fa8b1d,f5d1fab6,3d012fbd,27971797,45d1f565,6fb2779d,6ae18e96,4d9bdf61,924a5f6,a7dfbecd,2224f1c5,70292f46) +,S(a09dd11d,b78332da,663acf08,c08b3d45,d0f4740f,5df66e39,d53e6c68,f5654040,649959b5,bfdfe8cd,45fc89b1,ea21cff5,94f6083c,da8f5e5b,94525d22,3e326217) +,S(53b22e4e,8a17b408,6b119087,2b8fbc9d,fc667b40,223ecd99,27cdf4d2,a9dadaa,87eb7fdf,b9c6e23f,e7c6a8d7,fdf94438,88c6c0b7,1a3728ae,ca8e83a9,4403bbe9) +,S(7de0aeb6,d3c264c7,f39b087a,e62dfb5e,aac6fb17,483bf33e,bc34a903,f0ee35a7,43f92307,6a2205a7,f2f0737b,2167863c,43f3cec2,ea3abe32,9bba3792,6f070847) +,S(ef20ed3f,3dd1cd8e,a610f1da,64086eda,a4a646dd,e2bff224,ae72f069,f341b532,c3477d8a,a0acf4a1,e9c83a1b,c890e59a,1b739a82,55d3747c,7403034b,221fd0f3) +,S(ab21ffa5,3c7baab0,4ee74647,5a5e5800,dcae9a10,644c84f3,a108cd41,cb0dda53,3a02b102,dc21cf05,3abfe19a,2747f34a,35ec6347,ccf02880,5aa95119,110cdebb) +,S(ee8aa184,532ceae,2c3a5071,d905c6ba,bd1982cb,391151f0,fa869339,aaa50ad5,157d9d2,be135082,9eaf2c54,94e6f90f,8a82ad35,2d486dc,58068cf1,c96a421e) +,S(6b234cdf,fed7575a,f1cd7ac0,76c4251d,5853718e,2ea07c04,77959afe,5c0af2ce,223c14f3,d3d61375,d104402b,bbd51026,a7644b15,4f4d254,85e9a4a6,e8dc2831) +,S(e04eb879,7821557,a875d846,75496d9e,420ac3c8,6e718e45,347a616d,7616e836,59f33383,8354990f,2189cec8,af523611,df4a1b30,3001c5d,84e1de70,bbc6bf31) +,S(6b8c79d7,791e8423,788627b7,a99be936,145a8eed,178c8bec,affa8a2d,72965da8,28fece24,22f67bd8,a2d6ef6c,66fa51b4,c4abe766,7480b520,4f77bd8b,2e3863a8) +,S(d21a9136,eed220a9,708c09ed,2b22f5f2,87868a1d,493f6ed6,2fe9a455,42a4da0e,efb15959,cc7a2c02,7ab7f5f6,ec8a538e,91df38be,f78de45d,dabcd8ef,9b5394b) +,S(f950b37e,a5bfc8c7,a76ebefb,f228043f,de066a1b,cbb30688,b73e085b,cce1ce6a,6bc569cd,609a15d4,28ce7874,53ab8d02,fcdc9c50,c8c44016,ee2b62a4,16849616) +,S(75a72a76,520a5f29,368338ec,fba063c8,977548f3,7bbe08a2,e1ff5e97,88b9bd3e,41c140e4,5e2be58a,dee8af9b,e64cbe8b,4c82860b,98299d52,3b27737b,3266f978) +,S(4474da75,3d9c68d7,2218648,1ce835ca,4e17220d,533adb53,38a1978f,cdfbc3f9,b5e2d3c4,ae2c8276,5a337068,58e76666,52a81638,27cb6b94,3d2b80cb,36ad3eb2) +,S(e3f3e682,fd38b067,33f3e91d,585f3ef2,aaf90409,ca125479,b93039fe,3437388c,aaef5ad5,4bfddc87,f7c3f969,94564ac2,27e6d5ac,ffd345ab,246ee2d8,60d9242) +,S(140ea6a8,ad374157,396b064,f7a952f5,358ff408,951895ee,b66b6140,d969afc7,2f340af0,b08a67db,e6ea7535,581b763,24308f37,6015de2,a4dbfa64,1990cc78) +,S(257c1e04,2fcceda7,9aac2bb1,1f01bce9,37b445b2,bff51fcb,555395d2,d0c16b89,73b21d9,75bf23f1,aa0efe21,5141bad2,5a235978,e36645d,8503a60,3956cb5c) +,S(c243452d,664d2610,d1acedb6,ab5201b9,cddce44a,b9320806,4824329a,e0b7a550,50607848,db2b53c3,c9ed2b4,8c0adc28,322d2e,1b30c3df,1ab9dc37,64b001ab) +,S(a0ae37a7,3aee0e63,c0ca3e50,e59a660f,c7ced178,10dcab26,7f91ed44,3f265fe,8332d25b,94e0555c,21ebab61,cd209599,bab277d2,fb9660f1,f237c9bb,4327668c) +,S(2e4886d6,678f10a4,460b4ca4,a9964125,413a739c,64b6abb9,c44f675,1b47dca9,96f6bb70,9602de31,1be57a61,966c8227,e5dda6c0,48d3f1d3,bb5bafa,fc1e8de) +,S(855b47b,efa7dee6,2452a602,980258cc,de813ae4,6f580a46,d5d18432,5b423f8c,c27f5513,114fea7f,b5a405d2,3f25915d,775ac895,7fdc6e74,2d968bbd,d86c181f) +,S(dd360b5,38fe460f,9d6ba828,e2ac7973,46dc386,de05022f,fe48e891,a115e2ac,8fbc127c,d9e79454,a0be9bb9,cf25b7e2,71a02e7f,b4c68653,b7e08329,747cd68f) +,S(993aa6eb,47f7713e,e6c5bea8,1a65af55,1036d0eb,3df8a6f7,e091c16d,3f424c7,8478497f,a774307,d47ed357,35462f3f,a680eb87,fda11107,275c1883,e859ee34) +,S(4828feb,5e3abb4a,2df7b990,e20e1214,804ef219,4cb8acf6,cb8e85b7,5696d961,d8d2636a,6b664b15,f371ab5d,3ff31279,f7c42678,ff380ab0,9c220b02,6ecf3e3f) +,S(fb8dbd84,64bbb5b1,904a2610,2321e59d,ee9debbd,afdbe585,3e1af139,f8fc472a,54e088c0,91a67284,6c81d136,85b4edb4,391e5121,3c4d35e8,47863018,62844742) +,S(851fc8f,cf378f62,5edb262d,e0360d2c,2e9566c6,93abea8a,aec29e5c,275ecc9f,dbe6025,e9857155,83b38b7,a167adff,da70398e,85223a6d,9b940fa8,30a9d9e3) +,S(4d5d07c4,23079d83,d001c000,8c76fb6a,e03bb39e,325d5794,b5414b,46c6777c,d1c1e970,5b80fef0,8450f941,1b8d6197,21f1491e,87745c26,9458d58c,18d14678) +,S(8164d5c9,cc72b489,b6a54e8b,d9cfa9f,8496cd34,3a227a74,f37948f9,5d35340d,90b51776,9e8c68c9,20f5e948,755b4da3,2b294bd3,eae81da6,e0c0b287,ce229bf7) +,S(19a42dbb,9ff7a400,aa821c88,807281ee,ff7df5c6,e047cc51,9693c191,6145e00,369e9596,903c35a8,bb38f4d2,a74da3c3,cd2246d6,b0391e98,e01d6101,439a1018) +,S(7299deb0,a9b7bb52,76c8acae,37ba0ee7,bbfc9c0,7845765c,136cd762,7e7b7f09,8a0a1d16,f00e3090,cfd9cae,d8aed291,ebc56d97,66a131a1,4fdcf6c9,ce6b49bf) +,S(12c7adbf,112e7718,a3ec6774,1597d6e9,87763a10,4350650,e6a804fa,507ecf6c,b3eced7f,bc3073f2,5f86d647,6d822b8e,eeeab7f2,1b3263be,615517e8,ef3b1a64) +,S(b2d76aba,c1af6c6a,b4840b34,db1125c8,d5baf2be,90dc7e6a,52edbf79,a4b0ccf6,92938b87,641e0886,3f22f5ef,e27f9b18,80210d14,312ea6a1,eacaca0e,58c0f73f) +,S(818baa52,8251c326,bf545ff3,a56596b,58e0b525,64ae359a,c1d5199,4b52106a,9f8b4753,a7b56b26,e0e79b9e,9ae5f30a,64d0ce27,5898bf3,c0f12e43,faa69681) +,S(e08080aa,21c9b6ba,da128bad,62dddd3e,e8e5afc1,c460b997,45eab92b,b1663a80,2b878efb,95a19892,8b3609a1,cdbbc1ad,d1530a38,b528539a,c52fff24,2c382dcc) +,S(7a8486a4,1d774bb1,32321247,f7b87964,1b18a621,508f5376,99b31798,490f3e8,ee8c3085,5c3fa5c1,6f90b68c,89944aa8,dcb824c8,c37a0feb,ac796403,15ee96a0) +,S(f74e74f1,6e67c1f3,f5952373,e53cb85e,650a6dae,2302f495,f6882b9d,e2b71cea,1b15103c,8566d2ee,cf5c59c,dab607e4,97075e30,1443b75,42620545,2d1d2bd6) +,S(3ab4150c,cdfd6793,5f8718f0,dc961126,114a5d82,e1791c2d,48740425,8e8ba004,2a6c6f1b,9b546945,f9d327b1,437b1c58,30a48eef,6a14887a,9d8ca24c,c6bc446d) +,S(effec0ed,bb80580a,7bdf80cb,38cf775a,43b786e4,2c80d73e,7a254216,ed7ab7c9,c7c27bd9,57c996e0,42ceda33,2d0b5972,91ae5725,6df77e82,48bb1716,127c582b) +,S(5f49ea21,4d80f735,fd5f51d0,55d4e2f0,fbf0f804,a8f32615,340bd6c1,65a059e1,72e0f032,83684df0,98e740df,bcc39d61,6956ea36,275ca5ae,dbcbd682,510496ca) +,S(2327c29a,7f906,4cbfd900,43d28618,5c555bb9,bb64bab1,c3e20417,4cee2591,db1711bd,ac9095db,39e3d2f7,d2b84129,41dc6f8d,116115eb,7bfe710c,13b9e41b) +,S(12f2f427,64f77c84,f8a97c5d,7743bd8c,cd0c6132,5cd10fd1,76975a97,b447991,713e4660,cadecd98,3b0e4986,855c2c67,bc220334,2991a18c,bb0c08f6,8282b246) +,S(cdd3eb6c,b496141c,b99bde6e,a66b2c78,7264e6c8,74efdda,5ffc53e4,b3292a08,d1270d9,7cd63394,b385739f,4da31dc0,80f410a6,aee164fb,8147b7f6,9f2f1cc9) +,S(2ad4df2,1ff316e7,ce29d76c,da40cb7e,31aa7e14,49fce23b,93f0d096,e1b74159,972c77aa,160c98d6,c64dd9d1,4a0cedad,875e09b5,b0d5378a,7311cd2d,a7d641a5) +,S(df0ed61,d6c8f906,f970b9af,b4080368,2f12127b,e318575f,8e2111bd,514c33a8,e9e67c4d,7b1b0fb6,fa0a4640,62d72f,28180e6,bc8bef1d,60a1ea79,2c4f259) +,S(9572faff,160577b1,83aca01e,45d61647,7dfe147f,a6ae0b26,ca0264aa,23d2870f,b7de270f,572e1503,8a4a9b3b,706eb7c0,2a6e5e56,ab0f73ce,9f4b7926,a79c5c5) +,S(52583f1f,1d51acb9,bd25b63e,158f66b9,8e021432,427efd5b,bd629594,ba951264,3267373a,94719487,344c9af6,1eb4b726,a595bfd3,41d78b33,f3db8897,7e53427f) +,S(c95cd125,7e59d04a,6d953d7d,f68089c0,c29b6a28,90ff264f,74b469fc,af7cfa58,f5c7c7fd,82d3fd51,4031ce72,657cffd2,da83d072,9b0c4d6c,66180214,9e6ac90b) +,S(67a190df,e1a2bf4e,cc23972d,24d1f13b,803a9b4e,5c1f3cec,55d2c2c,3b0b2487,5c35f795,c29a2f07,74ded776,72ab5a7d,45902f50,e76a229a,212d580e,5edeb8c9) +,S(7ffcb588,ee9192c4,3bc5bd3b,4d0c8211,28c3f2a0,62ec3b0d,77752ada,69f468e3,9204301a,fd0ecd0d,26f49878,47c42c70,e526f7d2,e69a97f9,2aa1c357,d4140a8a) +,S(7d693f1e,6e35e062,83f35910,3c1cdd8a,5279c4ad,ed0edb63,d6c574ea,322e91d6,a9042da9,ff323c4d,46b2b40a,1d44970c,92e3cb32,ddd8dc21,d32d609,c5611888) +,S(7e0e5dae,8ce3c883,49a9ee95,fb357694,a7bd48d0,f27c2eba,49896e4a,3da04fab,a397f8ac,dd4077f9,58d7b5fe,28582bcd,4c46d1ea,fa253db5,18fe90c7,61dbaa4d) +,S(715ea4a8,e5eca76e,48605688,560872d6,7a499a8f,e84f715e,a91d724d,71fc0f06,9a7b3eda,8b82dcb4,60ba3515,18c22f59,fade0636,dc893050,a51530d,77ef8501) +,S(52a9c85c,ca99e4ca,50f5efb0,118fa604,b7e789b6,b589a5d6,368bab11,44c8dbda,3796e4e7,87dda75a,59c7503a,f27732d,8c973414,c1ea0a90,fb6cede8,a5066fa8) +,S(58f1c65d,ee5ea200,57644796,a94e4a42,771c827,fe032116,657e990,b56e42e,7f12725d,388a22e3,4f191714,9f48f0a3,3d537c8a,1037247c,de0594ea,a11de507) +,S(3ce165f6,5f569bb5,e594110e,ef91f30b,7e330586,e86cc4c8,347d1ab0,f4a8eda1,90480327,7376335,72d92c00,10313f96,9a0c5d18,c852597d,1f88020d,f69987bd) +,S(133bb4fb,1a16b008,80379e4d,ca980355,c747683,cbd7e81d,87a9eb8f,4219a314,30e76cea,f57f8b17,de6d31e,447fb926,b1678651,e980338e,8f8327d2,648ba25c) +,S(cb26bb35,4cf94461,c675838f,653c3844,24ce543f,32ed7b5,ec1b6b33,a2f7670a,d6f9be8c,7f3781ea,fc765264,c9e84f2f,6d2ff771,25b8d381,199b67c3,763c4f2e) +,S(7d944d40,58cb78ac,739b85e,6dd3be5,6b08fd56,767fd02b,1d5bba08,d4639f1a,79716d18,44baabcb,aded3600,ffa68989,45920de9,1f2cbc83,e6326ed4,e37c3fc0) +,S(c4577e42,ad4014,e1fbc0a4,d69fe37f,49937d1c,19a95765,74f2437a,d06e6589,4a76bf04,18a4a8b,af103581,b6c2cd16,727fccaf,12a3998d,52b1a095,c5388570) +,S(c71f462,9196f35a,cefd651b,3f6f2b30,485e35f3,305dc774,21535961,60a17a0f,9ff53452,52ccf823,b83d47a1,a6a70f84,b9c83142,db0136cf,d03b1f24,6ec57590) +,S(35acf6e1,cad058b6,7543eb60,ef4d896d,c21c4b5e,292c3885,d9e42cf3,85bd22be,cce4ea31,c9a37f8f,21e32a5f,6f272699,7cddc6fd,8ab11c0d,12c3ca4b,fe6b0e92) +,S(c2872bec,f2abb3fe,8a258b3c,51a2bf82,6712ec12,587cb33c,a6765a4f,e3a3e448,a739cf63,63cdf69c,15c9827a,f759e0fa,f7d92112,9bce9e18,bad86c0a,9f6bf467) +,S(50fa12eb,c3dfb3b,dbb61a16,a8b0cc6b,6e6882ae,f245360c,e5524143,27d2bfe3,873afcc9,5ed9a3e5,2f1b0515,d901e9c9,3677d49,4e64a478,11ec59c4,c3374393) +,S(3ff1688d,65cc134e,c6f27fa2,eba78abb,2cf22eeb,57163e2a,150ed7aa,17b3640b,ec8f8f66,11d8f7ed,a296e690,63b3393e,58d8bf85,90630da7,3dc2c0ec,e9e05870) +,S(91a113c6,c53b57dd,60b2eb66,e6bf7ab0,e721dac1,acd71d76,2c278b31,f2fc2701,beb6c79a,2fdba188,4f98ec5b,fd97626a,131f5c16,d4466a84,a9d77213,96220b17) +,S(732b5521,e6cb7053,ebfec5a9,c5b35f47,8da4a9b4,c4bc5708,42b0e8b1,242bad45,30afe970,fa640757,bff0e825,93a102b2,e1b619db,7f7d68f1,17f27543,e72f57c) +,S(94831570,f0146aaa,fd2a7ee5,11f992c,6e2999a4,b22cb176,dd516dbe,e0e16e5f,eb275132,385efd06,35baab61,5367697b,8bef0c93,14fac991,4a2c04e4,aaf785df) +,S(dadb60a9,3af95d47,cebb540a,1c0aecf2,839f1be3,e264a294,bbd03317,686726b0,8b4bb755,46efb999,cddcb88a,ad5b28dd,b73ae1c6,48c810bc,cd9d0f03,c200e27d) +,S(148ebf0f,7e23a220,52ca69ee,57237eca,6c1caf1f,faeb8718,b9b8dade,4b97be1e,32f68bfb,464ae6a2,b23ac7dc,3910a87b,89ff7042,e863ed3d,3038d75a,f3689f4e) +,S(ec532193,614ca440,33a8275,49c65e0a,af446a21,6705f9e0,68e448e8,6e882bd4,30277366,58dd1673,d9f701ab,50dc3238,f073a297,d579cb8e,2ee51dc8,bcd44b36) +,S(bcb65ed5,b16fe248,bddda875,28eab71f,d9357099,af71ddd2,9a8471e9,b2b26e99,ed827c35,e6e13dff,ade8b9c9,d2c620e6,576db5a7,1b1e22a0,3f943f96,cb7282c5) +,S(de30301f,18df0e9c,15d709a1,35c30473,28cd3356,95922ae0,f283290a,638d516e,89398261,37dbf197,53012e47,6846f6d5,45a48312,bd6f4c65,255b89f4,a1b9df99) +,S(2eb56a7d,b051e9a5,8a7c12a3,a92509d9,5da4956e,8b820006,aef166fa,92873644,30867ff9,7ef8d955,d497abfb,463838aa,c946d487,d702956f,b75ebf89,e25bddc2) +,S(88f839f6,d7f06f85,82ed781d,12062442,66d4f9a1,e2007a89,f660fd24,ebb30d5f,29ce1d8a,376a587e,96fae37b,521a8903,8f0bffd8,9f9934d4,eada0750,32faba00) +,S(112cb93a,8db33b09,641aef75,c3f9a399,b1808314,64e8a855,16e309c4,99ca9a16,66b1a1cc,f2255c2c,119bd0ed,a75dfe73,fe2e9d9f,3aa9a6d7,43a4b7aa,9d76bccc) +,S(407dbfb5,53b43e95,639aa6c8,d6868ef3,2f41f1ea,70cd4aa5,9d76ea2c,83b567d7,69fdde78,a4971ce0,b05a57a3,8891691c,d1fb371f,b1322a6f,97849c64,bd7b57ed) +,S(16fb5fd1,fb41d76d,ffc130d8,9549465f,7976a3b1,ecd6a4d,9e5d55e6,b2a6a40d,3d39a810,95904ac4,9559aa89,8fa087b9,b84ed72b,55f17fa3,aef8b32a,10e942c4) +,S(e40302f0,6c102ca6,e6be1370,2aa6e860,5e71fd37,6c87e2d0,c0ebbf49,6fcb31c1,d32d294e,1e80cd,94925538,2156db9f,2bea101a,f652309b,8943cdf,b82d75a3) +,S(8f2cfdc0,eadf8b00,f74305c7,892a4326,9cd31300,d716d652,92a7a36f,7f1b3b9d,6d0e726,838fd161,32d19538,147248a9,5d76c7c0,beadf1d0,b553e4b6,b7d1a2d1) +,S(c7a636f1,1a9cf793,4385daa0,5c3f3abc,8c3a1589,7be0b49d,ae789fbc,e07674cb,4f715f0e,e52c638c,954b8b3a,84baac76,6a891889,db0b7f82,6bdf81e8,4040cfbe) +,S(245aed6e,5fc309bd,980d5597,9380e8c5,79dcc887,a2758e13,24ed3a1,833dc820,a7980b85,c6ce770b,13a888ff,22a1356e,4136eaf2,49238c38,dd103016,f0d0b1da) +,S(91ea17c1,d90556a3,722dffa5,631286b7,f9db0f01,e411ac16,f5203c4,1a8a824d,281023e9,88fdcec1,94af265e,c407910c,54d25f20,69d64b13,c5261f0,c157a3c5) +,S(729db97d,35fdb72c,a354c65,a0e7f76,7bff9ade,964b1d57,a98f9bf0,39a74eb1,59596a57,7c888b01,6e00143c,63f0be1b,d86d95a1,ef59e075,fe7e377,1472bfc4) +,S(f8cb711d,f74a4961,1391871e,d8de6a63,89679130,b587beef,f4eebcbb,9daaae9b,4c52c310,c6f960c1,53f386ed,6842c4d5,bc1b4c99,433567b0,fbc40e93,91a5e022) +,S(1700d0a,32624d75,258d80a6,2228b6ec,91e66949,a463f3b5,16dffe43,b9fa08fd,a007bbb6,b687b509,f450908e,b617f176,92918f18,be3113d3,8a80ebe4,4ee750b5) +,S(9f2f3ee7,70a2c422,b9b92eb8,a52570ab,b5354154,57f0efec,fcd9141f,62894132,c977d79f,ef198135,b69aa3c3,77a7f251,3274911a,73736b2e,c543a721,17908588) +,S(86f75064,8a2b829a,91acae01,4beb20f9,aa9ee46e,8e513678,c4fbd7c3,2ac36e6e,1768035e,bd1fd375,7caacc22,495a5902,a3c616e6,49eeebe7,4377b996,30192b28) +,S(1d4207d7,adcbd969,d432bc74,35f2fb75,b35adbe3,fa1f45ab,bf3ee074,b8269f68,11d80191,accff888,928a0835,562186c7,30367e90,91d310d8,2a712a9b,13d70f99) +,S(f782bf74,2e55fd7c,ab249b2,1570d9e8,cfc12f46,5330d2e6,57eff609,7c3d19b6,896e9e48,a60ace9,84d07ebf,12449980,9d96639d,101b3405,59eed877,908394f) +,S(22bde2e7,e3c0d268,f556c478,82e50f2b,634c4235,9067cbd5,a0daed53,1a166a7f,5e03a94a,5baf0f92,7f4beaf7,6b7e9649,aa578eb3,f105515c,ed670c3e,e1fa3e72) +,S(85ef9f8e,b54cc4f3,aeed4769,85529945,7eb4f3bb,1e5849a2,aec7b257,a8a9a074,8a0245d2,f0c8eaf2,84a01114,d29c65f1,c146af0c,dedfb5ff,9e3be650,e2acaab5) +,S(3bd6c026,63620684,4d2e1a89,2378ec64,177145d6,24062d23,ce9c2d08,4f34ca81,7f0e5053,87fade82,8596f440,3687b04f,4a2693ee,25361442,1d9712e4,b3e0c179) +,S(364f9a2d,641173de,4a0cd185,972f6d78,75b06722,3cececc2,9bfb8aed,7ccd3311,39e7616,8d64795b,504de9d5,3049dcb3,a95fb3c9,affa2d5e,8e8cb35b,6cf71219) +,S(8833f933,f4049c7,98493b,e5f764bc,47dae8fa,baf420d8,44c7436c,eec27898,bf615e47,1b0f1029,1afb2839,2c874f83,ae55b15a,58e61be4,12b7c7a6,13868279) +,S(d4fa5129,4835f9dc,49cc3ad,b9401f61,97654f43,ec88f206,9a63852d,6abb4a6,f24535f9,9efed47e,80d66925,8924e56a,44530eba,a2aff32b,70f36551,1db59521) +,S(50eb8613,99f79883,58b9de58,88c47cd7,bd4547c3,96e1280f,2806efd0,d0715b89,dff64137,f74442a4,dd0c25ff,ea968845,f9e14ff4,d3e32010,f1c64ca7,6afb1be) +,S(f8608ede,92c5a1e0,5f61c065,606ae232,b0f81161,bcec88bf,b4f2b14e,22165cca,e583acc4,7ee133b4,8c3c1eb6,5d6f4891,b53c84ec,7bb352ec,3b6e41ff,aa6a2089) +,S(2c00145a,60e21169,98f23b9f,6f83223a,6ceafa12,c1b92844,2a17bd63,582a4fd,ed76c7cf,c65a881c,5dd270bc,7be9ce49,c2990e43,425ccb7a,eebe64e7,eff423d) +,S(b42d4c38,79f7aeec,96f212f,1d5bd79f,bdeb9850,ae44af81,b4b3467a,85c29c49,7bdbbcb6,1eb04e41,9ea8f9ba,dd5289e0,d718158b,63ef0599,55e3c5de,41f833f1) +,S(a5831ace,8c19fd68,85e9b9cf,34b9fa4a,9e80eb3c,36e256cc,44cbe521,6efb7128,e10dc489,3e0fa1ca,f2dee476,5b8ab518,c3778f4c,583abe27,af293869,c765955a) +,S(9fccb821,59ed46e9,18a407b4,967e1154,4566afbd,df6c0639,d5cced94,50e56b17,c430e829,438188ed,a443cb2c,aa7d6939,3004ed75,5ff61e57,8dbe9e64,251615ee) +,S(c1efe41f,44186467,cc0def62,eb0f0ac9,22b8bad8,e2347849,28b465e7,1789fcc5,5d73f89f,709d54d4,e167806f,a07ef07a,7fd1a7aa,dab9896d,33c290f1,dca74872) +,S(805c0816,43fffffa,c9055f2a,996fc2f,fa02b4ab,4fa440f4,8af5878b,4eadb694,b0a0dacf,d9b3b9d0,51ac59e2,b367a8f2,eaae274a,ee2b05d9,18cc0042,eb02b6c5) +,S(d5da1b82,9b477768,bec17829,1c9abc82,b595bab8,6240e705,715de420,fefe498,dba833fd,df1915b8,fb43b39d,dbbd635,8f12d4c4,31b547c4,af07a6fd,75fde785) +,S(73a2441b,1f1b9ddb,844caf0f,8cb0a91b,5adc6556,6f883026,8ceeca8f,7c6c5cae,512e46ba,b47e9eaf,64cfce27,24566bf9,ab43e32a,bb0e098a,5dac9687,11927437) +,S(dbff750d,bed18702,eacea6d8,b54540e6,ae60ea05,85d77db8,7a63a050,806037f4,1f349895,29ce56b8,bba91938,16e842fc,f74b56e1,568857d8,2f193e02,207f84db) +,S(57c73f7d,57c7882c,5d574f70,fa225552,ab3d7741,260bfd3c,b616d6be,9698dbb9,f633edba,f7f6cc7a,9d8ff9eb,75bced20,f865fc9e,81245e77,32db2ed3,876e42f) +,S(6663e27a,7760f187,a1f67823,64044da8,d4cb82ef,e296f5ca,90c5d81a,49b7cc5,4df0d12,4ca9c8db,4885f8d5,18cbf06d,f5b437e,242cf86b,b11df29c,5c83937c) +,S(83f688c5,88ee13f4,a9e72023,5169dbd7,ebbe0c68,4cb61827,3e2b75bf,5fc581d3,f76e519a,151ba05f,df5f11e6,f3cfbcdc,4b00776b,14c4598c,51783088,2b2bc6c5) +,S(2114e129,1f65c339,d1bd4373,6c677937,4385b3a5,5dafa8e4,a0515134,6b650389,88103399,1b682f7e,9ba02fd3,e104932f,802ed44e,b996beff,7fa9523e,c9c2a9d4) +,S(a68b163c,db6c8aae,8ddeda39,7d8031a1,394ddc36,48168f13,47774ad1,d569233a,eba470d3,4ae15c94,57ba1b3e,cf5f3d96,682b8095,f83eba7b,f319feee,6740d3e1) +,S(a44b2a55,baa92a2b,cdd2f06f,36874d69,40416b79,20bb6daa,2bd9edaf,c12bbaf6,d06941d8,28f1092d,3667ce3d,59d23159,54d6cbcf,c0da31d5,1663a6bb,ccedbb47) +,S(5630eea0,8fee5570,c094ded,917746e9,18535cb8,b0286bf6,f6cc294d,5714fd33,91f60b64,3457dd9a,b2a02ff,99f931e,b38b4d87,204de10,d8a30cea,ce576b62) +,S(cc8b173b,d3112432,cd0c741a,8620fc26,ac5c5d89,e05c18c3,13067fe0,a41b4b00,8cdcccfe,b4ca500c,34dc3087,58f424f8,52517974,9a33e27e,8859515a,2f7c0926) +,S(abe16c8b,e0c99bf4,d396e70d,af00af89,b5d95f5a,3ba33570,892d086c,4b807943,14b2bcfe,8cec39c5,826fad38,9b8f8788,51e1595b,b25b1a87,149d8627,1218e9b) +,S(62411146,ca2da616,b557f0af,ccc2cb75,d278b07a,4dacd864,7e449ddd,cf29c09b,d081b63d,67ff0c07,5f00a3c7,2771c581,87804c1e,4ec5bf68,faffbd21,4c71e15f) +,S(5952a672,a50af560,66de08ad,be4f5cc2,38f3e4ee,84160b1d,14534c4e,2b50ed52,f7d7e2e3,e9612005,a0344e93,454f112c,792f825,f3d3044a,28d9af6b,798da761) +,S(128fd5b5,420f68be,3742def,c987da3e,bca771d7,af1cf8e3,12d6b3ba,df162492,afe5edc4,80c1c8b9,5580dd8c,aef14338,c09fbf6a,a1c951d3,57ca4df2,9d3f183) +,S(6315678a,13cd71e4,6e283287,24499671,6adedf31,38841718,cf5168f,60d4bf8d,ff691d8d,c5f97f7a,f2ae319b,dc590518,6ec3bd36,7f492d0a,95cda47,9492ad3b) +,S(50277159,4169f70a,ab39095d,d8027324,e212f78b,c3b0865a,a57f1574,dba1bdb1,e31fb30a,58eca0da,aea93548,bdeb9f32,325d6c30,69b3d936,d610bbc0,de3b771f) +,S(51eac8f8,8cdd7ac2,46375960,c6b7d9fa,a89352a5,4024003b,cada1e6f,df389721,6d4c8750,95d6ccfd,9d8a5830,c4672c71,d414ffe7,cff2cc15,b7b5d169,48e872d9) +,S(bd39330,76c0f542,a0590ad6,398b2418,92b899ab,75ba0065,b1ace928,b8cc0ecc,12f4bfc4,57e97c3c,9d4a21c2,ad106ee8,8cb5bfc9,92d151ad,589e90f7,d65b5d8) +,S(bd0eb600,5ae967e,81214a1,889f7dc5,d1e765a1,af74a93,f5292758,539d6dd6,2e532797,9e6a22a2,63025e57,4805e4c2,6d62b33c,5269d35b,bdeee7f6,4a2cfc3) +,S(b7b068b6,8ed18d80,67a0c971,a06cb3f0,5c96ad7f,371dd849,aec3a2f9,bbe23eb6,89871d76,d3e6b605,9997345d,4246087a,a3fa61c7,dd75f5c7,b2ed1e20,59a00350) +,S(10cf2c38,643a08b,dd842c4b,79efa2c0,3b5dcd1b,c708b253,ef71fba7,f0e51f48,e37d14c,934524d2,dc562f6f,997227e1,44094184,e8342995,d5562000,34e71f4f) +,S(5936b571,20b6dc97,ee242ba2,deaafad4,5ab83795,9f1e7390,54a0c026,df7bb342,86bab74f,b9d4f776,e82831c6,3a409237,d5923c7e,7b3e0b18,12ae203b,64fc750) +,S(67bb9ab0,bc48fafa,3ca66493,995ea995,e36cdfb7,152d64ed,ddc56aa2,6c315896,cfa9a456,dc2c82b7,f87f4216,e365f5e7,97223d2a,820a127c,a5ee4ee9,281b71b5) +,S(5580326,678b44ad,fb313c23,dd8a7dbd,c6869fd,70cc58b6,d20f8b92,ecfd81b5,6d343687,f3dc733b,55dac794,c895e5d5,9032613,563f2d72,ee94afe4,c2a932d9) +,S(fe285767,53d2466d,d056d2bb,b7141cf7,e52c2b96,d0ef3c8,52c728a7,d2dd8126,f344b3ad,c8077e92,24c6c5a9,c9f40a1a,d8721351,6b8691ab,c5fa9f73,726a6c98) +,S(12f25359,638fe4f3,97a17f99,c233b2ea,7a794d71,e677b206,aa32f251,8cef615,dd0d68e5,324e4325,ebd45766,441677de,40c15792,19d65c6e,9c63f15a,91519c20) +,S(f1e45fa7,21bf7fb4,45fe3eed,29c26bb8,bf1ea59e,de7c1a6b,e652663d,233c3e9d,6d145f2a,c3a041a9,83b9865e,66775342,a0f8a435,de19626d,ca8b9328,797e20eb) +,S(6b6ab442,d2623235,dcc7e3e4,85d00ade,7f219576,509c528e,6a3417a4,fefd328d,5d627367,ed25278a,6d3505c8,e13970ba,253a26a3,c605d11f,1eb345c5,56584e95) +,S(83e10be5,d21bbef2,ed1ceb33,c4e558ce,bee76405,257d9573,51f5d90e,f219552,41f5e174,c6e9b283,2a39c2fc,4d4fc573,634a8975,e143243d,14dc4be3,434a4380) +,S(2ba25948,9571ce20,f792129d,f43caf4d,ddd93b76,e4c8cd63,7a9de68f,f8d615c5,9469a49a,d1a814d4,2f460325,b7d58f2b,eeb85183,a370cc3,69a685e6,a87f6e61) +,S(3fac1508,b669f540,77a840ca,3ddeec5b,b70c03b0,ff93a77d,f2f73df,2728f36b,dfbac9d5,ceb21745,a6d27c3f,d6fd96b,af708066,a3bf765a,208b7231,d5fb6955) +,S(8996dc02,9b79d0f9,d57b8c8,549fc01c,2e1c1c7c,2ce2cd70,7a0bba0a,b3420ee,d08fcc05,5194c4bb,2d17ad54,2f9ec734,f2a9ab8b,a7dd0467,c5d916aa,10f7b8b1) +,S(16af9433,c9baf15d,921f931e,f530a477,b04b2e03,e1e8cd05,42e20628,df7c3241,65863e2a,acae34b5,a1dd53e0,5efd423b,165235cc,69195973,2d0f64e,c5b56fac) +,S(d82af39e,eda70e3c,f28e2f6b,b8009131,59ada2d3,854e81a9,3798e402,43d1d3c,fe03de8a,326e8bd,b202b5b9,929c2f3d,4bc8abea,a2377cb2,29cd4630,d1dc1c50) +,S(a7ad92e4,7a442903,c2f91033,7e2ebc98,14bfc943,f2747eda,666bc813,c04382ef,ffba6b43,9379448b,56b20163,44439b9e,8d6da764,72f67a27,9c7f45a,359234c1) +,S(fe9b9274,7b27f7b0,6419dd38,53e61762,de7a5116,48008802,681bf521,21a1ff92,f32bec26,b9d24872,1a47c65b,48426130,b8e72e68,d231bd4d,82c5d4c2,bde605a9) +,S(8e22ed5b,e5d80940,970de428,5ca609af,872b8a4f,b8c93942,fa1e62d8,588ac5f5,6a461962,b74b0f93,afa72284,4837ec30,b99a65da,d688c161,cfa42028,2ed97167) +,S(bd3bb0ec,bfdcf06a,62f0046a,989b45e9,c76f4d9e,b3225495,eff70685,71518fb2,5592029f,3eed8e35,727865f1,dd2a6de5,e19e6eb5,f92e520,529fe97a,c296820a) +,S(50a9dbb0,b08a48b8,76dc65fe,6e2efd92,d44053ed,73b8c279,5b688e00,a1fd1455,4a1fae82,51581f9e,32fe8f67,5675ef70,dd7c2ec6,2a42eb3d,e1aa13e6,717df147) +,S(6c1dc44e,67b52cf5,a4564ce1,7a9da713,c718833a,6d527e7d,ebc6b1f2,c893693,89cb4508,681d58ad,77900c1c,aeb25c59,b307c9f6,c84f1329,35e32af1,e39f8f67) +,S(3ffc35e2,4d4fd0e6,ffe4d1c9,b5097d10,c12dc7c0,4356cea3,b5fad66b,5f3333c0,89718e69,78748c6d,e99d181f,137eb74,6e28b05f,27af7726,e86c5f5c,daa1eaea) +,S(fe2261bd,b40fc492,99be54de,1d0bf22a,634aec85,77b5e9e1,51626d67,3f4214eb,896bf33a,5c9b7537,b621a168,f3da1bd7,dbc94816,922350fb,38925c96,5e57c175) +,S(129b6e5,dba2fe86,749274a4,f1ec5999,b2fc682,933a1120,cb8e16bf,4f4131e8,24dce651,b0fe4770,6c78c217,f0d5ed4d,4bda4e7e,4e7ea6b9,ca59e751,b018b5bc) +,S(c2d1b280,79d91abe,1a44c4bb,96ab548,90323054,94075907,37b39ea5,e1fedd72,6974b9f3,80edabdf,e7961bbd,71ba1971,ded6ba24,90466d1d,a5715d9f,92472637) +,S(d8dc5f38,76f6049d,a9a5c9e9,396d287f,911e06cb,ac0148e8,26c8de93,15bd464c,701d0a43,ab41f321,b8f86ea1,b1f51d0e,c22a3399,c1d8534a,433ebc2,38ec248e) +,S(2b1a41d7,ebb9756a,b62a96fa,57909ad1,a747dad4,b3730da9,a12dac8e,3ee4c414,8ebb1512,3f43224a,c2cb4ba7,c90ed765,5470a968,454d0c81,1ebe3384,5c6ca968) +,S(724fe9d6,e7f75b52,7da19421,3c984e31,f63ac3f7,1b5819bc,344ea339,567bc179,a1db688d,ba1d85fb,20da08f,802b5195,163d179c,7bc60f70,4ade1f26,4e1552fc) +,S(835b30f2,8e54b834,5ce95569,7d71b7a5,7cd4b5b3,17ee3fce,57722454,7695c9bf,f431ded9,b7ba9477,ff041f83,22685e4a,8c88c91e,15a14f21,6b16e302,e243cd11) +,S(f5015d22,16cfe581,e650e579,c49b6ccf,b5ca4dc6,42561256,21df7fc8,19047ee6,45b099ab,febbb493,5356872c,40c06825,47aaef2a,72e80d27,521b65ea,e2d4918a) +,S(df0b1b57,f3a0dde8,b136a92f,bf953a83,694244bf,99782ea,98050bcb,3313f826,6f7c8326,bf5f6e15,538a1f31,273adea,6908e5db,7f38f395,49284822,12124d5) +,S(a5a24cab,96c04bdd,6e5180a5,8fe27f9e,51897bcc,3a0aa9d8,de06de65,53d2890d,4f6dfa5a,a6b44550,105fbf39,7dce3a4c,e0b42362,4a97d979,eb31324f,f1215525) +,S(849c2e79,422d1dce,4b568aa4,c80eba4d,d8acd237,71f6dff7,40849bd3,ecdb7e41,a465929c,a3ab167a,dcc4fcb1,7ef9102c,35d8937c,fa900ef1,8022918a,6ebfe79e) +,S(a9a98d5d,d8f8ce0e,ddcd90ae,671c52b7,1b09b75d,b4185d4a,1ff12c71,70b499a0,a4eb522e,3aad7f1,6aec7758,c9528bb0,c07184c9,e3c965f7,afefe128,bd285c5c) +,S(8d60786e,1ec1fbe9,61e056c2,d6a57c5d,813d7f20,bc8c68ac,eea0020a,2c4e57af,3a39b0f1,6cc346c7,fc695f45,91b557b6,3c1f8500,89d742b1,60c39744,90e55720) +,S(4710166e,65b9a2d,8de5b80c,192303ed,25cbb80c,b91c57a0,b31a38c5,5c218fd1,b4cd95bc,fa48a016,658382af,37ada302,26887fc9,8200f77c,2b8819a9,ef489206) +,S(e2183510,40815901,c78a304,e6f0d545,5a116560,a91d84fc,157f061,5ed6c0de,6c557bb5,358454d,419c5cb5,1bcb85e7,db3b04ba,d18e1a63,a75687c9,8fd6d973) +,S(807cf529,8730d656,e68b4aa6,5f8d8692,ce246c2c,4e668c69,b5e93e8c,d26b289c,b22a6fc3,d7ffdf57,f18e7447,38cb1bb0,aafb7b39,101d3259,d31574f9,fff644e2) +,S(568f659d,f19f14e1,5d91f3d6,bd2a4690,b274901e,cf6fc684,dd0d8615,8dfbdd85,28eaf8bc,1db68471,4ffbfbce,30977c7,606bc591,dfb8ec02,e43a31c2,ecafbde7) +,S(651dacbc,564fdedf,f4e5e3b6,f2dd366,37c69140,7fa923a8,ce88ed1c,a65e6b86,88dfdb8e,6f117a1e,b99ba423,89ed2db6,cd5608e7,8be2c896,334ffb8d,2e19aa79) +,S(5a17c956,8214ae71,80322b0e,574529c4,dd7d951c,872809c6,b33ece6d,8cd7cd0d,ba4b0cdc,7d7e6ff9,5a97e4c2,6af714ae,f00c9142,5e562ffa,16942fe2,852a3e06) +,S(6d564251,5edd2987,568dc237,b5b98fa8,de9b86a3,e7176e62,f2609dfd,65810920,a99a0d1a,12534f64,fa97227,825b094a,22fc16bb,e8777669,d5aedc4d,58e81ff0) +,S(e3687c75,c0689381,22f60fc5,b346e8dd,17b2dff9,cd7fbea,94aa54b7,ba1f6de9,4dfd4537,1f62a968,399cfaba,87a0b985,cb333510,dfca666d,395e0f8e,2b7f473e) +,S(1a3d974b,49e7e68e,bb2851c9,c9f22d9a,5929ccde,9d635e8d,61aff93f,f7244472,f6c9e7e2,98815ef8,d53a7bd7,9f10275e,ea74ccd8,5d97cc3d,cf2e97b1,83c97c86) +,S(8e0dba73,12c4afe,8e1bc508,4d9f4944,654a5693,81a64158,d7db7007,3f897cb3,560eb34a,2451905f,2e9daeaa,63dff50f,761bd68a,2321a714,45930de0,4801875) +,S(35d9eaef,6c4ded5c,371a655f,2fdbac45,35471c32,b369955b,f8f30d95,21cd5817,c5a084ba,7b2ea4c2,e3c3d081,dab53c9a,ee40e10f,607ce88c,899f0e3f,5850d75a) +,S(44d1dd16,c42b7811,f78374d8,2ec9983,7fbee7ce,4b3a8ccf,81ae4ed6,3b7d2c73,6a7bd35c,b10c4e89,60e3eba1,8f658510,3be8d1a8,5c4932f9,f1e48d81,e3f66604) +,S(4b7a54a5,e7153a54,e4400ef,9311d6,cc16f641,6695fd92,5fcae9ed,6b2738d5,43a7bf76,ac2f663e,daf0036d,b665291f,cf983c0,791a8a6d,a5ee1956,2dc18850) +,S(add4a15d,d1a350e9,e5df62b5,4a6638d,76ee221a,4007a19e,db5bc93e,87f11ea6,c26d6fcb,3a8bc1fc,f1474c26,31a4216d,740cf94b,a9d7e48c,8f01be28,885ee849) +,S(9b52aafa,119ada49,ce33340d,ff75ac50,ac9a9d87,775e8e45,da58452f,228a23c2,67640253,503b5e3f,89f7ad07,b9379bfe,77c946d,4f61b83d,3fced91b,69e850af) +,S(965916f5,89854944,26c1efb7,88079a55,f8109cb3,8bb111b8,42ef7f00,2d4a45d6,9aa2ef4e,61902148,aea7769c,a561d04b,cbe1b340,a231388,e332c30b,8488e531) +,S(3af7890d,c045aaa4,2f7a8f26,5fcff9ea,41bae0f9,87c75c22,3ae3311d,e09b6ffc,dbb31417,27adbd5d,e34202b7,f7a880a2,41f18b0f,b1a40a25,376c4a30,ec607152) +,S(dc465cfe,c07f839b,46406f4d,9a0078d7,57c2fe0,e62aa4e2,212ed33d,5b2026a,1ef12aff,a98868bf,b51901f7,2693f868,5ba2248d,91440380,53bd137b,24b3bc8) +,S(5ae92f8a,cb9e2ca7,2f4d4c70,f4daaf96,bd237bab,2a83c0de,693d8207,baaa0f4b,54e266f7,aa1b7f22,8f24ab91,5e3f0a92,3220512a,de239da3,1069bbf2,35d63049) +,S(38134bb,c6c5a4b3,63421af6,ae573ce7,20421d36,1f4966c7,b9e7f125,f49659ac,5d42678c,d6f89848,72399321,fa86318f,7a4e3f05,4c3bc6f4,6782be35,4ac4aa16) +,S(f2b807a1,3fd603b4,111ac02d,5c646f6e,eb819a4f,7893992b,9132aa83,76892a57,6f1beea1,a315c000,3c957d85,bc5171d0,ccb8ff06,446f4748,738a3c78,f9ec2d4b) +,S(debe05cb,b308a6da,a1eb55bd,73c3f1ba,248ade5d,ceb1ef3a,baecc6ac,7a5e8c09,f4fb16b1,44beb4ca,789aff58,9374e476,efccbbbe,b74e2693,a4d05ba5,a809ff05) +,S(15cbbf1,2720f8f5,fa1a7752,b6f33333,91cf3d0e,c40f0292,24f5b7b2,c966c099,be3b1573,fe38200,a464f4f0,c3c2f9d6,24bd59bc,9412110f,6eca2ada,2f1c7294) +,S(e4fadc29,2f0cf77e,4b14c3cd,b567f5c9,be82fc93,dcdf2b50,bdf20fdb,f5984769,2858e2ba,c9834a2f,942ea7fe,2e339d8e,b384c255,6a48d688,a9510808,a1235452) +,S(b0a8c6dd,f57434e8,a8bee1a9,530cb9d,3d4ac31e,edd17653,3d84780c,6909554a,4f7467d3,62185e38,f6d6c30,e4c3e4ac,e167f3cb,aefcab8b,eac754eb,c76ea3dd) +,S(a4398869,26e4d06e,5337e61d,dcc6f491,4f40c04,eb3ec752,47d9d058,9dfea2af,ac1fdc5b,70d792c0,7bf7e55a,b07ea1ce,477dcef6,cce8585,84cc90ad,c62b6272) +,S(84b362fb,1597f179,f30b7e2c,b516153,94619081,1131d45c,ba55fd1,94f369be,d2a80ffa,44965152,78c2ee3b,122b5c3f,e6d27f9d,6ed6ba94,9258c2fd,94eed4dc) +,S(75182684,96e2d037,24c11192,e9112501,f7c27d19,8b92fa1c,3b0e931c,2b85d32d,eddd2a6d,d884f93a,b6f8d225,c9fb32b8,9f396f1c,2613be98,d866b713,14a00d70) +,S(aa96e0b8,104884cd,7e22211b,8b12e6e6,b3f3e3f7,fdff04fc,202d8946,838fe15f,d8a9b5c3,9739fae3,dd3b2483,4fd2981d,ea529097,2ba52541,56905664,f289e3e0) +,S(ada17e80,82a0a15f,366f3d6e,6775b5ef,35c980f7,12ea7522,1aa796f4,2454988e,7df4c1e3,191214b6,e40fdae,2f5dabaa,b6e9837b,f53eb10b,dd28e674,230cf2e5) +,S(322a0524,20f0fdbc,85f35fc2,de6690e5,a61260f1,428ec662,4185ee8c,d2385caa,fc81cabd,789995e7,d36d3de0,1b650a20,1befd7a7,a415d250,697114e3,c95e096d) +,S(5082ad62,3bf2ff8c,b4571b9b,86303032,ecd137bc,86c5514d,b9f218c,4f091153,b29d3823,eb4ed958,9b0fbfc9,2d006fb3,698ab596,d3e60360,e435bbdc,be4c80b3) +,S(de9e45fc,e9e0dee8,3bc806ae,286a2c5a,a7978608,42ddf02,d29a6ac3,9fbec470,bcda9466,e7207f7b,7d986e,36b3f238,d5bc51ac,90ec35bc,56e0949b,334ef964) +,S(95cbc3a5,61ff4cfa,278678a5,6f8b16a1,efe2d286,c7103047,310454cf,a1a822bc,8720fda5,58d23b5f,af9b80eb,dd5fa625,93325a6b,eb5ffbd8,f333cd9d,9c8b7366) +,S(fa0e59a0,969de9fa,aaf7be60,24136559,cb384b76,26d3bdec,f70f3e55,696a0632,2e8af3c2,a54e837,ddbfc32d,8a47f342,a856b854,7ec4b0ea,6fb3695,48b8b588) +,S(56aadb8,2056ff5b,3337aa5d,337671a8,77168b0c,f0330e8d,8f5445a0,cdd75075,d6c4cd4f,db81d8df,b095f681,f7349fdc,c2cc80d9,399fc16e,5fa3e86,9460a5f0) +,S(7da6a13c,11d5b063,8132254f,c064ff3f,d3818a5c,e07168eb,ed5b7345,53bbc19,26e912dc,5b03258a,f914cd86,88d6a068,266eef77,7d4f45f1,7c47cf92,16d00c4c) +,S(4004b235,d58417a0,ea1a2071,32b30a8,1dcd6a9c,3ea875a3,6d2a6225,e2b56917,1c960bd1,443c22fa,96f06eff,a717b5bd,efe8b105,7402cd93,7a6aa909,5775e226) +,S(b12c4d85,6ec6c85f,3553bfee,c7dacbf4,f742ccc1,356fbc8d,ab3d25b7,52bdfe93,a8a11692,49dba87,8c8e6c56,ff8f699f,d7e69c6,f994d05d,4e0643a9,7f9cd2e2) +,S(a78d9a2e,8b74ccdf,97c6ea9c,aada2644,8b560287,7d7b0970,41d24840,91490970,39cdd434,1d1e16dc,b89fe937,665e70da,ea80a174,5ae7b99d,dcad04e0,efe841a6) +,S(c8233855,b1f242bf,59b86372,ae49a985,2528440f,e3aa8e,28d594e0,114d2ae8,6f515202,a14738ee,ae4b430c,27391144,c551bfe6,bf24005b,81f92900,bda92b7e) +,S(6da24dec,9d6ec569,8dda9655,672a9b79,4923f595,9157af10,64cb53cd,5e5e8f6d,59517e76,8b0d39d0,2c075a46,c1e653f8,cf876fe,cfb10746,a8c248cf,4c73fcba) +,S(d0c55dca,ab79e0c,84ef08ad,57ff67c5,b36336f,2f6231d6,8efa2fac,54558ef0,d4365ebb,4096888f,c9a74d90,1adc4c5e,16f5dddb,442cb5d6,b5e22b32,99aa573) +,S(d76f084f,237dedd,ac8a1936,319d198e,baef2c4a,3b81ae42,e92f96b6,e222490c,c7737563,9639b7c8,32e4bf45,efc8da2f,53e20e25,641ea714,85674a40,1dd5f14) +,S(6a1f6920,9196c02e,6919abd2,c8fc835b,889c5ca1,6bb25e3d,ef7d0c4b,9f4e6d29,84371bc2,7bd206d7,389534ef,f2a49c6,cca4c9c9,874f59b1,ccc8b5b,bd5df3b) +,S(693b3520,85e1ea36,bc5c8ce8,3fa49843,369300c5,170010c1,b11a3c76,4deb12d6,4441c9b7,808b1ba9,8199349b,243f08db,6cdf5326,d7453828,16f008d9,45c1251e) +,S(5ee94c65,70953f27,37c16a59,590f7cd7,87143bab,405f6b23,718878c7,bc95741d,8578d18e,a49f9204,e51513a8,94920224,70837b2b,ee480929,5e4c4f0d,cf5c7794) +,S(30c174b0,e7b0cec7,e6da6a5d,335f48ee,6f59ef16,984e8912,32e874d6,2e51fe2e,af7f955a,8807444,56b2c965,5c4ad915,e040a360,eef0c4c7,891db1ae,6983867) +,S(3121068a,eb60a54f,dd427eb0,92e30895,92335900,cf191eea,79118442,67b7f4ca,d9e8f74,b8d9c0e7,c35e314b,51a52a95,bf672adb,9c6fb104,8d2ea489,5135aeae) +,S(a06f5e3,6513a659,106ec301,cf1f2df5,6093e690,38daaebd,4b17ea45,9e977ff1,eb19f18a,15630965,d2bd8bce,9e350374,1ab35f0e,4b442f12,9c9d831f,3811cffa) +,S(a26af0b6,50967dba,1c4a33b5,5226c2a,ad445f43,84567580,3b97ca1c,f3d217c7,22c8aba1,604df49,abe16949,59b33cce,db11c241,cbdb171c,50b0fb0a,399e6839) +,S(8e4471cb,b650097e,d3b0e938,18b8ec5,a86fedd1,addc6ed1,8703a99b,4128919b,fa5457bb,4068bf35,7b050244,6eef2507,c1d87051,28770161,ef0e92dd,d2308495) +,S(e9116ea3,24650463,fde960ed,eb7d5dd1,f5754915,62c99f48,31b553ba,2663ba1b,e30d7323,fc29e388,94244422,63434cdb,aebc5895,8a6fb350,33141e96,46a4529b) +,S(8b2267e6,9052f769,833b0fb0,ffe413f3,4b8edb93,9a2009b8,59d6673c,4ca6ec37,97f80a18,ac047152,178432b3,d445a0e9,84755d9b,7ad43165,8707185d,d573fc5e) +,S(79947669,d7bc732d,ca08e0cd,d3e601f3,c4344532,e35aa7a7,12271b12,339ee2b8,55906cbf,e782d32c,13cea8e,83812e8c,84c76d38,472ee59e,134994b4,b7b92897) +,S(ca6d40aa,2f863c02,b6444727,d00f8923,ec58afec,3b4a4e51,f4be232a,4b4c7c7d,ec73856,b0529f1d,9d2ed892,b22b059f,35e4a91b,b60c6a6d,e919d611,d9bd90e9) +,S(7ba23bca,5f9a88c4,588dec37,3861b699,ddfc9f5a,5b277bc5,e6e16f54,513fe7d4,25f10a4f,eeb77ff0,e24170af,dea0e2d2,3f2289a3,e53ad674,1640cc69,c042dcf5) +,S(186da622,d0e8a9ba,e26d43e0,b601c68b,311d2046,4eb36f2b,f86c3e0e,5d4ffcf7,53a6f54a,dd11af9d,50bd82d9,70825bcc,fe9da1d5,ab55e64,bbe4582b,f5248d37) +,S(e9601474,568cfe7e,6cdbf488,63f11f12,fa17ecdd,c623cb11,4818eb52,cafcdf8b,96d51b2,7b5e4fd8,1bbb009a,2ce40fc7,65fc6a3,7f8bda60,c4927766,a52267da) +,S(811f5957,accf9f32,3e48ac3a,33fbaeaf,c5120858,943e7065,9c0da185,71d1d4e9,ede77562,cc8ac601,e3dbdfb5,944d59af,63bd1aa2,ffb35bf4,1f79c418,d1d67937) +,S(77424acd,1d55424a,edb0149,a6ea0349,afcf44c6,667caa51,302b70f9,5fddf277,70e15309,989a2512,422a5bff,221c0e0e,df608746,7a34dbaa,99e77f9c,62b56c3f) +,S(e9e139fd,73c2c50,375d3966,ed4af6f0,4bd80bb,439121,d61bfe66,99dabd2e,260efa55,805918e,d45c98b9,c119bed4,21483d88,722e0f87,de7a31b5,e4b541fb) +,S(a9a5313b,e634813a,b10b9b3,6b38ed1d,a971c0de,5b6d1010,4cbe426d,544e7d79,ef7b3203,2a95144f,17803f09,72f6e2cb,80e6a099,5196911f,916225ac,e97bbb97) +,S(ff29a1dc,b5c97b7c,c5e2b73d,7a0e0244,bef71dfc,765127f5,f7e0f38b,f8a099db,b8334f11,682b9a22,ec08a376,dc3994c2,7d235d5b,a4a77803,79ec0fb6,7b4d0345) +,S(c98df4d2,da452118,852c096c,bb34c8ca,a2ebcb6a,e9a3420d,a4fd3eec,cc31c5f,f4f9c618,44cea236,edef80a1,4634159c,72663322,7372cbda,4b2680,b5dbbf7) +,S(66126139,77cfafb2,283e1a92,d6327174,86add807,b88cf793,12fef2b7,197289a8,504387f6,70caf906,2db248c3,ed5faee0,269d0190,70dd5acc,c8599f5f,5e01d1d0) +,S(efa8bcf,281ad4da,2f083e6e,182765cd,ab0e66f2,e8411007,e216a69b,d73d5e94,6e1afd7,e97061c6,cd0794f6,837aefe6,e8ab76b6,53d80846,98747ed4,64e20a) +,S(d4f9fa7e,6e385f02,c068ce7a,1b80343c,20f85b7a,4699c126,575915bf,69a2f6e7,a6496004,f280f970,c1028b3c,e0d94187,34dece11,3f9fc737,2ef0125c,851de143) +,S(5980a5c,456f383e,f0add523,13fe37a8,874059ee,497b0a23,c6dfbb2f,9f6c494,e1da9a59,c8e3d482,ece7972,9c77308,e47bcd90,cdff915c,32a94908,db1651fd) +,S(988ca976,ac6bcfb0,b42125c0,939a1207,2eb13565,29da3e72,6b70b2b9,5c310e12,97368d81,79a76a51,7c7d063a,179a2941,fe5df19f,25f1e1fd,42a32af9,d5de16cc) +,S(ca49ad0d,25b36130,cc878861,f4b72a4f,e945bc0b,dbae2f4c,629a6375,3d88037f,5ad2c0b7,2e084bb3,95b9268f,22ba1774,c6e423e2,4a5191d5,b940c89c,e1039f0e) +,S(ec18622f,b9771723,c8e6e6e3,5096e517,38c4dafb,82b10317,1f55f900,b24c2e06,5803ea86,c839ddad,6c288b8c,b382a1cf,76a790c5,6f99df9a,fc9915e,eac6dd61) +,S(c53aa261,60e627bf,bd905ff2,6b50a171,18062ebc,af9d9ca0,c486430f,b6de5da2,7d6298e0,f17a515,529fc5bd,2b85c7ef,d183710b,96d62a2c,5a0195cd,ea561790) +,S(ad138110,f9161559,229ead18,4b7ea7b2,846384e9,dc22b8eb,5b771027,8c8913d2,135a3ed1,d9df6a0e,105c7c,e6ce625a,f8173d76,60ea04b4,9ee781a8,90595eef) +,S(46946390,304df8d9,15705fc4,5714f3b4,233a5ec1,afdaf145,b6c09717,9c6b43e1,aef28d5f,88f62a7,e3ecb978,6efc97f1,1123fde3,88ec1bed,bbeee3c9,f9d3e014) +,S(d464a300,df9de2ee,220ae23,4d59b6cf,44f4d280,7ab4f588,aa21dd1e,eeb80819,89988349,b1ab280,8b829754,7e5b36cb,e66ddd16,4d7542d1,cb0cf210,44a8be1c) +,S(5e99ed21,9ade424e,25b807c5,bcbeb05,9b638b7a,4ffb3c6d,d3bd054b,b7af9f41,a373ab0c,4aba0b04,878451bb,96807604,7d811fd3,605e8e46,57574efb,21681aae) +,S(805edc92,6fddf92,d33db068,9334d778,4b30f73e,4e65517,42e62c50,fc6ff2a3,170e4317,4361275c,2102aa8f,5406ff9e,7bd35523,8bf1e946,1a6f16c0,38beecdf) +,S(ec6e5a3f,bb96f0af,dd700701,8c046998,49a879ef,5ebcaf67,456748f2,f25fd18a,9401937d,cf584df5,a9399fa7,bb309ffe,80ae015,20933d63,df1fc181,b2979fbf) +,S(94f226aa,a25c710e,2cc68683,2b9124a,ffc5c3fa,179ace52,327c6866,cfdbb3ca,b92762c3,a4c56d95,1ef16db7,b3992e9e,aa2f9c3,ec48f077,62a379f8,408f94a) +,S(8d2668fd,5d46bd4a,fc84183f,4fc31dac,964358b,fa6b03f9,16ac5bec,a619a92d,c24f6815,3e49048c,a461eea8,ce50c8db,7794b10d,d8080236,2af6677b,45e45f95) +,S(2a3ef112,d00514a,c562de17,a68bc4de,c4c04db7,8266892d,b645ac6b,ced47f67,6e93173d,64333933,c3db0f56,8c05410d,8a1dc73b,6a30c6bc,2b0d5493,d9f9fe1f) +,S(6eaa1185,19d6cdff,45d88426,6fac5867,790faca7,4ccc31bd,6eb19551,8f752dd,affb02eb,277a2bdc,db79d91,10ee8a7d,58c9662,22cfac03,b3d26cd6,3c678f9b) +,S(d17802d0,1944d9f7,aab2b542,fac985ce,e56172b9,e5629e53,ddf57e0a,8dd07137,485ae7ac,34d13d9c,9ade04f2,b3fb8cc7,d0cff406,97abbe2d,4961e753,b8de013) +,S(9e4cd82,67c121f8,96c8104f,988a140a,71f0cf18,782b574d,407a4840,607f5804,c05f08,3fb5c4d3,9d3e237b,101f46e0,6547828e,f05040ae,87db7874,9d7f3bf6) +,S(927758c2,12452995,886e97b4,b1d16c53,4603c,7362e190,dd2558a8,43521a41,30e4d5df,c5ff4b5a,5f4f757a,3483234d,4c658b7b,f24dd509,7968627a,a2a86d56) +,S(589906c5,90a1e143,ae7ea4fb,84edc7a,9f00bc90,dfeadfba,1933c36b,57f2bd25,e9d1d51d,92223636,cab62cab,362b79b2,12a18be6,6468f06b,a543921e,bc9b1c61) +,S(5b516216,1171c076,b10d4987,3aff89b,c080d2b1,9e3ebc3a,de8dcfd1,734e2f35,572c40fd,24965ce8,a78c3402,381bfd90,b683d6a0,d379d7ca,21e66804,31b8ffe8) +,S(1603bb4b,3dced105,b1a2b748,21080a5c,2629a52b,56823524,84deb617,2f6a9694,2dc4243d,fd20fd16,d1f2798f,23e43be5,f88d5feb,1f6fecca,6fadd5c3,f5a63c37) +,S(7bbf7555,4c14bf1a,63ef9f38,ae3ec279,5cf0aa1f,335c816e,580bdeee,10d95ed2,d2e12648,81ba6d5e,e8cf389e,84e37ee1,7c178b8,dda63756,32d9330c,beeeac53) +,S(b2d3aee,d083787,eb4e14f,328640a3,c557724c,e06a62b9,17134ebd,fe576073,68cd90be,2df0fa6b,da2693b0,f18357b7,ea5205e,2a1f5fd7,5a1413b4,fd9ce0d6) +,S(dd10759e,86121fd,6296f171,57a90f2d,bc217238,53969f85,4a71461b,27df81be,713442b0,65546c39,1b71ef30,3bb6ebc0,659471be,fc165a3a,686aae0b,270f13c9) +,S(54229d57,3a274ca,6eda6194,62dce4b9,35ed143d,16e470f1,239f1045,6dd2de16,a6739dc0,916112b7,4fd6ab7a,134093fd,55541758,5b3fb39f,da647bc6,5cde08b3) +,S(141f3cdc,124460ea,15fc80fa,dbba8fce,d89c4426,74e9a3dc,55f74f69,66bb8ff,f0c8d7d4,dac4ba66,1768514f,c9bb9e2b,319645da,735e5be1,51790483,d7b477ac) +,S(e9795743,efacb0d0,4c91c74d,33837b61,8d08acc1,cc2603ac,f02b1610,16fd1363,9f1c8ab6,735f3161,811f710a,1b5703d6,aac65c23,35fc1af1,32ba005b,bbe66d7c) +,S(e5e8c40e,c6c9475d,d4cff6a9,c9db5cb3,f8202bf1,bf60ed41,3e213d6f,2c860797,a9570e76,482a8177,b1adf9a0,1a7716f4,b1e754ef,864d2deb,354a96dc,ea1decb) +,S(5292362e,a095d145,c002f027,be53a28e,d5244982,bcea97c,b56d9ab6,162f7ae9,e7f00a61,8e63664,4555170d,9f13420e,fe1849dd,641bbabd,d3648250,81934e37) +,S(a6772998,3d6a765a,67e9e3a7,45e7de0e,1e42f34e,46b7cdde,8ab20262,ad246822,53281b0b,bb45bbf6,a1e804e4,cb6f443,537b4bb,d551c9d0,8976d53c,1020407f) +,S(7ed3bc8a,8a68ea64,c9dd316f,48f012ed,229e5f9,1a294666,4546ef68,bb48959a,238e6696,a7cac135,ac551927,fef28c04,5bbf23ac,9d24ef52,3d69aaef,27312e69) +,S(96702aaf,a9e17a9b,5fa4fe87,d3b45633,b59779ba,57002679,63a3a5,7e7442c8,53deadec,73ed54d4,db98093f,9e269442,d9a4a955,f9b18878,8be2c410,84014a4) +,S(bd3e9c04,42a9b0db,b063aa20,b09e7e0b,4ea18ecc,55a5794e,14108aea,1ffdea66,b5e43b5,fd8cfa37,dfd49f34,1ef14b0b,c2cc571e,cf9f7511,f2f11e15,825a57dd) +,S(d95c6dde,f07abe75,215e14ba,e76a3be1,6dc514f1,7542a246,e48a2a35,108c0833,e49d6c1b,baaf6f7e,44fa7389,31767757,76d6756b,ce8353ab,ca6e648a,cd2e8fdd) +,S(86f7406,7a86227b,2f5414cd,12c9907a,b78464be,8a5c2284,7d8442ea,d585fe8a,53c73db9,3ebd3340,2856a7e3,d91d29e2,e9439a3d,c43120e2,1fb5bb04,384a8e68) +,S(bdd92d35,ba51344e,4deb6b77,126fde21,9e7030e6,5e1d96fd,4987f1ec,bc5ee6ca,a49915dc,b4f29eb5,af9d643a,6c6f581d,94a205de,3a8bf3f6,a26d294a,be11cebb) +,S(dd4b5fdd,3ca88300,74f19532,728a31e4,152be230,2e6ef55d,a6ef9209,fc70b65e,fed2978a,3cc4c8d8,2012cd5,7e06ea37,4ac5f802,a0032e8a,21d58239,860856bf) +,S(fab1a71f,f8a64cb5,14c94e0d,1c67fb23,70998570,ebbb0e25,9e09df03,e82aaeed,6208c3fe,3fd0d9c,640a1908,1a6a6db4,cdeaf7f2,ede4835d,46549734,c1c50035) +,S(4d6fcaff,167a869e,311e8dd3,f736230e,78634ebc,c4470b91,686018c,7b529509,e860a3b9,28927956,1cd132de,a1de3456,576c4cc6,138bb079,a166b9a6,79555751) +,S(502caf19,5004fb43,75b13ca5,16583e1b,3f60b32f,d9769832,b42423a,f7ec78c3,c0aadc3,36019a17,ebf7f2f0,5afc036e,e807df5a,c2869bcd,19c2aca0,1b5ccec8) +,S(35727dc6,ebe8f38b,1a84d201,2fb24a2e,9ddaedbc,63e8de82,e18de4a3,c4d021ac,8eaca26b,3b88adf2,d19d9d52,c84d83ff,89451750,6a77b4fa,fd717b07,4b414322) +,S(7ced897a,47b5b0d5,f4db6d9a,ecd9c5d,54b35789,91902324,6f270d7e,7ac4b377,1c6ce993,fb84c89,ef5dbdfe,68dad70d,ca39a4ce,29cbc658,d5332d1a,6f6cb157) +,S(60d1d74f,660a5f6d,bac1ee84,5aa43dd8,889c9e4c,6b0ce1ab,e9952ea2,7146972d,dc4291c7,db1dcde0,8e618261,b8d177aa,77b5b0f,2aa8f341,8afc9eeb,dbf068b) +,S(a8b28606,e7040dac,7941cca0,b9cec031,31db3f95,bee7d6a9,8d60c3a,1091f81c,3fbac401,61c81632,ac8655c6,d5c02744,7c836244,e228b9a5,bf5d799f,1fb810ea) +,S(6418a48d,2705a27d,5fe68188,58a61a21,4e4dd39e,4151aa89,9fc6d414,95f975c5,21abfd32,14d98ff7,5b154250,8480b32d,ea8c50c2,3400235b,be800520,1609c7a4) +,S(b46f6f80,c71cb354,3058372b,9ba5e6d5,2617728c,54c10cf6,6ead7ca1,de2700bc,2008111e,c4b86ec4,26bde7ab,f52bf201,10787bed,d7b2e922,e3a5a60f,e68a0f4e) +,S(a0ef81c3,c9f78950,41a8d90,69cc22e9,22bc0cac,4e61a030,495ddf48,eaa6dcfe,8617df0,b32975a1,6666f86c,136e8c99,c07ff948,ff8d8176,9d968544,aee5eaa8) +,S(c03cfcd4,21cc7095,5a3e10e4,a4ed12f0,d31abe86,506da6e9,c83cf6e1,df73d093,8d6f0b3,c0d6edf4,b5d2041a,94d13f89,91adbb03,22ba9f,a56b31cb,63d4400f) +,S(4085a2aa,95e4e8f,11b0e94e,2673c48d,d42506a1,81d93a19,b5f79d45,ab88b688,cc769f7d,f45cece,d3cddf9f,c75c4dc9,bb7018cb,f54986da,434128af,b26c0f28) +,S(a485186a,b21c4650,e9f7375b,2ba644db,f22e2db2,20933cce,2bf0ca7a,c404fcb,2d227efb,68649a60,bee9461e,9390ba02,eb133cb0,eb8388e3,f64d23a4,332ec903) +,S(9faa3103,b212c2ba,9a454898,fb451d17,c3632b7f,c9368452,3ddb88a,7599f14f,9dcb34ce,51f7c4db,7cebb0a2,1b50ff2a,d67c6bd9,7066e505,60132168,3be236e9) +,S(1bb9ddd4,804edffd,78d00b86,ccf6a07d,a798d91e,5d88f2a9,37575d96,81187564,6577e8f3,ac22184b,d46339b8,25a426cf,2dc8cc86,78767d87,999a8e63,5789dfe0) +,S(7b32d099,c78bb658,24868172,1b375689,b91f0650,45fe3d9c,8af4a331,2acfdf58,a4c92e67,f4bc53c5,aa84cef5,908a36ab,afcbaf66,a946d98d,4254271a,b4f088a5) +,S(daf23c72,c67145d5,e2a55109,f95742d9,28cc16da,e53d0453,c8dc22fe,a9eec7f4,205dac83,6614ebe2,a55c04a5,970d4ae5,a9ba4b1d,d8d51f52,50de622d,2a2a472a) +,S(6f156518,addc53c9,76a16944,a059a465,8c49f6c8,6ac4339e,82a2f69f,a3599279,50a277ea,6650fd6a,4a5e4c2e,fb09bfe2,78fe8fc2,c7a86089,b4bb0fa5,fa7262d8) +,S(17661b7b,5b5a8a4c,f700397a,1f819c7d,a6c44cf9,a7d28bcc,df6e7fdb,efe50580,dc1d7f84,841d8ee9,3a9f9fa4,6a03b2a8,365398c3,f94b57d6,77ad4238,264c7868) +,S(c3042389,1483fe1b,12f16146,f48ffe67,3a1ca3ea,ea330d54,db5f7c95,fbfce6b2,131d108c,14a4fda7,77d323f3,f717fdd0,a422acfd,20b9db1e,2b2c4039,a330ce3b) +,S(654da43f,70e4c85f,c9aa2d5a,12ce1a51,d4364a09,5c230ce4,f8ae61b3,cde7fa4c,f82cfe9d,bec57ffa,4109e9fc,c9d79135,49817f50,9fde8195,79190d38,f0afd2f2) +,S(c17be24f,d7d2535a,c4eb722b,bbc4444c,fa529cb1,283585c0,730813de,7219b481,2d35a0b2,27582d2c,b8155b92,680f6651,c0040508,ae3de034,cac87591,654c0c86) +,S(fcb1fa46,f8178153,fe5f10b8,a91a411b,cdc4cfc5,61b5eb2d,29446a79,8deb14fb,29c75252,4cb13054,2b9c1a26,b4606eae,6f40ba1a,f73d006f,5bac65e9,3821f0f0) +,S(7b86452,e43ae1f7,177c131d,999b5fa,a6e4a107,e0a06f6f,4305a8ff,d1ead9d8,3e7cd53b,b2f27d89,829e331b,8236f92e,fcf674c6,478846c2,c18307c6,e82691f5) +,S(8271b58b,67a27540,c1d8305a,840475f5,3faa0031,4e779e2b,9e578c07,366a342b,5cf145f8,6fdff832,6712be08,ca1f3a27,d3e58fc0,baee76f7,a052f7df,450dbed2) +,S(3f027c76,4ebf933b,50df3d37,77f60210,4b997d1d,4b9cee19,cb549c58,b5d0fa23,cb44dc89,c533abb3,e255fbd2,6dace4aa,836caf4b,2589113d,82ad1886,7eee5d80) +,S(fbeadb62,ffe218e5,d0245d5c,4bce7334,cbbfbe91,610e8bd9,f0b89953,bf472bf6,7e824c09,9727cd33,1aafba9c,6776815e,3f954fb,539efa5c,fc4ce034,db602c09) +,S(ee2807ab,44643652,12b021b0,dbe94618,5d22fae2,f500a740,127f4dfe,32ee4c60,d958ade6,cb9d3a,ae21602e,d25556b3,b3869202,beab0910,1a1d97e4,8e360e1) +,S(94ab159f,2448f865,f3d38d65,12273da4,ff476289,3dbf74d2,ef889807,81d6802,88739de5,da331b70,87c58bd0,d734bd75,5853753d,1d3b97fe,39c68555,8868576d) +,S(98d2e8e5,a41a0bf4,a880a510,b4b65321,7b9a62f0,c466c589,d0c1634f,557666cf,aa24bed8,a5cacda,bc3c950f,d56bbd1f,f156efb2,4632e073,ac822875,2617d1f6) +,S(64efcff2,76cda1b7,c8e5ab1b,12c73a48,5a25113,eb9a5be,496e52b,ec6ad16,ac29e2d7,18bbf63a,16003992,d85a9090,98ae89,834dcb24,293d6bf1,b8130e3a) +,S(6a8e3376,1636ef4d,b1116d54,34f3fa05,d8cde7e5,31b260ee,6aa9ee61,1c4cf5ed,5161b5ef,4bafa1af,f76a1e21,bdad444a,2526cf5c,c81636cc,36f18400,b8dc47af) +,S(4786ac32,6312dcbf,a1386ca8,c505715f,2bc7f85c,22b6049a,e4386bec,11648013,67c80d39,bfb6cc58,7fb312c3,8fea53cf,6937216e,8e7f3b3b,4a2290e,6d6df687) +,S(b87d2d08,ee206c18,646713e,8af6bfad,c77754c9,59158fac,c31928af,c66bf596,6110c98f,bafaffc1,7b40277c,17ad9650,15de7069,705019c6,b7a74cae,eec6e65b) +,S(ea9f310b,d088429e,236d565f,d1b3129c,7ca8573c,191d1893,c1c157d2,a0867d4e,61c95d39,c1893c68,fdc60ddb,27909f2d,98c9ddd6,efc67ccc,7482c0e4,3c05b144) +,S(abf862bb,9db85d51,5d6a37f5,5f3942b4,5404238e,d49d3124,59f9ab38,29b34ebb,30d13c26,2157c1f,1ffc8a46,a3679e65,35be1981,c202e7de,10de5386,db863739) +,S(80767b75,df3e69dd,757b4c4b,fd0b4be,f75fecc6,ae22b488,214b0035,a276e492,ceea1fbd,bcce30be,2d88b601,895a8fd2,92f61b61,cafa5589,f9eb9652,8a78fbce) +,S(8b7a47e7,dfc35093,77771622,482e45fc,84708ab2,c9c734d4,fdc9e8d2,499dd950,dbbd399a,d62e8309,14bd0ba6,19a9963b,8aacc765,cad19734,e2526af4,2b2013d4) +,S(13700ef1,f1e82cab,7e9a7d79,d76fcfb0,b6e8c18,ec1e6546,d27eb919,bd871f2c,97488000,f96aa2a1,5913502b,30ae5bd5,f9edc84a,f97dac7d,c79be68d,a0f7f4e0) +,S(51f9a79a,991fe61e,c5b7c93b,d0905bf1,2fea0e0c,bb9e9a7b,d5d99188,f42c8a16,a3ffae0e,92e3bde2,51c9a8c4,1a6d05ef,2fa2ed53,d7a21402,e759c102,65d96000) +,S(ec7c6892,644bcff,715b027b,be48936b,26dde18c,bb4a1a9c,fa1628ba,84d5b456,51bc2b69,b76646df,51644c28,8570bac5,d51a0e9d,6e9f0ce7,1abf6812,650b18bd) +,S(efb8249f,bed3299f,7715b3fa,b6a23bf2,86560ad3,72e31e6c,ec725522,227f5c2,f36f4624,59a7fced,3c621158,8eac73c5,54593c4e,b7c82fe7,b0951bfc,8987bba0) +,S(4efe94a4,c34083dd,49762ea,eaf58feb,72f6e283,9931b706,56427bc,e9913bd,5c8b9448,5c687c16,76605dc2,d414f37c,da98a562,c71e7e72,fb2b8d5e,6ae0d60d) +,S(ecc5864,fd6a1f7e,1e20a84c,d9dc7090,9775446e,2e0bf6cc,bf896bf7,97f9dd73,49eefb1,981d4b87,ff21ca80,5471770e,8e063541,58e9c1fd,9995718b,14d9d6f) +,S(133f3710,9bcf5655,48d03c90,b82d55de,cfae1cf8,a5f3e117,5eaee107,aa7eb121,1af96963,e9113d2c,588ab083,58df45cc,8b68312c,9aaed504,3f17fffa,b29bdd7f) +,S(a8b1b9f3,971667be,2a65072c,efe8b1e5,e64f652a,4758f51b,4888087d,4fb489b4,556d9a3e,c2861fdc,da258a1f,8c6e81d8,1df43669,e64e3daa,90dad4c7,c6c0b662) +,S(104889df,dd81534b,655921ae,5483db4b,b3227f2,fc3563fc,4af46e1e,2c4fa88c,a70984a0,ce97af36,b827aaa5,218a9743,73feb2e6,fd7e2a02,408590,47323ee1) +,S(4603c58f,4fbc4575,7e9e165f,8a4b41e6,b0d2bf09,b1124998,3881ecef,2a8852d7,37e5990d,7c50bed3,2b72a43a,2e6a0ac7,5676cc82,113e3196,d6569e21,3adcd0c) +,S(5d1ddb75,774d6419,9f07f578,21786ad5,9fd7119c,f895196f,deec090f,1240748e,519140b0,1b340a4,a7aa2864,fef5a066,feb59c6,3355c222,6805e45e,160bcd9d) +,S(c9f86104,62644b3a,ec4daa3e,bac656b9,de816cc3,a5aff1a3,633f90af,8401a97f,405087e8,80403629,516d485,f17590a,1277e058,840b3fac,4e02d3bd,7be92954) +,S(b774b1e9,9f42b296,dab0e371,6d4ee04f,8bd517e6,7846d0b3,3ef5e0f2,569e97ae,ec78bffc,d6cfa76e,513a2b4b,db638f73,519b570f,f423936,ec0a54f7,9ceb5f9) +,S(d7a1e238,ad3eddf5,29002e8e,87476ae3,6668d656,595b3d10,2486f1a5,c30e6a28,5c9fdd1b,e132b9eb,4d7b935c,2209e105,55cb28e6,c4616be5,7b248607,697ef6e2) +,S(832b146a,cd002cb8,199e800c,47b2a0cf,d96591e9,91f1b406,b2db981f,c0aff924,f64632de,b99254ce,9d60b026,76551e8c,e21b300c,86fa5bd,8bd7c32a,4a81a18c) +,S(635f97ae,1785487f,437fee89,9ec21d13,dd8228f2,e209637e,18c85ecd,6cf50202,b53fec65,1a1af1ab,2f51eaf8,8a3af104,e1a40e82,691da03d,9a179c6a,3b30e5f9) +,S(f882f983,99891dcb,d58b931d,c215ca05,a232aa9a,7cfe5acb,5226ebe4,f4a598de,3d0313cd,aa36668,5422a6e0,2dd7c560,11fef0ce,3c268a42,3509991a,97cb4562) +,S(5b16de8e,3f8b8670,a98099a5,250e3102,51107cd5,d04bb804,e2a7175f,48183594,33c3d3f9,e3099917,e707a429,3c83205,4a26cf2b,2a9e3118,fa64f441,e7561fcb) +,S(b47e085e,c7a7977c,be3e2329,ea417e98,e86eea9b,aa23fc93,67cc06db,cf06647,cf6f1cc3,f564879a,f9515604,4b7b856b,827335af,5cdcd55d,1f8bde5b,d3f539e5) +,S(afd1a856,e0624d6c,16a876c1,2f78ba44,303460f4,d3cc793b,5dd32a98,d8aca9b7,3b334e53,83301f24,df0e2df6,12cbd7fe,3e1b6650,d5355bb6,c9d3873d,f42d73b8) +,S(454316e,69f558ff,6e19057c,9c754b2b,83eab233,f696ccd1,b80bbb42,3c81ae57,ebbbce3d,4e1cf2a7,315a394d,d03bfb64,300ac0f5,11627d06,7a5341b,43a4ace9) +,S(a51f1d61,dc60b34c,65345205,b2a316ec,766560b9,c50d72a2,330f828a,ec978d05,d4e9b10a,58bfcc59,ef24379f,532784a7,ccc4c077,8aa11bd8,bf008846,44175faf) +,S(771329ba,3ae1f814,764fb9c9,ebe68f37,26b8260a,90d4e49a,7dfbfd30,80cc6128,128479e4,bbcd5b06,ddf46f49,614f6ae1,bb8914a0,7a0a5bc7,34b69b39,caf71b1d) +,S(aaa59016,d18bc9e6,2716bdb8,6d0c6bcc,e04f74f1,98f17675,c021d078,166c9fee,36cd35fd,53be5c17,84dec1ce,80ab3ff4,95abf363,17824a12,71cef620,2784f91) +,S(be187d0,b3afc0,bcbf98ec,bf31bfcb,f4121265,c4b815d6,9403d9ef,926cd254,a3aa0d55,8b5f6720,9d8a6514,fe22026e,66e8d972,912a6503,5faaecf0,ac2d9b25) +,S(228afb7,a9564fd3,641bd417,20a0e44c,d2ab5d99,844fa61e,264ca823,e197da88,24457982,391e3209,88cc44fe,e42cd242,80fe1f64,b87814b9,bb485d2,ed0d7757) +,S(dd55db40,e3333379,7b8ae013,297b477e,bca2f586,16f29300,6625aab4,6c367ee9,836a69d6,603fd34f,92d3f775,d25ce89d,b92d2803,48a21178,44f9273f,1a97a9e9) +,S(f82dfaf2,5113d8d5,728c53de,3b43f2b9,d2aac0f2,f90b762f,390f745d,7e10093a,1097ff80,ef2f5dc,88873c1,2b5acf0c,a8a803cb,ba3624d,4a036649,ffa07bcb) +,S(666f1006,57ebb1b,f05f50c1,2bfa7fe7,cdf11e0d,6cb37c99,4b39df89,acefc7e1,3e3ceb4b,eb292e5,3c00e4bf,ab6dd9d3,becfab1f,19880c3e,cbb93a4c,415f67a7) +,S(9769b542,3b098d8c,18871a53,8403ba2c,d32f556a,7ca7b089,ceb9134a,5d983e73,536e7c80,5c71c49,9d9acbed,c6fd94a8,3e64a2c,8afd8721,12f6848d,60851084) +,S(26081d34,3771ce6e,39ba59dd,2c2e15c2,4c6903eb,b6c157fd,b1c51dc4,e5343bf,82f6d675,39d04825,4cda5bea,e4879547,9570f86c,9ccbe1a2,ee0deb39,afcf5efb) +,S(feef7b4a,dbb0e287,a0762b14,445a8fae,b860e08b,19600b41,45d92447,be732bde,44e79fff,55aed478,f8d951e7,f4a327f6,c4a1e282,ce617a3b,5128f528,33851e5) +,S(ffb8488d,f26d306b,70b5b1be,4b6f2e4e,b6d6b2b,4cf05d3e,9502f3f9,81406cef,f2891496,f5affbf0,bc60c46e,b96baf7,2a4e6797,3297a28a,948adb92,1cfd5dcb) +,S(fd1ec3c1,736f2edc,5c080981,fdd99fca,9e301851,cbe8d840,38f03a6,59f21ea2,86755e0c,7b01dbff,ed701a7e,b5deb21,3566f331,d707888f,4f658879,cfbf3bf0) +,S(addbda08,d536486c,b9d0b4f1,5ffc9104,ff75be96,739d4641,a405e2c4,2775fa4d,4d70179e,1237e2d4,61a0a0b3,c3bf9df7,9483afcc,1b8fe02f,47d4b312,2f339089) +,S(fb5e9c09,8ff0520d,b162e57c,19b80ced,7c63ea68,1c7a2c56,2557a1ea,d2d7a46b,c4d9cfa0,d31cfac0,78c187dd,2ccea738,4667776f,b8eb0935,9330fab4,b9f67e2c) +,S(28c33364,1762626a,c9e4d2d0,53a1e5f0,771449e7,a0977f2c,63db4681,1c675b45,239e717,a76b80f6,2b11c6f2,c459d516,bf81dbb1,4dabba88,9f1e627b,5fcb525f) +,S(68e783ee,84fea44c,59c46bbb,170d7751,c47fb05b,602e9995,2469def7,cd061c9b,7054cae8,31dcb37f,ae8d8298,859b4e56,772f8a6c,d079918d,b49c7bbe,cde61f16) +,S(1526613f,fda17eea,1a7930da,c1be4a6a,4ddffaa5,1adf3c92,73f3a2da,44d69c46,c9c3d04c,996c4d40,b906bbcf,5b0ac89,f541ae4,81b7c5c1,8f9b5762,7b9796af) +,S(263e6099,2adc9f24,1cd1c16c,de291760,babe6e41,d4e3d064,f1a8768b,94bc5439,3ba3eade,1c5b8225,7559c0d7,97c47e5c,41f60195,463b2eac,74801439,b3a6663) +,S(ce58e7e0,73c871b2,673e18e3,c9ebbb8e,e6bbb2d6,226e3d0f,4bbe6bb6,73e72816,85ba41f4,13158058,fe8d068d,df70f97c,acd4f512,cdcded1d,ff9c3c39,eb1ce1f3) +,S(47c3eb29,1402d2d5,25a95ee6,fc54d1f9,721f29c1,e5b51cb9,d82d234b,94de6594,beb5da30,3383e0d1,4d13eca0,8eb8af0,14f8220a,81b1e8f6,47c1f95c,4503380e) +,S(8f5e8092,c71ce97e,af578fa,52f174d,ad0133f3,94bf2ca,ef5c7adb,bbb37ad,1ca41380,ac714a5d,3c6be070,117b10b2,dcff62d1,bef220e2,4063c971,89f6ffa5) +,S(edefd606,5883e90c,31215558,b05f297c,45c64fcd,34cb864e,3f0265e5,7e7d5a4,924502b3,1d0e8df2,2a54ae07,edf1b0bb,f2ad1df4,7de805a,43ae11ae,8cf3d628) +,S(31516a47,50773473,6e691ec4,e6891eef,601d6e42,d7f4ea4a,1e5008cb,b77e151e,7f243d73,6ec9d71c,d2047cd8,d97c159d,345003d8,72556e94,4f7aaa74,acb8562e) +,S(9049e0ee,149d379b,77963972,1027627f,5cf68f7a,9b1c81fd,189ae6dd,eea5c552,ecd60031,71dd9199,77ef92b4,262388a0,7aec9cbe,65d80882,1847a5b8,c758ad26) +,S(977ac11,98214ec6,eb92699c,aaa9c219,6246df82,85a6afd2,fbef31,a5a93b8c,27e01787,d6e29c74,f6308e21,24f9fa99,6a5b78b5,4f45fc95,b71430a,abfb964c) +,S(bd7ead55,e8ebc96e,5429f59,52427ca3,8dad3d9d,649676c5,52a01099,3c359a26,9e596b26,8c90186f,8cf38e1b,f47d6d6a,d7204c78,b557b3bd,25125bdd,c3ef7824) +,S(90c82d89,9178857e,e2563cdf,d822b872,2901b53d,3b93a6f9,2905a4a2,163be70d,3779d0d,c99fc814,8b2f58c9,fab70952,373365d6,1adb6e5d,9ac3f761,9f27e943) +,S(a312a0c,3111faf7,2cea8b7c,3e2786a1,65362caf,11919687,3368c77f,117ac42f,1b78c42e,af0e6219,ccbe3ed2,384f5529,dff57894,b9c82566,255fc4d0,fc798b6a) +,S(7cd723db,c046d3f4,5b0fa248,1197790f,688632b4,5f57569e,2f7754c0,9fc9bcca,eb5fb704,a5cc0b22,979bd64a,790f428,b57bcc79,3bde8fc4,4d6bc9b1,8c21e495) +,S(2b24dc16,59324483,3851815c,1675d051,60713a5,7dff00f8,9e72df7b,d1c7352a,ab05061c,224fb577,a72f5d2a,38a9e59d,18c52645,9564afca,a9539d0,c64c8fc6) +,S(955ffe05,c4653033,c2b4afa1,fcf8d3f1,3b55c9ba,80d67c37,598f6d87,97f11b1f,d3502a31,bb37b950,93b3e594,944d4bac,3314d490,d375e118,4e8c5a7f,2346e6a5) +,S(699392f3,c2baba31,1bfa8aea,180283c1,9036ea92,f287fc08,adb32fa,6785fefa,242acb3f,fcbce5f5,9dba097f,3d358862,11232403,2730700d,724488e,8bee3478) +,S(193d04f3,61eeec14,633c702a,f8e7eb22,2c3de17c,a0130e9b,cbfb3daa,94674d24,39b68a32,79e62533,8bfda780,9f0f8264,ed2ba2b5,ea9c0035,6459882a,a943e088) +,S(564387e1,ed778e70,baf9f876,2a0171a2,6a4e660a,bc6eaf1c,7ef9f00,69794817,7cf553f9,128d0716,e3c81039,3d1ca83f,1cf0fd82,7f7d4ff0,ff538637,34ef42cf) +,S(f0eba12f,b282171f,d20aef8e,192741e5,4469c5c7,bab13f51,7084d293,c3c294cf,bb0211fd,18229247,5238ba93,f6992d34,a41a7ae6,78750b04,fd34f3cf,af61f90e) +,S(a54b91bd,b09d29ab,f4cb354d,283c436f,a8e9cb20,d3a7fd35,e59f59c4,200bc13f,bae1af42,3459a852,bc16d45c,cd35fd94,c0033d89,5c86fdfc,f4fad5e6,3bec2cd2) +,S(a9294788,b2c9d997,18193553,403350af,78008113,ed58cbcf,a2816c80,46f75d47,dea8059,c24c1c84,44a0263b,2896725b,79c2c8a2,6d425479,f44bb7ad,225bed8f) +,S(b6967b59,ea3d2899,c14fd2,cdd4590e,68dce683,de275313,ec94d5d6,1bee65d1,67eb4a27,8813f69f,e5bbc586,15dcab17,11bca30,77327665,2fc333d0,52fd2a0c) +,S(ffc0f3fd,241ebede,ddb0c43a,a9b8fc2a,9e778963,1af8d54b,bf99c64,add0cd7f,203e3aec,321e40fd,414c002c,e5c6cf90,2f3e75d8,ae0e3604,61028ca1,e21da260) +,S(d8f86220,c390bcfc,f714ec3,8b6f6ee3,d37b41da,4026805d,6fbbc798,8a936ab2,7c0ad863,31ab776f,c22b2539,fd65086,2cfd2ba6,2f5d67a1,6eb957b1,8d812bf7) +,S(11295381,19a146b,442c3447,400b6e7e,9b2190ba,dd42a75e,24460ca6,45a3cb88,44950501,75662a98,793416c5,3c55febc,7babcd29,398d6099,23e1c3e1,92dac1ab) +,S(d7cf3779,236c4a8f,d592525,d30dc0a9,a3318c05,1823e0b0,43a6542d,f38d92d4,1f866df2,429a3dcf,1a285265,18308c25,262c1ea7,2aa2267c,39a315c6,dcd22ac) +,S(d2bb0f89,a0897404,25fc85ce,4d8fe24c,ca061808,e426b08f,ff49a525,137449b0,fc4c4bfa,2bf202e,4d10969a,2c4ca383,17a8c179,20dcb965,7de7aaa9,6b97ff33) +,S(832d95a0,cfb91494,5b43d9a0,4f037266,2ad4453d,353f6e78,47d4aefc,449dabc2,6ec0aabd,3c3981b,8ff55747,63bfb800,453f302a,8161de79,b6b623d9,253124f0) +,S(3a224983,f83c41d,33d3aa2a,c9d29ca9,55850388,a968407,664b2830,3967f25c,7cc31841,96c4fb8a,953602ec,3c79ac75,69e1fd1,7a263946,27826a88,7d651f79) +,S(81197d87,1452332c,2fb18793,c0ebeca,3d1b8a4c,f161b709,e3da21f,3917917b,56a0980d,1ed1f77,3c960de3,1ce4aad3,90a5ea76,fc410a2b,107ed82d,b8bdbef9) +,S(b8204012,c77ebdcf,790f48fc,4acb23f0,b03e5d40,6fdcf212,81545200,faa2b4b6,b8718e0,12ed5a02,16485561,8a5fb6c4,ee4db08e,dc9c1842,881287c7,dc7191b3) +,S(766d82f3,b602c418,d020596a,58e61400,20f58fd1,52448443,2f816dc4,8d437750,d17969a3,c71ea79a,3854b526,efd56f8,148b2d79,3ea3c76e,eb14ab7e,de5841d4) +,S(35fe7655,5d4c88c,dacad9ac,1bf125d9,924276c7,8c2ea9c6,a9c1ae87,52d1e323,9ce2d43,ef8fdb37,82a38d69,972229df,9b9c0c98,abad263,1df192f7,e0e75324) +,S(a29581d2,55efc206,4d1d1839,621daef2,ab049724,167ced73,7566f4cc,3a81f5ad,7eced1c0,575b6152,38db2928,964f7713,f65edd4d,c31a4b34,ae20b6a2,babaa8b1) +,S(d7787fd3,75473801,2370e71f,4d2575a5,b9f89e11,aee370ca,2660dff9,dc6a807e,2875ab09,bb1b2a7e,cc6cb39a,939e4a91,2ddb1dbd,5ca43ca7,93ac663,552ae91c) +,S(1fb6cf61,e8be4d39,b36578cd,8853da6a,1e62cc7f,29426838,a7ecf0a2,77395288,1c018114,2dfbefaa,6bfc2957,6b79c91b,16cf03d3,81285e2e,b74f71db,1986e43f) +,S(511e9c97,866e651b,c4e32e41,92f75019,42316ead,6a0cd78d,fa61e0f1,e76aab8a,2e8cd531,d55bb19e,886b86cf,f7105591,68a9507c,7d78d34b,9ec50f92,5485931f) +,S(74afe7a5,6387bd58,d5996a9a,9650730,44141ca3,1f5236e9,da977289,73c9d434,be7311c2,b4566819,12d13546,8ac1e26f,6113b960,3039c24c,5e77edcf,de452567) +,S(5b545191,25d5f8e,cfbae2ed,bb724782,d07ff380,10eca9a9,29ccc9c1,ecd0f04d,21126f87,a0cf1824,1040d707,4d37e8a3,f035471,63de669b,9f502fd8,92322dfb) +,S(5286fb50,1a525e82,a944d1ba,eab49572,52d86693,19af1367,eaa8d5c3,e73ee8d9,f2abec43,68f3800b,30da81de,5b81e564,f94942a4,9409bcb,a9faffd2,51daa0ec) +,S(7b01eb86,c102438,4be1f023,90a5ed7d,beea652d,cf3ef77f,92fd883c,f2993069,becae52a,915d1393,15435d9d,edb72e2f,fb9bda33,4b2e39ed,6e698344,9e1ef819) +,S(3955e911,874fd6d6,74e04ed1,ea3b43a4,486a0ac4,19735114,3b451c3b,3028a674,3552c619,a845adea,64951c82,75994959,8609a3d,2f691d0d,5947b474,4636e06c) +,S(b67801c6,d96aca89,22d8e7a9,96e95729,c4c29d63,180e4f73,dcf013f1,98eb0d29,876e3361,d82f58f3,f1292315,1509ed62,2e2a73af,d063466d,4af5cf1c,1ffbb150) +,S(1efe4004,1c7ddbba,1aade160,cec007e9,8abfcba4,7d292839,4598b5c0,1b763b10,d9f00f5e,d0868390,230168e7,c5839be7,cef8ebe0,b3b70d73,ebd92931,678dadac) +,S(2083d5be,389e4bd0,23f7685f,2ad00b23,e3687672,72183afb,d5d02384,36d122fb,11b6176c,c7554617,935304d0,4e12e8a7,4bacc20d,d438bf77,a1729a15,b424937e) +,S(8a9420d3,93ff0ba0,25bcbb4f,eaaf715e,4ab14281,85b2dd91,f8eede56,f3006e46,f48edd10,dff93031,2b5df63d,ec9c7a2f,ca373d77,65033de3,8a54d37b,2ab1f4c8) +,S(64a2e8bf,b42de0b4,b2dc8fd5,9e3b2c18,753b43dc,e914fbc1,478818f8,145891c5,82583660,40ebc62f,d5526ecb,9f952091,47f7048a,4004a0a4,7b08905,12ac098) +,S(eb97193,28c44e0a,3f2568bc,b99815a7,c5c2e7b7,90e7fcb5,a2e7f7d9,920404f,cfd26c16,e6709873,1219fdc4,aa8ed998,c6fef955,78d7908c,c72c04a4,4bcf305) +,S(cea3219c,e03a2433,f9ad8d93,73a6bef6,c1f30b3f,fa79d7cc,6ced36be,9abc9c03,13ea8ed6,a0dd8fa3,29bd7563,a34f3499,6442b03a,f2eb703b,d8d5228c,cc4c4e7f) +,S(2e1675b4,f00a0843,89b0587b,f0cb723e,1a833539,c024caed,36101cb2,bc4c4774,ec1d76d2,2752a662,5dafb3c9,6235eb94,f9af1286,2b3eff6d,2a0fb965,ad3173c7) +,S(b0eb3277,7c8d1b09,e22c9b9f,1c37e8ab,74be3c49,7ab6d73e,7fb6ec11,10602438,6d44054e,a4cb4a22,3811bbf6,6d2ab2dc,f7263d7d,6421a368,9a9ca4f,97fac66) +,S(48254bd4,8df24e2a,759c5ef9,cee30855,1c1f79da,b0a32695,2196ea1f,987b6d70,9c12a458,f39f4880,ff04b96c,72b8877f,b4ad0020,495626f4,1d9b32a8,84f7a36) +,S(e3c6dc6,cfd0b94a,57b3d34b,3a77f4f4,45328a12,764e4619,efef75f9,f49fe8e9,5c229420,500f2fa2,888d834f,a517188a,207d8f88,c98b7b7d,31484a49,c4d43a31) +,S(a8d9d9cd,def3362c,b260ad0f,3de51aa5,db066c74,4166d9ac,57db782f,656be9e4,bc696df,80eaccdd,bccc9ac8,960325bf,1a0e9aa6,100908b3,cd0c0ce3,43205db2) +,S(38281034,a34cd153,34b6fdc3,26fdc558,555147cb,534a1c31,89beec74,5a2eca97,f4371a13,a65de538,f31ecc5b,50ce4b92,d5dc5645,9e523851,f6fcdac6,5994b5e0) +,S(b745114b,449f0d7a,4521d7e6,728c89ff,54131e6d,8add9f3b,bf18edff,bebc6ca1,18678d66,781a9120,ba33e01c,ee3fb1ac,b7790f18,b30a651a,99b913c,e621eb67) +,S(5987629f,9c26a8cf,ff39955c,3144f4ab,c4d094c8,8270f3de,620fcdaf,93a7fa9,a554b7be,24e49819,f1256c9e,72b8d981,2aa5984a,c942bd81,5709ee03,67894a07) +,S(8fc9dd0,d84cf297,75ece75e,8cfd7c38,dc9f602a,b0152b01,982be4a1,f29b7290,ed128f96,2cf60503,7acdf6d5,9578ca8,9a232a0c,c432364f,2b661ac9,2a3176b5) +,S(c8b5b1af,90d64379,f2c02ac9,51ff715b,2978ef0,bc87f721,3edfd09,983ecc35,c295c0d4,964ef85a,59490ae,dbfd98bb,f6096217,d7633f0,44470b6c,a1816b55) +,S(b4eabf60,c44d78fc,298b2c90,6cdcf7da,a23d095d,867fd304,513f90c5,437775c5,82d906a1,2d10d6d8,e4c843b5,48ab645b,e6f32104,f07d8fd8,c128351b,e7b526bd) +,S(b19350e8,a5163076,bba0b2e7,2159865f,59a8ea83,b0154fb7,64308bc7,4d0bcfa5,29e4ca7a,554269c3,21a12b37,a4fd0fb2,d3e57ed5,4e79423d,f715bd2,ecda9907) +,S(fecf1ff7,663c7921,40f4deac,ced92484,8c66bec6,f4a5550d,c340896c,5543b886,b2621f65,d52538e2,92a50808,9008efa0,8f530fd9,a321bf30,6dd24f26,c9a1208d) +,S(ab70fe2,355d6d6b,5c5a3f5,a6bdb605,86372165,b8f07d2b,ccfd61f4,798dcb7,7adfb6d3,dd44adff,87ce3727,efef0bc,6fdf9f49,44fbd238,822974d6,dd57e8ea) +,S(5ae5d60a,efd1dae2,43df9d7e,ca025c3f,452b6c62,216c1c1e,8b315ceb,b94769b,d90d73b9,6e33cbe3,6d96c45,656f098b,e7e57d25,dd03be95,8b9cb2a1,d00bb434) +,S(fc51f965,bf8dbdde,b5fa4af8,7abee8a9,a380918d,4d8524e6,73f8501a,291eb96b,ceebbb7e,35eda612,47ad8c8a,5d54af8c,9dbc9bd1,194ba5a9,5844fae4,b658496f) +,S(368b51e3,778f8ddc,2d09e9b7,fc2808c8,ac793edd,244fe177,fe3229a,e5a6d919,5b3ff9e5,af4c6ae0,575b553c,c0ce17cf,fc4da66e,e19fc3f6,2d047007,e1716db) +,S(ac9c4efa,5f63ca07,35fafa0e,9612b459,1a764955,d435c14f,91717e42,26ec0186,5d4d3ebf,9a064670,e09f1d48,79bc9e3e,22198188,5610731,29aa403e,73d7777a) +,S(2b5f951f,360dbecb,9eb1d31d,b414aa13,9d9a7d7c,ed952a72,c0f93a61,d52fbc08,8d46f1b9,cb8883e4,cb504715,eae4326f,11187e46,de477dec,2108ccbc,2b3ddd35) +,S(25a3593f,9670924a,a35c2008,bd8278a9,a78d22d6,572841c,98c4399e,26f67cfa,3b07ab0b,8d400f1,af88561d,af8bb7c6,a6e4b7c6,a8bf5915,4cd85291,66ecd965) +,S(3f03be51,b35e265d,d9cb974c,4ac021d9,d22b2291,40016bb4,e9edf52,36193eca,a17df05d,e4b0e5bf,c7ecac3e,e3253017,cc1d47b2,9fd3d1d5,411f2660,c34932f9) +,S(edbe9bd6,f16782a5,a00d7003,488b9291,faa4f22c,9602c736,a3698587,995d25d,64569751,212d2f6e,c2e7a6a8,973be7fb,c49d7a0c,8857fe76,f9c48011,735179ed) +,S(1f477d33,1fb16ac7,45c29e48,77df8c17,83f69e85,5a111a30,e4717fc8,ebf85377,64c947cf,64a66ad,8a417bae,1bbc1cff,56826349,e024d3bc,bc4a9078,f4bda708) +,S(b8ef8b11,901602cc,9fd1559f,c4bd6bdb,22f9bb7d,8b289c6b,fdae85c3,e9aa3e9a,60b3594a,7349c920,33d816fb,295f41b2,7c4d1d86,b4c9d2e2,2cc3f4f,e603f582) +,S(eb6b31eb,198741f7,49e4b69f,85c23e4b,58e3223b,df8537cf,60a94411,f03e0071,576746c8,ba579896,969c228d,67a57cd8,8501e27c,773a3444,35b7e860,bec9f471) +,S(47193aec,aeae207,ad675228,f4506db8,40a316a2,6cdb328c,2af6c24b,bd5e9a8b,dc67bbbd,ca7cfeb5,981571f5,7022986a,4ec3e408,b641c34a,57b7cfd5,5139a1ad) +,S(ae3c9591,c2768a02,f99b0076,9c56fdf3,1a98fae,1eca3680,38698abb,1d44f961,ba9b0c42,90c2fb0a,ad84754b,e1c3fa0d,7e34f737,f3874af0,4ed2824a,46efdb24) +,S(178ef542,8c4cc38f,f088c383,71f0ead1,4e7b4423,6d90bc7e,9ffc3db2,fdbe9b9d,a5f01afd,74aa9324,b10f6041,27ccae19,24da7b23,72269ef,ab984fe6,ba1b347b) +,S(2df7e5c1,3d0fdda3,3ef8f69b,f0ebe1d0,8649b106,8c965d97,37a7e9b3,c13f4c92,eddbf5c6,324853c3,7d478864,a68d0b40,2c28ac46,295c00c2,2359e10d,d0693d94) +,S(671abd13,fe274da6,a5cb6119,f33fc88e,37ee1b75,59adf215,e08fcead,ee946b8,49d7cd3f,3b8162f4,a85787c6,91bc29fd,69eaccb7,1354bbc2,8ba17227,8a8689fc) +,S(b69fbdbe,e72b1418,6fab59f0,6b57d940,fb8cb5cd,92c53727,a0eed42e,532ed39e,71f488d2,e104d21f,c816631e,d774a714,94c0c609,c86ee052,210113d,672ea302) +,S(1d5b8e6a,25fcc50e,a4a5429b,6233e276,47d978d1,28a5f495,a66b1b12,d7cd8714,8428efab,d2bd23c3,2de8da3b,cb630ee7,ebe84541,ec3eff60,645ec4fa,3978a6) +,S(4844a10e,ffce265b,1a5338e6,a10c4f18,b95b0681,bd702e30,9a376e23,7fcefa22,9018e1d0,34bf225,b4826e42,565a76d9,43c868c3,168d74b9,33b34596,98b5192b) +,S(9567ea6e,231a9c9c,3ea5bd83,59b7340c,dff96e3f,d1fa7a5b,c56c88a1,a57d951c,507e21e0,cc59bab1,f2c38cb3,42b9f83b,f291992,a0c83edb,4cb62b49,6c54759b) +,S(60f2f714,71258f56,6de74774,eda196e,46a30d66,3dc0b308,1cbad662,72f07bcc,12588be3,f62dd2c8,1e485efc,76c754d2,de642f53,d3937c68,f058c61b,ed7b6c22) +,S(4276ad32,b33ba53,ef2ab0af,9fc42af6,6c7bb23d,c7b7a9df,9c00e1dd,f76b6283,9c477729,c61fccfc,a2dc0c3,c3a9ac89,b98f437f,bb221be1,268a6f17,5d0dcd9b) +,S(fa3ec157,f8186c36,3419d818,4473745b,fdd2d054,e0c16e1e,fccd514e,95c9336,a7864a68,91aec12c,fe8104a0,eb3cbec4,4a907380,11a3acbb,d5fb6680,289cfa2a) +,S(7d7d2728,b1db5fdc,38ad6a75,3f39df22,88d50838,b106475e,28ba6eb7,5248b600,25d9d454,8b505739,16ec7bcc,877f6aef,e2641eee,8f78f1b1,a7f74c11,40173e1c) +,S(8cb9cc7e,4ec87013,b6994670,aae06b1a,a4785c06,614ca24d,cb6534,6592ffb9,728c4a8b,36bf36b2,a0bedad9,144c3261,71df8448,e87d151b,d8bee067,769113c1) +,S(8a9aadfc,84aa81d4,46442635,d47a9a4e,988e64de,6fe8836,79b8de44,f57c0169,60f39bce,be18abd,10afefa0,2d076d49,73d9615,10017a1f,469eab8a,c15eab60) +,S(3ea01e46,3a9bfcfa,39125216,7b6ce771,5fb309e4,37d495b7,852be3c1,af2a0b5f,2b756a06,75da2633,b8d2650a,a2102738,d5918420,9c57dd64,7b4c6c2c,c5250252) +,S(a0683395,c5245bdc,24b2b275,e8c2a196,5068fda,253343f7,49ab56e8,93672c4c,7f25a7ca,92d25547,975ddfab,fe50c247,6b4855cb,8f9ec4b8,ecbe9271,779431ea) +,S(b8293e68,1e33b654,7d2902ce,3addaeed,2fcc021a,cf7ee396,9be12661,b2abfb5e,7943e6b6,fd0c90fa,824b1e8d,25d63a1b,c01f16fd,3c9e2254,e1dc35fe,416a5afb) +,S(412722e8,ba1809cf,2df25d5a,49c7648d,b19e42c7,3cc30b7e,1107ee4b,f0aabaa1,557a299c,38ef6a75,61d79a10,ea052a52,818ce67e,1b341c1a,d70b984e,8e41fa39) +,S(7a62c6fa,f4a1f6fe,4a45aa48,a854a16d,a2fb19a1,a5647e3e,28a35d0f,619b2844,dab31641,6241ad42,3e7ee774,acb52a96,26b4b6ca,a4ea0b4a,67a513fd,9637dfd4) +,S(c3915b0c,19df99,ac0ef05,3a07b36d,62643630,201073b2,8e3ec588,6714a695,8f21f136,3cb4ff42,a52f74b4,b10f1dc3,5bcd782d,b477ecf6,38866d79,541de3bf) +,S(2a373fd3,ddd12547,3e30efe2,5533316f,355dd52a,6854d7f4,8144d19b,648f4b59,2ba90aa0,b3de3887,c1ba231f,49b28294,677adcb3,2e81c2f0,3c563e0d,221260a3) +,S(d8729e12,46cc8a52,a5c9b7ee,dcdf4d3b,3d0ff8aa,6efafdc5,ddf37480,2dda4476,1966d7a8,7e527a7a,bc1e829f,90e4e3e8,f4a7df30,48f098c0,df8a5eb0,2a8bc40) +,S(ce45fb7d,2ccb83af,dd1662e0,3ffec83b,5173dd2e,448eaa87,edc980f9,10a20dfa,5973238,531c5a84,1388c656,3d4f3579,41283e31,44d84ea3,31374d8d,e2122244) +,S(230a69,f0fff585,a1163702,4b16481f,65bf27a5,3ad7992d,47ec8ff5,edfe073e,61ae3fbd,90f157ba,6332de25,a571777c,30d8144b,e12d9a25,42bc1877,1b6abedd) +,S(d7f91496,1bdd4fe4,7b538429,df2bee94,cc4d66d9,270da392,a85e8c62,1527700b,67ee9184,bb2cb2b,9671aaec,57634814,b6a1a9f5,dd0430e6,6c5e2774,5afa9f13) +,S(4f2e459b,3eac7349,41cb81d9,2d8b3942,ee7b0ded,b2d9d8c1,90ff390c,aff7e4c3,4188f6be,c3526afa,2b29f953,f5044bf3,8e583c27,395c9f8c,979ff539,b4198e17) +,S(8a4a7b6c,3b598e42,851b0913,209a95fd,edf0f8be,6f152b33,1dac61a2,6f9b6997,53c457a9,f8926415,63e85b0c,b39ac9ee,69b31c65,5e3bc200,d37d86ae,d4291997) +,S(a48f69c2,9dbbc922,78a5f8b4,4a2fa2be,f432a4d1,e6fcfda3,8ad60dbe,6d157990,f251873,152f4ec8,fe5fc88b,cdf28ae,acef895b,1d0f0ce4,44105e14,7ac0ff22) +,S(fc0ec54e,20f7e8b1,fed5cc89,d18a5004,b7aa55ba,7520dc18,c9cbd935,7c78eb4c,17374d8d,36116ef6,49b723af,62a48350,4bd47bd4,c17c7990,fb0e119b,47f21ba8) +,S(8203924d,9fc7e5d7,6e3c593,ad439d3f,8512c0fe,5c298163,c8caaa3d,f7b39755,a224b743,258a82ac,2dec871a,dca1dafc,2bfa8e33,b2217785,2b97e57,2e1344f7) +,S(c4f66a17,a595217d,58d5b5b5,da997a7c,79b870c0,f5fa9dde,e146fa5d,c21f9380,13bc8ef7,ce6f915e,fd7a3522,f5fb9c3b,ac603d0e,343d344c,74565eb9,e8e3c777) +,S(4341f0a1,efdd7d68,435f1998,559e43b7,7d1c6780,d3d3e7e6,212efd96,5b30cb47,1777a450,1a693970,c2bf759b,a253e716,b17cd5eb,9a247d47,cc382424,48ae90a1) +,S(865d8a50,ad3b8c21,f8ff0e92,8e853789,a607abe6,e155b04b,3b81d80,c97c29d4,2a506b83,c4166a1e,fdc32c2f,b2d027e4,837d9989,a82d08ee,a31a46c9,dc72b272) +,S(d8d95cfa,ac50b79f,3189093d,50b03b38,3b798532,3f01ba52,d76f033c,83c832e2,cddf6560,d9942228,5a3c0f18,58a7c27d,fd7b8bac,9b23477d,8677a1a3,c01a8454) +,S(d09fa59,8ae65883,60247b05,519aef86,2b1c5196,d38aed11,e8350fe0,5bfd6cd0,45f51a97,67445680,37b1bde9,86696834,6dfaca49,719c5174,a9f9eea2,92ed4ab8) +,S(e19796c9,c9b48a5e,59556b72,9d9b8073,71cd7267,812b044d,637aae50,d6d3d1d3,1b86acc0,d904a31a,b5637e18,872eb31d,32617930,2f3d6bb9,36016653,9f218d89) +,S(6a88899f,be0c3c82,96fd27f8,6f89283a,f83df13c,a273217c,fef69d8,b048afb8,68ba38cc,bee044a7,a026ada9,d51e8d49,97083dfd,f65bd483,a45eb58d,5cc774b0) +,S(e5082ab6,a112848f,9f5f3362,8be3e267,87e24cbc,6d5563c0,7addeed7,ee44662,c3c1727c,d0c09130,8323326d,210a68d3,68bcbf81,bb3814f,dcfe6631,d42968da) +,S(795f456f,5d0cc15c,72ea286c,c881d8a0,21294e05,cf80ef7f,4497caea,92235487,bea99154,424f54d1,e91322cc,c52d3a51,4627fb1b,2fe9062d,91d90177,20530ccd) +,S(6e9e5f96,8c233f4d,8d2bcb8f,25d9232b,f2230e9e,fbafc89c,dca17498,8d7909ba,3f8b0b0f,e60aaf3a,89f5de79,35f9979a,ac3f3fc6,fb161d3f,29ab2ad5,d50411e2) +,S(72ef1e88,89cb7f22,19b4a7ac,92d5678e,a04c898c,5b83128a,1f7fa8a1,63772f28,dffb88e5,3f348c29,411e4d47,3ccd7d41,8a0617a2,6a640a9c,4b03aa08,15ab10d3) +,S(4a91fcd4,32f6d2e7,ad20787d,749524b2,e3e1c348,31b41041,c311421c,1aff04f1,bcd9108e,6e8c6da6,a15156c5,5c9d60be,e4aecad3,b0756cd5,81b1eaf0,ad300b9f) +,S(5f5255d9,8c7465d6,63fb4507,ac985629,8a434d5d,429d5a9,7b645256,e2cebab2,7c38536c,31e7331a,362fc944,38510aed,bad4cf29,bf0e7cab,c995ac6c,1fec04ec) +,S(866b5f8d,a735ab93,e84f7811,a33f1604,40a51373,7b52e675,7f212c8d,65c9eb05,af2cfb6f,9e32f412,5f1c66ac,61393756,b8c6016f,9d45a58b,43e16c6,d3549be5) +,S(636aca,387e767f,4702fb3a,d7b50b4c,4b40fb78,2c8c44b3,a298051d,bb3a71f1,70e580b,6993c9ac,5a48c2f7,558773c1,f5c4ff3f,aa929635,a2a44e97,c0eacae9) +,S(31a28d8c,2205f5c5,75ddd861,df94bfa,5b6b6e38,83797d1c,7d4a487,5fcf7f7,a790eae6,788407dc,89df860a,9ac25011,8b8c65f5,f47e0bae,6aae95ee,2d733698) +,S(c7f36e08,bcea178f,7acb0b92,fdb32411,a028ce88,be5e3480,a47c2c88,891827c8,5c285010,4742764e,7df86e80,e6e2d975,472abeb1,bd5664d3,a994289c,112a9e9d) +,S(85a82c69,2a5e248f,42a3f0d3,e092840c,de52e31f,19a2a161,85b2ad10,6afd92d3,eeec281e,55c79f17,332c4ce0,7ac4edc4,a3d75e67,558b4b3e,4dc86532,6132155c) +,S(e67482d2,4c2e3a75,3c1fa968,bf120a4b,7883d00,950bb0bd,ef5472e0,dfb09287,f9801b51,e0450fcb,9e405ebf,cb535355,24db5e9,91bf1572,6f446aad,34ae4194) +,S(c6ba17e7,81fad656,c9c93e54,36409414,c58e2761,b0297b8e,1811dd68,62779f1a,92583a9c,515a096e,8691b384,4104419d,c4e86966,4da70b3,afcfceb4,b9d74c92) +,S(67cf02c5,a616b59a,ddd421dd,15812e95,f36e6d16,af501663,9e60dd4,a8706b24,7856ad72,8a5f0d18,bf4bc3d3,75468f85,7bbdb1c1,206fcbc4,7ae66b5,6ac91b29) +,S(72bb64a0,aa8c690e,7bb6ed99,847488b9,f37490cb,a7fa120e,a7b5df10,8fce4b61,6057c37e,198f6428,3b9481f0,53441e97,dc827cde,edc55410,5108fdba,a14d81bb) +,S(1b132067,209e179a,5b77977b,eb81aea1,c480b32d,81729c5,32d100df,310575cb,67482a94,b5ddae4f,cfd613eb,68680dd6,c8172553,18478bf,79b5c07a,b0cd817b) +,S(96f5f126,4b68fd7e,f633330e,f32951c0,3716b62,7d1f3368,703447,f9dbb5a0,941fa02f,c6262bcf,dccb1cdd,1637c9cf,719077c8,1b26e7e7,2bb8fe4a,4d530e19) +,S(95335907,9c15cfa4,a674ce65,113127f7,a1ce740a,ecceef55,da5ceed8,e4e56a51,57ee067a,5f506b14,5c1c20ad,6e5d6b11,9bca103a,60c2e6e3,b5049b4d,db15baa) +,S(72ca7d41,76c687b2,1125c290,e737075a,3281ce7d,76b72725,c7680956,e0463f23,1e6a85aa,246b0f1b,324365fd,19809840,242fef0e,6d658cae,cc84bbc3,ad56af44) +,S(d5376a10,2cf819b3,a439feec,b04d9fa3,c90d76c3,b9bb749f,bcd6aa26,39ed5ea,3659d2df,266a0ff9,c2854f6e,f5a5ab04,1c0d8547,77fd4f75,320e064c,c4d0a4da) +,S(664a26cf,a965b59d,10c05dd6,e0aa4e6b,c66f356f,bb61b699,113a83d9,e0a2b4ff,fd191a92,c88d577e,47e725eb,a3c38b3b,9074bc42,16c5d6b,4edb3af7,2c4e20f9) +,S(7729abf,ecf9ca40,e8867936,7fef2d84,29bd877a,56f36780,1e677273,8e8cba7e,d5cb7517,42c9de11,84dcbfb7,5c9e139b,a59b6255,b59c7ef8,539de55e,7a709d36) +,S(c6d5f50f,e8e784db,630bc589,b4df5810,a2001482,9ca1608a,cd3e3634,7bd8141,eedd06e7,95d063ef,3d1627f0,bc7ef37d,a4846580,61e472b8,89679d3c,d88ab294) +,S(baa60dda,3cf83a11,82dc2ef4,f79d362e,6b32304f,896d30a5,b363c639,56ec70d9,cc9e6274,75feba44,b93451d2,753e94a2,85315277,7674b3fb,c67490e5,3627043b) +,S(370243c0,92b957c4,74df755f,e0951321,49dd3669,1a89fa84,e43a0668,8ca235ff,bbe8ff04,6600f245,349fbf3b,1c8ff04d,8d51185,3e35d13b,30deba91,84383ba2) +,S(1182291,92b1e768,2abe56b1,9f90e41a,c882edb2,27b25559,ce4448cb,dd19ff06,24271274,e6156ea9,e3f82ba2,8a72d476,8509dfad,b985c200,244687d5,8a11c1be) +,S(dd134e0,e4fe672,38716aa4,edba1ad7,6879be6,8b5bb029,b32704b7,9edfb2b6,7aed5398,40cd7dd4,7e94c224,151627a5,62f6a519,2f0d0b5c,416e6f1e,5e8a337f) +,S(ab7e722f,458d3acb,ad28a29,2f90cd8f,c2e09b2a,2beff3f8,f08517dc,e673e3a3,522a2227,c724f9bf,1ae08d93,c4c6ffc2,f5434173,7fbfa502,d6e49b1c,2ec4c792) +,S(2fa16842,ebebd6fa,e6c67327,bd5fdcdc,7e985b1c,22dfe307,23a9e2dc,ec43df8d,f027937c,9624aaf1,ccbf7c58,66bdd9d4,5bbb279,c2a37813,9166b720,32030773) +,S(adf5e014,e1f18c38,fd1863cf,76a6dcfe,65827107,fbe0eb99,117a859b,c5268bc5,c9cb3584,728b1771,16985b28,f5259aa5,279e15a8,1c1cc6b9,2b9e5f8a,6206961d) +,S(d939322b,a9b2cff2,6a2b1c4b,5ffcd96d,822dde66,ad0aca31,c24a8260,c9fc6d26,162fb654,6118a68d,7fb88bdb,3e3ab784,9278a5eb,13a940e3,3228580a,2258c8f5) +,S(18fb2621,71f79e5f,46c0087c,ac8e55d9,66f29a49,e2c91363,58900787,3d7e3a6d,cac82dd2,4a0f75ee,adfe906e,ccafd36c,5b0c97d9,cb150fcf,d08b28cb,83787a05) +,S(b8c0ac07,5d009e4b,5ee44298,89864cf6,fd54092,df835ec2,6658c902,57b670d3,2dbc6d4b,6ff28cc1,14e1f34d,2b6cbe52,7ca7dead,24f84681,4407c4e,a0df0bdb) +,S(6477536e,43a3ba01,8988c8ba,753d732f,9ec061a3,49f7826e,2c426ae5,3f2232bc,ede465d7,6b7798de,832e5f68,512cf3c4,d17282a5,ef88725b,36d8af1,5c5d2679) +,S(55b052a6,52008a83,41135e55,ef7de2b1,33eca8b9,ea0c4800,ce4f8019,5f7067db,a823cc05,63efbc19,d47c2c92,5771497a,ef6377a3,8be0d23c,81a56f06,25c43e56) +,S(c86a02fd,becc3647,16c58f5d,f3f150da,6ba86499,2df09dd5,82b9653f,10cc9289,263d1b5e,eff52a27,1a9c46ee,8adf1194,1da9d3bf,e69f62b7,262099af,43d6fe3a) +,S(23c659e0,3a59381b,3d47beea,60f0244f,66af0596,5f903297,c53aeeaa,d143e90a,1c14650e,3aa16bd5,b67e6077,be307cac,2bd2cd39,b246d6f7,216d73dd,dacbaf64) +,S(2f6d8482,734aff4e,21094c39,2c5fe833,1c8f9756,4de252c2,f6f690ad,8b2fa9d,8b143db3,7e14b40,3fa98a74,a81adc79,c34f17ce,5c9e6f21,68770957,1eb639ae) +,S(6d58e265,d6b08c0b,b050ee18,5175a9ed,51b5c64f,d523ab35,ed1457d2,f9caf153,d0675517,eb71ed0c,4fbb86c6,a2b4a7df,259a7795,3293777f,3a87f620,2265edee) +,S(4af09f2f,69d7b9,6676f472,d7f2009b,f0bb6f0,986f502f,322afacb,7e9d570f,1f93342b,ddfe5896,52e8b64f,a348f333,5396012d,3e870885,5b31024,f14f8e7f) +,S(813e446f,87d923ab,ad8b8649,71b1ca39,d00217f8,232a71cc,d6346798,3a9a0e9b,8ce9f4b3,541a8029,f1476728,2bedf1f4,367ff257,60f2ccce,7b273b2c,dccff418) +,S(53c4fd57,ca0b1eb8,7f5ca0f2,3ecae8eb,c44e9c19,aee3477a,3ca8524e,dcdefaf7,b3db3613,aa916430,a3227d73,35bd0532,74c122b8,18e4ac52,858e513f,c3ab95a4) +,S(e0f8afc2,ec89411,d926355,2c33af71,328331dc,9c9452fe,b0665c39,ae90121f,13523c16,1a00784b,f15d2867,15cc05ec,227248ff,80082e73,ecb139e8,f229eb4e) +,S(fe3efcee,6b82a5b5,a8c9a51d,ccc11f01,ef8f1a7e,588ec4b,17ba1369,cc6bb80b,be17246a,4d8660ca,98d57f07,ddbabc29,650f9a89,9da60a53,d21c6c96,dfdee15e) +,S(8a5182ea,591089a5,11ba9f19,ce4fe062,31b7e2ce,ec4cf75e,5c11094b,9ddc8de5,73688cc,f13d97eb,19a86c2d,8b010406,1c69ca94,fc9ec90d,8ada10ae,37503600) +,S(2d95aecf,72501ef8,e20bc117,22dbcc09,38c552f8,f4e0596c,9974d62b,a99fc884,7d9c418e,e1745ac9,e8f5e4c3,9ada4400,e65acb22,d336bcc9,fa2cdbe9,97f7de88) +,S(7908e4f6,ede4d311,3dfaf114,9bf6e40f,e1f8e33d,72094448,5105a113,21d18b80,11d92d74,9b011e83,5e06d7e6,1103cbe,bf958d8d,bd47d0b0,1ac2ad22,2f7d275) +,S(2c6dc24a,687d8437,44baf725,c75e7524,c0e6571,f32817f4,40183b6e,cbaa9f95,9692bdaa,775b832b,48584ccf,713421e7,5074f1b7,ed5477f1,4335db2,7abf03bc) +,S(a019d9a0,4a9780c9,43dd65fb,b87534cb,ab7c0831,f845e724,d663578,ec7bc090,38de35e6,faa2a1ae,e0649333,898a6ca9,264dcdd5,ad9f289d,ef750110,9bc99d4d) +,S(ced934dd,5c15335d,d050af1d,a8295d2e,bd9b8272,58d689ac,f4a48d85,5ef8a0d9,bc0c9237,1ee7fe7b,69c7c100,e5258c9f,1d68b6dc,309736e4,e05718dc,3a49cb6b) +,S(65e5ffe6,502ea7a1,47fe9c98,9cc745a3,b5262bd3,888069c3,92d1d1f0,a08dbb83,c80ee080,84dc5e65,de8df271,c1132cab,b8be293b,69a390a6,fb3932e8,51ffaf38) +,S(f4466d47,2365b665,6d1947b0,6e67e393,4c0e4f3b,91d52ea6,1f4588f2,4d217655,17afe3f7,2d384ccd,9beb59c3,d64353ba,57713f03,b8644e3c,eef45db,c74ae84e) +,S(66a80bd8,ec0d08ef,3d9aca5b,4329198c,b949ce84,7933ef2a,10baac28,dc98cea,7457685c,600a707d,5fd5d527,9f309b9d,5b14e668,1656869d,b041ba77,97029537) +,S(240e3632,7c3f4c63,afdb84d0,8586bf90,9b359c8d,7012f9ff,aec81986,4c44d597,a701b76c,d369e013,7b627216,f75d0ec9,fa208b66,2d7075bb,a6b6d39c,6a1cbb30) +,S(137f0df8,cafdb26d,36e1b57,c427ce08,444516da,ad1ca806,9dd60e2f,2ee23f92,c2922219,9e4e7bf2,f9159138,13e68273,6bb6a998,6c015caa,43cd30a5,aec74a49) +,S(965fef87,a63bedda,fd4b2e35,e1d0baf9,17d5850b,1f6beca4,64d4fae1,997d3a41,5f19603,369108a5,c599ce56,22bbf02b,cf541867,a57cff2d,8b527148,30124ed3) +,S(1e2ca98e,519c60e6,cf7ff3c9,51cde109,209188e0,6c68f4dc,c22eacf1,34a4125e,edaf4c8d,8bb97032,89f9fb0d,d0023783,fd35e779,41773a00,fb4289cd,ef8411bb) +,S(e8e0e2f0,378595db,68f96e6a,882752bf,df039778,e261375a,47fd4394,2b68006d,75b42822,1e2fbf9c,42772d35,e4bf1e0e,8d3b1ad7,92ff25ca,a488b51d,4ef7186f) +,S(a405f5b0,28e89d81,79e7fa9c,2ebac86c,ffd20ade,60dc5226,cfe6c91e,5c2f6634,c27ea4e3,b0da9e58,665f507,84225107,7893d6cf,5225d5d8,a06f68d1,1d863550) +,S(bcbc3c77,7367168e,169f3fcf,dd2340cf,9e6af955,d6038a0c,b763f036,6f4564cd,c7c120cf,99138201,40ec5339,ec23f5c,1ac0dd73,c9f947dc,e19c034f,7e7a502d) +,S(fd569bd5,14843a2d,e86ab2c0,475e0c67,4959c04f,bc230255,db3e82d1,15cb0758,aea9c73b,bc083366,fc5e31fc,90a1da72,66a9c43a,9d16f6ee,67bd56b7,9c354cc9) +,S(c2fdf561,eca2e3b8,f1107475,9cc43b9a,789ef592,e8afe885,d88b9dba,469c616b,678f57fa,fb2e42fb,bd1482d1,e22c866e,683e4fa7,6c1d2714,6540610d,9cbd1360) +,S(50f20965,510b3317,2836e1e2,d6e00ea6,160a9c71,2aa30bbf,ac527c62,9d8f4088,fd9852c6,974c603,7e88bf45,a279b565,d1246924,e3c4a0f4,8877b716,69b68141) +,S(3f293417,1e371e20,cbe0a858,e5984175,ba465906,fd64a7e6,161c8a7e,5847764c,763e8dbe,571ac3dc,1e803f32,7e2f4585,7268774f,1a45c50,9390dfd4,96bd374b) +,S(8276d399,fe32e931,65f2ef6a,2f4198e7,944bb9a3,226b1a55,fff52dce,d2b92b3d,e955a591,5c496a1,623466be,88c45a3,f545527b,4edd4283,582c03f7,2a2d897b) +,S(e77e7701,f4b405c3,5c8b7a6e,ee7d0637,fa1f566f,d2a2cb64,531dbcc6,19a9e474,23fae4c0,7661e588,365ddde2,63b97f2,cca2023b,c70633a1,41a2eb,1d3799cb) +,S(7ae8112a,732d6428,25aa2eef,10298300,42939628,69e7eea9,3fbc7b3d,2c5210a2,3590e349,f878af6,7f7754f9,abf4ffdc,4d4f4442,48c1e039,6071271f,be5971ce) +,S(f9fe96f6,8e20a422,5b563483,c1d2389a,ebd8a97,b1b9accb,ed7bc51,8077771e,cf3802de,20b5ae42,b1d1db65,b033f2e3,602ca08d,972eed63,9234e1c1,48542478) +,S(b9c5eb6d,ab28292e,49a76b34,49cf903c,dfe79b85,f7797623,924a4295,bf0cd171,adc0a5d8,18926d8d,7bdc83fc,72b2ed11,19b87592,900ae961,ffbb165c,4d5bced1) +,S(b7e25a76,3f3b8bd6,1c57da51,bd90ab57,1df3fcab,28003104,30c44fa5,4a6a5765,c471aa74,babc3fb7,dc80138c,83940e42,961f80a3,23e9741c,c44607a8,258141d) +,S(5808e4f3,e01937f0,e9c887ff,8ea3a34f,8fca4d8d,7868a9d5,7de6d854,a0582d71,fee8cfef,2d78896,55dc9560,68e1a23a,4308a8f7,7962c2e4,f90b2ddc,87f011bd) +,S(92ac7dd9,8da0a4e6,60964943,3887974c,5ec4b32f,875c02ba,1163d06c,b424793b,857b2046,8104a986,a0030596,62039e60,71c8f950,b7f7f746,16fcacbf,b8eee5fa) +,S(5c38092f,fba5798d,48d0068d,d1037563,1f40a693,194584fb,7199c409,b85d52b2,32b1d628,15ee2555,f582f16d,d59c4658,67691e1b,389d1fe3,222b5444,294ab391) +,S(ad7beb62,cec8aa9a,b619693,eb40c477,53e22897,a0007693,f10ce664,21d5c15e,49f98176,a360297,42402a93,26e34a38,cc837278,3873b076,f887c811,e2bd98db) +,S(aa335f87,c61f2e9,7d87355e,2a1c2e51,f2a0ac92,1cfd3cb7,5189f256,386ef185,b39741b2,fc158d6a,435bfa8e,1a68eedf,13deab27,388032fa,fa22d649,c9c9a8a0) +,S(854ef509,24fa2fb4,9b7b7b49,44ad8c9d,87627883,60ce8bd9,36e64f12,a550356d,c5af2246,96c7e32c,a385f7e,3eb8326b,7d9e3537,43a95c8f,3010a160,1d6f534b) +,S(71b6366e,42a8e2c5,31ad6770,ff01481f,5a39c54a,d38e0ac6,f068117d,8d5c9d5c,d6684df5,92f085cd,aee8313,59bbceb0,1a357edf,b36f8e14,706245ef,f01db334) +,S(3a4d1869,55b698d0,5e760d75,8842bd1f,cd869e84,c2c29e44,4ca83bd0,3408d6b4,5ddd1b14,15ff793a,80fc196a,83ff2736,e9791418,fba7eb98,71b51269,170d9904) +,S(f596d242,7e51e5ce,403d673,cbdd71b,75550271,dd2d7d93,79883258,9d3c5739,cb9ef0ea,f6326a5f,83e40428,79675f81,188763b1,ec06fa26,3d7793cb,82b4ceb0) +,S(4bb25028,b5598090,15286b2a,a8858e52,227f3b11,9075077b,3083fe16,77efd4ef,cb63c7c6,9de6503a,d33ee35f,95d4533e,1e978f30,2762b478,e88d18aa,5c4ff098) +,S(77c7c018,4c89f974,df648e0d,ea57ee40,73acd63f,c6e22a55,6269ca4e,a5dc1c99,978faba,232a2b0a,9cf3de55,976ca950,ce3f197e,e774b2e0,d4bd1e5f,e65a1b41) +,S(834d038,926b1ff6,13dc9001,7d021bf4,5bae5,d3741460,db681332,61975c30,f5624b83,614f5e82,10190b34,9f966fde,cd4eeefb,e3e6b046,b3028d6c,3807b475) +,S(370045a0,a7f8a64c,a2b9c64e,85a07fe8,9a7f725b,2cdec8db,258b3d3a,d9cf379e,cbec192c,cfc58b62,6b89d6d3,9b4bf622,81e308b2,2aa3ddf,51d45561,37b1811c) +,S(61302164,6103ee82,1c3103d5,f4d2aba4,645816cf,a67d94d8,ca53dcc2,92ca36d2,935e3db4,5ee1789d,ed8f0ded,ac0430e2,7317f38a,87682850,9568feb8,15e20a1d) +,S(4d6868cd,4df5b1eb,8d27e045,ef04209b,c1dd0bd7,aa712937,8f7bc025,e569d90f,dc0079be,850ab0ab,ef9881ac,740140c6,958e12ad,edfcbd79,2f446d78,7157780a) +,S(43413ee9,a35c7c44,bc95369d,38d9e7ed,53175f17,6f9eb54,6df98540,93105549,9eaef64f,45b421d1,ee80731f,ed61f658,861feb4c,72b5b2b0,ec659825,63172f7b) +,S(1e728340,95183b28,a443e00d,6ae01921,75844d9b,ffb1c77f,c00d388a,80a6b76,d1931ac7,fccf26d3,a2ef72ec,e8c7ecef,c51ad264,ecca5748,7e9cfe5e,d798428c) +,S(7b5995f0,fb0b8246,c588e393,4499404,415f0d03,c9174317,6cb2f4ae,b06960c0,716c7849,b6963a9,f1a7998f,49cfac4c,42a329f8,77d7c8fe,5b35f958,ceb9c0eb) +,S(9c5efff9,2be6057,f5223d41,87fbafd1,a59c364b,239120a2,fa1c4596,4fdad960,4f4aa66e,e42548c9,4d6cafa0,81e59ce7,ab65cbd,78027de6,b1edaa,25e6d7dd) +,S(46970472,192c3690,3c7bd061,dee19fee,5f3a973b,a70430f3,581abae1,3a61e55d,4d232a77,62e04a36,c62894d3,41665ff9,ad8ba55d,353d52cf,44f392cf,7787922b) +,S(add62a3e,583dce2c,55e97257,b64c26bf,5e86b0db,92962b3f,a54e7c52,ac00b32e,3c700f82,c5365611,f3cb1ca9,cb6b0c2a,dda80e04,617142ef,eccfabee,178d3dae) +,S(526115b5,34b212fd,9836a98f,853ab3c1,24bb68bf,afc1d641,b47d08d7,39566c4f,29c983e6,2a4de19,4efa5b2a,9cd4971d,6a86c8e9,f535d599,ee04db95,120fdf4b) +,S(87908ac3,ee8f4e5f,31aa08c0,ac97e93b,81ac75fe,33bfbff0,7d4f0934,7c911f45,b756def7,52c71c51,3f69235e,8d515d6b,f3289a5,a579b999,a695a2f6,49586ba8) +,S(2d6e6ed5,d2ea8912,6797b396,8ac1b0e,f876904b,acbace80,a2613b35,d9bbdd11,b1b66613,50ee7a2b,d149ec9b,25a502a1,6ba6143d,32da00f3,13cc389a,7c0e480b) +,S(f076c9e9,8590180d,dfd36cd6,160c21fb,7dc60263,77435e74,30f74cc3,c46533f9,2c9decd8,6da7b49b,1b4d0a8f,47aaaf9d,19d9e8bb,365c383b,63726f64,ae56fb98) +,S(fb52489b,6d101de1,2f51720a,60a78207,84ab4dd8,39d05c9d,a3b9c349,a74452d6,f1a967ae,deb5329e,faac7381,f3f0bc76,9eb8cc89,78d5d56e,f382a17d,4c3baf4b) +,S(dc1e911,53b3435a,8f23cb08,a7b52f64,a5e2870c,9345896d,ab4ab880,9710241c,3468d632,eb3a51fe,133381ce,2b5dc9a1,64f8eb68,9c019b0b,7e48d504,50e85630) +,S(2d8c6759,6c7856d,b7062c63,2aaffbee,46779bdc,777f0be2,a64093d,41d4000,c7006eca,b64904f2,9cd7baaa,14a5226a,e5c4b3fa,68c62cf,65789066,2eb8e8ca) +,S(31e9d361,fa0041fd,bb73665f,2e1541f6,c41764e7,78023272,478cd7f8,e9552f06,62fdf441,4effb45c,5408a0dc,c0a78041,cbe39cac,562659c,ab8c2b89,1a940c11) +,S(792f50cf,66aa0f00,68bd7fb,ee12bf44,e1fa6662,41c43d2f,275a248c,29459830,633cf86a,a3f10f31,40aaffe1,d04ee094,aad1cc56,129149c3,2702c33e,40d91e3f) +,S(be4f52ab,8f6ad1f0,664e4d28,b67be76b,c3d318f3,9f455708,94060e03,2f8547b3,22ffbfca,44482e40,19ef36d9,209b4262,48d62591,7d81b6a1,57ad945a,1878b4c1) +,S(bb693c4f,7110d2d3,8bdcd6af,d8b29b43,80d003a7,d0f6420b,e8d02cec,3e7cf385,3bdfb9c3,948034e9,31904f13,e3dcfa78,13d3413f,5c2daebc,744bac87,9e4314b2) +,S(56e8a65d,2eb188d4,64dd4280,b987b5f9,8b92b8e4,34b6bb1d,1800fc4a,f8f2deb5,11cd5d14,63777189,f8c7d19a,c692461b,d21fa20f,f12d1976,3b915fa4,33006cbc) +,S(f09d5cee,514e56e5,9566953d,f8600a94,cbad003e,9c898261,5bb998f6,a5b8cbb4,d07ee0a9,a0e88f5d,6da3d918,d5f309ca,7234373b,d528cd8c,21ee9ca5,3d1bafd0) +,S(58671c9f,687ab0a6,f6b7c687,ef546765,7f29ecd9,d6250088,d588742,7b96fa6c,70355403,abefa39a,72d89348,9a8251c2,10d59df,80b4d284,f3f02246,f3f6c60c) +,S(e47ec1f,8a7169d2,9c05cb96,42ba126c,aff841f8,c2edfcf,25ec9303,772eea78,ce97644c,ca60474,4c269973,fdfbf169,bf0fa377,61737dd3,77692b9b,ac775c9d) +,S(ed95cc7a,a24a4ed4,1dfb019e,31abc80d,93ca5c04,b0515f2c,492e9105,efdb12cc,1602bbfa,f17e8c16,30ab470f,bd8fd829,b4a466ca,9f210904,7e0903c4,e012d789) +,S(b6fa3ced,a07a9cf4,db717242,9de8069,216a7b51,4145470d,d811755d,a2908a2e,64f695ae,7f19c7d1,17af6ca9,36dcb2df,8715ff96,c8134313,c111da69,7a354dfe) +,S(2e3047cb,4d210007,39b8d5ce,e4884a5f,ae969eef,898a600c,2202da33,239b3627,197f37c0,7c11943e,40328e3a,3c7c11d8,f2d77d16,84532631,53b7cbd7,69808c9d) +,S(df9c446,7a691cae,b8a01ec1,a4a8ebc,fbbacfc,ca347aa5,39d56853,c14ecd3e,acf9554e,906e86ba,8459c108,d49f7aa1,e1e4b2ee,9957101a,f16d43f7,7dfaf6aa) +,S(d452f3bb,2e3e54c4,1f68267b,f846f504,99f39f28,5edb86cd,68330ed9,510aff54,52c5d16b,41eb1029,7f86a30,28d1b610,6f6c5aad,61b63bd3,53d95b2b,fd214755) +,S(cc196d06,9ad60096,c4ba1057,fa4fcd9c,4a50b28b,78227074,22d531b9,dd85a5be,bd930456,14388283,b28cb67,758c792e,5f9d6c0e,2d4c1a86,745e0504,ec902b24) +,S(4974252f,9c246a45,1187b1b6,546cbf27,af9c21cc,d03c7b37,df7a604b,a3b6859c,276e69e5,b85e3241,33f9ec76,d628fee8,3af37bd8,def6e677,bba19739,9da14305) +,S(311548d2,d9f880a7,17e77608,8574ff4c,185cb0f0,a9660ef6,7a94d090,3e2fd845,82b2dfdc,2d0ca2e1,d403c1db,7593dc01,2043122a,fb50961e,d5f86174,18a3d7b7) +,S(30068568,4497d5d3,2c98d3ee,1136a9af,d5bbc79e,340528cc,4e0b3c55,74e867f4,57c141af,fd650050,79ea563b,e9ebb161,a7725bb8,e41e3c13,ec528b2d,df23430f) +,S(1c223f58,1f03b4fc,68024db4,876b743d,8a2b635f,988340f0,d22c389c,43d130a1,9d99aaea,d3bd3b1a,9891dae7,4a3dd857,3a86b643,6c623c00,6604b211,4e27c133) +,S(a675c89a,5d453821,429109cf,45cac77a,880e0e6,396a0b4f,16053ff9,eabfe4c1,8cda99bf,c3426739,c4888767,113b7f4c,9b321a61,1b63b4d1,2dd50a79,d80b90f7) +,S(e990a236,d7854ca7,3e40c661,93dbf3ab,74198351,1236988b,cca29eef,772b32c3,a3d42c05,851b8138,ef1bbb7b,41510bb6,fc893baa,928c98ac,91127b3b,a100aa12) +,S(2a6eff8,af4b8049,2c3d31ed,f6672d1c,d0b231d7,6deeb590,a8d0c4c0,83586027,2a7427d6,951e07fc,4d5cd4f3,ca8a3415,8f0d03c2,3cd2f250,541c0f11,8013a623) +,S(7dad1061,9c4a7bd5,1edf6813,daa8fb4a,2a9e494f,9835db8a,42f4b0ca,827df50a,3e3b2b7b,a44500d0,277b792c,8a529fb3,41667560,1c4e443c,9c2fb2e0,dd17f1ee) +,S(39d5b162,fd48725,1bb42303,b7b8887b,92180fa,ddbdfb7b,a14ef2e0,3cc32aa0,3a8bafa4,5645e4e9,bf4e0175,69fad346,210e65ea,fa92b971,413a2190,b64b6f09) +,S(f9ac329c,ba09d60b,5aa62bed,81e9ca15,7a3bc53d,acd83836,89742ef3,cfcfd795,9c2fff50,aad80c18,2e6593ae,796ada7a,e0a42a4,17ce77bd,ea7be927,161be4ff) +,S(19adeabb,6e9aea9c,fe245329,623b8bcb,3554eff3,999b0b0b,8e035450,14cd964f,c570d99,99e9c62d,a3321f3f,a548d43b,99f05df3,e17273cc,2a45a3d9,20654cf8) +,S(978f705b,eb9b6009,22285468,521eddae,e71f6521,1ae79567,3b122090,fd4eb3c3,8eaa7bc6,1ae92adb,506f9e32,c66f5457,4e1d929b,ef4953cd,a1cd3f8d,c98ff8ef) +,S(e29b57d8,f6808d6b,ec982a12,ac70afca,1c9c19ff,a7b0c724,4fcc5b0e,3dc2fcf1,f7d60b14,133721c3,471fd91a,864e576d,84e5a06e,b031b1fb,3a2947b2,a33b159b) +,S(72073aee,f39510e2,81cca2d9,7831e533,56cc6016,9462a9f0,45100dae,3443bca8,bd761539,177458ee,dff87628,d155c9a2,d6a00e26,51158def,6ce72c35,84d56a3c) +,S(c949cbc9,48db844d,2cd04810,433f982a,680b6a95,e3461ff2,108492f9,247fefb3,162ca70c,c9f19d2,d3da47b,3b0a2361,f5c21492,a12828ae,9c0ff9c7,ef1d7b20) +,S(9acb7d8c,e958f7e5,189676c3,e7248ad7,9f717a67,2d4c80b5,9c425663,e078810d,112dc86f,1b241c26,30d87412,2faad000,473bce32,95bd6989,8b6a4521,7773284a) +,S(e468a13c,e5ad4c24,4df9aaa5,e13987f9,50900b4,a32ba33f,430935c2,1250e4bf,61e3e755,a91bb2a5,3fc2ac70,bb232b2,c1aa356,d494656c,5df93232,a866e400) +,S(26779f67,75d8caf1,46638c17,71e33b02,b41c61df,325acbd4,506199c1,bea8310,e9de26b5,c076eb9,cf3436dd,d9bc7f8e,5772720a,a8401227,7af573eb,65a769) +,S(8c408da9,a816c7ba,ae2846ed,bd923211,926e5e5c,ad595a5f,f2dbb190,f48857a9,89373ca7,e9f3f96c,1f0bc7ee,d427dea,99808bd3,b943964e,f0db4bc4,a7a1256b) +,S(9ccbac95,d80bafbc,b7e699c,aaccea8d,3169db5e,328e1519,825a3f4b,adee6a19,5a8d6936,a2859d57,6accb35a,5e80c944,4d71612e,76cd755e,aa3465b0,dcad8aee) +,S(34c7b7ed,6fe88bc9,803567ae,71ea7c28,c9511f60,e2ebfa8,fffeba31,dbbce2d7,31a3bfbd,c42cffa6,c77aa417,955c671a,426497e6,b35efaee,83a58bf,84de02c8) +,S(7940ca7f,c3bc810b,5679456b,88a73cae,4b2abed8,47260052,ffcb33de,edef6155,8923cf73,9285b368,d32d690c,488d8b38,5d3285aa,c399fdf,6e263daf,4e0b35c5) +,S(2cb10da7,104ff7d8,d8f1742,43425c2c,5e8773ed,71e62e4d,cc0c2d4a,56ac3a08,610cb16f,53ddfd28,7a7ff301,a8047555,801c13b4,81033c94,4e145b1f,98458520) +,S(ced78e5e,58e2893c,3910bd9d,d43fc362,ce06dcea,f44c5aec,ca17eb0e,cdc1fc53,c66050cb,835c97cb,c08ae0df,242895c8,f0f0085d,85a020b5,122e041f,8fb09607) +,S(5e83a4f7,7c4cc672,a7a381f3,e527c8fb,331e8d75,f8578a85,39ae1007,51903f24,545cda31,25c29fca,b343c22f,824c86e8,89f2cd3c,d2a6f3b8,9e3308fa,2968b8fb) +,S(c62958f8,33217811,cb099492,fb8c13a4,5b3d04b8,12a0c1f1,68cac595,e7efcfa0,e179e98,1b92f1be,25c9f892,d6a71ef4,62f3e1c5,43127fe1,f2b711f1,bf61aba2) +,S(7eba00b2,f151282b,83c7fa9b,5df6d9a7,b764e7f,42ca29a9,2734859f,a2f0f016,9e3162bf,a619123e,8e87728d,da825814,4b760c2a,3d05fc2f,1fc25565,1d72a7cb) +,S(8f68c1f4,83ce557b,98d96444,4a2a7d2c,a05d8f25,e6f9f909,cb44b58d,a030cd90,30f15dc2,17e7ce70,a6fae901,70930130,8f7d8706,80c43840,765ee89a,5f864e00) +,S(393d5b72,a9bbc392,4f712195,51ba7f65,4bc4df18,cf93dcaa,bace126f,c4262b5b,976cf232,fe59a3eb,c6514242,19128395,2945cfb,f792e4c8,19248346,37f16e9c) +,S(e1648650,d0d4ca1e,8fac2522,cda2a042,bc93b879,2d6f870,29c6d888,a11312ca,4d919105,9ea261fd,9470ffb9,e60c703,6d21da3a,ce975880,39e1a820,c636f269) +,S(efc7519f,4676989a,a12d823e,8e49b1de,96397ca2,11fe729c,cf0fd67b,bc6d6a74,3f304e50,be6dc6f1,b7c79979,4ae38ff,ed11a253,778d0294,13a98547,e3b889d5) +,S(85726e3e,aa8f7016,1c3629c2,84b7a7ef,79259de0,84f8bbf6,9358f66d,a439133f,756800a8,11a472ec,a72604e4,c2eea080,94971b58,3738e7eb,2c817250,2595e47f) +,S(2e238f2f,de3c39e1,19119541,9eccde3e,b0c4fee3,e432fcf3,f58c4f77,4ba070b1,7ce6b671,c0c79a82,2fdcb88a,a10a8033,bcd0e1a9,2cfab941,d052c09e,4e5e4c81) +,S(9cdc6aac,41e79b7b,ae77a7b9,bc027e99,1d4f8c1c,2b4913a3,1eaaf1a0,9bd87f24,9d666c3c,3503b9ab,d609b074,743f8a3f,460c0122,ad7a0cc5,a22a6d17,9d948ba1) +,S(360dd1e4,608c9215,287936b6,97e5e819,390629a0,7bec616f,7fc713fc,5ef8ec3f,7628d770,5c744125,d5885c2b,de25693c,5afaf8a,3d5739a5,deeeb5e9,ac1c62da) +,S(8657fbee,524c5f5e,25aecdf7,7306c97b,78119e0a,5f155c4f,37918e87,12302d35,242172c2,f90ea26d,b1f7d2cd,dbb9af4d,78a1660a,32402a83,6e598c92,df9e999f) +,S(3ae7e8db,7b069528,acea3e0a,dc005d52,7ca9e1ca,dd3d3cdd,5564ea86,5e1a453,ac203ebf,98b7e46b,bcad5156,cc058857,f32a8d62,2114acc4,55cde626,591fc5c9) +,S(81bdb0a1,9852adc7,afcd9775,54143362,c7e724df,884f1a2e,796d88bd,1c1696cd,2f189af1,a90f9445,353d0549,4d5562f7,4a3d37cd,1362d92a,aefe0393,9b46ef0d) +,S(e95b0171,dd117d45,263141e6,95ceaa52,3498a8d9,d1f09ae6,855fad1c,5e5c3e8,dc8bf907,ea6a4824,9cf930b0,bad3e3a6,c179fda4,107a0812,76f02a9b,9c689416) +,S(20e3979,e95fb62e,ecfa4ff1,3aa3fd46,94b24ab,c814f560,ce180262,11b70bc8,c9d01545,50f1d7be,da471272,822522dd,d6924a98,f6331fd1,cf6837d7,db91da1f) +,S(e0405598,cda639ec,6c058a61,4c39d56,f71c43ea,693f9b86,c9df1bf9,e4fef30b,9df9b561,a7bb2ebd,67b67031,a92dda6e,12550d0f,5cc2368a,603ae64f,ed20ef3b) +,S(faea8667,646d1600,2dbbdfd8,74a59ddc,a2b8024,b2f7f6f0,f2c2036d,ab5c5e9,8112167f,ed386f1,d1e02307,de202bd2,363cd1f5,fefe0621,1c4564fe,eb0220a9) +,S(f01d6b90,18ab421d,d410404c,b8690720,65522bf8,5734008f,105cf385,a023a80f,eba29d0,f0c5408e,d681984d,c525982a,befccd9f,7ff01dd2,6da4999c,f3f6a295) +,S(5906b143,9b994465,c9f3d4fd,f7f09a4a,b9ae0864,262b0140,def21014,8b097533,2917b92b,d0368fff,6e6a98d9,18cfeda4,d039c73,a3cb865a,5d77abff,9fe7970b) +,S(d6443bcf,53ba252e,925f5ae3,5d508732,a3289059,308fa67c,7b051ed9,66b6cc92,e0155fa0,366a2d1c,af8d2c17,a4ad9cf7,f4fc0102,f1e1ec13,7f1b2b51,1af0e7dc) +,S(b95a72a1,dbcfa0eb,ed2200ad,b57d71f0,b96a9703,8bd3cba5,78eff5f4,e9454196,f89c7cd9,783a4c34,1bdd05d8,241ec4eb,d8815463,4d05cc84,d5601f4a,6f3fac0d) +,S(50b287b4,d8b41f03,88804ae2,2b56abc7,be632cb8,a20629b5,3a00fd3d,9a879b6,67c3bbfa,4d8307c0,bd32106,57f5c0b4,78bc070e,53a3024e,1ffe103e,e5397076) +,S(64feb83a,5a81f6d8,8218e2a0,4e6f97b4,6efb89a,6f394264,d905c93a,cb7e5493,3fa224d4,eda77580,4d6ba88e,63df4c3b,5d9fab1e,519eca92,1ada5f44,741d5035) +,S(9434b5f9,2d63c2c,c90ee2fd,b7f7289f,b6277c69,3076d73e,cc38b032,bc8b5cd6,c940b3a6,4c04e6b7,1de7f727,d6fc0883,29443276,6d2ccd51,6d24dc22,3998aee9) +,S(a6db8e98,6d1bda8,995015e4,807b900d,704f8d3b,8ac5fc49,aa16bc61,82390724,3277c29e,bf27d0b5,ef8af507,5e295f23,92c41f29,3803a8b1,6ce601eb,2abedbd0) +,S(50733cc1,dd80ddbd,b254ea6f,14d0679c,6839e6b1,73aa0bc0,9d0ef5bb,bc5c2f9c,246e1742,a5a9172a,ed4e1e0a,9c0d623a,5233334e,47bcb68a,aec41101,92771eaa) +,S(4252122d,5a89f621,2c7b0a99,5ebfa8c3,b980e142,f7a89e07,d4788d91,1163ad99,bc63b87b,fda041bd,f9ac11c,e2e8ab3d,a1368cd0,2e276b55,6419e0ee,3d7fe284) +,S(6bc86411,d3f9d25,bad0a922,21f0146c,9173cc99,d00470ba,a41897fe,b5678f5,e2c1cd75,3915e977,c20d4508,1af1946b,1d8c5926,cca74ab5,c4ec0bd7,921c4cda) +,S(c786df9c,6b2e656d,a30146cb,14da5372,64683e46,5569b1dc,df4c1541,580d40a0,b8d229d1,d8773d5,dedde14a,dcf8816e,acaa274a,1f4ebd01,2086159d,1feb32f) +,S(f42032f7,dc6dc676,5b1a9453,74ee45f8,486e9b94,6a57e651,7dfefb0f,9ea3164c,ad2d7a22,e477f5ce,ad0fbcc1,fe2c2533,78920fd6,cd9ed4ec,1095fa88,2189131a) +,S(3c2fb5d9,a5bc7ad2,d4ce0970,5090a5fe,ef54a6ad,7f8d827b,2ce51785,b29ba5f3,3ec2d878,a4d836c1,71f68648,f8cac869,472847f3,4c267139,5f38e0b5,e96b653d) +,S(b182d837,dbb1e47c,bdbe559e,f30f03e9,ae1efc93,a5a165e3,10285bfd,ffe47303,c40cbcdb,d7f1fd56,c486a35,67420a7f,e4ed4ca8,43a68bdc,81eccbdd,213d7c5e) +,S(75a35130,cea9cec2,81792d7f,ffe84375,a4aec378,57496122,9a77270b,43b12391,988821ee,b6ee31c9,8201a90e,853c4afb,8e330592,6349d405,90c4840d,fdf3fb5c) +,S(a97b9c85,97362b4b,aab43b64,db7e5e0f,3e4cfea9,82939289,e5266f09,87fc8503,ccb75937,fd647eb6,7da4aa7b,72e8d873,c9f035a5,cfa120fd,4d4881f0,9924d8a7) +,S(d129bad3,4c7674ca,60a6f07e,1c1ee8b4,aa3dce4e,82ff890b,cd256324,13a56fe7,b3c8d404,7c8610a1,a56af634,b54dc568,6af075a0,a0cdd4f1,75855fa6,d22cc4c5) +,S(d8a0aed3,cf37542e,a0f06c6e,754503d7,3bd693cf,c3c357f2,7445989e,137f73e2,ba4ad8e6,3bde0d8c,42172a7b,59e1f4f4,581f48e,cffc45bf,929d815f,8133e6a9) +,S(9f905bc0,a5f479ee,6162ed38,24d74a1b,d6d48bd5,4611f840,ab1ac55b,7b84be18,5babdad,4248a4ef,4606dd26,1807e25f,6206dc81,6eeaddda,fd8b5082,52e3da53) +,S(d51c86e1,4519166d,c2aa7604,c88670c6,ca44a84c,6735f692,ee4dda79,e957b85d,fcee6753,29130c5,f4b260a9,cc7efb73,d51e6ec,8ac1ec52,28ca0ab6,51d5b8f0) +,S(ce251fde,ffdf0f59,5a563941,179f6f8a,86402b2c,6bddd1ea,7b37b89,bc649102,5b26a79,882b2f89,79610eb6,5de06e02,b09412e8,bbff66c5,cc650211,d1b9ccf5) +,S(6168ac7b,101fbe73,5b9339b6,9c459fbe,44a6f6c7,bd488beb,bf0b81da,ce511f3,65b6e531,f350983a,2f55db14,588e92db,436f7068,5117255f,ed474aa2,53b5c9ff) +,S(aab2deff,7e77f414,59d4361d,2722b448,6530f0c9,46b93d96,975f5a96,eb4bd091,b416562d,c5b057ef,7e63ec2d,daf0aed4,84320d7b,60695809,c6fa3aa9,e4eaa431) +,S(9ebed934,ca30351f,44b7ea4f,f3f6453f,6d0c7f81,869226c,c8f4312f,d413056,766a6f8c,311550eb,a8500ab6,f3466ca3,52e6b960,c4a52cb9,870ff784,4191a2aa) +,S(a2e78d35,d51970c3,42d03a09,bf3286c2,3a131ff9,abc4bea6,352826d4,5fe2da0e,fcb844e0,4bdf8d96,f423c499,44275ac5,8885c384,57975268,ec8cd880,dc640346) +,S(1a49f352,5203a773,9c7cce34,d21c51fe,dfeba5e5,c0f21622,eb954621,e3d6726d,e617de36,7c6a9283,8d4bcfd2,bf2fd21c,15b53007,6a0367b7,6d6ea65b,af032213) +,S(be65c6c,de6c54b6,c0c4d306,65cb4d61,211c97dc,a74c57b7,13f41028,e2d14832,d7875fb7,5cce3a40,9a74e48a,9b577a04,4c09a43a,989606b5,b44fbade,89e6c03f) +,S(a1572e58,60b10c96,bb3e0b6,7a047d4a,9957448d,74bd8a44,823de9cb,50aaa639,5ae37e0d,88c9f6d,173026ac,58ef45fd,17b0a0da,40304954,f9671c56,93946d1b) +,S(21917639,b6ef2333,378bafe5,fed1780b,24d9fa82,17ee49e7,369099a8,8c9baee5,fee39df,4bcb318b,4dcc4017,7f1af605,f22c44ec,d67a15cc,297f02fc,dfec4eb7) +,S(ac2a8d9b,b2219c98,444d03a0,36db728,ffa182d0,d31831ad,f2643010,bb76d3fe,adec7f18,c9474dc8,d0741d1a,5e72e479,c8b86f74,327fc5d3,cd79cf86,869310ab) +,S(c540463f,bf62ef36,a972d797,2bf79054,80b8e67,415f1895,d42d261c,165d1b86,f04a3516,83039c2e,8bac5ef5,1db4e105,95a27e25,cfe680ed,e7d840e4,f70e50b3) +,S(df63238c,77e75ec9,b844431b,d15007d6,56b849eb,4b6902b4,e79f0d6e,9527ef29,63846f3f,dfba6f2e,46bc7f2f,17af5067,a953cd0b,dbe2fef2,52e73be,b8a17330) +,S(43dd347a,1bf0ee84,ad774d4f,70c67cea,594946c2,94cbc330,15bbdd21,890998d4,b6f58d9e,e6e13c1d,b65dbd28,2343d8d2,3f73035a,b4399672,15b0300c,f7dfb48) +,S(5af8e3e7,f5ba9d80,73c5c1e3,c8d0a62,52eef1c1,17043e01,7d610f20,8b5eff0,246c7a4c,6f6e75aa,eb60e256,756e6365,711e98a6,aefa5345,adefb632,321d39da) +,S(60e7513a,b327df8e,e3d44222,95e0d886,b264f560,1c4e3d03,3b405d37,f6ae8518,4c58466e,b68d6c81,33fa6639,12f4a12c,a4a9f3e3,d4e0f6e2,7e92a85d,4d541cd3) +,S(126520ec,f3129775,786c4d64,7226174d,3ccaf5ae,2e4a1514,90e1b691,f07946a0,d5a2544c,efec281f,e70f05e8,2494085c,133fb918,6416435d,4b7fe673,88c440) +,S(b588e8a0,2396bfa7,8512585b,cd0d0e4a,7d14b5e9,f76e1426,b4591c9,6602c585,d7c6a7d0,827852f9,e34942f9,a6f5eae9,cd0a7f29,d30057cc,46d13e2d,4ec04caa) +,S(257f90fe,4409ef7d,30730e37,d7358c7b,60a1cc21,57acedd0,355d7a1c,89b5750b,b14da56d,9aa8fb67,b2d1260d,8de63c00,a9a7aafc,6fb890a0,e1a148ed,5e371201) +,S(8072b8cb,47c71331,9ed2ce85,cf913c87,85955c84,d338daed,58528427,3f3a4a56,6d7a0ed6,bf3383be,8953b47,d93ac5a5,e40e8547,2fc6d3d7,71f89007,f8d20d39) +,S(fab935ba,b2b72a27,b338ef89,509b3830,b7800817,19c2b3ec,8467c736,24ca2640,2a610c06,77fb514c,b224dcd6,56c5136d,88f87f34,86fa0699,eb71319d,c85a103a) +,S(7c6364c6,4906b7c2,e1ca0d87,6c163932,7e8e146b,afd94c83,2330f990,f979ae52,c97e7b44,26b91f6c,88ab7e39,d57f7b7d,4a5e0f9c,ff15aad5,e58e7017,d51c5317) +,S(98beb1ac,48c8824d,447a10cb,43b51167,b8e7cf0d,9eb4e4c8,43403b03,2208570c,1712c13e,ddff8fd5,191fdb28,717efb74,ed52a9f,f47bc21e,b15838d,fcf00af3) +,S(f683a667,31241c44,4adcf062,156f3fdc,d04e8450,911908e1,95bbea2d,8c5bf918,460eac53,48ea1e78,9fdef168,a150065e,1e4a2f83,85268385,3355586c,87453f1c) +,S(38f065a7,165e5d4,d31238de,8dc38f43,4dd024c6,6eca026d,de03c4cb,b43639a5,790bacf5,d35a688b,130bdb38,29073b8,28837b9c,9357544e,1e44d766,e401d044) +,S(cee8a218,2b3004fe,76714511,30340b0,7cf10241,d9e933c4,97ae84e9,a1d525f2,ed373709,3e0eb05d,3ee2823b,25bbbb11,ec943848,1a3ceae1,89573d71,7a596b3d) +,S(164c6ee5,620f4582,35520eb0,8276d85,9a14e266,b7b59576,d0a3e0a6,636f124a,fe92dd66,139f02c8,76ff6e57,8c769a4d,63484072,5c909bc9,481d4a52,f60565f3) +,S(d4606a18,1a0bd363,eb63849a,81c77d0b,942ff14e,7f885c61,d1fb772,78ef1008,81e7b2cd,e7c5d9,29e1d69a,309a334f,2c01b084,e82b789a,835a7aa8,5d7e93a4) +,S(905f5725,1df1651e,83aa8b3,dec2d96b,a32155eb,90d7f985,b3ce5213,2092be07,e4acfdaa,9eb8995a,a4ac8a0a,2b66cbbb,d561fe6b,389c56f,3af6f62a,d7579632) +,S(2e3ab14c,d3aa69de,a35a8ad4,99130302,b16f3d3,9df06b77,7c30e404,91eb6dda,ade534e7,ea0217a8,88c50bf4,ef81dddb,a5c7ffbe,bc0f90e7,110df2a8,e0c7c2c0) +,S(98207cc0,23f50a6e,5f5ce8a5,68c5b24,d4f4f741,94de76a6,d1e6f44e,72619a9b,fdacc236,bd424684,52508806,b08fabdd,98a15b15,6751953b,95b4c5f1,40bce374) +,S(b6d8bc0f,894863a2,3a793c3d,a33a5e66,cafe8696,f9cdd40e,777a40ea,aa203ee2,7e9b246c,8555b4c2,47c45fe1,d1e5d160,c7ed7d37,a3a43440,deee6ef4,15dc092c) +,S(56d030ad,eb30f1b4,7f806276,651a56d8,7f0d8b6c,458092e1,61351368,8cd0f6c3,bb3a1513,155c5885,e084180a,1728902b,33e1a61b,364c8d9c,94d67ca2,e386f131) +,S(77251aac,f919aa4e,b7610a77,ba27d94,c85b973c,af04c885,92fe5272,a48ec088,ef27aac0,593cc67b,93535bc8,4d0a04a3,e8a865a1,bdf65312,85beac2b,d58e149d) +,S(cb7b6a,cbbbdc23,64711585,6d80df3,2ec9aaa0,c6380b3e,677299d0,13658121,1f818bab,72575e35,a60ce7f1,c720e9ce,2f59b086,63cba841,ea288920,16a40ca4) +,S(4a18eb1c,bddb4c3f,ed44fdfc,6242959c,29720142,21d10154,c7fbca68,5c475d0,bb24f347,ebdcdc0a,6429f8ba,49065475,9cce87aa,8df10496,6d2ebcf2,97e70ffd) +,S(384286ca,1003c97d,7d151032,97d81cfb,e3e3dbbe,5dc70c76,6a8dbdc7,c1e625c,7201deb,638d2ec,6cbb4db4,e955ee1b,a3015cee,e06d2ddc,f024daab,8f07a277) +,S(84b6d6ae,d5e00e31,73c24d39,80f05cd6,f61625e3,11439a55,e03ae2db,d79a7d55,a3da9e1a,4c32e4f9,a1d326c3,6670296d,3ffb18fc,266e169,a99d4d00,4de383b1) +,S(aa1cab51,f7239cd4,dd27a4c4,805e614c,5d972cbe,c2830ebe,7daf6ed8,781c37e9,cf8bb72e,535fc8cd,12a2f4d5,e8f9e257,38a28812,1c93b061,5fd4fdeb,368be5bf) +,S(7c4f183a,f4abbe43,d7fa6d5,77ea6c14,83302f2d,b863a7c5,bf072e51,3d2140bc,1eb08c67,a417c0b,58fe8185,1a66902a,a608db07,24dc38c6,706bb80f,5956c808) +,S(dc30f68e,58ff30a,4bf2f6b,28b30708,506140a2,1a971c04,8afe04cf,94b54d31,6f996e08,8d4f7f53,aa1c2050,644a47ed,bcc1da4f,519978f8,6496ba1e,c7be2688) +,S(145185a9,ac6b036f,d0d3cd25,c904b3b7,c8f1d0ad,3ffe5f89,d87b7804,8b017426,d7f6acb2,828ccbc0,db0708e2,79db6313,fc955d2b,cf9e2754,1a7535e3,24c7bc90) +,S(e8700138,5c0bc4e2,9911f29a,e39a5ae3,ad3cf1cf,d690cbef,32f313ea,fd190fa9,92d83708,2e5139d0,f8084001,8ebf8703,da250361,466caa96,717edd0d,6e7ada7f) +,S(5fac0aa7,9963a1e4,5e1c668e,3512d0fe,2eb2c709,d5ecc71f,c862d5dd,523f864,9c7bfd73,445e7d9e,139b96e6,813f1f80,2ec632c6,a76e9dfb,8afecf40,2788d16a) +,S(441f40f6,f3ca4dde,5a085c15,57f14cf3,fbb7c3f2,5716c33c,63ee90f,45c564e2,c81f1205,1179c2a6,f2614495,322cf40a,34cab55d,c90d61b4,d1bc3787,ec3baeae) +,S(a4068c1f,c63d8f21,203cb6af,b37d796a,3c454bd9,db974ab8,e8bfba8b,b832b043,b5318b99,e9354250,a837f8cb,cf8d9cde,d95bb1d,1db0becb,1e887535,4ddb96ca) +,S(44563417,c647b097,d0238a57,74998fce,3c809a26,f6d2b71c,eeecebfb,134cfad3,3f417680,1c15172c,ef636dc3,12742429,13d59079,73ad09c3,9fd8c6a,8a95104) +,S(d57a5fde,47873327,728f5706,d2f0d64,1c5386a9,fdc41808,a2c062ab,942acb6a,cffcd62a,c0c85aae,4a6b7881,f3be170d,9836abda,baa47d60,8c0b8f60,f9aaedd1) +,S(9dcedd10,d495fa2b,6f4b4387,57cb38be,d6f09949,17e7ece,7de913f7,8cb111fd,73196e22,59d4ae9,950725dc,77321567,167d7761,29cc32e9,d92b6dcd,4c056223) +,S(aea290f3,a4ffd405,d51f1c8b,5f11cf74,60f05300,a1e24c08,25b96910,b24e32c1,f6c100a6,3c918f8,f64ffe8a,95840421,dc384635,e3465cf8,65034bde,17ca8eb9) +,S(bbfcd317,5091846f,181696f6,35fb1b05,802e7659,7ca97040,31339381,46812234,2a0a4ebb,1f09b31e,aab4478,89000fbb,5876d7e2,dd889393,3001a977,8aaa3a15) +,S(2a3b4e65,d9d7661c,addfe1e1,96beaca3,ccbc0348,dff6d2df,21f394c7,a7f4594d,74c6f171,1a2c0c01,78bb6a27,b6e17cda,bddb7260,acbc533,a49b19d1,e0b4a110) +,S(d8e47e32,15cbe145,aaa9efec,ada428f1,8d8c599e,98d2f9d7,8177215c,c85dc2ae,5c4d4f6b,aadcd87c,7ac76eb8,22e1c0db,e7c81342,702bfd98,e193df1,809e0511) +,S(5b5954d1,25d77778,f3c1514c,6256ef65,2ae0ab97,151f8856,dda6c87d,1e04a34f,1c5ddf3f,b185edb9,14769482,95e687e4,40497582,26b36fc6,3502922f,cd1bf81e) +,S(e8097e1a,12c6837,a8f29eec,31ccbd16,f191e7a7,d7b199dd,d6d9ee6b,7f26ef55,84ab3d24,e2c4407b,53e4299b,8de1aa8a,22dab9be,b6efa5c,5715a943,65174b9a) +,S(495ebcc5,b0573416,f2b3e705,fe4a4bfe,1e756211,5f37b8a2,dec57688,dedbdd45,3bc65725,6783970c,7696d5a7,b04ac7ca,8c627ce9,251844e9,e7cca774,4d385be7) +,S(4ffc69af,b9cf40ff,c94beac6,aa020109,b7855e0,a993984f,5e59ba16,fc78ad51,6d43d1f9,e3283528,494c9783,cdcbe9ae,2ede071b,ed494c57,2539df6e,b185ca1) +,S(b047e0d1,afc92251,7eaf5c0d,a9d0a093,fde5e829,84c8483e,d256640d,166dfc75,dca2ef00,a282972,d4bf67cb,74fb31af,da5b8145,ec1b7a65,6636376c,504a70df) +,S(ea7b0b93,48e0b3e2,be800ed,6ca4b121,277a496e,84fb6680,2658f68,37b1d530,cef40d2c,e1cf820b,19b435bb,a541ff1c,fa572b1,ca3693d0,cfeb3b32,8ddf918) +,S(e35a53cc,ad74738a,bde75a3e,e2b10d7a,d4ec39bf,e32e1daa,ecc151f3,bef1966b,ad06a8ab,a0296c17,fb24eff3,b27284c5,6ebca204,f6eee752,276ab9a8,1f1bce13) +,S(70334511,ae9acd50,e094f034,17dbba05,4a104c84,ea8d6250,13e1f8f6,907261a3,d1f603e0,5af2e1df,4b8eac69,b4067810,c302ed18,f02bc964,2eba34f6,bc67e84a) +,S(13adc074,c3ea8877,4598d0b9,ad653285,c81bd98d,d4bb6a43,c126db2c,d1f08d7,4bbda9d3,c83c7a64,fcccf3e2,c4251a7e,f61966b7,ec48e89,c991d44b,9588c83b) +,S(4a2a5fa0,71702fa0,934b66ae,7c003f00,306f07b8,625d92f2,d2276efd,18ce5f0c,f9c2f4ac,d8c594a4,117a836,7fa5224e,a7ccbe60,2475e3ed,b19a317c,5feff6e9) +,S(e2f7dc14,79bac0e,a95b5a2,1a9f4e,8c42a23b,8f25d09d,dacb9a3b,fe3ec638,ae6c82,c4f3dc5,41f140a5,2eb6b0c,dd0e200e,d0d951b,e85efd4b,b9b086ad) +,S(eb1d6d07,8f6b74f5,c48a913b,8510e8d0,5cfeb954,856f3ebc,628d0db1,a253963a,f3d73300,e216d14f,d5a67c35,91b362be,f13818c3,36a93784,875ce9b4,2cd8c7d2) +,S(a22c6d71,1d79ae71,403feb96,6dc11adf,253a5d3f,d3d74b44,5f7268bd,84b52277,86d5212,bf37db8b,4e873476,36201714,3f295f0b,d69d2187,8904a53c,831af06) +,S(42f7eb02,797cc76a,21c95db3,c9a0014,4ec5defe,553a45b5,1b701c0b,6f5ed3d0,60525877,3cb86452,928e37d,ce19e2ad,4da63174,2f049214,9f9823ed,ba679519) +,S(f5250698,b37da26,20a3a80d,a9c1c88f,792677a2,6d2b9fa5,49065339,ecc1e95c,b0826c,66edbd2c,5562bb14,d6f8df25,a5d0bc54,7a1163dd,4a8dc1e3,7d140266) +,S(b845d4a0,bc8db805,43526506,cac5c093,cece5c5a,85750d54,317dd78c,7bc10832,e38db2fa,207ce0b4,d9b01ee8,b174a24e,f28591c9,9d203ca5,7d90080,807279b) +,S(4955d281,746b8c9,4bac7d53,26aa28c3,9fba7149,7b4fc036,f9971f7a,870a67cd,ce72ebf4,aef6e987,3fa5cf3,e66ec918,911885ae,848aff22,eeef12e2,e50e6cee) +,S(20fdca2a,a03d6105,50f2eab8,d5e7d47d,c4e2e9ed,e6d2c7b,bfe64d75,176b9e9,1e077683,2c44d6d2,19d19c7b,aec0a303,f4d3d5f6,4ad8ca35,83f87325,6aee262f) +,S(418de9de,9adbec78,769eba7a,cab3853a,9a85ebc7,2bdffc86,844d0f32,15de4877,20d521c9,974c8ee0,f817ee37,a0fa14d2,eefc4e05,2c93ce87,ee665898,9e49c5a2) +,S(135b5a4a,f64eaa0f,d288bee5,c1bb7846,30df305b,5d3b13da,d8c446d3,6e13485f,3e571c3c,fe32fe42,669b08c9,14a655ce,828f41cb,12b9c18,9234f4eb,1aac0437) +,S(7eb64f50,5e26671d,21d3b2c9,fefbe094,c6300348,25248e86,5daa8939,f8b7e90d,be847834,f303ae8a,55ebaf3b,5bccfd61,6284e836,13eecdae,ab43bb6e,d4d4e986) +,S(9ee1ccd1,670be914,f9b7a070,962f7ac5,ac9d069c,eb3e0748,72db2e08,32870fd6,7d3d9dd4,9e71fd68,4271b17a,a8203ab6,1d2bf6d5,2fe3773c,78a8ccbe,d256cfed) +,S(a256c06a,796cffbc,5c90d91e,93ded565,b9755b7c,b760794e,e3060b33,3c217e71,e9ef8b6d,7731c262,6c93fb06,b7a6b3fb,fbbe0e0f,54682409,e5218a74,d4a064fd) +,S(dde8a9af,ec32c1fb,be9470d7,a435b4fb,bd34416d,e703a1ab,5188fe8f,f721aa4b,e7dbb850,aced2fb2,fcf5ea6b,edeaf383,e4ae0fe7,98badf41,66e58f13,6a87f3ae) +,S(fe88599,811d0e9,f780d359,2e8106fa,2f54fb6b,ba1df66a,b7b0b41,2c130c49,b3b0b8b3,c7f36d43,86f30438,1989d885,31edab91,f25251b4,e01b3d3a,6ec97f2d) +,S(d7da001e,8a606b37,ca65ae71,32214cf8,258dd422,efe0fc83,adabd56d,64b0467d,97f503ce,8eee1873,7e422bdf,91f051f7,1025353b,3a1f6f1,545206f8,2a32aa5d) +,S(65237583,e3e1a640,c2c16a9,a49d09c1,f5dbe2d7,a3845989,574abe33,397e747b,2296a1b1,e2350d8f,14a6fed3,afe30fac,a45ff345,9f8f515a,370aa260,d435f7a3) +,S(419a8e03,2d8fd27c,afda6538,9b757550,313307d,12fd185b,4d2f026a,40ae1de4,2932ea7d,3421d738,d821030,f75b0343,fffe9d25,8b605cf7,e20f6b48,1a94db03) +,S(275d261f,7ae2ab4a,4ad1fd66,1621a223,7ce08787,beaeeee1,a537b103,c0a44023,da955bd0,4ef1256c,9e184615,c4ee666d,c9ae14c7,d95caa7a,5dca6f11,1e5e2e58) +,S(3ac6681b,d0a2968,290ad83,cb0e00c6,6a9962cb,4c082366,953e294,58ff3651,28348b56,38ede228,7578cf14,ae385066,4595a2a8,d86282a0,edcc389a,346066d4) +,S(d4ba242d,9407df55,a9f672b7,e01cb1db,99ef744b,d24d3e47,9b1841af,a6c1f05b,9e395144,aa1fe50,9d72d086,4a1673c5,24c4ad65,fb7bdb16,cbd52053,1c6f11a3) +,S(c6525077,2bd399d9,901d57b5,7e8fc941,cae0f5fb,6d47ee3f,5b3a7cea,3fba2e83,629f7edc,a6ec6b0c,579cf9f1,867e1bef,e3bf9bea,8d8e64b7,2b18532a,47280efa) +,S(f12daac6,d38fcb00,c2425a79,2c52225c,a94d544,c6b96076,7ec9c885,d6d4430d,1764feee,2584dee3,abf2aaf,737a068f,fa6aec89,6c02e2fd,cf0ccad2,7ee8f210) +,S(db858a7f,4a84d88f,236b5994,dca409b3,d7111df4,f7e5c009,4ad1decd,82036673,c0606c89,e4b13042,9e0a63f5,1c93b3bc,95d98832,d89a9515,2e5c1874,f2c94a53) +,S(237f5f80,4d4c50eb,d611b079,5cbc6567,101ec8ba,1a265976,64472f7f,5a725ed3,b558d31b,7647c4c9,1367d696,a67e5d88,76454900,f340cd,5b8d7490,9fdd5993) +,S(e962e9c7,7c97cf36,32bf0a88,d6e939d2,68af9fc6,ebca96b8,6fb679a2,d953eb20,931395ff,a50a854f,5aa29314,c50c253c,c3175739,9c2eb20,600b0217,9f8ef48a) +,S(890514d2,14b57796,85c0cd66,818d182c,3d285af9,771c7c48,92ea2ac,115a8c3a,47c5a,a4d76cfb,2a62993b,b499df86,fbe7e130,d4758235,7decd72c,b61aee8) +,S(8b058976,295a316e,65da1774,da78722d,8d729f88,5ea4402b,f20dc67b,bab7f815,aeed497f,57d52480,23b94a3b,5fbe9c0,e34d0039,2d57b34b,377bda9e,b8703335) +,S(6a4685e0,7d96a793,d55a6416,6b089623,755fe549,3a879fbf,fc9a5a74,7ee7991f,313ffb6d,98044c92,f37b3f66,81f1b4b2,d9b2e42a,7c34a5bb,db45b9c,6063aad) +,S(65157530,e4ffeeda,41064bf1,f8d85174,2b9b8f64,87a05ea9,3d2198bb,3f33fc26,5b0e76a,8f96facf,9d492232,95a0c6f5,6a609504,b9b07c38,a72b6f15,4cb8c9f1) +,S(9f6c288c,1e04703,46b02d47,8fc0a40c,dfc0229d,928639cc,6ad2ac88,96e55085,2af7c1c1,7210b552,4ae2083b,b45e9749,c9452776,c12d5e83,ce265c98,51266c8c) +,S(c566e04f,e5ef7062,7d914a04,40731caf,3a7dccbd,5415cc1a,a2d81328,b8a6da75,a3fa5263,a7f66158,67f43270,77d3b2df,8db1befd,552249ad,e96db0d2,8c439282) +,S(6963ffcc,cb62ca7e,565fa9e7,99db54c3,dcaad601,95bd2dd8,df70d447,c443ba4f,96c715c6,84bed531,27c28e3d,6d6a0214,883aa214,25c4626b,4c11cf17,36b8f134) +,S(50db27a9,8e0328e2,81139df7,5376bec6,37e9272c,f7c23333,510bf5cc,c4f46b2a,b5221242,9eec82,1e9143fe,af9e7813,c135be82,bfc153f5,2ac061dc,c1302d92) +,S(7badba3,8f23f854,2404e636,b96e86a6,84557310,2bceb7c0,241e71c6,1ae22ad5,bd000395,b5d0ba4c,a76ac682,5191fbeb,f6066d8a,81c4a210,56ceda82,e13459e4) +,S(147667bd,5591aa83,26fa497f,c60f8e7,a5ceda47,9d4b2f7d,93bdab3d,81bcbd0e,bcdbbbc4,2adac6ea,413fc3f3,6cd2089f,420a6183,a918bf98,fff27aee,3e870849) +,S(ee576c33,e8404e1e,11e1b5d8,6ea52335,cf8b0ade,49dd16a3,7a61fc10,cd3eefd8,722bad17,6e083868,b3c14ee9,a70013d9,89c01b5f,44188ec6,7db7bc3d,ca26fe2a) +,S(8e3cfa71,f3b7d3cb,fe59d8e0,b579b76e,d33d318f,41d3b76,121b02d3,2acdec80,86be156d,b76429cb,ff2c67e0,c015b7d,d0007c7e,33f6041a,d817ae9d,ed5dc4fc) +,S(e220362f,2df8a485,51dbb7ad,634c4bb3,714151fc,db3cc2f8,e483aac,50d88768,acb8e001,a81eb6ac,99dca40,2d62fed3,8891fe2,eeb8e023,6d8f2447,6f4fd200) +,S(1777fc26,9bd7aebf,c014c785,25dcd40c,f93db012,31541cac,448c44f4,89628808,641bdcb2,b87e04ad,3ea3a3d4,c364e93,1171b2a2,cf3c0205,77552b7e,594c649f) +,S(ddfb5269,fcbac0bf,a855d2c4,c9062c77,836af1d1,145b4df5,688b6a5,24c11651,c353674b,9520ea9e,eac3bbce,a85b0709,d0284c37,a7faf78,8b573ebd,67bac8be) +,S(b01ea11,d4704bb4,24cb11d8,b42411a7,3f227c84,dc10eb13,c2b20a1b,bf23258a,240844e,9ea3edfd,948d2df4,51538cba,ed57f157,d0632f2b,8b644570,5f9ccaf9) +,S(934e20a,46fbb416,fbe829d1,46bebdf5,2220c0db,958c2a9c,64244713,4509cabe,76b7a1cf,79ebb5fa,58f77e64,4395d33e,bf90c0be,37e7439,c3d29013,25b0dd76) +,S(15bfe959,5ee58bec,791981dd,13ac5380,6615ff53,95dd4661,28c23f59,ea236967,d6dd460b,d3d36bdc,eb7d3ba7,745fe6c2,fddba241,fadcbdee,44f377f,bd43ee00) +,S(5e1a723f,403cf56f,8019797e,6f8191f6,6e7ccf15,dfb1965e,590490b6,224ecd24,97342532,36c48696,645a7e60,552eeacd,4cba990d,6d73117a,dc6f2967,a6a0fdbd) +,S(1485fddc,85c819da,8894c1b3,8be82eee,762a052f,3830dbb3,7d21ee74,868c778c,d779373d,d503731b,52f9e689,805988c0,b916a579,921c637b,286c580,93343d5d) +,S(6f4b7385,f881c9ed,202ab6ec,c8302626,668a1296,36274f3c,ac4296e9,1eece7db,fcf6f192,c6c80fff,3f5c2bbc,7c6c4a5b,b0ea2e3,70799827,440e998,cf6b26a4) +,S(bc27cb29,33ca44d3,b56280d7,7d69af2f,9220f4aa,49aa0fab,685c7c54,62adaf76,7607d5b7,a02c5e21,cfafccc1,26e8439,88c10942,aae6333d,b5262426,1ed4da98) +,S(76f86b25,2530d87a,b04e64c2,4cd1e05a,e8324bf0,a717280d,3845cc5f,a6a1a733,2db7ce38,33bd24b3,55e95b89,ae6d8a54,19124761,e382745f,2a7347ce,fd7c382c) +,S(5615175d,2ec968f8,81dacc1d,1bd6c06b,df87c9ab,53fdef11,335818f,bafa918b,5f755638,6154cee9,e71d21b9,cee3971c,7d41e3e0,ca2c1ff,f66982b4,d66fec25) +,S(6390f1af,1ef24aae,20e2ce29,dfe9a0d1,50b2826b,f5cb3629,8e0dc16d,ee2bdf8,cf3e2b98,4f120d10,16f82e1b,8916928c,263f3323,52bbedb3,c29ae1ed,b0d49b1d) +,S(bc5df46b,4fbcb83f,7aa53579,ac8d5c3e,8482941e,cf848810,f9239138,b57e9378,d4d15516,624e72d5,9002dca8,3c8b5914,b224d4c3,75260dbd,cda88f9f,2f772627) +,S(3d069f1d,dd52177f,cd802195,c7c8b2ef,1e43c34,9bd88b41,43bc2d54,6a2b8d33,2ba48861,14218d67,1b1fa4e4,2aae97fd,66164e94,af1e3026,8dfe9dfa,7155fde9) +,S(fa657492,fab9ab23,f1a49c17,40079d7e,abafd7a8,72e481b8,7b30cb63,8a47757c,89d2c7b9,2f1ad11b,d2808968,c426a00f,e584ad83,86dff03c,1a047804,a2e98630) +,S(e2318d84,61f85ac0,7db07d08,aacbed7c,5f5a45fd,7e505bb7,ac86b417,6b3eb46d,3b0170a3,b6f466e0,380ab984,e5bf4b34,89cbc479,cb2808cb,445614bd,8ab012e9) +,S(defa0810,91d1db16,fc2f86b4,fa5a7331,f0c15682,55855134,10f41a6d,a2bfa6a5,8429db90,fbb25354,3e77ca0f,e7a731d7,f1a481bb,f1c997e8,5f585844,423ace4a) +,S(fbaa7567,7306fdd4,8c85514c,bcb78e04,ef4d693a,dc7c356e,f95ad34a,cc880db0,45c4972a,161f4a23,cd71f726,d5617b71,421b68f,b0611097,3edf11b3,8a391909) +,S(5dd76e24,e3cc0c5b,ded55d15,858f1c19,dfff7e43,b299df43,3ee77b46,2122205e,992de68b,87bd6760,a75d6b90,89dcb2b5,5f0b39c8,eb079ba0,e4451fb,dee8f2d3) +,S(890c7a78,d0f1db95,75b53e98,a0a63d81,8096422a,3ee18403,ede8ffa6,3af9418f,7a362df8,7430b479,11e8d310,558195c8,fed28b05,531b68a9,1631ef97,ac008085) +,S(4914f692,f88e858c,b6174e6a,9d4bbdf9,87f0e373,1bf6e69b,8bf3531a,43a37e6c,8751e02b,fa9e0384,2ff3e4aa,307cb7c5,fe4f7941,1069249b,c8b19866,b6169cf5) +,S(a5f97745,ddc25117,81693df1,bd15203f,9d23bc93,9015be73,c6b4e256,d1d05416,57a99674,cf64bff9,7b9ba0c5,69d253dd,52aa188e,3ec645aa,89466c79,5d0f0370) +,S(62da0bf9,8d32519c,16fac809,95869f09,b570b953,e0a7bd83,9623a9c9,bebbdf84,9b9ec74a,c960fa8c,2ea8bd4d,93ff624a,9ce54fa2,4a1822a2,37d962d5,64e9121d) +,S(5caa2062,c25d7df2,23718f9d,ff29a403,e5200d22,bf064b44,c9519742,4c448a5f,6063bf93,1f72f65b,9ca76400,de5f5204,a8a0bdc4,b19cfd12,2664aa33,79a7a27b) +,S(4a81083c,c18dcec3,5825415b,2854250c,9dc651fd,5d897610,2ceb7691,576ebe60,850f48f8,7ffbf26d,eaad1f8b,2c0b8272,5f7c313f,55811b98,408f8f34,8421f241) +,S(ba8baaf4,9d0c194a,4814070c,786fd9f,4b8dc012,c42ed667,7b39f67d,da7fccaa,ceaa8874,10bbe854,9e87af6a,15ae1326,d85bb995,19a8c4d5,dd3a8599,d9ae0ff2) +,S(4c780a0b,886fdcbc,a30f239e,21495f9d,5ea38a6a,7960ecb,ea4dd2dc,9266103e,7e50e1d5,b6c811fc,f86ee651,5d64e06b,26827ba3,656dfd51,1fa64124,224e182a) +,S(50a433f7,f528d66a,961d7123,7e6d2bf6,7321896,5ec6599d,b1f34b0c,db21524c,6bca1083,9ef8d450,e56829d0,cb23ddcc,81e2e7df,e79b53f3,2f8aab9f,e2eec15b) +,S(b98e05de,573e37c2,80d6de1b,fd479bf9,bd23a6b7,2f6ab34f,caf03236,c67ec5fa,d86f07e0,8a4c3d61,f087dff3,a2af2d98,58787d2f,424b49da,de0c584f,4d8756b3) +,S(d0cb5279,e76b8be9,b2e9cdd7,b0c841b3,33398541,24923224,db54a91a,81995433,11fcafb7,28a3307d,2d87f2ae,d107b0b,d64f6030,b89e845e,1f67ce7,4cf7ee6d) +,S(90c89963,619b1593,d5fd7eb6,751ef03f,aa7c6802,46e36bcc,5d0bbae6,25376720,6e8f2a86,75b803f2,c3c87f9a,98318cbc,61b99073,2b8b33b6,62197ec5,73f64a71) +,S(bd3ad39b,989c3a08,e45007d9,116b0d4e,2dcb6a14,26a44dc2,29bff230,6c1a89be,7e633d7,de03e6d6,a7a4a833,f338160b,cb914997,6dc2080,28c3e2dd,b1c1b11a) +,S(1da5082d,a6e4721a,499d5559,91e8d216,f26167b7,d6de224d,17bc4e5b,ac94093f,5f864511,4b89eb63,60ef865e,6eb887c2,bb0b97e3,9a0b7078,888049c1,29f63c77) +,S(19320416,52e24197,d195a0f1,99818925,35c19790,99d15992,8999073b,4028d659,2cf34c91,2d1666fe,1abd3b0,49b12dcc,f7086e58,b7700b23,497bec18,e057059) +,S(79a7b5e0,482523d0,85bf574f,2e6e431d,b3bd6ae8,4e921b87,fff0f683,976efa9a,f713e011,70de0de8,a8cbe229,b147cf82,efc7fe3c,d7171785,c85bbbfa,ef935755) +,S(c2e16cc6,8559a160,9fe16d0a,9be4016d,55fccdc4,2d22ee62,895e0eea,a64436b,22399345,d40c11bb,79b9f036,5fdf6a91,4e1f43e9,bb1f0a87,81d2ede9,fdb6a118) +,S(f76c0f67,bd3c648d,c320125,5c34a93f,ed656378,8c9f61a9,c60933d4,e2d55d7,205c9c5b,83bbf922,8e99191d,e7ef0feb,429050e8,2b9fb3ca,1dbd2d5,cd35f612) +,S(24a3af8f,ee393ae3,2c30230d,ed6f96f2,9797d591,1cc3d934,b16e1304,de7bd75a,302041e9,2ce00cb5,d4a667ea,90df7f90,576865d3,7f462126,400c77a0,a44259b9) +,S(2e8bf897,5f29a6ba,636e6ddc,1e2dcd6a,1373f123,c6f155b3,3c8f46dd,b18baf7c,a93f0c91,258ec64b,d6e18761,872cf0e2,c89f9713,b9008605,b0378f8,1ec867ae) +,S(a5d35483,7f90d71c,8d829897,b3a8fa36,7c38b41c,879a3e6d,52f2988a,b88dcf68,853a586d,9661cd50,12d1ae6a,1501b874,739405c4,c7e32bd4,23ab7c1,62382bfa) +,S(51a6c879,ba6f75d9,4480aa71,2a343be1,bb9aebc6,bb4ca3be,de16d33e,992659c7,3e636d28,f8b0a4fa,a3ecd585,80d46253,61f496b0,344382b3,5742fcc9,403e7e05) +,S(a1d34e3c,aba45bf,1772d2f4,bcacd17e,342b66ec,97dadbd6,780cc453,ff2449d5,6c3a3b8e,9717365d,2f21e2ef,d72308b3,45008ebb,10ca02e,969d14c9,1aaf677c) +,S(fce0f1a1,69034370,33de7e6d,b2364b0d,4441c5f2,ee405e68,5dc546c2,58adc2ad,c018bc7c,fc5ad1f1,36103729,e1a177a7,495a6195,915ca5ae,c086804b,8c107865) +,S(e380e6af,c47b11c5,1ba0c8c3,9b796179,39b07cd9,988896c,38011e73,a4f98a81,60ecd299,c22fbed9,132bd455,1f44022e,151927e4,7ad93f1a,a0539c37,2680f6cc) +,S(6382fb8b,2f4179e3,191d863b,a0ec4cd,94b52103,f24a0377,8f6ee27c,7c81115c,6e8d4181,9621bf4e,3c04c5ea,2b4c0146,dd0ed973,bd4530df,d671f39a,e54db63a) +,S(c488650f,d66629fb,927dcb0b,9f5d0771,1caaa3f7,ad6df39f,7d8f98d9,65490aed,b395d9fa,46475b16,6beed01e,90c9cfd7,83e6138a,7bbc6d5d,f919d41f,3e512c) +,S(5cf1f5be,462dd02d,f8d1e9b,6cb1540a,4f1e5be,de9c8d29,954bfb0,217e494a,5e8727bc,2429c9a7,5123967b,b598207c,46105822,5402bfcd,c3d070b9,b2351d20) +,S(9644ace5,9dba2b1a,f3f3a4af,da130ba3,c3bdefd9,39c3b52e,670ead47,54407b9c,5e83dd4a,e338fc0b,8c501f98,72295400,4b2465f8,4f1c272d,20e3a2bf,300b1b79) +,S(728e6659,f0bb9bd5,916846ff,3aab6f10,85517ad2,c17254e4,c2ce908,c7934781,7df32327,354020,319e9cb7,696b0384,6b8e5bf6,691cc73f,829abd42,44e674b9) +,S(80e68c8a,31d715a7,5068091a,142d4a60,ff30d2c9,42f625c5,d234bb78,31009e8e,fe04addb,b9c47f69,3dc0b126,67b0960c,1b4a7bf2,882aa626,b1888e5e,e4157fd9) +,S(e655129e,90211425,558cbf1a,4eeeb630,df68a4e4,f96a176b,db55500a,89f5af02,d5e3a471,ba698897,9f747ae1,a1aa87e,e10c5069,3df12ed3,ed52307d,a0202a69) +,S(30a9e289,f6ab5edd,7b56f48c,e7373a6a,97dc698b,511343c2,8c5c217c,de67ab6a,f4016c18,c4f75d52,927127bf,c403a83d,4ce304d2,8a4fb965,beef9fda,4e9d3f4e) +,S(8a6a4557,2c1dba29,c9499ecf,d59ea43b,1ebec5a8,78a3e2c5,2de09aa7,c0288e69,56e4aceb,e8315c2f,b9271519,80a21d,c17ebad,63223380,b24a7237,33ec205b) +,S(647d3443,9f4e4f50,cee5b0d6,8047f130,965f8abf,482f6166,8859c86e,326c1bd1,f951b5a0,b180894c,f74c5235,cc625888,fb830382,3b0d085a,dbe857ad,dbc22088) +,S(6d143d17,9f0a42a6,85031c6c,f62ef32,2cde46b3,978b04ba,bc37bd3,34de5634,925d0fd9,11c7863d,b0ed42c1,76591307,72b456fe,83bb8063,3afe5340,cab4b5a7) +,S(f21cebe2,7ce8dd3e,fa30428a,cee881b4,d65eddd1,30f9fa62,9d78291c,a4f4b0bb,4a6d7f43,f2ed3d26,330e58c9,27a87c55,850620fe,1edc6e36,c9a3978,8f922ea9) +,S(37883073,e227a5de,452c7706,a4a06594,5a891c06,e594fd4e,191d36f6,79117c35,224bb4cb,389f3d25,42411fd6,594ad6ec,bf4f1c9,11f723e1,53dbb420,33ae8ec5) +,S(c21520ae,e6cb0358,53a7da78,919c88ec,84c17d10,3ac13ec8,6a412d9b,96e57c54,56720dfc,f748ca09,e27e8aa6,e29ea591,c0205290,3d38bc35,3b0b0155,113a5bbd) +,S(96cdb3f0,d6194675,7346b2a2,1767fc01,2e6d1ca6,f5e788d2,f89e2fd8,89a57924,9f5fda94,e0455b28,1cccc531,7118b175,edd6c93,c212e7c9,fe845f0b,cac5a592) +,S(7b5e5f5e,564606bb,a71b8f1a,7d410b1e,6482f508,879e1bd,38ecdc44,b7effee4,92a3f1b4,84ddc60b,4b005282,89984241,4f91b9bb,fd55eaba,37dddd0a,dcc1c6e) +,S(541fd344,c9d553fa,1e87c9cb,72150cae,a69a9a10,771ac96d,fb292be7,261912f5,80ef7a00,6ce5ac0e,975ecd69,601fd059,a9860e07,77f6f31f,365187b1,f6c9b392) +,S(2b2b3929,50b07da0,5c20b72e,4101e36a,bdfccb6a,2a7f36d5,b57f58dd,1403035c,ff6c1ba2,caee889c,14414086,456f096f,d065a7d,d2f9c7b0,9ed4eb71,3b4002a0) +,S(23acbca3,4754dffa,8cb3176f,d1435d6,4cba0deb,84e12ae7,adaafe88,497aa60c,5d95b3de,26f703a4,fe9efaf,cb273921,56a49687,a71433f6,9a2813ab,5fdb35d2) +,S(5fdfa393,6bf9c699,24417a2a,f36054d5,95640b6e,3ae30807,5ef51bb6,cd63fe34,97fdd994,bf74c959,2a5435fe,f1baea41,8a79c5fc,1243fedb,5fbb0466,4d599d04) +,S(177cf8ef,58aeefed,2832d53,417c7025,c6b56fb3,8122ccc5,2b33f79c,71c461fd,d8a12d8c,69da9b31,832cc10b,55b57a60,b900c19d,f8f38c92,f6bccfdb,98d3acf8) +,S(14f90282,e5a3121d,a59e919a,fcd146a1,9251cf5d,c0d805bb,bd013eef,4ab78bd3,74a504be,928ed13c,f29032e,5c3dcb3,a18a1df8,aad26b4c,a64ebabe,6afb4244) +,S(31099221,e6ceaf16,81b22b33,dd8ee3ef,1c2a95f7,2bed88e8,15333f69,f91867b3,772e45f0,930ebd2b,7f5b7ca0,640467a0,8ab5472b,f6bd347c,903cfecf,8f80176a) +,S(a6a0a416,d8eb22be,49036f4b,dfc79c6e,6cd167cb,38813269,70e199ad,c5d1b5de,54d036de,6b84f308,84faebee,4f944375,fed61a6e,7763bb40,a283ab52,3335af10) +,S(c7c5cb1d,ce484477,82e7da9b,55bb8482,4f715a80,d844294a,3c05dfd8,3dde77cb,bb66731,1bb0c2a4,e493e257,d289a42d,3630ee24,ba0f7f86,134a7c6a,72dbc3df) +,S(f1bdcb49,43267948,fe1c9b7b,51afcc79,7027e4fe,f98c2175,d7d1b8de,770328b,271f57bb,a9249cd7,dc510173,5a2168c6,ea97b341,b44cacc5,4083d115,6de8e728) +,S(2815f09a,8f0e2dfa,d21f50c4,60b8f69d,3aad54d8,aaa99226,86050582,b954d912,dec68871,752d862b,32ffdf2b,482ce1c0,6a659bcd,3a2931a6,29bda260,cb3cbf35) +,S(622619ba,8b74a0d0,5f8fa899,aaddd272,c9e6d43c,49bb6708,367155ec,4907d0c2,aab9b1ad,10201d50,7bea05bb,5b20453b,6474154d,ebe3ddc0,c86535ad,7c701954) +,S(a0390604,a40611cc,6e36c81d,30cc3e75,d162e695,1ae0515c,75417744,c093b997,60428c28,8d32d229,7417b6d9,b1003522,8190a83,66cae58,f7887037,9fb99641) +,S(422c7d1e,b0498cc4,dbba0135,ababc80e,5416f187,11f0dff3,80f1e1dc,23bedf0e,9c47d3b7,eb5713dd,cbb9ec8a,60d931c6,3382452,a4c0861a,847a354b,ba57d9f1) +,S(982844d4,7f572298,afd6734d,98064369,d81e4851,4b176059,6d3a1e85,6f043f5d,9b86f6a7,678cb5f9,a4304f1a,a8d3458d,fa85e65a,ffc79da3,faa1fc8e,a2b7ed2f) +,S(993385f,a76b9373,422e4411,b9e8a85d,3ac0e09a,f9598570,63d50a8,67b67ed2,3e7a9a3b,222a66d2,f55fce7f,e33effbb,bce8cfc2,8991d8aa,376a8ce2,4e9b8460) +,S(15b05ee3,179d1dfa,61bfb0d0,1903f93a,f7e04f98,cfd40be3,2ec094d,1bd5a4a1,ed1301a1,451cecad,30e8fadd,801c9db5,5acfd697,3ed36621,2f2e3032,adddd939) +,S(6062aed5,7d6312fc,433bf7f4,9c10772e,829e294f,e7ad07db,177c75cc,9fe5e52e,96aa4495,c6eb07da,9a5a0e19,8771dce5,23a5d7ff,de314562,3b704f44,c4ffcd24) +,S(ef45dd6c,1213ac0a,5df18426,9491cb3e,bb5312d3,fb55c7f2,8351c98a,1ba564e3,91541d32,43e032f9,450f3605,cab238f2,703a9eea,8e429824,7a6ef63a,45540e68) +,S(a1e32dcb,c3a13a46,166ebb73,7e09041c,3487120a,6ec46987,6befb2a9,94f4a69a,ba88b7b1,8cdb2088,b5998b34,461b8a5,d85a57c6,31aa10f8,6ff808e6,3186e5ed) +,S(817e6c2,6d4ae706,f43ddd7a,cfa4eeed,6498ea2b,86aa661,9a0b45f4,e22ea33d,8aeed38,bccea5e3,4923b959,53bc9629,d9348442,4f33b06b,b02c882,25e47bf6) +,S(e734f5a7,736014fe,2ac9137f,d025f914,7574d67b,3696596,9f89b5e1,aeebf88d,74fe8220,7c83d3ba,ec54f032,f11f9309,9be25f53,565f0d60,5f2ab406,5287c997) +,S(87b2d307,414c314f,184eef07,6e9809d8,ea19c002,390b5047,38eb7bbe,ba1ae7d1,37f5c369,f5dd54b6,87729036,b88dbf37,45f33da,8c2bc9b2,64213468,f1c56841) +,S(dda23ad9,6c51604e,602b8e6e,9f08a67f,981bfa98,93194369,269c56b7,7986b772,6de02623,5ef973da,13e2577a,bbcde720,aa8fbe12,23c5288c,5724bbc0,228074a2) +,S(8d56a723,6adfe6a1,46182431,da5ff846,aee78931,27564954,f14172f5,27048fb9,c7cd6bfb,fdc51a83,252d4e4a,2c978cd7,67fa3809,521678cf,7dc5e514,eaf0b418) +,S(9da30ccf,f147de11,de528d14,863a4fcb,a2ef228f,506aee98,eabee895,eb618def,a4ab41eb,a16b4733,34a818f4,b6bd3c43,de4a9392,c15c9e19,a8b4e961,7fd4bbe7) +,S(e3339c3a,b14145e5,40c08544,eaa631c4,7be6c09e,563ec93d,2a05f219,f4afdf2e,fd586d7f,3a668a0b,f888083a,9ea84f48,43598417,f55dfea9,790ee89a,c412fed7) +,S(a6e08d07,66274337,f3b139a8,d6fc3f61,4dde9ef7,2e03fc52,45f7dfcb,1c0ab41e,d9620b61,116af945,708a610,c78f0b52,8abd97c0,21ee34fa,10d289cb,f3c06d4b) +,S(f8ffa0d3,b463fc5d,44e6eaad,caecaa85,8515bc4,69fe76e1,4ecdb25d,e503a040,e80dd6f8,934fa405,fd4d74b1,1da0d09c,dd723df,daf46221,796cd7e2,4bb83f1c) +,S(22a212a4,3c00408c,b4b94e2a,45a6a999,917c0fc7,aaa565d,c6f982cc,64b0d0d4,663d8ed0,3128ada4,f421853d,8ffd8201,1ec8b997,4b0d827c,ed318551,ff9930de) +,S(8d33b62,f162963a,f6636f18,ef33a83c,e9a17fb6,b1fc58de,6d271d,472a9d82,cf0092e6,60311726,e0856ff7,1893555b,625b117d,4698e4f3,f31611eb,21a56f5e) +,S(3bbf59cc,5b4aa31d,dfa0ce94,1853ff69,9db29cc7,a0021cb2,11ba28d0,1dc61d3f,d54beb79,d1edb94c,d6bd5ae7,11a3ff22,9f2baa0b,efaa139a,e4724ae3,624d8318) +,S(4cc9c2ed,3a7266ca,faffb517,d3ad4aea,2d4d877,d9b08433,a4fca2a3,691aec68,70ac52d6,1094da70,5f714f60,854a5656,8c25cb13,1502171,7bd4085e,8b489756) +,S(a997cf82,50d7ec36,125189bf,eb6b8631,cec31fdc,f156d34b,186f29c6,5d0b30cb,ca73d95b,93b43983,b2c51518,b4e419f8,415f14fc,b6356287,cd65d49f,92929d5e) +,S(5fae92aa,7c43ac60,b4bb4f90,ae2ac462,a6f88681,9aeada99,4d0694a3,a6dc1722,6b7ebdc4,dbe15dd0,9c1e4587,c7f297c1,74d5c933,6bc91511,f31e0cae,2e51b280) +,S(cf541216,323a9591,13561470,2b187b35,fffaff7d,8cf1993a,5144c7d4,aa836308,9d955733,feaab81c,4b03fe4d,25fe36a2,5075357c,b6ebf8dc,1822cee9,7f585f80) +,S(9c2c8607,bad80760,efb4ba73,442a359a,c1cb9b45,f81e54be,28f3f6f4,4699773e,7848812f,f3101eed,137b4dd1,4f503a42,9d71c157,449767c6,a5850204,869a9817) +,S(2f3bca36,fe504b7e,93f70176,2e65dacd,250b3789,541076ac,86352481,c896f77e,5af55f5d,b2e84dfa,38bdd0eb,fde7ea68,33471d28,add88dd2,a7e7c63f,dfe513a) +,S(f2fa3afc,fe4e5da,385f26d8,1848f801,7401b06f,652121d6,9468d2ee,f640260f,54cea12a,b4ced3ee,2ca351df,4310e96a,d3ca0d80,c3a3c86b,267c4620,bd0f69a2) +,S(82559cc9,ead1465f,a910b781,cb2a50ed,9a2b6ff5,d8513182,425b7dfd,983afa50,db5dd99e,242287bb,c94cd149,6e4aff70,7232e2bc,1fa4c440,5cd9f22c,fc4d239d) +,S(954079af,1494e324,fb707e7c,e9f1fc2a,751e194e,4ee058a6,e55e26d8,34901f5,2f90eb0f,43bfff96,c3b0f3a1,bd48c00b,85d3650e,52d1f614,ed65ce70,4fa19e99) +,S(c913a980,b1aca09a,19654428,6edfed20,dce31676,1fbff05c,1c05fa70,7eced342,17d2864e,df39460f,99b5b51c,91752c57,10ca7af9,a6e10c4e,c2b3e9e1,7317d3c1) +,S(815b7dfd,3b97ad9f,cf6ce427,ffe4a91f,2b541e2a,11305b17,2fd7b63b,82272db0,f0b958eb,fbf32959,dbc407bd,5290ca66,6f28bcec,2fa69d1a,7108a2ea,19d58484) +,S(7f7c1689,e93b7c77,20ab5b74,572e87b5,d2a907bd,624fb6ff,d5f29f3f,c64795d5,691a2f46,430c53c,375829fb,46ed4030,b5bc4dd6,70646523,45fbadbe,e6f8a1f9) +,S(8911275c,106e5a48,1c3dc5be,b9b42e2,3be8cf2a,5a76198e,e6749b24,bd9c5e7,747cb0c2,16d899c0,da5a8ed8,f279a650,f4537e7d,ca51bf56,b3ca8c43,92b5e99d) +,S(24cc2552,c907e757,9e85bf7f,fc868ebe,53e44b97,102b31f2,38678bb7,ad8c244a,a152808f,7d615060,ba9e78ae,720c2fca,a67772b7,fd99ed6,ffd5fbe7,ed114567) +,S(b0fc5873,68795dc8,55e3e19d,9236244a,812d1920,afef4c9,7f1e6c79,25395f85,f8b46879,5a0e40ba,2029538a,fb7cef58,9bde7b3f,fcc010a4,4ac962b0,afb8d7e4) +,S(cd6f4558,d634fc66,6dce566d,f94397f,d3ab9178,affd3707,55852679,adc6565f,d34d7be0,ea40586e,4f9007d7,4aca55e9,edb4b31d,8ad4f344,1f611a9d,94161b8a) +,S(fc5e8a3b,ada62f0b,6453f445,7dd4aff3,993005d6,de7b94d7,19fd487e,b88fb7a4,46041321,f7fed84d,2266d4a4,d86d836f,12f12296,d62ed296,6a7d5507,d6717130) +,S(dc72a540,55c962ed,90e64916,bdfaf6ea,aaaacbe2,fc180a7b,7e7bda98,f45488d9,e3b46394,41a2063e,59c4cb06,1a0a7e5a,a171fe39,812922f8,c04df63f,41c8e588) +,S(7d135c33,88bd5896,47f4cc3d,67fc7809,a7a4c530,e96fb5c,7dabe3b4,32a4fd90,79dd3834,8a61b642,9eb7a837,4e9c2176,95cff14a,3596a18d,19f84360,8aa0922e) +,S(7a56712d,b72ac3a6,353dad9a,15cfc9d2,7d9ff67e,9a35936a,e38e1c01,5980980f,6eda856b,9b5d4019,d0efb2f4,9f1af933,8969872c,126b2682,f56a8b08,97a83696) +,S(d3495480,25c7f966,d59b40d9,6ccb9831,2948c992,fcbe2f6a,7a7feb6a,946125a9,b346f8bb,532da4de,96908618,b0f85a10,fe9a87a8,d612e4ac,53bdbaf,9dfdb3c) +,S(22175a8b,d0a51763,d1818054,60951698,14af196c,df8648f5,29d27a9a,825e60b3,756d5713,81b5ce71,e23c0190,a1062fd0,645eddd1,7dc84c9b,b1c7d810,c13db63d) +,S(f557e381,37a1c6e0,a19e4207,4a1dd59b,17c5137d,97a58fc2,55d18be1,bf63877f,6cf0bb41,577ea3bb,7c9945d5,db33a862,3c1cce5e,d6fc13b9,b0739ea9,9af10381) +,S(8ddbadb9,c6a78978,2540d3e1,9ada3ed0,5ef35f45,a38be470,7083dff,75d501cd,75b4c5f9,51f70fb8,a89fec5,d52ea0b1,dbfc5709,3c1ee5eb,ff2ab0bf,f5854644) +,S(53f0892,cac79f48,2194dd9f,fc076305,a8ecdd4,977ac278,92e2d454,965a2aee,b39f7a9c,ecdd4ed6,d0fb1608,3b86d1af,68aa85b8,c733617e,5e97ecda,269ef97e) +,S(2712110,8fe28f55,c746525d,e7cfd4c2,f3a11b8e,3c6329db,a57a7b32,5a7edb40,cf6732b3,74681ab7,3448bad0,ae54b953,ee5d7bb2,5a8658d,3b366a78,dae5fa69) +,S(e7627b26,ff0448bb,cb45a538,2ff8ec9f,9376127a,b8425213,46e899b4,41cb5660,79842f72,e02820b1,e6b6843f,3a0c23dd,c0941ac2,b6fd30a4,39397ede,c78bc40d) +,S(37c48874,f07ce0c6,cf5be181,9ba31bfd,9a19aac,97b27011,1de59fcf,559fcb57,34dcc405,6a6dfa3f,283e0dd1,8b1722e,bad0e367,c30d9f1a,d552f394,9ce19b22) +,S(316868fa,33cf5544,1e9b9bc0,9f74fa1f,8daa9058,3fb8b3cf,8d339971,311eddfc,89fa5c82,9d9f4687,f7cb6b8f,ae20d6a8,cf872ded,a7f9b6e0,6e168c1e,45db4e73) +,S(d34a83f3,7b7673b9,6c8695f1,81ce837f,ce2f15b8,72664d3b,1a045c7a,bceadd44,e4f2cefd,59198808,15692950,19b9120b,495a44d3,4862323f,808b11b3,a8698081) +,S(687a48cd,4142060a,171a1efd,c41dce8f,8127ab64,ebd7c22c,7803f077,19168799,c082e152,41f7db05,ae6c1e15,e4ccc340,f4a7c8c2,cfd8bfb1,6bcd04e7,e635726f) +,S(70d2cd79,1d2d1418,9cf67e48,519aecb4,d58be2af,164d0605,2132517e,87f444e5,73b4c12b,edda1a70,89ae9db8,f105059a,2a558475,f5cf4796,1042c470,c9e190a7) +,S(2a6f2786,a191130e,dba1307f,f1bb0f61,c3d7b8ad,c02286f6,44871cc,170dd2c1,28a0c85b,8ec93fcd,1b9a0617,780da654,e5448475,a02a6222,f7065132,5ad64b2a) +,S(3f482e12,8d5bfc4e,d2f359cd,b4244db7,ec7edf92,f3fc5dde,5367d125,dde8c772,d41be140,cc4b4217,cdfaed4e,b09ce5d4,d3e95b52,ed6689ed,3f6dfde7,3c581cd4) +,S(96673e27,fb0f8a46,8fcc53de,12876045,77786d93,5afbca99,35545363,6614a5d7,f6a4eee7,1c4249c6,ef850090,59c12f6a,44adb8a9,cefe7a8c,ff2ac0a0,da28884f) +,S(be7a886e,499a9c2b,c05e5f64,77bcbb4f,26772e58,4565897,408eb36a,e25a9c58,24457eb7,802810f4,de64516f,24718b06,d61b0adc,bcf0d279,d883b2bb,45363a40) +,S(123985af,a3253837,e51f933f,8f25591a,823b2442,88cf8ba5,a0247ec9,94eecee4,a952096,21f7a9a4,3867c6a1,987dd661,1d3cf996,2aebfadc,dee0a5b8,6df196b7) +,S(75887ee8,c28bd2f6,a96086d9,aef71b7b,5a5fce50,80c3963,787089ed,e39b0214,47386fd9,a9216193,3bb500d9,a1ee8207,dc3edbc,17d3ccc7,32d9c90b,8995eb48) +,S(4f7642fb,12376864,29104657,2a2fffe5,2322df39,7cc097e8,f7a57816,e6709fe2,4f2ff70f,2e99354a,60cc5b2b,c3ef33d3,7e3e9ee7,16766018,e3a0ba39,efe5f971) +,S(8117d4fd,551c9ae7,4c9fdac4,5d87bb66,9bc7dc35,4b08de03,7c4a1378,734653b,13633743,d1ee8fd7,8482e3a,3a9e39e9,75b0f6a7,efb227fa,84feb897,693c5c10) +,S(8afabdf9,acd49723,d73c0deb,1016ddce,571abaa1,a71ae3e9,a20bcecc,ade5782b,2b66e3fa,ee86dde2,23dcc7b6,10ea8ed2,dd42124a,247b7937,9e190098,2580c71e) +,S(c4819cb5,b5af7aa2,895b81c9,31dc6bd1,de4a1434,daaa4fbf,abfca6d9,28c9965c,ae4db5d5,e1a09a03,67df8c9f,fbd2ae07,9f79ff96,410a9a5c,17229fe,5575c22d) +,S(dae02e8f,5d106f77,c8a1e1f5,4366daee,d312da83,1f86dce2,3e846e30,737d49f7,6d666cf4,73d269bf,aa7c3eac,4e5a2868,57df3661,c949b5ea,7f9a7a0d,11206bb8) +,S(a8762d34,c6f8317f,cba5c64c,68e25d55,e5bf7e4,5caadb65,a5468d2e,f9d779f0,6accd443,bb181cd4,591f8fca,210f9996,86460bcc,89dc06a0,2edd7bf3,d4b75533) +,S(bf503c35,fc8a0c55,fdf4149e,96b2d218,d29e4b9,1f703e7a,9b0d4da5,4153d99,7e1c09ab,a1437e02,a2be3d4d,7a444753,e475acd6,e3a42056,94e68ea3,cb7d1847) +,S(7898067,48cc0ad5,ab3a3449,ac82a1c7,d51f2b96,791ee038,dfceae58,ea0c5cc0,66b59634,96eb4a69,b87aa0da,2905449f,ffd2ae3f,ba1555f6,5c9b8ec0,e94ad922) +,S(25833d28,addd8172,c2a323d7,cf498482,732a0be2,c10d1895,8d097cc0,ff4c9a19,74708306,d01258d9,bac99a69,58ce1117,f245d6f1,4a1f92d0,dd48ca9a,4c7b7da6) +,S(6800bb8a,9dffe170,9ceac95d,7d066461,88c2cb65,6c09cd2e,717ec674,87ce1be3,d5228e3a,1e0bce22,c2d85b44,e670e78e,ffb1ec69,6c01a722,2cd1e62a,dc4e63d4) +,S(3d7d5874,42e4816d,af2f0897,dbb06cea,f6c673da,445a5342,c61a8793,420d107b,422b212c,93ab83e5,d6323ad0,35a55321,b7441835,b83f180f,c3803ccb,46fa4ba4) +,S(3c44084f,aeee2803,34db27ea,63339db3,9e8359b5,c9cc9a85,7ea49740,32d063e,36493b7f,1a732a87,db4703bd,61a76825,4a82846f,31d8920f,2cba7ecc,1d744491) +,S(cefffb5e,d26cf721,a51bfb2d,460b91a,a0b40a81,52073da2,cb75050d,f7fe8d19,b4e40e1,1eac7572,efefac2f,a97e5cb2,a0d042c,3ae8c541,e51be4bc,f6d33f4e) +,S(63add0db,5f5099a3,2f274c38,780cc215,bfd58753,144bd464,e75b0da2,dde97938,bbed5231,fe6d5b4,9679a13c,c3c6c382,5c300fb8,42b5eafb,13355c41,120c6848) +,S(ba5d1f34,63130cfc,425cc6db,dfe08329,4d7aef4d,cb207e3f,d1cefebc,7c791920,70df29d7,8030a8ba,56514df4,b6ecbd2f,ebfaa1b3,df7b23ea,ed16458f,f2f18786) +,S(7d363dd1,c6dd28da,94a7f850,ee753327,8b735dbf,f43e9456,67fc26e7,af75d6e1,46026468,2bd00bad,a5be02aa,5034e762,fe50d02d,6cb8dcdc,5aafa21e,423267da) +,S(e2dc0164,c9060646,904206ff,37f912ce,2d50458a,3ca186ee,fdda8d53,4184070,de5267d1,354d12ad,8d9a5930,443dbef9,65947f2a,5efa206e,146e7b1e,df7f5a2d) +,S(2e53caa6,35f0ad1c,7bc4c2ee,1e29b39a,972edbd0,7d3c0feb,9ab0d945,45815ee5,1bb33d23,ad85b572,130e93d2,fe366e49,8371c49b,b47ceebe,de3c1286,3f443b23) +,S(5dbefdc4,9fabdf50,e6bc1464,13d59940,cb36551e,5a6607bb,13213ffe,b56eba1,893fd0a6,1797abe2,fceb4054,c4f540a4,ed644ed3,13a2200b,e1d532db,44d0374) +,S(5ff207e4,2b52b004,6ab8bede,6bd26f5,316ae52c,d148965d,8a21e8d9,63374a2b,1b778704,daa94eb7,a36ad0e7,22a6d56e,c0b43c7b,a739985a,538bcc22,b9181bb4) +,S(da260b,ff4bfb8c,a54261ed,c96493d3,ffa90273,a55538dc,c9b237ec,e775fb3c,c7c744c1,dbe1cd19,20edbe3,c13f7631,1378140d,9ee64c3e,ab072401,86c067dc) +,S(b1985ca2,e7103268,f18d1063,c59d8d78,2250f450,c467d7b2,f4e41c28,1714421,16357630,3970159a,99a34c0f,e114b95c,f115d9d7,dc9b09ad,7c81d769,aeee6898) +,S(bf98e773,fe93f15a,ced03ac8,368e4276,1cf3821b,461cd844,2426d2d,cd1f7d7c,f4fe02f5,f45a9cbb,b67ef626,f239bad6,e5108c28,d783d70f,6bd889b8,6331185a) +,S(5dd657a9,ff99f15b,56c5143e,86ba7bc4,b0f34957,71d91805,71a3d003,ff008fa0,8da0b780,f644b14d,2b661b9b,484225b9,86b13038,a8a9bdf6,6999144a,4f5c212e) +,S(53b42d75,bccf2203,7252ee9d,25830f3e,36e7ed8d,8e1b6d4c,b2371e14,fd4fdba9,7791453a,dda2ca19,a775d684,9ee60c18,ca495808,6f8b56e5,1bf2b216,9690cd73) +,S(a3f43f6d,eb178109,cf4aaeed,a0666bec,481a1894,c25a4fc7,f4a87e82,680d63b2,d0331e73,7dc25db7,35625621,85073240,3a69a474,d5f78e54,93486b5b,3d1c067a) +,S(b83bea86,b07b217d,ddac9cde,9b42b334,c994cd1f,92beaa87,57a7e7cd,2c71b1eb,b68f8fd,66b45aa0,dd568458,73eb7829,1e613569,58345fba,7dcef9ee,dab957ca) +,S(16ce1de,573b3654,a0c00212,e878811b,25832f36,373da91b,9d9d7c89,d06ff12,264031fc,7441fe5d,4ce8ebc9,232d1837,7fa810a0,a0e19ba7,5ab16ae5,e93d5763) +,S(18fdf98e,93a7e380,8762e819,2b6e634e,f255b2ee,51c65b58,1ab799ff,52409e15,2d71afd6,c6298868,52ea0a1,943dbcc8,ff844ba3,80b177e8,62f92852,97868dad) +,S(3d5f8af4,ff89de18,866f596b,91300a32,a7aedcb2,a9423f4f,e364cf26,e2f53e96,46e9bc8c,ddc56d4d,ba25a2f6,e77a6a70,2e712496,7591725f,1d240e7f,9836548) +,S(69dc1e7c,11516a15,9edfa4bb,1afe0ea3,5be5b7a4,7695df8e,728a8dac,e2997db2,71be8ddd,d4c51c1d,5c13704,3aee6129,9541e929,799f7b6f,da08aee4,52f4ce8f) +,S(4e8278ed,ce9b340,1ddb1c3c,6b208539,164e1ad0,3adc082a,8d9dd5a0,9c63f737,13e6a5ea,7b2e8ebe,babd812f,2579b8bf,56b476ce,dd23c418,9be7b85a,940c5d79) +,S(91157569,7aed20df,771c1f4e,78b73dea,c89b2781,9b8a5ae7,5e2dc12,e6e7d148,e7114d60,218eb1bd,73074957,5b96fd10,50fa2d09,f37c0fe6,2887042,24ca1a28) +,S(3a37e743,bd2fe2f1,3f667abc,b6c03077,fd82722b,859d7bcc,ebeaf1bb,a6087d93,4192a6b7,eef51034,64040fb2,6b8d9928,21e321b8,cd611b4c,8d3e0186,646f5dad) +,S(d45b5787,9e4732ad,ad0996d5,879980a1,fc8dda5c,b628435e,96c3b44b,faf98f09,e4d4f5ac,1e4b039e,731143d7,60e2ef35,dc243097,d2e2382d,b86dc82d,eba0554a) +,S(ae5ff450,aa607a9b,bf4549d8,4d96adbc,6041cb0d,719793f9,2ec53b96,14522a00,2f061b20,e9bca3af,358e8d14,a04f1d82,97d1e1dd,a406d60a,d15727d0,66b2b8fa) +,S(befd3684,32785d19,7709ec42,e3b6407c,7a539b55,d97c8fe7,afd4f96f,d2050e17,65691153,b2efb4af,ebd2dae1,a50fd3aa,b648c7af,f5804d99,5270cc22,c02e151f) +,S(d13626c,bc00cd,36c776c7,8bdb17c8,18a2bc14,9612e0fc,7ab7888b,eab48382,ea4c3fc9,fe2238f7,1023ab83,fe0e09a1,dc167c0e,6aa05933,8f177cbd,241bdd45) +,S(9730fd42,fa9ffdc,414f90dd,ac790110,9619c01b,f43bfcab,e65a341e,2434435e,de61024,6152fb04,c997fd62,961209f9,44badeb3,6ea7774e,30e8c8a0,8bb0b496) +,S(a27e09ee,9dd4e34c,6a92f4be,aa1b8c0b,2a60b33e,99fa981d,afaac623,9f616d15,33e6d8f7,bcaaa24,b6008e44,377b4892,5f88e884,5fe73807,8cd4f405,a2747f14) +,S(d2dc7884,31e5a497,3905876d,bd6ceac7,8246c9d0,73d68872,f54685eb,5970763c,85f96d40,e31ecc47,dc07fea4,4856068d,15d2a999,735aeb3a,4959e4f9,9ecf5fc8) +,S(38fe7a6c,c401daba,981875a0,f0c2f528,30ce31d8,816a1d3d,47a3d96a,664a02f7,e9893a1a,87034596,9d95e644,313d9b65,5896a931,81d36f6c,7e390102,3cb28c74) +,S(f2d38ff,14100172,d117dff6,1522c61c,3a590eb7,ee9fca77,dc264e60,32291d78,94eb4046,ab31eda3,7593e705,792fdfee,2e3df8f3,655befa9,ef0ef392,4b02dab) +,S(9e23c290,94b6b8e7,4e112b11,69c5c775,4b690d0e,141b74f8,2988bd84,78d42021,e2528717,28fc8d9a,283bdfa3,a011d28a,f531f392,b5da6da7,1834a29f,203e747f) +,S(3054117c,33c15a,504156e0,97e9a0f7,d76be8a9,c1c88fba,e1d9d2c5,4e1c9185,998844e2,b73e9468,1b0b09d7,4ca48dc2,f29c6df5,f3c38f7f,b6846178,d4ccae2e) +,S(65d1e830,3421444b,7d5f8600,2c6de12c,16f15a88,504c6876,b9e94cfd,a206810a,71c9cca1,6e066545,b11e2c29,edbac8f4,8533ec41,1e331e15,a2bed53f,1b1878db) +,S(124b78b8,948c4374,7c5b32de,50cbb055,ebf9fe7c,56437573,40723180,131ec0dd,c0fefa74,970829d9,4c1314b3,64a8516e,3a3c7fb8,e1d49f06,b1b9c19f,be18ddd6) +,S(f6d81a5c,395ab698,28e5f1f7,84edc6f6,a55137b1,411baa28,615abdfc,36c18567,3a759acd,4b758dbe,79e22f4b,26774b88,40121768,f655664f,c3f9bbbc,91f564cd) +,S(e76bd19b,fe13dc17,ddd14619,da6b12c9,f2819514,6acef71a,9e7bc32a,7abbea8a,68cee27f,152177e3,afa7d47,903801cb,b20ba02a,c48fefd6,e23fc102,e6456bc7) +,S(7356c0d,ff8f26eb,7df215c5,cf923c4e,237fd7ad,cbe58f7f,d5c745be,6451a830,16a0d86f,ebcf42d2,e89e9a1a,803838d3,1dd7debc,527d49e4,a7db799c,e1eeee6) +,S(b8d00a56,43fdc57b,dd949193,c5df30d,8ecf5b4d,8b3a13e2,64ba3ef7,c8bfacc9,f05acf53,9343641c,3feac336,28e9b08b,9a4e3c49,94c029aa,470fde03,d5d8cf8a) +,S(f555e29d,4dd3e0eb,d03f3866,596be43c,677d1ac4,1a1a3a8,1936ca6c,89618880,171d88d1,9abf05a6,981eddea,8f030e53,117a2e2a,97c2f352,255038fe,32ecf95a) +,S(172e6167,6e7755f3,c6a59c40,97a8a870,cdc09d73,2064d24c,3db8ada,7ca50ec1,7c1e58e0,38f322d3,e147b3db,e9b8f311,135d688a,98458da9,f6f8a6d5,4d4e2a96) +,S(f8f5fee7,d4e8eb51,92cb7ad3,9ee26cfb,44724b7b,f9c74fcd,61f95e3a,f33fabc5,607fd05e,361bfd66,519b5e11,d00d22af,8b0ce85c,11b16cd8,eaba71e1,2ebe6bbf) +,S(6fc770f3,f6169350,bb8b247d,16088031,4348ef73,cee49e5,c0f56a19,d2d66491,47708f10,80e755f1,2b1b0d9b,3439312b,dca07d85,fe94fda8,414dbdc6,ed9353de) +,S(2b8c0b49,94d3f78,79776d8f,bd2980c8,7840df15,82427cc4,f07ac806,eb7f7e3,3a335552,ccb38312,92a71376,9c7994e4,19a7919d,b776ce6c,db2ff092,92e4d798) +,S(e473c99b,dffad22b,72b6fcb0,d741179e,afb78aa0,de4b5d42,dd19d7d7,72ab1a60,2d0f795c,61ed1ac8,b5691d5e,9d52b19a,42c368fb,9d0787fa,8ef3b275,2a3d9d26) +,S(f389dc2d,b76a47af,f9d7a380,ab49274b,1a40c4f7,970bfa63,729da698,b4afdc4e,b15c2100,b63f7f5f,911a6474,25866d79,5a57dd97,74c21cd1,4907dec0,f5f3afab) +,S(df6e3625,8fdefe31,dffa19ff,2416f8b4,9fbc09c5,e86569e4,4b7330fa,56cb6e1c,4b5fedbe,835f0b8f,ae20f627,c8e74f41,a5443c1,a764c466,65f673f9,f62dfc7b) +,S(27e40da1,a5d7cabc,ce586e33,a4ace757,da972cf6,17c3781f,3fb0e0c4,e6f0a70e,ffc4b339,9cc0b701,36d871ea,a7c3a6ab,fa9dc92,72625fb5,b8bde8d8,be55904d) +,S(71b6f20e,e558ac12,829362ae,53900a59,ae29cc70,77dd1001,d9d7eae,36b95618,e765adc,1125219b,316beb88,4c0434eb,a6f62499,b8b2d217,c209c7cd,622d0597) +,S(535d5fc6,1eef1a92,50ceaef8,e09e1797,8debd360,8b03f72c,bfe265a2,633332e2,f8453dc2,4ad1ef7b,819d4329,a4752757,26c98e55,65440cc5,b5d509d8,61c98a38) +,S(d1e2222a,26817cd3,a537f2fb,7437ce06,ce9fa651,9d3c1967,71aac21b,97de68bd,a131cb69,cbd27e62,cb65ab48,a7f3035f,a78ef40c,6c42e94e,da326ccd,2b452849) +,S(5aba9590,2b5062c1,59b9639e,f08912b8,e7eacda9,759a4e98,b0e21d96,c2597b07,896a74fe,e2596e46,1e93f4ca,178646cb,4bc5454,227a2dce,1bb5d532,e558b334) +,S(9f07bed8,4449bf9a,815a546e,ffcbd0af,f22c9016,188d15ad,7c353e2e,5cf84343,6fa14d01,ba16dd07,15f3e68,d57738f7,1cb56d95,61eb84cb,ad63bbd2,d9ba439b) +,S(80a1920b,14723439,cc2090b7,189f96e0,20e6eba5,5f8964ad,2f0be013,b4925515,fdb63791,6d074376,8e32f983,f2ff1754,43136323,50b98674,2ccb9ae2,7997a020) +,S(dbb37c16,202dfd9e,914f2922,e8930789,a70d4de0,9fe7eb25,7d9a2b83,aec2b4c2,f6bcb8a,2c7bfa20,491d3fff,bd36e82d,91a7228,9e4fb6f8,9e167803,a17b7932) +,S(f03035f2,f0ad31ac,59e64a6c,f46e9ee2,a2243ee7,de5ccb0d,cb30083,97551b4c,1a1aacb9,798651c1,2bdc6ce7,4146e259,4263474e,d7b9d42d,78026331,60748722) +,S(1886fa45,e7447e89,b0873362,605beafc,4e05965e,53fabe41,41e1c42,4fb234d5,eb5374d,a4a198cd,d9027311,6b4331ed,f0f6a7a2,fc52aa44,8a9274b9,ee3d7743) +,S(46a262a2,5b76baf8,ae0ba3f4,ed8f86fe,e4854272,cbd0ed41,313c4e0a,357471b4,c08ee494,66d7dc12,a8e08880,732574e6,f6fedbf2,71d6dc37,eec3c324,33d8070e) +,S(d521c6c4,a0db2668,5a36b61c,b73d3504,ea7b7488,e3d75410,494e89e4,ab404d37,41f334e7,6a28cb9e,25e6efd4,fe3eee2d,17480189,b921d726,aa027b3f,75f94bfa) +,S(8f44a4e3,c18d714f,62054e54,6e9ca86e,818fcf39,fdde40c8,3044ddbe,be3b951f,210ec152,f8c90d7b,8486d1f9,c5c49a48,68249795,bf7d0171,34d9573a,d5b22aaf) +,S(d5a74098,eb20aaf7,b664fb8d,63e08b0,430733f1,466552db,417ec648,36a31dd7,7eedeaca,97f1c85a,98496159,eb024564,1c8ef0dc,21c31ff8,9d06012a,3387647e) +,S(d2a63a99,d6ab9e57,a2a6d39d,3738c3bc,94505332,2a34d3d2,4cabd1ce,5111bb08,e50f6c3e,796ac830,e276fac9,ab6738b4,722fc87,880f2e93,7417198d,9c6c1323) +,S(a1b826f2,1f7abe38,c622b93a,7510114d,dffe4cb6,d3fe0627,dcc0465c,bc82ad9a,c9cec051,a253ab24,a8507b07,d24ee4a,c1d5a5c7,33f0c3d5,611e8a9a,e4aa9667) +,S(40719ba6,89926b5b,ca99a4,161a1bc,d999d40,2311fc5b,e2f5260a,c3c10208,9edb353a,73e9fdad,96ca6b77,b467dd9,c7d6d2c8,e041d8f2,19448ea4,c603bcd0) +,S(c0ee8dda,80fed10,721e7cd8,9dbd237,216f4e84,bb8f7138,11f8ca16,1e3a0977,6a786e53,2a0f49cf,eabf0338,1d64de56,1a1973c9,36d6a5ca,4aaf4cba,b8fbe1e7) +,S(9c75860,ecdeaf1b,c598a530,48a22158,8099afbe,20cb08c1,3afbb133,b2681809,d7019eb3,5fb61aee,56a1afaf,2675a028,b8735dcc,b3f5d93b,c3e29672,9203321b) +,S(e39df640,6dbf2584,fecea5bf,aae78b5d,bca93ef0,9054c754,d8b235c2,c5463657,33ab2fce,3a2e3e7d,e2ab230b,e69bcb7a,4d71c87e,a1ff5d34,eb8b78f2,d5c61a55) +,S(22480e,4a7cadd0,d17a418a,78074f80,c4731ce5,d9f1268b,1ca50204,1ff8282a,993591da,11ea4445,8ccf8bc,2cd55fae,69e96a77,89d006dd,b85a22ae,85316200) +,S(c613fa66,231d38b3,359c3b94,132a2337,e2a8c608,3c88b41e,58434c19,48a6a1ca,8087377b,c3d6ca30,8c932dc6,ff82430f,3fce21c0,1a8b8b6,c28bab78,d3ddab43) +,S(c0a94837,c2fb86ad,ca791fb,bb0838c1,3bb0c981,e23c4ff7,94dfa5fa,c663e5,1f81050e,d21fcd5a,471657fe,abe6fccf,a391f1e1,9a88c143,4644bfb5,e1f69f9e) +,S(87ab257a,cc2296af,d921bebc,8e52fab1,c9c21f08,ae09faab,18858a06,1e408ccf,d5dd88e7,89d2f2d4,3773854f,ca980411,3dd69475,a56864d,3c869205,d682027c) +,S(10d14c28,cf44c5d8,fbf5caf6,b307f6f,ee203968,eea1be3e,b3697515,2edf45b6,46926a1e,dd4f79ad,74fd506e,4443375,23ec76fa,e09d216d,3ef3ed4c,73b635fa) +,S(2eb78fea,63035a3d,db64149b,612832b0,c9ab7880,539c67e9,d722e252,f7e23166,4f72ef76,d3dd59c0,a4e1be46,6ca5a3ce,fd84d207,f7d671b,240fd41b,20e72af3) +,S(14d8ab11,402af341,dc5cbb6e,1116b858,14decf11,e6761b09,31b449b0,20b6f56d,91bf8c4d,cc717657,990e0e3b,3558a01f,ebbe534e,897d1204,8a7d978c,3a1d735d) +,S(cebc042f,2e7bd361,934da5e6,dd2dc8a,9e73537f,5d5e3e46,3a88bcc3,ff6d5552,baa841c8,5e0a7287,b1f16c89,8ef03f22,3097e92c,44952c32,45f2fab1,dcd988c5) +,S(4f28e546,ef539c7e,8f33191b,897b7245,8f48a01d,79f65b8e,a8f672f7,d0ab027b,b1c1db0d,55be796d,2b415259,89088a7,d86c41f8,cd8ccdff,2bda49f2,407123d5) +,S(c4d31178,b73cf9ab,b0e1d554,a2cf93db,ed9a7b9e,8f49c9c5,4d63c815,6e111505,f5e4528,7089cd96,3118e279,bfc6661c,1e77ab67,b81a71bb,4ec14fe0,ef0c13f) +,S(8e260505,bf045c43,f3fd972e,d4189725,a4db0774,52f94eb9,51e42eb5,6131f0f0,4afee681,c6069893,5ce21991,208457b0,11548d97,9a33a0be,cf3c840f,77c4b4d8) +,S(982818ce,69b4c6f7,631daac,868af6a6,79fa6631,8c9da2c4,bac994ba,f9c95d81,f5b13c91,e7593e5b,69c85957,6398b186,8c503b6c,25179270,7e602f52,f30ca9c9) +,S(75c2f2b3,53720779,8737488d,16a5ca6e,dade382b,78f2b2b3,226fd5ed,6ac6c855,95aec19f,b97734cb,8426e530,afda15e4,c3c3dedb,2aaa24f,7ca73b4b,af475960) +,S(606ed5f1,8e4dc1e5,3b6f5ae3,896433c2,a904cb84,1ea021fb,84537f6a,9dd45ed,3165cf75,26f277f5,b9bf22e7,36291513,10158d63,b97b7c88,d49d88d2,d63dde9d) +,S(a33e07b,c2934f5e,f02ae143,6b3ef5ae,d2d633f4,2b40e35b,d365fe2e,b8c72d51,e93cfd7d,f2e98817,9eb9c348,73530504,bc5cd8e5,d8393f0e,844073ee,df6d6511) +,S(5ee1d077,735a4a18,533b36d1,eb484f14,98b220eb,cd41746,b0947403,d6b4644e,7d4e1233,46a6ba1d,8a862514,4d4bc5be,72e23d,f25287c7,3512817d,e632f8ef) +,S(7485b837,2bb28a8f,d496f6a0,33b92ba5,96202661,8adef933,d6aadc56,55765b0b,a58defb8,deb4445d,80016c9f,5c04c2f6,e06986c8,cc95da94,3105d8fb,d0fe84ed) +,S(3a321f94,2268584c,cac5d8ce,5d6011b1,22169e73,d9093b2c,e3e0bdf9,ad680d21,99fb13c0,ecb6c544,1347a4fb,842a7269,1492219,f9bb7c25,1916f837,7d4e2cc0) +,S(c115a2e8,265c6005,10bf7108,ee30bee1,77893d5b,ab0a8cc1,754810c3,3f112585,e2f0a636,5836a24c,7a5c6997,45022e8d,e0b88afd,37737c84,d1ae437d,eaf0b3d3) +,S(d8895b97,cd390ca2,cf8e6093,c125541,1602fd98,97074a8e,aa11bd3f,5b0f3c1e,af8c594b,bd2308e0,12a632b3,1d05a25e,23247f75,6d7a22f6,fcf48cde,28056ad) +,S(4ad1fd48,e77fe497,b4a15e7e,869377bb,163d760e,105e46a9,a5477d69,fa944eb5,a96cce4f,e2f5f590,17af2359,1dcbda3,b640271e,95290d59,1fdcbd8d,ecf39703) +,S(62ffcf4b,7ce6c5cb,76766893,bd0a6f2a,e33ef821,d953c001,51c4be3e,67f2cd8b,d6b1d025,152db954,968ea1bb,dd2a89db,16103f55,47cdd042,9b7380f7,c4c985f8) +,S(e71343c3,cec5e49f,60fea970,6d256a4d,ba499e86,6f9ab33d,6045a1be,cac40a,ee1fe3df,df226027,78228bba,91afd126,a96fc10b,f5d2cad1,26091119,3a92b426) +,S(31766ef2,f3531ead,2c7bbaa3,279e81e0,b040182,ab78065f,d193061,2792035b,87b93ca8,91151ee9,775669bd,df2e5bf7,9f728d52,efabf584,352ba4db,8cd6f6d7) +,S(1e8764f1,982a97d8,b65a0a60,53a2fb5d,39f1221e,dd4f532,b007b2c8,c52d39f,8ed84e0a,de68b789,5ecf8c07,80ba0b26,53faeb49,3d23a453,cc23987a,b51f3a18) +,S(e249cd91,4e35f97c,92a07f4d,6f9961bc,d7f6efe5,ccdfd44,cb3bb698,9939fe43,9ee2fb47,4abdac66,5bb0178f,d8ff3bef,6381a90d,bfab05e4,a9e5566c,cc362ffd) +,S(b9a28764,d21db971,f7cb0c1e,87c9db64,ee6a1acc,485a02e4,5d5ffafe,ea1012b9,1b55a989,43ff4fb,25db6aa1,12d5c459,b1ee0fa3,aea913cc,54878682,f625e882) +,S(5d042803,9f8c37b4,dc92a9ba,43bf7213,971488df,be699901,31820bda,c0b6ff03,1ffd5348,88796c6c,a631c3a1,4773f89a,ea6d5914,bcdf27c,38949147,cab8ac1d) +,S(6d817b42,52986e2e,8ecb908e,99011265,df0cff59,61a82b2c,baf0c61e,c8b22326,55cac99a,d6a70b96,5559af1f,c5b67469,5d653662,bce7594e,22916fa,7c4b826c) +,S(9b069431,297f0d35,91451039,df8a382c,1eba93c2,f62f4e98,90e54559,39916ae8,70bf9138,a04b9f14,2841a2e6,bdc3600f,1b22c81c,ba27f308,19a763b6,e64fef71) +,S(dbf5e41e,d83110a0,5dce4bbb,bee05f0b,f9700ef8,273b4bbd,57099bc9,460050f6,e3e8f5e1,697b05b1,23632b89,28c3b34a,6cf1e6f,327b4252,c3009046,c8406404) +,S(c8ef12ee,22aaefbe,9ca024bf,ba8fd744,d7c5d489,663cde66,a3ff1dee,8174ef33,db64c2c,db21415,fc552968,fbef01ed,131db2f0,1ec8372d,1b9da98f,4792e8e5) +,S(3d086c8f,af84b66d,bb9212f1,512663b1,793d6893,23f45af,9bdd17ba,fed8d7ce,2d6a47fa,9e1b6c20,a2cf30dd,a99547a,b9ab9c13,5ef86ebc,280ac62d,2ce7847c) +,S(e173d58,714db8bc,cfff3ab8,8cf1be0b,547e03f9,db60c97b,ba5a6735,cbf4bf4a,44b8f991,6764f393,68b36b56,9033e304,7fe90662,70758fb6,85cc3f6d,e31b2fc) +,S(31ef8faa,90826125,66e739cf,299de928,68c6027,b882978e,f72d014c,4aa4f379,9fb9e021,fafac237,8d21caf,f1262d7f,bd9b8333,eaab0fe8,8a3499b3,d153a2e5) +,S(5e112e52,2997b67e,146b998d,781bc528,7e2ad47c,b2c5863d,eccb0873,fa088b3b,19cf3f06,d3c1fdeb,8147e074,a42fe178,c0b14135,2dda5274,50a7d5ce,58d3d441) +,S(9ba2cddb,c1a5153f,89e9144,e862acfe,c624095b,8cf8b7a5,b15edd6e,c7b70eae,f032469b,9527911a,92dcff6b,5847fbb8,9f4ce42e,f20b40d4,80b3a58c,72fc805b) +,S(9ff7e46a,4e2c6e9a,d5843f4c,c5e112c6,557babe,723203de,d75be7eb,179e814,ec890ac0,2ece651a,6614bab2,1e4944a7,d248c886,bebb33c3,36c28df0,69be91ff) +,S(2a13752a,1aea6e21,d25ea21d,b644ab0b,fb84b130,8d3f2083,be26098f,fc4978f1,18f4936e,65ab66db,11bf53e5,7eb7d114,4820fd01,ed827f96,652514fc,d8ce910f) +,S(a0647c4f,2b4f271,97f3fbc3,bd81bc7f,f72d964c,1bcc131e,caf9bda6,57b356d7,5e023102,9a8eafe8,9466181a,80440196,e850390f,d42dfbc2,1d3fbf6d,6373a56c) +,S(6abaff96,aeaca928,ba9a0503,dcff7a51,420feffc,33b1ad53,b1a7bd57,8c641ede,ab59c03f,7ad47f73,df424882,dc3ac2bc,dc2ae6ed,3eaae48e,b807b010,98dc0de2) +,S(442abb18,54161ba2,47fd366e,52d40d56,65293573,c339aa2b,28dc67c6,70f4ee99,c3f44b44,d13ee3ed,4ffe5188,c5134d60,a28806b0,687b5652,99924655,342a5898) +,S(9f54f23b,45f632c1,f05245f6,c5d1c433,9e18671f,da494eb4,3bd22be7,b1610096,25c9e532,1a5563f1,f47a1e4c,99d6def8,541601ac,8420de96,190157ed,aa17445) +,S(50296c0c,185abbc4,1c86f578,8dad10f2,7f76074e,24e931db,53944b48,6ddee613,81a02b32,b1edd539,37ee1c78,ab630f2b,45336e16,cfc560f0,adeb464,fb71b9f8) +,S(39c2d099,e2892b2b,1b6abb1,a198305c,ed59d94,f7022cd6,d521b510,9a8fc219,8900f6e6,3fe1a7c7,27728b92,aea4d70c,1316570f,edba940c,e626e94e,f03dddff) +,S(3581e30b,17067e44,664201ba,d7a6ada3,e0648516,260b760f,b406dc48,11c9d0f4,c8bac129,83e49250,bc478ee5,fcfc0660,37d68f9f,fda1acc3,6861743e,d7a794b5) +,S(72b67dfe,d341824b,9fa09057,b8362d1,38287eac,7292610,1169e41f,19dce477,be527b0e,52ce07a6,99065bbd,ebd360fb,72c6dc77,88030aa9,45fbbabe,7f038524) +,S(805af91,4a973e36,43712cd4,4a1da4a8,3d1237e5,9c991387,17175aec,4a8667c4,f6a7beea,205810ff,5d1f0e8f,5818854a,bb730c7a,1ddf02c0,968b1b05,92ed8a15) +,S(44794289,4b297a87,e3cdeead,5cb2dc42,9fdeeed5,b8038189,331874ac,88e67536,d67efdbe,8d7ab8e8,1e25c340,77687b94,d22d8ec,b89d7f5d,46ca212f,abcc1b5) +,S(b73347c9,baa967a7,5e5c8ac3,14f3c6cf,275cc893,72b26bee,731693cb,48d36df4,307f8fa1,98f1ba57,7ba330d5,816cb8de,d9ec3f13,6bec0586,53c64675,753f1542) +,S(ec6d499a,efd540e9,357f100,4a136049,d1f7df5a,d99c44c4,6e3ed416,9e40acb6,21e8082c,df4fa2a8,38327e80,aac15ee4,40549109,aaf6ea01,ccbfb95d,3f7a47c4) +,S(7607b7ff,8bd8369a,67d22545,c40a1588,aa2e50c1,b5be6115,cbb8794e,2085f283,6c4a9aa2,1dd2ad4f,7d6c4f02,23885803,ac3b06fa,6c0772ec,bfb610b6,a1d25ea5) +,S(dec4b7ae,42e8a25,2c414458,d4e0d7fa,4bf4d0,c9432754,13d3b770,8fb53839,bc54d902,6d035b64,35796475,67805bdf,af6cdda4,d0177206,384c4ca9,8edb5898) +,S(a7be1017,82bf48e8,37c2e0ec,821e37b3,eab03607,36561152,a95a06a7,fbb7ae2b,dfd27057,dfaae0a9,b9523a9e,dc28a2bc,3631e84d,5fdf8c3d,e1e65055,805fe0bb) +,S(cb398b20,29e55994,741b87cb,592e9099,926229a,aea60bd6,30eaa528,726a04a7,263e89b5,85475a8a,50723568,d3328fdf,56c8fa8a,f0f796fe,7b4d2fc5,9aafe2fc) +,S(438a6d60,c289dab2,e8933153,5c2e09b7,a677cfcc,a605ea72,8815bdd2,615c852c,109ed19a,51e01f3b,a9dbea30,f652676b,b3a8afd3,5ab5178c,ae557793,13025f) +,S(4db8d4d,882fe513,e5738be2,347a05e9,2c97816c,b39339b,adeef99,7b682e50,88280370,d13551a8,a9803a28,c56bac47,70feb07f,56a1a0eb,d132262a,f1ea574f) +,S(ae2ad953,bf13c4c5,c3fd5ba3,389323fc,260de722,e36bdbae,6db77b2,1c0df210,a5866bb1,7580958,df07c171,80606be1,25b3ee73,9c3bae92,8fa35e9d,8efc7364) +,S(85b3809a,3f772b20,dc526b9c,19de8cd4,9c2d9814,df4a9b60,1aadd016,64c66c9d,984a8061,2ce95364,b9819440,551ab1b6,4028f61d,3028b725,74dfbeb6,8c174cd8) +,S(7e2ddaec,e443396a,7c7eede7,ad96c2b,63faaef1,66109949,e7431b06,309259e4,3aeb7f92,14fd37f2,aeec1921,e64e7a8f,e6a4c704,dfbbaf62,779d0eb3,3b1e81cd) +,S(4565a74,6cd1d26e,962bebb4,447985ed,7b1622f3,faade84,1291d694,17c3ea84,7215d7b9,6362fcd2,320c0c29,e0b304d0,ab174103,bfd372ef,e6e4534c,64ff3708) +,S(aa8c5a11,712aa04d,a870bad1,606c9549,bbf676d3,1ea5b260,27bd1055,ed56f996,11ec28a5,a7435436,3d302f23,24eba092,68028664,f0ebd323,cb7bc587,7d92aac5) +,S(d9d5c0d4,b5a3305c,9f057dc9,8ecf7482,f6d825e4,69a641f2,caff9180,b7096e0d,d2b0eae9,cdf57651,bd296ad2,f4403e77,d643db66,fadd7a84,27a150f3,6d547ec) +,S(2ab2e7ea,1e1bf61a,8bedaa4f,e8fe3a7a,db66c25,ed1b7ebc,536efc7f,8de22777,28806bd1,fc7dca1b,a0cdc177,908e0588,605f8c1e,e76cbc07,ea05b6ad,80c0e5) +,S(2da97d42,a9d064d7,38bc7fc2,f2db39a9,588d57f9,8094903d,cdaf5054,238c1568,fff93946,e789b902,8694ff95,a68a7fb2,981ca0d5,d2b6de3a,b3112381,b8360f1a) +,S(470fd28f,31418f2d,70367e4e,961da5cd,af8d0255,5bf6bcf5,e7db8967,6dbb174c,59a49444,2a250264,3faf843a,cd242640,e3622df9,da6bb1cc,6c956b7e,5a26078b) +,S(e41bbdd4,6b78fad7,ee62c33,9664fbc7,e884f88e,dc184e12,715e8368,160a7ef5,40252593,7979b92c,f72bfa7d,b3f378f0,cb4de758,a6348c7b,2b1d73d,57ac9faf) +,S(9761799a,7e155a4d,e6aefab,963b23fb,1f17d8a9,cc5f8c64,6d4dd638,2359c553,493bb00,3ab38aab,cb4d4491,b6b9e8ec,ef068c9b,933fbb32,6e0e1c75,ca44bf1c) +,S(d59fe2e0,5fcdcc2f,dcc22cb,b9220051,2c936bc8,2205f5df,75267a5d,b45b1245,68af556f,949df3fb,d8299f05,f5e85874,57d109bb,4d395634,89d3ac77,3d4b7b2e) +,S(f8bf168b,8a03f3c4,8e7568ab,ef613bf9,3f515f71,93a24b62,827455a6,c6bdf142,434f350e,8eeba6f6,d8f07137,a33199b8,88907744,eb547384,dcd96aad,5f9f3911) +,S(65298ff,636b442c,8c45e748,c3cd2d1b,94770ff3,3bde1d63,21135bc0,89ed81d9,d0aca445,cf460f5f,47090202,2c84fe1d,ac0a81e0,b7458e4c,9b21dc34,8c223ceb) +,S(d1ac0d0e,25dd02d6,fea02b6c,c98f4b17,38046416,93258208,f04a81d3,450aeaa5,be491f07,1833efce,56197dd4,d3471eba,2a23491d,f09a87f9,8a4ff14,257d1dda) +,S(be876d37,fc1605e9,ea0923c4,e53497a3,8d51190b,dfc3dbbb,3191a483,949cae1a,8499ad31,ca5acd99,4a98caa9,2a91a321,5fd1f1f6,cd70c463,afb91673,ab6b3a72) +,S(7c440cd,aff0d8da,6fb5e2c8,fe27a301,c2906a63,7d9b1bf2,db848f13,175de738,7dd6cf71,cb013a8e,9494cca6,b418fb,e99e9c80,3ff34d35,e586fe25,8ffc4fef) +,S(25086ee5,f0037c83,e38abbaa,e0e3356f,c49020d6,f9006edb,235937a0,4d7074fb,35c21eff,8cb888db,d3271a5c,4dc1db52,2072e58d,974af68b,4d6cecd5,d13e582c) +,S(b1a7584b,6f43a593,363d6e62,edade636,55ffc711,48e6c9b4,2915d0d5,ebf4dbe9,f418f23a,9dde8808,59816098,ea06d2e4,dbad3385,737b7bff,a1b339e,1b556718) +,S(87e1c0c6,aece59e9,1118829d,ba8e0271,db30409f,c08dd790,4296b91,43fb7aae,4694c5cc,176cf309,e4bd4935,b88e2fb0,e7e1b63c,28c5bab5,d3356733,184ef152) +,S(19f43d3f,4bf0f2b1,9a157f3,3f71c5a1,20e2135,3187b508,e568dc5d,8131a2ea,3ff130d9,835e0eab,2744cdb2,5607fa63,edcf9648,d910e25f,b885ba9f,b340860) +,S(a7f9239c,5e8e371d,7d175c8b,120816be,2e543d89,a22c3f7c,5478ae1a,14f8f6b8,75711a87,561fc767,93510d5,47abe6f1,678d0cd7,335e7bbf,b87abbc2,cc3089e4) +,S(9f3598e8,f80cee53,969a79a6,d3b655c0,66283a8e,f2c5d7b7,8ce89e67,5d06446d,d9cbf50d,c2aedfd4,51fcd93a,46245bc0,772e9f9d,fe5a25f6,3af027b2,ea1edf79) +,S(cc00a72a,66dfc8a9,e7a4edd6,699764ca,c15140e7,216daa59,cadf0edf,d1e3267f,91b10836,c8ebd031,2f72cf2c,cf26c89e,1489c100,c72a04cc,71c0d08,45c27d94) +,S(2dc7758d,b176a48f,f3117aa9,671f7b6b,f0b2128a,4bc60fc3,f907eb1f,d20ff347,afc82704,39787ab6,bec0d4f0,7b7f2896,43073cfb,65e9d3ce,db8ff7b,791f2f59) +,S(2502f7f5,8dba7c37,bc4637ab,8c77c047,700dea3f,5b760ec7,9b68121,9cee008e,f6fea3d6,4e776f5c,cd293dd9,4109d6f0,1e55c039,c30438eb,6e626489,c92f078b) +,S(70d39d43,d7f2092,53967479,de620ed2,bcf963de,6ceae3b1,a80fd275,1801382,fef8bea6,45807be0,e1c5c3e2,4d391d8,bf0a6b33,564749d1,4fcf4ef,a8aa7133) +,S(a09962fe,9a934004,bc31f92f,526ff444,da7889e1,79453a55,b0fee769,34c69c2,dd717079,8cf19b8,1f55fdcf,86cd3755,f708256e,694fdaf5,f929c967,eff687b5) +,S(355a2555,4590dcf2,84ca548f,9ec9f40b,22482773,cf122a40,25ed416b,9d29c692,549ed0bf,db861bb7,4684ebef,7d70ac56,3703997e,c59b1f86,bb4b5dfa,574a2f64) +,S(4c145d2c,a165a5a8,b66f7fdf,c16bcd5c,c22304f2,f0ec3145,9b9fb0fc,797c9b9a,7cc14054,948caa4f,be04b54f,1b60a51d,cc482fc8,c94825f7,8de4f4a9,a63f8d5e) +,S(b5ac199b,fa591300,6d635fc6,86d87cb2,52c5c67a,6b897a09,bee578f4,9c57f8f3,41e164ae,d3d967da,94f0cd06,91cb3ec0,79c5712c,279b3a8a,d75affda,2879b234) +,S(ad619913,f00f620,38321c3,59931a9e,fd26941a,aa02a812,8d9f3bf4,8818185,d7b5a033,9e4b8ab2,bf66a597,45c0b496,b5825886,9084d306,660670f3,a9de912) +,S(f8314cdf,d7659ce,e8377abe,f4c80b00,9c99c1b2,f2bee37d,a726c6d2,a1deea90,db5a45c9,a7ea22cb,dba3a784,131ee81c,2a1d9edf,d9ccb9f9,6fc93d35,a332eab7) +,S(1fe1bfca,5df9c482,68e88661,89e238e3,7915957b,aa1e0c3e,af317d12,c2f84650,dbe03060,745396b6,fb22d6cf,a6b27329,3b3ed08b,a24ddb38,8942199a,765d7414) +,S(c414da43,814bcc43,31269d58,1c0a8c14,9e304f5c,13614a89,7f414725,9ed39070,ca194f90,dac3f722,6090b94a,3b94db7c,5c68931c,7461619d,8b912692,4fd90a4c) +,S(81a098c3,d1ebf427,69f621b8,3eced558,9dc0faaf,24206f97,480e40d1,25faba3,fffac91a,3b729698,b0b26f8a,e6391b1c,8f8327f4,7978b011,d7d1cebb,6b0ad8bc) +,S(f99441dd,e4332003,b6421463,b4bf6595,172121d3,f000763b,a40cccdf,be2cf439,231fa7c3,fffcee74,bd111f18,3689062e,1b6b366b,2fe14440,2061de8e,4688b3b9) +,S(2f930e6d,e3586768,792e565c,211e1abf,99e05fe8,79c01083,3e6e5121,7abdcc60,2d51a776,209a3da9,ca4dda22,7beea48,a93a90db,b51f0721,2864f36,a56424e7) +,S(9f8e96d5,99fd07bb,e9e0010f,90802d25,4b30e359,bf0fdcaa,d6e782da,62c6d25e,baeaf150,de04c7ae,d8d34278,aba6eeb4,9b3f213b,fd56585d,41890632,d6b64e02) +,S(57f186f6,fa5f4aee,e3e8b44a,d775301b,66d7fedc,4ab8c827,cb138386,64727f10,5a65c0c4,a69b16e0,1c32a95e,77c8f99d,53bc15af,5c168457,19bc8220,d7baf849) +,S(d344361d,dd0b764c,be16f46f,5efe166c,10a88bfe,bf532a8f,a1fe138a,78e0e1ac,dc1afcbb,a84b8524,a5d985ac,5506f15f,d0b92f85,875c2c4a,4144a93e,e455792) +,S(444163a7,58095900,e5c8fda4,88ecae95,24fe54ae,2592ae53,7e6db41e,8019344f,bae54b91,e69ddcb2,c1bf22e0,bdd721b7,a9ca51b,dad93b28,59e09509,77c26488) +,S(5ce2e1d6,46f10fe7,e4196414,37fa2c16,48029fd5,5340d2e5,f32d467,e0c4e222,6e95f538,cadb1b56,8313429f,35fb925d,d9ba571d,bc6f3970,ff4fd276,4228e82b) +,S(8b7226b0,8525a07a,84ee858b,58c418d3,1d4acdaf,9b081761,56b83a8b,fde6d773,684e6dc,37a2ba2d,89c0b01a,b4e1fcc2,1734eed8,2f7b1509,6724acab,5e276006) +,S(6aa5e306,36046384,ac8e3da3,f2f00713,8acaa0b,b0d12ee2,1e69018a,4d0554a3,2144dece,31a7453d,3a07e290,cef1b694,f393e5d3,f6cb07b7,a8c991b5,2a788029) +,S(8537990b,dd59836d,da16ccee,3871a232,3bd841f,6128f845,b0369857,66c7e0e2,beda6acb,946a6e08,43ec2890,c2d11ee2,404cadec,afb3f1c0,37cfb9fb,7b733fb) +,S(85a8cf21,1de57c,9c0ba88d,2f9a773,61041619,639c9de3,e2f2bc71,cb9e66d6,80d1d1cc,3c757338,f5a6aecd,815cd5aa,1d772aeb,5c1efa05,d5b64886,97ff6de7) +,S(d4f18d05,cb183c54,7594ea93,9330c174,37870e7d,48a613ab,4a920e38,18068267,32fc3b50,394bfc8f,a2a3f912,b35ebb69,d388c87b,198c3619,b04b6b3c,36b6190a) +,S(123e8bc5,65ceba86,d4c1726d,5e7e2a32,ac6f628e,940aa97f,c96ff72c,ec79e637,e54b4332,975774e0,748fb58f,3ddc5a14,8c3eb1cd,824bab83,edc76c28,e991d2c5) +,S(ac26cf03,c5a95e3,9a975746,a26bde6,8eddd6b1,6c83a3c5,81fa0a79,e93d0cdb,73ebeeed,b96d879b,882ae503,2f400142,5c8ed97f,98daa225,346a5b7e,9abc4832) +,S(54f2cc5a,a4d81daf,6600e921,441f5aa1,5bb51a42,7479e123,b9561d0c,8c71299e,3ff4e7f0,83f85039,d238a740,b7fd16a1,e313cbb5,b0c6fe5d,ad99f221,da4aa27e) +,S(8bd785,b73cca1c,6c405ca9,1ed4833b,428b7ddc,1a61c8d9,b0d1dea8,ef133586,fc5b65e2,5c3fde0f,3239ab96,625a9751,27a30cbe,f98e1ee,735c1f71,c86cf292) +,S(bd4218be,af5f92dd,f96a54fa,fe873cf2,171c2e30,a13c866e,e830bb2f,abb17d5c,86097c6f,91024f4f,8900853b,d17dbede,e2674e36,9f3fc69f,a2578eab,174e783f) +,S(a4006630,1b63e757,fce2f5d2,a7444e5a,1f2d7509,b7f59476,6951f38c,1755b497,87aef8b3,eb160df9,4b46a56a,337b6400,c724658c,a49c1162,c418e900,29efde08) +,S(5c5af5f5,65b2870d,6fd08f95,b4146379,15cda056,e18ef682,4cbbbcf8,adca740a,c7c6de6c,e679f0dc,84e28027,86ea726b,8eb0ad04,af4b9a5e,de516f11,583607cc) +,S(b5c3629,b86e9235,478aa7e2,d2e5b539,b70765b7,79ace9ec,ae76a659,80f0ebd3,86a8a06,84fef80,7a081bf0,3f08c078,7ad04420,76f5e1d4,521cffec,8b2dc96d) +,S(1784e06a,cd25fa66,72d1fc08,9219cdb4,54f5c711,4237bfe4,a2143eb3,20a0bedc,11feb0a7,d8d43ebd,5bfde5fd,21fcaa5e,7f091da6,3acf4b91,956172b3,5d3af378) +,S(39266c28,48f58af4,47e5ce4f,61cb3ba6,9c3bfdad,7e5742fb,ba4ca3f4,f175a291,7be4b872,9d1e2fa8,fee16e5,bfcdf4ef,2cff2872,e9c7fea2,c1997d6c,5d7f1efe) +,S(d6fbeb8c,72214cee,58b33bbf,2eb04924,f96e9b63,d104aa92,fbb09c8f,c2e4b1a7,cd9bbb10,a800d777,9d4cda4,561a2b8,759b4dde,45dfa2c,319e4e59,39938c8) +,S(42ee0a83,85464cbf,cd4a9ac2,73001bb8,592f2a74,b28ab7c,2eb7055e,2a471b76,d22c6ec9,d5499b4f,26947233,a5589aeb,14c94376,9a6166c2,af9d323b,e1adea4f) +,S(8cd2a043,4de9b238,f4dbc3b7,e56ffbea,4f025e2d,6c73a68a,4aa62bb4,9e9057f2,abfe69a9,986ae1db,52a807c7,c08a1116,a2dc7aa2,ec3b649d,7326bafa,ca74d21e) +,S(14c35089,62dcb50,d01750a9,441eda38,1a95abe3,72c501bf,a99f953a,5c94da3b,bc57dbf6,bba79503,f33be20f,96a54fda,fcd7be9,cb064410,3db11e3e,2034a3ae) +,S(2cddb646,76717e44,86fbe0a7,f7d6d853,7c3fff9,465e31e6,8da22abd,b3eedee6,136346f0,cf5fd102,932036c,3605179d,1429a706,71d95524,a14869a3,d1cae8f4) +,S(d806ee3,b5702d23,50c3f179,a00c3701,9c055103,318594c5,8f10b100,1b705aeb,79201749,21e69cac,a0ad5902,42e39a04,c3af8cc4,c665587c,cc0c89b8,3744b9b2) +,S(534f24,715e9b8f,f5f76a4f,a617839f,6fe2f175,3cbc3d80,331d12e,98f6ec30,e26ebaf6,4affe9d7,1ba2cd55,421c33ef,2e4a3fb1,c59a72b5,93ececec,65a40e1c) +,S(f33af0ef,4e23c8ae,7f3de5c5,22e8bd9a,6e527c8a,23242c8,4ae6677e,ec90b8f5,8510bee6,bacb5633,45f38075,8d85dd0f,493d179c,b9250d25,fe88134a,6055aefe) +,S(3cad4725,12a745f6,7e36fb92,1a2926d6,ae294278,8004386b,272d8520,f5a9aa61,d12ccf97,27da84fd,317116e4,9d45d741,776c8278,4b2c9f1a,e3773e1f,57b8934a) +,S(4b7fcc39,5f50944d,5cf3b3f6,2b1bbc3e,3aca20e6,d259e931,d3398d08,cb6fcdf1,99acfb05,a106a389,b7ad644c,cd275396,d76b046e,9992e573,dcead5c6,c7da96ff) +,S(9b5c0e8b,22a62110,bca2770b,778f0a2d,6d67e908,c57f806d,7470f5c6,abbb27f6,da52c77f,ea3056fa,dae674e6,daff8b21,100d007d,8bdefb12,fd56efe8,13c15a02) +,S(ee7b7f5c,e79eac13,d9b500ed,ee0b65d8,e7c93203,aaad71a6,9a935e31,20722361,e77ccd78,bf6380e0,5e5e8de2,20448a00,cabe7d6c,6b7ac318,56c09e2a,9a390778) +,S(b4774237,d36a59f0,e39a133,756bebf7,4df43365,2a4505c8,b0b84833,dd5b3a1d,5a5a03a9,e3463ce2,fa8bbfc9,afde9c25,763f4874,3cf0b2ca,7dc42c3f,9bf3accb) +,S(5827142,c69944cb,a066a985,79acdc02,83e1df82,8935ba82,5aa55047,5a52271e,c05c5805,6bcb6cce,ed5e8c8a,beac78b9,69c3b482,7ef5b402,c94fe1fa,f7fc81a7) +,S(ba06eb6c,a54fe697,9be9e9c0,f8c77be5,ada7bd7f,43894d1d,1705cc18,9c9b0ed,176be0,b5d3db28,7f235e2f,a9531fba,65f5ff8d,55b784dc,bf7271bf,864e3d5) +,S(ed84c2b6,11c1208f,2f059d37,a3d2ddc9,c3a0196c,9b9dee3a,5f2cbb0d,9383625b,6dff970e,b08bb4c5,4dd6ad6e,df25bbb4,621a5ea9,3869de76,2524dd2c,af1c6f6b) +,S(158b136,86fbdcb6,ad8ea001,9005405,b5cfc0d8,f614592b,d9e76b1d,8cdd568a,8c576136,634af4e7,9034b450,1bae33e0,9b5712f8,642cbeb,2b7c8910,cb28fab2) +,S(687d52da,10df8013,7232821a,990adf74,c54711de,110027f0,68464c9d,162c2410,dad3819f,8071b3cd,dd84fde,550d24e6,31785e1c,e137e115,8b5cc687,8cd09f10) +,S(32e8617d,de77c33c,a1d317db,d350298,50dc7fb7,148913cf,413e04b,384dc81c,9cb2fdd5,15231e83,21a3feef,804d62e9,2b8b9c0f,dfb73dd9,c3323017,b29f2ff7) +,S(a53a659f,7cc90421,21d96a90,3801753c,ea43b363,405af6,16d50b4e,fff054df,96734742,ecb3c201,742f8f64,df22569c,92212928,ca0d5453,d706f905,33c345cf) +,S(8a9e4990,b9b1a2b1,32ca9507,16170713,bcbf5719,2dca9d71,7fc9c4fd,a3993fe5,9542de81,f66098dc,c0bb0f89,44ea56bb,bb7e86f,9c63222c,80620c7d,2fac20d) +,S(5966c5b0,f92c5906,b9bda0a,7b3f10f8,e4c29796,f953db1d,35976175,dcb431d4,539665b9,90bc3810,4b7938f3,47ac94dd,7b9228cf,7270284,a825a202,ac62d135) +,S(2170d9c7,4ca5e85,305d159e,697fd1d,d32d6f6c,a2806992,f082ce00,9139c34f,b5cbf529,66f71e55,8015c90b,ea2b95fb,4a0fed8d,ef1f9af4,518789e7,39076c64) +,S(86e9b03c,2497519d,615f83f9,d0f9bf9b,101b75cc,50059e19,4d7b58a2,9b6fdf76,215d042d,7976ea35,a3dd586c,f5b286ba,a30e013,966fbb45,99845111,db8b56ed) +,S(2cc7d91,ba630172,ae56cf60,9a5d3c05,e27c2e68,7d607c85,ffcbf6c9,a467028a,9404f869,32385290,dff3f8fa,1a085661,5855aa6d,e9742d8f,9e2777f9,472ab5c5) +,S(84a89b0b,304ed760,c3a3d972,5a65764a,11d59ebc,25249f69,1d3b8711,10d3cc73,b7200408,fb1ab866,53b61321,10b6bc53,c8a0805e,568f8a0a,80a65678,c54c5829) +,S(4e9c88e,d10be9ea,a34bae15,8ba3093b,42ad9cb7,356f34dd,33eada3b,1937b4a7,b92050dc,95423a8c,759222ea,c09593c1,342c2dde,5fe382d5,6838df0a,877dbd9b) +,S(fe2883e6,6db454d5,31f2aaec,96f4f3f2,868ef393,d09c7685,a65d476,c6c97a99,1ac28015,1bc7c0a1,cc4be80,c6eff3a2,b8ae70b1,180c6a15,7c89dd3e,3e78568d) +,S(c74df902,ba66c205,e49f25c5,62d1eb18,f4f4f697,3cf49135,16000924,80f3f68f,17f7bbc9,59dd7e6d,9043ad38,7c0097b,403c8d1f,e676b8db,d7f2c63,1fa1ecd9) +,S(e7e7a72a,41f95b51,2ea42d1c,76da24bf,67059e,c27d5313,55c30e60,69a72c16,a20c2f51,6e9ba9b1,fd3a8473,8309ace7,da6006bf,bc42d4ed,657da6eb,6efedb8c) +,S(5a93859e,dc4ee632,9d36536e,1bf1008b,603d6a8,859ac6c3,a098748b,d6e18bce,489326a0,1e05c331,d97db6cb,68f098c4,6712d7d2,994e6c8d,be892138,e2106220) +,S(6161b293,71353343,a46d0917,4f6467ea,25a0f77f,fe614133,7fd3bf77,71062de8,57c439d9,a1682d4f,773c8260,6ee65e88,473544ae,64194ab2,3fafc2dd,7612b385) +,S(c35b16b5,a3808dd9,553c7644,400d6fe8,ca48c8ae,49c78018,4a71eff6,b94ce4ee,6c3baede,4925766f,3a7c59e6,d6c1c966,c3348b1f,5883498e,9956f3e6,6d8fe13f) +,S(fbdae49,32baf904,1d295378,2d227dce,4e2af60a,86796a69,86b777ce,bd2cd134,9ed9b5fb,df42e755,a9cd761a,cbb92877,6c66d299,35dc526c,f6950ba3,d63d0c95) +,S(6c5bdede,17ce2007,a3a1c18f,af8a846a,ce67b751,3d8bd602,23610ae4,b01b720b,6492873c,26a22bc6,39d4614a,202cbb2f,2a08b78a,753592f4,10c855d8,12f8d39b) +,S(eba4e62a,bf52b379,9305bfc0,eecc63c0,5221a0b8,b554432c,15e460d4,21dddeb1,e378e6c8,d6ddc7a6,72d83c3c,9d863c53,32b1cdc8,21ed458c,b817c49b,6dbdc519) +,S(5a79ee4a,1aab7803,23ced132,f9c67d5a,c740900e,cf71a0b0,ddb1d6c9,794cd90e,9f608713,47b3a231,548909fc,812624ef,26eb26fa,98630512,2b1466f2,665176cd) +,S(78b702ed,6d816c15,eb31dc27,619d5bf0,6ad646b2,e39750f0,73c31d03,e50d9385,9f1cc224,91befaa4,fbe9721f,86bebcb0,11024a08,4380e46d,bf11ce99,f157fd24) +,S(494e82e4,1c24936e,c291f69e,791979ae,3e2a6696,c8f68601,b57942a8,fe6b98eb,59f3af2f,c720847c,19fceea6,e3d2a918,ff7f564b,2e3bd7a4,beda6415,65bf5da2) +,S(28b3ff40,467a8c68,69fdc61c,33f002f9,73705468,4fc707ab,c0b495e9,a5c0b401,46a44995,b2c8f0ca,a32d8e33,b8e38465,4cfbaf1d,addc4d1b,852b2a04,58f84e34) +,S(4e4cf4f4,38a40e8a,aea162d9,dac13531,f5730d96,59c436fe,d8acd06a,c4c46be,4fb4bf3f,bc394c7b,57f81a59,2ea14c30,1e9ca990,5f48ee7a,5db08ea5,eb6dfd7f) +,S(e2ace7b1,3a9e3e22,a9b8ee66,c56e80f1,9370cda9,eb3ffb6,2d20805c,7f4c34be,1c8fcde1,2a653492,6428319a,981e1602,44aa823e,a82831b4,d0eafd9a,2159318e) +,S(e090ff27,e42469c9,91dab9a8,dc9a3a41,d46b7482,a59ba9b,cf4de93b,c95c7e78,d070752,c5679b45,4e1b617e,8315a48,1cd9d24e,eb53a671,3b4160ac,64e6f824) +,S(705c8790,7b976b8d,c8ccd3aa,897b2ed9,ea091c37,e285c37b,aa321c89,15ce089e,edccb405,5ae9f933,973950f7,eb79657f,e94fe286,27f6cb2e,784d667c,21ad4d3c) +,S(4aefb3df,663a28f0,d531e390,339a56a0,4da1c64d,4692c086,de232740,6d386d57,167af97b,43a36a18,1dfde22e,633547e0,eaac2f16,84e8753e,1ba1741c,2a18fe3f) +,S(ea909685,ee8c283d,1d7dfc4d,6ec8910b,b8d821d3,3997f24c,db5f5ee3,bb7bd72b,685b64,d3e02ee2,be2045ba,c3bb428,636258db,33177da3,17f6de0c,f8c805f8) +,S(5987cd59,ecccc129,b3498331,f20cbfef,f377cacb,dea76ce,2e221aac,d3aace8c,3427cdb4,f7367d60,44ba21b8,adfd5863,bae2981b,340c9bff,d0d7e93b,ee4d6140) +,S(e23845ea,e6ed3d33,14fd6f6e,f6d6e9f5,92f921c9,f448eb93,edb49869,97837eb2,89eb22d6,455cc139,e42c6263,b65233c5,4b1a3b45,34ec3d7e,58b788f2,6b11b131) +,S(cac7dbd9,7dcd353f,fbf60696,d325bf14,2e3920ce,26570b59,ff9aa65a,a6993199,6e81a4e,cd60a26c,90f890fd,6de2d159,50bb70e8,92eed375,25a48f3,31307620) +,S(9dab063,3a5952fe,f168d6c0,3ebb226d,de3e591b,4ad0c9dc,96b247ae,49a317de,846d87d2,7662b958,b3422b3c,a3410ffd,1ae549d0,c6757bf4,f96d2d77,168cc83c) +,S(bce277d9,ed439b09,f255cee8,af5363a1,12ec2d5e,b111196d,be30fb21,43f501e4,63f472d5,2649843c,42e8f900,5adfa50,d6a938ef,8f4f04d8,897a68d8,8c213328) +,S(df9f8700,2a6baec7,8b79cded,bb501dfd,54f376f4,5756501e,f03a6c7e,ac5f1d7a,2a1c5c92,789fa6e2,84105f4c,74b0a108,27ea2f05,5560bec0,5d0000be,b9b6c4d5) +,S(6211dcc9,307c40ac,3c7be1c7,5553511c,15d3224e,3b305c5a,39653d83,f134dbb8,545c00d9,f02b8833,5fe4851a,88cbde99,f7f02d05,ac674f5a,6559ac9b,d03febb1) +,S(d739aa30,8d9022fc,45735eed,3ff92f38,545f6c9b,b70994fc,b5f41f78,772c9378,d3c3fbb,9077dd53,d023838a,5c35b728,af4a90c0,1f16739d,12870e1b,15e1e6ac) +,S(9d85e55e,8ed84471,b6822c68,3268c35b,fa314b72,470e51c1,a7ac9f25,f8bceb6,8b01f444,e84436ee,ae159a32,7026d279,5c4116b3,b2e78f90,99f1035,1511ac88) +,S(25d39bff,22c40a94,b194c38f,be9d001d,4a632407,237fb091,163e463d,7c5c70f,33381905,11368982,445ad7f6,608be022,209466c7,98b9abe4,f4fca781,2c0c398e) +,S(67553ed3,f14c28d5,2abc36c9,3f15d0c4,7f6fe1dd,628b652f,36b29225,ef8ff51c,da5d42d5,9d41893d,10ed28d,569c0cbe,1cc077e3,36bb5c21,e3712bbb,9c480383) +,S(ea3e80f8,c800b52c,a6dcbd2d,399ec5db,65057477,8852a73d,68af22d6,f1abbefb,5cd8f55d,b5330919,377b48d0,8ac1bce0,dfb8c3ea,2b97a5bf,547b7beb,ea64a4d7) +,S(7cf11aaf,638b1fe7,3b8c5753,48bcc01a,41c61ee8,f2eb3279,c2ad21b7,f6f60780,579d9a90,3a8a77a5,6bef3ce0,53ffb3c3,cf969f9a,39ea5bad,b1fa075b,e918f048) +,S(ed377aa8,42897f6d,1092caa7,42c29285,2349bd7c,a0e0cbce,d3cda58e,ffaf5e17,44d1e8bb,6491dfea,cde53662,5e5d7b52,1ca11a47,1eeda260,647f6f0,f0c5f917) +,S(fcafcd82,dfc87415,6e0db5ab,2fa2b56f,dd488032,d22ddc1a,b7a0ec8,1f1c4083,42f88e6a,cf851a7e,ca3fc28d,f771cce2,bef0d7ce,3d26da45,a2d9c307,e9e7e040) +,S(4d372865,7fde43e1,68744112,26b34713,9c1ca4ac,c2905858,de50def8,5515339c,5dc438eb,7091eecd,a4868c48,a7933b71,7ba99d8d,5e8a946d,ca9605a4,7421df39) +,S(aea6fc55,47faaa10,a898f21a,f63249ac,a0625f78,ea819629,8bca035d,7639e470,4d20c80f,173980d2,8e6bf433,bd1dacc3,1882e283,35fa9993,ef808464,a5568d42) +,S(f0ce04bd,bfa81a58,e157a49a,11695baf,7233470e,baa7ae76,3a07f0b7,f71cfce,f9e4d701,baa6f197,d9912b57,d9df016a,b789e60e,d731afeb,f2e5f920,b4eef9f6) +,S(cc476e63,130a950b,b8284c8f,fe74a059,8d9d44d4,c0372a9d,bbabca17,517523f6,d2cd50d2,e2cae10c,df744ff6,61a6c96b,64e17368,5f81027a,c937a292,3ad7476e) +,S(90e0477e,8dacfda2,7a563448,65947a05,d0afe9ea,60634473,143508fc,6abfc73a,d117be49,166bb010,afb0b82,a46a4204,c18ffa42,e3c89764,3eaae0f3,303dcd9b) +,S(522a6781,951f6ec7,76b6cf9f,cd20287d,6977764c,517d4ebc,7209d55,5714b5d4,a109c149,6318d481,4cb22199,3567e5f4,5147b64f,c1f9216b,922d653,7637031) +,S(b0a4c701,725326e5,611ea140,325b0536,b22406bc,c1e7eef2,1f874ff4,e02ec2a5,df44faa2,8a60eb90,3974649d,54cf340e,293fbd09,66b7b7d8,884e4c8d,dc1ec875) +,S(9e874924,90f8d4ca,2ada28a3,2bccfdaa,51ead138,3421d7d3,482af7f6,6df47c51,a58a577d,d03a719d,1bbb64,6ec3051b,44535da0,5e7e04d9,fca42716,2e335fd7) +,S(650a307,7b8007ed,f0441dfb,b7103d3c,d5146ecb,b949f9d9,c8c99e2f,25df7324,aa05b394,8c909957,ed1bd7e2,720286d7,56c7e413,8aa202be,b08bc446,2fdf86e8) +,S(f891ea99,2a3ef255,6feafa4d,7dd3f7eb,1f1401c2,b75d65d2,6ab81372,bab6f932,f7002bf5,821837f5,8df109f7,2ba5eea5,6c767a4e,198a7594,21467d64,df5e0bd3) +,S(d35e82bd,44fe54b,5d2c0543,91260c04,a5ce8d47,32e83ccc,2f3035e5,56bf2626,b002495,99705173,e0a45f97,196b9e41,1a7f5d1e,33f1b39,100b511c,e51f6953) +,S(7dd56d5,1f139070,a382af7a,2db135bf,854c8e98,2a325b41,ed869de4,349323bc,a23a473a,7f263bf4,944ab5bc,2d82e20e,8e9256fd,b11dbc17,bc0e6bfa,a8325f5e) +,S(afed2eb3,c5a95b4a,e88ee73d,b57594c4,7013cf13,a48431b0,f7930d5c,27f5c3f2,26b49096,da666097,3403eabe,342ab065,78c8ec6f,bc3ac7d7,2b3c95dd,54735dbd) +,S(13826776,74f36fe9,ca81cea,ac65c2b5,51e9fad3,af246f,4cdc65cb,cec534c5,a78e8139,760a94e8,3b3f5ff2,a65fbc7b,6b2b55fc,978b8399,df2d7947,18b496f1) +,S(99200c12,6fed5ec,1fc849f7,e9769a7b,aae3178,bd6b59ef,2563ed6c,5342b80f,7a7f1713,38a84536,e73f358f,91eb80b1,6ce8ef27,ea55795d,16aa7f05,577fc13f) +,S(159febb0,27e04f1c,321b852a,3cca550,28aac30a,8bc27caa,73a069e4,df7029cb,6bc7e080,8834b880,c590d249,241b709,e7280a05,7cbc1897,9b8cc9b3,cc21a821) +,S(2add9be1,a3acdd9f,efebdc0d,a4272ca9,311567e4,61db8eb7,3519c1c,6473bbc4,357ae640,a88c55e0,d3559faf,b0775d78,2373537c,c25e595f,f21ed1ff,b36b5925) +,S(8e2d4265,1742837b,b077fcd1,488e73e,5dccd6ba,6401c6c1,8d36fe9c,c428b664,ee9a5b1e,a04ab8d9,6430ef39,7756f62f,a1dcf35f,fff314a1,c3eb1dc8,d9a1e5e7) +,S(79dd7d76,5b4d7db0,537a69d9,b94210e3,8e7a11f8,cb9cdd8c,6aed6a15,748a3ac9,868c4b6,26dc49fd,de693201,3b89cf13,e1dfa1eb,56fb4de8,9e5467dd,86e449d9) +,S(552c2ba9,96a13b57,32c3b2fe,d4e9579d,365e03d9,2bcb231d,f14d1d1c,288a963,118e11e8,646a0335,6834379c,bc93c1d1,3ad80145,dee0a51c,49b10e17,f6952f79) +,S(fcfde18,a53b5a68,9d33bbf7,79d0b699,2faee8ec,243e72c0,7ca09185,d997e581,6709b56f,43013d47,23f15969,ee01b0b9,ff0d9d95,5e2b98eb,7e78e1ad,49cf3d80) +,S(e9e9d7a7,4ad279c5,691367dc,9c4b7bda,b27451b6,a8e4ed47,afae1883,96d8d82c,292bca82,e6d1c88e,8869f33a,7a6df2ec,ad812dca,4c46eab4,5c56c3b9,15f79497) +,S(514054e1,3e7ceee9,3a19dce9,96256b5b,5876a55c,6cab3c48,74b15547,4a58f285,f9ea80de,80403f34,2866dc40,cb0a9aa,4b38b98c,c4c38e3b,37f4da03,fdf7f5e7) +,S(ac0364,eeb9e7b9,b9589051,635de6c9,447b327e,8c820272,f04a4750,6cc5f290,ccde3ebf,13b5a291,a73b0c8b,9a69414,4b217661,7b0a7735,3a6e92eb,4af21b7e) +,S(cf558594,4a73a11a,ef500dc9,60cde799,ffb4983d,ae76826a,a027fd77,811058ba,369ed987,eac1683c,4e8874c6,40049a33,867fa0a,520e5204,df328d89,f197bfaf) +,S(ee216b85,62eaf12c,9189055e,32cc55c8,2ba5e3e0,237de083,a6e77878,63c56291,2a8bad1d,a697832c,856f6adb,e1cc5058,77e543c3,429b090a,1d3cf0,d2df6248) +,S(89903a70,55dfcb5d,175acd28,f7161862,c9fe22dc,ab752d88,3f52801f,92ab1892,e89c4f9b,7954c2b8,cd3b4868,ae171331,871a2693,9355d88b,8d37d4f6,b90c143f) +,S(f9830f50,66b1b44a,89231a81,1192a284,9ac94ec4,13f5223d,51d1e75c,a7727884,18ac8170,58795d51,cb9a5c2c,c249bcfb,ff3fe3b9,1506b721,763c8fcd,7e2ae44c) +,S(326be8c8,55c9f742,19228eae,f7d79c48,b02c2e04,3bc28e9f,275d6754,31afa8e0,293647f8,76b00450,b223e715,5faefac5,990322bd,eef964c7,185acec7,7c105d06) +,S(6117b67e,bbd6b120,906da047,88ad7dde,3549bc5f,c4f80e04,9b216b00,d441dc9,7ebe5576,17dabcd9,f41aa34e,1443e12e,715c9a7,ccfa04f7,ec6a9a25,74c1e540) +,S(1fa858e8,aed841c0,902db240,aa0e4c80,f26927dd,94e0e404,7e8ecc25,216dafce,26566614,2111086b,caff0e12,e4b38940,ecf05a5b,58f3e705,d7011b49,413a52fc) +,S(dd77d202,96a15eda,eef79ced,9b59e77c,1483b936,6e9949ef,ba3298a0,efac4886,b1914a11,80cb154a,f791a934,8c89bb0,70f2ac9b,acc50c5,f75b425a,df6bf125) +,S(e5fdfb45,1e7ac947,ece4e8c0,5b87b9a9,2d49aae3,5ef95f5d,1d18bcad,18053337,841d054a,47b4998d,d3ad8dd3,d2a1ee68,406a195b,1975bd1a,d4194417,fdc4cad5) +,S(decd87d4,6fb74380,56a83258,bee67d9b,1a49e170,bb1b549a,a5c2a2bd,cbc050ef,5ccd1cd3,614fad6f,601a4ad6,e964ee69,a1e06e8a,2e29edbc,7d19562,a4aebc5a) +,S(1a94991b,939bf699,468c465b,5aa4b064,520222,c0ccfcff,193a8484,6f6e4b8e,31b1e6f5,30147e1d,ec0199ae,1830a36c,bcf4fce1,e1258441,3e89eed6,889b9d1) +,S(f32874f,d0f18d03,7f0ae5f2,ddba8f16,fe7ca4f0,d694e803,b9216c59,91bb456a,1dd8f5ed,f228a9d,53cf881e,a4e3c479,6017be43,e613ac30,690435b7,84a4056) +,S(1c5991ef,154b79dc,df2ceafb,3f7fd7b0,7ce7563a,9312ee6f,1dbe5960,f91ba569,497d2a93,28ddb18,221b0075,3432f510,bbf042a5,ebc44cf9,3090d064,4a252a7b) +,S(3c88095e,dce54996,3bf6e312,4dfc14ff,4ed4ecc9,d6240af1,6ecd5984,5f01de9a,499a17ee,e13c81b9,bb7b297,5e7ed1a1,231d9094,348d22fb,9254c520,a65be01c) +,S(c849c359,1c4fdb68,55971840,c0b78bd3,59d1de02,130adf7,e277cb4e,f6eb7748,6add7151,b2640b78,b8fcfdc,fee4310a,4c4c97c8,bb0cdc2e,3bbdf802,750a7920) +,S(f53017aa,a5f79e34,5a0cc318,f40115f2,52ba5401,614b9eb8,ac9245cb,3ca5680d,2d8b8c24,ad89361b,6d77bc72,fb0c7da8,ff129a5f,2bc00e26,e635483e,c4c44b1f) +,S(b3657e9f,84975313,640b7302,a288ef4d,2dbf36ca,651c0189,b39fc10c,87d7c4b0,d821329c,a2f18f94,7a71f5f7,51ac1b2c,e56aa432,992e7a3d,ef84e631,db61fa14) +,S(79942dcf,a834e013,77bb3eec,b7fa31a7,b4eabe7a,578c46d9,3a0dd17c,b3455f61,4c08fe53,c3afcbd1,7fa0a809,bd4ff7af,88713a3e,d7713f82,18c4d4d5,2a757ac4) +,S(e5f14474,619e3acf,905da5c2,3d1bc311,7f1d58ff,8c63ed2e,fe939a22,5fd9d9a8,d4d225b5,85b6b319,431939a6,8e2dafbf,8ed90a6e,5fb559c0,70779d67,7c03028c) +,S(bc5ca503,3ca4398d,5f3c6240,946c5d7,c9102996,e302b9bb,640aaeed,8c9b54d2,ac15cc8,51e59843,fbb2956f,55d39f24,200922bb,6cbf1e86,68ed3ecd,6fae2627) +,S(2f3abe56,d63a2afd,35e35d4f,9e964c61,a5483402,5fea8cfa,66ba9aed,f75947b2,7adeb38c,e14ebe73,8dceae8c,77903b24,3066aed9,bc4886c1,356449a8,27496d5b) +,S(704bf0b5,f564ccef,4d6e5f8b,eb2e90c2,4b46d581,93cc0a41,5bfee2fe,95021b75,44618d17,c54684e,ea1ffe1,53892090,b74201d8,ab3f9312,e7359ed6,5ca94c27) +,S(a898e473,d4b59956,2a905ede,afc78bcc,9f374c6a,f524fc37,86a91375,83d749dd,5452e556,7d72dab5,e085ab72,1168b5e9,c96a0fce,f9d5862b,9c5a0daf,3769395b) +,S(fc4f83da,817b1648,a8a1be3f,dbd0f309,db712225,2988ac8f,64774c29,e8d9d573,57876e31,6a0ea473,3e34f34c,b0df75b1,1194017b,258cc944,7ccded35,19edd00b) +,S(63e97e30,82c36634,d151f0a8,837956d6,16d5d4,64c66373,253bb94,ed5c8236,af68f06a,e045e5be,88242af4,2e314ecc,d719f76e,33092e6d,8b69f791,446c2acf) +,S(4c06073,5107e9fe,f27dfbfd,5df447c,16f1c911,8ec5cfc,8083a588,9dd82b23,8c8508d4,b86e9eac,2058a912,f2581ae7,fe81647e,e27075d4,fd01b051,fe0ab636) +,S(667f609,7b6af1f,cff58520,83175f85,ea01a1d3,c508b12d,a2e19281,c8d8e443,ff9fd0d7,4a0cb42f,3d7ff6d1,67e5a65f,23c34679,caf3f94,ed5d1073,af31607c) +,S(e01e169e,7fbb4365,58e07dce,8f8dead,e2ec2e27,7d18db95,ef8e9f85,ce800fd7,f49f594b,9d60c59d,155ea702,a1b5e3a7,b26aeec6,71b275e7,10d0139a,21041960) +,S(ed10fbe2,565f80a7,65fc90ef,224c7893,cf9df84d,aa0a3b2,9089f7f1,c014ca50,ffc44137,c3ac6fc6,fddc65d1,87d6b456,819ab1b2,df461ecf,899c70fc,59387031) +,S(4563833d,d0052218,5a43bfaf,7e55c2d2,62a12feb,b76254bb,e8310687,e917cc36,fac05d5c,c781d49e,9bab4cbe,384b511d,1c8c1fe4,f68cdc2c,8c576be0,1c669e63) +,S(bf5907b0,1d05136c,b0a1b514,73682fa1,68772a1b,9f5db994,3bdacb3a,1e8c47db,fc69b036,4559f5d3,f9e0c1a3,e4da38ac,b9968e9,17311288,69da2158,2e334cbd) +,S(be106d73,d01ce0fc,5555d4f2,379c906,1ea6ca18,ef8ef8fa,754ecf64,cfc27fd5,9c84f04,947687e,f7d641ba,ff89a11b,da9e9769,8f8ceefe,54e2a4ca,267956e) +,S(5bceda4,2e94ac3e,68f6a3e4,e4509872,4724e9fa,59ee0918,859884e2,2c98f15f,4b19d70b,e1471e3c,7907f797,7311f5e2,ba78c6f5,6f2ccaf1,cb6b684f,7d048934) +,S(e0831b14,fcb2d4f7,3d17b6c7,f6d16803,304cbb32,2bffcd6c,84bdb891,9d7cc9d7,b474a715,5520cd3f,65b64d08,b8e92ca2,4b2238b3,11d91db2,48720a6b,65444038) +,S(df818b88,2300aaf8,41cb3962,2f0c9166,468c1ad1,3aa284f5,89dc354f,bb1fe97f,40f571f9,f63fb358,231c204b,3b9707f0,c5cf11c6,d7ffb93c,991cf7f8,dcfb3895) +,S(d9fdd569,bfc89237,4bc56a1e,e56bab5a,cb5e0ce9,85939b85,c929fde5,82a07bcb,5c56b150,4cf3767e,e22e4b00,fa467b75,4c9ccec4,c1364216,d34ee210,aa5b56ce) +,S(11a93998,d031bc3e,d55e74c9,ab327945,cbace727,647bfcd7,5ed04a2e,4836ba,4aa311b0,6fc8fc86,b67e8eb2,1e75d997,189fa22b,a33e7e99,b07d610b,1c94655) +,S(7c4fc747,7319464e,2d71f787,80aeb385,aebb0420,d8f8588,9652d5de,aaad580d,31d6d7fc,2cae58f7,b3e4804e,f615d7e1,edf9d06c,d1035b30,ee9b55b,21b06eae) +,S(83704a5f,4ef8ca9e,a3d5b163,2bb3df98,acd774d6,4e07b219,b9a36a9,ce88e1b7,52976995,faeb6179,bde4c123,1437dc73,b53b6f90,f0cce08,1e3e1644,e1ebeb18) +,S(5de15f19,21258b5c,f12f240d,147bd38e,fd5e3c3d,dbf148c5,9e541c01,ca7d724c,c0e18562,1500f0,e3fbbdef,45550e16,5fc2a2a,adc72558,e49f1e3b,f5f4fb00) +,S(f5d1fb46,e3288419,1f2cc8e8,2ba81ba7,5bf1d7b5,97ff82ae,8731d27b,7f059938,3d5118fc,9acc8394,9e0bcba5,c7c79fec,2f0cad64,7910976b,e4e8f9ff,43d8baa0) +,S(8ebe619a,985f720b,9381a99c,db63d089,6a787dc9,7d007354,fa83b931,223f8596,7968b6fd,e3dcc13c,512aae25,d9a8127f,313e2d9c,34489606,864732b4,c3b5ca1f) +,S(5b14482d,f96cb0a0,5664bcdf,e4ff7b87,6169db9e,8107b0b5,78baba9e,b1f8fcdf,19a4ed84,cd2ab376,b1e0c2c9,ecded5cf,2e874f09,6d84d946,22be5806,9f8a5e82) +,S(ae810d52,7f94dad0,d140877e,ddc5e0e6,cb636325,f4c926a,1a263f1f,beb9a8b8,c94f0c8a,f5ceca8f,ea29dbe6,c8afa649,f813744d,39e303b,c1f0c135,867658f) +,S(38853d15,d74060fc,7eb2a56a,b8772f6,855aaf83,b731d853,b99fde93,e7c06e7b,ade73ce5,4f513c89,531b5bad,7f47ce7e,a498da85,e378639a,5ae0507e,1f27fa7d) +,S(837a1d99,db477c6c,da832700,37f111f6,eec5402,2bf74773,4c18bbab,35b503b4,ce852762,ed9b36cf,65602da,cfd3a250,c547a971,1977ba86,64f72cb3,89ac1f8c) +,S(3136acd5,a1460d8d,717e452b,a2069b88,4eb6fa81,756f8768,932c210e,df08173f,42ad61fb,edf97b53,f59ed7b6,afaeaadb,831134ef,73e33b1e,26b2816c,99fc330) +,S(a9609269,c3ef7f09,2a43e394,e482483c,119d94df,10bcce43,6691230b,b77d3201,8c580df7,9147069a,5c84abb,73e28b6b,ab9c7c0f,7803d6f1,d9fa86c8,f324be1f) +,S(3cb613e1,1ce19ea4,a8a90eda,cb182c09,5b1601c4,92822974,6ec22fda,be699e08,f05a18f5,aef9dfe6,87e69a9f,287fd868,4c975765,284f578,50294598,51538b05) +,S(b41c56a7,47232950,7777847e,178eaa67,ce61f561,21c7f21,2c525bd3,e7adc359,b0026b4b,6f9dc954,7efedd80,d914a3e9,65b17378,e6e0055e,527f6754,c5c589fb) +,S(f44724a1,3cdcf9fe,5b4a8f3a,f0d3e076,4559c14d,87eb8ea3,803a41da,9ee9dbf5,355b54b0,7ae7c477,9eaa314c,953340f2,f5583ae2,ba730339,acd231e5,c3d64627) +,S(6fceab96,d5851eea,b5db9caa,9a0ff7e7,86c2e097,5c2207d4,67f343e3,cb36ae1a,83f2b505,20094ad6,cb8443aa,69b8af96,b531341b,81cadc21,565d28e7,43bf2c47) +,S(2acc57ff,ff168361,9275273e,9a821fae,54947539,7f6b1936,13917af0,ef83cab5,764b04bc,9068fae5,75a202c1,f01f87,f3650358,3f5d3042,1e246020,9fdcb94e) +,S(2ac302a,28126e57,5e6aee8b,2b12ad19,f5e1c056,2d63d73e,80204b1d,1d4227d2,74494cb4,1e7828f6,9d2dd529,a70f2e52,9bf4b524,26a2a3c1,ab10a974,99624589) +,S(c5de085e,4dcf8dab,497a645,c7abd513,4054b225,32ce8405,f6e5134c,515d9de3,d1da7171,31a859a,a2c90816,386f0318,9759326a,6cef86f9,f3425bf2,390bed7c) +,S(54729254,5f78e410,db85d01a,182bc5ed,84bf6843,3b5784cc,852d3e70,acbfe90b,618b0f0a,7919751f,46c0ec61,1dddd798,cd89d4dd,32d1acac,31432308,d1a615ba) +,S(c6fc6b5d,84bd05b1,ec8b0ed8,fd4eceb9,dda38669,3859d90a,a0853c3,7f75e8a6,d3d8ffb4,988f7e47,2c26bd4b,83f95453,149d1534,bfafa97c,39a1e8d2,70c53582) +,S(1e325c1,ef4a976e,77d6e76e,f9a6dc51,175175bf,23e2c46d,7203d6bf,86ea05ca,60f35511,510aad52,e156e265,6e7ec137,c319b8c1,a1591258,590186ee,be4c1471) +,S(bbca6232,ed8c6093,7ad123f6,87af56db,28947e01,99340510,95850d38,6ac1d89c,d1257327,269836af,2793a1ea,21106bb7,ec95885f,de541f66,1a4a7c38,39c222a1) +,S(c55b1ec1,1f7aff98,710c3b80,34021aa1,83645a14,edfc6926,cd56eeb,f1e5332b,e541bc98,7ecd2b66,d10ce29c,572272ec,28c26b1b,1703919f,d0b28e76,4ffa87df) +,S(f026dc49,feb91051,68f76b0e,7abcb9a3,cc78a5c4,e520c2,57d2f688,5f1c49df,2471f06b,5dc74f9f,6cca7d72,86571c1b,54ab3813,d30bfb57,53274a4b,4257f5c5) +,S(3f721c3c,605169fe,dee4a4f2,b07865be,e1f0838c,669f7eb0,f234e700,f2fb16f5,9691b1cc,ead5fba9,9d9f1feb,fae6baa3,cc7717ab,c5a671f3,8def1556,e27e100) +,S(65bccdce,bb7e968c,a1c5dd12,2d5440b,97b07014,9838f4ae,95962044,b822b0ae,bd594952,f8424625,91375009,3cc6716f,cf7bae14,a6fbab35,4a962282,ee0b3fdb) +,S(6c155658,7020a902,c225d721,7b1a5f2c,5646179,df5613d9,b95826ff,7723f42f,1ee346cb,5841939e,42aa41ed,84bd24b,33075490,68de1809,8e5f8605,59e9c073) +,S(d2c9f745,8f75b42f,b48dea34,13b2bf9b,dc045542,8c5a3dd4,2a08716b,bfc4367,e2a9be5c,8f06a432,6f148cb3,cf58f767,cfc8f8ea,1ff4656e,ec19a64b,183f650e) +,S(aa11c12f,5fda607,aeb4af7f,8430cae,3f5df00a,43910ff9,e413b3a4,7295a38,e506e63c,a0568d96,2c489851,489fbb62,acb60d9a,fb9dcf1c,7aba7be2,2e02c67e) +,S(a355e383,43937932,21affe2f,843d2541,3faf807a,900bc299,5a201f10,d5748f99,22ce77fc,c627019a,ff0245d3,ef2b31fa,55687ea7,69a4948c,5656945c,c5a5c74) +,S(d8f4e393,8b93f252,da68e1b0,16fe8889,d837ea8e,61e5d3f6,8928bf32,22643cfc,c895006,61003ee5,3d8f739,d6fb7cea,e2f7b414,28a65ca1,bf493a3e,27a2e826) +,S(f69ff0ca,3aa0ee7,122a00a9,4b6ef41e,13945263,96e8c590,84ab2b37,6b899cfe,a5211104,271a3020,d65ca305,c0daa6ac,cbbdb1b1,d349a2ba,1abcfad9,bf63a7d5) +,S(64b1b59d,7415d433,7f5b9a3d,98f06d10,7e647525,b347011d,6d3b423b,2a377592,12ea2814,ac8e0bf,1da8e617,c8f051ad,5799593d,f9ffc1f8,abc963b0,faf202b9) +,S(bac6a7ef,9a3de971,51044204,ddc3a2d3,4668613e,101a7e6a,5f93c25a,6b20dca9,7bc2b764,57620478,321de1fd,8ae8afe9,6047d087,b95390c5,bc69b972,654b97cf) +,S(fddae798,dad79951,a4c3b803,11ced882,903c9dcb,4d4dacca,c4cadceb,b837f688,2e21e1f9,f45ded15,76829823,4892d2ca,26ad5b6d,7b0baa77,c2dfbba,b1dbca19) +,S(3dc783eb,40779120,25b7dfe8,f493f073,b3a8520c,ef0c94b2,1c3a5388,b0a9a01a,b3fd9020,2ca16d20,fbe8cee8,fb8bcbcc,821696c1,15545aae,84c414a0,c4401bb1) +,S(299a187d,299c61cb,6893a5d9,cc8831e3,df92ab13,da2f0048,555d1358,e55e866d,ef0b105e,52a18751,56080cc,cefde2b2,848d43ba,6d650068,2b71fb9d,d34b819c) +,S(b690b4aa,fde43b5b,362de597,100c74d8,97cbc750,688a46b4,cb1093e2,e253dc4b,affd5af2,30e4de4f,9971627e,dac86808,c97bfa30,f051af29,bf91e36f,c3edf0f7) +,S(7217384c,1596318c,2a98db2b,7264c909,f823de21,702f5e64,b19af937,cbb8be39,b125b7aa,1bd67232,df7d2d3a,a671bbc1,bace159f,3ba2fad5,e82a1ae3,965d5c01) +,S(4bb4a86a,58f1248a,11f61599,f420fc69,bc77b7c6,86d2838,f4368971,67013852,29909cb1,3bce655e,88300d78,4f7984de,352c9b9a,960148e,a5b65acd,99b62d4b) +,S(4b3a9328,2e473993,9d7722a,7de44fcd,51658eff,93c3711d,3a8f0193,9a54902f,9a012a8e,7df3b988,204fe0e0,50cc197f,a27618ca,d8d712cf,520c7be4,cf4e0f02) +,S(5488985b,26978af,50099d93,8d7b1aa,c545b07,44938190,e0b880c2,11782b26,b51f749a,76b998c0,83dcdbe7,21d5fa0b,c4aa4392,f81821ab,3436fbf0,37d37bd7) +,S(7f2ff4bc,f270b566,d2d26cbd,ffeb1b9b,31b2cd7,b647d89a,2c86c003,b23f644b,f48749b6,21ed28ae,47223281,fe8e633f,35580bf4,8eea29f,d6aae487,ee8e0588) +,S(3305c475,1d63baa8,18f5bdc0,b4e46c9,acdf1c42,9ff5d177,bdfc214a,b838efbc,491d45be,85ae9675,310ae85d,258c6c9c,8e28d7fc,5239363c,911eb12d,ee68a435) +,S(4195dd13,ae5ea569,179dc64,b07f66dd,4a2e2878,d81a222,304d6a88,4da60b86,bbdb99ff,8d4ce150,543b48ee,9109f127,5234c69e,52293758,d0171ae4,ecd49677) +,S(8dca7466,8ffbf319,7dd9826,cfc7f450,fed841ed,83e1d466,e92470ca,1e2582e0,2b19be5f,69fae0e2,563a3f80,2f9450e0,fc48ebe5,973f542c,4c12fbea,97627e57) +,S(e235d150,3449667e,ba23d119,9b5225db,1b26220f,60f84476,70c6bdaa,f5eb7aa9,3d4d8dd6,b0c8c2e0,c8f54f6b,dffe8dd0,5ae22d5a,b4f9dc18,f17acafb,3fab327) +,S(aa214fc7,23c3c458,8bbfd962,b86cc3b3,e1ed52a,25524ed3,ee5c4933,1748ddf3,9b54e29f,63240e30,434f7a22,2679006c,24593e26,90254978,35a60897,d3578e18) +,S(1c468a51,cc9d2632,860bffba,9ed83e5a,e97dc1d8,c8bc3577,5dfef223,b3ffcc73,fc569e94,8eb20528,98b4cea3,86486afa,cec0188e,44dc4e0,25b34855,f1466e87) +,S(c663e752,ce62dec0,81f8ad57,3e4f5c92,138e6a8b,e6c9d015,d5cd2cf0,ccd1a203,ffc249a7,554fb97,c0f9d96f,4cb06fb7,ce6e868c,e7e60b30,f67a2b9e,919f6f98) +,S(949a84d8,5f68f70,81f379e1,9d673748,bed14bb8,dba2458c,34327c03,c893067f,1b9fe41c,f474e57f,8497f6f6,76472a28,fba6b259,91297f81,474cb6fc,f31380f0) +,S(6a4bf3ea,5798c8ed,4b35c629,c6cfdc0e,d16d0d27,39f8bcb8,c34a9105,fa35fed,6f69e357,d5123305,56d04946,f9265353,77610fee,20667815,e7f3cb01,e8196b24) +,S(d0a99a37,d1df89c0,99b0dc1c,16f325b9,b2ec1455,21d4f80e,ad67da85,4f2a5357,7a75846d,eaf7c4e3,5c0c87f,83732eaa,7f6903f7,b721648a,87e1909b,53d3e9c) +,S(e2a45683,f3781309,b6223a7a,5ca64c4c,cbc5d45f,29c66082,912568ca,3ec6d3c0,8e386acb,63c52ed6,5aaacecb,fab458b9,9585951e,cd0e35a6,19c0fc39,5ce1c0ab) +,S(9527ae80,10ddd443,7237c2b3,c8f3afb9,f31e1696,5b10fedf,f150c296,3cb8e60,6e0843a,87833be4,f882c417,7198d985,5af8b144,11e78c3c,497fc49f,5f728479) +,S(15f15c4a,2cc43062,d4360a8d,dcf8e0f,52bc4741,c7924f6d,e1dd9f12,a06b9b2,66a127e7,2c55db1b,57050f4c,a0d8abf3,9ccb455d,9785a4f3,2ee67a42,3bfe5ccd) +,S(558648bd,64c52dd1,189912b2,67078e8b,d3c68952,47e6c848,d7dc529a,7a24a75b,12332187,62872867,5bc88378,88deadf9,3a8f2c5c,864371dc,6be0be63,44fad7ed) +,S(1e87928a,b6e10b59,6b231b08,87a823f1,3c6b3ff3,2852d35c,d1167244,fea2db0b,4cf60a4,767783a9,1c9747c5,7abbade1,3d7fc02f,e833b474,648038c3,b68d96f5) +,S(7a169de9,1d4c3f0,3296279,2c3ebfe7,f2eb4410,f7b9a34d,c402ae64,ce9231fb,1ca2e8be,7a7603b7,d95820ab,86487a04,c91ab3fc,c88e2f0b,514a1589,3908e463) +,S(65185a2f,bbc8c96f,cf9a6df4,d002128,afff1f2e,5c0182a2,95639a7d,9fecaafb,10b6902e,e83c5683,3d796b99,665cf365,c1e41d63,41fe72a4,72e5ea6e,39dbb9e9) +,S(61c45212,4664432e,8fbcd950,1dbbcd9f,1fb8842d,c8e61758,439b6d5d,bf8dd626,2a9c7c57,48509dca,ebfc5062,4d7a0b0c,21c9f5a,45733f8d,e0441bf7,f2b359c0) +,S(f61aff9e,267b6d91,e3d4ab45,73457987,b1af9a9,38b659f4,1ad5cf57,8cc59d62,51d0b694,e5692be0,6841a3eb,160474cc,6c248213,19c9648,c32ea444,29cb2553) +,S(29f27a51,8fd448cd,73aee0dd,7316e566,c655ca44,afc5daa3,ee359ae5,b96f8bef,d5957a97,a6447a8e,a8301219,5fd53c1b,63784a8,14c29c80,d0061fac,2c6cc1a7) +,S(c656d66a,efc3597a,2ee977ba,bdb7357,a2485a6c,d654c56c,bc58a0ad,598f202d,f8267b3f,f293a5b5,11f4e466,dce0fa88,a37f1603,a3a8092c,934fb824,1427a59f) +,S(f28477cb,efe654fb,ccd3a9ab,e816f950,3749e183,3b1faebd,418c85c9,112a5135,9df0f505,6ad98099,ac0dc723,34af973d,9c98c597,ee26e22f,a0a7a60a,a3b76cb7) +,S(d007a1a8,b6f05046,a66fe0f0,9a02e510,3ca7555a,277c40a8,87a71920,5a429e79,d9a68c51,f17fd51e,b19e4946,694e90f5,2cf664ed,d2d45489,5f880400,b410b8ce) +,S(348f74ca,7e5b1ff9,e6ccf3d9,90ff1f7a,4e3a8296,725075e0,33a85b2f,5ba0f338,1648c7f,32a206a4,e21e7309,f1a68a4b,b2ee116a,f3fab3f5,7455da93,7c4afc7a) +,S(1f54e125,7ff3dbcb,f1b55720,564f0c72,d322b8e1,f14d2b9c,1f6244d9,c85f6f70,34c23405,4a970b58,2cbbcdce,e67cc564,6e187cd9,b3024dfc,731a212c,c53c2861) +,S(a984f8be,33360b3f,a012cb99,65ed10e6,43a8df49,26f8188f,24719a7c,ad6b5238,79a592f9,15c925a0,98406d08,75ec4fa,90b5015c,4001addf,1cab32f7,9f06f213) +,S(2ca5e948,76db7877,fb828609,68e39c8e,a413a057,1a39e20e,a7b98f93,f4cc4887,b1ce7c2f,8380eaff,57299cef,e840c552,53629691,7ed367a3,5c59c3b4,ae67a02d) +,S(65bc7a84,15cdd07,5f493310,de05b7a4,ae7c874d,5b5221d4,7ee556ef,4c21a0d5,ad20620,aa39a14f,dfad58b7,9f1ad70d,2c637119,d9eb33b7,ca9abca1,f5dc3db3) +,S(a0b6b293,a9e25a97,18fa0db1,16362757,6e39cd43,83140822,b2241fa8,c432f276,2cbd88cf,29570778,8a6d79a3,b451833d,c596fa08,8b26c6a9,962880bc,48ae2b19) +,S(b4d308f5,74f7832f,4f402626,5ff81788,91a86724,9df74486,f241baf2,28e130a3,ca82dfe7,4c5768aa,46927fe,70c93227,cc7c30ed,c2fb6303,9a1552db,534019f9) +,S(819b48da,f19c48c1,f6efd0b7,c4ff5996,dcd5e99e,7146bde4,1c83e333,ac891b3e,c15bcf4,c9a630f4,e1489585,e5719746,ac55210e,c9b82da3,898a0d88,4eab0459) +,S(66528e21,adf8c447,526d616c,777dde1,fa7469ec,175facb8,3ac9ed2f,db773f85,c5d38c7,c13449ad,4f346498,1eb7abbc,a98de561,d94f46bc,edf3dd10,1839d91e) +,S(a26e3a0b,6f61c611,28c2afc9,15ddf48b,8d3d3901,df93a2b2,aeb82579,4822e605,41f4e806,787884ec,84716647,ed72f331,126f141,6837a232,e1612ac9,99c7d115) +,S(56623040,c198fbcb,9aa32066,90da22a5,a0496a82,5313a2fd,529fc9b,26647d22,35867158,42a4c950,e67b9033,23c55fe0,3ba3bf92,a9ecc5f8,39708869,7e2e1e98) +,S(acb401f1,b535f181,75ba9cc5,8e32514b,be8b6d19,1401248f,20500dba,23ad4f,f57fbfc7,9bb94ec0,eac7d09e,52b699e6,d8407335,e6dda706,f7d1bfe0,71e09f6a) +,S(9e02a873,fbbeddcf,b760d48e,6e29e6a0,b37cae8d,6348a8d5,bd651be0,59ecdb33,9f926735,cb2f46eb,71005600,56dea853,9fd6d140,2a57d05a,e884e8f1,1a293c39) +,S(3e88f76b,ec410c46,ca20cf7,2d90c66f,476fb966,c46f20b7,facb7f50,17f71617,bbbb4d9,a453277f,a7bb83d2,eb8b2950,3fe51b0,7d4b93fd,5e993663,9b78438b) +,S(cd39870c,a6484a9f,e6d30e47,3a6f5e8b,3ecc1702,e191b5de,3d4d6cbf,dade08e6,234240c2,8f2b2233,9369298e,f22cf32a,7663edb4,2524f02d,6879b4c9,f4ab442d) +,S(5de275c2,69799058,3348c4cf,8c039b44,daf431d2,b7b1f862,98ae24ea,271644c9,adcf9fc3,10ce2d93,8459db47,30273255,cc483342,3f6bd4dc,56593f06,6466b8a9) +,S(2d986200,bd9dbe51,eee40ec1,2730701c,621333db,9e71c232,1a6463e1,f26cb76b,57433deb,d9149b32,37315114,e9747758,228d17be,5f7c54d4,f552e730,1e094329) +,S(654868b7,39d6a72e,75223cac,d0f827d1,789c410c,fe0d5ab7,24cdbc2a,c9bcb269,3d8d4270,63cfe,6724f8d4,77ddbd10,b24899a,3ab0a33d,87683646,9f4806ba) +,S(d97cf5c8,e1a40197,75312099,fb1a2d62,2b3354d0,e524cbe7,bbd3187,506f909d,53c8784c,cfc900a2,f159e98b,76481239,3d883d70,8a953905,44691b5,1c8c97d4) +,S(697707cc,9c74c828,7396d53b,9e5d436b,24b861d0,2fcd9208,dcdcfb54,8ad2d903,bd203dfe,7f4a3484,1f5ec966,f063d251,a89b7da5,468bb2f7,32775a1f,3a62412f) +,S(36b4329f,fbbbd80b,e8eecd1,358c05f3,6616b456,588571da,c23d7752,edf15d65,7c42145,d8774827,a0cbe9e,b9ca7b90,2353c6f6,118291ad,950dfee6,124fef3f) +,S(dad2b02d,a182ef28,5b00b0e3,2af77064,ca6b3c1,41766194,7fae0663,4861e144,ece34dc3,704d0561,f6029366,aa45f192,a2b55b1a,1786e8a2,d84b2361,eb2c2af1) +,S(4cdf386a,c0e7cbc6,e19c5f85,1edb009a,59b0526,f3f4d0ca,3c82f280,dd33531,3f8b3eda,4ae484e0,95916efb,ecf1ed3a,27bcb034,6cbae87c,6a388488,331ddc86) +,S(d4b65a7a,eb74d38f,2a8e9383,2ad27a7,2e2a89f2,2ccb5c24,9e4e55d4,da7a0cf1,a080a32c,ac9e0ee2,6e6538a0,233f2374,3428b2ad,821852fa,bbad2a23,63a7d7e3) +,S(c41cd230,d99c5f66,7d7ea000,53945fed,70a2a807,4893d488,5be2ee46,cadff9bf,4a7faa2,3ea4ab42,5f21e12d,dea7530d,429c64fb,c05e1b24,adc24f55,c34af43) +,S(4c67ce59,9a841ecf,ec147a89,c120619a,227100ab,c5dd0ba8,da6d362,6f687824,aec0ecc4,b65694f,150da4f8,fd514d37,52f4c6d1,aebd8b5c,19846ea3,bf4b13b2) +,S(e765b00d,a067b5cf,a40bf02,dc8ed6bd,4e59b470,ed6eebad,c02b49eb,1d20c37,23e0df00,9ca95773,a91c0805,40b024b8,34c0d7de,4dfd6c43,76c979fd,2665f21d) +,S(18a8cbe4,d7585fe2,3b958cab,a9303d9,505928a5,7ca1058,21a9f192,ea52298c,9d00506,4a1f3406,c3864d73,2ebf3e1d,b6f20234,d0f5a99c,3623ed9d,530d71cc) +,S(2dc043ea,a53c27b6,50e2f1c,b6fb7fd8,26c4fccb,9572bbf5,103356bf,87b3d649,2695f192,af96b031,a41b72e7,a61593cc,30672c07,cedb0908,35ee207a,5cf18271) +,S(71699cbd,e1efa1f2,914bd0ac,9b28111,8053f7ec,d51e79c0,44daa4ac,ded9c9e9,8519592f,a3b05922,86797110,b222231c,fef973bc,d51ea4c4,34998999,63637c05) +,S(23f4668e,40761e37,235dc0cd,41b6c7ff,1951678f,131763b8,7d394e12,6be4c370,1cce4181,2279761d,8753dfaf,8bdd206c,e4cbfc5f,ccfa8826,9d2d4327,431fa689) +,S(92366959,9a173d3e,826233c7,8062863c,2a92b525,106c1159,4885058e,4a7797a6,d1c9f57c,d03c0042,38f898bd,cb45c064,a1f2cc56,222bbc03,a61997fc,877b23d4) +,S(a2dd03bb,a75a7bb2,fc9915df,c66c0b22,76a7347e,6cca3d32,e5727cb8,b54bfb70,9ba4266d,b9c66907,b25c41bd,b96f8a94,a9559830,f171a878,66372067,51c7126e) +,S(79174d3e,2379484a,d3191db7,26073dff,d69a31c8,94314f7b,282ed68e,71395ad7,1cada148,7ded181b,f1a9cd30,21afb04f,4402a171,3a570d7e,9f4928c1,2069315) +,S(874597e3,80449235,af5c10e3,7af7eeb8,f755ebe0,6784d5e3,ba0d1021,fcd3b12c,2ebbde83,58c4f2ed,cc89bd52,e6cd61df,a251bcf5,713858d3,d247750e,266a6129) +,S(f23c1888,c22a764,c85c6328,387e9126,f4ad772c,fa0a6034,914d5f60,7efcddc1,6cd5bdba,cb3c6cd7,4c2c5cf8,1c62e774,560211ac,f1ee8096,be9eee5e,b716881e) +,S(a4c2054c,3a834498,6dcca592,db5fbe06,7f80d32f,8c492436,79c57b76,ae13b96,7ca515b7,8a3d5590,6100ecda,f7066459,db9db34,3bec1b4c,6a57626e,1f560444) +,S(d6880dbf,50d3faa9,835404e5,d723eec8,b1bae88e,b8ca22bb,a85fda5b,6a8cb669,a08c4200,718edd4e,42b775b1,1beb9a6f,eb3bb93,b54c57af,5218eeb9,7aa9fa09) +,S(2dfcf2b0,babd3990,c305cdbf,cae7795b,a2fb3cb6,3ea0cd17,787122ab,5af86bb8,e0e921a,15882601,c151fd93,d7b7c607,cf033633,e6498004,d29cbf76,7fb19f6d) +,S(d1dc82f9,aae7e02e,177680f1,e5d73ae,8a178207,7b5ebddf,45b56bac,fa1f11b1,4c9294c,e3ad0fa0,ceefde5f,fd80905f,ce57a5c7,c6807da4,186c9b4a,7c9d6237) +,S(ff111200,4231109b,d131e7e0,f6434461,ff699d8c,6be3e6bb,7eb9e827,9af4a4b3,2c30b8db,bbe56de5,3d8b3307,9dd741ca,8c7aa596,78a3c75b,a781a77a,e470620e) +,S(9fc4e1ac,28a8f268,c66aec12,f5e795d,f3dc23d5,c515c5ec,11c394c5,e6f2a11b,188bc037,ab114fd6,508627db,12317d0d,fa194cd1,bfd56c1a,4ba25d07,206aaaa9) +,S(bdb0b373,5bcad639,386579e2,aa78fc40,ec2f4700,4b3174b0,1bc2cfdf,f4164f95,45d65b9f,eb1f60f3,29195060,78d5c016,8c6b1820,6afcab34,a2623e1,d2bc70a9) +,S(1386e11f,3950b8d9,e87589da,c3dc9a47,bf36b0c7,8378d2fb,253e5bdf,9f704465,415f50f4,f048413c,7eec4c2d,122a4f7d,f4908265,31f9dec2,313bc7b,b1b2402e) +,S(be246169,75b321a2,edd491be,90b7a11d,75a36c12,ca782d20,732a285c,5a6a1572,ca9109cd,5b041864,5026977,9490edc9,d239778c,25609736,7b52d82d,97f588cc) +,S(baa5965a,c352a017,80b1359,3945030b,32c83b60,805bff01,476ece26,cf89384,c83a9515,dee6663b,b5688d5b,483f0a2e,51c8180e,a130e0ea,48f7a4f0,1d3d06e6) +,S(17dfb33b,957bd5d3,36c918f2,cd1fdc95,23e2980f,20a7666d,bd5e8a7f,8ab1f83e,32ffdb3,db6dfa31,ca67a5b0,27a648be,b978b6cb,7ace4241,a0b6a7d8,ceedda20) +,S(ec5dce25,af07a01d,9dc43a9,e92dfb51,29146307,cef69b48,cb7b6e85,d9cbd91f,1018c449,949bb2cc,e185a9,4a9a06b6,bca4c8b0,1a3079b5,3f86d830,21d46de) +,S(a56b5b4e,d4e4e3a6,29701889,2cf21f67,868ebf37,b8696ebc,83afd980,b5c63817,1cea139e,521c70e3,f0a4b02c,c20345df,90a579b1,20ea5dce,bc1385bd,162adfd7) +,S(2ff27783,681d264b,540df574,b478e3a6,2b919e0a,c4ab1b66,3e279083,25a707b7,3a477dcf,65b233e1,34ddae74,7fa5971c,cc0498e7,be9f17cd,5e34bb0b,480d360) +,S(aea30054,dcc9f7eb,c9dbbd45,cbcea779,49780d59,11edcc19,937e6352,a726b3c0,7ba5e2d8,9f681e00,bb74a353,f37c36c0,7264acc,d6a31529,cd5275ee,94a631fc) +,S(78531772,142432df,81802ec2,84884682,5ae2bc93,aed1fa8b,e345c106,7e23d059,6b8d514c,a0a13c1c,6425e5ad,f808aeff,f88fc6be,dbdfc788,1d174868,efd21063) +,S(c104c683,8448cda2,c94b0303,7b5ddcca,d4db1d7e,e744e70f,5f9275b3,244b8405,ac9e6545,3722e2c9,d7d97aa,767c3235,2a213391,aa2e327d,3884ecd,93f4b133) +,S(d4b02b47,3f851a30,604356c0,e9310d4d,7bd0f9a1,17db0c90,54862b58,969887c5,d451896a,5eba571d,4e55d26,9c3c8082,55c5cf18,f1f2d033,b8d30788,224a68f2) +,S(93d2f6a3,e97e4aa4,10fb6006,f3853f85,65bd14d,aec87192,e61b8f97,93f29b32,a0a840bd,336034f1,a98a0239,c6ab3ecb,eadd69c2,51b2e03c,339dd4bd,7a407308) +,S(7d7d7357,467e23a1,2022788b,2ada9a69,1243fbae,486cc61b,56458e2e,781f8f3b,59d5566d,97bb583b,940de406,44e19530,b1bc7ced,2a00c50,f4bbef30,d899e7e6) +,S(ea80f7b5,8c72080f,f2d83604,ccf6e4d3,28a71914,abf94888,8dc87c42,15fd4a6b,ecc6e626,f01f73b2,5d7e92e0,d1220b82,8f2f8ef3,3cc92111,3d15bfab,179ad8ef) +,S(c74366e7,26949fa0,6913e6ab,c41cb17e,c3837659,253c3038,30d543f6,ac0e4aa6,671ed272,2626ab33,14b6b1d8,1cda24d2,9fc132f9,51f97b95,8e72bc0b,9eb42d3) +,S(6170ed4d,c3dc2218,2b45c1c6,fcee9fc1,3897ac17,fc32fb25,aaf2880f,4cbd11bd,cb40f34e,7e8faa89,71338834,21cb247a,4c938f3e,f6a97cd3,1711f803,c872621) +,S(7dacf9ad,5775fa62,f99e093,5e948526,b94ef22e,912ae95d,8dd4e5ba,744a2ebd,69931690,6c73045,d8530a39,d33a8e21,d5912969,9f7b721c,1dd0c616,725d5778) +,S(b1d113f2,ad7b487,908767a0,b6faa413,6a8b3dad,41dad9d2,b6e8e7c,9f294639,7c802cbf,4596903a,90b1de93,649bff3a,6f63ab85,a9e3529a,7d907b41,7f973b61) +,S(d09d8d8a,17a1b113,aaafc270,db36ed63,4342d90c,64b6ae97,9733391d,eb67f3a4,c48701eb,738c3edc,a4f78313,a56660f5,3da8ebaa,3cd8d469,d1dd5910,c618851f) +,S(c264ffb3,c223e60f,fa34faf9,feb18668,4b05b7e0,6770db1f,9561ed5a,ea0bfef7,e4df501e,ebb4cdce,bbe6c4cc,b966de77,18ac5479,3e403e79,389ac330,92928e6e) +,S(55505edd,605e4299,afb5a69d,81f6df34,c7c2133e,dbc7bb10,ebc49187,857d7c49,ddc19610,7c3bee6d,ad955e1f,76afb31e,93a88e4b,de8aee59,aba50864,c295a487) +,S(9d61801b,a07c358c,f9942bd,d3614d3f,74904b8f,8f8aa8e6,a957eadf,79fe99ef,7d9d5980,2fb5dacd,93ec6c6a,92ef86bb,6079076f,7d964d31,70e3ad3b,7bb854a5) +,S(f1a6cc66,3dbf46da,e1ca98af,610f09e5,e9251a44,f6b9915c,b68c58f7,9038645d,e41bc6cd,747c0390,6d29e29c,4cbc2dec,6817114e,daedf220,b7fce48e,7e6f42ee) +,S(df247558,50b523d6,de15c3ec,38537a3c,af9a90fa,2c0e8b25,35696289,10517a79,bb567ba,e42e9899,85fc478a,4303188c,2da741fe,bbd1742c,818ec1c,e64818a5) +,S(4dc30b60,b174bb78,1f339277,ce3996f7,fe102e13,d80873b1,1a9e6b4d,54247cef,b13e5069,a7344a99,4f9cd284,1d9291a6,50e1d969,dd3061dd,ef34f037,7c85e20f) +,S(e77aac3e,946f7715,b9d0999b,1f3aadfe,de9c31dc,f8eab336,c5bcaa51,f16f64a,9d78c14d,90cb37a3,835d23,fd8d5a37,2b8fa160,1274e5f0,2bae50f1,587a11bd) +,S(24f29bd3,51e62864,3a7d2fa,6c47ab78,a6d0c6f2,c73bdf00,864e8bd0,c3f038d7,4a34c7f0,22e43220,f6d30d59,3d3ccb54,dbbcc50b,4b845712,e72636da,d0cecff3) +,S(ad4b9b47,b9cac9f8,a5f3728c,ec610000,163ac2ec,6a18cc34,b630134d,9fcc9364,afc8726e,e0f988f0,53247177,1efb25ae,e07b70ba,ec7c425c,50e3eae,2898c077) +,S(1d38128d,ce7ede1b,265a4f8c,4e6b911c,d0e28087,87244a60,dd9f646e,2932e509,857a6c8,e4f43cfe,129e11bb,462101d7,9c76e99e,c7b4aed4,efc029be,b1b9c1c5) +,S(c171b7a2,7badcf84,c3c61afd,7568d23,5a14f0f4,fec777b,4a91c92c,61358677,cde264a0,48d2cd4c,d53d7371,8546802f,1ab67815,d6ebb3cf,b6415f4d,5cf4057e) +,S(d50f20d6,f4781aeb,eeca2a8e,85e8b75c,187c6d34,a940266,daa16876,96acef4d,9aa99671,35a1dae1,af29ed05,9fa15eb2,a4aaca27,99d98c64,5ae0ed03,7f08f37a) +,S(6b83cb07,7bfd33d,181fc835,63eabdd3,a50be6d4,abb64a16,e338f18c,c098a977,3e04e660,cfe61fd8,1ec67b2,d20ca9fb,f9c6e038,71f7c838,b261ade0,51b564e9) +,S(2e75abad,dc0501f3,afa90484,e85972b2,679d1d04,62d6d206,42c73830,15213b19,4754077d,a6868edb,a0943397,3c60a581,88a55ced,dee38351,93ce045a,e93517de) +,S(8a322085,d749f63a,38dcfbba,624d0c87,b9bcb66c,e4e3d84a,e97f7781,a0e9a164,3b592b8f,9d8cc10b,58fbdc7e,982e3fa6,7aa67c90,e9ca884a,e1f57291,6d7e2076) +,S(b890b7f9,ba1f1945,2a7bf1bf,944f9949,36bb4ad,5e2e0fb8,15ddc1e,2f30d72b,c1b652c4,f8e9d91c,8a92f76e,f6f72ed3,3357b35a,5ac00d63,a039df78,eb778a46) +,S(cdf33d41,c54c8a0e,dd3a0b1a,12290d13,715de82b,21af5306,a1197444,acfdd5c9,2d7b78f,31d08fc8,afdb3940,ef1afaf7,3bf37029,1e1be3c9,5acdc673,ee2150d) +,S(20b24e10,c0f85631,fb891ae5,c0b0b36e,5a3829df,a5018c1d,8b59fe87,b051b55d,b5b9204,67394039,df0a34f1,308b086a,454c7957,40d31fd8,960f6ab8,33998c41) +,S(61976c23,257b9adc,48147038,ff5ace08,39d88274,9810bc9,25590555,b0e1c709,2b31a4c2,a712edd6,6b2da3f,84447c73,f2e3f652,d22b81d,d37ac4a9,def5390f) +,S(4ff22758,a2a25681,d28fbf09,e4cea5f4,74c00681,d9b4fe6d,ef3227e3,6092b52e,4b0f517a,4e56697b,37341ab0,6fbc92e2,4ae3d03d,392c33d2,377f7432,10a89fdc) +,S(46145b19,639938dd,9c6c84eb,d4180cf9,752cf9fe,a77ca609,5ffc8f7e,ead61f35,5b7b55dd,8a5e7d00,a3b62d20,2f371d42,8eeacc9e,7556547d,f2396c85,9503f6f8) +,S(32464689,a5d7626c,fd02b5fc,da68a8f8,dec32eba,887b523c,4b4e379b,c40bee7,6e9cb8c5,3fb716c0,b583b356,7ba6890d,2cdccd39,646a49c8,132ef061,d89f6710) +,S(56438894,2c9aa575,efbaec77,cbecd9fe,79fb4461,c61ac051,195ae384,dc0d6ddb,663528a4,29696073,f9d47d2c,bb2c256,9bf6c452,c171ca43,7cd3480f,95b69a05) +,S(f04fa37b,9c510bea,ec12fd4a,307b1b0e,d934fa1c,78cbfbe3,bf904b00,91491e4e,19b7da4d,826a314f,586c4c78,457a3075,76f3ada4,61af5bb6,c374178c,23a79326) +,S(36fe4596,b1ca6409,741f7a0c,b899f89f,a727207e,eedc8e57,504847d,2cb304cd,78f11f,4473b124,5772a101,564b6468,43d4bf76,afacf02c,bc45ab39,c7221e19) +,S(ce3e6d1b,f2deae03,8ea4333b,ebfa026,d1954ffd,f50df66,e2899b05,1ee87b0d,4cd4635f,10af69c7,50e96ede,e4f38591,2a14b104,ed9023af,60ac6e93,a9b9bcb0) +,S(33ad3a7f,a6008875,74bd735c,b2ec5dff,10ffc5dc,3163d8d1,62644086,888d29,8c959ba3,2f7b8ed0,4cb2bf2f,2b5e5f56,b29a851c,8d1f6bff,b48fab31,5335b3e0) +,S(7101a2b2,36aa7903,6348006e,cb8f81f6,b481ed8d,8a3081aa,40ed475f,13fde43d,d0a93654,51471aca,80a05745,57b4a24,9d627dd5,c1428ed5,79feac02,5fd2cd2e) +,S(ba3b4042,9c0bb526,c31cf602,3f9abe17,69974344,5e66566c,851501a5,d125471f,7db3e93b,e9944c42,b1654407,6d5bc6a0,99806c67,6cc7415a,9d110661,f4c644e6) +,S(57c6a582,1da61528,dc291aec,3a9f1a86,229594a2,27767583,5687ee91,15acd72,a9e4750b,5580b225,7768ce7a,b2909466,589a1a12,2e54a7af,35f44de,44cd5dce) +,S(c8353ee5,847efb7a,ec03d949,633132b3,9ad898e8,9a367c77,7b4a2ece,c47a7c10,dfce02ff,71060be,5e12d377,524c798e,97bafd6,e9aa9e10,27c07a8d,6f7d3a55) +,S(b0f6ef67,78b4ee99,6d7807ca,9f1f6f44,203eed8e,62584c6d,666e3698,e41c0eb1,b92763af,c9ea095,f757e921,ac0bdb02,605eb66e,d3e1735f,f8f17e63,dee5460e) +,S(f2e4015e,62645bd4,6f858b25,cb636f97,6ccfe5f8,da065b65,1ec170c,ecf5c411,8c05cf9b,19459597,7c1d1b6,4ff6e902,5d78a175,6416e0a,ebf33c21,7b3d5dda) +,S(ffcde722,ad4a2223,24396b52,5a95a233,31dab41d,95a4e19c,1a23c2e3,db7460f9,f7282903,525ac2ed,3f9db21a,92d3fe4e,b1635a8c,77dcbf8b,e671146c,8eca8115) +,S(81dc05b5,2d9a210c,4904bbde,cfb4eacd,8b3f08f1,d667e9f0,a27345a9,7d37b37a,747aad1d,bd0003a6,d89f9d9c,fc00977,719d24a5,b8ebb807,98d1b644,87105f5e) +,S(5b92318d,a267772d,94656087,8d698aaa,7d2c721b,28dfbc20,9e4a3e8d,1b0eef1c,b2d274ec,7aade417,4f2f8766,1b5018bb,47c83d32,b2fed50c,437348a7,93041906) +,S(3eabd0fd,6b5bc51b,c187c943,511c3005,8f86e474,8547fcd6,49595070,26fb805c,95e8bbe,8187398f,fa4ea4cb,b50bae2,19f8cc5a,5f09503b,3edd115f,729b2101) +,S(a64d3807,f92b91e0,717c310,ec799908,43e3a394,a5ece3c8,7c3bb209,8d3123ae,50fbacf8,be11f6b0,ea0e36b3,5c46bdb0,8fb79064,59b52901,9af59b1c,e80ad239) +,S(db9ce153,7cd47f3f,4b08858a,d429c975,9ce6738c,2e6d56f0,fca12e70,777b83a1,a91b2016,9fb1e2f,fd52192d,7030d86f,66358516,5ba32829,6c9aac95,192afbf6) +,S(bea03f49,76ee0a86,e00bfddc,79e52173,1baef841,d751ee47,9a46cfe7,89de2399,feec1fb0,3901a923,862054e6,7024ba7f,4c485c70,2ff22aa4,1620e857,6dcc863) +,S(cda308eb,6975d59,db439e23,32505d29,4ebdca67,5373ed79,25b52a6e,f60a33c9,7d2053c5,414c9bcc,5155f17a,6fc206d8,81cc882,54341778,1c5db51f,3ce4c224) +,S(430bfb3a,802988b3,a68d5595,c989cbe,75d409d2,68dd84b9,a1d4a5b9,42360174,3de4c6e1,3c87338c,8bef6195,6559335e,bec503fa,2025529b,b015cac6,6d8060fc) +,S(b4b1b7c9,932be243,6b06b2c1,e5de312e,4a409498,11a226d8,5bb30c5e,1487c36d,e169a70c,b95988dd,fe1a98df,527fc172,61cc3103,88d41ed3,4bff23bb,31da4dc0) +,S(7a954055,d2d6acda,8dbe81e7,46310113,e26af09b,91cd59dc,92a479c6,d6079ef4,83c6d3ff,4582eea7,becaf8bd,422c0558,a2bc8d6f,cb615c59,7c46982,47cabcb3) +,S(aedd36fa,91a7f95f,2b2f32c9,1be77860,75783bcf,8fcb20b5,f20ca664,dd89474b,c747f32a,174ec6a7,936f13a4,7e80a2e9,324b7f5,e163b396,218c4c35,9391e565) +,S(41052d48,54402d09,a813492a,2f9362ee,9799ffa,3d270200,45a0ae07,9f913f60,97cbdcf9,b60518c9,74ddd987,386d60d1,3d10defc,8fe64511,843d5bf7,13774178) +,S(886e5afb,69f6debc,c1c5be6f,b636eea8,7314ff1f,975cd96,9070e376,c1a9973c,6a8ec4b7,98fec5e,b4a8d645,c7b72663,d6bf4aff,8f4f4b36,c064bf3b,f6e7b5ef) +,S(c93adec2,ddf85ba8,d9147c91,82ee4fbb,5727081e,a6938c0,a4bcfbfe,6856dee8,9ebef5d,2b2253e9,4474331d,b52739c1,71214093,aeab11e4,e51a2be4,e201dfb1) +,S(d97166fa,94a4e51b,ad21e1d9,76e01011,655ce24f,5f5afdb8,feda67bf,8ae65a83,815ac894,57f83bf9,5579fed2,ea470ad2,ac1c83f8,546ef3f8,bc383701,1bc62a48) +,S(c23cf94f,c5a93aa1,719ea8d4,4f426fd3,d48220cc,10ea558e,e4680c1a,dc91b18a,64a4dd89,8f36efa6,efce9354,fa30f506,be3766f3,a31839e,1fba56b,5a07ebd3) +,S(7236b1df,88751e98,2689e049,c5084b71,b8d7979c,2c412a3c,995e61c7,2440929a,67155955,bf5d1916,9e36636e,ba56fe44,f7cef6d1,b0afd3c2,beb59b26,5e3b67a6) +,S(d1890a85,df4f7933,ff72fad6,5b95f5c,c9fd8683,3c1bd2fd,56a3b7c3,e90428d,8b4896ad,4b4469d8,af074eba,ac38563a,ca68888c,5411ce0e,b3701ced,75d4f87e) +,S(41ae85b1,9fcaf4a6,13901d2,3cd2376,62f299c9,7cb306ee,8ffc13fc,75d54e15,20d99cc3,215f0b1c,20922ffc,6e111b53,e88ffb39,bb6e118c,61b9e3ee,fa7d01f1) +,S(d125489c,4e07c44f,35d39008,e4e29c43,c28ca505,3e370570,a7bd34c7,57e673f5,d142e19e,825ff93e,b6661160,b60d4e06,b4393388,43500b29,2d4d62a9,28db2bd2) +,S(8c50b3d3,667b2aa1,a60c425d,1128d389,f2786b3d,656ee126,dd57af96,ebaad9e4,55eb7ca1,c2bb5881,7f82cfc,c8b5ca35,5c2aec5c,68dd479d,948261ee,d342fce1) +,S(3e77a3c8,a2e995b7,582f502f,9bb1230b,35311af4,dc8d0744,9211a13b,444fd42,99c427f5,8365ca18,75272508,7dc57985,d59d72ed,aedfd5f9,d61517c6,1fb8679d) +,S(73ffde64,80547448,658ae5a8,529755d7,2ad7ec84,5711f0b3,20acc53e,a15ab609,786de118,c6a0daee,48f3f585,d10b9f2c,b4947661,b844ed51,59903ce5,f2cc8d18) +,S(8f2ec78b,47c61a39,c2ed1110,902b3a43,4fc9ddfc,b11b1ed,75c675be,5b8a172c,441686b5,c1327f0f,d2bee35c,5d8f2aef,b6da72ac,e6206982,6d6812a0,5b937346) +,S(c36c0376,d360f87d,28069511,7eddf1fc,75ae7118,5fd5a82b,b47d8fcf,519ae4d4,44c31c56,cda1c2d4,41161ab7,45f3c0,25c4ada3,72396658,cca23f93,bdb6a303) +,S(1ff06490,3cc7e686,d408909,4812a7d8,531c4188,ab8aaf4f,f10bcc5a,9cac352c,87af78d5,3122ad89,9a6a1297,fcc87c1f,252bbf9c,d8cfbf57,f64cb6ad,fe77f3a8) +,S(1265a4c0,6e1f1a6,126a9e37,a6e4f90b,290fe449,49b82bca,8ea73759,451e0b25,4f0f7a6c,9bc7f00c,42b90d95,95871176,d723941e,38335581,8f7aacdd,f830d15d) +,S(2595358e,4d45d362,5fa1c89d,a3249cc5,a26ec3d1,e554a863,51b79fc3,4eeea90c,d9b8d147,e4e00450,1baeeb5a,8440235a,88913063,bb1ffa78,9402c3f7,2c603899) +,S(3f432621,7a5f415c,b028f338,40fc226e,5906a09b,d054eb55,45609fee,90135082,a572303a,131fb0f9,c63d88e6,3520ef2e,77bcfea5,1031fa60,fada909,a610c830) +,S(9ee85c9b,4cb0102a,6b21c517,947d798c,c26dd853,7bb5d6c0,46a50144,f3297f45,85b798ab,c2e4fcdd,bf3e17b0,49e2a495,6239ba16,9917ed08,ebe109e0,4ac8016d) +,S(479c2ec0,28e8c83f,d7946f43,8d802ed3,d728179,55d94c55,bdef5050,67774934,c262229e,23eacd99,f9d3fb37,b7b9040,47cdd5a6,6872f4ac,800dbb3,d87fc3fd) +,S(2a52f4d,821cf4ae,758ed477,6cdc3bc9,2d3924fd,97a12f1f,4dd5a646,24766b4b,28500754,6ca8f142,6f3a4a6f,6ccf8437,37c6a917,7ab59b92,728f588,f11509aa) +,S(d89159a6,d5447ab1,bd03d44a,a8db3410,c86305b4,4f06b25,b88c4244,5ab1e929,c539ee3a,e7dec645,810c4a02,e1777977,d98ddba2,281d5701,2ed2a4c5,85057013) +,S(c91267af,4c303e07,ad82c1e6,2ddd45d7,cfae00a8,d27a34f1,eea8d15c,1add920,975967db,347415ae,24b427a1,b8f7229f,8db0758a,7ea13f7c,582c260,c0711b85) +,S(c860be31,18ce92b0,39b27a50,960d3caf,88e24bae,6e45fd8c,5a253a78,e3d0e6cb,15b8374,922f44f3,adaa213d,5e3facdc,9de1ff6,4da677d3,d89f6e0a,a800413f) +,S(eb8b5f4,2fa90313,b3dd7d4b,d47338e2,9861e52c,b492e9dd,6a1897ec,4da14c14,9d1c4d0d,56c570b,8835e188,517fe7db,490aa6b2,bfbe1564,579e7af9,c0647bf) +,S(151e39fd,d5961da7,44ac5871,94081a88,666d3dda,6507404b,607d449f,1b3c005f,476bca6d,6bfc5e2b,2c183794,563d35ac,aa8d38bd,ec3846b0,22831bda,38fa28fe) +,S(b46d2d52,b764f922,7ead0399,c391a9db,1737c9ab,35394951,5a57c76c,c3c05c59,8aeb78db,db1e52bb,a8030a3f,b9f57f6,644332be,6d0ad41c,34b7fbd3,13c6eccf) +,S(a89e77d,30c66dba,a27a2dfd,5af0684f,f6ccc84e,49b8d98,f402a88b,20e5bf7,af45b2da,cffcc49d,4f6db574,29f13971,c74f5321,4dd4af49,2bc7ae5f,10abe1ec) +,S(8d774c5b,eaa0cc57,7479873f,9bf5ff6c,808afa4c,6fa6f2be,88b53841,4cd088c5,6b9461a6,600ae1ac,4e617149,73fa8b48,74dd7cc,9f331eb6,e15bfcc3,2e26eb63) +,S(34ecc029,105f5e19,d6c2471e,eae5b671,cd55f2c1,bfba7dc8,46787c92,ba7de2a3,13e3cd9a,db98a6b2,433dba08,ec7d40c9,c2467878,f6f4bcd0,ce60397,67aca327) +,S(41b10298,6889f83e,e89d4f8,fa50898b,c9bbf650,2d153c36,85064c9b,f3dc3c43,559f5bf4,fb827bc,dd068d3,cdb14d6c,ace08a47,c30e3fc7,8972ceb8,9f88c21f) +,S(4a77505,79ae33e4,55228533,b8856da2,b14f70a8,d13ac2f4,f6bdc5eb,4f5c9aba,d365922e,3a487635,3ee1b02b,511c7926,e5c5edfd,aac153e2,686ce4df,b623ed2f) +,S(173af9bc,efacadf6,c107748f,278adc1b,d42174e6,8fe06d9d,f84fe278,70eda280,7b120d62,2463b94a,57303cfb,2c477f95,49d41a66,d6ee7c2a,4c652284,b8535faa) +,S(f0fa5cfd,ba53a5ba,df707983,134c3459,5ba232b5,7fb67a94,5c5c0f25,a0539be9,ccbc91a9,c0a2efd2,3bffec87,cadd16dd,f4292aef,a59b3d31,6e9c7082,742edb6d) +,S(a5df803f,751c4846,10799c60,db405439,9b1d5bfc,c99fb316,fe884468,e57ab77b,27f8f706,a2f08ff3,249f8b62,ac0d59b6,31fe52fa,7ab08ad5,2d09ff2c,4138dcd4) +,S(d165fa7e,d61c251e,a93e8f16,c9291b09,1f258720,fd303a3d,c573131b,d98628cb,cc0dee9,f01f0dce,aba94461,1e48f9c5,282a7480,eded0794,81d0b8c,a9819a73) +,S(87703371,46a8694e,2bb5cb10,76ffcd94,309c9c8c,be6e8cf6,5a77f4ca,4d31efb1,ee64af6a,5569a205,2cd98c10,871b2ba0,6addae3b,3cec463f,6002d86f,b16e5e9) +,S(1c7e4ec7,c090906,3d98f786,dc22db53,da4d258d,6e75cbae,30d4b99e,f4ca47d4,d2001df7,3297e6ec,c0aec17,e72cfa6f,5951e2bc,f03e4aa5,5f329c77,47cd92d8) +,S(d485ec0a,1a0abc6a,69f308d4,c7f8b8bd,fff5ac6f,ad4ae4ee,271a87ce,973b58fb,68f51764,ee705265,3e2f7d7b,7415847c,3856e3e,1a7f4932,6fbfc9c6,5976cd48) +,S(ae5ab510,48215ea2,3be55d93,4e0dce0b,ff88f09d,10c8953e,390b79f2,da26e43f,9f80d71,36a5da61,7f90d0c8,a6d9aecc,5cf88abf,6bbc2181,5f8320a7,2fa8929f) +,S(cb879f42,4613487c,24aa73a7,36f211ea,96541877,33fd7091,40a824ae,7641a708,d46a4ad5,7f607301,f61648b6,e99891d9,ccc41af1,af29a66b,b894575a,a6b3d5a2) +,S(1e8d6ac8,ec0b543d,1e0aea66,7f35b556,87e30be0,72841fc9,3f599c81,4a750d7e,8965853e,6519ae5d,c523cb52,720b004f,ad2f03e7,aa3e0413,bc68efcc,c0617f85) +,S(dd8e5b0f,be63df6f,5c20e447,778f923,2e1b2c22,4d28cfda,b2c672c6,66d05f8c,d8b75f77,f955219b,d4d95e65,35d5cb0d,23c2a1d1,671b9416,2da9c4c9,b2d4a94a) +,S(78ac44e9,938bf51a,691132e,93ec3a42,22be3185,35209054,a76b87c6,645e0252,c0f66cf0,3c20dd,d136d1f1,cc00eb17,efdf2a4e,72d373a3,99c20da8,8342299d) +,S(d53110b9,5034e916,d904cd15,1170761d,4f3492ad,9e257265,3ef37739,df9bb035,c091177d,796d199e,5c05abeb,29d0df1e,e5ceb93,d272e6d,d254b6d9,a6dd35d8) +,S(868b2732,3debb9aa,60942498,3be71d0b,451ea44b,64c22225,2af3d63c,3eb512b,8951dd34,39774c8d,89cf4b4c,485889e3,df2503a,102ae568,c63fa74d,23ee659f) +,S(672de7f2,34e96153,d83da7fe,3e199099,52ee988d,961620ac,b8c6b4c3,520fc50d,ab02a8b5,2a2d9306,8a83a0dd,23ff882f,b1052f22,72a0ad11,cea13c63,4efa33a2) +,S(4887f473,af8189d9,c46ae22f,c86ba6e0,f03c81a1,490de032,72b07937,b63a7527,a2e7a713,e1e6691a,ce09dc0f,a86c92b0,a0097899,7fbf26d3,98581731,a577a21d) +,S(f97ddd77,38bb419d,ec051fcf,a93753ff,e3dfa122,6cf02e1f,23afb376,7a121440,2fa9c241,f747fcda,dd09139,437eafc8,94e7a47c,ec8a7ffa,1e054ce9,21d73243) +,S(ebe75f9b,2c92af9f,11eefb04,3456f6ef,f616d1ec,b616a9e9,9e7f8960,4f1d62fe,40b5cf37,b06cfb0f,294da3c0,f756c867,af06449f,e2a916c8,a327117e,9a47f74b) +,S(10d376b1,1f0138b3,238deefa,b57dc84,7ef66849,14e9f120,1a9619c6,b1715a13,a216f393,1f398b67,d68a2888,1d5a31f6,e5e0da82,e2b5060,4c6f6322,9cd21748) +,S(69e26679,f103a1f9,8a9a4d88,c973874e,db7c82ca,99e48554,37284445,b55517b,cab62aa5,13b41a9c,56ea455b,6a880b95,9d400bba,74e7a203,7b60ccb0,4a89b8c8) +,S(3acf827d,81e39933,64e99fa5,63f89305,dcc60b62,44ecc0a6,b101c6f6,ecd5bdab,77e3bd28,40a99c45,30ab7767,4d8ed17f,f57a4f1a,4ab91732,7059114c,c06fadbf) +,S(2e5125bf,9e263d80,7a220063,434f928,d9a4907f,68601eb9,829041e1,a7b89bc4,9810022a,d7d3c333,d7c022d9,d0779b9b,5807226c,9fd41e65,c3fc8e1a,a7a0b51f) +,S(7b68da4a,197f6bdf,56948023,d2baf10c,9449d6b0,b18addc,49385125,e62506bf,85a92b7a,190aec87,bdcb9df8,42e93917,9254ae6f,b45e6764,32e410ef,4b28434b) +,S(60d4b53,9a29562e,8fab8ad7,3b699550,3fe7d6c1,e2ba1465,f05c92b1,61dc829f,2c2ad439,8fc7c836,5b2efcf2,1e4d0156,1a753f5e,d945ef2,bb1a3394,203d07eb) +,S(5a3a1bd,30250a40,d22aed42,71892b88,3c03ea0a,baba458,6b65cc50,4c79b107,9bf3bf42,df1637cb,80c1fef2,cb9bfaef,dcbff761,89cf9f5e,d00f0f4a,e551e31b) +,S(9b9d93b5,6b70fc67,5476c6a,6913e173,11ed1ade,6ea7b810,b9c90977,a8f3707,ae01a481,7a9ce6ef,5584a48b,fb96a9c5,21d5bb7e,2bf73cb4,b71f4dfe,aa7da298) +,S(44bdd82,86a3a4d7,6ecad7f1,ef66022c,6a49b916,3d7a8ccd,e54bb017,814d2f70,26d345a0,52034ce8,b4382905,f60f8885,e20afd4c,54df6d6c,ccd1c2e2,5d06adaa) +,S(8de8205f,e44946c8,582dcbe7,152dfe3a,7eb85e7,bc070282,3c972727,54463869,1dd97d78,e12a92f0,cc2145ee,db4ef561,af21d3db,f3cb123,ce0bb582,6791a30b) +,S(c36a713e,3d88ae25,f79b4add,90c6a724,77be7d9e,a62ca0ab,2d5a800d,41f9321f,2df57da8,6cf17f7d,63ebb85e,e7570869,cf90b462,e76af48b,641c07c9,45a638f6) +,S(1ce37a88,f25b8b81,941db8a6,13a7d952,c2cf868f,e979bc0d,5f35410d,147207a8,7fab8cb5,f6611850,e541dce2,315a7833,3999041,5c18ab0a,718dfe32,e0ebe992) +,S(e489744b,dbb11e61,a7e827ca,ad18ba55,41f4c02a,b50b75a0,353f4a2d,f504d575,6abad3b5,3ad97e6d,a301ff7c,7931f37e,55246ab4,c7560,363ff214,2cb9a398) +,S(cb4ec0aa,c1cddaf1,c7a67507,5cad6762,cf8ffce7,6a06f76a,38bb88c4,5181ca3d,7f15e726,5092287c,d2ccf3c5,dfcda0c1,8c63f2ad,21c06a2b,469bba5a,d9e4ff36) +,S(aee1c436,6b923847,40127dc4,150c6dcc,ea62864f,394415ed,9a39d539,adda44e6,2496d2da,97990e6f,5fb1526d,b93e92e7,8a011c33,61218d,c3d3c56d,952f8666) +,S(a099ce61,d950fa1f,19abc21a,79c74021,472c46ab,d8f67798,34df0429,ba785491,c4dc483d,6d61ab1d,7578ee0d,7548e0b4,295891a1,39774c22,7d073232,f2f3ecfb) +,S(6c57db5f,b194dde1,b8cc9686,fdb65fd4,eaf8aba1,84434344,7a770ddc,9055e429,2dfb48f1,58663b3,6a7747e8,4b5a9001,163ea20e,f07649f7,1d7a21b9,b11995e2) +,S(f6efa15f,20b2e91b,cd7323a6,51e5d7b7,a8b323df,924c616f,21a7d6e0,e34d3c76,ed48a439,2bb4d596,58e75757,95a0a4d2,7443415d,7662a535,a6246d64,3804fc1e) +,S(e7983476,a900be4,e9dfed94,42f575e6,4d9af362,1e874a99,576e06e5,d31485f8,9d21080a,8b0534f,6b2dfff8,9eb8172b,cb5388ff,d910fdfa,405ead29,9df779be) +,S(88ffff0d,7b415f76,8c515d80,9c607949,b469b07f,3978caff,1ba64e,ce198ba1,6816bd9,ab0e773c,38b73787,2881e96b,8eaf381,b155b205,79b24a39,eb9e0fad) +,S(e5fd2c3c,a1c85b03,3d93a3c1,261a5c1e,c4adb72a,7700405e,7c0bb108,d8fec1fe,97bdee17,50801ab9,a96e3fd4,ec4860,e59034e5,c02f9168,79b1e654,5a65fd39) +,S(fb010f18,146336ff,30dee37,b25aa384,9588b83a,bf943125,613d2c72,c2f5b3c4,4b0ff7e,7a6f15c4,d377e92e,73c8935b,d2d9f7b3,5be91cec,da891f61,c7631bbb) +,S(9be574b2,c28b1460,a1d67d94,43e4bb85,c46a6bcd,a957499a,179cc8f9,7ed33c2a,16aada1a,367def6e,d4f34409,e0ff5d41,f3854494,6a764040,e1109574,109bb310) +,S(358e97b7,6799ae09,b80b6797,90e34630,3d61fd4e,71733d6b,3c90fdee,2ad44bf1,3eeb5209,175677af,c16a3869,5ff7d3a5,e9704201,b802ec33,50c6c2ba,c0ff4144) +,S(2ed930c1,c941b209,b6e7cf3e,83971e70,9e36bed7,a4d3884a,faaf013d,5b589b59,ff6a5a5,e601377b,9dd974bc,4fe71e36,403f2cc,90b16834,b1beb6a0,98553d2e) +,S(d86110c0,6e8b20a2,e6da1930,fbda70a0,d8c022e3,e68255f7,262168f3,2bd58986,34dd600f,9b7157cb,2ec545e5,c50b3f95,2f422b21,4afe255,b7337815,1f3dc048) +,S(4e7ffdde,305ea002,f7dfadbe,e2da926e,6d2c2714,596fb052,7eddfe92,81d4fefd,fb4dc1e9,476cb2d1,3bef4548,9ab7ca86,6ccbdd71,4cfc937d,bf024f12,ff04eaef) +,S(6ba04fe,47c4c99f,849fbd68,7e1ca6f6,3e00179,3ba3a08f,86acf668,df0afdfd,dad78b7a,9d34c738,31112801,91476b92,b8eff31f,fcaa6d,a0704244,5fe32e37) +,S(bda2c2c4,86029d0d,b804f1ea,e9215150,34276a88,179154dd,d5d9f176,cd7f50ba,a70291fa,47b98bf1,fecd9aa5,b53ca619,41d62c9e,c8b02ea7,91c79482,afc8f1c3) +,S(99801a16,4da92a6b,de6ec7a2,69c2798c,b421af01,5ec24c8f,1b090169,18980a5,3af209c7,de27a683,56f242e3,8805a368,66cf7780,60c2806d,76f9eb06,35c18358) +,S(67fcf955,dba84390,638517f9,5792d09b,64c056aa,ba98acf9,d63c2bbd,df5f021f,96f96080,b5758233,ee15e8c4,7ffdc3ae,bbc752a9,d7697e1c,3ec3d479,4f912d2b) +,S(c15990a0,50c2946a,e4518cf6,84ac9cae,1022a29a,bd88f8c2,c8e724c2,89b954c6,611bc99c,e4ad5b6e,3ac932cd,e2e70e0b,a3690ec,758bdead,5edb3b0f,b5b95d56) +,S(c5261ad4,f6d03a0b,c15ace20,aaf95bf,94d9ab5a,95a45d90,6ce7a622,3b09d59c,5fd1b7a3,b22732c7,4b5dc1ca,fac99882,467bd80,53f2f606,ca5af8fe,6d741448) +,S(b0bec3f4,eae81fd7,2b70027,72a49acf,46a5c50f,48358df5,e174eea3,c0da88a4,13a4cf63,fca873d6,cf1b8c35,ce25f439,4d74a5d2,f2fa2799,d4c3bb98,8b50ab67) +,S(e3d32fa8,9218a38a,c503780b,dfe23dcc,e6a7138,d84668b3,f71b3fdf,891b6256,246ebe20,7ab7c536,8f7c9795,9e7aa1fe,69909d50,f4b24263,c32b8bea,7674b85b) +,S(ebf3bd9c,1920f625,4c32467b,7c1c138d,3ac6a4c2,b185557f,6eeffd7b,2aae0d63,58ed82e1,25fa2241,2bc4397e,73009692,af1d5feb,f640a422,f52e5cb6,42d4bccf) +,S(d062e72b,3dc76d03,5827786d,a9cbcb03,b710ea61,2eac883d,b7f50df3,fc6f7175,cc56b076,dc3cf1b9,e544858c,1a31723,33ba9848,a8c463f2,abf2c6d0,dae14a6a) +,S(97444eb2,32b09240,fc596530,374da035,f5ebd37e,6c74b51c,8158eab7,8ae30f89,fa06190f,d2072bad,b9144f72,db18819,ba76399e,d171d4bb,1293c20d,63d70391) +,S(3e1ffac8,15f68300,4714f302,1ed39460,d5e4d63f,6fdc445f,12d8470f,b273c242,86f0839f,8610c4cc,6ae85d54,b951441e,efb700e9,9ce54aa9,fb6c7988,a8494c25) +,S(deef1e7c,12e498e8,6542acf2,3782ece5,2a02b13e,3b4e71cf,e39e79ba,541d2679,e039a94,f4b169fe,a13ed182,f9e541e5,2b117536,d90024e6,9f3bcc7c,988714cb) +,S(69ed1a62,b3de5c,c5785b27,c7926e52,4ca1527,9f8a00eb,b5e1c247,a6c8265,9c5fce7a,84b79a67,9f3030cf,a179a682,cc22c464,11ffc8b1,ceb885ab,4753de36) +,S(cdb36419,5c3be45a,bc9f58e,e5a499a6,ef58ff2d,296ff989,9fa987c6,b753f82c,34a1a6fb,7a6b6c95,2a604340,d2c30c15,69c46123,e5cc5318,833f3a3f,bd622e47) +,S(c5749ad9,f4583689,f2ed313f,dc35fe8,acb6a85e,dd0498c5,ddcd4842,fa21c555,f22ea47,ba61044b,54ef967e,c8c82167,3d14d710,334784f6,a7b46d48,19f99cf6) +,S(fc86862f,b2fac126,e4341121,c82a9e14,d7a48b9c,988b8458,300dc3a,ba10dffb,42339dc,e304641,f814327b,ca5a611f,3638d610,85826d70,3d94c76b,8297f6f9) +,S(66dd174e,446ae0c6,3ded267a,faa20ba5,62131459,5576d10a,1e44ef18,69e36ca9,d93a449f,6d3fef4e,435f6fa6,3191b625,b883c303,1dd8b380,777b556e,acee9df0) +,S(736a80e9,15b39c21,5e5efbe8,ed6f8fff,7aa826f8,5c940110,3c7ce372,86d952c6,4a9e17d8,9066ecb2,95447058,4dc58c36,c84b3d9a,30ea45cc,e62454fc,ae13e0ba) +,S(7b747f80,f4a324af,e6042edb,d8682d3,1b8fe12e,19936844,b44c3e73,f6b7075e,c2684490,56e7633d,2add97c9,75079594,b9c0d038,cb864331,aebddd3e,18830199) +,S(dfd54b47,e4d2abe1,c40e0a1c,2916469a,7e8a61b3,bd95a1ea,8b5fa182,903d8339,c705b4a6,761d2ca,49f87fa9,ebb4b39,35c3c633,4f6b7643,417c8a29,95515fa9) +,S(992a5fca,521a86e3,dce0ccc5,fd1b2ca3,656f44c1,f4967931,8ccb7a28,7879213d,ca2836c0,496c75b6,4c56c13,641d0402,b64cb2c7,617c9fbb,d820245a,9321217) +,S(38e59093,acc26364,de9cc5f4,de398799,54774d68,ed4b0283,2bde2a26,cfcd23bd,953c21c3,14ad2e0d,511d3f05,678358f9,eec2fa48,d6b24c9,6ed4efd5,da3b3719) +,S(889ea31a,5969b77a,c41c0a39,cc5d006f,6ff14f22,a62a5f26,d736ebcc,f5df8239,4c2fa5d9,c2f0316f,dcd6462b,e7571f4,92aaee96,c3c888e5,21cfabcf,78d2c3f4) +,S(f70e24a1,6807d5a1,8e15fdd,f31301e8,bd210ed,5d3d614d,82eec8b0,326d7b6e,dcf95677,b29a5ae6,15e2e7b6,c370cf69,ccec71e8,9569f0b0,5715963e,da6a34a1) +,S(d6eb7425,9c17d292,e1b1a4ea,624e6876,a78aa774,2b14e94,d3fd1b43,562e35e3,c05013d1,4056ea0f,e5f1fca4,b0c74b5f,776a8564,ac973973,c929707b,b3f078bb) +,S(df7cc5f2,69faf306,6050409a,6a03cdeb,8f33d1d7,4e30658e,e871de09,59701b16,3d8a28f5,f604c765,5f28dcf,b2f3407e,6a63db14,6b879fb5,bc785e65,59319147) +,S(e6bfa4b5,85f6df59,7840119b,6a31d0e,4ad800ea,239bbbbf,a8a1a36c,f8c6b5ba,312b5d55,35402ae1,37f9a02c,aba859a0,22a8ba00,88a2305e,4afe8283,98844dba) +,S(3c762a8b,acb68a13,2e3e022b,35634b3c,1907cdbb,261ff639,9520352d,fd94b3af,2ad358b9,65555cf1,e0027e3a,b93d46c5,b104324e,2c62f9b2,5f70930e,bf49f385) +,S(b4d94e26,9955b213,8025e5a5,bc5ea171,c2ea6d04,9ab60184,88f47f7b,f6a6d3f5,197b20a8,81e9280d,96b5b4d6,ceb3fa20,38a28654,63e76ff,d0b5b401,8b59bd1c) +,S(406e616d,907a0f72,12acdf3f,d5341a79,9b482697,88976615,388064c9,74cd8ed1,72730d26,b2698e29,7f62fd98,2a3955c,da516ebd,642d6619,2d33a915,ba39d0ac) +,S(1762d974,37705ae8,37603446,c8c11568,c7878053,f25baf9e,e3bd23f9,5babdaf1,1db8fe6c,77f41656,1fa4df40,23662039,66a8f891,e5467b55,3a2593a5,1ba796ba) +,S(f5fbeece,aa5386c4,d75c92a9,88ce6bf0,f957a0ed,3f0caff9,42f1f29c,7ad765ee,fa45a4e5,85ccc691,88426bd2,8ae561d,a2f59d10,e4bd63b0,4f8a53ef,1cc3ab28) +,S(7e0d92d0,d12bb892,b87b8bc0,993b4422,cd1e9d95,144602c3,a2aa3c06,bc945ecd,601b1019,746bbd4,ba9bf00b,4ffaccd0,b1bf885f,57ec49d2,9fc91744,8aa70761) +,S(64cfeaa1,4d4e0cda,db6b6a2d,9e2c2820,d2fa7817,43d7b2c2,8211b1fa,e17ee0db,f0b199a6,1a1856b3,360f519a,a6056900,7a0ee623,69e0aece,ea64f0d0,8cf568f8) +,S(c90f70e6,99ba1a75,86073eb4,5540b3e0,80bc78a4,e811069e,f861b048,5f11c88b,7a8257ca,cdc7538a,13b55285,939c614c,14d6a94f,70509900,44b286d6,7eb84e14) +,S(3edbcf0e,b4e5e640,f40afec9,ad370813,426b5488,3090f8d4,b72b1680,6694f42a,ede4512c,c4baf93d,f05c14c9,cb17b1c1,fec46052,c7087306,2214a05d,60743c80) +,S(77adf15b,ae449ae2,f63d7c44,3c56cf9d,64d43840,5154473a,5948cc79,160b64d0,a1bf9aaf,7804cae2,c377f98e,86b75e90,6886d293,21aed43c,77e330dc,df9113d0) +,S(350632ea,23e39962,3daa53d6,5a916f31,b2ca02bb,5bca1f58,35b85165,b430398c,41931339,48282550,bfa1cef9,94c28873,ee0165e2,fa970d04,e51f8ee2,b87916be) +,S(3d6aae93,5ee4ab6d,46de768a,d6938703,262e9fdb,13bade31,d38fbd0,9fade000,62674fcc,6eaddef7,b971e964,5a688e32,14186605,615982ed,a09de4ba,13eaab23) +,S(856e564,a155a29d,c1b739e6,309fbbe8,5ea4debf,f12a9249,347a5435,af674993,a0e6deeb,3777ceb4,6017ee63,caeda231,e616fda3,c105f0cd,6174a3b3,dea84256) +,S(95f8b405,c1ca86fe,d56727ea,eecbcce7,32d2c521,415eff95,b3cb42dc,5230cc7f,c8c66b1f,2637df4e,2a5375e,3a2e5e4a,a89404c,810322ce,c4b2bd1c,91163ccf) +,S(b51de213,54aa18ed,6ea589fa,e3b92d90,732dad07,6c80b842,579d53bd,2089e0e0,8f069737,1baca2db,208f7db4,c43a85fe,d816eca4,e35fe95b,780e2c4,a3f1b948) +,S(e36ac0b2,c4b73783,7a96b372,b8d0779f,41605e99,2a0013a5,3c8eb4eb,d5e2a988,d41ea6e,ef06bd62,7c2acd2f,645acd8a,75e353c2,448aba53,452787b6,670eedd7) +,S(4d08e46b,a3e812b0,67071dc8,b76cbbb2,4effce48,cf4a4c5b,ff4e15af,71c51635,fcbf2dd0,ba055845,b70cc545,5a8658f,39ef2176,9802fbda,2d3ab98,ba914c3d) +,S(31421774,5b1a6b68,918e8afa,4e8dda05,6094a6cb,6024c3e0,c10fdd99,245d7501,7ea6ac19,1c0db139,eafdc961,e8f91f1d,79269f69,cce275f7,abe9598c,2916fbd5) +,S(79bb2dbd,f9afbc9c,f605ad45,4768cad3,14d48241,724b301,7b5abd51,6f8dd4f9,d1c9dce0,30fe1a72,5d100c07,d842a78d,beb689a,606a933,ca865051,49007b8c) +,S(112abf7c,1d5d66d0,cbcbf42,1874bcb8,88d3b3b7,5c2cf36b,1399fc04,17525731,b3d3ee4a,f44b5372,8d0957c5,e388094c,34fe0f5d,c51abfc5,76c1e18a,c920dabb) +,S(f6257a3a,60365e63,471fe77f,893a8ae3,174d30a1,9aa495cf,251812d4,c5040400,293ef8f3,91804cdb,34845404,996a24a9,5554fd24,185ec85c,3a27ef8e,c89938cf) +,S(ee7c8ee8,bec75bae,db32c6f4,3b3b7a04,2c10e903,de9e7d21,5ca08135,d59a682e,e68a0137,398fb186,d5168e64,4421ac4b,30a635fd,c15527f3,e56b21b7,c0008ff6) +,S(e292a4c0,fd63ec7c,c661ee1b,25c9d5c7,dd805a97,fc6e64ce,5d3d18ad,ddc92aa8,ede226,7fa6fe51,1d4a510f,e7f5e14d,8fa29fc8,b77d61ea,2e140739,29644745) +,S(cf914327,85a05d41,2ad06146,6df68649,d3b8e0f6,86a83a70,d32c2fdc,978d8124,f74c1223,7b0899dd,53afaad1,b9b06704,c61c6e97,81456e86,ea55e65,96b0b13d) +,S(88e58d21,95376fcf,b3f0c44c,b013f2ba,3379ba55,2ceca46c,38ed48f1,263fe894,f2f38177,bc673cbd,70853432,6ece1090,5863ad84,1140c59a,2a782af6,ccbaa71a) +,S(90ada18b,df0c62d9,dfa35e14,d1eab9b3,48d09579,f4e82cb3,65dad65b,62ba53c5,2c4e704b,fc9a9b97,7d330d92,602c677a,4a06040,74517775,d441d0ce,6c5e5e2f) +,S(3bdc1eca,a939c8b8,c164e5f3,1a02a6dc,9d2712a4,6c30f54f,e2159934,d492d1e5,e53acd26,28f6e646,edb5f53a,d9e1639e,43b4ee9d,b61a3545,a9874609,9b3c1e94) +,S(54a206cc,48c7d529,c8bd2ca3,91501ca2,1b58f5ed,921ba11a,95eadfab,3a720bf,83f4f820,b9a07ae2,8c5e137b,c9ec4f0c,31c875a4,b055b0bc,8de38f74,c54c06fd) +,S(2754b021,13885a9a,f44cacd5,2999a03b,d16c90e,4e3a7a67,cb3426df,f6abe546,f8969b1e,e955f8e2,dc0d3090,167c0116,66beaa68,35bbb1dd,e721c4cf,768ef566) +,S(ae438153,4cf07fc9,1dd14a40,68b3cfe3,aa6e608a,bf1d1c1e,13ac54ee,e0759165,e7807ae7,395fd072,6f77d7dc,956c58a0,69243b63,32bad336,72d2eebd,662fb99) +,S(cb9d28c5,357165dd,fe18010e,4263e626,65fd6315,60ec8126,c7b60603,6ec067a1,86879039,f3264d1e,511fa8e2,4298c9ed,6f1e7625,897666ad,4db9a43,3338f5c4) +,S(763534f5,52317771,551524ae,7ce33579,41da627f,db77d4e1,a9cf72a5,f182d276,9fd8ae13,b1706cce,ad190066,9b1d2f46,8c177970,b5173f76,55efee54,ec5cd8de) +,S(3990fb8b,39d529d0,b2d38432,3c60ffdd,3b32f7c,278aca88,f49f1523,fa16ded5,e43c977f,427570b5,b238edd0,77db9df8,b1b82e20,b73b8d56,84a2ee37,886edb83) +,S(6b76502a,22280e31,d0b6375d,6dffef0a,94dad7bf,e640a406,2ad696fc,2744cbf6,e667122c,b6861cfc,97fc4ed0,e6193883,c79a896c,79e31603,a67063d2,421845a) +,S(7ac03be7,2ff15233,5ec9c349,98e77ff7,79e5f348,a49fda4a,e52a69cc,6b02c02a,74a9e36f,af0ef72d,b493617e,9474b112,593de375,c845c8dc,c1028ee7,9fd17599) +,S(31a83e18,c03c570f,31c3ecbe,bb787aad,6492cdc2,3e07d3a4,43b56ca2,51c0888f,3cbddf10,9bf08e81,830dfa49,d4d3cf95,224b7a4e,fd6d9997,9dceb64a,a8d7e440) +,S(ec13f2e8,53935ae0,705c2644,d1512bfb,8ea4adaa,d45a454e,f761dc68,c7ace561,54139641,97e2f5c5,5b4b7f5c,5267ea7a,bf36b01d,cbd62765,ff56322,c107f321) +,S(ce8e23cc,aa38e603,70defdd9,37803f02,18ae79a7,3679c363,4dab15a,bd46004a,1ddcf92,92ea77c8,4a1346a,a5f79f13,26c9092f,14ce1992,dfc24bf1,a2da35d5) +,S(77d80689,f7cd8585,fc03cb20,14d02425,3b547962,a282beff,17aee956,88292ee2,466283f6,429248fe,301e18ef,61a89784,47142fd7,fcc5c496,36dca83e,ae8e9f03) +,S(6eed61a1,4e7e7ea5,54a4e43a,61fa7eb8,b8e7fd0d,52de9ad8,e4e9b130,78178a5f,2cb4d228,90af9cb,a3c050ab,12a3dd53,1f1c6d6a,e4393449,219d86e2,6465bbab) +,S(10cb3737,a7916d84,12c955d4,32d1ad46,d8c7a60a,e44936ba,f62b2a26,b698e4f9,35499a5d,11e356ad,fc5960d5,8d6842e8,ea0615f5,e8bf39c1,8c217cc6,7a1faa97) +,S(e866ac84,6040f92b,c52d298a,6ae110da,e16bc797,d6958858,1f63c00f,6cc68211,257803b9,ef7bb5ac,59c6b59d,32a49d53,64c6659a,cb0482e,a9d57530,4e244f90) +,S(5e75ce15,aeb91c2c,e4ce06a2,decf02a1,db85ef5a,a43c42b6,179d4a,2eb4e404,a08d537e,529a6654,a785969c,8d8b0b86,e3a76f91,d9b72d92,992f8215,1b61bd1f) +,S(fa80c52a,12afecf4,7a5b48fd,60fa35b5,ffd122d,8616ca07,1c1271a9,bfe2c104,74487acc,dbe2e60e,e054643c,37cd624b,3dbbc3d3,4aaa6009,9c97cfe4,b3d69e81) +,S(ddec1720,dca13ec0,2eee97cb,445044e8,d6b049f5,694ce5a,efa664d9,d89b6dc,122b68af,feed4f56,b72a4a7e,e20a7f8a,8daa9883,9a797857,8dac0851,1b843872) +,S(85116566,57b70a1a,96c5da0e,fa5d3025,49fcd00d,104a4989,442ff143,a08b5a59,2c96bdcc,430c6c28,9d54806c,9c17961a,8121b10c,5168cfed,a0dc8edc,9f4f551) +,S(7de80b36,89b9dfe9,de2f4fd3,4dbcedba,9ad39842,f105f580,d8d5f6f7,e1eb3e58,43d20653,db727ee6,155998cd,f7bb70b0,9be15c7c,a04593b1,398b4586,baa3c417) +,S(e66179d,366fa7af,a982c480,9578d469,91731ce8,c669d8e6,bdc399c2,a2484b1a,9371d856,28bfb10e,d07c3390,b9f08222,98793229,ca2cf2ee,75d53d2d,e8144441) +,S(1d435048,d7b8bfa9,6df91fa8,f8f6d1ce,913bce85,c2c7a1ad,cc199afa,5da012f1,4e389f26,4f36b2c9,296934ad,5f567eed,30f3179d,6538ef70,f4205219,2c3eac82) +,S(5866c91b,619f53ee,3256772f,56191a35,23696c7e,2b5140a2,89f36c11,c1cdfca7,67090999,33ade86e,3a5d384c,840fc584,2a85087,10085798,913c41b0,e2dc1737) +,S(1e06d768,20c95907,405fc2c6,bd75e1c2,fb9c4d0e,4cee156,94e1a4d7,65a77a01,4aea359f,bd26d7a6,1b1e9f75,5544363,27eea590,fd2d5eb8,87ece7c,41759674) +,S(ee415cb8,5e1ef106,28c149bb,2d2f9e1b,a8083367,60a7b56a,f122cf4c,9b59e5c9,f52aeac6,e2fb8a7e,ca5a629f,b431736a,eec16a06,c1a4b876,94ad8bed,bad88ae0) +,S(42da5368,b60f85c0,9f52c3c,9aa82e66,4868ee37,4b1851e,d37ba6a3,fb717e6d,71f65b16,a3937a5e,b535da,ec530798,d1c91c88,722fadb6,580510bc,5f27ed65) +,S(10bf9254,6300aa51,bb08f849,5acf4e53,b1eb4e57,1328fef8,304189e9,7acb81e5,9b519bf3,482c9516,132388c6,dabced4d,971d033c,52bb5607,6c788a37,a9eb49cb) +,S(2f6456be,5c2c184a,1dbdde7c,2dff16ac,8f504a9b,d86de1a7,d9d3c1b2,bb0688d8,6bcdc62d,4e6184ef,1fd39720,55da6e7d,45cca6d9,4d15c052,8ddfa715,4aa68336) +,S(e68e8fb9,beec6d15,207e7017,c3574e34,102fd7f6,5e5f18f1,e533487e,5bb2fae5,13624e45,da0b6edb,df4ae938,82148590,63094aac,1b25d534,f80ca56c,814a944c) +,S(7d314f19,4b776d00,b946825d,f634f763,e0b5aba9,b1fb0424,833301bc,ab1e94ab,80d402d6,a8dca19e,709b9e23,4dfda4f3,9f9f758c,928c1b9d,842b2d5d,aea3fa54) +,S(fd78e68e,5b5b9522,14b35d5f,a0951f4c,4d5df056,28c5bafb,9c6144e5,c2c33a49,49c62b9,aa91e5f4,be13a209,7f941c9d,cefbb300,eeed9fc4,a12c1e45,37f4535b) +,S(e751f61a,11e0b68b,205fd306,9f4abab0,b2576131,3ac3ffc4,eb4c525b,f2b28f6d,aafd8f6,2fe20722,b180ba67,f9c3b6e8,8ab2b96,956d603c,868a8867,c09ddba5) +,S(6db64d2e,281e6734,a8908de8,554dfa93,d7811f01,2852a306,9e6ed59e,c09a4823,1c1276a9,1de36164,309d83a2,d9fdd003,d889612c,6026817a,cda97f8b,d2cec77a) +,S(4de91b17,fc227eca,652f8d15,8cf0c696,c6902df2,b44a02ea,d05dfd68,e408a17e,130fd485,d59456b1,48458cba,922e9ce7,79968340,d7e5267,b2f288d9,6df924ae) +,S(356ceb61,8c57db92,931a305,4537ddbf,8bad8cb0,c13f447c,1c3fa485,5c0ba01b,6f52d242,ec189e41,d8ca010,cdd645a0,8889206a,4df81651,1e820e0a,74bbaa7) +,S(595d8d68,1ccf61b0,456ec03c,53cc5a93,85e553b5,36033f8,ec56c575,db49cce3,773b50cf,f0718e6a,6a269cd9,65b5001d,f5613238,3e279bc8,fb937580,a76ad035) +,S(b076afb7,234e8fd4,4107caee,8d31338a,5122d785,4707605c,2e5dae93,2e6c935b,a18e661,1921080a,84a74df6,15006847,981b552a,4c3021fc,93967c64,b19d629f) +,S(834a4467,bada612e,2705b0ae,19fc9f1c,b80e6e9f,7c4c01e,5899fba0,1f60cfe9,9215b4e5,f8194645,813f00a8,58f77324,e28522de,16e93e80,93197310,38ed9af8) +,S(d00093b1,ba6eea04,c08df30c,90b2f7de,6e13b42,c645b01b,127003b,5642aae0,87739294,746ec547,4497a951,c26ca6e9,12ae4638,1d0e2804,5363fe26,de088434) +,S(66a33bcc,71bb2f0b,ea36e5d0,f1446ce5,f3d44a9c,b715e6ba,ed00cf70,4c4ce1d1,27d0f5b1,a40fb2f1,e1f9440b,c1c15731,50efa23d,b8997928,cbdc0e03,2824a6bf) +,S(ac65226c,dc40fb92,a9632724,20983b87,9e1a7615,fcbde26,ac9754ab,408211f0,ae633790,687f1c02,52115aff,3a7d5c92,9064bbff,616b5eb0,87d5c1ee,57cf8d3f) +,S(a4b98213,78cb0e23,d46b1359,43b354da,3825e27a,76f33334,147a3ee7,52a81913,2786a9fc,3701a6e7,caf07030,3bb382b2,ce6d7c52,42496130,13382f59,92fec4e5) +,S(6f58e6ad,e4af1dcf,633d3f35,8ac86836,cf0968a,49c2e85f,2434ffb4,2475a34f,70e30dbc,dd567c8d,a6aa970d,3131009a,f5297a36,f80750be,6462f1e8,336db9ee) +,S(9bc7ace7,d55fcd7e,e67a0484,7d0d6902,f053288,ef17b3c2,64072dc0,ae0e94d9,7f57fd70,93f3d09e,53a82818,e5ca4cc1,6b46f73d,2c00e50c,698d5963,8a8f3f7) +,S(248195de,ab1ad52d,fe739d17,a03ab762,927e058b,ae666f2a,4f7e220,3173bb3d,1b1914d,3dc9f584,51ac3346,d05f033a,b793277b,dd80262e,d2ffc219,6965b96) +,S(f6008de0,21c5cd46,d9d811d4,4070a7d6,46105a55,2a68c389,a11161ce,9baaae2d,962cd254,e5b0d724,5ddf7114,32ab2800,16f5583a,b8fa02a8,61b7c3db,eed77d91) +,S(f6dce5a3,a919eab8,c1d850b,4643dd3b,96e5c7e2,a1923b58,202543e5,4ece5b40,c1b88f2a,b3d516e4,7d289ecb,b16b9bb7,4082a6c0,8ccafee1,21abf691,73734c08) +,S(23fd6281,b4958fb3,b94ac9cf,851561ca,415cc979,7ed619bd,15192ca7,7ad39a71,fac12f70,ee38f19,b2dbbd5c,3cfe02e1,b69bbde8,7a45f8d0,bdfc909b,640622b0) +,S(da3a5c2d,7cdeffda,1ff2085f,fcda0ded,eb40bd40,3591395,e4b20b0a,25a1aa8e,e0d90d58,a6cf6038,10bf2891,d51da508,77d3aaad,5ccc971d,944ea960,c943e3be) +,S(22113f6b,8015b2f5,bbff28c2,cd5dc253,c495cc62,88361c27,3e788aa3,58a94554,7b6f7bac,2db4f198,20ca6e90,bab75cd0,983536bb,80051e6b,7da589ee,dd2ae962) +,S(3b59d8f,d59a2e6,89c9d1c8,a4e2515e,73317cf7,41e38108,eaad880a,e3417c72,bb96d412,50614b50,8903c28e,b5d39ed5,b4e735f2,ea10bfa,1265aba7,f21ded5) +,S(3407e5a2,4831b572,abc0eeaf,c587b20e,9339dd05,ebf395d5,378cb151,e0dfe661,49214182,78e4d0be,31cd4e1b,9b0458b7,7e028840,4a0745f0,40960dff,b9022926) +,S(9540e180,47717f7e,f6ce71a8,31368919,e4acbfb6,18c1582d,cb4093f7,caad2601,6fe0f64c,3f0aec37,5b36758a,7f65c7b8,e9329f62,3309900,efdd58f0,7bcf244) +,S(bd02f758,513ef045,af72344,f5d790cc,1c549a23,147a2743,b8c0cb30,891af3a1,3c605d60,13a560d0,d792c5a7,6ae2f739,7631ea13,7347864,4c6bbae6,dde96079) +,S(43b10d72,cf1ba39b,17abb149,884fd00e,56525f61,594f9654,48683c16,88f3e69a,cbce7dc6,1bf71def,95bbf6f2,fb03751b,8a0c6350,9eb9ead3,713366d,8cb71407) +,S(32900344,9ad58567,6ba2607d,c873a8f0,80d9c0eb,2f7314cd,9746008f,3c569642,8c6560c6,9a037d5a,3b2e740c,270ff543,54abb60e,b32ce5cb,4d18ecf8,1ab7ef60) +,S(a1495bc1,91188644,4991e097,5334c9eb,cc277640,f568a7b3,1350e4b7,222b885a,c5a1c341,67cbed14,7f28f794,d9d2867a,9019948e,56f986a0,e69a0d6d,6ae7dd1d) +,S(4640f683,f180cf5a,4929c2ab,5169de2,85861055,67c7c2a3,3db2d01b,c3c8d726,7d6ced33,7e752ab5,c87fb211,903c3a91,e5b0ee78,361a43,b716754f,d0daad8) +,S(91b3f9d2,7e989062,ced571ec,f373ff66,f8775213,95e625db,7d1b5168,e895473a,d7efd35f,56ffd001,bcf0191e,2692e832,99d0715a,edc1a19,2b74d8f3,c0b23b80) +,S(437cb866,aedcc0d5,8d89a41f,95cf5dd0,b355f244,7885843f,c163d54,a3839db3,9d644bce,31992f2f,302c5daf,67e42b78,74bf3f9a,a944e936,aef17203,5ac2bddf) +,S(be8cd347,572e0e46,5c745c83,26799611,a5ebb1ad,3ae74bf,474a6386,6f4a3705,6d39457f,c1010837,eac6bd41,bd4a245e,10bb39f1,77c5633b,92bda8a2,c50a3dd0) +,S(f40a76f2,130d31a8,c560795b,54fa119b,153a9a75,bfe7dd28,cc00ca35,2d258331,f92558a4,69f1055e,251c8814,7a94dd08,44bb2048,31f2d33f,d95858bf,dffd695) +,S(17e01809,b94d294f,c4438a92,6f90a295,5a9ed96f,a201df62,b96b19d1,7e837876,c9506f35,8efcf330,35603c30,880d5625,db15175c,486f3c5,841a14e8,8e5f4e72) +,S(7dbc457d,7ad4752f,8d57a09e,d4e8cf02,6c8b009c,bc29afe5,ce2ee745,61630da9,fea9908b,ca852ed8,3c1b44da,207e8bc9,221b8dbc,7e8b61ba,ab8d29b4,14eb29de) +,S(89fe19a7,6fe2208b,ee4de72,249a503b,88c63e22,71794bcb,9484fd11,1df7902d,8a4853de,c3cd9e1a,713e46eb,e771ee97,b88defe4,7e1106d,88ccd713,4e3a6779) +,S(3753a13f,531da9e3,5569ba37,7db76dcf,b43b5483,1e65fd50,a6ea560e,e70f3eb2,ace8aec3,867312f4,f095b4e0,d08ad314,2005cae8,b1369223,d1301e29,8e51d4c8) +,S(30d76056,384beb45,4c54b4bc,fcdcfe0b,1c1ad5b0,5e693384,8794846e,c93a144f,f79b9c96,8eee678d,b899f349,412bf193,5da9cd,c0ccdec8,2e45ac5e,58f3d3f) +,S(d9864700,7c74872b,40ec273c,59aa149f,8059a1fa,95e5b47e,378ec515,841eb2fe,782a39eb,ea47da96,9361a337,c5e2cc0e,49d43dc,6c6f9da6,6952f347,ca51845d) +,S(40d665ec,53720f95,42ffaf3c,30e8602b,53c52123,e9dd3b91,6a2e9099,8d534fb2,cc420012,490afedb,d840a466,bc27f66d,526a965a,ee653886,8cee46a0,6a58ee30) +,S(f31507a5,516719bb,f07438a8,7b6d6d93,d02a88ca,c18fcec3,9190f358,bab3647c,dbec3898,f884cb2,aedfcdff,402ca4ec,8c8f8727,485060c6,8da0d2e4,edb46eec) +,S(62573f5f,75db743e,7939137b,6b5e1d0d,41468ed6,28d2b76f,ca26ed2d,22532c03,9a4da6c0,d7966d8b,138497df,af25b0cf,2d14215f,ff039065,d42897f0,df33be40) +,S(d0887924,f15c5069,1d7ace01,7eeda410,e8d0a10e,f6091a4a,7b5f368a,42c54416,b2fdc385,527d34f7,a434c1a4,1f9fddc5,add3b1e6,82b63838,da0ecd91,16571c4) +,S(f7585b4b,5f3318b2,2307f34d,3e4bcedb,d4b91eb,180be664,4d031bbe,9b5e3d90,b6fd16dd,49993bd6,4d05398b,9ba7714e,798d3ffe,95393231,395c03da,b3ccc819) +,S(c9cdc99c,198ca8e4,458e5473,3e5cc0c8,100fb0b2,2dc6f07e,b1e99d2f,6a4cdc42,c4c21204,67198733,a845efda,33a5c1b7,67cd8ad3,47a16b6d,4a6f5ac,995dd680) +,S(1a054d1,5c4fcf45,384ead78,e1260eda,dee9e907,84021c99,179a9fc1,c7a3ac49,50ac5d54,d4fad7d1,5fbff150,d70a3ce2,9825e79e,206f4279,f1030d29,2de89a07) +,S(b0796a05,52245e66,56b3ce51,99864d40,aed71b62,3b9d55b0,d99163de,7a8e3455,a061fa65,63a84b15,1ef666d,9f99abcb,f1611e3f,6e26dae2,6be7ac56,c0f2768d) +,S(66fcf877,6ea02717,aca92a3b,5c19387e,72658125,f6e20da0,7595e376,804c3738,9fc66cf2,3195dcdd,7a72225d,96a8c5fd,1c84287d,2189e414,d0deb6b6,76e67518) +,S(3c7caf6e,d3da8c0a,effd832c,f5356114,55646982,3a62dabf,2ccb3de3,452ac96c,e44ca4ee,bb290527,4cf8f554,40c92ad9,6055fe3e,1bb344ab,ace5c4f,80e3b984) +,S(edf616b1,1e7fd6c5,96df3fa,77bfbde,f3f82e7f,93e5addc,53c83933,844e4b73,879982bb,b89ac019,e83f5c,dac1fcf4,fb918e2f,53a5ec35,45be03e1,89bfe152) +,S(7e9af2ac,b3044985,181de5aa,9908259e,77207ab,933c7915,9dcd7aaa,90527eec,e4cc83d9,d29778a5,eb83936d,97bad637,370e74a4,3254eca7,65d0a449,106ee3a5) +,S(32dad830,3bfb015b,6aa6759b,c2e8d4bc,2a9e356d,92d97286,c92dbcf4,53591aaa,ee27e7fa,b36a2450,f04962f2,ee60f9bb,68a1147c,9ecabaf7,e0981564,c1164fd7) +,S(d20720f5,73f1db82,c1a2dc61,d3684d7b,a3943186,cd513a5a,9eecd59a,c9225a82,3b29448e,cac88f13,7dcddeb9,36f02724,6819c6c3,3f03a2f8,cc40a6e6,f8704570) +,S(3a732b5f,5dd6dc77,1d215321,f8cd223d,22f2195,9d45c708,5b000129,94d5f03b,3fc75d80,ea7a0663,c90cc7e8,8a6096f1,b3a8c9c6,9849ea50,f1fd5c94,7928cfc7) +,S(201961f5,412beebb,7e190d75,70977b50,230810bc,b3b69e3a,dfb5e259,d811333c,eaa3f681,3816ca15,dfb9aebc,8888b578,e592825,82dd1b47,ea50cad4,f59b0101) +,S(cb184267,70cd3b68,151f7d82,cf7a12c,dae332,868663ab,4546c119,fe26f4ad,6c395538,eb09c00a,3e973def,8272eed4,27a3ca9b,a77d1a0e,c4e206f8,74591a40) +,S(2c13d3ca,9ddbe3b4,2920f0ed,28622260,2cbc0493,e5156655,30b53da4,7ae3ba59,f7d9f8f0,c58510b2,db28e723,6d9af034,658599dc,fae14274,efbff408,dfd18613) +,S(3ae7b7a3,86ae6c41,90b3a0e1,e5f1a7ce,4fffc405,84f05043,93e716a4,3ec83d41,643043a8,55603964,c46e3ba0,999c73e6,ab34703d,9dcdf9de,1743db7,71591bd9) +,S(b5eea0d4,ac4d0a9d,e37fb1d9,6825233d,a00f26be,86c0b640,f0fb34c3,465bc441,9cb5b93a,56d35b2f,2d921c4f,15b4ce0f,fbb9240d,30754ace,f16b3019,54732e1c) +,S(dc049453,9b8d5200,d513eeed,edc2afdf,e76146db,358a86b4,12ae9e28,e8501e3,6f6f2d25,b331a4b3,686adc14,c26814,96004900,34524b53,8418fe5b,9776a3bd) +,S(821e937d,a6fae1b8,3b6aeb4c,f5315bcf,77b2fb07,d0081889,80478765,cea7f398,41405d00,33224982,2acfc2e7,87be9658,7baca419,14b70315,c1a57843,3f85aa21) +,S(818bdf95,f55a8e51,c0d08d83,29574c28,1ae3397c,f6ac5224,4d82ea53,8f465c60,bfd41438,46dbbf6e,3fc442c9,7a66e8b5,32445d39,fae8c473,51e0ee9,9a9a53f2) +,S(e3bb3262,36533fd7,84fc6d9,84cc5590,2b03a19b,6c956665,322c0bb6,264b6d72,bbe4844e,2be51197,d8d84c75,ab83cee7,c9ed7dff,51eac125,1161e09c,c1078aae) +,S(36e3355b,5f946199,b33dad7f,b42d1245,4cf8126c,568c4be2,cb2abe4a,b83decd2,fbd5d87a,8c012064,3ed3441e,ec686237,1759ccdb,4a7f564e,c2ff9584,ab824833) +,S(bd7fc193,1b06bd7b,c6c274ea,73d33e71,1e1e57f1,e6bf7a8b,6452d979,777aaccc,95b84e3,d8c41224,c74451c5,ec8a23ca,35436798,c2f34ad1,b1cd095,2f0170ce) +,S(b82cb5d5,2e026caf,bc075968,6e1c6c18,206231e4,f25c956c,b3a05690,8c72034a,6417cb0e,f1a18ad5,e1a2a5c6,945f3b38,b0522ac8,70188640,80a0f33e,2796b042) +,S(47d70d51,e97fad87,fa0b1c10,43246c0b,32108c36,734c90ec,9de5a2cb,c6227682,6d5a2cdf,e916fe8e,8b45d5fe,14ce650b,79a3cc9c,e4f99aae,2e9c449a,a79a4a08) +,S(13fa7ee2,5ea49c25,200b40e6,b9232eca,16dc6840,4f76b43f,510c8a12,d520dead,2722287e,35c9f98c,6041cb15,845d515c,870f5943,74a1ebd7,36f973e7,5e6dc30d) +,S(c1350b7b,2a4e73bb,90d36674,771d5537,1fa647ff,c490726a,3748e7d2,e72fa7a,2370f4c9,403ba7,8e950274,bc1f87a7,bc80c1fe,7618169d,5c9bc5c4,81e1badf) +,S(dfe512c6,f884588c,80c1ea7e,1da4b3db,ab8d4beb,60749f40,9402d583,ac793e05,b52da5f0,333b904f,678dcd37,a890b79,e985dbfa,b501e61c,89930678,5a0bdf09) +,S(88da191,2face14,e6f5ded2,30d303fc,867f9b26,d85c2299,bfac1a23,9757b34f,4236025e,f82eab9a,f1fd3c12,42a73cb7,fa305e5c,ef6ad5ab,ea62cb8a,4d74bbc8) +,S(b7a82133,7cad0eb6,c1de7b3c,8aff8798,8ee936c,921a7dee,1434156c,c6505abe,d03b693b,4fbce189,a552a66c,3ef4586,35454006,308c40ed,c7dbbc29,75361b7f) +,S(44971116,c14d80b2,f0f88829,fa1fac44,ac44124,11ac6e92,fb898e72,a0aa7ed3,9171395b,3cac83ba,18e9a0a0,34fec786,986534d,667b0521,801638ec,e19343f9) +,S(95f0aa61,8bd8573c,81b2dc3c,aa16b577,6ee636a5,a8f9c963,b8a45370,7f35a618,7f2300b3,90006ec7,37365423,2b488d72,edf5192a,a1d5afc9,4bc95a18,edf5532f) +,S(e1bd29e8,778a30e7,d9d91da2,3db2da23,bc2e8d08,d5cd170e,8e753e3e,917b728b,592894f2,114c11d5,f04dd5fa,6b341cb8,29c58e1d,a7adb51a,19d881be,39f87eee) +,S(f6110619,208f64ea,8f0e8164,1ffe9f32,8e706427,87dcf8c9,28ca8629,adb99e7e,cff63452,a596744a,75c5e8a6,badc4937,e6f2c860,39196251,30784499,733651a4) +,S(4a3f7c9f,1ba0f01f,d6d42aa4,284e4481,ed1433c9,3248da63,76f25b62,d2d2348b,dcd4c18b,2ee4e447,3515c727,1467e6b3,86b6e640,834598e1,4ce3f679,47f5c2b3) +,S(50fc4d78,3964a68,b26689df,34d996cb,6f229f2a,ed017a98,4e027407,5fd730a,7ccd6964,c6c5ab52,5d31db1b,ccefc3e2,7a0882b5,8586a955,b76c754,9698a7c6) +,S(1bdc6b52,e92022,229cb15a,6436d601,26c640da,bd9697d8,bd0c49bf,606ce554,1ddb0cbd,e7b0816e,b65d7ea3,98da0744,b3ff390b,d2e13cbb,f8fe85eb,8f3d2059) +,S(62dac912,48f29712,c3126524,90db807a,af92d3fb,36117f6a,f5c7f5f,de317000,b3bc4dd8,97a2fcf7,483c0015,f793810,29bf6f01,7be37530,18b55e35,4250ee0d) +,S(ea552caf,1d0810ff,24eb5089,31b57573,d8eca976,2b314f9f,38301b04,ff5e2193,68181368,108c4fab,7c58bcdb,5bac3a3e,31eb1b3b,837c7ead,e691b56d,e24aa832) +,S(7d6132a0,9e2c0af4,9e3359de,a750551d,7addad6,8bdc602f,e65af48b,bc1127a9,5bf6234c,903e5f72,45b46187,9d780ffd,72aef438,c0b65c7c,d0b5fc2f,8ad29d16) +,S(916d0d6a,3d08a94c,604c34ae,8c930edb,5ad57532,4dd5fadf,7a4841b2,775c475d,e3cd9b7f,79572001,a1ad9c19,2921ede7,64b12210,4d4d8796,a435eb13,d883d391) +,S(804128a3,d982b50d,203135a9,c59449ec,c43ebb35,b2bf5266,6b710975,a3847524,bcebda70,4364414,dc269d2,6214968b,95ad5bce,239ca9be,f10fa1bc,d6f31757) +,S(850314b3,4898b572,5898dd9e,f39196f3,cabf4026,8248844b,1c3d2f55,a3346f2a,eb8d17e0,3c9f7fde,29276d95,c20b657f,af2173e3,7c620a0f,d2ea7ab5,f4706b33) +,S(fd879539,8c0ee90b,89aa731,a4ab60b7,be0375fb,59932879,7bd73390,58d7aa8,3fd62aa8,35d10f6f,8bf3338b,b48bbc33,8f235cb0,6bcccbe7,56716129,abe8159e) +,S(51536953,12e7c4db,bb18ecbc,26c51224,8f841792,e557e879,8eda9db2,c9840357,175d3e7f,92ddce9e,5595fc26,725f2c09,fc322b2a,251fc323,ad3c6f08,44badaca) +,S(8783f2c5,f7325f73,e5941ec3,5f91449d,558e31f,28af335b,2fde477,86aa2808,dc602736,ccef3e41,60b100a5,ef99c6e5,c59734c3,42b545e6,21d9b03,daf0030c) +,S(c871ab31,4afd8d5a,a58a0cc1,a5eb49aa,f25b4b3b,6e0ffcf5,38851576,27c0726c,d06b7e2b,f44d36aa,fcf653df,a675bbe1,36a18938,60864df1,fbc9e604,5a3707fc) +,S(40efd5c2,1a9807bc,b34a44,71066619,a2bba48f,c306293a,ab59d9c4,b30e9b23,85cf348,4df34dad,2f7aaee7,b8a6f585,4de1314c,215f6f0f,e5a38e61,f3decad1) +,S(7feb5d9,844798a0,2413cae7,cd791e6f,54250fb8,12f998ed,e0ea6eb1,435986e,d90ca7e,8e800e6f,fd0ea027,b8a379b3,9030a03c,7b111d68,465d2a05,99dd358d) +,S(1b2da7e6,f9fa412c,ec873512,7328f1e9,ea77501,5741a284,12018290,76a79b2d,9fe58682,ba3f6ee0,c7b73933,d14ce656,e3fe49dc,ec7a5643,efa07a3f,1a4f26dc) +,S(d7fc1f3f,7a6bcaed,1a84e8e5,7127a6f6,37d935a4,35500e21,47e8fe03,d3b06066,29938603,d89fb118,14d33850,451f5c1e,bc5a5943,70c2d8f0,1d9bed34,f0b2e940) +,S(45352264,1cd962bf,35d8ab65,3d8d6c97,75782706,1454a2ba,3d957152,e177ee5f,de5005a4,3989b6c0,cee0a71,b534137f,b946b262,bfe353c9,6a217c06,c23826b9) +,S(91733546,dedbbc4,c7c32af7,760e0a4b,c2bdf82a,73e2a91c,2d70afb1,100b84ab,e60a6ca6,f2a5b12a,307cab41,8793b7c8,b7ecbaf5,18166c61,acee16ea,83071a3e) +,S(26bcacdb,bd4cabe3,e7adc5b9,27465ac9,616725b7,dce240e6,37117a5d,80a9ffb,172208e7,6603837e,4a9cfeea,22bc6002,a5cb8f1,36d73dd7,ce30d010,acc05db5) +,S(18b520f3,e997b5d5,46a1d81,ad95c52e,7841f14e,11e9d677,de918fae,7bd408d6,51b0cc1d,4c6ec5ba,e6c587d0,d6489663,dcf74bbc,d93c4839,6e4203a9,caae57e8) +,S(e25c2492,b7b25c37,cb88da91,cd76021f,de8511cd,27188b0f,d4bb4fe3,dd845e8a,244facfc,a7dfe65d,6e1d1d84,9bec4e4d,17af0d6d,2611333d,b8b7498f,96c88bd6) +,S(97e572bd,300d9649,b9de3c8a,b02d4ce3,bfbe4ba2,68844329,85971951,5c34a535,324a34a9,39004c24,b2e55e66,83577259,6c9cb2f,84378bd7,e77806eb,75e77070) +,S(4d31f4b9,42526f1e,769bcf70,85f39523,60475a0c,3f8d0a4b,c1fd6a07,a4765fda,27815d6f,3b083965,8fcbb540,925986d2,bc6d1fed,d1c254e2,9580f413,99afa899) +,S(7344c521,23968b7f,7ee12500,e9efa4c3,859a72fb,cb1cc9d7,af91e6b3,b5bbe152,4794848b,1541a965,b7527533,a6d43398,d619df34,2608021,a26bf9a8,76e0e4f7) +,S(1d099181,8da474dc,38e08fc6,d97ac823,be34f4a9,81adee58,806f68cc,ffe1ce9,f5449d7,c69816bb,6f04b32e,69e46771,c7910f3d,77cee6e2,af75c293,119f729d) +,S(84607e2f,ab205637,4b708486,51e84966,9c386eb7,c6855a1a,837c8fb8,5da8e7c3,975b5227,26e4625d,cc5c55ee,22dc667f,1fff7c4e,417cb4b1,45bcb3a4,53180ac3) +,S(3d2ad8dc,11a9103b,2f03b3b6,24d93114,83f4faee,c4b9bc22,f4f8f559,16bae70c,b4f79cd7,27d433f3,72735afd,64ef4da7,de9ac35f,98b3b6fe,5de956a5,ba93f9c0) +,S(2ad5f6ad,c7fe8540,8b9bf547,a564727f,374e9194,460f6037,ee299f83,e842c883,f613f0b0,8e306fa9,fbf39919,e3040d16,ede4dc6f,9d45ce42,e63f4b02,70832f9) +,S(ca92aa9b,e8893819,e49fc29c,dc98a42f,e23084d1,fcc37d19,3e9c638c,db0f2f93,462a5ee3,2bcdca5e,c6bf6819,32ded511,12ca847f,7e110405,a893b011,874a66a2) +,S(4e435dd7,ce2783f1,5bbded75,e832665,e4b4cb00,b50e2a69,d986d2b6,d3d893af,cddec0e7,1615f7f5,769cf2d,ee649723,1218fd34,91a07fa1,fe619f2,26673042) +,S(b1d936c3,fa1fea01,e3e28332,51f3790e,1e0f0038,58656e8,af53a72,118cbd6b,183b67ca,8039f372,d04b685e,c515466e,8ca1fdc3,7b2ae8c1,ebc5fb02,9c0ced9a) +,S(77282290,d994b6db,10b06247,1b86caab,e4524850,22a1e63a,682f92a1,ae65019c,feff37f,1fee0cb5,569db439,a7697327,1a2e4254,a9125ce6,cd94fbae,110f6363) +,S(acd0184f,18bb7c72,f7b6ac5a,7ba3f617,c40e159b,a3dea242,ed8e6c23,ad89dc82,3ab71793,fdf23305,aaebfb52,982a2603,e56d7b3a,5430585b,557d3406,42fddfba) +,S(933e3401,91e41c37,69b60410,fc0ac56a,e5bb44a2,413921b3,d25a52a7,14015cf4,ad3aa53c,76c106db,6187f4ab,755d077d,c6d878c7,64181565,77bd5d3b,affad12d) +,S(6e02abec,969eb027,bcea0303,6648fe60,da6a7c67,d1e4df3f,a34c1225,36de6fa1,c0283bd0,9fb2bc2b,19bf5086,f1eb5c6a,a7dfa258,64c73647,8a6cf0cf,c5ed5c14) +,S(2b86559e,82e5ea58,423163f4,448327f4,2429f1e3,14097621,667cf1d4,f0af1ab3,35bcfa55,9e2a71aa,4ea25edf,f9e1c59e,2274ade5,9354e22a,9cff37e9,31258107) +,S(1c02f45e,5787587b,9d68df04,66df67c9,552301d1,3b32f50b,8c9a2d5b,c826606,5f5de968,b39e9263,c1624aa8,811a4391,35150e,f8167698,c381388b,18a232f7) +,S(d0a65374,7fdd0c5a,68c55060,dd4ed734,34956730,1997d07e,d333b5a8,79894eed,272fe0be,bb192ec8,9f2f64fb,43f3a3,cceff7d2,cf92cbf4,4ddd8fd7,b104b85f) +,S(bb48b81e,e0dffe05,b6b8d05,5e1d2e5,37481eb8,2ce2bb81,cfdfbcef,bca5c6de,717b99e9,63d59e1d,66c0737b,9843231c,9c5e1bfb,26820215,78e8e01f,9e5a3fa8) +,S(23901c4c,625d77bb,1d390891,6befda04,522c698d,3c4e82c5,227c3975,3d7bc3fc,2434bb8d,98ebf9bc,42459328,464c4a7b,b26f258,2d454209,af66edb7,e84effbf) +,S(2a150d7a,961b5c28,434cf4de,ab9bdd3c,d019f667,67437158,c0f3fc38,54de70ab,e0d4756,9cec0eff,b155d7e7,37ee49d9,863374b2,4c6f4ac,876a80f3,7fdf7461) +,S(d42bd53b,1de9e41d,6e5ada81,3b86370f,ec1cfe1e,cc8ace39,edeccdf4,e16e7111,e3d4de0e,e5cb0d3,e3dcfed5,a09dcc,28c9f1ec,969d70cc,ffbd34fd,d0ceca5c) +,S(2a865f60,413764f0,d50adde6,4825eed1,134c6875,d1712396,938cd8ff,784b743d,4b628cf4,8e2a56b0,2142bf67,8829a388,929a0c0,5784426c,ed114f21,ca1dfade) +,S(2189b2e2,e88054d9,c71c2321,8cd229f8,a0165a15,650d1557,3eccc450,671817fe,6b9e0fbc,f9b9c354,644dd8df,3ec14217,66fb6783,5c698a1f,d598d074,aae79d19) +,S(e619a8d8,d63ce9ec,7f11cde4,1cfd33e9,62884fd7,471a4e67,9b9fd1c6,8537fefd,d819f364,5438c886,915f46b,40fb5c6d,6932077d,6f9726d8,86b9ddc4,d5a552a0) +,S(80c0df21,91bd2fa,2fa21bc7,ea86e54b,ee25d9ad,43893869,1cee20a9,b5792763,b27d7eed,198a695b,405cc3a,9204242e,45833ab,3b9feaea,f81db33f,938dde53) +,S(cb3926e1,eaee7f44,6f2eb390,64d4ced3,cf8bfda7,9c54a25f,6894be15,61c2d02e,35d9e098,6612e1c6,fbc2dcf3,54022f34,5b2220de,139d1ca7,5dbaabe,46c69160) +,S(82e82221,5dae0056,917680ba,a3233d29,23a2a0d0,68939d9d,2e2fe013,9aa2a8b8,f28975c9,b27352f3,f6a2972e,ef33eaf8,5d0d0a4c,673e3495,afb71869,e768bcfe) +,S(6b48f2d2,d756c7f1,77d5d33,cf62e419,b32fe0e7,352e84d4,d3056571,fd837e52,d4741717,3212dad1,b476b8fb,7ace774d,fdd545fd,6f99ba1e,b701018d,f762ad14) +,S(6cc8e1cf,ca1a026d,c1db0d97,46029b6e,b9895d7,61f66549,4f29cafc,1243b56,429b0dfb,ca05d077,d4d87022,d5ab333f,d9068170,5e246fbb,6861bd07,7e85b500) +,S(fe3de551,3fc157b6,e5bfbe45,d88f9339,71ff5ad3,c436ca5f,21794899,33f01e9,a50a9cfd,8aee1546,c422c5e1,494dd42a,db36bf43,89bac501,38211c21,803be0db) +,S(25140d46,a9453d6c,9370c901,6cb163a5,a5faf371,50152526,b01c7454,56b995de,6e00dcdd,82ee197a,3d5ca028,86fd7fee,56319f7a,925a39b3,becba6b4,c806cc11) +,S(4b9c4d2f,bbd879a7,de69e578,a2ffc7c8,8a0c700,f27f2e7d,cb8e0c2,ba3654f2,4c876a6d,7778cd81,bb02c450,5867d448,c78e9884,c72af037,55a66d7b,848e248e) +,S(2c11d305,3eb4b59d,8e8319bc,2b62624d,b97244a4,47326f24,6b83e959,5797c2f8,41e096b6,a1d2082b,c852782c,74a02cea,55dc09c,64b9d19,1265c1ed,9c306340) +,S(9a515c26,394d56b8,77c2b70e,ba1745df,9322810e,63c379ac,1c2320bc,48baa2f7,5ccafbd5,d1dc3d86,4a7ac805,adab05bb,5eb27f8f,dfabfb1f,708b2e8d,42e097e6) +,S(791a6bbc,91321ca3,6e017798,1a611cc0,db9d2600,34d2c26f,5f6fa5c2,ef7a5fcb,4cc5b203,db4459a1,f396cb31,acbaf9ca,18446f1c,cfded245,a3b32100,38417ba4) +,S(ad40b691,d3eb6ee0,e22e6d7e,1e0eafff,7afffe6f,2e0e3b75,103001f2,3a9653ec,ff7b436,47c2e09e,84f90910,2b2abe7c,2d38dc2b,151abd2,4f92d214,5607cdb0) +,S(52eeb361,405a56a1,331e3fa4,b854156e,7c403961,240f6003,135df1fa,8f3e475d,128e88f9,1f089e60,61d3df85,fcb2c50a,b0e67ec3,a7e5b3c7,ef1f53a4,5d5336c3) +,S(fe1a5ff5,162731b9,7b4423d,ad1b5169,5401920a,6b1a07c3,6ae9a25,ec3fbd18,22076aaf,ee720a1d,96e0987a,c7bb8756,b04a6b25,ddf5823e,e2f93ac9,e54c85f9) +,S(4c64f48c,fa628f72,b2897c28,4411684f,c0795753,60b8633a,188a89eb,e7fe1ea0,2eeabfd7,1b976ac2,acff49fb,bd029ef1,a42344c5,489334fd,393cc4a9,c305b4d2) +,S(44cbb9b1,7ec26b5e,3489c17d,1da0776d,539d2efe,d9317987,b86225e8,77b4eef4,f5c58a8,6ef02531,bcffcd80,ce788f5c,e43f5ad0,37e940bc,70d8411d,27c32673) +,S(2a5a456a,99eeea58,761c8802,7a86a310,63cdc681,b4ba0e2d,e5bce690,db8f3e84,7c3a47de,ce538330,49e998b3,4415c46a,2ac5c633,1a074e8a,8b4cdcc2,c6d1770e) +,S(566c0ddf,ebb82deb,bc867f76,e2fc5ce4,71249a9d,1b659237,2bfbf9ed,4eb6bf04,76989cd0,e0ffe1fb,a5992e71,50272abe,8a483f5c,6bff023f,3e5e1265,3598bc80) +,S(6fe42288,6d5d8232,4b229084,b1b2924c,b6c45080,3aa095ba,aeb2dd14,7b6def9f,b3b394b3,fc2682be,6e8c1e5a,ef2c87ce,eebe8d98,31aa60d9,ead74896,d7d9a38) +,S(35b45332,b65703f0,4feeaccc,39e04e1,72e58555,db94f04b,1899d835,9abf996b,6643809e,ae897680,5e37891d,3a241094,27ad6dc5,48429a07,64e2e12f,e89c2d29) +,S(17288055,5c0c5643,bd740b89,bbe47949,58ddb0e0,786cbc80,84d64ff7,838930da,f60cda88,7f85da2,3fa719f1,29aab43b,8b9a1578,53f91836,3fee5bd4,fcd16a2d) +,S(76eb57a6,c2d7bb45,d6faee14,4ba7c798,2d8ab2f0,5240862,aaf32c22,77dbc985,ef7cd7e4,d10ab9ce,4551c6ad,18a3ac6a,bc851768,18fe0805,f1c6107a,5c8c291e) +,S(1e5b38b5,81ad0859,454370f5,2f636726,5987e7b3,981af60f,a987c4c0,2440040b,d9817e99,89af200b,da690446,df5d8681,92808bee,91ba077b,400e8de2,712c2ade) +,S(ee17e98e,12a9efb7,c27aee78,15da31e2,af0d3294,40e7dbe1,9783caa0,2bef5709,a78346df,4d7dded6,9146931b,f1ce1b6f,1aae295,50a877ad,5f2dd0e6,adb43e42) +,S(bd574652,1eec6a76,7c2a14fb,15c85590,f7a19e12,342d09ec,67dd98e1,7739a81e,f26894f2,b8eca34,493bf871,dd6a133f,efbf1ab7,687a15fc,336d885c,6f5698a9) +,S(63852cb9,391a1ee0,23947718,b27c51a,8f9a5d0f,2f707f2,d0afd728,6596aaed,9d7c8c01,102abe28,43a7cff5,a1b15fa8,b56f50ed,1a034963,2e867007,e946d639) +,S(6c3fb2c2,d49c1c29,4eff674,158a3971,f65010ce,93f53614,ac9e0497,e31c296a,ffccd06b,98cb8021,589e833c,9c8b3b38,67850545,7e8dcf2e,775bbc71,47243707) +,S(3c29a60,103f7f0d,6f9a186e,48ac242e,46a525e2,380c4430,609f26d,6c3559bd,9381e8a8,7b4bdf9b,361acf28,cbe43e1f,a8fb073,ae2d1d09,6df7813f,bbdcfe22) +,S(bb76e94f,6f9ceffc,53ee4b3b,e27d99f2,d02eac69,8a4865f,9cb0293,a68c5eff,9ae48507,33f5984f,21726a37,c6ed7a79,e832af6,83afa20c,ee5d117f,63ab7472) +,S(422fcd5e,d2774d45,6d5f6312,c716582b,c142fcd1,342b71a3,d729643a,d022b492,b6d75412,aa9d6ff8,9be3a0b0,17384764,35ad4408,b544b53,acb5ba63,119b6bc1) +,S(328db4a7,9fff0037,c79aedeb,e8895e37,75b1e6b0,4d0a7a32,e2fcabe3,29c60dcb,40a2fab2,622ca3f6,39711923,812d8687,9d92b15e,ceaf5855,a970cf32,854b8970) +,S(4269bd58,abcd5e92,c62b0895,1c5ae948,efa1c96f,39ad3601,5e28d809,74da818f,1d1412ac,57ae762a,c3918ee5,33577c29,a8e63afd,c33b69d5,e6758416,6ff87b65) +,S(6c08ab40,97320e51,f3c571d,3beb7d7e,cfb690b7,af3d449b,50bfd276,290b8830,aba73078,edbed082,2164c850,5ca4bc58,6e53b174,83675f9a,26734cb0,747320b8) +,S(f4929f5d,99d0a5a7,3d20a223,c84261c4,6a085af9,fae2fa8c,4a025489,30174c22,afc89b10,7a38c32c,a24e947a,d8efd761,cad69f7f,ce0d595d,d4cfa849,201f6178) +,S(5cf5baf8,726c125b,e1499cb5,3f33bc0,37c983e3,b03f37af,6b48f3c6,29827611,17bd2e3c,d12adb0,5502a9a3,aa418cb8,c3809868,56d00c5f,319c34e,66074a65) +,S(c4639023,b41d90eb,2b275a2d,b7ab632a,592535ff,b439491c,f0e4e692,8188904f,738e1a93,5ace46a8,fb4f6ee0,b9026314,d8c243a,8fe08f37,b23b9c11,11763de2) +,S(a21b2fc0,2a60cae4,e694f206,1bd083be,5ed681e6,53af9271,a8ef9983,5807ce92,7f80d5e5,5a684392,939d6d1d,537919c4,99e799e3,4bdbb27c,b3d79587,f08d5194) +,S(7841ddd5,80f9f3a6,e702b0f9,3e1a4158,5e2c10c8,fcf98add,2a0f6286,c5d285b9,4dabb8e6,2aef6506,392b0fa9,4e2005a5,ad03c4fa,5fb6de65,2e89b31f,6e5ed166) +,S(5d5fccd1,378e4983,8d8b05d,41f89660,1b3a7c0,58df493e,2a74b55f,d8210356,a7e7b0ad,fba08a37,6fa3cbe2,75dcfbfa,bd0629ec,e8a5830d,d6993ec5,15ccf447) +,S(7fbd50a7,360c09ff,fe55369b,fbf6be2f,70cc5965,340e0489,77e01b68,2ab6c9ea,17ff93bf,4fc95325,26caac54,89e22f4b,265f63c2,cf46ff6e,a5b1d387,98a9b72) +,S(d6c8bc1a,479ea533,e99afda5,95365a32,cb1f3a26,72b4b960,2e039494,5b379061,cbfadb4,a6039cad,67ded1e8,8513dbf4,bb1dd3e3,437c989a,1df98b31,d234975f) +,S(5753de48,683d633c,11103cc5,b1bb04e1,5a935e99,297c73f2,fe851d91,5d5ea18a,10ef5d7e,ca1580b7,31ed4fc,3cd606b9,e6af8b1e,dea8bcc9,b91d522a,af361376) +,S(fc0d0265,b6cfdd0f,6b755a8a,c87f0ad5,b5a19894,5348c719,e9593566,91a638f,c5f31483,3c166c18,8c62415c,e58297fe,157fc6e4,b8e36b16,ce28cc75,df9017a6) +,S(61570f72,5b030b63,def84933,d0d25039,cabc8853,e5185302,d3f2d3ed,2611eea3,b3edb685,379c0068,9e9f522b,a5ad9163,9df723b6,b5c3eb96,3b05e5e0,a4b8fa15) +,S(5fa72a54,36b2b7eb,c15b34a,fefbb908,acbada63,23809159,66785d12,fbb3d6e1,1c027ed3,a34e892d,4b3d56fa,7a93ac18,663e475,a16a3d2,fac0ec90,be6d9ce6) +,S(5296b2b3,9f179516,d3cb85bd,5b86a9fb,274da608,be6e95b6,c44267af,187e2371,728aa26,e5869775,9c392558,34d00992,73eb6986,5db38b3e,df87f394,31c75dbb) +,S(b145c8b4,4c3f3c77,658899f0,a5b97c4b,dc2b195c,aa56b328,e0535217,88c80298,c73d96b6,47c2e764,e36caa26,8ebfe40e,c07b1e0,947e392f,be2a9095,7dba2595) +,S(bb585531,3cd05f8f,7fc96d8b,6e5194fd,2a70ff55,e7a7c067,cfbf54bd,129d87c1,31ed0367,8d24c231,8c4295a7,90d31094,e54ca68e,47b289c8,45b2f638,64812607) +,S(c6ebab34,ab48c0aa,aa5243f,c82a90e1,9a2012ad,74c925f2,e4e22f6b,13d6e5e,8107a95f,28e11f9b,bcef4b22,c4228c0,b530cdac,1c977640,53828b8a,15fc065) +,S(92e6ec9f,83dd27e6,3be3b0bc,8ebc521e,d84219bc,177f15cf,1bc840d5,be2b551b,931aabb1,5b3479bf,994f7eeb,34871b04,81efa404,c40e063e,59aabb77,2553ac79) +,S(280280ef,424f01ec,3fff321a,61dde1c3,4e674a56,7142c8e6,643ad1d7,e2dc4d51,84710eb4,5a88503f,b1078d06,26522501,fc165ebc,ce3b90a2,925ab1be,3c9ebfc4) +,S(6326eb72,abc4017e,c3f55af7,6a50a4a8,d0074ce1,2f5c9e08,146682ea,e406d047,53dcc346,7b61d08a,204a70b8,7658e4b3,c4016c8d,b5f03004,af6b545a,60223871) +,S(6e59dc29,408efda3,1bcd7b05,276b9f8e,bd9caffc,7f22c207,61f9fd0,a281ecb8,81c60999,45a6a834,8f2bc7e8,4ee002af,ec5729dc,aeed8187,87060c68,c2763887) +,S(100b0cdb,ed05ba0a,fcfbedde,94ecb25a,5cacfb8f,bbb80fed,1a9d87ab,72e4b5d6,1ac27087,8d6764fc,ce5f036e,ea50294,cf38c4c9,1ca9c3c2,87718505,491e11b5) +,S(95865771,e313a1f8,5629585,7ab9aafc,68a124b,6ae61f1a,a7b6e9f5,fb5de6b4,1c5195a4,338bfee5,9910935a,f5fa6091,7d06a2ff,3908fecb,b3fbe30,b0b52b41) +,S(6962774c,9035ce5e,fbb8e715,9d381004,a1828d67,38082e1f,45307ea2,d1d60eae,e9c36d21,6a2acbe5,5f9f9535,bea4b38e,7b75a149,3a281e4e,11b19064,e282c036) +,S(8e0fb8c0,d2d7977a,23f19efb,aec886a7,5170cd08,6a035386,ac784b15,9fec90eb,1218a3d7,6306cd4a,b3debd20,9bf9238d,ce00984f,47b5fafc,b715e2a,655ca9d9) +,S(6e9ea5e1,127c4c60,a01cd278,ac1dc091,e768acd,41566200,47aaa32a,e9cdf5e4,bfad3214,9a299887,c74bcb20,33e01704,ace7c646,eb00dc71,fd1e0461,af05a6eb) +,S(60fd55,9198e1ce,86c401a1,d31d04a8,fec7da21,4efd01d7,f2081027,1c49206,4f234575,cf4e6150,16ad551c,2f8e7635,3718b626,70ed30c4,a4c15e9a,488e0755) +,S(d413c7fd,2c2bd34e,2ab3e871,38495543,3b5ceb32,cba0e9e5,1e0ce198,cd5ea806,b585f836,7ef44ee1,8e32dd1d,95d6f8eb,555d8e53,451e5d8d,1cfca993,b23e344d) +,S(e26a95ac,c0855b56,b702cba4,abcf2004,c7343cf4,72056bb6,161ac077,bfecf98b,36a4834e,4532fa30,eb1caa21,c1572c46,efe4f7fa,e3c370b8,3f1fc221,632f8c2f) +,S(f0541a0a,d29e3806,e2812aab,ac185a55,687e058a,eb17157,e00a1cae,5a9e3d9a,40e81917,4473fbbb,58d40f1e,ccb2444e,ca4a616d,b0efc710,8f887c09,dd04b4b6) +,S(db1112bb,394f5e1a,b315f575,e2cfb59,4b83b599,6c82365c,c2095bdb,eb7c3cb9,c53249ca,30eb726e,6dfdb792,4db693da,f9740213,d87c410c,afa3ade9,51f9f688) +,S(2ad80407,9fdb7722,c96abd1d,35e76a7d,30948c7d,7b1e62a5,ab0994fd,667103df,5289aade,9f71ef7b,dce049cd,3052f8f9,653a9b69,3876b607,7bb42d77,9829bbe) +,S(7bcd5085,eea0f429,238c23bd,bc14017a,f8dde478,9d99b2de,325503f1,fcf7e738,7338f8a,7980de0f,404764be,7fb22578,ee820c6,16044f18,ad12d4bb,4b35a2a7) +,S(85819e4b,348ef2b6,d141baaf,3297248,7f34b594,8d834249,df465fc8,29a83188,306e8693,e7e718e6,39f48a1f,7dd5d977,9da12288,ef3edc6b,74afb1a2,906f931d) +,S(8d035a4b,5905b0ef,7fd9b050,ac1c006,2c0a8d84,1ab342bd,9444d101,92ed4a79,1ede85ef,aa83c466,4ac1cc71,c2d4027f,632f7ebe,2a097d98,9278cda6,35e2e0a0) +,S(bdc84795,289c3268,628904fd,5d8ef1f1,a89587f6,652aa883,5e83c47d,c008c282,1d8342d9,e330c123,7e232067,6fec10ab,b19c0d76,744915da,9980a9a5,6459a61b) +,S(75dab97b,d9e6571c,afbd8ce5,ffef58b5,72b6d8ff,838777f9,21834b61,1079c079,d048e6d1,fe2598db,31adfa59,8a445f0f,7f97ea3f,dbf8fe92,f2aa495,ff033bdf) +,S(b2a4a872,4a6ccfaa,8b8bde86,64fef1fd,bf9d4edc,215f9f71,738885a9,af19b42a,9bec2c2e,76be8104,f2dc4ea1,3e1ec916,23baf856,a92863cb,33b2781c,35f9060d) +,S(caeb3a77,35824f9a,b24e364c,789fe66,4729fe9,d6577ab3,f9cc857a,e1c2bdaa,ad96c92e,e91cf44e,8f0480cd,106b115f,23f0a30c,fd6ab638,86ee87cb,ba5ed885) +,S(a897e41a,75e6bfb0,78c272d,ec320e70,13afb506,478d984a,b5532b04,6da0502f,136cff6d,896be55b,5da484b6,15a09e9b,13453973,79fe4157,64ac5b5f,35aab82c) +,S(a33679a2,dc5080d4,a77fee11,5de9eab6,d32e6479,bd4fa795,3e4a03e5,3242412,1840b712,9ae52592,d99ee262,a56ae597,37e2202d,2871681c,6625de82,7c57819e) +,S(3183fdb2,b5ad14cf,9e2ee00c,e23b2c42,dfbeab54,acdbf786,622a83f,4db62fd5,7501e003,2ba129c8,50c0f17d,2a16b3c8,602c5225,1bac7212,6d454cd5,fc35a92c) +,S(aa6ac020,42f80323,ca77289c,88dc702e,e354fe1c,eedc720,2b87601d,7641b00,3ef01b0f,8b396221,8c5118e3,2168a6aa,ac901e02,5610db0e,8cf2ab21,bb06995c) +,S(f952d843,386eeef2,64b1078f,d835308d,514bc162,559c8f3f,c8ab5c18,378b40c7,fab32d0e,850f4bac,9a4af6d4,7d15976f,2e6fcf3c,958a72fa,b8db1817,cbc5dedd) +,S(75b58bbe,a5a1d00b,40f2fa2f,9e2ca8c2,eb568bc1,fe5559c,7e40ab8f,a0148e67,7fd6db81,7359736d,26883e35,727f4b21,2813be05,8d5d2477,1563696c,feaaf021) +,S(504e2324,34a12a8f,a96f64e,d39a7c0d,4168bd75,1e0b6249,6b24ab05,eff49d46,3bbb93f8,3d2ee95e,2e2821be,c3d98f4e,1f2def75,b5f8ed09,6947c4a9,1c933ea7) +,S(563fe95,1482826b,38f21deb,207a30d0,21271292,8b53c790,c33080b5,c4fc14d5,9b875a5c,70ee8bac,9e6d7225,1981c9f6,c3b5bb49,c8772243,14c4b287,e990bba3) +,S(91ed3211,161cf1ee,96499e83,7baa574d,1f56b244,56fc1589,d61f4d40,dea01443,f1664cf2,578f5ff5,8d81c281,514c7f95,56bce3d2,2150db9c,6f4a4df,db73d14) +,S(27526d79,f92c2519,838e3e0,a9ebfd02,f66e857b,d49cd8ec,6deaca31,d6064be2,9e4b644c,5bf8d50c,96892f3d,6843c94,f9afb359,55fb10b8,6a2f166a,6fa17f00) +,S(3ad1833b,df1ab0,effb0dd4,d535285a,900060e0,f38555c,ffd3e7f3,392b5c07,5c37afe3,89bf6e88,b88c9a34,6ab5a0f6,2128828a,22b6f907,8f9bc6ff,ed5c311a) +,S(eeda869c,21a8911b,cf713c68,caf261d1,e7fc58b4,3bdb0fb7,e83e677a,ec3ff6d9,f58e7eb2,3a62a9ec,f7a13dd7,b6b6809f,5cf8bc2d,22af477,e002f2c2,9c44d444) +,S(c7a806e7,bfc982b9,342fd4fc,e8f34786,9509fb0c,f0f54522,98162dc8,ec5a398,ba895fb4,f9084463,3eac5226,e91a08c9,e83281db,c406ab37,fa3ffc38,421a3647) +,S(c59586d4,ecde0cfc,3a1f5744,45cea454,aff18703,720fb4b5,1cd7b0de,de79c9b3,1eefa71d,5e67d9aa,15231b20,966951e1,93ebebf7,ae54ea34,e84b7c98,7cd853ff) +,S(3b259287,5283a78c,5aaebc13,5ba13c5d,4e5a1e6c,cfa196ed,6eb7960,e7eed0be,274d3739,5757e482,1ee56c6a,f56c8acd,f58cb337,6bb5096d,2cff4e33,ebb3c1c1) +,S(d062159c,e511418f,ea6e9853,b1e8d769,96c686dd,eef71443,e994a347,3b90e239,95ca957a,b37c702d,c707a3e6,388532cf,26cd3db2,64e4e9cd,fe0aec9e,77ab27e3) +,S(12a2bd87,c4ca2337,7915bd12,3f39e88a,fd7257e9,9587d70c,a9d8fcd3,2aa7ce4b,85562f37,ac813598,cf59e427,106fe886,aa1a078,1170f14d,3968119a,9ed65e61) +,S(9214dd98,2737e4b1,585b3363,c363ef83,b40a3228,53d6c54a,f5b1bf1a,a21e43a8,dbc49c6d,abe985f,d95202b6,bb925094,8b98bbcf,71486065,9b77c447,396e8eb1) +,S(34439200,b0dd5b6c,4fe8cb57,2e26de38,3311a479,ee39ea47,221a179f,fbbc124e,b8c15197,1ea4149c,d2a77b4d,14cea316,6d70b971,a7f9ef3d,315ce741,2ad43e1c) +,S(396b4410,cb5a59ac,15fa6034,7215ac8e,4ce3490,4dd15b41,46e90679,ca3128d3,ad4eef77,94f0c541,e70fd5be,45652364,c43e91aa,34683525,36c8b1ee,c061cba8) +,S(8ee1b02e,3ddb0913,dc781279,6316fde2,4489c98a,4e4c3cfa,c84b4350,34d53d65,9a4686,a5241a7a,cd4295b4,f1c9f094,3f8991a2,b7edeea8,bc4e9c4e,47956cfb) +,S(78f4da51,26b42e21,1d69c640,4e128c71,cd08fb67,efac0157,3bf128c6,73bbf6e2,b3836f1a,e397d7fd,c88d2089,6731fe04,6a46b2e0,b617117b,161e1e7b,3a2958e6) +,S(ff5c1378,c8a233e0,5edeed70,e23bb9e5,a5eb65a8,4b37c6c4,7c0a4952,e00169b8,a7275aab,c73eaa15,22328118,68de268f,189d3adb,da113553,e3f9d36,7664a0ea) +,S(18ff6e74,87ebb21,dc935fdc,265616bd,d3a4bc2b,35037483,c911f185,596a93c0,34209cf1,2710b007,821ba024,f0491e54,bade44da,5980f505,37869b8,b410d0dd) +,S(3ece6ecd,1c52894d,90043c67,59d158e7,143c9806,658e8e65,5fa53867,6609b0b,4b1bbdb7,7ed6deaf,fba0d241,5f2b7993,89cf7df0,7acfb8a7,a22f42d7,7858c622) +,S(a5356c78,6cdabe6,a1c379a4,ca18acb7,b41fd691,c32c31ac,6cd0edcb,9fdc5694,ab8f37e6,d19af264,58ec5b1c,78f54a4b,877c9416,ad76b646,7e91ca4b,24f988f2) +,S(e5dffa5d,961253d7,f99445b8,f8d8aadc,5415c550,da64a987,ee604278,12de570c,401ebeb4,afacec6e,d41006e9,c60e0ec7,a4840c2b,c64527ad,80d640e9,70800186) +,S(12c46133,4aa32bb8,465c1e9f,afe68d91,63a7a9df,e11940f4,593697d5,fd0c9140,e4fdfe80,be2fa183,4c32598c,a096a5d8,15386dc8,67588354,300018ff,5b2e0c2c) +,S(bd8d9bdc,ebfeaaae,691a19ec,c20cca22,af76db4c,ee54f904,ee5aa8cb,2010ccd8,cd5fca87,4a6cc17,79658266,158066a2,840e61d2,28bdd4cd,f2697e19,7c6c994d) +,S(597d8ca,babc10d5,5402f3a7,48987270,7cd5d3b8,3356ea13,6c8c5135,cefe3fc8,bb21d384,a48ed346,eadc6ba0,2b1e2231,7b2014bc,62d17fa0,9196213,6e12ab88) +,S(3d91a096,24fe1048,dafae0e8,c693226,cb89157b,980aa490,a9a12598,e77d7c19,738fee86,ab5a6e43,753b22cc,d6a28732,65db5dcd,38a6be5a,6635e8f0,136340e9) +,S(44addcb,55d0870a,19682075,116c8fc,d8f49b5c,5ef767ea,aec513fd,8d71841e,5e126cb7,8d13c0d0,55c3363,b236bba1,21cc5618,40e3cc3c,e100722f,1cdbdb63) +,S(5bc89297,4447eb3f,54b7b451,6da3d1a8,f23d6d42,54ec7268,f3e9b2f4,78d88467,6d708655,6b679453,253df54f,68541560,b5e542ea,8f1a4a9d,a023d8bc,6baf9559) +,S(8fe4f040,553ba9ef,47a0086f,a8dbb75a,2362af22,a58e0739,7c62d2dd,2ed2fc40,b2d0c561,5afbbe3a,18fcd594,a8e91e14,ac714af9,e34938f1,74a2c7d4,2028f65d) +,S(e36702c,2af02461,4d5f65a6,b855848c,6d72709b,b3ffbb5d,f08206c0,9c481a27,c5558c45,9cc186be,665a54f,19ed5f67,983bc004,c1c196fe,80c57310,59f1505) +,S(45b0165,d5eb9c2f,22c6f2e6,3f2cfaf3,5d4a71e7,460a41a3,9d3708c3,111387d4,8fcc8dcf,9eba288,f0183ba8,345c4b08,1b44cf73,b9df77cf,3e94c089,1e53cbae) +,S(ad02f6e7,378d62e8,87d651a4,eaec6d75,9b15f4f3,b7e999e5,2e9e493f,7d765205,25090d49,2164feca,33270e1b,3b08ead0,fcbc7ee4,aca4b4b7,7e06d865,5259a63f) +,S(5684c664,de3844ae,90bc93ad,426bbf69,5f349b97,6080193a,710b6125,3d6fcb0a,c5138172,4fb53812,9dffe038,7029b209,946a913a,cbc06370,b3b58f1c,759ac8f2) +,S(cb36c4a0,f6d2beae,282e9783,2148704f,aea7bea8,af0abca,ac670a7b,3808a2d6,d0aaf774,d65b7eff,589afcca,746b02e1,edbd10b3,e2938d6,5a0bd17c,f71de58d) +,S(143e1741,5da8c61a,959643cd,bcbd1eba,169257,2a935eda,1d0e2495,6eeee4d3,c12840f7,7a9fb642,50d19be1,5f35199e,1da83a3a,54fda063,99a6908f,87c9beb2) +,S(b6292192,d471ab52,fee206cb,64bb526e,6b8519c4,3df9ae85,4e4aafca,d53c1509,3d6fb4ea,45ae494a,e2c4c776,29047e33,f73af147,4fd217c9,856d5d1,3b837c56) +,S(d490352c,70551c78,9951a057,cb02eb17,fd710a0f,27dceaa2,ff224ec5,3c566a14,15ef3825,97ee6d88,ed8840f5,9d496c0e,6685349a,f1c62c27,a32eb7b2,bb193fb3) +,S(4797be1f,7ae122c9,2193fda3,80dac3a0,fdc14361,110a2a3f,5beb9f26,f3d85449,9377f25c,591ca377,2ffcdd37,65ef9a3d,6fa7c2,79d18e45,83901795,2e5fa3af) +,S(fcf5b790,98cff1c3,b02be521,76e1c6c6,ac10bcf,f083ae4,5d26ead9,82839614,8d94f596,5b075d45,a8f732dc,9fbe679,dffaf0ea,d2c90d16,b2c7ace1,1de05c45) +,S(d7153203,1e8cf246,683ee529,b2dcf54,1a731397,89e5c354,3bffbf4d,f95f76f6,740af4a,40e7849b,a41c4dea,4b7e0479,ca377fc2,69db00f8,b484c7a8,c4c745bc) +,S(27946ccb,dba75dc2,23663d14,2b56bd9f,2e63cbfa,73290de1,8fb7e988,31b44330,52c0ed5e,abb069e0,84fd8363,dcdb9134,364dcd4d,87b46025,9c3460ed,63e04ad5) +,S(cf3ea523,751eff3c,a785884a,b019199d,2a0ccf3c,1d90679e,141d4e75,74e41f61,b38d0808,936a2920,ece323ac,a707e1e4,914b51e5,e54843c9,63abf292,88ef17af) +,S(d06327e7,917280c5,d8a5c516,7e0d0c1b,e5fd9e25,4c877e9b,9ae6b264,6d9a126f,c3cc3913,9d0d7b8b,6a6b0c7d,b48213ba,eade2202,544dab7f,9ae42e08,fc7c781e) +,S(acfc233f,28f98688,2ac5ea8e,61478f62,505b8b48,38833499,1ccad1ed,5ee2a871,244a188a,64a6aa7,9f74e940,8681b45f,88b5c65f,d120650b,1a25674,eabb338a) +,S(87fb09cd,b3b8a514,f6a02da6,1d9b160b,798fdf7f,3f05d7ed,25c1c4fb,84b19253,586effe8,c4252dd8,c225a6a2,8e515abc,e36568af,107f8c75,a941e936,acbf6e38) +,S(77225acb,8ae251d2,be2f48a3,2eff0c6e,4f558287,13dc8a6d,3c6b7bb5,de9538de,d6eb8501,2aa7fe12,285e28dc,3efe9cf5,b0cc8e91,6fd63f71,c28c3f5,60259a8d) +,S(b03074f3,f2effb45,5caf88ef,e0eca7d5,6f901b18,fd04c01a,f0425c58,1f13dd5a,c8e8c915,fe06d774,8ceb2da1,78816b8a,4db1d082,6df3064e,7a4b0f85,ae99d461) +,S(992278e5,229bad50,82c8c346,8542f91,e2761305,62a34627,b1d97aad,a5999908,56ef7d8,d360d7b8,5af0f210,161ad17d,dacebd13,c45b9c8b,34f1ac73,bd6a1ac4) +,S(b73a2eca,5e9d0e4a,ef4f6ac3,e9610f3,1c72c67b,6a152fb4,82681595,8d44be12,c621ee64,b03b17e1,a25f27c2,aaea43d5,eb2918d9,e0949306,d2ef720e,8975c00c) +,S(7f6dba94,39e3302b,e4f7e0b6,f2363609,eedb30e,dc0b135d,e4aef970,cbcbc607,61685e2a,eb8e8244,175deb0,a006b5c,4292bd73,40b2fa1,3548262a,db98a3d7) +,S(88f0e36d,345aaeab,e8af18a2,d14191c3,8330c5e0,d4e32c5f,c562e549,cfad763c,bd062c83,13e44ed1,891b8048,2ee93ac9,95a0142e,e0543a92,a215735d,1e94ac05) +,S(da3a270a,bc03e6e5,3f572a27,94c8075c,8ce4590,b1b626e0,8a83fba,45dab386,884b46e2,3ab44b4b,c3d09f5b,97994e4b,109f2db4,ee04bc77,6752fdc2,6f0df055) +,S(df346699,77cd82a4,8e3e1b11,6311a5fa,3bb0389c,1c500fd5,15573af6,da0b2cfd,2ecf1fe5,fcec27d6,35c28d58,5fdb01ec,2192c8a3,848a72db,f53b7759,7b8b3735) +,S(11a4dfcb,3a443c3e,259c9f27,e24ca426,6e08fbdf,e4bbedb7,2e6cae42,569b0116,7fc6c4cd,1e3a0e22,d0ee0249,d6940def,bd776bac,9da5a98e,23cb6025,42b3de9e) +,S(2ffd148c,132eba23,e235bbd8,f09be1af,dcfd6e4e,5f2f0b49,6e4fadec,b931706e,6a4def93,52d875c8,31794fb3,6cf0448a,8c9ab5ae,804c6397,cec41b0f,24583acf) +,S(109e1f3b,7043c5d6,fb822b8a,54c6949f,117e829b,4065c0fc,c3ba5e05,a79142f5,c976793,6c034671,e5aceabb,9b08f5fb,af3cea75,a7a4485e,6c08f7fd,a63786fc) +,S(bfeea71a,8bb8ebbd,ca6135c6,26b739bc,eb2ada11,9babf946,6db9f4be,c7406610,44ff78f4,76074ac8,fd7ef860,cab01522,750fec0e,4b86f11d,831eecb5,22d1f682) +,S(4d2b7cd4,6cb01842,46e7846e,d0572489,e306b370,81515cb1,8a7c6cd1,dfb51665,60ebb290,44169e56,1d10a8e0,a2971b69,82276f1c,e7d11f60,ad7decde,e1fe9c95) +,S(66f2068c,e65a1a61,ad95ff3c,a2f15f55,29e0ce3,ad522dd3,d6083d5f,793e0e5c,a95bef60,2bb89e00,98723b4d,7fb421a5,b2cc751c,e8862ed7,439c1b36,efba2f72) +,S(4908ff3a,27aebeca,8697ec,dd7d5483,c6e56427,9d78f013,129e26ae,2ff459df,4c5def88,b60cbb2c,a3430911,aa84e4fa,1055fe1d,921c8fb7,bbb83b45,62b0f5bf) +,S(f9a90175,3a0f4236,dcb612cb,fcbf3f31,d97a8e6c,cc4f9e74,3887407,5d19ecb6,ed3c6f61,259943d0,310208e3,dd8d5a40,a5bfa646,35fca871,a6df79c0,830e24d6) +,S(ffed50c1,2434484c,ae866c1,86b88550,b0bd02e9,db04657f,aa81a672,8e321850,f16e95db,d44bc7c5,66fa0a23,669827e9,9cdf4372,6fba5f4e,a3e28d86,33edaa77) +,S(8061e9b6,2dd9d027,d43d13bd,1361ef3d,ccb4e599,c8d3d015,1d3adccb,6c762eb9,d33a9196,419b283e,5579ac98,8c1b6e60,378fc692,69b18da,a38f362d,20ca6895) +,S(ef8d0e44,e8b6b5e4,857d3d87,c82b01d8,f254c516,fdd139ff,7b8d034b,45698162,8325ccfb,6da9438c,e99dffa2,92afddbc,e1a101a1,20955945,cfb1608c,d35e7065) +,S(a31af5aa,cbc4f6ac,aebb9abf,de164046,1b631b2b,8cc43eb3,edb53185,fc1822e4,c3dbc990,691987e6,a8c318d,e381202e,a0c2297c,f06668c7,a2f027de,e5118a2c) +,S(81e47ea6,b60a3819,2094e7f8,f7bb3f48,a839b26e,d2aee7e3,e159bb39,798cac0f,186a8c4,97ba163e,aa779f6d,a8cf88a2,9f5d79f0,43e6f195,9c14bb1c,b1a53967) +,S(e15af4c7,8c61227,ffbf080b,a3b1dc2a,4966639b,926aae67,f2bec480,5c1fd232,76fd417f,4fe9e7c0,96db39ea,180d38ad,2360eac4,2730186a,b1da32c7,33fe9a63) +,S(3a185818,fb47ffff,640f265d,a2c712eb,f7e022ff,67a21a22,a2e941b3,f72639e0,8d370a41,1f133f43,34534b15,655717f0,73293f59,3bd34c5a,fc5c933e,120e76f1) +,S(18e05d9,2f227564,b572069e,18a271fe,2fef9d81,14eaee28,adb0fd2f,5f078e07,75f390d4,6e8f464a,d71067bf,b0d6596d,a945ea44,c7ede2f8,a9082440,d7e9a263) +,S(7bb788b2,4f4e5d49,2af81fdc,2f3a0274,6eedc5a8,cc74d1cf,ad17c2d5,4e80a107,5b28450f,1cd8c61,2b73038,ae889c39,d33cd64f,d452ab5d,28810177,dbb6a28f) +,S(a156cb3f,e4425b79,3334e19d,2b1208ce,5e6e8fdd,78748c0b,a1116031,912fb9d8,b2571319,c644e959,ba401415,3cba9b3f,cd8ac2f0,f8fa1f04,2d59ecce,5de14d21) +,S(eba23049,f5228794,1651a922,f60bc406,aa15acd1,59eaaf37,d1f2cb31,e7d20b25,ac8f8df,155b2703,d65b33a9,af581a02,8afdbe06,f4927a4c,5546ab7f,b5b2cada) +,S(8203a1da,56c4fb7c,96816507,f99a9a2c,950da51d,af7d21bf,123402ee,a95954a8,913884dc,10a53ab4,6b2be70f,5e2d201b,4c6bb23e,b6644817,b4257664,ed2ece88) +,S(d46609e3,ec19ef57,97ef86b4,ec51b8e5,7a854643,f817e7a0,9be4bc7f,291e7795,e1b3a8fe,3cda0479,11ab8c09,ecbbabd3,ce96974d,8a309ba8,c38c1d04,ef730830) +,S(1ffa9ab5,8eea8682,76849108,9e12ee5a,cb0ea4fc,e6f68436,377e985f,fabe919b,302140c0,7d64e9eb,6ea74636,f9efff59,e907a16f,5c876658,2f4a242c,b52f1236) +,S(4032bf99,32057d1c,8b6a8923,1575d3bc,6e2d6d0e,e1c7aaeb,ffa9ebe3,bcd9a0e3,13ae5217,f9f70a4,5f626295,b30eba49,e9f7c697,e3ed7cde,95442a03,b7916a54) +,S(8d32845a,14575fa5,ea061425,5e48e37b,f3a55bd3,9d924648,209d26ec,b94a20cd,e0416169,8f1e1626,18ce160b,e8b502b0,20a5ab81,7853903d,ad7ea792,b76266fd) +,S(403754d8,1a0dbcb7,1ff4893c,a5551387,b73d64b0,25bb612d,5e2187e6,7acea8b4,134dd3d6,8d642070,cb7778c,7ecc8d78,5c1deeb7,2582e25f,5c58b19f,2f59256e) +,S(4fbe9818,60e5f281,cb1afa62,8e8787d3,28afae7c,fcb73637,e2d64337,bd6e08fc,31a10b4d,78155900,7cec4099,3b5c59f,4bbb2328,b00a7550,572a604e,8d55b6c) +,S(a5414064,747b2ac1,e8868074,3a0fb05e,7ef510a2,a48d4f44,4647663c,b5c48b39,4b3ba626,56cbe6ce,2f228f8e,88d00ddf,135d6b81,979286d9,ec41c81a,f74ef7e2) +,S(5af99ffd,9f27830e,6ba54e05,63b3bd39,4bd8cdb5,764f78ea,b103405a,dbf3a01d,f625b35c,f510f9c3,db948363,3b2951e4,b2209b37,1397bdbf,1d899a7,400a4318) +,S(7fa7dbf0,1b2fd3f9,3ff4ee6e,17115c19,1f663d95,ff446dc9,d53d3e31,c98026af,f8aa82d5,28f2ee61,1a71b432,d553eff,ff1aafcd,8bf18e3d,b6dfa38a,f33eff7c) +,S(4838c0c,ed78e7c1,e3707d85,7311b2ca,6c7a4396,5be4e363,d4a374d3,36324640,4404fc6f,1a6c1751,3354d364,ffd43bdd,61b874f0,714430be,8a5571a1,808b5150) +,S(309c59a9,b42b374d,5c88136b,43310fbd,fccd6ba,e439e7ce,3a9c5e7c,ccb8dda1,fdded8d0,661b8ccd,834e4762,db87640a,fb1e9636,b894dd48,e1b4fb54,863863d0) +,S(1cc76e1d,788111f8,eeaed575,43afecba,548785d,3d66296,223142a4,7be59190,560e4685,6204121e,402c977e,76fac50c,446560a4,9bd2be30,c6dd2c58,62ef357a) +,S(188e8999,b9de6190,a65cc051,f936585,9e7a0498,4452402a,3093b4cb,24116589,aca3c642,dec398db,81fab67c,d05ffa2d,948a430a,e26eaa0b,ec3b2cd1,20b01666) +,S(2fca76ef,b917fadd,88e30d06,d6f398e7,6803307a,b8ac9817,4baa2945,9e9517eb,186c092d,95755005,4292ee1b,986b55c8,ee3be8ad,8adb6387,5e4dc582,c1105078) +,S(41d690fd,b5eb4f10,8aac4bff,26eaf866,86489227,b6e59b89,25440780,10e3eba3,251f34b9,d69611a4,31fe9605,7be2e10,6d058db4,34e0c814,b0b8a0c5,f2e50b63) +,S(282f850d,344e63bd,abc4542c,66cf1f1,a6807b1a,19ed7864,82d06a6f,a03b1e05,de82333,48fc960e,b22f5641,5265c1bc,be290ed9,4ee81fae,248d4676,d38a1a5c) +,S(bdba09b1,c1810ad1,ab2f5da1,b628a44d,a8512221,993c83ee,4a9484fe,6416bd2f,7049aac,e507d6f8,d77587eb,b8759f51,1b7bb2c6,5de0481b,d82a2f82,246d229b) +,S(e7e238af,4639d3f7,e5ec4298,65aade7c,c1127f41,d04b3d11,477456c2,b155a79f,da29edf,1e3c0ede,5546ed8d,cf8fa801,b5bf0dc,720a02dc,d9d706c9,a9c6bdaa) +,S(53a635cc,4e24790f,3ec5c17f,f854e2a1,800b2529,fa882945,50a0d237,58d622f7,ae6bf987,2d3a31a7,4f97299d,2fbae146,58c32dfe,418ee242,2029fff8,166656f8) +,S(10750fa7,df634f7c,7d8bd73d,e056e48a,50c413fc,282748d9,f4d0b485,d0ac5c1b,fdc72a01,883f0ed0,52d97ffa,8e6935b2,3f684f58,5e6c29b3,702f5147,dc645e04) +,S(881e3e57,ed8f639c,5023e45c,4e843bf8,e7d13323,289f92c7,143faf66,a65c3fcd,12f991ee,3390b45b,af1aefa9,dcd20da2,5891ac5d,35073750,47836a0d,e75b4dc) +,S(6be50501,4d72c612,bc0d5df9,13beac50,bafefaf0,aac7d032,824a102f,25bb45f7,4a0e0d0f,f2477287,ebd8c221,5bbf3e33,fff7194b,4217f9c7,57efa361,1b3abfb4) +,S(2ca955ef,23ed3481,615d1f0,db0fe5b3,f0fe5f1f,1b7f96a4,bdf814af,c4a58987,2dffc8f1,ce4ceeaa,d09a7610,7ee08e48,a591a177,9de2c84a,765a53e1,808e3c78) +,S(250da25d,5be3561a,92b56f0a,a7ab8fc2,bf7398d7,aca09237,3d416615,6991a05a,b0e62549,ca492ef2,9ab753e2,62b9c3a0,10df946a,99a982ab,812aa48c,def60c81) +,S(57606839,4791a29f,b66f2314,73b6bc6a,ff383623,c889695a,910c1894,d9c060b3,bac9ea05,7285d6b2,7911b19,b32fec7c,1b25db58,ae39eede,f4aedf09,46c04ae1) +,S(46edba34,d53e958c,c3e4e74a,ba8bb4d7,c6266aa8,9fe804fc,e27bb8eb,cba98e2e,2b85a88f,136b201f,9a1747a6,dc55f59b,41049a69,f824e3e2,f7f00787,f687aa6e) +,S(5d4f6ce9,ac52d698,1a13e73c,3156dff3,918d5b72,5e42f415,a503e573,bd6611fa,4c633703,1de35eed,dfc5e646,e8b0f812,2b951fa5,343d7b59,ceaa5c85,e1ce5c08) +,S(c77db927,f7e637fc,24a38bd7,f605383e,91e4e2de,8ba5b1ca,baed4376,8ae120c7,347f43e9,47b5d13c,c7cb6fc9,fc2caa5,2991a0e1,bbd4bc96,d98ff26f,1a81bc5e) +,S(ebe2ccfd,ce91b78c,95cdd34d,79fc9a28,478c406a,224bfb4,668dd5f,197934f4,d7866df2,d346bd30,84ad837a,a0c65cb4,62cad5cf,3d23b0e4,bd260fbb,f4666ec9) +,S(ddc5f94a,d4420ae4,8ece780e,26940338,294b8929,549fb897,82c06e09,b7935549,25802633,a0127d73,21ef0a12,a2a6eb32,692f2d30,5e7d3cee,f137eac5,8896ff71) +,S(e4000918,46f79f21,71b299ae,6b93108a,9377708a,e7d3f5c3,147a98d0,95e876b4,c8d8c4db,8fdecd8e,fda047f,b92bd9b7,3c999493,27c491ce,df19718b,6152c434) +,S(4add9850,90e16b5c,525de57f,a15a9c38,97527b6d,8683e407,3a978cac,53b29b66,dfa1601,d36d2021,6efe432f,8a335e2f,42b6d645,7fd6f032,d727157,32a85dbf) +,S(8a5536ff,ff9c9dc7,b2a67823,5d60ad10,834c9029,bc243f3a,f10d7e14,4ca0a78f,72ee78e4,e0a618ee,191dc7fb,c1143e4d,70ffd570,bd50ce8f,d368ec29,c22bc926) +,S(9f708795,6233a0e,59757e17,5a87e34b,f7a7485c,94f9aa62,61854b4b,3ac62c05,ff9902b9,6a6cd1cb,6ea35965,3527decc,7827318,97b5c8dc,c24e2399,fb16ff15) +,S(bfa5d3b,e3fd56da,d8e70330,dccb79f5,bcc46cfc,220f4921,4cb8e700,e7cd0ae1,2a4870ce,aa2e001f,567ac21a,79eefe94,8763b5ab,c63fa649,8a5cffa4,126c6d0f) +,S(a965e34,47f07286,b91df55,3e4211af,e6b837ad,a9cc10a4,905975f,1983f2fe,393bb45c,3f6eded,b6de1e70,5a706501,cdd10ea0,2548279e,c75e4dd9,15f0da2b) +,S(e5e38677,c1e4a659,51358301,dbba1e3f,c44f5c23,af7011aa,5ab93ad3,c69b18c1,7939d32,de371524,c3b14f5c,745ea023,34f9222,31f29d8f,c8294802,b334821d) +,S(473453e1,80511622,cbe6df28,46f479c3,b8638efe,9af11beb,21dd093a,24d243e,e2b897f,eec79c08,5afb9daf,c9ead107,57d21019,c655d0a4,e5254a69,941962c7) +,S(fff734d0,e5f24c63,dfbc061b,bac37c88,ec5aeead,4974cefd,77f1eb5e,86219772,ef8a22bb,c29c9756,37c600eb,82ee5873,778d539c,a289a50c,5490b5cd,8ee0bfe2) +,S(d0508f53,85f92779,809a1892,43a58f71,47f643a2,a8f5876,510b191a,fa292dd2,329eae7a,2ee52766,a5a2874c,3912d777,e23c4aee,390aca18,140ced23,b8e82d8) +,S(93170604,98fb43a8,41d09d53,98807f99,23405879,be9f224d,52d21971,130fba89,e84fe72a,cd89fd4f,f7db1817,edab493,5f809b78,6d0c3448,f19505e5,a79e60a) +,S(63634cc3,ce570dfd,8bf90307,f4543528,e26f2637,ce32d690,75cecd2f,63dd127,bd12dd78,7ebe0ea6,661dc389,5bdb6478,7435e9da,5812d06d,d9188b47,e1a31939) +,S(30c7e2a7,925a47a1,5aa1e2a9,6f564e31,61b7a559,3af1a696,91088dc8,9ee64431,5ef4f2d9,cfefe53f,3dc76f96,1a04bd71,6aeca894,73553a0,1faeed0f,6bd2d506) +,S(f7b7e1e,d56b7caa,74f60145,98c18126,d8bf10ad,c37cf1bb,5e6c88ae,f9f6e6e4,a019d45a,7e091a62,8b7125e,d3720f95,dcc091e4,2ff17050,da596fdb,58ebc508) +,S(c6e9b0e1,177dedb1,2e19a0c0,d1167a8d,8095b2fa,1f2dc402,adef0cad,d5d87d3a,64440da5,2b3ec64,4565ad12,6f732ae3,c81276df,5ef15605,3318693c,91c12b43) +,S(653d41dc,e6ae6cb9,45533e54,63b50a4b,72f6efa9,7884d878,52c32eac,fa0f59e,693da28a,13a9cde,d1b7597a,c199e00f,fac2f6f0,6bb0dc58,940b6734,e5eb934a) +,S(b9830b38,f0f8d466,e363fe57,38124fd1,8c9f60f8,cdaf6fd1,a10205b9,5c7212ce,a3e31906,6ace61e4,ad861027,7a12d498,5c35969f,62e5573a,5bf4ac35,277cf444) +,S(94d9457b,eb2bf3db,cd38a667,adda8750,f449af92,6a92fc93,f1dbaa85,457182ec,ff1bd647,8f00626d,1b203da6,992a2366,2ca2b39e,f6c1528e,956d7d81,7e2497c5) +,S(816f295f,1648ccd4,360b1807,bfb9b05e,4a84af7a,140a1f2a,f4016527,1d4b5b80,98217f98,6ff6f38,1987db34,7c6d432b,f24b664a,bb47124e,641d0677,aa4ec143) +,S(3b830637,17254b06,16c1a5e8,999dcdc7,cf3cac91,67284981,75c6909,92e2b2d8,dc2d471c,5323eeeb,611495f9,cb37840c,905eaeac,a85cca33,76d24705,d152acce) +,S(33282bad,f48bba9b,3db3cab7,c3b46c83,867a63b0,db393ed1,2a4bf49f,cd2f7c5b,78733604,b1c94144,ab9a4886,80bc53ec,9d67c4cf,dc77af88,40bc3535,f2c42309) +,S(58e15e93,95c3abc5,2ea68f94,6e3f7943,b1ddcc8c,e258aca2,8cd9f5e3,14b257ca,d7c15bc8,53dedf6b,f7dfad87,bcac6e37,f90d32b8,344d95a6,44879ba1,e170070f) +,S(c9ee3e27,54e8c8a1,e99c39ee,cd3d0b50,f8fcd03f,ccdab94b,e503a1ef,b66d900f,a1ce86c4,7f78400,51c87612,1b26922f,2b4b2358,e302c568,da6310f5,14909db5) +,S(6e2621bf,dcab8898,7d50b5ac,b27eb94,b52cfd9d,29e80d2e,befb5478,a3c5a514,ec4c657f,ebbe25bd,9d6b172,68ada77c,5bc4f32f,57f325db,9556ae0b,4d1adda2) +,S(6e3c35cb,9c86216a,250ae256,f8ab076a,76264ca9,97b1a6e7,41ee96da,5cfb2c9a,d45f0082,46489230,268e5c99,56dcff9c,bf6a0621,f8978be8,f2183920,eef3dd74) +,S(f3b5baab,882e20ae,b0f444e7,47688392,37acdb60,e7c878ff,40ec0aab,7896c278,7d8d6b2f,92addfcf,a248aa96,e8a87e92,4c821c1c,cf7b343a,f588ce7e,93e37260) +,S(b89b2380,110087ce,8c8bfded,7dc98e40,3cada8dd,77b2e68d,120361dd,6beeca0a,616e00aa,4aba8494,9835b0a1,eb0ff955,6268d2cc,91b7672,d0164693,848389b8) +,S(6659b720,1db6e160,58854e12,dd78b89d,40d91a17,b7eac836,ab8453c9,ee3cdbe5,5ac9db66,325b000,1983df0b,6693d93b,adf7e35a,a18f76ea,e2053e34,b1b8908d) +,S(6fc76d79,bf3c34ce,afe73e9d,7a77af23,bcc7e894,dc555f63,8b9d53c6,c15803e6,c366b411,1d6ee57d,52d3938e,f2c0c620,746d636c,92ab73f0,bc812888,ef0b5ac0) +,S(a06b2395,238326ea,20545cd7,b021a5cc,9e21e9e3,26c28b1c,fb50f3d5,e0f6e069,8560335b,a5c16aec,a297f185,ab09e976,dc57934,61170b35,b8a3b6b7,4ff622f1) +,S(bb8064ee,177f3753,19e45c8c,4dcdda70,ddc4bfff,1a866b7a,ae7922e3,13d1515a,a3be84ad,274704ff,e7a76277,d87687ff,572633b,2fb46b4b,40f601a1,ccb98d7d) +,S(27f08788,6a2c0ab,8f26ef15,a85d2d38,f6fb8cba,622acf21,77ac20f2,f05962be,ab2f2929,45163b83,c9cda8e9,4f6d8f7f,167bb589,50d4226f,827c5b5f,a782f8d2) +,S(f51d558,dfd8f74b,7c9c3768,65f82932,65c1bbad,d8aa64d1,ebbc09df,b7f6de1,101c88a8,170355ec,ac23ac98,ab5aac67,7a68a94b,9343012f,74cccfe9,308c039b) +,S(60fed665,a3ba26d,eccd1ab6,c956ed2f,e33da384,dc687f41,6c37b550,123a5441,4bc061b9,b2d7c63a,ac042a7c,efb2b5c6,a43260f6,8bd0f843,fa218cc2,3fc9b5bd) +,S(fdb04aaa,f2958755,ed65f968,ce4fbb81,ccd8c616,32e9494d,510a7b3e,d2564256,afbcece8,c52725ce,c0ef2aaf,a094385a,831afaa6,7c4cdc9,57712bf6,1073990a) +,S(7f45848c,cac04d5a,d9caa28c,e60628c,aea7f076,262689e8,27fc7084,d6b94dbb,51e16503,e044b101,a0d12d73,3a57d8c1,546c1f04,386721d7,a6f9fb15,458e41c9) +,S(b4091018,4c556249,30ec006,95f02723,b9cef749,57996d50,72642d8a,b492c9be,1b3c221c,235e721e,95bdd451,f0f0fc8d,a6a18260,d47b0c09,5f3e1b1e,f6135e5d) +,S(4d5b1a50,d00b83fa,93ab4746,3f84dc21,d0ff4559,2e697fa0,bf8e8f68,5e1c9713,da52a118,24ed00e,6a2434d1,ab383f0f,1e495dac,d08c6a2d,2425e25,a9434af2) +,S(63fb80ea,cb68910f,69700533,8a1769f0,69acdc85,da71618a,9cc03557,1d4bdca4,7f2e51d0,4446763,9cfdc2fb,247c7cb9,5b8e01a5,e27e6bda,6713ba98,1936573e) +,S(f5035d5e,12313edd,b0c31851,266f7e92,6f16c1f5,a6031aae,bd5e14fc,18304faf,7381fc4b,cfb33c18,7bb59e22,be95081c,6f52cefe,dd84bf6c,799f419,453f61fd) +,S(f62c9afc,5a2cfec6,afd54b78,375a73b0,eb5a73b6,f53e24a0,6d1e9111,ff20e835,a5d386e,211845ce,9ffeb917,76a8b91e,27f0773,b2d53fb8,2ac44b8e,83198350) +,S(7477749f,3824c134,c1a91bfd,d1b646f6,43f8109,c2f46887,22799f6d,53e6280b,232b459,2259cff5,99e4af77,1e03c94a,11fc32bf,f2598beb,2316d3aa,d9461c55) +,S(2e2c5f43,5fcf4fcf,72f9629e,ef6ac5f4,31073f2e,7034d6a7,64af194b,1e84b6ca,cb94ef61,c794f44f,2c7d1115,b9dca665,7fd1c184,e30f6f60,caf40e75,142ee26a) +,S(8f7e4f94,fd2a651,86e4624a,93272af8,2d362587,62a0baae,f65cf47a,bcd8214a,9edada6a,d23cf1c0,dd98b1f9,d9a83879,4c21654d,239f1a9b,dbace84e,de6145a2) +,S(e184ae37,4704eed2,b054b667,33544ff5,6ce55a9f,bcd7625f,740b6a67,621c75c3,ea773744,2212bf1d,a26fd119,248b0c51,c413ebaf,75e52de8,97b4383d,b397e144) +,S(fa47fd9b,94cb72b2,60fe208b,c022dfe3,a2bce2f9,ec776313,a497cd91,4166850e,9a12bbf8,a6e0ff91,5176f71b,16327c7,ea5d928d,816de31f,c8de2be4,57b0c185) +,S(98d36e76,a4caf051,e848fa49,64e09bfa,815109f8,63cd5e99,405e64ec,d526c67,706b36aa,6e67352,8fed83b6,8118ae7,1e043964,f444c477,590430aa,8d80d19e) +,S(e7722849,c00c5875,44751cf9,a88fe964,9efc05a3,4d810788,f30a2057,cc1d0c72,d64ba14f,978e1769,51951a4e,8431af78,57e6d97a,f5fc5ba0,2a1fd46b,1c215e7e) +,S(93374edb,547efea,e5f22d56,acd80ce2,80e4d47a,bddd1d9c,9d85afe4,aa6fe6e,e9c40824,cdedb038,9b42e2e7,2e15009b,215d9080,7df6316e,6e81ec9d,40dbbee3) +,S(840eb546,a076bf81,e4954196,6eb8c437,3a055239,8dc4deb8,62a73b76,8b380e28,97b69f93,ac1009d,a3f47ff1,b62ea845,f2900d7c,84e8a1d1,48d96f,df6fdb98) +,S(fdc4ef19,59ca06ae,92587249,e45d456f,d7484278,6f4b3381,676094ab,446c3e8d,c832aa3f,f0ce9f79,1fbe89e1,5511e25c,6a7a4230,401471c3,7b9ab011,1b304366) +,S(42abeb49,83403d4b,5f529eff,16bb991c,ce705250,5a61fd6b,96467a51,f661651e,d815247a,f807af52,b454e83c,9d46327e,d80d3ec3,60f84a3c,dc88b9b2,59efb05e) +,S(176fc9a0,b44a34ff,fd652cc8,bf715a12,a9d5f40b,adef6032,24536660,5e0680af,a47100b7,e0fc557a,f5ca7dc1,c220b5a,770231ac,184f14f,57e554d6,11daba35) +,S(11fa2a03,aba7cdd3,1940923d,37045c99,ff531ba2,a1266fc,26ce7a26,c6495e63,360c9e1c,54fbc823,9878d725,30254bfa,70453c3b,934915e9,5ea4542c,1026b272) +,S(b2dda11e,db5f668b,8d90dc96,9d10f8dc,6c95a16a,a3e2cbb,3a1ccc03,d9acec22,f4d44dc4,8c260995,4fc1316a,2d5bfe6a,18ea754,43bd9a55,2b2f2f08,aa0652c5) +,S(baa1d433,e2adc426,5f87f407,1c8c35ca,423f3e76,5a835a70,2d804593,cfc3f7b,3f55a493,9e25a77,8a9d3ad5,4ccccebb,8a45486e,1aeb817c,dc0a2799,6e70e996) +,S(478f18c,30470c65,b578a6c5,df9c71ac,934e3439,ee5d5d23,21f8f5a1,7adfe55c,c43dccf1,9a9e48c4,41ebdc12,f2876cbe,32852cbf,d3bebc9b,a3708fe,6cfa450e) +,S(18223de3,d62283f6,c440102a,a1769ac6,f5e1a0a2,cf3fdb2d,ec62563f,4e149ebb,57fc95f7,f8e3151b,80fa4e68,45349b7,961fe72a,d6ffe725,e3a0a0f8,907a4555) +,S(2c8c523e,179bc8d2,1e3faa5f,5db5dcf2,cfcb0426,3f138cde,428746d9,94a17276,c3f00baa,69061521,5d512c97,aac1b858,40842fa0,d8bdc773,4e11d370,4f6330f3) +,S(a001d77,af44959f,f1e83be7,d6b16496,2aecd428,3ae2c38d,f3ed3fb6,a0f12460,e68a305b,6f60a1ae,5a01eaa6,7675f0d9,8e6c5baf,75d725bd,d0e2a499,1c323770) +,S(cd8a1d36,2ba4a2db,255ebbab,ede7ab7d,383b641c,515250a5,cf52a2b6,a5b2ea9,20716fe1,e0857b5b,55b836d9,39d3175,188a6f9d,d3cc42ba,8c61a7a8,d9a7a1d1) +,S(7796adbb,7949b234,6df5147e,c3d7e0c2,5b61a874,43fea9f4,b4e742fe,6c1218a5,fc338089,c80c6415,dbb32994,cf5e2af6,b5c3342d,d291d7da,def80628,a904edfb) +,S(3c345146,27eb74dd,88ecbb47,aa9933ba,b7fc8cfc,bd80654a,f96aad51,5c1a7017,cf4318c4,1c021c06,5c100913,dc84259d,2b8d6ee8,102e5c6d,c3f809a5,7f8f2beb) +,S(cb4470d2,d5715339,acf391e6,5e3cc397,eac932d5,5acb65cd,a94538fd,eb684f67,15e6e6f3,383b8bd,1b674497,589ed7cb,e0f41394,e366ec61,b7e1b927,daa6434b) +,S(954a527f,c4496d02,915f0b11,4e95f104,c500be4d,a61eca3,2fadde9d,c1f118f2,96acbc82,d0dd6226,5652b61e,226b7ef1,c6f00491,91bce5cc,fecaebd2,fdd28ed0) +,S(d3be92f5,697a11cb,b8374938,9fe89418,97707ffb,24fcce90,16debabb,a4faa4ec,23d04ff1,e309abd2,aeac3159,ed9acffb,9c5336f5,517531c9,f1cc2dc3,a2d300bb) +,S(7490df7d,5a7ca290,fe029f3e,d92f530a,23a7c983,654bf19d,5c9ee21d,b4f57586,3d7f28c8,81b259e9,f5f735fb,be608154,b80f38d9,b5131bd9,a6e2dabe,7ab2bd54) +,S(992c4a82,1176a784,ba2767ae,a3d39697,5f96ea50,b7bc8947,2356fd98,20aa666f,519d9792,458fd39,7050829b,6ef7449d,da4ebdcf,fecb2a3,8ca0f057,f051c851) +,S(f070e211,b384b497,3d2dac23,3373a3cf,6dc7b9a6,2529af9c,b2fb1e84,b40901e1,175cb1d4,f8339521,26d4b41d,9fe27781,92a2a1d4,7d5faa48,1e96f51,beaad506) +,S(108f6113,c2795472,244db9f2,3a1002b9,349bd34e,f9c9d70f,e146df96,be198ede,2bb9d195,d087015c,253af145,bdd6134a,1845dd92,45d7d8c7,c12ad2ba,2027ba2f) +,S(ceea04f7,9b611056,ed7043f9,707bb318,e3ad332,1da82104,9790b1d9,d264349e,5380e9f,1c52e5ba,6ce18afd,289f49bb,c358bb90,9db23d67,a851dcf,9ba5ec9) +,S(1c74297b,14a4fbf1,2a6421f7,561c549,414147c3,2a683391,c4cc5eb0,79948cd7,581c9642,98232591,bd5469eb,c1a01be8,37bd5d43,cb63e21e,8540ee84,52b12ab1) +,S(14bd0f2a,ebcbdc9,22fe8660,c63bf12,c6db8521,f1f0acf,7406e982,a103bdc2,46c3002b,1e5f25e3,98c8d7af,e340aab7,23ccb0d2,7e24bec4,55d547ff,1df59c96) +,S(32c923a1,526240db,b234ab72,565d6880,b260e7a4,33747aa2,802da713,c30ae9a3,b79bdd74,6ce4ecd4,a554d66e,b787e312,a1ed53e9,c77cd6fc,73b1bfee,8b13d620) +,S(af0ec2cf,21ecdfc6,a71c6edf,6f73ab6c,76600a89,86b62006,8b246008,7cdf168,d229f3c2,7db8019a,eeb8f25d,84f3e341,681de4ab,2173f510,51ef4249,7a9dbb0a) +,S(1d648075,8273a9a9,c970cb10,5ae7e537,b017aadc,8be5044c,a1f6a3ef,4d2cb275,3faae8a6,87925e3c,e9c3482,d34c76a5,702c9bea,a307aa45,f2ee992,efd86387) +,S(160ebccd,b4d5561b,488037ac,25224afd,91c66584,660af970,672d9514,87376568,f510b49c,b58b09f9,46001627,2fe744cf,e6e7abef,8f54552b,41b6158c,2ce2db5) +,S(50867128,704795c1,a190077d,49a87c99,8b10601b,c37b7aa9,908ce92f,28969c30,106fc462,a115f2b3,e83a5474,7a692101,8c73853d,83d8a1b2,2b0bb785,bda8a896) +,S(3ff4aa26,7e8d344c,ac75a46f,7b17af59,5d056078,fe860a96,573a8f0c,164c54ee,2632d1fe,f4b34a45,ac38a80d,236b51ae,de92fb72,47b81f6d,af1b9554,4d426d82) +,S(739f875c,ebe795f0,cbb846c5,88c2b809,21468ec6,4ae09034,6032a97d,fda93c1c,8393a2b0,f3e68c9e,a57d5c8b,f8355d8e,71f4699f,201636da,5451023c,92a1b98f) +,S(717bbfa2,b2c4818,ae620498,3506a421,8cdff59f,2e040521,764b8013,b688c7bf,9229cafb,e99cbcd5,3f73938e,82723d2f,e7187ca2,13d9e0a,57c12254,dbc7f63d) +,S(cc0a808f,2618d1f4,27f165df,4412739a,6ad9af38,e8c25a2b,14bc97aa,1c5b0f7b,3b83d5f2,3d94aa87,9769c3d0,5e921731,17c345a1,3418ec3,2f92d4b2,c1e275ad) +,S(4a0b31f8,8f82abc5,6867fffa,6deb20d2,d8e7613b,aff466db,b260734d,1ef8b1c9,375d7c69,83784dbe,a5bfa8c5,8f8baead,8e94b9b5,95c01d9b,2747a06c,5fb7272e) +,S(52149a1c,53b2da97,f39e9dd0,23443cd2,b21e404e,b6235014,ce04c616,9f5d05a8,a9f9a4cb,ea6d202a,c6b5aa93,28f583c4,45db83e5,8ba7fc25,3eb43e3,df7f542a) +,S(6e294aff,9e9fe4df,9345bd93,1229a7b0,955a3b63,fd19d1ac,57bbed72,50262b8b,abe6fad1,5fe423b,e1a55867,137c485f,85639823,beb6ab2,81dd9e1e,ed447123) +,S(e9a70c2,c5e962c4,dffe24f3,8930e095,c2b0b540,cca2d891,2f6f5b4f,e4592e9d,8d115293,95051750,ccc9369,63b987f3,96bd05a1,49915103,1e47baab,358decf8) +,S(e6c934a,57ec5422,5d42dbca,715e62fc,ae957590,52849f8c,b5f282a9,b82d4adf,6da738b2,40ff3070,bf0c4ac5,50ca5a77,31db8a07,20312e2f,f9de572d,d7b67d4f) +,S(89b46ad7,cbcf1b6e,8741e422,ef53beea,49662d96,bcebbffb,57baf0d2,1441a0a2,b7205431,1798624a,3a1708a8,986ca47e,374d9704,22f7d3fc,57ca7f22,94913e8) +,S(5b949cc2,69f0b0a0,c3b85fd9,e45b737e,7379a4bc,70d926cd,cad87ae3,4e7a686,7e54863,c1efbe6a,a98d6466,65057347,7291b068,a43f1783,9d02b190,9327bac9) +,S(787baad8,9882587a,97b049cb,9906db7d,b909239,aa50e073,d476081b,4a73d7eb,8e3bb416,b57585f9,8b337b72,b23c2b9e,c790ef6c,bd397b18,ab78f8a8,cb662425) +,S(58460ae1,5a204740,c375cef9,e447edc1,2fb6a0ae,2f8d18b2,8e82ba60,729c82be,1bdf3641,d16d89ee,378e83ea,302efb0e,2a9471ac,9bcbf1e1,662885a0,81c7780d) +,S(c9bc29a2,1f7383a3,a90ed3d3,fc5f6d32,1697e354,a77173fd,77899d17,2012f63f,1c850132,db81d86e,e866d9e5,75c4f7b6,270599f,2e48c0b4,94317dc3,97d1043b) +,S(d4c54b66,a1ff77b7,63f8c520,181e4ae2,6b82643d,758f872d,cddef933,36cb84b7,23e64d9b,f7456086,ce8b778a,194f8b8d,f1f0bf38,fbb8454f,d271d062,ddb9b9ce) +,S(a947a90b,b27db3eb,8b4ca4cf,f947e587,54fe6a48,7b922ab1,9ef4b5c2,99eabe3f,c83e7022,f6e12dbb,f95e95dd,2bde8b94,3d72cbb6,5b222f57,94d13251,c9fb975c) +,S(d83f6040,4099d448,8ec6785,131524f7,3e58727e,829b3d58,7d445197,cb367746,6d50285f,831e1173,cfd7de2d,d1c7c29,532a391c,3f450b7,f25e758b,f412a8a7) +,S(75d60448,78902615,467175b4,bc16c936,14bb10e7,c9fae9f4,57d4a210,2d506a0b,885237bd,b4277447,fc7970c2,4e3e7240,ca24a07c,e46b8bac,7a91272c,ad9c5854) +,S(1f96a542,2ea4726b,b639d270,17eadf33,43bfbb7f,f1fe9307,a20fb5c5,f1c4fda,5f80a9b3,ec8b0fde,ee914ae8,e6052100,77701a73,57829803,4cac5d44,91ce0a22) +,S(3c0159ab,4f27b61e,c2599ad0,a79b4228,9000fcb9,ceadb440,24e1527a,f5ebb9b1,77df26bb,659283a,37abc70f,9f465794,ef3fb178,107ccaa7,a5404c88,a67a12ef) +,S(5b250c4a,25293ab5,34f287a4,9f9f966b,7ebc1c93,e5a774f7,c98980fa,7980e07a,dd6c9c36,5c015685,9e1ec5fd,3a740d1d,7eaea301,2311d1,a9cf505e,7e594613) +,S(20a6dfe3,71696c50,c3a7abf9,3341c41d,9d6d2111,729fe45e,f3ceb49e,977151fb,bfdd0224,fff97fd7,ac3eda1e,ec0e6f02,8bf7a3b8,23cb49d1,52d643e8,fef3d820) +,S(915fe7ad,5840d789,b94d1bd3,2d555340,3c9152f0,340a5f87,6862ca40,19825b79,8d2f0ba,3459615a,2036a07,ca57d0e0,f3a4290b,f5fa7327,2431e3e7,bc44255) +,S(d6aefb63,618e2fd0,34e4f17c,eb766d5b,c27c9a15,d796b16b,7cf8ba71,31a2404,f0abb6a6,e862f6e5,d71b062d,e9bb7b9,dfb2e4be,1c5a85a6,dd3e0c25,3617e8cb) +,S(4c804837,7d65a97e,f65a342b,c4549e16,5cb1c50c,cd1549e4,d2d2ec10,c663882d,e1ec6bee,d0bb7243,a384e6ef,100e5180,4de6ac00,b06d7b67,3e445dc5,7b76dc8c) +,S(3a6df802,f372b56,1ebed30b,a4740d03,d257d256,4931422d,fd3c8c1c,619847f4,d168c60c,9a86bea7,e48e58db,d8e6bdcf,b6ea7d31,d57f8996,70f79e33,241bc439) +,S(423eedec,169fa4aa,52588642,a62ec6d3,8acf2ca1,c8098c24,4a56a6b3,169f9932,4887b475,7f27b4b8,d288c05d,3efc1d98,c0428b5d,e4db1cb0,6dcc4782,10cc6f52) +,S(2864f372,8f8c5ca7,5dc56dad,8b968c71,a008eaab,80b8bf28,16bba436,78465be6,14f5e2c3,423f863,64962871,b786c840,50cc07b9,f537ddfe,cf81b95a,a276b813) +,S(cb96234a,985e2ada,d8130ec5,472efca5,7ed7331d,ae7570c4,dd42f4db,9597ff08,69722bbe,5b367ce,5868b30b,31f67c8c,a5f047ba,a7f65202,48041458,66b88d5a) +,S(3be93dc2,99b7e701,ddf0f239,286ac598,bea1ce42,f1e21ae8,1cdf07a7,66c1123e,8a9c69a6,6a475e40,d81b5d0c,7734cec3,40f528f7,4fa0073c,ee92161e,cbb92d00) +,S(9022c43c,7acf3552,fed52d25,d25dd3f2,9aa61fa6,988a5499,6aa3626b,88b7f497,c514a46,f328c9a5,dc2fd03f,81ce3fda,915f1e8f,127348ff,55e4b5ca,2eba0e53) +,S(a24cade9,47a24abc,a050ef7,f62d138b,85c96d0d,2edac403,dad58ff7,8a2a9d3b,a209613b,c05a7b52,41697e24,73fa7fc,412f8fc5,b2fd0447,a2e20e71,949cbc0a) +,S(cb2010d3,94259307,ee3491c5,58efbaaa,203cef1f,8a0a1e99,67a4ff3e,719495f7,1bc5b6a5,b5acd447,baec221,141b601b,a5a3a640,7f84b8f4,319a760a,6226b0c) +,S(fda8c6d7,c6302b27,76172f01,5e59da8e,4af1e96c,3bd05f2e,a393fb7e,1dc1ecbd,87ce1baa,ef24102e,19c7a17e,b267acee,7681d40d,705f7058,c514c9c1,f615e666) +,S(b459fb13,5b9902e1,760286b,b37ffa03,ceabb618,e684823c,17ba97dd,c95ebdf5,6e35fbaf,b5175d3f,ac60f2db,97447cc4,a79c212d,5496ab7e,4b536ddd,797a19d7) +,S(ec137d8f,23b119eb,a286af6c,583ef011,5d21f335,8a1a2df,ba6af216,d03b4a36,344fd1e4,869d68a0,87a1974a,d48b9704,5db2940c,dec017fd,a0605c11,8e5c7bfa) +,S(8e0be401,9f2d3cb8,9ab07348,cae295c5,eb7fd7aa,fa5a83e9,3d68d994,af68e14f,542fcba8,51510baf,6f962401,e8a607c5,34a32971,22645ebe,2dd51867,b26c80d4) +,S(b1dc8611,3cc18708,338542ac,698a6981,a6192261,7c1f71d4,3b72baeb,1c0dab03,f3e61423,5b683727,f1cca8e8,41de0474,e8c4da8,d2bef431,3cc2da5c,c4ccf38d) +,S(d438b027,7f6c7048,c1eba2c,c1d7e554,888a7025,3f513261,3bccad8f,a5a0a9d5,fc419852,23f6ba14,adda0abc,389d2d16,4a910dab,b464232,298c2a1c,50ae64be) +,S(5484d618,5cdf3f21,42235130,62ddf251,1f53a84f,f0fada86,602c4b13,3dea0f70,6e697180,33860802,6ff41cec,cea79f48,b695aa37,2a76d046,47603a67,ccf9615c) +,S(8c1856e7,6842f5ce,82c09a82,4d343a6b,ac67ff27,f6d32de6,7117dd75,59df362c,70f78515,c4bd17c,23f61049,d6ccded4,100234ba,b7e1b9be,16925635,a9aeea2a) +,S(48052022,94350095,8c904f57,54285e1a,7a17ff81,dde1f50,8586273e,40bd531d,7f1ad451,38b44b15,33327a0b,15fba2a3,f70989e9,1c271b1,461750c1,5044294b) +,S(4adae425,86b0b95c,fc26159c,6aa0b1ee,dbbc936c,83fd6056,f2b730ec,14dc17e1,e6d0f9d0,bfec452e,3f2f9b39,4d73c72b,990f9683,b6004fa3,8e8831b4,f46f9d4a) +,S(d296fd2,926eab53,db70b1d8,d5c999c5,7eb36987,62537954,2074ae12,af5844f0,b4472b2,c33661db,50b4370,e0ae7811,b16646bd,3f4771a3,113d677c,7f1c0cba) +,S(1dbf607f,5d1ea26f,ee8e416a,52c8475e,a8363cde,6bebcbb9,bc04cf4d,cd19cd54,832c9d78,60c8acc4,5d00a568,2d28fe07,4952a897,619f8b23,42dee2b5,e20482d3) +,S(12321adb,c5997830,8689b103,ec1552eb,679a3ae9,70ccfc46,f4adab54,f8dcb2b2,92dd316c,bef2864c,bd5002f5,ba052712,3f920db9,44992ccf,1b2f967c,b70d1f1f) +,S(fa2c024b,76460eb7,a64d1e1e,fe059496,c28372c8,1d00cbec,9ea76f62,546642ee,5a848904,a654469b,dc3eec26,736d7677,ceae5fd6,d6f30adf,8c3fb95a,bd8e5d8f) +,S(a77dcc2b,218b5acc,d6172931,91e8ac19,fa4d74ab,4c88b84,775d2f35,3f51e7c3,de872263,4e2ff356,7d9e419f,26ff51b6,c41fbbf,48124d01,8409a516,9735a950) +,S(83d740a8,52a6139b,53b60796,50d64902,9f9fe35f,87689977,66246b2f,91e038a,1c630f32,722468ea,72bfa970,8a27bd9a,97b68e53,12b7799f,66ede01e,9c75b57) +,S(d894b986,d74580bd,84b24a68,eba87e8,32a9c34d,bafc5717,cdc03c22,8758c9a9,f0d68c3d,284574ea,21a357e8,cad5fecb,90a57b52,62f6ee06,1868d970,458d502e) +,S(67b4473b,3f1420f5,a8fcb39c,8671d583,cc1b9f48,e288f311,2af6241c,4190a786,14fb410e,e33f4a6a,3fe5dd9d,c30d581d,a350c756,6b513290,7f3ce97,29310b55) +,S(24522965,87039934,a6927d0b,782988cc,b126b61e,db154f07,18d97d41,6dc8f0c6,538c4e2,a7e180e2,14e36785,6dedb105,f688f1c5,9bf81d30,d92a8a93,d3c5a82) +,S(b47bdb89,b087a27a,663f9884,7ab44a64,43fc43df,bb61f4d2,bc5b7ff9,234644cc,ee508868,402613fa,1a200032,afacf672,9bb3f7f2,43b2f415,383f4067,d0212483) +,S(92eb31b5,79ac7b0f,d32ac278,4f3d2c63,93c285c9,567bf912,584c00af,3be97d8e,518e379b,ea24a823,e725a3a3,3608e62a,7a40aaf5,318c2c,41afefe8,ec9afe7) +,S(a5e06969,cd69f1b6,c30ab55,1028e1c6,1bef12b4,b2c2d1a2,572c3648,fc739332,378a3b33,3db8d289,667bcd98,9a3cbe9f,f20b08de,4047164c,7f4bf9fe,5d1f93b5) +,S(604823c2,f1ab2bf7,eba63c65,610fe0eb,c958e8c4,7f509c8b,42b79934,7fbd9bc6,29f532aa,3707e872,2169a02c,210fa9f6,100c6b1f,926c73e,a3bd0427,a1844733) +,S(1b4bde22,bfef0cb0,ec9e84fc,e3af2e8d,ce7f381c,e9766b1c,c1d5fd90,9a1bc891,ab20347e,3f4c7ba3,2bb773d1,50868756,69865df1,18297657,6c283704,49451f49) +,S(10caa116,2067d668,5371a20d,97313b54,4d79b61b,3bb41a87,980eac97,e82f58ee,7ee4f118,32d9c2bb,1f849731,d779d12,571a084a,4ecbf4d6,128f33f,6af477e4) +,S(71e7f07,513d42fd,5c0ad06c,c96ce17d,3542a4a1,a101e581,f7394c2f,d89e2072,e214ca42,1033650f,e420e574,e2266c23,3897de25,90dc3999,bee41181,db0a81e4) +,S(fcbe392d,82b4859a,2424ecec,dd8cd47d,bbb89d15,ea2b9591,f5ff1067,e2cbadaf,9b06334f,6ae45d74,44b5f09a,995fd91c,a2712ac8,b159126c,8cc0120c,513f0bcf) +,S(a64d9e9b,5c583eed,aa7934ef,a7ad036,8dc9adc1,9437f97a,7a16b645,cf46e262,9357dd,1aef4b07,a376b468,99692754,9ddfe9d6,7982a7fc,d607f02b,8a7158a2) +,S(e634938c,aaa4010f,f4a1e760,d87a253d,5fd645a2,4f85a75f,8eba78bd,d876fcd7,84be5fa9,c11d8c3f,54f757ca,d9ec4e18,86e52db1,4b3cd0d3,97f666fb,f347d24e) +,S(4640245e,23e6eb75,6e0a44f7,698c1faa,33ea4f87,7a52f850,3477ad4f,8ae2f4bc,ca2a72a4,1348d3f2,6a7fb977,d3106710,2494a982,a96c6514,7fbfcca9,1ed2225b) +,S(c2a175c7,badbfe95,cf7db594,626a42d0,1247ebe5,160c58a0,2437fcd5,eed8c59,94814fe3,7692ad4f,ef0f4fd3,41c63f84,b282324e,faafbc59,38d88f4f,eff210e) +,S(b1296159,d0651519,d76bffdd,98013d1a,bb17de49,111e3035,5f7a1d40,3d8d9148,ae3c442c,2dac0847,bd8d9052,a5470b9c,80536fd9,feb5f820,e4c54ac1,78aa44e) +,S(d30b1976,b0867b57,84d5e619,a5a63516,13980093,5a9458ed,59e4a3bc,ab69b7c8,1b1eee49,690de06d,7a71c334,4fc0a647,133f2fc2,99a8f096,a8a445bb,27f5b96f) +,S(fb1c3b4,5b0f6f0e,35b93a5e,ea157e60,134b00c5,38a6e429,301962f8,38fe51ae,cf79bafa,d7c3fb08,49e1c2cd,48a90ae4,af507bba,5a42f3fe,bb1e101d,7f5fb818) +,S(2bc4d2c1,d34c6d41,9d97ddc0,c758fac9,ff6489fd,786065a3,61ef442a,fe37199f,5b932f15,9500ef4e,a331be88,7022f42f,5148c54b,30957b0,424a168c,c6d76ceb) +,S(2744c1af,3459c35f,d8e1b27,668ac653,eb25f017,e4fa15d,6c1a6bae,e50f3a99,12f95a25,a87e482c,c647b1a9,f22286cf,3297a354,4c7b575e,aa888dd5,6db2844a) +,S(6429f3ff,d37b53d4,88024393,d3a9dabf,f84e3974,ef60f446,61ec9da5,efc736ee,e8426421,f15768f0,caf020ec,3999e8d3,a1aafcb8,24339574,fe119500,a168016a) +,S(33c132ef,437e9dd8,ee9c028a,2ad51c9e,5a836eb5,4bd97e5b,4b5b6bcf,38d006af,e2527602,e5e74d67,5a5115cb,9a89c579,c760445c,c70d95f1,9ac82a1e,6ca16c6d) +,S(3ac856f3,7d53e19f,f6ab49e3,94da6ed2,c8645e65,f4666bfb,163778ce,7cd910ab,ef40efa2,55d7a5bf,99e39055,8993f753,8fd203d6,7fdfb7d0,81cf8bc7,947cafcc) +,S(5ec9648d,b58770e0,314217e,f090c776,396f47e8,ba27c30b,98c35955,aab03247,3d3402e0,8fb71448,6ee97fd9,15293e53,b095fe03,9cc3100f,21240a24,d70819b6) +,S(54955c84,3c5dddd,89f60de3,828fe4f7,1666d807,ff88006f,b46c37bb,8a822645,c8745950,64b3c721,9eda8253,633deb6e,ac9a7825,8d1de2e6,c2dee05c,f167405d) +,S(e0e845f9,35054008,fa44cc4f,1f2e538,33b58e73,bc6a04fd,c16faa76,c1a92d3c,edc48f46,2a41dc1b,bc604e0c,82d993,edc2990d,f59fa034,11702d86,46dd1c1d) +,S(bdb43235,19acce9f,b95f83fa,485940c5,69108af1,376cd09c,884e6419,718ed14e,5669c5ac,84bacd6,eb6fa8e7,39da1196,dde69170,f5d4e5c6,2ad528,66b6d9a5) +,S(d208bcfd,f9754dc6,7e099754,983fb58d,e5679bda,96d8404f,266c0e65,9e4160ee,c602f6f,f0f586f6,7ac771d1,fbf9d807,c2edf68c,a2c10cc2,314221fc,cd3007ee) +,S(3cce9096,450e620f,29b2446,39e8809a,39000315,a887d6e3,da141ed3,32b1c30a,db0ee91,b8447860,18289da1,11b3bb62,289d21f5,2aa8f436,562e982d,bab44be1) +,S(6c351350,d0fa9ae6,e1723848,33e654a3,f3f655de,7530d9bb,59d92462,1dcf8253,2e5ea374,7a368904,e4cc663,feaf6f92,4060dd70,95bab9,ca2e0773,4c48df83) +,S(c64b42da,d63cff5a,ec1eb168,41fead6b,3dbcbd97,f6786efb,5336da16,35950d2f,73706863,cfee031e,3fee4be1,9241cd94,42c24f4c,c57faf70,f8ff8b81,f094ccef) +,S(c4b99a41,7b2277a4,159bf3b4,859e36de,399862ac,70ffb482,b92e1b11,99c748d4,6ae88f86,1ff14b38,b545ec86,1a808c5c,cc78c3e7,91b48f29,350afe20,9efdc33f) +,S(eecf955a,f1ae50dc,44b57715,5ea67ae,1ae39cf3,fd306eee,e943908b,a7a42a56,26c9e114,22cd3db4,b278adb0,8e4c16a2,1a4c0a9f,b837a493,6cbdb70c,65fc5be) +,S(454ef33b,402e3a59,d437925a,b62100d0,974abf69,8803c04,436b4d2d,5a5819c9,4a38e398,1e1d9809,72df7faa,b06bfa96,20fe213a,36ca0227,c7c20ca9,2ef31563) +,S(50f11935,c20dd410,7a2cfb65,2c94e39,8df7d985,c183259a,70f6a04c,6ac5734a,aed27454,75f207b5,dc1e9f4d,f8cf1108,c9507b03,d0e889d8,d33ebfb7,3b10e670) +,S(43bfd366,10b67773,a254a077,624c2b53,4d8ded30,bf53e918,4f10e597,e2edd980,fd0655e2,e6b257ee,a249a5d4,299146d0,e08653cc,cef19a88,5ad6b33b,ae8f345c) +,S(7ad3c8d8,85cacf19,ed6aca96,4607f344,91448d7a,651fda8f,2446686e,bd06a9f3,9cb921c2,3e338436,73fa1bd,101dc4f8,a9a714ad,7fb91057,dd5af779,835000a0) +,S(874346d6,9cfbfc7a,2e13c605,baa69c5b,d39bd69,36841594,1cc50cd3,18c17380,35326549,dcc29eba,4d35a559,e8f2f0ba,b4d94ada,f2c18612,a45c9c90,8d99ef4f) +,S(1001f64a,23afdd92,789390a2,bfde9ae1,d85737ce,3e5087cb,b1bf2d5c,fd0e6943,184b6a2d,ebd086eb,6e04db54,2146059,e6ee341d,1c8854e6,e57345fd,5dd237dc) +,S(659607d2,68695906,fe752434,a229c309,60b33825,a41589d8,6e663230,c1610fe3,77005570,df191869,38a56d95,4643d991,486c70cd,3d5c336e,11a9667f,fd8f7862) +,S(eab041d9,67f89c37,c04bc6f5,a9059d69,a53e5fbf,ef7c17e1,7cef48d7,e346abbf,a2c2fe6e,63e38c06,477d2821,d22b4a0e,4edb0b55,cb1d9fdd,6cd01ebb,d8fa51c9) +,S(4ff2394f,377db94f,e96f51da,d7364407,ed6bc1d9,3822f24,91630c3c,abacda99,4a77b936,a42493f0,d739afce,b769c7ec,cc0d4720,93e839a4,330054db,22e93b31) +,S(7952c74d,e0576ddc,c85f42e6,24937e98,1502b2c0,105b69bd,4e35f59f,1c2847b2,e7159304,dbd9183f,3abde60d,5ad65ab,5a4972ba,19739b65,1d50c056,ebdd5b81) +,S(b3149a8e,f602b6a3,c69a769d,893d561d,c7438a74,bf47c2f8,ba07941d,b0dd214c,99e591f2,2f8da0b0,c9d7024b,c82d1031,cc4336e6,bf1436a6,bf03bc11,3f041979) +,S(ac3bf353,ce672165,a7e736dd,632c7018,1e454200,77471380,7b875d3e,c81ead58,78def098,2f0f5936,5f5c6519,1857463f,7376ec93,f15c01c6,980d352d,17a40195) +,S(9edcef9e,d26ac408,61d3fdc6,66e09068,a9b1e05,cc23202e,1d0b6e03,faf546de,b1387281,71de9aeb,b02b5290,d3d56d63,b6c98c00,cecf8b0b,540f70a3,79556f2b) +,S(fd48622e,8dc91972,7ac21c30,c0fb8d02,d8cfdead,dfc39a22,59853e17,5d8e6d26,4bf26514,204912d6,8bca0ce6,71a967d9,921bb882,33099b76,7a056967,3fd42bcf) +,S(e6dc2ea,c28def67,78b0a351,6ef0f4b,104fc7c9,88a03a46,8cfbf207,ca0ae0e8,d1892329,e77d5770,d9a84e59,c2d6f6e1,db6de419,87c5e3a0,ea508ea4,a11b3762) +,S(e8ff8f65,559128fb,3fc52650,ba063717,cd2d140e,ed3fc4a9,10dccaad,bb0503db,f35c361a,8ea9b3a8,139676c,3ff31cdf,5511535,7859e5f9,3590302d,bd21e21d) +,S(2e18c597,d4e4a4c7,d54bee9,215a1ee3,d149dce3,25cdc4af,f62a3da4,1922c2bd,3e8595ae,4b6cd57b,7f685a75,87ed61a3,281b52ff,d76e9126,4a0f0666,701c5354) +,S(589924a1,2cc867c5,b2289f81,2d93f324,c2df420e,3c948bbc,e74b6bb4,6d30f262,f9bf3d02,cd0001c0,bb9558ff,515ee86f,e39d4357,fd39cc3c,8ce73c75,72850466) +,S(ef55eae6,4a07199f,1a3f3463,5007a8c3,8d39db17,48af39cb,584d4471,d3d32e18,9d31abdf,91bfedda,3c1f02a,aceea672,21d347f3,5d355042,75452c91,5f4b19b5) +,S(7a8f75a9,41182eee,49883295,56588c86,3021548,70ecc05b,31b83a1d,74be05d0,bda4d0ac,ac72ccc0,c07270fd,1c2bba00,4cc9ce5a,fc927f,6d4bc0a9,b2fb4a64) +,S(330f8a4a,582dad9c,159e0f9,a47101b9,223fed7f,896679e4,f764b02b,3d1d9eeb,50695f30,f9dc9c75,6df20cd9,aca3a06d,7199c138,4b3ede52,2dfa0816,31fea2f7) +,S(6dd34c6f,b89722cd,182cd5b6,a0d83132,56814bc,7ff147ae,668618e0,30bceab1,8998216e,8ccfeee2,78e5c0dd,e206d3b,1fe058c3,990159f,be3beb2a,2a97cd60) +,S(66c2d4bc,1e1ee63e,75481e23,1e6df60b,82c73758,36d4c9e9,fa99a576,304ceb8,f6871e84,fcb56780,682bb226,a8d2f46b,89cf516a,7aa0de01,2ccd981a,b739244c) +,S(560ac5cb,b9a55c0c,8bd6a36e,9dc90922,9297a452,b83f8db0,e0899577,cdb8d04d,b6255568,4574e609,ab7dff47,938008da,5b11adaa,480becaf,287f2216,cf1c7891) +,S(a2377a79,e597dffe,224988b1,63ca63c6,67827b81,ccc645ea,cc23ddb2,2a1503e8,7663e301,4dcdbd71,620ff660,426581cb,7e723605,72b651a7,103faf36,480834bd) +,S(fac987,e1c77065,bb1eeec0,fdd92f05,5d10e738,befbb155,152bde06,87c7fadb,c6fd2faf,683f4e87,77a6166b,59c4b93,e7f5d803,fec49ef3,29e1a4ee,9981e803) +,S(81ee9f52,9b5c6b11,8fc6ec23,88f3ecac,4120f8ec,d134d22c,f809e2cb,1e88a490,e8bba906,3a3ba848,7bdf4a82,c5014493,40da0e2b,fda93fc2,b6440b50,d24536d8) +,S(e6439a0d,545c7431,cd8321ea,420dd3d1,9932427d,475df712,529bfd17,99dbc4aa,6c86e739,b6d0f23c,d3570bc1,86fd9e1f,e617fc41,8089f2a9,d42d0b91,2b4c8d39) +,S(e08169e0,f7362908,a0d207f,bf49a44f,5839c76e,7ad80a74,44e7d24b,573f0bfd,948ce18f,15ef6e2a,23f2db47,db402d38,2a4a3cc3,a8a3756a,c382cba4,f608283f) +,S(5687e6f5,7b2bacda,eafe58b5,94bc322e,70c7afe7,884ab4fa,4d46467a,7a8ba729,994d9091,e432b4f6,72e7f711,b5e0a7bc,b07fae10,b6e05ca0,5a088cc6,e4d89d80) +,S(6edfc830,82a178b0,d9160f4c,f0b01004,65c29bea,e3c29d31,e3826aad,9fa1979,5f4c6676,3df8ac3c,4490ec9,fcb0695b,e9c0532f,df526e83,f27ad47b,5bfff2d9) +,S(28128135,a17d0e29,4871831d,2542c2e6,80dcd79f,6b4fafc2,722b7db8,4ed449ef,4f7e515e,b5c7eb7e,415d7b02,83ff11c4,8f3f3ce,a724c476,71d02d1,50835702) +,S(f55371f4,2d617023,dd5542fa,db9a9127,c16ac04,1545db5a,a18cdbb0,cca4cacc,d0c795cc,54057d47,5bd080a1,acbe6881,3263f593,917e012c,dc1bdafb,920b3ec2) +,S(10fffd7d,a62de848,c07b50b9,64e3b31,ee6a13ed,996fe92d,565cc54,fd0b7c1b,92107e28,5319ce07,61e5f212,5724f2eb,fc61498,f838717c,6637c7af,8f0fee23) +,S(a6a73f68,bcb103c0,523c8f28,f14fafd7,5b8d399d,617a68d4,6ad0a1c8,6f12a46c,d18efb60,37f40a9f,6567c993,24f3a7a7,543fbc30,feec0252,87dc862e,b22fa279) +,S(2984cd0d,5c4f1c06,3854d233,6cdfdca6,50c94275,975feb2d,1b0b5bb1,c7dda582,41b0a86,8064dfd6,5c2653b0,27dfcc75,50eb755d,7c1f5c78,b0c13493,acbb4db0) +,S(a701d075,7be9ff89,67c67622,dfa8ff9f,82f7d5d7,814f6c29,c73045d0,c5b16589,ada61af5,62851c60,66501019,70953ba6,fca0d99f,42378b8a,5059ceb,2a0835f) +,S(f07463c9,c37479e8,259a32a,a2e8f283,27cc267b,95aec8c1,1242a092,bf4c47b,1ae9bb16,e538ff69,1e9ecc98,838e112a,a2016657,c7af104c,ee92471c,df6cc136) +,S(fdec5a71,21a17f37,b4c2e93f,56d910a1,788d2da,b3cce509,b3e2f3cc,f141043b,a62e32d9,336fcfd1,4bab6cf3,26ee3f31,4d2ad023,430768ae,8f093408,e3505d90) +,S(be32f9cf,9a13d4d2,652d122c,c0ce07b,da21fc85,52c0808c,23dd5a5a,9ffb3599,a4a73b26,2b5f8239,e8c279b,20f79c71,7ea47a64,1c084f52,f1bd4f3d,dbcf9c43) +,S(735a1f6e,2575ee01,9ebee00f,a4acbcc5,93bb6572,c4db9505,bf96a2f,43b66f38,20b1c7a,99c6cfcd,58b3f00a,3f9d7739,f9cb682d,946b33c8,879f041e,15e198f8) +,S(a0b840b0,6d92eb95,4f029204,1229b9f0,f1838bdb,4ead7432,4d8facd,70f7447c,383fa2d6,47d88c1b,fc9b04a8,a27b3a99,1a22b82f,7c99fce5,5cf30855,ed1c22f7) +,S(3e54abd4,36a9763e,52b7f46f,4955a339,6db284cc,77d0b351,fee7a568,e4774c83,1c64ede4,fb372325,dd435f71,e4dc914,391da9f1,ee08a21e,2eb5ec18,2834b0ab) +,S(24675c97,67f69242,4e1d43e3,1c46ecf,b418fe9b,3fcdb495,822362b,2a8adcb8,9e38e08a,4359dd9a,a9ddf4c0,8fd1147e,c70ccf1f,8855cdbd,49f44dcf,1edcc36d) +,S(16e0176,9f5a5c0d,f6db88e7,fc95419a,96f836f4,f8255a96,77ca2710,2330e317,30641d0b,fbf7a1de,24c72692,b7032355,6996bf3f,1b541dae,d6ccfe8a,f847646e) +,S(a2e30015,a53829d7,c95d5704,3d6dac44,bca932b7,d4115826,c602aae6,8e4ef847,33ecf0cf,e81236c4,e8fb76e9,645e4827,9bfa617,f6d2760f,dde2b110,77da6ce3) +,S(cd9bcbcf,b7338c75,3fe393d2,2e2e44f8,45a09b83,fe4ce29e,546f2a58,7d7422c5,7683e5e7,f990e09a,e15902e6,c57b8db9,e2b1d29e,8d3bf33a,f90291a4,616c794d) +,S(77a00bb9,6abb918d,774a2a4c,3828fa5d,c7d40bfe,aee10091,f5d92cae,cdfca277,f3febab5,3310a2dd,5dd7a5e1,33572b3a,83950172,be7e4cd6,fec7575d,10142e02) +,S(be2f342c,ca1f161,d15f98cb,ccac9f2c,806c6d1b,f34656b5,c671c730,bdae8efa,c9c7a70a,88ed250d,6a7c0307,d3dd907f,ca8b399d,4affce18,e988ce5c,e0efb5f8) +,S(538bc08,c3c775bd,33edee48,c96c6fbc,1435b0c,f00aa42c,6c15fc7c,5540dd6e,9d8b1293,14283325,8d676a92,d479ebb2,c5ca171d,a43fefae,74c7740c,7e956eb9) +,S(d5e26827,fc0d8283,ee020376,56e83ae1,3ee306db,92d0bba1,6b3fd99c,7af15578,b41d4816,b9643a41,c4f8c5f,4121cddd,d7eceeea,9f2156ff,676d6d2b,61b7d210) +,S(7d18f6e9,95f9077f,c371fcce,729835bf,aa903ef6,682404da,bff6949,4b7faac,1423bd83,89410b9,a2cd8c3d,3d13b495,d856b103,eeb96e64,8c258ecb,a77d581f) +,S(fcb3cd95,fb0b4940,bdf0bd4c,ff534d94,26489c72,953b19d0,cedce320,6e3eb556,46043aaa,3d1ce85a,3009911f,763f49bf,df3d7fa6,347f5573,4c6c36cf,97f15702) +,S(a0e8413e,f66527ff,12f6de1d,2ed4eca4,6617064c,afcc4e98,495f2694,34492800,ac640fc,e3d5d094,54ee6811,81f8bc5f,3fb1bac6,84c8c572,b24fe3a8,66234d13) +,S(fbf60da6,aecd3cd,9137b28c,f7bfe541,efe60e65,52470f80,e301884c,1e9cf33f,aab83f4c,9d9e5ed9,ee35be7d,33a02bec,ebca4f40,8f6fafaa,6f385a89,8f7d846b) +,S(771c8d7f,73bf2b9f,4f032e7c,daf17c39,c375ce1d,2e180758,fcffd82b,26fe206c,af22f29,ac2ec5a8,ecb69e2,aa954f49,63d4a58c,2d6769b2,5255e9ae,2689f756) +,S(a30bea5b,4a911ae8,de11a310,a9cd3616,54143337,30aa182e,ba75601,3d12ab80,aad0f1fb,a9a8d6a5,71301b1b,dd11f4bb,161c26e5,3d3d5143,ad2678f8,9960029a) +,S(55d93940,b0a76283,6aac5bb8,c04f490d,e7ad8da0,4cee090a,e1f381e8,5c13fd27,f1c58d73,b90819b,bab9933d,60f54370,7a625449,d637f01d,bfcd6b44,bb467937) +,S(f6b03260,ae0373f5,b2ebaf15,1a74369c,22535844,13ec4356,ea4a9a32,f2132f81,4fd750b3,7f377f97,7b62580b,6ee7176e,a720a434,8df7aa86,642cc6b3,963cfdaa) +,S(80f7aad4,3deccf41,cf4540db,97150bd4,f4665ef7,72bf6c4e,e551c566,d11d13c6,20a9b836,67cbb397,aadb1211,fbc9a78e,2e998354,6f263403,1d844e7,b95766aa) +,S(4f574d76,130e2eac,16bd6b64,85bdd2fc,88855c3c,68a232b0,29560509,463f0c90,33dabadd,62ec0192,9fc3ad15,587150e8,ead8518,327207c8,7ad2a7ec,c712d268) +,S(41b6872f,f47a0d4a,764ab086,764e1844,a8b4c775,cb2bb06f,643a7c13,5a633e6c,301d54fd,d55c9204,4d337b83,ff17dec3,3faf0bf7,ddf7b5c0,afc8934f,65d54e17) +,S(9f4c75f0,cb44460,ad14d416,76c8b60a,1ae979cb,1ff6a506,b5523cee,8acb1bbd,253d8a0e,985fdeba,1ced50c7,aa3724ae,79c75c6d,7c82315e,65f3b579,5fcf70ec) +,S(25db3430,667796c3,b5f3ec0a,cf4f11e4,73518ce9,aec19932,3f0c5adf,e32f4a87,cce88dd2,ec02e348,ba569fec,15a3c527,ba580e44,c32f25cb,fa6f99f2,a1eb4250) +,S(fa71cf1c,2312c228,c706a7a0,2dc3b9e2,f571b468,913b9cb,3fc5ed1a,faf730d,156df61d,752533f7,afee2781,30763eb9,45a6198b,a78a8288,f30e381b,a809eb61) +,S(f5d3adb5,6d77855d,8e0d0b71,300e620c,f96a45f1,5948d97b,affc3ad1,7226294b,95fea642,5be2e987,968f54f8,f3fb30f1,e9a1ba5f,57b68b1,101a5981,a47f9f4c) +,S(907eec9,6db952f0,eb7d0436,c47f5980,dcae53fa,ebabe57c,aaca00e0,10361460,1cefe286,19dfb7f1,969c7618,e0ed4775,e23527df,6a214754,4cd066a4,65f92468) +,S(abbcec4,36e06bc7,bb92dd79,bcc5d9d7,73189ef9,2546dfc4,54b5d624,2c96e8cc,d1546a38,1f335077,ef40473d,baac9c37,66aba23b,8040c4c0,60778d13,8603be7d) +,S(42f1594f,b1e088f7,2020b68f,7fdd9027,b9638619,b0320410,fc4bec4f,4fbdda76,9a417cab,515a08fc,9e7a7c64,7029a457,9881caeb,df8430bd,c1712af1,3c6b02ba) +,S(a4aace90,751aafa1,fe3e14b9,ead1d460,e1cf029d,cc82afb2,4d169248,e63f83f,97ec83af,dbf32c34,df9cafe7,de0b6ee0,67460d5a,607e1ea,fd13a96d,51999d54) +,S(ac7ef2c9,56b41a0d,824999ca,550ddce0,83f2aba4,8f2bce5,644a579,c0e248c4,d97b0ee7,f3a109bc,bd308b3,e4d4ce2e,c1a65878,e7e5939a,76c9d8f3,6959c5f1) +,S(e9cb9aa0,ab09aa1c,18daf08f,bbdd0457,25d4ac95,8607a88e,5bb14c1d,61d826bf,a1cc215a,124e31c2,e426e337,89736101,b739a56,b6d4e139,ce65272e,2e4b9a5b) +,S(885de0dc,e9700b34,9e10dc17,68f9fe12,2672ed3b,ff9d20cd,93b98e38,ebcc67a4,f66a36d3,75272f66,cad46fcc,cc5d3df6,8c023da0,1ebcf766,f4dfbb0,60e1eae) +,S(8ad4ade1,ff9a19a4,fdc89e75,e4cb61c9,1485ebce,b1e4c063,ccb8001a,c5038e6b,e02acfc2,19c22881,d38a8232,fae54d82,e0b1fb77,e6b8b741,890357c5,be261ff0) +,S(5b395388,a62979a2,b931f243,7f3f65ab,292ddad7,728e67c0,e753565e,578fa354,7e77c8a9,7c274030,b22e802f,f0fd69f4,da65e54a,b50953f8,b9945b79,20fb89f5) +,S(271982cf,eb593e95,17a8fa5,6f62fd23,ddb6c7b3,8e5a87e3,712793b6,f10a2d14,6661cb55,543414dc,e02b3650,8660d54f,48086cbe,4b517092,564188d,6815d2ad) +,S(458be91f,a61f477e,47d7b997,931c992,86281efd,21445349,af820000,58b2a93f,48725c06,e7dbe303,f0c73d43,a5a62b6e,131d004,2bae9dd9,ec12cf97,8df04c49) +,S(763f00b,348c1cb9,e922c6dd,a7e72e22,8624fae0,158af602,457fffc4,cb0bf3c1,8119c3e5,b190c6d8,7f3d7066,72136a3b,d0f1b198,d9f304b4,cfb383ec,e075de74) +,S(4fd5e9e2,77fdf260,8ece7268,10343542,312773f3,2518b363,7075fe98,dcf7719b,c234141c,d3e83309,539aa906,2b17ee35,99a3246d,86ad20d6,2885cfaf,5a88162f) +,S(c578afee,a7e492e6,30ca55ff,8923d9d0,9a6d0583,5553c61d,fe871b6d,e1d956b0,bc2d5e2f,add48f2a,50e357cd,4d4c120e,e744fd96,dca0a959,c0bf482e,2e081ce5) +,S(df02c64e,7a60b87f,73b4add8,5ad93b40,bb6a862c,18e0fba4,3f722650,c0439107,d86dc018,525efc69,cc7b282,cd145650,3b9bddae,607e14ef,3e380d53,c266fe29) +,S(9471f488,84cff3a9,2a99dcb9,4cad96f9,d4761570,c0bda860,bf1b0a9c,32a27a4f,23471d9f,6b3905a2,6d9481ec,dfa10a2e,7c7a5405,119dc8db,de839140,2e063e13) +,S(6d1b5784,f58e5393,fec90c50,a674278a,cb841f46,97da9eda,12013447,a2e0b863,d052c806,2905ef3f,6302892f,48b20497,e89cf7d4,3c345ba5,94233cf8,2586a17a) +,S(94eef4c8,be627560,17e13634,53f733a7,fd590dc1,294cefb6,4d8965fb,3d2ed1d7,49a1e5e4,d72e6a21,14e7c4d0,eb9c9240,b3b988d3,21d2999b,46a562e6,1a203c97) +,S(3206fc87,582d1267,92c2a68a,7400a29f,61097fdd,3ecf4cda,fe495993,87ec15f7,c9a7af2b,88df18f4,fe453bf,fc4af355,519fdf21,9251bf6f,879f291c,32a38eb2) +,S(fcd215,45f8a36a,a5a81bd7,1fb1804d,b3fa112c,c21542de,27cd34e7,f7309a1,191c6b9a,42b0adda,bacffaa9,89bbebea,3424a3bf,11345ff5,2af9c3fb,6193ad0) +,S(4432309a,40f6c71f,cb7fbe26,d6390778,fe6f816,3ee50264,2b2027c4,86fee04b,550981ec,b4d2f6df,fd25f26e,6d65f62e,5e549c1d,79639c4c,d07b6282,2d075847) +,S(7cbff748,7bed64ba,7d6346f9,18e23992,a3712ed,1b7cb89d,a6c0540a,335b582a,ddf155a2,bfb25607,ee6bca12,f6df2a01,98513445,9b353c60,9806fbbe,2d9fbdef) +,S(f8cd164b,ad3e65e3,63368645,76c49035,a95f7928,350c855c,fa534f6,80709789,25412c86,23bca2e9,8d5531ee,d57c80c3,ab01abfc,498cbef3,deeff0e,ae6912a) +,S(6fad2644,990a231f,c27bd678,36ff84c0,11fdec01,120dcc0d,f114b032,1d60648d,6beaeb65,ddd28481,a23af85a,5a417323,350d057e,1a574b0f,5d994816,844d9d98) +,S(1fbf086e,d0adb5d1,9c49947f,d019046b,289c5703,1cf876d0,8cba81e3,7739dd6,86e3511,3d4593f7,a8142c45,8e915fcd,685efd0b,f8cca8a0,79ebded3,f4453acc) +,S(30cc2cab,fd0a2244,2c8a6e00,5b6220e5,4061dbb1,4f8ceabb,6215bce,f5f5b312,b5a1f70d,4a05fff9,9716ac44,57a4342e,7d4bdef2,6cd07fee,b515c56b,19fe72b2) +,S(156efdd1,901ebad9,70eb167a,bb99ac5c,676a0929,3feb0b37,8ba19ba3,6c2a3935,b1d39453,32f0e107,15d06df2,d784b1c3,bac221a7,f184bfe2,4824a368,9ff33051) +,S(48682e29,6b8e8123,c9fb6246,5e8480d5,54350734,bc763757,f319d40c,87f2ddfe,efa5e5e2,be832508,e71b15f5,3a7f1d77,773129e2,e57b2b86,9545cfc9,a20360f8) +,S(d188747c,968b67b1,88958f37,b9990bb3,1a54e3d3,e3fe9e06,7aa9b1a0,87f5e3d4,6d60a049,25660c21,81efbbd5,6a436409,6bbdfa39,b37f70e6,4d13f3ca,6bc76b92) +,S(d7cfeac2,7fdb5922,a5f534c2,b1d325a2,903217f2,ff41b6ea,1e5d2264,8095d3,19618c66,87bb0d92,52133c84,26fb8aa6,4fe1355c,86aaea97,b9ef49fb,de063e75) +,S(dd795951,27b0ff86,94dd131c,e85ca6ef,9aa2022d,d0c7f053,4c83735c,43096c02,caeb4cdc,2633b01f,1b51f7e6,103ede8c,a0ccef5d,e33a8ece,5ddfba8f,736e2adc) +,S(5b2bf207,9a319707,52496851,68aad1e9,5582408,7e5d361e,87b77900,d9c63939,728df41e,69c939fb,59803668,6c44d0b6,f102dc4d,ee146a33,42e1c04c,9b6e30cc) +,S(d2a26a5c,313aef0d,6ac190cb,11c84771,abf97d8e,c7e6e67,bd3313fd,15c2ba11,84a1fb57,1507d012,9d98ebf5,34fac803,5de7a43e,48868269,d5e9656a,773fe768) +,S(22c22c99,860b2b6c,630487f2,5263e77,91b62450,290e9df,379efa7,1edadb52,d2b227b3,dc85c1a1,ed64a7e5,6dd6b178,ce0ab5e,68647b50,1178ac78,4b7d1c93) +,S(b811b039,d2cf5f3b,95e38e2e,14da67bc,417cfd8,623593ee,1f2e924f,d9a064c4,a860653d,ca39030e,8c1ed7bf,aeab73f2,a68cb8a0,5263aaf2,431b6f8d,9c862a28) +,S(59ee23c9,26b38d6d,d6c091a1,d4adcdca,b3a5a548,a5cdaf92,fee9fe2b,c3cc2957,67462318,96e4f107,67e39d47,b03268af,5b54edb0,9f9e8e0c,3f3f89a3,e9d204cb) +,S(cc79ede7,ca5a9ba5,a7c5114,d2039d5e,c6a54db8,fee6c102,577a20d9,18ba857a,2cdc980,3a06af30,c19b262a,12f54132,933ec985,afbd1598,45c40be3,2e24861a) +,S(1319c7a6,2f3959b4,cfee1223,b225c6e9,9070753,a1ad33d8,8f3a8b78,a886f7da,d8a75f9d,b8266ea4,2b650265,6b6c0ee9,7f3598d6,3d149ad6,9a5829e2,f3c29085) +,S(e4ae90fd,74e9b229,b9100cef,1da59b80,753b4f0a,cd7790f6,34930a92,b1eea356,370f1c98,f72e698,73c8d0a4,e76fb117,d7e5a9a4,d13521f,f4902a1b,ed3688e5) +,S(286a98b7,b0b0527c,310afd37,717b5061,467be24f,8a0b5528,52ff26ee,d658988b,d10699be,f79e800a,519b964a,163cffb9,722c3ba5,b56694a5,c1a9b883,b32965d8) +,S(9b8544b3,79746ba1,8524e084,2d15b853,46577b81,7084e02f,7d0cb820,7448f5d6,8421c0f2,ba15f648,246f9cb7,3b10d6db,1de7aefb,fafd9b52,16234dab,8e70218e) +,S(81efaf7b,50a18c8c,2481299,bbd2adba,f3510ac4,f871c3c0,f849ef6d,4550681a,ea8567a2,9c871ba7,fccea923,fe07e8ba,2071d7db,25d33ce7,a6125c0c,2afacd17) +,S(6680fbdb,dab850c9,115d5765,344f1466,b88cc5dc,8de9fab,549f281e,974ed7b,c7871b4b,2690f4ad,1e67ea81,e2cefac2,988082d8,b1c70e67,4389c79a,bc880368) +,S(4c38ce7b,a8e3d317,6f615d6e,27578edc,746fb80e,4701efae,f7557469,a1dce4bc,f6e73d73,61ff5407,10dc9f1a,4bd5c1eb,a7d8c8d6,45f0427e,a4fc3e45,3990b88c) +,S(767146d6,bc1d5bb9,c73321b5,4cf6bc61,e8209703,fe4dddf7,2b3d6089,da60be69,86df7dc3,6894f88e,fe24a4ee,fc78b1e0,fbb5138d,31666be7,97b8934f,d0b9a37) +,S(bffd4856,360c02ac,ee741a65,486d5a7,44e2a005,9db5ef5f,f87b9e18,3adbed20,c11246aa,3bd4ec3f,71f88d2,cb3b96ba,2c210f90,d8234c21,99bf7781,f96ad781) +,S(ad19b5f7,45556650,eb496450,968d056a,fbcb55b6,8852f510,ac96df54,cdc677c0,f78295f8,59445c52,d6ea285,3fe9baa0,5e453bf0,9b3f4d28,6c99e858,62a04bbe) +,S(5924f679,bb94f6db,d8232b01,ca8dfbcb,37a83d24,d0e7026f,b526162d,c82aaac7,baee6567,6a526460,ec7563ad,42482d37,a42f2fcb,f4a5eb7,b37b515,a6c3f1b9) +,S(dee240ea,c90d5399,89d3b3f5,764e0680,1e601a4d,f2c09226,21eb0b7f,bb53ccc6,12668b,72cc139f,5f9fff4c,ef24b5ec,d0648e03,64c17417,f35bfca8,b819316a) +,S(e288a00b,e18b0987,9765940e,caf8972b,1a09f67b,fdc455c8,8e3b4ed9,dc0dad81,fd81e0a5,adf1df8f,42c64825,6b107d44,887d01da,f4cf89c9,11529124,16a1e4e0) +,S(e747d6c7,3f5366ed,241501a0,ca6dc04a,aca7241d,8effbd94,7d3e6a0d,bb6eadb,9954822b,15f44840,9c9e73d,97722194,1eb6a218,ef1ef4f,269ab118,8f9c773c) +,S(57b8865b,ac78b9a1,c244452e,8057be3b,4fe2c6de,9ca9a295,ded04377,2b61aefa,d0e46172,8828f0d3,f1fa808b,1dea8516,b0c30d93,4acc8c90,6ca2bcad,303f06b7) +,S(abda4b38,47ed5cee,7ace4e8e,e652336f,26a8f4bf,4bd610f6,e87e5936,e4e8339b,8860963b,8f266c30,9c6a00c6,cdb44048,a9a1b76,d0a5a652,b4453f7d,330bdd9f) +,S(7f05f2d9,5621d06a,d344bf91,7fa8b9c4,2ceafa3d,fabd0620,bf7086fd,9539e089,298ec6d,8d5a9506,8d916678,dc8e62b3,7b6fb9ef,7967da8a,8419433f,79922f29) +,S(99e4f06b,b8845bb2,12638573,63f7cfbf,3f15570,44256dab,21b5a8fb,c43e2453,5d76066a,86d5c498,323af928,2c3bf419,acb758c9,7883d236,7d9d9e3f,eb8e1417) +,S(ff994b1f,6447ae81,8bbbf97b,8b6d655d,900b04ad,eec06fc1,f57eab70,95375094,6a63980d,3a9324a1,9339a073,977130de,d0fddc50,5b86ff73,464dae04,c3004a68) +,S(3e9af52,f00d1993,8b6205dc,7b6f8ef3,31d624da,fdb2f09d,fd701b78,ed8b0471,a674914c,ac86037b,f0585de4,d867424a,ab9841dc,83c0ca8f,347e16dc,1407167f) +,S(eece935a,e5cd4afe,baca6998,63c5e8c2,e0b338a3,e2ae7dbf,e34102f6,f1c613f8,be70c210,b925dc66,c8546e65,ae9600b4,21a9f668,c3a09a01,8bc5b88b,91cf4d74) +,S(bf10e625,7d336eb4,a962bd97,4cbd9f10,76787b8b,90575250,7f0cfc2e,121d1276,1d93f629,8ddbce2f,1f670326,265c4ba0,f7f5256b,472412f7,a24f999e,f4e1c64c) +,S(73e43284,c80d4ea5,c992ffe3,cdce4149,d490843e,bbac444b,f47ed5a7,3d6e0bb4,82cab83b,c7d2d2bc,87881618,54034d7b,dab132b0,6340b316,964854b7,f2ee3e6b) +,S(5410340,b614b676,63173725,ecf0b8e1,67c2de61,ce999639,be2051dd,2695f8b8,f191ec95,9d6fd8f4,eca243b7,8d844214,976d97e0,65218487,3366ca25,f2e6a091) +,S(203d28e2,694df7a5,6c9b9d42,907c1e02,192e8030,77ead781,8198b2a9,69b127fe,c06fb7ff,2361ac16,a884f0a7,9e4f5a19,b0b5b207,9901e634,be237643,ba93852c) +,S(f9a1e3dd,f53e41b8,84f7c4e2,c2b47131,8d14705a,4e7362df,3221222e,6b2c1921,cd150a1a,abe8ea0d,853245eb,509c1d4f,e26c54b6,98cf9aad,26849a7d,e63b6264) +,S(e82e5e89,db35aedd,4d63b7e,4d55d637,cd2eafcf,f16ffbd5,b0fd1444,c7c783bb,6701a95d,ccae2272,2a834957,e0a4a3b8,3cf5ff19,2f41e8,1619dc46,b8238cda) +,S(9fb768b7,16032fd7,f21315b7,79776882,767d5d64,c9141267,a0ddedb1,55d4ae08,13474a8f,90fda6a3,43e3ea23,e858327,dc2f4c40,4a445f77,4b39b92d,a312574a) +,S(d0793463,ca7cdb50,3622f1cf,90032794,52af3fa8,1866e536,159fd23e,ba6082d7,35301f6b,66858d6a,3e97480b,ec3d2a53,8dee8465,ff5c15a9,1144ede,a208bd0c) +,S(cf8fc191,273383df,f1d703f7,bb237ea6,cb5d1307,8ce8ae62,67fd20da,4d845e05,efce641,3bb676e5,5c0b64d7,589ad771,23900e0d,60feb71f,93270390,ec66ecc1) +,S(f12aeec7,55a7138e,4e91024a,3006db3d,eff6ec84,ffa73d96,da21ef00,452064fd,f0f0660a,22cd7cda,25206f10,e82ca005,3a40d539,472cf41c,b86ed8ae,3d29abd9) +,S(3c40f94d,ab460ccf,c8e47a1e,d015b074,ebfb6142,fbbf5b4d,e77aca70,be67c57a,998efa4e,26df60a6,f1a466f4,c27b2dce,ce6367b2,e05a5ad9,dd71ed8b,482ce55c) +,S(f2fc6db0,49861d3c,a01a6778,22299264,88184967,3802ed49,503857d2,2860f00c,79f0f245,1cc6c5b8,d36c330a,ef8c9c84,95619911,1d4a01a3,d9363382,8b609576) +,S(35d3e3c0,29fdc9e3,88da1cf3,d52df6bd,9ac0ec9e,e591adde,26d3e414,f4fb92f5,62ba2346,6d19ec1b,64d2a6cc,9822feb8,e03df178,3f526a9a,13d10fa7,72de3219) +,S(5628da0b,cc2c0583,902a56ae,711a2217,455bba47,c7222dfe,d60580c6,461b4ae3,1cee8f17,8ce4c7f9,8cf2a2c5,92bf39aa,57616913,bb66f232,a813904e,7b574ed9) +,S(7ec54044,c3fe53ac,8437a540,968e0b,b725e794,a8c240c6,5dac1f12,4ce21be3,f6290891,af9af62d,5dfe10b,d567af1d,6b4b22f2,8177a14b,44edcd0a,be811c0d) +,S(eef7a7c2,a0224a78,aff7c61b,d2379259,7b307a20,bf1c253d,6f03d57f,a8a84203,5c7d6875,905e26dd,2fa4e5,24f73b00,6f4bd0b6,786639af,5d222411,bf69daf0) +,S(3f1e6459,38e4285d,ed30be98,1d149f68,24b264c7,df920f0c,c5d776df,83228cc3,a6a5df53,856be619,25e42d58,2f705567,39c3d7c7,a6e222b8,6385b63e,d1316916) +,S(c83ff186,ae3f42d5,a2c39b43,7712d607,92b9006a,d8bbcc89,97bb9b35,d1663cc6,2380aa52,44674eae,3d96d65,f484e7a7,62cbfa10,96c5a313,9eb4628e,77b72d40) +,S(41d20761,160125ae,c669b1cd,395110bc,94e09a,ffb52ef4,e7e86e,1f4a61a5,c8509f71,2c20aeef,7399d11e,7c438d0e,9b4dec72,76c1013e,a4c76d31,ee5c7496) +,S(cd358f38,d2cb11f2,9fb54431,dc5adee6,721c444a,8fab5743,1149e504,8ba0dab8,e6ab91a8,79a51f40,cf75e405,e508cad8,ec54dbd8,2dd4115c,fda7b255,b1a6fe1b) +,S(d1e1851d,cc95a94c,a8c77b42,5b4430a1,ac10e526,e3f4c6dc,f20267dd,7c5f2d2f,889de789,43c6674e,6bf28470,3ef8867c,8d827681,d2df8bd7,75384ad7,15730ecb) +,S(89268637,1febc520,14709cc6,b2aeb5dc,32e06b14,cdae3d76,b1bc04e7,b9b5dc8e,46823e42,9c0815e,ff99cd7d,f3712f78,9c102af,173b61f,8de08519,f19a3783) +,S(c7341942,420d4e63,263a144c,8a10d22a,fecb1bef,64f926a7,83951e0f,6490caee,925019a5,212e9de7,2e6e2336,c3e2aa75,9511396c,a171412b,53c8f9ff,3743dcd2) +,S(fdede5f,38d83f9f,a4ba3218,fac6f0aa,7c9f464e,33dc59f9,8a3444e,fc0ed7e7,26e4cd3f,3dcd6a6a,211bc8d0,65564250,49c6db2e,9946dcaf,43cb42f3,b0f20449) +,S(b2b5364a,eaedfe4c,f046193a,6777ec1a,1841436e,3cb17c34,9d27f42e,8e536618,32b886d0,f0f94a7f,1b1d87e7,4f2c7dcb,ba4a5dde,8e93c864,f8f48bb4,50d08ffa) +,S(4c3693f4,52a95b79,85e39982,f316897,93d289cf,66b3326f,3e1cc77e,457f64bc,48d7bdfe,fb8c3abb,584db0b,d3407ed3,3e543715,d4ede995,df0e1b8,52e12123) +,S(5cea23d4,927f0385,57f6bc1f,b926e594,93250b3d,6d934a16,9265ae08,24a35e60,5806886e,b01ca724,8434f2f8,be33287b,d9cb3c3e,b927bc4b,4fefbd51,ba98b5b6) +,S(db0a50f6,b4558c10,61a3ff88,1da60f9a,77b42469,a9713c8f,8339b8a7,b903d93,7afa6cd2,57685f49,9635d15c,bb7defac,d6f94c17,aa19be02,4e2efc70,d84c45be) +,S(b0029adb,25f32b75,8023ced1,632de91b,3e3e55a6,1abb56d5,aada032,f2c01ab5,baadabe2,2ebc5fc6,d5dee65b,262e96c,63c99fc9,13277d84,9ec8a730,e1bbfe91) +,S(c336b077,3ce16975,bc204169,8126a40e,f8cad886,6a52c50,c5081ba7,b878af5,6f46f5e7,b82aec01,ad499340,fb90b81,420b4a3f,977579af,d3eb0ce9,c7d752bb) +,S(f403fde4,7232a9db,9efda1c0,5df49636,2137f5c,aacdfc93,1346dacb,d2501451,ba30815c,197de8f2,258c83d8,dd7ed0cc,cbb5388a,415b8629,2cf5c271,2e75bcbf) +,S(85cd71a2,20beec1,3edd0133,6b0b85e2,da056a1c,4a48a328,f371af1a,ee502c30,d6accbba,491c915e,88474b92,bf23c740,2648085f,88a62d51,b26954b3,f6d2d4c6) +,S(324d65,b3c2bc55,d3b2a125,1b673ecc,d26d2b23,e333849b,7549339f,7f0d9a42,83750e95,32086164,e9aaec58,b6a2f00a,3838d76a,208d6453,14042334,b4af616a) +,S(322033a5,c90d7a31,9439c368,b1301f1b,d088974c,91560063,793b6f2,63b401f3,a61f4714,488bd2bc,84bdb122,c615ac94,a7d05157,e6d961df,4f873f5a,582e4606) +,S(a414ed01,691f2a43,b18dbda2,2d3d009f,f94f8b02,672e49f0,58dc2323,b71f5836,2fa3e483,a12ba874,12d709a9,47cdf22,6b96523a,ac7f4afe,c93f98be,f97ec01f) +,S(774310b1,7752d7bc,d8b3059,f7f4cac9,e661a841,9dcb20fe,355bc7be,3a4c65e9,b3333227,469ec87f,19e14e3c,98148b4b,45bde0f6,698829e9,3bbc9313,56e18b12) +,S(fbb23c7b,5c15bbcc,7ad0118b,6826e385,3f6c4078,5342ea57,11109f8a,27dd11e,b12ec70c,9b4c908e,2538f4c6,b0b3d548,ee199f9a,1e9b6535,f1c78081,41664ad5) +,S(4bf836d7,fa7308c,89b075df,1f336fc8,af3c6ce0,64e1253f,853f623d,c483b400,8b368da,424e5a83,48cfe987,93d47a1e,1e9bbeb7,3f5282af,82e12e4a,c7eac850) +,S(91b4a84a,e521232d,71e3d202,49dd1b3b,d134509f,e3e1ed1a,4e8b5062,a438bdd2,52d30545,4972471e,6900afbe,2471e1c9,16c82ce2,2f955ab8,454f9b65,b70ed759) +,S(9751092f,62147caf,f3953cf4,8a117082,37a78b6,5bf0de56,848da1e9,4c3c3a42,57fd0a15,fe069db5,5fbe870c,96d4280,7b9ebd87,33908bd7,49ba0121,a900b08e) +,S(54439284,6f6d46c9,8ac10a58,ac3c34b7,3cc5569f,8f9fd7f3,4e7ad2be,826bf293,1aff0b85,e5b9033d,7c44e877,57513317,a17734d1,13043cd0,780da032,2dc3ed03) +,S(172704b7,fd7f5560,f17cb6ff,ff9a0144,9a05a113,29b86df0,a8d3256,ce139a9f,a416c0af,b170cdfe,169f894a,b10aa97f,2c068a4f,d70a6878,ec9f359f,e8323bea) +,S(2236799a,a82d4b64,5f412aef,eae944b5,e28e0996,8a243ce5,b8986861,6f735dfb,7f20b2cd,af70cbdc,6aeec02a,dae1535d,4bd919c2,631ed69b,9913771c,2f482c1) +,S(6a52af7f,c6f75636,c33047b8,9f0eec31,66bd97d,8df6579d,2e2a441,6ec4fe8b,4eb0813d,220849bc,e0b948e9,a6efcafd,339f8861,eacb9885,40ff8e1,acf1efdb) +,S(8696e0b4,ae3f0dea,bf6d8dd3,854faa5d,d07b01a8,86f710ad,9b4cd84a,5d61a617,67633be1,a662024f,77931f06,38884175,d2c234cd,c4709637,4711c79f,42a897df) +,S(6c4b727e,3bf9af50,fcae1ed6,163ecb00,142d9a53,b6d3f54c,8aa14064,1358ce7e,c4f2665f,395af262,b30561d1,48bb0f4a,f5603102,80f57f40,1506ec37,2bde79a3) +,S(a51d2296,98aa29a9,6d0e5510,f3e815f9,cfc6d492,dd0b2fd5,bbfdefa4,984a6934,861f0848,7658d4a0,141e9d38,aa0e268f,40bad7c9,e2615a37,7a4b974a,6828d525) +,S(1afc4051,cfb5635f,9c2a8477,7dee5fd9,fc4d40a8,3ebe2f89,f36c0b9d,8327288,61ac4eb9,16567e13,d1b03ae7,ad5c3d8d,ef85bf6f,387c511e,bba6c237,96e95f7a) +,S(f8fcde05,5a2a92de,c65d1842,6607a939,b3475abe,2437c5d3,88387fd4,afdff590,4cb8f7e2,825625ba,e3f179bd,4ef94560,6e186346,61edbf48,8ce51ea8,ce1b0404) +,S(cb3dad82,7e7464cb,5fed0cbf,7e29e6ec,112ea411,706d10e5,c1fe6fbc,a04a3e9,a33abaa7,6c9afe3a,a8ce5add,7a2a056,b396cdda,2a002161,3de97556,a0364629) +,S(39d2cea0,acf8059b,a6275a08,ec3a3664,f09cfc43,f143c317,bed8d751,33d4ba0d,6beb4ca3,d3009ac8,881d6d15,e0a29eda,6738befe,e31707d7,f95eacc5,fbd77192) +,S(90bfc4da,3be2d74b,ff9b5539,d0787bf4,4a1b6d7c,2baa14a1,dc6801d4,42187f96,1254e7ee,c8acb35c,fa0695c5,85f61b69,def3ef5a,6219fa97,e3b09dbb,351152f) +,S(50772bcd,454ae992,f97ac3f8,9d8193d5,ed50b69a,b2e62e04,d6a115a6,6e71c977,f199a8f6,f78b0b97,cc20316f,66177383,64338fda,3eee7f0,f36eb0ff,64accdcc) +,S(afe51284,f033bb43,ac6feaea,9520e83e,f2cc1e42,9e273bc3,1b087161,52ea6926,77ecc481,9ffe6efd,33592907,17d22ceb,f4344c9d,f5f5ea4e,4d443d17,25c8aa1e) +,S(b0caf67c,151b838e,4ecaee09,c7908c95,bd3ef86c,797a5a8d,71cb3bf0,3a46ab17,10ae756,7bd2f6d6,712c448b,34636eea,2c7c3d99,98901308,14825b4e,423284bb) +,S(f2766b4,8cac8f6a,80a7cf39,81725834,d186e88d,735fc7f1,5135ce58,43b3dc8c,63590fcc,a4e21c39,50cd78a0,569c0d2e,959254e1,4bf2ff22,8d8fb216,b53601bb) +,S(80d50e7d,28269280,f8ce0dd3,6afb9f43,38df0403,d5661c99,27ff817a,46f60a0e,22fec5b9,7472824a,9b2ff25a,68d947a5,a8952ae,b763f37f,70228978,514cd22) +,S(18114ad0,7097b5f3,7d788165,e45ca1b8,462da0b5,78e5d37b,e4be3632,35d2fff6,87c5f261,39cb366f,25fb6bfa,fcc8408b,f4c69c81,29df3cfe,9190213f,8c15a66f) +,S(3bd52737,68294cd8,73a48831,8f958e45,85871165,c82cf6a3,9126e378,43975444,8c92d391,e39a50f3,4388510f,c8dbb686,27f29251,92ae8edb,b2613948,c01281ac) +,S(acf47eeb,526208ba,8a3de26e,481a86ac,f17f5f88,81d89d43,ab8a5a26,e00db5a5,b451b4cc,8be8339e,4203c913,98b9a29e,de86a91d,3e347688,53442446,429ace0a) +,S(5e39f375,87a07536,86bcd792,1183c424,20159044,a9f66ecc,2bdd552c,62ec35c2,b7131328,297c6995,7df6783b,d9bc550d,5c553e1,30bfc3e,fffedbd7,5e2d003b) +,S(315b67c3,d980796f,6f0a5505,ff2d25f2,8551615d,12bd73de,b10c4897,580371ba,dfaf812f,7525e087,2d11e10d,612004cb,3e2a7024,8c40416e,5020ef66,82d3bc1f) +,S(8f6764f7,73810396,62537cc5,aed6a8e0,318654cd,a95d8695,89fa471a,edd0d7a0,b91cf5db,2994d207,135c1dbf,b9d9d78f,7e3adea5,8c176630,c09140b7,f5c67e84) +,S(e844b948,118fc6a7,eb2f96e,ece3cab6,def55940,75c7b7af,fcc5603,f2012f96,707668d8,89db03d1,561596da,a831aa92,771a0fb9,e1b21273,d11a3415,82292314) +,S(fbbedfd8,4144785e,fa71e234,59973cb8,87deda88,971eb62a,3007f350,1fd0ae4e,51d23941,cf84f121,ff1e6a5d,651d9528,6ef1d803,819ce64,3aba8d16,67ba7dd9) +,S(a0190399,c692b9a,db172ba8,348b404f,19442b60,4df60142,f6330f36,ca6bf352,6ce7491a,b5329042,25556069,71502da1,601e3a04,f38601d0,80b31654,20fb527f) +,S(d240e135,4b9e6dc9,110a6b25,afcf35e0,74fb02fa,f3dbe484,4f46818a,89bca65a,d704be81,e2597460,6014ffcc,ef12563b,45faf24,3e070727,64f341b8,7dfcdb7d) +,S(39bd84aa,f8a15b0b,809888f,133871f3,c40ea5f,2825582,a35fa9a7,808e5e87,94ad6588,658752fc,ce45ea1b,752ecd02,2b621c5a,26908cf8,69c44584,1d831d33) +,S(2172be6e,dccfd021,a56a553e,53f814c7,c7cdd55f,d181d671,4ade45e7,72093142,b21439df,f7229e61,cd3b7c77,fa750a94,660f60a7,53da96ba,d8ca7e20,69abf76d) +,S(57db209d,a40f30ae,fcca7838,2ba525e2,231343b9,250a1b1f,67fad7f4,d4079594,34ce9bac,bd35557e,2f73c718,4287b493,c524a3a,d6b403f4,ae777026,42fd37e3) +,S(845c2bc3,3683d899,8b90a2d5,ff299064,5214b272,a056ed93,63621406,d3a4cc11,44a46738,839b2e3e,1b6b19bc,56a1ff06,7754126b,20654e51,3a1f13c6,de4c6535) +,S(705af30b,251cc64a,26edc929,e3e9ff3e,32ada2e,69c2cfd0,eefce4cb,a37329d1,c0e693eb,94c0c1f6,cf1a0ed4,8c9b13ae,faba8ebd,926c4fe3,ec9071be,2db463dc) +,S(9b2a64df,9b1f8e,34844e3d,920b1af3,14df1b7,78b863d6,f1a6b94a,869061be,5ff03134,722faad1,ab6f87f0,bc3c6abe,8406bdf3,6506b662,6d066ce1,fa6a7cf7) +,S(494967f0,1a0c07df,e7d9a8b3,e6a4ad13,893a894c,2619238,7384e38a,d514cff3,11ba0803,72bc4ffe,b86e25c8,b69ea450,5f6e3b24,504b5e38,210beff8,5d82e1af) +,S(fd547247,812e4233,55c4a977,4dfecfae,812ef2f8,f3fd832d,a3af2ac9,257d50a4,65ed23c4,d776baf4,53faf3d,d3edf65a,5d9935ef,9e22fef2,53319e22,ca4bf51) +,S(4aa16ea2,68ae95b3,2f405fd9,6fa78478,7c369015,4c124733,a07c1953,874b6246,4306725f,579fc013,2cb8c640,7361c7c4,685a2a49,532fa14a,36010779,7f5104e7) +,S(de6fdd33,8b6eaad1,bec84d55,992a5b74,aaca294a,5f804015,796d69c2,cfe67add,e58564e9,d2cc10e7,184d65b1,7e0271a7,f2e59073,bdca05f,ae664f82,7e6fba13) +,S(c8290adf,d0da5f1d,1805f36f,288a8709,eae0b93b,1a7490da,5ffc29fa,bf834592,ff161787,f096e022,f513afc4,e0b84d73,e7f9f347,798e1026,931271b0,8f1c8a87) +,S(1b95c512,815603a6,19750d6e,463d5a33,55f09c22,56484ae9,8f1c76c1,10ed8fec,93b3750c,3a1272d8,bc9e4c52,b5efb6bc,d794c2c3,939bbea6,1848c9ed,423bb39b) +,S(ac0d9939,104bbaf4,d2eb2560,356f2bd4,f1037ee8,397f0703,b7ebfb49,463a22e3,c6e6d039,d6acc470,c1ee1013,722c4a00,4c59e472,11da3025,49351216,f0bb8985) +,S(d8c8f5b6,366c1d29,b2f28f53,8645b17c,f001ae59,71a19f05,fb6ebb3e,9e36faec,5db24ba,6d78e76b,42262b65,e631390c,8540b72a,746cc5b,edc1b681,8b1a113b) +,S(d42ccf6e,6d1c663a,3dd95fd3,c016d535,c50e394,fd63b353,2949716c,49315737,e7337f22,2d353eda,651087c5,13cfea43,96e9cc5e,22aefb4a,5fb3ea8b,579c7298) +,S(53417fa2,4871adb7,6d875c05,8c46065,681f6372,95d221db,ea76d88d,f687b817,d014e6ea,e00c4ec8,ad931dd2,5cf569d2,efb3068f,7aaf5ded,d4978546,1bb31d76) +,S(202e9476,53b677a8,d7aca305,c52af8b9,d33b1ec4,c5ec94fc,5f7775aa,c478f150,539a24fb,211da532,b378f3e5,cdd688b5,c57343c8,2e03a637,39544c8b,34e3087f) +,S(434f1027,72aa0555,8bcb2f6b,1f64bc8d,72bf1bb2,8b972c3a,f6f342d5,f1493f93,a9db9031,f2d1b8b0,e5840fc2,b4534970,90aee2af,5bbd83d2,c14a5ad8,acbf8c14) +,S(a0e54d1a,f09c47f7,cf56d3a5,725d6777,9fdf920d,3c1dd566,caf71666,de7d5d17,87f5db7f,197185b4,73cfc293,7b0661ce,1ea92099,fbb51151,63c2b26d,47ba97f0) +,S(2d43cada,5455b682,f6430cbd,96a2e316,ac0b4b27,e9fb8777,a94dd2c5,81c0e350,bcf18180,1c1722db,1bd9b8f1,8a1989c0,fb372acf,fecbf9f2,c37ec4b3,b459c916) +,S(e5e6dd12,6340f04,431552e9,903ff4a3,c309ea1e,c498e483,e19b9cc1,37418d4d,58d35fe2,24ab47d,93cd53,fba32252,4a3ea9b6,d96390df,25935a1b,dd12126e) +,S(b112e4d3,ff9adc6f,706cac35,195843cf,302324e5,6aa7305,9c8b5f3a,6dd7dbc7,4fe76714,6529e6f6,b0379366,334595be,efcc7cde,d3596ed8,83e3b30e,780dbccc) +,S(d26b5261,ca7be739,95de1bd4,d75991ef,4d357fa2,5c8d513a,e209ac6f,64ad960,5f3b8e07,74e78bb7,5c395bcc,8512f2c0,1b6c451b,5c8d6ff4,18f9ef35,30c6d046) +,S(e2e4f568,eaf2807e,cf43ce08,3146e961,92271bb8,d6d9b24c,e7315b00,1cf04fbd,56894a02,58093a34,22f2ad5e,548158fa,c55ce47e,d00ede05,40434424,4e204b93) +,S(a62080a4,2d8aa307,32255b2b,a239d9fc,19729eec,1dc24bca,67652705,9b1182cb,ae848a12,893c34f2,260c33c8,ce2bcb7,14fb1438,8e6f3f06,d9192549,6a9ec13e) +,S(684c1647,7771de55,ddea8aec,290c1e25,65120fcb,fc8ce0db,4316dde3,f5ae8d91,ba85dda9,44dcfdf8,cfca86dc,ba902675,3d99e751,5719e579,64e0fa0c,3be1f06) +,S(3d730e7a,afa97950,bee35934,da18648c,d0bd62e6,9a49281c,b63589d0,5efbd2fd,c28545f2,3dceca1a,ad0a9c77,23b61519,44a3c984,d57517a7,cf6702ce,f4dbb630) +,S(337c9584,b49a49d9,29b1212d,dee7ecb6,39f007b8,9ba94180,80c9548,459c48b7,b26db317,3e996893,fe1e0797,f75cd05a,2eb23ddf,4806407e,1f173d29,48bb0bde) +,S(7013edd6,f49ba92f,9c9757d1,d3374229,706078df,c2e9c64c,c2e84cbe,85c6b5b7,e850419,7975353b,2863b577,d6f0c392,a8c5bdb4,2dd557e9,8e971114,5e078de4) +,S(9877cf36,bde592fb,5f4a4581,2bc3c39c,68ac9956,23b3487a,635d6e45,89e26e1c,6207d384,737a0d80,fa9f42e0,57684584,efe1fa4,5cd73eb7,bd50abc3,2722f159) +,S(6d35bf57,1c91a2ca,1765ed62,f9b2f680,cbd0955,bc76332c,c83a7378,4bf3eafd,47a589b5,15a88d78,6f94f64d,674182e9,7dd12450,ab3ec375,a9a31d8a,375e5f7d) +,S(40ebcc0f,be3a2a59,968bf6cb,4d638873,5468b532,80a9c96b,639dede3,171db2b8,c2181816,ab9f0d72,c5cb167c,5bbf7e57,9f17d7f4,484996e6,3a23e0dd,5f5d3a8f) +,S(90de4b6c,3a5ccf14,cb033478,577461af,8c347731,9857ff40,79e6ef27,5e557b87,c534bd97,a4af903b,f307c1ce,549a9976,70edb69b,c76ae827,f277ffe8,133cf394) +,S(54e89b59,b73c76b6,cac52433,305c41b6,8f50df66,9b99f47f,599504ee,93ddb110,d307e828,1e89cba4,86ac125c,1c5d8bc,943394ee,222b4b06,f4e3e5c7,b5da176b) +,S(f2ef67ad,60858ac9,fb03ad25,f75f85e2,e5ac151d,95c96967,93ca080,58756f2d,92c0dfa9,372e1e7b,7363f229,2776c059,56742f60,7b100be3,56dffefb,bcda8cf0) +,S(65b7d935,a71dcb6d,eac70b64,91b9fc50,35c63f21,655a856b,afd00a33,52f5be39,b0773657,cbdd3813,8f50813c,558ddbe0,3f8ad81d,e420401f,175bade7,1429927d) +,S(6e950ff,6471cf66,72ea542f,cf05aea8,2c2e1e0a,c2247021,4c78895e,e291ee22,c0ca0886,f0ac828e,21a5c60,776494fc,a6f19e71,741de92e,c11323e7,e874788) +,S(c3b15f8f,96c0079b,471896ac,89d7d11,8ea1607f,18a20627,fb18e1ff,24ee3c1b,33a033c6,68e3cff6,414835a6,ae3f89f6,643326cc,7e149f56,99ab4fbe,d5f506b9) +,S(9e333d9e,1c022776,da901c19,e6936c3c,1af45491,a93e9405,ae343c54,775f36b4,c6734e91,3d013610,6c77a1d3,ced1babb,a6c6723e,316c3fd,34a7911f,cef616d7) +,S(398d2109,4c0baf8a,ab63ceb,6aa6b64c,678bbe86,f7e01b3b,8c0ff291,450244bd,f1ffb185,112ee219,24a1702,183f9075,471611e9,54fafb4e,36f6acc8,4ac7acf7) +,S(8f99c7d,553ca4ea,b160a07b,6d457058,90634086,80c709c,530aef44,bce43c8a,52a15e23,2e90d233,211d707d,5849e214,1f56e8d,189783ab,3c09f37d,b86a776c) +,S(8d798338,b2774399,487fe227,e2d883c8,39698301,5f01bf00,d154f4f9,296512a9,7cb53de9,9303a6be,9aee01eb,3a5c115d,eff0e18b,2cb5e852,75e9b7ff,53e35666) +,S(c9d6aa,ff6b648d,69416bfc,6e4688c5,cf13b711,29c785e7,3ad1e04f,ba02be57,9fa83446,5405aa0f,332a6aa1,922e3fcb,90de108a,db01796d,9045d423,ca0c2632) +,S(f736cad3,f1264671,f2e79bc9,c21551c4,aaa5da0f,befc1928,b9e7fab1,f59c8c5c,2ceae81d,16206893,b3810abf,d2aedb5c,55b79222,1346cc9c,908346e7,cd3e661a) +,S(7748965,7c1fcd79,60fa4a8,36feef6d,835f960a,d3b85009,7462a71e,8320a34d,cfacdaa1,2906f705,d83212b1,55475160,e02cde20,71fc5c9f,6a6d59b6,8e100aa7) +,S(279f43f1,e26ebe73,34924bae,563a0e34,e5cea7f0,eb9f5702,129fa6cf,8b0c67a5,eb5a49af,bada9830,7ceec508,70a49027,7d1cd6f7,6f332249,b2cf2505,82a2a828) +,S(cfccc083,9bbcc7d3,5ceca575,3b9148e4,ddd4464,5727cf47,26f33d62,d83a6a03,e3cc09a0,9d26889e,c969c734,a3361dcc,d638b17,608baa1c,e7cbb99d,a5bc23fa) +,S(e60b0451,70c2e3bf,dd627fcc,5eab1218,d3d598fe,a41f6bf1,dace1a35,2daeb287,a493847f,4f1d3bf,9e90c022,851bb652,691af15c,f4c6c539,bf2831ae,9cf8f2c8) +,S(11875535,ebc90fb1,eb7a08ce,90dede09,fa8cce24,b3911fa6,44ce8111,8848b433,2fb1757e,38148919,bb197d43,48aa536f,c0f06f9a,859ef737,ea50b1fd,82968ce) +,S(c69559b3,75cdaea3,56003ad2,3edd8ca6,c415868c,a13a30d9,11d4c694,f5822179,a39427b4,914b58fb,dd35408a,67ace872,8c299a39,278335da,9228ac85,24652906) +,S(625ff5c3,1e951b28,40f431fb,4842f510,8b738722,cdd52c4e,fdb495ed,e42f1f7d,a3eb00d7,4eb30337,d3f61ae9,d595996e,c7d5a3f0,ceb39f23,3df0f5ff,43298d7a) +,S(1e2fb107,bbb46666,8c31a927,3ce57baf,fd1df905,3fa28286,196a03da,74327c2a,aa882338,5261bb03,a8d8793b,c8f98330,97c22731,46ded3d8,966b16f,337643e2) +,S(d0cbd747,970ab0f6,19e5e4e7,78709399,b65b3f14,24a084b4,a2dca8ab,10d76ebe,7b5f778a,94d3d75d,57b5e979,3de246bb,f36669df,b7dcc24a,ecf4e153,2025b73b) +,S(ab4c057c,a40b84f9,10142209,a5c173ad,6ef31616,db80bd13,61959f11,b739f9e1,598f12b3,4695bb27,ccb2fdfe,a0911ece,eecf2cc3,1063a3bd,42dd100f,e93c7ced) +,S(f9c11e91,2cd3cf06,d31e4795,40c703a7,4f5f3100,8e6ce299,30d5f08c,7307276d,f873ce74,bab3785,156468ce,3d6a8cbf,c532db23,2a0a92fe,91d290cb,ad08713) +,S(2d95744a,79c4d234,40e2f40c,a83cd89e,61576686,21293dab,6716072b,2089b77f,a25249bb,9dd8a94d,44576a4d,7ed800c1,9adc5e26,82874ea0,5d63bcff,2f6b2704) +,S(3bec0dff,e9a96bb1,f3cbccf,cc96ecf7,e1335b1b,86f13b63,6467fd31,5cc33abb,e31f8a49,dee2408a,2d0b9288,4e381379,9fe404ec,1d8b96ab,39413f82,52b85b5f) +,S(23721d31,616051ab,60287a0c,2b4ada42,1bf00825,127ea0eb,1341beaf,a207fedb,8cafc4b5,40e6f3a8,6fd1b546,87ff8c3a,fa2372e0,24696071,59b6e195,f633b169) +,S(ff8e494c,446cf1c4,bd557615,a4a1ce2,b8d25bac,62a89929,993cfd,51d45099,113e1b98,555ddb77,b8680eff,c57eeb96,4038de04,26a05289,8744f8ca,4f3ef028) +,S(f170cfff,f158e368,81cb677a,c9d9512a,3c1705c4,850d5a85,17a66636,7b0cdf21,49512fe4,3ff0f91d,b9ab918b,808ac11c,b5eeb4cb,ed905f21,adce5e4e,42ebbf7f) +,S(e9ff6261,d6c05d6e,4e35e373,57fca0cd,3c3ea884,4a33e504,df3dfa2b,a524d158,4969683b,9af581c1,963525b4,e8244e5e,6b7e7e48,f85c1fe0,1e9f0dc2,c66e591d) +,S(c1c4879a,b614ad86,cb64d15e,cba92aaf,4d1c7742,76d6aec3,4b59f731,addf6cde,6d7185b8,fc1b99be,383a7a5f,385a08f,d7125e3e,f72f93c,25063bfa,d44abeda) +,S(deb0c036,3818a101,ba38a657,5c0db8e4,a65f824d,57014dea,1c110387,7bf2d9ca,f658d43b,f0c106cf,6b45e552,3fcd066e,e754180e,8510b58,43708b5a,b40dbe32) +,S(c4d4164d,f782df0,f5366667,83e5aa9a,8b05c7c6,91c47a49,14798685,1da3fc9b,6c394d4c,3118c8a1,30bea2,2396562f,6dfcf8cb,8f0a91ec,20a43bd1,548bd80b) +,S(94d83b82,f6db0da3,f1bc24ac,8c5bdd0f,6e89cf2a,bafd33bd,2fb3ca87,9cf63a84,9e8658be,59d64a28,7cc0cfde,1f35b83f,e3e098dc,6212afac,ea234437,2591f2ab) +,S(9de3fae6,e6934304,a84eed5a,58e077b3,76da7310,61859847,d6abecfa,fa650dba,7e4cd395,ea8b90fc,20850be2,4ba8dd83,e79dbc4f,4efed68f,504eec04,f9bcb212) +,S(251869eb,7a567c9b,7866c9b5,a829206d,867f2092,8f3a6fe6,46ebc3d5,2df7d99e,bd87d706,c49690a1,9e0ad77e,4b3b8f0c,5efba7e1,2a448a3b,b4ad3c7d,44e35e7e) +,S(e92e5aef,818b2980,43227673,3d15021d,c84192d5,bc9307fa,1add63a2,8e888a9d,ba3a3157,96ab2051,ad53b5e7,a058f700,ea90e40c,c5855712,d2176a0a,c232f94f) +,S(b6a8a783,c2716ba8,9a37c7,d7022dbc,25fef8f6,76c676b8,267038ae,64a33258,93b09e15,8bf081ab,9e69c4c1,6d965743,cc08ad85,a8eb248c,9c67043f,fe61ebbf) +,S(26e95f26,7ee205ad,50dcc75d,82330877,394c56c,84546cb3,72fecda5,f57c2556,dfc935f8,63840ca4,71bed804,d0c2d14e,c9528a9b,ba1e6f25,6545311e,5cae673a) +,S(6c1ed40d,dd086dd8,2fb00bbe,d969ea90,7e363496,97c350e3,2d0074d3,3e05bc13,854d177b,5593cdc3,ab1e4903,c64be02,2b6b0cb2,25c71390,9316faae,a235b269) +,S(a9286b2e,81030401,c37d69cb,1e73caa,b1c68a4f,4ce1538b,11ed850e,67d11aa9,64ab5453,c3a1166c,18f35115,1f031117,e29b1a31,237cb2ba,51f1a873,529766fb) +,S(a2b862c0,ca02cc3a,e1bc5737,876f81ed,83dffeb2,4e6954c7,3cf97bb2,50050cc0,db3a03cf,d704f98d,dad8f48c,5861988a,1caf439d,b50c196a,32289622,b9a49b3d) +,S(19259392,58c25edd,953117d1,fc7a74a4,a9cc2fad,892255e4,fefdac84,4784c917,b86a1bfc,b7bc8844,abe424a5,b7409abf,26e8ac62,7983fafa,70dbdaef,43a88eba) +,S(6b85864b,194b2cfd,af1d6550,4960370,306ee34f,87c91187,230de0de,42fafd09,54a9ddf3,87458a54,cd305e06,61dd43f8,3911e88a,db6f0256,d19cdf15,3ab4b388) +,S(407cbd77,b88e6d47,60b07e26,f53fefd1,2b98bed3,5403c693,e7ea33b4,cd74b5c3,eb73a1d0,fd122265,dc880cb2,920b4eda,610ff1cd,a74660aa,7cb91323,e5485d60) +,S(f65cd6a4,594299a9,6cdb5f9a,7889cf44,62cca331,d3329f7c,43ecb224,d58c817e,8c906c4a,11925697,9f84722a,9440d2e5,f97e483,542658b6,8538aa0b,f10f5572) +,S(2ea38854,775422db,43eb69b7,bbd47a6a,b8ef1694,28753fa8,8cf49c8,9efc6e63,bf6f2d21,2b21c740,a25dfacb,bd22436b,5118f1a,2004bb90,adf580c9,6f21f1e6) +,S(f2bb4814,94677f3b,6af8aa4e,6a3b1100,c2e0e99e,289536e7,eca3e61,a20793ee,a3a788bb,2a810267,9a3d98f2,6a9a2740,91a3a29c,234043ae,aacc488a,67849762) +,S(e157c4a2,84354b8a,73d5e5ec,58dc1ceb,2396ca3d,7f651e6f,4547aa78,99899daf,f06970d9,5bef3e0b,e2bd4597,a1c96581,275c9719,605f63f,9618816d,669a0bc3) +,S(25aa7f3a,3a14731f,c7fa3b81,31a569e7,4bf32c9e,3492e626,aa4a4316,f263cf12,e5c2e210,a8a75180,31778f4f,4737a0dc,bd1a1312,1dfb40c5,5c435803,4bc3eeee) +,S(73ba2208,8cb96b2a,c23dd2a9,7b3cfd2d,c504ccb6,24c2dfd,5062f8e2,bcc442ee,ab9d3a1c,6bd762b,9cd866ab,7abc0e1,f898c567,61c7071a,d64d5233,caec0ca5) +,S(da94893b,3e73246f,6a72041a,44c7279e,dd8d4d3d,55b20db2,eb0e08df,4c5837f2,6949f652,8601b0fe,e572ac03,89fc3530,6b2d09d7,b59c40c7,a1a607cf,51684006) +,S(908480b2,35c49b11,12bd6504,5b3a8e13,7cbd4820,3046880,1688ed05,abb8b7b5,8a887f57,622a7482,3fd40b26,f58ae7a0,18d2d03c,d5ed31cb,93a529e3,387fec7b) +,S(682d7401,31c966e3,2a8bd150,27fae9f5,4452fce1,360c449b,1b20bbd0,257d58d1,ee7f773f,9d074436,685a2fe7,21b1b829,9369f543,dcac37e9,9adf43b6,4525c19d) +,S(c8661c4e,dbe125bc,a31e7a22,83aa0f9a,b4b3ae70,8512fab2,21bdb4d3,8c89fcb,30299a17,16d3fe04,7f48627e,36195b21,e6800d4d,a26dcc63,96c7fea5,8f25a2a) +,S(5112b1c6,2b88e704,f0d2c731,834019aa,d51a108e,1a8614e4,f6e62f68,d7372b4,1bfb5f8a,ee37bb82,5494c9ce,651d32d8,d47e5a29,4b9123e0,7311f260,9ab4053d) +,S(b9214d34,49e16aac,b90f6704,ee589f6d,8fa45126,be235e9b,61ef3ebf,2150eb99,c9465341,2dbb107b,965d177f,de11bb25,53e8795,69814d17,34ee9ae5,267529bb) +,S(94185601,f959999,1999c919,82e5042f,b7e68583,533f9569,73788d5c,3a087b2,5e51c755,de79b6d2,eb640039,a4268d3a,601750c8,dcd0a942,eafc9339,6fa36c98) +,S(3cdad3b2,2a707d9,90fe4228,adefc934,e8c69a9a,8a4cbd87,844a6ff5,a073f511,f6de425f,26e17045,5589e22e,7824dacc,f8cb8561,832db31a,e8fd2910,558ff9f3) +,S(ca986704,a0d1935e,1611e176,60394d00,7d2aa1cd,cb17357b,b4a557e4,f5a4b5ce,8d527934,a73f2b0d,b3cf571a,ac53b3de,11ac99d4,6ba995b7,5a09195e,b10bb5f0) +,S(f5920156,3ec396c5,82fd6090,2d98ac,2d5dcf5a,cd37e651,a1e80c43,f76940e0,2e821f19,7e27f927,20230f1d,9e26dff,5b3d977e,4b4a6cc6,7482f3ec,3cd5523) +,S(9ced8c1e,bbe0d213,b396fb89,8aa8c24d,870d305d,e9346239,b2cb0315,c883cdc,79367b21,4a2e21fb,1e9b24d9,fed6a0dd,b377534d,4da2b501,6999ebf7,f77de2c) +,S(5b07b283,ca262751,4a10817e,bdfc8044,883f4de3,38cae14f,de955f18,9713dac5,b8d6d9f6,8a71aec6,3b7bb44d,1d2b678c,75ff83c6,37c254c8,3a14be30,a5957b5e) +,S(4c2eb4cf,3fe64ba0,21297b8e,321cac6f,a8245614,45848933,19453052,69337386,35ee2473,1830eea9,85171af0,96b6bc0a,72f3e83c,6d83f8af,8ef1131d,c8b52c8a) +,S(5f24fcf5,f8c0bf43,43b8a0e,b3b6d8f7,2901c902,6d43f8de,4bcb1cdc,6d5019cc,87c2a306,138265bb,59b2b2b5,6992fb37,b2ab28d4,ff4909f,d6067e2b,4f312cfa) +,S(e26bda51,c385a875,5083faf5,6a915944,3eb351a7,88e1597b,f17649b9,b23ab8f5,35d66322,ba25896d,2a14a0a8,a3f5bf91,d3ceab49,9b2683f5,db7f58e,68ca1071) +,S(ae5be06a,b1ae531e,5d2338ca,d929b5a3,4c283035,95282aee,7c3ac259,8196bbd6,f4f486a5,bf11191c,9134d522,62ccd692,cc5c6686,c9013ed2,782b816c,da416d25) +,S(d143463b,4661a173,6b88f274,6b3c20c6,d054683f,9efa5221,ffd3badd,14804880,77b28055,7aa11d3d,b2ac8de2,c9c5757e,d0c9b0cb,af6fca3d,bb295bcb,c3ff8afa) +,S(54804f7,28ff88d0,bf6fb4a8,a24d4eb0,ee5379f9,30f890f7,8e31afca,87f23343,79288e99,a38accc2,c59ff29d,9da5df60,42d63089,45900378,c40dd765,2f0f5626) +,S(68c21fc9,93d41345,484cf5c9,8aa93bf2,25fc2c01,922a0151,cb3e247c,f130ba0d,9c435478,23b9d8bc,2e8ba0f3,8f2b60dc,ca5b6030,eef51c6,cdd20eb5,a02c6245) +,S(2f50b870,96b2e15d,6fb35001,cd8f95a,875cea3a,edf21a2b,c433b254,7798b856,44b09dfc,e0b8d522,17e7d9f2,9bbc5d6f,9886fe9e,3e360688,8d7c4e70,c3bea0ff) +,S(9d054954,f0c22da5,f330b3e0,69310a93,66b72129,2fd3c98e,76464796,847d16df,45962d48,143c94b3,57400130,d3e050a7,4defd464,223ad599,e6aa947b,12679a85) +,S(31980b95,9f51a6bd,4cfd9a11,b86dda39,af66ffb,97713ba7,3edf8c10,462d5685,d0a02979,5b45ba4e,7464fc47,7a09a90b,7265f5aa,e6b0d655,fca5828a,837c2840) +,S(e9c0615,f0444234,1f522d93,eda33b29,8951a267,7c4cdcbd,fa02a63c,a57d1ed9,7aef87dc,7095f483,5ebf2b3,156be9dd,ecedf54b,1b0c739f,c513ebda,5c5f296e) +,S(fec8bd3f,f19fa6fd,17523af6,27384c7c,6c92fa85,aeab8bf,bbdd2178,89b12650,d01a278,6ee8f9db,38b1ceb1,a3fb1df6,b631c0a5,23e92460,d0d51367,1098e414) +,S(2094133c,86322dd7,ee1abf80,2ddde826,e6385342,6bc87510,dff63f3a,b94f54eb,efb2ecd2,13bfda3a,227b791e,c24ff627,17ab559f,1bd289b7,e7db992f,d941e850) +,S(a34c3385,ee882646,b44bfbf0,f64225b2,fb86df27,c616a2ba,6cabbb68,cf36f3bc,e99bbaac,57c9f5ef,c64c6687,6f2bd6d3,b9ec8eb5,f9227c98,9a768f34,23e91422) +,S(df09dbfb,564515f3,a6d86e05,dca59a0a,c353746f,b291d9c,add27d68,6810cbec,90738e50,6bead3aa,c0cc4a2d,cdfb8529,5e752945,a7b2e357,1a99c901,49017c47) +,S(df9817de,89526a26,c61e4294,f245ce06,8b5e22a6,4937d5f9,6898b9ed,74078989,c4db6e86,c6a44091,23227adc,345d6eb7,d2f12acb,f2df3b44,978a1743,94072f15) +,S(2e713387,7a0419b3,7bf77874,b24fd0,7cae9fb1,59919a50,223437b,7746eada,5dcc4c1e,12502573,b0520817,16fa46d1,8ba43ff7,e7f8c8cc,e3c141ca,6176f805) +,S(99826364,f0061305,1ba033ad,63b95884,97158ee6,9542d06a,f2f86d91,3bea7a2,5f109254,24af4592,2ab30701,464d504d,6006969e,30a9ce5d,76a3b115,6158c6ea) +,S(19222e8b,5fec6d2f,33a35fca,83c3b9eb,effb9e3a,f2ca9c53,929fe5f2,a43bcd32,c79b4f98,4621b2c1,d627dade,f01fe761,8af239e6,b80c23ed,a2dd1b1b,e750549b) +,S(e0ea59f8,6b7925d3,ad511280,8b1ae5ed,c0acf6c6,d4ed0846,d870a663,5573970,bbfa69be,ef531b32,5272ee02,8c880178,57ab2a32,65b5a6b5,38ef81db,83b5de52) +,S(7df189b7,c29c06ab,83f7d849,58ba3d1e,7da3ebcb,feeb9dc4,64b60420,3631fdd0,88e00d45,8287fbea,5c14ab33,6a879948,e81d9798,cb82054b,772728a4,4b69e56) +,S(42b9867e,7cde3ef2,b4b73f3,e4df7504,b7f06cb0,67aedabc,16edb276,97bbca58,eab47aa1,df9af0f5,40d1c6d2,ba7edcc6,fd436f56,c944c872,1e1f4958,63144390) +,S(9ffd9a,5535bd30,a697f61e,e6fd0ffe,b1a7e5c1,9459bd3a,708a7112,3a3da54b,79fb0a7a,8334fe38,64fef8a7,60610920,af2741c1,fa41f582,37e92acc,29644011) +,S(13ea8e5d,1116a57f,8b223a5f,79c750de,6c25511d,558e6878,e92cb134,7b81e393,a41efd37,d35ea994,8175d989,cde449d0,e325b40e,a247edd9,e8f4eef,e6a4d283) +,S(110d401b,d7a1a0c,e484fdb2,34cd839d,5e40cad8,6244cdee,5c4f2ba3,ee1e2eb3,cdd91a5,4dfa47d2,98a46f15,c021a38,975ca108,f2653019,46013427,349d7ca) +,S(48a9f1a2,fe29b05e,d419a14e,8ed288de,46affeb2,296522a1,f2407b76,a8f6b040,f1c5ea7,887c029f,67202b41,198113cc,f1ba5617,79afc1eb,db0e10ec,5b5d2a91) +,S(d8c4d9a,feb94e7f,7b831464,77aa4e3e,a48b6af5,35015941,4047cd01,1beb7176,fb8af9c8,da06c2b8,8787793,bd19d7ca,6cc64508,7713af45,4f5fb4c7,eeda3c2a) +,S(34e84417,2f5ff4a2,70a9064c,d5994327,9cefde94,d295f424,2c491efa,bc1f0839,2da40cc0,5120e4e7,8e84435f,895a3ed7,6c507bda,4d16cd14,b602deb4,366ff9fa) +,S(ea802ca2,f07a4348,791b7df8,99639d06,c6db8d15,74ae8441,b29c2d18,18b7a6c8,ea475a0f,5f74e6fe,ccfca44b,ddc38a4e,3cc19c49,e2bffa49,a9572146,6338a155) +,S(d80542c7,a7be8da6,6346d867,4154f65a,b1cc8e94,19299d81,6a5c874,f25ee43f,5e85d69f,b5c72ae,bd94b1e4,67e0d30,df8da61e,4150f4ec,e3efcfae,78d88d25) +,S(bdb35e49,7c1c0d1d,7a120366,cd259e7,31cb253,1bf804ae,f0c82cdf,561d0c0c,2675a4ee,aea6dfed,8597c08a,69fc251b,7bad9869,e83f485a,73dd1638,605915b0) +,S(5174e27a,9a1eeafe,6411f3af,b627223c,db0da11,6bca0ac3,d39a3080,815e22a7,b1223046,5f58d183,fcda2603,e4593398,51ed87ed,6839d9b0,4c845459,daa3d5bb) +,S(c8b1299b,1b2880ee,7720ad03,62588349,44bcc309,6a7081eb,ce10ef20,ab1f6731,ead86be8,85584e4d,34ac18e3,d787031f,72feb217,694a32a0,76f2f88d,a04f3440) +,S(fc1378cb,c42fd6e2,f61be9bf,e60bb2c9,b36c5a0a,4aefef09,c8287a3c,f1310d31,ae4ff85e,5b22d2fc,914192d6,28324d12,51ffc469,1ba8ca13,f8347edb,5a9170d4) +,S(7c0bf943,23e7c1a,8004b23c,c05327a4,d4127c7b,eed27e3c,4a825e41,5f3c3a6e,30ad62ec,bd19f80a,a9dcbb5b,145d18af,3248eeb2,1d14e648,d7fd7217,f1089728) +,S(2ede5f01,232c0409,34b07b70,1ccce3d8,27f85ad,2a56c987,e29cd6ee,d841efdf,24cbe9f4,69f036a7,6e140720,f65817dc,847e9562,4820dbdf,b8a1384c,8d39bdfc) +,S(decd1afe,faf01eee,d2dd89c,bdb9711c,4f1899fd,437d0371,55cf74f5,9aa0858,899d1c8c,49b0b3a1,89a24445,568becb1,d3b1420d,ffb2c7a3,8fc291b,258f8ebd) +,S(1dacbc1,4be6e70c,4043f5be,3f972d36,3cb456a2,2ee1b1ce,3e207578,8233a79f,fc3b04b4,f502affd,37d71c58,d6f1a61e,b126cda0,e156608d,7f2ab786,e0734486) +,S(12ad0f7f,cc7cddd7,60cc6a3,3fd3de83,b1ab0e3d,cca013a5,68d5978b,a176cc19,b4e0cf97,335b374,661f6c21,46aa7315,a2c4f6f2,b839f88d,5376e256,99e6e216) +,S(f649bb96,e477a5f3,f852dd31,65496c07,5e14a85d,fa929794,64f1297b,d56fd1c8,46e37dfa,7eddec82,88fd18eb,9ac200e6,79337296,e2cad24e,d67f98a6,2e61d040) +,S(34f5e5a1,248db96f,a165950,a9b74392,acda22d9,95496808,82760daf,642c600e,a8a6637d,a1cad7d2,f72fe1a,df67eff8,49d0ab0d,7e06d7c1,a11078aa,de9dc733) +,S(26e940f9,ab45caba,adb1e4d3,23e5cf70,575c44dc,dd2f0b10,1540174d,d2aa715a,972aeeed,c5fd01ff,3b04f236,c799039a,9c7fe6f0,db1348e8,b97dc885,c57926e5) +,S(e3ad36a5,132f1067,503498e1,ed4b315d,4d06cc67,3a9207ce,47224497,12f51a4a,4fa719b7,37cdf1b1,cd5b963f,16a47e6a,e43dbe0d,490423de,fe5deecc,5baf9e8f) +,S(413fd0f9,4e231525,1aae9d6f,61aa0038,dbf7cc03,10c81185,394c8cc4,8b721a9d,9281c5b9,ac1f56f1,50776cf4,69e57118,8cc6989c,ae41b950,f72ff25a,d6de836e) +,S(9841a473,600446a5,5ce0ab4f,2e77ad12,bc2abc34,1e607241,c0c61d2a,d87148d5,7d1bb113,ee4b5199,95231834,1e05d87f,f9bb355f,df958410,3d161969,1d786f4c) +,S(1d4cdc2e,3e06c052,69958eba,f00484b3,36594f9b,be1ea98c,2382e608,cf78272d,6cf5d126,766fe5f7,75bfef7d,c2d91b48,66d4bff4,c8eb4e59,230d1903,16ac6bb4) +,S(da74f388,86de9c6e,36227258,758111ce,3b9414cf,cf8d5cfa,bcd9b3f5,44f1262a,d9231255,e3d9189e,a8d0344a,80978b83,3f1afb57,5c799f01,8b4ab73e,866a38fa) +,S(b2ebf119,46e37704,e1e12345,c68f70a9,a031c0b1,e85c0833,c5df9c0a,b836a6b5,c1652832,1666f0f4,19806a4a,86f4aa8e,46fccb4c,f7b6493e,26d9699a,9db2bde4) +,S(9fd899da,eb6f84ac,edfdeb4b,fbf8b521,6b5757e8,10d22d4e,56afc38e,da747cf,2daef35c,7ef36b82,d6158256,2466895b,9656970b,4beee8cc,2e0b12da,83d7af64) +,S(eda65e56,9cf07e84,19d07f6f,4aedd24,3c46df2c,bac92772,bca7edc6,ba17b217,1f394c99,b48348e6,fb709e5c,b4b4b77d,41eac2aa,bea2a4a6,353d1982,a9985281) +,S(78567d1a,1a96df56,299c9ee2,1d916472,303178b6,9b18fb00,a23c10e4,f093ed5b,9321fb0,6c5d2dc8,52e64d6e,453d9923,bff7c626,efaf5e50,245b4ff2,64158f23) +,S(c639e1a5,90f5973f,148e96f9,15c94d8d,7c7ec36c,bdf15150,83503aa9,9ef5636e,3620e7fe,faaf7581,886776e4,f7391599,94ae3e2f,2a59d4e1,ad6d508e,f4db90d4) +,S(73ef6655,c49894,7aa2b63b,89b77f14,3ac096a1,d7333494,d9774ada,5467b60e,c04509b6,2135fa8f,816436e,6ec0f513,ccbb23f8,782e2ca4,d5eebfea,6a5297af) +,S(bfa4506c,dca70a3b,a8fb0188,e0384bf7,3afbaa0,6818d503,df5015f4,f10cf341,9fc7388e,2edd63f7,9a5d328d,1b949a2c,a364075e,f94c8de8,37cda5e1,7d566ba1) +,S(2d594b,814a9e92,7ac9433f,3400c5e5,1a58457,6f47b8f7,f5f0b8d8,f48b2cb2,fa9a1577,d565b906,1acb9efb,4bf415ed,f264b662,594d1ccd,51baf83f,101183a7) +,S(401ae44c,a4039850,4d57390f,66044f6b,cf1e9fe9,f0f2b057,3f64f026,b6d5f3e6,ed947768,36ce65ec,f947b81,9dedd31e,c8ceacd0,16a40a35,78a592bd,4c2626f) +,S(43f9397e,a000ac26,8a315406,fc9cd047,b9cad513,8a7dab38,2717744c,ec6662b9,14d5bbe0,52dd8635,29c0b0b2,dff7379f,3e2ae95,6c5b4920,b36452d9,56085bca) +,S(25036a12,d8eca48a,78cb5e84,41aa5a53,16376e83,e2ac7819,db9895c4,dcf2a22e,14c421de,dcfdf9ec,b69a24fe,1c289ec9,f4d0f9ca,6f4b9409,35ac9815,a4154209) +,S(30e9c9a0,d9b9c92e,65794acf,a2cea34a,8d56e3db,d5b56205,59100128,26bf8991,999e4729,bca75c06,18f0bf9e,8ebf0455,3460031d,4ae47623,5e4ba182,2f62550b) +,S(a8fb641,fe27c40a,8e410831,fe1b0d2,cf74072a,bb626b19,2fa51341,e99ca538,f3832ab3,4eb6917,3e2f3755,366b2bf2,4dbe257e,eb516e39,4bfb91e0,a63cff8) +,S(5e09a349,98a824e2,f3ffe2ae,34a835ce,6b2f0d28,43b765fa,8dee010,49df7867,20ea03e8,4817593b,931d1612,2d01dc7e,52715fb9,36838de9,d2c9fb69,9c935025) +,S(e62a12e9,d02a5a7a,475dbcc8,79850ba8,340b638b,a5c3b505,8d3c7ffb,c90f0dcd,b075d21b,40e5897c,7e849529,bceec7f1,d5f87881,318c115f,acc99680,31d17f55) +,S(45aa5534,530265c1,c358b529,de15487c,b6bef551,5125e835,e027b0a,a69a9cb6,2e56d88c,acb32ed3,24068fc4,4c03ed2b,1b70392c,9facfc2c,2fafc696,fdb8d397) +,S(7fe3d940,50e2f358,31b410ce,e54c7c82,5eb05553,981f1c45,b136a24c,4d4a4b57,97b0cfad,4f6669f6,efb2d35c,42302e10,87c03b3b,1c22e23,24050399,345165a5) +,S(110dd614,85bedfa6,c09a2e5d,5737ab2,4a5b35aa,40129388,c6ce876f,bd3d9c30,7972ec2c,621155fd,12f0a1cc,30927669,13a9165a,7dab66aa,8f8fca53,7411041c) +,S(7427d28c,aecb7a35,a4100c42,9fe03d5e,6d3f2f91,a5067866,c618c4c4,5fc53547,8cf74ed7,1324616d,bf4135d,8f442ba8,b473ebab,fe981f2,3a426eed,bbbcff16) +,S(9779c811,98040c8e,754b9df4,b547c09a,a9f25410,1ca1fdde,365b0ef8,34ed95aa,148280a1,d26c8ff9,51774c55,7590081e,36030a10,a148c322,3c7379,67d036b8) +,S(41113833,f7da3a4a,4736fa62,ad7b4508,74ef5b9a,b0961665,e30f3081,7d861adf,98399ec3,485a984,cdbb6817,783223b6,59884450,881d2f41,3f4e59f0,ed5fbc65) +,S(f9830e6b,9a9a9dbe,50abcae1,d44d4856,3a92e505,aefd52d9,2259c41f,4b8b14bd,12061be8,5a0042ea,1baa46df,b36d6f78,62c11cb5,b8a070aa,6c6a8991,62ea1c0d) +,S(71284b2b,36a4c8a4,40fdd713,6b647482,bc73d680,3d6d0142,833d34bd,f2794077,6e54f5fe,8cff4ebe,bad1b47c,4e5d6407,44be9171,b391492c,df48bc35,10e195df) +,S(524a04d,a1b7ba04,34377531,99178ceb,7ea18f36,2c300aeb,a8daefe8,6e63e9d5,1c71ed93,861c3b1e,41a7fcd6,57225e92,b2ddc507,4d54652e,3898683,8c3688a2) +,S(e1fb70fd,2057dc3b,c545fb80,eb91cc9,479cada2,93c3492e,260b0a75,4bdc0222,aa799a9c,25786c64,d5138ba2,1f801e5e,88fc2602,d4e288f1,96c8d79d,7bad2278) +,S(2bf126e9,8302e8cb,407570f8,c3fe1206,3c91bf2f,63cdd9a9,3dcc403f,a8592d29,6452a6a2,20edbb86,3ed65ed6,cddd70d2,6b4975bc,e843a41a,10ce6ed3,d38591f2) +,S(faa217d0,1d9f0517,5950dd5d,e02972c8,b2c88076,36090d2a,6f17e7df,2a70cd7,73077022,dc1cb45a,f9e9d056,19635760,66ba7b07,bc79601d,ae7dca1c,a6cdc033) +,S(3d184ee0,ed45af08,6a7263b3,47b12449,a7270887,b8460b7c,6428ae4a,6dc4836e,d002efdf,1259dd8e,ab5bb606,97e8892b,4cb5376d,c26d08e,52b7c9a,760e8826) +,S(3c825a76,29890675,bfdcdb73,27f37c4e,43214a91,c6ddb6d0,f31e13d3,cd26eae,45bc7ae4,649d70ba,99df5d07,92e89130,87a272b1,bb2d6043,dcad0fda,a5444fac) +,S(3a8822a8,d5b230ef,62f657ed,31a12d63,2862f22d,eff16f08,8065981b,ed3e926e,ddca63dc,57ea2ecd,b25e8d03,2868b12d,abe8f7ba,8125a4c5,56d80a9f,9784a04) +,S(d0042da6,aa3b60a2,463e3396,98229067,c80f8924,12d8323e,7482ff2c,53ad86cd,40697e7c,4c5d6c,4ba11cee,fdbae25c,e234ece6,7db446df,daa03025,5f8adf35) +,S(a06e32ee,93d70c5f,a45a68e,2a180be4,7d8a7f60,17d035e,47c94d47,6f3838df,f4bc98ee,c7f50d34,4e88ee87,d8705b50,4cc0fd5a,5bfba498,5fe0699a,df811bdd) +,S(21426073,9f41da95,2dcfa74e,dbcc2f22,375fb359,93f83842,99e3735b,e39b45a5,697f2d88,74cd2249,cb84c9aa,16d20956,f5c40358,9d5b7965,ea4b46d1,9cd61249) +,S(84d52769,327646d6,13e3e1ec,2d20791d,76b765eb,fc5fafaa,20097164,dc9cda7e,d87be4b4,2e2e55fc,8f87dab5,c8c64493,f09b3996,87ef8fb,3a6c653a,a2250cf8) +,S(ca48382b,49283747,d433be3f,ee0569ac,7d3714fc,bbd76157,ac5229ee,ee25dd0,b67165e7,60894bf4,3cc80df5,6e3109,db7e370a,bebc7503,ce20836d,3f0ebb2d) +,S(8a6a751f,816c206b,91e67608,58fd7def,8ea70956,598b1c61,8e0699ce,602cda79,617ea6f1,c7f98cb6,41f01862,1f4c8cf,12a556e5,675765cc,c7bb1283,cc8ed073) +,S(1d035f81,fdc7c483,9936692,9bebc7d9,15fd3c0a,380f3348,13c65527,d82344ba,e4203070,f687298d,af8f6d66,6030f3a0,5826b0b9,31f0e55,8c356aea,b3464712) +,S(d28f1a4a,1198f572,a8130bbe,3f25e585,348a33c,2d73053c,ee7e29de,8a3ce79c,2841bd4b,c46c772a,57018c74,8510fc7a,dab16644,f157d51,9c38391c,4470f7b7) +,S(41c71a1e,eafbd926,4a49ba4d,e976e72c,691026a2,b1773d4a,88670b4f,d9c57fb8,c2b198e2,e4557f8,41203c16,b511d61d,b39e8a67,21b776e9,865158e1,91ea5ac) +,S(3f0ae72f,b1a06f84,803ff8ad,fa0e5c76,ed0b596e,d52568e2,6fe4aacf,6cdbc3ee,69a9dc3e,a0ae93b0,6c4650f2,941ebe38,fcd4eba2,fc9cc0b2,3fb9c127,81c53f78) +,S(b59e2f6,2f01449e,d6728b04,e9334f10,54c4c8e2,db4a422f,70566b55,ba4d2e5f,1b6b73a5,7444de3f,4137f2ba,722e70ab,e6a785fe,1ead6fae,9f2ec5db,299f00d3) +,S(42145fda,e72df9aa,fa3c20ff,cbf11a0a,d357515e,ec6846a6,5cc6ffd8,8fcb1347,4a34e518,c9d39736,3c88ad65,62ecc0ea,2652c6f,48955852,99a0de0b,5f42b6) +,S(17a085d7,8d8013f9,b98a8509,aad7553f,bda81df3,33aa6f7b,2457a74b,c83f6739,412d9b80,efeca81b,29619ca6,8bdcdebf,7cd253c5,88793675,6a379655,d10df76a) +,S(f5ec770b,2e0d0afc,7b155abe,bf310270,28bdff39,a08d113f,b0409624,e7049ae0,e9ce5d46,2dc5d255,a09ba37a,a7a5edcc,aad29ce8,6f9c6b58,d2781e81,5d88a25) +,S(45e3976b,749279e4,486d2db6,fbbc7731,168e7311,d7d75f62,b754839c,2fd17918,84f0c079,c0127eb,d1064724,927459d9,ebc22eb3,502a99a0,e5876e15,29c8845e) +,S(df15c304,378da361,7f821d07,d00d1bdc,189fae9b,7aabbc71,51c2117d,8fe0c21a,589daf,cad5cc54,58544b9d,a69dc510,9f8f1e82,866b1076,ff1d229,5942deb4) +,S(c5798ca4,547cea39,75e3b613,911434e4,e5f503bc,9ec6e9a4,8dfe8386,a371494c,2864334d,fb2bff0a,4690f2ce,d1a1d1cd,e3b13f96,325f295a,8e0d4f1b,b13413f6) +,S(773ba0e2,e1a80ca3,9060556e,2fa8d15f,83dfd018,dd226751,9262651c,9765c915,e59a686a,3fd13284,e380188,fa40e9e8,28991374,20c906b9,ae882512,7dc7dc60) +,S(6ed4cac2,e1685eec,16c12251,db5dbceb,90f542e3,854177d9,83ee6024,d6e7a740,2558db33,ab598118,1802a84,e6ed32ae,49c25379,606a3150,6ad03ec0,a5308b98) +,S(21cfc6ee,d98915cc,1bb52da8,e83aae9a,64970d4f,ca3e70d1,6536043e,bfb60fef,8154f487,290cb8ea,73cd147,c1286d5b,9f471665,d9e0ee24,c2be264a,2f1fbc36) +,S(f8db764e,bb8f031c,88921a73,92f75323,7d1f4a22,7bc8cc64,8bcfa9a1,235cdc11,82c25fea,2d0a1e37,e16dc4e1,b6737ee2,281693b0,b48911db,c79c1470,c4e6274f) +,S(d52f4eef,14a5a860,983eb0ac,8e02def9,53f2ba03,604cc60c,80882e56,ad6b3dfa,b34b3131,7e37b973,9559bc2,6f85226e,705bf06e,1fcd818f,d5b88eed,f2d6b7ed) +,S(3e9d0688,b9b67517,e25b526a,4e46be08,4e95a171,f9d99ae3,4cca6c14,66adaf6e,e1938d76,c4349375,1d5b9876,4ada7b7f,57144878,78805540,70b7c27c,9bfa312e) +,S(c74f8dab,54590ad1,3fff217f,b62f43ed,7f42ffe3,6c8fddac,fb6315f4,a3406094,1bd8025b,57dd382,5b5b6896,e90ab5ba,fd31ef46,8f02846f,29f1b1fb,f90302d9) +,S(71f88089,a8e0ac,6cd92e03,b1dafb04,76c0f489,f16def9,75985abd,5dcd02ed,839bb263,7827e6ab,f6941b53,67c9aa09,835c588,3956733c,267fb52b,6be767a9) +,S(983d1cde,7d75d70e,328a8a62,ec82a96d,5174ed4f,c9676e10,7c282be7,bd408b07,5fe2426f,287fd353,173c699a,39407e36,c365c413,76986640,7c12f11c,5dc436a) +,S(3cf9defa,a067fd0f,6b012fe9,8b05aea2,83c332e8,cbc8296d,c777951,9e62519a,3fbffaec,c77d872,7dad2011,aa314690,2806f763,b73b780e,375508a5,c77a613) +,S(f415897a,cf653c3c,26fc5231,f375e28f,c23041aa,af05455a,e81419dc,25546e30,3a9d5669,806ef66b,7a0661dc,cb941531,d81fa7f3,e08fec72,ee6312fc,4a7f59e7) +,S(5bfb64c9,cacbd09,244f3a96,d5a6800c,4a012297,95962fbe,a429b659,8e085eb1,e5c4ecb4,9cc4c685,a4fadc80,77889298,b94e779f,7f462aa2,130ed8b,ccc0604) +,S(61a5a78,a086ccfe,9f54cb0b,750b7c8c,5c8dc4b0,e32f3c69,c65ce4f8,9009587d,50193c13,affe3a34,1ff3b8a0,b37f07f4,b49667c9,f8940311,9ecec58f,a76d8c60) +,S(e74514ed,93784bda,ca6e30e4,da2a9a78,c7c70bf9,42cb4ba6,afdc357a,c694ed1d,ee4a8c9f,7d55dd09,c51117d0,754d301a,cc36dcb,49d437dd,ca46a920,7088440b) +,S(dd9aa58,f2cc4c0a,8d2bf548,6dea653c,b4671e40,c0073df5,352b2a9b,95637617,6478aca1,582a65d2,6c0f42e7,48f06e60,ab85a494,d0129b85,5b5fdc62,7dc7f580) +,S(fd7f2622,665c2005,9bdb8c46,d140ecda,ce013ada,6dcf3503,e28eae44,c2dcd83e,536c948e,5db2978,31e2ab3f,fee860d5,dd7fdd16,645cf561,67e484,f4a62c61) +,S(9635dbcb,b2595930,835598a7,149a8a37,be64f607,c227b307,4d8e8184,c2ae99fe,1b2cb226,bd9f23d,bd243ea3,eb57baac,163f4e49,6272d220,9f436f81,7b6d9442) +,S(642ead1c,c24db5c4,77d798b1,515083a7,7777476b,c3a03993,883a7ab5,e1abf814,185293e9,6e6dcd7c,209fc891,d96f9dfc,4012f756,7d3e2f1c,282eb0fa,5de46eff) +,S(3c5be7eb,3aeab34a,2d982ebf,3a766962,822ddb39,527ab79b,83540818,a4e2931c,a161ecfd,2b906280,46d6d1de,c149eee0,e6c92ccc,5f936a51,e2a4c3,82e555a9) +,S(c1a90946,6c0ea8e4,b60611fd,6c61733a,6d90b0f9,d1b7a761,1f9e3e84,6423bde9,f928d301,b6c27eed,79b8a8a,ba388ef5,24b17220,7ebd7396,5623e60f,f650dcf4) +,S(e49d97c4,2ec1b8f1,43180188,382b265e,4216bdcd,82824a15,3a0e1d73,83207541,8e521e4b,95a1f4b0,934753af,cc3b73b4,7b3eb00a,a9c7af48,7e4e5a02,6234b733) +,S(49f71f26,f0d828be,9e9a70c1,bf768117,ad2fe6b4,6e9f416d,eaf17695,80dccfc1,86f4404a,67e8e6a6,9a901589,d7c09873,eb553aca,41b0cb66,f4767621,76ff0d79) +,S(487d806f,67635c8f,b66afe46,3754a5b4,64afa469,2ca69541,5d91a6cc,8903e853,b610d414,26951e55,46bb7216,6dfb62fc,602b3d20,18c38670,760f55a3,6c45c688) +,S(47af5aaf,cc7b69e4,bc536d57,8f57b958,3fa17666,2d302141,54e3e35b,57357e38,b79a4c34,709d215e,dd3b0fe4,9cde9de5,b45ccdd2,af25bbd3,602a0c90,9834dbee) +,S(84f79cc1,a257fcad,546d8218,5caae7da,8a8d523e,7feabb79,16ad7d8f,5421575,cc84b844,55ef03ea,59913a0a,1919c0d,cde9fd92,ce872029,57a998d3,80ec1986) +,S(550b7e54,3d3accfc,eb488b6f,b2b48d0b,9017a5d4,ed54d55a,72b8ac6f,c83f6d14,91f318dc,ea83ec1f,f43d5172,bba5ab1,7891f3e1,2e162b6b,8c512589,5f2e5141) +,S(f691885b,eece383f,1f56593f,92de0b34,1627cd58,389afaba,f442663,88aa6a32,1e6c920d,2eb76656,63c7586f,7907471f,79e5faa1,b6fbf4a6,c905e422,9a441638) +,S(4e3c52a,96889e52,b99aa469,b5f07dc6,f6720e49,29f3961,fae2c59a,98ffacf9,ba3a3d9f,dccc36fd,a8642167,7f54de2d,4c079b2c,e70b46cc,926d7d9c,ef1978c4) +,S(66720c8e,c638367c,c934347b,d8768338,54eaaa01,a81a876b,d2321e41,40381224,eb595ebd,67c5a08b,24482042,5035ecad,f20fcfe8,9a84a60a,93f3c05,a926d574) +,S(4b01f86f,f9feb661,eb33d7eb,87f940b,74302cb7,449b0bc4,84e97af9,56b79d2c,2680db84,1b233e25,16b74190,fd3a0cdd,b8fce285,ed8577b1,e13c2205,9af0d3a) +,S(dea430d,6a4b5e18,fa04f77b,55f85d36,df9dcd47,87ad5899,c16d2533,74494867,46b1f5b6,307a1c05,f3b42ff,e7a272c8,c63c2a92,19bd2971,d70ea793,5bd508e8) +,S(3f987bbe,d7fe896b,8a8067a6,de49de63,670e7260,f255e5c8,a926b9d1,fb62945b,373b2f51,86d7d9eb,18570d3b,9e48756b,663cab9,df388899,7af923c9,bd79971d) +,S(6cbcf291,56e3cb2a,b0d3c03f,3f4c0283,d953a641,9f7e8655,d8c46566,e3990b70,535c1017,fb40108b,24de2a8,358d217,8e47961,e5f4cca2,aa7e7c2b,339c60b0) +,S(d253488a,5610a541,e4ce2cac,bf4d4901,5fe63dec,94615e80,d795b39d,9885201c,c58ac205,e7323ca8,9bfd284e,9c9bcf3b,89b05571,b84d3afc,d69a9a96,9ae4fcc6) +,S(bb77470d,cf0851b2,29494d6b,e69aeabb,dac44010,17200af6,391cc2d2,352bd9e7,187cc653,b6b56e6e,6c9969ea,705a6d9d,3539d4b8,b8777371,b64deff6,45307942) +,S(438c5a3e,1ede7063,eb928da9,693d7602,809b9e08,e49951f2,6a600eb3,e929ad1d,d2918af0,67d34eeb,d8f179ad,2f3f105e,a5cbfc9e,1f416cec,372a5175,8ae797c5) +,S(35db0905,e28b3e7b,b8c4425b,8d9151b9,9cce6a6f,b6e11561,65b7e356,9191e69c,25963fe,ba45cdbf,5472c046,3da3279a,60a3f1ca,9ace47d0,4c4648b1,52d2e560) +,S(6ef2e9b,79e48447,7532ba0,1b658af1,e27b13b1,f1635317,6b47d994,cf3c6bce,88cc8a3a,aa1f2040,7976ae7a,9bfe09f4,f0c1fb85,72f122f8,4aeee871,b87867ca) +,S(c85fa35,4c064f00,ac39d455,7884f8a6,420c4192,aef2d6af,8afd61ec,2b977b33,3d17f849,6ba4a79a,bcdaf502,87fa5fe6,15d2c24e,58f27ab2,7cfb2d86,140a5f0c) +,S(7f47028b,4e84f4a4,21909f01,85df2743,e3f18f1e,134f90ae,166c4089,a9d44803,4c025c2a,c2a1af49,fd7e1e3d,2ddab9ed,104a0e21,17895fc,36eaf9c,7a550e9d) +,S(6ecc57c0,5c7f6b98,6cad9c94,435664e,3b036ae7,325ea091,234ac216,3dd0e324,67086288,9346eaf7,e6bc8ac5,25d60d5c,41bd9701,f5cc5f58,7995fd6,1c75def6) +,S(46a2a28f,61fbbf15,c3afacaa,e181f527,2b957bb4,7f127465,fc03d021,76359328,88b36e79,2c071ec4,adf1a34f,a3d1114f,f9813f91,39b2db5,83320bef,134ace83) +,S(a2072cb2,e25bc045,fe40dead,8fd3f7d6,449f8d7b,57adeb47,b6ae9b7f,7d6a5b2a,fc019c0d,8c9263f3,aed518e4,44c1e5bd,dcf796fc,7d16cc6e,c90c4c59,7877e36a) +,S(fec203e9,60d4ead8,e3510545,3e73999,1ce5234d,a92a20f1,813414a3,599874c5,118cddc6,fe918be8,d2c5483e,c985aaa8,4d708767,4af70444,1fc0692c,b92a540e) +,S(fd166bf7,a69d80da,6e03c740,2ce6f4,a05f1df4,e2a131a,daef89a5,86f73681,1e3f6791,7f2d3824,ba4ef07,86ed8f08,c65860a7,e6913fd6,8cdd759a,2deabf29) +,S(a479787d,b514baf5,b46a578,6a221d72,2eda896a,a7fc1e43,4817f125,2bbe0d6e,1a6f7857,92bc5fc4,e2fcd87c,6b82ed34,20426f30,a9c6fde,4f09ae14,9ce426a1) +,S(7aeeb17d,f75e9c7,2dab575d,2ad1cf87,b3eedf99,8df4b14d,d42b50e3,7895f041,8060c0fd,5f903934,d47f3886,8731ddfd,a6fc1355,53be9a44,38418174,37b79fbf) +,S(6dd254bb,63c3fcc9,a5d1758e,90c0c6d2,bb1a19ae,788b351d,191d0261,cba75c76,b00b5cff,f3246b0f,ec835345,1d9df948,4fd903d2,e278ac2e,59d8ca20,647c2ba0) +,S(d9e76bea,acd64f55,9a9c2888,5834317f,c24fe5f6,7e540d27,6233c187,76cd7323,4d079fbd,15ab81b4,f3aed0d,663178c4,33f976d4,f69af7dd,ecf61a13,b831e71c) +,S(b57b26a0,55c4f224,865b22,287c9402,4c801618,c50b00df,33ef8509,a94a0f57,5abc4303,1701260a,f41a0e49,a100da19,8d033179,8b26026d,6401654d,39d53670) +,S(e03c71c7,9d902be8,5caf4df6,aa401a6d,18592725,2f10be1,f4190b67,bee3bb8f,e5f16a54,ce5772cb,1390e49f,966a00e6,893ceadd,5a753c7f,9d82a2ec,7324240) +,S(b7f3b64c,980f19f4,e4f46083,c1ca758,70f4313b,3c23c5b8,6acd6c8d,57ec0de4,5fd0d8f9,2a70c9aa,bcc1523f,91fa603b,e17fa73,fce73899,2c1d720d,3d55b1ca) +,S(27b24868,2a1b9186,3a1f5c9b,a5010a37,2349c417,e1d7acaf,dd94c7db,c5e12733,c54c23bc,4e17418b,deface22,b8e527e1,4de1aee9,71c921fa,fb3f58eb,e4778125) +,S(5d4b2b1b,5f9e640,bad96aec,6d3bc5b6,169411e9,5dac7346,d1f7f885,50679a14,80f0e3e7,7e8d6c48,62b1f6c9,c0ee37a3,3b98be7d,e1c6c8ef,12759b73,c20a2e3) +,S(790a4189,63c3ec0,ba6babae,18ddb717,463d3ec7,c0b01852,5e760e96,ac5fc2c1,6db8b456,9f2fed97,783a6e80,413d8ff,cd0ac6e,d512f712,4cdacad4,4845242f) +,S(38dd209d,705c3f63,9cbdb0b4,22160943,4ddf1366,56f2cc8b,22d27479,c5446f99,8b793f60,3621f6b0,1b1ac36b,cfd92c3a,7dffb7fb,fcbf831b,1db077ff,7482c25a) +,S(29c6b2a9,24f95c8,58857951,cea2baa0,bee9866d,77b3f7d6,3cf9debb,16437528,c408f565,cc78e5,15a6e0c1,7a96392d,2952e25b,d067a0f2,d2f10eff,b54c2ce3) +,S(19f1ab5,b54c80a5,a32a1fb8,1bb3f389,ebb53641,6c8a844d,3846c2cd,350420c0,38a56a7d,7eaf4155,4f5b8090,c06fcbba,9f516a23,340617e4,dc5951d3,35b75de0) +,S(fa3d2b8e,d73ab5c3,24980054,27830806,3715c17c,7981db6a,61757048,1e1d780a,7bc0b4e2,4cde1ca3,e30ec601,73121a43,f87f679d,cfac6db5,a9bd132b,d6a89454) +,S(908e538d,730377d9,d3585ae,59b0949,c46a6aca,bb04e725,70b189d5,57c26825,5e108800,6cddf00,39f7d855,64252cfa,d4a37761,2b58b6b,5fb2942,7e274af6) +,S(e57bfd8,f38d456f,2e977090,d9f81673,db11a195,568a85b8,dd8bb725,a30d22ec,b5965e5e,e680e791,e87ceab7,156a3e03,dda7e9a0,9a9dcd76,a72dc838,d9e2e6a1) +,S(aabc514c,b88112c4,6e6e1221,d61e2abf,dd7a3bcb,a2c7cb78,4d57dea6,1950534b,96e3d9b3,f3a4c3cb,1473f61c,e224dcbc,a535c90a,7d993409,ed079d32,3c8facc1) +,S(94a800a4,6eb9506a,8f6dd737,ba45c697,4e563c3e,1df40959,4198d1fc,e499d2d8,627ef26,d39e19d,ab4d6bfd,9d4fcc0f,4bb4d97e,b0886426,40b7ca31,952be814) +,S(1022de3d,6caa7542,ddeb47d2,1f82cc3b,6e04170,ed9d4ef6,81b58b81,efd6c3a9,2317f1e8,37716a0d,842884b,cd77cc3e,d6235dae,9fad5661,9f20a883,af459b5e) +,S(9509f343,17c15f7,a54cafc7,3d4275bb,41e39183,53858724,4031baaf,97bed951,dec71a0c,7f8108b2,5e296361,2d6623b6,7b2f6d9c,69d7b6cf,d7273503,fc72b4ba) +,S(bbf19e9a,efbee2db,fbd5eef8,492f52be,2e2f9072,6b3adc1,d16f0627,f4f19d25,d9e691de,f2ce976,c66d806b,f35a2b13,56f9fc07,7b7bb239,30668081,4b52cea0) +,S(b5997bb4,5b359516,b28ee935,e4d59c39,ae434c29,5e5d98e2,2ddeff57,4afabc5,fb6d36a6,fb2e1aaf,d9b5d89c,39a854f4,a3cec053,1e1a776c,b4267b4a,d2bd8ac7) +,S(fb746cf0,cbf2f56f,6a3a99dc,71e84cc5,af76899a,3a7d02c,fb272391,b77c8384,d1e4cf27,57373ab2,d1ba3f2d,d5bf8b26,a74d6814,23a5b16c,9621b788,a51e9796) +,S(644facf9,e6290462,1a5278c3,f4a2ff8,84600c23,69eeb557,bc412540,c4966655,5b5ee0cb,449423fb,67c9b542,3868f7b7,6d1968b,9d7dd751,75e7dd5,2f994b88) +,S(c41931cc,9c311617,f77faa3f,6b6f6e21,bd030c2d,9778b065,6ca105f,cdb8658c,8a759dda,8db8a8ed,eb1f2972,12858879,bb2f49c7,468d8edd,14d28525,ca3c0746) +,S(e8dd9063,48691527,e4f4fc96,2a0e5608,d151aa68,53257e2b,1acb7d94,56f66aa2,470d108a,4180fbd1,2a377517,c5e472d4,680ec468,52bfa472,cc400ac6,91541a0) +,S(6b48efeb,ea6d0d17,346fba31,8fa33deb,301062d5,94b254bb,db6dd28b,ffe27451,94cbae78,eff2064c,cf91bcc4,fe1ae3ef,3d767b63,6eb4720e,35f2340e,87c1e941) +,S(1cb08c2b,72f069c0,e1e4afb,7ea73e48,a33f23cc,cb89fb08,db1b0919,62bedbd4,64d3500d,5b6577e6,6c18d3be,fc0a7dd0,833d3245,1ad03257,b45a31a4,67c14095) +,S(2150558d,bc64dcb6,55224045,6d943208,7b7c7182,3901f78d,9702a736,998906fc,b49e2adb,321e0c49,ddeaa152,9bf83095,762ea96f,6c1290dd,b6ad29b3,c84b8657) +,S(530f4c16,58284100,55a67001,eebf528c,f9286825,fbb60ae5,da4ecac,e3d7f4c1,80b147ab,1eae8922,50bf82fe,1a9263bb,41573617,7dc02e91,fe7e07b9,66bc6af9) +,S(c5158947,8266dd62,fa495d4f,94bbe77,b1230f44,685ac488,7642576c,8d92e6b8,1705fd37,da813af6,2a799e41,3a45a4e2,4d2121e0,1065e692,ec1de149,43be7c90) +,S(e6963d21,b576da6e,6aa6f1ec,da7674d0,d827d533,31e19d85,83ba0e7,31553f86,d3560d2f,91c7219c,76962a5e,3b2aea76,604b5ad4,82da8f8c,419cf2c8,7cfdbe61) +,S(c5aa5963,a249a9a5,9445c0da,9537d482,dcb6ed9c,8372e455,4d440931,3c3f169,7e7f9c15,4ba213f5,981389d6,22af8694,b1efbdc8,18998923,92c9d654,92ae7fa6) +,S(bd04e3d8,5bffa429,81310c7b,2c885f04,69f01977,2819f6f2,5e69621e,5a32752,dc4da51f,b88ed097,b17358d3,da4fb755,254d8ceb,5b0df72c,9dc995b3,8e145d9d) +,S(f8f55476,4418c668,3390b604,c9f9f452,1ef63756,58000c49,d3b8b1da,80261dd4,9943a6e4,1b928da0,fad12667,cc997ea5,6af49db3,8c499a2f,a2343efb,52ea450f) +,S(77dc24bc,5f32159e,7c3b6a3d,168a6698,43b12253,e403299f,b4fa3db8,74350dec,240d860e,c38457ab,6d741edc,e4fd8c51,67f75733,f12fe892,aece4f9a,578c6bd5) +,S(9f238f7d,588d53f1,52da8118,2691194d,99a56fee,373745c9,aa2a3a7e,58d18825,dff57ffa,c2012315,ad6516d6,92902476,cdb2d3f1,58803c3b,4dc854ed,8ba9b756) +,S(92f95782,a59da5c3,a12401da,34c24ae3,fbf3822e,355ec948,6020ac04,3ebbbb6e,1c6231c4,e09c414c,e0d3cbf,9be73bbe,4f1fdd,b3d65a41,c716f0f9,a39788db) +,S(1b40dd47,f435579,1474b560,66a0efb9,88271a1c,19186bcb,b1715196,84f3130d,9fe6dcec,991d652,c9e13099,66b0aeb3,53869f99,28ebc955,6c64973a,4d983b5a) +,S(473f6b8e,d4162f9a,2f40d48a,8827f79d,180052e1,7b28b240,4772fe1d,64cd82d3,743450df,fc8315db,72c01f1b,21c4eea,9c0a39e4,c1e92e33,91096576,37e97fe2) +,S(40cfc629,a550b437,9e0941ae,fa8abc6c,8b492155,2045a8b7,560262a4,86954932,e627bc57,9c84859b,d2a9ba9c,9d7a69d3,8c8f06d7,ccd9e68e,fbaa0697,655a8a23) +,S(4c91dbc9,8d2d2891,a7861599,ab55fce,943755f,5f7c909b,3f0f85a2,bbb75c95,5e541495,ecf13109,6ac3aeda,5324fe5f,6f761ddd,d2972fe,812242ce,12fd23d5) +,S(1fe3c538,ac185172,44461f82,63961364,c3c74bc6,9a91bb4e,69973971,8e729d23,974c02cb,d7d97c,65f89b90,327e6dde,e627d96a,275c869f,22c14bf9,6be05389) +,S(fbe873db,56579349,4ca9c844,8a6e0dde,226d4e4a,2f210661,30fe1075,bb11dd6e,c91061e4,d03f9f09,21f56d76,eb78640d,4df80464,459fc41d,4ca33d4b,5ebbc5fe) +,S(b58277a8,3a6d6779,82af314f,7a41a69a,b1744e6b,1cfb4803,f52a25e9,8200957d,c8faf7cd,59e43256,33403b90,7abb1b83,d3f0cade,ddb9884d,77c5fa54,b55fc51a) +,S(3949cb,e84b7790,a7a110d7,9c41d548,d379604f,ec567cea,e3aaf0f6,fd0d9b49,cdfe904e,56a9c88a,76292c3a,5da21100,57795a76,fddc1610,e7efab84,750617b3) +,S(6ee9ab2b,537aeea0,bd8332dc,d810cb7d,36f8f7f3,57be2bb3,5d84e236,f1bca531,d75518a4,d975b0d1,e2780851,4b726626,dfc182a3,885900f0,4d82c839,1c64722b) +,S(c2875d78,3e15f959,33bbbd48,8a24c65d,2001f599,3536fa83,8a3e056c,20a2eabe,e5870c25,20adee27,83cbeaaa,cfae7283,538446b,7cfd7ded,12e68ffd,3f66de8b) +,S(88e26c2f,dd475547,8795e8dd,8285f73a,dd9eb9b2,68c1b16,65f1a701,cb3c81e9,d00344e1,9d14b3f,1dcf5c7e,8269237d,a2af90ea,93a9e24f,3a0040ee,d3f171f1) +,S(ca8e8c50,660f3928,3cb72105,43710f56,9a1518a,7948689d,3d7e2ce7,a038bc55,57600213,1892bc9b,5afede4f,e71f5ec1,a1516039,ace088f,9a851278,c52b2487) +,S(ecb6e53f,4330d0ec,b9aa3605,b6e6d209,222d611,72858b1f,d2663797,772e0249,b054af9,4c535d01,bcbd955,61770aa2,e08678ea,cd8de0db,d8efcdf8,623e9eb7) +,S(a011ad64,55123316,9916b20d,ca6efe7d,e78c6b58,feee97fa,7f9e3fc6,8d889cfe,f53b71eb,63f87651,aa0de66e,a51f56f7,c5e3ee26,ed4ccdf4,1978d7b6,f0191277) +,S(3ddda2f4,ec1b4020,31a73abf,ae69dd42,8d801bb3,fc96fd1e,b06334d3,cd7dc27f,eb1b6b4,137ca36f,5b160112,38fba958,32c5e5b0,aa5560dc,39600db0,624b6c1a) +,S(13f5b643,e908dc91,415ff856,76357687,bb777f21,3972cebe,e8157828,53982d8e,bc2d3402,f3af6ee7,bef0ec2b,73c75e53,b70309ec,633d97af,b9ababc0,62d20ec2) +,S(ed9fc1ba,60a7db8,93db8148,48790e52,4a246279,d938a04b,cf168ae5,71618e2e,b241c920,ab995cf9,4ab1b707,b06bbc7e,1cf7b8eb,80325934,d57e9e9c,6ba08459) +,S(89d4f6fa,f6252ba0,d036dcb4,54fa5f1d,311ee828,1cc5ca85,73fe7607,7b16fadc,5f441ff0,56fd4e24,ca4c9efb,859d6e16,2e4daa4b,a7f3fc58,e42a540c,23b6075f) +,S(4acfd390,e8a1b430,9af0c28c,87f51308,a1ec5741,8c194072,45c96c79,30498a3b,dde7b57e,5e5ab271,78f2ae5b,6494a578,2757f508,bafbbe64,30b96bc4,96728d2f) +,S(8320cbe,fa7483dc,4f5e7b7d,d74cf492,b95b7e31,b1bdc651,6595b605,eecc134d,e766291d,13959f5,805de8f2,aa59cd66,8376d93e,4b775010,426db24e,b2ff41f7) +,S(fbfa6a21,deb1d183,cfeda065,687a0b96,6d8e50fe,475a17a,7b690019,6e7c696c,f5901c10,5f30f5d9,75530b0,3f943caf,8de85a12,f54e4c7e,5685184e,8bacae2f) +,S(70695a81,45fad213,aa14a7ec,d3c84f51,53e3906d,5483db4a,c6e8c229,ecd2c3b,febf34ba,9744a37d,6b91335f,c735c426,1208595b,3b8d048a,3fb48e76,2008e90) +,S(89fd8cfa,8fd5bdda,b6a80bb9,96ebcc92,6074a15d,371622b6,1cd772f6,ae1ae9a9,85c2cddd,a8065ee2,244b3d35,61e9e057,87c6cc4e,d4b1ff59,53b736cd,d3876108) +,S(342256b4,cfd8e5b7,5f5d088e,3a919d64,ccf38827,b18bdd00,2ee9a6c3,fb4dad,c54f4704,f3512e55,4d96ef92,3005e4aa,34a157e5,8bd6b180,e219dd51,16c4be16) +,S(cbd38ba1,189a152e,bf78ea23,3eccebc7,16f4c28f,273f5c8b,ec9df397,9dba0dd1,d3df2ea,fa52ad52,9089c7c9,581dccbd,a2a0e060,7fd4b902,cc915f28,717c2d29) +,S(5f7ae38f,61dcf176,45affec8,7514c624,85b880ad,38df28ae,b695cac0,fd1d27ed,9b955855,f74cc040,63cfa4d1,fd098e5d,e0030c4c,6dedee41,71bb5e7b,c0939226) +,S(72e72eac,aef492f2,f3c5ce7d,dca58f40,c919a194,3662adb4,3d855a8b,532d194c,d7b5e558,a0cb091d,3b39407e,1dd58b95,30fe7561,6b4c3352,bfa51320,509d2d7f) +,S(925a19f0,c73d85d5,674a62b0,2d5496c0,5868fd41,a43696ce,eb153a0a,2e5b8051,2ff229b9,6c23cdd8,2bdc56da,37495c29,78fae40c,b429a1c7,3111d392,3c5505c3) +,S(baca4fb3,33bf98dc,165cb9e4,3bec920e,bbded256,e990820c,8f902e84,3f6e02bf,af304697,137728d4,e96a38d7,95b830c0,6c18579a,9b46f4da,a94a13e8,d3a0341) +,S(fbe24c7a,53b90f3f,918b92ea,e58ef633,bb72e695,2eee6c6c,2210f6d8,8da9e0df,1febd844,af3d057e,c9ace544,d5fd57f0,c125c55f,1d9df636,4f6be8fc,bc53e3b5) +,S(73b7de54,ae8a38c6,ccde88c9,3f526c2e,54d823de,a6415488,5e864a2a,1b0574,2cfa6943,634201d8,9438e6c6,fbb7224b,c2e6b313,538523f3,305c75c3,5c68aeb0) +,S(84960402,31a60cd4,cd623d4b,80bc69aa,7cfa7c0b,52cd88b4,2f22ca66,17151dfa,b5324b5c,af293ece,38deafd0,76835e10,469997af,7dcccd89,172ad20e,f36162a6) +,S(b6de647b,98585f7c,61f0712,76c6f62a,40926888,b1bab4fe,ad64098b,4b9434dc,f7180d81,be634f34,d878a645,2c662e8a,db9c18e0,ca7e7c13,8bc51e1c,1a5f5c0a) +,S(e062011f,da416281,bc296718,300a080e,fe7ab89d,8469e8dc,fd50680e,12dd9348,c33030e4,1ec1b1c5,4ad01bb9,8c4e2c48,32b2516b,1b2b3b22,adc4add8,1b690787) +,S(f7c7545,649b4659,49618dea,7fd15a06,1e7ee032,5d955649,b76b66f0,534a5501,2a929b2,a68342c1,81b2f55d,6b543584,ac06077,d95ad8f3,fd3f3ffc,24f56a3f) +,S(bd90ad48,1694f297,6506e2bd,e97d5803,b810f9ab,7479ae90,dc1fb146,38d4d5a0,f973b70d,8dca64e0,c9384b7,ad3b4ab6,4d3c74aa,722f9284,a9da82d5,5c6d02e2) +,S(cb5d91e6,68b3c202,b72a38c2,f98e6e4f,14bb566c,f7996d9c,c08aaa07,210b1b1a,68e9920c,597b633f,9bfdfb8,72814422,4ad69ec1,e435e843,73a9255d,79f52d7e) +,S(d251bb9,83bf849b,8f058ff6,32ac6bea,bcd12649,4fea947a,f943cdf0,6e0c240b,5098026d,b8ec5c54,8e3ae103,f0d172bf,e84281aa,b8c0b131,16295587,ed4500f6) +,S(27235299,c1f8d73c,268bca88,62d2b6d6,635f151a,d148c662,6c0cd5cc,1a3d2234,5b03cc60,f9224aa3,10d8193c,74e70cbb,6513ba73,d6d98ad3,2e1c2d,7f78ad52) +,S(1cf437b,aef8e007,ba02a24e,735d8444,698e5edf,2f9d41d3,cdb28cf3,3dd53851,e3fcdb74,b580b8ce,8f6edfe1,c276c478,da11323b,4e96862b,926ca4c7,f739a8f3) +,S(aa872c85,70e9449d,6cf020c6,77669c8a,7ad408e4,d9fa194,99867c6a,f77df918,572579ea,3d1d9575,e60a79a0,7a2aed83,4fdfba52,61b962ed,42e59322,c02fd873) +,S(b3224a2e,80c3a174,66a9994b,717b4c37,424f12bf,9dd3f17f,6eecd801,3ee2ed56,7ad1cea1,128c1605,552b8be2,a5fb6bb8,907e4290,d76bc82b,e17ecc32,1be6fa43) +,S(29b8f73a,7fdf6032,4c907022,b0107c72,ed951eef,29687feb,a8de56ab,4e47b8ad,19b849d9,bbdcf00,a6bba6b2,f1058695,4f286884,9b5be608,d6b4c357,1098f54c) +,S(3c2f5680,96f946ce,3d048364,dce939b4,a05ae9a7,c31c2a11,d2a29a1a,3fed06e2,47701685,b698de43,ac515062,9c40a15a,bb952a0e,bdd96,ba4a1b4c,5f61658b) +,S(b80f00c1,ec0d059,c9f5c69c,10cfcb26,651716d9,3d0b5702,b2c7b295,85af4c55,aac197db,ab42141d,31f63425,5df908fd,fd026d10,1263aa7,63d99414,adfdd02e) +,S(66af071,6b78b854,16572c86,fb3e51e9,b6d66ebb,bfc2a2f8,dd664010,83c83435,b8b2ce8e,fe794b13,4fcaad05,821dd884,9a8318db,614d858,8dfd4d2d,65314398) +,S(7ce8342a,6ea85f61,559cd2ab,e82debe,82eb5aca,142153e5,320562a7,6ba155c0,8a930243,5ebf4269,d75363c6,93ad4255,59f493e0,e492150a,9f110c90,8d7750a) +,S(cfbc37c5,184fe206,7f7b5c6f,c5e50adc,ed58ae61,d9059bb,4ff64a19,f48483eb,bd567b19,3da2b2fd,bb8941a5,be9fc72f,11d9cfa2,4c4438c6,a4db3091,9c8867cb) +,S(728c27be,52c5a742,859774d3,2d33fbcd,41e997d7,25d6be46,af480c8c,f9ec436c,745c7738,2a833cee,19808d12,9768c213,7500e8b0,b140e3b2,94abe97c,9a7c73e7) +,S(4553277,fbb30c09,a1ac1ac6,cb7d38f5,88cd5f3e,d4ebf6bf,5b5f6e78,12d47d5c,3ea80bc9,dac9f1a5,ac4beedb,d254cc15,728f0ee1,6949ce97,53f1bfbf,98e3c78a) +,S(7b752d90,9fd6d063,f1ac0f22,d8cf1e6c,78a335c6,ed11743,88192fe3,cba54cef,a252376f,e482ec59,2ac440e7,3aac3b46,a149e35,1aac2d51,244ffd93,f51d11ec) +,S(e78e796c,eaba974d,89d344f2,b610e84b,d51443bd,1fea5422,d2bea957,5467a376,13f0797,376bcf76,b6ade4c6,a95b6446,962ff925,b32fef9f,4549aa1d,e64e2b1a) +,S(1b7a8c02,83f25ac4,cd4a841f,4045035f,92a39bd2,c1903c90,4071eb44,5e8d702a,1843f757,7d03b6b2,22bdc28f,47c7fe6,fb83b25a,8d795b46,9e3ee9d1,ccf7623d) +,S(90d06a90,6ad81dae,20cfc2fc,6be85b2d,41dd9f23,63e13423,c557c4c4,bf3e5e4f,6ba7a127,58861784,2d7ee3d5,9b71ec99,86a72ae7,71312739,79544095,1e5237dd) +,S(d7bb4e18,ab61d8f1,de4b5bd9,9a5d03ef,1e0185ca,55ef14fb,be1f0b5,4cc4803f,311f268f,a672975b,acabcab5,1dec5754,48eb5a82,685e339e,e23b41fa,112873e6) +,S(6d5f1808,f17e0b81,a6bf12aa,34032644,b708882,96e99861,fe5ba4c5,5546c44f,8eb304c8,92cee7e0,70649d73,ae76893a,610504d3,fdf37af0,92d5dc7a,9eab1094) +,S(e4f62cf,9835a4e5,c2b7a456,596498df,2973192a,af2c80ef,c036c71,69df470b,874a48df,1a25a003,ada8939b,f727e0ec,b7d2e4d7,1efbec4,7193a2b0,50ecaf28) +,S(7fb31d8d,b3d5b77d,4aa9d0d2,692013ce,c82ccd6,83a2235d,848037b,dc6bf8ee,ed5cfa61,9fb4e350,dc37e2a5,2bb67104,90dcb484,b19af368,8101e59c,f9f0f0a) +,S(8887db9c,e3eddeef,ece414a4,f46ff048,3c4fd25b,14354869,6c60871c,5eaa9ffc,50294d61,1040a466,f826e654,3fb93f94,b4d60b11,d589287d,6ea33df5,a8dcf366) +,S(9d9d224a,595c843d,1f70297c,13b3645f,385eec97,80fa9e50,d27115f7,b677aae7,af9d5f61,24594cd9,a3aa7100,ae6f169d,dfd467c4,1affefe9,c9a0a5e6,6d7f2802) +,S(743d9b40,527b23b8,f165b6fb,9d5c14ef,450e1ce6,94439354,ab501eaa,2f34137c,6aad08c3,bf602b52,7d43e3a6,e7efcfd7,f24222fb,f8213f25,e8195501,9c8f0885) +,S(63c850eb,f0cd6fc3,3bb7a4f5,6d43c389,1f93b11b,5f67e3d2,f9b7537e,e5a951e3,29d214e8,bde33612,a5a160e0,f7cf3acc,3b83686c,ec5d7c36,dd90ebb1,d97c7ab5) +,S(b95608d9,84c13243,63809f82,b42cd16,fcf3c6be,5b19ccd2,249016eb,d93b4a54,41aabb2f,e7083dfb,ea380fff,2467a843,c88ef6b4,9740e73b,33a088a7,649fb0ef) +,S(8361b632,5eeafafa,f01e3624,6bd8f0c7,aab461ef,cb3484e6,c1ee871a,7ef95114,34ac956e,791cef3a,baed24de,7f0f59e0,bf34dc75,edd10159,b3870248,255eef36) +,S(807109d4,931731c0,a94127af,cc98e487,1fb44467,6d8cde89,88dfc252,868bc853,363e3944,be00a734,4c50afc9,cbb43183,f56eb20a,c0a5d9ec,74857484,ed9e1d61) +,S(25ef876e,d1654570,244ec258,e7ebda09,35b11784,bf5afb7c,8652e5f8,bdb34055,63459bb2,b8affcb4,1f6ad9b,9437f3cc,6d8082ac,d400928a,29f11fdf,503c8553) +,S(1aa87b1b,54eb6bd3,5fefb162,b27ad9dc,eee4b5ec,c1b69d4f,1fc6e230,d1848435,e5cd86ac,23c3790,369d7fcb,2189098b,a4fb3007,f82e5090,22e8ce5a,b44258d) +,S(cce2b0fd,9497190d,e6ea068c,98bba7de,a8f50aa,12930b4d,9060808c,b1ce6152,b6aea7ee,becee274,2bd8146,d792a6e9,ae75fd79,bb8882c8,11135d0f,8d5e68c3) +,S(fe421506,955b7cf6,f6a84228,30f7c6fa,95e4576c,da711415,5a49c238,e0bdcd4b,4e4a31d5,9b70b51,f73a4d02,eb09e4cb,7dc74a29,bef959ed,86558fc7,d4c8f401) +,S(cb26c118,264778ef,512f8acc,385e5ac3,10b489dc,88991e15,13665b7d,587d713e,7375bbd0,9fb3051f,a907fee6,80683f93,54403c76,85ca7eb,97a711eb,69033c6) +,S(8f286ae6,171d88d7,d82cdc28,93960bcf,53768c8,9cf1f149,fba0acc6,f5056014,6852d427,a888c5a2,4e748f2e,e482d38a,42879db2,2e824d1c,d72cf15b,8e32b085) +,S(b7af4b6d,7eb4eb03,e827f099,fb8b02f4,bdca366d,811d031b,ae827941,235e75a0,7cea697a,e8cc53ff,8c738ec2,55a64e4,4a499643,4bc5e16,422ebb9c,17d3dd12) +,S(c8471c9f,53eaa3fc,850ae514,dfa1109d,e89c500b,e965682c,6a4bc2f9,105be1e0,7d5f32ce,d1e758ff,e38325b4,778e68b6,f0ae5509,fcf9195,c1a79d41,57dc519) +,S(8d192ced,73629184,ff6db80e,b2c6df4c,a8ad77f6,dfc98c52,9406e7aa,dd506536,3b01ec04,ff45b037,c1444255,9cb2f629,7b4f8cff,e4c3eed6,3b95d4a8,88fb2137) +,S(318aa156,f4912dd9,7b90ae6d,c29b0f8a,99f616a2,5b023f08,ad35a8c5,10ec5015,b398cdd9,5ad52ba1,d7038cdc,67e36c74,5625fb94,f62b1b9f,aa2eb5dd,be6ce52f) +,S(b7fcf98a,6a385f68,a1c6f9ee,c6f069c1,81b0c94,df8c05ef,b59b49e3,aad66f54,912e2098,e3b6e44f,46eb6382,83f554e1,80af035b,16c0eb3a,4e000cb8,d4ea2da7) +,S(599b7a5b,e7a7cc6,3e0b66,38171c0d,41d78efb,92a9bc8a,1d0e8f48,b2b92fc2,afb3343a,1983a867,c8e196c5,92f745c,9060330c,1f0c0509,375e30de,3a214b7c) +,S(c3578705,3221f18f,69dbc241,f927ec48,3280ade6,44c70129,2b30a11,a296db9c,2b75b2e9,fdef6060,29633ae,481ba7dc,8ca52847,d4d0a201,9da74056,40a980bd) +,S(9e2020e7,cc4153b0,adc2b1ef,3cf607ac,305a480e,3a8854d1,1907fca0,4811fa7,19153a83,2c9a0612,dfea182f,a855a039,33035757,2e98e5ef,43f26699,3b8bc6b5) +,S(1e0c4c68,6e5242c0,6645f4ac,6ccb18c0,82c5d5e6,c89322b4,3b6079b6,ccb5a5f3,63c4a4d7,3ab71f2f,c49f5532,b543e381,83ce223a,c8609be9,d6b72981,8b5dedfc) +,S(44b11683,5f922e88,e7ed4328,cfb212f6,aabb6199,64fbdf3a,87dc7f24,faa761e0,a9181b5c,341cd78f,2e1446a9,e99acfee,7aa5b91d,4c7da20a,b7cf200c,f470ffbd) +,S(940baf24,717ccfda,e539064d,f6e4b670,2ad8b60a,c32e38cb,fa4eadf2,6a7bd3e2,bf5ab95d,2cd9b68f,cdf535bb,84b967a3,f4fc44d5,5e6d21af,d09e1de,f5f13ad5) +,S(4191f800,85767106,a9e5fa6,8521366e,a3adbd79,ea315b93,9e63f797,2995e7c5,662791d3,407f50b3,7a68e15f,5ee71991,2e893099,a907db3e,f818938f,9c3bb2cb) +,S(1bb8ec05,76ce9cad,f96b418d,cb5c7d46,9b49ca81,7f253b15,8b26cca1,cb9a472d,762e9c6b,2335769,72396f,36a56efc,f2618754,f1c30923,30b521bc,4e0198b7) +,S(c5216da7,91635b83,e55ec5a2,d9f3f8be,b1a2b0e3,cb097528,654c50a3,315be78,2536358,e58ffcbe,789d34e3,25d9f59a,2210c247,a80eac8,c716214b,9d5e520e) +,S(7b1488fc,83a02d7f,d12b9eea,555922d3,f4a9c42b,52f030d9,bdd39156,f0890225,ae7dba7a,d95420f2,8c8185cf,5aa2b777,b9fc5c14,b6c47048,d8ef071a,77dd4397) +,S(e245e4f9,7d6c69d1,5e244f4a,668afd07,d57fea2c,f8401b2d,8cfb6ada,f01f8891,88a0648a,ed5eab1,d57226e4,63411b9d,3632537d,699f39dc,7d7cbe5,49e76900) +,S(ed78f3d5,1f4fb987,5918a0cd,d6e5280d,6516f5a5,acdee916,d3e7c7a1,d757d188,ebc569ce,9b3cd325,528cde0f,9a2ef54c,d9f920a2,1ba7785f,62ef40dd,9463a81d) +,S(3e8d870f,bf768b41,8264ad34,89026fe7,8870e201,3f98696c,81dc3b7b,c0b1b599,28558e59,a6a6c255,a352cc9a,c20508eb,55af7449,8d75ded,c94fe414,fadeb218) +,S(96125a01,8f901790,fe25b41c,f2f7fc98,50cd30c8,cbd05ffa,cb76bc45,94d5f5a8,125db476,3fc8ccde,492e7eb4,45873147,8f8ddc5b,6c2b588a,b72d9b1b,fcd4c43f) +,S(779d9847,6fd72d41,937fe1e3,e12d4076,5cc61f41,19b37437,3919782,18a3dfa0,75a3aa4b,95523e05,42f38dab,b2d80895,cf3738fe,5152c8d0,96a587d5,90442891) +,S(681e390c,323224a0,7ccd9520,23c9d89f,4069100d,3b275c5a,e773efe6,170f4e4a,a9bff0ee,334bcf6e,a3bc44e7,5d85acc,f753a471,ac008e0d,47b19ac2,476b184a) +,S(d7b8530f,3fa18d18,ed94b938,2906e431,44ad5994,5eef1d53,e3290887,5c4af2b9,2efa5bd1,acc4ce6,73b8c76a,beab2e87,6399f84,94a1450,bd6833dd,debddb92) +,S(1277ad75,6e965ecb,c8c04ea6,c22042a3,ca3e71e0,74334012,7063d3b2,da257a5f,38c90310,ee2bd94e,5f3149f1,f38d065f,8df110f,92f126f1,3a69013c,515134ed) +,S(4e66e596,94c521a1,8114b232,427dfb97,8c7f14ec,7b5e18e8,9c11cb5e,6a2f6f65,47d553c1,8a858b59,f1aa8f4a,51803450,c237fd2e,60b137f6,d13647e7,6683caea) +,S(1fc1e8bf,3eae2dfc,b141be5e,ea612378,209ab1bd,7ccce45c,d51fcfb2,8f192aa3,5632d350,ab6b3da1,599779c9,9cd8d7b5,e317ca9d,ef3245a8,eb62af95,ef769c20) +,S(7eca2d92,8d2bf4fc,ed1a8336,eb87c5f7,b864b842,b3057c8f,97d5dfd3,76771d7f,969da039,7a37997c,c243d448,90d8110e,fa580359,bfb35342,bf69dec7,4bb17337) +,S(2531025f,8fddd665,cf34baec,52733303,28e47e4d,827248ad,9a1e6c4e,be3db9a7,e404fbcd,d180b2ad,931b4f61,5902eb06,cf00f66,6f1323f7,bf0652fa,94dff64d) +,S(dd28941c,bf6e4bd,76b4bad7,88f700a6,8c4937a,67958c3,bf6388a9,d5e26441,cc45f07b,9ea1a81c,8d89af84,8883ad1d,53ee8a52,2416c445,c4963791,7a366909) +,S(d3af9e12,53ffb85,ec7829a,4d41d704,1ea62952,4d7452a8,d9ab6ef0,1d6b509b,9c115e78,91b383ec,20739d37,6450a2e6,6f332e5e,c7a3a97b,2eca8c0,ae819bbf) +,S(2c59063f,13ac98a5,ed196aec,4f2aba11,c8647d78,42be85f4,ab87a007,2b49001,e9738418,cbb6e31c,f588a3b8,70883f90,ed3bd8e4,86e3c77a,37fd1152,c22637d2) +,S(6c0ace3,f182c963,45deeee3,c41c5e51,8dce984d,3d409a89,6d766ea1,b1ff0e0c,17e09dc8,dfc53cb4,952fec4c,92782ce4,3515544f,6181bde1,1d1ba1a,bda709ee) +,S(f161125f,3a229d29,2053fb9f,6f118550,43d80e33,9bd45af8,c1519043,2098c9d9,1b442ffe,a186cf2c,343b90b3,66a3a008,e08edf90,f073e740,abd5d20b,8dfa1327) +,S(fd081f05,6b219fef,56a3fc1b,6dc7873a,fb054b40,1b3ae0b2,414384e0,9080827a,9711912f,4ceb0036,3e5921b5,c2f7ca49,387b78cb,f1b9c2ac,9c5d5d1d,1bd8203) +,S(72c6eecd,d87657bb,ffc3a03d,b6e1f9dc,83252d2d,c73ba3f5,8642fc08,fee42b4e,282180c1,7737b51e,d047cc50,64d53cec,6340eefb,d969525e,a1524f0c,a305e39f) +,S(10df231d,4582143f,1ad7fe00,508cbbfb,3d49775d,f13dcee1,d6155768,c14bfc51,b7743bf4,e7cd49f8,88cd0d26,ac196037,e1da9402,26518e07,407bad1d,20af7dc6) +,S(354e8b0b,e40bd9a0,36620006,744c0913,5bd4bcea,34ab3371,9561e36e,f465956a,3e7407a2,2b9d71eb,a04239fa,600834d7,5f643c8,b4ca6308,475f6c9e,8d35fd4) +,S(2ae99ec0,6a4e080e,879a60fd,a93a47df,9ba7e0f3,b87a6772,be6d7e23,9bf2c42f,3fdfcc57,6a36adbd,52467e01,f3490fbd,82766cea,b956f80c,7b1d29b0,5066c31d) +,S(f47ff09d,5e93e827,72e73c7a,8f1623e0,823b09bf,86ba3023,a223a680,fd849bd9,379ad3a3,cd546d27,35fbe5d9,97c3dd8b,8c45a3d1,ce8e9c49,b23bbaea,e93a08ea) +,S(252c0934,acc3a624,c4d8b409,111b248a,2242dba4,7d57718a,aedc9cfd,20647cdf,17b7a015,a2ea993e,89a7161b,f50124ad,561ef131,609981ac,fc92e495,cd2ec91d) +,S(b7f6bde6,7cdbbf9,4a3e06b7,dc1bea75,d6247197,a8617a6e,a1f65f44,a7459006,6d6ad596,fd3472c,9d7eff56,943c1a03,ee4f540f,29782f77,afe999e6,14f5e316) +,S(210c956f,e0a741a7,edad58d5,d47a2a34,fface7c,5edad0f8,f4953b72,28350b2f,4d4498a0,892a9a9a,4e87ccdf,424d7910,bf90fe95,186653c7,6e6966a5,e7a816b8) +,S(7ab93adf,b8f35eef,8af99e5e,e37aaeee,401a1936,fc0b8c88,518065d,12f4a74,4f0782b1,c78954b,8ce37bdc,7e533145,3b885d92,da1dbf85,940da9a9,b7f0dd8d) +,S(bbe1b787,9c93e7cd,891f628b,c9a655e6,f4c7cde4,fa799596,74978224,9fd05fd0,493d3dd7,be33acf1,38ef5b73,8eb8f8f5,4e270323,8f70078d,5f7bd9e7,177088cd) +,S(61f42d35,ffcc6151,f8c93b21,5df0cab1,fb804cde,f9c68818,fc4f413,b804942d,46ef1e12,d6add082,3917a758,9c137d45,c38ae2ed,eadd847d,aa574e06,18708396) +,S(18542b75,3e78191c,b3dabcf,f9c64a8e,5e4b075d,d600fe60,b830e732,7fbc7b40,6a816e01,41b17e86,65ec280b,f6da9dbf,8061329b,6db9d13a,a9f10c0f,41340118) +,S(ef83d0f4,a3d2963e,d14e708c,6d22017e,aa97b2f5,23b06f1,140b4105,459781d0,5587e5,13725819,1b10bd40,e616e06d,16a50392,7a8b1394,a562c396,973d98b6) +,S(fe73429a,7714dac6,ed0db327,d6949d43,30d2b16e,a513d3b6,7b74452d,78a82a4d,7079088d,fd828815,ae087319,c232817a,4928f743,843a4966,e9411276,d16214b3) +,S(2e8b8a63,3048900c,4b82ff8d,fd86a971,86e3f1b4,6206b252,f06a8c85,82555130,74e10dbd,ca84d796,b3b37ae,b32624c5,2c5aabc5,d4fcc5d2,21c1aed4,71c940b) +,S(9f4164f5,4f34a59f,3a7be378,66a8204,def2fd98,8dae6dbf,5d471e0b,caab7017,4b662fde,bf2615c0,8c7b53d0,b2915d50,ddd2916f,a3599d81,bb2eab6d,80e93f57) +,S(c6f3a26b,adab6699,aa08fcf4,6f0ac900,2be3597c,16133225,6a5e6577,11b16ecc,f29db1d6,579d0e36,4528c297,36019f4b,6e8f060d,ad5effe6,d357d709,882a250a) +,S(76a4f5ef,6a869e28,e6494cbc,ffc6eec0,1ca983ad,1b8219cb,d2b84eca,96f8b910,e1d8bd7d,55a297df,32ee185c,c60db286,a2e46cb1,312a8995,5923a068,cd3318d5) +,S(d2c25c8a,cfaa0b2b,3f6e70d5,bf095700,68102f8b,24867970,ef3c8000,b2212d1a,bc907681,9c7926dc,bf81278f,7dbfc4cb,292a8071,177ce8a4,f4e9346b,a2d9e500) +,S(b2fc2ca,5a30c678,61b0bd22,5bf2c088,26d799a5,9c9a680d,dabac9aa,5cb624fe,d4abc7c9,fab915d0,fe9dcf59,a0f83ca,56b27566,6e9841cb,b5b14874,5f6732ee) +,S(110ef531,7824c321,ba7fa94f,ac98de3a,c6cf44af,db92b7be,1006c751,9b425065,cc3daa20,6c0eb83,6bdfe640,1f7461a,261e7233,c70e615f,db82a991,77b83cb7) +,S(fe21a607,7419ed88,12d16ba7,5485e01e,3c063359,f95a8634,3aab1c84,ba6ac00b,d6e08c98,4b7a5282,bc1857b8,82604fc0,692a2fa6,40cf5a5c,d298f344,54c836b7) +,S(c5e45275,ec85bb32,edd32702,7d7d87ac,8394bc51,722e0bd9,58281e61,c454fcef,9b158ee7,89034035,fec4f06f,2fc81755,59f9f762,38742715,92ca6ff9,e5712a8e) +,S(cc68f3f3,36360481,5583d65,7da51968,a4a44a69,1264bac8,289791aa,dc7a4ef4,9db5cab6,7b31f3fb,f3b5fde2,273496f7,93316358,6d14e80b,bbca4613,319df9aa) +,S(6d33be85,5fe8bade,89109a3a,8c089aa3,f7e9d178,969100b7,eee7a693,d83ace80,9312736,87c08455,c43b4cab,afe71408,333fbd69,d330315a,3fc9a52,a9d473d0) +,S(5aa581c2,fc48c38c,2aa2e176,c12f12b5,4810ff6f,862fa17a,196c06e4,812b9e3c,adbff08b,bf6fd5e9,9f91f9f0,9881cfcc,a7b5c2af,709bf838,6055079b,2f75f3c4) +,S(12eb2dde,dc6ea4e8,dfd43067,9d45052b,b882e4d9,bf516b,61edaf00,305fe883,8f948ee0,f8514f9a,1bd8a71f,20c95e4d,e30caa5b,bb3a383d,9561f027,34bb1950) +,S(3d0d7eda,43045e9f,62dc680a,be47e933,74a95d59,945b69cc,60acb89d,e40dcded,45c53d35,e369af07,eb223a79,1d148ea7,1875cd1,8ca066d3,399743f9,65e184b4) +,S(173d4741,5803d266,7ea94abf,319c5917,204256ca,e217647c,c024a9b3,be7b70c,2da6c348,cb066462,eddfe8bd,3dd00ec1,34a0a060,4b7e17d7,e6cda389,dd4d5463) +,S(10659655,e2f1ba5d,db390184,c2d6d1df,1cd2abfa,4cd4bc18,c89decc9,5b5d6319,5ac2793,3a88870e,d5c7752a,459ced45,69435a09,7cd0e030,25608cf4,ac2ae267) +,S(e462be7c,380d7bbe,cd45c6dd,8fe60219,404b0c9,4c5e0e4d,31a23064,2b5b95,872183ec,1ba5b854,1f3f99d8,ceac80c5,9e84756d,cae2e694,9b43ea7e,d1cf752e) +,S(8200badd,1df41faa,19b20cb8,efa424d2,2f39b1f9,26b692c0,2a0ef6e7,feeed67c,8402fa9a,6ef0f83f,42546b05,360296d3,74db551a,d89be995,f2c11866,5be528b3) +,S(760e2457,a3e1a165,526e9fe2,2b5bcad6,e8107581,337cecac,e2ae87dd,a3c54592,c5111ec3,24158a21,56b897a3,82bee2bd,de0f9df,af9ef611,a7fd3fc7,4a635b3e) +,S(ba6229c7,1729cae6,5275719d,9a35691c,f260a003,168f1a25,1ac00b09,aa17872,7d281600,6bd8981,82126d21,70fa0ab1,d5dd0c7b,cc377a88,c43cbf61,70a633c3) +,S(a2cf1392,571e758e,6ec74708,dc45f70f,90833ad4,135e7a34,9d2810a1,8efb5216,2420ffdd,afe96506,9e6f9266,1e3839ba,c9b1db40,d40149ae,3acc8683,86acd175) +,S(f8822204,27cc4b37,33268925,fb80beb5,a52e5391,b2c8e31e,f6e99592,1775af20,6cf6eb9e,b19825da,6edc5d2a,66f3987d,c9eb01e2,b70e6395,abe2903,d43acee) +,S(eea28950,fb676991,444f96c5,7e42ea16,aa380e3d,dde63111,fac35708,a4e45b3c,34d30722,98a686ec,7e1a8095,4e2911f1,5e11d426,ecacf11c,eb45a5cc,7204114c) +,S(7f252a72,6f9a1497,f61bc4ee,7b194a31,432c0178,2f40b16f,2d36e9c3,7279e25f,8edf25c5,f50c6f0d,f8a17f92,611bf024,14e02d0c,de38aced,e96d5a7f,4467c449) +,S(d3da23fa,56881cf3,a42a50a7,42e1067f,54ec24f,2de19921,b1ae7f15,fb90509f,b4ec4b17,8e555cbd,15210f09,bd1ab43,28e458fe,6aa3e800,44bf0093,ea08f90c) +,S(6752f294,f8ad85e9,60b6a88c,cfca7874,5c80ed7a,93f6f05,3782ac73,d96e31e3,976222ef,a6f6358d,42d6289a,4f11bd65,e7e755a3,845ed49e,3c972b5c,5fdb2418) +,S(4fe21b06,24a45b69,7f42aa54,10e6385d,645a8d49,2a61ece5,c8d5b2ad,1fe74efe,f7666c09,7caeea3a,c4b2993b,64f4c0cb,ac934099,8870ade,b7cee48a,c3c2c413) +,S(15af87cf,6dc1acc5,1d323a36,b2daf163,ccc8c201,a92f0677,6a26ae27,7fb9d766,53fe4566,6a975d35,ed20a5a,7bbe63c4,4cf8011d,45e7a171,d5d72e57,5debefbb) +,S(656f3686,c60039b4,4c39a5d3,ee82cd08,e8aa8ed4,b9a943e,42281407,4ab6821b,9f277baf,2da730b3,dacc2a43,512411c0,13ffca65,7092e695,d49c8d24,a4cda4d5) +,S(a13286fd,2c17a61e,6bf8d209,d64f5879,2534b037,cd854470,a09c8c8d,95aa0564,9322d3d4,c735a485,5d76e5d1,fd27fdbb,a8af2fcf,ddf7bdf3,f9e26f97,7f4cd1df) +,S(3b355928,4ddb285a,1eab73c5,6e6bc554,9f40d83a,2b859e01,a30032f3,a5a7109c,780670b5,67755fa5,10fc3385,7745a69c,bbe73e3f,8186b3c1,8a82c51d,5e1d9be0) +,S(b0b15be8,6c2dbfed,6da6e7c6,51c10b17,504070,7d1747c3,ff2dddbb,256fa495,8d2c438a,42750adf,345332d,f02f6c4,55a07fce,afcc51e4,96c270ff,913546e3) +,S(c754130,bd717ab0,fc17e14d,dd6ec50d,aa6bc02c,a338cd9a,798ee62e,72d517db,fddf938b,28500dd,c9f1fe0e,70104564,d1bad398,d3bee900,ff609c8d,f56d3b26) +,S(ee615579,33d877e4,9bb228e3,62766ada,8615d382,c022c333,39f78ff6,5e5d9ceb,3dd38b15,5ce01a1b,3d5434f1,b2e04a26,6a830f47,fe89263c,b0ad1b5e,18bd8b76) +,S(f830dd7,4d03a39,d7f5ba3d,132b40bf,130b33cb,9b6609e2,12b6479a,14287c9,9183a68c,33c2d25d,c237f8ed,b5a63d44,4dd2bffb,d1255631,221edb9a,4c9e9e91) +,S(544fa477,3aa3589d,9e63c8f0,f30cd189,a8b6658e,ba908212,cb1b4caf,2d5f64ca,bbf57d7d,b5c6b8d6,e202a7b9,8ed06edf,e1a9ad01,381da1d8,11405fcb,8ef717c3) +,S(9b270440,132f5b09,6fec6214,dac1e27f,3e6c6f7f,25eb2cab,680c3fea,e0b41b1e,a7e591d,eb990617,6bc87263,6ea19e04,c9a3aea9,59059078,2a757fd7,6d99c6dd) +,S(bbd69c5f,f0b9228b,cfeebb97,32b3c316,c14d9a54,d5a3e9ca,ebb337e1,e33525e4,78cc6c84,8c246e7b,7636949d,4e3f2b94,989c77c4,812b8189,cb857cd1,3457c403) +,S(a920edc1,4ddf5bda,56719c0c,2adaea7c,9aa8aab9,25a5d6fd,41172725,bc65341d,b8afac74,46e560ce,bcaaf438,69dc9287,2805fc14,122cb19a,bb59e51,8336ff80) +,S(3c6e9595,a201956d,ed27e83,41b22822,445148e6,d00b2fcd,ecfdd66b,2405ae3f,2b8ef9a7,d7c37d0,d2b77309,74718eba,16f221a5,f3074678,317f0b6b,7b0841b1) +,S(c35c9e45,3f487f8f,ae5b6010,e1bc1ac3,ebe4ee53,33666876,13cc4b35,5162ed91,7a8e64d4,9f827631,579421ad,3c7f7ea1,f4866432,a341f955,6741c521,c757addf) +,S(8fc84331,a8f8dffe,28f30d71,b39c105a,ec09aca,4876241c,1c81a223,a1953637,aac7257a,cf0fce3a,ff8fc7ea,e8d19606,2ba6d7ad,9b7987bc,35a92b9b,20360174) +,S(b43ca4ce,f1b4a2d0,1a20fc64,2f3e1456,317f729a,1ee69798,4ed88bfc,1c5a2908,39ae1e51,f352c0c9,8a79cca6,cc859eb7,92bad6ae,5318f99d,d62d3bd4,d8fedad5) +,S(7f29c501,75628aee,5d39db41,cc4d89a6,9f133f00,47500f6b,aa7a90cf,e13159d2,cf17c6f2,f6072b50,257f722b,5756d8ad,c7486cc1,d21a925e,8cd29a15,4b514cd1) +,S(3fb93959,55ea2522,61b0488,212e15d6,b28e975e,5ff5f357,15337538,247f2a54,7c3db409,e06d6980,d834639f,e9e357bf,e6a4e9b0,ae6b4fb8,f5e45143,ff625ddd) +,S(945ad871,18199665,a4078a46,a9596bd3,ec7cab84,b6323a0,7ceefc63,d7ba29f5,6eb6d896,a24d02c0,630c909e,65d13d4c,2eacf1ef,6e600b89,1b171594,aa28c206) +,S(513bfa93,57c827c1,b3c0289b,c4ce443b,cadfbef0,b28b32a9,265ab85e,67efaf4d,645c5b3f,d45030f,1aaea514,baba7069,91def89b,56fdc292,4b684241,6653b6d2) +,S(d41b35bd,421ef7bb,1c03c794,477c2851,dee92831,714180e6,6e57e735,caba5835,beea2116,9cf971a5,ffd83596,d9bd77eb,cb1e0c7d,506a45ae,be8c0c7c,22738f9d) +,S(96006d64,fac8f0de,88f93e05,da8e76e6,40afc1b2,8ee09a7d,5633643b,d89ee3e7,1404173d,e96a97e9,ae9bcad5,c9093d05,cba96479,30bfe6d1,96664d0b,13c93618) +,S(ad528227,12257f87,d1ef82c4,4af5f046,648c2a72,497651bc,2327e971,1170e7bb,2ea908a6,c742f542,324be959,4746ee48,4229d497,cc8bd535,e7989525,aa36f079) +,S(b4709a81,c067f6e3,93ef97ab,c26675da,6f01a2f7,e3f35275,e7089ea8,ad5644d6,f655b89b,d6a83838,ffd23f6a,fb944bc0,57fe7f1,1d321a0d,2152568d,91751d99) +,S(3b7bc8ac,5ba85b40,2080612a,84e0226f,3b43c8de,c0e54b6e,ea779b76,812782f0,8405dedc,a02825f3,5a60333f,190001fd,98ea3995,9dc6e61,c28c5e2e,5213fb0e) +,S(2a76b67,d197e7a3,7a38bb10,d49d523d,c4beb4a3,75336974,7e22e407,9e0310ca,6331389f,b9cf9fee,e89b089a,95abca6b,a3c2aba5,38725c1a,6848fa46,997d0e87) +,S(9938e808,77c2baa4,53e0256e,d250439d,b11732de,1abf7555,949a7574,f62819e3,250b061f,bba0faa4,468a080a,fee8264c,f72fc12f,2ac91dd7,13ed92a1,1b281124) +,S(7366eac0,7e5e4573,333291,3e42f111,e53a78a6,5069898,52db2355,de089230,b8dfda33,31646343,bfb60b2f,25050967,e735861e,1654f0f7,ff42ed9,5dd652a4) +,S(10fc632c,cab22fd3,2583599a,a2efaaf1,6e1b01e6,a5a96c59,50871012,33022152,cf53d9ec,c74aef44,7019150f,ddfde494,c2382a07,b2dfd73b,c628478f,7fbae0eb) +,S(785f4da0,240de52d,bb50b1bd,bc53994a,47318076,9a1fe06e,5a40a8e,e677ce63,9b5759d2,f77bbb9,e40ac169,a01500ca,6dd6bd70,6a003871,e7ba4d66,b32db9e6) +,S(a7f20615,593850c3,27aaa06f,c03e0d46,d3ff20a0,9b849810,1759638d,8cbb9cf,13b9ebb6,f0cd59ef,54e0f935,87a14fe1,2337e346,94f5e8f1,10323fbd,d7604d3c) +,S(cf083e4f,e0ed4444,85dbd99d,8e6823bb,483eb749,b94ce672,8671de8,6105aa4a,36eaa305,37378494,17050dc2,8290c74d,d9ff9df4,cbfa434a,2b89de00,e06f3099) +,S(9fb8c370,bca485d1,dcadc251,ee906f58,6f3e177,be37baec,6912e535,f5c7ab0a,df5cf77e,1ad07532,7150136e,7ebe7f35,1db47415,74444b24,e9cf2f4f,31ec683c) +,S(ff9e2f29,170dd456,2c94d48c,eeb0390d,db783702,c13574f,8a8c6a79,6427adca,784c7b68,3c824603,5077911f,957aa33b,47534180,d70a60d9,f248b860,736a24c2) +,S(802343c3,e07f9f9d,ed2ca436,3e455427,367b852c,d23ffd7f,fd690eab,90b4162a,b093f0c5,f0fc7d01,a5dfb7f6,bf9d90d8,8595140a,a13fbfc0,f7d6af2f,54ff5ce0) +,S(ae74ed87,11a1a684,9e558e05,47ff8f9b,f6337551,1dd3d272,ee0597fb,fc2d6914,c304897c,e5afb5b9,a383cb64,e85071a3,cfbb2981,93ea6ce0,55257ba4,cf15bec6) +,S(c099b05a,dceb601a,14892c97,7b267152,f29ea71e,fed6090e,7267249e,43c2390f,6c3ad3eb,8c95c72f,e0030a7d,34329945,fd1eb71d,8c4aa1f9,8fa4656c,6bef067f) +,S(97c6949,a25581f5,945814e9,9d590dff,67d936d5,94101005,4cac33d0,fb3658a5,cdc7faad,5bc387ce,a16a10f6,6971e5ee,6d32756b,596adc14,57081ad4,1dbd2e4e) +,S(14a19edc,a1ec89e9,524548ef,cf3dbc03,81b14b46,928f7425,87b11df1,7aa721f7,f83c4d0,aca08709,63a017b6,8db3434d,6088015c,2ff1d8bd,739fd620,35d1a19e) +,S(4742af63,c7597424,e6d04a8c,cb43142c,54c5b350,175bf5a7,27c39820,2187d00e,bb1f2f72,b21e15f,ec17af32,2147edfe,1ca80ac8,3e030dfe,8be39fdd,f340c56d) +,S(a6597869,4d168b00,d9df41de,fcd48ae9,68313394,db683407,330ffae9,f2559a11,6bf65c42,13317a5d,fb561e8c,872c8b1b,90bdabc8,8a8d2e1e,39919f8e,5043ced3) +,S(9e62e468,1e22abde,4d7a2fa1,2f7867f6,ecbfc15b,54990e26,821a8cde,fed76985,4877297b,a64fa8ed,c039ab1a,e62ac72d,8d7bbf05,7513d1,4237b8dd,9f1acd37) +,S(d24333b4,de55b0f5,d47c72e4,88cee8ee,8c960903,260a64d2,c89bca45,db7352c5,688b20b0,617ac12d,5be38fa2,ab52e785,69766a83,2d8b44d5,cfd6ee88,b19b9f1d) +,S(d203301a,13d1c8ae,a8c79007,1ef8116c,3916bb3e,dd5110a7,304b9145,465be838,a606dcea,398dc313,e61c8fbb,dbbc3874,3c103297,164e66a1,4412a21a,5319e55c) +,S(d1aa98ab,7010146f,16a9d6b,cd911535,2595bfa5,1bccb3d5,5e3a4a87,62666610,3abafa4,999294e8,80e3fae9,edb4206b,9b9786d,bddcaec,e2d01cf1,ab715690) +,S(1e20823e,81051b2,65535085,9aefed6,3631dbe,23b4e79,abd3c17c,21f053f4,e238adb6,86592008,f7fe34b9,9b934060,15c323ec,55981b27,85feae6e,5fde7186) +,S(d878afb8,8527a861,4b4276d8,fba39300,72196017,6f437014,980b7bbf,d4320ffc,7403107b,fca8ac64,baa94a4b,128e72ee,4a015675,845519ba,d5609331,1680e7) +,S(53f86d45,61deef96,ca88a685,38fd35ec,a95740a4,3a52c601,faaad0c2,aa3ab72f,667a6ece,bfb97682,c5e9e5df,b6d29156,9604f63,d9ab00ab,8cb10000,e6b01514) +,S(20990660,f1055420,b885fb0a,38824740,3b141c37,5aa20dce,8a29191a,e77bbb16,7d434476,9e302e38,9e14c02e,f5fd8a5c,64cfcf3d,e9813f1c,f53bc6d3,4da93559) +,S(1e70619c,381a6adc,e5d925e0,c9c74f97,3c02ff64,ff2662d7,34efc485,d2bce895,c923f771,f543ffed,42935c28,8474aaaf,80a46ad4,3c579ce0,bb5e663d,668b24b3) +#endif +}; +const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)] = { + S(8f68b9d2,f63b5f33,9239c1ad,981f162e,e88c5678,723ea335,1b7b444c,9ec4c0da,662a9f2d,ba063986,de1d90c2,b6be215d,bbea2cfe,95510bfd,f23cbf79,501fff82) +#if WINDOW_G > 2 +,S(38381dbe,2e509f22,8ba93363,f2451f08,fd845cb3,51d954be,18e2b8ed,d23809fa,e4a32d0a,fb917dc,b09405a5,520eb1cc,3681fccb,32d8f24d,bd707518,331fed52) +#endif +#if WINDOW_G > 3 +,S(49262724,e4372ae6,f6921b82,aa4699a1,f186aea5,40122630,3ea42648,97c2a310,1337e773,bca7abf9,5a2cfa56,9714303b,6d163612,a75ff8ce,c41b681,5e27ded0) +,S(e306568c,1a240c90,d5e253b3,e477e2f8,4dcc1a56,ff06db8d,1384b079,cebd2d31,eac6fe3,78934260,888f2b10,7f7d0db6,ffbc8042,be373826,692b4083,92546e44) +#endif +#if WINDOW_G > 4 +,S(3b9e100e,2428cefc,271b0e76,23fbd633,74ebf8d9,aab41dd9,c530c39e,363136b0,fafb9815,2d16bb71,df1533eb,8f475b26,a2ae28a3,3ad31f81,953ec16f,6cdbbc8a) +,S(bb0aad49,712ac9a9,2b76ca80,f5dedef7,17ca0768,8107beee,9608f047,2f485d3f,ea699c53,c5835479,8ecd201f,7297da34,895a5afa,31670bff,e7939250,3ca2f975) +,S(79090ac8,e4eefcc0,d4e8eb19,7afe0113,e1e58b4d,b01123de,4aeed33a,36718dc9,eaab722b,91905b8f,13d816cb,cd9aaa56,dd36afb7,ba9008b,963322b1,1cfae7c5) +,S(e77c81ad,e9f97b55,1c03dbbc,e549ba66,8dd71de7,cd775ad2,a269694c,7f60c7d1,3acf1478,eef81321,c5fc3b32,3ea81543,631470f7,1c2986d3,4ec581f2,82d72449) +#endif +#if WINDOW_G > 5 +,S(de2b5ce9,dbce511c,f2d8878e,3ded87cc,3d633dae,a2d45341,501fb3a4,55ccf6b0,f10576f3,d3c3e0e1,bbf717e9,8b1a3744,65b8c45a,c66318bb,34829eb7,11100666) +,S(d07bddff,d491a2fe,1ea59fbd,7c121217,29659ca5,de46658b,26b1460b,13c03c56,b2ad4708,cd3c97dd,f9c40e2,a1de04d5,61d963ff,8cc2eea7,6be3f60c,2b405ce7) +,S(82403e7c,5d3016af,3765ec4c,396ce8e1,f8da45c,434b8257,10edab41,bb6a4d51,d09661b,e27cb767,4456badd,b3e84051,99ab6ccc,4ec67c1b,11e92ead,7b463b19) +,S(eadc3131,fbd626f5,263faa58,c4caf4d9,930f933d,9541c23f,438cb486,750680cf,d3c977b1,c9b4a897,5c64b36c,972d5d01,a388fb9d,c3791a74,36094ff1,2c87a914) +,S(3903ee5f,6758ff24,c518a4b3,86748f4f,36bdd65c,b77e78ac,609f2909,fc7987d9,e92194e,a15241d6,40915934,bd234749,8d222a18,4927a8da,b0cfe2ae,182be83b) +,S(d0803b78,39ab48a3,8475bdcc,f9a9f219,5759c343,dbbf8e93,23e1f882,5be6a5d9,2cc3b180,ff29c97e,a12ec15f,b38bafa4,4ecf06c,e51d1d24,2894a926,64582f0b) +,S(1f56f096,b18a7499,a153a5ae,acf8be05,8496dd23,da8e6c19,215628fb,c0567ed0,fef22b8a,3b52f490,83004436,b65cd69,c94189f4,1a93c0d5,1fc13cb4,379dff58) +,S(1d9f69b1,a4a47432,e386f525,234aa30,79e947cf,cf203297,4e0fc05b,638e213b,d898ec17,949c0761,b38500c3,a2b1da24,5438d5b3,d3f6f720,41f15d6e,e4d4ccbb) +#endif +#if WINDOW_G > 6 +,S(128c913,4d9dcb78,12fc4361,5c67ad0,55213354,dc8008b1,aeb5a9dc,fb629efd,fee3e54a,dd152610,d9725936,99d662,c160c8e4,ec6f76e4,5ff41818,be67c96) +,S(21ec012f,5a95b94d,244b8d51,9756075c,301f2854,8e2c51fc,49c0e3d9,d1a9685,2def2105,77af497f,4c7fef71,6949f28e,7418eda6,fd5fc162,d128de19,3cde08ae) +,S(688f5202,fb9d8bc0,9e480e89,4c7cfc74,761c3be7,7dafb11c,58422836,3e331cc5,96ba7d59,63b541a7,2ec7cabd,92403434,1a393eaf,89eebd94,62d9c218,c7302cd3) +,S(fb5c9eea,1cb9a8f5,b3314c30,a50d35,744d0ef,e8bbf68,2e4d3ab4,f7f02baf,29fb8844,e18fc551,fb28bd26,95c5e95c,6868e0cc,7e526af0,91157e9d,fb630418) +,S(f1479fe2,2eedae3f,2f5f6a5d,84a9de1d,593168ec,7b52380d,e0b3625c,cac03421,1a642d5d,2fd88b82,13b50d1a,3fbd3419,c0b4630c,48352131,cb856b2e,22764606) +,S(2273edc5,e8199774,93c5b0e0,9fe0effa,f60f7b,2898565a,69f5c7b2,bf1a7950,b3aea238,8fd978d9,29f1a1df,98495358,b64691fc,4f50b530,906ae39e,fe7bda12) +,S(99f8480c,30504378,b47d10b3,2b39da2f,496d59f4,b1462856,56f05ad7,9bef5214,e001d55d,8e224286,8d8bd397,cb5aa99e,d930e437,e4e62151,71da7ae6,6264b2cd) +,S(382257f,e4751280,d74fdfc6,993c8642,9c000d5,87f57635,bc9656ba,996a6f1f,c2dc733d,fe52cb06,265a4f1d,a6b5f1f9,30dbfa39,e3659973,1c672aad,8b51d474) +,S(23a13632,9125386b,e45f4e1b,2acc847a,62e5eaf9,f6d5f452,6e145e7f,ecefb24b,9129777e,643ba22,2bf817a1,af7155f1,413cc370,3734ba6f,49f15f55,996854c0) +,S(6659ea60,58a664de,a35791a1,8c5cded4,8cf5593d,c440b9d4,8a30ac35,79149f0b,2adcc705,a85d836f,b347b69e,742fc6c3,5300d1d8,e534f1ff,c820c6d6,b2f2199d) +,S(52dc3bc6,e1acd3b4,7ece6f6c,89fd2a3e,2899b487,41421033,37a67dd,1ba939fc,5daeb346,32ad107f,bd83d9da,15a3c4ff,1e8f6ba3,ee5193e2,709e89c3,43d05746) +,S(524b2a97,93cd5745,bd9189ba,9c947bc1,693fbceb,75f074f6,17376b10,d5573551,9e8099d6,cb23fb1a,9deb92cc,3e8a2fb5,a6865ac6,3dececa0,2d146e1b,bcc80b71) +,S(732181a8,e2bc5953,923e6c3d,d960e9b7,525b7b95,e5906997,6fe79156,1782756e,2516c6b3,5592eb0a,42ba193c,bae98ab,e3c42d96,148f1d84,edac621a,722e4823) +,S(b8e8942d,926e38fd,f338496a,c2ef6fca,49a7ae3d,f76eb15d,8d570111,e502664b,7990d56e,7dea588e,4d670ba2,2031e6c7,97248641,69e51d77,f792f5ed,befaf8eb) +,S(144e88f6,3e73abff,72cac11e,7ddccf79,19e744e6,278941ae,18d1b797,e098e4e5,63cdbf3,5df3c655,c58197f,ea54633d,158705cf,7dc2eb3b,4e09f83c,3021837c) +,S(9436e3dc,489ecd8e,2d16a739,c9c73e3d,60e5bc93,68157039,75b8efbd,5c3a9081,1460531f,50cb6ebf,d1aa7806,ea84e7f7,8e8d76b2,b3a66d5e,3a0bf60,39a7e59c) +#endif +#if WINDOW_G > 7 +,S(9d3c2561,7a56d10b,46d9b01a,1710d193,e840e005,df669e76,1936c275,20890db9,6bbdc0bc,4c4ae9bc,c2dfee9b,82da9b94,1f89ffcd,e8af2aca,4467ce3,78521ea3) +,S(29f98e50,f51b7f8b,e18c6ae0,b453c4f2,d0aca5a8,b0e61d2d,dda8506,3fdb76c8,daf3bcdc,ae8e031c,73eb8b21,14058063,58a6ec30,ad379186,df80e3c7,f0e5d28f) +,S(d67d30c2,c71daa36,1805e31,1dd6046e,17a89752,94d76e1a,538af074,4dc22c94,48b9b0e7,12c807b0,b92e690a,a2e068cc,e87ebbbe,aaf4bd96,9c1114bb,a54f670c) +,S(f22c2ba8,8ce9c2e4,b772c9b7,6d03a017,59aa7b9,97a78334,83566027,2fc81649,6aa9e710,f190be16,243a4e0f,1570270a,2d92dca9,8cf99a3,cbc06fdd,f9b7028f) +,S(c5e718d,6b94c83,e52533c9,ef3234f,36b722ed,cfc074a5,eff30969,9ac5f894,24961051,ccfc6619,dd64e810,fa9c504b,f7f8ce9e,cc445d7e,642b3166,eeef436) +,S(26a8bcaa,c836eb7d,57618999,ef87ee4e,c291dc8b,333554a2,c1f66f73,7944d611,c20051ba,7236663,ace2da29,c1e0763c,e57192d0,e199e7a6,c69cc65d,bbbcecc9) +,S(388e3570,fb7b1545,9bf01ba1,7a6496d5,6bcf65e1,764e7aa,2c083346,2dfa098c,2d4e0d22,a2eb0ff0,545561e5,ae344be6,99120d12,45db6bde,a9500f5f,a07be798) +,S(68189bab,b5a0783e,23227efa,4eab2c6e,da2d1c,2ea57fca,7a7f8f72,15250709,bd30bd83,3694d3fa,a14954f6,251445f8,3e42d517,30d30855,a0eb834d,3c7ae856) +,S(642e0823,bb347795,967b7aa9,418a25,ea6ff683,fd7b3d42,b88d90d1,292190ab,db73dea7,86ec052f,e3674892,639daf39,286b4690,63b68903,210639c7,f3b4000f) +,S(9ab6ea81,e5bf5505,751addea,5896afab,7f4eff2f,d3986027,f916835c,64924afa,38c06aa7,4870a5e7,2ff29efc,bce4b3e7,dd951c9b,29966f2b,47d007ac,7629bb6c) +,S(b09805ae,e567f69c,71a98248,e89e64f9,e059e015,bde01a62,dd18158e,e94a8ee7,62aea16a,7ec912ef,cc5382eb,6d220ac3,dea885a8,e3da12c,8147b28e,1983d221) +,S(3d632a5b,636ed5a3,4a58bfbc,9831691a,91d6b5f0,975bfb5a,82b4c1bc,107e6e5,577a449e,75bf16d9,2eb6ba0f,9cb4d496,7a7ee09c,f1605aef,682cfa31,cf395a1c) +,S(6b821bf0,f70d5ff2,ceedb69d,d96ac8bb,b51e3635,3a36d50a,b1c1a697,40cef707,5212ce11,993fc120,88028674,5cddea94,6371b4,dfa2f47a,6d83b789,c6d12e5d) +,S(bf294951,4496fe0b,8527740b,5cd9394e,dc33b330,c91d996c,789db854,45728b23,790aede5,da35ce7a,343f745c,410de38f,4c53bc2a,bb41bbae,c13272b1,e912782c) +,S(a55354c3,82bf968a,16668267,c4498946,4906f69b,114f6f06,742b6035,1d75ec80,2809bddc,45661a5f,28b31967,6cdfb5b1,9dd6d296,d1828c88,179a630c,ca5962e8) +,S(fc015036,abcd8311,bbfa1574,ffb4980f,b893f8af,84f519f4,5a6fa344,2649a693,d0f6a278,1946e04b,385cd004,29acd3f6,f5542aca,3e7c789,657f676b,f19db819) +,S(6164410d,9f81f352,272a799f,b4afbe24,59caea6c,511fa4ea,b7578980,d9a7aae,92bc1480,ba19fcd,3cbee69c,95b9396f,4982fff5,d4e7dac0,abec7153,ee5a7966) +,S(ef816535,8de9d737,728f9a9b,3182b4f5,6e25917d,1ec05fc6,faa0fc85,170b5f2d,dc372426,403ca9c4,50649df8,8b6fd32d,f1721dc,cb1c7d7e,155c83ea,747ec595) +,S(428c34b9,89a436dd,dc704e68,170d2c40,178c5646,841eb2e2,642c0a48,8987a8ed,b1f24158,251c4646,ca04dc3e,64369634,3836f97e,71945f4f,51237abd,3aeebe06) +,S(6eb61782,f909157b,415e6243,7bebbd6a,5f19da73,7eda64a5,5acfe206,65417a9e,4fe7c546,baedf2b1,6c92f168,f99c42f6,af03edee,290ecc39,4c4efff,e8577b72) +,S(992e0af1,466d4fec,5ef83009,98ce31df,cb6f9573,d14c1646,e4371c62,a376fa4b,d0e3da69,1e4396b2,eb01e3a9,964365,50d000e6,31d79ae3,871690d5,29f9e825) +,S(fedb564b,adc70078,f20f31d1,12496934,513e9903,8cf5b9c3,1084383,5721d11,1a8e2a49,57e8420c,f2d5d97d,657f1602,ba26ae87,d5408b2f,a9448def,38157a39) +,S(f3f2068a,4dd89d18,1247088d,3c424916,3e683226,6274b575,e54430d0,73b24bd,f2aabd19,a7f462,1426ab1e,e0aa7e33,12381c5f,e1f1cf0e,75c1a7f7,7ba2bfa8) +,S(32b9225e,4217a359,8de4e7c1,476a8581,5b6aa458,d93dae02,b3d30772,3ca13680,7466e804,26856340,12985683,dd071e97,53246214,733808a3,96f35d0e,5a133802) +,S(85008a87,385ed6b0,4ff89979,2eb592f9,ee6c6b93,fa24dc7f,c6299b9f,dae64a8a,1f279e2b,8a5b0576,fb9569f6,c0825876,84b5b38f,a250e362,2ae6e284,a504a2df) +,S(4dac7833,ebbeab0b,ec8edac7,cfc49bfd,b835362,f0130e9,e44452f6,a82effd4,fc9d1970,f230aa68,6114ada5,7b4237dd,133dc3b5,db8ec1f0,ccd09aa,23c740a) +,S(9b755881,45a65d54,19b40226,e535df5b,4b44de41,1b93d71,31f3102,d56dbeeb,d0324171,d6937b7,c9b38290,7dbba3b5,c1516061,59e7ce1f,a1ed9d11,e089a02d) +,S(1bd6ceb9,2592a7d7,a66e6e8b,1b645db5,98b525ca,461dc4bd,b583ed9a,cbbc8bdd,9a59de87,84a98bea,48b7abb1,a5b7055,5a1c4ce5,551cde4e,7b790ac4,9a29944c) +,S(25a8b2b9,3b360941,6525b08a,7fe786e9,6b3a3c7d,8b444637,268f5355,bd5b56ee,3c58ccf7,5734687f,dbd027e6,3ec6c550,45f131ae,df71a40a,c45e4e8b,965f22ec) +,S(244b2833,27c33efb,221a5767,15225d6a,bf5a1caa,8da543c0,d88b21e5,17ed9f5f,220036ac,e48d8953,5aecec92,a29f5012,37f83ce6,44380db,c229f0bf,c1f53d7d) +,S(6f97ac0f,27b87905,6b442d13,e566978e,91f0cc1d,d6ac1e64,e9764a35,325dd1b7,83c6e70c,fac6c707,226ce1cc,691b38a0,7e937f5a,5f2d9c81,4dd0d3ff,9f433d32) +,S(72c5d60f,eb014e2d,ba8265ca,d454f261,2d6abcd4,b2236bad,c94c4801,561dce1f,e3119a19,7ef91963,b3b28216,3c5d3acb,97b281b6,d246cbf0,690b40da,63978fe2) +#endif +#if WINDOW_G > 8 +,S(a96d2da0,1b10186,6998659d,f441a1b0,2af32b94,aae8c6ea,707d9ed0,d5f33825,660d7d83,5da5235,9f7cfd41,28c370aa,5659ea71,16a91690,6c0e8108,a513f9f) +,S(2cce6f63,4d815ecc,1981d200,87616677,d906aa27,990c4875,17314dc5,5be3c4fa,615210dd,bd599e91,1b6f997a,fd05475,b33cb274,c9ecb6e5,d3c23323,beba4b50) +,S(992b0084,525dd399,d98602d9,8b8d53b2,4558fafc,758a2f46,60e89bd6,a645f0c4,83ca98d2,26545a29,8c45f40b,11420602,f5a5c70e,595eea57,2da64d61,a4e2f98d) +,S(434efb45,3089619f,cc761ee4,3fd4b77d,c6b0c69e,b45eb88e,44ef766e,9beb7357,3dbb0d6d,1c0b92e,5965586d,236c0be9,26967ac8,830b9bd0,1e9efc2,2a9291ea) +,S(a2179ad,2c683306,a2e4735,93efe304,f0dbf589,c4dc2b88,4bddc5c7,e3fbc156,ee4539f8,ab980176,a18e6dfa,bdb609d2,88a2d223,86dcb20,19207afa,f6033c1f) +,S(3934081e,d3e1e147,aa52bb40,9221ef6,a445f22a,66718f14,6d63907a,ef05a2e1,bc370656,31391b7a,209e79d4,9f1e959b,d3a9fefe,752c6062,14fab290,a7b5b3c7) +,S(35bc24e1,59a2b939,438354,6cc4255f,f1f3f7e2,105293db,39688e07,df95d8ef,dee1fc70,a9698da,f7abeb5c,56724f8,e87e0cd3,8849edfa,246ed0a8,9223ae15) +,S(f5d1e75c,251fb473,8552a0ee,f05d8e65,63aa14e1,bcae5b48,bc7e5258,b948127d,e260c1bc,7044f058,8f409134,d298528b,e7d586f4,bf7b6fe,92d212a8,6f7170fe) +,S(ee0a76d3,6fed282f,a1170dd,6acb7743,f9617bb3,60350f54,d12da1cc,7eb121c,f8cfc2db,eba6960f,e6135ef,ff9e10ca,4e56c458,4b42b516,6dbf7af1,420ba5b1) +,S(9e3b87cf,78927664,15cab377,f1774d14,4d1879f6,16da5676,f94790d1,9ca689d8,f8f34522,da3ca2ac,b273b0c2,b1b1f26a,7a9c2d96,b4547482,266a8e6d,bab3b577) +,S(e26f256f,d08942c0,3c85b89e,e66b8b50,12f409c7,4f625152,86e5b310,eb4868f0,bab3c4d9,6fea49fa,6d08c656,23c9b127,3552c23f,3c4f12f2,1bbe8bfb,56f210f9) +,S(8ac74046,a5d38398,d14b6763,4f07abc5,a3f5c852,ea8c421c,f0858980,11da6c2,d20ca793,f56e3198,854f5916,35402c2,4a71af95,c84288e,1495d324,7229b3dc) +,S(5b00e095,634694cc,93d531a8,6e81d29e,753928bf,b2c83a83,ac677a92,55932bd0,8d2f267a,8071c48c,616daf18,d587e,42882b33,748032d6,4bc3efd6,60a99656) +,S(162190c4,80c5d7b,ab1ae4ba,7b2a6611,546ffb9a,b4e9ea87,2c0357f8,9e11f0b1,db5e2104,12448a9c,e586d7a3,13bdcc6d,bb84192e,98c5d9d8,79693030,92423525) +,S(f6a84421,b4b383e8,87f8520,e06017db,476774dc,9aff636c,f26a676c,85b145b1,504c71a9,596770ed,7a2da8,2e8fe1ee,93717215,bf88e0a8,ed74a80,4037a3b3) +,S(1f02d142,f0b5d3d8,b3f8937d,a49f908d,83e5919e,55c9c134,55a759a9,932dd6e5,e6a5cb33,8ed36df7,50ec2eae,5db7c9ff,fbc9035f,48ae0348,fb3882da,39863e65) +,S(61f4d96b,c326a1fe,a2ae38c3,73484a56,68e29bf5,12d77a04,34a62278,1d78899f,651ef738,62005ac7,64f97021,6180c25e,2172724b,375e6b38,b3a37ad2,d7b4aab8) +,S(ba7d5c0d,623c5e79,8088a71f,8d2916e0,7c7ebe2b,1afa19c1,9c917cae,31c11616,da409f40,d7e3f6c,78655153,fb35595,a1ec37e7,e66c8958,ce45b07d,bd5f5a51) +,S(8b90a590,eacb977c,6e6a68ee,6dbc3e19,fe5a92a6,9abc43c3,bb16f9d1,925bdb09,a5cf5f42,ef655d59,ae734e1,f746a752,4d01ef75,d829b9a9,2a035180,fb5df718) +,S(87f35227,21914cfd,ce8294a3,cb5ae171,f0d994ff,f55b25b7,1c9e9aac,dff4fe4c,cc71d1af,530bc5e1,eae7c1ef,b9a91335,f26b283f,222a3552,dda24c28,64babb2f) +,S(aeea4d36,ba405159,bf0ffe8a,5530f1f3,83d5509f,187ef58b,6c1eee4a,cb77a15d,db563dea,e7403df8,7d3031c2,48aaa28d,96958f7d,ce36b3f7,8d55607a,60d3ac1a) +,S(300fe98d,3996eb9d,57c6f1ef,8058d4c,d8dda436,5774edb6,2a338a59,afcc7111,d148a017,8fdda40c,f937913c,143b76fd,d2e6e226,d27225e3,a49658b2,38c40e77) +,S(c700af5e,22cd146e,839095a1,f6743e4f,d01e9c1b,76d4c73a,a5005f42,99c19fdb,3fe00181,b1f01c27,27ab1fc6,bb6ea569,d4a3092,c2d511d2,8b5546aa,194b32c0) +,S(d03d08e1,17b94138,1aa147af,38448539,94228f75,f96bb4a5,941c3748,cf50bc60,5b119ffd,2785bcc5,2e0bfbfd,c541da8d,f47dd076,e91440fa,10e071b3,a896e31d) +,S(6c6710fa,17a520b8,56d7fadb,6af81a5f,ea9c983e,c94cf832,b395da5f,c22bd361,db4efd26,36e281ea,419964f3,c0897b05,b036a408,25ed4ad6,4fba393c,f2804941) +,S(d7b5c239,9df47a16,6b6cb900,d08a5d9a,5ea3bfe9,94f861d9,b46f3fbd,a3d91bbb,ed791f4e,4ab1c25e,9c83494d,794ffe1f,a3c8a065,29c0b710,cffd597d,64efe8ba) +,S(90f699ab,8f728152,e2deb8dc,ceaaa3ee,53ff2f23,2341a952,4aba9e8e,50f66c06,8bd0c3a7,7f5312bb,9d46d80e,c36921f8,561558ce,6e63c08e,641c82c9,fefce91d) +,S(4d0eae3e,3d7adc34,c91eaead,6a16f569,37557dce,2b68744a,bb9ae71a,8dfb65cc,816b0806,a9508731,ba99a685,142aa52e,6e874c99,5096a53,52c6e2f2,1fa3de5a) +,S(46cd9edd,ec318498,dfb4f815,3315185d,689a2399,8e06b1d0,2438f7c9,b2f7de62,3b5bc1a3,d5fd7874,8c964a8b,b813388b,e0d5d168,1247d008,10a846fa,561f29bc) +,S(4aac80e,3f6eaab7,1c576297,b4552e40,653748fe,21a580ae,bce4eb83,2ff730b,3d42a00d,8014f46a,80fe2dd5,bac6a046,40d331a9,4f1de050,9e435398,6c8c7954) +,S(59bea661,b73d9c09,131e4573,199937a,e03e96f6,2ecbc637,4bb681a5,582a4114,31a20be8,ee8a2c2e,81d062e7,8e891504,d9f2639a,bd5db5c1,30be3d2c,b1afa47d) +,S(7fe9065,88b2ee92,2b19acd3,fec7a4de,9ee089a4,a4e1c338,5e293567,90ca6037,dfb45d90,c5f43eeb,1f5eb326,20763ff4,2659b763,e7ec72a7,c69e9369,35e5c128) +,S(db390f91,32277889,784b5e4a,cf8f2fd1,f3a5fc47,f2c8262f,19dc9518,95322157,4364955b,241c831f,94fd7d4,da63db19,2aaeb5c0,ade82dc8,d5d61cac,d690bbad) +,S(34dd0266,e5fc19ac,7daa9e61,5ae8f78c,985732a6,1c53c29,e6e5d407,7391ebc8,c2d6b6d8,e73fe00,e6013b1d,2c2b48bc,77a5db6b,45232ddb,6611ea1f,c5dd797b) +,S(eea7f72b,7e31608d,d3dfcfbe,16e2ef95,5e6c7ec5,328f84db,336e3df1,9d1772ab,9662c8f1,ccdea4c3,48ea6d94,739aa747,17219556,c6be9b8,8af0d30d,514004bb) +,S(c6af087a,f1b10eb3,93de412d,de856129,9376d264,36d907fc,10d3e7a3,88c391f2,ba99d62e,31856457,8ad8847a,9cfeaba5,e5ff9824,2c614959,eeeb4ae7,50825144) +,S(eae34735,6c715740,ab73d034,bcb43f5a,aff37fbf,50d35518,1364c999,feccefc7,b9386c75,da8bf645,cd6f15d8,4944f74b,9685256d,b61fda98,79fe6639,92fe4703) +,S(4a548c25,f4d8f54,4f9a27e,64e49626,41b68ae3,1d90461,65c24ff7,fb40438f,ae9f2c85,bd608cf6,ef5e40c6,7e29a63d,4c274215,c2a0d578,38252f28,196f6d10) +,S(61925679,dd6545a8,ea19743d,7cb3c0bf,453318d9,e180da53,f43af2b0,ecf744af,a0682d84,d7215372,e9ec062c,a3e4aa1f,47fc551d,44e3d1a1,7260a44f,2bcb184d) +,S(e1db5e86,9574ab76,d4fa260d,2425ef62,50267ab8,52ff04fe,25f0150,9137ea2a,c8eaf421,9fd5f7a3,6c1a99a1,d0c61250,836e204b,fb496774,83f43c81,511905a8) +,S(3062cbca,73923842,2a0ab862,a1fd84f0,38e63691,cfc204a7,d2f9d263,d248c7f1,8f112e57,e3f2970,dce89eee,1e184310,721a85f1,cc9feb2c,f55c047f,dd9670cb) +,S(67c393cc,aa9736fc,eec7a861,eb53f953,9da74ff2,97764f4e,4e814004,4da4f739,93d329d0,9a165fe2,2f8009d5,ad59b524,33ac24d5,46c7d394,2d147c4d,49853203) +,S(c67471f2,36cf2187,ee5a5619,d581cc7d,ac5bc5b1,e8bb728,f943084f,e899bf5e,75c90c9c,787b318d,943c3247,74cbbcc8,3a533f37,fb684aea,62fe6848,8de2c513) +,S(d5015fef,d5938dd9,2133d7a4,25aaac5,12143acc,6547070,1827e98a,e4ed1b52,44305616,a02236f1,5c37c0d6,51d845dc,e9966860,b798f79f,4006c25d,7cf03d6b) +,S(aebcbf65,aaa89615,cb48ed56,4002ed9a,243ca309,1cf503b7,3c1929ce,8164f2d2,4fc1f25d,1a30ee2b,4220305b,a9c88e86,a6ee7f55,55399ee5,35e7d37f,e4b3f019) +,S(15cb1617,1727deef,49ad6821,932a39d1,bb8f980b,b5370d81,5ef00ff,ebb30e43,64ad8c82,87fc053f,ee35c1b9,9734b34d,2dfff86b,490ead93,b1fe7d2b,f80ebd7a) +,S(d404209e,8530d674,9bb88a5,525211a1,19fb2523,63e2698,6bd03080,4c49c123,3763fd68,fdb85d19,e8506275,3b5a327c,46ef87be,8a3432c5,62bcc622,40a7a128) +,S(f3abf8cf,c232849,58e330c2,fc327ac4,d40b4497,f422aa4e,d42e9381,9bffdd96,50861f05,d831327c,3e907643,2d7a7621,d1dfe9ec,7ccf2061,cc720e9a,7d5b0d5d) +,S(78a32893,2ee9dbfb,3f84755a,651b9d23,5cf92b46,c3e4bb4e,57b7ff6f,7c874dea,925b783a,966721f4,6eaccd87,495eab7d,b3c36eb2,92c1a473,b4617f6b,9ac85895) +,S(8165210f,5d146f8a,1ac1ed91,a7bb678d,1b7d15e4,3ed55e8d,f6503209,a750cd4a,fe390d3a,19e22bdc,cbd45875,e396c713,85954166,a1edb63a,384b8587,915d260d) +,S(75269de8,6c2f3d34,cdf17dd6,f3efa198,ba73431f,cf0072f3,633ca57f,7dfe3f09,b162a65f,d19927ec,4446e3db,d5ee8850,f463f39f,1df1a0b1,f5ed153e,704805bd) +,S(5e36ce8f,b393949e,5b9c4e10,44fb2ff7,c520a7b7,a9016b38,9544e512,427145b0,7c40e718,292f96a4,1d9822ce,d54aea90,22074c5c,c82ba4e,7d39a4e0,7811614c) +,S(c8cc7129,fdebbfc6,c0576edc,6ac983e5,c249d360,76da7d25,b05c0b6b,16632746,48a8cce3,a77e4498,76d1a332,c539feba,2653fbaf,d4f75e68,e4674d78,4c716fb1) +,S(9fe1db36,f1ee3e6d,3924d2a9,ae3ddcaf,fa85798b,7383a1dd,2d6c0c14,ea46973f,1d35b6a8,607045c0,95ed9658,80212b63,43dc55ec,beb3223e,7c2e76ce,2c74f6d2) +,S(4ca8ab8a,3d45748e,6e19e02d,dc351279,e23648db,d26d2465,7c9713f5,bc8ecda2,8a5866ad,9bb7db92,273c9f23,c0876c95,13b8a68d,bb20c5cf,164a9a39,4e3e73da) +,S(c8d0150,e4a989ec,5cdbc724,21b1e29f,f1f30818,1d8117b1,3d376f58,b72060c0,5c5880a4,c5a73a4a,1ae42a9d,f0b20032,7ac4a732,cb26e717,49e63365,5082ebd1) +,S(3d61557b,b4b9fde6,49fe1b7c,981c9883,9e368444,f130bfea,fc1e1a0c,12f2aa31,933167ff,62cd840b,3a960c90,e6b1c37e,1e233695,318ea286,71c87992,de5b56f9) +,S(67569f9f,fd44ca09,5b478dbb,85c3ed1f,feaadaed,cb624552,ccfaf169,24e69e2a,62bb2948,230fbd2c,aa941288,7adfb24b,d16619de,af0fc102,feb1b26d,67eb7fcc) +,S(6313d13e,debf1401,eb7d279,2c66daa8,6e3075d0,3cf0daf7,f3b753e,7372fbc2,44621230,50eb1245,86975455,63e06e2f,2839f874,beaff9c2,f65e26ad,d3573ef3) +,S(6f8ec9e7,fbbe6e8c,d0e3085b,47c6cb2b,88529f2,15f13195,5e2fde24,4dd23968,1fb61e14,523b3fae,b543b215,dc46eeeb,23e1950a,8301c78d,c510c76f,ed36cd79) +,S(56613dac,3c5aa1ac,bd9a0ec2,f839b4c3,36f0ae58,e0e02244,7bec0546,710b7f6c,247263ab,86c398f9,3b23319,4434af8b,530908bd,dd7f716c,f7b73aa9,8eca79e8) +,S(c9de15e7,b4147219,137e6e57,c5a7ddd6,17e91ab0,6859dda0,41eb3c21,87aee08c,c7178ea5,cfa056d0,dfd11c87,715591cc,40cc5db1,f5e4b70f,d8ffbfc4,3f8b0009) +,S(7590a4a,627d5e90,e42a4b0f,6be6497a,f906182d,d2dddc48,a8b6bbfd,f56c0504,d611e21a,b5498760,5c97e878,baa464bc,cc5bd875,353b69f8,1f93ce2a,a6c38587) +,S(94b1da0f,b310e056,db0dff72,81db3362,1fcc555d,bf3c973b,76097908,7fe19d6a,8318893d,d5b41a56,33a2ab4,ae4b953c,45c42e9c,8f2fd159,85286de3,fd4fc217) +#endif +#if WINDOW_G > 9 +,S(b5af4299,bcdacef1,e07d081,daec2cfa,d6f8f821,38e151a5,f20e6d52,84c9a6cb,c0984407,8a7db82d,f572987e,b137dc09,c8cf65fd,aedcb20,43b2479b,ab95448d) +,S(5f49ad43,70744587,3980a153,c851829b,f8ef6141,9889bb0c,3c476847,6939c3e3,5c40d385,20f56c3d,ba08ae1,b40fc24a,2ae25c94,45cae0f7,d01d1800,747e04eb) +,S(f6bb067f,88ccc11c,64e30d1a,e6893942,16bea3bf,26ec9c64,5cde1b9e,487da385,315a476d,7268978c,d89d4ec8,adde4a83,28dbfdd9,f2bf44fe,ad4ed721,78288f55) +,S(7b47cede,c02b19e0,94daea0e,ec000455,52690b49,44b3f10,beeed2bf,f9df6950,1bcda5f4,9beedec9,6ebac5a7,957918af,53b7ccd8,c211330,280ed93b,e0efe9a6) +,S(ba69d7f3,82d56d9,eb65e1ab,2d70f52d,18223621,c0029035,a78fd660,9940876d,5f44a2fd,56d5289c,f36bdb9,50ee2538,1d1cf935,ae1aec76,84b6d11f,975d393d) +,S(a3b70894,d226c195,223713bf,330ba39,fe7ec35f,9743347d,1d3dfdb9,7bd929ff,5d0cbdf,42755aa0,355ad2e1,ab39479,495edf2c,20bb0aa5,93cc04cd,56ae6135) +,S(c756e23e,bb2d81fd,91fe73b5,20eb3bfe,5ae602b3,448cf84f,e8da37d,d1c804e5,89f4b6fa,edf86b9b,ca9f52b2,9864a982,5a4faba9,d4fb35f8,98511210,34df49ff) +,S(36327c35,6fab94ab,f791c234,1c39049c,65410e9c,6cdfaa00,d172ee84,3671822c,fe3588a4,698c8d35,f0e01f04,e94f7039,eb745631,8c25927a,be7d061f,d3ed4c6d) +,S(3b75bfbe,8e372311,f46ecf6f,c5eb2af4,b66051b1,874b0c32,1189e106,37dd21bb,b9144a33,e3c3339a,4595e248,87940b4e,2e42a095,d7d1bc2a,ea50aa29,5a879908) +,S(44a61f10,57b4e88a,c55ed72,1f8f4477,5f0272bd,379a97b4,d92a7f75,f0d3c5e2,e870ea65,80340464,9716ec1f,5b79392,18162306,6dc14086,111de144,82d80141) +,S(11ae02f7,663c0a,24c6fe5,ce9206ed,1ebed2e6,ca294acb,74c9a227,97fefd,635a1b87,a262fb30,5008737a,e70422cd,a4e35766,940e424b,d697d28c,dfd6a36f) +,S(c751310a,dfb25d14,2e6ab1b0,ab31b37c,8e987af2,105d5981,69085ca,3e142f5c,a4630dd8,ed2717a9,f10485a4,be685c5a,ccca851d,4bcc1886,4df943ba,ee821014) +,S(fff4d7c6,4009f39c,41757b17,3eb2536c,a639b72b,e15af7f,790bddb7,efefe46a,694a798e,ffe22d1,1030697a,292a4bb1,4c110d6b,dad7edc6,e8976450,ce5080e5) +,S(7d76ea39,c13c9f46,e931e8bc,1cd43707,932b1a,31254d18,c06c8ce9,c3f90534,bc14b2ba,8f0a3d8f,34c7cf7c,3458c916,4cee438b,39a5a6d4,d2a1c9fe,8be415bb) +,S(b6efcad2,ca6ae4f3,6f080707,530aaaad,625fda5e,825f77e8,a6730e95,5e07ad39,4868d8ef,8a56d327,3f6f4a3,23ea6ad6,4694301a,1f6405f0,a421939,bdb1c765) +,S(1a04b12a,a889c4a6,d37f9050,e75406d3,48e38faa,c0d2ab4a,e30caa6e,3633a32e,f43a0c8f,fad38d90,6c817dca,3e7ea09e,21e1c801,7af86966,c246ebc8,dc75911d) +,S(adaeb0fe,9b345190,4e878b12,6c8edddf,b70e2500,5a4d6a6c,531aad51,83209b7e,2b26b16d,dd4d29a7,8cc6b4e,198e6ede,b1c59def,c6793173,f33cb039,d37522ad) +,S(4e4ca02,3931f3fc,b512121d,2d632764,d97fa125,8460d0d1,9a94eb88,2c6e0679,ef90eecd,3704a6c9,454c6860,928eb332,cc917b17,f2594348,515822d1,84537467) +,S(a1f3c279,df69c13a,711b5ee4,139f603b,5654ecac,adc02a22,a7c2087,c11e2971,57249794,54cb78dd,7ef69916,5efe2326,e8aafad7,a8a923b2,252523ad,b6a16b2d) +,S(aac76f81,488668e6,f4b0c911,bc9675ff,c19424c8,6a6903c4,f4b13e0c,e798c7a5,24ae16df,dd6c7d6c,1391df3f,73609bc2,c3759536,eb277189,588a72d1,84dd2978) +,S(70e94171,e59622f0,de360166,6498e6c9,ddce496,a15e30a2,a5bdb701,d0034769,d6d7c0a7,75a9cbef,2b84d4e8,200f92a,446111bb,cf46a57d,5e244f1a,1103b757) +,S(ca17e5e7,11d44492,496fa849,c6ab1c47,3426706b,5b8282b6,f288e096,8ec78890,b3ddd632,2ce577b8,ddb9f501,e17d32cc,e6c58fee,4e283410,5e32f3e8,8bce2c2e) +,S(1a16a58d,8d70fde8,6ac0700f,3a43ab9c,255ec001,8d5fe571,7ec6324a,2faa62e8,f2cb2eba,65aff0a3,dd7bc137,257c1d30,dc2eb6f3,7a3897e1,16c0eb1d,1a710c27) +,S(8f2dde65,b4ddf10,c29c6bbf,5ab2ac11,2dd3357a,e3e5f01e,98190e32,94b9d4f2,e06b8cf7,e5a736d5,4e954bd,8591f7cd,79df335b,d3279f5d,80493fe4,df4c6afb) +,S(3314b553,f8213e7c,80d4562e,cdb3564,ba1d7285,6c88d8c5,a3adda90,4950162,33e83c5e,e3f7c550,f94a7434,e3cad51e,b4dab462,13acc24,fc4aa1f9,fc43532d) +,S(7c107ef4,65ac0c2f,fc5b11a3,348a7cc3,fa589554,ee2b6606,2af3c5ba,25304000,6b5bcf12,2e8a0705,d067fe78,e56d365e,89b5a979,c23f124b,508e63ee,975702c5) +,S(e918a829,325adf67,511e257e,e5596d08,19be4605,36b20cb9,7b76a54a,5be4f8b3,1a92f0a0,b46152c3,e1ba8f0d,12119c15,b70af0ef,3ff0ebf,a9dc9207,cf2fa8ae) +,S(8770da03,d4f3a4b9,e92dd2e3,be309c81,c346c97d,2cea15d1,e3fc94cf,41b9b079,d025430f,dc633d57,18d372fe,64f57fac,53f96461,1fb5005a,10ce842d,ab123c03) +,S(c6b4ad3f,ae2b2557,b126a57f,6bbc039d,a6589f70,c6283ea1,7314aad5,acd8b22b,e8523dcd,2c1c3412,35df278d,e49c38df,85f2888e,cf3c76fb,46e1affa,d8d29bfe) +,S(9aced948,6ffbf984,373b1e91,ff871619,4622741b,1e1ab968,9c88cb70,37a86e14,d7a7eb1f,1b4c31df,ff43cc32,1949c1d3,16e1e7ec,a6a852cd,e8e7f592,8b352d9) +,S(af51536f,fccbdab4,c4f4015b,1e8aca69,b08bf055,e038b22b,87c54f5f,1b9007f3,b6bb0b4c,95c07ecf,49ffa85b,abb1d308,cbe813b7,703a27ef,cf849e,47130f7b) +,S(ec5306df,3ea0abb5,6fc45a09,25c1c925,56e02ffa,18238c3e,5bb2ee53,11823ce2,c950cdb6,720f65f4,18065352,43c90bd8,9457f4bf,d941c9f6,89812840,2dee8b99) +,S(293b1ca5,be127bc6,1a397ecd,59164363,587f468c,81de4d87,6c5d9bae,e72d90a0,4821030f,238e9f05,e93d81d9,1764863d,443a524,3d18e61b,ae26f74d,ba35d821) +,S(ebe54b7d,99876ab6,b2951f0e,e68bfc10,16877142,22ef83c1,2561f486,b4865488,2a1d651c,caf8802f,fa699d91,b8242f51,58d84fa0,d481bc47,9246eeb8,6d381c07) +,S(88f77523,3ab0d69b,ed220109,b29d0d99,33ac8325,445d19df,d38d9c69,3464acdc,8f915122,fbd95ef5,31ea2cb1,aec6bebf,8e059059,459c0d5b,79a282cb,cb276702) +,S(1d84753d,e7210dd8,9db6cfa0,8ebe9797,c7fa40b9,6e94439f,b8117359,a2b3bb01,f7360b5a,ba53a4d8,7440b6d6,f540c485,2e889c33,9f34260d,abfa7861,f1f41ad6) +,S(19e69df5,176f82c1,cf1ae032,cb388ce3,36f82a3e,5e741e1c,27fcefb5,311d4b2f,c401f4fe,c9ba53be,be175dc8,cc1d17b3,9d9f7af,5bb496e0,b95bba6,cbd5c143) +,S(73189e02,c1f125ff,df1a9399,57f29aa5,19b04f5e,42adf729,53d354cc,aee3f2c9,52b8e88f,1c6e7cf8,621d21b0,1e406038,d901de1c,4101d424,1009c01,a537f704) +,S(c5ebe082,8ff1a8bf,52f8956c,b747f1d3,278fd2b0,a5ae7669,1c256e9,2887a74f,ce58cb9,62e74b98,1ab97dc9,2d736b5e,c506e51d,6c09b382,3eff1cdb,cd259860) +,S(783c1621,f7990e01,4296feed,3bc883d5,1a780867,c83b9166,435a0562,4982da76,370b3e2,c9a189c6,9c565c3e,8eb8019d,f5224574,bd5ffbc6,22f563e1,8a36da30) +,S(555e7e80,ccc6a46,1724cbd6,4a53721d,fad66fcb,2c71d579,4d799f6f,fa2b3305,67bbf165,d39d7042,18f5ed31,28fe6dd6,db9b4809,b3270eb,63bda603,f44e9e41) +,S(40c49a26,ab1cd46c,f1e8467e,242c6b1b,faa40a4,cacdd50a,4b0213a5,40243471,16950b00,5002622f,e0b9fdb4,c34224c3,ad55bf30,67f4e96b,dc2813f6,2fdadf86) +,S(eb6b3be5,db098d18,9c810b9f,5593c746,47306226,d77e162,7c8b62f6,d7935298,3d295584,3f356f5c,1f990231,701cedc8,c84e9671,44be22fb,9bd74f0e,15c5bc8) +,S(177218a4,2b55c169,1ca0a073,4d061b53,a0683536,9a04fca9,3f670ce,5eb26091,9611661a,a8a3bc73,7717f243,e5e8b97a,57e0e72,759f0f4e,cedb690c,b3a5fa42) +,S(841a8fa2,f3bc5f8a,7d028c00,127c267a,ea0c3762,8b07ebe3,7f883a67,8fd2a680,579bf37d,b2fd1f77,a0057712,88dbbdcc,526938c,4f9ba89d,9a42d4f3,452cf1b0) +,S(b01ef554,3a377f1e,c801421d,a399c53c,3585789c,d7e51691,32250a61,6edea82d,28f30ce9,7e29b2f1,3af626a0,7a37f14,82e119d1,e66389eb,9620200b,25a90265) +,S(b93e014e,8e3cc643,17ee70d6,ef8c9918,ba344e7c,b38a9a6,2591b0ac,4f38904,129c185,5bdfd10c,6bf152e1,2ff89b4,d0b368ed,c0ae01f7,2b29fc95,240ac3d3) +,S(e0f426f2,43c50d9a,ff80a1dd,26d63189,a00601c6,8ac81373,5fbf548,7acd522,96d883e0,951adc5e,304bd848,ccf39c2a,1c19382a,eb24ad1e,1430d705,deb749fc) +,S(e11e9c74,40e897ad,2870adda,63b9ec04,d5379f14,b3bbbdf2,147ea9b7,9c73233c,49d6e54b,29197532,3f5a9df0,3e22e359,e125e34d,d9f3d6c5,cb9f0a20,6dc1f019) +,S(91ad584b,c5ef145,3b796eca,20027cc2,ae38ee70,9ac4591c,79cf67a7,a96b2c2b,d815a213,a620c531,11f79e5d,b5d9c3c5,565dfd97,ece841e2,3e9c1ca7,530bac2a) +,S(3e725392,f4fa34f2,7413785,cb322f35,1032971c,2303f3da,bfe40461,4299f8d2,8e323a51,5addeed5,f3548217,6907efa5,4e0c1d57,7895839e,42223e5,7708ae85) +,S(5e87bec2,1a589ab,483c00ac,fa863f35,91d9119b,9a0239bc,ed4f5790,45a98160,a88a3b84,33c75c1f,9eaf3c15,9fc39a6e,33625f1c,d0cd7263,3a825023,f2e7d47b) +,S(c2e08613,2cb93b35,749cb652,44e99909,da18260e,d252cf32,489fa1c8,d268a0ed,d3f2e3ad,1f16365d,d47038d6,854e0773,28e02e64,d05a4764,4ed0d82a,8c8a5761) +,S(99304c5e,ccf09869,7b2193c2,31dd9432,3b9053d0,e4b9025c,74517ba7,f1978af,ee77fa7b,638b1396,6f7e77e3,43dd04a0,ba1324f3,1e0da111,338019aa,209dc789) +,S(40e108c5,59adfb37,651f04f7,9ef895b,25a79f03,650d6b1d,1c21322a,b4c5c6bc,8980ab38,5733e648,84aff3f8,c47fef44,210eb2ab,a094eb2c,fc5e464b,679db653) +,S(98c88257,2d190721,20c31528,7f508df4,6d6276dd,c9711aca,5bbeacdc,88c6a78a,5d1aa976,1f5c5ffb,d12ea7f4,8d0510e8,b57f270e,e08c3256,f3ee676b,41a61c92) +,S(389aba7a,25e92306,b84eeab7,a16c37ae,d7b4cf09,806ff740,c05dab20,60af6fed,673ab0c9,ec48e2e8,d372ed60,812b2990,49c32637,35f61c13,d6f0ecf6,d065707e) +,S(9dc64fba,832c956e,93efda62,e5f11b3a,6619eaaa,e539b732,61453eea,ca53df17,180b38a9,3c56ab10,a4267ad8,d8a358ef,8f60a9c9,9483889f,956bafda,f45990ac) +,S(71118e18,e758c2c3,6203528b,8b6707ab,b3439b0c,d3d508a9,6759c155,fe4921f7,c2f61af1,2c1b4e9c,64908719,f11b52d1,76bf22f7,e1cc800b,5ec79e28,aa104ee0) +,S(33bcedee,11b9f3c4,924e0990,9adc5fd1,46218b23,6531a242,45cbb2a8,3ec3d096,15f4bd1a,6c22c673,941a71f6,f4694fdb,f83b3e8d,5e317e9d,655057d5,acfbad0a) +,S(4b599b3a,4ab5e9f1,f161e5cb,62fdba55,fbd97740,759871d0,e66b20dc,4e13ccb4,635039da,9035272b,8b706411,9b342144,6c96019a,2c6df423,2b18299d,4a3fb523) +,S(19f6bf4c,dae54ca9,41b8f642,95136026,decb8dda,35e97627,5694365b,21269d10,a24c3fdc,90b06dc,264bca48,db27502f,6cb31a6b,609d3f3d,a1c92c64,cf3c95d7) +,S(bc3df1a9,8027d14d,f6629adf,7ad073ae,8a270875,b177a67a,58dd46f,1b01314c,99dd3a91,54f51d07,2ee33e89,8d915189,93445065,770745e7,b6bb30ab,808d1f76) +,S(977a4264,521a70e8,4d25f5b5,ac1ae5f6,c34ef31e,4dda285e,1ea4a9e5,7dd72c3c,f1bfc819,7aab2fe4,d0425b61,cd403fc9,dbf44f68,32e1c41b,4fce9b2a,2b9f5a0c) +,S(5fdfde4a,85fc5a53,3ed4a7f5,8adc7b1c,98b2611,3e271b47,a1c12c69,dc9b339,3edf2baf,bd6a94e6,951bad5,26fb24b9,731c2588,b2f6eb1c,e9744f49,16c6555a) +,S(b8bcd72c,dcd28afc,eeac1ac5,fb7db8c,afc17abf,82268747,6ce01423,e9e9c50d,82633c5,2e6dc057,9bbd9f2f,3771a53f,9cb6d0e3,6a7566db,f2c45125,3c55e9d) +,S(6c20b999,133bc37b,c65d01eb,6e946565,721bc2e9,da735c72,8be8a41c,1f75c77,20caf674,d8ad036e,25f42aa4,7a5ae475,5e36f44a,79c5ff20,cf6df115,40b71e53) +,S(bbe49141,69655f15,39ce4bf2,f2e919df,f877b5fa,163b7a70,22bc91ad,315adb07,8cd3e025,6618d23c,8c6b5ff6,db8fc0a5,a77b847f,ec876ac,40f76e9c,cbf93a1e) +,S(748b3078,e38374bf,7f39bbb,c5641737,bf6dfeae,d3980c75,2fe14c68,65e73786,7f7cae0a,61a7dfa2,471f2c80,217fc847,ea86b6b0,6297aeb2,8f3c94cf,2a811ac8) +,S(fa63c7c5,b89a2559,4615728b,2272cf68,5d39d592,d052c0bc,d23d48be,c764e4b4,c4c32ba2,77519d60,e1e38a50,6d67d041,804724d6,5cb4dd31,fbe7d692,8ca47c8a) +,S(c2ed7197,d014e380,a365ea13,d948314b,86978eb0,70e3e444,6c953871,cc56c91c,5c73c293,e7c1cd18,f7854a09,d8b9b0fb,3404bdb7,737dc070,9bdc01e,466a595e) +,S(2514c1ef,cb1e0bd6,c2f34e84,6f3e8006,6c2b3a04,c0d9fab5,f22fe872,6fc266be,c5a0ac6c,7bbb2d9,ff844346,65f66ec6,507c35dd,8ccf9ad0,69a1ec94,c64e3eb3) +,S(5bc07f05,11647f2,58dd2e28,9a3843c8,e2318bff,c96a081d,f6b6ef94,4e286350,213ce093,1217ef04,8d87d059,f2584db5,7a91c465,1e112c66,a41f85ab,ebbcbea4) +,S(edb56e42,97375b03,8a573f70,67ae464f,db9c1335,f6a03dd8,862a1731,9a3cad8a,d3e61a70,16f8d546,61b8414a,426f3be4,35862053,1d981f2e,5314447f,15ef5fa7) +,S(2925276e,78266481,3bf60998,2e028646,6849088e,d0d77d55,817c8d9d,73d5d732,f53157a6,a97c989d,ceb2d755,dbb0cee1,84b33213,20dd6d22,62213fe4,9a87296f) +,S(2c4579d5,bda0f4a5,37209882,937019e9,91286379,c3afb37f,a69e409e,9bc0a034,e150bf4d,d889c3c4,655acd23,f3107bca,a319d467,b1b9b15c,336ca934,5ef7d99c) +,S(5f260a00,11f9f876,bbe29587,af31832,25f21b8,42698b3d,5688545,a8808904,6ad33a32,164caa1f,7a4d2ce0,6eac3d,736fe64e,d83a3a9b,53473a89,8ee02350) +,S(3bbbbcc6,12095ec9,52fd430,f3fb3d6a,9d1f2c69,e8885100,d65a4d7,b6ac4b8b,328e828,3846a6e7,db5b090f,8c9581da,40d244cb,aa3b5948,7e4f9faa,550b0c97) +,S(4985027b,dd0fd8ef,fec9af44,bc222f4a,343e80ca,662d917d,affb9d81,956acff0,58befd2e,37a36e41,305561b5,f2716a23,460b1014,fe814654,68c16c22,3b8affda) +,S(214638e8,d2e30891,9b5eb2d8,803b3dcc,6e826ecc,e1b59b,92e263d5,67959de7,9dd8921,6f131e29,35ae0454,ff5fc9c2,dc22c0f1,c8de7dd8,ad9d41e4,f632342a) +,S(6ced8705,5ced2d6a,f3e3532b,965e0a31,6876c110,69155f35,444004f6,e6f3cfdd,f51b1aab,c86f556f,8b7ba4e2,a1e6aee7,55b17c01,997fcac0,a83eb56f,7e546ec6) +,S(95016e67,876c936c,e3263498,7859d1ad,7fc3ade4,4219727,30a1c886,c9dcfacb,299e78c4,e6e266ee,ffbd284b,81005bab,4df7232f,2e43f160,742bb392,6af4f660) +,S(4bec66c8,30401c39,c42a8019,fc398cf0,c513d20f,9db30763,51315319,ee6f23f2,f1dffe92,3b7d4609,871aa916,28929c63,4fcdeda1,543fc3d5,8e8b2735,938514fc) +,S(b50513d1,40513b97,6ac0015a,60e53ae5,9088c4ef,5ab27bb2,7f3eda78,848a59c7,9c41cae5,1182e6c2,3fb254c5,1b786ccd,dc9282c9,a6674841,29a5894b,99c36399) +,S(59792653,3989a039,6a69bda3,8a920ac9,d1df3845,26f30c00,3e415593,b690708d,7f2c14b7,274887db,5e656192,19ee6737,4c750cb3,97ae4bab,3a3ed02f,1aba648f) +,S(7ba2b766,cf012a93,478fe2b3,e916d665,251cc7f9,3ec16dd3,4db37056,5eacf6f,14fd8938,f950798c,37121286,5e8bdd14,3dcc7e8c,2c84aa69,3fb311f,856404bb) +,S(3062f2fe,f69c90d9,fc947af8,a9e839cd,7f9e9d22,566bd3a7,1c43df9b,eab5d6bb,db84a833,49916d41,7fde7b71,9d92a716,64047d4,21a36bba,ad9972bc,6f5ee58) +,S(ed5f949d,69dbec8a,77f4d695,cb446700,f6fae687,e327cce3,db38c2fd,54b06e74,4724e060,57b3d50,65104ff9,29950bcb,2a690723,f15999fd,ee62febf,2d8930e3) +,S(4d655e03,30028276,e9312fe,a6acc010,30e12950,9ebd68d3,d7170e46,61b7cdc,90efc122,6c27549b,2f5e046b,69e97f04,4399579e,278ccd0b,7bcee523,10ea99bb) +,S(f6b60756,b888efec,d0a9edf4,a483f95b,68e05e80,c351a60d,bf166faa,eaf1b35d,27bedebd,aa781584,6a896b24,1afaf9b0,cb57e98f,bce5df6,bfd22a3d,38a5fb8c) +,S(cc592caa,942ba237,72c4db94,58d6ea2c,8c81c538,8fc7cb51,6ca30188,a3c55748,36e2f7cd,358e5608,36e77d10,361c3f1,bb6bd2b1,d640307c,63d512d1,db288158) +,S(4acba9dc,a5bb4698,21a3acb8,cedf4304,f9372161,976d0edf,6a7a032f,f6c1a456,b36e983a,b2ab47f3,3e72287e,9bbd02cd,d6fb302a,972f2166,9cae4e85,52262437) +,S(c8a5185e,42279d3,2b50e0c6,1b9ce961,7be3633d,84a9472d,97446ddb,eb061f91,cfaa50b7,445e189b,d64c1df7,4668eeb1,cdb7cbd1,ff65c0ff,3c38d22d,9bd4b5cb) +,S(c1c95567,7f4f611,365168a8,89de10ad,535faf08,65f8d20e,52b1041,d35f18f9,34f7bc3b,3d956b63,9afc1eb,956f4472,543919e1,3708e7eb,537ab941,48033749) +,S(8df4fbb7,36f6736e,b4a09370,33f7d256,8bb68d68,f3e1f8fa,8df1ae51,d236a8f3,3d7185fe,8e9a2d00,3987af26,71bb3850,cef6b0f7,70770c81,22977764,5d02122c) +,S(d635f0,e35c7cb8,f2aa1ec0,c475011d,c2c8bbb6,d1ebc297,c2baa5e6,aa5af3dd,926ebd,c588e8b3,1a990a5b,5907ae5f,441e5a99,1853c643,5e36803c,7ba51a2f) +,S(b58d12d,5f865375,7514ea38,30e38e05,3678b525,e8b51923,d6460720,b46a4bc,f7b59183,5b0ebab3,935d587c,e995c0b4,d77c9e40,ea4837f6,48e44841,7438d3e) +,S(bb7c6a8c,b4013640,ecfad075,578e89ae,12cb4253,6461d780,11ba76db,da9a7f36,7dda0258,3774d618,68995b83,5708295a,3c2f5c40,306dcba7,d1c20da1,4836581c) +,S(14f6f0f7,92cc8cef,9dca990a,7fa5b7aa,f116b819,722cfb91,9683b298,3514a9e6,88c35f92,7a07598c,90ce5aac,4b3fecb5,2261045f,f23800b9,7b96f210,3a4d7055) +,S(4b95e5f4,eb9fa118,5ddad896,457f4aa2,fb60f4d0,496ad4fa,76bbbce7,77448541,1e100787,513acb31,ba087f51,201201ed,502d1f08,f7e2b8f4,d27706d1,45e71d21) +,S(e9a17fc0,67f75b2c,6384aa31,223355a3,a7af5366,4d85dc16,dcecbd2a,364b63ae,420a2388,ad674523,62f8fcf0,12b601ab,a40e06a,1b4dac1,9560c085,de7fb8c7) +,S(39d8536,f320ec81,4ee3d066,c0834130,96d4ff43,8331a81c,f10ad544,43ff9169,70ee89e9,1478e898,60d66a55,6054abd0,c7434535,13a7a3be,7a76e367,c28ca248) +,S(9779a0c8,8624d6c,beb1dc72,f371ce26,9f95b993,c49ff20e,1daa3c,2fb636e8,9d9e27cc,67296c50,9da4b0e,6037920b,369684d8,a64cb907,d230a4ab,a0c2712e) +,S(cd4c584a,1dabb48f,6a5c09de,9caf36ff,4a97471f,d1565586,bd78b4fb,66f0b401,95902ab1,eff06e2,b3e104b0,cad2c28e,6fd60eed,c47657f0,bc433411,273446f1) +,S(46ca11f4,142362cb,513164f7,c72b776e,dbeb3f65,5d527196,88eabeea,2561aba4,8060431a,2a2ad442,dfb6d3cb,d6263c61,bcfd0946,6204e2f5,e832c4d5,a434c9ff) +,S(dfebd179,1ffb63f5,76f5c753,50031a21,eb712de5,7e8f83b4,75ac39d8,8a94a513,cfed6c7e,39b2b54c,206aa0e2,2f7c610c,6576af2d,ecb28f0a,a71cb1ad,c7be75de) +,S(c71c6532,82fd063b,44633d9d,7a3b94f9,43daf1a1,7967ffcf,e1238087,5d2c2469,62fcd7cd,e006a10,38df8aed,33abe940,f18a4736,52adeba8,620d1b54,a9d376d0) +,S(63ebbb4d,dc8ba09a,4e2640fb,f48fb75a,6864ec41,fc1647b1,e9f8aef7,34c0ff37,e59d034b,fe16f4b,41d090e1,97360a85,dbf1ae4f,719c62df,77261205,da4ae28e) +,S(650498c8,cb51bf16,58eeac61,61b5892d,ce6e5c1c,271d40bc,eea14db9,dd12814a,e7e66785,5d8e0193,24457769,bbd5d14a,7a614585,70ad5e6e,e3058af9,64a65279) +,S(14a1e03f,14c00863,81599c07,b816df44,90815a8,40c1032a,c41225a8,47c43fd5,35244a59,bc6ba88f,46f66bac,9bb8ef5e,4926da38,50532ddb,6d6d606f,35fe98de) +,S(1c9f6eb2,f6a8a1e8,ecf9a16,71154fff,a4f14c15,bbd50f08,4d6f5315,b6903c5c,e6bde1f5,2ca4ff63,9b66fc51,150eee99,5386383e,402f987d,d266065d,2a03a033) +,S(1de71eed,bade7b1,7c80966,4b00d56c,b43ea61a,c0e069d9,7cff0218,f970f8bf,8d4b2de,77edeeae,d78d42e1,6b7bc94d,ea99d65d,985769bb,5c67da66,18ee1434) +,S(f4432a80,ce954d2e,baa2f062,8bbab706,479f7a39,838d8c3,5a96eaab,5f5cb4b1,96fe6ead,ac34a40c,3cabf47,6fc09382,91f3d077,29c6302c,c67a189c,bed579bf) +,S(8f71e74d,17964af4,5623d3f9,68424119,cb37e1ca,c1524737,4828b5e9,2519fb21,6990f0df,d7f0ca4b,a77678e4,ebf6946e,5b6b1720,869c91c,ec07854d,604865ab) +,S(22293157,5e3dc25e,665546e2,96a83a0,5a09d052,cef701a1,20019c49,c6a6745e,aad8f887,42585607,c792bfae,8a941caa,83d05082,defea859,86a6ead8,e5c423b0) +,S(6585fe63,2ef3a69a,816bf5f2,9e627650,cc57d069,3ac217c6,3b73aa2a,f248a096,820aa3bb,20281afe,edd9ca57,76ecc55f,dc8a893f,de11f7cc,12f37a83,6cfd9f8b) +,S(22232479,e55c51ca,b2963ce5,abf06281,aaec472f,e610d339,1951e41f,93f67bf8,e192fab,2cf22d7f,e67f0514,bc1329a2,888a8f18,a8d6504b,b7c5a9bb,ebf927d2) +,S(da8d02fd,e4ba069e,bccaba08,2b396c94,4460148b,70e98f60,8267db02,5ddf16fc,1a30213d,e337084a,47d67e7c,17a2e64d,579756d0,8b66f4d0,59a76021,e63fa2bb) +,S(a6f72c62,854e82de,f1b8a006,64c4e8b9,ad49e092,78ee6501,708a9f18,92202ebf,8355972d,b08c8104,b7c56ab,c2318ef4,2e270989,1a83837e,daa35537,1d03ba4) +,S(2074fd3a,309e85a0,5c6f8c35,937dcc56,a15077ce,99f5a8ee,8d55ae2a,3bc7db68,e11c02ea,cb783c94,2e58fc0e,806a9816,3061a4e9,aea9582e,53ae1f08,322cff97) +,S(49ed5666,fae9aa2b,70cd316f,62a4b62e,29aa59f3,1826106c,8611c50c,79a1a5e3,5ca7e49a,ae144e2b,dcc0b19e,f986967a,1477c209,2a8368b6,324bac6c,807643f7) +,S(2289ec7e,a1f7e4e9,85f472a7,13722335,b582c4e9,8e191468,3ed13622,5d6c1b1f,11e2b18,689a0867,517bff6,77fe40f7,b03f898b,d70e8902,61a512ca,d9cbbeb1) +,S(ea852ebe,23f1efbe,d8ac64a5,58ba2ba3,fbed0e52,ffc70635,bc49cebf,85859164,bde2ef41,fe97a639,73266583,c7a4e415,25ef1351,5b25cfaf,c97aa635,41cbb824) +,S(5718f0e6,7cc07d3f,1ac1a954,8fef08a4,290b257d,a4179855,3fe9be1b,d302f0ea,98ec4d5b,fca65d7e,e72d8bd5,3645a6af,a6ffcaa0,a2eb894f,d4e40ecf,69acbe90) +,S(df62a2ab,d77afd7d,ee8f0650,b75458e3,10269c3f,780cdad5,50bebd92,4b810a4c,6a6606cc,e384d27b,80bea2e9,588663e0,8d39fe8e,9fc8a8cd,54c4829b,8e4c034) +,S(1010fc45,4b0c268b,c339bd19,809508e7,9ea7dc0e,efd779aa,4974cdae,805e6668,686a3adb,681b597,2b30a323,c6b6bd2a,d51194f1,9d3d801c,3fa65fab,e96410e1) +,S(8ac79852,75673818,69fe93c9,6141493e,72ca344,790487b,d5425ed6,9f5c5c18,bb314248,fcbfc867,d1972e04,b9ef1f90,775375f9,9d25bcec,684c72c9,bdd1c08e) +,S(560e9711,88cbc7ce,c61f3bf4,45f0ade3,6f3f174d,219a160,5f9c8692,3f848b9d,9e92dace,6775cc67,bfbbf21f,c64e6e9d,4d133f8a,c18ee277,bc80ef6d,d1b9cd2f) +#endif +#if WINDOW_G > 10 +,S(8c464204,4b95eb66,cc95ca08,8469a1c0,28eea52f,7f709fe,e6d90700,f5fb943a,bf10fc5d,7bc25181,301b3a61,5ebea597,a3492025,953c3aa5,1a11271e,689d0223) +,S(d293f74c,f3578b71,35377247,cd8b0367,7f2245da,f87453cb,4d8d1cc2,871eb5aa,86c2013a,61dfea14,63e45931,eb09050f,f080e3d4,ae357423,ba7afbed,a64a6f26) +,S(35997241,ae757b1f,c767611e,c76eb935,fefbf7a7,33666aff,4c6bd744,d7687d35,bcbea61f,246bcd4c,c3c7fd35,7bd393da,2f36e0ef,cca0df9c,5994f96f,c44b2aa0) +,S(d096097,7467197d,3c1a0ef8,44ee35dc,285a17c5,bd9e06de,15f36025,7f6464eb,342af6a5,1e06db96,692954bf,c79cde9e,3dd44869,9e88b03c,d144b70b,bd3e8783) +,S(8e875c99,2aeaead6,7033a375,521b0f85,62125797,23a25470,bfdf898c,ae41a777,24aa273d,2d2f19bb,4e0ba10,13127ad2,a5ee6686,1ec6d0c6,53f7a989,73c0bbd8) +,S(bf51d1f3,2703a4c,d1ef47d8,172c5bb8,d622f444,8569aee,d2de1b9,ae541855,8f81e352,b6c60acf,bbde6e40,99353d84,5918d931,4433c30f,3c60a710,cf9aa484) +,S(6fb6b462,9726856,22b2d141,5083ef56,2ebb115b,6cdcbaee,696a8d4c,8341c26f,9c08f7bf,f9cfcd9e,cca923b3,e578ba45,468f2530,baca2032,a899f060,b83c9c73) +,S(75583ac1,8b5cf78d,7de6a21f,aff045fb,1db56f68,6b2cf89d,678df62,93617438,8259a22c,b08546ff,e237c7d,9c669c96,71fe014,9840082d,f6790340,9b69f900) +,S(42611933,a5d759ac,7ec51c89,31b76e95,4aabc2e3,61010f36,cdd8ff9c,b4c0ef92,88a644ce,6b8acbce,a378e2bd,54eb84c5,58cde403,f99cbf8,7830151d,21ed4261) +,S(243a6dbf,6128f964,bdae776c,a716bdc5,6dff9c95,24baf845,8a43ade3,af520d2,262a2e8a,5ce4db48,d0401850,e92bdfa8,3dda744d,a3d9025d,6091f1a5,201b7e50) +,S(212bd175,1548c6d2,41e9307,a7df15bc,46e57e2c,5a76bd58,82b1291,d8c2ac76,82461bc7,6cc97273,267cc788,a8b24082,57f04ef4,719a9aaa,e33cbd77,79391bc) +,S(da6d030b,21f96d2a,aa0b3e56,28ae0ec8,8ca8a546,10bd61fb,c1a7c16b,4d61177b,5b5bc635,8fab0287,4a2b8596,1b49ec29,2c2aad1e,1eabbd0a,1cebdbe7,2e3f9fde) +,S(dc230af0,55a243b0,a581e101,2eea48fc,4a43137e,cfe80108,86a9f4e3,f6c1f01f,d0f98e1b,e70a458d,7030120d,a3d7feed,2eb5a9ab,601718bb,950fa03e,568180ca) +,S(82c2de3a,c815c686,98ce73b5,6f232684,ee9c5972,f0a44797,dc16d04b,a9089df1,1c847065,c6c2cc18,fa253b8e,c1fe178d,c859844,2c1fa432,54462d97,93b8573d) +,S(6ca2de88,74e4916e,e1965dfa,200af89a,cc439f20,6a4077f6,67076149,e20494a3,6ef0b344,97aa85dd,a43cc1aa,57dc7ce6,cd51119d,ae96ae06,99b5119a,9a662043) +,S(ba2687c4,1728fb65,206448f8,28400efb,cf1149a4,90bd31f8,8d33af53,7851d97f,96ad25f1,1f2ce7aa,e8b803bb,3c62cd32,3345500,243b1de5,d61f20b1,86b4c0c4) +,S(ac362040,1947f301,16032d5a,4b303323,d311f533,e46a1aa5,f1ea2f08,d553e0d,53839f95,fef32884,5a75881f,a17db91c,1d5b981b,7b20937f,df171c3f,2cb30a22) +,S(6780ecee,5b1b7205,68d4241e,c3b35c9e,4158c7c2,2dbba46b,ac769476,79049e13,9ac115f0,31e0888d,2dc90b9f,3562e732,46520d57,ecc7ae4e,e0fbf401,3057d9a8) +,S(95377a47,e7a2d5d5,30510d62,2bbd3439,c0f7653a,ab294254,cbb10390,d2a63732,57ac9110,9dafb62c,fe1abe4d,fc64557b,bb01f76a,36649d7b,91be523,f8195fc0) +,S(4f195bf,98fd83bf,7ee97c5,9bd42af5,486a8507,3327415e,85f17a17,2add8921,a56acf25,1c82323,6327cae3,6b1cadd,1a057bbc,f1ef3b59,a865c7b8,691cf3dc) +,S(eccd1fd1,efe8299f,d2208240,adbaabce,cc0510d2,d7b6f6ba,d9e291b1,4cbcb53f,ec2ff321,6da50fa5,c57d6f2d,3198e019,2d9b6f8b,ffc26b29,13580447,a42c667c) +,S(c757444a,f2c3425c,728ff41c,f7cb7475,502e7601,c1edf2b,1eec84e1,b058f438,e1d481b6,169f143e,29701105,bc8b6657,9cd267fc,685014b8,fd070283,6362e53a) +,S(3562837e,bff50776,58d99662,7a11a367,aef3255c,1c470ac6,36f1b57c,645250b8,cdcf4a0d,97aa58fc,ccd374bb,bcafc00,fa1d0d35,ca7fab9c,f4d72d66,299234d8) +,S(ce9dc245,f62e97ab,d2d339e9,7fac18b7,b1f2f07d,fb654a82,b113317c,86d4a3a1,f6e1e325,342afb8e,64fe8520,ec37abde,fcaf1b30,be6ecb79,27ba5615,f0d184d5) +,S(ac022f3b,48ee44ba,9d271a8c,1a01fa8a,aab4818c,e5383dd5,42d9d6e3,2c858a12,1e0563a8,91f8d11f,1989e091,739611de,191e497e,66055aaf,45db9ba9,72ca76fa) +,S(d1d4f682,cb12cfaa,e46e57e6,db6f2277,55a83782,88cca4ff,3a999c0b,a651d9f9,1b19bfe5,870e1931,4c23b4b0,71672233,1607264,acb8e960,488598e7,85e71a36) +,S(79962171,bbddaf94,45fbacd4,f9bdd1a8,892e754b,2d0052ee,2435303a,ff1c8a37,b8ac27de,2a952beb,45472f77,b34c1354,fe47b6a9,daf0720a,b8515be3,7bb98a7d) +,S(445a17c4,2390b604,bb3c3573,b061a2f1,20ecb3b1,83a0f8d8,cf032e3c,509d3b90,b75f4088,7c07fe5c,a0c057c8,7eff4966,4ea76941,e409a6aa,e34ad4b1,693f97b1) +,S(6166b5f9,63a9f47f,5fac49a7,8d175763,8c39cd49,11d16ccf,b0e83bc3,f402051,ba337661,8302aeb2,213e4620,4ec57492,933d6df5,5a045d7e,5317ddf,e92430b3) +,S(cd666e74,28901afe,8e67d0e4,48de7e3,30b6dbdb,a34db4a9,29315d3f,8b251531,af72d8b9,43cba540,e42398e7,49fc89ed,44095951,f11b24f9,e5451810,3802304b) +,S(c833be8c,fd2f6fe0,46d837a1,1d990355,5a6285bc,d7b8814e,e839cbad,523ac72,7ea8f90b,44112363,a8d75153,150c3b4e,b6c07dbe,fe8c8ed6,3a24984,c9a6af03) +,S(cc185f36,3036d385,d890ac1f,5e95b162,e40e4a4f,e8427613,98200369,f25ea477,e0768836,146d9c98,98aaabe5,a9ce12ef,f66d0775,4055eb42,832eeb9f,26338236) +,S(148e0863,24bbc2ba,b67c9be7,407b809,77ccd910,e92c9770,47943c29,8c9c4a5a,89e83c85,9cddfc80,9de733ae,6138e97d,b706a331,fb7176ee,55dfe3ba,c2408797) +,S(9b1539c1,aba5b583,5c88d9b1,92a3761d,cf8b649,54f53a7e,460e0122,bec95c76,391cde19,45be59da,d4c895f1,3aa1ce24,d8472e42,a232795b,967f21d5,acefdc18) +,S(68a2e6c1,75fb01d3,76a9e575,ff427cc7,a6032774,a974bdd3,e93b8a73,e4495cd,153e6484,c8c30dde,5f269b74,1c599647,666cab7,e273d4f2,5573dc4e,78e00752) +,S(58fe9049,35a5a40c,3b633440,533cccac,7669e9a2,e7c2f0b6,6c36c228,61dfb04e,b36905c5,92450e2d,71d06e2a,2d599a77,71ac1e27,15a79555,b39fbb60,5536e1bb) +,S(823c0f96,dcbdd9b0,bfdaff2a,19b6027d,3e9bca6,e298378,3375a783,5eac7080,d91546cc,f34d9a58,babeb6d5,43bf3c36,8831a2b0,d9043db8,895cd208,f2ad0a7f) +,S(4a56aeae,e908f908,55fe7b71,3013ee7,d6812152,4f7decaf,533cde20,2d14537,7e60c801,33b718d2,119995b3,3790eb9a,3129a7fb,2e030d8d,21af90a,c622b7a2) +,S(6c0f3855,e6c4f5f2,c4594e2b,8881319b,82a64bf4,9fe0968a,71f6ca3b,f9240334,5c8e7b6d,a9efbba8,4b5ade85,305aead3,e1478ad1,b4d56fc8,3acfe34d,23b5203c) +,S(d9cf8f2c,d1704907,15dde21c,f172e648,496e40b,5248f331,3aeba2a3,35ac9632,92a7c251,b440f930,bd98299,c35d57f7,15867e90,b6c3e8e6,b073815c,3c934344) +,S(4bfcb492,8b91dc7b,afa7ed43,d9af3039,77592728,fcf1b9e2,7c6767f7,b993d898,276a06f1,ecd9d410,b34c9a4a,e3aa33b8,1854a4e9,e4703dda,7bfca949,a45d14f7) +,S(abde5893,ac4032f4,4ed93dee,8156596e,7cdcc575,e5928792,944019ac,23c434e8,5e03a809,2b9e6044,e942af7a,7cef02fb,46162cb2,4c19916e,d774b00d,8195c40a) +,S(205d6307,7a98a8e1,178814b4,9281da20,4482f1ae,31be20a8,3b3b0fd,526e1cc5,4bbe295c,943e3560,6b95cb19,d6e64bfc,b9cab7d2,55657614,7a79ff50,6fe4d780) +,S(cb4c4c83,e6673a1c,6c228a42,36e6031d,b59653bc,45bf4b7c,3b98cdd2,441c43bd,142e0276,39267ea0,f7c2ff39,75afe714,62f3340c,1fea5149,cfe4e8ea,e31a2769) +,S(25a1f4b2,7ff5bdfb,3af54a4b,493356ef,92ccf0b2,dec7c4f2,b5abb225,2cca77a7,1b25dd93,153f8341,7df3b3af,c991f2d9,36c32e8b,288a7fe9,3e9ff97b,335c3c38) +,S(222f76a7,7eeca0d6,a511c863,a657cb89,5a1b7154,957b66dc,89ca77aa,2a54237b,a8f2bee0,64eff88d,87a598a,8665d295,a205c884,2f6a3492,7945a02f,2cb0b289) +,S(32d4328d,1ad2651b,41bf1015,6936b406,379f5c26,99f1c2da,ec3cbd8f,3b4dfa8d,9f6de6e2,3294a33b,5f4d4062,3e478096,df5de0a1,d069290d,204ce930,7988261d) +,S(cde9ecbe,6948cd70,3b193790,6662b7d,187d0830,cf991b14,e8265691,81f1d3f0,84887b32,e1218d2,9b77794c,e8ad56c5,f5abe8ff,f95515e2,4bce81b1,5b029720) +,S(bc89f45c,3baaef4c,a8343582,6506a006,509f4e7e,265e4b80,11d53d3,a748947d,eff5bca2,714db146,7a272fce,534f79be,9fa15af,7226ba49,51129f5e,6fe68475) +,S(62678cc0,eea2bbfe,2bd4ba65,5434a9ad,39b409b9,b57efdf0,9940f748,ddb51d4f,8d384f4f,d234d31d,1c161245,ef6dd54e,a5cc8ab9,e7bcc883,6735051c,37a74acf) +,S(15e01d39,c63ae225,63dc89cf,3dfa2736,df7c0ac3,4fe86f8a,f219f933,86bc93d0,1f563532,314fcb81,c1725133,49769861,e7efb999,fa317ef4,2bc75588,10cfb13b) +,S(4f8d2b49,3493258d,ff98e813,e428ae9c,52c60103,1bdbeb9,7b8f364b,2bac10e3,8c7d117b,67955db6,c0058028,3f919f57,1e8c58e4,216ca1bc,d66b264e,169b73f) +,S(d14ce31a,2bf16b60,983e397c,ddd3588c,3b0d77b4,f449136f,1a789276,b56f1d61,9a15f620,b227d83a,3722ca6e,4dd7bbf5,833f24c7,2584f356,11ef3734,ad3f0910) +,S(35221b4e,b8c275f5,c10d656c,9bfea000,24c1aa2,c4130841,9c3e8e3b,66f780f1,3d1c5a02,5274afcb,bd78382b,b2778657,6888d46,1b5dffa0,f8ec5dd9,3bf8e808) +,S(82ed9c3b,1c76c1b8,f44ff6f2,9f443b20,83f68617,7270843c,49eac0aa,34a8ddc8,262e9e6b,c2ab2b86,7342081d,90002690,e81f5a58,aefd6fc4,8a91dc5d,e95f1340) +,S(919e960e,acf2aa36,e86342f7,742e97c4,9c49b64a,ff5c6118,d181e349,10717b85,4b51a94e,a3ea1679,cd9ce9d5,ac329f13,ef530d42,c7821650,5a082fe4,d945b861) +,S(cdacae3e,20ce551a,beeabcaf,a643ce62,edca3de1,acf06c30,65ffd366,5bc3ec7d,aaacbb13,872b076a,e28c326d,fa54f4ee,235df4a4,b341c9b1,3d322071,6eb95bb6) +,S(1a4508e2,1bd05c09,f3d80f82,90726f08,de3a62ff,b663d5a8,f949ce26,92a5f2ab,52780ff0,976eb033,760459bf,4bf02994,c6e672c5,6d25d3e6,2b320f5,2cca97ba) +,S(8e46eeed,5686f25c,a94f73d1,3f26c98a,e9129f77,f3aa18dd,d5214262,803a0b45,ee56d38d,7041eea7,c87f2ed1,e7f0aeb6,7253d556,610e8200,782c9af6,1dedcf4d) +,S(782910fa,3bd6b309,dad797c1,5b618469,68d6171e,7a0a0532,a92e5bb3,697e4031,ff178365,c44c2a28,e84c31b8,946b0a80,717914ff,6d3f22dd,ee409753,44e4b3f4) +,S(2ab9e8c,c5a710ca,6cc2d0a2,94f1d7d2,65c50aa8,f9069041,ae93c91a,e5f64e8a,aabcd0f,a2254bad,67cf23d,a5934947,18536602,a13d81c9,db23afc9,a7f89b9b) +,S(d04667c4,4fb25b22,8320cc53,35252937,a094ddc2,4610f7a5,fcb1bd1d,6382c9e5,7c93613f,8bf048e7,86af436e,cac4fa86,6e5a91d8,3064f5c,e31d4794,b2b0f74e) +,S(b9c476f9,799cdda4,a51b0476,c5838994,f157bd29,c9361252,def4af83,6e86b0f7,2ec7619b,c77948b3,f25cefbc,46845527,d1a9b0da,a90529ef,f13aab4a,ca97932e) +,S(90bdedab,f13f9940,4b9d8c56,5d64739c,4ef765ff,dee2ae0d,64fda841,286eee85,a9f47882,d9a848ab,4be812a4,8187d26c,7f8bb8dd,b94f7725,5c628104,e0cf21f5) +,S(a0c394a8,2177734,c02b8310,74ebf0ff,ff4208cd,dcd59e7b,a680737a,fc485c84,c4f08932,b4c62f34,fc82434f,e9b7b164,e835cab6,2f34ee3f,d640e5d7,d09364b) +,S(1b0319bd,3896e8c6,284f949c,72e7694e,bd3c2923,ebeac273,b9aab50d,30294c3e,15dbfe9b,17c3aae7,e5f8233d,703b7b1a,1401b672,1da32080,53ed52f,a2ee339d) +,S(9914ef0f,e92f16be,a27a9354,518dcc0,1210eb3b,3a90f2ab,6992e3d9,bfdc719d,7a0bd065,cea0b11,e8df3629,faf65a30,5e671d2c,86332b83,98ddc2b1,b3c4086b) +,S(3a68fa19,5599f638,7dafa176,395c9615,5798ad6d,7ace7810,daaedd13,ddf60d3e,74575ae6,a3f569db,394faef1,e0641ca4,de158eee,9a8ac54f,5cd96bf7,d4e71a89) +,S(b7361d41,e2b67e31,f1872b1,b1bffc8e,41193dec,7f012385,9da69c60,5e88b2e5,fa9d6b95,66d49bca,73cf5890,f6e7acd0,315347bd,f10be9c2,9b0907e1,80668344) +,S(341e9987,42d84640,f6fd1354,3fb7ff9e,aa93a4d3,12e99bc6,37b85b83,25174e81,c49608dc,91b46187,611cbcff,762e5fc1,e95b4e9a,6ed747ac,8612b6b9,8bfcfc95) +,S(83d6a445,de34f557,40084909,402c9718,1f6420bf,af87426e,2a0f75da,c483e6f6,7a86db44,58c8fb53,5edcf48a,14a94dd8,e9fbed09,277db0fd,787c121b,a1dddfc1) +,S(4f11235a,14bcae9,89082bf1,c6a499d8,32d17686,2fcffbdd,a40b84b9,26ac351b,b50624f1,5f31269d,168021c8,37739cb7,8678ded,be59e288,6e963339,e94a2acf) +,S(8fbb5727,21cfe12c,ea685907,ab6e3d7e,eafb3892,c082115b,998e9a9c,d3ee2b89,da7fe685,c8148e1a,5cd8de8e,2a5b5aa4,ef1bb1a5,af8bfab7,91c923a3,66906680) +,S(804ca63c,b9243f5f,76605b1f,53f5989d,286023f2,fc672bd6,3f52c59f,5496c3de,372912,eedb1156,a1b8300e,eaeb44f8,865fab6d,49c89fd8,43170b05,d75233c6) +,S(b2795c6a,b83ca824,6b18de87,5660d04,60b48ed7,1de9bbf5,8cc1769c,2d2a5365,66e8c2b5,88530b6b,4d351044,186a8a01,db684157,9bdc041f,90d0935b,2a49d820) +,S(deb5304d,b61bd914,c0939d07,c0464eb4,caf3903b,1903a588,208c5e05,36d9dad3,18d54f43,e7e45e76,6a4b6249,1e48073c,40507dd8,3f7b3b27,762a06a9,4d5777ca) +,S(111bf502,d177ec34,b6c61d69,63366901,eb79d5e8,5749f5cf,7743cebb,9b7714c4,be80d52a,bc38bbcc,f036bad4,5e47a0f1,7d8ba20,fe6780f0,bf8c38d7,696a4e54) +,S(94b10f43,c15c5393,e8d4e71f,db863865,daceeb50,674d0f8b,161bd38,dcbe92a5,ec55af2e,a34e8c36,5b3f7729,110586cf,8d087dd7,f1a0ae9b,d25b9b77,f5be6dc7) +,S(4627abf2,2d447784,c53e529d,62d3036b,fb4a422d,10146248,d3b1f188,e895593,8b341d8d,6110b59b,738172d5,6651e948,cbea9ef4,c7e8dc48,3a560503,eb7b3e4a) +,S(19ce15cf,dfeadcc3,7375727b,5ddc5327,585dcabe,c172aa80,757ba468,297c355f,506555e,ce829141,736ca9ec,886cef26,83853e7e,5b3ba66,25cccfd8,4de60f81) +,S(75a40681,8293fcae,8c3e97d8,e1f916d,2950682e,16d3def0,fe6dcfd0,ab9a3e55,5292d5c0,e02ee24d,8139f2af,495298b7,4526780b,f39f5f22,a047d155,dc8c7930) +,S(a7eb8b8d,ef4b7686,b47a341d,4f4a7333,88cb82ce,8f3226f1,cbbf79bc,1f3bf578,85d98b6f,e238577c,b3b52bf3,94a72589,24407ca2,86865cc8,80cfc93f,bd8199a1) +,S(a5b9a2b5,dcc91d67,b352d14,3c19f6b9,6c9f8344,50e16c00,e8a938de,b3da647a,f12d4fa8,39850471,64335aba,1260cff1,26fc4e13,fd16cc29,63472f28,7b9571c1) +,S(7999c6ed,48d589a6,5df7c20e,e9b0fdf5,df58d831,78ad6171,57c09cc8,44015cca,156f4505,3706c3a1,c54b3fec,bd3f12c8,aaacaf0d,22755014,5bcb731d,418f5756) +,S(88fe81f3,b708edd1,b85baade,6c05c7ad,42202058,6dc2e8e2,fead379,c49829b1,cd62e24f,b04b7d2b,b1434150,260a052c,8972a8cd,daa1db10,d99d40d7,df727c01) +,S(18fb0eb0,cfcc61fe,423192be,b694a77d,91216537,5087a64e,89557d5f,4fe86763,3cf72b1f,dfe8b565,38e88e23,ed871d7,80f4a6e3,55229922,b1f28c5d,38169785) +,S(dadb3231,2be4f2cc,cff171d5,baf18e76,4719fa,eb5fcb66,d919c86,efd38aac,8d67945d,752de8bc,b0740e42,3a154449,50e0b330,c6a73981,3d9f4b30,f98bc0d7) +,S(f0b9a086,7cdd9f64,6b3aa0cb,e3105ba,7b17e09c,6c1c39c2,d8057f06,a39e5c8e,2b534e56,25e6d180,40dcf431,9821cbbc,3ff91303,c14bdc81,370c9e0b,5ef4e9de) +,S(dc0e0b05,2e49c3a7,e5d0e253,672e8d43,1cd60166,648b932d,406fbe8a,c2fcb7e0,ff919786,8e1c651a,4cd39cb5,6921e24a,223e7af3,821fdbea,86547e1,c7b791d9) +,S(e71cae98,fb6ddd47,35ec365b,515c6ca5,6bea748f,11811038,b74aa5a2,32eb91ee,804ae818,396c20f6,e2fc5bc7,5dbd1f41,9ed731a7,2801d06c,e6682bcf,1d600266) +,S(50d1b5b2,f7b2e4ff,3b594d48,6bd2ca6c,6b5d5368,2079bb9f,88d792b4,d4ddfd8c,556cf4c5,18fa0660,86b9b03f,aba18fd,5c554fe7,4020df5b,6e34bc88,4d5cc744) +,S(c087403e,2bd5d954,df8c5e86,f23f6cb4,96634886,b4709747,325321d1,bc2701aa,9db44987,d8517300,6e3a549,eed87e06,258bc14b,e2b00679,3a2252,a3507712) +,S(dd1037f7,f3843422,de8988fd,3f68a299,4d45f8f5,1e9242b3,7980f517,bd6d6894,ca8e6d61,5cfbbcdd,8b1ab8b7,673093a6,1a9c08ce,56b065f2,54fc191b,25cccce1) +,S(de229a19,67ca589b,f4a840c3,d18f764c,424dfda5,6c099d14,73a9cc7d,34b5ceb4,958fc9ca,84ca63a9,4323f4b2,ae46ff44,a1d352c1,1b8e8be7,2d5115b,54122b22) +,S(15e33c9,cc9d84fa,16225f48,70a35a42,f8a3a3dd,67a8dcb1,143c7ee2,4cdfd9c,413c0206,ed48cd5d,36205836,45e4ad6a,a59a1e15,c7f36256,2f89b9b3,660e920) +,S(53422561,ca3c4d87,2d23e317,3b21ae38,dc010b99,b7ab0fc4,394e408c,a3d6bee0,6ee906e5,e505909f,6507c7ab,779ce1c8,20f2c50b,a71bb8b7,8debb3fb,6103048e) +,S(829dcf4f,9b2c4f37,32800bbf,f5cb71ca,308bf0a,9176a74,a031d972,9a82b2fc,47378200,429e538a,4e249d3c,9f58873d,abe3f8c4,615c5d3,3525f6ae,5f8483c4) +,S(ed6f6eb7,3769b1b1,4923b989,acff97f1,c05594ba,1d5f4ebe,450e65c3,8ae911e5,dfee6f2f,3fe584db,8b98cd0b,69ff6219,d52e2d9d,a372ffbe,18e500e1,a2c38eb4) +,S(47e52398,1fbe720e,8fcd1982,df2b184b,70616ebe,cb4913da,30327205,c0455503,afd2dceb,f360c30f,6820cfbd,1de0de70,179f4cb8,6c461251,5eae2f4a,baf3e900) +,S(b02937d5,8f48e1f8,6f3f1170,f5e880e4,ba10e2a8,c13dd0df,49fde04b,a9037312,dcb0a4f,3e4c8456,316de580,5355e17f,8a6c7924,f68cbcf5,347d3c7a,28c18c4f) +,S(9f993cf5,3578c1c3,25c10c2d,c3c066eb,878486eb,dfdc65d4,4ee57fd0,ec1989f8,c6b8d40b,16b8811c,d666ea43,2e61baf9,e83eda6f,d38275d,9143b386,31c8bb52) +,S(943b6cc2,5913ec1d,f12730ed,bdfd1d0d,ce431784,f36fe84e,599f9b89,dd3240e6,e58102ba,cac2ff3f,d42d7ca3,254ef55a,9604d3ff,fab5b16d,9f77482,4fed3fd0) +,S(9b0e67e,69b3f9ec,51843da4,f7b5a7c8,59511dcf,47f58a64,81fbf2f0,19acfe0a,6a4ddc28,17a4ecb4,ce2defc7,d7333ca6,2e074c36,f7e49c67,4a009d30,edc54dd8) +,S(97dcee33,9cd8d18f,8c3b0fd4,48ca6e6,c8246b4,136bacc,72ae8673,a4571651,6163a205,cc20bf39,8aae36cf,c8933dc6,29b95246,48823d51,d82d2d2,74e693e4) +,S(a1e5e6f9,26961eda,7cea9c26,f4a1ba02,798c940f,2b7dc267,2999ff7a,d2292ced,50274b7a,6a710f74,ed138401,36d97657,cfc07af9,3b9e8fbe,ca18d31b,8d5f19d) +,S(473d5fcf,7cdfddfc,52fc9bdc,6fc77180,1c21bdb1,840821a6,1a984296,5b4884a9,348836a7,ad7f550,feb2d703,6c82d95b,89ff95eb,e8be6250,eba7c5b1,8fd856af) +,S(9c187442,7384b2d0,4fcc33b2,70544c98,db8c1e13,2bb149d4,54c51ea1,4796f613,2d6dec43,970f0079,3da12e47,595cefba,c1825d36,c71342b,7913f7f5,fcae0a19) +,S(11ce1c46,9150e2bf,b742d826,be740e4a,ed63c729,5f5bf51e,c7a6aa6,562b154,6e86514f,ea38280f,abdf8b93,be8b7d92,67f3b28c,af2a4271,aa3b6a62,1f4fa33d) +,S(1e037904,e4e2de6f,2893c354,18d1cc6f,dde2fd71,4bacf1cd,4d9a5c56,79656042,1bb759c9,34c26821,2a28aa38,a0af035e,3c81ac85,3c01e21b,462e81a5,8c960755) +,S(52fc9467,23f899aa,f1a94f24,f9e3620,3f8d505e,31cc6800,9951d9a7,c0071d82,4632ae0,75430820,20cdfb99,270b47ba,39c909b3,4b3a39db,92419697,d0bd6dbb) +,S(cb585905,997519cb,214f9e39,496f5386,35069eb4,d78dea4f,f9e9d803,642b20d,1b9f42e7,a5b475a1,e42a0f51,ce2d5e50,7131b2f3,5990ed45,64e3913,ec93ac7d) +,S(382c2857,29f14558,75727584,5d37bcd3,e7ab180d,a11c7a12,cecae00f,b4a69c46,cb27e912,20a70fb3,6e258684,3f128693,495907a3,e0b248e4,a25c1e7e,54039440) +,S(16f086c6,c2850e49,8f8456dc,eb33a692,a4dd613f,b2f9564b,6dcecb88,4f4e5024,2e152a08,88eb1188,3448ca68,25a65034,73cb5ece,c9ad5df3,12deefed,279339a9) +,S(7589bd1b,1f0a3577,5530f0ae,446ea275,4439a51f,66730950,6eed6177,65a02492,2d840e12,d3758153,1e5771bb,14d3634,4076fc3,630c389c,ad9765,98462d49) +,S(18b9ae40,cce63a51,3dedbd2b,c3beee9,a80cc5f5,a26b4446,9a0326f4,d4930890,24b86a4d,d5ed3c44,71b57138,2b270d0b,9e0032d7,8e0ad18a,cf6a4eb9,2a2690e4) +,S(8c1f74a4,acc71ef6,4030db5d,14be8627,94e9ba6e,102c89a4,ccfe8a8a,d3ebb48a,a79f0119,98aea529,1e3ba735,c8b26c86,1af1c119,92d5dc94,16eb1673,9245677a) +,S(8d80592d,36bfaab7,5b557ba0,d03825b4,2c0fca08,8ec7d046,5cd2c203,c2bfb080,3e479487,91f27453,4d0a1bd4,a533fd2a,7671a654,10cd7a51,859b466f,151d3f6) +,S(eab0bb19,f477e158,ec85046c,f2c56777,f36782e9,e0452770,f7125765,670ca248,a27d7081,23093af4,daf55e56,32ba071f,37f0bd64,3f189ebd,70074cca,7cc04640) +,S(ff0d0dc9,ebbb2fa2,6d3b249f,d5260ce9,9647e1d,db48799b,db532c6a,2a0a039c,12b0f6ae,7f161f8b,ce1c3505,5d9b760a,fad5b0f5,66211023,3c43942e,fab31fa9) +,S(d89a3235,71dbbd1b,92340346,8b08b7be,be22b320,3ee6b0ad,42a2aa96,3837d526,25da35b9,9988f167,3108124d,9e6f6f1f,db4a0490,5546fb62,146b7421,36e3cf27) +,S(f150023b,f01cab2c,433cdafa,86751f7f,13ffb315,55d34a22,9ec4c012,925b43fd,31f70e21,26ac896,6dc966b7,17a9e483,8ac37a6a,2072bf34,1a9c3d33,3ac7a9cc) +,S(d98ebd3b,2d580978,72ae9d5e,2c2cd0da,76f442c8,e0b4470d,9b3ee019,c83af2a8,9ed5b6a9,5a061970,34bf9873,da6c7224,930fb358,a514c823,e0017c92,75dba3f5) +,S(55b62d85,833a94ee,dfc2e313,df3ca816,8173533b,fa77d827,583fb01b,cbc3c746,9f848773,cb95af7,b79eb921,19a7a139,1f4dbbbf,44c81897,15bad111,364a835c) +,S(dfaf4d76,fef73f93,44c69de8,f6c1c3fc,ec759c49,a2a7a1ca,2860fecf,bd718de6,ac4af693,44e2c287,f6409f94,c36d93ed,7fba1f15,195bd971,357d3142,725a0671) +,S(84a444a3,4510922c,37420f29,a16ee22b,a7839f3c,5810cbf8,38b7f3e6,c5fe29da,ef733d80,2215c12e,143f420a,673069fe,6e89af70,cbf975f,a1898550,1114f06a) +,S(d7c84e11,46c87008,3ddd24d1,296811a3,2c337749,83892548,6291aa53,a72212af,b187dd58,a3be40bd,c3d357e5,480aec61,9579b2d1,4d79745,f84cd406,10844ac4) +,S(fdedc27f,a70b08be,f3a9f616,575072cc,c7fca4b5,71a2ea06,9ffea788,5598051d,fe9b7b1a,1c575a9e,354d279,ba7f4de2,53f6f54d,e7245fbb,3ec462a4,7b9bf9a) +,S(cfa7478a,d3f2cc6a,92022b35,58437b3,f950c250,4d96b9a5,c2d5c795,ef122e77,f3e48dca,e9592835,354f8eed,ffdd4c2e,2ad7800a,3da863bb,158945b2,261409c4) +,S(8e9157f8,3fd62097,70fb7493,d7678fce,aa1584bc,d8dde3f8,337dce8,ee0eefe2,6079ba89,8c05dfb6,ba4f91df,4b4b229c,3322fb5a,44fa988a,c8d9f3a5,3a05351b) +,S(7bf5efb6,103eac30,ec4eb80a,9bddff22,9d422ffc,6a7f9dfd,bea8b928,3116f75,efadb659,64791edf,e5935554,25796141,2cba4b4c,3553fe67,ba138931,3ba71a3b) +,S(f5ba02b7,b7b2c2d2,68c7b1b5,37697079,690a13fc,89d1d53e,85f27820,d0e8df0b,66316d26,b2640e41,bfc329d1,9d2d4430,a9266b64,c3c793a3,af7f1515,9e465485) +,S(5eaacdf3,dceca4c9,6d2bc3db,f22951fb,87c10da5,f1250828,4a1498bf,ff004475,cb3db3ed,9721ce09,16985d40,4831cd04,b38f5810,977ea106,c8c25194,ad1f122d) +,S(1cfe5c17,b8d61134,53552ba6,ad513371,d1320abf,4fa2de41,77c5a768,a64a5554,53837cf6,4846b887,1e64a2f7,e319f740,99bcabe6,7a0894,5edea46b,fd1dcd5d) +,S(92a83f47,8a2ccc86,1cc91dd2,a1210fbe,286f47bb,44e46880,5e21f0a3,7a5dbc10,fee35c65,fcd45b02,f8270b8b,c198132c,cb69ff9,ec35043,684f54f5,c999de94) +,S(172285ba,d5d539b0,f4d86ea1,35bdb79,73c07ad3,24bf5dd1,4f74ab69,cad277d3,45abf940,cf356364,e0bafa15,cee3e20e,cfc29040,288b4897,314c22f9,aaada654) +,S(ad17bd53,92e19bab,8554ae08,bf9158dd,3126ce81,3a05c32c,7646eb73,cb164762,a129819,1c833987,775d4f47,d9d70d4f,8139c651,896f9b94,e164574c,8d065586) +,S(10421b3e,91a4a89c,1f6ce9e9,13e511c3,c23fd307,c4064a12,5267cb31,2ebdeb1c,539bb5d0,9e49f0fd,186b8a51,73118cb,98569700,dac77cc1,92359286,3aa53319) +,S(c43adcfa,78152a3d,dcb9eba6,6632aa5,2e8476de,1e0e30ff,39735b06,21de5bfd,6ddd09ca,2122580b,847d04f0,5dacbb7b,1e81c6e2,6057d880,1a911a55,9cabdebf) +,S(f7a99ccb,603a58d0,4c6b9e50,d9e7d988,14434f1d,92aae27b,5c8d9006,98bf9a73,ccdfc244,76f4393a,e96d6809,1cb74130,5e62934c,cafc9b08,78a3a77d,a71a7ccb) +,S(9abc95bf,70174ea3,5038f44f,4a2ca9be,f602d516,9d249aac,b3175be7,e09c826,6cfbceed,3e71f8a3,d427d2c9,f8cedaca,22a9fedb,4cab7763,617198e0,d7adfe0c) +,S(8a7ca893,35c84873,ecb4af06,b493c9cf,d7bd08fc,d0535c5,546bb9ed,5c5d8d82,2518b372,90d3c08,72f1ee4e,54144799,209ae3fe,d2f285ba,7b00193,21e31bc1) +,S(70c8e379,8649628d,969182fd,862f8d4a,b39fdbdc,c246fb79,ff1c9227,a64d1c3e,c7931ad5,27ec0a4a,ec297d9e,fd56208f,936c9517,4efdb86f,7f50e321,26ea3cbb) +,S(d783f6b4,6121ee0,71ddcf61,b4808fdc,934a82e7,c185876b,9572d628,31002121,aa92bd84,14226949,9e107c82,b9a64898,28b3ed15,694ba62c,a031d98b,5e9c7fbb) +,S(c1f06a1c,29abb43a,cadffbb8,7ea8e4c6,b7592795,9c778758,1a17e4e7,7b654c18,1dae0de2,f1db42cf,ab9b0e7d,9e5a098f,bc102470,aa418547,6cd1925e,fbecdbf0) +,S(2ad74e11,3205b587,866633ea,32172662,d1498a27,48698724,87b7e62e,52cc5105,c70c7507,de1fa1fd,625aa7d3,755c83a,b5c85159,4b8bee10,5de45da0,d0ff779e) +,S(f490e9ad,72246a46,6eb74e23,371c4f57,a9e32b57,74ac9ac0,3d800978,d77408b6,546f367f,8fdd1687,ba6ef15e,4c258507,77e49a1a,8b449fb9,63a0f01a,a9dc3d6a) +,S(20502891,8357b697,e05788b0,55f8bb32,80c431c5,de07055,3f123373,981d6149,39d040e5,44110e22,58da6771,2852fd09,9489ee5b,5c77a777,7966abd0,468e3b0d) +,S(6e91bb8e,c169a3a3,eef59915,d4de9296,e4b78299,e038c5d1,bb001eb2,f86eae95,d2c21297,88f8c9f1,16434063,a89fac48,45305dd5,d208c887,2ae94ba2,80877dfd) +,S(cf2947c8,39fc40b0,610d0d2f,e1e5ad53,39e7d0ba,9e7dea01,90678bb1,6ba34905,6145a70f,7f0cd53f,d758d7b,172e875d,8db00f6a,131ec7ba,aec140b2,3f37c63d) +,S(b48f8387,ea93a6c8,561c9b01,ad32a28,1c8db1c1,ac3c6864,ad161874,fa2366f1,2cab333,cbe07d3e,26fd971b,3609cfc8,9f46bd81,df84276b,375315d2,7a2d253c) +,S(7c4b5f66,c572d34,e4cae58c,696fd43c,30f6054e,8145715e,f391eda1,42a1f827,3cbe264f,be125af0,3907c5fc,c61232c2,d0adc2ad,5f94f3b0,8ed32ad,99843d97) +,S(e5796368,d4649e19,6227f989,78758d9,8fe24e51,f5d5a567,378a85e0,850d86e8,74bb343,c9a69128,9ae880bf,67a7e4be,1fa111b8,d6608896,46ec354e,f6c9d4a7) +,S(dfa1065e,fe83e9ef,c19b8841,6e3ca5d9,67c1ab26,53c7d650,9f02ba58,fc4d637f,22d2567,eb0237ba,2f270e04,685e5352,e23fdf19,a2aa0a23,1ec83eed,ca5042d) +,S(2ea1d8aa,d436c332,8fda3ce9,8e710b80,8f463844,cf131f2f,2347b37a,928af132,33fa7e0f,b8c2ad10,580a243c,ccf2a4b2,13ff9620,7a034432,8fc61f31,e98dc4c) +,S(12ae1451,8122af3f,a788298b,5e59df37,ab6a976c,f8a931b4,c0a51de5,d567253f,85ff1dd2,b3271d2e,de2fa732,9e3f0a5a,1c3ff9ae,b55555a7,926d31a0,1d24877d) +,S(fd46e1ef,b588af1a,a72b84fe,dec75a3b,125579ef,55ef8270,85645930,95bf6619,d06adc6e,ceb6292f,60c7d477,c73a2aff,342e6b7a,e81c5ea4,f57cb7b,27a51b17) +,S(ed7d93e,b8c0d1ef,1c49e1bf,be22acd,c7a17946,b172de61,4a290d0b,7f32b52b,4d0ec30a,39a81c3a,f8f6668a,742abeb2,b5552284,a68ce246,f368ce9f,b2303ada) +,S(fccfdfa5,cd0e79a6,9febda81,475c06dd,58517913,3624f4dc,9d808b6d,e9619ef,79b9040d,11d09bed,f89959c6,992a9636,ec62324a,d60e1513,9bd2441a,dd0adf49) +,S(831762b8,6a9b9afe,d2a044b2,7bc714cb,16823ea7,22b44010,a57a5564,4b4ac477,147ae062,8ef3bfdc,b48b3f77,f84dfd77,2754c1dc,a626aff6,9c3169e4,9956c708) +,S(33448c01,a84d5303,c8f70adb,bfe0ccf9,f92cc461,f2656fb3,4903b99d,4ef26b01,e5727349,ae8ba61,c8ca8284,ee7f906,208ad03c,6fd7c95f,736ea541,ffb8f2ff) +,S(920a1261,6ddf1304,157ccb8c,50ebaf6d,60df85da,b19b24a2,48254cc2,7d215a6,19e4d4f9,cc91e890,3d2f7a11,ca8c0b97,e2cb671c,e0c4ee36,9f1a3ca0,f28d0f4e) +,S(1df8ce1d,3e370b9c,3f60ac00,cbac25c5,458385a5,c4b926b7,fcafe62e,536b1ba4,344df46e,e3635079,52af6160,2729094e,3fcbabf5,bc701083,533e7e60,5099a92b) +,S(7227847d,abfe26b8,13c18175,c37a0526,2e2243c8,d80d93b6,286b2881,d38b7b72,bede79eb,33da3cdd,95289c93,46165cf9,28b5aa41,c46b364,622988b8,a7973d24) +,S(6defba59,e1218bfa,b02571f8,ccc84104,3caff74f,26d8d995,9729f292,eff7fb8d,4d7baa8e,21f2fbc5,96f770d1,bd34e77c,2c188c05,5921c1a6,95696a8d,4c340a04) +,S(c667f4ef,f5127d24,6b31ae02,2adf53be,8302e1a,b631a0f9,90b16051,e02d6bd3,3d7bce76,ce11bdf6,fd4d822c,37d746a2,f8de283d,527af237,3e80c4a4,dad34cf5) +,S(ed9e8674,441620f5,990dcc24,23a2ab00,6fbca1b8,e6bb3d23,55c2c72f,ce29d866,64d5ed9b,b4289a2b,b81a12f3,30930dee,7c03dd71,1ec361a5,8297c22a,5806ad30) +,S(86a36c57,e6b0cee0,33c00b25,66344ef3,219e57ee,ac452ea0,b0eeb98c,3176fb24,b4f4bdda,9e9b58df,4e103874,89592b5d,b147b43e,79a1af25,135e8db3,eafff739) +,S(2e237784,45396ff3,a0e105ac,ba151e3d,fd02bf82,1de70e04,33792280,bccca913,f736539c,e77983f0,610464c4,3bbcc904,f43726dc,a336304f,c0b716c3,67148551) +,S(ccd3c14c,7790d936,5226dbcf,11a0bc00,9db88a87,ac2d68c1,6899f980,20a1390f,b240b35f,bd6d5dd9,f33bac2a,f1899320,f8a9cba8,7df0a67,81cdfdd7,1c3af907) +,S(7713be7f,988d7b1,c6c6566d,558978d,eba4efad,b82761b2,17bccd87,3637b018,8fb91a6f,a9d62baa,2eeef7c5,15fab341,c75f31e6,64ee7d94,70db34c2,74475781) +,S(5485ad60,35dcb3b,9520acf5,6b0855cd,34c739ff,1c59798b,1ab667ba,a4982b02,1dec6c7b,1e7c14ca,743df62e,589311bf,57cbd455,e7dcbf9f,cd439962,96a90f0f) +,S(a597503a,d3be484d,1d2d1cf,c4e8540c,411bd201,f2b05ed1,89c9a3dc,b0ee0f19,35113e7d,38001199,1e2cee66,4dbcf490,becbd6f0,765c94dc,e2855ee3,b01113cd) +,S(ba91b251,abb130b1,57dd07a3,dbd2fd91,1ae24937,80c8046c,b94de57c,dd91ce4a,cfcc2080,500aedfb,a69f33f5,4f642fbb,8377420f,e1799dcf,e1dc3593,d3e1f6c) +,S(adfb5a58,83cc7bd3,c6fd3386,95c86414,5c6d2f4a,603fb2e2,fb045bff,86d324a4,16574ed7,45d82dfd,c50415a1,8c30da91,3a525753,cc975722,22a5553f,7b0cdc5c) +,S(1084914d,dd710a5c,ac854b14,10a4be35,ba1f13a4,e0fba3e2,9d94edcf,a3561ae8,653ca135,3240ef60,412ac6cd,adf8e664,2f2b74a3,5908c3ba,be6dcf85,49c25e99) +,S(704aa271,9af38b14,17a8abe5,b881efe,81876a6a,f807833f,133cdcd1,6e6c6f7b,a6fee2b3,48c1180b,c48726c9,be2a1a41,11395af4,42ba7b92,63f4f66e,a3769e54) +,S(46048cc1,7f5d2a86,5c1f5734,893c6683,fe68b0e8,942c9080,51d7b836,a8aec289,d85cec30,89a8f77d,75bf9c6,bb4f8a33,2e766834,3841b277,a461a079,8b288efd) +,S(50f1e6be,315d3b21,636781ba,8598d2f9,7d04ccf,5ba1fc76,3d547657,77fce9e9,f7dcb7d6,2057b9f2,8cc24975,9dc9621f,25dd0ce1,47e00db7,d095fb0e,ee6b0b00) +,S(7ed0a244,676655ad,10efa03,7748d49e,944df1f3,5bd46d0,3b7ffcd0,a63501c,a8377a65,593f227b,446eb266,936ae475,e9b3ae65,a60768d8,2690d0f0,5c18c21) +,S(d039ca1,ee66c2cf,611c431d,cff1bd2e,19b29d3b,b1f37342,c29f4632,4febccc7,db0d0d82,14f4c661,629ff5e2,4cfdcc84,6e652ee1,15a6476e,7813104e,696d736f) +,S(c27973a,cc55fe2f,4531768d,94cd4a0e,8e36729c,aad61579,7beed810,a7b092b7,cdc310ea,b36ab246,c56d5402,9b9e3314,878e1f1,ff7520db,43917a14,1f41c99) +,S(36842942,cce3c683,25472e48,de202d15,ac14a180,3a2dd84,6de0c33c,6446e945,5000b3f8,19ab82fa,3589db9a,eed5609b,208d95fa,ddaebcb,57403b96,7b8f2f7) +,S(d1aa195c,338621b5,19ff3a8c,55abb454,74865ef7,85e0fd7b,c4554ae,6d62d0e9,e7e1dd33,dc293859,b4634576,d8840630,832ce773,a9a8bc88,c2e67251,a7b737a8) +,S(4f423d32,607439ec,366bd6ff,5766ec13,a59b2c2a,8cd008b0,489f267f,5c0f00f0,5e3c7e9d,7ee94c15,c048e6aa,272c888c,b6c3e058,4b4f4ee,f5e1d787,a4e7a9f4) +,S(6bb1c680,ff8991ef,17c0859a,9b5fa9b8,ebcb9afa,af7398c5,9101bb99,7f06c4a,318da775,d912ae5,d17c242c,97615c5f,217005fd,535b839f,189ff3c9,8669a253) +,S(14095d4,4713a46a,5fcb251c,9fbee2e6,bc393423,30303b8b,d0f2d09a,c0096f68,647e000b,3660b374,959e632f,6867c7fc,1c7aa4fb,b7f5593,22dcb2ba,e604a2b1) +,S(12112bf0,346e9c6e,4a8f831f,6c087876,8943191a,38e9fb83,8b2613b0,4b5e5323,e4149ac2,cb4533d9,4c3abf62,aee4dab9,faf64065,89cfe10e,30a42986,9657a3d0) +,S(f99360cc,c2ed4810,d80974eb,eaeb59fd,4f2197a7,8459729b,4f75c370,8bca5738,b92a2f5e,86d77a8a,c2c1b9f8,6e1971db,a06e4414,935020db,c0c83a92,ee6f1cb3) +,S(2dee5a4e,c81a3ecc,4872112b,be53f51e,64ae779c,49488567,a654e806,ea809ca4,1e2ea8a1,df6d47c1,c0aa1bcf,ffcf260e,bdea4d63,934ff3b1,bcb1e1a4,c73d4954) +,S(5baa6a2,139eeb78,f49638f7,b0dc5010,b73688d1,bbd746a5,f2382c7b,d461229,72677383,10a352f1,9f2a75cd,9e42509f,b08a0ca9,60154693,cc01d595,25dca81d) +,S(a3f77eb9,321d44d6,b774a6f3,b1319e46,f60d102c,d96e983c,8f8568ba,82913d70,f93d75df,8271e70f,1aa38630,26bec1d0,f6db1765,77470077,d3fceb8e,5c613a05) +,S(46ba66b5,fa1f9274,378fd62d,68ae9f38,8588d766,ebbe97db,72f9084d,c7f2cf08,5473e24,3078b8df,92df9b55,52ad5055,f44bf7e2,ecf0785b,72db5dd9,238897f9) +,S(db6a0246,ddcf0260,b2b415b6,f551fad0,bccb15c,ca196af4,291d21ce,ce80dbf2,396cd446,f93e1c97,a56c6f6f,63cd0966,5f88856f,e75e1c7e,a985917f,28591d3c) +,S(b82f8d1c,a7a298da,3992c4e5,8dba1b0b,38187eb8,66992e8c,5cc1c834,6e6c8fa1,4b0ae76a,f9b0413c,8d4fdbdd,db767c6a,b1b80589,533e3ee0,28eb6036,1483461) +,S(446e96a4,dc9264af,e9cc6348,aa612861,d106fdd7,b7ff94a1,82e0f018,c485f000,32dfe3d9,21593a58,1fe23b7e,ccf677bd,2771c40c,a612a507,c8e33df0,99568440) +,S(c86f10,7bfa6dcc,b9f00ca3,465049de,5c8a3e6c,d85bdfb8,1ada1d39,303a2eb9,e64f7066,7e910814,ae18c6a,7323474d,9dcb277e,4aaa7ed8,88bae4ae,7c34219d) +,S(bed8eb6e,cda14299,e4cd94cc,202be7b8,9201c2ab,302a5cdb,83e5f5ba,db6cd710,15736cfa,b375a40c,5d367b9f,6692746d,16a1f03c,20941256,708489a5,5d411aac) +,S(b3efa7f2,c5f6ad10,41f171b5,ad759480,665e0a52,de82a881,da1926e0,8f64d38f,3df63c84,32761a24,eb0dfa,ae98e034,b6dbd361,3fb53ff,c535fac8,ff1677e6) +,S(b0460da0,cd869b5f,235213a8,49e143e1,8fa9afc1,651ee921,ebdc525d,2715cbd2,c11a3ead,f3541877,ce73b4c0,2b57b299,46b4725e,cf630eee,865bb121,b86fd7ee) +,S(28b09517,a17452be,b2c19187,12d600d4,b4969253,a7d0d52a,49cec3ce,d73bc071,36696708,73c7591,11163518,40af594,40ffd6d0,690ddae7,fce7a43d,e920a326) +,S(521becd8,192acb58,7ae76b7,c0bf17fa,ad86afc,47157753,6b1a51b0,fbb5f136,648a54c6,d7aff13e,cccf399e,15451682,ee06710e,edf32669,1dc7fe83,75ac858d) +,S(b7bc19d0,b7fd9d65,26c9bca1,b587d84e,a2a200a7,76d39082,368b761f,79f6cf67,5adefabe,e0d0c8cf,4252c29a,773163b6,4a1e9ffe,ffbfe3ad,2f796e8d,1f70acae) +,S(e48e3be5,1b6ca8d5,41f0c241,21558cec,66db7b6d,c13e7114,dc931f0d,397aea8b,dbcf6357,5b16e2f1,30f064bf,ff12b465,f6cb3a3e,f9f74431,4bf41e7e,e0f28ac) +,S(395c6de,71c692a6,a3247596,8e28f2a5,4ec795b5,9759e890,9b2f4290,9f455751,ee5e0118,3c7dda2,c1eed4e1,5aca155f,b5b097e4,499bc3c3,fcfc2c85,a669a13d) +,S(28938ac3,b1184399,22741291,9c0fec36,663da3aa,8a4e89a8,1a66052b,ca808d99,4ae8de7a,b1ebc1be,a2beadb1,80cb9a10,da168295,ba1ea5f8,310b986,4f174603) +,S(5c0f618,95e88cf6,205472f2,3e27e853,be3af64f,d0a376f5,8523ee6b,5248f5a4,be5c3c55,cd09ebb3,b7363456,9fdb50fb,8473e3d8,3441e624,b41b1c3d,e44be51b) +,S(abe1f7bf,22d0f733,ed28e125,f7ed05ba,ae2e8f13,1eba2ec0,1554dac,5e3ca1d7,2a5a48db,3de31f6a,9708ffe4,b996cb33,e553e6b5,95aeaffc,918aa2c4,1ab0ab4e) +,S(c3042427,57d370b3,79124907,ea609129,5f1dbeec,442a6349,bccfd29c,e08d8be7,67a64eb3,3e0fda75,535b35e2,f8c9811d,528959c1,29e8f144,8bb75ce9,b1868934) +,S(65a59946,356f219d,77af0b6a,9e1a43f7,3152746,6af41c21,c81532fe,3140f5b8,64e7128d,5d3e4fa0,518cf27f,c070da20,1692b059,3d84641f,2463a61c,74f35918) +,S(6c7d2e3b,48428c87,46b066f2,bb99da10,60311cb7,d4dae19e,de2eb53f,141413e2,4ba47bf,c2e7c670,4de2864d,1ed7b383,286292fe,28f7c7ab,2a664bcb,6cb7e3a1) +,S(dd257bd,b99c89c2,b47798a9,bc93ff57,5655797f,a45399cf,44acf58e,93fdcdd9,f8d670f2,a9207f25,52e7e0d7,14289103,e8194f81,6390e0cc,1af2ae36,c1b3e4af) +,S(2516034e,b8ddc424,42952b8f,acd47c62,6827b87c,b08f263e,b2aab5e6,ecc23d7b,ad8e8879,f5feea07,ad3545bc,a731dd30,bd2ab534,4b486826,433c75a1,6216ac9e) +,S(7e723054,27b591e3,b19834b3,8211edc1,7f075215,6591980b,907dce0a,d934246d,5c91fcbb,d8c184a6,f21671df,1098760b,2506bee8,e32474e3,3b080147,4e63a71f) +,S(1b1f9d16,ac3c0d2a,4b87691,45a6f6bb,8d4fb57f,ef9df33e,72b5d399,6dd1898b,6442bf1e,5ffe450,b14a399e,16241a5a,15e94453,94519bd1,24d0a67,f35b4b1b) +,S(e0f1fa4e,57cdea43,a3b9f671,596631c6,65b5144d,93c51a23,e9006c63,fc872f2b,c83851fb,54890d14,2f605617,151dd47,74f9a3de,cd27d864,a49c176,af32e564) +,S(ae95bbb,697c820a,251a3667,b2a0a078,40efa027,99d7bd0b,3e9a12eb,32728c3a,e0dbba97,280096d,86ea4da9,45ae509d,1140e0dc,7b803f10,e685b148,6baebb41) +,S(fc8ff885,d52ef42c,1fe529ea,853ff8c3,afad1ae,6e7f1b30,69e34076,682aed31,525eced4,b26e8f62,7b904f1b,3356d01a,9cced71,432ac850,433e0a64,b1e3dd14) +,S(6613136a,459d625a,d5b5753,3a965a0c,ed68d63c,13652546,c629cab3,32c8e810,10f29ff8,24d30a94,b3d732b4,3b168bd2,28b4cb01,4012469b,93a9853b,655b65cb) +,S(45085915,7b683327,c76309b3,96ef3b63,19dda841,f6be1b91,f24f5a37,ddea56f0,b9a71446,584a88e4,6a155e34,f08d5a6b,2b6ebbbf,b4b1aa12,bbc7654f,91956821) +,S(168ee3bd,8f10ba0d,deb82576,cd5e1711,be58af4c,2274464f,e32f3f7,7c8a4325,6eef1e63,43ff409f,a916891c,982f8700,465fb184,5820b886,68b74202,6678b34c) +,S(b3191d97,763c2341,4eb4db8d,eb2003e4,fdd86b4c,6077931b,71802714,ef048c04,b4ac3085,59f975ca,be7d53d8,3ebdd5c3,ce6860d6,37710a04,f885a83c,c2152edd) +,S(da9d5c5b,4e73dc93,3c72acca,1e93f4bb,3ec477fc,f201096a,51ea0226,3a2f8738,7fb6a2da,65f966c3,689b93b0,d6366511,400c05d0,8b0a15b5,b4b3209,a812f8aa) +,S(140e55d2,a7e75678,1791730f,c526470,8d1cfaa0,954e215c,1e65bcc,e4b0dd66,4bfba0d8,63ea2597,91e470d8,1ef36318,87e2d5e5,c897918b,ce805941,953d5b3) +,S(15a9ccf6,4b95cc87,cee9bd01,bfe3d8bf,b438f7f8,66344a1c,f3f399eb,16b173d8,4f5472cd,bdebed25,605e51fb,f0b31a93,5d0ba59a,6e51bf90,e0363c8d,9bb33f3b) +,S(e86e364b,6776701d,b7b3d3d8,fad181bc,c7ed5e91,2d0a888f,814caa3d,88af6e06,22fd460,afc040d,3e995518,c6286989,24a466d1,4a624915,f834c357,4dea7b92) +,S(3c261a98,cd25f0db,2321134c,723ebce7,b1f81d3a,a6d5bddb,fc282fae,5a500eb6,2b8d2145,5e498211,8a4b6ed7,ec96a66c,4027a506,deaeecbc,45535fc5,77abd9c1) +,S(49b6a811,4d55b517,6cbb1f6c,177aacfc,368c3b5d,238300b,d66546ed,f4c955c8,d1b124a4,9f0e7c1,6b8e001,7f1b0b2a,ab94411,391d5bca,5b535838,a3815b94) +,S(6ec8e861,f0d3e5a5,3f9deab6,20cc4b81,6cee801f,f7a43f71,f34a8dac,c525f6b9,42e0545b,68ccafbd,3309c4f7,eb6b5eb1,1e01a871,c63fae27,782001ab,a6dcfd6a) +,S(7342b341,59aca5cf,d305a2e2,a8f14da4,4b527e57,4640fe1a,c08898aa,4595b9ac,b5261302,d2442ee2,363969a8,4ea61281,27f64f40,ac86dac1,21b5d234,53160124) +,S(842b30bd,54ef350b,65dcfc43,df26967c,b2747757,a609c54b,687d30b9,5a686fa9,4ffa9e92,2caa36b9,ecf31f63,f5c8de57,7d594f7c,71e7e77b,9cc5ac83,f336ead6) +,S(2dba435d,d589a7c7,bc3fb60d,495757ef,7c13bb0a,3e91a153,9998e04c,19f94862,c440720e,a4b23cb9,d238eca1,6775e500,931d3e5c,7df853ed,55cd4889,5e8cc0a1) +,S(9d1e8524,8f84ce5b,2a75a457,819390be,bb284fbd,3d035c07,998d3c45,c73bec02,8e40ee4c,c935ccac,2338bbc8,4a8063f3,6d62e8cf,849bff40,1298074c,94eb9ead) +,S(d2735ac5,d1fba75b,d4f63912,11549755,9a7f8623,62e25cf4,e76562d2,d8b441af,bd2ac36,19f9f339,77b7cb0e,5b52f3e5,b4ade86d,1c9fb31d,a1d8fb36,7dafc081) +,S(b0130e38,f46cff13,ad1a68d3,15729395,b27c2b96,e0a957cd,ca63adfe,b0a3e11a,3d9f697f,4a61401c,87eff844,3b11776a,610f1516,4366c1b5,535599a0,c6aa3c4) +,S(e0aa062f,15306af8,b662d8f3,3b89de8b,f59faa78,29942caa,ed82e668,35ec76a7,c5f5f0b5,6ea77304,a5dffb8a,cac98387,34305b54,25fc6181,79a4457e,c15e6f2e) +,S(ed1626c1,a8e6d1c9,187e15c4,ae9875ec,2156d685,997ac413,9f44bd0b,19432d5,3c0d895b,9dcb4a3f,4235e531,ee7373f7,7f0fad46,c5938d7e,69d50429,71f0c35d) +,S(a2cccc31,4e18fdaf,8cc25aa6,74c974f8,664744db,86e04be8,431d2ed0,4dc92833,b6410e49,d6d471ee,d20e5536,8672f5e4,2e1b9c88,c06438a8,46c3a74f,c759d71c) +,S(5bfc192f,db15f62c,4af19119,b2d96a88,b3b24e06,3d54b31f,a35f675b,f668bf27,46774374,acb4e140,90431bb3,9f62a38a,dbe0dc62,4021e23b,6099e198,47d99051) +,S(66842a89,da73c404,32a2e553,97efb009,61eb2155,886ac90e,97dab5f0,9227028,3a8e83c3,511ea048,88d2dc9d,f1016cd9,da171bc6,89c9af4e,90b18091,21941de9) +,S(ec823197,3ba95f98,d45f8991,3ee8b92b,e3a4a84d,d59342f7,1810766b,cdc516e8,532d3c79,f5113f4e,1973bc88,2a953b5d,77d5476d,ac9972ae,f1d25e19,ab7206fe) +,S(3b65fe78,bc516176,aed5e5b6,5f3ed39f,e8e8e26c,32ab07ad,1ac2519f,72fc140b,856d36de,5190eb9c,13f7f976,466f95de,566a1fd7,314cec1b,9c9f7adf,98208d98) +,S(3ac0eca,51c43525,e9e545ce,83fdd009,f9f31eb3,2722b945,18262036,d18cc346,dc72018b,c3b2a4cf,3244ef31,340e0944,325bebc8,b134de50,9ab3024a,a213a7e6) +,S(4929658d,6c50ece6,edd2db7c,217d9be0,bcdac8b9,bb50972f,fbe53a04,2ee23508,e5aca42c,61aabbd4,b8555980,a2328741,6dfc8df8,d7a10c3a,7284bd90,aacec38a) +,S(9d16e76f,4bc96492,f0e9e748,8c6d2297,7830e2ab,491a6278,1d60ab5b,153a6291,e6590f00,e4ac6922,5436318,9770aef5,5eaa988a,44e9711,da7266ec,895ac7ab) +,S(b0649c4a,1327e7fa,f52a9bbe,7ff97add,4e13b36a,27c0676d,5e09b2b8,1f5df94d,991c8316,a6f36848,e072a080,77f75a8a,d79fdd08,1a606d12,b355c3c,3891acdd) +,S(8f194a21,f6303ded,2c9ce51c,44a4a16b,eb39a8f6,5fe13c9,6b7c12bd,b052235d,bd1df3d0,c9af82e2,545afb23,e9a2dc85,c635172c,edfe70f1,bd755d26,9730739e) +,S(1da71a97,cc7a4cd9,4777f6c3,dd5e665b,3872b721,c6c2262a,60e87f1d,efe21ff0,78d17a41,39036e1a,7af2b9af,1273afeb,a4d30e8,66a3e6e8,7f0d0468,4be6a06) +,S(9fed363,e493f262,d3efabb1,c52291c7,e04e401b,b181290f,7a37af3c,df86aa45,130cc33e,e164adff,bedb1827,6a5c965f,53a54f36,90dfcd6c,b3fff836,703de729) +,S(d166eccd,221c3568,199ebc38,fcbb6140,7a601a3a,c1e7a98f,ebb75a87,a7a1e49f,262222b7,e7c200bd,5dcec562,85485434,b0628c7c,ce5483c9,93795f76,a072f06e) +,S(e7853cbd,3e3770c1,cc307839,294a2e8e,b998a56e,393435cc,2930920a,8ddbe0fd,7977e6ca,67147cc4,965d2918,1023c3bc,cff1e7b1,8fa4850b,80a140f6,980e5a8e) +,S(a8b0feb1,cb140201,2bea3cd5,6b1a1f02,51036ce7,423f511,480f49c5,6227a17f,ccd7c3db,9d3ab6db,6cceedd6,d3801c8f,67afe792,c8977b5,27c9dcfa,75ba8a9f) +,S(57ce5dd9,e1815755,31e90579,74f58b98,6d02e406,a846ab26,c9059f6c,56d617d7,cc34c090,4399f316,269598f8,aa8f9aed,829f61f2,5efc9bc4,e851ac63,fe142d14) +,S(479790b6,4f60fc6d,befbbc1d,365ab3e4,8077b6c6,cbf02f2d,6c8b986f,d0f9c858,157f4982,e3581925,dd25382a,e3e48fa6,5cff911a,95e9bf43,5df8b356,87f2f9b) +,S(55abc7b,1ffe0a41,2181b622,813be76c,8ee0a0ca,3cb37b1c,cb265087,fff17c68,bd134249,23e94c53,4cf9e603,a1dd259,606272bf,8283f2d6,69bedd4c,a971d99f) +,S(6ca7e032,8bf5d67a,b804d431,e5f709e,bd3156e0,1d4511da,1dc67394,24d2e659,c428b133,f3683909,6551c2ff,2f870d80,d80aaaf4,6d2b1a69,7722057,5eca2647) +,S(60df19a9,83e9086c,4cbd20ba,fbafa8b2,346ae4ee,9c1ad4dd,99959e91,2df530d3,dae7b854,29f817a0,421c2f1e,e4e8e4d,a09d60f8,84701e31,d7a8b7b0,3b79cc48) +#endif +#if WINDOW_G > 11 +,S(6f18d50e,5ef5f2ad,bad80ea1,c59a3847,5c22ff05,6ba52c7,e1d26d6d,d3686bce,d1d7ea0f,a166efd0,facf5c83,bc3786e0,d3f3405d,5b4578f5,13a336ad,f0d7d7a9) +,S(b634dc9d,5ed51336,4ac9569a,8ddee9d9,fcdfe00e,65e59233,b3be8a07,2fd949e0,d72e46e2,c61b2575,f25a505c,bdc3456e,fdf18976,6562a1a7,e86d036,eb31db69) +,S(5a37fcf0,2dba24f3,e6646171,43dbc5ab,40d91983,69f5cf0e,4fc566fd,97445910,a960d1d8,13f8746c,662a9582,614c7847,33e6153d,2975cb59,c3342463,75c69d1e) +,S(8aaf16a7,37318032,c60201b6,b196d8fd,eeeb8f8f,1aab29e1,1b83ae1b,f112661c,c461ef56,66a3a4a7,563cc0c2,845f2ae7,6d03a795,987c615d,611bab48,ab9a8e44) +,S(456f0ba5,a05f15ef,d93e7f49,e0729c45,1d85a693,42c2804d,9cd4b8ae,af5e3434,a680f4a9,99221a8b,7f46da13,13041e16,13f616bd,84b9135b,b0f7ecb2,7311cad5) +,S(f89c36a1,f1905409,75f146d9,31e12cb9,4bfdc90f,a178970a,9d0b34cb,38f5c741,3b562c80,58e31b92,a1186615,9c1ffa3b,4b1df38c,eb4a1646,579d2375,9c44099b) +,S(7f6beb11,2e1d8600,d8c4903,1d69cfb4,e23876e6,32f30428,9d2c2503,41f3f76a,a1937407,c0925afc,be994b9b,51627b98,8d98ed6,e8cf6fb9,cddd0ec,a4ff4a9b) +,S(905ad0aa,b585c7c3,78b7130b,ad1d5001,1010f543,194f40d3,827dc606,12d73511,bfce0701,c3ddcd38,150130ae,e91d16d4,a447821f,a2e098aa,b83b8025,b7177a9) +,S(f559c2d1,62122fca,7201e7a3,b6033d1,e54187f4,7550b2ae,f1d51521,f7408b6c,3f10d622,dfd0eb14,7f6f04dc,43108273,7695ea42,38ced7f2,5dc167ad,34154481) +,S(19b328a4,fa17149c,ccae5830,a8bedf53,7c0d8a0c,c3616345,6f4d91d0,718ce8b4,9a1ce80a,2a4e6923,69925883,8e786779,fdff7f09,25d68855,12644d04,9e582f64) +,S(afab98a0,e75619bc,ebcabc24,c1a6a0bf,2743d4f4,921fe53,3a393648,adad5d4a,bf1b3a87,759139a5,79741c09,21f29a10,7c8e5be3,13d75715,7dfd39be,923a32db) +,S(c2cabf7c,1d86a34d,addb36d9,c83a8ec9,b2dfe0ee,8176d085,cca91fd8,ee4181c7,5b32b724,53f1335c,724465bd,6eceb8f5,159ab150,e9c972ac,f51d27aa,4d91070f) +,S(92839424,8e847452,29a8c534,7c14355e,4f6e9cfa,2c1a2be4,f5ad6cfc,2a89f593,bb9c585d,fd41ee06,99ca7b4a,146faf68,51983b15,d652e996,c888a171,7c8c3a07) +,S(bca2853c,389ef184,208cba64,617bd7ad,55e55f12,d0c9fb4a,a8dc30d0,c73c7dfa,9f41289e,f32aeded,3d45952b,16a62fba,fe9a142e,1e65340,17588d79,e1df63a2) +,S(a4ea7bda,94b565a8,ebf53aea,5ce672c5,5745b7bd,37ca77e4,a0e4f281,71bf56fd,c9507485,1405ea90,9b9e1a28,42c5953e,629eef31,37bb0fb0,970cce6a,893e96bc) +,S(71707d45,af71139e,d7327ced,89a2403,da57c18a,8527bb1f,f754e78c,60d5e169,24b36484,fe4da6f3,a3f4e4a8,55a477dd,3eef0f39,fd3c585f,1b9de9d7,10223ef9) +,S(52c1de03,296f591,9d5cf4d2,36b8ff51,5b1f5ff6,d73228c0,7dda706e,4fdf9a05,db958d59,d73d574,384066e4,fda3b785,c9509714,90607c51,35d1d34d,5a344d0e) +,S(7b09c0b0,7852e845,30691989,cbccbb87,74dc2007,df827120,d8b1ea62,2368912f,4edf5717,ffc52817,d0eebeeb,782ba4d,9545a5c,da979f3b,e9c09e84,f82bd263) +,S(e99870ce,b29ad1a8,2bc08834,3e3b3c03,f26e7062,66b32540,681c689d,ffb8300a,8080ad92,78947d65,bcc12dbc,614d17a8,8ff75e3d,91230fad,c6f785a8,cd597f9f) +,S(c7e2326d,e28b8139,85db4cb9,c3d4c5ee,2dd2c2bd,2b912444,adc3a434,205c38e7,5f2863f9,cdc0cc95,1fb87000,e177cf05,d31adf8c,543d899d,195bf5e1,c6ad940e) +,S(883596c8,4ca7bd78,3c586bfd,28fba489,4c6bb66b,5ea52244,1199b55d,3e3f7965,fb114be8,59255f10,c96d6d4a,72945ac9,47a22f5b,68ecfac6,9406bce2,58e9282e) +,S(7f73a648,a19640f5,b0f029dd,37e56e7f,5cf61659,5e532dcf,7ffeb7e3,f20b42cc,4f76248a,f931aedf,b4e2df3e,ba3b426d,8ef191b,9d59507f,4a94ffa8,80ff4feb) +,S(c89ee34a,3660d03a,ce3b5604,1196a66,18c8739a,8a4795bd,db9c382a,9741aa3d,a4a3b888,35fbac57,f2f79ac9,d0ef292f,6838764,b99de084,684d1b95,12923884) +,S(24be4c56,d7dc0c4e,50050cf4,31d81f19,b5c46889,430563fd,566c4ed3,d941d5bc,e07236e2,4936315d,5f0714a2,af1ad769,f6a5fc7,a56fc1cb,ac09a085,f29e6213) +,S(6c31e71e,caa91c00,798ee5c5,3237a9f2,2866a91d,26936852,c4eb9853,e40b94f5,65aff323,2b5f2cd1,c1117e0a,c30b94e9,34543cd9,480f7922,5723c385,9ccf8cd7) +,S(506c373c,8479693d,3e03c022,9b61839f,e470a574,d31fa286,92601ed7,8e58b7e7,4fd0bfd3,a57c5035,268bd4ae,707fee83,e24f8676,e0ffe3ca,1673faca,1b7ab65) +,S(59d9a5f3,ea1a6cc6,16e7b097,871f731c,57571a09,1dc01b45,b48c5332,c98349a4,94ad373e,ee6496c3,263c348f,a7ee539,53aadf13,1aa6b638,21c16e0d,55fc8447) +,S(a524cfab,65371648,f641912f,a6ce67d5,c6f8929d,366448d6,4de381b3,22d75c69,14c26ff9,87fbd599,17a6ae90,bbe7c79a,ac1b6158,c3f46144,71aa36a9,45782823) +,S(126c986d,f83c6307,87c0d3ac,6a6b2393,8aa3fdd4,df26e76a,92af2c65,7f48c550,808539d3,a56a6f8f,3bcf04dd,31ac72e0,3f74ab1d,5e9afd39,7741656b,3d4c5c5c) +,S(32cabbc0,1aebcfb2,7e1a9d5b,4cd05550,d8ff25d7,b9a81db7,3188474a,ce39722,7d30120a,e08031c4,12c070f,6ee6b52a,be191021,faa9f5bb,9576feb1,8fbccee9) +,S(3fde1cba,f7ded6f8,a98975ab,ad5a64aa,8a9f0864,16dc25da,359e1cf8,22f42c64,e50fcac,61f0f174,b0e93cae,691212cc,44ffeda1,60dcff91,9ee3c960,2f5ac075) +,S(9cad22ca,d6c3dfbc,1d3a08d,6b102727,36e9db37,1ee1f26b,3ce932c7,11462e24,5ae84f1d,873dcd04,7f0781cb,aabbb53,422bb119,4e59d5a6,8824db95,50461c6b) +,S(9859020,aa807626,3a8ca18e,91c1afad,c20cf9f,9249c24e,1c652d19,7d5872ef,454323fd,21ab7d6e,470976f7,2d85fa39,a084e7eb,b332edd6,a3d054b8,d3c73e69) +,S(821699a3,e7cbcbd5,a2b093b6,c825281c,ac00bc53,c44b33a9,d8c31b9e,464eb2b6,f7d59c17,2400cb9b,72b44cbc,bbbd3e9f,e62cf451,bce6f840,23b073ab,66a9726a) +,S(bd06d4be,36423862,795fc7a5,5c48ceb8,440b3cc3,fc286dad,74ea7f6d,8cd370d9,3b09193a,fdcec88,ca4a5663,2cbb808f,61bb1253,fbcd1714,accd508,6183b90e) +,S(2c7112e7,9c8cc78d,f04a4ed0,e043c6ca,bb4b734d,9177f822,5bc41123,4bbdf4d2,c81ccfad,d42e2248,7612884a,d900f61e,bae242ef,65ff1afd,6e03ec42,38391243) +,S(51ae390f,a65d772c,833cbb8c,9ddf9ceb,b7f5236e,f1983905,762b7aaf,e122131e,3d7c9f80,80406b06,282f2a88,87dbb714,f1e96e1,e84eaec8,1256e1a8,ed7ba06e) +,S(c59de112,de237a43,2bcb8348,e3b31356,c7432672,6b9167a1,77d826e4,dacc59ea,36109f16,7c5eb66d,9f09c1d9,c5e1676c,aa33e403,a8e052b0,2854c689,d5903b25) +,S(8b99f23a,b7509d9b,151cb89a,45753026,77ca1e6,9219f0f7,57d01823,f556d978,86a31aad,f53afe44,f533cf0e,4bcd573c,d338e12f,904c8e9a,dc8e0080,f56a4164) +,S(4c670f65,7d6fa9bd,9ee4135a,1ef1882e,61f5fb7c,9deea717,39fe0ab9,78369dd5,531a8226,5d4b5363,12875dc1,7f891d1,b54e0435,1b539dd3,c100b797,efe65417) +,S(8e967e35,9daa0f95,fd7024e6,e57f0640,36aed9dc,9df0f33d,9388cedd,e0f38548,36f8055b,a59afaa5,8c88b833,ba110381,45fa0ab1,f0160d2f,1f1a1765,190d218f) +,S(3f611915,9c45a37d,5c7bfaa,cf0cc959,5e2e097c,8c7bc3e,c82e9e33,3b2ac9e1,c80134a,b7437dc5,23e08757,8eeada53,b9d2f3ee,25b754fa,f6c32e02,d597d7d6) +,S(3f59e49d,7c61412b,53fb203a,c7ebdedf,66bba683,87070745,9f85000c,f47641d9,bedd7088,4243dfe3,d238f101,f5dcd4e,64cd0978,986d50f2,ae3e2563,a43ad5b0) +,S(5b7d84c9,b64836a4,3bc44b5b,fcf170e9,ad46d4da,197a2781,bbbcaf87,5bf6d490,9f55b29c,c7d6b0ff,facb8975,507df04b,f2164e5b,9928156a,7c73fec2,b34d984f) +,S(e1ee74ae,ac3e83c,f73bf1f9,aafc3eab,90decf0d,a071aa88,962c29ea,51744b1c,9e86d2f8,b34e8525,568d674,8839839d,eefbe15b,80c66216,50acc508,f1277030) +,S(fa1ccd5b,8d489448,e3196c22,e96ca7ed,eba721ac,beee200e,5ddc496b,6beea871,e2b7f59a,326a6654,9d6479a8,a7a56d7e,8513504b,fd2a9829,d25e5855,2f9bc469) +,S(ef1e1cd7,f386096,1f6199d1,ab4a63ac,b292316b,f7a5e7a0,4c9f0c3a,7bfdc8bf,4cef9c01,a9de111d,8395dadc,e411e532,5783d377,559dc687,eeb510c2,ba98ef05) +,S(db714eb9,3e75d3ba,dfa5cc4e,d4813db2,fe9c395,95a1ee8e,9b3e468a,e1326120,3dc49a86,b81278f4,84d30311,c8816840,fa3cb701,665c067f,618295aa,6a71a206) +,S(5997f38d,bd572858,43ccf936,ee9d3feb,d70c79c7,9ad1c452,29af32fe,e6ea5d5a,adf7d862,b716011b,b9749e08,965c1ddf,1f44b678,df548eec,45a69a56,97e4a224) +,S(97d6f6d9,a920577,7b08ae66,6fc1fc7a,956654bd,3bc6c039,ea4eec3d,3bbaeb92,b450dc47,ff219854,dad5ab97,13dfbbf7,ce03fedf,4e7ffc68,4bdf1b5c,c20068b9) +,S(4f453fcd,5ec8b72b,69549ae3,c4eef99c,40232bca,1d6b10ab,c4b00d00,5ad307c4,aaded568,c4a8bc87,c7a442ba,f960d9e8,bd61f15e,d668f816,b94c0d2,9683f7f) +,S(5a604a3,50593035,c71c0a6a,caa7946c,ae4c4490,c0db71e6,49972705,949424d6,e578fc12,6d8701a7,a02b92b9,3fa89d09,ae82779e,2f78586a,8937a6f4,133be9c8) +,S(3f3071a2,916832fa,1b64cf0d,5b5fe8ee,2de601c9,34e08498,5d118696,7c635b3,e915b199,baeb233,b22adb6f,69df0e43,8712f25c,1be4470d,53851e4,451ad3a3) +,S(745bc1cd,643189ac,fcf02c5f,bf99c222,f7476a6c,2ede6c45,31849491,901c06e5,59a2bb4a,8703775d,e9a519bd,10e59db4,be16cb41,d0275d21,87291d06,d29933f0) +,S(bbd06e8c,adb3959d,853591a6,6387989,ab396736,8a6c1942,17580911,2637238e,ae0d8296,b484e5f3,dc46cb88,90b86a4,d562b003,a65a0c2a,2b4eded,38b8b690) +,S(fcda8db6,128dbe66,850b7e43,63a3b35e,9f3eb569,b7af97a3,85e53fd4,922cf07c,4bf3ddfc,37a0f9a8,5f758ee1,4c4d5c86,cd11f1e8,2a05ff28,3a0f535f,f9551974) +,S(6325dfdf,fc9c7ded,2a65e113,27210ccb,4ed2da97,4eded570,5ca1add9,9873cce2,89fe4c99,683e6fc7,170ada7e,26179fea,7ce1930f,af1a7358,4d7d56d3,4cf222e1) +,S(77594ca6,93495096,3ab5797a,5279d0a7,513df59b,41a3ad59,245e3f29,22ee0d7f,195eb112,2ccfbfc8,fdeddf45,ef2ef58f,631df03b,ca66a4a9,5818dd83,e5faabb2) +,S(f356ec67,ea9b242f,4f1348fd,c6592772,e2defd7e,308427b,ede15452,baa67867,3d2265b9,e23f8ea4,9a2b7145,9c98b03f,d75a2110,8f104121,e4a2fb4c,d633ba7a) +,S(3360ae12,9b0fa48e,c78e3091,4f8ae6f9,86149f0b,590a12ff,cadfdd2e,f8a205c9,79b37bf2,720d5a11,3ec09872,22b0a626,3d7a2051,e337cb83,dcb52df7,25d18a34) +,S(44e90f52,c703c50d,b331a4c5,fc47613f,b29040ab,9ff0f282,3fc15ad3,f9e8727b,62dfb341,92653e6f,636d013a,718932f6,95c2491e,26d16feb,4009ec05,e2f55f17) +,S(e5d367a9,b5c3ae22,31195876,4b28fe35,c9e04289,518aa09e,e7902b5e,4ec84047,ea1b257f,1abf0fa,6fb37c06,907052e7,fbbc06b4,c2382ace,9c9a98bc,e6f8bcf0) +,S(8478e8fd,7910e5ad,3c061e6d,422806a5,559baab,e083b8de,1005413b,59a63957,4f793418,5193499,13fe38c4,514bd4bf,2f3f1ebd,b492fd5c,fd8c1bc3,1a2df1d6) +,S(c38327c8,587731b,f5b5e224,79c9274,10c97dff,f6855b6d,c2ccf761,2a84b42d,eb03afac,cb1b102e,7e87d61f,5012ce74,a213fefa,b855db22,bc657d52,4dabfcd6) +,S(b9e8a812,5348a672,558f48c9,d17f28a2,4662b4b6,604ee14c,d622b521,bc51f10a,35c2780d,65fcd07b,51ea0224,1771b523,3813e7bb,97a1744c,e3dad732,ef1ccfee) +,S(a54aa2d5,95cfa325,38d2e483,70ba86af,d3c3b53d,2141b0fd,cc68a729,a5cc713e,bf74dc6e,63c02b2e,e676b9c8,6a851a48,7e9552b9,a32eabaf,4e1faa06,8bb8a159) +,S(d45fec3c,e2df54eb,844ad145,fb8884ac,420ce2ad,85cd55ea,4cc19e1f,da9fd956,ed8cfb00,65aecb6a,6901dbf9,b8c208d4,bf6be1e7,ee74a08d,205c48bf,8cb81bd6) +,S(f4b44e98,f728b318,ca959829,d4cd836c,5c0136ab,8e433101,87be24ad,53192172,ef5521b3,960bce49,2c841fd8,8cf7b8dd,2febdd8b,f0aa64e8,4d3c2a09,89ea9fa1) +,S(dec6d1bf,d349110,faa0cd40,e8533078,dcec40c6,e260b9e2,8412d424,353d67e3,73a16f81,3609c901,71efe44f,32ffc90f,9451b0b3,24107b72,54ca2fba,65095895) +,S(1fbcdd53,72e17c41,9310b9c0,2273534d,265f1c24,bc1a6039,238b5b7a,b3ff013e,9cf4ff4a,6a61c11,20c4d14b,97275547,b2358f75,8a2a774f,22bc77f2,4c6c27ca) +,S(d9cef0cb,38c6ed7,7aed53f4,93a31daa,50ea1ff9,aa43b890,357012fb,e2ab593b,32a416fe,246872d5,b68e6654,7f19dda5,e161cd13,ed041486,4d0c2dd,3653303f) +,S(1641b549,88e22a18,45e2135f,88d2386,4e2f607c,ce33fcce,de174a60,1ff03da3,edd3f0d9,ed718767,3664e1b9,540f816d,48e3ffd1,cfad86fb,5b68dfbd,7d94922f) +,S(99ef6c16,3c5d9ffb,1b638b21,1ef60166,37938f83,ac4ef76f,96c5366c,3a243cdd,6b6eef62,d819581d,e1dd7796,df043e02,7f912bbe,6ba1e499,a311769e,d6f66b48) +,S(49358d2d,c24c2e8b,80ff79b0,9c53645e,b9c47fb2,8ea4ffe4,e2f4679f,5b5bc97c,512a14a7,f9df40eb,ef7c1cbf,f8e1caf7,b8c80748,7bee3865,37837cae,dc1cf5b4) +,S(e31d3fcf,b1dedfe9,2549c5e1,a14cf383,c8c122a5,a430aee8,a4eec846,7ceb206b,7bc3c266,69db747b,a3ad1dd,e83464f9,effc4dad,b4de7687,e6c3ae56,a5b0449b) +,S(a82ec9d6,ac86bcad,fbb32e66,a28d7483,ad1fbb7f,979a15d4,4e324ce1,86c64adf,bac87d2b,c28b1ae5,f4ab46f1,ac779936,3a9efad0,b1e1f81,6c4ec6d3,cf74c89) +,S(21650994,2bffa2e2,479ab82b,18cd3aba,dc370c3,18c71c08,1bfb53d4,c8ea113d,97a8246a,2f653450,be513b6f,62419f90,f84511be,9a5f3103,feca77c9,c81fcae3) +,S(735050d8,208d9688,7fdf8070,e448e905,e4e666c6,3db5857f,63ceb362,c6dd4b84,2e3fb438,563661c9,e6fe23f0,7c8219ac,216887cb,ad307918,90001f9e,2ab9e2e9) +,S(1d021861,e679dc08,a34c3813,bb9c3e9b,65f87800,79dc08ba,197b3b66,47afe506,14b6d0b9,2303483d,9e92cd0,e295bf08,4a10e84c,ee0b7c50,ceaa6ba7,a6fd2f1f) +,S(7a7eee74,86ca8973,a858c15d,54eff96f,f91c5577,4985433c,1bdc4f4e,46d7810b,5e83a07f,5d9150e7,a7f5057d,87d19ccf,448fed1b,bc1e2297,c7012cbb,77b498cf) +,S(811c3d4,fe0a3061,47c05cce,32a32ada,48593802,32f24b51,f50e726d,a702beec,a6fcc16c,6c9cf4f9,2e84214e,35ad8577,b28e599d,31ed74ef,c95eb2bc,833d9f0a) +,S(2ca14438,89ea9e8f,24d5b1e,e44b26d3,ca25ed08,30ae950b,4357da49,21ad606c,7b48a6c6,92d8a29f,a82c656,f8e6213,c5e90be3,7413d86f,42e10e63,1026c551) +,S(a980ffe1,61041afc,339566d2,957e6624,5dd3e0a5,deee9c80,d57b1f1f,390277bf,3276f7a2,a139343b,87744079,7a174d99,457d5005,71ce47fd,10e41456,7a1c64c) +,S(e570a3d9,cbccb74f,c582954a,998d9371,fde41d98,e65de6bc,9579d6ea,d9cd80bd,5a749177,6658398e,99d3035,12c168bd,9400bc6b,c7dea2df,2739abe4,16973a52) +,S(f5fbaab8,952cf50e,66d3d985,d9280bad,71bd25fb,662358c9,72b954c3,7bce1110,1aca2123,6179f821,a4f097c9,b48a744f,8010818d,3ac6cf,b02f57f3,1fd77175) +,S(2e5942fb,ecbda8ac,15408d25,84ab7c75,6f9e525e,c4dbf375,5559dea1,718d89be,95106507,d14199a7,8f123d6c,f6b59262,30e12a1a,8c0ca016,40c556fb,14bc790b) +,S(92bd04a9,891c99e9,6c9e7f64,a9bab705,a9fc83f,a739413e,a2f33001,b55dd296,cf5e3733,659bfd9c,e5417ba6,817b6a0f,5cc71c34,22165fbf,13019fad,822ba587) +,S(30ddfd9f,a50feae1,e3cc5426,93ddcd62,4d0e52b0,867248ff,ed7d3041,a7b11083,ff15d0fe,2bb183ef,a18389e3,df4269ca,21bdfa0f,87ac641b,14bdaf66,26eb42ed) +,S(8cf5150b,df8ac68a,af319688,245719e4,67ddddb,72fa7f1c,baf39de7,252a9f4f,4c28497b,a299bb19,83b18bc2,508c98d8,2a9963ab,4145807a,2130fc05,4186cfd5) +,S(1f4b4efd,50974efb,3caed9f7,4f6dd979,4a8e3c09,8decc1b8,69032885,265e46c7,6c4b04c7,f7c6b00d,c38adeb8,a47c7c0a,68535229,26500a76,ee1c6feb,179fd399) +,S(9d524900,979afa33,8d5883ba,d13d038c,3f915cb9,f2e29a2,2a028b18,d091af81,409a113c,37c732d,1104453d,6b161d33,db3257c7,b9a73e1,e0f1679e,6802be38) +,S(52e1e4e4,46eed9d0,fd5c124c,1c23403c,5b03984c,f3fb0734,c627f34b,dda2e3a1,674a5731,7375ffa8,c3c4104f,12c1713a,e2dbc630,75a77e5b,26243217,88320a7) +,S(827b171a,8eef4e31,e6ca8b6e,7c6e36fa,e0a6c93,a77d7148,fd22f7a8,16401c8b,65cd85fd,d9b801cf,7de6d14c,b78ba114,1d58c7fa,129f9f08,8275f364,f7ca7540) +,S(124f45e9,61d89642,6a1abc32,e582e246,3db29954,1bea0383,c83f917b,6cdf2f9b,734e2fe4,110b65b1,2d60626f,c6288f87,e48e7a7d,213a4f83,58bb4d67,978d6c62) +,S(3b71298,18b2b324,10e4f002,899204c4,fb4ac9d6,c08d1169,5f5f5699,9a4d67e2,28b6f78b,cee16b5,5c010c51,ec465609,54ba6368,a18ae218,5607c1fb,42c27c3b) +,S(d271d87e,63b5363,e664485,ea6ae70e,e2b887a1,c7f7e0a4,290033b5,512d8a00,65d43804,7865e280,273122ba,8d8644d0,60ef5927,34971c9b,510238eb,9d6da847) +,S(1d1c6d85,2db35160,67cd2d82,e2ba552c,c5ca0c9,ae7bd661,e8494b25,cdc03a7,bc31f4c5,673a0256,ee9b6840,7aeea035,e19f874c,bdd7aebb,ae8b1005,4e691f62) +,S(8fee89b4,71e394c0,ddad274c,ba07de4,bf8d2ecc,695647fb,1d3756fd,46efdd9d,5d5ed0c3,8479578f,d17ae148,7198f9cf,4ba5cf71,46a9b4c4,34ca62f1,bd2b8c6c) +,S(681fcf09,55a0f351,6026302c,ce3ee475,8ef9385f,908dace5,5d7fbd30,8810a6ec,4307f75b,99927624,80187edb,c4c6575c,aa54e8f4,190f0885,e6d358ca,2a38faa) +,S(717fd6dd,fcb5a71b,6a584a28,904cd3e2,6f6c1a89,7fc32918,90792937,b3a6971b,b403f829,71d4ad04,dfc40553,27f6da8e,1b05e25d,341d6511,d7cd859f,58b17992) +,S(f2b95723,94eb9786,dc1f4998,6ad8c340,d2983279,c7323a34,227013e3,754f2ff6,b553d381,3efdcd41,7189645d,d9917b73,bb69e705,e7a6520d,dbaa497e,7766763b) +,S(58714be6,d7d86c89,65309b52,414135c1,9ab6fed0,1d56d7b1,4237485d,96730b1b,c011f34,3e38ce5b,deab84ab,f0e31537,4039845c,5fa4fcf8,1c9a4d5e,6fe3e533) +,S(d33ce5ab,c828f8c1,b9700d49,e9c6b4fa,b30819fb,b2bea23b,7f915bc0,7a6ff3c3,739b6222,39134988,22372ba6,3fbe22f1,ef59394f,37db956f,caca4c11,75a23395) +,S(82202e32,fc7d0128,4eba58ff,42f7d94a,24904808,d6f920d5,9837b26d,63b55479,fde63954,50aa55e4,fcc4fb0a,8ac2c880,63aa3202,9a00004d,edd033b6,2563b4c8) +,S(25e63218,5bfb4c88,fa300e37,c8b64a,941e6487,a34262b7,419fa7c,2dea7781,ae696b07,4802ab99,4df2d84c,c6731d7e,9caa124,548c2a11,42ddcdbe,f716e640) +,S(e0336a05,b9254e1a,f2468a36,343a0dff,9da8773a,1efdc487,53c1a95b,605c114e,41d75960,377ada38,79b97455,346266c5,5ba05915,9ddad050,d96d9d8b,afb12a18) +,S(843363af,7fd2b1bd,1c9a9253,e42489c1,34ee875a,db57b752,62d731aa,9a996662,e5c0a2d1,dbfcf013,ed4bda36,f153a328,12c4b3b1,66e48473,4d2d3562,ffcde6ca) +,S(adb210b8,1cdb7f18,f97955cf,fa7e5763,abb9f202,9d283c05,26df6332,951178de,2c211f05,d8182aa6,d784721,948afa11,364db5ec,2e1becf0,68eb91a5,74ea0e35) +,S(ab0c5fa1,a2fe2235,ee93854f,59a13792,2034604e,5857b6e0,88b65142,f24d7491,e54725cb,e36d6e15,71ca7384,7383553,b9dc48cd,eca6932b,8d92f785,b80124d2) +,S(3e5de77a,1d2163e4,3f3124b0,af4f5473,868a080b,67acd835,f9cbc88d,7885deda,a6ed34a4,2f9503b8,b83e66b8,377f514a,e1927dc4,c37ef6d2,254e651d,15746630) +,S(60c68b3d,31d1d326,5b71f068,8f32f671,32184815,f83a9ceb,50eaef6,4991ec05,977acc61,9f7d24c8,a95aecbe,987737a5,89886729,500ed32a,9d760fca,7c00d498) +,S(21b052e9,b646e595,b6c04a76,a66b9b25,4a126729,6bea0654,64fc5b31,69c135e2,1029e4cd,2fb3d717,6e87292c,4b0dfd7f,18db6ed4,59aa9285,38f0989c,540779e7) +,S(700caf3,7c664515,ee501e66,60be4cca,f58bb2ef,5b11f79d,c027dba3,7b523d68,7df76b88,f1c346f3,2e32487c,19957830,8eac9b7e,56edc948,e1a934c7,6fa08be1) +,S(c5ab9bd2,1293844a,ce5f1c9f,56458315,5d34aeaf,565a5696,29969664,49541e8d,2d2081c6,c61d6c8a,a0df4467,8ec53a7e,9b34d90c,57db2f29,c0361304,1c422d8) +,S(8afc3f2e,d53f5dc1,448d15af,8c2151d8,5713fbdd,5d46a3df,a4ad376a,16d75a3,11f6393,2627bed9,e015a99d,42193e6b,6767c513,f3457897,64db1a4e,4b9b6c8f) +,S(414ad9c6,bb55eadf,cf4cf729,27ae3682,c0d69867,ede9f4d8,6e173c50,3a5007a7,c4bcd0f8,f4de9b1d,1102306b,667a546d,dafb6f82,edbdffd6,181dd3a0,8f603585) +,S(8211e240,b84b7317,a9c5ec88,fdc426d1,a163a2d3,aaf088fd,b2317247,cb04a1e3,ca76a59b,b268bf51,4f06c4f6,d5961b33,a74f10b1,70a9e9be,4e7942ad,26722bbb) +,S(a54dfd32,363add3c,75ec4452,3094b27a,3f7cd291,43ee52f4,29e59daf,22ba700e,f160822c,59510098,3e38d130,49b44865,3639ac74,6a93ebbb,2798d92e,bad4490b) +,S(77d64c55,52b29b18,a7aee1a8,1e1e9d3f,e2921a43,cfbd95e9,a3ba7cb9,498860f7,e97bb8f9,5ea9c8f4,440ad9d7,36d9a06a,fed03a9,cc96597,8d06f2e7,8208ff10) +,S(485b3814,b33e6bf1,1f47f0f5,f0e5a189,1b57c103,60f13d61,ba7947e1,6e309ca9,e6bb7870,ce607c62,a6050dd0,946c8653,f998576f,2c781b5f,15282632,4e38bdb) +,S(ed2381ec,a90a78c2,def618be,1b6edc51,7ced2ac8,14aee9aa,b0a7068f,72739c,cb0873e0,ba326452,380c291e,c635381e,d6859916,2ca10fbc,3de45ffb,134954c7) +,S(e444af79,d36bc127,c83c7369,a4cba0fe,955b6a66,8f2e7a68,4a65e57c,44ed971d,a7876f03,27b6823a,aaf55ca1,6a48998a,ec50e5de,10d34e9,dd7c554f,d3785fff) +,S(af8c34d7,7de75a2d,5f64296c,152fea4f,b8677b8a,96cb278c,7ed7e50,69fc1fca,48ce5862,ab6ec1a8,ce55899f,24632be2,f3c451cb,8b81ca8c,f9ecc3b2,2984d673) +,S(e999d466,243a44ed,18e745a8,1da04a31,8940c88,760480cb,e315436c,f67efe13,f41e8e70,63a84661,c22ac0e7,5cdedbd0,ef55d3eb,7fa813cb,2f7d1fb0,237fe36) +,S(c40ef8aa,7d8964ff,a3cc923a,2fdebec,72cafaa,58b72d66,e209b644,604bcc72,480e35b5,6549a1e6,f112c3b6,176f3378,ff50ebc7,b3efac2f,696f0627,b7238ce5) +,S(482ee41d,e3f9499c,8992b546,e209aa5d,679e4b8a,22a26615,1bd1b0f3,9a52982f,510e6070,d2131815,2d52eff0,ee10ec6f,563f92ec,a0e549f8,32efee81,dcd3de3d) +,S(4660a468,25a3c1d6,67003c69,4d36f8b7,6df7ca32,c6029fd4,65dcf726,5c58fae5,3d982bf5,46b5c296,988acc72,2dade97,791de8e0,150397c0,700bfa10,ba23f618) +,S(b85e624c,92ba6f0b,3fb1dc03,37589994,d8a3aee1,76314d87,3c8bef0,eb5d8f8d,88936b33,20a55ba4,24bff93e,fb36ef77,e2cdff26,866cd486,88c61868,ad75679b) +,S(a41920b5,361a26bf,bd187eba,b62fd5b3,b3be282f,94ef94c6,b1698754,902683e3,7790a196,29d93b4d,3d27201b,32053e02,c95a8f9f,260647d1,491c7a4a,e15ea98a) +,S(93882da9,79262a60,3252f01b,bf101d89,ed1abf8b,15507937,55979f4,fbb7f86e,938884d,f0a716ef,137450b,ad5f022e,23e570f1,3ed37e02,15a40910,189d7e44) +,S(a10509f8,3efeda60,acf56b64,3709b197,ebfa6a59,e66efb06,79c23225,c8952e00,759083d5,559bde4d,9a37df5,24cae4f8,5a06e7a4,7c0e15fe,830f0677,c24d1ddb) +,S(2b945a97,6ea74278,73d7e587,dfe75eaf,c55de704,8aa26d29,4b3b1ef9,2beb3651,423c07ed,27ccbf6b,9d1cbabc,e00b451b,cb488d10,e5daf752,6980ef65,6893c65) +,S(86f9d9bb,c1a0bfe4,e03da0,13f17017,f6951691,28d51073,b594457b,fcc37f0,f370c624,2e303796,9339cd4b,fbc19e8f,62388f02,649247ed,df3c6c67,464c32bb) +,S(f8995af9,555e044e,6238d895,8bdb4e13,3aa9cc0f,90a9206c,16d0f83,dd61ed91,b2d4d2e3,1bee12c8,3b8bdab8,34fa2e63,1febdb93,4af194bc,d0825921,4ea8a060) +,S(ab55a27f,69eb352d,455eee7f,bbc1c74,fdea2621,63d09dbe,2f554417,819394ce,8ac56493,60f585b5,72373bc1,74a930e2,4d54674a,89789353,4a166200,e31b801a) +,S(4fc106c9,c428df98,916a8906,95e98353,ce84723f,fadae522,e8a89916,a23b9fa6,90d732e8,3d54341e,4f4c88be,3392687d,fdebbc4a,7c19afd1,92531688,9eb92031) +,S(c9c85980,8831cccb,77d87b25,73a894e3,874080db,ba076b2,4626bc82,3149a91,9fad4ccd,8c0949f9,be9a6355,f0bdfa36,c5f99268,780566e6,a6f302e3,b2abf0b8) +,S(c0cb5b7e,2293abba,5ff78c46,aa1422fd,a278eb5c,ddd58cb7,aee77149,1c5209e7,8101f42e,36648586,5db6b572,d0df4ca3,cc72789e,ed8d27d5,1330d733,4e10c47b) +,S(dbfc03c5,16d93f83,472ab60c,391bdd69,af2f70ce,fbce15d,140f1590,d8ce0b63,f838e14d,7228ca2e,9a33ecfe,c376aa4e,4811fa24,debc7b46,4658c153,fed26564) +,S(de260685,eea13ff1,1571d891,35607b0,435140b9,62e3baf3,7cc3f3d3,484f59c8,6bc23ec9,a6025865,e6363335,bb66f1e6,c1f5f54c,aa5f8acc,d7f8fae5,99cfbbcc) +,S(58d78d60,b8cb8fdb,1b62f79,f6c17ebb,1ed8129f,c7819e5f,6f73c58b,faa2e71e,7cbbe4f2,fd6bc671,8c222f5e,16391133,b04d6d3d,bb263531,40aa4053,b44bccc1) +,S(e72b9b1a,eed54fe5,ab0869aa,90014e3b,fde1af12,f646d738,211ebefe,2c00a490,cd92d14d,8f595833,842af020,a2cc82a0,d9465969,77d25d34,8cff3273,90af4fc2) +,S(6a86bae,d55a5be1,8b7cef97,c9dff8a8,b725f614,2221485b,3b9f348d,570fd658,138a2691,4c3b3015,10312140,7709fa87,60a14f14,571a9d40,81c06d67,ef2c5724) +,S(1ca08cf6,7240f244,d6cb0059,564fc283,b17c39e1,b624716e,e100aee,bb0a1fc5,22e24fce,655d09ec,34a36317,c66adf07,deec2743,4e9c016a,b3447b3f,d9ef0a55) +,S(d95dc128,feba49c4,73e1ee30,bcddf76e,b7cf628a,fd495607,f558201,824a0b0f,d5340ab8,fea3e137,d1061274,c69b68e3,633e98ba,ae2fe116,1612c4d6,c7c7e8a1) +,S(2cccd22a,7f4fd501,6c3a14e4,769a88bb,ae7e288b,d9987afc,f3c073f8,ccd83857,ae82663c,aea89fdb,4710f849,ff8e4fb8,c2a7b614,4edb5f3b,f2564dd,73b389e) +,S(ec17b5f6,c8e4de23,937bc003,7dd7b411,ae4a9ac8,1f2801d1,c5eebeb0,95628a43,b3e0d51d,fd5815b0,631fa298,968fe70f,74319620,f0798734,8e66e6e9,6658df83) +,S(a63aaf7e,62907f4e,1a613cdd,ccf1cc98,cee8e12c,8bace3ca,95685889,6c96b6f4,2f953ebc,dc5f9973,e9d44ab1,23255a21,f8bc1a7d,e800cdee,ef754031,aee8216e) +,S(8eb4ff30,318d8d0d,6b45636c,b296d137,90e345af,19a14b2c,550e0169,87ad32f3,4b8e238b,ae7ffc7e,7d600151,c5ebb776,cc01d51,827f171,8f28af77,ca4a3e3) +,S(ab1420af,bb5b4397,f578a6e5,74a63aec,2432fa8c,b4712341,4374add9,8276b8d2,faf6328e,a197e927,65b9df90,a79558b,8f264acd,7f75b574,90ce657f,64b94396) +,S(daa1890e,6b2ba1aa,dcc16f1c,c1d5999d,5102aa6b,348ffb5e,9630bd1a,886f680a,19facb69,5a63eb94,cb6f6005,cf2bbd23,8744f05c,2c220510,94bf6dfa,352fa209) +,S(f199f52e,5398d1b4,899a1b0e,df8ebb73,cb08a642,bd22ff2e,b1cf647,7f2a28e3,3619abab,a5e2131d,4ccf8747,67ef9b75,2d5278ac,5549bd9e,5c1b5985,9ec2f454) +,S(182a9e93,a5f9ecf3,6bf20bc1,497a4a35,e75c86f5,9c9fc046,e2752223,f046ad6a,c6095e88,c39dee18,ca867693,d85617c7,e0924dca,34af07a5,c731e488,ffb8bcfd) +,S(8a4cb53,636fe66,b660a701,64277fb2,5ac21eae,906327c,3b509954,b214abbb,693e5851,4cc6a941,23ee707f,ad25d638,8efcb85c,25500bbf,63fd6926,a1d0ed1c) +,S(4901335a,3b40c33e,115e3105,82c55972,f495178c,813bd8d4,2b208916,5c8c1282,47007176,429d740d,dcac70eb,9e1f0e94,f26a9a0e,4dde0166,24d9d801,c84214e3) +,S(8180e5a7,7c34362b,461b49e1,4b9f2e05,df64f55d,cad82b8f,cdf41232,984e01dd,34cf5621,d4b9f100,aa34b0fd,5ac91d,cb3fb49c,130f3e65,de742ac,af05040b) +,S(8f71227e,fea9f4a8,9dcaeee3,58eaa5d5,a90e1d7c,b7d232a4,b1085fe1,3651ee9f,a4da15bc,bb2b79a0,a27c344f,3b914c7f,e272676a,bc045aae,e90daf4e,9655ad73) +,S(dbeb9b74,cdc9bacb,83592a2,a3cc19a6,d1ea8eaa,5a086a3c,cc68d423,cfb58264,be668792,83f07fb5,830732eb,79e16bbc,18e86df9,b659e2d4,5b1009a3,40576161) +,S(f328e93f,a7f52cac,3c7b09b6,280528dd,7d9ea4df,8317a958,ab0a617d,71591933,41ce8c59,811f9e90,61dc3f3a,7d85d394,2f780c17,d7ebca60,fc042311,f2405547) +,S(56d4f403,416b1bec,49c5f44c,2021c245,d4ca4181,5131cb7d,8fb0cf08,30fea051,cc5f6133,948f77be,934cb637,3d5dce8c,51ae1a92,e3d802a8,d35a3ad8,50bd39ce) +,S(8e22e04b,8bb476b7,ccebecf2,a327fd41,dd90c9fa,67cfc49,e9cf4ebc,39022b8,1f8fa60,3204696d,34d03c02,31d3ef58,934e7992,c2c81d6d,3e4193b3,8286b8b) +,S(341b22e4,b9a77c68,f93624dc,1cfefade,b396eb72,bf9fce1a,51867d7a,ef064f6,95839f87,7bc36957,59562bcf,dbcb2db,af11ed72,7d329e27,cfc8ff8b,92d9441a) +,S(3ea42e93,9f234112,879e8680,94fb8a8c,e6af9799,c000b050,45eb2026,3b324763,44324167,6f5aa6f0,4fe4d51f,fecfa8fd,60a5c0a3,38b16f59,1866bd51,2e01a623) +,S(afe7b44c,ef10514e,f94faa1b,b8cde91c,23d8a660,a71c3173,42f927bf,535d625b,7617a788,51218772,bcd51f18,54b063ee,6cfcdd77,7a388427,51cacfc8,7c8b4b65) +,S(a360ca02,abb40d4c,6e0ac725,f2c035d1,12f69ee3,ff0e1dda,37a3fbe6,a2034d2b,161e7178,3fec3ea0,305d0f72,3a60846f,9d8bbe79,255a3814,fab83269,916b646d) +,S(10484e5f,f7d9fe7d,9b65d989,9b2ecdf7,5984d18c,1199f61e,c914a85b,78011b88,12d1c0e2,1e137357,9ede1086,c2c1449f,e7f4e03d,78f7b184,4f744d6f,9576cdc9) +,S(76c2dce1,5dad9ddc,24276c40,eda7de6a,b11245e6,5b051ba6,7eec39c6,d256b138,d9a601ce,585b0839,92e3fca2,a43739a3,61a8967d,3eb0f605,ed4cef15,fc64ce82) +,S(671a31d4,c3e6ed98,b044fcb1,83dc60c7,d1d83988,3a547356,27b99b75,11d4d2e1,6fdd8d15,2005ef3f,7ef3762f,bf43a849,281f185e,a52c1b3b,8ad371b,e053088) +,S(91d0f565,a2da6903,12b72998,57f71c18,c2343a5b,a6f17243,1bee12b6,6e898a37,9d6a55b9,1956a288,d56906a1,1f7cddd,e6393ad6,7249147a,41eb209d,7f32f681) +,S(7e59f058,1953a2c3,cbd4d0cd,8f4df7b8,6b90d8de,7240b2d4,de9ee9ab,628512ba,33b0d1eb,74cc7d60,ef419b0a,f9f03714,35a012fe,328fbdbd,9d9b69bb,9a42a173) +,S(ef78b65e,b791bed,212652ad,ab1f32ff,f43a285b,e040380d,d3492afe,1f788a26,9f3e2538,96d5afc2,3ea7ab1b,24ffac00,f156cdef,93957910,abb1cd1b,6508d306) +,S(78b978d0,199833ee,417ce2f5,fc12cb01,cb0c0e4c,ee752e1f,50a8cdf9,b56b7cd3,9f9c7dd7,372606bb,e3170141,31591f5d,dd631f91,71460cd0,19709478,c1560dd9) +,S(5f785b31,f9945a20,e992f5e8,80abab72,906ffdfa,7ba7ccef,f1b3d26d,70bfe64a,a3cc480e,b3cb386a,ffa1988d,3227911d,57522413,e5d0846e,a6d0a17,2b881c1c) +,S(9fee7999,7cbb492f,cf3aadfa,44484d71,2c3887d,6375c887,fcee9fe5,7806b3d1,43114327,7e94c760,1fbef25a,60e7d448,c0f0b8f0,c6c64437,a129d4ac,fe24c22e) +,S(12f2dd5d,b75d8885,7b7befd7,cdbd7c76,c0f46213,f9a53102,acd8b0c,4ee3f30b,ce27598b,e85049e,9ad3ecfa,d3864070,f8510570,742dd021,6dcb4aa5,334097d8) +,S(c694aeb4,3ee2b51c,3f0e2bef,bc1b718e,fbb86f9f,1d2a84d5,3178325d,cf997bd7,41481f3e,b6a69311,2cac3e5c,c85a6f83,6fc5190e,ae71f226,bdc887a8,ed050977) +,S(fe266a46,14c5c05c,baf3493f,5af3befa,9bd16100,860bab1,49ad78ca,81047ae9,e2e18ebe,c44694d4,b7c614ad,a772a5c4,f58ca087,4957f20b,741b954,18471e6b) +,S(7975e1dc,926b07c,487abfa5,8c183f21,daff04e7,f67a7250,d2152699,356118dd,c984b97,44e2b300,ca54b779,da94dae5,f943468d,9b9729d8,21cfc709,351409e5) +,S(93573cdb,50183589,a0909e8e,6186d700,7022848e,b7fd6951,a137cf16,a18a2b06,7a957c66,3047f6ae,d9490039,d136cace,caae2d8a,fc9f50f0,26590e62,18bf47d5) +,S(c0bd2e1e,a60f6feb,8e0ac7dd,485fc4fe,6771d80e,e29b4829,fa37faf8,81d77660,685b74fd,9edde1c7,69076267,d9f247e8,2effc83f,e25af065,56aff25b,335bacd) +,S(56bac0e1,93192207,906e5f45,d55d5919,b676852b,daa43253,8c4c6984,9c24bf3e,e3bf51d3,9856b812,d2e480bb,c8b118e5,f5c0ae9,f8d09096,a5d207ec,2fc18ebf) +,S(53b41b13,fe7cddd2,ebfec7c4,a985fded,5225fa0a,b93dfc65,2314d1e5,9142c06c,90fcba57,44e4f565,5d2e038d,ccd2bdff,cb4ecf20,48f2ba98,8f62fe9b,c3b69c4b) +,S(bda05e31,ccc0edb9,47ebaa26,9182ca2c,b1136400,674ce5f5,d55fcf2a,c2e765bb,97275979,31236982,a7459356,7308ea97,2fff08da,ae8f707b,447dc6ba,7acf75e8) +,S(48dd1c6a,8a900820,1fe09f19,a8f65f82,91196e95,1c57189b,21aede15,4b0413d8,79a1f6fb,1a943dca,6517e287,80e72f85,c5a6150d,9c50d7af,78c8b63a,c09b98f5) +,S(75406269,e28c428c,8eeff4e2,ce9a2d48,2be8346f,3446451c,13c04380,292f1f2c,4743b097,211c807e,23cd13d7,692efc44,202c44cd,dde5a89f,9e7cdc5a,133e996a) +,S(1aa55d93,bf318133,8840ae4d,24314ffc,74420002,4ddab165,4018604a,2192ee5f,babac354,92d59e8a,656ac7e9,9b6cb2cd,7a6a8e88,1361118f,41e38f1,2cbc3bfc) +,S(75be4c50,db7bc629,e64fa850,3d89f722,34d214f4,9b176fba,b937120c,477dcf03,b5520bba,8c606db2,833d934,3c860c6b,ed2e5e2a,41a6c3fb,51154c82,94b6f819) +,S(f3604822,e4ed8b2d,d4b2486,b611b95b,6508e10a,1c725c7d,8d638254,3cef6c8c,f405ac79,7404bc6a,25a1a412,f2cbd698,75d99d2c,b23ac105,f9839446,222dc0f5) +,S(6c9216e6,6f9326be,fad5f727,ae0326b1,da54ee91,f041d2bf,2d87dff0,e77cefe8,64a021b9,bc1947c8,df546f92,2f5230df,1ec2f372,50651704,557377fb,39d16517) +,S(ae479bbd,ce97732d,df313861,76807678,988346e2,5b12bb09,e74d474d,6905668a,a3ce0355,c5996087,89936336,64d9bdd2,b33a6f97,ea3f28b3,f4b7c0ac,92612929) +,S(ce92c179,66f74db2,1c6abcf8,36cfd2f7,9ccc05a7,aaaf74ff,4807052d,754898be,f3e3d3f3,530f38c4,ca59cec9,c8e3456b,8adebf80,3f10927c,e44e79ca,601bb978) +,S(8a0bbeb6,815275c1,77553d87,5988c4dd,a96f5ae2,378a3b9f,477cf162,6e6ea68d,958b795e,46f45412,acaa9f77,85a4e34,a7c74eac,228476d6,4e917983,5fe77f4e) +,S(c2a44ee9,975400e2,912a033c,5ed1e7a,7f0e97a7,1c86e8d0,c2e5136,8dd9ccfe,956435ef,7d24a507,dbfb69b2,93b51369,70cd17b8,ebf6bc60,596a9545,3675668f) +,S(b615f625,534ddf61,47b78520,85443bcd,3d3bbe91,c815dc29,3cc891c7,199ea1e1,4cabf4f1,99e21468,62a90876,4f65c624,fe3afd1c,6b399e12,267dc1e7,6ec3ea25) +,S(afccaf8d,fdcf272a,cf56dde9,3980bee7,b64a0c54,f80830b5,5fd0b93b,e8a75a0e,8d8ec5d,6f6fc44f,89f6d9ba,735861af,e7d6a660,7d88e95,54f2c141,1042a63e) +,S(534176a8,c5311b26,1f39395d,f78300b,559d072a,cb3873ac,32833c8a,9b135f53,ab84f84b,5eeea7b4,87ef6639,8fa756fa,b16155d,683ef643,b03c7e6c,8ab2f436) +,S(5f7aa173,97ef95cd,f47651ac,6220f3f2,8705abbc,6531b93e,a65fcd14,1b91f34c,72f7d898,3cddb34f,2ed1b28f,17a77d8e,70cffcbb,e0462ab8,b7548561,9881da22) +,S(d4fb4a4c,c1e2fb72,b301db19,335afd7a,b6a95258,6903f449,aa287fc,ac8f3d3b,76b572e8,4a9db287,19d098cd,5dee787e,f213adf7,9ae90306,8881894,e14154f9) +,S(3dc67563,843b2f3a,f793116c,23db0dd0,dad0975c,5abbf569,4c6d454c,9f7a9ff4,ddf65b9e,4db83b7f,43d0ccf8,49a8088,4894b277,4fb39fbf,78076a60,356753ae) +,S(657912bd,1edd014d,1386c449,50cd1667,9c3e415d,b36e36b1,3bb5c82c,a2f897d6,4e2fdfdb,11bbe240,8fc7fb3a,acd06c69,78205e48,c9f5a143,4300927e,fed505cf) +,S(5a453b3,5f82585c,f64473e5,f3fe937,6f412b5f,c4ade7b8,f9081717,3fd69f99,fc169e11,3448b590,4e1dbf06,f4aba1a3,ec2fb4b5,7f2b4c4f,a29b6617,58097ebe) +,S(c3adf45a,c24b4bc8,69acfaf1,f96a3043,d01c68b2,f4ff689,93b37b3,a4052679,3d923207,cd374b49,d3a85bea,972b8d09,4f0d4b83,cedc97d7,edc2ac68,10ae19cc) +,S(1a32edc8,905ddc84,2756420b,e1f25daf,5bd84f0f,acb046b6,e9040fe9,5e1e1d56,7f467d9d,113a77f8,c1cb73ad,16a62f4f,f1612c80,f8cf859c,ca42164,68eb4c51) +,S(70957d98,62e5977a,c328b7da,2e51024a,f925c142,eb1a46b7,b4a3bf20,a74d6c98,269b56c6,2e42cc34,a0951348,881d2c53,7d7ee231,f2327ec1,441fd273,bef09381) +,S(7e69416,5a02b16c,107ae454,b6cdf25,bf6dd256,d976ab44,bd7edc84,837537a7,ffb874db,38360c11,e2d0d2ce,3e47363,a6aac21d,78a37b24,3e66826b,445185f5) +,S(4f81a159,7b42e9b5,24be7ac6,ff4405d8,3b9d8a75,e37b58b6,eed5525,6ddf9678,b2531207,18676065,ad8ffbe1,6d27df4c,3558eed7,992538b3,77cb8497,86e0a78c) +,S(fa250368,577065af,b60be8d,e9381334,9be6fdd6,1bdd02d9,3591a35d,294fd547,f0b991e3,96c77cbf,5d642f0d,cf5ee10b,3b0a1fa7,7b696f06,d4d61cd4,48e81625) +,S(f4df5ebd,67162bfc,3e3da517,23fec6d8,6b61d6c4,a5876c4d,440f025a,272ba3d4,b23ba279,8bc75fb2,d590e384,c9e375ce,6380dc5b,90970d44,674e32a1,8052212b) +,S(ab5b6b1d,b3725b65,fae28e5c,44460d6c,51b8971a,655541c,4a587076,a1ac5015,16d2c457,ecdc1718,3a9d7876,d785adf0,424f72b8,d08b6a9e,286ea5cb,26ee2ece) +,S(a8a4ec7e,13db5370,40680dcc,470d38a4,2e08d99,3c30f981,ac877ce0,28869e55,4a9ded9c,2cdfee53,897d0874,965878a4,754025d5,babb07bb,2d248151,cb7f60a4) +,S(337f54f6,33bd60db,583d08,165c1011,6f914dd9,e2abcfaa,5f1b1410,b8245f48,9453eb28,696afc4a,40b5452b,d3abae4c,679b58e5,408b0a94,ea456771,8176dbfc) +,S(eee337ab,dc2baaf1,544c767,41a5054c,f6db480d,529d20e4,33b642b5,fd901b53,65ad5b88,2cc00d4,a4ba1d8b,a6956f88,825616cd,5f6c9830,87264247,869c27be) +,S(59f52e18,57cb000a,ec1aaf0c,b43f1274,f56e477c,50f010b8,4513fcef,752f1548,d8ca8f6e,8db03b19,8047006b,a6ec1e29,4f225461,9978ce70,a1ae0f53,9e1698be) +,S(6c200a0c,25fadb2a,8a9618d9,d7d86287,8583ab10,f2b4915e,8f5a5f05,406f3e12,14d4984e,374cf35c,145af24d,a5c0d0f8,504649d,b1793a61,7d6ed949,ef8081f8) +,S(1654a2fd,51dfb6f8,71aad878,239b657a,f8144ff8,98a3c2a0,32cffbc3,8aac07fa,8b6965c3,82d98569,b6cdcc1d,4c71705c,e36d46c5,fa5df714,8d59043d,161a839c) +,S(c48033c9,ab473556,c9982f33,953f96d6,7b3ed1c0,7e98efae,8de232f7,67556d77,af3f48a8,7bc43168,10787382,8dcffaad,abe4a54,828b02b6,f897ab4b,ed968bac) +,S(5dd977fa,a9d228d5,1885aaea,557f7a98,1a95771f,212c3ba,f1a4e428,3c3c6032,3bff9d4a,ba178f6c,d2ce5204,3daa06f2,abb06acd,274beb45,49e72a37,8f2eb656) +,S(2a76dc25,dd9a96c4,bcff1d8a,f3c9aaeb,261e4c69,a5d832ab,efefdf29,ce42a564,493452f2,3ad5cae7,de8c972a,af5c3883,7ff82aa,df616c5b,2fcab4c6,d5244806) +,S(cdbd3506,4c0e7923,822bab4d,b4662b2a,fd3935a9,a49e6d6f,f2db8f4b,d29a4b8d,b2126f2e,b61e274f,a688a84c,386fdb5f,58b84515,1543f143,a8ce0a3c,557a90ce) +,S(983f249b,2cb9d4f6,34d82d6c,e713aff9,2bcfd525,a4146a75,bf6f725d,2b54d978,79cd2406,850be02d,a6c4d25f,5a02dabe,af302e77,238833ef,cff0484,8a8abca2) +,S(88c765b4,a5a0a9f3,a257e21e,ffb23e51,9e128489,fade1383,96fdc18c,38afd4f4,f4d5fe64,729995a3,e505cc03,1d144682,e3336ae3,45c28697,1cf89b7d,595f46c2) +,S(197505ec,d603cb0a,199c7d08,b88d0e63,1d147d07,45603692,6b67a582,b7d52c31,947ec13b,f2d75fc5,af5a746,15a75aec,2f212adf,a234e08f,49a561e4,f9057f15) +,S(98184232,e10f605f,58a700c3,d6bc04d,9a19790f,eb638fec,668320b6,3b2eaaf8,ef3076ed,c0e2fa39,30ea837e,36c31f59,dbbdf192,ab18bd7f,39578e1c,eff9c85b) +,S(50f0db35,cba0134b,790f47a9,e322670e,f0c7d081,6869a764,892f8e23,6c0bc002,1c1b1c13,d98a84ea,e77260f6,58e265d8,9e466b44,b8604edd,83233fcb,68396072) +,S(d9e340ea,1a44bb50,ae4bb19f,3f4228f4,99ac8516,cd6bfa86,80c1dc31,d5665502,128a1688,335a2193,ff805251,b83baee9,341445ad,25048f75,355f4b35,5b4aaad8) +,S(15aa8133,1b84ddd,8c706702,555dc19,d42cb4a9,a9474c9,1e33c0f8,e87c539c,79530720,96586400,ebdd2ba1,7762ccbb,2a14bf47,45f63b1d,e22c6a6d,8942dbc1) +,S(6f708704,53d19a4d,b910d169,c7c7be23,d489dd18,23604242,55e182f8,7a5d34d2,e0531956,7c1c2bf4,a0a9beab,d7c4dbb9,c15246fd,5a6de101,35578aa9,99c7dde2) +,S(31e920df,cddca3a4,89ad97e9,168854f7,867f9a58,fe2d3f1b,f33f8dc3,c7167674,52712c3d,b0c6e58,15157660,ebe27dd,244a9c5f,b12cb8af,dbe82900,c3706f39) +,S(93300e11,708ff01d,96f81fbc,f1888c96,8258dec2,86a315ab,8d01f2da,4c8d51d8,15368647,3b6a208c,8449b53,66584e4c,9e0b7636,1256df46,4c93d4a0,e26c33ff) +,S(8f7ad50b,f62d6702,616cfdf,3712c1ca,30c94632,720797dc,ecd54f65,cfacb3db,5ac10a32,7dc52bc,33290080,a1a194c8,1eff0d71,65f9d34,7e4f8b44,8443c637) +,S(6ed80b82,76270d71,c468f5d7,350c608a,7f5cf51d,c8efbdd7,4458a487,2989f4a9,bcba2bf7,38f6e77b,465e47b7,c687c7e1,77fd3cf2,163b5a2,e00923d0,89826dc0) +,S(ec6c1d7d,b94989e2,962cb85f,777eada2,7c2b11b2,86949e38,eea2bb4b,7ce3714c,add9f9af,6042dfdb,1d4089d0,ebca5755,8ef2664d,52fce516,df3b030e,9ed08fdd) +,S(8f77cb2c,24dcc192,593a82d3,510859b9,c59bca8e,9546735c,1fe26084,4a37f093,51674986,fbf499fa,70b55bd4,f0a70cb8,423fdebd,587e6213,83199b3c,4fe07202) +,S(e2addf74,dae831af,aa4c4ed6,2f4a32dd,1122f2d6,243d049f,1fd78c1d,64b6aca,7dbcb394,1eadfb0b,8a56022,4da66128,a73a1aa0,20a5b23c,cf58118f,e28b2297) +,S(bf7af1bc,614d31c9,9afb7c6d,b8cd45b3,3a22b151,34ba872d,3e845da3,2b1e3eb,108d39e7,8cf88a22,fba9e255,23267bd5,2b850464,f1277239,7542ec2c,50125a21) +,S(88ffc7f,cec6580,5b92c5f6,952d82cc,35b4f068,a7581987,93ebc59,8efe50e4,382dacca,94b42c3e,ba1558c7,82394564,d39193c9,8b9e8cf4,a63dc4da,4d378a4c) +,S(b114a384,ef4ae60,b9c569ae,636eab27,9070e207,34cf83b7,a28353d4,7d3a152b,37c7673c,e58ee20a,6076438c,9bbe5cbf,bb826076,6d8a7001,b188c477,cca3fa70) +,S(e411a42f,e20d23b6,fa768fa1,e310192c,cfb0cd2b,1914c9da,627db3a8,c7e801b0,feb1b79b,43ee7980,7252bbc1,728af29a,8f6828ae,8aec480b,91c85008,959b1039) +,S(191f687e,46432313,c085182a,ede5e7c4,31057ad7,f1f48fd7,cb814fcd,74ee1999,5464b42b,3f77ce2d,59a39efb,83808cd8,43e5c540,3d5081e6,e4f4b1e,926dbc72) +,S(63ff4977,33b0a49e,f618c4ff,1aef537,9837744c,85a19bf0,b2208eb9,506bcd81,6ccaef97,ca835931,f3a87b50,a93f2a4,39535d8c,87e26090,3ae49b29,30593d3b) +,S(efe36425,c37705ba,69e7056c,2e8c628,f4ce72a4,68d85556,4c57e5ad,b7fc2c1c,392b9b5f,27ac49c5,831a5f52,c2e55bb2,8faa7f12,521732d0,8dd910c0,51970ad5) +,S(6d2126b,dd7cc08d,1bd41910,21704a1e,841d4737,4e5a0a99,9880051d,f77e94a5,2e9b823a,cda1be97,52f72ce6,ead42127,efb4d4b0,8daf55f5,5da6f956,84e6e806) +,S(cf7b9ff4,297d9c5b,91c6340d,c1cca93c,6d453ac9,86b4ef54,b20df6a5,4933743,8a57808a,2c07002b,111efec2,bf751b54,c20613c4,1e3612ca,83baa3f,eb670c15) +,S(b160242b,4cbe5ee1,d1dba4e8,e2d55a0,27f5a5bf,f7c023f2,c1524fe6,5f7e83e,ac35795,6cf31260,7ee9f54,fb39d3e,4f1faaf4,67d09567,6075b8c6,3c0fb5a0) +,S(7a86452c,4f8918d9,86d3dce0,22619a72,1744d9c6,dfd0e733,c02cdaa5,6abb050e,30d30b1c,b558b0e0,fbaa1fb3,596cf454,542370fa,43d8a85a,91eb6bc5,c90de179) +,S(a279bc1a,64d206ef,ea96d3a,b97c6770,af41ba40,9381d372,408052ff,582323b9,aefc853d,701ebc44,679a7ab1,fe033182,e96199d3,4b58261d,a1b4a6bc,6ce42046) +,S(e8e28570,5c16016b,608c301a,ac59f868,f7691886,261eb01a,d4e6ec6,a9e5cc76,92350315,f8e78051,b703b7a,49427272,c988ea66,27699eb8,f2fb3eac,9f0a983d) +,S(1fd9cef8,14f3fc81,8055f300,a734f9cc,46da1585,b939be73,459e0ce1,8a9f2bbd,dcc4f73f,a50fcc8e,6ec3c71b,c045f020,c26d79a9,794a25cd,26488c0d,9cabb55e) +,S(321b1afc,70275fd6,fd48942,df364f6f,c609d4b6,cf4e574d,39f1ad06,927e5f11,1368ecef,808bb311,ae9ad36f,8a4c81fb,725a80f8,ed029680,c5b54463,80add33d) +,S(4dff29fb,6518e393,dad0cad9,b0dec257,f9ef1e9c,c50cd741,8108c42e,f6d7bf72,4159786e,5aa4e82,4d7bfd06,713ec8f6,d92f8f8b,48304efd,e4d0f4c2,30dfb70c) +,S(937a84a5,eb63055c,65b162e1,1a3f2e54,c839b972,95a8c1b9,274373f7,5ced1e0b,a03078bb,bf11a351,da7fb3b5,2e3e7a2d,62c122b1,a9cf9954,53294f37,7966afc6) +,S(be3faa9b,7cab73b8,4fb2a87d,25db7fc5,56f07393,b3177c7a,56df0447,e96cc3d2,e7051ee0,1ad794af,571dacc4,4e91f7f6,9276446a,7e348ee1,2998968,afaf77f) +,S(58b39c6b,cc36d506,765d24da,6058d7dd,36928d13,b0fbe1f8,c680df15,756c9b41,449e9691,aaa846d9,a7412b77,73f7ae6f,b4ecd99e,c57863d,ad72d3f0,423d74ff) +,S(9b18a971,b1660b46,720e2100,865742c,8c91282b,1c72c7b2,8192bdc9,c3765798,2812e522,98adf83d,2cc07a93,4a065016,2be28d37,59cfd50,6c792e31,32e0f49f) +,S(a6c44c03,dbacd4bd,7a35e207,61778826,c86740c5,c92942d7,f73a1b3e,dec0f59e,73316b7c,d1fa3410,76b73727,8aaf39c6,2258d29e,c40c80e0,797493cc,7056077f) +,S(1ffb2755,628ff8d5,d837495b,94ad78a0,5dde2043,bbfa3aaa,21a05a3a,21682ee3,4a0478f7,6b8b6c,ffd9962d,f70e2a83,a71243ad,c690efec,5f95aff8,dbb5943b) +,S(aea4c48e,36051144,482538a8,8ee5f72,b67a21e7,8fb425c,3d6f1e78,419b8283,4517cab8,c28eb397,bd89d216,ce711332,82c7b530,6b64499b,2216bba9,41a80b27) +,S(ddc59bfa,5f8c0270,8436fabb,5003ca6f,b972f14,382bf127,f5297990,b4ed3eb,f6c3f19f,b80e75b6,53c370b6,742045e9,ad7dbc80,3a996696,99605345,ebd995c1) +,S(22184fe7,ed301b2d,62bf83ed,64742f6f,94d204c9,866a637d,d03c58b,54c80a8,9db27528,1073a3d5,617a389d,c5698255,3bc55d6a,3b80cab4,ace36140,8179b442) +,S(e58617f4,74e46f4a,74b0ed2d,6bafc3cb,6488c510,87136eea,f98aa37a,f201cef3,cc6a7375,52dde05e,71bf2047,d49a41b0,c6b141e2,e4f519d4,36d4f8e4,f2aa2220) +,S(c1aa4092,5addc5fe,de6c2c5a,ba73b3f2,b7394a0f,1d02846c,5b2a0379,824f8e41,9713af07,e30af560,9516ce73,5083ab53,2475bf26,5713570,28b586c1,d28c687b) +,S(4aa5d88d,89576459,1ccd1c2,3064c718,69e4d320,b0b71b5a,c08d291a,c1df6168,1d0ea41b,915c288e,c6b36cc3,f7806481,c048482,dce586ad,f240d32a,c913e6e6) +,S(93876d91,73137834,dca5e192,fa869a02,738d4171,391df1e7,43296f93,a2a8a977,7948463d,32bad450,24e63d9d,d5786a69,73fc6c8f,9d2a7c3d,e2d6fbad,7a6457a4) +,S(c80cd7d,30268025,b233dd13,f2f2af37,5d18080a,54c406ee,50e4890f,a91b7b28,9f73b58b,1f1d11f9,1648f904,ac7ad275,9e6260c9,27870292,278fe521,b718bc4b) +,S(d2bd24d9,7dd4a345,a8c4e857,97a9c30c,e8e7e7c4,3ce79bb8,fba4250e,a0c8c5cb,330f0cb8,15cb1931,90331055,809eb028,55ae895,ee1a30f7,665166b9,6494b9e) +,S(d4e4a3a2,90deea18,fb15457d,f3ab9815,5d722589,515a38b8,dc303307,5dd7e9f4,4854493e,77d0ecb1,742bdc9b,a5219e9a,71c57a6c,b914b8a5,6eec21dd,3e7d1c21) +,S(f0fb6cf4,810de399,fcd1b246,f0e76e2b,d318f82e,1601ebea,2779be6d,47236d19,e3ad5160,66480239,88b0b197,3eb2a41e,2cc9b4d3,7cf58d07,ad0edde7,ac595daf) +,S(dd4ec58e,3f4c470c,36991740,d02b0fc7,9a4f9df1,98647ab0,ebf73b10,34858939,3a6ecc86,a3b058ce,f278c839,541e92dc,737a6390,94ffa464,17e37da0,40a3bfe3) +,S(ec56910,1d7ed954,d4efe1b6,c4f6ade1,2af12f3a,ddc75a8b,8fdaebb7,ab904e51,3497c67f,5d594f71,4327111a,e22f2621,be7cbaad,b2cc1d6d,be0b7e50,d450c54a) +,S(ca45def8,51856a5,7ca5e1aa,64edc3cb,e25ef6b0,e28abda5,a85d9a19,dbaa35c5,db8b2357,268db9eb,e013fcde,111372c2,6eb4ed69,5a7a3df0,4d1d33db,703521b2) +,S(b44c5388,964521e2,4803c8b6,3dc8a494,40f8ba15,435ce2e6,5f6dc092,15b49a47,2e16435d,f30c4b80,cf125e04,b85166b9,509890a9,c1daf1f5,72462a83,de198d00) +,S(95b735e2,35862f14,e9291a5,4b46d977,33a20ce1,b59b4603,666cfeca,e05dea26,e1281705,5f38be19,9bc9977,b6e80c08,f22ab5b1,286ea553,21145675,264aabb9) +,S(83d9d867,8fbb0263,6ce8d231,3ee4716c,a15c71b2,66c1a7ce,e56928ed,73e5bdfc,e0494c2f,be92f132,effe7d78,499f4a00,c35027c2,37df8545,9918687b,6b949246) +,S(98b7c85,a04c546d,bbf6bad1,6914e247,1d3b478c,f30dd6f0,2e843770,49bbae03,769c3b95,3733dfd9,d9027da4,a10b0a65,ce4106f9,44364972,e569c63d,3b2ace57) +,S(3ce7b677,852d34ec,34358a8f,4da66d53,75019cb1,19a45dfe,864062a,a3b12e45,68d2790f,1838b86,96272c4b,d5e418a9,2cf03d9,de44f218,e42562dd,467e409a) +,S(a0bc28f4,d4da7101,41d0dca7,51542b83,6b50bdc8,997b291,e074727e,cad7836f,6ed7e149,40f2781c,d685a581,99f163d2,177eecbc,ca785224,2a8b4859,97e47c88) +,S(9a571ba3,52b1d62b,4e5d290a,c0d41983,97750fc4,9a18cb68,18fe11ab,1e185c0b,1a91cccd,b2b1f58f,9cfc0dfe,d3464917,f6c2870,9bdd8128,ff61e295,ad1b4ad1) +,S(fba0544f,cdd2de73,d24eca5,55a8c4b0,4e135c1d,8348cb93,d53f647e,2a21b9bf,7a11a425,a4ec6acf,2eafe631,ff83be6a,f71a6cc9,f7dbe3f7,aed57e04,2774568a) +,S(d96b253a,1edbf662,3902bdd7,1c3bad9,ecad1115,45614b48,5f7abca1,d4920a9b,2bc88998,f951b831,2f27d09f,2f331536,1499f1c8,b172f1f2,408d0660,3b18c2e8) +,S(2b3c17ce,1081b825,94ae14da,f9723f9,9823382e,947c1356,13a4b8a6,42267c2b,a4cd589f,2ebd245b,88c7f1fa,427a2ab6,e77205c2,dbbcc74f,dbbdfa69,336048ff) +,S(69698780,fdac522c,69313ea7,2e244d9d,3f6bc5c9,4fd86125,2eb56369,c96439f9,e8eeb3c6,460f475f,c06b5943,9bb9994d,8d6e4314,fe20020e,c1001f77,25a03154) +,S(1e344611,4cb4dc4c,963e172c,9bfc2f4a,d1577efc,ae2ffc6d,76395ef9,a0848c68,debbb8df,e6f59a0e,b96d464,3bbc6d51,a2bb4621,6059de1d,a473436c,404f5b19) +,S(6ccfae02,4c7f2a9a,ba12c191,bd35e287,d5c30284,c4273a1f,c558ae8d,286aa61a,c2014174,c78a2fd,d342ade2,51e4588d,94c4cdf1,ee83ade8,54e48388,b6e7cb11) +,S(5b5fd487,69b6a133,35bf0a2e,61a2128a,db43153f,9497c77e,c32b16e2,ca4c728e,9954353f,b23c9d44,eadf2632,168711b5,5a54c9da,53c41088,50fe77cd,8cf00c77) +,S(6b74a257,27af44dd,61fbbbd2,7323b63f,e6a41d9d,f5412215,65a6a9bc,35d069e,a4e1214,f17b8dff,b5bd689c,5f004c98,39b87a46,15245756,48099d33,f432a34c) +,S(5171a187,8ae9ed01,837408b9,fe08f317,8688606c,aae04b2,63cbf143,b8e372a2,b5e7de6b,964153cc,fe64a472,8a8f20a4,44da8e15,c593b7e8,68140276,b172d06) +,S(df9e86a,4337ef32,3518568c,e52958ab,dbce8a92,840b756c,279e96cd,43c8e80d,5442baee,c72f460a,110e8ff6,1e938132,50b2ccdf,61941df,5f591bb4,73027da7) +,S(ce070279,eb6f1f71,af876ab7,3903fbd0,ac9e4693,7b6d3307,2ec80182,3887c850,de83ddf9,88f9d345,e1ff2a79,e91f8ad9,6ea23097,538dde84,aea0ded4,b6a155eb) +,S(a0255c62,44afc84c,58238936,c9d08d36,96e5789b,ed28c40,7667f348,4c2f35fd,93e2d407,aef898d7,c898293,fb20f222,6cd5017,cd62669f,17ee0d16,773c6f7a) +,S(ae82dead,b76d5dd7,140e1197,a383ff62,138e1840,dc2f7ef0,d5126dca,86f0d86b,239dbbac,caaa0779,a9f6d8ec,2e30b590,72d36b58,199a27c6,5f5815ca,5720964a) +,S(cf0999ce,bee65e2e,d596441e,a8942461,97c597ac,9c090884,44c375d9,16332393,6620cbd2,f074edd5,1ff8cd5,45adcdbd,1c664ad2,6935880,8655ffb3,3a748ca4) +,S(5fb4af74,6404b01b,63bff1b4,1bacbb36,9ec06801,9454622a,76258033,9cd3965c,464cb2e1,2cce697c,d409529f,a48e7448,916a51b4,5954fe93,d99ce392,272abff5) +,S(15af3c0a,46b5232e,55e5687,a2bc4acc,2c7a350f,8114e3a0,1993a0f3,1b3216b4,ae03739b,bdce38b0,4735acd9,3a3ff7ba,86c8189e,56a5bb37,ad83a574,cdd45a83) +,S(5d0035d1,d008ccc5,42cb8b5d,32d973da,32c88787,640d0465,76d33e36,540b4b10,448ed8e5,bffa9f28,6689061f,73a74f17,76db8a8c,d5b4af39,6173e7be,6e54c465) +,S(944c70f3,9cf749df,edb9d322,ffc69e3a,a40b0704,fc4af915,e027bad4,83c95527,b0ac0c3b,bf489332,64a6e95c,e49a669a,df10acfd,48e22fc2,1a18ecbd,b86c6f0c) +,S(fa5219f0,82ec3c4a,3f246754,dad62f04,52e26225,6cd28acc,846bc5d6,151e4402,32ce81e9,d6403132,d7b64f26,a0289031,eb730d2b,dcd0065a,1b4e3f3,a7afae9) +,S(c9f4aa30,ddbee263,509455a,858b8518,85c6a16b,5d9bf032,70443928,38a30ede,5ef717c6,b438af31,9a892799,46b73ba7,add20334,c2fa5bae,a15b7632,34ad7b7c) +,S(2f4cf3ca,7454d569,5b0dd2fd,c72d4ffe,529b362,deeea120,162c178e,7b770319,dcda920e,3566ebcb,f47c1ce0,fb767092,fe7c87c5,ff146042,d5a0ceb7,a2f7d487) +,S(2417f576,2e0cd74a,f07a41a7,51f91b3e,a1cb0a42,2246af4,a0a96b8,79969945,6a96d755,f8dc71bc,adad0a3f,61cb44ed,741ef96d,96baacee,fcfba7ff,1e7807d9) +,S(9ab22f84,305a1c1f,675ca5ba,cbb3dba4,d43d060a,ee9148c6,6cfb61b8,5888852c,af0506fa,a2588e3a,7aeac12a,7acdda3b,b51d996b,2cca9c18,e23b517a,a428a03e) +,S(f7421ea2,24627926,28ed878,7e154724,77a91726,5a162f52,87501d1d,24a72b6c,db0ae665,e4484132,f372ca6d,8cd46115,fe1c72cc,885804dd,8f508900,5743fcf6) +,S(35756af3,548d57e8,dc0bb791,8b9875b1,10a912bb,7d971e35,4963bd7f,df5c6f75,1ca46dba,78a2b4fd,d4ed69ae,bd4e1961,86d94b8e,20b1660f,c517098d,e077a1d2) +,S(a7e9f00c,494cfaf2,16449d9a,b0dae7ff,de4041c2,fe031bc0,241c44db,1bf01837,f2aeb9ae,480b406a,9753d009,3b5fbb74,5a7760de,4ef508b7,d10804c0,161a0280) +,S(69451dba,92872879,7737755b,7655ce70,64838aa2,9084fc1a,c88f5e6f,ca62adb7,26218fa8,d40df091,31d845d4,96c7b950,1071537b,51a3143c,c73f1a7,b02b1cd9) +,S(c49c3b30,15cca66f,ce986a37,588205fc,89a92d0f,c520ad3,5eb6cce3,daabf06d,7afde84a,665b02b0,e0cf9ca9,9d2ad097,6242919c,53e31b5e,6216d67c,580e354c) +,S(e9e181bf,b68e6e38,c5b6ee1d,f11c14f8,90c0c744,8570387,1ab6b624,6b9dae8f,b0bcfedb,3f394317,907e260,c3651aa4,d1af5ca5,e1a34018,fc6c26a2,d5ef5e1b) +,S(a428586f,adf41cf,5b5c9e52,e0d6e1f9,2e7d8738,ab99e8bc,4062e302,de392324,77c3e18b,fe71c937,65b911e8,b49cdee9,a2a7413f,4de831c8,3f967f08,95b8d142) +,S(f5c92ed2,de1d1a25,4b4a4830,b656a674,38077be7,5efed94d,785dd0d9,72712cf,7ee98d3a,497849cd,5b5f6dcb,c51c5119,228fdf7e,1a67f1e,d7c670b9,eb3958fb) +,S(a85707ca,6c85f506,311b6930,767b5571,e18c19c7,ff2574bd,f268f018,b49c3f66,1785fe71,cde2e189,aaf67d10,337b8fb8,53654335,4d5ba73d,77518d9f,5e8aa050) +,S(8866f5f,a4c8d1c2,f2de0cf8,19eca5c4,d084ab60,67a7d97c,f9942fe,c0a7468d,3014226c,3f33907a,2f6c49ad,c762be6e,2915288b,a7ec009a,fe693048,3588336e) +,S(425f6d73,37eb2d68,e17d07c8,bda406cf,92af22b5,6461bd66,f40be14c,ae0688cc,e865526f,7c42e391,1ab73290,e80bd9fc,9643659,5871bdbd,ef8d698f,d04d4980) +,S(f70fc3e,1de3b3fd,55418441,43deb4be,36bfe6af,3bc9d9a2,f8ac823d,68323139,8b47994b,1febb309,e3774a82,d6b18d78,8ae5750b,40aa944a,dae404b5,da24ce03) +,S(1be960f3,38d2a16,703b10c,eafa121c,d59c66d9,439e9067,58a0b363,2a83116c,7fa4ca2f,8218ee04,351549cc,3b0100fb,647e0db,19eea010,62f1c0de,3de29aef) +,S(1f2a2d3,bc5c80a3,8af51e9f,5694a80e,e915eb89,4831ea7e,48472d53,320cf385,a18cea39,174b4c49,f9bcb945,5e6701f9,47053f07,6782ce9f,f55653be,6d3940e5) +,S(61d6b60,70846b0b,b7790861,17cafaa9,9aa67c37,fe77140e,88477f3e,44d04766,c7f4be90,86849ae1,632eb59a,6c96de66,b7c4b1ea,caf724d2,5338c11c,a8f2688f) +,S(2b37093,2d9a6451,79508daf,4be7f26,6d540538,9276fc4f,e6ccf0d4,1ee6cc9c,c002a3f4,2c8998b1,ee16a1d8,616ce0b7,91cdfc44,61839d9f,5ca0090e,295beca7) +,S(48f5c3ef,aba8b7a3,4d7fd136,fe9b01f,64af0e95,6a27663a,87cd6629,f2708858,8cc38cb7,fce46724,7c2f09cc,52f973be,90aefdbf,b52895e2,b88f03e8,fe32b5ab) +,S(e609b597,2e5ec227,6f5cfc87,67b6d534,adfbe9e9,9e60b86,e981dd9b,3e62cfa0,6be9c1ee,ff205fd3,e3b85e3d,bbf1b27a,335ca616,9ae189f,a433e65,f2b43081) +,S(ebe40b1a,5b2c9cc8,46eb8ea8,1ef0c1ce,f19a767b,2da6ab0b,2ab66a01,b16d205a,2f7710e8,e4fecbd1,39899bd,1964f5da,967d6920,d70b2f4,45d6f914,97c67058) +,S(97cd4c39,9391b1ef,653d32f3,9b062bcf,dbc72d45,83d81b3f,f70df659,358e3abd,a05a6184,a175b6de,f9bc35c5,6e9f5cae,263acf2b,a233bfe8,13dd98a7,fbf37968) +,S(826928aa,1d3fd0e8,53cd99fc,e6559ae7,257343aa,378100e,bf64a3c1,bea7e6d9,bc4a2db1,a3bde90a,ff50fddf,cf6f844a,faad7f8a,89bb399b,20b07b2,2e1efc79) +,S(3e754097,f3ac95dd,176e9181,410bae7a,83bd1431,6772e398,967ed39a,5fa19121,746cce99,c6a2cff8,a0907ea1,5cf9436c,ca7f94,7f3f1801,135fe675,a518df32) +,S(ce539464,b49b9947,808a236c,8a027066,82991f46,3bb828fa,44653266,329365db,3578fec2,b8bc4763,61f2fda,29c2c38b,a7bda79c,11b2cd41,a74d4c02,762e5dd9) +,S(c933d9d9,cda615ad,7ac41d6a,e64a77cb,44a2b669,21533669,2c90c3af,53e349dd,4a6da24f,83baebbb,8f2a8ede,298babce,a25b054a,a1c4cc11,f9f0b0db,572c610) +,S(459aa43b,1aa9815f,e9116f2e,78ddddef,a78e2def,28027d51,d081a3bc,800b2ac4,1acedbc3,de995e30,b16900d4,cddcd1f2,5c615156,fc29645,4bd5fc7c,63e993d5) +,S(5f2aa5d9,9862ad29,eb467564,639abfc,ff445334,9a30c4d4,3b27f913,1e3b0a5e,571eca2b,e61d0bf2,d9def9ba,445b39b2,5acfbbb7,dd4e2cfb,ce7541c9,61ace144) +,S(ec66ea1d,e6cc5d59,8c393e68,1a338549,fc2c3d7f,947b40f5,75681e60,88f4fd1d,d711ffdb,3b378435,5894dfa9,d0a5497a,5540739f,a3706597,8ab7dbea,a9280f52) +,S(6ac53df5,aa097f2d,9983f018,bd1cab39,69ad0638,c78547ab,1a481682,ad6105fe,95f69a81,5127b919,9488f224,24307969,3cd51796,bba08578,abfc8e05,6618a598) +,S(a8a3e9e2,9e4ad0fd,c466dcb8,fdc02cf4,16fb5c85,b3454fd,3842f129,9f96c0b0,df86eb3e,3006dea5,ed6d152,f394d7c3,169b8d09,bde3685,ce138a55,6716dc2b) +,S(50a764d2,a0d8741b,95ec84a2,feda6df8,1dbe987c,31861166,32c40c3d,e6db251c,b28203f0,233917c1,4b67632a,ce9b512d,76a8c7e2,430a4a40,85cfb422,7fe41055) +,S(c2c314b1,5ef9df1d,26856c9f,a6e39cf9,1bd9c584,582893a9,423746ca,1ab51ef9,a27f9286,ff7fdfaa,b949a9f5,d59f08b7,a22f1e31,e7175d44,93e219a4,e92ab759) +,S(ba655585,da44c8d1,2b3ce375,e220a4c3,64868b75,370fdb75,dbf6bb92,76a9d3df,3d64e16b,a03a385b,def18f61,432cc49c,bdd9d04e,6fc8873b,e51663bb,ca4fda50) +,S(3d45fa49,d4d100a4,b5a76a65,1a5100e,56bd0d13,b9e141c2,aca5cfef,a46e600e,92953c,38eeee42,e1da93b1,3c75ba48,da30390e,731801ec,ed5bdc2b,58059176) +,S(e464c346,e40dc3e2,40e5d96e,1fb2c10c,83e5ab7f,45138596,4ca46b04,bc8c3a8c,63f14b46,182950bd,282205aa,374cd67b,ca364a4,f57cf90f,c7ac90d6,5204cf4e) +,S(14a7e12f,e235b307,5b0d218,bd3dc720,d56f3fe4,c73841e3,fdf42dd5,aea42688,d79683cc,40cef482,ed6a22d4,8137a4f0,eac31249,9ae13809,9eebf3a3,15e9ff2a) +,S(8e7afbb8,21af73b2,25b34ffa,bb2ff6f4,61d2ee2b,85d5d936,a99fb078,963828be,40e4776,5aa0768c,f055bea0,e20e1062,bb528470,dee61ec1,6cc9ce7d,ae6b1853) +,S(9d641162,3227bd0f,4bcf9f1f,9e5ce829,7d844055,8a7ec246,5b160690,53297573,ed0d83a0,68001be5,70067ea4,70fec09e,1f8630d5,da5d1b2c,126c35c3,9b07fc8d) +,S(6758c6d6,d9e49d9f,4125b52b,e3da74e7,52bb40f1,44af0f0b,7bd80589,7fc83eaf,749ae08e,c2aa2c36,3a229b3d,e9577dbc,5f7d22cc,d46826e3,6a1cb434,184fd292) +,S(b3e11a0,45702d8b,14d93df6,3a4c11f5,32632719,b4a33fb8,da11514,bc61d73a,c6e152b1,2b267ec2,1a23892,8cb97044,9660c6b6,34b22d18,9a86fbd9,a9d562eb) +,S(50a325ea,3b309911,1371b0f,e0b9e276,137bf43c,22108b98,994ed5a0,d66fa5f1,946dad1f,d39e0aa5,8a758527,9b39efea,8a99399c,2750739,dfeae140,3745b70e) +,S(f7c8f249,3befd5a2,cf6802ce,8ac508ee,a97341a6,a46efe39,1214e322,e95e9661,3c072cc4,eec1f370,144b7ec0,598e4d96,573883e7,fa3f3f5d,4e33d88d,1e34cb67) +,S(302d3b50,c1543386,f0b0b94e,9c49ea68,38c7e7bb,86c28cc3,c8965dc8,38f85b6,988047d0,d891aa2f,60b66e5a,96c78c91,3588d128,d4e7f720,5672d25a,88310744) +,S(cb8ee728,2e7e5ba6,d0e8ecb,55ede89a,1d3810fc,b0d8f86a,fbf53b7d,219f0eb7,4b04ea2b,efad1099,8c9a4e3,cf0491c2,bc10bd60,e06a118e,75fe0163,ab8094cd) +,S(645caa2b,4a0cd8aa,20cf6f04,ac73a49d,74f92035,f90bd31b,211572d4,cfd5fd42,793f2996,35f9d7c1,de62b64e,afe516db,b0aa1323,7f51d0a6,b6fc8346,fb7ef5b9) +,S(4d37342f,6148b5e7,5434b8df,6617d64c,f00b1c73,3d85f4f3,e69c4a27,395f5a21,6400092b,d4c5c705,464a7db2,b1b6b667,4eebd7dd,38d05cde,d1577d8a,53a708bd) +,S(e634bf17,24e07b2,b4ac6285,ed28bd39,747a2134,36e76d3d,bd693170,18c0e0d8,cccbcade,4b82a51e,c31d9d8b,6b113876,5e9660fb,e897ca53,20db873,13e9f021) +,S(80a00de6,2767c513,d5bff535,431d259a,64c49006,3bbf992b,a5111005,360cef38,7dceb589,e8d73366,c467e23e,8fdc7e03,b2620df7,9530b6b2,3fcdcdf,628ef572) +,S(606d50e6,d23d50ed,9a5b8409,f11d5c76,baf5b765,f719625d,5b2e2dd,9e8f8a0f,19f55492,45b1b4c2,fcc1d220,6c171200,4cbb41e8,bb7c8cc7,48c4366b,3fb32788) +,S(9c8a0a14,f7d44fb7,4a7ea835,ae4a1932,266c3083,38d66a24,7fdd60ee,e4f0420,42c6c237,31578dd2,31eda621,81aedd29,8737fc7a,3b2be8b4,d0187459,e5d9169a) +,S(d6ccfcf7,81a46f58,ff9a0154,8a417924,1a32d3ca,43a8e59,cebc33db,1e35da1c,a1caba1a,ce846b8d,8b4824e6,1570f832,87cbcfbc,910256d5,68bdf223,861d084f) +,S(8cfaf36a,3e4c3ff2,4556f446,4947c8d0,6eed5ded,a40ec0da,4596bad9,f5f2e3c4,991b6ecc,ede6cdfd,e33f81d1,c1067f22,6b72373b,96ca31fc,c80e0692,d8f3c4d7) +,S(d46c3d81,5b0f3a0b,bcef3973,8c6a6cc7,189849b0,4917fda0,541c08eb,b7e664a0,35524bb6,d053e5d7,c8adc9b6,3a84ed81,58cffe99,4041e642,1fece58a,d967c159) +,S(8ed7f0a5,2f1f8df7,f82dce33,e4637dcf,e2ce9b75,ca02ef04,90c23fec,2b7adfff,f02460c7,b418d10c,96c27225,3dee3b66,4be1aa5d,427759a5,5d90c223,628d99ff) +,S(433ecadc,a8a351bd,52ba4d6c,aeea3ff0,825c46b2,8abd2c2b,cea85f6,6daaa2ca,4d3b71bc,c2d7d177,45cd03c4,86f390e3,f6d396fc,83d0438f,983a142f,162977e5) +,S(c0771ef3,10377f83,7a9bbddd,81f6642b,ba04493b,15c054eb,249b3f9c,bba006e6,3e53ddab,1d816a02,7898c6b4,778d4c48,e1ea2b33,a63955b0,784df258,ef4ccb1e) +,S(dc2e0226,4a6a87b9,53997383,e35c6cd8,92072ba8,a741fd23,8ff3a9c5,f597ad7,898ee746,ecd5f723,440ac0ff,6f597e85,8ddbacc9,cbc80e01,d8a3c1f1,7c12c74d) +,S(16bace34,59ad8cbf,1fc5f781,19cd9e31,d043d7b2,ed839f03,11f0b760,6adab771,f64532,6ec697e3,2ca23979,72b2b834,66e835b1,2bd49243,e896c1df,c02fb1c4) +,S(afb94d8f,3a271439,146539a8,68f00346,9af55eda,839c81a4,725f3a5,7d69c736,afdb294e,a455031d,a70a4eff,7563d764,bdf37fa7,5594c9cb,386e8bd1,a35201d8) +,S(bb31d236,4a98f7f4,1edb0ae7,6018e5ea,ecc33780,5f781dc7,6b15aa9,d0e89b74,1a064c03,1f47cc7e,cd49f032,f4dcd95e,87cbc28a,7b9d9c27,a92a4c1f,da031a9a) +,S(f73b1b6c,4bbf5da8,16604ee3,ef6e83b,241e486e,d727e700,1c3c115,3c4318b8,9a28ad6e,9d64cba,b58ac225,5c01b261,25ba08ef,3b7d5ffb,476f9b8a,6c8c9b17) +,S(63bd212,d0ddc5a0,84f8ea7b,69605b2b,708c8766,f0d3313,b236e921,91afa8a4,ee6f4f6,4824032,afbb0b3,a9fd342d,2fbca8e,ccecdb0f,a3307698,c56c3e67) +,S(6367d22b,36068022,30a416b7,8c689078,967b955d,875fd629,9e007f86,1abc6465,c3ee1f2d,14e6793f,17e444ad,5595f9b3,118d1647,9259e0bb,ec628897,f69417eb) +,S(64e2e543,fbb7f52e,57901e3a,448394c6,c922d0f,b632c4f,2df061a8,9485976e,641a602e,336a68b4,fc447e5a,5863a4e6,89511942,4fce011b,48f937df,fcab2a4c) +,S(2e290afd,18c835c8,d1d79e86,9d9c1322,e16e824a,60e67f38,d6bf3031,e3fee1c6,7f85628e,d2fa6b67,7686b0e,c29a3626,da18ccac,5e373874,96266458,79390f21) +,S(859a208a,c475d3d,f5f22907,988c7774,c0ba2dcc,d80ba42b,17ef1087,2cee401e,a667c645,778e743a,d62ed1e3,cfa12fcf,84b982a5,f1349e31,33627ffa,8b19f5d8) +,S(c9291908,ccc50aae,f19c0b86,829fdc63,b608d3db,d92b0939,b92ac02a,2bcaf21,e5c52bb7,47111f58,c71352c8,b2fc89fb,20cb7d45,77c6231a,17d8d01b,6cd2599) +,S(50359490,42b5b620,78ab0141,1f1a1d4b,64bc42c7,58da4459,b04d41c4,61cefb26,f61e823d,b68c064f,f80d9bd8,f272f817,347c132a,f7bd2af1,e5b451ea,bf4f04e0) +,S(f9bcfae7,d6a3f1fb,612787c3,53b535ec,39f29a01,9f45f43e,7b61f2de,c4a4cbf3,f4d86e6f,273ad7e7,902d5a99,50fc846a,a6565862,aeddc67b,28fc07a1,232ff883) +,S(1c8fe8b,901cf050,e93c0004,b0764715,602ac4e9,7f8d5dba,d7747039,f14a9152,b25ddb34,7c452942,92143b6e,cb19f87f,b42a0f27,f6f74c4c,99d7b80c,7d36769c) +,S(3c50be1,4cbe3a87,d363947c,6eb534e0,8ff676cf,412bc4dd,2c543131,e786f552,4434471c,6e03f600,d8a27775,4466cad0,194f553d,bb653238,8a0ee4a3,9b05a74d) +,S(64cd71b2,555472f8,fa968b4b,4f8c8b24,5b3e91ad,6d9dd409,fe72702e,e70522f5,f1b1cb3a,e9fa4855,2d7fc2a,819bd629,40350a3c,168782af,5bff16d8,89ede304) +,S(c1c00444,c584c346,d1bdded8,7cc40b0e,fd8f69e7,d2ec8bcc,c41e3414,619af7a8,d631b494,3e3febb0,87bb391a,d5810b61,f78dbccc,bc6de38e,ee09005d,3d879436) +,S(fa509582,dad5bb61,c7450fd0,3b7e4ba0,2fbd0c28,af971b96,cbef5956,3fa2a7ed,267c2764,617c2f78,9ab890d7,56be2195,2acdff5b,3490b816,165e2b36,2f3df4e5) +,S(655dcee6,864e926a,a6e05f04,b604c2da,35175e0c,f7d264d0,50920d46,c1a2386c,da2eaeda,bf062cb4,ba2d36c4,67965baa,5f1dc238,b5e22df7,2bbe14f2,cfee19c8) +,S(6ab5e1ac,1b7be624,97c8fbe,fec5c4d4,2cc1de06,d15a1beb,7606fc0a,df3c213e,26f983b2,4eb319c,7443e024,7fecdf58,f833928d,4e809d3c,f36231e4,d0a9e466) +,S(c7da869e,39caa2d,e9f73a0d,3f73ab73,6224e2a5,47ef5af3,5f5a9d51,60c25f3b,e99b1102,49a607d8,12af4cf6,76ae4c4a,cfdc0f89,9ec2175d,c7942b6b,40da579f) +,S(2a6d4ca1,5f1c3ced,ed68091f,af4d149b,e20b6854,bf015084,a9cc0d21,4944ef99,dfc27688,ae9295e9,ab8d9284,6a703ac5,5cb44bf3,13f179b4,ced6b638,e661ae0) +,S(447260b3,bba7224c,aa659f70,b1e7716a,92600a27,18129575,2de62cda,11c846c0,f17e3e0f,33ef2ede,8980c922,613947,8331e2a6,40260996,db8da1e0,dc8999bf) +,S(8cdb1cad,baba7003,8d4b0f44,1b312aed,5a8788a6,6e5356fd,5b994f6f,a7781969,b3a5bd0e,262e673a,ae7be06d,8d56c203,b88750e4,ba06cfa1,7c177edd,74536977) +,S(28be0f50,fb60f905,18323e6c,dcf46c0c,bc3e2c0f,175d8576,85126a85,d5caaefe,5cc058f7,fb188c4c,e1140429,568c3176,8d986fc3,e96409de,21bf9ba3,862b7320) +,S(b6dccba,dd2dfad4,8b69218a,d9cf839e,837e2262,7f8f0eb6,f23484a2,994673a0,e1c14ad7,297f1626,774aa2ab,5dcc730a,49623176,ae81eeaf,b52cfd4c,fa2de992) +,S(e45ebec8,8813f7e5,7a7ecec9,dc5fcda6,b9cbb0f9,19bae1d,be770955,e3766a87,3a62a0bb,4ccf3783,7c384885,7acbaa9f,f915cc7f,13a46856,3ff135eb,dfbb07a) +,S(de926f77,26f39d48,1e0b9e55,22b7c874,59bc9d07,df65f0eb,7b21fea,e8dccdbb,9d190ea9,263d4240,24b618ce,1239f6e1,115be2b1,d721aba0,f5f367f6,304d8e05) +,S(f7621384,20669c04,6d794807,569722b4,91e4272e,1305f091,b54a03f2,ecf2caf0,d0c7e8e5,a227f2a9,5c594528,4590caa3,3088c92b,b4c7cf6d,12d293d0,4b9e4914) +,S(4e795e86,44ffee08,f44d472e,8ba0eb9d,a5cdb1d1,619a437d,4a8bbfe8,565ce751,5292d8e5,478268f9,bb9b4be3,c751e587,65038c55,99cb3549,749e83e2,1590a4e0) +,S(70e64689,a944b03f,32b33a97,c8923531,cdf75e8d,e8577559,bf45d2d2,ddb50b3d,a675c6e5,460b89a4,a2dae263,c71e6edf,925a93bb,a916951a,5364d252,c225586) +,S(21637c2e,682b247e,cb8c1c,8b4bff1f,477ef390,3b9da0fa,b08b5cf2,5b67056b,e357165e,3e761a55,7e4c2b6c,727d8387,c5716b58,e24d0e04,8314979e,4e92d882) +,S(7691a399,8dad2e1,741a4135,18bdbb,d8ae5bb1,7466a949,a40560a3,9c1d1964,225f1404,b05b5bb6,cdbf2296,f76e7f27,257280e,28c68be4,d8c81c47,a422b74) +,S(748316a4,f3950849,9af5a14b,27eabf9,b0d11e91,d8752cb,69899af8,79af9302,cdcdd4d2,6bd709d8,c3d87c12,6dd8a2c4,f600fc1b,9e84461f,1793047b,5bfd7ee2) +,S(af588dab,3839e85c,6dc84aa6,c1e05294,a9708951,8006b390,c2ffe0ef,f6ed9b8a,a3d37640,1b06548f,2794131f,5e002aad,616ca135,8cf0c81d,87015416,37d9cff0) +,S(bd91dc60,31706ffb,19b61796,995728b0,5f869d07,6f0b6537,35c46e10,d9b42dc6,3c963ed1,5a74f5c6,1a28db8e,de070870,cdce2cf7,d6525a6d,16171076,44f153b2) +,S(e625c4a5,91460bbf,5c3aa583,c4cb1e1f,c202c82,7debb82d,985732ed,ede98f47,d026c5f9,a9035396,1de50534,8e4ac600,812a461,c913299d,7fddccc1,5970b72e) +,S(6bd227fe,d4b193af,8b94553c,718357e4,122cd057,d95980e8,ebc8fe5c,7fdaac1c,5f3fe540,a98b044,9ed835d3,b0a2b4e7,c66a0549,e4b7b9f0,22fd5249,c621a9f9) +,S(27707a25,895e6f38,523d3872,c5b34e7c,68a0f0f9,54c6ef49,5cff6664,1edb2609,ef6f4f8e,c893d697,69f34b38,f7f677e9,e5de5c91,48cdf35e,3a18022,3ea777ee) +,S(6052248e,3359414e,bb7770ea,4284d7c,c01770c0,e75466db,1f314e0f,cff0ebde,3d982058,5cf0d546,9fa62e02,aa556fb,1a1ac7d3,1cb9712c,8b118e2a,e3f7b7a2) +,S(f2cb5b53,4fa6124c,16d82506,8b229857,4d4fc666,9b45550e,6c75a114,f370f6bc,5cde5707,63a5cad2,13952def,43cc779f,8ec9dcbb,c5fac8a0,ad7a740b,7241112e) +,S(77ad8215,9fe6b9f9,e08030c7,a75c601f,4989b51,4ef6db20,aa9d0b23,e87a502e,9268a1ee,ffc24932,74856add,2ba1ebb3,c13678,99af932a,87fc680d,ea9b703d) +,S(4418748d,171cf80f,a7f80fd7,c2d7891b,5cc9aa0f,ba4ec1c8,a114cbc9,4a8fd29d,5130285,79f01b7f,72f18322,b279fe7a,9916c16a,a67c6aee,babbb418,fb1835c1) +,S(16af4960,6f89c87b,7e5901b4,d11a826d,126e59ff,df7d0883,1d37d7e6,367355e0,1a138440,537223c9,e8e131ca,8ea3b38c,12c8e8ea,50ee09f6,8ca4c2cd,4cb04c2e) +,S(22d2043c,ab4431b8,cf77ba0c,ad81848c,730a730,35277e4a,ae6392f9,de120f9d,d7795dad,5e5b46d0,9c36520a,c7fccf9f,4d71f9c9,8ed3d45a,432f4f6b,991b8acd) +,S(57e7a8b,34826533,7e203360,2f6244b6,41d92c8b,b2419734,9fbb3271,57676302,4d9238e8,ba4bc8b2,c3abd2eb,6bb2e545,5146afdd,3d1ce2a0,9752803b,4599b83a) +,S(45567f60,2755027e,282b39ed,5ddab1c,7ea19a82,4c0609da,9ab455b0,26acc359,db55ed5a,77a354ed,e4229161,141392dd,82c1ccf7,f726fd4c,2fbba48d,4134f5a7) +,S(968fb554,91059347,9dc1933c,a8453201,798a0be7,1a284c38,3e8fa5a0,f67fa80f,63586b1,6853f550,c36d8394,56718376,1c14101,dd03cbd0,b164cca1,24e8920e) +,S(f366c649,f633cd7,f1fef522,b78f7b85,3d640acd,11af2d17,14c14251,ad873107,5fc396af,38f4988d,82c4cfab,59d415ef,25b260d5,711ad546,e56fb65c,7482c6b9) +,S(aa0c4fd4,4a2e68b2,edc16eff,d2b3c29c,59b19289,1503e6e9,ad068743,fc201d06,614e3224,2fba7977,464b5c4d,b76270d0,2763aca2,54aa5b82,b5ddf8b7,ff3fee33) +,S(6c886cee,19b2cec6,91c57abb,da830e45,da4cbdcf,37484ad2,b4444948,8f2cc876,24cfcbbd,9ab4df87,87eb384,fec64e5a,a197e897,bcf2dcf5,def4b94e,afc16a1) +,S(4d600199,c33f76ee,c81d1686,f116d4e0,fbe5e4ca,df3bee43,9a81785b,c6095554,cb414cce,b769f70e,115d4321,fdfed743,2bf73dc4,9f1628e9,dad15f32,5fae614a) +,S(377dd0a0,196d59e0,e71e8472,4b65bb16,12c3caca,d2f2230a,a675a25a,5d0a4fc2,2c727e7d,8c8e27dc,a5ff7c27,b349752,1159c736,2b51f38f,e0343c74,acfeb560) +,S(9cc0cf8a,23afdf35,1bb1826f,9d900b8a,e8aa5019,8cf36552,9ca928a5,9c820f46,b572f15b,e2aac0a8,c8142c53,ea43a0a0,693e5446,5d5531f8,b068d347,f7e67256) +,S(d55dfaa6,41492b1e,981d154a,2be0441e,4cfb01ea,a51c40ea,d4a4d8ed,19fa3050,2e795dcb,408c74c2,a9898f31,523a1e72,da0c4c77,c2dd2eb,45fb2e51,8f238ac1) +,S(46bf63d7,2d113152,3075efb3,fac6c07e,e3d27e87,279724e8,46306dee,7d210fd5,771bb1f2,30fa3253,7e3b433a,2905c4a2,dc4a2e37,32e282fc,94cb2c88,33b0b199) +,S(4bcfe388,3e77c17,8c6f1826,f75e7c3b,594ef8b8,c1a9ba3a,13f00597,50ca3aad,b5562e93,9dcf4672,fa283cf5,6c05389c,ec5ea923,b47d09b6,2ddaaf54,8a1b0129) +,S(c9681af4,715e69ee,d7cce802,34bb2a49,6255ba39,1df76c57,df9747b8,d8c241db,c8b175cb,b03d5206,5f2bb846,81bdcb04,da530e81,31082e08,28c21f7e,cde038e6) +,S(9fa0a1b,56bd6ac7,f4a2671a,3b4f6ae9,bd5538bd,4c6b4101,790b16bc,c2fbc33c,27f9eabe,785c7cce,e4859959,348b4864,16056f68,6d445fb5,c08fd8b6,33129e63) +,S(15042df0,ca178aac,723e7b9,8677964f,a87203f2,bc0e1fea,a56ec6a4,73d0381e,445db657,dac86b0d,f8f9eb59,a143e75f,e271cbfd,2420b3a1,677ee3bd,8d0183f2) +,S(354f6a63,d4c1877,e0e7da3e,921db767,6b7f9dd0,eaf8b65,eb08b032,1f37e9b2,1000503b,d65b80be,eb72f480,a43efd65,2eb784d8,650bffea,5559aa2b,104ea8fc) +,S(19c36161,7a448fc0,49cd8864,d2707d6e,9e4ba74e,79ae3d8a,c11430c5,99de065c,2f9f9fd8,fd38ee81,94ef570c,1b7299ee,75742d18,1610a2fa,4dd06f30,989acff5) +,S(3739848a,d2ab8a66,b6a7a2d4,add9fa8f,5a50807b,56ce5d39,5bd4c146,7083f88e,6fd71820,611102bd,f4dd2056,92e188cd,68a5409,1036951e,6f58162c,65f0cbc9) +,S(9c22cb45,261c2336,7dce66f1,f84b84f5,2dd7e58f,8ac6dba9,50062eac,1c10aa35,ff84e3f5,8c25be72,910bead6,286dcb9f,605b0017,1996d46e,c8dbee64,52a1116) +,S(572145c8,7f311732,7ecc71e4,5e37c555,5a412785,7513fabb,d0fbdd49,6db4538e,163e63ac,5e3908da,2aed5166,c121548d,5338c6ac,4ea7550,242c7910,8a38871f) +,S(c9f07954,d8413eb5,8ef213b7,51a966c7,4c641ed9,8db8685b,d931e321,2de940ef,9e6844bc,804f3d3c,a065fe7c,b09bcecc,92cf5af3,ede9041d,792c184c,cde17fd0) +,S(ac297f46,b07c8a29,d664a24d,f05a8a51,f7b0e4aa,e8800c3,f9291a13,787f25e3,686e3b7f,78e45ad7,fd1bbca0,54a5d182,b1556c77,753c1858,75e98de8,29b66cbb) +,S(6c5913b,b383a688,390274df,121eda23,5ad55dbc,80bc198c,21897934,98b3e1b5,54b9b83a,e3649f4a,2f11ebf4,61e24a55,53e5b4b5,d0f78dc9,1c35aade,2cb9ccf1) +,S(b9926fa3,f503356b,eca59ee9,2163cbf9,846e3efd,c793db45,cf7ea8e5,af2495df,d6dd7c5,33d4e7a1,ed415c51,1fc15e05,54fd00c,100bf047,bb8f9054,42e2a512) +,S(4325d1d2,f2cabe77,fe0ac758,f6073057,cb36adcc,5357fd5a,31473ad8,74e69556,de437968,2ff6315f,8870562d,560cc48f,818c8fb5,c45ad932,ed5a7d4f,534904a9) +,S(a183e95f,fd84bfca,4afc9059,ce1c40f4,eed924dc,d1bfff11,d38a8c1,14164917,11c57610,c7ffca41,145046d,4cdf95ec,c38d695d,bef057f0,a0d01bb4,41d64b95) +,S(b340d0d9,ad6528f0,d9651414,f48fdbc2,ab7af5fd,3baa8091,84d5e881,6cd07114,85ed726a,9ecd70f7,f964dfbd,40e4b68e,ae2671a9,b6c3d384,919d040e,120dd4e1) +,S(b52daa88,35992fa4,1595f0a4,c9e075d0,b146fae3,6c0d640e,8e6f34c2,16719377,6088b139,9fa83889,a6cb5cba,d478c7a0,4f42f082,24b169df,85ec90e4,7a4ad7ad) +,S(90bbd15,42b0f88e,9f7f82bf,7c2b5fe5,f269ba36,4523a18d,5dc5709a,2ab9d8ad,c9df924a,51af344c,a71461d2,bd3743df,c6958490,caa68743,e06e7348,528fc4e5) +,S(f72ee5a8,1696194f,ed3d4603,f2c9312e,b31c54fb,438b1fd2,2788ea6a,a3aa8365,e2963d82,b6ca0f4b,8ffc1078,cd45a72d,e66f4cc,78567074,4fc1721,e50fde8a) +,S(108aeb71,5bc70525,42f5d6dd,dfd348f3,66a10f4d,d99f9298,c35a8397,e6b9fb53,8388b339,75a58e04,a0f6df47,23728986,97b8d970,ac6bd45b,49b9cf1c,3209f1ce) +,S(dc3daeed,87345ebf,824a5ff5,c7f46268,fe54c901,493e2e86,e2667fb6,ff61d5b0,b5a7e641,238e0467,196c1683,bab47f66,cf001079,932a5d56,da20f89d,d93411e5) +,S(3f96a83c,2be16120,e81e1d26,e3853ef3,a82c5f32,f8d6bef9,38179c06,4265c589,eb8d370e,797cf20f,d5a0d734,9fbd027d,630ba1fa,bafffa0f,2ea37131,6b5c64b3) +,S(27caf86c,e1f423e3,1cca2278,244fbe3,b358357f,af1b7866,1de13b96,eff5c4f3,e8f77718,647acfb4,633ddbc2,3dbdca0f,2187e24a,2f2d45a1,39bfa1b8,a2b30f61) +,S(6681cfb9,e2418786,1887f964,84819645,2d301a1c,7c082361,67a24c62,f74d04f,9c89eb3a,7849e944,2f5f521c,c08d11ef,f1ce4869,98d4d760,8dcb4a37,b815151d) +,S(6711b849,48664639,67274709,2fbbafa2,fcac45dc,1795e80e,67fb0e65,beba8da5,ca12c83f,1c8f5ed9,222d8cec,bbcaa51d,6b986a5f,60d2c118,b812b259,294cfcc6) +,S(5ee9cfd0,b1102cdb,a0fd22b0,569875c5,fdd73467,22769011,8b7843e2,b71dd94d,1dd7a4e5,bd7f9ee4,e17c518f,19b60332,60d2294,8b5f463a,ed9021de,87d7d86) +,S(586dad7b,13390be6,f3d95a46,6d0224de,d7538f1d,2d2d9785,e38a3f2a,edf4924c,c777eda5,a68a3582,1735bd33,7119e58c,bc2fb101,c995f986,7bed9786,cc2b64d0) +,S(5a752d2,fa012c7,1924b6e6,90ddc7e8,867f6ee0,ad8eed91,84f7250d,665091ec,57f2232b,32b36429,f15029fc,5789042f,ec1ace97,5f2cad27,d53ae819,47b95db6) +,S(f93cbeff,22bc577e,a9cfef22,378eb142,426372e0,7be72e60,2a8064,a53e638e,abc772bb,401bdb42,94b16670,2279e4f3,eeadb75d,57190a59,96f34237,83afe50f) +,S(8c272c9e,96130972,2efc34c3,6a6e63ac,76052cfb,856eb8cc,3dd014e9,d2608a9,9987d168,13c57162,3ba7d226,18b54003,731e3716,3495edfd,e85e927e,6e4607b3) +,S(bf78a0d6,1519542b,a54226c4,d386ddc0,38dfd84c,9f9555e2,3e187c11,4d769bc5,6094e1e4,d84ec081,e6014b59,d42959ef,e160587d,315bcfe5,5d26ec98,b1910280) +,S(5b264b76,cd092a1b,ffbab651,f42485fd,497aaa5a,e311eb28,ee1fdb99,32e65caa,944f9359,4b68d7c3,6610fdc8,85695b06,1dd84722,d5d88c84,c8c188e0,69d70d78) +,S(a2473cea,8075a0d1,33bc1459,8d147705,322f7151,274e797,4b7e042a,c082b559,64de830d,b6557b06,d9b09d79,4f6c905b,5168d32a,708484b5,d2c68a89,a2575a18) +,S(3e18d5e6,3dd0c514,4341535d,a7087bd5,f14b0708,a292350,6528a803,609efa45,6e9c71b9,7d007382,f82fd041,be53470c,26dc2f16,26a9f0a6,e1d9ff67,54288c5b) +,S(d1acdbcd,b91e6315,bce96eb0,9c229086,6a767441,4285984b,71af6156,8294dfa5,5e3b0cd8,9872375c,3f807201,73e29d3c,accb67e9,66b99452,2c9e9f88,613da5a4) +,S(3aa999e2,9344e0f2,b5ecc880,a35ecf75,25ddb028,c40f64e1,a210aeb7,d850c90d,cd2ce25c,fbe3a1be,dd2e6fcb,e9e9a881,28c454e,c7ca1951,5673aabf,a543d42b) +,S(98a2361d,7c3815cb,ecd0aa4c,8a3a6ca3,3e1b31e2,5a4b6398,146d6709,61a5017d,1f33df78,3040c13,be821395,8d78e039,516df25d,4d9d0de6,d397128a,2c09f2bc) +,S(528b9d8c,907ab870,6d7a5562,84cb69cb,ff348247,be1b7cc4,61351674,53d98d0,f91eb836,d6665778,7c6d67bb,800a1141,29700d53,194c5051,aba7ead3,ddeafabd) +,S(f1adec8d,3d1b0d20,8bda6a86,6b8cf730,f4be50e6,2c8d993a,3556c1ce,625029b6,478324aa,c3bf6182,25bfb61b,32d47956,57e4a754,e08a978f,964741d4,1bcc7224) +,S(ab2ef133,b1b115ac,41870cf8,d75d4aa0,e0181ca,742a8f10,f74d50a7,3924a099,a2c47b74,c584eeab,57949ef5,38c0af69,2f2baace,70a730a5,75629ab0,566a91ea) +,S(9d4eb41a,f6da6f83,b1d20e2b,f9370868,539a617d,111b8c72,348c9b27,e0576f85,c1c7b00d,b786c84f,a8adfe90,4353305f,73acc3c7,1c2580d7,cc5d6b33,c5f30eea) +,S(30edd57f,7b1b2c81,c886dff0,5d9e9062,a553638f,9e4311d0,18a42229,3fb916d9,6bc4774b,16d257a1,81e20b48,5acfce30,f7449e64,aa288502,d44e7c4a,44842ee7) +,S(28e3eb9d,9a2b855,65c58fc6,a492014c,f10969a7,1e81066a,41d1c574,31306583,fc653b87,80734067,e5245c,8c150ae3,59ad3c15,df4a8e7d,dc93c8fc,dfbb6c2c) +,S(cb984735,e3c842d0,a2fbe578,ff3e8263,5a3a8bb6,749d8e08,c91571a6,9aac75a3,e935a0cc,7181c3f5,3013f977,ad714af4,4c3e257b,e9936268,b481429b,7bea8367) +,S(36186672,7e8307ea,eea83b10,6850dfcd,5e4d665b,20aa37a3,ed0051ab,a40fe170,ec626ed3,2ae6dc01,f5d4c710,ce2cb349,ab27cbf2,da5d924b,e32ef8d1,707a6d) +,S(b1a40d5e,69e9f365,c2accd54,dc8267bf,4260abb2,3b503136,2183b17,4c6b7d2e,76619dab,2a7b41f5,2401ff89,4ef632eb,31eddea8,bae27c3,af04730a,3dc186ec) +,S(abd488b3,dff60a23,e83f0ccb,22620064,b32a8f35,d4c22be2,42eb1427,15660825,6eff80f2,17dae3af,96c7a463,d1848bab,fa994904,91a1105b,e1bf7f23,840b3a89) +,S(ac0cfb04,d91ceb48,2f497974,321bdb10,2a572115,73fe4598,c92510ca,4dd6aa22,6b5f6d87,4a90d0a9,658ae4a,64474d9a,3950314a,4662ade8,1c5e5605,274582d5) +,S(1fa8be0f,476c4b67,697c7541,dd1d8be,a3a0bff3,552948e6,87baf11,afc34432,c6b25084,8038461e,32961d20,181c7187,fe79df6b,8f5c5e54,96ddb5ab,80788d33) +,S(281b43c0,d3738989,a817d313,755c5f0f,f336a4d5,7e8d0ec9,b29fb425,c1f90e56,26b5070e,ba1059c9,b73e3db3,1227a6a7,68683044,7f823689,921a9bbc,bc9f4a9c) +,S(d64e69e9,54e81ec4,7446327f,55e5a82d,3b83eb46,2a92af12,f0b2694,c88f4052,aa7ed55f,284c3ca2,9be75565,f66ea54a,27a8f00d,afaff0d5,8f394797,3dc8622a) +,S(f4cdbaee,d4b01db1,f0b5b0c9,d6178235,483fb58c,5421ba54,17bbcd4f,e4e7b028,66d590eb,29d69904,deb9f48c,5a250089,b2b92447,8ea91302,1ddbab19,6c63b47) +,S(8ff94c4a,6c46e334,feca809,79d21a0,761fc1cd,1de76f4c,7243ff0a,93c9dca5,123ddc33,5f3c68e3,29f42d4f,187fdcc5,77207134,a8bb777c,2ab08dae,f149abf7) +,S(c7869b4,6e34186b,7e87c0e6,23b64fb0,efed70c4,f2af5e70,5c33ecd1,27cf267a,66295439,36620898,2f17d95d,7da2bbd7,29aefa4,69005a59,629720a7,5c11f48a) +,S(e0ea76c6,ad5dc87,bd26ba9e,25b5041b,9836f72,6eec0142,351b2431,6cce1a4,8bd724e6,632049ab,88aa620a,78922b65,6a3a4417,c8af7dbc,5a03d4b8,d4eff928) +,S(2fa63ac7,3e5f8982,36419f1f,4883f52c,e8e357d2,4b4aa7bf,c6aa7eb1,29e30159,57e1601c,d6323fa8,f5a5b314,6b5e5c44,7251db28,6f79d51,7d0b038e,b8d8c3fd) +,S(74ed4038,d4c50930,22e783fc,1bb7a671,49d00877,b202012f,6aa6d32d,c73026a1,5b74f70e,65d009e8,8cc618e4,9f7bfda6,58234f80,38e9835e,80e6fd42,6b28476f) +,S(71d6aca6,e38713dc,6ded1f93,4fdf20fa,16ce75dc,dc405148,eaefd2d8,f0025f97,b4314533,7d48dfc8,278c6c4f,b19f69d2,72ffd4d,a22dabae,dd3e60a,7067e302) +,S(28fb47f1,6e91bc9f,9a2d5720,f40297ae,ee617ec6,897044ac,8a174acc,5bed5292,d04b6961,d72472be,4fcdb605,9943c1b4,ef8e7aed,2ba7859e,bdb84a4,f8b498f7) +,S(68fcd5f5,c8655b5f,5d2fca79,59a7b32f,828c5a5d,e262f6f8,94270ee2,1f47a37a,57480650,33627166,c372bc4e,7a710275,7aa1ad4e,5460dfb6,d3d27f32,778d74ab) +,S(c7617ad2,f423abc4,7ed7f8a8,a7a6002d,17c9744d,1ac6be97,49110685,95aa36da,d9904b67,fba96cad,cbe7a9db,833c614a,69e330fc,a06ca2e8,d597f657,b7121d9d) +,S(a7ef4e9d,2396fe16,c0e78b95,5259a9d1,474fdc21,8b24e8c8,df566192,a6487cdd,d6782604,91c6be04,98c3f7e6,86f22f37,23c1e4dd,4f7655c1,f40509ef,5af67f28) +,S(f3be7846,7ff03676,4ace420f,4091bb2e,71856d18,9e24890,eab6b436,771e2578,f3027657,45cbf3e5,67a6966f,6b27ffc1,dc58f3a,6811f309,434662bb,636dbc5) +,S(5c947f95,5bd9ce29,5214c30,3ebf4f35,6c8d9e2a,4e173470,94d3f755,36f0259c,b6b7b775,3e7552a3,d2dfdf49,8578a24d,90a81d8d,68ef39c4,68fb5ca7,b75e76cc) +,S(236fd960,c3b1735e,279b8702,8c25a074,2c54c189,d1040c13,4e4cf40b,bd8b2c68,9ab59bf7,c0bac18d,d0d9360e,b79a76cd,b44bacbe,b425d181,873ac390,59bbc279) +,S(c92c9f26,17cce2f7,659d0243,8b9d8932,c1a9e9ff,ca8b0d99,cd7613b3,b1947b31,abdea94c,1a5e64eb,65e70769,51ace2b2,e4804ddf,1539d50b,725fe09b,52357a51) +,S(986087c9,142c608c,33783a12,4d22c316,733c2ae8,bc1fbd2,8bd1a142,6da94fc0,14925bf5,fd76b51d,6be82c65,4562cdf,8f5baddc,eb26c68d,3fa6113f,ab42a1cd) +,S(465a1f74,f4f6baad,7c644e21,f35650b6,22424e93,83b421bf,91478621,a48a1d43,26da71e4,179430bd,ee6698d5,7db01553,d41c147b,83247157,9f2fe923,c788cb48) +,S(dd7658cd,f28117c4,4ff3c88b,d0b46adb,c7aa2ed9,1590ca00,785cee6f,5c9796b4,32317c0d,1e10e997,a74935a,8e45d27f,9a9b8ac0,f77dcf37,c1c7b340,cfcc43be) +,S(55bd2abf,a803c49e,b4548b17,725f52fc,6222af8b,dd9aed09,715ceb87,57c72033,34ad33b3,9d7344b3,abfc603b,8dcf2a54,96b991b8,41564e35,53adfc85,3d3ebf43) +,S(77be5c06,d10c226c,8c9616d3,15b1e1c,44006876,4189fc36,db0c88a5,ec12fcde,ccf2cbca,5c474949,88f27ae1,b0361b9c,20e8b55e,d965f7f6,ec8fd9e0,429ba01b) +,S(fab72486,3eb6f261,f0460b19,bea7dbdd,80b890ee,d4bb5618,30db6af2,f52ab21c,914f03a,408a2e2e,aa9174ed,99d80e68,b67f6afa,fa9da5c1,5d22f74c,8876d0b0) +,S(232a2039,fafe8b86,50a671f8,de78314a,510db65d,5cf105a1,9db8082,2a0b2f66,14ca7082,510bc1e3,533b9f6e,e216ec13,3be3a6e2,64d2e218,d95f3ec2,ad78576a) +,S(b3482839,612a4ff7,a0584752,68f13e69,deee9fa2,894a8cfc,64e39054,1b7f58e7,722d02ed,df30025b,eb4e9fa,f7c58de1,653b8224,66b1193a,3f2fb71d,5d26ae44) +,S(d3873a57,b0a7587,cab10871,a9322712,cf6fd84a,226dd7b2,85823996,5a353210,3b7e4984,59c7e706,cdff95b1,c55e3351,f1f45d0c,c9fc11d6,60e5e27f,5160f186) +,S(8828788c,eeebb2b7,71d289a7,147c0a7a,26a049c3,26dcb281,cc9b2dba,162c20ad,e428a195,87425f22,3d798922,b4971c26,5da2fa2d,de4a364c,c8c65f48,c07b71a7) +,S(79fee531,26d0c00d,74986c18,993fa174,52f8dbb4,ea75680a,37f0b3f4,ea7e537d,fde50071,3143f994,b4d7b4a1,43ab3abd,525cebbe,93d5b5a4,560017a8,802cb5b6) +,S(f44f39f0,5a9f5f79,5f0f3a8c,e03ab50b,3672429c,bf699cba,ac1e58a8,66814e91,b95e45d1,e4de1300,950a27af,bab28bba,ff75a246,46ac70e3,fc09da30,d59a1dd4) +,S(1138e209,baf9c9b7,b89d7d78,832cf7be,da45afbf,3c2fa148,50426ec2,80aa9abb,15c28d6a,3965b2af,ea28520,7e67f2eb,ac7d5917,9672f88,3727e499,f06a0d6e) +,S(29d3e942,1b98d78c,60e4685a,aa503130,dcd3d3f1,5afc2620,472b83f9,34912c1e,90a514f8,49680969,215d46b6,db7c53b9,411c8c67,c88bace1,a6d45ca7,d2bf5825) +,S(a8a36a94,5fdd33e0,4f0c18d7,cd2d4709,d6efeb88,a53fa0c7,e90969c0,84ff3eb8,1dd7f905,edbfcd70,26aedbe,1cee1cae,23db1fcd,479f02a9,bb596af5,f56ab564) +,S(5a048ece,b3fa944f,90eab4f0,c3e7a06c,3c35f2ca,81263fd5,3670c212,6a981eff,124f1bae,b70fed65,d53caf7b,5e88077c,8e330d05,692199b2,4b3d6d4b,b7c886ff) +,S(32070282,c5ebc2f,665ee579,c645fac4,fd1eb4ec,d7297158,3dc81288,e932b8ba,8f69662d,d68407e,dafb11ee,8842707,c17eda9a,803cbd55,b86dadf2,85bdaa17) +,S(7c22865b,fb04d3f1,bb988a7b,80a49fe,c7810593,27a19786,db77a47e,57afe787,a02eb26e,30f599d7,d5599734,439f19cb,d0830b72,60e70d53,97f06e1,d036bd3b) +,S(a0ba4c13,30ad8252,c06c8269,a3dcc365,fd842e5a,aaf33a4,22de13cb,b9385cc,58ecab13,5cfdbbf7,f3b6d2ce,277b9e84,940fdb14,47568960,c13290e5,fe239bc8) +,S(42ae6042,c8a2ba5d,c8fe47a4,12e2c0cf,7be448,70e67819,4e31ec23,44f76309,72ad69ac,7ba38bf2,2210a6e7,53c64467,36ea3a23,cbc96c3c,e19f209b,dea1542e) +,S(8f3ae8b6,45507a2e,3ea5d82f,47020739,d8f35f0c,8fc11e7c,6e802d5b,87b2a19,61bb8e35,3028ed54,1b83420e,fb9b1473,60425927,d3f9b6a5,d1d2b80,ee5b4cfe) +,S(3a84ba4b,1e151920,a0e4fb4f,30953e6c,a7ba1e12,62ae44c0,d91b437,b05df32f,b20f6579,43525f14,7b23abe9,c90e1d0f,32c44eeb,cddc6ce7,d3cbad9e,7d3e20c0) +,S(6481fe6c,b04a503,3ecc102b,de462e7d,7b87d181,2bc145b6,2d25fd88,e7316210,bcc1b4ab,f5f32ad0,9176538b,808c9187,d4e88b0e,aef31075,b26e5c27,8f64560d) +,S(5340174,722c583f,af9cd365,1f73b33f,8e4bd1ca,cac0af4d,1ff13064,d551a094,e4902135,448a616d,e435180,f85d0a95,d9e4655b,aebf8a41,a3bbe221,1a66a8e) +,S(c0693eae,a5825c4d,6c24e08b,d57bc32d,6c9ee2a7,90dcb49b,b350f852,4e2867cc,da20fb4b,7627411e,5c6c601,bcb8fb55,f4f6178a,efe0ca04,62c85d86,33b9a05e) +,S(c51d0f73,72fd0502,d17f9200,ca189821,e63e581a,8356735c,a91b6e93,3cfa0d9d,8d10e6b2,7ed7edd,2cfff134,54eb979b,a2797a7d,3c6fb413,b3bad4c2,2e352655) +,S(16811856,4d2d99ae,2daf79f8,58b52ad3,3666008e,d9d2c59d,be3160df,bec3290c,2bebf1a1,45617848,e81dbac3,4522cd0b,3e9cc84a,3c08602d,1adf77ba,292e7460) +,S(7ae94933,e1438525,b2ce1622,5654aa6f,b15999a,57835a09,20a49748,7c0afeb5,91912e37,830a645a,138282a5,1e3331bd,a13b87b6,f443f901,95a2f4f5,bd9b95f5) +,S(e7792d97,d02b76ab,2414c5f6,c2d1bf0a,c27709b0,55b2c36b,179599a1,3019d4ac,9f4d9689,5fceb179,b98c75a0,d5d56cc1,dd274614,a2816e8d,16fb98e0,ed3f2b52) +,S(2ffb9d4,946fd63f,24cff64f,4ac79450,3d97d706,eea6c4f7,69d9e34d,3247bde1,66b1c74,34881531,2bd6907a,6e3608ea,cff18832,5576fa9f,f32257b7,eb81014f) +,S(4544ba32,f90ceeb1,1412aafa,b4ae7351,aeb6f4ba,12e00ea3,c165c8b1,ecbb2fbe,62fbd7b4,c2a5cee8,bfb9ede9,b02dbbfc,2bba538b,834797b3,948887cb,9f8f6736) +,S(250b01b9,25d9ffa2,75eb156d,d8c67b5e,5d981ce7,8824d37a,1b09e3e6,7918980f,ba1d924a,32f0da86,e532bcbe,6766259f,eb185161,4042c0ff,261eb81d,3e09c481) +,S(9cf30e54,1f2a5fdc,73046807,32e962ee,62e0b813,901e30f5,ecbe1fee,abeb4d2,7cb246cd,1281b77b,19601d14,baa8ff62,848259eb,6567c741,c6bd54a3,b5510723) +,S(edc9e8b1,3c61a1e0,8f93be12,495084ed,b5a90eca,4f11dc03,cd217b1a,56285a2c,66c2fd21,7e8fac7,4fd43b1b,58c80661,b0e8df85,a2fddfda,5e9f99fe,621e1f3d) +,S(dd94295f,8388a498,2aaa4164,927b81ba,cae9d002,b3ddb6b6,97082c70,f1e2c66e,838c060c,d409c1ea,9bcd9e8c,b1fac83f,3b08c2b2,482d8f4b,fd3ebc18,8d6706b) +#endif +#if WINDOW_G > 12 +,S(7e068e04,dfc0be48,e5c0d3b3,5bfc734e,96e96ddd,d0ac4876,92f74535,685ab7e,df2cd146,90d225c8,d04052e6,93f14bf,69351e08,79883646,2c88401e,4ec70d0a) +,S(73a9bfcf,d10aac9b,46e659f,76c439a0,b7c2a073,7dec217a,21f43f39,949a5052,73b91529,3ea7b052,682062c,8f86cbf,bf379df6,91a9cec2,4a1424a9,b3be10dd) +,S(efddff84,c8cc754,e6e34678,d85809bc,55cc224b,f69be05a,daa847ec,d408c55b,65dd8f41,8264aab2,efe6ed7e,c45b4ac,8aac218a,3b6713fc,1736dd6d,c2f188d5) +,S(46a94585,7118384d,8d23d6df,a4386dd9,dc264f5b,171a7585,7565688e,bfd73f4b,3de5af7e,a298c18f,4dbf16cb,38e7f617,1e684ee8,e8df2a6d,256c011a,65aaf35c) +,S(6890edb2,7ce3c265,d4afa17b,be160a94,45dd0c8c,9ad6d93b,910ea47f,3821cd3f,60f47c5b,10ef5494,cd8810a7,ca8802ab,7c24beea,eb67b852,dd22040f,77cbd1ab) +,S(8cc9eb6,340b886a,81ec4b32,87a251c1,e33e68c2,1f55688d,952b44b4,2a05f5ae,9b176b0d,90e38290,8911981a,3bc475b9,f0323870,150c9c95,5078bf02,307fb6eb) +,S(2b062f5a,da48de0b,58001cca,e96cde15,227875e0,26c94e0b,fd1fe2a,495b0475,537f1c68,3d5170c5,8097bad,4bf17276,da9de994,8eff6805,48b35390,2f1eab0d) +,S(dd55b91a,84b3d53f,4332ff7f,224e9231,cd358bdf,27f30082,52d7a8be,bb7240f9,e6f1a08,a40b6530,ed737609,4deef969,774d2173,a3ac158b,ff681908,192a5c94) +,S(ac5127e0,40b1a979,46c0cdb1,c782ee2c,8986fd80,d7151e75,16fc964a,f2c59c70,849e2249,323d0539,dda0a82e,1764593f,8afbb097,880af8e2,4765ea01,b7ae5db9) +,S(df2f2eda,f0b6ce9a,3784e9ce,1e1ddae7,9d136423,153174bf,f72212c1,b5311123,b9d98f8e,bd78bc20,316da64f,46644026,fde6ab44,162027be,dbac75f6,e86d46a5) +,S(fd83b387,d630c176,23b85e21,62113610,97bdc5f4,3fb08027,73ff93d7,a373e5f9,9a962a7d,375f35a5,9d7503d4,c0fddc9,115805bc,38438837,d3c670b6,ab6cd2ee) +,S(d8fbdfc1,155ec8ac,8bead443,ba3feaa8,d565ca1e,4206cc95,5feb8e1,32cac4df,f9453c0f,ccb99cb4,739258ed,febf7642,7fb1fcd6,1f963abc,9cb9a5ea,751f73ac) +,S(9fc9749a,20a3e8c0,1b309389,16aaf3d6,85f00872,b82350dd,c89110c0,dfbf86d6,a2f679a7,6c92ac59,5773bca7,8f0f18,75c85cba,e75a6379,1094a799,863e19df) +,S(29e0e346,71a91ce9,bdabcf25,2e2196bb,65b81092,d3728f62,b58c815f,2f476a3f,2f440c61,b82e0ae4,798a35fb,9c66b261,1ce5ad0a,ab42f9d4,174bd698,d4d0c0e6) +,S(e4068a15,398955a0,f27e6f92,9cc3dfb8,7fbee70b,a86ee78f,8736b519,ae102d7,a3f2f2ad,550f9cb6,aed99943,84a9a350,16b91143,747d4e7,7d69e698,8f165086) +,S(51b45e10,bb1bd989,8bb156c8,a4c81978,10f16364,d3d55092,48a42028,726c9f2c,e30719d0,4225de63,281ac479,70010cc0,8a1f1d51,48c57f6b,b478c95b,e3e141a2) +,S(14cd5d29,7b8ab6b5,e92ec2e6,6c63b3d,64dc492f,d5a0c5ac,f6fcbfa5,aaa0b83e,5bf307d7,7cdcc866,349ad1fa,fb1c7d8d,5be19270,2a46b327,9b72bd77,e3666805) +,S(a5a8a711,49d6d146,c32254ca,e9c18288,45e9f2df,419ed68f,8c3cddb5,d22c4da6,9f47d887,7bc3d345,af4ae693,35639bf0,b003f481,7833d2d5,49c0bbad,3cbf6c2e) +,S(359328d2,4baa4232,d75b13dd,d146624d,bda494e5,2cc778f9,99a4c0c4,1f9372cb,d31556b5,71df399e,99084afe,c8f680b,b6695d7d,648f7050,a7881acf,241af6d8) +,S(c9eb81ca,4f2a5a2c,17268a12,d901edb0,c8fdacc1,d26c5e8,91af95bd,e673e7fd,6d4a512f,c974fe9a,711ae19c,d9bfbd6b,5acb73e5,355608df,76ed2942,488adb66) +,S(e26631f8,16f3b308,ac4c9f90,eb6102e2,48e55730,24f41f38,6ccde5e6,c2ca8e2c,16e0b2a8,823aecd0,165e2f10,20518253,96cfb814,bd5a248,58a4615f,eb9306bd) +,S(f76e9af3,65c0e7e5,7807b24,269c4732,677e5af9,a3b0a965,8db8355f,f99110ba,80cbf439,d26f164e,bdaf2542,385f9d65,9d174c62,96ada102,8a0cb013,bd2a9407) +,S(dcc8145b,af891483,295d6ab6,9a88fce0,bc333d54,841e7421,e65f6270,852c5dd9,cedb3770,a620e7a9,b40d6cd1,60363bb0,296155cd,80d89480,ccac619a,f31e2a19) +,S(7645e13a,6a1c4d0f,a56a199e,cae93018,7660bc40,41edb847,ed33fad3,c603e4fd,7c8ea51b,7990e5d5,125eccbb,5da890d2,bcfc5353,b22c42ee,1864c22c,be91e713) +,S(ba26886e,d74cbcef,afe7210d,51c1b6bd,4658225d,45e20fb4,4222b318,9e2f3f25,fd885db2,23ddadee,9e65fa64,abba326d,e0b89627,7359e893,bdf50db8,a2b3409d) +,S(68b500e1,31005b1d,901bda65,4a525e80,fc6578d,5e792c92,299d21a5,19050fe1,71ef7d7a,b3544a94,f3dac8e8,77da5468,8df9b127,83e02022,7e05d5f,6b12f96b) +,S(2ccca7e2,613fa83c,27ff851f,12c6fa07,5b19f7c9,940a5064,b84ea75a,da7996ff,5ab70a22,22dd1ad0,d0db2d2f,c59390b,cf37af8f,bed4570,3c6ae0f3,27d7707f) +,S(6d797d2d,6a56a45a,1b5af718,3cb6dca4,383ad9c0,4d5cf3c1,827f4da6,f7179f14,aae34e5,d203d18d,99e84bee,7d6f5a8b,b80e541e,15a3aea6,7b162551,e80edf3f) +,S(aa6997c4,37be76b1,9553751a,d96a53e4,9a565a58,55f67b5,11605996,e98ee327,6034a421,9cdb40e0,9698a15b,2e2f5f1b,6532e277,a1f4f4cb,3cc0c33c,c684835) +,S(56c40fbf,fb8e1d70,a345d53a,7b0f897e,1e62484,dc01adea,d010c5be,ba2a0f48,e9d06789,78b9290,27ba0e09,173d8ca9,676a4a78,7e299f4c,458cb6aa,46f0bd01) +,S(db6ff6a8,3963ed7b,dc262be0,8b52c3dd,b6e1e237,2a535073,1d2903d5,17918d89,a40112fa,f30fd44,b42f6b18,c144ca0f,e248d65,d757bdc,162b7118,7d951769) +,S(8df55701,a46f63e2,338e730d,4a543013,dcdd1173,754e5de4,151ca180,63402c6d,64cf9c9a,64b63ff0,1396ddaf,b48bbf62,b3e69665,bc89ea93,b9dd12dd,57a1c3df) +,S(9d10bc2c,51018f57,407ae460,e5dd5e45,66485cce,de258af3,7bef48a0,1b0588a1,38ea3c08,b2a4e171,7edebe44,e03dfeb9,726b302e,aea0eac2,fcbc9389,84922c04) +,S(13bbc875,cc07a787,2ca7a706,8201606e,560257b,fce7e66,2e4b9807,37640367,b4cd971a,47c82a66,d8ca19ac,baaf1b1e,d2ea3daf,d6f54769,7fe474b1,c0c2c708) +,S(8f26dc37,f617b174,dc947630,d0da6dc9,1857d9a3,13c92b1e,24ec9cc9,5ea9c3e1,3848a303,1d96bf27,4e423877,6591ac44,f887f2fc,1553375b,d5cf76e0,e73f15ef) +,S(2e1e543d,f290916f,5e55236f,660dbe13,a23e0d9b,11065041,ad3a579a,4c7b5f21,885a4527,626e05da,c10cd9f3,218434b7,947bc083,28fe2d28,ff10ad2f,b5473846) +,S(c83c2ca3,e0509ea8,bb876936,e3eb69b5,8bed8f50,e8c7b85a,1238082c,ee3f3109,2b9602a9,bc808de2,b0b0da10,d09da554,74b75e75,5301cc0e,3b07c331,329cd5ed) +,S(8c7903b4,e2c114e5,3264111a,ee385311,afee8b1c,90606700,578d1fab,d3d29607,dd02dad1,964df94d,1eebea9,a2a343e8,b488c401,88299b25,28d47376,f1025731) +,S(48263c54,dd7575cc,b30adfc6,c1c1eb85,b5185786,654c89bd,a38a681d,a6569cc0,e6f107bd,dacdb528,ed98e49,a25936ea,e223ac5f,55cb7955,ddadfb88,1213167f) +,S(6a7c050a,ea7d1f58,7918644c,63cd5d98,accb7127,c54ee274,95fb2546,16f0d2d3,fad19261,27a2646e,34bf733d,c089b0ca,f80f7383,b4bb1546,28d7256e,d821e232) +,S(e1f0a53f,62fbc202,df9147dc,c31cb09f,ece879a,ccc5a3b,f105a198,7f5c3ea8,3930a10f,b0eea30,c314848,94037780,3968f692,fe2e5d8d,cfe920f1,e5706277) +,S(bc0fb113,cb0fca5b,fd66efca,e8a4c866,da9b6a0a,6d4e613b,48526675,d3182b7b,e11e725e,6993eebb,d2715f69,13ecb148,37892c56,745c601,31ca1c6c,bf090f31) +,S(1fe5a0f4,9c438f48,64bf9ebf,89eae7b7,ee7e6a1,74a134fe,266b0329,cb42f908,db8095ce,f912641c,92b3878b,cfa7b596,694514a,ce9b779b,35ad6109,c675f66c) +,S(5de3fdb4,90167002,fa6e61aa,eabfa53c,ade6ea83,3f3c8f6d,e434320a,aa524cd4,b5cbde88,862ad6ce,b344a1dd,88d1ac29,6d7e9ca3,d5e98535,dc158579,147e08f0) +,S(93b06993,a913dfcf,5eeb0be6,294a645a,b2964f2d,e2196073,8adbfcbc,23da54f,7836782f,856cb744,4187330e,fca3c7e2,9c151ad8,1e8b507c,4d14a14d,492ae0b8) +,S(705740d,27d90741,e685a044,f6b055e0,9c33369b,e3815851,886b7860,8e762f0c,c4a58fbb,738d46c6,9e93193b,529f12ac,b2142b32,1fbb3c55,d3f5dc99,173d956e) +,S(7619a000,fc485526,734a20e1,99530f0a,e5b78767,61040864,34a1a1e1,1d93e296,7f300de1,182f479c,f6fa0afe,a2ceb59,ab26f675,77203201,4f8be86d,46ebed6) +,S(fe20f5a8,ddbb5201,6cd346fc,d281413d,cc0d54b6,384e460d,bec5428a,599ff2fe,5b488ae6,e2604871,afebe551,f9957b0d,338cf47a,b4ecae0b,ae7a92b9,242d879c) +,S(995b9727,ba7e52cf,2dd29e07,73c751f9,70768121,8ab88b84,422e1e3f,42ad11e2,c3c9ddc9,7ee41468,c4ec5e5f,529bd8b8,49c8d585,f905b91f,42af5c6d,2f7fd26e) +,S(cb4f2e4d,2ca94d7c,79e91344,55161921,636d26a0,d84c2a16,e267c242,702b3136,215eb6ee,394940e6,cf00df48,f7e2b8b,1b9b2f71,7a68ee49,bbb879de,803ddb9b) +,S(ca0a2a56,34b49144,bacb1070,7668eb67,4572b69d,5e1a4e6f,c722c256,b9fce397,92079cc9,74ab2fbb,a5098c85,56ada7a7,6e2562a7,bdb5ebf,e958eb82,d3f4841b) +,S(fb82332d,c6c0c0af,d72f27a0,24ef163a,bfadde89,67b4c246,acd6b922,e3af7c7b,1a697119,f21cb690,338beaa5,2e2c4b1b,2b90d399,19ccf0c6,60dc540c,a934c7ee) +,S(d056ee05,d9258def,20e184a4,e2018bd6,d07550a0,63db4673,6afec42a,5c513dd2,af2c1d0,d222e356,67e7cfb6,201ad727,89ab0fc4,d68dc31c,276d998c,bc15bffb) +,S(3fadb222,c6584262,c4046c59,4b778635,c6325712,cd828726,7aea1253,42526f12,da5c8c07,fa6811d3,84ca7e8b,fa1d74b7,d181e0e1,eab86717,58666b7e,c199ae96) +,S(d27ac969,e222e50e,5dd915dd,39d3e453,214b818e,fb67e924,8ab4263b,1d9c4b61,c4857694,baead305,6e6709a3,28403236,9a7c55a,d81e7f6f,9b494a76,cb3a1c7f) +,S(412379b4,8b981ae6,a5fa4324,bffd69ef,99cd3a01,91a1acbc,d9340f01,72c565d4,f24036c9,c7dbe4f0,2ca523e7,ebe6ab57,c755053b,245523ab,ac9d3e87,fcfa280e) +,S(d8234eaa,99374c13,b9a8cc3b,663d00a5,bef7909f,b21243ea,ce9dfaa3,f79336f1,b8cbe8e,c4b465f6,6a3c1593,292babc,1845d8f9,1dc80e5c,b1ff904b,6e755c27) +,S(426f8b35,68c5ff9c,bac0ea34,9d8d3c00,427d323a,3d877bbe,47fbaf2a,5d189009,4e02293d,ce023c7b,9c7a1ba7,27cb82b9,9931f57f,78853bfd,7dc4399c,bd00586d) +,S(f1c706f9,2ee5f2c,2412a7fd,c9ca5c79,8717576e,c780f6cc,fe72760a,4497dfa5,c5e1a1a1,727f55c3,b3978700,51a09b84,9ef75895,d6b9c4d5,9f85cfac,2bb7e740) +,S(84e2e07e,cc1d5987,968d6682,525356b7,5982001e,67598b67,608f1869,36c2c679,41ab1343,8ab5ecdc,cbe75a8a,b7fceba5,2903f4f6,f5b43bb6,28173866,cc28555a) +,S(7935eec2,fe535823,44abb699,3a18cf6a,3d599b0b,ef0f6068,9c689b40,76ad2b54,ce2fc96a,ab978861,b6ced574,fe4f5c85,b77480ad,e3d75b40,6c4cfbd5,53371910) +,S(d542a4a8,319f6d56,b79abbef,9da3a009,3e8c2689,421e3839,27aa6a30,b0dbd9a0,5104a162,65d285ea,8f99f3e9,c1951a06,6badb70c,985877a4,f1979aec,7b8173e1) +,S(bc692619,42289890,4af0157,a038126c,41011b9,26fb232f,d3c27d9a,44ece2be,8e2f10c1,47e2a630,9372e854,3cb8ef77,11e2022e,db25f4f9,847369c7,fe52f3bc) +,S(ebe1b736,bb178c08,deacdd80,b48ab650,ae079a90,95f43e51,f4521bf5,d18d8d03,ad81c659,b1450de,45f78ef4,b2a8126b,782f2061,fc8eebbb,cd0a2ea,cddb7514) +,S(e626b908,49e1853e,4fdf887a,df8f0562,666d094a,9382be7b,de152dec,b9e2774c,90cf55da,a4192a27,caab406,2cfb8758,2dca7342,c59627c3,f513ff9,f4834ea) +,S(fba7a057,ba048792,2313b8b5,ba4514f0,d8f571c,bc7ac0b6,1a987a9c,e4381e67,7d2af7fc,142653ba,bf05133f,958a57eb,7cea5b90,ee5300f7,18cee7ae,d69ec44a) +,S(144cdb95,5b5d5181,5a2e5bdb,57033e67,239735a,456579ea,1e3be689,94c35a54,e6016f89,e896fc59,80150d2b,8135b4b,ed0a108f,8a2eaa83,91987a77,6253f1e6) +,S(538de6e,e7ab1b5e,cd74a2d1,a9599d9f,ad28cd8f,2679eb6,81c25e1f,183c0a24,36c0a747,79611193,5bdbac87,d5b38a05,2482b973,213d0960,1de8404b,14121004) +,S(76914f0f,d28f73ee,20ca3806,263b757c,7876eba7,54bef2e,9d10615a,ebc03794,6de24dca,e16855bf,22355786,1626c62c,59330752,f9f8808e,c3930680,33a12642) +,S(69915e6c,f675f7da,f595f7f9,6c912f29,86bee7bb,aa5800af,27e32baa,9e34e4a7,6094fbc0,2f109855,77b53c91,8dd2da3b,139bc31b,77674d56,df72cf22,2b9513c9) +,S(4ee6c20c,900bd4fd,be942dcf,db91182e,2c37eb35,e4287e5d,859ba847,18ce3015,84ac9769,863d618c,4b738e66,8c293d3d,42e2a9c6,4c47cf75,90ed50f3,2062cd64) +,S(a6813c1a,f57bf8a3,8ece11dc,a4c8c581,aa598211,af9ec6a,d2271796,88a0fa61,6420274d,f4e29631,5b7e2335,e98fb2f1,d415c99b,dc5a00e1,d182e809,5b8edca4) +,S(421003b7,107b2897,24dfc743,275db49e,69d91077,6ee53d6c,fdfe6ab,710fce84,cb955569,7b924395,c31cb149,88bcfea6,a932087,3aa8002a,c218f33c,76f9427f) +,S(9cb19e1,cb8c4fc,4009d362,eacf5f25,5e125298,5b546df8,fc60bdc6,48c8c522,227015d3,2c6ee68b,63e20e70,ed7cff86,8fd286e0,905bf623,1b7e894e,c7d70d12) +,S(c7413596,8193588f,38f412d6,4e2ce0cb,c4a7ac4b,75e33704,36236362,8bb953c2,7bee7fa0,1b7cc4d6,d22dd4c9,ec16b39,5e1d70f2,52778801,9ae75ef4,a908aa6b) +,S(2a8e8a05,321f4926,e8fac1ea,8a97cc64,c2f8e398,e86ecec,9dc2e676,61df22cc,63b86507,4e4fdcaa,acb60c21,c0d3f813,64f0c007,faff7780,9c81fbdb,981fae42) +,S(f3ef2e60,7d403594,48aab014,ea8e2dca,5af1d8c7,c6f66127,3552293e,d497a14d,dfcd5334,214b9f44,bc5d1d96,49d78c15,9e9ce44b,f43dbca9,c637c31d,622cccc9) +,S(6d5c41c8,169c33a5,d1111b36,1b1d6713,a9396424,bbfeb65a,80e40280,4857ead9,4c1f74c4,9f01bc2a,27a91d37,f59bde,3d674220,a521aa4a,6a0c548a,a45e84c8) +,S(5d812a61,c6a986b0,2c5982ce,34fd478d,60822322,47e07c73,488c71f4,4afff85c,37083f7b,16018fc4,25749e16,4c923484,680b1517,8bed41fd,cc8da253,ffa960b8) +,S(e01596ec,b82ff347,c3ba9710,82911855,720177a6,9efa7d5,dc6aa847,7f73093e,a674c832,849884b9,d38da5d0,6a58e4a7,a17acac1,8776577e,5547eb3b,b45b3bdd) +,S(67a5a900,313ff2e,7b32fcae,adcff7f0,ad52b960,ef6b0d0b,8344402c,9980f55,e77efddb,5e8e8865,eb807575,37c41e0c,9fdf928a,eb8b6a03,f41703c9,3c0a4a02) +,S(2b96879c,2e2d0ad8,281c1647,7de62583,53d77db3,57281c21,7df0d7c3,6466b277,dd5d3473,43bac32b,cc72408f,64a9fe7e,7e0dae06,786a7074,3cbbc846,80b62b25) +,S(ab94378d,f08748d7,2df137ae,a3e3e123,639b054b,fb726bad,825e2d9c,310367e9,5785ce24,40037d11,a8331865,c78ddaf5,7f9d769f,f2df11c9,9e3dd018,43a10f03) +,S(70782556,fd6fde3,8c93def6,ca3b6c8d,2f3fd4db,87be4985,fa3aabb0,43e7439f,7913bf65,ecf15020,cc5274b4,8eaf5351,51894bd8,fa236af,8f9b3fb8,178ebec7) +,S(3025d070,138bd507,b338c72c,1024a3f7,6b4d5e80,efcedeb3,e71a018b,77ca3942,3a8a6a0e,175eff95,a94172b5,f2a4ee53,8d503295,63a5b096,f83dd669,eb470ae) +,S(3fe372d0,65e97abb,94069e7b,2a8d01e6,576081a1,93897ac9,901a3d18,b9ab0b6,2efcee92,3154dcc0,377315e4,1d67b5a4,82403552,ce260c2d,4c1020a2,54842e5a) +,S(368c7011,3a9133ee,97ebe8f9,cc06bd7f,c3c373e0,da810164,bce5a30,2af55636,21bd40fa,4870a8e1,6f28b942,bc169712,eb7d70e5,a6faa4a1,35bf86b4,d06162a8) +,S(7df8ffd8,beb45e4e,1e440f23,ad6d713,57682f68,e54fd003,87eeac94,ecd96810,3d9e4cf9,908e5a99,44857d78,94c7ffe7,dc55550d,a07d3c9,ec07667d,982ed0df) +,S(cb6ad939,eb49c7ee,7c216262,49b11276,88269172,504fb8bb,dd2dbf7d,b6f23d4,ec8604db,18f27367,de1319c4,59f8e668,5480ca65,e1789cb3,45e0018e,ea98346d) +,S(5ae526c8,fc319e6,e054e6a7,59d9b205,d8a1e042,e684c53d,39098f28,70f4265a,da1e1281,14c25a90,cff3ef80,d5577c08,a03f4bab,d9e33850,f2488617,d50a9a63) +,S(868d7889,6ddbacc,1bbf2b10,e00456d6,17477767,5b8d3323,a8786ae7,25ff7661,d92d681d,189b0df8,e2be57ba,a9c146f6,46e6ce48,342a0ef2,96fc3093,af22ca1d) +,S(9f2f0b4d,e7b881b6,c4dd1f8a,74106a32,23bd3298,47c325a4,8341d899,d7686b74,6fbbd511,c2974af8,b5729ca6,658562f2,deca285c,b47f16e3,c444fc14,8e440088) +,S(faaf222b,813b0df1,5bf2da98,3ee2eaf6,c522f5eb,e8c08b4f,e6950376,d3fca8a3,bec53e69,2e98dac6,8fb2ae87,44f12abd,47f00e6c,5d6d1469,b2cdb41d,440b472e) +,S(7f5209b9,db4ab9fa,2c2a7ab7,6c5c62f,13c81c80,a4ec4008,fd67d229,a7161475,a13d6cda,f9e8699f,f397d1c7,6f191cd8,a58be40b,9acc4ce4,e69cea0b,4a48d193) +,S(f436156e,80b136f0,8065f395,e2700a14,50c7b492,405a0c04,6834bf4f,12c84c2a,cdd957b0,5684e01b,a760807d,39b007e8,e7aa890b,8882a0e5,9118951b,bd7e60c4) +,S(ef9aa749,5c5b37d8,2060c2bb,3454fa6,88216754,2b24d69f,201f1c31,3cf1d06e,f840da4d,f1d84a8f,ac125750,e4e6cd7c,50003aef,d1f77666,54ccf4ca,f27a4aa9) +,S(7deedc43,e96eb93a,c290809c,25e7936d,6d9e1cc8,a5971d40,b122896f,fb5de05a,e65c0e66,27b9d0e4,e7b349,ccf12fcd,de6683fb,6bc93381,22026b65,26a8e0ce) +,S(5a1bef15,6669795c,47be7495,582f361d,878384f4,f283e15c,e74b3ce,986d6459,ce985a81,1fdb02b2,9e35b97e,1833e380,69b28b81,ddf8cd61,b1179c47,2ccf39ff) +,S(d8123d39,233413c2,b14eeb78,983c6fad,73b8fdcf,84b2383b,fa453558,e525fa8e,ea9d399d,905b7200,46ff78a5,abb3cb56,835e35a3,c958095,ea226947,a633ef73) +,S(62f43dd4,f1f4c310,266a36c3,909afb5f,10d3dfd1,a7a6b5d8,93931334,e4d4bc8,bb7589f1,f83bd647,2e34fe22,53a101f2,75525829,daa2e8ef,89fa1dcb,b590f3ed) +,S(6cf371,d549c045,1415aa75,cf594d4,865f6e44,6f62df4f,cc1cf312,f79d72f7,f8ceb62b,5c979bd2,82a4ce20,682b45a0,2b3dee9d,68ce16a,7581adc5,c9e93af4) +,S(5bd7b780,770be9c3,7c1638dd,8f954086,49aeb371,516bdf3c,509efc5b,47cdd7e7,d46c7848,8a87aaf4,f606b91c,5add0c25,efc12c03,2a28b1e3,2190999,286ba9ff) +,S(c7704954,a319bd4a,e5a08665,3b959ba0,81eecd7f,f15681af,e6bf3db,c36b6a62,373543e8,24784ba8,3f53b9c6,189ccc4b,e508f600,b15c7378,36e3b3ca,516d0fe7) +,S(2b4f27fe,41533a9d,d807da70,7102c1ee,d6e92c8d,9e43958,8fedc6d0,39b19cda,98ba8310,ecd7cb1,c11fadd4,a92f4c30,49ba2180,24015d6b,89e2ad9,f81fb424) +,S(e7d4171,b3dc34d,2600c581,d6931f97,2c920c81,3d7c3db5,4d306c8a,5d4c0e5a,b29581ba,9a825387,99fa97ef,b5a6c4a3,3e75b71,d1cd51f7,5b6144f2,4a9a409a) +,S(6203022c,18f43577,5270043,56a2717f,2face761,e806e84b,2b5660d5,f1c5d52e,18a52f25,5d0a4d75,275fe97,3542b97e,212efd6,aa8864eb,6c80865,136a720d) +,S(bd81c7a2,8c1c80db,a0e327fe,3b0fccca,48987679,791e6630,e81c004,92e43b2b,ca50a84e,a14bbc64,9e0831f0,7f185536,416064ac,e93a8678,db1e2347,803871c0) +,S(9bc43e1a,d3c1390f,cd1385cd,603a6e0d,b875eb4e,6f3a554a,626a9b4,fc4bc29a,857a58bf,9aa54bb5,7acd8b34,b79717b2,64ea39bd,d8f4a22e,6b12e6a6,e0cb2cd4) +,S(3055a68d,194de3c7,9ef0117c,b98bfaa1,5e5bfb71,c656f908,2c8769cc,a7e40f33,183f9ea,dfebe1c4,bf0218cf,b6aba6bc,acbd8c72,a7fe086c,1c9233e4,340d1d10) +,S(4adbf984,ad1fd188,c9271072,43583b80,2cec1231,7d8bbe1b,71079fbb,734b08ac,14527188,9560ceff,3d950766,8e3f2d0b,2192ceb6,f79f5954,7094d5e3,d7ec04e6) +,S(38f72dcc,27e041d9,c7bae397,9cf16d22,83fc6a36,aa074b0c,d00651d1,a56487cc,5238c97c,33a106e4,1370d6f2,c0b6ffc6,49610444,2e51988d,f7160c3a,933dc0bf) +,S(de55bd8a,7bdffde0,a1413828,ac59ff2a,4560647,47c27813,322188c6,655be2d3,477861b0,df5b25f3,75f9d097,97b0afb7,67bf9d51,b996d51c,e65d3bb5,42d9da) +,S(c617bcfd,c47e02b8,918edf98,666fe912,e19340ea,6c567893,8739b89e,5e3bcc66,b90ba117,357e7683,2ae0f4e8,644cfc49,a6e04672,b5b08d47,3b826349,65117072) +,S(4655c196,1b5188c9,4b6402f1,e92b3033,c455f4db,ecadb672,4adab3bb,f1c84758,3ceecc93,a2575f4d,fb202df4,f4bc05ea,714600c0,28389b5c,f2c1c6dd,e6fbc4a0) +,S(fca90f40,dc05e5ad,3693c503,fab43da0,110df431,9c1dc4c9,e5f86e8d,d7726a45,f5822f9b,be3e6604,1af37aeb,19a70a6e,7478edec,68c8e1c3,e6cc86fc,5f5771ca) +,S(3176cc4a,dcb28258,779e88d7,f90d3b3e,a31cbe05,78c7cafb,93ff151b,d27f61e9,3863f2cc,148a0a43,c94fe7bb,afb5ab5b,6a18ce44,56cd06aa,c340c231,42cc0135) +,S(63269f73,d124210a,d070db15,14f82cc5,51d9c19c,d31a54e0,b811e650,ebb2ddc4,bf8ec7dd,8a787a42,4a74114e,5088c387,38246bc,3f6aa188,e300f0db,d85cd0ac) +,S(679a1d32,8d0f53b6,1ae7f544,541326a8,f07e749,34dd2708,dee3ce54,632003d0,83ca1348,8f21eca3,11be341d,5f6ee9a6,c9b3eb55,c9a3485c,349018a,725c350f) +,S(69a27d79,29982c84,d3948568,a54d8933,f7172f9d,e80276fb,846cf399,e0b38b28,f411d207,cb0f0bb8,574b16a1,22f39bd7,69c8b7f5,ac2db4f3,a02163e4,3bb26168) +,S(298d5057,1af5042,cbff2171,6029cef2,abfdabb9,cafebc7f,9dd56c8f,6773ee4d,f4343e71,d271844e,412e62c4,bf6dc36f,4271bda7,9ccfa220,75e3c055,aa97e9e1) +,S(3f2983da,46d1f101,8f8eb984,5bcf3930,e26f66e4,544f63b1,f8f8b979,200c4653,4973a914,c4ad33b1,36d57e6,b326d380,9b2c38bc,79d81b53,b26c5995,9d71db0) +,S(f836fd3e,30ceb88d,942d64b2,a1d2a6f9,54412ea1,ef6a3b13,59faa8bf,7e3538dd,720a3081,53476b5a,709fd29c,158b7720,c8161ee3,6e6aba3,b28e0282,cf7f9367) +,S(dd72eb9b,911e38a2,63bc8ee4,fe991fe9,295ed522,1eef930,b3ae2df2,ef583a,2a0da5a5,688bf7f9,79285d9b,360b53b2,398e86b1,43f10b86,83cb40c9,40c1b2ef) +,S(551e2650,46ab255c,c427bd81,8258b7f3,7cef92a4,496119be,283f033,4968a619,317c33d2,4cd8f35b,9b86a5ec,d1582a6e,e5ca16aa,3c6ea23b,2007a370,e7bc4f30) +,S(6683de92,131de3d0,ecb19a30,47825591,ab28cb61,5c852a90,fbd3ad78,5336c650,49eea58e,7fd95523,f8a9556e,c46fa0e4,b3c3b2c2,8e5d9e4,d636d089,282225f8) +,S(b5b3b1e2,84a6ea65,e0a9b146,e8f895e9,ca99ef3d,31a4bac7,bea49c89,3cf97805,a1720a94,f333e296,f2b91437,e19500be,3cf16cc3,547e9667,ffa4ee88,e5b6fe0d) +,S(a5019773,7c337684,9709a232,9718d463,ccdde43a,55350d10,11a2401f,9bcbf466,9cc069e,ffefc5dd,e8fa5e09,b6b751eb,c51fff8c,fbf3c27e,12efad87,a9d429e2) +,S(9ec3498f,eb2bd861,42841b66,3b1c58b2,e5cb7224,88e2f849,e1236b63,ec1588fb,e00c91a5,e14b97f0,362719bf,2150dfed,e517e585,a807333b,a000652f,c1f5f12) +,S(e10b6cb4,adc13185,750b446b,ab926667,581f97bc,5aaf04b1,f4731abe,f3c5b6b2,53a51213,7db20477,f3a87bba,5b65c01d,d5520b42,f2660ed3,c1f5fdc8,35e2b9c3) +,S(b754a967,e36ea7c7,98c93691,e02b6043,60ace927,13b18d0d,3ff61ce1,dd3ae314,8a9a3963,9aa7ee59,a42f8d5f,bab01e50,d83ee029,933cf59b,e12b82a1,5473d849) +,S(5fefcb61,c10cbf3e,6f8a51e,6bea569d,7999a275,6340ac8d,489183ff,32efa869,d81b3093,cbc4835c,1d88c093,28c20541,dfe49950,9b349207,15bbe1bf,4e881e83) +,S(fe51a3bb,4ac97e1,96009400,b27c8995,f0ed6f0a,b29b9184,70aa442f,27d2d848,8568fce0,a4c39e44,f2b8aaf,59f0b183,d306254f,83cbd6,ec5fd568,c9116a58) +,S(6a3e4629,9fccfedb,c58d5d38,aeb2a420,391df798,e447558d,7b591466,fab7dee3,1bed8fba,7bb15d9d,d42e7b5a,3ab1d9e6,89873eb9,e3161a91,aec3ee9b,22a5e548) +,S(adfdbcb8,3c40d4de,f7d62d97,e16bd32,33db304d,392492ee,7457ffc8,97450c37,7b082bdc,163549ec,2a8b588c,4156ac23,8fde7819,2e1cc195,6be85b87,f4138e0e) +,S(96850fcc,9c202c54,83654c27,2d17011,509ed7dc,6ecc6cb9,f06c3dd5,113bf61,10404432,7f966c49,af0c05da,c7ec18b5,b9fcc455,a01c3b6c,88b8b0,d281aaf7) +,S(2ae21197,8f78ca14,d88151ca,804379a7,1703f514,166f3ac4,f09409b5,5c458bbe,4de74cd9,576035fd,451c7dde,387961ce,2328e327,fa0312c8,6cbc9dc4,19ecf7b1) +,S(edc18742,e1b5c996,2661a332,cd62c426,7e5816e3,c52746cf,b79eac61,1a987e57,80003b3f,c63309bf,3f9d484f,ebabe579,29ba9032,30311bc0,2c021a34,5b4fe5e) +,S(7802aa2a,5fa0f0ae,29a90885,c8b94368,38b35d49,843765aa,1d6a640c,fe43a244,c7f329f,e63239a8,407297e0,416c49bb,7e3dda11,85baa5dd,7f5f7167,9192a803) +,S(fb774579,b124475a,c36ede71,2e3fc5aa,c2173de8,35e72386,bf67bf7f,992335cf,c0e66b51,63c17b7a,e43ebf0e,31a8d641,b6f413a6,b763ac01,cdfcbcc0,47a82c94) +,S(d81a3d8a,43abae9e,32f94881,fe9c1200,695a9c24,a31b6982,51e21b3,fcbc2852,630dd811,e8a8cb6d,7bf51de7,e0a98db5,a693e3a3,c9064dbf,2ccf6bf2,dd12673f) +,S(519fcfd4,97cf068b,804da0c7,e2268cda,7cb2eda0,4be5249f,9bf776b7,c7324cf0,bec6f4cd,198ab3eb,be691646,6e44ab9f,a357c8ec,3bca391d,c20e6ffc,9562fdb9) +,S(cc4ad3e4,8fd66073,5e193853,e0f9b1c2,3e31b284,e2770441,24f9296f,868ef592,88af158d,8583c474,7d5520ac,67b03c75,9b12151e,db25af68,996263ad,d783c27b) +,S(add950ae,6f5186a5,98b40cf9,64ded6ea,c06a57a1,4b85de33,8f709034,78d24117,c59ca4bd,2d69285c,debd6853,a0bec744,111f6dfc,7004d65b,c047bff4,a3affa7d) +,S(dc071b45,43097de7,12bc8173,cb358af,ef0437c6,7c4927dd,d0bc3f6d,bab383e4,793912a9,899b304c,173b2adf,c187dfbf,f28fcaa0,fb11b85f,9e410b40,e95ca8ed) +,S(5dce337e,6db6099d,a9c37da4,a96b7a72,fd97a672,47f6babe,94d79b1a,aec167c7,1b887fba,1f098a43,b6482991,f16ba2a0,eb35bf56,64eb21d5,7549dbd6,4e4377f6) +,S(516eb6ad,8493a662,6d22ead8,e808982,900a83f4,3e6109e5,ba284cf9,e1f5cfcb,ca350ab3,8085b46f,48d8308c,61d3f947,ef6a8511,bb36fe3c,68d30fef,ece05042) +,S(f767c150,3b1f2da1,e5b91211,4e917c87,732b3fb8,8c860a3,35af1c7c,f00e5e75,3ecef8c8,cdbe467b,888f64a2,655ddab5,9ec610e,153cd657,95bb473d,a1aaab54) +,S(f9bbebcf,f792c8c,a7bbc5d8,f177de7a,4185582c,2cc65e75,31f3ac26,73c977f0,290ab4fe,fecb3a26,256f767b,8a19e55f,ac751eaa,acecaf52,b8c99657,49614a85) +,S(c6bfe1fe,be5c8db1,f55bff42,c123df61,6ec3adbc,c9b08e8e,af477fcf,4d47c45f,c595f882,d6d6a2ff,d832eddc,95679890,41c27101,347ea995,c79ad56c,d641792f) +,S(56c2d771,808fb4c8,71dcfe6e,5170bb47,c5559521,8b872425,761829e5,e0d3ce1e,6de72ae6,9e03e626,fdca9188,9e721c61,12ec15af,7163629f,5ee0fc9f,540468ba) +,S(20218b05,ec9f5be5,87a96d8c,3c0cf7d2,da9ecffe,fc604fb5,66a3667,5109d663,2ec1a7c2,c5357e24,1f2ea0aa,7a7321ae,b41bfa3a,88b42e12,e79283bb,ef8f6993) +,S(3a089269,a04ccd9,5bfdb4f3,3494aff3,519035f4,bb3a4f09,e2afcaff,976be4ee,e5680e25,fb0ba1fe,91693757,b3404b32,bbeba22,640da757,ed91ad85,6842d1a2) +,S(8f9f2296,a0cd8b53,db0fd0f2,59860496,dfd3e101,b2975a2e,2856523a,f45b3f07,61c15907,2cacdf31,b229015c,d6290d77,8ab3be0a,57785920,a3fb5722,b5c625b5) +,S(86580be8,695bda97,cd1599b2,6d4b6328,97e2b90,d1ea106c,836f474c,fe88070e,abae68a1,7e19ac58,38a2fe5f,d07dc7ee,2bb220a8,9dba4ac6,166c51ab,b17d7d21) +,S(fb6ac38a,1e69d589,ecc5b4f0,e57aa1e5,eb1f9458,fb187d04,8c72dd29,72b4d762,d601dd16,bec271f3,16f1d3af,2b82b5cb,e5d1806f,b960014,7fb01301,86ac32c1) +,S(7c10606b,c54fea81,bf3aec94,72bb09ce,c5bb7d31,b66e27b4,242b8dbe,7ea5f0b0,12215180,d3d65643,76583987,240b445a,2ea522a,3e0250ab,d14d77db,bdf68f54) +,S(85e6ab94,833593bc,74c7822b,1d9f384a,740a5be6,3b846495,2042b017,2d52a1a6,f5c160d0,68d6f86a,8f651213,8cd28e3e,d6e69fcc,dc75f0f9,81fe5ebe,1fae93a) +,S(7e1e2d3a,99cd1ba0,51b74ea0,e5471f50,5e626aec,b880ca27,f02113ad,ff51cfe5,413ec82e,e9d4fe37,8c232229,136f1ade,c1eb96ce,c0062997,81f4b009,9dad89bc) +,S(589640ad,813735f2,ed7a08dd,6931c61d,6a9490ac,729c2bd2,928ebd01,e87aaacd,89d6b10b,8a89fb4b,3679fc33,96c4cd5,7a1e909b,e343ee15,c1a02719,20485429) +,S(7080cf4f,f3465ce8,fdcdb0ef,3741c19d,91fdd7d4,44118c5d,7b7ad040,5e6e6608,7a3f0da9,5cbc0ba0,b5c6d334,f80db1d8,3033489d,34143d34,7dfad89f,8e2441fe) +,S(bb660b4c,2d400269,2dd96bd4,d7737c31,91deb03,6553e61c,7d59a876,26917c55,b494ad13,a7560497,6068403,15e8b86f,f150af11,18dc02fa,f5ea3f40,c0983c24) +,S(73a241ec,7ebf15b2,4408161c,5d8a5c65,3f4f4fb0,8cddae0c,1e2c506d,9f221b27,80534bb4,33a0a56f,78486504,1d480d8f,64bbe192,a2f6f32b,5e1bc175,d463640a) +,S(fdc1ef51,f08bfdbc,7705741e,6a2b58bf,9e45f202,c3d7ba6f,89a15aaa,78b1fe07,7e9d00dc,dc1e4878,647ac05b,55832540,1684f714,755f4e36,880e5a0e,996c0586) +,S(204842cb,a0ce5cc1,3ab44736,ea0e33df,a15ab13a,912687bc,6d6733d3,a33618af,afc92205,a6e991cb,fad18741,818a94f2,9e1804dc,2145ba35,896f92ac,c96bd521) +,S(a03a9c1e,f82c3151,81009567,50486869,a47c4a99,83bad93e,b2bcb60,157ed768,786f9164,fb9c6980,eef3e5ee,d9a43b8b,2158ba2,dcd8663c,a26cf19f,f6090a65) +,S(5e3b6e5f,6cb41784,6355e3ff,7da813cd,fa18bd42,c54565ba,ee19b15b,dbc00ed2,b9c3a553,42bf2284,fc3b8f9f,88d3e4d9,9d6f358a,c5c8acfd,e340036c,42ee603f) +,S(19b0960e,82d1280,663dfbd6,efb2746c,abf76476,1029a54b,154385c,a05dbc70,f8b28bbc,440112a9,45f35645,135d041d,33df5ded,92116f31,2d2664f4,e5504773) +,S(1061e900,7597bafe,74b9b274,ba1a22cc,6f1c2d1d,b6be8d05,9876638,dff3677e,707ac922,dec592ec,44d7b59e,be2518a5,fe2ffff1,4cf4cfa9,8155c781,21444b21) +,S(c9184c11,60fc7d87,5439b567,69a0e501,cc0e221e,3b155f57,9a71cf1,f3030b85,880b69e3,7c04689f,d6dd30f8,75f23899,8e83e594,9fb1ee30,8c43e982,28327805) +,S(a35fb304,4dec52cd,8fc5af94,e6c26ba5,c8fa2364,2622af12,d37559ff,4374cf04,1544f375,692a3584,ac7adcb9,a3422dcf,8b360471,85326840,42dd755c,112242fd) +,S(ba8c03ad,60ffebe8,118efbe8,eb130f6a,1b2c501a,78000a8c,1b204bd1,b90929ca,e95ef729,a3f341e0,faf73211,2f7800ab,65b88d47,ae137722,f11369c6,e3aaafbe) +,S(d2ba5755,842d8a77,97fba189,f49a010a,fe08495f,5e64bba3,361d1b52,8f30ddb9,da3669b1,cad179f,784bc5f0,c3a55d60,549e72c,390b7d47,7c030bfa,53df7957) +,S(3e04eb58,7ec988b2,77b1d2b2,880ccb24,d3de1579,54ac994a,86db9ae,6c8703f2,fa412113,e6dc85d9,eeb1d650,3df96fbc,ff3c6089,cc5c207b,b98cdb4f,e728dd9c) +,S(efe5bb42,4339a49d,3e19aefa,91f466d6,60c9f120,5df91ca1,7a0da3c2,699fe7f6,98c6212f,fb39640f,cea21db2,97cf9fc5,e3576b0a,7cb4408f,f9e3e9d3,245156e9) +,S(a29442e5,a330336d,eefe6591,5c4e0ea7,bca2dc2d,9816c8a3,2bd66a4,baa0908b,a1bf8829,7320e47c,3b774c13,a6fb9e6,dc5e7789,44666311,2db427a9,dea135e6) +,S(454bccba,6f7225f6,a91f632d,1c9218b1,48e877ff,8018d371,4da8aa88,f08bb792,da0ded31,2d532b01,60a1106b,202ea0dd,8157753d,a07e0e3e,918958b7,45ec713c) +,S(3163940,32c39566,cb0631af,a2505404,56573782,e940dfce,d425834c,dcc2dca9,18c561c4,1b15b0d1,a477464c,6f4d668a,67f0895f,a55544dd,8445a8db,cfcc5fc7) +,S(54b5375f,53f07bf2,f15fced,ffc7132d,5240893a,3bce0a92,bc4fc884,49b07703,31be2b3f,a944251,e52922bd,fa2ea218,f5df11c6,d67226a7,b3f163ee,61abdee7) +,S(283ce31b,745d067,2bfb9b6a,694da3cc,de9033c4,639e8328,d2b7ee6,58b3bd,f6a948a4,d452bb56,e3dc24e7,6e81d2c9,dc1c7aa,67aab38f,f9d20044,d8c0245a) +,S(b5e74f53,117ba754,7b12419c,b0494579,48d5f831,624bb3e3,a60167f2,10e99967,5f635754,d635f9aa,a83c22e8,9f383008,3da8331f,4cfd9b5e,10d48280,718dd3e6) +,S(681e5f32,cfa33183,170dc776,fcd51daf,d587c34b,1cd27134,a856713,cbf83080,c587d8b8,d144e4dd,7b4361d9,b7fcf30a,76f646ef,fbe390e3,8f241a54,7279266a) +,S(1fba5eb7,722f289f,2521ec17,d05df56d,2f28b221,5ff8c621,b925a5fd,29f1d0c,df1140d9,97ecfd4d,fa7f287e,fcacb66a,34283b63,5b2bb7d1,524dcbe9,eb11f5ba) +,S(38bff4b0,df378b3c,ed38fc5a,733f1bce,17855b64,cc254f20,31e1300a,6a0d0a77,6d4f065d,f634296e,64c485ee,32537475,f35a5065,e73bfdc2,520dca1c,6606b1be) +,S(707013c3,59a9264b,be4050d5,27b5798f,779df8a0,77cc95ed,6e08f74e,e57de831,b9f379a0,315386c0,657b8dcc,53cd98ae,582313a7,632e4c3f,da9c9157,14ea422) +,S(ad94ed2f,70282484,e490abbb,320905ab,fc5b8c91,9de6535a,73da3f63,45642ef5,9dbe8813,a554e1f3,e98011fe,c6545216,fdf4973,6d026bd6,cb8702c2,aac88457) +,S(47b56de4,e991876a,499ad155,2443785c,fd174f87,58b881f5,4f545584,ff62612e,a140537,5855beb7,7c56117a,5f753777,383d92d2,d4912d9,86bd59a5,7cefdced) +,S(51bce64e,9291a693,1f24643a,f11f2813,f31f624d,cf336af,3cf7b48,15f431e8,8f743d9,a3012247,ee35d28,4120394f,f40c4c69,d75ae13,a063aaba,ed07e552) +,S(76287cfe,b52c5a0f,ce98e56b,49b4ebe0,83b80bee,3bc7447,a0cb9542,e7f7a43f,736b7e56,fa5744bb,d39d064a,50d98b07,e9e3399b,dc5847ff,13e33eb6,e2a7a7bc) +,S(614d739e,ad01010c,3191aaa2,c1b7771a,8dc29bcc,f1c4d55b,181acdc0,df6b8f5e,5ccd4e8f,e8607b76,c8a96c2c,5000464e,5591efdb,aaf07166,4f4db66d,c2f8085) +,S(c38444c8,ee8c35f2,b339404d,90d53ed0,35cd5889,89663808,3e2d33a,5e4e1bc9,8b4408cd,de5452eb,dc222109,287fa9ab,1d2ffc9a,16b93f44,1f4bfaf6,6ccd29f2) +,S(8a9c9649,c6016f35,d819bf02,852bfde6,56a1c197,2dbb6539,2391df7a,99c8f349,b2dcd957,be2c19fa,6c4a6030,a4cb500b,1797aa5a,339181af,dc6e974a,d769a8ed) +,S(a0f5cd1b,e4449709,25d0ea0a,6cd28d75,96292ab4,1d1766bc,ed6b3311,bea04b03,d270b1e9,291b29b0,ce045d92,3e449ce0,c8d7931a,71cf4b8,68af9594,927ff95b) +,S(a78f2336,87675987,7afbdbaf,28e2590,25c64ddc,a9543a64,709d4c11,1f3a9614,1365fac9,a5d245be,e5245b3a,b1f50d19,de34aa9a,439f5e7e,e241f042,32a6de83) +,S(3bfd37e3,ae482c5b,92baa6f5,a413a46b,af6cae30,9ee3fb51,4a9fc3e4,b391769,2d930818,34bbb0dc,66e424a0,7778c9cf,d0219c06,4dc7fd66,bdc554f0,396d1c59) +,S(92cac49a,261d23,e776ea75,7e796d2a,d426f23d,602ece5d,1b41cd71,d13881a2,8c76ec13,8e0f37c8,99a3e587,a8c0c5d8,c7a43ac8,187a35da,c0d8492e,571521c1) +,S(cf6ede0,ea7dc67,cc370894,1493567b,718944de,7a96dd6b,82940214,b56842a,e2b717d4,e939608b,7ad6128a,53dc8c52,fa070d0,f591842c,a76e8d0f,54627cb7) +,S(6204c998,ba512945,26ecb92b,bb06e218,968c8c2d,11e0435e,3dd1bf82,fa91e17a,1690a15f,e78365c9,c8fae21e,f0af2a3f,d1ed18c7,9a607939,d12d8add,94cd0ea4) +,S(a2c4fb48,cc5500e1,35268d13,a6ac2e16,d8ce0707,f2237f12,ef71affd,e4c0aa5d,3809440e,e608c897,cb7e3906,c58123ab,c403f57a,8d59b950,9e5f2d70,3c0cd839) +,S(d8af7fa1,cc303e4b,c5da36a6,d3b2e309,6acc8ec4,d73224f2,b667873d,eb656f60,9fc7f2bd,5a5533c5,dfb39f9,7045b135,5e14d81b,9edeae5d,dd4ccfff,f0c6de0d) +,S(3e9a00ad,b873291a,604e6bbd,b05304bd,3770733e,d1daf90a,864d775d,76dea0e7,deb49457,f6d1c4ef,53524e37,f19a8d77,20a5cb9b,321b4630,51f8eeb4,901ded0) +,S(bef5ae9,30aa620c,9854346a,ac1b2ac9,760ca8d5,ea189368,9de50e5,d3dc3d7f,20d80c42,f7925f59,b0212b9c,7d4041e5,5da98a3,fe373034,c0fdfad6,48dfc48f) +,S(cd4169fb,cd28d507,6c174308,8f39645a,38215e47,888a435d,5922b490,9155f67f,f9e62ca2,1a5564dd,5a65f274,356c1b68,a170dac6,4b5aa5b9,29dc2f26,35e74674) +,S(a4b691ed,34cd2624,fdda2504,797d76cd,4bd37b11,4cf3921d,538b6042,ed5a4c28,c65374b1,6781b4c1,15b0ca54,53e3397e,5c045a77,72c72d12,c336c205,d26af55d) +,S(5e4e916a,4226b788,197cf68f,aa850c0f,c2b3a615,bf9e847d,c9e55dbd,88aa4818,3f3c3ea2,5c7c52e6,5c9991f4,464f4b2f,f3395d05,3eb27280,8d984a31,b798951e) +,S(dd4782cf,f4d69f72,c951b3ad,50a4c601,f743e6ba,2194d05c,a5f474d5,eba74a7c,97a7bb5e,9854ef7c,5e3dd6ae,8628d8c2,5d3a791,d4db281d,6c7c12c8,20977b99) +,S(a1530ad5,4ab405ec,ddb94543,2669c07c,281aff41,13e4af0b,cc080991,c1adce36,f3d25221,2732842e,5dddda78,1e2aa5b1,b18550b6,fdbb968a,77444958,4a63e756) +,S(51924ef7,b438e4f0,614523f,232af64b,e5ee0d32,ad8e5323,4a2d76ca,9e64719e,87c115a8,11f94db5,6736e82b,8b644bfb,fdfe6e55,8ead8176,26858c77,128a8095) +,S(82cfee68,e137d874,107625d4,be20a9d5,6ac9055c,6b97563,a3bd5568,53fada6e,dd49aa46,c4f5c51c,72a804d7,6dee7a72,a363e978,502a5cc0,6ff67987,30733b7a) +,S(a3738876,f7f1ef44,5a1346b,36c7da6,e02b70fd,2cc3bf30,a4efd7e5,5f2e623a,6596f52b,e1ea52b2,be0de46e,5480331a,b1204d36,581b2edf,368d9611,ea04a21a) +,S(ae4ca6f7,aec818d7,2b624fd6,b2ccf24a,8d8382b3,18b0dd7d,d8203658,2980bcbc,6a7ada03,35ad7c57,1e2a29f2,554c8bbb,34815596,1aa995e9,2378c97a,dd8f1ae2) +,S(be33562b,fa9d762f,9b18d198,4dccb9c8,4d6ac894,2d8506b1,400f7dfa,89d12732,b666efb8,77c666a7,35336cc2,14e874a5,c4f5c956,903048fe,473d2e6e,9475d442) +,S(9d7da6d9,815b3db8,5303b288,8a60ff6b,f382891f,5c45ecf,37cb92da,37c74446,46c29073,72ba5be0,e61f6d73,4b413d44,df3d2c0d,89fcc1ac,5402b68d,755b12a8) +,S(39233d31,e513c2bc,c0602849,8bb7b3be,b5981fb,7c99a366,b62a9df4,3b0d4d3f,fc27857c,92e0ea4f,4d8ac3e1,c61fa774,1ec57d4b,a9affc81,f97e384d,b916dfd8) +,S(5be2d788,db90e83b,58d02dd,7b58f41a,547e6f33,a82d84b4,3f7e5143,db7768be,b8cf3a8,6b2dfa33,e71396f2,e84fb6cf,d585ef6b,9a264875,b9049f2f,6fde1026) +,S(3ff59de8,191fa14c,113600c2,5700479e,7c53a0be,3827f5d6,82f7861e,88f162ac,25d5985,6ab0b6e7,beff5f60,c279a11f,8ae4efb,5e79a4df,d815cc32,2dc77ba2) +,S(81dc9c30,ed221920,98ad9475,da00f8d8,b61a18a4,e6305b58,75f75bc1,719a256f,2970745e,5c44cb27,a6f8f9c9,869a25f8,9cccf024,4d40ffc2,ca678d28,f54682a5) +,S(ba3e1e16,579c4099,1576121b,230d4f4a,ea386943,bb7a8d24,f765a3e4,9b70e9da,a1eeb808,653cfa67,8a9d8d9c,7d30e7b1,54eb0de6,55abaabd,90f82236,32c72f4e) +,S(35ffe81,50faaee1,141f52a5,1b7d1e69,fa66d194,3b96f04c,a0589c48,83f854f8,d66a1822,e83f6dd3,fcca09b8,df1105c0,b4ad3163,6070dc9,b7dd08a8,c9366fad) +,S(398ebc22,1435f972,1c214c0a,e38b9817,8b50d7e3,e5724f68,5b950aad,60763a06,c2df549d,eb2eeab,fccd4da7,fc2c8ce9,15551b87,14903011,6825b804,80811f46) +,S(2ba27f33,e7d0a75d,1d18511a,84e5ce1e,9ca89d2a,a44fda0d,6cfa1389,ca89e96,5023684b,832375c3,8f39946c,c91ca114,45c2ac54,fcc12f19,c6bb662b,997cf4a7) +,S(4257063e,7ec51f92,4ecd485,653182eb,2b54973e,f1ff0144,65cd151e,f9e829c2,47351f41,16dd0515,11c9ab35,b69abd64,919f8b5a,812ad5d7,47c5462b,55232c1c) +,S(77e737c1,b5b3ca56,94218582,d2e56519,80da8195,88ee46eb,e3ef172d,9b4063a8,f7cb5c5,e66798ad,37c8d4f1,1cb912e3,651ae45c,4d7b07b5,e0e20c2,89d1587a) +,S(dfcbb64d,71018c1f,bdef98b8,2a4cb72d,ef027d43,47b5e8c4,4a7eec7a,34cdaa4f,dfc0cdbc,c7207588,8af379e8,751c4f09,bc2f4e58,2dca9a92,e06b0c5d,97972a23) +,S(8eb686d0,a7871e8e,32ac5256,746d7189,b39855e2,2a52ce78,ce6962ad,d355ae8a,ea8b3611,fec52837,fd0afe42,4c22c5fb,89b79675,6e8a6a5e,d71e331c,6ccc30da) +,S(d17d8713,ebaf2dd5,316703ff,8c4c20fe,ee56522d,bea7a987,85a96b1d,36cc3e54,ea70b7e8,6d7862ca,9d8a7a19,bf8941d0,e9fdb872,4e46f8b5,6821d85b,ddc10b54) +,S(7d4c77e6,ae050a1c,856d28e9,c14eeeda,249c471f,82cd6cfa,3ec037e2,30b3ba89,c5a07653,f5fbdf93,4b180f39,327d102d,900ad68c,3da1a7bc,ea773fe9,6265fe60) +,S(96381109,451e5e68,6d61d51b,3b250bcc,3721dced,de39e88,f4f50c1b,4d7ebcab,9498f419,b088ca54,7f17642b,dd6f0fe6,9f06514,a7228394,7f15d165,64801b64) +,S(7400b550,54353d73,7b2da8f2,f8f4e953,85f44e83,fda3cd20,8afaf90a,978c2ba7,9933aca3,ce503677,e2129a04,cdb1d5ca,e36bed1d,275048be,6b18aae7,fd909771) +,S(3d7b0c11,fff7bfd2,71ef5963,9f12ebd8,d1de3bc3,93b51be2,a011e4ba,66ff59f,b6397431,7f7ca0e5,ce1eb57d,8a886144,8bddb12f,75469789,b791c4cf,32404b9d) +,S(4944d9ec,7ebf7f14,e6312545,5c8dd996,45d128dd,fde3743c,5cd6f4cf,65c46328,f0655193,13baaec1,329cd408,c9d1f3d3,5c2f49d9,126c9d1f,5bf271bf,2c589996) +,S(9960432b,4764b1d0,f8607d6d,8e08b355,f37b9933,69bacb51,89ce46d2,79bdecf1,304ebb4c,921d2fa,29200ea9,ec214adf,f7e1a9f8,debab865,78fac56b,7160ebd) +,S(313f535b,63585658,fc3409cc,726b5ded,9196cc59,6331681d,9ca84aa3,bb3de4d6,e511a48a,a55fe0eb,e5f23bcf,d01ff4f1,59b049ff,8c999fb3,dd64092f,c56c9716) +,S(85c4586f,8cd36dc0,db9b9006,ef4f74ec,c99478d6,5c011bcb,3ccf034c,548ed7b2,cd6953c0,45c5d6c,dc632592,3f9b0070,144c8c5a,67639f63,a75b4d10,5b434229) +,S(968bc6d2,a7fc359d,1edb668d,b7381eeb,d489b20d,b64d651d,21d706f9,94671af8,fb0ad6a3,723d707c,c1b2f330,4e59517e,de88bcfc,b52f3ce,d0bdb7c,f0725186) +,S(2325aceb,3722e77e,e6cc7221,56ec0e87,26d343cd,cff6a420,e58c563,bf28985d,601a7f53,dd295978,f2a59683,6f3e9eec,19b9c8fd,e81bba5a,21acc8ff,878d39e1) +,S(8c6e76ab,b2313bea,dc0667f9,9aaf32a6,4b1c9335,87c31dff,5407fdd,67acd2e4,27e3b850,d422df3a,c93b19c4,229b390e,3d7bb92e,340daa46,b3f5112d,1e50c29f) +,S(e31fee31,34468d3e,4d6b2c72,8d538a14,352e7a8,8b9837af,9d8d4230,5e36748f,89b096e1,2d1948f8,937974f6,b9a101e2,37f9df3e,280d4139,e419a1b2,6d0309be) +,S(596b586e,849404b4,7c742fdd,7e5a3398,da748ab0,67ae2981,215c17d4,b0d306c6,e96c5cc5,912cc711,5e4e8f05,edadf219,2ac27760,2b2ce791,ff6e18f8,62a0a16b) +,S(200cc167,5cf500cb,a199c3b7,1195270f,d453d5a3,8313f317,71452486,15aa1c02,780aacc8,7e34429c,6445c133,49240371,1905e24e,c17de4b3,e7b79cf5,5320ce61) +,S(7e4d5432,e10e1fcf,79148f8,77a4f247,70f0e96f,81331767,dfb5e9dd,2ad2025f,35f5dbb2,6ee82837,f37f5fd7,d417982d,fa58f0ca,13e3136e,ec0b5251,63aa432a) +,S(c1ed7508,95c97e6e,7a78f800,b6eb10c0,ff21f879,352870e5,776bb7bd,9c0237b7,90723a06,8dc0aa89,9c31e89f,64ffec3d,a38e8095,97209bb1,d8b1418f,eb418fb9) +,S(e5fd4ae8,a53e809f,83d239b2,a15d8dd2,9948ddae,6956d8de,fc7ce730,b2104770,6a4dda9c,1cbb2197,208e8ebd,35f2ddbb,50c7bf5,df4c112a,de02f0de,f71c4fa2) +,S(3ce75f2,4b33bd88,7ab72cdb,42f9ecef,e3534d15,f6733f2c,a766eac1,da51f30d,9eda315b,51ddf6e2,62ce9b5d,828af559,a43eb48c,d3dc9362,13bf04cb,1a838ed7) +,S(98c04c4f,33a81cd4,e498d8ce,77edf598,527fb9a8,8e19dd34,ad8cef3b,8813391c,fd2bcd67,f853f812,f4371c46,30560957,acb4843a,8ff21949,483f0617,ff8bd3a7) +,S(50e9c88,2906cb06,cbce62f8,413ce43d,f3d2dd28,6e4141b1,fc8a079,a87bbf3,43c713b,b05f19cc,685eefb2,ba04474a,479a615a,2f3c8a9c,e1c6243c,d82fa3fb) +,S(5d41ba17,458bde3b,64faa66,3f21b76c,71bf6564,2a73e3a2,eeb8a831,43adf2d1,17effc54,b3082159,2b39e22b,7ab058f,7f64fa7,68763510,87cc445f,57b6cec5) +,S(4e332cbf,2a02593b,6e83cb8e,1d92e076,6b34cc60,646fe3e7,89d38f9d,24d5b077,50fa745c,3ab90300,95b69985,99e391e1,744ad03d,decd1955,c8b2a859,e79e1f95) +,S(1bbf629d,27ee825b,c357455e,43410507,c83cd47c,dddb53f8,34716ebb,35a2dae9,850908c1,e99753f3,4f40070e,c0bd85e5,8fb72f69,601d3709,71ffa894,3de9bb75) +,S(a9149aef,f9dbd62a,ad0cb3f5,debdcb30,23aece9b,dc79db8a,a25f5b01,b5cde650,a7bb4b46,e6db111f,468a16d0,9df686d6,ae3c148c,61d99a79,918f0bf6,b4c327bd) +,S(801009ee,185d642,19de5b40,6b21dacb,b98ffcdd,75f8037f,fc5e1721,fdb72a71,e8216609,57c7ad6c,1dd36f70,645c75f1,38283905,898650f2,daf2e5af,37e26441) +,S(c070e99a,e466f67a,b234584,66f132ec,96c6b639,3900468a,b7368a86,c0ba6770,883fabdf,358d4f56,8a56f77e,3b291fff,be6f8fcf,9c0f0171,a1544905,50769362) +,S(6be89639,cf612761,78f549a9,ed0af9a1,8e028c53,1dff79da,71c5ff1f,54109f4a,777aed7d,dd379131,26a92f38,ff9970c4,ff2dd6f1,6d766e0d,8215fdb3,9604cf14) +,S(d1fd31d4,1ce71e4a,2052e79,6dbb1a87,10094505,2b9d9009,2195afc5,9624ce8c,f357abd3,78a8029d,eaa796d9,1860e5e5,36d5f2aa,ea2bda2e,5b510949,253fded1) +,S(1c85382d,66fef14b,3cde617c,a426996,614c328a,ead99033,7aed469b,8f169d9e,58c5af1c,b236e6a8,4f58702a,b727d9a5,e2406a4d,fdbf9113,a8f895ef,78a71f9) +,S(2d8fa9ed,d5fd67b7,42e5c2d5,2c128ad7,eec32cb7,43cba12e,272edfd9,4f36b5ea,71b15f39,37eb2a09,f9533af4,bc964c32,23145340,f780731f,aa9ad1d,8f2cd37d) +,S(4f512379,d9f6c596,700d0a15,950ddbde,40ceb1c6,87030c95,4c538122,dfdbafb4,54de9b05,f864df5e,ba861980,c7dd8567,4b320afb,e0381674,c7f7c083,4248c05b) +,S(9a5f91ba,48562c21,58e60949,6d43eca3,2c69995c,ed93e834,168d22c,d9e7cd1c,9f88a3ec,c668eca2,e01b1126,6acf9c51,29bfa33e,e12f7638,2d40d2a9,b722b86b) +,S(dda30502,d417fae4,c4ccc6b6,e833b75d,d84d54fe,d58fcf0,6577dd8,52f9f610,fbb88dda,2e74641e,6d45468d,102e2a42,7f4c57a,6c7fab0c,5d4dbfc1,155469a1) +,S(8d2e9e7c,5586141d,848e50cc,631ce5f4,600dfb1,618d65e8,e88da5e3,5b26e117,989c39ec,ffd67c54,d55ab4fd,85c2a556,bb72fabc,f763c9a9,e33a1ed0,251aa86) +,S(726ce076,e6b63d6c,b071cee1,c3d1da27,10c911cd,e3d59bbf,a27a7ca9,641ee995,4e41baa0,c91ff8d3,4d2d01ac,d8ab5d36,6ea5e81,d489595,1c49622e,610af9c1) +,S(debc91fe,183503d3,fbac0dc2,c9e95062,c0d42971,ed2e97aa,27dbacd9,bea43a1a,13593715,a6fece9a,f33b2ab8,d5f26e6,6dfdf3c8,ff688100,d497a333,be2d2f11) +,S(c5394335,77914ab8,e7039e8c,472ff2d7,237c794e,d6b24f41,c585e910,f0fd4b28,2805359b,628a9c4e,7b304112,80aa2a0d,23c26cf6,9a47310d,1fc6fc54,cd26087b) +,S(9a2892fd,33c300b1,802bf1fb,e8a8faec,72b81810,4bee4e1c,c998bc79,a05f29b0,997f123b,c2fa0136,522ebc53,a5ce37cc,5538705d,f5fa8beb,b37f72ff,45186e33) +,S(d4a22cac,f224fbe,7ed7fe42,7e0bf180,1503bbbf,d73de79f,4c558104,b39a351a,8268fe97,30622e09,2a513349,548e346a,23260311,a82e860,341af6b8,3ace752b) +,S(4a4cf3ff,15adbe1d,8d414963,b0709fb9,11d4d2bb,877dc03c,77594fb,9cc11659,57c84583,36f1952a,62441810,ea64ad3,5109a30b,c39ff36f,c2dedd60,d1ced874) +,S(58c0eced,b580d530,98c836cf,42ca2648,e85e0b27,871caf44,1f69bf0c,158e1539,eaf79c49,1e1dbc94,4e63d36f,702cd1aa,92e54a09,fa11ffd7,4121783e,e842467e) +,S(b0fbd0e8,a60c7e89,38a154f3,fe586a33,26132302,7f4e416f,634cc9bf,724892bb,27ba767d,6757f40d,b54fcb50,104998ba,6dd83f93,137c3d07,9a0330c7,82a5d3c3) +,S(a94ae12a,26b0135a,125fecf3,e4ef1844,ee90c2f7,84cb4081,8c16d8c2,d992f0d3,a37447ba,665e7595,c7816a6f,6bba3d66,e046fe36,8877c95,bbc8a760,218e2050) +,S(8cbdb09b,3eb74fae,32b6c484,4f9004dc,c540e240,7305aeeb,9adbe308,8cdcbeb5,2b863a2,91f6efd2,ff07b14c,4e5a169,912df745,1b49e3b8,10e72cf4,34c932fe) +,S(3f8cfac3,b70eebe1,cc6fb89e,d508abd6,ab3131c,40d37afc,f8f39c87,34cdbac8,dbb02111,846ef25d,794b303d,b48964b5,a68b5287,b443d321,f0c493a1,2d58b65e) +,S(b61604e0,cea3e79c,12fe9a4e,1816630b,31fcaf4d,b3ac84b9,547da60,df15b25b,1aaf2bad,9ea0fa5b,56665b41,ba1264a4,317d5388,9018d92c,ea2e9d98,29b86801) +,S(eb0e7410,3c6ab38e,1c26630a,7fbd68b6,fa51bda3,64d1ca3f,7c86ef0,451327d7,dfa05017,57c4d3c1,9541c9c7,d9fb7438,45cdaacc,2ee377d4,4c36817a,e0e82e6d) +,S(636fc503,be51e64c,8dad2812,6762c04b,1fcfdd7e,4b25544f,4bcd0bf6,9556b7ae,57b83b0f,5104149,7f3b6735,a8b7d886,b633c8dd,5052d1e6,9848703a,313f4cd9) +,S(2fcc70ec,4d42235b,c6afc2bd,1d2de19c,5ba9dc65,4ea3e288,c15c7358,e52ab330,6a356018,2bfa1e22,db64cbbf,cfcdb695,35bde8e8,2519d069,39577e65,256a30ce) +,S(115006c3,8d38b8bf,db8969eb,d6bdfa95,83be81e5,bd5bc7d0,1cd10e22,7ea94b54,6043ad02,16eb3fba,9af39e83,f6e87802,3fac023a,73252780,2505a1d4,2080e08a) +,S(17d565a,15ba1c29,60ca2da8,2fe54d01,3756a986,bedc19a5,15b653f2,8db3aaf1,917bb9dd,42040b3e,4b8b05aa,b9d31252,7a633819,33534c35,f274ad7a,9bc7399c) +,S(dcc2489,88501c43,b8598f7,a3e5bca9,d2af8f8a,b482f30e,2374c6d,6b221ef2,a859757d,d5c6ec52,b1f102a6,ef00decd,cd14cab5,99f1eb0a,57864646,4f652e72) +,S(a68b2b9f,4e9430b7,cdd919db,6e808a7f,ae2cf9c3,d43cba03,d833fa8f,351f0b0f,e34b8a32,d3ad0923,8e95614d,92778021,7f45b14d,f2f9cf66,d6525bc5,94786526) +,S(2f954e5a,938e1198,5d2d11e9,ead59539,fe7e2f17,4702d3c2,3190829f,8d0e9462,b2f0d379,fa8b7d40,ba2fecc8,46a393b1,f6aaa6bf,9f89ac61,e55ab1e7,bb16dd5) +,S(223d3d13,6bca94fd,9b3fcae8,6bb2ddeb,3cc33c8d,3ccff556,fa93938c,c27ffe4f,87e19106,e317187c,c256f7dd,83d6219b,27f6cd8a,53bb4ec0,9c74ca58,51512915) +,S(5591d8e8,291161b6,43df3a3e,9b4f495c,b614432b,a0f3aabf,517834ad,9e8f7b2e,2c8d6a35,f6267e52,d9bd454e,bba4719d,30b3fe7e,c40a1416,673ef594,e6d07c2) +,S(eb2cfc4a,d15d1a14,870cbaec,b9e9aefb,4141841e,2e4e6252,c8e93751,45f29a29,78810e08,10bfd992,b7b04c79,c7650150,e62f210d,6d35cb95,5bc67215,7052e5ac) +,S(6112c3f9,9680a818,5e4b1d4c,539cc436,bdcdb47d,2e19f927,d5e3e9,eca3f74b,6e860bdd,723c8bfa,dac8f9d4,1f6ca96,f2579d7c,6a690f35,3b8da52b,98da4403) +,S(892120d8,d552d8b0,c42c23b,9a0f17c3,b9b32914,d7e31579,7b391ded,a7d58b16,e62523ac,b3c778f2,f913d1f6,4bdcc037,cc4a9496,ccf0cedf,32502316,b5cf7941) +,S(4758b456,217ad3be,2315583,963044a5,60ca4a49,168461c5,ecbd1e91,1fc4dc0a,99e4255a,4f30973f,57eec6a,1c30ac1b,bb74987b,3c4e7ca,9604878c,d9d83679) +,S(ab0422a6,9a207a87,97fa0c6f,978479af,a3b95dc7,d962e143,b99e7575,6e5629da,73398d0f,fc9855,ebc280c3,2b8dfced,84af0f70,4994edfa,7a06e2e3,a5823faa) +,S(1980432a,ccb90b14,30d0b4c3,5829374d,852cc7a6,f0a1b20,ee7ad43e,d545d227,96ae3873,bfbc8ceb,2afd1a0e,9b989bd0,69c919f8,f2e51546,7668da5b,9e8b05c5) +,S(4288137f,e2dffb3a,ca761cd7,2abbef3e,93b8a015,743d50cb,b716252e,e0e93f17,c02c333e,36c366a6,fbd855f1,4da07672,71fddb04,59e788de,456086dd,aa238825) +,S(d65fac35,5bc89da,afc4d16,aa73fa4,77e43276,e0db7d3d,52d9281a,d6b6cde2,e6f4c975,a6c5f337,b4500545,603862d3,8e9f07e4,18886b13,5678478,c007383f) +,S(7029b144,e62dd27a,4fe8b54e,1607936e,beb96784,d1b294c8,43e19978,b98f6ca7,8b10ed66,58056c6e,3a2c90c3,855444f0,9a1af347,c73dd14a,a478f2a6,7140a25c) +,S(4f2760eb,df969bdd,e80ea87d,a5da0c19,fa343e4e,44715711,50295b43,cf9183b2,43e2c17b,f3f9ef09,fa01fd39,b8f69b69,15d8625d,4daff425,d4629677,83e28167) +,S(cc996aad,db4196a8,f355f0d2,3b9fa539,b573ce57,f2ee7e52,14372615,c374a5fc,b1c40f87,18782935,c30a9cb6,6be85d11,44284bad,bfff9923,2c09f2dc,a8ef28d) +,S(c7818ad3,f3e3d905,b2c38e39,85eb7091,cd9b3285,3bdac631,3cf4303c,d54ade42,55574c4e,7bbb850b,14763fb0,fc1443cf,3403a5fd,d1f5f937,8007fbaf,94339eee) +,S(6cd03584,6fc48ebf,f4344d1f,3ae5d258,9a45dbc9,e779445e,52a75737,2589c4fd,afa85b7d,b165e371,adf67dda,8e4d1fa9,4d811c92,8d2d4723,a44e8cc8,93416e34) +,S(d652a205,f716b1ae,632b7235,91152314,f5231b92,474dcfd3,bfaebbad,443b2e0a,d2198421,b78240f7,cb82f0d8,5de03d8b,c4646a23,ec166dcb,a458a06e,b93bedcf) +,S(a807d04d,cd844a1d,f99b3e4f,e3400459,81ff0baf,d34e2d73,a6a052f8,dc52fb54,188a78bb,73939835,3bbe5079,ffbbc718,c385c047,97cfb151,af019e9f,a2e2cd9a) +,S(1efd2bbc,a5d6ad48,e93acd07,d6cb02b9,b8c3a95e,9f4cede2,24efdc17,cc9eb2d7,f951ef88,1b98c7e6,357e191a,1bb357f6,2a9d2ae,a8af1a05,63eef3,66745b39) +,S(5bc5e54,d27d3db5,982bcd04,497fe0e3,ea0ff13,7c3bdf66,6ed0b9ac,2395888f,3555bc02,d4f4eb01,661f8b85,7321b36a,5a22d975,2710375,4c1f65f2,82ec3300) +,S(f600a8d,26b08d0d,e6e2ea80,e8ad2f1e,158cca71,15be6f22,1f5b808f,746a3247,23be5a13,4bc3fa5b,7ef75b2,8e8e11ba,76c753dc,6516caa3,cd5b3ab1,8bca3523) +,S(fc7e4e0b,2ab2a7a8,cc5712a8,be590135,f5119bc3,6c73f81a,e492bd26,90ccaf7b,4bd612f4,1f274690,6ea862b8,a6dd8929,e4a682b5,aa835cdd,b31c90ab,381151a6) +,S(51325f3c,fe12d00b,fac67eec,d79b63e5,41641d58,76aa9700,bcd3b3b5,89442655,d6a894ad,7b7ae6e2,db962360,579657ff,982a35e5,91cc3b33,a4437a4b,133ef941) +,S(2db3ac27,1a55f608,f21bd2d5,717f003a,afee9a6d,b8fefa09,5626e4a,c598aec8,c526bf33,a0c01c60,c1cc9fc9,d66609f5,3c662168,b47cfdd6,e0de0c88,9bf9533e) +,S(9080772,93deb01b,5eb05b55,47de4321,35fbd436,3f391be5,1e1d205d,d5fa7dcc,fe961eac,17243337,653d318,b5c62159,64dfef84,d3cc3f23,e034c102,5ed7442d) +,S(32a1ad81,e5a64fc8,2dacc03f,6790cd4f,45557ad,3d3597cc,e2ec37bc,339ed9d6,87abcf68,18010022,7097b63c,a795cec6,79cb55d8,a9076cf3,d1371062,627cb07a) +,S(f7cba8fa,58689c51,a0f1af76,971d17a9,8c5849d,55b396e9,a3771d17,4d9246f9,f4b0aba9,10d5a9ca,eda4d733,35d5fba2,5309a0c2,fc83072c,ac37b9ec,af58ee45) +,S(cda6b104,2da900d9,d65b6b7b,c0579a43,fab75f55,ae7046d5,8ee8af82,6329ea81,70c86c0e,acfd7401,5a1171a0,1e3601e1,a8ee20e2,9ac7c0fc,68d6f1d,cd1771e3) +,S(a261a640,9c5b1ce,9a8f27b0,544ca0bd,a46f3bca,d11b7f2a,c23878f0,f67ee58b,1e26a71d,4c42dae9,b4e9cda8,fd33d725,85da67c3,52594d4,20c6e410,f3fff888) +,S(bc70c967,fd7f842c,c018e885,d1fb6d34,9435aa3c,682f6884,6b394ba6,e9f4db57,a2b99d3a,837e2de0,c40a0784,7865701,3032efc4,87c47e57,18d84e11,f8bd9468) +,S(364152f7,5dc43149,4cbfdba3,ffaf234a,c7a26567,1051e026,9c60389a,7077a9c2,ac3ac7d9,f4ec8543,3038ae4e,7ede71d5,3c8fa601,25bcd8ea,e084c32a,546d265) +,S(52fea4be,d57d5d58,d92f59d8,e4022df9,d82ca42f,a3d89326,cc36dd96,94f3043d,b7e98328,52f98a75,f738f9a3,7a67b39c,5708c608,5b6ab99b,2495428d,8c4feb35) +,S(34fee910,c8bac880,f973a096,a9ac3ffb,9c32ecc3,d2be3ce6,7b8d6822,863e1a4d,e0f01096,9c9dc446,c78db14b,122e260c,2231f6a0,971d08b2,24355620,689c7a17) +,S(6af28f0b,f4c9d2e8,192424ec,31f076f7,f815ab0,f476a4bb,4019b3bd,db49c65b,2c55fd2f,bb663b31,1a9aa346,917f6064,17d1e1dd,bca45d3,f1350feb,6ea45248) +,S(70b6ab66,39e4b41e,644f1b6b,6ac5d36f,a4f0ad81,3baec03b,8bc74f72,4d320e46,ec6409e6,4f4e4fcc,d19ad5f1,96d3cdd,96f7135d,dfcdec95,23780c18,8a913a14) +,S(ede56f11,4ab975ae,adbeff50,ff7dbbe3,614196a,138600bc,15508481,a065724d,9e7fae4c,11f421ed,26d839dc,61b0684b,71906b63,6efdd73c,2dadfc9,5336ecfc) +,S(83c34c3c,840a7310,3d819d74,66648e66,5de54af9,f1683efe,6857c3e4,556df8a4,9c238041,562dd6c0,eecd9771,9ce2eed2,90aa8137,f109840f,d31d70a4,c86cd10) +,S(aa2afc90,89b98,5228cf03,205e87a4,52cbdb45,24d377c6,1020593d,a0c7e200,3443196a,b382ac19,d3d3bc4f,a3161e00,6d812924,fe8a86af,2db5cc27,96be01f4) +,S(e42ec7dc,4310cc8b,9f2956a0,2fbf71fb,e90eb045,881ee800,e3a75730,4155c520,939ef2cf,a52d91cf,e20324bb,e8da54d9,2d000945,58abe7b6,93c2679c,d625336c) +,S(bc0bdd24,937c5200,fd78de47,a16ef9f4,181617ab,267fddd3,4a3c5606,32ec2b21,db04a4c,10b521f7,986e0e1d,192b0870,4a028511,205d7ac9,df6d2993,52b63035) +,S(dc88c9d8,9b43a733,5e310fbb,3f760e29,55c005d5,640df990,6264ebae,adadc8e7,2d6779e4,6f984794,65bfc677,79feb7b7,3fe37b32,cc23d636,25a3c8d4,fc2fc512) +,S(a7ae0d8a,b0c932c6,2ff0cb02,e05d76ef,5ee3dc50,88c57210,f6f9e349,80111c20,d632abc9,d63162c8,98b9dc94,b321de53,ac8dcc45,69233cdd,1d07da1,92e553a2) +,S(4620236e,e7bd6eab,db203af7,57da6e64,d631ac9b,a5f03215,592a5acc,5cbe0e97,5df4244f,69ea1e2a,6cf30cdf,4fae66a2,707851bc,7028d8c8,8fa97690,28627c6e) +,S(804cb84a,3d8bd930,51f50aca,cf932301,5cd35fff,349d8a38,e2bd991f,27d8f671,4b77b812,9ee0f835,96ab2f19,20362128,cdc39552,bbe6d267,bbc9a8e4,70ae8d3f) +,S(6ea5370f,5382b2f2,b801fcbe,ea463912,b4f6fb4d,e207237,8e71dbbd,b91c2ed2,f5b4f909,d8f3ff08,e92a002,f1959ec8,8b513ee2,d37825b1,a8bbe141,90b2d88d) +,S(d8b8de1c,4ff575a6,12bb0852,af61c6b3,1ee56403,b81a1f47,69fc7072,a2e22ba6,1e3c4190,d37abf89,896ad827,55c256e5,f23cbdcb,47b05892,8d538df4,e2468c0e) +,S(66ac1864,4a0bd6e,9c73f3ea,43a00d6c,80d38467,5080a9e,475c8291,edf1b147,2cc60c0f,7db6b776,1503efd,551e1a36,9be98ec6,73dab0bc,a61881cc,4fa1260e) +,S(47194a2c,4ed223e7,7663cf9,38b5a5ca,f2784435,c375d85b,ef3c5367,3f60e942,b0fde11b,5a64dc13,7bf2738c,75027d57,5808a3ce,abdf7604,5f4484c0,d3d9f920) +,S(1141c859,9af2d983,88274742,88dd768c,9fdc1b2a,c5f06290,10bd3cf4,2a4c6186,7a431f47,61ed4613,3317555a,578d0f8,5392a0d2,ba98ec64,d6b508d3,eef0226e) +,S(f905bdd8,e80afe9e,d65da689,bfb8e549,487002d6,16ac651d,4ba300c3,e7496f79,1ec7bf7f,3bfb5045,d461b03b,a7f05067,cd999fc5,f9f4c0fc,a7e25b19,77bfcf72) +,S(ba54b8e4,fba452ee,23c4faad,b14f0af8,232ea62f,ad47a3e5,573f1fac,f15e9e0,af556ae9,efcabbcd,bbd8e48a,82ac80f3,9c96ed0b,11370b8,da1bd4a0,60f5cda8) +,S(59d3ead0,561f6e24,30e87f3c,f361a2b4,1494a042,3a775e9,c08a28b4,a26a80a,9b26f47d,50a92229,c28a278d,427c7306,f5f1ba1c,c2d095d9,ac51e18f,a9bc8) +,S(2a6e5a3f,ab4cc928,d8f2924b,e7e0f3cf,15520a08,eff00f5b,129d9070,ac865d47,55c0350,58727023,86d19196,4609351c,919913de,e93800cb,38b77183,5ca625a5) +,S(898f50d1,c35bee41,88afe91,842cf659,fff1fb1c,5aaebd84,6828b002,a8907502,b2456e80,c97c2ad0,1ae02e49,6b84c02,fc9bd0f1,4a3c5a79,dafb8f8f,62f3267b) +,S(d1854ab8,b49bf0cb,1f9d2304,e9ee3cd3,bda5d9a3,ac04fbf9,422c4671,d6af85a,4e2500f,d8818180,5b16a077,53eddf34,d7bdeb02,17df7fab,d0afebe9,47155c20) +,S(861fb88a,394db6e1,f03cc787,d968ef7e,4a417df4,2856d303,a3edfc66,feaf4680,a5d7e95a,ab8b0b13,23fff11b,638ce02,68f3c38b,dbc018dd,dc6d2362,a135da6) +,S(9544f768,b9fa9dfc,3c155d90,b676cf7b,ea526903,39fc111c,b0ccf62d,813403d6,cec4d92f,cbde624f,851ed21,bbf5154b,28d87603,5e302902,53e99670,806e047f) +,S(f7722192,f80a66be,23cd7b07,89f3a094,311cd40d,3b7149ba,2cb5cca8,d1db68e9,41d0e9f,3243d64e,73e26661,cc851e5,1c11e320,277f7462,d40efe0f,c81b516e) +,S(876b4c65,1f88729b,dbf9927a,89ea91e5,b6bd8e7c,439f6fc1,be9e07ad,698e14ed,ece2cf81,1cfae9dd,cf787b88,f62f2537,7b573084,86ab84e1,6ad31ddc,f96b49da) +,S(706af4e4,62249924,88461427,8917899c,721be8f6,3353b127,b7ecb03c,7b70b10,c972d972,c65d200,e695bd29,813deb74,cdcf0ee0,e612f545,aa6506e9,7e58a5f3) +,S(ce97a218,c9c96262,b5cdde0b,a27e5f4a,4301b75b,f9d17dde,f1495b7d,f3863c9d,e9398e1a,20fd1426,88916410,d7af68f1,c12900b2,72b03f55,c5770aca,2a1ef10) +,S(fb625b9a,92cf831e,886a1f01,c2db3d53,7dae0feb,e9b3d9bc,a8fe6449,d53be895,7f783e74,ba569e04,a29d68f,12cbf223,1fe2a8c2,a651f44c,30d597de,82599a37) +,S(81ffbf69,7a7d2b8b,51b9098a,8833244a,f126c6f3,b42ddbc4,c6b2c5a5,55f4747d,e2c67357,982eefb7,3213d530,3cdaaa7d,90b4d1de,d0fd4d0a,8b002162,f006f33b) +,S(6dfc0f66,8c30ab7c,af16d4d6,309ca2ec,679d6b77,be695ba8,c0f31b55,6a0ed0e4,a41ed2b2,d9a0aa74,3182d7a6,20f441e9,36772438,bfddfd90,5aeff87d,b15a563c) +,S(1c6bf1d1,b953e56a,ba1a9b5b,f63c328,1d5715df,88bcc23f,e77f94c3,3b501b44,c667214d,b4ca1782,19c368b,f7c2ba4a,8f1e74df,91a22d3a,8e336089,e4e4b0ef) +,S(b69112df,5d999f60,5d863231,9144d2f3,5417b9f0,d1e78ba6,b2afd247,fadef93d,2163cf7a,302886e7,70fafeb,8acaddec,464f115c,89422020,9a034c63,558df4ae) +,S(bc038732,ac230f91,7c58b8fc,f9ef9229,9737a2cd,8e01687c,da464bde,4976b6e0,3392601,796373,603e1d6f,a7e23385,7a7ae0d9,df638ab3,7191c046,a25682d2) +,S(96df3295,1047ad4c,6aa4d9ae,e59bb00c,7489c20c,aded01ae,1833ebda,27e32d81,418f6c2d,74ce633c,181189bb,f5d0f066,cbfaa8f1,e6674466,1818c4ef,e2e2034b) +,S(a3c53227,939e40ab,ec6fcefd,eb6193c1,cb6a65fa,2f3501d2,63cd2fa7,6a304979,4468caa5,498ea6f1,92f29ade,37a2f667,f46798,dc600de8,cafa0ed6,dbc967e4) +,S(93fd8207,3dfd6d6d,6b85f1b3,1e172a61,7a0c7d46,b91d5a92,601af0ad,2545eb2b,601beac1,9a8a6a41,1bfca863,6acfebb3,9611559b,20b8a866,88397d47,d563a847) +,S(ba7d3bef,2e2c63f1,f9acef,2468ad8d,a5bc0d9e,b45e4a2b,ee87a0ba,86ca0a9b,ffff9a67,33129e31,10d33ed0,bc5b6bd9,376f29b1,7bbf2e09,7c6efcae,a55114dc) +,S(e0d955c0,2a4f9c35,97597258,2964d7a4,218898fa,97ef3011,1904290e,36157a8,176fdf9e,7d420bb9,a0782f0f,8707789,b28cbc69,d5a6797b,aa2bb985,1c617f0) +,S(16b2c140,8320cb93,112da689,c690d6ab,6cd226fd,e1752dcd,a444750,bff81ac9,2a2face3,dafd3932,f2617488,faa17b6e,5025f792,53c65edd,2abc7790,d98bb281) +,S(2fbb0432,9c823e2f,645d61d9,795a414e,220db4b8,eb4da0c7,fc22bc10,e9f502da,1adf66ef,15eaddfb,abbcda69,c87068ab,cbfe58e,69f58246,a0ab6259,90ebc31d) +,S(649134da,f42d2579,b6522f2f,404d6456,c178f883,8c9ddccc,e132de4e,67208ebf,4385abfc,3c554bc2,78844648,a9aea5a,e7709b51,fe644e8a,4a756c3b,f09355cb) +,S(b95544b1,dcb81f9c,e0601c17,29c7fdef,128d62b0,b8993023,dbcedf8b,d3991cd,f871fadc,ffbade32,d51f2d45,4f0726f,206fe760,93c0ab0f,33cc5383,769dcd2a) +,S(cd403bfc,5034d0c0,a23df5b4,a4b1b096,ace1ea17,288f89f,d063c0ca,5dd668de,c1296131,aa56f46f,49f59760,f3a4bf0e,3fa92e54,a5d8f160,54ee1fd4,26717742) +,S(a4aaf37,d7f8bdc9,90202074,c9a8f56a,1ad78479,95b4d939,4b6ea478,3c04c581,4cb3b6f2,dc02b61c,fd2594f9,40773d73,1a8cb9cb,388af431,9348d3,af16da34) +,S(57102ff8,ebdf048e,85edd3c5,2864578e,97478fc7,e6e7b937,6c37d9f8,abf438c4,c84f1d9b,eaec1962,e79e308c,251b2f31,915aef16,90ab5128,8331d8ee,f8161d4f) +,S(68fe98e9,3c5c5fe1,108c08c5,8fafc701,12424685,c6809774,832b0623,a3c9b6ac,492ac417,fd956b87,ee8078e2,c46f21e3,cb5ea58f,ee871cd4,d6480cf9,c4df273) +,S(d4bbb6,9ef5e23a,f0932cef,2eea4ab,d97baea2,b0893d43,ec08be40,2a4a5e77,5818e60,9c1dae31,f65e223d,f0cd08c5,9e74884c,2a2dc166,607fa4b0,47c7c98c) +,S(e9627957,a8eb8b72,7f0d872f,28acc53d,23a5c53f,763f3b5d,68c7e690,5a83192a,5da92e7d,dc291696,d9466d17,d4ca6cca,cab1057,4f5a08d6,6e59ba87,cd0d984f) +,S(49f21cad,a83bf2eb,7c508ffb,70f9fe84,1cd547f2,df83f207,6dd2382f,1711caf5,1c7d8129,5f834ed8,ac73afc2,132e6eff,2447611a,4fed8114,ca18925f,39f31931) +,S(58282a9,40f61d53,14d1d110,c18713d4,6c34a8cc,5b0ff64d,fd6d0182,aefa792e,7855e155,d3e0f2d6,52370145,7d83d7dd,2a96ee49,3eac091e,677f0a34,105f6ddd) +,S(c9c97a32,4b07027a,7b5db6f1,d70bec7d,dc3a14e7,43d492e5,f5569199,23ca118d,f601f40f,894ddfe1,c2b1e99f,7c2032b9,15d600d9,e2ec41e8,747d74c6,9664b56d) +,S(9e4dc175,8ed67501,86a7bcdd,a11f9273,9bbbe0cc,aa72862b,8d515a21,159e054e,ca11c31f,2bb866a6,be0736aa,19b7e36f,fcf4f4c8,715ebd3b,c9483813,cfc6c0ab) +,S(fd063789,3ae0030b,cd8c1e5e,8cdfbdda,8e5af1f6,268f552f,7a7f0c6b,8aafe2b5,8c09eb0b,68d744a,20468a8e,4326dc01,f4a35480,df1a0435,b2e21d53,dc8e676) +,S(37dfdf3b,6e7a7651,9ba81c3e,c1377580,d85360b5,b466ec77,b3f2b272,fd4af04e,cc3137b2,7b732758,d78f3b07,80129e77,43dcd85,ec941727,ea3b4f8e,d0fb7844) +,S(45ef106a,c8a5e25c,771a2f18,bd2be0c9,a69cb49,de16d8ff,e72a45d4,6c1dbae0,cad6a40d,742e7db7,3f7bd452,e0163490,60e5681b,31918bf4,2ad8b698,220ab158) +,S(258c52f9,88b9ca25,73cde71,472bf58,99648cdb,c1052d14,be02469c,11fdfca4,4491d88b,26ea5c7c,6a66c9e2,1a5b61fd,d60d0b8,8394cffc,359af9ec,29939dfd) +,S(bc92a4a7,727c4e36,3d0cddb9,d36f1d9,d4f8ff67,de881c83,afd51193,a9e65217,76ff6a08,b18b4795,61f1c024,d464e9c0,331c22b4,ba3779d7,9dd13122,63aa5120) +,S(8a19e8c2,58c04834,f11ceccb,c156bbe,23e4e837,fb5ff353,249c12d1,45f27ebd,15fc6c70,bff48ea2,c56caca,2b978fe1,8f50a9cb,85c19f06,5d65e507,e4e92c1a) +,S(e59b82d1,ab90344d,b113c1a7,a39968bf,e6f3b1a8,c2a44572,d9c911ea,55d70eea,91e33d8c,d58c6a1b,e4df0bc0,12eaa76f,6634d699,814b80,cc22afc8,313b91be) +,S(f994ee5f,88244cd6,bc417db7,2f941bea,f3456d2,5dacbeb3,330031b0,7371a7d0,9026f86a,ecc299b3,302bf9c0,4dae48f7,d9c2689f,42707d40,51440a05,ad9c62e2) +,S(776c4c8c,32d1fa50,27b17bc7,9803d121,8000cccd,565d95ff,c1e3a693,7800410f,40ece234,438e7738,6f8201d5,3d3e319,988b64a6,38413803,165f0bad,c8785149) +,S(393675a5,dd13b001,29caea3d,8bf25730,32c1968a,c5e02620,fb83fae5,b5c9b12e,39e6cfc4,793400ce,ed16ff4c,4b0ebcc3,2e5dc773,4e742dc0,3784a69f,a75a8b00) +,S(d7cdd294,22edc7b6,2cdde130,e90be1fc,94dcfdf2,7bf38eaa,2f09fa8c,c3401b1e,dcb9cb28,73cd18b,b74ca141,dc79eb46,728bdd9,8bf14302,db5c7065,354fb184) +,S(bce3f127,2726449e,3f620671,824949d1,9026137a,9885a1b9,9cb67dcf,6e56bc2c,a4240017,ee92dda4,be968f04,ad125ad,1c33c37d,c52a497d,296d5786,e6e76217) +,S(9df098cd,efe9414a,79adaf44,21e35faf,70080137,74399eb9,738dee97,ff5d6e52,6bf9235f,ef36943c,d0f17bb8,6917d97,f04bf4b4,dbef1baf,3b788eba,51abf15d) +,S(9958582e,e561dc4a,9a4839a8,292713a0,5d88ab4,72222522,e8dcc94d,b3d43f1d,e0958a14,b63af23e,86f76cba,2259b37a,850008b3,43b5cdc7,8cb4e88d,68c226a) +,S(3e7fb8ce,7d7b279e,7d292447,c88c048b,dda93379,5233a871,bad933c4,6dfb1f24,4279d08,34108239,2d77a5dd,906ba4be,e36352aa,9385f09d,2296ecad,648806e5) +,S(1cd05450,f7405a11,cec93ee,7826cf58,97611d69,fcb681c7,1ac0a6a3,75e8ed62,85bbc70,bb52b040,d620a3a0,20b9536e,5759d35c,9931936b,39a203b,af34d0f0) +,S(5047776,32145a3d,f6f87bd0,1b81032f,93cf99ca,fb4c5e3,c76adbf7,d7c9b367,7badf59,919c7771,89eb97ce,6c71f418,a0e67b23,884cbf7a,1ed60804,57d1d2c3) +,S(1ea912c9,49b64ba8,309b8d87,ad1498a4,79fd302b,f7f2f0be,636f7a0e,4470e6ea,9b279fdd,b1211de,8414896d,3502ae8d,4acd50e6,cf83ab4d,29086d0,42b7650) +,S(9b3fa0d3,4b00076b,cb4e0b00,95f03c4b,e1ed329b,d2f4c7ac,8c03028f,21a01628,10117a48,b2a58ef5,2e0d5dcb,cec661f,8cef81d5,50efdf41,26e9527c,27d420de) +,S(65fef7b8,1d39dc4,b3ac7f7f,5bad14c3,6200d128,d0257e22,ff678fc0,824c94eb,3021e1ee,680c4fc2,77373b9b,36ef276e,f2dcd6ec,7a02b2fe,3259af09,2708b475) +,S(3e77b23d,af763a55,644c0f2,bc2bef5b,6ef5e1bb,8fdedd46,c5a2917f,7f85f9ac,55b278e9,5bb07879,9c7f0766,a2db2c79,8d4fc785,10fd021b,415b3e4c,2a4f3221) +,S(2ac4dabf,2fec922b,c4615fba,1cd7d352,f69fbf8a,3232f783,96f8c08b,21de2965,2c33c017,76238bcf,2be6018,7f85a518,6d649425,1eff089f,a92f3eac,219f957f) +,S(febc8a20,67da04d0,855feac7,42b2cebb,748be0f1,97e31558,68d54285,4d62c66e,aee39287,3d45e63f,f9a9d583,e105a771,e3db346d,a262bbd1,a554a8d2,65d96083) +,S(a41174b4,a5982751,88c2d10b,d5c5401a,2654202,dc4e38d3,e1c8f689,8606a569,bc6b63b9,9fb5f85e,c6965337,e82b651d,6b589f2f,8d90f67e,3bd087e9,1f732a00) +,S(122196cf,5d10a3af,3bb97fc6,d12f749a,907c194d,3caf2ae9,3a3a464e,5a5de220,ccf46742,b3c1e213,544e2c7c,59423fdd,674697c5,d405b2b9,46fc6e92,9304e533) +,S(77bad5cb,104dcc7,e1bbfaa0,8c867761,9f93ec61,e8e3b73e,799b663c,2e1eadb3,889747b,ad8bdebf,48e1214d,df2522ed,4023fd8c,5ef08fea,411e8609,c6faa3cc) +,S(1e8d4075,8c49ad41,6ad45163,73327e6e,4e3f6c89,695e15d2,f5517ebb,12d4a98b,1d16ccb0,730a619,c9b379a2,ecbc4f83,98d94aa0,d4881cd1,25968160,e3b09f4) +,S(c87a656b,240241dd,487f4974,afb5b535,880ff2ac,f4a028cf,b1869fa5,fbb6ee42,16f25f3a,6fac9538,5ed74412,fa6a790d,34f694a8,b4c99cb7,6ddaff70,be757beb) +,S(96b01407,482c6e88,e9769944,cce16a05,669adf16,e7393b80,71fbd9c2,4b55a4eb,b32be280,590384f0,e08d68de,38688018,82b786e2,1b178ca4,578bfffb,94b50223) +,S(120f68b3,739562e6,81e72fb7,46d08f54,b2afd162,22e1deff,7ebbf884,6dae4af5,7c1eb74f,2b2376f9,477c6729,bd90e14d,2f4da9d,615c8743,dedc1690,300bcc78) +,S(e64871ec,2789b455,8608be2c,f248fee8,49a4411d,285c0989,b65c5dc4,e6acd157,2980b2d1,4999b0b5,5b79ecfd,45ef91fe,f3dbfae5,d02f2145,84376294,58e10a6b) +,S(608b1009,b20d3e2c,25324adf,c73e5c86,43daa1e2,53a8d266,eb43863,aa6798ad,826e5a03,ad5c9638,51181c68,ccf0e663,a021e13c,43efc38b,3b4fe2c8,8d0e13df) +,S(8c978155,8132e45f,60a61435,36f4c1a8,cdc4dc2b,6850b3e5,7c65f841,a1bb152a,ca3b3098,394d81ef,a9083c5,3864f194,1875d63d,9c31b44b,a6ed4137,db7460fc) +,S(353591a,c73b2482,f8d8e731,ce01106f,10072757,68210627,f80c8f8d,9821bf3e,2b7e3d1a,501ab469,ac6306db,2608eab,70ae8981,9f44bdf9,d4f84c7b,41eb6412) +,S(eb2dfd88,ec357372,ece70a67,178fce32,3c387b7d,a9fda978,b05dc430,9cd78857,6f2bb6ed,1f5a5521,c441a8cf,9852372e,3dd7aa7f,ca0a1f63,18c47ef1,a24b88e4) +,S(a41c0ff6,5db1050e,6998f3b0,7eef66dc,abd72ae9,8672c487,b29ff732,992eb279,56fa7b20,5616ff9d,f619d7f8,65210727,bc0786eb,2aacc244,ba951eee,99a99cd4) +,S(8e748b35,f5bb1500,ca45917e,859df11,615d85ad,861bcea9,41524e57,a2217e92,55413362,e226c6a7,84bf8604,3973bc50,825515a3,96cfe66c,9ef75e3e,fca46df8) +,S(a83f6007,cce70624,73cde2c7,b7ec7bfe,bc506c27,ccce7708,f35d535c,26dd17e5,ad48ed2d,af217e5c,63397a37,9d50d615,5a1ac614,887a2cbb,26c3b74c,626af268) +,S(f9ed7a92,7e451624,9380246e,bfd397de,5cf208dd,b47573ab,f118afed,1282d2fa,c1574616,3a6f30f7,80d5d53c,670d380f,3c84407,b4be5324,87bbb5d,c8237b70) +,S(a2bde78a,175ec7a6,7f917707,8f09f812,c7dff012,46c5255a,f0112672,6c2ea08e,7125698f,e82d4c0b,6d7d2741,9dc503f9,3b5dd62a,a5db9e20,b091323d,c9ca12ec) +,S(ca8c05c7,9dcb6736,905cc0e9,b8e1690b,6b37da42,e1875a56,e62ea231,bf9899b2,504c51ca,1e19adba,66560c1e,3fba9caa,2751259d,71389996,41d0f19f,1487534c) +,S(fc106ee,61db13ac,4137ecdd,15018278,61fd4b21,c979f97c,617b019,54eca02b,6da55a28,4fc26638,2afce9c2,cdc5a2c2,971f2cd7,5c92f08e,6bc99651,7bbef3ee) +,S(2cb21839,f47b1068,5419a321,7ac7846f,504f674b,c2f8f90b,8b9b6a71,6492a8ab,1feb332,ae75044a,f6807feb,965e2fc8,63726433,45a97af,f1081249,f00a5757) +,S(678c50ee,759c07ff,fca2963e,fba55edb,56ba3572,79970224,5d4f2132,5561f3ae,1989b787,abbf04c1,c93afce2,d389e1f9,780b1657,daa77107,c498bff4,aecba96c) +,S(ab63e1ce,aa2e34d9,8215097c,30b2f266,75d407ca,41f3dda4,1b21c910,824aa6fc,ec65be61,1150ff72,715d3da2,c4541ad6,812eb7e5,7d0f4d82,4792556a,6ce2363c) +,S(a69399ca,fad59597,5a639a2a,31264983,ec567279,b052bcc9,f5c919ae,903dd336,b525c659,c30c4f4d,a7a799dc,c93ae348,1c87304b,63491755,1c43e12e,c50d97dd) +,S(32bf4282,507bcf5e,d25cb5ed,439c82d0,bd7a48af,d3be41fb,e13753bd,c0fc5f3e,cd92017a,4336d9fd,25682f90,be347e82,6773c598,1e80033a,c20bb695,e79bff2) +,S(a1fcc983,7e720096,7203e2cc,11450716,f2fe6484,f681b2ec,5e42e9b8,eedfd862,1e16b6c3,17e8fb89,dfffa79a,722de49e,a419affd,bc17fa96,4ba6c316,31ed4fd7) +,S(d85a314e,69617e50,18df1e82,21cf738b,60485cf3,3abe8838,472b32b9,7f0ceae0,71a0ffee,e92dde66,66b4b5da,a88a79b4,fbbcbacf,3308a4e8,6e1aa367,e00a52f1) +,S(189226fa,688c70e,415b20e3,1356eac2,f5a53b5e,8043e24e,4ee03faa,f20c2e7f,d9bfd8ac,40c7d53e,7bcbe575,9987cf62,fc2bba7f,952e4eaa,1a0587de,f1515aa6) +,S(d3542e0a,6a931162,d7a674e6,32cf2135,32465d25,4d2d9241,ff70709a,559e1330,25e8f51,e2664234,34cbe5ed,622bbd83,dbd42784,4b1f2bf,9a079917,4b57c369) +,S(514d9e86,fb2cb612,1ec6e6b8,25875856,9a8c0a5a,adbfe45f,2876be18,753a2bc5,700785c0,be5423c4,341918d9,f65f79d9,1b8370bc,48629791,45ca8418,57cbf261) +,S(c9f86365,12e9ccfd,e1f1db33,5ae606ab,43f9aa62,2d723f6a,d6d684a3,ea3fe495,30d3a631,3868a01c,9c6f9445,ddcbe3b9,b7b80b58,f31f5db3,a3b3beb2,1e30270b) +,S(226f20c,8fc089fe,98cd96f,a0e790db,641200a7,2b908768,357d206f,2c2deb93,2e23fbb8,b43e9362,3fc2045,24b43da9,5e02626f,ee180cff,1c03b95a,aa5f66bc) +,S(a1b27668,d4b6f94c,7219bd9e,6b8a7e61,9fcc79fd,88d9bda0,a38496b6,cb5350bd,3933fc5e,b6e1c16a,e7aa62bc,200fd5ed,c96b5f74,b72b9b94,2644f32d,d6d68a32) +,S(10f13657,87bc31,1f7b7181,808eb0b,57dd4e7c,1590dae3,8c40df7e,afe28887,1a52e487,9bdc3ec,4e6c570d,91d4edce,291338b4,a79a3995,db5c6e85,e3366d84) +,S(8aaa0ee,a984f583,f9f55861,500dc5ec,f613b3d8,8f989884,273e1841,cdbe3e46,52962154,f85277d,c02c46ab,c2f246ed,24e56458,156d97b8,f2197d22,a133260d) +,S(32805a71,24b1b7,9b397ce5,f7a93a98,dc9472ef,a5b8b4aa,3bd66643,f1c89d2e,af525c7c,b7c139f5,cd2d0a85,82a74ed6,9e23c765,c0b882a2,f4d50e58,843091fd) +,S(c72f10cc,909ad449,7fb0835a,4f3a520d,58db0c2,87f6ab12,cde50749,a9412451,a5666e7d,5197ba9e,37d5ff15,b64b60f3,b8e2ca32,67467030,a7a112d6,f2c7c65a) +,S(6ec768c7,870211b2,415a74ad,c203bd41,72c0fa5a,d4c05f97,c0320865,77fc9a22,18394a22,aa2dbb0,925e6710,549c8c3,b51cbf42,db67d4d0,5da260ce,af1b09fb) +,S(de36ebbb,ff99d156,60506143,87045fc9,a846e7d0,eef91e61,dc93a71c,3ca64737,c5817652,f3cb37b,40647dcd,a476c4e0,488208ba,1b4d0c81,b39a4b4e,900f4270) +,S(f534155d,5538fc68,5ac01ef8,6dea6f4c,19bea322,b46a297b,c0c20ab7,3cc00218,4fab7df2,979d98ca,eeeb38a4,9a2d1253,f9d0924f,14dda603,d3d5706,b3b9523c) +,S(dafdb850,a1db9025,80ecb98,155b687c,8db2088,d0dab521,bc7fcc1,3286129d,43965ffc,ae6c4c14,3febe601,f36fbbd2,7d0ccc50,60ffe91a,a2ef2fef,651ada22) +,S(ac9a0a21,1dcabc85,1816893e,e33cc69e,2efe4069,680b3721,2999f9f4,99d705ce,16ebfe40,8281d2bd,ffa1e02c,2d00d712,acf64eb1,39f5ba88,79c3971b,98c728ef) +,S(afb37bd4,b48cf6e9,5e1eb8b9,7b8b69fd,31ae2b2f,3b7aceb,1db81ebe,98503030,1ccf4164,f8d9cdd9,6f231af3,e5fa313d,c47c06de,ce44dd84,d3fcdb16,a4b7929) +,S(1b902ef,6c294f83,3ab18e7f,21d6470c,f553682d,2b1287d5,1a602925,3888e709,7735c5ff,34e49fe7,2385e9fe,40d66a4c,66ca0102,46c724aa,24b1ecee,dcd69ebe) +,S(6e4e5b10,8a202958,7c5b4ec3,d33220fc,c61b41c5,8c3bf0b2,55e4e28b,7c3133e2,b49f8306,5c336af4,469ea410,648915a4,b55ae504,6cea2f66,f14a99d,9a8fcfbe) +,S(87ce3f7f,bb800210,5b853276,d3931b9,12342d98,7d81e80b,5b10d1ab,1b7e9714,56c6a847,79dbf39c,293c386,9c1e3385,6b71f898,dd46ee16,d1e1973a,4cf0f635) +,S(8724329b,b7ba649c,9c019372,45a1e946,d368a706,2747dd0c,9f6667aa,c9426b2d,44458e8,48d7d44b,5dba5a5b,b0fa0479,55b109d5,21d170d8,9d090ff9,650b944c) +,S(b91befa6,4735c091,32db18b6,b64d7d7f,c6338dcc,cec845cd,7d297f62,b6a1a4bc,bb3961ef,8c9b79c6,867f16cf,be4766a0,15e7ca0c,8f9f340b,14cf701d,e0138467) +,S(4321ea59,332e97ea,3bcfbb89,68a3489c,9ae3d6b8,65cd696c,d8de3200,a0d08fb3,97e480d4,c5149d53,d7582e3f,c73a35ea,3f6b023,5ce50f7e,e31cb600,84cd538e) +,S(dc4597b2,836d96a6,431051d2,5a98d421,7950a8d5,e88c2069,5752ca6,f6f1bc6d,c712580d,16ba30ca,e84e3a83,c35725ab,362bb4fd,e4c42ad7,f9b73f20,53df36ff) +,S(ce644ef0,85ff3009,b261750,8de007bb,c5f19b65,2d9f8992,9972d39c,159a009,9a41d0,58db965,baa00c92,f6409ab0,c9402a69,20a66c17,c089906c,d73cc8f7) +,S(ba1e35c,b6c7b4ba,b81aecf4,23cb8ef2,2ec439c2,584682b4,a7444e01,9936b41a,f3b3c652,f91dde46,3e178d6f,7b17a8e4,1098b33,1cead28a,d2fce694,35bd6272) +,S(b9f98ea0,2a331bbf,60fc839f,845d8f43,6988c747,1902d14d,72ed1360,86e3920f,9fb2501,a7f23a16,cc726f5e,8aa17c12,35d9b04f,a94bb27d,318fb292,c60d03d3) +,S(70591746,55f90f81,c478e702,ffcff930,dc10dbf1,16d7aed0,9c1a369e,807e886f,8267a0a4,b9d6f0ca,db1ec92,560aa3f7,d09d3f41,d1f36f8c,64b95509,b205a59f) +,S(efda78bc,c43ca063,a7b6469f,84012161,14cc5a6e,4e31c31e,b76221ac,c25434bf,7b436ff6,ef45f859,f521b13,53193d13,4cdf8064,449af2aa,92be3781,56fa2864) +,S(229a4b0f,5d62095e,3a630988,c8056aeb,35fbd874,1a2f0e,4306d094,750ccc34,170d33af,491c74e3,d2d694ce,f6a519bc,741acf35,dc6a3428,8bea3595,e234de6e) +,S(c770f48e,20a02132,189d44b8,3acd0f93,f91860b4,81a6bf17,8ce8e2ec,6af07100,7e1120d3,8b2a191f,9ed43aca,3325beae,a6d8dbbf,7e0bf8c9,610f8621,c0266eec) +,S(a5db2c63,3901d52,8b60a48a,20b189a9,e89b8998,3d424af8,eb74869a,f286aa44,b9961d92,6a93d5b0,1a74e6ab,d9c37eed,384e186,8051ba14,46fe1a37,24af1e50) +,S(3ec7169e,9f330288,a63897b7,c168db9a,4b447e48,cea2c5ff,77b298,da41db1c,c3fe974d,e8e60eda,22c4aa34,ed34a4d6,4b3be268,12e58b49,e4477835,f3053fb2) +,S(b733de17,c3311184,d5860d4c,f99e48eb,810cff93,ce92eb77,7cf2c114,fb5bf3b3,c75c0dd,72d20ad3,2000d537,ebb61571,57fc4ace,9f26a90a,d28e1a43,480c11b0) +,S(57d6e208,d555bc24,15d49616,a158075c,27db59e,6a821df2,8b450161,6c2ed278,83870a79,d130da5a,3528e353,353b34f6,74b5d02e,6cf2a891,fca34c6c,3746eba8) +,S(9e4234f1,aa69a478,3bf2fd3c,3208f6f2,6f069409,fdb2faab,8d792588,6ad3673d,5f9a4773,7725ebc3,e8bed041,47a05841,9fb42b16,affec29b,d753733e,288d0653) +,S(6fe3ff9d,9fc12ffd,bd896202,fd8ae913,22e4fcf2,76068a75,8d43f1f3,9ab68173,ef0d5682,1d414608,273ef7b5,9208c59,bf94e16,3e7faa3c,2ab3da22,b509fa1b) +,S(2c31e54f,d2586e19,efaaf415,e54cb499,54c49257,d11b161f,ff2aae5b,b45c4631,bedfb0ad,364ab1ac,e7f53c0e,9fb825e4,39af354,1a70708b,d8e0e423,13311346) +,S(51597259,23148c3,478ea2ee,2b933858,4d745b89,49c2f782,3b8660e7,78203ebc,329f6153,f688b743,c4fdc470,25790503,b81ff7ce,5a613362,8a59f3bf,66aa1817) +,S(188b3324,58f7d7b8,dc3fcb3b,df51ccfa,d394684,cde37d60,70d41e46,cdcaf1f4,4dea5da,d112a117,31a6b04c,8999c6a8,3d1ddec2,88aaf104,487656a4,d3901910) +,S(92058e41,a503e158,8ceb0a49,4e13e2a8,85f804cf,7f13c90e,307372d5,cfa6e471,368072d4,449e685e,17e5a230,e2177e95,bcbe177a,58cd1510,68e7255d,84ec108a) +,S(6a6f5226,44e06506,f27a7a68,96eac537,726f79e8,9e83105d,5b647883,34099fcf,cf3edd4b,d8ced83e,b167b664,574987f4,7104e79a,5a4b5321,4c19a32d,a5132586) +,S(7e37cea2,340cdcc3,ca21e0ef,ad548f37,c77c3402,34f0148d,89cf926f,2376bb26,c72d829b,42a27c6a,b062938e,5cbc22a,6b02d42b,d31cb69e,83b9fe9a,cc9a0016) +,S(1e6c2069,cf0f6cf7,bafb4b39,bc97a8dc,800d010c,52c3cc5a,d848fb82,d8d0b667,c181e76,bca1d846,86ecfbdc,2cb09140,49146986,630b7e81,f86c7238,8e60196f) +,S(5566600f,e6eea4f7,b06336c8,d44b47ea,f36ba43c,ca404be3,5203ef5b,6f07e16,6bbbd08f,7adc1979,ed4acb4c,f372eda,69e5ac16,7695a78b,5a7fe1ce,1057e55) +,S(435c634d,ed451c5c,21c5adc,45d94f8c,69045016,d529ba76,19ad07d9,31c791b5,31ede268,8252a50f,2206f959,1953c0ca,85009876,2b6f6c14,24b4e47,c74d4cc1) +,S(6fb8cce6,a66071c7,395c0612,252a414d,f19a0d2a,f855e7e9,dd142342,9c57b9b6,17f94249,e2f05314,d4799fad,68232626,183dadee,abfe34c5,b845d89f,2768e052) +,S(866f3e99,20fc4c94,9496a695,f54ee634,11c711a2,99e05890,148de8c3,2980dc36,e99c55af,4f8dc3c1,d38a11e1,3c00db2d,f5211f02,e837909b,ae188786,d18d62f7) +,S(80c13410,b7164899,a724f723,4dcbe505,62404f0b,7c027c79,4616f618,80468b2d,8631942e,71a01e4f,d7b59281,9dc69d39,bd6e8fe1,c2c41621,6d8df895,280b91aa) +,S(8f85bdee,ef4e9d88,53e68be,c17bb6ec,bf37abc0,a4ba44d2,c3815dc1,82a7da99,36d45bdf,8ae9342c,af0f8ce7,8aa591a3,4e8c295e,49ee6962,b4a9fb7e,ee17897e) +,S(9cd0b2b,3393cda6,ccedaf4,ee8a1b3,17a920e4,826da2aa,4404a01a,49600749,3831d35a,51d9650b,b1901e34,8f0c4ea2,3a00c492,a4960463,414e5dee,aafc5a5a) +,S(a0c5f1af,15c67ffd,6cf832f7,974c779a,3ab7ca,dffa32d3,bdbe0377,d49f33b0,6aff40d4,42de6262,41734412,3620c5ff,3079392b,b8843c57,80029682,1cb91ec) +,S(af396f40,13e217,d7e1fbf0,2ec4039e,c0111370,37cb2d78,90a82313,58edfacc,aaaeb9e2,5a57534a,2dc35d16,705f0e5d,6754c599,e85864bc,936e94f5,9acfb936) +,S(fdac3c57,e3e0ecc5,e7e871b0,dbe35979,87d4c071,f2f89307,cf1e71c4,91ed0eaf,3028a0cc,a22ef096,73c877af,ccfe36d6,b14d14ff,5da10b18,cdee6068,3ca09fc7) +,S(e3aeb123,9587baa9,ae12b6a9,68efaedc,ae745fd6,aac5103e,14a471d9,eefa88b7,7ed1c786,52c1544b,e306833f,bb27d1a5,7b460305,a2c8f6cd,2d33397b,caf769c7) +,S(96baede3,382a0162,fb4cc663,c91acb94,eb83d7a,3e3e0a0e,6055a50c,d78352f5,78722e97,b3ad2824,388c3a80,fb930089,5100d61,ea58f997,2adae059,f0c50cbc) +,S(68704956,16975637,f35e1eda,4db546fe,ba93d122,446a3e40,8de04ee2,3bf5f5b5,6247d2fe,b5f7471f,3a06c7a2,4c4261a,934bd226,772405ff,46e361bc,614ca494) +,S(71ccc634,2ca1f858,8ae02d72,eb0dd2b3,62eaf652,f83edad7,94095e09,f4bcf749,487aebd9,23b10e69,4a8e3f22,2703e5a1,aee17794,42a96c68,6cb9f983,dd2a45fb) +,S(6fda1dd0,65739a2e,58cd183,1e8b6109,713844ba,f249cdff,25d0b3ec,f635d3f0,a2ee44f4,8afccb72,4f8a96c3,2a88a8b0,a232a93d,553713df,60a965f5,2078108e) +,S(d3f27709,ff5ad97b,45e395c1,39947115,65cbfcf5,838e7b64,b1016cc6,d5147f45,f96cac16,cdc8e1c3,54e026ed,29bbd6c7,29006ee1,51d9d61a,4391567,93265077) +,S(27ba1944,a28a6eff,78a7d064,bb8292c6,68f82793,8e2be786,41ee366e,a4a011d6,24bef875,9d216430,e7312fc9,458f0571,fcbe305d,574694d0,a77f7a98,4e7bdcab) +,S(fd37b812,5fd87ce0,82fca9ff,7872e0e9,772f4c44,1870748e,e35e7d00,944fe190,9450a525,d9ae198d,db9b8c43,fb337df2,8ec68a44,60106951,1847b9a0,27dcb453) +,S(d9967cca,92583e0d,8d329b63,f32a8017,4467518a,595d8b80,2c24cc8a,8e071c69,6aca3673,c2c39d69,3bc86dbb,92e5af27,28361cd3,2179eab9,7ed64ae9,73376c25) +,S(8ee82d3c,4a8d01eb,d22798ef,bfd95c16,f53cd45f,e3d044f,3d89ed40,b94a0a3c,e0b0ab7e,9167fb9d,aa71c3a,fd5b9c0b,79c8b6a0,db3ae2f0,36c626c7,791e1b2d) +,S(461ec3d2,817cb549,a9fea029,15029707,8d709ccd,bf22da47,64c8a1db,c562caa,661b2d7d,cb5c9790,510f6e12,61650401,26cdf80d,b086259a,db16af47,af6684af) +,S(3155885c,935caed,469bb7ff,b53ff6b8,59f51780,f3de5890,673101bd,41f5793e,603594e9,92ac108f,8d0bbdfe,8f3576e,8ca6ac2,69c7581e,28d434ce,2043dfff) +,S(5cac93b0,ad9199c1,906267a0,ad8874e4,c68a60a2,b9fb6f0d,cad42758,2a4ea9eb,836faa98,a116dab9,69961fe7,ad7483eb,c48e7295,37e6634a,e423b99,880032ab) +,S(1fb6d3ac,afd5ef56,8b6eea1c,4a8f0179,54d05274,24487904,7e3ec56c,6956cc42,b8ef91f2,f89e4f32,6df6a1ec,50c6362,7431be48,1183c839,3133dafd,2e2a5411) +,S(89c0b1e1,52f0005d,a30618f0,3fdee7b3,69fe0157,f7bb2bdc,d31fc773,d82b28f2,61d6e357,bbf46816,acd05de5,b26c67b5,ad8223d8,ac9f47a9,25477ab1,80b4a507) +,S(7c5d18b,1f9d1afc,d663875a,34193240,7cb968be,f31d751,807ab1b,b79a211e,45fbe7ea,985bda0f,bd23b449,5d4e945f,d136b5b1,296c9b3b,6dcb9c37,bc779ff3) +,S(c827cfc1,9393108c,9b31ad4d,b5eb7f00,b6afdad3,a5e2f792,ddf9dd13,f159f85c,5c5fe07a,3025d401,54fe12fc,89951e2c,330ea3d,d6335a12,9c31aaa6,753a1cb1) +,S(6347b32b,b1f3f7dc,205e2fa4,6b201b4,2e0dfa80,550741e6,57117875,57cc5d9b,f8f30e10,9508d34c,a48d7255,3f8ac26d,a455d3f3,b170ee52,e22be1a3,ae8c3ba4) +,S(d489f595,e822101d,5f6e4283,7db032ae,bfa21f3a,94998130,e0a1d226,67ae1014,8b112e89,8dc4a146,8f64c33d,1261f8c9,2bfa98df,eb9500c2,2b4a66d9,227c66a9) +,S(90cb9c63,fb4afbce,adeb8f98,1e76a645,2200d73,d43bc0b2,76f058dc,b8a6205b,894afdc0,f6ba7f1a,bbaf19c6,720471d8,2611a77b,5bf6c87b,a02324ce,52e74645) +,S(40df68bb,19f121f4,e566a1be,f0a98954,869bb06c,699e818b,bc49a795,6a196af4,70d41c09,d0cedf7c,31c9f830,3610f6b6,e1d6b3d2,a431e69d,a31bdd63,220cec90) +,S(4936fd74,a0ac5045,91c962b6,431f17fc,a888dd1e,b35549d7,8b41143a,83da41bf,33a8e1dd,6517853e,d7c68af8,5b3f1cf5,3fc5b72b,5dd0f392,c5ab5ff2,1bff4f92) +,S(17177538,811075b8,f5baad59,2958074b,c1a0c6e7,b2a3f594,288e82b0,da023557,583d4814,efd8742c,5e7a0c5f,734da121,b163fe28,239a8775,4bbb072,c1b10837) +,S(a126b7fb,ad5145ea,b414c82d,8f21f208,6abb118f,3692bab,586770cf,4f8926a2,79b4ac17,b601b4d2,1a2bfdb7,41f7fec2,88d46594,699e4394,452cb2d1,ae2ec669) +,S(51eccf61,f8840048,d55de51,2d865a52,3485db8d,869844fd,ba30e703,ae871163,594ad253,97bdc9f0,82c0c46a,200ea090,12b2c6a9,57a53dce,e87caed3,2ea8d50f) +,S(97781633,6f1b7131,f55966cc,a79d25af,d8984438,8b516882,5105ba3b,52b3c7a9,f1df3541,b4b08fe0,cdda20e0,a5275eb6,105011ee,f4355516,e47e89d9,3b214c60) +,S(8bc2c43a,72248dab,5c78cf6d,b1a35ce8,64231d3a,870bbf01,cdb79be0,2c93f7fe,d52e2e76,173e9dbf,9e8106a,ffbb9d7b,b428f07,80269b2e,f49bbe0e,14cbb425) +,S(59ed7881,6c7ca119,ca4abd03,34b90b37,6c327175,e899e0d9,79953e50,5aef9f2,239fc027,690c0feb,e4db46a2,8669e0da,20779425,34bc6133,152a606a,16449910) +,S(bec399d1,76714995,d4192390,72a39c59,c8ff8e9a,2cab6520,ca0cf6b,2fc70fda,ffc4bdef,7831208d,23a1ab9a,de52f346,a21a2f7c,efc5ffbf,70999bfd,ad0ba8e7) +,S(93bd25ee,f4cef1db,fa5f9951,7d22a77d,9e3b87db,58c63076,68a35885,9e0c4d34,dd7d1412,97361b84,9a43b1f9,4f89970d,fa008c63,3404860,794e6a87,6735b4dc) +,S(b203a657,fb4e4d51,158b2e70,87455a57,44e553c5,bdea4f8e,3e8e6c92,eddcf58,98246948,c63e182,61f0d4c7,543fba7b,c74ae5a7,a19afa6a,ac80359,5ed8c99c) +,S(af38b53c,1dcd27b5,8118a28d,11da8aaa,3e20ac21,4cff64e7,be683dd,80f6aa69,91e38936,ba8b2b42,34686723,7a3fac67,5ec10179,18f8ac16,acdc32f9,c09fd919) +,S(55e4da5b,b99d805,e2058756,20ab4cee,988ed472,f5e6d86,2f8c574f,6bfd8518,7368be34,75179d32,e15b5976,c34c366e,e7713b25,8f179309,40b16117,aceb2d35) +,S(d3d7e82a,a7ebe240,83e1a15e,1d817d91,a3608c6d,d25a35d9,183a0c9,e42133f5,a5245cc,e89537c6,895080b0,6c5e2772,4b1c6d69,6c1bfbfc,ae6a7d4f,fc5d504b) +,S(8bd14f9f,e6b54437,9761e803,1dcc9907,beab754b,68c6c3f2,2316e5a6,6ee48799,f89dc150,a3876257,51663a26,35633868,ecb2eb27,d9ae8603,89110aff,6978fe19) +,S(b1d72365,3f50f42,cfeb0858,972a5a22,3a7dbc5b,4823704,85c88fd2,22212932,40597dd8,594ee1f9,b74aa52d,385b21dd,6279864e,7d0255,70bf3716,c02143ac) +,S(44d303e1,cb7d920c,93be4763,e045cef5,c22d4403,5e1d3a8,593f4f72,679d3023,79fbdefc,5ed6da2f,31bd6fcc,83e3cee3,e77e41a9,a01b2004,76912c61,5d89a70c) +,S(1655ec54,447aaae9,727bd4b9,60eb996,92558999,83d4aed,3dfeba12,3b0cb3ca,8e90e578,cf96e31e,988f7bf8,a9f06d94,6ea28fa6,b1dad744,3b9ece50,6626fcdf) +,S(b02ae3fb,530566bf,66da9326,18990e6e,7902b104,800cacb1,9717bb7d,845a3f29,c6d32713,f4483031,19bb7631,1b397427,d8c05232,92a61051,62a0307d,7b006876) +,S(13c46566,53a0042b,8755e140,2b12b9ad,8e123699,a153ec6e,65e49cd,10c5bcd3,70f3672c,498f603e,3c521ea4,3ac3e10,7bab13a8,a78b02b0,4492c51,6d41c88) +,S(e7c7562b,3fc37b8,2e9c7bff,c5e97b39,dee483f,141df4c6,361eda3c,4f1483f,734be460,3d2b4958,c1bdce51,57a16d0e,1a937298,1dbb2833,1b12f8e6,c3454066) +,S(de025d2d,fb6cfc75,342b2ed1,ebc7b27f,332f3921,c304b8d2,263d7fba,2959aefc,46c609b1,6ab6f3d0,2dafc30c,38373a30,1a88c31d,80694598,5e676f1c,16de12f1) +,S(21e788b4,fed21c3d,25ddb714,abaf053a,25730af4,83817e4b,6a42c323,3eca2e01,1fe716bd,a7d07592,b66af9b8,32335b9d,b249b1f9,cd413c58,ddd29fda,e5c1c4c6) +,S(a7db27ca,7481d50b,1a458242,c75b28e6,d1bc1a9d,da97e012,e39cff10,7b79edce,c4f8686d,cabde6c1,d3455fc1,795a7cc4,84239d2,3b11e238,85136183,71ae73f8) +,S(c5205173,2790f240,e2161627,5ac894cd,e80a7d3e,bd5bdccf,41af64b6,5e2d477a,e9aa295b,209410a0,f0e8e216,deadc3f8,af87700a,40543cda,463beac9,f62ba20b) +,S(487bf4ad,99d1daeb,f1c25f86,d36ebcd9,38e91eea,8b855d05,ea9371c4,9572846d,81293837,ac6ded0b,ee04b2a5,4c18ae0,32f72970,86de0ffe,791a9576,fcfebf70) +,S(bd6dd2a6,bfcf688b,84fe2d55,e56025d,35567574,20edfcb1,3cd14483,e08cb53,c86a45e1,84c83806,38ea1501,c2851598,c467d2c,d1c51a1a,1b037324,d9ab0fca) +,S(94a417fd,fbf188e4,1334fbb6,906731e8,70dbca18,672bece7,936a4c7c,235ec737,e03c6607,343ec14b,81eaf124,bcfb7d97,564e9f93,546f9765,299a443,d9be8e34) +,S(2a57dac3,3fa13b26,a96d9b73,317a23c0,2ac597d3,3968fa8,ebd88d94,66aba51e,1754a6bf,1db7b3b8,b0a7996e,545f34fd,3b05bfd9,805b50c4,42db2937,e8c13b61) +,S(ba2e4a71,6142a39,67c613e9,93083c32,d1c66da1,2c3f9742,eae90b7f,ec7e7df7,c262f8c1,a704e83b,ed7fc60c,5adec65e,ccc6de35,8247cc97,1da7acfe,834cb07e) +,S(4ae19743,b3132512,d28a12b1,1fbbd824,8bb0b9a,730d5a8,a862ea8,ecc01ca9,67b7267d,48fa3ea1,d1c1ec7c,a6a8ba0,cb27883c,3f9d4193,20b4c8f7,a017eece) +,S(4cfb26c,81823667,f18e6ff9,d77493f0,778b9bf,411b63ad,61850ea7,7706ddcb,10df8a3e,3a8c93df,4d7af16,407c3211,aa6c6079,c397a0c7,78e1e277,24e4028e) +,S(9f9e4566,a014b66f,fbc3ef,b3c05062,15f06102,6f7d6561,934d3db9,5d130349,492b8ba2,76d526bb,98fd0c17,c5a0aa7a,ab6e5c9c,ccfc95fb,a417d25,9396c592) +,S(e36c0513,3641b560,b0f9f4c1,1159e2f,ecf2a194,b55f3bd2,22ecf1f6,ac239301,c7fd74ba,48e7fc40,6322aea8,e9f83a82,20e9a113,ac2b0c7f,aa05a5bd,bb43736c) +,S(91b013b3,b94d4568,78737580,bf1da11a,a0bbe0a4,e3ec65e0,33e9f824,d8480bbf,15e3707e,c13a2529,22a6f824,7e33d172,948790ac,3d367f00,6472f22b,e8cfc5b4) +,S(254d1788,8c676d52,236782de,2d539f2c,41f667a,d75d0107,7d43f723,ea324f56,f7042d2e,93511e5d,13f4aa03,bb2dbf27,9bec3df,97974275,5fd25133,c814094a) +,S(452d6b7e,ce7d0f71,2afabe44,2a22f16e,34fce662,99697f0b,6135678,56f4079a,21ea8ba1,28cffe76,3400d69f,ce13204a,9a39ee59,14132d23,db3315a4,7f776998) +,S(1580b9d0,7888f41,81b86b85,5b1982d2,81783185,5f28c163,1f151479,cc4c508b,4d9d1e9c,78b3d9dd,73bcbbe8,778c1b7f,65b69faa,f6576dc3,ecdd00f5,c1d689ff) +,S(79dda23f,c31694c9,16d1470c,2cf25a02,45a5aa7e,d084af45,c43960a,a2fc2700,7c7bc169,a58b8d8c,c4b74e0f,377031ce,d7158c21,a156fc03,c34f25a3,a95bc978) +,S(866da7a9,bf80cdc2,13e500af,b5f4aa0e,419b4905,44653b5,fe2daee1,4149dbe6,626d38b3,b45d57aa,6867e8ad,c8abc49a,81a282c,6bc6524b,239819ab,766bd3d7) +,S(432bc912,bed271e9,321624cf,c6062b96,cdb502ca,f990522e,1024b80b,9411d374,e645449e,dd7c4d41,41e0cc5a,cc5d45df,4cb341c2,baebb605,bcdce6a3,e411cf01) +,S(ac3d3b28,83ec385a,15297086,525d937b,717f5ad,83a5be4,77b3ec9f,6410518e,d126eefc,c9ed7e75,c10d01b2,c0e790e7,3dde58f9,54185a12,5fcc7268,84b9b8db) +,S(4570834b,2a82385d,6db696d9,56ae2667,fa18b262,960d064a,5c13da43,abd6aa37,1e9d6083,b249bf88,7ba2eb59,a9597e7,d9d15c64,ad6404e1,21a486b0,61236f28) +,S(88e9a6a0,ffaae05b,7c29bf79,2163c0aa,b224b051,36aeffd3,341355d4,b983ef15,ed382a2d,fa2f63ea,dc4ef5e2,579abafc,fe457475,d1ae8413,99969324,718d1e5a) +,S(16810eb4,de3327c6,a505663d,cad7f618,b397033b,d6c9748c,4fd8748,2adff706,352ebd8,91326c9d,2159e84c,40dc29ae,30693b7e,5a9ed119,1fbc2cf,ee60c81b) +,S(d7d03a92,95064981,1cdc6503,588d157c,88c861d9,43fa9cab,e2e3301c,994adf7b,8c820bfe,933c2c05,1ca3042d,5ce781e6,ef419c8f,d9aa83ef,2a915e36,382f9627) +,S(5b2c9504,f645ac90,24e25c4a,e880ce7b,f33aed77,e45518d9,1c6f2652,ddcf11b0,500b37bc,c7764f32,11d681e5,e8f2a407,440e1da2,4eaec354,fc289c76,29296449) +,S(d18e26ed,d2c78bbc,16982675,9d59eec3,bab1a64d,f579dc2d,6284add4,8cfbd761,1a1e0172,37a3e78,8fd8989a,a5bb6944,685915da,1392e1a4,4a6c7ef5,7d0770c3) +,S(5f6b1416,9bbc4795,8ca21e88,df252546,dc9e46bf,85d64772,24f34ce2,8e58222d,3a8e7616,4d5a0501,947ca0bf,163e64bb,3a57918d,e383c600,e02aadaf,4b7fd6a6) +,S(d7a625e8,dcc8b456,69802023,8fe85691,ec2e050a,25421373,39bdbc8a,f762bc7,8f1f9935,a8ce2607,abd7bcbc,fec1fd8c,208683a7,10000806,20d50b4d,36ea3643) +,S(a56a5419,72aea4f7,15dc891b,3a1b34ea,7ffb42c9,5e02a771,6bac663e,8d5913f9,47b3dfcd,ad785671,180f7bbf,a7f5d144,59b44023,640e3897,1e999a90,6bc3f994) +,S(1ebb89d7,e574cbd1,37b1a3cd,4a306b44,30325db3,361b7c3a,d93116fa,baade31e,2039c52f,bd30c84b,4983d118,5422a342,ee020c33,49357e6c,b9550075,38da4dc7) +,S(b5728208,931a6575,4b5cd1a4,a798ec27,e189effa,3ee4f0c5,ad493a88,b49706fe,aba785e7,2da3d301,cb29a612,562078bf,358f680a,317836c2,14ddf7d1,bede9ee) +,S(56661670,d67b7c77,202a00de,effc1ef6,f5162a97,47afca8a,a2457c85,85a775c9,adaf08e1,83bc5107,4c55122,e549d3c1,4de8a893,39f199b2,ea044a25,4d8803f6) +,S(18ab56e1,ecc86b69,77104243,35737b51,c18521d1,b170a3e9,3fd068f0,ddf2704d,cc694c3f,43bfba9b,20c9572c,acb30563,df74f07e,ce1ff9ff,46b8259e,8119e94a) +,S(bc12a874,48270360,1575b754,bf5f50f,6e945185,2e0f27c3,c1aa0f1b,ce0ac357,9c6ce76b,ac175ce1,d667783c,7204ace4,abe12d56,62ff36f9,5de017c6,f1ada1e9) +,S(a4494c26,99b2da0d,6edbdd6c,353eca75,75666796,5ddbe457,2c27ac46,79054584,589804d5,8360a9e7,d3e2a914,61d5b1ba,e8f0cf69,3b8add03,5545386d,5082d621) +,S(1ff846f9,6d0e4e7e,be34de77,d036a027,f1baf9e2,ea3dc9c7,8284ac9c,ce3aea6e,8a0a336b,9f0e3560,31f5d1a8,d4c0b68f,27ba3eef,a52dc974,8d03e12d,653f2e6a) +,S(33181aae,91573ddc,728839e0,4173f716,6862d724,35744099,ffa8f1f2,9510b374,1252129a,8cc8ce4c,1ddaaa0a,4c34c4a5,f01ee26b,3e1a9fed,ad0e7c9f,bdc5223e) +,S(e687832d,fb0e44ae,f7649b15,77274a94,64426406,fe4c6ae5,7028c9e5,78012594,5e5b3897,6b734b7,b65caec8,c77ffb7f,c5de4f98,eecab002,8cac0c4a,a513b7c0) +,S(354bbec3,ed9371ac,58174b5e,2a18c76c,c22951,df4c6aa5,755c72f3,94b37def,40d0c876,9283416d,b3613ac7,37401e3f,3c2f4def,bbaba44b,5c2a83fc,c614c29a) +,S(fa46ac6c,5205b81f,3c9e8aa6,8b5ebef2,a8bc68bf,fa2f4511,ae36f726,7439a485,3853f9fa,b016d2a8,1cde37b,13f91185,f25657a,765fbb35,c1b4d52e,3f67d180) +,S(426f86b7,33255f8e,1e85263c,923fb86e,56a53d77,945f6688,5627ed43,3024328c,92ec0168,5301c89d,5b13c4c4,57b22215,658c6341,6aff9148,6a2efbcd,4e8c4fdf) +,S(5c8d1c9b,f9a72d5b,e15d3f4d,17d48cf1,7685dfec,b5ae1ede,b47b6e58,80bc64e3,6205550e,286c8150,6638a3c7,c20f0dec,b6a26b53,641d2dc4,e18d0f7d,29bda7e5) +,S(3a021dbc,7bf7501f,ddc31356,26a9cb01,be673373,fa663c80,271be570,e683422f,64a89c54,ddadf89,784e508a,d056492a,a7a71b82,485fcfff,54c7b0de,4c1bfa53) +,S(8d82aa49,1d719f00,75d2dd9,11d642da,7c0062c3,2296726f,a504af27,23ba47bb,6e616f50,6d1478f6,988ed10d,6c6d3c50,7c2ae8fd,4760e699,1ff5c62c,53e4e77a) +,S(6feee988,fe488e1a,6ed5d60e,fcac1b3d,bbe5451,6e7aad76,f27f08e5,3c5e536f,ee9f95,839fba96,ba26d848,425b68a0,73dcee61,35e04eef,f482998c,b044c502) +,S(36240979,bafd0d57,72fcadc7,314093c6,3063880a,e895ce5d,2df3e59c,ae16fa1b,619d0376,58ef3d85,a7afe326,77d832cb,eb20820c,157836ca,65f17c61,c84afa48) +,S(4c2b8847,4da56053,c2046fc3,26e81704,b78494c,91877407,9984a3,cf6a18f4,459a9e69,17a4d711,61ca0b43,85c5a823,734286e3,d0cab398,dda1fe21,3b28142c) +,S(f921c9fd,b33211ba,a7f4eb5b,15044c34,d6e54f50,af7b85ad,84e12fba,b1478ac2,38cda9b8,c850483e,48c6b16a,5f7f624d,e31faec3,5cd594f9,3171490f,ae016973) +,S(a57769e6,6181d68f,8f86c8a7,da3fdb4e,850ae07d,f41e78b8,ca42c6b2,1b19b257,212a987e,644bc42b,f757e00d,54d50ba5,1dcd6698,280f8eb3,8829dafc,527cfc6c) +,S(95a78104,37abecad,888c9195,23c9b16b,375a2714,fed74639,1ea949a,c7c11d9f,eae320aa,227b056b,242723df,1f11a494,ec642876,91a22748,9e1ecb2,a2cfdf78) +,S(76a7e034,f7ef3e14,2ada9a64,ce984008,9f034a5d,8584a0e5,d10d40f4,29cfa42a,999dc0e4,9633eb3c,2a4ec931,9bc2eedc,9f2e4996,522a2404,79c9468b,668effa2) +,S(eba89396,47567805,1cddf92,9db7d82d,427010cd,5e94247d,f4e8cd1e,eb5881d6,b92ae1f1,c0885214,3f37d8be,616cc5d6,aebe0f8a,8da4a6a5,d4a69b5,dbbca552) +,S(a53a48d8,59fe156,6b14f872,aaed4735,dc0b7589,713ce8ad,dd3f3e1d,6e23704f,9e738da0,7e85a3a8,3d89403f,3ee7d564,4f463418,676cea0d,2528b515,39387fb6) +,S(8326590b,dba5f8a3,8e39b148,105063a7,c831cdf9,98288fb5,95b4fd5e,a707d3bc,a02cf88,a2a1dd25,2d00d62e,cfa4130f,61b7d4f,297e6b06,cb4661b2,bf768982) +,S(6a492194,ba8c10bf,e31714a2,17a74b2f,b0c35a2c,95c54af,7f5ac6df,17916030,3cf0bd65,8e0c937a,92ee8b4f,b4fc3289,c531cd00,6febd45d,b6b6c522,f8c77b87) +,S(b4ac71c6,ff797eed,61d80c49,46ba221d,3b34bf13,7e3d4747,4b6c3068,33c52a57,46acb2e4,8fb6fefc,ef3d2343,4624e0d6,14ae3b60,df813683,90503506,d52820f7) +,S(8b11711e,65bc29e1,16bf05b4,e557b211,13b19b93,a1c1ef9b,49a19316,c286e0bc,79c4a0cf,cf383538,21ad695e,5b4eae58,faa6bcf5,c722c491,aa9078c,8aaf0dde) +,S(b8b00a76,e86b2579,97603f82,e80fde24,727362c3,6d7a192d,8974f643,4408e098,5db6718,8b0108dd,7cc6fa1c,fead7b2e,9e0b9ffb,78487d0a,5851b6f8,513e56c6) +,S(884c3a1b,fb6b968,53427a8f,69b713c6,bebe8f69,645fa52,c50e2d2d,61d89814,3dacc0e5,94b2eef,3743f821,df54dec0,ff28aa4b,d5b18fbf,14d658ce,7a3749b) +,S(3d0c1dcf,51aabf63,fe04100d,cbf6fb4e,c004dd1a,aeb637d8,496a47f9,74637596,576ebd5b,bf5de2cd,6242a6f,599fbb76,883fe013,3e2ef05d,22843236,a5df51c) +,S(56b3edaf,61539adc,25c57f79,a277b77f,1ae972b6,3d5328fa,13f811e2,dabca8c7,40383900,a2b28602,71ab3d2b,5dda95d0,96bdfbab,79b3d347,dbdac66d,2d2e98eb) +,S(426e29bf,50f34c9f,434eacfa,845485fe,5fbb11d8,319f9457,a74905fb,2bcfd3e2,eac47ee8,eeff40c6,20d10cd5,c3b9df40,eeb60b88,df1f57a3,5d613198,33cb117a) +,S(955737c9,f4e24d7e,c6d419ba,a2edadc7,cf0a91fb,5bfc3ea6,7ed50ca7,62929308,97bbb89d,18fd9040,2fa78314,359bf645,b69831b5,bb82e608,67baceed,481675dd) +,S(5d72a813,d46427a0,f2fae639,fd7e7ad0,704e74a0,83a784a1,cbb85017,e8b3e514,c92f410e,851fc61e,559d6839,a99eb95a,2e8c2636,f51c45ac,9bc1613c,b8876c2f) +,S(c7da9359,e9bc8890,620876d9,170495c2,dda7849c,7852406,22551bb7,e769b6ef,12278168,71508d00,95d90787,24a0c7d9,cb41f6c5,c82f01c6,d3794c3f,5c10653) +,S(67080a26,da7af0fd,c2fee080,f20ae516,d92697d7,fe1adace,9729064f,569ac683,ad9a07ac,fbba708b,30944107,e510eac0,8e08c5ce,79f77714,aa522cfc,2316d94d) +,S(210d5a39,d61428f7,6f878ddc,82e3afae,3947f404,5c155a41,63a00570,5bfc0dbf,617effe6,b0a629c2,ed14cc29,67a9193c,2efa804c,93e997ac,96eb1803,2e8c511c) +,S(5d0b9231,ca1511b9,c53242a9,37837d13,9b8e461c,6ff655fc,59021d04,e334ed98,c8070121,f4794eda,713ae1b4,a9e7d6cd,1a2f58e1,f6f8d986,bd13a66e,bfe924ae) +,S(687bb82c,42101161,ed0c8bd5,44c71975,9013fe2a,fcd10ab6,3ce78a67,e2907392,eaf63d87,758aa3a6,f9fc721c,f8b209cf,fafc8e81,10397e35,6a25e966,100d9eeb) +,S(51a44157,b8048f68,1a2a3931,ff2c3ff3,c63527d1,f4bccda4,e66a6d1,ce5f5d33,6ffc8d16,519c2940,14fdc8f4,20a63890,1a0c5667,2db96a1e,c5127fe9,e847dd31) +,S(b2862572,56f515a3,5624786a,478c3bfc,a5dd7b2,2bd7c4f9,89f70bcb,8de86775,22ae96a8,a5a5396,b7a67e5b,29292ffa,f53b64de,45f17692,abcd932d,4664f3a3) +,S(f76b721e,201078ca,eebd89a5,ca396213,6ee129bc,fb92ae58,4bb7c7fe,835bc30,599c6ab1,8419840,3d6b3d17,161bafff,223a0a38,1e96a4b7,a062f4a3,e6c0d561) +,S(12f24a87,63adee06,e82f20b7,ff696911,d9a3b88b,36dedb97,93b07c34,c4178e9c,59fd7b9f,96f01fb7,b265d939,c2827bee,b2427fdf,8c2e1b7,35178d58,e055b7f1) +,S(9e1b8a90,de6c6bbe,2a082d47,758240cc,bcfaf145,c48f90ce,fa0221e3,1922260a,fa5e86a5,b54bd9e0,7c2a54f4,2097d004,8a71eb06,ea48c0a6,6cda5981,b390f9f) +,S(63f05903,20b73eb7,b01b6a66,e28e31f1,ed4117f8,6c4d20a3,8c109031,2fbaae9c,24b8c9d2,d34a81fe,6e88967,a263877f,40bd68ca,baf5d9c5,1abe8b1,9501d8eb) +,S(447c7409,f5402a3d,a1f569a4,ad9f2855,e5c89b6e,99c743a8,e27992b4,63905999,d44e8d9a,b34a7a09,47b37723,be016c08,716baa73,8b93f28d,b7790370,ad49e154) +,S(74a4406a,4c5340af,ab77db0c,20f197e4,25eed4f4,a3f986df,1bbf10df,f8793254,162d678a,a4ba712,8cd36907,d1c46b16,dc4c07bc,52aa46d,fc7987eb,67742023) +,S(f7035171,31872637,ab0e63cc,841cc7b6,2bf5e076,53a45ff,3a23246e,8f047c07,c84b0391,4f470785,721762a9,5972b59e,b3c7eec9,66718936,ccaee9c1,da1097ef) +,S(ec4fe07b,57b23581,2c53bd70,6b0a4152,2194d168,dca164f6,ac999f6f,72eaae11,af495291,45deb29f,ec2b1dc4,e9b76051,b2f9df79,bdd304d7,b5528f5c,a2fff789) +,S(17156de8,fa96174f,7a0b274e,e168d0d4,c6552047,11f36388,78dbab4a,cdd2ac9d,2ae3ec4,36c1460c,984e37ed,6decb88f,c2de9f84,79e28ca6,abb6803f,1461ac3d) +,S(e41b462b,9c5a47fa,cfa9be56,dd30cd,549cb90c,9506a6a,abfca643,9a1b2ede,108fe2b2,8bda60a,c68fb353,38c6958f,e1b3604c,22215311,d380bf11,17507f4) +,S(ba6c0159,20a67883,d7880051,51a8038f,f357ea78,c53b95ad,38a6f437,7744aa38,da49c0e7,deb6b746,83366aa5,c0e8e710,cda1441b,6686f680,4579b5b9,16002cf3) +,S(26f0186e,883a4b6b,87102ab7,f7e52663,7e8a9553,8495729c,ee283568,f8cbf1ae,eef8de4,bb2197ca,ccd51980,995a18a0,aad78823,75702d3,98b245db,4bd5f47a) +,S(10b93de,80c0cebc,351b5588,c0140e63,e00874e3,da663cdd,c4501ca5,b40c9d22,ed3189dd,f79af36b,e7986b02,7ec495ec,1dfef7f2,14358284,2d05b4d0,1c903258) +,S(e79ec274,337a82c1,c97b32da,8f5a8c55,7a159540,76c94255,8bc9a3e7,77769dde,9f23079f,22dafce3,54a4c175,d888f3ee,e527dad9,83d7502c,3b651762,628a06f6) +,S(fda0175,44f0ad3f,c8b9915e,8e0caa4,2be265e3,92041b0c,1b7d31a1,6fc101e1,424e9a27,85d59c6e,bc7e4298,1a505733,e4d49a76,b84a030d,db2f5c1,858902e7) +,S(681f01cb,5380cdfe,50314725,88bc830c,8327d8a3,cbcfdb31,577cf11b,a099c6bd,bf9d2117,cdc3b05f,9c06cef0,6fc9e757,59c02fad,8e0d98cd,794918,f39002bc) +,S(70c25a6b,2a2d2cc2,dd251f4d,9aca250b,d6fe9f8d,b9eff961,1de2095c,dbd12f64,c9eeaf68,a386b2cf,cd3f4dc4,793ea5b7,134dae04,d991e1f4,6b299a4d,1a966126) +,S(464ded2c,404b42d4,fefd5ea4,5f408666,3b466e85,fe8b304,3b121b8,9fccbb9d,ac113904,6ad3f613,23ad2d3e,a568367,610bb47b,e41a5260,79627122,105d910b) +,S(a32df72,48e79198,5d455109,a8c5dfc1,b7ff8990,1b5ce3f0,2ad2f134,13a103db,6db4b4fb,9d60906b,9aea2d1d,876296c8,cf9ad8d3,3e65e173,8212134a,4b160e72) +,S(fe49ce9e,7ee5d39c,97029774,64ec4fea,3ccb74dc,2a5c7fe9,a7695315,165179a,653f553a,35925dce,eefb9866,26155723,90bfc582,b4c426e6,3f58f0fa,3fe7dc8c) +,S(868b2e55,c895a7c2,4da24750,c126b10d,ec0f1a0a,2add5a87,8aa7316e,3354ad14,5e288874,cdea19fd,71f03594,1a6291bc,776bca82,804324,efb61f24,7ac299ef) +,S(fe0790da,90ae34c6,8ad3f1c0,80fc486b,d267ff7e,fd32d1ae,c63d08b5,8c098461,ad331393,de35b283,471a0244,422c6132,cdbfccdb,5680bef4,16f3beaf,6cf7177e) +,S(fe7fca8d,f4f80dc,ff16b196,167dfefa,42a23bf5,66837955,7f6d8279,6fe9a9d9,bbc4dd8a,d7ee925,dd80cb3d,681476ae,ccc5729c,e1815b1e,71c8f1cb,d8d4eb3b) +,S(a236c270,aa4ce20b,eb51b11b,511cf4c2,ae797598,e9f03fd2,3aa36858,9434cfc2,593599c5,75a7bdeb,41cc3ade,608c210a,8bc37040,fbb69f4c,4863a31f,2088f29b) +,S(d6a04a5,6bb8c27f,3ea8a348,538364e2,800472ea,d9e1f644,565546fc,76519248,4b95470d,50b97629,22b099ab,a5761243,dbf6e466,226e8e07,9b77069a,b542deb9) +,S(d09cd377,d64a045f,e1a76f97,4d701a24,67773228,3261aebd,74e02ea9,f8a30e7f,9f0942b9,2b702b3,d76ed2d0,1caf880d,41a342ea,ee06ae57,b90a924d,6588ffea) +,S(d030c72c,16d01a9d,6c2e5245,61c7e3fd,b9a469bf,ff0a7440,b2ed0ea5,e5d98b8b,c6b1308,dba4f981,16b60ff,eaea843b,fddeee67,ca1406f4,73db0f11,531f2c8e) +,S(56c456c6,d2c04a7d,441980ab,80b39a55,57d0c6f7,5706bba1,100c6bb1,e345a691,c5b2f0dc,2c735d0f,8ef10ffc,2753c2b2,825ce525,a0613189,fae34e64,26084819) +,S(aad5adf3,b505d1f4,28dd1b98,dd4fdde5,29d911c5,e0e5837d,75e51bac,308400c9,e94adf67,4f7994c1,123aa411,b790c68c,f55569f2,1df4b6e4,6afab87e,2777acc6) +,S(ac8cd8b4,dd76b8f7,4886b089,f18b4cb2,ca1d43c3,19ed034e,6b1867a3,5e6a0ef0,71d70894,f9daab15,7413f827,1cadcfc6,ffb71db4,9bcc81f3,c759d4f7,137ba96d) +,S(3964006d,f110fa45,409d7a4d,5996b44,93eb4150,f4217948,41dc5357,dc47ca1d,e4a11c6d,21dbd93a,f922a2bd,23f057e5,c2f24474,36bfd7d6,395a46df,3ad7cdb) +,S(2be10b92,27a312bb,74ea37b1,9bf910b7,723a1ff8,fb43dd55,1a0e1fbf,7bca56ec,19aa8afb,c886dc0d,293ecca9,4290b24b,755b2de8,c1dbc0b4,59052edc,c6df59ab) +,S(379c1556,2bd7f51a,1d219a34,dffc8bab,ccc1e417,1c38d342,a4c6325a,b5ad6ae5,47a1f28f,a6371df5,66dce223,10d95535,e7bc6734,7f20748d,b983fac4,2f185907) +,S(24054dc2,e675459d,2af584a7,d78110e9,30a36290,989dd4f9,914cf7a8,1fce9809,6572ae1d,3e05d0a7,1c4e06d4,820d16a5,3553dc81,a6f02a76,12b584a2,e57ae592) +,S(9812e6a6,f46ca979,ab7cd879,1023b32,913199c8,b850298f,a3bb4c8e,a02420a4,468f6eed,dfecd933,1bbaf36,986f9377,3afd963b,56577151,52a12b9c,88f937f0) +,S(46058644,6a348e4a,d84c928d,62c9de2a,9f6c14fb,95c83c6b,96203a5a,7f13c700,9dc55ee3,ca3d701f,e6759c20,3b18840f,4c873f11,57b21ad,90401e77,622d57ab) +,S(a8dbaf97,2d5b05f2,a44d862f,e4aed0fa,1cb877ca,639ac322,8e909507,bcbe006a,3db54c03,f082937c,4f98d38c,6141d0bf,253e6729,b83c9902,51ac4a97,176fa4bc) +,S(9b8b39f4,f4d91329,13324bcd,44f9846a,8b3019,22671128,74178009,391149fe,490a4f72,1c452e5a,88ffc693,90b0d1b3,4e4cae7f,2e0ab097,6b396a99,1c52c1d3) +,S(334681d5,a7ef46db,196404ea,9e501f81,7406ce24,27a64597,73e358ad,314615eb,2b23603a,1d80cd6a,9f04775a,52069de2,e328fdc1,37fe6b6d,6c165442,53ad6c0d) +,S(feb8e310,c63c6ebd,294639b4,a4cce42,bd5f8372,b7aeaa88,2023f0e0,29c32529,cb6e42ad,6a0cd780,aa57934b,86682260,68a45c63,bdf7e617,fbcbf86d,db43b213) +,S(f4a17bc2,c7334e92,dc923252,3b910a55,a8ca5cb6,2b3d93b3,fcf0f2c4,8705cb67,812b7795,1b24729,4b3d55a3,2f45260a,e7f4a9e3,d5cfa304,bb0471b0,da6e9dfe) +,S(8ec2ac7b,85514349,5496d596,bfcaaf4e,c330a995,f082324c,7e0479ba,4ccf181b,ea1588b6,7811d263,7bcb3bcf,5cf0bc4,70e92797,27b1c258,ce4ebba9,35250130) +,S(b1e6d61b,d9aecdbc,c9c4b6d,9e48c6f7,e4aa9eb7,7da3c001,53443c6c,4d4f19a,43af7b55,b2e2c976,8b1fdb34,48d6f339,1bc20aba,eccb1a3,5aef98af,b28cbf4a) +,S(4d83d2e8,210d47dc,3904a397,4db35433,1a951963,2d4e2e4,b69f2049,2f13b2be,7ed96c83,3874fc97,be45f1d8,8e5842b9,7a0e3bac,95400036,7c8572f6,3d37a6b3) +,S(1448e92e,fd51fc21,d6f5d514,35527f67,25f5c5ee,b0b29c36,b9eb6e8f,2bb20b84,248a338f,c8be83e5,2f91c9a2,2868973c,13336aa6,39e43f4c,ea8bbeb9,96e344ad) +,S(e23b03d6,9c2250ac,2cdcc7d4,4e0a218e,39d928b0,2585fe63,dcf7093c,924e4ead,8c69c7d0,4a8a4b7c,1997ef44,fadb04d7,80b91cba,13dee454,2effb8ae,71b9aea9) +,S(4cd1e35e,21fb3fe6,946a929b,9aebfcb8,78663224,da66af94,e5a722b4,32b5d7cb,6b1112dc,5e865b10,ba688780,32978617,eca892d7,730ca984,cba4ab07,7167e3bc) +,S(f3cebaf8,92cb7b0,27cb9212,3596ece0,bf25c6b0,d8f1dbf5,f2efb204,a0db647,a615ddeb,8418c013,91923b88,7bba5d3e,cf3c7172,efbdaab7,e12582bc,a968d8e0) +,S(4b8acd28,500bf88d,68337c81,33181706,dfe341de,7b1d5736,a3a85a2c,6d655e7d,be93d7c3,825a5675,84d6f76e,52f3b06,7b7c5d87,844f18ac,624c96e0,fd219bb8) +,S(8dc7ac81,d04e0088,63fd2de6,2cc68de8,3e567d81,85aebc53,d4771950,7ceb9fe1,62d4b64a,be7b1931,c47a7755,e25c803f,1eb14c89,2ee100e8,214b94c4,11fa9198) +,S(aa63343f,3078d48d,942bbbe,df4f2c19,a817c257,9003e033,7104e530,c1b89a23,277ef834,23a6730f,69c20f4d,9de94758,13befc6d,ce389bb,fe7958e6,6ea7b524) +,S(37de5061,9f301e40,8e9096c0,1a37df3a,dadeba61,bc217495,5d04d7a1,5121d30,7e7049c,33e40b96,6a136516,c005597c,e3f6aa70,d6db4c31,f5732fbc,e538898a) +,S(6d18cf55,506d59ce,a3e8cd44,f347481c,3ebc6682,2f91445e,11f2c0c,45eb83b4,e930e9c1,ca8b73f4,7fb9818e,5d4db8a0,220f7ba7,ce807854,c8ff2af7,b8a30cdb) +,S(77d85660,6de7dac5,dd4203c4,90152c9c,f70243fd,eb1d1c0a,5b797b39,16caa7d3,3f57cfe3,9b37d550,c9db0fc9,4b3c0e3b,1a2722ec,f920522e,8c37d848,f59c659c) +,S(5c2e69a6,c44b5bb1,c55dc8b5,6f9d4fb8,ea56450b,d69d9229,670e635d,f381bf16,f082049d,a69ca9b,a2821a8c,2fd0b46c,9ec21af2,4c34b049,f1af0126,75a3588d) +,S(329c01f5,66d925b,251944ed,92beb06a,aaacb98d,89b2aaf1,918ce400,b5a393ee,7e29b038,427a0fff,6ad50c80,aa49252e,e21c2c45,3d4c72a9,c3cafedf,faa57abf) +,S(4c2e631f,18b2dfa4,37ebb401,771d7b0e,b670f4fc,8546499d,f62b49bd,629525da,8a95ebfb,87423fa7,4c131432,6b7c204c,50c6c2d,a3f85370,1f789ca3,fe9a6f9c) +,S(fe121b93,d254465,c7f7cf02,ce10a575,d3808ce4,c6133fd9,392fbf1b,63d03fdc,33129b07,7bda4311,94fb997f,9443a0ff,e59438a,f360b635,2a80cbce,a49e0ba6) +,S(323ac27b,1cdbf3f7,74e20521,f1e74b8b,2cf8c5d4,4180316d,a532ae61,2f784c23,21156108,f6a64ac5,888b15fe,834ba9a5,c8489e16,f3d31197,bb296b2d,3fc3dc18) +,S(11478f62,fdfcb1e0,3a5f0ed5,ce0c2101,eeccbca1,e5934d37,41b1a8d2,7afd533,a9f79673,2fd3ecc8,644cdb17,6d11527a,aba8d0b2,985366c,70d96999,ec5f9153) +,S(9f0909b6,c9d3c1ad,eb88acf3,aed5a6a6,bc8d82b5,767896e5,e7343efc,20b9d078,a5161ca6,c5c95d64,dc663e30,b8f65234,61a579d7,b99a57a3,3b0f3844,e47db181) +,S(4960a875,32a9ad42,299d8cd1,a1af80bb,2807acb1,b52f1711,c55957d3,a64a6b9f,578e51f3,f1b46628,eb48f54a,93f82f24,4bfc6202,eef77dd8,cd6b90b4,de976625) +,S(675c29c2,bdb265e,5490951c,bfc9f73d,d142d536,4b5ec668,54b582f0,5d310354,22d1f669,3d82de84,202d4f9a,186bdfa6,8cb8ad5f,9da33a49,83229047,e08bd6d1) +,S(c4096cbd,6c75d0e2,6a922177,916ab32d,a9053adf,ad849d36,f65b7c9b,107ce605,5f236b47,2ae3c979,2ff61efb,9633ae05,b2b97e51,24a3c2,94f5be53,95c2bb46) +,S(9ea0d341,ddd05401,f01205ec,2c754155,b1ddd460,1fa3789,dd80ed9b,3b905c0b,3bf48101,97e7d0b7,6f3692cd,53989764,ba7ce059,953f7b71,7e615c20,da28e69) +,S(bdebbed7,84bffa33,72a6edd2,d9815b0d,637367f2,de3768c7,b4dd75a4,32fb92e4,5ff3437e,b62a9b62,dc16af10,5a20941d,297a431f,ca2b0067,6734c4ae,cfd0b9c0) +,S(a486fa44,b46e34f2,d6aea82c,8f554210,cbfe674,77b560c7,bccc7d6c,9e910932,1ab7e36d,8a15e284,8a3caa0,f54ca555,b8ad5baa,7f47fca8,3231c822,f897317a) +,S(4463a0a5,57a1a926,aa204376,a20aefab,66e7abb1,18c7f769,fbd1a7d1,29cbba08,4a823aa5,ab7b602a,704f01de,20b8ad13,7dc08152,25ceace0,9a9dab69,d034af0d) +,S(d6e08a4f,c45e8dfb,ab713584,d91d1d8,8cbdc5c6,2eeb4b4c,593a73df,4d825ac4,2cd85bb4,77c0d0ba,5071ae8f,c0fe2dbd,8be98d9,622fe506,c59800cb,5eb4c55f) +,S(b626e299,2a69cad4,e6076dca,29bbfd34,546d31d0,a4f8b656,a433fa87,f96a10f1,6df4b2ce,ba919268,f1568632,55e27655,62ac5e3b,8cbbfd34,3c656f43,43cb5bc6) +,S(3619e6eb,74645070,b2dd6196,5fe4d25e,25a4dfeb,619e3b05,7e31a566,947139a5,964b8989,ba156121,9d36c3bf,29467c7b,79940c3b,450c1431,1aa0d725,1282093f) +,S(b3529b5e,6718843f,c40a3a65,d5330961,41e5c060,e326aa84,7ccf7f48,c8bda2e9,49e6e0d3,7ce1bf45,e9c595ac,285becf5,31111e7b,2a67b057,9d4fc552,59c1b935) +,S(e51f0067,5bd7145f,fcf85527,dd247ef1,4a199778,94035598,d42afdf1,2fa9e05b,d59aaf3e,8b4d72eb,4523d5fc,69b047e5,7d2e175f,30eb6c8c,ec729cbf,c1b32666) +,S(8a87f066,f64bc468,d225eb6a,a0a7b54b,91c930e4,d4520720,1705f831,cde79b28,a92a5d95,e0057c95,b219062f,5d0e4277,249c34ac,6255113b,b5eebea5,66800227) +,S(d8a81015,aa878ee5,a69c771e,bf88daad,3a926afb,b8aef632,cd7d987b,fd310b06,af77f7e8,f276ed4e,963e3a26,2f3942c7,ec9f31da,199ead3,d5e5f53f,e20acbdd) +,S(88c3fa19,4f3f4d93,dbe5b8a3,865d28d6,51c9abd,519af4d2,c3b743d4,ce0cc5c1,104caf7a,f9ff822,7b3671a7,e7745bee,26b5deda,9982b9d9,a9d648e0,760d8f8d) +,S(f8738725,3434b0ea,f05e9c76,3c729a8a,22070111,6c5a6484,5532c3d9,41ce648e,a8b5eed1,d4ee7913,b69f6627,d3e1be,4c286e15,78167201,46fc9e21,786f7bd7) +,S(5fca538,5afb021f,94cca826,5689605c,7b35c8f8,dc8fef60,6b18420f,909acc33,1d7fa51,f5c28bfd,eb1f9a52,723eb2bf,c5b4d078,d5d4b639,2b791af5,d5b2b3a8) +,S(47484548,d4b2acd9,bb2cef9d,bed4bd0f,f1fddf4f,e1561a51,891464fa,cf5007db,ea61e154,f011cfe0,46fa2539,7fb444fd,b93e223b,ed882bce,3ddaa3c8,328f44a8) +,S(331f17ff,b14d43f,ec69a6fe,b41a8021,dd8ef56d,2540234a,b466ac85,e6c5b8f1,ba20bca1,8d774731,b6b64a0f,8a19311f,37d8c061,2c4699b,68d569b0,9eec144b) +,S(6aba62d,200bd2c6,4ab88ce9,80530e56,5b8971c,f9c427f1,5e9b146d,dbdc68ce,e4c936d7,d7d98919,acd26ef0,cf071f2d,fcf65fd7,78dd8c5b,ab026,e9f832c8) +,S(c76b6c35,e72fa19c,621022b4,d9ec6ece,c0cfee8d,c73254fc,f52cbc69,23ca19c5,5b0ffa7a,48ee8599,9b74d0a1,d7fa0289,b49dba85,7b21bfb1,ee7ba831,fa13efc9) +,S(c056ea3d,43f33df9,b01590fa,429c14a6,aaa438ed,415254a4,4a93854,ce1bb77a,d5b194e3,2337a9f1,2c479e7f,576a571e,58355a02,8ba0231c,c337b8c7,eb3dca7b) +,S(3d688ccc,8ddf0ef1,137bb897,e6b8f3b7,7df652c4,93cac3a1,47e88b3d,bdac938a,bca94788,4d7ae1f2,960daead,111558f7,38b6bc9a,7af3bb4a,691af22d,4d5879fc) +,S(4faffaf6,69ce1180,a9145f0c,df6fd834,c59d7a9f,5f2e49cf,3924b33d,8d2a179,9e015cac,2dca2ec2,5580c16d,8c910abb,dcbad872,79bcc485,b71f5561,60159d2) +,S(47578e3,7cd7eb78,6b5a44eb,3decc7c4,e8ba0c7,6699ef61,4ac30579,a24aecad,948ac817,a6bee00b,c68eab83,fb628ed8,7fd0066,9ebc8569,45eef8c9,67171651) +,S(9aade275,3eaa646a,24ad1a35,f74887db,8c72fda7,77b59dfe,103e1a95,dc618836,b651c384,8f4625f3,1e6e7a05,c94483f,ceef2fed,dc7f4256,87e0373d,d02bca96) +,S(b1b0c3e0,b1c6ee75,55a81852,447b2bcf,321c9b9f,629caf9a,276133af,63aed711,493accfd,624e6ff3,dfc1d0dc,aff17113,c2c74167,58cbd571,759bab24,300ac827) +,S(c557758f,b192a058,eaec5762,ff391a9b,2a0ce462,7bae01c,156dcf3e,bf2a8ff6,1d4e9b53,d209e195,9f10f671,b1bfdbf3,98921284,a7719766,39947969,6d1bd3b3) +,S(73522ded,5120ed4f,b49b5ca6,df5a1b6,edcc082,48df4d07,cc9ad923,2b7b5e0e,47569d94,cdf0270e,d1d299ce,d5bcfdc7,7f87db4e,c9725a96,e4388cf8,dee08d74) +,S(16571c0d,66328963,2a3ae46d,fc2bee50,fd6fbc0c,f0ec73ad,72bb9c2f,e8323506,65de9d86,9e001c60,ced57911,e7ce6150,a936d684,d759f143,d2224448,4bec68d2) +,S(f5fe5564,2eb630a5,c860cc8d,7c9ef86d,b1810d2e,82dcb343,dbe2f958,98e5f090,5cee7a1f,bea9dac8,ca340dcd,fc2c097a,eec2dabd,d7ed7504,e20c913e,9fadfa87) +,S(ef09db32,70d09043,43da67a0,b87cedaf,7aece017,58d78591,8814e3ca,396e3592,5934f805,ba246e9f,965c6161,cefdf4e3,7df14271,2ae076ea,80ca239a,c7b675e2) +,S(886cdbd7,27d2f099,9852b102,bf201ed2,5e174622,f974b0c1,3edfe523,373a54e8,dacb328a,7fca6e5a,e5351825,564e4f89,5166f687,38d46142,6eea7b09,dca73b2b) +,S(b7d86bcd,4f7bf2e,8529ff84,88d9f3e9,62071308,9bbd91f9,6e4ef82a,ce237cff,c6b0aff1,375a547e,a8546dc4,17574843,3acf2a4,ed0d002e,e32fd88f,3b702f0e) +,S(d7d171b2,8132ab85,30791059,395d94ec,c24f5e99,67bc6c4d,22bfc7ba,eb388c67,983770e0,2421e2b6,55d3c135,1bb39bf7,7be39682,97088744,bfe6543d,dc1a8f8f) +,S(ffe712fd,881e30e7,229f1cfa,833dad90,f01a1896,c1493502,a429080a,9794b1be,f4299e03,75d084a,10b11ae5,8f2fa2be,f18b037a,53165586,cdac18ce,54505da8) +,S(563c92b3,3226951,cd7cd10b,3f7b35c7,dff3f0de,6f03d66,9f664655,57d13f7c,dca1eef4,85bef41,80b0ccfb,2416f948,9bb21094,854f5f43,769cb37,33ec10c1) +,S(b8e76ef3,3a2cebce,614056d7,efa47c15,dd52c228,66a7d3dd,9a0d4d64,68f32437,4454e79d,652ae799,a3a539ba,42619a1c,3076ccc2,109dc4a2,2aa41a28,918651c2) +,S(36db2304,f60703a2,df2e429f,b8a99841,7b4a4f3,e08642d2,c5675460,aaf1c971,a0536e8f,5cc30aa3,d9b859ee,e26b1abb,ecf7f9b4,8c8fef0,f842fc9,a684b5cc) +,S(c5d4e51d,1521637d,d6055e52,9e9ae2a4,d537c1a1,b7c6a314,f9d558a1,88d9a5ab,c841eeed,6a13782c,fbf65b08,c6570994,aaf7093c,4b48ad0d,e04db33a,6feb3f6d) +,S(50c03dc2,985859f6,ffb79ed3,f635e17a,b0561533,600af220,7cd98f9f,71c4bffd,c68c8797,a7ed229a,f59a2bd7,451c748a,5c425528,8b7f6b0a,68b64a77,d7137720) +,S(2806d84b,3e7e6f9a,2e10ae5d,cf5bb0ef,98560691,71d31ff3,3645346d,f08333ef,72f23443,38e34ccb,4ccb5ddb,f3a6b58e,bf8cac26,4243785e,54a9b503,c87b429d) +,S(40d70ddd,1ef58dd1,c43e33c6,29840fee,82bb9c1b,e222b53f,4c58952f,388790a4,9b1a9d57,b6dd9932,338d170e,af4d5516,e654685b,3946930d,96b2a1d7,f70770d5) +,S(8850ec32,4e71213,bd77b193,ee21da82,ac733804,17983905,d0156608,8b87c835,aafff7a0,a9160b91,92df58ea,a65c0716,961480b2,b0cb4d3a,7d637f77,ddc160e2) +,S(54951509,bd7c29f4,77f9d4a6,2be485d7,de291b0,6a308bd2,c240cf71,50ad6e8b,2fdb347c,f2a23b9f,a3a45c76,44cc1fa9,b1d8f79f,77c02f27,f136c732,c7ef2722) +,S(9f5ec355,cdf8eb4f,be5af1ab,70a3e7cf,1c3d3e8b,e643621f,acf8f69f,af7e5d44,b203dd5f,b38b3550,6fda94b,ada1c4bb,12b8be5e,92bf8a58,4886f2ca,19d3c06e) +,S(812e4a9c,1bba9e52,8cb5e606,c8b326fe,8b72f0e2,3062837b,bdf371a2,2ec0b3da,2ba7b5b7,14a9ae39,c62bd36a,1ed00135,5d98d248,9ef90f24,d10d1c58,f8e222a1) +,S(e6035ddb,cf85616b,540ff16e,cd5d7fd1,af52c6f6,2a26ec36,c5c1ca86,2a3d924a,a945389e,f687fcac,6f918718,a1f29f19,173d3104,69c5954a,d6cfb5df,f01eec86) +,S(d788a5e8,d771d471,b7169693,86b2339b,2643f129,a6b50bc6,321e752,6a033446,34b85622,5095783e,fa57fe32,a7d91b65,c0c9a42f,79fe30e0,b2598967,e97d3990) +,S(663733dd,29374f9f,1db5f11,6fa32b56,c8ef42f,706bd802,5615d4a4,77c6f41c,3585d45,3ae0fc59,1614e916,a1400b79,85b59f66,6e2553c1,394ec26d,d078676d) +,S(5ec6e728,5ae1413,3dbad4d1,19e2e3d5,6affda33,356146f0,a5ab023d,b323ad9c,3dd241bf,cfc6301e,29cd609d,b1a0fca3,d35a56e4,668de9f6,45c23d69,c0884579) +,S(f18fc442,1fbb66a2,7c336647,1459717c,87532be5,d4416cee,e4a674a3,2cf8f3c5,d38a0881,3bb33df1,fb4e83,6686c0fa,26847e5,f7580de9,b4f229cd,1359d560) +,S(818f549e,d9bcfe1f,14b8d336,21342465,7dec0dfe,eea1d719,20622442,39f5345a,37ce611f,cca2f448,45c1a8e9,d7f4b3f8,48b24c5c,2b9f5368,8cc2c8df,846602ee) +,S(75e2c791,f98e3fc8,2a74ee3a,532e8796,4f4fa8eb,6421aa64,17a5b00b,1edce942,51f2373b,a4951362,68aa17c7,1160855c,7c4d37be,222a8b26,f2d54cd5,37e5f6b4) +,S(711f8db6,4c0c6d31,daff4ec1,f9937730,9b44de59,9f4b9119,9ca6836e,1e3954d3,485955e3,432ac82d,f3170fcf,7b3519cd,6e4dfbba,170bbeb5,b75e3e7d,70caa4b0) +,S(63502c26,6f755a1e,4be2104e,e8ca9c2c,5216f50f,e21e003a,16071bc8,df3ba6a5,a5c829ea,c8fc3f4a,f55075bd,afe77977,3954b88a,f1f3a8dd,90f28aa1,49bea942) +,S(2a677459,ccfee070,1b5bb82f,d2ee57e6,13f5c3d6,3927938c,92d10954,c2850872,ff6e9798,5c5db0b2,9bb1cbf5,db03e0c4,401bbf28,eb39e053,714d5c5e,ef7cbe71) +,S(68f85f87,78fb69a7,9db4a22,3d7faf95,5b359bd0,5f230d99,f051b008,32b52cbe,dc2e949,f4fc3189,c4f7b771,f8b56b85,ef9c65c0,b3bdf89e,405d5f3c,ffc92210) +,S(7ee9d5b7,3b542036,509fd8b9,de590b24,9e9883c8,6f4bb90e,1c2904f3,d2b74ade,98122413,241cf205,f91c6977,b925ddd7,4920636a,9dd67828,2c30ee,7343e62) +,S(8447b090,cdb19271,db368023,d40e520,102b5d04,79eaf391,3817553e,24aa33c8,25b43fe6,55a27481,c02eacd3,9025a523,121d02a5,78896a78,c14a8c21,f7c0bdb0) +,S(316073b9,3f1550e6,b7951f56,90c5ef3b,e45e622e,77a2f268,c89a8b6f,2816a645,557ca5ac,2fc70ce8,c3e54a4d,b31d5c77,a1a6f38a,18646caf,6a52db31,947624be) +,S(fae2312d,a2ef21ac,358fe949,5c011b18,cdaa8ef1,c99284ae,5fc1eb77,4836d6ac,6f3bf661,2d99e865,b0cee7cb,3fccbf08,aa948ad9,b29b4b8b,54eee8d6,3f0b76c7) +,S(280a2bef,5588dfdf,b1e1691,d3162aec,7d4c72c6,b76f23e1,2f8ce783,54f839f0,f00ded1b,c31a9774,a87be1bc,7e440585,b2b4ba63,cc0d9c73,ca7b4873,93683f72) +,S(3f43e77a,9b7b92c9,92b7e5d2,8c75444f,4d0609b2,8aa65ddb,86bf6ac0,bf7ccdcd,b3117903,bb3c0a54,bc6bd6b9,92b8d85c,ac267855,50075536,6cf70a84,4c72a2d6) +,S(3a0afdc8,387bfa34,87e53929,51e10e,9535500d,f6506296,46df162d,d469f2de,75697cc8,f0f690b6,e1f86dff,3f2ca53d,907d4cf7,c8ff324e,8b4187ac,c9bb29c7) +,S(3f972b64,209f723e,99a6e7c4,a72072a0,2789d0aa,8a23d660,949ea417,7970809d,7a482428,7a6bfd9c,afc26e76,9a02c5ff,9a7c053e,e63f2342,b32a4f84,42e47d15) +,S(938ac0f,fa73364d,11df1ecc,4b84e3d1,c21ff85d,71f404df,e8daf4a,e889b0b4,a1c09ed3,d526b381,dee8820,eda06a10,4e968995,64cb604a,63fba74a,45be0312) +,S(5355ed75,2993e74c,275eb9ed,3bd34575,631c9b5a,64e99071,8311ec8a,f4e28bcc,bbb1007d,680aaaaf,ac10279f,600f1851,c8188547,3091a40,ddf7253c,fc6ad088) +,S(880e32ed,70ba76c6,d83bda46,a4340646,b033696f,ab62e457,4e989311,fbf277b7,76feb2cb,8d10d5e2,406763d5,f696686b,8dcdaaf,330e4e7c,623cc7a8,6e0410bc) +,S(daf778aa,a2755b68,2b8beec1,14b74e9c,857ac503,daad6bee,bd6d11f1,8f11aa8,1ed85c62,710d3017,9f0f3024,d6ed6976,e38325f0,92981c88,fd4982ee,98a5f428) +,S(e5c3e9dd,75633d27,d19c0a4f,f3533f80,9a60b95a,42c8c464,1cf7abda,8fb474dd,f1e56af6,5c5c087e,ab303699,f20bc9f,71b7b7fe,16332afb,2517b241,8dfb0dfc) +,S(5d403f34,ecdfd870,977f3bf2,ffb274c9,6859c20c,8cd7afd,d116837d,c0096973,6b5be47c,70246cc5,9781ba70,71764d72,2335c334,443e5e4a,5ba12939,d8f6aeb1) +,S(50ba053c,25511f71,b35b4caa,c990ab27,993bf034,f3e55f81,3896458b,5e246b12,d2f12a45,5c7a3170,67690399,3063dab0,9f8a22a2,bccbe5b8,8a7fa2bb,f2291f63) +,S(385a80ea,ee4aa9ed,a07898f0,b3658793,9f290622,399c3a00,b38bf02f,66629cf,a543320b,d72ac6e5,d750806d,6a90b8fb,8cfe4902,46991eb1,6e6a6974,befcd50) +,S(98610b9,904ede38,6e69de6c,3d40518e,eaa669a5,23620a9b,276e1996,bdedbef,907755a2,eb6aa100,d0cd0c89,25b5ff8f,b88f72d3,61d83315,c4ad0d94,8a06b581) +,S(83f10807,d9640d3b,dfc7b0d3,dcbbf6a2,19ae215b,4754f29e,d4579999,191b7fe8,f62d231b,5095d6d2,860e69c6,509de2c6,fe719e4a,fbc2b5e2,489a6f9a,7293364) +,S(51d22293,927335c6,2f82b028,52759fd1,e3f287fc,67b6059e,74dca17d,4fb1c246,b9b803a3,b5145b4d,188b909e,23c8b126,f7184bdd,3128587b,e05219df,6c63745d) +,S(be6a6342,e5783d43,d2691945,826c37c5,3e8cc24c,5a09fc70,3689def1,4f465006,81c718fc,3fc15279,da9efc14,13ddcfd8,81bc7e4b,1c36004c,2008dba2,7c7ef000) +,S(f21334d9,c36f1284,a4bb043b,58b27070,448681d9,a82ae81,a4e8f226,bc790036,44851,3a87fd30,453dcc1e,b21e293b,f5f143b8,2cf2708e,428f4753,8816eff2) +,S(1558c4e5,af34463f,810cb1f1,b73bd27e,932a832,9253e2cb,419eafae,c9730508,cb8cc650,25e14132,3663f3f4,1a75085c,6921bb37,428a149e,2dd1fe4d,f4c917f8) +,S(1853a32c,8f6020d8,1b4d3596,a88e3825,b575a4ed,99072e64,2e090a1a,665d71e2,8da2a31c,b170aea0,e364aedb,b1861fff,eaf26888,b29405e8,9e3ed982,a03a8367) +,S(ef585cbc,f0f03bec,21df60db,cfafa9dc,2da679b4,3bdd590b,8cc35388,cccd323d,2bc5e203,aff91f6d,38592e07,82813905,f02ccdba,1daa7acd,d93f6d80,78c2f296) +,S(3f4c2e37,e1ea68eb,befd9971,424b3c7b,1fa45864,e0d13471,a1476808,b2fd5c14,678990ab,3d283b3f,aaa665b0,4f329b51,51b9c17,b54385e3,30de36a4,7e0eeaa5) +,S(2b001b8a,d557ac4a,181cb20a,b3abf2ac,59fc9b10,20b5533b,621b4119,e421693a,fe4f3007,f8d19db1,73e6f8c3,48b2525,310a328d,2ca0c675,8fa29723,82c6b94a) +,S(6589d1dd,7d5a08ff,8deb5b10,81fb0ca3,79c90d27,58ba0bb9,8d05bc93,452cd229,82409480,ed842993,4bc8dca2,3e000fd5,fdc5475b,192bc7fa,a1179165,9a8149a9) +,S(c233fd0d,f5d3835b,8e855316,276a6a90,ab4377e5,a3a3a8a8,3b89f0f5,27950a6f,8fe8e0a8,775a9a43,12cfbac0,85aefe06,31468031,86b8b84f,49422392,b4f6f3e5) +,S(82731a85,2a848eee,d6ee3f57,f75a2bfa,a388670f,89f6f6e7,b65b13d0,764cc14a,c00c509a,307c5e87,f1b09688,38e34a21,1ffacc9b,8a7504c1,2080e4cd,39117583) +,S(e21387a0,e5d8b1b0,5aab5150,122942ec,c9dde3b5,53eac977,7eea6d0,6d2a50d,c74de509,f90d93df,343c920,74ac5dfc,fc81c95,93354349,bb2810dc,8db0ff83) +,S(180871fd,2fa443d9,c5b5c341,4d635b8e,92780fc1,6d04236a,bc9a49,5b9fdc25,d66c7150,6008f37a,422014a8,bbe025c6,1f25e636,e2778146,59985003,ab14d120) +,S(b5a9de7e,ed112a8c,1ef29a9a,31156b90,d64dff93,4d83fab4,b44d30e0,bccb2c42,5675a679,a81c3faf,3b0afe66,ef85721,30315ccf,b0ff3d91,130a71f4,3539db38) +,S(9acce472,61f1e50d,f42baf78,c05a5cf9,8ce5697b,6d3b4d,40d011fd,aee7d6,fb7c413c,40464c69,e5756830,4325a79e,6cb8c831,add29e0a,95f88feb,9507a05c) +,S(f80ab79b,7bef7712,2fc7bc4b,2193deed,916796e3,67d85100,a02cc0eb,8b574e5c,c6d4d03f,842d8b25,d9b5834e,d6cdcacc,3a1ac585,b5d22aa,c77019dd,1d5c8f6d) +,S(b431e355,cdb4230c,3005845e,f60b24d9,25d81448,ec161aee,faea1f98,bc9366a1,ebcdadd4,ae230a14,382ddb98,552b6e69,7aebace5,5cc7390e,f69d176d,da41c1cd) +,S(7aa60b9e,8c93a63,51eb686f,46dca4e6,efe56edf,6c2089c5,93f6a800,6e75f1fb,4c81e2,17700bf1,e053e389,2e33e694,cb424800,b4068c98,328f00ef,5fa0347e) +,S(1a88250b,3aa4243b,7441d1a4,da37b4dd,d304fbef,272f696b,a72e7610,1286b30b,625b9d05,57d3815b,e06d8cb0,f056a9be,b33b7658,f459b3fe,3fd5f4ab,69b7a473) +,S(5b524eeb,49fd558a,2d34db23,cb5dcee1,6c4ca47,1eba9966,82dedbc3,aa2b57c7,2d5c2c97,56b7ce1d,735b163d,56e02bdc,25c8b227,2bca2d5d,bf252906,bb8ae50c) +,S(ae60e777,6d9fbe79,d24cb8b1,f756098,191550d8,433bc7d1,8920584e,7676d2c5,430fe986,73772472,ca11be83,eefc8678,b76c36d4,346a311f,fff926fb,158d7784) +,S(323a5e3d,9e29f668,d460b081,a5dce6fb,53e8d730,9c42f105,ab4f812a,62efb9d4,2b457b3,69483f42,16656d1d,3b5ea9af,da6216a4,47661830,c2fa56be,804776ba) +,S(acd1b5b6,591e552c,864e612e,d69429b2,b3db8649,7a5962a2,a8b36511,7a7c1c9d,e6131fff,56f6900,926ba772,92526348,67544d25,1ebc4fa3,26562190,8e6e88b8) +,S(6b4e2c70,817852e0,2a26286b,155248ce,f2e61e60,84742cf1,14ebf74f,785b36f4,8400951c,7a529bdc,2007130d,1cd5297,7398f7fc,d66e5a1a,1e4e8644,e5b893df) +,S(c2b2c727,d67b0a46,1f44cb91,48c34744,4e6a375f,80a817c7,1517969f,8084ab31,fed64359,ebf37b0f,998aa251,9c281fd3,a52c47d4,89051718,82481fae,c36d5f59) +,S(3385eeda,b5b2bd94,f794609d,978a0f86,2ec56422,bda0ef71,2207ca1b,904f202e,2808d2af,1db8a8ee,1c5975aa,31a9f441,b12a2186,746a474b,4907bb71,603d7443) +,S(800f6cd7,f2cb437b,8470c292,3fab4786,edce15f0,d4c52a82,33519c07,14c803f2,981f2e3e,ad11aa0,cde06ca5,9b26028c,23e0a88c,ec397734,ad0152f4,d4a37056) +,S(73aa0bff,3a9f286f,d3c103c6,d7bb6caa,ebfaf4b7,614f1f32,4741c600,eeaa2f3b,30bc529,81a9b983,cb89fe73,dd8bce7c,a54a2e3c,4fde6846,701f1da5,18c6f7b1) +,S(9280fce6,ab5c13f6,80bfdfa9,c3e7612f,86380498,9bcf29ca,789169fb,a178f2c5,4b96ecdb,c5bc2e3b,2fd397b1,8f7f5bb7,aeb6a7bd,db0a3b23,3e74f7cd,ccae36bb) +,S(72055c4b,bb50b9ef,b589be16,270d12ea,9f438780,e5eccb81,7dbf69d,a66e03ca,aeaa257f,c30a77dd,58574693,51a8623d,985ad705,aa1fe3f9,8915a6c6,f6bc7cb) +,S(f0f3cfd0,c771e3db,ba687c7,3fa827cc,eb8e887,12abc8e0,3085d047,e7c1879f,2c612e7d,8b744c54,f8f0c4b3,24fe10a3,1bf8aa5c,cf6e2e20,eff98153,a4936b33) +,S(97c78b65,70b0f270,6fac8fe8,ea4376ac,d8b61177,e5e7b3ec,67a7af9b,e6f5dcfa,1aeb950c,fea95858,a97da765,c3cb5941,1334609b,347c4daa,1279d58f,3be14c3d) +,S(b39ffa1e,967e6fc3,d493a9de,48b077fa,4b7908f5,33a73eeb,9b5c9efe,9e509e69,f55f3951,81ac72cc,d618c00,71c817e3,f76c302f,11219e16,f3b40e75,ea65dc05) +,S(159b9f7a,5ff27c4d,1bc3fcc4,d91b160a,1b2a972,8b1e7fd1,7351c663,f8e7baaa,b0aaef6d,86c54ffa,eba1c7f0,d789fd41,5e60127d,578c2697,a8380b7c,a4c4360a) +,S(25810fd1,8d4a4b16,c7d07a62,b626fc45,6dff76ab,3c1361aa,f729f7f3,cb85e44c,f4052325,7794bd70,ad295526,ab4b8b00,9252dd5f,33578f44,2fcd2219,2f6a2d9b) +,S(27e20a4d,5860a328,c499864c,9075881,eab36291,2da641d,6e1934df,473352b2,c1598cf2,888cb50f,e270b490,503c11a7,d3822a2b,e86a7b,65cb9499,3b45203) +,S(483f454e,517a94e6,6708f465,ba217b60,6d684a68,4d9472dd,685f3bd1,341448a2,c13b3144,d93b9a36,45d23346,c5dcb70d,d338d06f,f0c22aa8,2ba68a61,7f9ad11f) +,S(4f47b2f6,31734aa6,5ae4c9a3,c1532f2,67ef068f,83a4f266,e2e0a59e,be04e6e5,58f1f34c,f11b9cb4,5d33ebcf,3edab72d,6824392e,dd547a27,c0134d66,58d99d2b) +,S(aa78eb7e,835ce84,b4f1774b,8e810cc0,d6f42a2b,11c44574,24fb6341,7797db07,39640139,d957d47c,59cc7541,d3f72e33,ee9ffc63,2171311b,cf493ea,185e743b) +,S(d2598985,83c00560,11dc0655,c37580b0,31a3f1f6,aa5f5944,17eb0ce8,cc033d49,3641c973,9de8818b,a294622a,2dabe172,b6a83006,4d04ed8b,c841d11a,5af24b08) +,S(4f023ba0,ecccb74f,56f38f87,7435907b,f2d2b85d,59f7ffaf,48712a48,55e26634,f80efc33,b15d5125,b8fc35ea,393b6c3f,a2ae094b,86a6ee95,bc48295f,b1a6a456) +,S(9c86f08b,48abd097,7bfe13cf,a15ac8be,8eda4128,f7c143c6,70bf7e2d,763a1589,11511f87,e9ecb88,39eff453,d29d4db2,17d4eeda,c8468a17,1a152f15,c1c2df45) +,S(3808718b,72e95cc8,fffaffce,cd57e269,c5e6ac77,69d8120e,9130d8b8,ee137576,f40ebdeb,cf5eb722,4dae59cf,8ed8b58c,c614a61a,9e3ccee,db789fd3,31ea728f) +,S(8defd15e,399492fc,71c80a1,3eda0244,eb349f47,5c7dfb42,55dfa752,fcdda3df,d3dfa778,4353d0c3,b4fb0d19,ffc39631,a01786ce,e3b0cc7f,f9e4c5f6,7bf7a771) +,S(8dac8d42,5ac1d07e,3a805248,798fade7,ed99f9d0,c324bd46,6eaa8aa7,dc24bf8a,f232fdb7,923234fc,d8b2f097,d354dd6e,62e9d926,20d28087,d6410b72,aaef8009) +,S(87ce6443,f3bce6de,287178b4,f243c3d1,e45d26fc,6f811d35,329cac04,7fa90e1b,a897019,62414ab4,c582799d,77edf3b0,f0af0d4,8f70e875,fac33e95,39724138) +,S(bfee6bfa,bf2fb77e,9eb60a3f,8b7775ba,124a21c8,741af3b,d22966c6,a8fdf08d,29a1c399,541e4bf1,7f26f215,52fc83ee,cd2e8be8,40b83fa6,9c9ce5d5,fbba76f7) +,S(c30fda5,b553a800,2341a553,7aff72b8,44873af,8381b41d,aef9af2b,5cc2bec1,5ce3eab5,87d88d64,fa44aafc,ce34046,8a96f76e,65dd562e,7d14153b,439fea6d) +,S(5e7151fd,594119d7,c5cadbf,e1b419f5,4d922607,728d70a0,f1dd4d8,3400ed97,6a8ceea5,a51d4a7d,62d36816,ecbdd75e,4c64ec96,6257820d,73bd9531,ea108917) +,S(a9c8eb0a,66cdd5f0,f33d0620,8525225b,e974af7a,b50d47c0,4bf690db,ec86100b,f209cb9d,898731f3,b02a24bc,ff290cd4,a4371e88,f3aeebf3,29c9e1b2,8b8e0a2f) +,S(955e79d7,93669150,471b1659,52ee6121,cb804373,5faf653b,9468511a,e3a2e439,68daafe3,2a9b67a0,10ea3bcc,1a56c7a0,2e82cddf,120e6826,1de0700b,cf930d06) +,S(22d27293,d3c1cc6a,5b3bc70b,3bb7e1d6,bef24805,3c8685fa,c192b409,dfa34a71,c74b44e3,4fc855b7,53c4e42e,740dbb59,4d5d76df,b39de389,e6c837e9,639b3357) +,S(d19fcece,f74b1767,4e9d91f7,1487aebf,70d46e8b,3a037835,b2f4e8c4,2137abc0,5b904bf6,3dca0981,3ce224f7,494ccba3,34ca9fe5,f365ca83,fe9adb6c,4adb7580) +,S(6aa1722a,adc74800,d6609113,6bc6a6a8,1723c36c,524a873f,2a437c91,c2336899,8e97004c,df495b4c,63164058,321549ce,3d9709d9,ed667c36,9a4f1ee2,d6319d07) +,S(79bd3623,9ee4d220,12d07262,e96ad186,b16e3b6b,720d052,f736f851,b0ea6efc,a4b43db,f568cda4,1dc972c7,1c7c92c3,6a31166f,ad6b80fe,42df4dbe,f418729e) +,S(b5e02b2c,146337b5,67583c5d,3690c0cf,a1c7d820,14028c9,e401182f,a4f16ce9,4b9646be,3facaa70,e793516f,a0e8a142,1a819ba6,718d26fb,938e2795,9069e0b2) +,S(8e33e271,de2deb4d,6444d64,387f790d,14a2b685,4b38857d,d05af743,7a7403a,d82d53a2,c7a4a1dc,eaa011bd,3e0ceb0,e08d73ff,fe9d71f,c913d6e2,89ecc429) +,S(4ffef442,77dba780,e5769b73,feda37da,abd6ef6,2f5ec36b,74593ca,4c19c2f5,a8a30857,378aa0ab,9ef6162c,fbb09f9b,796755bd,67bf9d69,4a186813,d392f854) +,S(878b652a,633805c8,b58b0334,11b9246f,f7e42ed6,ecba6bde,fb737126,e9f57368,2cfbeb3e,d691158c,d3ae71f0,b4a41d42,148c9711,d274820a,d541efc1,56e85836) +,S(ef9a6a15,aee2aed1,46b99ee6,a79acbc1,a0aa0b2f,1b082783,dd40b106,9deb415e,9909e2ba,7fd53514,a1bc4480,2b49c7aa,cffd9cda,19c54d82,6d9bd08e,49e97240) +,S(d5c248d4,1551d230,60835885,5db0ce8e,c7814e18,c2d548fc,dcfac207,645bf37,f9c5e89e,7bf01f82,8cb78c88,c14d50a8,3cbeb45f,82daa9cb,3c3804c1,15a36f05) +,S(edbf25cc,a526157d,9676e614,81455682,6dad0c0f,96ec289,f2c5919f,57227d1a,6845488,be056456,4a833c13,70d37257,d0ca701e,f6e574c7,409dae02,ee99554d) +,S(5c12026f,b8e2e376,2521f5cf,cf9286b,14be80b0,dfcf378b,26fe6ea5,4ccf09bb,3d98d5ef,4e2c6528,7950154d,581c9a44,94b81a50,40ba9047,1bfa6758,66daa596) +,S(c27e6243,5056055d,614dcef7,f67338c7,ae728bd4,af3970a0,b434d2b2,e48e2d6d,76b586fc,703cf946,f78839ee,bcd28c56,9e372d97,856333ce,d82137aa,7d8525c9) +,S(a298c704,5140186b,4d424e8a,f98ee604,7f67603f,ab14a7e7,b96daede,51abaf8a,4dc70158,2a1b1935,4a5b430d,b4a0c21c,463b779e,ba72f108,5d7d638d,68108fda) +,S(e1fce957,82dae8b0,ac204fb1,9496a332,fdf40014,88ebaf07,3a62f33e,192013c4,40517ee5,d5786ff9,6aa2b50a,a77a10d5,e8ca6439,44f308a4,a264e367,1dd02f4c) +,S(e719bfc,5f06b800,8e4e49bb,62361544,1a2b0c42,f673f3a2,1e139bfc,b097d6d,f0c83c1d,83f5df68,a1e3929e,e18c4945,d14e2c33,4f9165e1,a0a462c2,aefd7822) +,S(77766a4b,a9d8cd62,840b1127,7e697dba,dc27c50,d9c8e35a,17f4c38b,50ad0a4e,5b3a2ad9,448327ba,22265ac,86c190bc,60b7586e,6f6e4554,b26b69ce,231b6431) +,S(f237721f,6215a855,f8660cda,41063690,4f2c9dd7,6260c292,597f28e4,348514b4,109daa1c,187b9f9c,ecae8c6d,33cb9874,46f5ade9,d57b3651,bccb9338,1acfef79) +,S(9408f5d5,e8891a1a,3cc4e7a8,a50dbc83,97517b3b,6c5af3b9,f1953f09,a67b3e08,1b82f212,c32f1ae9,c95f87b9,5ced2bf,ca33e954,32d9eb90,ed879ec9,59691555) +,S(b2837655,11707926,c9f214f1,3e90675f,883649c8,8f1660f4,c4f9f6c1,552a7064,89553739,15be8962,e6f03ca4,5bd5516f,be6ee041,519c4131,829b0bd7,6d1abfcf) +,S(ce42ba00,36b5f54a,4ed2a9dc,b6c0d29f,98641331,3f92f9c1,43767bfe,4b78f4a9,6e547292,cf35baf4,768c9179,2f706bfb,39b757d8,2452a802,4a7bd37f,e3a048d4) +,S(bb3da2a0,1a063a97,bec9325e,8d4af420,d3942bbc,42f0807d,8e9edce2,eccbcc59,7c28e7aa,bc39907f,ef58a19e,cd6e7b2e,25d6eb00,8da14d9d,5c559d27,fad70b32) +,S(25d84c3c,97f3a074,ea76f620,d6fb2691,dd3e9592,6de8eacf,5392c0de,36c490ee,5e0e7745,88c8a9b,7b91ffb,1ad6fd27,4153096c,9e759540,16f73a43,16d5651a) +,S(8baa3bfd,ca256f18,2e55a01d,e7c07617,7649942b,e743b4a7,faf39446,84d5765b,6147e897,8bbe15cd,171c2816,4730b211,587bfe7d,7e71811,7f308b80,d30506f1) +,S(507d6a0a,5b7d0385,11c65dea,8024c706,4d3b6b9b,287c7192,74c69797,21f5170,139f1647,70ea83ae,47ea8141,c3ae32bb,c12793d0,ce30fb37,2dc3adad,7f7bf5d3) +,S(7c6992f7,a059c5be,99b7354b,10fc217c,e45620f3,b4ff30d6,d640fd3a,26bbd846,964474e,fa63641c,2aa7062d,7139fbec,1f64e6a0,50e1ad03,2741a0e3,b5e0bee6) +,S(f62832b0,1bf65b23,14850750,9ea6f157,3d5e3317,bfb0a38f,cfcc6692,5a698bf2,d7314810,7b8fdfd7,3f6ce6f8,84f375bd,1546cc3b,8c75840d,3668c2a6,54c1ec95) +,S(aed21cab,d8e4ec36,2b4e2091,3be3c7c4,594f628a,cccca657,deff8b9c,6bd1ebad,f800ef3,833c7ffa,a8ade1ac,2f41d456,b880a205,60251dfd,f9cdd672,bb7100f8) +,S(46de78a9,343a9a41,6b91b877,aca94252,9e0ba8ca,b6c01f66,e06cdfdb,714bf405,c1441252,4f3ea73e,e12809c6,f19184d9,81f30b87,8df8bf6,6c89d98b,ed4d2bcf) +,S(2832b5b8,ab82e932,5356ae19,3043b99b,ba4b6591,a750a174,a6303b42,54bd41bc,c0363e03,3f59f149,23ece534,cb86695,a8275224,f490849e,249e63f7,34aba440) +,S(5b57c502,4b5c1621,77cabe39,b0f36bda,d85bd04,2736c7ff,9395f0c4,cbe43f9a,842407,dc0c0473,f1bf57b9,b35d84ed,b282ed4c,7adccc06,8530c8c1,bd20766c) +,S(b384da70,8063758e,825bf821,196b4a9c,814c45d8,a9edbaf3,dac4cbb1,c1c2f103,e6e661df,6400cc40,74f92596,590757fb,aa237515,af30ed13,df30befd,230fa325) +,S(36ffd991,563e448a,9b0a5da9,61a5466a,82a5b672,15ec8f8,e7300c5a,5c9a5e1c,97067835,fc17d47e,94187320,84d722a5,d1a742d6,4b513b6,32aed897,bb961c) +,S(8367e452,57c20367,e4e60ecc,33adcd87,5b9d142c,c6c362e7,f5aab34a,ed89d81c,fc7ff090,3ffab26e,d38a9e74,df43819e,b77ce2d5,bbdcf27a,f1f3bf19,948be121) +,S(f6ce47e4,8cc9296f,b40539e2,41238658,4719fb9,d4b1ad17,9c98969b,dcb0564b,368d2b6a,fe5edc0b,6f159017,5cd192ae,b524a606,7800aa60,930d60a,87950e1c) +,S(438c23e4,bedaa6f0,527d20c2,a725645f,194ccb58,8ff9eac6,5091da7b,f9fae013,54620a30,c7218257,dbdc93b5,3722a213,e28dc6bf,f8e48b45,6d6131a6,92ff15f8) +,S(1cf672f8,cc9434bf,7ace8722,85db5017,a1fa1dab,2eec7fbc,84e8492d,86bee7bd,d6d23d25,8bb4dda5,957ccced,b767cefd,8932b511,e2479018,16734bc5,b5cafdcc) +,S(47464e12,b0fa29b6,6e9cd157,4f7155fd,94305263,8af28bf4,4325a23f,3e1a2861,209a41d5,3bcdf566,5e966e80,84869a83,a2468db0,a1b19e56,81da864d,a2b05141) +,S(a9adfba1,c884c904,e6877a0a,9bbf73ae,c4ee223,e0b02ff8,717c075a,6aa964a2,ab16101d,a7bbc35c,73f371d4,afeb527e,b2d809a0,8487a36c,6cfae404,83f79dc8) +,S(2932fede,10600312,5ac983dd,659ecf95,824421ae,5f417f97,d3101c6f,c58edcbe,8601a743,e666156b,f2e34fe0,6f4cb11d,2df54fe1,7c842176,e1075423,dd76d727) +,S(5abf5528,2f87ad04,202b62c5,8ff7440c,64f9ba39,e6989df3,e31d665a,73a50216,71dc4e16,f2705c02,2ca1b37,edc5ce0,610b6f57,282d69c5,d3269295,5a1fabf) +,S(419495d,9a121cad,41887fc2,82c2c7e6,f359cbc,d24093ec,57399c3d,a801843a,9152e197,40295094,11afefc7,83990732,d5e6617c,d8e389d2,956536aa,f73e0c31) +,S(fca38482,ea2be49c,3c27979a,5acbb158,a902bc4e,226f7eae,4165ab7a,29fbc3af,1260735e,5fe62664,90a35f0f,7296c441,bad50a75,7b00e34f,28856a6d,cf46f5f4) +,S(bcf05123,3d703688,aca13530,55bc3ab2,d499ec40,8c912de1,4b7af456,55065d06,f32657f1,645690b,35484e63,a3456885,c16d4991,7670e71d,5f5cb65f,a5fb8bf9) +,S(4e70b42f,6391b424,b159cf74,f5fc96b2,68bf6cc4,a26658e4,79dd8a4b,8e9a92e1,8ba78811,1af31c06,77b24fa4,4b6ce356,66c595b2,3fe4fd36,591b33f7,e53b3688) +,S(3fe853d7,331c60ea,c213703c,a7628dc1,3cdb83f3,8a25ce6e,1be84f0d,e921742f,fb7dbb77,c2c6dc13,6f596154,f24dd3,f27b5125,9b60476d,b230e54,5ddca5d6) +,S(d803377f,c3cadd40,a2aa810,4e97641,ca42f582,3ccf65f5,ee726349,f648b9be,6357b84f,281a8080,54ab7fbf,ecc113ac,aeed2118,5ad12900,d824719e,8fd6fe99) +,S(5ddfdc7b,6f9e7162,2b7128e,77fa5ed2,90a05114,d6d8b845,94106c9e,70bebe1,23eaced,fa1efb7b,fae74c81,a1d03066,714b6dd9,1198e1e9,d5911ee4,55cd76ad) +,S(5f150243,c964948f,e91353e6,b12d167b,7913b46e,d7214411,5bc4cd4a,3b6f7dd5,36abc949,7a2fd102,14991e2,ba360c4f,b18147cd,955754e5,71cdd4d9,b8af903f) +,S(24b4fc97,5b0c4429,7a4cc89c,2b127eff,539f022,61544e14,97969bac,50942647,bd3e3fdf,54ad07d8,5faf8881,9014a77b,11d96f2c,a43cb8f9,a823a257,9eb5c207) +,S(a020eb35,5556b5fc,9de5ba2b,28644187,f11b18ea,ae61e76e,1dcce55c,e42202e0,9a71ea1f,1ad2f457,16b667c0,a982e2b,9765ac6e,beb71880,27e9059d,56639f66) +,S(60b79064,f7173eac,60531de5,961c47e3,8a224c78,ccd58a0f,86f6afda,e1f37a68,3ad04a4c,f6a47d6d,6b9fcbae,d8b54a7d,3437e4e3,627256de,cfc5f38c,490786b7) +,S(835cf1f2,b57d1e54,4ac2d915,9c8e3fdf,d2e233b5,d1109685,1777b7e3,a1f7d60b,7d23dd35,136edb13,bbbf7733,9e1c6e01,a7112f95,7c929b16,1665ca07,f6a84b31) +,S(faf74350,1f1edad5,2e1d8ad,e4b319bb,606cd7de,3188cdca,b1d39527,837f77ed,dbbeb0bd,bffb580e,4b9a0fa0,39b7acff,fbcd11b,85751476,16d48bdf,fe21bcc9) +,S(396c6fc3,e072bae2,3e7f74ed,f121271d,44091a5,d3b2a762,a39dd77,d2de938,5de522f8,a143544d,4cc49940,96b8f54e,9fb0e076,f46aa479,9e99d162,de6fa667) +,S(f8ab940,ad8df2ca,1c2622f8,8ef20c,ae8e605c,1e43b684,881147ee,d44ab88,99fe5281,fa7427ce,c9857163,f804c429,630d28f5,33e451e0,4063e70d,ddbff796) +,S(a6202868,af6dfffc,1e122219,a829c374,8197af4c,95901e78,75841b46,bd772367,2607a20b,c82a49c1,4fa54eb6,f8d68d8f,fe9c4fc4,d83b0e4d,145f7bab,5e9af45) +,S(b12d1993,49a98616,90764484,23a4fdbc,cfbced5f,b76a2bda,4d7c4984,7067e41e,a66dd4e0,ac6c8ab1,29045eb3,f7014449,73fdd555,7001b7ec,99c33d,c2d75e31) +,S(8dc8f55,b4990f5f,c6cd3b97,b1938304,9ae0a734,5cdc9c64,fd67bdc2,15eb3b3c,1be7457d,62cc8fd8,cbb54cc3,88722f4a,c00ce438,c847c2f5,fa641119,e5435d83) +,S(2c0b7337,d1db9e4b,7d521c4b,36351f65,f128643d,add0c53b,1b6d619c,658feeec,e8a27b9c,eb7c1219,f7bdae62,c07cee15,ef765b95,3b082d9a,d8b99005,b39bad53) +,S(891fb4a2,50100689,a48a0d1d,22414ab2,b17ad692,bb5f0d0e,66d06c93,da3bab35,41685166,cdf43c13,be93c03b,c347f3c8,52d06c0e,661a4c7c,cb53e24,e7260f6) +,S(4a3379b1,511c440f,e7213729,de668ef0,39fbccb6,1f5bbb02,ed99ed3b,69ca1738,b12a3dc2,39e9191d,a89d75ee,db44ce88,17b3bf03,d4172b00,39d1464c,a3ac0f6f) +,S(b8b2a7c8,54936bfa,62da360f,83bf8d65,7dc58e3c,1c8780d2,2c57061a,5f815521,8f922c0b,7719362c,25ac7001,252a89ba,1cd4412c,17c2b021,c065a3d5,f6a2d15b) +,S(9066fe19,d1dc52e5,7a9341d,77cf73a8,2fb56ab6,22c97a7f,f0191247,db9624fb,23d19b43,6ec3c575,d81d4929,eb6789a4,c281f5bc,abbc896,2153e7d4,711baf50) +,S(bf9ab14c,19c9e9b1,ca1a18df,2b5b73ee,9f32c8de,6e6757c2,b0534d75,7cced8ec,ec969923,3c3863de,aa72418,837a3af7,85e79375,d5bc91dd,481f174,e9759c0) +,S(68b2686f,9c654a02,225b7e69,e8eb7aaf,78c65686,e885b1af,10265e35,316f9d03,1d3d7504,846826bd,8554d407,739272ab,b6b407d6,f4f7419a,f284b81b,f14da9c3) +,S(20dc8385,5251a21a,94c989d3,92c9f36a,4d3bf669,bf7bda7d,e0427003,710bf2fa,217e6ff,713d329f,f9080c4b,3608c877,975d6794,5623e24a,974760f0,95aa749f) +,S(f0beb49b,555d998c,a39859bf,8c59184a,5c822e46,9a875568,1689a1ca,b5fd0368,e0e05ae7,a23ddf94,ba33b3b3,a75d3f4,2e8ff7f0,160c32f5,3bd08b40,72664aac) +,S(8f1aa973,270ff9eb,a41ad8ab,f2cf4c44,16ddc1ca,dc8a62cf,aab5a3b5,c4a0ee57,90aa3660,e3409b17,a86a441f,12f6eba0,2bd6bbb0,2b9a0a87,71e30a6,595920ec) +,S(c71eb135,278dc147,60cca847,a934b880,fecd43a8,aac9dfb,41382283,928a9957,41667f77,485281b8,89307ad5,decc7f6f,51d23ac4,7e71b299,a9d8715e,b6003804) +,S(e900726e,50d66a9f,37d09df5,d4965c5c,fa904d3d,bba1d180,b0fed651,bec41c81,d520aa30,db036f40,b34e64f2,cdc7d7b3,117f7725,786e9d5a,921c5f09,71028e39) +,S(940ab0af,a15952a9,ba3a6d6b,720efde6,58d72dd7,4f87cc3b,edae63b6,123fa38,fec6d747,6f788a19,b85e443a,a49116e1,6e5061f0,53c40702,f8765d28,f3bfcbcd) +,S(9a13de6d,643e9866,4df3ce9d,412c5ce6,a03ba46a,640c6be,8b62e70c,a8c76949,42388296,6c2d8d87,8b4c914d,4bc6cbc9,a4601630,2eb6a499,6103953,6926dd5e) +,S(438429b2,b31129d9,4a86b149,7d7f62e9,b76d6a5d,bde09d6f,256f83ba,76c577c3,e4360186,a7229be1,b33cb600,be833bdb,b2398e98,7c46c6cd,2e44f932,5cbc1c7d) +,S(3f63b25d,66d472e5,fac7b524,e4300e97,c8bb59be,6a3a8f01,8c1677c6,96d02605,4587042,158e19cd,2bd19bbe,5cff2c69,d9971aa2,fbdf649d,44c95f3b,50ca39dd) +,S(661fdf7,17c7a520,a384f90b,98dedef0,47afe5ed,6cfbd3d1,e1735c5a,bb8cc0c5,bd9a243a,b43c0e19,2592f00e,a52f820f,b83b7433,b1d96549,d9970293,7da80abd) +,S(b9c1bb26,daac6af7,d0c27c36,7ea2d4c8,c999d7c,75bc58cc,279c5f89,5ab951ce,a4d3bf34,a42b86bb,7c66c5b2,eed5d7f1,b872d17b,b58c938a,767b87eb,1b140f4e) +,S(cf5ac4a0,fc6cd9d8,50aaf473,3efd2bb9,7d9b23ec,bab5d099,9b11bfa0,b127e8fa,44926316,c37f1718,7fa94fe,3a62caf5,ad465d77,fd484287,2caf1605,f91070ec) +,S(aa52b2af,ab8da32e,3b882c57,ff0a34fb,749caaa1,b3c29b74,13c86471,beb3b422,4b562728,4a7be595,1b68df35,e320252f,73326084,16c60244,ac4e3ecc,c0859ce) +,S(610f22e,b3aa08d0,a9f2909c,546896bc,7926b056,7987217a,d347f183,4868211c,a52e190d,f35fc4b3,19571e6,166eda3d,2dbf637b,c27746ea,c1bc3552,4819e6bb) +,S(13f24c3,a485a58c,e0454330,79512796,db65f15a,4265fb44,acc3cc34,c51a6d80,faccbfb6,18e069ff,3cdc4327,cf807366,f07976d,b24fae61,1a44984c,7f3bc3b) +,S(15cebea8,49279b29,cb0112e6,922c5a85,caeb18fb,415cebdf,92285d9d,a0eb0f24,23e5ccfe,158ff9bd,539af7ed,4a77b1c1,c36de452,8d0c0d05,821e89f8,e075d833) +,S(2605a18e,fb7d5367,dc41b1d6,24d61a,cf92e0c8,96f29a5,5f2dc872,4d97f6,8d6a6774,f111b7ec,dc58ae51,80ad6fd2,fd6d674c,9402e2f4,f944bd50,5e66d375) +,S(e588e272,a78756f3,7fa36d6c,d35b362a,25cd0513,3694b56c,33d0b05c,be7f9995,15beb983,20b84296,9b8715c6,ad23e53e,115425c0,d071917,66e56ffd,5472fbb7) +,S(80032522,f264edc5,b6b205cb,f79ca7e,3a02cc39,93458b6c,cb98750d,bd6b46a5,479c92f4,fb4e1eba,98f8b93b,5aa9725e,fd2c1de8,d4c3d043,bca7183b,851a44a8) +,S(950c040e,e1a581b5,70501308,a21287e7,94b525b7,f916d3f3,c166a2fa,1641bfaa,e43db20e,911d70a6,9f171725,f760237a,52441a88,dc385a75,1e4ef1db,b738ea71) +,S(e899ff36,423fee57,2e70aeca,db8bc0f5,a634b9be,282dd875,9db5500a,86c391fa,7ed97b0,dfe6b68e,26710034,f87a911,88611790,cb18a790,a0248c7c,b43a9bd1) +,S(d236688f,c206b7a,8f8ce5c7,66e19fb8,6a7415d2,9c57845e,8332a5cb,d8a1a51b,72f2359f,e3d54a60,fe6d6508,5183b525,d5098887,55219113,adb05c2c,656ec9e9) +,S(8d3d7c71,da4b2f24,83e458c5,85c628f5,430eab5f,ddc2686a,e94e2fa2,119dcccf,33c408e4,7948f20c,bd79c22a,d647ff1e,1f435c03,1f594aad,82778f58,1f61178f) +,S(320f137a,e8918199,51a542ba,5d1063fb,fee4b750,c56168a5,87d7fd9b,b72651a9,b840546a,e2a4e1ef,32275a02,153bf003,8603698,a8c5e232,6795bcf3,d3c402c5) +,S(9e8affce,3fe6b259,f4568607,2d46401a,7546c87f,9a46e0de,8ce577c6,1881352c,d0ea3701,d83b7f7c,260ebaf0,97236525,af8639f6,c53ecf92,73e77bd4,c29d02f1) +,S(5df465b8,1d353987,293c915e,a24121ef,daf70ff4,9ad2bf53,9bec72b3,c61eef64,3206c5ff,5ae4c841,58c193d,40f46083,8b38047c,f33c3e54,38541a7a,d5e690af) +,S(999cd326,a18c350b,f4861d48,826ba3c5,1312bb39,886a064d,6e1465d4,8ef28f58,2cd8ab2a,d6dccdf6,7998e662,99551608,a9fceab0,be884b0d,d418911d,c8b1ef12) +,S(81d8fcee,574d9c16,fa2ba6f4,255460cb,479a6667,4761b4cd,c0ab026b,6bce163b,594e7f34,f5897a6a,3b79a996,f5a69814,3cf771fc,fd7c8ca6,38cb4ac5,98673143) +,S(9e83d724,b9ac73be,f932b42d,56f85183,85839c9e,c953a0dd,4da6d843,d096d278,f8b18cab,fed05acb,89efda95,ac496ec5,d3a000,a4a1d689,a1afa5e2,30c88869) +,S(98ba38b1,3b443c08,aecb1f64,73b2d901,908ec33b,35baa317,64f91144,3e320c3e,343f61d7,fc2232fb,f5d2f972,e6f42f49,d8ece7a,3434a0a4,4df1d602,3f99b84f) +,S(2092ea5a,9adf5eec,5a7a9488,6e970671,5822447b,e6c35285,de704806,52a875ec,ddfb72eb,52382722,a94facc8,e2616661,95a7e9c2,6594228f,304adc7b,ea4e7f35) +,S(f9ee909a,8f45a05e,ac77bce4,ebc97410,c044c639,95a1de76,5b9304c2,2eeb75a,861031ba,93f5b0e8,473e50fd,2aeaf13e,3a39c0d3,7e2e9d51,a41ee4ee,1301705e) +,S(a13878e2,3bc55a7c,b342dfc0,2eea9bf9,5c676e27,c63e8603,c75ce535,35df101c,35c0ced0,3d4bb091,92a2f83,3d3e81a6,233f0585,35c72ed0,1bfff82,7b108427) +,S(e8ec81d2,cd32dfd8,7284cfce,9d80c03,b863a7f8,3a71865d,34f7b1b6,104ae3e4,60be9b77,ee12dd7f,f532b01a,f517bfc9,1d24c4e8,b0865e4e,c6e27227,417648b) +,S(f07cb255,1529dc43,3470b18f,e4e06390,d48e9898,69b9a97a,6642b898,1cf35b60,bd46eb77,6d74633d,59b4b941,2e2355a9,c6e85421,59513d2b,a3297a6,c223b550) +,S(39bce423,dcfda9f0,a97189ae,a60b836,42becd3f,2f2cbdd8,2fe884da,baaf7f51,c1599caa,4b71219e,74490312,7303ec91,f3430be8,14979a2b,2db78bb1,ea2c8e4d) +,S(6da611cb,d51db814,18b3de21,13c9e4ff,58142f67,cf2d8ec8,e0fd105,1e9ad3cf,6bc2f048,3250f654,fdbd494e,bb03480e,f7fe5568,2e19cd70,4d178ff3,41e4b7f) +,S(cedb9c03,8d2e0eb9,8a4a5e8e,fa7e95c5,f4e13a47,79470c70,9a3c9fbb,8b1aed8a,79a2fd31,de42d8bc,820d5d56,ed084f40,46804fa5,f7f5e8fe,eca6ad4d,859a0d40) +,S(7d895498,6d1106d0,32f40458,f6c41fe6,25393f84,d00ded8a,3a07a107,5ae3d82,5d4fb6cf,ff1c594b,61aa117c,7e0ade0e,edd110c2,b2109866,ee7d586a,1a6d0d61) +,S(a4f29162,737043af,eb1e2606,93ecec60,851aaf50,c6e9daa1,75a00c43,d7dc3df7,beebfce8,fb764b15,38fabb20,145aaed3,92265d7b,c4628846,b2726821,c79c4439) +,S(b6389dac,de4ccb08,ec0ce964,e689bbcc,e0ba8165,6680c0a2,9cb162f0,f91cab70,e440c7db,d2d02474,17b2826d,28e31fe7,9ee836a7,eefdacdd,679040ca,50303529) +,S(72ce6dac,f752c36f,978ac2d6,aeef37f5,ae4ee016,999ccb49,27b8aefb,f6fcc9e1,ce6ac297,bbd84403,d60c6d4d,5e01027e,8ad38acd,e796bbc6,7c45f10e,d79bbca6) +,S(efad336f,cfd7425a,560931fa,a6bc50c1,4fb3e5ad,f8ad175,31b13846,6c255f06,3fb784f4,eeee9a11,ec7ab559,71817163,9eab6b09,4419203b,2b422e8f,e15a82c0) +,S(f98d4a2d,4bb2166,7c74bd1f,393ca57,22002c6c,f382b49c,2895deb2,34eaae3,9875e31f,7e3778a8,34750763,c6147cba,97a26f8a,d669e69e,9a36cc45,b56fd148) +,S(768cf74d,2bc24233,2c5eea34,2ac13ed1,2b0d161e,65876eaf,b0b89460,c934183f,42337607,e55b4d7a,f86e9f72,dd06a550,af083b32,e72e6265,4ba00fa7,a2fdc34e) +,S(ac26f3b0,1d05c625,915ec27a,aa916d0b,d34cfb6e,22525c59,9791274d,a5beff7b,e36760ac,89b61681,d1913bcb,1ebeb199,a3005576,b8bde54a,42fcecdf,e94f4045) +,S(dadd4181,741a0be2,e665045e,1b042a3a,fcd9050d,a08d1285,21298f34,1f74fbac,6cf46fe0,da78dd04,261e4e2c,863574e7,f6a4dfbc,a902802b,8056e00c,e4a84f60) +,S(e5651598,ce9e6a86,2fb139ed,143f1b73,2c4e1eea,91a88f82,a6fd0ab9,1a86a3e8,bb421336,69ab6c10,109723d8,ff4d5f6c,770fd8a,d569a21a,9e9efdb2,f1f1ac98) +,S(f26f791e,b4f0f596,39b69b45,401ee3ab,2d47a2b7,dcc3d65,de9e48ae,270f5b02,22e34b25,1fe5bbf2,5183c799,ea45757c,2693c591,633a84fb,e1a9bc0b,470ff699) +,S(a50cf10b,95612f48,7a9da048,a84dd8a3,2d2bec22,9db798ac,19fde68e,623da9da,50107d3c,a76a264,1db9f9f4,7cd60598,ce345ecd,cc3de888,e4c81553,bdcc576) +,S(c74883b9,2736c1b,d5f86a5c,1817cb9b,e917e5ab,5ec5cc10,a1197f1b,a45c13c,e03c43bc,e7393cff,d53e73b,60ea2759,d1c2bd55,c2b7a32e,847f4bd1,2c8beedc) +,S(a3437d0,1741ed88,bb05c00f,629e2c8d,be7cada4,dd002e9c,98dfe800,9e1c0a9,a627e05a,257fcabd,1fda00af,a4d3eef8,fc268e67,bb41c9e,d2160713,847bca1c) +,S(a6cc4988,f179bab4,de98ba89,530686fc,90c00c77,4a3f093,8329ffa3,99c8312d,f4eba473,7db25a79,29bcad7c,11346471,bbba86ef,4f611643,712ff475,9d70b6df) +,S(efb34a8,f5778d57,b3333077,6ca1abe3,9e680183,13936f24,da1aca,70b84dbe,a94a216e,fc53fa98,320878e7,167536ba,7e5845ca,149b2595,2f029878,7f428d3f) +,S(139846d8,1385e6bb,b23914ef,487fb9ab,19ec3b8,3fa45a94,a2c5fbd6,fcdfa07a,4fb7cc4e,599b10cd,a99f6aff,28dfda0b,62d837b2,e8c96aa0,9c34cbc6,acfce099) +,S(660923af,98ba567a,83df6eea,ab53ea62,49c2090a,13299bb7,a538cdab,adf2a101,b28b58ca,b1a29722,699890ee,8462f440,ee2a5686,9715478d,4460f0d8,8c94bd29) +,S(f18092b5,8c7517de,3f389d31,f1a6345a,d2f86bd0,c1dc9a98,d3e03890,f52be3c6,a83e7a04,91484ed7,7dc27697,33b0321c,440ca763,2a36c6d0,7e8a9afd,68f9c906) +,S(e8d0aa0d,1b2c540f,38a6a6e2,5b5fb295,7b700467,648cff74,bfee1138,81d0ab75,a324cbbe,52055c1b,d0cc3f29,88a80982,1abfc0cb,feaa56e9,f19bb8ab,d314409a) +,S(2586a0c0,230a0743,f9613df,51f7463e,1d8ee72d,503025f3,c7d2dfc4,6f526c1a,a29735a1,eb2b470d,43c7b469,4850f5c3,ce9b1da2,47406653,ede03ac0,9816c735) +,S(217cfa88,8d826d46,c31bb2d2,7dd7c8f5,8be68254,e42c0e48,a12cab42,677dffd8,4d5d9c30,9ff0fb15,35f9901,7af91ded,34179c57,f48131a0,6d96b6a,c01ac4ce) +,S(4ea65934,71aa3b8f,9e6791eb,37cfd67,943af3bf,100d7ccb,8203a353,1aedf4c0,feed9ac4,19a302c4,58047403,5c95e997,ded8a534,c88beca5,6c12984,84b7b4c5) +,S(974b828b,51026aa4,ea522150,c497eebc,7d7759f2,c9645f7d,4faac24d,18c7a1ae,c0369da0,c3087336,2566f344,ca81f261,65cd3a03,fcb05093,96d18fed,4faa9d26) +,S(d9815b79,d572d7a5,94dc8ae9,3cf45b36,99bb4544,ed1d5755,529c7096,9c978186,9fcebacb,f5181954,ac4ea24f,508fa67f,5b6c20d8,64ed53ec,d67e358a,e75241fa) +,S(52712597,d9bd4e7,cbd506f1,bd65aac1,478208bd,f9f6ad38,efd2b30e,b8368837,52eca996,ba2cecad,9a0911d1,65368010,68bbf0c1,12d6dd79,aef23262,8b3df18e) +,S(d94231af,d890f5f9,ef70e1fe,e8a8f4e8,ed2fc89e,2b8ad818,6af55de8,449abf6d,26592b6e,f0789218,273475fc,32d865cb,84278ff4,8cd0de27,e0646549,219e2867) +,S(64851231,7a69d956,3b3a99d4,b763eb9a,b661f7b0,714d34bf,e5328a4d,a99a7d90,eb20ba33,515040e3,6fa02088,5a3e9216,1e06d3b3,78122fb4,af4920a3,51d46bc6) +,S(d0a4b11b,ef662f17,98f413a5,fc062567,70df9edf,ee00217,79c3811c,ef68a8c2,d4bb9920,18e16945,c38ef5c9,9ab39eeb,748b7a63,ff4d4dbe,8b329f74,dd70b9cd) +,S(1d89b886,c4b24868,1fbe103d,dcbd76b1,dcf54637,3bd5249b,3dc07f06,985802b6,a339ccca,aacd1057,7e36056b,a3a70c6a,a7885a45,42bcdf30,30d0939f,6369535d) +,S(b6cecdd5,936343e4,f136682f,a38ba0b7,9dbab223,beb0b6c0,10a75cb2,e4dbb256,2935c053,87dd87a2,5bda5d1f,ed813666,5f77d12e,8242dd58,3ba8db03,319f7be8) +,S(84b244e0,a0cad847,35ca6c5f,bf581968,40f1b491,98682c4,28aea50,bf2f8e24,62e28e8c,7df80b11,f5713087,ee3a5d8b,148c8e62,da0de1ba,d8289ac8,861f7a71) +,S(f95eccff,2a908028,39436610,2e377c41,66433159,43feb6d1,638df6c1,cc114d1a,bd0da83f,1a0306cd,b8d1b9ea,189856ee,56d16e81,61b4f9ca,7de38d2b,e558eba2) +,S(7c4cedfd,3e613de4,af2ccd25,59a2dd23,2a1e6335,e410d327,27fef321,d10f55e3,331f2109,d9d00536,c697f73c,672a660d,11d4827d,41306696,cdc224e,e7d7b1d8) +,S(235c2e38,1bf2d829,e4b918de,435e276,f88af866,ed31a1c3,4b9f7203,a0269713,50dcdf0d,2671092e,e7c48614,44eaa87a,815a1304,4600fd0f,f26104ef,a0dbf929) +,S(2a961cd0,9ab50975,517ca488,d1c4a388,cdf2686,c5dde923,76128683,ea07cd73,85c91076,b2ee46d2,3cc0f7fd,e7654723,84f84c2e,edd7552d,d7f93be9,2398abe5) +,S(958bc491,f0afb8cb,8713f591,cbf183f7,e00c4775,93d1b51,a628f40e,4cfd65e3,bf5be339,fa21dfe4,9113e026,af0761a1,b2a09a7a,ae8f6eef,92d50c6a,89a65b3) +,S(6e960ca3,7b5b7abf,99f5a2e2,46b7e953,adb5ccc,6424e73d,dc865bd8,3d5f78fd,53ad4bd1,d5e9643f,5f2df612,ea16fcc8,dcc4b0b2,9ccd5a81,bd659b35,6a5e0e15) +,S(d7ac920e,9272bbad,dd961525,7d91d6a8,e747e4a7,a48ddb5a,8b2ece8f,f0d05871,6381b9fc,c37bac5e,38c0b96d,c098c3,9d4c7620,61b66dc4,adf66e24,f0c87ed8) +,S(9b0803b,1de95706,ec123844,ebe941ae,4481c12f,f2d9c078,b6c1d531,5d730609,160cf3d6,b12afdfc,eac2ed01,fe4b801c,5a5ff0bb,13cc3ef2,f5f0962a,6b3fb1b0) +,S(5d50746e,5b74e006,9dce0153,aba04216,991bd509,f022f3ea,689553bc,a4c5fd88,b0fb205f,d2a14b1b,bdba2e48,429c92b6,99cb336f,b6ed0e58,9276118b,6b259ff8) +,S(e1bc2669,fa27629c,92708748,36008c2d,ef4483ab,c686ecf0,bbd01a85,fcbe04ff,6fb7af71,83c0921,6173fd43,5b3a1b2b,15e8b149,3bed8e78,3d409f84,cd95ecf) +,S(cfc9081c,b5a893db,40c51979,7dfa1cf2,f36ac620,cf7017a2,fe90dccb,d8bfbf78,26a88d23,50772fc3,2f377c15,a9bf817c,db321d1a,55c4d659,b5f29ae6,96a69ac2) +,S(54d9c9d,12bd68c5,3961246d,b98ed78c,cd8ad158,8458d4b0,5fad9df4,2229bb9b,b5e97c31,1dec2259,630c961f,ed33d7d4,f8de7005,849225eb,a4549d76,de1cbff6) +,S(8a914ee6,7e9d6619,d00f1924,8735c7b2,bfb11eaa,61fe42e8,d64b5a53,43057dff,1b91e1da,3374da49,8bc2f018,c2a6fa51,99c51846,a2f59b05,a6311ac3,1bc040c8) +,S(d4b81177,3e641dfa,bc704fba,e9ab0ab8,aa2f4c42,fbd23b03,a0b0595,d0240522,ac30ce3b,1ea4a14f,4a5bd364,20f40df1,cf2e6835,17107b8,ce6fbe05,665cc726) +,S(b810a787,c232357c,bb82c351,79249f64,6f3c8e2e,72e0e004,36226670,14780ba9,54364034,1078dd7f,216bac76,9abc8467,4a422c30,f1b7aef7,6a2dbbb0,158319e2) +,S(d71f88ce,dc738ef7,1ad691ea,c3a7eed0,d29c762d,8ec7ce0d,14e72d3f,f534a833,a47cce83,1aaaadae,a2d9d0d9,7b4c5125,97c1b514,95c3aad9,d2a4e716,cfbcd99) +,S(170cf31d,4cac628e,139d9d89,662ce5e1,1ad7092c,cc6c6174,96c99d71,6d147ffc,4fb3b894,e741f585,15e8baa,addf3119,adf6c4ee,695253a4,6f9a5dec,cc6d77a5) +,S(8e7692a3,b1275e80,38ccbf66,ecb9a55b,bfd48d49,4085b4d3,1729a644,ecc316af,f339c1d3,af07525e,26500665,ce66a91a,4fc0bfa6,b8a46411,34cab540,68c504b1) +,S(5d1ff338,3dda5e81,32c47002,ee2b77ce,a07ca869,e7684d40,a27cbefa,4aca891a,a1adb3ac,b0decbdb,6772e62e,74c4516,fe843833,8d2979cf,5b091801,bf5fbb8b) +,S(d566cfdd,a9dec66b,ddf2605d,a37ad558,375e1c5c,5f5403eb,d75ff6ec,3c2b8af7,13e2232c,78586da9,741598bb,25a90a4c,b6007bd7,bfb75ed8,427ade0e,619c78bd) +,S(cbd708f9,cc713af1,999ae74b,2b9ee3db,3cb85bce,249c5e33,764997d0,2fd96493,f01a1d6c,4ca9b0b8,9337a5af,889d8dd9,c264f4bf,6b8066d6,55cf9267,684cb2cb) +,S(fee1ece4,e8ac73c8,8220bea2,153800f3,e8d049b8,f89053f4,ad4b5ba3,f0ed0fe2,9b5208ea,17c80640,a353354a,7cf42f6a,f9763db0,bdb0954f,53d56a2e,ea26aad6) +,S(c6aafa66,de444853,8d7a6c3a,fcb35a8d,db916f33,14c15dbb,79c48bc9,46ee843f,8a61c6b6,7fc590f7,bc81a761,7a6e24fa,34c49d5b,30b11bfa,7cdaf3bf,d1505b1b) +,S(ac351560,83d91f7e,4898551e,7666bbce,dcbe21ff,f005ef1e,a866781,d9aac415,d709d997,77109afb,28c318fb,eeec8a27,5577410b,8da6d494,5ac7d660,1334483d) +,S(a89c2616,7c024b4,81455d19,93ac04f5,7a212e34,95066ef9,21968f72,3d914e18,551d3662,6127866c,77df092f,5ed8dab1,3569ce68,433de199,ac8219ee,13a3c1ab) +,S(9951831d,b58499ea,e94018d8,cfb9162e,b045b95a,fd246a3a,72e8808d,1ca3f06b,fe39aeec,b9d5f867,d5827146,fb384808,81696ea1,5b0d1188,fd487b16,d9e4d773) +,S(b71e17e0,14564447,955be26c,61ecebc6,8615e2e9,37cd2e8c,78d26922,681fba96,ebcfddf1,d21fb8cb,95e3cb22,4efe9553,1a6c5ba9,cc92bdc4,3011c50b,63b9e3bf) +,S(e170f81e,dbdd9ff6,d460ef6a,1c3d4bcb,2fe89fed,4e6742c2,2d683ffc,15914074,93f110ee,f971cac,8ce206e3,df6f9caf,801fa7eb,c7df14d2,d6f67e72,ab96e67f) +,S(431a5547,318d05c5,5ecf04ed,a1fabbb1,4ac8dd8a,47dccc73,acf5d5c8,1ec104f2,3e3188ad,7b141a36,4afa1f04,57ca827a,7a6f1f70,75ca8dea,6fd08bf2,bfa779e7) +,S(299e6a6e,e1587523,2be26ce4,a1f80cb1,3c193291,7f0b5eec,383ffec2,62203394,5dbb70ed,3ad4a211,bfc8e8bf,4c00a055,23c9b3e4,ed3790c9,3bb2a77e,5301575) +,S(66db488f,f2b58869,b2fb5f78,61e7f825,bc99ac9b,ea02b59f,b0978c9c,c38934ee,ab76e112,b51c83f8,b10e997,2f6866c4,6040e7ef,eb14817f,c316b730,e8ae6a5f) +,S(1259856b,66980d52,bb3912fa,78ad5b70,54c812b5,fed402a1,c3c8247d,26274932,ead7cd3f,c67895c7,edfe0557,d5681bc2,d70dfcbb,870c7c22,45d458c7,f2150383) +,S(502c8614,cbb0f3dc,caa5272f,dd252c7c,4269968c,efebecf9,102745df,fdf1cf00,711bc688,7e4e356,fd9d0695,16af0a38,1b2f4500,6487154c,10b90995,3bc53c3c) +,S(e051193c,323c6403,f69c1073,47b6b7fd,f43acdec,17c00c42,2249bcc7,aa8d6fd,2102c271,ce428ee6,16d1d2bc,f25c2630,c574d9b1,87f8b9f1,c85117e3,8a560455) +,S(c9187bae,d768d32,29fd90c1,5c3b37e7,abe7c58,b538acb8,ae0741,adf1dc46,c130d443,f9ebba4a,197d0252,615ac29d,5714f6dc,f27fc0f8,d7547335,89c92c0f) +,S(5b08567e,b9f3b3ee,2b03ae70,1c6b0641,23dba4d4,4e8297a1,6eaec8d9,e90fe897,ad071c15,9079c91a,cdee9c72,6e8f4cbb,914d4b4b,750fed92,aa81a987,a90c27c9) +,S(ae5b648a,c5817a86,cfb06a26,d62691ab,8a9cc554,d0eaa86f,839f4a51,b43ba7cc,1ea8ab0d,b665c22a,ab0a48c3,da17c629,66e75212,a6fe9983,d5e925d,432db311) +,S(3b9bacd0,a092856d,98eea5c5,ccc9abb4,4f2e0d3,27e578f0,42102148,890178d2,b681e88e,9603ba1c,57b628d7,ea929ae0,b79be447,f181a491,1fdc65df,21bd5052) +,S(524df580,a74066da,d522f827,95e415ab,f6dfbf7a,1c1f6d7e,e8d05a86,4659fef4,3facc728,5f3bc1e1,a6fc210c,ad302ef1,9c72c5f9,e358b9c1,ed2aba72,2652f35f) +,S(2e0637f2,ade775c4,87d09a38,3480b875,599a34ea,7fc70cdf,f6ed309d,450e4363,e3c6eb08,7e2f4e49,cc78e903,e4ad55f3,1aafb7ee,ada72369,6da8a0a0,f764738e) +,S(f7fec6ad,beafbd3b,e413fb33,587b9427,3f785728,226f764b,bda6130b,aa0cc483,f646a974,8eb457c7,fc8fefd8,e63b976b,dd42093a,e59fc544,c66531d1,9e08c68d) +,S(75f94ce0,6af64c43,2b6c95b1,2d892dc8,cd6eb497,4d826299,29ad8bc4,8a3608be,bf8716d0,a2b7906a,69316b32,21ec0076,6e32c892,2c7be6c6,22e8877b,b1958a29) +,S(410296de,5e0df3cb,c4f039f,cc869090,f62e07e9,d3011043,31bdc1cc,f3fb4d85,e963579c,a314dd96,ab8a82ff,86265b82,da74267f,c861f96c,383f72ed,3ffecfa0) +,S(cc824eac,5f5e16b,2f7c1703,d97da67b,69b4e698,16cfbb23,cbdffe00,d73ffa05,17c30da6,9f414ef9,5dc58218,27c7880f,d18c6f1a,92afaaa8,b8cf10a3,353e8abb) +,S(acc1b0ef,4d26ed8c,d78f0b3f,d3177077,d2074b64,fa5d8d03,a83ff113,7e6e5820,6cce44c6,8519ae91,19d2a80,4f8fbeed,4fcd24d0,169e8000,11150c8d,9c3ce6c3) +,S(1cb3076e,ccce1d9b,774bccf,4318b921,583c2b8e,31877825,7c2fc71b,c90da922,2a2f276c,58605d,82a17dfd,3ecdc5a2,a6372df2,cf25bb04,c628748e,4ce373cc) +,S(6efda451,2a22f49b,587ea975,9e5a400,8cb3a521,7a38b978,3d5825aa,84fe13f2,11d44ed5,6dfe2fb3,1ff2a54a,de5a2a5b,60673cfd,bcbd5039,54a94758,878e2424) +,S(47f69619,aef4378b,5cc931ec,da8fd996,e2fcf1cd,17de9cdd,51b30c3b,9dbf0858,149556a1,9776e3d6,da457af2,a4d70d66,d2fa28a,c33abee9,bf890894,7cb5e274) +,S(dd3d8e1e,97f5dd5d,539032c5,13a19e26,8b2eaebc,1a47cd4f,8ff48335,794d28e4,7968bc00,20f6a83a,a973d7c6,382ebf33,c2233bb,34be9c2,e0ff9eaa,4c467e83) +,S(2bd454ee,a19d3a6c,be55737c,d3cb4b32,7de2a2b7,50535f91,97aad2b6,65e16d78,a70b0f0,d6a1278f,34271c66,7ad40feb,9f7c6248,87e3f754,9c1f1fd7,129f7f99) +,S(8cfe75bb,2a7e74b4,4da035b2,9a26784e,915462df,13ac2d91,4733184,f5a5ee0,648ffc56,bdc87c86,4f6226d1,c9245540,b65c2da2,7fdadca1,eeff2e24,6607cd1e) +,S(5eff34ae,19c462cb,c2fdab83,24b57bc8,5e046a68,4f112f6e,665b3255,65724d36,198fb5bb,9db347ff,c2289629,d2e01051,d551e783,47c6a6b0,ccfcde15,a04d68a4) +,S(9aa54554,f3673b08,e36db624,47631774,a2c51bb8,1f18aa61,426639f,78f92b91,8744a3ad,4a6e7404,d2e22faf,272b50bd,1d167b46,5f25c6fa,75c8d784,61384806) +,S(4b837575,8cfb5970,dfc7463c,5df06ebb,ac88a2a8,b9d7565a,955cb53a,5ff259e0,87591d42,bda1a53f,6e474396,a1233df6,ed70766a,ab7aaaa9,9171a5e4,fa8df208) +,S(5d4b74b4,9134f90e,673f5a57,959c7cef,c49dc725,85734428,226cc5ef,76428bb1,1b2a8910,f466ee15,abe6bf3f,100d8da0,cdc2f6bb,f19c3cfc,b1f07a0f,bed89425) +,S(d50be2c0,c55244ce,5d93bafa,f62ee680,2d475441,7ab9c2b2,5702a309,57cad2d8,fe207e4c,6ee89ab4,c0185461,7eaa5de4,5a4dc0f2,bc4544e,f241cd5c,162f583) +,S(bb0f61ce,8e0eb384,64e48915,5bf985aa,f93bbff1,416db2e9,a1da034e,1075bff1,13a715,2ddeb0df,30ea1032,cbcb08ef,4e6b0561,31474412,631f6fbf,b77b7d0e) +,S(3ce6bddb,473f01b2,170e41fb,22fc5efa,63e22b9e,14d9bd22,88632bf8,4ddcb2f5,43086057,f4b3d298,426b7308,110dc52e,9a84268f,1bac1edf,8d47a25a,ace0922e) +,S(ffdfb14a,ef1680bf,c90b5490,c7cdb75e,bbcbbff1,a56c3c85,bd37460b,b38f81aa,f3045def,2f1f19e,232880d0,e948b5a5,24f228c7,3bbcca54,7c216ee1,eaf4af0d) +,S(1ac1f2e1,9ab4264d,8126eb60,a2330aee,c828d102,507ac0fe,d59fa4c0,8223172c,7636a4bc,339486af,b215e3a8,f80d8f02,d8fae063,81b4e7f5,133f1936,d8e18bf8) +,S(52534c0a,740e89a,6142957a,a20f2339,b1a1a6b6,7e6c9a2,2d6661ec,adec228e,cf6fe6ba,fe41c899,c1ec2fa5,d884fafa,e1a31835,ae8022f1,365a97cf,3261b669) +,S(40920285,7cd22c2c,78cdccd6,137d32b1,4f36f2c,964a278d,5b9f6462,651b09eb,40c94f73,a5fa3e3f,66dfef1b,f4f16091,f6b7738e,b8a865fb,3bde12c4,2d031d0d) +,S(8b1d3c33,4b9ccdb2,14aac6e4,e840db16,25a5b3c2,4069d9e7,c81bc51,9b029289,114fd464,2acf9599,1fd65898,57822277,8020769f,145f86e5,630d6db5,5e23e853) +,S(ae14de60,b7c7f13a,59c6bbd2,64162dc,8a6055e6,3d3460fd,7e473979,f4a242bd,8b960489,cdb5a333,a14463e2,376f2113,afccfee7,afa00ef1,6cac6a3e,4c65a412) +,S(f37f1c40,99c95e6c,3e8d4e39,5dfddbaf,b8153948,137de420,788386e,2ed3e3d7,1f290080,82f6ad34,b2283d76,9cf76577,a564411,4f51af5,310c0a3,b3fb3606) +,S(1fb07fae,9636889c,34441c1d,3c2496bc,a13f8933,666d05df,aa53ecb2,1b017a84,128189c9,3931576a,c4b68934,b7ff551b,58e6da46,fa97fcb7,b8df8c9c,637753c0) +,S(44d1eb54,e112eced,480ea2b5,1ba22ba7,2afb0721,d0d6b715,52bd9728,4815f3cc,a6e13b28,574c526f,12673e02,ed7938fa,ea1855b7,d5b6e88e,3c3a9b2a,f2ed7043) +,S(6980972e,5732b875,7fe311cf,f76f7bd0,ec94918a,759a7cbf,d8795645,a103238e,7b9fe832,4ffb9143,21776b24,a92fa09a,ac4a0fce,17c5bc26,2d2eb063,63d26a5e) +,S(6a3a8c9d,405bb1e4,de59639c,4f6406a1,a8566a62,9d85b79b,f7030255,50efcfa3,3e8abae8,7b22d04a,8fdb408e,196b47a4,2e0f59eb,9d51924d,ce8de66,cac038ba) +,S(ff3108d4,1598464a,bf5844c4,dbcfa027,bfb6804c,946c3683,1da390b6,4412ed0b,805565e3,3ee1d089,5c6abe85,77054648,11f5d4d0,219cb515,dc072d47,cbd0a317) +,S(ee4f76a,2f8549ab,3e134e53,335dcb5b,49972750,180491bb,2139324e,95517d73,6bd90167,22402b11,68989e89,9c942767,8307367d,8a29075c,8fe81049,7071a838) +,S(c21175cb,1ca958f,36a3b720,5cbaba0c,230c6305,8cd09966,ac78f51a,4c53e0a4,6a2183a6,7a7ca0af,256a0ecd,2c085d81,585a02eb,2ffe6a44,ea923688,cc72bf51) +,S(2d5e4c08,a9a0b398,34e46e39,e7cab91b,953141c0,c5f2d292,c409cbf3,9a37d6fc,7569b9c5,31a331fa,9234f37,e9005ed0,4b512721,dc4ef054,d6164046,75c6e15e) +,S(6302c041,bfbbeb09,cc012408,631765f1,5d573b67,6b799c26,ef7c2a4c,bb15dbc3,32a8f20f,67ce42a0,ac4ddfed,d0932e91,a1e51488,49e463f,915af082,7e491025) +,S(3e61516c,198de08e,f7dc9cfb,89ef9b94,5b6c67cc,2deab08c,a3b36612,5934e2d,1effbbf7,4d5f7104,f7784944,70f62784,5692f3ed,48e4dbe,e956e063,37520d9) +,S(a008bab2,d7d134d2,4ab35a37,8f330521,b8989219,108b05a7,d8aab0ae,e542fe30,77a377ec,903c06e5,463ec2fd,e9c05e43,f5454aea,82b99de6,be09fe31,51b475a1) +,S(7782ff48,b928962a,950f42b8,2e43017,28711467,16f22f8,c389917e,a624005f,78f23e49,38a03e0c,ad1b766d,b9bafe30,8ad2c9cf,5b22bc18,c78c8898,fb608c15) +,S(233b4a78,c26ab44f,d1019d64,8c896eea,f6ffbe71,8cfefc20,d20676f8,27ddcfc2,de508436,d976df90,487ddc1a,48284cdd,f553d342,2e0977b5,18f3ed9e,773b655c) +,S(8014aa29,6eed493,d83d7aed,2d8c3342,3f7a4623,295f2a07,92c5de0c,71b8bb0e,dc58729d,f2a5bc9b,1170caba,4856a9e1,695f39af,81a1e444,f3e6dd55,f583d92) +,S(8a01e90b,233dae71,1bb050ce,7bc61c8c,60882aea,ebead2c1,b284ab59,dbbbdfce,580ed75d,c9e3693e,92c06cc4,12c95a77,b34b72ef,20a51cf4,ca4ddbad,7691fdb0) +,S(50a2349,24a29158,70e6372d,582ba07f,a569881a,96bd1a4,4cbb9232,1ae733b4,6943c220,a97701d4,a79d8e2f,a446fce3,aa21d00e,2f7cfcde,3edabcda,678cc751) +,S(cbf49357,8c96744f,7ab07bd6,182640ee,b51b8f6d,a8a655ce,cbd2087a,eeaa6d83,4d1b36f4,5711db99,404bdb1c,9484a04d,29e79fa5,87d051d5,e75f07c4,ee8d4bf0) +,S(737b3d75,e4edd296,8d164c2e,828b31d8,7c63d11f,fa4ebd89,ad59ba71,8a8efe38,ec7f7ba1,8aa8e515,4527002e,edc8327a,ff1ebf6d,d3877439,e7c822b5,35f31586) +,S(29cb2864,251939ae,6c7f46d6,9d7b4416,8812e0c5,9aaa8b8b,b7e22ffc,ac38813a,c3ec280a,7c98b2c5,c96d77c8,b410ff1b,b5f1eb51,debd38f0,528bb73a,eca2e6e9) +,S(1858aa59,24282fbd,e44dffa2,5197954f,f3668954,24741d35,2c9594fc,5e28fe9d,a0e891d6,b0a69fab,9fbd7879,a7e4ab4c,be50b1d4,4be76485,96fec281,d2d4bd46) +,S(72ce7c58,1a420eaf,67bae314,d4f092e9,26c1378d,d346c4fc,2a9e9174,862eb75c,2329177a,5a9c3e0c,f6e236ae,30858bbb,8bec121f,f7462ff3,6284bde0,7425ae1c) +,S(34c1ca5e,5dfab6d2,4abdcb83,9ddf9bc,a3f9dcbd,ecc315,17bd6f46,af112903,93f6fead,c931cc97,37c4aeb,6a589a08,80088a24,eb49a1a2,7aca807b,22a1f803) +,S(7c5ac4a,80af5867,f803100c,cee3d676,8d348b47,9ce26243,284ba0dd,24392c36,a4468964,903be647,31fdb23d,1ea7ab84,a3201cfe,ab585b86,3370ea40,66fc5828) +,S(be2ddd13,244c7728,1a98851c,8683ff7d,b57bf3d,a746cb35,e594b7ec,4c363caa,adb75939,af8a2cf,1cf3e5b9,2bc7ba65,8c45ea85,47959f25,7dfe4592,3e580fa2) +,S(6dee1f6a,3b3befdc,a4a44471,d62dfd9f,7f7b222b,819979b7,901a1764,8ec13806,5d9e8501,4fa5f6ff,f8c0356c,eb013122,1a9a2431,f641ab6,af3b9999,5c2e5651) +,S(15f264e6,8e2c8ed7,490355b3,a7b11512,c764386b,f6bafc31,80ee6fe7,9de68c19,90574d26,302bf408,ef9053fd,371cf29b,c41291ab,a76ab74e,ddf3f8c5,70326aba) +,S(3d7cfbe9,4cc890c,ea592b78,5a984c8d,6d4c5e7b,183f3666,df9805e,be9c91a3,d55cddd4,4ea7065a,f8f51694,f6a84b54,42b30b48,e7630d12,6827dfe5,e7f62808) +,S(54388bf9,d7951dc,7ab5dd3e,74971201,1ec637b0,7febee14,45b1dcd9,9c3a1e10,17b36788,25dc2a5f,9bc8738b,3f560d23,725f99c2,a9d6fdcf,6fbeff54,aae5a547) +,S(3c229fdd,9a0080a5,948a0d2c,c9281794,425327c5,52063c94,be5f0197,6a088313,34975795,a84f83b4,af883d12,c373c505,192f0a71,fed21d8d,3a8dbb8d,2a926a1c) +,S(b612bb6e,e14659a6,e1691f36,8fa8d7ad,1974e74e,36f1ab26,15705271,27c63210,5948c5d,d623cdf1,f9477733,dd5e8eaa,5240817,e8e08dc2,23b6072c,a4df5bb4) +,S(ec56e585,54470dd4,28341ed3,e900e33b,ae381e42,2efb3d64,d2edefe0,7b05f613,ecd7f151,acf6e308,dfff2bd6,578bce76,86effe0c,d3b156d9,df8f66cf,295e9c45) +,S(1bef3ca,85ff9f8f,bd80c8ba,f9b15b26,a565eeaf,e4d4f08f,25ee748f,fc11f80d,fe0260bb,96be497b,a194b892,71bc8989,125f0a0a,de88b135,272c5683,f92914f9) +,S(1bdbac4a,522b68e2,a90e4265,3d2bf4ad,c4b27e5,a2ebb251,68a083e9,9107c20a,4d60e326,3ede7fa0,10467b9,d2e8b206,5b09e127,e3fba9e,3d228439,50d63ea1) +,S(e9032f9a,567ab8da,551e0f8b,1b2c2c22,6e601b7f,e894b837,3bd9eaad,3662fc84,ac563e6,47d21af3,a0cb0a49,dafde0f1,21d60994,8dcb4000,64e3196d,74eb70e9) +,S(7ce746ec,44af748,a5508044,f56e3467,a9608deb,c8a051a9,fda907c3,8f79c75,8f0879c1,3166bd23,be7bbb80,46f3c019,2c6b8fa0,52fad7d5,40640fd5,f2aa426a) +,S(e0d52789,19de6d1c,a0929856,46cd3200,68862dcb,ef369fc9,6c6de4c,bb59eecd,98f4679d,b4ebdd90,a4f54791,29740bd5,f46680f1,d3ebfce8,8cda2946,ca886b20) +,S(c6a245cd,cf1f4b58,4400a4d4,82f2088a,e28c8b85,641c1f18,a13aea,7e5ca397,d306dbb9,f8f2cb09,958ff944,ab5e6cd1,cb11eca8,33021bf3,605e6768,961ac628) +,S(ff956c8d,9710f082,a1f34ace,c99987fe,4ade0919,4a0deb06,a1b286e7,3695c910,fabec52b,866afd46,1fe8c832,fd8a9375,a8086aec,b0e2e39f,b7823d0c,13bcc306) +,S(549dda4a,d1a604c,d0f44fe4,5c4dc276,5cef1216,6f4accc7,3ff12152,26c23af0,71e3afc0,e05ba826,36eede7,1abb15e1,166fec97,562c4381,a33f765e,100631ef) +,S(66d3df09,21573cc,e69896e8,2dd91f9d,6070dd12,edc21723,2077e644,9e776416,93981613,59a2ee3e,d9429dd3,eaf058bc,9ccf1c9,ea931ebc,25ff279d,5bb46d5d) +,S(61bd3dbc,9426386,9c53ede5,a5c4f186,8a4d7a82,fae1be7,37b702f5,79e4f8d9,8c056a47,e27d4f49,2c9ddf54,efa48c,502aee81,e2336caa,c1b572b4,e082e780) +,S(8a6d8b46,4a31daa9,2702f784,9148db1c,4ef20c76,fa67c006,47d6f3b9,80178f4e,d1f406ee,e4087601,96c82f9e,38205147,c31309a1,93bf4d8c,cfe67cba,ae8f7407) +,S(e2b60e93,99eb8441,700aa90e,1edd981d,37893b42,5acf6b1b,809fd1e4,922e573e,68a0c65f,e394829a,8ae09dc0,ab35d789,bd8a38ad,800e9ed,63513eea,4e19f7af) +,S(4c76030f,e85cfc92,64f16cad,99dfa541,fc23b8c7,2b558574,ac6f26cd,d4f55e85,44b352d8,9a31b4ec,c8f9a574,51855f7d,e98c63aa,98aec090,2d959be8,a12b7bb6) +,S(dcba96a3,59103c35,aa2c9ef,538c13a0,2f0e8997,3663d580,fe454762,5fbaed2e,af9e205f,727698a,de9f91bd,75bfb73c,b13053d2,db2d83de,b4d14c22,176544b4) +,S(fd0497d8,f75fff9a,cbfd3e03,6c9edc73,e682427f,e9b66a43,3b5b2b31,f2dc7883,d23014b6,9c8d1077,ab3fb2fc,c0bde4a9,44576289,896de135,9c0badf,fcd62d79) +,S(5bb401bb,b38e413,43d1b779,54e83f9e,e705009a,eb8a1077,542cc6ed,edf48040,431fccb5,acec1391,f68ea628,378e3ca8,ca944573,ecfa5e,e7a82bf8,82599c14) +,S(1fa96a4f,f9cc6ad8,b2741c38,b35c377e,3acac704,67bc5d20,a262db5b,48bb283b,c3448c92,ffc65afc,f1eaf7f1,f9e149eb,6404dcc7,1b222ac8,bfca8feb,eeb963eb) +,S(9534aef,1ae551d2,7a638453,171d0a63,697ea420,2fec8f11,61432291,642f86ea,cd0c943c,38837dd0,33d48a4e,ca13e96f,46fd7f21,2cbff849,6432aac0,ef729591) +,S(ea72afed,43300390,bc98d08f,3aa4ff4a,138440bf,1a8f8b7,b57032a0,d01b8ceb,e174dd8c,3692cc2,9ca856a4,4eae7e94,af4fb044,85172809,25ea66d2,d858663e) +,S(39593534,3ca2523a,603801f2,abf3a1d3,16569862,35d79fa9,a01f86d4,5c122327,acd3e3e9,2cd76dc8,551cbf0e,94475125,42a5b887,ac6c975b,45d2e000,9953dd96) +,S(d57b2a2a,375e5a0f,6967d4b5,3dfbb51b,4f74eff8,72742a3f,246e3e09,ec2d4721,12d6f848,4d107ec3,10ec2091,3482781d,c0aeeb94,71ae7b03,6a0d2551,d3ed306) +,S(9f2dfc5,1b99eef6,e6c781a,fe0135d5,fc5def8f,d520119c,59bbaaf6,442f1082,8f20962,fd273048,fa3ca6e4,ea96fe0d,7ad1d758,99e25a77,e0f8b56e,5b20dd0d) +,S(b1c30bc6,f030c913,49b36c1f,9c0deda1,afa58776,58c5a16a,9352c1bd,229884b,f8a459d1,6e77888d,cd5c63d1,8a2e28cb,5563e727,f53b59f1,939390c6,1eecdfc3) +,S(8a663e7,40cad237,12dad6f9,1bb5d266,30542933,853e02eb,665e198d,a5c6e53b,e206b399,51175d15,daccf711,63b0918c,786a8fe,2077812,c0c1eee6,bb5c1e99) +,S(2b0956cb,e0ca91ee,f44fac0a,76cc0b00,5f4a5ae8,27e63696,fe1aa8b4,a92941a1,a31e6fa8,dd454eaf,90ee1e11,62627e3,3f84b8fe,da29f423,ddf2a962,386cffd2) +#endif +#if WINDOW_G > 13 +,S(e0144151,7a2ac970,eb6381df,7e11fb4c,6b009980,6a0d330,d5429126,e662c3bd,8238ce9b,a691c80c,21563934,18d18dbf,aeb3fd34,48863a1e,7f4ba360,408dfcee) +,S(be3213e,8b062f33,caf16c53,5a0b666,f344e0d7,1e28aeba,8b215a3,7ec86c37,552523ba,eaca38a4,cd795683,852a2643,550fb83d,d1db0adc,3f1b29c9,7d51cd1f) +,S(623393b6,bfbfbd64,fc7aa1db,9e58e274,1c18eb6d,b5eb30ab,c4fe167e,a9e8ff2b,7c0e4174,f0fd5bf2,a025e316,fa3b7b97,1339a197,b52b0b50,bad4dfe,34e42cd3) +,S(dadeb702,dd0a1e87,669eb624,b8cf40bd,bffe79aa,8afab26f,bc6215b1,dcfe97a,930890ca,e4c29b41,2d660acb,8cd39bca,5a522599,a1ab0bb4,8fbc38df,17253490) +,S(b528d3b7,83179b82,bb1c9cfe,c26184cd,ac98ad5,8e253c13,627fb778,c9362f33,63203af,1545122a,63940676,ba2d18a1,aa902e08,8bb444f0,47c2bd52,db8babab) +,S(2ff223e0,93986e22,ae418a5c,804e9e81,7a4de562,d7436e0,2d025ab7,11734a6a,c5c8d188,ec9cda19,bda76d8a,97838ab7,81990475,d4a00096,5efa79c0,100f678) +,S(cb8731d5,e1e53c9,ccfd2c39,3c8ab1cd,9ec839f6,99fc712f,f946e74b,99eb1742,cd2f9df8,38fec504,dd125248,92ce8a4,a9db3848,e487076d,8c18e53c,f6d19fb5) +,S(1377ac45,d776a5cb,76ec265a,af272690,6dac52dd,be987799,36bb1271,e0cf4a2e,a4b3330d,d5954932,d5a7a818,7d9493e0,25ab2155,d4ed0d4,f34aca1e,c2a04670) +,S(984b9bf2,f140c75f,e03489bd,88041faa,22fbac73,7ac10724,c511a253,641a5ccd,c474f639,9733eecb,a750ea82,ac4d50c7,d82f4c9a,942a2bb5,90b1431f,c8d14ff3) +,S(4b8fd000,74f57cf9,b135d56a,c002bf99,d5050479,7298cc4d,857960d7,afbdcb06,7c044103,1df0f6f7,721937a4,c60cf76c,95560ee9,4c6d097e,3a8e37b3,34c703bf) +,S(57316653,68412236,619250b2,58bd0ddb,34fc751b,8becc0b6,60585683,218b6079,d1d56e4f,30f01c57,48972898,b8afe142,16f8335b,e3a39c37,da64050a,91652904) +,S(c9a00197,a0ff16f2,fbf2cb59,767d43f4,60737367,4f2bbbd2,53c7220f,db69f286,177c6783,d739117c,1de074b0,c605cabc,6b4dfeed,a531f4e4,9cc518,40142f0b) +,S(e23416da,91df23a9,db161618,579b3008,c87b9ef5,7ee8bff6,45eec6ce,a61881cb,e556417f,84043691,e7ec82e0,e1718296,e42fbcf4,a3de0137,93772dd5,70b8da15) +,S(9f96e3f2,369d753c,e6614c45,77bd8a9,14293eee,8a749c1e,3b0e2955,638e9ad8,f5cd1268,1567a4da,71650d10,e413e0eb,9b01a396,e529cff6,b494b2b9,a21ddff1) +,S(48657ba4,b24b0123,cd54317d,de6a3245,ae488078,5ba43d5f,1d94fbf6,b9301fd2,191edec0,6eb53781,2813ca77,2a9021b0,dd4931a0,929a7e36,a4a8c66f,aef0d890) +,S(67b322e9,d72e864d,8cb15511,11402d7a,c6c858c8,77832d4,e0187e69,6a36f24a,cfeb12c2,6b58bf15,3bf87058,c5faa833,e15c867,f7f9a208,c3dfdf3a,c7f6946a) +,S(42e8068,542bdd98,fcce8925,52002db,c545ba13,16082d40,fbde06f0,a44ded15,1645a9b0,c1f33cf5,27364915,8c4f261d,a1ee814e,7aac6402,bf644451,bfc4aae5) +,S(8ee7dce1,339c50dd,55619107,9bbac005,3e058cca,4a8c8e30,7588c105,fe90d4c7,ffbd0af4,8aae8279,2cda6170,5dbe9fe0,98e102ff,1e6f11d2,b4669a81,6ec9d5f9) +,S(abc9504,12926a71,6adaaaf2,7b209216,37a935f0,cc66eece,55978a82,1fa368e6,72e54935,e9b461e7,9fb75c48,4dae4fd2,155a4a48,d3a467c9,624c5f6d,71f79203) +,S(bd250320,81e0e9b5,3b00568d,40378fcc,fd72fd8d,783f2f3b,433ddd1b,a6976ba8,5adb8bdb,85855498,994ca879,717b8e7a,e8c4c87d,29d6a1ca,4c3c6395,6c3ceb39) +,S(b4fb262,fbeee84e,49ae9167,7e7aa0d9,b31609e0,48888740,c018a5e1,8ae25f71,34df3f86,dc091d51,258ecbe4,1cf616e9,265d6d36,8ea3403b,24cdc7f8,e176e5fc) +,S(d1ba9b67,66f24eaf,a145ad14,81063b5f,e4604817,21b361c4,95de8833,be605c01,e80a6cbd,17de2f1e,663ce7f2,8917e3a9,f871943c,a4b8ba75,68476a3,d9e8400a) +,S(5c98b6b0,3a3e5a8d,2d46652d,5eb9e2ab,a80c6702,69dc5ba8,3732752e,922639b3,81e2f9a,145d0cdd,2c51bd13,f907a04,6a35efb6,635292e0,6b8f6513,c50f4a54) +,S(c1fa4688,f75fb86f,61cb7071,4fb25f2e,908abf0e,a87aa84,c8db5dd,4c2618f8,f2f74a77,6d4bf26d,17f55d0b,1aa913cb,9db869e5,ab861d9b,2043ccb9,ca8397ea) +,S(5e806e9,a644eb32,51c62ba2,f09a755b,96aec78b,4405df76,dc22ba6c,f7227ec1,b88c8118,d6a1829d,6aecaa05,742313a,b871d2eb,72f31bba,9d84f87f,a73e614b) +,S(f9d147fe,fd2c1a7b,f623d965,bc7901bd,968636d,eff54c14,34c6326e,d1c8de9a,c7887249,ab6686c7,93a7d77b,41173060,40de44cb,84980c33,cd548d72,d29caffd) +,S(b98cc956,85f6d11f,a8d38a1f,50799634,9f7020ae,3171023b,abea0fec,a70ccdb1,f074d495,3689e8a3,6ee4cc0d,40882355,3dcbdf21,70975f49,5712adbc,990ecf7f) +,S(f161cad4,100817e7,ef9091dc,714bcba6,18458493,f3bb6b03,4648a649,6817b474,b7eeb92e,396af324,22881eb2,45e62515,c4410af9,fa519ffd,61289f6d,9b740904) +,S(7c8b6c89,2ea4061e,456abac2,46edc08b,fb54aff6,8a2678fb,1b7b1c08,5326914c,f08e1f02,6ea1d2c2,9ff5eacd,2b34682,2960723d,cdab95b1,d69c8af,5e7692f8) +,S(4668c29f,16334658,195b93cc,ef71a076,3ab2078f,724dde5d,d3635eed,24f28729,5db228c9,8391ec52,324c723,39d99514,8fd22f7c,2f61cfa1,29ee7400,4c74ea4f) +,S(3443d0f3,9dd6da5c,19a39f8c,f3672652,96fa6729,c9290b2f,4e21c7e5,3167b65e,4b6db639,9a088ddc,8ed31f63,7c079451,14a4320b,b7ed94b9,2a87c0e8,97429234) +,S(d3ce3501,17a04e95,58281e69,3574c096,458dbca9,afac20e8,ffec7810,8bc227b4,bcfc77b9,628f6ee9,3541e47f,8d556ad0,7696ee6e,90ce384a,9b77fcab,6eb9908) +,S(c4dc6363,ad772452,221f8640,9de0ac28,f2bc1ac3,cd2d7080,23301560,f95127af,78c9ba8f,d789a666,439bc949,38345250,38a79c5,97f6a71b,3e096b8b,752d3038) +,S(c771f94,221a47ec,fcd78d7a,123d2e0e,1bf4edcc,bbcdd075,b23d29da,6d5ac666,4dee3b30,829f5aae,f4471924,65de293f,f2ec526f,5b8f5980,d9155f71,ce8d6091) +,S(bff88ce8,96338f7f,5b6516e6,448a1f25,36a1e9bf,275afd50,e772517d,79e6e199,8f3f0c7a,b62010a4,eb0b6211,7e9761d9,c1552629,bb55bf68,53274158,a788c206) +,S(4afcd064,5d57bf24,e850e7e3,d3cac224,6a467e76,f2ce02da,576a1f2a,9a3b97a,52f23b54,87b2af93,6cc692f6,1876d6c0,ef927d3b,c06df93,984ae54e,4d10f0a2) +,S(c4bc122c,b9bf0e20,57f933fd,94db012f,79e23c34,98007abd,f8a8ba21,32b1f373,e40c47b6,a31d81ba,dc45d427,3ab56d77,1daf76bd,7bdf8ce1,a8778861,66fbfc6d) +,S(487a19b1,d1be7791,ce223d27,bab11aca,837a0f8a,7d34d9dd,b4c68f18,51f821a8,a53cd743,16ff4e9a,8633554,45415e35,5552403,7b25ce67,f519e44a,a5d0ef98) +,S(274a3cec,be06c748,7603516,588ccffd,f4ac3d80,a85887f8,10632cb8,4301a326,17a24be3,afbe8b45,9a72cab,5385cb6f,5d06b47a,63bf19b3,ff4989c4,85a9f40d) +,S(32b31f77,b0cb99ac,3bfc34e,7558f9d3,e82fcc6a,be2c4,8a079106,33afa9e8,447b44c,c191da90,e0eb3f71,db804472,17f422d5,b1732a8,993da80a,5d8f5bc2) +,S(78c39dcf,55561468,dc339d46,ffd09337,945285e1,66dfc29,25d8b85a,24a2752,d691ddbb,4e41ca85,eebdf63d,5c023e62,a6680931,5e1109ce,89088467,7ba3ac55) +,S(5fc75911,a4920777,c4502116,deefc1a8,d2f21f96,2b1e725f,a04d6fb3,9d34e5ff,59f36f7f,18f5885c,dff524d9,6a139749,f3fe1662,4b728d50,7a460bb3,497512f2) +,S(ca1590e9,152b2b49,a6d0fc16,4e346e19,fa62dde6,f693b64a,e38289d3,ad08fa8a,46a7bb3c,1174ed75,49e9eae1,7126455d,535ea744,936947f5,24a8ff30,8046dc8c) +,S(5c715266,5ff0bdeb,a7f6e660,bf66d5ad,743d94bc,5ba9b7f1,f3d50cdd,9d11fa1f,7da23b15,56e995c3,a21ee9dd,ccccca4e,e41684a4,f208c39,b31ffe9c,4473a03e) +,S(c7f71da3,6361c73a,55dc3877,4f2e1033,fa0c09ce,1c9557c8,c29d8684,e4177e82,8d6e47f,b5c2cecb,6b22dbf9,a04f0f95,77c6f50c,3429df92,78edb85,59b0dedf) +,S(6e91bd9f,5264a13e,37925900,433b7536,4130b4cc,e6fa716d,a0101c2b,dc58afab,5baa7455,506b5849,5d820c20,f209aa01,ee0f9434,1df5b449,9ed23a51,b4fd604f) +,S(1f00de8e,69ac7cbf,c75c789d,f3322813,244907a0,35059072,68954196,baef0d33,2892ce90,f32330ed,2800c30b,4482b67a,e65fec8,41ba6fea,b2e83703,dae040f4) +,S(c00133f5,7d8c469,421efa3a,d71d8d58,1a2f5b0b,2324de10,91d79145,7d300638,3c76b182,d3ee982,dd05ea45,59e8e31b,1aa3dc12,fdcb67a2,f86434ed,34f18895) +,S(af639e7,95e8269e,12cef756,4bbf970,cdb172e0,66cde48d,2f8e9083,c60cad49,1bd01179,ce92cd29,e414a74,cd1de487,c479daf,5673b219,8082c474,2426abb4) +,S(e6dbd27d,5447c044,18fa0a5d,8ebcb9a0,ede58538,8b73ccd5,4e979797,31f4c9a1,77f38524,f2848320,3d4c780a,d0cf8bd,a2071037,348db8ee,6b5deabe,3d242153) +,S(f51a8d23,c95b70aa,d02dd904,ec1119ea,8d1e3e1e,e405646e,4c2dfd53,336360a9,426b2c9a,1d703cf6,c748871,4959acda,ae5c6aab,51945138,73e4b1a9,c0f46c57) +,S(e12f11e7,fe437b7,f578d8fc,33ae3a60,a3e4d1ac,1ee45863,42944d50,a0f6bcf4,22d15d58,35fa89ab,563985b1,4114c957,8bfec8d6,6dc7d253,e3c6d900,4419f5d2) +,S(e758860a,8ec762d0,62f51e56,d958a14f,ac619351,9d890bb9,bf6bc7ed,e988e14c,42d9e0ef,10b84f21,fb88d780,dcb4750f,10438682,3b003b23,ec41c297,567ecd78) +,S(3c933fe9,ba21e5c,d822b90c,78a54b7a,d4799882,ef91f2c6,e423a398,20a64163,c1eaa0be,531922e2,ca5b23a5,6700b4ad,7fc16135,11f67f96,b672ddf3,669080df) +,S(4757576a,83c9066c,b6eb6b08,e91a79c0,df828e4e,3c09ce07,939134fd,ea857872,13f22fb2,62d77f15,de3e8388,d9270c45,818248e8,9d950d7b,58ee6c6,c38277a) +,S(35e63903,70085140,b19df903,9a7fff42,46570fcd,8661caa8,129d6b4,31045c7,2855f4bc,aa9d60d8,6a44f022,b3c28e84,53cfb3ad,a58691f1,b0e9cae5,e5b9e8c9) +,S(ad446e01,1f118207,3565f031,6d0a85f6,ad5330dc,6a8be4fe,82be632e,32126fa3,240382f1,decee3f5,1f92b2f8,1ac0eab2,1d8acb54,2f730d43,15c194f6,28e83e39) +,S(fbe9e5f3,eb01ac37,820af752,9c4221a6,89164ef5,d77461af,f82d6400,6a718815,f2f30cad,d85a2e0c,e393e088,44de9215,ba207384,2abf8468,47801ff6,12d088e6) +,S(1e675320,d81ff430,a0549aa2,482cc9b8,b9b585f6,32d32916,6e952f13,3b038135,ca0f1276,c9c7d995,c5baa5de,2988700c,2e2c7f1b,366d1db1,b44b4c9a,f0686aa7) +,S(176dc770,23b0e52b,a2eb8068,ad27924b,94c3f643,30e0e85f,3593917c,d6267718,d2dc6288,5df75b06,f450686f,df660950,548d4f6,85d1a701,d510f3fe,297ca8d9) +,S(3c8536c2,32a02b3a,b36feadb,ccc7c541,7ac83942,3cfc8dd,99a0ab7b,41a9c938,a684eea5,249cd12a,d24dd8f1,73022ad1,8ebc7f52,d6a3bd9d,bdc4f5ad,a25186b5) +,S(48aa73ab,c61a76b6,e54c446f,ba881198,ec6ea003,d63c54a5,605a322d,7af006fd,c28c5eee,ffb20882,2d018506,5cf3ddf3,5977fab7,40e4d4e,cdbf9935,8e403a64) +,S(74732762,abd028d,9dad2b36,38baca49,263d170d,ca7e4cb,d83a3a1b,53cc1ff1,ca11df0c,e8dfa09f,3f2ef7ce,5c023b6c,927a88fe,60ba9f3f,ddfbd69d,e536c2c6) +,S(eb71ab09,520e5915,767dc918,814fe901,a4042725,5247c02e,b8672c5b,95698522,5fad7ae0,a7e95b38,ed6563cb,2023b2a9,c81b6901,c007f1eb,8749f56e,4d48e995) +,S(2b101bf6,c7763df5,72eda74b,eb179cc6,af5e8695,965761ce,f8444371,7ef5be6b,dd16c8,4e1d1a3d,98d4629f,ef258421,f6664719,7f89a597,67fe862,3f140ce9) +,S(a099efa8,2c666552,5332b050,75e81ba2,13976afe,8f3b33eb,ca2a4436,6e0ab337,f883957b,5cf1f2b3,ddd6c7fa,a126acca,fb1e33b5,e5b753ab,dc0a99bd,5d136c07) +,S(f4396856,a61c3ce9,5b72ab6d,470bdeb1,8cc107cd,2f58f15,3d5bc99f,8b62f95d,6e3ead1a,a8edb0b0,67240ca,f3274e63,df81c2f3,e1ef2567,cfd76c01,6e9f6133) +,S(da732197,26aabb18,4a0aabe5,a493d803,53215b7c,49458008,bd5e387f,694050c0,e2075f29,17724b68,6bcb987d,85e954e1,9489af4c,e7ce1b46,66d84604,e9a0eeb6) +,S(99171a1e,19596183,f4259c09,b9740201,8fea44d1,4d0f2f45,75f4d66f,980a6792,522b840c,83e1eef3,e7f2cbd8,e07bec0,66af1bd2,e7607f5f,27a767b1,75219a4f) +,S(353cc684,8a2c4f36,2408997a,944889c0,1db7bcf6,9133323f,8f0d34ca,758cf08f,1865bc62,f4ba0156,7e2b283f,702834c8,97effd14,6e0e5fa2,43d5124d,ce67ebe7) +,S(8b16983b,5053d3d3,8e67c77f,1b6fccc1,b9ed7e3d,d57a26d5,deb242dd,7a312852,49d93f92,fa5953d3,956adeed,cff49ac8,caeb3d2,c72a0e9f,be6c85e5,d85d47c6) +,S(68f5dea4,b1da327c,227b2513,83fb622,efb36730,3bac02ef,505e0464,750cabc9,26740f9c,5d624b9d,aed25774,46c9c742,146de045,71cb750c,4356898f,e3d31782) +,S(faf5207f,c3acf00c,8e19d8bd,7208a6d7,cc936706,98559244,e74bb202,20c699b,fab7b446,17a6c6e5,4ac186ac,971de8e7,d42c1527,8607eeb,b8564a0b,cef1936c) +,S(c3d1aa91,b541c5bd,3da04707,a2f01a16,917c0420,a26604a2,bcaf5081,e8d17630,5b57806e,5a58c405,f06d7ce5,4e5f7b45,c9b631a3,44c92c64,d8cd1435,fcd9ce27) +,S(23278a35,4970b920,450db526,391b30f2,54b5bd5a,fe2c1455,623c99fa,8ac8db1a,864d81da,e8df9e47,1ac93b74,660542df,3570486b,fbd2144d,55dee441,90e1888b) +,S(602f6181,33cbca4d,74de4ab,29dcd101,7c12c32b,ecaed25,485765c5,478c0146,4c42cfb7,279ec350,f77d2da1,599b9c85,9ffab342,ce6a011f,91c9e460,27aa968) +,S(1dc4cfc7,126c3b2,5d82aa46,3dcc8cff,c545a9ab,c7962690,fd4ecaad,25843ee9,a9357982,5c535575,35820f17,25e32afb,6002b1b9,2a9b43ac,18225e61,b3fedeb1) +,S(3694f121,6e02bc79,14cd9910,8ca65fc5,887a95df,8b04e8b3,3c6c23cf,ce35af82,7ffee291,b1c41976,d456e742,88458b9e,c61e57c9,9b8386d1,d1c36424,38555d88) +,S(743ada75,a9596420,7b8725e0,af06c2c4,457be03b,a920c3b4,b65922b2,1df1bdbf,8f2b81b5,5ac4c5d8,9cc23ed,92dc1b43,5629b9f9,39b126c0,b16d7175,b40f908f) +,S(bfe9397,7c7cc4a7,b9cc42d7,f044607c,f047cf2e,26d6f94f,210af7d6,b2420085,625d6059,8f80dc83,1ef2b51,dee53d5,666c3dfe,a02e1d92,1260906f,ae373d64) +,S(86c02c0e,6ee646c8,c2944751,7867a1ad,cb56ebff,c8795f83,73e6d8b9,1b240eb9,659b5e9f,da4b1098,b76af529,f56f809,59d39f48,916477b4,bfa66af,c85be4ed) +,S(3b281045,857f01e9,995d357d,3a84dc66,6c4f8f47,4b82ace5,dc3a9229,387bfda4,9948272c,cdeb1542,47c7c42f,1f313dad,e318a123,3f500f8a,16d80e7f,d2e9fd4c) +,S(cddccdd3,b54d979f,504d33d,46d6ff2a,9859038e,33087a3,da9a5284,fefc47c0,9f2a13f8,369313c1,44d91e5e,807ddd65,196c991,a7eb0321,2133aeb4,56683b8) +,S(98100502,a6023ddb,ee34462b,d0232711,8f8c2e9f,33708088,40352c34,870e16d7,1a8bfef4,69af3b3b,1e381c08,454a84ec,4cf8fb66,bd721a57,47a94e90,1969b9cb) +,S(8b76757d,b2fc179b,9016847,9b82124b,c26092f9,b35de316,c90223e5,99978179,47eaf326,588e65ca,541a71a6,a1167321,ee449268,1e8b4960,6eaf9a73,42b16f05) +,S(e66ed7dc,897fb660,6f44d8a9,46b0c61c,45c83bb2,d55ea771,bf2571d6,7ecc3b43,e536f79b,8a9fff4e,c6cffd47,8a405bd,7f1745f9,9374d810,518cc5a9,f214dcbe) +,S(e0600592,cc9c0b9f,8cead065,6ef5c115,ead63209,6a0a0d2,2626aa13,f2bc88c8,628d94b7,8b84705d,16e55254,4c138416,e7f75f5d,d549ff7c,a42d51cb,7f5a584f) +,S(1b0af242,a9cf25d4,cc758fc7,63e2f07,62db2e42,6b392cfb,ffc5ac07,19152767,33ae8aa5,eec30559,a3d28da0,d9354048,592dec4b,2f975a0,ed043fc3,c856a2be) +,S(e204ffaa,142f7eda,3505beee,db0bcbf0,9b80924d,ce5bced5,439aa4d6,af5acb7d,a2804d9b,98e11519,adeacdd1,aef2c22b,a02f7030,479a559e,6924db49,5d8911ba) +,S(afc40e67,651531f6,214ea1fc,13173d4c,a35431f4,92845964,69cf099a,d515ed5,57ef6ef4,1e480de9,32ae8596,3b04d267,5e629707,cd3bdb45,5896d333,b648e0) +,S(59538bdb,747b641f,800588b0,45c0e3c9,72963406,5ca601d4,690dee22,abe8d226,a030486a,3c919c35,4c26547a,3de96087,52ca7a28,5d378e28,652031dc,ec2d4438) +,S(6a91d34f,c38d4028,c63a4bae,bedb2a76,b964cf44,1804a6f1,efbe469a,a997ed8f,32500c83,6a0b5274,2d2ead10,dd3e73eb,45f221d1,ca6cea00,f2b01d75,d9073260) +,S(9260e687,b11d97ee,97dc44ab,5e21c344,332ae39d,c85c2ee8,f7760cc2,8ac28d61,f47df3d,e8d8654e,f7124f5e,2dcd9d95,c1d13e83,a33e5d18,92ce9851,6223e778) +,S(3490e733,7a66f301,f678561f,4b4f293c,b48820c3,dcf9be06,a0390410,4cfe3cba,49591a79,7edb70ac,74f87636,85bbb22a,a8169536,532886f1,f5ea0721,5e9bbd6c) +,S(9729f4fe,1f47a9a3,7dcb1311,ea9548a1,d71d7a81,27803c8a,6ec0a680,8d07b4a0,56e1a5d4,ccc4fd72,8e7ee569,e22efea5,c8f03d73,fe8ab86c,2dcb8af2,eb17f896) +,S(af63904f,6da423d,1cfd77a6,680044f0,5e694eb5,80ccb4b1,c37d8d83,ae9c2caf,6decdc2f,5fe2b948,d15fa10b,4a7e2edd,b8cfaf0f,7c79a400,f3d1b306,dbe110b2) +,S(96271f72,1f4a1f21,a2274edf,87c294fd,403cf0e0,c7b7b1f2,f242fb7a,2c435a3f,66ffbc73,1fc8cfd5,2bfbbca4,49f6e949,71940077,ae411e79,51cf5b21,ca5adddf) +,S(a42ef215,1f0cc5a0,15827287,eba8d960,dfa5a13c,7ee2696a,95bd94ca,4b717c7d,5e491ed4,5f08a591,32296929,814608ee,e3243172,b523a1b,a4995f6b,50046fec) +,S(193b3ded,e770a757,d859c289,68be2780,fc4ce92b,135bec2f,7fb2c07b,b862e5e4,192c4bba,ffbb735e,a1d5cd1,38de0556,d1d1d740,980c5775,22d19b5e,f0716700) +,S(ccf9a075,da6f44e4,cf3b4fc8,26feef3e,54084b0,e2756029,e290a7ce,8c1e8dc7,d04f844d,ccf2c30b,9020f0a2,308219c6,a5d6491,ffe9ba67,bf6b20c9,9a35a183) +,S(7ebea25b,1d69bb43,f60ec69e,f9853208,d3ddffb9,6dce3831,873e7ace,d25b0140,24540af2,bf87d637,54f1a47d,13a3f38,2a948375,8955dd16,fc83e7ca,4fec3d65) +,S(c9eb4a,c2a31b01,9b7ff038,38478b6,674662eb,d729ae45,d7111c63,84a038c7,7e2ee03d,caed3f4e,bef2b90d,78ae42a3,12f6e8b3,29d116a6,e26bdded,81f32240) +,S(45756e0c,8c84e9e,a7b23bc5,cfd87b4a,cd0b290d,86c547b8,7fed946f,e5acd867,9c3f522c,e577c017,3db984c3,d7dc16d0,31326e2c,85b08413,4611da0a,70acdd1f) +,S(1bd58481,21bed636,c789e341,665e2477,59438de7,10aba25c,e4a0db7f,13e3c0da,cb0eb897,bf905399,63a8a7b7,50787430,ffd4d6d7,9589c8e7,350f4351,4786a90b) +,S(f199562c,8e809ba5,84aa80a9,759dd98c,32eda7e0,ccfa4063,547ced9,d9324dc1,33519ead,76430498,949dbcea,33ca14de,2f7ea811,cdd38f32,4009ac7a,b408d1d0) +,S(7fb4e910,e9e37dc1,f56ac3b9,30589522,975319e9,84dcb559,6743d3d4,f45ea6f3,b74a03c,cdbec9c,f36b59bc,fe3203dc,5f4d94a7,bd54c628,55f0d04e,67c960ee) +,S(503d08fd,19839d78,aca27020,54dc4233,c1a1d68a,6b9cf136,4c6fa9fe,886c03e6,84ad95db,9a09eb87,bd905914,473d23de,698459d5,7c436f77,58937bd1,8e448e0a) +,S(335c9204,e6aed3e2,586d0dea,c87158a5,62db42c8,e42fac25,9196083,51e1e713,15b359bb,10f8bee2,940849d4,212fdd84,49b60c5d,d3419ce6,7ef9f0ac,f4c1c2f9) +,S(ba68e5cb,e0f7159f,821117df,5720bb50,f218c298,9ce3f5ef,30c44134,2834bc9f,2ac25bdd,ff34e4e,ff45a2ed,e412a287,101ff447,71c657f3,ca57bc94,40fa5d72) +,S(93d6e713,311d8430,58c20267,739c494b,446d7943,a1e47a0a,2a5ec20,877e6baa,5997c19c,99a2fd26,e0471041,b509f9d,e10bf615,7cd4f24f,db56a65d,201a0856) +,S(7a94bc1b,5cc77a0a,73a84fbe,c5d1b68,cb8f4626,8ecc0c22,ac7500a4,5f397172,128c1c6e,82a4d52a,719c9f8c,1bedf4d3,32d3695,16decef,34af6b4d,578bee5) +,S(f031eda7,c19383d9,45eec848,f6f3e467,75fbe52d,bacadc54,c213c596,c821b809,b4a78d0d,1c17e4f5,db81e2e7,ee52f195,eb505d36,af96bea0,5170c776,23cabab8) +,S(86ef1acd,5c17e082,dd4cb924,c74d0195,ce9f375,60ca7608,57ab7d70,2039907c,6936a13d,b9078ac9,426d34b1,6d5673d,36c3105c,9cc77de1,ef7e0ec2,4cf3bb3c) +,S(fceb6cc9,c78e3a35,49b9beeb,62a14fb8,6d24eec9,2ab10bc9,40916b60,cbc6d720,7c2e6024,5f561f1c,e0b69701,512ca518,9f8d9292,ea75562f,8b17873,77f7583d) +,S(a1d9ed1b,9a36f348,1f426d83,7afe4380,d475e36e,3b140f3e,cd2213ee,dfa5c8d9,3683c97c,a1273f29,ec02cb77,9e9fee54,78bd5e3b,e6aa8c60,7d5bf07,dfa558a0) +,S(d98de999,6311ed55,e15bbdc7,58affca1,3e8f629a,77eb3dac,844f90e0,51bd48c7,8af6194d,272a8ee7,68d1b810,778e5c2,69394353,969d77cc,7d449f2,84ef2a22) +,S(78328db7,cd6afa29,b6f1ba80,d65f8050,60f4d223,9897a3ed,bee8ba3f,a99aac60,e37e496f,1d143ac4,8123377f,4e136442,629f8185,c4996f01,f35c7a9e,76fc5efb) +,S(3d701493,31faf0b,37c1e1c0,9b29ee6c,5d9747cf,cdb26117,223d1f66,e336db5e,d1e99140,8311b20a,b41f7ce0,ab4e9dd3,414ea3c5,b87f88b6,648cd1d3,e77600ad) +,S(f619acc0,47e0d4ab,bd5ba2a,7a54ecc4,e223986,fdbf7a96,e90f762a,ce288628,f24eb63d,e1545d10,fc96a2d7,e7fc1ee,f9cdccdf,cefb5de6,8fa4eca6,781564f2) +,S(cca809b8,71f85a00,3344a851,4f797fce,91718f35,9e2fb489,a1dbc00c,aad0a2d2,b7d72ab8,35658359,2258f260,a1f62f97,aba642ed,382992f7,12b11c11,6890b037) +,S(bbd19766,ee2c501d,afb4eec0,30fba145,aa26c45b,51c1beea,a7d3ed1c,7dc81958,bc709dff,70b3612e,7cf0a6e8,9724442f,6c1ca4ce,c32efcfe,b98f1acf,df5250fa) +,S(6a6fdca0,e4a58197,267a1938,1644aa5d,ca8f0ee8,3a68a5f7,9c34d4af,ec1cfadd,c28b1236,76585255,cc104298,d7ebcc70,6bd7ff6f,cadb0c36,db6517e9,d2732081) +,S(922e3e1,fd401a22,ee7d693d,e52f0ade,9564af2b,17a4be0,2c553216,df5c8006,a7b10065,aae84a40,b9b79e0c,5ca8a227,696841c7,20b944aa,3b9eb1c4,1488f757) +,S(53ffae4e,3526b553,f92bd9da,e3cbd3b3,aff8a6da,d4895490,38382f98,a676eac8,81fdfcae,b51f80b8,3d23b222,8ce860ec,9e665292,c456fd23,cfde43ed,99f8c6f4) +,S(14a0ddd1,c94596f8,9d3e7028,929cfe4a,7c2e70c6,b55d15b9,77227862,a03d119,2b5dc071,febe1d1d,df7e1483,53dc6558,7e8c94ef,b598ee83,806f1fbe,976dd086) +,S(7368240d,fb74f35b,b51a2542,8caf3b90,bebe272a,739eff4d,c0150f1e,3d68c8f9,95392b17,b4c5e82e,774c7168,7c46469f,21801a72,b15cbcd8,fd2ba85e,e4a7a27f) +,S(4c0a8053,b9eab39d,2396825e,2416885f,5fbdb610,7bc5879e,6400d010,20580560,85a222a7,5b7de532,617f67f6,5408b79e,f5a6f826,6083c2f0,93ca97bb,d7db5427) +,S(ca0d66a8,24a6f8ac,bd9447a4,933dfcb2,6751a26a,f5790a1e,91e32053,3ddabbf8,61cc898d,4f8b0845,11dfd49b,1ef01e43,6f7d7d08,a5f16b2,1550f329,79395d18) +,S(646a0775,e62f6a36,d520763b,5c7fb081,a3d7dff7,355cba76,45358a6e,55e9d6d4,3e528844,e7380a64,20db2366,22c936f9,b1100046,e17c66f7,a6b1a01f,7b7dbbb4) +,S(435565ec,f3d6bc13,142d7c47,7052da71,bac77f3e,a81107f2,30303003,6455d070,4ed52896,89fd8d96,343ca8f6,c9f0c70f,ab6edc5c,1ae96d15,9fa9eb4d,a4c9f6bd) +,S(d8b01896,9328544a,a51f22fe,e605c693,7a014aac,37316f,ff6a760b,93aa8f9d,63f51e42,a2b879ad,36d60719,c1497b5d,dd412782,e4c620ac,989f7259,3a06edf3) +,S(b9475950,4a9b3052,94af6f2b,6f182e5e,83a30abb,47f0799a,21ee5446,d63d48d7,cbc74028,37a899bf,79b89676,9e358ad6,9680277c,34ae1018,4290689,c2fb876) +,S(14317c49,2972d5be,c5a01b5e,34842135,d521b467,1b262f0f,c3e6a271,ff8e0ef0,cc4d2235,d1cecfd2,2e6a476a,7db483d9,d318e79e,4c3486cf,c2090651,c2069381) +,S(8bbdb357,5b6867f4,4f062ab3,38928d52,78c4b873,4e95c5f8,fcddd4e4,9d44f8c6,d38d3387,32424054,c05a67e6,c7d00e62,1279eca2,ee1b59fa,90b97f33,5173a778) +,S(7775fef6,36ecbe78,9279786,b996c0d7,380b00f9,4ed31476,1ab0b190,f06aa685,53152a73,162dd659,dce57d7f,cb885c44,34243153,2b8318e1,2a996ebf,2f55407b) +,S(db5e4bd1,39ebe377,bca64950,29e72fb4,bc9b0ea5,5450e42b,a7491c0c,39693b48,a6468113,a5a796ad,a337ceb3,238827dc,416ca20e,bdbe4e62,14194e66,cc5a0abb) +,S(eab057b0,578c52e2,eac11be3,9f069cf1,6ebf0631,709560fc,2414ff11,f1c619eb,5422023f,cf69b8a8,458e5c6c,3c2de1e8,6fb041ce,180c5f75,cddb455,fd023f67) +,S(e955fcd3,c657d611,7e2d43cc,651333e,c231ba32,418e6fe6,d021183f,e7f5e44c,dd0eaa98,65212f27,2454953a,4c46c5da,973095fc,b2e36369,cfe228f4,828e6b57) +,S(5f5a3c57,58eafc30,c311f596,f1d6605f,ec0f5e73,eafb27a7,2a07f91b,42d8e49,3cde0b0,1d1fb2ea,9d85a04a,aa4536f5,c6d9f55e,84ca890c,cf23ef2a,5dcdf1a2) +,S(fb7a31e4,ff0ade1e,efffbd7a,e04af118,49c82cf2,6ad219c0,7572d924,8b99bab,ea87aa0c,431de57e,ee86bc4e,be463dd7,9e69102c,736345a,5502b07f,31df2a01) +,S(d57b1d6a,a3e87779,4b9f8dd9,683ee3a3,6ec18d3d,e6b22b44,e411778d,4bae1ffb,256ffed6,b85bd2f0,9dadb0e,43ccbaec,9fcb9e57,22d88ca,73f8d7ab,dc0f62ee) +,S(9326fc52,d3a24a38,ef0fc90e,183697b3,f726832,c70bcb5b,bd6ac548,cbb8f1a6,863bd0a0,cc0a2bea,d21176f5,c99fafa8,d7d766c2,54d57308,1a58a6f,12889a2b) +,S(58362cd5,abc9b5e6,57617e94,620ad087,d5d310d5,313ef6da,36079b4b,a93caff4,5f2a404,4e86bbd8,d73b673b,2e432233,d6923cf3,c262e1c0,3da48d42,f62fc52f) +,S(7dd488b9,cd06e68f,e01b3a9,6b318d61,b8c4cd69,7e9a3681,34fce81,841738ee,fd7aa5ed,130c897,cb770846,a3d292a0,d963ded0,5266010f,34a99ebe,99782cf) +,S(9bf78b02,524c1554,3330d7d5,a3b41705,1fa2a324,6ba8061d,f9550640,cfe798d,59f537d6,6d2e6801,d79d5a70,3b4219c8,c7d06385,76964f48,10427548,90cf5a83) +,S(4c816973,743ad5cb,18db4f87,9bbd6d1c,e71513b6,eeebfc39,3663dc36,eb3fc47,1a6dc6ac,37a49400,a933ef09,f00f9650,44c6f8eb,d516c254,ab142d89,d41105f) +,S(60636bc2,c7486343,59296408,40f3a26c,173f4e5a,7f0031a8,35c1c56f,b1051be8,71a78b7a,3aed2bc9,70a4190b,d1be56e,efc2e6b,7cf81b08,541dd8f5,dbe88e8b) +,S(a6e772de,c3e90a70,6c663fc9,4d5e6cd3,12211537,40ca4a2f,47a0f3,7f8d00a,25b8fe1f,5c727181,4a6175a8,10aa1eb8,f1090221,d78c32ca,76ba7c73,d0eed520) +,S(79c6653c,60307215,fabb4b2a,aa8bfbaf,1692f613,166326c9,19324e5,7cb89262,36d5ed12,b6b49496,e2b79da4,c0955cbf,c24eaa3c,204e28f8,db1e7ed2,d2197bcb) +,S(3f556b2e,4530fade,d4774af4,ce4454c3,4a2bdb4e,aabda42e,d4ba8546,d646cb15,bab1d321,1ce84331,3be8996b,f5c5c4e2,c9fd04d8,397cf9e0,58829389,ecfd25c3) +,S(eda59a23,8d21fe9f,5e11e0fb,cf731fe2,d645c52a,f3861dd9,3b7273b7,3fb3913a,22f22f01,4ba320b8,2cc29c06,d75b7eb7,d3cea857,40cb2562,4161b9a8,712bbfee) +,S(7a1ea77,323dfb4f,36958adf,71d4f03,3a2bea2b,a9f62cb0,c42a4279,7de68548,4866ce25,ee7a2b5d,a276f976,6261318c,6d2d7f51,f6f41940,f6cc3f20,264825a0) +,S(ad0fd3a,ad62d6d0,bae7c51d,590876e2,33d1028f,62d5c178,a0ecc3d9,a323de2a,88e024c5,9672469f,54f4a64e,b792d761,d163157d,ed982787,a6d40382,83b0601) +,S(1bf19432,f4044a69,56d6e9d6,7b84a5cb,ee743771,8d634dfd,20706cdc,602729d3,4114b200,afb6a1a0,75ef8e3e,16c37e9b,4f2acd9c,3fa4e922,63d1c430,7c516aa9) +,S(514616f2,bc2dafa,8be3b9d5,f00b694d,2fb1af5f,12d219af,c35204c2,e121d93b,3e5cee53,608a299c,f67f4e0a,65adbf2,57ba8eb7,450058a,74072ccf,922eaf9c) +,S(8e3fece8,5338ed31,93721d18,1cff34e4,fdc42330,6a8e1a1c,3b002da1,6921a661,b095734b,6736486b,676dfc24,9cac99ef,12894543,8b333b2e,77664f8,20f686d2) +,S(46c06820,df101ed2,92842186,7d8a20b9,6db1eb9a,ae63355,916d438c,a7ad4447,fcaa10f4,59bb73f,c48d1b60,1147b535,d7d43958,1bcfe26f,9acc7abc,ddf1afa9) +,S(56334df7,1f9b390a,b001e406,ab37af71,3fff8c69,1c2eedba,fec7dbf,cf722b31,22d04394,340dc156,a73c4b0b,f49a6c93,8a3724c4,4744690,4af420bc,726707dc) +,S(202e246d,89045f8c,9dbe3dc9,7ca52d23,b2fd55fa,1b5cbd37,cb882663,ca67c4f,f4e6cf89,9cbcf023,1c9f661e,c4588072,7a6241e3,513cb365,9a2e7b20,a17a62b1) +,S(c8054ee0,10211c2c,f5bc1ff9,43552eff,c56b635c,d65e409d,ece239e9,9b9bd4d5,f50515af,51601cbc,de6842b4,3b854b05,bf1ebd1,678c46b,46e22827,17f31057) +,S(9c29788c,235eb61a,d2940708,4b9701a1,ea3282ae,56f984f5,1c625538,14438383,32111eec,efdbef2e,236469db,4ad30e30,c116cc42,99dd286c,2ab70ec4,9759ead7) +,S(5854e8d0,b7b5c394,7068dc86,f94c3cd6,72999023,367509e7,4bc1745c,19a57ef8,7e7901c5,c06bebd,f50c4113,4e0d2d3c,edafec05,417d45f2,345b75cb,a63eb98d) +,S(8bb2fff0,f45be789,a0446e1b,3547a44d,1104a5dd,9c8e50b7,4d0fa891,f73fef34,c332e365,a5343ea6,6c571e2b,c383f767,efb979df,72223a79,35da9173,73b182c1) +,S(ea88e65,6ee43387,86165faa,cb643cda,992f5656,dc7333c4,5ad8b561,8ccd209e,c38c40d6,4a7a343d,8ab357ab,845725c6,af9f4f4a,843986f1,fd0a83a2,5df0f909) +,S(c0c1d4df,857c7ea6,13322c2e,e0d4ba2a,a3b18ab8,cc8d9ff6,6981d6a9,4446295a,247115d1,e8eef7d,ce6ae1db,ec9be46a,9a284648,ebb7a918,7292fe05,9d72b981) +,S(91e6a4f9,407d3600,2a808d8d,db723ebe,67b8e212,792ba65d,b74e028c,ec7fc72a,ef6ae560,35f58be8,5cce98f7,b2106e0a,12e57dbb,47a4a995,47ee5041,3c5721ba) +,S(cd749618,9a8c1d36,2995cf61,380d0366,24a7a402,e21cf078,18794e08,fb208454,f3dc92be,15d1f912,a03debcf,88afcaba,2dd6ba2f,1d23a4f6,ba02c5ed,cbaf0bd9) +,S(99f5d12d,2e68e70,c304f3fa,44eb24a6,85f63065,af0a15e9,f71752ff,82943018,59f1921a,d97ebf33,68f962c9,c0a297b1,dff9f980,246d5dfb,61168dc1,da0b8a9e) +,S(63c6cd30,f9c07096,11656b1e,75d17191,a6ac02db,9debadff,7b3d602b,b9f7608f,2e439373,70a41b8f,e0e5f0a1,3ab75be4,6d8b1ef4,ee71723,4b73ffef,461083f0) +,S(b7407f26,90a5ea11,d9b7fc55,17e6c1b1,9e04fe47,180b1e93,94cd5e97,5d184d92,1b953929,47dd4984,7420f727,7a6796e7,828ee880,3e0d701a,aed8cf7d,513de6d2) +,S(24979116,161c8840,dd521e96,27a50056,c29ce48d,d86b6297,150f9a6d,e383fd40,13dd71ab,3dd69cf7,384d3e32,5fb16648,76f99943,f7ba3649,143e09b0,28b9a70b) +,S(f109b6c3,6122b278,8656c80d,4c84150b,b419919,4650d96b,6f2de8f7,f9d73b7d,a7457369,bef8d54d,c0a91d4a,39496f85,bd971f6b,4a13dc77,142ead5d,791c96ac) +,S(59b303f8,2031c370,4f17c929,7fbd0ac1,36be9900,a26b5516,9f0e3b6d,69118df9,30c7c4dd,1666271a,5ac8c936,b35068c1,9830306d,c695e02,d6c65ebd,2fd678c3) +,S(6627359a,eb3910db,4ba54cd6,c7b884c9,a678621a,d2bf6cd6,6023974e,d462fc52,bcbcf9ba,d2de78a7,fc486734,79379778,feab83dd,ea4f50b2,555c457d,a910d487) +,S(76fdad80,c4fb507d,9c9d2305,90e818ac,ec7efc04,1184281e,9212785a,dd51f1d9,cc8cc7cc,349cf307,f34adf7e,f559855b,9b88b70d,7fc9d19a,18cecddb,e3a8c346) +,S(7893406,e99cf08a,52fed9cc,4a9bafdb,7f2380cb,4c288700,b983b791,e1313330,ec15e1af,39eafe5a,d081acd3,fbd5b8ec,d0c2e83b,7a5b8074,50ef80af,2511d149) +,S(c454aa4,e8d02133,ed93c229,d0e834f5,18f16cd,d83a39ff,3bbb1ba0,838c81d5,a98e61cf,89c43808,f4895924,529a6e59,8af57be6,debf5f5c,67e3b3a8,73ac51f0) +,S(ff0bc21c,cbe5c122,dd2ba8f9,64239010,97dac1ee,3957b27b,f990b611,72402880,c34089c,1f7b2181,8d4cd5f8,9e445ec1,ecd634f7,52960da,467cd396,77bca50a) +,S(8e4486e3,49a0423b,d8132e39,812b78f0,3a0e61e9,d3eb7735,86f1e279,3731c301,897b24d4,37cc260d,52e1866f,4dc222ed,16bbf084,c108883c,a8a7b9b2,9a2053a1) +,S(4f4ca57f,84f5c4e9,6aca30d2,351089d,bf7fb6c,13847584,590fa5b4,4dc579e7,d53db7dc,1691556c,36f1cb1f,8a1b91a9,33634975,8f28d0b7,17d250e5,ade63a9e) +,S(fe8924b2,d7a24fa9,5c61830,aed8fba,79b3a96f,388b6423,c760aad8,cfc203bb,bd303e29,c6be0e2b,f4e79df9,cb17e0ac,e92c3784,fa8c26a,7e3cea32,d0b056be) +,S(3099f75c,f6a8c72f,8685895d,152f99b3,8ed9a3,320f3fc5,dcdcd14d,c46abb5d,fbb5bc2a,ec76529c,a278a32c,2a95c2a7,4a939c4,c0e2c0bc,6fc20b2e,a6fc9f1c) +,S(3b939f83,f84126f3,b6632de0,12405c9f,43244322,2ac384b9,7415c2dc,9c72f4eb,843b7353,ec454380,e9d4cc20,23a138b5,c1e602c7,f48be55f,1d3c24ca,f05607fb) +,S(dc7506a0,4a50e345,dca3cbc0,6384a938,b032f197,d6d30932,7b0c646d,95c732d8,fe942311,f6d49d62,99f9559a,3d16f43d,c6a39d4e,b623f9ea,e8dde39d,9bd5772a) +,S(f5a4c596,c6996a35,172fb61a,2721d75c,3dde68fb,4abc9433,f84d20ea,83b30dea,175e0d3e,77d2f63b,bb2ef922,d30b962,fd783b30,ef7dd8e3,5ae680bb,9df26572) +,S(7e9038e2,c499049f,e5d222ae,2f79f4b1,373c2f69,262f133,cb9be1f9,aea4029e,3592e66a,343335bc,e016276,6550a363,1d7dc64b,2223bdfe,7146f32b,8025c737) +,S(80f22f73,d16bfc6f,d6c28e92,1f990eb6,e2cb803a,d920850f,af489ff,f62b1f41,8714a5d3,c5ee74bc,73e11fd,24cf4d80,370e6711,c726ed68,2a1bd77e,7b503b28) +,S(498a2ae9,e86e53f8,43470a58,ab96fe0b,7c3107,d9d23535,fc887bfa,fe0c897d,47aa9eb3,73e841e1,4260f651,6ab3081f,7ec3809d,53b8609e,c3cced3a,6401bb53) +,S(601af64c,d14ce184,ca52c542,7a78c746,8e9c069a,80277b6d,960ddf30,3b3a010e,2900a63f,ca1576d0,11b46c27,32c87ef5,56dd579b,3bcd59,9161cd20,ceb7fa18) +,S(8fb2e0f0,7b2fcbc4,ad58b06a,822aa683,957f2bf1,5dd5984,9a1341ff,2d74a25b,7cd82350,8d797cea,b1b386f7,5d5f82af,6137dc9,9f6d6e6,b7c68cb4,75070aa4) +,S(336d780f,e9d14e8,b55a1498,72c63bc,83468eaf,aef3282c,9bde58af,6a69e6d9,92d1004,be45bee6,b8eeba68,2fd0187a,ac3e6679,f4fe0fb0,b723214,a63d2261) +,S(507ac721,f4d58704,4f8d2cbd,fb03aaea,b0634303,cce3e1a5,e4e47efa,90d5872d,b89a398d,e7db05d7,a1055093,97b83d60,9ba53c95,39caaf0e,917d22c8,307174d9) +,S(c42dcec1,3bb7fb96,29171026,f66c012c,992c604c,bea189a0,46e688a9,473ba343,8aa37731,a53223cb,a021bfe7,c413929d,8fe010ec,353464b,e3c1ce02,e54f7bb5) +,S(b02ea2c3,cd6093a2,d5e6b5c4,5c510848,857eedb6,50038417,d9f41947,2a866a2c,ebb45c50,cea190c6,1bb7c505,8cfce93b,ed1d8ee8,c75a5bf8,6ac9c127,2fa5527c) +,S(f4d193d2,9f20ed2e,273dc2c9,aeab43b5,85626d41,59b7edb1,51e17c45,ef70d84b,bda19a3f,19b834a2,c493f8cf,14cda579,1f84b6c,611ea7e7,280e5196,1add0974) +,S(8740dceb,19eac62b,75859b9e,4d0302d3,cc84f6bb,1ff6e857,eef7fb64,fe5f1bb0,a729eb0,4783205a,2e1d5b6e,7eb5221c,f2f151de,1489d1b,1d98fb68,e7c6ca49) +,S(79ec464a,85a29f08,d910bc94,449ce88,50aec626,3693bf6c,92a5ea23,84fcc9cb,77d170f5,b52ed0b2,9aad476d,85abae3,a1d7c544,c625ba2c,d44e68ea,ef53b39) +,S(4f1018d5,dd54bb71,cbc0e29b,255eafd4,6fb3aac0,45889238,847efcce,3207fceb,c32819e5,d23cc2e7,73a9b2a0,271fbe3b,a64531d9,2d416222,24a2f64e,3be7dd8c) +,S(dfbf1936,2094e85f,ddb25de6,8ca85cd4,e53768ab,81780eb0,33a0607b,fbe969a1,25ea0b59,33ba21c3,2ac5f1e4,932debcc,a2ca3aba,e0b7c671,93d97e1d,af80e563) +,S(184c66c0,2c36883,2c1805f1,8612449,940a371,54174f9,b67bb41a,85226649,cf63fe44,f1cfc791,4fb4a24c,1e0530e4,736f815b,a910b487,ec4fec7d,f8662eaf) +,S(daab3606,d386e04e,e39a8a51,a8242e43,ede9de09,f50322e0,a0f410f5,f043686,c0ba1c4,ebe7d10,6fd0d0ac,4e8f6e8c,fbb2b682,3a9d55e5,dbb7718e,d411718a) +,S(a887f4a,5311f252,ba0219d1,f848d334,26b0e216,69020dfa,89dcc339,7e04530f,5a7c04bd,8c37cac7,f429bff3,eda01dce,a5b4fa44,eecd3195,2878f79f,9dedeace) +,S(1b315664,409feb98,4d5dbfd5,a85afbce,4784a907,b284958d,28123f61,7c2d207a,2972cc7c,ba348e5a,5841d463,4597fd57,84eea5ba,a99bdc37,3119c568,aba205bb) +,S(154adfd4,27c30d56,d5f5de1e,d7e8465,6727e69f,82ec8d1f,19dfa16,b1fe4984,5ba86e8a,324b279e,449f61ba,a7fa52df,882477c4,921f2079,98199775,3e0372b5) +,S(debd69f9,fe55c15f,b28df417,cb1af3c2,585fe89f,b44c2f94,94fec0d5,88480994,98d8cc21,55c16d24,e8b1b831,4fcf616b,2564ff,9345fc9e,f8de3cd7,57f9708d) +,S(9fcd3490,2a7c54f9,a2855fc0,9558c465,e0316c3d,fb72c66b,71d4492a,efbaf9e2,a7ac4160,c2b5a416,89e9e49c,8d5aba67,143e1de8,26498be5,1cfa691f,f7f5d14c) +,S(59cacdf6,fe4bae99,598fb1d2,df3de7e0,586fd792,eee0d9bb,fdabfa73,8943a727,7c730d34,7b3ead16,c74d349e,191c484f,624599c4,d379acf,ed8d2341,160df035) +,S(5ce1abd1,fb291d97,db3a4c9e,c4ace635,34e6b373,407a8821,67722fec,7fb226c,abc24634,b4070973,d8a11025,5ff7a81b,a39de6f,5275d3f,7630de8f,23b7526) +,S(f783628e,bd0a0b4f,6ee68001,5b3014f5,e70897d0,ce159baf,3afb1aa3,207d73c,d06438fd,5b96b88c,94a68b6b,1f5fbf32,6c7a6efb,83b2f1df,2849f809,cc39af61) +,S(7830fabc,cc7229ee,35c7130d,b441d2ea,9a988d47,72ebe00c,6c159658,537ba0b3,49e8b58e,6aead178,3d5c901f,a803a33f,78acc889,27f2d57e,835aaadd,1b38fa7f) +,S(c930390e,a8901286,21a4399e,ef9a4a90,6416d549,c28f7482,6252fab,5fcba9e1,fa0e87da,3d0618a2,f54e8fd,d14b4bca,3bab137c,daab0197,4d110ef,b161cfce) +,S(2a0da867,20571917,6f949876,e5f00ec3,ba0924b0,a5e758b5,2d0c23dc,da9cd28a,96cd04fc,69350959,595b4870,f6df11cf,90c1fa1e,cd04ddd1,975d0bf0,fc907647) +,S(f64881e2,60da581a,f576e92e,3968e24,f2bef6ce,dc1c9c53,256374b3,1446fc83,808a945b,660b67f4,43ef833d,b491fa56,2aacec09,f8a2dac3,863b72f5,e7c8b94) +,S(970bd933,5ec5f0d,3a3cea17,5090f1e0,c181e488,1565c341,33017f99,ab81f052,4d1d270f,e284774a,fcbb6658,d5cc019b,8eb30bdb,39464a79,6ca1431f,1ae9fc48) +,S(dfe94b31,24c4541f,4723ecfd,f5cad197,2c058886,9283073,35415bce,e4c4779a,cc283e53,d547606a,a0fafe8c,5d3403c5,d047aff6,8b194b1c,1855a7ab,9540e23b) +,S(f1813379,673ae594,8fa30bba,d8737d0e,16c8bdd1,8f7047e3,bf33a39e,858df800,acd2c1a6,139a2dbf,9b008d50,d0b4d1f2,20bfb9d8,c24855d2,ed54440b,a87d294a) +,S(f4fbc156,fb631bdf,51192bd0,1c0db0c8,8890ec97,9c368f3e,c2106043,6d423740,3cb08cf0,5b07deff,431faf91,e1874baf,9cfccd3a,df487f4b,4f69026c,1fb7149f) +,S(124da4e8,3b079d72,4a7a9a72,5cc45a80,cb92675e,74541bbe,d36224e2,793de6d,3e700066,f12e0cba,4d6200fb,2a759554,1cd15531,ea065e6a,c6fb4986,548d00e7) +,S(749721c4,455e7826,1de045bb,266b97d0,6c2b112d,2ac8c16,428ce961,b78d1138,27556aed,a3f331c2,fe95b237,d3326c7d,25bc594,39f07b87,86559fc,55a3032) +,S(62cdca49,aa58f55,21c60dfe,d50fbf58,257676bb,fd4c4e97,9ff9a91b,7627a028,8bd49b9a,e16d10ea,7ee1528b,4f433e8f,17c4a688,a7148fbb,d10ed605,595c37b5) +,S(64d650f1,39b13aa6,16d3b227,5ed164b1,1cd3a1e8,81759344,7895a4b1,686478c6,deeee52a,f7572d87,f339595b,79643402,f9e2a065,7b95ba42,6b83d87f,3dfa5c2f) +,S(d08a3e55,66c636ef,3417c17c,d8526df6,37cb935e,db00365a,1ecc9f4a,9ab59d,2db049c7,5eec5176,3fcd3502,33856da4,e9ed32fd,24242a54,9c9ae462,240dc103) +,S(8761705a,35bcc509,afa20d62,61859afe,97154782,49ba47c6,f4b8df0e,30f20d89,b34c25ee,bb029622,4929c3db,78046a09,fd43b9e,be2dbf64,436f0df8,adb726ae) +,S(e3453933,4ce22643,146cc317,54e7ce7e,e35f6f4,e37b307,c4e9e11a,3c6f5f85,73ee178a,941e81be,ff22a0ca,f2bb4513,1afdde7b,336a3bf7,ad05c1,d465d97d) +,S(8389192f,6609a7e7,ac8e6f11,fdbfce8e,246b36bf,95e0de27,fac36082,34ca917b,957073a5,50448ec2,9d67b681,ccfb1aa2,67c88976,e53c99be,c68c378c,f2b636f) +,S(8bfd70c0,67bbe25f,e2e78029,a97fd863,bbf287fb,7a24eb8d,e5a61af4,c3c5d387,e2e6c66b,ee7265cd,5a1b1d64,4f24fcec,8b59001a,6edbb1fd,5d894740,f3f952fb) +,S(a5d0999a,a05f0bb1,59a1582d,980520b,eaf82015,68875269,fdb593e0,e6ff257d,e34d9720,5ef05766,676b62b3,62ce4b34,fe6d27d1,a644050b,f9c65c34,c423635a) +,S(44e479a7,b949c88b,507942e3,89ffd9d,17645185,92d4e544,2827baaa,5d5043ce,7b86ec29,8c12c463,b0a71416,24a570a9,e2b10d77,ae12ee23,2504edde,213a7087) +,S(60dec943,d9797811,706e0251,e0abd0ca,3f37bb8d,559213c4,3176ce3d,352aa558,2dc689f4,a31c59f6,c5181448,d6985335,16b0764f,8cc6fd50,8bc109d6,69fcaab8) +,S(5ca58d38,5b5449e6,f93c5c5,35941b98,d4ab829f,e641bb24,af7e7ab3,1f7709b,82afbae9,80eb6f48,110ce090,7f39ddc0,945d9d84,d5d3feb7,4d96581e,c17cd575) +,S(b775967e,a1b1d60c,9b09cf3d,26bf86c3,b9a23ea3,cd329138,10099048,d18b031c,d2b7169b,ecfa1055,70d885c4,adcfadcf,66f12d8c,846f70b7,12004097,840fef1) +,S(73d8d4f6,7d602f61,3c3595f,b9aa05d7,a23bc4c1,1fa3844e,92e6b79a,40220f96,bf722a2c,ffc9fee5,bea18530,9ecd14ec,bb17fb3d,568fe85d,331575ab,2400ce3d) +,S(e8104df9,f49f7822,152bcce,79c6df0c,8b1e9745,448c24d6,1e7b1180,99182b75,dc2fd539,ec8f2beb,1bfb0da0,f95ffbb,e14fc682,1c5d5023,96b1253f,82137361) +,S(ecd72ef6,fb6c432c,8e1449b6,d16180e5,777e5524,4900f209,e89e995c,546113e6,1671715d,358fba99,e509f518,e1458600,4252913e,268129e0,e00d64eb,7a26e135) +,S(e3b5ccf,be829bd1,6f1fc6b5,fa6d7c35,464bfe10,7e9d6455,a9907050,a4fc36cc,ce7abb9b,5471c1a6,de17a2c9,b5b671fa,296cb5f0,10b5ffa3,31e7a87d,a28044f5) +,S(f3591a02,ffab91d4,eb7e75f7,f4ebd22c,41c1ce4f,25f89c5e,d7ca1ab9,27107734,345a2e11,f2bab926,487c7d53,5314bb6b,cf04746b,be2edc10,18a57c2b,94fa4b3d) +,S(ca4b045d,ae54ad95,37d184f9,ffc5a950,c61349d3,227ae1a6,5501ad97,cb45c635,e30f817e,255ebeca,352f3c24,b441d1e9,4660f456,ce9cd72,eaf4c4b4,d7c1d806) +,S(f7cc5740,54a9ea61,fb8ebdb7,b76a95f6,30094720,675aaa72,dfd29bb6,6f41ea38,9d463d8c,fc5424d9,18275aeb,5e046be3,b3dd7fbf,f52d4990,f52c81e,b2556eac) +,S(f75b5f79,fba3e3f8,ee64bbef,7d34e8a9,b4fd9bfb,27b6a9f8,76b1f70d,ed6ab6c2,220b40bc,5c3fb77b,72c48e36,2745677f,7e0e8266,f85a14f9,d4030ec0,90a43faa) +,S(2aa367a2,5060236a,627d89b6,ad0a398d,89d86a64,735a4fde,e88fa4c,d9cd450,2bfedc25,2491b1a,764a802b,c4d77d86,1e70ecff,e9aef8f6,e829448c,d841fc32) +,S(ff7f49c1,11783cf6,e7da1e22,15827b07,a1078ce7,b1eb3257,65a37c38,a141620f,69550c9e,2e48058e,8bca8b54,21251dfb,a488c585,df644bea,d519acf6,54702733) +,S(31d05358,1164f4ec,a45f7338,fd3ebb90,76d017b4,5e679601,6fd02a0b,5c3aa39f,f124319b,72177ff1,462fa90,2e1f8d23,d4d3ea0e,d1bfd1fe,6bccd92a,9963f575) +,S(6eaf0edd,fd1203ec,a2cbf2f3,8da9ad7,c8a02d3,ab5f06ea,bb88fb5f,7e6a3bd0,d9336d01,2d8e9474,49c521a0,10a3b83a,815a0c74,a31596d4,125909c6,73e05f08) +,S(b95a519,77991ab7,fc3943ac,ff5fa88d,68e759c8,11cb91b9,e9a1ba97,7eda1347,8cf2cb5f,446d448a,5a98fbfe,75a2ffa6,9758bd15,36eea87f,533822bf,6de5ef23) +,S(4e5301d4,8ce5edba,f3b1dc21,2e804e7e,1fd386f5,6b90eeea,da6c1c58,211427e8,f503ec3d,e169fdb2,e1d2f684,cbd9d684,dcabaad9,376d96b7,6fb0a5d8,1b9f0d9) +,S(4fd1a9e5,9031b43,715f92cd,c49c2d0a,fc7c2b54,ad61d7a3,9142033c,3cf49cd2,73ecc11c,ab0165bc,3ab4b43b,ecef694a,2d99c9be,8b877160,2c885a6c,8e4adcb1) +,S(67406865,b32543fa,5ebb7fa4,a8d8fae0,384070fa,2e8a4b86,74510099,20257c84,3fdd9ad5,93a4e0b9,4f4451f5,e3227df7,e829a45c,ef3d271f,3fd85896,bbc62008) +,S(14b955ae,d6ee5be6,ef3dcfa0,edac40a0,de7e8dad,19c8dcb4,e4992a65,a46569e4,d4b920b6,21823f81,8481eff6,761353dd,7d9f31c2,5ea9d1eb,ed60a5d5,fa2daf70) +,S(14f283bc,5608d5fa,dfaa0b3f,fe42fd20,4003e434,c6368fb7,22ca5f22,3339ae42,b2415e3d,c3aefd3f,c644d4bf,b0a87fdb,bf0ba630,2baec8c3,7c1577cf,9edb7397) +,S(3fde0c67,7d3ce20a,6e6275be,7f80cba8,5416a55c,58dfd09,8e733a32,1fbd1c1f,9b8ef7dc,610f192c,949782f9,bea1f08,9a018b25,8926389a,1155d033,1adaaac6) +,S(9c55e669,df5f3d05,f15c74dd,48290540,b993bf4c,41dd9247,df5332a2,ed17267,23db0ce9,30c97665,175abd78,33757fc1,8c6b3c32,2d260810,981b4e0a,6e4979f6) +,S(bde84df,ae141a0d,6e8da60b,30f41746,506d2dc3,4b3faee7,d8568a92,82968d16,45a33214,ff1361df,e724697b,99a6c686,900374f3,6c298dcb,468f38c4,4ab3ab04) +,S(1940294a,b8f3c2ca,45f68f45,4c60c5a1,e5d97085,946b30c0,54939daf,c99546a3,563f9f99,3816c62a,1e60ea76,77c61bb0,848bc926,e76e386a,bfd96bb4,ece3b81e) +,S(dd6ea1e0,d0d13e64,7d0df92e,ad22d838,757a34d6,373ccad6,6829fcce,b32ccb0e,c018e9e3,6bf4e8b2,853ad27f,a49e5ff8,384b557c,aa00c3fd,d8e008f0,ee33c313) +,S(657847e8,c7844562,e26656bf,bbc27b84,dc104737,42c4dffe,c0669616,5b7fbf19,dd90dfb6,58b6ada4,901beda9,a4a9a8a,42c6a4b4,e79a4172,5b5f6ab6,95f2df5) +,S(fb7024b1,40be9d6e,906d26c2,edb781cb,49b8e71f,396b8d3e,352506b3,fe3dea6b,de408ff4,e50b2328,b6ad961e,9dd1ac46,fea36005,1407061c,5a0fca32,eb08efdf) +,S(2d29c008,65a7b279,d3a80179,cd3e8944,b3f2be0c,49a398df,a3113350,d1d8e8e0,caaf127a,ee704a4a,65802748,59649e45,25c55005,f2667ee9,92e9d923,daefcf8f) +,S(db690474,79b7209f,4de8d42b,a3c1be3a,39268589,a7c33632,6d87c1cc,53d5662d,90de8be9,5c3587aa,9913ce32,c83e24e9,c58c1fbf,2922c63c,b777770,fbaa4e00) +,S(9806506f,922e4f0a,afd54ada,258d6fc1,723c7087,ccf13f0a,df247356,c941697b,c07e2018,a8cab841,37698eef,3d31cad1,b97fef49,77b277c9,25245a12,f16bc237) +,S(ab868d3f,e6da25ac,5b11c112,28f14621,661e0ad1,e33d25ea,ae1ae7af,60e40187,ee24b698,334a9850,1a1195ce,d57a7fd9,4b12c488,bbd301d4,d47d5f13,3cbf54ad) +,S(e7561fd1,9d2a8ee6,12056be1,74257e28,3122f366,abf66f49,31fd89ee,fd8dcda2,2052e74b,e3656d8c,5c766ea7,3227b75b,85bcb190,8a07918d,5a8a8001,3e166d5a) +,S(5f19523d,84bbe307,be08f2e0,fa844cb5,7b562f01,39950820,83c2df9b,e8f21e6c,3a96fe16,28ee1dde,2ae9ad2d,5724eb88,33377542,6e91acb9,d9be7c41,7265d7fa) +,S(c9fa4668,3c949b11,2422ec1d,c5501efe,2fdcad17,255c7545,69837d28,d9c10cc1,1aaae75d,18f691ac,cf1dcd8d,9e8e0348,b5b6e734,76d47ffa,b5e23ede,c7fd1dba) +,S(1da90e2a,1e911879,ccfa084c,393b8205,1799b2d4,15a42401,b1ab793b,beb8d8c,3d3f7c69,11ea4d38,46cbae1,53b3fc32,74994ee5,1f4fd332,2da4d28e,c89c0b63) +,S(c6fcf10f,3851e432,6bd504ac,b7847f7,707e4098,d8f66915,3e6f89ad,f31b3186,d0ac89f4,a16a63d8,6e36ea10,8f8ee5c8,4e2705af,a9c98bff,3ea5253,93a50ced) +,S(15057a2e,eb56c67c,cb6b7d4e,f1257ae0,3cf236b,1f9b6588,fefd7f46,16378233,4dbab530,ccc0a7a8,c49543ef,5e3d0a87,6f205a62,2f9a90cf,5054bb0f,dc4930c2) +,S(37eeaee0,72d5ac0e,6ea7337d,d07ddebd,45bf1cb7,8c02dea3,6d1e419f,308b20f,b0c64496,5d9daa14,19c77249,a32a3a3d,a5761adb,bf5a394a,ebb91630,f361d506) +,S(5a207bf8,3a8bd0e3,3c71cd96,d928bdc5,f1d6ce8b,7ad9bebe,61a27362,2557745c,3accb757,fadc9b6a,2a5494ac,15744113,ee878901,323c6138,19ec7666,60f54dad) +,S(fe08dd6a,1a0fe325,5a391271,e81befb6,f6b2ee08,907046d1,642d39bb,fbabd139,42c342d1,3535822e,e4ef1b43,69f204c3,665d2326,1379b0d6,c520c64e,181ef40) +,S(b7d262c9,8dfdbba,6483edcf,38044cad,d6d859e0,3d1ddac,a39cb999,78706111,96086350,b308b397,6a007c8f,5181b5ba,30bb4c11,653d689,ee97fe47,28d798e8) +,S(4b12ab2e,23b33775,3ae97d7c,1badf5a,7d354b57,dcc78407,6836f802,34130c86,419d4e0d,9f708bf4,2e11e73,a1fe5815,2bc9649e,49ae45c0,f52fb8f0,f23c450e) +,S(fc6d2682,a96eccda,4b49570c,8bcc47c4,8f362bab,7750b4f7,4f30cc49,d8e88dac,1af56527,30264580,d1f22612,e90597f8,694aff0,96001848,8a243ac,f4beedbb) +,S(c7b9c3a9,a189eba0,54742c40,c4afdb9e,5e07e6c0,e442cf06,32e9b655,1e607e8b,5bb68277,2f2274db,62084cd1,9c1a545e,ef6b38b8,d4dc3e30,fc58042f,f01822ab) +,S(eba4d342,30dea72f,29a339ba,3ed4306a,46c761c2,bb6f9627,3406fa7,50dfd956,fce17a0f,23d278b2,e3da1747,706840cd,d31b01a5,8793506d,2155cbf5,dd237cee) +,S(a4d36dc0,2177d471,35b4358c,6adec285,3595dcf4,6cd9acc8,944a569f,82c04155,85a29779,63b21be0,e378fd0f,b5a60fdf,65f3e45d,c2fafad1,13377f4,81f00281) +,S(4916d063,ae8bfae1,e3f5bf56,fde73abe,eb165aa,4e6d4a16,9060ac95,76109ba2,a7916703,4a0b40d5,f967a08c,a536b7c8,3b2b0b4f,67638656,4ae9b4d4,4c3f22ee) +,S(761cdb10,b2966030,85f8f1a4,404ab49c,9de01979,85817f97,ecbae412,eedd046,1d115720,763b545d,72f8f50a,b881e7fb,9789f0ea,8dda90cf,2ee2f3a2,2e193db7) +,S(d7a2570,4d718e92,df85541b,490bc13e,860ff014,e8ddd9d2,e05fca2b,8dc64ea3,5e454b9d,21346767,71c0e035,fbc6dec6,6102db85,aa3acace,c158f43e,534cb90c) +,S(2af6004f,7962c52b,b0ebcb06,32975bbe,a6b9a99,4dc5a5df,eb20a43f,3d4d3bbe,6988a9e2,26f8cc15,3108e3e,b68c6596,be1deb1b,53239933,d91e095d,d81a14f3) +,S(a92740e5,3bab0860,1127571e,5d33184f,ca805d18,75ba4959,74108f5c,a9504255,5df2851e,2eb76b71,66dfd3d,3aa84e0,96d49c85,10daa44e,68d75eb6,c6d2379f) +,S(90d0961a,510d8a6b,60a87c44,93a0c8ea,76856770,d076057,bcc7ed98,70014939,74d4753c,1c913088,66b6f7a8,a2386ad3,7c13dc2f,85b4b4d3,f8d7603a,ccaa545d) +,S(ce52bea,f2e3a604,f62bfa27,92e2e083,8dd5c6a6,ca338ded,249be611,4ecd12b,a869de73,738a0a2b,7c824444,925f3d9b,dd08670a,8f8ff1a1,a4988008,2d5c009e) +,S(99ca8dc2,10e3fcd2,ffd39a47,1c06ac49,12215441,6cf16be7,cc3e350f,f3cd05c4,78087a80,131adc2c,6bf26309,ef0720be,4550fbe8,912142,c6ce496a,dfbc4982) +,S(be442cc2,9f5a7bc5,d07ff1f4,322deb90,cbfcc6a1,7d8e611a,b51ec610,a202d1c6,6250f2c4,680ed934,8028f2c0,1acf5bb2,fb3d1f25,e324b734,11156128,77c084a2) +,S(53f5f5f4,37fb010,2130346b,51b9b14f,e75d95f9,b8f80e65,67770bb0,e4ec8e54,8da52b53,c6e733f5,aa0dd2ef,23e2e1c2,24c0d571,328520f9,cb1cc5dd,28c62f93) +,S(206ce565,e90ebff,7d799e3a,134a56f6,a897ab19,186ed554,11de6daa,5c8c4d6c,c2ff5d22,bd2d6dca,7dfec5c2,e79d5320,aaa5d53c,38ae0675,4dca9a96,a6a75804) +,S(d1dcbfbb,87ee2fab,811f2a72,726d2b54,2176a20,cc23f744,faadf2ac,7073f443,106c63b,41800bb7,bcafc27e,3f8337d8,f71da693,e1f4350c,1870f968,edd17db9) +,S(d21aa173,c54376ba,1eb9d432,26ffc9aa,a516fd0,ef17c2f6,db117392,db749328,37cf5df4,e01480d6,604f79de,63a754b0,2326f9a4,ed74cb24,7724c682,6074e424) +,S(5234b024,a22c69a7,569acfbe,2cbb7ce6,15e56383,f8e1e031,78dd54eb,7d1fa3d2,2beae442,651db52d,62bc3b04,2a5b343a,b4103895,a74aeddf,d9189630,8bc000cb) +,S(9e6e9875,9f3e21ab,a709dbd4,f598894d,f5048dcf,5ee6cb6a,50941c13,35412f64,2b670199,e38f2e5a,424dd169,e047189,43111033,a7e4f4a9,2dc26906,31757ea8) +,S(8416e295,9a718e77,10df8a92,72de9bb2,89232c73,832597fc,d28f2928,8743ae45,6ef49202,801b408e,d81b7904,4cd1f002,20732a74,764c44db,4c77121f,1133d139) +,S(852a4fa7,48a3b2f,326405eb,e52ba2dc,27462f72,9ea3429b,b108e27a,d53561a5,3e06c046,ee0d9c23,6b0e441c,2cbeb672,770b99f7,8d062ac6,a81ccaf3,a562e520) +,S(2880dda0,2dbe56be,b93b876d,3c083ced,fa6097a1,cb234c5d,3282942e,3677c1bd,dfb0ea10,92d46bb4,fe95366c,5370dfa2,3d371f78,40e919d3,bf966441,f1bb43a) +,S(cb6fbc02,9e828d7f,c03dbf86,99a676a0,37b53555,275c86f0,7709ff89,f1819c65,fc4e2d9a,36577399,15cd50c2,1cb76cb8,ce9161fb,e05babda,ce516277,86062266) +,S(8087bb5b,ff1c3438,21b24106,606d0ec3,abc76a5,8a872161,5f6305ef,f81afebe,578b287a,a602c02b,8f5c5030,ae9a4632,23a4437e,944f4353,d9bc17de,824ce72) +,S(369f54bc,30f2c90c,7af0def2,2517ce58,f8ae829d,124ed482,653a28fb,42d3a33a,b8f2eaf,35af7e32,c63c97ae,f5962143,61f466bd,c4cc1b40,b4526157,b9b59d16) +,S(87be4c4c,1b2f871,53bb2448,ffdb6ac7,df294628,6be49eb6,edd3d533,1fed8f7d,7ef474bc,6386c0a1,5771ec54,21cd51d0,71fdc8a8,66938a2a,dfe6f4eb,ca0effb1) +,S(7b6678f0,18f75bea,8c310eeb,239edbe2,80393f1b,5eed1cfb,c013fa29,1e14715e,78e8b8e2,666ee69a,7388275d,2aa1bbf3,d985707d,3dd52890,c181a8b1,f38b1fd7) +,S(89ec641,96729e02,2a9608f5,8fba388b,77d2826d,6b37caed,90d27394,b160f135,5def3142,108d7387,19ee5a7,41deb18b,5e3030b0,d919a1f8,ac94157,a4786cff) +,S(2cbec739,3769090b,3aa2acba,b78c3fac,8b83749d,641f9311,99e6d1a6,36177f8e,3140e7e7,57ad2d5a,cb34a007,f4f26aeb,67fea7cc,8902fbad,2ca92083,f3de8886) +,S(678cefcd,a2d6a58b,53e7b116,d03020ae,29d57618,4663fcf0,2ebcf0ee,bd946908,f45be9e0,13298eef,37cd56ee,932b2a41,18834fc4,331c1713,314bd028,e6a3491) +,S(8ddbd278,adcc4ece,4692305a,94cdf011,5073b073,c88c1524,b43f1822,c73ec0df,90510edd,3c52c6c8,caa9ea1a,e28c7784,5d2d675b,a33b1022,68b93b17,80fc5b0c) +,S(972bf082,b162ff5f,22b149c3,d238260c,607d7878,aaf70739,3041d0c0,d7e36626,4685b3ba,f61cbca4,d99b64f4,3e90a442,6eca9f24,d0235324,797505be,4c4087dc) +,S(42af0d52,66604ab9,7de801c5,4514d23d,d8c1f760,bc86280f,540cc57c,bbc97230,5649b89,8c9029ed,4357160b,d97b74d5,cced0668,98de3b89,77192bec,1699ce38) +,S(5366770,87296d1d,8e6138bc,a9a1a0c6,1748ee21,4c0410a9,fa5623f3,d7bb30ac,e0683a60,786ba0d3,52619c2f,672d90ba,7c297b2e,59591f31,fd8b8fd8,ed5cac1d) +,S(a03b6284,e85bb18f,f04308d6,bce40e91,7d5d0ab4,ad920255,9de55c11,fc39fc24,2739ee82,c22cc348,23fe7235,a939db8a,c073005b,e014b564,4cad5a8f,e8785493) +,S(2f394ed7,268a53a6,bd998055,a24f7dd,f5801dc9,99233a63,7332e24f,26b66e97,b52b4f3e,e934ba86,d1bd3714,a26bc4c0,e49d09f,5d055413,8d3f4cdd,73918d88) +,S(91773010,527e537e,3aa0c19a,611ef5fe,7740bced,ef0b56eb,bb35a12c,7133f8ab,68f937b3,28b64809,27e1063a,bbbc36b5,b097ae5c,ccfbb965,f4814f,ea9fb5b6) +,S(2851bdbf,cddc8af1,7a20c1ae,bd529df8,28486bc5,50a00b24,763600d6,904af615,d302c085,702e27ae,6d46c376,33035d6,ee2acfc8,3b731758,5d15b2d6,dccb1356) +,S(e986d7ab,25499f1,45610b79,1b47e597,8be3d363,5a6f29c2,5d34da48,314bdfef,d0638dc,b3b3c150,10ec63b9,61104559,cfdb182d,31c41c16,5f53c331,47de35a6) +,S(bc45db2c,5639b2ce,2dc1c5e0,d831d824,ab44daca,7fbfa099,b2e648e2,8f8bfc03,5d93e3b1,27b289ad,49e32740,a9f53e0,79a80580,82606884,2c1f9b52,7213e32) +,S(4145d67e,47d9809d,2c67b4c8,49e29101,849ef512,ca7b22fd,667498cb,50a8dfc6,5471f4fc,2a4f7f82,9708604d,90daa64f,daeae007,d6290ea9,4922173a,4513f096) +,S(2d157f7f,4cd79d56,bb15314a,a738dcea,427e3087,e7a5afa3,c1ad740f,5c686825,c1c4f318,76159f4b,94e7a29a,2766bb46,962a4e21,3a7234ee,eabf1ea2,296fc1c0) +,S(2f426284,77040b2e,5dfe26cb,c12a81b,d6e89696,8226987b,361d7961,a73933ba,bdce120d,141b2879,effcf601,c75532f8,a384f942,879f24bd,45e483d1,8144075e) +,S(b419cfa7,6cc91302,e683c9c0,eef23ca7,bf9f8f44,37ea220a,b8a1fffc,3bbf527f,bb86954e,290f2419,e4891a70,b48806b4,a911e956,e3cd0dba,3c0251e3,aa929517) +,S(cdb4a6f9,5734164f,c7af2913,f0ded939,2b17bd09,b03698dc,ae2d72d5,4925236f,89eda236,bd1bf5d7,e500c47,d4996451,d57c963c,4f125ff,c9ef8e6e,aac8e7aa) +,S(ed4ea751,a45ac44a,33e6f2f1,50392fe8,a12a8c4c,2233ca3e,321800f8,f408c256,9c7e9da7,4a2b349a,ae9266d4,d04d912c,a296d963,98ace64a,caf40634,970ffef2) +,S(9b06fd38,fdf963c2,830ccfcd,1df08a73,84a74b02,fa79a87c,96decd0a,3cfbf5d3,e866461c,e7ee6015,aec4ba3c,d4dad0d6,3ede27a3,2a1b20d4,eb29de00,6b226416) +,S(df11481e,efc1cd1a,97e13f1e,e0702056,c2b7894b,de1a44ef,5166e521,1af6ae75,a1411856,35429fa1,ebee1f24,de73e2cd,80c76661,717abad4,a8354aba,222b7e02) +,S(f8328d01,b1f3fb3,d07bc65d,e807c619,46e4df15,a518a845,23da032d,12a3c9f5,e29dbc74,7746d478,9ca9a6d0,b5ca9ebe,de174914,7a709df0,d5e0f100,cdca6216) +,S(3e3afbbd,b7fc2301,f9a13590,acc4fb5,ff0d1b7a,92e09e46,1fcf0093,4d3fff86,1fc7f7e1,b9821c51,bd44c8d0,9619aeb1,a5c2af1c,3ec28742,f0f26212,6eb6ebd6) +,S(aad17eea,68348015,9cc19f8b,69d335b4,78ede880,4c551660,74d1ea9b,1ff86125,e993b8c,ebab89db,67cf45bf,361ee910,dfa1749d,26b488e8,ed6cf9df,9d365257) +,S(213fbb19,5515c686,fe8f44b6,fe26a178,286442b8,fb29072d,37ce9972,910ea35c,497b951b,7df7f4bb,2d0ee577,19876203,d68c3958,62781362,18e8969d,ed52a852) +,S(cd7f72a5,78ed819e,3e93321e,c8b8c7a7,eba91b47,92821a2,92493790,370120fa,a3d51c70,99280f2c,fa2c537d,991077e6,ca4eac91,93e97ce2,d8ff5fcf,45bb1148) +,S(70a360c7,a72939,f9a3a28a,1d1a9e2f,8240aec1,878f9b19,68923e0,b67f3b51,a1d9c07c,53a4dbc2,2ea4ae36,b6a0bb8c,dd175c98,6d2f61b7,3eb05552,ad710259) +,S(544a615b,4f8e2b66,fa1dd19,99e9cbe8,eedc35fd,9cda6d33,7a076601,21b5e46a,75d26db9,c76fc8d7,65286aec,bdd9c97f,d7ba7a9a,7308e6bd,75150b35,ba8451e5) +,S(4218d79f,76a073d7,af19b265,74d5b5c8,f8b779f7,36c23c92,a01c3467,8ec8acef,6815f631,49073b5f,e65c05f4,eb284c21,87e60355,e207cbda,f2c01eb9,becfb28e) +,S(6ada2638,1a82acc1,8a333759,8635f83a,3deca5d,9e4dbb38,64a2fc1a,a269b0a9,53d356da,65f7526f,60d05f32,b8b5f841,2e77b6f8,b61533ba,e8ace229,5eda6c08) +,S(5fa99d01,d9f29a59,75518e98,7c382c41,8bd46ea4,7813f579,3366618e,e118b09e,d479d238,38deb81b,dcce381e,4982652a,f15f6602,dbec34cd,6fc0e82d,33fc3b39) +,S(cc6ed576,34cc67ab,6ea676d7,2fef96d3,bbb4a00,b2b7fe44,12d0195b,44d76f6e,b15c15a,d50999b8,aac9e5f1,5834284f,dd801b0d,da4be94,f520af62,f7bf820c) +,S(e4cd0fdb,5323ea3f,deb10bf8,90a26b6d,ff447679,d8747ddf,ec32ee3a,40ffceb4,fbdb40c8,ba9c4357,656af718,db7629c4,e2caa87b,c41f8c48,d5d86a30,d220e1f5) +,S(77fd722a,ba51b929,ac1e3ca1,a2346833,b3c1fec,7a756568,6afb7cd8,9b88a8af,d02519e1,d6e9cb4,4f378ee3,1df4bb74,6b5b555b,2c7b0691,9cf90f5b,3de98505) +,S(4d391fbc,a9dd3d47,9d3ca57b,f299f4f8,6291e523,95ff73e2,665418c2,997a41dd,5cc9ec33,b55e606b,b93e9fcd,593c43f3,e5d4a3c4,39ec6fce,1a9ebf25,b4ce899e) +,S(740bc446,17b17b84,5c99d63c,3c92fe81,2eb232f8,8161a2ba,83f3a445,73084e97,fd8ec6e,f4f9567,71717481,c1301876,fb10742a,99028c67,883254af,f8355464) +,S(c258c21c,adeb8453,5bafd8d6,cced030,c6aa12c4,1bdcc392,b2d10e5b,1b46e5c,7cdf037f,3e60bd7f,739d08af,a20de5f2,b73646a7,5ec3e2af,4cb62139,5d171d31) +,S(8fc88069,733a4d5d,bd80261,c0c9ca65,fac22a5e,1bffd768,dbeffb83,24130d44,4211a94b,f88c042d,54d37ba7,41cee691,ca5bf0a6,38f0ca95,954f4aa0,12fc946e) +,S(cf62ee1a,40321c24,7fbb0e0b,ce99d314,f5152de3,32b827c9,67a61bb9,c96ad4c,6284a7c3,e64f7b8d,4bd978c0,77dc0d22,e6137336,6410d5a1,9bb09640,1ec4a3fe) +,S(53351f8a,4d447760,ecc88443,19b69160,bb00b3ca,fd6fd9d0,6c0040e4,549f8ba7,83844e19,3816e6ff,755c148f,d5488384,c7c1cbb8,8c09ea0a,16352bcd,377f6b83) +,S(a02063ce,ee2c9191,94d0e1f6,2ace9407,baa0157a,d2e600a9,e173348a,1d06bb0c,630461b5,55653f52,da9b40ea,c4448a8b,fcdaeeb0,1007dde0,5f4c186e,9f146339) +,S(70bcbdcc,25de1764,7274f374,196608aa,c360c09e,951b9857,5a6a8d6f,e1d35660,3bd5bd9b,716359ce,80b5e719,a9e1d40c,3a1c7430,94a82b64,a90b0f4e,db461d74) +,S(df8ad77,83cfc3c0,6fbb1fe5,2a515de0,54b161c1,74155fff,13812d19,aadc8fc7,bc4090f6,416db0c,9d34ff20,a0b7cb99,af38401b,1264c604,44ec7355,80069569) +,S(2504e9cc,ef399800,5f2fff3a,452d56fa,8788df47,e05509ed,777a9d9e,540a30f9,73c506a2,c6f48efc,af7f4d2f,ab5fd833,6fd6514e,db690a51,11659f79,7390612a) +,S(24ee0724,1c920334,3a6a6fa5,68979fce,18a9ce0c,819e3a61,571141a3,5bc97025,ee642ecd,605b84e8,68940a6c,cd7f4d93,fa0c6816,2fb0bf6,ba22427c,b0bd7b8a) +,S(1ead5ce0,9665c05a,63cd8eb1,12097f35,4961e12b,25c03093,e1c6d919,7a3929b3,1800df5d,a1abcc4a,b1c32fbe,a1dd7120,7284b5f5,dee7009d,c2f4aa6d,7156fcc3) +,S(47cf2ff2,26084f8f,9020b0dc,d838874b,160c69ef,2e5e89c0,98e7891e,ea05d507,a340d3df,129b5aff,1044d0d2,c3866464,bca2efdc,8dc83516,cf8fa522,d5fb7d48) +,S(4064fb9b,8e2e4952,a218bb8e,ae474a4d,51f050a8,3f9a7e75,b04e39c4,42d6cbdd,ff9cec76,a2ef1930,92d3e02a,aaddce0d,18ea66c0,d1adfd2b,9c7886dd,b835de10) +,S(838ac8d6,e58e20d0,321e0150,ba6d401f,cdd70a40,69d980d2,22de3353,fb81904e,993a6f96,2909dbbf,7b9a6b25,14153331,b1ef24fc,e892710,5f95488a,d95614bc) +,S(a5e36d83,189d43d2,34d6ea26,ecf5943,5aedee72,bc4cf385,5fce9b5e,e202f266,78c02c3c,e25c3b89,9dd2933f,b41435a3,dfc2d1b5,e7ebbfe9,54ab1c94,79822c55) +,S(9e240cbc,d357c4d3,34f31209,58d6f7ad,5ad79e7a,9b51f572,5ddc8fe3,1fba72c9,aea34a5c,ed60a062,ec1476b7,b30b3c9c,68cc5e10,cef9f0eb,6729172c,b511f06b) +,S(ad1b0646,bb315380,5c22b91d,1ee47a26,dfc9ed5a,860be0c7,ea8daec3,b6dc2eba,ee2e61a2,2499c509,1a910c9e,ea159873,a298daa9,6d30d8bb,353b9955,92dd2083) +,S(4f7b0889,11d8f64a,550d8c7f,11ecaa6,fa12df74,a236a0cc,35cb7cd3,5b0ec72b,931af41b,d297e18,b4d9ffac,8d7f8691,29b94250,f1de1d99,3e31525c,4dbb21e3) +,S(dab2a170,e4108f3c,93fba874,70bb12fa,834d0274,35695870,d2d3523c,93d3a7ee,262f12cf,c37f010d,deaecb24,d08ce35b,293a5c6f,1746651e,7bb0b2fb,c573ae4d) +,S(3437257b,784d72e,419e5082,311b5a66,d499f687,c4bcfa31,7abc7484,a3cf39be,ce9bcf07,6da8d68e,8453fa14,3b06d7c0,f38bd0a0,76f1cec2,a49b3bda,a5c398d3) +,S(4594ae9f,82611ab5,bf786024,ea34bfaf,939fa409,34ad155c,9ed5e736,899545b,2255c7f5,62b0ba72,c3834e72,e77b478d,77d3f15e,3ee0cda4,c4b3f928,ead450f5) +,S(7337705,12db06fb,36b21fc,26b585a7,3aebb036,b22743c2,f13212dd,81898819,753ddd59,725fb0a2,561cf461,c587f3f8,848b53ed,29283c51,5150c57f,50307887) +,S(bd915814,4d2afef3,552d81c1,8c74abc,a53f4c2d,654f72e,3f2abd66,d69790ff,1af609e1,7f27e373,b42b3277,a5f4714a,31ae895b,95e0c5b9,50e7ed2d,1827763e) +,S(8a11cd4c,a51dfee2,28c1ced9,3d8870d,67782740,1f49fc73,d4ce56db,915bb557,d30ad7ee,ae9f9c97,eec27822,9f47100e,ca46b3f0,27339719,6be0f619,56f5cf23) +,S(7929b5f0,2802bfeb,6c23e688,65b0272b,cfd058d7,c0a45ea6,97d46d87,6f9bfcfd,f9bbae21,8039783d,4d1e366c,32a890c1,8c80d1cd,41f08b36,963b54e2,f4fde5d0) +,S(80df06ac,1d5b966f,8080e79b,cc9f01f3,d55f8855,9b1a58bc,f6e4c526,3bd89d01,346926d0,a59558a9,2625614b,ac010f36,5ee5c337,2660fa7e,be41aac9,41136538) +,S(74545478,9ff383f2,94a92b4f,383ad13b,ed4b01da,d20f4ac6,efc83315,be5ccaf7,36489f77,81ee77fe,de1ea165,c4cf2b5f,e8217361,9e760cea,fae777cb,c160fa9a) +,S(2c6d35bc,b213a8a0,95c11fdb,42828b7f,e562d7d5,f877de67,de62bcd8,5af8fe85,aa30e370,34094f9f,4502206c,72f23298,2e60139c,2bd35631,44dbe6b4,c75d159b) +,S(8353657a,9d934eb0,2811846a,728cd162,4b43429d,304aa7be,830da70f,b2e338db,f8400438,20ffa5d,28189c5a,ce693c8a,ed4a4caf,3aff83b1,66a9d404,74e02b71) +,S(f216e93a,54ce56d7,c7ef6336,561a6299,2177ca73,4ed867f6,fd1a8ddf,aaae494f,db0a3f13,a0fe8326,63e8fad,b11cc347,8da296b7,2f1b672,3f43ea44,acd30611) +,S(dc371221,9b5d73f9,6562baa4,b62ec7f4,2e9a3dc8,de6e7112,273d0811,a88324fb,eecc9092,ec563e96,3720acaa,929f9bb4,4f1c9015,7c3300fb,581b154f,df57c004) +,S(db34736d,48f0b4f1,e1ef6029,6ef534ae,b10f047b,4256516d,d4499072,36649475,1c29cd6c,f7a8c786,952c34c9,b93e5188,1a116966,164d0fdf,dd1be4fe,ac586bec) +,S(a248457,20468424,f355af53,62f5bcf1,971b09ed,358fbd33,78fc7297,3696add,9a703d61,37d0deb8,a3767a56,c2e24573,baffc931,bc850694,8c9a3776,26547803) +,S(bb7b806f,a9ac753b,bbeaa429,31f68d0e,3eba38b9,8fb25ed2,40c9faa3,124436c4,8f812574,a1a8bbe8,d9b682e3,d9b0150c,7c6ff9c,f9b42e64,6e5836a8,12426752) +,S(6703c476,fc28a023,f6619427,69e0f068,489344aa,74495ad5,17b096ff,c3ecf446,8b48023f,7c9ba723,584211a3,6731e14,f42699ab,522e15e,ed3ac43d,28e2a38c) +,S(bcaaf8e4,bfa4b448,fe23f3b7,a1612b82,14cf0daa,349463b7,1b44ba61,e2dbf6a2,bdff2700,e2cc953f,e9d08835,dbe8793b,b07498ec,68ccd736,d6fe1710,d5c7f404) +,S(906b4fda,1a557220,1dd5b446,d726a2e6,21794517,3ec74f7b,bfed8791,9310cd49,d753f2db,cd2c4d28,d0304bc4,78690871,cf838490,2d7f4f93,441a74d3,892653cf) +,S(9ec09783,18f7d95,5180e326,e1bfdd04,fa5369cd,eb786905,8d726ac3,9ef93d5f,9cca8057,994b1641,53ac6842,4d28fb70,ad22baf8,f894a049,d1794add,97acf205) +,S(53347906,b75440ec,28362a96,f114d2f3,6f823cbe,bb0030f3,a2de3314,12b8209d,ccb38e0,471f8abe,47ef1bf0,29550ec5,59581680,3e19034a,b06a090c,ca0c1fa0) +,S(27c53f29,61b70480,93e24b18,eb357807,a33e5411,15215337,3b98f80d,d23a4870,5a3f4b8d,e18636c4,71fc70e5,9ac8c4e4,703fa5fa,880594fe,2f3b888b,da575601) +,S(921927e3,7a115f9a,12a616ba,cf55c213,22ed51a3,e75caa5b,eaccce75,de59b68f,bdbb7c7b,c1e4c5b5,98afb590,6263d779,55884e71,17864ae2,e0636c4d,727b141) +,S(973b3c87,6eb81ffd,677c692c,ae432751,efb3e609,1a3d9ff8,dde6cd6e,3f3ea8c2,340df771,129510b,a4112c5d,adbcecd9,8684b0ae,3a9683b8,49aebdd9,57bbb0ed) +,S(20b817de,f0533767,9938ef03,69204700,d5972c32,12656ce4,205e9ac,1b01ae71,2ae2fe5b,e2daa016,1c65c352,94a0abc5,c6b1ce64,fea99c12,34a14aa8,8395707b) +,S(63e2544f,7a7e9181,7a347b7,f72eb43d,ca9fc5d6,3d931402,aa6889b4,a3c95876,e62aee6d,20d714ce,5cdf52,18bd5fae,adf49cb1,f86e6067,f91cad71,280d16b1) +,S(2f90de10,71508cf0,b3583abf,c47d762d,a69dd472,e4183421,6ac39753,e22aeb80,5371bebd,4a0dd74,625e5e02,5a118488,880f3a89,9c23e64b,76193abd,3788d389) +,S(8d423ce8,faa96d05,45e37cf7,5e5a351f,7c9359c2,ad1c48a,c9adcf29,d2ed7209,83d4b83d,ee76c401,a18df794,8a655c3f,bb9d23c1,5ac0bd6e,ea80b129,bab40f2) +,S(12fa4142,5e028aff,303111a2,9144242,a9c91d88,55b3ea3,becec110,80181efd,6b95b370,8e792b57,ac10eddb,362eb10f,ee5c3b8b,b2e37d4d,c4d2ac40,e8c3ff57) +,S(923ca95f,2a3bdd7c,d7505632,cdf2d730,ce70196f,ffd0cbbf,f8347882,8a706f73,f8b0c866,c39b6173,b383983b,210cfff3,1903afdb,cad0b2ee,3e541ab5,2746abbc) +,S(844d53e,878240e9,63e3875a,728f4704,64ce3aa1,66209776,a869e0d6,88893646,c60cd291,92bf8c1f,f98c47b4,a713bc75,1c84f9c7,19fb32b2,5b855e73,6feeaca1) +,S(43786fd6,c5471d8d,ba277ff8,1005a5df,8838299f,66636b2a,65e7ac21,f1dc98f3,d292a2c2,9c8c5bbd,8f79109c,b8706fe7,745ff884,f98c127e,9142f52a,56091b51) +,S(6d1bc28d,f5e9ecf6,38783f71,fb98a2ce,bb0dec45,8b07257c,e94736dc,ae36d7ab,c2c54192,bfd80447,86214cf7,a28108dc,e2c00e07,2321638d,a0e80023,88d549e6) +,S(6bc4ef34,7f74ce3c,2ef3f89c,c3e265d5,6c742ccc,ff84b7f6,7d8956ab,16ff86c6,eb4492fd,2d2ab04f,1276be35,c6bde62d,be26a6e4,60c5c66b,8b0fccf1,79b46408) +,S(6af45075,fa810958,d42a756e,d08d5c,d67a62b,cb33cddc,b35fa99b,bf678b38,adbb724f,e7682c7,678ffc3f,ab738666,886c7b93,84960bfd,5287ff9f,ba5bff28) +,S(eb6d8b76,36466365,a96f49cd,355b7460,939f340f,905ad1ca,a24e8a66,55260600,7ae9cefd,aea30b7f,b9ba11ff,603b81d2,41f7a187,33f95c3,3c2bae0d,7fbea3cd) +,S(bd0c2233,2fef7d3f,6738dd69,4bad4cf5,b34d5e9b,ad6500af,11e4575e,91795068,eaba5c4e,2ea0b21c,a9100b6,66823a4d,a91c4d57,3aa9d136,76f820be,9d1cf209) +,S(c5e23bbd,c5049419,3483e083,14249157,aa56d9f,804374b5,54c9879,52b7e392,4caeb8cb,f684217f,bfdcd02e,3aa4ae3f,8d59e766,855b4fe2,f7f8ac7a,6e597751) +,S(b5717631,f3aaab92,5543edb0,3d21c604,17178e98,dea38bd8,10867cf8,8c92d2a3,e74209cc,324a9ef,8b31874,524dbab4,d2bdf0ac,8f1d20e9,a02409f2,8c11942a) +,S(9c456099,49601f2f,caca85d5,d30a07e1,b2d17b7c,7b838cca,2fe4b5e9,5d305cfc,2d7a1540,a109dc7c,2841b61b,31e50078,329273c3,585c8674,674ee06e,ff04eeb6) +,S(52ae2946,c0ab36c4,a8aff175,73b6604b,e33dae5d,73228d54,98c77a51,8aa82f63,70e23d9b,66061bfa,4d03f899,b65493f2,7179f5c8,643104d,24dd771c,777f87b4) +,S(149ec3bf,55ff462d,dc1ba490,384081e9,89db9ac2,c29efdce,f4f59f0a,394adf9,59c1d88,b91db942,2ae8fbc7,ce6951c8,49642b5c,df949801,341a8bc1,789dd7af) +,S(aff89294,d66718dd,dff83534,61538da3,dbe14a09,c14d0576,8a163810,42ea7ea7,71866beb,cf5887a5,ece2352a,cbc256dd,7b615491,2a88cbb9,a924e764,4d59266b) +,S(de44f478,2cb30472,ad52d49b,303e2b41,33887eb7,38e2ab78,da7bb406,584e76fc,6798ad84,25bad82c,57c630d,7ac8ef21,b13d08fa,830edda7,eefd23c9,ce482bf5) +,S(e0bc7a73,76169366,c172c88b,e1ba02c6,b3a380eb,2894e134,5a2ec7c7,39682e61,bd147eb9,33b18fe8,dfe7c0ec,87b7e993,5ad1f7c2,ab5424d3,c23609cd,262cb2e0) +,S(5ee34f27,2af69f33,9473cfa7,a536a22,ed26139a,71cfbb11,27c7a476,32f0e6d,c1df8f96,dc0d4d82,f6a57de9,85cdefc5,1316bf10,dc3636cb,80762aea,c4e13b8c) +,S(4dca3bc1,77fa7a63,9b8c274d,fe157d7b,67296846,bed5d13a,68bce5e8,e599a0f2,8fd2b558,36fb9aeb,fdb3fd75,8f59c8e9,2fb48968,52eff2a1,d01c32c5,3d2fb234) +,S(554f6bc1,87560290,ef9ed937,3e993f54,98081034,a03484f5,bc184751,f8b48136,b454c3b7,dfd512a3,517834e0,e8c3f50f,de80863a,1e0fd83d,2064a6bc,a172b26a) +,S(95a81b50,a6c0879a,6a960b2e,162dc22e,955af87c,b539eba4,20b2825b,85592ad4,be55e8c4,dfed22d1,f5872b75,f38aa4c3,7c7d5086,f67011af,2651ab0c,c45c712) +,S(907b6d53,9e496a6e,358d14d3,431f5582,44a4f8a6,ea291d85,3efb8be7,477e5c4d,b3d3d694,3853bb9e,67817fad,1dd7d1d5,ff33e200,2922665c,21f872e4,77150eac) +,S(8527c81b,b342576f,67737cb2,33f17605,c8884c64,6b7a8357,5bcccc09,c7f17aa6,b6d675bc,db8d5249,57b1930c,145777f1,9cd47b9d,33386a64,5044e8f5,877604fc) +,S(8e1e3a7d,5a320d92,4ea13436,f906e9b,bc6bf83a,819b9e9f,913974e2,efab00ec,d94f03ab,d81d5f25,c323dad4,ea792c50,792e07c,79281c4a,ff309e0f,f418b0b9) +,S(fc02cb93,be1f4a8d,9acbd86,bc68cb6a,dd0d8949,5cc7434d,72cfab75,519a8d76,71f7a532,729e45c5,98a6ceb0,885a256e,ffe4cd9d,967e84e9,8b73c772,7e4d4f94) +,S(cf981302,a2858b3b,b1ac44db,4f08751b,ff76357f,9b2ed6af,80a289b1,be6e7b8,237e9c12,bf23666e,70205ded,984f1fa2,f1a8a828,b88847ba,d3a1be88,8d73b528) +,S(3e6e45dc,1408e920,3ca74cbb,ac8d50cf,71718d1e,ba05228,e97dc4be,a8231d82,2e3fdb7a,2ad3a805,f61f287c,a7ef86df,961009e1,f0fde8a3,14774677,3b1ef848) +,S(bb047795,7581471,10809088,8119b0ee,3ce1b2b2,df2668b3,749b9eda,707d4657,95a72efc,5f95f3a6,af5ad697,7dbeeed2,8d6ee55b,fce29bc1,bc439168,75c67587) +,S(4e015d42,b8b02c10,4aba3103,4ce04cb5,fe356d,81291939,3f5d1b9,68dd6748,d35b20e7,dfbf6d71,d94e96ff,c9267422,746419fa,811bcd2d,d3942c00,70a870fb) +,S(609a4c57,90c8b210,9eb7391b,d68d078e,70850af2,410df867,92a37459,24a49daf,f3a6327e,bc965b3a,581cb14e,78a4390b,14431d00,d1f34e8a,e35502f,bad0e98) +,S(ccbe0736,2a955ac0,4e1b7558,a17ecf61,b9ea0761,305b4aa1,780bab03,a27fc730,f96b7c16,6c98a1d7,65ea4e3a,e0643298,d981a012,4b03fabb,71fc47f9,1c92cd3b) +,S(6ed60282,85df2302,e6b10ef9,4e11ce0,9143c569,a84388c3,e2151c69,c3ccab14,675ea3b0,687a3b78,e8fc7564,9665e62f,e91b0d1c,25852608,1d591ea5,1ad196e7) +,S(bdff05cb,a0cca14c,55b3c592,38515532,70806177,443dac7f,4c07ff69,cb49d8e0,5149ad04,86cd8ecc,274a7239,833910f,f09d7993,aaac9798,1dd106da,6e0c9a50) +,S(64ce68c,cc70325b,22be5366,579aed1c,af9f6e55,c2c7386e,ed579911,4e2bff2b,f8c89976,3c8a9a0e,ef61dddf,2213cbba,11bf1be1,eab6506b,d596aede,45cb1cae) +,S(cd42e46f,489150f3,dcaf3c06,e1e5a2f6,b40de7f5,626107ed,af01471a,18ab2bb4,d9c250dd,d2026967,b4c921f4,e253a788,17f11f89,f679e5c2,81dfda0a,1bcfada) +,S(f7c29007,e7145420,e2da7e8e,3ec4daea,5e9b121c,35c4ec43,59d55f01,89619735,66451406,4dbda93e,637735a5,6a06ddb0,5ea2933a,36cfa3dd,c2ba4a33,eba493b7) +,S(6339c1e1,d4944856,26b3d221,4715835c,377609d2,d91150f2,c5c1f679,5e93b7a8,efbe6dea,47b4e8f7,ff55a20d,8facb8c1,d10a6960,98762d95,be532fc7,3ed59b28) +,S(fccf1f13,7d22ed06,5f4bbcf1,e9f4eb86,7b1ec78,d9f40b4d,aaf58014,3489b37b,a5a77c2f,ef9facc3,881559d9,d9756b4d,6646beaf,21b3511c,64a4b550,7dbf3e10) +,S(da97ff10,6f284ec,f123b554,17bc8f5c,a13434d7,58ec3d4e,935c1600,404f62d2,65c2168b,4900330d,f2f1e3d1,cd8ab92a,4f308222,881a493c,f8b301cc,af12e168) +,S(6676a4d5,428a24ce,36957556,c1b44593,343ab6f2,21f0b9bd,dce2d898,333e4fd8,45bddca4,b9332535,f5f4d3d8,3467d793,b7afcf58,45a19593,854b1c5f,3daf7b41) +,S(791e6abe,cf461420,54a22c7c,d3deea41,53396e7a,2a619ccd,30212ade,e57859ca,e4033bfd,8c55c93,ec732990,aff43ecb,e2ec07dd,17e4ec92,68a7b0cc,fadd37a1) +,S(3a7c7bb2,d5181550,a78985aa,84b73246,c66dd947,4bd7c5ae,20717f31,af0018a1,2388eb17,e03cedc5,221f732a,9e505f8a,b6c38d25,184afd14,37b52d45,fe9d7459) +,S(249a2db1,86801c96,9cbca936,101381d7,62b74017,2b454c3b,ef720bc5,413ab999,da185c41,76aa91c1,d783cf9c,85c075e8,2f708e0b,3ec930cf,f71897b5,d1d5e7a3) +,S(b25e0d53,b4e0cc09,985f21e0,c5655e50,32c0857f,b792b136,14da6885,6b4f8590,1bd17aff,6b02e3ac,e1cfac42,fd28d837,ac5b80,42b21055,d6b84e67,5d83eda2) +,S(73605368,5e83388,a869db66,f110243e,bd1073f7,517fecd6,1359eab,b7862fcd,e9c7a02d,842c5a6,fa43407,6e12d41f,e767fae5,5a75e913,d6912536,6d5f9d56) +,S(ec2f0b56,71392e97,2f8a0c9,af259d42,2e5b52da,5e70fff9,7115c961,77f1b1d9,47f7debb,adb24e59,c8571fa,98e56d32,d49e072b,4fdec818,2049498e,908183a8) +,S(7d7a8fa8,250dd43a,91a2ad2f,320e18c1,afc25595,213778e5,cbfa6058,4be2d378,6b48ba16,89627d77,2700f11,9bc20d7,fab2b07a,413f752e,2a0e111,60fea3be) +,S(316a71ce,52b6723b,a67aaa01,e26082c6,6e59490,cff4c366,5c695ff,aa6713d7,d6f1c1a0,7820c612,12b44cf6,e5cb4ba1,84152ffd,cf82e020,e95af73,d6a1cb9e) +,S(21a2a8c3,ade89ff,c32e5fc6,ead97a22,9ace8857,11db9930,ade6e72a,9fbcca51,95fd3d04,38df517b,5712aafb,432f0e35,726fd438,a2b941e4,7c56c1cf,8882e4d0) +,S(3f181867,b3ad8170,dad46c68,f513afae,1ad2cfde,41f9535,5369ec32,728f94d5,a51a94e4,e9f20eaa,d5599189,4222ab0d,91abb8f0,38b00a91,5f09df10,a2317527) +,S(e9673139,11be39bc,f11ecb9b,690ecfb4,79b7aa6d,3158ea69,7d0092f0,89f63c1e,c100cf7,6f8783e3,8de2017c,32022a0,da9be6e8,61307546,1f98142d,4903abc2) +,S(61ea8ab0,1407ac7e,547e94b0,6f3986c6,d3096d43,2bd08cd8,61554fae,9008b122,e5c55bcc,a6f713a9,76490488,e69f1cee,150167f4,283fa792,a105ca8f,f4a4d182) +,S(ad8fae7a,17457fdd,9f481554,239a3f1,49673df7,24a3a402,cab73f93,bedab9fe,53b7dfef,7966c4bb,bb01d037,12563f79,48517220,2ed375d4,d777efef,50f03e6b) +,S(8605cedf,bf7f2e54,d3f62f27,44d9d436,cdf9974c,9190020c,586818bd,b6a829d3,5af8a55f,ca2aa1a,6209fe4d,a7708ff6,e7a33df0,50e85873,d786f54b,7d946b88) +,S(bdde544b,465b9ef4,7dcffa5a,7a794cf9,6e83253c,2f22d4c8,cbcd2d6c,ff921d87,6c536367,7ba867f5,5ede7d23,81be6ab,ec97c8d,f88a1a74,14ebd6ce,8caadcd8) +,S(31882a45,e8b088dc,93eeafca,85c28f49,62a47bd2,bad916bb,fe3e7346,32fe1cdb,b3588f0,c5f86e1e,12ab833c,12e028c9,d03557a9,e02aa1a6,fd11d693,55f176bc) +,S(17be4052,45800f9e,db510b72,603b8e63,e49fadbd,62798883,b0d04f76,a5dc1202,1504ebdc,df8855ae,28f7738,e40d277d,81667e55,a2f59cb9,c9e33a4b,8d32fc54) +,S(c633bd33,bb697d2a,6bfc4e69,707f2b28,a303eaf5,a601b08c,9c56afad,cb629537,86e3f413,2d4764db,f2c06b92,461c64f3,9f3b7f78,33139eac,2b4d59b7,ba18cef8) +,S(f39e208a,f4c710f7,190881f3,a33cd113,633434b6,3b460062,570618f5,8260bb52,90c56805,807b36f6,272e2b66,4d943c33,d0171ee3,ba5cd4e2,bfe52f92,b9e2e62c) +,S(ce984394,14f29607,a54ddfb3,72db8ac5,ee4e5414,f59f73db,89360232,f4a16c54,1a4805a1,d1057b13,c72f7835,4d40ae96,bb80542d,ba5ebd7f,627cfbae,ba24e0d7) +,S(5266e79f,81107a4f,ba571af1,885d755,94504122,a15a673f,6257f633,bb0a76bb,5e7ad1d0,9cc85f12,8773ca39,77b55c20,18d38200,fb739918,d3b0fc96,a559b457) +,S(4fb9de57,63f47aa3,bf370113,c778bc8b,67507009,5126f5c1,1ffc158f,be7056e4,2cd97636,8eec7197,aa2fa34,72fe3db2,29fe0275,8789d75e,52e87553,1486f7ef) +,S(ad168024,a99eddbd,aabec840,6158cb92,4ae7bba8,d233745b,ded57407,23cc0226,ab105015,968e4673,8ede230b,b53c4be6,9ee6386b,91ee03cb,a21f7040,f14095de) +,S(55829ae,f7cc555b,733aea9b,f1b307d,277923ba,148ba8d5,5a7c8001,73719cb8,6a7b2eeb,9c9b9585,5403b47d,6c60a7bc,382969f6,c4bafd3d,3c4f09a7,63267689) +,S(2119f233,8efa4e0e,2204bbe7,84e9de01,4e1e4c43,450d5910,960ebc38,6b78b935,9f219dc3,778544c6,7a337db9,69c513a8,52acb469,34a71957,11c36913,b8e7bb93) +,S(11fc3e1b,9491be9,d7de53ca,a2558d36,c5227498,3f5c1b32,57f0fe5b,b1295bbf,1c69c74d,ecb05933,6aa6b6c0,231105ad,91b8d188,d109ced6,2198c528,844cf6f5) +,S(34b6ce6f,ea6e5143,95091bc8,67e606ad,5e64ac18,99085821,80abea3b,dfd2a908,5b6ed904,f4bdbef3,fb9e41a1,32c7a313,28e9f325,4e180694,40339642,2bccad6d) +,S(6c225dca,b45768ab,3b1c567d,97ef745c,b326fb3d,2db6ae2e,22a40c95,3610a84c,7e85d752,2180fd8c,ebf63cfa,2d843bdb,912fe042,d00ea29c,d72fd768,402a1084) +,S(5f776e5,41dd95c2,32fcc757,14b688b,cbfd2020,e7043e3,2a707144,5a8ed7d7,3b8c5c78,fc6d8354,3a09de0b,9a64d529,c116803f,6d0d62ff,2a20b369,8b273c0e) +,S(3e26d8c5,531543ef,5e37eaa6,3244faa5,d5371e48,16fd94e9,b8bbd932,891b0e23,30a09d1b,43a4a036,ee1a53bc,6c3ebfa,a5b4c70f,6d8af4b0,c70faabe,b79bb65) +,S(c634da91,c17a3568,aaa970ac,26553e45,6be8afb,ee12c85e,8aa0dabf,f18b36af,649681ba,e1390a7b,d05d34bd,98d87ed4,16eb9f99,c606f46d,6d522019,f1a925f0) +,S(ed335d6,4d643598,c6eab4ee,fc242d7e,4e8361b3,ac8d747e,806962df,2e7e9a7e,f0e7c3f8,19c97aa7,2334b690,98f28bee,5a1552e7,f578d5e1,eb56b600,fcaa93e7) +,S(d37f8c09,411359ec,3f63dbf2,2870ffb2,d10be164,7553f28e,d72d9585,1e521581,da7cbfb9,ba3ae036,72df1be7,56d3c9be,831467d4,cbe3b51a,191e47b4,9d1f1922) +,S(ee3121d7,c7475ea5,c3aae061,1c6b420c,5b32d05,ee86f919,43c3352e,7515c360,703b2e37,97bea3b2,9b447411,dad7b12d,b809164a,ba690281,b76f245b,bc4c1686) +,S(7b42c9bc,5c2b114e,a0ef1a59,492a6132,3f5c7290,427572b5,fe98017d,1987a12b,5cf76382,e85b73d7,56fcd92a,99242725,dd57edde,30ddd9c9,dc7dcd95,260d27da) +,S(9af5ff9a,b13a53a2,93f9b6b9,a0f925d4,7c8f9b84,5f6933c3,ad074922,f8a555cd,ca93ec9e,89954734,c8aa13fa,5908c855,13a9ec19,6417042c,a336f1fa,be5d4153) +,S(5ebfa274,1a2df1b,6e1d591,f70983dc,a5b2b850,856bd7b6,59c81877,3848dacc,b0adcb9,6ac23c64,2904c15e,822991e8,46e12411,f472e0fb,5fb69fc7,a0f7ad18) +,S(93b58d08,465e5eac,8518382b,c1f6ebec,daeb486,7da65dd3,ac125e6c,fcc81e6f,54be8918,c3151784,d74646c3,6bca9c8b,8a50b8d8,63b1db8c,f4fb3ef5,1a24a4e7) +,S(a28a579b,4fb46474,ffc943ee,32b40664,5bc86899,edaa111,32c31f1d,cb6fc858,40ee91a3,d5625648,196605f,f650ab7,6e059b14,faef6396,46c9b153,9af14670) +,S(e987909,781d5560,b71f6029,750d20ad,add7cb47,f90c9078,e8de5f2a,d606ac9a,7121ac3,4c80dacf,ffea346f,5c5e1a81,c55318de,ac8cc907,10274f18,ee9819d2) +,S(291ff11d,158780d7,fc0ee62a,e395456e,5c84bca9,75e84a7d,1d2b3bf4,61e1dcef,c5c8cbe8,abb6854b,670298ce,8224a945,71e79e37,9335acee,c230366a,53ec2616) +,S(4adb1390,9e28b53e,42bd9e57,373aa131,efda7d16,b8dffd82,4bd9803e,fde315b4,66d7eb12,b827ae7c,970a796e,5c0c99b1,24eb7002,4fde63ee,fa2ecdf5,d4b1456a) +,S(55e25f4b,95240efd,e3c7e47b,2254601e,1707a8d,e40bf384,6b3a7024,da7591ff,e9f2257b,7e98606d,743000b3,72dcba0b,e4491ae3,22e82266,4b1e2b5b,78c830c2) +,S(d24e7493,e41dfc32,be7a6d8d,5463834d,388ddd01,8c213ad8,aa3005b1,fa747eca,e73a8216,a51b4b16,5e9f5bee,414d49f2,6d7feba0,982b9e93,fc4b7863,48c26cac) +,S(a510b252,6d015da1,cb7e4600,3ed61af7,caa03562,19227d9,ed8eea13,61fd8b2a,3d98c2a0,9015abba,63eb15a2,80c6c479,eaa2b2f2,a0011adc,3565d2f3,8abea726) +,S(c04d04d8,127500d5,15bac63c,ca55d76c,8404cde6,fe681f4f,6b8c2b48,87b314d1,cb3fcd77,9fb80eba,99cdb937,31bc0814,e3cd4458,df7fee1b,98c4067a,db4d9d59) +,S(ec9c7c61,146c3357,ba851e69,18ffa770,6b5dd2ff,a789245a,df70f90,eebd0649,9a09d3fa,10ca6923,c068803c,e9161923,b36b0709,b12627a4,dafd0e3d,3d186170) +,S(95df5d3f,5d504c45,f4b7e840,3805e54b,b2598511,2ca53064,baced58,a0488cc,a43dcd85,89b85305,b07d1ef3,23eb305a,35079cdb,743dcc21,c7a6ad48,4ce8ecc6) +,S(b8eece0c,3a950c52,c46bf50e,b5dff949,2fc8ec4d,6bb19651,c72d447,633a6d16,74e942a3,1b75bf83,ba6c1460,d969a2c2,4a49572c,ce3fb84b,8d0b08e1,d5583744) +,S(599ece16,d1f69c22,53deac51,75121ea0,c82b2d77,c5e2c0ba,520bf1c,72dd09a2,48a10c3,25af3d0e,dd8e2e72,5d7baf48,b2fdb672,66423859,9f73d231,a911bb14) +,S(b8ba5a06,8d9458a9,6e2fdfaa,961acd80,7fff711b,bba4e3bc,35a5fcdf,e82ab32,8035ab22,7554582e,9038845,44d32a53,c2d82417,6e2ac7e3,2d44cecc,50f8ca4d) +,S(b6846be1,cccd7865,e56d3d7a,f1b1fff3,ae806380,a1710c50,8c35ed17,227e65f4,bbdb7025,32945f0a,de989f52,68230763,361ee9d4,9c0e6241,77fe6fb6,cbc7201) +,S(a1ffa65e,69872bbe,ed009e53,f846d9a1,20dd31b3,a11932ff,c3580ff8,da9d0fe,aa32e580,d5763bf9,dd054999,68b6ba6f,31c210cb,26846ada,dc0045b1,ceda215b) +,S(9b38176d,67091c7d,f448c707,80cef08a,2ad73cd6,de65eebe,b62f9a21,730d0fa2,22d26b19,c0fb9b7e,f1ec86ba,b8ff5996,64a45988,190499d2,6fb604ed,4e609207) +,S(bc2ccc9e,209dc64f,bb132553,bdab43fa,accfa4d,7deac898,1fa52841,35fd0cd2,47366adc,176ff88b,674931b,a8791fbd,350d1d13,71891343,74d58305,a55ccfa6) +,S(1ce000a1,65452a62,5d036f51,4fbd2a30,d4518734,e7f93aa6,7a7dcd7,24730f6a,e09103fb,5b90f0ed,54b34baf,3e3d5bf3,fa288acd,b6b0ec19,ee3062af,35c6811d) +,S(846c569a,887d64c0,e8fb26a4,49c62447,4cc63d68,4da0909d,63dcdd0a,dde0031f,547753,132c9f98,d7facf93,d4ff0416,7dcbe44,77987be4,7df408c6,fa12c07e) +,S(6365a8f7,28656e23,c9c58518,5686b18b,701f7b1f,54c84b82,f5c81ea5,74fe59e9,8c7cddfd,a992e53c,ad151d46,c9cc0b3d,be27f2b5,7ffcc23f,c8d9cfa7,eb16c2eb) +,S(ed425f3c,89ae3d8d,97972619,55e8fd17,71dc5bf5,98c5237f,bd267f80,7d2939fc,4226abdc,14f7a03b,cd7285fd,19cf14f6,10c98d0,6e3c1d74,daffd602,99a3590b) +,S(cda5246c,2e1b7ebe,8d667f23,5ae310be,85a0bd7a,2e903d56,62a6dca3,971f00c7,791ef296,f8ea9b34,918534ba,318a4fea,96b2c2f3,21e6d3f6,eae8248b,29247f56) +,S(b42a84e6,ce79c1e1,bedd3f7e,596a11c2,f5017d98,386fbbc6,f906a5a3,f4eaf99e,2e722cc9,60bb3718,36ffad5e,47509fcb,cc3d0601,70b02610,823fa40e,d407e6ac) +,S(358be08c,e1e2e9bc,b43149df,58700875,be23cad0,ba8524c1,6d46a01f,ab0bcf90,f3c4fef0,70baaccc,f64fe0bf,b6f5111b,462318a6,36489b00,34f05c44,1f9d1308) +,S(3ed6435d,e5b36230,a4f74bfe,14571041,427d16f7,9b433ac9,85c9e135,6016a789,1c72e85e,142743d2,b5be677e,352d3dff,ee0dc56d,5aa56d91,4b92762,6041f26f) +,S(249f7e2c,580dda16,5940d7e2,672176f4,afb7e50,b9250610,c253d9e6,2416c910,6fc16311,49e9916e,8f70f842,3dcde36e,1630f508,79e96e48,6dc7147b,3aa9f50c) +,S(97b3b144,e8381ba3,1b0f6f0b,752cbf91,14d2d76f,6f418d4c,69f0de6e,c89cc85f,67c9bd30,33b720b5,a1449257,f1de85a,f7282260,9e411dc2,1820444d,c988724f) +,S(3b38459e,868b2912,51d0fcaf,41245087,80610d0e,395e9b68,cfaeef1a,5f395a85,be5180dd,bfde7454,c78cc9a2,b77245eb,91ec4c25,9b17e3a3,c3e8e49d,5225ce6f) +,S(4e6f1790,9f33e08a,914974f4,48270fd0,74fb35d1,49a017ef,c54fe21c,96163ebf,fb6578f,6f47156,5b6d3491,3a9a5e4c,dcd2880,d774e6a3,e56cd078,e6b9fd15) +,S(9141ac63,e408937d,7425a0a6,70a2565e,72e301b7,75619a92,18db32da,315c75de,d35e290a,56bec3e1,3cc55e72,12aa57db,f10b34df,bd7847a0,5de91c4f,546d6045) +,S(ec9b73ca,72052751,565c006a,4fc9200,337c9162,88eddaa2,e212c611,395ba578,37e11ef5,c1a22e77,38d5f3ab,4c74e2f1,ba192275,4c4e7905,1b15010f,3c224887) +,S(56fc14e1,bb1a928f,ce0430b1,feaac6e5,aef50208,be530d7e,f0f5b81a,ce1caca3,4e5a6084,f8680d07,9f3101d7,a80f452b,b05e597c,c38d9865,f6d7f307,90209001) +,S(aecd741b,2cebd4cc,82b7c362,70f1b22c,cf3997c3,f180e1e4,d803a89a,657df731,5f104b33,6c0df49f,1936356e,8dd09b3a,256bd317,afffd4d,8ccc57e7,f90b8e21) +,S(516267af,54f83d52,24a22b9a,4309e9eb,9b5c1072,31c3ff0d,418f8bd4,15836cb8,4187389b,9e062c17,f4ef6fd5,4b6b8439,cc37e85d,8a3db13d,86592098,7befe4fc) +,S(68bbeabd,8d3f4473,f91a0368,7383b4ff,6e7658dc,6e1287e7,f258f543,2466fed5,cf63c80f,ac99b42,7a67f7cc,d978d5b0,8656fc7a,6a383c27,48635ad,97049c4) +,S(20ce22ab,69467e9b,51d59213,8b52c1e4,49ba908f,909658a2,b90dbeb5,b07b67be,562da07d,9f4173f6,9232d17e,49ba2c17,31649ff1,4a9dcc3e,68f20dd2,de97ce2d) +,S(b5b7d6d3,a4a59f92,3afc1ec6,a5215786,9c86cd90,7ff80b07,d04160ac,6e798f78,d05e32c9,775125ee,dbc55af,4d1597b4,45b5eaba,5bbf6dbc,b8ef3e79,fe9d4de5) +,S(955bd489,7a4280b1,5de3d848,f75f6dba,3967e593,6b077d4a,cdc4c30a,33f45df4,4bbeb7cb,5d79991c,ef3b9fe5,bf25dc01,6448261b,44b156b2,749f9734,3d453a02) +,S(9f60e951,98e7370e,b3c02fe1,8bf53735,50fee849,9c876211,201e47f8,660a5a98,6395aaa9,33ed5866,a02570f5,9321d89b,c865a7ea,62e28a6a,3a62c4fa,4cd613cc) +,S(7081f0b6,f5923d0d,be4041c7,589a7100,9c2b6459,a255468,999f2d4e,50d776ee,9cb60005,e067019e,93aec9c9,1bf28b4a,27f3f0a3,288c4758,403a9ff7,668f9fc9) +,S(e290180,d8d5a7c,1b0e982a,bd63ef9a,b607d605,87e663ff,fb0ab73b,3369561f,462776fe,77289a4a,250ccc7b,80b54e51,993f741a,14299f78,61b88d17,d4d924f7) +,S(8aea7328,b285bd5e,b63d5939,c5c8c6b4,ac254cdf,c42cb521,2f4c5643,58598bfb,b682da77,4fc55ff,eb4a559a,8ca0580a,13819aee,990d9e22,8e0192f8,9568ec2) +,S(e9d108b2,54b24b57,ea4fc287,45865c09,27302d7a,1dfe90fe,b3a17906,2f256e68,fff7274,6d29d9fb,e7b0fc0b,1af14365,8d0ba69a,a45a72c4,8f67b939,aba128d0) +,S(9ea1f93d,1f317e61,786d4909,429e4cc8,b81f2914,17d28913,6d886b86,adba0fee,231dff25,d3b0b351,6e63ba6a,afdee115,975a5c00,b95936e4,5d9c6be4,6980ec0a) +,S(e8a12415,e5fabbee,7cd687c,43e8d530,80701d01,85980c5,7181b68d,481e7a0d,dd69839c,e263e746,99462f18,58745727,ac53bf2,2e0385dd,5d6a21b9,922f62c6) +,S(e287f3ba,ae486145,a1c2e04c,7f6d5c1a,ed796840,27636cef,b4446ff3,6c3def2,9395413d,401db0ea,4ec53bae,ff215580,5bcfbe8e,7e6bd6e0,be5b9fbf,9d968c63) +,S(8f99f79c,ec205ab0,e79756eb,a14c8e7d,fb23e232,6ab77927,641960dd,56ad1194,805953e6,15cc6d6e,2f61b0da,389b24bc,89cbff4f,c9f0ade8,c5dfff99,e819a2ea) +,S(9c87ab6a,8cb723ad,e0cdfb59,e5a1ff6d,3adb63d4,7af33e14,c6b3c343,c766f586,74798122,7a3bd79e,7d5012cb,bc81cff7,6a3699e3,75874200,4edc6e8a,a965bb19) +,S(c52c8608,6f245de4,baa10b7,fb512ff4,6042bd50,7d88bc3e,c75ec75d,d99dc00a,e8c2813a,bae8b8bd,9c8762d8,37d42fe7,85e5406c,5fb5cc2,ca05ae03,4ab3f844) +,S(b6286e1,94d5be25,9a79c6b6,ebd634ac,dd7c3fd,66ab0de,d8d4e160,ba8dafb2,72ec2ea8,ee0bf270,777cdf7b,47991524,27eaaf24,2a0334aa,18b3855a,899b5910) +,S(df7b56f2,45f2f8b,7213792e,370ca89a,45c648a0,5f3ba4ce,8c5d6d34,2f086b6d,386ced48,3850bdcf,4209fc90,d039b96d,39ac18cd,5d97ecb4,3df23ae6,1596ab4a) +,S(2acf4c9f,4cd42357,3e9110ed,a64aab59,459b2b37,675e420f,48ecd068,6d46a3b0,5f1a5829,aea5e981,cddff9bb,d2521ffa,58b37baf,9544c0cf,f622857d,5a2cc579) +,S(bfaf95aa,eb55d378,7210033d,b352372e,6a64f2ac,a420b877,586b684d,9cd33f36,7d22bb13,bb61e76e,2a2fce3e,bbf9ec83,78c6ed2e,5f143b0f,60803cda,b0a3d8ee) +,S(78cdd360,4eaba890,da793c9e,f589cca5,faacb6a9,14a29f6a,6add7d8d,74f31421,ed7e9c15,5b801d1,16b0d60e,fb5e2287,76430c8e,faff4bfd,327a38dc,ea19a634) +,S(f2ebcfa9,50a391f,c7b97713,566a8a49,edb8944c,7cb68276,d9843c22,8d213d2e,b1c7630d,956f9f13,c53a180c,569d534f,9513d16,4f3dd900,bb3f5e78,b0fa4eaa) +,S(43cd60d,83bfcbb3,cc19943,34552eae,857593aa,e8158adf,ca850b9d,1aaf4c2b,ff64bab1,f721e6b,9e23d659,224998cd,996230c,4fccd302,47e9e110,607e8f62) +,S(41925ce0,c01a49dd,7be0c3a3,b27f13b7,2168dfb,a5ec1315,f9209709,f38ea93c,5346b95e,cb6a0ac0,1a2f49c1,9b02d9a9,a725a676,f144ac26,c48f0d8b,94f77110) +,S(fd231210,6c762d82,a851bb47,8d0ee0d8,fa1c232,7e26feee,3e6ece5b,323877e5,39763316,f5a6ece8,baf748d6,234eedc1,4bf33462,1db3e66e,7eb2fab4,f96fa162) +,S(fe3e8a98,cb7abe1f,36a54a0a,a3d1c9f,d5ad684b,d05cb2,6ea683d8,f4556ef7,7d220677,34d80663,a1ff05f9,bad5a648,837b4475,abe0746c,3fa940e0,4f1223bf) +,S(e602a764,ae0d1bdc,4c3f9b1d,271717db,38232e94,84181ab6,9ba8eb73,4f5ec5dd,ad1038aa,26268b10,2c1f951,6b77b482,8bc9bef5,7b483450,d513e6f4,cc916fdb) +,S(871895cf,adb772d9,719cd962,5dd391b,3218142d,364764e,eb0bc6ff,8d81e086,49a09064,f7916421,9d51ef56,53861350,dda2c9ca,4e6269cb,555c8996,3f37722e) +,S(e229d56e,77755805,c814ec27,8fbcc56e,8ed4ec4f,4c14907f,4ab3a0e0,fa7e4b4,cdb07ebd,66d68055,bed7a46b,63ceaea8,6d42659a,ae6ebce5,795ab908,14e48af2) +,S(5535f85,6b0cc868,88ca3118,9d20d68f,471066af,a70addd6,ca4a9537,68bbf8ed,8655c844,245e2a67,8427822f,ac3206a1,f6f52953,4f7a6c29,6ab4825b,770ac5e8) +,S(10657905,4b37ce9a,e240d78e,3d1066c,b8c48d21,fb7130c,dd35ee5,24767ad6,52836b7a,508a6190,28eb013,c0355f70,4393a5af,e133abe2,e8b81dd4,83e125f5) +,S(3366b207,2521d023,99e9e311,e3447778,e796db0c,87428e4b,e6cb0ff3,a0868c1c,ec6022a4,22a8dd2c,a7f2f15d,39998394,ac908c64,74a34ae3,255a28d,4311638c) +,S(4a789396,339be46c,73608a1f,59fdb41e,91bd0164,66417332,f2630316,b5953ca,d45b657f,615aad45,809c0af8,4eb8618d,6e6e0346,ae1ba101,3a123ef9,e5b4c442) +,S(ee4f2484,fa0a9c7f,dc0c64ad,4df60628,d75d70b5,7ab9f0fc,ae9947e3,89f1302e,52b77894,d8ecdfae,df7dbd0d,8dab74a3,4092073f,47a543cb,f81ebf42,9f80170) +,S(4095b5c,163f226f,7937fbb8,3035f6a3,9aa9b760,c5086c0e,af9959fe,25f30a1f,1ce180ac,65554d4e,e9b14595,5c059f64,6a15d032,930465aa,d5547c58,5dff7ab) +,S(6a225d3b,67d9d42,412ecd9f,d018bfbb,7a36a59c,d2f53494,3d6cc62f,b0436a24,29b3d63d,9352e0cc,aa23c91e,e300592f,cc698abc,c73c48da,6a384f99,ea7c2701) +,S(23efaa41,e5f9bbbf,c6953a89,e3f4b9e2,17249254,94f2057c,f46d0c8d,71d36e93,cc89a7b1,7f2671a2,5bd7075,5c269219,88cea3a1,1315b86e,f218e493,7cdb789d) +,S(e30c1e97,f7f99957,58d591bd,6a398ae2,f972176b,f637c66a,258ad081,4f3ae55f,1a70cb6c,3e66e925,fc1edb4d,4d29bd89,3e8e4755,6825adf3,11e64b01,866509e1) +,S(be64d782,acd416d5,2b612f53,4601876b,f05aac91,13c8d265,b57ca32b,df08e278,7a41844a,43e837c9,293b81c8,73cb504f,bff8f15f,5a21e61f,9466acd5,87ad7e4a) +,S(caac02be,e009a61c,672b4c2,82fdf2f0,73ada0b8,d4a45450,76d24c38,f23822ac,7d93e4bb,a040f4e2,23acc304,75c455e5,72a9a64f,c66108ea,500ca62f,9216d06f) +,S(da2539b0,3a9cea94,9209321e,e1719b3,c1ef94c3,86d0e860,fc0ec1e7,684ccb3,e85e1387,bef1cea2,f67f601f,8067e9a4,b1b1306f,6a33df15,7795cbf0,ce3cf9f5) +,S(bf2ee552,5c965248,64bc1bd8,ad9cfba6,4ce4fe7b,be9b4198,700e936,799cc0ed,889dea1d,b1298a24,a11529bc,30339023,5df42398,e760304f,6343030f,6058f18e) +,S(b3e4b141,cb0c3662,9fe4c9ff,7a42c635,1130602a,720a6264,30b967c1,47abde36,f66f7118,c38a828d,8c4ff83e,5d6affeb,eff979bb,2e419f56,a7d7c8aa,52865657) +,S(451eb24f,fad7211a,11181826,5a223649,24a25593,63c33e01,4967ba58,889475a0,889ff940,49f6c3b7,9a5bd321,1c1f33e3,4cb2f8c5,bfb141a2,1fe5419e,44565bb6) +,S(29ab658a,6a754778,2127a0b0,c4b8af33,ea4c77bf,4bc0fc53,b5d65d07,38f5984c,aab1bda9,c77d6c3b,a619f9a,d72da6be,947b8baa,b80b16d2,15ee01a2,2bf0f2c1) +,S(9b59c407,d815c224,5bbb9c0,d1da59fa,9d9e79a,c654f8ac,2879b341,297b24db,a4ef058e,e6300114,c2827811,abacc0a9,17bb35b6,9b1b76c,c761ab8d,a676d190) +,S(87d27b65,82aeb975,8b9b970e,76c3ac77,78e69a7a,52ac620f,c0564e74,a66c9fd0,3ff3b3cc,dec29337,41c83e08,7f07f41c,4d03d5c,93268b1a,cd9098e1,37511e03) +,S(fbb3684d,38958163,bd85a0ab,36bcb93b,7fe7d383,b70d8bf4,d9bba6f6,989701dc,7b07cdc6,c9c5b3bd,10dc2af7,b2606d09,759e7342,68a5d4c0,301be264,87b94504) +,S(82022ae4,ccc42b9d,223cc1ad,c66e58a5,a3ef1494,f95274ea,cc7cf79f,4314a453,c2424250,9ddf2da1,6f0481a,9b4db450,3a81805e,9a8eaa3b,b5cd0e49,15d2b695) +,S(ba5cd45b,3b51cb37,bbe475fa,e91f8975,ab4e657c,57d0801a,1dbec958,be20f901,2e0d4fc0,f8b4f58e,3407eddd,298e5324,7f9eb718,b58e4164,78e3a01e,cf41b0a5) +,S(1293c841,b316d1be,76ab4444,53e72e22,cfadaf3a,df5b6d27,7cd065d8,8a6703fc,98f58f37,40fb4988,b844ab52,3420709c,2488f144,88049749,28670aad,5133c2fa) +,S(ec9fb3c8,54bf1bda,dbb972de,a8ae36c7,987d77e4,8d8437c2,c69aa988,df5015c6,d5f35bfd,ea59e974,961d6b36,4832560c,fe425d54,bfceccb2,a00411cc,a5486d3f) +,S(2ecce03f,4cd55b69,6cbd4466,2e7d58f6,9950eaec,6adaed62,7694dcb7,2544d244,e14f30a9,7f1cf747,ead403ca,e07cc4cc,d1bc793f,de79082f,f6615e6,43f68879) +,S(ed8faf7f,a63ee520,7825e7fa,56f6ef8a,4c6ad5af,ac507c3d,77c025cf,566fb3b2,df120b8,ab21273c,a5af1040,7fa3e54d,cb0636c4,8ebf88f2,c9b046d8,83684a9d) +,S(47cb8f7b,8780dabe,c1eb456a,f30fd917,bf3fd9f,3c28e3a5,bc078c5f,14c32e4f,f8607a02,1f16aa6c,68afc948,f21ee2de,c5889d19,8978e9af,66931bd2,b4aa3203) +,S(76365ac1,fdebab2f,3b9a3ee3,8afe70ea,d4962047,1e38e5ca,cf215a24,3d762009,2cacaf72,8b4bb600,ff37d3a6,97d45fa6,5d778334,dcddc32,11fc51b5,4e53aa28) +,S(c9dd5de0,99b8e552,e1375055,63edc83,9f09311e,11868ea8,a233309e,cc27b424,4bd4d238,4e615eb7,c68f134a,eafe7d2b,38163a8b,b117f9e4,b382236b,b8f8c1a5) +,S(22b6a7ad,cc406ebc,7c1c2f96,bdbcb6f8,9a1e08b7,822e2a31,83e5932d,ad0a8961,52b86095,bab24f4f,d2ebe9a9,534af2d6,87b553e2,77536d5e,22c1eddf,ae0ac794) +,S(3ee808a7,49fa7df0,c37017fe,cab7f6be,96f06c04,b2de4d24,a331a9b6,9f81a158,3e954cef,5f1f9ecd,887dc174,64cffe5,6c4b1356,d841ed0c,1e23c1c,2439cb4a) +,S(2938bc58,8a7a4896,de69ae4,4d5b6240,aa97d302,7043048f,3e49c222,b8fa4803,f26bbe61,9fad1d90,de74826c,ba6ea02a,9ea59a1c,59cb4818,65b054d0,39ada03e) +,S(682558ec,da97c9de,4cbea34f,5df43274,94962e5c,df72b0b1,2c3977d7,e1a15451,c4c2e765,22c7013f,19253c4c,c8ec6cc6,8b543f33,5aeb620f,112824af,b9fedc6c) +,S(720d8c68,fc520da5,79f6811d,e1f3d045,cbfad09,f7f7d8c,8ba68b4,6493620,b867e8a8,4f7a6d06,4d6fd4b,8bbb31a9,7ac26c3,b485fa29,50d545e2,644c9cb5) +,S(967fb3e7,1bdf658d,356153ec,6c0463a9,994d5d2f,b3aca9e0,2a17f5eb,f4b84831,b84a65f8,861724b3,2f5d0926,ec9a84d7,e3cddfc9,c7887a09,4cf602eb,547cc83f) +,S(1d9fd25c,77ecc3de,8e5fc113,1ef13b9a,73f6ebd4,f8673d88,db2a418e,8bcedc85,54a06301,d9720fb4,bfbff58e,23fa4233,33012c9,d62bf0e4,aa6adc4e,ae8035d7) +,S(80138158,a1137af3,114dff5f,f346e339,7d04029f,9050d44a,b4cea89,f1311c0a,16f49876,e6d6ac18,c25cc712,da3afe70,bc5e9489,7c55dc36,bdd234aa,6a5a6b31) +,S(aab4021,77fa5844,e3a0906b,3107df22,33aa3418,222a8c55,c6c37933,c3ef632f,9b83208f,3ad0dced,382d5876,7a089711,9a062039,9a7fbd2f,7034e5e0,3201b092) +,S(8f3fd14c,7670f464,d9ef1e3b,3014be60,3c523237,14bbcfe1,d3612f13,fa72f10,84cb7094,7901b81f,bbfa593a,5c8606e6,862ef6f5,d71c30a4,b546c08b,4205c68e) +,S(3ba9c91c,aba3c06f,eaf4578a,33979ec8,df69a903,30cb8d88,e49953ed,4a1f4933,7048a74c,3eb66231,e8410799,591bbef,fdcff65b,b492072f,582ee47b,7a6f99cc) +,S(2f8c37d2,89dab0e0,d5152468,29f6cb61,7344c21c,29860645,5f29a9ca,dcf36a7c,37f0b64e,9d02710e,bfaf145e,69c79965,4223d093,7a834201,d2f74d40,eb508396) +,S(45e6eba2,c9209d27,b87f6050,a656fca,73fc6128,cedbd2d3,ec40ca,76dce846,a3e28d44,ba1882bb,d1c91a63,5ee22582,81386757,4e66ad90,8a062c93,bf5f16ec) +,S(a5ecd3d3,80a0cd23,4467143f,fe842d9d,82ea7d9b,98ad23cc,605fb8b1,fd767ee9,22f12823,8ea84269,3fb31fe5,b5015cf2,c9ab6c33,d167b95,9bea6e29,4f11353f) +,S(f7f45a71,c4663b0d,44369821,318374e8,51eb66a9,ff6034a2,c943ff90,174be83,3a1633cd,4ec197f5,40d3d6e3,e6a3281d,7fbdf46c,f52fa149,8acc0a43,5b46fce5) +,S(92582286,6b314e17,5af03b7d,e5717d42,52bf6c82,a55ec832,a94b274b,487cb59c,fc8e9584,736809dc,65234670,495bbc7,d6c2f52c,ddfac4a0,369f0527,4a811f68) +,S(c15fe8d3,2303d00a,2f57fa96,6ae6fa75,1d7849f1,4dd527b5,a7f76cc1,e556da4,36242bd0,4685dff1,a67c445c,50cd348b,e017c06a,e2e9cd06,7b5fb109,81c10951) +,S(49ef826,152aa60e,310372df,270bf0d4,4dd7136,7d72be5c,a464f60c,c62b5355,7cad4ba2,dc4480b,9a1c572c,77a93e16,4e369d2e,b565e165,d9c7d2cb,20c4c645) +,S(c8de09e7,538ff94f,e12c876e,163133e3,629b2f1d,ed6686a3,be4ae122,9c91a18f,b5a7f31f,e58088a1,5f1e872,d6096562,9cecb10f,1a76fe88,5eab6247,697c2635) +,S(d86b9fa4,616f43af,1d7a6cd3,d9af24a9,6b3d5119,ef764576,9461ffeb,96abb344,2388ce8e,8f931b49,9481b660,669cb8e8,56df6f72,e392e539,fb570e19,f003bcab) +,S(a2cd7618,f351e2b1,3fa7b719,30fe3041,87c4969e,4f3ec55a,7433ae6f,cbbf88,3e0b5c62,436a363b,1455711a,b310c362,29870cd3,a096324a,a8dd36b8,5d19d685) +,S(b7283cd4,e33e4a3d,7836e4f6,b39b5576,ad6c213b,ed2fab87,ab442ccf,2100b2ca,918006fb,111c2307,1821e7e3,25eab3f,9083367,4248fc,2733173e,8eabc9ea) +,S(b1fd2d2e,9707ba8d,355b123b,9ca31365,d12e1854,6efccd9a,cda40f6,48b9a769,8c37cc16,8e8f55de,f604d222,62818bfe,1a40cf3d,62dae94b,58c9ef4b,475e674e) +,S(1b0997e7,4242e85e,cb4be32,885b5a6e,cf6077c7,395d262e,7c0d2b82,cb39f90f,55b4d8d4,27cd1d8a,ed8c2d2e,f3bcf8ce,f30fae12,4c14b183,fa36923b,6b7760b3) +,S(56ffbbbc,94ac925,dea36258,8ee1bbb3,4f1dc9b8,1bfd7e69,8e055065,d98d78d6,aa73208f,46d72bdb,20af3d23,5bf1c5ba,a517fcb7,b8036208,9f8a7198,d8edc65f) +,S(c125fab0,7ddb7f9c,3426cd36,812611e8,e3908191,67228685,3533e0d9,3ad7045e,2806703f,622f654a,f6c3f118,92c1dd8f,1f235ef4,4df464b6,8ccd30f1,9b77e5ae) +,S(e7ede9db,e4e0c742,8b1fa6fe,e81e80ae,dbab85fb,f259d301,48a51423,fe7f4a17,93ab277a,9fbc5cfa,c80d32e6,5e7f50d2,e236925b,c2dba1d9,e635a56c,d33fc066) +,S(74701763,f1bd6bcc,470c3da9,d853f967,a47c1628,c48b1cc8,aa395159,a3df93f3,ab2c011c,7c5510f3,37393dd5,f05547ba,bd22237b,28ed69d8,a4b6ed55,5d8ac8ee) +,S(8d27f97,55baf71f,e6dffb8d,83784e32,a65541c,5c656576,89c900d5,e79081b8,a7176e68,f3c89601,4ae1f837,bd52227f,f308f90c,b7f31386,e5586125,1ac250ad) +,S(63e06afe,9040b531,eac0a0ff,1ac25db8,71b0db01,8e9828c1,f5798ce,accc7ea9,aaa11884,a9dbe08b,6b28fcf9,9049aed5,c911244,b2a6a13e,9300c007,f4910aa5) +,S(dc7ea1ae,27d60ab3,42d617d0,23e4b1ab,6bf8bac2,882084b5,dde95894,744ed50f,93c7d76e,2b95c5ff,bbfe97fc,754a5a3,b63efba6,e111540e,48a0291c,142f3dfa) +,S(f3aeef6d,f69cef4a,3d7dfb69,1b5aea99,36e40239,bb976253,2213bd1b,f6e842d7,57d37dda,339c7002,f87bde03,1cb1e8ae,72e5628e,f493c115,1fbd0f46,2208de5d) +,S(825bd84c,316e64ea,dc5d081,23d7272e,ae87dafb,28f69b67,816a1aca,76bec3ce,61e3a7fd,ba8370a8,6a3e3f69,d62f87f0,849a2564,97658f1d,c28ca11b,40a52251) +,S(310a2cd7,4dec5370,9d2988cd,8e9426a1,edb63b9,50ec3ba7,f5aeeb93,3856a75d,5d6d86ae,dfa5e57f,7f2b4ab3,aaec250f,e3ff1eee,3e18c228,ffa3b81f,17122c97) +,S(3471d475,62a512d0,f82355ae,f9bb6c3f,69f04db8,977ee4d8,5af582c0,1b425217,272dde70,2fe0b69e,bf86d68c,5037b425,ccd444a9,45040358,aed399eb,db9cba31) +,S(bf6d2563,bfafaf24,20a2b3df,6829aec8,aaeee4eb,ea3538d,8086807e,4c257a2f,e8077a00,7e7b496b,64f847ef,755746b8,3a2738c4,4c1e7ff1,a920ee2b,40b496d) +,S(eb33cfc4,a883f718,52fce42a,3cd876e6,d6f4d465,327223fb,bdbed425,2b9cddc4,9bd400f2,ef608bd9,904f03ad,27de86fb,eaab9137,e25de8d2,a7dada4a,1ee5453f) +,S(1317e0d0,3e5df319,fb383edf,7de95645,6b123d3d,a0d8d08f,82091d6,ecc2279f,3bf6424d,5c6f9d56,b0d22b60,706a5471,dcae4297,eacbbb25,2a9d2292,33675afd) +,S(81b09f2e,99dc43eb,eb22cf5d,c5406f30,7e00f8e4,267bb456,c99bce34,309aeb56,9d4856a4,b300eeac,42f5b1df,92e331c9,1dbc5f6f,ebf17d7c,49580180,a3361932) +,S(deea567,a32ff19,722626ba,ef4ea337,ed436d32,d23df7e,98b86644,855a62f2,5c912697,c61a17fe,8557ab3,40c1792d,4a8310ef,69e785a6,dfe66d43,9d032414) +,S(ce4ad083,5746d173,e68e02ff,a7a91b9e,96ae44b1,cee86755,ef3dc4e8,e43444e5,be86cb89,5238d4c,b553e289,1545fe84,df7cc81a,ff1c2a20,d3406f62,7f03aa7d) +,S(9a993e3d,407f1af6,e4d19a32,48a0715f,2e36384c,7d8184f6,fbbce7ff,530b077e,e4a1a52d,80a267ee,99a7bd6f,e6d96ffa,3f87001d,c543f4e2,481eebc1,301a7a7e) +,S(1f10df2d,7c7f05c8,1717ae6a,1267aa63,9247c7ef,45aafccc,6b36112,fb9bd0d8,670b265b,71e2db79,32683b0e,c967e9af,e45ad643,27cc29af,fdc783b0,58760410) +,S(70ceb257,29c9208e,7db17633,dca775de,d57d1dff,9d914a5a,bad5711,86621b53,6e016e91,b3f3455f,cde11c0e,c6d1d75a,ee9825,7e9d64a,ce7c1ec3,49df0c62) +,S(ba46e5e6,4dc882fb,dfb7921,a106060,43fb6c4,ace9f2fd,46693f7e,74694e3e,eaeb4eb9,79381ff,8a208e06,9d8c436,5868d0b3,dea049cb,f342c88,7d789acc) +,S(bba3badf,d233ad20,e4179bea,f3d7579e,a631d154,e048f7a9,e320d388,3c30d81,f2a7c70d,69dd44c7,317a0af4,e765693e,2bdfce6,8c8a51e8,ed3f9003,5e1b961d) +,S(6df6a769,d300ba68,17e58f1b,f41e0af2,57d491f,38e59283,d93750a6,36d3f8a5,63a083b3,aa51c772,eced1f31,ccdfb4d9,ebf0f492,99f12819,dad9a36d,a73a4a6f) +,S(affd131a,4b8c9a98,294c7ea8,793a5173,4fab1953,1d2fe236,1ada5c14,a7174f2c,4c3de4d9,ec4a3698,3feed322,58a9788f,3426891c,b3205708,73429671,3411be6d) +,S(2da31049,9e54b18a,19dba546,4c7c708d,d42ccac6,bc2196ee,2f0a2453,3b0abc7e,f354ac91,20ad9f8b,56d09d44,51c4d052,426981a3,f7b47e7c,bb0549f,232db974) +,S(3882ec53,cbe3f82a,e8d381ac,edb4c31f,23cdd201,eec93f2b,2dc7d0cf,92e57b61,1d34315d,e5a7bfcc,492b0046,b2740646,71a43d53,2fb0bc78,6cd80ca2,ef7e6e3a) +,S(fcab8635,6a08ab26,39bc8e4e,8e9eb5e3,46825975,2a65cb28,d559bb48,7387f9f1,af4080c0,d08f07ce,57566753,ad3570ae,bef2b38d,4ef7f54,d7b2054,c8fceb94) +,S(fd34b8bb,8a897e12,a29dcd5a,57540caa,847bf011,a1548ebe,5dd89d75,9d36bb58,51a66aac,6a56f973,57927eaa,723106e4,d19b603b,d0d5a55b,76235197,7910b2f3) +,S(1e89bd20,c0d85bf0,76c7a167,87c7d817,1d3b4660,99dd82fa,808d98e5,87d4b469,4f53a9d0,e5768760,3dedae47,574f3123,dcf11590,fbc4d353,eafc8629,3cfe882a) +,S(8a1ea7ba,66909ace,c8d7d93e,aefbaba9,ddca459e,548c448f,5fb3a957,7baa05ed,d58059e9,64f37a4,39f7655b,25018031,ea1f1fcf,8ae94f99,e09c04cf,8b7be091) +,S(e0c3780d,80d59926,96886549,af2961b0,e4451f0c,b5572cb,d7ff76d6,1d1331a1,99d9d2e6,a13c3b1f,c2fe6f1e,5230e7b3,d827ddae,bbeda551,1144f68e,4945491d) +,S(964354e6,ed23ac12,16fed36c,5daade18,8e7e1bdc,ff20e60e,f7cc8c0e,83996035,f748a09a,8563c6e8,72253198,4e6f0622,7e6a408d,3c633529,aa8bd326,3428998a) +,S(9809e729,5125c862,fc6eab86,969861c7,8bd09415,585414a1,ab1dbc3c,1afe3f9b,d8536228,bbf55568,833909f8,6fc84a58,ab0fc089,432fc05e,fd46bf63,987b9fd7) +,S(195f4d02,305e4c42,28d83bf9,4025fc7d,1d8d7173,da14bb34,abbecc4c,f01ed17,957db8b4,97aeb9cd,68152e0,23cb4467,ce13845d,3a88e21a,726b8766,7c9d637f) +,S(562eaaba,3eb17e34,efa3f726,d02490ea,b0203fe6,81b836c0,f2c44a1a,854e0b37,b4e658ed,9e664804,2d3a35a7,70ef4253,97093ba4,d7b32da5,9db56a6f,8552b1e8) +,S(84a2c5eb,1efa9014,80c57969,3302f34f,de3a602c,a4b1a28,8d79f28e,dec8282,700d51c7,88cfeed8,587261db,adcac440,c703313f,5f0da023,bdf62b36,46207cf1) +,S(83d12fcf,dbd9168,b14e7340,6c6d4b84,b93e2bad,77d4c7fb,8ba00973,3672f913,e4856e26,bf2532cf,bafc78b3,682ce9cd,3c0dd6fd,861218ee,523b5131,e7279a7b) +,S(9988a6f2,bbd9320e,fbe73bf,9f4643f8,ce64d522,9ed4b701,dfb0068e,dd5451cf,bbb352fc,bd3b2650,d0a44e4d,892f89a4,d2f431c,2abe9910,ed5a1dd1,8a882d5b) +,S(3e92183d,cfa615c7,33721d1e,2a2116b1,83017d4c,2aa70b51,60f80a10,afff0724,c7888251,f4bcbe62,f0dfe545,3a73f3d2,76a2f30a,74e57d7f,22680b39,142dc945) +,S(d9175300,fa1efe3a,4cb130fa,fb36275d,e5f85b98,5ea5844d,e7763d6c,8239492f,59138c65,e9592a0c,d9a36220,d165abfc,fbad38d8,85eeb521,c5566702,9b678b4b) +,S(6ff5825f,7c12bee6,5d17f7b4,7766e677,ed74c5b8,7a95d068,b4741129,36d933dc,661ae9de,cb7974b,2304be0a,4d2b8d80,2ea9aca8,40cd0381,31f80248,378c0edf) +,S(ed6cbeb1,a8761064,3067d580,ac024f7b,9560366b,bae875ab,15ceb116,50b1c31d,9140687e,d1e889c1,6564d60f,702e8101,1269c476,f19d7f45,19a7d66a,8617dede) +,S(5f8ccceb,32d75aa3,1096b56e,eb132230,853bf6e,38643ca4,43abe04a,8bd69164,35f72a3d,d0c81dcd,4b6ac0fa,c4f5834a,4f6576f0,21cd2d45,6bde5b7e,7995da3a) +,S(81e02085,9bb23977,522896c6,7ed66751,86580d62,f015af7c,479a6e23,982d0b7b,8791fa9e,4159f26f,b42ddc08,85d562b2,fce84a38,e2af9960,1ebdbc64,cffbb669) +,S(de226b16,dd1e5c26,9b7aba7a,d63badc8,3eb435e8,7aca85f1,41d42712,95d8f721,62e1e399,fa2ce72c,3f87dc03,de33d913,3428416a,434dd20d,84156470,1ac8423a) +,S(60a46f42,3fcd3295,fd058be5,9f7ff164,fa762995,27cbd2b1,d13a0bdd,97d140f3,9571d2de,7b789e17,e46bc31e,1a03cab5,912cb854,ccbfec8e,f4d370e,df7f1219) +,S(6fef445c,e1b4bd91,fbd3a77a,ba0c6364,80d7e759,3f42a7f5,ce089fcb,c32249c0,115fbcfb,af46db83,9ae0cae2,e581796f,f82e73d8,7d4c9a91,9a92c5e9,f4fa347d) +,S(6d37f51c,a8d2f953,a3e5f7c2,6edebe57,a9892b5c,14482a30,9145c4fe,4293522f,78e511f3,6718ad4b,de6897c,d3b90e08,cbefae5b,a884bdda,a967eee,9d5309af) +,S(c0ac827,5bd0701f,5c9cb035,eddbe996,738aa155,fe74acea,a76b0351,3d46098,e7f32a2a,188fa708,6a968490,60ce26a4,31d76231,6a65a6b7,c3e83201,f8e3cd97) +,S(9000dba8,6f895023,1fc507df,85faf4a5,822a648d,4b256b93,5d012060,50cde108,9b7ae836,94b2e9e8,bbd8383c,2f4cb03c,32331902,2f58cff1,779d83cb,654ef3fd) +,S(f1109bf4,b490bc8f,36609253,26c2a2e1,ad58dea7,463e1d9a,28aae8d6,969098a1,87431a27,9fd72c10,80230514,1c8c17ec,6e3382c2,c325b022,4a800509,5d2f24c5) +,S(4de871e5,4e9cc6f0,8c4aac8b,36d61f83,929adc8d,4f6e18b0,d1dc855,6e8c0003,25d1fcf,ca98e8a6,c75d7fce,19de16bc,805f4b70,e9a3e9c7,f0187f07,70d3bba6) +,S(a23cb675,92972bbf,3a6e89ff,94e10010,8f47b467,fd8cdc80,b66013d8,62766ece,8dc70b84,ed05c23d,a1681126,77d23aaf,cbca18cd,fd7e9dc7,cae5aeb9,47cf548c) +,S(295d0cc,e96d8f8b,91ba9dd3,be703cc5,79d3c938,a5b7c32b,bb40e149,584244e5,a6d45a06,a16bd4bf,6af0fe37,6538ae5e,745e078c,12b3ac95,2653f7ee,2b03c926) +,S(7c683b91,9d5376a6,d40b13d5,1fbd1769,6cb40bcd,efd248af,9e102545,eebabbce,3da0c9d0,3608856f,5b7ed30b,8d9f1562,197d4e5a,7c23ae39,332b1ada,adfd3f73) +,S(30f7512e,d27e249a,95e0e21f,fe22ec23,8505f39e,ca9f41ec,df5e7ef8,1c0c3189,2f5fd85e,25ea3a3a,15928651,4b473197,9e4e7f7f,56e88164,fad41e42,e4875169) +,S(9377bf8c,96584f27,324a41c7,78d6314b,1c7f842f,b4910835,431f5a76,2f514961,d599cc55,e2eddb2a,e7d7fe92,aed830d0,3cfa892d,3a89cad4,335fd6d3,69f3df42) +,S(3589ffe8,67f20495,ba3530b8,5f83c54f,28a66e78,6bff4ca2,40ac1d55,6d31e9be,98822eaa,983089e1,209c22a8,9f133dc4,d75b3a67,8fdd385b,581a9274,6d224c89) +,S(39c1b1f4,b2dadc4c,e58e0f84,1fcc6415,2c79e77a,11d53f85,999db8b8,ea3f8935,e785271a,d9df3389,6436991d,eff9da83,50bb8a42,616cd31e,6289aa84,d4256721) +,S(dcf11459,d3d62c2d,99879918,8b6118e4,b103f9da,2453b72c,ad5eeded,8b25be33,dc038c1a,af3270e6,345a92fe,7c7dddc6,a190f6c8,fae7d7b3,30a3cc72,f3a1c074) +,S(614929dd,1de9b0c1,3f4d82e5,5bd8050c,a32ff05e,6eb238f0,eed635b3,6623d1d,afe8517,c9e7f17b,a1918e3b,e8180ff6,afafdc43,1acbea6a,e0eaa75e,c4d8a24b) +,S(f4a72228,cff6da94,a45da35,5ec8adbf,ef81609f,b59a8296,a7c1b0ba,9cce743c,545200fb,de095aae,9de90f1,569c6bf,2fbcd025,3cca1e50,a25a81a6,e19cdacb) +,S(63cc4273,6caa5597,46e62fbf,5371b943,57aa164c,fc8fda65,b5fe524,e2c93f7,1fa4ef5b,c5a6413a,d6ad2bd3,4b08289,e7d8224e,450f04fe,9b47c45,ace5665) +,S(ac175228,118438a6,d2cf761,f345cb04,aa7f9d89,9678c201,6b84be2b,8eab8889,dd7df8ae,29643dac,27ab01b6,8f7765f0,832f2989,99a13396,3435a982,aa4af2b1) +,S(9dbb5eb9,637c41b6,c4a5a2f,72efab5b,823e8622,f3786c03,dd678816,9e4a0e48,772d6ba,13f4d61f,42dcde34,b8519aa2,5aa0107,89c625cd,1ba38d4e,b7d924d7) +,S(717095dd,d2fcc135,1015b586,65a0d888,4e88f599,b8c32fb1,73d5731c,3ef7dddc,1de0f109,52b470bc,fb23da3f,3c7b640b,4727326d,d18e020e,581fdfb4,7e4fa5af) +,S(5ac230d3,f829b1ea,401e3964,c14d6e9d,a32c4a68,2ccdbb2a,3319a964,265872ca,fac3c3a6,27dbf66b,c5e06a16,e319ca43,423484d8,3217ae81,51bdcfae,c9c026ea) +,S(d27ecaaf,a39f415,e1457537,b2e74e1d,382496a1,51118100,8577cf76,1f8752ef,fc480b67,46cbaf31,e3d8eb6,4121b68,d5938e84,face3ae3,5dcdfa4b,71c6c037) +,S(e08777dd,f92d99b7,c4f87d53,9fada8c5,703af619,3a088d64,77f1e20b,f2ac6cda,25a4f88a,c6cb18b2,4e96ecc5,3ce10d5c,1202c4e7,edbdc070,db05a501,29ccfee9) +,S(45ae7ab7,afe9580f,bdaa6a13,8896ab97,63bbe3e6,88054776,753a1180,699ba6ed,dc1af7ed,127fe06e,4d0d440e,3d96f43e,502f797e,fefcff1,6c46e6a8,a156f322) +,S(fd28cb3b,71c50453,b3cf509a,768b4c2e,6ae26514,5801c045,327e1de4,f4d00590,b0684f95,4867cf44,aa5081f0,8174ce21,3298a22b,257f6159,c2666518,5ce5a7b6) +,S(f226f00d,ac6f49f0,a195e4e2,23b9fba7,95681660,7671dd7a,158b3260,1c1d850d,d05d5c4f,6925a38a,b4630e53,a1986fe9,d823a08a,3691550f,10f71b65,a109ef86) +,S(3cc61613,a80d8480,87ce23a7,2b3038f8,a994e1ec,8c9c740f,f0e44e90,760337a3,8474f96a,24093af6,94221f09,f95ab010,90377f1e,52a173f5,a11dbbda,cd3c3956) +,S(721ecd89,8cd99712,bd3be233,1f57d686,633e7ed5,c95e6223,e5cdace0,ce60e736,31d294d8,6fc07cae,4a09450b,fec633c6,21dc34a1,2f7668ad,532ac192,a0ffd69f) +,S(dcbaca58,1144d9b1,b2586271,5e58fa8c,d5b1062c,ffabaa2,db0fcffa,2b2eff38,9cf7621d,339f6cff,90efbdca,5e2c6174,708b53e6,1af38689,e6d3b257,21ec7d34) +,S(ed314e93,e649ec2b,ce491938,2c7a256e,b9300b99,528e7878,3421f337,15db8b92,70a81aaf,229fef2,e2922355,e1f15465,53ea0348,e3dfb18b,c837ddcb,60744a11) +,S(6bd19bcc,7a59bc8d,19a97768,95f65ae8,5f5c7eb6,429c09,85436b8c,29c036ee,51346de3,f4f65681,bdbea28f,843545c5,31803ce7,78b5732c,bc42735,4999090) +,S(99ed1e15,6ac8dfb3,604228bb,5be088bf,ebe9d640,7ad8be15,5777c6b1,d43d9acf,75b159a4,478b4cca,80ea0ac0,472436ad,69f57e9a,f447c61,e19910c3,9d2c922) +,S(3e166f8c,793addf0,84add90f,b0303970,f00c3c3,8c36171c,c7fe0877,b2452045,91659a63,b0cd2a65,ec330f6f,b9a6cc6d,9f07e382,7b94b8da,1921aa8,1d5bbd59) +,S(fc1baad9,a3a95f38,bf8d1b16,8409d09d,a1b1a432,841f656,cf8559cd,176df936,31f7a7bd,b013b89d,5045f248,982b5b4e,e0b4d791,21b6e638,84a563f1,a08af43d) +,S(80b3ad3d,4b371eca,c903c879,53386884,3bd31843,4e9c925a,5a5a819c,ff7ff340,fb1ca8bd,aac96d84,c67ed7d3,b65fac69,108ae28,7347abfd,f20e4cdb,712af178) +,S(bad065ab,2901f727,d76c6c36,48ef7aac,2a87d49,4d727422,73cc2e4,68616af2,ae9d7902,16b5eead,4d9d69a2,eaba2972,fa925a34,13f15d92,236329c7,470a37ed) +,S(d1f046d9,d700ca6,995beb99,cc8781e5,a2fb758f,7e81bca9,bce435f9,129b8fe7,274ede5d,7eb815af,34716718,84433143,3090fc0a,46575017,fca345a0,6111a4df) +,S(db535f55,e3dca80a,58dea798,d29aa0f6,99df1761,473a7ea1,751a047a,33f0a22f,e7d8015d,931a3bca,1193df83,7e7a8f10,e61b86d6,477a37cc,ed3528ad,5b53ff6b) +,S(da1dba06,a56ef0fa,f98b1a5d,b9a4f184,8635b7e5,164cdd50,82ae691c,ca42a80,86a8383c,a69531bc,ae806621,5cb4160,8807e265,b2179508,d928e312,a210c9ff) +,S(267c26b4,d980066c,7dd4f29f,f7b54277,3b176b77,9b3588ae,ff5ec28a,9aa42e7,3390c03f,f4e5eb25,5d230053,1d93daa9,d584658c,7fa30341,42ff20b5,827161d) +,S(8024af52,4e6ff955,70c7915,208491aa,5561fd29,fee5c27d,4f3483ff,c1cbea0a,c9de78d0,498f726b,8078fc0,609e76ff,df7a8a71,7345ca16,dff1d7cb,b2dd86b0) +,S(11ff6a68,c7beb420,7f0d7dd,371cf000,dc3dc195,406882d2,77953445,6208f661,b53ddc25,254781b5,1e7cac25,c1f7e3bb,916b75ba,97a7fdbd,658c1bc0,a7b4092c) +,S(562a1083,f9a68203,39a32d7a,65a9982a,b70d6596,b00751f6,aa88c27f,36e3c929,a380ec7f,908808b,950e7d25,510ad741,66ec2061,50923364,55744acb,b1e05b51) +,S(4efe70fd,327c0d69,3b6a7598,7ef64573,e097fa5,4cf077af,68d082e2,d341c413,10d47b9b,92e0b62d,d9a8befc,3ed1db10,b110a346,8cec98a,4a1abef2,c8ce3dc7) +,S(4d64bf0c,d7f128b0,bde8576c,91e01c27,354abd98,2cd3034f,f9ac09c0,23a51f20,159e741a,f57fdffa,de7bf38e,14dbc2e7,da3c524f,3d4c8d6e,b9dc32e5,e8a5e28f) +,S(9a41634a,ff3278d6,b3ef0064,ceecefa3,466de2ac,372ae43b,c48f30b3,a187bf,eefee0f,aebb77cf,8447a193,6564498a,f409e530,f4053c3c,ad27eaa0,6aeae2a) +,S(e1804fb,9a6bde08,8efec2d,2e5c6774,2c85cffc,e78254cf,4fc4ded2,9102418b,e9cab1eb,9c1664b9,c2fe81c9,b3a665ae,447e93c3,183cde7b,fa56ab34,7efcdda7) +,S(a603744,c0247b0a,f821705a,dff44d2c,717611f0,25f9fb41,1eb62f1b,64593212,820fd32b,706a7638,4335c0a2,f8713b9a,6dcdb015,a96b9d9c,e5c19bb8,ca603b61) +,S(a6f1d9b6,895b1298,34972a2f,ec96064d,a1108ab3,aae276cb,66a620a0,495f20b0,9a95dcd0,df038394,63ff5ea8,18679c3f,7f55d7ef,83a06880,29c9d543,6dc8273c) +,S(4ac51432,7822b63,e00f920a,b6e22142,f09f30f3,bd74c418,93baf126,cdac5c48,abf5d148,77e94a46,45fda161,f9455bbe,7ff037c7,720f6a6a,d7e4bc31,a0f43885) +,S(5a2cf55b,a16eeae5,8cec588e,1b339422,48af6e37,33604475,2dabbf7a,f7fb7a9b,8f27be2d,32ff72cd,4fc5aeca,5de55a21,a45f8c1f,7163dc4f,e0c00040,e69322e2) +,S(e16f23e8,ef48c1f6,4012b27,f6ffc4ea,a876053e,30cb388f,232b3d8,db011c99,195ffd52,b0afa5c0,da95bb97,7bda614e,47ffe3ea,13429799,e8c390f,b8c56000) +,S(65367cd7,ac109f71,50de4263,cdd86e92,28923a3a,ff96945a,c1bbd163,8524fb84,cf0b9ba,fbe67dd6,4d09b170,beb4fe8c,a7687c95,68086b6,8a7834a5,1747d731) +,S(10a8840b,39443b8d,7a44228b,d6dd6647,89da489c,8e954d54,a5cef366,6bd6eac2,7ff6f76e,e4aa58de,185163ac,ef7fad13,d8cc4055,c4e10a60,7987e034,c661eff2) +,S(3fefe8a6,c01b8202,6bb9d038,c577f16,7b1db5ea,91ae80e1,528b1327,5245d6a0,a96df5a9,37e6144a,454a0b54,39d68eff,a959757a,7c9fe350,ecd58c3a,3b637b5e) +,S(ef93d77c,e4162e9,6bffb908,f5d654d0,58595fd5,d6184c62,6c3ada21,c4052b61,40088b85,c18d97c7,f59a23a8,645d169d,e535261f,6cd7466b,953fbf40,f3cd0bf5) +,S(f1789f5e,b0fa903d,485edbd8,4971b7c4,9224a2cd,519bdd40,d627bd82,b0ca4872,4c845cb6,5456457e,a2f570f4,77b1f4a1,9e36a905,adaaa8d0,5830161f,a71a9da8) +,S(d0bb1788,ebc75ed0,20c0d15b,ad4e41f0,64193890,8a8704bf,ff3cc4d4,cc9b3274,3a120ca8,95a327f4,8e687796,30666649,43ac5524,44df62fd,8f7abbff,222a7641) +,S(164ac10c,f7807ae6,4d6aab31,72110d42,2f05e461,aeb9805a,3facdf7c,dce8963a,8dcf43d4,40f1dd90,bb1d6f85,849f98fc,9b6dca26,301f3209,3f9dc59b,ea549b69) +,S(f122d965,a8e40e3a,b857dcf8,92949f0c,cd3aca29,739a2e40,9876c782,941fbe5f,4d994b9d,d9e68983,78a192d0,bb670bec,71504372,d218e257,f50d0268,da447371) +,S(ac971547,75e5a92a,1aee2cdb,f5781f09,b975fc21,816e7829,662143a4,e48870a8,249fb603,795b1742,96767945,278dc97a,53fff7dc,f8bbfede,f8943c71,43c9aa71) +,S(959ec91e,dfd5fdcc,90d3da81,1e9c870e,fb0add6e,144b3fbd,d48c485d,2d330906,1e5ec128,b707c761,b61b5ebc,653585fe,29f48975,2a4724b9,aed90a22,6257ebdc) +,S(590795d8,ed7d8232,457b2d15,76de09f0,3c6abd8d,23b5e8b7,c59ba93e,1e982859,5edd2a86,1a3c8841,60e16490,a47ab42d,a09cb123,a9d803c0,6835292d,34576708) +,S(c5372b98,7439245b,eda17853,5cad1507,48fdb4b5,bf1ba555,89714dce,a3e0ba9e,f82d0b61,7159db8c,35536a5,46b69c4c,767afc43,8b64b5a0,22e899b1,60bca987) +,S(f3d959fc,ae39cbd3,ec8d2016,630f26c4,10161128,7dcbdee1,6534f96c,e35bd38a,e1e55c1f,87602783,2ffe2f97,fe460147,da586a03,ed0ad6ce,1603cf17,ac9b3562) +,S(922bc76e,be3ce378,2be3d960,489b064d,3a28043,f8a92cf8,dd5cec2e,537fad9e,b3199f57,2508efda,230b9ea7,51a95218,116fbf5b,d1032b54,352c0995,f5122109) +,S(45c7dd40,7a6d2c95,79ab1df0,8070acca,2c461d88,dbafca12,99a38734,d9f0360d,3a17855b,5f2469ed,6c3c4e04,4dd96f4a,d076eba6,a60e8e73,2644d25e,67e85ac4) +,S(6422d998,dfd4b00a,3dd89a5b,74411c14,f1af5c9e,1f090d5b,33ee2d26,b959bacb,e2358f34,491218a1,93d8cea2,276f5b3f,376f597c,703bba09,cdbf7d89,37a3bb7) +,S(8e048214,33196d15,1a4640f1,92bf6c1e,95b1a3cf,5365a6f,535cc82c,c4b0535c,d6d2d73a,1f652c55,9f282ee5,35f55aa0,20012195,8ba94e65,b638ef50,e97c34ce) +,S(5a2b3da8,b5eb2f0f,8a25a9e1,7124613e,b8a7080f,15d42c4,a1c0709f,e64a79bb,607c791d,eb54aafe,6dc95f8e,6ef9d8a5,a6435a82,6b824cd4,4227f188,bf86e6b7) +,S(143587a3,5cf614a6,750f3d91,220abf49,c5296e00,3cdde13e,1a0d2d5c,f6cd7ccf,49bc85fa,de6cc58b,49a1af49,46c340b,15f14c7c,2e83201b,6622f2df,86a653d7) +,S(f0080c42,8737c74c,c3b2c4bc,8c9d8505,ba357b7c,ff25f1a3,ac81be19,dca93193,bdd0119f,57bf674a,7d7cfe32,7027d1c,1c6a5ad9,2ca24f0b,5cf25c39,4a3951f1) +,S(877ae373,e547fef4,36cb26b6,85d7c426,3e162dae,ac0749ce,f7748d50,5d130034,1f0af495,b750341a,ed956b79,8f268ca3,e1275e15,32e5ca8e,6f9f6df0,d4dfcf5f) +,S(a418df6f,635ca18,8c96a071,469a272f,e55f0706,b73aca0,d1df2ab9,e8e619d4,2b06cdbb,5bbb24e0,fe499a6d,aa5b5918,2e755818,694b8856,525ffcd6,2f754e3) +,S(4c213d74,bb6fbad2,25edce4f,44c7b0b4,114dc209,4eb52967,1d907637,a2aedeab,741bef9f,ccc65c15,8752c7d5,48afa9cd,402fb5fb,206c5be0,e480df73,9f970b51) +,S(a37906fd,3f94e51b,1a94073a,4890011b,2cf93bc3,bb4cdbff,ecb7056,20deb13a,60a3b0b1,c14a9b1d,184d5e55,23314b70,8a8a16dd,894aa332,f01a2d67,30e6030a) +,S(2c677eed,639eaf51,64b8ae3d,26bb4652,d6d6528e,5b85225c,5e84ec4d,4de72301,df0e4c06,d3bb7cba,17f89240,cac07c24,5fe63931,3b2d278e,aca1b9ff,7ee832a) +,S(b551f814,eaf86be5,335fc3c,5b01c001,684473b0,cfac8939,5d61df4b,7d7e77b4,a979cb35,469715f8,3033f923,b4ae1e7f,8818b6e6,11a4cbb1,bd399ce3,646664b) +,S(98d5c718,5c8c04ea,f1f61ad7,40df0c71,2cd47ba8,74141984,fba82146,ddf45c39,aca52591,5c737ec2,eaf88f5,f1ecea89,9d4a8e2c,428f5bc5,b36d2ba4,a0050804) +,S(5148e2f7,260fb652,68c10485,4fbccc62,ed1e1386,ef8fbbc9,a0b23e2b,94cefc7c,65b4dd2d,35dea498,5ba4a8cc,b1a08dbb,9e9b2716,7ca96e1,29672452,a7ca2500) +,S(12c699c1,8c9d6410,b8a40ccc,bbeb4514,a08a227c,982df1da,f91e9131,8e0e753c,7d953c42,89b55724,3469a197,50516e88,4889e968,4ed28e1,20b022d8,932fcc99) +,S(4d0d3ff8,a7734011,b36ecac3,7ebb2312,134e4479,5039ac63,9dc69d48,120a8d20,edff17a0,e0984c60,3c4f1026,197f2173,960b3d29,f0b0ea57,3979605b,144ec64) +,S(ce90b70b,3e7b7a71,a91b0985,a668336f,ccb069d9,81a9fbe4,48125061,5536e42d,8cde9d56,12e0ead7,524640ca,2875606c,d3af73e6,457f1e67,2e63a478,5569000) +,S(28c79327,6bb1879d,99fbf985,1d2fa908,d197f5b1,c83be97e,360c4931,563b2d8,c8944e40,e2f3b546,5b6b10f6,ae1cfbe3,bc0f3e3e,33d91085,7c18496c,ec643868) +,S(6e2dad06,2413cf01,804c2b6b,55b707f3,864d4c80,87d30665,9a1fea53,e7442443,9da67c64,e05d6914,30a1fba7,39c0fe36,497bc028,43441f7d,c4c035df,129430e0) +,S(bef94ac8,3763946,c434d03d,fdf437f9,19f26188,923ee54f,8715b724,8c4d20fe,d2324534,e5fc1dc6,6fb83032,e95e1406,38648473,ce7e38aa,ee7ced54,31e25db) +,S(53548c57,f1b45c1d,ca166a24,c0f2653c,9b7d8664,3d45d125,918cedaf,818e433d,cc138946,f0c207f9,c01307e2,130b13a9,c36aec5c,3cad640d,b6a93804,f10c3b44) +,S(7fd4f784,7f25c901,4e8b0e09,b8b723ed,2aee71ab,fd47988f,90f6ff40,4b5867e,ffc3debc,901f12ad,96605805,a6e402db,58eec18d,375fa976,41b5d226,74a1bd9d) +,S(444a8a7e,499789b4,49c62424,cd9046ef,d4251bf6,9cb883cc,d3dc79fa,5397dd9d,4cc5f03b,3356b020,ae8c775,708d56c2,abbe8e41,bf393f82,8f7c45e4,dbb30282) +,S(ff05c877,84d8625d,20694bd0,a4201c7a,4af8c67,8e62abc1,acb0cea8,5726bd8b,7cf0e8ce,6ac26253,cfa5a0b5,cbe984ee,a55f6aa0,90bd12d9,6ec2de7,a996eeb3) +,S(80fdf7ae,6aa31b6b,ce894ea0,83fd9274,e29f4704,88f0a7c6,79b8339a,de7e4ab2,77d7317b,16962745,6344a8b4,bd4575c6,49e066bf,bde58fe,3f46e60a,3952fb75) +,S(ac38a4c8,10a307ca,d5020a74,f0d772d7,ef20227b,7eb49589,6854aead,41879214,f49c4cbb,3c675858,416f77ca,92e229ec,d75ecfab,3415d213,c7cd2cea,1f5016ac) +,S(b3736edd,f1e10262,fd562f40,8f502f19,3a90a435,de9ab6fe,a2691155,a5f75514,818cefaf,f190353c,f01cb068,2a15ae0c,eafa2de,657ee751,4e483057,ad5a78c8) +,S(66d67e12,d100c116,b57f6d5e,ac6a85ab,e698d4f5,cfb6722f,12738b33,310dc295,9cd4fa1f,3a0c9a54,d3608ea7,9bbd7ea,685faec6,32d7318f,d4e25fea,14a05dd3) +,S(b856d75f,756ae484,daaeb651,46ecdf0a,9fa10c6b,a7b9b33e,b8747135,3eb59043,5c8542b1,2f249649,4b3a177d,8df246f2,6566da1c,727284c4,b041a7db,89cb0a38) +,S(683bfd7,3202393,458142cd,661a6543,c736b15f,b8595548,afc52951,f9c47d27,90f52a40,f5dbdf26,51429f84,ac68cd96,420387a2,8d94d746,b4163411,762de166) +,S(2feaa1f0,811e1e65,13895934,533a0941,41ee1ca7,f8975896,3d00f8a9,1b2923c2,9dd80976,b884d401,5d7701c3,5e6ee1ef,690d1820,7d06e02b,7e3a10f,e8499c1a) +,S(ce652937,da9ebaf3,a9765e9b,144d20cd,847070aa,1a968097,80e07b58,2287cda4,c1c46ffb,5f152dbe,5a9db378,29e7ae84,454e1736,eb7a1b68,1b321f3,41ba572) +,S(9a695bd9,170163fb,ab3f9738,a750bdc7,556087b6,b04dc8a8,4fd5fe68,78976211,f40ba1f3,75accd85,9a42b133,294868d9,dce262d,64d6bc27,d0c9cf12,3eaeda70) +,S(e5baaf68,bd3083ec,bfabd6d0,9e4da4c3,5908b0a1,75578ec7,18cd3223,bd34ba44,ab8651f0,365cc3c1,50476d0e,da3e86a4,5feb7f46,a9afbdbc,e4defb99,ba27fb0) +,S(2c26cea2,b507fe77,d8f3530b,b7ee1fdb,dd0c4dc8,bf63d04c,e06376d8,ffe59cc7,b344e3af,54d03eb9,b0b67151,b5845297,c30a1cc2,aefc004a,5000b69c,e630d62e) +,S(7c67539f,52af2e61,88deadaf,a07e2f6,4d53339c,7fca7a3,c2a149f5,c8bbd0e4,3f9872fd,c21c9136,4ecc97e,c6642ec7,df7a2cbe,61b63038,96ee73e9,309067c9) +,S(4b5ddd2d,ec8b0bc9,3b6e1d17,e1da71c8,3345614f,74201aab,8f9adc1c,aa249574,cfada2dc,aa3eefdb,434d18b3,d2a85a6b,6e16e755,6e55fd69,5dfb36a8,aac5460b) +,S(d775c2f2,ccfc0835,86a66edb,873a84f8,f9bb6680,2eb0be59,216bc35b,88d80e4b,c8a5d9b7,988a2231,cf6aa0b5,19640a86,ff56ca57,91135ea7,65bb3a4c,fc53ddbb) +,S(71a3cf09,78810f9d,fb01d984,43dc3da4,b005b07b,36ad4dc,d3c803a9,bcd9bb4a,8aab8e21,7db0301b,9640c5b3,9617ad55,bd4a3c4d,8989df5a,1ad31040,bcaaa55) +,S(bc71a054,92b696e6,200596ae,3d778ef6,a82f7d05,825c0d3f,ddee8bb1,991f53b7,15789125,9785b8d8,b1374460,630a908,d1125536,e400fb52,b07aaf61,729a2a15) +,S(9d220919,ee62bfdc,fb81ec81,a0f60e58,e8d94a0b,c6b79f7e,6f891c64,fc847abc,8149379b,1a073c2b,8dffe886,59f4e94c,75f3a7c8,a7bfaa16,e530bc7e,6ed0c675) +,S(8369766a,d30bbd19,a330c6c9,1e3ad594,d25bff1b,4e3696e5,c6c8c33e,eff33425,a27f7682,b3f4575c,858970d9,c21f7daf,8ed5d28d,8617c8a4,e4b958b9,72e79e4a) +,S(4e277875,e4aeaab,1a8d36b5,487fb427,e91f51ad,1cd68ab4,57db2e8b,20542451,9faeff65,5bbc4b81,f96bf1d2,a152a546,d138fd0d,a8f8523e,7635020e,a26566e0) +,S(27f907b5,1b9dfff3,e68d202,72605a91,825046c1,b21336b1,8b91023,39a0d2fa,115225c3,6cb13600,fb84bf3d,dd5c49d8,105f459,ffc4068a,cbfd7b0c,52d4a15) +,S(6d9feb20,650674c4,437ff42d,41f70f16,ef0900a8,f3cd6818,64b42eed,56b1fab3,82cd97ec,d82b3c1c,2e55f857,653afa3b,5f7f7b00,39aa2444,f60574d2,fa02065) +,S(8981d2b4,3360669d,361c3b36,3284e729,ecb9cdbd,3bd17558,857f2cf7,8187bfac,1b9aeb27,d5a45d1d,8791bf73,614ecd5c,216b263,6c27645a,3e86d781,70d48498) +,S(84a67518,e47ad1fe,25540d55,77e92ce2,81691685,6d3c10ce,9c5985a7,72e1d72e,d3cb93af,85072ea2,e6c11777,dc4b73fc,16ca04e2,699ef356,dc8a5341,c5631658) +,S(d3e66756,72a6cf77,50c111e2,e65a6674,7e666cdd,b9dfb418,d50c28d1,aca8c683,7776ecaa,20e5c6c3,ab5aca5d,8233f83f,4e2e815b,dd1063f0,7359fae3,a6556dd9) +,S(ede97def,71d45688,804e76b5,ee52563e,522a7684,a68efc4a,f7b2db38,65b87bba,92e6d20f,c9c1276,60a279f9,5758a80e,85bafb8f,b77eb513,7587b692,fdae702f) +,S(3359e142,e000484e,cf7db3ae,2312e703,6ff84f84,247ac6ed,25a0b9c,eae8c871,67b039f2,3c845fa1,f38c98bf,739dbf28,d00ada09,36e4377f,87166f9d,d21cdf66) +,S(e0d0a972,c0502fd,2654a3dc,40914a55,96f675ae,cf0d958f,8fd62c7e,122b44a1,cbeb1bc,34575a7e,bbfd916e,dda11903,3ee29e2d,1b11e171,8db7bd47,576b0312) +,S(50b89367,5df77704,64031ac7,a1f5d5ed,4f332019,d8da2605,9397df84,21a4c987,c4765d81,63ec9eb,a089c3f2,56d6ff0c,45c38253,3d9ed204,cb04f335,d292f293) +,S(5dc62d8e,66775ff6,f21e84e9,9f8e8123,7f80cbbe,41ce9113,91ce432d,cd6d446a,4b456b7d,e27045a5,76e1cdab,d163fd5c,b020cabf,125f5de9,9ad6eb14,1773a9c2) +,S(8ba1778f,c7921845,d2632e18,790710c0,4e56ba7e,22efdb03,fdcd4f96,22c10971,1f31fcff,a8359658,b39d7d43,59707268,48ffebe8,8f418c53,f48c7af6,3e3e3854) +,S(a3a14614,7d1ea7bb,e6bad055,fbf9810a,999a102b,ba8b694b,e7ada06c,8db9fc7,c9827731,d4321284,23ccd6eb,3531ffcc,b3bdb87b,1a727d57,a697eac3,886ac294) +,S(9620a847,bd2034aa,c81671c4,436682c5,f6ce1af6,4d8df286,21ad1c2f,e0af78f5,e1cc6d08,a7e3dffe,cb47e32f,4156bcdd,6168a205,e8959f0d,99e1555,4d826e1c) +,S(a40d86a0,aa7d6a79,3f0b6a52,c48d8fff,95b2c57c,584996ee,bc9d98e2,796016b,ec54d4e2,d453466d,ad94c15c,b25617d8,62911b4,45f44873,96ecd950,a351ea2) +,S(71ef35a6,f60f268a,57573b97,9745986f,7e5f40e9,ba64efbd,5ed90779,b3484c80,eabffa1e,9ff3590a,c577df7f,6f5a6ad7,2f3693c,be475669,8751637b,4f8a1ba3) +,S(bbd1a408,c742a3b2,e49ffa52,c5f70958,5308abbe,f103e674,86fc76d7,a4f68de2,4941cbec,9d07e13e,1b0fbe96,c7328459,ee6e1e08,50a079a,2ac0b61b,5d246124) +,S(169ebf38,92116df5,3e09c92f,f2c89b5f,805d60ff,9584d2ab,433f1f9e,84ba9009,914f5516,e7667ee1,581b5ade,bf1de48e,c997d149,1e932a08,34503599,7c6228d) +,S(8f157abc,4c5ec7fb,eac11545,890d8e45,d71c8d9e,4c4e0c3,9777502c,f8666acc,d41576ba,1e78a9fb,9899883e,602bca3e,14dc709,8982e1bc,63518138,3ff25908) +,S(8cd338d5,694b26dc,4ebcd8,39a006da,84f71f93,94fb8100,91ed8cb5,b4ec9a8d,40318c10,dd88d9b9,c080eccf,45464ab3,3fd9d34,c2027d95,2a6ecd21,d0002578) +,S(20e47e2f,7ba5ba2a,d36171a,f4ad760f,a64748c2,94892e28,cbf0ee3e,293272f2,b96ad220,56b89821,5c052089,789e4267,162ddaf8,76c720a7,71b15254,67be00bd) +,S(582ed8a5,a0d38f9c,db6942d1,1f411dee,f9c31ec6,ffbf1579,3f3cb5e6,5f2bb880,14928c0e,4f9d9d3d,ec4a8db5,64baf4be,948ea892,34a6e352,a4cf4796,3ce8486) +,S(f4a6f59a,6e76c11d,3f7daf30,b8c046eb,b0bcab8b,6d1f5e7b,877eb1b4,601896d6,2d39c6e9,e5d84156,559a05d4,a9b148e5,ccde4641,e4bd9abe,edc8a648,b070f0c5) +,S(2a820c60,f71cf5c,76e66bf0,15623f06,fc8564b8,c763a52d,2c329af7,30957b24,b38c0703,d7429599,e6c9a1d7,250078d2,36f77f7d,b9956d37,fd92646,77ff3ca2) +,S(8c2d9c4e,9fccbf64,871d4802,6077a3a9,33634d3b,c1d7f872,6231848a,6e2799e,ad50136c,ae43bb6d,8c49c534,e80985a7,cf032d77,604c2db8,d5954858,a9351a7d) +,S(b18e9053,744b3ed,d0b991e,23927593,db00d25f,adfc4490,6eb0d19b,74061ba9,90f5ca44,c829b2c6,771edd73,998034d3,43a8aab8,442302a7,2ffea92,b33877b6) +,S(cf1d157,b03d435b,905d2f58,cc53bfa1,d124827c,f4ac4109,33078dcd,1ce835be,ee37a9a1,5547c7d6,a0f03cf2,1451cd64,3ea656df,61eeb1ab,1196d959,ca71b459) +,S(8d8b9d8a,d91a840f,b2e1ac36,a6f4bce5,92fc13d1,f22f84c1,562d63f7,e54a6007,9528be43,93ca8f2d,dae0ec3b,439abded,ee9227e1,47ce6ee1,ce61b46b,b842dba) +,S(604b5544,bbc5b0d5,716c936f,b0d9a4cb,7ae04a8e,1d5a506f,2561b463,fc87fc9d,33fe2f9c,4fb9a6e7,41c1e5fe,7d3d9edb,ee3cde6f,106a1d8a,3e319254,a16ac8eb) +,S(3e7ed414,1058ee44,6057aab7,49e14ca2,cbd16d64,7959fe53,9ec0916,fbaed8f6,fc15b241,86dec6e0,c91aa697,10a015d1,f66bd361,82f18648,1ba24568,952e79fc) +,S(d0ae7435,86c17b8a,c9524243,16cf42c1,26e46f69,4c69cf26,736d0527,7943f326,bfa02de8,b983588a,d4398865,abf6b69c,fbaca03e,8bb5f04b,1971ce1b,f74e0757) +,S(ef5c05ce,d4f343e3,7e6ce2f9,45380ade,3627bc65,9de0597f,5f851eb9,88be1441,d9267c1b,379f19e,3bd0e40b,74ae8e21,b681e7c2,ad49f635,d60c619,74103281) +,S(176b8feb,d7998ad9,7c73015c,3b09d9af,d7cf4265,c7bf38ca,8dc64864,5c8f49ae,b4bcbe4c,8267c9a3,69cda190,5676c781,7f989f5e,a014f4c5,fc821bf3,8522f1b4) +,S(88f683db,cffc14e,ebb58d69,fb6da62f,b20771dd,3542fa00,97b3a766,bd16c3dd,bbef3de,812103c5,266797ca,252b74e,cf80096,b2972219,f52ff718,1d1cb601) +,S(a65d438f,1247ec44,fd8c4121,c3d67891,8488b082,31fb8854,dd1fe238,f637abaa,5f65c84e,551e433f,dfdcf3c0,b4c771af,4bb50095,dd0fc986,d4d4a82f,9a3f36a3) +,S(bd6a7e51,c5028bb7,f7e08148,af1597c6,d5cddab9,2883d2f,f6a5a6a0,6398cc27,3f2280c4,247cdd22,e8b97979,b9a98e93,c1ed14d,a76eef66,2ddb70f6,7859d885) +,S(a672436c,2896a0dc,54b1814e,c5101451,58f7a3ac,74d36202,34411a09,909d274b,dee80293,468178d9,5baacea6,badade56,c81f3d9d,95642654,a7afcece,bfc2ec3f) +,S(ca0f55fe,d3a1d0cf,1adb0993,d7d2daa6,57891ba9,321104bc,8d9e0379,f03a24b0,dc01b8e4,63462dcd,91588baa,ebca8d8f,52016683,9671399d,b5843e6f,5a3cfa6f) +,S(610ff08d,9bff021e,544961c,cb2fe206,211843a7,ea0c74cc,b91f0b5c,4b6429a1,4be3b18a,ee965fa7,dabdaee6,8fcd3e12,d889bc36,35f160dd,9b0760be,d1d46b28) +,S(2d6f8215,a70aeccb,78cf006c,ddf8f0a2,6b695dc9,622dd622,38fcc638,a9ff42ae,3fc0964,e2a3c969,e61e4e5b,ed50f337,7a988715,246c50fd,3ff45487,95a3927b) +,S(8c0e99b4,868e39c5,b610b132,de1a09ae,99846826,a42fc4ea,70b0c630,88a1bbbb,32b8ca42,f0a240cb,2876a41d,e61b8c17,6ead992e,8785a95,c384c536,141cfe52) +,S(1528ba8f,9000ae75,e3062af7,74ef6d77,658c6d1d,65af87e4,dbac9eb0,8fc96ed7,a8dd278d,54df6bcd,1d4e6466,5753a8bd,2d39f0d5,c731a53a,5faeca64,513b5651) +,S(c1466ea5,d9256a7a,f13a040e,29515858,104394bf,ac5af7d2,fa09ef7a,6ff1d7a4,cab6fec6,fb36d879,f0684b54,6003df0,d8bab3b6,e1050a7b,c05457b2,75be5128) +,S(ce8bb093,e051089d,2a297a87,cf90c3f2,2ea946ba,87a76b56,c6f11812,d3e98cb4,a8dbba51,b90684fe,6dff556f,bd13baac,679cbcad,90b0e888,4c252e95,e03a0470) +,S(76f3a73,7c9d9e15,8d30ddd9,b092a94e,7c426763,a17a96ea,9186582e,6d6c86d,5b1ca07c,4f345e6c,778ad27e,c6ce3f05,b29c5302,7e40443,b202a022,e5d16c8a) +,S(f757dfc3,23390b21,3bb98872,5dd7d43b,2ed997fe,af7681ad,ee1572d5,a74017f,d0b4e4ea,67879726,700b63d9,88eb3957,74ec4f67,ca1a56be,461d244b,a5b83cf8) +,S(59bf6198,a2deaefd,f080ec6d,3dbe3c67,f27a5769,d91c65c,1492a87b,9ed5f5d0,bf5eb739,9011a282,3110834c,4d467855,6e02f2ed,601529b3,a2f3d70f,8410f8b2) +,S(b1d02f0a,c86d8757,48685790,918c15a,a7b0e85c,f12cc52d,53f8082e,549ba16,7925e03,99926b76,8a80878d,63f3852b,97297725,96d3d06b,85437fc2,571a19d0) +,S(cd27372f,41d8e07d,1bd2ec1,27c41842,7e5267ef,14f3a908,882e4e40,381d1905,cce36e03,661b9f33,ccf810f3,b411693a,c3329617,52098352,2acaf0c9,5dc77297) +,S(112644fc,26ca3599,3b68940f,5cbaab4f,ad2258cf,bbc81695,b01db49b,dd9d3ace,8685f790,7b5ab95f,2f7a49b3,bedf09d3,7ff1362b,3be9db90,4e74d049,15c0bf60) +,S(918df72a,99ce4a16,20e84575,935a24d9,92fb51ea,eb8498bb,3a606e2c,d97d3ce,88b339ec,9ebbff98,f1b8b0d3,c90794cd,bb6b7918,2749b065,602ccfeb,bb8a8461) +,S(9b8f18f2,65c4ffc8,9425b51,d48a770,436e6424,f34a1af2,a7dacfab,fcdcb83b,bfb95e8,6a34c1b9,2c2e8c78,fc628139,476c4af9,3f63d247,5e454a9a,d585ba55) +,S(ad02f2a,c396626a,42abe52a,1ea1d8e4,3821740a,d8b3340c,9b9c78ff,bc24ce30,fcc738e6,cf8a7872,ff827cfe,1b7bb7a7,ad8c97e5,e254db13,255c2d07,1a2885fb) +,S(359afbd,5e60dac9,8ee34f3,f5acf126,9b5c1928,8f54476c,84bfb9ad,da6d85a3,2e2aa1e7,9cd3fed6,71272155,3932ce17,44358636,a18230f6,b501579f,b3088955) +,S(5639aa3e,230f2f1c,e10c34a3,1cd6c78f,c3c15c0,2061f3ca,55e09116,68b279de,e0b6e95c,15de7f0b,3fa3bc26,3a9e83e2,e3a7d51b,462709c,8ed6c2ec,b511bef1) +,S(309cffcc,7b2f959d,85cef3d0,c25efc2b,693d3b6c,ad42ce4a,d8657652,d669ec44,3abb62f,d917b1be,79809520,5521d522,32f949a6,7999274b,cf7965b7,a950077d) +,S(51f3d5d2,dac1d7c0,5d8eab6,375c9130,534a026a,48abf3ca,ce91af6e,533b86b2,50b1e7f,4bdc48ed,9f3fbfe0,ca05bdda,34f9cf2a,ad04235a,ba998a8f,a3e99f74) +,S(8f563d18,33aa4100,4540e0c6,f501d327,4158b0f4,8b3e4e1f,a3fe25ee,29c2a244,4d4c71d8,5ea93371,57f5248d,a012898f,3d031d93,c1803589,2875928,67432193) +,S(36ca2909,d68fdab9,cbc45b39,fb096ac0,3c4853c0,ee19d108,ee7c72c8,a77177a9,64f511df,c8252960,85f3d095,31467a5e,69cbf363,30e12ed6,90516208,d24301b0) +,S(f628b8d5,1f3ffd7c,c201ca9c,2db26f0f,58dd918e,b4d70cf3,80734702,8ea306e0,bd6bce3,ea82e9b,2e8d6eb2,7f557def,b7c2d77d,e6329c1e,a2d360bb,d8adc2e8) +,S(fb7a6bf5,a82c0b,b2a6922c,9d0350d4,b44fa7d7,61002f25,86e41152,c0e67c1b,c12a1c37,f1c9c703,1f1406,efe8f3e9,8419fc33,23a1acfb,345ebc9,4a702da1) +,S(c2091919,5c3e2af2,df14080f,400c8c75,bf8ec01d,a5a5b033,75391fbc,fe78d092,b307b56f,cbebdab3,ef87b1fa,3b66c327,7aec3818,e880de6c,3826b632,f1adeb9) +,S(7627df89,3d1727fa,a06d7c4c,93774a48,73c3bef8,d19bc03e,8d1bfe28,bd3192d1,35d2676c,36f455f7,aa29a865,f0776c52,1326dacf,f6d366f4,bcf726b1,b68451e1) +,S(26666518,7c9f33a9,6d25df65,8dbfe035,a3df6f73,cb059639,ed54b296,2c62b9,bb30bbc7,d34a5e26,a51fe757,8356a876,c4e7fcae,f4a977ba,468025a4,c686630d) +,S(3bda9185,fa9802e7,7dc6a02e,8f2a6f71,ef8b125f,735837bb,c7abf3a4,c62ac683,202edf2b,c11d1784,d7875a76,a0ae3876,22b3475c,bb0ca118,9362e54c,a05b85) +,S(2f90bcde,4486b64d,81313c71,48570d22,3be1978b,7f524097,bc033d6b,983a5c4d,63864e50,2028d475,365b2e30,cca99dd,f4aa759e,cf579705,270fda71,bc384f89) +,S(8893f5d4,e9b00e6f,dc992e65,4c9fcd71,7083edc2,6c71dcb6,562bcfbc,c8becda7,1faf3055,8e631074,fbf566a1,fe0c6996,a80fa29d,6cdb8313,fe313b4,b238ab50) +,S(acfc4ae6,86be5de3,eda4fac5,4da73510,f482fc25,309ce37d,855c3495,8555abba,387f4597,d1878a6a,d37a5b99,8ec291fd,76423f7c,f9bd037c,b9071685,2ac52d87) +,S(2ac4d090,a4c5e988,2f3a892d,d28a5229,d5fe35e7,d74660d9,5422a55e,2017a469,6058f516,2aa3ec45,47a79f2d,7d8e6869,927d172b,f75a1914,a3bc2571,df086c09) +,S(137ed3f,fc13c572,e5bc235c,d13c7e62,c9b1a3ec,250c024e,9c9f584e,7ebadef6,c1e95cc,3a464f51,b43ff02,3c8758f1,319e7c2,f37acbf5,4fb8536a,8ec6fdba) +,S(28a037a,72148a3d,2c89f606,81152b94,6cfb16f7,58f0a002,cfe4d857,ef3ecfe4,b2f4b650,135cde9b,8d3788cf,5c6e7a3a,ec595124,fa903aa8,a1bb3984,fb973d10) +,S(303ecd51,8fd433fb,ce9d426e,8761a76f,78ad6d5b,5f34c0ae,3bbaddcf,1a7a9eeb,6a7fca44,3b73b19e,967a5945,a275cb1a,cbd8dc3e,89d85385,ea956339,99abb602) +,S(cf63042e,5680f71c,2641defd,9d6569ba,c69cf079,f8b3140a,50923381,51533202,39f3376d,fb17fdc5,719a2052,5e1aa428,176643a,f50dc9b6,b8ff3401,eceb4ee8) +,S(cfafbbef,b4a49fb6,96923b6f,2e56c493,34a229a8,e2dd968c,44f485aa,1b1fe4b7,dc0ed34d,4a9c17e1,ddfafbc7,1d76f71,f3950698,18faa16,b5d25c6,c69f9007) +,S(ec0e3de1,fd527ea,6a493ff7,b3c6aa40,4a7ffd76,9a08953d,785d2f31,390d363e,94bddbce,300234c1,82f3c6a,717f53cd,723129c0,ff353528,fc5c285f,8e7a35dd) +,S(f07d3cd1,914422cf,d4b9c0c3,501916bd,13e9cd84,eeb02f7f,84be2a40,4b2bcde0,cf0c96fa,cb393218,37c48de5,16d1f705,dfe91206,8ae2d810,3aa1f77b,39637320) +,S(4a4254b6,6f2e204e,a3264ac0,a00c7a63,8a6fab7d,e67643e2,8217099f,3648db10,b5510e29,be93fc35,efbef989,15f7df95,b187ab08,bacb157a,c26ab2bc,2ee5023a) +,S(56f3bcf,b38eaf1d,35e62582,9f671945,910285b0,3805c1d9,b5d813e8,e87774a8,a9b964e7,9e6b7f9a,9abf3e5c,a147f773,8a1e8270,8677e6ba,c57a7a75,d1ed9dc6) +,S(f89d8f4e,7d32efc,c2d95bf,feaa4c9d,af6b9886,51fe7561,ace561be,6b081295,ca632f11,56a33867,63a65691,17186994,75e48f51,48d770d1,449ec719,8dbacc69) +,S(5c3791a0,d3e716eb,50ae4a07,51f0e92b,2890b933,c6d9aaf9,758e5205,27c5530b,44ef13c6,2de52d11,179e30da,e913493a,c4ed861c,336ae1c3,ca1f8bab,a7b34616) +,S(2748765a,e6baa4ae,62cd7156,16ceeadb,8ab94ef0,d3a3e331,15fa0132,aba38d27,71d4d19d,de63770d,60905bbe,6c7ae92a,f36b333,a93b3359,cd4f1f2,77f69e48) +,S(964f1fa2,f8ecd778,2ce4ee1,87ee3e78,d2c41a0,45a95453,22e363be,bb27e254,c744bbca,de64a883,e9481a5f,a2cce621,5137ae00,3b9822e6,77556610,d4138a2e) +,S(8bf60775,8709c9fa,8503594f,e6c379ff,ee758a07,4f7d2754,58985e25,79b8ca3b,3e638992,b3fbdd72,ff51cfb8,fb118d0e,ccc193ee,718a7715,a5ae6188,87dd51a4) +,S(fa107123,9189239c,2bfc5a95,ddbee798,fbff70d8,ee0d5f5,a10238dd,2e06612,a60cd5e,1a4eb0a5,99133ea9,71d5ec1e,315a6be1,2d773936,c624c468,f968e7f1) +,S(5b48c6d0,9f6f97fe,c03d145e,f797cb8b,3fe2503c,a8944593,83c34e51,44975588,44d86689,352611bc,c1291762,d965f136,173d6c45,28077d83,c6410a3a,906e30a0) +,S(80e153e8,23aa7e3f,2865d1ea,1e5e88c8,5d4e854d,54bca5b1,ae8f1bca,eeb94fd0,edd3fe29,e435c11b,13a92d8,ef4f6413,c888a12c,71823f7,3ed7acba,a06b9728) +,S(16e225d9,77bf7526,c2590dd1,54c6e29b,cd25de9f,7b1fe3d,ae7ed6d0,79ccf2c4,e0702d23,b9b57554,6d2db82a,fcdc22b7,40088c52,e0fa274d,d85188ac,9710768) +,S(a3440a09,15a16c74,8221b65e,7825ebcb,bb064aa2,de3593ce,7a691efc,d9456938,ff7c7aa0,3a582a8f,5641323a,7f437a67,26fa5d3d,e7c3e26b,be970904,d4dbf40c) +,S(8154334c,d1164468,2320401,f2d59385,8d607203,93eb37c8,a030e9e,cdaa2b5f,bba4094e,5f97e4e7,b0f0676f,4a091488,17126ad8,7d573d54,150139c6,5b3d5142) +,S(c91348ca,27b5baca,3a092b25,74e09976,fe7f2361,3e1b5efa,329e6a5b,7d4d93c7,ce241d0d,e9d49a2c,5060e62d,c01bfb59,e7c37295,4095f639,9d61e73c,5976b44a) +,S(9408b5a8,79fead4c,67635e99,59ca9649,cf362940,737e6436,3ba2590d,7e6e8a88,e10b410a,26c710c1,bf2858d5,21f46094,e02155d2,84b80fdf,cbf17645,7f994fc0) +,S(b851d158,eefe48b8,79e0a159,f8582aae,f80ddf90,d9021b92,e7d3e7e5,d6bdd2ce,290ae2e1,792421,c1cc53f0,69c7d580,60facfd8,e537693f,6abdaa2,c6d85469) +,S(9d320b4d,4a7c2007,65805387,5e536093,87e7a5b8,54da05eb,1b971e6a,e53d10fc,4f6acb7b,6a1f190d,6822acd0,ae783b0c,9b44be61,ca68306e,79603f47,25d7c456) +,S(6d779810,7b29ec65,4ff86799,d13a4d89,eaa49114,d00744c2,2f30a9e8,358ac7b5,8f7993cc,105c4f09,ba060a2a,ce265cc5,77b2a334,3ba3880,4b0a3e79,db823950) +,S(bdb2d2ce,77e14fb6,9a17d62d,b8056d28,680c9607,2c82772d,73c91da9,e57f6489,9c1ef71,d43c3b19,dcf8eced,ea6f5648,8a3bc00,3c2b0c1,84c9e42e,5baa590d) +,S(49a8ccff,1ab70a94,a4db4787,f73bb058,1f7897a8,d0a1adea,741ffda3,f055b3fa,f298d277,2049ebd1,ee2414ed,6e053ad5,15b41914,fd6de43d,8bd9282a,6c6ba426) +,S(ca3f7d6e,b466b7b0,56267992,d317a02d,3b3d5652,b51040d7,7f1a173a,769d2236,a26d6225,9dcf384e,f78e6f2b,f96a42c0,90e538ad,f6f1a1b7,126dbb12,8e145c37) +,S(b672ce14,f1c427d1,b478469c,b0d08b99,902e9cad,a66bc65b,c00ea630,737176e4,176c0979,15176,27a0f1af,f3c5a56c,83f4f550,b8c4bedd,b818bf76,68865efa) +,S(bdcbab57,d4ad621b,d6db6866,f43778aa,2c26dd78,8f2e968b,da3c913a,ee9c199b,79868872,9bb213fd,7dc75a33,8d6168da,1cee9f0e,e93c7c11,24055232,88df5603) +,S(f5f25f1e,382f7df5,74c64aa9,6c5f423e,d5beed0,82d80196,1cb384b2,55fbf9f5,ea388f0b,5ad84aae,58393a82,9a50a4d0,f54bc068,e12724c,98a9dffa,f2210221) +,S(d2a10464,f9f8ab9e,1ca6e280,b2747c43,60372049,85a2650a,a730b894,16ae09c3,d19719ed,8dc46533,28d8dca,f2c902eb,2c9ffaeb,ab3c1b45,4fdcf68b,229c5962) +,S(89255afe,e6724c4b,c5522105,8e5e6aa5,19058c3f,f3ff691c,c5f81a00,20410038,8d626dd,9560c934,11b52ffb,4fbab500,c833c3b4,671713e6,9147d8af,da3fd7bd) +,S(5e468c42,c5eceeee,2a67d73f,57819019,5165e3f2,6c93f94,beb12fbd,556e3952,af83e24a,467f97e2,ab8b6a8c,330e400f,ce1fdeb4,3a4ae1ed,c3866505,8cf240de) +,S(70c2bfac,9eca198b,f606850e,8f54ab03,552caf8e,9385036d,7fc85007,e99c4e2c,60322365,f5ffae57,8a8f9939,20cf7596,3b45d940,d2c4591,544feb6c,d6ea37b3) +,S(16143d3a,fe5f6b42,500f86d,7c79630f,bbb0db1a,64e901ee,ab641c0c,b9c2f318,7078e814,bdf81d7,81109561,d4d1cd37,9fd74924,4cad1e68,ecb8b247,d76a8a94) +,S(8ac33ead,a9341644,db25b034,60ff60ab,e1326eb7,73a0bed0,29f6e966,16b62bce,6d07756,6f0d18b4,bd055d0e,d99bda50,ea9e614f,da46005d,c6d9dbfd,18945cc6) +,S(476b98b8,9e7feafd,ef5f0116,6e0c8eb6,70cb3325,a10fbce7,71ea9e06,2566e22a,38dbf041,83252b86,7e138483,c012f220,fd98bd5d,b80fbf47,30c5d0e1,d6a91050) +,S(e4d262ef,f0de9c3b,d3302bcb,321adfa1,2e383a7f,19297058,a19c453e,ed497f11,a1f830fc,2fd6120c,8f2070c4,9ea49001,953d0c0e,7c02050b,fec7cf7b,ce2781d3) +,S(67bc850f,48f0be1b,f18c4f7c,b9f33e67,e2e09279,4196d987,1bec0fcf,f0b5cbf8,e2560470,334aa4b2,4693e927,1d2f20cd,b7e6fabc,92e0f355,526dceb8,5f52d32f) +,S(50dcb2c5,c0dd4942,2564be02,2ab274e,b543a6a5,a2712b8d,58f51e12,72ef2797,2cbc036f,b69c44c9,9c7854b4,9705dccb,8d2ea16a,2f77fca8,90d89f8d,4ab04ea0) +,S(6c9bc577,784948f4,1e8a57f1,bddf5665,f860804e,89912876,44ba7b76,8758bd6e,84a671f3,5998ac84,7329ca3d,1224901b,a0401915,c9280260,cd40ff44,ebb3ff20) +,S(5dac93c6,d27cdbb9,9f3ceb36,18c6ead1,28b44146,467390e7,a337c494,8382a868,86572065,1805082e,7434578a,a97704f8,8a91c2b8,e315ed8b,ac2a4bf8,342df508) +,S(207903c6,5e1c57e1,7a6e9484,d3073c0f,f6b2a40a,b46b996f,2ed2be7c,85780c86,4b568420,29564d4f,6c4fd310,73e17a3a,bbdcb83,115a6c14,854633c1,47f6a442) +,S(da025f63,9be593e9,3ab35113,2282830f,6ffbc94c,829111dd,29546221,2edc2f90,9b4acdeb,a315e576,f0edea9a,21acf5c8,714defa6,5ef4ae68,eb694383,916d2723) +,S(327faacd,1b489c8,2126ffa6,b87cf191,2a0f61f5,ee47eea5,6030a50f,b2823cb1,634ab42,6010009b,144c5ac2,903e5f8b,14c00c67,5fe177e9,6b7f9ecf,b8c33b9b) +,S(44cffbee,1619f462,a853478b,a9d1bfd8,6c9cab17,f5bf50cc,79a24558,7b7e8084,b08983db,62079e28,7eaf8c28,81079a45,76442a1c,fe35f64,563c714d,748e7da4) +,S(c5d945ca,13730ce2,c21ad679,734d1deb,beb19785,480f93a,43a2170e,6a6fe3a,a3aad11b,4d8b7140,f67f7287,8e4a9c1f,74102ffb,ca3ef04,46e7bf1b,ae3cc3fb) +,S(f4d8cf19,84dfe935,11b2694b,8f1db0ed,d4bf22f6,435359e6,77fa42e1,cec0de31,83d02d22,3aae1880,d7ad76bf,c7e3bfde,5b48a55d,4fb0ff02,c0ba5c2,e9a30845) +,S(13d721dc,8e7b0bc8,90c6380a,fd0f0ee7,a2dce0e1,e153ae70,7e50ae7c,1837c4cd,c620c1e3,e1575411,7eb9e823,70af7e4c,9309c412,d5f14d28,e976112e,88841116) +,S(e5f9efa6,66fc6728,207eb55d,94c1daf2,5164824c,e27b1783,92862e11,6265ce1a,500a9fe6,18302bb5,22ff9fbe,163d79b6,1f0f3cf,53e0956c,7712f23d,5c0d9975) +,S(73ee3cbd,a1ba137,65a7abb9,827b1b32,a48ea0e0,a43e9698,8da603c3,c319c9ec,d96832b4,4093689c,beb30bd5,a2e825f3,bbc909d0,20e18744,b0a5ec5a,1ab38f58) +,S(11b92fc5,94046bba,813285e7,122750a4,3e028501,f027a55d,f101d2cf,c5990d91,e08b24aa,e20fcfe0,40dcfcd0,80949b2c,23b324cd,1d957b63,9fe91716,a4315417) +,S(3043669c,22be0dc5,fb14442a,22a625d,b1bf4952,362f06a0,623ca1cf,9160935b,dc4834b0,4bf47d6b,fad52c04,4d26e21b,41eeadb2,5c92ca22,6dd2c86,24d0eb34) +,S(490c39aa,c290d144,2b87622b,407dec4a,3f92aa61,6a9c8495,132b5c7d,3d5f9a0c,5c76c0fd,57844aa6,fe81361f,73cb314f,110f87de,6773e1ea,b3d68dae,2926b986) +,S(fdd5cd58,67d73347,ca1fb212,772b0c42,3a4caf94,a3e0bf2d,2bbb2433,9002d03a,efe5f407,d1d26bc7,6fb5bcc0,6bc94da5,bd69f84c,85d89172,10bce909,77411995) +,S(bc8a108e,b0830fce,443db272,2655ac40,e2d35989,cad192d8,e9c5017,14435ea9,924c0258,cbc3da74,a708a384,b93196c0,76bd3af6,2907cd60,22069b93,e3c979f9) +,S(ed809b6e,41f4b6cb,86ae431a,718989cd,2c706ea4,10152e3b,3395df8e,ae924b44,135d805c,3295589,c8d42ffe,947aa88,bede6699,b119f8a,324c9bfc,64315da8) +,S(26b50ac7,5d871e07,4147d2f1,ee42d6a8,4398212,79e9f276,7978517b,6cda52d8,26599c63,86426e9f,b14b4c8,3494f0e,1fe37ea0,521e4518,e346bad,545dd7a0) +,S(cced88de,27d0ccd4,7f6746ff,98907cf1,679f6b10,67785dd7,25ab94d4,9fe8efd5,5b0ede2b,4dc584ac,b4b6adc2,c52b4268,e2beba67,ce2bc825,fe4df43d,73f5729a) +,S(d8edf7cb,31526332,308429c1,178886ce,bf3fe516,18f472bb,52da883d,d83c6249,a56abc3e,c155eef6,d43427e1,30ba691d,8c71b80,6b487343,7f3daf07,17984be3) +,S(ed82c3c9,f8db3a75,50949aa5,cd6c8fce,52648910,53f66515,c2fb71c4,7564b4ef,5ee59949,6d9d3c7,6fa9a26d,444a8a45,41ddccc8,15fccf39,b06e8fe5,20b2f0b4) +,S(6e277bae,e89aeb54,5e6249d,56d50848,5853b3ad,8588365e,7771ae44,3d8ca937,84871bd8,1e6f94a7,c31a3fe6,63a1170c,8f9623dc,4e24a5b4,3f7d023,39f40b8e) +,S(aeb67ac8,67271210,565b1229,3e1aff94,f2f8b642,76768967,f702afb9,48a03c5c,fcd3c588,94259c03,cde7898d,66ff5ac6,747100bf,3707e89b,6980d21d,78bde197) +,S(9f07ff4b,aa20c756,94c967d1,e38633e8,45753193,a3d13af2,3ba7ce07,5283da79,ae8b7f0d,49d06168,ff3c5f36,3aca3f1c,14308cf7,d95bae36,3975fb7f,dff2136b) +,S(24046d14,a026daba,1644b3ef,7bc5501b,baafc3c9,76acfdf7,243395d5,713e1520,265485e9,6dc40a31,ba93cd0e,915534b4,37fd5380,bad0d6cd,321867cc,aa029ae6) +,S(1376926,bf8fd1c6,80344f48,c574e6b9,1806afab,7d9f90c9,13bbc233,2b3de519,a34100e7,c4b44c26,f86b2198,e7d3696d,8aed9051,a1755ced,56ebe795,d5a61fa5) +,S(943c6d4e,816cc668,87f7c85f,b116ae82,5e4c38a6,581cd5f1,1efc9a3e,ef5a7d6e,d93d4724,f618da6d,29e35165,7883ee36,74112f70,3169eb24,eca31a60,969de8dd) +,S(adf8041f,159260fd,cafc9e61,d5f4f867,a0f46e94,af60bf53,d4d0808e,885432d9,c4eaba1f,99d2516f,3d731bcb,be90b36e,c055ff5d,e6c3ed95,2b95a037,1be57958) +,S(15c17f13,a404ae08,11ddefb6,707a9fa9,dc0d9461,8325dbb8,d96537c0,6e2dcc44,8740d352,21f95e8,36842b48,2512d79d,a799fb62,60d65dc6,79df383a,e9b6898e) +,S(87bbbb35,62365994,9c5bd575,86b813dc,966ec9ed,1ac31435,80e4b7cd,cacb8ca0,159992c,1bfc3c24,95e14ccb,e24a3e9b,6a28f4e9,1cad4a36,f83624a8,d22a48c4) +,S(39bd144a,96454c1,9e082b5f,eae9c433,564da73c,d5d44daf,95b5c176,9f1fa105,ffe8a11c,30b5d4d6,f8abe12e,bc3ca8f9,dadf1527,330319bc,fa277b13,256fb207) +,S(c4e4eb4f,9bcec0c6,6bb99bfe,265b2f4c,a1c69676,ee970a9a,b78bbd64,a83bca7a,1bb9a83d,316cb9c4,bce4be2b,d05e6381,2ecb493b,44fc3cb7,c2248a0e,96bfc286) +,S(c183e783,1c80d334,f0ddd2f4,48ca035e,8b53f034,f53c1801,488e4aec,cf244e69,f998feaa,c7711d48,3db38926,8ddc080c,8ff2f95,494e60b1,59330d8b,d9a8b820) +,S(99d1d7ac,22a2e108,f093b630,f374d9d2,7ac812d9,5753bb6b,e39c2401,fed47d92,a67d334,88dfe341,e8dca3d9,b36a897b,52080a3d,c366c8b0,39cc4de3,52d0e1f0) +,S(e0700a5d,16cd89bb,df3d6f18,76909082,985a3339,e7f5d2bc,5c3ccc92,ad61cea5,26f6abe0,38953fa8,40bec97b,c9d59c20,1fd08b29,4a7ac7e3,bd994e07,70a0b0f0) +,S(b19bf6e8,cf36d839,51b813b5,67aa62ee,5415e95c,d3fa668b,55487a3e,61a7e721,630e78a5,ca2cdb2e,cd59f59e,4c10e712,46c1055b,a7709041,fc03f8b9,1970153d) +,S(25009156,e90dd0ec,88027adf,a9701474,39abaf72,1c333943,c6fe6e19,ff71fd44,324047dc,86477632,214ed74,cb933859,b7825500,2d19ddec,9c466e1f,573afc11) +,S(45ce7fe8,bbe45d1c,9bb0c98d,9d4c500a,aca5011f,96238681,771b8538,61a3e4ae,8cbc22af,d1adb8f0,a5c72570,2b6c7f65,9e41b176,1358832,7ca062e4,2392f8b1) +,S(73255507,d3a27fc6,7df39212,a286ef6,b939e953,43b12683,4e38148b,619ec059,3174d6e6,e941020d,db0f3ded,aed6c8cc,eeba10ed,1344ce28,a354e93f,25c35b63) +,S(96b2cef4,1c6c39e,1ec9a945,8c8bad3f,6025962d,a1207885,97800ac1,c811df58,ed85ed21,41b4ad26,3adab5b7,c0c0035c,2fbf9e2d,983dda99,7d1249c6,8a7fa8cd) +,S(5764181c,d941b28a,a307bebb,912ae87,57f23cc9,37025cdb,b983eef6,42b9c772,e8173b4f,c23908fd,db5f6437,5457a43d,2495764c,f3ce1b8e,f2c8d2be,e0ac7089) +,S(38ec7839,7e965056,2b1e314,5d5b2782,ea16d2a3,82bb6c60,efd29edc,93ec1b61,acf04ea4,c7b6de2c,d8acaa3b,a4bf2656,f522e631,1cd51089,744d4c96,318ec96e) +,S(6ec4ef80,13d01c79,758439fa,108f7389,79c9f7dd,4b285eb8,b7aed579,76c0b572,2328e642,e618ecdf,3a6560e,3eb6af15,7a6d266a,f5f3c4df,13c1ba2f,c898be7e) +,S(d8da1f6b,30c27b1a,5000fc14,9a768683,4c40a581,c4ed67ba,88492449,ef77141b,ccb532d6,876d92cf,2b8c310,839387d7,d92464e1,727287dc,49a3b348,2d519758) +,S(84f25402,734970ec,966aa9f0,eca84a1e,6894d36c,338722b4,e5fed162,8f7ccb90,f2d7fd09,f07e6302,cc97d283,d9f06319,9bee137,d3946944,983c2192,335cd8b1) +,S(ef6752b5,58874372,859190e3,91d86ff7,3adabfd4,cf008038,136b2ddc,ce9503e3,23d9ca50,13cb479,7cbaa675,98dcf98e,73f949e4,614390f9,1e6159f8,3f131c56) +,S(f88d8590,3b3fe67c,f641cb52,c77c776c,fe198f74,fe116a46,602bc2c0,1085ba6d,58af2abd,2178ad68,a3695714,cddf14e4,21da61a2,8e6cfa32,40507fb7,ba08742d) +,S(93b739bd,d366b95c,675daaa8,c5ded7d2,18cde6d5,d15d354,645de017,2db9c01c,24ec535,6c2f8eaa,633af5b9,6ae0fcad,7afea5f1,c7c8bfb4,748b886e,25cf3627) +,S(732cf404,da7ae5a2,dbf82f80,180c1154,6d313b92,58980f95,d413f223,443394,858e8326,1758b90a,902eae58,a777b56,e8820084,153c9e43,1b7d789a,4d596953) +,S(efde0719,2c40002d,3f82e024,a1b838b7,65fc252b,5be4af75,28ea5994,a9d36e32,89c1d35c,3a153576,91a63585,183a9c6f,b8dd69b5,69d45483,f0c2f80d,3dd9107b) +,S(9eedaaf2,80693392,76420c1c,da950bda,f114e65b,9b1a74a6,b42dd90c,1ec90a15,1399dc24,7fa540cd,3249728d,a4d28c52,26f427e1,ac3b533,7de8ba07,d3164de2) +,S(23f0ea8d,342aa214,69deaafe,bfdb487f,775805c7,d4ba17dd,877d3d42,19433195,dc1c6e31,d2a481c5,5d32ca8d,1d4e93c1,63444dc3,9e7c306e,4fcbfd46,b699b03) +,S(d85270,58c29e60,58916e82,76a305d2,edd47c0d,4e33052c,74cb76e,abe060b8,9a0e4904,e4db5bb9,5ec9e510,59ea4993,84d497b6,8a9a1258,3a2fda6e,bd0cfac8) +,S(1b34c95c,ccf91204,5922d2d1,90cf3860,f7d36b37,7ab3763a,d4d9046b,309f28b8,70c2320c,3f5f663a,b6478c3d,2607cb4d,f7080de8,91bb408f,6f14a11e,2951e948) +,S(32558fdc,ae5e596b,b756d4e2,f10707a,89569d36,1498e8c2,8fca1473,4b84b228,7759a8b7,5ed5755b,b23978c4,3d5aacd9,fe63f6e0,74b6fcfb,501906f9,16038d86) +,S(64818b77,37d2bc57,391a3820,2040afbd,6028d7ec,fa3d6bf8,577cb1e8,dd984acd,4202b934,6ae9554d,9227b891,4a6304bd,2cf895ec,a7267e1f,5707489,71ca2300) +,S(c6af6ac6,ec2d7cb5,42aa2373,24288551,bcd33705,72e1b1aa,e572d87d,8d77b333,fffe5559,4ae5a2df,18e393bc,dd0407ed,5d5af18b,85f22352,9fcc7cda,dec78cbf) +,S(91f8fc44,94ea12f8,fa2a031,7f32fd44,2e7a9e34,28eeaf13,a8b0de3e,a4f1cef0,6a0a47a,d81b1dd0,ac6765f4,20cc26af,e76c2225,eaea2a42,481ff6d9,a554dbcf) +,S(e159a9fa,6a26f57c,879b081f,dc015b46,dc610a61,2335d6c8,e353fc42,11c1c017,c209c643,445ae009,a75656f9,b4c1df2c,f1c181c7,ca81d0b6,bd749afa,a93e8851) +,S(e8e9fc5e,135f3a97,1211eda9,c06d283f,1a705169,b89e5813,556beba5,a4f9330b,e8b96899,3b73e8f6,da7b55fa,6f1e44b5,c88423b9,f3fc5553,fe0b10d4,e9af0abb) +,S(f3f5d529,d5ae4c0c,36c27ec6,e13384b4,11aa9818,aeefb5b1,64243536,bc0edead,3f740643,1e40c133,345abbc4,ffc5e0aa,1dd1e306,43e52ae5,33f5be61,db3d34b9) +,S(c5b76430,f5d8bb9a,e1b9acff,e1417602,9eae65c,9ca1606a,2e4f6d7,6cc81159,80689f09,70089098,24087591,6915380a,29b13933,9a000fad,d2e86d8,cf2429c1) +,S(954aa4b4,34f59074,45ed30c9,ffb6db50,ff275564,72894261,e935109c,cfc09b0,8023ca86,1bad2c25,6cd76be8,b3b0fcf3,a808b76e,80a70ec5,83265d3d,c72e4ad) +,S(55da8bb,4803f339,3020c9b9,30a58336,1b96ee54,4bbb4249,d6df1335,6e3d528b,dcc44b88,ca06e9f5,86cbb209,da01785c,2387b14d,355a2575,799ef7ce,32e5b64c) +,S(8084e800,d810b286,b0ad48d3,d262b4e1,db59eabc,a176e368,77a7f8bb,a3a1de03,d8beea9c,59f865fc,9f09c12,9bc5f980,70d60ac,eb348f85,e0888fc4,63dc1480) +,S(1b2bb6c2,36c87f88,748f49a1,5094949b,d15e0217,b00c0bd7,f85efa41,5718b39b,2164b195,6aadf36e,f1bdd018,6bea9a4,c3c3f42c,b0e81dc,8101ad14,51029c74) +,S(fba687e8,125c372,e5dc65ce,3d2febed,de9139d9,9f91ad84,830da38a,54377872,8944eadf,3b89501,ca4a7a82,105a9613,55aabbf2,57f4bf83,923ec12,73e001c9) +,S(b58e4b80,a5f1c16f,f9c699c9,75a2d797,d21e155e,f091ba94,8aae2dfe,fd560cbd,fff9caba,1429bfa6,e571b7f4,12d6aa97,4606f7d,9025efec,937a5128,52cec3ec) +,S(8ebcd526,da5d6c21,55222551,e05c6be4,114fdb7c,9d43a900,fcef17ce,3426edec,73a0fb98,6b3301b6,3eaaafb1,a52f5467,de11f034,aeedc21e,ae97df86,513aa97e) +,S(fba4540b,924b29e8,95dc68f0,e971549b,7354e032,64040d2d,bb956691,1bee325e,529088c3,3b9857ae,342ba0d0,7e52843a,290f3c27,16f5321b,6c9e6f51,9105ebd4) +,S(8b7a2c97,a1a7d324,6d86301a,66f3f36e,ce014c97,651b25b0,ab46f4e8,bf9c44de,b82854ab,699c35b3,6786c1f4,71ea7536,7c88a684,43fc17b9,4cb328fd,a4b247c7) +,S(9df11743,5adb7154,e7003bbb,a1ba909b,93179677,4bd4896f,40c39a58,ead2279c,a7922f4e,a216cc36,c36913d6,e7ab8641,d4566865,dd7a2f83,77ef219b,41b884eb) +,S(5beb7b84,749b444c,82efd9e7,37314892,c54b6215,c1f9be9e,414adae4,56931cd8,99e425f,32cd0a7c,28e753fb,ff308eff,d32b7cfc,eb51df7b,64f60e9b,2fabb95c) +,S(2a830c43,ff204ba,78c5114f,4a3b7b09,c9f8ed5d,17066f43,cd512af6,4c788879,12523a4,e8882652,eba827fe,d207eb00,9ba14809,9ee42865,61e96230,62666c84) +,S(f71a46a1,4c1f2a18,e68ab408,bcd32d94,985a7714,19c1419,1b69221e,1c57486a,adf19b3e,ea79a53,4fcce36a,4cc0da0f,4fac443f,b281cf0a,ef675b6d,20534875) +,S(2b80e5dc,aa9c2b31,678ae2d9,f7d63c0c,bbad2bab,36c412fd,cb6436a7,c69d193b,bc83e04d,71d60062,b681ce04,c506247b,8f3c9019,c2084ffa,27621d62,22119c3) +,S(49cbdf3b,e521c69c,68375b58,d4449341,75424a0c,3c45d5b,b975235c,e63beece,c5615eea,f0f0e7ce,c3756aba,d3a136ae,91d260f1,563997a8,ae46c49a,5c62de7f) +,S(ce4d4714,b643b115,9215e2f3,1dd070f7,f7aa663b,9ca87739,79c5ba31,ce9ee1b2,b1f35e12,a2fc3aa3,4db59ef5,e62101b0,479745b4,200c10aa,d6f8fddb,1efeac38) +,S(6827b6bb,aa905ac3,8d93bb1b,5d5881c5,a8bef479,ed7c5656,2992d4dd,61e10054,8524a87b,af65020d,91848427,95801f54,30fc3727,7ef2064d,1aff8ecf,296bb869) +,S(e71e4d5,48f4d7f1,c7b7879a,a03a49a0,ab947218,b16dd125,19af4ad1,8056535f,495d0461,7098b3d5,6f7e3bed,ab5c9813,83aeed68,3ded1c09,f0d1bb38,e32f574) +,S(ef683979,7429fb30,d436aa32,a3feda68,65652816,873ce542,6320667c,6e00e032,b4b18e4a,de1197e8,fded846,f188a6ac,2f17506,f014d404,fbba3635,534613f) +,S(c729c1,ac8f7eff,e908007d,e2eed85,dd557e36,c1ec645b,a258b03,e52deaf4,2e83edc2,18584f6a,c5ebade6,a335a087,12365b89,ac38f27,bde7ebf4,561305fe) +,S(cf1d3919,9a716d53,b2bc4f2c,3ae2ded1,290d54c2,2124a88c,c1cc7fb1,115735ab,6b44f5a5,7ec3402c,e8980970,dab8538b,c276c8ee,ad542908,9b7b70d6,dd00e6e6) +,S(6cf3d7a0,266dee28,f3f1f772,ee90da75,a9c28a7f,f82d8f55,cf9d609a,5becdeae,3bd18fb3,1e11cce2,895b9cf9,4d9a99bc,ede5c9b4,c44ede14,34dfaeb,49bc58d4) +,S(da4b5832,ae63eeca,cdee4274,f00ae932,56393cae,cf830be7,f28749c0,7d395542,9aabb23b,d2d940f1,815610c9,d1684b92,106374e3,1b694ec4,dfec8818,cdb2210b) +,S(f91ae350,23210e16,f9c63270,cea2c6bf,407d1a10,e95842d4,b8ad5f7a,4330bbfa,1f161ac,d1962573,5969290e,fd3d1af1,53c91543,33651e16,1b51086b,913aa1c2) +,S(7e1bef52,cc3e2a2e,45847c86,27328526,c72e3f73,fa1c8255,56c874b2,f2f1ac02,be4b0f7e,a706e4d3,db7048fe,e0fc4f50,8ff0523,ee8d97f4,4c4c1787,e6f6e6fe) +,S(dd2695d,30dc2ee3,748e256c,cdc92eb7,706567f1,4be720ec,b27fc814,d3d5998f,9af32c44,f1028013,9ee7cf99,845472b5,bba67740,f0f0b96e,d1a02a19,a32dc74f) +,S(78fae650,714763c8,d12602ba,33b76da,125fe395,43fb37c9,4d20b337,649dbb9d,78dc4c0f,726cce6,f65826e5,eaf1fea4,c3b92532,6624ce1,21de2351,bfce3aa6) +,S(1edf521e,510e5dd2,aa1d3e00,d016b45a,1b6fb6b8,591d98df,ee692636,8dc98bd5,9a0d016d,9b2e9b8d,d0f4d817,71ab0f20,aeafd8d3,63beca59,7518da41,55311f86) +,S(8607bb0c,5e53b60b,9153272c,d3cc69e4,7ce28694,37562b4d,4166aa18,d0101d39,15ca31e,c83c6541,c35a294a,a648af8e,38870757,27924e98,8ef566d5,96eb519a) +,S(65fd300d,9a0503f7,80a0dbb7,c42b9bb7,37f9607,912f2df7,166b65f7,96d02eab,fcd15350,84fba852,11f94540,1f6b43f2,904caf3c,d44ecaa5,335b928b,4ea3b5d9) +,S(c918b3a7,6c847ce1,c01845f0,34ccbeb3,36d031a9,33093f99,f47f1458,cc02d148,f256f403,dbbb2e20,32063270,faa6e62,596329d,ca85ceb5,3ed3adfd,7f728568) +,S(6ac2dcfd,2f0b879,becb429,140ade0d,532e54d4,dbe0bbb5,c1352ace,5661817,f2c26310,abf9396c,5af23074,e72251c3,784c3de3,60466dc,ccaaae16,4a9e2af3) +,S(8d71c4ee,54acf389,cee39b94,b5feb2b2,cf8e95a9,45f6a95f,5b0bff2f,cb3f3d19,98442bd9,5a02c1c4,7dba3881,e3306103,f0bc8857,89b44cb6,54875847,f1ce52d) +,S(e8bd24d3,fd557118,f2c0abbb,511e874,2e5d7368,a909b072,b3dee124,44f583c3,e1d2c3a6,e28622db,65b7992a,6716459e,2380285a,cd60f43a,4d4b1bf0,8bce6538) +,S(62dc2975,5cf8cf89,e52c8c51,6311e3b4,483fd024,ab2ad1d0,32d7255a,3c075217,799e132,d80d22d8,e0f01e9c,d0954251,8b3fc8a9,48f3cd1e,9391f8f,5c0e2a97) +,S(37db13aa,cf727e60,cb102709,9c7d3c07,4d43234f,66a95451,a6050496,d44c0e13,c383bbe,8f8ceff4,196e9d07,e013a1f6,d3402a6d,d09eafb0,62924334,89b1066b) +,S(37bfb765,eab7719e,c858e17c,472f1df1,be9dc439,2699ec39,37875b30,fb2aa1ab,72718bfd,865dc4c2,2f935f4a,98af8ca6,5cf44b5d,66f0eea,23b53563,d1721364) +,S(433ede12,87fcbf35,5fdba6e1,f62148a7,b5d5c3fe,1200d456,6dba452,a85d1b94,b27c5613,ad6e513b,28f0c959,13e30781,137a4c7c,7aee6e60,5715d949,4757c20e) +,S(e582d9f,c5ed0de6,92a1917f,6ab7df46,d23295d0,b8b27b32,3af9a57d,3e671861,33ee8785,e2770dbd,7e79faa5,386cb1d1,d1c9e073,1b78dfd6,5571deff,d4073154) +,S(60b07b40,634bf15a,ee2d4e5d,a0f06ade,ad8fae01,4a6a189e,4e428600,4c9442c2,fee087cd,d243ba,62b4a2cd,68d8aac5,1557f29c,a57b0f37,ff2119b1,bc4b283d) +,S(4b167276,1e5f7ca,a245e35,b6e88fba,643e6da7,ce37c9b2,10265ad3,2de03100,28aacf02,476887e0,90d26c1d,cd51f15c,cacda02b,b6314a64,73b90c93,8ed8dde7) +,S(5d56113d,6d797e74,c4803e63,89a88ae2,fab97de1,4ed4e7b2,a17d2f9b,fe2a3170,94ef2a8,534eb2ff,a62462a2,7eb2b34e,c6545992,e2d973ab,ee42b1e7,d9cd524f) +,S(a9d03fae,75111ad8,d1157287,8e8c4473,f4a06cd8,f28dfa7e,e38b3d06,3a34f828,a0733c0c,c7319879,2ca665bf,968f6bab,480c94b4,c7de262e,4d9d1f95,33517881) +,S(74199571,2b1abce9,ed4db3b7,7b3f7e70,58fd3716,1666c522,50855f25,660e1ad5,710caea8,97f7589,cfd3b8a3,22726000,ea3ef2c1,8aac385f,22b67bd9,da44db) +,S(9f16990d,bf81a5b1,eeba1e5f,84673e16,ba0106f2,acc68be7,cabab96f,25918dc8,d60d47b,62321042,34c49d39,c03806ab,135d46f1,ea6587b0,f0b6588c,50ebc4f5) +,S(3b5069bc,4f12b9a7,ad91c888,fabd15a7,c99143f4,c8b24619,b6a70c0b,2301d57d,dbb87cd1,ae59a944,9fb4ddfd,4b311d66,da18544e,a86b75a8,979828c7,fddd1a79) +,S(9dea63a9,67b5a36e,bbbf9af,bbfabb31,f90cdcd7,9b75c68,1159b946,dabaee90,b14bb99b,11bab958,e31a605c,e9180d23,5c7d2eb,94d4de57,b8a66627,c6bc4464) +,S(d0b23392,1da36a84,2565cb53,4411e63b,9fe6b2c,c33c3a18,8e0ddf48,55e31e79,80ed93ea,1a6e5492,dcaf1cfc,c350b3b2,99117276,43fb6a75,15c435e5,f74f8e9) +,S(8adc9655,966ae44b,f98ca7a4,9f441e3f,acfe85c8,f7111da5,52c817b3,90b03d20,ce72054c,6a717312,180c80ea,c9337430,5dd1d566,db1b93b4,eed1a6e5,73c0021e) +,S(f6f76bf8,cf6d3dea,700800b6,d018a4a6,141ac610,e2e13fe3,ec916726,1e0c1670,b2c478af,e1ea9876,98e5e2a1,6b3a4ee,63e4fef7,6644da54,e241c395,3f9a302c) +,S(d58287d,38b7da30,174fcaa1,873b3913,2176388d,6da5f9fe,f873d86f,14b898e5,785fc934,69ed085e,8318f91d,114ad0cf,da2b8ff5,61e545ee,3502e9ec,6afc8402) +,S(7772ca23,50c5ee55,9ffe810c,6d8702c1,538e3d11,f4b8354a,2fbf674,39a3661c,5a2312de,853fda14,5b48aefb,23e98e4f,fe3dd3a8,ae1fcd6c,931d9a43,686edddb) +,S(a2f9f976,c50f3687,7ad0ac95,efc3fb2c,46ce903e,76ade308,69705df,72433ad5,ec565311,24c289f3,35e11b22,bf8d7445,f201dd4b,68afa38a,22af056f,c8c285f3) +,S(e20d9765,85f8c567,24d0ec16,5ad27110,26fce166,b52ce11b,cb221a80,4f8b15f7,63b61933,c7f63862,98b48b6b,c6abb54b,21d08220,166ac31b,fc85d4dd,998f33fb) +,S(8868b59d,ca1de2,cbe98d94,506db1df,659ba688,b2bf093e,42dcec03,acecc18f,f02e9b07,96b98fb0,51dbfe8,4524ebf6,dea56251,afb53076,e2215d83,fcf2fd0e) +,S(1099f82f,e32a1361,a785f86b,9a6bf0e8,99c83226,7826d6a4,3f8581b8,89fb677c,13fb83f2,9aa7f271,2cf20cd3,592eac46,cd2d3e61,9afe9aac,7fcf37d8,9c44445b) +,S(4af9c696,77ece7b3,5f732969,8ca61b27,deae65ca,ee2d5d31,ef2051f4,35cbeea3,73004596,429da976,f96e3f80,a24408a4,ebfe5196,8130c698,5b210826,664e5ef0) +,S(9680cbca,5aceb8b0,322d4bbe,8713cab9,300d1f8b,d16ee045,edb3b543,57dab473,2f293940,e36ba1d2,ecd4697c,209b33e0,6904ee3c,2798aaec,e9131d9,bd0df58a) +,S(7eefcc3a,fd6347f0,5f9c3720,31480c92,3eb7fdfa,d6e9c0ee,4e2db9ae,27fae7c2,b8e9fa75,4f745c14,7c753e42,17bb1e28,7bb93d9d,aceb357e,9738f10b,fb5cac06) +,S(b823156,d63612b9,3461fbf3,6894955d,65e7805,b025c2fe,98fd46fb,2f9fddb4,f23c517a,826fe91e,45f453eb,fe9eadd4,d0b537c6,a2a8f60c,dab9dc58,10bd465a) +,S(e801d35e,2035fd54,92178706,e2e765a9,bfb9de22,e89182b4,4d5144d3,85bdadd9,1e648234,27dee6f0,818868e0,419e37a9,1c216200,3faa7478,48161809,76956a26) +,S(e9d4610e,56b70969,284369e5,7e890fc,29fd7750,8489a1c,2f348f52,cdc67f3a,8e5f6aac,357d82e1,a29bfca2,2ee4516b,1df0e622,257c2c1f,7d9a84fe,b48e4a0e) +,S(71c3ef0f,51d6ddee,340d7aa0,94680084,b94bae8a,e3528ff,4a481af6,d3b7609b,4d1674dc,2f8087a3,138adc4d,aa615a43,db6886d4,4992fca4,544f57e3,315f6b96) +,S(9567ce43,b6f5c41f,bdf8b44d,938abac5,21aadb83,c157b947,ce999c0e,4a7d6f20,c9d86317,31ea318,a647ca8,945cc35d,1fd0fdd9,b2de4fe3,5e2a0021,33a35538) +,S(34523d4f,81166739,10b3de85,11a1921,4f8fc753,fd8963e,b9db22b7,8edcc141,900fb9fe,268b88eb,9b80a066,277d8ba,877bca84,f277dce7,7d6e90c4,8422ac90) +,S(69fd1f7e,5f1c43df,a2f4350b,f20e5cf1,f2993dfc,b61cd278,1590ad79,e3c1bd98,633726cf,8b74940a,edb15665,a9277973,2d1c923,2bcdd615,43c9f3a,6c51d7f3) +,S(e4c2c424,c28cb8f7,3146dd39,bb4fc6ba,411b2a75,e317faa2,a9f878af,e94a3de7,fb8d17e8,468e5ef4,8da60739,820515cd,c861378e,9b3bd158,fcc8a949,eb21ae89) +,S(5710459a,ada916d0,9c1feb59,c494863,98e44513,226119ea,5ded7b1e,34e32773,89deedbd,d2d83a58,4e56b409,30a8355e,905bf12a,f33f49f0,7383eca4,e63871bc) +,S(d56faed4,171806e1,5ac17f91,37101b27,59a3a8a9,90b85bc1,89b217a0,6fd48e64,fa871ec3,3408b2d6,b62f513f,5368f549,ebe43977,a48878c7,6d731447,34a6652c) +,S(e7416eeb,da0b805b,68b47be8,eedf87dc,cb5cf012,804d03f7,604525db,aa599bcb,8610c716,f11c567e,313eb4c7,77e4314b,533d4f37,13b11185,bbcf5442,b9a56c19) +,S(8ca59862,ebdd3541,91c60608,13ce32c6,a4fbfca4,6e60175f,2d5f1607,d5fa997d,aaf3480f,b132feac,6adfa195,2b14d0d,113dd6ee,faad71c6,980d5691,e37698f4) +,S(6496dc45,1fd43b45,1915867a,846c5203,6eb8e4c5,28c2a181,72fba6f1,53243413,44fdc41,f85c99e,e00a281b,9292cf1b,153fe2bc,5c8b3e87,cb14d624,e44da1f2) +,S(3a424463,aa82416a,a38bc248,dcaccd20,67d20721,d4e8f5d6,c9cb2fc1,91925a5d,71a56463,fd242591,434775cb,37c81bf0,d4857abf,aa527ca9,c3178464,8afa9fb2) +,S(6a945b05,51d55194,adbf7985,aa85fe63,8811781e,6b787418,1574d109,d178c2e6,186d343a,1ca3a836,32421fc0,d267ca27,80df9af1,32625d31,924e99ff,9b57ac44) +,S(13f1f692,682d04b7,b7e7381b,8c5c13b1,32baac0e,b7f8c8aa,c9ffd77d,3aadd47f,572a05e4,9622ff88,9eb36852,85d1400f,43372533,38c47ce2,282aa4ae,26e99f0e) +,S(79fa13c1,4f0de8f1,ed98e7b3,3edb77f5,a2700707,e54ce522,a516634b,d2804330,a094bd88,e1969ee7,3f41e40e,60f7198,cf2484ab,5a2efaa0,96e891ee,d5987c65) +,S(df1ff6db,d2c61bf7,c273f735,a6dab3d,fb08377d,bb3dd101,9dda03db,e533130a,2fdc7ad,68c58689,92e5c969,d8d14a94,cd0061b7,5ab0e824,fd19611d,923f886e) +,S(a8223280,5f5939ad,180f8776,810cc7,2bff651b,df7972ec,51d86d2a,1acbdb34,9681590f,982e3632,b2aea9b4,40043751,e7f2ef2a,d4b125b5,2784ffb5,17c2dfba) +,S(406b0cc0,49f3bf58,6990ada1,63c73932,b3780fad,ba3fd8c4,79e6a688,484c7c44,aab0e4ef,f2508e54,79074fe0,218aee7e,8b217932,859192d3,1bb20817,df6503dd) +,S(4e7043fd,5783479c,3dcf103d,bc4d9bc8,523c81ea,dbac9460,4b73300c,f516bcc8,196287b7,3ed01bd1,e8033ead,66c92625,77c859b6,73a4c7fa,98f53d69,e82d1133) +,S(a9a2a671,b945a5f5,90575c0e,ff24c070,a7d55b00,e9d2f44e,43cf400f,f3e9997,6cd45e20,cb972715,167f957c,af7f2f3f,9ae22ce4,3b46d4ca,5b2a58db,6e0c6285) +,S(692a1394,75ffae88,fba47ae4,9315a6ef,12b2dec7,6807608b,22ba3ff2,883d3c01,74dd5b4a,3c14a54,c0a86732,1a77d160,c834773f,8063406,85a65c16,6ee46131) +,S(36f915fd,156638bb,88928e75,d00fcd49,63b44ac,f5d016e7,7ddaa8c8,d62cfad8,3f11eb6,16edd183,5ee17d02,722cf6de,991dc8b0,e37fce3c,cf7f5db,e842e8b9) +,S(3f0f6f5a,7e010c0b,5442fd6c,a3643144,a5202a7e,bb3ac8f,99aa38d6,4aa53b31,2574d7cf,5b33e29a,950099ac,db0ffb3f,ab1f9ed7,f13cdf9a,b869fd07,c35c649) +,S(8c58faff,71f661d,b21d4258,a92aacf3,508a9dfa,bfc00cfd,26b95673,34b7b067,38d1e894,ea1d4ee2,843d08a8,80b11325,e9a8a171,59de273f,694a14d6,73944893) +,S(d806731a,205c1a3c,64b91864,2d940b12,dbc6f580,866b7a9c,f287fb7,c5da78de,870a8430,2ff57abb,735da831,863525fb,70402006,d241eba8,d43c2ebe,cdd0e05e) +,S(7dbda37e,195db041,a4dde151,5a7cdd97,416bde09,12b9a741,3354204e,2b848648,83c89c7a,649d0070,fde84ff1,32f60a9f,e1c0261a,87a8ccf3,885fb003,10715e71) +,S(8afc23c0,c803b0e2,df78ee09,3b776cfb,410a1b52,7d4be45e,58d8cee8,3ec54a1,b041eece,4f4ae4a0,b3a52957,386394be,bf7b11a2,b97eb5b4,1bee89c,352ed76b) +,S(4e4424c2,2c50fab0,4b803b4b,2562114b,1b2531cd,e5786112,36fb9021,3652207b,22bf6181,51187118,fb421e4,fb0cf243,889d5ca5,c14b6ab5,7e7b9d0d,d9796e6f) +,S(60717788,5a230af8,a0816e39,6e39b34a,f394b1ee,c93ba382,8fd92941,e6e97453,a84df29f,2b9da41b,14f24762,df6db87,fc0a18fa,89e356f4,9f8f4017,dc4b26) +,S(c9f73d20,384e56ec,37bbbf8d,facf70e4,a271f169,2dc22ac,6022ca24,8caf3213,7622e7f4,c77f9581,b73c9bfa,8bf5b578,89070e8b,97616cb0,69ea25f8,8dfb5437) +,S(19ea5dfb,dab5a1d8,c3c2bfea,48d90f6d,a8b9959c,630bfc4a,81ea5eda,ee45282a,c21295d,14bd81,7c3a4d62,af307b1c,870a959d,7d6e4c65,3b8e1db8,fdf1d56c) +,S(564bdb1e,30b2c292,cdf0e149,1bfaf852,4780669,717de5cb,290cbe6d,c1617b58,9a8da0e8,6fc0b95f,99e84198,877f5ddf,32508c1c,ebb9984,7004f74e,7e2b1c0d) +,S(5bc93842,4f3ee6cc,926e2123,7bee0739,50b39d1d,e0dda3b5,4bf46953,7d0bf06b,d4e9c3a9,662778be,b7f4bd4,cd753a50,32bb003b,694b5e00,c119dea4,20fd5d16) +,S(19432e94,829e8b57,3eef4fc3,181c7d7f,5b2a5f2d,a2e8c3a5,980db9bc,5cb7f99e,f75c999e,5c5b8567,bb69316e,36e01acf,2e860781,5c5703f7,a4be72bb,9abcbcf6) +,S(d399281e,6196ce19,a2ec28bf,a0b1b559,8d0235d1,beef1672,ea230cda,20080b8d,1ca7e95,20ffce3a,33e94931,95eba433,d5483cf0,d5edbea9,6384d1a3,5168aa19) +,S(6c84e35a,b220fa9f,e55f5556,302f6656,39372e97,74ae26ba,e21ca8ea,10e73c88,98a11b2a,bd442c0a,d49711e7,b0e8b234,1d15465,71efe9b8,9a7b4c02,1101b2b3) +,S(7814cd8a,b1b045ed,a1797f14,c83bd807,ec4205b6,e9df4858,1180a80c,a0f8f64b,ef917e40,edc8b8ff,f53e8b70,4de63adf,6bf17730,41af2284,1b0e38d3,b515f33b) +,S(7a01ee83,1c8e22a8,bfdaccfc,cd280532,444e710d,7138b993,fb6e06c7,996235f,fe512d09,19895c2a,b62f2e08,90dc3bc,dcb06198,18160b41,4527e7c,281a5519) +,S(655ee6bc,df86c9ef,918b5660,5d4a5e79,512e856f,3f3e40ce,72e8217c,1f9bd908,cbeba5a6,91fcb085,f3996ea9,d081e69b,7dfdefba,123df5c3,cae94f63,12f87721) +,S(ebd68009,fb0372e8,eb0be25f,e78117bc,3d4d4814,440f1d9e,1cf87ee1,de5219bb,8efb7e38,6f96df55,bf0aed2d,6bdb75f3,6da8cdb6,ff65868b,d8ce79b4,ba58814b) +,S(87340818,9ac05bbb,4e95cf05,17d5abd6,8b7834cf,1168f914,9f1d63b6,19a3865b,9f1fbd27,72ce0f15,c91d4dee,dfae0a3e,7d24c0fa,de2bf30c,df63f93c,14480838) +,S(61b6b213,b02a7bb6,4de62e92,515690cb,5dda3a4d,aa96f68b,a12f2c63,30513df3,cc71b8f2,4eff8194,36ad2962,8c003a1b,c42c6ce6,53997d56,e0162508,c2b6144e) +,S(4ba7ee4d,77171ae2,e39c9e66,3849841a,ed5e02e2,182d872,98f0a064,3925fe37,5cdbd5b4,fe344f16,cb72158e,b80a726f,5a9da4f7,751bc4f1,f1fdc734,8e96dbd6) +,S(d5827a7f,c4d5dcd4,32e5bd7a,46892e9a,6f9a3971,fe9e1de2,ee247e6f,208badb7,f790fadc,9d0e0c0f,61efb534,9b23c60c,2fb667a6,3b52cf18,ca0f0a1a,6098e1fa) +,S(81ec5159,7f950cf7,c0d44d4a,89efe691,e9086dfd,ca25098d,411cb9b2,93237633,885b27dd,c9eff80c,94653f28,ef92fb60,741d3a2,aa828065,5fa60b73,eb9a1e7f) +,S(28fc41f4,a0d4f680,76a3e06d,af0aff1e,6e723779,d8ac9e68,4cdba2fd,6ab6dec7,b1e4af1e,7affabc7,3eab9415,c15b235d,482c6a8d,b1085f54,d80ca2aa,49657225) +,S(d5e753d6,c5bf75c7,cb0f5b85,77fa2f9f,6341a88c,cf59b5d1,328b18a8,f7ae4f47,d1aa54b9,8eb01a32,2518a10c,8ecd66ea,fc2f380d,d97953cf,faf0c540,c4a1bff9) +,S(1682355d,89094297,e6008fac,44c1a5a9,257d413d,7589286d,8bad4873,1476e836,4f69c762,e29f90c9,e8459b11,d53ed84c,2ec9c2d9,ded4ea02,78d04546,eb09cf4a) +,S(9ef7a85f,b64cae73,2eb511a7,8cc46e22,73425d1a,d02272e7,9030240b,23e781db,c720356f,6f6a5a47,3f35e2f2,f5e92e2,78a50c9f,3a77604b,3eb3987,d09ce73c) +,S(4f6aebb3,6f429a52,4cb1be48,ace0eaaa,2174468,c13cf612,dd7ec70a,2e915ec,406ad94d,a8b6d790,2ad3609,252b6d7d,b28f96e,8780f6c6,39620b11,cf8e761f) +,S(4cac3e0e,5ac02e66,66710dae,5c0d7e8b,7a3cc7f1,a42b1f8e,88561bb,223f8232,9396ec8e,aa96f3c8,4ffcb9c,d8c29d27,dca65556,c2fe5931,8ba05a08,cb263142) +,S(86f3463,3aa2ac57,2c4a9dd1,64c7606,f61fbd78,60619937,38ea0a60,f79367b8,c802fd2b,556179db,5f776c9f,db4c38af,cfb2aa61,b5ae712a,3f23e58,25824f05) +,S(5323f145,7685e123,e7a5ab4c,d1d39fa8,bcd6f23,ba3d74da,318dc7ff,347103a9,3092fb79,ecccb29e,12dec977,cbbf38fb,94cab4f1,fee1e8e3,46100378,88691cb1) +,S(d3d70d46,402711c7,e680c45f,3a0e1c5f,f85cf106,983ff0e7,1a7f1178,33ea74fd,91982773,d9b90f31,16893b9e,eea7fb9,e4f722f3,e1577c90,fdf6f625,a8d07bad) +,S(df63b937,28a87613,2db5d71,43654f1d,f8cb89fa,1ab1efdd,6fd864bb,db6d4359,7c3b79ca,191a3ecb,6c793034,832fa5b2,a2c7bed4,84b792a7,91bacb7b,62ce5510) +,S(f1fe9222,8cc334d9,5f303169,a4e2262b,28a99494,c7decec3,9746be85,71b70c74,5588f3b8,4e65fa72,a2b35f60,f99af1e3,b67a2435,8c28eb64,69de5136,e751a10e) +,S(9030e75d,918ca330,edfec14c,b7cb28d0,fb0adbb5,fa29fc7d,cb3c9085,ba74fd95,7df20128,61698984,c0928821,c38aded7,5a452dc1,3bbdc4cd,71ad99da,38b427f7) +,S(1cd3c139,35bedb87,134f628c,576411eb,dfa0b586,2c3cc7d5,ddd7cf5c,77ad641a,2154edf2,5488bb08,be93a25e,c847b26,88264cf1,30fabcf,5924bde1,4b9a324d) +,S(e56e0737,a19fec7c,78b9f462,1ec0d5bb,bd6e91ff,ac995f42,202f127d,2446ad96,8830d827,368c760e,40a8d9bb,b693e975,1e69b42f,4b2ed776,98f889aa,3ead70d7) +,S(1b0a6ac4,58abe5e3,63e6dfeb,24ad8a65,56fd0886,78086657,587e63f1,5fb6b101,d2df6fda,e64263a2,b133e5aa,bdddee5e,9a35e86b,2e1f5926,5212cc49,335178dc) +,S(10a14146,8fd4618e,4ed390a6,246d62a2,50bb1676,45cfc679,d80cc081,23ea22b2,3383b868,dd7fdd1a,ecd13dba,f4ebb151,f9a09b25,bc30d562,b033800,fd40185f) +,S(9dc4ab51,5378a351,6db8837e,568afa72,e357f7d7,95d546ac,8a73e419,a43f5e35,8ddaa2d,9bcecfbf,e2a422be,1ea591ee,bfe05ce1,90439a06,cc68d66a,6305903f) +,S(aa93175d,e7a4e1fb,c538eb19,e89b20ae,13539e99,362035de,1aaac76e,3ced7196,edcedb04,c1344568,9f3e133a,d8b48004,c18d146b,ece3da05,effb864a,c2afb9ad) +,S(8171f3e4,da02d9a0,8bb6fcbc,6d06cc6a,94f3cefa,35d4ce27,536ef6fb,222edf7b,e91be5fc,aae62aba,1c02b55f,73c1a64f,c32038b7,a658f189,7499ca59,e9e6dd6b) +,S(51f6c983,c89128e6,635888c9,3c79cf79,893fe627,437464b1,11b08058,1aa19ab6,5d2ef149,4bb164f5,20c1dbf4,1a8dc650,b8cee400,d5e37252,a3d0f059,3881a067) +,S(c0a1f184,766b30dc,6a5016b1,9db0dda7,ec34dfac,74dae580,9500ab8f,6fd7d38a,bdcad3e2,c7b6daf1,29d41051,624d26a9,b27f361e,c695d490,52893597,eac6f01e) +,S(b1bb1ecc,95435169,4ab6fe0,7341efba,fde9279b,1eb78a22,2bd39472,33a0eb02,df523f5b,525342e2,c0cdbf0a,671e0c95,4b149084,de4c61d5,5a7bfab4,c81689a8) +,S(b5cc30dc,86d04ed5,88539ea7,e437391e,3b0891e7,6818c470,1803de7d,640b5dce,f1cc0d9e,45c7312d,fb1acc8,62e03f28,9f55561d,fffe4b65,ca41e62f,42d4ec14) +,S(de2b49e7,5f0ff53,28155b3e,a7d5941c,8cacee23,51fe16b0,da8e940f,9263ccb6,34d7a42b,b12dbf67,b0d7c680,178154ae,4690d5b5,703572ab,74b4d93f,6d8de99f) +,S(8b18f4e7,c129e117,e898404,65870cfc,ea5c0db0,ef2ef11a,d515f3ce,57cc8f51,6b1e1086,c8674a59,3c5e9d6c,dc8edcb3,72281c27,e6b2caff,8842e008,99111f37) +,S(727162c0,27cec888,918e46f1,762a830d,822ce424,b6a5f442,f9e582a9,17c86889,de348296,1452a369,e6fde5af,693e5247,24865623,cc516e7e,8416f38a,2f223cca) +,S(4ae4fc1f,4dd17483,f18eb9b8,1c2494be,946a75fc,a3f61605,6d0856b7,3505058c,d87e7812,e901fc17,da034a05,bd878470,59999b36,e2c617a3,9ae46921,f2563e7) +,S(e90bc9ac,e9e873fe,91826f01,66affd02,72007bba,4ef690bf,58b15206,5ff43cd1,4bc820e8,9acdfd68,51c9b0c0,65b9bfd,47f0762c,d2e56d58,905e6360,4564fa87) +,S(ba0ae6a1,db432fb6,f7a1af7d,be9ef746,8340ba5,7f051020,9af4076d,f51450ba,7d3839b7,4099420,1729894c,51a2c30b,51019a18,c32ea908,c58876af,912be720) +,S(70661b81,f77c6531,1d98b403,ed7b97d7,4f9682bf,2981fa5d,ef882022,d3accfeb,9022b973,18959f4d,9ae4bd7c,fb06fe66,7b4eeb92,5f46677e,4e5bc4e4,a6d06387) +,S(fe1b7b47,28153a07,11f81b81,7d9efa38,29451c15,8d1f11d8,e5e0922,fc471a47,95a075cc,68cfb7c6,fb115dc0,5e4c31aa,85725bdf,2344dfae,19c8a034,d2b0f847) +,S(8acf3bd2,bbaea907,28013d04,f27e3a5c,4325bc37,ec5c5e86,7ab70f7e,9acc3fc0,f679e3fb,36da27d4,f29c06a2,5951f80d,b3e2e0ef,dbe2c785,ee148657,3e16174e) +,S(1d855d37,25fc7d5a,b87fc6a4,7f62ba7c,d2db01d1,ca0f14f,1d6ea8d8,4af395e3,ceb263ac,2d41654e,d4655183,f6268c5d,9b0a9ad0,da8912a5,815dc8d3,20b1b90) +,S(1abb4566,30c24ce3,c84ec6f6,d70d19b7,9934498,451f02e,3926d70,592a8cba,4627706f,6be87fd7,2ad886ef,73245452,1778d293,41229863,f4b19548,74525885) +,S(1b4790fa,672c12ff,965d07e2,44a3f30b,620e5c66,4b098a5f,b86f2bea,93eac036,eed050fc,a758e2d1,f2a2a9a0,6b8391fd,7c19fd70,9c9e1283,1b018d24,e7edd60e) +,S(61878b2c,fc9cc88e,30ddcfc1,2561367b,44c106a0,21e3dc98,a433732a,68de3dd3,fa2454a0,37c279d,1b54cb77,498a9efb,afc6f50b,6b13e29d,436000df,1eaed78e) +,S(84048df0,2767feb1,7bcc21ec,f4502238,abc7271a,931730b5,3354010a,8544308a,d4712e4a,39d608e5,d47f9814,f7763c6e,605accaa,438ccb7c,838c88ec,e993c32f) +,S(eb7ac4e5,6c96175e,c3f1e1e0,37e89f95,8ba37d0c,a88055cf,889bac33,ca683a94,4941e267,2ccc274b,6d8bfe07,513dfc6f,cc07de33,2f517011,2bc3814f,5e85da8a) +,S(48a36ac9,877d4bda,b62b452b,a0288dc1,4cbce455,3809feaf,1a4195af,22142e91,e24d6d8a,1256288,6c6d8848,4e950d8,27eec39c,21ff6e25,30b50eba,ab69659c) +,S(9c3125d0,5a62a25d,7869af3b,1b23a00e,e817b664,c82d2a91,2522ce16,bccca1b5,c6ecda10,f6707168,18417277,4e18f5f5,38566361,5506b450,a189b6bd,39e5afe3) +,S(33e81e21,dcc7670d,c7f3843e,4dc8be3,10160bed,49af116b,c2ca91e6,90f80d68,e694c1d3,a0a386d2,e6df1167,8efe38ae,9ce417e8,9ec05bb8,fa592906,55757b6f) +,S(9543769e,6899e0fc,bfeb1071,50959827,5c1d0d4b,8a68f056,d8e1c033,1b6a1ad2,700cffd,afc58410,7635f148,72ed1ceb,1c4be86,7f668b16,3f579534,ec9b0d7e) +,S(4f41ccd1,73e62c39,7d481e6e,5b50807e,6ca9b163,e21dc203,a0d50826,7439efdd,fbf98ed6,aa8c1972,d88b309b,ab74b254,8fea56bf,e158d1ee,d95ce77d,c69f79d) +,S(4cfb6a45,584b00df,be3fd9c3,38eebc28,a667fe6a,4651bbd9,64ecf20,645f12e5,2ddfd6da,fe080e87,470fac21,d1255900,219638a2,5e72b12f,5501921a,f614652b) +,S(9efb8bec,d9bba33c,a5e217fd,8fae533b,8e536bc9,1817f982,1f217757,75eca626,661300ed,529c15e,918bcf9c,1a7dc3e1,8e3573b8,875e2f8e,9440f8ca,b0658fb4) +,S(c2a80952,5be7e4c0,b85ab953,ebe6dc5c,f5d3c0f9,e850e470,da9e61da,e430e441,1d2ded36,bf72697c,7da6fa22,1c09fbc3,6be06363,d50d277b,4839c4ef,809d9d2d) +,S(42b7ff6b,49ae822b,f5a16276,4c620b13,2501a1b4,1bf830c,a242e02,3bbaa707,e41fe058,83f0e400,712de994,dcbb5a38,fb2c7595,c5ea8b0,eb90a236,82b71d6d) +,S(ee0bb129,d420b641,2afe1518,55f78f39,e00cc3b4,7ee3b86d,f781f0e2,abb0c28c,f71d0e7a,5a4fa247,67c6204b,60edbadd,54b17455,54ae9099,258343eb,5c0aec61) +,S(1f1d8a07,9cdb3bf5,2671a716,26c503c,77546ce4,2a252e78,9ca487c0,78ef5b9a,c611130d,ae55512d,ea8e8e6f,9fbc3064,180ee4aa,63d1dcfc,5c39e98d,97571c20) +,S(5bda9c06,ecdc9fb1,5926ebe5,5418f016,7cf3136e,5f9317b8,b2912fec,d2a31310,358ffb70,dce1260c,80fe59d5,b72eadb3,89076168,a17b63fe,b728dc28,45ecad7) +,S(c32f6503,fa50c727,66652dec,8e0efd71,edc78973,48061be9,1f847544,df866ea6,67234a26,7a13ecc4,7b09443,cb13f0b0,6a34af2a,20b80856,6deb9c71,1fca304) +,S(5483d511,b71feb06,70e6c83f,29612640,849bb673,896bb069,941cdea8,9489caed,a09a6a62,d3233437,40adf0f3,8d8e4ddf,494d5350,7944becf,bfed3927,d88c1148) +,S(3d2d8f5f,f0b86ab9,1ecb9342,5a6cc246,d5e3c6fd,9c43d047,2d518958,ea322ef,4188348b,4c23ce05,1879cf4a,b71d7608,fb45d7ec,a184c509,c739f364,d955b830) +,S(3a5c3939,29ed6780,5fdffa9d,f936bc10,735ddf03,aab89e9e,40b47574,21af1dc0,760b1919,76752916,2ac2a7de,22975c83,44dcd52b,a945c81e,dd8224e,90a7011d) +,S(a3d522ac,7c1cc06e,3ef9272e,fe24a0c4,64886948,3373df90,e5dd484,d4590a83,6f53ba2c,b739dd61,219684a9,50001697,28c377c6,93054795,5661f2c4,ee1b6be2) +,S(ef0b0931,13992018,44078583,62e02aa2,c1437d87,ddb95d42,36751445,d8e8180f,73bf4407,8d184772,7d0408cd,f92f8c74,2173520a,41971980,1b9c842b,9486c634) +,S(8140effd,1498ceb9,c2211899,161185a6,a770c15c,d1ca3e07,f26f40c,6d15da20,4c74f3df,6d2db7f1,be68b7eb,2162f03b,51c1102,a02dc3e,45fc49fd,22a474) +,S(3445d720,8e089f1f,93d32f4d,3fd6fd65,7603c7f0,378b74,215a59bc,ebe122f0,6d41035d,fdb54ef3,3a3c8626,f036e1a2,38da0637,e82953d4,b63e23a4,890b6d5b) +,S(e14b2a5a,6235369a,1d1933f9,7124cde1,789a366d,5fe6ab9c,72c23d43,f7a58cd7,216f06c5,2f63c102,6cafe6ce,58a9e589,d67a9f19,625513be,44744d0b,f9fc8f8f) +,S(6d9640bc,8389bc44,fcd0b2b3,3c088170,eec93106,67348dea,f8f3e92e,2d891e0b,4b4c1485,6e42db64,9fe04759,a42887fc,68b5d4b0,8161b31a,1852bc41,7d04227d) +,S(272f1404,5c461f21,3f67cc60,d7c03b1a,fd028a05,b9e06324,62a0afce,fd9b2916,98635ec0,c0b23538,a63f78d,800eb0df,fd6b7583,31544b1e,825cd433,ab348416) +,S(a8c99928,eaae745a,631250be,cde1ce3a,4152334e,de916257,681329ee,1f3a07e3,4ccc2686,abdf3f7e,8e1149aa,5162fed1,24ae51b7,e61e4620,9f5cd611,e7351621) +,S(fb024b33,7f93d565,899be686,9b1e4c81,1c660d50,fd31cef,fac38600,d8975409,339686b7,8bff3c95,7e8730c3,9457966f,ee562ca2,89d95e12,7b072f47,c4c7fdb0) +,S(e0e48547,aa613549,773ecfe3,691b84d8,a6cb14f9,ce4494f2,35187057,28562f9c,60b6dd8b,56407580,52748838,9396004b,778609f8,69f47676,a6d76eef,dca7b307) +,S(bd6c402d,378b8b53,9f74d29,605e1b0b,ed9e383d,dfec2169,8076ef59,125d16e4,cc3aac9c,bb761c7b,3776a8f8,c8c6d2c2,a276924b,79510f10,75521b22,9def2c24) +,S(e6919231,eefa4f44,144e2c55,4f695235,d5886cbd,e150aef5,52c217ac,5e451c0,e74ee1d4,d34d2612,b4d56133,c2a11cfd,73a888fc,6927f46b,c2aba9ac,63b1cfa7) +,S(1a9acc6a,2a487874,4d92ac5a,328bdb3a,37c481e,8c145463,f9cba4a1,a03d03a9,ba6069a,960e3628,fae22422,47fe1f5e,df71fc81,b49b5ca1,26a7c588,fdf0fb10) +,S(5b52bba9,2e5fe301,f2c4e939,52db99b8,abfde642,3d6da8d5,36ccef4c,f6070910,108ddbdd,901e227d,118c68f0,a71aed0a,cc1ab1b0,2fe74341,f546ede5,b747ae29) +,S(92c13760,1ebe82a9,b11a096a,73be2828,652b0a4,d7f9a286,f1338a6,b1e05242,2e3e93fc,2dc6d0fa,5d43dd57,85f6c79a,51a588bd,d14e0275,59fac06c,a449d7c) +,S(3cb6f8da,79964c17,73a1c749,e89542bd,94b4f279,f6061d69,a12ffe5f,1d4318b8,42e4c1a8,b4f45ad8,dc23bd02,faee2956,72a77771,6e6b1d54,d05ba413,6bb11956) +,S(5fed6351,d34518dd,111a5110,50de0e5,3c60a14d,9a80183f,66415145,bdbf5db,6b79a590,de07a4d0,b74140b6,49bd8375,da77e01e,295e76cd,56a6588,7746c3f6) +,S(2b88f0a7,81c384f2,b7c245d3,7c061128,a14132b1,fd0fb56e,7d3193e3,d95d3840,f787e7a2,11446e57,655b6453,c2244974,c1632bb9,4838a981,bd4873f8,89a0e10e) +,S(c7b247b1,5a3f55fb,35b0ac3e,1da36719,18507f94,e988efd2,47bb02d,83293443,4ab40437,34c65f11,236b6ac8,bc27c548,c3c8e5f6,64f3cb67,99e7b8d0,6db85f4f) +,S(ddfda933,8dcb9481,5c08a20,12c137e0,45df69d2,121d4534,4c6aa375,e03647dd,e95f79fd,2a116bd,5972e93a,c58712d0,95f91255,a46fa091,bbcbfe5b,57795c1b) +,S(dc8da645,5084b105,6c7e3233,b247e87e,9d15a6b6,677f8c29,da04fefa,371da7db,c2a345a3,fde3ec03,f6a07fea,8bd7685,8fc66d28,6637cc80,93132048,441449c3) +,S(f53f3b26,c5fcbfa8,f1263bc7,a6439056,a31547cd,3a8c795b,8e355482,d1ff5333,113ed45,e664b9ca,98d88f1d,a17c4fb3,5249e8ec,7998b1d1,bb68be3a,e6716ac1) +,S(648d23fd,c6d4b5e,4ee1d647,7d969df6,7d754686,9313ba39,1d89dc90,b646cae9,d035e045,239375d3,4e6ffbd4,bae0697c,9b336454,3261206,15edbe28,3e18962) +,S(92e6dd0e,5dbe580f,82473f3e,dd70b343,bd51bde2,b1ca91cb,1c483fe1,3c2839b1,cd90dffe,a5447bd2,592d1a46,5a09b391,a61ab01e,a10c9201,5ddf4614,b39577a5) +,S(1315e58a,7616ef8c,fa223ec5,49415a54,eaec0583,6be6fb78,2ef4ee60,f49f687b,729e0100,802d60cb,c54e1fa4,5dac72aa,2fe189a1,737da80f,1ac58426,d7e1431c) +,S(3c8a9799,9857fd85,e26b284,a3554e51,86b001d5,e6d075e6,c9402148,ab3e2a3b,464f0492,acc720a5,59487b3d,60502067,a722e915,a10412f6,d6c69dbd,28b25977) +,S(ea417230,cc94c5f4,436b37ca,e6f9ace1,bf3c7f8,ff03c879,f862ea76,127591c8,961238cb,8d95d50b,baccff1e,b9cd4040,6f4ec475,7026b3ac,e916067d,85a4faa6) +,S(8eccf9c2,f271079e,329a8c81,62c98af7,48496ca0,b0c5840b,ceb19a15,361a6ceb,3e259a19,165bf1aa,630c6a7c,52f37b29,c8ac5239,a132fa5b,b53d687,b17e56af) +,S(32f0fc83,b3503a59,6873c34a,b54eb6aa,7bf3d913,842cd556,77f398b5,4f0f296d,d4736d6d,906f78b7,62eda345,9cb5f7b0,311e50ad,cc9a1e26,655d8ca2,fb81a811) +,S(b7d63110,77c83a8f,a43c171d,a5ff7cbf,e4fa4cc0,b2614a9f,63831836,e0d7accb,6095f640,56441552,a8ac27ef,9c1eba64,8b84a5b4,c19237e3,5e285ebd,796be9de) +,S(ef6c904a,22df4fb0,a54cd74e,6563e56d,588b4f8,d6926cf0,6c32694b,be536954,308910b1,44cd37a4,e5bc3d3c,43715e22,aa7a0492,e0e9cc9f,b1095a22,65dbaa4) +,S(19e13bd1,e62825bc,acceebf0,b48e17fa,b375241e,6eaaae27,672d7ab,22941a6a,6f22c329,7005bc1,155308bb,dbf8ccc2,855ea666,e4af3bba,d3e3c90c,28b613f7) +,S(57d9bcdf,10f2f790,79349ae4,5f2980b0,9a98a7ab,d792a5df,967b7b11,1c8e9420,bf665de1,d9b7854d,e34f8fcb,1cc027b1,42ebfdf5,bfe4e65e,b5068a72,9a65db68) +,S(37bc6685,7c3d5e8b,878874e,3d1ed324,bb530a21,f13d057e,4e3f87ae,3df06b2,15419bdc,764db12e,f12abbea,c1ca7bbf,77764abd,72f5eec8,3a81c452,4c998539) +,S(1b30c5d9,9ca59151,33c012a5,96512c2c,b572e11c,a7412138,7f3658a9,f9c2cec2,dc42320b,2a0dcd0c,5404d842,17af8c9c,2344f751,16a5d691,1db0590,5ef39697) +,S(96831db3,50c55ac,dd329f4f,85ad4a5d,e6e89f21,85b93e65,b8db4e1f,c1efd0bf,86f43820,fd03739a,d0e75ef6,17072f2c,82bd8bd5,a1f8cef4,55e49ed9,cfd47837) +,S(cd2f500f,aa1f04a5,58309f28,f7acd542,bce7999e,a17cb792,66b93cd5,44e3d8ad,1f977080,ddfceaee,97c743c2,4815f795,27dd1b05,63ef009e,92994046,c8dd8c29) +,S(60392a7d,237c9e27,a3318ff9,d3552928,802f519e,60a783e8,ff32be17,4ad01c08,eb7f3147,df91d1f8,d8994afb,df297c44,88ae9e1c,539fe065,663d856f,22893fdc) +,S(f6cf77ad,df6ab73,20d68fb,9f3c1d7f,d8abb679,179b3c90,d22574f9,fa37ee9a,8ffa29c3,3587f716,6b5d513b,7df76311,77e81eba,1cf9b523,280c778e,2442ebd1) +,S(57c8015a,f542c514,595b6f4f,f11be2fc,944a0ea2,d26a4abd,1807142,da7cdf7a,b67c779e,80153cc6,7b6b32d3,3a3754dc,ffb692bf,d16e3e3d,2c9c673e,a8b05da9) +,S(7fe08558,ac184922,ffbd5c51,cae99931,2f58a17f,bb643b4b,fa1e419e,6b4fe462,7600477d,8bbf58b5,36e7e9e4,cd595858,7268cb5d,1599079e,5a88fbe7,79ec7a11) +,S(2e16f56e,73b39bef,d729b87a,d8e7c4e,3d81095f,58be177d,87bd9f3e,dd517b75,4ce271ef,57323a0d,baac950e,668f0981,77aa59f0,7a0211aa,69b4e417,375fcb7a) +,S(a4d4700d,456d7802,be781f66,6ca24a68,49200de6,d2dd97ad,9c2eba62,18ffdedb,c099f86d,e7ba0f0,e8f0e762,8864a4d8,9124aae5,af12f6d5,efed434f,c66e4532) +,S(b4764d50,50119e3e,a316c921,91e57ae5,a2327e74,187f145d,c048c199,db3fc059,e39be8fa,cc272129,3ec831ea,9016a188,4f127070,4fa4f092,c2f3d56a,4798653c) +,S(3e686ba7,d291abf0,ced5b352,e84fc696,c29fe123,aeb82235,5031931b,e7e2d0e,7b35c0ab,7cc3c81,f84caf9a,9321b9b8,5a889b07,98c9eed8,8c7dc4c1,a985d266) +,S(d7886f2d,1d4c70ef,c5961e56,33122317,58400105,288d3346,db49407c,d24a46c5,da645ee6,17c46024,b2e25903,d4d7dbab,c5ef503f,814f23e8,68d94040,54b9efc8) +,S(7cbd23cc,14654d40,5aa57ba7,1e375466,cea867f2,325db475,d3a7990f,ba17a40,eddce5af,96e66db4,b985541e,e638ecea,88d327f,edd37039,54ce5a1d,d2dcbc51) +,S(54626185,c279e1da,eecea0a9,233c2190,18f877bb,58614a5c,5d2b9894,17eb9795,6507ed85,dc8f8454,bf96730,5cfc7919,8cfb07f0,dc64b09d,928d0b86,e0e9b6f8) +,S(edcef155,1cbec2ce,2bedb20a,addabefa,59e68cf9,e2200681,89285c08,563c32e,ade67143,75592853,c296ab45,bcba4db4,bed59efd,9df68b33,b03d7a3d,be753179) +,S(e027a953,ff6ef9d3,f27db47f,bc91db7f,6a30bc5c,c834add9,9cf8d086,23380cd,1e6b244d,e18ad020,8e52d174,ac452a81,62eafc80,975872e4,c7e362da,cba2bbf5) +,S(a5006d68,db980242,54ea251f,3787d527,66dbf92c,aaa20960,e17ac6f6,72e2b2d6,a1938d7e,e854dd5b,94d98766,c0f74723,72d1e6df,5cd6dbab,fa63faa5,6a0b2b9c) +,S(327075f2,1a1fd9e,da69adf7,32995919,dbb02025,ee504e0,3d5e5066,8427be11,41a57eb1,c32e94be,948ee335,6d855fa2,611a4ec2,4519adf3,2deab381,6bc4debb) +,S(97e1a5c6,66694bca,6b10cdcd,7e95f74b,9c87ac04,c623799a,c1c7959f,1a3363bd,3cc9a48d,1ec7561f,7b72bb6c,4d671c25,56689498,42546a9,48c9b927,c8ab5e88) +,S(450fa640,a7374dcf,d11bce28,f4eeb4ab,d0a2d868,9f6fda04,7f790ed3,b0c07a21,eae88298,dc17cfa1,d482a1f1,70d1dd36,aa35a56c,7eba231f,c4c3ca16,efa77f4c) +,S(f5aa7340,fc0a66a1,2da09ce1,f4094240,d81fad91,87e944a8,a7a1ef4b,9e0a6559,1255b3da,9ef992f1,c62e7738,f84dba74,899d9810,9db522e3,49ad9fc7,2aeb5017) +,S(6900965,55197836,a7b23841,97fbd75a,8857ac8a,8b14ec8c,90cc94a7,8a42f1b4,1dc181d2,38c976d,b4627107,2be05f32,952b5bb4,e9ef4710,f1bad8c,171b027b) +,S(2b1aa05a,8ed84136,7e99f377,bc3760c3,bc3bc0f9,33555e87,8ff2d212,c3f290aa,47b25af4,1eb8bc31,915f5896,57f368bc,35e9000a,cbdd0a41,7b267e58,cc13e280) +,S(a4e6b69c,a18caff0,d993540d,3005e5db,454b1e39,d4c81a7a,b5315d25,d052d81d,7cff2103,9c587904,a42d78ed,c2e7a6ec,df4fcb21,17c89822,36fadc01,a15d70c5) +,S(ab44bb96,c74fca4b,3e39cb0f,d9dd7795,f728e1b2,80a7cfa1,7a36916f,b39d2582,59d91ba4,519fd8cc,9e773feb,b1915967,7edc0dd8,1e794ab7,cb76a2c9,9026f5c1) +,S(83b0c85b,3fb9c3e4,8c96a31a,e5442288,93472975,5d42fcc7,715dbc23,9de332a2,e99f5640,fb620582,fd833b34,2f086800,9652d739,2d6494b1,e36d301f,35a6da6e) +,S(ea45313e,624ecf81,676911ee,500bc0f,e5bd10f4,40e04788,41eb215a,ef954537,4ab8b00c,e2359cce,203bde53,b9e8a454,d5afb101,4d0b644e,81ad1313,6c0c7445) +,S(936c10e4,af823d96,9f7f7a26,98c927cb,ae6d609e,37cf7412,ac4cea1f,51a3cd4e,46f72bbb,10dd850b,8e3e5bdc,f0359f6c,bdb9067b,13d2b60,bf68e8df,b17b7213) +,S(436a5d5b,61aac3db,392cf8e1,36a89b31,847bb116,5d1e296b,36c90d60,f2e9bfd6,f81e688d,ae67cacc,1978559c,84a90f9e,5e342bda,e73647e,33655686,2f36d68d) +,S(9eb95427,3fe789a1,3a24b929,e54f6262,d931a442,2e61867a,abd84d80,4b315d7,38bfc192,7dc0e640,820fba,8effa82a,d29f204a,fec11c60,768f95a3,4d2ef59c) +,S(3826b6f5,87ecbc0a,cb6b4328,a00f63e6,ecb77a0d,bda277a,e6e4ba5,fa280d8a,d9435fe,dcefe69b,213e6eb9,eda63f89,db35e293,8ba3d6e6,57232f04,3a4ef271) +,S(a348cd11,ae0ea1be,3f993bcf,84364b9f,4dbdceb8,db3cca21,cd0f8ca2,4a1dde2,1fc851d3,db7cfaf2,6a1c202f,212b68a0,7078ebd,6d6441e9,1d1d4884,1c83ac75) +,S(bfe15639,237fdf3c,4e67646d,724264e,5d70d1e7,3cb70205,3c4e9a06,2bdf7329,902b37e6,1ec5e59d,9c3c09d1,d7767483,345488dc,e492e3ad,f12d04f9,2b5f88e4) +,S(e2fdb14d,81a1b6f4,d40dc346,c8205821,2642ae10,2707e944,14413cc9,c03dfa5e,3011b4ed,846e8551,6c66925a,e7676062,131e37b2,9b00c408,6c60a3e2,3488fceb) +,S(bbc659c6,8f476748,17663659,db4ac222,cf1119ea,ac27c38a,535ddec6,913c7416,1f8b6ee1,9fdb512a,fadd13a4,d3fe13b,48250120,975b8c7a,47798267,7954b954) +,S(65bd2a02,9866789b,dbd6f743,af85a789,ce9141b6,fd9ee056,cef4de8d,a2505521,32dbe030,1cedb7bc,5d5644a4,6c3e6c56,990b184d,710a770c,6b65f39d,3378f5a5) +,S(1ec0e6eb,8382cf7c,24d75a49,fc0f3724,e9318d90,9e05d406,a3a5916b,2278e981,e50e129c,f486bcaf,eac8ade3,c697debe,fa56ac06,337cd9fc,240cfc2b,3415715a) +,S(7390af1c,203da259,9e1aceb1,ea101628,c0399c92,33658d9e,10dcb10f,63a9eb8c,7d215496,60647b09,d7bcad45,1debe7d8,2c3adaa3,39bce418,320e0df0,977c3126) +,S(99a51469,7b913764,783ff7f3,7099cc45,127baf1e,d8931eb2,b4b71e81,6a1a533b,49c0d00f,7503770b,fcbd57d,bae748fc,809d21f0,8ea38d4c,8a288063,a7e2e8e4) +,S(e4d6e0b1,3b4804cc,cfb7dbf,ef1b7026,320ba2e0,c4fc98cb,f12fad65,8a0394d9,aeb0eaac,73a006fe,6a75ad20,3e0ce2fb,af5fc3dd,81865b6c,75075d36,3b761a41) +,S(488a4141,507ce5ea,cb3e1c46,ad23fb3,1a9aa058,2b553459,d885116e,19fe1a04,6bd6a066,43ef8c7,4cdeaf25,ead63b04,e82f8073,a5fd904f,d7235f4,cf12bd12) +,S(c0ffe24d,ed0ca54d,1ad1c2ff,d2dfbac3,2cb65b47,ca42e8c5,5d2c15d9,67babaa1,d15cc63e,29c54df2,19dbbba8,8df7011f,a0a330e1,6756567d,bbd7c6bd,7e7e9289) +,S(336d9b02,6c74e25,9dedd36d,d8fc5ef1,31b05d0f,f20bffb2,8305b923,767780b1,4aedacfc,9886a707,aebe6510,e1bdb89f,2b1b6461,1471fd1,b055e7f5,414e647b) +,S(98353eb9,8973a7be,3bbd3711,dc7b86e5,9a2a175a,ce8464a7,6aece2d,2dcf04f,a877fac2,27894a43,8f610887,305e1c12,8e45b4a4,3d6c596d,9807461f,aaee767e) +,S(cdc35e1c,17fff9df,63639cec,b54fcb0a,71c9fb77,c38eb905,3f37c361,36da1e61,a8ccb6ba,fe917260,df64f0cc,dc14a31c,87ae559d,7d629778,2bb9b668,9494eace) +,S(912cb1c1,5e62a0b2,71458409,39c06f15,5d7407ec,526ccb5b,5159a934,80111941,584c14d5,1723c447,cd0cecc8,6c70dda6,6fa710b9,8348f5ad,bf4bd587,37049bf6) +,S(2145e17c,7c1e8acd,99eec6e2,cff40341,ffd19568,9800d02b,5ddce693,c3bff3bc,3b8a71a2,40c0b373,95b0e9b8,99da7bac,a5c43088,afafeb68,957bff4f,7636356f) +,S(e4a09336,7e877272,2224f7e1,d03cdc85,43e0910a,20bfc4ab,3aa2ea94,8d0b1692,24b1ec31,33146f03,8eeb8315,afa6e34e,898f48dc,af7d0f80,328155f7,c2cf846e) +,S(fdf526dd,464d459b,b7f387ed,46402875,2b1390d8,4006ebb0,f579b36c,d328db40,4396e6c5,679216d1,dd2cf776,61264ec5,9373269a,a745c963,14147c0d,e53a3987) +,S(6c85c16,b3e37273,509933eb,caddf3f6,52ca4c49,4e751da4,fab5bfb4,ec729f86,9b530fc8,520b807e,5e649040,c5de9929,e592ce99,1b9f9cf1,21766f16,eb648d6f) +,S(4fbfae3c,596ee2c0,10c98ce4,bde00cfb,4e7da2,25583203,feb0c791,2ce28e58,fecf0504,ed0e364b,95edcfdc,ff50fd62,396b8a65,83bc1799,3e73557e,da6ff099) +,S(9bcc3b7b,80171179,3b683c2b,90e9c811,97c1d7bb,d3c281fa,1503513e,778bab8,da2eac92,878289d1,a77825ab,9859baa3,a887f009,d7d8be9f,3b70b917,41bc0b43) +,S(4415a040,e70a3b3,f5a95695,672d1314,855b0a26,3b5e3c8a,24e02f9,6b635150,d8a53b8f,cf55a9f8,81e92160,39afd5c5,6843ac56,39f3223e,c58a5869,da3986be) +,S(55e759c9,cdafbcf6,a38988fc,be203839,b617b536,2d537092,4d2084b7,45b2341,4a6933ea,ca8a3405,89952483,4a231585,3c1191b7,42eb95d6,cf7f82af,f931bb95) +,S(21021f25,bee23c2f,a57e072,bdc83e09,8d115358,adbde4b9,5ed63488,5540e9c8,9aef5691,a7700eff,7c42c98f,8dc822a3,4ed8dc1c,7f8648d4,ba5bfe3c,f9a8c9f0) +,S(2b4e311d,dded1aff,edff3c64,10d40b8a,c70771ef,6904e4a7,a28c7982,cdb376d1,145c30f5,6b255b07,fe43d02,b57f5b96,48b25dd3,6c792575,d20ac730,d709b05c) +,S(5190b21c,7e166100,c90dbf5b,e05d25b6,5ed91caf,904b091e,8b98b5f4,5d5378b3,b83cce47,1fbdc5f8,b50e3f26,8be0d540,1826d26c,216c1166,4040b4a,66650073) +,S(2b211ee4,54c65c0b,3647c7b2,87608189,88b1b009,77d016ae,1f2f4030,545b56f7,75743959,17d8fc1d,571a2563,47a61288,fff74669,b863f506,f9b70ddd,76854f5c) +,S(cb30b792,b41e0aee,3478ec37,ff6ba66f,a3caad4f,9418e1b6,d4af94ae,e64134d4,45571ade,cb3a9f4b,922b8b4e,c0d1c728,9142300d,daeb08e7,71b1aab6,228358c5) +,S(f4e437a8,d2fcaa16,e9749d07,89be67b,e4687952,7eea12e0,65c3cd32,4e4bc6c,fb52d28b,7e81ae8a,30de51f8,bdd0ee28,8e7647fc,392249c4,3449e62a,77ba97c4) +,S(a0a676a7,6a2a19b3,bc6a726c,193d9df8,ce85a94b,cb678080,545c53cd,df50d518,647fe8c6,b1b7bd21,b9816e5,aae40700,41198d68,a3c9bfe8,e437fc88,8f190a71) +,S(15dd4fea,d7f39428,b10544ab,1eaeeee6,75a2ba5d,15d8971c,7860a5bb,b7ff7b7e,89955ddd,5fab2154,7d231342,7b7322d2,53924d1f,1b1fa961,8442c471,9c38445c) +,S(a806b800,40294b47,6377a188,ed74dd9f,1bdea3f,f72cd2b8,850f6321,930ca522,4b6d7365,47d8b1af,697f1fa8,8ab3bb86,53e49aac,618910db,9c6bedc8,deb97213) +,S(41e3723d,ca086487,7a36ff9f,6e431ee8,58a983ac,f3c0406d,f31ba3f5,5b9f148b,8ab166ca,f27c58d0,1a80b136,dcda9fd2,2753c52c,dffca007,9139481d,3b8392e4) +,S(63b8a0f2,78558c89,d9ba3e58,70946615,690e0447,f8d4c953,ea00bca8,65bba3c4,321fad41,85eb8b49,53a95da0,f004c80,8c09b297,728b3a0c,2d300b32,43cf787f) +,S(62beb7f,aa8b0d3a,505cae5f,82229a61,c1ca21da,d2ff856c,8942a9a9,b14c5963,e3d9ccbd,7120c27f,5cd88655,3efdc43,a36f4c02,2f5b7045,1ac9d7bf,56bffd4b) +,S(b75a180a,f524b89e,be5d79a9,92f0313,bc133fcf,3cb2d99a,c65f2c48,1bd20427,e7855056,b11cc054,d37094b4,1e62dfb3,6a636964,633eed48,c39b8225,4a1d2747) +,S(4e5bbf6d,5298fc76,97ddf9cb,e4d063a2,6b51f93c,eef032f2,f03eed04,fe4949e9,66702686,40cd9dc6,54514a19,ecd80930,1871fbbe,99254119,476e44e3,16a12188) +,S(a9778c3d,f509f069,3baedb83,6d5fc1aa,b78e86e6,dcb61200,74bf6df,c173237,33a9c991,86a0f913,95fa0e50,d0a85d65,9230a41c,8c0be5d6,90ee013f,29d0cab7) +,S(f1b3aaad,16664be7,c49790bc,1a4936ac,757fb3e7,26ccbc95,cdb7bb63,cf570449,d1dfe1cb,ea3fdc10,3f218398,14626782,643426,24d3aa3a,52b0fb4a,7460cc06) +,S(d66cfd3a,b015d585,6a436ad6,a4cf019d,9563a05c,af4ce2d0,6988a4c5,9349f598,5ea179b6,d097d9e5,663b7305,6db940f8,d8e91bbe,fb951756,d07cf6fa,111efc4d) +,S(a532a4f0,924b5d13,bef0f30a,a982edfd,5d87a16f,2c0d8470,ea8fe3bc,da0ac7aa,c2e62c19,ca4e3481,3cc3de70,df50386f,74fd1efa,ac6217ad,5532a927,1f8d5c1c) +,S(a9ab2512,5df78835,ffbd08c0,9e07b632,81ebb3ef,3fe2fb3e,1a3e5ff6,28439b70,58ff55db,56e015aa,9aa43698,acc35df1,f2eaadb5,4e950c7e,3501a5b5,85877514) +,S(ce058f84,90813dec,c184dc83,915c6d5,53df174a,41ed6521,f2cff46c,460466eb,414d38c4,58817414,5a815a7,84f4f71a,28237741,97b37d47,c7646b2f,8af3e745) +,S(991fab65,30a2b36a,ab385c7f,31644de9,afe9253,9db603d4,737beaa9,6e406299,2a29b576,77c544bd,f156dc9d,44da01f4,5d373cfb,7ada94df,4f82af9f,e48eed57) +,S(ee6cc81f,bd034eef,cc841921,5ab4817,ddfdd2fe,a13f1e14,e91c3f2,af715d8e,b8f79ffe,48c3e965,21c7358d,ea5cbc04,df8fd847,a97bca3f,6893af3b,e386d8be) +,S(66a2d372,d6426657,5544d5cc,5141e003,16ff2dfe,813357a3,c5daccda,159c5ef2,b57d2d6b,91c6f48d,389423b9,af265e04,780000d0,598229a0,5bada3f7,4dbc8929) +,S(20a02dd9,f697de3a,15043e73,fc7f36a3,7a5798e5,acb4cac6,adf5c692,3a421da9,1e6cf100,d162361e,aa6ab61e,711e3dca,ab4ab538,2fcc6b97,33836c30,cdcf34f7) +,S(a0b8ca43,7818e81f,6be98b15,4da25331,9f92b79a,1ceda110,92e3a303,cb7bf552,4541bceb,f447d990,50663ca1,10fce2da,218508e6,48b630ba,a1abfe5a,3d543be6) +,S(51714ead,73dce488,7e15c25f,b5cba9cd,e0d5018d,db5b8ffb,9e4174eb,1cc52c63,47b794a0,82ef561e,bee272c7,d66dd201,a5c24831,99977097,73b9141f,9bdafebf) +,S(18ea2763,1fe4de07,3e7c41f6,a9921e91,7da195a4,13417a2f,ba74ac2c,d6451c59,398a0b37,fff6bba9,b33e0428,e8d7c93c,d31b3b83,2e955e6b,106aed50,d64df316) +,S(e1d58b4f,c39e1834,a61ec341,acfa985f,c3d1f0a5,9d75b0cd,e8b9057,17c5a87e,1b62ee02,15fdfdec,8fe2ab3,bb7f99e5,af82153a,dd9c7f2,cf299225,9c6b3c47) +,S(39793917,30d3c125,7dff5ba8,eb253dc3,2c19c541,11caf9a3,bbdec3e7,716c5a84,d6a1fb50,189f36d9,912cded5,c851da8c,be7b4ebd,41c2a1e3,f78aa4a7,f5f18015) +,S(49b49e4b,601b406d,381dbf88,8b02519e,1d57360b,24f2aef1,5520f17a,5b9ede88,fcf3ccca,2f2d7b3,59be7be1,9e45a3,a0a76e9c,d0e42fad,bff7e772,f969a38d) +,S(2cd8190d,b42f36d,20d88548,f0ff17a1,d64e38a1,2241e4c3,2bfdaa45,28bdc871,f729c369,22141490,5aa84f45,e5abfeae,2fff780d,2b16aa67,77ef59b,68259187) +,S(1fd0fb11,17385466,2da0cb2c,f1f9d19a,b5b642ea,45d1c6f2,30808626,5e41025a,3136a688,fec60820,abc7825d,1c7012da,94e928d6,dbb6c08f,5579181e,469ce0e9) +,S(f08e5f3b,d7f8b5be,18648a0f,5bd844e5,3f93d5bb,120d3871,7de4440,7af3a141,3dd8725,9067eae1,cab61bdf,cc94ea0d,bf7ea1bc,df1d289f,a526e15f,d9902fac) +,S(a0033c06,b997fa96,373a046b,b5c6bdd7,a0584cf0,1feec5a5,d3f5cab1,1c5ee207,eed61931,aacbe48d,708c2cda,2208d40c,39a577b6,3d4ffa17,d140a8db,c3e268b4) +,S(77deec08,68bea671,df01e29b,117791a7,83ff8f70,4426bb1e,1ea91b6e,62c16f70,b908a228,ba8f73f6,3271ae7e,f19f5e9c,fcc1fe27,c0a224b5,dc426b00,5664861d) +,S(2fcded5f,fe2f10ed,1a1bd1fc,63506b3d,994a03c1,c188d960,5fd5aa1b,a9aa72b1,155bebf6,f09a86f1,d20d7c12,e12a0c66,b4df6628,4ff9d45d,3fab7d76,6bbefc6) +,S(1f0c0b2d,fdf5e733,abcadd0c,9ba47c09,8667f8ff,77c2a904,c8310e20,995db3ad,bd711bcb,84cef55f,5139b761,33268489,70f63182,85ccbe44,8efd7566,577bc566) +,S(b4a8544,e7162c44,60dbdf3c,5edf654f,d603fded,4aa885ef,465ea8f9,a37dcf8,53c04391,b3f2e8b2,32e27b,2292cb38,99f8ee6e,dbe1934c,13938a3d,203c62b2) +,S(df0ebe82,dcdeb735,38f31cdf,ad307397,d00a900c,6d94221a,9d85b0b7,2c5bd68c,c3299639,e7fe2e55,447b869e,3a4acf8b,4a1d07e2,d70701c6,8a2f4733,88decfb2) +,S(eb04b9b6,d1c38c33,e1eed101,fd28f89e,f9fd460e,5b379576,ec7c9267,3c101c0,4f26d849,7f47f80b,2b13cab5,782d6e9c,f5ee7548,3974a4eb,8d8f28,f5e0ee9e) +,S(7bc9efe2,197cc6ce,ac94b37a,cab9865,7db4ee0e,ea7b9cfa,ce9f71d0,d3294334,d931bcad,52347906,a941d940,4b5b3a51,ad8fb493,1c15c9a3,7ff782da,5da72013) +,S(8922d1e8,f4bd52c6,4bd0c10c,66a3e8b5,1321dc50,cc964844,e0a41ad3,b73e0b9b,2b643cf1,7d23e21e,890e6abd,3337dc52,61c9eec6,d5edc318,2a02a7a3,4a41c431) +,S(42f2ede3,3a9312ed,22f6a842,ac46801f,139a7da,77ca0e9a,cdc19d1a,f2ddcc72,50d45bcc,715c985c,b9260edf,fdc8e342,ab95360a,6bf4776a,c70e3497,8f26f99b) +,S(7bdc9720,1862feb2,58879255,726b5e4,627549f2,92936ea2,f3b27051,4d6761c6,700eb72b,7f77adf5,76e6f0bf,f8406660,65372ee4,cad6269,f1ca8541,2da4fa8c) +,S(b9b527a6,4bf549bf,5e42e0d8,5228e1a1,f79d1647,d2102306,6b6d98e1,746314cf,8e1b3464,2a721f5b,93a2a2b6,802f30ea,e35b1539,c6d84eb7,499299aa,aa0cd93f) +,S(b65de529,34d47765,1c29192,93ce1177,d187c431,590d2d74,978ac258,75e3dda9,3d6fcbe7,4ab9b5ce,b3dc5535,13036457,f0755509,ecbd94ef,324e36d6,3b9fa529) +,S(18eab632,608751e,af3604f6,a3f05611,a036edea,3405aca5,c2e66366,ce7c6b9b,89eb07bc,94671119,36e11f05,79f91e6e,ccd42605,24bd7dd9,9d12b365,95074c5) +,S(a2611066,4a479643,909a1606,596d39db,c7502ee4,a31b40a1,4eb1c60e,ead360d5,4b45d74d,88025576,3262d9fe,38198218,85721a81,f323cac0,3e87f372,75814901) +,S(789454b1,2c108537,a019dc58,35cf25c9,c77ac0fa,f6001959,5da9435d,3c08a8a7,6bee870f,ed2859fa,cbef4337,8a0bd760,8841da03,252687a2,591ae0bf,a5829041) +,S(1977c206,fb4f65f0,11b683b9,c2e0df95,f81570f9,9f6625ed,7cfe25d4,62791569,de76dda3,c22244aa,95ff435e,5a9ebe05,9dcc79b2,75d91de4,67de435e,bf698479) +,S(891f0df7,d259d536,40fe6086,1ac34d7d,ec3b5ad4,c3f56585,189ac986,65f4222f,cc5e0bf7,f538a2a,1ee7a601,1a8d6b0e,5c3293ab,404257d,ba90ace9,1b2de219) +,S(8534bbf6,9262f81e,5926c282,f412b4d3,50169de0,3c5c5e55,c80a937f,fe99530b,fbeee581,e0bb0737,4cc764c0,be5451e8,f70cfc23,4d415cf9,fb08e7eb,557423b5) +,S(e5b6f564,4e7dfd3,7474eafa,354598d5,58fc897c,f010198,9e44b07e,a86f63fb,4368bbfa,68a83a8b,76de7d98,38880780,8e153cc9,b380ad0,b2c6ce26,6118da79) +,S(f9591a8b,11c3e514,983dc5e5,507247a8,46e184f3,b4e38e29,f7c90d4e,6c2b850,423b6436,2361f587,cca4e288,a366a1fa,957de393,f29ff2a5,1fe97a0a,d90ff6b5) +,S(3d3239d3,252f5e9e,ef9eb617,c9646379,7c995059,57bc7821,2f2920b1,ff72384c,1c3e37b6,fc9bafac,e52798bf,695eb4df,ef860ee1,a9b67df7,8f73ca9f,22a2e57a) +,S(f4089723,4b574d76,86a8e855,408612a2,a0a6ce61,c1f14055,201d5c67,bcc5dfb8,6b8283b7,3e72fc91,54aaac24,2565a79f,c3a62fa7,602ffaf3,c7453209,c0a56a4) +,S(ace076e7,aea9c745,f6be65f8,498b8b47,95058ed2,b0413c64,bc4b462a,2e267ccf,b62c617,377fa9e5,eb72ed6d,caf353e2,dc58f362,a994520a,31f1dac1,168b97aa) +,S(70ccbba7,408c6069,3230b848,eadb1d1d,b4e63f33,b4fdf6af,29d6fc2d,86ec161,fc1cd9a0,46d30e60,e4128677,654a80ca,5a4ff338,71fbeec4,d7782c7b,a14d6959) +,S(e6e7a8b2,7c0c5b0c,5ea58d3a,4af5abc5,9e33fcb3,9970aede,7a8de629,e758d372,d40d11c4,c8c8b5a5,d511fee2,793e2c80,b40df3a5,c98bd704,9a8db3e5,c98d4a66) +,S(cdc495c7,e0a02e68,329495b7,19e2c424,7910e9a5,cff6739,117b1d32,23216346,63664f6e,9306c0ac,f29ddcd8,7f1df6ec,d51fc68c,6ce422f0,559205b1,681583d4) +,S(2784e89c,2fd721e0,22ba33,3b824dc1,d0142f19,6f35ae4f,825975d0,7a2fc5cc,ba58a66,bdfa661d,354232b9,b25628f4,5a391e44,f00841db,4a335ef5,dc3b8cf4) +,S(ab699b62,ebcb7380,2141dd83,184ba3cf,c9118bf,f6af4d0b,9b98ecde,b01a2390,5e548210,b71420f6,c5d42547,da0a7ccd,2be0117b,79847e71,a609044a,34766905) +,S(781ea7a5,67ffe37f,b9fad6d3,96dd1eaa,2209552a,9835ae08,dda3d4f0,b75756ec,3c76d87b,46f63b97,e4d48174,4ba664cc,403a507,dacdf4b2,af9505a0,f2637256) +,S(75ab2d30,dd5c0a82,a5c04fe7,b8fee5a3,a0e1ce3b,e20b33fd,39d0bd3e,e374029c,aaf46147,fdb1393a,cb9f6f8e,694c1cf7,30536efa,b5ef921a,72215fcd,61914b9f) +,S(294b6698,37303da9,6d23caea,684ad56d,8712433,d11c7ced,85a10cf8,8ddaff0,af4d7ef7,feb73e9e,a9407fa8,b38bf1f1,e5861bfc,82f9cb42,22fa64f7,9b46f7c1) +,S(d8676aea,7433639f,c9683b06,bd97011c,f290f6e9,1257ee55,ea3c6e34,b824c8d6,710c8876,35d45545,90f3e5c,d6aac133,9017b2a,de71e30f,d71a5b71,97a7456d) +,S(5e4eca03,d90f5ac,2ac4771c,6d86a458,cee71427,a93b7544,fd8bee74,161270d0,44fe0143,b970f8bf,affa6d60,33628894,a93bb4a4,f48cbb9f,f0caf0b7,40c97351) +,S(90152daa,244fba85,fe708f21,29b55485,265c3a3d,dbc761dc,157f125b,8580097e,1694d2c9,200b8690,b59fa3b2,8fc2f613,8a6d392c,48357939,b9435739,83ef2cf7) +,S(67dd54f0,96f171c4,53fa953f,acbf2b9c,daf3a199,732ee0f1,91fb3c90,8c5637b5,5327db43,2d33676d,b6502236,5a338c62,5fd6c4a4,536645df,b36279bc,4ede74b1) +,S(c6496a83,8f95ff57,65a0f144,774cf543,2e770457,55efc790,142df95f,bb6c51ef,cc0041d6,604d1d73,92d86f01,d8b05b53,1177b51e,3a38b8ca,ca8267fc,bcd752a2) +,S(e799d70a,b163bfd,475e5e72,8810d9d2,425bf4b6,9461e9ad,933fdb6f,68c11c74,fc34745f,e29bee3f,9b0adcf7,618c6d13,e504449d,1a272b21,5ef9fc18,14ba8600) +,S(6d3c97b0,151a9011,5032aa22,1183d82e,820c8774,c3dcd75a,cb6f45ac,5d489d3b,5aa8bd01,3d15d77b,8f695d43,8cedd9ee,64b57df9,ee672323,1c2cd5b1,4ad4749f) +,S(86e53e00,1c1e7de7,419cf2d9,a4c6a39b,b96d8ec3,a82f8165,45658eff,a517539,f8b1b70,f2efecc0,cedda525,40663114,c24491ac,266df520,ce475f01,ab44ad86) +,S(a641c339,ac877cce,a9a3267a,78edb33f,75feb90,1f3c8743,47c50843,52a9880a,d88a6d4f,2b275ac5,3c7dc101,b7d69ca5,407559c6,afdc9009,c34a7256,f982163) +,S(3a0153a9,4d778266,4581de43,6de31754,b925aad5,4090cceb,9e013568,9d82511a,f6ca48,94935c5a,7a252df3,8ff06cf9,11154b0d,9f0ac55e,35a33d7a,58802035) +,S(e78024e8,a131c9ad,40526b31,d26e96f4,2c2e51d7,c63f458c,5bec2a61,472b170f,c540a14b,1ad7b18f,23493d9c,edab65dd,3a309204,976408ea,f197f658,9f4e0c53) +,S(7858c85e,8351f0ec,740380fa,b1924668,7f05a161,e2dd87cc,7df13338,a86a5162,cad94344,5313a06f,c382897e,7c444d53,7e658e06,5a76fa60,928d7e5b,36a6de1c) +,S(6643e28,1c5bddd4,35a68c17,965f334,ddb9da8a,d599a4b8,2f37147a,cb0263e6,9f9f9e36,8ee1aa0b,9bc8f928,284968d5,6f2dc8fa,6944ff36,d728b588,a72cf79b) +,S(5f36d937,a286f14c,96fe8f9e,3ea05d56,b3132523,e9a135e7,106592d6,b9b2254b,9d6377c,c8265ff2,dcebf753,ef2fd39e,9adb0e1c,3c86acfc,2e54648b,9056310a) +,S(212eb1ae,93d3a0aa,5f626f26,628503c2,310f9172,461ea12f,b17677eb,c63e2224,51e57e33,347f2016,c738d9fd,cf528269,bbc5afe,f5fd6fa5,1dfcfd47,4b6d1b67) +,S(526952c8,940b9f93,32848145,203ce261,dedb3b93,8e6f277e,9a085d77,35e9eab4,8657cfa3,56df2aaf,9a5fe2fd,81804ff8,1d9aa58f,143fa109,52e4f4cd,85a42918) +,S(20f1750d,ef762812,e4ba8778,c953a2d1,419e03c,b97ab6ef,8f98be07,4c1c099f,d2fee9f5,3e7ad2a7,fb20bf88,16a1ec2d,d9d97b4e,5abc060e,bd8e8b31,bacd485e) +,S(e231a3b7,ea011665,c223cfb2,7f13c691,dbc7f5e5,efb66496,da2936dc,d67ee910,aa645c2e,18e80131,f3e7316c,7cdf13c3,45e4f602,fb17011e,96eb5fc0,bf65d53f) +,S(7a4e4d52,3fd026dd,3daeac35,552e7299,d01aa962,687a02cb,ed7174b6,25c702ad,351c12b6,a7398e5a,ae461204,4cd7c9a4,7d2bdfc1,1f941b84,71eb3304,fdb965d2) +,S(fd2f707e,76965670,67ca5a5c,a0010c6f,9a858967,19a23eaa,5574d1c6,cbf137b3,c45a430c,1d5ae473,31f9b161,3ce55f41,df00e287,9e3bf8aa,1ae75306,f8315408) +,S(c506cc1e,8cf2f4fc,e1011d67,6d304877,6c2ac2a4,f8265373,f3f918d3,f02bb89d,8de6dfb3,74029b33,2fa47f6d,1f7ba609,bea33d6e,2f58ef0c,58641e2,a5d3118a) +,S(2ea7ad02,d9ccf999,86ab901c,3c9cde3c,ad1bb4d7,d8f86eeb,b8204b75,ab5c0369,11222bd8,6d750302,763648dd,daf76947,2b213562,494ebd9c,e4003195,eb0ed43) +,S(ab8cc192,3555e4e5,2f84b421,ba2ac134,f8a6023a,ddfd279c,4c338cd1,9e159c5c,2c48e3bd,cc268dbc,23e9fbda,6c449079,5a5b54eb,54ca8ff5,14d1f23f,8751ee1a) +,S(88fec2e1,cc7c41fa,91b48e1c,2a71089a,c3778427,f2cfce04,c54af407,f5dad430,ccb45e88,4f696653,5fac7a04,9b035c26,dce30666,fb1fecf3,c4b89deb,8b3ed80b) +,S(404587ae,1accf5d1,b42c3127,2ea0cdce,940522a1,c64c757c,11d3768,774b0d41,e8dcf25b,25ae61f4,f7368c36,9b351b35,63401deb,5ce55325,f96a393f,ef0e787b) +,S(8a701eb9,cadea8c0,8d0cf20a,b2750915,28a377cf,bc4d9097,51424d1a,7eb9ab8a,4f045982,82a9ac70,c3c76154,ca98b5a1,265e8b26,6f02d43a,4549cdea,caba5a45) +,S(c2812978,194009c2,9da141fd,b108a4c3,66e15e06,c6d64389,29b2aa78,89ad3d56,85409efb,6670e969,a2834255,dcb1e546,9c9db5e7,6e549afa,974936c8,b75db5c1) +,S(9ffd36b1,c810c843,92bb04d1,90b82be0,f8ea4b4,2baa6129,8adfb810,71d72fe,11e27a4b,a11f0df8,1a42955e,bfa9fe1a,6f25fda4,6a65fd87,1caa3d6a,1b38404) +,S(ac4a0044,bc92b017,cad07210,750eec62,39e43147,5e3feb25,f1c6f879,a5a48b96,41c7c3ba,731002ff,1e749853,344c1f53,f526bbbf,457b4de2,d5f88ce4,1eb8dfe1) +,S(c78b101c,157ca920,b3fc83bf,9d19fc5f,57d8086c,d764e142,24ae4e86,7b06eb5a,1a8d2c6e,b9d660ff,faf5f533,b4f3b8f6,b7a9d7cd,5c29c1d2,deb37f19,d38126c8) +,S(d08f3b05,572348b9,5f3c1c2d,baedd921,c24b0db8,e6d17d13,578e5ae8,77147cd2,27b5fcde,a067cbb,69ae3e5c,90a38523,4987dfaf,5dfe0696,91461e26,762713cb) +,S(40ea043d,5060f61e,b81db0f1,c7c5c1fc,1091cf51,c5808489,3d08c4b2,a5e312f5,2ef11ec4,2836302f,e02719be,259f1536,43de03e,fb659f30,84816a00,1d66b27c) +,S(f9d104bd,fb53b4b2,de8827b2,8242eba5,17db73f9,dbb1eec3,9f184ad0,358362e7,d7644a0b,6c371948,2ba707b6,d7d43f0a,68f4e3c1,4af6f167,296ccfcf,4d771877) +,S(dd276aee,14c34829,4e6132b4,9a05dac,fea5f8a2,41712b6e,5703778d,eff9ddc9,9be617d,5d92eec9,7fede655,39690d0f,4803f760,2b74066b,7bc98353,a5ceb7ef) +,S(8522f839,d5f17bd0,c67d11f6,7f0db8db,2104c7d7,785252f4,c8be84f0,61155d49,b7791951,80311f8f,6cb9b59c,ddca495a,e01f3edd,599f8777,3163a959,5a3ea117) +,S(732802bd,b4f3be8e,fc02a62,4614672a,51049166,4bfce64e,eb2030d8,b6b5b225,7bd4cdec,590eee1d,6a505f92,cc0b25ce,d9022d62,d1155f8e,35a6ab72,46a3c6f3) +,S(1b3641a1,2c4f8352,21e73276,b8bdea15,f5ffcbaf,c4496fc6,8fbdb573,5967af62,3d50ef5,e5d12b7b,2ede2e15,3b4cd01c,b824c32,7a8e1ce,f0fd866d,99664048) +,S(d3034e18,4e9284ff,ed6cbe60,cb66d391,c897255,dbbe8c85,2c79525d,3f01a7ce,b3666304,16ce50e7,2a094b05,85f1ba1e,11172ac4,eeb353b4,8c4f8f99,f9d09e25) +,S(8e7a8200,bd22f5ef,18fa4461,8f4f85a,61c6db2a,a3ad176d,65c3270a,69e9db17,841fe3b5,1cce979b,f87536ed,c71f4cd4,4a482475,19b35cea,dee4b3b1,f3530568) +,S(fcccb4de,29ab8671,d1aaee27,61421ae1,c4af5f3d,839009e8,5dab0b65,60a4027e,a0229f96,203b89af,d5b6ac06,9e977e71,a6e269d4,bea29c47,fa6bd22e,f7f993b) +,S(e68cfd7f,44358180,84c681f0,aead705b,9e74a476,1f99e576,9252c007,e44c8a26,add9c0a7,b027e2ae,42378d50,cf0d0eb5,71229161,8e9f13c1,672121d2,c428f82e) +,S(8b6f0fad,4b81ac16,4866de7a,c8bb3252,63bfe008,b726e9a8,72e0461,2c6891d8,9bad6508,a8d604b7,8088d328,ca27fe13,91493e8f,a6291288,92ecaed,ba4bc9ca) +,S(108a0caa,37ac1949,263178cf,20674616,470f8943,57a921ba,8cfd499b,d64b78b1,68150d22,be05956f,5ffe302e,1ff517c7,9b7c0452,6112b2a7,5a819f64,a265bf55) +,S(fed18333,844c579,1d32daa8,3370a5c6,ab8e13a5,2654a08b,42940284,c757edb6,67bddf37,8395ab84,eba29a97,6952ea34,b1b52c2e,d3f89e56,f839c1ff,36457fe5) +,S(bebfb39d,ecd56cf3,50bed6f1,a4cde24,848b2d84,23518da5,1fb2ee0,90170a2f,1302b4b3,bb86f887,22925fbd,e146d948,5acb2db,a61e751,97dd40ca,2ba11573) +,S(67135aed,2a58d3b6,c4470d3c,b4da7b56,af8d5057,9d28a86c,9c67bf28,181e716c,97c40aab,2786e3ef,dc8f3e77,8f374446,30fa2f3f,53eb040,194809c,8efd6664) +,S(b00eb5bb,9566e5a,cdb09dd4,14d6df03,c3dea75e,90db8b9,c37928e5,4354f90e,6d120e41,1cb6e674,e9973aa6,3999af3a,ccc3a670,112c964d,8aef93ee,e69b1258) +,S(721b1a6c,be8d2022,f09db6d3,ba39b2d9,23337592,de9efbb8,ecdf3384,f3bb73a2,cdb41b62,631a0f47,75ae1f2,e94f8075,4acbb2e7,950be088,5b458c8e,4a05310f) +,S(cb8d78ac,15b12ca,8dd47cde,190c420e,42f60b83,9489bf71,d10a3e44,df8a0837,80be31a6,a3073675,e8cd3846,cfb2e127,abdc448b,1081a2d5,d177ccff,ea96dbc2) +,S(491cfbcc,4919d884,d23f3ae6,6d143e55,37e5c52b,e2ee017a,afec785,6c781920,76321b50,26283088,d344d29c,c4d9f2ec,3ba714d4,edc1bee6,2b17ecc4,56874189) +,S(6ca33ee,48992263,23aed33f,f822303b,8145d146,c5ebc27c,fb3700b3,6ab507b4,96b73ab3,f189d064,1e0a20cf,d09522bf,8c376a0a,9c9dbec6,44e3e8d2,c0b11f4e) +,S(6d1fdfcb,3c48971b,6cbb33d3,822cfa68,1bf602ef,98160f89,97ccaba8,19d842c7,82bc7c4,66088262,5e57c062,96f04600,fa555ac4,5596b769,9c6d29c,cfb1713f) +,S(a3e81699,1cf92f41,a69ac3ca,36b23796,daeb533c,3e1e9b55,c88e3fa9,fea43554,87a6fa9b,e802467a,fa206b0b,45405309,65887df5,786d20fa,25e94832,312855f1) +,S(fc84abd7,cbfbc329,4eac7438,d50b2ac4,7f570e4f,3f2ffab5,71f8c3e8,7dd49c70,7447b269,71356b0,e59b3f1c,d99b6416,589f6c3b,a566c75b,6915377d,a7f73dd9) +,S(beb23240,8fc515ba,180d3125,2eca15a1,af4e02a8,73a69769,53982408,355d1b1,12fa480d,6fa8a9aa,e5edeba9,31b765b0,e2bbe6a1,5eb9e95,b3bc343f,519c1459) +,S(68891679,cffad7f3,19a373d7,1bc02529,a50e63b,60434f13,df760364,1a99eb8e,40b78db7,6db28aa2,d2ea7c1e,86d01503,7736ce96,2e6ec524,da07b5b7,68772fb8) +,S(ec435ad,1ae7b040,fde2f736,e8fb5d53,b42e2fcd,428e9d96,ed401ee2,bb068817,13bf6eaa,1283436f,4a828a85,66c4f795,26860c45,d650fac2,44bbec8e,fc96f9f2) +,S(679f5afa,661f688b,7dfb7ce7,f77e4904,60a75576,6216a49f,374594d0,6bde3033,ff3fffd9,6c254fda,558f14bf,c8f05cb6,c8fddd32,a487d709,4e0fb35c,6f617ca1) +,S(9febd8ea,5dc26e5,fbf48aeb,64307b21,1aa2fc02,eceb6d68,ba89a652,f633be60,c0867bc8,ea6238a4,ad36e785,cbbc5e0f,3fc5dc96,2c778992,72be4364,8e630bee) +,S(d886b154,c534b48e,db6bed69,6dd8f9f1,347b381,1b593acf,e2137c93,600b1601,a4cbc118,aa07daa9,c4e246c8,efeaa3f7,d74028c1,93b77964,f10ab5d6,f75d077) +,S(af8ccbef,c187a3a6,83f6ab6,8ff217a1,96a8e27,dcec349a,b7ee4a74,446e9d47,3ee327c,99880392,7da5b625,be554e6f,1662a733,25a8fdc4,990716cf,6be941f0) +,S(1e9800e7,891c261c,a3451d22,44a54a84,42d33458,a997b365,4a6198bc,7dd3d26a,322f8986,bd6ffc0d,d5f1a321,e82e6b37,978120c9,66f753bd,5669a773,65a215d4) +,S(115c62f2,9f008009,5840dc97,f3a90f30,aae4ffa6,a2d255e4,15d64c56,77150044,4d944c12,7e37ce5e,fd7660e0,1e4fdf0a,cceef95e,8bc2da14,a8fd7e32,ead8af95) +,S(1cb9f9d,acbf79dd,b34d78e8,e51225bf,3f53135f,f4282ba2,59855968,2ae0178c,8fd3a4e3,7a189bc9,421595e2,bcf234e,d7b602d0,855de84a,50c68cb4,bd1a4bf5) +,S(62a15bc4,63e4c167,4bab2a5b,dc991e39,af86d258,f9de770b,66a79ee5,2fbfe357,b78fca9f,d9467e4d,256da69f,e6f45522,d376fe41,e8ebde9f,9f7bde4b,8ef52749) +,S(574a6ce0,5bf31948,31570914,a73bed4e,6bd2c82a,5a19dec4,54b11e93,5edf505e,e7b2e2cc,cbd6f338,f0ea60b8,c1a9a50e,d02dbaba,8bb5cb78,9b281a97,5c001318) +,S(64c6e37c,a3a361a4,baf9ceda,d9ed24fd,c5ae50ab,560e6319,4adad1d5,264084e6,e6e42f56,56b6b404,9c54a07,f35ae004,4b7a480e,8271c8d3,f7996ed6,68116067) +,S(49065a97,fe4a8de5,55646af8,475607a7,71b27746,ade7fb11,55308107,4900fd84,985d689f,67a03090,9ab8eb43,c7b2767c,94e7217b,fbb43342,83485f1a,d70ae7f9) +,S(6fd32ff9,185790bd,876a683b,7e889f32,8500c91e,7e5889aa,44394caa,330999cb,12fe8084,1be1f25d,7a93784e,9c6bf01f,efbd6493,8f1a678c,64497a8c,85d2de3b) +,S(4a67d4da,48189c8e,6ff34812,f7094851,2d6d12c4,26fdc98b,4ebb92b6,62d3b185,58ea83f2,f6e5b777,737c668e,efa71b8f,3e50095d,389a5540,684cea51,7f8150f5) +,S(ea1ac931,d3a92770,5d20752d,b9adb464,edecf4c5,95c20c85,987e1beb,a79f4db2,cf689b0e,25aa9601,58316597,b06fd91b,426b5753,68a48830,9c3f6f34,6722b83e) +,S(8cb35a6e,248a0527,d572663f,7abc99c9,61414af3,f196c6c1,2de4dbf4,dd545c5a,4b32e4e0,47dacdb6,66edfc3f,a08d500d,c43292ab,f36bea7c,4a3952e6,680cfcfa) +,S(247c800c,f150c2ea,cfef8dfb,f4581560,84318684,430788e3,c8d99ccd,d27f21c8,cc82d8dc,914fd1a0,e626462f,5829eb7e,a708395d,db3e70a7,57942e85,1f1d0db6) +,S(6543d7c4,7fb927c,fb0f3566,6103708e,5e0c4a4c,ed202482,c9f48647,33426673,e252b29a,69b4ad75,814ae0d1,631ea750,20bbc730,3fdc819c,88d8f3d4,7907ebab) +,S(c4f11255,d81c33a3,a09da4ac,af5c9c16,d5e759db,2e1026c2,9b3556b4,c388e6d0,e2e636a8,1af48ab5,814e5530,e48f518d,95379eab,186e94f2,4fcd551d,1ca8fd49) +,S(cf186a9d,85da39b7,7383d92a,14af5a05,b082848f,c9e60598,1bad8ef9,5e019eec,cabde21b,c860fe08,53f672a1,64010968,6b49f37e,61cc642,48f455bc,b079e3fc) +,S(e6c3e353,ad69dc13,e595c2c7,a88b8fd8,fe9d1d47,3d45f7f6,be9ae903,86ea8f32,7d3becc9,4f455c1d,21610800,a4985f33,96b5a920,d5ed2b57,2107c28,ac690be1) +,S(3827b3a3,9bcb554d,54695dc6,bcf22911,d1ba01f7,730d1c11,8d6a7b2e,c1060988,32413047,b7c9ee83,1b818c5e,cb8f4c10,c800a362,419227bf,d9f50aff,ca25a211) +,S(ff37cd38,a4b149a2,a8dae898,c40b0ef4,4b55ed85,11b5413e,48f5608d,cc6d24fa,5e615919,8f4c6665,7c3a489b,86853a95,f3ffded5,20433cec,a6832cac,b9c49048) +,S(bdff4fc8,5b492fae,1ef34322,9e83b751,d9e53c7c,455141de,f68d3e8a,320ce509,e8fd9864,9dcc5d66,6155088a,29959e12,531f8a4e,44d70b8a,43b4fde0,8bde3d20) +,S(fd6ba29c,313ff2d5,7fb2719d,9018f11e,e59d1007,24146aef,625a9b3c,3bbcd0af,187daf5e,913310c3,39f584b,3196b877,5018dbe8,1e38abf6,de73e97d,f5c1079d) +,S(ea3c422d,48606929,ef72ae1c,3ac30178,4f4b5f78,1405fb62,1d0b710b,1b29ff28,e458b41e,c6c3e06f,c37637ee,fa316e25,d10b377c,ef99aaf2,564fef92,33bf208c) +,S(46537133,4982d600,8d228924,f0b459b8,2ba8aed,af1b3c39,f87053f,487b3978,fd96654c,13189def,f243bb29,e2143dca,3b2444da,3b895700,6bbff65a,4dadf3f0) +,S(fda493f1,1226069a,ac76227f,9f9e1051,b5b29b4a,a2d0f9dd,99637176,8578d8f5,5a33593d,f63d136d,f43a69d7,f9803a62,e04e55b5,25633a06,d8eb86c7,e1d46fa3) +,S(74fc42e9,5f09018a,5468e283,5ea36fee,7ab5e757,c57200cd,966174f,39f3e4c1,ccaa0b40,3802c914,da86204d,45f8f5d7,3760e075,4bfd10b3,2a8b2521,218751f0) +,S(98cec4a,997b79a0,cb818da,58e41477,d98f8c2,8140fbaf,e118bb1a,ec483d53,2fce6058,14945cd5,367b82fa,182c19d5,ac422d9e,840eae4,d81689ac,7eaaec08) +,S(c742ddb7,89a5cbdc,2055119f,697fd575,e4fa1540,96cc5fc1,3c2374b1,13cba60f,9b0af128,34a990e1,d402474b,e6dbaa1,b32248f4,f2b1d680,13fa0dea,46f3532d) +,S(dba2e04f,9a78066a,b5897913,6c4c7224,5b5973d8,3b13819b,77409fd1,e791eb89,34747922,3adb5f74,168240e7,a178f077,aa0e90e0,870456a8,89dfca5e,633baf43) +,S(6d4cae43,6e598586,7b984dcb,6c2472b3,6cc47f86,eb69fbf,1069c69c,42f6538d,c7fb58c9,f0c4f7ce,dd7c53c9,23efef52,125c2b67,d67f1ced,b98bb1f3,d5e0a84f) +,S(4c457f6e,d5b67b05,5b664ed4,3bae291a,9ec5b539,6fd9410f,9cc16a03,b8523982,492e5bcf,20aae19f,5462ed68,2a72827a,a435f47f,ec218e98,8e91fed5,20f344eb) +,S(4d7e6922,34778a41,f58033bf,d74ae295,51fd8ac3,64cd817,9cdd441f,cb46eb3f,756ec0b2,ff5c9d3c,3a453879,17ada4bb,6d7bbd07,bd10d2ad,c092f46,c62750c4) +,S(ac5be50,69bad479,bdbc565e,ab74ef94,4a48399c,a4af915c,fefc47e3,7d464b2,3246e3fe,bc5810b6,37722c54,69ce45d8,8bad5daa,529b4381,928b7cfa,de874345) +,S(7da88d41,21350139,bfe6a481,2534b25a,24f91e0b,60d882d1,5d69e840,da3995b2,9888ad8d,62a7a4f8,700bb03c,f9772432,6a2d092c,98adbeb5,cbc20348,f0b9c587) +,S(389ff31a,63239cd2,c9aa3eb,4d3ceb49,5d3b922b,5d137d4,e8b52be3,b1abf149,b0ec2a2f,bc840bf2,8a22ab22,b76c1485,42f54ed,5515ad49,dc3c0037,38fe7c93) +,S(c1cc1acf,5fb128b2,ea65afaa,d3d5736e,a94b2e49,8dfcf6f8,f3c27a5d,596c4370,8903584d,1986ad31,6cc6bf2d,aa2a88cc,ecfec6a9,c1bb153b,27c409e6,934fd38e) +,S(399ace52,b92768a2,a4740be8,31c96c04,2a34957,e91b3cf9,8b3518b4,87c9aa3a,908314b3,abdb3a47,a117ae09,5d609fa3,fd9af1c3,ca04a869,786eb134,48800005) +,S(69543fd,8c9d01a5,702d9859,305a52b9,470cc606,cadbc76,d8283ba9,ba06d0a2,e998e7d9,a0c372ed,2e348f17,b3298088,404eb1c3,8a901d1b,6f4e8a19,731057df) +,S(2172d54f,df9b46ef,5a1289a5,872b1c28,911e553c,f703ad6d,400b6af7,e8200100,2121b47d,3b790e5e,c820df5,772b226f,34a8fbeb,f642b5d9,edc18971,1b687a8c) +,S(f606f7e9,37a324e5,d0e6847d,24923965,cc27133a,10e43f28,6d45f7ce,9d5e8b56,70013fb8,622a21e2,d1337944,89324a13,f5b80580,91ca08d1,a30e7571,3e86e007) +,S(9f1520c2,dfceb64f,1f432013,b342af35,2f95bb2d,d49aa14e,dfcd8e71,7c40fc99,fe8fca26,feb1f004,8fa4fe3b,764a907e,d53dc0a4,10308199,6cad54d3,898e863d) +,S(6670af6e,7587676e,eb0674eb,75c93d38,53afe418,cb286605,18a9370a,231eaa08,2993ff5e,dfc071ee,97fcee9,bb12fd8,fb59fccc,524d8537,34ba4cee,4beb09f3) +,S(15c6d58b,345cc4bc,e4ca4e2f,ee954c2d,40650a4e,ad6c9524,65f59a94,b3898350,894c53b,47276196,65a0f3ad,f528d2c0,221b12aa,73df2cf3,a6b0e778,a363cf7f) +,S(bc4ab6bf,60dbde42,c9293ef1,75f85a48,adfffd20,960ea454,8a919977,75389621,fe28a0ba,24a4e2a7,45d6bb68,ecd71931,791a74,61549a44,37a34761,19040e42) +,S(5dab1c63,23fbf2f6,e495e87f,1c703ba8,64f20e50,4007dc80,54ef2e11,d3e6ee1,1fd0c200,cf4460bd,ae6db415,3e68bffb,e7f01ac1,6b30e305,9c134a86,52695d93) +,S(2df1cd57,d7357c44,7be28dbb,c339ceb,5cea0bd8,e702fbb2,dd67c189,6a8acaf2,33192011,20cbc8dd,c3b9c031,94db76f5,86eefa67,995dd741,492f425a,e2f1b9e8) +,S(2d81ac17,5a02daf0,83100585,ed2bac76,3d9f9764,15356fea,584ddef,60d9ab8d,f9908cd1,3b1785f5,78297fd4,9e6c26e4,21052e2c,ce9f51c9,cd58183c,2df9a0b7) +,S(1fac1762,fb732e73,2440d40a,5356eb17,67b1e7f4,f11e8db5,9ef90702,437dc097,edd5784c,a58d5113,2b5a08ac,e75cb30d,5ae7ce27,129f158,4df5d95a,7b9b8729) +,S(d06a0b5b,4694b90b,80c93e88,4aa9086e,45cabaf0,99b15a9c,c2b19678,38c8c98e,4cad46ba,2777b24f,cd1b391b,222ff3b1,14fcc814,5f78ada4,98620cfb,747def3) +,S(4928df27,590240f9,9907928a,cb6f0695,870059b8,cf9b1d69,29b152b1,7de53445,b773e60b,655b3b0e,7b0c400f,37dc336b,240b83cc,286a8ac5,3dba751a,3300d505) +,S(a61bcdf9,cd541811,4ba99261,7322827f,f945d450,c331ddda,1b8639ff,87a28390,3e771d6e,d6fdbb28,54601b2b,301fe24d,8e61b370,ebe644ee,b40fe807,b8d93a68) +,S(535a35b9,3e2fb7ab,b3b1228c,a7977,fb8e34c,107f093f,9f641b15,11db93c3,2471ff35,5657cc8c,38283fba,27c2e3c2,92475fb5,e8d52e96,f0c9fec9,b2ff786f) +,S(e68a652c,e0140f29,376888bb,c6be70b0,f23ad42a,d10b8acf,a5f790b4,c465d4d0,49d7390c,c368060b,3134ecb6,dad52120,ea6e0c7e,b80c94c,6cf9c1d,3c1a7385) +,S(e8939e7a,74dfccd3,ef17855c,3ea20e99,f5f05f6f,8bc4757,6b4f0e99,37e25fde,6b48a73e,ff0a55b7,c90c0fdf,449e4c2b,3773f454,da2c388b,3e0829fe,d661b173) +,S(496013ea,31451874,800fa293,a6e70ac,7fe16483,67c31daf,bfd00faf,48751543,b5715111,8790556f,8a4001cb,282b3312,581e1508,b8537f65,6142e2f1,ab8c4332) +,S(444735b0,b1efc3a9,56957a07,22604d09,bb0f6c29,e7cc5201,89ddc3c1,804b1e1f,b1ad60a3,461abab3,a9732a85,7050e55a,3e9a439f,32a5b21f,9aebe400,7e59d6e4) +,S(5805ac8,4acd7d5c,f85a40e7,4b9c98c3,e8882189,e77aa475,da3b4114,3ed9511c,c952923b,fbba533f,7bd70dcf,d8d69b7,1ad0022,aeae363,bb48134d,6a3c07c0) +,S(8ac11518,30fdc785,5e1c53a1,2b690202,c12619bd,c46c8898,dcab77ef,279a9501,29fb7cc7,7867fa0e,1d015493,abfb2000,d5deb3b8,ddb3053a,d59d6bd4,a9ca4fa4) +,S(aa47add3,e42998cb,68fc8a7c,cc7beff5,4d70226f,22f41ec6,7bd7b444,aab542d,cfa5ac81,ebefd98c,3af4f9e3,9f67459a,4f8e8c4f,c1959816,f771e75c,c43683e9) +,S(f3504127,a27a14ee,92133f75,364922b7,d3984898,e433d3e4,19e88db9,e599889a,f1af9f7e,9f9868a8,84ecdae5,47bcb886,56c6d423,a066b313,c09cdf08,601b45df) +,S(33730f44,edcbe688,35887076,69a989a6,272d3ce5,9261b98c,7c6eeeed,7e4bf08d,3f833928,d87716d0,4b2a32d8,1bd2d789,b6fd057e,cc70a794,8605cbe6,e1775a6b) +,S(3169d6dc,8c06f584,880bdf07,29249cc0,a33d417f,be137478,6e5b4a14,3edfb0d6,2a91422d,ec563839,ba782f59,68f428c8,a311600c,2fde77fc,ea163e86,aa74ce5f) +,S(d8c64582,13aae81,cf07a64d,5a8dc3eb,c8c43a45,d57f8e9,80cfccc6,f02a4429,c4873051,968863ae,8c92f195,c9fee3b2,c4773d47,849e2a7b,e7f48c4a,93822aea) +,S(ae67101f,307e246f,7a7cb039,5631b884,7e59c8d8,14da3fe1,7891f69f,402b6f11,f5f2dbb4,a90b09e8,b96767af,a9f9a357,1d3900f9,7d8222ae,e411e1c7,11ed44cb) +,S(a9e87231,83ba8338,1c0a7dc9,c81a2c5e,b4e2ff43,82574f0c,1a9d7f14,81dbd8ee,96810599,90d90e33,d69fb59b,ee68344f,333153ac,3d73a335,4b7ddd6f,96468901) +,S(616bf21c,ae7d40b,2694f43a,a33e6848,694ef879,fb5bc48d,ad141e34,e43376f2,bec18f83,2aa8a0ba,83245115,3b5a4faa,4a27725a,a3d9e799,bf05dc94,9880fc77) +,S(121e8335,601f33d4,78a882b1,1e9be5bb,39be47cf,701a695f,8d351098,af3f5c2d,2e992933,18faa04b,7d85fdfd,cbff81df,10dd070,4485b659,f682a298,4d03b3e8) +,S(bf884797,3025ca9c,9413948,fef1bc48,3a83cc28,4a909933,25c8c97b,b89f1141,1953a326,3d26d1d7,86d5ae3a,7838d125,6de24760,6abbb63f,e2713f6,6ead5386) +,S(7c28e9a6,5a3800f9,85c94d4b,ddc75cd0,dd1b06e0,faeda124,e86600a5,6af811f0,a3756db7,e339f03,8914cedb,707427b4,2d396fd6,f2e43863,13414863,8ab5c277) +,S(e5ec6dad,45e62cf4,1ccb5bf6,bb92387b,46be0791,31bc2b9c,b8b93172,90a66077,d0045ecc,775703ca,f854bea4,be3c4d21,2bacd092,7a210eda,67c33aba,e44f0e19) +,S(6fc96e1f,92039545,fb31c352,544a5974,7036263e,34d8e043,58336169,118c2fed,d032de87,1571de8d,96b0457f,84397e36,6ca7c20d,d90d089d,9aababad,8b8a9a51) +,S(89e3d351,1c219c47,42e79091,47c13146,1db684dc,e1a1149a,cf49115a,746e4133,aabd970b,672e8468,d84b53d2,303d57eb,52fde5bb,bb224b03,6892f918,630c5c90) +,S(2b7a60f0,b2136453,878eb44e,aadb8da8,c043e947,fea1de8,4ff8e18a,390d5890,c829b16,1ba032a0,59340709,1b38b365,b806686d,19026f41,ae8bbab7,d04a5244) +,S(464b9f1a,c2c2aeb7,e6f7c3df,a8782f25,bfeb9879,9263a9d4,2f872050,6c9627e7,7c260bf4,59e1bcc2,df7761db,e503875e,9a23a107,6cb4e8aa,dac5b5b5,b6f7502c) +,S(79253e30,43572295,e331519,e774b670,b25141a,986eb5ab,268b63a2,759b616f,da609d7a,55b62353,b20f5bae,969665ca,ed6467d8,f2577f69,10003586,e27f88e1) +,S(634287c,e900c0cb,5c2b1967,f55190f9,19acb09,43596773,87642d16,dd399556,a2350909,8cf01601,30c042db,253334ac,223c473e,312bf758,1fcb461a,c3debead) +,S(761121c3,8bd8fd5b,a3418557,f6a75b42,d7ef2f4b,91620223,3587f183,421bee98,4014715f,f9c17435,10e6eeb0,1bb29226,76070e34,afaed040,5c897bdb,52dd530f) +,S(2618c8c1,bfbbdf1a,59da3078,4e50a2b0,77990fe1,c2f074b3,e63dd606,6d453413,ae539a37,20f5b6ab,18ce584b,4ea3cb46,4bdaf35b,326fdab0,58169ddd,32a48da0) +,S(d429fccc,10c6f025,fc7a57e1,949308b4,d91699b5,c099820d,ab31f1db,90f685be,da2b15c1,ee155918,de414ae9,1be51688,a8df043d,6fb6c964,689bd4e,5a648edf) +,S(6a18e3c7,c04b8cab,36e07625,ba2daef5,bf1e0cf6,36650b6d,56dda8d8,e4e8b705,66291330,f56c96db,ebf9c9da,bc52541d,20e75440,25fcc49e,d6215d8b,c0e94eec) +,S(985b6846,d1c9f3fe,5482fa4a,d6a21c65,d7ca3eff,a41b3220,1a37a122,f8f97756,3e2b23dd,98e18f6b,76a2f2c3,2c543f8b,bb9dc6c0,8d391592,d56f5440,aaa3a92e) +,S(948a0ddb,4ba838a4,63eee339,5c7bcca2,96fba8e3,9654ff33,55c9296c,9e6e8c64,c5b34c25,da19d83e,b67b69b5,2e527d61,c7b705ed,2f794d2e,12c4325c,3cf5c1d8) +,S(4332d02c,1332b03f,b7a46b47,e82617b2,a437fcc,694868c4,256aa40f,a8a3de2e,e6e5196f,5f9c555d,a94327c0,39411780,393985ab,73765de1,e1bbe0dd,8aaa5289) +,S(5dc977b9,2ac1c895,f3150b68,a8d69f5a,f7e12dc5,6b211d96,a67cc3fb,722a5aa3,45888ca7,4bf1ec9e,1cbd2912,3cc696d2,83260c34,3410217d,10fd0b95,9d07844d) +,S(5b9cf534,ca94f124,a9b0cb6d,f0003924,605e3bd7,d063a2b0,c6e1a81e,3fd15764,44e98dc3,b0516ffe,bda48790,fa0b2d67,f9ba4b48,ce88bd1d,d81bcbc,897458) +,S(84353007,3a63714c,7d26baf9,c895e2de,e2feb4b0,9746ca66,97fd7ff6,d5372f59,d7373a9e,37689d44,4cb7361c,f2f3452,3f9fea7c,826c62d2,3ca3f368,b0c7a175) +,S(9cf0000e,3eef9b5c,89c8485f,c3826e78,8f1a28df,f8746619,804030fa,c21e6a61,2b3dab3a,d8684b2d,94e1fcb9,d2005c20,2764cd76,aa91e0a1,ac2612f7,fe91543c) +,S(bb292fdc,5897188e,20888b25,b491a757,8ee02853,83aff5e9,99671a24,4ce1235c,d3b6d9c3,50ba7863,bcb83990,95893348,d5e9b8f7,27e1a3a0,9e02f59a,412507e5) +,S(95d6d1d8,9835ed57,6a88a21a,9239b623,efd2bc6b,f27c5ced,2d770c90,fb7d680,c91535ad,39db65ce,fab4ac72,f3ce692,b39e7d38,c72ce468,e40bfe06,6cbaf048) +,S(cbe3f20f,a164ec20,9c2c3fb9,ca0c95,15ea3787,df2c8fd8,9ee50a3a,85d09a46,cd589754,faea165b,48e22280,4186e6ed,734a2251,a6588e8b,8252eff9,afb9a28) +,S(3e01dab9,9bab9e20,59b1c215,ba67835d,2942f4,487d6094,9f39e293,b39f604a,b41ddc32,33365044,ee350979,8679f3e8,d0a556f9,e8b6a267,bd5cb5e,8523d481) +,S(298974c0,5543dc96,15f1cfd2,e4b6331d,c798918e,15e3f350,97213a64,76afef7a,68018355,55f2d8be,a74e02e8,747f60b2,22354ea3,62cb657d,e5cd8060,7a99da2f) +,S(1d70674d,54763c96,ea3764b4,641d14f6,2aabdec8,a093c3df,d936793f,511fdc61,9674adac,697e44bc,6324378e,59753f42,80774101,623dc10e,8a4eb4be,38dfe632) +,S(75220107,b43ab970,6261875e,c8f8b634,73c47aaf,91ab8fba,cc0b1c4f,40fece1,29094e7c,c3bf07d0,12aebf2b,fb56efb8,41bc9ad5,9c350b7b,885602e,a3aeaffb) +,S(cfadb9ff,b3474ec3,27db31aa,b0bac83b,fc7f4c8c,9d0efdf9,2e7e7922,f779720,ffb7657f,6f7b8cc5,78f22ee0,2a99fa82,97d41806,cd2b8b06,ab00b993,d9a09b2) +,S(24ee919d,be3c5603,adee46e1,39d84aa7,34a7b4f4,d7b826f4,64ce8b6b,c1cb828f,44039756,794b547b,9360b63c,539b8f11,ca651476,ed57fe29,364a5ea6,17ff1506) +,S(5995e246,2f755256,f4d6b8f1,a5cbeec,c50ddb53,fe4391dd,1b530eff,7cb100f4,77ddda7c,7da05165,c46d7ba2,40127ff,fe78ac6b,13dd018c,e08161d6,d81dc64a) +,S(a7233471,97dd478c,e129fa20,59193c08,364f8c37,1cf19c2,9dbd51c3,234d54dd,2c4e695e,ec2b2ccb,384a5fa0,1a96664,9cfdd711,1a1d19ad,92f2eef1,31796e68) +,S(6466ab69,d5bc21cb,d7e75fcc,5de9fcc9,a57cfed6,3ad41c23,4ed56cd0,132251a5,76e7ef89,6dbb16e2,76622f5e,5f6894da,2e0c1ecf,c4af05d2,990dfa4,25294dc9) +,S(a5eccf90,a29388ab,de6fca2a,bf216145,7fab8bb5,1e33d4f1,1e0acda0,f5c28e60,afd75916,468a11f3,73e88643,56690adf,110e74e2,c81123f7,94805b26,620e3ac3) +,S(4251bac7,493678d9,f26e52a1,e3ed9e58,6a15d060,4d1c9cdf,89ed5871,ee9c2779,fa1df27d,92e6716d,76990c60,e6603bcc,4bb023c9,dff938d,3a15ad8b,72987aa5) +,S(77a9e6a2,4c3cc21,d8cf6b97,3181e283,f40c9d0,26a81903,f042c2a4,fa7db30e,a1ef4fef,23f25ccd,bddb757f,aaa10ccf,e78d9310,72b2f180,b6e3de5d,18155aa0) +,S(33fe7961,c40d4e1b,d6ade73c,4577fa2a,e9c0d20e,999f639d,e751ff7e,6fdbea6b,91b7d5cd,4eeb306c,e316e7c1,464c30cf,9a591994,7232b037,5840b8c,d5f54849) +,S(43f66b2e,5ee52211,a48a9d8c,b485be2f,39535701,5249c311,5b682170,f9179564,5370b55f,fec0ebbf,c30cf7f,e63f5f88,3555e699,728e6892,1dbf7874,2da46a45) +,S(4ad36614,97ef1074,d74c7f6b,446ea87b,ad2f0b43,73f5970e,1a745b6c,38b19bfc,8f5dc1aa,769a5bfd,5eada00d,436f850f,6f9eea82,329ebcfc,cd4cd60,ef5cfd39) +,S(9799aaef,95204d54,f3734dc9,75b797aa,59336866,9b2f12f9,155d5953,c012754d,4b6b34a3,d31fe173,43a5b476,bc492d54,44c256ec,ea236f3a,9845a875,e83e6353) +,S(c86249f0,c6e4635c,2d03f252,50e35d67,c1c22f51,6f9a8dca,fbc9d41,15d828a1,e21770b,37dc4d0d,f4d260b3,94bc76b2,46523893,469f1025,86d99467,ee95ec73) +,S(b48dfcc5,de5687ef,c7282c84,cfd4060,61a08fe6,92fb08e,3accdc2e,6656038d,87e3e1f,ec737074,71f69c7b,c7147665,c0b52a95,37ad1566,277b6d19,fce8927c) +,S(77dceb6c,62d65535,c625c828,fd3836a3,146fa4d,36732da8,58503fcd,4e357fca,d90b2600,5a139713,525b8521,3d370ed2,4304d08c,87fbb67e,9091d1ea,18228bd4) +,S(5b588cbf,4cda0184,4df1cd63,3cc70ac8,69cfb43e,332f5c17,47364750,3175e49a,1424ef1d,f9e69e4a,84eb823b,2f95fce5,a52e1978,474697c0,d47890ca,fad55cda) +,S(c087bbba,83934208,8c70251,8c9ddd93,2c50cea5,11c443b7,da107685,9320b20c,77f26a69,717555f3,b030e345,5cbe4b30,f637c23c,7ebc2b5f,6ec2207b,9209d996) +,S(8d16057b,68f8082f,208b3e7c,fc2c558c,247d7d60,f117ea38,35e474c1,3031ed94,3d305db6,62ffd13d,100f6e0d,19c439e1,6ffb8ca7,eec6b14f,ed551091,d6ba3eca) +,S(75fee0a6,3d32bc8,6dbb8cd2,af7371ff,d17daa96,5e1e19d9,242fdcc1,edc184b7,c2b1e4ff,abc30975,fe7c992f,f8091795,61ee89e,9a040409,10bfdc64,93efa2f8) +,S(65da3959,b147093d,7d092599,a87710a,dda7fb75,460e47a1,10d5c1e2,6f368abb,3599e1f5,2f92c1e1,c3f2b463,d9a30230,a6f53028,cbae3ce9,5e345c5c,21862844) +,S(6561fc10,94632125,d76b787c,a7539870,5dda1a5b,f4407f4d,f8140b6f,967933d3,4c06c7ce,a88e2828,3eae8aec,ab6e8802,cd083f37,6d3a1ad6,29fa9b55,920e6337) +,S(c9a53f80,70493701,523041a6,a9d23343,c8a3fc30,6664d6a3,5ca5e7a4,80c4410e,9af470a9,b2e30d45,ebef0dd0,6e3b2736,369d4dad,f2366d42,18344a22,b6e4bf9) +,S(5c1525f3,443e56dd,b009f45a,1b9a1540,c203f814,5f577bf0,3c734597,33b89158,967892f7,cb3ed91a,d74f4c80,3625707b,58574afa,cb99fc02,f5b3493b,eb4f4f18) +,S(3565ccda,d87c171d,714add6d,472fee0e,69bb6ea9,75f61454,d69939cb,541648ed,9f7d87bf,ec2b6358,5dbd09bb,d008b197,4f02d3a7,6a8d54ed,d486a2d9,3462aef8) +,S(4003ef34,c0f5e1a8,afcf29df,42a14a5c,4527d3dd,138b5eda,bd8de661,1d0e3614,67203152,44894cef,cc3d0a76,35839c2f,3d3ead0f,36174e2c,d3c4c682,4c3048c4) +,S(f5c4df5b,37965079,3ebb7de3,9b495a26,13886422,929393,1cf55d1d,912ea57f,b0b93c3e,12a98cc4,5a3672c7,4a3610d3,aca34da5,7d31a968,f30047e0,31eb3482) +,S(bc9f680,e21186cd,ba63533e,56580289,cbe8698e,69ced0b3,97a96793,569e213a,6adffb78,8105518d,50fb94ff,87d204dd,7bf54ef5,b91e1d72,713fa9,b32e06a3) +,S(4dce8797,f1fe8811,453e15d3,7a3e2621,549e8347,4e7046b0,55f99d2a,c9a16516,ea5e6b77,cca7825a,95cfd9f3,7d70d7b2,fc8a8aa8,749a9d43,37ce0754,abe668ea) +,S(f49b5aba,1ef29570,bd72a0c0,40009382,af2a4f85,26511eee,81869d3e,9759b16b,2e496c20,b996e8d2,696125d0,f60abc66,1d2fb343,b4181202,8658e459,d57c7f7d) +,S(26917d4a,7573e1d2,7b4ff765,72bf2948,a2d02f07,7d7d7fa0,54a1bee4,92125ec,b8e47f7e,ae9b66a0,2a6fd2d5,cf8c88c9,7eb12530,a618678,ad5ce83,7cd8f97) +,S(1b4948d6,285a2fe4,98cb71da,f213e6d8,7ead776e,cf8bbcb1,cd7faad4,fb29d290,1ab4081f,ef87d925,9b736c7a,92d28618,d5698499,b2f5e27b,dd30c1b4,24d3bfd8) +,S(14d712ec,8179baf7,9dd9676f,ea99653c,f8b20ff4,a69636c7,7258bd57,99ae64ca,2e1db8a6,424650ec,32b0df37,d72ce3f0,6f38538,53bafad6,d366e04e,380c6ef0) +,S(7675220,41747684,9e1967e1,54445913,a1111988,8b5bf813,4d9694f7,1d952453,3f1fb063,6457b603,3a155a90,6a722de4,de1a5c3d,6094dc27,37776843,ed82fd31) +,S(5ac8e534,a8828b67,40016d02,80bb1e26,a53b16f,96b24937,fc84ba34,dd49fc63,193d020f,68f5fb7b,2c5a429,6909ce70,18568f87,115e987a,8e5e206e,b8a1fc73) +,S(87cddeb2,8d16562a,531135b6,193449e,d618d0dd,6acf6c43,3372202d,ab4a14b8,5c1de4e6,7c958ad9,9411cecb,de2e9129,cd709425,135c84b,e5b68cba,9f846e2e) +,S(c431ca25,a39ed09f,48e1dfe7,afa86630,4d4f8b7e,eb0d6d52,f8c778a0,424c84cb,450607d6,5b2dbe6d,35cf2d11,d3129330,489eded6,e35ff429,2aeae0a6,7100d825) +,S(8c5021e8,985c1a11,4bfaf3d4,40edc4a3,aaa93002,5c2f2c1d,9bff3683,88a3dd5a,4cb960aa,8077d81c,71d74ba,6096fd4a,b6d31fae,d4315db1,3c2b60aa,a12fb108) +,S(338e54bb,38a47485,8c17c07a,177dbbf,6e7a14b,26781bb7,70b9d717,6e513d4f,7876ae4e,84cacfa4,c22951de,f67763ba,c44a6ad5,52ee66fb,92f80cf8,c4420548) +,S(87f3bca9,efbb3a21,917683ab,ccd268ad,3c7b0fe1,7eff461b,cb06ee8d,2f1f3c5a,a7a1d2a1,ecccfc54,4881f258,bf5fbbc8,e5cc11f1,a117c7f8,361a33ed,55229b61) +,S(f4023df,8ed85856,8e56a037,5a6a78d8,de27d6dc,467c9aad,52407bbb,413a3e40,b2499142,fc4e3a11,6aa30e56,6d59f373,d5e2c545,3e274161,5cff9f6a,1fe178cc) +,S(cfb51fc6,d55a8a22,89d3d282,fe63b2fb,453b512f,374e01a8,92708564,9c6f2d3a,8d4a3223,283811ed,28ec120e,761e61d3,e4ea5312,1cb2525e,b567fe9c,9070635d) +,S(59a44a0b,97050147,bf219db,22249635,c45f77b1,1721c486,8937ce96,ae43c539,31e1ca6,6a910f3f,1de1d0cd,55eb8a76,400ff959,13774efd,158d931e,7039afa) +,S(b99cee56,ec277a37,6ab44628,14bb3a8e,d8e26d73,19fd786f,8ab570e8,28a8ee7e,46e0f398,dda05d4d,7253b16a,b4d80c14,b6be5d31,d1dce230,62ab1135,c23494ad) +,S(a39e136a,d96b1a22,6d039872,5da75b38,1c6b922b,52947cb0,25207ad0,d172bd2,7a5c0758,74de08e,3d10fa71,79639fa8,7dbfc977,8af1a3a2,d910a1b9,b6abb532) +,S(6e8b4125,3b2eb74e,626dd59a,eb7512b7,2c23c855,35f479c4,5b48d974,57001976,cc0b88e1,e4e8c045,5e804068,acb85aa2,715bc82,ec21ab47,873999e8,cd2bc88e) +,S(9942b6f5,681e4189,f7fb6ec9,8efd1343,cd1fb66f,1c98e418,9c44478a,51abb019,200d0ebb,b0cc2d52,90a11e6f,f7c989e2,d2fe986b,ed266430,56951679,8d0e7a9a) +,S(7fdce1ec,3c57b949,44166918,b48af352,759636f7,2eafd744,642e0f7e,5078506d,d7785aef,c19a76e3,73b786ed,1e2d2ce7,53cfb979,65d3d46b,2e313a2a,d7baabd2) +,S(6f13205c,958c83f0,f170906b,d77c79ab,5f51654d,88195b04,a70d4e06,93989c57,8ac9a15b,b386e483,b268d4f1,c950da35,33deb99,55116c99,e848f13f,73b55ee0) +,S(f955a35d,833c69be,40a0665,f4dffbfb,cd405f4f,5b4247e6,e50cd4b6,3697654e,89f4fbce,22468389,a4af2407,f40eb37c,f56e80b2,7da1983e,4e2fa4f5,8bc9ee44) +,S(dbcd152d,619646a3,42a25743,1df9798d,b58b8d1,89238132,e65fb6a8,26248007,66fa717e,c1948fd3,e4425e9e,2e6830f7,e57d23e3,d0219dce,c02b4d36,32d8ba13) +,S(f1aebce8,e57b909f,ac7cfb1d,a2e7953f,99f713b2,8b35b5cc,71eea153,5e6e8ebe,8755fa14,3e77e5aa,60dc24d0,92e4f596,88b0bfd9,585fd57e,1b7f610b,e5d9d516) +,S(a202164d,941f84bf,f89ceab6,50430905,c002bc5a,91d505f5,fef6e48a,4b55187,e0cd42b,2bc268b5,1e572e97,8b9bce4d,b6d4b095,ade884c1,bee3b3ef,c2f057ff) +,S(572e1657,46fde7de,9480eccb,287f8b9a,b1344da5,8026861,e784047d,ca8ad68a,c174ade7,c066abb4,8d2461eb,405dad76,39eda86b,a0fd170,47569617,31eb5d9f) +,S(f4e2c907,fee4d753,c08b1052,b76e49e8,b67047ca,59e64dac,58acce9a,5beba31d,b243aa2d,3a92d2d8,e48b8317,ca8fe897,2b76d134,248070f8,f41bf871,2c11c42c) +,S(a6fc6aec,84455716,f5e9e436,d68809b2,26698781,f24d0463,e06963a5,fdf06dd5,dc16a615,548efd18,6ae135fd,f748d9f0,a96b7f4e,918513d5,73900aa,1818ca8d) +,S(bd806817,5fde9652,9ccd8eec,937f2cbc,c4ffb3ce,b04cc9bc,c00cde2d,5a05f026,b2791ae7,8e014328,e0fe6a0d,8b6bddc6,db048274,5152bf76,bce228b3,64a26216) +,S(f888a667,6f8c3d20,b9d5e810,ecae6b8f,2d8614b2,3a5da51e,16386dd3,5c0165ef,fb4ee20f,e429f3ef,f6f4bfe3,9c7b1ebb,57978853,de242239,42a3dadc,909a0dea) +,S(7c8d1e05,5adbaa71,ec9023a4,8d160fcd,c3182ee6,bda76fd2,3ba8877c,409ae200,8a3b820b,ec595523,d96936f4,fce83779,c489b9a4,f2c8c524,f16e1764,2f907ceb) +,S(18886ea4,ee257120,610ccd71,593baf72,6dfd9bb7,5229959e,75c14e76,26fabf43,266c6695,f57068b0,d33ad3f,7d02b7a,898a3184,39889d31,ffa98d86,e091531d) +,S(fea70f1e,38c8adbd,3339a44e,cac036b9,1242a099,506789a3,184fdcfa,6be52cba,9dff6df5,ba8c1b9,ddc58093,a36670b6,76c0e2f,d745c468,83e26ece,3b9e7915) +,S(4de30389,45aa3c90,76d99142,e79451b8,96dcbf7b,fe420c8f,b1dc4b4a,37d1365a,cee74e9e,9093de64,2401eb2e,201b3377,992ac0a2,13b0b16d,35664ed8,d287cba4) +,S(67d09dd1,eafebe79,c63b8c40,1c102982,8c2d8e6b,6b5bfda3,73988830,1a104fb2,10eb5508,92660d96,8e99049e,818f89bc,d4f03558,d9f2c984,61ffaa5b,bd360a5f) +,S(2b5d70fe,186834f8,d3b96d4d,87031cd5,325e55f4,ffa31b5a,f5ffdd77,40e6010f,646e7e53,24d2a373,78b1f54a,fb2081b4,38439890,c9f53b1f,7bda4d47,a895ed02) +,S(cb426299,8700a76c,193f7b44,6aed0ad0,5d600b23,ca24c752,527f62df,e17be248,92843e13,f3eb60c9,e5f74eb,8cce7723,bcfd0250,4c2186e6,5ace939e,5819a8b6) +,S(3ee6ab7e,75b3bc57,135ce4d0,1e6de88b,22d0b853,fd8e0d25,f9b04ded,418e4e41,69c83f98,4e52519b,931b6afc,933f5200,6ee1ab4f,680ee768,9ad55368,1b4bcc87) +,S(583774b0,a95a5143,17232df6,f17d7829,6918acc7,2a385724,e904085f,c887e7be,33bb1e66,ee8cf17,30c16073,665c353,f8f047fe,150b4424,18c736aa,807c3e7b) +,S(af32e1ef,39822787,79082b77,2a643ea3,eb334100,9a7a3fcb,a8838e0,7079dc1a,6985e28d,c660123e,73aee7e8,b1a36697,16938331,e4b4b7f8,b3a9ecb7,4e95fd4c) +,S(6edf7fdd,32667551,9b60c740,efbfc3f5,50f7249c,deabbf9c,948adc16,e034d0c4,f08c5f18,5def7da7,5fb0de81,9b092691,64534f14,bb7d96d4,bb4513d,ef46026) +,S(3b9a6645,5d268f94,6c504120,a81821e0,86257a60,b3fd9f00,72a0a4f0,1f16b42,ed583a15,aedf6c08,95f60109,6190106,3dfa4848,645b0117,e2e1bddd,2cfe7c7b) +,S(bd035b08,2b5cfdb0,d17cbdf0,7a012b0f,27b52943,82e8bae2,d683ad0a,747a1039,6494cbad,ed4ad7e8,aa135ccd,572be8ac,e94a23c3,8b62bf61,ac90f9a3,9bb2ef54) +,S(e25fbf19,fe9b180b,ae3316ef,89e0382,4dda59b1,41022ff7,a8c45b44,f15338c3,45ec47f6,58a3dd52,34241258,1852e694,7c2c8f11,9f4fbbe6,f6388363,174c7cf2) +,S(2e231dcd,8ffd7356,52ebea7,50165405,f30f595c,3871ee6c,7c072e64,ecffc9b8,c664452,db15961a,8458f3d3,ea24ade2,7610d4cb,ee51927d,29cf3164,6f59317a) +,S(7c0f29c9,3932626f,1b1ae126,316e065,fd2a4174,a66a6048,3b458660,f5338fc8,27ef533d,df6f1272,c0255d7a,587f56a9,b76e2c4f,98c98162,350233ba,75cd037f) +,S(e702d61c,ea6f9fef,fb43e014,4794fb32,7bd857e1,70b299ba,31bb6a20,7cd5bb48,c4779881,c924ee3e,7f228a71,2de07794,ee5e28af,ca63af21,12ec0eb3,1a3f79c9) +,S(f1780044,eadec1b5,bee75c11,7c1647ed,c362c5a4,35a66d8,cc2ae45f,66c852a8,5f8de9f0,f31b3977,f08f63ac,1380310d,e8b7a304,85c9f0f8,9a677572,329e1c18) +,S(7a41b37f,22ec5b18,d4952c53,326665a5,1582ccb7,1660b69f,8d00701f,1f12dd9e,8440be13,2c57259c,80cd74d,2a2f1e01,3448865e,2429c2b9,db750951,607fc443) +,S(94fff7d,8111d69e,198f4e16,57c3551a,a5ce6316,d520a779,ca4ccd0b,282db6d3,482c9270,26c0c05,578a75d3,8b1d8ed7,42541d30,3a933b90,9c3249bc,505c6fc0) +,S(d6a6d44e,8a3ffaa9,56cac76b,1b05a4a9,d3775989,2f70e560,a54c9440,17f4e9d1,48c3bb22,cd839de9,9163bbe7,83a8a057,c7b93e87,de388b6c,dc57ba57,90863e1a) +,S(cc0e25c0,8e24edab,1e5dbc47,71543b92,c47c0993,95b93d53,699204f9,50cdf80c,20c52cb3,7170cf3b,43b76ab2,cb4a6d3b,1a977c55,2431b8c8,220282bd,51fb70b) +,S(cf953f68,4cb7d1af,a125d0ea,cfb83cb5,efddb6a4,41079be3,db72573b,62f8d827,70cfe366,a45d11b1,a847a7b,8e3e50a3,b302fa50,1afc89ac,b89eddb,30909c0c) +,S(1ac22694,2b34ab06,ff16b711,2fd5fe1e,f8ce6975,143ab19f,bff99d6b,6815d5dc,a43d457e,2bd0975,4e9b7fdd,d9e16681,1bd823d2,24476615,4d9e3fa5,ab6539fc) +,S(d02bbbff,1153804a,f0f800bc,f959406c,496349fd,a412e9e9,bb9f7232,7a4d65c2,5de80de,3c7832f7,1d744f9b,9ef08b56,d41e682,1c20f2f2,876fffc1,b802a384) +,S(3ccad347,8d464ee3,42e1cc2b,2c4b299e,d8a60326,4837a040,25a8525b,4f1831a7,35ea2a4c,a59b55b6,ac79fdd,6ceb3401,47492f3e,49b5035a,f3036b26,d02691c0) +,S(eac4d554,3e69c3ce,d762e90,fff84b3d,b3a758b3,419d06b,80f7ba43,36033688,aa64fada,c54374bb,fe8449aa,ddaa1846,ee00fb6d,c9435dbf,17f6a12f,d1deacbe) +,S(3d2879b1,73d93713,3326d0c6,133be281,5df62465,d3dbb7a9,a028e0cc,63fca753,576ce64d,9b95b5e8,a9e3eecb,34cdb8d1,fd38a08c,2a6a8c9d,8f0a7296,68d6e0f0) +,S(3f58ab8d,56a9682e,25137087,ca8c766a,72358a56,99ebbce4,cf74e304,6976ca14,3c9053d1,1a2a8a8,1f30f45f,1b480dad,f6bce20a,15e6315,447405a7,b321f29d) +,S(4f5f1289,b48dcd19,41a9df0f,a8aeae42,2a4ed913,58845b97,3145ddb1,13fd12d7,b5c3e32c,c40c6577,3e286ed,a233ddf,42ac0d6a,5a3c3e86,77f8256,e0dc1428) +,S(a64a29e2,a52dc6fa,e74e70dd,da2bacd7,e4a9dcdf,f9a0bbc5,ad0392dc,93376a76,ade2f8a6,faa9b1b7,7baefe87,33ddc365,c776f2cc,b0e5730b,4ebb0166,418a9590) +,S(dee0aa12,c4d6f88a,d1d86f94,e1c6d3e0,b8694b5d,e234af04,994cc7db,c8480e70,cbd9acd4,cbda37cf,a9d368df,332d30d6,413ae1c8,d34219,3d4651f8,62f93389) +,S(8677a99d,c8af6ae1,b653e294,80eb66fd,772b958c,882fdf74,f9c0f188,d5796936,31c668c8,348c048e,4b7a24f3,a0861f44,6621151d,4dc3e9ed,783eaf81,ff97232e) +,S(51117d3a,cb73a7cc,2b229bc7,9bd6d676,f44aedc1,98cedd80,ed6178c1,f6997fee,5c638c04,123f85c1,170651d3,96343e,78f20770,321c1a4d,174e568c,39110cd6) +,S(48d8af64,69670828,e87585d4,52ea1242,a83c9f8,3423e468,9c3ca383,9f141b12,558a8f42,f07f49a7,c6a9843b,9055ed05,1998dd35,9406c40f,dc4d64e3,5265e9de) +,S(62ba9ac1,b0fdeee5,a143d457,41c164e9,d4060c7d,f5bbb17a,ecbe80f5,f6966d2c,65a0653f,2290416c,5fc96494,b70b3b99,9329fe67,3b034aed,b586c118,a5d9450e) +,S(be4df7cb,679da56b,50ef2058,3c79310,508d8d05,43f3004a,486297d2,49febf0d,c1b56550,dd5f3e7f,a898cb8b,aca88694,ca697306,fa3fa09,95f6c43c,d5f3ba9b) +,S(e49c036c,cca2e068,5acdf34,8473316,424eac2c,ce1550c3,a0c435b0,28c9979d,456bc25f,457fde5,5bd0d273,d27afd7d,21186b1e,3b42bbca,b168992e,61609a1b) +,S(ae6845ed,a81d5d90,b3fddfc9,cb774c2a,976e701a,ad5c1302,7057a6f8,97fd58e3,529bdc55,322ae360,9926194e,7539a534,4501126c,e69b3e11,e5b4a675,7ed755bc) +,S(52a1d8f8,bcc2b772,cc8717e0,2d713864,4c274499,4a19ed18,3fbeae31,bea25e1b,da2a0b2c,e7f17894,848e77f9,53b7528b,dbb80673,c70341dc,9f869e60,4189011b) +,S(ffbbaf01,d89a7804,d5d19f50,dd5a4abd,cc5529c,90d26918,425f3805,96a2250a,88b5f7b7,eba662bd,5aa47a6,c2fe1322,2d514410,f6b1a145,38c37ed9,9a9880e2) +,S(6ffa438,aab51ab7,afb840ee,d4f85725,4473fbc8,ff6051f9,fe5a59e0,ff8c942e,5b0226dd,3b88a040,33860dc6,69613bcb,50a0e95a,2ac7df8e,66884c7e,e602d775) +,S(9c895658,f92ac47e,318f5ee5,91d26a10,c2c1b77a,c8bc8cb5,a45ec943,8a2fc79,708071e2,665ebd58,f1655e28,6de258ec,ef4b0115,ff74f38e,516acfa9,c01045f9) +,S(532e6e0d,efba35b1,3fdbffd1,8ebece3c,a59bb3ce,54fbbb5,df1df6f0,c1861ba9,1af465da,d326bbc3,eb732ed2,464b4593,36f04b0f,a50ba7ff,f61b4754,aebc5b8a) +,S(99043321,e3f27092,cdadd8e,b50cb4a3,8a8a9f80,83da6ea1,38d48e00,e5fff425,11be8597,325c250f,d9e5b1be,8e52c336,404ecb24,df29b786,ef9d1f04,8f77ea6f) +,S(96799080,3a0934a9,9a0a6e94,120c22bd,7d79085c,c331e172,87daf46e,7c4084f9,ea90012d,18450bfe,6a520b5c,9b2812ee,574903aa,d75cad04,7dc46c23,98005e03) +,S(74f5d157,915ffe10,cf6d9981,9eff7616,1f36f71b,4fc386ab,729dac37,3aa0afb9,54a0011e,4922bc74,12ae225c,dcc8c447,4e4ce4a4,941a409a,2c49d421,19b29eb5) +,S(12692753,81c63955,5700ddeb,e8d7a751,76e5f3d7,2aa0631e,3e7cd6a8,c1927855,b92e5076,811002d5,44c554fa,1e1d10b5,3eefeffd,513357b7,2c5e0cc1,c39ae553) +,S(84ef81b,1d143d73,5b6ae35,af18d810,d7cdcfbc,dd1c68e1,1aae007b,80230d9f,cae39a2b,a5b4ce8c,21ebcf2c,638a2e5a,b0dda645,aa6e01bb,33ca2edc,b575d42a) +,S(1c22ada3,326e6ac7,6647af5e,ed62a85,c8d89dd2,a733ea62,dd71512d,ec9037ad,f5a598c6,1562a6af,99e46283,cb9e6fd4,bc4142dc,99600b64,49304981,16aab458) +,S(6b91ca4f,f08eabd5,aa8dd35f,e9e04153,c00f1f48,50bbff4e,73671cc1,fa4aff1b,c6cdaada,85adf99d,4fb68c8b,6104f585,b3c9551a,7dd87977,8cb250fe,11b31852) +,S(57bb4999,6d2e2157,613f0321,983736e4,b99063b5,e8f7188e,23f7895c,edf85bc2,93b46dc6,72eea90e,9274b9b2,73a82da,d0a1ad14,55b550e,94fdb765,ab47cc3a) +,S(75790b27,ebf7566e,1056d9f2,463df8f0,67c38a2,78af81cc,b40f5260,4a33ba6e,ca0c8ca3,d99b0a5d,b065decf,346eadd4,3af8dc71,9ae06dac,6be99c5c,b89d2045) +,S(ca7a75ad,a90b590b,f7f2b6fd,e3004a1e,8dd7b4f4,db8c4a08,f32bcbb5,474ebe9,b3278d9c,5c9351e7,bf4e8a08,e0f1dc00,51273259,acdcba1e,fd3ded69,83fc69e3) +,S(a6dc68b9,3bf46294,392a8d6c,e52bb365,47b65a5a,f318765c,7a4f5d5,2f90b2d1,41ba6d67,fc575561,a0f3c76a,931dc62,37f53348,819224de,8f925c33,c90ad45b) +,S(da2139f3,f8afc90a,c7f5a025,20c36110,2fafed4c,3f525b56,fe0dae1f,6bb6bba5,95adcb88,fa9ed816,dc097522,de5a394e,71e92c1d,f5bac36,9ad06067,1b6349db) +,S(a32b2475,2f0e0063,acb4194b,faba9ccb,2159357b,23f102cd,f5a8e24f,413da4de,57df4143,bd8b27fc,c7716ffd,8c35036f,e09f8ab8,34f053db,ddfd3161,ebe576cc) +,S(aaea491d,33824ff3,c7319d8b,a233c73a,741718f2,2c921392,b893894c,ade9bedc,c8fb291,84d8dc65,93a6a3a1,a5aed86d,a7ad0d32,d5f8ef4e,b24b6154,4c1a63a7) +,S(2935e0e2,7a8409bd,224f3eb3,d68fb639,ccf75d5c,2b0315e7,ed388acd,887f2c75,c4ff024,62c9ae40,983d0068,180d4c3,977e900d,fdfc164,c89a938,c568aad4) +,S(7fca8076,9e2e7253,5834259a,abeafecb,fdebbd96,5066181,63d244ce,770fe577,a3ddc3ab,f04ded22,cac3b8f6,ffd14ffb,69cfecba,7dbaeed9,9a5e13cd,55bc3542) +,S(c5b5f1c6,1caa4a7,fa5e665f,57b45134,bc129ec7,131642a9,6a7b4191,5e8b483e,26cb3816,da5098cd,a3f58fd0,c26011e9,73dabb66,d8cc9257,6d37bfbb,9cb538e4) +,S(410da274,df436772,64decf4b,f790035b,d7d5b174,cffdb4f4,56bfb6a0,79a50d88,71c81968,188eb349,6dc2ef1e,841979fa,254a1939,5bbf00f8,8e1d2bbe,ef9a6abf) +,S(3d9928ca,334dc800,abb6c5a2,43a2681b,6f7976ac,50abf387,54058d05,cf67769a,cfcc01dc,766127b5,3e183cdd,80a0a1e4,62bf01ab,c4df115b,2e4f4e9f,95d2beb7) +,S(65a8f57b,c523e4a6,4777ce31,2000a322,d858eae1,f39fc919,2e4f436c,c8040cec,820698b9,9e953745,b1ff7b0e,a22bff63,c9df69fc,c2055b32,3f07fdc0,61192432) +,S(84e553cc,baa606c2,ffd3ef5c,a62725a4,55f4e539,24a72153,1ac3e66a,5d92fb79,34d6af32,4aaa9465,fd9f7731,1c01221d,4c0b5f75,1902dd67,4dcfd0f3,9cc5f8d2) +,S(3b4a7558,28851226,f391578d,5d146da8,dda3d4b4,f79a36ac,5f8c166a,773783,e37c96fc,4de83cc2,eb4b3cc1,44d4d35a,1a4249bc,4cd7c787,7d0084c1,b1a59e53) +,S(6dbbd12c,6164e8d,ea489819,37fcd12e,74339578,6482ddb8,9226d9ef,50cee6b0,89e48f49,b3f5d154,52e47c17,e1a68ace,eed3bc6,8002a70,33316116,ade02b90) +,S(b64180db,3b926481,74a0b743,1f84af72,f1118e9d,6cc1fe02,f0bfb72a,97c441f6,b394f997,83d00816,267a4f0f,8c95a05c,33cc19db,eac704d9,9e1f0c2c,4fb25fd2) +,S(2173f38c,f47377c6,d977fc08,ebb67f29,37e96fbe,e46b2115,b260f03a,216b5c56,bda02a78,3c4a684,fd88c6df,6becf56,3bd1c61a,4e79d36f,27e22fb3,212e2abf) +,S(9dd9ecd3,f3732f0d,864df0b4,8cf35e06,ea2b89a6,a8a2756a,222e266d,fc5c5214,e42ea720,2ba68242,ed9256a,57db94ad,dcf00b1a,50ded06f,a70d712e,17e921fe) +,S(705f9fed,5cebb62e,dd549526,af729092,9d398232,604d136b,2a121cf,e7af71a9,bb2cb17d,aa4472eb,12e69a4a,57a7863c,2b32c100,a1601d2c,44d2cc29,750d30a8) +,S(f1a908d1,807169bd,7fb7fcd8,cfc125e3,3fbcdaa2,8d8df1a2,17b84c2b,2cef4410,e86cc08,804c6c56,f81cfa75,9851e67a,d792bbe4,87812cc1,4e7aa468,b8911512) +,S(db0c5d79,35693c81,c752a475,6852260c,5625e434,5247cd5f,d40cdc24,e1355f57,120c5ea9,fb00d295,37721f1e,2539ebe5,d0de9bd5,354ce629,fe8c2e8d,c683daea) +,S(5e4d5935,56007e92,1b158f68,3411da86,e979d470,7b53caf5,9a2ed94b,ca423ec6,71588b00,1a0e9ed3,27862fb3,7ce6aefd,c309b5a0,928766dc,b947773e,6272d935) +,S(1a79ee08,3c46e5f8,8e97fd11,22410164,a264d106,7ecfabcd,4872af40,4fec7f28,f928dbfc,49bf7553,356289f,18a5c8fe,54f94bd4,d9406aac,c4df7a32,32349111) +,S(e693f88b,e3be0c46,cb40a2d7,f3a0a435,1c3a1812,4abdf46e,86ca3af3,6cac5468,55f0b7bd,24ab2a2b,aef2db89,d8aec5af,fb4f354d,66538efb,78f094a6,dd649cc4) +,S(6d15e8b1,f3c73c76,f73b12d4,f5e96e28,43bb6157,5d0d7e58,1bcc551a,329ca25e,f21f3ee1,84386427,32a0d05e,419f8a59,173f8cbe,6e3b765d,b74c3588,2d7f069d) +,S(48b8f127,b2614af4,95303f2c,f6593d16,20dd98e4,ff536dc4,8a5aaade,3bddb682,8ed1b9ba,ec137c62,5127e23b,55d786d6,a50d191d,6803ae99,c7ce57ec,2f546e3f) +,S(2ec32631,ee1e4510,94719f29,1a32e0a0,8c29fca4,8ff7e3d4,170a7c0f,5aeb3028,eb861d9f,e21b536e,58d0ee35,9d07d09a,491572f8,13eaac91,6105785c,697aa945) +,S(f7960ecb,3b35d4d4,5ed2c13f,b55cc944,7ab72f66,ea1857b6,776b8ca0,afafce3a,90245cf8,d40f6b40,a7140334,da02eea7,d8f7cf7f,8f87c510,cd6d9ae7,8410f08a) +,S(a94ccc3e,4b22f7e6,ef385780,d58f3aa1,139b29b8,c7dcb5af,7a247125,ba613ef2,ef7050fa,dd6afa0d,a89ba357,cbc6a66e,782471cb,8cfa4c45,e94d445d,a2845409) +,S(e48a7ff8,6d80f430,d3d6f57,6c56f026,8c42b3ed,17086399,56d62f54,f5485c38,b1695229,b4997b0b,229e3c65,c7ffb42b,e429b702,47b98231,a7bd9c5a,5e9a6255) +,S(df99488c,7d46c83a,cda5b422,b2a633d6,cccb09bb,f6488d9e,ac79e9bb,7f22d2ae,89490280,a958f45c,4501a878,5bd3c72b,aaf83a45,d91a38c3,e0477562,f345fd4b) +,S(a150c6c0,4db9f9f4,6f64368e,bba348ef,2bb4e43e,29b27770,553ef41a,ef22fd84,61dfaa74,e1525a0e,c3922ab0,20e3ed1c,e7b5397e,b4485cca,e1f64f29,19c5c201) +,S(9b7dedfa,452ec6f9,1d7aa167,bc984a28,937392ff,d856a4e1,204aa541,f3aa0edd,a37f4912,2f5168de,bca0ef6e,7c9b31ab,b4262c09,ccadbe79,10a4a844,ffd2c74a) +,S(c7d77a51,6d0cea71,b20f75c5,579a5906,ad1aa83c,f9209a23,d38ed358,28e51904,399a7c7d,9e1a3660,37b0a7a1,49b0dae9,8e5a288,cb5ece7f,56de4d8d,74a44bd6) +,S(d313a829,8e4de5b9,a166c2b0,f73d9812,fc1d1dec,b3b86e8d,8062794b,42fe73fd,6524463a,7eb26e2f,34f062c5,dbbdb4db,b8514c9c,60af6a16,fc9a8830,1f708fe4) +,S(4bbf363b,4d66c693,6469b8e,83c4f18e,2e6c2a3c,498f38b9,787607fe,97211e5f,9e42ca4b,243872c5,8c7b6406,11817743,82bb0d59,c0de2562,9f26e8c0,7d1c60c3) +,S(3be10ed,23a0ce86,d4a7ef1d,a667cf19,d471bd37,7467403e,3f84535f,861e9cf2,bb959378,cb317c0,6534748a,49bb9fa8,edfd2090,cb95cead,a7b0433,4066d885) +,S(fcd1f880,d723963c,829074ec,8d29eec4,946da198,cba5d96,b169cdb3,5dca2076,9489bce3,a31362e1,c4cec275,5fa5fc86,d3b105ae,25bed346,7c0919d3,b2a87b01) +,S(b5fb358,993d3662,b2e7114c,d8ea0681,f39f42a8,52cd217c,f0ec0271,fab317c4,89d88eb8,ee622cbc,f0dbfa82,8b04ac27,80a653c5,14df734a,791b3bbb,f3a71b43) +,S(a86bbad1,7fca460a,4740f39b,d2ccab3f,30fc137f,604e77c9,55624815,8fe274e7,c26dc259,ba969ac7,8d294742,e4962c07,1394ede1,263f5a0b,d03b7a29,30753fb) +,S(ed321f6,348cbc96,7e34bc7b,a935d129,9dd3fc94,c27d1467,88792180,1330d29a,b4078360,832b5de1,c77b44d6,cf07bdc8,fc5ac402,15002135,1be0d251,a3f7c3b5) +,S(c8179275,e4ddb936,f55e827e,de094c4a,2c425b8f,701fc979,96ed7194,1ad17dea,d99f1c5b,e241d165,eb49b0b9,266486af,8ce5e963,c52b2622,e16fe99d,d82553a7) +,S(6f08f13f,23b9b383,49274328,3f8dfcfd,eeaf82e,1d91e512,df1d0d7d,de84985b,96b6a829,f99f433a,6ee58ed0,50370ac5,665d61e,22cc7a76,a4a3fe08,d8bd602e) +,S(9443a7e3,410f9d4f,ef9f8b60,9eac3e5f,e6ab5d6c,a11855e4,b35c7e67,9f8f9d5a,d8c507b5,78188c3f,31bc93e6,d07abc22,ac9b2add,5a11db53,8fa0f936,3beded57) +,S(432ea8ca,3ed53681,ad3afcfa,570056ed,d38c8848,de293d2,e37703f5,133c502b,9e19228b,70b52bb0,8e66a49,826c6a61,965dddc,64270118,faa3389b,6bedff71) +,S(1d17589a,42f82fd8,c5a584a3,d3c7fed8,5e22ffea,e2b732c1,30f903fe,1982403b,9f7bcfb4,8f18d208,26564ed0,245f0c6b,511e965f,be5e0e94,54e0f552,78c39ceb) +,S(743399b5,cd84846f,65e778ea,790412ce,1ab8c6ff,ff7c098b,55436a1f,e18e6b2d,dc6cc81a,82801be4,e6566d3f,c01b6fd1,e84ff49c,e5ccf145,fb1f49b2,d8b784bc) +,S(e4378558,3b2848c1,62e3e80e,3b5f9242,5330d232,e05f871f,a279a0da,7910b2a7,c39b4171,aa4978e4,7d3f99f,8179a189,d5e2421b,d076d1f0,80cdacf0,55624b68) +,S(eef768a3,1b1639a8,f1755ac7,d00a6463,8f8a99ce,f5f42a10,664026b3,6718d63e,2a9005f4,cbf4e686,1af0043a,fe97b065,878efcb8,8be29ef5,ee648473,1e24a991) +,S(15db4687,2504612c,f40dce1b,d601d848,fc2afa9f,b2de929a,1800caa1,bfc91fe9,a8b6e64e,7d508d9a,504678a9,d90b82ca,1e72360b,95a2f515,f17710cc,4e7eded8) +,S(ad45facf,2529a84b,9d28d2a0,456a1fd9,d2b3303e,fc78e2a0,c7757bad,d4a4191,1a78e571,473f3035,16ef5867,8f77d5ad,bf8d8109,60f9925a,a6b4a88d,3654f069) +,S(41a03744,6e027b4c,eb775050,a892bac2,1c19b66d,5fa4bd89,58c949b5,b9151824,ed7c44dd,fa96d38f,a721cb2e,60e07a84,27c53acd,6435ce74,bb45437d,95140317) +,S(2020b869,58f4c7ff,2cf64589,f1043d,5a70d5d6,dac0740,56011f1d,27217ae0,111959e2,2757f431,a1994617,124eb1c6,b37f5961,29d52aa0,490b94f7,e1c4e9e0) +,S(2f99a946,859f74a9,50f3bf27,d85a169e,99c5f755,71000180,283383a9,eabd4ba1,3e622182,d3caeaa2,47a4ed24,6e608592,36ecba9d,4e8d79fa,12854f74,df89fc53) +,S(ddcf3989,57f65390,167688c,2e227f29,e7c5675,d4a83a3c,177ebdd1,9e369baa,a700c63f,3fa6833a,239a3cee,a90dd021,c3c3428c,f2b11b87,3da1dc01,2f4b2431) +,S(9863a7b8,4252360,19e2fa9e,9319c5b,92df1eaa,c0b7917b,73bd1042,191ace4f,49a499a9,281dab21,4bf09f8c,724a30ea,3a1fa7ae,4f1b2b6a,3bf63562,e03b69e6) +,S(6c5465f9,ea2c5917,34f3734a,64b8e92e,19cb4def,3c6d5d2e,467a8f58,dd733886,57e22bb,179df35d,15aa2616,a319ab3f,768f655f,a1c07c8d,3dafc443,1e0e733c) +,S(ab375513,360b3beb,d0ca387,fb0a0690,25acb654,fe703a53,d979f14,50f3fcdd,3e9c1149,309a2de5,9b7842f4,3c37a6ed,57f0f776,503ee7c5,46445c2f,6c41be4a) +,S(6acbe3ea,4a72eeb0,b23aee37,905b22d0,ff0878a9,e9143111,4821207a,4c2603d2,1ecefcbe,9f934d96,a163dad7,6c9e6806,ac2ca23c,e495a533,aecb19d,df0d32b9) +,S(7955d144,58fd0c42,5e4ac9f9,c766e253,b4ddd105,7f1c8c3,653f95cf,3a955d89,8fa9c5f7,304387f0,94a89225,53a20287,40c6723b,d25245,84735024,9650aaca) +,S(b5972d0c,90433f,702b25a2,27bd3da2,d488ebbf,e5782132,28c20cd8,35ace377,235470bf,7fbc3de5,279ef70e,d174b2fc,e3e78f84,5c0bf212,cf3d64cb,42b008fa) +,S(a266a810,33a5fa68,a204f3bc,53cc79f2,cc500d7e,4495f8e4,d9cb48bd,4bcf886,31a8b1a1,958d15b7,664390e6,a46f3e37,d52b7824,5b0b91ec,b568b7bd,f55949f8) +,S(1c6412ec,21191b63,5bbbf47e,1e9f7c21,ae7f4f3f,7de0f123,451e421d,44b9cc15,833f8a2c,1111c4f3,f5973851,d0256309,6e7fec1b,22ff969d,82a62284,c42c685a) +,S(ee3532ab,17575b57,9c19ccbe,fee04ff3,8172677c,5e625f68,a7462107,3e0b7fda,f12e10c8,b2fd987b,83dff04d,cc48ee6b,4b704b4,92b2cf53,a9af4510,6e7e8718) +,S(5ed10fbe,4867937,2ed2765a,f7f5b4bd,52ef9a4b,96515e,37944d9f,ee1a3838,8c4eb9b4,9fbe3924,ed8ac641,25dce66,a4bffd7b,5fbc68af,2a8c8633,b4080573) +,S(fe348a21,f04c85ed,69fe7345,f73420e1,b8f6b859,7082152a,15a1d535,d01378d2,d595d446,c9f5abf4,5ceabd10,3e38e423,5069473d,7d9f9911,7fa9cfd2,81f2b7b) +,S(7140369,b7b64ba0,861e1c0,b5ba3973,b573679c,c091623d,bda88745,fb2436e9,f0770350,f9799607,28c3bc21,30c6672e,40dfa362,72c50ad,1f376a54,83a12b2d) +,S(6d14c4e4,8e981e3a,e7ec6b88,b1230096,a7465db,a8381bd4,aa82157,99dad15d,25e4d2aa,a5f2d12a,a4e635f6,db58b2d5,f9c6de8f,b5bea99a,50e5b050,e7e0f841) +,S(7931b9c6,a6837d7e,3620558e,55504e88,4dffe071,5bb628d,aeadb0af,1a4383da,586caa73,320925c6,ddd12128,bf3bd38d,96b7a904,8422c2ff,9d5cfede,fbe80c0b) +,S(149e9d6a,35b83d43,5d0e1f32,a1518b88,88dca145,27aabd95,b0ecd0bd,e5cec834,45807aa0,fd84cc65,e91d49b3,8d012fb4,f87b11cc,1906e1f,cbc74c5a,ce5606f5) +,S(656b276e,b4b351a8,222f2b59,d7949010,1bf6e696,c284bff7,b809bd27,d297394,8746f309,5f8643a2,928ebfa9,a0e35893,905eb6d3,faa8e5d9,b6473281,7b763291) +,S(60f399e3,68086989,ee62370f,f7852e1f,3656a720,539880a6,9884b60a,f1eb02e,55dca05a,8347be14,85251676,d20b779f,9e5976fe,4def267d,4f1b2b6f,d444ad59) +,S(4dbda303,a67a41c,a46f417,54f9bdc1,34a305a,9018ce0d,4cadbe41,886eaa13,e062cc86,fec33458,d65f9fe6,4433b745,909a3b95,d23d7970,c22585b8,3fa48fc4) +,S(816ae1ca,4d64cd9,5a7c10c8,fd819c6b,f8c8b1c4,f495b111,d07f2a00,dd0363d1,c09f6bff,c331d6fd,56ea5520,8e9d13bb,b12187f2,d49366b,2dfd1c18,66526009) +,S(45839f9c,983fe0a7,c3b2b8fa,e5e288ad,87202944,c16d60a0,f18daf,8081b52b,f9368e07,4de74eb4,81f7beb,30835af9,aff40c6b,cda104db,2a785a6a,65dd8649) +,S(50ae4a48,3a49203b,1e04c482,ec2454f2,44b7157d,b23bcd50,63c5b6e8,d4223465,e1b8cfd7,e7bd2e1f,65f2031e,c583bda5,a619028,5c364658,36dba37e,7d5f3008) +,S(df77b231,60395089,19edde15,b21ace77,c5d8bb4b,ed26f9db,a694195f,616b72d6,8a4b75b8,9ecebfbc,b88cff82,2673665c,c99e270c,b33f3037,17dc9500,8b4344a4) +,S(ec6c0e19,978e2f18,b74419d6,70274075,6d2d238d,63b2d345,437b0b8e,f233277d,f90dab9a,2dfc4cc,62571dc1,35bfe4c6,96bd3968,173ced8a,4a363f0b,2636e553) +,S(2874416f,90e7fce6,a6d4eacb,1a722218,5af2a885,4852be4b,a4619011,617b3329,1f323675,f6ced648,8ba4c9af,7912ad7f,b8628e49,5b4da82d,448dd265,eaeb4466) +,S(872367ec,586d3a80,f8c87f3e,83b6dd3e,529de5cb,897c9d2b,e7dacf3f,70ff4247,e5bb60e0,fae0843b,788768b5,e427e009,7dc571c9,e4b62eec,eef68512,a6a3ac05) +,S(c10f2004,baffd30,ae430ce9,40c4af34,4339a0b2,13bf1f48,91b8da3e,424713cc,37be9055,f0c39b36,c546d456,b3f82edf,bf6dbf79,6343ee59,c3537fbd,8631c7ee) +,S(14e12ee1,91c83005,6bdf0f15,3353e80,733b8bb3,b93bc59d,a356dd94,70d847c5,e9707b8e,e00c1781,12b32ba7,c66d7245,d487f032,18d20da,b1550e3a,9befcfb2) +,S(dac3ba1e,2583379d,d2cdd89f,6ad053e4,3687eab4,ae804305,7b57823c,489fdf36,45e3da4d,88211519,55c20ab1,c2d1ec4e,d13a6942,fd37bfa4,7614745c,6fe2c041) +,S(d9bfc67a,5c086ae,e879fad0,b03a5a2c,a2507dbb,fdd2cb09,2644dcfe,bf800bf4,e015dd4b,5a39f5bd,1536c8b1,e93490f6,e5bb4e8e,b23e6ca4,2fc14634,2be6730) +,S(de6f3452,2f04ca0f,170d7e58,1d965982,8a9a981c,12f6cb34,761873,7996c61e,1ec16f3b,28d74fa9,43b9c251,f34e15f1,2fc6d814,ff024e3b,826054ee,f72a0cc7) +,S(432ab355,338e17ae,884a15ef,2365283e,b35c873a,4fa8cd93,f54bf828,a0e30eaf,f56066a1,a130dbf,8a3e076,720c10a5,caa9af0a,7d86ab9e,8703dcff,95447807) +,S(3d2e3507,cfa127c3,a350f546,d95431d4,8d96990d,b5beaafa,35a408d6,7f7c4d99,da60885f,4711c373,145655ca,b0f8a235,7f4a0508,2bbd2ac5,1b255593,a35f74f2) +,S(7f3f431c,b96dd4be,37c29d0a,55f3b71b,f781c7c6,191983f,4576e518,24ba87ef,f4df4345,7649d24c,2b8259f6,f7177b96,cfdb08c2,4e9161c1,695c8027,60b8bfec) +,S(4270bf59,f2c87000,44b6cdd8,b558e6ae,6f7b67d5,f128d716,3d604a7f,2f687143,358cef,2e8ff919,6865da0a,15a25524,6c4a180d,ed25174e,d08eabd,4da99315) +,S(c663722b,9930fc9c,4113af50,d51c6539,b7931cab,ebe2ebd,46f95b8c,7f603852,3443e7b3,2cdf23d8,eb532a31,3ca4b32,b94768c,78f8f13f,719708de,925ecfab) +,S(b0014864,e396ff02,cebd7b65,c66e57f9,168e8f3,95ae614f,21f8f162,c86c4e14,3f6c99d7,e2ec94de,ee65007d,ab501230,4a80b69e,a0e0672c,b7dbe4ba,182eb876) +,S(64c9cd93,98fe9da3,5d3329f0,ccb82e43,c2d735f4,d2467b2e,1250c410,da84f41a,d24b50ab,71bf6033,d1206fc6,dcedf049,c223ef78,ff50905e,c8d95115,564372e9) +,S(ffe0841d,51e05862,4f759706,b27db960,ecccfad4,cf326736,ab4fd9db,cd29b766,6bd1f1c9,f6956c10,4fec1595,24d8064f,eb5d8391,30b34a01,77c07491,79cf2562) +,S(d1dd0c0,c053c597,bad38d63,c40d1e7,4b451861,cf0f20fa,47fd3f9b,77ca7432,34aa97fd,b59495f0,3e7b5628,daaaf66b,5c9dc5ad,de929032,80ba23bd,6c55976f) +,S(87a436e8,c76bd7f7,a3e49cd3,af996f1d,9153f704,1b185d8d,f99eca45,ae8e5779,8d2cf3f9,12553844,ff905d5b,2a1fc36c,369ea4ff,6a89a027,b6dbe797,f11006f3) +,S(a54500a7,4899c440,384f707d,a8fd62ec,1801070d,cd5396e4,b59e9ecb,df27c379,e216444a,6d26bb06,5f5b5e5,72c927f8,5315df3f,11da2cae,2f334572,33cb2668) +,S(937ea4f7,99a319f4,fa5aea85,b48d6323,28417b72,8690a9c,88fbd51a,57d8187b,2931a7fc,9eb4aec8,b7dce4af,d14438ac,fce77bda,a7d3e7bb,b24c8554,cfdc9d9d) +,S(50793c76,bb914aa3,204dbc96,cb04ff26,c7060863,8d497f07,a1eb05d9,b7fa6f36,afaafc78,b5e30762,b68940df,41de9ef3,d963b603,6bb1ffbd,eb13fd67,4bdab21) +,S(8b600630,fadae564,dcd1c570,9bfe1ad5,f8da5282,61d55bf1,3a29766f,6d8bb5a,fbf1b64a,3bd0439a,ec45a7c3,859374c1,7885389b,9c201f4d,c1142120,6b2916c0) +,S(14e88bdd,e32a15ed,a37c9650,ffc18ba,1fc61643,22b167bd,635f3d02,e78c8458,82c1ec3,dc240faa,5fa355be,475afe0b,5cc2cd13,760249d7,35b1efe9,976f02c9) +,S(c201e4a3,24b68472,d453dc02,8c78b1c9,975a3d92,efc70a30,a912fcf4,991c6c06,263a954,41d6e6d0,8ebf3e50,3c786a12,a82f5f8c,d38dccee,62469e9c,f0e2dc08) +,S(4097665d,319a8b3f,71861b1e,11828cdd,4094182e,611b35a7,c5d10ee,99db4fb,ca0d7ceb,b1aa2b1f,576cd1ef,56ffee03,322a6b95,505727a8,5dcb70d5,27a506a) +,S(173d287a,eff9293e,dd2021a0,4be052d9,3713341f,37a537a4,45deab49,b427fa92,9626e204,f03a1886,c27c37b5,85725465,72e5302c,d3f9ce54,1fb9a46c,16432548) +,S(c923c74d,1b114f,30d4b03c,92629bed,227fb8c6,8f1f39e7,8f121a44,694d4256,58edbe6b,dd5e1382,108d1e08,ef022788,c9f91803,d8ad4273,1f413440,5b5b3d29) +,S(92fa7906,b1f25c2d,3df104c5,196cf31f,93e5a8be,6cb91a57,c88c4ab7,cb92d46,a12162bd,79341fc1,e8f74db6,2bcd0d9c,ae99a75e,ce588240,79a61751,c887f307) +,S(37477df6,f51f78c2,a9c8e17e,ed30d5dc,976a9c91,4aea94c,691aa3c4,8639140,6a6a26ed,1955656c,64c6e15d,e50b0453,25c3da66,f5067730,5c2d5fc2,a8089872) +,S(b5b2ee59,1195f38d,f834e78c,abf00fb0,be9bc724,36c5f596,67ada098,dd0521bf,10f36f85,95233008,46dd276d,951abe90,cc8baeb0,fd8fe44,314706e2,15ddd5e4) +,S(b05d1b8,443f1bfe,36a415e9,d307ef2,56039335,76ecb630,94845b03,d2a137bb,99fece4b,ddc90b2c,3102a415,6f0d63f8,54098f48,3e1ef64,65f7f062,7d066cbc) +,S(e5d711bd,4778b3bd,cefd703a,e9525b5b,d69dcd86,6cd0b179,de76ae8a,5d918fd,8af014ae,5aa05b29,a0c88e21,8fef5690,9685d524,af389327,5421c35c,6db64248) +,S(7703cab8,377a482f,bff1c6fc,4d137998,1e217d11,c424beb9,f4f1f786,86fa4f30,3323edd1,3c80b8db,c7e247fd,5568c92c,8dd329ed,420aff0a,8e903571,e884e8b3) +,S(f834af29,c18bb488,366cf722,52a44357,2c87da2c,c14b3085,5405f626,154f3cc8,2e8a0ac0,ca5441a2,9e27dc09,4fd5bcc6,6bd8f7c4,717615c2,82001fed,bd5ab248) +,S(783b093d,13f33c60,1db8ee84,51d852ae,13bbcd7d,1d03a79,4c774336,4bbbaee0,3aa90b01,cfde6abf,fa0dbfb2,ec2cefb,6b5fb1c7,41701ab,66ec9b82,74ae5b4b) +,S(be3cc435,a7770b99,14a243b,48ef2c77,3ae42e82,1c18a266,6f92da59,e01c3391,f0d3bd36,9118c58,159fc64d,e61ebc58,a560f705,25dd5c51,e6aa9276,5ce4a701) +,S(3e980bd7,adac00ee,fe362454,5fee1ae1,97f89e06,84576a08,fc909285,783b606d,c64f0e41,204c946c,74473434,7e091147,67455e30,53fd488a,34d333fe,e9c5c228) +,S(a6b04140,aa621e6a,34959bf1,29790d72,91d7b154,5dd5e7c3,35bbcfb2,d582b442,9cb2c9e2,9cc05d97,5e61d151,542af6e7,a997f8d8,ee42d37f,8041c169,abcce830) +,S(7ea7a83f,c133cb8f,a109a6a1,b29b2c3a,29ba432d,222382e5,1f280e2a,47fa721b,cbe384e8,8a1f7731,831c5562,ad1430a6,6aabab75,e38571b4,5bb7dd8e,a699d7e8) +,S(8525e87e,f0fc9ebe,2f82b5fc,a14ba6d4,8189f9ee,146aa6c8,d842aca6,90fa042,dcf06a78,f311a3cf,182a393f,2a34a570,192873e4,7dfe22a6,86c70e75,6b32c86f) +,S(7555a77d,fa050d0c,9ed29c33,765fe967,16dafff3,6cd04fc0,952a7b41,bbd56dce,9854c0a7,bdc3dc1f,d8bd0a3c,d0af3111,18dc0392,830699cf,d0bd6f1f,17152177) +,S(9ed142a0,7a0adac1,14e6f026,133e00c4,972bb3bb,bee62f71,beee17d,9aac296b,c1eaea41,6c80e3b8,d24d4006,f699af50,9f4dca85,11c27f6a,39150a20,2b7a9d08) +,S(a3fd2cb3,784d8ccd,92aa67c,8118fd80,c9d761c4,2e0169d5,fb13b1a8,dfc56b79,75cd9b41,55db55f2,d50fcdd4,8c90d58a,b0d13df2,7a09df6d,659bfd5b,f87ea755) +,S(2ab4be05,217e7ee8,799ad598,b9c0e211,554338e2,8bb6d42f,c9952203,605ad251,2c2a1a58,da066d4a,7fc8c8eb,83e1e47b,b788afc8,3c8c5dc7,bd8f5e31,5476d853) +,S(4afc2888,af8c1aae,af6268af,566ecceb,8c95d09,d9f8f359,2cea567b,8648c383,b1e26b82,5e69e92e,98902579,7e99c7eb,cf3f284b,e1de0054,58b59336,a84f5eed) +,S(dd800faa,92319d2e,48038600,aac1c2b2,f63f5fc8,dafd988b,548021b5,2d8e3d4a,59fe8092,6e0468d7,60e522ac,91881bc6,8fdbc192,14fee60c,e8e1a977,1039ed7d) +,S(84aaf3d1,daa3a5f8,89b9bc88,6afb07f8,7bb5182,6df9d7e2,af5a74f3,c6378c91,f4164ab8,45eadd6f,a6331218,ecce096b,a04fd586,b744f0e8,11c2a48,3835afbb) +,S(b770f2c3,9e2e9db8,a92823a3,adffb690,d2ffc180,b88cefcc,8adad3a8,27c40b2b,f7c6e37,9894982,5d1b90a9,16ea564f,7e319c97,ca6cd22e,79f599e8,dc0d53e6) +,S(a60608a8,a0d7e556,70145c5f,bb107cc9,7cb1db87,2493f362,36a21e7e,babb2b29,3423527c,4e414548,96406f90,6d4a3819,a289c91f,b580ce19,6f25c57,7b54de5f) +,S(80f470f9,7b7f393a,5e6b4e5f,cc911a73,20f6b0f7,fcabf2d9,21eb649b,53414597,57d8f2f9,6e1bbe0c,1328faea,13c3f3b,770fa14e,4b5b7e4a,fa1ce9f1,2bd9adc3) +,S(4e111bf2,1f5248cc,3fff0096,c64a7b58,72e4a3db,1f0397fe,261cb33a,995abb6f,249cf172,102733bf,5fd829c1,d60bd930,c03af614,31faab0f,6d5acbb6,96eb2b9f) +,S(7d8c0cb5,47fa1d8c,10254660,a20e85ec,960cb70d,f38174f0,18416c68,c62844c9,2d79ba3c,17ec4d79,a157335b,f358cfd3,72b0f1ae,1f6bc743,40400571,5f35a271) +,S(bc0d4cbd,95896fa5,7f23d48f,a5a9f2f0,14b132b8,9b5953aa,f612aaf9,670a0034,f5d06670,7b316581,7a641091,55773bcb,83d7563f,28ea5412,480a0f48,2fa0639d) +,S(b154a2ae,ad08d115,95eddbe1,c9321e15,5cceb0a6,a7e646a4,2dfe70fa,b6d37a40,9abade21,674dd12b,d01e586f,695c896e,17120d8d,9e3c756,c8b5e53f,3216592a) +,S(ef603c34,a6ce06f2,7053bc31,841fe2e6,314be756,7e477325,5315ca58,5772e1e4,f9ebbe28,96f3b0b9,923a7e57,d819a231,15fced8f,3bd08f51,64aae597,c49ad65d) +,S(a601176c,2d901ebb,ad5a05d9,1adc0041,14f7bda,1ac496e2,c04e23fe,82aa9376,f781ddb7,ce0c3649,3772fb84,9e914377,d59abcf9,d3eade68,f8c8a303,1ae88ab8) +,S(abc41547,b6b3104e,fab968b9,bc9a9027,b1c7f0ef,3a9007eb,27331539,5c31e6a7,cd2858a2,28f21d6f,bd8a1821,dd78399b,594c5bd3,52628dce,879b8a37,d97e0ec9) +,S(92890105,c9c721,b2e4c430,26e413a,941d1da6,d31b48a9,2f2e3a17,d87f5a81,c1cad87b,1bdcc617,1e432e17,c13b47c4,15c22399,a7cbfe2b,b3097f28,da60a5da) +,S(e520dea6,9f4b35ca,46a46831,9947690c,500a7a80,6bd64228,ad144a7d,c37ca563,6c00d766,ac3f8fbe,90355dda,6ad4e2d9,e2330b0a,db673356,638b0d3c,8a2a82de) +,S(c0337a23,e2b3f1c1,a57d18a7,9d6ef25e,ac2e9315,18f0ffb3,7502d701,c57fadc4,fcea5873,be22df35,4729c3d5,b07a570d,7ac7e938,f6e061ec,cdd2146f,50808b65) +,S(276c62bb,6a8e2c07,6b5fb6a7,62d1d624,1b796a96,f53593c,fa51279b,2981ac04,5c53a65a,bb6b01d2,3f9284d7,d696236c,773c4578,88f692b,73e2ea17,6e1afc1a) +,S(604e1e87,e5051dc2,b837ccdd,43c8ede4,c4a2de6f,67a9ded4,fad1ddbe,8d663a5f,f70fe23c,e3511973,93d4d675,9444d862,ace4c473,99c34349,2d06b27,8b429bee) +,S(f2fc151f,470d9106,d58b05be,5e9039ba,4aba16ae,f7e4ceec,3b6e3887,5c41f6fa,f49bd2c7,f1aa5c63,d8e7f2d6,e0769060,d4188773,9c16b7b8,5d2a9216,e1e98de0) +,S(8e031346,e9f34ef,3b81d9cd,7e46eaf8,7ee0b294,d66b0315,eb0902e1,340ac560,ff00c8bd,a5e21e1e,5127441c,ee0504e,6b028c,ec0dca,450145f9,2c394296) +,S(a8680f1a,d75b7a8f,27a1cbe1,6b2954eb,d4e26eb3,a85d1a0a,96b9f40f,e5a9970b,60c6bf41,a55bdac6,397281f2,a3f52896,757401be,c42964c6,9501973b,e6070c01) +,S(4d68a1e7,f4d82ea1,e03407c0,5085c794,9ca8c00,d4dcb066,128e6c6f,504f4658,85c5de11,e5dd3691,2aa95d2d,2c36dd6d,26a9550a,3a672af4,d36265e7,a3d1ce76) +,S(3708f41c,2a6d8649,6983cdc1,bd02eb39,758c0bc1,ae78a483,5c6a20ae,e6c2a7a9,310b799e,79b7f5dd,5c9ae0f8,7aab193e,3c2b7145,c70af9e7,f4553faf,abec4152) +,S(8c883967,45028c5f,f1b96181,43f5b732,2d1a18cd,3abb1a92,f6ce3780,a115f059,24563ad4,e4ae484a,c344180,66dd87c,40128e42,5c8dce10,b008a7e7,620725d8) +,S(c445e76a,7b377ad3,bdd0fd1a,94a7263b,652e83c2,6342305d,a0e1ff4,d58f8fb0,4bf5a41a,dc8ddb61,3afbd3c1,3aae7dc6,f60ae2e7,23065b8c,c94cea61,cbacc89d) +,S(4ad9613a,c8a635fe,60d9f1d4,da4b9fd6,36949d5e,edaaee8d,eb2f65da,8e419f16,5a9b5b06,8f67a0fb,3ad31c83,ef1a81b9,38745877,b4b07316,42ab4951,68b0d7c4) +,S(beb3eae1,958bfe6c,9ab49d77,648aa662,2e397fbc,58e90b0c,20d1d29f,d760c943,d5a46be,f43a67ab,225dc6fb,5aa68daf,ec76f27b,6a822678,dbaeff88,382c9b8) +,S(aaa9aab0,bc0e21b3,be3f1dae,ad4a076b,4623fc14,3e4018ab,9df9a19f,d134f397,9c7d7fe,19642c65,a6c0347e,8fa2dad2,d3f094f8,bab6790e,d3c703ba,2742e40b) +,S(553c1e89,99d6f446,2fd7ae86,f1cf9d24,d4011661,9fd5d356,604d6a55,ad99dc52,26b40d3b,8410ac5a,6d2ba776,f7c5f0dd,3f6fe494,379344ed,6460bd6f,f550cebc) +,S(859885ea,36378fc4,398dae9c,4725d604,c3d56509,559ed28a,b47ebf82,5aa1abc8,fae5aef9,fc74b963,bb2fd930,5b2d1636,e6e84aa,3c40b066,9e531fcf,f00687f5) +,S(5fb0a118,679c5d48,554bf7c1,63b82345,89e51032,a70c654b,bb7bdee,f0368f93,e8d55f0,4a6816d3,bfb02111,eb95d868,5b9966ad,39d94c70,a4cf1826,6bc2a2d0) +,S(a424347,86f3e153,c9bd737c,1e70ddae,bbed445d,77ce4302,194be82f,94f91dfa,27d1cad6,abd9fda9,c1012f4d,f25b69fd,a54239a5,8ec12496,97116548,e7beed46) +,S(5d007508,63fc1f3,a0a8213c,c729310c,39465945,72b083ee,f571b921,a0c821e7,e538fbc4,5d055a07,b2cc2605,61238486,d99bfa81,6b0407f9,39f1d12b,feb2df3a) +,S(a3eb25b8,97b10286,934605a0,e4aab7f9,e80393aa,71cdea52,5f82f5e8,282e3db9,e2b354c2,1430c45e,4236baaf,128967c7,6beec58b,e6890c6f,303d83f,71e7f77d) +,S(73f63220,8a133202,96f3f51c,d10fc816,1e309e51,4ea35f0f,ff72e09c,e897981b,43412959,cc78f32e,d6df7ded,349a92e,3095257a,8a1b5dc4,15ed073,a420179) +,S(5f0825d1,c21bb5f3,8f0d9628,f6046648,7760512d,f1bb9bb4,ccfec4e7,48da41af,debac60e,1d95de12,84f1abd5,b6592824,5becd4b8,c2496323,b374239f,fe5c0cab) +,S(cc42a6f2,b4a8e9f2,fae3f624,cd12294e,efc26dff,c66a676d,a10259fe,f7d84294,91b26600,f92cbd05,f13f2adb,2b5fb17f,118a7ae1,6a011690,1bae0e14,3b230519) +,S(7d56e0e7,6eebe13f,a81aad7a,8efbcd1f,4de0c5d6,bd136261,8f0002ec,6f635a17,95462707,fe55e3ee,46dca813,eea5de7c,51122ec,55a91754,f7d13ac2,43fa1ad8) +,S(7972b61b,4fe85ec4,acb605b3,aadb56b6,fba8cafc,3c764dc6,add54c06,f7a5be61,ba186670,2642fa6e,a7cf5141,c46a8e92,4764c4ce,5d45b7dd,9f4926c9,32b8c7d8) +,S(edc8a440,347b1500,899f6360,9674f90f,4344c87f,361fae0b,bbe08235,d5025626,2f812740,9a14bf59,9bcc7cef,ad140b2e,7bf84122,9a51e486,4d01ecc4,1b2cd77b) +,S(bd9b65c9,7a8cf4d5,2f727b57,19f99986,d4ea1bbf,25560d18,d54877cd,3db16899,59cf7127,4e878e5c,bf0d9e02,dbe4f861,ee9c8e3f,5dfe99af,7db98e2b,c2fe432d) +,S(27635e38,1191e8cc,d3756571,44c5d8d8,72d91802,5950a106,f3be2acc,4cf35782,c359fe47,a019870d,7fa3ab,8f51bad4,eb5251f3,7e6b8ce9,db1992f7,cd1ab7d) +,S(4492dcc3,16c05300,a96abad1,47a00e98,359950f4,95dfb261,839ddf21,3b21d85c,edf1371,a4e81e42,dbfb8c6d,2229dc5a,fafed4bf,a58c2433,18934ed7,dc9ad35b) +,S(f8124c40,409e01e5,8de8a386,9bd88f8f,25887fc6,cee37c01,279aa606,edf9c67b,e0071d1,d31fee0a,8a26269c,3d7f3662,2b0f008c,61e749d3,65560c21,a26fa6bc) +,S(cc597b67,66eccdf,a2c0716a,dd5e51c2,ce3aed33,8f55f0b1,b5784bc3,9a05a2b5,12e031fc,394a43d9,d1e12ec4,28e8d5b,df52dae7,f3ef22da,74e3a418,74682865) +,S(142cb2c6,bc1283fb,d2164270,7d525dd3,d4a45f71,a63222ee,6fdd31e2,805aeda2,bde93d12,c72c422a,e4d5b718,bec6458,ed082bfb,7c686f2e,1815edc6,5ed66ec0) +,S(fbf4d602,dd765941,e696704a,1a8977a9,c3327375,e3f0d479,68fd9148,c01d2d3c,65b46df7,99e895cb,a6d4cae8,e68f6160,c7b96fb2,9af7d18d,8ef1396,c06afa8d) +,S(efdb5d57,bb5fe8cc,e3300ea5,ec14c50d,f09436db,cc58ebc7,c6d123e1,8dbfffb8,39083803,d9a90c62,6219ce93,167bd89d,d444e47e,ddd60deb,8137b8a4,203fe01) +,S(5bca4334,faa30557,b4b36c7,b6bf2d4e,921f59f1,eadebd74,97690742,2c3f35ad,3c97baf5,e2a663f7,22bf2fe1,cd646db5,79d27f2a,353fb45b,520d227b,c21206e3) +,S(9aa1dbbc,e90cf065,5ad8a0f0,54aa6641,ff921e97,1a73cd4c,49ff1f3f,51156632,cbf6e81d,8bf1e85d,b802f0f0,b9cc1125,6e0b337a,b90112dc,6513bf40,2b1a4200) +,S(2fc7fc55,86ed7676,4d5d4d23,ddec2827,5386e56f,eff09b86,abaa9562,73c2d408,5bff69e4,773c34ae,e477b0c3,e0310b5d,6019a558,5d4c7f3f,54f9c810,69d6285f) +,S(8e5fb941,c3ac6f2c,43195487,80df9116,6ef3b210,f2fff34,764cccbb,d34190b2,dbe2c1b1,5f6668e2,c63ae154,ce7b32fb,8d29b59e,dcf1ac4b,1df9baeb,fd10d2ce) +,S(7a5bbb59,4748d6dd,5d3389e,aa95b8da,dcfbaa07,26693690,4801bd61,b3d49c6,c2d28043,a42d33fe,8d8b755c,61235c68,ca13861c,effe3fa7,fd4edeac,634187c0) +,S(95beb8bd,f0d33531,ae73ee1b,1b631ce0,917c2fe2,22534745,f87faf21,bfb76753,c6cf8600,d9c55975,527e269f,b4a0e4cb,b9bd7783,7e230ada,a43c2f0b,c64f45b) +,S(f44ecb0c,6d896dc0,304fa480,90ab9793,576dbbd9,76b8fa32,540d223,e2968d25,545064f6,29644329,76a03c62,9ea46a09,e20e470f,5e76f810,6d19f353,c321086a) +,S(8dd32cd3,3dbd936e,6173ef50,1f7ae265,d56d68c2,77061e07,4fb49d26,538109de,6b110e5c,80daac20,5392bca8,a47d6d90,ad158c25,a10c0851,ae985f70,7c3f1e76) +,S(3d4afd30,b0f0f578,d4fbc77e,b71d044d,fea5e3f,891cda8c,77075dda,6237997b,2816e0e8,664df57e,c793d442,49c23ada,ae286ab,e748493e,d83b1efc,58bb9ce) +,S(a9b739fb,beaa3b22,b295ccac,86a07ba2,b8391381,2d2be020,a5ffd17,85d95ff1,a1d08230,21d6a6ae,f696d732,3c43fdec,d3c5d42b,8ed7ad40,1a55b2ae,bfb84f1b) +,S(e9009747,e51251eb,fc2cc754,c8b55966,a37e5d67,acf9b632,bb77f46b,9203715a,34258967,9ea8f997,71b476f2,5571a588,756f277a,17ce3907,d9cdab4f,cef9df72) +,S(7e348ced,55aad74c,c24d09b9,6b332084,2108fe41,3ac4c6c1,a8376439,f21a3f2e,39874f8e,3b722795,d8465706,e439e4f5,c884c22f,365920f9,1edcf83e,b4389e5f) +,S(a7dd6676,5ec2d701,56f2cdab,f0fcc0d3,8e340fb6,8a0d1220,aaaa74a6,fbb1f55a,b7091bf2,ab00a63d,292ded9b,b00bbe9,63710dad,445e8e73,760a50e7,2f41d447) +,S(b8579e9,a8cccbf6,dc033a48,16d8934c,51c0852a,4693fa96,a308d51e,3f57025,e696ecdf,4d79151b,2f164a3e,bc11bda,42c88833,6f694fec,a8bcdcc5,7158268b) +,S(7b29c45,9de0080c,bf8c8c72,e7b59a7f,184f1c1d,46787cda,bb42c2c2,bff57af8,40de8367,a6d8d13d,41901ca5,60376ede,817578b7,25f4e614,5dc46de9,5f801799) +,S(1ceffa6f,89b65be7,ac20e34e,f0b7e503,d1c4e9d,b31fe14e,179afdd,96f00f9f,6fdee8b1,f05930bd,ed98feb7,81790e10,8e293bf5,bcaa6da9,79a744b5,1a76f179) +,S(556e2d6d,11d301c5,6d5d01e9,a01e2ec6,80ba4efe,a004de47,ca2d97d9,15e58d74,9588349b,b633d7b6,b55ba7ee,feecbc99,3d66e6c7,2f4d8961,8a2c5d7,5249d711) +,S(b3506e88,73b93dc8,ed04518a,42b62ea2,b97f7bf4,e9ee66ba,6a7ab917,a1e51586,474f8100,1230fb7b,fe693eaa,7acba9fe,5917a39f,1f8fe3fd,5823ae4c,1b0b3b38) +,S(d186af3,89cb4908,db01a886,f90ee67c,1ba7ff3a,19994504,e9774b96,bd2628f3,3b39782b,c6567cdc,b4778c75,a862ef36,d01d746f,f411821d,5d08f7ee,f2a2db7d) +,S(f951d921,e1065ac2,3fa45900,62c639d,19e8c980,2a810d55,d6788572,ef987bb7,dcf7ddc1,87f8e975,27db239,7f553b5d,51abc66,bb76a070,55d098c7,f9d7d950) +,S(8dce8e16,7bac6fc6,1161b75e,8f340e0b,8bcbf874,fc82a42e,bb53e0fa,c4d915ec,11ce53a1,4a9eb9eb,9b4b410b,34d26ed7,9c0287f4,9032f674,e3212617,e0ae940c) +,S(ce2d3cdd,a0a7a43c,d7d2ed15,ec12a7aa,755dfc5a,ed5a85dc,4f439eea,99e26e2b,6a96aebb,e7ca2740,ea75c285,3c582207,6a8eed64,7e21809a,36b97c60,7a5a145) +,S(239466fc,dcc2d4c5,cef367b5,c8339248,f712c40a,558c80f0,5ea390a8,dcd92092,f2ce223c,9b49f08b,ca63ee8e,98e01736,65d176ab,3b7d718e,d0e855e1,27ac28cd) +,S(220ab764,341d3c08,d9c5bcd8,331e0973,4a2f3c64,4766395e,f6a5fee,3563e033,ec1e4460,d03013ef,467dc7a4,2b520c03,aa51a9a3,57817f4c,f9dcd837,56df5011) +,S(d5455dfe,16406a6c,70fffd81,f3c4d10e,845f0b12,64fa3db4,ee2ffe80,904b469f,a0f93b8d,257e1e62,265d99e4,9158497c,28a20af0,2af959b8,8810a10,60aaf9a) +,S(52367377,a1f6f05d,df054665,f1eec0d2,f5039cf9,cfc1d37e,1a9d89f2,88e60c72,78d89f55,430fc352,cd58d047,7e2497a0,d05e7016,d98f9ce6,a039fc5d,9ec7bb41) +,S(5b996113,3ecc9422,26a3dc88,67364125,a8e569f1,912e6c9f,4c1ddea5,5fa56395,bb9d7764,12076caf,5d8ac902,c5e2fd5f,f7a0bcaa,10898f19,10142af6,4e436d0a) +,S(f36cdb5c,bfbed1e6,58c7fa4a,5b0a6773,eecd1a43,db96cf0c,7c24f32,b84c13fb,cfc6d2f0,5ee9eda2,9156aee1,81b62659,993744e7,479379b9,3156c919,18c394c) +,S(3208c58e,25107af2,b38bf754,5531266f,842ce33,10ec7e44,595fb91,7079a6f9,831c6dcb,5346b6c9,605d9ab5,895ec2cb,653599a2,c88801c6,45a4758a,32c785d7) +,S(a6073a07,1f8510e2,aa021b80,b44d7356,47253583,6501a5a8,c5253918,8c9927a7,e93a9fc5,4c8a7612,16718baa,dcfc9bba,6fefa30d,85803246,2a9f191a,6364fec9) +,S(3350b462,f79eaf7f,260f2147,6aa7ffe8,f7ec1a7e,35624713,9e335758,b9f0d913,1f0c9db3,fce1222,fbd2341,ba8d2e93,20f33bc,482a4d4e,80571711,21152959) +,S(a54d5b17,bc82a74,9207c89b,5a1650cc,1773913e,66f6744c,11de24ce,3073caa,3c243b5f,5309dd11,83c7fe5d,49222c9e,fe62dc26,f92b73af,cdb7b7b1,32cd3ab8) +,S(6590a2bf,676a7a34,a1424f7b,1c7863e,8a7d346d,563905ca,e5b25729,4a04cf8,11cd5803,490419a,1382d972,eea2f734,4f8d0cec,42466f09,39650645,a3e781e7) +,S(b3c09c02,9fc7f48b,d2f461a2,a367011,8840393d,fb5b9592,89e96ec9,c7cba9a5,e7b5aa6c,bce54ad0,197bb1bd,ac030e2b,c6a3e6d6,af2db60a,b97cc92b,8f5cfa9) +,S(d7968ea8,44a137a,7db36143,98b29972,cdc693ef,8fdd4644,26a92939,18fa8bc0,82402589,2901434e,cbd5dd29,410ce2e5,56dd3174,d74da2e5,28326ec8,ad57a75c) +,S(8a57bc6c,2f98f9cc,d1eca172,b2501adb,3bf6edc8,4b50365c,6d959f00,838e8304,2ebf5462,a0f85985,438b5d67,cbfa68c1,bf643410,11a478b9,92cbfe0d,87e7d14e) +,S(51886841,684750a8,c3cb8d18,f8c863cd,1a555dd3,7f0efb4e,551d0d50,6073fd22,eb05f09b,9e983ad0,a6ce0f15,c2f5983c,6a28ce50,6c52f691,f30517da,36f3f192) +,S(fea8c35f,27e4794f,a9eab856,615d55d2,d3a02616,9b9eb7b0,ab7493e2,f67c85f3,c325de97,cf0a6e3a,98512337,8e2ba2e7,b24158f5,4aa97c88,9b54a502,8c148864) +,S(6612cccc,d7bc25e4,f8dab955,d5c1c9cd,d79d5f69,7ef4c510,77b5027e,d1f94b63,615512c1,7a378d0a,e7aabab5,253df9b,e9bd6a80,15c3b200,73d0499a,3457860b) +,S(c998b07a,499859db,4c9d698,33199956,f8a7ae67,9f6d3533,cbdbd7e4,a86f8746,d9e01371,919e775e,a259d81b,ea206e9,37d6b5e9,113838a6,6af11bf0,8dd17138) +,S(5c0e4669,c5cf965f,854fcd0d,23ddc908,c32e3915,460d44bb,520fb0c,3a4cc1e1,cfebbbaf,7e0f9a4d,d2f35ffa,cd0f7cb9,89f5eded,c8b3c554,64fb909c,675adea1) +,S(d0fdda48,30385167,f06f6433,c6a9d3fb,7ab3195b,64f9750b,cb2dbfb8,7158c0fd,4cde5577,6a34f61f,c82e1359,8618336b,f5c6e315,d10abc35,8f0020e3,ef1283db) +,S(d925570f,d78bf65a,5d48265,6222ce74,7cab153,19b7cfd3,7bc70185,fa4a3e81,3c399a,c448ba90,1a21a5c7,b9c6575c,ff52bee0,cdd00ed1,673d8370,87c1924c) +,S(45d2b56d,81f84bac,2077d607,484b0802,a023cc4f,d7818f9a,1d0c2187,98374c8,14ca18d1,92a9cb37,ad50506e,a25663cc,9829411f,848bbf05,3064041,9c19d7f4) +,S(6ad3ac11,8588c5bb,f793404d,df9a10f8,ea8c1978,65a93fba,5b7170b7,9e157400,fa25741f,1e242c3f,edf20e80,fd76292e,382eb5ad,1731ec97,a8762fe9,811686d7) +,S(5da24445,b6dc960b,793ea9e3,912b21d8,26d54028,2ddcbf5,28e1ebf,4a595f52,bc18ff8c,ad1dca69,8995063b,ff8a2fd2,fabfa0d9,8c8885fd,1b401f3,65f16026) +,S(ddff6468,11ce86d2,93b9b89f,865d7133,d7b5f189,d527cf44,5ed15efc,ad32b346,7260e994,cb22016b,e121ae08,12b01c3,4d236b67,13ea510d,b1aeda36,567f5737) +,S(a8b9ff3b,9120fa93,d0f2f50b,c8509846,c1030d98,dc9d5243,6ad9e69b,f897f029,5cbfa29a,4e516872,ea9a4c2c,a3b07efc,c866aaf6,a2b1d7b2,3597e332,8466c591) +,S(943077fb,177b9d6a,723c18ed,ac8deeb2,62875264,868eceb7,a2fc1a01,51dbcafd,219a9fc,41ad01c9,d3f8248d,ac7df93f,ccb6e312,fa5fd442,e48f4a95,18e7eb4e) +,S(75cb61ac,9c9817a,fdf60f52,4245ebbf,82b33f9f,a564d74e,9e810f36,6458b8e3,aa8135bd,f66f0843,460986f5,f9df6b9e,66441477,cd58cfb8,5b3adfde,ec03c367) +,S(1bb7e177,27cb8e85,4bc922b2,28e7f0ae,c34fdcf3,b9bad0c5,750e7c8,e31fccc8,bbf72886,1e855e70,bd9e322c,2425cdea,855ea00c,3e6263d5,2380da38,c0221ca3) +,S(9443384b,39e9dbf3,45b4b41c,f05d0f30,87f02471,c98e2a2e,afda94da,8bee8dbb,e3661173,ccb211f6,38cac6e2,27e3939f,e7b5da57,f6f7a504,abae01c8,fa4544ee) +,S(49bd15d5,a68caab2,8d51638a,ec1a9668,b4c27d54,d6691839,61ccea76,ef740d25,648fc868,8760e47d,fbfb9f0b,d995cc0f,77563b60,eacf3e57,9db7439f,3f18c6e4) +,S(d0c7b78e,92809e85,84d3684f,d078907e,c151aa78,a5832f90,73f945fd,7acfed85,a80d95ab,be494a40,b5529046,bc305203,be91e475,22ad9d57,7ab95b3,8e970c89) +,S(debddd46,3ab22232,5e98f9c7,5cdc875a,7c4c28d8,79748bf0,cd96bd7d,92eb9275,d103c8d,c3fffcb0,5ffb3dd7,a73af259,50d02064,b12bc754,ab594c71,ab9799c) +,S(1d79b17c,192a6a15,8ea2d6bf,9da07312,9f9ebcc8,54b02dc3,3f64012f,1bf33998,6ec818b3,dbc1c8a8,50d986f,bcf64702,c787682,bc408a12,b78e6bbd,4cf60a5e) +,S(2feb76eb,ff5d47e9,7289c38d,7d1535ff,74bd3b57,264c5844,9edfd36e,6e81ca1b,45bd4e4a,7ba3a823,dfae18cd,1f9cabc7,bb462e74,7899c899,378c33bb,89f93b74) +,S(14d0d90,faef5a77,f5372ab6,2e4f5efd,3eef1b39,498653c0,6372fe0b,b0682573,517f169a,80c2b930,4f530f51,d7196831,601a4f97,72ba1312,36ba92f6,36081453) +,S(7306a7a5,728f91c3,384bd9ad,b10b39b2,ad094137,46d2e476,fd522abf,ff313321,215e22ab,a5b9e87b,35bbd4e4,f492f1b1,574c85ed,25b86a85,a8e17b81,b7a915a2) +,S(85d8454f,870cdb8c,b32873a0,698fad20,fd24067a,737e9719,76d4d362,6a55aaba,36d63c0a,36eb9e8e,522a0715,cb9c833d,539fe7ee,111af3bb,951434b1,3117e4a2) +,S(c68f6782,993067aa,259b21cb,9e19122a,2f7da28,96d8cdff,c1f0a0e4,b34384c3,74e6e96a,331c3387,7ea484fb,995d6a3,8dcd493,6b2994ff,b7dc3681,3079e94a) +,S(81448111,5dbe5550,846d5c9c,3351c89c,e29cd850,6870a17f,e18e3184,4214dd3,75dd78b3,d4cdc29c,697740e9,2478689d,540ea33e,5edd6785,210abcb1,670d19a8) +,S(310b5b19,de24d478,f5f25993,a706f21f,24214e1b,cf614ebe,3e204815,60c945f5,8b42c6ca,f01d205,e09d017e,2e840d69,bf04cc53,f02a21a1,47e33327,104318c3) +,S(cf8a47c7,4bafe2b9,dfde4bca,b2e6d451,b0a90f11,c684f420,a025974c,bc4bc3e,f0b7b264,a9a78699,786331e6,2c8762be,614d8a69,c0a65c3d,1cc201bb,e34c97d1) +,S(a0fc6226,7352a904,e70100ec,63d3b60b,ab553388,69b982d3,3d747af9,8b8650fc,ba3ae54c,16b24eb4,64b88c39,521c399f,cd162eb3,f9966497,e2b96f2b,3b85865f) +,S(aae5dbe2,535edd47,584d0339,10045333,2e1eaf70,a4e1bfb0,7dce3c23,6cff8bdb,7cfaa5f6,e55806b7,bb278439,2473732e,a51d85c5,a3558321,91195533,b7a7449b) +,S(8a4e9311,5b897550,cbc0792f,b2705a18,5c317226,86da5bd5,b0a17bb,503ae39,1623adc8,d85f08c7,1751b976,daa17572,2442aed8,a9dc1692,2dde923f,d17cef2c) +,S(cbcef535,eca90b09,5295cd61,29010259,8627e1a0,ccbaff26,a51cdac6,87066463,651c2ffa,c2a2c99c,3fcafb9d,8c50e156,498fee17,3462fc25,9d87fb8d,6b212653) +,S(25971559,4d6a2bd0,baa90e33,62b9c841,bf12c4d,2ead6609,9902eac1,ed0f8c99,49e01b6c,c97404cb,8144002b,c33e8bb1,d974dd22,d0a26a82,94bad2bf,2875245e) +,S(b754d68b,2b049f6b,ac389044,c80f0364,a707da5e,3e9b2a89,1672cd29,b6f1445f,1b29b7c1,625e23d1,67092e3e,ddfc2f4e,bea55542,5f4ddda1,af2aec5e,4de37740) +,S(20aea5a8,50e68f39,cc7ca2fe,2f38b5a2,ab0bde8b,d294c40a,afa898ff,4f084037,6ed576b3,f17666ec,6aafd6a5,6fe7e1b2,ab1e883c,31230fc2,b4e1df0,3f59444) +,S(26844e02,919de923,3288cba9,a97eb85a,c6939fd0,7cd01e7b,f0d5e1db,e31979a6,3df9a8e,6a5fad1,266f11e,518fb60c,cc08a6c2,832c45a1,6c7c5520,5c9ebfb7) +,S(11afca61,33a69aaf,27cfd413,becdf9b4,efbe0a6b,1a38b3fd,485dca95,dc28414c,8d4b8790,c0677fe6,22847bbf,8e47b400,9e4678fb,b9c9377b,2121f5ac,db737b1c) +,S(c46e14d5,2fe25d65,37bbe09f,ce7e95e0,4986337b,23e7160d,f3d78dee,e8d2a63d,a200fdab,4211e9ff,2d008dd7,7ddf67a5,1f04b9ef,43fa1758,9b175d58,f5d2b723) +,S(570aa12,578afe09,245f598a,210a7605,2412283c,8f58e142,d31d9cd8,d455e4d7,c28fdb61,f8e90de1,d43439e0,8512a071,9a2beda9,5d0a5601,b932c0f1,2cc50ac8) +,S(d312db5e,88a1cea0,28570b84,e3854e16,224236ac,cfb14d1f,3a33108d,fbc3fa64,ca5e5089,1843383c,845fa0aa,e031c930,64b8aa4a,ea72e6cf,36b617f6,cf97e1de) +,S(1ee22876,9981670e,14da9ad9,9279f001,c9be5eb8,76224a6d,1fe4ec08,aa398087,62101114,e303e37a,dfe42c65,54460d4,b68603a2,580c7452,6ff31c9f,2176dcc) +,S(1fb9cacd,e2b84ff4,ae85511d,1c964c01,1700b9d7,2d4c04a9,4afa9aa5,57bb81a0,430b73c1,295c5f2a,d6d9f59f,74201435,15b1306b,2cfa038e,e0456752,5f737fcb) +,S(d04cc82d,d3cf0b47,69f2934a,9807e743,4a998bb9,fa44d145,f191a176,611c085b,7a4a19af,b551d151,c42cf1ca,ce123dd5,8f4c13ac,c865b92d,15520169,1be5fa9) +,S(1e4cb208,8bd4d17e,ba8b97f1,f27df5df,8a544f8a,548dde15,712e8704,cfe7e9aa,d805c61e,b72933ec,e799930a,53fda3f3,db066396,5c71be51,5e8466cd,a59b828d) +,S(520aa398,707a85a0,d672bbad,cbcfdab8,8f769f69,df3de8c7,17d6dc48,de51590d,98d344e4,a9047a22,c09095e2,f1176aad,3b54724d,998e052a,39a52554,4ee9ada8) +,S(3a9fe3de,165bef7c,2e0d45a0,60693fc8,e7080ac9,783245d7,a79cac6e,7b614ef2,5189446,fd3fdeef,c7a895f5,2934c888,7607ff49,aa6d798e,151061ef,73038d4a) +,S(9c929dcc,c26c0805,e4289a3a,2b6d68c9,8e3c6806,43730056,65fd8e73,da149938,6dfbf940,b4c29209,3f39f6ba,b102762a,c81edf2d,aabe6dd9,56aa140d,396ba2fa) +,S(355b60ce,f4e00651,8baf1e42,e5e7a08b,ee22abab,c69aca66,d117748,89be419e,7f478a3b,b277fb10,5fe0eaaa,cb53fb73,4fc01dae,bb44f1b1,ed146f43,fc2604e2) +,S(76bff14f,21ad4442,e1389bb1,c11e1019,ea966091,97439705,dfce7bf3,d7f7f37f,3855a291,376aab12,b5f4da79,bc22e02e,a29a34f8,9223f07b,93f6a549,8289d763) +,S(91bb9cdf,10577a3b,7e23aadd,35883396,becbb4bf,fa22e1db,fa08f8b6,6156b454,ec6cbb9e,4f149b02,edc53e93,d1611b5c,a3edea42,c2ca9a1e,f2cccf25,94edbb91) +,S(9e56b10f,1ba86c61,36481204,f0c45b09,a7dde7d,4eb32537,f8c310a5,a8865562,cdf3453d,8552c16c,48bca1a3,79ee8c6a,8b523eaf,d1862d5,16f4361d,5a8aa67c) +,S(4e73594d,af286bde,4e6e28a4,23930571,a11dcb75,4e9a4af5,f4972d,988e09f9,a59f23d0,70c042ce,e03d812c,ea274035,af0d8e53,828a418,cd1b51f1,458a36e7) +,S(156fdff7,e92d89fa,691d3c55,7cb2c614,393d5973,4b11bb1,d9fac953,3923d860,4e929637,c448760c,ef6d68f6,4665023c,bff653cd,23132ee,620eb013,a13b360b) +,S(f2c8b650,eb372336,5d57a905,23d34db9,70d23d52,1f893569,98b0a7e7,ae8ea03b,bd9ac314,84a99bf6,973422a5,60bde9ec,204488c7,6739583d,72f42a87,181a7881) +,S(27dd3657,a4a37430,5f5bb92b,a7b816ba,88d526a2,1ae316c,d4a4e67a,c751e3e3,880cfdd3,c0faa401,6afaf3d5,1fe975e4,8a756b01,f7d84e8c,226424b,83be3304) +,S(f6c25e0c,19f7357c,3cc5d98,1cc4b7f3,7a390182,c2673708,1c64f163,ebb3d1bc,8c80b3ea,7c05a0fa,39944d66,643b3589,29534152,adf37c2f,183e7c22,8e89e43d) +,S(c678800c,71305ea1,ea2847d3,d9d37612,ae280305,716fdf45,87ac7f4,a7fad4f2,be5ffbf4,d2fb2b8c,ddb49a42,ebeaf5d8,55d41d39,f106e2d9,2d549e88,6c0b63c6) +,S(f35db221,e66b7786,fc9e2d3a,68f0d1ee,f98177df,a05bfd30,931912e8,13f6d560,4899a808,e6b2040,89974ca5,afe5b1ee,9eccb15,36a7c7c7,bb67cc00,e43f29fa) +,S(2b93e37d,a915633e,db9843d6,c33888c3,5d944f04,c4074deb,d021c639,93e69de9,eb3d1095,c6ffa1cc,93f72a58,f1320efc,366a4a5f,c7250167,6f2d3c88,4b0522f0) +,S(818023b3,90454716,f51913ab,fdb406f,e4875b94,8b14a331,60901d1,66091b69,b3f5718a,6224e447,c5af3e1,f38e4f2e,6fe57389,fa7d8990,f98e44c2,a227e7b1) +,S(1676e6a,244ca69d,b2ae565b,65b14184,6645ce7b,213dc1fb,db33f060,3c662bb6,88e1cba5,deef5dc1,26b20830,d2c7c0d,aeb9689b,16ecc1fd,cf4a31fb,822e0298) +,S(2f931a1,a92537de,38629d73,323e2f21,d9657454,30e32e4c,3912cb21,dc298d54,93292d08,6fbc0fae,eef6fe43,f5626711,95a5b2d1,bdbbccc,52e1dfae,a30ef904) +,S(7ba4d612,f0dd8c91,8bff20d9,b4f45486,be8a32c1,122601af,2d1730c8,a1fd0279,8aad7aa1,f5b06431,b2e20af1,4cd049a9,3018e3c5,bc4c4310,d0234e78,d2401179) +,S(e8dfab0,85fe7a91,6a79b2be,723799eb,d6974d08,ccc8e3d8,5286aa61,c81d5e78,2121686e,519db556,e6595d47,a5487bb8,fbaec53b,b18dd81c,37dbab40,6e3f926c) +,S(7d5623bc,b1597ef4,6f907106,17eb2e6a,ea751da1,5535a64c,94c90c9a,d84ab5e,dc639f31,8004c4de,31514b70,ebe2e8b8,701b3cd4,5d66b7e4,204dcbc2,a0ce7575) +,S(8e81e2d,8074bec7,48986194,b3b82200,1e4ac916,81de2ad5,7b9c84fb,88a7ffa3,4085ec1d,f4a34480,ca56f6cf,762d03f7,fa94e99a,8df93e6c,dc781499,59fa890) +,S(a9d5a3e7,8290ee62,5e18affd,169c6829,73e68ac9,2b5cc52b,53ed3a85,a68da71e,1cdaad6b,f9eb5889,5189ed29,8793388a,8d6e8b20,ce47a536,ee89be4a,b4805fd6) +,S(4f7c17ca,bcda7c0e,3b7b313,4312f848,984985f0,e46ac497,d64b123c,57dba2cd,860bedd9,5f470c3b,f3cbe7c1,d5070cd0,c877010a,9baa8f5e,888b5ca8,a34a25d7) +,S(478f3d7a,9234a7b9,a91bd016,f55734e9,34b8c3c,535725b5,b4fbb0ab,9fa64921,db97a394,f0253f18,ebabca05,c21e9a7c,3f253054,d83f2101,8ffb4d93,b8051a1f) +,S(ace7e57b,73d96e7d,69f7cc01,b1da179f,3ea09aab,61fba329,f2552eb1,fe7963d5,fa0251f2,2b8dbd04,ec90f824,be025965,7e213e4c,1030611b,796efb89,26908918) +,S(cd56e867,f5170771,8253757c,dcdf69ef,4401f2f8,a1d09f24,374040e7,a908d1fd,878f7216,52cf0ba4,8a2b29a2,2f620c7d,83e4bd84,277b7b90,a454bba2,7f338fe1) +,S(3042ea5c,d9d2f89a,64b1dd24,97b25da5,67a2c672,ba067e33,e923e513,ee4d5329,b84c144,d5516a14,a0a8568c,d6d227a2,d3fa1d86,8e05e612,81ce41b3,5a68b1fb) +,S(55e088d,a094ed26,82b042,bafa0345,30a2e291,57af3f1b,ce351ec9,9e712ec0,c6f8297f,64398324,96091933,514c5449,cacadf,82d51db2,82c9d2e,c66b33e9) +,S(bd2db13a,69dd93bc,a37f9181,7a57a0e9,e0e0da83,eed71875,e63b4691,3b408966,46e12660,f9489b2f,123c25d5,f65b3f8,187ee6e4,405b8cf8,78a742a,9b0da2d) +,S(7d7a5110,cdbb8455,5fe678e6,24ed1a14,ef7c5219,986a7ecb,6095624e,7fd3d210,c9578dc3,c0a54524,f819d640,abaa4a04,626a46da,15c0867,72774a59,6ac6c37c) +,S(1ef12317,513b1354,2a966981,34edabc6,fd4e6d29,1bd7782,5bdb30f4,937a3fa7,e0e4b688,a391bcef,3451cee3,36a8c9f9,12319899,4684c039,909489db,590e1ade) +,S(effa0403,766fb976,dbec6b2e,332d2f12,9f463b86,8b9a1d19,49d30cea,1606baaf,8c5b1c83,bf3efa64,f38de1b7,da03de17,b0cbfdc4,5b4a03c2,38221def,bc1cb082) +,S(dc9271e9,76a9a042,5565f022,273af5bf,20bf780d,9d0ea069,df5da661,a087d65c,dc8679e7,b27bd30c,986f11bb,1c73b76c,55ce7c7c,621490c1,944cd8a6,b63d6063) +,S(ae1ddc2,1e1ca02c,218f6946,275501d6,a1336b93,ddb1b2,384ab414,b8264619,21c6b39d,300b6125,ec8e5c8e,19aa76d7,32466bc9,a887c76a,1ff4220,7db26b48) +,S(aea2c00f,fe5835c9,2b892480,83164635,33dd989,bf2bca12,85cce3ab,4e82cf5b,615598cf,935a6112,42a20e84,e670b193,9aad65d4,53ba967,3e8193b2,93dfa97f) +,S(913d0e16,34b43a86,f55b30b6,5914767d,b45e723e,636c866b,6348c8be,8aebf696,e14c6607,51affda4,d02574af,43172024,39c0c10e,148d4305,1487a5c4,39971a9f) +,S(4f0b3354,775cac80,5e0d6191,6bb0f9c8,40fc163d,8878c05a,301252d2,3bc26fc0,b0b75486,3aedfdf8,3a6eb2eb,5f3e25f1,6c0e1077,6e855ac3,fa8fc3f3,bd8da1e3) +,S(5da21940,73cc978f,7673b2f7,5c65ead2,f469df96,f80883b,181a3da4,f316129d,8516d080,743d2670,570d5e63,e19eb543,237b1db,6285b1ea,f3bc1459,8ef311d1) +,S(76e1b330,ca7af91a,ccb92fb4,63404d36,a8fbc132,269d163d,d4beeed1,6be74a23,10b39253,c5908ef3,ec96f2e5,2ffa0dec,2ce2800,31a791,bcaae0de,1e7f5326) +,S(c4be488b,2f210ee1,82f91263,78b23359,8fe8ef57,671ddbe1,d76975d0,ee393e64,bec1392f,a1a09a54,480beadc,b98ca024,b910cd70,f807eaee,10d4e270,bb79f449) +,S(546918d,a141fd77,b1f13848,d3d608c0,25f5be00,4d36a542,56d0ca5c,9333ff37,3d1d4c7,9684be1a,5cf00d71,6cf9a1bf,b0b82ba4,833704dc,c2d23e8f,39914ac7) +,S(cdfc6fc4,2c51ebd1,2df368b0,98ff0f40,2e6df8b1,9c67e10a,320c1960,266078de,5985e930,23e5264,547bef45,6b3774f3,c2689411,b6f7463c,febe068,fd89cb0d) +,S(7730fccc,593b14a0,6f21eec6,2408e146,36f0e4b,4718ce99,c99bbcd4,7cf03034,f17d0fe2,736e412,9c30151b,492aa7dd,52beacb7,6f97001c,cc28f991,3e016b72) +,S(8aa4c3de,474308f4,674c7b55,9f895bc5,d855a7a9,5fadf090,5726b354,7941b3ea,f275c44a,eac2623,1bf4ae9a,df403ed2,78d9da42,150c98be,7dbd5f71,5cb8594d) +,S(15926da4,97a4e925,8976f87f,f8940491,f32d33dd,7855b13c,5cb54d10,d325bb79,15ac60b6,5b1ebfa8,e871bf67,ec9f71b8,1aa03c78,82880d40,d35f16d8,67ce8e51) +,S(55f4f4fe,aa741574,79462b48,f001688e,fc99f545,d4566dbb,35faeebd,f5b1710d,80ecea05,63f24c84,e767b894,57dfec3f,d015a4ad,b6e3fe0f,662521b4,bb02d15f) +,S(95a56acf,402f7f33,fa357c4a,e4db337e,f04a60d7,4cd73e0d,b137f68,e0e93cee,e72405bf,b7c9ba84,16f4e72c,a30c9ae5,d21c89e3,ce5b61a4,bd521b4e,ef6501fd) +,S(28a9fd90,b50d7bb5,13034b7b,c36a9783,c2a697ff,499bcd6,4b0881ab,8e7a2aac,76b151b0,5c7e7ea4,9a263596,81508781,a37cfaf5,14fa1720,b583faa3,9794a788) +,S(6406dd13,6d6462c4,a4116b93,eac38eb0,b571e2d3,99cdb93c,b36fa5ef,e734b672,3974c77b,92b8e614,52d9c9d0,62a911f9,b4c5eb1a,977da74f,defea358,5dd7fd1e) +,S(8fd8f23f,cb62e1c0,94fef903,9933747e,9d40c37e,376703c2,e3c8b666,f1066529,8b0b2f9b,de10175b,24a9099d,75926296,5ba19013,20912baf,3100e057,d4ab5c8) +,S(51780a2b,d4457368,9c0679bd,c8c94e43,cc525bab,2d2723cc,3e0eec15,63a1a24b,5026cd9b,e178d1e,c746e5db,29391c4d,4b6b08a3,3530fdfc,64603fa2,f0e01109) +,S(aa01493a,e7c7f9bf,3d2fe0e5,cd939dca,5b8c8534,6848d065,beeb42a9,8c283561,a08f0b45,4a42b5e3,6463af14,5199e3d2,1783e908,b3e130f0,e9e88110,2cda82d9) +,S(cd8ab749,d4bbe6d4,ac81c4fa,d6a27e81,e4456d4,196cdafb,97fa6053,18ceab70,fc6c7739,bd68a20d,e01c9249,3cd7ad3d,ca862183,b0529231,da32f1b8,5df59beb) +,S(e69cdef2,e824501e,7a17bc54,e0bb4886,379f56e1,c59a27ea,e00bec5c,55fe3e32,e80ed10,40375398,10125338,f6291791,3fe735e6,6c4bbc80,f41d858d,8ac41cd4) +,S(5a4e72d9,182b1f7e,efb08af1,9e3181cc,f6b6ec69,790184a2,f30188e0,dbff8a8d,2d1cf7f2,d5a857d8,3b31c588,5ac33a5d,7b62ea62,7b5b0bee,2d912502,2df9da19) +,S(9e000859,48bd6211,410416b0,3920a79e,d78f154,5dd0330a,8f23d1b5,f8984a2b,36ae0492,412fd3c,c230680c,edb0dfc8,151ab85a,d8d3338,db611674,c88e3f62) +,S(7e0b97ae,b12f8734,ecad35d4,aea425c7,99f88485,f0bc8d18,ac82f213,258bc6ff,e76f4e24,a4be1b6a,3fc3b0b8,ab0b6e5c,ab95fb40,4692f7bc,cc7640b5,69f3946e) +,S(62285cfb,1bdfc495,dca81ff2,867878fa,b3064be5,81be0c86,b9336c6,61038ee2,f2c91be4,5f60e9f3,40e85ea0,8f159dd4,a65ca8d8,21a6e4f7,71f4dc17,849b5161) +,S(70234e81,2de1b5cd,699870ef,36d5c19c,cd3765ba,eef3cac8,6f126a,a6c82623,e2dbf98a,f92a777,263f3c92,4738ba,3140f769,fd5b6ec,7139bb8,41330736) +,S(ae770461,8f31d5cd,ede40ef5,7434b0a7,7dc1b4e6,7f4be5e6,136978a7,cd5db07d,a4e25164,65584487,3f520e42,74037c,5cc43e12,95167b01,d46d3e93,d93d16e6) +,S(cec7ac8f,e4db698b,48ab78fb,768e6094,5b7f4ce7,d643e604,9e349b6f,246f2b53,491bb545,99330685,433bfd2a,7a4fc831,7f5d3cf4,80d6bc32,5ca6d001,b65fadfb) +,S(80276e96,b051e49f,276f62e8,35622979,852e4cf,c2ff8665,8db4d5c7,7c5eee36,f510d696,882589f0,870d526e,5f7513a4,2c4d4ce5,3733f30c,f06d7dc4,f42f6d9d) +,S(b19027d4,9d85faae,e6163934,ef8f8508,e9e351c9,82bda741,b8944317,da85b27d,c12461cb,dec0e69c,b378443a,f2eb042e,8439f812,205742d6,dbabb372,ea47a824) +,S(57599d4a,cf07c001,d3d3fc78,aae147f1,989c656f,fbc43081,29e05b2e,570c792c,5cf8ea0f,d215ba16,e18e181b,1b4b4f02,38b57af3,9010ba23,f13bbdc4,18514b0) +,S(5ab76283,fa110b82,c53cda2b,653e763c,306e6f8c,2b07d490,bad6e418,eae6e4b7,ff365643,cc2a78e3,17a7de95,b37b3f83,aebe8272,4162a884,f7437aba,b55e8ea0) +,S(7b93d9e4,8602d7b7,ea52dd45,fa0031de,66ea88e4,4250c898,64903e7f,959d4a85,99ccb201,5ab91fe9,a0f50a0,fefad6c3,f6dd060,1f2ad099,a4851d33,162b52f0) +,S(2d5878b6,af642776,41101be7,2b37b4b9,1de26a21,b9610a93,7ee2ce2,fb96ebb6,138ee05d,df4b004e,820815d9,46716f2c,a887066b,b7d218f5,47d4bd7c,2cfc585a) +,S(1d637068,eebc32da,24a0fce,2e41cb57,cf1ccff5,38cfbee7,ac13269c,e560af3b,6a932df1,a2896445,6685ce54,2ddca0ae,d589a494,b7ee89ed,1b4ccfd2,c276eadb) +,S(82babb6b,460e1235,f3187a68,912b057,26a478ef,fe929a3,9479cf04,467de64c,3a9f4e33,603d0396,1f3c11c,94d58369,5de43a1a,327d0faf,f51089e1,1345647f) +,S(ae86e71d,4e715bfd,b63d899a,9daae610,a01c5134,c1b9262,c276dcaa,b48090a,3564b48b,fcae8f7b,feac4df9,3b458678,6f2f9e83,9c9c6126,a301de29,4cfd7b5e) +,S(35a5c2fb,fc661cc3,f4ad6ad7,f1eb32b6,664c50bc,91f4000e,f5774364,2aa413e8,4a5029a2,887f6648,3e072782,68a81c85,b901d692,4ccae752,7111bcce,cad6cde5) +,S(386bf07f,4dd508a7,61e7c29a,dd251d9a,76324496,6c6d760e,cbc6b069,5858e2dc,d4f14804,9c1fa038,1d903e19,68fb14b2,f07c621,15a81f41,e811ad87,de407696) +,S(dfec381c,9bd6f4cc,50ac445e,c9104d87,f9c46c7c,cbd70909,fabde6aa,12346f96,5e7344f8,25b6649b,df97ef3c,ad96945b,d1ce0f76,a48b7f2e,56ccff02,797553f1) +,S(3606dcc6,4db04cc,5493e0b7,ea0bfc2,f8a24302,d2358aaa,7c1ea8,842abbb2,a5c8743b,bc4d9b74,b8b569a1,feca3667,87eea8b1,be2025ed,bb547e78,5687301d) +,S(3441e737,e19096e2,9a3025a4,71d192a0,db086038,8e76d2b6,66052825,e52b0016,6d10f7e,d5cac98e,73c3ad47,bb233a39,5eb9bd4a,37861b9e,7dbb60f7,81eef0da) +,S(b2c97c2e,460d8c34,b5ea7a5c,456a9cf5,b1d902bf,5cdff030,25410a,26636e99,67133081,a8c8ef30,753417b3,cf6973e2,1f151e1f,27216bfa,23289ea3,e2057b7c) +,S(2740bd8b,59a43ddc,f8ffdabe,d59027b5,9b7932b7,3db45a97,3b6c1501,57e045fd,8106f2b1,f69f1ad4,2c0787a6,3c137753,987aabe4,b0ebd82e,1ea7807e,93b02a85) +,S(a1acffd9,bdbd94c0,cd8b4f40,3f9400c,aaa8e269,d8cc49a6,9ee565e1,89b6c21b,62ec7d7e,733f518,974acfbd,4f4e4f44,bcc4fdc0,cc194a66,df7c16bf,ef0235b) +,S(50bb2ad6,8d524acc,3278c0f1,538d3aad,9a5357bd,332d8cff,6301f417,57349847,d8fc33d5,d03526bd,b97d4c6e,1ef018ba,ba4b33e5,9677f139,b8535287,fbacfb32) +,S(ebdfb262,6031b4fa,d675e860,12288101,948e2ca0,8fd0d32e,c9fd0838,5f4fdbd9,b078066c,c470113d,db3964e4,466e319b,4f853a42,8951aa0a,9c4629a7,a40dbf2e) +,S(5daf4c23,65482a2f,bdef73e8,208fd5ad,d57b35f8,171541f6,3a48b742,e98bd48f,9015bfcb,5a248607,f5ffc83c,4fa3dfec,9cbd11f2,c230327d,b2cc75ca,2e87f967) +,S(22db9c20,5d840814,67a19517,f353f825,238c905f,2b12a77d,8551cc9,ee8533c7,680a1bc8,23432a28,a3219264,2b9acf0e,7ad19e29,b604631c,85f7038b,386dcdf8) +,S(404435d1,2e8be51,92625213,f86e6e55,9fb44658,44694d4f,4db72861,d4c100ae,9ebce682,b321eefa,e8e04776,8f82491a,dd734e5a,941e0f4c,b6284f78,6d1586d1) +,S(dcc36eff,6831a6de,f8600d1a,3d52da1c,fe59df9c,cc69c9f2,60c26532,e837530f,8609b5e6,7360b7e8,5ea98c13,578566cb,b6b385ff,6990d4d6,5b795acc,1f77a893) +,S(ef0dfb94,1a1c383e,4a44cd04,c633cb48,e991d140,45e2d9a8,b4353e79,9c1a1514,2685d60,f2a75f9a,b733afab,f693ed05,9c3599bc,3e3346d4,61e5c86a,f76f6f42) +,S(24884cfd,c6c3efd6,b4d2e18f,2ca66b06,410b0fba,d9d61b30,86abc537,1d766b8a,7c1cdc85,66f3daa7,d395c6bf,8a23c130,86a78619,aa68519e,4657b17d,ace2267d) +,S(541b6691,c7004a81,2c607756,f81b6f05,485b0708,678d9a45,de74632,4acd8b20,ddccf301,8a3c429a,c749f0d5,2383784,cefff3df,ae98517f,c7f5e764,c5c609d7) +,S(5462969,67262e3f,a905eea4,ff1f8296,f792cfc8,bb9dbb9a,138242c1,a1fa822d,63012289,8e429527,4fad8e7f,9865659f,da2d7370,10f6e185,70dadbfe,21e6880e) +,S(94070912,ad2c129d,cd122bb9,704616fc,3ddfd949,6ce9f6d,6e18020c,ec848e83,9c3b38e5,6bfac9f1,4c901080,b5a732a4,b5d261f8,2b571536,d1fba6d9,b714017b) +,S(2a6330e4,8ddc661e,afa8071c,c1417b92,ea73b060,3653a017,3edb92a5,6e3ca6c9,b38c51cd,4754c350,ba2d56a3,fbf4fbab,5802bc38,6b5516f3,d8b761e3,c3fc7d79) +,S(9142e493,5f95da17,5ae4078c,5ff5a7d4,8c418c1c,7efc4c39,dacb047a,d3f7424d,15165a74,c47133a9,e8684ea5,5a4f9b05,37d0ab7f,58a7eac0,e698adcc,b885cd05) +,S(2e198b29,5cac4dee,dba63ef3,888d47e8,bb8d372,7fcbd69a,d1eea656,ca85804d,31dd5db3,e700ffbe,152b0c2b,1b1c830c,eb382468,1c522e63,676b9ec,6780fd52) +,S(b44e35e9,b2efcafa,f123e52a,7bd9bc58,32a671e2,fbf0264e,5a3f536c,b272f72d,8d489fe3,beb39fd4,2632b80a,1243e64b,f80c81c1,3934ab08,71c16a5a,5aa43423) +,S(dc99ad01,e1324b6d,b5ecf365,c22463dc,f609f0b5,90e6d3be,efddf641,b83a3cd7,b4b422ca,2feabeaf,32c0ad6a,4393c087,a4c1e794,47a043de,cf0fe486,ed11b682) +,S(e174838e,eb991c2d,cfaaf89b,b868f4d1,3029ebfc,ea286376,48fc51ba,f962a359,f80dcc87,27cbddc9,4bb1b60a,4da5cc74,238dc62,821a9ec7,c05ad2a,a0e7570b) +,S(6240358b,15bd16d4,42cd79a4,8b739eb5,4ca21d18,b568b497,65d10dfa,a2583d33,6acb054d,724e7550,ed6d8caa,8a436d51,fc546116,df33413f,a613c0dd,6cec2d00) +,S(a757fceb,560aac0f,543a29b4,bfd3af7a,aa61c077,2c1c07b2,e6268342,e63f8d70,5864ceef,f80855d0,fb4713e2,7bc6a202,b4c07450,6749457b,39d0c40c,f40352da) +,S(f36e1073,57c3149d,902e9416,2e509d19,d4b1f498,bc74814,3a1bd411,2f777bba,d4d7da2d,139a2693,e40d9396,76c3fe48,45f74b43,78f0c25a,14aa9698,3bd1993e) +,S(84ef2d4b,55a40ff7,13934949,b6277ef0,4a8e0e4f,cc49420b,17269d59,224af99a,57affcb7,1d3508f,65ff2b7a,b1d6752,60465e76,754efe3e,80a83085,85ea73a6) +,S(138ef64b,274ff66d,7defdca3,4ff28bae,96b046df,408b3f47,84f78784,3fce7576,ebdd04e5,1d517c43,412010cb,d03252ed,dfe97912,ee4a7d4c,ed98551b,fee1ecf1) +,S(e82f03fe,2ba05692,212a1145,550d3057,2d454728,e2d9989b,435cb608,3d1f318c,191a6fb9,cf295881,92aaaf1f,ea34e123,613b2937,602650f2,eb25f63f,5812dcda) +,S(56a68400,676b6fac,7eb5fb3e,7f345ec0,11117098,c0d1a96b,e44bd2c8,5aafb317,3a41827a,5ae1b7cc,5b9dcb5f,4c41819e,f49ff2fc,ce1d1949,3f5b0ce,9f1dfb4e) +,S(82f5747f,1b353db4,f3afe255,e1f2660a,8f735b1a,e40a5008,4efa3c32,dc1309f5,42e8b903,f4ccc01f,7e87e4c6,71572bbf,d05f9ea2,a4cf7bd7,dd5a9906,264a0144) +,S(89136941,c47b1964,a4b89e0c,376b3136,80ef76c1,19e02bb,bfad594,76e0cf13,b3a2a785,fb6a564f,f4871bc5,177c635,d722e659,77f621a,f6f7537a,2c2d3f3b) +,S(c6250969,c98f580,f0cb51,eef5d8a1,b9954bb,97671df1,c7360a5f,42238909,83d0324c,915eab22,4dd3f935,e197e0e9,552d5bd9,6b1ed240,219731a3,58ec724) +,S(e2399ad9,63913200,4664a481,dea99d85,ad12938d,dd0e4184,27411fd4,8fc7e3b4,60fffd62,beae28e2,2ea836ed,389c3780,5d8b1fa1,fb10f298,f9b54df8,93c69d47) +,S(4d00b1c,186d2992,9a6383d6,cc8d1796,a59c5d7,c27cc7b8,5a1f821c,3003d959,8752ead1,27eb19fd,49dc8ce7,a0b7c7e6,dd4aa3dd,6f8d5cb4,687327e8,ce487640) +,S(344663ef,8b8b52c9,1aa548e9,8b7e1c48,933cbfa3,59644318,5ea973ae,9264121e,73d099c8,9dfe8eec,b957e624,bea5673,6fe3885c,e2f72b06,dfeae760,514d9efd) +,S(37ff484d,dbd22a98,333038d4,7949b4f3,f411d3d5,7ca319e3,5c788bbd,a0de6648,55a5394b,51618d81,d2fb1455,4ec1f5c3,a45cf086,83980bfb,a9aae6a9,20547c67) +,S(cf3bcddb,ad5066b,909339d1,4cc6d3d8,d2881f70,d6f12e1,4d795b06,17556ca5,e12686bc,99e20f20,6220e402,32760224,b61b90f7,8b7c0b1,3c197a47,11678a6f) +,S(961d02e7,db8fd1ac,a38f9110,13d74a5b,d35e47a1,49818d41,49f02edf,5da73402,9462eaac,d698677c,16515ca3,bff217e9,765dc8ad,fe2fa82a,1db05158,71fed240) +,S(43e62f90,574a8e65,25d22ca6,74814ac,3648b724,45a535c,5e1af97e,b46ec3ba,6def0a56,17c1cf17,9369e20e,d18d0503,e141dc85,9edc73a3,18f6a35b,3d939734) +,S(9e682b79,9d79018c,352113cf,98de93b2,457e4b4,a962d160,33b80052,57dfdbb7,9db9cb16,bfe96343,89c468a0,6405d2c9,b2983354,ee9a81e9,3f23ec5d,5049041b) +,S(790187a7,8079b59d,b2a22d13,8520192,5f9682e4,2002c8f9,436876e4,d5a1a8b4,25c8b46,f6b43180,3654381e,56a8e6aa,ade0ad1d,6a6044de,17e9592c,affa456e) +,S(928a4b8a,6c744b33,99e22d65,35a21ffd,662a0dc3,d5bab1d,683ce555,f0169583,251fee84,c064954b,e1daf7e4,5fec87a9,323d55f6,687fdeaa,75d4dcc9,9a6fcf84) +,S(684e88da,81182f2c,ac5872de,8c98b86f,a6ffb73e,9bbfbfde,6c16c3f4,be084c88,c451b59d,fc9d62d5,921ae45f,f7557ab3,ad179eb0,6afb8bb6,bff0645,cf6383fe) +,S(8bdd2e83,a403b0cd,7a8ebfa8,6949bceb,8e8166ce,a8596f6c,ad7b7bfa,4d174343,7220c147,97f682f8,7d707b2f,eec937c3,643bb359,e9effbad,8ccbc8f,a8177172) +,S(c3fa3b21,6e3c4952,85258ef5,f921f6b,b7195869,e46948b4,b69e80b0,be399543,eb2044ed,21f6661b,77088050,3026c2c5,5a519ca1,748bb10f,c8eed953,aec1796) +,S(1c063c13,eb2d2959,379fb0df,50d355e0,195a8bd2,e642ab48,3d6a38a7,af7e63a2,20538f92,d14c9ff6,75c5005c,8c40e26a,b0042874,7f446ed7,cfcf5737,870f2abb) +,S(60c06797,7b54c18f,4b82dc6c,227cb539,6c6086de,107e3999,81f1b5e0,f31d452,3f4546c4,e3eb11b2,e6fd2617,b57afafe,ce0e8bf7,aacc13b,73755f18,dc98429a) +,S(fc15cf99,92256abb,cf263e90,a231ed8b,421cdc2b,af185722,c0af008b,fea36856,abe346a4,d9c40853,70dd46e4,69a3bf24,c01dbd97,f5c9997e,27634dd7,c635d798) +,S(f6143985,18173bb7,428da262,bc8b07b8,1a92b06a,65926ee5,c6f8fe44,27249454,b1d832ef,3a2558c2,d41f06d,4be8e5e8,11fcede9,9cc784aa,b9f3ce18,d701cf84) +,S(579458a9,62218442,41e68542,76a116ab,1f1fd43,109d4bc7,ad5216dc,ee61b5f5,33e56474,68c157c6,15cc8d46,135bed70,21274a4d,97aebe23,7bdd4b61,2c53e2d8) +,S(637553dc,b0804132,b5562678,fe355e8f,abab2001,fe17e3bd,8c051e7a,41fe62e7,28bd6dc2,ad586e1f,f1a6a951,167ba14f,6989b296,874e0d3c,31917920,9b572dce) +,S(eebbd70f,6f64855b,e21ddb92,3e54f583,89e99ddb,577fa8ea,66c3722e,b580e2a3,3d1b6979,15b50345,4a55606e,ad3ac4ec,7c986698,3df60e1d,edc86827,32fd4d68) +,S(4ec8931f,2bf4b1da,6891135f,37791236,3a6e888b,6e5c5ddb,2e350e42,686c56fb,d5f6c679,4c2b306a,bd719770,48dc3e28,3cbab910,556919f5,35d9df23,56a09bc7) +,S(6b5a7f76,fc5b7e7a,7d84deab,ffd5c771,8f49375c,cc4dc1a7,35bc253a,bee9730e,1e935dc4,8fbf5f6a,b12562df,11855757,9eafb8ab,f6ad8b7a,f8f9df64,43b58af8) +,S(2a3129eb,f620958a,4264c759,17e29807,5f5b73f3,21d4cf27,683e4788,9e013af7,e940f5e4,c1fc28b3,fa346ede,fdb8ac7d,4066732f,a6c276c6,89a1921f,d1020da4) +,S(8bfe81c,e99443f3,78307f34,5bf2c826,94a8723b,c4836d12,4c6f5163,bb28b5ab,58b16e27,857e5faf,9768edc2,68d177a4,87de9848,52e65348,36464ac3,f0433c71) +,S(47820cd9,449c566d,2d39daf3,ee4d356d,5423692,a050cf83,1c1337bd,8ad61be3,48dfae03,2988a810,6d069d,22f27445,1200d38c,a9aea665,5e5f28cc,9952c2e4) +,S(2d7f03ce,8e453605,89d221d8,84c3ef28,f9e8dc52,41d7d131,cd6e9921,55a934e2,8414b3c0,5a39f38e,1f14d55f,e28604f9,16a7b272,6d6c843a,57a2b8e8,b7ee9c72) +,S(83887cec,919d8c86,c2150d4e,e842505b,f5a5b06c,b3b1e67f,1dc2005e,99d8e37b,fee0e7cd,f5c9eae2,78d34fe1,2e58845f,fcea9de7,f9883e32,7a2ee941,92b4c009) +,S(519f9e1,138bbab2,da8c03f,565c3fe0,a9d0b709,1a7b50f3,f37df191,d1ca1e24,64d6bafe,2bffce42,3f631ec0,781e96f5,ef6cd6a9,ade6b9eb,367c036a,1a61ba9e) +,S(8091f78f,84bc74ea,69ade208,72936152,3946ffe6,63edee6c,3cd13ad9,4a8fba61,1aaaa58b,af84688c,1cba5d90,d700aaac,6765faec,39e7a212,fe13a9cc,b0bda1a) +,S(50abc00d,d3fe5748,7c2a5343,4a36f10d,8388cf20,56cd5bb4,9ed8e97e,7adb3afc,ab8bad95,14b6040f,b1c64f01,d9b9db01,670fe0d9,3add5d6,8a80e41d,8ded25ea) +,S(a9a428bb,4da01f44,a9e4f253,3436ae75,20e5722e,6d12931f,aa20772b,36a2f110,ba05121a,1830a26c,440f0582,2fa53e20,f8c226b6,85b437a0,557c8450,774c0c5f) +,S(d7afdbd4,6314d677,727fa11b,211e99a1,d6948be5,b7753ecf,64e9b1d0,ac7a83ce,b5f8b97d,748a4abb,a390ed9d,79cb42ab,ee9b2afa,517288f4,80aba1cd,34e21d04) +,S(2b6b834c,d2b54466,a3d41694,b672ac55,13f19b1a,d518ba99,d622abfd,9b6de265,c1922593,ddc0b3d2,ad1d52dd,3cbeb2e5,74ec849b,892d9df1,87ccec50,7ab9b0d6) +,S(f393cf4a,d7f93fa3,1596ef7e,a9c11c6b,f29c344b,1a3ee5a2,51360c9b,a96ac8ea,4e811ca9,de67ceeb,90e48016,30d06125,fbfa56b3,35e3a7ec,41bedbaa,7a8133e1) +,S(bc3b9250,4e14b254,81305012,a248a94,bbc546bd,52fbc0e,848d75e,9c8f418a,9a52afc6,f8b487c1,7653a911,f11d78c5,8f5eca38,c761a2d9,af0ef2ad,a6a58223) +,S(2f5a0e73,c601fb8a,7321e170,4abdb1f7,e71edc3b,bf6f9cec,1467eef,5f6055c0,d8bb1d0d,142d2cb1,3b9d97f8,f807212,b79a5ecf,13d942eb,c5a3f442,6553e393) +,S(b83e51e3,b4fc69ac,84d099b9,6916c11d,8d8d8d7b,f5cbe15b,fa13ed34,73a54ae8,232e0f88,69c53923,22018084,a7cfc251,daeb7a84,6e1daa78,f3f365c2,ca3dda5b) +,S(10971993,50b07a32,1532b372,2ee89058,e90e9b30,5908cc0e,a249a40b,e7516377,69a0b67c,7bd55a04,9be3a3a5,e308799d,dc735f9,ce56ff67,2c796b6e,5a0a1055) +,S(dbeef75c,c95d5018,f3d71711,a0299dd2,62250814,c1469647,dcb27a23,e85c4477,dd4712cd,16334f8e,2baa6855,6c5237f8,676311e3,1cbf9753,35e76a90,88d66413) +,S(28cb1199,2bdee938,f3405f18,537b410f,2723888,e4ca0d29,d96806d5,6baf114f,e6c63fe,bbe5dd81,e3a9fc1e,83a5ce89,c3e2ef6c,c2a57fea,695ebf4b,e81e5aa3) +,S(f0a2df0b,64efe99e,65f9f176,89cec5d4,caef385a,e4676da3,790ba2e2,4e9f60ba,a7ca7e08,b900f664,14498c12,aaa77da6,6a2520,7bcf1a85,713b6d14,807a4519) +,S(d1bb46eb,38e54396,dc7ad4f,f553106,54fe9b06,9abb1410,799dffe5,482b0f00,14b0619f,e08830b6,d0a5463,96826b6c,d03bbd2c,af930b14,a031f922,eace4214) +,S(27bd2e56,7705126a,5f5adb31,ac1d09a1,85d74002,c548a84,15c0cce0,1f69517a,12203dd7,cba21cd2,9f9ce428,a8e302d7,202690ad,8734c08f,65578192,a5468d32) +,S(6b2cc790,1c72e201,693835ef,ab2b676f,55441add,b8dbc3bd,61d43201,bfd21d9c,59973406,deea0493,daff90d4,b62ff38c,6690bb05,18e75560,1bd5b3a3,4add7456) +,S(75e85c3f,32f953c5,632a8bcc,6bfcd6bd,c63c3b93,e607d267,5df09fb5,94840f27,22f5a376,8714c73d,96b24f89,d426e668,bc59aca0,cbf6dc47,723f01ed,6cb6bb30) +,S(d37a3071,969e152f,41c0eed5,7e28f1e6,f26e1752,68c52683,15e200b9,f86d56a7,53d52726,98751d1d,dc4b1fb,d9621723,70e296c3,b47436d3,abe20356,76ff6181) +,S(715bb304,7f5e6973,36546640,8e183bb2,67693198,94e341d2,37d5101e,a7414976,28440f5f,9e82d5e8,7a5ea672,2e95c3d6,a89dd1fb,3d81aca,db7609ee,a1a968d4) +,S(f72d142a,4f5b1595,a7b4a52c,c6812ec2,8e4924a4,b087c139,68d8adf7,dac642e8,501b644b,b5d8042c,f16ab9bb,bc594c14,585486cc,fbaf47a6,5378f97a,761087dd) +,S(7b3eff8f,b4ca8a3a,5fc3cf02,a469f34,3840846c,d8fbff28,243b962,c1284c26,be2588fd,15396124,a50bc555,5e161022,3bbf636e,fd510522,811902b5,b1748579) +,S(2441a8d7,71fbeca4,cd365225,7974e4cf,ec2a7035,ff2b58a5,9cc5fc37,8a113dd8,54b0776,5316713,4bbf4c6a,7ac23360,fe035d2d,9316cfcc,ae129893,82447981) +,S(c20fca4e,d05467ca,45b916b1,2f4ab386,512d097c,b64b824d,e78e9a2a,14cf7591,8851acc7,96ee4072,ca87e69c,9dad10e7,931fc48b,238cf46d,2b2355a,e4eecc02) +,S(2f6b0e8d,1375263,b74e415a,ad758130,a34c6c6d,690ddd67,63492eb2,49ec8e7,d0c791f8,438cf6a7,976cb614,eb4c9f67,adc72275,f6236868,e384d538,daf25dbe) +,S(bfafc1be,426f056d,6f8b3ed1,1374db21,fc00373c,3dd8c762,c5ab91ea,b2b665dd,9c41f297,a4cf003a,7fa7b071,a106da4,6dc40050,a7592781,68436115,150e2a2e) +,S(cf711dca,90560273,6d776f86,759d74f,895980f7,1728dbe9,1df93076,cdcb4e8c,52a379bf,cf25216f,e3556def,e889b23e,2f91f6a6,47ece012,4e140aa7,734f1cd5) +,S(b9be95de,27aaf198,c3001ec3,63690f2f,f516fd75,1864794e,1c3516c9,abd1384b,68875f97,dca1dc43,3e9b614,488cb8f8,1ff85d58,2ba853cd,27fc1227,1ecb6df9) +,S(f5f257e6,c4d06a8c,53442b37,7519ae03,7bec31b3,c257f331,fff53773,28e9638e,b6a1e60a,48d03213,bb52e3ed,d20d0ca,c80beaec,bb40169e,35ff2165,43e986dd) +,S(fc35c74c,17e38aa1,15803603,30af7d92,a5281b3f,cb6cebf9,df09155e,64099ce7,6e2f984d,41e8693b,5a4c1c58,9814d131,8421fbbb,2ec8e45a,c6239227,db79dae9) +,S(ac135e01,49d97363,7405e5a9,89ffaca6,c1bc18a1,cce34aa7,4732fcce,d54384dd,3e38bacd,ff954a6b,6bccbf63,9f8d709,d8e54553,6113dcb1,c471a162,af021d0) +,S(60a013fb,efb3c5d7,802400c4,e791a019,bfd8f657,cf4c1055,f3674f92,9f5f345d,7e763c48,3582fe3e,2a0a5138,ca320013,9907e364,5468b5b2,711205f3,38a1bd97) +,S(a099a106,5d907a8a,43a3d027,3a789992,ceb3a659,bef93a9,6ed04ea,19a7acb7,137f9ffb,fe3c22ff,c034bb57,9f0c9b46,d5cca4a0,db1407db,6fe3d7b,5bc5a50d) +,S(9ba1da86,d02763d6,187ea5a8,c11c9da4,c6ed7017,49f107b,9ef4fc3,94a792ab,f19e22d8,ab5459c5,5bf87908,90175184,8716aea6,5c2d9650,c472199d,6663f741) +,S(3642701a,d30d1430,17be9363,3f28d90d,b5e02238,9350934f,63a514c9,a677ada0,2fdf9ab9,c76bbbc6,c4e79f48,7a8bbd86,6432fa98,4f52ac22,3440de3b,f1aba970) +,S(29f79c58,100b7098,d8d53012,e2c98719,6188c0d,54712c31,c2ea3a52,d6941a5b,be9edd99,eaa6c1bb,d0ec42f,586a2806,919d5bb7,2d59bf3,7216890b,9a2d524b) +,S(e011aadf,bc35284f,816d5030,c3feb350,4b470d0,ac5ff061,e5ed2c47,89ba1bbc,e0a98f93,4f2b591a,36e6ee97,f293be77,21ec1a9,3f4b2700,55a0c01a,3cc979e3) +,S(a5c8816b,fe5356,37eb54b6,88b9221e,ee06a51,77ffedfb,3ed96ee0,4fd78585,3f86637b,9d63b11a,44897792,9a6aed53,7d65951d,aed6476f,e03be5a8,c9ff8e5f) +,S(3b952c23,7e44350b,95207798,e708fce6,2e6d49e0,912a2509,abef16c9,c7194707,f784972a,419e6c8a,c9d41a38,57912e66,e6ebb631,6bcdeeda,ff49b59d,bdd68936) +,S(8d9796bc,d9d8152f,80c7982a,187a4aaa,b75dd611,99f86632,72502f24,dd57af04,fb9b1479,94a31e3a,28d5695f,2d689951,317c2d2,98e9892c,89c98202,b7e611bd) +,S(96b2bc5b,2f4e6445,1536f689,d7889669,4fde4d7b,6ef67f51,84517704,6a02de40,e0b76d26,f91982db,5039bbf5,afbfce51,914eee9b,352c178b,2145c4a1,88e89cc) +,S(9bf7cf10,9f129500,e2a8f54d,8658ef97,4e3ab2b9,a1d0d036,25bef5d2,432e2d79,2113d7ad,f77e1c68,51b8bb52,188ebd25,dd6373a7,19bcc20b,e32d0f19,496e8582) +,S(10d3ffa7,20375b5e,afc8c741,4d9aa184,c91f853d,61d58dab,11a04f2a,f3d4f1b7,c1f84b2a,8a96f43c,b215c704,6f8c3f02,c98d750a,d416f21b,eeb10ea3,f298c90) +,S(56d64e2b,6adf1cd0,b8d63692,1b68733,e92577e,88430e92,c0e679e8,c3a5eb6,1370e,fbe98423,488427c2,57d5e696,5d4b687e,25e4b824,51b1a6eb,7ef71cc0) +,S(fec4a03e,1c83cf20,75deddbd,20c24792,6dbfa352,a56821c1,420adc34,731528bf,a152b2af,8670e42d,3bba0d98,f387e9bf,1bab788e,fd7bcb2a,a787e6a8,bda95509) +,S(580a7517,7ccea9ac,63ae6d53,e8959e5a,a45d11db,29a87001,779c260f,2fee92eb,793be69c,3263c64c,2048c411,115375a4,86733a90,d8c12a06,862f4f9c,669e8edd) +,S(9286bfe5,78931ceb,cf97431b,1137a19a,991b46d2,d0dec2f5,35edb976,6af636f6,7e774d30,e962db42,83cb38fb,2053b780,c55fce80,51edd5f2,8cb1b5a5,d329f516) +,S(606d55a9,9b702652,5382cf2e,efeec65a,803e3851,da60a041,e5422c1c,28f4890d,dc895a6e,3c2a6411,4a04a1e0,31b8aa17,79ae2c05,1f4eee54,7f8a54c,50eda1a7) +,S(a16a0d40,833ec1cd,dcfef2f1,bcfc8ed8,11387dc6,4e4df6,6e807f69,75f917f5,548d7d37,13de4a53,151f32a8,2880d087,7fd281d9,63011388,ba991bd8,822d6527) +,S(5949d2,be574e23,9a3e3e7a,ae20726c,4a687a15,edf5a62d,9b79d0c3,4f9f0329,71dcb25a,167ab25c,311d9427,5480f78e,f7f4e777,9723e55f,337a9121,445288a9) +,S(841f4e4a,e67b0d8a,49d7b295,e9c1ff4f,cd1e2333,82101536,cef7c4e5,7968b240,1f561c9c,265fa4ed,eb979f4,a8dbe679,ccae8037,8cd73d5c,b56671d0,571f4161) +,S(22623df8,c748e9f2,88bd4b83,142788ff,faf680ae,a2640d,dd43ec1e,46cb7442,380ef00a,dfcdb592,f964381d,ce9f787,17d5827b,494c3aaa,d5e0e013,87a55da3) +,S(816067c3,6438301e,ea07a21e,5a60a17e,670083de,b3b66e2d,c88c6548,f45185e4,5afa391b,9a95e9f1,f04f4e8e,236fc39e,2eeedcec,45026647,f5982aee,4dc4cbf7) +,S(f8f23561,4745c531,24cf6431,ba8e0425,7d28af9c,2c196485,3546924d,ce085c1f,a165067,e3b41b55,a548c1b9,3fe76b5e,bd101275,acd29e75,7f66753,6734750f) +,S(21325584,e25b8a15,c25537d4,c70853b2,28bb933d,de04be23,7753b933,57f2f57a,3708c8f2,78ef57a,f0b00d5,17f21a6f,f627b5f1,59ba1f53,d20b727e,86e873e2) +,S(b2f4f7fc,f48519b2,c00c24b3,7ffac141,88b0baac,bc915c77,845cd6a6,3fdfbda3,b206b59e,6f52ee43,3e7196bb,5f4cf3c7,de49723a,cd5b3e17,1c94e28c,7d57702c) +,S(b4e65d4f,5f420006,b7c70fd3,9564f9c3,fd9c5c53,dacae064,62212fec,ee7f7265,307b6ef2,e3993bf4,f321723e,a83ec2c4,3c75b8d,684665bf,fc073506,816bee0e) +,S(4f104593,9ac609ad,25f3968e,9798ee93,aa58b61d,43f4bab,8f2352b1,de3a7240,ed8d87bb,988395fa,581698f5,c55a5093,ed9d0a89,3f4aa4bd,186221ee,7f8179ae) +,S(9b5e74ff,e515c125,9fa6b215,7ad7529f,90018e85,23888738,d097c016,494672fa,1d55866d,4c4e30f1,7bdbf70c,43fb3b9d,fe2df3d8,41e18bc4,3db3e3af,21fece15) +,S(77bf442,ac8cf718,102968f9,49387b1b,30f8a2c2,c76a2cf5,10d817c8,7e17e302,bb0f9e61,1d90046b,1d3b1103,e6c5beed,e4daaa85,f6eee1f2,6a6e756f,d32af0e9) +,S(27de125c,d49f2049,6b028f34,b16a9988,d2f5d469,30834fe6,4bcd388b,78c266a9,f43d86a8,483dd92a,2ad9dac2,4039ad2b,84cdfc2d,323979b8,1a43de25,5cb54bfe) +,S(21bf7178,ae1d75e1,94bb60ae,4efb5a8d,7f026cf0,7f845b13,2250989c,4be9c116,6caa82ad,bc21df15,d1744466,4d3b58f8,76b52291,5696481d,434f689a,edb8d967) +,S(249254,93ee016a,41b65b7f,8289da2,dc9100f9,9c0b956a,66d245b0,5632e234,bca30194,1cb51f98,1504c536,74f6f904,d883ff46,7aec96f8,2ed5ce31,7c45b3d) +,S(d3f644c1,e3472b4c,d46d89b9,6b937108,ea8e9425,9b9316fe,230e7538,7d867f76,91822603,fd629732,a3b37ed9,d5227942,2e536ae,316bfb7c,597b2da5,d8cade5) +,S(c8461f4b,e2bd14c,a88e52c8,147f656d,915c2675,46252e89,d0337f7a,e325b261,18971181,97ac799b,3f632868,e46efdf5,fa3b615a,a8a92b07,e38ceeda,9cdcae06) +,S(b6e5f590,be20a938,c1b57e1d,a7bd6ca1,a8c2406a,aaa5860d,9133342a,c395a380,a6728cf1,a2f2eade,72d86569,ab5a6305,cf01eec9,6a6de026,ff146d5e,7d8a04b6) +,S(3d25179d,465701d0,56d4eee4,b5efc10d,8b70138d,f14908c0,3124ec95,59eb5d6c,158b7bfe,1d61d7ec,633e88e2,b3c5897a,3b56f7a2,ac557c8c,3e032a71,8b95980f) +,S(abb5d54,c7171499,95893425,bda27f10,d8515511,91af6927,9849a597,46f94d99,4cdfebcc,3be28dea,36d06e89,ff4209c3,7012ff0a,d93d7ad0,4e454422,c4b9a161) +,S(989d0125,115ef9c2,900dedaa,4e31cbb2,f1243386,73ec624c,52352907,b325c73e,d3699ee9,945de070,fc1f28ee,14279750,d553df63,2951c0c8,d1668206,94c6c8df) +,S(c4c5c5d4,29c3d1ff,628bbe4,e0edf70d,5e05db13,c82a2af8,2d0e4232,5e013884,c2c76cb8,825188a9,fc29da67,70ade97f,ccee860d,d13323ee,f2ba7e7,efa97eea) +,S(8662d850,c623b65c,8db5080a,900a0e83,be947111,ec0b9edc,3601549e,26c0807b,a71d677,b0c9e7a4,f66a72b3,2918083b,f91e724c,cf8c9526,b3df0f6e,35da840b) +,S(d26fef49,7e7359bf,33309b38,93abbd44,543b73c7,c0eaa626,cbdedb17,1d083898,ad8bb209,bb090b39,6b501ea9,a5070f90,4d60c20,d48dbad9,56d381f8,79851395) +,S(569be8e8,c584b682,7d742ff8,5b402112,5b4560f5,f173c983,8f8785d2,229d8d0f,b09381a4,a8267d89,a8d5581b,f9a49d52,47c74a33,5e26e354,22edafc7,d41b8559) +,S(de34acc3,4d1787b3,ad967bc6,c5960d8f,842f82bb,c95aa255,d4a9e794,d30116d4,2fddb41c,b2b6b52a,57cf4d3e,883d3f0,e322c40b,ef098505,b6cb3d77,a21816d3) +,S(47430b48,76dbb762,6d549b86,1742a5b3,ece85240,70dd83d5,5446fa99,c5c50b1a,d75592ba,7004573,58c6a0ea,dc8ec772,b53dd048,8ddc73e8,5af357a4,af200df1) +,S(f1d1e0b5,e6687266,ba17339b,76bbab6d,8c2d8ffe,f6c68fd7,9140b097,d6e9fe13,a56226,fc233385,349c5483,72300f97,a1d8494d,a67db50b,b96543d5,bf24e580) +,S(22a6f735,76140de1,3dbd0426,e968c374,6e8132ff,383f44c3,c0515b85,f8cdbcd0,9dcd89a8,90270e3e,358dc004,40f95a43,430a399d,a8405e48,e69e3455,fbd18d1b) +,S(2ddc5328,afd8ca0,9bb0c6ea,57442e8e,fc307b30,c29e2867,b46654e3,e1a9ada2,7b9ab90e,db84e6e8,7bedaa6e,31ff90e1,7d07793,19977393,b5fedb73,c087dee4) +,S(60b6f839,a60af52f,d30a116c,58b9c65,1fb1c854,546dfa9e,1a01e2c1,95da0fca,5e77f69f,28cfb414,be39b07b,2469d8eb,b0e74306,1d856bcd,ca54d83e,20d26c40) +,S(2790c19b,9b9092e5,cb06bfd,f95ea43a,2a1f1f28,57c96776,dcd26a7d,ddee53c,fdeea120,d04e6e78,b2387afa,a0217098,de067759,8b2bc5b6,2715d9f3,714e7f64) +,S(e544320f,9ee8bc8b,127576b1,6fad9782,db181ea3,4514f7c0,d7f9046,f5113803,b93762fb,2397444,e69b63dd,9dce7c32,3c73680a,e26b5e0f,95211972,c0510741) +,S(6c7f25ae,73e428d5,860a236c,bbd4d74f,8e2706cd,69bb4cee,39f9aafa,db55313d,d8cb8fc9,e33f9b18,e9a0864b,e58ea921,8db30c4b,d5dff091,6a44b581,c8dc9121) +,S(289d1b28,ff710d47,4d1e9c3e,f3952f27,dd9eaa3a,30ef499,121ea53b,9b93d4e8,f36af80a,aebc2dd5,84cd5cb7,245b3cba,64285932,77f4be38,cf2b394a,ee880667) +,S(f02ab597,ac01d673,25e87b5d,29130c18,2a6f4a8a,d4ef7476,b9fa1da7,5910b5aa,ae88c02a,ecf28b13,ecec5379,5c34633d,d3262d1f,65ecaaaf,fe89640a,cce38adb) +,S(a9a974f,71a73106,57732c82,d6d4c6d3,c625bb70,4ec29a8d,2d8f8418,dca0413a,c20df433,eed4e96f,d5ef222d,860ed1e5,af1497ac,cfd1dc21,26e8925b,91b372cd) +,S(7866190d,728e0899,19a0e9c7,8634b55e,4cc392fc,1650471f,4a21cf40,8d77496a,1bb5fcd9,540422ef,caa8e265,c35a1e64,29d79de3,a9369b23,3512913,ac0cfd22) +,S(c8a7ffe3,44b3b8eb,f00e4e2d,e63d9540,25cc115a,9110c773,ce0130a4,8333b9ac,ca1ffbe5,10c63b5,674141aa,5ca87246,ca91280f,da97e806,dbb523fe,5ee67b6e) +,S(6cbba6a,13ff6ad3,83419e84,e4da6871,9cc1e633,d4cf3347,2f9966e6,4f9208ba,35122582,c7893f4,4fb92c34,e9c4661b,5859889,62a7d1fc,fac8a2a6,1e214a88) +,S(e07f8dbd,691a8611,eb5450c8,2c765dac,ffe9aa81,49ba3e12,87b23fda,fd9de719,932e35f0,8e39cfee,a2593799,4e118c7f,acb0c6e,5b526bc6,894b061d,8cfbc509) +,S(62136898,32fd9416,cde720d7,1d3f32a5,51f3e238,fccc69b8,4b633a2c,86d2c5d4,137e9a4d,62247e41,8596d968,4f1e5997,791f3b6d,69cbcf68,206f715d,be784e9c) +,S(8b010588,62de6706,253eb2fa,f710c086,40a318ba,1ea684f2,3254e8c0,dba7b9eb,54a48862,dcc56c60,cccbf43c,f7a33f9f,dbd7e419,56f0f48e,2ce2371a,19bfd264) +,S(12d3908c,14af8346,fefbbbac,e56bcbae,3fb2ed87,dc30b1cf,eaf480ea,84f213d8,fc4615fb,df7ddac9,84676421,2c4d99,fef41e5d,98e5824e,cb181a98,9a67fdfc) +,S(219d05e2,a7b8cc69,bbce368f,62922992,b474286e,df7c13dc,8da62d16,1784cd2,8aee4f73,9a7eb1e7,8ee9407d,e8fbabef,dd28203b,2161ede2,761e178,a34c7f5c) +,S(d7d0cd59,9a76fa91,f691fa23,ad265f38,49bbe213,c38cb074,852005b6,d85de204,f349572c,60750dae,5ea1330e,a725a0ef,ed1a2d60,c0b1d9d1,e938f37c,911ce2fa) +,S(a3fa69f5,a04c9023,83d8b73f,6fa8fc3c,9f65cfbb,2c77042d,635f4978,eabb6c6d,c798a1a8,9994aab1,4af95b18,f389a2f1,accb2d7,59997e83,72c1ca5a,c3cbdea2) +,S(902e881a,825c457d,79872e71,e5d94170,8540734c,1d050e92,cc5c8afb,13b2d1cd,ff075132,63bf6fb9,11163ccc,f62f8246,de099f07,ccfc9e33,8ac82c30,bda62d43) +,S(325f19f2,4c470556,d361aa2b,3f1932bb,6923ea5a,4f8cb505,d34cc60e,729c144,f4a9aeb8,29a6a0cd,f981bf35,81bf8f9d,73e3e9c1,61996178,2a57c46b,9e94bec4) +,S(6994f3b4,41a6cf61,53e5f860,2cfffacc,bcdf7245,eb078247,63bb07c6,fa1edd4b,ec2fc5ea,892da897,29c479d8,d3f05152,198ee4ab,87f73bd9,27db1160,1874c174) +,S(21855832,4e8f796f,fd51bd2f,8c1f6a8,5663c5a2,b5bad37f,3b7a1052,6acb2d8c,e77ceecb,33cec03c,99690d44,b0343bf7,3b93c495,5d67ccf4,b15d1d76,a1897c2d) +,S(905daa3b,32f2a801,a567c312,ae4772b5,3196933f,487aa1b0,a5674cef,9d91b099,bf6285c3,6d271719,13691d5d,767fdc17,82b64843,5b2ca1d6,b695871c,41cf369f) +,S(df7cfb84,34b60524,75fe5161,3dbe0e7f,1b685376,315397f5,b39951ee,b65339f1,e725cd7e,1419e455,2d953393,dd9651d5,d1beb3c,6fa44d2e,e580ccf4,df558243) +,S(e7fb9efc,88842b9e,a3c96b82,1ca5eb80,385cb276,28cf64a5,d8c5bcb4,e5732491,c8e676bc,a6f9e037,263b8390,675a97d,1353c128,eddabd5f,5e928153,78f22331) +,S(d1a35f0c,272ba216,1e6ac0a3,fa440f59,bad79715,d71e12fe,cc12369d,cd24285b,1f5b70f7,d475716d,b9ef2f21,bb156400,49dc41a8,96102ec1,806b949a,c99edb3c) +,S(66ba6e8,5f2ddd4c,e17da74a,c7ae629e,4f420429,45932e5,55110da5,2a7b079f,d8ebac5b,eb8eefbc,f4da4f35,79bdffbe,21967904,36487733,263089e7,7a80402) +,S(6f7f69a,26881052,b4bcf806,575f9c50,c36e7c22,1d7b9e48,7b1f39a0,b4f3a749,11d06b84,d89b88b,ab4352b9,cc160e50,bc183558,25bb602b,89235aa6,7331a4c4) +,S(4be16d6f,571d503b,26169906,75c01ac5,41c23afe,84cadb90,eda0c21c,926c0abd,1041ede,ffa1f2dd,61a116c5,dd33fed5,d9ede78f,cb2311bd,9a04fe32,9ec1d06d) +,S(8af88c5d,b55eacb6,760abbc7,91698c57,19160335,ee569bd,33bf050b,1e75886,4f5b850b,6bf2b4b1,29aeeb24,596007c0,ca203eb5,d2be6bea,f61bf596,bdd9a12c) +,S(ad33e77a,3316eb8e,1a764849,13915e81,edb69518,8ce7507,2e2b6088,4cef8672,fa0161e2,4bc88bd9,da5157fd,7950c75d,6c4f4f89,f158f13f,16ca5e4c,af7ccd90) +,S(444a81ef,7620afe7,91d96ee9,b1c34485,cdb51e1f,6022dba0,69ededb3,d9d8c2bc,a88017d9,a49d4ebc,2ee811c7,fbfcd9ba,bd268329,1efafb52,e641af11,9751e2fd) +,S(5b1e07a3,9530f8b6,60787e9d,26503a2f,77af3ad1,24ac8aa5,1d10b663,ceaa5c51,fcf4c0d3,8d55e0fb,2731e59b,686a806a,e87cb510,7bbd013b,4500c470,f77810b9) +,S(3e8c17,e986a86,57b4c403,3317e67d,b1d42e7d,9625e844,ba533ed1,73174309,deebe49f,f4f5a35d,ea0f396,63c7ee0e,9db702f5,c296fe5e,696f5521,94cd6caa) +,S(a1096eee,5e9bcb19,9d24c078,b46b528b,6432af90,7f1d57e5,746e83d8,4d112c1,bd13e4fe,699436cd,656b3019,acd54f3c,97eace0f,e1e92fc1,3f08a76d,d2e7c6d4) +,S(54758579,4218de75,db40a6d8,99a75ee8,36861093,4ded0938,98c071b7,6665f2f0,3bd55642,13e1c689,70cdcd94,fddaa656,6bcde4bf,29c761b5,c6f613f6,19174548) +,S(4eb32992,fcb4bc44,bff56604,f4f74586,a4400290,5ee9adf7,f7bbc694,45456057,8576a8f2,68349f01,ada77c67,30510030,e0cc9d8c,66db7609,21661540,ba45c3d4) +,S(350b2def,d2eb4933,c6d428e7,5990a7c0,f291723,f92e5ea2,69c5b4c8,b661a22d,61acdb00,add9f34b,f36126d8,380ef5bf,70f807a8,1320d59e,3540fb25,90de6943) +,S(914ea8be,ce7f8819,5337341e,eaca129b,2da3c96b,306b017,d7afd984,75f360ff,f2aa5548,ebef80a7,483b563c,e8b242db,582948a4,9fc89213,d3272a63,85ac7b53) +,S(f656e17,38da25f4,baabaa6b,d70e3f5f,ad6d44f9,c53e1a33,4596246b,83dc0fef,40a8b4fc,34639287,a65f53c,f373c2c4,c742ce4b,2040fef5,4c31dac9,59fd83e5) +,S(a47c8af0,334e3ce5,464310bb,c0daa66e,d77e1023,a2124182,ce3e6771,933b618f,6dbccb54,56d7c75,5e71694f,fa1713eb,41ec5b2e,8715ec4b,52295294,c0c7f08) +,S(a8a2862,5e1d04a6,5e87947f,82178d5c,3b5fde31,1eace688,6766ee9d,30753ca9,f82ad6f7,483aa04d,a79e672,efa109be,1feb3f75,d73923ba,94df2f1e,2efc2169) +,S(a01ff54e,5f8eb855,e26903cb,3fd407ef,4fe06208,a0f44837,1e83f7a2,31c017d0,2247c6f9,c52f1a68,84c18ec0,77d92514,9fd59b00,27663ee2,f0e5b2ee,f2edf92) +,S(e7b09c3a,626ac89b,6caadbd6,99a320c,61ef4fe3,11f6072f,f2d7c875,8d42aed1,8ed996d3,6a7b50e9,8e5c64ac,e03cf5a3,37c3c5a1,6d99c5e2,c0faefcd,38609fdc) +,S(3bba9e53,336c2a06,ca89fb52,26059041,96307c97,373cb717,3f35a45b,863ff2fd,f2fe9109,3faffc16,f58ccaea,e54e9b8c,419d5123,6e8c960d,52ae8341,27d24799) +,S(f61d22b6,dc660174,22122400,432f533,11950c21,b6240acd,af905f9c,2c0630a3,6068f5a,1a662cf3,93eb7e86,5cdfab18,692bb250,15de2796,1421a457,49ffb05) +,S(a5b60855,6b1aa22d,8bc38dcb,8f3e4721,891c45dc,2702d13,7189be70,e8a80962,f77f97d2,d5e305ca,1fe20b99,e6c182ae,3a9b3a69,7cd5e34a,7199032,fcb1ddb6) +,S(70c3aaf9,eb2562,e1cae950,be6f592e,f030301b,28022ac1,be3aa5cc,85e1a259,3f2cb7cd,31a8d319,ce4626f7,213aaef7,3f91f2be,a17addeb,61f217b9,4c587583) +,S(1dd70dd1,a8755e37,28dfcc4d,443e7911,a67952af,c33e7d93,b975d136,8d06e530,4684f974,1f5894ef,47040074,2ecc73dd,240e677d,b6bee0c4,141dfcd,7190d084) +,S(d44d698d,7aacfd4b,d8d6bb7f,2d0dca82,f5d37c3d,46573546,2b180cc6,9083fcf9,a18d803d,4232965,90c67b0f,4c415bd7,c0c94041,3740be47,2819bebf,87dc407) +,S(84589ae1,30455742,85522ae7,4b1bc3bb,62730a10,6154d9f9,4109c010,51b34ca5,b979fa08,f2a9af49,bf6ffce9,b2fa707f,de14fcba,3de3b903,49bf6235,37b3606c) +,S(3dec8fdf,89118996,bed31c1e,fff15c1d,bc84e73f,fd04c6f5,469d2f04,8b724627,b143f3c1,e20b5bcf,dbd1a555,f4ff88df,dacccaa2,bfd4310c,16ae2710,1beb2c8c) +,S(367a5fc5,519dd9c6,39bfcc4,70ce465e,23a8dde,417b412a,2f0f4374,8cac160,5b8fbddf,2c6bfc90,e291b136,a3e0f8f3,faa64820,97a87cc2,dbafac5c,a7f021a6) +,S(8aa5587e,7777606f,60bab6b3,20d88e93,1e7c2efd,487bacce,5fa3256c,9463efc1,ac5ba76c,98bfa132,c16921ec,aad52289,50beeb34,449e0c18,88a39fd1,d3f091dc) +,S(79c00191,ea632ea,30fd9e6,b0d11c6,af3aa441,eca678c6,a5d6bf3c,c84cae0,3f954070,3b19a941,3ac0b659,bf401c2d,ae9c8bdf,2bd19e85,472d2d82,39dfb899) +,S(c84de722,21a59e95,cdd951a0,66483255,e858aaa4,ada498b3,d4ef8bf8,3a04fc8,73cde958,915abf28,df811109,a6220449,548fcd2,f639102,158bc451,4af0a0b9) +,S(8b1b8c50,c6327d61,e063822b,2a3c5935,fedf74dc,fe694c21,8cb6b892,b5a9d6d5,57bd8952,9f156435,f47dfc47,9ff4314c,c036766b,5b6437f8,41f60cb0,fe168b) +,S(b45eec8a,3ae82f98,52117c4a,341f8184,33a31ce7,719d7650,e783fd52,48702c52,cd556b5c,c7086b4f,905d0fc,ea01497b,25411785,9ee9046d,c988c6e1,9e0a1c90) +,S(a2d5dcdd,d93096c7,67b4871e,ac58cbdc,31ab7013,865a9cd2,c5707780,80757319,7aa406b4,b130b23e,9e6b5978,b1e0b537,227ae8a8,af62c1a6,a6d46ae,4b064547) +,S(712036b4,e5d35950,a7564ea8,3509bec1,e97f6e19,121ae5db,3d314c19,b9ed2b2d,25862ff3,8d0560ea,4698d2f,425342c8,e3a32232,f9c9572a,21d7414e,68a93616) +,S(5bcef0f7,d70fc8ba,942e58c8,79afc973,dca402e3,795adf0,7562b552,f0bfb392,7cc85a4c,ecb45bfd,3efb0e12,c3fc56f9,1a444ce4,73256474,54ccb089,baf1919) +,S(dcd5702f,9d508a1b,afab9f0,af5c4e9b,b9e5f214,6767ab0e,b5c1d859,39741ada,f7eaead7,ea13e3a7,dccd40a4,a2526501,3369d558,6f0c735f,9eb2518e,ddcc1fa1) +,S(2cea30d0,4f629d,91c3ade,1b8b7176,363bfcb9,25d3eec9,784b91bb,e6cb3d9f,a83f4bad,a42ab171,cfc9a76a,a3dde34b,c48ba454,b39b36e3,44446096,a1c42624) +,S(858b41f2,767b191e,df15fcb1,3a41934d,150e54d6,e95035d0,9c6dfc7,a1c32f8d,8180b97d,76dc95f5,478a2172,4802a28,b34d6e9d,f65d5358,e5cecf82,9fde8dd7) +,S(d5c98002,bee359b8,6d1234e5,ff418013,3eb9a668,d2f1294,245fd020,c30e81e6,4e522da4,cd2bc795,65a2e4e,e2fc87b7,a0b6bce9,1d90376d,921aeb49,5b3781de) +,S(ebf9162,2f9cea9f,71a4ddf5,82de4b7d,34002d76,da8acfb7,d4d6c3a1,9520c1ed,eee75322,3e1881cd,8e3fb483,318c75aa,7e43d049,8e53536e,cd481d18,5ad4e251) +,S(387f6a9,d08756f3,8c2e111,af74be68,acc4504,f3669ff6,b406f6c8,a61db4d,288595e3,ea1d5f91,26df96d5,dcf5cf4d,ed0bbba2,37224c4a,59db552e,87cdd28a) +,S(897ff1c0,989bd52e,383a2d70,e5920144,9aa409ee,9fef20df,25574956,dfe46714,3cfbc0c9,308c6529,f4e95a00,644a873a,de094069,36dfd6c6,bcaecfa5,9adc9d1) +,S(3255a8a6,8e0484c7,8b6bbf21,e2d8b24f,bbcbb337,6f84feef,b577ef1a,b5a395af,17b3c002,f9204b84,e6d4a426,d2d74893,79ef3fd5,441e881f,d8122599,2912aeb3) +,S(2ca4a952,d4d9e3b0,3943eeaf,b1eda225,1fbca101,e7071b7e,2778ef9f,ddc55599,bfacbacc,df02c18d,f81a2c04,4748c7eb,e98631cb,63ca16a0,9892e163,23891e00) +,S(c3e8289c,478c334a,d47b0410,e1b6ecb6,46ee5f8,8a4dbd73,10505f6a,de4383b2,5792c2ce,b0431238,647f4309,cb4ed220,229bee,2727b91f,de4004b3,d6f0f55f) +,S(2bbdef60,a86292f9,867ad63c,67f98420,86fb968d,db92d9d5,f87bd27c,15119049,f4a4b762,3536c479,29099d19,3d40d4d0,e75dac62,54f03538,80286756,60a85362) +,S(77a6e090,9e7dacb3,18014ef0,714a4be1,fe3ee47b,e22afd2c,e0333cb9,ff2496a9,54f0e475,b1a9906c,d1d915d1,81961492,34461e27,e163c384,3815d188,5251065f) +,S(d195b96b,78719254,deb4f413,979f64d6,ea94d5e4,79350b11,45c39e45,4f40ff0,238a4440,613c846e,9472d4b2,b0a4db88,b8245cad,a5af469b,d997f729,c0e0636c) +,S(c39aa336,208aa65d,75bb0f3c,6084f414,ad024d15,48da5bd8,113a619b,4815b1f,7aab1ed6,32741dd4,14883b22,6e573ee6,455a0053,6d849200,4b233153,1126fe5a) +,S(e80ca23d,baf82db,cbe0bd27,24cbb31,d6661c70,44d8a8d2,2967764c,fde31f30,a153d1d4,73187878,bcbc583a,5eb83e5d,f67e8142,46861713,8c484744,a597451b) +,S(395b7a65,a5a9c23a,f96723a,4d595a7d,f3e8505f,e0aec120,711cb7b0,2e72ef80,59020dd5,47476e39,36ad37b1,9a256543,4f88cf03,2992f4b6,2229a5e7,e49bf990) +,S(67a7e8db,b83e23d2,7b57e2cd,9512a5da,e8b49545,ffef2577,644fda22,910b495c,7c01499d,3791b9f4,100a89f7,8e80b410,41fd34ee,68ce1f15,a8753032,e8965735) +,S(c4038e7d,76d2e7b0,86986395,2cbe2ce3,ecfb4b08,61423892,ac9b3b3f,6dc0c7e7,61bb3b0d,9efc9b7d,326a27ba,bc34fc8c,129460b,6642629e,72f20351,65e92f3b) +,S(7705a5e2,26a4d3ae,ee69c52f,5fc3f575,b9bdda08,70a19a8,8a525698,c3a25e5a,458e096c,f01906f8,c2426973,d1c6a982,44be9e02,22406207,3a883e4b,53c7a1b7) +,S(f3ce8bc3,5958b5e6,16a994fa,1fe0396,68a5f1f1,b464a875,9e4a3475,34ff48d0,9c1a1d97,be3ad78b,67c8c441,f7aec63f,8dc92aa0,87500d6b,222a2473,e10058fe) +,S(905ec120,de69cebd,b9a9d764,e01d6f88,3ebb94ad,af5685d7,6649e7f3,3ca4e0d0,92617e99,3974aa3a,774a75d0,e51c00ca,4d42ce12,d79ab0e9,3a8e449e,9ca9d554) +,S(b1b74a4d,a3578592,8bad0edc,3664c1e1,27d48447,fdb246b4,f15ada68,9b21eeed,c43539c7,b84e9e8f,bcce3823,1322c4d0,c14e4d90,33c4e132,8f5b26ea,9d3206d9) +,S(d440165,c72f2d46,b2fa2a47,1c42dab7,8dcf814d,12d3e025,bd5fb963,3d8bcf1,e0864950,261f5fac,e97ad9cf,fc7683df,fabab749,1d80422a,ca30721f,5343ae3e) +,S(ff524c4f,722c19a7,f7b910be,6d573a57,fe08d5af,6580aed1,de03f939,5053b303,fd4ad4e,5b25aa8b,b3a62dea,b320335b,5b9f1368,62f5f913,98fbaa61,b753bf0d) +,S(effde0bd,331c1083,e4b76a53,c9c1ba43,8fafa2b0,4a3ada44,63a5fef1,8d8d091e,fd7a869c,a75c2105,e6ae5420,86ccef0e,c563bddf,2b41ab9a,ee0e14c3,1d947dde) +,S(a5e746c0,99c8d99e,88b4a304,b583adb2,1115ba64,e409d278,f40c4571,2f3875e8,7f832112,c2af3830,2c4baba4,f073f7fe,84170939,dd9e8c07,fd2c1eef,2e934a68) +,S(6accb9e3,af5ee943,9d8daa72,2fe45513,7df5e274,486fa46a,1ba19093,32ccb431,f0de1658,842d6580,507c26a9,b68f92e5,a3faf108,1fcf5dc4,43ec9dc9,9f28dcae) +,S(c813d055,e40d32bf,6e8e782b,3ef85698,b86f3d31,ed0123ba,1ec8978a,f72b6d4e,baf6d757,2f924631,c4da4191,684c6280,47d37ef4,2bb9528d,28879011,8d068ca6) +,S(8b882012,2cadfc62,44fbaeb5,8be4d587,599dfae6,2fdf1177,38a844d,97c7aaf9,f5e6c293,ac900da4,f716e131,fa5a42a8,7867c8a4,76808b2d,4093c782,6f7a6a3) +,S(8f075050,f49ee582,b54a5acc,4ffaa443,bc02ff34,4d0717ee,9619d83,2d7310ce,13b901bb,7ab3d325,7cc555c4,a4799a3d,f1f9f9a8,6b7021c9,b99a1315,b5f7fd3f) +,S(bbc852f8,cf643e54,3c65fb1d,f2f72c97,89a456db,21c81f66,921d411f,b0374c58,ad08eabb,e7971e24,b2bf604c,fb248b3f,a27e1c2f,84f032cd,4c14bba2,b30a590b) +,S(2d77dc4b,662b55bb,878edddc,9dcc2dcb,9278cc,b1e549fc,ffa02503,1a80bc1f,288bb0d8,4fa7f2a1,ad1a62f4,e76ef6ee,c07707a0,89caffff,a8e60870,ecd058eb) +,S(bc83f71f,f3b4a86e,b9bdf7d9,94bba6c8,c90945ab,9c858b4f,fea7914a,d7ccbdf9,18e91fa3,e5067d23,809ed455,3d119541,fa3c2563,a3a88b30,20d3e49,4b232292) +,S(7d5b9657,8d9b88e6,b0e11b7e,847d0524,45f83dc0,e2bbb7b3,205db435,2c200919,1e689f7b,8830c10d,c28e7230,c569af4c,b1c9e672,aafd4d35,2faf5570,90515ba9) +,S(85e9f364,8d758688,31dbab4c,7460c4a1,51614887,cacc3cdc,1baf928a,200cdc80,7f4ce518,d5045c0,5865224c,c07f7fc3,5ba5e4f4,c03ffa9d,d5f8e5a1,31369e27) +,S(425390df,c1c094bd,34855816,dbbdb71a,9c1d1077,45b1c65d,a101d974,4acd0810,81f14cdd,20ef4d70,69026d94,f09de176,707547c3,8c0f27d,1e277d4f,1f49bc00) +,S(3cc7cf0b,66dc93ac,250d00bb,60a0f75a,dbb59409,bf8e4419,4cedaff6,413549d7,331a632f,c3dbd899,f688bcf9,9df70e66,ae17b719,a2beb23a,664c1d6,1c204a58) +,S(fd72088d,b8a1bce8,8fc923b,cff789d8,9d6a0b2a,2be3b5f0,17e2b3eb,ce70853d,d3912b23,a38819ba,eb329638,3a0bedd9,93db4aa8,df647494,b710dec9,9eaf599) +,S(3e558f8d,5e0096da,4d8940af,9a0baa25,c7318541,c7dd37a6,b72b35ac,efe65060,2a403d7f,69d805c,3ebbdb3e,fba95b87,f78f6431,7fec0dde,7695053d,e660e90a) +,S(70708223,f525f222,16c00149,fe1b745f,721ec32a,90fd0b01,e82f2049,d8694a7e,ef4ad787,f0b4d53f,19d86ac9,7d943b5,fce17d88,6366354b,410dabeb,efd12569) +,S(eca29625,eabffaf6,4b9eddb7,11e4cf76,440b4a94,def9d2fc,6e5e9114,aa414f72,f1f83875,75afa3fc,b23bb227,4c5890cf,f798b628,283989dc,d3538b8e,237618cf) +,S(5b7c4750,542df0c4,c4606db4,6861925a,da7423a5,66d6c108,77838f65,5f297695,42811366,1ae1889f,d6ccb1a2,4cd9a6a5,de04db2d,5e805079,5f922b9e,791f784d) +,S(af1a5fe6,40cb2ee,d36982dd,1e7882fe,bd5da168,8005838c,b379b986,bc012042,71570549,305fa634,a63d12ed,1fcfc8a2,5768778e,863d4778,b7e41215,ad3e6224) +,S(727443a2,46787e70,f83cd1be,1189c4cb,e1e8b18b,1d57746a,9a319676,9366b1d2,86357826,9bba3e89,a12565cc,1770e5b4,4df56ac0,d202fdea,d68928d0,6d16d540) +,S(967979,db34e62a,149e6835,213991f7,ae2c9a2b,abf3d255,6c5e198a,12640b8d,99dc1d4f,52445651,3cee44ac,3bf3d1ed,8547b827,251b3b01,4d4c07c1,fd9edcc4) +,S(794009db,8f3491e,27ef9d73,905b06b2,be56937d,be57b8b1,59dfb883,af203601,5a6ad64d,7ee5e1cd,15a6a087,289d86b4,5db60d24,243917e7,50eca61e,2ada40b6) +,S(87cbda39,6f90b090,dba9470b,1fb0dd1f,d2f4212f,50791511,cf6297e,a9851d10,9ca095f3,a2a4f997,501fb4c9,c5585dc7,fb8f7952,e11cd3e7,73a92005,a41b63f0) +,S(9ed57b03,475d1752,58c20772,1be7e12,cd1f3ada,5b95fa8,4b245b01,b910acb0,d58c9054,43bd81af,85c58a7b,d0cb3e8b,25310644,8e1ef50d,324eea36,a3bbd5eb) +,S(ef8d0a22,92ca4498,2dac77e3,86113363,35fd9521,fd266be7,d5d354e6,28b0402,e55c4b4a,556881da,a4a23e5b,677c1a9a,f2f547d2,e2b4037f,f9758a74,3cb58b6b) +,S(6dba21f5,a274f29d,502d369f,4fa4ed08,2299f6e1,b12f5c75,abd01597,d127e3d9,7685f72f,a0ce41e,8c4302de,3e6e9c81,c951f69d,d2df0f3c,930da77a,51a39d94) +,S(8cdc3ebf,857ac235,7dc1b0f4,26ed2a52,7841969b,7fb332aa,6ba44693,c8399a3d,234dd3c1,915ac714,6cd8724,9b68a19b,df250dab,2748abec,a5876fa4,b7f910ca) +,S(a00829c8,caa665b4,7e3391b6,f4706898,a9c790fa,29344de1,e88fd882,b5eca2da,b7c8fcc7,1e834cce,5884b129,98318254,23486297,6068eaa8,184b5316,fd424110) +,S(5872f762,446cbeb1,4a12e54a,1d4f22d6,a4ed5b2e,eff7c5f5,640801dd,2149ce6a,8aacd3e8,862757fa,1a70c29e,24364ef4,4c37d5d8,bbacde2a,c75a0c1c,28ee198f) +,S(b70ed5c0,5dba7150,f22677d2,e5b532cf,53e7ceac,919d3b2f,ec4cc6b9,2fd34f2,7e43f528,cc74171c,a2fcee0b,18d8fcb,76c3d69b,8560831,26bd4482,a4d28cf8) +,S(4beaa213,3c6161d0,c7da6d7c,8eb09cba,2e8ca505,a790a7d3,9d0c16b,8053bb52,da4c083c,9cbdda2e,c6626d8f,e4b2ee13,703496c,c298bffa,db1acdca,99d4f6d5) +,S(a8d31ec6,53ce1834,a78de363,c5f9abd1,8594b34,4d34f5fc,8a10e81f,5804831,b4d6a9cd,7cbbe370,9edb5601,cb7c8ba4,8c462c18,594a4bce,64f4c286,dac5cff9) +#endif +#if WINDOW_G > 14 +,S(a8f11586,f3df4945,a753c485,ee0fd4d,e410771d,bddc1b26,c9ff10e0,77b915b7,a4ad6f16,dbd741bc,71b2dfd2,dd2d340,3816bf73,4e73cc10,abcfa6bb,d0f161a4) +,S(13e697c3,812d4772,254082da,372892d4,e1a66e1a,eb16bbd4,f7a0d531,c979cb2,87fa7baa,f6def12d,31e42c14,f672c0d6,a9d0e2e1,ceee2546,d65bd01,c18df57f) +,S(3cae4590,821a9697,a5963269,b44f0222,98f60021,b6048b3f,49c6fd4d,8650c7a,e03f8745,60418449,ad97f28,41664745,349329d,268c1c43,86e25147,6e44b234) +,S(6f42f6b1,cb6bbe13,cf081480,766cbb36,9d2e63e,e691722e,ac81621c,66e0fccd,e5d8f8eb,67702ed9,e33c7b71,e3cd7b25,cc9cd315,314815b0,b67e8622,fd35f022) +,S(43d24bc8,469cfdb7,51ca7d82,98727059,6fac14e2,11d37041,370f3bec,90e411eb,2129d618,fb1f7030,9715b2ee,d8e70aad,8b172b74,425cd747,3a3fe40,d7c50dea) +,S(259170e1,d48b6f36,6a281592,3474f0de,434f4ccc,e45126e4,a15c503e,c1f8b97c,9ec06188,dc194bc2,be131217,bb862943,aa9cf36b,7703c45f,b1ffd282,c3c12549) +,S(18d547f0,426139b8,7837d1c1,ca0f5f06,883581b2,c001e8e7,2565c9fa,80fa2719,26d9dc3,e1145ccd,23ae36e0,5c133f6a,5ebaa9fd,bb954792,3e762a8a,9fb60260) +,S(23b5936b,f2dc961f,2fc93814,4c96232d,dceb477a,753253cf,1bf05713,1b9e58be,9b678070,1bd976e8,8d66e740,2c00bec8,e4fbdaf4,976289a4,4391b28d,45519b07) +,S(46de46fc,209df62,6185387,938724fb,702c3239,fcf29113,2807894d,148774f6,cdc2ab0b,5d37a348,1b44de55,d9c50ce5,4322f8be,6f284ed1,ee49f04b,65f4f2d8) +,S(d3b78208,f5876faa,c4d3c970,3a87a586,e897c11f,dca9a7cb,6573c814,9b5d5da9,112ecaec,9f4451ae,23485579,9cfee804,ee053df7,8e65713a,cd43d953,471863e1) +,S(52d51f46,ac86afc,391e6a1d,8ab1d862,2492ae18,b3e86f13,5e42fed9,4cf3735a,cea47627,e7eefa90,7b8bfd12,f3212ea0,bfaf9e00,f407bb4,8a86039,d4815215) +,S(46451d04,48f3f959,e133723e,b9138a73,b3877adf,f294ff15,6303a845,65a4c39a,fd1c4a00,bbd9aa06,afb14790,5c0530e1,d6c3b5da,c9001b9f,8ec76df3,c7bf3c76) +,S(a12f5e51,16c58aae,90d8532a,9182d54,f539014e,e2d8357e,5ac7854,26fc78db,3db94e9b,f37ced91,7c9f466d,2a6db2bb,21725e9f,f4dc1482,3e6e384a,265e0cad) +,S(98999fcc,38fe6b71,97ebfd61,fe8942dd,be944f98,6f139c4b,7bd6bd3,28ac250c,48adfd3e,c348281d,c23335bb,8702cf8,acbdfc84,9ee34a3a,14bf36ca,b7dd0ae8) +,S(8ac22420,f9b9aa05,705b31f,bdb57d05,218ad72,ce09b489,4d0b515b,4e5940a8,37a7e2ca,442b2446,686f91da,db6975b,6f63454,e3a96df3,de8c62a4,364d30b6) +,S(cd0804d7,b1aea00c,13a94a33,f75f3736,f5759080,96a2d418,c5b54c72,de31d619,c7f68576,10df1c38,6e677bb,dd6dc121,b3d9e9ca,e54d22bc,a5ce1184,a3dc755e) +,S(b6c4bde6,2f8fe3d7,3c32e641,573098c1,c559e847,e40f60c3,49d40050,49b0411e,62c691f1,68510458,3e5191b3,758d7e3a,b2cfa31e,7a00d7b,97e39f88,786f9a9) +,S(c20990dc,70134917,42cec766,8b725c26,d918cb46,6cbf7ebe,7b1f37bd,63d5df0a,6f1e71ce,e28b22e1,9c6f180a,4d7a48be,9fc696f4,cfd418d,134c1196,6e285d1f) +,S(ebf16672,45ac7f7,385b5356,dbf977a9,3602a11,40ada114,7face805,dd93f9fb,24b15faf,3b3ac9f9,833882db,b81a976,9a37e6ad,1a4228c9,a4f7d0aa,fcca3400) +,S(1c620657,63199ded,804deefc,c33822f9,cf3d4c1d,72f2022f,37714eb3,83367621,600221e1,48f74ad4,dae118d1,b6dca782,e00117d4,92881c23,b5a7cb79,86cad767) +,S(40b300d0,7520348,38bec63e,f155b527,286db841,754702d1,d512c183,345d492d,29305ffb,31b1feba,abe027b5,f432679c,e265a57a,3960b8b5,a66e6de9,5a10fee6) +,S(5768ffa5,c8b56772,1e10c2ea,421afef5,dfd84120,a8d40e13,751a895a,fccc6c2d,52ee5ce2,e60ec485,7ee62e81,fb2eb118,4d2a6ecf,d8ab7e09,dd728d16,5e508d30) +,S(d906e71a,b6bc6697,858c66d6,82aa85af,e8d80ced,5f470ac0,8158b5aa,4cabf2b7,c75ace8c,74552756,8cad89e2,201dd954,bc6f4ae6,3a671d2c,9bed78f6,40b7e70c) +,S(f71937e,f4553a81,a3f155d2,2f81a5b6,e080c0ac,bd8f5c5a,fd437960,6a63460d,d6e4e57d,422df901,e6292a28,c83c3bf4,136b5700,f6da0351,33099feb,f1228b19) +,S(3c498699,da858f1b,364c464f,b4317b76,5d085393,1c187888,83072cfb,39ee337c,cf3033a8,9749a0f4,fd4ad867,67b919a1,c946dc67,cc46524b,af5c0015,833daa0c) +,S(c416570e,cbc5576f,97090660,438dc3ec,be269c42,6e36fc44,45d53b0e,b2c5d54d,cf6380d8,76e20ce9,5cc181ac,4fdd42c4,b91d7132,d1b1c19c,4cc0db01,4ed782e) +,S(8f97b2bd,344fcf8,62846992,e826f5b6,7fe7d103,28f34231,8a9f7de9,20d71110,e296632,fe41f8cd,b3da3ca,e1c356a4,2424c649,11dcdd58,c21aa1f8,cee07ec0) +,S(6283f371,8e67e917,5b8c1bf,28e66bd8,470dc4a0,1a720a8f,cf1df325,fcb0e10f,5e80225c,87c0d6fe,3432db79,e8cf4365,8640ad4f,21efd2a4,333eb6ae,a46bd342) +,S(9e29c616,ba66db06,bb71e56a,2a049727,e07b83ff,cdbff6ab,898a73a2,f2f9d58d,b5997133,bdfa29e4,431494f2,8444f186,7c4fcc1a,516ca195,c8eb6fe3,f5693dfe) +,S(7a0db51d,56a2b33b,8ab33329,a1d41454,a30e34fc,3db33a31,45c1cb07,923ca061,334164ab,64cdd8fe,9a106f2d,156a16c1,5da4f07,fbd7f1ad,e9d1fd7a,c8630fc9) +,S(5994233c,13ba74ea,19c1c65a,c3653a6c,cef79c4b,bbb827af,e736545e,33ac05bc,2175bea7,3090437c,9af6f994,b33023b0,5fdb278d,c0c59063,eb3b805e,a6b6bf6e) +,S(11e13de,2371f715,4d15373d,d52c504e,50811146,10ebeaa3,f47a3335,ee4e17de,fa961827,b81e71fd,60696d97,17820d67,ec86e8b8,74d3d4bb,f50df644,61f738b2) +,S(787099cb,c8896328,dad08bca,4e682e4,90461574,29aaf740,23795a1a,47f25ccc,1ea5755,bd653ed,ee7ee8d0,b3e6214,df2e31d7,731a1c9e,47a95f46,8c3c8ac5) +,S(c644c88a,fa42bae1,27bec7d9,528cd695,7bf7d906,942baa4e,14ac960f,46469cd,9d7b39cd,22007b04,f61c5905,3a3b7614,81dd45a1,532d395c,baf8ffff,377f2644) +,S(79d1abe5,cdc8b0c4,9508a87d,46163d1f,ada43640,ca1a5e89,d2f1c07,8c58820a,465cdc,983f1be8,948b850e,a9a4d9bd,f3898781,65d5a186,1c94d3d0,3fb9289) +,S(e8d4fa8e,db2a1612,d7b6fd8c,d6aa2f1e,a8f1ba1,32572d6e,dd0826ce,bede0e55,92aa3d43,e944d032,afa03d23,dcdb4604,56cb0363,1fe2f8fc,404dd9f3,f832f065) +,S(6f99e75e,b09110e7,3d5e304f,bf569037,577554e,51861356,40c2c69f,4a92e88e,63b5bf05,c554aa30,261a09e3,b292b9ce,8f1bcbf0,ad91c35,aed04f31,567757bd) +,S(cb089170,d912f8ae,e59f21f8,8860c0d5,182b5252,3b2cdf35,b9795d1f,20c37815,4e8c5b3b,6d79cab9,9f2570de,8c58c34e,6b6f5e19,b285bc4,6988ac86,20e645b5) +,S(5c248793,51e487d3,af1b6d16,b25367fd,9d2b7185,9923c565,5d7567d8,ffd621f0,5806bb36,ac3cca86,2624401c,27c54e90,c76fc747,7e83e6f6,ac89f22,35c84211) +,S(f1d10f0a,2ce54b90,ee71ccdd,eb6dc4d4,c2cab0c9,5cd35bea,5f20d3b3,51d15896,7bdb4d3e,cc613f8a,8fb84d25,541970e0,6c7385e3,c04022d5,82e2efb8,4998eead) +,S(536a5966,b594b460,bd27b4f3,aea6b555,95940f06,311970a0,36dc0fa2,3a274519,c44b0b54,cdb4eb87,b5d70d9f,bfd4a601,5c34182a,31a882c9,880878,7910b3d4) +,S(7f8165ce,ed27a393,41d542e,ba9ae875,554265f6,1c1c56c6,cc0bbd66,2ff88686,6993724,26c18b1b,dd1207e2,f3bcc0b8,673f481a,e7638d5d,45134835,9b4e39d6) +,S(12214607,c610d012,83b9265b,c59d7458,4e0a79f6,8a4e8535,a72809fe,11a6830a,5d26e498,9e3edaf6,27cc4bb7,105ba8de,3344e506,d9bc9a33,8f1e3219,e473e609) +,S(9ad7f097,1d1c326b,8ac468ef,706f53a1,9e8fff25,8e599f0e,72acaa15,b21d58b7,2e7c0921,2199c7cb,da8d3645,a5bd7831,4234849c,41a238c2,a3dd7fad,fdb8a880) +,S(355f75a4,9df69d8e,4ccad41b,1fb0445f,619ba9aa,34697a5e,24ec8e92,f5b41068,9ca83421,4622ad8a,90a09469,d155bbec,717295ec,c071894c,6c91a7b6,e1345f24) +,S(bcde8058,8336a996,fa6af5bb,5ebf7441,ed3bda73,4802ab5d,5c0eac31,8017c706,49e40844,78cf1912,ddc91907,26411814,a782a3c1,452117c9,993d9e8b,4f247563) +,S(372cbbc3,3417320e,21ac4ba5,f286a9ed,273b6425,e8ed22b,d0c352e4,f0a97270,6e05363c,bbbd6b11,8f2842d1,243dd629,247e90d8,4e7c9d02,c3677f93,d1d01bca) +,S(a1122e8d,82e97ff6,ce9fd024,cd4ff32c,76aa0aac,c1c2849d,887240a7,a368e064,ef97035e,1df99943,1139cb88,e03bdcf0,8b3a5c86,d4b42d13,9b3acb12,e4e7df3d) +,S(e0101d71,1d0c7b60,8093997c,229bbbed,63b05224,53c0079a,518826f9,2bfc9d5c,a0acb9e9,c3d3d384,7f2d38bf,29da71c9,af0b5a41,5bf738fc,be24e367,c8db2fcc) +,S(6df3e575,4b62c92,41f8aba4,12804ddb,74ec864a,12076a34,d9cdf9ce,be336e8b,bc66fbf9,276fc85d,767c2155,ef481295,963cf371,c0ae6b48,50140d1f,c32f80d6) +,S(e5794801,97d3eb68,fd859d0a,a616912f,a2a52a7e,f3881969,626f43ae,4ac20586,3ba69743,176c43f7,7afdabef,a06eabf5,94b9d0ec,1114f352,7cb1b127,697a5275) +,S(7b290c31,de7dcb10,177313f1,9a15d751,c128bb2,16823c5d,69298baf,575657cc,9d3b3707,d8f2b17f,e14b6b1d,80c55d14,b747c3e0,8c79d55a,bb54809f,d96f99e2) +,S(4ce2adcc,18632b7a,560bfc3,beb7138d,8ab210de,6cc7f6cb,47171b45,13e991f7,5aa8204b,689d8f69,a42e08d,5ecd2936,97ba76b2,1bae122c,e9252659,25a874c6) +,S(dd798cc9,97530af7,d7ce96d1,a6a93aba,c29056db,c69eebca,f4649648,4942bcb3,e9ed537e,7b679852,88bab4bf,36ed677c,14db982c,9ce8714,b4f3a32b,56609e49) +,S(356f4414,9da655e7,c9ea5a3a,5c4847a9,f908c608,aa492efb,15e7cb00,8b065b79,2adb4e6a,ce059ee,44ee8962,b4aa8c71,a4d55f31,28f56877,6c70c4c7,19fa6332) +,S(b607a62b,c16ffea9,b30f61d9,c711adb1,d110c6b4,357b1e0b,dc71c8e9,4d06668b,6b933ae0,9ba42b06,96419a90,e6579a33,8f4f3fc7,5134abf,70cef838,efc5270e) +,S(77fec5c9,24fbca2f,f564bdc2,96ebbfdf,d52f0dfb,15011792,57085c0a,8fec498e,6c7729a7,c92a6626,44f33fd3,1ad5142a,b521720,24e31308,dc11f73c,ee29d69) +,S(804dd2d9,8014a95b,7fea2651,195585ac,acab7a46,1f3134ad,f2c4403b,3de98461,66fae33c,458de63b,dd04fce8,1c425938,dc13194c,ac03205a,c278c071,918a4e84) +,S(65866c36,90a6cf74,95ef54a4,f222bf9e,3ea803a8,98eebc19,2214133e,9ad35234,8cecbc5f,4a152864,6350711f,c4df57dd,8a2c44d,4133ec17,c95e00d8,b49c62ee) +,S(eaccdd6f,2a9616ed,d6f8c3dd,bcb04c1d,49f0c4c3,8d8c34fa,d47174f9,2323e15d,15a435eb,e23d23fb,2313b59e,2fe0367b,17b6d9d,e900332a,20430362,19c4591b) +,S(860d382,8ccde42e,b27652d1,c159d9db,57a0b9de,f290b071,e93e36aa,f730c53e,b4688879,ef616c7b,87bd37,641e0381,115dd487,d5fa3e87,99257afd,26906aeb) +,S(fe446d0e,8d174570,49394416,9c332f9c,eb47e70,3f214d83,2777398a,dc8189bd,d4cb299e,760ef11e,a3846dd3,9a49f34,4d5c10bd,ba66dccb,a43e3647,718e598d) +,S(e4e6bb03,528f913b,bc34d910,2a96385e,bd0b8aa9,a07a863f,9d5d41c7,b982a578,46ed6885,471b4806,aca3c265,d0c40535,4bd63da0,af35a89c,e8a86896,63d38690) +,S(12d69042,a5515732,8b729ba4,4fc3bac1,95c419f8,ec71f438,e676d722,4509bc56,80d7fe55,52e88a74,a87d24ea,de1f9e35,de5c45ea,b8a9b48,9e7a0b8,4bcf5d31) +,S(d3ab5380,1f1b1f7,36d94c4f,2af00a81,ee1815ed,83dafdb6,ef5189e4,13a32552,691c4594,657c0809,f7b6335f,fa4fddcf,8af5b729,9262f790,2ef12e34,f546a401) +,S(50bd549c,2da95051,7b4c72c3,67074539,412f3b4c,45ec69cf,aed0fe61,25b50d7b,147f8768,515cb545,2f291d4f,5a627f36,5c88b2b,d19457b0,1fa711fd,9bc71abc) +,S(a36bfbc2,330165f0,728578b9,ec81d14,c0417090,e6ed73ac,e8aff550,2ad9c62a,acb88155,5251f37e,f31aca05,bf33f9af,9ccc57df,58692067,4f11b787,8c7c9337) +,S(2be3d416,ca9627d5,9f259f0,1d52d915,9972f50,c391531d,70a6b79f,735e7413,fc0eaf6c,97d11c6b,cbc2722a,b3e821d5,363b04b8,edf2b700,15ce37f2,f70e51de) +,S(7ca7ca3,393a9884,c94430ad,20731f2b,7629203e,9c892d22,ae6df1a9,fa66aecb,c05c74b4,e2580f6b,9be6efd4,379b7631,26d3e0d6,d4e9925d,1a7f874c,fd620f43) +,S(6805c83e,19aad851,6fd7a4b7,e9bbb82e,28d9d0e7,1f1608f9,dcf37a71,3b434893,2313791b,8fc68b18,444cb309,9cadde98,f4c95ff9,88ddf601,ea3eacb5,bf1c1512) +,S(7540f073,3a358a90,80d2b07b,64e179e6,5de8010,6eed4eec,dc8c879a,87d007ab,998820f3,bac2fc51,48b0823a,d20b5f77,eb7acf5c,fb2e968d,2b98711,a1ef778c) +,S(6eb9b5ac,960407e4,465a0c22,8d98621e,47f169f7,61189aa8,f7de2fe8,79daa64a,6a32f21d,379c38e9,229ed85b,33b4a35b,9999281d,f96ecdc0,18d2482,67d85d54) +,S(e32d3fe0,80d92f46,58331d25,f0f2bbdd,43671885,98cda416,7b4920ff,afd5cae,61a8a2bc,aa82c5d1,1e958a0,fbfae374,138efec6,84ea8e18,af1d13b3,5388d1b4) +,S(22a0ca56,c95c5221,3ca126b,65e5382a,5f14d17c,976da5df,54942495,43415d70,4cfbb8e7,7e3f04c8,69e62ffc,edf23907,e8b17a48,13fc95d3,cf307e2,978e0bc6) +,S(ce3aeaf2,dceb0f4c,50120b90,fc027d7b,b5a4cddd,fc337e05,14298873,e3ff340d,49f2b65c,4a64b462,69e93c2f,ca6cdf14,b0c81982,b095ed3,644805c,cf333021) +,S(75251b27,b360b236,9c0cb297,c5f6ec1b,70f6afbd,5af1acfc,38bd765,9c9dd5bf,cd0559b3,9b18ceef,85c15189,fbd7a93,1ceb3f7f,6cc93d3d,7681f564,17f3f891) +,S(9d69e5b3,32a9ba92,17884f7,e7a1ab91,53a65c43,917c566a,c2969f50,accb9047,9ef330b9,d347c93d,a9441706,a502491d,55d27723,ac1138dc,751308ee,fc6b3a37) +,S(783ccac1,f7d6409f,758849b6,f7c4d5bc,401fe5f5,b08c2f84,1e0e3fc4,fd7a2d47,e5c62a27,65ea5ab8,6aa1aa00,9297d1fe,57248127,a5d3c36b,9665cd93,b6255f83) +,S(dffbb444,8362773f,e45e0272,eeb1a8b8,fefee1b5,59a6bb12,b9613fe,55ef33d4,fd539cf6,aacc930d,2ff104dd,405ae6e,e4a6b3ad,1a9a0038,f4ffb4ba,1a6115c5) +,S(cfc948b3,c14d06fd,c528d299,22305663,d7a427f2,fe08cc2d,942528d,dac8ebe3,81ab799e,5be02ce0,d3aece6f,c6ce84ae,988872fc,ab640d96,c3ea6bbf,3e2e709f) +,S(d9fb08fe,6a7cb6ce,721cca32,74e20732,5933595a,e59aa0d8,811008f5,cee83490,2c7f1287,8b6ad3b5,88cf9483,f08a92ca,ccc18ece,93c68297,4d80ae31,54965938) +,S(4272b558,49ef0ac2,d7830183,bfe3cc45,65ab9d9f,32b9366a,b0477d1,ae93956a,caa07aa5,d117616d,9f442b94,40549bd0,f64e7a2e,3cf96053,bd14faab,196c698b) +,S(69536c0d,6404b026,61598e11,1e6eaa4f,e50a2cfe,879b0f74,4df57727,933367fa,aeed065,2c5325a9,53913334,7e4fc4b0,d2583608,c2086bf6,b2e5ad25,261c6bfd) +,S(199589ed,5c4b6e24,65d58257,2fcfc194,60f7643b,7019c02f,8038d04,70368268,c48567e7,ef7a3507,14d1b479,1a70e7b0,5c1d4351,eabacd9a,1d8d5e80,a5da23c2) +,S(ef3c4f9e,53ed652b,f48feb4d,1c7b711f,5526dfaf,6588007d,1c2ce942,86db1f4,128e416d,570c3eff,d45da6a6,31246fc4,f45b7d2b,8cf85a93,22b5f65b,361fc49) +,S(6bc3a126,11ca8f8,3d0790c9,f5b5b137,4ce51c66,6c553ff6,9d103370,3b3d7cc4,b20988c9,4b882f50,a0ba8194,2f168bc8,f29eb6fc,4c3d0149,571968e4,81b76ab4) +,S(a0100574,5ea131b1,4c180c17,f26bd3c8,1bd48ca6,c2310c4d,34bad277,6bf51aab,177551d,299c9ca9,92de3e9e,f82b115e,6d3cea9c,fb276955,5509795e,4870a546) +,S(15553b6b,defdbee,532599ab,9e0de23,b4954dcc,912f49e8,f084ebb5,af6088e5,8dbaf203,351a1119,16e8aeb2,e5eeaade,b0ee5d9c,2f5020,62b9f5cc,ca40cbf5) +,S(ae84a42d,49dad25f,f0a5320b,d6a33f8d,79c9f2c7,2871f41e,f8b02cc2,c469452a,9b23f07a,234782b1,cfa524b1,ad539ea7,b8fac3cd,e9bfb867,799a2587,95a48ca8) +,S(eecfc7a7,a41f75dd,43e2b85b,5af33ad5,f017e0d4,8f9b9bee,f0cf4499,a3c762d0,65526d26,73b9e5b2,8ec256bc,a524e376,f0e40f62,2db6e492,e1c53820,a3180d11) +,S(35e427f6,d0be7dc1,2d306ecf,be9fd8ff,107a044f,81c38c8c,5b9a181d,f4565440,de09eefd,27a8bb89,d8fc38e8,d32aecb,5c6bdc57,5cdf91ca,2f18e926,dfcca94e) +,S(d27cec9d,11130024,7f71fadd,4ace1139,cbe3168d,174c93d,4c756c42,89cef3da,5747fbf8,c4040895,fded5c00,e1f60403,40e07827,8924ca96,2f83b3f,e50ed701) +,S(df30926a,ca9062bd,7bbef9d9,e312a1cc,49442ebd,9994b93f,dc652e68,25efe5b9,8d1ffe08,de113447,5c3adb77,ee5aa58c,593486f9,c3f27c32,a20df570,6ff5c572) +,S(c2602b7b,56d0eb73,ab494934,5eb77e88,787e54c,79558ea3,dafe3f50,84f96682,45885bf4,65996b12,993efe44,39861b39,84d5fa89,5242ea8,f498695,57391182) +,S(d6d606e6,28c55e08,61a37803,72c17b1,6a2fe04b,e68a0cc7,60fdf7ac,85c8816c,76b299fb,9e716eed,7f09c879,ea8256bc,a953454e,490edabe,c90a2e5,dd277da8) +,S(d1bb671a,10ec5393,9d67f6aa,3b09e1b,57bb6414,e1f707dc,b832ff67,56289c4,47559cac,311f20cd,55760ed6,2e1e87ac,cd8603e4,c1d0cba9,79f6802,6b294a94) +,S(739ab4bd,6b6132f8,2659fcda,5fb46836,7adf2133,37f897fd,70a9552e,786dcb91,b562e798,2bf508ba,1b932deb,3e6b5962,70bba4ca,402db3b4,d806da6e,fbf6670d) +,S(a710cd7b,2aef0005,6d8db954,2abe6cba,2a6c6132,a48a6670,c501fa82,4de21388,4a6037d1,87db5b52,2996bb0e,47fc7509,1ad9eda8,e15faa56,92d56006,e72fb220) +,S(cdbf59c9,b38e40cc,d63b36b8,b6e894a,c6baa22a,93a1382c,9d7fd070,58e69b7a,3e836c78,6954d509,348314df,8ce08f0b,59967aef,4e5f0136,9c6d0f91,2682d77) +,S(1d32e93f,6e5e138e,7d226636,d5e0946b,8117f91b,bd59efb1,560a15bc,657e4dd3,82c43daa,bc1e23d6,3632e167,6bbca422,9797551f,f729cb5d,c8ac1460,46ed20f7) +,S(2730066,cbe72e84,304e3563,a18689a1,c6c8e0b3,e92d8c0,d63a96c7,e3573337,8804d5cc,6aa91f7a,1ae23506,17332f7d,811b8f1f,752fea43,5208b770,94e67c58) +,S(44624ea,a1607e8b,8bcbd736,9c67f86e,6b0f5226,4cc76a3d,b40042cd,bc621cc4,95867a99,d110d9d9,e382d3d8,a5dff78c,d8db012a,972a87ae,ac24bb42,b2747e53) +,S(8ba805d8,864774eb,4494ca5b,f8257bf6,980466f8,30028340,8aafd665,7f1ef49e,1a1164e3,c1b243cc,57507b07,7348495,95cf67c7,b40d4d7f,f10ad096,3f3866b4) +,S(297d0130,25bdd2d3,f4a008d0,d8c51a3c,7b16b605,95958d9e,93e427a8,7ac01267,56361e70,22138026,683b7bf3,1a6bedaa,988d3938,cf8399aa,e0f3175e,61d7e2bc) +,S(d866bb84,23527208,e66f34bc,e26a8ac0,daea9d03,27c9dccd,cdf0e2a,a0588f52,5e16262d,3564736f,30f26e68,1c5ea26a,b6f63429,f0b25dd2,5635a3b3,1fc45584) +,S(ab1e9d8e,b18e016c,d8ec49e4,388636d,5dd2ab55,8b3dbaa2,433a976a,ad8f16a2,a14cbcec,6327451b,15d47fac,d3f3cbbe,fef828c4,6ea07a0a,9c7155cf,2a2f291c) +,S(cf2f035a,ce393efd,3032cb05,4f4e92ae,5311dd04,bf8f3653,5197748d,2094cd30,75b38e90,9f02bb50,7a778243,35a1c97d,75bc653f,c6dcffcf,615bf8c2,ec6b32f5) +,S(a801d552,e63ba120,2c3ff08b,8fb025df,e545ed35,1adf00f,1a08d982,9e8bf9bd,bdb9274d,f5298fab,4cb08f42,252639e4,a24b553e,892cd1ea,93499c47,41c23165) +,S(f7ad7a63,eb2b90aa,3de2a80e,844e5336,287984f0,6075d9f1,26f24108,f4a5869b,d151e7d,9766a81,1db45134,7cc22654,c5ac40f4,a1d82d96,2de02c58,d46cda31) +,S(732541be,26fcc3e8,c824d539,28282611,96717b00,2af01bc8,57f4c0ac,cded0a80,d44adf28,f26370a8,3c9eee24,4e870dab,3fa7a508,bd14a56f,17c9a845,5055f8ca) +,S(892ee5f2,a5266a86,5bf2094,14c31225,b92dffda,7a3ec00c,ee53dc0b,8c3a3367,21bef833,3b983665,7d243b85,c0b4e2cb,6a5b339d,831cfef5,d676c7d8,87a0df00) +,S(1a4597e3,77569fed,70875f9b,f8f5531e,6bd3b363,b96a345f,9275365c,e1e64424,bd142738,fff7b9db,cbff1c,93a968b1,f0ef3e63,8279b745,21aa53a7,6e611f7a) +,S(c7306404,4b4a3a00,6a584193,e915a174,631c8a2e,ac45973,c815a2f4,aee82f35,280adb29,4f9642cc,cbcc4345,28bacdc5,74beb7df,84c06216,68cc2fec,d78731e6) +,S(c06d9d55,264e4ea9,e160fa78,78a7e4fb,1757f6db,fe610966,503ae03,b4723f2e,c0d82600,ae072564,b29373a1,ff1a036a,45f68f22,9d1594ad,1c9584cc,ab732743) +,S(e878c0b2,bf38b500,6c309a51,5121a3c4,5b13440d,74ff6e27,5bfe71d7,51e6926a,4b8be149,11432ff6,c5169731,1c1db30b,c921cc95,b4c98a39,5228c08,b99b6229) +,S(d1f6621f,89ac4421,7ef39a54,a0922c77,dc7addf4,78b15796,2558ae72,9b24f65e,657556fe,e02492c1,97c9c97a,67bf1d6c,eb689415,80a1ce6a,1e4d98d9,64902f3a) +,S(f9199ae3,ae51f441,d88d72d6,9c1ff64a,d5cc4979,b5fd6a23,c514e9b4,66ea0a5a,3c484bb8,8ec31009,eb95b971,69c7ae03,c20dd833,eef53cdf,fdab8cd5,7a82d4eb) +,S(4e059bc7,516d5fe2,510ae63,d3ca9543,f840bff5,710a744d,62de3965,af6a657f,222309ca,242c5858,5a792045,bbfb3e55,b61daa3c,afedd1ee,19a0038b,f929a47) +,S(c1673413,d8b4298f,6ca04741,a3c32d79,83a7d5b3,dd39ada2,53013d3c,9750ac65,333b1660,7b998e8e,fa7e3d32,2d51c052,1de24d3e,9e389f0e,9a00015d,6cc32d54) +,S(c078723d,8abfbc03,63f12766,cf9c6261,9c31173,5f3a9654,b653a8f9,e08f551c,880fa5d0,be09cb8e,4f145749,1c7f54e1,ceef1477,ba7ed718,5f27013e,32deb89) +,S(c77f3351,4b44b047,3835e3ff,abe8d7ac,ae5f912d,aea4e6e0,4ed03feb,78c41ce5,cade531d,26ee668b,5e2fc7ce,421de2f,d9a14dfb,87286c22,c840144e,1290e910) +,S(90e14c45,4ba40739,10f800b2,bcc7b017,ec58660,bdb1e72,16cc6afb,8320277e,61dfb75d,f5f74d47,287f828d,c4ff46d7,fa351a1f,66da99da,40e74758,2c6bd4b2) +,S(34c65f34,23f2474b,7e2f294c,ed4da6b5,c05d19ef,a2b5a792,103b681a,be1a3f68,d0fba1a3,b12d3e4e,f18acdbc,68fc285b,8ef1365,6aa900c8,c86ae191,37f028ee) +,S(fdcc63b0,aa5017ce,215735cc,2802eee6,aa5ef53a,6a258dd7,a128ed7b,9a5df38d,217ea863,5c9b88c7,19c7f9e6,1286844b,d4f4b758,81535954,7b24df0,1fd5bf03) +,S(10624260,58bb9f6,a5e83740,59595ffd,e7013492,4392c753,15853f4d,9c7070f8,84a92509,e809874f,86e60bdf,85c75d7f,2cab596e,185f56d9,262b06e4,e79cf785) +,S(e21f29c6,70cfc7e8,b104921,bb524414,53acdc5f,fd80066,39417966,ca235c9d,41be8bdb,969ddd53,9093dc1,b85dbd4c,a78f7e68,67fa916c,36136d24,b6c4af38) +,S(154a85d8,60b532cc,16bfdcb2,2769fdf3,6dac818e,cd2daeb0,864eee0c,f78a5c5b,15f2dfc9,3e5e08e4,9d340ce4,bb805afd,79f940dc,f97456eb,c73b47ea,5098e429) +,S(ae6f8b12,d52907e8,4ae5063a,114f8e2a,da7be317,454ea505,571f2132,5e4acf42,49376af9,1aea68bd,cdcd637a,909b639c,b7ff8800,ee003fe6,540d6797,f0f296d1) +,S(de42ac26,47fece4e,69341582,7e3c5b7d,a19dbbd6,22da9fa8,58a3be29,8a47bb65,e57cc346,b83b33cb,79a34805,42811d1d,4178805b,a2b88de6,d90b4fe0,ba8e2740) +,S(14c2030a,c65ec50d,2f7c176c,45256587,59cae0d6,55cd57c2,c1ea970a,11d7bd0e,f3d9f0f0,5881801c,ad4df439,3a3bd2df,1a045181,af7ccbe6,7500b02f,61edece) +,S(32fd40e4,7a94e51b,e4c927c1,42b5f470,b2abd2b6,2773934c,a29a5ff3,924b2e8,b3d74958,f17147e5,1da38ded,7cb09c27,96b7e36c,3149d85c,9b7db85,acd89bbd) +,S(fe468154,cef5383,4820fa33,ad85c158,33635cb4,a55870fb,f588fa6,b8d2918c,96650453,25235606,7bcbc214,b0a04021,bc71c9c5,4617b1be,dd34e6cb,dbb42873) +,S(57826e08,8fa3841d,a33ad3da,e5b5a688,1ee770f5,bfe45f5d,507b4801,ccb511d9,6cb01dc4,4da6d83e,77a6e8a6,d374275e,7d8484fb,4863b5f0,34bace60,30e6b3be) +,S(61bf08fb,1d537624,1dca6119,19f0dfcc,7787090a,6747cdff,8757b037,a1ea59ae,6bcc632a,f4f43c6b,547e6ac5,5854268f,1801614e,5bc9d4e6,ea0dcd99,79f7adb1) +,S(f54dac2c,b5521855,9dc274ce,25b77645,6525e91b,c011e657,5ff812e8,d846ea4a,bb9734dd,af492c18,82bd36fb,f365009,bd41b8bf,1378d9c6,a18477b9,ed627f11) +,S(640ebea4,b85cafa0,d5a38ef7,7373bfb1,36b9571e,f9694724,680e92fb,13efe03e,eaf8d756,c70ee813,60dadfd9,702f660b,516fe3a8,4c50043,92bc7c1b,892a43ac) +,S(6c4814d1,e3c6c16c,366c8776,93b6df4e,266b45a4,26fb0d5b,a2d8fef3,a3803975,d9330c82,8fb02d63,33d57990,b6bedffa,ccd143d5,1b5eac78,5c7f058f,af77a37c) +,S(8dca10b5,95293452,7bd2f264,6170b6fd,59d636a1,f2578b6f,cbde0c96,8bb2db30,50da6972,64516689,57d2273e,55dd046f,1c398d1b,9e5e864d,ae6746fb,825ec83b) +,S(1409a8cc,34389c3d,3fd1b482,fefdb25,3ba32070,dc23b7ae,6b8a1ac0,2f00b776,f8f1c0c6,3bef8011,27ffaf53,d5c07c,430566e2,6c4a9591,f92d694f,82d7a9f8) +,S(1c752b3a,2cdb6257,fe8bb102,e7560b8c,6f86e7ca,e809892f,58df3b16,728c0999,9f1341ca,61dd07f8,882596fd,12531577,d09fcb45,5a086b0d,17dd5390,8326c741) +,S(ae8bb1ae,a4341bf4,c18e7d99,7bc3ebb3,d9f13c9f,b01b93f,885cb32f,d0586999,92eaf2f5,c4e231a6,851a2324,a146400e,6b9eaf63,8eca473b,9d4e034a,3d5c8e6b) +,S(e3d2429b,ba45b4c,2d9c9bed,45f384a1,7d74cd28,56c87772,6d9a98fe,67bcef97,729da85f,927c04e2,c1db1458,c133bdef,c454d0d8,88262b1f,418f3420,5df2380c) +,S(858ee23b,e5166c66,b99d48dd,24cb5078,fcad23e4,a8df9f91,53ffcab2,fb8624b,c5088132,3af436fd,c4f63b91,b06061d4,b26fadd4,6bccaf05,bbe1a8b7,338cdbf2) +,S(7c6a82f0,e2d6c5a3,ba37be0e,1bd8d4e1,99f9aa3e,c9c58054,a66099b9,a4938a1e,881916a7,87e1f9eb,b38906c,c101b0e6,5d245fb7,733c0093,9a7f6f0a,9b4d113b) +,S(4c980c4c,144e4060,c00e7476,c782cb83,42ae8b02,6a155904,c29837b9,fc25caf2,fbc05490,a62e49f5,6daac9dd,5c730f90,183ee565,d62ca949,5bc7ce56,61c2e8c1) +,S(c9b66a8f,6c163037,f5bbc7b9,889e9cfc,357ed5f7,a5e5cd17,6a7e4bd9,6da2fa3e,4eb8b3e5,365a6a44,4b277b4e,89b89e04,2b44cbf8,b73f183d,42c9d8b6,547885d3) +,S(f2f8fb3e,2bd3cd82,99e2faaf,bd5809f0,12190658,b1efa389,f58ffe28,c1056fbe,db6c4cac,35f78015,8fed40c4,341a93b5,64af02c0,12d4817c,478726fe,4faf8273) +,S(8556c286,895b9402,283b5d2,f90ec950,f91c4dbd,6c1c8a0d,6b27cb8c,3bc7da8f,f2979daa,81ea79b5,d3ee2718,4aff3805,9bce1bb7,fa36cc53,4d139b83,c176badf) +,S(4d4c2752,5f24a7d3,ec3673b6,a3c8f110,f5bb5c5f,e9675776,3d81620,90579267,43ee95e6,5834075a,83675a88,15babeb9,824d4703,763b5b09,8c3aff78,837b353c) +,S(cc6689e1,d08b243c,a49a7020,b08ce4ad,817193c7,456fbf4a,97fca02d,f1ccf2e6,32f00dd1,1080c238,cc7e8c9c,60a1b7dd,7503417,2ad0464e,1cdb4221,35ea580d) +,S(966525b9,26bb6596,584cbb3,5da78cec,e6709134,700974f2,6cff34a1,23fba535,b5c18347,52894cc5,26336590,d961af5d,2453d9a3,40bd151d,259d8be7,6c5a9e7b) +,S(df7f51dd,b0e6c595,c8f3de9e,eed5da8b,b05e2cf9,a4555001,760888e6,38b11c4d,19759148,2d4f49cc,b69ef50c,a1cbf3a2,49e3958a,aa9af2c7,becbb72b,8d53f8e2) +,S(4ac2754f,93745ef5,61d6d213,7fd2339a,81cfb619,b6699d9d,21897ed,975f6fea,854a0153,17ce38ef,e070da13,c07829f2,1bf50d40,6458109b,5700a3ec,ed6a3c0) +,S(7c062917,2c59c7ef,2d488806,b1131193,b6b6f0e0,221d1ebb,eca1b358,43959694,77f73272,291c1c73,5d79857d,60cc9db6,b6128e86,4613b3dc,92dd970b,d5dba9ff) +,S(c80152f1,e4b7728a,36acf22,158b8215,d8ce0ea7,401274a2,1139dd71,59d81557,dc0c54e9,88d2ee7d,e8a56eab,d358aaaa,4542a45b,a170db58,89d634f1,dae95df5) +,S(9c2352fa,464cd430,31f43578,53feaddf,7d5ee143,c6403ea1,230961b6,377423c6,841277d5,71934bc0,20f71b36,dcba2293,65819fa2,b20c57b3,5774a524,d6fb20d8) +,S(8d7554f5,fcaae19,cbc20c7b,73f22f30,aaeba42c,a22bef77,3d780205,8c8e1d7a,c6bfa4c0,9db5101,d33abd0c,47c4e125,bffab86b,8ed50864,6b6a2b0f,322bf5d2) +,S(1e75acec,28a2ce98,5929479d,e0842826,bd556b56,6961d5db,66c9055f,b1b63635,89cbe475,d2036dbc,9227db67,d62b51e9,ac669a22,76e4e1e9,d0be9b1d,58efca6d) +,S(9fe62187,5e71bed4,7d9f2d79,91e76b41,88b2c8c6,10f20d33,5b38bed2,eee85236,9a3fe290,fbe192f4,8a44177d,4f0d037a,fc6fa8b1,c57032b1,3d5894c8,c426e8cd) +,S(8dc1710f,8869b645,73c361d1,ada3f43f,6f2c175e,b24ec358,6409e978,1687a220,37a4187e,bce1845,9520b60,9317a4b8,f33b371f,1a768ba1,96316f41,373ec87) +,S(71ad2a17,5cf75568,214fbbd1,f177c1a9,9eb75486,c161f1b7,ad47063b,567e8d6a,29d80786,e42d9cd,4c801f96,a7d44eda,5e325acf,3b82e143,2576ff1a,3b334850) +,S(be0eeb11,aaab9c1c,ef7a2004,731e3ca4,435c8a02,548b36b2,db68ea4a,56ad8b7a,cd7ad5,c9b7e867,1a1c7889,95e45cff,bcdfe42a,6222e0c4,1054a0f5,f7bb00f2) +,S(364154a1,3a7d9fa0,b349c6fb,ec36ea43,51cdabfd,8fa79318,88e4ea5d,ee8bf6d4,40b40474,7e8b30a6,a3cdf3ba,f0956fa5,f7f61a2f,89a8cf7e,c2ed7445,504a71ee) +,S(19daf7ab,c9f69a31,8b2cf1c6,69d50532,5bbd7254,c4bc4126,d7b31dcd,e7b558f1,6b740772,606874b6,5b1f819c,c7339ffa,30669d9b,2770506c,e9fb243c,6ee4a925) +,S(5ab3dc00,eb9efd03,ae491844,50fe176b,765c5da7,d95ffe6f,61aa0073,7366c918,2603f1ce,935e3af8,af5e3d1d,d76a3410,200037c,87c17a93,96e11018,260dfa01) +,S(47bc2c3,d7dd83f7,2b2160a2,64640e58,16316d0e,3272abf4,b859dd0f,6c7b27d7,1ceefb1f,23dc61a7,2f663d9c,3cdd6625,441a63f9,f9cae8d5,c4ba88d1,22c0f258) +,S(b220435e,e903f1bf,3b443549,5a01e739,250be2c1,43f08a73,bd7dbfcd,75602ab5,3659abe7,953b817f,fd1c02b6,56da4e54,9df250c0,7c28e9c0,89ba315a,bf25e1dd) +,S(be25604b,d52413fe,2c743031,98aeff78,c27086f8,97fe4b20,be5b6251,52fa2fb4,ebdb5191,aa195ee,a0a39bf7,399bbe03,76073830,fe54cccb,a3194eef,d8d34fe5) +,S(5cedfbfd,633f16f7,8ec8a8f,3dad7cc6,edc1a6bf,3e37cf3,65069731,64aad0e3,70e687a9,d8632ed6,ab188f14,229f2e31,34a3adc8,727c7b0a,d7a16d78,1244c9a9) +,S(8109ca32,a86fa712,690315e2,1bc09265,bb6bae74,588f507,1bedebac,47e54a3a,e7f3342c,6e8a3dd1,f6d02bf7,5610511f,d0cffb40,1c14633d,308c2939,e662cbf2) +,S(54264a0f,dfb894a6,b29b6922,b859d715,77f0359,ef825442,e0d43b79,a0fbfe3e,4884ea59,cb88fb60,4ca4de66,110b7d98,ec529112,d4574cbe,9a2e7a5e,5a4a644d) +,S(f2756955,a6a7db9f,eabaae3c,844cfd37,5d86ad8b,a84dcfba,582bf4a,273f90f3,b24c14a7,d2f60103,a7d3652b,c5e68988,390c0e67,1f0fca22,ed927f6c,96302239) +,S(351da3e,6ab7c98e,840d0dfa,e7231d21,ca21a81b,3638371a,673892d2,e40498b9,e1c5ffeb,43b443ab,d31332bf,aa314fda,5a4c2634,afccfb97,67bceb3f,13ed5f3b) +,S(b5107be0,90f84c7a,e3d89782,c6751b22,f9a7ad2b,3a1810c8,f14bdd8d,52344357,3d5571d2,36a7c9a1,aada0835,9e8ce162,c46a878,5e09265d,bb52b419,144c5b6c) +,S(b6172135,85b2557b,7c253189,9422c428,79825eaf,64d8e8e2,2f7bae12,31c9ceb7,dbfe3609,df9b8e1a,33629219,eb241daf,42d8be2d,b9a20a0d,942f24ce,1a117e3b) +,S(5eeaaf7f,577b445d,13481c9d,a567825c,f0a5a3f2,9ccfbbbf,d8f1f8a5,36e712cf,84a4352d,c40556ff,ab75acd3,b5a63366,39119d8b,f814feb,e55fb3ee,dea5821c) +,S(c1bec874,44b0210a,9a86ca9b,94891d00,e1fee6c7,490aa26a,1af61f97,5dad1c13,14a61af6,d280ea47,433d795,1786351d,f90a9879,7678781a,8d9d8884,e88a06a6) +,S(34787098,f0df9eb5,e4825449,6fd7eb6b,3118dd45,aa0ccea9,f606a794,126b9ad3,85c30ff1,c8dbde4b,88fe9ff8,20c9908a,a35a0c53,c2175524,a5929eea,5566a564) +,S(6599b07b,5d31c19e,ee02e287,ccaa1bce,70890b14,cd739140,6f1d862b,39d794a6,d18396df,27e6fc21,a9c36a1,8d8f73ef,c79e6c56,ecbab9cb,83750220,a816d5ff) +,S(27b50b15,c92c010c,60feb473,5ac6ae0f,9ec0af75,81e41a90,a3a940da,a1a44ee8,31c2c3c8,61e64b7c,df8ca011,bd4002ba,5373ec63,8c3608fd,619bbb92,3552c1b5) +,S(40aed5af,953f3a17,f5d17622,127f16bd,4cc5bbee,33e23443,5f49c4f7,a48e7a32,e47011ee,96c702a1,1eff428d,2940ddab,d17b76cc,6765d5ed,126876ea,2496f6e6) +,S(cb56977d,f69956da,cf40909b,69fe44c1,4a5ad547,a025d684,c9815ff1,b5331ef8,9904de7a,9ce0f656,2f025ffc,79e8b3a4,2e410ad5,8f0caa16,62a13e29,f0b00bd2) +,S(11dc40ff,58c6d2a5,9768a776,41c611a8,2aa651c1,15e9d36c,bd3ebd18,ac7a0df9,4717af95,274f820,28592bc7,4a84e467,9d168dfd,826a292,5789edf4,a06e0e50) +,S(3baee366,3d2033a7,f3170bd0,723eded9,2fad6501,702fa530,b26d0623,8d6992d0,47497025,41900ac2,fb236a26,81ca09db,c34fc84e,98ca289b,63e07d17,2e4671f4) +,S(6b19e8e6,b2010e2b,d461d716,66f691ea,88417df6,773208f5,18ee5fb1,e0fb580,a7c74380,9f744b05,99b6c4e4,709a8b86,241ef931,effd9323,9a6d15f7,22916578) +,S(412a2c52,b31158ab,9d3bf4ac,d4355eab,b7e94e98,6a839681,94a7322c,72bff9f8,c649c493,b19b713c,8b3c4e30,567547ab,472a599e,cc95ea73,d36d373d,c92f7dc1) +,S(b5e0c57b,f79e7364,9826a818,bed1d521,3cb88645,5dc91a4,eb157a8a,dd869c24,752feebe,9614e233,3b876297,175078fe,f9adc63a,4639242,6c88ca94,aa06163c) +,S(f656ab08,9e75bac0,6eaaf373,1cc71347,6a636347,35ab57c0,222589b1,e914160f,d05493f3,52b660e0,4cb00b45,5cede6b1,74337488,dd1650c8,4ddeaeee,b73a6ae9) +,S(bd2465b7,b5af290d,2d1157fa,76e4550c,ddb23922,7d30c255,8f0cc3ad,ae5fa32a,63a28c79,cbb50c21,bcfc85ab,269090ea,d56f6396,1fcc6dfe,b3a000e7,3284880a) +,S(d53c8d24,3dc3600d,fa32dd69,11a87ab,722108e4,192d7cec,4d84eefb,9b32a351,af681092,6afda47a,ef5bc91d,97f273ab,78a21c01,64f59c0c,ed66f7a8,5b67ca24) +,S(4a83ae18,ab379d5e,f6cd2be,77f64abf,8fc23b52,edc88ea4,9efc1bfe,402432c9,e9eef9c2,f595ad74,abf10b85,6ea24ac5,603d46de,c320f9d9,a1453be3,92eef8a6) +,S(d1df4416,dc7cce22,832f9ab0,b74d927b,f9b3b7a5,c52acee5,3d95812f,f26caa82,9e5242f1,163a863a,a5702af3,cdc21f7d,b0143f76,ddba2a2d,d592676c,57c310f) +,S(e6add3b2,583addd7,8299fd2b,14b87155,93dcb13a,3231458d,ab6864ce,87b9c890,384bb2a0,930ecde4,1e9945f6,247a6530,58e26bf6,88226c8f,ee9a1ec7,a1f07740) +,S(7d3f5447,295479f2,96c11443,eb9b1fbd,fe81a258,78ce4195,d2f01290,7e01fe4,d12e4fd7,9f66a45b,2596b066,651d8686,83e62627,95f681a4,12022046,86304ac5) +,S(60636a7,45442fa9,57f21668,7fbdde4e,a6f7f80a,ea2832e,ca3ea43b,d1f12709,395ef963,bec2979c,fb211f8b,da3f4b4f,2c129ce8,26a35367,d955243d,3b40022b) +,S(6bce0837,39c04ba6,b9dbba8c,f668bea9,4d8a8b38,2ac17b87,765bdd52,86e47963,a2d85e2a,7ff5c433,c2c77363,666ddd3f,3fb28f8b,2b7aea1,16a8f42e,384a0a37) +,S(59e4e7e4,438ceba0,cad5f146,bc127c1c,df7f4735,f581a0b2,6a53a366,947d4581,32207f5,95fa4cee,3c8ea269,9578b28b,6290a3c,33eb0ba7,e3bf7267,b2bfa445) +,S(ae2cb18,d4f053ea,3a497162,8c822f6d,72806f79,bd39dcc8,364ea256,f30af032,583d363,b9ac6fd2,709985c5,79603d9,4902da04,1563879d,245433d0,abc54a1) +,S(bc4eb578,630ebde0,f58fb192,377de006,c630e96a,51219379,43e9a240,c30951f7,5224d403,4635eea8,e63b9e87,2875f27a,129de5ff,fae3d516,5f6d0cfb,5bb7e584) +,S(848ca19,6fc34e2c,e484f74d,79565ba6,9685128e,7b2d21fe,8cf0e4b1,edbd3b13,2a41e449,532de110,e0d3fbb2,bb794fb9,32d0d4a6,33aa65f8,ec40e5bd,5c4314ef) +,S(b90e1d09,4257ae30,bd12debe,648d4cea,3f063740,e3f9d3fb,c67eaa4b,8ca0bcfd,5604b475,31b28a6a,e0a13a47,31f6cc70,de91d429,d2204d45,e1423652,5a5a4b43) +,S(430752bc,3e1191f3,6e084f2,5f3e30b,da104f40,1de93267,62dde1cc,39d94c71,e707daaf,841f62f5,6d9c45fd,3304e616,30b6af9c,d6871476,6132e127,40f5ebe0) +,S(ab919243,c8bd75b9,d67f331a,b3b487e0,ee9c97ff,c35de7b7,e29827c1,ab643be2,d4d853b0,3971f1fc,ce365db9,cf4a54f1,5e6059c3,c5138b2e,dd765c51,7bdc0c7d) +,S(adce8be3,2277c2cf,6ee46781,f1da8f30,1cafea51,18322adf,8d6b8a29,fc3f7551,e819a7fe,73311592,bcfda0a7,3609748e,6c039066,feba9e5d,41e125e8,4dd67fb4) +,S(d6ed759d,15f5d47a,146e7fac,423b952a,5eabc238,a0382762,c2a226ed,8c24b601,456caee9,1c212f19,acdc2d82,9eb90cb0,2ac35a72,8d280042,658af65a,b6840e9e) +,S(3583bc8f,c3ca09c6,6f2f4fe2,83da5c47,f0ebcccb,fe8e94ab,fd315173,fd3fb2be,ed60aa95,504e9b31,81225d0c,a4f513c6,6da2a2ce,9fa9afaa,c12e04c4,f1d50b59) +,S(223879b3,b9e50b46,7bceda29,905d09be,1acb206,5b23a61c,686d6f39,bf0744d4,a8326789,ddb38afb,e993ae33,6cb1c3f7,92addfad,e47663fa,52a296a3,b6f2873f) +,S(29329ca6,c6ce20b5,81a90873,7206d44a,95ff382f,1ca0cafb,755a3450,83883d69,5d2aa87f,59e13a0a,8ca4460a,4db7f496,1c118ab9,b4f783e1,305bf43,ed44fe71) +,S(e1c6a08c,593454a4,aa116edf,13345cdf,6dc00b1d,b63b7a64,fdea70bf,e4301ea,e0f9f3ff,5e7e395c,42b3e093,87b8363d,37092335,31c317d8,1b61f20d,f06fa662) +,S(da098bf4,133f656d,f2a09d95,c437eaed,fadb4c9,8102d164,b355c7c9,38e65216,74ffa0cb,1fe7f0af,8a1a6ed0,531f8e98,28be1110,90b580dc,5ff55fe7,b75d9b66) +,S(f3f7c27d,54b40dec,5b3da04,b2cd222e,1507aa70,bd236bd4,2d6e5c95,c71bbe7c,80e17f04,7cb2203c,cc58c364,d77e9a1c,8abb092c,18a9f8d5,6edcdaf6,1ae4062e) +,S(466b6e28,8981fbcc,92c4ec3a,a54eae4e,2e266041,5b242aa5,523579b5,b1fe93cd,9ae0e0c7,d056b2a6,831f540c,67a97732,33bedbd5,bdcd2904,2a8987cf,1fe2a86f) +,S(e15af336,8c59576c,a36b5f80,d9ec0458,d9534bf2,6650cc26,a2079946,ac43fcce,7fe0423,e6ea121b,308d167b,ada98cc2,fb8cd772,f95c3d84,c1907f09,66e5b46c) +,S(c20ab235,6dfe247,d8fd1a9c,d8c4f16d,a5322bff,692efe70,f256521d,1b990492,3c0aae11,e4cf9a17,57feb324,e1a2f0e,48d5978c,6007429d,ab32b2f4,d1a19bd6) +,S(d8b6c190,4a848755,f126651c,d96fe374,7c5a3744,1fb7048f,e15c4693,dbe35e17,fefb5310,e7e38891,70fca6ec,61ffd2d3,72605ed3,4bd22d73,c852a92c,c22fd30f) +,S(a8256823,5416b18,a01d2df0,f47757d0,f42c26e3,780ae6ca,2421aef3,83361f8f,c9192412,77948b80,87d1c45c,a95224ae,5f9c294d,fa74c1ec,42ad6004,f8646540) +,S(28f2a237,c4dcad5b,a6bb5274,1e743020,e90bc598,8ee66b39,cd672ed2,ccac6c33,416c59f6,c1b1b036,f38a5523,722954eb,52848872,8ecfac4b,5bfea63d,cfc181db) +,S(e65d92b7,571bbea5,4e541862,a4dc7890,bd546782,bca886e8,3c1ea17f,33d77e9f,6116ed43,13def2ae,6b0f2b92,ff07c91f,4139982c,12511152,fd7ed5fd,851bd04e) +,S(68adb9ee,c7ae0198,726b0457,91fe52b4,b5c2ec78,4199da86,bceac230,d55914b5,41ff0808,e42aae9f,e93ff704,6f08fb38,4b72d7ec,7b1dc6cc,e0071306,7ee5cfd5) +,S(3f0f7d6e,6bf73a97,40eb842a,35cd4800,85db4766,f7fc374e,1ac915c0,e4d6d6e2,392aecf6,8b446346,2d37a106,8299a09d,9ceeeaa4,f0ee3397,dc54b2f3,5e3332d6) +,S(929aa2ad,48a1f3a0,24fbf7ea,70e9d57b,9ef65afc,b3cb2d8c,5041a933,321359e4,b1cfddf3,4693ff40,ef16d8f1,8fd1fec,a71252cf,ee13ba4a,16094c20,3b4fbf66) +,S(9a9ff691,f16ad46a,d0b753a6,fb09025b,e196b443,839114a9,580eb2e7,fc494e2a,3776f83b,92c135f2,5e5e600,27f65e2d,582fa2cb,f5842c3f,644fb726,1e305c67) +,S(6752b226,65900d81,47ea6b73,25b212a2,9bcf899,799eb1e6,213857dc,6959d32e,fafdac9c,2f791be2,d1cfa78b,7530859d,c1b2ff43,e546de14,1f42baef,3d6d1371) +,S(9fc32749,e636e845,aebfede1,1d0928a1,8cc6e3b4,5a2536a9,fae0a2b,ddca6434,9021fa85,56c5fe05,cc87bdd3,6cebb00b,3d1b77e1,80ce2f8a,a4d155ee,84fc6441) +,S(60ca338f,ff905b58,b1d70d5f,89c4cebe,15600495,698b262b,e1550da,a0054a99,6d57de6b,f7c637ac,4d728090,9960ce01,4b541abe,754b82c,bfc87ad1,5fbe6ede) +,S(91537a09,697d3658,b06b853,d07153da,6d0228f0,786f334,db6151c,64becb87,231a2595,e04dadb4,b3900188,9f34b43d,5cd3c81c,f13fc6df,d432a377,4f53015) +,S(93a85356,195e109d,ddf054d1,2a901d83,b10db692,fc17e878,849eecfa,5d387fff,58f2112c,3df38b46,51e347fa,5aa8569a,48d95b2,670c76ba,d0de339a,72ee87e4) +,S(d5d1f0ac,bc2ed1f,50490030,43fd020d,7a1afb27,cdf78318,6a043bef,b0708eec,c473908d,4d754fe2,a5fdea86,62a6ad21,b711560d,77ad85d4,e3b47175,b5133e52) +,S(afe283d3,8cbb257c,5f2c0dde,2fd1bd56,2ad33e5e,605c24be,51a255ec,5725b1bf,a050f64e,978a9ee6,36885656,5cf22d7c,2fb45e64,6df60abf,6d3f9e1,132311a7) +,S(179667a1,72e0c37f,33e835d9,b5b6f326,3d963f37,1dd07d40,e790e0a1,21765180,da24290e,e38be6aa,ea2e86e6,bf683d4d,90f5fb79,20257b78,aee8be4d,fa65eea1) +,S(9add8ed2,6feeca4c,d3e583f0,88398ecc,f245d30,a888e135,b86ac1a7,e4e42d05,41bcd07c,c2e6acef,bc488d74,8a338c9a,7e6d3e43,85029f75,63dcde83,54d82232) +,S(25ba1237,6bb6e146,5195db78,29f51889,869dc972,fc9805d3,f6dfabb8,bce6b,a39dfc2d,223f924,47ae617d,537a4877,e6a47e0a,7e5fdbca,e1bfc956,a9c42571) +,S(dbd78620,c9a75ddf,55d0a41f,7312ec44,d3108f34,e7d75195,d3d49f99,88e2f986,c184bf06,ef304b72,1637bd3a,d511dc92,297dd5f5,9bd8d053,a048702a,fdbc400f) +,S(f8d67c64,b71d14af,b07d734f,675913cb,7a1bebc1,6e4a4916,44f8f4f4,6eb69448,eda6023e,5df40a5c,89a7bd26,94767a5,f17042ad,f95fb4f2,88bf9fdd,b91b280f) +,S(fd5f3228,56c096d3,4683a672,64ca5d76,58a8b7bd,41c3c1f2,5de2e6b3,164c8fd7,8372223f,3fab4f89,f6604b16,dd66db85,b8a27eaf,30741bd3,7a90d34f,f19c154a) +,S(ea49d0e1,b07948b8,b122d52f,8e8be6c6,e470262e,1c239b40,483a6076,c005136,b81ee77d,3d8489ab,42a9978,48a2ba17,273517fa,604a2abd,f2e1e726,d71b7e19) +,S(bab8ce82,c1210a99,ce17a5cf,3636baa5,52cc793f,89fd25bc,b6f078c3,92149bc8,afe2bb15,d00cf460,953a7c1c,8e466556,136ebd4e,ebf61a76,e49726f1,e3aa8e73) +,S(98802d2e,225bcdc7,9e02e746,891cdf12,ac434154,c08c2e78,589dd9f4,27277e1e,1eeb6b5c,4fc6459f,28e3fc49,6d9a6baa,fc66ede0,85d4b0d7,4af45840,78987514) +,S(5dc54290,2b33fd65,7d37a22c,c669ff21,75825cad,b34e1ee4,7aecf7f5,2dfd750a,41fb96de,60564df7,6c8ec857,d7f0ceda,2b330fda,2195a70f,5f64f973,ec0144d6) +,S(c4894f07,f6679f4e,13369495,dd501aca,73666303,2f7bab6c,fb81d7a9,1495834e,31b7e5c0,35e81c22,89de373f,85d648dd,892021e7,1d120742,e4ac6af2,44a25a8d) +,S(f7c9950c,d5c5afda,ede613bb,8f21ca15,b0e92487,81e16378,c7f2cba,5efd7beb,1746037c,b9211262,f0867180,16f0fed1,75debbb9,5eca39df,ed757c02,aa282d24) +,S(96703c67,4e7e2859,f274e7f8,d458f7a2,89ac0bc4,961ef3bb,b120a1e1,b82b5a55,1f92a15e,5e8b476a,a165823e,59da387f,2f9ab551,4703010c,c35b787d,c7d8ddf) +,S(4e8fa83b,bf9307a7,8b997e49,68227e86,a0402f0,643f98bc,5d13837b,63d08156,81f1f92,bb2a9ca8,14cd212a,6de7ebe9,7a04ed97,4de89e5f,cd8749ba,6e49e4ea) +,S(bc239122,b0cb1f43,2ed0c2ec,bb3c5391,b7eebafc,c4190fc5,8f62d313,7f58c1bd,5b3cd401,d9cf971a,6b9f70a4,b6f8fab2,d0026a24,cceaea2,a86aef0e,a76a3cfa) +,S(90b7138d,5d2e11b2,86d29b78,521aa9d7,205351f0,1451e134,8a593b78,fe5f1778,77cdd3f5,829af7d9,937ac98f,58a78b99,b54fe9d7,593415f2,18dde880,b5039a37) +,S(631d0fd3,27bca9a6,aec8eff9,54fdde7b,df43edb7,b1f602fd,a32c387,825841e7,d6e8af71,273702a3,a2a767af,3c438f0,b07ab614,2fd0f67d,74a9d358,74e29100) +,S(ac2a0153,d810371c,6a7bc097,ed09be67,14ae9935,4a9910ad,7ee77ab9,6d54cdee,39707795,a4f01640,87b5e149,2ec8fc1e,be11d8f7,c43555ac,6f4674fb,8ac5b0b0) +,S(89751ec3,c1aeb288,1953d3d3,f2f634ee,29b1aa18,c55b8b62,59d5cadc,852ac99e,8b4d51e7,e2f94c0e,ef80e16d,9b62c935,2ac91394,902537f1,e93744c9,72f22a3) +,S(849a6cfe,5e3ab81,2e21f491,4c6ec76b,5233d405,7ffd487d,bb0b5091,2ac499d2,a490b967,b5fcea21,d0135ec3,c9ed5efe,ecf7ac6c,81e06648,66cdca60,a1be7037) +,S(4ffa897e,17d760e,41859b6f,3bfc421c,55fa1e31,eb999f72,5028be41,cc8a9ed,87b4b5ab,d9875b94,aebe632c,64ea441c,71ec7353,5ae2c83b,d9b904e3,7f7fd326) +,S(4fda56c3,8bae34b6,55b2ed2b,621e5074,7ed1dc13,a1a815f3,be12a223,d54c43c6,6cfaa7b3,c53a1dfd,a03dc7eb,6086b84f,ac280c55,7c357d16,fa5938cb,c149bb10) +,S(b572c9c7,9ecd2ee3,154c56a5,9c81444c,b16df1f7,82198eb7,40a78c7a,e5c7e99,a1fb603e,42d3ac6a,5ef5dd74,ced31624,fed9086,5b02b3c9,2bbad21a,ffb1b79a) +,S(a77038c8,e79abb7e,a94b4e17,35f0f5fd,a07b1ad3,367047f4,895a5104,dfeaa623,e9bef9db,e8e2078b,346aee0e,efd64657,2210e451,ed2e8d63,b92be059,c577e1ea) +,S(3158f3e1,14de5071,c6e2bff9,32f1c269,7e374dbb,786e960b,7e59df03,26e2e1c9,1d0e950a,9124a626,4553d29,3e5cb8cd,9dd05d45,f48de2ba,f60fcee0,ca42a9cd) +,S(b0825b69,373aad7b,53c256c3,1258169f,2736d47b,1c4aa22d,a052b864,375a807c,23ec01bf,a857fa0,1f3d46f8,7857b211,f7533c9d,611dfdf7,951d190a,d7ef07db) +,S(9578e6e2,1a738f66,ca04647c,ec610da1,afc5602b,1e72e096,bd192ed,f19c205c,fb5da982,7208b4e6,11e6dc5d,dd8b8ba3,569a578f,275e6d21,3417fd37,7e4e6cae) +,S(a0aa979a,5448d27b,e42c39e2,2fcdf40e,d3b64c74,42b2c40e,2f6d38ff,fabb196d,7a9bf938,937be244,38aa212,d9342f98,ab9a35dc,1361fe56,5d04a25f,176eaff9) +,S(f535145c,d57aca97,f4cef68b,ce57d5fb,62ccd1ea,b48dfeb1,3b87b188,4614be82,1323e73b,dcd6b16f,bc481294,198d8235,b98a1885,a336f07d,593e5df3,a21ccc11) +,S(587d9e30,2f9d60ed,eeae03ca,252cd2fb,117bd07,fc91163d,a7cc569d,1b023f9f,7bcd5b42,3c01038c,9d3f7f71,ef52b4ef,a99e4be1,6de4314a,5e517e8a,950f45d5) +,S(b1e3b70,aa8a0cab,ec119ca0,5430396,ed98d9f9,e3e1a650,94cbd985,4cbd0932,3c9496c8,eec7dd92,9718f7a2,8c7a67b5,c4e55d88,5a943cc0,deefbd11,fa4f8de2) +,S(8f7001e2,928200d3,a478ba12,424be4c8,de8f16f2,a932e000,1468d9a0,48d57816,bedb10ab,72eacf26,1ab17a34,e5138686,34995952,545129b5,5bd6c7cd,84b50bc3) +,S(c95bae04,e1c397e1,498822f7,b7910019,922e43de,83119ae4,8517aa9b,aad6f35,8fff7d3c,d8bd7af6,c8523375,84f73aa,2f1b03c6,585c7987,98fe29aa,36620486) +,S(228fba21,ffe5ff9c,e04017e2,7cf04c71,1cc454d4,534d3404,49bbd1c9,60d2230d,825fb4a9,169ab67f,50963731,10f27fc3,f6f7acbc,9f2918f,c6f0bfa8,a92ed32e) +,S(89610875,bb7c5f53,87929e38,22249817,ade80ed2,a69dec5a,eee31a48,6c40e316,f7d5f522,92a53c2a,447f9b6a,5c06b3f,22fcf19e,4a200ef0,9167c255,a373ef47) +,S(9f0542f8,8e7e2b4b,c20b7b5b,87f051af,6650f605,67dca77b,7b6e1ccb,2a63f6e8,2b80c840,5e343203,d0a7d1cc,ccc99736,4bfa10d0,6e71880d,a0955cc0,b1ff98a2) +,S(859b6ce5,b7075222,549b59bd,3de967b2,1655d163,c57e94e5,6c9fae12,e5222061,25b8cf47,baba2000,19036027,fc86f03a,1c4c406c,4a8b2c34,398b7191,bf125aa6) +,S(e6febd1c,91e66c5d,afc7caaf,4150a023,b70c57fe,2a14f84b,c9fabce7,34982ddd,b606e3cc,f997b627,a0a02c4c,e147e0ef,58e3e275,a43940a3,4ac74760,457ae5e5) +,S(956912,ea1f5ce3,52d39e67,a41e4ec5,8c7106e0,4552e1a0,48e4b195,6cff8c01,b1eb2fe7,7419c11f,f7e34dfd,a752064,39fa2e6f,b9f9d34f,70740950,cee3cf40) +,S(1bca39eb,9b6a5d5,3575e510,6955143d,a6fe9d67,999500,ea78cb89,d832ddba,47afc8c9,358e5f7f,e92370d1,44ecac99,4e69afbf,6ef1af7a,32adefb7,9331173f) +,S(2c6db85b,c4d84c2e,61f0b5c6,2f330e7e,dd672c63,a14fa534,9e4d1488,ad462c5c,bb488565,cb2da5c9,be8a6f6,c71555bd,d85b4a53,20ca0753,f524f91e,ca1e331d) +,S(f66c0d73,36bc153c,5f85e297,52845255,8957a08b,603e4d3c,746e0c19,572c9f82,74e32022,faa58df3,1e4a02b6,f00ce5e7,bf34ec93,d8095144,a1af69f9,c637f01a) +,S(774959ef,cf8c126a,67012f8,10217d39,298040ad,da97e973,9fe13f9,927f6757,c33b9f7d,b2901f8f,171151c5,dd8b890b,62c0a1c1,9b7d4691,9c23ed00,cdafdc24) +,S(f59361a5,74b69786,f7ea4abe,44eef2f4,5000328d,dd72c2d5,a6dce9b8,63037ca6,34deb360,ece45bb0,a2417618,e7c67adb,24b33620,80d464af,a1ef20ae,35da05b) +,S(add233d,31c179da,bb62567d,2a5bc5d7,9afc5c50,93dc8196,9767ccf3,8790a5a0,b9ecd675,13d81a64,8ca5ab2f,4d580d3f,7f7d4def,909f2759,af61e497,b6d8f82e) +,S(3d204b0d,1d705714,7e947150,52a531bd,b6749743,5c94c7f4,8f821579,170fa257,ae20862b,cd86c6d8,e8344911,cfa8914d,f40e3a80,b762fd54,e2b7f704,4de86017) +,S(22be58e5,1c5ce0e2,f1ee6f5e,523a2f55,e110c4b7,bd3135d2,39d7a25a,94bc13f4,56894dfd,6c2cb7c8,5689cf04,3c1d4221,a7dfdfd0,d05b1e68,cc41afb6,6a472a04) +,S(6e015fb9,af8ec2d3,9f101509,f8f1fc9c,d95dcf57,82621ead,4651a062,c8487687,c7dc43db,d1d068da,9cb751fe,51251bf8,7f6edbc0,bb19925a,bc02cf6d,d7cf8554) +,S(3baa1e60,42844786,fb720758,67ec526c,2e0f7fab,ac8e0eca,24eff876,47720c2b,909d202a,b40037e,9afe2ef4,d8638491,d27a1d24,98e497a0,908a52c1,52b1f8da) +,S(689cad9b,2cde514,b9c25275,d6a3e68a,ce0b2216,4418a403,a83d88a2,4dc4d25f,53e7be29,165632b1,d1887aab,94c525f7,86166f32,56b44e70,295dd0d8,bb9f22f0) +,S(c1cc4802,101d0251,76875033,ed9fcc07,a66a57a7,71ca1374,63d7c7b,655fdb6b,ffa73601,5dc4ccf6,8afc41e8,e254501,93eb75a1,60a98c,6c800d0c,f10edc5a) +,S(888e34,86eef22e,2a25aaec,9bc9b84d,fec14fa4,c98e9d57,4fb9e08f,5b0f76a2,d2e3ec7c,db9286b4,b0223762,234d771f,a5b6f378,b6a4bbb3,c94c3303,af49b4f3) +,S(ab355f17,a43d24dc,330a9195,c2be2ed5,6894a9d,e38d3dd1,1a31f9d9,9ca88a93,7f8f8748,c07cfbd9,fce0ac7c,b624f2d0,f83bc49a,53276b00,7ca2b821,51988e6e) +,S(12a65c28,aa2020c6,5f56d916,c1cd111,10f68f0c,2408863e,635e05f0,1dbe4141,48bbab23,1be95484,7a0b61d3,89913ff4,5a8b97bc,384a0780,294d97d3,9c9b9be2) +,S(9d96107c,591d95b,42854234,1371290b,370640d4,2dca9fb,5f5397db,84a5577e,183fa1b1,cda4719e,869c8b44,e97cf214,3ab14e5d,e5d0d781,78e5d68a,923b3dc4) +,S(7ad05c26,aa642731,9eded7a,43f72faa,d344ef4,d413d884,67bea154,4459ad55,cbd8ea0,7fcbda54,813f990b,a6eb8450,6faa12d1,cd478a9b,cc278a32,511ba8f9) +,S(d1ddaa71,27959090,65ea358f,b887e4b0,894028bd,457d217,f1ef6b9d,143a2292,e040cd3,d5f19cc0,456a55a3,88ccb81f,787eae9e,51a289cd,d8ae8d25,881e6ed2) +,S(ec3bc5da,a9be90e5,1af0c1a2,bf41adfa,8023bb4f,b40e65d1,c65a0e82,6bdc30a6,d4962737,f9df1f4,48df1d9c,d8f7a140,233c2175,5d8ef5c6,f292b230,9ce263cf) +,S(f3135904,dc55f515,806dbecf,d51b8106,f13dd1d3,43f78e05,91de1f94,86fd193f,c5bd3002,24934faa,2f9ec634,53fcb3a8,20af608e,efbeb963,23871faf,a7dc2246) +,S(fb5f135f,b2f7638f,36bc332e,1bbd2050,335c141a,49db5452,619f266f,df85e8f9,6e71e045,827c3ef1,b75bffd2,ce54361,1e627cca,c94c8d3c,9b8fff62,e10b7b6) +,S(d1dc12ca,62a1285,e3c16125,f71a1b7,7b0dfa9d,c1068ba,2bb56bf3,98864620,6a6bda82,232af467,afaecb2d,f4a7ca53,3c41d63,d8f7093b,f04a2964,6e4f19e0) +,S(52354730,2d24cb39,f9117e35,d9374ea8,f3b6d027,cfcc23b7,58f0bc1d,b4f2d94,83719f2a,ccc79c43,1d8ea584,c78dd5f8,daded80a,fc3341f2,5789181b,7671d586) +,S(fd8247d,d208839f,93eebd97,f6068ae8,a6640a46,48c16b65,6bc992b8,4ccfc5e6,dd560b93,9b530bf9,a8bfd5f9,614f498a,49e54061,61107517,e9ab0104,54e42f3f) +,S(da5d83a1,9254990a,c14af844,df04bcb9,accab655,5468d08f,3b5d93b8,425f1600,9e5a8786,6be51fe3,54bc2412,6315f8de,1f0113cb,ae78b72f,cc70572c,d978fba6) +,S(1205f8ce,b9c89dce,13cd44f4,9ef0b2e8,14b78639,372d9f61,f0543f54,bdef2944,6c820a46,afd1dd98,499636d6,afc34ae8,218a8c90,2f210dbe,530a9211,a058768a) +,S(7d94e0f3,3969c5c8,164739ff,11aa05e0,45b32702,333d947f,8a0cbb80,57dd3c71,7b92b367,33f92723,17948d9c,a1875303,865fd47c,ecab145d,9ac9d4c9,864d62bb) +,S(d7f22ab5,6840dd87,d939c4ae,3bbe5a67,75e7a2c6,dc969a96,40c7f65a,9c18b2d8,bfc60718,2509244,b0ab951b,f4032852,54b73d5,a23a19a0,b4ccff25,1e5dbd6a) +,S(cee33146,2accf4fa,5f06b598,cc36aa06,342c83d7,eb4b6aff,90b9555b,fee0fe61,97583a48,5c323459,ef4b3f02,bf63f9bc,315cdf91,6163b389,c6a48cf7,4127da34) +,S(1e1d2d64,1ec550e1,1a29bc03,cf7c8442,ca13f10a,182783c0,d4ee9bf0,8c3c8a18,1ca8ff62,fadef98a,4d1faa0d,28e75e5f,117cd890,2934e457,e042b870,d8cff1bb) +,S(f10b2e75,8246bf49,1b70ff95,a385e701,dbbf333a,95a94652,6df7cb7a,4b4cb68f,ad15b5a4,d39d6458,55e57a65,3872d9d7,5f4b3168,182bdee0,a6289f68,aa7f99af) +,S(4674dd8f,16ba5557,c9ef32a0,2b6be805,e864e7af,c4fecb8f,666cf396,f7e6b0a7,c9d95120,73388bfd,45f702ac,8851b5b7,531edbe2,df04d855,7bd58b3a,c889f48a) +,S(95bb741,da472f82,8ff1f98,970c2bc9,1dcaa4ff,2cd4c0eb,195978b3,242c66f5,1e097cf6,d47dbdfa,8c3f2ce,90e0ccde,5adbd581,9a6e135,957ce258,805a4130) +,S(9a892056,42e03fae,b24d8fe0,f94e4f6f,d0c72581,604a65a0,99e3d28b,b103d2dd,c6bee4e0,d94c30de,b99c1a21,5d28d7cf,930e89a0,7865ea1c,87d39f5e,1522b33a) +,S(ade39c3b,e9540095,2176bb09,20541076,dac8e68a,a20903b1,5048e5db,4b0539a4,6bec56bd,60596cb5,7ea8a355,a6a6a4bc,90871c81,de902b0,6abd45d2,5802b204) +,S(45f808f8,bab4b4e1,a790240a,f036516f,bf0a8eaa,dd4dede1,eb88bbb0,7d248b8b,3f3bc72f,bced768d,bb90ddef,5b1baa9d,aba634f,1fe19842,c3b4b456,8957794a) +,S(ac9aa903,845a3081,2ddb195d,d79ffb6b,6e8ef0e,d34d0a5,49b577ca,35a116be,368ddbfd,1c5a2fa,c2c183af,19097414,82b272d0,52cec4b1,745fba6b,4a9fba89) +,S(ba26fbbc,ffa6b9f3,584f18ca,255da089,f561c30f,29a378e2,9f76de9e,b756f6b6,55f67b11,81ff78c4,c4c86e7c,931e314f,dffb392,306a7145,5efe875b,fbe39ba3) +,S(d4b1a902,1ebed925,9d53f2e,d76b03d,25b4241e,d5f932d3,a54c4dd5,db3f0423,6f1dda69,9e60053f,d9d2f5c2,c2ed2ae8,ba3337a9,b669ba05,3e48d974,f73c2d93) +,S(bc91d139,b2de4778,458ca891,fa97e413,d4cf32b1,753cfe0e,540726c4,648b451e,b56454c3,4f568840,6d198248,19ba350e,aa291f16,5676d7c9,fbd2d592,169c76e7) +,S(cd7a85ca,a0f408b,26b29306,3e01dee4,acaa8f9b,36f7273f,378290f,a4435450,1d9508b,1e7f5bc7,ba8fe5d4,f44e8c57,2bff9a98,887c3ef5,2fba3057,f132c5c5) +,S(497f8e85,57880856,32edbfec,b0065ac8,3267fc31,da9100ce,c2b99cba,1e7c26f6,e6729428,fabdec3,2db731bb,f33cf45e,5001b890,8f82c0fe,f7cac291,f89c6a46) +,S(68a607,4065c372,a95e7a6d,fc742e32,e59cc4b,86f9127f,f9465474,a466e30d,58e59131,1cfff974,e9e9162e,e974de92,904ffaf6,ffb97f49,d9dbb1ca,bfd927e) +,S(79d2dba1,67b93ef8,82ca60ef,b803e1a6,eadb4406,7f9dbf6b,d45c1a72,23da19b2,a59f1b7d,9ca146bf,93b89f2e,244dbf00,31511075,4dc03050,aabf0d20,41230ad0) +,S(5a2802ac,f4b92bf8,1c98c431,28ebe1f9,c921c211,910b6648,6391ca0e,4c6ad50c,5a0d7b4d,49b5835,dc3b395c,83031571,f7c361dd,840b41d0,405db351,14d86eaf) +,S(87b8a84b,1fd98b53,e9eede06,74555c7d,806d5b7f,4cfced4,16203280,18c398d5,a38c4d7d,549bd5d,28fa39e9,805e81bb,975cd137,64aa8c7c,a7055d63,bdec52f2) +,S(f7ca4d9e,7ac11395,70db6a06,c7f00833,5982181a,6642846,5d0899bd,907a9223,2c3dcce1,2ee6a995,52a72eee,e0968552,919502,5d4962c5,a33035d4,501badda) +,S(15bf39e1,5a11ff6d,216c0f7f,f1597f7e,ceeeda34,91b450f5,3b3407cc,bf7ced7d,325462a,6591d018,e495c6f3,fedb3abd,75d5a4f,15e9ab99,e43418cc,4aef1ecc) +,S(2755adc5,e69db19d,7caf52ee,117c6907,5b342e73,4af64a4c,77b369d4,269897b0,199bbefa,7e0b1c10,bd78ead,d5e65a6c,e6b3ee49,1400b9ad,a7874bcc,be580d5) +,S(96ef0e89,80602225,1d8bb9e8,693f3a67,5152cc9c,43c4e953,5310b9f2,c4338d8c,2414e799,14b2d6e2,a9be60ed,52508d6c,15765c0a,7fc1746,8820fb99,a9feed56) +,S(c1642d67,339fa6dc,c553233f,116f8086,2edbfc24,5512c2bd,4ca6e348,712bfb19,65e9a14,c7356a36,625022cf,873161b8,ef43ce38,a99586cb,9b5c8189,f3c6b8dc) +,S(54c536b3,cb6da9b7,e4483ce5,d5c9e660,bf973ef2,f4c8b095,f52dfbed,ffdfb96e,777f16c3,b026b75a,c9863f38,d015f04d,e1067f2a,a9cbd15f,9ee27475,ad46a4b7) +,S(706041aa,63dee9bd,4a441238,bd343bef,14e69929,f6e007e,181ae87a,68362926,36e15a44,57b86f4d,9b233dd3,37fab91f,67e4c811,3340463f,8f443b50,5a0ba014) +,S(49acc336,116c91af,6f90a6a2,d69b9d3d,c0be0a16,afb9830c,c1af0b5e,749b2765,bc4f0f6c,725e037e,3a9d9be6,c5d4f80d,67b3e28b,92e5d3a8,fbc8f66d,9ba97d52) +,S(96bee384,ff79ed86,a9d816cf,32f3d569,d1ae03d2,d154c65e,a117707d,74c818b1,848e45ec,27eaad75,5328d84c,a76a7235,ef4f492f,5be115a,a622171b,51dbac8e) +,S(3b2b0810,c4052498,189affe0,4c7ebce7,b9050aa4,6a702d0f,72c5c770,4ca4d1ec,f782ad72,1bec3b8d,b1df97d4,7765434f,e4145c81,27acece3,9dbba604,4df2543f) +,S(54c3547d,e4873721,df6215fb,ef7bcb4b,b9acce42,7b0381cf,2de151f7,c69549f0,5e7ce1b,728a3b21,e94b4138,bcb89af,f4778dba,fd21aa42,16d83a7c,9ae81edf) +,S(9f1c53de,e7b895d5,6081585a,c6eb3821,d89bfa61,55cc96d2,e8b6c472,edf57f27,38369e41,ecbdb4ac,619aa7da,4d708eaf,4c572ed7,f1f2c079,d0bd17d5,3ba8288f) +,S(e79f75e,a1a224c2,a0533936,65a5f705,15eb0aed,b924dfbb,5aa30055,d1d82b44,30c65139,f6a6f5ee,5304334b,1ce9dd15,27ba6031,2ff2697b,8eebbdab,67105171) +,S(7f95a1da,79cf25cd,a904b7f3,11674d02,fc6dbf34,ae8ba7e0,b179b48a,d942821a,3d3dd8bb,31cbafd3,247ddceb,be1faeb3,b00e057f,7e90bd1a,78f89cdf,648f7c8e) +,S(41e83f7b,9067a7c3,bb6ec755,ab7c83a4,dff74c93,65d0259c,cb635bea,718a416a,a54a4b56,5286b26b,d0bec338,2053c349,2de80062,2189e2ef,ed10e3c3,9457a34e) +,S(81599046,453d0a96,2c5f3b47,fee7f827,537c7c58,c5ad068e,e5e6ae6f,7a9c6848,4a83b015,3abd0df4,177ef3f7,e8a7ac7a,e8e5afb9,a2fd359a,c30c13ee,321f943e) +,S(11c9aa76,2cc334f0,a3274f15,17a1e60f,2f0eedfa,d603f83a,120162bb,e87830d0,7c73d374,26f648fe,4a9978c6,a64ac787,f4c8d79f,b58b0f58,70e373e4,d317136a) +,S(2b41f344,b285a31a,ebf4f4fd,f0c4f463,49fcc794,e5762e04,dc39efc7,936735c9,7eb708ba,3f683d48,db8e0c25,ac8a6f8e,5c340749,c3d6ed5,7936d515,7f3d6e73) +,S(dc063e66,38098e8c,6ff55a73,faa20099,c10d0258,87c19850,43d1011b,ab211b93,4abdfdf1,285ca3ad,65bb9a85,7ad647f7,fff01782,79fc6df1,6179e1d,495d212e) +,S(7cb514e8,b6361aee,f9a7abe1,f84ef401,97de721b,609c3151,a056eb03,71ccdf8a,4d359c89,7d03a633,369bddcd,52a67387,fd4d1e00,2406502d,9ba6e967,a5efd0be) +,S(103a6644,ee731721,bf29f036,97641fde,9775a642,9ce8d97a,26b06ceb,f9066693,127b6948,6db0d230,6ae90a1,4b8c8ecc,1e9293eb,cf154371,5ecbd579,e886a726) +,S(adfaf771,662d719e,532ba045,72a50f12,144fafd0,afe93f7e,1d8edd13,99226e5b,b4d0335e,8b600a4f,84d919ba,514bc249,e3048cc4,281db3b9,a7c62013,4f00bbca) +,S(609d9352,30f3c6ed,bf64275a,23a9a258,33fb8c3,9c25dde,4b55ce22,e64b50fc,cbbae84,c57f9c52,67278c4d,3b0cc5de,9327ba71,ca1a1bb1,8aec9a97,bce17552) +,S(5ea5aa20,1b958a8c,49b70510,b7c6a29f,86d9ded9,afd4e833,77c433d0,f62d9ba3,27c5cee9,fe3c0bc2,af8d0e30,57eb0f57,b1fa4237,996bf8ef,5ccd25ef,e1b87ecc) +,S(3f801115,3603a689,800c04d2,7d3b3fe5,c415ea29,c6e11951,7a56712f,20a10862,4280ab61,65b122e1,85abf4d4,14a31961,ac6595cb,421db183,34e57cb3,fe9bd059) +,S(54981ffb,5b692a3d,6d9ec7ce,f027fff3,c5dafb7,aaab4c5,572522b9,e1157e5,893183bb,554c81de,21c84134,e395b9fe,80a5a9ee,b06e3b67,2ef93127,24c307ae) +,S(97c18e92,d499ef62,77585c6b,28f36fec,e9a2e118,f793260e,32750861,a1aeb813,38a87702,7f1df077,d6e734fe,18a023ff,36c6d4bf,4a7bc7ce,d3a3d38f,c3069f33) +,S(d5507aae,97bb6e17,410bc87,26d9eb2d,11558b96,6c54e7db,6428b44a,3589820c,e78d0140,7468dda6,d9c4af92,1984460c,e523c101,79f7aa15,d8004dbc,4fc63cb9) +,S(220d6c2e,6c500d01,9ded2aa6,5de205f7,cdbb15e5,69038ba5,7bb1700f,1182ca70,64b68506,c387ec2d,9e030448,797bc28c,5e09e8a9,95f5f80e,70c26a1f,db7b16b3) +,S(c1a45038,da6aaf1e,396595c,3ab404eb,9584ec90,d894985c,18e779de,793d20ba,1a443da1,72e281aa,4393e1de,6f1e4f89,4fe5d1ec,b3a5bcd9,607cf79e,6f20b533) +,S(9a66f9b7,f3162c80,d22d0b5d,2a659bc6,ac01c74f,46804ca6,c908b6cb,90fb419e,3465357b,209c2b,a7c766b6,9c17abdc,69205c54,787fd0ef,e744692,16b95d3) +,S(8b305bcb,1b6156e3,22f0f0df,28265cc8,79e5909b,b76b546e,eb223d62,89883387,929a341d,dfa05574,90cf5293,244d924e,852b00d0,d328ffe4,7ccc5356,623a31a) +,S(4e36ee67,b5398169,8ed9460a,cb450023,7198f249,4dded391,4c2ae003,63c8f664,a784c95a,9a443b7,5859a1b1,373eb750,150e1ac9,d5120ca6,f273578b,73df77a6) +,S(167275aa,38d02988,c53e0a36,d8312e32,369bc677,6d7143df,cc6fb83f,66747caf,f26b9851,31abcf45,369a6415,84b2956a,7122a51f,b909bc30,5427eff3,916e6e14) +,S(c93d0b74,c99358d6,d24a962a,15adafcc,8a4e57ca,df0afeb4,9d46ef53,cf619797,f93b324a,b144c6df,336e34e1,beef5c13,b931668e,54ab34a5,eee1a8f5,5acc683) +,S(8bcaa2d4,671bb4b6,8a924109,32128551,fbf6d924,d4854027,7c1dff57,3bc4a8f2,88be3e1,6482477e,62255fb3,24512abe,27cbb4df,f63c6d8c,93c3c923,47e519d2) +,S(69d186de,f9a7ea8,be833f2,590db08c,fc0acfbc,64a648b6,8ca412d6,88c03808,d776b644,43a81bf7,527f658e,45d92324,a08ce171,6db6c259,898fab8c,f3d6d41d) +,S(4a53595e,e2cfbc6,7bdc9f07,308f57c,7ff5afc8,a35e27ec,e22cdbdf,6efde161,e55913de,d481077a,ea36c502,494b3b72,b1691786,335b0278,3e40fa1c,1a1b0876) +,S(90856f9a,5f7bbc14,557dd419,516ce5c9,aa451bce,13c17ce5,5c9fb1b5,f2924995,ca083d2e,b5a3a067,4a2534fe,e03bd99d,976b96bd,2b7f16ea,6e2552ee,648e934) +,S(2eed315e,d863298c,aa374ca6,2bf8313a,a0ca07e1,9a94bc4d,58eb235b,52d36dfc,afa36c8f,90d7adeb,ec33ec69,40c08d1f,2a4044a7,477da88a,6653d90b,880856a7) +,S(345a7f2,ab7ef064,eccdbe6a,ebd11dc5,3c7ede0,b62ab3de,f8e409e6,258e84c4,c0c0dce5,93cf9647,c0228d8,42b78407,c3b634ac,799fae19,f0e685d2,6ccfd73f) +,S(5a669d7c,209b222b,47843a5a,633e0b53,48442258,663a58cf,f6ee3cc4,1b893d3d,7067be1d,8636698,2b808b16,3c05e57f,2be77d1a,2bf78038,e242f5c7,4ce10523) +,S(3f0b0f3c,30a991bf,927f5119,6fb4af39,e1399d01,1766b1ff,1f0ff2d8,a3199062,be8f8781,4c06a75,97d062c2,196a49ef,93a73923,f43d16ac,82c015e5,4789d472) +,S(9d7f2c64,98e78982,8492b8c9,2e0e49c7,b5c9d4b2,e86c409d,828447fe,4a2f5a13,95ccc540,8202dbc,78323d6c,7ef66d51,4af34699,5be50b56,98a5864d,34e502cb) +,S(9f741436,55b3cfb5,39917a7c,79fec4ba,164503a8,3958aee1,f6e8f34b,3d861b78,345738c,ff8f3c64,f5cda5a7,a1aee7ef,f3a33141,a5139c3f,b891c6aa,feaaa7ad) +,S(cf1d3136,11d4b6ec,5f1a9728,c9a7b037,d9c16d65,bad95fdb,17376200,b1a9a97a,51c72169,bf7b1ad8,6159fead,dcf3b0a7,a7fc13cf,7bf12d98,409dc3b4,fcb7a9a2) +,S(7e04c6ef,c7433f3f,fa2bb827,3fdcb3a,e0470abb,cc7c8dc5,414ff77a,915868a0,781125c,2184eeb8,87019f7,c5c0b4a5,5922d11c,53c3db9e,d5795bc6,e7539cc4) +,S(fa6d73b2,a97801b6,16697ac6,102b002a,53d29d33,289708f,d8f73964,77f3d57d,543db558,25c67a4,cd010413,9f8a093,7ea7ac2a,380799f1,c2249569,3cf557dd) +,S(d0fd7208,8deac18b,1bd63fbd,6d5be0ef,5dcd34c5,538a9b64,ef43daea,ef321d1a,7a5e1e2a,1b290241,7879f223,8cc8928a,65988130,81366846,69841b93,3ddc3a1f) +,S(e856e67,e28330ed,77d8687f,bfdce5d9,ab8ec155,4c94ae0f,491d1e43,9361cb99,c51585a1,9da7c26a,4fc07c6a,f17999e7,a6718542,d7500fc9,1bd21fc3,8acf1eea) +,S(389cff20,9f240748,b9beba0,34d36e0,5e758a3c,95c678e,28cb0226,37db1bcc,ae5a0d3,db1e17fe,30daa2af,1e1f759e,905811c8,95706b7c,e5741051,2b7ac4c) +,S(28ce0f42,ff79cdb8,16b666c9,c3014051,d46e8df2,e2377c3b,619b78d5,17f21a1a,4e835188,f742237c,fe581edd,937b7294,e06fb295,d401b35f,5b7b293c,6d57f875) +,S(3d955bfe,5b27beb9,68400d11,3b8666e2,63af6ef0,ac6ee49e,8628e2ac,4d1e69c4,1fbd2aa9,b6913655,e00f1384,a15a7215,d3d7340e,4891893a,a67faf39,88801e9e) +,S(53dcaec1,2dd48ad9,ee65c9bb,ef21a023,58cac930,316263d4,9d607074,8aceb771,5b976f2,411d7624,d4659e5f,db624b05,9dd5e06e,f0b65740,ba394020,b9d279dd) +,S(ab822568,f7e9da8d,3f1220e3,24752c80,b02a8124,f8d9f65b,3b4532ec,3740881f,6c2152dd,34451ab5,b47b7c08,f7edada8,f9f230c3,5fdc2de3,35cd93d9,e25703c8) +,S(36719c40,1518b976,684bbdd9,2a923485,ce92b321,dc26534f,e5a0473e,4c873c30,d5d58a83,d493cccd,d16a1282,68aa93e4,94ce8638,41ec947,930c72e0,887564fd) +,S(360c82e6,18a53dc2,e44677b,a0bb8c2e,2a08f6d7,afbe8498,15d605c3,2e5fa969,ade18222,e1d0fbe0,a31c55b8,d2cb947f,1fcdea11,1e08ea3a,4f3dff02,e3e38b70) +,S(ecf50737,25a3b81e,dc621bb8,6c98fd59,f805d6b8,2f08380c,64270df1,95f020f,f5431b8a,cba5d27,1da26cb4,fc3412fb,14ccf088,6e0e08ff,ce0db47c,6b4172aa) +,S(3b751389,e6dadda0,85298860,76076249,46df960c,e030caf6,91f91d46,4d05be4c,244b0028,48829fc3,824dbe61,168fa1c0,3e4d3835,d3da3a53,7c729f0a,191e92cf) +,S(ee6e33ee,7fd9d7e7,aab10b8d,2c58f2a7,26ed307b,6fa69b3b,f1f08a74,f1b04ffc,4233398d,6ee49505,c5f21525,6cc9112f,5dfdd7e3,4bfb9a8a,476b3cd8,2645b8f) +,S(e7141075,e20f0903,f39fa384,f91a5708,7f24deb3,68571939,572caf0d,2fb543f9,5265e24a,bd84336c,26b4607,dfa25c44,49c4693f,adddca01,599d814c,21787cee) +,S(d401b043,ee9944dd,7429a8c9,4291dc55,7e5827d5,88375dbf,1513d394,a778826a,9ac9b417,5ac3666d,7c6327be,5172b8b8,1dbdc96,eaf8578b,76f01128,4434b937) +,S(d48c45cb,b90394d8,23574c16,60898091,75d503b5,99d936f1,f60246d1,79c9cac5,4e6b2bad,a67ebb7,a0743cf8,52298052,2737f0fc,6cbef646,fb270d44,2a285612) +,S(19f6446,fabe1899,ec4476ee,1d61f6af,961da42,ada1f77d,2ab41cc4,28791c64,7a0aa5b1,4f2ae030,d9711963,bbe160ca,424f6a7f,17b6a709,b5f0dce5,af1d0498) +,S(2db1d56e,f19a848f,6d6747c6,82cffa47,78444b3a,d57ea076,b0560b1c,4e57c83e,701a5894,d1d6b6cc,b421b168,fd34aeaa,e85262ab,44f70c65,b8ff61ac,ee541cf6) +,S(443597f7,9da3df8b,5fddf8da,3bc3a060,83f2cb6f,affbb1ab,8a12db92,59661adf,31b2c4ea,362a0cbe,2b9b1488,719b7ac4,3a85f7c9,63e9f2bb,b46ee055,71e2ac2) +,S(e49ad52a,7bd2db07,d972def2,d1ce6684,69aaf6b3,3c7e3427,52d79fa0,9d2ee9ad,b2063f37,1ca78c2c,429cd401,c5e46d6b,dcbf373f,5cb77163,5760b8ed,b4f91ba4) +,S(35b3fc0a,4a625cb5,808e1c2e,73c962e1,6ab7dfb3,28109ef,fdf81e15,841afd0a,cb558481,145a5f75,b639133e,8ce42c98,d36d8fa8,5348c815,d92a2c8e,cc993bf1) +,S(1cc238ef,3f64a075,c3c264b,ed42a0ac,aa6de195,7db40d52,86c482cf,f62f609a,d3382317,2b8a1450,bd918aa3,c57de76d,3012887c,98452f7b,c1f58610,f528af49) +,S(f5a2794f,48885192,dec727c7,79fb0b6f,c2cdf399,4ef7cacb,94e35791,4d138e84,d3ed4f1b,912f5dce,5a0842ff,d2e671b7,f3ae8448,b1a73f43,249a1acf,915b9c34) +,S(21b41016,a8eb7c6f,5519d94b,adb0fa7a,5c553822,6d080e3d,6d2956e8,8a9579e9,802570ed,b9b01b1b,ed79b6f1,76ebc4b3,55dfdd16,f43e82e8,7803be0,fc44e274) +,S(9b5611b7,938ac10a,9818bda7,3615a47c,1ee0f072,75aa3dcc,b8919dcb,e7beaa88,89787c01,d088e3b3,603047e5,2f49981f,7f007c8c,a88502c1,3bd9c327,e3c83b1f) +,S(28163c9a,b08a7ad9,38c7b35d,b19e700b,3865800a,55a3103d,2213c9ef,2c03858e,661e089b,df356bd4,afcd0604,fa5ade9e,74c5663e,77ab57f4,a069bcf9,b8b227bb) +,S(bae9ac08,aecc06f0,ffb8540e,2589a32f,11d34a7f,6d899e5,7a8f5ec5,bcf1601d,f5b63d9f,8a5d23b0,80d0bb6c,b8df736,aa660a3b,6f987683,cc0a54e5,f7d1b4d4) +,S(19f48542,3ed01783,cb83d2d,2efd7264,a10c6c23,1f5a242b,112eccb6,31d91f7c,79ce383f,f011ce13,87537ebc,3e70dcfe,2cc2764a,3d180fdc,74a21062,a5b75f50) +,S(cf459ca,cc8c4ff2,c827efae,6593a52,838658ec,bf1a78f4,75965856,a8ad007e,786781e3,3279964e,da5e6374,bf088fa7,5d18901,df01a0d3,6c87b62e,b419dca0) +,S(c19f2008,e6945d10,471a13e4,8b16f3a6,381de3e2,b24f2d92,77ded25e,930d1f47,7179aaf5,322b51d8,7758219f,cc30e9d6,bad5ab77,b35dced9,6a513b4b,fa7fe147) +,S(3fc1b649,3b6cbecb,1767d0e5,6202c84f,39a6b41,87f05ac0,d659c45f,5bc565c,db9edee1,1768e29b,4eefddae,c6234622,55d06e0f,1979c8c3,5c366f4b,5cac3f5b) +,S(502f74d2,cf589c65,e63b2a8d,b2b1e4ba,5f851715,bbb27e8f,165fd34f,29cff7c5,755e6c73,765bc45a,c2f9d4da,499198a7,36743571,40846ce3,6afd8063,981a96b1) +,S(b9eb62bd,7cc6d1d8,b0eca2b6,1920be5,9227534e,7fb581c6,4dcec4f8,f1ec44ca,ac567b37,891e3eb5,c40fecf2,d4c5b106,bd222c8b,64ab491,f7a028a6,a02178e8) +,S(2e5280c7,25a109f4,c5de565b,9fe5357c,718f9fea,db53aa9c,b07a0f3b,f5030ad4,4783be94,1b162e,79f58d4c,448756bb,8ea18c4b,692e236b,4b2b3ffa,24a456b4) +,S(bd59ac74,92d24606,9b233efc,1b68c371,bbc9713a,284f7f0c,699a1d5e,ccca64ab,1abc71f2,fce8372a,a4a16abf,1d75bd87,a19c08ed,c8843f44,fb71bb7c,a74ec4e3) +,S(6acd12ba,4623582d,d769c8bd,3d6adabc,2c13ba3f,bb67e4ed,ee0fe70f,3f832f5b,982fce11,ff1e6c05,2f21be20,ce1710d8,5cc043dd,eca9bc43,5d100d9f,f68150b0) +,S(601f4285,8b0cbce9,90500c64,e7eb77e1,c433dca5,55e6ddff,5264a98,d688decc,56110eb5,d5b3ed79,5906ed4,c0275827,79cff7fc,ddecbe7c,74d2bf10,ab2beac1) +,S(4d393daf,c47391d8,8208263d,b8132156,e9fdd6b7,da48eae,90489d12,832dc938,a14180a7,898a5a00,6ae5b8c8,d034c233,93ed2ef4,faf6a4fc,42c4df1d,62d0ea7a) +,S(4ea24f6c,3c164285,166bf2b,1918b3ee,3cac8631,5a1175d5,4104506f,68b7171c,87da621a,a18d1a18,b1dc222f,af37b5a0,b149714a,e755ef03,ee3af91d,f2a7f5ea) +,S(eb1f6f2c,a5749f80,b88a7359,f0b67230,b2b844a2,4fb72dba,f5604e73,cf6e432a,6f58093a,55e3cb37,8830e58b,10612b24,56a35fa4,b8e60409,1b9b8304,e35cca51) +,S(2361315a,3d41b82,98a9d768,be7f453c,eeb977af,bf1db132,c831bc00,aaccc9ab,90df3be,336d4b58,7965778d,9300cc1b,3d954d4a,89abf173,a9bfd99c,29492dbd) +,S(44f432f0,46c7defb,630d5535,aca1bd47,10505012,6b2454b3,4591b079,7f8e9b28,1fdfbcb7,25eee981,c19f98b4,6bd19dff,9b6cbdab,730ca2e3,1643d415,e3aa0489) +,S(d563a475,4c130e71,81b60a66,a3f2ee52,7040f9f0,eac9e26,866fb226,f93db593,49fab7c9,6e320961,6f4610dd,532d547b,b24f7f07,f916f10e,630ae5cd,b40d3b11) +,S(2fac4651,f0ac9876,4a74c066,16e7f1b8,aa6d2bb2,99ef9f0f,43bca81e,7a4089b,fff2b7b8,c330e1f9,86a69324,a63bf10f,fad8e78f,dfbb6062,c96a67b9,eb460d5f) +,S(b6f60ef3,d8b793d6,5794aa89,12e8e1a0,9ef7604a,5c9eaede,b803fb31,e8195dde,b9b17946,4057de11,9d0bf993,fe92e4a8,bb633d6c,d03ce8b5,10200166,467e6bbb) +,S(d08c6813,65789ba2,4e580637,2eaa1ad1,d1254462,3cb64d83,5ea2e1d8,6e34620a,e94875ca,f5beb1cc,f88fa3c5,e2776203,a6f3cb5e,b4803618,52215d0a,9076b185) +,S(dfda222c,a4ddbb56,661f56d,b9b74be9,a5a7c34c,4761483d,928aa48,9bfabf52,bfac4ed0,ab4ccfa7,caf64d8e,ffdf1aab,6aad50db,595b1b49,7fab28d7,656b6475) +,S(3f72e4cc,ef5c0bbf,995bf8b4,67759969,d93ee40,8e738a4d,41f55896,17f241ed,c42ad857,3f49218,c7daca7c,8ebc5c7d,f9ac301a,2aea209c,ab6648f9,8ea16f5c) +,S(6e85f587,91431b6e,dd848aa4,70101103,f63881d3,2fa9f1c1,e3324161,e9ebf0ee,f7f00d38,31e09d69,f0684107,59dcf837,eed3d833,90efa352,40a9ac5b,2daa2a57) +,S(d991fc76,2f75235a,5268a32d,64dbeac1,b2333a34,5ad552a4,cedfab54,9b191f14,90d58a07,794983c8,3f6edcfb,55ed0b68,8f43d9f5,eb7678d,29610299,63c748b) +,S(24cd7922,7ef207bb,6b9b678,5156bf76,77101e6d,f5fb5576,a9d33175,8d7c00,44608974,5f1157bf,9c9f45a1,b212a978,8e348a0f,55129935,b038940f,84e91468) +,S(5c053ed8,367806a2,8545692a,47314850,66910d02,3373b89d,e85bc7a1,c25bf6bd,9a3e45f8,dde03e64,6d6c546c,cf4c8fc5,a253054a,2d6df43b,d8c4afb6,385311f2) +,S(4f3a4d88,20948d82,b598f118,1d350719,ffaa5ce9,9a7f614f,a9e3cbf2,e021a6cc,149c6722,980a41ce,5d4c0b94,9cbe3c99,4d94f2d7,c36ef45c,d7b9084a,79f451a2) +,S(badbce64,8d55b579,cf8d6dc6,74580211,a6bff856,10804077,adad7c2d,238aa542,567d75d7,1570d7e5,184f4f4c,a53fb92d,654b67d1,f6bff96d,fddcc3fb,932f0343) +,S(d2eda540,5f828eb2,cd3bc5c1,9f9a838f,8a1186eb,3cbe9575,5cf6642d,13601942,ecb3dc3,655ea992,4773cb57,f4f4c8d,6380c665,69f08184,f521dada,c108629c) +,S(191ad0df,31c7f3b8,258e5bfc,ec9d1ff1,2143b240,24d93a17,893da095,97304f1e,4ad4991,6bd2296f,b6f6b697,dbf5a3cc,4c3ba136,6f6dfade,c859b190,48fb523f) +,S(f108bdc4,a1874aff,35bd1fac,b8e81b5a,7a7ed597,e78dfb7a,c716bf7e,7a15dcac,b88e4fa0,d630d92d,bbdeda05,4a6c6624,e7bb1d5b,a6dded85,347e5275,e08c9414) +,S(30fb7605,7e2a6cdd,59fa279b,3574cf1f,db9d5159,19d0e523,990be02b,da1ebffc,5743e72a,752b558,1b959a48,3b6229c2,33fa1b3b,2719ad3c,a6f8f9ba,1702ae8d) +,S(6facb1e2,6d1ef1cf,ff413145,63f3b2e4,e762ee7,3e43378,c4c15f85,1cd948bb,92000e2e,a3a5bdbf,f6eaeae8,8619f2a,48b649c9,19972b7b,83cbac22,62d484d7) +,S(741c1253,8cd4da52,c596840f,e6233558,fb480a0d,43232756,2a9e2d59,a574b981,79040b6d,580efd7d,84356117,a93941f6,b47e6c0,a53627e1,bb80fcbc,e6881234) +,S(2b86fe60,2b2e87f,59498185,4af1f986,7debc5a,84ae8bf,94d2d6ab,4ec8be09,cf4c27b6,b33b5020,2ff7fdd3,ff0743e8,f28ca75d,3cb74d21,ecf21dab,ad7ae079) +,S(e6e7b676,9f0ed86,4163e9d3,66a7e2a7,a37f1ee8,e827b105,3119b8b,d36e7b84,c2e5b9b1,d82b4504,454062de,6c24430f,53e03bd1,819eb1e3,2f24606,73d09be2) +,S(86600d22,e7bec946,5b0afe05,5e733b03,f8f81548,ea44e008,740ac807,ddaabbe1,abb367d0,5e6d2fd0,a2c1d0af,5ded2926,1439c985,ef287860,80614bf9,8e8e33fd) +,S(67171261,5cbe2da0,b252a773,58f81c91,fbe561f4,87df09e6,cedc8a55,cb3414b2,bf02d81d,10a47287,2b7e65e4,93d97cfa,e3bd6ba4,39977371,8cde674,8829b0a3) +,S(97db468e,7f3a25c4,c34e202c,e9b2480a,4344aa9e,1b76a147,4bd375ed,6d10c0da,c58ceb67,a28f99de,2eca70ef,e8af24fb,c381f962,d5db6e3c,481cca6c,469c4c27) +,S(f3ac0267,ef19ae9d,762c4023,4ba97e33,a88b015a,e6a83f4b,cf730d84,405aed26,cfb8a3ef,d1104873,8c1c927,b31ebd05,105bcce1,d57c7fad,1972a5fd,cbe84f06) +,S(fa44128c,3c258fd,5a99c85e,775fca63,4e8a46d8,4fbff953,b373bd50,6ca3da85,f3196e74,d17cae3e,3c9958cd,ca591374,ddffcba,7e362139,17e5e119,a5538b1b) +,S(95244462,1eda0b2d,acdc1a57,41725c1f,a7c5660c,feafe18d,ff8789ba,164e7dbd,214bb6b1,7af1584b,76a9e5a6,2c32eefb,497324d5,7b00f71d,24b162e7,1383bff9) +,S(11de80de,c03a732d,6769e52c,64be4d2f,fb1d696b,2a658721,94aa384,392dff9,e1eb8932,42386216,f543eea,a2d1099e,531d8e27,7cb2e5fd,ec76b3af,e9e9c7b7) +,S(7318b452,a2b9d23a,eeb30bb1,3883dff5,b373be94,94451c72,36a2c02d,a4c37e75,26713361,aaedfdbc,2966fd1a,ecfa705,772012b2,564b077c,7f5db7b2,c810861c) +,S(82d189ad,e5610825,1b03cae0,4b138ff7,dd2d77b5,422535c5,cef9be7c,1899cf75,3634267b,1b3c3de0,d2dba36b,924949b6,7e05d790,29c9452c,18c6ff70,252d570) +,S(e5dfe995,82152513,80859865,f16fd0fd,e4d60c7,be0e2aa2,d9b2af4f,3714f8f7,e1d87d8f,fdef889,52918e62,5bcc90e6,83f337a6,103cd000,1cfd01d1,eef4b9bf) +,S(54cdeddc,9fda5fe4,63240f72,8ca66c34,ec05394,899f2472,d82d2378,28a06a3f,27bab620,cc373ed,10a71c18,345ff27f,e20e1bef,98052afc,bb45fdc1,80b94a2c) +,S(7f96757b,8b473785,e1359cd5,bffbce2d,5b26e8fb,579d7833,607d58,a791c47a,d4b43e2e,20a43fa3,5a96d1ff,93109aa0,b7831fdc,2d2c016e,181beac9,c1cfcc4c) +,S(eaed18ba,83238fa5,ce4e6c82,edaef108,b1f9929,3148f3e6,2d3a6d4b,535455be,1017291b,805f7b1f,eba367f5,9a1a10b5,f7501355,7e6eb921,20838c50,aab0d29b) +,S(91ca8ba1,da9c2625,66a135ad,81f57b10,65ea4632,5bec5d42,ca1ad62b,826f04fe,2d5d619e,84fac3c1,e30343ba,a61d3bfd,e1c4a9a9,8d968e92,d560956e,138e34ee) +,S(8a31ad57,12e32254,7d0d2907,cb73adfb,a9a1ed5f,fe98d645,22082e6f,1cdb1364,8ecc3fea,886737f4,f94a2984,e6edba9,8128b2d3,bc79a209,2b2c1a7b,b00bff9e) +,S(123acd6b,ca673170,400bfc4,1071cca5,4e03daf3,e1ed1458,88470c04,568b972e,e97dc60e,cfec2d5,c6a6e173,9d60f7e9,838ad723,ad0fc7e1,52b5e70d,b48b853b) +,S(d7c26043,ad647f0f,d056c10b,4ac932c6,6a545bbd,509de346,d4391942,52e69df7,6bbf2f04,2c9459cb,c72e6aa3,1b6d8e4d,e606eeb7,d5d4e0f5,7f729a79,ab1f5e9e) +,S(67c4eb00,548e2cdf,50626c8b,1aec1173,8370da41,9280c9b0,1c8783ee,91e018d0,ffff201d,91a4538a,97ceb50b,c9aac646,bedda1d1,3f22a121,c709bfc6,23b95a67) +,S(7e1264ea,486b08c5,19c7d8e6,5c80e1d4,d2994bb0,95185c72,63172b1f,ead93428,1797609c,816f10a2,e82afe39,65112a35,798b0874,b24503a8,f57c983b,6ce7ef6) +,S(912cb164,5f7d7bfe,5ea443af,1c458500,a95ff22b,212109e3,12fa01c2,41319cf8,bab658b0,111c48f8,a2f620a5,fd130d53,e1c70e7,62e33dec,55b22d87,38c1eb99) +,S(1d60694f,15577a40,f6b9f299,be5eb62d,251f62ad,b9b5651b,df804e27,df919fb7,3799eb92,e18335b0,bdbc29b1,f8ce07ff,3f7cd409,5840d5,dd324bca,2f902a14) +,S(8166b50b,811bf53,4a94af10,7672ab4a,4e154b2f,c5cebee8,c8ef6ebc,18cc3906,6dea31f3,343e5b45,f5b08c19,903491f9,349f4ca,29818fa9,16f5e02d,85e09ef) +,S(4852393,e42d0821,6664d5d,f85eee60,9660eaf9,54ccc6d,fb1c31f9,da17923,e4cadcab,17f64d8a,f5dd74da,eaeab7f7,13be1de9,600d4db1,a781a058,5ed2006d) +,S(f40031b5,ba171b26,e02be47a,c34173aa,18ec3850,1b1d529e,a922a418,1c3491c9,c2db89ec,2e50105c,4074b729,a53ef0a7,9371d2a3,354d2d23,8fb39bf4,bcb5028c) +,S(8926d233,3c842f9a,213547a2,fc5ef5de,b0bbd603,e69d347c,41e7d49e,aad76cb2,8459bc10,b7b2617,b0d434f4,b62a4452,80bb951e,b4ada14c,fa800389,b3ff892a) +,S(7f362b16,9d9bd514,c6289cdc,70ea4b77,e7518db6,a2e33acb,8acefcd3,d8c5726d,dd1e69e2,71d77dc,2629cded,72869345,7c63ea2c,8636c712,e45e6af0,4c15fe35) +,S(261b8037,98ca780b,50dfd56b,81093f32,d7c348e,4f093b91,70470ccc,4516ee1c,5723ca6a,5959d589,4a24c12b,5f87a5af,84c7a6a6,89304000,344bf5d4,81c7752a) +,S(d137c0e8,edb32642,12f6b958,8b527a9e,9e57f3fc,c358a2b,68f11d61,89fbd900,d1043b3,5f809513,ae370588,4adf90c1,9d164c3a,8166027,92ca55df,74c71466) +,S(96274665,253f4479,753de9ff,ac94af8c,943b8231,b1302040,bee72240,2ccc445e,8ef6f9fc,f1e21c2b,d913f877,98c6ac9,f53445f3,6c2b1678,a301a4f5,17867296) +,S(bc6ea584,b1f9b006,5f39226b,e31a866f,7f90229e,12aade70,136dc747,b37f70c3,23f1c4eb,99dfbcbf,66539762,4d20c4dd,4414bf15,172cde8a,b7652ad6,f87ad5e0) +,S(3e968741,5adc1afa,696e3222,fe351939,1d3f19b6,feb1de83,f4f1aec4,d25e2387,e3f4de27,67ea84c7,8baf1382,4b7917dd,477bdc87,cf1cf38f,8f5da1,e096b528) +,S(b5973535,c9c9d4bc,2b2a9b38,57cdfdf6,4995d64b,81c9e68b,abe4d4eb,4eee489,907cff05,5eded925,770280de,9ee0e025,1629796e,8ca05a47,48ddaf98,72bfdc3e) +,S(d616bde5,acd5f345,d23e8b2c,3d95038a,a1d7a354,a7613cac,57ec3e8,d07e11e,6c88c62d,d795d065,c6c86478,cacc56d3,2282b4f8,f3059aaa,55388555,449879df) +,S(540345c6,5869d3cb,cf4099c3,ba7422e0,feb87ab6,ad67429c,2dc99840,e6bc82b5,9f424998,bceafc7a,a58e5f16,c58e53d0,c0d51f64,285b0afe,e84ec9f6,b22f8f37) +,S(6b7893d0,ace6ab5f,c93f2e80,65a3de57,4d552e5d,4a89d660,714113c5,a256fb84,81a016a3,7be94a2a,f45b1bfb,968006a3,58398fab,424811f7,6765fe75,d4438d5d) +,S(357ea5e1,7a0795ca,cac47e4b,9e59bb24,45d1b6cb,2c713f04,7029f6de,2be57734,571de7e0,27dd05af,90bebc29,bd7345f5,77babdd2,75498bb6,d43a668a,8a4d6206) +,S(7baa2739,1db2a0c8,679d0e18,8c5e7c8f,ef1814ad,b7bb3955,519b4189,1a63ec40,73b56168,20fddbb5,749e8dfe,ef834f74,e266df86,e34510cc,f5eebb52,a868075d) +,S(4d5251b2,dd778e04,5143169f,8cab93b,9a9b7428,1a0ea1ff,964225a8,10b1e578,9376395f,2091036,16a95686,4e55382b,39b6934,2b2964d8,34face11,a44f491b) +,S(3c0fb553,b0c6330a,3cc06bb3,b0cb4c2b,31be7582,55264b29,98bbc166,ff57f7ca,f1f409bb,cc227824,4dc08c3,147e0b83,3522da9,6859400f,8d19272,e33ef1d9) +,S(6dcc7ba0,4b3b0827,e3bcb462,7b7db8d0,e0997c7f,900d27de,2d6c87d9,aab2c373,f2dcb11e,87b69faf,4400e9b3,186eeb6a,4fb48cad,6d6da276,3943772a,4e18b450) +,S(a5271e35,ca54c1b3,16d6113a,40414ed9,26bade46,c3258c6e,82a63e9d,927ce06a,e2d6051f,bf42dd9b,e0b2e00,1fa4e308,66232871,313f9c82,fd6ee37,6e8e376b) +,S(574d1ffd,976c616f,60371e4a,76b2712e,84b0a231,8d3c1c0d,3b56b10c,e978efe0,13733a17,a956efa5,733dc130,cc4c848c,19ecd6f8,7fae5ac,82c73de5,6d1bfa0) +,S(ccccd911,ea84c247,262a6e61,8028b2c1,a147f55f,b637b570,97400472,fe3e27ce,cc4b4f5e,491f32aa,eb6d0404,5965a97a,e4119e73,33bd1b39,f2ea9873,7d8f33ef) +,S(df1e4fa5,410f1438,9a41ca26,31eef376,4f10868a,f2f05a1,50e2c7f,8c3a2643,8185a88e,2b4a343d,bbc10da,723d4cb8,29014cd6,3211a82a,63627b01,1b01e87e) +,S(2ca6b7e,b53516c7,2e216263,213c0d60,fbb02f,dd227f6e,4ad29069,f6da9213,81d5fd1f,5264af85,53a8227b,7500d82b,84ca1fb5,87ea30bd,ab30fae3,67e3d7b3) +,S(df4bd790,ac3a0db,1663a8fd,aec1cdb5,b30c7a67,99ac2ed0,16f1c474,5bea92a1,db80f378,f33f920a,d0f4fad9,595b0655,44ffc36c,ebc3f294,3db13b83,cf609bbe) +,S(792648ad,8c053cb2,102dde19,789d3782,79e0e0ca,c500f40,d46bce68,97af2839,3c2d9b55,afa4ba1e,1ce3d142,5e17ca6f,191b4013,7b7d8162,8de35e8,801f72f4) +,S(dc6fe845,50fc1136,1f648fab,deb9b3f8,e7fee837,ea545228,b2fbd432,e53a8aab,2a4bf746,19fc5408,b4bc6421,f4a570aa,172ef263,c890c853,d7b06aa0,65960dff) +,S(10d4786e,9151f2de,89f368f8,9502b7fa,74b7b9e5,7a1485ab,f82fccb4,9c2deca8,15da7f51,bc84f421,2ce948cc,28663e57,8b4b851a,f6533f2a,b548adc8,147d2243) +,S(67c7c0ae,e82dfd5a,194dc416,41388947,29ddce96,5b7d50f3,ca922512,6e730bf7,a8bf40e5,666ba93f,1f723414,24d8a7a1,6a2aed83,7f022fdf,557e6082,e3e515fe) +,S(602c3df0,8a2efee8,329f391c,a9f7b2f8,31ab6d32,bc4623c8,92272934,1f78a4f0,ac17903b,3808ee52,c0208342,696f5250,5789206d,515421ee,8b1ab28f,5b788eb6) +,S(c3441893,e78910c8,3cf917fa,44b608b6,671ea508,37a7d2e0,4e658c6e,2a91d9ef,b5388381,17c264a4,a0876c3b,7c261bea,229c2d0,a7399c05,114f520b,a7185dcd) +,S(49dc68b4,412dc3c6,c4b265c1,6cde755d,bcd49f0f,394d552b,76f67ff5,33c7fddf,f1490a38,cdbb6c88,d270eead,7de6358,132cff29,ddb6aea0,1baf6353,4c0cdae9) +,S(89080197,4a95beff,da864c28,36997c7d,3a4c0fc0,4ad59eb1,5ba4b124,702d0f04,86e165a3,b2e7eb55,9a7996ad,63265609,aa6e3385,30b51d22,4ae4f16c,d30be3c0) +,S(c9671a3d,f749d635,5684de03,1764cf19,1087bd06,965d23bc,4ea0555d,29ee0804,33cc0d4b,b02a1910,c158db0,ad2bcd66,c9585f9b,456321d7,61752148,e6224d85) +,S(f3c1a76e,1d4ce622,dc667a4f,dc0f4ede,7eb7111a,1539ce5a,bca71d2,fd48a26c,269ebdcc,e1d42428,4e0dd49a,73968676,58857998,7a062320,6251ccd0,ac9f9e2) +,S(12002fa6,68924900,8a540429,50ba2901,5870a70f,7fe95ae3,dba4b07f,aa6fa460,51543d34,34568008,74e8b1f6,6ec72fd8,e2936b6a,6022401c,d13d50bf,931996ca) +,S(a59df11d,d3fcf1d3,264028b3,6e26dcf5,62083e44,f91f3d27,f23acdcd,f1392a9a,4dbda718,48afff3f,faffaab0,5c5376e5,5fd15ced,68b03ac4,4785ab2,201cbe70) +,S(89f738a9,802d7deb,5cf2895f,60916fa3,d6d74bf9,e740d2f3,13ba393a,b40cacaf,293aa5b5,b03557a,e7288066,5ade09cd,ae6abc71,8e7d445b,cbf85a44,a035b73e) +,S(d0414978,6252c5fb,b4bfdae7,56092769,dfcdc2f2,ae38a5fd,92ba9df7,f91a9ee,53ffb526,a24df2b3,d6e8faf5,ee6d79dd,7f427d8c,14d2d5b5,880f1863,e7e95099) +,S(4a638f24,ef3528c7,a4e42cdf,3f5bb946,81e6435,ba2c99d3,625dc282,b941d341,39d97ef2,949f1338,bc016ec7,89585780,832043ff,33777357,9ecefac0,ae40620b) +,S(70a25f6,34d32af1,47c4dd06,5d52f78c,eb5e53fd,64bb151e,18e8629d,f4f8088,1b6bf3d8,15a0f919,68dfd6a7,7ab7417,d4aed9c0,a52b93b9,9b4e4e41,d1e558ce) +,S(59ea9490,24765add,f99fd908,11c65ac1,d0f9ee8f,27e459b9,b5851765,8e96ab82,b38bc716,896e0337,e4a1b361,59e2b5b4,e1680ef5,beb4b47e,c5934b4c,8d6675b3) +,S(874a6ecc,6260617f,c6d4f334,40c8e080,3d993594,ccc2d47f,be2869af,9881f2aa,f509e39,6663327f,7d768a67,aa0d2ef8,353b613c,bb60fc38,bd2715cf,349c02e) +,S(dbf3567a,1e634ab1,63a860ce,244f3046,c7f486f1,b12928d3,1c44624a,48bb5df0,bcdfcc85,38e4702f,99f9d55,eaa55216,730405a5,66fbdf07,4c62b310,6baf7ce3) +,S(a534bcb1,96450965,5593155d,2da069a8,4800e4e,eca0b504,62d844eb,d179ac50,f86b38e2,d558be4a,b0a216a2,906099dd,f3cc16b7,30e784e8,745f39cd,829ff3de) +,S(e11bb840,b79063c,4e090771,29d2bce7,8f291f10,120b57ad,63594780,fd1f1905,7fcac0ad,e0cdc573,67c9d74,1c6c9928,15b7c3fd,3a19b266,e0e5a94a,9a9ef9cd) +,S(d79bf0b6,552c5b6e,6e9192b9,765e687f,ea226d86,c6f83f44,b427ea9f,14b404f8,54e7a54d,583e2cac,129f17d6,835597aa,934b4732,6ffecbfe,deb503a9,eb9660ad) +,S(103396a6,57856b61,5507969d,958de14c,251bbbd4,9851a5e9,ea64e0ae,2f87817a,9d66ba9f,cf3e0c2a,655cabd3,91774015,e209d771,334c461e,d27b683f,f83b477b) +,S(9b49e25d,ae607f4f,fd876837,5ffc0fb7,142f9cb1,f0fde836,537f320a,9636723a,3472462f,f9fa5ab3,1fd1279e,7953dbc9,85623021,e714c951,bf00f632,e9f72ab9) +,S(a017d4f8,8e757556,b7ee81b9,d4c9b260,ba2f7f8e,5e1b69a5,fff94abf,723cc438,5f2819cf,53fcc35f,c9c15d2f,13dd51e5,2c8dd134,f012aed3,4b4383f4,8b00cd95) +,S(aff1db2d,3fa6dc00,51a8723a,7127d57f,69ed0b49,ccbca35e,25f72bd,19076211,7cccb7c9,4adc2075,9c7f8870,fbeb1a1e,9f95d644,af0411be,a6b12d3,aa6f00d7) +,S(21ccbdab,f6902a86,d368d445,dfba0f31,4f80de6c,c7f05f7e,9fd1818d,45a174de,eda0b8b8,7f40e9f1,bdd5ded,e65bd72b,6cbe049c,bb1575c9,6b779818,a67251d4) +,S(c3e58ebe,36b0e5b7,2e15c47e,cca6848f,5312369d,d270dd18,93b589b0,56ff7082,212df92d,d724e3aa,c42e293e,b1a2de5,3c340712,7ebba791,b901ff87,9fce94b0) +,S(f19961ea,da1d77df,2fb9d976,7d7c664e,c0400066,2ecd7244,12b72dc3,c5de133,74f321a9,1287943a,8ed14d02,96b05ada,1a24fb52,a09d467e,8e8175ef,8f04a2c9) +,S(3aecbe48,2aaf6af,35e63dda,fc919adc,f974e89e,765c4437,69ef535e,cdc05e01,92b854b9,30e5e4a8,85397592,fde89d3a,601c733f,d88d230a,a1168e36,ee367273) +,S(55fdd639,b87de7c3,9acb95ed,33222935,bd4217c0,fee1c924,f1060f54,fd22055d,81f4ef46,16e51585,cb443bce,f16ad8e2,36d6ed18,87ddfa60,ddba2089,f4b83c4d) +,S(b86a6272,ceed47d2,4ef4cc67,bef0b117,c0761b4c,29548c8a,367d8ae7,bf90744,1c0de18c,d5f3331c,5439020c,5964404,be582f88,3feec4c3,112396ce,b657c4fb) +,S(d141a7ae,9d92913a,26deec5d,d2acb7a2,115da997,63be5a76,c5a0a415,8b5b8170,de784bc0,9308c82b,ce3be9c8,9abe41a,4ed9b9dd,cf817aab,3785e344,dfdc2ecb) +,S(af340559,6902ad5b,e3fe3464,3cbcea5e,7a478a32,b1bde828,ec966837,192344e4,3f65050d,13e7b969,35b013c4,9df385d9,833d419f,aac0f754,5c395ca3,75ae8965) +,S(b70dce7f,870d3d12,472d3c5,481a1288,cccfdb2d,12637a9d,973f4e12,b026cefd,4b4f733d,e5322132,80a36e4,ba57894d,a563f4ac,b1a55a9c,83c8dbc8,96a7fdf5) +,S(14fa3dee,44dafb00,d2e71c91,5d217cd7,a9c2b50a,edcd0025,f7aad2d5,b6c62ce4,67c3a65a,65bd4292,d271fe13,9a8c9d84,343bdf68,cc16e50,11676580,6bc30d8f) +,S(baaa6a53,26a7fc36,e519d9a2,48dd3aca,f6f0628d,a6406021,caf0d0c,56d9bb3d,4fe9c638,c1078c39,a0fc39cb,e9a81bc3,4b15840b,631ecbd3,8ca4a2bc,10d1f3a) +,S(ffe2afcb,5e53bc7c,9ee07740,c8094a3a,32c8e627,4dec7eb8,cf2673a2,dba11725,68d7092e,2b8b56da,1653dfd6,42de49c1,799d3ad5,864e052c,8829815d,b2ad952a) +,S(a25d7c5e,83a0659c,5ead610e,b581d325,adfdd3b8,af03736e,4039ee1f,40612431,679ecfcb,b1da355f,d73d02e8,b79fc949,bdc9fb5b,5a4e28c,5e68c244,7599c806) +,S(1c5d082b,3121c4b0,2e0e2244,88e53b8d,ac5500b,bd396f0,7fc218dc,7311b299,a2a435af,4838d028,4d459216,f3955427,59f1f51e,9a15f28e,d83987dd,9c09e5b1) +,S(d8d21200,2cf2ceae,6c9a90db,89f7d0e0,42a2e97c,458b9024,437e28ed,a775ca26,b31b6a02,4b01de6b,6159ee51,3c118921,f61a536d,c1442525,cc613290,364b9df2) +,S(b5265664,54579771,947bee20,f8e7bc48,1e15d07,2adcecbc,3aae7b91,a4d0f3b3,170ad05a,da7f67ee,f7c611ba,3c55c835,f054bcf2,445e5c1a,399c7cd7,640ba8be) +,S(1d0d2a24,8982635,18a28203,b78cb089,acd5c296,98b86b7b,48fd4db6,3c80812b,71e2e1a2,7bff3bf,9e85e145,7f446048,7643f154,1cbe829e,f600d861,dbb752e0) +,S(cbbd4ee6,33aec586,ec7ba712,c3bbffaf,a0e6497b,8618a476,b64c660b,340046da,d792753f,c73090ac,177ec5e3,40aada73,3b31dcf3,a1f46952,625dab85,7e9b9795) +,S(73cfd295,99b6b80f,8757a873,ce9166ea,b1960f77,fa8f1d55,ddcdc90,9420a751,17832aab,c1083af5,683f8cf7,23c6376c,c22d190,241e1e37,6b1ef2dd,7333c873) +,S(20572bf8,abe50ea,37a064f,738dd18f,531b9404,e7e4d693,2c9fc34f,ef6dede3,41c79375,11c8911f,3146bb2f,63750887,c663d2d6,f3fbbd53,30af73c6,9d332191) +,S(ac208805,2f1518d0,3724ef5d,cb149f36,1ed713a2,94392f92,96173857,94794f70,1820bb1a,e843255,9025f3ac,977d9f59,4e812cd7,e27c390b,b2fe905,ae2b7017) +,S(33467f95,60aae872,b5c9afba,7f29cd32,a213f197,47745d8d,945d06e8,295afacc,44040bd8,138d9bb2,76181e21,79f4bf98,4b0c3965,a1a47d34,be8f47ff,52e15af2) +,S(1a77910,75bd3497,cbaff6a5,d5e8bd6f,439f5bb7,ca3eeb98,68033ef1,cff83f03,d8af802b,daeebe88,f823c43d,447f1906,63ede3d4,c4b9dbd5,caf82a3d,b4f1cecd) +,S(dfacafe8,cc15f85c,f829d913,9a9aedc8,6a98e010,5308572f,94c183b5,533f5bb2,c076b6d,c708d2c9,895e22f3,2fe42f4,33ad38c2,a0c55aaa,5c551fac,fe601916) +,S(3cd975ea,9eb5fc56,14955bb2,db0ca413,b83116e3,a09454dc,7fe973c5,7ee33ca9,261e5544,2fd503f7,7c1c7a49,de96fb50,aeac56d,30cf3ae4,8b2e1cb,1b9fcb6a) +,S(168ac250,d23cbce6,23eeda,1389e261,c56bc718,4234bebe,6b108bf9,bf6df45d,add3ffb7,b0a9a860,21ca51e2,f3d2e2d,19206bad,78d9e661,2895068a,c880fcb2) +,S(47bae439,31966a6,984241b2,2afc8b86,94db88c2,abdb1737,728e1af0,e3803968,a7cb7d64,a07cd13d,2c8dc7a7,8a7a144f,8edf915,5cec20af,102260b2,d8d355a4) +,S(76e73a26,730b1444,8ecf60e1,3489de8b,93355af6,8943669f,20da17f1,4f04d517,41f75520,3d5d528b,2e81bab1,9ce8031b,bf9c73ce,7927645d,178ad762,669b99fb) +,S(f6f08712,d85f9219,bb475122,1ada6a75,1a8d4758,f5dd72f,f5231d56,e634c19f,d72cfc42,379ee25,eb0fb134,338109a3,7752fdd8,1ad102b5,f365a276,1d133f10) +,S(1acac95c,9b0ed53b,e6c37d03,7d47a796,2a371caf,cede380e,799d0110,b0634f7f,658c6b74,44846952,93a5215c,63695a5b,fc80f818,633e0278,f6a1193c,6d441bc1) +,S(5759a8bd,ab76d449,13258631,68773369,5b76d2da,7b1e4004,1bf99198,bb25f218,15c1dc97,8ecff6f7,cfd6cbb5,44ab8666,83127b41,951c247a,f44855,4afde3cd) +,S(cae1e14e,c28ddbfa,379a97d0,5f3ae379,3771750f,5a9ec743,2039f440,8fa7e2f5,eef09268,6b9f60da,8e64ae64,8f13d01,8f7b9ef6,aa849f9f,72df2f9d,f80fbf60) +,S(9aaa132b,947da7e4,9c1de2ea,ce06e3f9,ccdc37d7,6d2081a,be5f3a37,9b0756a0,e9bee628,d6a64476,af601737,68829c11,e8646e8c,beba7174,806d800f,56f6676) +,S(f38b62b2,4d609d01,70cbe85a,cedde44b,7a766a30,d8b7db6,8d935735,c4d0d204,8b61a5f7,e3caa2f9,17ef9ce2,c5eb2499,667558f,7c4e4e84,2644dfdf,a57666c6) +,S(25c121fc,74c57f34,29a143,8ff3c47a,f06b5de,74c4dcef,4a093b87,3a2ab659,69254121,eadbd76f,289cbf3c,21cc96fc,436ea33,9ccbc8e6,fed92b2d,331246da) +,S(95666156,c40929aa,8a7ca656,c42c64d0,e24c3789,ad3781f7,9e2a0ea,c7ab9c1f,116f5750,7e07b846,92106d6b,6976741a,59bf7cf7,909733e8,e1fb54f3,fd77e783) +,S(cdf1c010,7c48b65b,c001df94,c6e84d12,d8885af5,820d65a5,4e7ffea1,ef4c0081,8f3d1be4,206bd313,e1c498e1,5e7a9995,64312ea5,aa823196,9c566349,9c3a04b8) +,S(955269f2,be0d5e20,5382b2c1,959103fd,fa2c2386,9bbdd33e,a09487fc,294dd1ee,6306a092,4ce63798,41b2d773,8cf97ca5,e259f81a,a67b1e0d,42903f1,beaa869e) +,S(78013976,449ddc23,4d32a793,5ea525d5,9afa3617,47e0a8f9,c8141d9c,2b231e14,8d28142c,bb88abfa,1a72d583,4e509d69,3cdee0d3,bdff4788,83618ce7,a1ace69a) +,S(e6d67a8d,fe513147,2c0fe227,bb08a8f2,25e2606e,23672969,ad3acd65,155f972e,46c8695a,5b9d931b,adb568c9,d3f9a8a9,dd501508,fed00c99,5159f518,bed035ae) +,S(1779ea78,eed6d974,563cac2b,b3e72693,409b7029,789e0188,d061a182,3f18e962,82590ffa,6b9e0e13,d2e72bef,96d555df,9f7d2b81,2423a947,e0dae41f,91cc0722) +,S(28ec208a,6e929f8e,a815fc17,7b927086,7d482547,53ba5c3d,3b56fa91,acbb67d8,b4453dd2,eb964348,94cc1cfa,25616a2e,2f0803e2,8796206c,dd31ccd2,dc69aff6) +,S(c218c6d8,3124c9d1,c988981f,d4614af7,ff85a572,dd89e4ef,6209e80f,e7656de6,7259c421,45ef6e9b,d4f451e6,e2dd226c,2e750650,8ff7834a,965cca4b,cdbfede8) +,S(4c9891e7,5559d993,536fec73,a433006f,4f0e4e42,f427300f,7a3825df,85b1cd9a,7463ce1b,9f9af66d,7a5d2d43,ab0f09ed,186eb132,92c75431,ccee645,4280aa2a) +,S(a89fcff0,694ed82d,537399eb,b59a054f,f43eb74,f8e1fc95,be0c03c5,9889c931,3ef3c627,e3011b2f,38d596d0,8ded759f,fe30ffc,9db95356,4e01c8a0,2949ea1e) +,S(a8b3ef89,561da88d,ca9890d,5e4be652,8a4b8fe1,691d1522,54bcca43,1e7ed801,c86fc397,52254f61,88ee5128,4bd54347,8abe7390,c784b51b,6d41c947,5d58bada) +,S(6a2fd5db,da9093c,2f7c7ed8,9eeeec7e,efd7e759,eacc2946,5d1f3a15,baef5b42,8b71ac63,3886ef25,74e212a0,499c34e2,d2c7c1ee,b70fe7f4,38e08914,48395e4a) +,S(d33dada5,30626dc9,1d23d16a,620dbeb4,7551ca44,dd6c8b18,fbf136b3,1ae4e097,4161f6a7,8273ead4,443c93f8,2562a29,1dea1adc,d84ba0d3,75a997d0,f07d4ed0) +,S(53ef9ef5,731d9473,93e70829,bcac3396,3b7a597a,1f3c861d,401af7f7,fb1559d0,8654f8c3,63e53905,a4d1e2c4,378fc3b5,fd5ffe3d,e7fd3adb,399d883b,3d1b9e18) +,S(5f13c5af,6979832,da1bd43c,4b7df970,1ad837cd,e59d8f15,381858d6,6263b0a1,3b0ec16a,1024c902,666dca02,4649c110,2a17205b,e4ac20df,26ce5b92,8baf90c1) +,S(674b7de7,f65337a8,c66dbf23,2f86d6a4,feedabbb,b71e83dc,fd854926,86f14f86,e3961790,a662c6b3,70460e16,18ce3b6f,42bb6142,78fe9e2e,6bb1179,181c2aae) +,S(291eed8b,47c3e2f6,b3c2967f,76743708,5c460c5d,d5d6a75c,489dcf0b,4d98b8eb,e19a9d2a,72fa37e1,e10ec853,9c772565,c53e36e9,160651d,c2a8e364,db408ef8) +,S(e737a407,1bf4fbe4,ee5d3d74,7df3cb54,cca38f48,f977919,907deccc,7090ee3a,ac66d422,79441d73,2809d695,68f700a0,3fc5be05,8241da39,9be3a63f,8da16069) +,S(67fb1676,7c3231f3,428b39e7,bdd082d7,1194a51,ae99a7a3,6c113e87,d338712f,38c2ae1f,afb521f2,279aae5b,6ba5c636,1dd34c04,a7726555,acb9265d,31c996f8) +,S(9b3b4788,71bc413c,5e9d2b9c,61e0cda7,f2fb908b,805f3370,45639,5e616230,7028b68e,af818a13,d32f116a,aeb0bf45,215d3d62,6e6ccb1e,a901544,ef1d696e) +,S(63193415,59bb1e39,2f92dad6,e5f8576f,7f49d4d1,439f4f61,a6f2be0a,75bd99e6,259d5f21,6c780a8a,5bba3e66,2242f26f,1adef829,a535dd97,11f8e786,f0a57932) +,S(4163082b,7720a8eb,e881b398,dae059ff,3a65fba7,f8b93afb,6e3dae6,6a969c79,3939395,d8e90807,e77e87a7,4c89f861,c689de81,a37caf6c,32788310,7b938ffc) +,S(b3a6baad,15c01677,ad6bed54,ea5ee415,4d0bcb7e,3ce59f17,7ff26,ef23b82b,711681f2,1e56c0c5,f2c2b011,dcf75716,300e305c,110f4071,51d11890,25bc4760) +,S(9011d111,fcebd882,b9a228da,fdee1297,824c4007,7d5ad9bd,59e603b,43be8f52,d530102e,aac87930,eff135f2,e55b5310,7c03ea00,d24f1201,6653e3e5,5d778246) +,S(d50adaf1,d68a746,e1e7b148,7660e90c,f268450b,df460d52,e1f761ab,bf7018df,4ed454c4,5eb30cd6,e6f1c4d8,7df2bea,e15ebc07,e4b4e50a,e4dea733,93abcf8c) +,S(cf886295,d1eca9f3,4c95acfa,b86a5061,82e30324,ba5b495c,70318cf7,9e910d70,59bb7068,3147c26e,45c76e7b,e018e467,1f47f488,2c044484,62a5053,8023fd40) +,S(38723d58,ffc69ea0,9a8f2655,dc225da3,78b9224a,f8d81e7a,bf8f29ee,292ddd24,c41d67bb,e699e504,3198adb8,ff11a5e0,4033b66,98d3ec18,256bab11,93db5535) +,S(5b41d5f8,1e2443db,d13521e6,e7b7fdf2,4a226cce,f369279,22b353ef,107f759d,8ad730a5,bfb9f01f,853434b,24866a49,912fc756,e086e781,a07ff2e7,98ef38d3) +,S(4f3c24c7,7dc7e41,843e9018,400d3bc7,5d1dc958,2895c11d,3855b80f,4709373d,a485adae,c547a5a4,e0695913,c4c2fb5d,ea16a3c,5211c162,4819d704,5b0d8d6b) +,S(f603e0c2,8b40c8b0,a6a0378b,c4289059,5a4cf4c9,2b74199a,4e4e231f,a6b458a6,a73aa12d,76572041,f01c33ea,ca599a30,9ba0b838,f1d67fd,67a9a5d5,c3ffe258) +,S(84ef0a98,229c7af,9404cc25,60f4fe1b,4c8e66d9,1aa96118,53fc4f25,eac78a61,653df937,3640b28b,2c2c4061,1d79c4c4,a2d577af,b572f5f9,e50cf3fd,2b2dbcd5) +,S(e675d998,6b3bcd4a,d098ec95,c386be9b,4e96e448,ce6c9371,15c5dedf,d97941b6,4319799e,c4103d65,18590091,e333cd58,9901b020,a62565b7,f84219bf,e31003fb) +,S(10837b33,3603f33b,e528f391,b5b672c8,93fbd813,99c5dfea,f6126e6c,2a2633bd,cdee9534,2456a261,8a293b49,d91ed2ae,f620addb,ed83fc66,d169da3a,a6d0e2f6) +,S(4cb1ddb6,6ad3c1b,68c6b0ea,408ba1d7,dafdbe54,89c22d47,7a62dcc7,77a8e013,6c005484,29e789f7,5c34d8cd,a473270d,75eb8f1c,3db13856,87cda96e,5cd4b370) +,S(db72d671,ff3e0102,b1c52481,b66ea142,8f7fcd43,15e2792,eae234a9,291926e6,71c55f71,68a088f9,980bdb6b,79b052d7,4edd0b19,7ab7359d,9a2f9ce9,f1c5a5d9) +,S(99f92125,162e18ce,7493e6e3,91cd06fd,681371b3,2e147ab0,24ae3799,15f586d3,9286b3de,12ee578a,12ded341,75bdb712,d939b7e5,555e86c1,82f1f283,3c1b1d40) +,S(a2b8b63c,8984a666,2b09c18d,b2d7f263,796660f4,3bd78eaf,af7c63b,986c92d9,2003787b,2af02879,642b0a2c,f716f4d5,85dac86f,e58c7d41,d1959763,310a67e1) +,S(9292ef40,21bbe6dd,8c26a862,c9b7da54,4292e479,a9e89264,618e3a47,9773b446,d1a51e4,65bdfdd0,dbf74fd3,d449f6bb,ea862eed,ad369c52,34a695f1,d229ead2) +,S(8d5a920,547d838f,90159068,ceeab220,cc6aa126,d423edd0,2e136cc0,1cea5d4,c3334a69,f7694e9,43ccb182,2caf2abf,f4caa83b,a006af52,bc010bab,8710b596) +,S(7b62f4a7,7b79c09,76dd2f74,4ec08d9d,21511fa0,7891ff5c,52b8dfa4,ae3430bc,70ab2073,cb3a7cea,350e6aed,dd0c9a6c,ff8e02eb,69bd14a8,a09e9b8e,ccb19a0a) +,S(e18a9c02,5829b47,cdd34c11,f97f2edb,a7fb9b9d,fa4777a6,dbdc3cd6,85245b12,7386fa51,881fe49a,adbd5327,8d6cd0c5,1063dab0,aa830b7d,88c7a4d7,9998e743) +,S(ab9b68ad,61335dea,767c763e,3294d414,74a6d4ce,e4ab9a78,7fbb6749,7307d0f,aab48fbf,53f365ad,bf94f823,ea973a25,f6ddd341,397bd81f,8e825f60,c916852b) +,S(3412531e,8423364d,8d8bac05,bb78973d,7b8d375a,9e52d81e,bed48027,2abdedeb,1b9f5eae,59ea3385,9de752f5,db973a86,4c735e69,fa8882ec,e1ca8350,77d77335) +,S(6a6425bb,af9f65d0,1a401330,46053b50,7ac8d45a,77b30de3,69eed52b,956799b0,7cbdae81,93368c60,5671ae9,faead4ca,2887bd8,9a06062b,dd6707fe,f849f484) +,S(87860648,af9ffbad,50871c2f,29bce0b3,e9693835,8a067201,5c1156a6,7107a4cf,8660c0d8,f1aea58a,c613f6f3,5b27baf5,53835493,fbc0e203,f024ee36,27bbfa53) +,S(35733610,71c55057,5392c685,3cadd8a3,6618443,d80b3625,53a2f197,d3c52539,42935628,adab5bd4,e0aad0dd,a7d76627,58524b2f,34ded1cc,d3e44249,6d213630) +,S(82d21949,2fd48d51,65bea027,6ac15cf5,d27bd736,45e03271,24f0f689,8a2f4a25,f13d9063,fed02a94,1b4e5c67,f42d82b5,33f18ff9,ca4622f6,79c6aabc,ea454c21) +,S(ba1a1c83,6dabf825,e517ff65,549e1d5e,729944a1,d7b17cea,aa4466ac,39ec6eba,f01dd751,3557249,d2fb224b,40ea19e0,57b4052e,adc46787,af587ad1,458bb4f0) +,S(5cfeac36,6bbe58d8,45a36cd7,de6601c8,56943a07,522364b2,23a1718e,6df8de8a,6651d3d5,a344af69,25fe039,c9e29e77,95544b96,66752f4f,c9a3bb57,c5586c32) +,S(e5e314fa,2b2bb630,6fc235ba,cfd356ae,bbf88bf7,eb039629,165d8651,c0c7d5ff,c727787b,a63cddb8,feef96b0,2f6c8d0c,9722fb4c,6274e034,32d9016a,eb4d8cb6) +,S(f84d8db4,b745cfc0,bad4844c,b5a28d7c,80ed5fe,6baefda4,1d9cff9c,158c7ec1,cbd7bc36,a8313a27,feb8121f,a8847bd7,937fa53a,d56ea066,fa600411,d87dcad8) +,S(8806a2b9,d72156ee,4948e86d,43f4b3ac,cb24529,e1b2b2f3,5ff94812,e9534513,aff42464,773f6535,b4dc5eb7,76a3f7b0,7bc2fdce,1413587f,c4055cc5,afca3129) +,S(e2ddb5ef,a1105437,b6107305,bc715e55,ec0266aa,a0ba1bcb,e12ab801,45af7eb2,43e4d056,804f229d,da5a1efa,8f429189,6c9edf94,fba505f3,1f22b511,8b698ba9) +,S(636f32ff,ea843368,c0cb708f,43841ef3,20151e39,35683ebd,bb1f476e,af2f8c5d,7fd53321,517616c,c7d24b51,851bede6,b03c50d9,82269773,dd51e36e,4898365d) +,S(bbcdd1f,f5b47391,d728a06d,b4783d5,b0e279cc,107488de,44446e36,9d11d143,6ac7dfc6,47d25b37,7281abf9,ead782a,b5f815d7,b2c9f6a8,46a8a6eb,9253014e) +,S(af0ed949,22336a4,337e9c01,53357e02,3d7a2728,3c649712,3e117944,39ed3577,d8b9c03,958dfa89,ec2105b1,d9542d68,568797e3,7df16cc3,861627f,298f3359) +,S(11ba75ae,db365552,b0d3f938,f03a115a,544a0818,b2f54f50,e4873249,6f80ce13,a6bce69c,f9838317,70f70370,7073e87c,61b65c0d,bfd34dea,f0c549f9,c58e674f) +,S(e7560fb5,79e5ca35,f45881db,b05383f4,c5536ea8,a5438fc4,ec198ba8,7543d3ad,ff48d1a0,bcf5e510,9ed50a0d,ed8e5b83,44da25e1,a1a3d421,606d19f7,e28fe79d) +,S(ce7e289c,61f4927b,bf933eb5,193fd2a3,a0686435,80c8f235,1e24c33c,e418cf10,17246f2e,e87f4ce,f1c8596a,ecdb1f95,1407ee7f,dd839c9,98102344,2f4dcbcf) +,S(b765b875,32ba4db1,211c612f,b833ba18,156fa0dd,875aa61,df1ba9b4,7d1c405d,862d28f6,d85a8ad3,bebfbc82,437404f5,2e0abafc,64369b51,b75364cd,c827171) +,S(400560bf,d2863ea,2bd9e246,4eafab2c,2798cb95,b976c022,bb9d2153,e5978a0,92ca9a1d,938e53d5,d10f1f83,54abe43c,e8f8c2c9,d4e851cc,a363ed59,71e2681) +,S(7859190b,8e619c98,76af21e9,64f323e5,221cd4c8,83dd9fdd,e56f691e,e3db91a2,e1874376,755165c3,72abd73e,415f2663,bd94cf28,2009492a,e5034da8,6f6bf949) +,S(87d90b40,bb472b84,f9d24caf,ba7a6437,b50febd9,5c643aaf,e235750b,12527ef6,e6a0f719,25697425,23517ea6,183faa64,dee1ef63,183ab1e8,3a603b98,20452c4e) +,S(dbae1ee5,a1b6affd,f9b41ff6,a1f2790b,2c492ce7,53865690,ce5281e,a7f08177,f6a2be90,a2c3cf,8e14bf87,4cc52648,b60f9a26,2930f6e8,9fadad4f,d919db6a) +,S(943a79cd,88260475,10d90c99,4d8d784b,32c03d1f,f2478102,96125f7b,28576216,48d4477b,f97c4cbb,4a96ff99,e427d4ac,cda9a367,2ae66930,88d8cc57,3bb3e2d7) +,S(699911a3,81ff3c7e,71b3a458,14133f3c,ec644378,e3244d66,6d083c55,7b6c040d,3eec684,3190d6f3,85b07116,b3b1ba15,4ecacec0,63e02933,9b83afad,5598b22a) +,S(f002302d,9ca256e5,cc38ad82,e529b461,efb69f28,52513917,fb8d63df,45e602ba,78455ea9,708b750a,97dc74ec,8939c880,d76010d6,78e0c112,3616483b,fb4e788f) +,S(5f701ce9,65a20314,a65e2c0e,1cedded9,ddfc9d01,41a1e095,e91b9915,cd2aacb1,57e770f2,d04e33ff,c9d7807a,4c3d1edb,3f9ed2,c19771d6,7e85e618,463e5663) +,S(454c122a,ff85c42e,49d6f033,87744462,8acfed31,90c41255,e8e34928,83563fcb,9d9d6435,a2c4d146,d92f34cc,40b32a7e,55584885,82143a,52039fd7,129fa6f6) +,S(d9abd19e,81f392d8,8382918d,6ab3f89d,de793abe,2eba3aa7,b58b0ca3,1e614e51,8c1a0f80,8b8d9e56,aed21554,95f8902e,a390505e,15cafbc4,2b71cf05,575abeec) +,S(20779414,b5ed6524,b3613a8c,d0b6e9c7,ff3b14b7,7264cb8d,7b266ef6,cbb224b7,c1437dd7,71f46cc4,3cfa52a1,28c70367,d6682553,28942150,c4068da4,8c218d66) +,S(141739f8,503f2225,feb40431,21f0a5ee,844a7707,62e37d1b,3e43fad0,81c631b5,a0a13de0,10566ee3,1af8c6e6,38411c1c,a3df6c63,c8ed67da,8ef7bd19,5fd6e73f) +,S(de8d06ae,dd58b148,91184145,fcd9bc64,634725fa,e4a77d35,70b21c8b,77890b60,a046f351,eccab99,1d3d1c1c,642387fb,fb9c3f92,75bbb93,46688555,f7aa9460) +,S(312c7ad1,53f7280a,9bb86cab,ac573944,d271bcfe,bd59291,c6f05fe4,ec003a81,3c6428db,5eea01c6,9fa2556b,1f20c1e7,4e65629b,e73e6429,81b971ad,b6563866) +,S(2eafa04b,d276e33,75b8d063,b206785c,ed69f763,7a5a8b99,ef7d3de,bbcaf35,f06464db,56ccf55a,1f41efe4,d1cedf81,a642da24,3cbe68eb,6ddf7ace,f67dac6d) +,S(5873091e,dcc8a95c,a0a47570,3d88e54e,1381c2d7,a418f615,eea97470,2c2c6fbb,5a91598,b8e47d2b,2fee6cdd,c33aa309,9bec74dd,21688542,9b76543a,c233ccdd) +,S(e713bd84,ca505ad3,aa022577,c0cac85b,466874a5,b02f4ab9,e8d14bba,c131fcb,706dab4a,fe49e6cf,d290913d,358d1dcf,62e8b4d5,b9bd46a,322ee4a6,5a660849) +,S(aacaa633,6fe86d41,b05feec1,cf4866d,340fd268,f869f912,c2373e10,bcd95340,d933cc5e,c01024e4,77d1e80e,c533f293,e4fd0dcf,7d1156b8,7ebd9d81,b9489c57) +,S(cbe0ce9c,77649031,25590e03,cd9643b5,dc45ecc,604d51fa,d5bcb8a,196b65ee,d2287fed,c331d56f,e585bf1b,793fd957,ce425492,df41d8b3,4faf84de,c3bf4d22) +,S(f9990413,deca9f9a,4ea6bb8,fd9b8732,57d15ec3,70e98187,f4170103,dd416dfd,b0593cb5,dbce573c,f0a75f2b,c4756781,963e1a2,e988e0cb,23efbe26,c215ace7) +,S(2ee21d79,bf3e82a6,2bcaef34,85276c5,3b51bfd8,becbc9f9,6ad316f3,a74bab97,fe3cfa79,b208de80,f659cb81,bed12184,ea2c2524,dc0bea05,64acefab,1acd8fb1) +,S(af5c91d3,44fccd3e,70345a2b,ccefc0d2,19287be5,aca40ebe,e61de522,56f25faf,bb58da83,bebb5346,9b345695,fc23853c,bc0221b8,5d75ced1,da107fc5,c106875c) +,S(2cf50e13,477d628d,117e0bb6,1d3ff9e6,1108fe94,bf82a6f2,4138a743,6077e0af,339c0a53,77a6465b,29377e1b,dc344464,875687e2,7d1f392d,96a275a,e259793) +,S(c51a6610,1522f63b,84b98ec9,31984865,eb3b29ce,fe115b28,a87f89c,67bc441a,240b9717,6af4beb4,b0502d7b,2caf8c7f,47a9362a,9f9610c5,826762ea,a2a2be5a) +,S(27478eb7,b14d84b0,80426792,b0e2e510,8a4804e3,a15e80b9,c430d7df,c09d05ce,eaa0a072,86fac65f,3da47bfb,4010fed0,fe8a9e17,ae42ece9,233c2078,2b36422d) +,S(531ca72,e21caa6a,43f0c9bd,d0bbca5a,b12dfb9f,70f045b2,f0865077,cdde192b,c4ed88b1,a0397589,3cb14ed0,897d6bd,783dc647,ba59772,16c308eb,630367e8) +,S(295775cd,950d0702,602278a1,56c1d05e,4343474,a4b3ae87,63f4a686,7688e42a,907fa8f,1269cb64,41591004,f6e62b14,4d6c54b5,f6ed424d,6b0a8a75,26935b49) +,S(e88425d8,bf6e89a0,f9c9f525,97eedd4,3c331058,10936c23,4da69d21,9a86f82,56d53ae5,e7a354d0,d65cf742,d603da2b,199e147,3d42bf3d,639f83a1,cf91cb65) +,S(4d20a032,c44453f7,b374a82f,f088d816,c1fa9338,57dae8c7,b87295,98869a4e,a7ad5993,af43cd42,1620e87f,fa0b3305,e7da39ef,704319f,ae5faf55,5e3fb43c) +,S(b98e9728,e9288607,a7ed6df9,c68749e3,9d7efa1c,4f964428,5e9bf81e,246e936c,1620c470,19b9cef8,7c1f0612,cf56adfb,5526573c,f7746a98,48a0d40a,3a92d38b) +,S(562eb109,e9988778,bed85413,2fa7d086,6b37a8b,fa2d2d3,470da3c6,97996a48,29f4f0da,e554e380,613156e3,34207e6,fe8fa678,4c08f2be,c3d6a59d,1e0941b1) +,S(b189e864,8dc0ee06,b09ea73a,9a01cc06,b6fa74dc,f626e41c,ffad926b,901ae851,4e42c870,3d04838a,9f0682fb,bc13c849,a515d5f2,f248f393,e2caf0c9,b6d61d0c) +,S(3894cdb3,425c618e,1da2c6bd,1177109c,49362a4f,24030692,244bb0dc,27af6913,20c0021,5c72939a,497f08f0,bdb03493,8d04ddd4,8fe8f3f2,97dfef19,ec9397c5) +,S(394f74a9,9146fd43,9035266b,ccee72e9,36ff59cb,eab7bf4e,925c6363,fce7d4f0,c7da15cb,c1cdcea3,21efb1fd,c56bb3d1,2bda06b9,993b6f5b,2293e493,5aa3e5a) +,S(44fc66ca,d6e67f97,be95c667,fd5dfdfe,dc82edba,35df2bf4,737b3ba4,14d15c27,9c485757,351825c5,245c6eab,2ec4a51b,ac60c9db,fff7988d,8f28728e,60f418d) +,S(fa355672,d9f7a1c5,30b2d76,f183720f,e50840cc,ba413b64,e449d2a,8b0518dc,63fe1c7f,d97c7744,35613167,660926e3,b7377fd5,97dad03c,9debba5c,a5a76e3) +,S(7325c269,50f1bf21,2f9cff6a,170e446e,62dafc2c,f05dc50,4eb951d2,6322eefa,5f8fa04f,ac5232b6,cb553630,5a48b647,263a57d1,2c485363,6c930497,40965f00) +,S(7004b364,c89ac7ba,ad03a03c,c8e2972,e5fc52c,bc656165,e08df216,afa216c2,971a4284,80556797,ebea8b1c,b37de6a4,1aa11abb,df9b28b7,7f50d362,b6554974) +,S(ffd45087,eb9308fe,e7644817,9406d9b9,77364732,f3570ebe,80a4710d,a0ef292f,f4ae4df0,5af2ee0e,456cca0a,2c9d93a0,83eb9751,a09c2f8c,5bcefce7,83764ffc) +,S(ad899e8b,a7aedce9,e53d86ac,5ca15408,140c8f1d,be3ba4a4,275f332f,b0320572,a914795,bfd9850a,24251eda,98bced8f,2e2627a7,8a1bf6e2,8b66ffec,f11ea105) +,S(7078718d,e94255ff,ae25f1df,4ec2ad90,e59ada11,5ad4a6dc,8b305fcb,93a1114f,ee736453,927cd7ed,bbb55010,32eaa95c,c0f6bb42,be77db4d,62b77650,1094ed7e) +,S(30858d4c,d39abb36,51b8d35,58800c18,5495bf31,bf23dc8b,176c1f04,171e304b,3aad8415,4abdfbb9,1eb95aa8,4e7ace9b,fd8b5f6f,cc8ea08b,e094c874,8161f85a) +,S(c06d6d2e,5637fd7f,df08b41e,5573478b,eb19dded,ead1f0c2,9309fd59,9551c787,78cb2514,37d4ca62,91bab9c5,57e88244,edb9dc30,fb1a6441,78217039,628e1db2) +,S(2f93455c,279d2a26,1cc7b724,4c32c853,459e5d99,32692fd8,ffe7ff0e,493de2c2,455f0902,74d698dd,a1a97586,fe797421,899f7c22,60ef0bbd,db0664e8,fa323156) +,S(c00c345b,b4b53f5a,5dbc5f10,597dbad0,75e28162,32e0ac71,fd778c50,20b663d5,c30f78de,3495063e,ab98f001,83fb4bb5,5cbf58a9,1bd52ea5,36a4a38b,cfe89288) +,S(7d78faed,f86a22b0,14e86e1d,f98d425c,fe2e65a2,39b37994,ab25a4d8,5c863382,cffee7d6,5181e361,679c9d51,feff7a36,e8d84282,32e752b9,62689eef,a1ff4441) +,S(ab492cb1,da2e8463,a2536c0c,7cf143a5,9626497b,23d4c179,d2af4cc7,f2b55866,11d4205f,55a74f81,e9512496,becb61c4,6363c42d,baede671,9bd7f2f9,3e00b14d) +,S(d1a3790b,478bf657,360b3459,555e1dc4,ece339d6,93b5b51c,8a3af121,79578688,c6028991,3ea89956,802f8b8e,cfc8dbc3,5894846d,1aba2074,9a55153b,83f73891) +,S(6fbb6fcd,36fe0388,a4bb648c,95a004f9,b3c64e4f,9aad672b,42d8c649,4c0cef3e,51be473c,74ca2609,c3b79c60,2fe90d98,62eb9d14,b9e52aa9,ddde106f,7253da44) +,S(db150ec5,680299af,681ce826,794e4818,c0d6d3d,e3c392e2,79ecb408,aa55b243,15e47cbc,1c4689bf,fbf7ef42,1db5c57b,e3ab8c16,b69bb518,2ed8a1cf,20067de8) +,S(51ffc919,afe67f04,a889323f,4438da99,72d2161a,54f9e81f,aa1e644e,9cb88835,e4b579b7,e985b38b,486d0600,3f825538,52a9d0ca,b8fc98d4,371a7e33,4898742b) +,S(fc86c54a,48052ae8,d8480235,e4dbb7a7,6d05d830,d2c0cbbd,297db0cf,3d2d6cea,6cd61522,e2a22531,da973c1f,9cca1c77,98ff66a3,8f568935,e378f73f,9f1d7dc3) +,S(d440de01,20d619b0,6add3d7f,66184864,5754a424,f4b1054,479a83bc,7df0db9f,3f09b245,91124175,89071c56,84215cde,a6999b17,b5b2f664,6074e7ec,6c38f68e) +,S(f3310bc7,7556f234,e7c83d69,48afebf0,5bd91a25,b516cf84,60d0d6ec,8483fefa,1d10f23c,e0e35816,6b817553,cbae0792,9e34a4a6,ebb47186,1d401341,1ef2b3e3) +,S(ea770a59,e88b598d,493fc75c,62eaa9e7,485271dc,edeb1d2f,76df983e,54cbb51c,e2a4baac,96c9538,3de82a29,5bf3cf30,53bfe2e4,6fb0861d,65c60c09,978601f) +,S(2cd56ef8,6fd04d2a,ed4f8520,951798c2,a1c69a38,8e635a2c,edfeb08e,3af0e331,3b9de80c,42e0c683,85aecbd9,c8775b56,86a8a376,39efd24,98664343,e712707f) +,S(37bb0206,c96d8fd4,5315e96c,860f5cb4,a44d2b6d,af17844,bc305b4b,59c9c649,c77b4a05,373c42e4,e071090a,7da9b4a,4ccbbeaf,d399496d,f6fea1d1,a83808b1) +,S(55fa08fb,f83dab6e,ea7034db,15bbddc0,ab2b472a,b29861af,543a970e,d16033ff,73c8a90a,86542970,4e25f370,a5caa4b,a68eb72f,5ede1edc,5549105,491858cd) +,S(4eafb675,281fe8,98593817,efe128ca,c59fb775,82f6006f,339631e0,6e7d2e7f,41347946,6630f6d3,9fa97404,6808067f,fca9e173,3e1c4149,6567eacf,47a0bc6) +,S(857587d8,375f24f9,e6924793,9ddf3a60,e0469f38,6ea0d55,d990f1e8,4ba5c7dc,1913a118,9d867c57,2f947fb4,3e062cec,3df37c3,e8edc6b1,927b315d,10c37be3) +,S(89e334d8,f71eacef,6cdd0a87,b1e03352,1078a1fd,20dff144,10108202,93143815,8b49aebe,71b60eca,c9256794,3cf74d9,80bb3e47,161b2730,9ed15872,7accd84c) +,S(69902d6,8a4ecb1,d2e496e8,cdaebf94,58f71f94,8f4341a4,11fbc2dc,524f694a,19a54c4a,5de17930,6c50cc03,b0b8d54,b613cd31,6f0bdfb7,851db63a,9c605896) +,S(52f8a3bc,832de46,1bade518,50121b5d,2ff475ab,5eb0e71b,a91ede46,41f0d576,2a946bc4,42f24ef9,469b8121,31021186,5b22f3a,adf93648,5b7907e4,791236e2) +,S(146fc341,4ca1c497,73734f6b,b78ee9e,56fedee4,9487ea01,a31d3e4c,152d2bf,82e21722,e415f5a4,1a076f3a,8324db4,2436da5,a3776f60,b5c6f53d,e5419db9) +,S(9e22043,8458e463,b1bd7399,28200a4f,ef7c3760,a7b6357e,afc29a5e,36b37b94,b1f5fd78,c1c40d98,1473fd4e,72af64d7,7387c28b,7f005191,5ed2587,674877a1) +,S(53190555,8d044a1b,94caad4,526cbed1,82807c65,2bb053d7,61301ab9,68323f1d,ce591f2d,61b47a8f,8707d8f6,a8717139,68ad569a,667ba4ac,f2d18356,ab6d326f) +,S(b93b3c6b,1297cadc,392b0cab,da322a1f,69791a68,b48b0ce7,4352ba3b,b8a3cc8a,136ec007,24fd378a,53d5c573,3aa7a06,15b2fb20,4fed82ea,934bc131,7e7ef22) +,S(62e6af72,a9fcc956,4367d44,c0699897,3674e3f7,b79c67bb,8c8a82f1,6d3f744,4c1e4e33,2e9316ff,24a7b38d,13ed1b30,a659a8d1,8423db6a,af6324f9,4e7d5475) +,S(c91facca,aad0790,886c4421,d28f3ce2,9d64dc87,514f06d,cfe95063,dbbd0e3b,e7a0c83a,18d655d9,7a555c51,4bf8f117,59ce866c,61a7e691,8ecb1cfc,21e50710) +,S(72b3b928,bea91ce8,767b2f22,958458ab,9a23f455,78f836,65c89717,7e7ea502,773235f2,c9ec74e1,c06e4e7f,89247d12,27f303ff,2fa354a0,663791a6,ffa40e49) +,S(1b014ac2,7213cc08,67877fa3,c0c07b1d,91529259,23f6164c,f1d204d9,addd6f4e,e0dec57a,c1ec264e,380909bc,c62394c7,413cfd48,180b1de1,c5440d08,99c67f2a) +,S(985e8845,97e2831c,4ba48888,ac219b3,bd891dc,63176953,4e0d8a96,bf583a83,5afa0b31,1e909594,4b228958,657b95dc,a198b008,6f5cda96,c3e4da6d,e444a418) +,S(ec3cded4,cce88ac6,22315a51,ec99ed3,1ba2cb32,74a43e6,98e033d4,e490bae,1c2a2236,2704a765,252b2a57,aa1ecaa5,4f1c21a5,2d67c050,a3dba077,ad4b4480) +,S(f882c4f7,7911f6e8,64da7cb0,5f09da54,b9cf7125,21504815,e6fdb9e5,73f24be6,9ba4a4c1,e0978ee6,1f83aedc,b1db2193,518a71d0,c112b9fa,59c629cd,d42ebde2) +,S(f06c3a4a,9f1e80cb,e2ee6b06,ff50e447,13d8eddd,5857243c,cd02c5d2,7996eac6,6b38bddf,fccb4888,da20ce7e,495bac5e,7b9ec8b2,2feaff5,8d4329c3,c546e839) +,S(dd1c366d,5be82883,eb86da5a,f9b5d5b2,89de6b9,1165b91c,20ad7b73,ab4de421,19bb181,70b31a81,45232ba7,ed0fa93c,273751f4,838633f3,c94647e2,93c06bc0) +,S(e965c1f6,89b3f7a5,97d23d9f,378b9a03,fb1c6e29,5354de36,a5bfed53,3338372e,d98295bd,890e98a5,9d6dd93d,bd9eca2e,e79b028c,7459779c,2d3fb665,46692242) +,S(4f9148b6,cf21f5fd,911d7fb0,e92132d4,686d3e10,12da444b,f5a89040,69c2fcaf,60e9b3ef,924260db,ad68793a,d684c316,6889b0d0,38474c70,6ca25978,4a5fa7ad) +,S(d9341e6,6a505a91,dcefd533,90abbd54,52b39594,42deef9f,6a67dac0,8faa5e00,eafdc1b5,2b7c97f2,21ba8635,d49b58fd,17cc7983,92e09d13,8c41d679,6fda331) +,S(b948bed3,4f426bbc,e6c24ca1,fd1d2092,1de6f9d9,f561c32f,877a4104,afe81ae6,5cacf40d,f6fba19d,763c5b0b,83aaa284,f9485705,ad882b6,d51bd46c,b12f532e) +,S(73011c97,dbeaca8,8bf04371,311e9558,1e494b73,1778a2f3,cf906cdf,64dd781f,2b5abb31,c2e56a38,e8236f7f,b28a93ec,1bef3fc8,9be46d92,c2fc476c,42ff4ed9) +,S(44835043,1373a095,13f756e7,36ac8342,24004348,70d6cc5d,ba31f74d,565056ce,748f041b,a9c990b7,70c36f68,5667109a,acdad74d,4569b107,c968e517,143499ae) +,S(3463b029,e9dd1907,bba2b582,c9ff1f26,4a5ef4b,40f5af28,2a00c136,97145ffd,9e30bb18,fbb70c1c,edff9065,968523af,33665b53,3f14457f,59d7edbb,d5f07c5c) +,S(5d95aa9a,9fc67758,56e6655c,21a62670,c567e236,a41b523,436beb2c,18e69c97,d6478496,4220cd62,b4651e8f,965bbde3,22aeacc0,6557f656,764a20e4,649a1ea5) +,S(48c65239,d03715f5,71ddc36f,313a1723,b014c047,30cbbd8b,ca9617b,e8fb3874,c0bd39e6,3cc00fde,74c991cf,f6d711a5,356b029,5b6eb9c0,28c445af,21de8325) +,S(67c610ba,fda8dfe6,c7977b70,7a57ebd3,9654c7d4,c9a0aef2,80c896e0,e8134078,c3d4ffc9,891a4267,612aefe9,6c1093f7,8e1b9a58,746c986,c5265381,3ba46aef) +,S(4605213f,4a21b15a,4a471e10,f157d0c3,faebaf0a,f7cd05c5,a27c56c1,88b6d430,9853c145,5f4b3d38,200aebf9,d08f87ae,3eb4a99a,3d94ace2,94331e03,876fb751) +,S(6277ce5d,fb56c2fe,3d32e28d,6754255a,ecece179,70615443,b0d33e5e,b54e475e,dc7a742f,92160074,69d53e73,da526102,a6f68e7f,e8f07a91,98614f0c,17daf06c) +,S(7fbc032a,fdb50898,3270249c,f1a7d27d,198432c1,6815b7d2,c929ab67,bf12f01a,dd696a37,fbc4f852,6db85ca0,6bb498e8,6dc33480,a4f84564,2b49775a,6bf20ae) +,S(dc849e28,6b934ef,30cab6c0,1cffaed6,9ea74ab6,96578027,4c88845b,8ac264f1,6d7f94ae,347b9b18,bfa2bc0,d6b9a8c1,13ef1a70,78e317a2,53f21590,667f4b5d) +,S(e29e0833,7da9e0b6,b6886c7d,fe010cd8,9a4b10c6,f5e4ce38,c1202f59,94a69016,de082f4a,9c21db41,573dde9,d2ca8256,57c67173,207d43ef,e42ea81a,ee812dbe) +,S(407f0e21,ddccb63b,5672eb15,742d72f7,1a522f9,20d04247,3e1438e3,7bdecd35,28d6f39c,cfb36986,351d7619,daba6271,3c9869f9,357504d3,25c112bb,74ad336e) +,S(653286df,15bf657f,1685bb92,98462383,7c819def,84a8c332,77f6d777,4c8dd3b3,c5ea3d4e,f7a97324,96a98abe,f999c25,9a8c622c,944a099e,146c0708,d108eb34) +,S(47613ca6,ca7fe67f,4286f12d,3b4bcd86,455a1863,94f2bfca,e162f991,3bf6ed7f,4409a6d6,2ae63ffa,a3f2be74,e7d0e5e,3ad4704,76282b0,c2919750,72be1386) +,S(8f9bf4cb,4aee791,12162fff,75f35393,509fcd4d,aada298,655bd58f,567e6adb,893c8b52,c2c25f8,e2ea051e,d1a35a3c,8ddbbf9f,508ac792,37e53143,7818102f) +,S(4b25cee4,2f955db9,79c85682,4dae806a,3925a33c,42e6b6b6,ab4997bd,884f68b1,ebe38f45,bfa13922,d3112af9,1324f526,1c5f864f,4d722576,24e3afe9,9eb7ebd8) +,S(a8a40ca0,56b5e168,6fb9a348,ae26b15b,cf812cc5,b9c5abc3,44f86021,69958e81,a55421a9,4f1fda1a,f6d64e48,cee3e4a3,434293d6,b49a5cde,b521c0de,49cd31cd) +,S(1f7e97c6,198e27a6,48ffebcb,55c001f0,d591ca64,77c7c1f9,43928e2d,dbe88dfe,2dcf0a3f,f296f744,dd402fd2,48d29c96,49abc871,28624da,28134cf7,6242e6d2) +,S(7ee29348,7d6520a5,586b3ba7,4a0a660a,a4392e5b,77529e8b,890a5927,aad1ab71,a51d3123,b4faabc3,77bcc565,d66d4c40,92decf92,f63f81d2,ba3a4f06,2a8ea485) +,S(30880ed,b4f5f2d0,95c34730,d10a8c02,11efdf6,784b4886,4afff98c,407734fe,4ca4b106,41c55905,9a19cbaa,bc6837b5,300aa1c9,8b0d8a72,8caf5cd2,914ea693) +,S(bb7ffe45,b725038b,597a20e2,6f67d0fa,c77730e2,4ebadc9a,23afb4ef,a01b4d50,dcfbe717,46bc35b9,81357857,c0b4564e,1ea11852,c5ed8372,bd15eb69,e674e14c) +,S(ddb59e25,20a5842c,62607d4c,6d31f2ed,b79e387,527dc12,5d96fd04,84385e51,2a167f97,85ee4285,7471c45,2c38639e,69940f77,b3fcd54c,a697100,37d9e5ef) +,S(3c405df1,36b1c6f9,99fe0b3,2bf5a305,bfa4a6e9,994a1506,9c5fcfc,318dacf5,ba5ab8fe,43a2de82,ce289cf1,2255f554,d7881d08,a54017f1,e0c84180,d963f3b8) +,S(ed4e6e9c,9d4eb277,73f2249c,13d6fc1c,5c07be47,9ca48e35,913f6fe8,384851a0,8242617e,36b3c298,b13aab58,b7383dd7,93ccd4d1,7787062e,195456ec,43fc4198) +,S(60fb7766,9f312be7,11d0a269,a72a85c,e06b70c8,1d34416f,f7ce1a28,41d50895,ba2097a9,772a616c,82cd5dc7,84585c80,65206913,474f49ef,71579a3f,8cc0d825) +,S(1336a678,bd5d495d,c688c039,a60b256,a09fc946,830fa80b,1622890d,9c8f0881,6d57f261,b1073b42,f6eeb514,58e994f4,7406b3f2,7245a0e7,528748fc,65a4937a) +,S(adb7e6dc,72c02a9,fb99645e,a3695824,db60df0b,f9b6a420,75cf02bc,4e3713ee,96325866,2a062180,20f8b86e,e5ef1e04,57d01fd6,d5541d6e,50798883,9f03b3c) +,S(674d6e5a,6501f824,87efd592,c37bc14a,ab596cec,4d5e6e8f,1be44a53,a9d2f416,e6ca1153,76af0429,1bc2dd6b,2c47a816,c17e0ad7,c252c1d,cdede8fd,c9a18630) +,S(ed73f5a7,93dd0359,68e253ba,8ac4f2ae,83d7f290,24eea4b6,fdc418e2,4b63dcdb,bf687b81,4691d48,5296e192,d5371ec,daa831ea,ce2d502,4e321add,b62f0faa) +,S(601cc630,47ce63d2,c1fbbc49,f3b2dbe5,6edbca09,17ac41e9,b39f7ac4,5cb3ff8,a773b9b6,d98c7b35,458e956f,f9cc71e0,8539b118,bc2529f0,fd496e54,efc2b25f) +,S(a31ffa07,e16fd36d,2edd7d1d,944ecdb8,2da2641e,cc6ccfe1,88219a67,5677a740,c2253d87,59ab43d7,c919710,9e9ecdae,df1f2d82,d34c5d82,d113958f,cbf1e3f) +,S(131060f1,ba302b06,b26360ad,de531db3,422a6bc9,6ca1e9e2,98b5da8a,c8266249,4dae16bd,40159bfc,96665d6a,d64c6c5,3ce90fe0,95a316a6,8cb84844,ec183cf9) +,S(f4a29fd7,90f35f1f,4b3240d6,c0cbb983,3e701a9b,ca241d3d,bb7630a6,da2de25a,b2ecd794,5afa51e0,1caf3c21,5334dd9e,9f9a1f6b,8f35767f,c63a3f00,69c01382) +,S(b30546b7,c5e45266,854b90ba,53afdab8,be115251,5ae22f1b,5e0c472b,a3b44042,f14a6b95,178fbb85,5aeb9cc3,a4e65560,3e8b18c1,4cc54cb4,1e059597,faad7f4) +,S(b6cbbb5,10ff83fb,c8bdd55f,cfafeae8,947f5e83,4cc78eef,dce45dee,2014e175,d0e29276,a14cfda6,f518a3fc,ac6a4163,13666f91,ce5ae7b9,7abfdff4,925cd415) +,S(fcaed74f,19199482,564ce4b0,7e1033ca,c17bd418,769981bb,6547caa3,b61bafd1,c52c08e,f5331ccc,271b108d,5e7794ee,4a493ce4,f6665773,f97902d6,ffcf40e0) +,S(c6d1ed83,29ade032,c9924945,189ff23a,c6b1befa,e4a33794,8b1b4126,6d14344d,6e1c0e9f,da231092,86d23cb3,2c588799,507368b8,8c0628de,b8a79c97,e4ba817f) +,S(ac7d0edb,a7b86cdb,60963277,cac43674,19dc5d85,ccd9a649,bd335dd5,eea2a9e2,61790bc0,ddf5307a,56fce870,4bc9eed6,9d61d857,f4d2fd34,d53a97f2,4c4c5206) +,S(fd9d0c61,d3dc3ff9,bc3735e2,b2c7d5d6,4a740b1a,bcd46a7a,860816f9,84a64645,701e082a,5e59460e,c3e3ca21,40137ed1,5bf9ef49,fb4673c7,4fa5e4ff,2ad8b762) +,S(82ce7d44,87101716,6ee31310,11bdf02b,336fe44c,88572c37,930a33ff,5bdcea1c,d7fdb097,3961ba18,b53b421b,21c0424b,7b4807ae,256d883e,2e3a6f22,9bc44c0b) +,S(5e507c80,bbd32e0b,efc31714,b464580e,f7ccd3a5,2004f2f1,9fb9b0f6,dad1a767,95facec8,a3b5c996,e0bc9d5f,77c11407,d0ee071b,9cf5af3d,ed625025,3aecc75b) +,S(640d6b4e,bde998b4,1bc86fbe,2e981683,a83789d,b71bca76,76715a29,143c9b55,61334a92,358ae235,104aca00,a632006b,769475a,da8789f4,f7047f75,c8b1123d) +,S(e951dbb6,96ceb16b,6059c3ec,9d84ae8b,8adb146f,fd79a323,59c04677,aff990e,d3443900,ea47be0e,10ea9178,3f1524f2,fe5c5720,efb62458,987dea0f,1612a94e) +,S(2b601b8a,550333aa,2a0e98c9,a4b28043,aa38f20b,13a72cb8,7a8cf212,cd0a2a92,2f3f309d,ff296fbb,a406602b,be72d9bb,c3ca0578,f5f0aa08,6e65ec0d,8989f670) +,S(d803b242,9814658d,df7cb378,bb9708ed,6ddd7270,ffb7d712,b64da007,158a5add,bffd353d,c4d664f8,6d7f150f,30e44ace,fef4abe3,83f30369,15b4d5d6,5ba3c131) +,S(d5a8348d,fbb9f9d5,798d7d1f,3515e25d,a2707869,26ae598d,500186d8,a284e86d,ce31c62,19960c61,f2a8a7bd,2fa36f0d,6ea7838,5463a4a2,9dc1ee95,2f37905) +,S(250dd67,781128de,65f0529a,11b2405b,eab01ee0,1e9bde06,cabcc9d3,cd038065,524aa9b5,8dc5c6e0,6951aa70,c4bfdffe,a2dae26c,1e8341a,5f63a180,731a0dcb) +,S(f3a2017,127dab2a,917dfaba,5eabb6da,bebe554,431e796f,a3b09771,66cd47ec,69d1de46,2e63beeb,1334fccd,ce147b96,23683942,21c4865c,d50fd687,5c1659c1) +,S(15626140,5aabf9f9,d7dfd218,3d7fe2c,900ee051,784537b8,deab8bcf,20c6e0e,863d8797,f2b20b0d,ca1a5b93,9a43a712,4d5f0725,8ae7caba,4b76d308,65f9a98b) +,S(3261fb49,2c55978b,20d2c5b2,3e6ac5d9,5e3b40a9,462b748c,62a41035,2efd227a,4072fb7e,3fafe456,8f62f4c9,83d0988f,f9096c14,317f7584,9fc1aed1,3e39708) +,S(2a5e6aaa,f5cd7466,b851802b,80305dff,3e655dd9,b0456bfc,fe704eb8,582836ac,2e3894d5,762e70d0,4d3595f8,83dbec7d,5125720,c516fcd,f361ab22,be67062d) +,S(e85a7e08,13294e2a,6eebb00d,2e3fdd76,318b7520,dc682705,8b3e923d,536cbcd7,5a936569,77b89e9f,10c4ba6b,7dcb1611,fb6a85fd,af0b1136,b19cf222,a2e9a477) +,S(8e36e66d,2f080ff2,a24ac836,25e50148,e5017b7d,b898820c,b7d73214,bc198b28,edf99b43,c2b976b1,6eda2a75,f8bf5aa8,6945d700,9965b528,bb78b530,3888c56d) +,S(99ead62e,11cc613f,2290332b,9d5ddb98,8c121ed5,21a0147,589bbfe7,db0f0c58,6e73b10d,bac646ab,44f3a062,4150da41,d666523f,ed55fdc1,c1146fd8,c4a262a7) +,S(15e233c4,783fced,39c74cb4,34e77491,83004e2,6e16c372,f6f7f23a,e30efb13,c9954660,eedf09c3,af8e1642,3b57af59,227ee5fc,e1885837,5ac5a853,34fc5034) +,S(3b33e0a1,254d310d,efbf526a,8a2314bf,18bb490f,e592e36f,6763b174,96f57a67,e4e6a395,a6e6c730,67fb2e0e,2c5dba63,9745daf8,bb9d6aab,e96f59d0,8eb24c83) +,S(8be3fe6,f3e45fda,270d54e6,49bdfa8c,1dbbecf6,35922aca,2d605c66,6933e859,10269847,15eddf7f,b7b23972,ed1f6fd6,882481f9,1a12eed7,f8fabad9,da0917c5) +,S(ae6863ae,e6d519be,773edc77,8e7bb5a7,5e0d30ca,91dd0920,aee35870,5bf6effc,d104a8c4,1939444a,1a5843e3,92fc5fa8,d2dd864c,1f442938,9dbdb543,415988b3) +,S(58a06c8c,658430fe,e03b3218,6ec051c1,18174f8b,ade2cfb4,a98cd9b8,13e12dc,17f4ba3,da575c84,81cdfc04,25567dd5,1d2b5e94,a8ed37cb,346f88fa,e6f3553c) +,S(cf0b0d64,3843e10f,142ff912,720373e7,2fd18576,1f3d6c71,52647afc,1ebae367,8ed9b909,f4b622d8,cf5d5b19,fa2e1cc4,bdb42133,c4dd9261,22f1aef4,6dac4c64) +,S(8be41872,15902e71,8f75558e,4b1a5ba7,9d3522d2,e8a2d723,f863c4d7,3c4713a9,f7be5a77,6b8ea8ee,1e59765,ecc6a33d,210eadbf,df4c5586,aba43710,49c715f3) +,S(1e6bfed2,36a10a7d,9efd88cf,af1dc1f1,9649197f,785b4a30,c68391ce,808f713b,90200be1,29c5235f,41a79bc7,2d4d10a9,b00911cf,b9f27b5c,6d47eba9,8530b8c8) +,S(97176463,8cee344b,1ebd8c67,17782c6a,86108b76,e1eb74a0,791527dd,b18e14b5,ccb128c5,2295ca09,626ccd39,b5827ffc,3168a628,6633843e,96184aed,d7bf898a) +,S(2fd20134,8e0b7259,415cc828,c3e4f79b,2184735c,86e534dd,77f1c5b9,9d8cbacb,41fc80ab,25ca1a82,67582a89,f901ac61,2237b942,9d724a2b,8cd0dcb6,c96564b2) +,S(5ba918f6,6bdb4013,481bee06,6aaafa88,f741c362,b5c3a4b,28dd4555,3c1aadd2,230f6c20,f39849af,9de4ff99,8e39ebcd,818d5d6d,8056ca67,8f04f33a,c4fafac5) +,S(69b5676d,b8e2a30a,8870c86c,4a859ba0,dee25a28,493909f0,9ac88af6,83b70797,4831db1,98c1b4dc,69942571,e4908ac7,41ec4568,e27089a4,682ee7c9,8ee905d2) +,S(faab5a9a,c530f7a3,343c71a4,273935bc,fb280258,24a63ce,8f8da6e2,a60135ab,1443a23e,793eb339,f4353371,34937bbe,9bda0eb8,c2fa2d50,bcd85757,68c79797) +,S(c70ef20,284cf135,7c437093,10451a9e,5ef10cbf,e3a0ebfd,b90f487b,8ca62d9,8970b394,35c29dc2,b8254d1c,9c4cdf54,6df52979,ca70ff8a,7dc171b0,5a176ce5) +,S(acb67abb,fa6dfd52,e9829767,182f5ea5,66dfaeab,42a2f2d9,aaa545e1,2e9cc68e,4a097150,2367b1eb,4f51f6c,a394d351,b734b30f,fb36dba0,9e53b4ea,3f6ebfce) +,S(2da4ea09,315e0f1b,f5b6e0c5,b8af330c,c27e26ef,54affcdb,fda834bc,cd578a3,a4097d6,ad006cca,53ea3391,10c80150,f63694be,c5ea7728,f77ebb83,2362a407) +,S(70cb8427,c2d5ee86,59b26055,3499374,63e7a482,6731ab85,6b3fd10b,be3dfdf,f44efbf9,a914063,3e8378c2,6e9676b8,351b6ddb,33f7e7db,5ced5208,e4cb7361) +,S(b14283ed,9a9db980,b135557d,97190066,60e4e1cd,3ab288b8,dccba9b1,67b24934,95fccfb3,827332be,a813457f,28a63a89,87dc8c5,340a8f88,76788a60,f03b2606) +,S(ca24774c,727efbb1,15bbbf12,20e59841,891dfd50,9f99744d,de815f5f,3e959555,2519e414,a9703de5,60f7412d,8949f509,bacecf3a,e672e7ac,58c5f98e,33162bb2) +,S(5a5c1b07,ddc79f18,26bb95e1,13e03894,bb63b593,c808f0a4,2bd44b36,dcd3765,a11bc328,2f672c9e,60846826,521add7,57b891b5,d4fde6c9,738c6329,dabf67b4) +,S(2caf2545,1daf272a,b169a4e9,b0eb9c0d,26888c18,ae7d8357,b8dd2b73,ee4cf7dc,bf8d8ea3,afc9d56d,9799083,c79f1289,7d20d7ed,48ba38a1,acb039b1,2292a3c5) +,S(af6650e3,4022d1a1,b66e8c3a,b0a8e9f3,baf44318,f6946a0d,d1c65aa1,e3f9c9ce,1b0222c1,a5f3691a,248154bc,bc9e5e9c,6b2c96c1,ca468feb,97a7c01f,2551bd5) +,S(3653e476,4215cd7f,83ff59e2,f63f2a7f,dafb8795,95006bd0,182e0e,78ca5b39,c91824ee,6ba3c685,2eeb2695,9a3b136b,371c9bac,4141344c,a1eb3051,8a6d8ab9) +,S(7826902b,cdd4e7b5,463452e1,baf88534,64723588,86643d49,cc89b482,298f6394,dd5bf1b6,91647ce2,86c745eb,6246d087,35cba4f,22c26a37,e326ed1c,4e3d968b) +,S(da19c301,4e77f987,abb00fda,8a5dc50f,d2777850,1fafec84,2ce7e5f6,37edd1da,757fb28b,366104a8,cbd26981,3697d8c7,821c6e0e,5acbb33f,9cbd5fed,25cce98a) +,S(efa31697,2a61cf86,df713186,c1bc61f7,63a618a0,8034c26c,462a2457,907436a,74f17527,e6c7aebb,ed6b28c6,26e612bf,82d61ad,cd1ca156,b971abfe,2efb15b0) +,S(379d460d,12fc351,4c46567a,ce05cc9e,ded3cc35,fb416bfb,76d14f3b,c5164f7e,f548ad44,a5c87313,aeb52885,5ac3a955,178c8992,2415837d,d3e7863d,685004fe) +,S(e3b66f05,ed217cb1,6e3f8ce3,56704f70,36b97104,e39c5649,83bc204c,5b112de4,8a2ee4f3,ab9c8cd4,40afe707,d8dc0fed,473db9c1,be2b6e7,b14de905,ba38ae2c) +,S(b14ebf0c,ccda021d,8db1fd20,a4108c48,750d10a7,e0659cca,64f3e6e,ee8c7a4d,c94ca9d4,d2ba47e4,576aaaad,c15f9019,f335ebc5,763cf232,f56f215d,ce42322c) +,S(1ffb2e29,df24e7a7,6a71f607,f4f03608,43d3715f,c3e468b9,92b684bf,1352cee1,27c39636,54ab505,4b008e5b,4598d025,ade823c3,df6aa7c8,18d4d4fd,32442990) +,S(63e13d75,38f1eb8b,7276ee28,acd56bf0,448f026c,f98c77fd,5f743c24,4872b70,845d65c0,a6cd8b30,7c7ea0c9,8024773,86a50daa,3f361539,57cf995a,43705cc4) +,S(169b95d5,417e6173,b4393c6f,1ace153c,21c83c7c,971418f1,27e1abf3,aaa04673,bcd1ca4e,5618a183,420b34d2,52d25dfa,e7cf699,3e936450,ffaae3d4,61a50c50) +,S(3dde4fce,54d27794,29b6f6a5,8c5315ff,ed682bc4,5601c623,948faa88,2309ed27,2b22dfb2,dc46f625,4f29f8a1,4cb4496a,dcef6806,26d4f499,a17c4751,4a1802a7) +,S(6b37e3b0,2422eccb,299e2b89,1a150be9,ef56a628,62c78c11,f3411614,9fd37802,a9c347b1,fa5105c5,a27ed367,261a1cb5,5d54a071,7a2927ed,29d45eca,6e958295) +,S(7bd6703,ef78de4d,f32f0d7a,274f6371,2d0b0a9b,fafc3f6f,5c03b654,599b443a,33d9b1b6,8254d47d,6aabb7b0,b66298d,8447d674,4612a2b1,f722a597,857fda25) +,S(2e9a4aa0,a2062c8a,63b18e5f,91a609de,b60ae126,93d7f1fa,757057e9,ce169b61,65a55523,e34dd131,3597b250,acd11763,62df6b07,1d3f0f1b,907fe0bf,46ff87ca) +,S(f90c1316,9524f407,8c7328a7,126c48f4,eadd6d65,8baccd1f,403a0b68,ff95e7e1,1d6a1b16,6f5b4f7,9f51b046,42306f53,bd84b7df,2a58457a,a8869,4111cb38) +,S(a7bf0bfa,8e84b448,9ee29801,a5d06f66,a17d2374,a6d91eea,2482354d,66c60074,e60ec871,7ea63cc0,e4785455,478848c0,363f6717,748ee9f0,1c928370,df0905cf) +,S(dc4ac1a8,372c06fb,ea7a44cd,11a352e6,fd204df6,f6868cb,5230e420,9ab36e6b,f3a1b986,c86134c7,40c0ac9f,8f2780,82a103aa,e9e4269,84516e09,659f668f) +,S(538086b2,aba47aa4,dae137a4,4bc747ce,9bb225c0,6aa015db,e9478da5,e2c9cdb3,42ed59f0,fb831257,84b15d27,b9086eff,9aec4d8b,9ac36f87,10f93bbb,2ce7d971) +,S(92eaffc8,955f3f06,fca49a8b,881734e8,6750b34a,d253f160,183388af,f18b8106,fdb45519,36f9e291,9e2e2e6f,7e5d2dfe,16e14da8,b5704a27,60e92d9b,13758767) +,S(63fda46a,4350fdea,fba277c6,190c5f37,c4cf7c88,ab1b2ba5,7b0ce9ec,60249c46,b64fd169,403a2687,f5f41038,91e811f,6dbb344f,2c3a1492,fc408f74,433c65e) +,S(f9f7568f,d2e444a8,14b03934,72564798,5c16424c,1ea6fa80,79f96df2,ff3c73d2,8ae3a292,fbef875d,ca18fd89,8e1e882c,ef7bc222,64140183,1cc2d268,ae795a14) +,S(43a5ef22,93462849,ecbf95d,3c92eb63,ea89a39d,2e0a5da1,eb261c1f,2e8e4bdd,896699cd,e580ef97,64ef1860,19317dd,f7c17ccc,34d340dd,b23621fd,5e5ea5aa) +,S(1fc26dd2,9a3ad966,4206f233,82e54363,6ec9d95e,a58e7af8,a4bc8aa4,736c155d,5f6c4cd9,c6f954f3,f0f3bc54,8bfc4a58,faec99d5,9f3466c0,bcc09053,346bab63) +,S(9a63cdf2,84ee5189,34b73c8f,d8b3932a,50ff88f4,8ecf9b40,c0056c7e,168956b3,e52e7902,6a8d4e95,c7f473e3,84b9966e,16347c60,8b6fb6c8,484335c1,2872f4ad) +,S(aabebcd6,8050337b,1e6caa45,13d279cc,ddc4c218,f849afff,8c1302f7,6b728bb5,808fc6b3,90c2f001,bff1993,346a55b3,663378d6,e457c639,b9a73f87,78ee8d09) +,S(9fd45b70,59cd26ff,2188167,ecdb5ad7,62efbcf2,b668830b,475df22a,bf526239,6fa79fa0,e76536af,92eeace7,77c1b735,19092fd4,870ead71,35634768,700a1241) +,S(ebb3ab2d,e71844f5,b6ff8baf,637cc0f1,1004611a,e8a3b570,1afeebb,a7a4edd4,30eed3cb,55a23613,3bec9aec,b620f1fb,1f39a067,8a44622e,84b9e271,62294133) +,S(a0e7ea2e,33c6a3eb,423138d,8faa7ae1,d7802a73,507d48c1,bb38bcf9,29838ca,31158fe7,ad132036,62449ed9,76c4aa17,67382a8a,cd42c842,ed22badc,882d7d26) +,S(a19abdde,db579ade,1dba9264,9d58b15f,1bf3b87c,eae44520,2ae758ad,f2164fa0,508d24fe,f53d8f4c,77e43ef8,eabecf3a,ddd04eeb,acfbecc9,637b6c07,fbe88084) +,S(e86ea1ab,95e23d10,f086c91f,289e2f80,d10ea0bc,aa9d8f3,1873158d,19166976,4b6bc016,6d95e08a,72c4dac7,9eeb405f,938346d2,ae45ea0f,ab76ba98,8c4e910a) +,S(aad23857,d8d835f8,e3785020,6b1cf1f1,efd9c9b6,ea15d42c,70444ed8,81710ca1,a550855c,381bca50,44be47c1,42d52259,af2f486f,622699a6,aec28138,554cf06f) +,S(b5c04c3b,436fe2ac,97bf2043,3ba57e9b,897816bc,eb8383be,ab11d488,e231a138,b1ee4b56,1965ab9a,9fa87112,57a250a2,d7f06de,7759918d,85c69d66,5546a6c0) +,S(eccf5dee,9b6e3fe3,1e3c02da,a2d5c408,72766edc,29da88b0,cdb01f4f,524b0ad9,7770c7e5,d97ca3f8,cdda858f,ed5976f7,cf2bdcc6,60459a64,daa495e9,28f4cc37) +,S(4c34b06f,6d02467c,9e667ceb,630d9865,4540b18b,8832292a,17e74d9a,d0cabc6f,57671dd,326be6d0,2ada8789,b5f27c7,b052c8c7,d300b2b3,ef881a24,53bcb6eb) +,S(9493f9c3,98a50b50,4db602ed,ef50cfce,5bcc9f0a,bcf80ffd,d5f65d1b,d030ca31,fb45d7d3,fc1216ac,6b948369,42d33e82,932af020,fd7c29f0,f2959eef,a41dcb30) +,S(b0ca3c54,153d435,b9d6427a,20ac3456,ab980b67,ee92c6f7,605aa934,faee0bbc,2e2a47e6,8b959402,1ed83edb,d4968c6a,2eb4be8e,2cf128e3,a3778751,20f27b16) +,S(d5632117,2e9b97eb,4b282d8e,1e303cbc,d50656df,2a99c9fa,bad35909,1888ee8b,30157215,efad51b8,20c03f8,2e4c9c93,11d15bc8,3dc75bea,e44e1e52,7f1ced7) +,S(3a0f593b,69396a6f,62655efd,97c103db,5e209554,8d45de93,8963cbc0,dbb9b4b4,66ba5298,590d027b,30dcd9cc,e4605e4a,73adf43c,6e377bcc,cd19eb92,e20e267c) +,S(10eb3c4c,cccd5ca,e15bcc7b,92d108a6,de762cec,b71bd78e,1917752f,b3f6cf86,6d65809c,79395f45,153d7650,74597eb7,edff81bb,598ed20b,f9780e45,bd91d077) +,S(40ae7e81,e33791bd,154945a5,105be36f,57477fdd,d36f83f9,d31fb73c,862e70f9,71511daf,e9cde10a,7e4ff05b,948a0454,e5fcd355,d98b2bf5,8ed3ca54,1a568498) +,S(994dac9f,3c047519,823c007c,57851a8d,41be0480,7c6ba5bb,88e19869,261fd12f,913e96eb,bcef4fe7,60469aed,51e9dbd8,4910d606,9646255c,9cb3bb7d,55b1e342) +,S(f0d9a17d,112e91df,63c106a0,5df3cf41,6471b817,a3ede631,d845b604,3c04d0a5,3ab43cb6,cefaa228,5c84a42a,8f1f41b5,631bab61,1d006946,f06be576,bc817f18) +,S(20919d38,ef12de1a,64992396,f7b265e6,2ab8267c,bb988d1a,6771d8e,724d16e5,81f79a2d,b629ce97,47f146d6,b16cdfd7,90fccd71,c46cf9f7,fe526e58,8ed1eafd) +,S(b92087f7,43494d53,71978b1d,63e11ae8,a1595239,33b87a44,704ca3d5,30f1b02e,6eef6ac2,49a8550a,135072c2,9bb42afe,5d27c8f7,fec88aee,6274d27,36dc0eb) +,S(f69dedef,a8894583,c05b1fd1,ae205fba,3ba11a37,ca628150,d287f01b,b6920b34,a9f88097,66d18287,9d97e01,5544c7ab,ca0cf8fc,c5b9f305,ed0bd9e5,58fa5b3d) +,S(8bd8b3c9,a301a76,9f5607a3,e116edab,9d87bf79,e4099d62,a328c1c5,f8b8b6a2,167117ec,ce6e15da,47a076c7,afd851a0,cb5dd1c3,d8187f4a,9aa5abca,cc0af771) +,S(d7e2bc76,e2a87357,82611,2619513c,10a2eff8,857fe6fe,a2e2c00,c6f8ef4f,85e1891f,531481a5,e935e80c,448d8da7,32f1d061,dd234e39,d55c58ee,df8cb93b) +,S(2701bed3,778a857e,c7a9095e,6487e92c,555ecc9,32ad8e0f,b1b59d70,4131768c,9e38370a,8d30d5d6,6aac5302,efc7496b,cd5734a2,20d2e76e,fae3c72c,a793d991) +,S(3662a916,a05a80a9,13bfc287,c81cf28b,7295dd1f,aa52badf,5ea1c83f,e1b90521,b14bfdf0,a33c9286,eac83a4c,b982f5ae,82e2e134,99bcb3de,3ac930e,2ed0c931) +,S(d778d74e,317063ff,6556388e,2d2ac429,410337a,d62917,a94b7654,6a04787e,f7d92bac,c92600b4,e8184960,11f135fd,adef70da,b72c1bb,9da26bcf,7a81f0b7) +,S(7b05001e,388f9197,ff3504fd,402a5291,d1257621,c8eb202b,dba87b56,154b6f8c,8c9c1c9b,5c151be,39f2875d,b31797ba,2899047b,6e5c491a,56f7fd28,1b897f2f) +,S(603546d0,1fe46be0,eaa9f00f,c99b2a6f,c38fc225,6553bef4,9ff47442,ffa7626c,1f86de50,aa457ed,ea306251,91cc3cd5,61cbd8f3,2b41145f,139110f0,64b73b74) +,S(80f9318a,ca3b7aca,65cb1965,a36981d0,86ba3b32,8a95cfd2,9c6bb718,1f662c25,c195025d,794abeff,49c9b1f6,724f72ca,70b0bada,d06ae11f,2101b49d,d592ae18) +,S(61182e02,a877565b,1209dce1,bc84c62,f3b1007c,48332c56,6dd6e697,664cf64f,d21f9259,517656d1,3efe7166,750c341b,6c064b0,542bac29,28424a30,ce4b51cd) +,S(21cd4f22,ec3a190c,77073680,58562d82,36d463c,f7706f10,fbebd283,c19378ff,2e04af2b,155beea,daace708,c510555b,467727fd,145426bd,680d1964,fc1b03b) +,S(2d3f6c78,94479443,6004ac92,554a507c,5a20ffd6,f275f715,b176b3b5,3d2000b0,72e0e16f,9d9ceaa,2ffc5a1a,71a2cee0,eea64e44,7f716eec,1fc417be,ba16d92f) +,S(a9f45433,c040d1ac,6bd36d33,5b655fd8,eec0d3a0,bf1a622b,df422039,239de17b,264ed6a,8da4a169,a66869a0,a846229e,81d52517,22fa4c2a,4c775322,f33b1184) +,S(16e052be,bb65657c,309d67e5,b68ea441,4179ace2,38315c8f,df88626e,84281ce,91c007f,fcd4633e,597ee06e,b28296bf,2837f30,8cb21be5,9bdbd52c,4ae0422a) +,S(ff6d96b6,f633beea,1de80512,73c06bbe,181a1098,db737c8,41a48d44,cfab935a,cd9a8011,c22b643a,90f1d9c7,54b7330f,1c1970fe,5ac04225,c2720054,fa6a8444) +,S(dc2e3b1b,a2619ea0,6e4ddc09,99630c4a,7b94c78e,ed13517,25b8b8da,137fa467,f97e82ad,49bb4389,84cd752e,820aac43,bc6cccc3,f9b0d9eb,c2337bdd,89cb83c9) +,S(d53b97c5,8e23d50a,3b855c43,80a992c9,2d667afa,bba4b028,20031f58,dd6947c9,24a54f43,bb9a04c0,8b93aa96,9dc61f92,e705ab75,e644a3c4,40391af0,ad375ec7) +,S(b598a510,beb9cbc1,c4e03f8c,1ff610e0,7123ddc6,ad69dd6e,f9fa7810,f79c8ab3,b895b8f7,68a80a37,77d8b5bd,46754473,c9590768,a56fd586,58ce97a,366dcdbd) +,S(cc2296b9,ee9726c,17b0cc6c,745a038e,38b5535,5e19fc49,e89f4ec3,372b2a05,6a466fd2,f9a5c412,9f5b2faf,aaef4cf2,be71406,590ae031,d68c482c,86e3f89f) +,S(3e84c76e,254c858d,51cd4e74,72c22ec8,364ce28c,de81ddbf,b7b3093f,44acf9b3,ce8ae6f5,f56814dd,21186370,f70196d1,339c264b,c78a502e,bd57e771,b438c81c) +,S(976f67c8,c626f8de,9de43f8b,39585d7f,d4cb35c6,e4211b00,68669ca9,a973a3db,ae4f1f6d,25af4ccc,3eca4b2f,6cda0cad,dcc28f78,c8e881c4,eaca9131,2f0b057) +,S(b28bc958,aed50ba7,6d5293f9,7c419828,53bec43c,21ef0f96,9000fa47,49ee95e3,e7d4cc8f,f68182a2,15dee707,4df2c351,906d5527,c47e6414,54e97c1c,b57525b2) +,S(e54dd5d2,16bc5903,9a630bba,7cccf5e6,81a3113e,be8fb57f,83c51209,965cddb2,86352dbf,5f2b2327,ca50458,b3b2cdd1,8d403629,a2e2a776,5562240,7e8407db) +,S(58379e1a,10115a0,8f2b93a2,3f2f4e2,2787aaec,cf129910,b1911b43,c209f379,a526d32c,abd99175,e63b4493,7a0dc96e,e0feb99c,bbe00c91,1e606537,c871c6c2) +,S(7858a68a,cb34cfd3,e1cb7d06,4d233322,ceefa6a7,a2de391f,991b94b4,da9ebd63,f54490f5,ede73b49,946ffe19,d5ae6f7f,ca026c07,b1dc0138,b1409383,5d792db0) +,S(3c8c636e,d20d58c2,f03c26ac,bbbfed70,3fd13304,74bdf2ea,7526f16b,4fe6f7f7,550069d1,cec630e8,6d22af01,5981f20c,ffdfabdd,6416bb00,f2dd8c6a,44401759) +,S(d03fc7ec,eb716cbd,f033d76e,8db97314,858674db,48ede8dc,1a1c7dd0,82ae7f93,16f7a717,a197fede,dadc25b5,a20b0486,1cfaa63e,3157e5ce,ff0c81d5,bba296d) +,S(6d6c983e,d60601d4,ae5ef4ab,c73914c9,b9546964,a6a3d2a5,681b09cd,afee2c22,13f5af59,61877fb9,2a2ac09a,eb691a88,20ca8361,81359fa3,96558ad7,b2276b1b) +,S(92a9f5d2,149065eb,1241d82,fd06ac2e,f1f48003,3bffb06b,ae3a9d88,a1d05f8d,f0be5964,75545835,f64b0985,1baad682,b84d7a39,91ea0f49,1d19b7ad,77ad75d) +,S(222aac7d,c2fe0066,b766e1fd,179c1912,5f289e98,33cce93c,749afe38,ce0aa74a,bd6c4d8,43e5923,b5944e40,8d309733,dc0cd9c8,b266dd8c,2df162de,fde5bf5b) +,S(28b14628,3a7e1785,1c9d1831,6c9ca17e,56a13c25,7877ca3f,49ab2369,ba2898f1,292856f9,572ecc,5f000e0b,1e7ebdc2,3ec72619,3c97542e,8ccb10cf,d608eac7) +,S(5031a6da,df8d12ff,9eb19209,b844b008,dcc26de,c4a6f9f1,bbaa45c9,daf909a6,ef31dc6e,3cb5c39c,64011c0c,89cddb04,7ef9a881,a0d718b,5057bdfa,3f5e1ffa) +,S(925835ee,ce55e98f,130008fd,a6f01768,aee2de4a,f96f239a,430d408d,95a627c3,cac1b7d7,60362e24,f3b5f277,e370ba70,f0f8c6dc,a338c15c,46c5fb4d,f9f1bba7) +,S(6b7253e6,9dd65781,8214fa04,67f59e92,a4671648,c465ea4,9c993bf3,de8d9e77,50a9cbd6,b429c3d7,32bc3b68,ec581327,1c2b0a4d,2d8587bc,7b26ee15,ee7e92bd) +,S(f82d660d,cd5df408,714213aa,a7406a3c,868a8d05,1fe37689,baa6fbc3,effb3e33,affe0a1a,b7bf498c,83b331fa,f3e7b723,2a2dbc66,3b93da28,e12f0d56,260677a1) +,S(990954a5,5342c5a8,db3fef46,da2b31ba,32b6d597,c67c8290,9329a90,c39845fc,d764f091,40891e20,a2130696,216049d0,b3eb1af5,7dcb9797,4c42abc,5298977b) +,S(d6b8e341,f8bad7e6,ff434dce,fcae81a4,1946f237,e0467120,fd420,f3dafc0b,a8ba941e,81677d32,140666f3,55fc28fa,7233ec8f,8fd13703,214bdf8f,340c389d) +,S(fabf5120,8632ee4c,81ad6d34,cc84de68,728197b0,fcf07971,326d4c04,7017b905,79c781e4,aa7dedda,4663b8db,7fff3cad,f9752cf7,ef2382e4,b0254489,7c6c04b2) +,S(e62db266,d9b208b1,83016754,c871a8d7,4b6848de,e496ee7,e2c1447c,2029b0d5,ef7410f4,f44d7414,53b9c1c6,8e5689bf,37cfecf2,1602e95f,3fe053dd,aea24f77) +,S(4bd90928,14753ea0,1025ea2b,86ae2310,5b581b48,98359481,d1b7d36e,d9c6e478,2f12e4b7,b825c858,5362afc0,d0029880,45fd638d,65f1865c,6ffb31ce,424baa50) +,S(3e397cfb,cc5c9fa1,15519366,c6e814ec,4b0ed9a5,dd093321,219e4028,28126ed,31c352e4,d4bef7cd,8929d3f0,aeecf9b,1d577ef0,e8086a28,40d46966,c1165dd) +,S(24bee951,54baf31c,f5322941,ffc01fda,9e89f80f,2662f5b4,edb751b6,5b372ee8,9568a4f3,a34ce5c9,8f591550,b75f2a84,be5cf67f,1fd7713c,c126f46e,1c3b6883) +,S(d242bb09,e4c6cc42,a2bdcdc6,bad2a02,8e4bfa21,430acb16,3f0e8a70,2ad2f0d7,2eede9ec,799b9e5a,13c40c4e,4cf6dc0f,9640d472,2a78cc6c,d920b610,d070b913) +,S(a57b5fd8,f50de3c5,98073cef,bc6fa56d,20dbacc0,72dbbf81,347bf0e8,7a36ebef,a99f123f,a45b1369,32394f8c,1f7ea2b3,563ca2ba,9c0da00d,b2c9c119,e6f20287) +,S(82a43e2c,a533abf0,6aab1199,fdd20f9e,1616a79b,859c6467,ffca4b27,989da9e,19cd40f5,8c997e78,311e5ba0,c0b3328a,b845da97,91dc8ef,a6cf7e5d,efd51c6a) +,S(95bf3b4d,b8ef8bab,16e00f5e,7dbe9907,b54c98f9,2331c4fe,688129a5,5cd021c9,2b4c46e5,b9d9f915,d5d020a3,3c63fe49,eeb32931,9373bf9b,e359c40a,19328c47) +,S(791ea768,4d333125,893356ed,dd8ebe4b,3f98ae58,e25a2d1,67006a4b,5c05799,5f72cf68,7827ce2,6bebd598,539f6519,a50788c,9d093766,9c3b9c29,f52d5422) +,S(85138ec5,a5d3f0a7,881ce23f,e34fbb80,fc3038e,bb7c2a24,ccfeb2ae,5ef07b74,8eb9e80d,8664b11b,d24753f2,bba612bf,c06bf9f2,a4bd061e,82ce9037,895b084d) +,S(3b4c1149,1d98483,9ff33b31,39da0341,f430175a,d5800c80,37e35dfc,a68ec256,574d6475,e225aeea,dace647a,1489b2ea,873175ea,83cff3f2,fec684b3,fd2ad143) +,S(2ea17f9c,6a028f58,396474bc,8c51b1e3,cb9ac0c6,7f73f533,a428281d,4101b04a,19d1f021,8b8cc0c1,bbfb8925,77087caf,ebed3409,69dc2281,3a1dd6eb,9d6c44a8) +,S(67839592,2fcc7ffb,627486db,e1d98a45,25ee1338,5a98c01d,6b3b9f8d,f64c507a,e13ed82a,a1adf761,7cce3760,d049a72c,7572508a,5ecd0615,1bbb589f,17e10a7a) +,S(54a0d2ed,39778fc1,237ab423,1e4384e6,4156c1a7,d5e999fb,2c92ba42,ef40ee68,3d879ff8,c25ed54d,df848e5c,49e3eeda,e8eccf33,afcb1c1f,67440810,8b3e979f) +,S(263ff1ed,726d0ff3,8b47b398,c713455a,3030d499,3a77ffac,b9cde4a2,cd12f7f3,a5f3fb33,c739bc93,c442508b,ac70884f,d90c3699,34fd698d,bc27f7b0,ca48a0ac) +,S(43b2fae4,a431beba,598b3ccf,caa1e034,91e7099f,c19508fb,8e693de6,dac9e3ac,3e43aac3,379c321a,5313b412,7cd00a1,bd8cd177,49c4240e,7cef1e97,22daf69c) +,S(a73e77a8,5733a296,2da7fe71,f4c16166,cf0acdc8,2d5288e1,8cb9479a,2a31f362,12b393ee,e323fd52,e44a9ab4,3e19256a,f7a8c892,76e9e6c,9052f0c5,3ecbc031) +,S(f007a9f2,bd3d0d4a,8cb9524e,a5aae499,6b2d0c1a,19aaa56d,4038a21c,6dabdd86,517a6a7b,3b75b68,bb04bdbd,d6f93414,c97b4b75,47b8fe22,c5828d6,7e979702) +,S(bc64853f,111371d0,8381c082,c72d2528,823e18b9,99de4303,c85a5fb8,87250833,51e7dc7,23256176,62a9f6f2,70bde4c7,94020e61,9e8dd87f,3f266d99,71596146) +,S(144dc699,a063c473,4b9bfd22,845317da,c4b55e92,a232b92f,965967b9,9c8e21df,a20a7982,7d57de38,85e573d1,6d22025b,648b9ed4,c656c48,bd6f4902,2b67c681) +,S(834ed659,98d49650,c3f525a1,b34ec725,89d167f7,a3cc6e86,8e4cdce3,b2ba3179,6bc2b06,c97a108b,2abf4033,152065f5,24c1bf1a,e79adbd,b7eeec17,9e598cbd) +,S(efce9278,6052c989,adc9595d,cd1500c9,8e93eaa,dafe2b87,2011bf55,3488b1a6,48ca33d4,cc89b486,c0930829,91f23147,d910f29c,c9d13787,7bebf55e,a3dc92ab) +,S(5b150240,c3563354,39adc9fd,23e9f94c,369a6cf9,27f45bc0,f0110cc1,b7321f4c,629b62e3,1a85fb44,b448c7e8,e76ec423,b059c9a,c8144c64,9d77a4da,eb044aa0) +,S(cec8cb02,3f166bd6,9fe04f66,8ef6e949,f4e3d26b,d748c30f,53a9b9f0,9ef3f9dd,997f9fdf,dee5cd89,352e6c38,760c4cd0,a7bb2696,94916567,ae60fc5f,39b908ca) +,S(58427cc8,edc5e616,3726519c,7522980c,30443eef,7e72cdbf,b135ede1,f15c0890,d2fe9c00,7eeb0be0,8295e972,e69db2e6,a54193d3,ec9a3ea9,f2515e59,6e34e88) +,S(a7d0a30c,1787b9f5,8ebff502,e4e38000,6bf896a,2feaefa4,4670dee,6030bee1,774eabaa,863fd4f1,63b3a16e,4c17078a,fd0a1761,b39ab05c,3c6b1d36,5e487592) +,S(9d70eeed,55ed86a1,ba17e817,4c400cb8,ab0e5da7,b568ca81,60b585df,d1a84e74,f4c1fde7,f11b329e,f3c3e196,bd78a3ce,5387662b,859f99c7,d61f7962,2d01b5f2) +,S(e0715fee,9639817b,8501de6d,6561e623,628de7ff,d0dbab5f,bf58ee4b,a365f684,e34ba5d,acb60318,c6ccc001,871800cd,98ba2c5d,529a42a2,fd145336,7b10c22c) +,S(594612b2,4cb1912f,fb945465,1036bfb2,79be0bbd,e718ca26,973552b6,93d20143,d68338a0,d03fd0c5,e6c6e3dc,7070c78,72eef1c8,cc2154db,cbdad699,b594b142) +,S(f4f41087,1dbd5394,5fde2583,b08ba65c,6729dc05,b32ec3ac,c8aadb72,a6c0d8,8e948ba3,853102b2,99f2f558,ffc66181,310bc676,4b82dd7e,85fd075d,70d92fbb) +,S(efca7b38,69f2981c,406cfa40,2bbdd00f,15ba56cf,c6e9f66,9bdfa14e,aa9b1d21,458fd928,a07fa32f,d6a0ffd6,64a16b21,2bdad00f,a4534093,209b0c92,f507f9b9) +,S(25b2384e,d9e09e70,8098971f,153ada48,f3f4a9ae,fb946225,77d213c1,e7b326cd,ef50fa0b,4cd30cdf,2667bb4f,7dff0287,df666dfe,7d5bdb9c,ab567af4,b77c7535) +,S(ed12b20f,aa2ac5de,db62c17,2bc67cdc,f0534a33,6a32e26d,b325321b,81901268,9245a6b1,35df02d9,3db1224b,1a0a296b,a39f07ac,ce7ccee8,eda552b9,748eca9a) +,S(5dfa472b,b84ada50,da3ede14,8bca4f0d,aa885d2c,61633336,b2a8a37c,76b200b0,f314a5d8,2d20fd30,ee237487,7a922a54,f4c10468,656a5432,974cc3db,c2c7fbb7) +,S(a9e5c0d6,5b6d4b4d,b242d87f,57c805a0,5b7f243a,515c5d34,a037ddc6,afcc4470,d90fa599,de5fc8d9,87a42c57,f3bf9dac,d5b766a,fdfa07db,4c56c0d,3d71324f) +,S(4e9ccc2,c0e3169e,e25a6701,a82e7f02,2663d3cf,585100c8,2c6b5da4,d8c42e8c,854aa160,d48d241d,f5bdd1da,2c74d1f9,a00fad7,effa29fa,5ecedc42,3ba43484) +,S(2122c569,da05f145,48d42f9c,5ce3a96b,bbcb49fd,fc5b2dbe,1a7ab0ea,84aec76d,40796418,39879018,93bac618,8a7286a8,f8745709,58a40cd6,1202ac,dba5867b) +,S(aa8cceb3,415df249,b5069899,75a853fd,eb409729,331b1807,ca2242e2,a75c6968,5362b581,fb676eb9,9f125fd,5f674be4,800d89f0,133a1363,f1cb30ec,1fa5b468) +,S(beaea0f0,1fd8e442,50648032,530e41cd,7e3c8271,f4b83b4f,7493039b,b21013aa,e21f7d1,53e5d411,794fb472,47897cc6,a86396f6,3f6291bb,fe2f0f12,a263873f) +,S(8eaa225e,63bb92b9,666bb318,22c166e0,3843ff47,482cec9a,69ff584e,d1a750a6,aa26b32,e69c5d94,19663e05,6c9f7a60,1274aec8,a839ff1b,b5a43c2e,136ffd64) +,S(bcba926,40d8b4cf,8d73c0e3,7867f5dd,81eef91,70e904e0,15f05f3e,1bf6591c,8913cf87,e33aae4c,a16b1391,75d60106,ac7d05f4,a8f10db2,b0569a6d,ec121260) +,S(2d03aaf,6828d0c5,9ffadaa7,5d1b7e95,b3c4a547,46faa5c7,c428fe45,1a9f3332,68468e2d,597e7534,37b3865b,3c968e4f,e3f6b1fa,996e6b4d,296a12c3,20e61cf2) +,S(b39b4de5,be757b36,b1e88773,47cdaebf,11f8d6b8,ab59d780,fbaf2263,a823b5b9,1b609d2,de73faa,d613c4dc,6ac3c2e0,33d62b22,7ca3fcfe,4aca992f,eef90b0e) +,S(eabf705f,b6996148,170b23,9fb8998e,df6214a2,cac27fe2,9c66a899,63d2f0f0,e1867fd2,98603f79,d17876f4,7aea4437,cb39ee7c,bdafbf0c,5452b024,86182d17) +,S(a4ce885a,ebe9335c,6ef43c6f,395e1644,201f578a,4caa7f74,65c12542,27f1bc80,bde32eef,f7fdc498,1c50942c,efb38cf3,c3f1a8a7,5addfe7c,f11723e,f57d0c41) +,S(db8ee69,b0e00ff7,6a094251,a53c61f2,e00dc65e,a11e00e5,553ae121,ea958361,24e7ba71,22742e09,728108ac,59c5f46,aba40d1d,c308edd2,9d494f39,d156b2d) +,S(88a5b43a,d6cdc2b5,aa3d58db,9a9a2e1a,6d70afa,808efa87,1d7f3cbc,509cf064,88483c55,e5bc8717,8114605c,1febc726,e14345d4,4211b670,6b6185d8,ea6b7103) +,S(e3cb24cd,2130716f,10a4d432,d4e59229,2e11a2f5,3190bffd,4f478da2,216b0051,df432db5,caabb417,f8252d37,dd23e117,38066c87,101cd934,73a2883a,1b7e8de0) +,S(d9c88471,97f04254,731794ec,e29ba74,f1d72f19,8f424beb,8309e1ad,e09e1301,12037266,331f04b6,db4264df,ae6d934e,5f753828,35a646f5,cfa4ae8b,e6defdc1) +,S(80bb740c,3510574d,10afa586,a6e541fe,b5368797,231d2a63,67d2890,8877dc58,24ff9389,bb268f42,b04f1702,f7b7c6c1,7194c7bc,c5f4f63,bbcd4ca8,ef476fca) +,S(4b8b08fc,400d6fae,da05cb19,65c9c785,8f93452e,d1be8f29,28c83e6b,4d2b06a1,70a6612,2549ec2f,6cde4a4a,9ae8a528,1b05081f,8eefa8cc,1111271a,1beea7ae) +,S(d2708078,4d19552b,13ec8473,1eafd2fb,bc0ae927,dd746a8c,be1dfced,d072ddc8,9362bac1,806dfc84,e736758f,22f1039d,57a5e44c,40586195,885abb78,f75d3355) +,S(7345d1a2,7b9dc922,f51a0466,57721451,cea5b54f,6673a484,7a210b4c,339d1f18,293053e8,c180ee0e,d81bc4fd,658fcd5b,99bad329,9e62aedb,74867df2,3ac12d98) +,S(3b3a6baf,b9003f37,ca27889b,a2be2a02,748ba52f,6c6dc719,afcacf2d,578b1e24,a9749973,c49ebecc,501f9b18,83056505,6c88c286,2747496b,951892c6,8a61ffcb) +,S(b2d1a3e9,15b02709,1abb5ba7,206ad2c,5d07079f,8d4c7fae,3e6837be,34159226,90007202,78d4188e,b8efc45e,8306ab47,be1c6a16,d88284dd,fb627b1d,92959898) +,S(298019e5,5de972ae,fd0b4c94,9a9d4eb,46689fa0,9b849947,bbe27805,4a3f4a5d,5b7a4298,be50ee99,363b5f9a,1ef103fe,4fec0034,fd8a2364,5cc76f8,ff804f0) +,S(604f1e62,7f503661,5b55fe74,4540df91,67fe575,e0aafe13,8af68214,f1080eb0,2ade0355,b373ddce,2353669e,6af5575,cc6b01ae,58b2a581,2b63f36b,58effd5d) +,S(ddcbadcf,63ffbfce,326db7e9,2df0d483,9a35df32,fc576070,9f2422f2,6e07b8be,7a3bf369,dc3a5ae0,c91cea62,1429ad45,76f7110,b654a1f0,edda9b57,3076306e) +,S(160a19ff,10c8b334,7683b21a,880226da,81d536de,d9dcd357,d4f2283,18853837,91dd522c,f6d1d276,e88287a5,a37afefc,ba010111,82b93eee,1483cf56,e6cf5218) +,S(bc1210ff,d75737ab,51300e3e,ea48a264,5f363793,1f4c6f95,e8507034,84834819,8acc70b,363e52ee,779e6342,ea7dcb7c,d7d09946,5b0eec60,e35ea360,e8baa7f4) +,S(c2da24ff,f2c5419c,3d2ab241,e55cbfff,5f41b9ae,4efaa105,abcc173,a81fa1ec,3fed4d9a,4eabf3bf,6b913bd9,279761f1,4aa630c,e278d0d8,4bc82ac7,af77481) +,S(73a495ab,b26d4be1,bd99935f,f5583f6c,f5c86d79,fc86a4ed,48f87f40,2f12259b,f4126c3b,3e9b8dc7,ead63ddb,5749fe5e,6cb0bb3e,3c85426b,950326ef,9092301a) +,S(599baa65,fdf949f0,f54c44bd,ff605ef6,2f53d68a,f0e44bf8,274f0b73,ce251227,297ec5da,e3893363,617f5448,b13237a1,91fb5a20,e52ee897,a124daff,9f1eaa9c) +,S(9a032a50,6786e1fb,bd9ecd25,243ea67d,57f9e4bf,d1083879,e309690c,fb07f253,a073c6cd,15445d6d,80c51af2,4e7f540d,f1b75fa0,89a4849a,ea14ea09,ededdb0a) +,S(792160b3,eda1d493,48ea96d6,857d8631,ed1e198c,c7f185d6,b9d2c75,2b1cae63,d12d76d8,bd73a681,9bc581e,cdb84efa,dd143704,5554984f,8f1132c5,fe1bc32f) +,S(8fc4cc45,9639aec0,2c337f16,589c09a7,e787dffb,69ba2907,37b6c465,db9f12d8,b2ce3c2,57ccb79a,b677a9d8,49ce1833,2a97fca7,28bf3e83,6dbefd23,5343571a) +,S(fc06a9a,5857b2e6,df0c3be8,b5840946,ca77f690,4ba114be,44e760e,267eeda5,6662078e,f0de0e94,5a770654,b8281a74,f82168c4,49455250,136dadf6,87c5bd2a) +,S(345da4f,e1e89eb,eb27b353,4352c5a8,32d3c9ee,456c01e4,657c2885,733b5f69,3db274c6,b89e7400,cec4e2a9,9995ece7,be8b98da,39a2fa48,bbec96a4,5c758be0) +,S(309850db,36d8c2b4,610cf8f3,e1c12431,3931aebe,1a9d2099,cb3bc7b6,fbd8b0d8,edb3a9bc,f6417672,af9b1379,9bd8aab2,f953391b,27cdf167,320005d2,3fb3e4d1) +,S(8a35d7fd,8c7c75f4,e22ba36d,d84533cb,f314a54a,2e17a43f,d250c941,5025b0aa,97ae015f,fe364a2b,6c12cc42,fe526eea,7250092f,79c40b94,ab7102c6,fde1fa5a) +,S(982d9d66,dbe6b738,2cf2820f,c72ed491,d6a61add,f1eff091,de30fcb4,96ca4161,b4a7b42,2e9cd74b,10cde7a8,12b4d88,f3621324,acdcc911,b39d0952,3cb3b501) +,S(1396bea9,57d47670,735ed20d,e2ecaf6b,afe7e067,5f2a0f65,6b3e719f,573cd1a2,cd77e7d5,a49d6cac,5e7871c4,58df45d8,821d77e,f3ad3db3,56989c1c,700cf484) +,S(6857993,76774ed8,a08da47a,9323241,71d09fdc,964893d2,aa5e783c,b8030057,640c986e,befd426,8fbfb131,8133ca77,879ced3b,56ec251d,12d0a650,28bc9d3e) +,S(801865ee,fecd50cf,4970e6ba,efeed453,769b3e14,c103db6b,2632e241,2405fb6c,b3d3f23c,8f75e475,8784016e,6ce1b91,8db76599,8c7c1aaf,af047282,ebd7a636) +,S(f09220f7,27e57fd3,209eac13,1ed93f96,142c400d,b9bd708c,9e716686,20f1793f,8280375b,1b2f4915,cb82a72c,43c9fc6c,f3a7de5c,32762b69,43187a8f,13510eb) +,S(1c814b69,6104f8e6,5a51b98c,e6b0c4f9,f26b5633,8ce24ee2,24a5aef2,967ab705,1cc2bbfc,61828277,90502c11,bcaa1f1c,b5e34891,a7c669f4,dbbb604b,df2e3135) +,S(22fff436,de961dd2,a7ef38c2,f588aade,320d0721,55e6a42a,3201bc6b,c7d24a54,6f13476a,f48f9197,3845af18,ce68ba91,77a0d4f,a835acce,76814c81,f6aaef5a) +,S(39da98ed,a85b2de3,c9bba6d4,1af633d5,5a392dac,b1d4fb9b,654fde5,a3343a65,29b89534,35045e6f,2ca41bfc,9e5c9ad2,55eee426,95f41744,b239659d,460fbdaf) +,S(6fb84bb6,3be24203,6e067346,1a5c1fbf,7d89a0b0,c98ad2e2,25cc3ba2,191fbdc8,21a37f8f,e4f821bb,3886333,c554d6ea,cb8924f2,bfdd7ebb,339a8a92,ec9bf8a4) +,S(29080a3b,7c1d33e1,13b70c4c,8388fd4f,59118a86,c4bf697d,25346368,8f60766b,745ea31c,e9731f68,89aaf5d8,1e7f686f,b345c9d7,3af728c6,7ac2b8d7,60ffecc9) +,S(a54f7e6b,aaf05de6,77e7d98c,5385d9e9,57f68d2a,8e3c24bc,11b6435f,50cfd955,f7d61099,22ff9c98,ee79998a,597dac10,be885d5a,e7b53158,fb671e38,470b5c69) +,S(7472bc8d,c109d56d,a5f150c0,bc41edce,7e378335,15e17267,62f50cce,e8845b2e,3c59290,820b997d,3c9109ac,7319048d,e37c5280,88e671fe,9cd85487,f03917fe) +,S(6f4cbc32,ff1805da,6cf83c64,b0d0eefc,6bae76d0,586de80f,df2317b0,a4e68267,29e492e5,89bf6c68,17731a29,76577124,c9bc9e32,1856bba8,8a060bf1,6a6c9d9a) +,S(1a93eff,b60cb865,8538cb27,d8c12490,483e6886,16320327,e2689591,c5413a12,d96609d9,251ea2b8,f150664f,efe6bf6f,a0634cda,b8846cc6,5f6c8a8e,97697c9a) +,S(79b82e7b,bb23efda,cd79c0f0,87f2d0d0,e2d3db59,97696c73,e6e94ea,8cb72027,bf16f23,47e594ec,fd087189,48d531e9,8306b173,88546493,d620218,b25e3758) +,S(a806c902,28fbc405,ef56057a,aee9993,ef177261,74d456fd,818126f2,5d93f986,fc49c640,7d9d26f2,f043a1b8,8a41bbc1,3ced6a93,bd669ddf,3186dab2,9eb7c5b7) +,S(227d9094,69eab478,9da2fe7b,3cb618d8,d781e0a6,54892f86,92eccce2,f41e9a1,81cbb45e,adfe3fc1,de5975cc,f87f0a44,e9f106d7,19cfe796,f33b5c60,85de7691) +,S(14f8dba6,4bb5aba,f7f58e8,1c9b0425,2c357f3f,fa8aeee9,fa4ac700,8c49e060,26b19dbc,52b913f3,b6aafb31,3de99445,b49d64ef,2503d28b,bf2f9e2f,4614609c) +,S(f22646cd,553c5008,aa3c4cf9,f01a05e9,20cee021,4e9b0553,38a75c1f,23e5fe4e,52cdb77b,7502794,ac16003e,2f4e859d,ec3e68d8,c84a3365,a307ac80,53d3089e) +,S(515de841,814df2fc,7cd43689,8780686e,f3bdbfff,83eed568,af19c75b,5ee93a2a,7395bd22,705a81a3,d62f3130,ad416db9,268961c7,facf81a4,44d2ed8f,e4df1282) +,S(59f4aed0,38f07bd7,b2aa6600,ca6f15f2,d396310f,e4ffe212,4e6a89e7,3c7c4ed3,47a048be,5d6e45c2,4fa69329,86b86edb,b990eae2,f5dc6524,3eadc69f,43b2ed3a) +,S(7492492a,d7f94293,4287c7e2,5f05203c,4c70b8f5,80d23b4d,4822d1ce,fa3450a1,19523158,2fa06da5,eb5368b0,f0b19971,1a1bdba7,50d1c6ab,80ca1b4a,d649eed6) +,S(2e12d13d,464de937,372a69be,b90dac92,78977cd0,e7b954d9,30360d6e,a51cc3af,35a900c5,6c7cf352,8c4a5af1,56dbebaf,32d2a128,8a58e3a2,ddbcb539,bc3e3505) +,S(ce4c4b4f,a52f06d1,11dce52c,402395e2,a6ffd186,dd8275b7,bd43e941,9f4699d7,957b994d,c5bcd5e0,179a67e7,94a40ac5,cfc074da,6d23d178,969fd8b9,2d9dc455) +,S(c51f1cac,5814de82,f4bd5d2f,a8e4950c,38fe78bb,8d09bc5b,628ec13c,e3084592,721122a2,f63289c1,f8925ce,34d810a4,be52f7bc,9bfea232,47617f95,8db1cc95) +,S(9fbaba14,8293f578,46c717c8,718a3a9b,9dc5df98,63ae10e8,9c3649a3,e26128b1,4917061f,ad964c4c,5d79780,7914b2f4,b6c3e730,3bd440b7,bc00f15d,bed2b497) +,S(a4a9ed86,ed3a1dce,5423c1e,1bb5fb9d,fbc1ed41,66a4219e,bd343922,8542ea9d,fcf6821e,46386764,c61eec0,19b1a84f,6a8851d,89be0da7,9d2768af,6eba9d89) +,S(a6fa3567,9a732aa7,b58582b1,5f3e95d1,f702ab16,5249e9e7,89a5a395,3858d1eb,3bd67e4e,c0dae02c,43d32cfb,d25a4b2a,75898bad,eb2986b5,6cf61825,ed2830ab) +,S(3b3992be,8f7e1b1b,4d8f5710,6feb825d,568b176d,af0e41f5,9c2fd59f,f67d9b7b,ddf2751,ac17a413,2ffc5c08,3e8c7728,a74b0063,377228bb,a60cdb87,1b5db297) +,S(e9ccb20a,8a279cef,2a15de57,e34f510a,f60ce397,3fa2ec2c,4558f166,7ad20201,b70a11bd,1b5414de,1b30035b,3dcd1dbf,17558bad,368c78c9,d5d9136,6592fa53) +,S(98083dcb,1356be80,b324aa95,e38217f7,c437f421,5a7f3e98,ba803fd8,5cc04445,bc0d9ebf,ade6c640,d16b82b6,5328a2,d5ef2f8b,52aeadca,e406ae25,e9b756a1) +,S(6a0f3b01,9e3b2a9d,453cc36d,275fae6a,b94aa14e,e0b4103d,137b1741,8b446ba3,ef30c9f8,46c54902,c10a4ee6,c5013b25,709e7109,fc004b6,e291b1bb,a021facb) +,S(83a62b60,6a1c4d03,1a18473c,f2230088,1d767332,9513b7a9,4f402f18,3dd45640,b23888d9,98bb9c00,ea57c9b9,517080de,95e6491d,cba0d7a5,729ab99b,12a1246) +,S(d2781bf,4b059449,75da8b83,cf82b43d,b5ee89fc,168186bf,74f22321,30678492,76fe1955,18e00974,6af44fb3,6e623f4b,fd0ae8b6,474e91c3,3ec364a3,91049d49) +,S(e4445252,dc6acf3c,f7b3663d,7176d46b,efe95e40,3063d1a1,68fd5742,2795a986,cf7613dd,eb200aef,e665bcf5,a6dd7fe3,cab6ede3,877f6a28,22b6620d,1eecda68) +,S(51f59cbe,68f523b5,b435633c,ce11c0fc,ed2129f3,5d392b2a,ef789044,722052f5,10403f8b,e7024887,3c4f0aa8,e4d0fe46,11f34268,178368e9,1eba8e4,d9b318fa) +,S(7d1806b8,410ec629,77fc41c8,8c86ebcc,74da9a0f,c6b35c43,68d069a2,c8c974f4,efe8890f,5aab9bd,c2da2956,bc089b58,b67ffd79,957ce0dd,9a53da,b26d68b5) +,S(add67544,8cb87ade,f8cfc3c1,85fbce12,e0d1525b,812fb5d0,2420481d,b22dde96,bb80527c,b22a3bf6,728ba305,bbff36ce,c6b44d68,9cf79ffb,93030460,8f461174) +,S(ceb2968f,fcc7b751,f9b560bf,b08f40ec,ba1395fc,9a3f63f1,65a1be1,862c3dae,67727357,b2dc8d2a,47606c1e,ae61ce54,1d79ba49,4a5e310,e0435b,383cf088) +,S(3a03b03a,1348cf01,afc60665,26b6fcbf,b3977ecd,7c17725c,a9f0c494,f31223d0,3e71c6e0,7da0635a,a2fadf5b,78c892c4,c95f794a,88594b72,183a9b2,4dcbe7a6) +,S(42ac22a8,c708f2fa,559f9b9c,fc7ca705,4356d18a,95a69137,bb8b8b17,2b771aa,ef669b2,85ed6abb,477dc2f2,bf0517f3,794c371,9ba5b267,8f622eb4,aa4ce374) +,S(b2ded9ee,ab06f1c4,19c5aad,5163e731,722c4923,818185c0,d99d6a8b,dc603a06,23bb4786,f84e6c75,e565a708,2600585c,e1fd60a2,b935bb4d,390d07ee,5e8646dc) +,S(ea1faab0,bb0b6cd5,454e63a3,d1546747,cf9707c6,48e4837f,3fc6b6f,a2ccc5a8,8fddc23e,651ebf4d,89e54148,2043fc34,7c26b66c,b2ad2d80,1fd2fb7e,77d4058a) +,S(487920c5,14ce0cf0,9d939ce5,81e13409,9fcad06d,3e6974f0,a3b5925,12cb3a86,db447217,8a92e9f8,65a1b022,3baf54fd,618a87a1,15887f02,11cddbe,986dc927) +,S(6828652,aa506655,60349cdf,132ca8c8,9a6f9a1b,8baf6adf,64e10c12,9ef9217b,9615f563,20db2860,9062aca4,7a136e85,40ebab0,3f8b5f7f,93bf0369,aeee0cc4) +,S(b66a66f1,9c94868b,3e45139c,ef9d7586,1a6d06db,72027814,83dbefbb,41157a94,5c0763d8,8aa90b2f,ee04eab9,fb96b280,5ed5f7e0,58c9805b,64fb17ae,9a0f224a) +,S(5318b13d,a824dbec,eced642d,d742ca30,479874e,31c1013d,d770a0b3,c9ddcd9f,13093540,9b5d56cc,d5004948,3bb22009,4b7d5a5b,6d357bd,76b79117,458e60ef) +,S(6bef6b9,555f29fe,b5277c48,863c990,8f1fe2c9,5b4b45fd,8c5eb482,3ef4964c,36c00eed,4281871,fc5e15d7,7acfe3c2,6793455b,9b3607dd,71f3e163,9790e3a2) +,S(7972f783,4c010837,89b92a08,d21b8b8a,b6ff6ef7,92eabe32,fa1c92da,4c8dba6,2c3352f3,f458a538,f8228321,c1adf9d4,a2df9f8b,bd22675b,afbdf041,9538f1e3) +,S(7f03f087,168dfd24,7a93e840,e68cd221,f02735d3,93d777ec,c9d2c9ff,7cb0228b,663dc741,fc8e98d0,7dece960,5b506b5d,a5f2af72,1b64480b,1dd3e7b5,a0ee7743) +,S(d06ffe61,973be011,2f17bec,6f4dedda,9b9d310,4ed22ed7,d4c2f009,843d2c04,175f409c,edd739dc,5adea16a,187a951b,d42df4de,d1aabfae,d56f1ac5,26cda8f5) +,S(9094c510,3a34209b,45f7062e,ec65c14b,72fa75f4,13999117,38cd7f6b,792119d9,da541e51,7211db66,272f8f8d,413e1717,13cf499f,6c9cd694,b98e53df,45e9d501) +,S(22bb9cee,8a5b99fc,d7ac7d67,5e232183,3f71a72d,55248a3b,451699f4,9f151eba,841e7292,93a98297,ebf2e9a6,6d106325,265d91cf,f7e4c245,845e5a40,522b94a0) +,S(b548dacc,944b013e,d50dfadd,fb84173f,d5829b2f,69a2242b,c152684e,7b8a3ecc,6c7b70fb,9ae39eaf,583939b1,1a1b8aad,673b18f2,7568d2e0,b2680b19,8c662a88) +,S(34f46e0a,2281a617,f8ab78c3,86ed27d,f837f23e,e986dd20,bf705daa,1b0188d,4ce4df08,bbf1e735,6760e05c,6e5d3f3e,664fea9d,6e1a72d6,bad17bbf,a3c089d5) +,S(3063ee2e,3834842b,84cce6d9,50ba5afa,1d645c5d,e0acdb00,a9cc4ce3,c266f649,b08247a,f79c2be1,a0e4e021,7c9ccfde,f76d1e46,65f3185e,8623aaf8,63bff9b6) +,S(d7232b55,3740b2fd,464a919c,46168ef1,e09638e3,65117eea,979130aa,d40fc525,f842c256,38e84dbf,47d13fcb,1763a296,47b72908,1b522623,4e307dc0,1a402ded) +,S(6025e82,e2ec643c,32b10e6f,62ef310a,11576957,96c10f8d,b099dd4e,1dd8cffa,1e5aeacc,cc5c5455,d542dc51,b12fa3d1,75061cc9,45931548,7467d09d,945e2596) +,S(141d07cc,256c4d2d,44ddb7f2,ef720aa8,4bef767b,3597ba32,3b39915c,1d84f175,a842c439,9366b2a1,91e850df,333c9cd4,6c983158,cc57989c,588c305a,1144ead8) +,S(ba4ad105,6ffde493,54d13149,31846519,86fee8b2,728917ec,bd1a0112,b986a90c,97ac53,f84e995d,92d14f0b,b156f47c,be5b6506,2a7f8b07,7e235da2,808029c2) +,S(5a6ed894,bae212f3,eb44304d,98ffba1,4a944cde,ccd12517,5e52d767,5e0f801d,d8160707,d43053e1,e5806d7a,bc17563c,ffaf92da,ac51deee,55fcb9ef,715b08d5) +,S(d82a95b6,56bd1abe,50933a3f,e291526,7b257807,c8cde42e,5f1648c7,f35c4f3b,748904dd,3157bb07,65f94c18,7528c74f,ac639a36,be18963b,676b9b37,83f54591) +,S(df7c9de9,8e748188,74967340,34a76645,c1e55bed,3a90fc65,dfd9726d,a2bd3826,3bd77fe3,e4a4018f,3e256ca0,2bb5c8b1,b783b729,21ce329a,fff9caf6,b530b1fe) +,S(d3ae1d68,4614c95b,51cc4af5,a9e8a05c,4ad7eb4a,ba4a65a8,9a151b96,d91bdb68,a24cad0c,ad0ba98a,860d6d74,aea57c3c,23780812,5fb2356b,b55f0bf2,95e25e67) +,S(ca85c924,48a27be2,2b68c9f4,c9ab431a,b380ccec,2439c8b1,944c234c,bd865758,c53177d7,6b16e0a4,389e1e32,7072d460,90e92f48,22043bea,924fab46,4023038c) +,S(34309aa3,4e9fda0d,f2c20da2,3e8f8f31,eebea096,1e769c92,6c4251bd,5440bb04,f655cca9,d5811164,577d0525,2f5605d1,b4e2b6d4,dd5540be,aefed4ae,84caf3e6) +,S(40212a4a,b2bfcac9,62442617,8a807655,185d2929,7e26c437,4879903b,41307b3e,26624605,6ceb4509,b481df00,79e25f1c,4dfea60e,a3768e8a,462ac273,8166dfea) +,S(2e441425,d121e140,5d2118b9,7a3b305a,fcf62e91,4f24bb72,46e92aeb,1ebdd152,c3c7a567,51dfd709,9535d07,23778131,692dfdb1,7584d9c0,c8fed42e,5eb662f5) +,S(31539912,9e59668b,49d9b8bd,5ee66b2f,aa727ff4,96f457f4,33400a20,b5242b5d,5e90a20f,a700c59c,fb0ca2cc,ae3f2837,6dde44c0,3cf6af64,365e4cd3,b4e6b3b4) +,S(3b586e2c,30eb1959,bd5171ad,54b81c36,cda6b0ec,b5e77b41,a7b5b0d3,e1ed4ba,6782aac,d675436c,d969f413,c471edf8,ff7d89a,d0a07575,16bb695b,19ef40fc) +,S(f4299c9e,b3453201,375b972f,fa39f01d,90c68625,a63c9d06,513fc9c,8c623fc3,cbd0e2a5,f9b9ebd3,f482a5bb,c5c17894,d5c320e0,28744292,31c94fe5,55ecf68e) +,S(96d35f35,eee50b32,32371acd,99d6db8e,d2b7c4df,1f62b867,5559543b,785503d2,c0e8bce8,8bee1e02,29a5d2ac,113c9f2a,feff0260,869ecde0,7cdb1cd6,3ba5f73f) +,S(ad3036ec,e2bcae0d,1fc34680,be2d293f,b40d9133,905af375,1ff89c49,2c183e1f,2c0773d4,bd30833d,24222f89,3a4f5e8,cd6abe06,63d66d63,2d5fb832,4c260f9a) +,S(a0f340da,909f04df,70a33195,1c48901f,6353f4d0,4d22f99b,3763f567,be9d207f,caa1d9de,46a37b8d,623a39a8,6792475c,bf3bd694,597351ac,515ecc8b,1a4fe78b) +,S(2adc4874,af0b3cfc,675421b9,5369ff0f,950b55d1,331aeee3,dcd0adf3,859be4d,6ad9fd3f,a840d02e,ddc01fa0,ffa61bf9,4dc1db4c,ec733976,bf1c6e41,bdd92b79) +,S(b9222a37,c14456a1,cf931410,d96cd84f,a304b9f8,5a96edd7,6e67f928,43536175,4002a875,dfc4cda7,4ff7145e,ca46aab8,8cfc5ed4,53b34eeb,1e5dd859,4793e3d3) +,S(530bae23,c3796fbf,76f86f6a,d8b59b80,801328b7,6c46e8f1,cba6398b,270919f8,d4d3b34c,6701f07,bc47d1d9,fb868fc2,b46ff397,2086cbc0,517e29d7,38a7964c) +,S(a7f2ce51,5b932506,c740e84,40f254d0,e0da57bf,4d9199f6,acfa3664,ec36b823,4946fc41,3ef1b3f1,86a2c781,6c05ce7f,803fc7de,a00fbc2e,7e6c4688,fcddadae) +,S(8ff613d1,1c81c4c9,fda3860,cbaa71f8,eab9ac3,d9263f31,55317949,d6ac1d53,54f683d1,fd382305,b2193554,bd3a6d2f,bfbb99b7,5d9c3e1b,876c3b52,e2bdef49) +,S(6fb3bc81,5ef3d8a0,d7aa1a69,dccbdfb6,3f7a58c4,7a12f98d,b09cc105,4306422d,798fe7ac,f9fc71ad,7023a8e2,c9376161,8fa632cb,ec607109,d28a63a3,9a4228f9) +,S(c32aa38e,bf0ec0ac,61bbea0d,d2c633c0,bd49ddae,d77179c7,e0098c8f,4488da8,e01f5fa5,1107cf4c,f4c1c5,78c3b5f3,a1baa059,90bb8913,9e2abb30,2e9e5042) +,S(ef5e1efb,d1ede40a,810434ae,833a4681,5f9021f9,41ef1d82,fb8c1399,16c4933a,94a9cd1,5f160c1f,4f85ec8,16fd1834,9cf19f8e,96ac9247,695ca37a,dbad6ef9) +,S(8e3aacf5,33de35e,4f923b36,c378ea57,7a5aa477,70ea6390,f92c73d,50fbfed2,49cd7650,ff69ed12,b96ac3b1,420784,7677497,b731e0ce,316eed65,7e40e014) +,S(84521790,204c64cb,e026152f,474b0da2,25703d93,25943821,7d66f20e,3ae0d06b,c1da2f7e,438fbc82,57f7fe4c,7e49b73a,446a19ae,775e7f1d,20c8fa31,edc3bd20) +,S(604cd900,97fe538d,b27cc2cf,a2d6c79,692f2e2b,c1b1b23d,1f0eb949,df560697,914d5288,29765538,d77f8e04,182c50f,d2d9aecb,2412ce47,4888d666,46b2258d) +,S(c13a44bc,9a27e241,5531b8a0,5570e66e,6763b3bf,a80e00bf,59d6124f,b3d67858,71557bf0,4c261c2b,19196d0e,9e459f3a,f629cc19,84f411,31835400,3a60563) +,S(14f3399d,5204b654,23d9318e,4adf3af9,dc43099,eb43b719,eb4644a4,897ffbff,13808cff,4c096655,72329034,d489433d,976cc011,d1a30ced,702ba4e9,5892422f) +,S(bd84d712,43dea7fe,f151b207,5d03d2ee,170488ab,4175965b,128411f3,f592a36d,57a1c602,408fee75,ea9e683f,43d7a984,bf03d66a,37513c50,5cbec6c6,6d286fc0) +,S(f319d4a9,b5f2c1ed,6619ae06,e5aaabe4,13a2a6c,265283fe,4a51c7ca,6c49b572,bd9d90c2,2a369a03,1856ca9c,86426171,db952537,edbb1ba8,93fd16ea,35aa43b2) +,S(9649689a,424ec9f5,aa4cf4c8,45588046,c50eaf9f,700d0412,83e02640,9a80c61b,5cba8567,95b0440a,53e0d1c6,ad560364,c398dda9,d2e97a1f,e594355e,1402fa33) +,S(45fe12f5,a340034f,381764b0,adf503b3,8026374,70eb26e9,6f4181e2,68cb1c38,ab7715c4,52e5581b,ed940fde,355892f2,b8a16a3d,d322123c,14a57a23,72f244c1) +,S(98bcd24c,3222401a,a4683213,5a378790,6c9812ee,989b8f52,fa522c6,d39adcc7,14c7cd38,7bb5191c,f49bbe41,52af8b03,7135a6a,bc7e4697,35a72a38,e44433a4) +,S(6dc56512,7be34196,a7653057,f79b854,83c275ab,65c05c2e,83663da5,31d7d652,a6839fcc,ba7db053,affaf5a9,4c95676f,9d65eba3,c2474472,cadbde17,2ad3692b) +,S(7a7f66de,b04492d1,fd2fb9aa,dbc4ea7b,ae5a3801,47b86e68,60513a57,eb6b10f,fffe4f2,b722f36f,1e555671,90d84d9a,39b819e,fb7a3436,29b83adf,f6045f05) +,S(aaf9f188,3865e2f7,eb500794,3888b4ec,9013371,f7162947,2cf52adb,bb5288b,df634c19,e7496b4b,478bc10c,7c00ac8a,5fc24dc6,4f193355,f0fa9c62,d6048243) +,S(6304b1d7,56988ca,25afb747,476acbad,2e5afa5c,86136090,c86a82a0,e52b373,91a2d829,2357463b,ea1a7cb,33d79be5,8bd71732,f1d2cc13,ba4b2724,6fd39f05) +,S(6eb17147,2aad3d80,bf4e06af,a36e37ee,5fed9c18,bbaa1c4f,5cd871dd,c526515b,6afd615a,e2512fa,70c9670f,b56682d0,f304a0c,6a23d1ab,fe958a7c,2a4173fe) +,S(9113b613,ba815ca6,43e7bf66,27dd71d9,8c2d40ea,5c00f596,6216ca9d,d32b1ce,8790dac5,bce4100b,8e4e5135,66a104ac,b55d3ca4,3d6ea083,d23716d3,3894de2d) +,S(5c7af38b,8821169e,2f7e2edf,18b3b73a,c387e6f6,a8ef1cdb,441f5a13,284f365,e12619ea,e2a07b8b,c55dda85,6cd37927,d448cf2a,f4028459,2e371e10,8e91358b) +,S(becf19e9,23fa7b4,1cca0efd,937a5b11,e227fd18,22743fff,80c42692,6631ff0,3213c209,9f255eee,93323d1f,b440cbb7,64e86f1a,4021b82c,485517b0,3440ed4a) +,S(f22954be,430be6ab,34dfbf92,264c2406,df3a0a7,19ed45a4,d09cb161,4abb0c91,a60397e3,ef3308a8,12527744,311673b,c18bc43f,352dba00,4dcd4124,7b84846b) +,S(c50ae8c7,61776e62,5156f9fe,7d863c36,79d43126,c5f3fee7,5b837a38,1803e770,be966bf5,99b67e6c,ffc421a5,e6d12e4b,cbde12,4d84eadd,781ea562,aac7dab8) +,S(c6c3a65f,e849c113,748e9b6b,c9a9419c,1a919503,36201a6d,f989bc5f,fa07d359,fc205b83,b4764ded,ef58082,11eef120,4d9fa959,4d5b7086,c2fa2c9c,3e56f37c) +,S(73466c27,8d5f13ad,dc7da10c,b8855c23,9069f57b,6ec5e80c,e27191aa,196d9b1a,7e7e2cfb,533cfe9b,24243cd6,7680ade2,35abddc3,d8d00faa,c8adae39,15ddf6a1) +,S(6315ac10,35eaf884,8919bb56,759f7013,92fe442c,771a42dd,dab88ab0,2fb0df2d,a49d2c97,6e0e66b4,50e8511f,d91f0f71,a7516fcb,70ca61a0,98f135ed,8e19396e) +,S(fa195146,fdb7ddbc,41daa8c5,98e1f811,36c33eb3,bf23dfc2,3f20b36,1c8e7bca,324fc70b,38677dd4,c8e7bd82,4b836d0e,738dd757,ca408ff1,95bdd5d2,bcb5cef2) +,S(ac40bc48,87734bd,51247e91,43e5e188,e5e2bfa4,2e3c0392,f39755f7,3952bcad,75904ebf,603c2f07,4eef9435,eb22c663,1279afad,94d3bbca,d5349881,7dc4a472) +,S(15b7e1ef,d2c41c6d,416b6dd2,5f6612f0,a0acb0c4,1b161b4b,c40c5ad2,a92604f6,a13da672,17501833,4c4057d8,85be8fb1,ceb6d369,6979b805,83fc0a37,bc27a0a3) +,S(adf4aea6,6fff705d,5bff3c84,93e8870,4ba4019f,ed550cc5,c203439,ff8512b3,53ad2122,30528e1f,4fee43c9,2369dca4,3d071177,3ccfff26,aa16a502,6206a3d1) +,S(da0d5286,fc261d92,1095e1cf,f67e729b,501f21b9,45e8d84f,ba2c80ff,335d105c,5632ce7a,e8d9ce7d,aac7cf26,2ef7bd27,418613c,b288e793,35a0a638,6abd83f9) +,S(463fd081,daf02794,18b95a48,bcb8dfef,3a9dc67c,2237d2e5,dded1522,f714d6d6,3de4cc76,7126750e,4038fb43,bf6af17,63ebc0b2,ef56ba8c,a376b815,6b4f28b0) +,S(15e37b9f,58ce033c,2f0ad85,d49f8207,2e2547c7,91c7ec52,a8606974,2badb586,38816873,5e37c957,c18ad56a,e7ab81ca,8fd89a2d,1710f032,54393ae,a046490d) +,S(2e121b79,765d4f4e,8e7aa8df,5c70e4b3,716b976e,9e4536c0,dbb3b5ae,4044a345,d7ba59fa,97a7d6b3,8b70ecea,312cb01,f9016b33,c160d1e8,d33fdf50,ffcbc928) +,S(8d4c7aa3,c59dede0,bc146b10,38f8f823,8182c4a7,1cde0d8,e17005e8,64ad29db,78aa343a,28a48f90,edd7fb31,849d6d3e,fdb4c677,73cb523f,82c0b187,2c17f44e) +,S(1ae12a1a,19a5d1,3b2f42c,35a385,f8302721,86a67801,c22818f6,94438c58,5cb421bd,990ddad8,16de9439,87bd96e7,e1ddfc5a,8d0f86f7,b30e3483,897815d3) +,S(7a6f584c,d48be9eb,a7b73377,8a173d5e,3833aed3,a603a226,741ae1f3,a1c21bbc,5995b840,bcb6cc28,b83d048,9faa5dbb,c6a93190,46b11b13,59827266,d177d27c) +,S(2dc5ccb4,8f78db2,3f0933f0,ef67bea0,53c7f2a6,80788bad,b71526a4,f55fe758,9e4743f9,ddb46206,a5449942,71743b44,713522f5,f358ab47,34c9afcd,f528736a) +,S(f7a5219c,75dc4426,4322bda0,3b603127,26a6b3aa,c471f42,a33072b4,a44fc9bb,9e1feda5,5da277d5,cb18381a,4471939b,a12c692a,a40ab965,fd03949c,d8124ab3) +,S(a1bc311a,e29e3926,5b3be1ba,23d7ffee,df0de8af,fba089c,fad797dd,8ba67c68,9abf66cf,109821c7,68c98164,b0598068,c4590d7e,b9ff4c53,594af6e8,e0ceee8d) +,S(2c2ffba2,e3fee930,fe8d061,3bbb8290,22429fc6,654d5ed3,61eb8720,1d6b92c5,ed89f28a,bad9510b,acf44d05,5934cc64,ac7e94e,2dbc72c9,986e6cb0,acbe434c) +,S(1d157e13,97f6b22c,3dbfe448,d1168b8a,bc963f86,bb3bda29,a8011f07,d2cb5ffc,bc7cfad1,e1633419,cef1c82c,d0249ee8,4c38b3f9,d628337b,aacf0449,4ca3c0b4) +,S(1b9e9723,56f8a4c9,5e8d5fbc,8e2f2cc5,99c77d62,90b2fd44,2e63b3e6,dc33c772,59db6eef,988386fd,21e8a772,a1fe048f,95ba77a5,122253c0,1a52830a,bc12742d) +,S(80460a3b,16fd9ba2,250b07fb,c77f2526,bec5488d,7d6c45ae,6f480308,39af48fb,bc7648a7,744347ad,e17da2e0,5cd1ce10,db704acd,26c81fbc,db251ff1,c6fdef10) +,S(c6903a0d,d8c26c8c,cdb675b5,972aa050,6912813c,a6f0c8b0,2edfb792,491222e7,f4759b4e,9db7f1db,7c8a1c38,dfe76d86,c3778423,29280aec,12b1be06,d8e49ff5) +,S(95ab78f3,a4268c8b,39aa645d,8c9fbfd5,b92469b0,809d6369,3d57d076,d305a241,8df4c8d0,ed85ac01,a965d580,78f36a5f,690aaa03,d9479d1,b2297a52,53e3c6) +,S(bafa3ae4,40a4b8d0,40862a18,cca806fe,8cd0e780,483b396e,41543486,db91d9b0,d7bd60f0,c0ee0b8e,38aad85a,85a42ede,56c66d54,ee73d371,a3bb7cdc,e93df670) +,S(7cbf5d9e,3bea6864,b87ae157,fee6e352,dc3a4f32,6e7cfc68,377fd199,a6dbb71b,42d082e7,5d55eb62,9771942e,3801c27a,fd80b502,a997ccc5,9f5a95f7,d7276999) +,S(9108db63,751b8a9e,f4870524,f1198f9c,c4d3ec20,af54119d,6011f263,de13ca29,8c1d6c47,aa016e83,d2c8f76c,df0935b1,b6f909b5,bf5c90b,f4203493,22c711d2) +,S(a705e7eb,c20ac4d7,43be660b,d61340c,9629d069,1b08ef01,a59e78e8,2d8b347,1ed8ec9,13ba19e0,851e1912,5854433a,f71b21d8,df64958c,afc5d7aa,cd29ccfd) +,S(b75483e1,60144d46,78af9a3d,701c4ffc,fe154c49,fad45ece,3945289d,c3781c3,a4c0455,13cfa7fb,ba2931cf,722fc569,87b2c79b,c4b94313,5a458d34,5ee16d57) +,S(c59aff26,bd4fdb9,37468989,763376f5,64abce,c00d54e3,45b6dc2d,9b7b76cc,c396c194,db446fb1,a22e86e1,8a37981e,d114e675,474bd24c,784daa96,91eb15b3) +,S(2f6701c7,815ba7c6,37c4649d,d05a31d3,e909d8ba,931e7136,1e0662e,3ea19985,937eb67b,9262bbd5,12a21e90,393f9e65,66e03203,55c77afe,cb98d1f4,bd25e8c3) +,S(170d1e33,f0862542,dc72b1b2,950ba98a,812cc308,74ecd0c9,23ce7c09,ed7cf9b3,5148ef39,68ff35f7,a633ba7,dab6cdaa,54dc6f87,510f1a7d,4d3019f0,c00bc868) +,S(743b02d,b02301db,453f8694,cd517c6b,433f609c,e205cac,6f6a49b8,55890708,7af6350d,56130339,1a9ddce5,f566b9b2,9c10d535,d5183850,6c743124,8dcd707c) +,S(ba6df8bc,f9d83988,4991c6fb,e0aa0ecb,d0b6cdc4,d0e372f,3ec83b51,da6a6570,7d27b176,3a01a8bd,fb7dbe0b,226dee6a,73ed3644,807ca33a,1f5fee61,cc161fcd) +,S(d3b63a2c,364f01db,6a6f384b,4bba6c2f,2fa46a02,86090826,1c8b5045,4b92ca5f,df6b9cfe,fe7aa14,a38bc44b,8b627b6,e0ceeca7,1720d630,cc4fabf7,b020e2d2) +,S(638c2b1e,374ff6b3,4b634f4c,bf363bbb,55d66c8c,af4d3fed,43cf436f,a1daa7f3,9854873,37b48f32,4feda3a1,f267dbe8,8831aedf,d7bd36c8,6cc8d862,857507d7) +,S(1749ab4a,607d7864,5c4cbd30,4bc34c06,94a7a636,9c8c8f8c,be4602bd,16c4b4b8,465bff86,b459b842,dfae4df6,99be1758,8b1aca97,f9802827,d892792c,748ac92) +,S(9071a5ff,ff23ae4e,2d81b2fe,d341bfa9,cb86ae6e,ed32870d,d549af20,a1db9feb,c0e3d4e8,277d099a,9801ddf3,3e513aa9,1761218a,967d530f,21d70894,ea7d38ab) +,S(91bc0055,28e2d857,ac644954,242fe0c7,bbaadcf2,9119837e,898244e3,a305ba6b,6fb63758,3aefe600,46997b88,315d5a24,683ff955,94398694,be304dcd,8b588f67) +,S(9663913d,48c865f6,312fe51b,6e8e7c6c,51ae397b,d141aaf2,df3d6ff5,edebbe68,c6251751,7e24d81d,b1da26a6,6627fbb3,28b5f818,6477b34,43f7c36a,918753bb) +,S(e88e8702,7843b941,61c71887,9a0a9a90,cc0d6dd3,8329c73c,a18acca4,3f44ffc9,7e31ae63,1f9c927f,bd055f58,e682935a,3225e778,9221a062,f2826d86,97143a61) +,S(5ad27e79,dee03a52,be771a9c,ded6a02a,58337f26,be810d1a,f8cc5ddc,f1eeb917,91c18e01,dbee34e9,a5302a7a,11bfa7fd,ac852e1b,e53aec2d,3138259b,bb53e6f6) +,S(bb7f4694,f2935a5e,8711ae47,bccca550,cee2632,4347b468,58e40c74,49111ead,d9f94c14,332ad75a,59dc784b,d674e8c6,146a2b74,566ac1ef,b0ca17dd,9eec8d74) +,S(ff77ae06,e0624cf5,f6d905ee,b0de7281,5377c026,3e01b6c4,a139e4ac,3304e82c,1f27acf9,933d08b6,f0892199,11805d14,1611a318,661e6e7c,75014b84,cc35c395) +,S(84c15fb3,1b12d39e,ae59ce0d,f8646e9a,67c85492,8d6c498b,4b836be2,eb19a060,6aea0d78,d54090e3,2216c3ae,be0dd433,a666e67b,44cce0ec,1609804f,fde33f74) +,S(9a48086a,8bb9b150,a6ccb966,3978f555,41db6d48,1b3d5266,e958cbd1,df9ee7ab,d8eb2109,13ee09e7,b5767661,13157905,b3cafed4,641903b6,da0ebc08,a0ce2f58) +,S(db32ad19,45f4d9f7,eff1b8c6,b87c5545,1b0c74d9,8f1c4ffc,6ff1e79a,21ab3033,2d56e65,a70bd23,617f85f1,4a5d0e4d,52aa6a70,a8594158,36d02d87,309c7eef) +,S(4de7f1aa,b9089f5c,b6d95b67,a04952b0,d4696cc7,6640e1da,f4bbf7d1,da985851,96f2cd33,5fd4b816,4499ddc5,5e81f5ea,c4db4399,17f2151a,f86d2ad1,e2b3612e) +,S(74bcfa73,5aa43e8d,1fb540fc,9922362b,21878c09,666bf541,a0e739b9,dcbfd1c6,84b26fc2,8b2a05cf,a67947d4,99c1ffe8,f94ed4d4,6ba583b7,cf26ee81,ba60bca8) +,S(9c596bcf,3d2e1df7,cd8d9807,8a1ab17b,f16e27d8,66cfb582,ef58498c,48ee0fc4,14dfc093,48f72d7d,af9e3599,8b5f18bd,5287f3f8,381308e0,63666028,dda9ac56) +,S(8e2a0d3b,2786d67c,a15cd72,4f2cc6dc,16cddfc5,cf080ef8,d9576b2e,e5b0ff9b,2ec4853c,c83c72d2,68555129,ce30c836,50fb59b5,17a3d61d,56ac4273,1b33ad06) +,S(25ec4838,5fee8fab,773498dd,85a23ec9,46c59839,14fb8a9f,d1239ea8,ade3f829,123bded6,5312030e,d4760047,1867aa4d,b7537239,b363b6cb,58ecff98,44986924) +,S(a1cd9872,7551e2c5,db7985b5,1698b97a,31b90d3d,32fbe60d,34f8ec2e,398df76e,40858565,aef814bb,8bd91fe1,410f9556,3f1bd170,345c1283,b64fb268,4980c398) +,S(bf7d3973,aae2cc31,e831390e,f2458e85,9ed6847,e9eefd6e,cf91e3d,4a4924ef,c2829fc4,2127b303,c801605f,35602b84,32357564,d9333ba8,d962d639,ef21a6aa) +,S(5a5299ef,e0d394ef,f4b510ba,96dc73bf,6332d358,e276bddd,527ec290,b73e3313,9ccd4618,17e18104,d324e1e8,1597eba0,cb6b475f,4e5f2e02,9cfd2d63,b613de79) +,S(90efd8cf,9e4b9d74,5cb36c13,20a8bb0d,b5cb8578,de49ea4b,c289043,e2ea810e,87a73339,aaceed7b,af47b5eb,97aca554,d80a4f78,d439ee14,4b2d0fb,f8df5e3a) +,S(3a174294,4db7f2d7,2498e2fc,e2026d5c,f8600ed6,958db97c,24ac0de8,417f6def,e60c566f,f3fd14e2,2ff0cdee,45c4c2,31797951,7aa0ca68,af91a5,e41f5f60) +,S(2213e0a1,3679040f,73e4d68c,bb941665,6ea83640,33abac76,2e64d509,48a97656,2b87ce0f,bec2728a,aae6586c,bc6d9a89,a4bb9b9a,211de522,cc909279,5860791c) +,S(382412a1,ab396523,8b06c47b,e941051a,bef3b215,16efb280,3ff3a1c4,824954c6,7cae8b14,1938312f,ba482980,ab9073da,c66c1ca0,d746231e,8ba8f331,4cfd9cea) +,S(3d76bfac,89c1269d,53b6ded6,bf13c785,361b1fa3,84be2ea0,d582ee43,f06de56a,18b1cdbf,96d12859,bf887b89,6d8f2e6c,a08b892c,688c7687,8294974d,af6d6284) +,S(715b18a0,68d86cfd,41a20541,847b36a3,ed7814c1,b5528751,927042f9,85e7ab70,2b8e0228,b0a4d39b,85a3d3d4,f5a10db,c6825659,f4b967c,361da449,24890911) +,S(a31a10ea,e38e6a00,ab4f004,8b45c8a3,e57856b0,d0b64e47,fa90e234,e17943f9,5d4b5150,7d3f3a82,87e5d51,6bb30b89,2cb9f540,96aa5962,1f77e028,480e594c) +,S(b397f965,1dbbb6db,34708066,a1743511,d4a16332,95f53772,72c43a6d,6e21c1b0,673fd327,45bea2fa,748a759,30679b2,471e4004,423dc8b3,f34f95ea,f88d2b8d) +,S(2e4b865b,c1245325,1ad8b3f6,e8776bd1,a5878b93,ec34f847,65af84fc,146d9919,b3e7d479,661ce034,50094432,c538f55f,c8be8693,73a91fd0,350c8089,ec0d76f) +,S(9a38c790,7c0751e5,ba750bc3,485b4a4,72b661c3,63a3980e,feeaf59a,98533a43,dad7ac3b,65493036,d30068ca,72808000,d54b42d6,d263de93,a1ced3d8,fa82ca71) +,S(5599d251,3b3c8337,f8af18ea,70d1d2e1,83f3e363,63735357,2b3f6cba,b4371d9b,7ccddd9e,ec8dd507,69f6f633,cc70488a,6a4e322a,2716218c,5de50fae,45398dfe) +,S(610c472,4699e983,530e8a32,b60a8077,c7f60226,cc3b2010,e49b2e30,f2a98afd,42157de0,fe6d8e53,17a3f565,fa450f53,8755679,6d98c7a7,ba0b3e96,844d25d1) +,S(89c082e1,1438e2b5,6a4bff8b,cadaf804,c9d11fa0,8f47bff5,39cd0741,76f24a59,f4dad4e6,19ccf814,e899d48a,904a88e0,6db6ab19,a2e06a7,b359db9d,cd0ad0ec) +,S(bf810fed,48d1ec4f,77cf3732,ed10a44,df9e4540,2e1a1e1,6b29c82e,32537565,6657fd30,337e294,fa31d30b,409b426d,546a47cf,38cd23bd,75aafaa0,b527d66e) +,S(3b1317b8,bb3c9c91,964ce369,19ea811b,90a8bd5d,ebadabc2,d4d1af3b,50fb3524,cfd5988a,78aa555b,595531f6,5fb0e3f1,e756c1db,626cf60b,4c1b17e6,caca603f) +,S(88520439,61558d79,7b084143,783d9e03,791e6183,c932d1a4,17eed30e,bcec0bd1,271097c4,4c723ab1,c1d13e9,93b7b232,235957ef,f21a13b1,2b3d302a,ed46ba1) +,S(6c420c30,343cf500,da0cc05a,c315d3c3,45ed8aa8,e0551bb0,32fbc512,732f34d7,fb3c0808,698d38f8,3310fe1c,15587cf7,137bef2f,666229b5,bc789dff,1b2f1111) +,S(b12e21e0,e060fcf5,580d75ef,22e8a800,33e2c19,487d0660,615f7d51,ba00e430,3931d63c,a6e0da2b,295bd22a,4bbb27f5,fb52d89a,3c4ac36,795747e6,e74ce944) +,S(4fb9da54,4da95655,c0de5654,f68c2820,a7884734,4bad6934,e671d56,e7bfe11d,16586701,9bc89b28,f5fdec40,78a2a51d,6e087ee4,29456cf3,d258b97c,209d44fb) +,S(18f8f6ef,23bf75f7,a7811025,5babbeff,792109ca,5a550472,245552e4,35588e7a,e712abe6,3a374f25,fd4b18c8,4b1451fd,ea77692a,43c0e3b1,cf3469fc,7a9acd55) +,S(d730d167,1bd36654,7188c07f,78d82ed5,6775d7ef,bd0967e6,1abddea7,7ed6073f,49c4bf3c,ad4e31df,d840045c,aa8be15e,43f90196,818e30f7,b379c74c,1d866553) +,S(a915fb72,7d4c40ab,547c983c,24a4f019,1f5e89ce,7ab0636,e903aef7,592208a6,fdf28a3f,6557f27,5813ccf3,8d927f40,b910c5a9,ddc3c83,14a48eb1,6a5956be) +,S(7abe8d85,bd95c580,cd9d532c,c1295f5a,ad5168d7,e3dcaf28,b19f5e76,95107157,694abe9b,9a6ed0d4,c3ac1db8,79b49038,6fe9d2f9,443647d1,91533fbf,aae3cc02) +,S(93a83e8d,c80c7cd7,64dafff1,edd148b2,9c336de7,cf978b14,fbd35625,c965942c,91ea5775,db50bf9,a7e3f79b,77c7d5b2,deddfa08,a1d455e6,fa21e547,356c634f) +,S(a334ed87,dfd2e1fd,699ce1f0,a09fe921,487f8321,6cdcf75d,fc8d7e5d,cbbd1af1,42a0874e,d148bd32,ba4324ae,eb0260cc,7f0d20f3,f43388,38904640,8f7ae7e0) +,S(811597c1,f4129ac6,e150c231,bfd8e4b8,4ad441ff,2c698486,affd4ac4,c22bf8b5,5f7fb47e,11b476cd,acce1552,95ac000f,3acb3838,6ad3c6ac,191dc12b,d1e299dd) +,S(cf754ed2,47c9eb9d,24f3129c,4b4cefd8,94b5e58b,832f158e,2e82911f,8177a59f,262cb605,2991777e,bd1ed5de,d2e7ce29,76dd73d1,ad4c9bf4,9fb5d8fc,fbe4a3d1) +,S(290ec604,a6b4d816,ffe75715,419b0f33,452530dc,94f48883,b3982161,4592b229,4235db3d,df2e3f1,b61ac412,a90f543a,ddcd519,4f4a315e,d889b32c,ec8f76e9) +,S(1f90b869,4bf9ffb5,7697ee72,29b7f20b,52b47997,35efd7f4,1e4b9102,51886858,dc3d7a68,abaf70b3,c84d533c,48ef38f6,9be7d26a,13c4e834,5a7bee29,c6d3c87a) +,S(ea20b4c0,931087a3,44d5642f,6c018aea,2da5f189,a4d25968,96110281,88545ba4,f9adfa96,f945e745,88d2ab41,e32ef5a,76b370f3,f0362e57,129c3998,e32cedeb) +,S(b8bb88c1,21948c01,3a61fbf9,bae86eda,28e9bb4c,6870b0f1,7109e5b7,c00cf4e1,90685129,8607d7ac,25bea5c6,1cc4feb4,4148e07d,2fc3fe7e,449773d4,8245019b) +,S(2345a244,f2f411f6,ef091904,81eb9083,9128f7d8,67e8b910,124d1e44,d116c529,a8eaf530,c69b792,d6595967,4f23b9,b0e239bf,b69d05ea,466f9f5c,9bd5affb) +,S(75aee824,38bb03a9,b9208cc9,b725f13a,1fee1aca,20ed129e,e5ecdd59,b92c89cc,fb6bc8a0,fe0f684,ce4cf153,2053312f,b97aa1e3,739fab8d,407db39a,737ee51b) +,S(ca46d3eb,c981eb1,764867,c99cd7fc,c414bdf0,31b2c9a8,96829ebd,f31e2e36,46363355,862a64b,97541f7a,7fc5cf51,ecae168c,c6530db5,3a7f2394,2e87bb96) +,S(4fc1d258,575c4830,bc7a03d7,6a259406,7d633e9a,da2c734f,45ce4d9f,99dbbe7d,cbdc616d,fed2bae2,9312c5bd,9e195bb,bfdeb2c8,d1aee5e8,cae8fa0a,4bd6baac) +,S(4edae08,54365c27,f6ad83b3,8f68c7d3,f0a09c6c,153791d4,df98b5f2,3f0b9be,cdc8a485,8ac66847,c732a2c5,4be86af8,d6d637f3,e62c7802,dd71c7b9,2eb18223) +,S(624dca60,16beeb28,c35bef5f,e97d320d,d725619c,3faa7ca5,ed79d491,72b12469,cc33b49a,6fd125cc,98d65a81,c0713cb6,2a7e687,276e7fb,641e2f76,52646c12) +,S(6738d38e,760e50b0,6a18a9eb,b5e3676e,c38f3487,e34461bf,2e5d52c,5bbd6b4a,c3ce0343,9b9f624e,a92eecc9,860ff680,63a907d5,b57c43e,465ead5b,bef5e709) +,S(bcb74527,10f178a9,eb48655e,3d373b56,8f02036c,e9ab826,4ab7cee8,52f7f9c0,4e928392,52ee05de,587c91d4,6eaf5e5,92ef41e1,5a2b5c2a,da9e4512,c25bb416) +,S(3375c7ca,1b5fb4d1,1838ffa0,c21d7e03,de34ca5c,92bb4592,bb4598c4,2b490382,8c284e32,f016d186,875b87d3,3bf4271,4b9013c8,ea159634,b39b7365,7ea837de) +,S(c347409b,336c0677,ee95de61,f93fad4,738268d5,6f31059d,380af075,60e496bf,37dfcc4c,c13bbfa,5df43c69,eda0c68c,42de70d6,ab64a9db,a4ed22f,1cec3fdb) +,S(305ea4ad,ce72ff73,976544d7,a3deb346,452ce997,f280c3a6,106b7c9e,3b9bf5d6,bfc33cd4,ca178310,c4caba86,5b87477,77e9e572,4278f0f0,56b86a86,1f2e13ea) +,S(8333f714,70e57841,312a33bb,4f1463df,d237651d,fec4e1a6,40c0ebe7,478c5a9f,d39b03d1,11657c2e,19ad78d,3e1208ef,f8505695,1bc67098,b891c42e,b427bcb7) +,S(500af03f,eba3b646,a0690f0,74cac255,804c8f8a,c2aaa1f5,f5cee4e4,41913e7,5e67542e,8a8f0411,e9985a76,97ba626d,f0607f66,9f9c11da,826b47b1,a52cfa2a) +,S(e440385,c16bc15,5023cab3,3e7a48e0,5e7e0c57,e0fe848f,26b146ab,237a3abc,dd8ac982,b627fc9d,7fd83c26,51805de3,d7369ef9,2e970664,8744badb,3db060aa) +,S(83eef59b,b0a26fa6,60c94e45,c097bcfc,8622c37,cec46eb3,f9e93aab,d0fa6438,8b51311c,ff685570,d9aa7a66,5b47a3ee,b6bc05c0,a2709421,c73ef814,bc703723) +,S(930cdc95,f723a7eb,d698c1f2,46692f39,e1add95e,f8cf84ca,171d4700,2a7d759c,ff161a2,31fc8964,5bb6dbb9,f595daf4,86cf01c1,944021ff,6ff793fc,2613bfbc) +,S(4f7cb0a2,c83f3520,86085b19,a6e5ccc1,b0beb700,35637e6e,8a79fd78,337c2616,aa32192b,82831ed,a9412f4d,6ac6d148,f68ef492,5b438cca,12a73b37,b4a8fb74) +,S(c7238fe3,17590be1,d8403ca1,3eacc6b1,71cccad7,e2e8f659,f11357ad,70590424,59079180,90bdc74d,aa06abf0,940519fd,d09f24b8,88c15cb,a632b814,fe8910fd) +,S(c6afda17,e6582427,95cd34e3,edefb600,70c73737,2d99f6c,b2b8dd3c,99874880,d805463d,15d185e8,b4461293,b6e6f6fc,a0b58a49,eefd4d0,11ef48cd,da5a16a4) +,S(4a14de26,ab18ebc3,414c6856,1a77d62a,221821f,8c216496,700bfbb8,21d95b2d,8037ef39,d1f190b1,a24078e3,e554ad1,cf86d5cd,f731478d,b34b6b5c,c9174314) +,S(cbcd6696,547fc496,8c6e7ba5,4caa4a74,43764852,43f479e5,558e2be5,77bbad00,8e0099e8,559db5d,dba0bc72,21505ef,d42c1c95,876539ab,19dedb2e,8e561482) +,S(37f168b6,4b41be85,46abd1a4,7a5ab3dd,5d690661,e41b16c3,87025106,caa4e2ae,8c617348,bce3bbf7,54a121b2,37342794,5d734e38,da08066,c4de59da,e60b5c89) +,S(3aba7081,55dbb35e,dc4a3fd1,1db54446,a7501ea0,d67b0286,8d2e6d77,99162697,829502c4,2dd1105c,cb046e0d,41cd68b4,38437394,b93f17de,5534f014,270c4602) +,S(84842bf5,fb46c697,44eca720,7b1be6b4,e5f5809e,eaeb3e9b,1058eca5,4498cafe,f4210fd5,b49f6484,2efe3089,327673d7,95642ad1,73b6840c,7323b7c4,16d61fb5) +,S(88383dee,ee0db44b,959edd96,feec2bdc,73d6ab56,9333fb3c,d4b18b01,ed8af5e3,8f0cf362,7aba3ceb,104009f0,baf84ed1,f57402e,fc330f10,6e0b45d5,4e0626ed) +,S(ad0a97ec,2197c5d7,4e8eb9bf,9798a24b,aa7c3e5f,ad6ac263,1acd5109,5178d8f9,72b352a7,445db832,2e33c93,5619e7d3,266f254,64a4c4f0,96051ebb,1e37065d) +,S(9b727e4,d107418e,1f62b499,99c1f8ec,55ef6e91,a9a10ec6,8905be97,33903d85,27d6456f,5ea52aee,a190dc81,647ce31d,15ac8c36,de65685b,4784eaad,4a32e41c) +,S(e86bbef3,8d740a44,7a2cb0d0,a89c2106,d85299f8,c38fa540,a7075efd,3a02fe03,8a9f75db,ecc532b6,ade5be9,b855a27e,185895ca,d6a6549c,f6c4c1c8,7e151b04) +,S(b72ac468,9209207,2cb735e7,d424a18c,5ef097c9,3a9b96ef,1ab7e29,d0f379de,89111544,27b03712,e2236fcb,12cbad35,98ef794f,b8141913,aeb1ad8d,ed9e6467) +,S(f8f5819b,203b2bfd,ab2dc532,53277103,2f9caf34,c53c7ec7,7253b314,2e731ff3,433fa831,3dab76fc,aad5bafb,12362126,6d8d7c09,9d513ee1,1b633c6e,e3f1e96e) +,S(8e4a8890,a15da3a6,c14d2df7,d09f6157,d5dc95f7,4f9518de,8aecbc4d,c0ac62f2,c06063ce,1d3c2a24,2494a1cd,db381513,6200827b,78ed080e,3cd14f4,5e545acc) +,S(b1f6dbe2,ad730748,f906d1d9,160996cb,f3f2450c,fa656856,e34f2481,40767081,ee6b2a03,3f3245da,76d01bc6,e61afcc6,94a9e64a,4f0256bc,62acb5a1,82e45ae2) +,S(2139dedc,a8365bce,b9c49cfe,3834e4d4,27a46750,d6b0f0a3,4e7672d3,d12509b4,b20a9101,b63be2a5,28340f58,893e10d9,d3c63fc7,77b5c6e6,a9a67193,13725870) +,S(da3aa585,85c00e41,87db0240,547ff665,376aebea,a24e5aa6,67d477f3,c4d3b914,92405390,d255ccfe,a6bc7dad,4fb1676b,c741e530,cebdaa3e,669bfabb,d1c4780a) +,S(89c47de6,84e1eb9f,a5828e65,dd17a852,7226a75c,3d113102,97f5b8f6,5b67b210,970bc229,d60b00a7,c2354a70,37ec8569,ad615faf,ac77ddab,f5847a09,c1fa57ea) +,S(48ea67ce,db716a95,6b6066f1,e5e9fc71,5994a4f6,f4e2cedc,bf0c09f,4f8c8fd1,513e45eb,159f9865,5ac821d0,e18f4e06,fa3cb8e0,9d45c3f1,8d3c3bfc,48ff3da) +,S(c5ae6651,ded2c479,a3b6c9b2,44fa35f1,2eb1eaf3,fc78b529,42ffab7c,4e33a1cf,ae6ad807,435d4a9e,e8bedcb6,3bc804e7,e67e9418,6494bc8e,384b29e2,31af8cb2) +,S(24e485b6,7c27af76,e18ed116,90c9dc90,73a0b80b,e93f5381,6669e2d,3c0175c9,fcb183d8,696805be,789d83fb,a197fd24,996d3542,b2f3eb5a,c207950d,f9c079b9) +,S(3bb47a19,b1bdc527,a8fe262a,ecee2d7f,1e772627,e5cd5c70,eb2a8c39,f1977628,2d10cdb9,91fb5042,905f822b,68846390,a922da1a,7b7b313c,47edaa6,85217fa3) +,S(7d4233a,cd50bad8,71e0587d,e10204f,6013a784,b65b6540,73307364,5f3078da,be85d3d,dca838a,1f35ca11,1333e943,fb498cdc,63258ac8,74bd6acf,2b934b77) +,S(b5d0d791,b6685aee,2f599505,d01bd3,d41d5a1c,531ac7fc,e6c33b97,cb0ed264,47fbad30,413084aa,619d7bd6,62502cfb,9648e64b,e757d6eb,24fd5e2d,6b1629) +,S(bd6178e5,b1c558ba,432a89a0,482585ca,40ea9922,7c94ce,23f5b081,d606c7f0,9cdc6bf9,d32b98cc,73bad7b8,c08914dd,b9a8c937,913eecca,fff72dae,fa1cddfd) +,S(13ca834c,a5f41671,ce7f0978,a310420d,6a82fc38,fcbd997b,88a1e79a,66fb9375,ae32a0df,7f269c8a,744e409e,16ec3d8a,eaac151a,99bdd7e5,50287005,6f48f6a) +,S(96322802,87add117,4040f802,ed5c71c8,5f924398,1ee78480,4f16e5f3,f0fecb6,2d07de71,cfda4b43,44baf838,7933a372,3d536411,7e4c0f84,2b402156,3f9b56b4) +,S(961efbd2,ae687808,bbe275a2,cba1769d,4ca537a4,1046c5ab,ff269c1f,b9477ad1,9d22a10a,294666eb,5c816bf3,c4dc2c44,d7836202,e15bed89,e3d28822,8193251d) +,S(4e7162a3,8926282,84ac4df5,88301fc8,5d91c869,2fb854a3,ffd34c47,7b216ee4,6e6dc88c,d91b9702,cb38cff,2d6a38e1,d512fb46,9d85f878,8510ed97,2704ba27) +,S(6c1f707d,51b1d3f4,ab261d52,6d0106e4,3e0a5b1c,76a59868,62e9d97c,bc6e3e38,d2563843,5dc8b102,c8f4ee13,dc345f85,289cd499,9bcfbe20,1bf3dc7e,7dae1f74) +,S(3ae98e6f,49d363fc,8416f965,4e57beeb,d37635fa,4e78d8eb,77caae69,f2201798,ffd95480,fcef0686,9ee781ef,cd2693f0,e6be2e27,f207411c,39a18465,4d2c3cae) +,S(eaf94fc3,fae4eed6,35382e91,2cf963da,2bbbda8c,3197e522,e0054cf1,4cdcd5b8,a838a439,3d4bc0ee,a57e6235,5dacfd97,7d70afc9,16e61209,10d13fad,7c1c22ec) +,S(7eb52e7f,bbf5b802,2fa6d66d,801c3632,2c195b6a,4eae4050,5295612a,a184e2c8,b4591e5c,c66521e1,b991f63f,456306ce,cb2e7568,5227788f,a2e9a75a,bd58b384) +,S(d22b8dd1,6ff24603,5fda0ebc,77129644,a8469373,99b2c7a2,60d8e985,d4f2a215,7a9a092,e8473776,6718e2b3,9068e163,e06618b1,6d6bc046,b33e2d76,8649611f) +,S(8f6eff05,f746f0e0,9b328ec6,2089e575,ca64175e,d950ae4b,c67a7ce0,83afa1b2,3681243f,ca51a6c5,7ac92100,f38df1fa,d1093fd6,ecd53231,bfc01fcd,89e38305) +,S(ac9ba060,ff520335,9a4111f5,c8c536e8,e27a79d7,33528ef7,9da7b21,36243a07,2ba3cf76,3dfc0860,ff3333bc,e660ebb9,c4e5a988,909880d4,1ceb4219,89f23f77) +,S(d6896830,62bec27c,815191b3,4addf36a,cee1cfe7,475d34d4,d83a83cc,6dce3992,9f038f46,529fb86,30b19b08,db11c630,70593570,70bc51b4,fc1ced24,f43fbd00) +,S(e815019a,f6923eb7,cf963f2d,476db569,bb04cc7d,78a0bbf5,3b422ee1,caf43b70,984c16e6,593d8642,de871694,800ca14a,a103a61,20b91c17,4e06567e,2d731c95) +,S(3670e86e,e9aaf036,40136ef7,3344152d,c792c8d5,a064c0eb,a511e14c,41d6f7b9,eac7dcca,e491cbb7,cd27a522,a7db96cc,7d300c35,7413433b,9bcd430e,152fcd33) +,S(3d03f819,4802149c,c6428aad,851bd879,189c557d,cc9ab1ff,8e2e4cdf,f0723308,1f56ada,27f2c923,27ed2fe5,88d8736a,fb68259a,1d5b1c14,7f85669a,eaf47615) +,S(bf2ac011,9e417837,d4815c9f,74351869,4395ae40,77429013,7aab32,980748c2,17a47bb9,6f7a3e7a,31b5a8ab,2adc9fe8,98fd94d2,9ea7c3b4,a5b6c5bc,9c367ac9) +,S(c72eea14,ef09c0e6,85c22840,95e73e0b,6aafa64f,9410eb0c,97f6ad4f,64dea571,9a46c93d,256f67e4,1ccb609f,4ce94390,df9c91,38a9d2db,9b993456,13346031) +,S(25463446,6da168cb,2d816bdc,3c9e3a43,7ca3463f,8c8a83f3,62704996,c1bb5b96,3d69cc73,6aca2a,cb97e1a3,cd57be14,243e458b,305df59b,3e3a67f9,fdc17b6e) +,S(b40dbb03,7062dfd7,7151013e,7cb0a921,15096a04,c39f7e2e,66188aaa,368c49d2,34923fac,7b1a4570,e824c3c5,2edd775f,ecf93573,2198f801,8f617db6,474fb519) +,S(23fba417,ff084b42,afddc4a5,c070305b,553ed7ce,1311e5d,4c1f7b2,772c9aeb,af4a342d,f9346ead,89b3caa6,6a3f187f,96f2b470,c0a26752,76e895cf,c5ca4adf) +,S(2e7ecc9e,d4f21af3,a3118799,d1ab7e3,a30d011,edc53e33,93dfdc5,6e80927b,b3959fdc,f6c4876,36813bfd,e7e83b4d,7ee0f1c3,54e0491,f3195b4b,aee2df72) +,S(1c68c34c,8aaa0f2c,7daa215a,961180af,3938599b,1324aec8,7a1b3841,710db2c3,d8d68179,71acb598,5cceec45,fc5a754e,e002d09d,4be45e8,ab6d2bdc,ad094b24) +,S(fc0ff082,ca6708eb,9b9294b6,fabef142,2cddb5a3,611dffc6,f06c05e7,f1eeddea,6f67fbb2,df22611,e2f1e796,c67d6c3d,14b17f98,2b6e39a2,7bef257a,d6955b70) +,S(fa683ae5,8dc85748,1a7ddedc,708865b9,267e9fe2,e485a243,1d005e47,64130548,4d9759ed,76326207,891a9649,3b4d2307,b9694fe2,c15e2327,a79dced,db8277e2) +,S(3cfead76,5ef36c3,fa9903bf,6d43cdd2,46ee8fb3,3fa1d13e,42fe9818,6d299009,85a18ee1,da24ebc7,3dd87aa3,ca1e7565,8f868fec,50225e2c,d5b5480e,cc0ccd49) +,S(487fdda7,364dacf6,2fcec7a3,fc2dfd27,c38079ef,d48f0220,85c62746,2c8ac658,1479200c,b06440a7,186a946f,83a137d5,7e5368b6,7ef8a66a,9540a131,e4bc9b8f) +,S(f3e413ff,81c2ee72,74c079f3,451f41c4,bbe1e51,f7c3a1ca,513392bc,9edd487e,46544553,79a33a0b,13fe5904,504cce47,55d0e2e5,6c4163a5,14d5b902,906caf54) +,S(d93692b0,53ad5194,b70b9be0,1dd80926,e2c93754,328b3eb7,bc85c45c,63e6258d,7221837b,3276bd2f,9ba0981d,883cd68d,97d2ce77,9dfa1073,d59b01e5,df311ec6) +,S(e85af4c7,42fd5424,2964eb26,b531fd77,550d3b2,eb64bf39,e97de203,ffe2d28,8368322c,e40ffca8,49ff1a53,76cacb17,98fbf4c4,38f58690,54dcb642,f805b9f1) +,S(9e4e35a2,d913a2e3,bc931c59,298ef6bb,3893b086,ee40c978,430d8436,49fce4ab,ccca94d7,d4bad95e,c15b19e7,9555579,d47cec60,9f42112d,3d992035,6d31f7be) +,S(7d72793c,dcd78afe,23e8b000,41d67983,6528b1f2,6978e262,4d022416,7ac5e741,1189804a,2558ff1f,63a7ee1f,ad5f8ab7,50a412ff,a83a9783,996e5f26,637100fa) +,S(3b8dd2bd,ca65d7de,6a7c55bb,47dd5ef1,5ce6f533,96ab335c,84c0c9a8,4e06a7da,2ac78cf3,e1baa981,b27dfc9f,e1b7cd2b,1ed4c37,f96af6e4,99bca1f7,de62aac) +,S(128aa84b,3d920356,db64bc95,b52d4c8f,3054cf5b,22c6039d,1d21ea60,b2274c44,5a748932,6a98019,824a9d7e,cbea2de0,5ccbd9f5,a2cc5dd3,ee0b3dcd,a92e8758) +,S(de8b04b2,c761b876,4c41c344,a3b57c41,fb62e6b4,ba25ab19,8fc2ded,2849e151,134ae148,d89de734,a222b656,b878fedc,886d5928,fc6bfab7,bdd0a74c,3753f1fb) +,S(f643025f,9fc3824a,6ce70677,23475aa8,8df24d59,682f5a6c,b18b1c0d,5e297017,24eb7c8b,e3de50a7,cb473bd8,81db3515,8f9484f8,8574af66,a15f920d,3986a049) +,S(ce2e5454,54324680,7035594b,1aabcf6d,5d8cad20,729a787a,7e01b61b,106fdf19,f3a2e5d6,745a16cb,3403a768,c1de8f73,cd26388c,c10f296f,f00cf9f5,209b1555) +,S(bafd293,dd071a21,25a857c2,6acc5afb,ea79093d,3c9771c3,cd3b875e,b74b3280,2d56802f,b8f26950,4adb2a51,a91ad2f0,d1ee6501,f8c9279c,6a27b524,8dddbb70) +,S(10e0909,5dc7ae30,9f1afbfe,1bcad71f,c66489ad,56256c3c,a648f554,c000f414,47a5a7cd,968dd158,e8436399,40c30179,3807713b,c09fb0d,83c6c851,c6b7029e) +,S(73b8149b,4e7bf050,b6cd9f4,93c85bf7,61062329,2dec76a3,2d7054b0,c794da63,44cb915f,b6813c71,dff3830b,ebb6888b,76312778,897903f1,d9988c37,3c362bbb) +,S(59a5dcce,9773617e,73c529da,6015ca40,bf923956,339a366b,84a69e23,d0a60fd4,4c62abdb,c4453ffa,2b806a6b,b823fbc1,59f57f23,2234c8da,a471192d,3081ee09) +,S(1ad2aae4,f571c6ff,1abfd45,35b3d085,1aeabdbd,b3a340f6,7bef0f78,f7afa954,1c394b1c,94539758,85d72498,b36a3be5,56b4f80,8ef52977,b0157885,649549b5) +,S(2403f66c,a6a7d60a,254b51e9,32cfb700,f37ad73d,193f25df,6024bd51,d0f337dc,9ad75d44,24517aff,7df86c,9bf4f315,cb40199d,4a2a5d5c,74044c4a,9c79d69f) +,S(f3139f4b,50dba596,87080a7e,b19bcc34,2b58df9,26576bc7,dfdc8e7,4914c524,fbaad228,ab34e8d4,451cf6b3,a1dbe225,bd46bfc4,8a4bcd94,10c150fc,5636c687) +,S(ec415f8a,81b1f559,714dd790,2441eb9b,c5c7bcbd,e87190c,c109ca04,a3e75149,9b90bd46,d27e0200,369fe995,3b50752f,d00b9472,fd31383a,f01bb88f,b223bc5b) +,S(5e336f17,264a53e7,d0899bf8,6f676440,f83ea0c1,5d53fae4,f19a71f6,998a3ca2,2a86fd9a,8358daac,828d42e7,9c6c0fa5,bf977cfe,56899db3,27ea32fc,cdf09f3d) +,S(98828ad8,a6ee9ca1,37f9ec2f,f0cac84f,5e664e09,68455773,3f8fbab3,ec38570d,ae7ba3cb,e617e9e1,6e67f34,f69af863,3e69c9ca,1f46b182,88126f16,9ec0e548) +,S(d6a7c2b7,169348d5,1d98f0c,27464732,6f67ad5a,4809acb1,6b783fae,36808436,698cc098,ebe430c5,4dc74fe5,dc300f64,7ac0a002,4109e002,d2f43ffe,89fb3d9e) +,S(9bf4a4ea,9fc4b731,5391b653,1d3ad3a0,f0fbaf59,b99f76aa,7807c442,f8e63bef,e69fbade,598fccf4,6f1f0931,f37f3c55,900dcc50,64e54ae4,191796fd,a4791068) +,S(38a09628,aa450076,3826f384,7e63121c,d6e9e645,f6ee0f,8cffb106,508021d0,5460c8df,56fb7d67,992928c7,fd969f95,d29de37c,14c2c9a2,2d60d661,6cb7c383) +,S(dcf8afd8,ee73bc87,c17c97c6,807fd3e6,a9c57a1b,cca058a1,ad24f2c2,6e9728b6,efee9612,3e78cfcf,1dc3132a,fa4ef492,12369710,fa2e8e99,3cc70b48,6ba78709) +,S(9c26ca1b,f52eb7b3,a0d40dc,cf546591,38945c43,41e0c611,40d0662d,1033420f,4bfbeeaa,ece9f2e,e11cc672,24749c3d,e12be6d2,d3d21d90,ed742d,31541ec) +,S(2209194a,6a3b76,1ddb2b1,3bca12f,3697248,4bec29e3,102d7734,9832ae6d,7dde1b85,cd00a08d,38035f68,fdef0576,c458476a,93eddfc7,4bd4927a,cbd64543) +,S(6ffff27c,ce5efa3,a8f8af72,edcfc736,9874abf8,5d15e1f4,cc71a186,9a7a29f0,27a0e163,bcdea297,1abe52a8,a92fe191,38b839f4,67772c83,81504328,fad94a2e) +,S(34e91b7e,e2c5f407,8a9d1ec4,7e2b2c02,1b8480b4,8c3b6e47,19cacc36,b4250382,8d60947a,42d88728,e0d67d2e,e9a0559b,55cf3887,92c733a7,3ed50b25,3706cb82) +,S(3b2de979,9106333a,98504128,e2135e5d,7deae86c,1c921c58,529aff14,12fd62ff,4ba40985,8c5b594d,f4bf5e81,bd7eccc6,3a7bbbaf,fb32926e,9a47503e,f031d86a) +,S(fbd44acd,9e593ac2,12fd1f64,c4e18d31,c3b3fffc,ae1c88c4,6aebaddd,ac608b2e,9f4feb5f,2ab68e29,ca64f458,d162dabc,7a05c552,2e38c4cb,74529e3e,41d805d6) +,S(d21c3321,bb6ba2aa,dc0cd52b,be68716,864ce1f8,44107374,c0481c0d,91729b39,2b51f18,7b95725e,f74deb00,8e9d96f4,f1a9bbb5,c9aa28fb,275f700,bd964566) +,S(ea2d29,f85855db,78808749,9ed79c2c,614406c3,adf64663,8756b60f,16166578,33971e79,39faeedf,15b14607,37fa7112,7d6f49aa,fc423f63,783e808d,1fd10369) +,S(2a1a6709,301ba6ef,c5ad4958,e29fa73a,caea18e9,e01214a9,65291977,8bec874a,56c971a8,d29d6641,9c05fcc9,9b0c0156,a1ebd007,bcab2cec,b9e920fc,85f796b9) +,S(aa870dd5,6434af8a,36d89551,a7109cac,c1d0c5d9,f5e43630,17bba88c,579cfb6e,d1fab1ea,cb5652f3,cd4d5836,82aa3cb,3b1b6854,c0ec1157,41486028,73625dd5) +,S(e979a3bc,5165f53a,60042a1b,11e8062a,e74f35f2,d70aab2d,b250a4a6,f4507507,4de86928,b9dfb2d,8509a1c4,8efdfbd7,a5432933,e3f12789,cd51ed9b,b967ff1e) +,S(620979cd,f37b1cc5,b1fe3e01,f761b8a2,ffc29bfe,8afb7cae,7ded5cd,37f97829,cc971616,6ad43824,4c6be489,7cac0b95,afe5ed6b,11be673f,d67f0d89,6d58f7d8) +,S(90a5df7d,986198fa,70152c7f,e2abc14e,2c80d5e,6b75b42b,aa042e03,f3aa00b3,77e0ad,2f3e1eed,472a543c,3852925b,327e3eb7,aae59030,2d7e12a7,862201d5) +,S(17802140,e10d8be8,ef210b69,b7fa1afc,16a85d9f,ea1150a6,c6e5e234,cf638446,af4982e7,fdcb7a8d,b6478b54,a5bd7cd7,c48d1dbd,2a3d003,7e87b6e,13c9f5f0) +,S(1f2b8d3c,fe515cd2,53f66b0d,59fc51b1,4cf75ac5,d9c7b4e8,4c75d92b,f0380b8,6902b31,19f38b04,5b979f94,cc140481,d4e6f7ad,b3efe12c,4de1bfcb,c71be72a) +,S(aee51eec,9e5dedb2,1619d114,5594ea7b,27e21a4b,37accccc,d5fe522d,2e46d29e,d40ef18,86725504,fca42c2c,b8b80dc2,c1028b71,1bf3fb18,9fdd579d,f7f0ff8a) +,S(40fe6d08,b714ee12,a4d643b4,21b331c4,fbac165b,d7cd88fc,ce35a873,875bed7f,c32f1cd6,3083a976,6b7dd8ee,7133831e,6796709a,c67953d3,4ec5d8df,922d2743) +,S(5425c555,8a6f9068,946f7075,db347e6f,cb6c723f,c5ff829f,1634fb2,13b3c820,c218eba,db4e3ad6,e41a28ba,129a0c1f,8626ae2a,16839b77,ba12257a,a6aa2318) +,S(83663c0e,f024207e,16ba74c5,ca534d37,733a7dfb,b2d531bb,21a28243,d0572a00,2699a48b,dc9af87e,bf18c9a0,929359cc,d7f2f137,b84fc070,2bc3497f,69c83d45) +,S(bf931d61,e72f217c,3b820b63,282f5d4a,c929134,efa06fff,88480f86,f6247535,82553f48,bc40dc42,cb8bb098,ecb84af6,5cb3956a,aae7bd0d,cfa9e181,de93c21a) +,S(1c6e0876,3c2242ab,17e2885a,537bef4,e8920782,9c573d00,64fb83e4,910312c1,b7c14efb,bea753a7,5d8a597c,7f1a716f,8ae4298f,379aa64e,d070ab2c,28e66185) +,S(9a2cf62f,9eb5810c,31b27614,1592f201,1eb158a,3d123610,99af0b77,7d42c0be,159ac59d,728d1c49,843a0207,e47d1cec,7b9b773a,9ddaad52,3ff27d78,d2767d7f) +,S(3596950b,393a56e3,443c3b93,b4f8288a,7faa8d74,d26cab37,dd7a5b4f,6a9e183f,f99bbbdf,c566b3e4,e65dd63a,15c727a4,403cbe85,202e45f4,ea5d3462,173babb7) +,S(6f556cb8,f5da812,24bbe628,6dc4e379,ec12b124,21cd95d8,6bb1d580,a13b5c37,eeee3133,1dc89e57,48fdf10a,1fc0693f,1c09aece,aa27dcbe,919d60f7,4748d656) +,S(b952070f,fe60bf94,cb14bf68,b37e3e54,bd9b8063,ec8cd4d5,20408756,bd318bff,57996eae,d38f066e,cb3f8113,aab5e4f7,f322859e,1fc075cd,69ad1ce4,3fc48ff9) +,S(dbecc166,8d94b2b4,8d37c133,26fffedc,3e690b76,87563677,23352ac,1eddc2a5,f124cd3c,e42f56d8,a7588145,e53931e0,ce8b79ca,ba5195f7,3dd861c9,9027823f) +,S(12dde570,aae95b1c,7cbc2da1,ed2d936,bbfa5155,f61979b3,e67057d1,5fe5e1db,328711a9,c30e4455,e2716e60,3bedf4d9,8fa25d1b,e892ac72,b5be17c2,b25ca311) +,S(64bb18aa,fbfb7def,3493c920,d2faf9c5,57856710,766b0bea,275db46f,f8271282,717c28ed,e9284844,49cd0db7,180cc5fa,20ba79d9,41c979bc,c0a8f274,3e2e2901) +,S(a798f4c9,bb3ef48f,d2ba3df5,2b040611,d0d5532b,9134aa28,e21b5585,d2379ee7,91f903cc,a4628477,b208bdba,59ecd246,bc50be70,34620a44,b55e0e9c,214e563e) +,S(7bfc5902,58f80000,82946c5f,a1a352aa,808fcc59,4bf2ed7f,bc6dad3d,8bab00ed,17b5dde0,3bf6a814,efbed180,3e5f1950,59499cc7,13e727d2,405e0748,2f912cd6) +,S(23bda819,978c9a09,864a1c53,e0fed0d6,ddc18777,b614780a,1c6fe08e,c35a820f,aab57ee2,7d226f88,6e55b8a7,c4d7a245,7badf96c,9312906a,3efe2cfd,3292af5a) +,S(8f649152,54696b2c,1804467b,e1619ba9,d37cd874,88db9418,1259d69e,135e1455,b05b39ff,241ac0c7,7e2fad78,da585b09,c98815e1,b368040,d493bbf1,3ab54ac1) +,S(177ea3c9,e592ca96,e9e0ef4c,87cb00a1,cd51ccb5,1e1d5252,963cfd08,77f30331,57185496,db5e5971,24e55b14,1042ef30,99f206c4,67415318,ccbefdb3,b18cacff) +,S(16042996,9ab25db9,e4ee4231,7497a607,360bb1fc,96e74d66,cd87cab4,44af2f36,1dfa3d9c,c3acaa95,1f7ad037,bea4c20f,c311a8d4,c2ce9cb0,bd30078e,b0ff64ce) +,S(10210453,fae1b545,de76c4a1,4b6ea5b6,172ea157,1fa60696,25753231,2630e29b,ec8aa759,5708f292,72e2ebab,eed6bdaf,955b27a1,469758b8,44c2668c,42acf576) +,S(659574c0,39345165,e35deee5,ab4c3b09,5b873ba1,fa14283d,6bced3f1,d562abc1,1a8b17c1,bbd83037,b20fc2ed,495b890e,526461c7,8f0b8d61,e94a35f1,bac9520a) +,S(a8a00f02,174b4d3b,9ca825ba,88cb1ec4,4c188343,5478a00f,38025a5d,1e2cfe58,fdac00d9,55b6872a,62a36dd1,cf666423,b4dd6b4f,4558cca6,d931a1b1,1e42561f) +,S(3ac8f67e,b4c2c3a8,2cd90fce,f612ec7e,7daa1072,6e4f8da3,57d9ab96,56e30414,15f71b5d,17dece22,a696fbf0,2e360226,bfaf685b,6575fb99,68fd52fe,7a21f9d1) +,S(87c56593,9fc7bce5,650e57d9,37e77642,a1ef510b,dadd117d,2732d316,a4f2ce19,59908fd3,e2b646ea,210606ed,c790851b,4077142c,ec7733f8,613dce61,3431570b) +,S(6531e4a7,f9cbc2f3,f0448bb7,f8250542,6cf5c7b9,d4a1ec6b,80098799,d5e43101,622a2201,f3c0f766,6e81be2f,22f1ea60,f4b45807,6800fae8,c353c283,b6ec3d7) +,S(e2a5b419,cf421b15,859aac6c,9beaefe6,29293f39,3beada53,e1ae567d,9bb7cb34,3c20b681,578aef9b,138f852e,90f49526,6d30f3b1,6ea2d3,23dee943,1af4a5af) +,S(d4e9df61,35cf81d2,21003bc6,e167b6c7,9e912c1c,2dcac775,f7d9d07d,6ffc7334,c8f54f41,513d7bde,3055c7f4,8436c812,898770da,754ed9ac,d6eaddfc,a80f6c21) +,S(b83ec734,10a1989b,988e2bfb,a46a421e,dc3ce47,d549d838,8970102f,98a6943e,4e0274ef,ea2966c5,200dbca,d8090f78,98bc66ea,44164fdb,31507ad1,e7e5db5b) +,S(ec57668e,12f0590b,e99a75c7,82c02ef9,88354f47,522c114d,bbdb9591,238d3eb,2b3c508e,81a3f696,389a5ec5,974a1bac,a572c042,69ad2709,25001215,c58ad7e) +,S(5acca76e,7578cb86,8d5ba7f0,aadfcf40,5ca4cc52,d778712b,785764a1,2afa01bc,7b0df4a4,5e048fae,65a0683b,ea0185ff,f867a578,179c153,5fa93561,54138359) +,S(bd563b91,6419f92c,43a7c2d,7042fa71,fd88e5e8,41115b5e,36a673cc,93de4e07,4ec5b773,b35a5579,b7c729fe,1cde3b32,ca34f97e,83b989b6,fe756597,3cbc840a) +,S(a070b055,839d93be,2b4ca25c,a4a6b133,5ef7d09a,268bce7a,fb1406c6,42e71025,d3fe8577,1241be24,ed209e8e,b5b28ec6,e3a0bf52,27f36036,3a7325c7,5eeb6acb) +,S(9c50323f,c758663,346c5863,84d5aef1,123b4338,eae00ec6,86aef2ed,e19b2f06,1dd9442c,cf588e6,6a3cebd7,bc68f2f,6f270d7b,bf01f088,a49a5ce6,da430229) +,S(90fe8f78,166e3f6c,2d19bd0,685fa2d0,1f6bf06c,2ea220ba,cedb0f22,ac9c558f,826d63c1,60fe3875,9c5887c9,cabe8f93,905fa1a5,e87a8272,670cfaa,ffeeba13) +,S(d2f44fa9,b704491e,69488c44,cc8ccd29,6addc630,2fc66900,1703afd9,a2a5d3b9,2de1d619,247636dd,ce1de2d9,75f14515,ec5807a8,c7c0cc4,5c7d03dc,fc19352b) +,S(17f1ce71,9e3dfefa,106e95e6,62786729,e8ec2bf6,25421ede,ca71ca14,5782b23a,62b51d27,74f514cb,5452cd29,e3907a7b,b39a9b9e,400d78bb,f6cca78f,cfc1aec5) +,S(5b1dcad4,5974f0ee,e99d7c23,83e48585,24428c94,daa956af,cd692c4d,5a63213f,6958ca48,f13e31aa,c52e531f,886da246,5ba713d4,748cf6e0,de16e0a0,366c33b4) +,S(ad284e67,a0682585,f18be40f,e966b605,8cc787be,c265606d,12f202e9,31f3067,c86ce860,ac3c3955,28321cb2,508e4da5,abb4dcfd,2844b95b,ede54ce5,b17e45b9) +,S(9ba71712,dee6f0a2,7352cfad,59f6c0ff,f133b1b1,37ecf884,a537b672,a4275c8c,b910f036,f906a419,21fd37d5,5e0273a5,332edf68,43dd8afa,43070542,b0849b40) +,S(cfc757d5,171c9d6a,ed8b9123,a2b4a405,d8e869fe,e80aebd,75255454,ee6319a9,43dc370a,c2eb8fb4,4f78940e,b41d614c,ccf2cd7c,c4f324a7,92ba37bc,7e48144e) +,S(b8288ec3,2e4a569,27df3e13,6e81498a,bc9a52af,80d74bd6,c85eead8,85e0c49d,a0d53c40,d2234ac2,df69605b,1422bd1e,4a1d77db,fb0d7269,13de63bc,a2f96078) +,S(3808cddc,497c9065,cec574e1,3b82a10,fe2323f6,65a99df,1e724221,3eeb9a79,eb046225,eb6aeac9,5659f1fe,75dd910d,2932cab6,9b4b810a,d83e7681,e0c32907) +,S(a1620bae,cc99c311,7b3889b4,7bca5d99,4ecfd67a,ad5a7461,646e55a5,19e46398,5cc4b5d2,edc5f7a8,54cc3054,1c7ec571,e06c59a,52bb5cf5,5882ec18,1b07c0fb) +,S(f1d942b2,bff74aa7,1f9cb411,91ee85d,e6955802,4a4d46eb,53ac02d1,32fefa93,19a564a2,8352bc48,a8dcd932,50274bd6,496cf488,6e2ba390,3cf91631,453f57ad) +,S(1a4e3836,a34db30,c47ed6d5,9ba6fb83,fcb7a5a,a0002ad7,1b93b154,a5fd566a,745e195f,d94900b0,aee3c5f8,7c6fc62e,fdddc18b,984900c4,20c77ba5,4141cff5) +,S(af37075f,866d7aa5,9371a08c,1e7aaa5c,d23ee51f,54428fb6,84c09b27,93b432,b32e8869,fbe53ef5,4250e803,facc93ff,a100a84,becaec5f,872d0548,da4ae9ad) +,S(88e39f4e,83a0d6ad,a1e01ac8,9021a7ea,fdd1f9de,740bc10a,4d572c46,fcee9330,a14f6881,bfaf691a,96249322,37522174,e8a17920,52da7bec,a6c77d4,5fb8a357) +,S(8e406574,a46e56a4,dd4cf780,9a7ecfad,5a1f9225,cfc2fbdc,6b7bfc84,a5ce14fd,bdc6108e,d5616bc2,3ed52c5a,1314642e,a9272707,20f00be9,62e48945,3550f167) +,S(aa31e1fc,118e00c9,8b8f561c,479c6427,8676356c,640304a8,3b687a34,8ad4a091,31c95ccc,2520c0db,7c7440ac,7e640be0,7a8ba4d9,c0020b1b,f31418fc,98d9eb17) +,S(ef278702,becf4f15,ad43fb6d,d0114077,d9f8bdc3,ff4c78d4,d0a2a15,8fe160b,377dcf3a,774d6416,58bf108a,87201b9f,f28c70fd,449a77f3,966ff441,d89246e1) +,S(d1903199,b9762761,fd02c4da,99fcc503,ac15332f,4be01b7f,a044c5c3,f848ebc7,662ca3d5,9ff2c5fe,a75ad64a,f7044a94,60abbc25,defd0a3,aa6b0e6f,2c7f4f3d) +,S(682ffe36,6838fa12,827ae055,7e38c12a,bb571227,47643f26,9cb9f1bc,922b07ab,4531b021,2e8fad86,6f6f67fb,d8eac752,1a360968,f0f9792c,a4568a55,855924e5) +,S(418fa3e0,b32be1f3,f06b96d9,728aeac3,3294ea8f,16f35139,76b30801,81d8e833,dc1608cb,68bb0480,859c9983,6baf9558,9451022e,b9966e0f,498245e0,2183ef80) +,S(e3f7dd7c,f5898b7b,174cd809,5c7c0890,4188bce4,bd6487ab,e974d979,f7faec2d,5ed5ca26,77d3bce0,15a6cb51,9922a55e,9ac1adc0,61bb0774,503e79e8,204441ea) +,S(810ecbe4,f43814f4,e658ce9,234d71b3,946556d7,2ba9c3f3,6fa04b,4dc25cf9,5fc57520,81397434,e395a752,560a8a76,252e6eea,b9ec067a,16befea4,1f1bf1ca) +,S(6dc50f0d,7e9518ab,fa16bcdb,f43ecb2f,745d5ee4,7269225e,36811819,6542b7ff,dfd5e416,2d596f5,b44602c2,20a87cfb,77473aca,6dde260f,856b3295,527bb87c) +,S(d39c9858,5ba2a859,a6fac25d,602c8e1,fb205a88,7aaf628f,5d1a210c,bc648fb5,6e92fc09,9df932e5,1bd0c6bd,5b6567f,61a1e8c3,93d69add,111e9320,661ad724) +,S(d7fd8580,59c1a86f,1b81c05b,ee63bda6,8ca93c4e,5ec99e91,88d9c7f4,40dae0d6,ceb56f19,cb3e5b39,64a4c58b,5cbeddcb,c736f0a1,8a2f8f3f,f0758f24,525a8fda) +,S(2e269d93,319a79d7,513e6f73,918638df,c4b1b7c,4c19ec83,b254d780,dc45fa87,650b6846,4e8537af,583cfc48,caaff61d,f31dc67d,5a48e0f8,5857d7c0,9bea1d70) +,S(19f396b7,7147937e,bef30096,44b292,2a6e3c6,5b5c929,22b73118,7120224,4751cc23,4d49e926,651a9a29,c2a8a55a,f7e4b25d,9cb4bd2e,83530bdf,494b131d) +,S(88f843b4,e3689ba0,264d6d4b,4d310afd,85de2ea1,6fbe7275,d33112c7,538a7c02,5dba8024,30d31ef1,412f2310,3ccc5951,66e903a,55bb2a35,8be1e715,27fe45eb) +,S(b1301f5e,1474083b,3828ba5a,837efc44,21990da5,275f6b1e,bf773b52,5ef14a1b,f9fa0af5,b508ca7f,2345d06c,5bf1e5e4,907f2b19,3681837a,802259e7,7208864) +,S(63bb3295,b57ac21c,4b96ae49,92b8f3c5,7c23743d,44ba348,195c5f58,d5360bb,f5e6a98,96683293,af6b9ded,f9f163ba,15b44017,120c61bc,c9e51758,f3ac793) +,S(dac9f722,7d0c012e,e3e1ce88,a99cddeb,9a23979,14c1cf1b,915dd41b,8ce27687,85bd90b7,7f2917c,cf1ebd47,3bfe04df,386d37de,69893cc6,9e79ae89,2255a12b) +,S(ef05aacc,a8082759,33719aa0,e0958f6e,4be6a6c2,3458f243,f84fb2df,9aa422f0,d6006b80,bf611afd,3f1ed523,988b3e8f,d44be73d,565ef30d,911e4226,ae546f23) +,S(dedf3d9c,807065ad,8c1e3714,f682ff86,4f6ae08d,6bc15773,53f27677,ff86783e,7bf6f3f,1f3e5ca6,6902639c,a0b071d9,50dc2331,52f1b47b,5c68923,9a1cccc6) +,S(3db2b461,d18b367f,cbb4aae0,7a73ce9,6c1b4cbe,140099f4,d3839764,7414b5da,515ead0b,a8ba7b25,9f04484a,4c55b532,5686b882,77562b99,21827706,a036a142) +,S(5516a03,3da8cc3e,28170010,5e8d57f3,daf5bb84,596c040a,3d2ae05b,41cecd4f,6bf44084,f0ad14a1,f129a267,e13b0717,6d2fd274,2d4be75a,2192e54,7ceeebf1) +,S(7bd86d5e,6fa18e26,cb0b6e2d,faf2a4d6,a784e831,2e7168bb,8e660e3d,92514c3c,9b634094,dcf4ade0,eb49eabb,a26334f1,7770bb94,b776de46,64d847fb,f1574afc) +,S(a24a8b40,d63c242c,3dcd2513,fbee3c04,cc15117e,aae40daf,b39c3373,e6a83bfe,49163714,afef59b3,b503eb73,ee091349,e599c563,bac4aa37,13d7a6d,6f5271a3) +,S(acbbcaec,8b01374b,454208a5,19051ebd,e5128307,785f7b25,706642f7,775a932b,102283d8,1bd1e9e7,e5641b8d,a701f51c,86047d76,51becfba,89478d8a,a6226572) +,S(efd5654,8f37a094,19f9fc11,6d818523,c4d76725,860d49e4,a1cd8434,a0cfda99,d521204b,da2b9db5,dfa47c9c,6ae4616a,52b3caad,5440e4f7,f1fc41ba,766bc180) +,S(15600bf3,ffca622,a163244f,47789725,b4c112b6,e3d7652f,fe829a6e,386041c3,b1a1ddb3,e2b0e170,8cc9e6db,13c7b111,93673cc8,397d9b59,5b4e8dea,a39cc5f7) +,S(8d14cebc,62f7cd8d,fc60c2de,d144c76f,55d9d6c1,be5380ca,1e1ecefc,5a85cc53,244bdd67,5030a8ec,af876f5,99a34f98,ef7388cf,e6705734,540f57f4,15641220) +,S(e3cb7328,29c6d09f,6ee940f6,5f30c79,7dbbc26b,b8b8c860,f6e07088,a485ebaa,e50a5c44,6768827d,ddd57e18,68064e61,51c8951e,e4cd920b,b664ca06,67096db0) +,S(9a18212d,45364ebd,3ecf4d76,3efcc66a,ebd17b7a,f8bb7f65,8679664e,16888e47,85297209,abebf492,ebeca275,bdf3bd2f,987d1e29,6bcee299,9d6e59e9,2b890143) +,S(43366191,859bb3bd,5b44f1a,d9076ec9,5439c082,c99f70d7,4363117,8020521b,9dd6d890,16666a3e,6bd8c0dc,76cc9792,fe5d76b8,c49cf9e3,75e031c8,bfae2556) +,S(1b77e51c,b11e514,29955ae2,37659c5b,a8050ddb,685e5b74,fbe38506,33bf9358,f198ea65,1ed4a743,a14fb905,fd0bfefd,843bb00d,675781de,5fb1552f,c7f382cd) +,S(7cc6fcc5,558cc6b7,156a62d2,e823631,e0b95e8c,57fb79d4,b4aa3ff4,9cb718cb,526becaa,c0c84e61,b3fc85f,60d028d2,eb90567e,319bd6f4,12b1a36b,9c3d30ac) +,S(18c1e51e,10a7dc5f,7783d511,6f2c0457,664ca2eb,6541ff29,591ee59b,f9f958cf,7f72840e,ccf4d03f,29ce01a6,725f6b97,d701a935,bce8a2b3,c1e44904,cf98a300) +,S(3b9335fb,b191bc9d,17efec98,77960307,2648edb7,2c427521,34df37b6,f1620c44,ca526125,8239c80a,1ae893b,268d28c2,b02d56f2,d03a8a7b,aca25def,34d6d694) +,S(f39660c7,ba9bf800,381b8ddb,d783dc6,acf8c183,95f9144f,688db8c9,9d7874f4,c5037625,2abd41f9,7574a607,52be4c31,e5ef2874,5e9d80a8,da2ea676,4bce5cc1) +,S(d1d2872e,ee06a4b5,d3b735b1,9db1d88e,cbbf9ba6,89c1e411,980b2cde,e70c86d6,dc5cd630,859fb9da,70f25023,5b7bf2ec,938743a,a9f04fd0,69d1d746,e3ebbfef) +,S(aa4f71b4,720f6470,8b6261a1,ee97bc7c,ee85b274,caf71a6a,1f7f000a,b06a1948,958fa65f,acdc42f6,c1e98f7d,f67ccc39,14dc5e8,d20bb872,32d7c898,e451c017) +,S(85904824,63e69633,42cd1e89,1502c309,d74e1722,fad8e766,d7e8f566,49bb732e,585601b5,5bfef406,ec5f71bb,6bae29c3,c5e77247,befbb549,5ced52a6,da64a2ff) +,S(dc899ab4,89a12ac4,4152ef63,48553ed8,29855449,c204327b,bcce6418,75df4d99,6791a965,65fb749c,44f133d4,b3c9c8d,77488831,c8a99ba9,7b66c9b,43deddb2) +,S(2fd60f25,3e0b4f1f,2589a096,f9a0ea3a,405906c2,690fce35,ac7df791,f106020d,872d52b0,1cbfc3b0,ff699950,5be33b51,64a7054,bb00e22a,9a87d692,dccbe782) +,S(a74830c1,7f816549,cd617b94,c0360b8c,9206b382,6782d351,650785a7,fb71212c,fa928b97,75b28be7,4e340cac,eabf866c,fe7e7299,7c276680,2d211b1b,389823b6) +,S(fd450d48,c59fc4db,e3366b43,caf00c2,bd10045,842311ab,20f8e24c,6a9a10b7,512d1998,db747e39,34451fb7,9aaed7af,48801051,dc8ef756,4580db9f,bad910d) +,S(c0816923,9f2bbbc7,34d52def,79f9f4bd,cbd8c435,d90561ba,fb23f12,f1fcb93,fa00c81a,8c5cc2d3,5f78f0d2,475851f1,73f70cbd,cf2c950,8ebad1ee,b35a0852) +,S(247c4075,9a0e7098,25a5d82,4fad3419,55103052,bcdc7ab,fe4e559c,84a04a66,8da3cae,878260ba,1b95a5db,900f20c,12597187,4191cf21,939ab6c7,fe378067) +,S(fbe3b30f,16ad6608,32f9ab15,2f44076,2f7a09a0,b07b12b6,4375db15,37fa4e9c,98cf3e68,2a914c3a,ee54971a,793a9309,8c63aab3,e2db5389,3f05450d,61b9080f) +,S(79f71ab6,fce86bad,be02055c,520e6e0d,88e98def,d37f2d2e,488bf455,3ec954c1,b5de6a0b,c1745341,3023a650,45262a31,e9264089,8a655b0a,4b3042d3,a9114330) +,S(d190f258,e2e3bb8e,6812da59,606f2f4a,2e3fd1ec,34e2c80a,9d280f5e,e1e9c4cd,98997b49,afec7d7a,26a26f50,9d4948c9,b5ebf9b4,3eef6183,3a2b7a8,6183c267) +,S(24f355ca,c0e00545,f47e199c,3818e76f,534eca88,776ff6e2,54244686,24f0b636,37710da6,5c3afbb4,308d5906,7ad044c1,4df30f03,427ac83c,23b829f5,37d25b46) +,S(bd221461,ae73e639,6b23d269,ed6907ba,330544d0,80342de3,a769d3cc,668cf536,a5f25513,3967fa67,b22dbe31,917d9d1b,ae11a1d9,dc7ab731,26e8f0e2,fbc8deda) +,S(cf0371e7,22194be7,ac5d19c1,1b447978,b38f8a1b,dc1dc3e2,471d4a8f,75d0f6cc,4bb04426,94fe9d55,cc49dd4e,e168b604,564b95f5,99566f3b,9fe2fbdf,16084f1e) +,S(ce21a5e0,287752fd,ae9e04ef,363540ed,f6736c34,266a2d77,b5d0bb5a,868fc32a,fc30fc93,bb5a2731,8b81b942,4fe330d1,878e710e,b9a44fa7,bf4cbfa7,10c7d0dd) +,S(7c95d800,da4720a4,102de774,d585f230,2b849e57,1f42982f,a785bd15,334b4b12,244deb56,fa5b4367,2c39693a,f09083f9,2b153a9d,4829ab3f,ff604fed,a266b30b) +,S(40bce9b4,f90489f4,d392fb93,3f98f71,e9281976,164b25b1,982cfcfe,338d93e2,5a9ebed7,25bf11e8,7bbec766,c52309d5,e2036454,447b8ee6,6dc79dac,7a2a9b4) +,S(f15a2ed8,2c00ed9b,9e7a9338,2d08c46b,33ba7bb5,dc15f5df,4cc29fdb,86f11c4,d02ce92c,e556287a,3acd4115,a190767d,2979dd7c,7a32dfde,cb6d806f,6e7d0205) +,S(4230d263,d5a4a915,cfd863c0,e38514b0,4929d352,d8a90c00,c0ab9ee0,56215932,4b134eb0,51699656,dedc7704,3d5586c1,62134b00,e21ab1b4,517bdc54,5f05fd69) +,S(6cd6bfa9,63327c26,fd2c7aa4,fc159956,1a90096c,dc88f414,d5cc9c64,df6a9e84,6741fda,1f774c52,20b04db1,9ba7402d,9b77eaf5,b8e9e2bd,a000d2df,2022565c) +,S(118face3,ab188a36,581cd1ce,1d434fdb,f1d06f50,1e9a64be,bfed2ea4,ba3f477b,a263037e,c8d5a9eb,be1a8b97,bbfa5624,ce00e852,44828af9,8cfc38ee,1da9052d) +,S(6be81e79,5fd1229a,fb24a395,fccfbb6a,ae4fda11,28f93faa,f74bfb76,c39794c7,edd0f9ae,bbbaaf0e,bd1c01f,af128730,5d5fc5c7,732885eb,327eb21f,62683869) +,S(b9a0023b,6fcbb06a,48f97684,509b8b9b,937f990e,4c3f1a61,27a8a18e,e4c96c3c,e1b25ce1,3e8bda89,ea631d71,4c07adfd,c31fc6b7,304b5e7f,1cc7221a,6597df11) +,S(4e384b06,ee4007e8,e70f22a6,1af73d89,4528722b,cf58bfa1,16eaa29f,e1f2334,2fa6ecd4,8faeedb6,240db0d1,14c7eb3e,63540e31,788f5f55,98c52fd2,538ef0d) +,S(14c8267b,6462dbfb,6ad45cff,58d9b22e,9fb0de4e,3d026999,9357acc4,d254ea52,86da149d,e14de86a,20becddd,e33e99cd,158a50aa,2da085c3,cf675eac,224b292d) +,S(42d0c7fc,21129bdc,97318985,73b6d111,568005b5,cbabcf55,c1828340,4f5de376,8f83e957,92880a3f,dac6738,e65ea463,1399daa4,defbd1e9,41a5586d,a42f652) +,S(bfb03349,2fc28eb,82bdf9b4,417f02ee,f93588a5,b138c520,77250499,23e9f135,c65872e6,9438a5e7,a20c3492,7a3de7d,85c690c8,b20af801,915585d1,98184882) +,S(1a111410,d04e1278,3cded32,b3602007,7dedfa32,6493a780,999c68a1,dee18047,874723b4,c6b63cbd,d957098f,d0124779,3e711a56,fcb8499a,a046f5d6,36d5be75) +,S(a47aa995,3a999aed,9c1d1f77,da8b736e,6d045d3f,9b32ecf,a6bd4225,fa66cf6e,c4ae1566,4da8e033,f0e3fbbe,472e16e0,70a4b40d,f210f7,3d0a6fe9,3dea782d) +,S(52ccf2b4,5cd2555d,5a0a5765,92b5ca7f,5ffa329b,6bb12979,8f2c10d4,bdf34119,92abe502,d23e9f61,f420e4a5,44e42864,2462dd0d,7d7f386f,ff7cf2b0,b3a5043f) +,S(5d2af6df,77107953,e6221a4a,ccecadf0,a2a8d676,5e720d2e,38c386a3,e6b48e4,5a44be69,80ca8082,5d435aec,34db8be4,6dbd05e9,9b8fa176,45888bd4,2260cfaf) +,S(e0f9b457,e184de7e,7484ad3a,dff4adbc,4dfe508c,14341dd9,d2c4f584,807e3fba,d0712e1,3bc4ad8c,78261681,3d00a237,36383731,7de79d0b,1f52264b,6ea70526) +,S(6797c2e1,d1c2643e,a831372a,abf36ab5,fcf88804,9a01f052,a7930792,acd2a7a4,ab005587,69f8d361,2217de,8d4bf205,925bde,7817e97f,d155fa94,8f084167) +,S(f302e07a,8953b3c1,f0b3796b,55bdf133,84809aa7,3dfe4fde,a0d56ae7,a04c2f26,339d529a,a6c0c8cf,f46682b9,c36390d8,28b2861d,6f4906dd,a4659028,c74d780a) +,S(aa4c04f,b8261965,9254f9b3,2d9e25cc,ec651f79,b710cc3d,bdf4eb3c,dfc207d8,520cbe2a,c8c0382a,23d2cea6,6a18f28,bb87e773,6bf60dc1,cca64a58,9fda48db) +,S(cc4bbc6e,7f4b02b5,ebe6d484,6352257,4651fed1,a079767b,fa53d1e0,dc38b5b9,4be5e0de,c97683d4,939077d1,edffcf6,dee4a88f,f7d42894,c3d50302,70c9554d) +,S(6a4bada6,cf1e123c,e80fcf83,2d6934f5,486901f1,6d3ad0af,cc87a4cf,205e6e79,b79145f8,24d693b3,832c6676,e35a73b8,d8acddf1,681720f6,c8d5ac7,f81752fb) +,S(d7ec4d61,1d440625,367b2c5f,a6904b8d,cf6f0d81,39cc3bc,16299e1b,50c9024c,18c402c6,3e818647,7f15bdb6,d514373c,89d1f7ff,bdab83f3,5267eb0c,daa81d89) +,S(4e21e4fa,4b570b40,77ff6876,a1d7e4ed,1db77d0f,56d35445,178ff508,5b197169,dab19080,ef84f0c8,4919d869,36de1aa3,ca85a1c0,aabe902f,b46b31b0,3b350580) +,S(32aa04b7,53752059,7b4ef603,62aa208a,effa6891,240a587c,e1cae58a,28a6075f,ca649475,a58a3ebd,c3802c13,f006335a,7d203ddc,88bbd1fa,f0787839,b9452f21) +,S(306bcc2b,94214994,e86c7fed,4f510ad7,9eb1af11,b824d897,a1cc7564,9eaafe0a,820c2986,abf17343,35089773,5b4da35c,56265a25,4a768346,5dc084aa,ecae6dcf) +,S(37d23716,1044ed4,b395b044,5d70eaaf,864530a7,fd8490c1,fe2d1ea5,61f4bc19,a6a9da7,70558993,ce38d5d4,c69dd25d,134f37f,c28dddef,2e7edc0,c1343b83) +,S(1f324230,886ef594,aecbe39,2d7a4434,fbb9fefa,fe22573e,9302d3c,dc81490f,39e53099,f25e977e,da860f77,6d09338b,c0e75446,42557c8c,b05761a7,c18537fa) +,S(256d4808,d6dd018d,392a6716,2af909f0,51bfeea0,9ce22a76,6266d1e7,61df967,d5643938,c7d9163b,38fc8072,609bcbf3,e063d78e,10cb8cee,32c00abc,6341df09) +,S(58a91493,ff7aa600,1f457506,624ce8ee,b1c142ca,d49f67f1,be099c58,3a7934f4,bde8d64a,79d5722d,6a96d240,897a7f48,8e20f19f,259fc6a1,e4483448,e0290122) +,S(b4a80e5d,eec9391,8f146b4b,e0d91630,606a5c79,1c4b7b87,d4363de6,e2691f2e,a6ff5b82,ca6fa424,efc00b20,7ea90991,fcd5af15,d23140ab,96da6cc8,bd532297) +,S(41bca570,b4981232,f21ba765,4f23d5ac,27f3bab6,9f1107fa,e3dc5102,6f8dafad,5a14cd59,9b0bb884,10ed1475,8445c49,3af3b7c9,2cc6435c,5560c4d7,832709db) +,S(bcff28e0,bb6c242,a7805142,122848ec,6951940,bb4a2e3,5ae05137,d73e8264,43661933,9ff9f2e8,278ef17,329682be,aa801596,e4a12b0e,615fbe7c,4b24e1aa) +,S(8aaa2f44,fbf66c2b,809180,bdbb4e2b,e25ff178,232fcaa5,a2c2563,8c1ea21c,69dc0de1,686bffad,1ceee711,95831b90,c57900a9,baf57ac,2f34a917,6d33e21f) +,S(930a3df,f84583b0,ced82f81,96c39c16,b9318f2b,44efde12,2be6c10c,70b33dc9,ae802936,2b10029a,a81cfc47,1251ffc3,6b586de,da9c1754,4a96d3ec,31cd6d1) +,S(907cf1c1,92b98461,8021a33d,1c9d22e3,22dc83ab,d5768a39,c04444bf,d4e76df2,527eb629,ca0a2e2,7da96361,ee727a34,97edb8c8,68694871,6a7dcca5,13b6f901) +,S(f9d32e84,76c666f6,29e86e0d,3804eee8,abe1ab26,ae2eb396,b584e4eb,e9583b88,d92f265e,9e6c5f4b,bc05a432,6fafeace,1516f823,3e5dc280,b239fa6c,bfdf7fb3) +,S(94772c31,70e50bbd,9952bc69,44e0007f,3d928cb2,c86465b2,ef040fa1,b4f90d9e,29021913,9326e358,2cfa8ee2,428c4307,86cb2de9,6ea2c735,eb71f759,bab14637) +,S(2b49cd38,8cec8c30,e984d40b,f1409c6f,df7ff24d,36cb699b,5f3c24c0,fcc872fb,9e65a427,ce5dcc20,db83a96b,720f29fd,df643b2b,a192736d,c621d92a,6583aa8) +,S(454f174d,8c344479,9bb58158,423d8413,ce87def9,2fd25a,5164807c,982d84e9,bf324810,d9894da6,1eb1e3cc,5a30639d,6500a453,c14e8a40,78353d42,7ac67ee1) +,S(df4461b1,dc1eaae8,5b4b7fe1,e87753e5,546f48f,e39da02f,f1012b24,58a79a17,ac4fd2bc,af8e0b51,48cc5a5d,46373209,8993b377,becd718,732fa339,95412fda) +,S(32973a0,d1be4c6d,1342b2a1,44ffb36b,81fd9b38,c0b7411a,65b8ccab,cda9161e,558b278b,f507b498,fdbbf73b,524c4652,53a0082b,d53a87f0,75d5a49a,bb601b69) +,S(cb63a9f2,d1a11b08,479275f,e1f0bc64,37126875,5bcd8a21,3481be2c,818c69d6,4949d3dd,a31db2b7,b2d42f2b,4709a870,5094d470,1e742f07,b6f86670,e43bfaa6) +,S(543ae5d,a0c271b8,41542353,277e1651,b7b0f587,a5b18ed2,856c2e07,41c28914,22c999cf,aba6f95b,21f87ab8,2f2edb2a,3dbb43a6,ff413506,83835ae8,bbcd0a37) +,S(7ffa63ef,3df62097,a3b61289,4eaf5bf7,4fb39ad2,9ec63f02,2c6f310e,77268c7e,9d26cd72,8fcbfe54,6eda19db,5ac61978,1b456699,59a21628,2500e5f5,389679ca) +,S(72cc6606,b02943a,5bd9a476,6b24caf4,e0e2f83,ae3bf671,5f05b39e,3436122b,f35ff21a,39503637,d05b744a,77797565,1e290541,326d920b,d5bcbb6f,74b56c3a) +,S(f5f21182,de67c3eb,396055f6,a8f64f5e,54043376,cdce9f3,3cffa601,4a348a4c,1fe09f94,8ad7f78,6c184675,3105cbd2,e0f8be91,f9160e81,9201fed3,3208b3c7) +,S(1cfa62a3,70171431,52fe149f,db07b00f,bd8d7928,e5eb145f,b4ff7343,fc19437a,1efe47f,e41677bd,337451b3,92eddb1c,ecfc19d0,5ef04727,12927d4c,77b2a742) +,S(b6609139,733864d3,abbdb6bf,4b827b2,3861594f,ce9e996,4637ef14,f0fb6849,2e807df,ae409cef,b7be1ffe,63351d8d,8de5fbeb,f3be5069,31befc97,d479c006) +,S(13da7c85,bffeaa0f,e295ce6,38de0b05,1b4aaf9b,d888f5c5,5f74fd60,abf2e016,c0477fad,fba6531e,f6369aaa,be663871,3bd6954a,d1e5df1,269c7208,31cd5bc3) +,S(2abda634,547a86aa,1188b2f6,ffaffb36,dd126d94,18406bed,8b81e29f,596526a0,7db36141,2e96e02c,34c0e39e,1201617f,2a7f2100,d5c3cf64,6dcbe563,e2b25524) +,S(4e161f2e,22785c68,3ac494d4,1e3cc2d5,e6b87be8,bd65e85,8aa255dc,8ea8fba0,c81a4e95,a2cfa101,fcb62112,b60c574c,623b5df6,5a1fcf51,e6bf2936,45d5f17b) +,S(586be2b5,740b0ed6,6f5c5f6f,217766e,ad5543eb,8e983ffb,928fc40,9e76397a,f11acf99,8bc2a25,48799529,9c7ea84d,98c6a525,6cbca56c,3ad534f9,26c6b08e) +,S(a76c4f91,1d0dcd58,9417fca9,8124f62e,789e0b05,91a9ce94,13e0b7d,e7d5986f,6a49fc1e,2b32aeaf,6f291184,3995602f,903c8d76,858fc532,9b3a1940,2c2c9b7c) +,S(15f11b1e,804a6d54,a496ee4f,f3030167,eb510e9c,c1754bd1,d46beace,1211a68c,f8968e8d,21bca271,75a79de5,31ad810,ca6c6da7,72ff96f9,937ef824,8f4fec45) +,S(f0169f41,685292bb,4ac93afd,58b2c239,3985ecd5,16acc8ed,ce46f325,74b23e58,6fbd711e,fd488c8b,43151ecf,e3a42ad6,25697053,1df18afb,68f8ad71,ee9aa05e) +,S(2f241e5e,2596d32b,6cdedc4e,b6de5f53,374e358d,8db78d08,9e772b37,6250f359,fe79f0a0,cdbef5a2,7287c86f,afbe917e,4c26c4ca,512f57e4,ab066d3a,3f7e71e) +,S(a14743eb,92bdf49f,5f404a54,ab193100,26f3fbd6,fc5a06e3,e8c6b33d,1f7a5559,3e7e5f24,b1d0425c,ee5c56ef,1e38098c,6d67fd12,f57eb2fb,1ee76c57,41d57c54) +,S(2d097299,db14ce88,8da72472,da686f67,b8ecc812,5618cae9,2acf6457,a011d2a9,e9cf7195,32f71130,5bae1fd4,ce3a8fb3,c8d71088,df35b49d,ad9c16d8,8734a187) +,S(aa7257f0,d7e51fbd,95598b7a,a994fac1,41aa76d6,318cbda0,20d30471,73317f2b,15e00f94,f684c30b,5cd4a978,c6245e6,8d30d959,a30fb39,834e97d8,c18a1b27) +,S(ae524618,e2877095,d52ffc94,67a081e8,b27b4b16,566e2b37,c8d11b1f,1f7416a0,d0275a1f,6d49a7c9,44a07a6b,ee5d5095,7b22b698,2607f822,8ad15253,a546ccb0) +,S(e7a85ef,ff8b0443,eace4cd8,81d768ba,ef4d93b9,79b17eae,fd237e8f,c9ff660f,4b53f073,8f07b360,7d66f720,b1222df3,eee2dd,ca20f40c,630a7911,a0fe2aa6) +,S(daa96eca,b8412eba,75f58a80,84a302a6,37dd7d77,bc9dc502,a2d083f8,35bf242e,ac3dfd97,a01557af,cd1f199c,afea0cce,52c8e3d4,975cb331,1c817c9,fab0815e) +,S(34dec21a,965b7027,44fa7881,4ff6f782,790d551b,7be35c,18cd46b2,e189baca,ee825c5c,5cc289b9,d7f01b43,4de4f0d,d250f9cf,c22c8d20,a1e54175,9bd23694) +,S(dc2178c1,2f015bee,829f0567,566d15e4,d607c8f3,b2992801,4b6a5607,1e61247d,fc86780e,31cf57ff,5da387d1,c3c25a19,36a263d,f6571de1,d098153a,97b41db8) +,S(6faee1e9,354bebe0,1fb65158,20b7e992,9517cb40,23d49d19,2a002ba4,e4782db4,a4915992,ceb8813b,e2778fb0,47766b6d,3958cf72,f18e9172,3f74cef0,1d2276a) +,S(a2bcc012,4112818e,571c8dae,3cb724dd,e45faa06,d04d7128,e9a71dce,22f300ca,1f594d9c,64ba43bc,11764c61,f8fef5c2,e31fda39,3447e7d2,10d004bb,c13870e3) +,S(b8cba39a,c51d86e7,d83a50af,f5370240,cd7b20f3,81aeb799,f951883f,458ead76,3a8bfe74,2b3a05be,27ef835,39988cc4,616365fa,e3738d35,29f9c0d1,c15eed4d) +,S(56e532dd,295792a6,ede9da94,c43e0b2a,25b72725,333f8205,7a352ac9,7a1991d3,a617e234,18bfdccc,8facb454,649a4914,2f0abd64,f30e06dc,838fd80d,7a141fc3) +,S(4803406c,e4049575,19f5306d,6daa003d,2aeddc1f,c1d4db45,15a8d35c,aa39a6d6,7add51c,12412f4,49d7b0e4,b7df38a4,83151126,49660956,da6273ef,8b53fd5e) +,S(bd61ad65,2e44effe,ca39620,2f84e4d5,d81cc579,2a2390f6,52409852,cd79c459,f3d7071b,8bb18928,1d827f71,ab7b1ad,5289033,ab28d20d,643af02f,a2b4ce5c) +,S(1b543175,e5b6f271,58048588,f81a791b,3ab216a3,578e2f79,354da6c9,5e4ea9bf,67a2e60b,321456b8,5b5499ca,e33cd6a6,d5445f91,eadb5a5a,f0e2164f,324417d7) +,S(2035953d,3319ffa5,9f75d86a,8d1b52c0,e8118ec4,d830d15e,d9616215,cb82d080,302cc0d8,5bc1e667,b160bc8a,64cc3bb8,763066a5,6652a0bc,c12691be,c41d7aa4) +,S(bf2a9739,f65bebbc,90413f9f,d311e095,e7628dcd,d76d25a9,8a4681ef,f4f84035,83932d07,cc950bcf,380cea81,28e04322,26b9a4bf,8536122b,fd055517,e7d3b2b7) +,S(a915504a,bb62b4a8,1288c44,8605e8ab,bafb4f0a,ffbcef23,c9c2a26f,f2cb8557,2fec1059,abe1bf4a,834c50c1,edf0e5a6,2ef21f7f,9da2fda,20989bae,18acd442) +,S(318939cc,fb2eb0f8,30d30079,7e209f00,6e28b899,8aecb548,b3b97900,9ea6aab7,5308df9d,10c7d151,cbcbe417,91b627ad,b7204db4,dbd2e01a,c5698e61,bdbda375) +,S(ff9e4851,d3f0c9cd,818facdf,4781cecb,7f622039,c23e236a,7e4b7368,64af1a8b,fd69f241,bac1c6b9,a52d6dd0,6e7bcb6,4a4a79a4,9c3881be,6ef8c83d,3f462c5e) +,S(497113be,a88d4888,2c98ac14,ba0bd0aa,d3c75c8a,58d374cc,86a7fd0a,b6259cc5,9029d9bb,96076d69,a264d2bb,6fea2f15,423ff1f6,ff47c02d,4699943c,9cbfbc4e) +,S(2b2cdb82,6653f563,dfc4c373,96d738e8,3d1dcc5a,ec5f4886,2d5ca84c,2ba69103,d1985cb3,f42e4ae1,7da33b7f,f8563236,6e2f5c89,b849ac73,afc3a7a8,1d049d85) +,S(c55dcffe,fe63e948,af77c8c8,32cb6c0a,c09ced5,5c338bef,fc27fd21,dc63b6c8,edef9fcd,b00fb62f,cc97c03f,26253069,de6f8d00,c13a5666,f574feb7,fabcab6a) +,S(52a0dbfd,371bcfb0,e2c69160,c9cca2b7,8dcf679f,774c9d99,706d306a,30eeb3c8,fe01f320,781275bc,a6c031e6,d71df467,56473d8a,780fc54a,6f8eb1ae,5640bf65) +,S(75c4ace7,6bb32bac,13141f21,615e11e,7608fda9,cba4723,9eb6bb8f,349a9e86,7fde50af,19506ba4,65d49b93,c8884478,dc34ec91,9bd5e22,be6bf71e,a870a70d) +,S(69cd7caa,b220abe7,8f36f7a4,633802b4,85969ac0,e9c4a244,7b0ad782,29daa879,4140a70b,8d9025d1,7fb3402d,2ac8afda,e9e0269,b29d488c,2266c1bd,58accc9c) +,S(b6cf3a30,d2a5ec8f,4480df82,ec6104ff,37355ca6,f16418ab,cad3a0c7,bd8da064,f12006b7,5d406558,51fde0eb,c68113b8,50441595,dfe3dddf,86c17a58,94a6d923) +,S(65c4a081,656d9b7,445131e8,6081b306,3a6e0c02,5339d3d7,cf48e9ec,4e8f59f1,51f4ebb9,4b63b8bd,2cdd6d88,c84c8608,bb380e38,c748ddb3,3dabff1c,f50197fa) +,S(c243570d,e74a1fbd,938bea43,bb17a929,47a228b1,ae47a6cd,15c37524,b034fa66,ca57366f,e3886510,903970ca,e1a5dc5e,bb857007,cd4cc56a,37fc7fca,8aa4cd40) +,S(9290d033,1c95584d,e2bace9b,788c50b2,f7fda83d,d45a4a37,5705400,45339d7,dcb3032f,c4a41076,8b8e442e,46cfb16,b63f4fe9,f94a7d5c,f932d0d4,95e699e6) +,S(295df203,cfa65b66,6afc86cf,b879d650,7075f75b,d1eb753c,709760f6,6ae9df94,2cf505f8,8220196f,9e5478e3,6bd82501,671c6b91,a404fc0f,b1fe00cf,12085934) +,S(1631e6c1,3f89dbca,36cc78db,1056a461,6ce2dcca,62f90b0c,5fcbf232,77d41116,acbcbff3,2c164cd3,b57d3b89,a326b5d1,46b5769f,a5b35df1,efabd2f4,407759d0) +,S(db0b2c5b,eec9f06a,9bb43e4c,de18d978,59a95cfb,9b319d2,5ba619ee,abc49e31,d647147,d8330315,1446a405,85bd857f,ebaef109,22ddd0e,3ac62231,8ee91abc) +,S(2581d046,9e8bdc16,e535c787,1a37c48f,929aad34,b694ac2e,5d264962,11e744f,7bf3c684,3d953b2,dbead1f4,8614646c,d18b0f2a,cdf6fbfd,3ca68498,ab25bc60) +,S(9db20da4,d576f564,372aeed6,eae78eed,f512d13b,13d4e9e2,eb3133c6,13c4b80,40f8b2b6,fa113b6,ed7dce55,d62587d8,a86a43b2,9e0b4876,c5607b89,9144d255) +,S(849b193c,e490990b,e2aa48a1,c31694c5,fa041f96,7086a83,cd1a06b6,ccb5e3c3,353b49a,6ac0c705,5a3d5e31,fa428e2,391165ce,402291b2,5e1b0496,bda41e1e) +,S(ae83dff6,5a1dcb6f,e2f56437,c83162a4,a388a16a,bd387d62,f5c5ed,ea08fe7e,e9c57ed6,5404a00b,a2f87613,4d484842,4a32246b,def6c31b,533caafe,7029eabb) +,S(24724eab,46175b4,efe51d4a,5993da48,1a62c6e5,f05d16a5,17e4f58c,fdb103,94465b42,e4e378c2,1ef0d1d1,8b25d140,fb17f51a,fa4d37e3,450c73c4,72468b04) +,S(c2e2f802,4ac48fcf,41a3790e,e9916018,5a301859,3cc3fa77,c7840552,6700659e,b1fe219,1563f9bd,20c4dd45,615d8cc,400911d,20cfb7a7,672b06,20d32a2a) +,S(8b889bc3,e2d1405b,47a1a05f,fd0c17ef,9b4dd75,4d30640b,e3c4de7d,f70791b5,e2d459ca,285629d,956d5046,54c5e907,6ed92fa6,c95643c0,7d746b78,e03a044a) +,S(336c0585,8f5ee169,fc09fc73,a181ccd1,3bd62dd7,c454837e,1a5d7676,abb2faad,5c29a656,e8f2804,6e855c6c,eb0d908e,38f1b62a,69c67948,9d6a03ce,64a90c2e) +,S(c9a6df46,411961d,a703ab23,605fce16,fe021576,92a9b80e,65b9e4ab,efc9ee93,8b63a4ab,18a4b190,89dbc53c,ef0b0dc9,20c0ec7e,1fcf075,195bccca,58d52f6d) +,S(6cea35c8,b3a45063,75456a6,2c95e8b3,7d84a6d3,e909c5a9,cc4800eb,5bc28367,68198888,eacc9380,4a3233ba,1801d586,e5bcb2b2,78efc7da,6764bd5d,edf0ee90) +,S(f13d4ee6,ea31999d,d8d1220a,13ce8353,7c350046,319a0412,e562cb8d,3e4ee80a,5f7afcc4,37f0b29a,ab11a8b2,14947521,bbb4b622,261b9e73,f989e1b9,9f43a2ab) +,S(7385b644,2e43ab56,f4df8a57,4d0a32ac,6e5a7114,13dcd992,f86c0b04,33830307,6d27608a,8ea00e22,4197c8a1,9e9511fc,7ecd7083,86e94ab9,6aaa35f9,c8c2c5f3) +,S(35923ab9,a784ee6e,5a4e911a,7552fa16,ccefa4e3,dcc90083,e5a19e31,4dfeb06b,c900475d,980cce8,7d5cc091,7a28c18c,2fecd5f5,cd2cc66d,e26deb61,1c5acb89) +,S(d88b6907,3abccb02,2e235e60,4f3e2877,ef979f85,a5b3fc4d,fdb166b,a4155d9a,1eefcc82,69a20b9b,48d30d00,e7ffd021,a9b7b171,378a299,819d6e6d,19d5ed24) +,S(b86c5281,cfb9f3b8,4be4f83b,1d13d33e,1f6abfae,bbedcac1,63362a76,8740a827,c1a32696,fc1f8507,289f111c,85483b23,23d228a6,773030e8,dcf30f6d,57857dbe) +,S(d2813221,9c730094,97c257f3,1fbeaee9,1afa001c,84e4b813,d7ee2452,6454c640,75d722d9,7111d6f6,b6324598,8720ce39,66fae55c,3d81e4d,ade294d6,1269b4ea) +,S(445addf5,bf941ace,6b4aad55,6f174ba1,ee793bf4,9f46295d,19fd8e2,807f8d3b,cbe249f1,fbb39f8d,93079d0c,e84302dd,52212b6c,828a1626,b7446f91,4f6727e) +,S(a2dfad8d,66fd47fd,38fbcb74,b983d366,c57a08d1,b04f1acc,4fdf047f,100552f2,63011d2b,43822a21,ddcdb1cf,ef4dc0d2,5f595165,26939761,953fb738,77586c9d) +,S(c4e84511,6644466b,8c573b8e,c7dd3788,ecf1c6c2,63ecfabb,b13f697f,2b2e3a7c,1e53964,a70e83a8,ed9f5d8a,b6b79629,7368bc5d,cc90e6fc,4e8e6f65,542f63cc) +,S(63c4cc2c,cf368a04,be814d1d,81fa4250,653ebeea,ccdffea7,944801f6,efee1aba,6fc2bb4,a7e573f5,fea2cabf,abd9a145,c7c36d62,11928341,e9553e8a,b38fa90c) +,S(51eb8782,a3445ef6,43f01634,caad6fe2,29585dd6,f073acf3,62cfaa3e,960343c6,56d20f56,8e6d868f,491b6e1b,80fa5c88,e3d625d1,433b1dcb,5ae2d35e,b40a960) +,S(d89ea50d,ab6c4c39,48fc4d4b,73d7812e,a6b59ee1,8e7a51e8,bf6249bd,ec59d068,a1ae85aa,e842ab60,95feec2a,d6ce6206,e81a6e76,7f0b7b20,d41cd28b,6a8c4258) +,S(d121a6a8,11f953fe,a90d8f3,4487d654,fb48e4f3,c5ac4db8,3e3f50a5,cd7bac9c,a5b9e6da,e07a0f1,dc1695e0,20502f55,5fbf136,df11b586,4ecc63e2,d7061a6e) +,S(83f7dd06,e5afbb3f,7b2563f0,faaaa3cb,20c32db1,5bdaeeb5,73219814,caa599b3,c452f49,1e4482c1,1cd4bf46,75d74c5,ab054163,b6d1b837,dd10aa05,950f199a) +,S(1f5ba7d9,b4cf8684,cd073892,4aee1919,1f611d78,a943d49b,509fffa6,31fdc19,a017e13,7a8a199a,e361dc18,527f0135,51e48b02,c2f7f102,a6c1ffbf,fdd0baba) +,S(d25fc73e,a83ef669,c2e127c7,1615df3b,ec61ee38,4a6b3396,cc52066e,c3b70b8b,9b5d55e1,c8dd008f,19b5e989,363ea737,e7d7bea3,f7b0d9b6,951dd78e,be6c5334) +,S(d749373f,ecc1814b,dc8ce6d1,2ebe84c9,e09806a,9cbec814,cf98dab2,4a46ddba,88012af1,84f7ce23,730a3a4f,191d0687,4d5652dc,2be47214,61e9ad31,b39ee397) +,S(8e05da99,971ba37d,38e7642b,693856af,a90d7206,2d360611,6c8f506d,68316b9c,73de534b,5833287b,61f3f985,2723be7b,e8e22ee3,1d1ef4fb,f45d6931,827e3db4) +,S(e71e83f1,c6b285db,157f4a14,825aa540,558a7853,673900aa,fdb84556,ae5c891e,e37980b,c180e3d2,481d81f,f9aa33cb,b297ffad,7dbbdd79,4fc013f5,43ee679f) +,S(bc66d644,dd9da12a,299557d5,fd35993b,ab05ac8f,bdd3802f,25b35890,db8eed32,5fa8c7e4,bdf77750,573a4ac7,1681ca04,4f796ea9,c8379cd5,ed55631d,bfdb8405) +,S(537f194e,efe43985,8dbe1eb2,8e27448f,fd1b554a,b12805fb,3af43538,fe0e37f7,e82018eb,447b2810,1502453f,db4c1cb6,666330d2,ea3331d3,f79d5652,a1d64af7) +,S(4af2a9f2,e0fa4b4e,731dbdf3,676538c1,110f3232,7b8f2766,a7f489de,8aec3b4b,cf2e0ca5,dc830856,43151cc0,1507af4f,d84b253,2f0fdcc9,6489baf8,6c1bd4ab) +,S(81369bd2,a4945c15,389aaea3,4e2855d7,6343e200,a9407ed,d05ae927,5585aa36,a9b4ba4,e26950c6,6648b573,3c0c4e5a,22a51e71,ac3c1fdc,78403eaf,3a667161) +,S(1c0813d7,ef91aa73,9e3a6f0c,e3c7edcb,2b7117a7,2ad1dad6,1aed130f,c61cdd3d,e3390572,67ac3bfc,5373cc31,14bd0f38,ccc3cb25,862b243c,912c0aeb,98bb86d) +,S(8a651923,d2622057,59e5f82,b38bfae7,dc922488,749ea56c,e43f0f74,c268f9ab,f3df434f,14f67030,fe888ba0,185e25c8,38520bf6,6e85023e,e4ff4f04,b056d9d1) +,S(89d98548,30a2a572,dbe91018,e66b28de,835dd02b,f793a469,2de3d720,d70e8f43,629868e9,9e434bfa,98bdc4,f191a08,72e68768,ce8a918c,7c2da42,75e5cb3b) +,S(97d0c83c,5d83d399,c567ecd5,dae551fb,7f1838de,1967e84c,7f053b81,62965fe9,fd716683,73347fbc,407543b6,70734733,df623a55,1766f55,8a02059a,2ce55c4d) +,S(20807bb2,650e6d82,38a66ed4,b239b59e,fe073a5f,9cbf0d6f,e3d9a16d,be427de9,46a25a29,c104c56d,8436155f,64b1d84a,b974fb2c,951470df,17a9704a,be5c1f9a) +,S(3cbb1786,945bedb5,c8ac2d0e,dda1b0bd,ee314cc5,faf56b75,fa878bf2,b218a8f3,ddcec0c0,d05403e8,ea2094a9,6ea910f8,3261932d,701a2ea0,4e93581a,7e4b7275) +,S(961d0144,1618561d,c3504859,7e1701bf,35412ad3,2d04486,704e5593,b9278734,7e137d6b,2060572b,ef66f8b4,c8ce535f,b858327e,26dc2295,6ee6c94b,c83859bc) +,S(2814918a,115ca2d,688f4358,9010b7d8,b8b560f3,6a3dce2,8fcc05e,acd4845b,dbf76f51,ef80e324,8820cb0b,bc7f0c2,4d50ae48,6387d206,c333222c,5f959dd1) +,S(6c4f3b00,c02c19a5,ddb0ab1,798929ca,222a9538,b641cb3c,dd61736,77c9442f,a91d13a4,d3888b82,eaba5173,3ff76fae,8022fb10,8cd61f19,206cd78,7d1c99cc) +,S(8f48304c,ac37d495,fa1a2ff,2178f442,4af030ca,70662a1d,c750bde,5f5d8dd4,ccff6176,47cbdd3c,3d0c588c,37a98723,c2b2aa14,fd17cf9f,ea45ec72,eda8defc) +,S(ae3da559,e3fce253,f5c1fbad,8e12a52d,ee989ea9,8552a192,93f7db0,eaac9405,430b86d1,322191c7,9aed5bb,12eece79,f2519bab,17998346,8aa13b69,94032ef7) +,S(90c093fc,27fa9de,66a1fdc4,d921e5da,6f4fa049,81cb6f91,e085f89b,96561471,1bdad536,4ae198ae,bbb0ff88,3bd5dd2e,dfbaa91d,e989f45a,30befa9,76f2db23) +,S(730a1c4,5ca28743,538fcacf,a65b7d90,b6f4b1c6,87364cd,53dd6585,328eeabf,7420e8da,cc64a059,b46221c6,c3adb4b3,46eceeb8,8effca39,1a1e36d0,d665257b) +,S(341eabe9,66c6ce4,65ac18ca,1eda053d,4e6137c,ac0796d4,36a942e5,99ef897a,d298003d,fdd9f529,c1977b3,ed426d6e,2df46098,539b20ef,c2011a36,b7e49cde) +,S(8f7e1b2,cb538fce,4b4a7775,90d1a95c,2fef8331,9792c0bc,8d5f3493,54fca169,71b0849f,cec62c5d,fdce37a2,61e2a06d,32b3e0de,87c8aebe,e5a95cab,b0c3f798) +,S(c7ea6b43,ce1e0e83,819bee9a,31fba823,3ee03a6b,14988b98,e80aef2c,eace0d56,e9f1328f,dca6a16e,2100ad40,138f9810,17e37e67,7e7ca747,c3a57ad9,24b8891e) +,S(b16ea5c3,b03e58b0,e6c217c8,6eacc4b9,3032add4,30acfd7a,e50eacb9,a0e5c1fb,507fed89,5c14380f,ab9e54e,a3624e5a,cbdaed64,b2712f88,48018b90,7a88f47c) +,S(15cf4de,7c36b72d,f7b98c00,8e928731,a2e71c69,cd0427f3,ac9264b1,5a5fd487,3865beea,6b36732c,5ecfd21a,562ab253,d618546b,c1c24745,8881b20,643d7e2f) +,S(394efbbb,fa740f53,b1e70eb9,d12671e7,55337357,b982921a,79915acf,ddd18218,8f1f1980,6c1d631e,6519aadf,b563dbf2,37b75db1,54baf06f,6fde8218,a0a68eb6) +,S(e6c3e152,27453d32,cd4449d1,ab1ad78d,58f5bb6,f29d813c,e7c6628f,b284399f,89d87957,4b640a87,abadc6a,dc51a533,838a83f,53de4448,9ff0640a,502dfd62) +,S(e2480000,9db30642,f925ef8a,e31c54fb,1340e88d,b6d633f8,415ceac5,f583cee6,39ad28f1,8ecd8302,5cc1fa72,ae4e9897,81318cea,9e506794,50abd959,f19758c0) +,S(1c134120,3c2e7e21,f5b10ecf,402d52bd,33db3278,70cdfcec,f3b277e4,78f551f4,cd6907b,57cfad79,5e14e7c3,b2a06a46,17b7a27c,ff476bfe,38d68d0f,1470dd63) +,S(6b2fbbb1,515c261c,954a0be0,279a1cd6,63daa083,1fbd58c9,c69b7be7,ee6047dd,d38ef59b,4e276fe5,6f1f2fe6,74b6974d,5ef1f4a9,74abb2c8,17cc68cf,78a164a) +,S(dd5098a,8cc8ccf0,7db82096,b52d1fa3,6bd26c2b,57f0cbe6,2ca954db,1773e9cb,a198ec1e,71c53d73,5b50000d,678d7d93,de64a72e,8ad018bb,f515b4f7,c7840aff) +,S(f6dc494,3baa0613,59a000ab,3aed3456,1972d425,34df86ae,3eb8e5e7,cae23c22,7150f3bc,5a968248,d8c71ea8,32b116db,73ff34e5,35ec1e6b,64b2474a,947174dc) +,S(e115c926,5930dc67,bda89798,e267dc48,12c06d2a,a05e4a5a,6519b0bc,7096f84c,5b0dc7bc,82b61275,2aa17a13,c1fe2cd7,6b60cf1e,ceaa9234,ec9e6609,7b2018ec) +,S(6687f498,98a22d8,58ef88a1,bcbfb446,33d51eb2,6c1fc2ec,eeecdae9,e0960c56,fd1912f5,7c0e691,23977524,ba58ea04,5757aeb9,309a5b94,3c993a93,57475ff) +,S(366ea4df,3aa8da52,763b513c,efa3c739,af61a497,6fc4c884,e879ddde,c2457d1c,876520ba,cca3c711,a23186a4,833db7c7,14b3de4f,fc86e8e4,cbd61cc0,9a48f34a) +,S(f7951805,eaddd012,2bed030,f3013e15,6fec02b9,80ba8ff1,1a0b978a,3fbeb778,b255b5c2,db866de0,a145a108,f5eb4b69,271c13aa,8db75fc9,f467843e,a59549a3) +,S(c77d217c,5c7b8fbb,f7bfd244,b2a2d2db,372d8217,43eb4a03,47858678,471d8be7,55573d9b,dd16bda6,ad916820,874d64d4,b260a489,b4a93427,1ea5a79a,f57dc5c3) +,S(c803dc3c,1432ac63,19db169,6d7ebc16,58021b8c,b92c0fe6,a59d1efc,2056f214,ce8e23ae,c7dca471,8666f61d,d7d8bc10,e06d1929,7fbad7b7,7d45526,9e207b09) +,S(676c4c3f,617b661,2affb2c2,dcfe072c,ddee8b29,dad9124f,dd24e87b,52a80b88,6df8c35,be6818bc,b6857f47,f59a11b,e05cebae,ee6c53ed,8cb93fa8,92c49e0b) +,S(8b0c8502,bfa15f59,335cc34,20e04c90,becc2308,12d40c7e,14fc3e30,88b8f34f,eb75d312,9fa4db28,27d20c93,de9c5cc9,4237bbb,a9710371,f767f686,e5ddbbbd) +,S(6ea07148,5594bd90,2d0d526c,28918bb2,cdb7d1cf,d3ad0b1f,a3ebbf76,71a2f90f,3a30be2c,2058cb43,c6f8ae98,1ce8986a,8b4dfc3d,81d49a80,4e40c81a,a1fc8220) +,S(aba7df4,8bcaa5e4,c4fd9a21,6b4bb3fa,27617205,693763bf,71b8b214,9cf83c48,6b1b719f,a0633abc,4580a9cb,9c1210a3,3e5e3bfd,177bc76,39057e51,3fb9b3fe) +,S(ccfca0f,ee5bebb7,26e2062e,2b5cd592,847031d3,5edc7767,414af809,9b3ac2ad,135b2ff2,4e40f04c,adef93ed,ceededb7,380c1e9a,e32a499,467af149,cfb532cd) +,S(9af36417,f3076595,42ea54b1,4671d2db,f7582ff9,b7e659a7,6465ee2d,4db88e35,dc5d07a2,58d4f5d5,ae649b63,e07a4253,8b8b3e42,c65a6ba3,44900028,c84df8aa) +,S(e2f308a3,e4d99e74,d6b37cc1,dc41d9fd,e98a4472,6e86764a,89fe959d,deaf922e,f5f8eebc,d9252e1c,74b9040b,569c9d5e,11d12af5,aa21051,8f87043c,7b47776a) +,S(a62581d4,c4fa4b6,aee11db0,8fb698e9,864cf336,578c536a,8a887d1a,89b43e35,b530ce21,bba9d034,d53dd490,2b76f25b,4391914a,5f87b6d8,2526f7c3,def132ba) +,S(11ef91f5,dfeaceaa,52f434b0,fc03085f,60c12ea9,4441574a,5725aa86,52c259b4,a2c81e79,cb5ad0d6,bf0221ce,2bf7497e,bc91026e,adf0e25e,6269dfb3,2ced7d8) +,S(ff549a04,fb86bf9e,3ad207b5,ac76a74c,2532a1a6,516327bc,96353baf,66269c5c,ef1088fc,633f639f,f0061bef,4c1e4c64,5897ba0e,ee229d44,d99be0d6,95e494db) +,S(11c9ebb8,893b6534,b323909,961bb8ee,4c90c854,52848ad4,18fcf223,c80eb7cd,4b0229e0,89a1ca0e,d60ce2ee,590211a8,769d333,5f4ef32f,4460f8be,940a0dd2) +,S(e86b3691,f8ae48c4,12a6216c,c3633f1e,88667299,f828d6b1,3ff88cac,e060b1b4,14d95d6a,61298fb5,1fc974fe,f3957db5,4aac7130,a1ed873c,cee5cada,6eec0c6a) +,S(e5b9550e,eaeed973,5d8068b2,2c48bd2a,608fdabb,563c0e5a,6c2b2351,24c49d19,506ff679,2ea7c37c,254d7ae1,a459204d,aca23016,93c1598c,2449b758,6d437de4) +,S(cab58ba0,cb15982a,c1ae5b51,ad65574f,55540820,d057e11e,f9c9f9b,a1388335,ae1c9e22,74958b33,2ce0f0c7,ef621a49,4d5b0ad,b04748c6,539dbcbd,6bd4ef18) +,S(715e4568,9bd663cf,e9c83006,82fc7c90,5ae2da55,42b0ea4,40cbe2eb,36e1eb43,58ccbf96,8860cbfc,6b03f6a,a5fe05db,14be0e3f,3d6224bd,ce6eb54f,7372aa85) +,S(df92f1de,4d22a7ee,6d2bf45a,5728745e,f59b6b07,29614536,722c7de7,965c0648,59e18767,f0e22894,be586a13,46950c03,88f1529e,cced0d18,50439dd0,e5bc192c) +,S(885dd01e,dc8ffd40,c5f26d7a,bcecf670,7a791ac0,b2332b91,12e69cbf,11399808,4ad58276,6e763ddc,3f4ff718,569f600d,8c764659,87ebd74c,d506c2,ba886ac8) +,S(d3fe74b6,17a1ab46,c773549b,af4bcbff,917c7ecc,fbedb63b,651b2197,89c1ff9e,b2e6bbee,5d84b593,d43467db,7372f40e,493a9fdc,c5d88fe6,5767f45c,837acf93) +,S(c3730836,74b97237,66d9e9de,f7b6d792,93faedf4,f7d86301,75862d62,d4ada8e3,b669a24,a31f8277,8686d2aa,6b2acd16,872570f0,8e6f06b8,394f498a,dc29f099) +,S(4ef2ace6,422be7ab,6a614e2b,fc43360a,2fdfcdde,51cb31c8,372a2042,2df4e100,86868f5c,37366665,fc6121e0,a8ab3a86,92ba1714,f5b8506f,9a3c3025,eaf9fbc8) +,S(51110764,573c540b,813ebc4e,79d59277,67e30ed1,70a951b7,9ed05f8e,8d142cf8,ea8890e4,9668304b,63fad75e,33f42601,f2649a21,724fc495,61110e79,d7ddfea9) +,S(36cbfeec,5491e1c2,f853d98a,275c1baa,e74dca33,2bd3d830,7d896607,c1cb651c,f67659d6,677b44cd,33c0cedc,d5886ad8,90eac77f,5b393fa5,6cba1077,54489eee) +,S(d1ff3875,e1ef071,eef96f05,bc19d356,aeee18a7,f3892f02,4d07b43b,c3f09dbf,ba825e43,72b4a644,dcb5b8f9,62e0099,ab75ef9e,34b54874,f8d68197,ecbe8eae) +,S(45e7bec6,75819b22,f2761ae7,575ebd6a,8ef87727,a15e33b,3edc7ead,dd58fa5d,3482080e,edaea330,240b539c,7d6a2e42,2cbaf40,f93d5052,28c773f9,6d80fa86) +,S(8ca5d7e4,bd79aebb,bcc5250d,c86ac1df,373eb3ce,1d8cf2ff,5916cbb7,1e8e016e,1af3f417,afa5c1c7,89474f79,a0755bbf,a9a268bf,fdf242f4,c1599dc7,b7cb1e55) +,S(56bf2e78,e7c43841,6324e581,7330a6bd,208edee5,3b5d61cb,a141f9cd,ec3002c4,e8f91e4b,3984a946,29060a4e,534bb4de,f345879a,f4884214,63dd0299,2bfc2fde) +,S(af152859,31540f00,1be4a65c,e3f55437,f7be7d8c,db0283bd,f96bf71c,c004455f,1f58be49,77cf9b8,b7ddf7fb,74f7356d,62b8fe33,6bf798de,3dc435b1,86122b40) +,S(2f4d8117,bcffeaab,7db186c5,7aedcb00,80d67b36,a560c5f0,e323b7d7,79be70b3,e0a50d82,80677ee9,caafcaaa,5d7d1747,3f4980c,73831f43,29b15452,94e71829) +,S(bd96815c,e6b6d0f1,3688cc26,777c42bf,50fb8cd8,cd0aa082,94ad498c,620d1f4d,8a882c49,6592b186,b0a4071c,b0b556ca,27f2ec82,417aa246,ae24b415,8e4ddb23) +,S(cf64bc04,e0796fec,112a5ef1,2c3cd909,5c041b46,2772b818,3e6656ea,16d046c2,6a05162a,eddf163a,fc2cc91f,34f7a7bf,41660b4e,a8ac7af5,698c259e,47e77e86) +,S(3dc4bd0c,2c8253e2,4ed942a0,7f45c2c6,390a9d07,6d334f3c,80dfabe9,282a86c5,e0994668,7cc9c6ca,e2d04840,6d34cd22,e4f8e271,da4416dc,77e59af1,7057c43c) +,S(40e00b89,e58de390,6a56133a,fa574019,51be1efa,6156baa0,45fb3987,94f7ff11,cf675e01,1f20efc4,24b882fb,b7bb9ca5,5a1134f,b628acd9,a597fb97,968641d) +,S(5626496f,1f49190a,48929e9a,403f9f54,319a6b1d,301cf256,692cadc0,41301c27,21702c7e,2ee0efcd,b98a0170,110e3495,e23fe5b9,9674bb0d,b6f09e57,fe76b48f) +,S(2a2c8f2c,a580145b,a9593b87,dfe0dcdd,caa3cef0,20b0e2cd,3792da6e,2f989a11,4aad23a0,e01f6a43,3f6c2a40,f480f945,d45c89b1,df42d67,acf6b0da,3f46bba8) +,S(68a74703,a88b88d9,ee974a87,af7b1be5,1866ea40,ab4cae9d,90a4c2c6,5822b565,3660b266,c74b8be1,c98d3b9,b1f14dd7,e039b476,733a1322,d2d7d2f6,9ad59700) +,S(b50ad45a,4898f77b,c5544dc1,cc8c0515,3b1e15ae,d043d2f1,40bf9dd7,29e413e1,1a59e623,3bea3be0,5713c06,b18badce,69b84693,636be68a,532adfa8,c617a773) +,S(df18b016,3ad015e8,da7e87ad,e6fa5312,d665c696,e42e466a,5e9e2a82,18337c22,532d4260,eb34306e,691f42dd,c215ffdf,2f6cf3ef,cc1363c6,46b8921,ccf277b0) +,S(405bc408,446bb0bd,49eb838a,eaadbf1b,27d413ef,a15fdec9,86e8446e,2c799391,1293bad0,ca26e4a9,f80dcdbf,1ccb70d3,fca9f403,89bcc331,e917d7e4,bf4d0b3e) +,S(1230acd2,75b02450,255fdebe,dd0ae807,38f081bc,5faaeebe,4542664b,ec57bb15,aa31d16d,b145414d,acc29c11,b0ed9fe4,fad90a7c,451d9706,4f7ec6fd,75b15703) +,S(4015c1de,3e09dc64,9ec990be,898db42d,1193e1cb,81956b08,da1c15c4,b9a2af48,d58b2d0e,553dd49f,ab07e5dc,c5a66543,b7dd351d,84375fdf,2ce1db56,8185e67c) +,S(f3da2f12,7f47b9a7,192f00a1,5576aeb0,8bc36211,7fe1246,ad61421,85f79009,865ca0c6,4aa629af,b84f761f,b26a4938,25fdec29,ce1d4a66,9dbcd138,41bb83c0) +,S(15f1e896,f7c7cc94,f3f921e7,6dc1e30c,f0d43b99,e9fa0352,42e56a4b,90a0c736,61e85195,215b864a,6f5bd52c,d0274526,dbc80af1,4395f9d1,ce60bf74,27c18b33) +,S(3fad3455,470a113a,2f773ed1,258111ff,da926643,f7fa1cf2,8e9f7b80,dfd2105b,ffbe436f,a1975bcd,ee4eae51,8dece7d0,cb34aeae,ade738d1,b39f4c6,6ca08a05) +,S(62bbb9ac,282329dc,65ae7b4f,bd15dca7,70a088e5,45850aaa,bc4c09b1,9177f92a,9c000eb7,f6104a03,51e1bd8c,d8ac8f7e,22578291,35eea222,866f2632,2573dd72) +,S(9bf86604,a46cf253,324f5608,b7bc87c8,72939597,131f12c0,eae3482d,b1935e42,e9f2dd2,15cce5af,16149d3f,1116d79,74f51267,1b575f8f,6ab6367f,fede26e9) +,S(a2ec976c,b5e72001,a25f95e,bbd7d354,2f3b174e,80ee3752,db082910,895f723,dbcb75c8,365c6248,c52a83fe,1c79d7b9,37ca8ebc,5060ba7f,60b881c1,964105d5) +,S(dd91f713,ee212c4d,f94b1fc8,c7f246b9,cd162a9c,5c8988b8,f3adff0f,fdb0aded,efd02821,c4eb853b,bb8c55ef,c54f41fe,7e53582a,230d52fa,c18a53d,ca40c81e) +,S(504e6ab0,c47fb3f4,b6b74a7b,1e67f6e8,c28ef108,62c2db35,f16f31cc,e71d423f,e7adb424,3200ab4e,71e50453,2d849315,1eae2247,50ff7a59,52bf2656,65b3ded1) +,S(1a9ea377,27fad3be,155f7ed5,1caf01ab,1d30195b,1629fba0,dd04b7af,c1a4b8c7,2140f144,e531dab2,22cd4137,921b4720,59efbd57,c1c97367,ff2083e7,f2420206) +,S(d76324e8,31920463,d5d94ce8,f9654393,89d97ba3,eb5e91ac,56898343,397b34aa,189631be,df5d46fe,fa8f60fc,a8b22fc2,ac987d23,b21ff267,560863,6ef3a72b) +,S(de87a315,50a6f146,e681d8a9,f9a7cde6,7da28c7b,5cd7a70b,703695e2,3c9bddfe,d33a05e7,77ba9e6d,155bab56,2b8cbba,27f4cc63,13038f7e,d193137f,d14b8502) +,S(d8381e05,7fbc1910,8b5a304,fa984e0c,cc0f5d27,303a3287,9ecfbf73,a1137974,1dc513d5,ac96238c,79d8f740,c855e045,e5c4e567,b3f44744,abb3bf46,ca394e8) +,S(69da86a3,b355f0d8,138bf809,79e314ab,7cb34e64,45be4842,b8f3810f,11b2ad66,7db776df,68bcac9a,c0f8f55e,8ee6a7e1,771d4148,1f5d953e,e9bf832e,cf713cfe) +,S(698f8b8,66093996,e2e357d4,d671d21b,230726a8,84079fbd,766332a5,4e7f18f3,5925e34e,dcab3458,ed959aa,3903ac93,c39b8ebd,1c562691,3f844150,d41ad20a) +,S(37274120,6cb7047d,aa97274f,b12aa8d2,e5eabca2,f3ab0b4b,daa3fd7a,3d5365df,30d36bad,c10337a2,db6c30f2,e8876226,5ccc6a1,7104460a,6f438a9d,3e8e9300) +,S(4e8c8df7,30f5d411,77355739,84a530b3,8ca4012d,3d4c8ce,f6c00689,b72cbeca,d9f7aed1,f5073c8a,8d2948d7,86ce6dd9,93a405ba,393a20a8,719287ce,797163) +,S(1e62c3c7,16e4f6ca,77b6d325,8553a5fd,59f67df,f7295115,cd6e4bb1,19b4b5aa,7df17da2,a7397df9,e314fd8b,6b03d293,ff7325e2,769d7477,ef3802a5,7d8010a0) +,S(c79f25a4,664cae13,d0971832,fee6a316,ff338f15,40c1f3e5,95c707c0,6e035db,5ef7879,c46266ca,7b342264,1594e81,5c189ce0,f057f187,e43a61fa,10330e85) +,S(768a47a3,64304a44,34b097e5,132edab2,b9840584,6e543dd4,755038da,e355cb9b,79896b63,eed7e866,32c33041,d037554e,551f2a73,6f2c2b35,4dd7d7ac,f6562344) +,S(131671bc,604d622,eea3f06f,200edb52,f7223fc9,3fc8d4e5,496af1a9,f72e56ad,5a6614d3,7985f503,2ad7a53,9b99ccf7,7c453f94,3975983c,e948dfe0,ffb867d6) +,S(3b9e6127,48d11bfc,1d2d0081,24e79a9c,604bdb94,6b25ac57,749ca6ef,302d7a58,379e7cc0,fecf689c,f905e84e,8516388f,3e1cb41a,aab8192c,aa024de0,3332cc70) +,S(4f9fdecd,10e8cc9c,f5f2573e,a2fd231f,b1313468,f516af1f,76af0eac,9ad51d76,26d6731b,71382ea2,1172142,fc5e0f5d,d0f7afa2,c9409fdc,62bced0,e8246194) +,S(25f313d7,ad044b0,538bff0a,ead5c689,d5fafec5,7cddd9a8,31b9a4f,59b848e0,f28c77b8,9202c9fe,e64c0580,75a972cc,a4839e20,42c32b66,517605d5,87470c40) +,S(24a8d407,e26c4cae,3f8dbc18,5820f345,81bf4355,7ad036a5,200b9b7a,68bb8d6e,fc6a5d96,4fa25fad,4d09a1a1,a4ec4697,818e46b0,8cdefb70,367e3453,2462b98b) +,S(ef4df8ea,5cc100e2,768aeab3,112c7ac0,6077b754,75cab97,df3ed51d,6d397f4c,fbf555d2,27eb051f,54965eb3,fac1e21b,82d216ec,807b1485,5074ee56,1ad70883) +,S(80c9d594,578f6e4,e8462dc,228cd99,9b621493,63d55cf5,80e1c524,627055e3,b6d5bf04,97b44e3a,7c7e52e3,28f63214,5eedda41,f80c44df,c7ca6d29,77436f24) +,S(35961cd1,57bc1774,40dd41b1,6a81e31e,52349a5a,e4085248,fe4a19c3,b10f7a45,b999ee7c,b32f1051,f0e7eb9d,4689fb30,fac7af1e,b410d53a,85e79f27,70a7566f) +,S(4aa49d09,32a7fc5f,77a76a12,16240142,596a82d6,6b59d388,24f0d8a1,e7f70948,adb5b12a,5e40bd0,a14c174b,13c242c6,c5f25ee0,642a6265,60d293d9,64a4671) +,S(110d8320,a9b2c5d6,5b06f0c0,cddd243d,c83cfe4f,671db970,d1213780,f6c4af0a,a97c2689,5c7b6ea,a3a02564,d2af735c,9b43ceeb,9f6f2557,3fc468b0,467b12a1) +,S(d01abcdc,a363b065,d8d2bb08,388c3545,cc8ee88e,90ee66c6,18a9f575,c0caee80,317409e4,a70e30ac,279914d7,135f9d18,e19fe520,4c83c472,5f86a614,1863b4f9) +,S(cea07679,64506753,8dc24b68,19bc3332,f320f16c,61eb7b85,96e25bc4,1499796,edff87c0,67e97ced,4aa330e4,e9dbec3f,d800934e,ed7238f7,8e97a46c,a6ad9ea3) +,S(d4463e7e,da5fcdd8,8ef0133,a5dbb1ca,c93aefb5,64581da1,3acc3871,cb94ce1f,bb1efe84,81dff341,dc7a4a8a,c2e44ca1,b071bcc3,81e7ecdf,4d4b7edb,6996547d) +,S(89cb575,5e9323b8,7771a2d0,58dc78ab,ad8bba70,6f845a8e,9a45a16e,ffbca1bb,f7e743f8,a24a6728,f8e8051f,5a303d71,f1f47059,202d332c,23f3a293,9ab97e37) +,S(d035032f,8e8e955b,b71006d5,a3b098eb,7dedb73f,a15d0d36,7e01c390,18bdea9e,1ba4cc2,fbabc437,a9d17ff4,f3c59f2d,2a416d2d,c07c0c81,c3e0a180,260bf2c0) +,S(fec9ff6a,e37da167,208b1247,b754cda4,6c6eb072,8d6b65b1,3754e2e2,eb3223e9,305400aa,27a59f3f,f19d1513,3c5a3655,464c6f39,94fd2ec4,562d7f85,fccfb767) +,S(3cfcc8e6,9e872314,5853743f,efd2802d,bb1a05dd,a03a731,77daf6ca,da9007f0,42b23158,fd0c1401,29298d42,a6cce708,743924fa,624d582a,94b682ee,4beb222e) +,S(4438bc8c,f41b7916,dfcdb038,5c9b6806,83362409,69ce8869,c294990b,cd340e45,78154e51,a4dd31d5,14885a18,b7185fc6,84c699de,2862f480,937c9697,6155ae70) +,S(d2ed1c29,faf76c12,fb15b514,6a31cc2f,c799cc4,5fb226bd,c38d3b0,176b5d52,54984b30,96d0c2ac,763654b3,32666baf,82c04562,d0d92310,cce6db16,216bb219) +,S(37f21b9c,d1243170,5ee6db23,eb578ab7,31f4b470,ab07e1e1,68e69bc7,539b170a,afdc95dd,6379244d,cbcfc811,54aa1917,e8093b54,8ec2be73,5867574a,82ec10cd) +,S(73fe29dd,54c8584a,7d25641e,c62f257d,400f013f,763c504f,f0a3ec02,d1ff8067,197ada53,ba57463e,e23b9831,ef8a6a69,d3d2f84d,c7225782,e7569603,fe1d1c83) +,S(56b27676,f0e88c45,3db1819d,36a73d03,95aae3b6,59f612a9,fe28714e,20bc73c,98660256,fb7d7d75,aca14107,dda9e7c2,28459341,ee6de72,9e463c2c,17367149) +,S(fd898f2f,e7f918a4,61f8e57e,f30380bc,5192a5d5,e1f520a0,5b99658e,8d57bf54,6861b3c3,5b0f6943,48bc4886,15eab8b1,36630618,592ac04f,80cdd632,aa63b620) +,S(fef75974,2911ca2,8057e141,6288b351,ccf2d490,634c98a7,a80153f,e9dc6929,9d5d0031,3417797a,83f0ecb5,d4f45890,d679660f,b1b19686,ffbe060e,deff716e) +,S(2c4338aa,18a27e60,d1daaa92,3d837414,f199f585,8d33b66b,471c6562,c8324bb1,13c28f36,25f2b273,8646cda3,5a2a729e,eac1de3d,80430cd1,6a0f3a9a,cb859fe7) +,S(53d6a5c1,deb56159,34416235,c2f597af,f6e10ed5,444d15c5,d9ca82b6,8e1820f8,26a5d559,cc04f53c,6b1ff3c2,4d5a62f,f63e50f4,b7c1b619,9dc54c20,628364c9) +,S(e432c338,e550a635,79ab747c,f01f3ffa,9e39d066,b221fbae,8b44429b,873decd5,297e10af,3006b09b,80d0ae19,3c1e8b3a,80ae9051,3dd9944a,444b2c7c,42d0066e) +,S(a61c5ac2,60f3048f,92cc2af1,6d3f6a4d,696e543,f044192c,9d840962,493f5cf0,1249d4f,83608025,331ab42f,bbe338b4,727a5ccf,b086aeb3,f1d9c96,26859158) +,S(a2f37e43,c3c2ffba,c45ad316,e912b586,2a9ac698,f85ea54e,98fe9a6c,e1fa038d,93e95000,6bd329ea,57397b25,71dc2e78,a466c4f8,76ace5fb,36d945b,a6e9b24c) +,S(b2257994,44c2ed2f,3114185a,6ca617b4,bf4ac15d,40d73b62,44a81852,d30260c2,fd4607f1,3d4ee761,adb6b139,3f87bf8,e8b05156,5561d650,a47efacc,5ef01dc3) +,S(d0607bf1,5317662c,73df9f40,805c9b3e,208ca1e,7fa8c04d,ab9766a2,8c7fffc2,f06da1e2,7e721799,41a9e128,e25ec992,eb030ca3,6161c02c,8ee31d22,388bd999) +,S(596aa391,d4831e61,55d80829,35a85bed,a1ea3190,a499ec6,374389cd,1bd5d8c9,cd9240b2,9845911e,47ad147e,ae55a0c8,639b994,8d72d2f2,72e89fdb,578d4ff9) +,S(433ec09e,19b7543f,a460de41,e70f63f6,6097ece6,dad9b5fb,f4030c7d,bc5862c1,dce03718,a609efe7,1858f6db,184708d1,9275ec2c,76d5e93f,e55a13e7,927cba95) +,S(343b03eb,c285418f,ad522784,f91707e4,f268451a,394e85d2,824c837e,fa48900a,e6595234,643667c4,bb885b8c,1ced3a29,a71212df,f2904549,ccb91de3,75787922) +,S(6094f67e,41b23bbf,4d594e97,b53391af,f10a978a,19244189,63814efa,ccd6488e,ea874289,dd943f7a,c109939b,8fa545f7,58359804,ad81ed0d,26cef135,cd138954) +,S(cd0c3700,bba5677c,8d0ff53d,f06bdbf5,c5adce29,64921c9f,a1591c91,ae0a375,720b88ac,9374709d,1919854c,237cc5fe,dc53b14,3897e4f,3502af17,d7510c63) +,S(d37ef1ea,95ae727e,5166dd59,bf5ee82a,1f215720,79d82e25,6369464e,d9a87cc4,59c5321a,d700c559,c92e500b,1d3a4589,15a88575,df9774e1,4bee7b2,ccf9bad8) +,S(238158e3,d58e7618,95f7a0b1,cdad8a24,3e19bfb6,d1c65929,ff08e766,e62c2b12,1f65fb1,8969ccb7,27d50e46,39c7551c,5b3f25b4,90b7d70c,cc5e4ae8,7293a0b) +,S(260a340a,5245a039,4a2f0908,f2912f0f,63ed68b6,aba66fb1,951128dc,9d542512,d30646c1,e8aabbd5,e758adbe,980715d2,b0b169c6,fe09c502,3beb7f5d,b5422be) +,S(7333eee5,d111e138,f6e0b2d,4b476ba3,6df4357d,b28c8e7d,f232c61a,6c3067bb,d427a423,a4de1e60,e8b73098,b8582e0e,18923637,c44c52ef,fa0b5f90,8ccf786) +,S(c411f215,dfb87aed,be2530c2,82a61e5b,37a0df71,1ce61fd1,25624b44,b7673eaf,ca3d89d7,d136fd46,161fdbd6,3f0b075a,afe90855,51e075d2,391f3206,382a0441) +,S(275b0a1,9dd09495,78298aa1,c4b62ff,11e715fb,6c3740fd,80d7ec03,3f2635e,30dcc412,faf3f389,c9919b6a,f96e7b28,6eb8abb4,ada80525,b9ca7eaa,f3ce74cc) +,S(9f774052,6818bbcc,b068c11c,b400eecb,da60c4dd,22353a3,4145e3e0,91f81617,a9e56fde,8f38116f,cafaea93,35ee3688,50da5107,a5a3e571,92f2bfc,1b55033) +,S(60fb35ce,f1098201,353bd7e6,89b42fc8,9f86dbc6,3eb400e5,3b8d16f6,28ae4358,1906ce1c,6a6f41a5,2f45424e,86633937,8ed56578,ffd94174,f4f85960,ee0f5c2e) +,S(1390a621,f999c3d,1737c72c,3235e542,99ce4796,d65c1ec5,45f60b71,19f4ae25,8f1cb557,b101a876,296881fd,5d30556f,55d739da,5122c0f1,43c04add,3485dbad) +,S(15f372d6,9be09ee3,8d43c453,dc488f17,42f53a7a,7923439,66946210,60f1cfcf,c6007ae8,a836a1fc,b5a4c0f5,e584fb7f,2c468d68,9efaefa,6303bd6a,beecb05d) +,S(bc2b2a76,17dd9fb9,e6d60931,ef2d5755,d33c7174,7e8e28e4,be151b42,14537d80,2582a69,b6e9b9a8,c5bb4b79,4ffeef15,96f383cd,670eb524,2ac4e7ba,375509e0) +,S(5f8e0957,61e307de,26ffd39c,92410937,5dac9c83,7a5a62f0,b0864cd8,a37f2686,d342dc84,7657354d,d524b32b,62f5f69d,5b2ecbfd,71831b28,565cae36,777534c7) +,S(5451cd91,9e849ec,b8dc75c7,9f939957,69a39234,38159544,dea98155,cb001c5c,e00d1d37,f9ec02d1,ae8222a,744381,4f16220,800f84d9,17cea9d5,9a9e2a60) +,S(737b89ae,9d9951da,d2b489bf,f2ff714b,dcfb13fd,829160c1,39875a46,7343adc7,ef9e2ab9,f8246113,726e5be3,5c1da48c,a6b4fca0,53d35dfa,8a3d826e,e48c5ced) +,S(8b80e227,9b0a91a7,6af48413,71ae6fdc,68f4f5c5,58de6efc,1ec0034a,36a26000,909b49ed,6ce8c555,25441ab5,1046956f,d25a3a73,5d979c04,43ae5891,fbd43df6) +,S(9db9379d,346cd59e,ed0c0d44,abc4baa0,3b7af170,9f034c79,151aaf54,69296780,1a8f9e50,918a104d,b525c439,bb16b64,179dc4d5,452c86fa,e87ab757,61e97031) +,S(3aa7c8c0,293e5c9d,fb50b63d,340851a3,88b1641b,b864cc08,fe776500,76f98d0d,974dde95,7c958b70,e0ff9399,d2d03da3,4dfc3437,c1ca557d,2240fdfb,3ae1d36d) +,S(26cfaf0,d27825e1,6014e5c3,19bb907b,7a3b777f,b6bc69da,5cdafec8,40d5b4b5,2eabc11,73729fdb,d31fabb1,722be99,e5b4355e,8c2b4bef,53b21dd8,3cf81ba4) +,S(ee495a13,bd1ba28d,cc26fc72,4cbfee95,3aa72852,57c883f0,cb09d6aa,1bdf3b20,b340a2f9,978013ce,8275b7cb,3fad5c1e,857bc6d7,b43782f2,1e737681,fb39b619) +,S(2e04dc81,831bb465,59d6c354,c4c6105f,41f61301,769d6006,adb290b1,b75540c9,d086cbba,4d221cc3,7cc96b20,adceff4a,6157ab9e,686d1fd5,5d56801,dcf4b779) +,S(557b5b41,b2b2e4c,598460ef,22888da0,aa2ec3a4,7980247a,e8bd465,a6e64c22,6a3c62ef,f80832ab,83a9d698,f61f7903,b7f64e41,9900950e,c7d79369,403d57b5) +,S(a0ea9ddc,e2797fbb,d384a1a,2c26d7c0,edf866f6,9addb763,dc44b112,dc1cdc5d,a085725e,d947778b,40a2baee,98dcf460,b084aeb0,3f96658,4f990895,b15e3378) +,S(1acb89f7,55a51f58,d8ed16e6,99a2294a,b2f4bff9,2fa2d1de,9883061,4ed4b5fd,5b243df,31c3bc95,79c47c57,58eef875,c18bb896,424c0293,22d729a8,b7a32a21) +,S(fbced690,b601e450,2f0ed32b,8c2ac448,31c4b327,a4ad9648,97637b08,2f3d3912,3235804b,549210ae,8cb5bdae,e5b1b474,e682cdfd,8af4acd9,8c0c19a3,cb5c017a) +,S(75339a0,82043d85,54ff592c,186a183e,4597a0ff,48f280ac,d760d134,9dfc6b5a,dbf1aaa6,8bd5db0d,8cdcfee7,de6635b4,b7877ef3,6da38418,5688fefd,dc584b18) +,S(d83caf1b,2994a763,77a2bba0,3c644e48,7f170d5,845a7d17,b8be8bb9,84b0ad1e,e479d930,6d2a405e,f0be6418,3d4f8dfc,a7f58ff,95df1e38,c92a401f,17745879) +,S(35fbbe06,39d9fc5e,d595a67f,442d7adc,ae6f566f,4641fb76,149d6c74,42af49b8,5eaf204e,6217ef53,1ab09a53,e6cf4d12,46d6c4e6,b71ae8ca,4e821474,94d00680) +,S(d5563a62,bd6fba1d,e252a5a5,9c03bdfa,6c570145,71cd1a31,bba43700,2a7c1251,2f83b6a3,2efa7b70,1b4d3262,9e7a8755,8b681d17,cff0b992,1e102b7b,f851f543) +,S(8f2a2a14,a834ec79,107153f0,ffaf8f46,5cbb46c7,5a72d07d,5e2af498,f3359b75,30ac7456,5c946e21,73bdbd9c,dc999e79,260445e0,dad2467b,97234789,a4de1184) +,S(74482ce2,45605bdf,f7d586f3,c2e343a6,8f9579f2,543f7f7,22a4b352,24361b4,b2cae040,9ae59ee9,bff4fb5a,34847ca3,e4acd880,e35e4d5a,5ce47b70,3cc565c7) +,S(ca0c158f,cd362d9e,3724bb2b,f07305a9,5adc440d,24270efa,2a8f208d,7f540295,9e1daa26,5a5effd1,29f62b,bf0f5c60,c0c2b73a,58ddbd99,c832125d,3927e7ae) +,S(9c5403ab,b8b04f47,5eb4ac6b,5d526784,8d237d3d,c36e8698,d59172c8,a9d9e268,89cd0c87,9d02beeb,ffb6dc2f,fa882711,2071cde4,ee71a7cf,669f64b7,d463fbb5) +,S(e6bf2997,5eb88332,64169169,62f49080,29072e85,797fb699,df05526c,c4ee0de9,ae9de06a,1952c472,6047bbb7,b967e6ac,db33a123,24b07165,d2caf737,3fa40068) +,S(ae4ec439,e4392deb,5e1b1565,2310d52e,9cf5c0a9,8753a95d,d7b51e1e,5889a744,1400b900,c3159d2,25ceac35,4e566d2f,4e6f057,f4664b8f,465b0f53,2ba61852) +,S(c6351ec4,27d1d6c5,64c05959,ccee21d9,b086a881,3f4d7406,ba8d0ec8,6cd139dd,b7173d5f,bec7a8da,89c4cfbc,a911687,f39a455a,9293640e,7d473bd3,ef2dba3f) +,S(fe44937d,a54556c2,a50d9538,98abc367,6da5d722,6c6d3379,20092042,d1219cbf,c5c2e2a3,174fffd5,74761486,669b0cab,5a5eb21e,be669ba,c5c5a4a8,46e404b) +,S(760dd500,b18aa066,19a3977f,ddbb6947,d092649e,485f2b6a,d26d01aa,445588a8,cac47a22,6da2825,38126d62,38751a4d,93daf13a,420be353,3fc0f7ad,db68c20) +,S(8bdd111c,e271b136,45d00636,f2d33c92,df570cbf,6bbdc156,69fd898c,ce4ea8ff,884f1430,8ab84796,d61e557d,abb4d15d,15114c0b,dc770388,6ca3ff0c,622df5ad) +,S(406c6d3e,79fed3cd,16d616e6,7fe004b5,4f589594,ecb7ca6e,24210224,c5b4eeb5,aeffee19,f82cee83,d4796668,8545f0b3,b8e61877,f34a0b23,c6a3573c,b98c9b7f) +,S(c645ea95,2580652e,8e05df6a,3d208df0,83e00eaf,50cd7d4d,a7c51458,324a41f5,8b4b9cc9,d3f00fce,332d2ae8,2874787a,6c6c8008,a7577ad5,d225f951,82e8bd2d) +,S(813cd833,dacd8916,76af5b48,5d1ff72b,df03f2ce,c7657e6d,249e79f1,f12d7476,c364d1ee,f5f1d5f2,7438c58d,ee926c18,7162cc71,383e9524,b80cbae,3cea17bb) +,S(fef2337,cf88e025,d70e2a44,e68c22bd,95371f36,14ad9009,f2ba8286,290495e5,b622fc00,8b0a0f9a,9a36ddeb,ce10d871,e5dcd7e9,65ed2784,21ab5891,6aaf7404) +,S(8505810f,22888b4c,c8bb708e,c1e4df79,a3a361d9,5ac2b259,acc18d68,e50b0952,b80fd8aa,b7196e00,3fe24ed,fc6742d3,e7b2115,967f838a,2ef00345,3dbd4d34) +,S(b7aa2500,c77effba,3e93a4e0,b09a0f52,92240fef,4282cae,4c8036ab,2e5e5561,85823a06,1fcf2328,2dde378,8802d211,fb2cda3c,316dbba,d30048be,1295d7c) +,S(6dd2e626,181f0007,6ed53763,32493f55,a77cf5,3c268524,2be805c,7da06c95,2a6a76bc,b3f96c70,78920303,c5ed3208,170fa969,6c5264e0,c3cb1d86,ca322da6) +,S(ff5181a7,ab79b40,a3afdd39,8ac729cf,e49a6a23,2fa46f9e,4ce0bdc4,696e9f9a,99c20ca8,b11b6a05,47e81074,8a34c606,140eb3c7,ce5c843f,60203249,62858aad) +,S(a5dfb758,32aa580a,790fce58,b4c04a1c,9de648f4,19ec33f0,92491275,e8243ef7,78a66f07,e1466785,edfd5523,99fd1935,1ccadfb,e3b25bf9,d5279ed4,1d0b9fd9) +,S(fc5e4688,ea6e4553,610946a7,dd3497e,a5f698b,82d6b439,6a21e082,a9aabfce,d1b32a9d,761df7cc,3d69b5be,d7aac28f,976be204,7b2aff0f,2824fb00,b70d697a) +,S(179fb126,a3cd9931,f135cbe7,2604d3bc,83cd986a,d9a7900a,17436875,d3507016,dc2a57cb,b0bd39d6,c8daf32f,fbe6b300,52cff0d3,12e84b72,c00a7d76,3578e749) +,S(af37b7e,cac16810,9c51fe45,b2d6da7c,3505c1e4,bdc88b10,5a386fcf,e30a6c1b,4dc24b79,61e9199a,f594974,32c9352b,4ca9d735,84dde4f7,a4c0127f,21cc17f1) +,S(62d66f6,b534cd8a,66236ca8,5b7de9a1,eeb49aa6,e65e5298,edd1a99f,96fb1dd1,83c05dc7,e69dcb3c,86dab3d1,153d93f3,e9861239,6e25d3f6,6a6d637,248f237e) +,S(6a40f396,1587f5ab,89280eb0,568ec9c8,6958b4d,d8a379ec,2ce2489b,7e451ece,74972d6,1100a0bf,7751a400,6093ec78,1fe16c82,baaf0e69,74142a17,a405da36) +,S(2838f8f0,c6e20e53,9ecba383,c6e07a2c,5022d436,904e5da2,b91b283e,40bbd6bb,6bbbf962,2b7c41a4,6b72a30b,d051551e,e1227362,b0664dc2,509404c2,819b4985) +,S(21e927c2,82cd4635,c9c19c00,f18ddfe8,7aa9b60f,f3000c3,2019871e,a443333a,6834c23d,e05bc59c,f6fc64a3,af61f049,7c247d86,f76a2ada,7771dd16,999febb1) +,S(d9817ec8,f88f9cef,92cf9df,1fa9099f,3f10ac61,fa641ddc,9f36e854,98822571,53c57b49,4d84c3e7,679060b7,c7c8d4ad,f2db0c4c,c8cabbc7,5c29ad15,80b963a9) +,S(6eaafe92,1994519c,1c61bbcc,c1ad6ac6,f7a2d0b4,fd88354a,6a458e78,17503e30,f29a7f85,f3e91dbd,9e011055,f47a5079,7f55fa4f,46a6b188,ea4694d5,a086b4e) +,S(2bd45f,1625722,2352b5bd,a6d8e2b8,e7d23c3,f8497fe7,348a8d59,97b5cdbb,b5f9d5a9,8ed6387a,41397e54,6b3ff76c,4c6bf446,3093e979,2d1f8748,7a6b725c) +,S(176d02ae,cf4f1313,ff804e22,326d6a13,8b641e2a,3fd4d38f,2c27a35d,f1f456de,5ac13641,d2f19a4f,77097a4e,8eaae498,2afe9494,9188e411,e03ed031,fed9eb40) +,S(6d0bfca8,6296255c,1fede5ef,8d04dad1,2b6625fd,7bc127f7,3f6b82d8,b257ca8c,3c5c434a,81c17be8,8101b5d5,ead55e60,9d9dfb10,c5ce1b41,484d5fb6,f595fc10) +,S(b67d3fe4,f6617324,a4063fc1,142ff4b8,2a605a26,8b8fa146,697db96d,570ecca8,63ed93c7,a95a0ea2,9ffd6090,5c096042,b5562997,4957f47b,2d5bca14,21114bf5) +,S(c171bc24,fd80dd05,4eb3e3a5,5f50c9a5,322989c8,a1213179,be4503d0,2fb1f1a,2ead84ac,7528e7ba,982fec81,4b68ff7f,7aecf675,281f126f,9f41a7c4,5deb2e03) +,S(c4936f57,96269373,21abb8d7,df07e4ae,48ae1f18,ee1f8ea5,6682ced8,ec911593,52ea3664,1b441154,81805582,dcddf216,80eaadf7,4fb324dc,67439b03,aaccb1b2) +,S(b0a38c84,ecc73fce,200658d3,cb43cbe8,e0df114b,5d1ff7a9,33158b67,b404dae0,40c381dd,fc600cfd,ff24d7c,988cd4ce,74c18fe,130f4248,2ced320b,b91f2ff3) +,S(1610da0b,300d59db,d8746d5e,17d71ab2,e7e9c1d,2b43b688,656e570c,60336b82,8923b2e2,fa3fd34f,eff4ad22,7f9f6638,745167d8,fb769b34,b3bb7e12,a25c892e) +,S(f6723495,10cb5b38,da909d65,333adb86,d22ed855,74d24d35,83294cfe,ac88d999,6f726bb3,891187c6,3c74392f,a1e3ffea,f55b9a9e,76e3b584,1d13dac2,e888c740) +,S(3cda21c1,d048a768,d2863f4d,1028459b,c9a91c31,2626940c,f762c074,23d85796,af05c34b,4a15e00b,b6ce97cf,501316a0,85ba33f2,cb536f27,324f5506,54a8f03a) +,S(24e1bc3c,84c0ce3f,52e1443c,1ce82330,b69bbdca,f09724d7,e616135a,d9f99c0c,61385dc5,e5c36e42,275109b7,9c22940d,3ee4c679,99802e67,3163c114,be7fb0eb) +,S(f9511548,94dc4fd6,e2907990,7da4a5d8,ffff1eba,4fe12201,a3ebadec,2620a2fa,d40669dc,1eee21c8,ee1110c2,def5de0d,4f08ca55,6758dd14,b6f3ce64,46b2fe4d) +,S(c6808c80,61dd7e3,f6fb5ae,d129d23b,c2101af0,130537d5,4bb99baa,1b8ee268,2fb3e2aa,77870909,993f9d91,bf670cf9,bcd5abfe,26ea9990,6f9805db,c8707f84) +,S(ca952b81,f79a35bc,effc9f2c,c66c9928,cda6330f,42c44f9a,3191ea5b,5f473c3c,aa53ac41,f34fee5a,2028f7fa,8ffd5106,23cf2dfc,cfe5a1f0,99ef3649,d7f846b2) +,S(679c1de6,521c29f1,9b0d3c5b,ab481e53,d01ec2ca,c719fbe4,16054bae,593c0592,61d4eff3,5daff1f,a4bb875e,bbb42722,9cc996d0,405c74d0,6ef0c6f1,31ade7c7) +,S(6f7ac468,d33618d7,8c59d849,3571abb5,1d445a43,af10fbed,c5d25b13,58170f76,9187ac46,f2076aa,5cf4de93,52e5437c,4cbd2220,d8070172,807e84c8,10a05090) +,S(f4ce85c0,86a4fb78,2f081fe5,379984c3,1a7aab89,ef9ac386,a6a8a11e,596278dc,89d6d9d6,75983a6a,d1dc4c45,a3dafc1,cf951dde,2a038261,b414eb94,f9899886) +,S(18b0b225,19360c19,739623b1,7850107c,32ca6b61,295a8161,fc9d2e1f,8d1e60d4,4d8fd58,98ba10a7,3aadae04,a9ed18a7,8c48bd94,7825f0f3,b42685e0,d391dcc9) +,S(3f75a866,537d022,f6b9b18a,330ecdc0,bdfa7aa7,5b213f4a,876705ff,635d8eb,fd0f335b,b4f41615,7ea2752,2b8aa40e,dcdcacbc,1beaa051,97ecc250,f0782cc9) +,S(58310e74,290245af,c4acb91f,20b29db0,f5195039,24b9f76f,16952141,875d0124,f79e457c,364b374b,43c8d6ee,b408cbb2,94fe8eae,c6914427,83a74757,c8b27f98) +,S(90692ace,4fd3c4cd,3c808952,d5ea0781,2192c807,4619b8aa,4274426e,feb7f6d4,3147db2e,7b3b8506,625c21bf,8803c5f4,e7250b0c,4523a6bd,e25e874f,76d1622e) +,S(154d18c9,6c441173,ba7b8d2b,5099d9d3,92ae7e0d,57419144,229697cf,52384f73,1c196518,31ad8cc5,ea72b3f0,ed0d30f,78b773a8,1f54fc37,29043a35,6fde93a5) +,S(311ebd4f,5f52bdca,290dc97c,73102ecc,421a0b07,4c53c052,11b0bfc7,3b6eb94,69d17492,eca55f53,72b04c34,6696454,ab779ddd,8c7eb07a,34c8971c,b5168019) +,S(f62a716,6976f82d,b62e48a5,1eb45464,c845b71,6436d639,a9aa0a06,feb57d0c,a0b93a32,3fc8c047,3c4198e1,5ab5f499,e3eaa4f1,4bf99a69,b3ac303f,34839448) +,S(c23e0cdd,5e39eec0,d3ad195b,19294bc4,30c11eaa,67c6e87b,a4e2a88c,60998ed4,a521d1b8,8e409682,bf7b7daf,ff45f697,6254b8ce,6c63985a,ad2d9cfa,559208fe) +,S(742ca7fa,a8b4a98f,28040f8c,15db6045,70353954,b862c223,c7979eb2,3443ebfc,251ef412,e97a7e21,292ad45e,46c40774,b97a78cc,7826e45b,cef481f4,a64b838f) +,S(622a14f9,7bd04407,63eb5d52,c15c2f3a,ae185395,e89dda70,3cc4c439,60c5592f,e5db52cb,ee60b303,69da59eb,87ce10c3,c485c239,ae1c849d,32e0e239,df4d4d46) +,S(3d6dbb7b,4e28da6,b731c67a,6c038107,c2ec325b,6b10e31d,9b7d5273,fc81e20c,f0b619ac,febe82f,8c4caf5e,6d4710b0,caf89c2e,1a20073d,66ebe05d,69fc2c9f) +,S(d450d441,bc191b5f,9c2556c5,a56d20c4,48afec13,c7e4b9be,320ddb90,b4c320e3,661be65,b5eef8e8,b357f521,d360379c,585c9e71,c27bd038,f2d63f72,6f6606af) +,S(82f9dd1e,ddb046b2,2b33bf19,2970e41f,c5df0c45,f1375133,fe1b365c,eed1ec7d,cde9eef5,554476e5,e775e829,1d38a572,1d055c4a,925c7eff,35a389b1,388e18d8) +,S(5227c547,834a79e2,d6fb0c3d,720661ac,7ec0e2ff,5a1480bf,3f31ac82,cfb2650d,dca309ff,621c591d,aea1bada,bb1be76d,2fa30a0e,1c83b4b0,d66cbd59,7612c0b2) +,S(3eac813d,7e2c8034,f1d58217,c4372a96,a1fcae27,b29ed9c4,e870034f,7faa78ba,94005cc8,7b8f7aba,143573b1,79aef942,c1519b3,9c63b58e,e420a875,7c4c8b80) +,S(9373c48b,50fb0243,b42762e,3b80994d,61986116,ba2c0677,a38daeac,7dcb21a0,295f694d,70f8295b,cddc1c76,141ed17c,a1cd8e5b,79909785,dad43e92,9247b250) +,S(14019457,db851046,42b51ece,50fb8d94,201a80e0,f29d52ad,1af35e4b,8d82c6a8,c47d97c9,df2816f9,a6147dba,7658b5da,f9588dab,8aa393c5,8f721786,9c498b9a) +,S(1b01f484,ce98064b,f60333d3,65d926fe,ee1cead3,c1497c88,8409be91,2288890b,6817b86a,86c98512,634bf90b,564ce109,13fad61f,c807a256,36a5d6aa,7f2d6005) +,S(5bad5660,f615f36f,6bb9ff3b,19c07b74,9519caab,fffd98a0,4520802c,88b6cb22,4d23780a,e6796a72,324c369b,1987465d,90540788,88987513,13dea0cd,69f90dc0) +,S(7044bd7c,29d2a7cd,d662bf16,90d5ee35,93175691,b62d68e3,f8f66ef5,8304c509,f263888d,52d74133,60ddfb1e,d1c09b9c,871d6eb1,e5833949,13d24973,5721ce12) +,S(186411c2,f90c5402,6445dc4a,4764318a,f3acd811,52c01dcf,d11d13cb,a8c02afc,462b9556,1bf18dff,8a4211d8,89f420d2,122c4ea9,7fda3d23,558b6304,d25b7aa3) +,S(62ea528c,185fd551,745c1512,6fbfd40e,5f8933de,4e1e3b95,92a93b0e,b762ec3f,276da42e,3c8a6755,6be49e00,2e42522b,e3b95e15,39a4708b,36429a94,4f6a86a3) +,S(5e2c7621,efa587ce,bd3c2392,a1b8dac8,50b15316,c42570ed,7270b521,a65d6cc0,c7faa23f,eafb70ce,723338d8,19bebd10,bae703d2,1e72b496,f2f95b6,e83d7d22) +,S(7e27207a,b80f124f,9694f143,9a0cd895,2c67a719,4075d9fd,1bb7c9a5,a22dfa3e,322b729f,e19d75f5,89749527,80f3ae04,48edf9e9,d8c24267,18812dc6,bef5e602) +,S(3de40b43,9077ea26,8d94aaa1,93e9c7cb,98e362a1,551b9b10,d5eb64ce,15986582,ba36c2b,e0f9d3d0,220eb47f,4ea66d01,59236411,2898172,8582d3c5,19576943) +,S(81e94808,7e89846e,6c7e5ad4,feb8f0da,4553e460,e3e4620,d87a206c,9d3232b,e216962e,4068a44,920e6a9e,f03efd5e,afae7f96,3497ecaa,dc741c37,7e9943b3) +,S(3056eeb0,d00a19cc,bb5a2ac7,f320ea3a,4e931187,498ec23c,daadc820,a34f49da,c6803559,271b265c,80257585,1f0a78e9,85abeaac,cb570787,f398766c,aa21fed3) +,S(9b1e1189,752fb763,7a61246a,7134145f,86b973b1,e44a5e7c,c59998a2,77ed64f2,f6793c87,9b8c380e,65296c8b,eaeb98c6,b66e0be0,d03865f4,4a09177,5dcfd332) +,S(807179ba,f1f9ce93,bb1f7dc6,e3c6514,99077419,472b9d8a,1a8cc4e2,f35c0c5,36807219,9966eb7,f18dfb7,d3316eec,54f1a9a7,7214d4fb,ce3f3ff2,935e2ced) +,S(60dd7b7c,cbcab93b,8ecfa461,8cfef03f,a74bdd47,9cb90a1,5e46ca7c,c1bafcc8,1d24d147,9987f779,90cde228,22ea0cd4,4236875d,943eda25,fa25096f,e16b8ce6) +,S(19daeb26,23383b3d,d15b0075,77a5e92f,bcedee4c,91996546,a7c52200,d243e4f8,12676559,3d67fe33,b1c01d4f,cae44be1,5f5f5e31,1149962,83ce8f92,f6485e3) +,S(f42f8e1a,813dab8,9e4db5de,27445215,c0fb1cd8,91c9a96f,ca5ae1db,14e84361,3cd2ab35,55705994,42070743,d01fe633,34819d2a,af95e97,6dbee1b4,e3ba2ae) +,S(1a2b774c,d5d0dd28,26d7c4e5,886d65b7,a219952c,6a413d2b,9fa8f765,73fe2bd8,4e2d0ecb,384a158e,e57da809,d065e39a,27830625,400c51ab,dffdf615,5d88032b) +,S(e9fa7d8,94c55075,1ad1731a,b322fab,fd3d17a,889bccc3,73e44e37,b4c2c880,67528cad,e7987d12,77c61681,36abe0c9,5dfdce09,33129f27,ffa9d36,53673bd2) +,S(5347f349,e54c301b,abcfd8cc,50f6fe6d,8fcd0fcd,861757d2,bc36cbfe,39f460b8,16d08dcc,2a837b6d,f9fe2ffa,b188a966,9d39181a,ed2aeb40,9ed17c8b,554e9d27) +,S(e20e8cea,4450bf03,149bdf60,e95f7ed3,69fd79d0,aff9fb8c,ef6e5287,830c7ddc,fa256932,fcc569e2,613bc0af,5f90263e,6db633f3,6cebfe46,4c70b043,9b886058) +,S(69132e10,b3a919a9,8a7188b3,e9afcf6c,2d53859a,5955e114,a41f1310,55ef8441,e6c339cd,ddd26e0e,ac4a1c2b,39e19cae,2d67e726,8518b750,94cb5e6c,b525d84e) +,S(11e10c95,9bd9f79d,c2819a87,e17c0de7,9105af6b,fdbe3f6b,88d198a7,106c861a,27c29227,4a3677c7,381fe385,8382ca38,d4b98e91,af4250fb,40540828,246d5c16) +,S(785934d,e1b1827a,471d7e59,2a4c3475,3054b00e,b8aae372,444b00ef,d9d894b1,7b8dd2e,a038d4e6,23f0f1f5,a2f75dbc,fe34e76f,6d106ae3,33d88a07,56dc4a60) +,S(f09c814e,8e66b8e5,930f1a49,28b28e5d,206f4108,fe99f04f,ead93096,1cc17605,469bf934,b4059a4c,4a942214,e1d86fe6,dc900426,c7d0eddb,8d89e86c,76d60f24) +,S(732901c7,26982b9f,ff1229a,3e8f7c83,2f47437b,412d0b3e,274a73e4,24ad6480,6b82e2d3,d4830086,cf416593,9b04ff7a,89b835bd,81cccd8a,7a29d47c,b70da3b7) +,S(b8369a11,d23ff4ea,99ce166a,4708ab9d,389cefed,b1843d8d,6fc11f74,7260faea,f4346c36,63ec0ab3,6ac12df7,f61e9848,c2d4cbd8,c8e6e173,2d104d0b,aecaef9) +,S(5499e409,3df85dad,411b8675,c09d0c0,c25bfefc,2afb0228,b94f834a,34ff83bb,7775c877,8fc6e8d0,519a67a8,7d2fe9c,c8abd8c1,15ae1700,ad1a94d7,925a4c78) +,S(fa5bc8e6,fa9b13e8,ad787ba1,497a6b97,5c34a64d,a0da5b5c,836bd71b,88c93740,8c919cc1,19e45de1,54f6d0d8,f22d3b51,169b3f0d,181bb40a,56213cfa,a4ad126a) +,S(a871c481,a84f4447,89ecded1,e2b1f525,9b1d4ab2,b16af331,199f89f5,730cdb0b,c478609,30b85d69,1ae45d62,7aeca01c,9f10a119,500d5d4a,c317fdd7,8de4a103) +,S(63d3be27,66d33bf8,f7a38577,aadd5d9b,234bb77f,d206b056,379e023b,ecd25616,9509d09a,6dad6da0,aa5151f8,dd8e3800,abd8a799,2276ea0d,3c958f76,498ada87) +,S(413ab945,c133d383,d70e81d3,34bda75c,be7bacf5,e49d71e3,7a884489,adb28f8f,c3d49f0d,6c65f6d6,1c9c84df,a4138076,f0168916,393612b,837c1df5,df710a02) +,S(df070f4d,ce208b39,e2614db,77c6aa32,2a50bb26,2ec7141a,b1e26835,911b85c2,b0b1f453,1815fa7,83609235,da7bec0e,f1bf2ad3,b0e71f7f,7c18de8f,83f55a3b) +,S(1ae86e7f,300efbe7,8cc933c,f8cda339,1f0f8f7e,411e6c0e,708a0d75,a1ab1815,d322b34f,f0778782,7d2da5c1,4d6bf17f,f8afc8a1,8051a724,bbd719e0,f5f31a2b) +,S(2a38dfd9,ee86308b,e0c76ca1,8dbb9ec0,fbaa86fb,51075887,9283c070,f31106a9,69cb45,94832b55,abd6b686,f67d493a,9d45e4a1,7d557723,fbbbbb83,7ab30cc4) +,S(2c6d7ab3,b1c3301d,65c79d40,583b566d,3ee39014,345a4553,a77a8e46,95b779e7,eb392dde,318bd27d,446b814e,73f9cbf1,380e38d,fed25022,bd584585,d671e470) +,S(758739e8,2aa2e25e,b1d8e027,b0e401b2,c82db2ca,549ebb9c,e1560ec4,531c5c77,d3792987,c3da2cc5,5760e52d,a19ea1b4,d0c2cce5,3f612760,bfc28414,37090975) +,S(7ef11cac,99fcb66b,71de229b,b34e82c6,e3149f85,ba1ffbf7,f22db64c,6a72588,64d7c546,28892864,1db41465,a134cfab,bc08ea64,11f5b2d5,b1de9f0f,7ae41b70) +,S(a7d48b06,c66ef847,f17b4b3d,ec40eb97,cb91bff1,c06d4a6,5d6db8c3,5561e4c7,2f22aae0,d6eb7221,d24f025d,ad1768a9,a619d6d9,db9d8e74,948d9263,3d0676f) +,S(a14d7354,1bb93625,d80f654,af67febb,d774e42b,6430a14,a907c52f,84088ab,adfe7f75,2b080bb6,89c031fe,c7c11d1a,bc303b7,f1a0ec2,38a4dac4,afbb2a5c) +,S(16076f95,b067381c,9d71cc9a,928f10db,43553332,f747e33e,367cc7ca,ffaa5f88,5c05040e,43a29d4d,e16b5e42,b672f618,8f0496ef,f307c269,13df7c79,ed2b1502) +,S(973450b4,a297ebf1,70630a71,fa74ae2c,8f3f8e39,18ff73fe,41bd1e65,5a5acd29,ba04c21f,e92ea639,99d5d87f,77181c31,ae8ed87c,dca22054,2f746fad,61f63039) +,S(aa29f7ef,d2f06187,108ab23e,16d9f3a7,74ab6459,550048cf,e1ddca0b,45fb5942,431cbd5,c77b31b4,d8b8568d,b092e721,a02d643a,75621eb6,1016b363,9728e2e8) +,S(bba61b3e,52614d14,358dc227,e0c0ea6c,e4dce364,fb7e0500,72d0d780,14642d9b,f33e0e72,6e9ee195,21fb4a80,2510156b,230a7ff,6e4c6b38,cd38b3cf,65336d6e) +,S(911443a6,979ede22,f23df6af,e4b1ab,73867dd7,a47e9268,3e3cd83f,241bfacc,a0e5be1d,31cf0375,7c2469a5,90f3493b,e43a99e2,755af9d8,b87aac67,ee7a6488) +,S(ff2126cc,5698e6c1,2da7f441,b031ea11,30132b86,23994f64,b332a8f2,87616d41,c616d5b3,79eeaae2,b072a11a,d2b316c1,b2c851d6,698b6d86,7fae1abd,482e91d4) +,S(2fe68e9d,de151731,12e1653a,2a6abce7,615062fe,a5375ef6,a2be1e90,67f6d8ed,c24e4b95,718acdfc,cd9f39f5,eca6f2fe,74fe7f9b,ae6aa352,e3651bbe,5d81c9b8) +,S(dc08aedd,90e96f6b,892ee62b,1f719619,6af44975,58d70f1e,7294863e,271ddb99,7250d846,1ac24a2e,e74bc5a7,53d5361f,8c012986,4364d84b,4afe22cf,c94aad99) +,S(e9c21052,f350d1dd,caa82594,b6eefb5b,f8f01ec4,1a423278,fba3951b,fcc7eaae,6992071d,becaac44,a5cd1537,cd066f2f,c432f198,621b70ab,360ea8d1,35757784) +,S(110d5ac,7838b9d2,d33bdf5e,8aed8529,5ceb9334,d409074f,3c26e3f9,f0cb792c,7879e339,427d8425,b597e76f,56a7a6e7,9a8cb00b,374ac98e,9cbec66a,47bceac) +,S(92982af9,ab48532f,cf2ece2c,9ab346b8,7def4729,8ebcc03b,91869aeb,42f9bbda,c6bf5a6e,8639e2ca,772e8c36,5f824b3d,331c7be9,4c13e9a8,ae6a779e,208a157e) +,S(c3f07f47,5246bb78,eac4e9cb,263c774a,3447acce,993a9707,14c1b553,79013162,f1931fa5,d6fd228a,a5781b35,45faba70,df6bca90,936acf17,f81a1155,4897e136) +,S(37640e7a,eef3f326,a598d363,df4f46dc,8f0decb5,ab6e368e,62294c53,ef3fdc7b,54fe19ac,83a074aa,796feef6,8d39358c,7be8848b,433e1eaf,9982701a,3eca7a1d) +,S(e903363b,6c90bd,2bf15176,83411d1d,aa9f0bb4,a22b5f03,ebbee32f,8f0cdf4d,fa44eae0,78b4b6fc,63abac71,ce0a6e0e,16b42d80,94179f1a,657eabd8,7eea2480) +,S(3c5fdd9f,7313d178,312bc477,849ce90b,a22770df,867a815b,2bd1d1a0,600afb6f,d81524ea,9e23ad00,bd7197ee,63457745,75795d6a,63b8b15,a19cf606,72159a05) +,S(40b540cf,43713ef5,c8b919af,6c991632,e60c198a,677887be,33b84c70,7c0ede8f,54586256,7352c824,49ebecbe,6eaae259,8e1cf694,fbb296bd,c14a4a59,240798e9) +,S(67da332f,f57adb72,8eb8b926,5a650e23,bfe5271e,396d74f3,9878c22,6f912053,91aec263,d7b74e09,b4fcffa4,87cee236,356e4fdd,bfa257c8,f3e3be0f,3a3b16f6) +,S(40cea066,fa029178,5662c994,db5b1153,e59fa121,c9133c2,fe1c6d20,91d44d98,61475cc7,a5ff5251,558f258b,aa8d69a1,52ed6497,c8ffcd55,2b66baa5,534df64c) +,S(c4eed050,248cf186,f8e2c079,870a139,c0cb13ed,2cec040e,d98a18ca,9b67ed0,50e9997e,263c7441,9e71405a,4d342e76,c5548e,1a7a3cc2,97e4e00e,91fc476c) +,S(676b60d2,14e309a6,8c7a8470,70d5bf62,8b71b7fd,322ae568,56fd4a48,9f3ee83,16e0d8d,371ad6bd,4713e9f,7c5f329c,72215cf,21a48527,35a0df71,205b733d) +,S(af268996,29117c69,c3beb193,c5cf7944,d4d3cc1b,7481d08e,1a190b45,c03e1fe7,359e17db,bdbe179c,8cb75ead,8a0e3c86,2b1d7d28,4aafd2c,e45e7b9a,c6d83ebf) +,S(62e15cc5,a30d1388,2b3c3890,4e1d11db,97b0a7b7,c658175d,e438591c,ed1ed489,fab66c6b,ab7b5ed5,815c81ca,65cf364,f4cdf8fd,7a6fe8e9,ab5ceb66,3bb4e8f5) +,S(6c7af496,df980977,41f5068,f34d0477,7da16397,c853539c,1b0c1263,2e43ccaa,4eb0e461,5c6fd9e4,3aa05201,88bb264b,d55b3a05,fc2b6c8c,d6f5f51a,4314f6b) +,S(757a45d4,4c662311,289be914,4ccca5ae,6ef89f51,52d66a2a,9be64096,cfc8fba3,732ddb9f,62fdf217,44d7daa6,35ca3e92,c3b84061,bae4c220,13339e06,fd4da7e0) +,S(14978c08,f1eaa9ce,4d878db3,29f0bc94,43301fdb,24b525e5,4f9f27d5,7fc114f9,439d8e8b,2b9fdc0d,85914620,9c883731,26e961f6,82407867,b10bdbb5,3074e5b7) +,S(3f231c93,760d9198,4a8d9adc,abd83c1b,3ae620c8,f067d103,6d1e5e02,2a72bcf9,95eb3a0,a928d3f7,dff3426d,763cf6ed,20d6df2f,c5dfb17f,c53ce0b7,90412bc7) +,S(c90268ee,75cc8e7d,7fe84298,b1db4255,80c3c45d,3643a280,e3d5d0f6,7337b616,f566fecd,1158d49c,c12a1dde,d0b1fd7d,d9cafbb6,ed3fd09b,48689f85,b01cb59) +,S(6457f0e,4d6cee8,7a2c0aee,85306a02,42c017d0,1e1c9807,5b460732,5c1d82f,67bf2f81,262de4e2,ba9d29aa,aecc9315,ff56c3ed,2e73d438,2a3dfa6d,faf9808a) +,S(ddc591c,1abcbb88,3de13bc4,490a66d5,3d96c97c,f1e21ae5,6a430c1c,39b1b629,80ae50f7,b81f043b,e3db78c4,da7b6078,871d4813,1e076ad9,de59fb27,b942f72e) +,S(22b19bf0,5efeb280,44b43bfd,7a6b3427,2e8b3c1,f6635ec8,d6966a,6667a252,47f504fb,ef2cea6c,8692d0a5,1f492560,151429c3,e522c23,2914e880,9ffdeef0) +,S(d5883bd6,c13d93ed,50371ce6,ed6c4263,395c5d28,f589c84e,cb9fbfc7,2dca651e,acde7b79,969cde2b,9a580387,d8e3a99c,45f15d38,f2e2ed79,688a3a95,80aa9a8) +,S(9615736a,4804dbbe,439f2f82,ca576623,a1675aeb,9ea9e40e,f6b910b6,c84af16b,a0967216,67f9dce6,25ce5331,62d45477,31be7427,74eeb1ec,4e3fe578,343c46be) +,S(ea36bced,959bc461,95e730f2,26224652,2472c2c5,70df6832,befa40aa,5c600e32,dd52094,82eb08c4,bc233090,2aa54333,87d06885,a9357f40,246348b4,4d97fbf9) +,S(44814860,ddf61b77,77cad443,18c21686,85c614b0,1c5830b3,b178a52,d85539bd,f3e5fd15,c71050b7,280643dd,bd2c55b9,219e7fda,cfbd2e98,94fa9a4c,9cc7ce75) +,S(814454b,cde86996,56b44c39,69bf0a8f,31b6d032,40098f9e,43d52266,cee66f49,8baf21a6,601db25f,2e18f5fe,decb9f31,9a6378c,adbff6ec,99bfa2ff,8d26b5c6) +,S(1ff790f1,11f7bbb5,b6db5f83,22ac696,c1de09d8,e50b9f4d,641ef76f,d43fdad,145d0aae,c218d6c0,219ce9c2,313b4962,f873c5c3,5424d3b,536c1543,14fa9517) +,S(275cc6c0,6a8faf20,c3c1e88b,87e27d35,661c6401,d3a1bd96,18cb016e,fdbc6d0c,45cc522e,97b61ff7,696c5780,638054cb,5e97b6d4,fc4a813c,7000a633,4e9f2a7c) +,S(9c78cd3f,874afab,23874f0c,8a84fbc8,a6d032f6,7fef6c6f,29c90513,bb6926f5,818a2406,fedf958f,7efafc4a,584ff6b1,7bae1b65,f67d1086,c3e013a2,cc318b1a) +,S(3c060395,f2cfe9f9,e3bb4afd,e5a71e03,c5a92491,323de27a,c9ebe1b,170153eb,344d08c3,8021fea2,6f55c0c5,85af3954,afda21e7,14cdedc6,8ffa3771,43b2ca27) +,S(f4b61a9f,7392b960,752bafd0,ce521e4e,57bcb898,cbb2dd9a,b0f7db8a,3ce5ff2,e412589e,f3678029,15813dfd,acfe8056,2a59894a,4c87640c,6044656c,e8998d5c) +,S(418698b7,6230acce,49505275,a0c01e9,4eb356a2,e3c242ff,470b64be,fa91ce85,cb9dfaf5,4c64ed94,f97e03d,30e07876,9e5a3142,d0fc0902,5e20ac2c,21c4ceeb) +,S(809cbcd7,91c1f309,864ca343,3d9a11dd,2db3d9c4,5350ac5b,27f55e19,b9941ce2,8161347a,92fdcb92,263f1d85,2923a15c,42d5012e,30d7d9b8,623cefa6,12b06bf2) +,S(6410c007,1d1025c9,8ce11509,5359e962,58c6a115,5e7f34fd,30fc8862,f9569f23,d76363d6,2661a55c,6c211bc4,13b1dd7d,63fa6964,a03d9461,e2870f2e,54c87d29) +,S(8394abff,22ef6051,7517e352,12a4dca,103a19ab,4091c7e8,fd417a,98fcfd2e,20d0ad3e,bc0fd15,fd405417,61bfbb40,8e37975d,a77321b,67ad2ef8,35732c0b) +,S(dbec1fa7,765386c1,d7558cb1,f19788bf,ce0e9fa4,7ca41edb,2f2d9ef8,78a04308,5d7c918e,335ef23a,934fc963,48dfd8f6,ce79885e,f4c463c5,b2645c8,48083ea0) +,S(9d6fe17f,3f53f921,893a422f,c9f675d4,652cbe09,a870c81d,8b2ab9ee,9a591cc2,fae9ccd0,b22ce7e3,2e7faed,2d47c36f,25cac5b1,e56ea936,a6811f11,8d485a2f) +,S(622f8f9d,65c4270b,1479e4d6,6f82fbc4,cf23e7a4,d09a6537,22c20d9c,54f85f55,e87650ee,4d9ac5d9,c6566612,1b6e4679,7e52953a,d7c3aedc,2fecc22f,d5b76591) +,S(cb1db853,b615cb5a,b92d0340,7ad7891f,2e7b1d4d,120ba3fd,a1ea3565,ee1d1436,8362a39d,9d425eae,2451d601,27ac2824,3819da08,856d0db2,18f339d6,fcf20046) +,S(5cbc6a63,59d9d6a5,2ceb093f,ca5cae,f32892f7,c9d04091,8245d9ae,ebd594cc,c4c18f88,7436575f,39b9e7c3,27c4efdc,6a3490b1,23c50743,ef03b1bc,34566bd) +,S(37a3cb08,3a9b7561,78ff2128,e7a5b9a1,19577af6,61974869,cf555dac,ee2d11d8,1a8a6297,4d0b6c5a,12155e9b,cf895c95,f6fd2b1a,2776c32,8d6b56f8,32f114ca) +,S(8e0611d7,ae0914d0,5d39e06b,9b359400,f21c3beb,73ede92d,bcaa6d96,8a995b95,ddd4f522,d1c6a964,9629727f,52740664,43e80ac9,7d9c68e1,225e60c5,38129bd7) +,S(9ec34a91,8a4648f0,1c1d726b,51b1874f,36410180,8bee25ac,c159c251,fc115510,bc5ee2aa,b5e43b01,b34ab989,5f4cd71d,1d3e6288,915daa2,e84ed531,4b388b8b) +,S(dc19ec7d,c901e215,f6d0603e,bb5494ca,aa9b5409,67a5a339,8915c4cd,84000654,b55b9596,a18e53c4,b82c669b,92defe5f,bb5e58b0,3cd227b6,3b439b4,ef13bf13) +,S(51bc3804,bda51e9,d0c45087,13599f12,b9a8599d,6e8ce949,5a3f595c,7d38dc8f,ef0d6522,fe3a3c4e,64ee1092,b9ae8f6,e7847bf,94044693,a3ac7cf0,f4aaa37) +,S(13463b32,dff393d3,dfddbe3f,bd6ade13,190e0bb5,83e3f126,344b5e01,3105e234,ea3df1a8,b8270f70,24910f40,a519cef4,9944fcf4,d82a4300,63b2026f,8f019ff4) +,S(c49b3261,2e286adb,606686d9,67dbf4b9,57819dac,9bb75f44,8f1416ec,f900fa5f,ffe45b6d,8c19de7e,c08256e2,96667d89,f290f5d2,25a9e380,c106972d,79551b1f) +,S(10fe7aff,36a8f4ef,79e2d8ac,619ca92e,2300878b,cf21a271,70f89e9b,6294dd28,f67da70f,623fe6fd,2c7113eb,fe6458fe,d0d5471,ab639050,685a0fd9,33afd6a3) +,S(d56037f6,efec78c6,e31e633c,570c5e46,96f96276,b86d0b89,e993f014,53592300,2499b92,4fd99b5e,a56f9649,bd8e53c4,b2f20dab,9fc1de83,dc199022,1f606b37) +,S(a3c1d0c8,939cd4b7,5cce8ce2,f3be0226,589fb32e,55457fde,8e700a77,a60bf003,b9054f66,bf6450cb,782533b9,33190084,d6f5944f,cf4e06f,de72d483,144c941c) +,S(85d0c4ca,e1cfe42f,b5f73f31,42e97e6b,c0855f7e,db19b1a,8668e413,4efcd249,d8372bc,937fa754,b81631aa,33a8ecbc,a25f86d3,d5e0627,d6964ee,5c08e68b) +,S(3092eae2,d41d0ccc,10af9d81,fe8c80f6,9ae27c9b,74b5f696,7a69211c,8d6ef98d,153f0882,f6b720bc,c8ae5924,923e0608,d6163c3b,32d36742,68718d6,e7f35e4e) +,S(4aeb6ac7,fe874a0f,1c24681d,884d5497,3486f293,9b01ebd9,74c34ea3,429be71a,d7077161,c508a7d9,63006566,f652afdd,df87d0b2,8daf3fba,21f206ec,a94a53e4) +,S(729bb0f7,be975284,a68363ef,40003a6e,c770fa4,5d6e6b99,ab0c5042,da563f32,1e0435d5,ea85370a,7293396b,407da43f,c540aa04,24f21de6,a002f555,cccd4480) +,S(96164ac5,1074dce1,3b973689,a39b6795,9bf5756c,4de94829,66bbdd23,9e665fdd,5cf13b8f,56c92710,80c11626,6bce26c2,14a39237,9aa68ed1,b7a05d65,7bbea247) +,S(6d45d79d,9297bb8a,326b889,391b18d7,31af609c,67b31be2,9b4273cc,405e3f80,2d99909a,7b6969fe,148111fa,1b9c9326,97fb465,494a8225,a6c62626,555ed02a) +,S(70091076,b5b81f33,42170f0,4881c941,d2fe9b0e,ff156221,66f0c92b,4f9e8e71,7c676c5a,4fb434d6,58f635a8,20b454f3,4c9795e8,b8860d27,4d0fecbc,ce7824a2) +,S(d04c0a77,c8fcb3a9,a02df253,b8819853,63dd47ca,bc1f8881,88d5e56,87a7db74,302d1b96,c35a2626,22bbc6e2,841b5cf8,efb77374,af428f9e,d69b2b11,6993db09) +,S(3c93d2bb,7ee61cb0,7a25ef65,f3e22eda,6e74d2eb,f3ede111,b4f2a28b,b4f206d5,65ed4db2,b1647b39,7225741e,241310e6,7a47f0ee,4f459ab1,3d29689e,cef70336) +,S(8efd5a54,a4c7567f,bd971cce,7ce3006e,3524dd81,cb7a4ee1,a5c61e12,62961037,6b9688d7,d73db9a7,1410738c,80430ea6,ea329145,718b4177,71e542a6,93b494cf) +,S(e7aa8121,34fa1f75,efd2ff02,273becca,18bf1ea9,47d168e2,cadd6e9a,6c448425,8af9da38,e2471dad,128e004a,d7b03932,2976d84b,7c91f91a,af471546,dfa5acdd) +,S(e4335a32,b3218d51,9c582689,85138591,4b7cd8fd,4e4eabc3,b5f9e0b4,c3212b84,ccfbfb0f,50b5fe75,c849510a,bac5870c,3016573a,53eda160,b14602c2,42ca02c7) +,S(aeff696f,e98cf587,745adbee,3fca1ae2,3f8f5768,56bbad5f,4a26afe,904a17c4,55dfb880,250b9a5b,7eb971a1,fbe0cd6,ad2d375b,88d98e52,6afcafeb,7ac4617) +,S(72fdb2e1,eb120244,4b20bd6d,afd6d49f,46a56f25,63e679c5,2de98cb5,bc999a5d,e29f2,34ad3637,7b4a9cf6,c307b8a3,a779cc22,ae472aac,eb519c10,8137162d) +,S(eda9f183,f89750bc,8c12ce7a,fee54145,42edd9ae,9fefd508,ab588bf1,6c7da0e3,a9328c5,81b0cb02,fc09fcfd,2a57d2c8,fa313ef5,4e205902,9bcf0846,811be308) +,S(744683c1,2a0150be,1d7655e,b5a3fc97,4303387b,e53bcdeb,41dfbabf,ff12f6be,df2e4b05,a459aa27,2d3de8dd,4c211dec,e35eb798,67050285,57dd53e3,5b9950f6) +,S(9f3cabfc,106653e4,65daeb52,e86d99ff,e3ac6df4,5eef90f0,61226cc0,32592ef5,9f20d174,1b78c8ec,d7425d19,fc0a4c9b,1f1cac8d,b97514b5,8585901c,41862306) +,S(9dc15715,9f59c338,d56a7d9d,ce63579e,9e95424d,e6db6927,418b024f,ed95936a,278716bc,3e131fa4,75b9ac00,6e868d88,ce17e6ba,d7ecd202,33fbba0,fb34f0f9) +,S(b6c91d90,b1bf3b46,4b526186,69e1c118,dcf8d6f9,c8ca7473,5a361a28,b53c823e,15132dc7,69e59b7b,fe5e9966,1b82e47b,3ee4c3a3,1c0b8201,517dc567,ff90a4bd) +,S(56604a9,ab972c4a,f18d5f8a,d5cb6d94,2d0c841,a7defd1b,b94b1b25,c31df400,3d2f2a27,adc2eb70,336b4b44,5229e09,a74a113a,f1b21bd9,1e3f2351,15f6a85b) +,S(a5b57de,fcd3016a,917ababf,171c3c31,ed62957b,cd8d233d,c551fd9,6216561d,3731d822,155afc28,8bd7ed39,30c3f6e3,58a46f5d,d9fb3ed2,6d7c7da2,a8dee233) +,S(da179b61,81e27ecd,d545af40,ea5967ab,7c0ea9ad,68a8c0e7,4d4a5aa6,4aafa549,c5c97c42,e74f4991,55191cf3,3118f05e,19633eac,ff5ea8d0,7ec866a0,7fbbef29) +,S(42a0e864,1b594b98,90357e4e,8c32422a,19f368e8,190170bc,6d8abca0,9cf12f1a,bac7a5e5,baf7ddf4,934aaeb9,5078e0a9,c449de0a,cb932b13,a93f474f,52312d85) +,S(74c85e38,944e2003,435bf345,124656a,6a409bdf,fd1c16dd,d1246d45,cadcaaf7,bc18315d,caf237d5,5f3ffc65,41bf9ca9,f39af9f0,cdde6fab,f602e888,dc51bb7a) +,S(8ceda42,698e5995,40091f6d,f50388e2,7c229b0e,76e7def7,f8986b6c,af975e79,a8915f5e,7c524e55,5743c392,2b31c426,71fa938f,84679389,b3738af7,59e92430) +,S(f44e2dd3,ffe43da2,66fbaa1,990d1f19,e3e4e44f,bb565ec8,74af57d5,feeac498,c307b3c1,a90da318,bf928a1a,a8894080,29874639,ece7700d,4f4dddee,d005f6f3) +,S(7e30bb38,c9a603f9,d5fe78f7,453d1c81,30c140b2,1ad7706b,601d6b77,5c703984,49c9de1d,1d057fa6,b135ebdc,f0b5ad9c,f9f51cef,95a4cb7c,ebc11d4a,3bbb6d7) +,S(8e1e53c7,4f7e1595,b4a5f7b4,5b324f0e,435473b0,a61cdd8b,1607c0ef,d11e3c56,584781c3,ae8a8beb,f6cd1bb8,3938fb12,35994977,2d1facc4,240fa43,7bc241d2) +,S(63d0cd75,54bf2c18,bb180269,2d19b4a5,4acd77c,d2eccb7f,360dfd5d,4b9f22bf,ed79b7af,eee5ec82,e498ebeb,467380b6,1369802c,3dd995ae,c844d3d2,91ddd756) +,S(feef5d30,b382dd6d,a0ec0d81,b18ae45a,8dbe12c3,dd695648,cea27c14,7d075be4,20ba81b6,b48ebc6,b185d6bb,2fb7bea5,c6a011a1,24f49550,415eb8f3,cde3aec7) +,S(21bb575f,db07a152,5ff0a7a2,d7d2c189,742df276,9306bc7a,30c2c3df,f2125b94,8ea74299,b7b40a93,3db6afb6,6577ce64,dd10d24a,89bc3907,1f656f5a,71c56953) +,S(dee2dc59,44cad7f2,310afc94,403067fc,5c1c3d2a,dde88ae0,55ba8bec,d6e5cb08,606542e4,5301a6ac,86c5c794,444006d,d77e2bda,11c8af0,6d883689,7a6b6dd7) +,S(4768a2e4,98ca0472,67cef4b4,18e6398c,81289c73,e617a2e8,ca021155,edc576d8,f8c574bf,beea93d7,1a2a331b,cee494f3,75c1bc3b,ea918106,9f1665fd,589dbc3a) +,S(53d75697,160c2b90,aaea7f95,ad24bd66,b5fd7681,f2802bef,d2a71080,74f66b40,4b04d94b,416a8098,144dccab,bcd8742b,13e85b2e,ec8817c7,7b7e5821,2e8b56c0) +,S(832f268d,ad5f3bb2,dafef9dc,f94bacec,b369d4a1,ffbdfdae,bd4fcd9d,77404e99,a6495805,c9b439b3,26e32f78,8b06765e,8d984a37,86ccb4e3,88b36bfc,c9cc582b) +,S(657acf28,15b8cc12,83265bcc,9c826be2,c6d5329b,351fee50,2ed96f4f,bb1a6333,171a0a97,b2809b24,a89b337a,cbeab96e,7d1d850d,dc577a10,ef3c757a,9c2da9fe) +,S(7e3d0a00,a3378c89,741184cf,36e41bb8,758fd131,eccd970,638f60d9,31b8348b,6f2cc777,31f94565,2a3b4c42,29be627e,bb70d5c1,67648d16,df5470f8,90512517) +,S(649a30aa,4fac6630,c7bab764,19f9a34c,6676f17c,2458fb1d,ac48317a,734242cc,fb3f07e2,5737d6b1,a28b074b,880db818,c9623c12,80268b02,dad90da1,c8d246d6) +,S(6b65264f,537fa580,9d21588,fd86b246,4d1818e1,ec7fc43b,94af9211,c835c986,537365ae,4e61460d,c2c1caf0,62ac870c,9536d8b9,436a0ef0,dee6a39e,2bf25611) +,S(dc1a5599,d5cba6b0,2d692eac,304b642b,db32afe2,59e2e8fc,3bdc8f40,72c66c51,bd18d5f8,f99c6070,b7bc06af,568e28b9,2b39dc31,ad49a842,4bff4a55,d11ff42e) +,S(726d39f4,86401794,9e7a5498,8e8fbb53,b8b13ec1,cd5fa3c2,88f0d933,894e193d,f23e9fc5,68c9e0cc,b258dba2,58b3dd65,7aca0dd4,d9cb7bf,274e62d4,f65543aa) +,S(78d76006,857c2f36,889c14ee,90a8f993,79c1e0f3,5344cafd,592c961f,75aa8ee5,76dfacfc,994f3985,70d98c75,4f5e6d00,ae3ed428,49cb75d1,580e81f6,3d7427c5) +,S(d69c3e30,88874c19,71bf077c,89247826,b464d3d5,292196f,88ef0ad6,892375a9,cc7b98de,86017934,c472bc7b,e56f14c8,7494cf5,6f2791a5,d3132c07,26315cf5) +,S(9b4022c,907c4aa6,87631f88,8d47bde4,faeab1c9,23e125f9,280dcf86,7920ae84,c7468b6a,a7b4db67,a9b4a23e,11fff527,19e454ee,65ed88eb,3b89e231,e504c284) +,S(e638a253,84e985a3,5dca200a,5e3786de,52617824,7ed0c9f7,9c9d598b,8bcf8447,69211bb0,be8fcd6f,cdb0ebdd,a8782be8,a47d8852,7bb74b3c,d98c41d5,6aae614c) +,S(e46758ab,e2838a28,42baafad,12376137,7cf72960,d6a93105,3270330a,203134b4,2c7ca1c4,73d0c3a5,8f5ca754,6604ac75,8c460c82,64f5ab4c,832893c3,fcbfc7c) +,S(c8c8083c,3bd1b84,9b9402bb,9472263e,37e7d2bc,53a77b4c,b0ae9b3d,bc70342a,9085d285,6ebd4446,127ab4c2,fe7e5c84,d5c5c114,8ee76a1c,da72933,9ca6578d) +,S(cf21f3d5,75f194a9,3133a382,514ca64a,f998b099,eb307655,46e2959,f71f838f,657df357,aa09b443,c4763432,45d3eae,4fedfd1f,7fa86896,2ffc5174,d61fc4ba) +,S(684aa68,d4aabda9,65adbb29,1056db00,1c41b900,e11770c,c77c687d,ebcd702f,c6f0c4bd,f6f6193b,928d81b2,812c4303,7e6b90eb,598a50b0,742dd21,8d82bf3f) +,S(b9a4ef5c,acf4a82,77b81803,6bcf2672,945ec080,e16e8c3b,19f7b612,c408c884,1cca67ba,9e98e737,b4a55145,7f254d4f,5d793d4e,22b81b35,f4ab48d0,92b9c745) +,S(ff439f87,d4784ca7,490da489,e2757106,e59836ba,f3fe2e4d,f6700c08,cdb2327e,98f21471,84659fa9,a9cdb709,f894236f,18ecdac9,f5834dfb,b91a7bf5,8edb7461) +,S(e1750c62,9c35027a,c1a5f1aa,c9fb4076,badfd925,f5915b11,a267672b,15945ed8,e17610ce,a0b8d837,d1038d7d,9300edfb,5832fa84,c4e630f5,2b01ac64,a79c0e17) +,S(2b7057dc,1c59ed7c,e64f187b,86adbbb7,1d228e5d,eea347c,75c73d2d,a73b3a28,1b136a49,713b433f,f2c79de6,77b5a322,8003e614,2b845470,5ce884ba,329e20a1) +,S(711c07c9,ae61ac68,f1041b58,c0f2ed07,1106c2b1,bc47e104,527d540f,53690434,e9199a45,2f5a3a39,9506473f,be6bb46a,3105aa70,2c517051,7b4c810a,5a194c09) +,S(54dc7650,68c38627,4619d9a1,faadc0d8,c2ad8296,dd0d00a5,f2e53c5e,1a1a0d4b,2e9b7179,3af2f752,c111fd71,c00f4bd0,8fa646a0,428b4813,885d4e4b,ab7e3fd9) +,S(9c5aecba,3f8b3507,db7cc231,c2c1674c,3c3e27be,84757fc,4f1521f9,c3d9323c,413455e1,9e157ddd,17f51c1e,618dd726,d300c023,f0a0d24b,518c93e3,f2954630) +,S(c22c2972,5f67e23,a369342d,9a4e1f6d,dc1bf6f5,88d63086,fb54718c,f5183a,a26ca30b,d97ad611,4ea4ece4,cfdd3928,23c02838,9723d53f,32c3b38,320eb707) +,S(8f87ac94,a29dd2c9,d37aa130,f8b4e67b,da595ca,a22803d1,e2d8cd4,eba4f2a9,551fab10,16227763,6d7ad2c,bb055439,21743078,e02fe0e1,b7dffd6,8749b04) +,S(bc486976,76c0f638,a116bcce,d7ee781b,876ef486,111fd680,4dedb176,8125dbd8,16d7c6d0,19708ccb,510ddcd8,698c2fdd,bc6978b8,7b0639d7,a1c8ec6e,ee3ea383) +,S(5a6ec844,201d9b39,92a46fe5,ad4f05db,6e8cf251,24ecae84,3a28da7d,46e75ae8,9e1538ef,f27344ae,8f9c1049,c12b49d0,2d5341fe,33652a8a,9f2eb512,c74ef224) +,S(dd6b2c56,b13f0ab5,4e0a75ec,526219e1,4d43ad78,7deae379,1dfb387c,541f4d6f,7379c5ff,1b793b97,c8acba99,97a3c079,f1c147a0,f63a2ec1,a0a771fb,fc3d432b) +,S(74e27534,4d7d8cab,e4995d08,6d61d27e,942e2514,3c6e3040,8402a5ff,12a63ebb,7b5914d7,fefb7b3d,2fdeb49,359878b8,355eecef,65ac589b,dd31ccb4,c270d854) +,S(bea186e4,b5e3663a,fb00230e,d8ac1660,67b022b9,b69b6e75,aaecb88d,d750d34d,35807d83,5b75e3ae,670bf35c,d415d37,6fbc86e7,4f99afbd,c60a0b46,9153a0d7) +,S(17ef6838,a07f65f7,cc094d4f,77743c6b,fde12ae3,b81625c,23826228,650f30f0,9d696a8e,a5356fa2,10626ce2,cf312fb7,198b0937,493c9dde,4711dba1,333eba5c) +,S(b3e1bfcb,38c89fac,af3baf39,80b21e47,d6465473,c9d6a29c,8a08cb18,141bcb7,aa33ab83,2a9d4eaf,2a50f9f8,ba55d0b,c5e3b120,69a8330c,23120928,5f6b90) +,S(689d499d,c754f099,83372631,2f307f0d,807f4f6,d67df40a,318aadd5,5776202a,dd4f9012,8a19dfbd,8f5f96ed,df2c7d79,d451f84f,fa63b1a5,9845f84b,759377eb) +,S(4bfb2e58,9df27505,91a73a4c,6ce88397,a2f68f6e,8f866e1f,d3af9df1,f3c96bb4,a9d94c07,29948553,6433f0ec,b4618d1d,af309c6b,73fa4749,aa949e6f,bdc24b7e) +,S(97a3004f,26461f5f,b6cbbca3,13eecbe7,5026d958,a1804c34,6e661722,c67f91d,8b8e9bfd,b9b704d5,13bb5a50,a725bae2,c7ceb6a1,ffcf8c49,8e87c6ff,e47844f9) +,S(a07a76e2,48f87384,48e607ee,7f30aed1,db657b9f,b159ac9a,3d38e8ad,61050c28,7d7749b7,aa6dcd68,931c3c0d,87eb73d9,6bd5f43a,b633e7b8,f77406a9,23fdd47f) +,S(9bcff8ce,3a280998,fe077cb7,a6e4854c,4c834e21,af118937,9a133986,320b8e25,da3214eb,5cfea248,f1f8a1c1,e8b0dfcd,4171b2fa,5e133854,84a6c99b,215c9ca1) +,S(8f1d2dd,bab8242e,fad20574,c0f28976,d2e98df7,5e144d27,e558b9c9,8d75a036,8bd117cb,294db5d6,a39097e9,8976c701,1042af41,680637d1,c8a1d56d,30800bab) +,S(73910449,2a44d0fa,d27b97b8,df75ca46,caefe44c,741848f5,36b78986,8d966991,d31b7807,e1db48a3,380608e6,5f865cf4,445c47f6,c6094819,da2450e4,6b78168b) +,S(e024cfa9,4fdae1e1,2895590f,222b167d,8a41a87b,b1a6b720,61ccac0c,4caf9dc3,d62f1129,cd84f36f,bd1b9439,6f5ce037,fbdafe41,fbebd066,110549fd,50b0ba05) +,S(a378ab39,e3dce826,6805bcec,b8123eb3,ffada53d,883c752e,e46ce4f8,5bf093fc,db9d124e,4c0a8d1f,14cfc406,4498a7a6,513261f3,300ebe0,99a41f0e,701c7dd3) +,S(bea5d211,b808e4bc,5aaa1a96,a9b8842b,5204b60e,24d5e518,4b4e92aa,12d8968f,caf8b92f,87c4b8fc,4692efb,889ccd64,610fd604,b9669dca,e033ae9a,453bbca9) +,S(7ec06291,40b6bfd4,cc4bd45a,8a953fc2,653d73c5,d366b5e8,b732dd8d,5d30428,e96c9515,da8dfae3,a2f4e01f,f02ebad9,8499a318,8905c0f0,fcbcbb58,87360a08) +,S(9f9698a7,6ccc8bc5,31dcd9a5,b21f3f8c,9d143194,8902312c,b5ab89cf,554c3b26,e08acb08,2ab0eb8f,fc31f7a3,1ca8dfbc,d4b1863e,29d155f,4abb8d54,6c59a221) +,S(ad955b37,a45f2bfa,1779e8c8,e6786af0,dc49dc9d,d692281c,da10b25d,7517214f,b2048fe,ee71c152,8c8f5dbb,cedde340,284af2c7,71ee86e1,8d565285,5de918ef) +,S(e7e56815,9412123b,7737b006,f48b3f32,513023a0,70c595af,1749c564,8222e21d,3ff11313,c2992218,cb3a1c01,e333f2fc,ffdd05a0,c381f8e2,24de6add,85aad0b0) +,S(4afab50b,55c2a433,488adadc,ca5d11,2e225f81,9ab817bb,116109ce,71dd3439,d232e25a,e5a8f6d5,68344997,442bdc54,de9cc597,cc474555,5f64cbfb,6252808d) +,S(2f739ca4,6559727c,cc2fdfa7,c66da19,b7d2660f,cc63b74,155057be,d55313bb,c39350a6,10a844f,80730a2f,27bbee8b,a06d7ae4,a279f490,f975111f,eada018b) +,S(f3596671,79f9343b,bc3238e7,bab4686b,5b7aaadc,95848f20,52adfc33,d15a990e,8b5759c8,e0bfb8ff,e298e824,ef18c042,65d7f886,1af8252f,8c9d9d92,c1822849) +,S(b3feced5,8d79e1c4,d0a210dc,de416353,404f533f,5a1295bd,4d888d59,b43725c3,b07089f0,871f7c3e,440ea905,cebf66de,52c68c04,a6aae237,e23c3272,26d99826) +,S(85c74622,bb28186b,5f1bffc9,74d51ea1,8bd7e6f9,1a02285d,6d8818df,b87d2f9c,8eb95100,63263c67,976fda8a,18910459,df0755b9,307e4145,cfdd18,15b799ff) +,S(3823d01,5b240e83,44c936a,c9a5f7f0,fbbe3059,1c20f39c,ca51be63,98ea7a7d,6e6539ac,8f404753,dda08dbe,f7ad4e48,69a67a93,f0efd0b7,b53c14be,130435fb) +,S(b73ae7aa,e97af1d1,b6ae34b5,f6188c62,33ac811e,1ce5818a,a9f20703,7deaa539,cf495bd7,2df163b1,f6908b7,23042bf1,137a325f,bb8ebd78,c0d12086,e7b76005) +,S(f6724463,faac9880,41dc4918,5e27b97e,889e74a1,81f35b58,2601328b,143688a2,a290e04a,f10a477c,7c0269ff,42285277,f1faced9,eff88272,45f2d069,58897554) +,S(9eff8038,1d546c1e,e1b5d562,947f3a98,427e17f4,84d0007f,eebd71c8,261ff959,bca422aa,d4748c66,6aa99f76,eb8e75b8,55f89b0,917ec29f,401caf83,cec111c9) +,S(93384df7,33d0fece,931587d3,410f2520,6bbbd992,5e6fce75,5432252d,8bc1bcc5,9e3beba1,b9a92647,c630cb4a,69b9bbf,80e301be,fb8eeafb,fa0021c3,ae27c38c) +,S(ca85653f,975882c3,71902d14,6f50b3ec,1dfe1fa4,b6e6d5a9,e5068685,632074bf,a64fdea1,66808f60,736f7d84,850f841f,588879e9,5d1adcf8,ccbdc4bf,4f743bba) +,S(b80a52f6,951aa063,1094a2e2,866d3a29,b95cf239,48753ea5,cf5c6f6e,8e082f90,61c95d57,d6fc3ca7,5f92771,61ca211,1f20a67,9a85f4f,2b8b0fbd,494d55dd) +,S(3d5d3037,3a97dd67,fe45b273,2ce21e19,b29587dd,301f3dd9,b411432,e642a3c8,5c8e3a19,896ef1a5,5cf1ad28,41e47dd6,1f207f22,3388c6aa,23d011d8,fd95929a) +,S(b274f8ca,29a87fe2,8a3a1269,ddc35b5b,44f9e4d9,81af118a,187a7c36,acb155c8,410d9c55,bc34c21a,6368155b,c282e449,c5317dd1,c4e5758e,27493fa0,4f028ea8) +,S(f1557792,8cac518,66f59814,a70c14f7,beeaefa5,33d3b535,df19d31b,ce1cacf8,113dbebd,9fef9cfb,93b5606a,e4b48aca,5b7e9c00,a59832e9,6865282b,80b70ecb) +,S(fbe3f262,18fcb657,7fe56753,42765926,59ff099e,f36252f4,cb5af101,622c40e6,4c872d52,f1202df3,e905a0d,3f9c89f,b347723c,99b1b273,8f3dbb83,df0fa2ff) +,S(ef7d13fa,25ef46c5,3663eddb,a677f6e3,b24c7e7c,6895e731,2c6993da,3d9384a2,cda2cc35,114e06d2,1f6f896,666c16db,78fef74d,2ee46fb6,a4a34e09,8546935f) +,S(8e34b93e,afb7f027,cdf8696f,a6407213,91860119,cae17b66,d4f16175,fd7118cc,3198f5fa,27ee190a,e56813e,910d917e,3bb8c850,20b0376e,e55e88ea,eb56397b) +,S(a8291a3b,8e544240,a0f0dcaf,6369b2cd,98ab80bb,4dcbc2fe,e023cea,1fa52399,f8305f7a,b1993569,82b8f2a0,1fa0e808,46a506ef,5cf0ccf4,fcba9211,284e15a8) +,S(bd36854f,90dcd6ac,978c2545,7800489,35c4cca,79a0f9b6,bf461da6,5522c88e,631a3d75,7c05e2cf,4a445b22,73cf663a,332610a,8461dff3,846503fa,12e65ae2) +,S(fad86e9a,ae78aaf2,e55e93f4,b8ee049c,73b86524,e942ab93,f05f9dfe,8b783116,657988b7,20822c63,dadaef15,a5cb3d49,be52946d,53b62ed7,1814ef3,b5aa4b7c) +,S(e1235938,db5e1f30,fa0b4d4e,a9e1925c,6308917c,23efde51,47fb818d,a39bcb2,7641244a,7384acbc,3133fd6e,9ed61af4,40e3b951,751f9d0c,384328f8,b87bb2bb) +,S(40ec62d9,7c9bf05a,cd4bd50c,137cb143,8e3331ac,554098a,57b6a92,afb137da,8b1468fa,f334dcfd,5a43d405,aacd3f31,7e868af2,73498367,4d0e5a06,67186a8e) +,S(f6f5c9e1,c7d94d25,9abe1a8d,745dabfe,59e911cb,c917fefc,e2da2a63,cacb26a0,7f2454a8,550b385e,f49c26fe,bac89a9f,33bd6c9c,2eb05c98,4303a16,6b21ca51) +,S(be4dd8db,c703a834,9e24773a,acefd0d5,70dd2ec,ef07bc70,ea8156bf,d5b516ab,46a7dc2,5d56052e,dc64a0d1,b414da49,dbb218d8,5abe14e5,c753eaa3,84b958ee) +,S(273f227d,448ee218,1e43f2a9,89d5942,54eae85e,54fe9f76,fb67ce81,169e1be1,67cf461a,a6c7ac60,1ccdd925,b4b38e84,1998cbec,cabf9441,29575438,a855f35f) +,S(94ca507b,96c063b5,bfa9d74a,c92e656e,db186570,9a017ce0,e5270bfc,8a8c4a31,98daf409,49c48c6b,8c674361,17aeb669,36c76169,8d39eda8,9922490b,4fa6a25d) +,S(91d6f747,c1c7e012,440cf7c1,34ba64f8,9ef67b54,3a57196b,d2bd6ae8,f5ef4356,e2117eb0,4d4d29cb,5b13f628,f69e5eaf,2befc095,2fa361fd,f757430a,168c19d6) +,S(8e2c4d62,c17835b0,97ba07b,37947515,e710e825,15bc614,75a66ed2,ac4cfb84,7b7f7e56,22bbca12,2863c230,5271ad25,b5e4195f,cb96e5a5,ca2be6d5,273d6532) +,S(55738482,d32c4248,1bb0d1a0,666adab3,8bd2441b,9436b690,77925e15,2d8c948f,93a6705b,ba5e5b36,e73fe83e,e0ea81b,3de393c9,1c209e89,af90c539,9af5ea2d) +,S(7faa0f45,45fa7d68,918396f6,19beb941,43d93f86,c5a26539,5016d386,b3e85086,cde251a8,3de1f2c7,11b884b5,33226baf,cac36791,1ff30e19,25f499ef,27da9c06) +,S(61a766a7,7bf6f8f3,a07ed7c6,6648606c,69134c6f,4ab4931,9033f9a5,e8b7d191,7dfa24d7,6bba181d,7bd77606,c73b1635,46f41751,c05c34dc,ec54773b,4abea4a) +,S(64317c72,4f1207dd,a6009736,6fd2d189,8b702e71,8cf84fcc,7c50427d,7eee171,d1d45f23,b1c5fda9,ee05652,dd30f898,c75923d8,293d6eb4,18a0e892,ae400895) +,S(4c328f82,5923e7c8,9cdba421,92ad7a37,5a328323,71242c4a,e108c771,fc47356,322421bd,92c5142c,efe89e59,4689a7a2,e8e5507e,be8b505f,9dc9ac86,9d90ae6) +,S(360aa32,797804f1,649c44aa,b38fa9a3,5d011301,708ac7cd,a4135c13,d86a6758,ce4b0fb6,6957f5a9,7e4ef923,ebfbd850,4f6d4098,5333db66,1152f1c,ac6eef59) +,S(5b110b6b,d9ec8ab6,635f5016,bc597f31,ec22f7ce,cfeedd2a,1e6f883f,64d2379e,9472fb70,87ab6f91,2b10c6ff,995af03c,5086c034,f0f69860,ead562a6,e409c8b2) +,S(be27b39b,5a657cf2,9ebb1b16,45f5e1d6,bb6e32bf,e3a52b08,a916e091,9affa38c,93fbf27b,5d03ae3f,471ad91b,69e74fd5,a8f2f925,2bd16473,62c4feac,d26d1dbe) +,S(8ec65d75,c599fe6a,bddf3cf4,6ddcb4d6,1e9b5324,f5e7b7be,5407cb5e,28a9df4f,3d52541d,49ce4b07,7b543747,3a219db8,29680777,3cdcbf80,e4b47786,14ca082) +,S(6edaa1b9,ea8c2c45,6c6a34c6,13ad60ed,aed18a04,32e96030,ac7305e3,2dbbf94c,c64c8279,40cbabbf,fcdd4db5,1719c53e,f8cdb650,67af48cf,fd731618,bd304b7f) +,S(3fb5f6f6,60847e2d,e04341e0,26c4102,68d5a1fe,880602de,c07be98c,22640a29,ddd43c38,95e663fa,5aee3227,4a16f532,df3a180f,e0813ba,3ba113d6,f6fbd9cb) +,S(2d740009,d7addda8,a802b263,35d41284,b3b9a119,248a3b,29b4a532,654e84c2,cbe1e2d8,1bffb79a,6f9292f,43ccbbad,e763a56d,6d68cde3,d946f310,dba8f28b) +,S(15bf4abc,1d74793f,6ebf2fe4,aa74e34d,b359ad76,3d5624d8,19c24386,33517436,5efdcb90,259b5dca,39054a98,b6702fb0,f2fd4b61,235ed4c6,cd1f3dc,dab15f12) +,S(feabbebf,3c6ee0ab,9b584162,476c8e9b,f7523c30,7874d7cc,c4a6b88c,b118d423,c51d328d,276502fa,f79168f7,3787d3ac,b4e7bb7e,1f65b421,64ad6e93,2d405460) +,S(e3664247,929c3455,e98de868,60010f47,4258c686,4d4a7c0e,4bec28d1,b9af3188,7cb4bd55,ba579fd4,a3066f83,710a3606,2fab9f87,34311609,902407a5,88454bc7) +,S(d570f391,365aa2ee,29b6db92,2a96e4db,f1820a6b,94fbb8b4,aec45ae2,f97a21af,c0841986,2b0adbae,1cb192e7,bf80dba1,830520e2,35e1e42,569a31cd,fc0c1543) +,S(9cfce5e3,5119ca91,38629b08,c75b77f0,db3cb593,b2bf8dbc,b7d6fe3c,d1eba55c,33891655,226885b4,cd74d8ce,f29e978f,60a71bea,be99a2c1,d2071f53,239e4f12) +,S(186ecba5,f9998439,f6a3dca1,a179608d,a15adf9f,f4d2f386,4268ec3e,e62e4407,ec7eaeb9,bec50709,e8dd761f,6253248b,2fd064a9,638953bf,510a38ae,c7c6d24) +,S(ad52f2f6,fe0b72ed,2a0fe483,3745aebf,acfae58b,b40a0291,21767058,3e0f6b83,b0cae754,85e3038e,c6dc8d,b4e95a54,63e3e6f2,1b99d991,2f521663,3eea0c71) +,S(aa06c0be,7d72350e,6b094df,f4dec4c1,993588f8,5bd82a1c,158f92cd,eaa7804,ed628163,29369fde,f0fac2f1,a533fcb2,a704637d,6dfaa1f4,a3b57f74,4efbeed0) +,S(5f7a102c,4bdf0a06,76e1bd4a,4df17a3f,124bfee6,312b3972,c49fc4a7,14b3e867,85f153db,ab40a9e6,747aef3b,cd30f59b,fc9776c3,93293222,8f534d59,9efb30e3) +,S(31a4309a,64c225e,69567574,e05bb994,3fe01679,6f09a0d9,358b1237,96cd3fe0,9b9862a2,916ad0f4,1e588567,5a1e357d,19ec82c5,b31f967d,af058e1f,da7cab16) +,S(8906bd2a,505e8401,cc89e32,b9362c84,3443b4f,bafb7c03,75bc883b,11c3e59c,ca78e1d0,1c6fca33,b39d690f,5b85c764,ee15dbfc,48fa78dc,5f7d7cc4,5323d187) +,S(41cc93ec,a27c4fc4,19fc1c8e,4568744e,dab8917d,d8936cd3,2723737e,e36b4f9d,c11d8299,bdb95efb,842ba828,a6d89120,1fc6a28a,9f208430,c1e2f748,bce6b7ae) +,S(6e1b0bc6,199c3b84,220020e1,1a698e74,2fa97a58,c498254c,d3af1e8b,23ef34ed,25e0ed2,3f04706,6b4134fa,b6252276,b2205bd0,7a8ba64c,636e0b0e,1d6d0217) +,S(b55741a5,7b9c7270,dd1e5115,995ecc55,8729832d,9f4e373a,6824d9a2,83490eb5,9adffc91,52eca815,465e533e,c82bab6,ec6b37a0,dbb3b6f8,c3bce25f,6e3d944b) +,S(fde1167e,67f0e084,251d50fb,bafb538c,9c375e4c,fd6441bc,59a46104,46ff090f,662451a2,444d39f9,58593a02,e9a94ec1,4a1b8d87,9dc80c5a,73bb68fb,67af754) +,S(bbc374da,188df5c6,5a633621,804d22e6,f7474faa,47a8af94,a1cb78fa,aee68040,c2c74abd,17acf272,6c03bbfe,7dbe06ce,eb1f4e0a,b0001aef,4d8f342c,aef50186) +,S(bde6680d,414ce86,548504d5,55c83b18,c9f94e45,f55b6683,166cc81f,583e0eb,2b1ce8a2,6b5bbd8e,a087eaa6,49f49a48,2891abda,87c2037b,a73409a2,69b5e2e8) +,S(8f9ba006,faf50323,b9637f00,9aa29cb,8e402219,75d329ce,15796428,6c84e5d3,1bb33199,e5c30e98,5f5eaa1d,65879a3c,703b7a50,cb04c7ec,a6c7512c,94180e16) +,S(19f03bc4,3b61d7a8,62bb81e0,f4b84c02,7359a170,de0108f0,e9b9e9d3,95b63481,8239d21c,f31ae885,ae10c62b,8be0ee1a,95db0368,cf0488c9,4a110a76,7d22dd73) +,S(667c2647,2261828f,2653a0eb,e70de204,29231fd8,132961dd,ba3e4853,8e332941,5758f0ef,4362f75b,c4356b3f,cd8cb2fc,3c77cb25,b7d65c8f,ef7b4096,e0d879e5) +,S(86558922,618551b5,c4c66c50,9b81a622,ca376318,7c558ca1,8a00a00d,cf100ca8,32cd16ef,955deafe,e3fedb4e,55fd2071,8e35c1e3,736dba12,9f3c3287,4413739b) +,S(255bfbc3,d0b0d6e,385905b4,af6ee2a0,18109db9,73788509,2d5fb275,f1b47b45,b1b1078c,afe453b9,a35fbc30,c5f605b8,4a1f61a3,1104b406,ab5014db,57e2b167) +,S(acdae8d2,eeab48c1,9507f575,6ba60b0c,e9d5b6be,e2ac15ba,d31e8932,fe89e14e,b077540,ab137999,7e7dfb3f,5e3fff46,10c2a369,2306ac0a,418d5026,caee0466) +,S(162b0c77,da3bc13,a62753f2,b7b19c9f,3fe864ca,66fa2dc4,226c5cd8,ca8d7112,377956e8,59c2f465,2af5159,bdfc86c,df0bd742,ec7f9eca,6e675b47,d6eda222) +,S(9453c9ef,afb6a23e,40ebf013,eb1af363,c28a6e14,d235c7eb,58d3d142,9d1b498b,65e3b737,ede3c00b,5f322b38,9b09a68c,2ff44f30,c7737932,4e9c94c9,bdd78961) +,S(8409ed29,38a5bec8,669e24db,88c1b6fb,b397ba64,d8a1826a,f011e2e8,32e85506,573a0053,1be979e,1ae3f2bc,3d28ce2b,7a3ec55a,bd00242e,73523a2,582500dd) +,S(3b55d457,b1878898,9c486cf5,3d1ef107,4161330c,64fc2250,81096148,f5ea2c45,24780fa0,3e83919b,9e3491a3,7e0b76d0,f5d32f2f,a4c3aaf0,d2e7c955,43476fc6) +,S(d3fa2c21,f4704812,a5b582f,9096fc87,422af325,5c5d006c,63e1e9ff,d2d9ebb6,a6aea607,9ed334eb,9355fbff,27650096,ab19a007,191d57b9,4a8fc12b,a59bbab9) +,S(a938a4a9,9dc45307,29f3bac7,4fcd7241,1e56cff6,f53fb048,c727087a,9a54b374,3949a589,388ef8cf,aee8fe82,fde39e01,41ad91c5,2beaea97,e7494659,1a27bebd) +,S(792220fa,aaf49862,479a6de2,35be75f7,e811d12,7420571f,e46213a3,e77aa93b,5f274791,31fc7585,8b82b021,52057cc4,f1686543,3eb6e22a,de56bea5,8823131e) +,S(b1bcdf1d,57699459,1bc11d27,cb15d84e,75eb3d5b,2f9b4bd6,1c848c14,e9b7f2d1,a2115735,8c35ac77,e116a0c7,77917e62,e1d09897,316e2389,41d8e170,90adeb50) +,S(735b746f,6f0d453a,c45cf288,6941cf13,c63899e1,a41ff3b4,cc1a4c74,a9b2ab33,e4c2b67a,c6bd7917,2478b52a,994dccd4,475cb24a,ed1eb77d,a39fbcda,9c02771f) +,S(1640d0cd,ba4b4fc2,f3670b35,2485027e,2724ea4f,df918b72,3807870a,39fbcb2e,a0a71f4b,ba481eab,999dfc3c,15275eb6,b06d129,48000828,be4754b2,749bae30) +,S(bff651f6,df72e476,a097231e,b496618f,6e7d621d,dfd45356,8b08c718,e138caa7,10dbc188,2d0a17fa,d769f855,bffe1a81,14183445,5d9ae144,e6eddb52,8e67f99d) +,S(1a3fa743,cf429f3b,49e122c4,5c6d6e8d,18c633b3,f9903c9a,207f0405,c2716b69,b1b2c87e,65faf1fd,debc377a,bd9648cc,24abeb81,75efa4cb,5f0a0b06,aa2f1e28) +,S(bc2a9ae8,e2940908,ef5420f0,9ef4c2b2,ae988e5c,c0c0efbf,62f8ea05,b305ff21,ede884fe,6b48627c,84c96869,5944be60,df3ed5c6,66f16b56,188a9e1d,6bb14e80) +,S(8cee080c,e9204a62,502ae88a,15965abc,b2a8f18c,80f6c461,24b073f7,63990ec,3adc08be,7bea0bc2,b2c5ca91,963f4c40,bdfdaaea,318fe3c7,866229e7,e53c8fb5) +,S(2fc784eb,f79f916f,7f57dfc5,8fc62e8d,bcdc7dc6,70d6a444,c13f397d,ed528e2c,56c58a3c,be510393,90a88028,12d03658,20141c,b1b24241,241dba91,74d6eb37) +,S(fcd83e1c,ec7a6db9,1aef0894,cfb2e1e0,d2b48fe4,88bcd28d,c14e7824,6e62aa35,a86c9321,e2dd113b,cb7ec78a,d9d4db68,b5ddbc01,70aa0f67,5586b08d,6694a853) +,S(4e4fc5b9,65584dc3,40cec4ed,87ab0610,d674e1c0,9d76d28f,e28888df,7f9be562,d2344fc3,de7e5372,ebd87d0c,ea5431d3,2364249c,f6c350b6,d7aa2353,26e9ac7c) +,S(8df04fe6,e93afc18,b0508831,320caa9d,b21fb740,46bcc364,aa80564f,6f89270e,d7b37dd,2463e50c,583dde08,ca253215,4d52bd8e,a4252c55,6749641b,71ee7214) +,S(f662c961,3102fc4f,afd27352,cc697de0,1f4a1406,f99a0656,6597b96e,cbc99305,43783b26,759a2eb7,8ba4a3cd,e865d1f6,474b1ae,26eeaa2a,15220353,f6bce384) +,S(2052f92,b66998ca,f172ce,15cde941,484c5ee3,d3ae329c,87f339df,ae944439,3e9ef8c,9f4257d,c563509,6df8efa8,ffd2312f,60684baf,bb9e5d,9cbd04ff) +,S(730aa6c8,9c8abb08,855bc551,1938bc46,bad8f226,4b162386,9f2e1ef7,c2d6702c,7523fb97,799e2bb2,f13ba1d,59510bec,ee682f98,f865aefa,cf3c6578,bf46ff81) +,S(c5773c0,7d65fcb9,7cefd396,b07dfa58,1ab237a6,be3c1739,e6db944b,c7991c59,6afea6af,44ea94f3,ee67d071,4b6654a2,b1b335cb,e914d305,1a60b05d,44cb81dc) +,S(3ef9a63a,5bdce751,48d7c585,5e3e9aec,90d34ca5,1a3b4829,979d67be,c38c83f9,145e65ae,635acb42,e7949060,fe44f350,3535d417,f3ce9e42,4c3b3d0f,b02f2c73) +,S(a1632263,42b900e5,887b1800,196c5be5,11065746,52cb88c1,4011aae4,6d14bdc8,beda5e2c,40b55506,31aae0d3,fd9997c5,3f37169a,2d810b5b,402210c7,7c372cdc) +,S(8c1f5646,65449ca1,f16015a,a876bdb4,4d965993,7ca6936d,5bbb80cd,c2da6d65,7cbacf98,f6f7363,8940358b,60beec4d,1cd1a1d,900f84bb,9db5f784,d4565034) +,S(693ab562,230c1ddd,3493c64c,6f7e2bb3,a74cc535,2b7efc30,630904,e700d5a6,db890cb6,d09d5be7,ddaeec01,299880a1,2e68acdb,dd950118,3c8f5f07,739cf4e7) +,S(d761653f,f7979336,f833ca51,b91b9e90,b2bc04f,7b7407eb,be3c8462,95d59df2,f81a5d74,446e9762,2391368a,ed154b2f,4faefa60,af93d727,8357fd6d,98537c5f) +,S(41de1c8c,a1315711,3435ce37,c2d2efef,24a67cae,59347d23,44bebf0f,a2cecc64,77629b7f,46cf1d57,a03898fb,cc9f4e37,937daac8,12c4df74,846d8c89,60095559) +,S(21f89207,4e3a00c9,39862265,c1762dd3,2662d182,397c1127,4ef144b7,f598b650,e6e30e11,566dce23,b7a6a06a,11e12bcc,978a6b7a,fa9297b,8c978f56,40f8b4f1) +,S(6163f61c,628b4800,dc49f30d,dff19310,369012a8,f31d4a25,27c790b4,c51f068,4e87a17a,12055cd0,4c4bc19,e052a219,7dc5847f,ec984f9c,aebb8f81,7a7065ec) +,S(a68ebde6,43ab3c15,72f5ab0f,85d683f2,6e6eaada,550e2425,f85596db,8e2dd200,487604ed,38a6387a,27e3cf1e,9d4865fe,7fc67e7c,ee26ab11,1f03e0a3,316de778) +,S(9b9fd342,4e065ff5,b82e0c4e,e5efa0b1,d0991087,684c46d5,7885adcf,b352d06c,b11a7a46,570eb251,6562ae87,90eeb403,823380c4,aae99329,de713677,5b5b5e0d) +,S(d80c347e,98db32bd,57ba5728,20c7322b,b295cc3a,ae326fd9,49e7557d,27151fc2,6d734eee,40229d19,465a0e2b,a011af39,62ff5c08,f83a2e17,e5c2783c,a430cb42) +,S(c8aba983,5f814895,e5d05139,7b23988c,7fefedd9,aed9dd20,a9bb0025,49e63ef9,3811b18d,8310a67,532be770,45461d82,e40c0ff5,6af355a7,55ed4708,f1ab0c7b) +,S(1bad15b0,a186d418,bb84a87d,d2fb9255,9aa64547,cf47a93f,73d23953,86b0e301,e432c50f,662da1ae,f7ee8f73,f5d7ac4b,4a4da6ee,5a943d17,7557e64b,5eeab1d2) +,S(720fcf05,dcbb0609,e5b45efa,e055811a,66d84384,16f7091d,7ea66186,922779e1,9045fb14,37d2086e,ae7d6a64,49effaae,17e3a559,571ab010,57f20fb5,80535906) +,S(96a540e7,8fb6647,63d3b129,8a1100b0,88a2c3e6,6da3ebe1,4b6c39cb,f01c4b2c,4debf0e5,c95b9a1,7bec7f14,12018197,88a1c325,12f60973,9d5b4909,f087b5c2) +,S(2f068148,d385bcd9,6fd6b60,b7e331b5,88419085,3942ed16,18b464c5,9c3ca99,596f3fb9,2fa7377f,a9ecc8e5,be8421cc,77339f62,c6f1572d,7a28266e,eb66ae52) +,S(466e9733,ef167fb7,233363de,16d9d510,74d8e5b6,35abaf38,20a037d4,f6b3e45c,73548e1b,d4d5b78b,821fb1d9,94919bac,a9d4e12e,13a2e8f2,d4c5df51,2553410e) +,S(f8a841c,a8c7fb3c,9a334f12,cfed9ddd,d1dbd4ac,764f3c6e,87a42818,a4a8e51d,57ebf669,72e9c4fc,7c435cc6,a85d381,6a969d02,ea85edc5,63c57187,34f0f926) +,S(d8c7d6e9,6719e74b,2eb7ae7,59d82ad2,6aa003ee,58e3d9df,ea97c7ae,6d6b887f,f1bec88e,5e8df038,b069692b,9e44245d,a11feed4,c89ff45f,17bbb6b7,1b0e43ca) +,S(afd5e13c,cabf51c,19c39c4c,815618a6,14a4f461,5fbaab69,624d366d,540ab638,9ced3d42,5c361706,16cdba99,653c00aa,e5212c5e,939c0bf0,3e5a1cb0,a05cba0a) +,S(fb491696,a4a1b9a1,572b462,f4628f66,b8368f3,3ce957d0,6ec29a0,92ce994e,b4fa2340,68741570,a56182bf,4f1c71eb,2c80d6a0,cffa42bf,a3e9d9da,59507de8) +,S(96e301b1,efd54091,80e3aa96,6652a253,78ce4bd3,cf587238,f0367a58,ec45b0a2,1bcdfe49,5ed90efe,7eb853f6,6fdc5b7,365ca2ae,e1d9b787,afd41b9f,c00f308c) +,S(9cde8d26,40d197a0,9ac00167,9b93092a,6eb8b13a,4d9fe2e5,6365a5f5,fc38d809,c86345d9,cf95fe50,40b2b2e6,2bf4267,72cdf10c,988a4f27,836d960d,c98501ef) +,S(d33ba473,10c37342,43e2219c,f3cf4881,2e843be3,c7492d01,80239bdd,20a829f2,ac774707,a5b0888e,b2ffa131,b71035d3,6af5be1d,3a3605b5,751b92c9,9e58a45a) +,S(6b364a32,1b5aecb3,749093e0,1b5229d6,5576e65e,1bea096c,29065a87,e26cf2aa,668ba97c,a01f659b,3687cef8,ac87dcd4,7a8a4f85,4a434f49,9592151c,b8f96152) +,S(d0009cbf,1d0d0673,5f66c16f,5cd4747b,d33b3347,fd7f096b,a026355e,917b5015,41c10a72,3e82bec0,b92e560d,3bf1e0d8,15a22e50,3afb4bf0,e5caf771,569a7dee) +,S(e618f641,a5b443d0,704102b5,40efb697,c470955a,8375e6b,a845c299,f377b701,9d615e53,edf6463,9b3b2d0,8684f8b6,15cf4122,33991a4b,5b7c85bb,f5698825) +,S(789c55f5,d393228c,7cc7920,9e705d29,867a6e9e,750d05da,9bc6dbdd,36c5c49f,8f38e43a,338058c9,39c64ff4,3f8f7bf0,2a7910bf,dc2f9af9,532049df,ca236de3) +,S(8fa4f0a8,1bacc20c,5d402478,23401597,bfbcc47b,973abe3d,71d33e2d,fee792f7,7dfac188,c5d6c17d,9e7430ed,d9038a6,e6fcf47,174347d8,7a68aa4e,cdc46c38) +,S(4d5f8d87,9377b056,afd4c8df,54a48673,c43fce03,d05be56a,56c42a23,356c34a2,b064c60f,a3b75513,577c171d,68acbef6,ac96f665,6a899d54,29e9427b,533b8e36) +,S(7a409ee0,8299930e,ddfc1e4a,db8475ca,9a99bf4f,a178a8b2,540ae448,ac87a3b1,5c4873af,c8a079cc,38a385c7,2ca039d4,4363425e,67de4cd4,15d09514,50f28e17) +,S(ac327275,44973221,dfb8b577,e33bd935,76407a86,77a1a842,bb04832f,68304e88,2b41b0de,3e406560,a57978e6,3359a911,6f993a91,9dd1c2ca,79c9a36a,6a4c8815) +,S(f9168fd3,973728c1,30dda9c6,907912d3,2e6cf9fb,b1c7a058,cc948f4e,44282720,c7005217,a6adf515,d8d3a87a,7e8a8b2e,aeb470db,c014824c,733e9a7b,17111677) +,S(818b9a9a,295d8f3b,bfb69d3a,f4749e5e,b0c1c04c,838ac3b2,9e74f6e5,dc73281a,141d14ab,64b3023c,597e96c9,3fdf393a,b53f45f4,56cd17a2,bd917af5,dca8daa5) +,S(90a416a9,dba0e05,bdd25dce,2dd0b0d9,200aef56,a6c0e16c,748e7d4c,99cac1c7,bc871391,95a2f128,af9c9c0d,56bff605,2fc27648,4e0a855d,6472f0e9,a779e0dc) +,S(678248e3,d48fd800,8e694890,b442d3f8,4f851881,9b152a6f,da24a6ea,88e1efb8,fa5d302b,51a36e66,98477693,9ba9c095,eb8b78c1,8f1bb114,53cb1904,a2185615) +,S(c2333e2e,742bb244,b7dac90a,18c2e65c,1dcb447b,11f8596c,bb3fcb8a,1e85195d,d15b8771,a31ff36d,b46b9ca1,b0ba345e,b877b7ec,48de20d4,71792a78,17ee826f) +,S(7d562291,9c72b694,d81bd71a,e78204af,995a63bf,3e8ecb3c,d9b3f589,c75ef8d8,aa554f52,67d9d3a5,8d35cf02,191b533d,ffdebf32,dde4cf07,252ef949,ec7df6bc) +,S(c5023f92,698f955e,4fcf7fda,288673ba,97b4d275,7f26f25a,c63ccfe9,155232b4,7d9dbce,def550c4,ee4c881f,69010859,c7a09ea5,36a8f7d7,17c1573d,c5db971f) +,S(37dc82b2,ed0e9533,e87867e8,d1eb57ed,707f335,b081d14d,d57aa247,645bb1d5,ff0c021a,d28649f2,3f000ae1,123f909f,1c803a9d,98ef2487,bf5d44bd,a97068dc) +,S(ceae1d30,2bf19dd3,a952ac79,8426244d,968b6ddf,25e16357,553f7636,a15ba8ed,c5a3a752,4d05206,39ecb8b,bf4282df,a1f9c795,ea74410a,ed9e064f,9a37c70) +,S(8bd49da5,fdb92648,f321bfc4,2d8145c5,20b8dea1,46b2bbf2,7a054698,3eb6574f,f769854c,5b5c9058,20ab0765,1a6d8104,e9a9dd1c,7aea6425,2b239ba9,7b0609f4) +,S(d1553a8,9a5226bb,3c5b6296,9f094b2c,1b761aaf,2605b0ba,b3793f6c,6959e8ee,d7b11159,d289d42b,8ca2889,f3dd7d01,e1cd0e5a,745b9f12,ab98b823,3211b2fc) +,S(ccf443ea,d8b17d4c,ec59ab81,74f1b1b4,8b6c3934,6e64a955,c617336e,aa6abc89,5cdbd39c,64510cdd,b342cce2,62915966,f8cef7cd,e10f4a7c,41a0d495,e5bdccd1) +,S(f95ad24e,7accb2b4,ce6afabf,6c1a40a0,172cf2b8,42871778,881ad94e,3f3d8d57,f3142d40,377543bb,6dee8195,743a6d73,e60dc5ef,4b0756eb,68d09d6e,326caf5b) +,S(464189d2,52726cd2,6f5ad4ca,5184503f,c546144a,ce7dfb32,5e4b4147,da7bcaba,910f8aae,acb04646,3c6a2a31,6174510d,8ae8bac9,fdce4c47,6c0dbd62,5196e2f9) +,S(637d373a,7355334e,70c78ae4,99429ce2,a5d97257,c0f407b8,1cb41704,d1b36415,469fa81,5dba5bd8,bb53a5fa,aff5b4c,18e7c28e,fbf21f52,14359d6c,7114c818) +,S(b489330e,2a4a4a6e,a99091aa,4e5aebaf,dcdba016,2bbc38df,5a49d4e4,7eee62b6,e1fed3d,93333ae9,2198b85e,fd68582a,35f6fb60,ff268494,720b387b,b3a7543e) +,S(8f2fbd92,70781f54,9d32ca01,2479438,2ec9cad6,2151c893,64c1cefb,c2324b12,2ae5c8a,2e018e74,2089a4b,12082c73,ba466dc9,851e7226,388e48ae,b1270a1d) +,S(a1871963,e9a65bd3,9e1b667c,55fe1a1b,87fe4215,8273c6c,f338f8cd,9119a828,e6881210,adb32d79,10dfe9da,c46c728b,20bca3e1,ad130240,f0dac7b9,fcc0cbc7) +,S(4a91a506,e8b32ca,13cbad7,99c4e3d7,21fd64c9,7ac8a1b1,e7f4bf2b,cc0ffa1e,66a0ee78,cb63bdd0,1a7c4bed,7bb565fe,832eb2c2,d32f2032,c33935f3,f16a40ca) +,S(61c960ef,2a3a6244,e8e7ee79,d4f5e98,88539c0a,b8be739b,314a100a,375ab66f,13b94913,ac8f600d,dbe9a82e,8987a061,3672629e,45d7d887,822faff2,60fb9e08) +,S(10325f87,f797c48b,2e6c7acb,bc0aa0e0,537fbf59,e74ab9fa,a7630c9b,86a04b72,685c5ae7,26b5c9c0,31e1c830,d513db4,b7fda140,14f8b723,7a9da11c,7ce9403f) +,S(71bca019,c15a3534,e5bebab0,6e1e1821,1ab01e97,dd24e1f9,1f89f834,b2cfde74,102387d9,a8da4f7,a483480b,316f0303,2178e668,f7a72719,2ae7e54d,27314a8e) +,S(7d30b01c,5c93abf8,9a50d14a,535a88f6,7cbb535b,1e58540,661fd7ea,91121fe6,e3d7e70d,1a9c0cb,2d6c86df,53709d18,b1989a5e,7642c1b7,cb381338,f6ed96d2) +,S(6f0322af,c1617968,b2550b3a,cafc8d0b,9445fd7a,4692f933,3ae9146e,fa2d3a4e,ba402962,d311b424,d05f199d,31b07d5c,8534ccff,caf817e0,88712bb4,2e6496a1) +,S(a3719ef2,c34bce90,feb7668c,a07d1a23,e2e6fbbe,1eef4b93,d2995e84,2c74688a,7164f77b,67aadb53,30b4127c,2d71dc46,f11e2d72,25968163,f4ea7358,134e5d56) +,S(3cb0007a,d2f1fb76,aa9752f0,218e2498,b7217440,a6a5136,68e95a78,4f71a72a,2f498749,12e8f469,e511b7a2,5a5046c0,f922a343,24620b51,3f6f0160,6de6b308) +,S(26b62d6e,f46929fd,88f00ca5,a699ac87,e090ab0c,8f02a078,393fb3ad,ae18c055,4fb9e53d,1b643585,4f2c78ed,1a818a80,1ff62c5d,fb0f8f23,d5e4d096,29886fbc) +,S(55e9ad69,68f490d,bfc2e17b,4e90dc5f,58335c1f,7bf30d44,79679acc,8cd7442,d4df7806,f74d9701,378ea804,be9a6270,85767e0f,b816ddec,4dbe34d9,536fe892) +,S(74a87add,723320ea,f1f9c35c,eddb6133,79835723,c74bc043,af36aeb3,5e1cbc45,5c79ef91,bccc2579,eea907ac,85ff8c0a,57fb48a7,c273f9af,6113e177,588fb14c) +,S(d4f1a9e0,2189ffca,c1d9914c,177fd66e,9d9a41cf,d1a38626,aed6b82f,70ba8020,923bf669,6ad7c71b,bfd696f3,9d68373b,9d0cbad,f367363e,2f70a93,4a0dea5c) +,S(593c7afd,c178edf,9eae7fb0,85984992,bc5ca489,16a2a155,a0314d8e,31fed706,ef39bd47,64f3b3b4,cd505e3a,628197df,5aa74126,30d83793,75c85b27,76a1073f) +,S(6622a6ea,569856b4,23e9f68a,78bab680,759a0089,3f6f645b,2e0eae60,f5dc9d3d,e84d491a,1bfc3127,3cfecf5b,65621213,bdf1af30,2dd39d26,d756e75c,4f9bc86d) +,S(d7149e32,fb34d956,1f5b25d0,650409f7,33a28fc1,fa4ad822,eabe98c6,74b3437d,2c249dbd,a1a82561,51b6eca8,a44bad96,1b2d37c6,d01c1d1a,70ceaa38,9b3f5039) +,S(64058ff8,7cadb65,8efbf32f,a68b7b3f,19915f5f,b434830f,bd5ca208,a4a09b6f,71c6dc90,f4d8082f,72d5697e,48fb380b,8486d7e1,5f113cc,28365ef7,d3ee9999) +,S(6a6cbb7f,5b571865,d70ec29d,425115a0,82d1fc1,f0209e8d,47be5e5,a9965dfc,fbf10d18,f3af0e94,b2a6ed30,c610f17f,5bd571a,41d073c4,2b2a4dce,c98ced0c) +,S(3f9a9be2,9a72cf7f,2086d9ff,3701a35a,94a7f81d,4b34a364,916a45e0,d8652874,25b12751,5ff033c1,70feaee1,189a35d8,ba0b8da,d4c943bb,4fdcebd2,1cffdf72) +,S(873be5e6,3cca17ca,95980167,9568b487,3d34c5ce,68abd305,169917a7,30dd206f,6ea148c1,280396a0,7ea5c5a4,17980f48,d076bdab,3df1628a,89da4c45,14bcbd4c) +,S(17865995,f28d4c4f,43e2e9f5,9b20edfd,830a65cd,d632cf9e,e7024ec3,4da0834a,6773c06d,478f3822,86c749c,5ae09a10,910b5666,5b6df747,36d20adc,af58332c) +,S(efe91146,fdfc4865,bd784853,ef79b8d4,d2f020db,3f901f45,38c74c80,bef49172,a81a34a8,dc3a229,8348109c,14d367c8,7abe6753,50d013e0,b1b0372d,2a6ee5ba) +,S(7ee6fb63,36cc88be,3b3c2821,1552031f,d017aa4e,192bc122,973545bf,924e8a8e,a656fe25,846e8173,327ab11b,d8ecd2ed,9d1909fb,21d1f789,588b4fa9,a8ceb0d8) +,S(449677d0,2a78e9a,ce374016,e19e7fae,46efd0d6,4839680a,4d5cbc42,173ee605,47017ad3,3357db8b,ceca2513,c6477157,f3daa99,9cccb709,bbe88340,29312013) +,S(ca9db080,12b9fd4a,cef2255e,83f35fb,e20806f3,9839c2a1,699c5d03,d7b5762,6a1a811,3d82a60b,677d61c0,af995bd1,4c598f08,f915e971,d9f17e9f,8398487b) +,S(d040da2,8dd69fc,67414651,714d4e94,5a27c4a2,9fb44612,d6d87f4f,80e2ba45,a1a72b85,957a01ca,8c8d5d3e,d9ae6a2b,31d2d192,cd7afb9a,4d1e4629,aeb9f356) +,S(27eeb708,fd2d52a9,47f69872,3706b67a,1d6e29b,cc0c86e8,111057f1,e3655608,7f67db4c,25b2e88e,275e53c1,c52eb47f,c2dab668,64b91236,522229d3,1b001a94) +,S(3bc82484,daab22ad,6d887a01,ea9f4b38,bb70e272,b15a7b4d,ab5e3dd2,439d8a23,b0ec952e,6cfe3ed7,4e6246d1,46c9c354,dacbc024,45b1af9a,6a668f0f,6fd52ded) +,S(d0a00060,13596198,8f070ff6,7ea731be,7f97a51f,68faf899,95eb0ad7,746aec69,dde4a735,d6dd08cc,28e2588e,9af0eed7,57017b38,790d381f,74748f30,9717a989) +,S(8efc4c50,51c65e10,56f5ccb6,a4be2014,a9dd043b,641b7690,cae2a8a9,1bbe8ecb,26fd1112,e1aa603c,91eb458e,3874d010,db58efab,5dd9ed20,e156886a,5f39fc13) +,S(e42271b8,881306ce,f166138,7d14f0d,da0db64a,b379368e,fa79969f,432cb110,d2b9999e,7ce9f3c5,8a6c77ce,a97cb9f5,f2860299,9bacdc7a,b7d5487f,8b5c9f5b) +,S(bb068f3f,8e7fbd31,f3aaf96f,de53d134,e3a88b63,9d8d43c6,4b3a2b45,2f8de740,574410bf,903c173e,23d88fb1,3f7534fe,566984c1,aa10f0d0,f54eea9e,7883819b) +,S(a3d0bd11,d728bee1,b166dff1,81c3682d,650fde7f,285ed5ef,b2ac5033,5327cd66,3e290c2a,42afb4ed,8b5a685f,69bdd379,44215104,17a61d8d,bd3dd2cd,805c5f44) +,S(9884434,78bfd51b,d27d04df,b5282a72,4cf82c21,487a8733,9347e560,994debdc,545574c4,359fe553,b694803c,5a07339b,b4e1a95a,b9fc72c7,5d4c8f5d,ec6ce4df) +,S(8cc104b8,58b8fb94,e0771dce,a103a7ae,adfc50cc,dea4cf93,a5f4ec9a,d44acea3,ad73883f,57c470cf,d477f228,8badab99,938b6723,516f97b1,22578f2b,f893b506) +,S(1627b08d,a822d244,ec8fe2e7,d8f02094,111fa362,e7190cbc,11229a4c,2043c626,41f6b029,80fb1370,c1e800de,39507798,8b6f315c,f910bb00,423ff727,e9e04c3c) +,S(459d4b1f,2676fd9c,2aac5937,376dc18c,fd4244d9,dc937407,d641e0d5,491df69,6f22ce37,a6ea6a5d,c9823197,22b0085a,e61fe140,d7558fcf,7bb44976,5de7aae6) +,S(cdfc7b3a,b755c181,72882e37,ff641e2a,94fa4e5e,b1b2947,4cd6e94b,f4f9387,76a11dae,107bced7,c2870dd,62ef183a,d45a02be,ce33e333,dea061fb,d89e787) +,S(5e189861,b1615f76,ac416236,e84b0961,b2639845,ecf6e6ee,8dc33217,b0952afd,1cfc65b0,9194d1f9,71136626,a2c3896f,5a3de705,ff1009c3,49a09c86,ea1667e1) +,S(84749eb3,3d482c59,81cc08bb,8634bad,fe0572d1,42367cc8,57a3c399,821d12c2,146a4fa2,3fecc0de,f00299c0,19406b30,dfbd9ad0,975717c8,7630e726,6e96022e) +,S(d73a1958,e9aa29b3,b1ab0807,2165c06f,daa38c90,6be76384,1851fa3,5711bca3,41f13f90,20633dac,3a5eca40,229ad15b,434c4f8d,4ea570ff,76d15d4f,63ea882e) +,S(1d77616e,1ccf1fda,bd4f0beb,6b60c1b3,1b94576e,bf2b61b8,c085cd79,caf8c018,7d3e5813,cf181271,55f3d084,df1077eb,2bfc9d6b,8ab6ede9,55c0ba4e,5095f23c) +,S(bac936d3,63887dab,cf27ea02,50bd550e,db37cb71,a2a8351f,fabcb1d,6d6ca9c4,7aa18819,8bd513e6,b45d6633,aa1af70d,b1a9c432,ffd1be4f,8a8fda79,a38c47f6) +,S(4d18c5c7,51639d86,b21712fe,b2333d52,5f4bd3f5,e4208537,e1e3bf7a,9343475f,2a60352a,4d8fcb6a,ce01b4c7,63619f16,156868c2,d85e882e,a2e7fb80,16f6500d) +,S(8e473caf,d74fb06,b483d955,ba3e35ec,e99a4495,cc86485,a8b6fada,c4c8eb4f,41708d5d,ae2de832,c7c38389,d0ae46c4,46add069,8e83990f,52a545f1,6ef66942) +,S(91366f76,48ed27a9,2ab639ac,f37aba5c,44e8bea6,1402e075,e307c4fa,ea2cefa8,868fe0f5,565092ad,677eb1c9,8959affe,5af504a0,c929bb58,2f5c3263,114ea371) +,S(1eab20f6,51b63685,a0a8489b,4e3247ce,1592c4db,40cb2f90,7eff1c58,c6609915,c142e9f4,b9522b0f,1db90912,c6f83c7,add6d8a,6bd1de4b,c54503a8,4e873cce) +,S(a0652eda,796ff72a,eaf8cfef,371594fb,e1528929,1320230d,2bc6a252,f4b49484,67e6d40e,8aaca7cd,f2a2047a,fc0a59c3,b4eddc1f,d3d5662f,45bb5792,9e4dc9a3) +,S(83915afa,c936886a,3deb8958,70e926e9,7ee4a6ab,1a5c66b,a1602c13,c4f959f1,86dad7b8,e870dba7,712ca968,1ab63524,2ed55fe0,36a148fe,25b1bdb1,1ac2da4c) +,S(293f0bc4,11454959,86b19fb8,6f738d2c,814523f8,b75b280,f8f9021f,95db6061,12d98ddc,894669fa,86b073e6,5855a0a1,760733e7,b7c5bf5e,868dd977,82a4fdbd) +,S(a829b1c0,d6780732,321871da,2d28ecdf,18d13311,4ddc33aa,8ff4caf0,58fb9ad,c5375298,501294a4,dc38d1f,a8c96f9b,789ee9c5,6533643e,1142bce6,8e1ef5ef) +,S(48133900,866a344,68309fc0,cc18f79,c0e01dfd,ed6a7bb4,e5a4697d,4b9cd462,335b7188,ccea4687,50fcdfc9,a6fa6034,c239fe6b,27cf6460,182a1c0e,c8c96707) +,S(7fe9d310,bbdaa101,b28c1e71,137a7ab5,181dca39,aa8d1469,bc06c856,3c7a70ec,18006c39,538a5141,2371828a,4d73e02,f4699a34,7e887318,57e394fe,75c8143c) +,S(1bd5b65b,d79c3eb,54ee1ce2,541b4352,1b7d6c37,d2a26f21,b51d2c07,103ebd8b,66e81b90,a120f04b,340adb2c,42143ef6,5d8a383,46e71856,673090ef,291d7bf2) +,S(237374f9,306e5714,5f37a1ce,1418a238,73938fa0,8bb971ab,fb5d97e8,e5fa0206,d8410815,fd4049e,f54abd51,fe2053a9,bde7f3ac,f40fe992,21bdcf8d,4b9808a5) +,S(33279bf7,38cee621,c17f75eb,bf78af4,58c1a4ef,a7197456,b57ee679,f2c34bfd,d63a21a4,5dc29462,13750d88,ea5e12c9,900b110b,ce433c49,e9b37382,7de327ac) +,S(ee274c71,b1f43251,11d7e100,5d7e9d97,ed1590d8,95cc6504,3e8ed6e5,5a87a9b,73f2bd1b,1baec4f8,ebbcf9ec,f613869e,8a262d99,7bdee49c,c5b2fb22,b652e9dd) +,S(2f49f0ab,c24536a3,3bb0857d,57c35846,f5dd036,3851a873,46f93d0e,53ab8de2,66b3dcd,d367958f,fd06121b,e42237a0,a9edaf21,79ded853,e8bf3c5,b6a81531) +,S(2d122193,ea92ca9b,46eec10e,2a23268e,9b1f972e,91821489,8cb12571,1e3094b0,b54d4b85,a02f77a1,57a48001,c0a26c81,2c038d0f,b91575cd,835183ff,3a0b7071) +,S(9047eae7,841f346a,374131ee,d4299fef,970f59e1,e4bb1fab,819fecb7,3026ad44,d59d3d2a,2c03be1e,553a54d,2dc61c9,e13364bf,3338a5f0,4e4466b6,86695061) +,S(f689480d,c0ddd61c,ba5aefe3,17aaa497,c2d051ed,d527cc20,16877986,12d7c8f,dac41495,a948d83e,37a9f310,18cd7abf,6d5608f2,213aa5cb,7a2b8f90,98d87398) +,S(4a01c418,be472958,5bae0c45,cf6233b9,ad0177ef,eb6e74ca,ded59788,a22d083a,8a12550b,83de095f,22411b16,937a85b5,a079c7ea,b8137f80,ffa66116,2a1c53f2) +,S(a6c715ad,cdc77020,febc4ae7,c6caf5a1,107147ba,8281d3f3,7945682e,72a5da7c,69b4ce46,2634da4e,e9e43559,72f87511,a26718d1,d232f726,577f0d5,6b49d165) +,S(68ecec4f,aa19ac3d,dd8b928e,8362ed53,3be24406,15f5ddf8,4b8a376b,cbff327d,f725f978,f6129f28,49a1c9fe,b07bc2b2,78fcdf4a,96a6ee3a,70b9b943,98a89f3d) +,S(5701d52e,2cdb7b71,a9ed91e6,95396487,1b656bc7,271299b,62ce0a4a,78dc69ee,eb8e4539,be99cbf0,ad730fa5,fcf785b7,35e1f5ad,f5c16c72,85abfeee,4058ea1b) +,S(8210f0c4,4b2f54b0,62de4761,b7c62d87,42424b13,ca0448ca,ba999eab,73b26409,1c79890,e4149248,b9dcd496,1da563f1,517275ec,79949969,8c6b864f,c03f8050) +,S(64cb2793,4ee57641,9d52cd81,6144543b,e4319d16,fdde7a7e,2bd824c,113bc1b7,c3144c3a,518eaebb,51a55bba,d87aba0a,12d3add5,5a5e00c0,94a2e227,80f0f6b7) +,S(37eb1010,acb889,932d8536,b86648e7,c124a8f5,1005c0fd,ec40bdd3,6369c82a,1da5703f,b387312d,d5a337c2,2d3f63b7,33dcc994,38109c2c,4807fc45,c02a2717) +,S(84bbf980,b54d60e1,ccfacb7,e861aded,b4cd7bd1,a3f7baa0,9a1898fa,22144d2b,3820c4d2,7b545166,2515064c,dc9b4cf,813c2435,e84a4a67,ba47068a,e6e09045) +,S(29e74c02,6b43add6,939ae05b,dc0a5e0e,b7d05bc0,536e23f8,8fed55e0,6f93f1f7,f0f6fd9c,798732c2,1dd1c550,3cfbd56a,71b335d3,aaa22359,75fb0c89,9571186c) +,S(98f3530,1122a0d2,629e5adc,579acbf8,8c0aea34,c3450ea6,784c4ce5,ee9672f1,427b899e,74e0c5cc,c289304d,b9a874c5,1d401369,55dc5b03,e0713bb0,8c3ec3ac) +,S(16af2e5c,4c37b50f,5f2b6e94,341e365c,90548d68,2bd9af37,1d849126,ad2c6c6b,1dd1bef1,6077f6df,32054335,c81ff474,33b7c1c7,d6243dbf,6a2564b0,fb9d8502) +,S(56998d6,bd5b2da6,d452f951,5343a9bc,4ed64463,adc6b8df,6a3edd64,e75e1cbc,ccd52462,9dbda3a3,10f3beac,7b3d3bb2,f1bf3c50,bca242ba,224861c8,1f26760f) +,S(f1732044,ec59c52,86273115,3c53aee0,c7f1c4df,e6e55cb0,e7e37d62,c1e11ce9,16a547b9,a61a6c10,4df1d1a9,de99f54,b42e0ad1,104a6a30,e6e616c4,dcadb2a2) +,S(6e5fcc4d,2df77b2b,8d2f95dc,56ddb885,6030f9af,aa51d86e,20d4772a,854b8973,11939a24,26c1ad6f,90db151e,c5c9f036,3f0b6898,2464fe92,c33aeedc,77347660) +,S(74a3ff02,98c3cbde,ba066554,d6def895,3954af05,f0f72365,680b7b8,4c5e9fc8,23b5f011,e50dd2b6,9c5ad6b,b4dad524,9c6a8abd,f134c232,f40de18c,3c65206) +,S(12a40a59,169e806c,8e32deb6,7e64c615,77a3ca,5c56723d,ebc98ed3,11983bc1,9d97709a,9c644c8e,3fcda745,a70cf3be,c405d230,eedac78f,96792bce,a715c081) +,S(f25dcc0c,5ae3f442,7fc17acc,bf888557,82673050,c3594abf,cea7eec4,7a4662af,52a20297,bb9213cd,d1b4f1f3,4f6168aa,ec2d326e,d9aef5eb,5b497c39,e0642e0b) +,S(fe31ac7b,ee45ffd7,99941eb1,8d65cb2d,38618938,c6278e45,4b87e41b,3c7d0f90,a5f1be4b,e0373cea,c3137a8a,c5b5cab3,e1209c93,2d49b245,eb99a0c6,469c3e64) +,S(c0ff7403,2855c2c9,ba06c2fc,6c9a8fc5,29b4ebb8,be082951,475196b0,ca4d6711,2c53707e,540e0c03,27a10980,25e356a,81fa6a48,b1e41d78,b7fe5515,b022173f) +,S(5b23e392,b87bef43,a3c08956,e1930c10,cae049e,b6f041f9,1bf3de75,4a84f984,c905adbc,337b9e7d,78781dd5,deaa0590,18e20bc3,5114c842,72343879,7a37987e) +,S(2100a6c5,b6b96ad6,37e13430,8d92e2cd,97902da4,7a016ccb,63a20cef,e72ac25c,a1fdc3cf,93560ea3,8418c470,679c5389,7bcc12aa,dc87ee6c,3429c68f,690f7e11) +,S(d57874e,509198e9,ee6ac826,b101ab2d,fe952895,ab288184,55f2d85a,eb2c3387,1c7bd36b,cdb6debc,99228b,341abac2,94dfd768,c9e00e73,8aa58339,d226f940) +,S(ff91057a,e46817be,b3874656,42afecb2,a290d31d,f18c6da3,d6313565,99657c4d,a2bb1559,96ca6cbe,2a375c3e,510df603,69d0cd8,f66d6571,9f9866f8,c6e73675) +,S(7f20e461,ee306c4d,7db625b3,49906235,14aca551,21b7890f,244de5e5,84d18b7f,8cc69fd1,eeb89a9f,9e126be4,3983ed45,d88c22fc,89f47006,ecd57431,4eb5d1c5) +,S(7ca32320,75421226,257670e4,5f277f4d,32cc7b4d,53588423,317203cc,b787696d,1e940799,8f25b7da,8f1212ba,c1dceaae,ca7b1952,26655535,6a98769c,b3da15fd) +,S(bcb7060e,f2685623,9aac249b,f603ce7d,b5c253a2,c998e44c,4ed60db6,730d5450,e03df58e,6d279025,955a4f52,dfce586b,f427e376,ca72e09,36d80c31,5047f57) +,S(30387990,3157ac6,fed71113,a004284e,82fdfc7a,3e08c0ff,1ff5dbc5,dbdfc04c,7132084a,1230ecfb,200ded60,9a1666a5,2f574014,d29475e1,6a061330,fbe19e7f) +,S(c5b3aa24,1147d664,a0b80f33,5dfefed8,a8f7c1a8,c6258686,cb16e3c,c365a249,fb5143c6,5f8907b9,a44f10fd,27064fef,93ee588f,9e77a65b,1cf64e4f,956f5748) +,S(11d8bdb2,b750146d,d78d8c55,6e6ac45f,4d34f1ae,35332673,cbb46bdd,3d76d9a9,1ea28ad5,c92761b8,7df96987,6e5b3243,9fe97661,87b5978a,d7515288,f30a5970) +,S(d6db4c60,742914e,c9c7bfa0,7a716cc5,f5492aa8,5381f31d,f76d089d,a773814d,b0ca5fa3,bc5d1fa2,c62a657d,77215b49,82f72e89,b138552d,bdea8166,359b6a3d) +,S(d28a6123,3b4e073,f1242c4f,5292bf70,9e1ae15e,a654bae3,4239133c,4a8a86e8,89519c8,8c44b38e,ad5c2ace,52d01de1,d74ee0de,5365567,cf1b21b2,2ae8b95) +,S(ff32042b,6a943772,d6f5794a,43420218,2ed31ac2,447167ba,ec82d19b,86751337,16961368,e20f2550,383268c3,9fe62fe3,b5d356b1,da2e4231,8f9618e3,13655f0e) +,S(f2c6177,30a9870f,5999ed69,d34efac3,589baa96,9f660cf9,ac839eee,a10e374c,fbb2480e,b6f191c0,15ee3c58,bd950aa6,7bee7569,1681250e,502e1d76,b6ec9069) +,S(dca14b70,e5e33022,eb559d90,1cf3a533,4c40bd45,7a43df85,e87acd40,90342539,7d038e51,30f77ec7,efe84748,4145594f,87d613bb,85a95715,9d0cd377,91678d23) +,S(9cbb407d,acc7c2df,2d86a258,d5ab2b43,31a18bea,9480f5e3,7727aef7,644416cf,7ab9fb64,c5f54f6a,4e5529b6,eb7834ae,80283bcd,c3f6b24a,8a014d02,b3b80b57) +,S(4552c48f,2d96ef41,aaf27778,a7ab4945,e4f2a2fb,7e1564ee,c375e50e,3516f555,e63da54e,28b70a99,5f35a1ac,3a25e384,6efafcbe,4e8f73fe,d84e095f,126524ac) +,S(b4cfb90b,168dc850,36559181,3d2d084a,9866512,9396f76,879280f2,38e4af3f,cfca0080,37006c35,7fd89c5a,1d444d19,5fd72d4,17fee670,e7b743dd,57f71b00) +,S(8e264996,e4e8a858,a1e32c59,b0df640b,a096401c,e77be6ee,ccd228d9,67dada3f,c9f5a8bc,89322e56,838c6d8d,859b6012,6d0a40f2,8377aca6,b5b4dacd,44931d0e) +,S(34ea02ae,49a4dce2,5ec2dc07,c71e3400,390b3054,83b8f30a,81021eef,5761ed99,b4b6f9ea,c41bf9d6,c4bba143,4639fd57,b8735d27,6098e374,d9324319,3def4c1b) +,S(bd391dfd,8569db85,b567c36c,5e6c378c,c152ad9b,c23d1fd6,1af23e29,543a56c3,9bf167d2,77e6bca3,a8d3cce7,61a36abe,91fcad0d,8d6ce398,877d3748,f2f13bf) +,S(67b295aa,440c8807,95369b98,c67d1d5c,1b9265af,58541994,7353c0bc,47ea8483,c94a0287,f2983c42,14f3baca,a8c5c791,d4d88fb7,30eb5b3d,4309f5cb,c5706f23) +,S(755e0335,284ad31b,5afb5775,fa191486,32b29c84,f38cafce,1b0b3b4f,2d073a42,c4506c75,c8cc96d2,8e31766e,a8ed1cf,531f4f7c,73888831,65f825d2,2b74c47d) +,S(e4b0cb3a,6149079b,5e47ccd,bfc4f351,64e575c9,20cd9827,a83f68e7,e5ba0a97,1604e71a,afa83b19,61bdd7ae,e4be5113,f9e9ddc2,29957255,cfe40341,9e45e5f4) +,S(3baca490,3147531c,905a2c73,277e4f39,c27ff6e5,41f6f2b,3ed4f730,3af0c4a,cf36fade,87b988ee,a4ccec6b,6b70ec01,d057173f,3aa7c79a,6bf4d412,d4bcafbc) +,S(229519e8,2a4dd2e7,ae77d713,21fbc8ff,f31191ee,6604823c,a6aefe03,19d06d95,a70e9af6,14ae7a1f,76224b8f,f5d1fc26,2e34707e,a6bfd26c,8cd7fba9,b5627e15) +,S(59364b22,4a53ed1a,7dbe9753,1b3a2600,2f700045,b0576733,8ee87a9b,2559dd54,b08cc507,70f5f3d8,851908b7,ed79ebc9,7f4f7342,61de0752,e14237c2,14eb5f6) +,S(d4b681cb,f3467c9c,649fd640,7991b4ac,3c66bf50,26ae93f9,e9b0238,9fb7c1f2,6df1a03f,4a5f00f4,8356bb9f,b23f1621,bb18a8e0,5afac4ce,4edbb01f,99a27000) +,S(49784426,fb036d23,a289f4f5,b3b92535,76da111f,ffcefdb6,a4163e55,2c56bc,76de5ca2,16ce703c,6a62ea4c,a0f7ae07,3744a22d,6db67389,9b0e93ff,a69e2a9d) +,S(5b213b9d,3f84b248,a98fe326,929b94a9,7bf78521,106a83fc,adba632c,8ed4892f,8eec203e,d015749f,f01402b1,722214d2,b58af86a,95384ae1,c39a7780,5623a204) +,S(6bb55cfb,9e3f5468,966711b8,6343e4af,6e372d04,ee7f570c,6a12005d,628959ef,75359562,9d633c9f,c2432ad5,f4c9f00,c6f54005,cdffaf82,438e3e58,70d14154) +,S(d760efaa,3a9e5c7a,967174a4,705baafe,d230dadb,4c957cf0,c025ab55,4b2eeb43,c019790a,b1b8498b,58daa784,ba02b7b5,672ba2b6,13d312cb,b4563f6f,e26675ce) +,S(f8be7bdc,6a361b6b,2844c60b,af7fec1a,216d75f6,96418734,337f9ccb,ae9117c0,df66b665,21e3dccf,639a323,5d773c21,4364062f,c5260323,3007e2cc,457d783a) +,S(6bbd2558,84348c88,c75a8155,6529be50,93b06a4,885c5d32,f1047357,a11434a2,842f9093,fd41b2a2,153727ae,ca2cbf00,a494ab7b,eef1a2cd,8696e972,1b1491d1) +,S(e692623d,cda3bde3,d32c1c01,f480d21f,9ccf8f1c,416a7dd5,17f1aab,12d3f3c6,30dab6f8,71f4c6d4,c768e086,fd6287ad,3fd000bc,3b04aa70,35cf441d,44764b89) +,S(86dbfe13,5db905ef,9ec7483c,6f51b75a,71726a1a,27e5131,8d6c0b2c,b0b933c2,371f23bd,45c46d3c,18056f23,10ab6afa,1259c88a,3a55f8ce,cecaea71,aea083a0) +,S(7ee329d5,9c625a92,594e620,4cb48559,458514f8,da94c7ba,fd2a4835,a4f10239,80a58a2b,e17f32da,dc80038c,7ed57de4,c7c561c6,69bf6786,57ee72ae,dd2bef04) +,S(e16a922b,8255d2c9,6ef776b,cda14285,b1cad5f7,62f75465,f8c82695,cf1065c2,44bc0e38,df9ce403,a927cb01,849e166e,6838468d,c7a8bd4e,6ec3fbbe,1f3465bd) +,S(5311e064,23145aa3,10737d38,41adf49b,988c1ca8,e8a705ca,3ca67f98,f756fe87,21c3f6ef,73bcca3a,c376e20f,dec775af,e22e708e,7e500c24,23114b4c,84ea8678) +,S(c09eda1d,dad1ca36,a9aaefdc,d16c5f50,a6ae499f,2cdefa2e,e5b61ab6,69f7fdf3,2220cbe5,bc279362,c5506404,e1df076,52624966,e3222b7a,62a1f7f9,faf00500) +,S(8888e104,18fb5c16,fc3c2b7e,b9ea06c1,da2df71f,c647b989,e71662a1,731628b4,7444a776,fa8f5bbe,959c71e2,c919b761,a2f8fdcb,5e66e5b,65e561e0,928e2d73) +,S(5c70258c,c1030231,d897c9a9,199df5b5,8b920f59,18141ece,d84bbcb8,b9b6c243,d627669a,e3dbb6d8,57d65a42,ec53bdf1,c688492,d189b1b8,67b75c3,f003ff90) +,S(eb58739b,878ea9f6,74b16f8a,406e7135,1ef06377,d9be32e8,1f657648,60e35ae0,752ae84c,8db0c7f4,e956d2b4,5750a5ef,24ea454,8f275f0,52b59ead,e3405ab5) +,S(996af698,ef26245e,35e4845a,dbf9c45d,6fec5564,c1fab0b4,8ac78f06,9840e0e7,a86b564c,ee788008,bbb04ee,e3d66c42,3c6910e7,7988aa54,420f3a4d,3137a1b5) +,S(bd03f2ea,a505bdd,7f39915,23f3e3b7,7532335a,6b5a11a1,4e303542,c00b8f4b,345f765f,cad902c4,56211eb0,bbe520ad,aacf55d9,e9c67787,aa02f18d,ccd88ea) +,S(8480c77f,3dd59c6,329c221b,ed8473e0,8cb0446d,c4e9bc6b,f2dba8d1,7ddf0f1,b055a135,a224f1e2,965cff1,a4f0d764,fed265bb,c644c696,2f3570d1,9af6e360) +,S(f46b6845,fa45e8c4,576b7c74,cd1a308e,f1adeedc,1d539d21,1158318c,ebd4c584,e1ed2665,34a14e05,c1ecf136,8cf8d6bf,fd9f0258,a5f0a53c,8abb00a3,e953c425) +,S(596db19c,38d91452,ad238f05,453bb773,9883df63,a0b545e2,47e5947c,d9f52a2e,bcb35b45,b172aeff,9e4fc5d1,714d6743,46bb4073,6f571291,e6575d34,f8b0d929) +,S(4cfbd998,f9544921,e5f1658d,e3ee95c6,df85b3f9,309f7a85,f6e4d08b,7e535497,ccd54e2e,437e4aff,7fc2ef17,3bed5ce6,b7d6e34b,4b386f36,72140d72,ceba71e9) +,S(c3f056d2,357ffe13,4403cee,6dd5ba3a,a7d2d0d,91d83f25,cb2cee44,34e57f94,1c31cee1,595b3682,fd85840e,312a61e4,40cbbf68,55418b30,bd6b24ab,c3bbf7b) +,S(e272370b,82ffc486,53274eb8,898409c5,9338e024,202be5e7,e18b5ec5,7f824680,d2f4e6c,619f0d,71e38990,f4e52881,de27ee31,ff7ad9cb,11a7f735,80a546cb) +,S(81537bc4,6a5fe897,827aeba4,6e66d576,6cd05a35,cd3fe1cd,9c06a2d7,194be59f,6706c254,125be3c5,92ad55f,6fa6289,4298f23f,2f4f397f,3bc84f50,79bcb8ae) +,S(50e161e2,6bc89d2c,816030ad,45559a3b,49c8606c,b28b6307,6ac6a051,9226d2b2,98478bc6,3f8d6be9,2db02910,67e5e359,e865d046,a5dd853a,fccb7592,72985c67) +,S(76ce7272,fcff02f9,bfc355eb,24286fab,88ba08ad,b15e099,22724b84,315be56,88f98fe7,62e37fdb,b72c1526,59528cdc,fc4c4203,c465e772,38dc8618,78a5a14d) +,S(77935c1,3a7f5f47,13098101,6e10ec54,d5ca10eb,492d4025,365d5265,ef7e6ebb,3c15e7c9,cf230340,44444126,5e74456a,4f3b72dd,7aff0ac1,aa76c67b,ce77dd0a) +,S(b37c3ecf,5813b5a5,2f52fc4,42049653,991d9241,e8677d2a,f9779fda,43c7a255,4361c742,c070b356,387fef42,1a9cdf79,58dd47a0,b7c9add5,57fa425d,626a1786) +,S(90c64aa3,28d43534,271e2f37,3460d8af,d17f9585,516b909a,6a7bea2f,1b12d2c6,79394191,a37a451f,e439e538,5e876c2d,ac397f0e,dfe29114,d14b9363,b76823c4) +,S(a314f637,2362ef7c,c4bec6a7,9396c318,568d9f05,9b6ca38a,c5f56090,c33e5e5e,b3a401e4,f7741130,95179507,2ce3b0e,53d2f51,f2dcaa9,d289e25a,8de01519) +,S(15c25f4e,80a7de90,8c49fc7b,649afd24,4c5a4be4,dfc15b2f,70099f73,6ad003dd,4aa9fb98,39855fca,c9f8bb26,b6322c95,e5d7adae,5aca9bf6,de073949,eb364b86) +,S(445e6d34,90f4ce76,22b6713f,584065a5,e0998d47,1b7603a,2527ed85,5d67d7a0,ecf994bd,7ba618b7,6eaca0,b852e0eb,be7b7f86,70d028e3,f52d1b2,846ce8ea) +,S(def695be,1ded66c3,650e9918,e942e4c,bd420fab,3a4708c2,43ab4e3f,1bf2101b,63569e13,532bf299,a0cf8d0e,a4addffc,1e782a1e,98a2f7c0,e0b64f50,8dd0afc5) +,S(eb364f1b,89938b48,2d32271,551f9529,5013185e,3ee2b534,bf01a288,9a534a88,9e6091fa,b439d0,d96f6a9d,cb468573,881234c1,6bbf4c50,32a6c950,99e6e6c1) +,S(7efe80e6,5c0134b8,49b6c58c,7d4c54ac,873e43fd,1b47f9d2,1d33f9c8,ee26646b,5411262d,63357cc8,d8280243,41d1767f,c25a0972,4c8c7a7f,3ddf6701,d12478e7) +,S(5f412876,3774e9de,6f2f25d8,a1d98de9,edf959a8,884643a4,fa18ac7a,26d6308,d3f6eff0,e336d4f5,abe35a12,4c47ed4e,5dbbe6d8,7d563fb1,8ea89242,aa454411) +,S(c63e3b34,bafd384b,2b60328b,4aee3a28,c7b3ed30,8a7cde45,87aa6c75,6c49c2dd,724fbbfc,11d05623,a5cb449e,a2f9f65f,a3de167a,a811bfcb,6ab9c3d0,3b123ad7) +,S(cc92795e,a0be5e79,757a86b5,147429eb,ca7a7c7,d51a8d3c,93650178,4f6ba5b5,92053ab3,db369d61,3af1093f,50829c73,4618c1d3,610ebc57,420d2824,935ae2ff) +,S(ba73d310,b5170cd1,57bbe14,63bfe944,ce7cea80,1b1aedb2,da3db11d,f1c7ea5c,4114e55,15806ca6,323edc6b,f0b75a92,834c72ff,9579d1f2,27fdadd6,d773c577) +,S(6047bc6,fd3a1c7b,9a36036a,94139542,7d9432c0,f652259e,1d52d709,e5088b22,bb119bf4,5d8ac9bb,1a918e6b,95cdf23e,6e2ccbf0,171579f7,ecfc9126,6d236b8a) +,S(a0600a7c,484559cf,3da255c4,935d2d97,1628fe8a,e75b88bb,1f3c4eca,e68f78d5,a439ac58,42bc6ee8,be096973,d87598da,349929c6,92e37852,e57ac941,eedef402) +,S(bfdef77e,1efac235,c1c49f04,290f89aa,c2e4632c,85f40481,dfdf5c59,d479e2a,e6e451cf,d76433ab,1de85511,9abaa5c7,8e4499a5,fa48ad77,f098c825,206dc7fc) +,S(81ff778c,373975,fb041cf8,ce4bc337,e2c977f2,d6bb2c61,9122240b,8e21234,3fc02add,e92c9928,e94e0ad0,218d6204,d71ef295,4c32227d,96b30b5b,9a61f640) +,S(84c4653c,d1af54f3,fc59dab4,5bbaa470,48f8eb13,4afc8f5b,60a8974a,cbf03933,98ff808b,a4682139,68b73ecb,67fe0a32,85dace7a,19d300dd,bd517e3d,b04ddba9) +,S(9d7ed86a,69f39ecd,c448de07,55197029,f81ee886,7c9a61b9,62d13eb3,abce35ae,d9b27e39,41c6bd1d,87dab6e9,32e8ba57,1dcd2c58,67177ce8,e7ef0fdc,668fccd5) +,S(540b7fe1,ee263e6b,3610bb96,1071d817,b9cdd162,77aaf28,87e7e5fd,df72f5b5,6638015d,591305c1,7a598a44,ba6871cb,8d1d3628,3ea25c5c,846bab2b,cd910340) +,S(4799c5ec,f1fb2112,f479abab,217ed0dc,e936c6bd,14215eee,6bbbb34f,d811cbe0,abfdeb73,4ac738cf,f607cd93,de58c0a3,237201eb,da47a808,3bccaee6,da5c5515) +,S(70a58362,b360c280,626a8698,7e4f2aa1,abdc9f8,f0b8c216,bb88b0cc,133c2312,5e37daac,d2835f3,1d924659,e51858ab,68e3a874,947360eb,c520767f,ce4d46d0) +,S(f345a0ca,857102b6,e225dfc5,7ae1cbbb,dd5c2737,116adbd8,b3d1f74,7d132b01,16fcaf2d,f7cae2ec,ef25da7b,3d51afd2,8f5e9920,5c0d74f0,c1e7b360,17eb2fb8) +,S(c3f4282b,29f253d4,fae8deb7,941484e3,9d2555d3,f96889b4,551e7d8a,eb2a209d,fc562248,8a6e83f1,6bb1530d,2a35629d,b25c8280,2eea7057,d22d109d,4263ac1d) +,S(5542218f,606e7cf3,9cf646a1,3677b0ed,4ff61aac,1dcea3f5,da5dd4a7,d4727632,f1bce63e,a11d5176,f47e576f,66817f45,4b51840b,a79695e6,3a1a1cd6,fb6c07db) +,S(65e81ed2,7d6b839e,5c3829f9,24beda63,98264de8,b2223479,43881582,4d124b35,2a17e09c,e4dd6e6a,32d85d71,e6cc2378,b53b9356,ee5790f6,8fc3040c,e6b6179f) +,S(5066b022,e43a5f83,c4290064,9e2b611e,750a5ded,7c89b8f5,892126f1,e112edf3,381e92b3,e407c6c5,d1c0ab40,6fbe1a99,57643da9,a2118cb1,3b8c6243,9328d9e8) +,S(8df78ac5,c5ff1cc6,df1e1dfb,58ef889b,17886433,61bea73b,a805c3ae,a83e2373,dc668ddf,5b39eebb,7b692997,f22140c1,8347e14b,edb6d343,96017e09,d37ca4d3) +,S(426c1767,7d7b00ee,af8d7d30,1bb11cea,1cebfa58,fc54bf0f,de719937,fb484434,4fcfa5b9,ab7b71fd,560ecbfa,985db2f2,418465f7,cbf8acd8,fdd71af5,7f9519d8) +,S(4f7f0061,bb90e396,63f6aadf,70dd3312,f781b2a2,3867df3c,566e18f9,b4a511e1,1308473f,d8956b35,97d904c6,cf73c05c,fd7c075d,c83848b8,571e666d,dc44b3df) +,S(7393002d,d2e85925,3b23db69,6c140258,8272a847,d834982c,5b22b256,93685107,b61532fc,6706f7ad,78548e76,b334a836,c899a49c,46afa1f4,4579b5cd,27641528) +,S(c41dff65,e88e5c6f,fca3b0ab,6ae69bde,c4215194,cd7c57ca,fd9b38be,feab4e05,9a9ba27b,a0b7e217,d31340cb,acd8506,7f052d8b,f92a4be1,cf59fbe9,6241f0c9) +,S(f619dc9d,6dcc39d2,9155082c,2ed9bc60,99296a8a,982327f0,60fd6208,5765c518,87961d3e,2b850ffd,f080d5aa,cceb1912,120ddbc3,4e0ad8d7,96e74afc,aa4871fd) +,S(6becdd5d,f02a7bbc,d1cc811c,fb83901c,46aa8207,35e81c29,a8d4d4ea,3f5cf99a,a45f7dd1,8949f842,2905c7ee,836004a6,5bb106d2,fb623d68,c2690c14,f181e39d) +,S(cd2390,db1e7c53,f424a893,c2529660,69a8f151,6f60722a,524578e3,e5427196,b817ed1b,457633ab,a3439454,6ed410cd,8140b9d2,e7e679b6,3322eae5,f3466e90) +,S(96cd9608,7f1cbcc9,b017ad2b,c7824285,4047dc3d,f98e7951,2fc09fbc,e3cd33ab,dfdb9090,c8a5ae70,13b8faa7,855554d7,3df381d7,88fd5569,d3a7ef7d,f729d625) +,S(99cd7508,5e9abb74,5fe03e3d,b100f2c5,2a43acc9,4127bd8f,83314baf,70d72b4a,19c98b68,2ded269a,57e50e3a,28b9cd65,344000ed,dac3d3e9,d8ac8370,662ee1c5) +,S(f53c2afa,647496ac,6c1220e1,4627c138,186286ef,b776449,55f9238,b39fdb20,1598c495,106a200,58fe1fd9,b29140e6,a93996d4,fe4cfdd6,74ec10f0,75badbd7) +,S(c127dad5,3b9457b9,51192c79,5793734a,d0a84671,ff6ba236,f53cc40f,769585f8,688e6264,da4e9d1e,fe66f5ab,db078c56,98696ef3,53b3bd42,c344b3f1,3d3ad744) +,S(882bc4c7,651634c,930384d1,3daf5a91,41508df3,2d34818a,e61bb65,40e92bd7,5c456414,430eece2,fc6e95b3,7700f608,9815f5cb,12a09ebe,8a87e370,85bcf255) +,S(4cbc141f,55c0b001,cfd934e4,dbbc2c2e,4b5dc68,72e3388f,2388e54c,e2a91bdc,1749d8e5,30d21894,221b2aa5,96541f1d,e700bbc1,e3427140,24f0a9b,9c0766b0) +,S(bff11777,6bb9bfd6,bbf872a1,3b9b6a62,32465cef,f16c3c75,441c39ea,2975528e,9e7412e4,ae492669,58dbdc9a,b7b1f4c5,d2edefc1,d4f0a483,27f2fd69,f992eb34) +,S(251416e5,887b294f,c752a1e2,3e991f11,90b8798b,11c97033,e470bfb5,b7bb6328,e6981dcf,15fb4b98,ac8a37da,267f1bb6,a2a38b86,3919d20f,72b5bc34,cb5e329c) +,S(bfe2490,569255d1,a62318c8,416e9114,66dec59a,bcca5df4,e64c2f48,46d050d4,f78bf673,577508c8,3846bd5a,312b9284,2283c47e,d4df7651,79d33bda,ba6eea54) +,S(e50d0a78,40779b75,fa121def,456865d9,3d7bb9c5,d566d790,58b1b56c,3fdc7b15,2f2688ee,4abcfa52,9424d4cd,eb40a8a6,a6de26b1,be8946f1,e4ba429b,5b32a6c8) +,S(b3a9d7ef,235df6ef,262e177d,19bd1121,167a056a,3957ffd2,a3d22d00,9a199bab,6a7adf,40ab5386,21fc3447,77c97416,66537460,44113c5b,a73455bd,9658753b) +,S(ec7277c4,20af5d48,3a6247d3,a1da7243,31c0e35a,85d6057d,55a3e526,bb7962bf,2dcd3e8c,5abc47d4,56bfcf,a8086889,89354e10,8188fb0b,c9ab4578,7b91d69d) +,S(91ed86a2,330ef91d,e085df2,a947c9de,f1284b8c,76d9b432,8dee9342,bd297242,fcc226b0,c46a36f3,ac56ec31,bf297360,8375f0f7,d248c669,f8b31ca9,9d056713) +,S(e2a09eb6,6e76b287,36c5824f,829afff2,439d973,e5be5b4,f3c55cea,e83bbda4,6b217b22,123bf3db,f35845f,315264c0,4a67ba18,a49abd08,6b2acc76,ca0b016c) +,S(78501449,bd76ff1f,58cdf2e9,203de4d8,3325ce45,1bf106d,2f474e91,bb0545c1,d0bbcc92,acbad044,218a830d,5f461332,cf488003,4b6f89fa,2f58b708,63aaa585) +,S(c3626c48,95df6e93,2c79d5d7,eac22ef1,d7679f1b,1df1259d,2be08aaf,7217d978,a594df74,250bcb50,dd9f294d,e7322b25,f72cf935,700856e3,c31fc5f,35e61b67) +,S(5c6e0358,ec09945a,c4240f22,3304f744,63269e16,c4f87dbb,99bbb744,bb4afaae,e6168dcb,d719ad05,8020dbc5,b03ec4c0,61b1fd87,d530913e,6df5d498,69e340d7) +,S(4a3fb364,d55fca64,4cc03c40,5a5956b8,a794718a,5b43cdf0,795e5d5d,5f79e7c0,4c4e0c11,5f88ef66,545280de,af9e3d59,3ff7d1ec,d8f20779,70ed84a7,8d660d28) +,S(fdc828e6,e305427d,c925de61,6f57e13f,5d0c8777,b538e511,49cdd304,1b022d05,de9e1037,db0dab0c,fedd8544,3b926a36,88e8bc54,7420b27,c65e2c6d,bbcb1662) +,S(6d70ad6c,375119a0,f4b2b65f,51257d7b,e73a8d69,ab944dcb,232b8fd8,e7021583,31de3a22,c8e8034a,d812a7d,234cad97,978aba7a,1c2996b7,aee623f5,858770e2) +,S(faa9dff,68f63fc5,7ca8c39d,8d950c2f,78a90317,c5d7f787,6ffa035,fcce8dc6,419b6c29,a7c02ea6,c8b7ed5b,c9b6fe89,1b3c705d,2ed2707f,3ef7995c,81a17de0) +,S(53d9472b,eb9a020,e84e10f0,1d5ed8c2,6219d24a,eab4cd67,dd30f084,8fa47a12,624f4c9c,64c02832,9b6ad395,dd51f960,41eeffc3,b3238764,57d21f85,d8c674ce) +,S(598daff5,aac2831e,21d5eff6,319e563e,3208ea18,e3ffe13f,2bf19444,73292f02,3db66869,2538e2f,e3689a41,dbb05504,bc86dabd,e033fc1,dbd7f84d,dd4e18c2) +,S(eefd321d,41fe6468,a7766276,5932449a,d3956209,c4c6a548,c4392db9,b4e39a97,6a372971,d5515d4e,c691b3cf,e73ccf6a,a491df97,570c9f52,3f29b108,c626c319) +,S(5a3a8225,49ecb78a,9c5aa12a,49e02c5e,10c168ac,e053f85f,30921724,96177ee4,482a65fb,f57726d9,d4ad61c6,75cdd5c3,25b6e59,899366a5,3ddbf239,96016448) +,S(e21f7d4d,b2343eb0,1d23d1c,5ec76db9,89e1e624,2fabc41a,b204ca64,838eee55,fb64c87d,ba7c54d6,f1d68d7f,a49d50b1,bd79d699,a75227e8,4363ed30,430b2605) +,S(fd688c92,f80983b8,496689ae,fcc0820a,a3d91fb2,aa4d599a,f48de5b0,98ed491e,7f946da9,9169612b,dd6ad8b5,d686052e,3ff25610,21432c92,f8728187,29e860e7) +,S(65594f34,947f182,bcd1703c,dbb1ddbc,4bf59b2c,2fff23f4,1d363631,cd54af0f,e8d98a21,a603eabe,cc1a1b83,9ccd553e,fa5eb258,5dc94e10,d134f40a,63b5bb1b) +,S(4f47f3b9,8bcf3917,464c07cd,be99d2ea,adf31166,8199324e,d120d087,e14789e7,279da4fb,d718e578,b10d316b,9994dd05,ffa05431,f85db2d6,6d4327d3,68aac28a) +,S(32cd8b52,c027e4e1,7991ccf5,6460f3dc,1d2ea6be,6434067d,bd4880e8,a09196dc,1d3066d3,76961716,1882da20,e467e035,4ad84041,f391a042,9e94d8a0,5d89807) +,S(c454b400,c7946f9b,b35003a7,c51e8037,dd03fcda,f0a19b14,f8daba3f,310d8bec,dffa7652,86aecb65,2744c9e0,21229687,1c305d91,6279b414,1ca1a,acc021b9) +,S(151b7159,4fce7438,2ac83025,6d98abbb,6ca309b6,64ef0235,53495342,34f7b4f6,fc61aa0d,722156b5,dd7ffd24,38100589,1bf236be,a41aff71,c3f1964f,15978a28) +,S(59716aa9,6b60ebde,848783d1,a686e9ab,e337b87d,104aa3f9,4cc7af46,ea8b8710,2e3062d4,a7d290eb,f53ee38,31dd8e80,354fd671,62a01a4c,73c57fb3,4582d345) +,S(81838542,7622429e,832e7a50,b1a670e1,2a626c3b,97cc69f7,abaadd5a,44a92395,18a88d63,d42e3ba2,af4b6c36,9971b0b9,35363e5d,77417116,b58de2d,8b6afb42) +,S(c95cf1fc,af7dd741,479a54ca,40a0e264,a989f0da,99b3a1b3,c4f67284,c8ae2a75,14b32e26,99662bee,51ad8534,fca1925a,a835cd00,9807c5e6,915b8283,63872f76) +,S(9362c939,ea51a649,2ae2dc2b,c01e4bfe,ccdf4612,97932668,2435bf44,e9c6ea1f,944684c5,2cb534b1,4871f48,41e889ad,933299bb,474b392d,a1e85ffc,5763c2e0) +,S(8852fd51,1e5f5e93,c6c3c7b8,4b0544af,cdb7d0b8,497d4bfc,90cb7322,28a77040,b0ea5bb9,c338a6de,7333b4cf,ac29f997,36c248,405facd2,6ce438f9,cb997a13) +,S(59105318,491ab266,2fb94506,532ed81b,74c8f82e,a13581ae,ef6c0c77,80696ad9,3417191f,bdcc1dd1,43323ff8,6e6051ee,921dcf69,9eda369a,afec66ff,a06097ec) +,S(c78bb701,8e96901d,3f13681e,ecc24df9,65b124b6,43f72904,ddf00ce8,bd28a127,ef07ce8,1b9c1cf1,26108dd5,f96ff86b,e0d49bdf,ad3d518b,1004b3c9,4c79bea0) +,S(9eb55ba5,2b5d11ae,3d419ede,5a5480b6,c2aee921,6f9aeb4a,96e51934,e8e4c11d,50094963,25b94022,2642ca89,1fb4697a,5e643e50,19670934,99937432,f020eaf) +,S(79ca2986,d40c7786,dc4d3e6f,71c33233,ad0b65fd,96822383,c11949f1,ab42f5e1,275db48a,fab1f0db,188e1298,4b391ce,6872e216,85c04c0f,3e62d42,d1e6d310) +,S(a2cf65b8,fe2a7abc,b78bcdf3,f25db18f,432ada89,1ce7d99f,faccefe8,e9673463,418e9be4,f6a1dce9,200823f0,5a6a0e31,7924a0f9,44c18b2f,1602a2fd,1ef13a72) +,S(7f6881f3,9f4684d1,3bf35c4b,c350b64b,28eb3c44,2adf05fb,c5e2c1e0,307fef19,20ac47a9,b954e805,db6fa20a,4e1a04f3,36c058f2,1946aff4,d4c24f63,6bd608eb) +,S(abf40dcf,72704e6c,65502d17,aa384bca,5834a802,62ec0de2,fd46ca2d,d9316ef,f605192b,a8c56b66,f3bdb35d,9c1df4d9,94662b41,85e8e6c2,9fde9d27,45039564) +,S(4fbb0d5d,ada948f6,2877c665,9cfe5f57,c6d5be5c,8cbb7bee,71cc575a,f4c92989,d2290911,45c718d5,243e1ef,92b8f7bc,2c77af95,f8666ce8,15900462,35d1c3dc) +,S(6c62710d,d0ce5eb9,5196e202,7c3c1d12,5a25f329,878b1f38,fa883146,b8ccffa4,c70ee1dc,174a6a4b,908b54d,69c94ec,5829bc8d,f6513c82,b0fc02ce,f566dde7) +,S(83ac175e,e220c800,a40adc87,df8450a3,963015a5,2c9e9497,602f930c,37af6c12,b7dd932,95601178,f6db7b5f,98046d7c,e42371ab,34e5f11,31f7cb31,59d37994) +,S(c823727a,348e275b,f52c18b1,43653c3f,8f0a5c0a,e8f48432,a8016486,ec3674b5,760237f6,2222cf21,fe1813da,4cfe9437,edca8286,cf3be63b,5bb05560,fa71235f) +,S(388b02ce,506784cf,2ec7e315,e765f126,23f764a,7d1ef836,fe360355,cb3f0517,ed0998cc,9069f336,c938b639,d6a74e8c,672a7d2a,2fe1dd1a,d7e18969,e7e57b20) +,S(517d4da9,e25f9eaf,7ab6efcd,cc00e6eb,7bfb975d,e8287b2b,d7d15914,4b7a981a,2ea7196b,a14b60c0,78444a20,2b67fedf,8fd119a3,7a39738b,17694cd4,c0dd712d) +,S(eac89275,54b0f71c,4ee80260,4945c5e5,578fdd50,ad68c478,2295670a,80432bee,dfe1ac53,dc9e18b7,1a930e73,cea36af2,8c8326eb,3615f858,fa1d3884,446f59a7) +,S(f77a0877,e7ffd2e2,cba9f0b2,c419e886,73711125,7cee4480,f6529851,6013ce29,fb245db7,29acfa2c,145011f4,42c9d480,5fcb0be8,b7f27dd9,9d532f6,aee2d57c) +,S(747d96af,94b3ae3,4cbcec25,fe8f4b74,e8d2077e,31ca2520,6d0d5613,3a49bd7e,b13d780b,8d322848,de5463af,3dc9c6fb,4cee70e0,da4731db,14916252,4b6d8d4f) +,S(9bf6ae06,6db68c50,4ef9b1cd,6d123efe,1d8608c5,3a1a2276,f1f44493,f8b5bf72,5b0080f7,694a756,f306714,aa9d8b3e,617b7c5e,84d862be,470df13d,e79c8994) +,S(91d0275d,e99c876b,d6de2cd,481fd72,13d9f6f0,e41c3444,4790dd80,cbc72e72,b12126c0,8b03b040,60183216,d1468246,d32d834c,57e687a8,9ce42ae4,d4eba7bf) +,S(e3cd4480,6585252c,8eb09442,74222016,5ed4cb90,462310ac,ddc769b1,b9a111e2,d8821a94,f1bd3def,434557ed,4739d625,c74548d1,44bd370b,180fc4d9,ee04afa0) +,S(3502269d,e8a68ef1,a0d74a0e,1423de94,99b84d3a,1fbef636,d9f38801,ed00d64a,9c4b6259,8c1bb627,449800ba,d9e93c7a,265114eb,99f9b5,7bca5b6a,72e3b302) +,S(244e51da,a54a3c4d,69f7a53e,6ef82bf4,7907bb40,7713f5e8,84694641,1daa2ec3,61f00ad5,f30928ca,a20cd38e,5af6b3fa,afd4def2,f8433609,4f08e82e,d46a0320) +,S(4f00186b,5d6f0420,88ac1221,a13e3aa4,60190cc2,2bd8fc26,4df81f44,1e508032,fcf58149,b8ab94c,67b30d73,4a3a5835,c7f89e44,6aa8d2d9,291c5f6c,b17b2e3c) +,S(10a96b69,2f522f4d,58d1c9af,463ae371,73e6f72d,93aaf756,6267b3d2,f62a579c,fcc7a656,c9d72dcc,1540a638,51328135,85d3a0f4,ba5242f,f5aa35f1,88ee3070) +,S(ee66c2c,2b19242f,4d7a22bd,df36fe3b,b5c151f7,1dd8a81,93fbae52,23064f9d,9d4f46db,7639d9a6,95d51d1e,44b08d6b,4791e443,744042e5,cc9e3933,cc27aefc) +,S(872337c4,e34a3dbb,f4b274a0,a47c1398,f78ce842,fb11b994,b550e9e2,e21934c2,aa8a7840,d6dbf62e,d91577c8,8b8c6baa,69e01f94,5294e3fe,4ccbadc4,c1d64221) +,S(e2eeb213,bfeb413a,9093be1a,7f75820e,5f48dc34,8515ef1c,7026c116,9be224a6,a49c846e,9132e039,9d66da39,57cebf1d,2e673831,3a89f682,c28d2230,1792d36b) +,S(fe264a9d,63932bdd,5cd4629a,dda37c9a,8d2bbb1f,5809d333,80a561a9,66af74c5,543b7920,c6c27b7a,515b5adc,b8d144ae,64118447,dee21638,1d6cfd2,5627fc53) +,S(13806a30,2d32152f,a1ee8060,67b07cc8,fce1e67f,16f21859,e7b60de1,37debf51,ffcb1150,7be5c2a8,90237923,5335b575,4cd83460,423ece53,18be988,c7e5e978) +,S(db67e361,f9d91cff,1d8b99db,b7bd2584,f1b91cfd,77473802,f603ee9d,debf4dfe,6407a133,7604fbb9,35fbdfb,9fd6e2a4,ea6d8f28,a63e7524,172cebfb,d3331e2b) +,S(606d4f47,d1d4cc58,3e30f214,e1ee57cd,98e68b6c,91c852ad,cad6c32c,989d8bd8,81911891,8a074dd6,ebfb95b1,c97b4fd8,5ef0887c,15ae5e88,ec6e97b9,cba46701) +,S(51d60942,e93fbcf7,e230c116,77528c0d,3b63f7ee,64c1da65,692aa91c,af482ecc,b82db22e,3f104807,6338369f,d77dc11,d982296d,e630af66,36cedecc,108ae433) +,S(2553006b,b8474473,29108ffd,cfd9c91d,22b7ad2b,6a0e7bb,72f98a0b,770da376,6173583e,e6b238be,ff3cd6cc,9bba1b48,d89dcf6f,481868dc,773eea98,59ffa871) +,S(52e35836,fb0a1c1f,efb092fe,3c95bb32,26bf9aaf,50fd1ddf,29ef0ba4,b100d794,639078d1,cd1cd22d,135ca950,d754d3f2,bcd11a95,91abb6c7,c4a5177c,53adc86f) +,S(332e02e5,5c089c84,82ee9863,a4dff4ea,b01a7a83,4747ff83,512fb567,7a8ee3d,b1edbfc7,9c1f9264,10c4cc3b,8919b4f4,e89bad8f,34135af5,f16b1c66,9a28b87c) +,S(d9113a61,7d5a4a75,2080931a,84bad37b,ce2f907b,cc05adf4,16750e8b,8951435a,ab1f66e5,8d3a5887,2f664b56,6c2468df,f9d4d76c,a73111bf,57e10d1a,f7df7aab) +,S(71999a85,799030fa,b0575523,fab4111c,f4b60351,e03f8703,1f5a852a,f22131d4,eb171070,d6124255,9adbd82,565c8dd3,fba6b8c0,df939501,4223b2e6,148668f4) +,S(a9436d74,a39c7193,368ccbf0,d24098be,41309668,87ebb8d8,4213e0b3,436c23cd,7b93ba5d,e2ad9b42,ac45ac85,43f7ae59,7300e745,8fed1359,bc392015,540e7a19) +,S(f6288f25,57359179,cd3659c6,1cceef6d,c5a69631,174f63ac,115633ef,83530b2a,d54f0f2d,51a365dc,7ba8b630,67ae663c,b4102e2c,59cfa616,b8878483,6ca85722) +,S(bf685c41,863c9fee,dff2fdd4,ba47d726,1f0fcb6f,b0432a8a,3b7c4f6d,6f52700a,336b1d57,43ca6d28,52e20cd6,ab276441,61b2ed82,ea4e0051,d88ea92c,a66828c7) +,S(672eaa18,1009f3da,3fe74eb7,4b479e24,4b73b54f,206f7342,eaa865ee,f945b00f,3f056594,a113cd63,810adf1d,b76efaad,babcd42d,347282c2,ce66ad54,37cb89d0) +,S(299deede,3b6722e4,4c5e7600,214f85aa,4dd70ac9,df75cfe6,c020ec58,c8c859f7,92ecac9e,4a6326a7,8b01c0e3,6466723a,3d00593b,6597b6e,e16924cd,60105137) +,S(e4268a68,7e6c26b9,2cec18b6,8581bf03,8b25544e,2040d505,7b9823b8,b01c07d5,35d1c370,95a9cc03,f91db5d4,250a904f,b9f9daed,9388b5cf,d6a3699e,b03c30c0) +,S(7164e9,bfa6ade,a42bcc27,db38cf5b,fe908499,eda21bf2,27063fb6,369b1ae1,a2367f94,fe683e07,1cb7ffb4,287cce88,b11336ca,98e6769e,178262a6,b9103d9b) +,S(84d8d32,a4be7402,1c94d3b6,c0913724,b2db26fd,862fee1b,c467a37f,b98b299a,46b92145,46603cb9,1cd5ff05,a237079a,e290b496,19d868f2,8143d660,94e61cf5) +,S(60372ba5,d0eaaacb,c1445979,74a0553a,6e63c4d,15001b76,39f5d05b,84f626dc,8fab368b,c4d011aa,edf7d98c,2e6a0359,5737b1bd,bf701060,d30c9f0e,a8e8c847) +,S(453c17f5,5364f812,a7da0f75,d7c074b1,81cc0901,a938447c,df55ba92,a7decfbc,53d465f2,6d3d86b,a76ad1e6,f147d208,474989a4,64ceb6ce,79972cc9,3e2e2c3a) +,S(cf1f79b4,b765a894,2b967271,85d0c2c4,dfab4c4d,d679693a,4b35b343,c411cdc4,b89916ea,4ea34abc,63b9292f,591b5c8d,5ce802df,9d4f2be,275ef244,7e1ece) +,S(74b07994,b7fe3a27,eff2f9aa,72f8746a,299f9eb7,81f09b15,f3ae595f,a0c4ac37,5464345,f4873a6e,9f4cb569,acc8e551,a9acff9e,5e0a92ca,e2c3f800,1888f905) +,S(f9de1544,89b7a06e,40115de1,fcb7897a,f6bb2b91,5a1e8971,8d5d5ee8,68bab74f,789b5c55,2b352db3,4345ca30,328f542b,ad22e5cf,d98e5b8b,e85646e8,d47a0e6e) +,S(c011f3d1,897cfe72,827d2cc7,c04a6aa7,496273ac,11f0df10,27ab4d69,aa745c5d,8e31fcd8,3842ffbb,a600e771,feb0cc2b,1fb257ab,7c19fe61,67802313,cdec95ad) +,S(16567ed2,4ea1cb2a,15418d66,c70c0587,386201f3,4dde86b,82f687f,95229648,fc4aa805,45366f8c,3ee336f4,51397e3,7f78188e,b6dff3ce,d80c7e7b,6d9f7cf2) +,S(8cd33d56,9acd3607,979b3c17,bf5c2175,ef6f3428,7a25c18e,89a1b38c,979d50e,f4312cbf,f301e942,61b7da0e,cadda424,336b1201,82ad73c3,c907be8d,840f8614) +,S(646e22ba,39927176,4e1df1b3,16767718,79d7a16d,587b9e47,5232a331,42ea2a5b,55378afe,5f29feb3,2a3152ba,4d83305e,f77b1025,79154aeb,7bb8b8ef,c5958576) +,S(2699d984,462e1fa6,208a833b,8af2e32f,58cf2d02,7707b4fe,2e3f888d,82e8e2fc,ed6c46a5,c5121755,5f236a62,21399a40,5fd87fca,f4cc6603,fffb440d,54b888c4) +,S(be4b6631,3fd3e2fb,163530c7,2fa4a41b,e36d04b2,638315a9,1d07de72,c4ced54c,a7a71077,83a27b72,4e8aa644,a88ea181,c770cf6f,489829c6,6660c44d,45fd2ddd) +,S(1f2ad69d,a1438b51,fe02a47,9cf865e2,18bdbe01,259b0818,1b6e7e6b,762a72a6,d4da99d5,7aa328df,3c587a45,2d756bae,fc09c626,fa5516bb,c8781b9e,b1ecd29b) +,S(b1adb241,721a1622,35540622,f8e84291,e1c2702d,70cad33a,89aa3806,f7acda43,e6cd9324,12542fc4,25b8f16c,c0820f3f,26f33e11,1ba0ca5c,b5aeaa54,1fa3d9c6) +,S(b604e2,f06df266,1163604f,2a1941ff,4d6991fb,84796c40,ccbe74e4,cf68e207,306936ee,e887427e,6005b265,38af5ca,53b3cab9,a3aebaaa,96556c46,7db96e88) +,S(afb935fa,1e30617a,9b4f26b2,e7b150b3,f33566b4,7b5b4a7d,6223fe3,9c0dced3,83624f43,66dd82d6,8e4cd94c,464b6322,db0b1774,9fa1125b,a0944503,b0c63b0d) +,S(5cc7252,a08ff892,93022eca,b56a5e9,cd2eb4c4,71161d15,5d7a5113,8b12d235,c272b6cc,42461529,b31943fd,fcb51a59,7a0eaec3,ae8c2754,827fe1ce,a182bcc4) +,S(6c17c206,7c72a1ba,410f2446,e4ae2012,6eccaf88,aa4fea14,522a7607,143c1122,7172af08,2adea428,2f6a3cbc,7946db2f,c0170975,50ad8ee7,f4c514e5,dcd693eb) +,S(fd82afcf,c55d226b,274cd62f,385e882f,716210f,9a14be15,baf7e17f,b98eac8,4aeac666,a1153851,6d66390e,6c7818d3,3de26fa9,3d234eb8,5e4d5b42,853eb3c1) +,S(3d0121e6,c758dc91,8ce3bbca,1884788b,20717075,1e80742c,49b202d3,c2f8012,ca6b47b,306cef6c,662bf21f,77bae3c4,25009561,72dfc630,e2b1a6da,e733413d) +,S(488306dd,3bf3bb5f,24160f1d,67b8c053,bceb8da3,cb1b05ae,7ae9fa72,e3f7b0c2,2356a8e6,77ae2f06,6135bd88,1fab5b4c,6aa57769,3e2d476a,1b2a4db7,fc6c27be) +,S(d7e91488,6786009e,eaf12d14,a23ec6e7,fe41e406,aca5a5b7,47010ee8,8441d6b2,c98389a9,143a8fdb,df4a67d8,7c05cd4d,fff75fae,845e7e62,26c61aff,3dc4dde6) +,S(873a2877,9c45280e,3d196725,5da756d0,ee5ac567,cbb7c52d,c8e654a7,ed78a1f1,9bb9672e,e76feae0,d52be301,983c182d,ec99b228,defb2166,5310a4ab,cae7eccd) +,S(410a7c98,85f531ab,46d99b26,b6fc2576,97723e4,bd9b9c57,6544542e,2cad2ff3,8bc9e686,4f139032,cd443148,4f43abd4,3234e3eb,3825a0a7,db8176be,cb5207cb) +,S(39269060,b38b4abb,107c2230,6f541353,d8627901,3399b368,8b650ad4,cbf99144,780c2949,aad303f,ef8fff3f,b9734551,b45639cd,9437935f,d93f7d95,bc9d1aa4) +,S(bbc52d26,36e861e1,3e593d4a,c6ad573a,e4698ede,f101b3e4,f4aaca54,325b9f9,4a311f44,9f16bfb6,4c5c554,5ba373e9,fc41b7ec,beadb4a6,a929cf0d,79f37922) +,S(bb74e659,5ed6d931,9716b8e6,120f0cb0,57dcce87,150cb26a,cbdf5b1c,f86ccbcd,9f2385a3,bb460cdb,8ec74db8,fc5e6014,f4310665,c5b69e1b,cf96203,1afe085) +,S(67e64d65,badbd97a,bb204cb4,f9009f5a,973700d8,34f6b6a5,395fbaa2,c6eb0672,a122f76f,67490b28,9977d730,df544f7,d725dfd0,93135ba4,4bb348c9,e4dd3303) +,S(dbd294ba,e0775f43,f58ee677,6240eaca,b9b29ceb,92fc3354,de4d4b20,95548050,1987ba2e,3ce8ef0,5b71acbf,4c69f706,e2cb4d6f,354f0fc6,53a7a9b9,5dd1c115) +,S(45c946f3,93658d3e,589fdcbb,6895c97d,60352342,3a3676df,680b6bad,de6cee1,629c7238,db2cd3e5,29e5b30f,a8ba5629,dcbb1ccd,ada1eb22,294f98f0,4cae2d00) +,S(33ad0e14,44be7775,3fe47875,2688e384,2be7ae06,7d38e473,6b7dbe0,c106e14f,d89eed78,6518775e,1ef441d5,fe51c4d4,b2a1e377,eb1a4cf7,804c2e1a,5175f1ef) +,S(f9f78161,4cd463fb,6e358274,e47812b,4b0113d8,3f426aa7,85756c6f,b9e7853e,5eab09ab,51247c76,f87f592d,77e0870,238877dc,a47cf6b4,5fe72940,ff4469a2) +,S(ed3015a6,7a1fec82,f0f7a59c,45cb69ae,8aa0d883,39a05f,f6959c9d,b7d761c5,b7c94a9c,28389f1d,17bdf197,307411fe,1c395483,da8a097a,fb3b5fcf,e392e16d) +,S(301af330,de741ec5,61b71fc3,c5048a42,6b55d58f,800934f5,c59aa8f5,914092b0,3d3137d8,262d196d,872fe1f9,8acba295,fec02ee1,30aa4c19,8c888765,357b67e4) +,S(21e197a7,85953a90,226c1ab0,441e35a0,fd8444b1,92c0e5ad,65588063,f40c1246,6811f94f,18a9569d,4df2ffa7,fd8d75ff,5f66ad1e,62da2a60,c0084381,4437a2c4) +,S(325fcc8c,27804b7c,e73d6687,70db7f5d,3ed4b6ac,feb04003,c61d6262,8fd41385,2110e8d7,24e3a03f,46183536,b208b595,8586202c,2e69b954,d3ee1500,21ae7d8) +,S(48597aad,ec69eb0d,90f60e6a,abf83129,1de759f5,eff24d81,8677248b,ea87d945,c3fd850a,cddc2597,499be90c,24e249b,328728ff,5443fbd5,6515a6f0,4111775d) +,S(58648599,8ac44bd2,e937796,d8dfa60d,c56d94c4,d53cfb77,ee0e380a,53ab8f76,2f47f278,6a285454,475d3c9,ffe9ee44,a93e15cb,b17772ec,67a30943,d3191110) +,S(bd2761c5,722288b1,409aa7a5,db7690d2,73dba76a,3847d94e,3e3d3a7f,2dd35597,42590713,6ab6745d,5e573412,663d4d93,29c4a284,4430899d,68e5ca64,197ad58c) +,S(fac9260f,1d420371,7e468769,1af8c270,dada5d97,5ceda9f2,64deffe9,1990b52a,9ce17c1,ebe94ab4,e092d1d5,850194d1,7e6a87e6,7b283ba4,ba68640a,94193314) +,S(82e65b52,e4585ec1,4bc03591,249cf4bc,e5391f69,7b813175,b3b4b403,a64d6877,627e196b,42d327be,48526318,2dafb37e,222578a0,ccbcc443,7941eca4,a82ac893) +,S(b9473eb4,dd002597,464965e5,b6d95842,543cd14,e18c95d5,b45bb654,eedbd6da,1b6e80a5,377ba31f,b5b6fcac,633321e7,f6e5b2ad,4a54e143,e963effd,6805c3a9) +,S(31113d99,4caaea40,40182db0,17a880ac,64b183af,1746b820,2f29fbd0,d1bcc524,3f476b72,eeeb7c27,f9d04cba,71ac54aa,a25ec4ab,15d77e17,8544a651,653e83ad) +,S(d04adc5e,73e21fc1,8c3b047,4d34f8cd,1cdcebdc,5dabf14,e258af57,860157d2,b21150d6,ad94a07c,d11a81c7,b741a2f0,5cd6a5ae,aba194ce,b874bd19,bfb6c326) +,S(4e59356b,f280f51a,c492751b,3b3c7c2e,3fd1fb58,679b4fb5,5abeeb65,bce6ac2b,33a1ed9a,1d9c34c8,42b95e4a,108c7985,21c1f06,91f3716a,68fa5c5f,89dc73f) +,S(53d76685,9ddc778c,b4f719ad,55f74fa7,85d52300,65c06b1e,4aafc560,39ba3547,168b5451,29170fe2,c53abea9,68a25dcc,2719090b,e0814635,a1dc7267,9d83a01) +,S(7e9107a0,d2830362,7e53e06d,6e82efa8,b1a037a,328df546,a6d04c30,3037a63f,222d8b81,2a99860e,87fa24e0,aaab4ddb,b903cbe6,39c46cb6,3f2144d7,f8856489) +,S(6775b2d7,b23dc08a,beb65049,db8552f5,565a092f,fad86865,c17347e2,a744106b,a6f23c87,fb639e66,9830ed33,34c6dd42,6bab0e23,aadcff44,1d4c73d1,a61efda4) +,S(559885b6,a54fd0dc,b275662e,f66566e2,87a17219,e9c02f68,8c1cc8f5,6f814673,2ec87df5,917d1d7b,f217621e,82c31844,d2bb138b,bc35f873,5b52309a,baf800c1) +,S(6fb774c1,2971b620,b40a17ec,74dccc9a,8c711844,a44a3e4d,e8310d47,bda53428,68ab0f6,57b823e3,35df55d1,ed9632a8,f0825f67,8a05d5eb,9e115ea3,e43ff4e7) +,S(623c155c,2787396e,815ecfdb,5f03bdb7,282aeda1,7c9298f5,306ec10e,21dd0b90,69382be3,a4bae926,47252910,ad1ec62f,f4bbcde5,6259cb52,10ff2158,6b111f66) +,S(c42c41e0,63db66dc,9b32c21c,af94a158,14fd5b62,aaa975d,3ca06925,f6d6ecc2,e93159a3,ad6fbcb6,38f7b09d,40601189,cafbe5c5,90c70103,b56fbd47,d36ccfba) +,S(1103e98e,7a1659ac,4242ad9d,6fb012d9,21696e58,413f71aa,e19fff6f,1c334fbf,9f2d4667,ce5a1285,524d91d9,265d7a5d,da9f5ea6,cd508cf5,90076d57,a975bc62) +,S(9e113cd5,9e7177b9,19859144,598263cd,630f72f3,4da00ad9,84964043,9d82878a,6a09bef7,6e13f2f6,8e70ee90,5dd5af4,495f5965,859a1d83,ef149f67,2643c9f7) +,S(c03c5ebc,d04bf8a2,bdec182b,32d8c726,1913652f,e4547892,3e0dba7a,1fe275ed,f567e3c7,4b9313c4,11ac9411,11f1b62f,74a16f79,e7d90817,b54d4d89,958cda21) +,S(205c4c44,7b84661b,cc8ab2f0,221343f4,140c9efa,fb107c59,b5095b48,25f54b24,94a10344,ac5f48a3,600309ef,8ef94242,a8050865,3c018e57,a7734d9e,da18a55c) +,S(e393821a,58c9e9c5,6e45cda0,334bebc4,359c4b3c,1a60bab3,f1dce2de,c1da81b6,5469cb0f,4edf5f47,80df616,3a6b7074,7b26291e,8830d113,79d84aa2,15814e6d) +,S(38fc36b7,a866b165,a424f0ae,74ca34bb,b05922d5,1bdb447,5df797ad,4d042e2f,a9279b50,4b3edff3,aa8fe039,3415c21a,556609bd,8089383f,f5dbdd34,291c2b1b) +,S(1c4a1aac,3c3247d9,99a75a00,305a4092,c5f34321,d3a33b66,b110331c,85be2b27,a10e4138,a835e3b1,16d7b6c9,46c752e8,dc92c39b,21677968,147a3cab,fa5a0f1) +,S(41d70c82,207c3b7b,716a2d4f,784302e7,e1034555,a79965b7,d951ebac,b7d62c00,7311a36f,cf3de546,37013e84,b2162c35,3eba0387,3d296427,220e5942,af398bac) +,S(bada1cce,dcf3dfc,9834c49d,200fb82a,b13cf2d3,d5da9ee5,c9c35448,352e660a,42e0d3db,511cbbe7,942ff10d,a7d49805,972d9373,a75545b7,206e490b,6c5dc651) +,S(233c0c68,4b9fe726,baf2b7d7,a0503e,7aba8b1b,3c4f28d9,4d095107,2b429bc2,a7bc02a6,2b81154,c3bce0f1,6a0b4f77,d412d162,1c713372,11ac1c61,a8f6fa28) +,S(a675f208,a0d48078,93525e1f,b6c5be3b,ef24ade,8d3ab14a,afac550a,fa6362cd,3f8edef0,3e0600fd,1fdf10e7,c5562ddb,af4266a1,52bfca59,e1235d7,c9e8223b) +,S(4adffdf7,a8a92b65,6f747fe2,92e6bfd2,cd3deb68,ccfd7f01,5639d779,7d21e48c,4d4079af,a6e89720,3a50015,92e43c6e,97fa1e57,11f21bef,c9df4274,441f7d81) +,S(c786e96d,fa658a6f,a9f1fbfb,a15d7021,835ebbb4,3e8ed3a2,c7ea573,c2944dba,81130470,7a10b1e8,74f5b856,b7223346,eef3c562,8959454b,d536494a,f075393f) +,S(10df82c4,64b75895,2c54f335,6fc24ace,cda4578f,d34ae82a,8a1eb2e3,d0830349,dae5c271,86031dd9,2eff2db9,6af91689,2a131cb2,44534495,c3562cb8,dbc5e1b0) +,S(55532c4c,c4483aac,26b049d7,df1da7e1,ef281c7d,bd99d21b,72626443,f2c748c4,58160e32,da446337,d0642596,c17500f7,b0e64081,1017bc1f,4452c4a6,8d2c2789) +,S(fe994c5,d63149e0,d31f6cdb,fce5b941,239c4adf,8d5e6866,37990411,d88ead47,200532b8,4ee2fb18,b2c27cd5,9c3940f3,58c6a2c1,d96ad043,4d826c8c,2a457dce) +,S(c7690e5b,3148cd96,592e654f,2eed33ec,a69d2684,545cbadc,6f6a7e8b,4d3cfbdd,98e0018c,36423854,6dede771,b78bc4b8,c52d956,d26eb22a,e447ab3a,144cd394) +,S(8f1f0986,d273476f,b31d4ddc,de949584,97ec74c9,acc6b0eb,900e4cc,2c98cac3,31f420f4,b9209657,1656b663,a06804fb,78597071,6c138106,119ef214,43aa765b) +,S(bee7ab1c,c23f6101,be01ed60,574ffca,70fbd4db,ae73e5c7,128da065,9f78c042,9187835b,66b2b634,a87d1baa,7666bda3,57dd5ed,26871976,8e0ea9a6,ed102dfc) +,S(8093581b,3205e5c1,90e9d38b,5b5ac422,b48fb5a3,9176bf7a,e1d377,c764f74b,3a3e06f3,4c00cf7f,6216e67f,2d55236d,db54640f,192897e9,fd68820c,bf22ce39) +,S(fc018da2,70dfe007,871e0be7,f5edfb7c,30fc30bd,bed5052c,78a7701b,50954702,9483d20d,af9fb123,723e0c17,7905e94f,462831c7,dceb0238,6f0942e5,188f3a90) +,S(f4ca4cab,7f06af06,d0a8bd7,97d6eed1,7354420d,65d80e09,32f6eaf1,ca12a39c,76770553,69f93094,3f368b0f,2ef6e412,f3d5a45d,1c7edc3d,9550fdd4,ebb1950) +,S(fb03fae2,87265749,787de276,84bfdab0,4993112d,f384113f,1dd41e6a,b438bdf3,ae8829f6,80f60534,50113930,2aba238b,1dc295bc,6598c060,af8393b5,1153b479) +,S(b76268c2,6b873f54,9438a569,5e2d5e24,a92da29a,ca26f18e,143e3290,69638a45,bb4543e,23abdead,c3377320,dd8ffb6a,d38967ac,ea90afd3,23c69373,eeb2407a) +,S(87db8064,9a5a31a6,487893d,f487c00b,143c09c8,fe878621,b592b25a,6c3d8646,872a4547,520d307b,a537d42a,ffbc8e9c,e04d1c80,e3d4f506,b001b0f4,79e92972) +,S(fb9295d5,a7c2cda9,c08b0f39,1fcdea4d,b768b086,dd170d8a,966516fa,bd476acf,62496929,a85c828c,cda71d2a,ae70c429,7bc12f03,5a99ff75,7d66cedd,5fb5135c) +,S(96f749ed,a1fc306,6d133829,774293e0,b179a598,327c3bde,a2e94200,770d12ba,c16915b8,af011de7,614fda0,ce1c4a3,ffeabc2e,2e891e4c,a2d9c277,247fc8c1) +,S(1564d7b9,77b4eb29,e7b23ba7,a3cf453a,8eaadc50,87448fb0,fd9310ec,653ec66d,6d8935ef,a7d41cb7,5c5dad07,c3ca864d,89e49f0,f74d4474,af85bf05,c408009f) +,S(93db7b68,9ed6ad1d,bb61223c,dcca7280,9cf4a49a,14d94f3c,7cae77c8,f1298340,9088165,7b4979f7,26b156c9,d34430db,4a0af993,eeb996c,d091ad5c,4f7bbaff) +,S(2656af7e,d8a2e718,9849cd,793baf93,1c23374a,a3b5596,d8c88841,2b6a5ad9,dca0f4b2,7c7f1547,97346dfc,589374d6,1224048b,ead5442c,9f8950f1,63689045) +,S(a7dc8558,c0adf996,b7f57c08,1b509e34,7819131d,42647498,ba819c12,6d26cbf7,9fc494c9,2bbf6116,14527eaa,1de4708a,f0c19847,3ee9164b,6b9de909,f6a4497d) +,S(1f6d4701,effe09fa,17ecc014,a7a0033c,143fbfac,ba4861cd,d7ee2fe8,5bcb2cda,84c5b017,81ce481a,e610bd8d,96ffa58b,b7a158e9,d1cccd79,7e6436dd,b1308de6) +,S(eefe37c5,d547b779,d905849e,dd1038b,f054233b,f2d1af47,1684e5c2,a1e69960,b5f00dee,8b1f7960,aa068db6,78b6b41a,f8c3e14b,27c1f43e,10f9b34c,fe8eefef) +,S(8d4e8462,60602ee0,948ba5c9,f0506046,d0bf3fd5,e1b93073,bcc8a6b3,30af96d0,62d0e36b,bdffa309,f1257b23,6327506,5a5e7999,b314dbed,edc75800,b35534ba) +,S(da22079d,352d3527,5a80b95f,80b7b8b1,3eb6d178,310b6889,a94cbf2b,9a9a898,e8b06b65,37aae428,cd25fae,d0c1af8b,827b296,886de122,c6690a19,fe94df72) +,S(beb411ff,67cdbb5e,58da6353,172813fe,e386c7,95550395,1ddc23e5,d4e579a4,919f8f30,41f53020,4d3620bc,b0bc80e5,9d87ab73,355c046d,cf2986d3,c9995866) +,S(b0a5732b,76b4a526,e8e742e3,528891c7,3a1febb5,c7657a90,4bc1f95b,96d462b6,a5e4f134,93f9e24,75ac7dab,479092cd,fb59a931,dd042add,3d875e22,76965a9e) +,S(5a87a782,13130193,4ce6180b,714e99c7,30fc8bd4,fd4e8c59,f5b6aae2,f3622561,a929d120,68a64953,90c559f1,ed8ff0d9,bef92431,66117208,d0e8a08a,de9a3d0b) +,S(777ba7aa,6c50e927,64ed93ac,daf56285,9909b031,7c3c5ab9,38ebba26,d62a1748,27a32172,d7ff61ea,b6a26d00,c252f99d,bcf614af,1434641d,cdbd5f4,10e6657e) +,S(ad0f9f5c,8fa07d5d,3c18d4a5,7dc16bc6,3be0dac5,9166fb42,6bfca8f0,65b76720,d2c9c778,3caf2c93,f6c3980e,60ec0fcc,1f1d5ffc,8aff6af,a912b5b4,245fff6e) +,S(8904706f,17aad850,7a71f0c0,94f981e0,5e5a42d9,7f5cc3ed,99b4f635,660e227b,371d5f58,a63ec71b,3cd8b601,ee622586,2822a2c3,99ac70f4,ce293846,23ad8198) +,S(ce32a220,2e276dd,3f5b0a10,38a70f21,3c29ba7,58934c4e,27ee3bc3,c9dadf00,e43d28,80486b34,65e545d7,6618d80c,56874afd,29ea4ee1,e79dbe5b,b1ec1f42) +,S(3d031c0,c717447e,19266420,cef08d59,ac2aed4,7e84c84f,8980e8ed,ee59c7c1,86eabd82,d6a5f57e,cdb52825,a8c726d5,4a9faba3,6272441b,22627c4,a321d970) +,S(9dc08947,fa3983dd,44730aee,d8e94f2c,78eefc44,df126804,281f740,53330b43,58838246,3fc02261,c0e771b9,3d4a90cc,c2c19f7,2893ffb,22fe6d5c,6c5e7318) +,S(f9fb51c7,29646acf,94ecadf7,30989d5e,669ca4fb,3b4dfe66,dad9838a,f239057e,d4a04a8f,f44b86c3,17ce4350,1a2325cd,46b5decf,5f4e14e7,17ef0c30,1241f8e7) +,S(d4a1c33e,816419c1,884c2838,abc7148,c61f05d3,71fe3de8,9f06b580,cc5e1006,28d8f049,a1daec88,5d186da2,66e2b8a2,893d90c8,5e720d03,a53cf8bb,f8a10208) +,S(1b1c6ab,74436126,203ffd8d,8e9c58b3,e18f2767,3a72bfb4,ae4c9e25,ce17c570,ad28aaa5,eaf7128,fc8788e5,b9c1c13b,a4cf16e9,f651da6b,6c43fd1c,cf2903dd) +,S(3d791154,b2c062fb,e1f6ad1,dcc17bd6,b648aadf,cd573cb7,d29f9e47,e089e1c3,a578f2d,a568b0b,e95e1189,7bad8311,3098787d,62756c99,7dc3d795,8e0d3745) +,S(6daac2f7,ee7b01f7,277b3a5a,44785b4b,c6b6adf9,b112dd6a,227b2b46,9f27940a,fe9504e5,75c1e349,9267624f,2b2e603,55befd7e,d66d7fe6,80c521b5,e0d1aaab) +,S(ea6343d7,73a5966c,2ea66806,ed59079e,8b216a9f,4fcbe8f6,744808b3,2478c26f,15ab94e5,cc1f4a5a,33955f6,b30571e2,5104c615,c0aef2bb,6a8f6693,64639f6f) +,S(ffc78cf2,4b436203,dcc1b892,c77fb336,463a8070,332783c6,1824acb3,f5cc55c,7bfe0b6d,666b28c2,3259c4f9,2c0dd94b,fcf53921,91d617df,da1c651a,1fcb81a3) +,S(db38103d,5156c309,67189677,9317879a,f31dcfa6,b8d0f5d9,1f2bc691,6090e6b0,b5b3e45d,9bd41082,cd3115ff,824ff027,78f47a0b,d0ae71fb,32c48d72,cd540c84) +,S(4c08de87,abf89885,2791b455,126e7e54,d660903,f407b842,7b4fcd70,53e0b000,a9f83c6f,dcea99fb,fcb301dd,c31146c8,25c02978,6e5019e8,7b1b6db0,731b9189) +,S(53b6a23b,8f93200c,41bf45b2,bd0d20a5,e6fa5db9,a3686a7c,c669815b,993604c5,31bbf5d2,21023fc2,fef75f0a,f7bc33e,b4d38323,cbdaa511,c40ed497,ef42a850) +,S(b39ebc0e,53b74f35,6f573a40,1df6f8d6,fe1e4fed,f7d976e9,949da398,a45b464e,9d58ae16,a633ea0e,86bad1de,39f0b203,c1ef0b24,b5f1d824,48fc606c,a97fdff1) +,S(182e4920,f4a60741,a0b94fc3,e3ff0bef,39f1d459,cd6c18fb,16b072b8,de0bd416,6d048d0e,ffdf4e60,8097cde5,46955541,491721a3,d6e051ef,9279c5c0,22a32fb6) +,S(7a39e7e0,a2da209d,8cbb9797,5f12acce,840dddfc,5acf7c5f,fe778a11,829e1003,c24aa083,20e6a786,1c161e14,f37b1c7a,65117e55,2c252445,20b47b67,66fb410) +,S(62e6173f,2273d3ff,d9fb640b,87d5cb15,e5df841e,3462bc5f,6b94575d,a110914e,7c424010,4ba37e57,48404997,689a01cb,851343f1,ea8259fc,938483dd,d70ac5d4) +,S(3960d4cd,96de0126,5c2cc88,68e94d66,40e9ac8a,f2abfcd5,2108848c,ad62467,fb24aaf2,85a54405,f75db03a,464bbc29,3bcaaa44,344c763f,dd44656,fa7faeed) +,S(463437ab,42694ce9,98ac17cb,fd4d9034,ab7a1be0,35f911e2,864441a3,eff8e3e3,370056b1,24b894d6,3631087b,194dc5ca,fcd2475c,a95402b8,418f1954,d47599e8) +,S(65774018,fd428788,e4234b36,42c8a354,770ddafa,c38040e9,49f194c0,ff7ad3a4,462ec7,cb17abb6,5200a88a,9874c7f9,40469a51,c48c1fdd,6c0938ad,67741467) +,S(738feb40,e7f16fc3,19ed6649,2507406e,6501308e,5112dff4,db9d12d3,bc0f138a,4923678b,84470212,cc5472de,2163ac3c,51ed5419,dc1b1b1e,78dc0946,f730b940) +,S(546841d9,7985d80b,a0eb3448,3dc5d17c,441b7eb5,d24b6216,ab98b14a,d320cf36,719434a4,952ee43a,b1006ce6,f7785734,c6a5c018,383eed75,e3660f7,94eb6829) +,S(31143de9,1a4b96eb,be7efe31,56b6688,5d39ce66,fa8ce202,57626dc2,8557ece4,d8d8bd18,36e5c388,2273143e,721bef10,b0c3005a,5e2fd3a7,e471ae33,ebfae7be) +,S(ad8076d9,29feddae,a52c009,f3967726,a0a94301,dfc12d59,da63c47b,df6566fe,39eedd66,13fb7141,796c0353,9f560ac,e23f844f,d0d3d422,5b36e41c,b6707602) +,S(b01a4f7b,9362be2e,78f5cdbf,d9e35f21,4d296a3f,3e233d93,2cf33c71,95b3f613,245b535f,c58254a2,157caa87,38e855ac,fa9b071c,1b6182f3,5260da9d,18e385cb) +,S(50f3458f,a781d513,a944ebd9,6f6b791a,1b0cedec,1421f9a0,16a7f350,2d5f429a,4972c646,c1ad5958,18766bab,5bf54ea9,e9c4fe3,19810f1e,27f46cc9,41594045) +,S(d7b606ed,e8fc3a20,925e0a59,5c9462d9,4e04b5c2,b64d13cc,19a47d1,ccf10b0a,dc39a8dd,d5447a0,f07b5e7a,6ea35286,ec01679d,ffb6eaea,6222711a,d57cc63f) +,S(7629836b,73691a1f,f3ae6c99,7e06f597,34fb9625,2d1ec88f,2af15cac,f89c199d,296e4034,8eacfd71,7f64beb5,76736398,62114296,5fc818a3,ea89ba52,1b1a410e) +,S(88f6a162,7baea31,3a2a5d5d,aeda2f4b,4becca6b,812a60d,4b5b4e22,6c822a1,d3acfe53,d6189ab8,31106ca8,2388fc28,5b567e5a,5172050,5be56bf0,187534eb) +,S(8e93c72f,cfeae58d,fecd373e,dd3f31ab,3e4fa28c,f53681dd,ebf37d40,c376283a,e9c82571,2d0cfc0d,e6f35e77,acf0597a,7e2437e2,80f13420,cbe93acc,52901d71) +,S(b2264df0,eaead63,111d7b05,8767cc7f,36d386c7,edf21792,e8aef135,9958b2bd,242eccda,5e4324a5,40e8d098,cad23ecb,88955bb1,126314fc,5da973ee,b1d83313) +,S(9f1c9e90,7a6813a8,da520f6,84553a4c,aab650a6,7eaf4f0e,f2ec212b,95a885ce,416dae6b,f47aeb47,453fd0f4,7da6375d,136b6ee2,450bfe75,504f3619,84a0f355) +,S(dcc7585,132b95e6,a4a24450,d557a0fc,3ec93506,fd1f5f02,17bd0f7a,6943fa1a,c62ca95e,d976d1e7,2bcad48d,9bc3a316,a35e8496,952a7a07,760ecbc,8903b001) +,S(e3c674b1,eeb380f3,f08b1d64,32f4dddd,77cb602,915ac478,4f3c769b,dc2a30fd,fa8b08f9,8bb4a1b7,568c9d3e,754292b,1a35cede,1b377c99,fcee16ff,a16bbe5e) +,S(1152da70,2b7341ff,69e8d3e,6f5ce8d3,bdcd3a03,27df54bb,846ac8e9,18e747e4,7c139d20,1e2ea5db,984cc8d2,4b66c64,8adbd0c9,48c0b085,d59c73ce,b4d7a91c) +,S(3449cac4,abbd3ae5,e09dbc5,c89258a3,df93ead9,1f62fad3,a5add3f9,87a2f83b,197ecb64,5dc998fe,eb9b0df8,6267c7c3,f7af9647,96fea60d,88d4de89,33171e2a) +,S(ad5cc468,11c5a39d,ffa313f6,578acb00,cdda9ce,b3757479,9f2afd6,a8df7a19,4fdf6093,c8fa8a92,7702982e,7e638948,b982d84f,ae6658bc,fa839354,6d6e76f4) +,S(acad447c,b57e8f5,f528a113,347e5c5a,2097766a,b4664c70,3f496635,759a7799,88e1b4ff,3bf3e967,d2c6c948,4bb727a1,d13231cd,acc45463,d421431a,b6fc46ad) +,S(b74286a7,e2699aee,9802563a,4da514cc,d74fd001,48534822,9214395b,36158246,8df2b491,ea018b23,b1c7fb54,b7a05db,b79b0ebe,1117e2d9,ce73e70d,d097bf90) +,S(86bc560b,19d583b3,62c1634a,139bbd16,db30e823,75913cd6,fb688e4,38ceca4d,2126168,75c3adc6,c2aa16ee,2e028052,9e6612b,fe4b1aee,e4961feb,f530423c) +,S(dd79faa2,e97dd468,5f3ff8b8,d5e55598,73736de3,9493a3f4,4e679516,f51e495a,2cb89020,efaae785,5376d901,4d1bc374,21e0ee60,29ac70c4,65bdcdd1,e240e57d) +,S(caf6318f,825ca3d8,6d45c681,60d897d1,76875e26,bcd36d00,82b4e1ea,e6d8c142,d7abc304,55a5fab2,68c6d17c,3763e586,5b9e266b,bc6211b9,48b5ff3d,19f5df72) +,S(c49dbf15,70c3f0ce,1afd166f,884af550,1f26905d,2f726185,7c026405,efe9a2bd,54eaad70,8bdb7b2a,59f5d69b,5be6ed79,5fbc4137,945be17c,b4736649,6e8cd3c0) +,S(a87447c2,83c88db2,15630cb7,6029132f,47dadd57,5ea6f9bc,10d1b36d,8317a91a,8489d3c3,6334d65,fdf6089b,df19c3e8,7eecd697,516e1756,5fc8b977,be82c363) +,S(7467b357,7d21b028,dab4100b,ebfa734d,36345024,adc60b1,10b8f96b,c7860889,b2978a5d,dea9765f,7877d8ff,fba66c0d,f7c8e0f4,6854deab,21908da2,8572b1a2) +,S(6af133d9,bf2d6b57,ef69e0e7,5eef6d,eeb82d31,af490320,bd26f4eb,38ffd42d,7f4a4d1e,ce23c530,a4d64c23,cf0bf8,a46c59aa,74dce4ac,2854c6bc,d11b056f) +,S(faff2662,5a41c80f,c0889d4,83eaf50c,596aa571,6807b118,1e94ce5b,581b0a7d,32f3d057,4afc487b,43b129af,f83bc7dc,d495402b,90fdc30f,736e87a5,469e8aa7) +,S(8c6983d2,8047ab24,ddb292cf,1c8836af,7e75d7ad,6ce23149,e022cb64,2439ba2f,70a10314,447eaa73,924fdf58,fc607dc1,c69a69aa,29b84dcb,156fec4e,568a5bb9) +,S(bfdda2aa,b23a37b2,bc129bb4,280a2c45,926360c3,2719872c,ae1e81b3,1b3d3d02,e8319769,b7d21199,9e5de1ae,76021c9c,2bf75ed0,4c9a6c2a,c52da4f4,88cf78a5) +,S(80e24bf,3559d05e,c0cf63af,21dd7adf,237c23e7,ed930c7b,4124ad4,46871de8,c8f37f91,4e78e037,602ae9bf,ea3511fd,2c95ad3,6665117d,64f9fbbd,ecd10063) +,S(7f56d940,2d6fb0ed,dc6ce187,2ee8e55f,45db30f9,8defa84d,f7fb76ca,aef5e800,f43b9e6c,b60ce85f,44682fae,d8a48e5,3d9599d4,f19b4757,74f7d6fe,2fb2554f) +,S(437e7a08,900216be,72f14ef7,33127d49,9130309a,73369d2e,58fd4187,a0d428bd,3f0a4c4c,63dc779d,69dea37f,786a5157,43b3560c,16d4e56,4a1d7802,f40dec83) +,S(3bb8db7e,8cb3534e,d7f70f8d,eeb1cb81,3ab21dd0,552c311f,f98f38e3,63321626,9ffd98a4,b3c271e7,83ec8c72,98ba83b3,f4f0a5bb,61ce1edd,5c1095ee,eb16a569) +,S(21de8ce4,6aaebc6b,4ac51620,e2c78904,f9300b6,2930fa79,699e2782,5dc2310f,12a21855,50ceab27,aeb2e7cf,14710b7c,b3dc837a,67a1e4d2,6950e2b8,1942b9c1) +,S(6c24ddca,e4245972,5268369c,545bc910,ffddd8c3,49d83fec,eb27af78,cfc0c965,6263abc6,ed17a124,c8b2c5e5,c91b157a,13512939,b9d60e48,929fe6d8,4d032338) +,S(ddc0dfb0,49f7b6b1,cd1d03c6,f8ed2470,ae320f04,bc6f13f5,a88ba89,7bd1f91b,57c5f0df,8fd22e02,da44cd05,74fbcc1,c8b4a903,a909f906,aef9208a,89eeddd0) +,S(6fc5fdee,78c61421,a3ec2284,583a56d8,f18e66eb,58c54dde,e5209a1f,3e3761eb,baeac905,6101b825,8b08a807,72c977bf,60956b2e,d98d1b25,e71b2b7e,10e3d25e) +,S(1b6735d6,ac2f1db0,1c3781d0,cf42e2cc,3ccbf030,2e3837f1,3f6655eb,ba0dfddc,621e8c0e,cedfd28e,608c3da5,135d63fb,93dc6919,2a6154db,bf63e315,2f7db68e) +,S(1a875a0c,ecae6600,4bbdab3c,4fa5a57f,925079dd,671bd9aa,e8ac5c51,b21a5e83,2317a0c0,81c17bed,a15e1148,f44beb72,d4e65fa4,96408778,8216f85b,3924d9fa) +,S(51635c0c,ce51684d,9631c8ad,f6c9c4a9,3f66dc04,a372c891,294c42ae,2be5a84a,5c6cf3f1,bbc9c21b,124e78cf,ba05b2f9,ffb9c902,3895d584,48622259,635d3517) +,S(c548df8c,b685f457,71c564ed,a3e9a77e,a4734faf,7cef877c,b0bd70ff,d85afe0d,2675d6b8,24f99a19,8825f1ee,19510492,9eb633d0,367c01f7,c922bfb,c2cd6dc2) +,S(121592ee,aa39a310,3c02502d,72e360f,f500853a,7d2e449b,16c5e443,f42e700c,b5cfa2c6,689d973d,e0578a39,bc687720,acc0305d,6ad3b678,1d36941b,7f0cb435) +,S(c2a8b66d,cce99233,b3d83699,b20f0c60,21a83ee1,46a491e6,d7e69ebc,92a3e046,e0f3aff2,64228803,d8c1d729,88780d2,ae8c344d,f9571b86,70254b39,b4243705) +,S(b2b703c2,56ab219e,528886a4,4d6b7772,5cfc1b5b,17865ecc,c46e2d2,2420514d,b6aff027,b4408177,8c6cfaa0,123590a7,4615394c,aa83891d,15013d35,ba28a9cf) +,S(d249c36d,fbf43f5d,c6ddb196,d78d4cbe,898d64cb,3b239f89,1e8c4245,ab647afb,4e58c9e9,4199e0b7,8a0179c2,c82b6442,17eb3fe7,80c687e5,166f56ec,f812d092) +,S(ac3519a1,92c13eb,b37cd560,1a141d80,817226ec,7c86a053,42655c1,997b476,3522765a,afc2fe6b,2af9b489,27809189,74c2bc57,58ce502,13777ce1,a569083a) +,S(e9b69596,8983ee86,340b96ce,efd9a289,e86e6d49,3f057962,77b99067,af83c70f,983a83a,e1b08fee,392e51e1,c12a8e12,731d592a,517e240e,ea508f7d,b34059d5) +,S(e11e982f,10e65120,ca357106,f273c5b2,9900454f,81456781,36f52871,65444dd6,e961b155,81ee9ec5,1e6a3616,b7182da1,bd2e5db4,d08dad5b,46bee558,44c21850) +,S(f63f4434,bb0c17dd,3a17c75d,2d179e41,10a7810a,847bd4eb,37827997,94e57b14,480bff24,69c2e268,a51b2147,3d6cf7ca,23a3c61b,513267f7,c25b092,7dcc8549) +,S(cd8ea46,d65bb2da,7234508e,fb48a828,27678525,d102fa85,6d26475,eadc1a69,ba231ab9,513f90be,9cc8260a,fc63b05a,5aaa0280,3502532c,916d99c7,20b7b2d0) +,S(af9a2285,ec491b56,9cf53c8,6ec188e0,5bf18d1c,d7e898c3,c881a5de,481bbe13,a0cca7f3,714f8d00,92af7bc9,62abbe5,4d106dd0,a6089607,35a6d9b4,73d9ed58) +,S(5d90a039,55f41998,62e5cef1,af05ddd9,114632eb,abf27d6b,9b92c6c8,cfed8640,a0025e54,482aa49,11d8a556,2205c2ae,2a0f75c4,6f3faa55,7463b9b9,cce1281d) +,S(aa1f071c,55541753,3a47b490,c5603aed,2d2e5282,71acd0de,6ea7c5bc,ba66a348,195d8b00,fd90b1ad,15e46620,22d78bb2,47c1e9a7,8ab3b018,f341a005,6267a167) +,S(4225728f,ee2495d6,73f64d5a,cee2e372,2713a3b4,dbd2f098,d20415c9,3ab513e6,76c17939,461504e6,e1420d53,c5b07449,ce7f976a,e4de178e,69552755,75e92412) +,S(669c2815,b3357084,bf7bab89,63753b0b,ebbea33e,5b731ba7,5f969890,3a281eb6,23fcf486,e2839e2d,91fb08a9,11ed7361,81de7406,54c13306,575c576c,d0459c28) +,S(7b29749b,393869b0,d7f0977b,340b9e07,76a20ceb,ff6d8f8e,f4650348,11773665,a0d68cd,b6033ab6,a4c92113,c8f07110,aa5cf600,2335d2d5,2ca9b956,2874832b) +,S(6f096ed8,56f38c26,25200774,77ef7ade,19fb616e,30ed560a,ee5b4987,5f43a7db,54453b3d,1ffce3dc,b5e72ec9,3f15b57c,6725b271,d3fe8b7d,8f30ed00,35845b6d) +,S(1354de01,ef040d5c,681318c5,a6dfe7af,5c8eba0e,ab581674,acd5335c,e33c4bec,4002513f,ed215b53,c65686ad,8366cd7e,38711fd9,98d27750,bfce7e24,dda317b) +,S(5f8afb0b,3800c535,47cdf93d,61ae5c67,233c2525,17f99c38,8e97e7a9,1a90b561,7dad53b7,a64b7068,967fc0dc,e7178a43,a06e56f7,7aab1a57,7910d69c,23540671) +,S(901d50d9,b88abad7,84e75135,85a81d9f,a1d167f2,c9f377b8,e2598cc7,b249f3d8,7242b591,3c80db3e,748c63ae,47ee6229,2c1bc29b,e9f9088d,fb882259,405c3dd0) +,S(2f5e27e7,4c7e00df,c0bf6401,7d1a888d,1bb7a3e1,3ff66874,f7c306e3,806a48d3,87c3836c,7fb767f,4b5ac585,62c48a18,21dede2a,7d63fe40,da75d967,cf9191d0) +,S(8b2277a1,70464589,1d8b54cc,43bd5fc3,54fa6f1b,e7a062e6,6349ac2c,40eef8ba,ac3a007d,6b3278de,1c043476,13b254b7,69c9e14a,c2f50f9d,5f025046,2e06081f) +,S(4a6273a4,e9f28e9a,82c3532b,e7d3e564,66e87273,ad1fcfad,7ecace6c,54890de4,6d8b0fb2,1cb99844,610a325c,9592cc1d,e7c8b32,d70e19b7,ab7df472,8fd1aa51) +,S(f07330e,2ab0150e,435fe3a6,8c703091,4e7fb52c,307d58d5,d5120bfb,891f84d5,25b6ebc5,4c1d9206,33891a8e,39aadebd,988bd98b,a29b04bf,6ce4c283,a4438b08) +,S(3a30b22d,6f1fd617,9fff2c21,d6635828,8c21fc8a,94a274b8,993ecb91,eaab54eb,94035c56,6ea179ac,d58eb0f9,d12cb41d,67b94fbe,65805110,61cd9806,890946b) +,S(8c4f39cb,87d7f65e,591fa10,fd46d08f,fc5de3e1,67d8c9e7,718bff95,b112a5a,726c4bb,c64373f1,9399db5,18b5f823,3faef361,3e363b84,ad76052e,bdc8f2e6) +,S(38118e59,63a1929e,74f6d98b,c80e44e4,d9b32254,6a0f1eb0,690d08f4,f3bd4bfb,23167e00,c29513e8,e82d1140,bef5bf02,b806a652,fee592fb,1dad0811,604a4b50) +,S(75d4246b,db065274,550e9784,f3c9437f,3aec0fde,3af54a0d,61430cdf,2626bf5c,8392f570,3896cc62,d66f8485,9f7f269,4ff40a81,9505447b,7d79bb98,77f8f621) +,S(ab3bb0ae,c1f390fc,8d1bd3fb,4ecdad66,3db868c7,c4fbe0ba,6cf4f059,7068ed87,91382a2,2dcfe0c1,b51148ce,bad2140,24cf099c,e3e5e3ee,867db7ee,d070c7e4) +,S(d1453e12,383386e1,1976cae0,8a448b63,1a977dd8,47c19d2f,d7a212ad,5090011c,7044d595,fa8f68c2,4a972658,590d7ab6,dfc06ace,b9d8c320,205b858e,ba0402c5) +,S(894afc53,b0d1bb6a,c948d117,7e83c42,b4ff4084,e593fd75,d0660680,2ec0a4eb,5c5eb493,73e74fc7,39ca4fba,1940ebe4,6912d896,7cfc036c,7402e8ff,8d071d7c) +,S(f1dbde60,43133dc6,8699e89a,3dcaddc1,fbcb5ea5,e815eb5,8e7a6b87,dea2e6e9,96a7b1a5,b36e5492,68168c91,775d6107,a3f87f9,fb5c8b3b,acb75dad,5dc544fa) +,S(ad9126ba,6d35d780,dd2841cb,2ba817d3,f0267446,ee99abd0,ee2b4910,a4450b8,f77eaa1e,66c0f3f6,88268d92,9c9ee53d,6dbbc20b,b74e864f,d7831cc9,3d47280b) +,S(70d5638f,d3fc43c7,6f321157,f9715994,3b797d8b,1d366f5a,a5a7f1e4,ff1ff7a6,ba6f2d41,7af1c5af,dac8c83d,dcc289e9,4d6f29b4,2631ab7b,19414bdf,4a9ece36) +,S(e43bb23e,1f82bcd2,708730b9,3d3ed915,e3b4ad84,61904f68,bd91a065,80a4ebad,3b528db,117cfb49,99941b0b,63f51ef3,926a6230,dadbfcdc,28fd1d6,2bd44147) +,S(9daf3516,a015bd59,b648fd9d,9143e76,46b2e3fa,df5e446a,c57f2e22,9c9dad2b,5ec57ad4,808a9f2,ed297f7d,a7794e2e,3f1bb14c,bef58047,e0bddfb1,8ff11149) +,S(13970b21,3115c499,5eac245b,33633c53,1f2be101,a541f129,7403a727,67df16f8,3444e05a,7e49ecfd,633c96dc,99a0fc81,cc3c359c,440ffcd4,5df61c5d,1c027e97) +,S(12aef793,66978a2d,3fab4377,7debd5c7,4315b002,829b49df,c80fbb4e,1eaa94c1,e3f5c1d6,ea42b741,8bb3446d,c23679f8,e7a96d02,a8f33d1d,3404126f,71f9e37b) +,S(62a2ef7b,887de5a6,19c753f5,e0bc45c1,7c47b8b1,ffbb0ce4,8b93caf1,d1ab4b02,7d00482c,20c25e01,ad6ae35e,89c263a3,5d0fc816,952a96b0,9f2c2fa4,b8fc9bef) +,S(e6b03f17,92df5b1e,ec324ea0,898c031b,d745221e,791d2406,2aa917fc,de6f8a87,b4ee4b18,41153d22,1ec0ffe0,ec05b1c3,408d71c,5d2ca29e,a01ef9c2,e669b205) +,S(dbc02e03,e03e2f14,53ff6410,afded1f4,f0d51461,5ee00f75,d041ee33,c4f35783,6a3a332d,99ffedd3,d442b44b,aaa9d12,9d93e372,36dad034,9c47bd83,7c7674c4) +,S(f11be23d,6884890f,78ccbcaa,c1759ceb,5e7f98dc,19073aba,b85d85be,5fd23ef0,9afda170,dc1270d2,e43989a,4ffac7d5,c848ee6a,51e03b58,c308a4fa,39e2cfe9) +,S(16ec4f95,1db5c83a,c2c26209,f2577650,e9c48c44,224b221c,c09b0b19,1c1c5552,e3959034,d259e9f5,163a44da,f87ffd63,7a35b220,eea5ec6c,301cba9,eb09dc54) +,S(3cf701ab,8991e981,e9cbfe30,7b3aced5,c2147c47,f76bc2a0,733ee544,3fef3f99,1e6a3069,d4d0bb8c,def98d49,cd303b51,c45617ed,833be051,ca2836bc,13b8e1ac) +,S(96d093fd,1a8efbe,4f93c544,d0d7e397,cc83e114,4574f804,570fa3ec,58d5669c,2a29438,a05fe50d,b980db60,b343b06d,1796ddff,7e7fe39a,356cb608,69c05ccb) +,S(a6457eee,21025732,5094d3eb,6f6ea05,21e83184,adeabfa7,b6cd1206,9a9dc9ee,83e436a8,b234778d,9c7be0db,88639177,1d7a48df,19c29c47,682fa2cc,30b5e7f2) +,S(1b366505,1c858ac3,5890e7dd,b4aa7984,dbacbbe1,f4d2b62d,5337b530,da9bb0a5,39d3c2d,42c5d292,40b474e7,2e94a64b,4612f5a,68f5b6bc,586db5fc,a41025d6) +,S(e09325f4,68328cc4,d69a71d4,8ffe0380,bc118cb3,b8f390d3,4c1e56fd,27f4589a,16cbf183,78946fb8,3ff9763,41c6cc3c,9b2f451d,7661bc3f,3811f7e6,ea89a01d) +,S(6a8ea7a9,ddfa0f9a,8473c47e,f5667e44,3e64e03c,5c33a9a1,f0f1257b,40e1ce62,92806471,56238c84,9c0aadaa,2e9efdcd,e5a56a2a,78803f7b,66210333,88f525db) +,S(480b30ca,dc57c623,9ede2763,f113b46e,599076ae,ec687c49,33343178,c620f2ea,b5aa1b8a,ffe1e5ed,de587df3,341dd34b,57180cd4,752a1bfd,d06e4c2c,273b4433) +,S(134be6f0,b03ea43e,98e2364,46a45253,ea5822df,46227aec,b24b09d5,b25a34b2,d4841d54,b7fc1736,b293d314,bf6352f2,c7b08ece,4de652d4,2c1b985,d1fd78a2) +,S(7c84e23f,c54de6a1,a4ff6c9a,c7c88ac6,732d019f,a53b1a9a,a6eb2ab8,a3101f31,4ca88bac,a8d52f44,3703fa27,4fddde3d,ae5924bd,26b062fc,6f7fd0d,43ddf5ad) +,S(7c6a349,911f02ef,2aebdc3b,ce77f639,94c4dd2a,a842b567,141c023f,4f2d92d5,9b4f2f9,6215aad9,c7e0edf6,efcd8aa8,74dbbcd5,4a0c4cd0,fb7e01e8,ba6884af) +,S(9e1dffc6,a919c9b8,4e3d818a,5ec60f7d,5a2baba7,7d2dd65e,137d2ba2,8a1aed3c,cf26f543,bb7ef705,e2d3c429,f0ea27,84e3daae,1a71c556,38d281fd,aa3b1738) +,S(e24f6abe,c7519588,33ecc765,7446ae36,937e310b,d5754c5c,343eecf3,6e140079,c38a0399,774ff24d,90f8e599,183bf011,aa3c911b,9a66bbe6,920522a6,7510e62d) +,S(517505bd,1fe28c21,2fa85f18,99823b01,bcc3bd1,748169ea,54f35ab7,870f0e1,da94c34a,5de41881,1184fe92,8b3f08fc,362aadf7,5e7abf87,5d5f4798,fa712f3f) +,S(a02217de,4ec87155,b877b7c9,dd7425b9,79627f0d,ebe127ce,27d4f3ef,fb988a8b,cdbd866d,7b69e8eb,9321d07b,2a5c9d8f,6eec8be2,f19a6d24,4c987a1a,12752bd5) +,S(2e595023,c8ba084c,1cbb2d05,96ec35b2,7c366bf,cde27666,35d7e820,8fcb0ae9,ac08f27e,b8fd5ac4,deb1f46b,23ac1c5c,aa02b918,9761e6ba,d7c1ebb0,f412d8cf) +,S(ce384358,fba557d3,b76df62e,d2264cf1,e0bc7b43,bab30be9,fd6f65e1,a82b6c2f,a3cbf24a,e067ad85,ae0fc86a,6e8490b6,1e44980b,52f29a75,4a3f7e4b,a79ad119) +,S(9715da8,79cb1c5c,4291e00,fd2822c1,7f067d63,664170fe,463e86c2,d25e46,c5179ad3,a4846fb8,d6f290b9,2f957e14,cee99f6e,12fc8066,ec4dfaaf,a82edb99) +,S(19f61bb0,4cedc19e,5054eeff,8d0bc384,6cf62a35,1af3ab95,e03e45d0,786e1aef,aaacadc8,db84d7c3,f869931b,bd33d295,45fb37cb,7e474fa1,7a69a683,117c05b8) +,S(2a69afa7,581777ad,38882f6c,659ff4da,33fcdc17,a5355583,d1f8ae37,7dcbd718,878eb429,d42dfbd6,435df1fa,c5e0ed4d,e7b2fe4b,6f7dd6f2,6a3150a2,213fa619) +,S(c3da1980,cdf257db,f2a5eda9,94267691,a5e1e679,79d4908c,c06f7f50,71002381,2cdf4de1,90ef2995,a984d882,598c24cc,35cfc47e,5cbd2d53,53d880cf,a944bfb6) +,S(19294eba,9d19c03b,497551cb,7cc8d8ad,3e3b2130,942ca8dd,c8bc5579,1c424d2d,5523ac45,e676daaf,2d8da00f,5e9240e3,d904a536,63e6b704,735889c8,84b680ba) +,S(d8b3b307,41ee7ff8,2306615f,2d2ef361,6e3f7cd7,fed9d56e,69300fb8,5eab6bd3,7d57c12d,e65bf3c4,6dde736c,373ea374,d090b240,6e1d97fc,8049e21e,aa10a74c) +,S(e2fa1bd1,164528f0,87c72a18,e9843e33,43b376d9,b5616b74,5e0c3d00,eca95fd1,72dcfc41,15b35406,8bd3057d,506d592,771eb3fd,60a2c2c3,dfc2645f,86b249e5) +,S(ac587775,bee32b7e,90031ad8,9786df14,8e4d9662,55a06399,e43c0441,883fd6b4,b6d3eaa,6f6a50ef,ef84c578,b241591e,4a718eef,fb40ac34,99a57079,b74c45b5) +,S(74976cb0,77d481f5,e6bf700,6db57a13,f362fabb,e6aaf25b,6e956452,9d093bbc,bb40be31,7cfde25c,75ea859,2b622e4,9d42a0a7,30602241,219bcc84,a5f4bfe1) +,S(e71e6967,f32647fc,2c13a94d,4bc1410a,cf9728d,1f543522,681d750b,2620a668,33c4fc82,720210d9,afb9f1fd,51671f3f,fc1df5f4,e61a5ff8,c59f06c7,91f996de) +,S(bc36cf57,161e9b17,828e4557,74204c59,805b35e3,abdf4ba4,daa9a5c3,fafad6d2,df34c492,3018e879,bf459cb4,528d2983,340444f5,a85efc29,71e260df,29cd8a20) +,S(925251b3,9c8761c6,317c2066,717a2e8d,89e43acf,89527ddd,6078fa49,2d040f95,aa7a084,8b2633ac,ce551f1c,63312895,f4ece420,5e224665,2c486beb,b8131f10) +,S(4ec27df3,d9e755ce,b93e1ca0,e0e43f44,595b529f,6460e3f4,e6cc3765,3a2bbb21,eee3fa06,257b4be9,387ac7b6,6cc1ff6a,aae43583,37d6ed71,27ff753f,1fb179ac) +,S(6f733e9c,b86c3a17,5bce6c08,347577eb,69cceb17,3c19abef,c94b6646,92859812,2a895d6f,c4a7a4f5,610e8b8,9e7361bb,db728625,ee31e6de,927c74f5,b10ad0fe) +,S(c631f4ec,f205b1b4,6bc0fce5,3680e6a7,27f9e64d,5ee3fe24,c37291a0,d3a69b53,f0de9e0,e4bea2a9,cc01a5d,2f9aad2,f5af7ab2,7c2ff98b,983dd2b6,38dced4c) +,S(9326d449,4fcb3049,8badc221,6d3a90c0,131d31ea,cbca74f7,2cf7da2c,bb6aa2b8,c3f268ba,4c9a9ab5,3f9edb88,74f2786c,4e4c065e,ab58487e,cd8101b,7132511a) +,S(538c52d4,8fa6c492,cf546349,675d6a2c,ba10b442,8827dfeb,69f0303b,1b7ac774,c1b1db4f,d6d50f3e,c7533ee8,cea0d47,883b57e6,dd4137c8,2132f846,3b81ebf9) +,S(5e58a25d,8bdb4576,d178fdb7,23158d26,508f8486,ad553727,907901d5,6e99a680,97c1f814,8880cd85,51c9f1e4,9ae58eb3,d1a01285,bfa8248,44bc794b,7d83ec62) +,S(1e9830ee,b75d6c6d,c70989d4,ccb85e62,34a1cf94,ef81b65a,49b25753,cb6c13c4,d0780a7f,9607e530,d80dc068,68b1cf8b,82d3047a,2977d204,65187ed3,13c94c6c) +,S(c5b441c2,f7e97a03,dd690cbc,ac605772,1524dce7,fb5068f3,f73d78ce,50fe0183,9bdd2242,e35008dd,4f907600,64eb3b29,427ee9b2,bbeeb548,62878688,a916e410) +,S(a5f56816,e9448d0a,aaa7593e,e3145678,3be74521,b129f13,f11a276e,d419492,8406662,65c275da,76ef289e,d36f8af6,6ead9be1,48cec081,7c21987e,9e8af9fc) +,S(c5e85955,44004f79,2260d553,25628858,ce50c95b,9362d868,90fdfd20,8d1184c4,6a5f02f1,c0f381f2,7fd21eb,928f03a,c8524dc5,9bfc1bca,d025a290,7cf939d1) +,S(d5dd810,9e691f5,8694c87b,59907ed5,ec18d37b,8554799c,1481ac78,825d2ac9,ffbaef54,fd35a5ab,a49f9946,a11e5ad9,2f29590c,20e28180,9f4be3e4,b156dbe0) +,S(ee5d42a2,c705bae5,a11d9d09,af3217d,2ec16588,64a60a56,d8e4a1cd,4313c61a,f08f0e08,89c015f5,3a2a74c3,3dd625da,b329181d,1d0f4fa0,14ec01e9,5d113d88) +,S(90409eee,78af819e,249f62ea,3b4d70a9,26557f8,731e50ed,532c0b30,4616d615,17aa7a7f,8af635c9,c4ea353c,56c89da9,70df599a,faec8916,ec9a6d82,cdf957f2) +,S(5f19aa1b,a6d6e3d6,9445e8cd,71c95e3f,a3ddad6c,ff0dcb4b,9e09aee5,65ba9e46,f82b3170,c2953397,a6cd29fc,9c87bcd9,76cbc7a3,5f953948,5a57a940,63c2e570) +,S(5081942d,1039bfcd,96a759c9,27583c45,8dd4c013,59fea307,40c65fad,d020606b,f6f204b0,97cecd15,b2619aef,c25328fb,226598b,fc9384bd,de99a4d6,567e9b8e) +,S(43eea7b1,acbb1450,c9a49b0,262639f,702612b1,b184ac15,675d6496,a5df1a54,a31636f9,ceecfbd6,60f78f,f6cee471,d4366d7f,ff863db4,9a5a652c,71b94797) +,S(f2860e98,a30a6c14,ac43dc9c,61bbae1f,b8ecb294,36c8f0a8,7dd43c01,486706a1,bc83bfae,9a4effeb,4beb025e,962108e5,4a5d7979,cb9ae2a0,7cc44295,b95a2e9c) +,S(6b4a8c28,7d5c7af,63ad8d34,9751116b,60a613f5,7cac229d,7ef0d9c8,166d69c9,48333ada,f4810cf,94c78d43,88f8842d,fdc9fd7c,d391e456,a592d8b2,200bd6c6) +,S(d1efc808,393d4498,50837323,9b791d0d,a814e888,2958da8a,87136d93,bf1b7d74,13247e74,3c323631,9e557476,4ad4dcf2,b91dbc97,2d38244a,fabe4c0c,d08a9924) +,S(d3fd7a6a,fdc7332d,f2e6683b,a05ab787,e3c48262,ce837f9e,d8ebae1c,1f6f7ab2,3d25bfd3,3ddd4f74,8ff395a6,b4f36d19,cdb28ce6,b56aaa55,e783e9f6,3d74e70b) +,S(816f76c4,c5ea8733,5f220c54,28b31cc6,89fd8267,e498a675,4d6a2620,a60d9aac,d3b61647,f6624bb3,9fbb672f,51b66613,8a441a3b,660bb223,1f255488,806e79c4) +,S(1e344f97,98f11372,aef5c6c7,6b32a568,16198e18,8e611026,1dc78338,2522cc93,474e0218,9bb4f698,15e304d4,8166e3cd,717a1bc,a9cf4e4b,1f5c5d23,a36e392c) +,S(4d3bcef1,d6cff8a0,e0582d11,22eb7f67,28aae077,e9ef7960,ec519ab,3c6d6087,29f1b01f,a70e6812,3dade19e,d5d2689,6c491389,27a2da1d,3c628965,bccf38e2) +,S(6d5d596e,467ce203,297cdfe6,ce4807a6,1686a8c9,f0606283,5e0fa194,894d027b,ef58ab41,1d6a002c,12f469e2,e9f8ded4,4291b270,4b7490c5,4c70c94a,cb7b24ce) +,S(86f6ebc9,c25f6866,f14af018,88486b22,6c89b1fb,64bd9ac6,e523e503,e2cc6819,b0725647,4d9f3b4,8d4055d,e15b72ca,ce599bfc,247ce9a8,4b0d5e72,16b30425) +,S(520115e9,a47c3df7,23f81df,8422c03a,ea0084df,b122759a,8d6a5b75,540cb339,93b12878,44f22aec,9d5ed727,3d204d85,d3bddaad,73e3545e,5725b171,2b8417bb) +,S(19c9ff30,e5e50038,7e9be1f8,efddca98,7a72de0,d5cad8ce,7569d4e7,2b381009,b43b0c98,402748ee,16b362c8,b68ae79f,8493a7ef,293b149e,3faf7247,83ee3661) +,S(bdf0f8e0,928affd0,87566820,3c95b3b4,e6baf9f,f1da25c9,73814c27,551ee4cf,5f701bb6,8f8a6795,cb4ad675,e00b5ca5,761a0eff,32a1d3f0,9b29d5b6,3885163b) +,S(5c609591,37a48dfb,f778dc26,80de17ce,390ec33c,ea5cace2,a969ee9d,1e413e1a,670078d8,59a2c138,93946d1,e052552d,fd92c380,5fdf2ed7,8aad7795,2ddf2f51) +,S(98f22ef1,b9a62928,c5ddbdf,70e71c08,eb910ff1,fa6a6a1,56de82bf,bed8fae,f87be19a,9433d279,8088c882,5d122e31,bec9102f,c580fa2,24d40f32,2a2db1e8) +,S(d1842bec,2bfc5fc0,d5208d7b,40e04b76,88f26add,9b5a6845,751147e4,b4524615,f0405ace,6dc9bc88,48d18586,b713ca3d,67b76ad9,4f2f794c,55fbe9d2,f72ffa56) +,S(732cdad8,e0aaee77,473c0140,9702cb39,555ee048,357fa448,33ce8e3f,5f50bea5,24666502,448268a5,bc2c693a,85a1fea9,dc5f010b,a9b0cce7,6bf36124,bca1cb0c) +,S(6c86ebd9,5200b1ff,dbb6ce6d,e9fff6b7,1b6100e3,1144239d,77e7201c,db2e8af5,39c687d5,abff0ec7,c7ccc4b2,a4a16ba9,7324430e,a1ef209d,5ea126d2,cef24539) +,S(655d63c1,47441ab0,e65f9893,dd38f3ca,22d2d8a,a7b2c87d,a2e2293,b24ffe0f,d19ede94,b25ca138,94ab8fe9,842cae29,92cb58da,592c19eb,57c4184a,45121281) +,S(8efc14d2,d5845886,ec264438,449ff49d,ddab7567,69999bd3,6191cb39,efa41b72,9f1052fc,416db1a1,d9797e66,a816b403,475ac091,ded4dfdc,e262d527,3c535293) +,S(31a7f0b9,1686e695,d1fae6e3,8fcdbeb4,246fde30,f2ca80d5,2d9fde31,c728eef2,9661bf7d,46248da3,8ae1ff52,a8aba654,351a1f58,4f3bbfed,1875d439,3612190d) +,S(9dd959a9,8c862275,93dcc957,e369b2fe,5cc1d411,d4162ad7,d8e22b64,633adb85,78ccfeef,d95ede71,32a7011d,bd39b9dd,f77e38bc,47f7432c,f90d6583,5a6e665e) +,S(51beca99,fe3cedfd,1ba44caf,58c0fe4,8b926e72,50e5ca7f,8a187cb4,909b1892,12f38fea,aa9de148,7c14eff6,96cccf6b,c7cb23a8,6f2b7e0f,10fa971f,3545a0b2) +,S(1a84e21,3ef9b9a5,9f9a4fe9,d21dc1cd,1ec7a102,fd91557c,1129921b,781e6b51,aefbd931,17a42a75,13db0e04,782aa0b6,9cd79d36,b074f026,bfb7682,983cb78c) +,S(9eb14847,2d02a287,cd197450,78d81963,3943183d,c76c2090,9f68b94,12eeeaf0,6fe4b5a2,d18ac52f,9a129a91,1db00993,ca505380,2054b5c5,48f35380,c6d467d) +,S(9ecb3cc8,da5475cf,1a66ef54,3286f07,f5be1196,2c1fd420,b394bae6,c4256441,b4160952,e3701895,6f25c5d2,98ce90c7,91797571,267902a0,bba53d2c,2fe2cde0) +,S(541e567c,b2160fe2,75e9d479,1beb8ad0,4c07d6b5,12b43d49,888963f6,d6696ce,2444e184,66cc09d6,aec704c6,ea8ef670,4ed1488c,dd8107c0,c625b783,6534d6f4) +,S(8c061b6b,b6b55fc3,7c6d805c,808fb3e1,6fab1cb3,a05853bc,4933eb39,ca7b3580,20430304,c3780c29,a977f8d3,54424539,67924c2e,9a1353da,40716ef5,a0a0d37d) +,S(b9b674ab,361aacec,bbb69f7f,7c2b1361,44e55da6,1566ed97,cd58152e,4d391033,7841975a,4cf0b5b7,3bad8433,10866275,8a8eb93c,3b5db58a,15346083,f3d10386) +,S(3453c3d2,27e1dfc5,3e22487d,cce25ab6,18a3d25a,48f6fd1f,8e9158ec,dd6bfa1c,aeef1768,b754d998,fcbc75db,7a750396,930d169d,bf933c1c,15dfe041,17ff63a6) +,S(f36f7b9f,28463b22,d2c43e29,6b96846c,1b3401ec,53490c5c,35ec197d,da2c440c,9876476d,e2cfb7eb,b1cdef50,a39d20c,4ba5000f,9edef22e,ab7b96c6,f0cb5585) +,S(77c64190,33ef6119,ac3edefe,ed519632,ef5dccf3,f46066bf,6d5204e0,66788b5d,980cc59e,a103486a,9c8cfccd,213cf704,3e6aacb6,abbf3293,c833de88,e5b2716a) +,S(818911ee,6051c4d5,19fb7785,d52c6f27,a82e2d79,a4a55623,909f3d6d,b549e851,5d031307,a2d66fce,4b607967,f662bc0,af855112,11cc209d,8457ff41,968fa325) +,S(bf5900a7,7c211a75,231ebe58,17f91748,c957f5ae,b98377b1,9554fe90,d11ff226,d910b2e3,1760f0de,838cc159,7da6915d,e6c3fb29,80bc0e65,e87a36f7,749cf1f1) +,S(654b4257,11f03dbe,75b7d60d,b578d75,20e7cb6f,4923f774,8799b4a1,df06fa16,12c9e75e,26d3ab4d,645a7a64,d97eb6c9,356a3951,fb715bbe,9e42f500,a0c3f44c) +,S(33a425f4,f178af6d,48b78873,cf70da66,aabbaae0,397e6673,7a9c6074,15ab3d2f,1e5aaddf,d76b1b91,14016f02,1812d7ea,18decd14,ca3e3925,89894151,92178cb0) +,S(cb088930,f0ba3995,d7542d48,92ce47e5,5d8fdd5d,7adf60d9,3651240b,12fe7636,aad156ed,f0b25c30,e4bc3784,a1b7857a,4cabbe5d,2ceffb72,ca2cb7d2,45ddb024) +,S(ffa9e81,afb11dee,83a54b47,fe9b41e4,de4191af,7279d19e,90e1c528,7c205c0a,405233e,b20a4848,80210b40,18c098ff,a0a17203,c5a13b12,5ec0fe92,1d1c3567) +,S(92ce3be2,8fd6c9db,be1cd4d1,f58005b2,af0c136,89181c52,a67c2503,2649a6af,cdb840c7,7e0fc2c3,d4b959c6,6fc47142,622c8a16,b30168a6,c62ef368,8bd23932) +,S(46079065,b64bd3d3,3e3efc91,374e1443,69adc4a,bcd2bcfd,91ebed0d,88f78cff,b09653a1,1c0710bd,b737611d,e5d80e67,a516dcc6,2ee3f63f,e2d6a7,f3794ae4) +,S(5cf961ff,de982138,958471b4,b316cae3,6246ae74,e1309400,a3acd118,e4736c93,ab8e425c,ab39325b,b94925d7,795d8799,18efc449,e44c9f03,cf7bf487,fc32b185) +,S(d8fa1009,27c1aad9,6ba97005,f8a24013,bc29082b,ada0e0ae,f6f72ec9,8abc4240,38d88e5e,183b2c09,d53adeb5,8d0525f0,83a512c4,1dd64cfb,a7024602,f39e484c) +,S(cdabe8c6,7d0d4627,54cdd3d5,3e70bcba,e2ec925c,a46a4536,ce3be9ae,e0b37d8a,c2032dac,527cd15a,a1d812ce,1c658cc2,a0a379a5,2a30613c,2737812a,6e683830) +,S(394fbdd6,7069d83,8fdf87f7,b1c179d9,1a491ca3,680f0103,46de3299,37e92374,5ceac741,828ac862,7fcd587c,69844243,d17ba038,901cdb42,36e96685,d589a693) +,S(84eb6d44,103f56df,96617c7,11c79dc7,a6161189,157a0782,74fec78,fc5f6c37,57a16660,4d1fa3d9,cb358e7a,47984a00,6926df57,4e06a313,7b3c7524,2e882320) +,S(295dca03,657995e5,d432a606,da12bec9,fec8f4f0,582d75dc,5657c973,7cf1051d,c4df0ad7,b1e3a29d,cca4120f,478a2d63,f18fc67f,bd201be4,e2fe05fa,66ba2d6c) +,S(b42d81ca,1bdfb038,d7888194,deda7307,eb846bf1,738d8b7d,89663bf2,8097fa7e,2d913cc9,93ed5118,1082c85a,42495133,ace8bc6c,65530309,c6e15794,aceff5cb) +,S(48484186,4f6d8f3e,94977a3,45bc0db3,1330910d,4c555032,da8da876,912df644,7a78a8c7,68c9d9ef,b5242fcd,b7a5946c,5fbedaa3,2914339f,8b0c0ac0,eb8a3146) +,S(7376d600,9a7a76b9,dfb7e225,c0da3186,b683fb13,daed9fdd,25ac6606,7e7d2316,fc733036,dabd7c4a,719b699c,da115547,8a52d69f,387b8a94,28744144,c0502901) +,S(9be9c65f,5fd6cbcf,522eb9ca,91427f68,152caa2,a152051e,3919307c,9f67ab8f,14da6642,fa3b7c37,41c9f953,d1e01c09,267b7885,8414fe5f,24f47c4,b44c413e) +,S(7d0ae5e4,18d6c6df,45f6d26a,7e962335,4ea1a338,8f183eac,85b1eac9,1962e2f5,551eedf8,264763b0,913307a5,14fd9e09,479f43a8,87983e69,509a3688,d09308be) +,S(d91d965,d3b85441,acec7257,d444cba0,6243b34,14e9665,9cc62cbd,89aea7db,54e26ec,9c82bf54,f06cce16,2cfb924,2a354c83,fe530937,9bbe733,6010f44f) +,S(44c8fe95,aa48f8bb,6c0a32da,a6263918,fc2df7b8,6a68f277,6bf405cd,1bf0566,87fc1fa8,3fea76e5,52f53612,45e54053,9d70377,cd865915,b6b78acb,f73a6e03) +,S(c7f8e825,5f2ddcfd,f21c5c20,ea84a527,2c5f6c59,99843c96,3bce9e0a,aa7ef398,5c1cf086,9c1f790,b1e59ddd,ec9729dc,2b73c6a1,be333dd7,e423a0be,bee50243) +,S(3a8ebd85,a2bd4b1e,6c0373d0,63e9cc4e,a91e6e1a,f4bd7af7,501e0160,8fb7f4d9,4d9351b7,3c3f6f36,1b86ae94,ccecd211,ee3b13a9,522d799f,e78c87df,4473f23c) +,S(bb01a4cf,ad90f3e0,5355f0b6,d1b28420,786c09dd,9db0ed5b,38a56506,4da77e9e,1742b511,43bc276f,273afb9,8473ee3d,3d962050,7462cdf4,a8c641ef,cc2eccde) +,S(eee45594,1a04bdec,a02e7e85,1d86987e,798c27df,adcfd5d8,2979960a,3983f4b9,3cc75025,9b5d215,37570928,1abca8a9,29f5609d,56c8dca4,3d1b23d3,cba3fedc) +,S(d2290ec5,120d591d,2e4e2796,3d10c0eb,e73d8b9b,600587ca,84173ce6,796123ba,c4760011,4c68baf7,b4053666,d8bd494b,b4ef1786,c1d7a522,8a656f10,1c837304) +,S(21e359ca,9b7326bc,b3380282,b9017df0,3cdfb7f0,af95f326,701bd8bc,25dc047a,68b866e8,555206e9,7cc43461,34c3a61d,ce2a50ab,2b514935,a05f8e04,ad95c70) +,S(b4acba20,94b35033,5095b208,9126367f,3203efc3,35caa43a,51857181,f4987e42,fa0f72af,77db4913,af6d906e,54eb33f0,a3e9d20e,d366c878,3b7c513c,c5165c16) +,S(5ac6b2da,18754c30,9ae46ac8,3592d673,ac5d61e0,35ef1b4,512aa9b6,7551862a,e93b1d74,105974cd,b6bd3043,c0dedb8c,b4eaa81,c949999e,68d52fa,4a3941a8) +,S(4a53cad7,2a894cab,9b761157,38ae78b0,c36c293,c60ba8d4,b87300aa,792c51d,4b0dcfda,b890ffdd,cf8a6a71,15f2a351,d883ad8,fe3d15a9,118f3e04,43f840c8) +,S(5edec48f,7d8c9b4c,af3371c2,6e054392,755fa073,1e660971,4e089b04,2a07bc36,b18b8d1e,407f934f,e526fa5d,38b3a408,76bab92a,2bc192b5,b7c206ed,6ad040e0) +,S(986b120,618abe6a,d965f9d9,6f50fd7b,29f1b897,8276ff8c,562519ab,8aa92890,2c981569,23ff1809,1cb47459,bafc0d51,699740b,ca59dd7a,14e07b9,432f681) +,S(8c61517b,397d36a6,b30f0894,98d525ff,bbda959a,126e9be6,f67b9831,e5e7372d,f7608f24,130ce8cf,56a7b762,c1563519,a4be88d1,79e90f1d,b432ac05,d472d771) +,S(d6abe67b,e30fa40,b642483e,a6ae7ecb,4217a07f,35546f97,469aae99,a286b8f6,b5e5675c,91aa08d2,a5a77349,5f1ad2bf,8b6b9dbf,4b35dc6c,262ff1c9,8eaa70ed) +,S(26be12b4,ae013009,45c8ec05,58edb030,e19a75ad,872104f6,8642bf5b,c30f7934,1086891b,3ce97d8a,a568fe54,28164f25,4fc15953,c97d40c8,f32c0ec6,6ed49fcd) +,S(3f0281e9,1dfdf1de,69d5112b,1b86ea89,d737d09f,1cbbb71d,2400d0e7,719987fb,27451e9a,2cb336a2,998d55ca,ac12e16c,fffbbd5a,3703897d,5f566ab4,5f4aba92) +,S(b84b8115,7b1782f1,e4b641c2,a001daac,ac7d53f5,b3f1fa5a,d0a5ddc2,732af3b0,a0c8f7f4,8fa49815,7a6c590d,4ea18dc2,c586b332,2a303061,c19edf44,ebba25ae) +,S(790ab328,fd86da4c,66f0989,296229fb,609de28e,cc8cc6d3,d315eb89,fdf31e38,cdcf83d3,44d103c6,736bb5c6,375bc2e4,3fcc46f5,777d6e5d,cc407700,15d29aa0) +,S(d5fee68a,f9b7f182,20ea6525,6a591f24,da79a642,4ea0fe31,88a0b658,9006fb51,87b8608b,1b3d0d71,c9ab2c9b,84654408,af6551c7,1e8ec6d4,a8f26cb3,20577532) +,S(410f9801,4622b22d,62eef39a,3c5350c9,e80ecef8,48c4295e,2ae279ca,9623e777,53dbc737,5766d9f8,ac0b8b7c,e4b852b0,3214fe70,24386915,84856c83,6376821) +,S(6cbfa6f,fc7a6009,75edf0b,c260bd2d,258bec55,382e650d,c464b16b,e5f34eeb,de72cf4e,33028bb9,18ed3a41,d885faf7,e1d5901a,ad7a325f,801f1a36,2ed730c5) +,S(2a75c02b,3325ec0b,ffa42250,e224a4de,e0c4c12b,69b71039,4bc3040d,80e5c504,ed666a2d,8ac26964,f0445d21,f1719ada,fbaea128,9edd69bc,94ae6123,a2e6b8bd) +,S(ea2bbd57,6c0b20a5,6790ad87,29f25475,24ef97e3,86663aba,2473994e,fab39134,d98d55fc,daedbd5c,3aab619e,1288634d,f526f873,19743f81,149ba85d,535172cc) +,S(893e9899,fe1b8a92,439c1594,634ff44d,1d0a60cd,8a0183a,b810bb8e,f80d0400,c680717b,aa2ff029,7baa807,d7290190,37c73d0f,a5a1878c,9fa2a6dd,d17cbb2) +,S(d75b0a2d,1e9a20c5,398fc3b7,cacc79ba,fd53a14e,ebe23196,e4bdf4a8,f8546422,37a8efdd,618bcff3,3dd0c0c9,f8bf3192,2e131764,305b610c,88a2b74e,44672981) +,S(96c84a8d,5dd2ec9b,44a5b2d7,af3b65e4,9c07786,969452c2,5e8e64f5,a264c14e,292ed1a0,dafdf3f4,83a2a419,6e1b6b28,4d7daf88,88c7268d,70e556fc,ff55341e) +,S(458895f0,77782a62,43abb775,7daec5af,264a71e0,6eccaf8a,3b23baaf,fbd7343f,809eb056,87bb618c,a0f4e1e7,c8d05e48,95f18393,2e949b22,b9ddab0c,55d32b93) +,S(59dba4a8,d7956515,7f639316,75fecc7b,58a0e91a,6c9c3d50,7dae6d40,2e67a9df,718094a2,83e47265,1ef52d4e,db25b0b9,9e069f,391ddfb0,d9987596,d2f4ee2f) +,S(a5f92445,b7cd75c3,9a4b3199,96baf00b,f855ebf,ab3e19bb,71d4346c,878b4bb,9bb1bdb5,baa4d56,5b9c5077,c86b96ec,953ce381,17cc8d53,7b0f3957,a582ddd1) +,S(f146eff,2a9ee1ec,a3f26d6a,17c89639,a1f3505d,2776e340,ae89449b,99c8b198,1674daf7,a66f1a89,7b5378e4,add6a196,fd27795d,88969a07,a210d33d,646a64af) +,S(e67f5967,d98c1d3c,3a4d0872,12d3b65f,6f8df216,5dc14633,92c23ecf,ffc17e1a,c3dbbcab,d1971eb7,a8b088c8,c71d65a8,328bf43,58f0e685,9025db87,e5391380) +,S(32e8d775,ed37cc2e,6f69c85b,71c95d65,d40f033c,b5eef362,86d4499b,fb6071f,2fbb1d8d,a6364791,95ecaf52,6f63eb86,e4604973,edebbf82,b796d88b,ade44334) +,S(b98c7cac,475ee4a3,c1815a17,e460f76e,e5334b27,e1ea319f,be8924b5,819a473b,d7f1bb1b,a653f20d,c7145420,d8c8c339,d789ee60,9b9ff0ce,73910b94,3deeb88f) +,S(d9830fd5,545dcca0,ee37a402,9f406cd7,50bbaf59,e60a80fe,da976bbe,ff9027d0,cffab795,e45a2833,75e7b861,728421d5,f9e22d03,44f835a4,c55207bc,6479b947) +,S(399fbb5e,4f4e27ab,3e737a32,d065fdd8,c003ecaa,84a2430b,4a7b4d40,eb6f9721,93f7b541,121d13bc,480f7868,ac9d8302,6706d2f1,a46955de,a3912735,c5f02e0) +,S(64e067fe,17127128,6ef0fbdb,b2adb4c3,395a1ddd,f2ea76e6,261e6cf0,112c6227,8ef6afa,4bac7536,a23f08ed,eb8656a3,47a13f25,2dfacd37,c215cc3f,473687ab) +,S(57eb5e46,40721263,97f0d12a,532aa1ff,abef7822,4ba9b10e,8fc95e1c,6075a071,8a700d2c,80df0b4d,7e2c9291,9a51e565,8dd6ba5e,59bf1503,7bf7a0a,935545a1) +,S(b83adb94,ba1874cc,c61ade9e,43093cae,5bd86ff5,e86615c1,abca14cb,6eb81877,93417bf2,1fe01c85,5c6f7782,a5cdb01,a5d13b29,d719f0fb,a2373ba2,8bada7f1) +,S(7a90bb49,71537bc9,3d1bed23,891e43c6,e350fa37,ef8e73a2,3fd46ea0,5ed879bf,ee0fa59,3a51af19,70a6d8b7,22d42bf7,ca253572,2324a59f,c041b3e7,305fa3d4) +,S(195e4afc,6c95d6d0,8273cb0d,fda2da3b,4696b569,650d4230,4d396fb,3e653831,44075199,9dce9d6c,f10ef736,7888dbb3,a713423c,f2881cd5,76a681ce,6fee2c8a) +,S(28ec566a,29bd09e2,f8b228b9,ff2ec49d,56660734,f2ea864e,856be0ff,fd6f60ee,5b4f5e34,298b5a56,a6826143,8ba59d25,4922078d,f36dfdfe,d4e8972c,647fe031) +,S(1e005b72,be1bb77c,80512581,58e940e3,544cc133,a76ddf49,b681422c,1815cd22,9c523adf,4ba5d753,93e432f,491f8e1a,435165b2,f40f79d7,889d82f,8951a25a) +,S(f54ae39a,d074c399,636f0dca,682b9405,4e87e87,3132d7f9,cf79ad85,fa82586d,db2e9b90,1c2dac2f,f4851f4e,b0ffae7a,4c0cdf34,ae9f964b,841c539d,84040667) +,S(bc8dafb8,d385cfca,3643fc75,c8a93f9,792d2b9a,715269b9,ec40d581,5936e6c6,dda791ce,186ff28c,db7636ad,4073996c,4a2e2875,80da17e8,90d03886,1c14aec9) +,S(60b6ea82,627f5414,16978e7d,3c9d911d,9d9de92f,3baa0975,a8de4e3a,8ed3ab2d,64693ab,fd095109,ef89cdb2,204f2f3,89dae035,f451fe28,58fcb4f1,dbff0999) +,S(9c8d1352,bf291803,22730718,5ee65aa8,b14211de,6d73dace,2937cc6a,1ee79134,3c6e0d66,48f3fb6b,23e6e4a9,5df3911d,797afb50,9c12e90d,7eac557c,7b1a9505) +,S(bb2a8344,2997babd,6cefa2a6,1c9d2fc7,a42db3d5,bfb19334,c7535bd5,630be896,20de4f27,69596e65,edcd695f,61a0d8,3c8925a0,c8707470,9e84bd41,615ac75f) +,S(ba8bca72,496a6046,7b250a38,cbb536e3,b9fb9ab1,43800655,8ef5d186,2b66d50a,81abbb33,e835f864,3d075858,7ce59671,7e08c1c6,75af4c5b,eb80429b,9dc46aec) +,S(529fde52,c4d1c978,405107ba,d862f7b1,995ffef5,cba4a59e,d71b366c,28e17b46,ed7c2521,d39ca130,60d5f509,d0a8b0b3,40eb78c0,d4e4fc4a,83318a65,226d0a05) +,S(6e0e10c9,4445acc3,593efdd5,4b8ea1f9,db4a45a1,4c2d0a27,edbe3fc0,7a90e91d,43537a25,d2091290,f753460d,8816ff10,41308e6d,fb04b7e7,d5a108d5,c9fd83a) +,S(b2f90714,6fe2e01c,5cbd73a0,c0a358c7,a05aa730,97a060ff,491f362c,75c20e90,d0e680d8,f7d27eff,12b332e8,a92b846b,4242a746,9b31740,6c6af499,5ab51948) +,S(bf631a7,933e3ab5,f7b8707e,55a9498e,31ec3f36,970bb9b3,f5efa0cd,1a3f28a0,1030146a,387d4fd9,c12544dd,a448133a,49b5a6e0,d4b96933,cd47e89c,608dd5b9) +,S(cd7ec470,e9d5e3fc,a4c344f2,9edcd4df,4b7033ef,5e7ee99,de0db6a8,43926034,3aae77b3,bb008cb6,e982d673,7f78e920,f3a587db,bc106c0a,25c65d45,df8a4f6e) +,S(b3ac95ff,8365813e,e71199eb,946b5888,7dd34b1b,a214482f,dd3b7fa,3b8ce6b6,e3d9bbdd,aaba7887,8e763360,abd370d5,9d941ba5,cf758d33,3b480f00,ec5e7672) +,S(7fdc21a8,6962fced,e6f9fbdd,77e60a00,4dfb858b,5b149362,dae4b4f4,a4ab84fa,2ec0f21c,3d1c6d60,f22817a2,954d02b1,ce6e8b91,d826c11e,f8e542c4,245a55f3) +,S(6f019691,def39afb,103e524a,598bca92,3c99e44d,7dff4866,f76fb6c4,47e6b40b,a225b484,cda916f3,559e5782,3b519827,8bd7300a,c31dace1,7a797582,2a2e2a31) +,S(cb9a979f,c4e8d887,f03956da,9ac89637,579813b0,c3b27874,82961a54,e54c16a5,ff42bdc3,1a837d98,b7d37a38,db3c74ee,6109e868,d06b7c33,d5562dde,b11ddbf2) +,S(2ccee51c,9d63f3e8,99314da1,656cbb15,635928bd,309cde4b,69699860,c0e28736,dff9a128,adb8b4fb,7bcaa1eb,6bfb390f,226b2ae0,b72443a4,5982d559,91d379eb) +,S(a239538c,c5e0b53e,879f484f,7202a52b,d52d1cdb,ca7ae7d0,639850cd,b2c4f57c,6cc1f9c5,8998e347,2c6db0b8,6b1d9092,d3cd0c84,267bea8e,75a172f9,f4879dd5) +,S(e77796ac,c619974a,63476635,7bb3bf33,6ad1e87e,8496bac3,378db956,7beaee90,3eaa4b63,c9679050,59d8cf67,7b7095c,4064534,1c592ccd,ddb7626c,10586f0c) +,S(52c332cf,37646a2c,c1bf25cd,26a6131c,3b243688,9c44d804,d2762fae,618250c6,2279bab0,a19f78a9,43e695d4,53a0dc3c,f0312987,6ccbb70b,1d61eae1,e92729bb) +,S(d68826da,36e5f78c,bf728468,88bbe6ef,f6e55d34,f8b47a9c,8296e662,4ad9bbb3,88ffeb15,5f70c6ab,9b83f9e8,30e2f449,7e661dac,889803a6,d30a2ddb,11bfca5f) +,S(af92bd8a,2a5b0034,ea074d69,a1d7a517,808d3b61,58f5f7c2,d3fb08e4,eb825cf3,2fef9245,a4a3c837,d4b57ded,52009294,c077a801,8f633313,b6db2d4c,92c724b7) +,S(df86fa3f,63d95d73,98872011,c7545b3c,f5f27fc6,a821bff4,5d09afd1,bf76d895,a891e766,12953c4f,37a463c5,ce449574,b1906c63,c192ba4c,67f4f78e,d1e93a35) +,S(a049a35e,119e27f6,e272774e,f470ca50,9a1da9b,a4e5d781,6e64a13a,23383c24,4cb8e2eb,ccc82ca4,a2f82841,34eb3a05,f85a2335,a3b1b117,92886029,96fb3fd6) +,S(b3193cbb,f3c8f3b0,b47b1a0e,5689461a,8da801c2,4c8d51ab,fc2e67b,1d9f331,2032a290,3f0cf0ad,21b63de1,565170a3,edee470,a4dbbabe,5f3d459a,3827c7ff) +,S(ff3cd387,554fb3a,89142ff7,3e97fdd8,884964bb,2f457283,e45b79ae,ef1d692d,24475b62,c1ade1b0,ba36ad93,27916e19,637071c,22fb59c1,f2108fb8,d38ec5b2) +,S(c095d24c,42b058d,c2f77e2b,463a2c7f,1ddd1dae,dd6f6111,11ba78db,26763204,d2648519,61974d6c,cf66de22,1028943d,ceccb181,ae03cd38,fb5aec22,fae54326) +,S(5365a446,389f54dd,8279826c,e1e7df5d,b4a9699d,b8208efe,80d1eff,2d883ee,74625a49,b7856c1f,b157776c,cd79270a,2957862c,a437bfc8,75986264,401e714e) +,S(4c073085,e96134b7,75248412,c36b3b33,77afa275,24c83369,a2477b8c,9851f15e,fed40d9f,a44f64b1,59c290e1,63d1add6,92bd2782,51de71db,e302cbfa,67e508aa) +,S(71edf152,ab95a066,2b7e5190,8af75f38,d03d27b0,3a3b6607,4f472b7,706a3114,c3e6f145,dad44a3d,5cf056d6,2c608b4c,840608bb,aa15a101,c9bd3cca,e511741d) +,S(1b7d41a9,3cba67ad,c145962e,7b2c6353,bfbc8eed,34eb4c27,bfc181d3,1ac0a802,b165e7e4,23c5d880,1bc3bd1,ee0c6778,50986b35,9dbad06e,aabb2f57,dbe553bf) +,S(ce997626,cb41ab98,58f591ca,c89f7a73,bc1df836,716ee74c,45c4c781,eef4ccc9,be76f81f,a8e4b053,f63be23a,5e72ad6b,7aa359aa,e9407b60,98bdcadf,e367b167) +,S(5b0cfa70,aeccd544,cd634d10,a2bcccdc,33e4525a,54259ba9,92c40100,698bbf2f,ec50e655,163994b6,4881369f,b3aab550,65df1a5b,dc6037a7,7c01e56,904660d2) +,S(a03873b9,695ee82a,42b72a90,f0cdfc68,dbedbd2e,a50d5ff6,e120d811,ce8d5097,5947c8e3,56e64f71,b36fc1f7,7ecfc7f,a31c0f0b,cbb05102,775648bc,f2435758) +,S(d6b91cc6,6dd31e59,f04c6e58,bd7448a3,fac62753,68579214,11a8b42c,66084ed1,fec7fa6d,778c0b63,e7dfd72f,ef044da0,903ccfc7,1786f0b1,85edd004,f691a0f2) +,S(896a1313,e0a96d35,9fd42841,7790baef,a40647cc,f56264a,ac3b72df,687b5692,831d4b47,52f5fcd3,4942ca26,95dc86d8,4fe49c73,7c2bd46a,f892eef7,304117e6) +,S(779e7400,8e564167,56795a4f,9d2021b7,94aa9689,eaa37780,8e3a6061,b5bdc04d,739ea3a9,4f38be31,df57c052,362d1872,333d2777,c6704c2,e69271d2,9f78b123) +,S(f20988a9,3a3273a5,a015866a,c4de930e,507b5b48,cc5ba52f,a2a71e9c,185e72a5,6c861907,8fadd612,c0535163,dfa4cf39,648b59d6,4b056bb0,4e06695b,3b51213a) +,S(7e8520e2,3151c78f,9f48bd10,5aff4087,dd90f9c4,2ac33e24,19499ab6,8e5b21aa,995827b,43c276dd,61403388,27b2fb9d,9fbb46ec,af10b65a,a8025971,608f38c9) +,S(98f0e4b0,9e72ec0f,d80ce3ad,eab29913,fe84fa49,1786bd79,7f6832cd,7ed4dc6a,58c42bdd,7ca43579,b45df8f,b2a6db3d,41f75a3f,89dfab0e,e000383,c9e04a54) +,S(31cf38d3,dec1162e,e75eeac6,6827aad,22fa3ee9,abfda002,b6956600,6fe596ec,ceeb4b04,fc6c31e7,7a6260ca,bdf92569,92841221,d60ca74e,81309472,8fff4442) +,S(60766d5b,50cc4d46,a1234c92,1baeec1d,29900e23,4493f174,2f06ada3,ed9dfbea,13debdc8,9795f421,6f796a53,74b87aaa,bca4f73e,fda2ecf,7d151870,179c44a4) +,S(1b0ebbaa,35e8ecb5,a76d9c30,ab88fa10,b211ce3,e7c2b428,117645b6,881c7895,a312adef,e1c4a34c,d9f75d10,bb2ceb29,79184181,bb955439,e317cde4,202b2f83) +,S(b3129f71,c3438602,c9c24ee3,2f997341,26dbd76c,60cf7713,200ffb68,e486fc94,bd4beeb5,70966285,6a15002e,a25046cf,996a1cc7,9a570549,467ac179,b4f145f9) +,S(2925ca17,662f0905,3927d40f,f2fdee1f,66cc5c13,c3587e78,fe48effc,40cc075f,6d37757e,64f0438d,7bfb3658,5df58dbe,a8ab8cdd,89871670,dbe221b7,4c416185) +,S(8d55b85e,fce6bd0f,ff8906d1,6497d35e,4b69e701,da7845f2,aec1a049,39c9ec45,435416dd,9fd01388,b717ba9a,df574456,785cc0fa,c115dc04,8a242270,4a3c77dd) +,S(a660a9bd,b419e19b,16823b5e,dc3fcdde,f1021b71,4debd17a,9a0619a3,aabc23c9,ef6d4bbc,e963bb1c,2edffa5c,ef70e330,bddccb4b,3b23cc52,d5b4a689,e0c76c32) +,S(8896427f,c92bdbfd,59699ec2,222b4bbf,2198e160,94945c77,1f207bbe,4cdd6b0b,bc6081fa,abd2df26,b087acbd,a2c67c63,2eb1a8dd,6fae2454,6f3fa747,be421ff1) +,S(47e5d9b2,3f429484,61ee9f38,2f14babb,f93e318f,32d67063,ed20e917,9894e993,bd17f8b5,6084d3f6,62facae,24e93e3e,29205f21,68903ade,4f7476a5,ba70e8b1) +,S(ff352870,69bf1131,6f530ef3,b32a487b,3f11e6e,f8518c15,b1202a18,4e6d5487,8920338,ccf36f98,4afde38e,1a74528e,86fddfc7,8d7a6964,cad4286f,231462b6) +,S(2a713d8f,eca88def,b5fda7f8,8de9c6cf,9b97bf0,4c070173,aa47dad9,197bae2d,5ba64900,f7d18ec6,8887bd26,d2769b0,26d22e96,1007b58c,b27b8983,a6e7adb1) +,S(853d813d,3133ed7d,a85065a5,755ca0c5,3f32f156,154853b4,b018668c,b165ace1,fda8017,e00d20db,6ee4c0a,5790b504,afc376ad,170d74bc,1261abcd,241ea020) +,S(d5c4dc15,37b048d8,6631fd14,7d896d6f,f403ceda,7de8883e,1ccc006b,6d9ccd99,9ea2829e,64213434,eaaaadc,43ed10b8,28e706a,5001d7df,47146058,8bffa8ed) +,S(f649da82,d50fa298,8c598d5c,caf1e7f7,2bde2cc8,8073b55a,2e43b6e7,5d44905e,4438f4cb,d3e1938a,b461b1e7,b94d8f6a,c6e287e2,50d06da6,67aacb1c,609bb6cb) +,S(adc3515d,4fb7776c,b1592a69,13254d7,afcb20bb,8a4d7529,7ddba70a,c35a7193,49b7bd8b,3f280916,c6024e46,afb45e6b,da5bb15f,3d3497fc,85e9a46f,acec3d80) +,S(d78c46f2,603a00df,b45d0495,c1e2b346,963dc82b,84512cac,c2227acb,383f75ed,76b02870,2e7a3da8,79272759,1e2f81ef,54ed02f,debde8b5,38f9ff1e,4335a21f) +,S(13904467,59e0fc27,c2a499ec,384e0906,bf293dcf,c13ca16f,d3bedfda,d320e466,5320c884,b74bcdc8,6e0c21f5,40c16f65,dc61f19e,9ec5e8ef,385fb637,ee7a3701) +,S(93700603,543ec558,3fe48141,310b184,aa8faa04,6058467c,389c10f3,b98c42f0,8e0acf55,bfc585df,4f8cae06,131753ee,23a7bcca,68354182,61450e1d,e1a136ce) +,S(bdcb9434,4c556618,a247c935,29c5ba74,c68f25ea,a5507148,1431c00d,6926884a,c29b7b1b,ad6ec5a8,e7046cf7,cdf99c6d,15f6a3e4,3c6ce718,9ae2acbd,531bb17a) +,S(839ac85a,9337818a,b07b5611,f67eb16,6342c1a6,8aadefc4,6842c023,336afb08,88b30690,e79fb157,3e424c80,75bc810a,fb9d57de,5464a253,79d06222,ea656b69) +,S(2959c32e,bcf9289,9882e003,c8a28e71,3d491402,4d24d878,ba8bed88,47b949c,ba2643c3,95fac027,6b7c55e4,d2d2f530,318665f1,ec2065d6,eaf32c05,123e04c0) +,S(71116eb0,5def3abf,bff3e235,a0306605,b18aa465,b47167b4,4eb3486c,c442f3aa,2652a726,35be8336,f9b51607,76b3af84,26a23716,871fa64c,898520eb,822d6630) +,S(400c1bcb,dd3e3978,3ca06e8c,2abe8b0b,9b45034,a1655cde,fb748ef4,e2a477af,1471c86c,c8b27b48,1d4c45d,1533a5c8,d46fc3cb,ea4788d6,c48dbdad,6f7670e3) +,S(2a4abe28,5cf94456,aa92216a,dd635abe,71a7e825,712d775f,d61fdc98,a4c9288f,3c0d2483,3d6ffcad,b471d234,4ee8d07,15c09719,b18cb581,8ede730,35d89c15) +,S(cb0113a,1832843f,7e32ce25,15b0b23b,8a803ea7,50b500b6,3fb89f6c,e7bb1884,816d7056,b775f13a,cfd94a6,f88f442e,519495a3,6e74d8f8,359a8a03,16583bda) +,S(4d7be7ae,5c4271f6,c1adeb7f,4dac8467,beae22bf,ae00a71b,1e353be9,5ef172fd,cd7e6415,5708d20a,9fc3b0e9,85517642,f677281b,49490439,14845a36,afe6ca56) +,S(bc285658,fd724cfe,e6ec8c7e,35f9197f,e9083bf5,439fd4d8,d9b262bb,7a3c38f3,80c10d7,59f76b4b,8330c96f,38a1af24,1d1b0db7,4e6befc4,4f085180,c1c33729) +,S(a829ee43,221d9955,38ce8aef,e80c49ac,dc6e71f,4293750c,c0585c1,69963f04,144f6b56,d996a18e,627d4c8b,8115b2c1,c369f410,ec8924c1,73382302,3758ba33) +,S(f5450bd7,efc9227b,e7d28ad6,75ee14df,1b2378fd,308e6c5e,68945ac9,a47d82d1,20201fb5,cba463af,cc46e6da,caac8417,63356e64,5cdcfa5d,9d810c48,272cf8e0) +,S(7dcbdb69,46dcf79d,454095f0,b61341e4,45243bc7,c2262817,374fea5,37a1a380,bd2cee4d,c7ebc71b,46fb3bec,bd6787eb,d2be3128,703a884d,98359c5a,43875977) +,S(f1d6c1db,cc8d33d4,fbff821c,8c788d06,2d906063,2f44a786,585a6526,20ce776a,3696a3c,8473bd07,76e77226,8cd09f96,3dbcd143,e631c32d,5d83254,ada29340) +,S(f1688e1a,d5df4e43,67caec6,f2234534,f65aac3b,79a94ca,32a786bb,9fee4b49,efb620b8,e2164685,c9a3837b,5c6eb70d,759824,96541aed,eb80aebe,4193e34e) +,S(b639e284,3ecffb0f,66c2819c,73787e10,527086e2,5d3da074,e037a915,e06a5813,61fde1dd,63ff304c,8ec99d4,67ffbabe,e8000637,b9856bec,344b825a,4f198407) +,S(11a4ff89,d5e63ec8,6a0ce18,53dde8a8,875c9a9b,f563526b,cd25b830,6e3314dd,9f7ec77c,9a3f88cb,7f64b1ca,f2b5c7cb,d70d65d6,dbdba9f2,68832f3c,a2e117a4) +,S(323db783,26abfd99,2b13d67f,3ae01415,77162203,c50322c5,7a7933e8,7d687d3a,92c8a67c,ec834653,d0f1a50e,a7834b38,631d83ec,ee38e50,33ed927f,7e14253b) +,S(2907fe12,c8433ab6,2e6283ec,85b93342,ecf14d16,6d90cfdb,b4061968,aa35170f,160f9790,66291ed7,d51962d4,be02d85f,8a92ff8f,258a9a07,55b8a5ca,2d57c2c2) +,S(67cef7bf,a58519cb,6c5cd8c4,f69d5cc8,84cc77a7,854a4b6e,a40b6dcd,57e43e17,e8071d35,e590dfa7,4d4f4da2,82033f1b,590b9383,70b571ac,ebb3bc11,b9b48482) +,S(81e40522,3d4ccb14,3952867b,b8398cd4,e5ab92c5,d91066b0,d1fdeaed,55c71165,55357564,af12b507,b2e24e6a,425697b9,e6356b82,da36f111,2b5c3394,183c0d10) +,S(4880abe1,47bcc598,a3743304,1afabe99,fc525daa,564c4b05,2aa60c27,5c814628,b6d944f1,ec69e7bf,2cdcf621,864ba76,a1df44a7,ed15ae15,290ddbe5,b91f585e) +,S(fa2bc507,19131dc7,d5f23fe6,9e60377e,2d2f11c7,f8a9a451,82aa69e6,24eef53e,9b0f2017,5f287d80,41f58930,6cd022e5,9b63bab5,1b26abfe,1a295ac3,46a2e9fc) +,S(aaa18fe1,25e781a8,901ac351,38d2bffa,83cf7c3c,99a4c7d8,54b30c70,c9483e8,6a8f9e1e,a40f6383,6008a0c3,596f7644,c044bf53,9700a142,ec5e3c97,c075b03c) +,S(d473950a,8465711f,71a6f1f0,22f4bfcc,1c16ba81,4bf73c2c,1eca244a,da4999f1,6eccf9c8,aafb09df,46ca0d36,ee9028dd,1df62bdc,6ade77b8,a5d410d1,a69bc775) +,S(d7e2b17c,f8e1895c,cf9fb163,b56f4be8,ad99133f,f00f2ce8,8ce911d3,3b8e36cc,b6557693,ed9371ce,69bf397b,56c0b566,21d38958,ebdc0b96,ca488570,1561e6bc) +,S(3f1e73f2,a2192809,acaecea1,71d175af,683e796,e1337db2,11b6b34,8ba924f0,a593bd94,96308bb7,76b63703,bc11e30a,c5f01c17,c8b9748f,3b4c8015,56f52c3f) +,S(4cbb68b4,27899c92,1c0d969c,94341d8d,161f3b8b,3fe4cfca,2b583a63,eb383dd2,6b3c29d4,97728ac7,b45cf7ce,ea618789,95935bea,bd146e1,6c756f61,4698b6cb) +,S(e41b826b,52ff9bea,354af41e,3004b7b9,edd01e13,8cbd466c,ba4cbab8,d63bb4e0,75d5b642,47388aa1,51d4d8d5,2568a804,fcf66ba2,42b3f56b,dee0350d,ecc527ed) +,S(d508dd5b,ec38f795,88bf2d9b,6bcc9f8,aa96689e,91c1381b,9f8db311,94588028,9b144547,1a2ee559,6584c927,2d779fa3,123a760d,9faeabfa,1e39d3b5,ddac2595) +,S(5276f127,3bad7149,ee5ff022,2769dd6e,973018e2,a9948070,fdc82148,ac637de0,73f778c2,caca737f,acd3d877,14e24d83,964dd47c,f22915e6,212bfb09,8e804e21) +,S(2e9ebbb5,9d108d21,71d28c27,32af659d,b534cd10,c5457cea,3fcef018,4d7761a,229d20ba,cbf0104f,b385621f,dfe386df,4f40c287,7d956046,60eb3923,46937bff) +,S(ad819539,5b94bb1f,4e60ab85,932b24cf,2c79c20b,79a972bd,db1e4201,c49f1d1f,9226c45f,4d161a1a,c5c3c0ba,a0536def,3c6052a4,ec22dd24,cc803a37,b5d791a1) +,S(f5d4baf3,93ee5acd,944b2057,78cae170,8a622f30,68d3147b,62bef05a,88fee96f,9a187396,9eeba528,9f5fca32,6bbb922,2eeff5f6,6d205a0c,78b77dea,ee17d1db) +,S(1a0f5e1c,b2fb5d01,fbcbfddc,da83693e,9619ea60,1669c728,7710733a,e6ca778c,3074e8d1,61da2d34,38be57cc,fc437742,533e415e,5f0c888b,834a2fe5,5d4fd6bf) +,S(a78f6f7a,110cd16f,99fbe16e,9be52782,248518d8,e621f478,2167887,f81cdae4,e3f78e8d,507f9af8,11653ab8,5f2286dc,db34d9dc,8106e9f0,57610267,411f02a0) +,S(c53e4243,b26ebe40,a1abffdf,3c42129c,47e92cb7,32bd66c0,3d4a4290,c68b1c25,bd4f96b5,b5801b82,300b2132,2c39fd2c,65b2d084,e657ba2d,7db5df15,ab960e34) +,S(a3a1ddc8,56957468,2e9b8a57,50bbc738,f72dc60a,1c09c95e,a6559b2a,736535e4,94887a0f,a4381d9e,dcc4faf5,1525ce98,fc43116d,29f68c99,236e4940,6842a741) +,S(8160ee7f,738f54a0,698806b8,35ed4bca,113bb568,b23fd331,ef5f1cc2,80b6230b,382ff30b,f13f1e28,95a38af3,13fcd099,249b195c,96ac42a6,6a929fc7,a907b17b) +,S(68552ddc,6b219554,dbabd276,e0f2a5d9,33610bcc,776bc40d,7efdc1c6,1b992e35,eee09352,c82dec92,b0ae8d8c,d6918ac6,df620dec,86a0e4ac,abfe8025,52a0ab5e) +,S(919fef57,f308255e,1fa802cb,5acab880,c1810c62,c79a4ecf,c2251a2c,cc02ef51,cb38c163,8f7890f2,d61a980f,ed712ca8,97296366,7927ff7,39de824d,207ab566) +,S(d7e493e2,e2c33635,ee8d22f3,76fa8de9,31ed4eb0,9771746,f48ba201,307e04d1,ff7e6d72,f712f2be,2bfffb43,2764f677,62917509,3cf6bfe5,eb5cb7ce,85c1a8b4) +,S(6b642a8d,f4131ddf,7f31dc9f,c26b96c9,286e1f80,de2af96d,52e383d1,ffa73a41,1e55e667,5f0ee13e,76818c02,ce424d8f,48cbc930,b25dbb85,363019c5,fc29979c) +,S(7ade4aa8,1df8c53d,1e64655f,bfe0ad88,4057e0b2,1c88bb2b,4c8d5f19,34794191,cb0e9802,fbf1027f,dd8d2167,f4f4680c,f9e18f4c,3bc3310a,c4014745,530a06fa) +,S(6d578cb3,1ed19dc,812fd360,a367996b,91a7ba42,7d2f74c3,e2a1721d,72e1c017,4ac9ad2e,aab987ed,dc994b74,733fc710,19301e1,f691999a,5161cb15,ba11e9b4) +,S(df95b5f7,7bb79814,21892d72,743abe4e,828a7544,f9f0e774,b1f5ada7,a054978c,4ccd011f,a966604b,32f70bd6,1a3c1515,c6d1b261,a3ce5c59,7078cc9d,f723b32) +,S(d7392d17,1cf72e1e,ddea0be,a242edf2,c418e9eb,7dcbe1b3,aa07ae7f,a11ef08c,4b696f78,20a9ac8d,a5f52c8e,9d1a39c,bbb3d3d9,fb5b38c8,1b46bcfc,90e869ef) +,S(f01f2aa9,82842315,98f414ae,f87c9d7b,6eaf21be,c4dddea1,3967677f,5d2a1032,7c3be753,da5485bf,13a4cd72,a9e3fbe2,28fc6a22,c502b19d,1b6f7d18,149e2b3e) +,S(cee8f811,4b1829ab,a47e9b5a,54de7cba,1f6edfe,624f30e2,ec4979f8,3145242,4b01f7b4,cebb1125,20bb0ab2,7013af9d,11d19c4,14b0c29f,d142c7d,5b903a09) +,S(f4215bb,973b5586,ec051388,203b1c99,cf69b555,6b1591d2,fc711842,759e9832,5d8a5ce3,ece7c011,df3d414d,e62ecd4,2d716c73,cab02e29,621307e0,658e6fe5) +,S(e39ecc23,90c9464c,32b08759,9a44586a,da09af95,ba8a3b30,2cb015d6,4a49b18a,bd7957c6,e1feb061,f5535231,4f5c5e5e,c8245f28,4638f390,d079cffe,bd2eea7a) +,S(9e6bbe6c,402e4cbf,e298e789,458fa9a6,68cfd407,3efb3d25,4699278,760589,989bf3f,9912b242,419c848c,f82c3fb6,8690ab05,bc23372f,eb9a850f,b4dd44ba) +,S(67504bbf,57824cd9,8a3bd82d,34fcb59,3d20590c,a90b5652,c4ea4695,1f48905d,93ebbf6d,3678478f,56ae5a54,cde812f7,d8d40928,21b5e82,71669dd3,f0b263d3) +,S(4e5bee50,503a28c0,9252b9bc,dd28af66,cecae127,2128e88e,fc431373,7324657d,d6891df5,3a4cdf2a,d7ab610b,817b0f60,c2502442,2e40269,a7da80dd,2672e0f3) +,S(7481d5a5,bef3d397,533e01b3,640b0809,fd6ff946,a1e5481f,b90f0b3d,dd05c21,21ee7275,9c217d19,3999df2b,e3cddff6,fe59f26a,e570e0ae,58868441,f37e342b) +,S(778dff4f,dd32f251,6defcd94,188f2440,26b9f789,ff4eefd5,84b2c15e,2bc61d62,996a2edc,f43e10d6,93cc2d00,c6f4506f,45be1dc5,c762fe20,3dce124e,34e320e0) +,S(cf531271,3d65d471,929f6108,12db63ac,b1c52203,eb879ca4,a8ee9f62,774580,38e28f4c,881391e0,55fa7148,2c92c097,c842dd,74a58d6b,5753d6e1,2f773b19) +,S(99702d01,9420286e,723625b5,62c8152a,2dd5f1a,eff84437,8a182cf4,25582031,8c4af2b2,654f1631,82d08bd6,e7f8b6ca,d5365b9e,d869fd23,e5a3c4d4,7e5990c) +,S(68614c88,6b59c198,c49245c1,e1232cb0,b4bcce31,e0a2aa15,9fb2331d,ff1dce66,49c870bc,7ac78e22,b635c2b9,6f29e641,3b29c6ec,8ec8b3b7,8fa6597c,90180c7c) +,S(f497a9bd,3c0e923d,5d622ab6,afeb9e8b,d9b4525f,d1f30cae,2a44d0b3,e13256b,af4d0273,e088adb0,b7de7724,b387e109,d49d20a6,eceb369c,12e07eb4,f28c9e32) +,S(50a764f7,f5e29cba,ed7ababb,97d2ace2,22c06c65,9ce87d77,83b5bd0d,d165bbbe,4abc57c5,4c9f1d54,e73cead6,d77a85a0,8be25ba0,ce96b8a5,1b4fb460,5eca949c) +,S(fccfe1e1,e312e6a3,92e83cb,97274576,56415255,b127ad54,432c93cf,4ae29bc0,e681795f,d8340902,da0018a0,dbb8a424,870e4bcf,7de95f0e,b2c7e98f,47a46c58) +,S(66de61ba,48c1fd44,80d5c78c,3f06c3e2,45ecaf25,e4c235d5,8408c90,e1b62ed1,bf3bf086,a90221ba,711819d0,d80194c,c45177e2,57b1408e,7e649f15,a92aa6a0) +,S(4373e7ff,e3995503,97bdee9,c9d3d70b,39f47446,45fd3c1,63b2012d,58e148d6,440a1376,16096124,42c7bff3,5f9a8aa2,3ac64e8b,bd5ca839,bd3c5a39,b84e6fe) +,S(c8774ea8,7d83fc06,c36ab357,b1fa76b6,c647cc9c,ebf2e125,3f3ab303,9306ef1d,ccbde78d,2e4d2c0d,ace4e660,efdc4d1f,a1dbb44,4cabb0df,bfe29de3,191f7249) +,S(748cb6cd,c57d89d7,8842fae7,731b1e28,3b59ed18,cb761c88,a4d2e4c1,c3359fc,62f5b6c4,11c72d4d,a412148b,8b038b32,8f98aecf,ece537a7,237b9f87,646b9a3b) +,S(35a83610,30fc10f3,53d2fdbf,cf67655a,91b86555,cd3d9eba,f962996f,ecf55cbf,6fd79f5c,df8093db,5c7f3a94,52dbe6ae,bd1ca410,199deb04,761ffffc,77ec9fec) +,S(cd05bbae,d0a8d78a,2e05e9d4,1c33cbd2,8d59d384,75d42389,43f9cc35,3a8a30c7,9f7336dc,8e77fd55,bd0b9e8f,23eedf1f,d0c16f69,921994db,dc2588dd,ff72a8f8) +,S(da3fe760,2547c831,2d4f515a,5ce530be,29379325,41c6de36,364c4b5d,ead43c58,df60bf1a,d2fca43f,6d482df4,61fc180e,5e3cf692,995bf8c1,7d32a263,730b3ddd) +,S(bbd7996c,25ba5c24,a14742a9,745dd2,8c18a598,8279581b,f8b5958a,8092051,896a39f1,310be1c5,9de4b86c,7c9bde10,8035ba39,864a45a3,69573d16,4afbc2d) +,S(bf7c20dd,64ba5f51,2a996bd,428fdbaa,df1853fb,f814e6c7,a415fb64,a3e16070,afaec0ea,2b18c89,93a1a565,f3db58dc,748df9eb,4d9f8a04,a18cdc23,4710d5c6) +,S(919d0aa8,10928129,cad99b09,85bea5ba,7d4ea114,9f9d5d65,2b6c0e0f,20464903,60d9352b,d053b01c,83caa121,63e8c9a3,e2153cbf,b335943,7a2a788b,7aa02dfb) +,S(5e7c2a9c,6ab8251e,8f8749ab,e0ef107c,aee593e1,a8632a6e,1e0e0c4e,d3cace9c,74186f42,6f03f806,36d79258,e9edf593,6e21e0b2,d882d933,c0241ae9,7d761582) +,S(2815184d,af1e838d,86d63a32,db5339df,24731743,aee62add,21e3a6c2,c2b0b1c0,2a4951e8,3ec61221,b1035c6b,a7d2cbed,f6ef93e8,cff69e01,295e09d9,20e05919) +,S(e3086e36,91432a20,8602458a,87d82955,c8920ca9,fe1c079,3eed878b,282ec3b0,13db4219,50388269,cd591c5c,d8e07ba1,b532f01b,485829e2,aae4f55,f05e4362) +,S(8264d534,2db3261c,d7e294c6,eba040f5,461fb9e7,e3fa13fb,dfcec29c,20f2fa7c,4dc311ff,10b92db6,b67f47ad,86fd74be,24e3dbe0,d6a74842,92f35d9f,6e95eac1) +,S(9edbed6,3c4b66ce,a8c2ac6d,89622d61,6838e1fd,9b93c363,c2bde528,a629b2b,c1706a02,5b1f9419,2dde89fc,63ae2a81,ea015ab2,964beb58,d5ca7ffe,84266644) +,S(68006753,672e9ae0,79fcdee7,9814a904,80c170a7,f644302d,e5de7982,7684e12e,fc1209de,88ca7c3a,614252e3,153df13a,6d0e8db0,4c82d83a,fcbe65a4,5c084398) +,S(acdfba80,9e519114,a11b1634,1835d7e4,5b93a6d4,7094846a,e1ecec00,18bc4531,a4e57d02,51511f2e,5b729309,4c50ebef,4f8d3cb0,d930ff48,20d0623b,d636d664) +,S(978304cb,e99eb899,5ef43f94,c67c471d,6d42ec19,f83f9323,3a44b9f2,e2d13896,ab26782d,2c1dbf16,a90f90c,8e49d250,1e1172f1,3e1bd20a,3deba979,85fcb110) +,S(8c8b561f,9c857510,88478c03,866b347f,46e06801,82482343,923d7e27,c67f49e8,e7908d27,79cc5b19,dd00f2f0,4ab52474,5c35cd6d,4b85932c,99614fdc,64048cc4) +,S(d4a7ebc1,987b1abb,5d02e598,190f73a,36d1176,d7f0f7a8,cb9491c1,b86a3c55,4f321dec,9c1832e3,b0d0c974,798834ab,6a410bfb,398ebf58,177f39a2,22ba4e50) +,S(14bbfb6e,7910f522,69e544f2,ad3175d2,3a36b7aa,8209c24d,1fbb4277,9508c261,d16147c7,2a1df442,d8e831e5,aecd54c6,8bc3f225,4d0f51e4,9a375053,73e8d08) +,S(d24ad71e,81de43d5,7096e101,6bd4d99a,46e52e56,782d99ee,838217a0,dfea0f5b,ae574f68,e07cead9,f214976,67a18c2f,fbbcbddf,2bfb6c95,3b7ba673,7d08903b) +,S(ac96889a,f0b46b7,6896b763,8e1a13f3,dd24459e,8601f892,c3367c7d,8b52931a,b68a8631,8672c378,d99b0b20,44b06190,876ab100,eadb12e6,c16c2ba7,c1ee2381) +,S(36b4da52,4f4ad5da,d7396445,1e79bd5c,20973df0,efa82bb2,da4bf68c,55afeeb7,5cb7598b,576f0db4,db1093c5,e6c9723c,f493bb91,450a0017,9f79c8e9,92dd6136) +,S(98c7bc3a,7054f928,d062ae65,b4140dd6,293f2fb6,cd16fbba,e00d39d0,b11befd2,82d134ac,3e614e4e,62b1b475,bbb5fd80,a5e6d3e4,e4572dc5,7cb666c9,a06131da) +,S(95bb18cd,991cdf72,1c627d62,aee4655e,aaed0b6a,b1e64537,fa89a0ac,f60b4a52,c37e37ee,5b87a5a5,e61824a3,ea519f03,dc3b0a77,f755485,d337ac79,f1f9e8c9) +,S(41e45ca2,b88a4679,6df9106b,c8b53180,81674c34,9646545,e5ad9b6d,e5f6cdc6,151ba666,b0fdb7a7,18110f62,83e3cb8f,8e40fb8b,fa1a1854,75958a3b,ec10d197) +,S(32d15f16,dda923d5,c2f1bf5c,9c003b33,b77d2450,95e5ad31,2ec62956,ae092805,58d64c72,96ba6976,d61774f,f37a0d1,6316cd19,3ac0d930,bdcf4924,cd904095) +,S(41c4e029,817de516,8dc04b2a,9bde3850,7ae48602,dab08db0,3272c694,6cf099eb,303738a8,7b888601,2f9e2053,5bb8b610,92f6222e,96968afb,98940d85,98181458) +,S(28b8ccf,b14a86a1,84fc3c3c,a6a7dbd8,763415,91a67d8b,4109f026,1dd964c5,899f98fd,5e0c59be,69150d8c,5a917d6e,864fa15c,63072769,f75f6353,8cb276e6) +,S(f2776367,762d6468,c9cc0e38,d3921813,16dd394c,eaeea519,786b4353,a5044586,1a873421,1b170183,a117e420,c41d2725,84acf219,a415778a,4eb0c34b,bee9a68c) +,S(7a1a5f53,6e96ee57,e10b1337,6bb1e895,d0703c6,5adfa4bd,f24937da,98bd7144,860921d5,67fbdd1f,11aa3ced,103453af,8c3f5037,b92ff10b,ee70ddc,e4323206) +,S(d82e79dc,5d6de6ff,8863e039,60401bd1,610500f1,57fd2b41,f20689d8,889c3f76,f1947dc2,ca625df3,af5ec97d,32e62c09,2139d108,948795ba,5cb164b9,351bbf34) +,S(6a2e184c,23ee235f,93f036c4,3875db01,22416a6d,26ef54bd,85a2b465,defd0351,6c44297d,724eb2d3,2f58a197,2f52a7ad,ee49d30f,c8f8424d,7f26c6e1,73dc6868) +,S(ea0d5281,bd1417c7,2dbedbd4,dff37c49,bf143417,d2a40dc2,573b4b3b,2ccddcde,c7a35ef7,685faf18,c5a4cfcb,2eca27b7,46b21d65,ed71aae9,15185cc2,6d2b54ee) +,S(d5432c9f,8ed0b4a4,c3e42dd8,28098f13,11d2cdf3,94672331,51fddbf2,a6030974,1e047ebb,8cc01a43,2ee6ea04,578513aa,17ad2bef,7fc7653e,936b2d22,bf8f6c3) +,S(c99ee053,655c9d53,1fdd2298,3cc03756,299f47bb,5e1d0a4,d7b861fa,c3b5e332,61c5187e,4e12f8fc,617a5fd8,746f28c3,368b6b19,1189172d,8c56e2f4,679f6b7a) +,S(f41ee431,170be2d7,fd488c3f,5f21f3f3,aae5e501,1a3c4ebe,d0f6db8f,63e11e55,f767b289,118391c4,4d27c1e0,76b7c70d,110cb938,e9c5c62f,1af200ad,7e9976cc) +,S(505a65a4,29388bcd,55561f5e,fb3090b2,2d553bac,2f8cee97,6c0685da,40006e41,c72c9e86,6b4de925,3d463d7,e7bcf7d3,d6e7c351,1fe6c4b4,7fc436f6,d793e0ae) +,S(ca34be0d,48bc2931,cabe71d7,9cd2bc23,ffa928a,5d532d67,f3665acd,375dc01e,263008ca,4dcf002f,8fdd580a,65701694,bf4530e8,baa0438d,b77ec246,75b4db4c) +,S(d52c25e,9a76600,b16dfa93,cf9c2df3,38c806a7,d8cff18a,1d262662,5fed6d7,80309810,6055c3a4,d5d1e5ac,945aa815,bb8ca3ed,10b5d54f,156e4336,39c4ac77) +,S(83e43bbe,62e39426,a0a74ef3,831cb4d2,776d7ea3,d5a2d57a,8280bae6,ae0bd8d7,a1c2c1b4,ea1140c8,cb4ec2a6,98a3f727,666eaf81,1ae9b89a,9e09db39,d1a257d2) +,S(12326a97,ad8dbe89,3181d76c,6d7507e2,74d62cca,1f0a3517,30e9ddd7,198de84f,79e7823e,7cfa4df0,bb31e9dc,ac415297,edc6e061,4fca2f18,1ac7fd46,d27fff48) +,S(1ad3375e,c82aa917,88bd787c,37fef8a0,2071509e,aef62e8a,dd5c5e4c,b096cea4,f9f9f10e,efc1fa79,454c6d55,b894d65b,ff5c445b,f4e9e46b,8c82a4c2,a94d5a71) +,S(8e8bf9c3,a752258c,278bcf19,7aeebae6,fcc198f9,2310b13d,d114c1a7,d10fd2c9,e2f41d5,b7d94378,5f61f572,763e6e88,df7b321e,9baf0445,482d9f22,f1160195) +,S(c44cd33a,144e2926,b7ebfb93,d7d9ab56,3888f6d2,694efbbf,a5665e10,f6e0ff7,c2d4afed,f77c22d2,88f9cf38,a057df90,baae8ca3,1e074d11,bb8f89f4,e9e1bf4b) +,S(b960f0cc,bd7d3431,4138accd,aadc2efa,d5b60071,7c69f1c5,92900a40,ea68b24a,e0cbda14,801794eb,19401935,3f8ab80a,f525b8eb,2b64e5ee,62afaa5a,da4680b1) +,S(f7104560,8fe120fe,5d036260,5bc3de58,76e24b6,20684413,a440cf56,6520559b,2e208f0f,fea3f78a,9a283f9a,6b601ce,db4df4b,b2fda7b6,306dc8b7,3d514f35) +,S(83a31aa2,cb10fc14,ca8cb2cd,b21cc163,41cc9862,67a5f1cb,75f3f90e,1a92c59c,be18918,400a6e32,b4fa3469,ea6e3613,251ceabb,29cbbfaf,2c16af07,fc5413ac) +,S(3d7b800f,8802e521,341f83a5,efdb355a,b60669d0,adc15531,72c62097,8106f6ab,f9b179a3,aae98427,e02d4f00,89b3cee7,250e30e5,ed72d59c,198d5ae7,1d639e72) +,S(7bef4e27,9064400c,48d4f27a,a754deaf,8af74b10,d5dfc497,98c38216,803f50e8,bab0d71f,d02c67e6,b274693f,6a4f402f,831aa4a3,5fd83014,fb07c5c2,e62d561d) +,S(e6b2c83f,2a6ea201,f56a024c,482a8076,2f2053b4,2e4d2901,4a5178d2,3361bcc,75d1f7b5,209cafe4,f98e63ac,53052a40,487b3390,e4ab73eb,ac63acb5,cc3dc88c) +,S(eb4f3b95,f12c16a8,e5e13446,d9b8ca7e,92c56bdf,565aa4f9,bc1c47af,914fd145,e3776908,e3f3228b,ba0c0523,7eaf1963,1835797b,ffd7eff5,61b30fb3,9fcd6307) +,S(e2926c0a,858b9732,82c1b34b,4c4ba4b0,3099797d,d29c5fb7,4447f28d,ff962e54,2730f3b,e59e862b,37ac50,e5375d08,920cb62,b87ee8d2,f5ec9975,886359e2) +,S(8bf4efd6,c11d7251,b06a5e08,99ff2e80,349f8022,387f3200,6d9de060,bfbf3f68,5514395,457848e,a79ba6c4,39a7c151,b497751a,a4a1784f,114686e,e351afb) +,S(4ea97c1b,920d2ec5,3c2182ce,d6f7e1f3,df49e673,1a14ecd7,d67aba0f,fd077c78,5e958afc,d3894757,e0aa89ed,ba26e035,f06e4b11,da13675e,29d382c7,b21fa9e) +,S(1b12e81,3c7c19be,18576f93,69d938f4,bc81bbfd,7e9eb443,cf2b9ef2,b8e2b3ee,47220a1f,718c36af,8eb8a9e7,ecee3899,ddc49127,91421438,8760d6d1,699a5ad1) +,S(7c6c144d,4f839904,ba40fba8,b739913,54f40bf0,f5810329,c4e3b961,ee6a101d,6eebb976,3ceae5f4,f1ef2473,a50b795b,a6375c72,df67d15,f310b5ca,9706b5eb) +,S(ec637ec6,bea71803,2bae7631,9227ae58,9581d3a7,131323ec,35f0d9fa,27a3e285,c12b830f,f273fe72,4f3bfdef,4279ce4a,8ae6d0a6,de5cbad2,b0a7b4ab,643c79db) +,S(33c8d6fc,d2b37103,2426910,6b9adb76,6c76f788,9627a9,6807572,e0af0f84,b3f01db0,7ed82f45,252d494c,af735e6d,3934ff78,c89c57e6,6c42a663,e5d6a792) +,S(35ee32e5,f7204f0d,d48b1a80,cea0a418,1d71205e,c373827b,2afc25eb,e3ab7e20,d57bc815,684adacc,756291c6,87d0eab1,63067976,a7c3a2a1,98ef1d8e,bad12935) +,S(97362395,200d807e,623826e8,3bdfa37b,e98793fd,6d7057f6,370720b7,5089a6b0,c908e9de,cd1d54a,172973b9,1706fc6c,c3367d75,2216c2d8,1085dffa,5627f06b) +,S(bd37e01,eb944b32,b379b195,16256ad7,4061760e,4eb44361,5e8e5fd4,34eae9a,dadb545e,2a613e54,6067cb6c,179fbdf6,d94b7b8b,c799adef,391b2957,2b93f57) +,S(b332b57a,4f070d20,35986e86,d82cc6f,7180293,53bd360f,d3f883fd,68e9c5ef,eebd3a05,933526ab,ba9e63f8,cb24ffa8,550e50d6,8cc7a4bf,215c551,ab89832b) +,S(fe5bf27f,9459e640,7489bb32,2012d1d1,69d40635,74dc05bd,6bdd6c38,cffb61a3,72c6318a,3775b8fc,5c790d6e,31bbfddc,7ee07a71,93e5f137,e3c3e098,bae25da9) +,S(f27cbe27,ed93086b,517c5859,9929310c,ad0e05fd,482f1fc3,af041852,c63a2a23,cce74e61,4e14bd09,8f11674f,23e30be6,b3276f4c,f85dedea,b3cbfa49,5a716e4) +,S(b328535,1a1b22cc,51b7a590,3582dc27,518bbfa7,410dc36c,e63da663,daa8693a,1b260487,7d3ad6e3,db75a0b5,d6b89df,df507809,c203b4c4,cb0712ce,ae2e3d2f) +,S(bb47bb09,70dae4b5,4f4c3aa4,ad4c966,ae42691e,ae39f1ea,a6711d6b,5f04b81e,2edfe19b,b52b7b0,2b4cf349,aeeeab0f,67524375,7f35b6e7,b920d343,e71561d2) +,S(fb6c9735,d4333142,5bf6ad83,50c7241d,b82e35a2,9cbafa37,d822304a,c1b3dd02,946a7ec7,1e0e6dd,a4d4c315,2a6e7489,8671dcb6,8a219781,3e2491a7,6a9e3357) +,S(c711f224,40cb6e74,a60509ec,23daa2d9,fbca44aa,9a093475,524e31e5,43575a3b,e4259800,352d0d79,c5e22d3e,2bf59f4d,e4b42484,68d15c47,ab5a9cbf,854294b2) +,S(9c748d45,a07e141c,639ef97e,8887ccc3,aa84bdc,ca0618ff,4f43b1bc,7496c83f,3dab775e,c3001657,e71a9d46,bf8cc120,9a74b9d5,1025f97c,4dbb9457,e932b5b4) +,S(9d5e6479,81a9278,6db60938,4a462621,23070938,d50e1bed,8df9474d,bee12513,30f2517c,6ff04eb8,9a6ef21,e4ff33b8,e14567ef,e38871bd,b9dba6d5,584c8b0e) +,S(4d24d6e8,91644ed6,ac1aa619,f9eb2b58,a9932c5b,3e8c82cb,589694d0,14b1d472,6ef1a21a,9dcba4d6,850e6593,3ee1a259,91203278,2f478fae,cda13d6e,5abdab22) +,S(fa226c4,36b389c4,50143041,da93c906,70258092,a8de85cb,d20a0dcd,284bc808,524d2992,655c77bb,59258257,5db3d663,a7a345f2,85572ff6,e9dd1dd3,21bebf6a) +,S(d4e659a8,e9af7543,2d9ec769,5dda0371,7bd79ff1,9ba73f07,ad0bf13a,45ad3b77,5f4a2de8,db9814f9,9b73ec63,6c77f847,1aa48356,ff67c8f8,3f0b6aaf,1ac7ba9e) +,S(157b6da0,1556b23f,b6c46b06,145727c0,21d6e573,782bcded,d594ae46,598df23,737d45d5,2c247718,e720fed0,56352768,ce111425,72730890,5a84a545,c53c560b) +,S(d97a6087,19c8572a,78b73938,5479e4bc,9a2b249e,a4f064a4,550ce127,fc4bd45e,f11e233a,75ba1651,144368b9,55bd4dd0,f4ba1f2d,2d0bce2e,82315e5b,78e0d76e) +,S(d2fdeec2,9b5f4ef6,374c2b87,57e4867b,d2e036d8,964a2ae,15632ca4,6f79a294,2d2c1502,a935f5b5,960abbda,9db42aea,c9f58f0a,bfaccddd,f8d59881,e2953872) +,S(fbc6a2b1,b3c0b039,9abc55fa,835bbeba,b0461db,41f3d9f3,160d0154,72861b3d,54421d5e,a5ed3abe,f22df1a7,26a2b5da,a298b41d,acc69bd5,a72952a2,13f928c4) +,S(7ac224b,cf7efd8d,b214db6,a6601d51,829d57d7,28c4c3cc,398ba57f,5079bf99,edf12fdb,9e281367,5e7df40b,1cc3c572,55213edd,c0fa07b,4e3f750d,36d6935c) +,S(f2bc4452,4af39f04,afb480c2,f7addb57,a04db86c,3691b26a,922b6ce5,a1724d9a,63c372e2,4a659127,ace8f54d,33969635,1d890dbf,7e2a31c4,251352ed,53c3a0bf) +,S(5ac48ffd,bf27b452,ca37dbdf,83f2fe6d,8f704040,f3a56180,ab991228,a74ad88c,c7ccab4a,e859e7bd,982310ff,2b7eb408,678b6f21,f52ebea8,41021f3d,fab6f091) +,S(daa3d659,a4defb4d,3291a16a,d669a43e,b6891e90,dbe0147f,568b650d,1213750a,af36d811,9ce1ff85,5dd637a3,bd475b10,50216093,aedf5f24,2c98da62,29bdcdbf) +,S(381d3791,30d4beaf,aed138d1,4072bbcc,b8d71d6,dbb13226,ff168f64,3bf55d37,fbfd7b62,3ce32a4,4335682c,d5ccd4b4,aa4430ce,d8fe3d34,9582bba,fedaf9c) +,S(757c7b23,ff6b6ecc,51ac84e6,26ed70ce,4e6e5c74,e4b65f3c,fd17c304,e19b1ccf,56848ab7,f814a047,2bd286f6,b386af5d,34b27c4e,a3ece71,f153dcc7,7e4027b8) +,S(ea498d11,ca35804c,d6103185,ae468bec,6c2f4f6d,ab025173,b1de4027,551b913,ee939bff,8d30bf5,9e3341e3,58acab90,17de8fb6,e2977847,f4322ceb,ca8829c6) +,S(9d119046,59ea5dff,30105d1b,5ee3f8dc,c9291bef,15844057,66e07d44,72ee1418,45355041,4d4715d,e8c087d4,f05b5f8b,a424ac3,49b3ceba,bf806b9c,e657e139) +,S(97bce776,90f8790f,e7d82b68,b7dc1b38,f3baded3,f7c67655,1894fc4f,cd1b834c,fcc18c2b,4f743ca0,e00f4b34,509fc237,c030b689,83451d5f,e7407b81,ed04f7b4) +,S(5339f056,abeb4926,f46dce7,3b8d735e,c6e9c4a3,2057c22a,49c86400,f15d7ed9,5be6a0b9,37e26dd9,f6db74a7,74fa10d2,cbae30f6,bdfafb,dfa2922c,58a8e37e) +,S(27f22d01,4dc5d3,162f39c9,7de3ef62,f2275b5e,cc6d5e32,6ab064ad,f762a446,6aebbb58,d671179,d712926e,d56cd280,8393fd85,dee45558,300a0f8a,a2986f09) +,S(94af2fff,61741cf2,5f158308,e7333e3f,678bf1ee,56adfd56,629312e2,2435f9d5,33a7269,79df6672,b13198f7,e674330,806f2dd9,50d8e82,1774f381,d9ec24d6) +,S(ae8a0e18,486273a5,36d526ee,3974031f,f3ed095b,a6835a68,2e943dc7,e19b37e4,23c2a51f,69df1826,9b21413e,505c0785,576fbc84,acbb2812,fda146c7,f5e8c8c) +,S(623fb527,d3d99023,9f720cbc,64478e0e,a0b84b28,5c0c3f3f,107b3e3d,7dc430aa,3ea48a8,d1eb543e,ade4a55a,f909e62,14e47d26,9471dbf,4d98a3e0,39c72849) +,S(1ff42295,d85e98be,f7aa84c4,47ec854,29f01b4e,c87371f2,b2025ba7,1e31a768,d9500f9,6e8c697,7ecc51d5,7bb7dfd1,3cc97017,58bb4196,b0b11d1b,3c24937) +,S(bc808b0b,67bedaeb,2e7a4bc0,d328efbb,1ff35dc3,b51716ca,3e501a3f,956aed3f,6af0de4b,26a6378e,6d86378d,d1f54243,929c37ee,d5c10bbd,86b80c3,ead8e545) +,S(e8ab92e0,17a9e956,354203b5,5d7b15fb,acc666a2,79158016,33a91865,b5bb46af,3e87cbd3,66926e66,3f5faa,426a9db9,811a9db4,de3a4bd8,79073b7f,c1e3197e) +,S(a7bf0061,c383040b,6e89ba95,b57102ae,2c291ad6,72bb5027,3c27fcd,f90613ec,79ac8ff2,4bbc79cf,431f4159,4852ad4e,2f0a9f86,ca72ac11,9d4e3fdf,8746539f) +,S(6841bcc7,22b705e2,759ba4e6,83d6b83a,19ee6b4a,375b38f4,5722474c,ca41894c,dac48021,5c168519,d147a966,451dd63,7838d236,5667803e,80658faa,1029a7e) +,S(d67e6d5e,a1606817,512f1db3,9033829f,69089a41,902189c5,20f0202b,8511479f,9cb4a747,7224f93a,8447152a,9fdf4c92,36a1b698,2e9196b5,a4355715,b9fd6ee9) +,S(61b3a7a0,53c477b9,e03d0a96,8ba38de0,b02e42df,162a13fe,8ad538c2,840eed06,94c07520,fa19457e,8d98fdbd,d9a9bf93,57642cd8,1b48fa58,b4b14a89,cb6142ce) +,S(cbd26d0e,a00f7dd,4b0b26ba,7358b2c7,587e233c,3a13c86a,d5022ecf,c865e4ba,50e832c9,d84ff55b,7ba79035,559bc889,53700622,59dec3cd,8b3eda3f,1f2b6e67) +,S(17a6f57e,d3d729d,c5ec018e,1b69394b,1ed78e59,6c7a5e31,bfe5dc43,f9c67e56,34f16cdb,c23e46e6,bda5db2,7538d7e1,f66751de,3eb05543,96c66a54,36bdfe9b) +,S(eaeb62d,93fa13e1,ff9d9a4,9eda40ce,dd6006e5,ced0e8b8,c02f7ab9,98f06f31,7e225365,b4b39204,b01c8890,4476c141,1c166f75,1726718,8ad917c4,9a719ad3) +,S(d09999b6,c35d5d71,55605a17,e7f82d3c,dd8d68ce,9be252e6,99493031,a39c7487,9165e761,8dfec3d7,cf733fcc,e548f672,362637aa,8687f47c,b1eb5c18,a780b061) +,S(2b4cf8d,7fb166d8,a6931bce,e67f580,870c61c7,635632a0,71166fc7,4a11c693,7974e2d5,164771d5,2e7a121e,2b015565,b3a874d,d6313721,ec69d3aa,b44d473e) +,S(d5c0045f,a411cdea,470d85a6,66aafa44,49ed682f,a1903c5b,c9594d19,5cbebea6,ffeebc77,5b24e736,8a8b46a3,64837466,85df5c8c,b40bf2b2,291f370e,94c6eca4) +,S(1eed08dd,d9569712,6c0a4039,c6aa5ae5,ab4aabe2,a88142c3,b9aa763c,632b5e38,d180547e,c4640035,ca86d925,10a70a64,5dcbf2b5,d3add4b0,3f6d0fba,5f4c2f8a) +,S(9591b04e,3de43104,3a6982e1,29a2e79f,f525888,846689f0,44e50b18,ce14413e,cc4cc696,73279c51,4aa4fd63,474050b1,930e627e,a1bd9d55,867d700e,fccf8155) +,S(690a17c1,b2dc7ff,520aecaa,380b19d6,d4a28669,83dc5df5,8ab2bfb7,6c7b0600,bdd8a858,e2d989ca,79fbfd46,60ffdc0b,e0231562,711b13d3,47cfd37b,7a53d4d) +,S(800a632a,aca6b505,f9fddc22,14efe53e,4e7ad2a1,a6c07d90,27d8109d,893851ab,bf242683,e0c1a24c,9220c6ab,deae8baa,12c6203c,a0080856,bc5e5ac6,4c3f3261) +,S(6dceb824,c48159d8,57a92334,4c72b4e5,cf2005c5,6fadedaf,5a8b780d,3ceeeab7,e6b961f7,6162ab6a,d44f3fb4,5aefc843,bf0d714a,1a50d13c,68036f42,30a1ad10) +,S(3ef5eff1,2b76432c,4bdfd1f8,23bdfdee,f60b5d0f,5d0b4051,2a3e22bb,665f2b0,8741e43e,9f78066e,d57d317b,d50252fb,11d8d235,3c2c9d57,76191c21,8798b0a9) +,S(4ce8d33f,a53f2e1d,aa696e9a,2de694df,2192db5f,8e6fe88e,b5d51340,83791c17,a023ff40,69587bb9,49ebb15a,d047f141,9985b521,ae915f54,bebc6dbf,5320558f) +,S(da030efd,a3f6363,926abcd1,182f183c,43c4a6d8,8bcb0519,3d137827,6dcd3fbe,c14f27d3,2251248e,3c4b8613,481e7c48,f1493b6e,5c0716c7,8d5e3b97,876ccf3a) +,S(65c12034,87b729bc,3709759d,beabdd79,ee7f50d7,ed2cedfe,f2c2b7e9,97192f40,f440d69e,d59adfbe,e087ef70,9b75b95d,13ac0e06,20683d3c,6d49762,ddf68a01) +,S(82c052fd,dbd6aceb,1f429f21,eed34d44,f915e949,7190aa6a,d487bd6e,68d91c20,90dfd944,c7c20ec4,4ce35d2d,4036eb97,894f5b93,6bef62a0,f2f65082,b0f7678d) +,S(43e2f20e,cab47065,e71abd8b,aa511163,e17e3efd,3e17d790,ba924de5,ab402255,6b1ff657,e37b65e0,bf2c5e60,47e36c8a,2b7ba965,79bdc711,c3ae5935,d2c47bed) +,S(27f177cc,6722e5a7,70200e2e,a9198bb9,f227251f,8efa1988,ac7342b0,985a3853,a76767a5,3743db5a,1062ccb,64452ad1,606d5065,9df8c0a5,64f049f7,764d6a99) +,S(6b1ce20d,d15cf54e,59aec7fa,c1919791,c40c926c,55801801,75c09ac0,dcce0147,c90a76f2,627d2510,8b89df25,23f069a3,6b102201,c2fb7e9c,932ae678,4a28906e) +,S(f9df6109,27b5ff70,d55d2a46,ebc6a734,df165bab,3bd27398,24a60727,5410f62b,4da454cf,7a381056,581fb115,d36161a4,4beeef74,26724d,d4f5500e,3a6c1612) +,S(16bd87e8,2f87778f,6b3f1da1,a04bc048,3b14de01,420b0074,81aab07d,ad806cbd,13a50b5d,886047b7,6898c85d,cd1bfb4,87642f95,8304d54d,12c03b25,9429170b) +,S(f35175c6,2244f0c3,ddb104fa,3ae57557,424c2d0e,f6a20246,e2fa48d3,2908dae7,dfc1ef36,8ffb4e8,2076ae27,7788444b,33880ee5,b6d5bd0a,9a2ba79f,30c4d1ff) +,S(6a9ec43a,b8a6cb70,465ba668,5e15fe2f,9e714c0e,31f1f227,186d95ad,2faeccd9,ee752bfe,4da4feb5,e4c0266a,57929e56,62483704,6e927e73,9edec593,8d538708) +,S(92e3b0b1,3df6dea4,371601ba,3d92f507,2388a23e,302edf74,6da973b4,613d2292,9442966a,dff82878,f6e0b8d9,9e56f99c,68eea310,79b365cc,5f057eed,ec38496a) +,S(35427db7,f03afb34,d13ba232,420e5d9c,4a8d16c7,924a2043,a217fbd,4287230b,5cfc1908,108fa47c,95ff8e02,634351d2,523dd990,aee1700c,7cda57c1,b106a734) +,S(a61be939,d3a33b8f,65b8fb5b,897598a7,ee25e71,5797014c,fdb087f1,90895825,fa6b7a9c,f2a4a71a,857bb126,44fdcf27,c9f4ccf2,7bf6a0d0,dcf8179e,af1a3396) +,S(659868b8,2a9422d7,1da877f8,59956376,b999dc3a,657278f0,89e1b7,a3014222,9ecb6c01,fb97f691,92402a76,13f7932,d8a82252,e6b97c66,5c727d9d,e6b2ac62) +,S(12667366,d27bbe3a,d75f00c7,b28fcf20,86e9caf6,e8b5615e,eee0f180,526602ec,dbac0f9c,32895bf1,21c90190,d5bfea81,84289a4f,a0cf498c,3a3084db,1d4a833f) +,S(74af3ac2,60461898,c502229a,8eb4e7e0,962c8f38,897e43f,6e421ca3,3240b7db,72f03ec2,7c24abdc,dbc9af25,41e10f51,5e470c7b,19ab9680,24eecce0,954c84cb) +,S(9aefb23,d88c5745,da9606e7,ce81d4f4,5a39c8d0,4f5d5f07,62653594,d3a34732,f797796e,5c1c0a56,9886af6b,fd8a8299,29ae1897,ca43314b,cb6ed78c,6c0b0572) +,S(93a3da8b,1f686078,1849ca06,24c2cec1,796f64f8,4f46da9d,34766eb9,dfc1f018,e5c50d0,fe7d2f53,fe1053a2,985d2b15,25125981,30de3cce,2ebf300b,4b944c0) +,S(ed8d18c3,f526a062,bd6095cc,249b7d10,ee09d072,435218be,f2ab6c90,c5ed66a6,42084909,f4bfb751,5ec6da47,2cba7678,7870a9fd,bfc86fba,669e31ff,233a72a2) +,S(dba838ae,b57fad4a,6ecfae8a,acb50123,decb0f60,b702a9cf,7af7d78d,814845df,c3213cec,8f225c2b,fc02519f,dce1f67,5ad59b20,91381f0e,feef93b0,3c6536b8) +,S(f1a033b8,64caff57,21857094,e1038fec,7879765a,3b977a4a,c6616162,68c1d8fe,9592b8b9,e4cc6a7,ce173980,e68fc405,88a83788,a08c6027,8623ef61,ba81b652) +,S(53967cf9,7058ad43,1222e9a,46caeba2,d8fa447a,6b0295ab,f40b8aa1,af1f0097,e8e86c76,cef5299a,9a15a6d3,4985411f,2a71b8fc,99f7a76e,230052fd,d5309017) +,S(2477d3a2,bc3fd88,6daba319,8c6fa6c9,5206bc1e,955e9d4a,c6e5916e,5883eae3,baddd174,ce70e285,1e7ed788,cb81cb7a,3402276e,d94e6e72,f20789bc,ec4f5257) +,S(b483c05e,22824454,52f44e9e,287bc21a,634018f7,babd1252,d7a6bc70,24d9cdc7,5d7cd9d,23ad04b3,3a7ccdb0,38676342,5b2338bf,48d4f910,853e9100,e1f3aadb) +,S(6ae41ce9,6c8f0a33,674f74a4,587db25f,7c368fa8,83abe414,a3f6bf13,840d46f8,d52f2dc7,d4fd791b,36e6448f,5c8f746,759e68ba,994de0d6,48c6b1b3,58476871) +,S(bd1a4d61,e19ce013,d06740be,c3ad88fe,bc3b2391,45563be4,41768f01,45f4c450,88c18e77,c5313848,bd19bf27,374deffb,1f40e479,9687791e,675af225,1141fda3) +,S(1d2fccee,47b4553b,215dd2c7,f26412d6,73319507,43136454,35426bc1,29b358d9,93e52147,c13791f6,aceab8dc,95df1637,83d985d8,3a4426d2,f825d126,e7b8c564) +,S(322cdebe,5aef9ab,957b355c,e8e4fa7c,23f23f83,bf311785,f0fc40be,ce0f7453,2eb8c80e,561e419e,f898f772,12eccab6,e6c4ffc2,5daf67b8,47853a6e,8475d19e) +,S(c7474f42,5491fe9d,51a9e00a,a42bc188,50d4fa36,c19d9869,6939962e,61e207b9,8dd394ad,799a69c8,da550741,7352e7a7,92a941d2,10b3f65,f634cdc3,1f42a875) +,S(ac33b339,1bddf66a,6d04c62c,da618bc4,1ad217c9,7d37526a,38d12e28,9fa9dd30,602267b,59fe438f,ac57d14a,8dd3451f,acde0be6,c8984b58,7cfc1b24,34ed9688) +,S(158e2a30,36f71701,2020f476,dd869974,66f157a2,27548e65,688ae79c,3bf8141b,fac16be0,6033e61,d34d1d,1e2c95ca,6109dfa3,64232edc,8f8f62d7,19ce6303) +,S(88384c6,42d1bdcb,af5b472c,2f7a54b2,11ae4947,433d5d35,add21374,33ec4b78,3c3a484d,5b8793ae,203f90bb,476b4d25,773b268a,8e89dfb5,dcb17576,166b3e7c) +,S(21e3c1d6,32299e3b,5da75f6e,7ffa2958,e5d686c2,6322491a,2597dd44,f6973d2,9866fc69,7b9399b7,4307b1ea,e27eda12,590bb138,b22485b9,de6e3cfd,8d23bba6) +,S(abc484c2,6d06ec8,bba4170f,727055de,2611145c,8e4a33ea,56507b60,3477d319,4f92a638,17f6b635,d2d944a6,b9194d40,c4ab7041,2a8ccf05,e2fee038,58d87592) +,S(7a98d6d0,202f4230,a12fe9d2,e321bc55,a3a3b35c,92443731,cc8112f0,579b08fa,bad00e1b,578de9d3,73f0ea77,85502035,c5a04c98,8904923b,f0059a3a,a8ec6285) +,S(282e401f,57ef51d9,f9a10959,d272e0da,e9898f32,d2a3e059,4a65c901,cb1ae10f,6bb8b543,e9461164,a66d55a0,adc51ada,4ac311be,c6625276,5b2c1639,c803037b) +,S(5259a2f8,3dacac1c,18a9a64,d9834c82,e862169c,7a1b9d24,2b521c4a,d7ec4274,196fac52,458c7d1c,3dfae8b8,2ca130ba,99d43a40,8bf41da7,d2e9d040,291f165b) +,S(cbc4fdda,9ed1707b,59db2171,38e9bc1d,eda499c0,78f22c28,4309e184,cf906081,2929df0b,24074d42,75e8a861,8f064466,9ca0dd45,752c7d5c,8cf32661,f8a1ebe8) +,S(96b294a7,ed8d4916,21f10b04,3c2a5ad8,88b92c76,3c93f375,f6d31d99,64b9cef8,f5502e33,f1416c8,77cf06f2,5752998d,a30ed434,365b8239,617ab3e1,65948a96) +,S(287e1f0a,a510c8f6,273362d4,ff8d96f0,dd27113a,b45d0bf0,1af5d5,d24f5038,4b5ddc1d,6c9c4423,1f27ebde,bf4afa29,df337f18,2a2559b0,33de6830,cd7b9e14) +,S(eed0e323,3475ee14,5160d4b7,49210f47,c58d7b26,95dc8036,eae0e6aa,91a545bf,22407aa5,430aa089,3f7218f,2ca23ea0,16eb04b3,3c967e6c,d4c68ad7,16e4378d) +,S(1417cc87,72c932b2,b1116b4d,ab4e86a6,e7d80fc7,b082a6a4,c148c50d,177299a8,66e06245,56f09207,ab2d944d,167590d6,44afa2b7,b598b92b,65706271,d7b50e30) +,S(af6029b8,93c549c7,3544e849,b01ff2d7,b991fb98,2b8a3baa,b9f1b8ed,2b24bc89,dea2973,a97bcb6d,3257121e,9233956d,43ea9155,8105559d,ae17db09,fbc14f2c) +,S(dbb5544d,d28d2510,8a91dfa5,9a3c7538,1b4173c5,eecc8e18,b5065fd8,fa4fa570,4f84feee,755215e9,15abfbb,ff46eb6,9148efbf,39f69261,a9d2a345,3aaf1bd2) +,S(50ee1b42,be9598e6,3fcb0467,18786633,18b550ec,16645f70,869b231b,674a1878,8f4fafc5,fb1e714d,f52c0a10,55016f9f,3ca57c9e,48fca138,68464b8d,70c6b2fe) +,S(77b88613,4bcf9ab7,a1a6e0bc,82137906,d5c24607,a6d4812b,a6d1c8d9,55a5669f,2ffe0de,c5426e8c,92fc247f,a024f1e2,86668e7e,d7a24c33,2c887946,4cbfdfcf) +,S(2bf83837,74a9b9d4,7acfa6cb,6010fd44,620f51c4,e076d5b7,e798edba,21d7fb8c,5f336533,5203a820,a9f75f58,61bf2d0b,fcad07ae,9e297433,79d22b3e,a75f40f7) +,S(207b1218,9a6c2653,69f66738,b2e61d3a,c43cfedc,bd9f94fa,2b883991,ae69e350,c43b15c8,c08b4592,70c887dd,d15cbe95,d627a3e1,4a1c7afe,da2b0c69,549649c2) +,S(5ec76ba9,63dbe3e1,d054ad89,7a00c7af,f60f043,d2472f6,d3369e87,45637cbc,b66d383a,c4ec579b,8350a1b0,b2751fdb,f2ab329f,6ad63cdb,d6d46e35,944009ae) +,S(d010ddeb,3959bd8a,7a7ac178,ca573326,b578e940,b46f5808,12398722,42e13c94,2343d4e2,a380fc9f,617ed8b0,903b722b,a707c53d,a2140021,403ac617,d71fe37) +,S(49157637,c5c47498,5590bdd0,e4a8cdb9,f9bfd422,99812950,9ed25a49,7dad0da4,2564d49e,5c53c818,770c8a36,6e92532b,59fb90ef,e7ff4dba,c6baedc6,b792eefa) +,S(7e39cef2,8285f9ad,1b5ea712,78720954,f4933546,bcd7f9a,b4c7bcc7,54147a9f,6bbe4096,c4c107d1,c361befc,75916c87,6a2a0da5,dde637bf,1f125a21,5408e78c) +,S(45457311,84171f1d,aa931d3c,16b9926,59357877,84a4655c,54822c9c,1685761a,a13710ad,597e7da8,f4b12c17,9afdc5e0,5fc4f05b,e204567,9314149,9c73b421) +,S(c0bbe693,23e256fc,f69f0427,74c59091,287bc0be,82f0b5a5,6ea8f957,6d647d8b,c22981fc,6a015c20,525a0bf7,a9ba8ac6,dab6256d,d763614e,ea250c5f,fb433231) +,S(bb224b39,ff7d27f8,1ba86e92,a6897776,85074fa5,48b5515,987df332,15dca58,73bbcc60,c3adbb94,651cb73b,b311f690,6995d611,8b8238c0,4519de94,1e6bd47a) +,S(94489617,8b4bb641,9cdce312,5d863395,7ea54002,7f759e39,a8846551,ad3a0866,4a16c110,7730cd80,55fb7ddf,93c6deab,e3282da3,8a35d79b,3238e8ee,c8917935) +,S(9ae267ae,a964e8de,68398609,d6351619,4019778b,2341696c,7e44f446,dc8fac38,6d175dce,e589920,851c02cc,3fe3dfee,e9398e53,7742249c,e2745713,fee236c3) +,S(9e237d91,a6ce503a,65dafb47,a9fc5f7f,6dbcf3cb,b026ea73,68403187,d95afd67,64d491e6,df79eadc,74c198f6,fbdc481a,330d030f,851c7fc9,63974047,ddf2d12f) +,S(a5c5e0d4,920f0e3e,6973b71b,90ae2b32,2fa16960,b850eefa,1e516b4c,37252d6c,1aae183c,52ba9f14,f06c57dc,b483ba6f,740d6bfa,7ebb72e8,266895c,e6f6551a) +,S(a6d0cd83,9a198c9f,62bbefc4,b91b696b,57a4f876,6a16fac8,1131a9b1,1b36bc1,97981c96,9f758543,2c810b09,460c07f8,8520e78,3e68529d,7a1d3bbb,e0a86e85) +,S(4a75be64,16d6a87d,49e393c8,a26467b9,4b43887f,a90a25bb,139626e8,58b122b6,ace3e92a,c693f8d4,210932c3,89d4275d,75a46c6f,a9a76358,39c26288,1b8f83ba) +,S(1559a339,7f1e1195,51d8b4c0,fa53b5af,c693ab8f,843e6b00,1a6fc435,5967d7ee,8e450f28,78b2e9ea,829e965f,ae4484be,7e98f39b,a7b0ecaa,b777914b,848f324c) +,S(33565a48,44d9b25c,109eb9f2,9546fd5a,3f30d4a6,157a4e69,6029420a,21f74deb,c8141513,c4e370e2,400b8df6,208e867d,9bcacdd,d87cd975,8f91913,3ba97557) +,S(b49c8814,23db909f,c68c73ee,3995a7db,89e919f2,dc697855,357053a5,7ce26988,65878108,879801bb,ae412aff,72e83051,bb13c415,60499b94,8e0831d3,c2e11fb7) +,S(3a9635b0,b82585d2,37068f72,76291c4f,cd3d211f,80fa7256,58e28dfe,920e3e93,a1711c74,ba4e1a1f,f0a9b6d2,12c8b995,7b6c8c0f,f71da246,154f13f4,719f0713) +,S(ce6dc56e,6f5c496,71a900c1,ae531e3a,a8246877,98044497,fc543013,2572bff8,1af98ef7,3703f8a7,6fc88e9e,c9134aa8,a9e24326,314bf4d8,2a0c85ed,af291f8) +,S(a945a79f,1627e79c,9ce1cc5b,79ad02b7,c07263a9,11f8f78a,ad314049,92bea11f,f41aa315,4049b7c8,c9bef95,f3462336,ccfadf0e,16c1f129,26a5c9e3,7a443bf5) +,S(3debe447,a5f793d4,210e1607,642abdc3,c3a8d446,5a553a45,d73ede0f,20819dae,c0463782,dc5383b4,f7f81557,efddb90d,30138670,858c4197,5a47e6a5,565e339e) +,S(dba32245,a37b5636,9d7120fb,a99880a5,aa590299,601c6cff,d33238a0,395f8d2f,d589ab1f,ff442551,12aa1283,3deb9b43,947059bc,9cb1b32,4d8a29e1,1da82b2e) +,S(9c52bd5d,1fd61e1f,8e75f23f,f6e8baea,a8b7b5e1,5e780870,ea9f8dea,2b75cd56,e6d0a620,c116a7d2,2b2f797c,da7119be,556cd834,caab1007,e9a8ac02,f8945859) +,S(1ec28a0f,24e8910a,85f3c583,415afad6,dc5e10be,cc600749,8cbb40ea,b80fd383,c616ac82,bc6aa8b7,1a3cf89c,b82d7e9d,ddb95761,dd64da13,290f6bd4,a4ff907c) +,S(4fcefc4f,134d223b,994c1274,bd39655,878a35fc,2f50e405,ce11c76,1a6833c6,50c62036,fa49f62f,ab1781da,ec17a13c,4ec82c57,7993fd20,c5c56d70,145c2a54) +,S(85481ce2,90bb32a6,eb0fcfb6,9cb9fdda,580d8808,5b09611d,2d8747f6,ca657e20,ad2f9361,85aea05b,6a0d20db,9b6620ee,ee718c2b,2ae1810,42f6bf1a,2b3a2453) +,S(11aa1424,7760f682,3c11cf4f,12c013f9,7b1c9eaa,5ff0a504,334d2e41,f5daebfe,dda53fb7,b09620c8,fbcdf9b6,605710aa,f807dad5,c7ee4e9f,c7dc9c34,23302646) +,S(908c4f4a,15c58b2c,a0512eb6,b07c67d6,5b08b99c,13d22358,a52bbe24,b3823dc0,5e708db1,d4b37459,e33db06e,21a45fa6,5dd5c959,22ee7b60,7162a77,d89fc674) +,S(d192c334,65630164,2edf01aa,d974fb7d,af13ce8b,2c8975c6,ddde145c,1a2784c9,96bf7877,ced69d6a,a71f0908,86e2dc9c,f6529297,a2f8500d,d683b6a7,ebe4504b) +,S(8fa0f7a1,97138152,75f6c886,245902ef,b6e57515,c28732fe,d49b7f57,c19c6b9b,c09b428a,e54fe6d2,effdb332,4b1fc1e1,11aaf4dc,965b72c5,f97a8a97,18fdb68b) +,S(e53249d5,4d80b59,31d40779,4c550ff5,d6cfc715,13e0f419,4d7b42e0,62e74681,face5c4e,f404cf9a,275846b,11339448,d9133e1b,470489ba,64c190e0,b73735d0) +,S(9a1c943e,7f7178dc,c4453de2,d578c4e6,ab80d538,70c03001,a7a4d5d6,fabca0de,6ae6fb2a,1a7d87c0,99f6eef5,dea6a53b,a296824b,d8ab0848,b44d1216,c2c0789c) +,S(f0d4f862,dd60a74b,e06c9478,1b14b9db,af5847f0,baa00a97,72b61857,bb3d192c,6f48f413,90f9cdb9,edffe12,859b82ff,f8f7b32b,b655f3af,f28175c0,8f1efd8) +,S(1f474fc9,f6ee1699,7a7f37b5,f10f1d02,f2445e12,ae17324e,cd31d2e,c6fb8e1,cbb396e0,4b754b24,3dd587a7,d71eb673,c41b0fb6,329013a6,8ba95dff,c6d0d9c4) +,S(dd871b68,1cf78706,61bd7b4d,1ab259a2,1636cedf,39ac276d,5d36f086,fc9ad4d3,89456fa8,cce6295e,56cd18f5,9d9b83a6,4e4983ca,b55d425d,730726ef,12958dc7) +,S(5223e3b8,3809df92,8db9f4fc,d2b81408,96ed1b89,e6480fe,8a6b815b,bc7a33a5,95b640ed,128da08e,a10148d9,6f53b9ce,e53077e4,64eac3ca,1f604225,75b12182) +,S(65f26a8c,88fed562,12f11676,e2f237d,b4c500e4,a4ee0715,ae2e332d,74c48815,78df921c,545b864d,7ebe6c36,bedd987c,51ac9d73,795b3c8a,2a125d2f,2fb8cbd2) +,S(b62376f4,bd858d69,dc5d2757,b67dfdf7,1d3f770f,e96a0dce,3c61fcad,ed0e2586,c58d5af0,d669832f,4ff38f98,298e9240,c6202343,4e829b0d,145093ac,9ef023f0) +,S(a3297102,6001a6ab,ac0e84c,bfc4c829,4c607d6,c2147833,b1f726,752ddf07,b2c820e9,35502858,eea3b657,c15173fb,d1d45454,3c4fa17a,591a20d1,802d5c65) +,S(3b6e214,94773849,46056d4a,dec9e5c6,86f9873d,76accfa4,b4a377ec,84081339,d7e8ac79,e03d1cd1,7c83ad60,6a140b26,dfe67ed1,254a46e2,9c527cfd,c6afdf96) +,S(ff6aaeab,11cd4c80,ea69c3c,a10f09a4,40b3e51,abf56ee7,2c337414,f3220264,71d8a65d,7a605e01,852f0fcb,1bccfef9,147007f5,7c6b83d0,ef127b0,fe90bdf9) +,S(a0800062,64942e,b9bc70b9,f40bcc7b,52c0d43a,b4d608b4,ff65d73d,75fd4a87,de229122,80c1d66b,364fc250,5b3020dd,1482e43e,c4e67ad2,f2e49ca7,df9659b7) +,S(7c2b8b50,7e2256da,15afa166,84dcb7e7,c437b925,6c042450,6025a551,cafadd5c,747b5b36,e247939,7dd719aa,6ce55c0a,218312b7,26adf84d,eb7e3820,57a0b375) +,S(631c89e9,ee8a3192,c593ef08,baf3fc1e,d30a47e4,6a4ee9b7,e1c6cf5f,d6a0a5e5,8d49bbec,85a5245d,ecf6b084,fc65c697,190f8220,cbb84525,a344263c,ae10e2af) +,S(7ee8cbf4,a0b12cb9,d598835,bcf13fed,72e441e3,bc4b515,4182cf7b,f2818b3c,ea3b208e,70542467,a1e09248,8f34b44c,3821f0dc,169c6037,a7299ecb,25111774) +,S(69c085e5,86fad3f9,7b94d5b4,63b937be,5a95905f,eb33b25e,11ef9e8d,6b5ab3c4,5badd881,779a04f1,3a7333f2,dfcd0fb3,6167d168,b86b6a8,27640559,6e5510c2) +,S(951c09f5,563288a4,e25284a5,a694aebc,1e4b3d45,db0f0ef5,86ce87ed,237aa05f,a0c2704a,fddd2f24,462ac715,cca72894,7de034a9,2c958111,3f55c58d,83911c24) +,S(ba30b632,6ad18aae,6d87a1c4,6af749e4,6d639106,76f25f8a,673d0249,5e813e42,6c174bd6,3def5d0,2ce342b,1d0f895c,ef792f42,a97768b0,d091a92b,14f5192e) +,S(53a1d69b,77ee7d09,f9530860,31e93038,42daf062,c1ec9f19,1328b346,559fea0a,baea6eed,b33605f7,4bdac4e,749650a7,256bf215,737d1081,2c805ed5,298de5b6) +,S(23635f56,f8122da0,91d7e3a0,1125b99,a0f87e98,a717dbe1,f6d9528e,82f9b4ae,1a326517,904ad591,43f0f733,8c98f11c,2ea0fc9b,54e9eeb8,c41e469d,ef0ed297) +,S(c574946f,79574d9a,32c588bb,5cd8fee5,dc60403e,81b11fad,cafc69be,67c0eb67,d2598c1a,8568e4bd,a477d9d9,909b083d,f55a7116,9ccddf5b,666a8b61,96e2f73c) +,S(966bbcbb,4d397eb1,91ea2ecc,871fb24,b0c47469,33df7b03,124408fe,583db143,11741ab6,a38217c,e55bba9f,1c7f41cb,2e69e54a,8a78cf02,60bd3d2b,22789b8f) +,S(6ebbecdf,69e6e137,ad70cfd1,741ed404,4b3620ff,15a07f8a,769edc8f,c1aa1667,2ac87d70,baa106f3,a3490b56,a5960f64,fd80160,d0c14d64,ca1d40c5,f244c57) +,S(815f7f47,8609fee,733b7239,b272afdd,89c2f984,5da8186f,4ee8be2e,2e3e73ce,a972e06b,388be908,86c1e324,e1d2b953,18e99ef3,c0120906,f1508732,f839b930) +,S(24799358,53364be7,4675e3e3,c141e64a,febf3a04,386fa41e,f19696bc,5d3253bb,d6233c69,ec254367,673bedc7,1319641b,f9c029a7,2523f8ba,39dc375a,df245804) +,S(db32eded,dc803ff,d5a1f3e7,8437efbe,8c098fd8,e05f2aaa,c03e0daf,50ba5622,30ceea35,22ba7bbf,2ffe9c1f,bb817fb0,748efb45,65d01eda,9f9cff5c,b5afdad9) +,S(c5fb9cd8,8408cd00,33592de0,e602ad35,74e873be,4442d0bf,fe3bf837,51601689,a604a6eb,85233ccf,ef57fe7f,8a73c430,10e94b8c,4189225b,fe97637f,e7b97935) +,S(7b74932c,71dc26be,429f53eb,efc29905,bdf088a3,f2cf4bb,9828b701,11798163,e07d2133,c628a82e,4a22f58d,710b7d88,892cb999,2f921c28,3772310,c72909ff) +,S(308a025,4f659ac0,7c4e0850,738a2f16,df89ca15,fd64b35f,8f968413,b00b2819,4b4758f4,1eab6491,a8b50fc5,17f7767b,add40ea1,7b1272d4,1b1adf09,5d33c990) +,S(26a78f16,95b595f,63ff1b4c,cd52acca,ae650319,e67554b3,a77f85a3,637fa8ec,3db38db3,ca1e5dec,c73f2192,c4af6ff,66842a38,c76d62c7,c5958fcb,67f38097) +,S(bc440e62,f8524e7b,aef0af7,38e60a61,b213ab6e,713fa9c7,66d28785,891f15ec,175add64,8d472b3f,1547970c,6de2a57b,d2d3833d,2e847810,253b3712,f4d740aa) +,S(f2300d54,ebe04aeb,7a9409c4,3f2bce46,72d9937f,cf7e2a86,c4e8d55a,ef2a4e26,59e0e44b,9e090bfa,5291f436,6a3a5336,a56dbc96,65ae1aeb,e71e8c7d,e2fe77af) +,S(4d34ac85,c64d7d4d,97d40331,3fc19118,ddf31d19,18196594,d2f7a08c,db951c1a,551b6581,e6a1949a,4bbc211f,30fea215,5da8389,a69f6681,96f947e5,f7c8f7f4) +,S(53c3e6f0,fa2795a,adab1a45,a0f30f00,5f0310e,2f989d7f,d1f4504e,d03f2c04,12b382e9,b867a8c8,55461627,b7996676,880784b0,19690280,e709e91d,93048a32) +,S(259b0a65,79eced6b,2dcaa804,ff86122a,24e0d338,165a3013,9ab59f30,343f9ed3,27195af8,5217e109,33e2e1ba,57ebe333,9910c84,9b4e8f6c,af5700bf,93395635) +,S(fe07b39c,f9bd07e7,980b45c2,bd791e14,450eadeb,f6c41206,e73c101d,51093908,a8e47a5e,7a7cd98f,4f5e0afb,b5cccf03,56491271,c85fe0e4,9ae12558,721c66fe) +,S(7f38bd5a,87e2ebd4,526bfa35,5ced4f47,87c404c7,74e7f481,85d40d10,894210a1,4073ed4,cc499ca9,e7f8ff5c,f91f9c4b,782b6e6,f6225edd,d6f69fa8,b0b7fdd2) +,S(8796a424,9a251ecc,c0b3b44a,37edd05b,e34efda1,20926343,3a099e7b,8ae40a82,c02ec680,2860ecd8,f6ac62e2,845e8470,ff60cc55,10bf0179,49f95517,c1dd25d5) +,S(cadcc04b,9d4d8e5,22c153bb,def50fc,941cf94f,bb3b254,61422a4,7e6891b0,4ea1718a,53d64935,ff01f0c3,37ed2b7e,a31f9a15,edbbb60d,bceef362,8a454259) +,S(f2e614fb,346faa61,ec752d79,f9518b1f,e8f535bf,75496cca,513fa961,77f571a,1831227a,b5a35867,82b30fe4,720d2467,68f8c358,8472100e,fea76526,4581fa0) +,S(cb10686b,d361e64e,d82d6aab,5373f62d,b165d3a1,30bc7022,cb3f37ab,d61adff1,d969d37d,9c3db8d4,2c60a24f,44abdf65,b19fc6f7,56a452d6,7ef1b099,613019d2) +,S(6e903855,15042422,cc16d104,962352f0,2e86847c,f816468d,5754c70,fbc6d3cd,cc49058,80b7c15f,6f718ff0,ec2d8544,62e636c4,3e20dbdc,ee318a87,2d52d9fa) +,S(2c0a40ca,38f70b73,ef4da636,185c8260,e50643ff,9b5a83a0,fc0d410f,5526ac12,3f1eda92,8c32cf57,64d768ef,7a6afeb3,89dba8b7,e5bbe5d5,29b50410,5136ab15) +,S(1da89240,4f7ac31,136097f3,ed3055ea,d700aac5,a87ad4c5,49246211,f0ab0d0,e20f1baa,6ca3514e,ed4ceba5,9afe1875,c717597a,b7dd3c37,6d638e,287bd49b) +,S(5113fec4,172e4cf4,4eb27c6e,932e1d93,f16b3ec5,8c791b3c,e22c9bb3,634f76cb,7b129bae,b450023b,ebf81c01,bcd486a9,b494884f,b005b2e9,48eceeae,a6911760) +,S(a8d236b7,bff53a1a,fe23dd5d,63433dd0,a267e05f,31bce172,f80c5d65,c24373c9,698101e4,33e8a6cc,45b07552,7aa4ffae,3714324f,d5da0ff6,4fbc7123,773dde9a) +,S(79b2cfbc,b5a0c79b,d2ba680f,a1b594ef,4b2869da,3baba7b2,81cbf373,9d6f89b6,df45bb38,a21f4838,9e9eec46,f34eb6a9,78967e6c,5d181a92,e989e275,45756aaf) +,S(ba0eca95,4ec16133,1245f4fe,d70b725b,97393053,84fb962b,d1a0a014,cc403bdd,7bb5626d,2ee7d5fb,ad9cb623,7ba48440,26cbc27d,651811f3,92682622,2df76258) +,S(69609368,c01a1920,d3f62310,311cb7d9,cfca4659,1f53fc31,1f0af251,1f99fcc7,73ee24fd,32b08bef,f4254bf4,51614b2b,c0269e59,c6caf25b,bedb4919,76186894) +,S(c0b4d69b,d2344ab6,df9d8427,d480296f,5e0333a6,4a447302,5eac698b,e916f676,817dd44c,49b24aaf,627620c,ff7bb843,a84c7eb3,cc7e77c4,f65ba06a,14abd07a) +,S(80fd0f21,435d42a3,5ba377d4,e2401afc,dec30b21,db770277,fbab9841,3c5d9f9c,502f305a,a3350f4f,50d418d4,9b19768e,4976020d,8e158f2a,6cada628,e79953fe) +,S(7e18fb26,a881189,e3862fe0,9006e1a5,e07aa6b,39a5ef66,4f52547e,1cd7ebcb,dac9006,d99e8a47,d3c5539a,508f3f41,c649d475,4a53fc43,2dace107,1112ca84) +,S(a5b8503e,3f7c067e,628e5f5a,e65a0891,74385de9,69049aaa,26df1906,ed85af56,e9cc7458,fda4c95b,6b502498,95f4bdfa,ad9ed7d,346609ee,6549fa16,6e98dd1d) +,S(d93f866,450f7693,689bc9a4,644b52a9,3d006ced,d284332,4dac7fc0,bc6ff548,94c7526a,14b30b8c,b5a2b33f,c6508dce,fa141bbe,b6aba116,cf3cc169,ca094b08) +,S(424ec330,e4f5dff4,31ce33ed,1ef8293b,b8cdd070,12b5b18a,67b3f4c4,d766bae3,94f29933,fc5ee8a9,27295c4d,8d28b3a3,67c60d6b,13247616,a4dcab96,b58e2dd0) +,S(58805d5b,10cf81e5,b114c372,69dd5dff,cdf7e153,370a8305,bcba9d3b,7ebfe952,15e7b2cc,3ab0ab9e,a36df4bd,ce66bf72,8c45e295,d4a6c94b,e366f86a,ab39df5d) +,S(dab0c80c,a05aa70a,e626f81d,7b85c06f,b418ca69,8067b9fd,83cc6e0d,6a3949e8,4c728c4c,527f9839,498aff2b,91e8a344,aedb11cf,7ab9486c,ab3c7014,3dde8e3) +,S(55b54261,cd493b2d,7dd46f1c,78ad3983,787a37e7,ad8092d8,5cd6a55a,b870e09b,bee36be0,1168a67c,13faf147,6a614b6c,bf7b149b,4600c93e,4ec199e0,9f7fc63a) +,S(ea4f2da7,a5cec770,d986ba06,b1f18ec2,b3907a44,47fa2bef,4c9fbc10,d92afd4e,18f9565a,41583c3b,f7015986,ca7c94c7,4222b81a,9ac26eec,e7954baf,cb470072) +,S(5d835d26,54e489c3,d726f54,bc06ee3f,11390023,fb8d16,61f76b2c,29cfb78e,83091f39,9d1bfaf5,216add5f,dd4d60a3,469aaf82,ca6bf5e4,1070c03f,792dcb2e) +,S(f5efa7d1,484fe717,428e9f54,88c12db1,c775073e,27d028bf,7def8c3f,4f558774,1139d67,793faccc,70c7f48f,c892c314,988d4767,b9d6fa2a,2f2b632f,367453a4) +,S(132950c1,6f24a24f,a907cc59,704692ed,b6a5d254,79dea8d8,38cd71a2,a5d6542,b1e87d14,db8725f4,e2c2522e,c2f3f290,11d664f0,e6e85368,6c142c3,bfefd736) +,S(e479b0c5,478e49b2,c9e211c0,8e610b4c,1f1917fe,5960ba35,9af83c9b,4640d05,66ab2af5,3ffbfca,fdceb064,452c8ab4,b112ed68,8bafed44,1b66ef80,92144364) +,S(41b8288c,19cfecba,562b30e4,93a4c796,dc3adc21,f0c7a9d1,6adf4459,375edc5a,3ae93bec,6f438174,b3956d57,d9dcf29a,d673f6ca,74c96120,c22018dc,fea42398) +,S(56696d31,6d3cb87a,a3eb312e,1cd41768,2d0183f3,b91f605b,c4389d59,d86052e4,5e96c041,e495e90e,2812c09e,81d431c4,eca7274a,2204cb,a3a00a0e,650c6b21) +,S(ea36425,bc35c1f2,f0d96a49,ce4f4446,72848c5b,ec47d7df,6ac5cc30,d3968ebe,b00381cd,a5c19740,a266e63d,d59fea3b,d3d3d3eb,c899bf9b,da8090f8,1eea766b) +,S(84463c57,b01dd5c9,b98e0e4,38e221af,58c0e077,20540b7,da0b4d89,b3c36502,deb3a24f,9a0305e8,812fbaa2,f81e5fea,fd24c375,6a529c3c,c2bf4aa3,8d87b30b) +,S(13a22d5b,d23428f9,912df3be,eb82f4b,411fb39b,1604fa7d,4db63862,293c2310,99a19b77,c6912900,1047d70b,7e84ed80,a8427709,67384cbc,da11a158,6ddfb1db) +,S(de017231,52bdadcd,21b028b,4cee806b,89e98728,f91784d3,a418d7b1,22aaeb57,7ac0a9cf,15ff4a0c,f7d8a0e9,d2fe1469,1a08d526,7e3475a9,381be3bc,64771e65) +,S(1fc63549,9d462327,afc13d0c,eecddb5e,e99bb085,55076d88,7c064e8e,e40396dc,841f309,e47fb335,d2691c43,248a151b,426f1205,ccba170c,7c644615,54258a55) +,S(323e5acb,f821f131,7ff1dddc,822cba0a,b3b2380c,ea2f1b76,903c906d,83491dda,afc25ce3,b13cad24,6f6d9a2f,71e97d1e,e31bd2b5,967a5cc,7ebb1caa,adc7ee) +,S(57b1ec40,5c187317,ff9e70dd,2fd0eca8,cf2b94f0,3d7737ac,dd1468ab,61f56384,247e6f6d,7e2e70ab,a8d50794,36b1f6a0,b27865ac,791d1f08,c334013a,4ed93386) +,S(d6f5f80f,80586e87,5cd322f5,7836327e,225aceb5,6d8a83b1,6cf3bd12,4b581074,e925199,b597c7a0,a179cf34,519ca3a,f35b6d9b,24d76118,ace70f99,f1932979) +,S(2fef6c2f,eaa8c4e7,1cd31179,e0bfaa85,95d26471,fc36be60,1df75cd9,94e73c02,eedc9575,5bbca159,2271bcdf,d9ec8bc3,466e4b77,36d28abd,e6d68ff9,b9820f06) +,S(e488b041,358bf98b,11cd31a7,77a7d93d,e9cb3a61,c49fbafc,4bdabcdd,7b895964,755147d5,ba8f1d44,4ed0eeb3,d072c11d,f448c132,b9e06f4d,66f92ab3,7114a1b5) +,S(ba2591b6,35e7747f,20553589,11e7165e,618b6150,222a70ab,afa66bc9,a931cf35,3c60585,b16b1d07,7bd578f1,85e76bf6,77ff788e,a9b2caee,6c64ef9b,143ef487) +,S(ff4b12b3,cb0ec8d1,750c648d,6ed2695e,a41f8e82,58ba8b16,bf4727ba,6120ccf4,e2cbc52b,f0031efa,74c1fc8d,25466888,41c695d2,393e19e7,287bb34f,afb689ec) +,S(9e42cb1c,aaac0c62,47e4028d,501c84ba,6279b39,dd17424,73c2cd10,9bd36063,c9d0d646,381ca19d,528d2ff2,b04aaefd,9f8095a6,8811f8e3,e85b5ff1,5a5da5f) +,S(610e8f14,eb180ac5,ee435530,812941e3,ed7dad5f,c7bc7924,10f296e2,449fe005,67632a19,b1567d77,b0b5f013,77c6a05e,9261ca50,d010340a,968d8507,877fd4d4) +,S(f4c4230,443f3324,7be7bd5e,5cc12a0,27f0ff23,ede41c44,beacedd0,64789752,55d7b7c6,866f6bfd,29a410e9,8d5d5e21,98719d60,93e2bafa,697a8b5f,734d8bb8) +,S(66221ff,1d344797,1f308b89,a26e993e,c4d1c05,2c2fa436,3729c9aa,8c9dad0d,c0c78a0f,be8ba04a,932a7d6d,604f0fac,4ee01452,fef801d,36d3ca93,c4b7a965) +,S(c3ea4e8d,f8ac15b2,1dd251f9,7ebd19ca,2d91e97e,b13085fa,98294915,6aecfcf3,a7286bd0,3bc8f0bb,a3d28b6f,c513c4d0,472225b7,aab70f62,18c1a735,b31f1547) +,S(762ea616,8b3056b9,da318ef7,53ae0cb4,ff57eb15,8fff58ec,7e4fca2c,b605a49b,195d761e,9caa7603,ff1b5ab9,85d4bdb9,d128ba93,33d6cd94,f00c62f2,9452c8e1) +,S(50cbfa1c,f9a07c2b,42783077,8cae738c,3c3a0d5,617b8c6b,81914720,25712a6a,40a37fbf,97da5646,a653ec25,eeef583e,15cc1db,5bee9ebf,addf9706,cb14e689) +,S(bb8b806c,6798d001,f0d6b31d,1b17cf31,7a5422d4,3a906a79,294e5243,e22ae3ba,46b763df,b7a7a967,75b6b3ac,d21cfa37,a187ab39,99506c99,31623acb,841d4dd3) +,S(5491fa1d,88f0c9f3,6d87e074,331a9a6d,c17a5f63,b1e3326,500a5bba,1f0081d2,6c206f15,7dfb29d0,3b0e5878,57d1abb3,5f18b260,45c58da,87e8c128,7f699a83) +,S(c9d2726f,5ce823a3,ce02ee66,262d0673,f04ee272,dbc16cc0,27068850,cf472435,ff62f77e,60de3ae1,52c7f943,c3eed295,fe6a7aaf,8e6ba0df,bb60a8a2,b6081aef) +,S(a0d934b4,68151a34,cea5ff0b,d002dfb0,ec51df7d,ca5afd35,56acd53e,39515256,2f27f413,ac43711d,fc69e5af,785546f5,8e0da1d0,c9e89271,c8933b21,5998a999) +,S(342b7a8d,a3664884,1d8198dc,5e17b669,f4e602bd,5dfb28f0,95b7751e,4ce8602e,cf36fd4b,24cc36a2,806f8926,db6951a4,4c545076,70ee674e,8e2fefb7,e33f65f0) +,S(1f0993db,1084fdf2,6b2fbcfc,cf0c8a24,124c2474,92acbcb9,6221b788,18542b87,fbf92437,f6feeffa,4e04267a,c8dc57d0,c6d521b0,2631c20f,876fd9f8,b00793a8) +,S(f8f4034b,d7fcc9b4,256433c0,c2b40f9b,2f45a117,3a371707,f6ebec47,e456d9aa,cd895dbe,d97ab95c,b3c98512,c46a538f,385b9b26,5438f7f9,8caa245c,c680f54c) +,S(c80f3bbe,d409d5a8,cc0502ec,d7d95d8b,69067e61,fd2e8f7d,45f06ba6,7db89a33,dc803aae,6b936dc7,27773f6e,17c5d2d,af87a1f9,464320c5,4fd0cdd6,d7ef5c1a) +,S(b19fd3c7,8ee32a3e,dba4d6db,bb1464b8,5b3a5865,7f0c06f8,31af5b39,de2b436e,242c72a1,91f17614,8ee25c12,e0f8d4ad,52837a48,9b94b16c,27c8053,43c8e523) +,S(c88c52f8,a658160c,b10614bf,c744f668,ac46b774,94592a1b,99562a6e,e6482099,5a2f3a43,bfa6873e,7a198ad5,4fc0e3cb,2047f268,6396231a,a158a5eb,f4aa3170) +,S(b5f02d99,8f8f1c5a,8c8995b0,6879c804,1dca6f17,3666613c,efdbb82,820164e0,8e39ef2,207f5d31,2e36ce55,3569d2d7,2204a9f2,500ccff8,50bb67d0,a0802585) +,S(4d4e728b,5da0713c,18fdde5b,290d24ae,f7150d42,f9e5625e,f05bd17b,124f8302,be413caa,b7c77064,91110243,a20545f,8f9e5357,49ce98d5,cdb41384,5471bb5c) +,S(92832d03,32f7ebae,b67701ca,a0a2bfc2,b36b6403,742f4ff5,ff2ae46c,242dd226,cacf8955,92bc2fd2,90dc5b5f,b4185159,3e4a6a0,709a51f7,32e8c554,7cdc4114) +,S(2807a982,b4fc3fc0,8908fc5e,b3734a83,b2e2035d,8c6e3036,b16f9ac2,f4bba58a,ddbb9f8,3a9a6ae0,9945ebfa,9cb7e7a8,49798032,8545379,df582f93,72cea69e) +,S(e755ddd9,139cc4fc,b266477d,645b4efb,b02088da,752d10af,aee5ff8a,45df9659,fa7daf3d,605846c6,35e2534d,746873ab,cd502ee4,27e62c45,ef66401b,c816beae) +,S(93c33dc5,152a9bf8,31c3cf7e,ea833ca0,485f852d,52a255f3,55d7e67a,c1964f63,4a3a36df,13c8cde5,48feb589,dc56eb16,9a874272,c7a0becd,d40554db,cf4d8f63) +,S(70d66e2c,8f934356,d6720d9b,4809b984,6c7ab1c4,f8604990,d2e559b,a59c24c,24e8b668,4ee0062d,7bd79b3a,c96e0316,dcbffe2c,973ff6bf,e99590fa,192603e8) +,S(c165111e,fc2d7105,f6bde2aa,7f682287,2d803fa2,ec904380,27195cc,147904d2,c71184de,f408b79f,32086d4b,2b0e5d95,aed6e0e0,eb99bfb2,7e917abb,8d3a5e74) +,S(12144a63,67cc355e,e75486,357b0c79,ff4fe703,57a2f89f,3e3f7e20,ef860204,f2bb05e6,e55171c,c839fdb1,2b49ba11,dfd53af1,7a5a9602,4327f93,940b8491) +,S(3179dfa8,bd134725,3988033e,70f806de,fde9c6c7,aa4a6d43,a5cf110d,6fda7828,3133a35a,ffd1f24f,579fb314,2e72590e,475e931e,8766d462,842972cd,70e49344) +,S(51fe3e70,e5f21b21,1cae97a9,d0fa49bd,166dac17,5087ac3,a93219bf,d17ee77f,f3309396,5677c691,2a987cc1,5b3f016a,4efc22c7,6f89f562,4830f09,a9fc9bd1) +,S(2d7c98c,a224ebd2,a5167017,88018bf2,1f29444b,6eeead79,dfd9e503,7fe1680e,abae552b,bbeb09d9,dc82af6a,eea16d50,613c9314,be23eb79,d254a16c,decdc02a) +,S(c356823a,37dc335a,918a5553,bb0dfb9c,704ba647,d6cef22c,1e71bc9b,dedaa333,d8715c0c,a0ebf8be,d79ea3d0,85a70d2b,b40efecf,7dded60e,13d0577,cc235e3d) +,S(91af0d4a,56a75616,e9cb1351,4ca27ef1,b7411d9e,5991be14,c1658450,71a2b3f,f6c845a8,76657a63,ed37bd33,46ca60ef,a8fd151c,24a9e35c,5893f969,2580e26) +,S(6a32ae36,93ee1e7b,77fe8418,7266e6c5,cb41c7a7,37351cea,987a4f80,a26cbe00,2816504,dc3efca2,67e4bba2,5d4c9dbb,e8622e99,4a712503,37320925,ed5f64db) +,S(5851d327,5e18fb4d,79292e6e,2bd6bf29,b6301e08,7b418ac1,43afdf70,7d880901,1e17a9c3,dfa8c3e6,c1e9c34a,785321a6,e58d8024,c61cd02a,8b83ad41,a2366211) +,S(233a98a8,9fec3399,f74d99cd,7d5d4894,1be8274d,8f7ecfa1,f4f3693a,fb26a654,e9d5a9ee,fa5e6cbf,9ffe590,bd7db1fb,b9e08125,93f42238,65298e9,eb42d7fd) +,S(8751bf4a,9676e2f9,5036c3ea,97749d8f,f452f67,cd1259c8,4c39e8de,9cf796c9,4f883d63,bfb0a01b,e26b31b,53ed8755,49ed6c1e,4b67a160,7fb68be1,7b845711) +,S(a21126cf,7330697d,714be16f,27986c9d,cca4a0f0,3a12b6a,d54ef31e,d7a3dc23,3b0e984f,565d9825,2c523913,d2d90a26,b47973a4,8d8669f6,8dcb4c62,399b9777) +,S(8123c441,96d17ce1,c6c1a9d6,2aaecfb4,cdde74b9,317599ea,450e62f1,5639c3e4,406c585b,c9aee3ea,dedc117e,d58b1c3f,db5846cb,6eb11592,469bf958,6872b068) +,S(6f8e1a45,c18ebfce,2e2f710,efbd7ffb,4f107a32,fa6a46a4,caaf8ee2,37a22805,b36a7c4d,712315f9,a89b5ac2,8d1a5d55,5ead81,d7c43b8,8155eee2,b3ba8d3b) +,S(51db2e94,7e75c9d5,4ea07ea3,35942071,5987090d,b81c3b99,40b85684,2b0f0bcf,70967acd,454e6ce8,ad015f45,e0578940,c95dd818,70268d0b,9782a595,9a1462d4) +,S(84e0b0fd,b16e03c2,cae53675,4eb3452c,86ef07a1,ba278abc,d5aeed37,f71a3151,5a8e435b,53a4b51e,2ea659b7,1f3371ea,dfb28579,8b062eda,300664b6,d3b204ed) +,S(ced68408,c2b01401,fc039059,5140ab68,14142b7e,d69a64bb,e6ec5d85,be833367,76ce2478,28d2581f,6779f723,327fa83c,8cb10451,fc34625b,d069885,3cfad07c) +,S(8d860f70,a32921af,6376c310,bf5093e0,572e9b3,44e9204d,f5487554,c4f5484c,6dd24078,cb9f8ea0,eeaa4f4,3f3cf99c,890966c,5da8fe0f,9cd70128,88907cfa) +,S(6223ee77,4e56b9e3,da6e008a,eb3ba06a,40bafa1e,84383ff5,65f98286,d9095d37,ebcec7ec,f750cde,9ff7972d,172340c3,c324d843,f31db269,c3f35a62,c5f15f36) +,S(326943a5,5e7b7ca6,951a78dd,afd00e10,c8ca7f6f,3c01a038,ffc4fc7a,20fe2c63,b3bc5a8b,c87ba023,ee22bb4d,3f92cd81,787f2af2,4ecaebe2,67fe0a86,21c5d201) +,S(f69b5d4a,eb0b550f,851f601c,92698789,f9f94821,47a0ade8,c8a19fe0,5742731f,2a74e8bd,94469645,c8a328b4,24975dc4,93adc83e,4baddba,6c41e10,3b58e90c) +,S(f69a5a88,b8f13bef,a987194d,6b00a79b,7e576749,3d180fe0,32a1868a,26d853ba,6eb589cc,9c51900e,a6d99110,206f60dd,cbdc368f,5ae8dd48,cea05218,3415cbfa) +,S(c00ffc9d,8a57cfcf,9624a812,dd2181f7,195f459c,3b858a19,864393bb,1d1a269e,3097e10a,d6abfc0a,3fa039fe,952034e7,6bda4fc5,c5614092,b124ee3b,bf55f87a) +,S(9c021c49,d6671103,cfddcc3d,8e54848a,addfefa1,d6de5455,e5bda021,126dd183,4fa1ad18,81362f4f,f0587b52,a7a1b483,2d14127,434ffc4,c5bb90e4,fce50834) +,S(59aae0a2,923bc36a,1a5bc8cb,ea5bbbc8,b34f1504,4671a046,eb3090ed,3f4b2345,659f89e0,faa1577e,36175240,2cf1736,a18b070e,4d4b0fae,9ed08297,362cb246) +,S(7ba1ee89,479254b1,f32e9e53,517f0961,79d17d81,3ab3666a,75d4bf7a,7113f252,6530b40b,7e66a084,97168778,61cffd96,5eb71e62,e8b0ad7a,7d2851aa,15a26dd8) +,S(4b0e5728,cef356a5,c6d08616,47c268b4,c8a12d8e,89c2da7b,78e9db87,7b606719,235ec085,a1f3651,11b5f03d,7237dcf3,d70e851a,6dab8446,10e45fa,2996e70b) +,S(54285c70,315d9a43,a040bd05,70c35713,68504efb,fd103098,79067d6e,765d4499,de233654,e7c05b5e,f144d25c,6d539157,51e83ce,7f88dedb,7fbef11f,d6acadb6) +,S(ae15f764,d20e4eba,b95c3463,402a2159,fcd21daf,fa831b3c,e47bec08,9bd43da8,474c4cb8,afeba9e9,3f1d0a2d,28911298,939328e,5e364d44,68c64cf4,fec2eb78) +,S(6de8743a,68c42b81,ad069f2b,fc1482c0,204640f7,74515924,441ebd9c,917e3974,7ed602bc,16300648,86ed0369,21936ee,aa5e9764,ffc294e0,bcded12b,bcc86f55) +,S(7e4951,dfae38e6,f9869fd9,6d058847,2a38b0f8,827052f8,46195e21,44213a47,6fa2e60,a3883383,f8efebc,f39329a3,b7aec31,2958510a,dbdd5a72,728035be) +,S(1f7eb5f4,47d53537,3d29770d,5d7ed36c,a2d2a4a5,550d8bc1,849382fe,3847df55,5a351374,da5a804e,3b995d43,49560f7b,aa417dab,936860c5,baa252cd,1753f25f) +,S(dcc1272e,b31560ec,64a4b53d,24727bde,da576493,b571b5b0,aa7bb3ad,e8b2dfb6,567e08e7,bde60e6d,a614f321,a9cdba4,1b860f41,387b3854,603a8740,f93039b2) +,S(3f4e219f,5014414a,3c757cd,28120043,3cc199b,fa843c40,b344b32b,87dc7e7d,dba2099d,839e9c1e,7d7d4c0c,9444e956,168e2bc,4df1dc52,bb5b4da6,3a8283f3) +,S(dac6f264,74fee94e,dfbe9de,cb2fb88e,272ff622,4d7f8b86,3076337d,6d37acec,1bfc6855,5af0f07a,c9329ed7,5549560e,8d3e0c67,753d2673,eb6706b5,27a0de10) +,S(82ac1fb6,5a975de1,4bbd5709,9e2574d5,ebf883c7,7f38a7c6,1408dd3d,5e49b33f,a6d9dde8,b43656b7,9ab5d880,f3af2ca8,b70da7dc,251a7299,cb236b1d,75276c56) +,S(19a59ade,a0da1340,36a533b8,ff202a58,55b9182f,b19e8b79,caea80b0,9e263706,58030bb4,b17da5b,1879a67a,12c1d929,88cee2a5,d8915528,26456762,9a99f256) +,S(27e8a699,eca192b6,7a66b1be,5b290e37,1ff8e912,5afef253,134af2c6,ae709ead,54ae6059,58d036ec,959d789a,5316c70,a09db19b,179e5d4f,effbb057,abd87eeb) +,S(25e6cdbe,5d7e37ea,fe2b51f1,95cac707,a2aaa70,57fd5e78,8fc926cf,76e65466,576b2c22,cb6ba6bd,6acf0eae,79b52ee4,1fdebde,25293347,d624973f,e9b66be1) +,S(a0114d87,cc03bfbf,97e96821,2b69c53f,12910c87,e87e7a79,109f83c1,7042dbb0,869c33a4,cec89d65,633bbe60,a3cf7b70,1e5c83eb,e7c229ea,a4c279a0,4203a9f9) +,S(e8017e4e,806557e4,61ea997,f5f46e72,9fb668d1,e8faacc3,5804c35b,6d5cbad3,eca21b4c,294ed18d,d0df0dbb,771b8bd1,659c2eae,2c843f8b,bfd3aad,f44a4070) +,S(948209cc,528dc6d6,a406c996,7d7c191,19ab5142,679ac9ba,afc5098d,4d7c83e,3cc37cf5,1aecaa1d,ef14a2bd,cb6a1084,f3e60da0,9fdc4fb0,9d9f9fa5,84f14b25) +,S(10f4d6e1,c141dc53,fecfbdb0,b39e3e8a,c7f5279b,dc231fdb,55b25551,df90fca0,4f5e59b0,9c6daad5,80adde67,1583af4d,fae40d52,6017d5b2,9e798bca,6917e735) +,S(66361888,5d081bf3,9e9fc4bf,a0922dbf,dbbe8eae,451c199f,9aa844f0,71a327e4,f31b98f6,48940706,13a086df,12416779,a5c16ad3,7cf885d,5f1fdb37,1be94cce) +,S(6afc24bb,ae6cbfca,b34fd467,f23a31a4,4a0a35f6,203dd7b,a881ee5f,f340db5,7ab76f2f,6bada7ac,1e01c930,90c741fd,90c41fa6,943aa804,ff960b17,3ab28cf8) +,S(3551d572,2eff7d0b,275e310,d1466a70,2b828d8c,fec039aa,ce629aa1,2a9c23a6,b58af71e,1f9a6cce,c48d1fd1,18902a21,7f1e7f35,3ee9d794,8133d41e,2d2d61eb) +,S(e6e8cceb,f6096fcb,8f21cd9e,d428260d,c3867e0d,9c4cacc8,b8900fff,7bd4c1aa,d1b12068,f85e64f,7c9de5ca,f1490bd8,6dabf18b,4b78b5ef,531d9bd4,f64f13a8) +,S(5cd74a22,d46e7769,15b3c84a,492fad11,8790534e,dd8d9bb1,e117a6a4,78f566cf,397b2429,f978404f,ec96a4b5,28db5a,1b0cf9ef,61f2fc7d,470f0554,eed5ee08) +,S(abeeb656,151fc7a0,fdfca1ae,fef91a7,ae156db7,c433178f,be6fd700,991e8b86,e2a10216,3a8bdd0e,8254f459,b573d182,eb55f2b4,969a3f80,267b060,9f208a8c) +,S(3f9702ac,3b96bd4,ac9412cc,8f40d5c,99f4d7b9,d211bd2b,18c6f96a,ebd2f958,e077e28d,8f171626,9488fa5b,67a54800,b0d5a519,4384ca56,f9836b87,68e9821a) +,S(3c8e54a0,d094d63d,60aecab8,675349e9,f229995,587cefde,eaa1f50,cf3032ac,e77aa94a,fd252860,3bff0189,f11d5f93,fb26fe86,dec719b2,f8bbeda1,3cf38ba8) +,S(8e88168f,41689167,ead8ca79,5ef784c9,8e3cdc41,43a0ff8f,2891d476,98387bee,fb4bf21f,343fc6eb,ca6fe337,ccb7a7a6,899bb29f,d2f60480,ffb0a187,e875b00e) +,S(d5c7df6f,31001177,f2e88aa5,43276617,7a598335,cf6ad98a,e55a6d66,1b75c1ec,2edb20b5,47b7c233,23d5c4e3,295921d9,9d98854,e780f4c1,e756021d,79f1b035) +,S(262b9c58,75087b02,490291f3,963160c,c1f5a3a0,fd6a905c,25c98bb9,f7268514,c7e4ec06,b4cc77a4,ee551a5f,6c90ea97,4a0b2193,f1b828c,305a0fc1,b22e5b81) +,S(cc94ea5b,a4fdaa06,93976b76,893dbd92,f602bcce,822ff271,7a13bc2d,6b31e7b1,c81c01ad,f2ff92f,5c2cc42,f3c30091,11e6901d,36c9af9f,9b408df5,c7460932) +,S(b21abb23,4c435197,5b73471e,3b2eebe2,f537b95d,1b19361d,31ca4e63,336b0066,db02da36,73e62e9d,e96e1bc7,b79ef4ed,49449c29,7f4f0330,227dabdd,5b4c3d9e) +,S(ed130512,5af211bb,28118dc7,fc22b8e,8bc2554a,a19a8c7,16f69f11,a03df1dc,fa146b3c,2e0eab2,bba69407,9ee3b6f4,2f64dab3,9c19a1a4,256283f5,bc0886ec) +,S(42b829a,96989e82,37e48200,20eca1d9,61e487d,a9c6f9ee,60586dad,8fcd0e83,c2e164f0,29b6cab0,14fe76ad,82ee7372,78124cf6,5f251c9c,c260e239,50ec4014) +,S(15f09133,fe57a223,e2c9ad79,dadbbc7d,ec85df2c,6af39fd4,a156eb0b,1602a13c,563206ac,b190bc2f,c7b24d2e,ff376cb8,64102efa,12f7be73,84898cc8,76a12b4f) +,S(b8446387,4262c03e,312eb0cb,e562f460,8cd4f65a,75b099d0,b45e0de7,8398f5bd,da730acf,79fa0282,a3a29b99,7a0ea45,ba0896e7,598be8fb,8298aaa6,9b94640d) +,S(6a926c00,ef4c32f2,52d9f336,29fc708b,e21f571f,1f320ae8,6e6c46b8,9511fb95,9106e0c8,2eb9fa36,4a84a2e8,8eadc9aa,9113927d,99adeb61,a2ac5527,5de9a9ba) +,S(fd6cbc21,9ec03dff,8f3d00e6,9de0c64d,30ca5a04,1556d0d5,87339b0a,925d064,742ce8ed,a4b47eeb,29883606,211c453f,fc15ae40,174e1c74,656a78ee,f3a85e8e) +,S(6fd7f1b7,61116218,68e1038f,d5f341,c43b61bc,b6ec53c2,8d84b321,ac664274,f681256b,947a9492,5b8402e4,26ef8d53,20c65a29,3a7758de,6b7e3f45,a9d635d) +,S(c28c2cff,1e418550,f73fb839,58c1ca6d,4c616c3,74a67978,d4dd71c1,99902ac5,537d774,83b1ca9,50174ee,381023de,cc210f91,3a66615c,b242829e,e3285285) +,S(89458f8b,7db2cd74,346b8b74,759088,fbf81591,5fa1e97a,3f34ff90,908cb183,9b5b21fa,378f50f,dff2e276,353179a,c0a6e43b,13373940,c2e73e20,106742bd) +,S(e66ed94e,793b894,552b3893,88a657d8,55ccbb2d,f9ae0061,2cc07244,bfd434a3,8a6a17f5,da95e907,7b03192b,eba324a3,5595b6d0,660851a4,7f9e2259,2f093275) +,S(8c7e4ce,f5dca16e,620d6690,ce3b9337,8000ca08,e73eac21,deb5deae,83359160,29a44639,f9a6b8ef,990b72c1,5ca6f539,31000a2f,394b59c9,36542992,7959c505) +,S(a0d1611a,807750a2,45c68132,2f7adab1,9b81de3,809a9a82,ac038294,b732bdb,c6e35357,246fec0b,ed0c5491,24f13f9a,a01fe39d,e7630357,110a5878,90d9bf95) +,S(c1cc130c,474f5ebf,e4b4e26e,a444d5d,7542609a,2bc65a68,9c6453f7,9dcf6ab5,deaba85c,f0f7f9fa,cac2415d,9f82c62e,9caf457e,fc9149fb,55bd8f2c,32f74ea7) +,S(d6dd2a36,763b77e6,259f1305,43c8262b,784a268e,45adcd26,efbd6d54,afeabd68,2987d048,9549cdd4,c27222a1,9562b005,56dac521,1e67d052,e76266bf,fbab179e) +,S(885cf8e4,ee0498f,29a7f3b6,a2420629,4a941f56,f3d852e1,4641a604,9415c49d,b1002bf3,e34ce44d,54a18be5,3737d98b,28ad0f7f,31d9bc37,ce31279c,fc039b2e) +,S(8f0c57d0,3d85979d,5bec7346,1f0a3b7d,540fd0c3,8d8a6775,fde2ca35,ec8a0d91,86a3f4a2,cc4f934a,8b833cfb,dbb96eaf,159e00ee,caa0871b,235e4f8f,97bf542f) +,S(53456583,d2f4d9fe,1a13883b,7775b363,3993c9ce,6bca547f,d05021a2,d36cd366,92cec0bd,cd83312c,455690fd,d715e41e,c29cc70d,f5eb2e17,7f0b2caa,f3b5214b) +,S(a5ac3a28,fad5cda9,200bef2c,454b73ee,bbc853a3,e8b2ff77,111ea25e,5f3b5359,4951843f,6e23b9ba,60f326b5,d6b13f1f,f49e8b3d,b399be4e,46cb3ab5,7ef10bec) +,S(2ec53b3e,6d91835e,d236898f,8857a64c,4d898098,9af6ba60,392b774,6eb99ad,e21f4abb,cc05952,eec3fe34,f02d64c7,e7a91658,b0b11b14,118c3489,7bb2a2ee) +,S(5863f940,a45c8f5e,a2361500,84c588b8,a7f99d26,84121d59,9073d38a,69494c38,db422c38,41a2bb32,98390c98,e9f4c23c,da27c64e,a5481870,b33a2bc,866852d4) +,S(3492772e,d177b4a2,5f9eed03,7094c52b,aa72dee7,1c5b315b,70948dcf,a1975a64,c5a26844,26418929,b5bd1488,49b3241b,d0eb5243,61106911,1fc32cdb,29087562) +,S(4405762c,ba4f63b4,2401ce63,120c3599,af37ac13,d2de044d,26d830,9e664a4b,3143da5a,8319bf4d,32941d58,e9bda807,74c58380,ad8c3a33,460bfd85,36d9baa2) +,S(4894f457,1324691,8f32111,e1bd94e8,a43f717d,74e8c465,550e864b,9ae2a16e,9c89818e,6f09fdc5,b36c65f7,12f26be6,40598712,fefda799,4b200967,7de01ea) +,S(620abc9d,4efdc1a,55edc41f,29834528,ca87b333,a8678e8c,205d6817,cb7ec3cc,f524cc99,9e911d67,dd0e8bd4,3e003ec1,64af288f,3135a602,4e93856f,8110f867) +,S(d69800fb,9fe61ca8,97f77226,d42749b,1274176e,29bb85a6,226f91e1,e8c62a7b,43baaafa,e10649d3,ff2bb0cf,10c58f8a,f01fd3f4,1a06c245,a4e9c483,8bc9e3f9) +,S(87a12e5e,d002cacf,f55901c0,d374f81c,ab9da24b,80e1fa9b,25f038c9,38344721,36586bc,17aaf4d2,5d02ae3e,e9f98235,f9d605fc,1954be4a,dbbcb917,1f736d72) +,S(a0af0d5c,bfdf4fa8,98a3ea89,867721d6,3178341b,ba30f091,946c72af,bb876624,100f795b,18dd85c0,9af012b2,5d7d5d1d,5118d02d,3837fabc,ceab0b23,99f98e43) +,S(ac94b41,7becf857,1248a94b,a853f4f9,dd47284,157e0b9b,1756c4ca,fb692086,cf94bf3d,d0c7f89f,acf8f678,5508e510,faf27a33,10915d99,80b9fcd9,62f75c92) +,S(649654d2,966fb2df,b917367,e2ea4034,fe886725,3711bc40,8520d5d,579a3481,bf8ac886,a7550c40,29279fe1,c4d330d0,89935427,d6967412,66d79ec1,f1a2780a) +,S(5f7776ad,e73826a7,fd2969a6,1511141f,cbf6fb11,23c8d7e4,3ff93835,ee1860c1,9faebe0,2140468d,4564f7c8,bfe4f097,dd0ba493,8656fb43,ea9f0f8d,22089e5b) +,S(f5dfe7be,f4c42f3c,e91fea18,10402c5a,9072b001,286a7371,35a00fd5,c71e2f17,9787d33f,821a0633,ab1982a4,f9240b53,38a5644a,4d203b1c,6b5cb212,3c837b4e) +,S(d3432817,3f33fa7,e517d6f0,408bfcb4,6a882c0a,6d78feb7,44f731e7,4e1bed23,bc1e6ff7,cbdaca91,edd419f2,e80e617c,506bf8d,8acd4548,8267938b,813a281) +,S(a4420846,95528dde,2c52d5ec,cd67266e,3024865a,c6e812e5,1ef4f780,505f9d2c,4a721caa,63d62b9a,c23ac717,7a27e27d,d54e5ff8,aa204bf7,3e6b3131,3ccc31ac) +,S(b3818c70,ea29c1bf,db63ba44,1e42c842,11f9d2e,4d6b07cc,79938d3b,b294b820,1b2c711,a98418b8,15abf79,44fa75b7,db8965c3,1779d4e6,1967f009,8c005d2a) +,S(3854b55b,def18a47,7e87f62e,d7607c6d,aa2e737d,e0e5015d,de7e90e4,570d43b0,2865de79,552c68ce,4841ad3a,69376a36,9d74d55a,98c35d25,f97656a2,fa22785b) +,S(e2e805af,78bf592,6a37fac8,7429f6ad,88c45522,e58e5c9,2bd2ddcb,e893ff33,c2206185,254ef80d,fcc7365f,1dee9a3a,cdac0ebc,d0ce6a5d,4c9a6875,f07a46f6) +,S(37510b86,df2d8e60,10d40e34,77af6c24,47f2a41a,fa35ed49,224bee62,eb0b77c1,1f30b802,6a3288d9,714b33b3,7a09cf20,cb754f09,730888d2,a09869ac,1e905ff9) +,S(14b2bcad,c5272c56,8930c574,d745fac7,d190558c,121df6e0,c2c9cc1a,f9662fcf,baaf56ed,f70fc0b6,520bea13,a8794d2,d397e935,65841028,6dafdc16,96caaf3b) +,S(2984937c,e3d6a155,7a185609,9e44bfb7,28dc6d0c,bd8c628a,23a383ca,3f38082a,637c5e4,9b0943d8,e09960fd,2375770c,5d4dc4b1,3ea460df,d5ba49ab,fd6339c0) +,S(e64f46da,d9b9e7ee,3d2878b2,f604728b,8203a591,d02e7d23,721fc436,165918c0,f7ec0e4c,9f66adf9,98b8e41a,d43fe3e4,7cb9be23,6356ef3,ef5b9a23,711e1140) +,S(3f587c9f,1b88ca37,d32af584,e510609e,ae113e54,8d07fbb9,a34f6916,908f686e,37712f53,41485518,241835aa,d31c45b6,f5370c6b,238380a4,ddbd0755,17b2b49e) +,S(8218250d,b1ee7484,b8892bdd,53be130b,4b5d3db4,7c3c9e36,5a17baac,5d8654a1,f19955f2,a7f954b9,2050c815,8e801222,8e77405f,c9f0676e,76ec2e4a,f3b93bf) +,S(5ad1a4a2,55a22c56,e8d17acf,786356f1,7ffd6453,262980f7,188879be,9e1eaac5,fec5d2b7,ac26e4f2,d4d7af01,b49295c3,3a969fd5,28e3aeb3,90e86bf9,85093dc4) +,S(1c92ee58,c5226166,c313b491,5c731d34,739068b8,f0241dde,6f0d7151,243304c6,5dff29a6,1197aab4,c1ac8a25,625c4dc1,11729680,15f03488,b8a4baaa,d541bcdc) +,S(fe622f9b,fd9c4ba8,8c80c82d,d1a07bac,c1c9da11,996240cd,50b6a41,f6f8fdc3,666e59ff,e9efb9a9,b7c36539,ac948438,f1de235b,fbed8fe7,3a084076,39f6b901) +,S(b2e8301d,ee34bbc1,d95de73f,b947bbd0,325bb3a5,555738a2,8fbe4e3,601a40d,6953963d,3496413c,53ef500,6def0fda,607d9a9a,319cb93e,22d9bfd,a0c3b807) +,S(1505e140,4644537b,56da7114,5efd34d1,566ee38f,dd4b549a,34ff312d,5cb9bb96,d6440284,c1ba972b,413f8c12,7fc40001,39954fd2,5ee4993b,4dcd5e3d,a2b843a6) +,S(7a524409,67918e47,53b451e5,243c6996,c053fce6,1f492995,8d2bb84,9fd1088d,e089d973,19788a2e,853a3067,c4a98c59,4fce75cc,a9ba908f,37780e1e,567b7284) +,S(69eff8da,8efa75c2,ab052d71,e898a975,c58a074f,c46fc6b3,2b385e41,93ff5a30,30e873ca,f0e7d1d,e58713db,cf7c5c9,6c9f068f,e0e3d1d6,c3863d44,8da1cca4) +,S(64a5649f,2da4eb15,1be3fb68,b1210cca,61b32492,60225ef5,53426992,95e6d6ec,8c53c12e,8fbd7c,811d4a85,95787105,4719c5fc,368845a1,6b8babba,1d92f56f) +,S(ca23d56f,46ce3458,d95a5b24,d998188c,3ed76a22,2034b337,933c4298,8c804fdb,efcbc7c7,d0d11fd3,ef1c0ac1,38d1a2bf,d0e94a85,a0700cb3,630dcaa,426a4c43) +,S(630b2d2e,62bf28a2,ebf80f2c,2bb10cc,82014ee0,c48e15a6,4cd691db,dfe8a55,908eba92,e889f132,4da0f927,9c1bfb74,dcf16786,c9c8a964,79757a79,d4443e9e) +,S(29b5c3d2,57674ebb,1cab5fd0,56534261,5a059eae,c8002aac,c000a857,a7b7c840,e7724381,f3f1cd4d,198a06aa,33b7fb9a,d6acdd57,45f900d7,be34fd6d,4f6dd41) +,S(f4b9c47a,2454985f,e732c151,3216f7aa,f5de769,89344c0a,4b8b46fa,c15508db,9c51095a,c45d901a,75229288,fe5d49c1,1dbab43b,9a030cc7,c6d71bf8,9d097378) +,S(af0dbf55,79f3f1f,91847143,99a09fff,75c8922b,48213c42,1cb17d11,2ab7ac71,56e7f5fe,e96e464d,50cf98b2,90a04917,430bc2c6,72a411a0,842149,8fe23d66) +,S(7ddbb2fb,f5d68e,6acf574f,1fba12e8,323e06d0,b6b80cb,1b9e9368,5543a8e9,888670aa,f057a051,1738d69d,162ac2f4,9074e5ae,d28cd6a3,a30edf9e,e874d7ed) +,S(43612257,2c25dce0,4a0273a8,a83890da,3a27848b,103d5ee9,1f0bb33f,ddf131c8,62cf1a80,7bdfeaf7,7b9d90bb,ec403b7a,b4261e04,62a16c58,5c9e1435,afb177d3) +,S(8691a20c,6df3b947,e173735b,d764ce9a,4a7773b4,4b4276a,873786a8,8e5b0932,974ca0c,6644983f,e4288afa,a80c03de,fa8d9215,c148a63f,1a1d4aef,365d9e81) +,S(7376518a,528c1190,b95cfdb,ef241485,c84f34d9,3690041a,e4d8b0db,295fe87,fcd56fa1,3d5cbebc,ea197636,ad3e7bb,f9faf472,56d44489,e7cbad3b,ca9e01e) +,S(9c5e491d,838b7471,87eeff8,f44ebd70,d6087ba7,fa2b957,8302e46a,3e5113ed,3e312d47,a32d61ee,f88dcb4d,aa38b024,7327ba59,cd377798,75bcd10c,2aa13278) +,S(884a9710,9e6e95f9,9a52d8a3,7b91480,d33a95e2,4f385ecb,d9666bc7,ddad4c63,f39408bf,4f27f2f4,ef65b195,b231edc6,c50aca83,60d23ff3,32b1c3e7,149e8d6a) +,S(f99760ec,771c8f39,d349fa7d,19b0ff65,bfd2ebbb,f2d4707,eff2d646,4beca7fd,d71a5750,a9737ff1,bdd2fbbb,9674905,5508c2eb,ad22aee3,6aff09f0,1fc9d996) +,S(f2cbe279,98214502,77f79ae5,22da1671,452c8e94,27562e3e,5d78fc17,9e758e2f,8334d592,9b50b714,a50ead97,6fcd8b12,f9806edc,5da45d8a,a226e029,282ab52d) +,S(df67bf7b,861d0636,30784bd7,f9a472df,6c2db3a4,7af8d06b,ea3665,cceb76fb,e939458e,513e55b8,7e4b90d4,3f073e47,620dbdec,d7ceb425,1353f4cf,a8d20624) +,S(e3f17365,4bb1e860,d1812852,c67c0095,50f82b34,434c5326,d5864884,bf64fcb3,9f07baf6,ae6b8c28,e8a9d807,22a97f51,bae7c98b,daa09578,5a2d1fae,3f359139) +,S(1cc073f8,ac4fe62f,e311eb31,42bd357e,45ea17,a844528c,7261bfb8,24642103,52303125,ef059a48,142036a1,ab6353cf,90a021d8,30a936ee,9cc4ffc4,91f514b3) +,S(f6b037a4,9394a077,7483c0ef,326e694c,be4b01a0,3accec75,629f7224,7fce7f0,f922659,25e4434c,4054ea7d,d4bdebc4,d3801c39,be53b037,715c6ec2,88b34db3) +,S(74966556,eb8c4cbf,cd364f06,b2bac116,5b914c76,d394dbf6,b5f2f7ca,14e54207,8ef7ffba,85b9eb27,f444de36,86ce67f7,75c8eb30,5bae0c6d,1962c839,a88202df) +,S(44d3ad0a,bd1f2ad,30957e00,594f7738,18777896,9b4237cc,d61931fb,a564ff35,af69cb36,28168fbc,f194f55e,e7691ca1,88178a44,2e6bb250,84c6ea77,a3d41748) +,S(7914f911,b6956f5,cb0fa063,bff4ee00,cb67058,3dd4eeba,daa4e445,97f816a1,a61b333a,e72fef24,a47f48df,90b5384b,b25b5f8d,5530a5e5,117a4f45,43948fc6) +,S(65a31bd4,10c97121,dcf656fb,55a71c94,ac34ba43,c3219b1c,86f19f56,bda94c38,a2e19092,35d8b549,b1926524,132a5220,e26beb5,f9d87ddf,f46aae23,dd8834c7) +,S(eb092b73,5b789bfe,9a466b70,3801b511,aaa33260,407b8750,cad24563,abaafb49,ee29705,18088ea6,132314c,999ee924,5f50346f,c7a9d114,169fc20a,2e6b6a42) +,S(38574e2e,8ff7d427,3870b6ae,d859322b,deac3824,bdc1ec6c,e34d88a,8d92196f,a0a6691b,4d770ffe,e5503d61,bba954d2,f4185860,19aa60f9,303f3e89,9fbbc7d6) +,S(5e555cf3,adf0d5fb,530f87cb,6fa753bd,e2c09d9b,d703a899,f27d2a15,a051a64e,41bba138,c76d1e98,90ce88be,1053bd3d,559e7118,4b900aff,c048a494,24e1768a) +,S(4e8518ed,92b06242,b0f28b2c,e02582db,e5f908ee,fc660c63,964f5e88,95b509c9,9e4fa860,cd07c071,fea0ccdb,f1b9284e,393d9f61,45dc4ddd,5ded2dad,b8897e5d) +,S(507d72be,dc881de7,86103317,77afe208,69619a4c,f6cd3012,e04c8cfd,2029b562,2f2ec47a,963f7c86,de8497cf,fa70846f,22dad843,29643444,706487c7,d9999da6) +,S(c87295fb,299c6f1b,410f1128,a1c88eb3,4467d0b3,df7dfcd2,18fa3819,58df06f6,2977ab13,5abd0c43,ef791c18,5cdd6b59,443ad076,5f190cd4,77620227,dc38c479) +,S(5f9fcb3e,2d7f842e,22ae0d41,48d74b9b,66b8d98f,fb66e4d0,1f279be7,931731ef,523a9ed2,a911ec36,87619cd3,f7ffde07,e11a2b19,e90771b1,8ff86170,a747193) +,S(42d833f2,b9717832,1b9174ee,75127d0f,5a850a63,52452942,56fc4257,f90f74e7,fcb299b0,ed234bb5,4f0c9ad3,e9a87bd3,f4a83bd9,916c9050,6952df68,f39dbda8) +,S(cb173f92,400cf477,47ec4ce9,f9852778,6636247d,55279b52,81388daf,99b77f68,f9d99960,1e669f8a,d8283ced,317eb2bd,5aebe201,ab97a62c,25573a0,65b28e0e) +,S(a73a52d,a2ed0dad,e9943a25,8e6a1f0b,6b2b772,b010d81f,a6eb3bb1,61877d65,71f7bd19,7e9d575e,25a4c592,92061743,2cf69ecd,f33705d0,3429966d,956a2e58) +,S(209411b0,398bdbaa,7412b2b1,49162c31,da88d9c1,5dd4db67,8ab3e19,c90a8415,1392e77d,af6bcf59,3162c8b2,2e8ff0b5,4ecf8e01,4fbdc743,dda8f061,ba8a24dd) +,S(74590b3f,a03daf8d,537d9eaf,410b6c61,780f4146,44e7360f,7d6e2710,3c8a6d9,d40fb53a,1f6768ae,b4918201,54dc85bb,62c5ee68,614f1e3,b6cbbdb8,e182d9f4) +,S(cd77abfc,78148f0e,1acc919d,e3afeee4,2cb6fae7,5f68ce7e,cd31e3a5,adb54544,a46dc809,f9b1d0ee,4ba8872f,95166de3,87b08a0,b68b3622,492841d3,f4c8ee1e) +,S(ad1d5f2f,ef4890e3,5d1916e5,2dc6bac2,612d3b0a,3511ce92,94262b7e,fe2da353,6aff87fe,3778f197,ca8b1a67,9b8f89f9,69fcaaa5,4ef0a629,c0dd311e,ae83e568) +,S(de45c27f,fdb38ff3,a91c0dda,56076875,be8a1369,23ef5a55,26af8829,c9a17705,43564551,83b6ec8c,48c1daf8,d8f0cacc,4b3bd932,5d6e5adb,89368834,2ef5ee90) +,S(deba00f,aa0d172,a6bf1c71,6d280e2c,8c8e35ba,9c15f0cb,ae574940,fb78883f,2b282f66,c9499232,dbe30521,da2298c9,7a0dfc43,562ac5af,74eaac20,1d2dd708) +,S(eb95be9c,eb4d5db2,ae9071,e5dca616,dcdffd15,762dda32,5d13b576,f6532b04,c21f9054,d504aeac,79f98cda,de167ee,60e8cd52,bd44e4e9,3d66e2be,a9867741) +,S(a2849585,a2d9d78b,9da83fa0,cdf7f4b2,62c29e29,876297fe,3ad3bcc3,691acca9,a165f5d5,9ba43cba,816ddc9c,b33c4d14,e4f768e7,96ce32ed,2f711127,7bb8c720) +,S(e5a492b8,cae88b61,c72c8772,eaf6de20,40c89597,a4c4c703,85c28e29,62bdad2d,a0dd4bd,8cc5136a,184fd7e3,aa025c2f,62f85693,163e726f,cffa37e,2be168c) +,S(875a7369,7940cc11,b00b28fd,c72b31f6,19c9018d,5c261af,f1cef7e1,be71b61f,93718642,241a4e8b,22760240,2b4f4e1,fef54882,1af31e69,cd45afb3,427fe8c0) +,S(39a301a4,69836ad3,f98d7086,24b53106,fd9d9aff,c1253059,f45617d6,ad6c0c7b,a7f00229,6ff382a6,4bcb9dd1,fd9afb5,4dfdc2f2,bac962c4,8bb76603,7224a403) +,S(8bc53451,922203aa,caae8513,4deadac8,10c585c9,f9fb44bc,57113a31,9474f090,a4bc9c8e,8ea5d122,54a6cecf,aa46b791,68cf14a2,280c86ca,177871b2,abc65b8e) +,S(796eec76,37c1fc11,3ef31366,dbefc78d,ba5735a9,28505c0c,e2a22ad8,b447b1bc,11e91c1c,f9195b5c,b8948081,7d8ca5e5,f0fa07e0,19ee5566,90da195b,c5eda060) +,S(ac52e134,1b531c25,60efb2eb,1c0c79b0,d1f3cb6f,3bcc4b16,6a7f701d,7d5a60df,4415cb74,b2ca5b76,985a1386,2278f53f,871813e2,905e51a,cad23265,64efe34f) +,S(c231c57a,ed49f271,2d571e10,fea59a11,c4d427c3,4a67b024,b4713af7,d2288d69,bb4ec242,6026ce7b,56471afb,c4ed8772,dada1335,61d07981,907d278e,70ce398c) +,S(1a1b76ef,11f3d64c,5670f06e,7354fc4f,a7c17129,75ed3094,b5a6df78,c8c03034,600c7a61,188e6ea8,76b8bd21,b121ee22,ba9d50a2,d2ce0fc3,d836829d,1f829430) +,S(82b4e49f,2d9d49c0,f409ce6,13b65a5,c031c8fa,adb3ec8b,62885760,c69bc5,67b8cfb9,56b80bee,5e5ec168,6cbad5f5,cddf38ae,3bffcafe,17d242ab,896fca10) +,S(bb3201,8ebb358d,575cf58f,c08426b2,f7116d40,8cd2d779,9acf6c4f,55de461f,8f3205b3,291c8da0,b0ebab8b,ac292913,12ad3a7a,83ac3ff1,6e6f55d0,445f22bf) +,S(fab9cc75,60a02c8a,e916bfe9,b61cce9e,32d37203,8b42b58,150db6a7,cdd40a22,132d8021,8e3b6ced,e6b3060,5812823b,80c7f0ba,f369caab,8b3b7cb3,bbb477d1) +,S(9f96535a,bbd2b21a,bf41bd19,549528fe,1353724e,cfa3870b,3df3256a,661c7e47,b8acdf49,a9783748,40232e1c,9a0f6854,1547b7d6,d1d60bb5,c321a1b6,54fee431) +,S(60d4754a,2faf463d,f7b0cc2b,ff4e6495,ea9fa9a2,e2f1f4e9,d773301b,3d406daa,43d16225,6bddfb93,3588da3e,511ec648,5599ef3f,7db3a1c8,899c21ea,2fc91936) +,S(3850610e,10a40ef1,5aaf4d4d,b11ce214,7c82a449,ea965cb2,5cd9ad46,45ba44d8,c10cdca4,aa919f20,4ab148c7,2eb4e6f3,7939c70e,e134433f,5c70e45c,fc30be3f) +,S(68089586,3a26181,a6966055,1ad8d431,9d325533,70839d17,fbfed5c7,fb84fab4,a0cee277,97d2ff7f,fb7a6805,604eec37,4ef4182f,a163c53,15924f,287bd447) +,S(aee5d57d,17a9167e,9d3ff19e,8eebeb09,7675b709,e3a89ec7,38280b9f,ab9404da,154f14e4,f991644d,aad6d858,940a6126,5a8f1c1e,ef6071db,5e138081,5e2d34c9) +,S(8f3362fa,659c58a8,2376ab88,c921fe2f,2c8a5de,f36c057b,3154800f,bd493950,5f88cf3c,3fc1ccc2,2105f3c7,8ba7b8c5,525a9fa7,7cf76976,8906d0e8,caa64408) +,S(2bfce32a,9d69a14d,324d8f94,15b42f87,25f5befd,ba3cc6ac,2a5c7778,f23187a3,f7e88e0,51ea8e3b,788e18e2,95355b2a,75fc3c3c,e62f7797,d3b02681,d6a3b63c) +,S(62984e62,5d026f0a,c6c82fb0,46dbc152,a05c9a22,3f55663d,5cdd87d1,e094022,1dadce42,d6b68fcb,19439f33,2d2db167,f33861de,28cd303d,c94e3a8b,7b26964e) +,S(15502824,b02a10a1,d7b13137,4175bcb5,6b70f796,fd3d0713,42bdee98,99d8a057,b391d51b,b2b89dae,5b687e16,e2ce1351,2296130b,e86a7d21,c1d3c6b7,b20eca57) +,S(1bd98bca,c0ed80d4,f23422d,c32c5922,1164ce33,55526ea1,61e1d9fe,518c0e11,6b0afff3,b0fa5029,b4e9731a,fe772fca,c0e30c84,e6c652e0,f22dfd41,a9cf0ef1) +,S(4dc9e532,d5543e88,a59872fa,24b99968,e649977f,9ea08bdc,303ca4e,d574bf40,7c05536,d9181687,133dec90,43cae3af,42dbe034,af05a746,b6de1ef8,20276947) +,S(3e92be78,d7c7db61,1049827,42b0d213,672cc543,c27628cb,f5985c19,5685f3a0,171c3afe,c69648e,7bb7912f,fdfecc4a,78cfd246,a4fe1263,e5eeedd5,330f84e4) +,S(57b6c4f4,75bb9ce2,2086a5a,dfd5473b,73b0f6d6,278afc7a,16854e6d,32b2842b,4fb4aff6,738f05ce,31ec7934,3638a717,3806d347,c11afd82,e39d492f,b961ebb) +,S(571ac8b,835c5f4,a7457344,e8572910,309f0d3a,26b849a1,b3bca2a5,28771b59,317ae805,3aa2855d,aaec95e1,72f4005a,6ae09ce7,187590b6,41fc13c4,9bb4cf9f) +,S(534c2141,e38a7880,bf146951,7d4ceaf2,a25bf5d6,a538eb1d,4161461a,ae54c4be,59dc6548,1b056dc8,c3e98364,ce6b76f5,fbc9c501,6ff24e0c,1c7bfffd,306b03e2) +,S(7a761f86,3a224193,157d3d1f,8fff8a05,e5c13366,a7ef7604,2cd3a1ff,f9f936f1,20e86bd4,5e93b784,f433d6a5,8056c6a8,e8d1fdd9,e924fd37,bd5b16fe,fa0ece9) +,S(c1497e7a,b9373d32,4bfe813c,32aa9dae,f1351351,c86ed382,fd3d4c5,6a54f62c,9401bb9,1621a327,2c233004,d6a8093d,f812ee66,604eaa86,32085b3e,482eccf8) +,S(2dd83787,e31e7237,f49a570d,adc675bb,147b91e1,3910f22c,e41bd16f,edf3c0bc,10148349,6883687b,7ee844f6,d60ee90f,1aeb7c0e,c9f83293,be96eb2f,5cd6d46d) +,S(938f1399,18a0fe3,55ddc7ec,d6dacd34,1d9c996f,9ab4f9d6,90b435e1,fbc0a74c,30c71b30,e7a3c244,b8a576be,9e527e6e,60d1834d,17908e6f,a0771daa,92517448) +,S(e71217df,430dc65a,d188f6,861b00ac,c3214125,447d8e26,7dc5473f,9471284,8f27019f,114e542e,96eb5121,b7c3e094,f18f6287,f2cefd9e,6a5290e8,5e1dbac0) +,S(ca2ba87e,4c040efd,c06ca7fa,50cbe414,b66bb2e3,ded2bfdf,7744f81a,91b102fc,24848b82,4019bae7,4cd7604d,101c4819,6e808ecc,79db885d,bed68354,ba3f138) +,S(c267ce5b,633c7f12,1be2b297,45b4dab9,ff488b02,c8f89ba8,706948c7,77167ad7,16184a77,954c3b5,f9e330f8,e8b308de,1489ebe4,bb9ffe59,f3f545da,e7748385) +,S(1eb9af42,96d58c44,bd6fe2ff,db05e0ba,1b5f581a,af842883,5a47a050,468f8b33,f88a1128,95e53e05,4e514117,5a2c54f6,a235cb08,3494a7a,991fba4a,fd0bf1b2) +,S(ba342b95,76bea3ec,15aafca6,2f4f505f,c35bc2ca,64e2f4be,22323b77,1ee39062,91be5746,1fb662f6,cc28e73d,f0dd61e5,20cd3ceb,2d6fb0b3,39a76e5a,39114afb) +,S(f3a8c7f2,86117118,a4714895,eda7f401,dce4be87,dab4d4fe,b55068b4,c948b350,1dd2f669,31f0ec62,74e8bd53,97cb6b50,d97f9238,2603c931,8ff1c6b,18893bf0) +,S(3cc304a4,3aa02bc5,25437a89,977b8ee0,9f5f997c,56c4d317,f531d22e,4a60f55b,9ce121dc,cce749b4,78823adc,c9a613b8,aaf78f5d,c2eac8b5,d5ee6aed,592c7bae) +,S(e5be6c29,b9f12f42,1f499fb1,13e54bf4,4a577fa6,d8d0dcd9,6b509f65,1b4f3587,7755eecc,721bdd9c,c6e8c96a,d398cff3,c03e77c7,9e34dfac,1f51873b,8771d40) +,S(f933bc46,f296b780,4284de6d,5bbeed68,bae90bdc,cd731cb,b9519c05,278c7fda,b6ec0484,faa4c53a,630a8b81,e1d567dd,543a4e55,4e89ba69,d72646c5,7ab3740) +,S(e1d21ebc,297edcc2,b595976b,2f65b2a7,a6797cfa,3e5abd27,34e2a962,dd2f507e,aa31ee8f,4c80a0fb,9e52f32,c7e4a69d,fbe8d297,8dba479e,b0c9f4d0,350012fc) +,S(c3cf0aa1,8e45aa16,343c52ac,41b12278,f9899b46,e17ef9d,d7b67f75,84a1eb72,174cf510,70418a6e,f83b3db4,97102ca9,5bd99985,f2554e5f,c32cdefb,ba47e411) +,S(e6a90aff,6e1f0311,34f93967,538040e4,92120644,8e8e2106,dbba6f5c,701700f8,93895ef2,1d3513e1,19228b95,86289c26,f3efc024,1ac2c963,b394cb87,265638c8) +,S(e2b695fc,8f1856c6,131761e0,9f75a558,94a4a7a9,2837dd29,f8e8a474,7a9b9a91,b580a2e4,240724d,5c5381df,27a17d72,4d0e638d,958c0a27,fcbba34d,da5361d5) +,S(c0660a14,6db599e2,15f813a9,f267d6db,4542a696,9b08334c,6bc80558,ae518063,6a901346,6bee774a,54ec2f97,47d7a8d1,e157a13,fcde8cfc,57e48d84,374f6ee6) +,S(5c41cced,2b091fa7,df1f8e30,3d78b117,842511eb,41717b59,f776e05e,39daacb5,dc4964e4,d91fc985,af5c0f87,f0026a6e,290bb1c0,b181fe2e,195f7001,52509f40) +,S(6abe8574,49cbaffd,d0e5fdf6,450484b5,f8636170,5c8a0a59,a3612dc0,8d0d52a1,c669b059,3a5fadf6,86b9583e,7fecc9f2,c5eae967,9eb5be36,a2018337,64703bdb) +,S(560dc0ec,2d407e81,4b5034cb,8d26c8bc,7c86487c,f74e2fb9,a076b521,f68e22de,faa241bb,ee929015,b4183152,5aff5062,3a270bfd,6026d94e,c3106e3a,e66783da) +,S(f3ef40ed,8d82c02,a141b953,e8593f06,b74b244a,b85edb18,eda3e693,3c8f90a3,aeaa6d25,6db6b12c,d9a6ab5b,d6d0d854,62c0d298,5a772648,db46b614,3050d4a7) +,S(413e0fff,df030385,248b1fe2,1bebedfa,77c1cb86,d665790b,21914da4,58a4479d,6fa9db70,80ab1736,ee7d54dc,e5d1b545,dd17e3f4,45b39038,595fe180,2b34b443) +,S(ed3c5ee2,cf1cc502,37e5c654,d903083c,6fce29e,cda0f427,5a6e1ac,940b8183,fd265e79,3474e60,109cac37,a867bb81,d8ba8b8f,94b13f08,c409ad5,362492c2) +,S(b98e14a2,3f5e5d6a,a99ef39f,18e234d4,42102e72,2e330d2e,e654b328,e2f3bf49,67a60b41,8e820ef9,72ffa57b,1e383b1,35585920,20434df0,e443c318,89734499) +,S(31bb6293,28793b42,dbafdc9e,6a418c51,f0a0cf0b,6da96879,11a6f046,c146e475,1bdb131c,b14a3d85,a532f889,89112231,341a546e,c88e8a25,8bfa341a,7826512) +,S(79b2d26f,f257ac80,ca67a639,9be17ff1,8ea0c10d,739b106a,a9310754,6ba0b252,e09448ea,b102b1cd,654b6e1e,7e4754e1,c63d11c2,46b0ec5d,31df6175,6b99e850) +,S(ab8cbf8b,c3a740d3,c1bfc2e6,efbd7ac,f444795,cf2e311d,edfd5c2d,124d55da,70599847,895f335,a8bd33f1,811201b9,a860555e,8cde2a27,4c348b4c,6ab449a5) +,S(f6b7c2ba,c5468fb1,cfa0785b,f67972b5,36367ef4,d3dc9ef9,25e88085,524e6021,663be56d,c325b2e2,3753bf15,1f6b2ea0,2d6a62b3,a3d5f565,2734401c,9c661a3b) +,S(f5d2e04d,229d784,d7af5af3,ea65a35d,637b404b,c431ca72,1bec7fa4,dee33377,16c90231,e570a434,700fd8e7,cae5f8d,fbfda2e0,e234ef23,a2e82452,a0a953e9) +,S(4df218c9,4277fac3,3ca43921,e29fba57,6f183e74,fa2ea781,88b8245d,eddab853,7828e929,6c589e6b,1d80b036,2c9bb0c9,2c2a79aa,378c597e,8a64b985,d6e4d108) +,S(60e1cbc2,78d4a0bc,b7973b32,964da674,9e2b3448,24075a0d,1db93e51,ee3414c1,cec0aaa2,3db6c3e,6d6c3189,c2dca9de,8ce91791,a721ecbc,1f09c7ad,468ee8c5) +,S(1e7a9c4d,a6cf3251,559d58eb,bafd1a7f,ee686c72,8b1ad271,d9da3b15,6a9f3737,794e3bbb,cdc0df3e,b9669a10,8a32d7b7,f3fb843,388cc55e,aa893f64,ce1b960e) +,S(e8984316,5ee703c2,a413c7,2a5c8ea0,605c0b4b,58cb844c,85df83c3,b4f361b0,69fd6f89,5cac1716,f0bacdd,5a880f12,f964c2cf,1cd402ee,27ccdbcb,5188b64d) +,S(2b95eaae,6078c535,32a23225,eb9821e,c7bf864b,75187df3,2736459,f0797e4e,aa6e1922,b5102e69,77fc23b5,ac2de98c,edcbcc37,54c928b1,7c7d124d,980666fa) +,S(403c1933,59ac9027,7aed0f41,f9ebc507,8ae553a6,ec3b8a4e,4f66a841,19d221a0,edab5156,8667e7b2,c7793e17,839e46e7,85a6c7a0,8af7295,8e25b411,13829ead) +,S(fb182399,c535de2d,556ecded,54e42f29,8c0054a6,1dea2477,9df1c7c3,bb53e1b5,7bed179b,73268027,4fa6b227,d13763d8,4fa62dec,2e351ac2,d3aa59d8,8961123e) +,S(9375a9d3,ecfff9b4,b672d90,45aa4872,f61c3b8e,4cf86a38,7daf74cd,affaa521,41c7bd13,f4e491db,77a42bb8,d65ba77d,f03acc6c,cd789759,37486d08,c3f691d4) +,S(abb9554e,1b68c554,81d8bb12,5b426a4c,433cb110,79254f8a,ddebabd2,9f5be0c7,946d680c,1bee958d,32089353,41ceb7ee,5b4a8168,a6368a92,e1ab1050,5d0e76d4) +,S(56e8aa51,37b38531,1e5e1097,4df857ea,b4f7e53d,11102021,6463c212,ebcb873d,b51e1981,7eee5672,afe7f688,92ada73,abe703ac,4e19770c,97dac300,8d3b1632) +,S(ac487fb0,4b00962b,2b098cfc,4f22eb28,e5007944,d32a136e,5988dd47,d9828f5,bd305529,5f4200e4,c5e6238d,76665bc7,67ad8402,dad13d8,6c6fb316,a214a5c) +,S(1dd7562a,ce273114,660ccde4,5f41d690,11621bce,56cc49c7,2016f19f,d94e9e9f,a8e8861b,ef664d9a,c19391b6,5bb97715,ef677199,a373f255,876aa9ad,d8a93043) +,S(c198019,cda66df3,2bd528db,e3869d6,1d1d7cae,57ced846,eebcf1e2,bcceb8c3,b0a9c52,ae2b2625,7699d3b1,861474,4d66f09f,8b795d81,acd3e5de,902b247a) +,S(950f54ab,3cb421f6,95404b53,9b1f4936,6b43e61c,7bf9879d,168027bd,f58dc386,e14586c,7f005f5f,21e122bb,2a35194,d5d2fcfa,4898c279,cc296b24,9b48b2a0) +,S(5b20af8a,31b69820,a56d0df0,c7374c8a,37805449,81e0c017,83b4ff49,2bd40ed9,7e49b8a1,c5bbcb32,55991da7,99613598,cfab9d8a,82f731d0,dc2f52a1,6ec39c55) +,S(eb8a10cf,3777670f,437f55c0,2ddd8681,63da41ff,5b534c63,ffb23ac9,ecaed755,99c18d8d,df2ba9a0,d46ea92d,8b983f50,c16f14b9,86b955e,a577f332,10533df2) +,S(12977f3f,d75a9c72,81358c91,73664b40,8d8ccc98,45153ede,c62b189d,8da2b176,f24f505a,75761c5d,939ad836,17f0c6,dfd8a2f3,fea04721,9078e2b2,1aa317df) +,S(7a591539,ff4fc3ce,2e2936d3,50d753fb,131ba419,8d034c65,e76d0744,c159096f,c95d8b25,52b3920a,6341ef43,5e3e797a,446565e0,652a562,7e0674c7,ca243425) +,S(993061ac,819fde52,ae500ed7,3277ecb,fd08930f,8adff61d,f5f9c3c6,cca49640,d54444ce,748f6058,10051838,52f0073a,8a5d1477,f14111d8,b623a316,a67ad06a) +,S(cf807c40,c5664fbd,910a31bd,ed3cb7e5,2e54d1ff,ffcb4b43,7a579931,6f803051,a5d21e6,6fa9b5a8,2882b77b,ca66b6e4,163d579a,d245d089,602274f4,55ca9881) +,S(9c0119ba,461d003e,c6fb7a01,2bb32b89,ec819d97,8fd4cfec,ca1c3b2f,1f14f0bd,b41c5fa,ce1e9a54,f1605e84,61b5e6ce,c11590c0,15838059,2c511360,f4b537c4) +,S(56ea3259,5d97b7f,d7f9fe51,b525d73d,3d77d483,f8bf8460,8d874d25,aed3da3c,f764a40,2cc9278a,f1ae6369,e1723bf5,f0a15a47,992f8fe0,ae33752e,473c3058) +,S(2851e3cc,2fa6752b,e0a65326,46aa8445,71736e1,d22a01fa,ab3becd6,50460acd,ad778ace,631584df,da4730a4,20242779,81f9f829,cb18b20f,8ce727b,d62d64b7) +,S(1674559a,528fe0ad,5aef46f4,eeb4e0ba,34b8c2e8,c23d3409,5ec1e164,ef351979,afaef98e,ee2ada75,7be9675f,fee76686,d2350972,a9d1b80d,fbbc0719,efc38b21) +,S(ede70ea,37946f71,848d72fc,7a98102b,f9c167f3,219671ab,1843b5c6,8ba6d7c0,920d6108,6929e5b8,30c4fa,eb155b4c,9d324001,59d748c9,d7e74980,d54be37b) +,S(fd3b1f22,c5037c8e,93f4f9ac,27ea723b,3d3e861e,694ef349,dfe51f83,50ac9fa5,cc02effd,6df18244,fcbd177,a624ff17,b0da8fec,fd60624a,3d066be0,9c466cdd) +,S(72f037df,352a4619,729bc550,e23ad7bb,6f2d7977,7d39ae36,bbc1d45d,d6e864c2,c4bfcde1,2a5cbba3,7e047070,5937c2c9,da702040,bf49cb5,c762d60c,e8fca76b) +,S(f17a9b25,601ec8ef,e320558f,ca832789,d0d8d558,76ff7c53,6af0f84b,ca799a61,c90583c6,2a863567,b0d8c41,e47c3d8e,7e196a1,9269a409,31a1eab8,f1402837) +,S(ea9fdf49,9e201fbb,b0a26a71,1b9be2e,dd17b2d2,b96390c,4aa2dd00,83bf5c86,64322654,c8bb2a83,ab0cb743,eb907234,d8503fe7,381e17be,c17bad5c,d33b4df1) +,S(8d5d6f0a,24aa6e3e,7dff42b9,ab8b22aa,656788b1,1e18ca35,b4ca6f19,1d50de6f,d509a2b5,e9800d5e,a7d1d047,e945e693,2e5c1923,59bb0210,1b2e8956,33e0257e) +,S(25ebcc4e,84a1d22c,f0a8c980,8252d96,7dfd528a,808ea293,ffcae94,50e1fb81,3127af8e,4012c2b5,c92e428,2e455de1,681eb1b2,6e660fcb,4ee8fef,b64c6101) +,S(c55c17a1,dcd8fa41,8a3edb5e,c2da8678,4fed0840,522b24ed,4bcb85c8,cc45c20,7d583091,25261489,44b56fed,17b07906,9d156fa2,e9bdc462,eeddeebe,68f4f463) +,S(f4297f59,21a867ba,1e58b9e1,def633f1,18e058d5,a7889721,f0e4814b,7e63ecce,a39f359e,35a123eb,5fb66d81,f117858f,b0557859,aa2c388,a8298d11,43f137a9) +,S(626b0a,cbcf0e7,daf7d218,74f72be4,8d824883,4428bfee,f82ea516,c2d1b98d,74ae6867,1c27a642,53a36590,5247cbeb,77173b07,2e429de2,3ce09730,8d54ddc4) +,S(8ed35ae3,c02c5db2,acb516f3,2d3b6823,61964f2e,701889ab,26dc9512,ed40172c,aef4c71c,e241be56,63a091d9,e230463d,237e0717,78b7b6ba,a63688c7,6c694334) +,S(5b082ab8,963510de,46c1cc49,4ac6d3c6,dfa25f33,8627a00b,6b98121c,73899ed,cd8b2b84,185718a1,c4686ff0,7cad18ec,fe3d4532,9537910d,31458086,c280bb32) +,S(deaf505d,b08a282,d5274de6,43c5719d,f51827e6,2ed035f1,74279276,7ddc1158,c1067344,5e4c0d47,ad1ca85d,713a5916,1aef6960,9294d738,103b945a,e99ed1c4) +,S(eb62dcb4,d820019c,e865129a,28b98b5,be6c6e16,a80f7c76,db3a15ee,31ba7aea,e78eec22,be4a175d,68b2257f,c5adbe46,fbe31c3d,5eed4736,2304d80,ae4577a7) +,S(6c58cb64,7ef638c2,337cfedc,a9345837,597ac142,577b2230,7d231a3e,5a9173cf,563008a5,7b823427,60bbc400,5f604024,92f0bcf0,2ab2430a,5d7accc5,b62cbcd0) +,S(106d8978,775a41b1,12f07815,7c3bc5db,bb5980d9,c745806a,b5ca5ede,8b468d51,bf960349,6f7d7906,141bc4fd,b1766102,e8dfc49f,decb469f,75dbc54f,21338dab) +,S(cd6124f4,21796b6f,44c34982,8b536ef7,44bf30ec,6ca08142,e959a35e,c0385224,97ccdb9f,2896e815,19bbe9e8,ae491e61,e83417c6,6db8b6a9,bede3aca,f6608ea1) +,S(2918b2d9,b0bd83d0,b8d02815,59219c6,bd708e2f,2139ad0,1815b1ff,ae60e03c,f322596e,c56984f2,e7b2ee90,8a9bb56a,d213f84f,3088aefa,67e372f2,76e2a233) +,S(6d3fe999,acc04d13,2462f14d,680a90c9,89b747f2,3601d779,507c36ce,8c2acc7d,a6c7413c,36b6399e,58a443b4,e4137ea5,551a9fb2,c5397457,9d55b48a,5df0e30b) +,S(bd74ac79,8b320aaa,e3e51123,9354d4e9,280c99c2,809e88be,13980305,62d55d52,73477881,9b9067a0,78b40108,38ae59f4,3f6ef064,ba35209c,46a9f0dc,aaf84597) +,S(303f6cbe,866b4574,9d282217,1f571fb7,8c54dbfe,901f2f43,681ebb0c,76e5700d,b13dea58,d3dfe08,7fd043f5,8e63e565,85230d6c,273d9e3b,22145e39,afd6ea4a) +,S(3bbb0824,16a2e3bd,e328f013,154f18c1,4e840030,707057cc,f4fa0fae,ff56181a,18b214c7,823b0cb1,76375146,7a49bb8c,ddc0047f,782e3802,be12a119,ecf0f480) +,S(ef42fcbc,999a3f80,b4e7319b,1fafc2c6,49f51845,2e423c55,f57e5e1e,f8338adf,786ffec5,60464882,48641155,38aac187,ced4678a,cee2b9ea,eab6ae61,ab2061e2) +,S(afb21e4e,c095bf31,34276f4e,f1a4883a,6038c20b,a7a87ba6,6288bb1a,3bc6f77d,cda832eb,73dc0e9,fb77315f,6cc7a313,2212c7b4,1075a290,d5917033,62363bad) +,S(329c98f5,a40b81bd,7d121b90,78b50bdf,bc16c9bc,47744368,34a5208f,20d39d63,dc14f7d8,4bd2a1e7,22fdab98,1044d6e5,98515df1,7da5536c,7a95866d,8231a) +,S(6929a4df,e15e7ac8,e8a9c5a9,3544af51,aa621dc7,ca04038a,9c9cf603,8e081754,e1333f46,e4d1f151,f2b8c341,d2ff90cf,d36cf73c,6f441b4c,5c0ae272,6a25fbf3) +,S(f40fbdb4,27d2d68e,854cbae0,24ea5980,5948ca40,e3fdfcc3,3efea0a4,57e2bc24,33493d84,41c8945a,9e291b58,5e12789,34990a7f,5fec49db,ea1ff605,4bf8802f) +,S(220417f3,d9fb32c0,1439e473,d638856,9b169c38,1057b780,c9de7d12,e30dd796,4cd93672,5abc4e39,89e64ed1,af9b3d4b,4732ac76,a6c34d6b,23274573,8d765a1a) +,S(dcbe3dcf,2c0120d9,4d6336ae,6158bdf2,859cdb03,8c76ea3c,cad4ed11,13ed216,670823d9,73c74725,ce929318,c2ea650d,5feb7c33,c7831a26,821f2614,7db7d8ee) +,S(34de2319,c535a31a,87fd9b70,33c363e2,8ff754a7,9e0669a6,37230443,228ab3b8,31c65b12,cf6f4a9d,662238b0,c8ab52af,ceb96acc,35b90b2b,81667b8b,dfd9895) +,S(f0fb2bde,a5626729,720ff432,542c5e41,abf0fbc4,772aca7a,75b882ab,2b364acd,114edca0,74520c9e,2f5b8059,59c5273f,25d2e621,d2f55709,b42d187c,932b6bb8) +,S(90477ee6,a00742ef,78662c11,f3725077,dbda7b66,7ba55b55,f9bfea1a,4c5f88f4,467196ec,638d137,33971505,f291dc0b,b9d0f3f8,f284e3ab,9035273e,d9c7279) +,S(ecdef6b7,455a41ff,96cf943d,e489858c,b7abc526,e41d463e,b24a56f9,dd6eeada,1116e7da,9fe72782,e8c656b,9f677c5b,dfb3e46c,98957c30,49efd7b6,dd5d3258) +,S(58d30bd1,d8dbf5d9,885b6e7e,4f28ceb8,381415eb,3851a031,ef04b073,65e16598,9cb96ab0,546246fb,f5cc0878,7b99db0b,26c9bdac,184a0eba,728fbd26,bc880480) +,S(a7587d1b,771b3421,f56e342a,cca98e7d,82c7dc60,765a481,53379da6,fd341c10,9499ba9d,8351d194,213ba35,43d4b563,aa28bba0,9a6d8811,9b55f389,90742929) +,S(8aa99d89,9db3c7e1,c28bfc5e,18abdfbf,d9fff46c,560e4fc0,cff65ce,e18ae6b0,aacbc2e2,bcc4ae58,1e354d29,617afee6,20ced0ff,859c62b6,669cf2e0,565a9bef) +,S(45d81a7a,b4158aa4,2e45fe7f,3966d278,75f8647b,defa0c8d,a761ebef,894ef249,93a76905,d0e785f2,db52e09f,573a461f,183f672f,9f10005a,eeed6e0c,d40d31bb) +,S(de19bc8,6fddeed9,909eff4,80b0760b,66a1a245,82e33be4,55b8061b,225942f9,6eb2c1f6,f604056a,15c4e91f,789e35b6,1a787abe,aded0f30,abd2525f,19486d00) +,S(653f0e92,977b7830,fa546dec,44f05549,80f5a9f6,61f2cecb,7e360efc,41d16380,58ba9f7a,eb7aed3,40b54d7a,6f9ad0aa,ab5eaa2a,7715d8ec,48d52ce3,c3c57128) +,S(c05441fe,2ddce6b6,64270b69,83d44d5c,251efcb8,2bce4665,9388eb3d,537acce,cc82b7bd,3a049b06,98feacc8,11a1c9fa,e95181d2,50c0c62a,55a6d662,c9587d65) +,S(7a569bc6,a089fbd,294dd5d0,b10f3a7a,31b6bf39,42ee97d0,49c9259f,7adf0a7c,2399d17a,f6207b8f,20286fc4,78896af4,5e596b09,7c97f662,9bff0c03,14db53e5) +,S(1c4c7a37,4e14ce88,fd08a1b3,10025711,7d96878a,e173d29e,1ac53a57,1d6ae794,919f9b82,e827cc78,7352f0ab,99770e97,bfe1b600,40cf1034,b7c5178b,3d1104fe) +,S(fd4ef218,a09baf70,57b53f65,2ca1e2e5,8386e867,521dc998,1bd4ffdc,619c31c1,b1d2e716,64fec6d9,3cc8bf17,70ab5f10,a49a0497,ac1586b7,b8299f7a,e92354ce) +,S(f012612c,1f933373,ac30413c,1b2cfb9b,6582957e,b74e4de5,29c0267a,e7552a41,a38b2418,e7ace7bf,3a15035b,a68f82b5,aae49192,5783066e,f0f0263d,6dbc86fa) +,S(8e0d504b,c9598eac,c4bd2726,8b3ad24c,a22b7534,32eb5a31,d7e54948,d57f6f4b,50f59455,ba1ea3a,5a0cc105,a1c40c4b,72637a31,44bf9438,a1e3b52e,7b30911c) +,S(8635604b,89ec22bb,b3b4e266,3e76cb3a,976cc78e,c7db31fa,fc16a7ab,411ed197,8a11d457,6868d117,4f41c40d,4c82d27e,3960d57d,4b1309a4,531c2617,b1d90227) +,S(aba7addf,c234513b,3e861382,654959c9,984628df,72b2a896,6459b3c4,86bdbd2b,ddec8263,bfdb4c38,c9e7fd,e4693b0d,962c6e5f,a4f9eb9b,9561e81a,f04a3a3c) +,S(12aa3b40,44f699c4,8ff6c598,8a7ce56,84f3af85,8cf2ebd3,4d59ca7f,f7501895,76397e3f,3c42935b,6a42222a,525c2166,7662ea00,25decbf7,8a856391,a03956db) +,S(e01136bd,da38f328,af447a50,43a48606,a1ab5a86,b3bca98,b13a53aa,c7061098,76f3fc47,c1aedcc,bf26ec5c,4f6ad56c,fa163212,65844d01,8d2f2b94,184b64df) +,S(639cb266,f0672340,d0a789a9,41eec287,b60c380e,f2f62f96,41b67137,4b286aa6,d381e7bd,5dffffd9,50645e56,63c36d91,83210038,d70df2ca,4bbb837,e8eff508) +,S(eb12f18c,89a6d2e6,5e07d20f,f7acf3c4,b903ce68,5237aca4,5692c0e0,f6a4714e,d26860ab,e6f97745,dfb01cf,f6225c36,bf62e5dd,24088d54,a6d44384,e9eed86a) +,S(8fd06b6d,96f37c6f,8e69187c,c5ace64a,6e36b45e,37de82b4,872731cc,8781e941,e7dc3254,3b40599e,852d4e9b,e35a5438,ff68b063,3b81c8ff,c2f3298e,931e9e98) +,S(d248d914,4ca3f10b,3fb66763,713492ac,93b42781,9119683f,bf0e0f08,1bb6b241,e7a2ca15,f1867e9a,d19ffdc3,f1a20d0f,2469fa6a,e04f94be,a289d019,c405318c) +,S(ba2150dc,15884df0,34a64e20,89023947,687d1322,475dd073,b163a4bf,4eaf0740,af92a566,a320a0a4,34095dc6,f02f765f,4ebdf04e,d81e2c04,a86e6e2e,923f8c94) +,S(fb12f487,225a6843,31e39309,3133f377,a6f841a7,f6f90ccb,18ce3d39,48b56616,e3358a9,406905b7,d6bc0a33,6a89a5ba,e62136a5,4135c3db,bb32f115,4cf92b9b) +,S(bdeb3e38,7c36bb9f,c45a1d62,f7128217,20e6d0a6,55a285dc,da87af3f,f59e0644,b23fb389,3cdb280a,43275691,3c1de5fa,6da12909,c0ebece7,12c9da49,69a3cb29) +,S(32f3ecc5,925ccc13,f753ddc7,d5c0c576,e80402ab,ffc6dc77,6e8bf74d,15735007,f950add3,926bebef,9d8e3a5e,4d0ebbef,24b54dfa,ae7c12d1,32b6e973,dc67c050) +,S(94a725ed,e57e5162,817d95b0,54e2732a,3afe3a6,52ae3e46,ca9de38f,6dd9f0fd,805f6634,f8ba79b8,ecd5f46f,74b741a4,de5f9678,d29b8cba,eec73498,27671f67) +,S(22197e54,d35357fc,ad20f6cc,986216e7,f24e6dc,cfd9bb89,3e5c1ee6,9a99b3a4,b3e7edac,abb1d1c3,d375f361,1f04a927,9d2995c9,3e18e7fc,4b5dca90,a2a3fe17) +,S(a51664bc,5a1edd2a,ee8ea644,7beef61b,419e20ad,ac955847,5e1d666b,1b4dd52d,b8a95fad,e3aeac7,bcd8670c,78dd1b2b,5dcad225,277ca5bd,f24f131d,94405c39) +,S(896a11cf,f9db64a1,aef51088,baec42d0,16dd5a99,98262f71,a005cdc8,ae8cab78,7a7263ea,f64962db,bd09a278,a3958708,e61c4858,1a759726,c225471b,20899077) +,S(fff75552,46da269a,2124d03c,677f59a2,18b995aa,e69c85d4,3b29f81e,5201a757,dbbf1558,6670c191,9da69467,6e8906f3,80eb3f61,34c656b2,a4ccfc71,4b3223f5) +,S(89da8ea8,56f946d6,6e9b07f3,db5b2ca7,49a07e5f,78b59c1b,e52e46b1,3793e198,25889e02,d2013d86,6653cad2,7b3504d1,4e547343,fec74a37,a3ee71a9,646a36b3) +,S(d260dbae,6ac3e8a1,442ca7b9,8f7118c5,7d6cef72,783c0b3b,a4ad7e7c,3a8836fc,e00ee7fc,95131cd3,3a446bf4,c21b85cc,45a8e61d,2d9d6cf0,287996e2,77b7cb6b) +,S(bacf90ec,75ff002b,c1a259f0,3c9debe5,9f5f9dd5,cc0cbff9,e8fd62c,4552a619,82dedfc1,42202786,a7a12a29,22937c0c,23bddd23,4418979e,78723ff2,6a9e5e88) +,S(1ec23fa,995a22ef,53a91dec,a5b2faa9,514b5ef8,faf125ad,da61f84c,5b13a397,1568ab1c,cf75692c,b7d41c53,2dd4427b,ed7043e6,cdfe01a6,2f9bcb47,cb97435d) +,S(48225de5,eb07155b,dd86e759,9e172a3b,b96f69bc,ddcdb051,af2dc769,f4450b1b,856ce939,b81d976c,6a6c249e,c0d087cb,36e28082,ba050de5,4948d92c,6693f4aa) +,S(e9ac9963,16c1ff8e,a7d2bbf4,148c8b3b,a869d4e1,290168f,b3831d6b,3bbd164f,2b1ac664,6bc87e3a,e6914792,d0bda8b8,5cfe1107,3d0447ef,e4a65acc,6eac846d) +,S(8af31ba2,af0b68c9,4290bdf4,b4b80345,5f52ee89,f4ddbc98,1dda1000,9c1a2ec2,a37cbc1,a5efc09c,dc944f42,a66a305a,b302eb17,21ce5088,a7deb46b,5223f0b6) +,S(1d211de7,d75d4389,4cdac235,9b0b9e40,6b71b8a9,8c0583a5,7d7a0056,b3e88779,3ae4bfde,20f83eae,96982e96,62d65443,4359b2bb,df249a85,c7c83b95,56d7679f) +,S(be6beeec,18aa8d77,20100975,3dc7d745,c6d49f9b,ea64ebfe,b8fdafc0,92a192ac,c9e14aa2,4bce41e0,f444030f,ddbf035d,e808bc06,63a70593,454ba287,4ebe50cf) +,S(b126dd86,555491a8,e2ab601b,2f133960,d86a7f9e,bcd2c88a,cbd8764f,1afee3b2,d22ae79f,fbc60439,baaf2c2e,418edb77,70837ebc,a909322d,b5580c30,27c20821) +,S(857b9c62,6350cec4,f928d456,7d30cad8,6f1cfad,142b338d,74a137ec,61212791,9d3dc070,f610ee55,cfb9cfaa,4bffda56,52f7fd18,7f354634,ed4f2dc,d27f9ca9) +,S(bbb7d30,3e242e87,2e94e3b4,27197ebe,5252c363,43ccd8ca,940202ff,fe5775ac,f2b5b210,a40d1fe,140f8638,3a5b0f9c,96885d5,d9857a3d,252523b8,d59d33f5) +,S(3e90a10c,a61bd12a,fe9caabd,e52dafbe,8bcd332c,e0ff8bd,7718b685,89e26447,3a4d342d,fec7d557,7cc52bf9,d7c60537,50150146,8a05baae,7b562dbe,b626a952) +,S(dc1f2531,d5e0d304,66b963fd,7d09524f,c66e6bbb,3855b6d3,141db170,9af05fa4,f1644b11,e8291f92,4884d3ea,cf89d857,fc98c3fc,e49fef96,7986e8e9,d67c9b0e) +,S(2b4714d1,fd0aa7ab,6c103ae9,19493efe,4a503d5f,beba56dd,93a8c9db,485c1dad,d65bb3c,47efcc3f,7484b6c0,9f51605,30542a81,d1192ac7,5d506c43,16f41220) +,S(c9ffd7fa,3b14fce7,c2946111,e940ab3c,8199b7e5,40bface2,5d8e3b0d,d1a15176,3b40f328,a4539bd0,a0b71e5d,91a881c8,87b31e11,453d9f5,82066f44,ead8d5a5) +,S(e019b0e7,6b4221c0,e45d387c,6ee41bdd,ed5e219e,a7069b73,d92b6339,2657c39e,792691b8,4c8748a,cf10475a,955aaf5a,77328c6,f03c2e9,bd1b20be,f363f368) +,S(51e07e1f,e8dc56df,f6394d1d,7f2887a6,9e7959bc,ca10af77,cd54064e,6268929d,c09b86d6,6837e473,574bdf95,f0b99851,b97a821f,6dc622d0,d9c6cfbf,18db5ceb) +,S(c5c19c69,9a9b6908,4625d3b9,5c6598cc,d1bba7a0,6d4e2f91,88f1b77b,4aab720c,af066357,107d856a,51c699a0,259774b3,352f8c12,988201c3,c71bfe3,c5d8280c) +,S(7b51ad32,ec4a6df5,f9c952e1,fcabd8dc,7661ec53,2631331e,5205d231,533f8d77,e1346672,ebbb97d8,569a12ae,fea65246,e1902f0a,9cd91894,a4b8aaad,5a02ad35) +,S(be3059dc,3789e16f,5ca8f6e2,c469f834,bcd3fa73,5d84377f,907cadf9,e7eb895a,5a6fa277,ee5d317e,81819fb1,11f40778,ab437567,48eed726,238ab5c7,f4d6ef06) +,S(cf75a66e,810f3284,52e09fa3,15451289,e1cba33a,ff1013e,4702ff1b,92b6f587,a0658bc5,8c894702,ec5c366c,5a6b18fd,86269d5a,8117dee3,601dc40f,cc93f17b) +,S(6356c70,7d5228e5,253f09b7,7020681a,fa64dfd6,3cabd703,91d7f892,d9822737,3241ba88,cef88e8f,98d19fda,717904fc,737a9c77,45838ba3,97141964,946ac7b5) +,S(90d7f09f,7b8a1232,236b4459,b031b0ff,d5e8c903,36a35f04,94a89615,3baf8554,4a612ce4,b18b7ae0,f3c557e,c4ab51bd,7c32f26b,24d0ca7e,accc748b,3a2db676) +,S(170265f9,5a3f936f,57a39e1f,a748a3cc,902b1b20,4306c49e,f4485b15,555f80af,d2f813a4,b329da9c,68104a55,301eb7cd,3ff6dfe1,c4aab9d9,d2fb03c9,e7ae2bee) +,S(2d6316de,37598fe8,ed6e3e52,ac47d442,636a6553,64274692,5a468f08,54377eea,e064f40,7f0d3b32,74a61d82,d7b75006,6fab6447,e66f2d4b,20439303,cdb3a107) +,S(8c89678e,73f3085a,1a766e14,f566625a,cc29dda6,3eb7bc9,ed1195b8,5fa2092b,12b42d8e,91c9640,b8b2509a,157229bc,a66d28b8,157742fb,a12d7405,eec110f5) +,S(ddeb928,de6424c,f9ea76f0,abc208f1,16731596,29fdb2c5,c8e6ed28,38ab6b11,b1395663,9ac1f06d,74aef36b,61916872,7709eaff,d8b76905,ca404459,325839b6) +,S(485e8e44,35c46bd1,d0c2a4db,19b958fd,4a87511a,ad4aae65,eec4f5ba,6cbb38ee,e621d1d8,736d6df5,df2db5d2,36887c27,a93733b8,d3232dc0,95d0b2b6,d0be516a) +,S(bc527a44,2547aca1,91fd98fb,84ce7b3b,6210378c,46f7bd46,bfd375a8,1b61206f,ff7c1cfb,d3c21616,85d6f405,e6f19e8b,6785e6be,ce374189,4efc149b,b3031707) +,S(9911194a,7a75269d,2fda7214,21e4e2e,3666ad12,3e76004,b5ff9afe,9ea89ca8,b1f350ab,c87d942f,1aea75fe,6c144ea2,fc5cc040,5c38af56,9ee45413,17c7bd4) +,S(93226535,e27a96af,7953597,4db1d4d5,4a65d3e9,331fc3df,7f028fa3,288c3189,98007e66,60fc6673,5e8e864,afc62171,49168a86,27d35eea,2d02d90f,e6f15331) +,S(752d352b,2459fb97,d5a0c46c,3fef99ed,50ebfe74,ceb1c881,b2fa518f,3aa59e72,c6e99a8a,2544731e,d932a164,ca0def49,dbfe4f29,f8894133,ff5eed02,66c4fbcc) +,S(ab37b416,dd06a595,ae6fe33d,717c4ff1,fd1de2ad,6c58e2b3,660e872e,aac7aeb5,182f07fd,61ba43fd,e11ad355,d7027fef,714c9b9c,364c0b72,1838ef7c,f85d9470) +,S(d2fa3ff2,b1cd8909,52a0d380,d43233f4,1eef04da,aeac6ceb,46dd8e6e,572d170a,85f3c854,3eea0e64,b8a9eabf,18057700,6c3a6f70,a790cce6,24a3f6f9,5752c520) +,S(e256c5b7,99ae8dd7,1daf5a7f,3dd94f94,e040d98,291a2d6e,9b398889,addff0c,b4375e5c,82517974,b515ae28,54c83443,e8bf9391,cb975013,727e3bc5,1473b133) +,S(30056648,afaac00,c1d77bd7,e7b5235a,fea2bc8c,58b34a6b,83e630d2,3036db6c,16ca5c30,6882fd6e,f7d82f93,b25ad01c,eb3e9e69,b8280f0e,e3aef2e2,ec204600) +,S(8602fe69,d4b1f32b,e8422928,200c5b5,816f08a1,759faafb,29861e07,c5dccef7,59a5ca0,35490ebe,66409e2a,283f4c9d,f6e0a7c7,9dd1ec82,f31f7e4e,4f23ead0) +,S(53bb9f5,ed205516,36ab170,7afc75b5,6ab3a75a,3d360c15,3b0b74c2,d7d9d64c,77c6c1ec,c7a53dc3,8c6540d4,461757c8,b5f7b66,654fd754,fbfa8f5a,a5318cbf) +,S(badc41b2,86982d76,e5374b3,dcf023e,dbc1e187,70cd0b2e,2916d436,108a4328,b1694651,a69dfad,924fdf5d,526c25cd,e732078f,31128556,3d42ebb1,3329e2fb) +,S(15b43026,f5134b3f,1ad441c9,793b9e57,a318d455,fd6f10df,e4b0bb91,5d36600,43568550,60fb010a,6d5123e8,b446a1e7,cfddb6b4,6e4fb18f,245a4be8,f9975a1a) +,S(fcc64bd,c9df17,4d4e8e18,cad6116,a48780e2,a180f7c7,57f532da,9fdf37e7,ede37062,35eca482,b935410b,6d495f53,12b133cc,238eeb6d,e8e5f593,65601951) +,S(f394fa79,254fbdc2,7a1b31df,1f868c48,9b48b6d5,1afab542,2da5b1f5,6f3edd2,f56d3d7d,e7f8d9c5,fd45d6e2,cc2af300,fdce3293,9be5b975,9d81cead,e2000e7d) +,S(3c7c8c54,6b853a5f,97f92932,5558793a,e1debf3,3f680d5,6a79bdef,d4608d91,575771ed,f26feb38,a728354a,6c4023ce,4b019d65,3f7adfee,3c83cf58,9f2fe4a) +,S(51d61258,43b8d621,6c0880d,f04f34d,9acbb422,d8194a98,dcbf222d,cf27fc4e,2d0bbd0e,ae299afb,93980894,bfbdbdf8,6edf9509,ea408286,ef602cf0,ce3b33a2) +,S(14b17f35,ac7b5914,e08babb5,5aa37cb4,26d3bd34,f2c1e4f,45acb493,8ef51a65,a9090e25,cd8273c3,15d1ac6a,15eab027,7981f6bd,a85fb082,2b24cc88,2918fbc1) +,S(59ceb93d,d78ff6a5,f45c5fcc,7c1ecd72,43f2d8af,e4ba8a3f,fb03053a,586387dc,28f4d0e6,38ac1fc1,98aa3548,56f4f19b,479ff825,5d150f29,871630ae,f82f3777) +,S(273bc0a7,eb63a0df,eea8d7ac,b24a5200,a7086078,388db5bb,37a0a6f6,acf24656,a971405,a287160e,22909b67,357fb63d,10af5ece,f725b1ac,17c7fc73,759936f3) +,S(c9b5b690,3a45e529,3a298219,cca93e0,52a2719c,25cf2f50,c4ff7f04,5f346475,7db09fca,ff1aeae2,dad001ff,1fca6166,a607eaff,bdfc327b,9b63e2a8,e97f665d) +,S(90044bea,c8459e34,edf7c40d,2a101b45,66728d1,cf0055ee,c8ea07ab,e39307f0,19763d08,77d4a896,ca9ecbc0,56d405b,5a6ebcce,1ff6ac26,593be19f,63caf6cf) +,S(6e0898bf,bf6baaef,d085f41,da7e6b93,6b6c9a88,3728dc7,8ce7d71b,fd597b2e,4769146,91587abc,c2f21e05,4542280a,f7260a72,e822edca,1e63c089,3bea3dd9) +,S(e94563b6,e0156145,ca2ef19f,58de9727,7b806969,a249629a,4f024b99,8a023792,c8949547,a4d25901,f3980cf5,333f65f5,8e1797d8,b42ccb0b,dc550e6d,5909927f) +,S(3cd027e4,173c2799,54d06c3c,ec05c0d,161a3b73,348db0d2,8c03d097,8921ad64,f0d1a3e8,ebc3387a,ee88189e,c1fb3f6d,5e73e895,7b7372d9,32b00144,248271ba) +,S(4c96f51,2b4f0758,38335d47,db599db9,a2dfe1d1,6783960c,dedda119,693d5686,4e840262,66897288,9bd54c15,219ae871,e6426b67,afa949c5,e1226bbe,1204dfe1) +,S(8b03ca2e,458873,963ba6b,c9dcd14b,59fb1190,3f2330cb,22997bb4,19002fbd,2b29df15,c6be49d8,27981ffe,aae26930,7a461f84,8285f561,4f910508,eb865781) +,S(f4217bd2,32229dbf,39066a17,c2524838,38098362,f0891b69,275dede1,f8e64f0d,7581350a,957f480c,89246800,86c2803e,99ff5037,938e3e19,22e3f9a6,7098dd96) +,S(247274b3,d5095d63,132673ca,dbf0e418,898468d3,9a30c538,a46a2719,42846bf8,4265a1b7,7d1dbc68,956f2441,9c4d2b70,9e71f6e4,6e24e336,a978285c,22a84f11) +,S(19c25b9b,97f40ddb,23d62bd4,a298ce7d,befdf39d,327aca47,61815c0a,28d4af9a,a9b5d705,94cf4c7e,b7e947e2,101b18bd,fb9f2f20,fc3bf89d,f5a63d7f,61d3b3ce) +,S(fb69718c,baf0c5f8,e20ca98c,2fdb18f5,59df27e5,c2a064fd,ffb2785a,73bf27d6,b612c590,4e0b1c54,7beb4e07,82ad2716,84eb895a,862b59b5,cf6476b8,af52107) +,S(9fe6e793,ed1aed77,d8381352,84890e3c,f817ca60,37ee80df,6646a3ce,9c316a6b,17214a01,99370a88,41717ae5,41d35a4,96f8f041,e9b3fe88,4188f6f4,e30b0657) +,S(c7f7ab4a,394f17c8,47010e9d,f1764fae,6159b140,578f70c9,fe50703b,aaba62cc,9673f262,c875953b,90558dec,8ddd04a2,6d7d3ac1,672e3d10,c1a3c656,b0318c19) +,S(cc2e30bc,2d63d4d2,bd0f5bca,8faac99e,a6add123,82d014c1,d7bf8285,7ede2297,cb87a21c,f1efe789,fe72ca0a,b6acc5be,63e6973,2ca899e6,fb9e05e7,72d4d8ff) +,S(6fe7070d,a78205ea,1f12661b,4538d0fb,60b4bb4,9c1709c9,e53de22e,c3c25d6b,2f6b773d,492a82f7,f9609cbe,e1af3c9b,2940a12f,1e615c1a,801c02b2,19e6b8cb) +,S(1affe9da,ab5da7f7,9b331e9f,91eb7e3a,f4dad51,2317ca45,3ae13528,66013d8f,2706d2aa,d3139097,73a0febc,191c7a0a,df2ef168,c65e759d,7c034bac,49c8a92b) +,S(13566dd2,d0cdb199,20a1f9c,aa1ab581,c3ddf2ad,125c13cf,efe199d5,bc338231,b403ab04,67df46b,2efa5b8a,4cfa8bd,97399c87,12ffc55e,cae8de52,d4f6f28c) +,S(135fae69,9a969720,b1c0d899,790afa99,83074584,da3ee8dc,1e011336,dbc3636e,b4260b88,2dc79423,8cd0fbe6,5242147b,c96690da,c391e3cf,d2c53ecd,2ae9fc60) +,S(1b05d97,744364a0,5432de4a,7d840834,3ffe211f,a543bccf,71a4b210,3bb0489,d61c9d21,671b2481,a4ca0c36,7d4ea919,ae1b331f,a8aedb87,cc6b6c98,85616a9a) +,S(2877f026,83a5cb48,7014da9d,419c8b9c,920f0940,718e2d06,d7252de5,5b46a84d,849f9fb2,88d3fdee,de734aaa,3592ef01,483e02d3,62a5e0ca,2ead6c0b,42628038) +,S(8a7024ce,6348d2fd,84be71ab,b363bdb8,86ec6a2d,29d9cd83,1934270a,27370b78,8f520972,9e4e1325,363a68f4,ad53737b,688c63dd,1cec6cfc,bf9da51a,98b29c0) +,S(5ac77dfb,2309c061,8f68b320,bb6eb76e,4b0f0792,b8235fc1,ed768c57,44fabb1d,fab11baa,beafeab4,43a14a82,f8d70228,57752732,7b016b56,32b924c9,ccbb1db6) +,S(aee4edc,93413d53,45e0df68,99fc2193,be318a8b,f279f0e0,56c0ac42,a60759d2,b6a87499,1dc68ba8,503beb0b,8a6c09df,cb9efb6b,a44aed6a,3cd7befb,506119b9) +,S(b51d3e77,741d0d44,3a67b5d5,67b45aac,2008c25b,5196c71d,c9f910e7,b76dd2d1,431c7ea3,cf4f577f,950d22e2,74b7cfdf,2c2934af,ad0215f9,459a802d,ddee4c21) +,S(803a2ff,c59c2a94,65d8935d,93d47653,86e5beb9,c8e702a,12d7b565,98a09841,d5e02ccc,5d8ccf6e,29a7fb76,5a257dc9,c902c900,a4fe16d1,53e9187e,290efbeb) +,S(22c17725,44eef514,5636a398,23e874df,8c58bc6b,6935598a,440ae9aa,5b738075,a67f431c,688d4426,c519be32,9b1dd50e,2c64648,4d3612f,35d52089,c98dbcfd) +,S(ed67feaa,5aab50a9,ff71c434,855bafb0,5191f036,c691c8c5,563395,d2053b86,b2d13cb6,4ea821df,f8829ee1,57cb5fca,81dcce75,d091719c,73cc7785,c443f0a8) +,S(f8cc5ae2,3b670b9,3c27ab8c,7d8055c8,4654b427,f9e6b733,b083fecc,c7c5d375,7dc996,7bc3a2f2,f516aab3,682f8d6a,32b84173,ecc742d5,c8a15c5c,72eb261b) +,S(838891a1,fa46e300,a20fa3d0,cba3fe09,3326ffd7,bcdd7c73,b6e96da,5d591332,d46717e2,c5fa3d52,a268aa9e,a85922e4,547ea986,3a37b1ae,b77d75b0,d48a8fea) +,S(92caeb7f,400d043,6d36656c,8ffd5d45,6097cb51,cf512c00,1fe613e,8dcd5544,2096bc03,dfd088ca,25cb9aef,29b24b99,2b2aa00b,e3429cad,c0976a3f,162e47e2) +,S(2e6226d,574b687c,20dcd4a9,683697f8,afce56a3,1e11cdef,6f0ba6f0,dceb89b4,d9c4d7a7,a7aa5f8b,f30f0930,d6c3bbdd,b1963b1d,8cf24796,141bddb1,ba8ffcf7) +,S(33aab3f4,17d936de,b8c1f07a,9fd5024f,802fa5b3,a593a6b0,9fd42871,75f4ee7d,4c13dc95,7311dfaf,932eb4cc,68c82550,3b185530,13008dc6,878dd092,50edca9c) +,S(ed74a882,a947da53,fd62a242,b67dcd04,50896a43,e9882c84,ada77f47,691e5fc4,454a18f,a8fc6d8d,e673410b,213875ee,35190221,9f7cf88e,f363be08,571030d8) +,S(b5d3f084,56db930a,7d8b4728,2caaf807,be7bca65,bddf9738,67a56224,39723ebd,a89e0271,28d5872a,f4d6b4d7,c5a7efa3,b0339a32,89a12918,2077c106,b61e1a4a) +,S(5e40e90c,1a01e008,d5fde186,283919ef,eb859921,c3ec07ca,e34eedc2,b0f07967,e4be6ef4,26eb3c94,70ee3084,f431c68d,82b2df48,5286082,82cc1b2,afe77900) +,S(2f4b14a2,674a743a,4aefd302,7fb214f1,a7678336,3c9e7c8f,8ebee72d,c5f29830,11b13461,b6578710,677bc733,3d28e773,c78dec4b,27ca1aac,a17121b0,de9868e6) +,S(71909162,35890bbe,6a8f7a99,5b1cc3c,a68b3ff9,7551d09,59a97835,5b7167c7,f9aa3992,124fa99f,167f1351,865a1456,8ed9eb92,c7cb2050,5082d228,4b1532de) +,S(8df50d7d,d3cf99c7,b0269ae5,e70546dd,bed3f05e,260bd834,575d56e,e65f7f0,835405bf,3c84c4ba,5e253fef,f306bd1c,c1240ef,8c03da98,d7c092db,3a2606ca) +,S(5e0f6a7c,e9bc1e0b,852841ad,52045b02,b4fd545b,f2106c82,17a76bcb,441173ee,ad70f065,4d75c88f,e6654d56,fe65c57b,857d91e8,ad6abff,148f3577,7afa2aa7) +,S(27880a25,21a78fca,cddd0b78,5a3da1f4,2e832641,8f804a2a,42fe3c0e,f69b43b7,ac9f930,12402aad,c55c12bd,e450700,b0208d85,a6784586,d04f1c93,6df8624a) +,S(6578c4a0,dc25e068,97482b12,3f38cef3,39cfd6b2,ec06c89f,6da11449,de5e43a5,8a249d9a,41e6c1a5,a776ddfd,ea93ba78,15f2e908,b8b854c2,3a7e3ff2,cb99bf70) +,S(c66e890a,71beeba3,301bbbef,2bcf4cdd,def8e634,dcf476f4,6907a280,df3dd33e,f3510cb8,9c46f493,c4a70976,34a9c502,11532929,ddc883ab,d43bd360,1b028dff) +,S(393f0dcd,24b47380,81197794,58bf5e48,b2f5479c,8efd8925,a1f78bef,6bd16665,9898d880,e24f840f,f1b4662d,3d444c29,6527cfe8,2b6f1b4f,f0e5928c,bf09de74) +,S(337fc469,43942ce4,f1601877,874366fc,a8726f4a,65a9bb26,c6c2c013,856a3adb,95df242b,2d4446de,b2b792a4,d36ceb2c,add17365,380d78c6,3b23b101,1b3be914) +,S(b7edfbe5,118cfeb1,4c1aa23b,48154dbf,5e9d1057,a2758516,7fb8e030,a457874,bc1e5723,dabdfd76,c98f408d,1d8c13e5,7dee979e,83b3d610,981b9718,f1e61eee) +,S(4dffac46,6a507b9c,2e2ee5b6,ca81d8e4,d4e8aae6,3d73395b,dd29b024,51436e5b,af227fa8,ad0bfc48,eb469596,b9b2759b,f41eb169,1fb8f896,1451489,ebe0d5d7) +,S(553ab99,3448879,b42c72e2,97d597a6,24416a45,f5b35720,c93a303b,c6dd0e88,5ba2d3fb,222a03dd,c5302b25,ffce74cd,58de90a1,c3e41928,19717c28,52ad1b39) +,S(b351ad4e,4c7df853,8f6f71d4,e95554ca,3a07932e,7a812309,b0b0c807,f98cea2a,5ba5141d,b3d4ff44,7efe06c9,c624d447,1aa3c3f3,47af74af,49929de8,d8558c70) +,S(844b9bc0,ae73df50,e5b80fe2,fb24a35c,dbc91c61,2753c2e8,e3765e1e,47d44263,80eeb80c,414c3a08,a42d89b8,87883d48,84b38bd1,40f7bbee,e977ff5b,c4c57b90) +,S(f64b4ef6,8fc11491,38ed4ef8,ab2d6336,3d494b37,b56649d1,5d15777a,8cd315b9,c6f83010,5dcfc707,f435cfa0,b6bc32f3,8ce8afb6,28bf9139,dfc47279,cafa56a5) +,S(969ceb7a,441f8be1,f16c94bd,6065db17,942f88dd,e5506742,7cd30dee,cf9ba5c7,a08ae62c,6e6758f9,724baa45,d35f3e03,9f636265,d841b61a,f1b31d20,bc8d65f8) +,S(e465041b,78c33311,d4397b30,9a8ba4de,6b312d10,ec2ca906,583162ca,1c599102,3f21d5d4,416f1954,7af1ba97,6687dea3,520ac304,43c180ad,3892d46b,86618f55) +,S(87b2e548,b019224f,b1021a06,522073dd,46892847,308fffe9,910ffc28,5b702bd0,6e641d35,9e7ff12b,20123b72,f0e5ef16,338c3418,38c2f4ea,6dab94c,7c3f6940) +,S(f832d7b3,590a59d7,ec2c8a63,7ca0347a,893fe461,4eaba097,8707c353,8296ee14,3fb3e845,4624fe35,326062b4,a6f30c85,f0e7101b,a3532455,7687812e,412233e) +,S(52aff21f,fe1819f3,7f8b5974,ab004393,6e99d8cd,8342b7bb,ad46d333,5e4d6651,66d79c3c,c7d08828,d8646e4a,6a44853b,4a49df0e,85c95e85,d9c995c2,d09b427c) +,S(aae62778,8069bcdb,fc91bdb,946cedab,63896817,575a471b,315a47cc,d567c678,f254c548,832d95f8,4f20215e,ca4805fe,356e806d,9b3b7338,7dd36e85,214b70bf) +,S(fc15d494,b6580e0d,e1c769c3,95c5d047,202e8d07,ba94bd1a,f96064b8,d1a4bfbc,f9327fc8,75319184,c1876748,bdbbdd3c,bfee8baa,bf46844b,af465d4e,ec6be335) +,S(aacec857,fa4bc62c,82790a4a,496206f2,d79a31dd,e17d2db2,d99619d8,c3d880d9,6dd1e4a2,adc502ac,150293d9,42a1cbea,a576da49,f1de7d15,de70bd67,d95c5fb0) +,S(c7ba3155,bf34fb9a,2441832a,27396e1,99836557,9c9cb856,44c3ace2,9ade66bc,afccc814,243a1fa1,345fa46f,ee4b4190,96082bf0,7866fa8a,2a887d84,d24192f4) +,S(cf7a0525,3bee95d7,711d8f7b,7b301f5d,8036a487,a55e3860,900b25b1,c4599115,e8a4a9be,7b9cf99a,5dcb4db9,8249350b,7a71a12f,a9582620,eda5a35,1a8a0484) +,S(a4336248,6b999ad1,623c4c32,c79ebb3,4e8d6f3b,484f808b,9a088ffb,2885a11c,edf8eef9,74d3e5ae,2a991a28,6323597f,5a161f9,2eeb9256,207be548,f9b38d16) +,S(d3cdbd98,8cefc8ac,3a442587,51364a10,649243a8,d4a63927,f4fa3b10,b1a7dcc8,f10e26c8,11f4a219,da4f948c,51e8b81b,d8bb357a,182031cf,40ffb464,d5f7d7c4) +,S(fa038534,28dd093,26977fc,da344269,fe3c61fe,35567eef,909a2309,8e5ceaef,f31c5d30,9e234b3b,44fbb52b,8c973aa2,bd85afac,1f9f0798,788721a9,380d8606) +,S(718c2bc,26dba98f,24f34af5,18e18870,5510c0a7,4e228cd6,9d4e39d8,a00a577f,c41d0d81,8f093246,5675a326,d0615b0,294b8455,909af0c6,e557195e,11225152) +,S(378ade51,463d949,1ed22ab1,834cd7bd,6b99a123,52c65e18,70d5005b,e97e602f,76469796,d7758ba4,b3bed1eb,9f8389a2,2a421f5a,20f8df71,72821a8a,508e4c1) +,S(40bd7df9,1255680b,b50d3d08,fead6815,5f807759,87e9cf80,15e6359c,9f138b8b,ec0417d4,2eb1ab50,a469a853,edc65ca5,2fe00ee7,53b30b9c,56536e3b,36144e8a) +,S(f01b30bb,985dfb53,7bb4cd62,18cb0b00,b5a77215,4d84a802,8a4969,260d963f,3cf483df,d6b58eb8,46e8ba1b,f06c2e9,6784255a,2afbf68,613f39f1,44b82417) +,S(2392d86a,1bf9a636,38eaa5dd,76a7c6c9,eabd50bc,9f2ba568,183c0995,f7195900,806cd3da,ac23f93c,3b11cb5d,a3bc4482,ea49ed2b,444c6e64,dc557e46,3ac5c033) +,S(b0e7747e,c9496fb,aa7798db,e616fa42,5b0b7acb,7409265d,c989b8e9,20087133,32fa615e,d0286b64,b83cbfb1,e8c4b133,85527655,48071401,89f42d93,330491e1) +,S(8d1342f4,2f6dc3cb,9bb741c1,9daa08e2,25fb6352,ffe860e1,76a26fda,a0601624,82d35ed7,57cb6f31,81af31fc,36f53817,191fb9b,c9338a97,3757d0bf,50d79d77) +,S(ad09dcc1,d3ebbbd6,ecd7be45,d7eec5d,ef743851,2ce076e3,cfc4f8b9,449a2ccb,26bde63a,e1f7fbd8,46260a64,372d015a,fd3d5ae6,125dd801,523a94fc,8421d04f) +,S(128f5199,68435c1,a27591a3,2edff533,d12a725c,f0c7e121,260cbb74,925cc292,dd8945f7,42f1d013,92152dbd,1e4dd8e,53277da8,bab68acd,8c7c8d73,f5d7e190) +,S(118c1167,196e8eac,e519d83d,17ae1e30,36ff1fa0,cbd1cc58,41cc3763,d1d8a931,eea348d,54f47b73,d5d8c2b4,7eb7604b,53beb345,c82ceca3,4f8639e1,45b2e3b2) +,S(81ee4bba,6a84edb1,83e1f2b7,5103e453,2ba9613a,b612e0f1,27009ee7,7be3bfb,e58208,d152059b,73b42039,e0a7a489,df067fab,1d1c2c04,9eed00cf,893f4847) +,S(494a821f,6f4b2d75,7e5be34c,fb9949ba,b9271599,3e060005,dd807c83,adf04f2f,8ab15e9f,c37d368,3586a1ed,ef9ddc59,8dae7206,499cf53c,31a8cc4b,d7ba15e0) +,S(3749271a,da87c292,724a3ad7,2861a7df,9757e31,3c3156a1,72cd3735,608c865a,aeffa1c1,aaab4f09,3998b4ef,e046aaf0,f404d590,d6cd762f,1aea5745,1f8aa3f5) +,S(103c8721,321ddfbb,cc3ef6af,1ea8fab1,3de6aca0,294dbc79,3a1e4216,563dc1f5,fe9cca2d,b459596c,462fb268,a8115880,16c2894e,e8839caa,362e4813,e8e827cf) +,S(ddbfc655,6aff403b,10a643fb,f62a60ed,656baa39,b10febe6,92140bf6,7b78f2f9,1cd4169e,cc8ac589,de57b5a6,e02e03df,f3cc7bb3,45993d5c,4ea57e6,852a8417) +,S(d025f583,3e51a9c6,a1c785c5,1c579528,5af0c297,c0fdb82a,f555fd59,88dbb28,5170614c,110f31ce,d88424fc,7d569f4e,e93d5017,a8c676af,c7261ed3,340d22ef) +,S(3f349cbd,8ebac9e,c570b0ca,29fe8ce8,dbd98eba,103f131d,daaf193,4fe78516,ec9641f3,175ed56b,d0c8f26d,188f9fa4,b38d069f,cef8f4cf,71acf66f,1ef7dbc9) +,S(7624599c,61e71532,a177e838,ba92d789,5160e43f,ad798fe2,9170e6d9,bbcc11ce,409e8cbf,6aea70b8,21533902,150148a0,7e45dd61,c9c8d24a,b8cc3da3,f03c49a3) +,S(8a1e1b47,3c699dea,aa418ba2,85cf7467,51af1cb0,8bf78228,932dc6ed,845403f4,1bd300a2,7a9a8da,6ed2bce3,73b9d39e,661d02bd,b4605740,20934bc6,abf3c483) +,S(eeb91c38,d9b834bb,5e3945b0,9655b988,96efff11,1e3dde8c,add6ef2c,7ea51b09,899d841,24f83b43,e2ea82ad,3a6411dc,cf36fa86,17bdab35,d83829d1,456c56be) +,S(46360f69,8c023375,6f050969,60b3defc,2a1897dd,44e0e159,d185ac04,3315ef47,ec02a6d3,828246f0,684d2059,23ba73ee,10cc88c9,575fc005,6271fb8c,67e0a4a0) +,S(16e5cccc,b410c20,e8de1e76,e5b71649,64cabc26,f629f8be,36eff4da,66f875ad,a80de48e,e079d9c,bac312e0,70f10d6f,fb875c90,7dd3ff57,c9bf8b90,57c0fe14) +,S(c315230,c8ee5bd8,429efc06,bd089f49,5f4c5a1e,2fb188bd,81e41bfb,85acc82f,71430e8e,cee9c6f5,eb91eb14,20e07b5d,736217e5,4bc25cac,9767a749,a477599b) +,S(7731eb8c,1684092a,d9d2ec69,b50339d1,19436082,c9116366,8ce2bda7,ee80c0c9,e6636efc,22a4c339,f8100dea,a227a709,42d18222,8cc58d13,ae4d613c,a879de8d) +,S(2c1c200,4a5f04c0,b83d143f,ede81755,67d4d54e,b2dc4ffb,de00b83d,9802f68b,b3e2e434,30d409cd,26490c1c,818b24ed,b10e835b,d6292422,45c529f7,6e299159) +,S(2d984bc6,a2031a3e,1a57d0ae,d13d798d,fab45382,d29e4a7e,8e029fdf,2a9d95c2,b169c34f,9932f02,8320ed87,4a74da8b,5cba81bd,f20a9454,feb315fe,a0926720) +,S(f61abdda,f7673f75,74e966f1,c77096c7,7f6e8659,746e45e7,2c9fbf3d,5e0db5f6,1717dd6f,86edd17a,b242212c,91878ef8,9ff1b865,b32b4e24,cfdab7de,de90937f) +,S(a68f5871,bfbce14a,1097eced,68a9e906,c94599cf,b6dd4176,ef946fa7,e5552c3b,cbc07a08,86faa82e,d231eb0,739a24e3,62a717ed,30b0512b,96ac8dd9,56ab05f2) +,S(52035076,1af3e786,60906105,36a2ced0,6f8209d,a0eb2757,cba705a3,467ccbe2,7a01b944,5f63cf43,cba95191,262b1b53,ae0af9b,4b172b78,3970f84f,f8ace09c) +,S(bc8f1537,9d4b9862,a437065b,10f6c28c,8c3323f4,51f2847c,63251000,c9f144d6,894826ed,61d85e90,58c00e74,cc731dd5,d62684b1,ca996c07,ab176df0,e4b951f7) +,S(536b0cb5,81dbf6,ab3b364,64a397d7,2a513bd8,a7bb8237,70a725d2,2eb12a98,85bc95fe,6e160f2f,9a31b7e2,74c09023,90cb2f4a,22f15ac3,3d0ee72a,b666f5bb) +,S(267840ea,e2f49fe8,9889bac7,40eb797e,ee42f922,c1821a66,163a580a,a0df90d0,2c7fe7f3,4e06f09d,a1a2b1ba,79906a0b,18c3d51b,d9b6011f,688c69e9,1504a00) +,S(d8fd79cf,6beed8c,fa57bedc,ca06e367,e0667e9d,a057222b,81fba682,979808ec,39cab613,9cef186a,248562d4,fa581384,d6c81de5,a0f7fc49,140d0822,f6126034) +,S(601407de,9ecff4d0,836228ae,eeaa612f,2b659706,576e2eca,74bc32a1,d3d14b7b,6cfde694,2f0e4495,1e25ff02,2f2501e6,7101828f,8088c7bc,a8ef2b25,88036ec3) +,S(f518c5c,bc0e8541,48c40253,d500a2d,1ea1d25f,d31dc777,d6365050,d3b26804,8dcc6378,2b1ce6fb,9f15c8fb,70c5fd0e,53e4d80a,cf38261f,49a558e1,de637b6b) +,S(16a9bcff,334e35e2,80258378,b2e25d9a,56ce58c3,b3426bd,da82978f,370ee6f6,c7b6656e,baa3864e,bfbc5294,fe9836a9,9fdc095d,ceac6a32,642e6911,a6f3e933) +,S(9d940fce,5ecdc659,30c945db,7151b823,a9259d0a,2a3991c9,f71e8b00,bbe35d4f,32f533d,d96f2e36,2109a96,48ef55b2,e5887387,80de97ad,c7974227,b23fe647) +,S(19e973f7,69c2d02a,8bed34dd,b7591828,5036e724,22227a81,850f3d31,3128f586,f2f5fab4,fe79c177,752ee60b,cd85e625,e459b50e,de702010,a6fbcbd1,5b31aa6f) +,S(ff07bc26,473271d6,4371a4d2,9b59f858,b1b01e40,472bb4e0,1769ed2b,66bf2097,3eba7660,492ae09a,abd7bb8,c5d80e33,44539ab7,276edfd5,b599b02f,27c60b8a) +,S(175f786c,93d89acb,8959d846,934c21df,5dc4f6ce,a9c1e150,e7da469f,d27e6605,343366e5,7f5b9f7a,407cd566,7ef1f0f2,464a2938,61fd5f2c,b0363a5b,dc9c2f9a) +,S(a9027f8e,b662a7e0,d70aa1ac,d3e0b9ba,d4e0bd8e,8bf8c883,40b0a7f5,cbafa761,2f9dfc2c,57bfd835,271d63ac,e3cecdfe,f6e19e0a,fc19ac0f,71ef9ec2,7fac30e3) +,S(677daf40,728a6c89,6804ed3,1df283e,19b41c2d,36a3a98f,d4b93fa6,6699983,1affbe57,3a561872,37dafd1b,bdcaa594,e499b298,6af58591,c6a2ea3a,2016c039) +,S(1105aff4,d4761b77,68db74ca,d9fc7aa0,14c5417e,de1fe641,ed1dcdb1,9b5a3690,bfabb1aa,76906ada,4a1ea463,f4caff44,a41afa71,b82e2457,d2756ddd,14946ff0) +,S(3221d033,16be670b,e05ecc94,8b537ca7,9318eb65,f93ab3e7,32e7f36c,bd06249e,92f7b5c9,85ba3fd8,7b14a093,74d4ef94,130d3642,517369e8,f9de5fa1,c8ccb803) +,S(ac10037c,ad83fcbe,6aa7acf2,3043ed,831dcdb5,66921f16,246488de,6e012fc8,d530eaa8,ebe1d47c,8e57892d,9301c4a4,29b223b2,7344e433,f2bf77c4,d9a20205) +,S(b3ea670b,f5001657,913d5d49,ee1005ea,65fdd33c,4ad81987,efa0331d,b29a3e53,6d758db6,df4275e3,fc148e91,6536505f,6393daef,c54c3b0,b708e0d0,8de3f1bc) +,S(42762d8,bf60f678,924b7cf5,4e8c513b,fa1223cf,98e124d9,18d88cd9,a54c8d88,96be42a1,f0dadc84,64a3522d,e13f10ad,3272505,f7d4fc54,e6dc1a33,ef6b2eed) +,S(7b9e0117,167c51ed,c3f7d2b9,edb61bde,aa90efd,88349510,c4b1cf1a,43a9ae6e,c43e0d1d,8a673cb,1f0d9d1a,e3a4c985,bd47a068,2528ac36,67976881,1ead7a4) +,S(1e807fdf,c69acac4,ba5be7fc,9c617005,d34ff896,dae25e6c,428abb96,3255239e,7db7d6e8,8bf3b869,fe4f7c11,65d85faf,55bd677f,5670ebdd,89d2f8b9,f56d972c) +,S(9aadd434,75384190,a6289f2,32cc6491,fb7a1d86,b04ae9ea,94dfd2c8,449c3961,fc491907,3ffe94d1,3b945382,eb9c482e,9da5a764,d9aa1d1c,c3d973aa,5edcd3f3) +,S(5012b7eb,481fd85,db13c3fe,2bdd06a,720eb4c9,805193d2,b99b4bf7,39802f26,db8555d7,e2cc1858,21920564,3c288352,22086161,1a611dcb,d1e98518,7c46cd4e) +,S(78f9e5ba,91071270,5160654e,2393cd73,85e4681f,8efb4a45,cdce5ef3,d73cc7b1,24c4512f,911101c9,d3a4fe24,b7468585,36cb8137,e13578e,95cc016b,96d86e20) +,S(91a7d927,4de2c0fe,84a10579,891ea8cd,f87fcf5b,a0939411,4612efd4,6bb9f826,d5a5e511,b85436b,89e46211,ec69dfa8,d0ee87eb,7c0daa31,24d48462,10e6c40) +,S(3940b4e9,4626f86d,4592b96a,4f27f874,c37c6cbf,5940de,37dafc1f,35350b69,ecc6176c,43df3f71,cbf0160b,697afeec,1a9a0d69,5ebdb7bc,34b0efe9,2cc68b39) +,S(76e7ab54,8c63ee6a,30c736ff,11762061,283af0e5,5a7dbbd2,23fe467b,85c95d8b,f266c922,fc5e61f1,65bf521c,33235e05,113140db,6a481b0e,e4f9976d,2696fdce) +,S(ecdc2e5d,b8d5028f,f93de09,c9f5a6b3,c439b14b,3c322c53,94622a13,80f04067,e70df9f2,bf6b0a35,9029f937,5e74aa93,4014e78d,e68e29b0,9d96da05,5ff78112) +,S(ccfe93db,de087d5b,9194b286,99243dc0,91d4dd5d,7189a5e0,d5621311,9dee9a94,2b0a0a20,cfef0c73,addd2dc6,d9b4ba7e,9e44f2c,26d9f376,8ef90241,b2d907da) +,S(4e82a200,e64f5b3b,3e473e50,e437c224,e21bf875,ec8ac364,7e599ba7,84f02574,ff696d9d,2d9cc0be,217394da,85201a1d,208e4309,9b9372a8,19f6d069,88839c0a) +,S(a292e105,6f3f0a1e,e816a49f,51ef4760,91324316,2e3c734e,802550a2,c942c17f,479a2e95,7a05a686,1c08df3b,221ed2c6,5d192181,189269fe,9ef42a8,e71fd6ef) +,S(47279a82,8311aa4c,b6138c9b,ccb2fc6c,c4b9d27e,2e334389,1773fc1,ee09f461,2480a805,496e8bd3,e02b36cf,8081bc5a,254f821e,40c0ef48,291ecbb1,6699a10b) +,S(b903b4f8,2126fe06,44976643,5f0982f4,394db57f,b473401,9536740,595562fc,e8c97572,bfae91fd,61cfee63,3b24bece,e587291,f65a6aff,b71c6a3b,615e1361) +,S(16b9e3eb,eadf469d,368ab368,431afb79,214bc728,5df165e6,c3bf98a4,701b05a5,26e74ff0,64cf5de9,ec3d084f,8d75337d,c04918eb,f783c65e,b50b948,d48eb003) +,S(4927fd2b,c17b92c1,3b3ca52e,759324ca,353e8505,ba81ac24,9003091d,1cebbfa9,95a6c16d,c4c52f20,2883ab4c,a9c050c2,b2849b71,e19e0df0,8ff495cd,f62d73ac) +,S(70c503d,93e47,10262c8b,b1630409,979b673a,79ad08b0,8d855365,f51ffcaa,2ad207aa,5fe05144,95baf3f0,b0807efb,d10265f0,5de63d6b,563e4ac5,e70b89ff) +,S(cf598642,32972f7a,a6cf12ce,dc5aa95d,4bd0f96e,38ed546b,9ba9040a,e25a9e6e,67f2f83a,f5f09b52,caed83e5,1b9d6de0,58a6e9b8,96d1a6ed,d7ab4d40,30332027) +,S(617b9e5a,8d0b8c44,b186aa60,281cee51,dc224e2c,9e1c4f07,c342a180,78b271f0,b64d8d5f,bc2907bf,90b983cb,a6126586,dbb7e7f3,d95993e2,2bc1b8f8,9472d200) +,S(d52e0c90,c69cd94e,3c849ea7,dbba79d8,6aed2a3e,3ca3f106,d2baa2a3,59c50534,36c8390c,fe400769,fd2b2fe1,b6af62d0,7fbd667c,fcd9a132,b6b4f974,a7e454f7) +,S(ea474a01,36d16bc2,fae6f568,9ea3c035,aa6580e6,b238f42f,e2ab19be,81330a46,d09379ce,aa89765e,1164f438,4b0f0ef0,c1e8be86,427c7455,af98e4b5,c9ee8145) +,S(4e5dd22c,b6a4b205,97f71375,cc49ee10,ba6b82cf,b06cf065,a25d6f5d,bef51d70,d4ff2ed0,55279f96,344dc16e,10e3410,40378ff8,b8d912c3,a17cbfb0,70588cf0) +,S(774587f7,f3038136,131fa9eb,f1eb3407,9e473a8b,b9e5acb7,317ff5c9,17447878,9d3779a1,2b067b00,d2a2a3e9,46f8078b,e6279024,d94c83c6,28c0cd48,145f510e) +,S(ab807569,d1a3630c,e5447b36,c205e601,a6a23069,4d2c0786,19d9b97c,e0ba6611,2b9eef15,54f8ee6,e11af6b,6a1d045e,d47b8821,ec84c6da,366afe10,2730e9ea) +,S(91602928,ed3cea8f,4faa254c,28962b68,c4437602,3076a5c1,6bad95ff,3e328049,764faf56,2d8de3c1,89b7fef7,62012be8,112db4,a3201692,95c7e76d,fcbd3be9) +,S(6c1ecc2a,258a44b1,ca1d964b,c86c5600,49fdfd98,b362c35e,3c830647,cf1266d4,1f9d3edf,5e0e8550,e4534c33,5b07d731,19c49c4e,29397f6a,938fc1bc,ebf8fcef) +,S(e176821a,4006b429,999de3a4,ada09166,f6e5deaa,f09fa613,60bd3733,db8f7084,7d07d1a5,390325d0,27b05e18,d90e7659,f5ef4c8c,c7c6dd00,c7a5427,4ec91842) +,S(2ae0b70e,53536893,8a7faee5,da5d8dbe,e5af4873,32caf51d,7bade79f,eea50df2,e70be2e8,c8110c31,c3eb5e36,31dc5a5e,bebeb184,e6b9f081,bb7236dd,cadf903a) +,S(1c686fcb,d7a751b2,d420614b,56d37c8f,81c9a600,335fa911,835dad8a,7c663e24,4fe2eeae,7ea1b639,b893329a,a65bbfcd,b9fd8f07,28614bd8,6a5b0712,76aa576) +,S(b369d7e5,c31c9a56,f480b44b,3354be,84145c3,97dbed68,d87a4c3c,be31dc5c,50800690,17d31473,59bab021,c876d152,c17ea8e8,b5c95762,c749a2d,29adf3cb) +,S(522d3ac3,42a0ff3a,9a8eb5ba,54ed4dad,fbcdb48f,53bc6e1f,2c0c12a5,61cb1e9d,32ed883e,1e1f562a,50063d79,45075ad9,9ab55ba6,fdff0d58,9d2b4a4d,10df82fa) +,S(7d001803,7b722a7a,17d74696,fed9bbb5,f3d5f6f,d8a623b6,9c952a2e,f2be939e,81ee30e6,deb893d6,274c4b46,8533d845,38073ed8,68b101e9,515ebd84,70e368de) +,S(c76b074b,b228dc24,1dc9b704,75fcc52d,a3f3bf0a,5e954910,ca4e6f16,bd298983,4fcc807b,4c1e37cb,6a6c42da,b939a7bb,6f1d5ec2,87320d74,408622fa,ece22266) +,S(8497f267,99c7f525,83c620f6,e284a9a0,35130556,9d7caa1a,f118de41,c51b05e4,3b861f56,16ce6234,c6847273,16bfa629,7cac9d5,ff562f66,24b26146,413960d1) +,S(ddb10ff0,a217ab76,241a587a,8cd46cdf,ce6ff5ae,e39d2d85,7f47eeb7,6d2bd68e,a4110196,fd0813ea,19846dc7,12537cb6,8faf9333,19e7e49b,553e523,f07b004f) +,S(47eb53da,455cbbb9,a8330e12,e0210d80,cc565661,348fec72,529390e2,a75b812e,88e4a8f,91ada187,5734dcf,42b85e2b,a3f5fc53,1f1c1df1,300c3d5f,e811fb70) +,S(eb0a8903,42fb2710,a4c7811e,78384918,dedea7a2,9bb7da46,e49211bd,95da1426,8d69a88b,d85e2edc,d8264cb6,c44d8218,1ce8946a,818c9d4a,6f757bf8,5817ac56) +,S(d400c8ef,655d3879,579ba4c,488c3e55,af5af95c,1701bd15,482b2549,9334906d,e7bafda2,5a9f5934,6bcec6e2,a9408f18,e81b76f9,7a9d721f,496c27f6,42725e5c) +,S(bae81c3d,1772e104,66625f8b,ef08d4a4,5f07892c,72bcee05,fb7e382,2a6261fc,4ce5f14f,74f28b03,34a6cc64,452b9049,8460493f,3b64d9be,2ecf98ef,c0270377) +,S(7f575b9b,46bd0f74,555a363c,d80122c4,232e8c53,a6624d8,e13b5c06,74986961,edc0ffd5,952fd4d3,c752271b,7cdfaf3b,4cefecd8,66d722f0,3da1e97b,49aaa080) +,S(a86871d9,1292f7fa,7249ee8,e77270fe,e7bddafd,3255b4a1,16851ae,411293f3,c21ee1b0,bd897d82,566cf438,b66439dd,3dfab0ec,3c7a4038,ccb86039,3b0b0187) +,S(c320cfdf,9cbc6579,8c8b33c4,d97d690b,64ae90c9,a5070646,8c8791e9,1ee4a18a,8f1a295b,2a3c8c5c,3b5bd8ce,e3380a04,819a8658,7be87d03,73a0194c,fafac74b) +,S(169a1b4,f2eacec2,be263ced,2e0576b4,ae77b863,525b2a9f,f8fc05d2,c07a8fc4,7703f867,d997a2ca,bb697f87,b97ea986,78777183,aea81417,1dd0946,309e77c) +,S(218de686,ed51588b,1307d8b6,54f7f6fc,e673cb37,553d23b7,b8c23367,d6b7ea5f,98325ea9,150a100a,f5d2af49,2fa25b23,40ee9606,1553c3d7,edd4d870,5288b8cf) +,S(c7c2e438,d12ed0ac,6363564,8bf2899c,d1b39b1b,200ffeda,4ef9cae0,5d8381e5,93a36085,fd09ff08,b83d50a8,3b140edd,a63e2442,e4bf4d1c,7ae44963,c1646f41) +,S(12e834e5,605d6e35,8cbe550b,8fe917dc,59194c58,66b265cc,50b00e3c,38fe058,6a44ecf2,17f46865,2e0991b7,df3b3565,444e7e29,3a2d6378,61a8f3c1,5ec1517e) +,S(30f33c39,af77735c,749fd328,e228ed67,bd625fbe,79dc3b06,ab31c173,777308fe,29a00f66,1c998f1d,bd62935e,44794420,7ffd7b1c,24f63806,9206e1c6,5c3d9604) +,S(c5bd81b6,b057e687,19c47964,d55ab996,6c7ea99b,25c1c2cb,50d6fbd9,af492358,5a6b1332,8562599e,e87c475a,1e7da886,c460ec67,ad81372a,7ed39498,41225e5e) +,S(1fd0e769,9d931a80,dbcfaf1,46b5cebe,b9547f8b,b7fa75fd,b2bac9ae,ac0908ab,11770838,88607506,bad87ba6,38c9ae26,d79a9dc6,6746816a,b9f21d64,fea96838) +,S(ac14a06a,4679e9af,b2ea3aea,15f2749,bc9610a3,b576a506,f96fa41a,76df97de,5aafae08,5b8a0a7d,48ebb339,f4dec906,21bf5162,dcb85100,eb7524e3,a65a4921) +,S(ad583074,13a4eba9,ceecba6b,c568bfbb,30566031,c06e8e97,5c5d992b,9ed2bd33,c2bda9bf,d5c87e0f,a663a40,34162dcb,29b61800,c1dcf02a,c11fe615,25af1772) +,S(5a8bd45d,6fd468dd,41ecafd5,aa072227,6d0176be,81b92061,b4277b73,32acfaab,878a8d5f,7903d74f,6abe28f8,d94d4767,3698a7e,6acbc32d,9e92f9d6,bf31c2d5) +,S(6690c9c1,d9666be4,56d3540a,6a2ed706,372256f0,43265478,7b54e56d,f28df74a,7ad591,23772578,999c90c1,24704c13,a7193b62,64240aef,63d12d88,340762a4) +,S(3c051303,c113779a,6137f46d,38d1175d,8778e460,8b1e0abb,f7bc4539,80b64a2f,9d4d04a0,ad1c772b,4a523c13,cc48990,c733eb87,993cdbaf,61dbf75c,4f6a96c2) +,S(1fdff503,66319168,f5dc381e,8085ac92,223b3484,a8b362c2,26d1f00c,976f9f04,5cb328e8,56aaeb05,62017bf8,65da44b2,94ad7404,df11e117,8426b79c,25a49fa6) +,S(ae83da7,52ec2098,a4a593ac,f99dd58f,cd48da14,361feaae,6cd992d3,96b4fd8e,6dc92b41,f1e1474b,a259e96b,ec4f2b36,108745b9,a500ad9a,edd9c828,4c3d129) +,S(c0f86e7a,6c0fee54,a2f73d2b,6b1522e9,fee994cb,d5089886,d98a4748,161811d7,4aea0b92,2441c184,c347243e,5ad5a064,ba00768d,52d7153,a5e0838f,f497d551) +,S(8e5b23f8,85d683a6,a6a657ed,d2d2f403,1320d4c0,83340126,d2958dc2,4c5f5ba2,25c6db80,477f37e0,ed6c6e3c,c96b1c7c,f9a7ca16,8e940e8a,b2946c7,3b02e61f) +,S(6672b4db,bb16c672,2592c239,7d9ea25e,f081d48d,aeb42c89,ae6c42bb,af09b3c5,a3778252,e239ae3a,f64e3b91,7f646181,4f71753d,b4bc958c,b5bcd3ba,4b5b1a4e) +,S(e0af1a1,b894fe1c,1f7de814,1a393a3f,b12b31e3,fcbd8f2a,356e61f4,402d76d0,37913973,b4de9a2d,23f4f795,709fe825,8eee8aee,afec5996,83d924e7,21fb9b0e) +,S(94355dd3,c3d73a1,cabdbe7a,295cb015,335a5a79,dd301718,10c245b3,d0c840ff,31e96abe,22a16033,56681d3e,e5e8330,628d8090,bfdcb925,79074cb6,82845475) +,S(fc340c8d,1e3e2849,1470dfcd,1c2fb445,e807e1a3,9c525ce8,141b292c,596d2e36,738e7213,7580eb3,615b7eed,9b069cd2,b644447,24696a,7cd22257,7a931464) +,S(c0c4e03,61d923fc,4201872a,1ff525c6,1697412a,7bea7a92,596e9204,f1af90c3,25c4c2c6,d6593ef7,ff5f04fa,a5b0b2ca,736ab33f,5c36dc63,433821b5,382fc4b2) +,S(81afd4a8,d666b97f,dcdf0d36,f2dfdf7,bf7c3322,69728b75,26dcb3aa,df51365c,b7fe7653,2c8d48fb,8c3d0382,68d57839,edf80cb5,732ae303,5c1b51c7,cb8d3efc) +,S(140b32fa,62130c2f,1d49e39d,15f9c64,f5cf54af,3a0c65b2,298e91e3,21b9477d,bac2aca4,c96d4363,12107b2d,8996875e,6772eaea,a5070920,39c1171b,9113b516) +,S(17418ab7,46f1eaa,b98725ab,68bca72b,9cc645d9,cbe0835e,4bf91a7b,3939b98,dc964031,b1292c03,117a4ce8,b3341e23,da54a539,fdd31126,41706257,bb9382b6) +,S(8f0222bb,6cbf7491,12b95780,b50077d7,be2a27ec,5bb6dab4,923cf36d,3a12618d,8df2a149,abcd276,31265890,471094cc,fe6bd8ed,b75c2364,6f7dd54e,30c4c6fb) +,S(e3965324,1c543ba1,2d0ca0ad,88c26ace,b265f42a,41d2b7d4,f252ecf0,a48275d0,44467da5,18786654,5722fa15,36c187a6,f67f2e8f,5a424336,b0ce8bbc,a53f9cca) +,S(6a4b614c,41c4a6d4,ba4f8c53,26d08bc4,ecbc72cd,d2415c3,b7caf285,acb07c1d,76dd92d6,3f85e1dd,685faa18,283f8667,2425de4c,95a7985a,cf5f74c2,7b29b576) +,S(afdd252f,82037cb1,928d896,74f3ff64,57b94412,b563a4e0,1a32cf2d,1afde412,d57f319,300a6f93,1155b0b8,3dd83a5e,d2b4a0e0,5d58786a,8024627b,73360609) +,S(65adaf88,4297a087,6ec0d433,ea82bd5b,9e3590c4,921fc2ef,d1fa0b12,cc74808,30e4ac9,77b97c4d,b7516c02,df65de7c,d9e8ae08,6146716c,3da4b26b,eca17033) +,S(eba0dd63,c667395a,9e9eda33,93f5d101,8462b957,1aae6a09,cb723e2d,a45704e7,8314c569,49b7c144,197647da,baf857ca,a164e385,62c1cf46,bb30e7a7,a8dcb680) +,S(d3341d4f,1f967f0f,10932a5,351c6c22,c748af09,1d547cc,2766e6f3,1a9f570c,9694fb83,74177e3d,80775206,f58b2e12,32b87c9a,21f060ec,19152435,45502951) +,S(1596b717,8dceadc1,b5f3a5de,89c089f,62506b6e,2c6e49a7,f1cc4a11,e502079f,97157538,2aba92cd,8f009de0,9dc143c8,51b0f3ea,31067381,48a34858,8c085d49) +,S(138c0bbb,17c63e1a,a3e65b50,3c602d8c,74178847,8dc2bcce,65b84cfc,95f7ec41,bdf88a3e,34f69fc2,415fb95d,a4b6d3b7,f159651f,36a2d4e0,b4063e5a,ee86dafb) +,S(7d99662d,e6274432,65ab2842,a4ed79be,480404b3,1b847c01,c557e277,ee073176,e2ceda2,bada9b63,ff2fc022,44124d3c,b83dd4d1,f3fb74b2,763ecdb6,46e4cbf0) +,S(9e3f4ea0,b1db451b,7d713eae,35802229,fabbbfd,6f6d0ab0,af7483a5,37992e63,a9023199,10301c3d,78933143,b54e87d4,1419524b,16c9c00c,5550fafd,e6be8b65) +,S(108c8cda,d6ffc3d,b0863a66,43f0a4bb,efcdb0c7,202f630f,f971a7ce,dec3ff40,847ab4b9,8fba1fbd,15f6bb2a,4b3d1038,726c2d66,f4c9b8e9,f740af8f,5067d95f) +,S(5258a6a,7c85d4f3,e650f0e5,1e2d8254,8a768c0a,f276da55,27ab0050,6e97e710,e5605a14,31c8941e,4f2aa3c7,9ab94e3f,ffed156e,ba2159a2,7fde377e,e2ea7e26) +,S(c40820e7,f46acad2,5bffcc6d,745aa3e,7036f26a,b6ae85f0,e3cb8f95,29dc3f3,6ddf9217,88249ac7,6ac2c9b0,1dc5e62e,91587d15,c76fe26d,6d7c3b2f,feaf3b12) +,S(c135f50f,160d04e,43148abf,d76509c4,e55aadc7,554e4ea5,823e013e,a0490da7,f9a597a6,b26a1485,a7d5a91d,486d099,93de9a4,6484edc8,72f8f4be,710aae69) +,S(484be5a8,b903230f,991c3118,38d3ebdd,9759f5cb,11a9d0a3,9bb11a03,3924268,18f80a36,a3d70e67,5bd65253,a1ad3e40,a3152d55,c1141315,57f8585e,315ba462) +,S(af67562e,998a4032,77fc5827,cf222258,cb2f23a7,4dcd0d4b,315564c3,eb66da9c,dd5bf89e,c9b2c178,6adea201,d36f3a66,771b3f2a,cfba7acb,c30024fb,fa73ad6f) +,S(38dd6cd,475f2808,938d92be,8ad0c955,f3cf3255,c3602b99,3c177e06,553af411,1abcdd02,d82cc0f,680362bb,f898bf89,304d681b,6bc3afcf,65454ab5,8d44214) +,S(ee37f0ab,3db1f9b3,2da0031d,48f53766,3530b68a,f47bdb87,679426b0,d90fa6d5,6cdb12d8,136fc9c6,2f025cbe,7882ef21,4e7b09dc,9fba4cf9,b021c4d6,610c0397) +,S(670684dd,fcc19f15,ba9201b,ca36d143,47dabf31,bad07e8d,68e6fbd,2630a98e,77bd28ff,a9699737,1304d4f,82d29d1f,a69dc123,6f2ee438,cffe3f2d,358ce706) +,S(1654f447,78026345,64e3608,bb29004a,812ea39a,d96830f6,66a92f5c,54a79359,11d91962,3f81fda0,36d2d021,607d9750,cbd30359,83c4f47a,21fc8116,ca93cbe9) +,S(ccf0a89d,429a0274,7b000326,d62825ec,6978f24e,8f92f490,e8cab1ab,ff90bfa1,5f047694,375222bd,5968dbcf,a331db73,85b4df25,72791c53,42c62467,3d84400d) +,S(45d36700,32ab11c7,897d648,67ed4d03,a9504461,bf28f3df,7e1276fe,4c1de796,67e837fb,37108844,2338086a,d1506453,ed1f37ff,fb14e617,93908c7c,2a8e6fa4) +,S(9af3b6e1,627a2ffb,c18ddf33,b668fece,bbe7ebe0,986df82f,1b2fdfa1,56dbc565,55e9562e,882f6629,1eae4c6b,5a82b0b,b5bc2cb2,b8f884bc,3e45a126,aeee19e0) +,S(ecfe9d5e,d3b9fe15,c320e05c,7e0f3b1a,5fdaa9a4,5e1ff99f,88012642,a5d45b4a,b3cc1fd0,e0117151,f53ec671,e1d207ad,5f2b0755,8956cf28,2be5228d,db5d48bb) +,S(6e482326,6ef64478,dfa30c6c,f3a951f9,fd9d3108,dbe80e5d,3cbf2217,70f5483c,97a3f599,906b1738,372212da,80309562,d3d4179d,d2abc2b6,41ef2f4e,6561095e) +,S(3de89149,f6c939cc,5419e4ba,f0baa93a,390f01a3,4ad0fb7b,3b170e54,60a380c6,e9a07758,1c4617c0,b996ae3f,b250b723,874b66fb,85a6d826,cc5826e5,bb068491) +,S(d4d28193,53ace188,703643d3,84622505,d9020459,a600349e,69016cf4,faed2e25,9a494bcf,e15bcdb0,97513682,ef09890a,424d6bc1,ad1cb73f,123ff5f6,7babb364) +,S(f694a819,fd0f2035,1193eba,c18e2db7,9c219191,2bfcc60b,6af8e067,2281095a,d80d1652,1e43f18a,4b663898,bfce8670,6f53436d,a30b0663,9ee6f99e,ca87e667) +,S(af8595b8,8de7c459,7d1d1614,ac897de0,5dd9ff05,593dd3b6,cbac81ce,d2e1fb5d,e9dcce9c,83ee7217,857d5ca5,a48bb720,69d467b6,897be9ac,658dfbef,3d40e6a6) +,S(df4177f6,a7deccf4,c618b710,b096bb4e,b310e4e2,470b5795,6a633154,8ae8123e,3638e20,5d42ebc6,7184e567,c177f479,18fbf9b1,e4f69435,487b289c,35c7fedf) +,S(ef50482,30344ae2,70ec6d30,f4daea23,ce7b64bd,b101638b,5a52ff3d,6dbe9fd3,a6eec78f,e38a2e6f,a9c062bd,4ce28dde,c5d25fd5,a3204281,ae30d79d,99a2658d) +,S(f89596f3,ddd57abe,3344080c,a6d85d0c,492261ca,7a698aad,ae00dafc,75615954,f8d7d2eb,45dc2b9e,a0979550,8d9da016,20b53a19,b4150ca6,36bf0f86,ab3dc0dc) +,S(a7c2ffd7,50b99bde,92ac1419,57d8df27,56ca49e9,3f4c7434,b24899f1,24fb3cc5,a1672ade,aadad853,47d1440,d573e3dc,91987d6d,ce55c67d,665402d5,f8b0a289) +,S(463f5f25,b5c63801,a6b1accc,6662e6de,5256fce7,37e1c875,2b4a880f,19ceeee9,858e4a68,39eb48a7,f1a7de4a,514fdb46,1f4203c2,65e308d0,3fb9770f,1f8f13e5) +,S(4c99bf38,57073c27,cc92314c,f260dbf9,e0f4bb7d,1a5ffadd,a808783d,3bb602b8,aa107422,ac7dbbbb,f6e8064d,22a5526a,96bcbca9,9dbaac33,c1f35b2f,c6df568f) +,S(f6825035,64438569,aa7a5a4b,e2468453,8d8bfb88,f7e983d5,33ebffd,f8588520,84ff2ce6,9d79938d,fd910bf0,25a2fe8d,e6013c03,74784b73,168049e,c851cf15) +,S(62ea02ca,16b2e528,2f913a,36463494,c00df046,8afbeb34,cc9573,b71577fc,36be98bd,2c83e8cf,e0fc1aad,98ffd9e2,9ccbad8f,a25b9da8,23de20fb,fe91f9b3) +,S(ea34600a,7591c57,d0a7e351,de6e6d0,2c72220,62a980cb,bcca8966,356a2984,25eccb4f,a6102f52,60e4c545,57aa960,b427e372,80c35b8,edad5f52,1bc93aca) +,S(5b76cc79,2e78f177,97b32c46,92f2eca5,1ae1b7be,a753ce98,8e58d116,6c667027,2e01ba25,799e1b9b,3416493e,3fe9fff2,c46e634c,2175a30d,7458429,3ea60b5e) +,S(62a52d8c,d8562624,48ce5315,28213ad0,6fc6044,b6490db7,c27b7662,bb66f07a,e8f5e0aa,aaa65c7c,2b51e665,f3b31157,54ab9fdc,ac492ee5,fbb2a348,d8db5376) +,S(a276992a,5e155e29,d091e05a,5f0513d9,ff2dfbee,6ec1ffd9,a91f55b9,bca641c1,3d480cf4,e3f6efda,6cea9cc9,d769b16c,d1f3d64,23aefe9a,abc82b8a,adb22e48) +,S(bdb5fd64,bc99741f,a2a672d4,a895aacc,98886a9a,d38a486d,ed1915f1,f0b515f,d9744595,ae6e1e64,5a52a094,75ad094e,6af9655f,185ab90c,c03262cd,39794f93) +,S(cd6c6829,9d2b1c60,9b70153a,45259261,91b9b9d0,9fcf0682,d312960c,c3f82c04,2178ce3f,1bc21a2f,7accf32a,b20d625a,182f8733,e460e8b9,e1067dfa,fee6b36e) +,S(ebbfa9e1,8a4107a2,475f99a8,672be581,f32426a2,d774acdb,efe501c0,af97a0f1,1845a5fd,d71baefa,64cdf1f,d1211158,a70752b3,adf2b4d4,b5bf1a9f,7a0abdf2) +,S(bd5af866,4d51256f,455a3190,88b754a5,34223135,1491f763,3e090bd6,27414fa6,f8b5bbf2,2154786a,29f75090,fca2e149,60f84b47,50ea8db,d7c309d2,52233f3c) +,S(34ef0b38,5a8e776f,1c3ff95a,5852027a,ab6d1da6,6201548a,fa181c81,55382b77,958180ce,9afc501f,84d4d3b4,eb556ca2,e6ae8dcf,f949db6d,33cca5e2,9b357280) +,S(4b5f6663,11e6956c,e186fe3,85f00069,c0dfbf67,e4130bda,64e0e89,1abaf471,a6cf3571,2e790d5f,b500324,773281c,43f6d008,f6578ab2,b48fe4de,1ce3b545) +,S(cb22489c,bac94ccc,887a1d7d,8836cacc,c8c2a43a,4e09595c,39cc6064,ca04546c,dced75ef,d7ee6ae0,18ff2690,9abc82ca,da74e823,c62e4268,606334e2,969bf94d) +,S(b069007c,4a50bfdd,38ebcbe4,31a952ae,5356d63a,9f4179b5,e4cda3f,fe478c42,bb90d5c8,e66c6194,ec55acc7,6dae5f0b,dd498746,2d24a265,c314e93d,618a0f41) +,S(18722ce2,9d9cf99a,e52a420e,23fd8e85,e1582d02,c520d4f1,16c2b82d,464091f9,9fe257cb,5cd5f644,183c8461,ac2dde6,94cc84e9,76d9c623,584a9d94,40fea12b) +,S(a1562afa,6420b34f,92a78951,e9ab1bd7,8772a181,636df487,81bf4bc0,b16bd196,ce4435e8,7105d006,9b353734,5a503e0f,a692d3a,8571e8b9,66d9a722,48ecbd1c) +,S(f466db58,b4fae060,b12b780b,df11c7e5,ea8a08cb,cc50e68b,f5d85926,b9f3cd97,c86b4153,45515a2c,9a831ff1,d6377a8c,cae62456,f207df2c,42a1e767,684f79a4) +,S(686a1d05,e2bfaac8,e31def35,21876c81,27be2ad1,34ef3dcf,6de52778,37278176,111404e1,7f2153ab,43597a74,be1c278a,998b3695,5f4d465f,271a6a46,8e9e8986) +,S(d8433d5f,e5ec423c,73bb3ec4,95d06cf5,3a77474c,1e97ff97,f72a0457,9a60926e,3df114d5,a9d63dad,ada0ec4f,f98cb8ce,f1ad419a,e2c23dc2,f24048b4,1879be1c) +,S(3a9a0aed,4581937f,fe49392f,488053df,349f0194,9666418f,16e56fcc,533cb73d,c9db1a90,2d6676da,251b4be9,7a643bdd,d55c2b15,95ce51b3,281cc866,40cb558b) +,S(b35a204a,28884708,3091abf3,34be3696,b1082fc7,5caeb0d5,18387aa2,711a4190,65f951c8,78232345,487e8e,376c22bc,e5d9e8d5,ac04ecbf,24cafef9,4de358f8) +,S(81ff6fec,11f48691,59a2d23b,b2a6a9b5,68c5e6c5,1df9905f,ff73e1cc,a2c505a,c7b794cc,d657519,fc05632e,33e23474,654f1344,6ef1b4aa,1a1da18b,4acc1e49) +,S(3588a9e1,7feaaca1,a62fcdfb,3952beba,43116167,bb238f10,a41fdfa9,bc316d8e,acb24c1a,58ed9a0b,9744fa76,df4742b9,b440347a,4b4446ea,a3e55234,102d4789) +,S(7eb13fdc,9588b724,e7cddaec,498a8b15,d57a49af,529c8c9a,cc8303b5,e81f91c0,89f6ac3f,38351f7d,e4b293e,f61a87a4,2c08a4a3,ae0c160a,563ae5af,dc62dcfd) +,S(2f68c6ef,b363459d,862710a0,a0ae67c4,afc3cc00,85f02e21,ca4d764,3c76e00a,f8be9930,3a3aa7e5,c50d3f53,9b88bfad,60f05fb0,1461d7a8,225bb21e,18616cd7) +,S(b11994c2,5e3e6d0d,917ac215,c5f39606,3b9b764b,5dfc2b75,ab8ef880,3b57d802,4a7ae35e,c525d91a,cfbdea6f,cc9afbc9,b3cc8c80,acb4385e,9bc20158,f9f2b55b) +,S(d8e7881a,e1e4d04,c431c097,25dd4cd9,b4efb4c4,3896256b,7de47fc6,3a3b30bf,ccaf57cc,138f0bbf,5dbde16e,91d14875,c0d5ea,3842e864,be8de17d,875fef67) +,S(88e02abf,a37ffc97,f564cf3d,8a086c8a,62c05720,802319a2,30ab7cfe,b448c478,ec2d3169,15dd0c2d,6f03f851,97a96f9a,6c0772ee,df0c4524,c08f58f2,39c89308) +,S(ad258ffc,b42d127e,a875b181,a8883a5,31d18a64,d75a6dd4,4111d697,90752d1f,acf5ad9d,bfbb14cf,a25748e3,96bf23eb,aefe1bab,6550b234,90ca0278,276e9db4) +,S(a2bfdb6d,38159e5a,604d564e,af29cf09,a0a8ac79,1aef5a63,e1c05da5,fb6a0c39,7a45c5c,a7ee7c0e,74c05914,1e3d898f,ab62a8c7,31ca0a66,a937ef55,51dad999) +,S(7c7bb792,ef21cd53,bcf33a82,6a1ebf93,e9f3357,51131f9b,36f659d9,594f453d,bc98b32e,173d91ca,e9daf137,766c5ca5,6e0434f0,e2eb070e,7fa7f8b2,e7364635) +,S(40a2000c,dc0c1c9e,4c037a3f,3113b48,f26730ce,11e03b1f,d2f07217,7816f8c,1966929f,210afe16,9daee99b,7b48eef7,27e1703c,8bf42006,922c0496,888b690a) +,S(6427d169,cfd7e9fc,1b310f68,e3371720,28c17dd7,c6d5a32f,4ed6d41a,634f3f1a,b1a71fdc,6a030ca3,d7dc2ce9,27f3b9b3,ca7169f5,2fdecba4,bc85e32b,4e52fcff) +,S(723013b4,24fd897a,1e8ab77d,ee0618c9,3c832117,94f8b822,9d7a9e51,1ba8194f,21acfca6,e5e0cc31,479e5a97,17494692,9134f2e6,ebcef2ac,c7779251,77e9aede) +,S(1b18b7a5,43a284b8,3165bfa8,ca947da5,376fc4a0,8f4070e0,a20aa905,fd12acb9,713ab4fd,9e0bab6c,aadd2f63,1c5ef168,7cae85e7,6146319e,94b19a1e,f6a69584) +,S(65e5990a,4700f51c,9d3e61d4,26c92f88,5506817c,d4d60c66,a341cf91,9646ff81,2ebdd818,f69cd135,1405c63a,7160ad4f,17a6a7e2,d4353db4,7b554eab,3e737819) +,S(eb131661,eb78d37f,92a851f4,506c43b5,1f2a155a,dac7eee3,b1dbc29b,a0b1250c,45f2f418,47d2258c,3f78a2d2,794e9aa8,eab23395,8debf0e,b1440d56,dc728334) +,S(f20aaa98,ab7d6f1,d6de080e,ecd0bd28,b14cac9e,7f27c931,5576b039,16777203,4d0dc753,84c942d9,347f007d,543bc399,ee01e84,7625d5c1,a57cdd67,79c4dfba) +,S(9994a963,ef21ca0e,9657cbcb,3da57f3f,e28ce389,60ae5dd2,812b2949,96969047,93d75bb1,35572b75,4801509e,5b64858b,c0a415e0,3968efe4,2e558786,8516362b) +,S(4696ef39,95e5818f,d7894737,2fd68c75,fbb455fa,8477863b,b2687fca,fc2cd7b5,1cdc53f1,c52112c2,f58a6f66,7c1e4e9,110d83f9,d765347e,a724c784,d8e5d5ee) +,S(7b052f1f,e1af9537,ab3bb5b,3e0e510f,7e101cf0,999f85be,c403fd62,53e68d25,69c7f158,4b6c36c,f7d881a0,fe4efa5e,3f879753,641ce0f4,3e73bfe4,77ada27c) +,S(99452d74,3311867d,1d86c1b1,decd1ed4,7192a58b,3ef98cf0,7816823b,1296abc9,ffabb50d,a1a0451d,36b811ab,5e0c55d8,751a1851,3ca8bca4,8d6b3ffc,61ba36e3) +,S(40c6fec6,5ded4688,31f72de9,fb5c7f67,32c0c170,29f19b36,b00b0f85,5a12424,17aa0baa,eb3ba6e4,c5000e96,c3eb620d,ce1dfd81,b35a3e79,b27b8246,97dd5741) +,S(b9bd9e2f,c55ce5dc,2e46e4df,56401c72,e01ac3d5,201a3cbb,a6609fef,ae2e827b,f545efa7,f95e9a60,72cb9750,6f929b4c,e0360c8f,a9f058e6,5b87bd55,a72abdcf) +,S(867c0fa9,f885935,2756e3e4,11666eb2,59a416b4,7c2ff329,e30be462,13178921,6fdda875,4a50ee1b,d229d4f0,fa8876d6,9caf9fb2,a6af19fd,dbbd2a81,5dae486b) +,S(1cbe8374,3decb58f,f2fc9668,7ba45c64,812507ec,c2f71d66,eeea12c2,92fb36cb,799533ce,46d2c091,d0b553b5,18c82317,f516049c,4a4f50be,909c875e,b0bbe21b) +,S(c654f9fd,57426248,fd24097,2595d71d,80cf771f,cabed8d4,63bdda8,340398cd,898e9224,c9e94d14,3f96702d,c296bf50,9b2cee37,da574bdf,b7c09cec,18357a18) +,S(49e8e14f,4a9f09ff,48725eda,85ecae6c,3fe3400b,81012e00,991f6a69,2d75083c,815230c9,284924fa,57d08944,2a30c61b,8ce19644,7a8ede69,fb645864,ef35977f) +,S(43a6ecde,ed83f1fa,8946f584,99e71bd9,978f610,b46d1613,c15fcfc0,f79786af,2995f70c,11eb448e,68eb3d10,c84b36cd,7605e249,1df1fa3,2e9eb57c,c0275482) +,S(96861d91,678e5004,7c491950,5bbfc70a,e342c3d2,361729b0,4d0bcb5f,d93eceb5,6845ec37,9bee6269,464b2e9f,156ada30,c518bb8e,105153e1,c3b3e948,d38078e7) +,S(3c72be53,c9f82add,504a1955,7b9560a1,7716a058,26063408,79aca60,c55f4515,e584b72b,cc4744d9,6a00dc44,b03ba61f,c2269731,a8178755,2a6dce8,25d31b81) +,S(ce4b4d07,deae1fad,33192544,448ac5b2,77ba7f70,27b81a08,d7f84581,4f71787b,2013299b,2c744a5b,da6b243c,d04d95b7,e515848c,dc28eb40,892d40c,210bd1b2) +,S(37984db1,6d288866,78e1804b,9c94ebf8,f3a1aa05,1fefce96,65712f98,198ce116,20a25966,8ed14a5f,fc3aac09,6d2351b3,b6cb19ab,da4c833b,4a2a6c68,55d1ce59) +,S(ac01bcf,b02e627b,2c9c931c,f87beb2f,4ad7328f,9caf627a,2bf695ed,b7353acd,be4eacf4,77c92348,fe0feea9,3075e93b,bb3633c6,6747524a,e387df82,176ea252) +,S(d5d6af83,1a81b72f,efe5618b,ea43335,bf1d81f1,73382fda,860260d8,1a2faa83,865f9ee,4ff0fc6b,fa761709,db4c67ee,a3213d07,21b2facd,fcd8fa57,8945698f) +,S(3c16399c,4de35853,a6dac8c1,8eea4b40,92a22a8d,5e69ed0c,13b9c2a4,3cd5e39c,bffc2dbc,c2ce4b04,6a92b967,d1a04b5a,2fe40be0,fd9930d0,45b51f8a,15b53edf) +,S(f67018d4,23e50a73,68045b0d,ce803e35,a26d9a5c,288a3a7c,c25ebb03,dad28187,ee97afc5,1c73531f,ea8998f5,53086a59,cc67c6db,955baaa2,8f57153c,afc4e772) +,S(de67026,529a32fa,b3ae79f6,ef9ece7a,47008d2,46f89053,e9339c4c,dcb53b30,4daa8700,4b055005,90611f78,43d258b9,516f1fe8,61cf06ca,d466e000,d3a68783) +,S(a133627c,af6e7ed3,1d267608,19b69f45,7e75ecae,2169284a,48b5ee16,b5dc8c10,755ef12a,fb5c071a,36dbe2b7,1f858d87,31c93d81,d271c999,8f632982,d7e97ce6) +,S(d255c1e7,ccc88c4c,33887c9c,b9c15a2b,52b08471,90ad1420,5fb5909e,d36059c7,83e3e1ca,99a386e8,4b119391,2c20593c,f9573996,d42cb7c3,6db24a5f,cb413080) +,S(aca6c69b,9ea17803,4af67422,71b8062f,77e6dbe5,1df2a570,65fb3057,ea185b8c,40cb09f2,adef414c,816b22f8,d7a59f8c,f5197fb9,b31614d9,ac172436,d0f54647) +,S(fbc19c84,3b656fcb,21d99c3,5289d3e3,2bc58fdb,c2404309,a9d8831a,f2365f24,cc22999f,203a4fae,59eac72c,28bed6d9,291f204b,707bffca,ca6d8359,1e403124) +,S(ea308c88,c366677d,5e575457,cd3e6978,5b491a02,c542dcae,5dd5e149,2f839c55,c1916831,2f48555f,b80845fc,ba89eee7,a7967807,d10c6f6e,b516c190,94873ac9) +,S(d911d62a,33fefc48,abfd4409,7ee2d32f,d7e85816,2a8a00d1,342646ac,8dda6cd2,f160f933,41bb32f7,401d153b,4a2decf8,b793fb5b,4d5520c9,6d9cb9e,cba79aa3) +,S(bb75b497,7d698442,7b0ac74b,939ab3d8,fb94304f,602e102,1fdacf22,27022a4e,ee3cc171,8e9190df,9b45d8d3,54eeef9e,11639423,dc091128,ae09e451,fffe3468) +,S(358e7639,b4031852,b983b5c0,a6c0d33e,5edb304a,3f8bd15c,35d35794,e2cf90f0,5da4be1d,2e9bef5a,5da3cc59,d3c4f85a,e6624ee3,17395ded,398147a,12c56c45) +,S(e098fb9c,440a5cdf,bc570270,4b57eeed,f3087b7,e196522e,4b194618,f3c874fe,9a5b80e6,b22dd111,1f824c36,4830e723,18b7825e,2f2a0fe6,ca460d0c,34eb6449) +,S(62d607b2,d1a16e4e,cf60480a,be9416a7,15d70b5c,56734e7d,1498ba03,7632528e,70c5f4d1,4f5c900a,96291a4e,d0f795ff,439d35d5,2c5bddd2,ab10571b,1d7d20c2) +,S(a630c5bd,ec76f869,40842391,cba6cdfb,9109940b,e1034b87,c6a1e5e6,9662857c,8f28f55e,beed2883,3e347b10,92ff8938,133558c3,bfeac1f6,a6b938a4,c783b79f) +,S(e2a164aa,e17cb0c4,8ae1e911,872b0b3a,7c0e29f0,93cd5e18,97145211,d72147b,23ccf99c,afd1bfbf,a7ce1ade,1590d609,9a423b26,381f5761,c19ba373,290e6193) +,S(742526f5,b95051cf,2ee34994,8385fa72,425162e7,e46bba3,febe5ce8,595a8b37,d106a3be,638987e6,870acf8d,26d4f78c,e6aa0e9b,63e4eb19,114fc97a,eee3a12f) +,S(ce7837c2,31c32444,10dcc790,de465c06,75404a1a,68d23fe9,b69d887e,9c554f45,2c0be877,20cfdb11,8c37b2de,a2c355,d12279da,58f75570,7e738867,146257a3) +,S(601167cb,2788b146,998f0b91,d582cbd,27f4b866,40db7ec6,7f26214,f3ab9212,50525e40,1f2da57d,1f605f34,8f11ac23,19ad1827,41d7be11,46538e83,e03bbeeb) +,S(d2f657da,6f7c3c80,9d2e5291,b1161d46,393009ce,e2bd22ae,32b99eed,f76fc728,6df58d32,b795b6de,2a9c3b15,f4f1dc9,4e6e6757,e01891e2,79acde59,d13e3e75) +,S(e9fb6b74,f84973fe,7c7a0924,e0133b92,bb4c22d1,ce9a94e8,433f0c72,2a86e00d,f4df6cd9,df43c150,9d4b9580,eb87298a,551ebec5,2438597c,87dd46d4,3a8ad2c4) +,S(98d46b64,e43f3384,88c63da7,35af1141,e8b41981,b706ac5a,7aa1c0ac,1182afd3,3b2ce203,5bbd2cd7,f3206b3b,6aa3ac68,31e0e2d4,7f9e57f2,3e780fc9,cf865733) +,S(b358a4c6,a7130b1e,a00d8403,7164e68f,c6cf96ea,c6580ee5,b1cc2452,8d2bb5b,3bbb25ab,4645c17a,2a6f7e64,2d3952eb,86462564,5647abd1,2e80d965,be1d3854) +,S(fd8807c6,c456582e,d03114a6,2b42316d,4d0d386a,aee634cb,d33f2f82,c1ad6f05,c67d1611,e45c57d6,1f8d721c,437c0ca2,189488bc,f363aab0,f25314b0,14f896) +,S(cd53fa2a,1f989ceb,cedfb7a5,237addfb,2efe9469,8b6509c9,3081710b,f0db107a,47e61ca6,4d26e617,8192e993,411d0540,bf7c37b5,8c748eb7,6c1c197c,87c3f844) +,S(38cfdfb1,1b60a68,b00a4096,8f2da5e4,4a60868b,de9af728,fcb888b4,9a098c66,65f4f191,92667492,d717cfbe,bafd0076,59c08392,30da216c,315f2cfa,d3725184) +,S(cc179d39,1c6ab4f3,7fae6380,35886e2f,82038bca,768d1396,13fae8df,a167a271,a12fff68,84a967e6,fdd6e14b,4083c0ba,2a2bcf49,f7d6071,d708c70,4722b1f3) +,S(cdd61b33,75fd00cf,430d9d54,202c5c61,465fe7c0,a3f51660,ce74a3bc,58068c,46e5334d,bad31f3f,6c4bccbc,6812cf13,5c039a5d,d51c6516,49564f45,45f13ab) +,S(39ecf8d5,4fa9c3b,fef7d5e6,5ebe0e75,288f17df,4b33036b,d034be2d,fa5bdbbd,21991cec,ef62e421,70da3bf9,8b2f9bd7,790d5b13,25159727,a53a0735,5ab1d956) +,S(7b621836,342994d2,3185da8,67d47e69,a67a184e,925a3,524f5e7b,63639263,b08c269a,1569538e,653f2beb,3e6e348d,c61537e0,7afc5f13,f56d1f74,518b274e) +,S(28e5ec3b,38359a6e,7d3a965a,c5713365,44b91ea5,c9f350bc,d315c153,72133bb4,5bdc5a02,62734535,8621c1f1,492b3434,be731c25,f82c1a32,163ecf09,7f548465) +,S(37ac3ac2,3f6b2a1,a3a5a99c,707a6b8d,5f05e80,133ac522,107ae5ff,414d33c7,460c947e,76eb51c8,42bd0e6,6ccc0937,87f61bc3,554538b4,c2065fdd,533d0b02) +,S(275f5ef2,a4546ba0,9d96d138,e698cd32,78cf27f3,2ee297a,5ff8dd41,f16bea50,ca91a3b8,5b0a493c,a49168b4,c9eff873,66212b9a,c030fe6d,a9be42b7,45d0464a) +,S(6c43669f,a69bd51c,63cacca0,21c69bf7,9a94ef9f,3f0aaa92,3be9380,a6702e34,b416195a,1419771d,82fc2ce0,637cf5a,29823d1a,95614642,c93a979e,5ff3fff6) +,S(606c37c1,271b90f7,482e6ba1,81bd956c,44a44189,346bfa67,539c188,ac0eb61f,f6af64cd,3f04e30a,1b4a7019,c6caa84b,823bd00f,587eb58a,e190ef25,322154b0) +,S(e4136e15,b3fdf609,f779d0c0,70ce8521,2babc592,577361d0,47ada13a,2a83d43b,1af23c84,ad240ac8,50da2ec2,721531e7,18776ddc,5847edd8,b4d79d52,26e53125) +,S(a338d942,6ce420ac,c9fb29b9,cf572af0,72c0d144,46dc2c3c,75b9d5c9,f7fa244d,c88a4399,f6e3ef2c,619cd9d5,215d305d,3715b962,b02b29ca,231446cf,8ea7c40f) +,S(c454d1b2,6f77ad27,a168d032,fc1a73ca,fcc4aac3,ace31f2a,433599fa,7107fd9a,989b6091,ba2ec267,380c5139,47059d4d,2773109c,1afc21a4,3be54ea6,ad8f19ee) +,S(bbd7bd30,5bf1b36c,6cd6c180,2f41525d,75675d76,9352dc60,1a727931,ee6f40c8,3c3263d3,75bd412e,1d7f7d5e,72f73216,6415ef3,52d1fcf0,58e6c046,ceb46abc) +,S(acae6fb0,5d5b503,c2e3d841,19ce3bbe,1380b363,e5d8763d,3c520a3f,df39f7b6,6fab4b7b,daba880c,9167ae8f,5feb9aa4,3ca19f28,77ec5021,df36ac7,db730293) +,S(c9d4ba53,a44403b3,b06915f,6bd9bb43,4716a639,453797e,5b8e1cf5,abc78425,749cca45,6abc2a6a,4e970589,42cefba5,a2f55dc5,39bf4f3e,be5088cf,ae04bf70) +,S(3408e460,99f1a176,fd52f70,3c772f1d,a46d32db,246815d,a21826dc,c5657e61,a93bd344,de7afec8,2ea2842d,40fbcf60,732be8fb,738b8364,aaaab796,1e20974f) +,S(5e061a06,f97f61d1,5f66c3ff,17372621,4ce82af,3e606b4e,9f64fb62,e405376c,609064a0,bde996b2,d909e50f,726ed7be,b4698ec7,5e1c9c45,3ba18815,2915cb1) +,S(b12ca67f,739f4284,3a7adf58,d2a2f3ca,fd245ff4,b766793c,c79cdc31,45579113,b1deaf81,34f017f,b2bc20cd,da75fcb7,d219c353,98ee9887,612781a0,e3f3d1e5) +,S(95a72f2f,c241fa0f,c9500cea,d9cf069d,23820078,f61d4492,508d0fc4,34fc223d,832a3979,1fb9fd9b,79748643,64643bcb,b227c39a,e4cb5051,d136263c,293cd453) +,S(ab8ccb01,4b672660,b867e544,926749bf,7172a0f5,ac6317a1,a18b7d15,f039fc94,28471e3c,a2d6e77c,87700c4c,7e3df1e9,2fe91efc,77724df3,2f20ceba,1ba000fb) +,S(26131926,5261c0d3,ecfa9769,fa987347,1b9d4ebf,dccd830a,96bd160b,61b47278,dc9ab665,485133d2,59d7b604,5e1e4f52,9b099e9d,4db9f680,4935e712,f8402f66) +,S(87a4227d,2303f5c0,acace6e,96586b68,178dc65e,2c99583e,8e427ad7,167c4a65,5bce1d82,216355d6,5bbf33e0,9b3baec4,fb0befff,ebe48b24,cc01d454,7de6db8) +,S(a6576ea2,39af87ba,392a225f,bcec3045,8920b494,68c54ff3,92d2f509,519ce85f,deb950bb,6a767b3f,3603be36,6234480c,1851ae4b,1980f902,f8fec863,dfabde82) +,S(ed41c3a2,48285ad9,1642f6a6,feccdbb1,66298fa6,467b0ec0,ea256570,c8e343a4,dccf3578,aafbc34d,8ca5fb6c,b4482de,4b94dc65,a8d22845,ac800947,dc1042b8) +,S(227756ff,800f7eb5,4493181f,83050c32,9f27a35b,891a3bc1,ea5f0e89,b94e77e7,571c9345,e9e95238,3c7dc62,69aa0fff,46455825,a032f33a,154a89ed,e13a09c3) +,S(6f3b91f1,3f2d6787,454bc7a2,2ee780a2,3c251697,c0da9aa0,a03dcc3f,f03e2b0b,432b396f,c2dcd370,647eadde,ec058a01,53fac955,4b3f400c,435c4755,5e61afe8) +,S(aa79f0aa,767db1c0,3893c9c9,c75a1f8f,457f3f36,72c1d2ae,31e58658,a916fe5,4da2c69c,8033860c,14f8438b,8edf290c,5d02f2e5,153b68ed,fb945043,a6e6a1f0) +,S(48f2a720,df970127,2385a961,5a215d8a,3d41e0b4,ad439c9a,9d0453af,4699e527,11669dc9,26f70e96,e76178c5,7d698d05,b6e7da96,eef4e986,c4f6e6be,216f22ac) +,S(561d8010,a81a1191,3bb2436b,bbe0ce2a,6f1af6c6,fc064d57,59edaf45,c7f9781a,bfb2561,bc311bdd,707aee1f,af3d5c9d,faa9d564,a5121bae,9989665,b074f026) +,S(64d0fc68,6369a225,a15cefec,431fe434,1a424c78,85bdf2,51cccf53,9e266fed,694fdfa8,12f6bffd,b1c75baa,3b843d02,1b69cc8,20f2a8b8,69908a00,ac7050c) +,S(2b80d86d,341d05f6,218eb96c,fb227834,44bdcdf3,65cc3809,1bcba0ff,fa8b3d09,152eb516,2794fd0f,abf030cb,1968faa4,100e803c,e5b8046d,c36e3075,9317a8a5) +,S(62652ecc,daf7ff5,3aa255de,ecbcd653,7840a657,dd53e58a,514ec1bb,98c9b5b9,2a05c8cd,bcc4a512,1d2cafd0,6289fa14,178e91b5,b1fa1190,e4c7c13f,f50cef6c) +,S(f23fe7d7,69cd7bd8,5e0d97c5,4163e596,a0e7dce9,488e8f67,4ca6f3ca,81726ce0,eb1355f6,ecac2b79,dd299fce,c0f273fc,3767a3f3,3ac4777d,cb871a1a,99077e1c) +,S(91d4028d,1ea8e320,5718f427,b427c21f,4780a944,55ec46c4,2fb2a1cf,4772af1e,7a529f92,3756a212,24dcd316,bf9a3f6b,f5bfbc54,3b015c10,54ae51be,5c2e6b2) +,S(7a8fdf03,175969a7,80475dad,c43e5c66,fa75846f,63cfd62c,e82d2153,d185670a,b7b58ebb,fa0b2d3e,ec2a2638,accd965e,c7db6cf1,c847c1b7,9f0714b0,c1cf7dde) +,S(9d72d9af,5e9d7b2,7fb2b867,4aa35438,946c4ca9,eb9ea4be,e20b2eb5,e7cdb89,324214ce,d556acd2,3ac00175,f120d59e,50dc95e,96e6fda6,ff348bde,5ff7e701) +,S(33556ab7,bbf601ba,44dcb33e,aa5efc82,3c70f507,550f3d7c,22f4ba62,cf2d6bcb,a21d830f,233a657f,7857560f,c030f053,656aada8,f7812424,f38a2409,7505dcb7) +,S(e002b33d,93022868,60b39e1c,2820ad06,2063c344,bef98dec,3a9a0428,20e2c507,3133f829,1c81d970,f879d1eb,2128f21d,7540e135,31189576,191ac4bb,d83d99b7) +,S(9eeb1972,ffd49c0c,7982671c,59071b20,422a053e,394db993,8ef7b3d8,98795c5d,ae48763e,5ad78988,7a756827,4a17708f,8afdd8be,bc9c0316,73dd9485,319763c0) +,S(60f821e8,ad12907f,e445f049,141c7718,a495d1ea,3e39edbf,f0a73018,a5cb6854,6dc1b291,62b025ae,2a285e59,a5b406dd,927a743b,483454d1,20426fa7,50adb95d) +,S(5b8bcdc6,40f4a217,6d0661ef,f2ca5d6c,b1aa2069,557274c8,287fba59,dfd65a41,42ab52dc,cad04998,63e634db,ebaae018,c999eee4,c3cf05b9,4f18d218,23f21256) +,S(e764e748,4ec2a2ac,6843df3b,5316f29b,701b5191,778bda16,a23a20c1,69ed0cff,e1007e10,4ae52971,875bf7ea,9e9d9431,94c2e9b5,bc7b2844,7b7acded,de7d633c) +,S(37f0d948,48742a8b,e73ef1ad,495b88f,ea95f7ee,b343152d,85f9e442,771a22b4,bf960e80,467cf81,bc22380b,af2f57f0,d5938ccc,55f3f691,784be72,7fa68bb2) +,S(7ff13c43,7f2189a1,18b2095f,be268dfe,e1375a3d,f71e88b8,4cf5b94d,63b04612,10295e49,1f0a882e,aba663f8,f0202223,21c422d5,f3b453f4,8ab8bf4b,4319930a) +,S(74f6853e,f4a2d018,4cf113d7,62fe2a1c,33ff2729,5414a5bf,3f381989,551ceaa4,629f116d,37c1809,f4e2ecfd,19c2627,6deff6c5,b89249fc,d4f6e82e,58eeea79) +,S(d54d88bd,abdcc56,c1bb8cbf,cdaea6ac,16949256,f78d70f6,7a1416ba,b4cf51ce,996afb9c,5b36f588,812bad4,95c368da,f9e96035,4bb7dd1,3f457a6e,da159b59) +,S(a860ca66,3ecd7482,c862fac6,f6a7b0e5,f5f6bb26,ee950db9,2942fc89,4b6fbacf,3445137d,2047c17d,65b3cb88,8e1b0ba3,619db023,bd989a0d,c585a59d,14da7b9f) +,S(d794dc2,4e0e36fc,6f38fc8e,7a68cdac,8d547d42,b9667241,2dd7e6d2,c40f9aab,22a9a90c,10f1b80,e277be34,3c492125,24ebc477,1f838070,f2be48bf,cec3a7f5) +,S(7e28db65,2115f5a4,575293c3,d792fc97,9ea1adf9,dac468e4,60e5526f,6847657f,8025944c,16a12ac9,25e67f13,3835bcbd,33c338d6,824b1fba,f0ee001b,d79d66e3) +,S(d3f13a27,524f0c87,266f3d46,14d965a1,3865df67,5d20c5aa,99a4411c,dc6322c4,9a1025a3,845a4bc1,9f7cc175,9377c7f,e46ecaf7,53263433,baed836f,77e2e841) +,S(d845636c,db18d557,1759f6e6,bad6a60d,3a67141c,b0bfbbf9,33e628bf,8344c053,40de706,ef833427,80e5120b,ec6e61e4,a8a3726,32818317,729e60e6,3ab7e37) +,S(f40f53fb,c672573b,c020338b,71589d53,3709ac32,b38cb943,ed0ca0ff,e592e552,502145c,5f542a77,652a4ab7,d79791cd,e92f3e72,d9d0190a,2724e114,49b64e0b) +,S(2065a8bb,a0d61dde,921a0741,21ae5678,8766f712,bdb3c4c5,776af9e3,774120be,fd12cac4,a85d5b10,1aec6ee1,4b1301a9,950df948,86427be5,55f52736,3ca29847) +,S(a9b1e8dc,410466c2,df97cc8e,bbcb3af5,f981726c,2daf8803,ef06ef2f,a23e038f,b09dd4e2,77b1d10d,bfdd06e1,a42baf37,a5157017,ba026d98,fee13512,4a1c5419) +,S(c54ce1c,bbfa3808,f24b2661,793c3574,a58aeb0d,128d7e5b,ddcd98a6,d8c9bdbb,c1a2291f,d20e8a23,f4012b54,37a7be7d,5af5f776,bdbb2c53,193e07da,bc1a3212) +,S(41ad2d03,31f57724,6476d0c1,f2c46216,6156296d,8bfd3783,eec40892,835ec421,62777bb0,f8b6ba08,128f1727,9c237286,abc5d2a6,492b9c67,3edc903,7b0e3008) +,S(a8eddde5,eb761183,ef5cce4d,a7958b92,db28bab8,2f695fbb,597f6535,50048a3c,7f60d3aa,95ee5ae5,f4cf10ac,cb5729e2,bf89ba7,6b1070c7,ba385f41,a5912685) +,S(f1db8d40,2cee572f,6eb250bd,ed3d978b,1346ce96,d65291da,977b42cd,36bd073,9bdd0bdb,a546ce4d,774f79fc,3561c0fb,ca11f4fd,b46ab1c2,a7520913,f254f42c) +,S(55cee66c,7ebecc0c,7f22d03f,8f166b99,ec7b5e6a,776bcf60,b5f4d452,c861bfc7,772832cd,55b13c5,890c7ba9,96731ced,5a2e1c05,6ac89469,320c08f4,43159d36) +,S(61427868,7710db98,d4347d4c,aae4c70a,9efbfc7e,bfeffe5d,6f33bddc,4aeddedf,fe8b32bb,d0c7a7d3,b93dcb7a,99a5cc8f,e386bf89,7dcdcd86,ffaac641,6550dd85) +,S(9f3ac763,c117bd99,658f5379,119aa025,cd422ed3,b1ed2cc8,545d6f93,39baf4e4,41b2409d,cec0065e,4026e879,84b99d35,4eed93f4,15e8981,256e8734,a4eebb74) +,S(8510bf74,8f5255a1,8f408565,30f909d5,2bed111d,6347da9d,8da2a97e,751d4a98,2ed99b6,6af7cc01,37329730,1b0b63c9,f8732547,fc632eb7,7357e67e,df5549b4) +,S(d81fc0cf,9646ae0,7dad1a3f,e06adaf,1d3508fb,13af2309,c200c2e1,2228807d,cac833d6,c94e674c,a7aec186,42e4a501,ffbfed92,dfa1015e,c95740e6,57978cd5) +,S(32aa5e70,972a899e,e25e6c6d,e43c32ee,df07ebcf,e5ed13e,5095f7c3,3bb55622,38e82901,990a1e42,38639a42,66a93fb5,4368df0e,befe19a,7f234424,a8b68c0d) +,S(68f7b02a,ea38424f,decbbfc3,498c6193,62c732a3,b048800c,85d042d,b284f7d4,bef680d,90660176,f3d3d009,9f6cf818,a277dc5b,3d765a30,b7a4ee9,cf3bd46e) +,S(9437ace9,6b566bb3,87d9946c,2c32c06,f62f1158,dead214f,2b721c6f,b6e8888d,f8dee3bb,331e1e33,9963b7e2,316a1352,c8748f42,44463ffa,5bf2265a,243941d5) +,S(af40e909,85e5ce8d,dfb6d6d4,222d3c57,2ffae40f,53de2c06,55a74cc,70cd8dc5,2f08f237,3fc922c3,f0ed9d6c,b9538f4b,c661ccac,ea2f4975,50f47ec2,17d8e626) +,S(382e5a07,f1f236d5,ca1a68b8,f0fdb813,29e0393c,c375df88,f87914d,cef93c64,e24ee731,c0a88fa4,8ed3dba,87e97096,e0ec2224,dd657411,a9f1a9e8,2b0a6657) +,S(99fce288,c6ef1d18,ad630097,8ba82dd9,1c779a60,b266109a,288d51c3,978fe565,294c9e53,3cd42a54,c071d5c8,acb7edc9,897db8ac,d25b5f10,9eaf8dac,42a9c1a4) +,S(748326fa,c8dc9394,2de0a000,933dc18c,6ef92cfe,bac46939,f4405d89,627e6727,adf2d561,45581b4f,e706ccd1,8dc82bcc,14d76fa6,94ac8a61,a51d06d2,89e36d2d) +,S(43fef689,67074a2b,7e944b76,8f8b1ca,15aac3ad,c8f5590c,f1f02c3,afa82e90,5313cf6e,8cac44d9,fd548032,dbef3ab2,26e93880,644468bc,799c87d4,c0bc3f99) +,S(404341da,829f537a,c425050c,5ba93ca7,baa8a8b7,dfe51c23,e2ce7c72,43d57659,f91a0d59,bc35db64,b250adca,3cfbbaa2,2a82cfb4,d684e8db,e17484ee,af009f9b) +,S(3af33cb6,b4d553e5,50fd35f1,a0b569e3,eae05737,7b7d735b,545f7f00,d9acae67,42aa2cea,deab8cb3,b1ee9c3f,4b1b06df,e157cbfa,3912035b,585980bb,cf85279c) +,S(2e96133a,1da8a378,c138583e,86ba1de2,3450b285,3559a431,654ec9aa,1f64229f,3bfa5a75,4dbd936d,7a41266c,97472020,6cac86b4,d684bc1a,59dd1f27,fed8e76b) +,S(adc4b672,69fbb719,92bd6e22,3cf9ecb3,c9388b5c,45ffadd6,94c72e2f,b355984a,ed177eea,ac8cbd88,2a368fcc,4908ba4c,8a4054ae,3411d75d,b06939cc,72522a7c) +,S(68ac3244,49eac1e3,df997282,65a0176,bf6c6115,64daf79a,135bc6c2,5578b6e,407a75bd,b1e5e6be,a9b815ce,833c0be5,f5c462c5,c71a086e,59fbe0d2,5e7b1fca) +,S(5176afcc,b4235cc5,ea41eaa7,b657a77,bb383bf,aa71ef8d,d33990b9,9c2acab9,cb363792,9d249fc6,1c0931c,8a27dbfa,c8371574,52c40306,c3291814,ceb57095) +,S(4938cd76,e1aa6b28,2a89e883,8671e4e3,82d7bc76,dc4653c8,46323cd2,51d18542,2bfe67eb,6da39ea8,c8160621,158eac48,550c3730,664590a2,731247a1,399bc42f) +,S(9364dddd,dadbaa52,efc81971,75041c81,e7ebb48a,f20b82a8,125d85fb,a7fea192,ee568f7,53513b91,cf6720,2c45c4f4,181e855,ac0300bf,d7de30e7,317a6ea2) +,S(bdbc0937,243e563,df29781d,3b14d4ac,a664fe5e,70f3d9c1,39ef1b69,57839156,2a84b153,549c6d1b,27dd9ac2,1ab86f34,9ace0619,6f814d08,92a1958e,d137bb1f) +,S(b616b635,adf7b64c,43c4e242,32ffb330,bf28ee8e,48918093,9584c26c,28c82f2c,27fddaab,e5d47957,6344022b,68744822,eec7b937,d29b0631,93c7f6c5,6385cc89) +,S(55a3849a,50606886,abf6f0a6,5a3e657f,46031cd7,4c117365,8f27aa14,326f3cac,4a522c0c,17fcd116,61b11d9b,f88e0ad,c7a5761e,e01db8ff,a7bc3dca,a7976b00) +,S(d53e472b,439dc5dd,c8ff479,ff678dae,95b2e207,c92df108,728c3783,f8818542,3f3f7ecf,df3d9f89,1c723161,75a57931,4ebeadab,3c4dccf,bf2b834,c762d30f) +,S(1e27dd,f6186285,41f5d8a1,6587e2a4,ed38c34d,8393a6c9,fc0a7c07,cef36053,280b223,da8d01c2,12315c1c,ba7dd8d9,96d3202b,91c4eb4b,26c802e5,9494378c) +,S(b6d9d97c,64ba01fb,e8a9d29b,806d8a6,42413bfb,fbb4ae0c,10d8fe52,7ae6415d,894875dc,d912f8fa,845614de,a2b09796,d402c738,ca1f3c9e,c0796681,d715b8e4) +,S(2c97985a,5fd96164,e4c4d9d5,9a9fb52e,b2e6df0c,77ed4745,3dca6eac,7550756a,b3526bbd,de58e408,a4f45dd6,61f5c6fe,2f82d2ca,3e2172e1,c99d1fee,93d44c98) +,S(405deafb,528991e2,ef924f55,b7e4dfd8,185de449,cd6f71d6,53025999,4caae657,e959b7e,59cecac7,f813dc1b,a15bb71b,4a4832ca,54026e18,479d71d9,191c3ad) +,S(4276ecae,a14c0556,b4573b26,dba35226,4fff2c3d,12a3e4a8,4937ae9a,3f687bfa,7611836b,d3b335b,66f92914,6df0de13,d6ecd47e,88369ffb,6c9aa493,e67dfc71) +,S(6fd734de,6d2fadcb,d7b19f56,ae7153d9,1ddb396f,e0c1e51f,ae31fe80,8a35556f,aaa647c6,92865772,f31fdc1a,3b430ffb,e1647e10,3cd5d629,19bcc905,ff7ae633) +,S(4f0a22c,ad6ebf6c,e6b444dd,35a54e38,70017bae,eecc14cc,3f7ca88a,6d4e27c9,1386d40e,680060ca,bb46d678,d2be7209,418d6f72,d3917e20,7b833124,29b43ea1) +,S(873ccb39,5c10f57,6e50093d,44879f2,687d9321,441d8a7c,993c1083,ae7b0570,b261d029,dbe15f4,ff70ee42,36f558de,8984db4a,608d45f,4e28d001,e564c5e2) +,S(75d41857,5be3709c,5c732073,24f36089,b87532b8,e91db4e6,70a89117,9d25e039,47e29f54,fa62ef44,139db763,4b1c8f5c,e027b0d7,e1ec3501,1e8c6dfc,dcd1a105) +,S(b325bb90,cea81ac1,c79df75b,e7615ace,9b2a9d4c,fa1f4504,1a47e0d4,30b64b67,3024fffc,2005699d,5351615f,baee8c49,8a319a19,45ac8132,71c609b4,23e14a07) +,S(436c92bd,a6c7e124,5aaffb22,62036329,ddb8984e,624f2469,b30fab18,1269ee2b,2a9f90d,88c01880,62a152d7,e7ed5acd,33f12e92,4e36fab0,bc0602f8,2c1d3e3) +,S(c0105c64,4e51d333,c7ed28b3,c94292d8,6d9c04f1,89b3827d,f1f22fe2,99bc51cc,d73bc012,1233ba52,ef9727b3,1249babe,bf63cacf,ece0192b,5cbd618c,c48a9d35) +,S(9f2a01b0,46109d49,d11ee109,5e94c281,1cb6f76f,7773141f,632b3a9,2e5f3f7e,1e260290,fda1caa9,ea315380,781f633f,21c90765,2815251a,fa70b169,e4b0da58) +,S(4d805499,23dc1905,7fd35a86,feefb937,f2b621e,48946e53,b8390620,3aef584a,2cd9c060,d66be813,12a3fd9f,ebb9cbdd,4fc23431,c3e0531f,4a026f50,a40dbd30) +,S(76779423,b5e5acad,55137380,276c4033,a865ae5f,9ada0f30,dee6986c,444a1526,9a6fc30b,4f4c5093,b343c8d1,aa204ef3,7c2a6d5c,712ad8d6,39ef545d,1eaa9a57) +,S(1ccc1998,33f8b121,18227adc,2f27c3fe,8d328b26,684b271e,85f8368f,40378881,da21e917,94851bd5,a8859173,830ddd0e,988ffdd7,f7dcb263,f6755eab,e2d73f75) +,S(afeea14,e8306fb8,e69689a3,d12efe72,949b6b03,8c4cdc70,c95bc351,1f999030,cafbd04e,79378032,47c71954,d8c2a11f,d60e53b,35045507,8f6701ed,621e7d53) +,S(cefa268b,e551b02f,8fe50481,44920abc,3d03d97,3f2e9368,d2d2cb42,341c11b3,77440b02,64eb1972,91d2d69,ebdc1de7,66915a09,aa01615,e4001d62,7219d491) +,S(8625c163,58bfd43d,888ef97b,e33d9938,c62f7f2a,9e7b9735,26dd14ca,7c76abda,e1351920,59085272,3ea7b55f,49c4045e,2dda5ceb,c1a31841,1b6cf38b,b97bc1c4) +,S(43b8caf5,d4f72519,19630044,13bd459c,f5913edc,ff303fa6,dceb3412,f8e39c2,7d1df179,13186dc0,d7957f61,a3232180,21a6b50f,61a86f33,72623f5f,d3dc1a11) +,S(163fff8b,cece557b,6fd77b4d,e22e5b55,a6ed51a7,76dfe2b1,362040bc,9e7e4fe0,29204f73,5bc6428,3c510e0e,2192299a,7f6ed56d,1a0cc569,aa37f895,c0c4646a) +,S(fdbfcee1,69aa6724,b5839a55,e1c54856,86503b51,d1320b37,dcd9af73,2bfc4497,d7f75ba3,7af2f969,31bfa612,446c6807,a207af9a,17269199,77b0d71b,16b11a0e) +,S(f1981a9,aa585d6d,102b3a7d,e3509e0f,ed002866,b379b4e2,ba9d175e,4e5879ee,bad6366b,71a7cd67,163b6313,3dcd442d,24f9362e,5d0b9791,2a8dbfb5,74517e1a) +,S(dd3de17f,1cffd240,424096cf,effcaeee,87bf4d30,4a41d5db,6953102e,4b91853d,d136d363,1b9b968b,7c7d1a16,b2302e7a,7770e5ce,afae92a3,8f6e1299,6fb04718) +,S(b1d95fc1,4e35f77f,7e64f62a,36b26218,86397228,35ccadb8,39fa7d7b,834bdae3,75611c0a,920e0251,345b3213,422959c5,ac66c495,14d50c35,de7aa7ff,2a330a6d) +,S(1eeb92e6,75f25a35,9ed16c8b,51a5c130,d2210c35,ce954430,ea2cb3a3,af69187,cdefc1ac,40fac4de,e42ba496,eae80bc7,680e214,4117e6da,c2b3bc12,ce9eec45) +,S(aeef491a,fabae168,9d58c2f3,808b22fd,760e8607,c043c10b,591ed211,6fbb5ce9,b0db916,30810159,7e79aa7,82d8b643,d739bda2,c45ee36c,4f328108,4e55a33c) +,S(c56793cf,822c3da5,300c6c2d,cf06b5ef,413d51af,633ec77b,b9b68b1d,d3079e43,a423e25e,1eb466da,f521c5d1,6395805f,a2da609,fcfcffc1,2728add5,61eb2c0c) +,S(2aa824c3,c8c648eb,8bd0c151,b30452aa,c097bc38,a9f53db5,a8375631,25887e06,20aa4bfa,3bb2c5c2,a113299f,6c61102c,7586deaa,938a33f8,4a517dc,4ba78ada) +,S(4a0bb8dc,1833942d,9ae3428,ed493cb9,5716b50e,c96db120,c18ccac4,f6c3dd9,d0526d5d,c8be139f,53427e50,17cedc51,6b4960ac,bb98d4a4,f07fdf26,640b78b) +,S(2808616a,309b64c1,5d061adf,ae65711a,a561f8b8,345132e1,5b18fdb0,e476240,d2190f22,7320a55e,ad2dc736,671db631,9b18d6cc,b4d2bffc,cb4b692f,74eeaa0c) +,S(3dc4b015,13a95221,32ef431d,33435ba,8cf9e6d7,7e4ac75e,54848916,c23e7959,eaa2516b,9b13bc99,1f4b8ba,fa90a6dc,a007fea4,e26fbe0b,a2c5d1da,326d5420) +,S(473f6157,50af1d8,839ee0d0,eb5dfb8a,c14ce65a,e04e5f03,99fe8666,bd6efe6a,18d204d9,1b27527c,50823d5,222c4e4c,e3e193e5,a282daf2,75d2b43c,ffba8412) +,S(3b87175a,db1a5e49,1cf7565a,28250c51,9fff906b,ef0eecb,e8e50a7d,a190aaaf,fc58f2dd,16f1a5cf,1a728117,dcac3dbf,3a3963f,3859a518,2616b65b,59e96403) +,S(12f1b577,1410d1be,d0c4863,360e37d9,d36643d8,e0cf6fe7,8770478f,504174fa,be29140e,6b5a40a1,40559972,7e0727f8,ca904c3b,813897d2,bea089d9,dc2f17bf) +,S(8658f35b,902afb85,408280f2,3b4d98db,9526b57a,1e6cd0e9,37d8c629,ae174a3c,4060349d,47a69720,7d29e83,d8c82197,d32bb9ae,8c83879,1e09a7b7,1c3e7c28) +,S(530545eb,526d9657,2ce6cfc0,22e1c0a7,b9965c7c,3c2db355,cb5d414a,6c1ac8c7,99243b26,17f8ae2,898b96b4,1c3c65f9,96a9f8f5,83ff341c,671a2d5f,2d04637a) +,S(2e808732,bbab8507,e65936f3,fd1d1662,91ada8c4,c0d865ff,849e0a1a,5f08d265,96dbf7c9,53fd2f61,7e149f06,89b66431,88b091d5,1227a1a6,a0ebb140,18a79fdb) +,S(4272e028,b4b9c90c,44526fe6,b25f5e84,4b8baba6,34ceb2e2,33447413,cd5bb35a,6b4a4076,fc3706a7,50b0c824,93f5e363,f9fcdb64,9d683a1f,fc3bc2af,fc8470cc) +,S(78712f3,449d07ac,7f8171d5,42ee8b40,4761e054,eb0362c8,3b30cd52,6f9ac60,c7ff5ae1,38ca3c13,79457619,dd76061b,7b59778,79db2ca1,5b07ea47,7aa41bf7) +,S(be40166a,60ad9af2,d1bdfc7d,9b0660c1,640d4f1b,640ce485,8fb22eda,65d15a21,78c49afc,1d992bdc,b70bab6d,d3619305,a32fe90a,2f2b1b43,38d77c80,b208cf90) +,S(2fd5831e,6bd5a79b,35bc75f,92e83e4c,9acff5cf,61eaad7e,dacb149f,46d5e6ba,82f38222,4b6be0f2,f52318eb,7fe44a4c,4c0c1b05,8eae3f99,dbdea80f,a70ca3d0) +,S(32fc3fb,4574a651,472e0328,c15a71e3,bf9a12ca,15d341f1,c5102dab,2ee6de37,7e9398a6,760df809,e5eb57df,8fdc3234,eff1aa8,bef57008,c36e7953,c07f25a9) +,S(b9018d98,3452e952,7944f2fb,3354487d,a82f8b90,e52689d4,edb2a91a,a8faa6bf,e9cd0e4e,5c5efcbf,9ca25cf9,f271f9c,a2c46b4a,322cc966,e7789607,324348f8) +,S(a74ba662,32afb3e7,d5c22ad1,c792da33,f1bc88dc,244a8ce5,d4d582bb,b16ced23,444c5512,b49c2c63,4cc0328d,20f7321,a88db1ee,6d525be3,5d2de8df,cc381377) +,S(40f6df83,6d5e8c94,332174e2,2fa43556,d06f48a8,f52cfd69,820c2c46,2185dbfa,852c5b98,15ba4ef0,18f5d231,195fb62d,afafc08d,fbf9159a,eb5f6063,ca353424) +,S(e05800f5,f7890a14,6bbbabb1,27924cc2,e33e3c81,eb88606c,6bca020f,1aa71747,ab905ec6,3af1bc11,897a44e,89c2c2a8,3fb7255,c0e7f76e,8378e59f,1289158f) +,S(7b75dff9,a1afde87,be8528f7,9df63d70,e4df925b,a15f01c5,8e8162f0,89ee735e,bc057ff8,bdc9e37f,554a6ad2,3ebfeb2e,5d64adb7,69fa0082,2b2d4902,ca82712e) +,S(2fb81423,3b01e312,7ceabacd,a9ca518e,b1ab993c,bff855a5,20a96f52,afa9a0cf,a7e4bc57,b53affba,9e2cd875,9665cd9,215fcc,35dfc402,4d1db86b,9605c4b7) +,S(f346a33a,ec17d0e6,a10262f2,fd8185eb,f80a1fbb,f6b06bdd,1c04f18d,75dbaaeb,c09caf81,120586fc,33a6a0bc,97ef5cc7,56d20806,1340a1cc,ba9955ff,4a059e10) +,S(d128544f,a5f5dd38,62a759b8,5d538baa,63d112e2,f8c343a1,1bb3b8bb,ebf548d8,7893faee,b73f0530,bb67e8e0,9c2806d7,e303dd5e,116bc9e5,93e4dcdb,eac031f8) +,S(69046ec4,11c06822,59de20b1,a2a8f84c,58c56765,2ddcae,a26f533a,9c706f43,c17a9640,adc07d61,4a264ffe,272cd686,99b9af9f,6890cdc9,ac02c761,637dda8a) +,S(7b50f61a,9dd7b9ef,7af49c17,6ca5555f,eadf3b67,90998365,29379dd2,a3c85b5b,c08e18cc,bea8a970,7bc34d98,6b36475e,e2e24695,2304df65,bbe0347b,6052416) +,S(794a9728,9db4743e,c91a8560,e430b14,a7d8312,1fbacfbd,ec37a9bd,c749d3f,c57a5b9a,f0cb23a3,5e9b092f,386cda86,bf2f8242,1f74dfa1,837047c3,ae0d2235) +,S(fd8d1485,3d2fa064,c4682ee1,1c319a8a,49fa9b23,2cde9d1a,9a44b2dc,93b2f251,8cc4001d,f0121ce0,ad2119d1,7aaba363,ec45345,87fa10b0,c94a5043,f641b91c) +,S(7b5fbad,8105fe06,6962a72e,39a9a4fb,fac27794,e39a6660,133b9ef4,a6877557,b9b4c9c,1200d879,6013de67,958176c6,dc04ef69,b1021057,de8d3b40,564fbcd3) +,S(2c7ffc8b,40eda03e,20e64678,68959141,c66f01e8,b7cb050d,c60e8a48,6f6e41f9,cd0f3510,39aed3c1,56ae2b0d,1a117f78,c14a704c,992db297,60d22700,2f71ff7a) +,S(79533078,d81a6fe8,446dd750,b59ecdc3,8904f13b,48ca89a6,5644aa8c,9233de64,d7c95bff,77fa9894,74634aab,3b8f86e0,ee0bf92a,3a338fb7,f89881e6,e1fd746) +,S(be96c5e5,d3fb03a1,801a7760,16bf3824,aa16010e,884359b,d5e30658,5f13b214,d156346f,158d0c1a,2ef96a95,86cd8d34,20be21de,6997904,8299744,b40a5d9f) +,S(165c53d1,9ac89139,c063d934,511478aa,bc296cb9,7201dbca,fea4cac2,16a4fa02,4b002644,1e6f1369,d3603780,f33f74e8,42a812d8,b4e7ff7a,4aeea468,35f67348) +,S(508fb72e,dbd27f3c,76569185,a18af8bc,6242462e,cecffffb,3352ce3a,da5ccb5e,e1698f3e,1d53607b,4911423a,f2167466,a473a8f1,e2226849,f4dfe551,dfd14652) +,S(e9be0fb7,8e95dc1c,7b79f4eb,7976367,a85034ce,ea8642cb,19106dad,1d10ab92,b7867a7f,51f89779,a32a7b8e,273f9659,fb84367b,90ca3ff6,afc2cdac,7f596c45) +,S(e6ea5e6f,97116554,2de16c66,1f15d6e1,24aa449e,960b393a,e5337de1,d4c94800,bbd62bdd,1c235fea,60be143a,9155ffa8,204a1b11,3f19f4e,6e683c7d,e234ca7e) +,S(ab3f8a0,5b8f5ff4,149a390b,a858092c,9653d159,6d84bbc5,6e4a7a8b,fd54d7e8,41008916,311de07b,16c1b49,c6aa65ed,8baaebf,7a4e75b1,5aa1bc34,37483e53) +,S(515e02e9,52a347e7,5e0c5eed,a266242b,48bf33d0,70048562,c20feb3f,aecea1e3,797b3ef8,f6c35440,58517c56,ef5c6464,fcb63353,2bd6d2e2,83487a1d,8a403b36) +,S(520cf598,b3552fe0,a42438f8,55aefb81,3a3e10d3,f4985998,492e06a2,42ef46e1,c69de50e,2bf9658a,40567066,3cac0e4,8c8d2920,95ac1df9,9535b7e9,209324ed) +,S(26a8e655,4a2cf338,33bd27fb,d96880bc,bcc1d360,2a76920c,37075790,1c50bb1a,ba5a4560,5ddc5236,2a0d09df,3247a507,9c87e652,c4ad35f2,e19ecc9e,ec1ae4af) +,S(bd06a5a2,362ac91a,759dc578,dff3a3f8,102a67ae,a86ac11,5ddb2e14,bc1bba44,e8751dd7,153537ca,eec17988,98337cd2,abdfa554,52c597c8,61c364dd,78f49de7) +,S(ddbccf92,da0ab07a,e99fda1f,4a03927d,66b0bd21,f1e54fc5,afd4f329,35a0cae7,26fc18c1,52755bc5,d68dc3f2,461d60ee,b4dfc02e,a04b4779,6e7725b1,23acf8dd) +,S(650e1616,2a30c776,b54130c9,9fbbf567,32e2bdde,f667b09b,9b7f25ed,93c0737c,14972f76,429eb04c,1ebb0583,8c54fa0d,309fee09,a55d7eb3,700be0df,5801d56b) +,S(2920d280,41ad7365,cc0e33c8,7a3d6f3c,f9fec9c3,b00e5698,55ae3b83,8cf08973,3821fdd1,fe36668e,16f2cbd0,b2704fbc,24354f08,8ba19a1f,67d1b11a,b70c2d68) +,S(3842fb0f,1b26bfe7,535c9f5b,cee85ba5,6cd491dc,346829a2,a178ce65,c5294302,8e02342a,cb0e1233,9e638018,a125622c,5f66ab52,86a74a6c,28982c25,aa3a0fe2) +,S(9c21d89f,f1142d24,1e62c1df,e0481268,c2273d01,f153af5c,d31b3514,5b9b41ac,f5a924a1,d60e1eb3,72837535,4e252740,593c96f4,87328e9e,2a80cae,15fabdb) +,S(59320ba5,c9088701,f354a3a1,93391880,2829ce91,be9b4c14,c9018fe6,4fcd387a,610e48aa,705e2e7f,86a6a12a,817984a1,7bc60f9b,abc0ba9f,775f3446,8e3f3815) +,S(d800691f,83c2903b,1add209b,35d796e7,15b805a0,9bbe6120,3bf68a08,a13c46e5,21d194ed,bcb8bea0,cc35a9f2,328f1689,cdacc58a,73f65a28,56811e54,d96e5576) +,S(865588f8,66c21986,7b9643d8,7f1215fb,90fe186f,46478e8,522a5da6,724f6e8f,91a6b315,a7ddca8d,b4ecfbc3,9b55eb81,393f4c51,f573fef6,e7ca0c9f,cc551e7d) +,S(9dfe808f,cf7f574a,ddb251c0,4b053d00,8915f8fa,5a975479,d43c719a,b67aa4ad,4d40cc00,ea6720db,ff1f1339,7bb26c0b,281686a8,726fa430,bce0e4e4,ff01b01d) +,S(835f1c87,cf8d4420,72728601,ab6aef63,cd0d73a1,80f81f07,f5d57cc6,bab5ef7d,bac2d1d4,c8541f65,be0644c9,40a18f7f,d2c30360,2083a455,4d70a111,1c5bf07c) +,S(9562dc71,33c48e4,b46d73ac,d42db4c0,b0222c4d,dcd0e76e,b4f84969,348fa46,7cfe0965,96f691de,d358c00e,a292975d,465ef064,e9437556,40bc1d4a,33c3a0ba) +,S(21afe3b9,4237473c,dc032588,c4c1b7ec,853987a6,dcd1fce,2c48bbb6,8d0f3b45,1751c5ef,674cf88d,d5385943,b40a20a4,6d20cbd3,9876adc4,a4a4bba8,477e78a7) +,S(89809c4d,572cc5c1,2241ae09,fe1cee6f,71aaa292,c9ff8d6e,c3eb8a92,8e144ebe,462c023e,1710ed77,bd47d22e,e222598c,68cd7c56,b004369,a9356a47,ed6809d) +,S(b7c6164f,b9e175c1,5724c596,988b496a,b9f5b0d9,dd45d0e6,4a0f08cb,9000e3e9,1a13e8e5,a23b40a0,aba44bad,5cb4d37d,a6061157,aeab7a0d,d327242,ab2ad11f) +,S(62088450,24eef2d5,4fabe8f8,fabf519,72908ac3,23596378,c377c458,9719bba8,26216b3,a353295e,a1877547,b826c240,351f227e,293abcd2,e3967fed,30391f5a) +,S(dcfe82df,4049089,f3f8b275,120ca438,998fb22f,e11d40e0,9d09c4ce,c12ad036,388f9754,39b1c412,10014136,c3b58fe3,30ab524d,d7d3524b,37ce9133,5cb3bf3f) +,S(324ec5b0,12de7919,2f27f5ed,166344e1,934b3527,2b197d28,9a634044,5dd4bce1,99944794,579e12e8,c5c0c11f,a8eae5f1,88cb8cdb,3ce7814c,f89e3f1b,a3d3de0f) +,S(b3a70b0f,af96cb56,7dc4245,13ab7c6c,bbc38634,faa0c286,b81b9754,454a363f,b507745b,97843c90,170f8ffb,f731fee8,4532c1d0,6b2a077c,2aba5d94,189545ed) +,S(c4a6ff4e,cdf1ac83,29a1cdb7,b5165d88,2a1f1823,d1c38006,1b53144f,56187fce,6f7d0fc0,c08a7ba7,386f9a59,330996ef,b13d9d21,eb6d3915,4c8fb919,66159919) +,S(61d9ee96,1ef58634,5c4a73e3,a8c3df82,eac28aa2,6d740cbe,1833dcf6,d5a38811,c9e4a482,1700107,f2d4af3d,fcc74e68,8123b589,4da1c2bb,1fd926e7,11330892) +,S(67ecbd0f,4f4fe300,49390655,5289c9a5,cb6ac090,dff38502,75f7751,a84c6172,e422b1dd,10467cfe,921028f6,71cc75cd,2be5d8a6,75e644e5,d3c40b3a,2836726d) +,S(47f6c669,70898fa8,16dcd4d7,4553c644,2ce5bbe9,cda91324,ee3bba7a,868ff0f7,e56b9590,838bdfaa,1c2be1c3,95f775e,4a0b3982,d0eee531,26ec7ddc,9e3f77a6) +,S(e39ec9af,c8dccd35,4b155dd3,1d1750cb,ab096807,f89c8afc,fe61e6d2,e348cfa3,df3fca08,99158319,b93bac62,88c302f8,a59e175a,cda9fbf7,6f0ad59,8358088) +,S(2d1aae84,500037f9,8e08b64,341eab03,e0f1cdf,5a079b46,738746c2,18b3a0,747c23ac,8173adcc,de767d2e,ac156384,ddf40797,131a6167,c32486aa,12c89e5) +,S(ed1bbf04,d4570df5,8f584158,1fc47665,481ebf59,cb88322e,497d128a,678c2b4a,a40765c4,772da2d0,b3c8f107,22ec3931,ab3fc8cc,c28b003c,bea1a0da,279c8fba) +,S(bcbc3e1f,7bd268,93f377b2,eee4b76d,49a8a603,738de309,5353fde3,deff55f3,fb697a08,2f2570bd,1e9e4ec3,fc7f6c81,2a27a7e6,f7b8a53e,30da80ef,f59ef2cc) +,S(4f98b2d9,2f0b5d57,51ed3784,94cf4de5,65cf632e,982a270b,2746a5a6,3da9333d,43857e7e,437bdc02,6dcdbe68,d056784f,a2cc606d,7ce09a0e,12978a74,5b67e529) +,S(9dbb995d,d0667371,1731bf05,c8029035,2b413411,45318de8,2236df5c,87728582,c0a90e4c,6fbc0665,f8cd9fb6,fd59ea3e,f6ae9a16,9bfb71fc,5fe73e3a,4d665f86) +,S(83692208,1d099344,3d979c51,90940e44,5465624d,3a945c05,7885cd00,5ce6b9e,49be5e40,2e1d05e0,67b16279,855bc1de,6f0d8aad,35d8bc0e,142dbe87,33a14e13) +,S(f713e920,7a699b68,12d7ee9d,1475ba85,a6c56af2,8b73ace7,cf67ed6b,55650e97,a5a2c2a2,45012812,29fc71c8,103db717,48a51f88,61765d31,4b9ec278,3d0aab45) +,S(919f2d21,256ae682,fe514320,9c6551cc,d165de1b,8213fdbc,9c06578d,ef705725,9780da96,eeaac4e8,c96f3d6a,89c222cc,9b16b4c2,e8faad4d,96cc0136,a06021d3) +,S(1738093d,197a5ce3,cedd1fa7,e2a8ff03,959a6c23,6aedf9e8,9dbd74c4,d82b6e48,74363112,d16b829,d371a0c,f1b3bcd1,2000254e,196ea80c,a9d46570,1ee4a1d8) +,S(41242a81,35811b36,d4ffc40d,bbdeaa7c,cce36135,3c4fc9f2,d23191a4,b9c46379,7b894326,789f3071,374983c7,cd2a5ad7,e0ee49c5,e740dd33,817a31ed,97c388ba) +,S(894a6ec9,96eaa8e0,9e077b34,7b4f1e1,a387c930,a526c469,aaefc0c5,402d41a,a080fb43,c8e6bc6,388fa766,2398e096,b65032e8,26c5a9a8,47793924,4dcf5e41) +,S(a71f2131,3599cb7e,8c1058c9,52a5712e,661d01d5,79bc7ee5,1fbadd35,34ca5d5f,afe5b47b,663ebd7c,d788e0f,d3f963c9,ac63ee24,b7495e61,4a5d6553,9ab5f859) +,S(8f330e77,82eb62e4,4ea389f5,7f1c58b3,458c5d39,127d9783,6ddef8c1,27fa390,894e6142,bc359171,999489e1,1ed08224,4a46100,136fba84,e2b8732,e9bb626b) +,S(d2f0700d,6124c46f,a64cb709,1181cea9,34fe0406,21267334,c85ace2,cf05fc6f,8dc30ae9,83a95b74,2d800490,fbd8c290,bda64daf,f82d8fa5,e69243cb,43556cb4) +,S(c2478e89,8c075873,ba6cd5e9,6a730e1c,b6ade2f2,7fc9e7ec,93da9201,63f88c32,c6412063,9921d8c5,77dced53,76907410,82b1b4ff,4434bd,9a55b6c,8591ed5c) +,S(c5bc11a3,4e701898,d22e2920,2806c880,b24efa7a,c6d4ee36,cd440386,e4463a10,2c2b89fc,48feefc8,8bcb4ef5,68d16b44,cd7d8c7,485c9703,91c1c243,bf91003e) +,S(4b3930e8,21827b05,8c487bd2,fefa3458,6d0d3f20,5a2236fe,1b735d63,ac8c62b9,c38a29ad,c9b9941d,dc92a0db,4ce5f312,252c1f66,8a3189c5,595a371,19321c6c) +,S(fc646e3c,eab5a96a,1785da2b,1b50f7db,f0515091,76ade1f5,b057d05f,3aa3b8fe,b2014537,dbf2637d,6f683fb1,6af00d5c,63d4ed59,cdbdd673,f3bfbd48,e9574dd5) +,S(c0ada793,e2d9ed24,8ce307da,a6bebffd,3df2fc27,d2001dd4,5dbfc7be,c5f97a0c,6f3a787e,d40f073b,4965d52c,40700f66,da93f679,9efceafb,4894788f,5c9c7fd7) +,S(b1a45f3d,f2d45a,e21e43af,31ec3159,e8877d91,3efea814,b66f6fa4,a227b157,d988122a,eab167b9,f89db9e2,dd82405b,404f8a9c,a9acfd29,81c8bfa4,273ed248) +,S(4e19b9e2,ad3e421f,1b85a174,89d8841f,65672fad,9a17ad70,ca4fcd12,716d7a68,51412d39,59b158c1,3905c267,f5cf66e2,364aeb8,b66a11fd,ea6f5471,35db6dcd) +,S(533ee2b1,379a6ddd,6e5b3a2a,3a197e7d,eece722d,5c5b9c66,5e1be9dc,f3c09adc,b91b7477,fd0eabdd,bdc4047a,9bcad0cd,9da8496e,bd328fa3,a3ab20a6,3508a6d9) +,S(ccdb933a,816ac55e,c8fb97e1,504fa512,67408fd3,77aeeaf9,565ab66c,a2033b94,20299202,99b57beb,5d3817f5,26aae569,b490b24c,d5834dbe,8b05e8bc,89110de4) +,S(770d7c72,2e9964d6,84dead28,328b1925,287184b4,6e3abbdc,534eb87a,e0ea5873,363c73a7,bbb9b2af,3c0cc91,6f8ffe74,837a99c8,58b5464c,9f253764,e4a78285) +,S(d440dafd,b1d0609f,7c2354d5,74e711cf,852b364,8827fd41,88228ca5,98f71eeb,57d438de,c1aa78b7,c872cae5,c6803a2c,9844809c,7bca1a54,1be6f779,893aae1c) +,S(1602ca76,35ee0795,4fed3cea,d3e54470,41033887,2f060e19,990f3cd3,501b951e,1ea7f857,4b72d3e2,bd45fe36,c828f18a,5810812f,ab6e0936,a7854ed7,c7e32bd6) +,S(9c4d2a24,e4ad8226,bccab8ee,96960b1b,4722d2a1,88a429ad,f9d194ca,6687f7e,e3a4b46f,bf608018,ada2383,5c70fbe,cabbd446,78c9e5c1,35e91138,7d66b01b) +,S(fdf84be7,5be40fa8,db537848,e2fc8ba2,b7c58824,74fea4f4,6e8fcf15,f33d3bb1,2af57dd8,60ba0e6c,dc3606a9,a902420f,9283f721,70ce32d8,39c33673,5da1ff77) +,S(6083a785,fc5aedbf,34615139,e2f97964,ef65d254,a38251ba,203f8ea0,26eea81c,bb4d48bb,894fb656,22cd752f,6e3bc6e7,670a4bd2,64675035,8481561a,2c18439c) +,S(e03ad08e,5b4b9e01,5103e028,668f09a2,7d2f5254,25c6a985,6dfee667,6afffb82,f53acd57,1ab23ddb,d6b104b8,71d957c7,f254bc40,c37017ad,f7350e18,7a24865b) +,S(5a382a4c,88656b6c,4a5c8dcf,4052b1c0,a0bbc0a9,86289ab0,e212fd24,b852d9bc,912caa9a,32a10900,eadd0eec,423f710a,3e0aaba7,93f7b675,912223a2,6ba14f31) +,S(37dd526a,b5392b03,3bd05ff9,3952a31c,7bb0cfe1,f02f4f57,3b8d0ef0,c05d5ec0,7e329228,36595c82,14c8a776,15482931,98966225,4d4315c,c236c156,254e3249) +,S(ed4460f9,cd4bc957,aca653a0,5b6f0935,9dd7e19a,6d65c60,ca585ea3,ee2e1263,733af30e,6edd2b2b,317bba97,d24abd7e,41af6256,e7353f97,58357ff4,1a701829) +,S(eb01d9cd,50ff4778,b29e5096,93388ee1,12cfbc35,2c1b1382,7b3195e7,44a3bc3a,24877b7,99b7a2c9,db23047a,3194e9cb,91e5dd50,d0f1e252,b6f3bfca,f5b4d110) +,S(9fcfa274,b180ce82,14624545,22bb9289,1e0a8fc9,71949bfe,7aa25cde,88dc284e,6787be0a,12a76a23,9de45596,2a11f7f4,4051fbbe,3ba7dfb3,996c60ee,97be2b9) +,S(c8a0d869,87a7a854,99bd5663,30a07d67,70265d8e,cd3286ce,c9be4d02,6145bff,a65c64e4,af865e6a,893e902b,b06c43d6,10bb8181,134a4b71,d136b5fd,f42982a8) +,S(374294c5,932d3f74,a6e74731,6c6a84ca,dfda6d35,5edd914b,70b26161,50628735,ac47d048,8433754e,3deb79c6,7056d828,14d73bdd,703b299a,ca910180,e518672f) +,S(baa9e3a6,2b4bf099,1fde27ad,4b043b50,76a184cb,4f9a6da9,9b56ecd8,a2ab99e5,1e8e836f,f76043c2,c187ee45,7138cf3a,270e2d3f,5bc96979,c12c34cf,9205c63d) +,S(72f85ea,784a5ef1,71516c22,13abca1e,8017db34,4e00b397,4cb509de,a124654d,c78ec627,6cbc5072,fd75b28c,8d395f13,e84731f,7767448d,e06c0ba7,372968bf) +,S(c9173d63,bf5a1301,f0750b1d,e3cb7061,bb9cdd36,296b422e,d23513d1,10b61903,d26a6a0a,ceef78eb,73c6b031,a5455d2c,2a9c4ab2,d916b7cc,7b8e627d,6d581c56) +,S(865ff86a,58fb9853,8bcfe496,26c0bb89,e419083d,f21dbf6a,7b13e041,d5cd3f18,f0bdbabb,8118de57,bce9a90c,83529ec8,abfc2812,ab0088d2,8ade4bde,fe2fa383) +,S(3f14eb28,fd9852c9,bf4d4497,4d794ef1,c30f7748,5c7bb766,6f32fcb5,5ad910ad,e982971b,ec014b05,a9b5657c,a0bf45b7,adfe19d,22726075,80b42eeb,f4dc5217) +,S(61dfae27,c7bb68a1,ede331c,6499a7ed,e242457a,77e5a606,cea82e9f,f450d01,973739f2,c1e4ff77,cae3cf59,b481e730,5ebe8196,c5b62b9d,a96ae224,9b83efa7) +,S(e319690b,e944c297,f7c1bc1f,462ac3b5,a74fb913,9b963384,ac11046f,4343883a,3dadda66,538ea9c8,8fa0c02f,208ede8a,b6ef3480,82af4a32,2ddb5fa7,96d2efeb) +,S(f3db5e84,a9015b39,1617fea6,58143553,baa1975a,ab017012,38dc4243,7d9eaf9b,df55628b,c50cb2b1,be2ef193,a7f90e6a,3bfef4ac,63aaeee7,39907906,547d8b62) +,S(83a7dcd,58742725,8d17657c,ec64b5ed,4807db49,911296e7,10cf349d,c4fc709f,e5201a27,c37cca5f,2f7bf74a,fe000c0f,56643a5b,bafe9f91,de181e74,1d327183) +,S(b95b2363,28f51c80,b376dd90,a0f92d08,1e395132,deaa8f42,c142f642,3d3611ee,c111a08c,a6dbccad,2e784498,22816422,f2200f6b,bb24842a,f96c9502,13479f55) +,S(c3ff0645,921f2b9b,2fe590de,dfbac094,8475bdfc,a6446177,6422cca5,6fb549e6,e07ecccb,4b972834,e2711423,c0fba72f,eb0bb7c0,71a9e206,bf7715f2,62f03e04) +,S(96a37acc,527ee163,51c46241,1df94da3,eb0229b8,6a6e34d0,234bdcb0,5313c10a,46014617,fdd3f8b3,a67269d5,20a49680,9e5fa57e,76da4ef3,59ef862a,c58380c) +,S(b135c091,ec98a07d,b624fe48,4d336b85,62facf81,50346e2d,d0be2cfd,618d1e0e,24456a71,e8f2cc29,19f53594,6d7aaa79,e3d7dcfb,4af2feb5,ea0a2ad3,a23ec070) +,S(71d26219,81730b69,b0411b1c,f553c81,6f35a34,e09d086c,4500ba,94812017,c25357f,8915a2c4,98fe0d60,ca979ecd,8bd7ded3,ad6bc9ad,262db1d2,c3d3e7be) +,S(363cae8,ab2259ee,80283084,d98dc16,60c0934,68e3e854,dd86d9a0,d5e97884,756c60f7,c5e113d8,6e92df38,8fc9a1a2,a4889d86,f7440429,7661365a,ccfd8ce8) +,S(aef32d83,81ba3804,6e5b3305,6764ce3a,726c4e5a,ea61a17,ac114599,63f36247,dea5fc8b,d4ceba19,89640462,a957a8a7,44ca42d6,901716a,734e6f87,9aadb81e) +,S(65980f89,e4d0e342,d4b4fcf5,228692c0,9ebfed11,52d951c7,80963e6f,8c81313e,2d594cdd,a1f0b9db,7b3d8815,f7402a06,acba8e31,b9b0c597,8d2118a2,5dffa75d) +,S(f979280d,7e35cce4,8b9372cd,f73cebe3,6ee08388,e98e6069,fbeeb168,52329433,9181e8aa,bf7d4723,4cb851d5,6b3ca08,8c5f31eb,6b1b8c7,2879cfba,bd3ecaac) +,S(3b9f877e,286a13c8,a8463db3,b306ad62,c152065c,6708bbd5,68931e8a,2deb537f,12436d2a,5269a319,4f605dc1,4a34fcb0,445be9f4,5cc2bdc1,b96d86e8,b9465631) +,S(f2c70f82,1f86e94d,426e3e3c,e31ee519,f5a95b6f,38b663ae,9a6aba4e,f7bdc4e5,dc534655,4ba850bc,fef2485d,51e08c3,ab546119,49fee2ee,4dfc4e09,ff203b44) +,S(e2fb481,da8a356a,ab82098a,f622db2d,6f0a4349,2428dbac,922c1350,65801f15,5f735bb5,bb805980,d85ae242,4855bb2d,5de0c1f5,5018e1a8,e65bc2f4,86b7742d) +,S(d99e2001,33cf632a,f66c382e,d8ef862a,17092764,2c8f1f40,bd3d7bb,f0070324,d00f12db,cdb6e1ed,d190a754,fcbefdec,ee459be4,d5a46d69,afd6cbf8,4a4d30f2) +,S(dd765b6b,cb2dd356,f5965a8d,38108610,688fedc,eb3ce48d,352b095b,aa0daa,636258b3,58171669,f0dc68bd,3dff2a6d,bea6e5ef,20060913,66b12082,e2d7fa0) +,S(f549c14,f099a957,6267ad6c,3adc985b,9d0626b7,3f1f5849,d64ceb1e,266a9965,45a17dc8,30118c3d,28e73a3c,3d026afc,29ecf50d,198afdab,dff3d130,8f32f3d3) +,S(20d80860,90a192a8,51eddb84,f79b2882,ad7ce8a0,9374b365,61e6da34,427e8226,b48b6947,9febc104,880aa8b4,17344206,b19dd720,e5392bac,7e1954d4,a341eec1) +,S(b9f383ff,2545078a,c22cf9cb,83fc9e00,e9d37f30,e03ae03,5694437d,c1de2d7f,14f8b209,d1128a44,20dfb93d,3dc9ccb6,7ed22dd8,ecf5a181,2cd687dd,64a2996b) +,S(2ba0e5b,cec7a4f0,c6edd1c8,2d2f5927,2d97f4dc,3ecf353,8d3854aa,8d6f9739,8b10b217,6e56e5e6,5b99a617,eb71da00,3bee99af,b80e5ef7,3ca8c332,5ca7a75f) +,S(28b45a0f,3c308ecd,c0f7beca,c62d42b,500b704a,9af39931,b8debae8,8cef27e,9a3f95d,a17888ac,19eb4e42,1279c400,a60a0c1f,70a11696,4cf6943,9fc858d8) +,S(d8993bb9,e73af10,26ab41f0,9ec5adf7,437ce08a,4295cccb,283657f0,7a9ca3a5,ad8930d7,817534b1,e8407db9,bb8a608f,538b2bc6,9827a234,743382b,4381ddbd) +,S(77cd88a1,76bfed38,d7dd7152,32e2554a,a644b79,64a85f86,dbd6ffc6,69714e82,4394630a,42436802,1d0a0681,87fcc6a4,dfee0fe3,6db3bf2f,dac6fc58,34faccf5) +,S(d2557185,9c0fd15f,1f3666d3,aba99e38,89419099,ce7be94a,81ca1045,158f2da,90e94d6e,ac00b9d9,19832505,75bb2f,3242e7fb,fb429dc2,a90e3231,d1316cf0) +,S(f4e26c7d,4ccd80e2,7620917a,fdc72ca,94178f54,547eb330,77baa95c,d92a981e,c8ff014d,a388dcc4,c634304b,5973b274,785927e6,190c5557,773b9a0b,ef7d7005) +,S(da3a12a9,50dcd18d,c9e531e9,86f85a53,e7ce5bb8,8f2b5869,9830c44d,8c14cba2,7380a5b8,c01209e9,a1face4d,798f63ad,519a67fe,6bc90511,c763ca19,7e8c6b41) +,S(3565fae0,daf5d9ef,609bede3,6e19417a,45d8c0d2,59163f71,b4d9f54,43756fcc,7b1ef713,a88f9965,be7e6799,4a936960,c44f67ae,d5fa798d,8c0286af,e9da257c) +,S(6683fb20,d435a139,bd08c35f,adcc8aa5,8fbb8f48,7f9576d1,6f41d086,3a4e3de6,6a969f08,566afbc,dc98abfc,9d0d4d54,5076ebaf,efc9b966,957f1dd0,af52209f) +,S(900de92c,cbd4528f,57a72013,77dc1b51,7af67416,1013a20b,30d356bf,e011f508,cb55db4c,8799575d,9dea64f6,9fdf081d,959210eb,32b26bee,b903bf0b,80264c60) +,S(9d84bcf8,1be8a9f5,df2c6e80,d1b5679e,476e39c5,c30351ef,dc6b0b41,61c17613,8aa0cee8,cbc22e60,b71d9066,3533c2cc,a02b8d7f,7df93ce9,897154c6,2fae046d) +,S(6280fba,a3c3c8e4,4fcf0f55,a783eea5,2ebda748,501730de,71781be,abadd211,45b74c18,f0c18d3b,76cc1089,8741246b,202fd272,cdd0e866,5e1f4d86,ee527f5a) +,S(a4237add,7a5ea66e,8a1b48cd,7d5ef195,d90f25e5,6f2f148c,6d4eeff1,805b9024,d512d16e,632bd9ce,6cb1b2d4,c9a41e36,f9a2b83e,73fc8631,1e4dfa1b,b3bf71af) +,S(51effda3,e84027a,47afb48e,dc5c1937,9a685a24,ded2998c,c2b74422,b1e83fe0,346a9d82,cc07ed91,d785c6f0,dc32b62,e3e7877a,892007cf,c015444e,46001f19) +,S(87ac6bee,837ce155,29c005a1,6eca4540,de1480b6,91bc0ed8,90fed51c,de923cf4,9a9aa52f,1be1a33b,7280d0a7,3c19f5c5,b6baf99d,3c9c2d54,4a8d9bf3,a25ceb71) +,S(c8fd7df6,a3b0c0e2,5a931146,72a0af1a,1f995f1a,109e6e83,10b0d433,5dc2666a,3a853149,9b28c2ee,b5baf17d,dba8f57,3cf6e269,f4f21b1e,72bf38c7,79d239c4) +,S(890f9eed,47126c8a,355658f9,296b1845,b142eb17,4c2270d2,46293ba2,997e5a54,f294c38a,1c929ba4,2a9234d3,249690d,10a990cc,137bda3c,ada4b3,6d4e4b79) +,S(9329dbcf,45adc298,65c8defb,ee2ce008,a3474855,39826516,b417b9d3,bd47c86a,469a6cde,e1b0c094,f536fa91,f7617890,1be77c00,896efc5d,94cdd787,3886959f) +,S(6fa5326e,7b161c7c,742188d1,c47263a8,2f1f78e1,df83c664,2546c9ac,70660332,86cfd636,11879179,16d51a4,eac57709,5b8abab2,1024ce5d,35d64b4c,78559375) +,S(ece2e23b,8915d7fd,dab9e58e,8489b053,24eb1485,d18eff66,ee5013ac,3e0556aa,6a94e4cb,8fdf0549,a01621b4,438c2757,fe9753f5,13dcbb35,5655f9b2,ebaaea58) +,S(891b613f,413c155b,c2dedaf9,96d75e1b,54a5b5b0,3705808c,f575cdf,1f697ced,11904787,c1fb6f8f,8856aeb9,f7e05bae,f599b78,d7450bf9,13288e95,ff3f871f) +,S(b7bd8742,d1af6cb2,9b55a307,dd3c0318,6923be55,78ba2797,e38a7154,8d6231c,269e9a33,7a9421b4,cf45938,1961b0a4,3e4a0f6d,f6a0f10,2d7a831a,d7d4cd3f) +,S(7c6f5db3,1620a83f,b4388d45,75d244ca,1f38a0d8,611300b5,d4fdc9c4,34a16432,d5c0c35b,e4a371b0,3b85214e,f5e472de,e6c8175a,b140f05f,6e52b766,aa313f7a) +,S(18d303bb,d2bd6f9b,7f941879,6a23fbea,5ece2078,982064a5,e040c95f,c534ad3b,76eaa3dd,b73af546,7b1862c5,7b4385a0,28b03b7c,66729fce,94885373,1ed2dccc) +,S(31c0daf3,31aa6248,de302243,a768aac0,c8e27da2,c2b8e0a8,7fd74214,b49bb78b,e8e1f975,b77550bc,d404631b,12c72d38,55d3bf5e,5477a588,b11d57e0,e71e1ebe) +,S(940aa62e,e3bff798,327e806,b644a972,fae9eb09,dffb8394,61b080b4,708f715d,2853e12d,56898ea6,8e922497,3660a29b,37ec41c7,339b8059,2075c7a,2836c1b5) +,S(66db37fe,3bcfd7bb,25ca4a1f,b2ee09df,5c748061,1c3a6fb5,d0f079dc,cdbf9b7a,a6d37fd5,5d58ee33,73898711,69794421,9cd7a2f3,3becc8fe,761bcf83,ce603b9a) +,S(fb04bfa,a93a8ed9,3d755351,98895c8f,e90d545f,8eb1d08d,5d7282bc,66026e3f,e77f3c9e,afa2791,b4db2f69,3438d051,47edc983,a8541296,a8cae9a2,174e03b5) +,S(5792afeb,7766365d,e6b36beb,aafde8a1,8e556ac4,207965d7,9e18c1ca,63465c78,95fa5ad4,4b93db96,2c26d740,d2aa582d,da19b761,480ecadc,212452ef,cd885b40) +,S(186c0feb,6298e341,a2440465,547ad137,c56593dd,ed82b608,6824097f,3f83f8eb,b3b58cce,8375d9a1,e63500d,141feec1,38778c46,4be1ad43,7c63256f,33ac3b6c) +,S(d39114b7,c22beefe,6796b6ae,3f740a39,9e3c98bb,58b647b3,5cb23ead,76eae678,1df690f,383db8a3,86284ff8,f914925d,c688aa2a,8ec01a2a,243eb309,e79aa071) +,S(6195550f,8ce49ce2,f762011b,2e8feaca,509a0628,eaa93151,4c779616,721b39b3,ee8208f1,6d86fdbb,c75c265e,88090c85,aec112be,a1d803e1,211151d6,cfbeee2c) +,S(a8429368,37b33a8,2d41a26d,e11a0fd8,7af231bf,30d3eb64,73aa064e,acfd8740,18524c63,c0cf7a0a,b4e0eddd,61717f6c,3221a8f6,3522d35d,4eccee30,b6ed82c9) +,S(bf42ae9e,a64351a6,eb1d2c64,57d23481,f913de5a,d3c00359,5eb8cb5b,228fb202,2d74804a,34413cef,8d2cb488,ea780cf5,15faabd2,36a9db67,91549577,70a09d3) +,S(f1bdfcaa,ba133809,f915e0af,1a08fcbb,dd9cb3d8,b62f545d,6b71b44b,b130daa2,51fba8b2,2c7935ed,4241a87,f19c2b76,bc1a288e,3e53855d,c532f0b8,1ee382c9) +,S(7bf32637,4c6adf01,c7796f59,a11e5c3d,103e3339,a0cfbdc2,dec57f5e,69429bcd,8926e57c,a1fe7442,72d2e89,d037feff,df263831,e40e9ac4,8473336a,269f6b44) +,S(95b652a7,7f58b0d3,4c6d25e1,c294907f,a22a3ee0,f8e8478a,4e8458ef,37791c2f,e7dc4caf,b5bfdaa4,7185f0f3,a98876d,b50bfb35,a77a8b11,b522196,9f255845) +,S(d9f8c6ab,693f8058,8c73e2a,9221b0c4,c8f1d1bb,5e1e58e1,8468a48b,c74f50e1,cb38d48a,89c1ecc0,23e0e248,e1991ac4,3fbddf5a,9beeb53b,4cd9c49d,41f42a9e) +,S(43f62528,287e50,5cbf1a68,18bd99c,9f307e95,84e0d73a,f9fefeb5,b6dff92b,85fbb4ea,b81a0409,ce43ca05,3dfd5a1,9756fb5,f4b964bd,dc409efe,696c2ace) +,S(425a68ad,6d20661c,ca7d688,6bb9c66,f37dbf29,30ccc6da,dc34025a,5ea7a92b,7853cbea,d7816579,fa98ab94,875ebd2e,7ceebf73,20b50b2f,7e67f0f6,dfd2eeee) +,S(929ea74f,9b75c327,a7b26127,8828feca,821e4d8f,c5e308da,f3169a2,bf84bc2,f19e6cfe,d8c966da,bb070d42,3c62289a,5193146e,4297fa35,5908663a,a36b0578) +,S(83da36be,b1bedbd9,4a4ee417,f9faae5c,c20a9763,2c1ab2c8,b997f23c,f6d35c31,a91def1d,7871aa84,eed0bce6,12bf6a82,98d0ebb7,536d8e49,f6757a48,aa7a86ea) +,S(a2e1da8b,4318fad3,52c8c285,46f0a8d7,8fd6cf6a,b506f8ac,2d6746c6,75f2d5b3,584489cc,58b08663,1cdd1b7,3e61cac3,52c16814,493b611e,ffb94a71,2cd85699) +,S(5d7c1af4,4b257440,22b82ca2,9923a180,bb7fc209,1990b111,12061b6e,9eec4d2b,b40ca0f6,a974223,3a7b0253,9f0dbefa,1bf23dfc,cd59c747,c290f525,2e960b02) +,S(e2831933,6cce89c9,993bf230,ae4311ed,48fb0913,b5f35da2,b7531418,b512a75b,660aa9d9,8bfea898,810107e1,711abff0,88881efa,4d9d586d,91381b11,67cc2a21) +,S(722c1e28,498d3c21,66fb0f1b,f44e3ba6,181a962,75efeed6,ac83b36c,12426031,27a135d2,3b70006b,480c3aa3,bd057bfa,200da08f,f9eff741,6bff7885,4a1795be) +,S(f3cd71bd,f93f2100,c534d788,ba607845,cf6049e3,b94f5274,84e8608d,7adb9c99,b8e86285,db09b729,dd789293,7cf5fdc,989e00f4,5dcd4916,a6860bf8,d77cecfe) +,S(36341496,d986b096,5e5ad593,de6f88,67aa6130,889714a3,dc0d58b7,19647318,8cbeb984,a3f4bb5d,75cf77ce,14368b9b,77dfeeeb,7313f16a,8a573953,c7b898a2) +,S(a48443b4,3783c58d,4b7b2f27,17efafc5,e5ffe24c,a7c26bbc,dcbf93,538fbdea,33bd2bf6,9a64a742,c461fc0b,b0ae8770,9ed47a9a,26e7d05c,b71e4e2d,20c894a5) +,S(d4364d96,71f2876e,843dede5,9991ac5a,cf92268a,73212ab0,54b1c196,197dddfa,b30038a0,fd9f7387,fb37754e,9b050e80,e0f28596,d251d627,5149149e,880f6d43) +,S(ce277a60,19ac0b41,16b9d863,5a2555cf,30ef3408,f1a15769,91e48d0f,9465d250,5260ee90,65c89bc,7ef55fa3,d5f5d7ed,594fe592,322b7e97,965a9a3a,5654e710) +,S(587ecb1e,7c08da9d,75ed0249,b1281762,e9c71475,5c3ae35a,f7d66b53,c83117be,c6dda341,cb7d88b,b4a1b13e,313dcca6,1ec58063,376d38f2,cf142b56,87bafcb6) +,S(d87f96bc,69510c4f,19b84e93,cd8dd0b2,eee4fbb6,c5c5074f,ea76a209,e059f41d,a9b83947,b557c4b6,41952117,45ddff77,b5952798,66fb4095,6b5361a1,b463d326) +,S(af9f0d3a,78454c,eb8ca65,c9d7a324,312c01e9,dd8a00ad,e923f2f6,41fb0ead,2d3003ef,29a5ad10,20262c54,936411f0,f8082630,8506fcb1,e1848a7d,5d16482b) +,S(efd0467e,f4791ec9,9380be87,394225ac,637f906f,800abf9b,1ad5b3cd,cf9f017f,a14308d6,b0d16772,f36da4fd,d77945f7,1d82276c,ec4dddc0,de24f760,965c5725) +,S(e892235e,39ac312c,f30dfb97,97e88446,dc1f9a3,ef5cb8eb,d540c64f,d6b6129a,5b291ebe,7c055f52,b9fae6ff,cdcc6dbf,f84cad1e,4d35f495,4dc19b3d,64eb992) +,S(3158351a,542ff38b,12f82b5a,daa6ea3e,6e75caae,600b76a1,16ebe3f8,c9bcd66b,2006c258,a327481c,d324acda,b8ddc331,6a6aca81,44dba340,527babd6,4de975e2) +,S(f17bbac8,c0a7d2da,bbc5a5cd,4b28e96,4ab88639,546b2b22,d40c519d,25dd448d,14f9f488,e76663bc,278961f4,a33e11f6,98d6f5fc,1eaac638,79ccfae,1ab40991) +,S(9aa24eb3,44e010c2,d6fd3efd,fa03cfe6,aff67d25,2f08dda9,3d00332d,3065defb,494cc5bf,e60fff11,f42190dc,e607f067,7e355a9,52ccc682,6845111,322ac050) +,S(3f36168d,77711926,deb0f7ea,b6dad80b,8c755db8,e6705fa5,61285f96,84f1ccc5,486d57cd,b46d998a,5d064f9c,68511657,e53e544a,ee8c5521,87a1cd16,4121c6c2) +,S(fad18e89,219c449,87551525,6150e4a8,1fa2b23a,b6c1d90c,2e2f9152,ee8cd054,b285a7de,4eeff44b,751b4e51,f252f3a0,be7c2223,a715e301,23e9bcea,495ea7d4) +,S(1cb1cf55,9c56951f,58147d84,9482dba7,8dc6050e,2897f389,e30aa87c,519dadb6,b9e54a71,93a8e255,b2cf1fe1,80fe54e4,3e17470,60e9128d,bd527abd,c7ef1f97) +,S(74e68afc,9c8d9e0c,92675d9e,2fc12803,4ce7d22f,e31f5332,d18817a3,bd05efda,1d8442db,d55e8abd,aa1de803,f4fb1295,e9a8710a,3f25a242,7af9a5d0,b5dd786a) +,S(10336317,ec82d4e8,543dea2e,b8cb597d,3aec0e70,fb2971f8,7c5699aa,e4576de2,f2ccc066,5eae8645,54816dfe,c82e1162,226ab207,a17c6085,62925f5a,ffa3e021) +,S(b06a55cf,57668bef,6c51bb66,ac8ba7fc,6714c864,ca788279,2c8b759d,290342b3,7311f47e,5b526dbc,e4bc7833,e4c5b45a,190e3517,8f0f8137,2857e7b0,fb1f0528) +,S(af83a357,81306453,e576c819,d1cdacd2,689b0198,4f108d2b,6d9b8148,50df5523,14f52176,909c7e1b,eda13d20,7567f31e,161a80ac,112e4016,ad7c0bd6,20ec0ce7) +,S(f8f56d54,54faf536,3ea98913,827d57f2,a8983112,aa8809dc,594af919,3ae5c4a5,cc9d4182,bcb00a0d,cb73bfcf,da46ced0,ecee167d,fd7bbfc8,899063e8,d659dd7d) +,S(61aa26b7,415001ae,d6b3afd0,1c690177,879cac31,93a2e410,4148df74,733c4ea1,972510d3,697b93ad,60711b39,f3b3c237,771bfbc0,b7238e78,5a786707,dd179f23) +,S(781f196c,dde0f8e5,10ad45ad,6be062aa,1315c246,85d0ca97,21533c65,627ad492,6f3248fb,e7e61cad,1b01ec2c,fdb4dc4a,b1f4dc25,3666d4ae,27a88d50,c566d18b) +,S(c422d61,7f84ddc6,4483d55e,19228dcb,395f16fc,e85b5c93,2778f62f,ce8917bd,2f3cef48,deefbbe9,9477389b,be898cb3,90499b2a,615899bf,1e910e21,ed337652) +,S(c325955e,b56fe9a6,66555a32,72f637d7,3351b65,da5059f2,17748e68,4da4a4a8,3fa27721,2364140b,5b71526f,ad963d01,16889555,bdd42fda,c2b451c,fb70a3b4) +,S(e393cca1,49142f01,9be9a4a6,e8597354,e34f8d55,b400fa4e,8ac6b4c5,7e50b7a7,e40b69bb,44d6d1e5,22cc30f7,26b7a262,3e5b76e,7b190f07,10325a08,a99fb2ac) +,S(33e3686a,e4e69510,e939e53d,62fd669f,f1a39af5,c6179364,a190ae11,a600cbf1,cfe60b76,1306222e,7052b0f1,f799380,ed564d47,1f6418ac,dfb13d98,47f9154) +,S(1c35b5c8,3072f4d9,b3b294b7,69ff1b8a,ed2954cd,a013c7b3,34b53fec,c783b251,1c691a2e,782ff393,b0ac6c31,94f4cb0,f8dbd5f5,b51654a4,3914a458,6b855318) +,S(147255dd,3af5eb26,119e3d86,b2bed206,43579099,742c4ccd,974f7fb9,83e47fa6,5e0a0a01,7497235b,4766b44e,2fbe8902,aa0e2c2,69e7ceb1,d65c0f34,7a97f7f9) +,S(9524d71,57304a13,71d46aa,bc43986a,5ece70cb,ea008aa2,b8c97070,6436b237,a343af97,db30b94b,3d8d366f,1cd27b11,83c9f44a,75f0aa93,8c4932aa,52f6ea55) +,S(8502e7c6,e498d868,3816188,a99d0f35,79058887,dbeb3c03,676b3b91,be7481a0,28bda608,a9e18df9,c304896f,94efa7d2,46ee528a,6061afd0,322e052b,e7cfb68e) +,S(b89a0d8d,a21903a7,200b196e,46714aa5,ad49c5b0,8fc84de7,8e72ca76,2a3ad3b9,953bac1f,85e4f631,38464a99,e6e3be5c,328b3c10,7523701,c60aad8f,d57e6bee) +,S(49bf791d,67125d38,496d8ae6,ffcc25f8,97114f6f,9fcd5541,9876dca,4bdd7d7,6c2976ec,1b9078a9,a90f55eb,510b1a89,17efca39,d2fda494,b9013d07,7f4e05d8) +,S(c63bdf20,1ff5b07c,14273727,ff174322,422b6497,9ca8427f,5f868eb3,a1fcf05e,c4135e1f,1b5a09b5,d628674c,21ead97a,42957d31,92a44de9,b785986b,3269a782) +,S(58c8c84b,e9f85bd,b26f99b3,cde715b4,4b057d56,d5411c3e,a3000829,27ebe551,15de85b2,1467bee0,d4e0b0c5,114fdafd,410cf720,3ab35f1c,1eb2577e,fc2ec620) +,S(5fc5177f,e0b59e31,e4abef85,31f3fbaa,e3399bb4,126b6119,c7acac83,777cf9b8,adf27f69,b613fa62,3cff72eb,4dd10b4c,4009b73f,2cb885d9,57ab8c78,ca705fe9) +,S(1017a9b8,5116ce3a,498888e5,7a408f36,12a6e8b,b18f6961,d6e1d2e4,38902928,24f7a939,5e0d3c0a,579ae611,b733248a,640db7da,929edb24,b11bd617,3e573658) +,S(d9ea68f4,6af94d9d,232a5deb,c485fed0,d719cdf3,2afe4617,524958ed,751a2c47,e59f2193,db2fe578,642a774f,c4fc8515,f638d1c0,ae8081f,e9d3c0a0,fe20410e) +,S(61d975c7,e4d7e262,5b067179,667325c9,a32ef6de,a0bcbcb4,a825d89f,de6f7aea,b7a00d17,5a2d827d,37de6c8,667bebd9,da92ba42,4efeb706,54092342,e644db9f) +,S(2ff5cd3a,fefe0c25,bbb8245f,c9399409,83194bf8,f4599f3,101e9d79,b7f8d9bf,3c154b7,11964aee,5fe9175d,deacabe2,400350e5,3ea1ba23,20d9e675,5aac8fa9) +,S(cb438486,954c4a00,effd88db,29e0e61c,f9fef94,5b42bbca,8939e0a5,dad9e8a9,920ab096,41789957,6c3a8ab7,249ae2cc,73d1443f,5c650ad3,4da9d473,221de71e) +,S(9aaeefc2,889948cd,f59fa4ac,352204ab,46aa399a,c848041f,446be421,e0e4758d,8e4d2899,2ef8d6d7,3e1e118c,70729e7b,4e0bc28,69d7b5da,72df7b46,38fb3365) +,S(ace47cbf,846e95f2,9387dab7,6ed4e272,e32f6215,1e745738,69f2bfbc,720c78f0,a35997f8,37b8e86c,3b4377d9,71098d88,95d6a008,b9d65552,b1385a4b,49c53d3d) +,S(66610f69,1558942f,8285a9df,3081e431,5c946a5f,df958f03,b2ffde5b,c591850f,be93a2f6,53a8630a,ef037f8a,624e623,8f2ad9d7,3ff4624e,f4240cd8,d3495a98) +,S(db4bc8b3,7a12e950,706e148e,4f07df0d,a24d1de,615f2201,2dc1befe,f1ad95ca,fd55628c,c260a1a2,e56b95ee,ebd6b854,f548dfcf,2c4a6b99,7c4e95a0,a52c4894) +,S(a2a7aebf,58a9a58,24d5a996,da18958a,5fc23d8,452d13b2,b254d4fa,bcba959,d6440764,1642f25c,8b31a117,cd7ed90b,dcdc54f9,e652a818,bfa032cd,18bf085) +,S(2d8846f3,fa8a7a0d,408f8ad,bd76366f,4bf7bade,c255e2fe,595e4e22,cfe86684,2c0a7297,228185cd,3b21c10b,5c7f490c,b01bfe72,9513eb63,f2716d27,f0fbe19) +,S(27ba20c,a44821f,d6ebd41c,8c29e584,6237d8bd,13b3eedb,a82b5aaf,10a6fc59,68d65fe7,b511bde2,f922f119,4bb411a0,c000b4fd,268c2c86,e14279ae,9a63e42) +,S(c2f0b611,3a6bebe9,22ec3e97,a3962280,ab0b6713,76a6778e,5ceb73a7,e2894b13,27b90863,65989917,68a9635a,7f6c674e,71a433fa,ce4f1ec4,cd775277,89d290e8) +,S(8420787c,a0df74fc,5c81d19e,64f7ed56,8bc54a2c,ce1c5714,1706888d,bdf377f8,4a94b5e6,ad402877,dc4c0df,38c7fe41,d9e6e085,e70431e9,99c2b724,e35ae74) +,S(29d08c36,c45715f4,1eb5138f,a5c2f002,b4021f2b,bdc49592,e4242443,1f4d5f0a,903d61f7,2e81352f,582ce3b3,ead7b6f9,e0340c23,6925882a,cdb41285,6181bcab) +,S(ccabdbe,f68b6549,2158d4c8,91dd1d23,efa7a84a,a985252a,3a1e895d,757e5f10,94a0e915,2addabd3,d5adad5e,cbcb38ec,e1a045bb,9d7295a,92aee49c,a6f0bb4b) +,S(5bd30e4,9e2ba9a,745c6ebe,434b8d4f,1d8c34c7,6d478ffb,2871466f,a3ff23e4,1067b3c8,5980ea3a,dd1a4cba,8bb0b96f,ad988cc6,4dd8e206,51eee853,915226ae) +,S(eb233898,8f12eb2b,5369d9f1,56d754dc,8733745b,30967e17,697e69c4,4fa80493,c258bfa5,e993ff4a,4a9eb82f,ce1530ce,25fe74ec,2bbc2639,683464f8,a26b5667) +,S(4b44ca53,f01e1c64,8ff41a97,721e7c3,b0d62b4d,b15c5bd5,d84621c,4dee2ace,d8999254,b359a155,99e59761,f42639ad,27caf87f,ed4ddc57,203fef6c,9abbd922) +,S(ce5ef1f7,6cef6b65,35631e65,d4f47924,df370ac8,ce059a19,5455fb1e,b156f7a1,74c9b95a,a4dc212c,3e127bdd,266aa89c,a4773f27,5607dff1,4438647c,f0e50a60) +,S(563d7e99,40325aee,e66557d0,b14b7e8e,14f86643,de2b3300,1bcfa7f1,ef788bc4,ceebeb99,9878a305,1a8bd9df,bd6cb2f7,3ac18776,ea78df41,30fd22d1,bcdf37da) +,S(ff929868,fb5a1b53,6acca702,f5dc1e83,efe8cb96,f96a3303,d107c6ae,ab5dbee3,82828150,fe8fbb3c,f2bfe03a,3c79fa5e,67c33d97,b12faaaf,572b1455,6ae11969) +,S(1004e4ad,487212a5,8af57ea1,49e0edae,6aac884,2f488bc7,1b75a5bd,4a20204c,88d9a6,164cbc21,52d60ee2,7c8003b6,b39e418,b10c72d0,504a6a7,d7b8b2db) +,S(28dca143,206abca7,1c48137f,8bebd26e,6c79666d,ce164fdd,ef1ca7ac,8e141a25,ec1dea42,575e5cc0,804f6da3,21ee739b,ff244cb,2b299413,4b8539e3,88f7ccf7) +,S(cbb81690,a7e511bf,56a5190,b9366345,7b4fe8f9,64b8fb57,36df2067,28e1ca48,c2d2686a,5405dc79,d6a2deef,95a97813,4a434309,c5303985,f173015c,6571e5e) +,S(3e1e663e,378c44b9,b61d04ca,bfaf65fc,df6b59a2,ae83719,11b11582,978f008f,bbf4b3b8,2010fd76,70d23b07,6018708e,8f78d70a,b2da1efd,be668c9b,d5125d51) +,S(7f742a3b,9edf6aaf,cfbbf368,5a622318,1a6c3b5d,588b74de,c2d2c049,91d97784,238a4f6b,5cd25489,1b8aa5bb,41f253e6,6a59a020,bce98966,ed4c75f6,b7939e32) +,S(f073f95f,f6c809d0,9271eb48,abf35b2d,b760caa6,54b0969c,e327cff,f806f43b,6a7eb8ce,9e297e07,170e9287,7fc737cf,bf923cc1,e72efdbe,5b3b4920,6602746f) +,S(855f6451,5b98ef1,67d3a11a,fec74625,cf3801ab,75df42d2,1b33b1bc,c36d074b,6e8cb794,9990748b,f54a9291,e7ec374f,a31bef56,ed1812a7,7b2ef00,149938fd) +,S(f0164c7,f204384,d3235b4c,cc1bb9ed,bb10cabc,d69c02b5,aed1dfa9,56c74d49,872fc547,78580a6f,38792974,a64399b8,cd674622,659ec31a,91fea06e,77e27118) +,S(16e83238,e95e29f3,ebc297e7,fbbc77eb,53431f3,cc90f809,1e540457,aced09bf,3f3c0ff5,754630bf,88ec765c,a5c04da3,f6ca4ad5,e72d9c0,715cddeb,69c4f8b0) +,S(70d371c8,8b2e47a,47982dfc,bc98ffd8,324b6bcf,2f1aa2a8,f4815f66,dd4949bc,34cc039d,3c69b4d1,833375db,e7315340,bab2452b,2a82163b,dec73702,f4c8da46) +,S(db250b65,6848570b,5a59a2f2,d45e99d2,de1b3813,46fa6ce0,8bca0b34,57c27d10,2859a0e8,fde87061,d7ea8786,f5667aa8,b2633e8c,c52926cc,c5427d64,a7ae6494) +,S(d6ecb3fd,b1ef3350,a2a831e2,321cfe9b,6b22b38d,6a8fa0f,b256f2cd,ac73f949,ad83f35b,c1b5c568,49436cfe,6ff17f5e,8abc6891,e24f4a0c,524d88e0,6c3f1028) +,S(ee2059ff,a2c5bef0,646bf76d,ae2f3bfa,193b8a28,bc74cfbf,a96b48,921ac0d0,3a8f4693,15d6a6e2,2e57edb7,e5897039,153e0283,8d66b1ce,1814ac74,195379e7) +,S(6dd7fa4d,bc12da89,1669cf7f,b1024a8a,551d7281,83fd221a,7a0ca9a0,8c2aa725,67fe6a0d,fca0fc02,1fc89584,d2a5f19e,ce890708,490c79e3,cdbd43ad,ad24493e) +,S(15102e09,b966ca25,1a9b4609,16ca1229,7ab64d60,980582e5,e8bf0e4d,80fd6c35,7ebf61f9,956109c4,3cfb52ad,4e60078c,93ea653f,17c7328f,9120545c,48988be7) +,S(a0697816,4a0511f9,3a48efe1,de74992b,54679aaa,a99e328d,6771386,945e9039,92d24154,971add65,c40e6f32,a5b5fd01,765effb6,c8d64676,c9d97e8b,f857d630) +,S(ac925df1,3a9ce7db,18b9071f,f81880f7,c8ec97be,4b78a31b,27917d71,da0defce,6347aee9,abe9b2bb,1f1e3ab2,2792009e,ee009011,337fb184,d3f637f3,186acba6) +,S(74f3c7b4,e237db77,9229cb2f,1fdba8be,9ba990ed,6dd84976,ff92646e,55e21091,44e9a71e,a07e4254,c4dae620,9c437873,7c56187f,23f42224,3167e45,932055f2) +,S(78f0a024,f6a5bbaa,f3eaf550,92a55bae,73348e82,37dc095c,11ee34fc,3194eb00,54e9b6e7,2f758d54,23d5b9bd,b329262d,6745eb32,c93c2571,f86f40cd,1cfeeef9) +,S(83d3e538,92d722a4,8c006910,a22f32ad,2ff7bdec,d9bd2ea3,a2f315cb,550a1bc3,a4f3c8e1,732b23ae,9f21c03e,7c3711ff,687683c3,13455107,68278332,8d9a25d0) +,S(15deb2e3,f0f0b65,5edbb7d1,8d86cedd,7242a693,a271d853,b468d57a,52cbd647,7cb1ea70,8e12acb,6bbec5ac,26f513cf,51460493,9db6cccb,ba712561,a6f4a80) +,S(6fc5c841,eca2637b,67fcd5f1,3c3dbf40,3b00e4e5,270bccad,617c58af,ac54195,afc3fc7d,92f0f77c,5147ae41,8aae93d3,b5cb7785,d65e623a,391d6a06,1f82d4c4) +,S(154dad09,40e83686,d0942998,e220f8b6,bd106af7,beb9bc66,1f1a4c2e,29300f20,9a47095d,b2a357c7,16d8773f,18c953ff,dc0ed270,1cd881f,f3088176,e61bd7ed) +,S(a498ef6b,89b882d6,81ea0647,f83d53aa,d1fb39e6,6bba74bf,8008a43f,197b301a,cf4d289e,f723ad46,27edc96f,5315bc2c,9ad39c04,4e8e6785,222ca142,3f5c2881) +,S(5c01e4d2,465c3326,1828c45d,bbb2cf69,79cdb746,fb659a6b,44f0f2f1,f388fa3f,315dab9e,5e53f939,610e9729,3e686d33,e46f8262,5ddfb45d,46728b03,927a6837) +,S(d058f58b,255164fe,e6d60472,2b32624b,2eb523b,6c7f1e6a,7ce1c248,fb3fe505,21761abe,1bcb844,39645310,7a3dd2ee,28bb4dc9,93dcd0e9,a09d5176,1a7c6536) +,S(eb89dbf1,67c1352e,5ea2a7fb,206663b1,8c95d962,cec35412,3b9be6b3,51799ca1,9566074f,ec54174,a49a5f84,e4965174,408425f2,22d485ec,b020740c,74b08ef1) +,S(19ddc300,84dda580,db5b1230,b0fe9508,5575eb10,680181ff,ee0d521b,17b39cb8,6af18172,bfb03b77,db456836,b9617f05,bbcbcccf,f6ed2dd9,a9c6e734,c01d188f) +,S(66240aec,7e72f707,69560e0c,f31f2c41,9a8efab5,32f17f59,19bd56e2,93c41e13,16fad661,3600a79d,41eba5b2,d0721dca,afe94372,fe83b20f,7178e29a,e6f3949a) +,S(3c75905b,9e7c7751,9f4617ff,6010c39f,92b852fe,89dca73d,cb3f15b0,23f7a286,799ffb8,94fd4f3e,61dd489f,da746fdb,ae955eb1,3c8dd9eb,e4f73d41,2feccec1) +,S(9719a34,e765cca4,68ab3453,3c6dedd1,6247af51,b73295f6,8b936914,c03f10a,4d4e7f2d,ee3aec6f,71fa8978,f532e995,c0e1533c,5cf0b51d,f35d8f8,29cc10ec) +,S(e32f292e,e5c41e2d,bd262c45,eda0b729,713207c0,17fa5c47,c8bce6,ca550814,105716c5,5995ffa6,998f2209,b9d0b37e,f2bd78be,527f6c12,b707faf1,ef73a82c) +,S(76aa4115,595e7656,c76300d0,a60e3316,fd9c1b60,d41920a6,128e59f0,74a9dde5,f3ca0754,b6daef99,acd6e1e6,fb36d93d,e068c0d2,26b843a6,e7e111e9,9df8efda) +,S(215186c7,ba018fee,747c2030,f57d1105,945b021b,be053da,efb1136b,f0d6f0a9,62994ba3,62d9a8a0,7432690,689a859e,ef498860,3d52352b,e27e0f8f,d02e4de7) +,S(62e16f47,4d3ce3d8,a21f0c8c,875eea7c,111ca0f5,21c03f54,6bcee790,ab0d48bd,e9a8c8ab,99f916e0,4141972c,f60843be,72088d1,e044b27c,6a84b21f,c787abb) +,S(372b5966,8b00faaa,a714e7a8,2462107a,3d1226e4,988faafe,988d06a7,dfb27bd0,c6d349aa,6a53d0bb,185e0f59,a4c137c,8622be1c,5df205f3,4b090080,bf4e4035) +,S(b11cb8c,cd6302bd,e6005ed0,9a1ce2ea,a81fbd9c,748a17e8,fe1c139e,d2d1d725,29ec84f8,e8d627a6,b81a63c,4b13abb,88d7e5d4,9e56e2b9,a3f15f40,60efa38d) +,S(652b5427,f45d07c1,8cd9afb6,7d5743e2,836d78f3,528917fe,2a5c6162,c4a06d81,3e93d9e4,25ce53a4,915bd12d,4327e89b,64a7112c,5ebae53,35c631c9,64b2e5f9) +,S(c0812ee9,89fa0531,56847bb4,edd517a6,7d6d7d0,90ab5955,a59326da,f3833afa,2450338a,cf923109,d67b0501,3557f310,f3b0550a,8f1cd5fc,6eef8a5c,14b46c27) +,S(627c169e,fb0d9937,8ddd0fd5,a73afa16,2a317e56,7d957695,41e52a41,d9344ca1,11dfbcf7,75bafe74,eec503cc,22c8b485,90a17079,580acdd9,c51158f5,efd0cd7b) +,S(69916299,5b83ba3a,6bf16e2,97e8031e,74dc9054,c05ab59a,335a8296,d876a66d,39e45d50,aeceb888,8a1d64ab,9cb3b127,71269b7e,a14ca4eb,2179d762,4ee6d953) +,S(6693adae,579636f3,2332a418,7e49ffc6,921aa51d,852b5136,9a96c8e1,cc268574,ae73a660,580a4005,50865060,dbe9ab43,2f304ca5,506b9f4e,7e17f602,1456bfa2) +,S(ccc178c,7168ac1e,e7bf7579,f75f9645,5ca2b558,e1e709ee,de86df5e,5ebe0789,81c63b04,eddbf33b,432e00c5,9e76d319,fd1ef2f7,d6f31349,1f7a3c10,431a2130) +,S(d80687f6,89f7c28b,d6ef1531,c4e4b283,c6e5dabc,ad7fe5d9,6dc20d30,e1feeea2,71e24cd5,9d2c33ac,2b298946,bc90e0fe,d229720d,539a6f5,e128973a,9bd6c5fb) +,S(c53a6911,88f785f3,efc1fe1a,d142a259,cbda5f76,f3e9de36,895a8963,ffefcb74,7a225bd6,a348728d,951d55bf,257de9e9,d88df32c,ff2c4391,f4ddae8e,ce357cc0) +,S(d512c64d,1932fd1,5636740e,2bbd302c,3d8674e6,52a30d40,ce879145,bed9b7c1,52e336dd,3c7eca6a,469bc97e,a330fa03,1cda3c57,a4354ba2,acffcaa,a1e6b424) +,S(384aed3b,531098a1,99312d65,74b1b1bb,e79a8bf0,ea4f7a86,c5114fda,b32061d6,f2290bbb,2bbe7b53,eb64f87b,17a9e1,49356d9e,de3c0be4,28a4dc7d,709ef731) +,S(6db6c2c1,1fbd5b92,31a4e34f,ca2f9315,dde00dee,909b8d53,d7149c6,6e3cecb7,cb2f0b26,e1bcd464,6e6ee074,8efcd499,f535a8ba,f61a38e7,aaae3511,3c781649) +,S(6bc2f0f2,c0118efd,4fbab4c4,90c56da9,d66c0b1b,ec88e8b1,c8da967a,95d1ae60,a568f40f,24e51e2a,d01c13de,4490f34d,5a5bff13,e005ce77,94a59128,f6d871ae) +,S(12e4e92a,aa40ad9d,281316d2,358bb0d6,c69fac28,24114a9b,a96091d1,64ee29cb,f717cba6,b07eac9c,34b8821c,218519c3,886d5cc7,a22be959,54b3eefa,8819bb51) +,S(6dee0e1c,b887e155,e67996de,92716821,7874f9f0,a14c8673,1eaba91d,272705b3,28d9f2fc,23807874,9dd40ac1,8ace2dce,18ac3980,7c7a5922,43260eb8,ededbc3) +,S(f9d667ac,ec2120aa,50c2b6f0,810b54eb,4928bef4,779e2311,7d12eebf,d093f139,29c9458a,52d4cde7,e32a265b,fb537b3e,5a5fdbe6,ece9be95,b645b960,c160166d) +,S(e026f66,af79f4ea,52955b52,bca16e2f,b2cb05f4,38568c06,ebf1ca25,e6f5be17,6319ae60,3e733681,c8caa501,d7715b98,6244c1df,1c42d391,d8d47e15,a681df15) +,S(1ddd29c9,bbb37823,1185f631,23d5e1fd,39c6b03e,44e2a542,318a6f3e,8325ffb8,22d80158,cee2f596,8da360e5,93a2a86,ce1ed25b,77a4d66,a2e7592d,26c2c715) +,S(138f88f5,f9f46b81,2246373,6034958a,d5476a0f,348ca538,f789e980,9c799f30,adac6393,3e2de680,6fc38d7b,23ec5214,43ab505d,cedde216,6accf786,bd4e4aa5) +,S(b516a9a9,4630ba5e,7469d5e5,ee0f03c2,51bfdf5,a1983506,79baca9a,e6de6f6,9c184956,7ad68859,89a2013a,5a902fea,66d398e4,6c85203e,b7a143b1,90b42587) +,S(bb1a5499,548ee5a6,79500a49,a1466b11,9d56918a,735c3e07,31939ed0,2d47abe7,b946e966,2df43be8,6478e809,ac690d4d,b25398e8,de13731e,89867f80,63f8021e) +,S(394ee032,8be13bc3,ffa069f3,92b72070,36ad018b,503ed70b,9bbf9f7b,458faf36,3a494b0,dd538dc,fa3a10e9,70b83c4a,2169b4ea,255c6423,50f7ee72,40a6910d) +,S(a021889,ce4c941,606c0226,2b423afd,f44d6a75,483dc4cf,797b3512,8131e2ed,d8ae98ca,572b5a38,cd10a763,6638c47f,2867710,373af6a1,bfab6cc9,64b26547) +,S(99e2cf77,a0f389ad,a6c21457,d3e94ee5,95fded19,89c326da,3cef2e49,670f2572,8144a88c,a90a7685,ea3155ea,8fa5cc0c,c282fc25,532aa5da,84494b97,94810a1c) +,S(23c4b50e,80278869,b77c62de,8232a70e,52a4a3c3,4d0d6114,78989746,54e57aca,afba6a63,e35b15f3,1a24e5b5,844b0f3c,b247deee,a764b3c1,1075c3b8,c65bb0b5) +,S(ae0ea240,91b09648,6bd06ec7,ab6dd488,fd6669be,58c2e91d,e8486560,47493d5a,63e13a3,aed0b2f5,a11e914a,3617b1ea,abf62d4d,731eda05,62251d76,939aea63) +,S(d9e9ec51,cea0b150,28199afd,70fa86ef,dfa90e86,b9613831,9cbbeb86,c6573bf2,561519ee,f8dd5ebb,df47d4bb,c24eed76,5ff4342d,6ec6e537,8a2952e7,db51354a) +,S(e674a628,7472d602,8c0b888e,1dc86429,207e38a,af61d3e7,60708721,c1a44613,c145e723,eabf1dc7,f09fcef,1ae24116,1bc0d24e,9c96c83a,3c4e76e4,cdbb9e7f) +,S(19a43fb6,ad571142,42644af6,a3ce367d,329f44e5,bbbd8948,9368620d,944f413f,29a616f2,5f2bf4df,e516574,cbe840de,9ab9ee1d,abc86ca9,6413bfb7,a79a4095) +,S(cf1e1a87,32eb52e1,660186f9,6aaa4cac,9248d8ef,2738a6e7,5e600f3b,658825d,379dd9a1,8355ac8a,94a9614b,e3f51540,c17a76dd,3e3f853f,252f0e75,164dd346) +,S(342147b5,8a1ac1d0,baba5b2d,e924e7a3,b804e385,466f5ae8,29138bc9,5c5b386b,9d8792c5,8917aabb,6a3cbc4c,7f18d2b0,768dc9b9,1871bf48,8ebabc00,f51e2bf0) +,S(1c24e35d,35fda6b1,f6ae6b43,7599ec91,dff1fbb3,b3d26976,783c0539,a8b9af32,58591ff1,68290b12,d729c621,f5da504c,e697ef00,7d922152,9a76ed61,2dbe8608) +,S(d0fa4d47,a29e1101,baa08cca,73e00d6,660e2588,6e1b5cce,ee1c2a5a,9fb806da,918cb1f1,608f9e40,37a59bb7,28c25708,db898d76,a8b2e2b9,d4450c64,3606212) +,S(f3307ffb,7e72413e,2207918d,8a93f183,d5cc93e6,ae07d196,a6d22f1d,253b2499,8a44b83b,feffd6d2,78442d72,51929c0d,42b690a2,d91d99bc,c5dff056,d37e1f27) +,S(77e612a6,9931080c,7d910573,fe55582b,30eb4ca4,c7b7fe1c,9c4eeda9,b296097f,cc85c0f3,6f020bb0,9705f560,15268e36,bf61db2b,814b51b7,c958f1a8,656c26b8) +,S(fe3b3fdb,b8d768aa,8248087b,70e6d0de,592c95e9,b9816996,a3b4c88b,21bb9605,23b44ffb,20e8fc95,ad3c035e,3f52fb53,51291965,95fbda63,8a192cf9,43630e0d) +,S(e664460b,253050fd,8814a2,b2bc0f56,fd8d2f53,94673a67,9a76eee3,f7ae6e80,bf0a7515,a0a6351e,62bdf527,6974f06d,be87345b,438eea33,ddb980fc,788eec9c) +,S(b8ab3266,6cb96b06,a363d87a,a7ee820c,695b7372,b9341b,292dd0f1,d5fc35af,720da144,39ac9d53,c480dc25,5eb45ffa,b9e406c,8eb5bae5,1c145058,8120f900) +,S(38242b07,d1904c72,6da9ca1c,f1acced2,96c1c4a9,b37671c2,e529917d,a651b99,3d47a793,688603a,d6ddfc87,1c85a19f,e21ac51b,d292ff7c,69e219e5,7a0dea85) +,S(ae9a9354,e451abb4,454766fb,7eaac21,5982008e,6cd47d7d,df5a6289,27131913,46d291c0,7f99fbb8,2eea4c66,525602f9,6af5c16b,f4c31ca8,c26a831e,a39985f) +,S(59e59fd6,6a89a538,f5277950,816bf2dc,7070f70e,98d04b95,1b83a80,dab205a9,cec6b519,4d1122d6,dd3e39a6,fb3e80a3,2d829158,3ddf0bb0,3dc3086e,9f247f4d) +,S(59aade5,c117e92a,97ba1785,2e1ef3f6,d000620d,a8f82e2c,1d4272d5,34a8e22a,6a6b6ab1,bd9a69cb,181538fd,eb4a9e8b,eda75811,96ef31ae,deaf516c,e68c1cc3) +,S(f29d02a4,5b464774,fbc1bcd7,7caaf22f,12efcc9b,2a569966,b9adbe8,18a9f075,ba87956,5e0a1c56,fd03175b,a781110,3f34542,ded10367,6d44f706,7b8ab418) +,S(db630bf6,e9ff0092,eebeebb8,a5bc72e8,774c083,cafa0519,2e6d913d,112181a8,6b764e8,2213a7de,79b9abe7,edabf502,d9ac04c8,eb5a4b26,9d22b666,f657685f) +,S(45b9f064,71b848c7,48ff3fc3,34d425d2,57a71abc,27c4d002,dda26c77,1b09d2b8,c2119389,e4cecaa9,c0c72e4e,20c95cf9,1acb1698,c0bcfd42,f8620a9e,d781de57) +,S(d4919e2,3a278aa4,25bb55cd,2fdcde2,eac63058,4cd57f50,390c6a9a,1015ffb4,f8e9f461,950f17fd,8c46f04a,3a6f3c52,5318cb93,a0aa3f3b,bf90c02e,80e1c288) +,S(ea000677,2a76378f,3faa3c1f,c7227cc1,4b11764a,3c9a14c0,4f18f9d0,b55acc46,eafaf0b5,9a308182,8e6d07d7,2e16509f,bbf76fbd,e1473e35,18b795c8,87ff84c6) +,S(70b539a4,4750f763,be1145b5,b433e98,847545a2,8fc72986,2c17045b,f0d6fded,d5438ebf,18eb5feb,fcf6edae,4fcca2af,e0208adb,2f82648,2af428cf,bc761464) +,S(10b4a235,99ce2be7,fdc31f8e,ad91523a,47b8162f,8ed9387b,4c208657,25fa88d3,773ef1b3,a3943b86,729661bb,6ce6f4ae,e8c7165f,97a88fe9,5df9e027,3ccf9e7c) +,S(67d7633,499323f7,cc378c5e,2e62cc6a,5f34ff83,e11e6061,9ec4a404,d63b91b7,cd7616ed,60f0f4fc,1006dcf1,850807d7,e8730954,30db6761,cb7cbbf1,a9c2958b) +,S(5744c77f,8371057,61b1c782,1c9d9c53,14219e1c,5df80ea0,f772f9fe,ff157aa7,578459ee,13ec92b8,b685acda,a153f24,f6c844bb,e195ad58,77364ead,7a9e5fa4) +,S(7c6b254d,39ab709c,cd63c2c2,56c43483,183b1b27,25ca49a3,19753f68,6486ad02,5669fcba,d8662be6,2d12cde6,30102f3,70f7ef0b,5b347fa8,6000ae6f,497fad6a) +,S(8ec715c5,bda8f9ef,3b197ea8,a182a3dd,6cbc3b8a,88227e00,53a2eefb,b2006676,e59ecc81,aea7f2a5,4f659bdf,a317bada,3f8ccb7b,134ae21d,733b9710,335e73c9) +,S(fc7eb1e0,95d0b18,58d22b5,ad36fbac,1b513d86,2bb3c9ef,61b55a5e,985e642,7206dfc3,10056bcc,4071e9f8,13495744,dd903d72,2aa0d6b7,3fb35394,4b66c85d) +,S(4954bd00,308e205b,90c191ab,6262daf2,81939084,668c43dd,1ae998d7,e143f1dc,8efa802f,e67f72c2,5b4fc279,4e23608,7b343d89,255272d6,3c3968c8,7f26237) +,S(f27e6c84,f60858e8,2eb53d39,a6860189,9172da9c,e0d1ea70,9225effe,23de6969,90533e33,321f1f5a,ce37ff79,b4dd3109,a1efd6eb,de502aae,4dbdf58b,1e697c74) +,S(166f3aeb,cd040509,85df120,edf55c1b,f6eed0b5,fb24173d,c7d9125d,d0b2b29a,54b8de8b,c24b1cd7,8f89820f,d4b3ac6a,1588ebce,6de99b9c,81773ba,5fd32e20) +,S(c0797522,8dabaaf2,b46108c4,88ebd104,b0bfafdb,b344b5e0,72f6cb6a,f58f3cdb,bae0280c,704e0d0d,2d421b20,828cd00d,9b388f32,fcadb511,ad5ed4de,281a4a29) +,S(81366739,2085f96c,6a39c9f5,ff60b51c,4991a289,7106619d,1ab0de9b,34de87bc,d7b8599,2464c1e1,9f575cfd,de5bec08,987230b6,20d911d5,d6dd3d2a,8a75e079) +,S(335f446a,f3964e77,8f4985a5,c19e371b,876494b4,467ed700,482558a,9cab3c65,6e8fa42,24cd52c4,b78af9de,b7efa726,c26a94d,85bfeb6,fdb1b97f,674cbe6f) +,S(b6a34b42,bf5e4781,df14fe99,1a14b414,fa488da2,29314366,1ba83ecf,1e80d60c,b633c9f3,cd359dc9,2ce47287,670fe80e,131315c1,6fc17811,f319f1e9,82f88e8b) +,S(95f99013,a9e937e6,ff784b07,23287960,5eb4532,e16b3881,25a18012,17ee3ed9,2d0fa2ee,1aed211d,5b90915f,f3b2116a,28528f19,35b6b534,333b102d,177c08a2) +,S(9c0923b0,d681933,bc8bca36,a6af4058,682c5661,95d3a211,a1ef602f,933f6a45,a72df8d,a9a951e5,a63f0424,4974d74f,fb809cf5,fe7c24da,9c1715a7,2419c7d5) +,S(931cd34d,e32188a8,802b6a73,204eadf2,cae8d8de,52423daf,daf042cb,946657f1,d84b7406,d58c53e2,89ca15bb,4ba78db3,6bd2947,34d0ee9d,6939c15a,9f28b856) +,S(24be4b41,f845c43b,5fc594ac,90e3e4aa,b49cc79c,4b0a8408,1803c27b,ce62fe4,c6651cb0,be54ab0,78940179,6dca2448,3d9349ee,e45e78d4,b786a636,83861bb9) +,S(f19a51c2,ebff1d77,81b0e7f0,a29947fc,3ed9dd26,9f0b9cb9,c27c3f7,500c81eb,8e1cfe92,6128173f,556b3ec4,4c394ba0,201a4f93,e2db054f,63934b2,479a301e) +,S(f6e7e4cb,88ecad49,a1653a6c,5510571a,cec77024,2f490774,a8dd62a7,d6e16363,60842dbb,b8ae082e,9538e725,1a3dd7f9,8edabff3,5444719d,97134a3c,236c97b3) +,S(e7b7bb26,af8cc2ba,6e54e923,6af55e40,7ff704c6,1264cacc,74d96b52,81f2ca00,3abaca16,e20f74d7,6d11a942,415987c7,8da5ed50,3d781f2f,aba6d534,cbc3908c) +,S(c8acf1d3,89a29f6d,e0d03835,80a0a562,aefcaa99,b184f910,f2c8370b,bedc4c16,924e9b2e,2c6463ac,e8eda0b3,feee2f82,73050559,1071bbcd,72f6e323,31617359) +,S(1453b2dc,efe09d16,373ffc2d,42e79805,64ff194c,6b9944dc,b12d3cdb,1d84ae27,2d7faeab,7ca11212,a1aa9d4,a462c04b,8dacd2ec,1f7ee3b8,28fcdfb7,a26c6e17) +,S(ae92e090,b3c6ae15,68a12c6c,882d1b4,345f0a46,b9ad364,bc869243,dd533f4d,3f50449b,a3865900,ff63d944,27a0b967,56c00179,5b5f51cd,5996ca2b,19ad7abf) +,S(3086b503,ad8afe4d,fe2795f7,c972e0c0,8d6f040a,1be88309,606fee4d,b977fd06,b8631fad,80689ce2,7f62db6c,d6a56f3c,d3dc110e,610f3732,fa3f2c10,a4d588d9) +,S(7a17def1,e9c2b175,9944eb35,262908e7,c988f602,2440e151,928dfb44,462e2856,42171a1,f71ae8ea,d437a1d7,e1ec3394,b713044d,6c895930,2535787f,b93fcec3) +,S(97975e9e,b0698b70,995411da,37ce2a87,91198b90,e104476e,b86c4a77,dc5ce9c4,b8999b7,69b36de2,13cfc81c,c2fffc3,65e5dbc2,db1906a0,ec88e931,cd05bd41) +,S(839fa603,a2ec722d,1253328e,15f7d187,55ee80fd,b6bc7b09,bbca59eb,316d1b22,4e43cdca,1b33fa9,cf397ef3,91d40b46,fdcfa770,b2be8e9d,9ee22d61,6e12dfa9) +,S(ccfb8b97,7baefebd,eaf49c7c,1ddada20,861e1c0d,acba4caf,4e30f21b,ca3a05a7,7d9bced6,62579237,a348071,3ea1af91,256e9d62,1265fa27,cc80b5fc,cf75f99f) +,S(8f9f369b,3f325823,e8c9b16f,f2142ebc,3c6f7bfd,dd28c4df,63d1c92b,581cb6a4,114c7d9b,3f54f549,c10d93d4,25843477,9c297e2f,3f07b208,12335fe2,5771b12c) +,S(f0deaa5c,324c5ead,6f6f1cb0,cf1dac32,ef342606,3533435,65ac164a,ac8f0f2f,ef6dd597,e2203c03,f0ce0780,bcc1e963,621c1460,7a4ce616,9ee6624d,11c2eee9) +,S(638362c2,18c9e0e8,72dafa8e,fed86fcf,da5641eb,7cd01725,9a85103,f04fa408,3c224389,bff1fd09,338ea28c,7c9a93cb,32be8749,4a6c629,5c1c3dff,2b582877) +,S(49acbef2,64708117,a53f52e6,84bc15e9,d004baa2,fb3a756a,72d35efb,49871759,b678efb3,fa09158f,d1f9c74a,87a56883,b0a8316c,d4848ef5,1f35dfc0,8c4b5bb) +,S(a79d63c7,b718cd66,b393e70a,f032bc50,a90209b2,5f5b07c0,303eb8d1,1db618ee,ecf7f89d,2f6f9877,9b5e390,ce5837ba,49bc2b3,a7c1047b,7a7c852e,89f1551a) +,S(c922d543,f192f654,3445d3f9,c36a05b8,2ee043e0,92afcae5,a21b9b17,a06d0257,cf77d5eb,9e555f90,34ce1c14,63f7c4b6,a0202d81,deb02ddf,a26113ba,292554e7) +,S(dbb8f077,b411a4dd,faf0d89c,3dc20375,1bb20e16,2052ee46,915528e5,1f461387,a6c0d5df,91cc4ba1,cbba0588,774d47e1,7ef97281,63ca8950,7ff6b779,da12b7e6) +,S(dea21a21,eccb1733,14d76fcf,dc6109c8,88a633d9,645f86e4,e59ee237,cb18110c,a1390d1d,69a304f1,a2792ecc,675f2dae,1ddef908,2f2e3929,6b9a068,3933264b) +,S(f088ed85,750dd58a,cd03b3a9,93d88760,34f50780,985f7552,114f957a,ce8904a1,b810e652,f596cb80,c369f61,f632bc3c,fcfb1fc2,b906acaf,c1f39d02,5e3ae4dd) +,S(b85da431,16b898e8,56fe3c18,b60a48b7,c2ba9f65,ad67c31d,f45ac3b6,608b774c,357d324b,474ae7d8,97398506,c550a1fc,5353a00c,7e6f1245,c0f57683,80ac9e1f) +,S(eaac0d2c,276000ff,899dcb3c,61b41663,70123276,14585bea,7704de95,d164514b,aad696cb,1af2f12,1ba915ec,64afc13d,a689719d,8f188424,25d6068e,9bb06a69) +,S(7a3cfc7e,51fbf61f,ffed3430,eb9ac40,c84164b0,21220837,29f20ed8,eacac977,9015b896,e034d2b6,684f7352,185e959b,5c45406f,6187930f,82f62269,d3ba70a) +,S(5a9def12,e06f0ac4,35b9f853,53db864c,77288050,c349ed7d,a8d8b109,b001a856,b63b74ba,868df816,9dfc30a9,1efbae1e,1617a230,3ed20239,9ecf5798,5ec4bf99) +,S(b937b3d4,287a0f84,5323cc72,95b4a201,ba9d97d3,2d968533,7caccbdc,ce8623ed,6f2ad251,a66e5ff0,77384746,9208db13,2a396dc2,17e781ce,9aa8d556,83fc0adf) +,S(d44f7fc2,97e079f4,ba0689de,dc743d4,964c6ab,8c34bbff,f95bf22e,b7d3c209,b5afe3b6,f6b02542,e6ce811b,f4bb0fce,79e7916f,fed8845c,dd83de07,9320a2d1) +,S(5980fbb1,6be7acd7,b090a2b1,c83dbf80,9148cc99,75fd6834,edf564c5,50fdf2f2,72340269,8d22b946,ae51c9c8,33d5b44d,ee884a02,e12a6d4a,23957483,32abac9) +,S(94733aeb,dce57a89,16961f41,3eb04b5e,71f0a055,29baf93f,c9ff178a,12b70511,e591b62e,5cf92ea4,306e16b5,acc5958d,a5516bf5,7a7dab17,db38cef7,44302c47) +,S(1172b006,3d5ae491,8699e756,75ddfc59,fb5cc8d4,f332ce72,f99fb99e,c9799d96,2845be1b,b97830d3,f9d04a3b,36ae381c,5654bef3,f3fa8516,3a7b9738,ed867ef4) +,S(29afd093,5ca567f7,eb4cc1c2,ebbbe8c3,bc405691,b41a2812,b7c71312,81bbe691,77e9a59d,c0aebd28,9cf2960,ebe7fc19,236c1859,7882df0f,a8e6e0c2,6d92b821) +,S(191c7ed6,72c36def,576f645c,6b475eff,793119e3,ebc3a29b,71eee3c9,cb52a635,642bdce7,90d0f104,54ebe4d6,282be83a,443f8f44,faba4c76,5b1491d8,c7c83210) +,S(237eff13,89c20d30,9902a738,fa4543d4,c2a4a2b5,6731603,500997bb,40d28eda,973d696c,ba9eb05d,73ce7491,5c1cf3d1,5a998608,7ce85854,f7bdd157,3d5c7394) +,S(d4985b52,80673074,53ec0edb,f02b9d4c,b1ce9a0c,af7c675,77789b8d,f3b5ab33,ad8fa145,94c510a7,830f3353,4ac94a98,cdf2fa30,b6a1b572,9222969c,e27eb1ea) +,S(3baed9b6,25f5d0b2,6e0132c6,20a9015,f79bd8d1,8e5ce170,20fed78f,a2238914,6ef88df1,3c7a9023,1180edfd,d041b950,3ad89f22,4ec557b7,2e900bc8,fa820c19) +,S(6e2298a6,102268b1,af97bf67,c0aba783,5463165b,1df8a824,530ee5d7,86d354f6,c3864e52,3bb5cfe0,a64adc7a,9e8926e9,876516a4,c83767d8,5ebfc39a,e125c19c) +,S(f9e87f15,2412598d,775131de,abbd0272,4d658849,cb60aac6,92280e63,8e835e9,e843a3dd,a30f9685,70fcf86e,86206c22,af40ce3a,3beb620c,aa167e63,271d95ac) +,S(f9925b7e,80b8b8b1,b5c56f80,74bd5ee1,9e419678,2c5a33d2,c59f8016,56cfbb0e,3e2fda0b,50aa7671,5810a8d2,2d4778d8,66bd2515,acf87b79,7b2f4875,dee19719) +,S(6fc34efd,5d11ae35,2cca3254,c5f8a040,52b81357,556d4d67,dd02d22b,91f4e49b,f14c656,ec946492,a6af3f2f,56fd7355,71e41b2c,dfeda7bd,ed567658,202f6e61) +,S(ab504458,4b38c846,e282038,1f02f55d,fc6a5648,1b1830c1,e4ee94e3,d11af8d9,4ad3821e,3f5219c,aab31787,2a8fbccf,f0f445d7,da30f05,d9523f55,13eee3cc) +,S(2378d11,716b6d34,85bd5a57,5c5b2c96,1b817abe,e21b7d45,38244933,5ce7e7a5,33682ec0,8c59a158,c4ef12bd,d2a46d31,6abc6dd4,f81a1fef,5be40577,4e03fab) +,S(cfa95425,8608d9b,9c568a1c,fd4b078a,ff49150f,a4681324,ac56b6e9,df569016,e200a3ae,2d82ddc2,a71767e5,842ef30c,86cd9b17,7c5e52ff,ac316e50,1e7e2) +,S(585542d9,a3a582a3,bde74fef,112924c4,e00cafcb,61518d87,f524211d,bdb98993,2035bc19,7a0ea2b6,8d1d1333,b5aadc61,c9dff2c1,e4dea034,1539ff15,9a3d18ae) +,S(fab2433,905e5b46,e47103f2,e353d503,cb141e61,2167cb4d,34946a5c,cd2c06b,7097d735,3f17734f,8eff6993,77916c9,884f67db,42f7a96c,62a3e1d9,9e341547) +,S(b10db548,be55521c,de5edc26,fa39716,154e365d,a1b8b7fd,2265d78b,7edee8cd,389efe1c,7fd8b4a5,4a42e651,b5c06a2a,7c153664,e52ef30d,90eda2d5,9e9690c8) +,S(218a8a36,273fce14,85c0c9f7,1910aff8,64910b00,6254af75,e78a6b5b,3d5c7bad,4a1984e8,e90d4695,b8dcf34a,55eaf568,b0fd34cc,528a147c,bebb052a,8e6e8604) +,S(e120bc22,fe6dc81f,dc3ead1b,a2ca966f,c5702ec,479793b1,5f0ebae3,b6c5ff3,9f92f1d5,e8aa56f6,1ef20685,c8085782,be180658,c7d2b9e1,c020c98e,cd425835) +,S(e83373fa,f80d4560,5ac4da9a,c9cfa220,b2a2c656,26857035,a228c93b,495be15f,8b915652,3c532657,7945021,d6c1b1a6,3b1fd090,ea93cf01,90fdb791,a2397a91) +,S(b7d8a393,a10590ea,91d2a495,eec07262,f2f43e29,74f7b2e5,6ba6ee92,17e3e74b,4ad6671f,58b2c7ba,7a940613,5986b3f3,5a6e13ec,8243b0fa,c8bec130,2afbad0f) +,S(75a5ed46,b2103f5f,ee808803,bf419bbc,232cf5d3,84955e8b,1d4fbaee,5194ca35,51b9670c,4c65e969,a5a56e15,25f33dc9,458c317b,6faf484a,186d52d1,757e4857) +,S(6d8d67cb,c309ecc6,3c1e04d4,aa42683c,775d5f32,51111500,9166c574,b0dd66e4,e127b8c,f431cf09,5939712e,c96d299e,efbdeeec,eeca3d2a,9f6b3d29,fb8f72fd) +,S(51a6d684,463065c8,7d3e0fee,ac72e4f3,1e5187a4,dd14d59e,ef71ee93,85fb229,7fe1069c,b384178c,ae2241fa,6886e1fd,286347f0,d2488dbb,f4d6eaf9,e722a90a) +,S(5140ba9e,81a272eb,30ac5c96,a8b054bf,870b1785,9519cdbe,4f2e6573,2a56e6bc,3b6a2c0e,7421eab3,147b61e6,d8252326,1819bd94,9e3c805f,ca2a12b2,e13599a9) +,S(b94c7812,6c60a3b0,48b28f47,f9d461e,27ffdf7f,93a3ee70,ae38962c,8060166b,bab7aa94,385d224f,f20e7c60,7f7f11db,4ec3526a,c226cc96,16af6a3e,356208f2) +,S(45046678,76689fbc,a94ebd79,ddb5d655,3e97b788,c91cee0,b62ee75c,1fd12ff3,635b3d75,a0621530,d7ff26cf,f1878d52,2864a6ea,e82b220f,d35ae5a5,edea1895) +,S(45f4025d,7b88ddaf,e39566e4,27060b7c,ac59ae7a,526ac3d6,a489424b,d677a54d,d732c322,18307ace,354ade14,21d13438,ac4c7c3,5b5021a6,cea9137f,b47465ac) +,S(c6e8912e,a197f39b,817b743d,deb3320b,558af332,96e0ebb,58c258c4,f1c0d5cc,6e0c8ecc,fd97ccd,deb08f4a,73ca13cf,b48d3633,afb74139,36550e0a,c23f04ea) +,S(6fd13fd,c7d3809d,6a3bf6b1,5208d0ab,5f476e99,57a7fc71,29824154,a05a7dd7,95922641,32be31b4,c34ea614,df6b8c1a,c386dbc2,1318868d,b40869a7,17b862e6) +,S(54fc0732,968b0207,ea2c115f,d11bfb57,b9b28164,4644d82f,45af1100,6b63d0b3,318ef9f3,b2173c45,bba5ffdd,8345a08b,66c8e183,80ef9dbb,b5d80c1f,15f95bfb) +,S(9e6ac718,6e09f698,1f384cdc,b9c48703,a8ee3726,d6d8ee3,a10499f5,e17731e1,95b4c37f,ec98faca,b41c628e,12f606e,79829b17,96ef3dce,c4aba99e,3882bc0a) +,S(85732ae2,eb7944a2,6609aea5,607604c4,c30f25ca,c365fb2,e01c7600,40542ce6,928a62fb,b082f38b,52890540,7b20f9ac,1f4841a7,bde217ab,828780ee,94749fcb) +,S(3ea5ace,80e47aa1,9bf1406d,3559fd50,85d38504,93752563,de66393e,37a652a1,db5fa543,142d36f,fcc1cc8,36b1f4c4,e82d4980,f2b277c7,bec53324,fbdc8e9c) +,S(7d40f7ae,f1866d87,8e42f9c8,d5afff76,2a427567,f6130f73,439d67fe,d14be54d,5bee61f5,31e4ebb5,679c9645,d565cf,f93b391b,f48c5504,a5054e23,47859d2a) +,S(3dc80cd7,478ea38e,1d6e1e41,aca892c4,4e4d8339,acd72fb4,c27861ae,3e7d8664,98412c68,68af56ab,19876499,fa30c8b7,8bfa5d19,b4aea0ec,52787690,49b7e3b5) +,S(2dd92155,81bbbcdb,a1900b90,9018ea30,2e40ec35,cf2b74ca,6065e8d1,f3bcc057,cdb59ee3,b5d42deb,5a4ffe56,46f5dec0,218d0e9d,569cdd3f,b96610ab,2a382fe5) +,S(a245a185,ed85c547,3b78a561,76a32e45,b35efe75,36a1fef4,569f4f70,ba510ae5,93b66fc4,6fde9554,1363bdbd,117073cd,f3f5e406,75fc5710,34bef6bc,47a2519c) +,S(5136c2e4,5004c1fd,615fe81a,e4463153,2753c670,86d1bba0,b3a35bdc,47bbec08,1743f5c5,d0a58608,a66fab55,69f7134d,7fe49fad,2dbee1a6,d01c581d,18f97d85) +,S(b65423af,618b242b,71e258e8,c22f975b,621a8900,9e0a3f12,f9f8314d,7fc6ca54,e3c39b1c,e4159306,e730c2ad,4ecec430,720355a2,815b63a9,720ef623,b91e4230) +,S(d6db49c6,4e68f6b0,59cb5a00,3c826a59,bea1e9fe,7622a2e,6eca605e,fe9a7858,cff0a39d,83e246f1,efad5dad,72c5df0d,62e9cf8f,4da81a5a,68586187,3dfd758f) +,S(ff2f739,8e5aaae1,a589a82f,e8e36315,34ff1081,cb083933,d08473b4,bd16f03,1559e2e8,49dc5aeb,50f3de13,1478fa99,e110627,aa0c4c5d,43ab03ca,dde04cdf) +,S(a7c9398c,5938a3ca,e32d2947,d8e3a58,e42a669f,5cd9b219,d8acf6f5,2cef9bf5,43e2a5a3,dae4bd5e,64a30861,7056fce6,cf86d0b7,41c3b46e,3a3ed90e,98d2d51c) +,S(faa9724a,357b6806,7be30aa6,4fb85879,1969191e,346d5d73,8a85b27c,c6608d72,ea1f8a66,8f4881fc,4ecfc556,f0ca4e12,b93ee6ca,54a0fce,b2fe51ca,174d9713) +,S(28301cf8,328171c0,74cd585f,6e5870ac,815de8d0,9c9f15c5,5540de9a,b29a86df,31910e6f,15585710,74e87f41,e5cc9c73,4ddd15bd,4436ec8f,59806afe,7901c2e4) +,S(fbde2380,ae0cccc4,e044ca59,92be8e11,5fc782eb,c1d49bc2,cbdfd1f5,d7908a09,c1a1d67c,74777fbb,68919bf4,11de555a,6485436f,7e34062b,480b7516,8a03dba3) +,S(59d8ba7b,6c71ba1d,191d4cce,662483cb,9784ede7,d1908e81,815d0a48,4b84bf7d,8a32e968,1ecf963b,3c23a9d2,f382490b,1f229b27,a663f4a6,9819c33b,f9f6149f) +,S(6c3a61d7,1c999ae0,604511ad,23f620ad,dfc7891b,925eeed1,6a5ca37f,b41b47e4,f7115905,c696c2b3,e2b82a30,9728923e,b8eba53c,363f1456,73676b59,9b50b9c0) +,S(8e53027f,8e137bfa,73eb5167,35382ba,ab3468f4,d4227b19,a45c51c2,ef3d8339,2b5ea7b9,542a83ab,a1c402ba,be13437b,c621067,96e83b7a,2cdedc52,2bcff513) +,S(113aa35e,6a5f794b,a56b04a3,d639b1e1,64a790b5,8ff310c,fbeab588,f93be16a,227c17e7,d95583e7,fdcc3ab7,b24182b5,1bb11e91,9f28fd7b,3a2e4a40,4f333962) +,S(16c4c83f,5a06b2de,9d3f39e7,1f0a9de7,af6e8fc7,b0fecaf3,2c82f1aa,fe9a5343,b4cbf71e,c3ad4635,87f8e355,cffe1ea,a19f1dc6,d233d617,776a69a9,ab8dec03) +,S(4d97594c,613de84a,e685199a,ac639a56,e5c15a0e,c00282bd,197cc2ea,90f8fbb0,b9f39a44,24cbb1e2,f77afa90,ec7266ee,64ea987e,80a32b34,483c1f2e,b0c5844a) +,S(b679693a,b3fecff0,819e0598,65406521,1f9aee9c,1ea44417,eba86ebe,32414ac3,7bfe1ba0,ae17291d,71aac3f3,66e5a927,56b53312,a6818d1a,78b7d9ef,a5d01b2f) +,S(a97c2730,a78cf5b7,538b518a,87d8fc55,f95a367d,4e021d23,79f163eb,98b6eb9a,aed1e51c,3ce7e35e,ff69e7d9,3fd3a968,59f0f23a,7bbab9d8,3b60cabd,cebd34f) +,S(7dd4e84f,6547d66b,5e0b204c,ed1d0258,4fe92ed8,6b504ae4,eb1b3d66,d43b8ca4,7956148f,de975510,5e3b5126,f82e77b,89a77b68,ffc9364c,bfb596e8,187ea99b) +,S(5e856d1d,25acc306,e8c1a2b7,a9ccea1,beb3008d,c224b38f,e2f31376,65d07c3f,7dccf6b1,55c12be2,f3da02c9,12fdb666,816558b1,11a2a545,9d88aa28,9d855e6c) +,S(c85ee868,7f507429,e5c26af6,7ef1fe45,e782661c,1fa03aa3,ee9dd9c9,302e5dd6,732de6ad,d071a0b0,b77e47bc,14e176d4,c85b39d0,ac5b4ea,55f0d367,dba5ab5d) +,S(a97ba3a5,cc2d5148,3f65c65b,483b3e4f,3c68e46b,87bcfea1,42aeed8,4c42e42b,f4eb1271,3024d1,b7612c3b,7dc3dff8,ca336f23,5db7daf9,3ca6f7d8,1bdb4a21) +,S(3c0396cf,6ff0150c,5b6bd528,4a05d0a5,3b735c85,125bd49c,f62db5b6,4eaf54a7,6ec02c02,f8d9a61e,6bb38d64,daaf3c7d,5324462e,37e2df8d,4ad12bfa,37fd2cb2) +,S(e36fcebc,e406d2a4,ad42f7dd,cc00e9f3,cf385eeb,58cee004,5aab8174,82d84f94,7c98182f,6edd358e,76d66de0,b45ae9f6,5eb75092,1a25194c,1911bd9f,7e6a1a6b) +,S(171ea2ec,b9641746,7d7edcf,ecd6d85,8577322e,6ebac130,5ab57f33,62eb4e37,9f219970,753a7b9c,e4f0c6ce,5745596a,aca8df7b,a73660c9,10add5a9,d4c533d6) +,S(a81d720a,bf8047e8,ef67bf2,71a13f47,636a5f9e,ec425649,1cbdad65,39652f9e,92b37c88,275c022b,635df6b,9246edf5,5dbd8284,eaa4cd7e,3d3ce6d1,c0ca3794) +,S(fa3b6973,4bd9939c,4b6ecd3b,f0a06327,2dc11345,1bddd717,f17b745f,bc3f99b3,f38a4e1a,bcb35097,7acc8f2e,d7f73f75,d406e7f2,22fdeea,2c12d8b9,e5d2dfa3) +,S(c117681e,b55bff67,feda80a1,ae88b4be,c806860d,91916619,288a7ce0,b31aef86,d94ae124,dca678bc,b69c9421,f295405f,d6dc1fac,de96a2b4,58ba5fd2,72faa032) +,S(5ccc0619,92744a57,683de5e3,7b956fa1,fd7287d,b4516fc9,f8635be3,a0db42a9,af1f73ea,4d2168e1,7550ffc,dcbba288,8397931b,e457ce6f,3f8082f8,cfc5f03) +,S(858b019c,8a93524f,6c86738d,cb10b534,d8caaf86,5c0ce75c,fc9b83b0,7c661a0a,7c59d30,1ffc8ce1,b0767ed7,91f84bc5,60bb8ca,ed3464ba,698a53c,160ec570) +,S(e1e217b8,69da0c77,599dcc38,40fa1d8c,a8d08b1a,4ac9a882,da1476cc,cc76fa56,83f0ef77,905f0801,4bd86e17,63b8c2cf,ab2018a8,9586620a,b49a15,9fc314ca) +,S(15a1ae40,b4fc51dc,554b75d4,db0c2bfd,62dfbbfc,dede18e1,4edbb689,91525cff,4f0453b7,e4e0e99d,9663e5c6,bb018007,b52c8e14,d78a28d,c4a888e4,8c4326c2) +,S(1b9a142f,fc4d03ea,4b079f2d,b05fad98,8ddb2d32,b359967f,c173801f,63320825,59bda7ed,5b691c20,4fc8f8ac,f53be298,ae628954,a8134d0f,dd097e67,be9ff9b6) +#endif +}; +#undef S diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.h new file mode 100644 index 00000000..949b62c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult.h @@ -0,0 +1,35 @@ +/***************************************************************************************************** + * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *****************************************************************************************************/ + +#ifndef SECP256K1_PRECOMPUTED_ECMULT_H +#define SECP256K1_PRECOMPUTED_ECMULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "group.h" +#if defined(EXHAUSTIVE_TEST_ORDER) +#if EXHAUSTIVE_TEST_ORDER == 13 +# define WINDOW_G 4 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define WINDOW_G 8 +# else +# error No known generator for the specified exhaustive test group order. +# endif +static secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; +static secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; +#else /* !defined(EXHAUSTIVE_TEST_ORDER) */ +# define WINDOW_G ECMULT_WINDOW_SIZE +extern const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; +extern const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PRECOMPUTED_ECMULT_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.c b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.c new file mode 100644 index 00000000..d67291fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.c @@ -0,0 +1,9750 @@ +/* This file was automatically generated by precompute_ecmult_gen. */ +/* See ecmult_gen_impl.h for details about the contents of this file. */ +#if defined HAVE_CONFIG_H +# include "libsecp256k1-config.h" +#endif +#include "../include/secp256k1.h" +#include "group.h" +#include "ecmult_gen.h" +#include "precomputed_ecmult_gen.h" +#ifdef EXHAUSTIVE_TEST_ORDER +# error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode +#endif /* EXHAUSTIVE_TEST_ORDER */ +#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u) +const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)] = { +#if ECMULT_GEN_PREC_BITS == 2 +{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), +S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), +S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), +S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823)}, +{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), +S(c3b55f99,9cd9113c,fcb4f29,be00c785,cc70d1c1,f1cfd0ed,593abe8d,260bd2bb,8945790b,5696225a,1c6a1f45,1d6b085e,cde2f332,df068271,f6279877,6d1015aa), +S(a4b41b41,1a255142,ee62144d,96ccfdc,a3cdf5a6,af32bdd8,d1c3d26b,d6aab0b9,3ade7f6a,299ee56c,299fcaad,72a146d2,62db1dcd,2ea1a355,d6e00294,ee34c3), +S(d4af67c6,75f97f30,4a621fe5,343dfa5b,e432d9f1,43758d4d,62df1e09,b79abfe8,d0fea700,2a851a85,33929e5f,1f41d4a9,68b9e520,6c19f3b0,35ce96a5,12b61921)}, +{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), +S(c28203a6,e0f93259,778bddca,10f994be,67cec8a3,109d0001,d830a8e7,b452794b,18df3a42,ec24b713,2ac4b6ec,dd7605e4,169aa07a,41d7559e,bde808d9,bbfbcb14), +S(4848adb6,b0350cd7,b745b603,cff69deb,8be10519,cc02881c,4b980157,5635aa37,7a814076,187ed7b9,84d0be65,b2f83b90,325441cf,54325183,beb01136,d626ca5c), +S(515d497f,f274da3d,9bb9e4f7,e1b77e8a,af859d52,be7c7e93,f197267,d73ce5ae,da648754,a5ed476,3fad55e1,e93f9687,2d1fe961,b448b9bf,2c42c885,b44678f0)}, +{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), +S(c3ae412c,a3e5f22b,44863ab1,b5e64719,99078ac0,d5844d9,6a37899f,3e064475,e491d89e,b38b0443,50d96e01,7baceb35,fa0e247,8c982d25,5a2a332c,239e0a54), +S(e72c3804,a774f3db,42348883,297b5035,c9dd3970,7e3bc60d,1e51e41,d7d8e395,e3cb5abb,c3c259ab,2c9e5,fa059c10,fe6f633b,4f99da29,61b9117e,61fbb457), +S(6a7b9de1,8d16a0e2,1b30cb61,3586ebc6,78b60618,e2b45e2d,8c94ad09,36227f74,ac1fb735,266d34,eb995f8f,91cbc339,f63b6e6,bd4c89f0,d7607908,75a4918f)}, +{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), +S(1b3ee78b,df5cbab,a7649125,40852351,602bb558,e4bea533,dbb08eb0,299ae994,9a0c2165,5512777f,fac5ed54,b8e5b4ce,d7a6b17d,643f8c3d,d0173a96,3a4c7aa), +S(6be3de2d,1ceb66ac,1ecd3435,3f241a89,cdaf48f4,a8d5522a,1d6f0083,3c4b2a39,88e10da0,e53b8f5a,ada0db7e,e1ce75c2,8898d5e,156e777f,7acc3ba0,9fee727f), +S(b38c82e4,3e0559db,6732e87a,7cb1e6e6,6164f6f2,258ce060,6d239836,5af9ec0d,9e0f87f4,9d240b33,dc325bd0,49e9fac5,6b7a64e8,57f27ab9,ad765604,2fe47653)}, +{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), +S(e4f916f1,a96dc6dd,8867a619,fef6cf67,14ec2642,12d7ba2b,14b5fbda,b584f339,b44855e3,3ddf19b4,31f109b1,daeea11c,340a9ad8,c17b78ea,c9979ecb,791c31fd), +S(4baca037,647377c6,f3146dcc,d732b21d,32449773,f55766d4,de5b239b,2ef89e6a,50b4b046,b9e3cab5,dffdefa,fa305051,7bdb2deb,9bd9fb,9d3cfca0,34a72228), +S(867d7d44,734389e9,71363522,9d4f2c3b,bfc66e57,44a5f01d,1c93c201,9dd3f363,e9b94307,b39ceb65,653f2206,ffc8c858,37654fb5,90eb8d1f,24a9c82e,d8b4d210)}, +{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), +S(d07eb76,bb6694dd,4d6160e7,4d4a397d,963ea132,f74d0b9,e9f35c06,830940,2b7f902,62c67203,d6f3fc8c,2d435309,7f8e80fa,c2a732a5,dfdf6dee,ab47f017), +S(36afeed4,b7507388,285fc481,beb1de1,bc8e143c,ce7b8e46,7c1e22c0,395fef48,5318e7c9,686171a8,ceefff55,3fc98e41,d9e0d789,a2e880fd,6487c2f5,54816a97), +S(cfc25614,fc96d911,24b3b74,7aed144d,8656693b,a2844934,d2ee61ab,ab794160,fa9e529b,be133fe2,835ec397,b130ff27,187aefdd,df524ed0,9fdd0486,5cf6c014)}, +{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), +S(456dfac3,c239290c,336d1b46,e9638bd2,592484bc,f76d011d,104cea57,dd0e5167,62264555,8de68f49,170a8aa4,121aa307,378984a1,76b8affc,241419e6,95500049), +S(71108a04,a50b30f8,29f1420f,b9994ba,384c2ff0,8a581672,e3464bb2,93f0f756,ff6a402c,eb50bb4f,7ae17680,458f53fe,d627b0b,dca24cb1,b033feda,f27cbff4), +S(f8261d8e,ea970b26,fb13ed01,cec553b0,a374b03e,c14763ec,13e68ff9,b219f39,3cee77fb,6e684798,68499e40,fd33fd61,e43ab21d,96a6bf78,35dad6c8,2fea2407)}, +{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), +S(ccf3d9af,434d96b9,fd9e12ee,45ea3858,5060b000,896f1de7,a73a12a1,3f635c73,7efe7415,8a3893af,d408b0c,fcd992d9,cff412f0,f77d6a9c,5d5a9235,d14f5e21), +S(18ade473,1ee3019f,ad5621f0,cfc0d6ee,ba69ab38,fdca04ae,fedddf1d,f9cad1ab,1ea6e4d3,63f1cbfb,e9d11c54,c2ab43a4,49e9610f,24b6adf4,446454c9,c3bdccf0), +S(8bc05563,1b13b451,5a99eebd,837e67e9,e80ab8d3,58ee840e,3140ac8e,131cc214,cede3aba,b11b6a91,4ef1ef36,30c12127,bb818ec9,b4d3ad38,a9e68641,a7b799a)}, +{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), +S(d194c03b,ff719a14,6bba239,fc3e1255,7637c9b1,30609ff9,1501942d,348930ee,5e9387d6,4bbc72de,39ca8141,c6c6d526,530e82,47b43161,72717b68,28d1c1c1), +S(cfe58760,54b85d2b,e1220cbc,28ba55f4,51cb3c4b,1ef1d39e,b82e8c25,7538b631,a7616b4a,f3564048,b5cdc6bd,b0250abb,ab1bdd33,a7a15857,31119d26,94ff4bea), +S(190a763e,58315639,578def37,53f4610e,5a802af9,e4873d3e,8c3186c0,e424ac42,b156da85,b8462fa6,83f85c7e,5f718ed7,34a159c2,5b18d092,185ff467,8b8840ed)}, +{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), +S(2beda894,682676e6,11bf6a,78cae329,c26b47c6,237d0e52,61a70b9c,36796207,103a18d9,a6785ad0,2129ca1b,96834d9f,f185d49c,edd1c053,96a8c9f4,dd16be16), +S(9602058a,fce0160a,70bd2a32,6cd3eb1b,e5ffbaa8,e05bc2db,fbb9c303,7b449ceb,1fa171c,682393c8,2b237910,2ba5ca8,7efa0543,b8cd65af,de324f14,cc53945b), +S(118d0b52,f418dcd2,b6864967,a49f9d88,809f2468,8bbb6c47,c68f2eb7,bbe7ab31,30ebfb30,ba0bac02,57bf568d,479b7bed,2b1512f9,33aaa040,4966b6fd,5e1678)}, +{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), +S(b5c353a5,c86b2d4a,9b00804e,f0439259,335d0bde,91dd2bac,a567cd5e,284be39a,5bba9f1e,877d5e0d,21e384d,52de73eb,9aefcaa5,132117d1,2dd984c9,4a0562e1), +S(337a0242,62b9fd60,28f5fcdb,c2305543,385010d6,98fb258a,d5c25b1c,4a765fed,e179c1fb,d671e158,36050d89,48fac97c,57abcae6,79e3be7f,16ed8b98,84dcb013), +S(ecc024ca,640ec936,f7e2320b,58147466,686528ed,579865d0,f61672e8,3e6b0f18,a1335b77,ddb11959,24d40e4c,81270679,270f87e4,158a745c,8d2d810c,ee7024eb)}, +{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), +S(34d6a7b6,733bf5e9,ae6aad06,5ee0793b,4f5e1ba9,97de99f9,8771ca57,81fb2382,22f8c6f6,dc7203a8,53e64cf1,dbf26d6d,e255f0bf,bddd9508,a759db8f,2c55cbd9), +S(8458b56c,982ccb85,8731c149,e2f38880,3958d6b7,55f38582,b9f4d95b,85d22ee3,b5b8fc5d,2da56779,a5b06b85,b5d07349,9b04cfb1,2d7b26b2,d9a4bf44,3f00cb05), +S(cdbf1327,3388dd49,c163ce36,8d451e3b,51bc7924,173efc08,376cac4d,6f73a84a,d2854757,18fa95a7,1978bb04,5e81095c,f1423d45,e533ba6e,ad91f40f,a6961d2a)}, +{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), +S(6666f098,c04d51a2,609c9eb6,596dc668,16735175,1458cd51,59f5bc1e,2c86722c,4ce5faca,45027cb6,85aad7de,e926be69,95b22719,d8d8fb61,260fc9d7,62a9e47b), +S(87b459b0,6e3e2750,31087f45,79e53818,fc200703,59d28147,ad79e39a,488c79ab,2656b94d,d33c0721,b90e981c,b47dda60,166839c0,1c5ca2ee,76979133,824d2488), +S(830acf28,c0a99fcd,f1d3409,ca3066fa,ef8d267a,7ae6ba4,55fceb5,7f76f83c,aa4ec098,51361d43,a339f418,a28de217,a9f464dc,26ceea5a,ae74b4f3,193a58a7)}, +{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), +S(e5abf144,9c4770fe,b6772067,b18dce01,efab139e,f0a4d73a,eeff868e,6425a7a4,ba62fc47,597dea8d,4bcd1a08,77730314,81ea6990,796a29b5,94bd06d7,d5330188), +S(699e20cd,3b320b24,878b6a98,4c3338d7,45f93ae1,a7aaf363,e20b18e1,8b6d0f56,6602370d,65efc133,83ee1c45,baae4a65,efce9bf8,acb0c3,cfedb5c2,94f36d2), +S(6cf56e78,d6f58bec,32184506,9f26cdbd,7f6ae28,ed310203,dfe410a4,b83449dc,4c24cc91,f78d5c14,690ae276,89a56531,34f89a09,c17e229b,3ab7379c,6da021c8)}, +{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), +S(ec45cef2,3211527f,220dd3c5,2e4b88be,8f0b0191,d9e73d7d,679fd75d,ae9dc2ae,ac07402f,c7cf8884,8f00e396,42b5e306,7749e10a,441c18b2,646b2fcf,3f76309e), +S(70234e32,61f2e099,a1525a81,9ab7c926,bd672805,ed3562,55369cec,85615e9b,785a6c93,f2673a8f,ccf3b332,35922f9,208dcaee,6932c27c,b8e40b0e,c9b06360), +S(a7c9a0cd,c3692f9a,48ba8307,de80b5d9,80593eef,9e236bf2,49c9693b,c2bb46b,d44258b3,790b9ca2,9636694,6e9ec845,3e3eacf1,a9253092,a7bc92d7,62a03d3c)}, +{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), +S(5d24589d,5ebf326c,9419d539,f06b2291,42c02d0e,44556a3c,772f484,6cb78938,2fb6e6bb,759dbfb7,57257d21,43064225,beeeaf42,4c99b426,aa27d969,d459a5a0), +S(43d4db79,797f6415,93248363,38980bb4,3c90400f,a698ab3a,ba38a4a0,9bb13701,e2bacfbf,b84517da,efb0e137,678ee0b7,bbeefd64,7256628d,7edf46f8,38c65ffd), +S(eb0e5c31,d95f3325,78596f3c,8a027e48,453b5c24,4d0627f3,cffbd413,f8c53db2,29386000,7c3c97da,cc0b5a30,1a7c7c6c,8a1dbfe1,5358c72c,5fa30912,634d4a0b)}, +{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), +S(b930b8c,a68df36d,80b589ba,72dda82b,502bcee2,cb98a9e9,95c3235b,457ad4c6,7b8fff37,9970f1b4,1a12baae,f7628868,fd3f1003,bd6ea442,46559b40,3a1e8bf6), +S(a6d3233,f7e1001c,eea237bc,d4484744,aa0888b7,a2b44b82,59a542a6,c0d6b552,d2f5772,1c2cbc0,7179d252,3cc0d0e6,94551842,afbb51e4,31a6efb3,9206a70c), +S(c1dd7db5,e5dc3f50,2b08a177,98bb1cfa,afd02252,1bdec7e5,f4653e7b,3303cbaa,558676c3,e25db8,c46bd903,2e9dd122,a981fc50,cbb9e807,157ef35b,5619d3bc)}, +{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), +S(cdd67435,c9fd1182,88f703b1,1fb4e848,9aa2b752,3237a279,ca30a11e,d05de955,149e113c,49db4e2d,bd50dffd,bd53dcf1,a5876825,da059718,e0575d3d,f39476f3), +S(b0fdcf78,9c509ff9,8bb36db8,dbbad047,36bce756,e350373d,ba4d452,8410280d,7c8a7550,91b2cac5,ab71d820,84b335e9,b630cee7,2a277e12,dcb04605,21747c9e), +S(b5ca53ad,77f1569d,ae1c26bf,84ab8e71,98e305fe,e21545e6,f3b2c734,aaa161f2,ec96edd,82ed1d41,cc8423d3,bba6d50,4659de8c,ae5730a9,a0b54fe1,25acdb34)}, +{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), +S(847cecc2,f30f30d3,40ff0276,9167e2db,97b07103,821eecfe,640fe4a1,b3f5a08b,e59c450,3ea1f4db,c4b00c6,e5b912f6,7dafd112,59773c66,d478781,bb343d40), +S(4157664b,4baa043b,9cb959d6,96aa1501,5635bfc8,a20ba704,b6477aaf,a9af9ea5,3e44d11,432b4e5b,97428706,4a787681,522ffe,28eab2f1,15e5bcd6,d42f69ea), +S(675389b6,32431381,bbc0d5eb,20f356aa,31418409,ea9150b,aa7f9c83,41b1124a,999645d2,7a169a1c,de866f4b,ae713070,b9b37c9c,a393567d,8ecd04c5,85b8059d)}, +{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), +S(ed362790,55151b78,4e6f5088,e99b7079,d2409203,c08a8791,7644a639,7a8b6199,84affa8c,62a0109c,b003196c,25296d8d,5d3e1904,c1cd10c2,1e73fad1,3a46caa1), +S(21227229,b8deca6f,c30351e1,7607ef99,23cc3f8,9aaaa48,9661487c,7b3bd0e3,a054a47,fcab568b,f8bd4234,a5d7fbec,b11d96e1,aa3ad5b4,88fbb405,a7437f21), +S(59f2227c,32afa124,999ad653,8393e47d,d64c4331,773e09ed,f0517651,3090f07d,1348ffdf,d8adad12,4370f188,cfb47fde,a8297e6f,ea00967,7061bf66,e03b0472)}, +{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), +S(27f03daf,a370763a,e2b44480,7b9e6779,9361efcf,cdd7be23,6c493392,f19253fc,eeedf887,cd8f3df0,9d1748c5,62723c56,31956880,cceb0f1f,c118052f,8c44b5ff), +S(d301d8c2,8d7413cf,3298cf95,1f7d6c3a,2e8d86ee,c5e3fbd5,e80e5358,4855e04b,6856d7f1,5e94773a,465cb69c,8b7f8961,a2988f50,fdc179d7,63a92ab5,d94b22a5), +S(8b88670b,72fd02c8,5f973403,5299ad19,484c1367,c8296c73,122d80c7,9bce8407,c98b5a2c,3b0d5c44,32975c0d,32c90794,63ade4fe,92cd4c44,4e8e64ae,7a05c5d4)}, +{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), +S(2a1e20e6,8cfbb77a,ec1f5666,dfc1c85c,c4a07dda,4ead1722,8d7f3633,6771be47,b1f5752b,3f6650ff,261898a7,a8c61f71,48e8f54f,a39e2f4f,8e94ea2f,b332a08a), +S(560d86db,354e5f8e,e8522056,aa9d0f5f,6329fca8,2bf11ba9,fc29505f,7974662d,bfd52860,f42f9d8d,84892fda,b78aa79,9143eee7,26fbc95,b5e17856,53b13878), +S(24c3c40b,df047994,d0416339,e64d6195,276e3779,68869b66,3ecdf186,4703207d,643b0918,c8dce682,50aa3abb,db68f9cf,f8ac64a2,2c7cb77,ef8fd252,36cdf29c)}, +{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), +S(28ecf7fd,a122550,8301ad75,6028e29e,13da7586,d8b2aaeb,f061e927,dd030db3,bc3e08d3,df4218b,88279f3d,cf75dca7,4a9f567b,75ad0a86,f9379c6e,37661962), +S(851aa3bf,37ee83d0,8318527a,5f4366ee,8ae98d29,de2254d6,2e4428fb,cb5e0f21,423393e3,937816e7,ada1df1c,ebdda887,5e114ab4,23059a35,96668a80,7820754), +S(7e6cf455,9d674d6f,a6263ffa,69cef00e,f69f50e5,4a5d6603,5efb7732,b1aec817,3c6d0cdb,c7ac0623,1c47c044,e28bba2f,105a1730,7cdce1a9,ced324c8,f770cea2)}, +{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), +S(9850c031,33d251c2,9f0d64a,f7941f4c,475c6099,e6ba606,9d396ce2,772a5e53,acad3120,b2b5aff9,209bdfce,34d6e5a0,899c9de9,15083064,b84fe57f,2e1c1adb), +S(14194578,53638284,4574721,cb83660,bedd3cff,b68c7023,3f3e6a8e,1d78d797,94d7a10,f4e52fca,c855fbc0,7c977386,b11e179b,db6e6488,67ff3957,28ef2556), +S(c35a90c9,d1f6e5f0,265b7f79,ec47025f,75eda795,27a80f3d,297eb2de,9a85c603,94336bed,d5187e4,5faa0993,875e2421,b7e02eb1,c4dd9e94,b4aab892,3f63f838)}, +{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), +S(100f81d7,3b016931,1291696c,c08236f3,6100d4e,10737bd9,2b583d74,1b1903dc,80740c37,a67af622,bcfad64c,38be6968,7e780ad7,318163fe,5d2373a5,b6c90976), +S(17d3e5c8,8a7c9ec5,8a600c2b,c5d0574,491d3c19,6cca5de5,1f812975,e6fd3152,6676bbb0,9ef082b5,f8ebe69b,22c57949,43df3335,2d329621,3238f39,36bc0b9a), +S(f7ccb6af,6dd503e9,a694d721,7e0444a9,6428f277,2cf0e511,cc73bf08,590a5475,817daf4f,3a7106,f23aa303,772a35a4,92d49ce,1d4cf9b5,fde4653d,28ac6cf8)}, +{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), +S(da3b16c5,dd1f95f7,6e54297a,d6be133a,ef0df2f,45f14a55,de978a02,6b8b5fda,6712c26a,cd07740a,70573f13,f42e2b10,edbe32ab,fdb517fa,7a61af6e,aa1c6132), +S(18e515af,fe6c7273,e2acc85b,6dc345c8,f0dce23b,219abd3a,d295f686,4e02ff15,339f848e,f0b1bc1d,fa748290,f25e381e,68cebff2,f3e47caf,ff654909,63fcd515), +S(66bdebee,8c0935ef,32735526,c077cadf,bbc14003,8cbe910e,66107308,8c2edf8b,91ca5bbf,3911b59e,d6c6fe5,2fdd9a94,5ed49883,275b8cac,7fe4c63b,530c7a50)}, +{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), +S(3af65e2b,b700e873,edcf50c7,913e6fb5,534e314f,a2eda897,29fad58f,c7a49b54,dafee0e8,7d70e7b6,fb159def,92a6e5d6,cfd6b8f3,68fdec20,7719e085,94bb8e28), +S(10db17f1,8b009000,660f7dc4,d1a48fba,13926ba,67b71c34,51d2557f,a6f141ca,2f5bcc34,51445a41,d5f574e0,278845d4,805f82ab,ec84bf1c,a39b4bc8,9abdac4c), +S(ab18b6c1,55cb972d,9152c11a,36877a3a,86df3379,181c712f,7242bddf,9fd8f099,b8b8f41b,dcfc9ac0,fc112dbb,63e4cf,72906ad5,1ddaf95c,2a8ecbe5,bae0e229)}, +{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), +S(cf03f3c4,11bf7fe1,46abf004,ecc3583a,25116d55,6c6fff00,71464810,8470f0aa,aa0c0197,d57d72d7,bf336ab3,5527f42e,c7472b8f,8113a9f0,c99f129,4b39e7bf), +S(5d78371e,cb875987,c9e65356,d35240b6,c51e3897,6f884d73,c80dc0d0,839e8b26,76451b48,5c9d7468,77017dd7,412e06b6,2ccfd59d,a1800765,31bae6a5,b2a0bf73), +S(c1df0be6,6001ba2f,2a4ac3a9,466eb526,f37432e0,43688623,8fddcfd1,c1a2bacc,a8b676d5,2b3ecf46,e5849f4c,7c7c46a7,33beff28,d59285a,755509cf,5c629060)}, +{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), +S(2afd690,bb940709,ed1a4f85,41658f4d,254edbdb,7a64fff7,c06c904c,47d0cc7,d2177070,3bcdc50c,bc219ac4,62a6fab3,5897b550,d057f9ef,837ac04a,f6233c2f), +S(aad6646,8406b84d,38782e5a,669bddfd,c2279bd7,df486dd7,93e15f82,47bb9cfa,5c0a68b6,2065ebad,f38595e9,5f7a44fe,2bfd7ca8,4ecbaa82,ad39fbd7,b5a1afe5), +S(4a7d2720,1b508d35,a89b6406,68e99cdf,5a400d1c,cb21732b,e51fb44d,61c4cbb,d714cc9,9d59036c,4d82b668,e852cd52,d4d09ba4,f4007346,c7c1bb97,232b0fbd)}, +{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), +S(970222f4,b79b7b44,bc10c23,1dd6ed2b,2d3412d9,a225fb31,53e8d633,57f2c9a4,5151094a,f28c4b19,6653a42a,dd1f2270,50f0bced,e5e9339a,cea08b7f,e44f9357), +S(5efd117f,645a903,dd4d3f60,72a1f9e0,3c5a91d5,c8042267,1f791747,df32cfa0,770add6c,9b44ecc6,6b7a5fd3,3801ffc3,112bee8a,af0c02c3,fc646347,fb8483f3), +S(ffe6a8da,2abb5280,2d5b9e43,d2d0505f,f564db87,57179c55,30238353,c51c5365,4f1a00f5,4171e1,65d40719,8b913be5,fa84f018,50c40123,9aaa98dd,b303cb71)}, +{S(d2fff4de,9ecfdbd2,dd99ebae,d038415b,19b6c44c,9717926c,9e9a668,3fdfd377,a7e8ef8b,89877e3c,cca566cc,7b7dd537,d157cab,121d1623,b6880567,ac66fa8b), +S(5aaf3141,4ec3d722,75d928a1,c6a528d1,c94ce228,19eb8932,b0da11c,9e4a4574,5d496edf,c3b054ed,5b7fd57c,e731e41b,a538089e,19c11232,2e844b49,918da76b), +S(5798970,da3ee2e,d65e087e,81d9ce60,fb7ee1d4,145af16b,42a4889b,31b68258,8a8fba47,b0b2d716,6324f55b,143b3b14,9af089b0,dc9b9557,40c5df93,3067841d), +S(b482e028,f9cfe926,6d7d4072,c01d30ea,28dfaf9e,268f979d,faaf0b11,4f420d45,eddfa10b,7cba2273,4fa22208,51fc47ba,82721443,19a60d40,624d4e7d,454aff71)}, +{S(b3b5422f,1361ce5c,bf7cc061,3c78aa88,a02683ee,cddeaaf3,f5516cb,291632e0,1790cb50,cc2c760a,c7c2e97c,c44aff29,86c73be5,59a88180,8d036e7a,94347156), +S(34359647,5f3bb33f,eaac445b,5574c7b0,d2fcecf1,50a098d2,445748bd,482b5e0b,7caef8f2,4aa39495,6a36abc7,6704f7f,f7be9b22,6e3a1004,bc3dccc8,3a58cfa5), +S(5000310b,6e81394c,4f91677b,a03c5ca2,5e5c2581,bdaeb320,573febcc,4bd638fa,1c238674,6752ef6,25526d5d,1c80e106,c45a7b83,9ffd9160,bbe6bbe2,8056b532), +S(be843ac0,1b9efaac,adb5c047,49c5990,7441afda,8f33b1ad,20f6335a,5bea9c02,1d14d074,baf0a79,6c165a23,fa9ac432,c46f6576,838625ca,1d73c7f5,327808b0)}, +{S(2e01d33a,c10caa03,ab514f75,46226f67,69a08f01,56017b64,a2436a34,447bfdbe,f5bd77a1,2c61f2ef,60a8c937,cf29e1e6,882b12c0,3e7a7763,f1ea498e,9207836), +S(c8104402,70594c5b,f4e36d2f,ed9e6fb4,2d362b49,5eab7a11,2b1e1c26,aaa20cec,939741b4,db55bca3,53879f72,6362518f,98538a95,77249283,e62b98b6,b3c65c34), +S(408038a2,a79bc8cc,f1fe98f7,d7ddc784,28fd3c71,ed6be435,d76f1390,ed4e3ec0,2dbc7345,f4a358c6,f9690213,1f0418ba,2db1fd01,7e47d8a7,583d30c8,e74027ba), +S(8f0e6b51,50d752a4,86f0edad,a8c21b14,1f7a73c7,2d797233,6a45fc96,8c857683,3cd1fe18,21f1291,7d86b629,ad5aa2ea,46243c8c,398be570,f1959d4a,47b5c3cd)}, +{S(934807e3,60b79e08,d1e28924,2478db59,331c171,6366f421,eda4417b,c0699286,f7f83c26,50e7a77e,2f760e68,7f475858,b2c2d770,195c199d,33a84324,e23f02ef), +S(73c23592,7ae07afa,1cfc030f,a8c874c1,e6d876a4,7414894e,dfd993d1,208ff29d,c2158086,e6dcb078,3a602887,d5d780bc,6e620946,91260289,5244ddc2,f98bb1f5), +S(e588d73a,6eb03f3c,4700380f,17f4c36a,41415cf6,43bd12b3,7e5eedd5,13612e84,3a1cc3ed,22df4c92,96dfa9e3,3faf5035,d084a6f4,fd06c27b,e9bdfefe,bcf1753), +S(7fe24906,485a5638,42ae477b,de90b8a3,1984bf42,7f43660a,f120370d,cf6a3d3d,16bf27da,45038c52,a6051298,26039376,a6fbf802,583ee59a,9752dd09,f30a7ed5)}, +{S(accea070,aa6709bf,efd88be4,bef1d485,a0da83e7,ac9a1eb0,eda8387e,b9fe666b,93fc1c9d,fed8fff9,60ef750e,94dd2342,5fa08c3d,8eda3eee,7f51381,196080e3), +S(412c82e9,f90a302d,f404bf6f,c3581516,b23519aa,2ec26f20,9c80fca3,1f4d0698,31b2bbb8,493e0c15,796d93bb,59cf70d2,7f9c65b4,b3a74969,8612f72e,a42e572b), +S(c0ce0313,52b119b9,795635d8,5e2f5153,a3514d6c,190e2a0c,f9effdf9,bcbdd6ff,b4ef69bd,d4671af5,2be6a4be,1ab4460,71485a7f,6fde10f3,65db8bb0,91eeceb2), +S(b7a23510,abe3c77b,3720006a,9e29c6c,180e40aa,889ea103,ea2387c1,1667aa9a,863f8837,faef7267,d7e36595,a15dd7a4,b2012733,c7347dff,501017f,188ce8b1)}, +{S(a488f83,2bf3e57b,5225f748,754ba2b5,cd9657c7,175198ae,122c3d1c,ee336ef2,4e326d40,648cf269,2db42532,55391fca,5c2b48d7,44a9e39f,bd1293dc,827e9021), +S(bf6227e2,a75c717f,fb3d8d62,361b9212,45bf64e,b19554ed,11040b32,521b9e52,209826fd,41f88c85,f90b4c4b,f90caba0,9cba91aa,687cc502,23bc71cb,7f5459a3), +S(c0ecca8e,90d6979b,54b9e9aa,5a804c8e,106b8b41,a609b85d,1824d079,e2b95f70,1ce95138,2b6eff47,9660cc00,8ed77229,b11158ef,15d97809,a6253439,b88cc4ff), +S(3d4861e1,6069f0f,ddacdb17,595e59df,54a07376,4237b29c,102eba03,230dcb3a,435fa321,90e459cb,137046d7,d316fcff,6fd6c954,a8e2476f,3d38d9e8,263deb51)}, +{S(a473de46,a554667a,368fd573,168dea23,3f81153d,e1b35b26,90da8863,71e6c131,4ba0b462,92aed936,7a2bf9e9,de48a08a,874fd681,aef86a15,58b49e4f,13dbbcec), +S(435ae44e,4f062fae,72ec122d,b7cd5d5a,719c5889,a76ee171,be0e5c61,c5c2d148,d4a6c494,1fafd583,39b59229,b384a5bb,85140ed9,b8cc99b6,38f995b4,2044f380), +S(c170e94b,8fbff40c,159b8fda,ab69093,49e7ce91,1658aa2,896049cc,56b4ee31,19b45604,e602baaa,7085e27a,69d8317f,26ecb345,a558a3e1,5456c1a6,5d89e992), +S(2a043b61,f5e22943,19a38b67,b3bf2f8c,89be156e,641159ad,c94144c9,971af395,17d7c7e1,6c097256,be0cfb11,d9a3cdd7,8bca6a1a,c9514e37,3f59aa5b,c48eeb9c)}, +{S(476d7ba4,35177a71,299267f4,14ef275d,48b434e1,380c1afd,9fac4606,f8e02be0,7f1255fa,57a60447,c14d6574,1d7774b9,695e6d25,1b46912d,d33c77f3,f756edc2), +S(ac4bc955,aae3fa7c,a4ac46a3,84cc2f7f,3cf71f73,b15dd3bc,30513ca2,7da2808a,694ee4e8,6ff945c4,4a5ffd3a,19965ae5,2e15cca9,b51d4795,855eaad7,fc959809), +S(43b4f6e4,25ce5fd6,2c5d6d5,ce33c6c2,df453c6a,9fcb3b15,83faba41,69fee22d,dfda0e64,572ee74f,1fbcc406,7879fbbc,b3896243,70d4bc7a,677eedc0,a3432e4c), +S(e2c0dd25,96da70ee,2569cd83,cea9281e,e37c731c,d0112018,7966da7e,75a9cadd,f87becf8,ed20a606,f8be39ec,2baff52f,60543859,fbbf2b9d,2f8c9933,838b6507)}, +{S(4f62ab4c,b7fb0d13,12620121,9841e932,b0de312d,674cd002,315594e9,81dfb3a1,1145fdd8,c5d16653,a9129b0c,39fcbbd9,5968d22c,ff2127bf,91e89847,35e2834f), +S(ca2ca59e,ad140068,e488658a,836090a8,eba824f0,3c6a81f8,fed13956,865f1be9,f8e286f9,8e9c9003,e4701dfe,83b79be0,d475e320,8cc6fda1,84095f5c,9d0d70b3), +S(eae775d0,8d013499,5ffcba75,33a6dd91,2a07ef45,5a20f49b,8e7b7ed2,75d3c54b,aa4ba756,dd0bd16b,32e86c7e,a520ce1a,bc224d2f,822059e,3df2cd7f,d8d1f855), +S(db566c14,bcae1071,e0bd82a,7a965a72,101d4b5c,29cd7aad,c91e5e99,f4648978,78569150,59ba0432,3afd6a3b,ae5eb503,f920318f,25fc8c45,d1b0fe35,fcbab0e1)}, +{S(110f05a7,489138c6,51e48771,d505c7ce,68bd6e61,67cf4c3,3933441f,a236f263,761652d,178d0d5c,f6189501,d02d7078,2f10f835,27894d79,4f93dff6,e90a3b16), +S(7e0419aa,c31953f4,73ac26a6,80fa9996,7e8f0af6,18ba8a64,de8be81,33f48b6f,b6ef4bd6,5b82a94d,e774eb86,63ad7144,f025fc3e,d8a229cc,af59a816,5c38638f), +S(ec0cc26c,6044567d,609cf31c,c874d9a1,844f61db,37ac4e04,10497e05,c7accec8,20004878,3f7d270e,81144d48,ec839dc1,d1ecdac7,75910eec,b2942619,c8baba8e), +S(942bb265,6d6cf90a,44b1701,76fa9b2b,e366ddbe,fce1a83c,cb3ecb4c,555626cc,e07e2e36,2a835d8e,31601417,fb185a06,14aa4598,6896880b,f1df90e9,aa5c40a7)}, +{S(81f4223,6a39a14e,d2764665,22edb719,f2fb72b2,c571ed67,343e2c57,4fb60e5b,34f10ee5,6c1d5e02,51e8ba8c,9f129391,521f0601,2ebb4549,7377967a,d8347e4b), +S(f983c256,b5c49a86,6bf19c43,50083f4a,7e9cfba8,723d4740,f6909434,3b422fb0,11dd2c7f,16c588c7,d675ddd2,be80e785,50f63fb9,1f1bc016,bc29891b,f5bbd8d5), +S(37fc1499,95a90668,a871c28d,8ed84092,b928fc95,2c459c6d,cde783,28c936ed,e0b07cfb,6fc2442e,4459036d,bcd0117f,c36760ef,2f1046de,17673726,a41316df), +S(4ffc822e,916594f3,fa007cd2,682f0c5d,91b835ac,dbda2ad6,3ac3b73e,5094a175,3ff732fb,57aee90d,ad86ede4,5afa2e18,c95a0a77,d6cd008b,11c95bfc,dc927843)}, +{S(2dc8f27b,b3bdcaa9,2feace80,f2f6212f,8209477e,531e74cb,f497372e,9a2f2263,7feb63a7,96b55bee,ffa180ba,fef47776,fc4fabd4,2ccdcd97,64b4bab3,10350790), +S(c395d4c4,d877c2c8,268621d9,5fbf4f3a,bf839512,c68dc89f,82d6e757,d3938cf7,b37a444,a4e73223,204799c3,df859859,892eae5a,73844d09,9d33eac6,37779a7a), +S(d31454b8,b44e2a30,395674f8,abdc4fb4,6ac242b1,68f0fcd9,c59cbe1d,c8d2b47e,c5a4cbe4,6f8775cd,9482de12,4bcf447a,14e75b52,74f04a5f,c7912457,e31a4d82), +S(c133b76c,a0e74084,b279a464,dd7d5ab5,829e8304,ad8bd982,b2e112a2,9f452272,3bc44411,65b0b601,93bbef51,641b2569,a57aa5c9,6150ffb3,936f00c6,b6434b80)}, +{S(118d5053,fa3ef05c,810cf906,3a410f53,38a9e6bf,513b9a7f,5259112f,f84ad7e4,a371fc9b,c9182528,27d6c842,32e4e44a,9d32eafa,84f1a02d,a86039d1,6309e92), +S(29f11f0d,1457c9ef,7660a6f7,efc42e79,f58ad31c,1df3ee82,33856c30,185a4152,60cc2ceb,5a506326,657219fb,5a8bfcc8,d290f5b,1e05f73a,5f410c10,6ad99bf0), +S(ab757a3a,7af4069e,23493c2f,3978b8af,67d735ea,92382381,727ca6a0,df3082d5,335e418d,1ac2ac71,81a96a7b,7d15c55f,f8c6e342,83aa7f9d,8ae130e,dbe0fd41), +S(37e90fb6,b197550,14d0ea75,1ef33c24,a00d8cf2,5ecd8476,8adabba4,477260f7,90ce4d73,7613beaf,3e884036,5071f104,b88a58a,94c80b4a,1325694,722abbae)}, +{S(568b3e2a,2db4792e,4ef4ee66,14e201f8,a847fdca,38bb003b,adb06d74,1e4f999b,7334b395,61cbcce4,49d83eed,205a4c40,d91d2751,938ba7d0,6ed9e5a5,e1ffea7c), +S(8e37181d,e892fa67,3f26c69c,f6940204,c8f5e5b4,7a027489,ba6f02ac,b87a40ff,9c1a3ad0,bf418dd3,876388af,d45c6ab6,dfa7f7f6,94e991e3,ef0895e,7d7a51c9), +S(cf2e6330,134713f0,cfb27276,9e65e4ae,83d7a3b,84900aaa,3d32d401,55a19673,b8a0a5ca,ebbb17c3,923448a,767804ef,43bb056b,724471f2,5b089b3,ec77e453), +S(ac0df937,d2d65ab2,e6bd28ac,76551b78,bcb1f38d,81f988e9,3fe2b8ed,740ab0b9,f546faf2,120b2e92,6c4f0f18,49cc01eb,834e1406,b5ab4d54,bf3abd22,2b40ec25)}, +{S(7c32fcd7,13305cc7,44fc4ff5,2d315e2d,d4cdf7c0,31b41a64,db6ecbf9,fd4edcbb,7f002bf7,b8e1b8f4,a4a4f2b,1922983e,fb901e13,59cbe934,8a31d91b,7bc86bf4), +S(c72e640,f0401cde,93d85764,224730de,8d46477b,538528b2,53361873,c9f39dfb,571700b2,b5768244,63541839,a1a890bc,dc823e39,a7d137f,9e31e849,583b8fbe), +S(3bf6cfec,83091c9e,1c1deab8,6271526d,9d9afce3,1f052a3a,c8ebd1a9,49005470,35fbff47,bc7d13bb,197e6d7d,50596617,79a06b,e956bfca,667cf070,b80b45de), +S(3416d9d3,6c2c2c6b,77a5d647,500b145c,926cb3e7,1aeb7e83,101dc410,a72bf818,c785a0c4,7408b8b0,30b386cf,9e39f1ef,7bbc4358,f66ddc20,22b1b781,8ca175cc)}, +{S(29d70da5,92094c96,e293c115,42b9dbab,b30df8db,ac98416b,65b0b75b,b3ca446e,a8a5aa3c,c3269596,dd8a9d98,87a3b772,efa1c668,3f8a947f,ff80c662,31c70799), +S(bcaf0322,1e406be9,5df0e9d8,79d82851,2a71aa7a,7a84d8c2,ceb0a6,9d33d827,7a9ecf5c,efb0adf0,c0a2af5b,dc6c2537,b1fdbe0d,be399bf5,6e9d3612,a94f4239), +S(7a24f37d,d6a8c278,cdae5cd1,70be20e5,b9c9c028,ffd3c9fe,4dd3fc18,45a339b2,705f933a,d0dc7a14,7838c060,abba9bc1,7012ccbe,83633551,536e8aba,c8b5ee1b), +S(c35ffef3,aa4a3e9d,93dcaa91,a972172b,785d997e,dee6cf34,e181d217,a3c83d97,122638e5,b7bd05a9,1c5ad0d9,bda96767,6281434,dd0f8a92,561df9bd,96779571)}, +{S(7885bb79,25196ae6,f45b6658,f3c04f5,a3b76cb6,1d60eaf2,45cb35c2,2552267a,9839aae2,b4d9de01,1a119d3a,d269a821,dd88d287,2f031910,a2f3cc22,2e8555a7), +S(b425f805,2659b55e,4b46894e,3498c273,e1869ffb,880e9c50,20bef244,ad471ea7,b0bde647,f6422b6,a8f8fd07,a6f8c73,5b5a17bd,9d6eb57b,34142a18,93825a7e), +S(ccdc5e4c,7593b182,a70c2f97,c358db89,f5b09cf9,de3c5bdf,2a44808e,a84023df,8004b543,df7a516e,faebadfd,c2121101,1ab99b4f,c7a8cdf1,43a56afc,8aa72854), +S(d55f41a9,331ead98,db392478,aea2ce68,ae5c9f84,179caed1,aba5d60f,246f576d,43eed529,61c8bc39,8da97200,92f66f18,69be7dc2,d644f291,98be290d,adabc6a3)}, +{S(422f029,1f51c4df,af233322,7015e4c1,ec8175b1,a8ab6b2f,60a9e291,7242d940,51ae32b0,ed5d39d,e1d61437,d363d59,181a68b6,4e052bc5,9d132da0,9c1f422e), +S(3287920f,f0fc9643,9b0aff00,d6944422,297d3f52,7539f579,98fe3d29,80cc58c4,eaab3473,d562fe1,6cb86453,52228f69,f34efede,6934a587,ce62760d,5fb7869a), +S(a9ce3776,2c703adf,e36d3f6c,7a2b04b9,288bd09e,59bf6fd8,25cb0ac,84bbc641,1e9e8e03,ade9a185,d0680f80,9a9a0468,2338a1bb,4fdc129d,f6a86377,2f9da89), +S(a7480262,bab701d4,11642b23,50934791,8e393f5f,3d55ca2d,fcdf1957,f20c4e04,460875e0,a7afbd6b,ee8491df,d1e80b58,9cba5bd3,a6e4d74e,a4f5bc6c,567460d4)}, +{S(43cf2273,e372157c,2180640,594c144c,93f64fa1,75f28cd2,5e7efebb,14028a93,1f8b092d,4cabc600,33782374,10eafd04,37d6436f,6064932,6f8de6d,94059d4e), +S(e327e5fe,3d20effd,89532c73,eae90c0a,36358e5e,65cff655,b25bd325,8339599f,311932aa,8e4c3f38,cf6ba972,d9872585,14d376,460a1185,6b3a8bbb,ef050996), +S(5fe08c73,62e99994,ea0416e7,d29e1f8e,56e66baa,ef9f3cd8,47732960,c6e545ba,f9373f76,5a340816,cde0db8f,486d6453,531c0ec7,4ddea72e,280d7f42,2fd7ad80), +S(5c32f5a4,74b7f6f0,c019f7d0,a2df5c77,4017dc1a,f93b5c00,bd531eac,32488609,94ca08eb,3d86eb5d,b8f31b4d,9455a6c6,1525a0cf,b388b698,4fb286c7,188d3193)}, +{S(9f10aba7,5a7b9fa0,233bf53c,d819ba2d,919f8acf,9a5e6717,2c93229d,547a40bd,85485295,254a4456,87b065aa,dad21f32,b31735e1,96333fb8,11117a00,d0bf2361), +S(b56da700,114ee476,21540199,e77ba271,e8d578a4,5be263c6,cee2e8ad,fb3a3e48,23ec87c4,236c1299,96ba8d3f,b8cc8af0,b099042c,6623deaf,2abc10cb,c17536fd), +S(a9d94ff7,a5be0ab7,5a8563d6,b061a8a0,7e12690,4870fe3e,39c4ce98,93e96b09,8d1b1b28,a0366d25,a61b617d,9fc10194,72fb3e5e,ff5ce43c,9e1bf1ec,708be6be), +S(fb9fa3f5,381ed2f8,b8f407b2,9991fa07,a6d7a265,4dd2b3b0,cffa3814,10efe8ec,8e9b9167,bf42b7f0,6bb22bb2,3fb40e01,bfbac1a0,dac536ba,b17e7970,803ed9f4)}, +{S(b365ce49,d21ca341,c173b6d7,2238c56b,f080d218,a89e57c6,ce1664f6,5c290a44,e77935dd,75d26531,d4045f72,3b4b5dc4,6608f8b,60f58989,d2ac4002,c304cf04), +S(f512da13,dec07111,2b2cdffe,f72b2b20,aab81bc4,8c3514d2,f6f1360e,ea17e855,3934b35b,87269072,77bb171b,fa2bf260,244b1f6a,13bdba7e,a3e43b8,d86d8abe), +S(3e000708,badfe5fd,d7f708ca,92bd5784,80d0164f,d76bb0bb,4dfaf9eb,e54335a6,713915c9,7c1b1d3a,7111ea47,6c232b85,527ed32b,1e6c4584,cf36e9d8,5abb9d80), +S(c6e97208,17f00aef,4988ea97,8f7a0240,efe4a0ce,203ff10f,4dc77e2b,eb49934,d47cc2d7,f0e499b4,985048fd,fd5f14,83d1f90d,a1abc2ff,340993cb,e7ae03d4)}, +{S(38186a1d,6092b158,554f3f6d,c6de049a,2037577b,2da8db39,163fde30,b19dbf2a,a8cf045,9c7ea28a,415d01f4,47566d54,f986cab5,eb272326,442f32ef,cb6c43c8), +S(ac911a57,1f58a283,517f1ae7,7b2ec8ce,1bbb2d17,3e2dd021,bbaf352e,edca57ad,c9e985f3,f278463b,66851c70,d2a2192,299a3bb1,7ac40661,bff10ea9,29734b3a), +S(9a691204,2f6e8cf2,7189de67,f04d15c5,b80df68e,daa7dc7b,74d08053,e32d4516,a60a7abd,6448fc26,3d49e9fc,32b51f05,1578a8c6,74827059,ddfb9f93,f4621acb), +S(8e6ecfe4,e5b519fc,be7bfc37,5b0738b4,618e5586,dea95ce1,8b870424,55b8d1da,4d459953,53cf5ec3,43b38aed,c3d6bf27,83230fbb,9fc0e147,5cc5ca9,6a341ef8)}, +{S(d8e5f3ba,c152215a,8cf8ca08,40aaad6c,7d001aa0,140bb0b4,dcac726,229ee272,e59390a8,21e8608b,e53fb258,a426dfb6,ca762fd0,9d574f7c,5555cb8d,7174b381), +S(281c15f2,ff06b872,5d0b9a22,2583cbe1,f29c6bd9,7d63db8f,426bbbb7,f36dfd57,ca452a00,fd4afd88,f5369ec0,5b3a99a8,7ebc60cc,db297d6e,ad1479ce,a8c87bf1), +S(69c61933,b91a122a,36087b61,1fb86372,3cfaec6a,5e51b4de,9db83fb5,cc5a1e5c,18b17e6d,74d632da,90946919,2ea6700a,ddfb34f1,f537e5ff,581e04c1,97437d78), +S(e97b38d0,9bc65cb3,421a6ba7,9efeb127,16fc82fd,b539f94c,1c068699,2aab5eb8,43244371,2d899972,a9ebfdab,4ab8a5d3,b7b14b0e,64d82d52,50b9875d,bfc9e1a8)}, +{S(f41bd2b0,e0f49133,747e831c,af4c7a0c,22d2b55f,1cd4ca53,1115d81b,b47754b0,869485d7,26d4687b,c57a9eb6,e90e93a7,bce3b523,998d16c1,297c996a,b68c4fa3), +S(b6161665,b95062e3,aefcc0b5,1220e1d4,dc6945ec,3f73ca4c,47449592,ca977cf9,edea5f23,e6dd49be,7d718fbc,d0368be2,ab3b556c,e1c1de15,1d811c81,44bfd39e), +S(efa245d4,3743d3cd,863a6144,cae9db8a,c7b80e58,4bb31a66,1b670b3e,a17a63b1,ccb90bd2,806117e3,3781f7fd,7ec24d22,b6174aa7,1c8b0f35,bd22e95b,7f5fd96b), +S(ff59688a,fc00c3ce,15e0b2fd,d829725d,28b9d07f,9fb13e7,61ea7f8c,c271914,9779dd1f,aa487c2d,b4c4bb48,3877a848,c329fe68,52c05a8c,7c8d1c51,95a905c6)}, +{S(67c452cb,e71c61c5,8aaf68cc,b1f6208d,5646432b,86774f8f,60081179,6d5337c9,d5f859de,a125aee2,11dcc7cb,b50b4fa3,ef4f9767,7eb94f65,b6a181df,9b938c0a), +S(247c1e17,4a3fcde8,580214e6,b791ad00,59a992d9,84a80f32,640e25ea,3841b18e,1a9f638a,74228a49,e083b3c,c233022f,6943ce4,457199ca,30f230d3,42fb15c4), +S(d36e3977,66121dd6,af8676ea,155f4898,c04ad6f9,d682841a,6811c4c7,2d0a498c,61c0712d,24db9d98,dd6dcdcb,e0a57878,b5cc5a88,d42c50c7,d5f144ce,a937ebf1), +S(b0a52f1f,2cad54b6,658a07a0,dd64c7df,e227aa3f,a32329bd,cf0dba1d,b33de23,c760832f,9be22f9d,c7d17a21,46255338,25ed8afd,1468d03d,d6ae5593,71bfad31)}, +{S(56d09714,cde8f0c,f1956cf,a56bb0aa,b73507c8,bc0399f8,c0fd17de,19e48e9b,d62e1f31,b40ca6ba,71de9059,8a9fb911,6c5f0007,df0c33eb,f50db688,ef0ab90f), +S(a070b352,ecfb2a06,d450cfbf,6800d7ab,6ecd58c4,a5d66c38,a330feb7,739c7dd0,226e8d14,8b074b35,db600e7f,4bbf40f5,c957e5d2,10b757de,3796f2db,1fa4e89f), +S(acf26ed4,9c8d49fc,69d83f06,168a7ead,77a0e16b,89fcd5b9,65da0d65,5dcb7d3f,54894631,5bfd024f,cfff92f2,df2e2ce8,987c385e,6147d783,612a91bb,5411126d), +S(33b944e9,fbcac6bb,4a0a2c95,168180de,fb88eb50,7cbe354,884af02e,dbf5e0c1,a0de73f,8c3646b2,dfeb126b,100a8e6,f5adfd54,2e26b225,d096d760,90f87c62)}, +{S(31095045,658b8c85,ec0c4ddc,7cbce691,d060181d,ffa08855,f3f36722,4c026225,9a8cc527,1c231ce7,aeb6e73b,9acbc16f,4b331b01,4bd457b8,799bad40,547c210c), +S(48472fcc,ddf9b0b3,99ca4d48,254695ba,4beb02da,849833ca,fe68454e,284998c9,a08a0346,83e54fda,d2a1fe63,20b67fb1,b58a4671,b4d08172,b1b6ffc3,c3852499), +S(22cbc8e8,e2d632e7,bbff1662,4b6b971b,ae0b1c12,14c342d6,61fccc2a,af196054,1fae61c2,9843ca1c,6ec5a163,f11c5c7a,1ec4637,4406f32,67a47c4,c111ef3d), +S(5024b68f,89c9eb0,fe4e1517,726f2cef,d270ecf8,182dd81d,20d65a67,8dc81c32,952869d4,4a76c942,ac9c0516,fc16b1d7,a0de7bc7,3fb1a18d,a7253d0b,cbd9019c)}, +{S(da34375c,e38127dc,cc88a823,55d763a7,2dd5d733,d9bac216,7c3e621b,ede529df,13426579,db1353d2,8095e1f2,a007904d,5c04a725,2c621ce4,41157aef,d2e28cf2), +S(ca76f69,937d5d84,659fce11,e1dce556,f450874,5c0e003c,5e474b84,515a7ef5,d2e10042,a71e3e65,d1290d8d,7b5389ea,4156528a,2633ba15,bfe900fa,c5464939), +S(8d7a5378,92f98107,3dcfea0c,9750e22d,e42066a7,ce3b4d16,8b1e56fd,c8a9b93b,ca32aad9,b5d0b83,8eeebde1,8eb7b526,8169b0ae,912539f9,49a1981,d6065703), +S(d58ca70a,51085dee,3d1c06a6,13a5a46d,22d1ba6f,6077df3e,f67b33b9,614869c7,bd212d56,451c1609,93ab9ffe,9371c3b0,76a2c702,d7c12823,ee66a084,ee82fbdb)}, +{S(a80dd274,9cb3c40d,af91b91f,6e8b0850,27fae17,96e416fb,8a172c27,d39e8789,466161e1,e9519ac5,e1b03652,cd1ce6cd,1d7dc696,aa59ab5c,565d822f,af427896), +S(e2313561,865ab364,7118595,e7a10279,4a94ff32,48b7247f,a21d2a3c,906cfc7d,9af6a874,d22254c,f148b479,7d70947d,3065d907,e01f35f2,6f14811c,bb1b36ca), +S(db567947,4a29e5aa,b6cd6cd9,9e92ef97,21eb61db,37b0d0ef,2807624a,e50f1b30,1132a05b,f945f3b4,3bb70fb2,1ef08fe6,c2d4f18,ef2fd356,73f3c430,6ee73ce3), +S(3b4569ea,9feb4458,1c89625,5f39f4d8,3f590d39,c50f3df9,1f061019,c8094e53,97fabe3a,cf3f72b6,c1f01688,690cdac1,c92afe2f,9b1a9138,b9951f97,ddbcdd8f)}, +{S(b3dee3f6,cc08c0ba,5b7ba3b8,50469647,34f7dca1,630e806e,f84157e8,2992c765,d523bf3c,6b004cbd,59db62b2,58395f63,d487d6ce,31799ee1,59ddf96e,d9bae2e8), +S(93c41e9d,ef80a2f6,93cbea0b,c5c111ae,11fd8a86,3940097c,b8753970,e3123733,83a51bb5,849464b3,ee5be4b6,5c5215ed,55e5f157,db8b64bf,aaed7099,497fee0a), +S(6ac20b8b,6c5314e1,72a39c51,a30fdd47,db16215f,e7ed2283,76f74eb3,718ce734,73b0cfa7,ca3836f8,15ef0ddb,d74ca28a,b83093b3,4ae41a94,e92ddfe0,89af26f3), +S(7536c8f8,dc949d7d,c43910a0,8007d6dd,8398f8e3,28ece93d,93b95171,7d2a6479,43e214ad,2c36155b,187973d1,bcdcbbd0,58448490,a1a835ae,2f661084,d8370a10)}, +{S(df9c2e20,68e1e333,f6acc6c3,ba9928eb,e761d4b0,27eaa1de,dae18079,29705021,491f455b,6e937f91,35fe9060,a8c5b6c1,60de5af9,ba90aba4,c060145a,da1b032d), +S(db3f1233,c95cafc0,a5ec4224,2a62e08,745dc259,28b9a938,e6940809,9376dee,94903b4b,2908cd49,95f0883f,1a11d65,880673c4,ef07aa9b,5416de42,8e4ed716), +S(a4eda54e,c923719f,8c4b217e,2c20690c,5986c871,fad99156,8a1f6614,4d48e91a,87736a5f,e71db939,3a673e7a,9bc89091,2ee0c459,5150b88c,792fc2a1,bad3a6b9), +S(ea2475a,ac3db1d8,60263b16,aaff75d5,3c68bd1b,da9123ac,951a8015,30961202,2e723212,716c3573,e58765d7,459070af,45a48555,c176af74,fbf212ab,ff29033e)}, +{S(afdfa934,6f7bcc74,ec473e17,f5048650,11c5251b,bd6c0c70,c25cb561,4b004da8,b16eec26,d575cec6,b8720f94,4ccdddd,78a5c446,a0cf286,fd933f6a,999a4a39), +S(e529f606,84edf5b9,5cd3aba7,233959e9,65639ebd,13c58d6b,c8824fde,3f6e94df,93354f65,e5299a8e,210a94ac,8a871f2a,a7a0a6d7,558fafe0,f67f7c5d,ab304610), +S(83438a3b,47df9b79,baabaeb8,40ea82f4,e7b6aa6c,49802c24,d380fdfa,2f453d0f,25fd4329,e2ac037c,46025db2,16d1d18f,395797ce,613c8c54,beffabd7,eb17eb73), +S(30b3d04f,76e7f7ca,9ddccff1,f904b937,dd972f39,11092f75,9070dd4f,f67cff48,b70176a2,30e72a7e,645c2122,4b9194f0,3c38f18,7020ebed,120df9af,588dbf4f)}, +{S(c8e9e9c6,55d9d7e3,16a16971,f7b7ed06,fa5a2ddb,56288169,ea96c439,6a53e01e,3bf36e6e,8cb2f52d,8a7a155d,1b3e4a17,e06ae0cb,b1dec52a,9b5fbb2,9f0b8a1f), +S(b6b755d8,3e6f1b3,e19a079b,daf2cfe7,22dceea0,2791b200,52ce09a4,d066f196,350f105c,6e52d1b6,da090848,1e338375,7f78a1b3,da3d64f9,eec159cc,ee2c425), +S(713368a8,f3fe29d9,cb8dbff8,6b74b41e,bf2fa4d8,11aced57,47cd800b,afa434cd,2a99e4fc,a4fa0758,8c6ff4ad,968323d,b753d9c4,42b81496,fb0cf028,e9c79173), +S(9e8a9fd0,23b165fc,8d95e7e1,39804c07,aad352cc,18b803d5,b7bf8ae5,5f2fb3,dd7ead28,6afc6105,89e1f4a6,386798e5,97e92401,397f8d50,2ad9802,71a1e81e)}, +{S(9d687619,c1c2c42e,3e466fd0,1ad5a0b8,b459ab12,642d80dc,1081ae1c,a8009f58,34fa7382,687f04f5,1fb15740,c31df8e3,145a0908,ac699527,983a712,23414391), +S(aff756a6,6ea7ea7d,85ba28df,fb25a543,f317f806,f18a4b62,5469ecc9,7e5468aa,b344ad2e,b5cbf601,805017e6,3f8a3d76,99ecfd82,28a9d2be,a7f34436,9e1563d9), +S(d7f37592,cd207f26,80c3e659,ab26a9f3,86270623,bcfd6737,fba2839a,a2ff3f7f,46a52a06,fec906ae,79a81333,39659e09,7ad928d2,4b9495eb,98e89062,d87b0d3e), +S(7fa626bb,98c9f1a,84db146d,584aa1a,3ae75f01,1a86800f,21c2ad77,eb1df5ec,c8a92713,ee8edcdd,3954b267,cd1aed45,929599a3,3d10ab09,5a1703c2,447bc9ef)}, +{S(bede42c9,3086c85,d6793a53,5fcedc15,6202042d,35051eac,a86ee941,aa961d84,e0e7ae8b,a657730c,2fc631ce,82b58bca,1dcd52bf,6f071eb0,cb7b9f7b,24bdeb5b), +S(dbc001ae,137b542,ec96adfa,367531f5,a88b124e,8dda4600,1b14433d,acb50db0,e49c3c9e,abd1e5c3,c5fa8df9,46d7705,e54f594e,d31a5b81,bbc9cf68,d15fd7fa), +S(e199e2ef,a5120572,b844d1bd,76b2b66d,e7f5d2ad,283d4b87,3dda2597,f739733,9926c3f3,88af1ded,eee14bc5,bbf3310,4be655ff,c3ad4798,5b8e4f13,48f3f5c2), +S(19df4eaf,d8bea6e8,edef3a83,415a7a15,a2c3a8a8,95d19651,6c0b0f1,1628f9d9,6e36af6e,9f01cd77,dfa50cc4,a647b222,d6503c57,b4b6cccb,7b9f96bb,d68fb968)}, +{S(998c1a4f,52aa78a,8ab3a94e,66d787b7,145fdaa6,4701c0bc,8bab6933,3ca18ec7,a069228d,355e75be,f50b4682,b210b776,95b997ab,12d87b3a,29e87b1d,289de833), +S(6388dbf6,171559be,2d7e02fa,2bebd597,c373c97f,95d7c4cb,614db1a,9c19a82e,b1d06e7c,83dd9880,a7e1582b,27b3be98,e2953cda,505ecf6e,3ee88bec,713e6035), +S(66f24649,523c8820,798f6e34,a3c0cac1,ebaf194b,c4c32c84,a8ec5a2d,2dedd188,ec6d60de,74e50469,64ab846,1d09335,ae9f657,bb8b6f7a,85e02867,11390425), +S(43784439,5667fc87,d1b4486b,f798d397,e6aa598d,be9f6b21,63fd8218,ea7c8490,dcf33b4c,5738904e,6a4a67b9,a6360ff1,e603fc6c,617a7b6b,17095d56,e6eb2989)}, +{S(8c422f9c,4e2aa24a,6513390,fbcd3531,50b28c5d,40ee8add,8c9d5591,6440cf99,21809c0,2c3f1879,f677997,919d0deb,fd8b2d00,5f249de0,e3df9b4e,8df20524), +S(46f4b7e6,6fc006d3,84e202ce,e1658299,cee653b3,db8672e2,a2e26506,8bfa8b73,d09d2a58,d6c88882,2b2ef6e9,3cd26cc2,4c20f338,50d05e7f,6c937a9c,f8670e7a), +S(a19360c0,66d42f02,541dffe7,fa9aac94,26a4de5a,8a756643,cb812e66,9be21d42,3dd23994,8e869afc,5ca5ca6a,f51fd836,7c612022,d9b78aa2,4a78b8bf,d48a7958), +S(53f1c8b6,f62e094c,3a814741,e2c31259,95fb285c,d8e12d1f,9130c9ce,b1eeb63f,9129139d,42e3c44e,f124685c,fdddddd5,ba9bf1ff,5a61534a,d48503c,b48568b5)}, +{S(3cd27c1f,ece87bf8,10e9c382,a0d7939a,de6f757d,9d0178a4,ea486e2e,241d1216,806192c8,1852c43b,d2439452,b42152e,b0f8a728,50f3af8b,be9670f,fc919897), +S(e00029c9,85a513c0,9eb33ad3,5d0b712f,30bed96a,48eda85c,fc2509b5,99f7b3c0,bc83f8eb,c1bbfb39,981c89f5,7c23912e,780e6cb4,e3a97599,28e51430,a7a205c3), +S(85282c5d,fe004218,1af469d8,8949c331,545e94c2,3a7782a6,4b5b2afd,7e2bc98a,88f0b05d,4032c6d2,8b4140dd,482fdf9a,724181a3,a1ed22a0,ba4b83c,fbd6a61c), +S(8e26c183,26188725,d12e7726,9eb3afcd,121c2b17,6d7678a0,93a496e0,9c4f65ea,a574d95,7e9eb080,5f83e417,f145a708,971e2153,a8ab8462,99d52583,8472e368)}, +{S(7e562c7f,87ba4090,c3147469,78bcb59,722627af,75555e0,ded87772,f67a5ef,433effc5,1a6da4b4,14f793fb,58961db1,fc6681da,2e367f06,331eae98,4c1f31d4), +S(b273ce89,62c52be5,cb23cae,d2b98015,78c7dae3,d10af405,461b4101,c0ff1c43,4ebad439,72b99896,f7f41019,57766925,f145d0ce,59424c8a,6c5cbacc,a3979f16), +S(dc301ce9,26e82026,38b1fe94,7d166507,642a89a1,509fe1c6,5c13af35,9fc34c11,a7230a1,52c96952,a6e5bf42,c4fb504f,12d2577b,40e8b947,53db719b,52ca6b53), +S(4a9fd32c,a97ed57e,83e5c712,5b7a2af7,3fa9ea4e,d96ed369,6aa9f0e3,cbfafda0,4659c8a8,b9d5c6c,cbfcaa9e,eb2cc24a,225de909,faba88c2,132ecf8a,da456ffd)}, +{S(9189ba51,a650f218,5b0e78b2,4fc81b3f,95896526,65bb6ec3,506eff71,71399ad4,981c7770,b6d9fe5e,f55f55b4,4dcd4b29,57ee7078,5cd95d84,d59bbf8,6049a067), +S(8043092c,79a5aa9,c85468f,3e95665b,f7742d3c,78e46529,9fa55525,df768f,5d4df375,eda914f2,49b3755f,365412e8,1f587da9,b444cad0,d3ff87e0,4a7d5f55), +S(c4ceb96c,c733f959,70fc29e1,6abc8ce6,61edb654,6ecda22d,854552ba,3ddca54c,6c1a710a,f15c503e,b2e4ce7b,341256b5,ab3f5a0d,bf1ae1ae,f47d12d4,9c6e3b4a), +S(ef2ffdd3,54249e01,63e49632,c12f236,f71dca92,536ac805,70792598,a46f784f,b121fddc,795491b6,97a1cd12,9964803e,68f60f13,55cee300,5d64f761,3fa1e3d9)}, +{S(b381f721,8381bcba,39ce4649,ded8aeed,43d5548a,b1b09981,a704856a,9b2af576,fd401803,9e993bc,1396a459,8270d4b3,f26f47f1,8babbdc,bfcc30b3,671302bd), +S(9b88c66e,8abab5ea,b4b0e3b8,10bcf0a0,d3987e1c,c53b04cf,9e445f2b,a50b1744,f2f8df3,6fdcb9a8,abe5778e,33fb1912,20b55224,85286f25,3914d175,cf5b85bd), +S(3da8ba80,a6744737,eb75edb4,3bdce32e,f6f1b74b,bc0f7f36,3cc2f342,209a4e52,d61d3a19,bdb8d194,1ee3e2a4,50d7e87,bd00652b,4a52c415,825185b4,a2ad1467), +S(a23779f1,b3716be7,82d4bbb4,3d81677e,d78ed041,c2786f33,49d56666,8bfcec02,33b57d01,c3f38b53,d96ebc7b,2aca2c08,66de0c9d,9764dcb8,dce0c27e,f4217963)}, +{S(e2937985,7de31ced,bca13b56,16a2b853,c1f6c915,8ba5b999,405603bf,eda41ce3,bfff0870,88508486,361a6388,b70638f6,7eacd5fc,a1a1e187,93b2c282,d4d90ec3), +S(42e86050,d6101847,d9aa35b6,45ec7a23,2fd77d5d,c60ad7cd,a10e531c,876187d7,e0a1140,b5e0ab81,79c4a1d9,4e67f6da,ff166fdb,48dd3dd9,4e110519,fdec0563), +S(236ce23b,a13fb252,ee19f08e,9a3948cc,f3edf6b8,9802175b,67d34e91,b82ca1f2,3b569c1b,5c8aae64,b154565,70d7335b,e9f4085a,a2c7e522,96094b93,f9642667), +S(aecaf4d5,282956a7,5831cc6a,a2c09b93,655ab061,1556fba0,8b81bcd,9d9284e5,efdd1e5f,f6c357f0,21d1fe01,d8c6f2fe,c2d0e85e,12b7fab3,6920e684,df21e93a)}, +{S(9eb2f66f,e59abee,bd7c1bd8,dc102027,e94890d6,d24cefe0,e0e3185a,d84567da,123480a6,b2109616,2f5c8bba,4c71ad28,b1ef6d3c,c6b864ab,eec3bfd5,15069b19), +S(e178a416,f501623e,5fb17e46,9d7ae900,1b508178,91f25b5a,83adc565,7556ed18,e0712be6,e78d1a97,452c35a,c19e0459,dd6762a6,9b5ec073,ad1d6ed5,8ba3b369), +S(99243b08,6c3ba8cc,f44cf61e,c7a4ec89,541019e8,65a04ecb,da7e4683,16b5e883,9fb51a9f,4cab9214,d5247350,10a557ca,403fa1c3,b55d722,19557d8b,df2de0c2), +S(c33c61e2,5ceeeb1f,2fa47e22,a93f16ca,123235c2,b7cf9af5,e712e88f,808fb372,a72ded7f,3a362df8,a0992be1,6ab23f52,996f200d,b4981d5c,9cb76712,f0a88274)}, +{S(46481a2d,9c09cf4f,e869ece0,3f065938,e144393b,125191de,a52975d6,f6e0f3f3,74245935,50f81ff0,412a2ccd,f0ec2149,a66a61d0,d63cfd19,74a672f2,ba3dc512), +S(b5d5fb4a,ff2752fb,114a8b1a,c285ad44,5dbcf4aa,fe8f75cb,31bc43a,4298d86f,6f2e10cb,b36e3f26,ca280661,3ac0c052,1fb0781b,214e404,92574c09,8d87e519), +S(308bac42,a25bafbf,93a6ae26,cf99cbc5,1a643215,2cfd927d,7250a964,bc459289,ab38c54b,5725609,3d83bd6c,1dcd4242,e13bd844,c2b7b6c3,b1fdc8e,f7c1abc4), +S(b3c63fe1,67804d24,bf0b00f4,1c4a0175,4886e9c6,a9047439,adf365d6,bca491a7,d0a1a577,da95a3e3,6e2657b9,f9804c8e,93b5e635,6e5fa540,4fe8e3c5,5cf89b2e)}, +{S(5111fd06,525fbe47,3fbd604,6faad331,e715cc48,d2851a8d,70b34c5e,35db531,96ffe690,ff3d3901,d9505f1f,a13c446d,4065ce5e,fabd4ced,59c4f8ca,440d1515), +S(bc12f2be,3b0f27e1,92c9d446,59bec78a,4a592f0e,997be28c,313d93ac,4769fb4a,143f1a68,1f6d69f,66f49543,b131a1f6,c8e3b933,271dd57a,3be9db9d,1f9c31b7), +S(edc09cf5,6730b640,689c052b,989bf0fd,de56d4e4,8079000a,b4e8eff2,23ab61b3,57f21a98,eadedef2,8ff6063d,53bf158b,c38e1c1f,6df2d6e0,5ff7ad18,47c91bea), +S(4ba6c933,962ee6dd,7b7a80fd,4102ead5,d94a224a,4236234a,72afef90,3537c70f,f84264af,c8424c8d,77b4cdc0,37f4fdfc,3b1c7dec,f0fd3da6,f696beb0,98b2840b)}, +{S(6d3b19f9,79986500,2f0fe9f7,67efdd28,73839d01,3b7f4cc0,842b0a85,c1934182,b261bd9c,c90bf00c,3ac67bf3,728ef44e,2aa1b660,6cfd4c41,20d1bab3,aa05efc), +S(b9e6fbd6,bacca67c,d2977ad7,458d006,bea2288f,598904af,6794cd1,dc819231,bfd5bcf,2aeca281,d596798d,482ab975,73b15bfa,db7df642,abdc727e,cf664f1e), +S(f2e3c13c,8e1da25a,3b05272c,fa653ef5,487ea653,6d55bed6,c9ee0e77,85325f90,7bcae36c,67ec60cc,108a8794,cb24a3,b70c5f0d,2d58c813,77dfbd7c,10972256), +S(1317a41e,f4f09481,db342808,63d49b1b,dfb2a11a,f843ddba,29499f1c,69cba337,28aa8ec0,ba9021f,c49e90f5,65c61254,3b2e6e0f,57370374,93fe349e,11ea5eed)}, +{S(5a9ce5ce,5b6c4aeb,88f47c4f,680002a3,d898da92,603c0513,d72ae0c0,239f10ca,c1d25370,ef453f49,7982bdc5,d7062098,1a0dcfe7,d07a0339,eadfc5bc,dd0d7874), +S(575eaa03,caf5e2bd,eea82550,f961b06b,e8c8a25d,a13f912c,856776a9,2c3cd783,732a2a82,da6c4d7c,79f5bef3,9b39831f,f8f79233,f9700346,fabff503,50624616), +S(b70091c1,99c77e1b,756625fc,de51262f,93e236ca,f48d6f79,d5ad6d2c,1c4eddff,d301345f,3d600128,503f3b0a,7ecb44de,f623c9d6,b3ed8cae,d676cabe,695cd53d), +S(338ea0d3,6d5d98fd,b95db010,633555de,c9cae973,720ac4e7,bfddc91b,176103f2,bd9e4e53,e18e541e,8ddb1d24,ffbf38d5,d2529ad3,3c043c07,1fe78847,63be57fb)}, +{S(cf850614,851d0868,16a329fc,f5c1afc,6dfdbbb0,ed9278f1,22de3890,cb693837,b768ddcf,f8dbe818,fcda1d41,1133a9d8,5ba6fa7c,9dc85b1f,23b3174d,69e3f33), +S(e3195ebc,5ee69554,73a626ea,14332378,1da933b0,fb5a1484,da2363d,65cadc7e,d0acda43,e7ff4df9,dd1f46bb,93e8bb3e,ff73644a,e024b5ca,8996a750,91928bd6), +S(5741cbec,60c5375f,6dc383c1,9b0dd4db,1a6a8aed,5658e87b,fef33a14,2e281580,66e9e972,2a6df27b,24500496,ded7638c,a19152d5,7c7adb04,74125ff5,1be6cb5b), +S(7e64bc9b,ea4c6460,b9b1ef71,95a4f4e2,5601d616,11ae689e,cb05b0b1,ade57298,bf43d8b2,65094986,324842b3,23fcb1f6,5d0896ef,1537630f,e42b669b,42758a62)}, +{S(17631e86,523e4d18,51417204,dde16c6a,bb7ded2f,2504bce,6683159,63e9b492,cc3a083e,e4622c59,4d934ecf,2471143f,4af9c4e,481866b4,637104ac,d815c97), +S(69d98c81,2dd5cd4,229eee2d,d82f75a4,986e514d,cd8dd1aa,1bed8447,e5f46fb,7d72fd27,40e91bbc,64a3ca20,243eb038,9cdc46d7,eab75343,8103f4b2,43e9de06), +S(76f7c0d1,c661944,5f0f5beb,568cdeb4,9cd483d,e5bcb737,2de66e73,cab23c2c,540422cd,994b4411,6ed2d068,5dc78193,fb5b5fd6,28e3f432,ee2d221f,8783ef7a), +S(6938d574,f67039b5,eb87fbdb,b759fcdf,4fc2c341,ac5817d6,8ea8277c,d4297574,5a2679bc,83685ca8,d3961d51,1a5ea081,8ae917c9,4606d552,620093eb,f399de53)}, +{S(60ad1b2,a075a3f5,fcf72668,cb48703a,f44c3442,23566340,b0fd682c,ae829ddb,534bb9d8,46bd457d,3574e528,87787f61,743b8cc8,e7b9032c,587992fa,c0ca2818), +S(1d66875f,42d8e75d,5651a635,1db1a820,725a29cf,74e0577d,833bf841,94e9a2d6,803ed33d,2188877a,c2e3d4e6,d78aae19,8d2eeb5e,a9e2c3cc,29cd5214,c20a78be), +S(cf400141,4811b30,70345420,e23ff7fc,bb800b9f,ea2e18cd,84b1b637,7b59ea39,2b8ca9bc,722dee2e,29996865,93178cdf,16503531,e3885322,d42b0ff4,dd091927), +S(ff2612ac,2f9925cb,cd76b975,b23aff70,428062f5,8f64a507,28b3021c,6548495c,e3bc502d,6046782f,8d2cd0f3,f5bd7ea,f661e4d8,5eebb56f,cf2e9d78,535994b3)}, +{S(4839ed9d,4a5e9c82,4c6ab373,b9cce0ee,6d8f19e4,2185c791,89b52aa3,52533187,a1663ed9,7007472,8367faff,33ba90f3,620b6b18,a816ff71,7fe8e97,20304323), +S(ea4b17,5edef6e2,46f8eb69,5bdd5b86,f06231d2,38303d94,c89399b4,af9a4531,aaf021e2,555632b4,da731da2,fb3fa644,2e8c34f7,9ed5a701,d9ff6be6,c3d3e7c7), +S(62def07d,3b90500b,548c2126,5d65f122,edf17b97,9defab64,3e702276,774ba43b,1caa772b,bd3ecd64,c83d903f,ae57a9de,49649abb,5aa7a21,2dc2a904,e97f9ad0), +S(b8cab6cc,e7898d3f,ffabaa1f,8bf0fcb6,fb00239c,27f33ca0,dd893d98,b2784eb0,96841107,cdcc5d3b,5c1c9c7f,39b92ff1,5831e400,73762437,7d062af3,4b0a1db0)}, +{S(63b931af,dd8dd850,d9b2f2fd,480e109,14365299,254ae0a7,b04cbc2a,def6a5a8,dddb17fd,8100129c,27b1122,34587e41,e6b47b01,9ed91775,b217a10b,3030288d), +S(a2a4d3f4,40c5500d,a0cca022,21cea8d5,89410fdd,7782d574,85112d8f,e6ffdd61,adbc7f46,db8b0f29,31dec8a,bdfcf396,96f158be,f6f28d4b,d88e14f5,5ecd7bd7), +S(242766db,7d3aa77a,6daafe42,1fc02bc2,d78bb495,771264fe,4f9ae1d7,837106cd,f9d7f63,7f83f5a0,6dc4cd42,af1aa54c,821f1711,66bb9c02,58ff6448,de3da6ac), +S(c089b764,f873e53f,9fb390b1,d802c7cf,e68f8dab,6f2ba524,4e309027,8ea60dda,7f83e920,b2fb47d1,c7b9aa13,eca044b1,7ab67d0c,94767d39,80aff8a3,1d9effaa)}, +{S(ee609aa5,cfe0de2c,45d1df32,707e4e8,d8c4c572,3acabf20,c95e8d12,9f237cdf,27a1804f,d2ecbe1c,9eb1958,d8b7898e,968c6e5,e798b2b,b86b7a55,f0b00695), +S(16c7fca9,8bc28613,af1133ca,6c3ed5fd,5792858a,73a87773,17c004d9,c88a81b7,7d6d7f8c,4ed838f,7f96a060,32d20e01,b792a729,57d502ef,575e68a6,c55c8b1b), +S(c2c5cfc2,4e16cf88,af21c30a,2e37461f,230a1401,2a970057,f20e87f1,de517cec,6a6c834c,bf6d682f,b1b4779f,1629b1b7,3feac678,38e34a08,74d335d4,9245c37e), +S(1c948040,7673a271,23dd0fd2,85de249a,49c94348,75ec6660,3d0afdb8,9edd4642,2122d99,6781bee8,628b27bc,cdc00293,43e3627a,f14e8e23,4a144b59,3ed887b5)}, +{S(a336ba43,9d7ddf1b,91b05a4f,72083cf5,1f8ff83c,15ac69df,7bcd2d30,c645cead,a99919fc,a5854c02,e7246315,477a6cca,e29005dd,e950c35e,7aef7d4,7e4cacd), +S(211e7055,6cf61cc9,9db2576,20048424,9a5cc104,e818857c,2bcfd86b,35f09d24,f69df2c7,d480cc49,8b605364,e4f64998,a7d26b26,f354dc7d,1780f0a3,324f4bb), +S(781b8f44,86276947,6dc1b3c3,f0935984,6e827615,b22cc0d1,4e92eb46,4420089f,c49a50ef,3ecceb1e,cc6081c3,7acd7449,73b8c2e1,9bdb9802,f55626d9,129bbe09), +S(62161d16,921adaa6,5aa8a7c,b3dd1dab,1e32f9c2,e4ddd119,e5d8a321,3e0f262b,eaae5b60,49d51781,ab479eb8,32153328,fce9b678,3778a06e,581fc028,e5352d8b)}, +{S(9bd360f1,9a65f3d3,757a6d30,74e793fc,8a972315,9dda6f9f,f84bafa9,8b70cfd0,d16b8dd1,5937851d,6382b0e7,f6f858f,862021cf,857f4576,2fce65fe,ef5081ac), +S(820f3f6d,f4747a54,563f4a2c,b1f9a2a3,4454d1ef,c28c4f87,2fa123e2,89a65fea,27a82421,216b7b0f,2cedbe3e,d45d4b1b,c70e47c7,cda3929a,f46d05e6,5b51124b), +S(37e88e66,33965cc1,c313ba45,6762548f,147eb369,debf6661,c8c63749,afca6d30,c2573a88,f797bf94,cb42d82c,c7e1dd5f,67b29517,f41c8950,cd27f77c,f4c4885f), +S(39d0df0e,22fa1770,3ebce0cf,753134bc,5ba82a82,b50886af,ddb4afa3,c67a2df7,3a05b6d7,3fef259d,f900ad7e,23ba9ca3,fa0e8c22,75a98ea7,d60d3ef8,5116bb2b)}, +{S(47686db4,ef418446,4955455b,8aa0cb42,9903b2df,9872087f,74923a43,6a5fa06d,997c2258,ba1958bf,6801fa6c,56a1eeaf,2f4d4f6f,16ee1ec9,389569e3,6abee360), +S(ef85e550,7edfc88c,697e9396,e700cdc9,70a0c65a,cded23ec,97e8fac3,637ff492,7edffbeb,c39d7ff7,90fc479c,704b5717,231b6c17,8a89a032,35b64361,c8f37bed), +S(4790f35d,c4cfc648,cc011693,d4de07b8,341a068d,b89bbdea,b5dc26e2,49673db,52b2c399,97870c54,98427e7c,3a1b1e6b,58151033,ce11d5e2,a07950b4,c0d6a228), +S(b4fe974d,2de71dcd,b6000352,1f2920c3,9c898c81,cbe9953e,41db3462,f298446c,f2f7921e,28e06841,1b7da1e6,81442a6f,e5df27bf,307fc5ad,90268199,eb8dae9d)}, +{S(17d69e5a,f192e0f2,693926e2,adbccce0,8aee8656,5b1838,54cb05f2,d8563ee0,ff0c4e1,bf955a39,f8d14bfc,68094b97,6f1f5429,e04b21eb,9a86e4df,d2e11507), +S(e275d881,a266b218,77523b34,6bd25e69,5ef771a6,b60bc0f9,44b9be13,fcb937f4,50917dec,bfb8c492,97254e5b,32635da0,e16f8a1c,cae44508,546e024d,b91710d9), +S(594e43dc,498fed,9206ecb,8cba88a8,789f34a6,c17700fe,b0b99533,3e18010b,100741ca,9d03b5ca,a094f383,78da3ac5,8d79081a,1015b133,1ce28e1,821eeec6), +S(15f7436d,98885865,3d74e5bc,8210a6d0,73e906f1,25f2f317,63636f8e,4d2a5bad,9b7d4de9,b9379a04,edc9b47a,851385c7,ad8263a4,a0f0735a,d990eb70,dfe860ef)}, +{S(dc728a2f,6062da93,9d72b4ff,2595991c,5eeabdf3,bdc7128d,2fc0f25b,aba482d,297fa2d7,8f62f21,16d3a68,e60bebb0,1bedb0cb,370bc401,30062a3c,f5e57c8b), +S(f842bf23,8f136dd5,db77b46b,7b55974d,dc4f02ae,80d80d4f,7979212f,442f2ee4,fee53360,1c8ae94e,b7fa61c1,5daf3bce,5f8d21db,1b38617c,d9a5d547,58279ae3), +S(5234fb57,d95b1033,21e67c8e,cfdf9983,c7f134f,fb105e6a,c7c11dbd,95a39d85,85abe819,a8a8df4c,c77eb61a,8ac1536,2985c508,f10f3280,e8585c96,f21fdd66), +S(bdcd155c,dee8a06,f8d6449a,f43af493,eba8c6f4,e3dd53a7,a7c880b2,155a04b9,be820a74,41ba1bb7,417901a1,99fc9f22,f5d8604c,42f10c5f,7d423081,505daf20)}, +{S(a00355b4,d41ed117,b9ee9146,de418905,aface350,60c02d8f,d8bf4af5,a20b77a,bdd0dd35,cd5857a1,9b3d0a67,a14b6047,acc7ffeb,70cf4409,633f53d5,bd85395c), +S(3604927b,eb1fa6ac,409d084c,86c8cbae,484e46fb,c9262f02,fc316fe8,ddce379c,5c92529b,1b66b9d2,9b060a9,10ed2da,4637e466,3957349a,83e9ac45,5dc17d53), +S(a681fd19,69da961b,35aca5ef,3a4325e2,12766646,4f63f019,90267865,1fa896c2,f3becaa0,377d0878,462005e4,795bad58,daaae64b,67b7db29,82d2516e,4c72811a), +S(1a87a251,7b770c6,705140f7,cea0bdb4,5abc9a6d,3a0bc0c5,1d801caf,907b635b,c18b4034,f7cddf7,b23673d,b8942ab1,93a698f3,15ef0849,b2c4601d,aca264bb)}, +{S(69ae3d10,523302cc,bcbafd00,1f40f48c,b4f918b9,65190983,24cf0479,f9175e18,e9583688,9ae86eed,ebc7f99c,19af452,7d239906,aa96c92f,2dc91f60,4704909b), +S(18641531,3ec224e9,dbdb0254,f810c2a2,85d477fd,357ec222,1b31617b,7bf51e15,e2900618,7bdc64f5,bb04c80f,7d7ea5af,2adc7d24,57862959,5a598240,219b2faa), +S(c3eaf844,8e1506db,eb0ad332,b26cb2c6,ed2c1d76,36a445b1,b0af2743,122fcf50,f6171ffc,88d5d448,d828a445,d59f7edf,fc37241f,2af04d39,1cdc4d99,8b3b9172), +S(2019838e,f4cc5420,37d97952,ac870d9d,abf443f5,56226166,9ce84839,df69e527,a70ac8e5,e8f76443,fd4765c3,84abb1bc,5ab66333,9c4c555d,8dd840a6,7f87049)}, +{S(90014ea0,f76360c0,aad4ec54,8698e053,1445716d,57e7bd8,9ad0c952,b806ddb7,d039a3d3,717a3b7,68822dfc,94c216df,26249d04,d2995fb9,559fc8a0,53b51fc6), +S(769e1d8f,67248191,113b7ab0,84103fbb,cf4950c8,7b19d6d8,65cafd44,b8bd18a4,8a7d2d69,aaf91be4,d4e86de9,35883b60,8b931f61,67b9e76c,ea43db6d,66952560), +S(a9ae4006,c04ffddb,ecc638c1,e348a014,b179dfeb,b9e8743a,b2d9fde,1a48ced3,30f74acd,4a29811e,718baea3,11d4f5b2,b70d4339,e83550f1,f4ed763c,52907908), +S(13f000d,912ade2f,c6a1c2a1,5dc7f3e6,380df54,44fabc7a,80ee4723,ea27af10,6dcd578c,12d35e33,1e202b81,ec93fd6c,30523f82,a524669,2b7896ef,53db20fc)}, +{S(8cffb25b,9df2cd59,a3d5efd2,bcd2f2f3,f96bd063,14c04246,a5c29083,eb08b219,113d1c14,753ccadb,4b5b8991,86c93f02,13c43711,305e7056,fccb8f5f,8f265714), +S(a3cf6723,3fab81a8,5c04d80a,5118132d,df914239,67a5e486,3f30c792,668fd49a,99274ec7,9a8b0188,a91971fc,631926d1,72923ed8,a91eeaa0,21494bbc,33ac92cf), +S(470e48c9,18310136,80712b3d,9a673795,91a4a7bb,2e25f6c5,59700ec9,b5f87692,3b9a2d0,d9ddcabd,511336aa,f0c1977c,2e09e37b,96664531,48b82476,6c562b8e), +S(eadf65bf,cb609b05,b000aed4,98e344ea,1913d376,c0200c2d,e2747e5e,a24d6900,c42cd81a,756dcd9e,687b42a7,2ad9621b,dfffa3a3,c8b7398a,ea0aabe5,fd737b96)}, +{S(68d83fa5,58a5eeef,8695eb2e,409a1774,61d43b2e,81e2d4f7,efcdce27,25a515f1,679ae994,24e430ae,7cc6d403,afcade07,eede7dcd,3d597717,fe93d1d2,3df076f8), +S(5a55b581,5c824e49,db51f218,913eef58,e8a666c,4191a290,b66ffa0c,abbe6546,8674ef7d,9ea73c1d,3a3915ba,e118c742,fd4d4e88,78adaacd,699963a,5eb9f796), +S(48d7425d,376cb7d9,d32b164e,920cbd7c,e7d174c3,7afc191c,66267221,6ab5489e,d8ffc4e8,29de5c69,dfad7fd2,3353bc49,a6e4fd42,c31a4b8e,16bc0bfa,ce26be4e), +S(ffd5b298,ed5a84f,e58e09bf,8df83308,3ffb4a1e,8c5ac3f6,1e594b03,406565ce,f56678a7,fece6530,6ab4a556,d7bdf41f,353c5470,d2b6293e,a97bc396,d8ee0fcd)}, +{S(3432345c,9df2e165,daddc0ce,9903a17c,2070e055,748a0695,123971ff,440a92d9,3b05179d,dfe73d48,4477c69b,434c05fd,55ad860f,dd286362,ac39cce4,5b7e5c47), +S(abe99ae7,698019bd,66615a5d,7df9c4b,cb498915,a868a48a,25ff29ed,747cff8c,f9b3f71,113c791f,b3353724,a812351d,3988b8ea,3a93821,db26631b,6907ea72), +S(4c493f53,3d4c0b6d,17fac73c,4301a054,75353360,1536da94,bca3b454,767b86c8,8c9743da,8b125a52,20a493d5,2c31440e,e1fb6fc7,dabe35e,7ac97c1c,94c85e0e), +S(2b73a96e,70fdfdd0,ffc601d4,9d78282,f997f73f,eea4ad75,f8c5d753,65db2f2b,994d51eb,c58dcdfe,a5fa01f7,522e5d70,1c21b325,9350b7f6,34c75fa3,1d4ab6c)}, +{S(bd721cf7,30d8cfc2,3bfd5778,67f40847,4fa01225,ddbf427a,c7cb73d0,60046af7,62fdc9aa,b8836c11,89e4cdc0,3d1c6c87,927e36be,2e4d55b5,76b1e6dd,91d7c11a), +S(3c3dfaad,d52f2531,cd835de8,b40a005e,aa2c015c,40366487,962d1363,64f4fa54,a2143a66,a76e30e8,150918d4,1d9eb97d,a69694ae,c426b6c5,5125f88,a22e9ef9), +S(bc075398,462afa25,57c6bb69,b6cc9ae8,75a490e3,e7c65b06,f7d70efa,166534fd,47309e89,1e0c1c68,c6a5532b,b34989d1,658f95fe,7dd7ce94,d2346e0c,15936758), +S(407ef9a4,a92a8471,400e2bdf,7620796a,410c648,e5a12c41,6fbab33e,2119512,60a1d1bd,aa7a7e88,d67b9d50,b20cf09,7888d0d4,5c83a55d,4ae93dda,49befce0)}, +{S(fd8ea149,749825c9,1fb53bc0,329e218c,2b49f62e,a56e7637,730f766f,527b7981,3c4cdba,1c38f4a2,82864b88,a58300bd,d885780,c63ce34f,4c7ba30c,5c55147), +S(e6163d4e,af44e81e,1e32226b,cbd676dd,1e299b6c,249f4fc9,b2706601,ae17f754,4f754176,cfd4ca24,b7c14b79,8149cb8d,40809aae,57a11764,4eb43e6f,22403d84), +S(c23ece67,f8260a8d,4d18b1c4,14ffa33d,d93b5a19,ee0903b4,c4765c03,414a17c6,8b448722,5b20ee7d,fe6cf78f,7220822b,e8afdf97,190511af,ac225a8f,1da22526), +S(3a73ac57,746f5de6,7deb557f,2bd4686a,72c69f2e,b9b2afa5,d8389719,5f955da2,7fb97414,c9738999,51310a0e,85e1e92c,db326de3,a5621318,6ad34638,832112cf)}, +{S(c6188e3e,4da144f1,a71ab806,22998e3a,cc580ae8,28b08c4d,f8ad88f5,5d0723e,d16037fb,b08be935,f89b12a0,810b2574,b7b0f9e2,5039c610,b60267de,1e8895cd), +S(f4eb0af6,b09cbbde,4203443e,2db7cd74,25b3aef1,4bd470,84fc9c6a,7781c45d,84e7dd03,9d221757,d29ef906,efc5124d,7d2833fe,b0d381b2,1d4a1e25,45615bb6), +S(4457652d,9123f6af,79613e87,eb90e62c,e4c7b4a6,3a5b2b2d,b183b23d,bd659f12,c3879b4,c4f249f1,f0cb1a52,874afcc0,46ed7c4f,5b346a63,dd798d0d,9179c3f8), +S(e5aa444c,ba5c8588,33e215c8,a521c552,bd6a449e,a202d2f9,32dbb6e5,4162adf6,111a1695,e7513c72,69e65977,3171da1c,8727b590,32de1df2,1d0ec7ed,67f5c16f)}, +{S(9d12d4d5,8f12e305,f34f165b,c5f000ef,823e4229,6e57a67c,22f3f2ec,bd5c5f7,f8ea4dc4,131d6d1c,d97bb52f,1c03a060,f1ca0af5,71269506,609f92e8,1409dd24), +S(1960c8c4,f9eae197,29769442,a86fb7cb,4a4ee4db,a577001f,13fa0fc6,342ccbed,dec5c3f2,9fa2f71b,992f3aa6,213f5bf5,d7c8a0d9,360c25af,b35f2bb7,776fbb74), +S(d5c94e32,5fad15af,bf295b61,900bb004,51cb568b,ffcd7f2f,c04e0f00,5a596114,e44ccfda,83eca7cf,babf25e5,9be125b0,c04c8130,4f188706,6824ce3a,7409a551), +S(db1b05d,cdd99edd,c6645c81,47aba91b,dcd1ae44,18e4a5dd,94812318,fe9f1e8c,f9818f9a,8b094718,2b88fa1b,689d1495,e94adb67,6e924637,b8dcd799,a1ee3262)}, +{S(7f07a821,c2102e7,c726a07a,892539aa,85e5e3ec,6f79691,37d79611,43b79b75,63411bd5,5ee5f782,e1d2788a,317d8689,6035663b,68b96438,711e74d3,aeb51ef0), +S(37d2f5b7,c66b5439,26e89aa8,f265679e,3b213098,6467fa97,27f365db,ba93c0c2,a1675968,10cf3f94,84455ede,f6ccfdf4,afc726ee,3561c081,8e535f74,cd324cc), +S(d041cfbf,b5f525c9,65fa7741,25b8f9bb,cda162cc,2b1f280c,a41065c0,56474a60,34c757e1,b819fe3d,fd62ba93,801491d,d4c1d05c,b973df22,fc64f23,1cc68550), +S(c640c211,f3004673,a3d8ca66,a18872ba,bbc1dacd,61347d87,78bb4d04,4892ab83,ac305f9,8a267919,68214e95,47d64d2a,c015c740,5619a73a,162287f1,55b1ffb1)}, +{S(760a6682,57ae7b8a,96c5c769,9039a102,cbaa111e,ad076621,88a45a4c,168a482a,ac81a374,c2da5e80,d22db86c,37302c9a,1b154e45,122f9d3f,b5c59b2,bee89a36), +S(5770bac1,871c8262,b4fff00b,a7520d55,d65bb0a4,7c9598db,3fcfee9a,27ff2763,825274f3,44421047,2390a3f3,a7b98de0,ce70bbf8,6d7241ca,a93b5955,24ae94db), +S(9432cd1d,8a62e580,16278ef2,c1ea2703,e628268,3eda8ca5,bd1a718e,6de864d1,5c7e685c,443bff0c,1eac25e2,489d0c15,eeac20be,bbfcb62a,a277938a,21901056), +S(32fa8231,6af1360c,9a58fefd,baf51580,6860463b,7325443d,ee873f40,8d7b8a26,b9879293,6561b733,948a7b6f,535e4699,515a442f,1006eea1,999be950,d2e04295)}, +{S(8f2a3f96,165eb6ed,6e04a3c3,6bc98bbd,8e224687,7e1f5279,4b9457e8,3a098653,cf4e0357,cabc0d24,b1eea14c,1b9bc9dd,e513584d,4d476a02,bfa3305,f9561360), +S(b590c88f,653caf4f,ef1395e4,3438781a,594966e1,fa38d019,c6297350,7cf9e142,b5f13a30,c368d049,7c3dbcf7,f7b07a19,350c5b32,248fb27a,a2a9ba33,5dd18a11), +S(71836bce,72f6b823,8edf858,ea84f2a2,4a0bc6d1,7419d751,e14a4813,bc2668d6,3156f04d,c1b89f36,1e7c878,94b92a87,2c63898f,38cfa4f0,48cac403,ca57fd5a), +S(1996fd72,66c764df,a93b77f5,c158a41d,adf46d38,ada30dca,62919df7,ab256fb,3990ba0,814ff4c3,48822de7,a4e67059,242d4990,78bdf784,28dc6c97,f66ffe48)}, +{S(fec456a8,6cd530b,d0512eec,301e3ef3,d5537be8,974bc23d,60e2efba,71b55ce6,bc77af1b,426e3427,6660dd70,2ee322ac,d1e19d0a,7b1d41a9,8bbe3866,9d087371), +S(9cb7d661,759605b,2237d552,e4967b9a,986fa9bc,8a602343,edcc429b,1b20b0ed,217252c3,1413ebaa,d31cbd1f,d0f6ee4c,4193475d,581806a3,6a864be3,918c9f8), +S(d95a3a88,9c8420d2,fc6b4d65,7f868305,3ba7888d,c946973e,647c6acb,82f4d86d,d7f4973c,bd3ca3c2,fbed8b4b,e78d665d,8140530a,ed5b81e0,c5ca04b2,c8cbb617), +S(8cf3ceaf,7cd77738,d6941ed3,3215ccf,cdaf13dc,910f126e,43356a45,bc9c2822,833e822c,cf90bd9a,dd06b052,dad6b73c,b5ee7678,c1a5e35f,d3e851bb,a9a9a6ce)}, +{S(a258e5e6,e1aac3d,707c5567,a9caae47,1b21224b,87828cbd,537f613a,6cdaaba7,d349347,e8f24cb9,1202c076,6c7247cd,e2eebe9e,62baeed4,aa51191,522c2c07), +S(f654c148,6e9e5a4,2ecd19c6,9b42e27b,94f3c3bb,3407b584,42684229,da0bb67d,cac5b906,d0665fc1,d7efd4f8,d1927f4b,98b9199f,69ce7614,b40ef0fc,dce340a), +S(f30d89a3,a536db35,b040eda1,5189a2b8,166a9e06,4cc92952,386be62,2f43f389,79ace00,4153547e,bbb903be,beceeb9,a916135f,42cb9a29,54817f9d,cb11deb1), +S(3e6e3577,bc22620b,e9a97210,74bb4bea,97379d57,bc1ed61a,33882224,305e4e1f,f634a97a,2e483822,3c4ce4de,50dbe0fc,117ad913,c3dbd75a,69ecaeca,1d413d62)}, +{S(316c28a3,63bf9651,2cd9f688,1bdf7430,dbf7e594,e6a7cff4,bd991c18,d2c0833a,4222087c,65b29e96,7c2562a3,4a491c0f,5ab5db22,2fc30d37,4c1157cb,5bf17741), +S(3384a50c,9f621970,2bfeb9f,5b6259ca,6062004f,b4375f22,22259e2e,ad496236,37afa3b5,23a6c185,3817cb56,e5f87e20,5f57f186,75b66ce2,4c1cb55c,fbe63b3), +S(32082a9a,45f6bd5a,90cf0efc,8c362da6,5f01a679,2c735f2e,a14346b,984279ec,fbfa9371,7ea480f0,a05c9de9,f6a50ed4,5a36b950,fe837c96,b8eda38c,1ad79b9b), +S(d7d044cd,fcf11946,97c63a98,94b56b2d,2b328eb,8fbdb2f7,f919479,2da1f0e4,46da7078,4a495b7b,e839d3c8,10cd7624,5f501685,15661bdb,4e786135,271453c1)}, +{S(3ce0395,6908baa4,1efed22a,3cd2b18b,e14bc3c,a17e8e46,7f757e56,5314f27f,fce17fc7,7d007d1c,25558760,d730019b,22ac9cff,6f4ba689,a1885b2d,5f0d0440), +S(2f5a7352,11a250d2,cb126237,c2c8ebdf,e9d7c628,9a319903,5a1ede18,b585cbe8,e3095320,3f1a2cde,eccb1e9d,5be869eb,f447471,9f7670de,f1b86cdc,fae5da73), +S(e86666e2,980948d,28d2baa4,c4a49d55,fff25b39,55695ac8,11ccd6d8,f882988a,823aa73d,20c0f848,66a8c63b,5631db07,b8a15f5d,90d79e3a,16c4040,a5106987), +S(1b1ce843,955f9c8c,28dac111,5e8a357c,dee3b723,70d1cd36,9d03a3c6,1b7e7342,5f8648e0,4965445d,cc8d6917,db45d7d8,3145d7ec,71f6e117,8e773724,a39e784f)}, +{S(feeaf523,3f208ccc,11478774,bb05c1e1,cc7ee923,32e6f84c,970a0579,aefcd4f2,47f6e6c8,3e5bf7be,5743f776,e607ba73,a83ffbc2,f1c581c5,c0cb1d98,b10be58c), +S(42086c81,d2685972,b69cc8f2,8fb8e949,80417664,76c11dad,1afddef7,773d72fa,b0e1b1f3,79082879,512302b4,1314b3ab,5a3f739e,aa8ac1f3,cb82ebc2,c2f9d13a), +S(5f8dd0eb,57f8a8f9,d1605e28,987aa1dd,bbbd05fe,8ae2aece,48fc6392,3bd6,c7daf790,b90ce9b,a73a3c1f,4b30a508,d41c0d53,f375ca86,b0ba2901,dd9ad482), +S(c92aad54,6d6046c2,4606c934,63391e5,a13be77d,e3eefe17,3b0011bb,129d3ad3,288c9ed0,2db46521,c9249b02,8f262b1f,9e684530,2cba4ae2,506025ad,ca0b8168)}, +{S(e3ee8330,33377c46,d51c8aa0,7919485a,ce3c3969,e533150d,a3e15479,f26c80a6,f757943e,9569814d,1d6bbb71,55294783,500c75d3,7510ac98,18497bb2,9388ca8f), +S(95811875,6d6505a0,89b46ec,648a2297,de391535,d3873b83,a7db485a,1ab8ae01,baa7fd9e,bf67d8a8,c1ac73dd,69bf264f,e0da962b,e26ce223,dd3dd5b9,8154e3a4), +S(1ea76ec,a1955521,2aab3141,173ddc67,8463fc79,2e887297,a713fea9,b6064fc8,c8b34073,8c73318e,d757034e,c947c5b3,ba7baed7,3eea8ea5,2c4d5b37,6186e283), +S(38281ae5,371b347f,bec1e9c7,841cb3d1,5a7ddfa7,684e9e93,e2c12cd1,acf0ee5d,8bf4f92d,92fabcab,c814e790,21ade825,448ffbc8,782ed1c5,60c72149,67fd5cbc)}, +{S(6bd00cc4,657b1902,51f8dd4b,9bec4668,b0c8cfb9,651395f4,8badda1c,a1dbcd3a,84d71092,e37a7401,810b17ec,3e0e4871,27c4847c,afb24d91,241514c7,779c61e5), +S(804cb958,a76c7348,17a62e10,2b1247f,462438e7,b0b3a96b,c202dc5b,c18de9,c775f60e,9e39fb0f,788e4447,fbc40690,ccaef5d4,2e9d7e89,e6ae41b5,8fd2fcb2), +S(d1050190,fb46792b,c29df9c2,5f2b9e48,99125548,336115fb,b7449c74,681c16ae,d677925f,e9448af3,76734c13,af2f7433,a9ab84cf,b7a6c4d5,d6091afa,766d878), +S(b81ee327,adb39987,c8d65543,7b7c771c,9061623c,bf36da42,ecc7c226,4ef708d1,6ec466cb,a3a52bad,a9f3f7a3,6ed90d4a,857a3570,610023a0,94fc5107,df2056ba)}, +{S(725d64c,4128d78d,11b4f7fa,eb9f04fd,9075ac9f,e1129eba,8544c3f6,685ebe04,36eaba03,94b7511,31a9c5f4,292a7307,1862fbb7,c43fee3c,1e5eadb2,7fb65db8), +S(40069204,ebd45314,a4d757ce,5a4020c0,e36f3bd7,fff73d30,60628b53,8d685861,d81134bb,5ebd3d7f,10a90cd,369ec3d6,9cab48c6,f49e5583,d766aae0,4d466d27), +S(901a167d,19e00cc5,14b3b724,759efa64,3eb7a8ce,9466eaf1,b6fab1c8,63b6f9bf,e100d9d1,e1451f09,2b5c1761,1e2d2376,75b1c95a,a71a052c,e7497a63,a9fea105), +S(f0fabd37,39f53d29,801e00e5,304cb5d9,a3553226,fff9ba5e,c8fe1030,26739c1d,cd23a575,ed09eac,f8446c8c,7f311ecc,78acac27,3a0fd6f7,988bdac6,361a4678)}, +{S(8f4e8dd8,20d7e026,ce2fba81,19028ea8,758f99ec,f7bc2f09,d239d60f,24027c9d,81b9197d,7374975d,1bcce80f,1a8a1e84,19a7a656,70a5dc21,49b00aa1,60055743), +S(e8e4ac24,1b8568c4,cec4f08a,9badff38,87c132e2,47add60f,3c39cb7a,8905027c,89c74e18,74737819,6fe1a4b6,3b2893a4,865de0b0,775598f9,33504aa5,ac453a91), +S(e6a8a510,f7316ef1,4e50e9f8,c8843220,c03df75f,e508d820,f3fa0dbb,5e9d0f94,1ecda600,14fc8668,32b1f2f1,b80ccb12,aabcbf94,f74f0a6d,dc6c692a,a20040af), +S(752c8264,bfb10ae3,aebbf561,3f65d191,d2956e3c,a7578e53,2a8b85bc,eb1d294e,1ff5c140,6558073,da1cc7ab,fa80d4c5,d557612e,c990206,6fd895af,11cd493c)}, +{S(9a9a4dfb,615c1e79,c2c19a19,34300742,7329b1f2,b7ae815,8ed8ebf1,5878d02e,39da7ba5,f1b9754b,e6fabbf7,a45b7ea,5cbcea2a,da2cf2bc,82aac66b,468af931), +S(14159eba,90d658df,ff2a3726,9ab60c0a,7540c68f,a77e0339,8caceb5f,6262d656,4497a299,27b365e1,35a77f61,bb6bac74,6918e3c6,79f97021,972c6013,d8109e6), +S(d4d3e7c,2ea5fb74,45160de8,19bec4d9,bc843b9,fc14fa74,6c0cb842,1b02a765,b55606cf,557bdebc,90da9255,f6a38a95,5ebc5998,bf021708,ee0a91a2,147ac684), +S(1acdbd72,130fda7a,122e015c,f3101670,d8090193,828710bd,1ff2b242,5d3ed896,b8cc1086,347ace8d,858ca6bd,56a80125,7d0f4333,b26541f,9865fb44,c5f349d7)}, +{S(93871b45,831fe55e,82338224,aabcb408,26c13f29,64c57fd1,b93711f,4ea53cff,79303c6d,1a8054f9,d66c5524,8ff9cd8e,17b5fdca,f9fa4388,9b0055e2,15c0a54), +S(8319d182,59cb7c75,228d314e,7db1db16,e34c9f62,2bf4e893,f06f86c4,3122dc51,5cccb4e,e295cade,ee396b80,10f6043d,d9141412,b8eb4216,60f9cc63,ee96f6de), +S(1d139778,64726f8b,7713beb7,6066df5d,d5116728,d5688fee,e20fa12f,14f9857d,3fd0294,d9ba6e7c,7a08bd63,d747365e,eadabab7,5ff1ca8a,95174569,c6fbe910), +S(a2c17270,296ad5e1,7ce111c2,899411a6,276efb6f,d6794a7d,212fc3cb,7d9fba31,b0a2e976,582022a3,a2c636c3,2c0909fb,533bbfa,193f8366,e65702c4,e0d8629e)}, +{S(24b75440,39c1351c,ccceacda,d31c758c,206331da,87a277ea,588a4376,82dad76b,854ebb44,a351e732,d900a1de,dbb0a5df,168a311c,4af01dd7,64722531,a3132213), +S(c89cdf5a,c0bae450,ffe0bdc7,f01ec47e,8a036cc9,43e0cd72,245cca5c,308d0087,e54935fb,6eea8620,a8b85fa6,d63d14ea,16c2edca,92fd6adc,7feabc35,91599acb), +S(255e5f4a,2bc33aed,aba2b7ec,b22ec225,30d3bb21,f7a63be4,bd5e2f6d,ad48e927,79cbe440,8da8c79,74bfc4ad,2715e2eb,eec2c950,8a01538,be795d21,c462b208), +S(e1497ffb,ab348f03,ea075d4a,bdc3d5fb,b2b9b413,5dab5190,2d8e1959,2be57e00,e3194cad,50cae1f3,7e713ad2,5bb635fb,74f6cbbe,83782411,65a8dbb6,ccee6faa)}, +{S(b9ed5a31,aaa443eb,99d8afea,7b32b81f,5860946a,5a5e63ae,def2a6bc,25c43f9f,e5bf15af,3e0a5fd5,12a14a6d,e03ce09b,a82b2fac,6fb8e16b,708752df,95f080c6), +S(45b0720c,7c7a16f5,9e07c7a2,b9f79ecc,194c4497,2a076bfe,cd662189,f51b5f4,b8acd754,a68d90f6,928fb515,d51d5c86,b86a832b,1506a251,447430a2,f255bc8f), +S(8a4c2587,cd27e533,7d848f56,43327489,19d3aa88,6d4b944,d4d44689,5cbe1ad,581ce4f3,7471bac8,9e904daf,c42013f4,2451a155,6ba12aad,deb02653,95926838), +S(4cf058d0,f5959eed,87402967,781dbfa4,29df9de1,327633f7,a6b354de,ebde5aaa,9254c0b5,709fa08c,684a59e1,1864a10a,3c4e9359,dd91b39b,15066b2e,e678a1a8)}, +{S(49208997,3351bf26,e5245cf8,afc6a69c,baa24dc8,5565ef5,d39e6a05,8b3cdf17,a4276fd0,1f754f88,11bdd14d,d1ced0d7,8bb7843f,a876e7d6,9531c223,2e9c9b4), +S(7b098cf0,f897637c,cd32c99d,de95acd9,2e05bb47,b16a58cb,d5e97827,734648f9,1d4e7732,2c99b9d1,dd330ef6,e955138a,6d0b606,1948b067,edf1c39b,61ab0505), +S(222b1686,82ca8f4c,b333da8,3a1f3cfb,e19f9e3a,8b597ceb,ceabd65e,720af23d,7278370b,c722a13b,d90164df,41323da4,6cb7b346,3c1428f7,265cbfd5,6d0d8d35), +S(97da8a09,8a3507b2,b5f330b,b405762b,cfd5c631,ed835bb0,842ad75d,a2175c31,5c051aef,a278fcd9,a2e230eb,993fe8da,f0c06306,14a5a6b1,799c0cd4,d3911144)}, +{S(265747dd,9f0d0396,faa54221,4a050192,3de7d376,f13768a1,50daa098,92ca71d7,412f5e39,db7cb201,3d083c20,19ddcb27,2ffd0a0b,89413e81,7718bae2,f1120fab), +S(918a2f6e,863bc4fd,87b5db45,15571d62,50e87c47,fca0914c,2b76d9df,185c0a32,a5551dbd,5c739407,880a5487,8ce218b6,766f0553,78f1a053,179ed3c8,3f362ff6), +S(6da6ff1b,ecb936d0,1ea353c4,ca3f949a,90153ec9,13329206,8b9be293,ae28998e,822ea180,8265bfb2,3fe6c6c4,51f62245,4185a813,e3f61604,c89044e8,555ae0a6), +S(bc0730da,9a06486a,99364ded,b612fb7,ac36cd21,466f7acf,e0be262e,55e0d269,7cffd8a6,13cf43cf,7eca904f,96a9e9dd,8b54dd22,49372095,95483592,64d7b8a0)}, +{S(96f6ae9f,84281919,50583f91,d4b76ec5,3c01dc20,6d06d33a,2560a8fa,11fe5daf,aac32455,acc71276,efed23dc,ab42fb8c,24bd18da,604b913e,bdd1318a,d1bc223), +S(f24cfc1a,9a29848c,f1d996d0,7fdc3ee1,ff14d1a3,a7811f18,e8bdcc47,a7806534,e0e4363d,2a227fc8,2df704b5,316410d3,a671ea2f,34702c0,7208fb27,6c1d12df), +S(1123af94,e86f2def,561f490,94ab160c,996f1955,dc2597f8,fe765c2b,d4793679,39d160a8,caf4b2c4,e4e95087,6e9a3183,55d4da27,9c7e2429,9762065,af62b2c1), +S(f5b8a7e4,6d4b110a,46d12dac,d308dad2,3f7f497d,b5a8a76d,c9577da6,f0943430,835941c3,b12ead86,6ca3f05e,c4b09953,9a8ab640,3e450590,37a990c6,88c1922f)}, +{S(f307f4b,b76a7bcf,1fe75d85,60a4c64,c748b32f,489e30b6,170057ed,225c9e95,fc200ac2,3ba3be6d,aa4d4f86,c89fdc5b,8eb00f8c,ebcf6a41,51411042,ad181fb5), +S(dbcf10f2,e43ae854,85fd600d,ca9ab27d,7ba393d,e6a333c0,7901cfc4,55352569,48d4448d,8ce674df,d254f09,17fdc390,de9aa8ff,29869da7,4c2529cc,dd476fb8), +S(38a07202,a23d26fd,663fa7e1,8e8a02a9,2631011e,57731024,3e717ac3,a0390078,fb6057ac,aa4fabb7,c4e922cb,ab2b7fb1,e4f0b3a7,6be215f7,7de296d3,ed709def), +S(5bd3e7ac,5f8619f,5db77e69,f7416149,b4afa5c7,95d25fbb,fb1da1ad,9e4617e3,9ae709f0,d7278b4e,b66919b,c666d63b,46bc228,8ca956eb,2e20238b,24725d56)}, +{S(35e48872,5074158a,8d2ed392,d178f6e2,e4c43fc9,689b32d,5f374c05,d637a53b,95143742,7bb0105b,5e7f60f2,d95ff164,ff808b7b,c2ad592d,68988e5e,bb5d5679), +S(8619863a,d49d8ab5,6c999e77,4653e1a7,4acb7a63,edb65840,76f3b3ae,903f3579,451500a1,3dac87a8,ace7fe4e,64dc6174,896b5002,67163bea,1d3db275,b8274cc5), +S(afeffbdc,dede5aaf,dc91475c,100918d2,f59039df,b5754f58,a330a469,1855e858,e05eacad,fe537099,35be0173,3d4b4dc6,7674d1a3,7d911d02,ea4f74f,6b63da04), +S(2b697c1a,2d2de701,16536722,945e46c9,21f02fd7,d8e9fd46,8fa9f159,1dec4273,6dd6ad5b,44541355,83b4833f,10de56a1,ed16c5a8,77d593ed,2538b95c,ce8785ef)}, +{S(cce6ccb3,fc1cbcc1,1f40457f,25157d24,6d3fefa2,24c340f1,ebdb3b02,3f02e3cf,9797a15e,ace0c660,eb93b185,7f6de7de,2d1d0f36,8c9a2eeb,a53b2860,b392bf2f), +S(71e75cd4,592214c9,556dc1b7,a7c8c5cf,77ab0249,a6a7ad9a,378e3e5d,d150939d,4e0c9607,c1b2866e,214f38e0,d4759bf3,b38f1f7a,35490b6d,70cf2e65,fde90bc4), +S(dea94d9b,c0222c46,c66012bc,91a3be34,d5df8157,56a9d97d,52c8c4b1,24ed243c,b3df667f,2615a0cf,2e7c0122,63af5067,b47d8cb,d22425f2,1bdba132,5e333588), +S(67bb4796,c88ec279,87e7d4e7,bd2e4e9e,bb1806b,95d3d8b4,e1a5d367,64e6d01,2af04b47,62d5a122,3bd0fd46,49be2b1d,92df5d8a,84ceb205,f2b70f2e,b5679290)}, +{S(86592c40,71b619fd,27e3825,ca585cdd,ea068958,7b59e3bb,b3581075,a3cb8a96,923844bf,2a197b85,b232b973,2922ce0c,a2431dc4,a59d27f0,2ff3b2f4,af7703bf), +S(e82a2871,fbff9467,96109300,26ffb096,d9509b43,6e786697,e85c57b3,389f4fbd,7732b419,f0d682a7,9ab047a7,d4a51685,fcaa3c8c,cd8115bc,4f7514f4,1717c804), +S(9c079fba,32d2288e,a0829fa1,1482dbb,8032397e,c676d744,c7b0ce84,a1c4f539,2b171739,85fa643a,ba7314d3,86f086c0,d4884b63,4062a4c8,3f7f05aa,575936a6), +S(78ea5f31,1d3c1943,e438601e,a885ae8e,efee93e9,26768d82,3e88a71d,9c22d773,953cb0dd,893aed33,9021e63b,277cca61,4d772c7e,a2b8ea3f,bd151b14,5cb144bc)}, +{S(4929a368,f9842917,73f5236f,dd5cbd7f,a8e8dd9f,261cbab,5948ad57,798cbf79,26a2a40b,33630e55,7b376fd8,134a8d48,542c08e8,c2d01a99,586d33c,66d37426), +S(bb4b9ce4,b8dd22bf,2873b2de,f29c494f,621d89e4,aebf3c23,566e0cd4,b4ffd288,d4f81742,4f778966,1274fc8,e8aa5c54,4434fca7,6b73b639,a04aab65,8bb77c2f), +S(6ff70715,17bdc2a4,c0267caa,38ca96ad,8a235744,2a24db87,a07cdec6,c3b022fa,2f16b295,a2db7a6d,321280c3,a53dfcf4,674dc215,38e2a556,75cd37e5,d3ee7362), +S(b5619c5e,edbc92f0,c88a9cad,9955a08b,764dd683,361bb7f2,8c611857,d473c45b,11f6864b,36116181,d2af3f6c,fe738c84,7820ebe1,53f0c82b,14e5c67a,b3a2213e)}, +{S(c7452697,d7691662,ae3b754c,7be11df8,ac70cc8c,e2e80a9b,9638b0f2,a323ecd5,fe84e963,3231caac,63a5c7cc,90cef693,a69ea140,c846e1b3,b96a6fc6,68b43c68), +S(c797ca59,95cda70a,a33093bc,4f7f83c6,1a31ab1e,dbd6f10d,31e0da05,64f41407,ce4a64f9,ae7eef1b,7abfad94,f4a6a7f1,c746268e,9006995e,8f7d311,1b81f85e), +S(288a2e26,8fb8fb28,29bd9d21,4ec5860b,fc1ed577,f40c6184,79a0b921,c2f4b67a,8343d03d,556bfee4,b66ca598,f4fecbcb,aa2723c2,f3c35203,ee12710d,d9ff0b52), +S(7aa02a72,adefd779,fd994c77,697ee142,dd25d168,38c8b8a0,5178b7e7,37f33032,a060f7d4,8e0c2929,864208a7,1668129b,3b3908c3,7e89ba0,e7e55aa6,5e3ed98e)}, +{S(34925d1a,b1c7c081,e945d66d,60ed394e,f474e38a,423562b3,95bc51d4,c4f55321,8ef8dd58,ae1661b5,a7c327ba,ac4105e6,d02d6a30,2263c5f8,62b712fa,b064e562), +S(2bbf19eb,9a6211a,7881c7e0,5483a318,c9d91280,d09e0634,2a54a9f2,b5654be8,3cf7b41,bfab218d,e182cf34,32450abf,88da1e16,fdb79699,ecfeb962,39d422d3), +S(97f1b30a,6ce2dd8e,1d0358fb,45b432fe,be6d9916,34ecc7a4,b7cb4f3c,f1663fb8,c7cba22b,88a5f5c4,498f0f22,cea6830e,1bb44e1c,7f9d9833,60139c2e,97dab7da), +S(b5d0e718,621a0a40,c2adf34a,3e1e64d6,bbad3598,e6944436,f8f87450,575d61ef,2e43eb70,8fb8e2a0,f24a1a12,7a890c07,d79b51d,60e3a281,649afa3c,182d5b77)}, +{S(463080f9,19ecd42f,593dc20a,2d3160cc,74d9592e,446f299d,be5446f4,236a5b17,2a65200d,e1b16975,9d5c75d6,fa6c666,ba45728d,343d6339,48233391,60c14a16), +S(547eef23,516851a2,2f160ec0,781a49f1,1480d07d,2607ab5a,89656c94,2f774b5a,eb6f249d,ee624cae,cbc59f02,63da0fcc,e33a515c,843c3632,661f13e4,39c4f0e4), +S(77f0c9a2,51d48b39,62f92e2a,679fd9cc,f458f17a,edf588be,d4bd6448,47f9306f,355f4827,b10e614b,4590242b,da546e53,dbd419de,1d1a7fa3,208d9350,3496db0c), +S(81e606c1,19b6ef80,418aa008,7ebaf9d3,7adff1ff,a81f739a,172a580b,27c7545c,ddb0404c,e56113c5,93920382,6d2adab2,6590b509,45865406,ce1fd256,6565209a)}, +{S(92d469ed,e0969dd6,7e9d7b31,f0f703e3,97cad53b,e6101b2e,eeb8714d,645eaa9c,24a0a786,916297f4,6a53c7c2,29a3c95,80eec521,355b823,f0488460,39595dd2), +S(e5035341,5c49c24d,f672a74e,4eb2d108,57fa987a,afc50178,ffba8797,5503006f,38522661,fe682984,7b6dda61,9dbbe47b,35c0c9eb,b79b5d2f,2c6ba882,26cb95d4), +S(d0777020,cf6dc469,cf020ce5,e64bc2e4,1e2bf116,4f4e814f,18bbbc4f,f468b0b8,997b2163,c4670401,281ad84b,a914cbe4,e76a5cb1,cb90c1bd,ecdac585,621cb0a6), +S(881abd9c,717f0a2,360de50d,66a9b655,b9459e62,80a985da,e811f2b2,154e307a,beec571,1375031f,354dda5c,b9d8377d,1cb49816,1f4c738d,f6b9d323,f9acacd)}, +{S(ab7d18ba,955fdaaa,b1a0bb25,25844e2a,9d2e204d,ff224588,ae96c41,e690e010,4e0090b1,dcd619c3,10ff5027,9c534612,84ec2467,77b63179,c80724c4,42d00204), +S(1a5982e3,37e3eb50,e679f24e,c3473b4d,1af3dcbe,ac3c7a96,a95f51f9,a9875266,dca6c614,85d55985,1fdc229,56ee59cd,fac74069,6276299b,a199f39c,869e5c9c), +S(bcdf870f,8d5394b4,f1f3446c,a25ec6d,5b4c939,b598e596,814a6dda,a054bb2f,71cfbdd,d1aa7722,892f83e4,ea2dec50,81c4d14e,548a16c4,2818b76d,5721fb7c), +S(cb28eeda,338a5088,db505da,949cddf2,741e071e,378f92f1,dbba270e,9c322c57,d98cba61,cceca53f,7d84d71f,f892b962,6f26e156,841d2dfb,7aaab839,3f515903)} +#endif +#if ECMULT_GEN_PREC_BITS == 4 +{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), +S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), +S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), +S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823), +S(b692c750,d23d3674,c351e3b7,e1a8a87b,14a5df81,852eaf35,209d0ec5,6e22a2cf,b18c4f17,252db89f,838de32f,b3340ea2,bb961a39,54b38c47,f9a8219c,4820a0cb), +S(691fc741,80e75b55,47b375f1,1bf60abe,451d27de,1743a436,5f8e4bac,ad421c09,8eb5fd9d,f3c03240,6cebf370,8125955f,bf2ef703,475d3fd6,1a0291b6,69b52d9d), +S(703b5f14,a7d82473,1196b52f,ae9ca8cb,b245b004,7a9928d7,d0c42f33,391411dc,5ed74eaa,49f276c0,4d61f31b,6da4137c,bde5673d,8e3f815d,efea7951,f88585c), +S(29b8ec47,d241eda1,e51bbb1e,3928444c,3747b4fe,7cecb365,2bbc4587,2f504875,88693238,8562f8bf,f7d72324,62ebc54,6b93a95f,77936b02,eb1cd6a7,d4199bcb), +S(444a07ad,e81916c9,32bdeec2,21c556c4,6b7f6491,e99b479,2cfec82f,4ec17910,2e084c2f,eead5200,77c151b6,eff9375a,713b9d15,5306708d,b3f538e1,8eb18cf), +S(e0dd618b,226ceddc,f560527e,20b4fe58,e5fcf28,39911ea6,c3e8a4a7,e15f9121,a063a157,3377bbbf,1b9a5ebe,afbe11aa,660c1e65,df1392b8,97205858,3c86a3fc), +S(9b99461a,2e8360f2,f2ba0bb8,bcaeb699,159e0652,69d9042a,fa0c4e30,a7b6f30d,3fe7fe04,3cb45303,3d4f5560,7d41cd76,9036a49b,82912350,6d8b9995,254154fd), +S(504da3a9,d9d9c81b,c2065398,4ed28cb1,b5beec9b,6ce5dfb6,cea94e54,fdff044b,cbd40d1e,858133c9,cd20b9e4,ff9fe94,f7cc9579,39e6df49,7a6bd702,797f96cf), +S(ddec0aac,1ebce6aa,ad6300d5,60f0e503,829f0bc6,479641f9,b19d9f6,484376fb,332ff5b1,fc83085e,736736bf,3c265e4c,8f80925e,6f38479d,6563bc34,e5faea1), +S(dc530ceb,b82c246e,41c522f1,d2571d31,4b14edf3,91577a2b,64e42172,b23562c1,563ddd93,857d6529,8b81de24,19e5cede,7a4c5b7,a2fe98f6,9efb8906,6f32a98a), +S(7604d60f,418dd132,78058942,fb2d2153,c0a2bfeb,e83c5011,a451bcb1,58db0773,38be14ae,d9e1c404,63ef92bd,d62c599a,b37625a8,182a3763,4fa2de90,535d50a9), +S(cb896744,77b20829,f5e2bd42,8852c70b,91cbd0af,cadf219,a69727b4,cbec8d7a,5710d17a,20ea0dff,980d3f06,38d8b910,b8940d00,dd4a323f,d777d942,213e1093)}, +{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), +S(f6fa4c02,1b697e93,ae34145b,481a3ac7,462343dc,6022040f,834dd9d2,c69b5d,5de5e04b,351f9928,b84abaed,d3319e61,ea91fc59,8d6fcac3,401d1ae7,c08943e), +S(cf805a58,d8f9b414,aa73cd0c,e545c9af,3f7d6543,8ae57688,81d30866,e81242d4,f455c617,99a2ca5c,fac3eb6f,23282774,7c9e914e,fce447ad,8fd71ffc,4fc3306b), +S(48dbd9a5,88d1f02d,6eacc5a6,36c0fb4f,de87eb44,11329442,1265b0ff,a72e473,9a206d25,5dc1d916,e3b1e301,cab1bd91,ea29eb7e,979c0b84,608ed770,4af325d0), +S(ceb3637b,28997733,ad6ef0dd,5004e32,9c87981b,e6d811a3,88804884,652780d4,6aed5e97,c0e836b2,73a309fc,5d389779,1f6f0bc9,246921ef,5fa9767f,dacac3f5), +S(8940dca2,52ebefad,61db720b,e709c749,7302b5e1,a4174893,9626910c,43708a18,e1b0d7be,1e36c585,8bc6125f,7fd5c423,5e643f7f,11668026,c1536e9d,f6305efd), +S(aa33c3cb,bb97ccee,5b8f452f,6a615900,392d78f5,b8c1f022,5266b8c,cb3449e0,e9ba50b4,7d3e3279,2253e925,5261f2f8,263c30dc,e613ea9e,737c3b92,8c8e3eef), +S(39f3965d,b455a466,930e5e82,ef214452,ef5c9019,bd805fe9,67fd362d,193a1b2a,8f69a32b,35bd6f1b,c5ada308,f61550b1,534c07b0,1a3465f0,564ed6d,a8f443c1), +S(6725d4a6,a827fef7,a0fb0214,900f526c,e23cc0b4,a6e291d0,ccb96ad9,e77393cd,69f91bac,b09facdd,b55fb70e,68164028,a8cf1bbc,207653c2,d898992f,89244f35), +S(3b71b2f,84d355f4,d246a57e,b235e396,ee236c57,d6ab3a46,f89b5d3c,1a911c1a,7616be06,59e5b42,9f105499,38d17654,c605f81a,e4bdf2b7,b9c1817b,c8db03b3), +S(a346e9c5,d8cc2ce1,1a733026,3136d92c,925f1b22,b27d3037,d9c4b109,9a06ecb6,4a3fd930,54f0cfa,6799e236,add0f928,6e45b77d,cef57797,7dcdac63,485c4f00), +S(8e3c768a,ee07f0aa,3eaa43e3,f6986805,b7829c50,d67861c0,c75ab390,5a6fb794,33d3c292,7a9e9c54,a671788a,fc0ec58d,cc2a0574,a172665e,347690d7,50de0acd), +S(b231176e,d39a928f,76a60397,79643e94,d5e75d17,238487be,f9b38b60,748711c3,3ae1ccae,204fb13d,74705b0b,8a0689eb,aea16e8e,c2f3d5db,177609ec,64027f0d), +S(8afbe02e,161ed971,44075da2,cea389b2,f53562d2,dc771d3f,9405259c,fe4232da,e2c16621,f38a0831,d2839585,9cbceb53,254398ef,b58308cc,bcf3d79,ee0af228), +S(1a263c8,c2c9080b,b0d4d61a,bb5d6b55,e6a7f520,80ef3f36,706e685d,7a527957,3925a458,779c3c25,7b546b99,7399a56c,b3c0b9ca,f6c77f9,c41b708d,f831253e), +S(35d88ae9,b1d3ee59,fe79c24e,de6cad1f,6d822f57,708ee54c,26e7495b,357e92c6,de74f353,d8115188,724c2a32,39b18661,6b8f7951,34aefc75,8e724a30,8be7f31e)}, +{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), +S(22165bce,e76e1594,5b9041e5,ccdee553,eba60e4f,1ece2d9f,e0ad7440,565f2665,fe8f383b,bae7e284,d1d890bd,569ab7b3,ebe5f1bb,b60ee19e,8e8de65f,88f3ab96), +S(a2600e0e,9265b7d8,fcc46a5,51872122,66ad5334,4ddedbf3,ac8cdf2a,b86f2b8e,d00f90a0,97fe3863,b4854dce,fa5a36e7,3f94015e,f892303f,2e5cb2c7,aefbf15), +S(38758ff9,5cefa7c1,b7a2443a,ba29b65b,aee1fa81,5ed49595,a4ec760f,b995df1d,43bc94bf,dfff3c59,7a6e41c0,52194d41,c1601b91,792f42a,6872ded2,a5e8f4cf), +S(57122897,d98019ae,a6dcbe99,49682895,c95471e8,d53680ac,49927e23,16abfd27,c30cb105,d9edc36c,9e237e93,2edd6bef,3d553d67,fec3a37b,fbe0ef56,a3cb6c), +S(7b7247c7,73470f13,2477c974,7820ce4d,51dde95b,dd14923d,e31dfb13,5a8aacdf,2e7054f4,a33361a7,a4282bb2,7e738884,3a91b211,3f71e160,60fb2235,6b40ffc1), +S(1d3f0661,13c271db,374adce9,ef0c444d,4ffbc1b2,a34b9c91,55986371,52376f68,1a4c07f3,e3752c71,f772c55b,d269f3ae,a9cb40a1,ac8a96b3,7387cd1c,bf22e864), +S(456ada98,2bcfa52a,55018711,6926b843,82754297,9af5c113,8af21e1e,3b625071,a7141c4c,673e441e,f67ccf99,53a7a6a6,3a77432,76261717,21f581b,2893243c), +S(b898efae,8582d8de,b315220c,dc79d2bc,1a221072,300e0971,c4a610f4,7f6b70dc,8da8b020,8d674418,5620db55,fa3cd928,be672c5c,22897030,bb5a5957,37758a8), +S(b732f7e6,9280227d,c1f56e84,7e72989,b834be6b,f04e2e3d,ca8553b5,ded18493,9157298a,5ff6e6e4,d705efcf,7601f33f,76cd2a64,6118103d,98fa000b,8ff9ad99), +S(9601ce19,964403b6,a58d1d51,be876199,d63755ef,91bd657a,fbfac3ef,c85c78d0,df06aeb0,517ae1da,ff3a48bd,7ecceaf5,b10ac9d9,67e7ef4,520593cf,d7502058), +S(a95814ec,11446773,36258a94,56670207,d068d8ae,19ada794,52210f2d,bd67bc5,29d7e4b3,5e5a4300,6297f9c1,f71a6a26,118693ce,fc738fea,ccf1b873,339617b3), +S(d3533330,c6afe33b,ae921c0f,558fe47d,b97e7711,ce98c884,3abe894,320e8926,e1be0b16,72f8ea16,b59a6b9a,20c27621,e63854cb,4efde5d8,d1da8929,4f777383), +S(4f05f649,e8ec9fe9,f675957f,7454a89e,c020feea,217782bb,43bbed43,b0a62881,dde64c2b,255d8518,da7461c6,b160286c,5222baa5,483fd5cf,dade9ae4,96432904), +S(1a06ead0,5ef3dcc1,a9080234,b6158fe5,681cc5ca,acebbbf2,c336ecdf,3505768b,63661e6e,816bad91,1c7bd073,a15b185,c4c7b7b0,ae440dd7,40a54286,3a86721f), +S(e2b163f9,f1b6ad48,e8bea9d3,b199cfe,378fbd2c,8f005cdc,e5959154,b2eca0e7,30759d6c,f55f7f15,a156a705,1f702294,72b9544,ba73fa40,27839cd5,67147083)}, +{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), +S(4afd2a50,f79b1403,844523a7,e88e0156,f77f7856,8668ac7c,79d2160f,cac27acd,40346549,fb5b8450,165c2a4,c47665be,b1d31f73,1cd758ce,6c8f2b17,37a832d1), +S(f4132840,9cd5ac7d,7a0c92f2,5e39eb57,b8fcfbd5,d535ec00,a281d3d5,1275199b,6b66ce56,99a92cf1,8f635a0,7441f0c1,3561c8d4,cb0075f8,8a1596da,b6da6d29), +S(1a6c66d3,1a54ae12,59b709b4,c70fb434,f3347d11,7921ce06,fd4f0dbe,d211e4f4,b6438fae,74524dbe,2d03e27c,8af409ad,67af8eb6,84760c85,1e81c6af,a4cb004e), +S(3afe6f2e,8b5f1cf4,20ba1dc9,f527c662,a3af94c3,9d0e726e,b7942a2f,c9c1a91d,892cde5,f1420590,ff801f3f,8ec2ace,69f0dd74,31ca7e7,aed14c37,c2c12492), +S(28afcf30,a1f5079d,e6f340bc,9e616ce0,7a89b67d,4e7f0dc0,6f54fe9e,d17f1519,b7cc26ec,9a25b585,33a43369,40b6bdc0,c2462e39,2246a863,e67bdefe,1ae51be1), +S(13980996,af67f2e4,6dc5f389,d0269d1f,39a9341d,5e941e6,b4ff7bdb,ea54cb65,37a37717,d206b584,9eb79193,96ff5af0,449f3164,4c9eb31c,f27d8a,be66c741), +S(b7b75484,8966d79b,aa10ad77,4c447872,dc4c78db,84a58b9b,a112f5ca,77630bab,ca5111f1,55becf6f,1a546463,8a417af3,2c72cfaa,da56f86c,d7654c06,bc8fdff3), +S(b957ab6a,c7d7692,65adf169,492b00eb,4d8a351d,1f189d24,3e66453f,17696dcb,47474297,433f0297,231e0d7f,e51f1846,3af3e463,e071859e,d6b12b05,2191b839), +S(53f2395b,af57e626,f977dead,da52c4a3,f8b98701,f57eb79a,735e73b4,4d4be4b5,1a31bf14,36b5dcfd,5dc24ff2,ab5fc7e1,15940bf,12ae40b3,73859ce,5e26d55b), +S(31f8493d,8a81860a,3762fbdb,5b623358,af37ca99,3ce1bdfd,91f41acf,5d8502ce,1b231e3d,9604e28f,65d06f18,10931210,3a4cfba3,95c6d856,ecc374be,556a296b), +S(77da894f,ef83a273,22138b96,64df3b02,fdb5bf02,4963a103,1000ab37,a821460f,86cdc4bc,3269d02f,d3e97843,fd2c9dfa,c9ad2d99,f7503222,ac4c4da,5394809c), +S(d222a486,cdb8a4a2,8c1030c4,39b512f,f849033f,cc844e08,fcfd8748,1f68430a,2d7d7e4a,281ba28b,75f2d966,1d25a46f,5ded9066,7422a92c,bfcb1f1,797b7e02), +S(e4431b98,21cfaa43,8a8dee6d,b7a19a38,729622c7,67cdc941,789a6b78,c7a2ae4d,770e652e,de9172c3,4f50ed14,bd8f83b0,720ee2f5,8717fc8,a07de08d,5f8ac400), +S(1bb4bf1,1a1fb6b,78093ad1,5fe5408b,f9e1477c,3844e243,a14c37b4,f394254b,d9cf3fa3,25a0ad1e,fef984c5,8cbe25d2,f88f3051,788cbd42,a8f71791,5229e944), +S(a8fc65fe,e4df466b,d6651ce5,7ef030f8,701e364d,f1de5334,92938856,deb74235,b4c7da06,4f7bcc17,b3308c1b,e7924317,fc02c53a,808b47b,d87700ce,1adffc97)}, +{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), +S(1badb614,6a647a09,894f60d1,6544e992,6da742d0,32df02d,ea347ffb,dd52f93b,6927c950,828e5449,bafee29d,e9977bdc,cd6a0185,3d3ef286,d9854f9a,75f5d4ac), +S(dbec52ad,5b8257f8,f41612a2,70047e4a,715853a5,f22091e3,496a238e,cf61379f,1ed383f7,dccbdff5,bebe8f0c,235767dc,ee220fa9,8d1b5ef9,6aba5ad7,87b46252), +S(5d2fc0e9,a5b1a743,131b4b16,88d504d,76422862,942de800,6c6d3611,3443999e,f7f89299,64793634,4156dce3,ca77c2bb,40536f50,60afd3b0,a3b37d3d,869dc11d), +S(761a1b70,83db07d7,340fb1bd,d5309ee0,e9e05bf5,6fc34a53,b6034365,ffd91ac0,82b1fac0,3d382fd0,109e45b5,8a07638b,1ce9ff2b,f45d3cd9,50843b69,43c75c7a), +S(ea397afe,9dcad2b9,4ad000d1,7abc4e5b,739e4132,997a7898,3c6c5c29,ebf7222f,24a87ba3,411ca610,5a696969,f86ab751,2c61e189,5ff4ad18,7193b5ef,7d8d2034), +S(3dc03137,8776b2ba,83a8124e,821de26d,1a52855d,d610eec2,d5c7eec5,9c92e81,b774a839,6ad7b7ad,9e6275eb,2731ad84,271fb8b4,6c3e12df,b74fe942,e6dcd35b), +S(49b98bed,ac9bbbbb,75f4f3fe,310af59b,1ec779cd,41b75982,6a929bcb,d40ada85,c09f3d79,3b143720,dbc1d04a,4d559f35,c650d372,12668736,1d824a9c,b100630e), +S(786555cd,2c6344d5,7f819963,1ee8536a,ba3ed77e,88501a2,20df332e,b41c9aea,f3e046a0,3ea9d39b,31377a11,dcf7c2bb,13ff138f,f021902a,4f927e3f,f48a60c8), +S(413259f7,3ac4366c,1385e7a3,79f54796,4b6295c1,298fdb7e,6046f711,44ee3055,a7a62864,4717b82f,b3fbb73f,fae2318f,985f1923,7df110fb,260434bb,81bfb4dd), +S(64922735,de394c7c,1d42e1ef,d8a19ef6,ef34e69,dc12bce7,c320f748,3993bce2,84bc17d5,5711e228,7e81ccaa,9625c73c,60923b0a,f266b70a,435b1c11,e7d29fff), +S(32d0955a,c57511db,5f27606b,67cdef94,a001bdc2,cc228bf2,951f5426,69d6dd51,7f9bb41c,d62d5863,c2dfecdf,8e3cc9c5,d104abf4,56b9030a,552ed607,73719520), +S(2428069d,b3ff968b,d1559c74,c3f38f17,e725340b,e956e6b6,e6ae3a70,4fe8af4a,1f074994,b487ca2c,9bf222ec,41cb54b1,bac8dd57,50e47f00,59ee74a5,1de0fb4), +S(a7f35a96,ab880ce6,b4e3c5ba,6502af7e,cf00c685,b260fe0c,380ff875,2bcb3e34,7d47fcf3,ed09412b,ed9fc737,212b6289,8b415372,c9338673,a14e7f42,7b4ac9d3), +S(ab624def,ee301beb,96d2626a,88a9adbb,665f9e83,f85640f3,79e4ee7d,c9282b2,4dd486c4,3525c5d4,668c5fb2,7d03c985,df69a344,62187396,ed9b360d,fde32f72), +S(f6b26f3,cb13dfe9,dca461c8,5b480140,df4a0c0e,b1d2f5d7,58de5173,eb4c4746,a5ab6d87,e6852ce6,9965a774,ccb94676,a440d1d0,c8b02f54,21c11bdc,b8406cfa)}, +{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), +S(a4e569c7,5d717deb,360a18b9,5bc0fc36,af132603,b74f3e0b,1bca3e31,14c28e64,a70e832c,e3d8d514,84136fba,9f81a2d7,8ab65b93,dc9f9080,1fcf3712,74340130), +S(2e7c85c5,7e68056c,e10ae193,66807434,c048a046,430d2087,92fc9b01,dbe06508,8c3f82a0,b8cb5022,dc7b04aa,6445b06,d251f9ed,bee00246,c33785de,979140eb), +S(fadbb0f0,b4bd864b,73527365,6455cc26,71251519,6c63dec4,41052585,fa86eb52,bcc086d7,54f08f77,1888bef7,4bd3bf9e,35f8498a,aa7cddba,acd63f0f,ef676738), +S(4aa439c5,2a0dd24d,c5f72b14,9a39e991,6dbcd4bc,4619fd34,94012a4d,430a2b0e,5482d41c,7fda4591,4150d653,2173b658,b5a06046,8270fc7c,2ea19d58,7b96e9fd), +S(2e1c9639,537015af,7de6bd50,e2697661,8ac633e5,f1946af5,34bdbc5c,9797aa4f,b6a39518,c607d0d2,94a36682,f4f6493b,c80f1624,792fec2e,e971f080,37dc6dcd), +S(63f28872,6d86ffbe,28a516e4,75f67972,e6266038,3be45c0f,d22e9a6d,d5d240ed,f62ca816,59ac13,10854091,c7851bc0,4d315466,b6187327,3af16f9f,68597dc7), +S(576c051b,2f4d2ace,ca5c067e,290a4d5f,d8f9b6f,19d4652a,449fc1d6,9d4b762d,a2b94a16,903d80d3,f965c43f,b751dc44,690f18fd,bf3e29f7,e21b855a,837664bd), +S(876afd3d,8466f7ea,eed3ee7c,e809528f,c4b392c9,efcc1f9e,753b4dd9,b84722e,e4453b1f,c3fcd636,b2c9bf97,6816b60c,246e254a,67bf2e59,22f835af,103c1107), +S(5a2ca063,6453a00d,b8cd6f60,3434f0d8,8642c119,b6302766,8ee67dc7,c10c9e3b,17be303e,40bdb2d5,9dfe354b,e58a387b,ff64112,3f6a13b2,80876a7,24c4d601), +S(46fbb84c,d08ce9d4,73e3b00,f5ba4cc2,f10fb84b,ea34a8f2,de114c31,8616def2,62410bd7,2ffda863,2400747d,1984d1f7,da285e9c,592729bb,ad9cee72,d266fc78), +S(417f7895,e2bc2999,469ce63b,66cc9bbc,4581b42e,c62171a8,ac32bdd5,23435283,1a5e10ef,826f058a,175fa5d5,21594182,a61a5a07,406e1f00,396935be,f78c9ef8), +S(916866c2,f33c0942,c8f12e54,8771645c,e1581ee8,6f58a90,67ededc6,b70e93b4,c7945f0b,d100c3a4,d624e527,ea9a8d9f,cedc9934,f903955b,aba58be3,c23819b), +S(c3630c36,acc78b38,8c5e8604,8110f113,3638c78b,fad169d9,d25d66fb,728ed4b,5788b6d1,7c74f601,e2bf5d77,eec182ad,1d9b2a89,6da8962,f9887bdb,5a6918e0), +S(64fd5fe6,cf91f11c,970692cd,d2ba6bd3,4d17faa7,77ace6db,d161e63b,93a0ee19,37ce3afe,f75712c3,301e4c97,6456ad79,e09326b2,28b23e10,b033bc53,a6efd060), +S(2ff8f0e0,5d514fe5,766bc683,f82af019,471a173b,b0e2ccb7,53eb45a5,8047041,9a13b872,e26b58d8,68e1db1d,7391afc1,ece8e410,a4bc3f42,dcae2b27,ec9a6e98)}, +{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), +S(69040dab,81af8b4b,759b852,40c16380,cc2bc3a5,bc8e9e68,7cee93a3,352d8055,e48d161e,b63c619,26c78402,528ad5a7,19a7fef4,4c03b933,37d51bfa,ec497817), +S(d00d4407,f7a1bc4a,57ce72b3,6fba7d8e,ca4f2303,292c2ebf,6940b34f,fd98aafa,ebdee075,32ccf753,1806337b,54a36a53,1641fb80,64d928ac,5a3626bf,e16dba4f), +S(9a3ab165,66f8c8ab,7b3d0d5f,7a3ec7bf,3cb69c0f,31346486,10c552f8,17a4abe2,7eafa760,7fb4cea0,dedcfb1b,1c16ebb9,8904a79e,37395aa3,1ced5c71,fc8c7774), +S(f9028f3f,4f5752a9,9ce55412,876c7067,a199a338,1d707bb9,3d2fc44,b165d000,a7346d7b,6ea796e3,2a19f104,34a7e0d7,b7e90326,81374d05,9b81badb,4dd651da), +S(e7bd1e16,60174f67,13a8db0d,2bf88a45,275a44e2,9a461c1d,cc6dc5c4,fd2b5c0f,9732850b,41082c88,5ab49289,fe11094f,c26bf80d,1b0998c5,1ce63cde,d7bad0fd), +S(d8b88e20,ee8db21e,28bd271b,46d77769,b446994f,5eb35ea8,d0613b29,67f8c1a,8b9905cf,547475e5,838e9191,388b1c64,25fea463,1e4ef825,e84e2226,2888d0b7), +S(3dfae04a,180749e7,e6949aa5,600ebe40,af61d644,ab5446dd,4b3334dd,f9bd7ce,963fb79a,a952447d,e274666f,16c08a2f,d5864825,78b870de,afbd98c6,adf4cca4), +S(4e0f4c4,b4905983,e12cf9cd,7dbcdf18,db9782b7,d4ea7e11,280d1f,7bc01e53,3305aeb,9b5f23af,bf1c759c,14a811a0,1bc3a5aa,19e26176,71690393,f3318bc6), +S(d74e6ecd,72453ee3,f68fc29f,f0de5b36,82c295df,2fc568a9,d68ad747,d4409b77,46dfc1af,819ee0,fd04e0cb,1af0835b,e8f6e53f,1ed28d67,6c0c172b,2e56a74a), +S(d1ef8f37,78dfe4bc,83c48c4f,e9aeb917,34320f2b,a86630e5,28f735d4,fd78fc68,6cc62683,1e417caa,9bdafef9,92c7267a,e7ace1a9,27d225e2,a5000b97,c45007c1), +S(64457682,4f541ec7,d8ba1964,32146322,3d1bd634,5cd09f03,a91aff2e,b9502b15,236ca78e,bec84846,74c43c52,55e2cb76,b41b01da,ded4dede,1a99e1b5,8fe80638), +S(f557af63,f3d8437c,1c48619c,4bad3e7f,d92c6ff6,63b86121,55bba4b7,efbf350c,efe2dfea,62a12ffe,5e4208b8,e5af4f07,13f8de73,824502e6,94b08d34,d1d92e2f), +S(f45ade55,84070898,1d244e7e,a546a34d,85fb1164,5ea86188,43d753d4,2baa1ecb,ec25cb2,6574f472,69a90070,3eff9a68,770ffa2a,7b12efa1,dcd81ce3,56a46978), +S(e3169959,74f4127d,e9002439,582f9790,6047bb58,d4bfdf74,3b6ebea5,b5663d65,cf7afc59,efac3d94,88260d14,a3e252e0,b51345bc,d3e07c1d,b07ec4e,28b6d60e), +S(bc9112f0,137446bd,1a218167,72b6afd7,65b19569,90f8e53a,f8db935c,2a88686b,a74e4d7,1e24d149,1667dced,bd7f58ab,851d685b,1c29e38d,6c9e613d,b65b7864)}, +{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), +S(7ce4a044,e4656f8c,687bc693,1c6fcca1,95322643,db41d,8407d880,4d6b6cb0,14fe83fa,eb944cd6,dab9e7b6,279ebde1,6ce1028e,5df74c77,7e6e00dd,55f69465), +S(5226b60e,b344786,bf572e3e,33e5aa14,6ee6feaf,35c3a2b7,22118560,183cadb,cb650e9c,e4f93861,cdb700d,13557323,8a7d7686,e22943f6,433dab6d,96253b10), +S(21c0342b,9a723249,ae7193fe,aa00baf6,beeb376,1f1bb125,7d0d9549,d46b403b,5b2dfee9,4a67c6a4,def4f55,a14af716,ab1be308,ecac6042,f86679a2,1f5114a0), +S(82e97dbf,f1d0d9bc,65797145,7c5aad62,ea75753f,df9d3e15,efcd3ba0,285d3476,7f67ccc2,f0aa795a,890d9a30,6838b9d3,c64c1371,75b0ab05,68622b3c,fdc8d25), +S(6c02ace6,1f479fbf,11059054,d8dc5761,ca0a97a0,22e520c4,8aa2f32,448b7392,4e57f208,ceed832a,3626f347,f8a30956,13a17e57,b0159ca5,33143166,77b91469), +S(8a367826,e40db24e,28fe31c2,fe24151c,8e4702b2,43a99d86,5448d83b,cf49a6f,b2bf6c78,299dc024,2fc66392,cf6c5097,42a05f15,935c835,3944e66b,bbb87c26), +S(c1c3921a,14f64598,11aa70c3,f756e689,82233a48,588bdfb7,84348459,19125af6,6f7109d9,47dabea5,da858a4c,75ba6c3f,162ad404,15e7ab46,7247963e,8f4a1326), +S(ebedcd5a,e0f0005b,2eb70d40,4a1bd4a5,f0537c48,e8f6149c,c042f9a,773c75c5,2b7103da,d29bb9d2,c07def6e,1094fa50,ea70f7c0,4f609b4c,bee0d576,57e506d6), +S(bda6fac6,99e09a50,ee0131c1,efaaec6c,7cde205c,d3b55c83,176d20c7,80678bc2,881c023c,86b948ed,31a5cdff,8f3f985e,cfec9111,627d813f,177afa76,89a16f89), +S(f6d335ac,66fc71a8,319eaa38,3eeb7fb7,41118280,531434f9,cb0b364e,90babd42,b14c40c7,8846262b,e117735a,30a3185b,49f8852d,2e3aa8f3,3dba4806,ea7ff2cb), +S(c5588c4,fcaa5c53,79f910fe,9bfa1224,fd20aacc,f1efdb2d,7ba87c5,3615ddbc,e60ac5b9,fa96e150,57378c1,11f384bc,16fb32a0,a0482f26,603aca30,ed1315fd), +S(db88be26,bbab7b99,f0f20c61,40ac77b0,28afd465,aa4d1294,9011a47b,b1d87f89,e126d612,91ef9a77,e90a8522,ee6e7dfd,fbfbc2a9,90986da5,65919317,dd4ebd1a), +S(1150279e,e9c0323b,b122c2da,6e8b28ed,5e5b02a2,162067ba,67f5aff5,e99214fc,74d876d8,4d00e091,ef0aeaf9,5aefda58,f3da4d52,51b2b28e,cec41a23,4b420401), +S(1bfe1d76,43526f3a,e0799982,69f9679a,9a54f1ee,bdad1f6c,9c8e096b,6e771023,ad94d693,961644ce,a37ee705,e06b4b5b,32c17011,7aba021d,6cf48746,d8637dc0), +S(928b3e6f,a0e6c2c5,896f6eb3,972fe96f,7e446782,50d313d1,54ffd666,2b43a615,50f2d7d5,fa221867,3f18540,f2f7b513,b6b4875b,9ed4a5ba,73de7800,37f842d8)}, +{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), +S(bf330f50,a9c015fd,8ff93153,561ecb91,27b84420,62fadf17,3dec27e2,a5f7b0,931f0891,94aefbf5,9c530d74,8ccf5a5d,83f3fb1f,cd9043ee,ebf50994,d8ec1248), +S(33db24e,b1ba1a5,cbe2832e,50d877c8,a4fea4d3,e63d7c71,fe8cf9ea,9fcd1cc5,8b0db6a2,37555121,ec8a2ed0,e8f80dfd,37082a0a,883d3fb7,d7d2dbd4,7c01f6c), +S(eefd96d2,1d6639db,6a7f3a79,26f5bcd6,618e6ae1,70551973,7dfca216,565513d3,d7644dcf,e46715c,1821babf,5ab153bf,a80d20a1,252718b9,b72f299d,21ba7218), +S(48c08093,fc737bb5,70a31154,290f709,3467c915,c4afcf6d,ae372e42,3ed69815,29581f74,659462b1,3951d930,a8912e33,a2928e34,5e3563fe,f88b42d2,28af2f26), +S(68c61ae5,15c1ebb,d395feba,8661a967,162dcbac,5cb13303,9a354c11,ee217267,9db2d6cb,b3880ab,ddf58293,7f76ad7a,70fb1c58,d2eb9a5c,468331b4,55c5ece9), +S(99afe669,baf69344,16b388b8,30b97e80,86886c62,86870e7f,58d6efc,377ded78,a684a9dc,84881a2f,bc340b96,4180a966,d00aa5ce,513693e7,9052795d,74f08f7c), +S(3e893680,b103cb80,e6a4eadc,abdd4eed,6fd53341,d08d6d78,85fde37a,49621bdb,d342db6a,a942396f,76b79de6,a6d48943,2beb59ec,4d1d6399,9244bd1,731a6855), +S(e19eee8c,7206fe64,a217e60,c791c834,de7cecf4,3ae1cf42,b697941b,c556252b,cf79152b,76b0ef1f,abd36175,48701716,32ffe2a1,57b006cc,4fceb313,17be8fd8), +S(50d544c9,b3a10831,e325dbcf,6b13c6ce,a06ba82f,ec3e5b9f,9442101a,a4c64d46,a89b1cfb,169019ac,19785c9b,8fd27f1f,177adcc6,c9b995b3,43b373f5,cd82c9cb), +S(e34ff94c,729ca264,1cd51264,1eea2aa7,ebb5c577,71bd1900,86a02aea,7cc2c1b3,454dd58f,c46f61c,30efbfe8,49c7b2ee,b1a99bbe,6c8a4f6e,c0063a46,a1f63f86), +S(50a5b0a6,919974b8,14c10ffc,8c6233f2,843840a5,834ff5b6,75134ee8,4f40a716,6cbafa57,ec555bd5,2f656a95,3d592aaf,e963d403,40a7540b,644855fa,7c94c3ad), +S(b5f7dfc,438a381d,edfb576,aa62f2e2,12264e1d,8222bea4,f71ba06a,b2b6f0cc,396484f5,3a14cd16,58813612,2fc55f7e,89c4fcab,6d73e5a,fdeffadc,3c9f9b0d), +S(4e2a7b73,1bba01ce,68f4becf,34ab78b4,3c89f711,3214fc8f,ba3e19e6,a449b7f2,aa85874,bca558b2,e674623,3e0ab93d,4ec34eb,6998f0df,3f153126,93739077), +S(3835d447,f4da18c2,1fea247c,9ff3436d,bd60878c,dd347f4c,ca1168f7,ae189ece,df5da21f,f6a6add7,17e53e6a,ff0220d8,9b1e71a1,30339194,81bbec2,40414a1c), +S(82452834,e84617fe,d7d32149,6abdcc54,2af5fa13,8f55faa7,c2245cdc,48c89f06,c01d6da3,96b923c7,290dbd1a,6c16a69d,8a872638,4f6285a,f589a0d0,20e892ac)}, +{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), +S(26da38b,1bfa8363,6be480cb,684ee5c,70957f93,7f9a2d57,3ec75396,bfee49fa,9763277d,f3c228b8,515bd08e,b29dffcc,eac8e3ae,786a9655,5fc1be21,cdd20d47), +S(52063926,34d12242,b2ff32c7,d0a8bb47,fbbd005a,bf7f92ce,78808a5,7b1cbe55,d0cfa8e,49b45823,881819ff,fdbb6d2f,5c65f35f,3572e13b,ff7af252,95efe81e), +S(af61f7dc,8ceb2277,db16412e,dc469b2b,f0e188ac,89c72bcf,20654379,716115f7,524b9b25,925b793a,8bdb8e06,83cdb414,db0f6dfb,e7e06274,d61ef87a,13493b66), +S(39e53a5f,f553d89b,dcbd6688,9eabd7d3,8c5fc6ba,24618d98,88bb6e42,92658f06,ae8439bb,6d32531c,45ac510e,20f1c7d2,b8dc70a6,65c11f2c,cda73603,97c6580c), +S(b687e250,531efb00,f7e12690,659bfe25,429ea2e6,f1dec5eb,74bbd1e4,89a95e31,1033e5b7,9c0adb6d,c0f12ff,afc5d81b,54d7930f,f6190dec,737bbb3e,c4c774ba), +S(4c17f5ec,34cdd368,dbb62f20,c3b86483,24e99e0e,95a7e624,64cabe76,222981a9,1e37e3df,b690b574,a11c9803,f1cb5618,ce4a0331,e17c5cb5,4873ed6d,de217019), +S(bb7c4b21,77b77a9f,8f78c2e6,25bb943e,9d05dbed,abdbe02e,497e5dab,c31dc477,a5f38fb,7ebbe67a,869b90d1,aa4fbaf5,cd7173b0,46cf3c5c,b31a272c,c0693c82), +S(3b18ce78,6688a74a,7256c067,a412aa59,45fbb506,fbf801b8,61734ab6,400744c8,d4f01881,47809cf6,5226529b,acf6e81b,7fdb609e,3eee050d,ec0f3140,2308ae20), +S(b671371e,2f0b770d,af8fb77,6a64948c,1481cba2,afd1a3c1,bd233946,e34c86af,4a58dda7,ee794384,496c539,7ccfaef9,fd75d05,c551e26d,2ac631e0,3d124fec), +S(caa559f1,b0afb30b,d62ede02,a9e28a9d,8bbb437d,e9a8963c,37e25898,428b845c,f73a14ef,2078cc23,92b99742,9dce6a50,5682bdb8,c2b5e587,31786814,9c777411), +S(2676f258,a761c508,5176ceed,a95cf9ea,4d6640df,a2c4abc3,e4954225,c23acf9f,fdc42fdf,b1636050,67786940,3aea320f,8ec1e8fa,b9033c3f,2b919f50,fac0271b), +S(ce17ef68,f6c7b456,4cab6be5,22495389,874f296e,b62d552b,6d621607,192005e9,94fd30c8,71add5fb,5161b468,ab60d254,472339c5,2668437e,7e172ec4,957d00c3), +S(42fca34,df3ec118,417d8d18,4e507f2,91d402aa,32c00b5b,a1dee38e,7fb0cc35,a046e52a,fb7eaf45,bb3205e9,56e0e780,977bff46,ea65633c,cb0cd2b4,a3aeb2aa), +S(99926617,c15dcd0c,95ff4903,ed9d6050,ad0e1982,84a3c9f9,6a24ed55,45641b13,64437785,afc882eb,4a78844d,14d79cc7,cead217a,3cdba8e8,473374e3,4d416b56), +S(3d4751a6,99a8e88c,aff3daf,3ddcebb2,63f0d56e,6d305245,4c16b0c6,f80e0d93,162f562d,32595699,172a5c6,4ba2dd35,11bc5430,f21495d1,2ae9f6a0,638c613a)}, +{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), +S(1d1c9798,3eef36d2,75478b94,ecd3e172,a39e49c7,1c79f932,2077f410,e1a9d0ae,5d8d6ec8,aef80d94,3e75ab6f,68408d84,6cf94216,af6e06ef,dd7e9e72,4abcd7b4), +S(60f8ca6d,1d60f524,8d582e8b,ea2fb8a0,dd2ddb3f,49bedc03,5d24973e,aead0b41,7c4e8b11,b0e8b135,bedc60cc,fd540dab,da868d50,78386aca,117bb71e,e108fc51), +S(c6f57fa7,6d2ce583,415e0366,9136b21c,725126e,56187c79,577949d0,797e196c,2772eb6d,94a50849,e58cf22a,eaf1e35d,6e2bf171,f180a44f,42cd8659,41ac2348), +S(3766f2fc,83c96803,e590fb7b,ceb842a0,8cd5602,e57cd00b,5a6e340a,361a7daa,ee3e9d18,da86e137,27560281,8806fc26,199514fb,98c76526,54c85842,649ed048), +S(20de0b0a,6b2200b1,a89499bc,5cf2dad,7dbb6c2,e9805259,21c5e6a7,29c40cff,b680c2e3,33083337,3fefd833,68986b50,d2a28319,9912a092,fbed8b5b,1f22663), +S(d2f06c3a,add7cdb5,ac606876,e4093fad,8c626408,ab6e6dd1,ead7ec93,4e0a1088,990df428,517d791f,ad749267,7666dbe0,6b71436c,5112295e,ab7bfb74,b4cc89fb), +S(c583dce0,f9c32b0,d8c87a9a,dc7dd093,d12037a6,ec162d5e,22ba72ff,beae41e1,d9390ef4,9f7f10fd,7b8641bb,f2ae8388,ed08cc19,3d1e6a13,81d8c198,42025aeb), +S(80f61ba8,a99d2081,f0652a9e,a25b8d23,716d55aa,c9355891,9a4b4d43,1e967f58,b8df023e,56eb796a,e70296b2,b47dea6e,d74ac4b1,99fa132d,c9c464f0,ddac27e2), +S(4ae1535c,dba6c272,6e78dae3,bc651f16,cdf6634f,95584886,899c829e,df12201c,ef66789a,13b7244b,ced52d30,c9af6613,55d66a9a,9efd3a40,703d38bf,c69c7c75), +S(2143bc02,b46d41b8,766db211,61ed21ef,5b0973,b7cebb00,beb89b71,4a6e16d7,7dcb12cb,137dd6e6,96791345,69e25e2d,57cbed88,ce39aff0,3d57ec3b,85160fea), +S(5c0b84bc,ca8945d3,a2356c68,afb8d1e5,d45357b6,b37e5afd,c2b00e6d,1f6c5eab,1608a492,bfb97a7e,746218c5,f673078,c70f5880,de8df87f,8aa5bfb9,89b43ee8), +S(f6cc5210,fa45c072,cb95e88d,ca93b9e3,f7b35e98,13c29976,2ed9364f,8c021e3,ae959f0b,5ce17592,5046e320,f86d9751,a6ec37a3,a773e5ef,c4681ebb,f5aa1baa), +S(d4df71da,5f272934,8653f60,bb02deb6,c314943,f50cc5ec,e4974ace,b5b4d0ac,17caf288,b3286dbe,2e8d0616,df592027,baf3e59f,1e52fe51,9644cf5b,66443c35), +S(44e8227e,177bb9c1,5aab6cd9,d987ef1a,af087d4,bb2672af,1a8d5412,a7d6cb59,4b9b2602,152e1152,92fb191f,2cbbec91,5ecea9e9,ed75121d,5cc7a88,69527cd), +S(97f092f2,75d1ec04,96f6b14c,10a280f7,25c9e4a5,d16afe2a,3f0837b5,422bc5db,12f04418,c131046a,e5c7ed64,f69d6a8f,d3a3d35e,30dd273e,72ff16df,a866822a)}, +{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), +S(5aa4d7d3,745f341a,c2869a8f,ce1e2a96,e25e49f7,1e5cf140,c0ad884f,47d8ae86,9f03a2ba,989bd4b5,9361448f,abe607ab,210d3887,8da85782,260937f5,9910d8d1), +S(91910df2,7ca6ab42,17ddcf1,d7efbfff,e69eb9cb,24a6648e,3aa7d738,c76290f7,e99691b1,d883491,e79e957b,4c65f975,601aa5a3,b056ebbf,abea6c7c,d7b9ff2f), +S(b5b7792f,99303195,4024caa9,e08bfc16,53f535fe,7bc3e34c,8491864f,74f48799,6cade2ce,595b6714,5d376b7d,7b435a3a,76b15912,6340f6aa,68ae15be,26a159ce), +S(8b54ad71,6c724ad7,e47e5efb,e6b7c93f,8923e7fb,8517ce0e,6f732486,f37ba1af,fb8aa95f,4a6e3522,371cdaf4,461f4d6,8a45481c,da065f7f,a697487e,fb8ea80c), +S(b4896855,b2614337,8c5842ef,b7dfded9,ba6c80fd,2eb154f7,e83c4734,ed7dba2b,30e20644,fd8a9a81,9c622641,b525647e,ae35b892,91410141,1a5df15d,36c4efb1), +S(5bc3cc33,89816b7f,414a473a,2deae3e5,ad3e7803,b7532f36,d2b31598,7c35d6ab,4dfe0f94,86d1ecf9,7de9b0a9,3e437f49,c015b9a7,677aa2a2,74868a4d,512c2ef0), +S(230bee0b,5eaaf145,f18ec782,1e861f12,26cec876,a50ac94a,4a88ed64,4a3f7d34,331778b7,d638cc22,269a7a3e,abd0c393,f7e08d0,dc761da6,25b70b5e,14f18c26), +S(8f55920f,c479e736,3000b33f,ebbb1559,d41a5873,93429368,78a6156a,d476b8bf,94fbaab6,7a49ff13,2435b28e,df7253af,43420841,b721221e,b5606a48,3061e441), +S(d64edeb3,709907c3,761afdea,f9b431fa,7c0d5912,8a603410,39e89346,1561b7fb,d64ce942,eda3a553,82c22d7e,f9b20c61,ba09fb35,4401fdda,c054e891,15134b9d), +S(ab22f920,a97eaefa,25e46069,1123f499,7b3a78e9,af738ad2,266c6c98,4b5fb63e,27f41b98,a05a5599,eb82b0c,37a9a70a,f19df223,5254816f,1b9411b2,52b77d), +S(3a409fc6,f4a19839,c6bd2187,5e2f9b1d,5e10ca36,5711a0b5,67084612,ebe049d6,21006d4e,399d55a1,6a7c136e,b192543b,36e73785,36506555,e9c5fea9,3e5bf265), +S(57305b7,7613e53,635ea239,c9e35edc,1a2a1680,fdf58358,93cb226,c0f11f50,b3316b71,954f5a14,acfe28bc,9e90c27c,715204e5,9db9a74e,a5b5cecd,2f43aef), +S(d5c78499,3727b6d6,18bc7b22,4b1da72b,1cd9122,81e8e58b,cf2dd698,b400cfa2,d1aab246,fc2da7be,de9d90cb,2c438d65,310b4785,ece43715,dd3a1a65,c8abca8a), +S(13a05a02,7191a7f3,eeb453c2,8b76afb5,150bc141,20b90f50,dbd0d218,15453e2e,94ab710a,3736322a,ed6b4443,abcdce44,a8556a3f,85f9d3a3,701dde54,52aa3927), +S(3e6033fe,9fc41a9d,6037d9e7,ef11fdb6,93d1af71,237d3983,2da15f12,aa080ff5,763af526,e9187e31,89955a60,b3914307,99ed7de9,e41b6c,39d8ae8,748af8f7)}, +{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), +S(4e83070c,e3eba290,c6cd520c,dcb4252b,9098270a,55fd47fd,eedf36da,b1706d47,561a3822,cd94b2a4,1f30bac8,695e05b7,69de8ae7,4241d2ef,f084922d,ccaf09ef), +S(4cb0754e,6863546f,afe0bfa,edc94c15,6d9ac68e,db700281,2a24933c,a0a30401,6cf6ab8e,306e4400,427b7820,52534566,52d2bc98,2510c84e,43b4ec61,3194c402), +S(a3689f89,d4874967,1b205a89,8e6c092a,b0cdbe2d,f1530bf1,99201a3a,6b0e3da5,5a58acbb,e6ad1676,a328e193,30c3297b,81e52e9a,4abfcd4f,7e0bdc2d,543bdf61), +S(79617bb3,c57e2db9,b2978984,2544e9ff,61055023,80faa2c1,9db34d60,b6cc0c8a,e63a05be,be1da5f1,b74450d3,60092dba,29122671,6e07280a,d78a1f17,5daa191), +S(6a474afb,415121c9,38c73c20,27a5fc93,f7e8ea81,d7df1144,a50b1c66,5be0d8cb,5c643389,af9fd383,b7d71966,d251dc20,db8b0d22,8aa94a04,289ee8d8,247877fe), +S(7bbcb86a,ebb40626,ce142507,b8cf0801,2f706862,7a46c76b,fb8eb115,be4163ce,b18769a0,735707da,4b1d7a1c,7690f190,2a3a1f30,67d54f8e,188f8a41,3826ade0), +S(5caeb262,447b4224,19f66418,4899762e,2e2a6b9f,f8aaccae,a29fc3f4,68a1b645,b894f2df,20dec514,2792de69,86a9582f,d6e1e3e0,fd97c5e8,9798624b,9d6e2236), +S(a8ec4087,e144437c,3acf2ab9,3f339415,74e79f9f,cd48bc47,cace25b0,4d4e451b,ef3ce687,12f91e5f,b38ccc98,5c0641f9,d57a6ac2,b72f8814,3e85e128,c7012a4b), +S(724a5b27,5dc8ff8a,e10b34e3,5d05a592,c50904e3,32153a20,78809bc7,5d69ed79,488b7096,f471a9f8,583a9b68,3119a211,6ede4c52,bf817b27,123488d2,9ecb8328), +S(1d1ab819,80b10336,75e10627,b7293cb7,7f31cd83,ad1a043b,ae9aceb4,aa0a7463,cfd42f33,c57814a7,acbb3f08,dd882a4a,c572412c,8502e82f,a3180452,7d2e0151), +S(98b12e59,8166e430,ea43d632,f8a4b981,f3745420,6d1233e6,f9c8756a,47dcf4d2,4f65841a,b8f18241,a46eac62,b875173d,350c78da,6d6af3db,d9fb9bbc,77f33b96), +S(58dab35d,9ec4e48d,6a7e619b,e926ec2c,45f67be3,3d89bde2,38963966,c96b3270,e5d0aaab,6191f65,e6340837,747339b5,acd35b86,823e06af,85eb54c8,7f926564), +S(41dfb55a,cad77bbf,80435b8b,7f2366e3,f41e64f4,74bd9895,dfe86e8b,50abfb83,147a71bb,3809c321,d960ef5d,9f767bde,7873efa5,c590e799,db46d8ba,8c1dd2cd), +S(d739d1a4,72dadc,eb59a120,3b8de564,5d5c1e1c,5ee96ebd,533442e0,de0c8684,610f527d,8cc0ddb6,cb17e24a,51aba4ab,5ab0d8aa,9ebd61c,5d26cf93,30a18293), +S(f887ab66,ed92339e,8fc9d8ea,1af72d3c,6426ba1,a8be283,e2457a97,342dfb4f,94de30b5,4e69b56,fefae855,51fd5a5f,111671f9,c5a733f1,1ef7464d,88d5d66e)}, +{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), +S(15fce59,bb77b091,90e5c39b,ae696127,4d51068d,ea51ce52,6c8525e7,b1ee3d1e,b55eb928,92ae639e,da63a4a6,f14fc6f0,ee2450b1,94df32da,9a1004a8,699797a8), +S(d3e5b06e,7648321e,4fe95ed8,e1316474,43996e1e,2cff5283,26783ba9,1906cf7b,2ad6127a,9e45be65,26ccdf8a,460cd441,cebb5689,9f3cfd41,2aae39e,c838b2c5), +S(114032d6,8e474d1b,a9fc40c2,f22f5b1d,6d12b9dd,9cbc286d,38274501,218c54b7,9dd3d787,706a063,c0d81bf,d1cecb6c,b7b5b446,6d7c955d,22cf05e0,822a9ef1), +S(a230cd33,6bb82fca,bee35435,dd0d560f,d286785a,f5425cd9,a4c9abdc,819e58c,57d99f9c,aef9cf3d,fa66dfb8,bedeec77,e21746b4,27e4869,39cdd8af,5a9182d0), +S(593e3646,546aafcb,fc8a293c,6cf0530e,5f1f2639,2f3ac2b0,b136583f,2981e8e,15c4b596,6589f9eb,5fe0d0a4,91e768ad,fc7f5283,875bfcd4,3b698a3b,4f268b43), +S(37729a9c,3ad25a03,e1cb6fbf,ff486df7,d518809f,66099d27,d203dab3,3d33dec5,dfcbd1b3,7905c99,21269ca,283405c5,208ef5eb,e96c0801,f8868631,69ba2c23), +S(46d8c723,f0b889bb,3272389f,ba3ba57e,d30d701f,7f730d0,c7ebc34b,8212cb9d,bc41f981,2017d9e1,1e4e2277,92b6e804,6318776a,d552960f,c751c36,c6d00a2f), +S(fe29d8c8,fd38be9f,c316c2b5,ab74dc69,ffbcc390,1e59df52,66aa345b,6b1408a3,338ea0c3,f80e4400,53858842,936562f2,8b9ea4ea,31540868,11e87150,89e9e304), +S(99ddf18d,cc6505b3,78a4cbb4,f45bea9e,44726ec1,cd51397a,d536dad7,b1b3ca2f,fa8e8ab4,b6071958,c237e5ed,5e0c0962,61825572,3411bcf9,8e923b1f,e748ce4a), +S(14c9fbd4,a0fe77f,1f518efd,13dd7eb0,cb7695f8,219db1be,d4e76fee,813a34dd,991011d6,f67f3e84,a54c2357,9897dff5,f2a58cd7,40bffbf0,a876a611,535f2540), +S(3cc95333,2788684f,bbea85ee,f49a2ae7,51d5e29c,48642a5d,45236bae,a122e5dd,2ed99469,8084af0c,44e7c819,cdeaf311,72f08aa8,ee70644f,ffa2dbbf,bf9c0bd6), +S(9fd0c95e,f60c6831,959f2b44,5a15a366,6463425c,3a64d213,b014edad,bd22e711,8bf7b7d7,50558a66,4481df71,2c14fe8c,9411d8e7,13fa61f0,fcaac1c9,2c1990b7), +S(b23e3552,9d02bd4f,bd847080,a5e9dc69,964b324d,e16af0a8,857f46e0,ad9f32f8,f3b98226,f77e4393,dc35409e,69269fe5,957a3e74,e5e5d7c1,ec11c4b7,3f5ae025), +S(9b674b33,b7bac25e,88896436,b6c80dec,be8cc797,fd34603f,a4007318,415b95ab,50811d7b,bf49c464,de0b274e,2acb4dec,5786043e,6bbded6f,13d0e131,c3b223ea), +S(2cdcffd1,ac351cd5,21216262,9a401b63,2f4f9c64,9fd0e250,2adbd66b,3a0855,54ca3d4b,6043a79a,66cfb5b7,37127ee5,c0a3e0fb,a4214052,6da020b0,c757f73e)}, +{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), +S(799812b7,d79876fc,7290c3dc,18fc6ea7,1d224373,2e79d17c,9737a47f,29fa8502,4118e843,99b5d024,a82002f2,7e791cf5,badd2e5d,98ae1f30,6d98ea6c,d1d9b4fe), +S(8be7f251,78840efb,df56c470,c4db43dc,54bae1e2,7cab2bfb,c7a6641f,e34f00ad,6db39ad,c7ad2102,90c29073,e48225aa,6d51f27d,d97c0b0f,e241f9fe,dbe1564), +S(bcba249f,59646b10,4f6aba48,1e886117,be0fd815,a6220e4f,f5a08eb6,ac16c612,e8d84c45,88ce9926,99b2d6fe,5ead0615,4b32a372,209e06d0,c3d8c42f,a0e22b86), +S(ae1a61b5,deed4d8a,915b94ca,72aeddbe,2c725ca2,86311610,476d94e0,73fb1415,e1f62c42,efb2da24,47b3b5f0,834617e,e06078f6,78ebf4a3,d38c45c2,f384e1b2), +S(a1e069e7,74cdf680,41c5aea5,39552c4e,bfefd4b6,3869db9e,c5532b09,e8370996,cc1216a0,cea149c1,f19ffcf0,eea82fea,29fa7f3e,b19d5eb,7307904d,a38652da), +S(e6433844,64b7b1ce,bdbbaa01,aea053cb,a36e0cbf,e1c9a652,8c714a45,6b6b66,22f16bb,17b781e4,47fc81d5,1ad5ec9f,c158b069,7c446bdf,52da86ee,6b4ebe8a), +S(accfa38a,10f8d4c2,f8342e29,272f7c54,73d10562,82653714,8b67a26c,5735ab9f,ac0e6829,1043396c,be583305,106514ae,354532ac,5ead4594,dd5a6d4e,332cec1e), +S(d201c17,a1e9efb1,7bc1c655,48c100e2,450614aa,b45b8125,9f2f7e31,4cfc924,4677a168,1eae4650,5c5d6c94,a6984480,43f3793d,ab496ba0,ab86064e,8b48ae23), +S(6612ab47,b35d942a,98427ff,ba59b78b,fe44437e,b87442a7,794e3274,89c3b335,cd540fda,9abe6c72,e298eddb,6d8c5a3e,c0953eff,4a61cc54,22d01ff5,f7329785), +S(35b1b6b9,ce9d1a9,802dd987,745c615b,87a96a83,d1b2465c,cc9f82f0,1c73571d,eee3f5ce,aa7961de,dbb80107,36e6758c,e9cc8b0d,58a6dedf,ecec9f2c,7a73865a), +S(c798e22a,59e65aa5,6647a86e,f9a91e80,98cb97e1,81e07b4d,c3fdd428,dfc3b1b2,45f881a3,1b10db23,ca93210e,22398cf4,81a6a61,6496fb5,ab82b456,7f99a392), +S(39d9dd1,955b77dc,4f4d7436,9d7785a9,c8ebfbc3,d359f15d,8d38d8f3,1097a2d2,64040f85,819c8a31,94dc8ab4,5d794fd0,dadb6826,70de6629,5afaaa1e,c669126d), +S(a9168a3e,d48f2332,48bd4a53,dd37e37b,d24b6284,a2522671,c6494bf5,84738bf1,6ec107ed,6f749a16,27a57227,4d7bcf8f,8ff71417,7d38f6cf,64040ca3,3292bf65), +S(88b92b0f,67c3524c,3d7b04a5,bf539b2a,a244f3de,64867754,bad51192,292a6f3,f65e55f8,f9239573,d77176ae,c976c545,a0e4668f,8c2f2fb6,cb2499ae,94af11ed), +S(6c7ef071,c8f4b0cc,67e66561,38d5354d,fe5c9edc,5cea2eb,a43a5751,317da5ea,40894203,7cf76552,33da385d,43e1bd8f,cb871737,c4b7f044,a44042a3,34d4bb6c)}, +{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), +S(a6bf4e6,9cb5faaa,8b1308d2,da8e2ada,516b5f18,733156dd,2de04cb9,ab1b0e9c,b84be8fd,2ac4b2f4,2934490d,2c7de2a7,8be093ea,907bab1c,94681e51,3ba7f4e3), +S(4d280f0d,190ce936,11ad117,ad7ca092,d61fc8cf,db1fc752,5788c7d,9cc97535,f20a17ec,c8fdbfb0,2db3b21a,acd35527,25a7aa8c,d20a6e23,bcdeca87,a6fc2112), +S(fc0fecbc,c71d83d7,c888c451,f862474f,2538e8a,800c8a93,f4c30be8,ef98e709,3e809271,356b87ad,87d15888,26b055cd,6ec7e44d,3c9e404c,a27a473a,8cd093cf), +S(c3746b0d,f41e4a85,be3bbe25,c1d64961,f80ed512,8ad3c3d6,2cc5b9f9,b231dabd,382a6d3d,d970f8d4,abe3a72f,58f0cbd5,33dfb21,b92571e0,19a0ed82,55974b77), +S(e5749369,b1e25400,2927cc8d,3b15b5a,dad570b2,cc6ab264,a8af3de5,fcd9a458,38cc0e66,e5b86153,1b8b7aba,c266235b,fd34833f,9b0a18ef,9ac361cb,407d774e), +S(d3463d82,782ece5,999dee44,cca08ccb,1d908f11,7f19d0e1,93f42e86,505470ce,ebb2cfb1,f948fa0,4204c39c,cd3c12fc,6379418,33e9ba07,cd714715,268e8c85), +S(9c88be4,50bee26f,14afddd2,80e247c7,7d07dade,81c55945,4091d1a5,6acc28e1,1a943839,793d91cb,865a3213,4d4ef1cb,927a90a5,e9da30c6,c88d72cb,1fef79), +S(77d8a57e,81ff4149,8703d289,c6d2d6f,209ba69e,99350060,d8e53d5,eb3709a9,6b692bad,ab736bc8,ccc1362c,24f05260,5c3d2b0,23deacf4,641c56f5,c2b79fa3), +S(64ad7f39,a9e7027a,51eaade,8ce6650e,2141e655,b443fe8,f67afbf1,7c970189,a730c9ce,acb21c6b,ba834441,9f417a6d,47ca382a,904e432e,3fc2235c,222acd1b), +S(6f1c3296,67d9cbee,7c44cdf,e5614882,1ab9ca61,1731c1a8,28520698,7f94609,ecd182d9,eed899,f9b8e5f4,71e5805f,ef716180,b8d1499c,82f6186,d09a0338), +S(8116e0e6,75ee5fe6,f0bc86c6,c3830977,a4432546,4d027eba,fa242f13,abe10e55,8cae3d9f,af3e4b04,f9555752,74eb60b,1ccd5f10,8b3e52e6,47871a5a,1671fd), +S(1593b19,7dd26cae,e667733e,d4b564f0,ff212f26,1bd6e81c,61acabe7,37b62f8b,3c9d3e7b,52301084,7a5c2f2a,39cb68d2,b9a88605,a12cfb39,fa790749,7107b746), +S(4bde92f9,1335891a,1f40ff,e4310cb4,10e2b172,27223f80,672b313a,184c9a26,c24904b1,c5d83c4b,31748a87,576880f2,73719ea,4413f945,e8233811,5282347b), +S(e04ce78e,b61966ca,ccaad985,376f23dc,7f4e5c22,7bbba119,a99911cc,b7fe0674,f5e3bee,98daaa6,1f45a2de,6e95e919,68f33ecf,4a71be8c,8fe5d925,92e43989), +S(e30ce87d,35b2a79b,ac96ede0,c3b632e5,506b5b86,22a0c483,c4a6038d,d846d191,d92e324c,c5d9a340,e69050bf,198063b5,e4fddd9c,a3e466b6,9fd00831,3eb13453)}, +{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), +S(3e169750,b508233a,580f67da,55ddf909,a6bdedb7,7a7c8a6a,ca262be3,d6e77a93,d8e9c3e8,733dd591,722f7020,a361b2da,e6a4e71b,7001f1ca,2ac8c89c,1b56fcae), +S(a502b4a5,7f7da399,710ced24,5452f975,314b44c5,2c6c1625,3e4c183c,d53f18b1,814e29d1,67240f5f,2a7a406c,bc0e4980,69def56d,c7e1c16b,2a67a903,59400c37), +S(710d4fa6,d7e2ef8e,373a011d,f28b2a15,88e9810d,c1c74a69,3b3e5de6,4bbba781,c39916e4,231ac0bc,90d1c25f,6768b4a6,cb3efcc9,99b42dc1,27065953,bfb3b307), +S(9735e24d,98430f34,7dba7882,9de4888d,1557f650,ca2ae2a1,48394c36,9b4931ae,9b5e03ff,c52da7a,4119c4e0,c86aadc8,eb3172a5,fc430cb8,ac121fd3,d2949b02), +S(3eac990,f2b5a7b9,7ad3c31b,830576f3,ebe86f15,efc78a0e,ce51e592,190710aa,2e75c1c1,786110a9,785a21c4,d72576b0,9fcddea0,b1828f8b,4a7eb45f,8d0f7081), +S(a797ac71,b5c615ab,52e5341d,5420684a,7ed20dd6,b7cfd205,2ef23b45,7302d01d,32fdc8e5,eee8870e,6bd9ee55,821bf2d5,30798606,85f4c9ce,4534b4e1,525e782a), +S(e9b05915,1e029c34,7c30a260,138378e0,a609051c,33b2da36,3dce9dc4,19b2deb5,5494d79f,9edc31b3,9259c82c,14f6c757,be0159dd,c79a8797,95af6150,484d8683), +S(8ed4c8af,27fa4013,a9d9826e,becd79a1,30cb2014,96e583d2,e2d80eab,573a5eee,4bd35c5,cf78a79c,d5568968,fb1043b,c8cb021f,b5729faf,509a09d8,b82e10c2), +S(14230106,2f11cd2f,b0e8abe,5a76a7c4,2eb3f019,ab8503f3,afa0bab4,487a4928,480dbfeb,2b36a3d3,4cdfd029,dfe3a42d,6297724a,15be840b,ff197fa6,ef5f594a), +S(425fb125,e156d90c,31dea3da,6ce5f3f0,2d1d78d5,9ec17c65,e89c3817,d10df34e,2e2a12cb,d621042,8cc2ce77,df2ec8cc,ec1a8a8a,9a2a2a3d,b537f1b2,13ca871b), +S(b54496c9,57e6e359,88118db8,26be100b,affc546b,511aaa43,6be0f72b,2072d698,4174ec3,ab8c5709,581d797a,831c341b,131d94f4,25715984,7c6b95da,e42d6ac2), +S(edb85684,1b5c164e,eed9b5d5,740972d5,781922c,e9d365c1,24475785,2d4c6602,56eedd35,dbb97163,df4f95d2,dc106a63,114e3f44,1cfb2d74,c57a51f9,87eebfba), +S(de82cea,e7a0a2c0,32db9642,49b47662,201721ea,754aefd5,b304d7cc,ab3ab426,8f533e0,81b88901,ebcd8547,3ade77,776ccbe1,fb1d2ca7,b038c205,be8a915d), +S(7e74f42f,e8d3e772,43d11177,ed249ea7,2e87ec05,cfb5af22,2de3120f,22b8214,2978928f,ca85867e,c9563f6d,5e044fa4,2eb480f0,e2ca86ea,acacb1d6,66bfc426), +S(995857b7,8066f2b1,473eeacc,fadafb7f,36fdc5d9,1ab5fd0b,3ac55be3,91935876,631de25e,51831901,aaa62ca9,391ae54,7dda101f,26ac6fa7,3396f885,3b9fb916)}, +{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), +S(e670a33e,75e7d765,9dbc17ef,a0466808,3c57e661,975e8197,84ed85c6,838bdc7d,df5e73e7,4a1f7445,d140fc7c,eee1038d,333590d3,6626d5bd,bdf399e,9d9b1843), +S(751a8413,11be980a,5a884850,c9101021,393634c4,862d6806,2b1e6855,2fb42d9b,26a416ba,afadc235,425ce35f,d72e17b8,6d13228a,ac64f30b,5cab853c,1d80a1bf), +S(f044f2af,6d6842d5,946ad6df,43784921,47c45378,721d1e39,ccdbc033,eb0d07f9,68e474b7,e3b1a102,efecbe4a,a20134af,9f3ddcfc,45213188,744f7816,f381f942), +S(24208410,f23c4fd9,42fca91,94b5da3e,de46e511,7b0446f6,e92eae4d,bfadef52,b17efefc,ca0bb9a5,1544f8fc,15474328,84d79be4,bb7cc122,9aa5d66e,450c4849), +S(6aee88ee,18046ce,6399c111,2ed2e9d1,5ae30b0,663b75d6,a20baa10,57a0287f,44155fad,94ff97af,ff36d407,4f0273a5,adaefee4,e2c48bd5,bb1973fb,53d65d20), +S(b112113b,921501f6,208ace14,74cd923e,c4ed6cb1,1b1fbdf1,2786f43,6d2efb0d,d63f1ebb,f305ae31,2b0fe166,23a9cabc,b7c7b76,1e62c8a0,3eb2388b,5635cdb5), +S(74cc4471,707dd64c,bc0688c2,1d15d3e6,863adbcd,3b6a0a08,78556ed0,239ae027,43c03176,1fcf3c22,3a7e70ca,9e27690b,53f8b3d5,a3782461,6d41fdd0,7202ee6b), +S(a23a0d76,d391dadd,23e1654d,a654f0ff,eb8eb983,fb4162c9,a9956c12,fb77d5cb,66e0fc9d,311c830a,3a2229,fc4f82e7,43592058,536a9e7c,722a037f,f87f1363), +S(ea0c9f05,6e39f66b,5ab9f833,5c8e4655,f4ec160c,7accf824,aa1b5dbf,2fc1f8c2,cbffc05d,64ebfc35,7df2966d,a170fd7a,a5861376,f8d7f3ab,6c004671,e0dc812a), +S(ea4ba4c9,2c8b511a,9559c223,abb33c27,22cec491,e48cd519,74b3355f,4e42cb7,4a4db6d6,f426d463,4d6717e3,d3b6ab71,88ba832e,8a18a4e0,4f17a698,bae7a41b), +S(939ad0a1,a64da497,1a6ff2a0,a709c485,30d752ad,a954c8a,f632f969,95561aab,9a763429,5ffe700e,e36d1d65,f53ecbdb,92bca222,e5e2ccb1,55cf3a5f,c751149c), +S(f2548d26,ae82f5d4,38ac89c9,f8a5f974,4632ce26,8fa7f62,9446a19e,2f7c8cf2,7e584e28,b1590b83,31ae2228,81eb28d5,14ac4360,b60aff7c,d5061606,c5cf4014), +S(a4156ded,fa8d19ad,6471653b,42342986,74f4f87e,a9258de7,6ad54fa6,f3b986ef,ec77cd09,b77e2ca,c7b4ad0f,5e05004a,593cef18,6c57145b,3f9510a4,24ca5ab9), +S(12575248,e8aba15d,28a06860,b5a03e0a,942e33b7,e5099128,da2ee781,98333c51,bd3aa2df,cf99aa06,593a3c9a,3d22dee6,bdcbafd4,414a47bc,38916a19,7c2c2025), +S(b4262622,5bb55310,903f5f23,3b0591b9,adb2a909,e09cac82,503ee54a,64372572,997ac9a4,f1a21373,121255ca,9b622dec,2b4e7652,89731f03,37fe5d94,24402685)}, +{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), +S(da759133,159b8d93,d75c9aaf,616d87df,8f7dcebc,a518d4ca,da418b7e,39a264ee,8ad545ae,37548bc6,1702d08f,8de7a2c4,3b3392f2,3b44b186,fe1592e9,2f102577), +S(29bc8d55,faa61a53,643e8a7a,8f8c039c,bb808abb,8ec4a96,b294e4e7,a5a1fd2b,4a170217,7131ba3,275bb1bd,797809ce,cee979a1,d2f161b6,8b632622,2f92100a), +S(c15e640,b71ed510,37d92f02,7de2ffb6,3524e1c,208a6722,aadbffe5,977de2aa,b208b26b,eeeb6d6,1d783e21,35e71c04,1ab78e0f,96315560,d3729c6b,cf69c6f0), +S(9a738ad5,89e86d47,84abc74a,ad4c781f,72ad7fa4,91654392,510ae297,4464c1c0,234423bd,6b770214,7e157d65,e35cab77,62794253,c3e82487,8a4fe726,6105ad55), +S(3692b32a,5be3acc5,3320e434,42c8d1b3,235d0635,49a493e2,e4a33b49,f02f5504,ac61c2ce,38ac1b0e,7b3c5d80,ce988759,18e9ff5d,669f61cb,b285ad07,6d436ee7), +S(dd501ea1,3aaa02ce,619171dd,4270fda,aa164f14,c90302c0,5a3e10c5,bcafaf5f,20ba19c0,8561667b,d24c59a5,a812fb32,972f9231,19a4d42d,48aca05d,9fdfb61e), +S(f7e3ec26,257636ee,74eb2c22,dc9da3d1,4d6cd511,a6c34d18,a59e3d52,b2099502,a2a302d3,50790316,f99cd37,66e61ea4,8b9b3a92,eab54f08,dbd6a061,5f495eb5), +S(281dac89,3afdc45f,4dba86a3,fc5b863a,23f55d97,e49137da,c7a31f64,a0621a04,12f9a757,c8ebf05c,8bf34270,77c6d2fa,852aee99,af3d4ff0,9c6522d7,5becb9b6), +S(8de33df6,91ab87b2,9e36c69,687cc788,dbe100bc,8be07786,892aae4,e44d5834,1a9c323d,65aca9dc,8a11b116,4fb2ad88,b8625f61,72efdcab,88da47e0,7cc74bd1), +S(f2b7d303,6342168d,75c1ab90,c7045095,d8f415cc,96a86154,97425cbd,e4067750,ebd266e0,7a10d930,80241d0a,218eb94d,51596e36,953ae60c,25fff023,25920883), +S(8148dcc3,da9ce438,7edd33f,484f6bc3,6ebf7b2b,5d5c88af,c22542f8,5c943a95,591a62f9,9796dd71,cb18f64a,8e30d6e,9ab8336b,e9c3a684,ecf891c0,3c6e836a), +S(ff688510,eccb5b50,957de634,e4324f21,5cadab7b,93bf0dc5,ce94736e,a93cde8a,37d46d44,e61fc958,6b0da8ac,2023bcf5,75f8a9c7,9d30c993,e3d9a650,764e1ce), +S(eeec9568,1a66969a,e524bd76,580efde7,99302202,16aa7549,d39a98b2,59d717e1,64c4db73,487b23fd,ab74b50e,53fc8d1d,336db703,444b5844,b0d8756b,b84c289c), +S(3b2616e9,b51808ef,430e714b,ceb9a747,aed9e31a,a9caf6c3,d57c1565,cd9b7f88,e6b4bdaa,aa1ea551,4af2705c,47f07417,b2a03bef,2b406760,e86765f7,23cb0438), +S(5f0eef38,c87db43f,6498709d,48c445a1,ac50b40d,f882ecb9,414a56e2,ec927ad0,8197f585,73b0c534,49c04d6a,b0baca10,3c97d9c3,9a61dafd,fc793c5f,df7104af)}, +{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), +S(170634ad,de4863bb,3090218e,543c310e,9bef094e,94003fb7,5f89b076,757f8900,b708e4e9,cdb53954,2bd573f6,eee4774b,ad2cd18a,ab0b0157,dd1d3aa3,aff70dd4), +S(caf1623e,21907368,7d3a686a,7d48f9b9,953fda37,3f68ceee,66b5647c,ba9ac0c8,95ec09e2,533a173e,1773b047,a0702977,3167a96c,c7a2bb42,74ecfd4,9b1b7948), +S(dd21377b,234e31e2,7a42e856,305186d6,33eda53e,5bdfb93b,f83159ab,9cd37bf2,27a40d9d,9bb0437c,c079c24e,e3a8a10b,c54c8af7,6dda2e35,ab61e260,ddf6feaf), +S(5d6d3e69,3865d2b8,4c0061c8,fc85da28,edd6ab37,bb6bc5d,eaef0d,6ed7d0a8,bb15835f,e6074d1d,c05e4840,a22532af,b33a1131,80073cce,17b77822,33dde5ce), +S(3df62006,31fbdf0d,8ae7d924,370927ca,f27587a0,d7bce798,e6556a8c,62f108ed,c4aa6712,405c44e9,389e0a03,952ce263,c073b849,ec66cb7,b9e203e4,12017771), +S(d49653b7,639eeba7,e9d82b1a,61b0e1c5,1363337c,eed06916,47f81c25,b2f71e6b,f1411513,77e6553b,66221284,3f390c4d,ef25b316,e1123b19,a5f77c97,b4559e79), +S(fb4a40b9,77153349,3d316d3f,2688f6ac,32b63e35,6f8fcc17,ca1a9008,b9a90745,d49d6d04,ba60238,5cca34c2,6e5e3ea2,8396a459,c9f54478,f1e93e94,fd3545e4), +S(2b5f9b4,512e7676,82d7f93b,39027d9c,4d2788c4,b587dd66,8e7e2a49,2d1fa3ad,507b76a7,33682d56,6a2773f5,c3cda342,2152e9c4,9c204aa,bd015dc3,9c9469f6), +S(55e1a77,2c3406b7,b300e7de,d35ff44d,76fbb312,7859c80f,841bd730,45c0c006,f7f2b9f4,7c2ec8d,9b476229,ec773a2d,7316b391,8f98d540,e110d196,58cdd0c3), +S(269a6ad,e6e25392,21f59cd,10456fe1,b5e3a756,1e13e578,3cc6b7c6,ef145ac,3827d2be,94cde1f,ded8306a,6619b933,ac2515cb,45cffd75,267caff4,1e76d6ca), +S(e48e1e7,87d48c62,8e85040e,2c836be9,cfb20d10,51a251cc,9e46b589,485a29f8,aee94719,b64713a1,ff2f2402,ec6a19c1,4df12f40,6214c49a,d9b00234,4325730c), +S(7612f9e,691cd23,701a213,79582527,d658be1f,526c220e,da6fc536,b3f7780d,a21538ee,e80268c9,ab6dbe6d,1890c4f2,99aa8dd9,82e9978c,b6ea37ed,53308c10), +S(34761add,2f2dfb4a,6adf1f0,81aff3c5,1faef7cb,bc1a989f,3e23afba,288c11ef,50c8b3b2,9424d319,8d55c10,3976f312,bfa480ee,9e93caf4,b75fa97e,1517d3a1), +S(8e57bcd4,5c8e9789,624ad4b3,8a9d5be8,bcac139e,a0abc310,a1c272b2,35942e69,8daf7fa3,43dd401b,c8aef9d9,c102b577,28535818,3e379de4,5e5ce268,e9f9b548), +S(b9c35f36,2b93a8fd,21c9307,91c659b,270fbe0c,965c8de8,b5b45ff1,e4c8eadb,2e506d1f,a9fdb177,e0a818d,b40d8f67,2b5ef2ab,72f051e,8f6eee9b,fc74b9e8)}, +{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), +S(1fb0f8f5,ce10e878,abf40518,116bbc18,ee77a22,f701108e,a8c4f9f,f6562080,8f761286,34089abe,b48bae3b,882019c0,9bcc5386,20fa98dd,4a3710a1,e4e9bb46), +S(4a807b29,3b312ca6,acb43f49,6436b137,36748bc,15c48dcb,7dd35e75,fd2a5668,6115f059,e21f7257,c8888959,d1401db4,c77a0086,34cc2206,e8a8d4ba,1540def8), +S(288ab400,5444930c,15410269,9757d7fe,b8410241,38c45db6,d6a628c8,e0100ad6,bed94f18,78f4b61b,c0b557d3,cecd946a,f9d105d7,a298cb73,fccbddd2,4210cf48), +S(22a7d3c8,85001932,985e9543,1e470770,f664ffd8,e4593aca,7c93a7d0,9fe01b93,65172aa0,9a61749d,d0695269,4a15696a,947c8b37,7ab24041,d76aa7c8,3055290), +S(4470823b,bbf22c97,7602d166,dc895df0,a562a732,f905ea78,416a74a1,eb0f35fd,1b1eeff,736ef902,aff3980c,36b47ce0,c7611f5f,cb83658f,7c5bc15b,c6e35414), +S(bf345a75,c16ba113,a4255ce6,cd485235,d7b71b8c,11fd0d49,1bff369e,240aaaa,8a8b2999,e06ffa8d,89932713,b1bb5c5,6837bf51,aea390ba,9579f2e5,566e7c1e), +S(9ca5d558,2737e890,f9a7dbaf,d921177f,459d791d,21f9993c,481594fe,b9aa7112,808fbe3f,cc3e80d3,f6e2703,f55b32ad,cc1ee8e9,6fdd0250,d7373b15,83918a6), +S(4d3b878d,ac7d1878,a2cb8ef1,29c488f,59f26f1c,d56d5476,7b008e47,eb7a293,ea8ade6,a46ce8f9,4602d631,e0147981,3422eb50,e87cddd6,792a1ee6,2c338f40), +S(2bef9f5c,accfea49,697aac36,24c7db8a,62f03620,109f1cce,fc46af89,25489a69,b39a88a0,d7d59b29,b7773984,53e6eb2f,7b557171,20de3625,a917853a,ed1f8d83), +S(74a0d8dc,415a228f,3bfa9533,e7d4e544,f03551c4,d55b0d2f,fd524d17,835c3132,d3c7c720,c44b1742,49c2d9ad,3e9c5f9c,eb174ba1,bcecab7b,5816cba9,9057b5c3), +S(33b23068,27e030cf,f0673254,ee13b94e,6d7377d5,fb8c9a83,ed50e9eb,4ac6d5f3,b0116426,ca9fc25c,a4f9834d,6d8974da,1571a54e,1f507696,879ecac2,5f23b095), +S(a45a4cb8,24d90134,5ea541f0,6896387a,12711d70,6f07a850,69478780,2e49a474,bb236a74,96161e43,f708abb8,80e3d0a7,a6354a33,cb760bcc,593bc8c8,7c8f433), +S(fba31e01,2f38c223,3750fb25,85c2c33,4fe3afb0,36b17fed,5e8d513d,552dc2b7,d6d8f5c2,745b2c90,d5c201f5,524f2b0d,49020ae2,4eca8e21,b95cebdf,af25e5c6), +S(8a5bf15f,e026e897,190ee896,f79927a8,a8658d05,f9a0f6a6,79ac8971,4ca26fbb,639849f2,41d99df9,d217d702,4e6c5bf2,9e44b7ad,63e0b091,bd235d45,4cb07ebc), +S(43daf5b8,4f1706fa,cdbfab46,e4ee5188,b8697efe,f6d1274a,77af6bf7,b1ae23f7,d2fae1e8,721553b7,e63130aa,76f61e96,a34e60bc,fe7bdb8d,6879a39e,db08d8a0)}, +{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), +S(472e2d82,220169b4,e249b18b,ee3d0188,70b91ff8,77fa9f64,9a23ca43,a5aa9271,908226fc,2704e162,c96297f7,6af76d80,32b7845e,9b998466,cd106e37,1a61feb1), +S(e9d0d14b,3cdd4531,f8125e83,dc3ddfda,18d64976,bb4521ae,83a9d9aa,8609b431,e1f950aa,821f586a,91988d6e,e3ca4db1,1574041d,140c64,2ba9a1ad,cd1c52ea), +S(e47190c1,f5fa4910,6160e301,69e8a087,76a9e996,aebef7d8,2b1d7248,7d38ac4d,50abab42,dea32fa5,af0d65cb,3dd950f1,d2e54bda,47d990ee,9fd9cf49,cc552d1b), +S(dd7cc010,b8c93c99,84c19b2,37aa2b6f,1e51c765,7b93bb9e,e4d0ea60,2d6dae8b,9f2773e8,15aa182d,f6ee5e70,8af9e8cc,6ed5f82b,994633b5,545ff889,c5503e5e), +S(6e4656b5,aa8f321d,80a46a7e,721ab22d,f5216f9b,602aa74a,84de050b,a3851d8d,170a272e,f646cd5b,e3c1d9d,14e19601,2f7b140a,136b509e,580c4800,7c0fa08), +S(d0cccf87,813d74c1,e0ef5315,2a2e82a8,9d6729bb,23c8f450,d1e5af64,4b7f6341,b5c903e9,dc51b73b,5cfaed20,b9986f80,b19aed65,d11e624c,53162315,2ab2cb5e), +S(87f7d90e,8f519af2,34262929,c4801bdb,fe472f0e,3eb746a0,cfdde906,1697a540,36b97cec,b6a1766d,b349034e,a980f0d3,cc653b,5ae732f3,e9868d37,1343db0f), +S(feacbc45,43a59a7a,3fe37bdf,5f05885a,a38cc3ae,68e423d9,e90da9df,15569f45,f1aaa0e4,230faf54,c1a394c4,fab80639,184d42bd,62fe74fa,d2b9d8de,2bd13779), +S(db4aad1a,7d5b51f4,be47fe0a,d8b14711,e03e0283,3076470e,7291f310,bb88b65,51b5928e,9e6adc38,be8e5e7f,a93336ea,4ae1f65d,de69b73c,62e04384,fcca96d2), +S(f6a6bd4d,3f763afc,721fd2d9,ed42d34f,df38bc9,4fec069a,8f8aeb76,8b23f74b,d513f993,f97d6fcc,9a7fcd74,458dc00,437fb611,b7e09b9e,a9e85c93,1facecb7), +S(982457c5,6c22522d,e0d10fa0,64a0f8e1,52fe9924,6f20a794,81df8fac,8fc08ab7,2e080dde,a66a3e43,af44f9ee,bbb9962f,16110b33,b0e9d83e,38333aaf,89be29c6), +S(2cd27cb8,d3646f0d,a549cf0e,94e70cbd,c40082df,b4a04456,47579397,e3e12d91,c17377cb,e2ab57d1,1d6c5cbd,c5fef865,440dd8eb,cb5cec53,124872dc,a49409e1), +S(6f34f416,2a190923,8a2b5561,54a056e4,9549d6f1,72929ab4,fb49175,b7da0cb1,2a0ff98f,98422e19,e394f868,7f2eb9d6,dbf7129c,c98df378,31895799,445a5211), +S(3190285d,d898dd64,770729cf,25f59339,eee3971f,16b08450,a87c9916,efb1adca,5423d919,1eb4bf71,fa55c153,161ec8a0,6f5930bc,17ad25f9,39f229d9,8af5382d), +S(3a150c48,d4c56e7e,9d910864,29b43219,9c95881a,d481e0d1,59aaee93,b19ceb72,290d1c34,f241d3b4,f7bcd618,f585578e,7d17a89b,9be52eea,41020f37,e1f521f2)}, +{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), +S(941512ff,9ddbed5,13d60b50,1f3425e5,d210fab7,f30b2ffd,db6bb10d,b102cfa4,ce038b23,257413b9,f3bb957e,43b25747,49fdb5c7,a975667c,72de28a4,46cf4572), +S(cc2210ec,ee7d9560,753ef5c9,1ff9590,230ea13d,8416d73e,47332720,ecc63f9e,cc800501,dadde2a4,152ff67f,9d430ed8,3ae15e7a,e5bb493f,95d41167,327eea9e), +S(384629d5,414c9230,60077a1d,e52fb3ee,ed883b32,46d6f21f,e18285c9,2b1562ab,9aa889f0,f0bb4632,7ff7ffab,beb7eb30,d8730560,edc85521,425d7f6b,372b2272), +S(1ff9dac3,a65aafa9,8693a45,3ac3ee51,915cf4ea,1651a456,b1a03aa0,250e9d97,9245a361,a7831503,be192d77,2f592cb1,f9129287,9ccfc15f,494eb437,9edafcbb), +S(448f1c1,db9f6274,e49511a6,26ad249,e2c0b808,1939a383,609bdabc,dd94ade5,6c142261,2a8a6cf4,1d4bf7ac,8e6e7c87,2dc33b72,a87ef595,e9e0ba72,c68fecb7), +S(c6b5006e,8fabf0c,d3e72c2b,45368021,b6e53820,59fcbca0,3da03181,b72e6eb7,c579f919,cb4bb266,a527a446,80dc9300,629ac1b7,4a5ed005,f5c455ee,bfd5aea7), +S(f4d156ae,da9f6e55,f455080d,35fc507a,bcd2b23f,de6d893b,5ba039db,27493953,7d45e992,a2d4b8cc,41c2849c,34e785b4,8fdb39c2,e715328e,9f7690a7,31bb5e66), +S(bd72705e,9d2a78f5,6d39be16,b1aae55,da527752,c3ada8ad,3f715d37,7e3784e4,5b5f856,7559fc2d,b7088120,9e71be70,db2a4404,e9076084,7f4d7bd4,e2aeb3c7), +S(9c6bce85,191030ff,c60b2b07,c8187f79,249fc982,47508c9f,2797da3,c21c06fb,dd7be1e8,86931a24,925e899b,347a81cd,85eb17bc,b73f9cae,1097935b,462d0937), +S(1a357743,84feeda0,405e9e16,28657462,218f4b2a,7921ed05,dccabcc6,6fe5aeb9,8e44029f,7b28b880,9640e5c6,60131513,e283ef66,983770ce,686aa706,81b1aaa4), +S(d1908dd7,f1b5eaa2,a1f9f066,683db7,b3ce644f,77a839f1,488c90a1,e372f18f,a221de7c,15bf27f4,ff71f3ee,fb068463,79d09aa,3b6e8b82,bbe9eac6,8c00738), +S(b7be7d12,1e964dda,820fb389,2f9e99aa,36e8dc2e,7498ea80,34af4397,ffb82b91,88813b9e,c333a6c4,78b627fa,afe0a657,dcf449ce,3a5adaa5,662a81b0,68b8f5ea), +S(6a66cc8d,27ad7843,ea1a9b74,373e413a,1b3b23a5,fd25a58d,6b75a231,b97538e7,afb5aa7f,f3cbdd2c,a4dc9694,e56141d1,85550285,8dd6c89c,7938be2c,a2856c4), +S(2b1e7d33,b7d1ff91,ac03cd10,f3756e9a,d39d358f,2f63c2fc,e89df693,5e16d3e,d42588b3,d1b1fdee,b860b4aa,d0ded901,bae1bb87,681fc257,e843ab8a,76280692), +S(f7745d72,7b747b4,e9d6e7c7,1242705d,140ed4c4,d43d28cf,a0a8afc5,37ac932c,f640180b,6b8b0eb,c94c8931,2f897e5d,1ecf427d,7c86d2d0,772ed63d,f4cc3444)}, +{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), +S(f0e363fc,4c8761ad,bf4245e2,b151a7d4,335c9856,bdb9fb2c,1e53fc76,28a9a69b,4629a699,3f8753b8,6d2190f6,505e009f,6fe56739,9dc77507,a1cd4cb8,920b0ced), +S(a28116fc,5e3541e8,8ffe043,160a97ca,b1d6e898,b6a3acf4,d150860e,5bb6a1c2,e43aec5d,22795bcf,7979e260,de7da3fc,46023dfe,8db4851c,165a2fb3,47c204e8), +S(cf6eca04,328af9f8,e461b6e8,9251f94b,3156a63b,d440d6c2,b6dee5c8,7ead5b29,1dcf90f5,9bcd5c0f,362de1f6,1b7a93d0,6ab64659,7f77bf94,b8bed972,9f096f2d), +S(44bcd74b,2cdc4b13,f48e3cbf,b005bf74,bd114fe0,5c2661ad,46642f8,7e952fd3,8873b17b,67848110,fd200c6c,bba0782,34dadccd,70dd83bd,cafbca31,df373440), +S(2dd5eaba,e7cbff44,d2e56df0,14fe3577,efbe6df3,57b870ca,fcf5bfa3,78d35cf3,6922806a,4ed044eb,d711f510,e7c5c846,ce892189,ba4479d3,7ee95a8a,11983756), +S(98294f63,5eac3fdf,f8e07f53,d24e650f,2e470b0,6be9193f,1463f1ba,c37bcf5d,6a03ece,4f397658,f232bde5,71f33a4b,a8058641,e301c99f,e1df978c,74236a47), +S(c68b7c67,36003c06,d29ed03b,2faedf60,5ef705f0,f1172166,b63bdcc5,437bcf0f,a62dfd76,c1df5d72,680eaf7d,51359a63,82ce005d,fac432e0,672f63cb,cc4367aa), +S(10da4eb6,72c088be,d2d4a28e,3e48efb5,f4a456be,b501183a,816615cc,f23b598a,ab798e69,26e55eb,c0435828,a8006356,5cc6ea48,892f748a,a6ed1685,36a3bec7), +S(24363000,a821cc76,4bb2c552,3c37457,9462263e,df791598,cf7ab8f0,89178ea1,c6d07d19,d53ffbdd,f367f46a,6fffd5ac,e2236f63,26fb18cb,3a7d543b,9f193b01), +S(459ff583,3501bc72,13c135c9,be63ef4b,fe99b731,917dd475,b356fd72,21705c8d,9c3ef5e7,4483e1a7,42316df0,9f313a10,17858e7f,ef432763,df139b4c,548aa325), +S(43e3d2c8,44b6ec8b,b5ffc06b,d2a48ad4,39893fc6,a9748cce,e55adc76,d616b503,62efde43,b6525e9d,6de6a7f9,8831e194,9296aeb,7ffe715b,4a064166,c18144f2), +S(8d6eb1ec,5abe1d6,2ecf6a0c,e1283a22,e1259cd9,4ae96c8b,1fa03521,8439f798,9b7e03f,f50082eb,38098a19,c417c4b2,74432e47,79faa37a,2ed5e43f,daaed45), +S(fbaf2899,4a9ebe2f,cbd854ca,d1beddc6,7ea94f73,321f3006,7d75b327,bf25b65f,184a40f0,777c4a8c,6614f8a4,d5ffd514,3215c0ea,9caef82d,c20285e0,4477cd77), +S(c58395d4,623cf0cf,8c7b0abf,686f71f8,6c0b1977,44ddd642,7a1c05f0,1e9f938d,1d8eef66,7d5b8ecd,af794b8f,2bd30b17,966de31d,83ba46e9,73fb4a2b,914b06bd), +S(40c74e1f,f01ae64d,85f958de,6d1faf97,6169b00f,aef64c9f,23c5cdba,5e17d294,b21a6ec2,1b409a69,f8f6987c,1b1705f2,47781843,73ae5695,14b46951,48448e6e)}, +{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), +S(a1df11b5,743dccf0,90fba9af,bc699089,bc923e16,96a7841e,5dd338dc,a8aea428,49a697c0,45f6232c,d0d7d5d9,c7e33701,758e6a12,9a9a50d1,f173beb4,5b9b601a), +S(fd7b2a1f,cce0c2de,e11c9f85,c245f43,1b9aed6f,a542d401,4677236f,4381b927,77bc8fa0,5639307c,463fd419,a784dcdd,be1bed1b,be42c315,dcbf9d24,a5c7dc1b), +S(7962833,c1cad761,fc1ecf60,62ab6f9b,b11cf765,2c5c2aa9,e4db18c0,544ec275,7a8bb3e8,209f1876,d3452f6f,40c3cab9,f7166dca,160e0f51,afc35302,75740cc1), +S(bc8ea787,2f386ed9,24197d6f,cde66dad,43b1bc,390ea517,ade69780,beaf444c,12f31c87,9b69c7a3,bed748db,6c0dc465,3a0c1cfa,e4cc7b97,c00abbef,1b86fdeb), +S(eb4a5a9,5957f070,73fd04fb,4f1d9403,ade11ac6,62f2db35,23a3c16e,4a34c040,277d8694,e598912d,7b1266f0,493d9141,febe0f46,bb69eb24,c8be701d,9e8c6f74), +S(391bb04b,b3b924d4,bc548329,64368cbd,7cbc1a79,c3410cf6,63565b9e,e62c5d44,951554f5,fc6b8ff6,40a0aa39,39929e9,41db1056,d05bf87b,ded15a32,f06197f0), +S(4b6a608d,baa71d6a,e20f543,f4a5041c,a06ab5a8,cfe0b331,6a6702b8,46212ea1,f3c31e22,bb3a2f28,bf1f0594,4f798603,107cb301,6bca7ea,a8b863b,5f85954e), +S(a560f348,ba8b5a1e,885158c2,a4e94464,1bbc59f,3fbf4851,3216f4a6,cfbdf8ae,98568f29,eccead17,257e558b,b3835772,5af94f69,42b943a4,36a95824,b92c529), +S(2356a93f,c5cd70f5,f5fde88e,6744efe3,d0d713f0,31f228a5,1cbe2c3a,4baf7107,59adb751,7111910f,9e1a690,139b10d6,f30c311a,4ab6b82e,d1ba7077,3a4994eb), +S(f7fefa64,ad63903e,66705d88,d5df718f,59b7e9e1,f9180d21,647b2a73,6e2f1d6,30b5d8fe,5393f9f3,b68dde98,1adfc77c,cb3953f6,7fbb3445,52fafe72,b9453532), +S(73d5d8d0,95d6c533,60914bcf,5b279c5f,f20145e4,e0ba1ee9,468c2edc,b59ee4e9,56df32f6,dad0b462,487d2b25,79dc14d8,34ef8705,d5efa77f,1f371bb7,641ff145), +S(a1d772f9,4377b24,c98933e8,47dcb51f,7a982940,d205e4e3,c31c2cad,9b90e410,617a72d2,ea1b82b5,775f13fa,1086eb6,2827572f,f6182101,3cfe60d2,7df6aadf), +S(28725dfa,ad66c6af,5f980f25,653ea5d5,116fcc37,be615037,48d71033,ffd322c0,67f3cd88,1ba30b09,3bbc1a25,34826f06,90b149e3,964e313d,e3706f60,31dd6c0a), +S(38573246,ddba2c47,a9d85ac8,c3a13ec8,4133da2a,cf6434ed,98acf5a6,84d89ba,e97fde8e,6b2c1395,a9f242a6,8fa989c9,5dabd2f2,ab830949,4c100a1e,fab317cb), +S(e69ebcca,426dc9cb,474c5f03,5b6e6245,cb18fad5,2d990ad9,6d29ea8b,e032c220,322ac73b,d7c6a5b,89f3926b,82578f6e,a6fc83de,a11da204,e15bad7b,51ab70a7)}, +{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), +S(db0d3761,c6b76d0f,4b3f6423,daa1acef,19d01f9d,c6230840,c4ef120,9e4f80e7,2ea359b1,f19e5d6c,e8360c04,12ca60b7,a43939ca,36fc873a,7a80a884,90d3d359), +S(a4539230,a9c0b4ff,65e2a8e6,47490c1e,752706bc,ece59a96,f2581cab,1b430bf2,9c80b433,f87ca7b0,3662b22d,73a99e91,a8c63fa4,9fd3b8b1,b17d669d,aaa9604), +S(a77cbd99,8019c652,7ad38d8,f8be3ce2,dfaeda98,d378cc3b,7f86e291,15a56adf,3d5ef26b,d797de9,6f8a0d9e,d14a5209,ffe8964d,2bb768ce,bc0c3422,85eacf77), +S(2b99d5fa,a416b572,c796d92a,ba9ad7d4,5b020fae,95aee14d,f114489d,cdbff30,4b89c70a,74e07b43,cbf503d8,86954759,9c3862ca,32bf168e,20a913c7,4fdfd266), +S(a007a8e7,a60dd06,6d11f1e7,4912eb12,91908cd9,a3fe6a8f,53393040,f9c6fa52,24b8c6a0,6160c947,61645355,ea365434,323c1d9b,2858f650,5526497b,d148873), +S(7f3f4e9,24fba80b,702f3252,64186077,2879a2e0,cf86c721,cb97c5a,cc1403f0,fa6c055a,4eaa3651,3746385e,c69170f,f3a1ce56,d9c06440,e49bca94,e97220db), +S(70f9b6fb,c3c4a20e,69c75791,2289936,4da614a4,dd49002b,291767cc,304309d0,5becf8f7,3c414163,6aecfb98,161da5a1,ddb08885,545d946e,c4f2f39d,66b15165), +S(ffd34a18,cb7a72a9,19b97602,2110dd29,484b3fbe,84ee3c9,46b370,f710d86c,b03c2cf3,84b6502e,f519c55,b40f0037,cab3e513,2304243b,f8e7117,cb4d4bdf), +S(ef8bb54c,c1fb8d0d,7be9f5c6,85dcc465,9ce9d874,bb1f860d,60bd0954,d751cf7a,79216699,1efe79ee,bd5232c,687af3ee,854c85f0,cc61888e,c2981689,b03060fb), +S(d1cb47ca,c6b4609b,3e7e8f00,76519a77,9d8f4494,baada6bb,43d3a034,5c3e93b5,a8bfd148,a40922ce,1a2a3383,ce323c5,32041c5b,f89917d8,41c79867,d6efdf49), +S(ed2c9d96,38443a38,9a00241e,ce1edea5,4ba0561d,a084d166,9054b486,89bcaf5c,f81239d9,ad7a2fe4,5a9ba8da,9aa306c0,3d22d79c,c80f7953,53c13a90,c81d0505), +S(d7174d31,4126e219,817fa00d,140990dd,43cbebb6,81c45d9f,c5e0dead,d8135ef1,38093e9a,ba7a7223,6a5e8a8,6ad4ee9a,a5cbd614,da2543ea,34021578,8938fcdc), +S(41dbba9a,b52c3f9,98ecc1cd,aea6a093,ce702077,8e5ac6a8,91be5bb5,f73cb8,5ef35b31,829851df,7c3a2304,5777b6e6,89e79e3a,a06c7b73,f3bd47dc,fff8dc99), +S(f9ab0480,d24efbbc,26f1d2f,f09db463,f3d50993,af39d822,85efa32,97c73b6c,40a5a11c,c647b069,4536d4c,e154a58a,db0cbaef,77b24591,bb39020b,ff9c72ee), +S(e59e905e,fe97f343,7bc6ef6f,b8e06ed4,1eeb5666,c3bf72f8,5fcd3fe6,d0f68928,28faea3,4fd42596,c3880cf2,74987c2f,2f228442,5666ebdb,e357d9f5,e8886c4c)}, +{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), +S(92932066,93f2280,8bc088eb,8b50cf83,93c0a33f,5149976d,27b837b1,2e769b6a,7d86f6a,418b04f5,2d01b933,428d1ec3,ce62d349,693d267f,48cb005b,1499aa0d), +S(10e4d4cc,b8efba85,37dcb831,c6badf34,85a3184d,b571fa59,55e3ed98,80fa8e63,270a80d8,ed085ced,f4dcac74,481a75b0,b42775bd,9a844a9e,e2de9be3,92781c96), +S(763ae8ea,212d756,ec3e6a55,9ea9575f,ee67ca83,9e61e61a,99315231,304eb9e8,4e1d3eb9,d1a49677,6d1619af,8acc9b35,c6135fd6,bf82845,5eb55a73,6137d0c0), +S(76ff82ef,27ad0b4c,157d0b24,d89aaed3,ea654fb5,e0492304,ab02b214,81eb7574,701384fe,e57f56cf,62930a9a,e1b5977,8071d8c1,c07746e1,b1b6e94b,1cece9e0), +S(fca9c2e,b84ac3d7,7a32396f,a0a1763f,7483aef7,2b171608,e34bf24f,2c0e3ba5,8678a539,d5b12652,78f2feff,bac321a4,ce2acaa3,d0983d29,27e9e90,1d46dede), +S(a75ffbd9,4ccc3e8c,93a54e06,e4b5fb2f,4410db28,b980283a,51ce071e,83572733,b0151288,ec977854,aaff4ae1,18b65289,ef356df5,1beabbd5,77054a42,da145fb9), +S(178095a7,416460bc,c42fd250,472e6d1e,3db37a73,5bdc0012,e52c4ca8,cf65d4bd,b9c37e8c,a7cce01c,9adeadd5,15759ece,60776e72,992b7c9a,c23b24a1,adde790c), +S(8969a958,1ebfb858,cac5b7f4,88c56e0a,966947d1,adaae934,6db4041f,4f8823a1,5c1ce169,fa336433,1aa72a02,e543cf69,9ebdbfae,2cc00ec0,f83d6f09,8e78fe3d), +S(a7e28d50,eb9a52e9,e18edd59,6b291fce,7024e915,e7ab8119,2cf4642f,7c54d8a8,e35bb3fb,d67ec191,b3a752f0,58428c1e,a92c2c8b,7e84223,363b15ce,28435dbf), +S(7a6542c5,2560ba89,ece8a01d,e9c9acb,e534ea36,48186e75,3bd214d4,cc8826b9,eb9a65b5,e5d3cfef,50f0876c,c9277014,af67ef01,b21fe8f7,13aa8661,f6be4c9d), +S(459ff50,f27af905,a415ed85,26564031,8e3a8b5f,11aa25b8,b0c27cbe,83448bf1,4d86fd56,e083330b,9053b2fc,88cf532d,7672912b,db7c2429,34c8be24,40be22a7), +S(e28b9feb,67173d65,78a8e38d,fdfa8a8,e71bb840,b1d97046,456a7aba,b1bdb4ae,9c8712b5,d2d7e596,d42e088b,801cf20b,7f6dba46,8438032b,c4b25d4,dfc5daf3), +S(3c313413,6261f337,e5b2b81a,6641acf3,4458c82b,524b88ab,844387a8,6acde303,c1948e72,3e2481f5,f0898fed,9c1def3f,8f88f0f1,b58cbc9c,69992a09,4fdf128e), +S(77774800,3a50c6fe,65a5772d,1e01b8be,d8acdfa7,da1cc233,ebe2620d,11b570cf,96522ec4,23bd6dbf,45969c79,15494f6f,bc4a41f8,b99dd400,b7f9b59b,8b45e279), +S(f491ac54,4678dc86,5ce81d7,60465bb3,791c9c38,a7f98016,3de914ab,4f488f23,9e62efde,f5eee54a,ab244604,a3357af2,729e8252,a04f006b,f0d61d7f,5f13437)}, +{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), +S(b1238187,25e216c6,631d4b98,d8d3c743,753529f2,8e02bf80,d1e9119a,f92d8b50,487f7171,60b8993f,a90edd77,3f7c1026,b5961881,895ad804,51b66d8b,d300e0f5), +S(b2ff5766,4b8079c6,3c5651d,e0b2fd47,80d1a18c,60d78c24,b2c57809,9429a552,c7ad3672,6d7e0618,eb506d65,c055a7ff,cba848f4,9b69dcc9,c02a85d1,5dd8ef90), +S(901272b2,bbabc0b6,12dba006,1d4e8ffb,e177c070,43f6ec6,2b437bff,9970685c,ad7c1fae,4b80cd30,c45516ca,e3433e8a,2d3272a5,79e4335c,22e452a1,845326a5), +S(1d5740ed,37452eb5,c645f8e3,cbc4969e,a6f419a,fc0e4662,8b017587,a6871ad0,c7a6436e,b66d164a,685a1b96,3387519f,b4179d38,40f2be68,28c9cd1f,8780bb86), +S(21f0eead,ca362d40,1abae7b9,2edccf19,70bd8c0c,35ffdc2,76820d7c,478ef1d5,d3073714,5d577587,db806eee,b9dc40ee,191f4b68,1c488f64,fee83a32,d1034ef6), +S(bebf44e,4cdbb310,16e0e43f,b183ebd7,263515cc,489fbce1,90cc104b,55225481,f7ace0d5,3dcdb783,e10513cf,2e6c5c63,c60efb67,fa0bc316,de0e571f,d399f519), +S(78f6920,e94f8d53,3dbcd31d,aaec5e94,76919efc,ddff1eea,4e79e1b4,3dfeb4f9,5696bc3c,c8dfd0c,490250c6,4263da19,36454cae,88f653c4,2f9004af,10eba182), +S(4a2d9099,949f854a,e13ef6d8,a0179957,a47fe355,92ed0ab5,b22994da,3e616e20,c922bf45,8feafa64,66e31c20,d99584b6,ab390f2e,5b97009b,5254d229,d2ea57e3), +S(762eb751,35672a8c,26fac373,af7c7396,70b8c0f3,336bc099,aa1f02a,7e804df1,edfa83d0,6cec4971,6cf3d1e7,fd2fcf3b,7e2143ff,8e67a5fa,c24f14da,b3ee01a2), +S(fa4621,897c70c6,8b62619f,c040d058,cc68275f,91b4efb7,b4f902ab,3059b822,8c1c575d,d6066045,9aa7908d,2246e846,103d887d,3b7549fc,b4ab9f6e,e1181a55), +S(6a61b260,3d77f92a,c4df3f3d,30000179,e6f0fa59,a6570233,1ccd0dad,6a146ed0,416c09fe,711b40d3,92723f10,688fbd1f,e30131ec,e8a0a547,9acaa8b2,ae8e335a), +S(8a80bd6d,316dbad9,41c345a2,6f3f7ed1,738934d3,f00efd65,edc54fbe,9d38d48e,82bf1bc2,468b4ffe,11561406,2a2f9ab4,71d40e72,a2f1a40c,8c573013,5a86228), +S(174daec7,77872ecf,46832a7a,ce3c1d5f,47304048,c9cf1248,124c2eca,3438a110,be42dc6f,b61964ad,59083c98,e459ea4,db3298f2,ea8c8379,be76859b,958b6f3c), +S(e11397da,68e78b89,c8f30102,f779e014,f572f9b3,a5d33ccc,b74c2234,ba9d294c,bff23953,fd62c1de,a4dcf767,924e5448,e6529bd3,85a1acdc,3efc0e8d,864fb9cc), +S(9f883f,27e68e8b,201d6ad5,28a04a8a,fce8b706,a4d6f2e4,5d07c4ab,8b0dd96f,965ecfd,1563f640,97f42529,305be630,12f9edcc,82ab67ac,9bee6979,b91ad5f3)}, +{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), +S(59d2d70a,2e90a652,54e06ceb,3793db1b,a78e9b4d,e043a3d,c5773b9e,4c200ea1,80d83c03,5aa47ae,956ded05,cab59b97,4f25c32d,9d6aeca1,32603249,b6d360b3), +S(4d9ba25,f51de6ac,3b63b60f,576354a3,40d89e09,51af3e9f,8d8eba83,c00160e0,218deea,f7a87a13,f7ca36ff,b4f85923,30ed0337,2665c688,e3632048,97dfdcb3), +S(41093dc4,cd6c91ff,67df50f,11031e3c,56d8e078,961e74f3,bf01b010,564e732b,b836ff47,2e29fdb9,c75a4a68,a3277d9d,d4568f0e,43333765,a7246fc1,69d6c074), +S(8a37aecf,7a111e82,21bd8aa4,756974e,adbfc33c,9bd6268b,247270e2,642c8abe,6a9cf7f,d48bd71f,d7f2dbf2,1564737a,2acff559,9aa3da27,925b6140,3e940bfd), +S(7b893836,b2777ef4,2e4a2add,c50bfe33,37f7c75b,f0acdb03,1829e372,129aa8b1,31b64a8e,fe772afc,eb8f631f,b3a4b39,39ca4a47,859a0fc8,59165c5e,d8fc0331), +S(2f493e24,6425e2b0,fa036211,5352d455,8357a2d5,b838ad4,232cf6e4,e4b7dc85,9cc11b9b,5c3a4da1,fdb1a119,aa5a546,47cf86f6,b5bea9f2,a9b6814d,6158fc63), +S(5622f09f,c50ac0eb,2a1fffc6,76604755,9d3a5046,54956aaa,640515e7,91000316,33e375db,350fc408,fff91c09,fd6ec673,4c12f5e4,46348864,b0586d8f,fd1205df), +S(fbe24d9d,29eead5b,72952323,df6e8b87,322d570c,37dd2191,690e9119,8a5b65c9,ca77d605,fa1c71bb,acc38061,f4b04768,e93ccbfd,dd626796,debaf531,6c17e89e), +S(1c324df0,4c5d8f9a,7cf6980f,7239d5dc,94f49053,5ef06925,6341ad0e,5099baaf,97611701,e282fde9,9263c30b,9439c244,b0fc4844,a61c905b,fc03d98,f81d025a), +S(f40508e2,4252b801,f4b34d4e,2941673f,be39a018,2d9e6b4a,e0fe3052,da22d16a,5477f0f3,f55f1571,8e070280,f3e5cc80,af79dc14,9954c40a,8c1aa63c,f1b52686), +S(fcd09f44,ebf12a38,8f12f1ac,1bcb6856,217030a,903dde22,5dd25986,2ada9b71,7d5fc263,6dec7d82,167f40a1,cf00cf9a,fb82a10c,a293c64e,8ff4b616,1f9f9d9a), +S(666675cc,1d4084e5,f4ac65ee,71fef1ea,66fb7b1b,f348d980,b11f711b,fbfa2517,93f65e6d,4038c57c,3e04a0ab,b3b1a45,4050098a,7199635a,ce8c8617,e14c6870), +S(8bacd663,9b1d1f4c,2038c96f,bfabb232,87aa6574,13b3b0ee,5aaac2cd,b8d629fc,50aef7a4,fdbf85bc,e0876914,ed1692f7,7f8854ea,a07022c0,46fe359c,e87284a8), +S(efa17098,da4d08cc,f879897b,ca2b4e3f,e19f1668,4428ae3,94a37f37,cb678d10,c43b0e05,584ee017,80956297,1c7602c8,3784c807,a88b6c51,7f25105e,d16596ae), +S(6c8eb955,497f33f,a1c0f1a9,a4f5017f,3f2613c3,3ab944b3,abee9171,d35f582,9e647007,dd811c9,bc1b907c,e1cc70a4,ae07722d,4dff6f06,d77f5937,9250d8)}, +{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), +S(d25026c,edd7663,2a256452,c6585ec2,e8c475f6,247f621c,c4438bde,b4a49ca3,4f8ab8c9,bf340f6d,c38a4830,3e114ac7,9406baaf,583533c3,bf6cc0d3,b529ed36), +S(7bb1335a,3340e2d2,ed2e88b0,5daf002e,6a903241,e142f9d4,e48d585c,a9cff8d3,eb65860e,c2a34d44,1f1677e3,f3cb2bb3,9d0761ee,200dcaac,68f683f8,7066bdc4), +S(809ab901,4a3ca64f,7dac499d,fbe84b51,6566f9b7,f504fd24,681fb9b0,be3a54a7,326d607f,e41037f1,bc1a4d56,4db58169,c637e902,99d52c37,d625862d,faeee076), +S(1fe79a30,e681a701,9c437773,1c99f7ad,b4b6a52e,289baf55,e67bc468,3a20b65f,b4843af,94698c22,ee928995,61418205,a745912f,3b0b11b8,b3a3cf5a,3008aa6d), +S(fb9ae54c,b674e5e9,ccb900f5,53d9cc06,949a6eb,76bcb6d,e7c8cf34,a6352936,3d2ecabc,841d29b0,b81ea46a,7b061c92,103c6036,5e9ce032,286243cb,91000b69), +S(d93164cf,ff3d386c,7d340da2,31479b7b,5167472d,a111e9bc,287be7e0,bbc06ceb,563ac770,b23ac56c,ba093d88,17e1a8a,47c9b607,eb773284,1c8b0c6d,f9cd9a9e), +S(3bc57534,178dcfb7,b80906b3,9db964,7e989039,1e13c2c9,f82d7b63,2a1b3367,5eb2254f,f7547cdd,745ca32f,e3ac49dc,2dadd808,558b7905,71a46132,d0293e09), +S(69c24add,b825c48a,ab10d0d8,36d2f4ff,79535742,f07bcff5,cfd568a2,ce28c8e4,a0465fd2,fd1f7924,e60a96f,472059e2,4df02324,7bc79e7,11f64d8d,a477dc06), +S(76d9304f,8dcde85e,9a331a6a,bc066d5b,72ce9fc3,a3e65614,37c376de,f6aea72c,6a31a164,af370f6d,2ba9729,fd2a7e5f,69d62729,bcecf340,48feb388,541e40d8), +S(f45517e4,13d15400,29e1bf03,aecbeded,9da08531,65a38956,79ca08ef,8d7c8011,7cb4b383,62f330f2,bc54d555,db060911,d7a0383,eda89b65,913cac4d,4098a1d1), +S(2e3b0113,818930dc,f9e6d0cb,d59032b5,e0aa1da8,1cd95f3c,1dfc8520,51135a12,22f9bbbc,e023e03b,d00f1c73,d2aeb9d6,96de61fa,47f5f6fa,31a5f269,b4029c5e), +S(11c85357,5073bac2,51a5f7e1,41aef0b2,8fa240fc,e8045f2a,e6fbe0b1,cf99d9da,ee8a317f,78545477,732e325b,4695f5de,b3bde843,11fb7fde,1a0e1cab,d8bc1c16), +S(f3cef221,8bfdda19,99885c8d,ee2e16a8,b53921e4,6045de20,94775856,9f2c84d8,a95ecfc8,e058dbe2,d57144ad,e65ac41b,b27cf4f,83150b13,f7f80878,81b98480), +S(b537bcd3,3bb129b1,db277096,afa2f42d,d63662cf,849a5c0e,f7438443,fd8d0e4c,76cf0b80,461e8984,bba8d8bb,f926ad96,6a7e9684,f09e4fbd,45657e65,d45ab69c), +S(4ca9dcbd,fc4ccc48,62c1b2ea,cb624698,40c3a0b3,95bbf084,9dfcc410,b89c3718,be50d6f0,845daab8,cb857c24,fa995624,dbf8c938,dbd982a4,85e66d4b,1db2c765)}, +{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), +S(d4e74c10,91365cde,4cf5168f,f4f523a4,1fe85d27,d50d2b8,76218259,10c3d5a2,ed9fd256,43ca55e9,53a209e7,5fd7e965,7706855f,d47d7053,ca9718dd,a834c691), +S(f992b772,821fc43e,61771037,acd07e54,96f61845,d5915056,5babc86f,11a766d9,8a8806f1,cf24eb13,e7b8cf1c,25d550b7,4aca323b,e3026382,e0dab78b,217a9f98), +S(1e9971ab,68dfe587,fe0f4612,ac8bc090,5c2daef8,616dfa6c,b7505e04,424f74c0,4e9c2118,6214b25e,6bca1e61,57ae70a2,5fcbddd4,7690acd0,e537110f,c08918b5), +S(ff3717b5,f433f50,9a4480c,80e6d115,c41767af,2fe6f0d8,679798dd,cebfa8b6,4e443023,e6bec3dd,f82b217b,d1c0c235,278d6fa7,8209e009,4c716c71,163ef474), +S(4dd0d667,f0d72439,b3d3adec,15bf05e8,129a1218,a8d7c645,307aefdc,616cbb0f,aa592262,93fc13e9,a11bf634,56d81d7f,fc503f33,3a523af5,1b1e9a9a,921a95ce), +S(c5475eac,51e02585,9916ff52,efac5c35,bf9b1b43,bd88e949,8807d772,f9e23b1c,2daa42ef,55198235,e8c4137a,d13bed86,d994fd1c,480ccbea,89c1c545,cc26fb27), +S(588d521f,6f9d2c44,e2ee47db,c05ea3fc,517d1d69,7c66a3a8,a62c72b8,645a6a87,24749bc7,3d997052,3eea9809,66701cd4,db072ff2,d9284255,e4f8c22a,afd75504), +S(d597241f,298a7b8,a1139b92,a8bde9b3,f91ea694,c450c808,e15df89a,feafe70e,5d17b691,ccb6cc27,79337e2c,8906b73,83876759,abf728af,c6889182,bf8301ef), +S(5d2d98db,c2d6a0f0,1cb8e201,516f65da,b43e704,78b0e5d7,deedde32,71614c03,c46181b4,d08d0555,7b031d3d,e5966ba3,6534c010,48875986,93584851,80ae7c53), +S(dceeb9b3,6e8e802d,f2ee9664,b3654b46,741ae546,6031162a,c83bb6da,98bae12,bf6e5152,53aeaf52,8ec5a0e1,de1f156,d64c9123,236178cd,ee9b2c3c,3e2710c2), +S(d4984e63,4d173439,e212d2e,2e8da9d0,d00d14f9,1c1d22ce,c37a537a,f3b0788d,c72c5356,63000ff1,9b17ebd4,be15230b,56528faf,c9622b2b,15e88318,4a5c359f), +S(13ccca15,767ae67,ad5a1b60,36bf0e3,e617d537,adc87238,be522265,b8fb813f,ac7d0ed8,2f30ba14,a4817fa0,9dcac107,3f3abde0,41da268b,c3bc9b61,38df6fce), +S(d891e13d,678ebe25,c129de51,7925ddea,c89ad77,4503bee0,d3be486b,2ed397,9a9b4d6b,62180606,9c6b5d9c,5f14701f,bbc8c436,9d148d40,dac50a58,4e87736b), +S(b6c1f018,2bcc65b2,be194313,9b2d61d4,20dbc415,becf5c44,356b3687,47c215c2,b7bae889,fab9f1a2,6050d82d,b983a6b8,c7edf242,69de609e,d963e0b,9230f79e), +S(853be70f,c6df02bf,271ad18a,6e94e277,53810df4,602276c,c5b0e9d6,2f55e587,bfef4966,5addf7bd,efe505b0,368be840,6fa2bcbf,316be956,53d2dbe8,c3db190c)}, +{S(d2fff4de,9ecfdbd2,dd99ebae,d038415b,19b6c44c,9717926c,9e9a668,3fdfd377,a7e8ef8b,89877e3c,cca566cc,7b7dd537,d157cab,121d1623,b6880567,ac66fa8b), +S(f88cac5b,7ef229e6,1a12c335,1603b853,4911e6e6,644dff0,16924cbe,53aa97f6,e853d434,c1dad0b5,4871e881,21673a90,71182684,12f3362c,e43486ff,61307196), +S(7e61ed71,5dde7b01,f1baabaf,bc1db38a,8074c3eb,ca665c4f,d70cf352,624d3d38,70bb8d04,ab22e016,1c5836dc,f08e2c3c,36ce3f67,f49e0a5b,99e21b5c,c6ed9069), +S(9df9045e,7deba246,11e8fe62,fb323077,dd495d3f,8ebbe4db,384baeeb,aa6b88fc,4d5f0bf9,f5cef832,aec0ae94,f204d1b5,18554378,440675da,8bb2d91a,8fcd5960), +S(5d134cde,d16d21c0,2bf962e,7f12f2d6,4e91586c,8070bfa2,61499edd,e00b2a57,b7b6bc8a,54e118e8,8cbdafc9,325fc6e9,125b46c3,66c85501,33561f0c,49c962be), +S(a565c3cd,2dfe5f28,4c98abad,82bd1a61,76bdbb7a,4ee51f80,29782d13,849f32e0,59ce572a,ff34600d,26ac0c17,4b5b508a,81e1a9f2,7f3ada66,44234439,63ea61a3), +S(8bb4eba,3d2b83f9,d6bdde6f,82253b2a,717cb133,f0a7512a,ddfbd29,c6b271ab,f0a0bcaf,14311a27,da09d57d,ce87ea6c,b2156be9,59982e18,5c92e64b,861f4ed1), +S(8b93bf92,a0f791b0,e60e4a33,8ecc5919,6fcb8f55,b7cd886f,cb71d66e,519333c8,77e26206,945f5dc6,ca3e3075,5834eb21,5c3111c1,4bc0b424,319d7d50,f42dbb8a), +S(b8a91ab4,eab1e465,e9ce0f05,b9cd5cc9,d7bd5ca0,29018129,7a2d2142,a3269d49,35eabe73,94dbc74c,e174be38,81b56b3c,d2ef6a16,4a7f92a3,17034917,239aa67c), +S(26f3e105,9bc8f39a,b56cbfce,cc7f8cfb,ead6cf57,ca4d6d4f,61653fbe,1934e2ba,7a970b03,a86755df,f2465be1,ba1634cb,dfad7486,ed7a8a57,b236ae0a,22993b3), +S(b1775563,68b77fe5,896d8eea,e8631dee,788d6b7d,b5fe84cf,66782308,3c0536c8,ed42a54e,36509460,ecaa422d,fade0836,8d96dfe7,ce4b0af2,fac64b84,a49c4a8), +S(7e8f9d20,9b9ae3e0,d8bcc4cd,8f678d77,b9ddde2,f85b811d,63558dc9,b82b4c2a,317ca8e7,697667a0,1d60345a,acc9eec1,57533739,683a3610,baee81d7,bbb2afe6), +S(ada7a37,a54998fc,ab666fcb,78189cba,f07ac132,d0ddb59e,26a959ed,2281689d,ca658fba,d7ef940e,61e0bd3e,41e04863,cfae0703,f997fe20,b6c4ff96,c1a6d53c), +S(93023c4,ec822347,55893d89,497ebce,c0a884ad,e93a5ee2,23514127,fefbd7e9,cbb91515,e8ce6330,55ab91df,96ec77e8,52a5ce34,f0fe3a08,315c30c8,660ec7c2), +S(f70d11bf,4b476ada,a3329b90,e5673313,2107c27a,da354d4f,53ca0913,117f3efc,38fe645c,7adb5944,cf396af1,3bcf69c9,f952f55a,57274f05,a88e5ba9,51b64064), +S(111c1a35,fab368ad,e90c5384,b0412268,a1a8f8d3,49662a83,4aa7c0d9,830a307c,bc8cf412,238469b5,7a316a27,1fe4ba42,f3fa6a62,efe1e12,54f20f61,8c0eead0)}, +{S(b3b5422f,1361ce5c,bf7cc061,3c78aa88,a02683ee,cddeaaf3,f5516cb,291632e0,1790cb50,cc2c760a,c7c2e97c,c44aff29,86c73be5,59a88180,8d036e7a,94347156), +S(a7087c6e,3cc50e11,5e42e86f,855fc0bb,8a0deae8,4c1f92ba,370152e7,69d7e73f,86a61264,c5ea922b,cf1dd751,b5296539,bc2c41b1,29d3881f,2affabe,51f6d1d3), +S(53ef19db,13d761c4,995bce5a,55365036,def1321f,e0b393b7,41b55b86,8ecc9ba7,7a7d9ef6,61ec075d,19e719ac,56f028bd,403609ef,ccc39881,189673ae,10ec05), +S(9ea51d5,4cec52d8,58f8c082,e4362b84,6a83e0f2,9c99df32,30c9a2d8,e5269818,41305f7f,a9535eae,fe7316d7,6ae49d92,47667649,5776c712,214b8fbd,f0c80cba), +S(9c0db1ac,fa10880f,d4da60e8,a8a7c6e,b4117f37,80394e83,fb591307,14dc6460,55b73b4e,80091775,1e680a18,6df01b67,cf0b38cc,e10bc0f4,dc98e0be,7b5c5a24), +S(9734eb47,f47f2b5,4edad15,791b890f,64794567,df7b4866,b8ccde2f,9890cc38,9bd277e7,7cecded5,9dfa120a,f6bf322a,910e972a,57543940,b74098fb,af5be122), +S(38aceb92,95b480d2,1ab23f0f,c2ffa615,ee4f6903,32aae091,596d0aec,a99e5efd,8a3c1050,4ca2b73e,c5249f9a,6edf0b67,65a8b02,4e8ee2d4,e90dd3a3,a8e3c4b7), +S(bc517f6,658a0f2,ec9bb49b,19573f9b,7c74a37c,c3f40c99,7c31db21,170fb0e8,b0dad7b6,18e1e061,902ad53e,a00d3cd2,e9a7821f,172caac3,3c1fc1ef,fbbd3c65), +S(6726e4bd,5ea071e7,43bdafd2,2fc7153f,49e36504,e8482db4,9d64f995,b8b073db,7cdfdb2a,6a42f050,841631d9,779802c7,3ccb6844,1ad48508,6598f6ac,f91533ab), +S(b586e330,a91d81ed,d9b972e3,d7a33c6a,b01019e5,6f809583,767370f9,2803be7d,8bea5cdc,619dd2b0,185a3242,1fa7dec3,662cda7a,9f1302d4,ffcdd31f,5959628a), +S(6a713584,e0d2fe01,64ab5ec1,f31f2798,fb85518d,7f91d512,d4380e11,3d3fd132,3a864153,4be74fa9,6bceb551,15d2b3f0,59fc61cd,54a046e8,d6216f2c,3cfe61d8), +S(2919d598,7a521f25,5dcdfb55,3e5a707f,696f3aae,47226585,248abd19,39519f38,bef08437,9a346d56,7c800354,e85aa596,6a0e2b03,91efb233,7d4a2df8,9d14e9bc), +S(78bd9c63,35fe26f8,68d85fd2,6ad879de,f582e074,fdf2b20,f6bde782,cced7a14,a5b6404c,cd6059af,2722b328,acc60b6,87759410,161c25c0,6866a6d6,89a26877), +S(fecdabd,1951afa1,406297f6,9ea98463,54e14a30,dec4e3de,8ee107ab,43f7e32c,d3095b1e,5d01e350,2a90289e,c508eab2,ee888bb9,fc72b16a,8625a42e,23ffec30), +S(e97f6e7,5ca07704,dca90e57,aaa27502,e1a1293e,d99e6126,d03c00f,53bad532,e07fe66d,9a2543df,5b618336,f75b0907,83c7d74c,d63d8914,22524339,1f598b91), +S(f7270282,7f520388,5412f3c7,9fdfc9ea,da219679,e78d089c,4c1117ce,d990c5e6,9711ff7b,4223c8b,f9aaed68,f70090b8,1f8163b6,7429ba7b,a59ac7de,ec2412a5)}, +{S(2e01d33a,c10caa03,ab514f75,46226f67,69a08f01,56017b64,a2436a34,447bfdbe,f5bd77a1,2c61f2ef,60a8c937,cf29e1e6,882b12c0,3e7a7763,f1ea498e,9207836), +S(7eab2720,b4dcdc09,8d85ef3,869bb07,9640ab46,2d6b186b,88f92426,ac563a0e,a8a15397,96e48dde,8137ce65,c55c6369,766b5df6,7dd0a6a0,6d4bdcda,a0c4c70c), +S(e6a98f52,eeb51268,91c4c6df,b6ae474,6cbcf21a,7352035e,6bb479d3,25a64de2,61c7b668,e144fb16,e72f06ff,71167211,6f6ec90,4c6ca901,61a71b16,f176e0e), +S(33cca5f8,bde4431e,40c3af09,2242f429,2dcb47ac,8b4954f7,3dd25dda,d572594e,5c23241d,46ad4994,1fc84c2a,9aa42bce,1ee4f3d1,cba680ee,8760cd37,e9924160), +S(e5daf317,a0024ea5,26bc1939,7a54d0e3,ff325e60,3ef6a0db,4ba1b366,e1f65c23,8d70ed47,6895c5ff,ec487a26,b7a3fb0d,73a32e8a,a4a80db0,ca00ac83,4371957e), +S(6131d574,7439ceac,e77bc0d0,b49981a8,4e3033e0,185b63b8,a6ea9dda,cb45e7ef,6e01f69,cbe2af0d,a1826d6c,ab34121d,6ab457fb,770f7450,c366010e,20dbee4a), +S(8a7a6e0c,5deeaa35,f13a9bd1,51c737ba,bbac2fc1,924318e5,8b71bb4a,87ececbe,92fdb178,b2834b39,7dfba6b,69e8ec68,e8db5368,546c54f4,a1ecec8f,e4e0c351), +S(585670f1,f244de6b,fa6c9b23,6f034fc9,47e7075a,59c7ddb7,f744e6d4,af423e9e,d337bcf,822decf2,3ebd7101,6b54dfe0,8dad6082,4a6307cb,f0ed140c,3bb14a59), +S(75a87820,7db72c1d,355cf92e,a74b3b78,fdc5c56b,88c698b3,7eb94e2c,f02d6dbd,88595a5e,e6444a98,3647cd80,cade49cc,92a764d8,f710ba67,63e012d6,b12e5d6f), +S(b6dd4054,943d57ab,3ec4897a,8f755e9b,42c3aec6,7860e182,804490e1,91b342a9,dc70eca6,9f7d62a5,8bdfbd97,dc0e2b83,18d1f890,97e8494d,9632e3db,c6168783), +S(fdd92a7f,566e855c,cc134e03,8b5eed94,39023e36,7985a077,875b150b,1663143,ee7b815b,19e1fea3,fbe2d687,b3611895,48407e6f,b4136865,cb2df984,fccd893a), +S(20734455,8b2ee591,756fa103,2859a08f,9218b547,ca7b67b7,266bf648,25209de6,b389f394,2c3edb68,468dc1e3,73ca3649,ee0f0bc3,78b8da6f,aee8f4c3,90867040), +S(1d29060b,7b0f6884,2ca58992,48e6dc57,f491248e,3851bdd9,80837ee4,a777f4e5,a3ec51c7,888554b4,1b21b6dc,da472271,8e5e70e5,8d7bb22c,b8045fe2,2a9ca251), +S(324ff1e6,4d1ef0bb,e5439a5,a3642ed1,f97b7ad6,dfeb6c7c,9af9400f,f414cca0,9810fef5,762b6517,5bb1469e,9ae69f94,68dbce8b,131a7e,6859461b,25581d94), +S(ee2e5e82,e7106cbf,47093a31,e88fdcca,5e00957c,1020f858,bcaeba82,f21c5b31,d75b0c29,e9360215,7a8d0359,991b5991,8bb17a64,6bc27e9d,4e5d2a27,3d4b43e5), +S(a2b27628,aae04348,72814af1,392c5872,1b787dce,6a78256f,3af5fb33,43fd9fd7,d2ac734b,639aa92e,40362fb6,42bd3de,9272c6de,81cd3c56,c802db25,1e20622e)}, +{S(934807e3,60b79e08,d1e28924,2478db59,331c171,6366f421,eda4417b,c0699286,f7f83c26,50e7a77e,2f760e68,7f475858,b2c2d770,195c199d,33a84324,e23f02ef), +S(73da18c8,9bfd61c,b2b6cf49,f776d53b,ff85de5f,796bd870,efd66099,a97ef7b6,fe5b0c10,1c109bf4,5112ec0c,205c1fdf,6feae62,e907c57a,c4c960be,22dffc8b), +S(19239b6e,d7dfedf2,6b926ff6,72905d85,1b0b39b,a20d0ac9,d24dff81,9aa44b0c,68108879,65ac0e8b,e19a9feb,70980400,fed7d280,a75f1990,65b911d6,39a734ab), +S(e03b6633,7b60f200,38d28ed4,1cbe30d,c84afc0f,1bcbb14d,40b73636,2ac08147,e3dcfe11,5065cd9f,f7ef8225,e9ee3685,fdc1c8e0,66306022,ca5aa599,977db560), +S(7f1744cb,eb8020db,13d21f53,81e7dfdf,b98624ac,ab4bfbb9,1dec9f5a,ef410ec8,fea6fc12,7ea0ebd1,bb3772c9,499bfde8,cec1cc40,e33b2e1f,a4fddf45,d03ce9ee), +S(b1d67d78,979a525,2093be3d,cf10125e,df13734a,eda07905,ad2fce0c,11015bc0,9d6872cf,b685ca9b,42e808c,8f854da,ed0c3939,40ccbd82,49856e84,ca2c9de6), +S(cc9c4e59,fdb57caf,bbdb63b2,f9c8d283,5d332666,96beecc,28d8c28b,2bbd4df6,a8aa77ce,fbdc1413,8d9889e3,55338948,82a8c56a,3c80516d,321d38ae,27c55ae), +S(c0a0db13,6f2dd096,412fec0f,6fb2652f,63346063,559525fc,1da8c67,12e1bc30,3b6257a4,13efda21,623c63f0,d78668d6,93dad095,8653942b,20b8bf3e,ecf8d542), +S(72abfdc9,eb47ad36,86fc6428,42d99247,d6331a5c,113f3f04,b5ada07c,dcf7b706,79cbfce7,65d63523,c7b02011,af3135b3,a67be602,c8e87754,53c45f6e,8538ba70), +S(85670d7,4dbf0d13,4c0ebe98,7f88972f,82fea44f,da5bee6e,8c865ba3,6010e45d,8a7b053e,f8336fb,a9e198c6,b8b7707c,20fa2224,a5d239a,7e40acc3,699d7bdc), +S(21c37875,d3577979,8693da88,85d2e0a0,5faee58d,ea74b21,782ad05c,7108f56a,30f8e75f,6f7caecb,ebf8353f,f06264dd,7b5638f7,fbe48e70,c76b0704,6ac2e3bc), +S(f73ef2db,94358b7a,ee9b7046,8a345c4a,94845bf8,daee156,f5fa9332,c9c2cb5,cdc5fde9,995563fc,612e8e6d,bcd21863,f8e83162,4d3a85b4,9a3d750,665c635), +S(72a27f5e,12944a7e,6406cbce,dd90c43a,bc6c1016,3fc0d325,f3dbac3a,156a2767,e09d85ec,963ebce6,26cd0f2f,16d882fe,488d7bd0,9888a2e5,ff05f570,86206a9f), +S(1e6f7788,61257d8f,ca81902b,394d9815,26f5a703,688c0636,a51853bd,85f05ead,a10cb6b5,e935cb46,cb1239a1,3d08c85,bb387812,9c21af4c,5781c345,f8a3ec5f), +S(ec27394b,44d9f24d,59384965,4c3d3662,a9a45cf9,cfa23557,9320c4bf,1e1dfc17,d28e9133,89c41173,89b8b665,b7ec1f7d,b2cfbb6c,9ff7363f,1f26948,517a12a2), +S(e27482fe,5e305f85,a4ecdc26,22f25c06,ac7f82d6,230b8c8e,4d8bff9a,8a78db10,e426cac3,b02eda3c,1b1f90e8,76f9770,29ed1623,62df1ae6,e68986ac,c346d7d1)}, +{S(accea070,aa6709bf,efd88be4,bef1d485,a0da83e7,ac9a1eb0,eda8387e,b9fe666b,93fc1c9d,fed8fff9,60ef750e,94dd2342,5fa08c3d,8eda3eee,7f51381,196080e3), +S(163e8e65,fb6e7ca8,585fc072,3750bf68,fea588de,5e713e7f,9538dbf1,1524dac8,1217686b,7ff2f144,88d5c121,df15026,b6757b8d,e72b1303,b830f516,4b4cf3c8), +S(7bc1be5d,358d6d0c,a42ebfa3,7d208024,d3b2451d,fa0dd7dd,d6c43159,76483b08,42dbc796,2228db1b,8268dfa0,2725fc82,5814a893,dbabd144,ec5a1cc0,fd8e31c3), +S(6fd5e39c,872cdd15,19df9822,6a0f84b9,a5cce99a,b72d3d54,27e24d24,d8b9655f,7969aad,162d6db9,973d2f9f,a1475ccf,39eddbe1,a205e28f,54594ed0,108136fb), +S(d65d659c,adf25d7d,6ce5fd2b,e8794007,6a4ef262,7284bc70,c4557021,4239e812,c1092daa,39ab1efe,480823f0,6038e5b0,35e1d2cc,1caa879e,1b7d057,8dcdd241), +S(754ebd39,5f6a7a88,b051016c,3631ab36,68733921,b9b95386,d924f6b7,aaac42df,95a20483,80e9a9ad,6b165cce,db441b6d,e439ef5,92802fb7,e314387a,94b2624d), +S(67340806,fe427a46,b9c3939,3dc5c7e6,680f5a3a,275c1008,408a2a11,ec43e2d8,ee7e2b49,b9e508a4,e7a3b6f4,72ec3a51,b4bca79b,897b08fa,e9ba77d2,90a0b4e8), +S(ef822b5a,2746c477,4f4089ef,a33f39e4,2e4e3675,69cb95c9,a6b75148,c0e76e86,9784c76c,6d35e6fc,aeb97de,6daf3401,4e594b81,c862e8f5,cd197e08,3a180888), +S(639bf346,fe9a3915,5a718e2c,c4191bba,4985c628,b5d504e2,de39a421,ae0b0415,d1bb783b,4bd96366,c4e9f82f,e6544bce,df39cbf,592a4aa4,7695182b,b632c443), +S(5de8f2dc,825fdea9,a0fe2aa9,a49b38a8,6f23e639,ee25668e,7445b607,df79ed02,a1a17c29,df23dc19,c013c05a,25094dfe,984591fc,a825aa3,577dae9d,6bb1c513), +S(467a55e3,c7f904b6,308f943c,fbf1c9c6,c8489622,9533bd31,5b008c0c,df5c6e5c,59c10ba7,ddaa2005,a169a884,6f5bdc83,633d260b,762a6bab,2cc8d9bb,401d0ca2), +S(6064e78,170d3667,b0226c1e,628c25bf,3fd01939,132f6fff,bec47896,9cef1880,d74e855,68d86986,f8850360,e74faa47,697a7ba9,9d7cf241,fd131af3,e90b0daf), +S(8dd19520,5cacd63f,7586954d,3f1cf4d2,25303baa,a56bfab4,c25fa9a0,63621dff,e772ecc0,dfa4fc98,9b6ac1e8,4a96e4dd,f1cf84ee,37e0a2c5,126f3dc5,6b8bc142), +S(178ca7d8,807067b9,253ce61a,cf0b49d7,1f973fec,62bbaf65,1af01974,c102ad33,293ae890,98cd4157,db11f6bf,c46414c5,47e152a4,e5276433,6d3a4ab,f9f2c798), +S(49fd915f,42daf79a,648d30de,c913616d,46e89e11,afb9d46f,b18aea34,e4203d2e,c94be4d0,e2ccb36c,c306aad0,940f23d5,20c2a29a,4588a78e,c4a8d792,2d96bf9c), +S(a76cdbb6,1982ae31,8b5d3be4,eb03cefc,8958abbf,578bc99c,5081bb2d,ecca6328,8f0ad9de,7d0a36e1,e27e5bb2,9510734c,509c5f60,c905982f,23865986,784134d7)}, +{S(a488f83,2bf3e57b,5225f748,754ba2b5,cd9657c7,175198ae,122c3d1c,ee336ef2,4e326d40,648cf269,2db42532,55391fca,5c2b48d7,44a9e39f,bd1293dc,827e9021), +S(c2e4a4bb,4cc75a7c,4e5fdae1,3b6910ec,7056bfe4,5c0ab7d1,2146bd69,5a7eaeb3,72b2d74b,6181bedf,4bff36d5,e1162304,65ad711e,c13c099,1dbf2b43,c567a603), +S(9e95d628,c5278b1c,56863ad9,e595739e,8cf36103,75e29168,5a5654ba,562292d5,8abdc7c0,8a472f49,4279be90,6d575b7d,17fbbfe2,47d97022,533fbdd7,1d4ff8e4), +S(76fa079a,2b9a0dc9,3a12d28e,cbede965,e33afdf6,ed28f3c7,c7d5295e,6b26943c,cdd558,61e9b7f6,ba779158,65b37c6,ef665077,9344f7ee,6e8d4b3,ae658c96), +S(a0269bcc,a3d91987,737ae43f,2d1b99d1,18a139b2,5d5b4ba9,cab55c62,66e4cc78,6febb984,7682c796,faf098b7,60c5ab58,b1688f3,49abaf25,3456c3cf,d60fd361), +S(f197660b,f5d0e191,d2a75f95,4230ad48,4e28027,f5e61d49,64f02fd2,b239b18c,cd05cec7,3eecdbd8,fd186f5e,73d121d8,2ae2df03,29bd7e44,408bf7f8,5b3009e9), +S(584dacb5,735c38ab,366ebb74,8ecba797,5be0576b,a52eeec8,c6fc353f,17d783ca,198e2b4,5d1e6ee2,888581c6,5dda9b44,a2441d09,4945deaf,77232861,4d6f0c98), +S(eb6d53e9,4f34c551,9fc21d83,f2092221,457e9697,9e535980,31c5a853,615637e6,b958d521,d74b297f,6e537d1a,9512c5bf,74a3a134,b2354d21,b24b30c3,1eb0e607), +S(d32c2816,b28e0bcf,d477c631,7ca9cea7,51c3d7a2,a4d2aa70,b6ea5568,63581e21,7e42e895,c6cc4eab,c85b2bdf,301e37ed,359ac182,ee1d6843,a3c1c7f7,d253cd0c), +S(bab8ec85,d297ac61,8aeca643,d3e54750,5974d165,4a2031d9,3fe2a865,7efaa8ca,f4544105,4f81f7e9,1a8c773c,369689ff,ee5b286a,ea652d22,7812c8b0,57ffd710), +S(7d75e064,5542097c,d70982b2,92697b2f,c3439a6a,26f1d51a,15766ba0,10c80b5b,9868b21d,2fd0340b,712b2958,ab4925ad,d22eae92,1ca2015,5b578d05,14019501), +S(4885a359,cbdb926b,3d2918e7,a7bfc8a7,ca9c6a8f,870824aa,fc2911c2,be3be588,7cfa2021,bc9eba8,27729709,ba83cd2b,d6c1d68b,2217dd07,c7af1977,35ce7206), +S(52c4990,8a3b1b8b,3eb084f5,33f5f559,e9113d53,8d753027,3b1f9bb5,d0fd03ec,adf0c562,21176de9,b5d54273,97feec53,735f430c,44082b1d,7233ad36,472815bb), +S(b07e4e7d,366026b1,e4487f0c,3a2d6825,909f526d,dfeae840,334fbcb7,b1681beb,26d3eb64,c795a304,f226b341,d49adab8,4b427557,1f683268,140853fb,dbf65459), +S(41d028a6,260d5c21,f3d31771,eb876c10,189c367a,b513b761,2530e974,6ef3b4b1,f8b295c4,a2d2d5cf,1be8fb36,9d2472bf,85263bcd,3a36a42d,705d2555,1a501791), +S(da36f37,ba62c357,1fff8b97,39d77d44,13ff457d,5933e77d,e4dc3d18,7bc601cd,ec0e35b6,6d1ef946,7f59d7bb,534beb75,13f8d2e5,1919d914,f10a7778,4d4abbd1)}, +{S(a473de46,a554667a,368fd573,168dea23,3f81153d,e1b35b26,90da8863,71e6c131,4ba0b462,92aed936,7a2bf9e9,de48a08a,874fd681,aef86a15,58b49e4f,13dbbcec), +S(ec3a1d66,a1f76399,c683837b,7b53e05c,5df3ffbe,325d3d4f,de12cb19,c44a8fc1,73392723,41f63fcc,d994c0af,d1459f82,c5479fc8,1628b8a,34b4d042,e68a23cc), +S(8de418b2,77aa4dcc,11619e6e,f76d6a5d,8ae48448,c6dedccc,f32b7238,b58a2e55,11e44fa8,68811549,8a7cf95b,91eb8c53,7119ef6c,3b9fd2d,37f428ce,94060ea5), +S(eaef8564,efa35058,1ffc48eb,329fe037,60b85bf7,864a433e,70b5e227,9282fd9d,90eeb6b4,c3252fa0,ae0ff9c4,ab2974ec,12cd8b43,8af9a0ad,64b8b3c,e404d35c), +S(6985a408,1a00ef94,ac404379,dbda4471,eb99bb45,69c90da3,241743c1,afa865e6,2485252,3273c205,8321276e,1cc4af69,380642d,3e2ec299,64da2d75,b17f3865), +S(df779625,ea469eae,1463fa21,b088cc70,6ac9d3e0,9c4ad69d,554222b7,7a2bdc0e,56e00902,4defe4e0,5f097ebf,ae0c4782,a93500db,bffdd525,8ab8ecd3,1253f224), +S(1a2d4b3f,29fec403,5b3cb811,147d66bc,70fcc480,4f07bc3,169b592,e4622665,600cc9e2,370d498d,d4db60ee,963c5dab,8da8a23e,8db3cb01,d805ac2a,d77ddb46), +S(2d8e71b5,17971a2e,351221d9,44e82447,e913772,216a4c40,f067087d,4106aa7d,d9284393,ad9a63f1,2e0981d7,aa9107de,21a91a16,ba43a25d,26895b4c,d793d525), +S(b53f44cf,a4f24aa5,a57aadf9,cfc0ee9c,d621d482,3a7046d2,8058f086,cdc91b1,8148f9da,95142591,dc71b505,ee60dab6,a680d0c4,1ddd1fcd,d59aaa3d,dd4a901d), +S(f31db738,2a3f41d8,d4079efb,cff1e3e1,e818b2d4,f83dca09,4a044a73,d64a7452,8eae5b98,cb9e9dd7,2a9332a5,5abb49f8,9bcd4b0a,d8f6913c,e6c1cafe,294ffc87), +S(7ce5ec00,ff2a3001,9eced47,3a891bfd,f2c2a9a1,8fd7e18e,3999ad19,b60d42bd,c514419e,272c3380,a7ce5dc,1883e7cb,2df64c89,5f2a730f,cde2f3c4,945b6ff7), +S(57ea4789,f7e02c29,7a089cff,9ae71fcd,f511cbc,926b9299,25a1e184,c6157c5e,c696731a,51132560,c77afd16,15cd5072,4cf0d136,7c4fa3ca,b19aec05,a8d701fd), +S(5cba3f4e,8aab710d,878697ef,9a1ae299,821960fc,caf88887,9c6f38db,4be1dbe0,336cd748,99412e3f,9ca14d01,2cebcce3,42ee9e97,638cdf3f,df5c0077,8d3e37b6), +S(56b0894,7d551fe1,2e9ab57e,a70d342e,3cb74d74,f549edc3,f7551eef,ca9f9fc0,e7ac85d2,a4baa20c,4e1bab03,7190490b,e3574ad1,f9cbc392,f28f45cf,db4dd2e1), +S(7ca03c7f,ab7f76a5,a258365e,55473083,5a9850af,6c83c311,b487a8c0,4ba87a28,1d144504,193db309,170a3ca7,36b39bf,46d08596,552a2962,6a3c40b0,a8f95e4), +S(5d041b98,b864a305,117791ec,21de3fbb,cbe58a84,8429d291,bad63895,442c9fb,46a179d0,decc9e6c,9b642c1,5fa126be,619872f,17c6273d,30e2ecb1,1d3c0252)}, +{S(476d7ba4,35177a71,299267f4,14ef275d,48b434e1,380c1afd,9fac4606,f8e02be0,7f1255fa,57a60447,c14d6574,1d7774b9,695e6d25,1b46912d,d33c77f3,f756edc2), +S(c68ac953,985c624e,dbbefae0,148f049b,c9de0f23,7b192e7b,e8f13921,dc478295,77efcfbf,a08be5c4,632cae8,c7e9e6a,520ddc19,dbc1271f,ad0070d8,366dfae1), +S(31462a8,ae0be4c9,b3d7a28f,3fe28e1b,994961a5,80cdb3ce,4ced5b5b,20077b77,3137a2d3,5303daf6,441b0ecd,244ee32c,1c87dcf4,27449c65,d3cd9bc2,6189db3a), +S(d78f7afe,6bcb8574,27dd87fd,3869e74a,760045d8,1841a895,f8e78697,189ab251,8e419b36,47160117,af77b5c7,97e6d695,65ac587d,ce16b94f,c11ae91,72b8eca8), +S(827f5436,f983e162,42213577,76403af3,d700ac7e,57e10ee,53985649,19922086,9f64f7aa,ff4c6234,5ef6017f,e027dbd6,26592cc4,f050ff48,ca4c8fc7,5ce87356), +S(6ba0ce5c,6893ee03,629f90e7,841790f0,414410f,8526e56a,b0f74f24,f5c2fefa,25d44a39,961099ef,b341c985,d1f7604f,298838ef,422ccd0a,91195f2,2b48e7d7), +S(2c43c784,bbbcdc5f,34789f99,46a9a5,59be71bd,3fde6f66,b6faf050,99b4dcec,4e5fdc4c,83eed83c,db5b5030,91bdeac6,a70cd8e1,ed187ae4,469b9057,18fa5386), +S(4faafbdb,1806f138,a265e889,db4bfeb7,ab53b2c9,622ed6b4,c6b392d3,1f7ccf07,d1843334,387f73c2,da122ba6,a633fc2,26fa3f70,e42d41a4,561e111e,aed5b357), +S(143b5028,c0bee52f,9dc11734,292d62b,17672d64,559ed0c7,49e02f20,8bf84bfe,887d583f,b7d6c57e,c1c58895,aa99ea4,7ff5406e,fc5e15eb,3d8db3a6,e8cbd4b1), +S(394ff209,a9586a19,396143ec,f8ab1785,a661b80d,8d2d9b28,c66c372b,add96e03,5ce203f6,801bd8b,92a673b5,486f8f03,8bebbcb,bea85bd6,7cab24ea,92a54895), +S(3e2670a7,794a06f4,2928430a,8bce2866,eebb6e38,90fdbc94,6b2c794,d32f0452,31d2e49e,9a6ce422,36bebb25,cb243965,6aa2a1fa,6712f17e,6d5d2b58,ae91c3b8), +S(c4cb5059,31eb4fb6,66fab44b,6e063435,35699e3f,8c3d4957,b971a271,78430a1e,9fb4a0e3,8d46c234,eba2ecc3,8628150f,41cbbde0,734453f7,c65f2444,c52a9565), +S(695d0e52,b32cf29d,2230b84,c1260595,8470dfe0,713aa116,61710c,8ce74e91,f4ade5d1,6d27de08,78d907aa,34b61f91,4135227e,97f0979,f4ff6241,4164ab5), +S(5aed2254,27ae4f7a,92292498,a345b20,49b00c0b,284d55dd,51e6cc82,154a4cbd,6da49cd4,5a48b051,f20987d5,415d58b1,9a4e1744,d83a5ff7,6bd95cec,1c6dbb11), +S(390aa9f6,18e5660,cd158531,7d0e01e5,5e6fb9d2,aa785533,6747eb80,caad2bb,bd7e8ccf,34e718ca,947500ca,a2d7e3e9,3cb0c6f7,d8b7c50c,7aeede81,95d0271a), +S(41ff7ecf,227a0f62,236265b,1bd5649b,96666154,115a2840,c37be05b,776c85d5,fa47dd69,a1d89724,f8801024,dbb52b83,d162f2e8,b8614224,4744afa3,530aa1c5)}, +{S(4f62ab4c,b7fb0d13,12620121,9841e932,b0de312d,674cd002,315594e9,81dfb3a1,1145fdd8,c5d16653,a9129b0c,39fcbbd9,5968d22c,ff2127bf,91e89847,35e2834f), +S(99813c3c,dfbda83c,a798f7df,5ea4f172,3de535e8,2f257577,de67250c,6e11370e,38bdd34b,18bd081c,83307a5c,fea76990,11a50437,ff93fc6d,aa22f9fc,d5021226), +S(75771c9b,9b6e8b88,cedcf4f4,3772b3c2,45f72319,7544d57,c6c920cc,137aad40,d8867e96,7b79997,c0526603,a2a6c201,18d93115,4362d804,1542e3d2,51a8759f), +S(fbc16489,7bebf96b,ca01a281,f2ca36c5,dbe51bd4,1a465b43,3311e163,16bbc85b,7959724,16729f2d,9ade6f1d,97157761,a81baac3,fff31e85,13b9989f,12f72175), +S(2d625707,d2c68919,8ad1b321,d60f6ba0,5e106abd,41bfe029,cbc60bb5,d5e0ddc4,5b3e78b2,a007c909,3722440a,d40c2ea3,6f71717b,c5822eef,322a13ad,614ba310), +S(cf23f492,64ab8e60,afd8c0d3,a8a6e938,fb6a3b06,66b9abed,23b6cb45,d5b33a78,479d121c,571eb9c0,e24c14eb,b3be4816,1363d752,fba522ef,a010ee7c,324be8ca), +S(c2f0f458,e56f387c,a92c2def,f02c3e44,dcc010e8,c2b7917c,751121e1,3e49df7a,d2bdb0a0,f56b97a0,ffd8664,1b34a1f,24ba9123,d089b256,6a50126b,90dfd936), +S(4bbfdb7c,8b393fa4,bdffb5d6,cfdf0721,d17e03d5,ff142b34,a0741039,4c84bed6,c115eef5,b815b3b0,c2f2ec4d,98b6a09c,36d8a320,2f81e777,eeea800c,662441ed), +S(49868964,9201341d,bb24a12d,ac0cd8cb,d973640f,19f13540,dcc9d21,d67a7d76,3bcc0077,5c6c7256,fe0e1d3c,a812ce2a,c16294a9,7b9ac6bb,32f796c1,3a2b50f8), +S(a1e22bff,d0567bc4,f0261a3a,db9c918b,a7d81791,d68e99f7,f8247ab1,1fa7591,9d1c7ff0,db87b176,5e284432,11299012,94ce44eb,31a4d6bb,49fc3cc6,d4735aaa), +S(2ad5fc7b,610a3ddc,e4950765,a86b12,e1f5e0af,89da287f,c930c035,b81fbbd0,9fbb7378,36c20ee5,bd5c081f,5588f57b,4fff0b1c,71a9f334,cff1df26,60085c82), +S(fb4dde8b,40a51684,ee59627,d5adba43,50d2ad89,3b0f4aac,6f7a9900,22b0fa1c,753d7603,674cd3cf,46ef3a5c,e19f0d8c,3be64921,6a581cb8,6dc62674,abfb221), +S(f36e438e,9180c9a7,19679a88,51f96690,6dc096ae,4a86e60a,a2a72bd1,b06ddcfb,3fd68d3b,64d890f4,aa653b0c,5a670273,a53409e9,242f0ccf,fb7ea68c,c91a553b), +S(7ff1d3bb,8de59536,19b5fa0c,9519cecd,fa121bde,ff31a689,65c18c42,d182e4f7,2953d0d,7b0d215d,f75955d2,97a8ce92,4b0f6ce2,726b29c4,2b7a2786,a459c551), +S(9385aa58,1de6a3c5,4b479bc5,8823f699,e65da4df,bfb277d4,b56b76e7,c41ee4f5,95d109c0,5e67ff73,2ef10f46,350a7578,f7aca034,962a573c,707b3977,97af5c72), +S(4f3891ae,e86c16d7,73237e7c,d2db7c7b,7ba260a0,4b85f6dd,91e2443c,bd21c831,a96dbd49,371bb1f4,9ed1dc90,17927def,30810e2e,b938de57,ab5665b,8de5e86f)}, +{S(110f05a7,489138c6,51e48771,d505c7ce,68bd6e61,67cf4c3,3933441f,a236f263,761652d,178d0d5c,f6189501,d02d7078,2f10f835,27894d79,4f93dff6,e90a3b16), +S(928df081,cd85c375,e53e825d,4a250160,a1a893f7,95e0a9b8,5378942d,e206a1f8,1f86b51c,49582064,f21e9673,3786eff1,dab4e713,69273cbb,9dfb3d7c,2d930fa2), +S(ed504706,702b297c,e62c2788,54a29419,e7e0f76d,d6eb602,e0defae2,8f74882b,67f3801f,31e2c8f8,5c3e409b,b104323d,ee41c794,802dbafe,ba832409,4efd3486), +S(d620c03f,dad08f0a,a67287d6,7b68e8ff,57d8fd09,2ecc0731,a236db54,83d897b6,f2a66048,6520abff,aa6cab39,b90c1d3d,89ac4738,fe560114,94117a73,60f30a41), +S(fe57b1d3,b1b33889,148509af,29a3c797,3bc726d2,593b14b,1118580e,6b8fc04e,d69026bd,820418aa,74e6c115,b2bed0b,d4f48cf,f1022367,230679e9,7d878547), +S(1de846e8,8e3bf169,465b4d66,6c0cc230,36c0bf12,b35ac6ca,5dd59935,59c11063,d925394c,c8eac4bc,31a49318,1821560b,bbe38d67,ea0040a9,42a1747,defb69da), +S(7a4dd28e,3ccf40d8,7ab743fb,6011acd3,981e4322,486d38c,6b6bd69c,368e9391,89e0dc28,680ddf3b,1a6ee4f7,b2b5a0a4,c417a9ca,4cdbaaf0,b08b4de2,e2653010), +S(593296c8,840e55ee,f7477ce0,e9d5747b,ce2a24f,e5e518a6,7813da6b,347fbd26,7ea971f6,37522c0,f0bfebab,17fef91b,8216ed49,1a0ec5d6,55f12062,6344c124), +S(b784949b,4228eeb8,b8e9979e,fd7309d0,3e5e3a2e,e658b017,86b664e6,db7afe2d,7f836c1a,3f93744d,e4f0563,456e3f36,56b536c3,1e8e7b39,5c0bc78d,9864910e), +S(2298a36f,6e66645,5ef8ac54,a3564c12,59b2ebcf,3a1dc1c6,8f290f78,fa366974,da9db0a6,26701765,293d39b7,1600c991,effb9ab9,2bf6f95b,a65f6b2e,9c3477b1), +S(253bd683,f5421bc3,4bfeca7b,5b48e6e6,d1db6398,983b451d,6f327288,513516b4,61b02eb9,b3d32555,9692df42,b4ce3267,297aa78b,7ac94afd,c08c3534,3346f8c8), +S(cd328c8f,5aa7ced4,d0b0744,39be20d9,f44924b9,c84fdee2,8363fc9c,1cfc80b3,9b0dcad6,5365b7bb,822c2c73,30105fe1,907e674f,9f11b13d,63385bba,b3278d3f), +S(29c6e1ce,3f8caa9c,d366a0e2,3b86fc16,986c3d12,7c391b2c,aee4ff5b,5c229a7a,dbd8686a,e8f95d99,cd7f133c,3211620a,b02d341d,2a50d04,e27a2430,de9f8371), +S(c2a3ace5,382bdf5d,a5dc3c5,9994d92,88efd495,32a3f0b4,a129cb69,a77fdfc1,d79b9211,55651adf,bacb249a,42ad5059,9bf0eb15,1d8b91a5,f6033c13,73db0480), +S(778c13f2,1cf131b2,86bbe8d6,9c4913bc,a0932939,a79a9446,a8c908e8,bfc396d8,963bd25e,461b56af,990fef90,5af101a3,a96299d9,44ffb8a5,e6c59359,a4d0129c), +S(c65a9cd,15f3b7f4,c0f668e8,53227b2e,4ac01865,37c58514,165b6bac,93e43112,ae0f8b04,1d5dc2d0,7a8688e5,ffc70da8,e7d5b4aa,92faa455,64fe31db,2d24929d)}, +{S(81f4223,6a39a14e,d2764665,22edb719,f2fb72b2,c571ed67,343e2c57,4fb60e5b,34f10ee5,6c1d5e02,51e8ba8c,9f129391,521f0601,2ebb4549,7377967a,d8347e4b), +S(bc6f8e27,8bc0f3f8,6bce4dc9,8ed98476,b4d7427c,3e3f3a79,f488d8bc,3f11313a,5a54bc1d,4b08aefd,53d16afc,79b5065,b637c0e3,d74dd46,62728307,ff6c7611), +S(259905bc,501d58da,72ff446a,315b9f75,89df7c14,4d9cc937,bd962d74,12ac343a,3c233cbc,a1660e91,fd41cce4,674386a5,d949ddff,2477cbb3,737e03f3,3adf25b), +S(5051c982,aa4a5d22,d8c4f57,42130c23,4665bcb3,4cfe0567,dfaf3e4f,a03d9721,9413cf4b,50784ad6,1afd8a6b,8ce23ae4,80480b86,6c08ac48,24379d57,8a4062d0), +S(c0158ef9,e70349fe,2d32c1ed,30c87c8,90de8ceb,46ede75b,2addba8,de2b26b,b462c3ff,b14bd8ba,c167709b,dcae0d46,a908fe55,2789e2ce,c5e43d62,b71aab70), +S(740d9568,b420a2dd,389b3fc8,67065e00,10eb2961,56eb6774,15755b4b,5e277ebd,eec4d9bf,693994b5,13ef673,987ec7f7,2d2c767e,9b41cfd7,858aacc7,edda7aaa), +S(ff333278,480b444e,99b65b7d,926675ec,6b16a64e,dffa2b75,9c5410d6,5fba02ee,1d0f842,e584e31a,480c8202,1824936e,e2f717e3,df72412b,155dd2b3,fb1aeb4b), +S(79b0a263,dd3a2b33,31d1369f,8e94cc7f,aa9b8364,2918f9cd,aad62d9f,7a5cbffb,225dec00,4437c7c2,2055851e,1c4968b3,f699dfc5,846c373a,13bec08f,5cc3890d), +S(2a12e289,7cc085d6,30996a53,cd9b0e64,4dcba64c,7a9c4a5d,c4affde5,42717d25,2b8e848a,43566c29,fc5242e0,4892cf58,1afb0667,9bb15b87,69252962,637e00f2), +S(dbf0d2c6,29bb1f42,10cfd3e7,2d119391,16d23a94,fe0c2828,9140a498,1cdd0749,54594d41,8b87961e,b6486d09,f717471b,13f4d39b,1b82484d,8463a4e7,b28ba974), +S(2a1eeaef,b3478200,de3fea29,c1368d22,ba52fed7,1175ec88,4325833a,e93ec8da,1220e686,97e0347e,d0117f98,ce8929ed,eac74f0b,2fecab82,11bc5eaa,638742ed), +S(8ecd4b9c,beaddc70,f20c09cd,67314d2a,3cf3c115,44cd3508,e74050ed,16e9f34e,52ddfd1,795af7cf,9f083a22,35c15084,87bfbf79,4e3af1f7,2183790e,a27b73c), +S(82ae9584,b592fdba,88ab48c,ceb9ff2e,b95f09be,29ad4700,104bf18e,bbf3e036,ac06c9c9,4d3f79c8,8ab2313f,dd507808,36cfa91b,f65c06d,76b547b1,24067fb0), +S(c3b19b24,35c6c07e,4d3254d2,1e0a30bb,21c2f45f,68a441e6,925c3ffd,72b230a,3bdd5ded,600a0c77,3c620ed1,d9545662,af5f3ec,b3b0763,6022a466,866aec3f), +S(49622f79,9672c94a,26f86edd,22e9e5aa,b8ad1a62,33abddc9,fbbabbb3,3fe276be,c114c6bd,f30f79c4,194100da,847518c4,f5688a3b,70dd60b6,c4f765a1,cd324d6), +S(c07b88f5,cd465622,2fdf8cfc,c7191c4e,a3dd6d18,21adf780,63d62d31,2b9e02d,e601c411,839e2371,8136fd1e,e5adf8b7,c5e59969,35bb152e,955d2ffd,58964059)}, +{S(2dc8f27b,b3bdcaa9,2feace80,f2f6212f,8209477e,531e74cb,f497372e,9a2f2263,7feb63a7,96b55bee,ffa180ba,fef47776,fc4fabd4,2ccdcd97,64b4bab3,10350790), +S(ac8dc04c,1c1b8c7e,abad287f,a1f62206,f307ee19,4ba04fb2,fdc0a908,98a13387,a06c53ed,5fce8db2,a52ccbde,38121da,fea83bcc,96482765,26522b5e,d762b0ae), +S(20c34368,618099a3,d6713278,7f2b5c9f,3aa0d419,40329291,3c97237d,b44c9072,e1d3f30b,8c4f9d31,df2dbcc,435a0bd9,e4ab9342,7df8f04,90c820d7,dd620444), +S(dfa3550d,49bee1f9,304f5bd2,5deb92ce,b1e5d49a,4e3535eb,5b55d429,e133d559,1ddc87e2,b3cad5aa,922391d2,b9bb11bf,a3db93cc,244dcebe,147eaaf7,610caeaf), +S(40510142,20037393,7df28434,48899fe7,2f6469a2,1d77e591,d77d2a16,b3cd9aa8,588afafd,85ed985d,ab38fee9,306ef133,ecb087cd,30ac939a,ff13e1ef,a0b658fa), +S(120068a2,65e77949,5450c83,c6ec07e1,b6825840,ca7a00af,6ecc6d3d,9590e73a,e2eff01b,d4aa986e,dec9248e,f69d747f,65dfa98d,537d5443,c1e7d9be,317d371f), +S(52a1135,9611cb35,6b71c05e,c0376ea4,27c9938f,1191cf3b,dc7d17de,9c29b39d,6299f3f3,2f0bb14b,f1c94b36,88fcc301,cc25c90d,def2f2b8,7b0d0050,193c987f), +S(23000a37,c68fb1f,4ab535a2,db033b76,10f252c5,7de5c03a,47502282,1200ea26,3ac23fb1,f0a42714,829cf914,ffada79f,234e1e5a,dacffd5d,34d3ca52,976c934d), +S(810aaf67,f149fb01,a64e25e6,55888a74,f6eea8b3,c5e96fa0,9fd9c689,3e7543bb,abfe36e6,3418a26e,7a19f2ae,aee72cba,416880a1,770e2bfa,79eeff32,35885e82), +S(cdc0b689,5afbdb4,f1c9521e,280cfbad,7b543619,b8d77c2a,20fdfcc4,66129e45,9d59f91f,bc3894f6,820fda03,ae13748b,572f9a2,d06dc312,4f824831,778d62ff), +S(1bf8e290,19706636,e5d2c34a,39de3f02,331460ed,916c17fe,8e36d097,9a5edcac,e15e619c,f4f096db,1ed1d51,ea5208eb,41625ee,6546f40e,324b754d,e0e202c5), +S(e54a04cd,f5893d80,1a1cc8f6,9dae01e5,34b92457,ab7319a2,4d2b6c2,78f57f76,8103dd9,b4a89691,b079aad5,71267e5a,f601dc04,858f065e,aeed5e92,34dffc0e), +S(711f6808,53d18d8b,911e2342,a301a805,a1c76c2b,b5987775,f5867df,e2325d00,91630ab,cdeca550,a32e9df2,30f02e64,983eeb89,396487d6,4b3c9d59,8350ca01), +S(765b24fb,d42d4d4,a9dec609,48ce7f91,7c3eee70,49a36373,9e44297e,3cced026,56408d2f,d859a211,26d14e77,81302eeb,87371c17,b1f9bf50,9e15f545,c240b79c), +S(b68f07de,6b13a7ce,739a7e9a,1c6a526e,d1df5cda,b7fad149,df46ace,3acc9919,5da1b851,a81fe645,47ef84a8,fe9a39ce,fcdc9abc,a3e95818,b34860f7,f54230bb), +S(d98bcef6,cb3e4a1f,5b9ff8c9,8ef7138d,ba98e80c,200113da,e7508497,54954a96,456c5f23,96fc1c71,79f6b3a3,a82d8bb7,8ab73d62,61b6a098,77527964,5ad80080)}, +{S(118d5053,fa3ef05c,810cf906,3a410f53,38a9e6bf,513b9a7f,5259112f,f84ad7e4,a371fc9b,c9182528,27d6c842,32e4e44a,9d32eafa,84f1a02d,a86039d1,6309e92), +S(ce68cb2b,ec0e3f64,ecab8273,71f248b6,9b25f4db,94ca333d,c8d3595,e6f4db70,a8355f23,f22d8225,7adc9865,55350250,8c0bd086,ad7d8b74,ec3f3ea0,ecc17e88), +S(7834c202,977d96dd,d2897bc0,b2e9b093,6b3bb91,36f78002,85dfba94,cfde7d74,62df13f7,87aecd0f,5f299a98,1b4b6763,82b69aa4,997c8419,1f93eee5,5a8da0e7), +S(5dc11a79,34d41b29,5b384824,89cc2fc6,eae9c348,2baf631,94023e2b,579b750f,bc8719da,924cd9db,901bd524,a5eee1eb,fc161286,508e192c,10f3b786,f167057a), +S(40f1348e,a0032b45,3f2b5339,d687a06,3790503,b4cc7b5e,374828dd,5374566a,b7c04bee,58dd65a2,b5417ed7,236557a9,5d90f89f,2f9be760,408f3806,5ec9c1f3), +S(5bb43572,6cfefc3f,dfcc3a89,3abe627a,3bb9fe92,2dc39256,368b630a,1bbc91c2,4266fcb6,cc3d664e,72943e33,3fc94db2,b76b9b43,1e5956a5,5fcdb36b,27d175a5), +S(c61ca2a7,48faba61,93325019,dde522a4,b4ad7ffa,ffade4ad,84bc46be,390d6833,88fae1ef,1728b211,6a24bf40,7df169b8,5987f26d,75a86b84,37b91bb5,607b4eff), +S(ebb9b8ba,c980a86b,9955a450,493875c1,1bc446f5,ead71ef1,8eeee3a2,ace3a417,77aaae20,a2959de0,8b53b7ad,6434aa02,f3c56dea,877d07b,fdff41e0,aa463b7e), +S(fd3b8946,296987d0,22123898,bffec5ec,b1072fed,c8e66617,a8d1b00b,6bbd9889,54240cbc,7512e6d4,744393a,439e8b4e,9973dc40,34c68b72,df04ddb8,b89e6acb), +S(80aac570,6eb40c4,c6b5cdf8,e25e5740,3aadbc07,f75b190a,444ab53d,4743ca1b,196c7cc8,3ce92b15,ba110e5a,ca1ca0b0,c3205f61,e58c1e4e,fec5e957,72274710), +S(450df283,6de16aa3,3b893d69,39c46224,6ac30dab,941be908,42b3d5c0,714f9670,970c934d,5b242d56,b036b8d9,4b1e8661,45181ae3,cd286bc2,962035a0,fd852a57), +S(64c57089,83eba9da,d7871fb5,64481b9,12612c20,4f2bfaf3,635314c7,3cc9bdb3,7abcce5c,fcfea03f,74665734,13a66116,d6289bad,2209253d,45e77ed4,bae9a738), +S(4692afdc,34fd208c,72726495,7517fe0d,b463d39,6ba454ab,c1b81898,cd7343f8,57b67c27,8a0ab12b,5eb4a55c,933cb45a,d6b5d955,2110762b,61fe79fa,535a783), +S(511415a6,1371abd8,c86d7fbe,4adce11f,f6cdf1bd,330eb95c,7c40ead7,e5fca53e,4adfb29,87b9ac39,baefe7c8,69aa931b,c07fe15e,5a5811b,9add7b77,1d56c8d9), +S(4aee2f4a,ab479df9,b2e1ed5e,19230669,e15d153,22b5472f,c8b138fb,7d542c30,92c8e16,fbea4d0b,114a7d84,292a9643,6839624b,daaebfd3,9d621f3,7f8b141f), +S(8c0bc6ef,25a255c9,3816cea7,599c39d7,acee681,9373b82e,96b81a43,dd267223,8ce9ad90,e893c56c,c0392afa,24109c94,2098b5c1,15468b41,e444568d,9904efa)}, +{S(568b3e2a,2db4792e,4ef4ee66,14e201f8,a847fdca,38bb003b,adb06d74,1e4f999b,7334b395,61cbcce4,49d83eed,205a4c40,d91d2751,938ba7d0,6ed9e5a5,e1ffea7c), +S(ce433da,719f5582,6e69f248,3c3db9db,de45e0ff,fa2cace9,f75cd210,433fadaf,c296f641,5200cb35,cb8e1f23,20b86cc,9b341541,b9256d77,afe302c0,1e2420ea), +S(ea19269e,945625dc,138b9e60,249baee6,8c63bbb7,2b898569,5459629,fcc7ecf1,f5a7bb81,53552b33,86deb8c0,26d88504,f6a85ac1,b9290ef6,f91c0278,2cbb370b), +S(19e8e269,b972af70,c61983cd,cb7446f4,23dc93fb,b0e3d8ba,3fd02476,477e596,3081973d,f2123602,770716d2,6937f31d,f0835148,8c9d1375,d2bfec67,24df9c3a), +S(4968feff,d34e4649,9ca759bc,8e90d374,de9e3199,a13e2b04,28a10df6,15fb7696,2936b2f5,8491cc78,38bdf347,a4ee0b36,db288e5f,9727980,810c6eac,a8d1edf9), +S(d258654b,45fe5366,3552e85,a7da0755,c4598eb,68aa96d4,624875b6,580ea359,52501a5,e7d7d931,417373ff,ce85e0fb,43ef595b,2056729e,b1daecb,91998d1b), +S(b86b0c06,76f64537,f9d38200,66aeadad,4f3b68b4,2b5974e0,9f218d81,a547e04e,52a0e4c2,b827e0b6,894ee674,88a894f7,577cf3f8,fe83ebc,9e103a28,3c054690), +S(9212971d,b38b95f4,e7b9cae1,f1519878,80ca177f,73adcd28,a6d03e8,cefe9a31,9ddd4828,3b079a75,74afcdd0,e7cc4c24,45a4e893,ddc2d2e5,d24c413e,9c676041), +S(42a070d,929191fb,fb691944,a311c931,40740061,2bf33de2,809dceba,ace68f50,5429699e,47e22e59,b6cf8cc7,dbf2c81,23d90d2b,a48f6839,db4dd0c4,7caf4412), +S(895744c5,5b460749,a1e8b784,19e8f6a2,1e53f06a,ae99bb50,df9bd94f,e1a20610,a1ebffc6,da8a497b,bbc52ebc,4de1f196,881d88c1,948b05ca,5b0641e8,c56ab005), +S(c9e8e6a1,414b54f6,c19e9ab4,bd9bfee0,86a3e8ea,7a6b3e58,80cc5988,20fa512f,6878f69a,59a5be7f,3e60c1b2,6e9b9663,9097a6ee,7facc8e0,e242f56,e9a2904a), +S(dbf66722,d309634,872fa8d4,d9ddf8ad,2d198344,41a8515,7521b491,1e9e3473,1823095d,dcf42369,f3ff23,cb3a6ee5,273b8f98,7de2bff9,67dbac10,6b76928f), +S(b133817c,f965b7b2,f5d80c05,b82049b1,464713a7,7cc80d53,1e930434,387ea7d,db03e202,2eec1d26,4cccb613,7679c6e9,e08ef66c,f11378ac,add8985c,88f5e693), +S(e198a2c6,3f0bbde2,f31b8d67,776b8aed,bb86ad58,e2896a67,11b5d5c0,fd3a8d3e,e8df361b,ef77d3d4,4ca4f7d6,c554fc2a,9e2401ba,96769bf1,503b243,8d8306b7), +S(5f3ff8bf,148ec6f7,18aba1fd,8ff0b37c,18e440ee,51beef26,59652c0e,39ab7255,5da559a9,40e22dca,bb4270d9,31acb7b0,2b19d7fa,3495abd6,d5ca7f50,d6281445), +S(1e9ca439,c93cd0b6,d9886234,105fc1b3,178ba0b1,c71742cd,5c043ed5,56045c5,f7d31c2a,1890f586,214371c9,77501788,cf162d88,641a5540,c49ce4,323f3ad8)}, +{S(7c32fcd7,13305cc7,44fc4ff5,2d315e2d,d4cdf7c0,31b41a64,db6ecbf9,fd4edcbb,7f002bf7,b8e1b8f4,a4a4f2b,1922983e,fb901e13,59cbe934,8a31d91b,7bc86bf4), +S(d8aebd7a,db0ece5b,ff422046,6856ea0a,6446862a,4d0a94ef,ac7327a3,acb201ab,6e96ecfa,e9697649,faff155d,cd01bc34,e6c8630,616dd143,1c816c4,9d1168d7), +S(7dd764e9,40746adb,e6dc9e23,f113209c,7fa75c21,7da4cbc0,dbe257f3,cc0e3064,97e244c1,a0c8d68a,fc7a3192,b1f029e8,dbc41d85,8e0b273e,c4eff27,97e63ce0), +S(394a3fb7,320acea1,cf99bdeb,fe686508,15b3b06a,500df196,c05459cb,80b7781a,ec88e635,9615da20,cdb6a16a,245c694,ff550cf,cfaf2939,39103517,653f8986), +S(a394cc44,e64c4b5d,b36b4dad,d0a458ea,9c760e80,342b99f7,5227e22f,6acb0de6,de19b475,9fe10976,e9f38b74,1738b12f,e69df952,26c20d19,5f9135,33458682), +S(1277835b,322b7118,9ea416a4,c9a51518,e3a42d8,419f723b,d2b242ec,f904e26e,ce764cd2,558ffc31,779f610e,b33be553,a80a0dd0,1136132c,6e84b142,e5f5a8b9), +S(7c7527c3,ca6c3b60,18d6af7c,9ad79f0d,461e3d0a,c426e0a8,3bc1610a,80897370,fa7dc6af,7682554b,9c6f4b9,3822bd91,46bdae61,88fd2626,6f13af48,55ab23d6), +S(aa59dd0a,2e342733,a151e156,a82d63c8,9e992530,7bd774d5,d08c327d,27409a89,f14bb267,18ee5ac4,44390439,b8727f1a,f5b62326,fbdfb36e,23ff2f08,3a60e223), +S(733fa3dd,25e41c7c,4e548de1,17572b87,31bcfb22,57f0b822,1be31943,4bc2560c,976fc63c,e29bf97c,499e220b,80bc48d7,1fc07e4f,27afbe03,fb4a610e,e79bf820), +S(d6bf5a3b,ee8b720d,266586cc,70fc5518,a577cb70,44dc30f,210912c9,f1609bdd,bbb5bd29,290cf1b4,28fd9150,db667219,878b1507,121c6fe5,b1730f05,474f98a5), +S(b3a7824b,4da122ce,1120fa6,f5046205,e2989b8d,7c4bc118,d540c91,ab1e4b30,c7e452d5,d23ab126,28301b38,d2286c89,87d402a7,7b5f1fa9,ac033675,4f4461b1), +S(383beab6,dccedb68,d6c461bb,dffd27f7,1dee3acd,2d9bfc78,f9c723db,2df57ee3,913f9d57,286e287c,594a99de,f59ee375,c8d5fa1a,ca9db39d,6397d1f4,ac524650), +S(1de5be5b,6fd264a3,f9445660,995afa2,39587660,9d224d8d,6d02e600,4e7f74c0,f3abf699,af7033f6,cee828e,3bcbdeb8,fcdbba9d,d0f76121,a77f1e9a,cc65c1fd), +S(787be997,f12fb2ed,744bf579,eaf42ead,86d36029,e3063ab0,78e1c932,da1896ed,d652cb82,20ea596,70a51612,71249ce0,62e5c584,bbfc385e,622d7e0a,46a243c6), +S(f5870f7c,4dc65314,8c4ffaea,79154e05,1fcd6769,54939f5e,cc33779,f99634ab,fdb57c99,9d115b59,6d77bf19,e42ea2b7,c0dbf4c1,acccf2c,ef82949a,2895ef3d), +S(721a5aaa,c5bf9886,543b1e42,aff4c222,c6a63847,df9d72bf,7feb57a5,a007e26,94fb4bb8,fb1f945a,d53dd78,82f6a789,ab0dd874,9d1621ce,38bfa0e5,5b50bab6)}, +{S(29d70da5,92094c96,e293c115,42b9dbab,b30df8db,ac98416b,65b0b75b,b3ca446e,a8a5aa3c,c3269596,dd8a9d98,87a3b772,efa1c668,3f8a947f,ff80c662,31c70799), +S(357c14b5,2c0eb735,74f675f9,cd9ba0ea,9d0b5334,d7cd5dc,a8d6cfb1,1359a86e,85ad0fbf,9b2f48f,86fa016d,89824a4d,eed06ad8,3db7340f,986cc8ad,ebe9b5ea), +S(72047bc0,29b36192,b1549087,5e360270,a7fecd3e,1ebe8815,61e7e0e9,2ecc6973,7d1153b9,54ec6a42,3df1157f,fc9d413c,f8c3837b,d4c84bc0,40ee5654,6ec95d2e), +S(a459ac94,974bb47a,8e5d3ba9,169e7327,349ad551,ba8ad12c,fb4e15bc,d4894e91,699eedc9,aeb4bc3d,cdb97dce,2ca019e7,218ab0af,2790bf80,c59ba156,9cbb8c74), +S(e6f35f3,4a17a4a0,a76d997,afd9a480,bf8ef1e4,29441d2f,bd9f9d2d,b3b93bf1,67feedbc,de8e075e,fb80a4d9,2959104e,a990d813,2b0d395c,8e893212,d47a2047), +S(88924114,3997a2ef,1e36bc46,7e7f2fd0,52fb02f9,cd79f4b5,e6ddc9c8,51e26aac,3b1ba5f4,8b0a89ff,a4ce1113,934d11db,26b88e8b,2eae3680,57048db5,e5488936), +S(9ece7680,448a953e,5469839a,12fd31f4,f6d07a2d,434159ab,414bf7dd,60d783e5,2d60b5b2,e6966e5,7969016d,74059dad,c03cc7ae,f7b80825,9a629041,e0cb1b1f), +S(aa98d665,de5df68,9e7d323e,943d411,e98db3fb,51124855,256d0b00,579caf90,ab791e6c,ebca5631,22965594,b52b43c9,5f323834,53b37368,281c895,7d1226e2), +S(306bf517,c30d81fb,1d931b26,49af7c70,87246821,8562e255,42576f53,2ab4e48b,d0d15fa8,1391438a,5416f0e7,1c7b9ca4,512fc802,d4c46a4b,779cb1d5,2842059b), +S(2c8ed21a,fb154f9c,c3e9a6d8,dd047af9,c124e6d2,46da9faa,36a580ce,91b1788c,7dda9e28,6803924c,d8ce710b,d68e0a85,fc2f8678,45258f99,43bbeb2e,f6a7528e), +S(4acfe8f4,6ea97663,56ecb2e1,c3055379,cb4a311e,7e4dfe9f,642fbfb4,18abf5fd,a5d6abd0,d44bc614,ddf25ec4,24526070,100873e7,c4501c65,c3045e24,7478c836), +S(f7b1d348,378a094c,3e8ccc30,3dd8ca52,fcfa019,24c52fd7,32544a40,cf47d783,b92c436a,8c7e7ca6,6dfc1223,c7fad4c3,c65aa955,b8ce913b,45437e54,9dbbd1c7), +S(1ea80a5c,38827511,69cb24f8,64f4c1d,a78f4dd4,6509a73c,381627a1,7862ab8a,126c7a44,5fd6d3a8,f57a3a55,4fbe3f1c,eb9bde07,99afad93,fd7aa6a,11a0dd16), +S(e76aaeb3,9cc18870,6067a0f6,54bc317b,89a72313,2b2bf079,9ee88af0,41597d5e,6d75f6aa,19727219,ea7f6f57,c0a7d801,3b9bf256,d8764219,d261b79b,48ad6108), +S(c6d1b9ac,f9fec422,e89102ae,4fa07021,e6c81049,dd1e66d1,d0903ad9,e072398,2e971363,41b318a4,dfc4e5b9,31a79f35,f90e673c,6bb7aa17,a2ec5f35,def14ff9), +S(d9faf06,ba5bd56b,ee78db82,4db777bc,e57aa5ce,5c4b98ff,8c736164,d4d8b2dc,97af746b,fb890c20,7af10658,38d9b850,2d8d0524,7a5592e2,89f6ffec,a66c5168)}, +{S(7885bb79,25196ae6,f45b6658,f3c04f5,a3b76cb6,1d60eaf2,45cb35c2,2552267a,9839aae2,b4d9de01,1a119d3a,d269a821,dd88d287,2f031910,a2f3cc22,2e8555a7), +S(fac317d2,cb5e27e7,74deba28,d3c2cf69,4364a190,329787bc,e325d80b,150c9fbd,c56d5053,b0a73378,b0d5fbf7,940ac348,abb46107,1b9f0100,c721154a,4d084e7e), +S(9ed46b01,f4e56c79,9b3f582e,2e35434a,25ec32e6,ab497137,6eba881e,7ca96ad4,5e8d2e27,96b8dc65,867f45bb,a623c59b,a365d840,1d9e889c,23d6acd8,d5bfb365), +S(6acaf24d,fce1919f,c8d8743d,7a5b64d3,3010a8e9,cb6340e9,7400d143,53620af4,b767f30a,87b29f8e,308a95b9,6848eb5d,c8bada19,74cee095,8fb75735,86f1d733), +S(1a2f9605,fdb3e5e5,3445c350,4e550312,b36a7dfe,5df0dac2,23aa53e5,dcd7264e,cc4b4a0a,6febc03b,155a755c,187421af,52a7e6eb,2227858b,c56b9feb,4befb45a), +S(4fe527ab,42540438,9d9afa,2a1da83c,968fe9c4,f678256b,d4998bb5,af963a2c,66dea7b,7e0540c4,75799ec3,3987a775,6ae86d43,56a295d0,fe8242cc,27ad7c4), +S(756ee16,fd1019ac,30e50f18,5606d1f5,fa91a7a0,b01329e6,2a949c80,b7590bba,4d190439,98483880,6323163a,6cb23a8b,e47152e5,a5439d24,513d30e0,21511050), +S(63935d2,711ec4d9,f33fb116,ce09ea58,b45b29ab,79614b14,278539b3,4ac44e83,703a7f21,c47d413c,9235fb0,36a7b441,87a90768,2d435953,439f0624,6550944a), +S(fb6bad0b,3503cf55,8a75531e,9e8915df,9a88277b,c766b37c,d9685b58,a91e3fed,483feda,8c214ac0,92ba5274,8b158b62,3a0d541,65fb5b0,7ce07e58,78cb39d4), +S(30c7d349,a9fd4825,82fb09de,f7d638b8,633fca82,b9bbd65c,ef8f6dcf,1c8c05b2,56c76d9d,6df4bd0a,a8030dde,a3839728,71aada1b,61bb34cc,1eda08ee,a14761ae), +S(13faa439,f73bb77d,d2423e1c,9989808f,96d98080,af214cb2,e0cde511,9eba8a14,ef6ed341,7ff03112,ece400db,b274d225,bea30a63,c9a063cc,9a987827,d3e380f0), +S(42112f0d,7628b3bb,7a0e4f0a,eb58d2b,9915f797,10aca7e2,67214532,2ebf502c,a1ad23fa,d76d983d,6cc4a654,95da8d6d,c5372849,d7fdcff1,34e5903a,e8441ce5), +S(d23fef28,114b49b9,77faea5,2bd0e30e,6a9ef11b,c513cb8f,3107e04a,e26a9ceb,5a4cd8b8,b0dbab13,2abc50af,c9d700bb,bc28dc84,3c12060f,612134f4,fe40aea2), +S(463bd8fd,21ba250d,1eee7500,e88aefa8,38211947,fee2be73,d6511300,6d28b5da,20f6f300,e2744ea0,1ed033c4,b5b9e7b6,707c06d4,d97c4771,ad35e305,b11aed86), +S(21795062,e337d1fd,994a7cb9,7407d33d,f40ac1de,4a585c1a,2b3ad400,8e03c4a8,e93a4632,da05b347,8be71e28,c55af8c6,b4b161b8,9f48064f,31755a1c,f6b0ed96), +S(e8f77f4d,272c5dd,f001f939,4b658b96,d58a54aa,bccb9de2,c501211c,6cf9364b,7044feed,21d1dd9f,80705bf3,d68fd160,31c02dc8,5a708f18,1bb7ce91,8655ea61)}, +{S(422f029,1f51c4df,af233322,7015e4c1,ec8175b1,a8ab6b2f,60a9e291,7242d940,51ae32b0,ed5d39d,e1d61437,d363d59,181a68b6,4e052bc5,9d132da0,9c1f422e), +S(f560c762,be8f90f3,b12c1447,4c3a2d37,53634a4d,fef3344,ba8e9a65,1becd50e,49bc8c46,e3207440,76082021,6d203410,fda33028,d3ff4ee3,af065502,ec96609f), +S(edc545ef,2402bc41,c4d7b437,65830ad7,f79128d5,91b4201d,1acb5f90,a7ea6a46,ec758c41,e0ff7bb1,fc28a91c,435c09d9,90338a6b,216504d7,a538691,6af80454), +S(67709f77,e324ec1a,fb57e5fe,43215f07,3cbd3d48,f6cd0bbb,c01f3ae4,1a3c5905,e65102d9,c33abbc4,82f2ed0f,fb156cbc,20210eda,19b5b345,f21150f3,ffb29e79), +S(6b73d1be,a5b5ffb5,438e4cd8,9af6d9c2,bc41a2d6,a9c6b405,ac6fe5d4,6ff920cb,84f7e06,6dc9bde7,782c7636,8aed4a2f,e570e51a,8494864d,88e6c1d0,ed732be9), +S(5aa1e427,64c4f0c8,60423a6d,54cccad7,f6093ba,b6a0e383,9e1e0b63,cd652121,3245d2b0,fe27d590,15cac18a,861d9ed4,a5131871,38faaae,4c01d1d7,759fc9dc), +S(a8460aa6,9cd68695,94288486,1f92a61,e7e924f,1d61b9be,1d31f923,efd803a6,f6bf9b9b,f65a68eb,925f6c63,4d16a6b5,6d92d68f,fb807084,7f09c0d9,d95b852a), +S(fa3b7d59,bcd32e9f,a4cee765,d9b54c1c,65d8cf67,8a88f6e5,3c3192e1,64143cc7,95ed2300,2f55b1c2,21061dc9,bd26f0ed,82c05ee9,4bcf1bad,3bf878e1,3ff33b84), +S(febd5d39,68446d45,fe1daf28,2018c980,f4a5030c,7710edfd,b79daa69,c10f2296,b8c37c65,bc7c42a0,65be333d,1827feba,70eb75f3,5f289e1e,413e2325,5ab9d551), +S(9d696bb4,4dbff608,af3ba93a,e98993e7,4a6d8902,42d406a1,7ae9c609,6bb9b29e,d92c5408,c0ec7131,9efb50d6,18875060,da65855d,8b2d1cc0,9f07f3e8,c0e1d77d), +S(8f4c98cc,21d39520,e837b075,479b8646,2837665a,ac82541d,1bdda842,ca5c2562,3de70692,afbdd878,5a858fe5,51321576,95f464e,cf2c1237,545b1e06,a1cbbe6e), +S(6d31e611,2317acb5,f2ebfc35,a4f66f05,af86ed84,720335ec,535c0f5a,cd14d952,8d22c3d8,32324673,9b20d9b3,7fc73b78,fdaf98a9,6cded077,6e561037,b2a85b1b), +S(dc891a7b,d96f10f,b6d8fe8c,1c749ea0,328ad2e1,353b49a9,8056c5c5,b637df01,475aca0d,c67d1f8f,92f6ffea,20c48300,2b0f7d3f,f5d2526a,cbd8b89f,25ed3eed), +S(c77ede67,1432ef33,73af321d,7d8fc6c0,f254aaa8,37feb14f,34817740,a54cb5b,ec2f427a,cbb9cd4d,96f83c7a,450efa09,6e12917a,122eb466,23c6b63e,dba11010), +S(7334718a,cb39692a,91c140fa,67c21c0c,da368242,aa1d0d2d,7223a0d8,5ce102c3,e3051cf3,4d5e51e3,901449a9,3595fcb4,327c59bc,1e2d92cd,4d4699c2,26ae4e84), +S(23c7e5d2,2b0bab9b,b95fbfe2,e39e6902,5c7bcc89,fad1a0be,1f5da48e,74b3f622,bc5a3ef3,c4679a16,ba09f2ef,4fb202a7,83257a5b,3f95b629,455e4173,9b5b317f)}, +{S(43cf2273,e372157c,2180640,594c144c,93f64fa1,75f28cd2,5e7efebb,14028a93,1f8b092d,4cabc600,33782374,10eafd04,37d6436f,6064932,6f8de6d,94059d4e), +S(83bf8ee2,2a69edf4,74e5b45e,50aa0bdf,4879b4d9,61d4b937,ab18d3,7869fe5e,296e8081,cb72663b,5223c040,a64c7aa5,273fc6ce,70261af9,cb3e071a,79b7c3ac), +S(66b8e44e,c913698e,d68f3b1a,df750442,442a4376,9ebe7859,84e4d233,9f666b1b,b09c7c2f,852bae4d,f90bcaaf,a664c792,ee88ac87,2d2e046d,aa6009b2,2412af94), +S(fea69879,e4eeadf9,275589dd,6339111e,5d29c581,30f22fb7,c6755d5b,2f5840f7,814a6766,65b54689,b3e2d415,4519bc8c,9676cf4e,91b928ef,3586da12,416f546), +S(bd147b40,5c3ca694,ceb4fe83,5f95676c,5428a065,add89f79,ac5859c9,7dc4d5fe,67544f50,a639f7a0,602a5fdf,2d425fb3,edea0cdd,f2cc5f9b,c61189bb,79cfbf58), +S(b3806514,838f93cf,6118c8e,f759cf82,394bab94,e020ca33,7d20c8da,bb61c79d,bf4c1bc7,35c5a806,d682a1fe,239a1027,51a547f1,7d1d87fa,59c9384e,3ca1fe45), +S(bb002b37,60adf886,a89d4ba3,23c17868,83f0f3dd,fd4232f1,28410770,563ba5ea,4aca65b6,68115f32,186773d8,41c061d6,8d4a860c,442b3f8b,c72776b8,3bcd22db), +S(7857b661,420c4251,3db90fad,ab97bfe1,9a1e3f91,5d524f66,86d0cc01,70652ac,75205776,8c2e420c,f255f9b0,df58bf4c,39316f63,612711c1,fc7fe5c0,b4e7ef7), +S(cd386b61,bfbd43e5,109b74f0,5d765ed0,5c4ceac7,85bff4a3,c8386ca9,54fb4553,aeef237e,892a3a1b,84183222,91f9119,64bc7240,2f32da46,47a159dc,4a7d6611), +S(94dcee6d,e36b346d,4dfb5ad6,3f488761,2a5734ae,e251b07d,6f81a3cb,7d255409,3265f73c,af4ef3f0,40919637,4e273be7,c0588085,1940bdc9,9d0ab66c,c488e203), +S(53199671,628f4a30,89e65e28,67489a1c,7f29c9a8,a34fe8a,c144623f,9ef9fc4b,45740e72,3b787de5,1ddf66db,96c91bbd,19954170,62fed0d9,69522916,7b2b10aa), +S(38596053,40ae3e91,d005b3e2,3a998796,195a5c5a,81b24286,458cb7e8,ec905e3d,5484588e,c9dc9485,bce07479,b1dfe9d5,c5007d9b,eb7c372,f52e526f,7627131), +S(594e1bd2,3a5ced9a,98e48bdf,dde40807,b9c2871f,79e1948d,7167b59,9ffecc53,1d7fcd4,bb9bf0ef,e0af9ed9,8da3e36b,2ceb0ea9,e1e3358f,4a590022,f5c530ea), +S(bef8b23f,95e0bdbd,3c0ba1fd,7afb8a58,1f038e23,e3e9eac2,b8848a08,6f23f816,9a234d55,f9c810b1,afff2a1e,b1738d18,4308d19d,11a0e1ec,cc571eaa,b9663c26), +S(632003fc,f53c8833,5542f216,e4020ef5,3eb225a4,be6c0e59,b92ebfe6,52721652,bb4d2dc2,f255b8d2,5c1803b8,88f40d8b,bbe6b2d9,f6754511,8264f809,cbd61844), +S(b7ae730a,e74aa208,9f3266b1,5358369c,4970c009,e6318581,4d541b07,c6c80a96,43a7b349,66b4bd5c,a1e45593,42642d35,ebc969da,544d4cc,65519915,34e80d65)}, +{S(9f10aba7,5a7b9fa0,233bf53c,d819ba2d,919f8acf,9a5e6717,2c93229d,547a40bd,85485295,254a4456,87b065aa,dad21f32,b31735e1,96333fb8,11117a00,d0bf2361), +S(75f8bcf3,831197e8,b9053c1e,5194155e,dae1867d,52f74911,a478085b,52d916b4,90448c24,35180385,a15a335d,a33af722,c9a395a7,16937aa6,b861aee5,b0b9567d), +S(2c05f980,7e24fd5e,87e4562d,65aeee0e,315ebc12,35731606,81e99bc6,be544c8,3a3c9e33,2e78cb5c,8ae90d20,edfc9eb0,3ba0ee07,82a158b9,154999f9,55e89210), +S(c8ff77e3,76a2c4ce,46664e1d,b33f281b,90e34103,500a9a46,83038062,42e59969,1d609bf6,2f6d3e86,c0510de8,4a42a45b,3fdaedd3,77101216,e43c2d86,751d7456), +S(b3205953,aa71cd5c,88ef7e55,3b94c8e3,ec4fd654,b7524c80,51908174,32850864,2c5d67dd,479dcdf3,41db7c5a,e0d03776,f3fe9ece,32dcda0,274a7955,b45edae3), +S(cb903c76,7ad3cd58,66c66429,9e9d07f1,cd35043,66784cd1,af3fc75b,73c4499e,8ef65e96,f1998688,2af0fedd,e0266d80,780ec031,fa47cc38,9e7bd059,eac83ba), +S(1a975b06,9e3f032,7fa9b706,3533fee9,f72c6c11,7ece27e9,cc83934d,a0c5d1e6,2cf46c5b,9f3596d9,5739dae3,a87564f6,13eb944c,5d1b6da5,3be8d76,14ddccf9), +S(d708ccf9,4dd50c89,de00a127,1cbd92bf,29f440b6,401c28fe,699f6f6e,50e0367f,fb173384,e0463978,a15de0ea,2ce146d7,b826f6a2,616d38ab,ae0a3dcf,1e11a1e), +S(11d850b5,4aa10ef7,8959f5dc,4aa9ce13,8ffa25cb,1034a365,234d0f6b,46458146,33162f6,bbb5ce33,af19cdaf,57dc82ec,69291c12,38e8f266,fd0becb0,bab02e8f), +S(7cd60401,be3033a1,85784a4b,adf9dd84,f4bfacc1,952597f0,6730f2d6,924332a2,6efade89,37b517f2,e1a1d41f,d6e6c137,d581d7a3,b55ec632,74ef8b87,1d9dd370), +S(bd82a0d8,34892e4c,974aa93,a64edeb0,9aa2e3b,16785166,c970206b,53ecf157,541cd14b,1fed321d,5a044abe,aa3bba7d,74c3f44b,db3f1fee,b05ddaa2,1f034ac5), +S(6f77bfc3,760934c0,edad8b77,f56d6309,179c8fd5,bbb731dc,42c279d,89f99a44,662854fa,e1da57ea,7e8eeb13,b3bf6744,f28cd210,ed461ede,7883dba7,f7b59d6e), +S(f31d35d4,dd0b2e6f,5b236e98,df56ca98,a5b6db2b,a2a8e0c4,eba41ab3,20cde154,e33e127c,b9c16469,83d71085,ec7ec9aa,12d41302,fa769c61,55af26ef,a7d1785e), +S(c0ea3ba7,be2030c7,790a3d48,7e720893,2e070691,82bd0024,5483be62,7916eab3,f5055e6f,298bb6b8,47e99275,64cb29f6,54d2131,1ff0a3ba,20a89ef5,992c0342), +S(23a696b0,e70e4197,d299abd0,b301b383,3df6f123,80120247,9e8b59a6,10a1fcf3,3af29a3b,ce23b0ce,afd9a25c,f1505958,b85d4f39,318a402d,cc48f98,ea953edf), +S(ac79289d,c14206be,742005e5,f367c4b9,e2b645a1,2c21d30f,ffeac884,e6f888da,27c49ede,7c0b42cf,91de7682,e6f224b,2a19f98f,72f40054,69c3121e,da2c4379)}, +{S(b365ce49,d21ca341,c173b6d7,2238c56b,f080d218,a89e57c6,ce1664f6,5c290a44,e77935dd,75d26531,d4045f72,3b4b5dc4,6608f8b,60f58989,d2ac4002,c304cf04), +S(af35612a,d1230c6b,3a260abb,69cc7099,f7025c1d,2a14d196,1914236e,4d4e1a44,b67d23d0,8737e96e,f629634,44b08f82,822c690a,b3d2838e,46ba259f,bb951b2f), +S(183181ca,37069462,5de3c48f,b8140ce9,84029874,e8189b4e,bcc8d91e,eb8d681d,a1780f41,8e7f00e1,e5ff8147,33a34699,79e6fd38,bfc03491,8acb042e,6ef4d6de), +S(4c1db656,41753e4e,5cf10f66,9a3e4b06,e18b3d0,1b56961d,8c400ae5,9ba239b8,cc57dad5,77b3d6c5,d96109ef,1006e33f,9c888598,c7248f60,5a531800,dd0c957b), +S(f0f61e45,cbe01564,17fdf9e6,db32d3b4,84fa0bbb,4be30aea,95dfc8ea,31529ee8,4b0de888,b71c441a,1c54849c,7e4a8129,d757213e,52b1796e,a5ab02a7,87087757), +S(84e4bc99,7066633c,a3997a55,a3fd3ef1,b4b99302,74349fb3,5da10b39,2f49a022,64512422,1acc41ab,68644fc,73b39a3c,6bcf1268,849bfc5,84aa7c85,4a48efcc), +S(a71007b1,e0747b7b,1b8b4398,232ee970,97f623ec,4924b8af,16ea98d3,6f98102a,91039909,9c42dbe9,1bdd719,d31bd00d,e040752b,cedf9927,77e0863a,96a5a259), +S(2f72cb7f,f0aed6c8,ef75c041,4ebc413c,21705889,de3e33dd,d3057668,4f882553,86450b7c,bfc89e63,ba1a1754,ba42125a,8b41f12,d5a5582f,ad86675a,b05bf998), +S(99f0e44,e11ea919,f16fa130,5ac6e72e,c11ae9dd,e08d3143,2ea9aed0,f902cc77,43f4e6af,ca0605e,749623e4,18027ee9,c64c059e,560d6c80,6219eec7,e475367d), +S(1aff311f,bed263a5,edcebb0f,e149302c,c0cc2b0b,92c69d33,d31c5522,eb9c9a94,8533cdcd,97190439,48d38bb6,845ca07a,9a9485fd,dbd44868,7f06143f,e85f046), +S(4a2dfcd1,4f601607,43273bfa,3702be5c,57f99a6a,29fa7f92,666d5020,6ffc852d,95931301,821cd6fb,63203fbd,a894de3a,57eb75b0,2f273f3d,bf462727,301dd9b4), +S(59c5a0da,480f334,944608fe,a580c302,965d26a0,dcd43b31,3854b302,af6abe35,40e27b3e,932ede7b,40490224,7b937b7f,2938edb0,a11b667f,16a90ed0,2a0309e4), +S(570bc6cf,fec905e1,564906b9,ebdecc13,60abe5a3,61f7c5c8,f03cd2ae,3ef9d125,55bff728,1f73045,82fe61e5,d4a92697,77503b39,9b320c45,ce5bb9bd,35def5c5), +S(bd7dab69,88ece4e3,621efa68,38a24032,ae9721c4,fcd835d8,6283b5f8,f9f02ee4,c7442cc0,95009f1a,193766f6,d050d165,d8cdca90,2ebe6d8f,237fb922,a1b6fb06), +S(a780a23d,eb8459fd,7195ea96,e8fedf8e,8b38edef,e0e0865a,b1d69d85,1d27c65c,f8c94632,a11f7185,9e3c7963,f24904a6,536321d5,f5e4652,3195f854,355de49c), +S(f0ab42b0,bb80f147,7f9fe3ae,f5944100,14a94142,e8312b91,86b0d6fa,3f0243ea,237a6ab6,b5e08f03,a7b58f98,e72227ac,6d3660f5,43da0694,b6821c9d,332724a4)}, +{S(38186a1d,6092b158,554f3f6d,c6de049a,2037577b,2da8db39,163fde30,b19dbf2a,a8cf045,9c7ea28a,415d01f4,47566d54,f986cab5,eb272326,442f32ef,cb6c43c8), +S(aaf937eb,c2084f16,301bdb4e,aa106263,cfe483a7,d0ba1b16,b93d921e,80f03a4d,7e18642e,8be01d91,86366b3c,c94aef09,c02501ea,e084a87a,a94d2d2,f85f84d9), +S(128b8279,ec2731f6,cf2ceed9,fed2cb49,f53d6237,112a84fc,c678189a,8e19867a,fc0dedbb,32524c1a,f44fefc,6b0e6bd2,ba65f23a,54f69986,52953154,41a89489), +S(7c3dac1e,6d89c8b6,e9645ec9,39dc634,a2cf5adb,323be29f,625703b,caeb21e2,a1b87f33,b5bd9351,15f16702,ae411a91,b3e9eb6a,814e678e,b3dd7431,6dff896a), +S(609d5c22,c8c7c1ae,211b4ca2,f709a1ab,75624b91,cb95d2d,6ea6baf3,eacc12c4,65a7b252,f13d08b,4b007967,69e6bee8,edb5cc68,d4ec8c46,527bcf77,535bd7bc), +S(691534e3,2faa9206,5fe7e8a1,8a863d78,afeeb581,97b1f48f,4f090bb6,9d3f9d11,2bfac0b5,35202013,60268e74,2376b901,a027d6f8,f0d91aa6,59341544,118a325b), +S(e6736a7e,e2f3f088,27012faf,3b3d1b7e,ed8dc136,3421e438,8ba70c5b,72eb4eb9,5a9b2651,26652e14,8fa3639,be0b4d5,1ba519c0,1285964e,7aa8a699,45bc71ef), +S(e3f05d6,2aa7b9d9,6e9480a0,a3eefe32,f1f6d45e,2fb1215c,ee5a3fdd,f147b154,47389f33,e03817ef,1051db5b,26efa711,46cf673c,12831163,2ee13576,b8508013), +S(b5041a3f,cf8b742a,dee6540d,e9974cbd,fe527e2f,4842a208,630b9d2,239c0657,4ea01569,fdf5b2e1,7631d2e8,2c2c0bbc,291d69f2,fdeb077f,4ea1df9a,6303ad57), +S(e5463af8,5dc090f9,9ff72771,c1cc3585,dfbf9dfe,329e69b5,fd0ac2ef,3f715ad6,c54085dc,a966fa9a,985d8e46,79335dcd,2d22d470,790f71cc,1d0aeccb,be9c5fad), +S(104b12f7,8fdbd727,2a5716f1,51238362,94261142,48209abe,e4dcbb4c,d7bb0416,ebb07749,12a3ce9a,e20b6696,e485811c,6a15ed53,a1015291,90672c47,e4442c6d), +S(1699a1d8,d04a07fb,32fcecb6,ae89092e,fcaaebd4,fd9c4af7,d79a5eeb,2c18da72,cff1a93d,4ccd9199,9c6259bc,fc975ab3,4992c8e1,8d1cae10,b0c1ce2,83101103), +S(13df43c4,4de2fda2,4b932131,e7c7fc62,896f2747,706ff959,85f98248,4cbc6179,1da341b8,734cec8b,74de0c08,a040ff68,d8d30ef1,dfe1ffe4,72ffc73d,a6a82a74), +S(2e101469,1b7e08f2,d3aa774c,f8f91ae6,e9aea711,fddeccc5,d816e5a3,dd752dfd,cd4e7f49,998ec720,a3ed2e45,8136fbe7,9942011d,da5d7fd4,2c56ed77,29f55b98), +S(b0296b3a,f9e819ac,a7b01bd5,7977ea85,5d2ba87d,24f820f0,c1ad5f84,6b9d10c1,192cc5d1,b6782d9e,e3f444ad,61c0b8d6,9772062e,7b03c615,b1cb7550,a76e1d11), +S(f9a11b59,6e369694,fd62d423,518e355b,a796269b,d2b5a88b,1c8bc812,40fe464f,8c919e60,86160ff7,8d1ce269,4512c16e,75f8a79e,da39df1c,ad104555,6d1543dd)}, +{S(d8e5f3ba,c152215a,8cf8ca08,40aaad6c,7d001aa0,140bb0b4,dcac726,229ee272,e59390a8,21e8608b,e53fb258,a426dfb6,ca762fd0,9d574f7c,5555cb8d,7174b381), +S(c2d7dc95,6c6721e8,6effb64d,5e1c4ec2,ffb13a28,706669fb,ac30f035,9d202663,8cb207fd,63af5339,f9a705f5,79f446cd,1a11c0e4,cde750cb,803b840e,5a4970a5), +S(bb3445f8,d7f47cf9,befd1a73,76dd9c96,f6d76fb5,b6d4b7de,e7f96dc8,c9e8f025,c1fddada,756d03aa,7d92135a,a8dd783d,63920238,1c2f5af4,7e702cbb,97ea783b), +S(1271c587,d72e74bf,286ae688,c022e129,f9a95567,9f74755a,24e85d81,486699eb,1259045a,cb14f2bd,7d5fc85d,d8c58303,9181d367,63e4733a,56172be4,b19c4a40), +S(76274ca3,884de253,ccd8e9fe,b2f7ceb6,1c7b6c49,1a358b42,e64994fb,80808263,d2639e7,539ec38e,b14c7d83,47fc4d10,c2a2d83f,81a1e4ad,1ba8267e,bfdd4dfa), +S(8d80c172,ea0f7e79,d3f2569c,49d49bf8,330cff73,fdce6b14,3a4a349d,e7cec2d8,86dd76ee,63fb3a85,ae315029,3e2d024c,ff1649d3,c823ca63,5a1fd992,975fda33), +S(441e6584,10404939,367bc434,f1c64c42,5b2bd11b,5beeec47,35919f02,4a4626f,3db30e8e,29e6cedb,7bb465eb,92526c4f,4b7d8361,b151ddb1,da878a87,86d83573), +S(10d89274,b0d498f3,d29df723,937c3838,49b4ffd8,b87427bd,a1d142d3,160c2b88,15df3d2d,b11e35fd,a423c709,24e497d9,77941b44,20e3093e,539d3406,e2fcf435), +S(3960dea1,9431a970,6bc4e886,8cbcaaf6,dfb9c87,17e664d0,4ff6eb5,4108f2ce,3cd86dfe,6d967078,9f090213,4661a7f,78e4854d,7e79e519,7283f8c9,a89ce6b3), +S(a1f9b8bf,15de0a59,141449eb,3a52a335,ab881489,7a7ae82f,964d3bff,f1dd38d8,dd563a40,ebbf06d0,84e21a10,dfd117e3,c8806975,53556b4c,2fb51100,6b498d6a), +S(17cbba26,9cf2b92,7d442075,396090da,62a2026f,ce3b3eca,858feb21,76659de2,71f31851,a2561f97,b0ac2495,d72904a0,bdddd83e,83a1dd87,b0db14e6,ff1348b5), +S(10dd7c20,902512d6,6484c830,53063a20,c7474504,3a378949,280a90b9,f8504102,1624bb25,937d3b47,43214401,c8016fff,f770f7ae,7d78d8df,381c2de9,13bc856c), +S(7ecc1dcf,5e9c56cd,43cf311d,5b31d269,50db89c7,2b51b624,745b3c75,eea68899,3ae1b7d,2e8252e6,43b73aa5,6d7c9b62,1f79d1bb,1d2973c,1bc3b150,a17d1ef5), +S(f57d8aa8,ca4c8377,14ca1ac8,e2fa456f,4c94b304,fd0b268,2084ab52,3768827a,2c5bb2ee,e4b509b7,7cadd78,4202c12c,3644ec47,9c599009,581f8b6a,7ef5bc83), +S(74905ca2,7116aec3,b96d16cf,fba3431f,5ccc3cb7,e5747525,124b5b31,bd6fd066,7d26da6c,1268cf67,846954f0,48c7dcb3,3a1244b5,8f0a8026,c3dbc651,68cbe871), +S(4e0b7166,de12f0ff,baeb2464,ba205624,e85b9238,4a3ebbcb,db9c6038,94ef0cef,8a85223,cf784126,3419d777,93fb66d9,19e3428c,5ab844dc,d3d9cc46,7ea95c10)}, +{S(f41bd2b0,e0f49133,747e831c,af4c7a0c,22d2b55f,1cd4ca53,1115d81b,b47754b0,869485d7,26d4687b,c57a9eb6,e90e93a7,bce3b523,998d16c1,297c996a,b68c4fa3), +S(ce2e4f9a,3c32ea4a,2198e61,8d7d88a9,153111cc,fc114a46,cb9b47c,63842146,5c90a793,c4f4b290,240dfc0c,1dc0df9d,a33214d8,3024304a,d49eab61,8c4d64e9), +S(924f51eb,823a89d1,3194305b,45ba1f8c,40a58987,73cb1a5a,a4a4017a,b55af76f,8cfbe8aa,d3b759f6,14c98aea,3b3443ac,46400a2f,5cf741ac,c7f590b3,39f3ea0e), +S(9f985579,fd32d32d,90ec233,c5577a12,b1fc350a,e94b5f08,ccd31cc0,33495f5f,ffae345d,8bae4446,bfd5b6a5,117c0b77,49cab9ff,eabbc8d6,531e0c34,fdaeb328), +S(b4d25ec2,6afed742,2ae7f209,f4201d0,91dfd595,3418bb05,12b1ce25,455ba8e6,8a13f82c,47489b6c,72223047,e8e079e0,165edf0,4c335814,b971a5d8,27d2cab6), +S(7f4ce1f9,acd1d262,6c6da2f9,7dc19ddb,ba3f15c7,7b6c88e6,3b0d4e41,a40a3c7f,750468cd,33a35da7,242142e1,e68128e4,b5210635,c4739aba,910ba9ec,c9c01fcf), +S(67f46710,16d87e34,b2d53d5e,c54f9fa5,f22c283b,a3dc5a17,70fc4a16,1a2be4c4,70503598,1378a67d,16827d9e,c87c591e,afb16fea,6a5ba182,4f6cf6c1,fa92b772), +S(1c30c0ad,43b0a74d,fb199442,b151865,7cf99e26,fca6e2f2,1cb97a6a,53c15893,3728e682,72a4020d,8365b4ca,eb153fe5,162e79c6,ca6a851a,e233a160,400b625d), +S(d92d821,8443e951,ad6ad28d,b7bd7101,756d91a0,cc3deba4,219ee34,ba2f6017,fc3dab7b,ac2436fd,a39a65d4,596dabc2,b65f8f0,c1195a51,5d8f2bd8,4f5530de), +S(3b6264bf,a47de486,3ceccda8,fe6c55a6,ab1d8188,d111b222,4aae150d,c3517ee3,e3f786ce,5adc8660,98965a41,62f4f510,8c1f34d9,2451af03,8f68e5f5,8f6c58d9), +S(c6b7190a,e4d0c14d,b3cba3db,c72fadb9,da9391d4,2eb7ac68,4e1b20fa,d89749ec,f4b7f04a,b1358c35,1b2c622b,aabf3e5f,dc5abd87,ab3cb388,86f73d91,202ce359), +S(c2846da6,a821c506,e022a927,257b8d21,57d82def,196f32a6,78b8cdca,d085779b,d5431c41,4ea1417f,3f4d90cb,c776ee29,9a6a8557,a256b3a2,58a887fa,fb5aa256), +S(7bbe2521,1f987b2,742b6266,d2c598b4,1de04ff,70b689aa,8be97f8c,63829bc8,dfb605ca,3491a434,e53fd0cc,d8bb2188,c6dbb06,cb18a9a5,cfc6844d,400982fb), +S(81a92f34,ce6c4383,a058d74,ac36b44f,f4bad7ad,b6ec6a92,87db84c5,9df3469b,31639fd5,7842ad40,4b204b26,7570a557,91dee70b,ac71630f,90924443,47597c32), +S(9e309152,54a25340,8a533606,d8f8dfb6,9ff93f1a,9d97212e,c261dcf8,ea3d1d7b,ab95d903,ccce7769,cc185c1d,4e24da15,b9c05bc2,7977c754,1b1023d4,39d75d26), +S(f72ff9,92e06721,559e127,28169de4,888efbee,e87542f8,fe0fa971,189baee7,db2e60c0,4678d370,cef335d1,d3e007ec,30dc03c1,f31c02cb,796de00a,f856e440)}, +{S(67c452cb,e71c61c5,8aaf68cc,b1f6208d,5646432b,86774f8f,60081179,6d5337c9,d5f859de,a125aee2,11dcc7cb,b50b4fa3,ef4f9767,7eb94f65,b6a181df,9b938c0a), +S(b068a1a0,e36426fb,2d959715,63faa818,1da81aaf,3ba3654a,f2570e0c,3d373d2e,9d29d11a,9333182b,3202e348,f547a9ac,ed5b6468,83608526,682b10b6,e1ad0f0b), +S(e33d0069,dcc14230,760f13d4,59c4ae5a,8af0383e,e6f37eb3,13a8b7c,587e0c30,aca7fc55,47536053,97b56a7,4d814548,993e11c7,4b89bf1a,b50ecb40,b9cbb5f1), +S(77f40f78,10b06a83,71c1493c,61a816bc,10f3b70d,5fcd025c,54de5036,eb6b2ce4,618187fb,f124b864,d69ae6f6,c9eb674a,eb73a074,b95194df,967b804b,c66d3e56), +S(d0ebe599,772c1450,979c403,25ef498b,69548f62,907bb455,1fba8f0d,c7b076f7,d0ffa315,3b96c94b,cb97af89,2f845295,ccfd1146,d8c682a8,3bb7488c,3fcec2f6), +S(2fe20698,39f33753,819d4b74,f0a036e9,2aefe03f,5b55f504,d3e1af7,eb5cc0eb,27e67641,1aa1a970,fa0fa0df,8a147716,b52ac4be,489194bf,3f192ae0,eceab892), +S(94dfb5be,319f7da5,ef283791,e6375480,1c337607,32f8e66e,bc649943,af99262d,4fedb692,4c6dbe8b,daec8caa,4273f77d,4736b73f,80446c5d,d4116329,5008225), +S(a0147c3d,f958362c,177aea45,908de2f5,afdb005a,89182e95,edd3f4e7,74ee0cf6,c81c0014,b273d2b6,2e7d40f9,d9b169cc,67ebc773,be51d8bc,7f35ff75,f0eeca0c), +S(91fd8598,f0a9c4b2,130310cc,417e7a3a,c1374b1c,2c76e675,f5f1a7df,32b1b96e,f2f277f1,154afaff,774390e2,e87bf67b,a722ee5d,b502a1c6,24042a7c,779d5a45), +S(613b839,a2dc9731,a2ba890a,e8f7c966,ab3c4237,fc14b05,7c561f6e,208c77fb,22b63998,85a758b5,848a318a,5aac49fc,aa14c4f,cb29f020,842280fa,618f235a), +S(653389e1,3b7f87e8,8d22d0de,d8b1de4a,b4902d12,a0c36e76,11ed3d0f,e1efcb86,ba710bfd,95e40d1,a4e8b4c4,cd1ee147,e01ebf1a,74f52483,4fc5148b,65a86e4b), +S(7b5aaf67,bd31c86b,e4877624,85b35fb1,4f6f480f,69aefa91,30e3208a,f9f9997,afdce71,1bf55d3d,4cb01dc9,3870e40a,851a8c7e,a7217607,1d3285f5,c727a9ed), +S(bbed5d70,be29d810,51bd811c,7f237856,7d097da5,cfb2d891,c0bc86da,7d680dec,229ba9e5,ddeaa4cc,498cce34,abea1d19,567e3a6c,878f8fc1,31be7b06,f8550aae), +S(1c4562b2,1dc0d0c,1c4bd826,603d07a2,8b7545f9,29e0cdde,77a1ce23,5d378d1b,b8976266,79671f6e,bd0b43da,9eef06bd,99dff8ee,5092e19,f260f468,ef16ef0), +S(a9edf307,c7fd7446,d71be12c,267a7135,688bf7c6,8f1dd65b,eed8208b,897dc380,9a20e692,9437be50,36a7b701,ad3a6a77,82234965,cadca1bf,4992da4a,24438f9f), +S(3bce25,ad7ebdd3,43645652,954ccfe1,1c5e9597,fa3a9f83,d51ea36f,2b55aae4,cfdbf98b,7f3575f4,4d37ac16,41352d12,bbf7e13a,4315cc04,3e9ab067,b3e41c52)}, +{S(56d09714,cde8f0c,f1956cf,a56bb0aa,b73507c8,bc0399f8,c0fd17de,19e48e9b,d62e1f31,b40ca6ba,71de9059,8a9fb911,6c5f0007,df0c33eb,f50db688,ef0ab90f), +S(8fd887e5,50b3b108,f17bf25a,12187b64,4b173b13,15d5dbb1,c9821c4f,9d05a37d,7b2d3e3b,731d83f,535c0c5f,1df2fe54,b1eb7c02,e43e73e5,42d0efc2,c9175fc1), +S(64331c37,736130c,78f719a7,52603e28,d8a48c9c,33e3676,2ddf079,4647588a,9f214dce,bcf18bea,5aa4823b,e72df87f,634e37e4,6b8e696f,41ac44f9,76834a5d), +S(6bed1320,7626f62b,4e323e92,ffbca06,4b682d74,59192c6f,a3569567,cadca363,8d435e2c,da580046,755f375f,b226ac7f,86d15c33,71114737,fc09b8f1,ff9d311), +S(e1c8c67c,56fba327,fa0b3790,8dde77b,a187df50,e2b0217d,8a151344,4cef208f,7be39f85,450ba36d,b2d46fa,457c68bc,e6c7d140,ac1f6f60,cc95d12a,b3dba197), +S(9e927dc5,427d6859,30da46a8,915934bd,4483374d,263d962c,fa0e9710,6cf285c,cb9b2596,90224417,d65d7bad,f89a946f,df0f7b68,2a28099a,118c146a,598ccf01), +S(fcf97f06,f70b77dd,47ee5661,ca5c5653,5b770d5a,ca61e88,10542124,92fa3748,5df3187,1f5af498,605324c,81dea770,67aa4952,7736a0e6,cd3cd6a6,ad4f185c), +S(f8922d31,8ee1c47f,29a5df4a,66ea44e7,7ac4ecbf,2440c4b9,3815f249,bc5a1b28,9377d8bd,548e7fa3,bfef786d,bca70039,24509e9b,d22e483d,9218fc48,34941d62), +S(6b7de62b,9c928cfa,e9da1197,951c010c,34dfbb7b,b111274f,ed5f4552,20909188,207d06d5,719938a4,f69be3ad,ffe9e83e,17d2e500,7d3dea3e,f34336f8,df3d226a), +S(e948b128,c6217752,8f1d0569,697c656d,92a92b37,34360795,73c9d7ab,61db30b0,7518e35e,1a5e4e2b,64966fbc,1185e7f6,b59766d6,a8fbd37f,36dd9354,14d68af2), +S(9d932075,5fd767b5,87d8cc95,3b2b7d49,4967a9ff,9fe673d3,8b7aa621,3dc4d7ae,80c62686,e574233b,21f8892f,7f8e3cf,4e05c47a,db687e38,4ce2079d,16fd7d36), +S(46eff49d,a6d4dd71,108dff71,e706a9a0,952a8774,efe6eb8,6cd28a90,1b89a8f6,8b26310e,ee49ba70,77f085e7,cb2f82a7,97fa3d50,c96e7148,892f57db,f89e3544), +S(72a59c5d,6286d1fe,c37b7bb0,ff34f67c,4a632530,37a22efe,7dba0305,2cca87eb,a3770634,995ae65d,c48151cb,f2e5efe4,bdb30825,cccb1277,e9728741,ea2832b), +S(1eb0e1c4,8471f8d4,1e34c22d,16bad4f8,2f0cc863,db92d412,8d7487,1f7f2f3d,232f76b7,1cd83c5a,4349358c,a661639a,b4d6a5b6,8eed0f11,a674385,8ce7bf95), +S(d4173198,3c8645f0,ec134630,7c6974f3,1aa396ad,f01a91b4,b618304b,34cad3b9,3825cdf0,bd454a15,ea3d18d6,b07dd5fa,42e1c46f,7fb6a1cc,f1a707e4,74b83550), +S(aa030fd2,52791775,e051f0ee,be7d6902,7da01452,67b4e712,960692f,1d59f72b,fc83d72d,5a0edc4e,c05ecb54,7111a10d,9341df1,b0544177,c2eda0a6,70980ba2)}, +{S(31095045,658b8c85,ec0c4ddc,7cbce691,d060181d,ffa08855,f3f36722,4c026225,9a8cc527,1c231ce7,aeb6e73b,9acbc16f,4b331b01,4bd457b8,799bad40,547c210c), +S(372f6cd,9a7b7907,4f730fa1,8cc1db50,a9747818,99df942f,4f2ceaab,e85c6678,7c9b42a3,81ebd00a,8d4aadaf,2e34daaa,e57f0633,94631677,ee675952,3c72753f), +S(77e7096e,7215e184,cb096b45,54f60fd9,4fc5f7b7,28bba5bf,be2a85b1,1984daf6,4a913cc1,dae55633,9a90de21,746d3e55,7e8db814,c23aa361,be967ccc,cd319643), +S(fd6c827,34bfd6d0,a6130095,d2c38135,e7992c34,6e85d7fc,e5b13410,767620fd,a3996aa6,1e87830e,6d2da97,5bd318f,c44ec9bd,ef552204,f3ecb761,b4541df6), +S(24824f95,be9fea47,be33b438,d855e2c,d0d8982c,2d8a0b0b,d84bba5a,eb8cf0b0,d7e5c1d4,d6c708db,a5b51a46,310bd68b,18b521b,e765fb50,e1d8978c,6460f1a1), +S(d1d2e882,62b62a1b,63ee8e90,31f37d7e,ba90b95a,3b577af4,c0bf5d4a,9cbc65cf,b88f4f9f,62ecbd5a,5165ab8d,92126053,66d719b0,9c5d41c7,539d9991,76d004a8), +S(9118fd29,acf4c565,1ee732d3,c606d374,c4e5306d,90614ae9,d5aab499,4ad300af,8498b6d1,dfa4b247,ddc437e6,cc2f4dbf,d46b4562,3912a2c6,1dea8068,c86d9e54), +S(c303d808,8f33b08b,ea8e2490,d8f4a108,27569644,9a116564,41166838,d6602b9,af7a213f,d6131447,4be0c27c,39abbe1a,3cc45c97,6f28182d,cddd7d86,ef1c26c1), +S(4f09e673,cf4036ca,6b466d49,11b21cb2,421ebd98,f336c6f,9be27aa,7dafa17f,d0b9b5de,d7517f0,f452d744,cc5c7201,f292df97,e70cf642,4879267c,160ccc96), +S(cea44dbe,7286698c,dfb48302,deeb4345,71ccabfd,844411bb,f0d63c70,626c8bfd,2cf9e22e,16dbc1fe,8f159bd0,36ff4496,7eb0d11d,977e181d,a885b200,a552108d), +S(799d8d8e,8297a1ed,5052961d,646c44fa,787ec15f,62c0ea1d,13ba4ac0,3b42dc4a,9ac6c9fd,e28c5dbf,23c76484,6ebae2ef,b4cd7e57,592d6608,9ca6fef6,faf148ef), +S(b7630524,9472c060,168677df,775b6696,97f281b1,3204908f,dbaaa74,b87d555b,5b157540,7c35c69e,9537a1e9,10410d6b,9c6d461b,9a00520,f6850bc8,9628bdcc), +S(9866d83d,7d9fe0b4,8db8c7bd,557326db,c74d757c,d0f063b5,a05eea98,7847758a,f664b109,f96f49f2,b06f3886,4f7c7e99,de8ac6b6,ec08f946,3855bd5b,c74f512a), +S(6b5cf6bd,565f780b,ad85093,3da4f5e7,6a168a5e,bb3c4658,c9ad6945,99ac1d0a,210f9b03,96d9d3c5,f2fd3ba1,a889cbaf,fcfe0bea,af2771fd,c021659b,835e639f), +S(1164bba1,af12b041,55796a4c,d5b17da4,db37470e,782b7875,ed553675,201d72e5,9f5e04a3,3b913c09,56e72111,bd99f2e5,1de13c2b,f496b72d,3b7bf9f3,42572d37), +S(ee09a791,3ddaadbe,13b1b198,a3e4e63b,5cb2f591,475827b8,1f9b81b4,1449dcda,88fafeba,bdd965bd,19bc434,8447f3b7,91de017c,3f89b292,4a6c6f76,839bc6f4)}, +{S(da34375c,e38127dc,cc88a823,55d763a7,2dd5d733,d9bac216,7c3e621b,ede529df,13426579,db1353d2,8095e1f2,a007904d,5c04a725,2c621ce4,41157aef,d2e28cf2), +S(a781c07f,cb52597e,f229d634,b3036507,c297843e,3e784024,d38b0025,72dc3009,e4fa3bcb,511877f0,8369465c,475dfbfd,e0973309,acd09a80,a9d191a4,e21aaa84), +S(d879e837,bb9174e2,19108746,91cbe6a1,9e19efc6,199464d5,2c9ba4f1,d32fa31f,e092c41,35550370,40c786e7,c3d5f72c,6be6988d,441829e3,85b1bfc,f1f00bd3), +S(9fe2fef4,5f1c5e21,110aa61,ee83af2d,2d409120,c6e510d4,dc2945b5,936c8ff4,a1d3701e,26007255,f4b8db48,bc6ef057,a7c146cc,ff50ef2a,e5f8d868,5a684a4b), +S(f2266efb,749fdf5c,dca22eba,8b9d8141,4b8cecf0,1bb25dbb,85f6e3fe,d88e55c4,11acf31c,ad2b4ab6,f3036259,a3b54bdc,6b8100f4,36bfc1ae,a17ba08b,8fdb8bf5), +S(527063af,4e7ebc65,2d45ae2c,e2149c26,f591b12,da157351,bf8b97d9,d998d007,3cdb282,740ff232,d9ac9988,8f0c20dc,96476b79,133af243,eeb01413,54c71ec8), +S(aa067591,c038a16c,2bb18b54,c6357140,731440f2,2b972152,d08726cb,f5654abf,81e8b530,a4997fd9,ff4122b8,b559c6f7,915b3d08,96ecc8f9,dcf01aca,f1f4a61a), +S(7a147e92,6e2b916a,c23e4fa8,d9349aa5,449e65fe,c52f01cd,a7be7863,fa2a1bd4,d13d4e2b,4e64a8c7,824b3051,e277da45,fd947048,ba7f9f09,6e6a6189,f6ae356b), +S(394773be,c4c8587c,a330f243,5ac5057c,f833333c,4693ed63,3d0e780,8d31dfdc,1374bfc8,7b1a7ad2,7c119dbd,cea325b2,c663aa4,18e9f62a,d5cdc878,88c8874e), +S(a1b4edda,14ce5c2c,ed276886,5a3a1519,ff2b56e0,f0e06741,613f7b3b,37d001b9,e462525e,6a1ca74c,be1e0973,139b2f1f,2b1458b7,dacf6f66,cd80ba4,1195516f), +S(a2a20ab,b8cb4a84,9625000d,a2ab6d80,6a2006d7,6994069b,2e50c83e,4aaa183d,3850f9d7,bfe1c1dc,b066f603,8a71f78,352d4cfb,44a7d646,81b86a7d,23b0b468), +S(d66412ac,30ed909,4c282dab,c40624ff,7fc5a593,494a9be2,954d0cd4,961999fd,ad6ad3d1,e3be49b5,402880f4,c67d1546,7b6d01fd,63e4f45f,f87e5901,7b8445a1), +S(ca666365,71fad850,3205e1d3,6c0b0062,9a6347b9,b9ad0a92,10ba208b,57fcd0e8,821d0dee,efc2bf47,4e575d10,83d63505,67235026,e50d9fad,541fb097,2cb196fa), +S(310184cf,7c38bb82,b04a80a7,5c4678a9,985336b0,f60acee2,2a048e87,bfbc6970,4e21334d,6440e46b,a12bc971,31d55598,94ec8648,ab901a94,c757b957,662b41f8), +S(e051316a,62329ec5,add4bf12,4fe30288,dacf5e82,b0977184,7c64bb4a,8c77802e,3358bcbf,94e23384,c9be2d87,79d56ab9,cc0fe4ce,23eb227a,741a3be5,3fdf36ad), +S(1dee1a31,e28d970d,11436760,7861cd75,292cfc9f,533197b6,7ce40e8c,62db266c,7f9c4f61,f534b388,7f00bf73,469601c0,9c6971cf,3ecbded7,63560e1e,ccd0e32b)}, +{S(a80dd274,9cb3c40d,af91b91f,6e8b0850,27fae17,96e416fb,8a172c27,d39e8789,466161e1,e9519ac5,e1b03652,cd1ce6cd,1d7dc696,aa59ab5c,565d822f,af427896), +S(493c8d4a,8a53ccc5,67d531a4,c833a8c2,6ebb3337,9f1f2330,9ffc7a5f,90ad860c,eb52116b,e4f5075e,e391948e,d7970c28,ce156e22,cd3e5820,ed0158a2,1158ea73), +S(42a51205,5158eff9,ed9b2df3,3f17a809,ddea781b,b0cad4f7,5ee9b16d,f03447e0,4b305c2a,987f11c,1700cc3c,b09914b1,cb30379,257c122,cab089da,b0115e93), +S(eeac8ba6,c3397ecb,ad93a0b5,1cbc9108,29aefb53,50a9bb5e,1db9ea58,a33dcab5,e0eaa01a,4596cbfc,76f418c2,6fa382ab,699e8ea6,1b700f76,98f5b913,da774b70), +S(33e903c6,ee45628,db06afde,dace17e8,bf8ff9b2,a4d1e3c2,c43ab4df,693d71a8,a9abf657,94edb2c,80a50e5c,e210f39c,fd37ce86,5eafac01,65191deb,adc9f379), +S(4af6278d,2c4ea624,c4a7c264,5fc4e5c3,85a983e0,1f5c0c2a,bab8c101,8ab36425,4af48c96,64a8e40e,33812cf2,6a4495d9,8bb7bc4d,3455e03c,21ed94f1,e6fcb069), +S(2855cffe,89b73f36,c4851fa3,92ffec8,5b7b4c7d,83998c67,ee8e710a,473c9f72,ecd7c273,c26c1d7,4de7bffa,6bd26a51,cfbf9716,7e9875da,cab2e632,25766e83), +S(1b06d384,d0fb68d6,396314d6,a6f12d91,3853306f,1a904494,24fb2c2e,d73e88e,3de9709c,cfb21234,f8d687a2,e6364caf,74ec05e2,82245cf5,9fe5d37e,e7e3e7b5), +S(cef34326,559a1922,ff354887,54a1bc1b,72d70955,33591c3a,9a2b871d,8845a9a0,aa2a7c74,6a149ceb,b276bc9f,860a96d0,285e9a46,d62b2c15,c9a78701,7cdba153), +S(39e39d53,d9c619be,c9204156,1c8dd8d1,4f5cba0c,94d93295,352c8448,d9ab988c,56c6817c,a33aabed,d8b724,754e8764,72e065fa,357917ab,d9d03199,4c04c3dc), +S(28cf0dcc,2765d3a8,ae99c40f,57d14adc,5d21e730,271f2465,142c5369,80b21878,908d84d6,3774fb34,774931b2,12530d35,8565392c,6ec35541,1cba899b,3fa29e7c), +S(383ae3fc,7967167,ad6dc50d,4af64da0,f5c44be5,4ac33d3,6779a8e4,7ec657d5,11ae57f7,6ef344c1,263974e4,25f27e6c,c68d25af,3c748935,f554e4f,5cc16ba2), +S(9f11beee,fdf9dbbd,c9487b01,869a7b18,c8db78d1,36027914,bf363f,951b1b6f,335899a8,7abd3401,d2ca87f1,ca330c10,c098f7ab,cc2d0206,faa0d8aa,e7726aae), +S(34278948,b6755e7f,2faa3674,f766e6dc,5029c644,55f7ba86,34e45370,a244eac6,f6e04f4a,f27a8768,23de58c9,d2ecfcaa,63a5027e,b6c7cb1b,428a159e,2110537a), +S(44828d6f,29e24d8f,1e1fd7e6,13bec429,27a1fa28,803b1ce8,ac43804a,bc2a4411,4781fc5c,6039f0f5,fba6d3fe,4fa8cc9d,bf9c3ee0,4c42a0f1,8835ecbc,b15a2168), +S(903910a7,1cb1f65c,838f84af,a3167c3d,f396436b,1c76403a,5526344c,ecb0a948,19978bd9,d0563fbe,d9cb07c6,f88e563a,7aa007d2,562feedd,5c8fad6,e555e66a)}, +{S(b3dee3f6,cc08c0ba,5b7ba3b8,50469647,34f7dca1,630e806e,f84157e8,2992c765,d523bf3c,6b004cbd,59db62b2,58395f63,d487d6ce,31799ee1,59ddf96e,d9bae2e8), +S(f5c52e87,8142cf16,d01aa78f,179460fd,7a8d7645,498118a1,a1ec386b,c2860a44,868b7621,a41ca177,84d6b4a4,d5a5ac40,ecced5ea,d8d5bf13,e5bfa29a,5f998c38), +S(26412ec7,e11e9347,d515de0e,98e14920,522610a7,2c090b51,f03bf049,86738df7,11a10543,394f932,19284377,1a2d0741,ebd89e8b,4a0c0dfa,8f8cc5c,db7cc207), +S(8e313452,7bc65ca9,241666a8,bec7c6f9,b92f2f46,c91c3843,e430a22c,4e6a92fb,bf6e2a1f,122f4b35,aadf5b3,c03be0d8,406c0b74,c3e48b1c,85023996,a0eb1214), +S(ed72bb0f,4800c2f4,2db83b49,137af4fd,40d53e5e,d690fe42,b93d8cf4,a603d3da,4dc24219,6e195c7c,c1bd412a,a0982a97,80ed39c7,c1f34181,6540ea3a,e52f0c27), +S(a84809bf,a6592d13,47f1f37c,e7a052be,d4a5e06e,e27c369a,61a74f26,552786ca,7bb26691,5e544c06,cb7aec5,aa61979c,a77bbb52,67dbaa2d,13517b40,3ead93cb), +S(889c0732,6ba150eb,cbe394a5,3bc9eed1,1c6759b0,4f8b82f9,79f24efd,b2469dff,6c9a2c99,7ee4f506,d3150dda,71ff54f0,88d8c904,596fd99d,d2f5017c,9d72fac6), +S(b6f64c81,b5e1ea08,8b712eb1,7a7ba7c4,ff4821e9,3e68c16,7f385e5c,d5e097e5,99286e7b,2c2b49f6,2c2a5d9a,58db244,5e5f4981,b1a7f40b,b0f86004,40e249a7), +S(4b131fc,5d5c5020,48aa2195,c079cb10,8bd101bf,bf4f54db,793bff99,3c2e4a0f,a689fc36,fb782cb5,c9722f4f,8f123ab9,5fc02dd,d1caafd7,eee117e2,e58c6609), +S(8bc5c221,9248c065,b713a126,facbeb63,ef435ce,6759ced7,62e189d8,82adfb92,6663fdc7,32a65abc,8b207cad,dd72ed15,68bdf3bf,c2e84345,9f964f73,fa325216), +S(ad8ca6f2,f29699e7,c4b055c5,bac3738e,d3b390db,21512a70,c3bc452,e231722,fbfd004d,174964ff,273fe355,d76281f,b47fa1be,eae7ec13,6e4cb5ca,5e703b54), +S(12270e16,b82ac7b2,20bee7f9,8c45c6d7,87d14d3c,2e9a2201,67650e2d,c56110b0,390c44c7,4d01351f,78b80029,e84b211d,4cba691,1201864a,d0632466,ee747bad), +S(48cb4d0f,e669f556,5c7e630b,bf435d0c,b0b47511,553301dd,a9bf6e35,b59fb9cd,be02b272,e6fb4e3e,79d6655a,aa37a132,8649b74d,4ab6d733,6cbcd1cb,d02d3f60), +S(558b4a91,b01ae7af,dbe952be,e03987d2,bc64337a,8178c079,f06ee88e,88b4fcc1,1dd61340,ab7dd93a,6b6e169,a4879fbf,75d24270,b0708cc7,51552ca4,f6018052), +S(af5fb90b,d4d48260,9fc8f8b4,34724c8d,162997f2,a6afe68d,97a6bf46,629aee86,ddfea22b,6fd0c331,68a196aa,29c0f0c6,7e828768,15527132,99c37e69,f788c4ad), +S(2ba58b64,b588a995,3872a303,8f478ee7,ae03b805,afa95c54,62920a80,8a12228f,b902f3ef,aa4a081d,1260030d,44d31436,7c5a5b7f,4ccc47c0,1f82035d,af92c39e)}, +{S(df9c2e20,68e1e333,f6acc6c3,ba9928eb,e761d4b0,27eaa1de,dae18079,29705021,491f455b,6e937f91,35fe9060,a8c5b6c1,60de5af9,ba90aba4,c060145a,da1b032d), +S(17cdf19b,1f93cbf4,47e2f77c,6f4adee6,bb62f01,8011e8c9,965eb336,899d4b6b,5d5d7d2b,33222ede,aa07c15d,7f07981b,a7a80c94,d9a4f2fe,7413b4c1,dff20e7b), +S(de7b1e48,3d1e4e54,39a65ab,b74bf705,92a75671,11f83390,78699547,ad798cdd,61087a47,1c37aa33,f538234a,9179e9ee,b4af8e89,7d1f5afb,497ae5ac,8609f8ce), +S(8baae56e,4774ca16,4bb58827,896bb7fd,6dbde044,3e88eb57,aef2cd98,e3968870,7edcb7e0,29411a39,bdc581d3,3a8769da,d0bb62b7,49e2e05e,4b698b73,d77471d), +S(74bcf4a8,18f280ae,6216e44b,fa8c65f5,4de08ee,14f2451e,ab85dbb6,33ecbc27,a72d7c82,19b2307a,3747a6af,e17480bc,12fbadd9,f326a09b,442e5f7c,fa18aa28), +S(8c24276a,5f468d59,d55a0ece,ffd642ca,ad8a7dbf,bd3ca6e9,abda6a3c,3e66c01c,b7463b3b,6fddb0c,cc2b9006,a7af9ba5,346921c1,ccfd24e7,4bb2d09e,9cf78c16), +S(ca4c86a5,438e1b85,aeb79319,95bb4cbb,c2ca6eeb,22eb18c4,449f8050,f8403023,6a86b9d2,d205188e,f6bd4414,1f9948df,7d9bb06a,538d5016,fe310d53,b3a95d18), +S(768b3d99,cf1a2d36,972615c0,b9dd964f,74692061,1d36bbe,892512,5855ae6c,5e821acd,1a49c270,b589b382,159ee4aa,ddf1a163,3f00513a,935f0f05,d4174dc9), +S(f69a77b2,368aa4d3,55639610,d3a4d6b2,72638efd,4ae36772,3868146c,50a81e0c,afc09cea,e975c008,c02827f2,86b4a85a,25e9f5ad,7e26ddf5,fe73f77,edff3141), +S(4d266e6d,8805e372,2ae985c0,3f808e09,4012a97,23cde34b,cc119732,1e3eeb4d,5747f4bb,38eb2a19,74315a74,7fecf1be,2633e3b6,93a6571a,e08bc2d6,8ee984ab), +S(6ccfa6fa,a5bc8629,10cffbd1,c7815328,bbe40716,62b6e66f,3e6db1fe,d796430f,1bb21cdf,c4aeb248,454a6e96,e6399a56,e872effb,ed3c89b6,95d52598,6b801367), +S(2bcac4d9,ad3f7bb,784ff508,3ee24058,871f92c6,db50cefa,3d84707e,8576c271,c2faffb2,f59066f,1ef1e186,3510f9d8,236d9d6c,37a9d5e2,9dc1bd37,1a349074), +S(4ab261a1,8413f27a,328dd402,4dcdc6fc,6d31d071,f479d8c0,f1857f0,2ace11a1,e53ea413,8cd3ff01,21acc725,345ce814,a6739aea,e4600dbb,258df68e,9e3dc4eb), +S(7c276455,398e6e95,45e253a6,b6381d74,1cee69cb,214686be,a81435d1,eb90c86,704bebf6,c434161a,66db20b9,5c859064,a339ffc,35510e49,bc378440,f6794d09), +S(b3a041b7,cf5e1d80,ed040d11,851e5e5,292b7a20,b125f018,979d2853,4e0b2d6,f8f8767,5801504b,98013371,525962f8,d40b44fd,d54862ea,4bd33629,b34deba9), +S(d10e348f,403ae107,5ac0f8af,b81b17a3,aa0d51f9,2cc8d271,2bb2d4f4,cea9a881,5fd767b,30135e1,418ee9b,b83719e0,5f99c3a8,87733c13,695dbdce,c1b26ec0)}, +{S(afdfa934,6f7bcc74,ec473e17,f5048650,11c5251b,bd6c0c70,c25cb561,4b004da8,b16eec26,d575cec6,b8720f94,4ccdddd,78a5c446,a0cf286,fd933f6a,999a4a39), +S(5a4fce51,d54d54ba,b8148e3f,2f8da91a,50c5a4c0,409be13b,723f3ed,7879e1e2,5ae7c52c,f602d6d3,b68f6989,f6e7cb97,484de6f8,d729dbbe,587756b8,cc8b2d1a), +S(53831467,eba14563,3181b826,839812e3,36c1a17d,ffe4bfae,f2baec53,ff428d8e,fa471d8,73ba000c,8d23b0d,6bf79d36,f57a7852,4aa8c52b,227fc42c,400b4fe9), +S(ab384400,3f19fcfc,10055f6,290a0540,cf2242d0,ccab8a4c,40319440,54f0aebb,af368bca,e17e62a,ec0a5544,4d65ecd3,a497306a,eff4a439,92e7d1d8,ed5495ea), +S(ed08f215,50f6510e,e8cb5e09,53ca47a3,9a140441,cd7dc8ac,2c319ca8,cd51c781,39e4c088,589c9851,b78aef9f,33678f7c,ed46d4a,658ccf49,b1c4de72,9fe3b64f), +S(feba0c3d,930d3c71,d2edd2e8,e63e5f67,3f81ea4a,5f8890eb,3fdc6e6e,9c729830,a507a2a8,a0fd3d76,214f59d0,cab63525,54148970,7cd0ae2c,6488efac,7d494d99), +S(f5da1419,be3e268d,b51dea4b,af8867f0,a02a29c9,599266e6,e0e37b,d569d8b,1ecd596,4748be32,44cfe953,6fa9ae30,104b1e6b,8ccd69f4,1e5891e2,242db1c8), +S(eaae3a45,5aa38fed,381ed64f,b6353d0f,2236d267,97f5dc1a,4e7a511,1654be5b,24f1dedd,7f3d9cef,572e7819,b09be2a0,de1f2f4a,6b2314f7,57a81b18,cd1fdd08), +S(a997a9f1,e9fb824d,768fa890,b91ec55f,c851127,5c16eb4a,99577fe4,87d155e5,9cf136a2,c3fd76f8,d4921bba,9d61917,b6ebbfa,f55a4cf5,69665d47,bce7a44c), +S(f20287b,958ffe72,72d443cd,de9fa6f5,f9ab208f,a74c6147,10c44c33,3777f1,ce614f5f,87c3a366,65d7f574,5446d80a,35a8113,1fb4dd2a,aabed948,b9e09931), +S(f9fb85f3,fc4e45a1,6b6eef55,cd8656db,de777390,f20b576,a28110da,e8ce5713,51de9f5a,7b2f0101,cd02e6c7,c98cdf93,a430d62a,1fec4f3e,95bdc3bf,a2212e13), +S(d5fa0933,f13c1f4e,89caeba4,101f44c0,420da5c6,7bfe1ea9,66cf01a5,ef48b1d8,5efc8918,8b9eb65d,faa6e0e9,812407ef,35d8db,76f9e722,ff63bc3c,3afc3b1a), +S(93899e6f,fc291a4b,e986f938,b8b378be,bf4c3d35,f9a1bdd3,ecea5f04,d8f4bada,a19a2983,55cb62fc,43334649,1c89f26d,fbb67bc3,872f7512,9229cb73,d126293e), +S(8fe07488,b5b173c,d530d796,a18eac08,80164c2a,ed787b05,90ac8dce,3bb120d8,829abce1,43ea8009,e4f5f481,125ca6d4,ecff3f32,577cdbf1,c054a23e,67f18b0b), +S(10c3b093,5461407c,369494a7,631eb4a2,365b122e,ce0a6b95,7c1bdbee,387394a4,f09d69ec,925c9a43,57648509,f7db85a9,22f609cd,32b400ce,3a80567,88a74627), +S(cfe48dfc,f5566fbd,7562ed68,576a7911,baef64f0,dc63e158,1a29bf23,3e1a058e,440c6051,19f2a948,b4b6c3a2,7e711cea,c7983d7,f4a2db9,537536db,fdebab76)}, +{S(53d772b6,b18211f7,1478e9d3,3a0c061e,2d232358,44177867,af91508d,e014f22d,b2e85a07,8160d31c,3ca32d9c,ba025904,1bea0368,d9eb13de,8af8f505,73142ed8), +S(b9d6067c,fc26ba4a,1f5bab8e,d5f28ffc,bb6bd6,b61990c4,1b091ec8,2cba973f,532d0ab,7731c02d,91cc7e51,71b625b3,af5a605,d92d02a5,fc4cee4f,afa09ebb), +S(e8a93ceb,3db0a4a3,9a3b768c,700fb504,652161e0,4a1d4d92,df52cd4b,83e65e38,791b967f,22543fea,9ec38e5e,a14a94cc,9d11ea8a,73ca0c13,e022d53b,f8bf1148), +S(ac6130f7,41e1601f,5a92bb75,90a799a8,3e8ad9c,c911ed7b,7dee1bcf,da14f332,97ea5d16,d5c7e368,c7b97c2d,7283cb03,f215f79c,d1d80276,6f9923e0,ce80ce44), +S(ac34d4c1,1d2d4ade,2f044e88,6b57cd45,c1b23550,538059c4,e9855077,4132643c,7191e155,aeb3b578,6b55db41,652e8af2,bac1f933,d6f62723,808c6172,bf0eb0aa), +S(a7c4bafb,f1988992,1ce15754,187d41b9,eb653dd,bc97cf05,ddf449d8,c9ff734c,ccf20733,da4aab6d,81db8d5a,d3f12d1d,9cbc943,8b92165c,e83c5afa,5ee108e3), +S(c04ba857,e758fdb0,29c02712,1671fe33,9b7184b3,50ad952e,9d234681,43f7568d,9ce5d9ca,65f96b76,b4b06f57,f34de7e3,c64a1d21,f07fd6fd,eb7d47e7,bbf4e6c8), +S(8230e7e7,81259e58,e9b74a49,340733dc,252bef7b,5b7dc82,a4e99f0b,2998ba67,9c71921,3b3254d1,f53b4f30,d0a8e665,186e272c,d0e5d316,a7451eb3,2ac8bb3f), +S(720c2f5f,6465d38d,3916939f,8d095657,e547cc5f,849f4a41,30485b1,2d94b5c7,8635961f,5f74d176,e4ae0ec6,e4b3b394,6d5b1766,fcb902fd,9f9bd982,2ad4e4c4), +S(263b45ca,b3547cf1,5eca4381,3d1c402e,5c209d3e,34a288cf,182aa4a3,f04304f,3516b1f3,524bbdcc,fddd94bc,fb86a43a,27a7a78a,fcbbefdd,6692fc21,87364438), +S(4edb7d61,a45ebb51,1fb0c220,6f16fe60,5a202976,9007c3e7,11b94889,a983d0c8,b482fee3,fe824b1a,3251cd2c,3f38ab4f,adad1fee,d398be92,58d2c81d,79b0eb36), +S(f44c286a,b8196e25,87c225f7,2091db05,e47f18b,5b9a0b9,79d2cd3b,15441767,b7aa2018,5925845e,661ad980,a6c215d5,fd7072cb,46010930,ae64089,4c8a0af8), +S(593f9bdd,b246bd1e,19eeaafa,17e348e,5199decc,8e63ef68,ed8bff89,bdffad48,5201d11f,a4ac67db,dd66fbaf,5c2ba20f,8bb1a6b3,18cdfbac,6b257aa8,d30dd316), +S(823b4c96,8be9e125,262d52d9,4aaff240,55def10d,6353a347,e4248de0,7889ecb2,adfafa7a,fb1c60e,e7fb3e2e,73c66063,5a9e97e0,4a38a120,b7a81f17,7d1a6c41), +S(8daef78b,c46e0f5f,858fd74c,68be31bd,3b474d9,6bd74deb,eeba69af,5ef3056a,15db0684,bb6d4e7f,b135a4ab,f4b81d4a,a9fc7e93,c26e3616,b7b938da,25d44a06), +S(2b7616ca,eb608427,5a14eb53,b67a2ee3,b831fb55,6f63e0b2,e01650f6,e6900a0d,915e7dbc,62f8e349,8ffdf22d,d3604d77,bb701137,b6c36543,84cce993,c4613ca4)} +#endif +#if ECMULT_GEN_PREC_BITS == 8 +{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), +S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), +S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), +S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823), +S(b692c750,d23d3674,c351e3b7,e1a8a87b,14a5df81,852eaf35,209d0ec5,6e22a2cf,b18c4f17,252db89f,838de32f,b3340ea2,bb961a39,54b38c47,f9a8219c,4820a0cb), +S(691fc741,80e75b55,47b375f1,1bf60abe,451d27de,1743a436,5f8e4bac,ad421c09,8eb5fd9d,f3c03240,6cebf370,8125955f,bf2ef703,475d3fd6,1a0291b6,69b52d9d), +S(703b5f14,a7d82473,1196b52f,ae9ca8cb,b245b004,7a9928d7,d0c42f33,391411dc,5ed74eaa,49f276c0,4d61f31b,6da4137c,bde5673d,8e3f815d,efea7951,f88585c), +S(29b8ec47,d241eda1,e51bbb1e,3928444c,3747b4fe,7cecb365,2bbc4587,2f504875,88693238,8562f8bf,f7d72324,62ebc54,6b93a95f,77936b02,eb1cd6a7,d4199bcb), +S(444a07ad,e81916c9,32bdeec2,21c556c4,6b7f6491,e99b479,2cfec82f,4ec17910,2e084c2f,eead5200,77c151b6,eff9375a,713b9d15,5306708d,b3f538e1,8eb18cf), +S(e0dd618b,226ceddc,f560527e,20b4fe58,e5fcf28,39911ea6,c3e8a4a7,e15f9121,a063a157,3377bbbf,1b9a5ebe,afbe11aa,660c1e65,df1392b8,97205858,3c86a3fc), +S(9b99461a,2e8360f2,f2ba0bb8,bcaeb699,159e0652,69d9042a,fa0c4e30,a7b6f30d,3fe7fe04,3cb45303,3d4f5560,7d41cd76,9036a49b,82912350,6d8b9995,254154fd), +S(504da3a9,d9d9c81b,c2065398,4ed28cb1,b5beec9b,6ce5dfb6,cea94e54,fdff044b,cbd40d1e,858133c9,cd20b9e4,ff9fe94,f7cc9579,39e6df49,7a6bd702,797f96cf), +S(ddec0aac,1ebce6aa,ad6300d5,60f0e503,829f0bc6,479641f9,b19d9f6,484376fb,332ff5b1,fc83085e,736736bf,3c265e4c,8f80925e,6f38479d,6563bc34,e5faea1), +S(dc530ceb,b82c246e,41c522f1,d2571d31,4b14edf3,91577a2b,64e42172,b23562c1,563ddd93,857d6529,8b81de24,19e5cede,7a4c5b7,a2fe98f6,9efb8906,6f32a98a), +S(7604d60f,418dd132,78058942,fb2d2153,c0a2bfeb,e83c5011,a451bcb1,58db0773,38be14ae,d9e1c404,63ef92bd,d62c599a,b37625a8,182a3763,4fa2de90,535d50a9), +S(cb896744,77b20829,f5e2bd42,8852c70b,91cbd0af,cadf219,a69727b4,cbec8d7a,5710d17a,20ea0dff,980d3f06,38d8b910,b8940d00,dd4a323f,d777d942,213e1093), +S(501915b1,391e083d,e88c795f,8464c846,f699a79e,edb1b963,3e29f71a,9ce4d022,9e1dcc94,17ceb0e,15762f8f,7d0db85f,3bce3ad6,fecbe2c3,567853ef,ccd6d0f9), +S(a63c0b8a,4eb2cb10,1e556904,a7246356,9909055,f45aa4c0,e89c2237,cbffafca,9650b428,12374811,738f4ac3,a2ac0505,396339be,4eeeda8b,c35e6fdd,c51a1e56), +S(a16760e5,c3643d19,da15c034,5feced27,488ccafa,ad5298fa,6ee1070d,a258a761,736a7c7e,69db053,6f541079,158d671d,598efb1c,d75ec804,c7b2b49b,1ad7638a), +S(840693fe,73b96819,bb1b24a9,35d5dc83,f361273c,d0989e76,1edc35ef,50faf90b,4294e19b,49558667,bc6237c6,86c30aba,a2660580,563d465a,fde9875d,74c9a57f), +S(97273c3e,26e12369,1d0ade3,3aa261cd,a45b2d2c,d749af71,a60c0d15,85e18e03,2700c565,dbb08439,fb74317e,60776fca,d0efc1a5,5d0ad87c,18f82f2d,a97caf19), +S(978d68a0,5ce30528,e4db2dae,99f6a245,f69cbd04,3c7171ce,ce2bee57,60e68b9,ffef379c,1515b068,df562f3f,bdadacfb,8aabe5aa,466105d1,97a8febc,1596915b), +S(dfaea7bc,c78d275d,9f6a74fd,21fdec14,bcabfa45,e44070c1,9c44d449,c5d52231,927b810b,c2994b8d,2ed5124d,98e2f5cc,58410607,82b1ed80,d0fae288,8c42d538), +S(ca0b766b,8b8d76fd,ce471a88,18e043d2,604d1ad2,b689cbce,70ceae78,fddf5a27,ddf9e3bc,935ea0bc,22f977ab,98a92414,643140ae,be0448a3,35d6d44a,1bedfc48), +S(11dcc001,3be8d4b7,85e87153,e060d13,57cabb5,34a2c1de,2a4a70cb,9803a031,5b5d46b0,6a96c30c,b1901c12,eaa1c656,3a2f35b1,e9026954,36e087aa,3deb777e), +S(a828121a,18d23262,bce26648,ab44c45d,c5027ae3,f74786b9,598f22b3,c408bf08,37893209,80d7d2de,6074778b,2e8916f0,4043a616,982a9b61,d4089623,31375cab), +S(291ec5eb,e010daff,3ac00825,3452b065,d9f7fcb3,66e125af,22f11358,6263fbaf,4647cba2,45d190d8,2337f217,c278c98c,370120b3,d4e04110,e6df2c54,92d63bb7), +S(44735d48,4c584d70,6afc573e,8ece7670,c79c7b99,99eb0141,4a73905d,34a1cf01,30a27c9f,67b47348,583f1e84,5e7af221,438d4c9f,a1e0cc19,7312ec6b,908d613b), +S(fce8958f,507d5d59,bf0fb944,7be40c23,db2741e6,f89351a7,f29fc642,a60c7d4a,69de744b,9d2ef778,a7280325,bc699cb8,29874d33,bacc1fe7,6264eff,600c815b), +S(171a3251,bc6e72cd,630f8130,d4695e48,e0e649c6,82bdd5b1,b87c7b7c,968cf664,3492ac7,faf2ab56,cfdd5278,9831ea1d,e90ddaa6,b4d6e6e6,fa960bab,2b55a55c), +S(adc566cc,6c9afbe1,41a011fe,e121f0b9,a5dded68,fa9cdf63,45a00fdd,d38d69b3,38db9e85,26ab355b,5ed12b5e,84e795e7,7e2d2c57,24cec516,9cca1946,1d8d9c04), +S(9694e1df,8067defc,de9dd34b,4a4bc91b,653ede57,3139b9f9,4df55858,74f04,f002d8b4,3940cd6b,7cba586e,18f1616e,db907010,230445d1,a96b9eee,b43778fa), +S(8a90adbb,a8c32e,a9149e02,57bd9d24,7da8b0f6,5cd6332c,5803f83e,26a1bdc5,f7f24ef2,aae5a954,db200e45,ae75bdfd,5f4ec6d7,b203459a,7360a9b1,5ae2a9d7), +S(234b3911,f965ef93,5ab16aa2,392d2198,f5df9022,962ceae3,5e73f05e,d7d8f817,a66aa264,a24e1a5c,e9bd5ce6,164cde8,4083c7b9,c354ebbc,caac78c3,f5da2aad), +S(7d22623c,84ed234,5194c248,eb984ad1,28d2d4b,638b687f,730a3693,10f1c4ed,f97e515b,618719be,ea3603ad,7c40e827,59bff425,a8633365,c28c755e,b06769c1), +S(e210b4e3,cf3a2e24,951b0623,a83a8793,11cb942,8d679cbb,16a15718,2e6655eb,f4bfb50,43768438,592e7b75,41bee9c5,f263dc15,59be620,c0dc128b,d5e29339), +S(878c0097,ddb0f977,d75d579e,ca8d0bf1,a887fe50,e33b0c8b,bbaf2874,8875b321,a3401763,39f99298,9335879c,dd43a46e,d21d1387,55be87c9,2f486629,49918020), +S(9a6dee6,4c79975d,2adcccf2,8cbd8bcd,c8bbff9b,2811039d,5a6fc051,9a212503,9c0f3d81,5d56afc8,31de81f2,750cb54,9fd5fc63,b63e2c66,ae88dffa,cd072236), +S(3fa53681,f50925b2,710b66ca,1efa5e8f,b819c5e4,206a591f,d1492a1e,d13279f5,82a5c753,367d57d4,fdad7e9e,8b7ba625,7c50c07,10f93c8,5cb180e1,a459698a), +S(7ce51172,8f94ef7,7924a1fb,fa8b7d1d,411d0e21,65c4a1ec,e105d4a0,909081cb,dbd596d1,bda2f32e,12cdc910,2762f3cd,627cf29b,1b145ca9,dd2037f1,7daa6a86), +S(afbee9e6,d5b0bd25,1dd70bc9,e3b3a013,40116e09,905bb29b,797ba66c,16db5135,8a315473,84275d82,3c5296ed,b56ef5d9,7af96617,dc2e507,c009be9c,f3d3da4), +S(14d13a78,96bd0978,d4a4d4d5,2266afd2,e0f21ea,5c1a693a,9ed4990,81e43974,dc84f2d1,86d91fca,62ef088d,1794715c,c8dcd9fe,efb4aa5c,46800240,886c41dc), +S(7bc1045c,4960054a,fc979961,5cd7faee,5dec92bb,98b4c3d0,9620a488,fd32c35a,b8f420ec,cb5dd9ae,3f075e28,811ec9ca,bd770836,ad40371,66073db5,c1166735), +S(fa24d112,4cf21fd1,bfb06c10,9fa49f10,c3ab248e,3d08f620,4529612b,f7a5328e,c0745547,b64a0068,25ae8f90,82f8565f,ed94865a,d185a364,602e6468,277b3cb9), +S(8758ade8,745d4d18,c8f7ad6a,32fa05e1,c7a08bcf,c7cad42f,7aef474b,de02cff3,7864edbd,2efcbdc3,946dd250,6fdc2ea5,2f1626e0,b7300f8,9ef16420,12ae4853), +S(d2783741,6944bdaa,d212dbd9,40cdc7fc,2847fe5c,a6eabd45,dd6daa9b,9e122693,c7139931,989b4f6d,3acf854d,5aec897,52c69105,2c6d2586,27ef13b7,66e91875), +S(624120d8,420a5afb,64673e4e,b272f7a9,3b7f1f7b,59f4b145,10115691,70a597a2,3e055b16,ce482c12,88bcb9f7,40128b71,e5a441b,4c45056c,dca1466c,6491cad2), +S(96a21be9,a6e8b94c,7ebd4782,809830ac,f2a373fc,6781405f,a320025a,e7bcb4de,772ce6fb,711c2898,dc8446,aaa8cc7b,41608392,6212908b,705ca412,1e2c5e1b), +S(a9e2a4b6,4032f43,46ee1148,46ba487d,9a82f80d,3408b8ea,8434c521,33135ce8,c8537b6e,51846fc3,18898604,192d86a6,36ba3c36,f7ec9aa9,6185e7be,f160b5d3), +S(b43b42e9,381358ce,b8a595c4,77a9caf4,afc6e0db,1f58af55,6dc5bbdf,2cb4449a,556e4e70,cf7d1a16,9249e954,b749619c,dd87aa7c,723176b1,7361966d,2d2b6fa), +S(224cd0fc,393fb763,bfbc3c44,b829f61a,22ae6b98,22622367,2d0890c3,eb9ce9e5,97273eeb,eb71bdb6,5ac5c677,807a533a,f190cd12,e01ccb9a,d617af76,c3bef1ae), +S(6c997b99,b7349b8b,6f399b78,34bcf510,56f070d4,b501f8a3,28ef3a39,7f6019ea,370796ed,ee708852,6ae9ba78,2aac403e,5b57dd21,cc77d0e,1674d6f4,e4ec60e), +S(9c8970cd,125f1c6,1b845a19,a153ef53,594bc62a,3121d43c,e9890888,9c5a7adf,2157717c,55747f64,b8b51feb,9a6c8483,6dc4de7f,40908ff4,4e37d7e9,ef1354b3), +S(eaf2ac12,6894bce4,8862c0de,165c03d6,4c561cb9,d338cb84,17d8811d,55af309d,f9e8f0f3,eeedcb85,67232a8e,cdbcbbfa,1a3b1a67,7a67c129,f07e091d,bb82ca78), +S(8b69c681,7de28f6d,c539687d,28dd6a0,7cf16302,f0cc0f41,a340f6b,2a5669a5,576e108d,b9ae716c,91859b28,25de886,2de16591,eac5cf3d,5a802785,4551f778), +S(aec8ab4d,f8c21840,c3d449f1,cf1100ff,baa91729,a35efbd2,53ad4ca,92af4d19,2350038d,bed217b6,353c31dd,bee52f96,e1706e8b,45350e96,6c55a522,b536ab3d), +S(32b75afb,9fc485f1,744c18ce,8987deb9,51cfd485,26aa491,3dcff45,6b5e394e,c5edbb3e,4b95fb5f,55d24017,86fe65e7,9b8c20f,4e927e2a,caeb2b0a,1aa34ae), +S(a2eba275,e957dcf1,a493b7c8,6ab340d4,647b6951,f8919dd6,ee0274db,a2178016,b89cabbc,ead15406,f57f0763,9cc5e036,45ddc32f,1283c556,ddf94eb8,e0e9cecd), +S(6af5da12,7be295c7,9485e35a,e0a6df36,302bfac3,a20a4325,13e81233,142d4ef9,c7df8582,7682d324,5f7a8d0f,9d17d460,53227aec,28c1de97,23afcf52,96bb8c7b), +S(1c06f8d6,6cebe13e,7cf9ab04,12cbb75a,741a2240,6b89170b,8e11c92b,84d5c9af,cb3b69a2,7a55b2f9,ba3f9ccb,67c50502,c024e8e6,556e7c42,9cea3f58,ad5028a0), +S(a9e3488f,c2dc8af0,a913227e,9ceb31a5,171fcbb9,752d8e82,1249a152,57b655ec,e07fb0fb,d8c6320b,d64645c8,e6785457,652e186d,951e0f92,f91a7ec,171bc993), +S(9d93b099,9bfd6ee3,2919d4d1,88896b80,46f07249,f913d92e,e1c27cf0,40d47277,bac5a0b9,cc9ff8d9,b6274be2,15c49e3a,67131b92,53f7e30f,44d401d7,97f47b30), +S(dd25451c,57c2ab68,542392ca,91e58a50,dd578648,36096c20,bfa8783c,1c359a8,5fcb8e40,32265bec,f5eb02a2,f07980d8,b56fb0fc,de51f140,a1ccf391,b8928602), +S(ca0ffd05,530a0671,fe49d0a2,4a0a0eb5,b19397cd,e8f881eb,542f7919,e793b260,638db61a,bbc020ce,ae9359d,3876f8bf,5ec75498,7f623d89,c3da60e8,f84b6960), +S(117ea7b5,1440731f,403d8485,a300d59e,a571deb2,44dc5bca,20352513,b5d0f691,7e72f426,20ac70e6,2ddd8ee8,edbdaa41,e9e7f46e,c8143f29,95c77289,298ca3f4), +S(c1791bcf,7d2d5477,24c30d4c,d5e8529c,2f03d7a9,711395cf,ddc5ee69,d0745064,30ba86d2,abed8606,1e9d2012,a0079813,26b232eb,34356b08,1afe7de9,3c79eb1), +S(2faa17b5,81123ed2,af8a2393,6b941de2,1cd3d276,4ca47347,5b27703a,f9b4b401,4fab0769,85484ad2,d2352ae2,9a74e90f,7d5d9514,c333443d,8ed54283,c7634ce6), +S(4bc4063e,68d9fed8,185ee402,8b4e1bf6,87c6c73c,c21f6131,799edc8e,83884ccf,3af276b4,24dc5208,7dca3be6,a5e0a133,2c427516,7cddfe4c,ec0710f9,41c62ecd), +S(e0c4a4f9,5fa0f060,b986214,68eb0131,1162accb,ec452a6,2756d36d,8aea45d6,88a49bb7,a66866db,e6905ce6,c15cae3f,2f98de34,7bbdbfda,ab2cd99,fc06297d), +S(6892a64a,e22fa15b,c0e540b2,b75d307d,ccb20675,10ed3d59,702312dc,27882d02,ffda7d9,bac7a8b2,4f83c1b2,11dbc454,8eca5023,30829ea,f5b47a9c,befb451a), +S(def9f462,12aa6e8,3d4578a6,9bece7a0,9e91ec9,28eba3f1,54afac97,d2418785,fba8f869,fbb39c64,8613ce1c,1c36d86d,f326f334,6de2200c,93c8e1f7,bace82e9), +S(32e37792,4336c65f,b112af1a,6978b5de,bc2e2f0a,f6f0b4cd,b6cad6f5,e0d4c177,d3cd48a0,61f45605,e2cfbbe6,9b636cf8,3c8afe36,6e7c8a72,b2cc1b47,a58abd1b), +S(1fd685df,86bfb84e,8bb90216,1a6a0e14,e111667c,aeea586,7f45b6cd,3f411527,be7d8cb4,c3723bfc,f2219442,9e164abd,65258c57,68509e1,a72e3ea5,b13ca966), +S(bc7775ab,a334a06c,c284be77,8e9a8b88,358f3ebd,7fa2a370,2f7700f1,53c93e94,dff3ec2c,84f8c35b,fc869ad,76139913,c25b379,8ddb1e69,4802ac27,602f4a6a), +S(2a3f2aab,10c9e9fb,cecb54c2,c411bd70,38334230,f2286b62,c06db5c2,6b74a6d0,42497e29,37395239,c102a1da,a08580ac,54fb89fa,7f2d2974,8b4f2081,bf15fcef), +S(d5c9be7b,985d769,3d5e7b96,3778daab,49944cf9,8ba2a522,b33d32de,1a7ca3a7,3122fb41,440c3f67,478e116c,1db5b65,2c8d137b,65cb712f,9d235e0e,686ea04), +S(aa772a33,12f19258,b1165378,1376caf9,16c73e3,8b842fa6,3237bf82,63ca771d,95df79b1,ca3951fa,3df74e4e,90db4a4d,b36fd7ee,1758e7c9,9e853faf,959e071e), +S(1faa7b4b,610b3060,166011fb,6eac0337,a8cb6dfa,9e90a8bd,6a84341e,11577791,716cedd4,ce760e78,a2e664ce,baf834ff,725b4296,3e23004a,ef309b5a,662cc36), +S(50a6be45,e41dcf82,659d0690,9aea539c,10fca3da,73a00372,fe9b2db5,46d7fb8a,ffafe7bc,adb82924,6ba72ddb,776b39b6,4a77627c,d36ac0b2,cc73e5ad,84740acd), +S(e27561a,6a206e59,2a8c7747,29d2968b,294378e9,9014f9d1,26eff921,133a1e2b,bc80b28d,573f7502,56da86d3,4118e699,75c671b1,e38b1d9d,1859fb83,681d9931), +S(cd5de182,85de5152,312ddef2,10d36849,a0a638fc,4215e232,13427899,268762f1,f0a0a3ba,b9149edb,c5d6586b,b50471d1,a7db3ec3,cc94ea9c,f9240683,d4ec2c44), +S(9f51022d,30e18985,ae67301b,5db7a3d6,2165335d,e3be70c6,e4f703be,d531199c,43c934d5,39144f1d,43401b71,605b08df,1bcb8bf1,ba3ee1e3,5c591a46,12328552), +S(b014734b,7b204960,adbf1329,129cb3dd,5d9b84a3,6367e643,76df433b,bafc9d2d,56dd6c55,46cef764,574944b2,c9cca7af,7ccb438b,2ffb31c5,7faff8bf,fc21eb09), +S(43f9f9db,bee57d22,e77b51dd,8aae4b30,3849d709,d06353be,8454db01,89b4a34e,f8962178,ae383491,28950190,1a290ed,23ca986a,dd0ea6fd,861f0162,d8032d4c), +S(1ce55c7e,10453890,c9b9171a,bc0d13c6,2ff6b802,1da6c47d,389d0558,c643a8b8,3363feef,920ea3e,b4cdffee,582e91f,7a02bf41,d11afcde,236369c4,4ba76ec9), +S(b45890e8,1ec53e8b,fa7373c9,c0160e69,1d739b3d,538d70be,2c2aea62,b6f2a4ba,70901d9,5e139291,691e17fe,f0d48797,60ec6f61,245f2657,6b9ef283,f81973ec), +S(d8f16bad,a3430da7,9bc7beca,660154b0,28d44348,b73731d8,b2f23229,6188bfe,f7baf0b8,80b60a8f,575b10d1,988aab0b,c29cc9dc,66494727,9c728967,ea24f26e), +S(e74323af,218329de,4aad97b6,c57db6e9,3dfa53ac,784224e2,6b087813,6a74ec3e,42a427c5,e1c72445,881fb359,265f4507,13e933ae,f3b8b10f,b60593b1,c5440236), +S(f5dbabba,6a55736f,b0e2eb38,973882e,ddbcda9b,651a10a,abf0110c,29b6f4f6,74846161,4bd5a349,caad7c3c,46c534e5,3b7e5440,7e3e31c,1247f0ee,4cd181f1), +S(e2d744ce,d24b72c7,c65aac97,b0fece86,77cd7edb,5b2029c6,41a0acf2,8cf72009,1895df09,8d9fab64,b86a701b,efc9c69,ca083ca9,e962c270,bd7af27f,a46d6e75), +S(e4181c43,1c9c9f53,362ecfa6,685d7d28,4b0f09f0,6472a5ef,6f3f77fe,6d24e4e7,d2eb8214,6dc4bf71,dc30e935,c5621b1f,c09819a4,8e572a44,1ea8981d,191f7030), +S(ac36676d,10365635,72c8205e,af547ee7,3e15524b,ab15b489,a0c68f7f,854fcedb,71038dd1,91a1992,e0864fe8,3820eafd,693f05d8,b32df573,817cb314,a24623b9), +S(aad2148d,fd0dd61f,81456435,22d5cdc6,8beeadee,6f60c22a,f23f7183,83f96d88,d7115c62,3d8455f7,955d0772,3f083a7c,341f5bee,64aade0b,426e781,f683b7fd), +S(7e8bd881,b50374f4,10aa55f0,e45991de,737cde63,f03e8077,e29bfd8,55f3316c,244997ad,ebd2ec32,71d9604e,6f9b0bd9,fe330105,acf71224,b203cf83,26b3b1ec), +S(a68beaaf,899a89d3,4c18576d,d9041b36,a1fc14bd,bb8c1588,809494cf,e87ae7f,3ffa0192,3233f77d,f47d8bde,3fd04fc7,f57c2af3,52508343,3f7e810f,4b6330a3), +S(fa9317a6,7e2a74ba,d53ae152,6e3a8a4,d7e8a59c,a1aba4cd,ba46fb23,a1870f05,b9a22792,af785e1c,6b1fd9a3,626ba75e,28583f09,fbd0d3a6,bc9a64dd,23bce82c), +S(2f820b30,6175e982,b1951cef,551a61a4,f9595dcb,35b5f647,fe8dede3,f68e5226,d4f915ed,4f8b3bd,f7e8e0a0,ddd97719,d3e22ff0,8c24c9df,c665d0d9,c4b2e4bd), +S(eaec7330,271b9056,6e98cb0,717741f2,7957ec24,c51f22c7,c25c2cf3,db09cf24,6d6e0108,e103be2e,3f4c8ac1,4a216e40,d8a993d5,5b0e9b89,2219dce6,3e47ae47), +S(2cbcf67c,6e1dd8ea,888c2898,8f636842,ff4b855c,9fb539c9,f3a9a4c,8885c88e,4031a26,c3b13bb6,d0027967,2e1a6e1e,af5d957,e841dfc2,c396c8d0,4e816cb9), +S(9103dd8d,6265d5c6,7f50eb7f,2227977e,53a48e39,a86083ff,965f5d3d,2032a29c,6a1bc02,14930959,ebb9f967,2f9f693a,ff3cc3d8,df65af26,21cba530,425fcb1e), +S(b47cba2,cf3adf57,e6cde1b8,9edb3303,d7c138e1,b59ce4b5,a57a517,aa497285,8d173f6e,af4c0363,7486df13,3fc64826,5aa32348,24f64842,5e36e2ad,226cdc0b), +S(6d59d90,23507028,6f36a203,702fc9c9,c9936b68,b08e5025,9584e385,1410ca5e,ca676e85,cc25987a,4c8e582e,ff1d49f0,5736517f,39e2855a,20cc77f,c40a0860), +S(748fc197,201aae7e,80e01c30,ce77c315,2469403f,a3b85be0,bece627e,93f657a7,6cd7f6ee,73015cc1,28562867,44b1f7dd,33293c72,a54f3e2a,2edd7bc2,6d2aa384), +S(ba8b964e,aa862c8a,9075dbdc,a69d2b90,aeaccf05,27c562c6,f310b3b,adb6486e,6531492a,64203962,4f3ee722,1bfbfd54,c66ec11d,93a66775,c305bc6d,c9a9bda1), +S(7b3a1c20,dd36acca,83f548e0,16907006,4dee8579,1342818c,f1185e89,5f6728f4,1829aa73,168eeec0,897358cc,3c4b8d04,da2b8ed8,1654c1b6,816452a0,943feb0), +S(8e39a814,1cb73d12,a18180c2,50a5c574,4cd0f4ef,42500d3d,a0892da3,bf5d24e3,2496a20b,5e5e3dca,30581c10,cc099093,5ee51283,79b6672e,ffc171c7,3f4fe34f), +S(89bc0ad5,d0b615e6,1510abfa,6ee0856c,d3fb9b33,d53738e1,827f041b,c86547f6,d5bcabf9,f555af1a,2f365910,1af8b19f,a12089e3,21dc2053,8611c3a1,e6f6a904), +S(2350902d,df8c0944,da5ba2a6,c5a9f16a,eb735474,6fbaeba8,4fd5a58d,c2571ab,dd1bf357,ab9ac929,eba9b93b,3f311ddf,2f10aad3,18871982,2ef665f0,36ad3fe7), +S(e53f6624,70227a12,a01f237f,9ac59afc,685276e,440450b4,b8d91e1b,9159a61,a95ee3d,430328e,116128be,c17a74bd,a87b6fe1,3e0adad5,7834ad89,ed597404), +S(dbdc2b2,ecbf18e,58e352cb,aaded3,7324e063,557425f4,a8fb2a50,637f0af2,e5a80b8b,4cb5a7a,af1175b,fd62dbc,ff044f9f,4f03fb89,b768c6d3,72729996), +S(7fa717e6,e78c1641,82b2e,78c2fef9,bda57060,3d0df678,c4716b0a,55f7ca60,59bcdf92,4c9b981e,ad7b30ae,937ef1b7,63b12c69,9fe20e6b,a7c3002a,edf82d34), +S(330a50d2,1a87984c,e657be73,d2570875,75e261ec,ed17d9c8,7150d1e2,6afcaa0f,253f486d,642fcc6e,5d53b79b,8a24bf25,131a1b2a,25b931a4,fb2e6019,34c7df92), +S(762b5213,78d46c16,70251e93,2737c75f,f28e0500,eedd6ae0,62919874,660e865b,efaee12f,3b411bde,7e6e8bf6,3d875a89,68164f6a,ddf102fc,869613f1,e8bbc095), +S(717d699d,f3a985c,8a8a8562,cced0432,4b616e41,e4bd8ebc,43bc1b44,2e2f7b35,cba0f7e4,f4d544e7,6127892f,a5ef8bca,13241760,5be8e7ad,4fdabf66,e8fbe571), +S(124de3d8,54e69390,b6908c5f,c770f602,8439082b,9f9e5e5f,cbf5f822,2193611b,c9b9d896,bb1b5cab,58c10bd9,b6519ed4,a1d3be2a,39ebc4ec,781bd673,351ef376), +S(fcbf142a,a6d9930,33fd9a17,2c7f46b9,63237738,9b76572,2975407,ea8b2440,4366db31,a5acd6e0,a8bb3481,9a654233,e6babe82,bbcb5967,cabca638,e9a19987), +S(82858b62,5d2bbcc1,372e3c38,256b9b1,cf018f3b,3e9d0b70,c17d1ac0,fbf75ca9,e6543ada,7d9a8928,e3a1f6d,b8c15649,379fae57,f99dd8cc,3b096579,8e785840), +S(577b38d2,ffb278de,62ac0df5,ccb6f2c4,e8f40e5d,c5549a7a,4881831e,bfb6b71d,171651e4,7f9eee1c,60ce5d95,9e77b98f,ce651c3,c661d8db,4798372,8ba1c03c), +S(28a83552,9aed0508,34510350,14bef19b,c1f20936,3fbb447,6cf72fb4,26267c45,cf949cce,8b331182,670f5300,29e3df92,57a576f0,e5923a0c,146aecdc,2db60446), +S(621d99c7,abe3982d,889d3b11,6c992a6e,f035ba8d,aeddd4ac,d5d7b04,bbeac79f,2a6b0dc8,a6ede522,b86ecbbd,b057192d,84294e8c,385cdaf7,cc5777d3,607ca69a), +S(8c6395c0,3ecfbba6,82926be8,b6e8d4d6,cf204d50,9f805453,ee40a010,1fab3959,d22e5810,5fde2b81,b82859ca,97a05e7,4c278cfa,b4fac1e4,50e70928,d73b67e2), +S(80ecc87f,b9d4bc15,8e365e31,4518beda,7087f9e,c8086e47,91314d1a,9b37398f,6bfef3c7,8d2e91f0,67075036,385ed8a8,f3a84102,1e44df55,397290ec,68e44812), +S(22cb24d4,e1354314,b1f9bd,c7e37963,3ee08264,ea7fe2fb,2b23ebf9,a35c1438,6e88715d,9d5fe90a,d0940724,b597a55f,386bebee,5eaf32c7,6e95b2c4,d407c808), +S(285cc203,a4eb1e79,1695f8dd,d34a048d,58350aec,4fdc8157,fc1a8427,76b56e19,59cae7e4,435a37d,bd3c3f91,279c7bd6,1cc466d,b1831a53,94f7aadd,4e1e108a), +S(61275052,386f258d,28af0420,d010fa87,c55281bf,59b68b71,698eee9c,824913cb,8532eca9,645479d,9ef72ec3,6d96eb11,418f9619,b0fa95c2,c4c81c86,75a81e76), +S(84d391e4,d946c2f2,b40b5b5e,b6a57463,1adfd4d4,9e034ba1,3a2c862e,68b36c64,f3384ad6,cb7ccfaa,567a2cc8,73c9e509,b4c2de1e,95f7ad30,26be00c1,83ca7419), +S(34e2a77e,cce22a6e,849e1b21,4a6cc570,10e3a0ed,73799e14,51616724,410d854f,cfdd8819,f0af720a,a372b923,fa81eaee,c427f3b2,a29acd3b,ce6710c7,c186d039), +S(bc45065a,b558b2c6,a28b0cf3,8bd26384,f82dbb36,e2029774,561883ed,e6600bf6,22c5a0b8,3dc2bc02,93d7019,b4623b10,aea9d36a,22b04882,954e3daf,e1885b73), +S(4b92a803,94dd5669,c0fa2d3a,c4d1e7ee,8e2954a1,719d37b4,4b02e342,9d183ea8,9218836c,698a5fdb,f95e0e58,8b64ad3e,e3aaef7c,613b47e3,f1464443,a48e3396), +S(acbf0ef8,453addbb,9a4b04dc,3acf662a,d069d5eb,530d7a03,2e6a8708,be241f89,d46405fb,3c8862d0,4e7cc53c,51beead0,dffb3045,a6349fef,6fbbcb9e,cb414036), +S(adbaa36a,4fb531ce,eb084fc,e65f3397,22188967,a947acb5,9f7ea73,52aae5d9,719265f,7e9bf7aa,2d789d96,282e527b,819a252b,7de8915,f44077af,8cc1a8e1), +S(3f5a74c5,98b258ac,b1cb3ace,e55a7a26,78f4613e,b85d784e,1b3c8abd,978619c3,ba16385,ce0487ea,67932ed6,23aaee87,2debdc7a,2bd02ea4,6a681ebf,72ef5df3), +S(6a231807,3d2c0fe0,c89245f6,5dac4052,ce931129,85b83555,c4cdf8a4,f1574135,fe44cf76,f44f3d27,bcb7839f,588fe09e,c6a5aa95,d6ae52b5,8059c7a2,c6afaf71), +S(35555f0f,4fb2677e,dd12f235,2821ef3a,331c78df,3259128f,dcf62f69,85892dd0,101d97af,b1ff1197,3c8336df,bfbc346e,5c5e06e8,f11bd602,aa93f412,2f66c388), +S(d45797ba,61a836d5,13834d,abd3090c,bd139f05,dd67be2d,cd99ea7,66565756,61b0aa,ec1bba4f,6040382f,cb049126,f7e6ba72,9cc4dbe1,f511b792,32204a65), +S(c06dc164,8c07d57b,fa6cb488,1d9c96ea,26cccb68,d40d169,1890ec68,d42d584c,fd4ee4f9,16739643,66ead6cf,fcf31729,bae2263e,c57c14f1,29fc61da,cce93dbd), +S(6826672c,ebb04679,a68958ee,3f64dc3c,69248f3,cfe0f8a8,28b164ab,417a508d,ce38e638,f19b1a66,b5647be4,3ec24f0c,562a8dfa,1b278117,87f9292b,8cba215f), +S(a2d998dd,a82576d1,6933b580,40dcec80,1f12ef10,34ad73d2,de3ee13,7d632abc,e168ae1b,7f288808,efdba59e,cea51299,d65a2c92,76ee7190,3f253384,30ff297), +S(2a9361bf,67b9e8c5,6e8d7b99,ad8b63e9,e10dd96c,1ee1eb35,40244415,270d9ad6,62bd2398,8d35c3a4,dfa31c56,57d099af,e9accd49,cfda6689,a997c862,5e05424c), +S(88ffd75b,7c3e1311,79f885e8,9060a662,460499a5,b2a457cc,47443183,a3015e34,a5a174cb,7b9b9c68,3cfac8cd,4325e0af,90f61241,28a83e23,ce1344c2,532e3a98), +S(2b9baa0c,d7f27a8b,4ada59a2,cd23c80d,94e8ef7e,3bb77d5b,a45b0547,c70abbd5,657251c8,2d564df8,a9fbc5f9,74c7d388,22089c1d,c338805a,33258c8b,db692bbe), +S(1fe51134,d37136d8,f473c5e8,7d316a8a,f0c63155,815e3b6,489f7dd1,91b229fa,f0df503,ee85d7e,b3c03545,dc491cf5,39ef8a3b,68e816c,bf94d126,adfbb343), +S(1a3211b9,9d946e96,bf190bc3,3fa2fcd1,f8cc0646,45599f81,dc7f33d4,3623c41c,ca6892b8,f8452e2f,5a78a463,fb325dcb,913cb17d,1a43ca78,bf2729f9,27a99ca2), +S(a6d7f275,c3600aaa,ae16a1e5,164084a9,6f8313c9,a71961f0,3b6e1a28,e0326e90,528756c8,ae9f109c,3a803d2f,d78dd27a,a66639f2,6b1e2fb,82a683f2,9e2d7993), +S(4acb6c7e,745afc4c,8258f92e,3a706049,a8c4cd51,6462b230,1a824114,e25c4352,3894a647,436c904c,6ef52e8b,6df86e61,4300894c,e0e7f87f,529e96e8,6f20796f), +S(245fd53c,7b9b6698,89ba6bbb,2b6d5603,c423d4c5,76c68a6,9289c1d8,54bbba73,e6a65161,8e8fe90b,36705e0e,82c1728f,49277a2b,6feedd45,d431f349,c759682d), +S(58e89f91,3383bead,5ba5ad57,bcb85f1a,44ef0f2a,4cec383a,7bc4fd92,9d78fae3,56edff42,42716182,9ad3b3c6,339299f2,1b56085d,a051e990,3ed02323,d9ff64b7), +S(e2f35afe,b9e38b16,a29a8452,a17abf93,36a82282,9fd2a726,efc2160e,10e7999e,3a19d922,d2d2b57d,927ae73f,80c7e1e9,40679fd3,fe34b4be,c4c2deea,13d94979), +S(558be465,de2edf0a,d5b7294a,69703376,7a96a366,e7f789af,3b93743f,372f5e1a,9dfd35c1,d1670bf2,e8696fac,9405330,62a90b4d,b4891986,9c8f98f3,6c586880), +S(b49f1db4,206a93ab,9ae73164,6f5364f,7b261d88,3d025764,b2bcbb90,6fecef01,7c81be22,2a77c149,14e48d26,bc81bc9c,2e10886f,2dec7f4c,1e7c42cf,d87c5f12), +S(6cebe305,dbf61912,36e37c34,31029ce7,b0059546,d5984f3f,c6d3b7b8,804d2cad,5e88f74,fb307758,6c7b9c08,ec2697ca,1360bc21,f453688d,edc82cf5,c96f16e8), +S(4e60a6c3,684a0435,99435fd7,7ce52576,aaca0b9a,e2e5ed78,b4f64044,ae89f6f1,668aef77,3c0fd526,e9b7f22d,55baba05,99ead770,442a23d7,fa0bf8e7,75385b2a), +S(d184099,4640c319,9a00608,aa1d3aa5,9527ef7f,46a08f26,3b83fc46,a10c0941,f7f89233,55989992,7b844a71,1f5c866e,3f4c981f,4cf6f190,fcd4846d,1d83d63b), +S(958627b7,214a7133,55521887,fdff08d4,64c66531,3fffa310,c53e74b,89194aeb,93ec45a8,e0aebea8,378b1c30,974bdcd1,4e7b8983,c8138c7a,cc85fe02,6884a91d), +S(7d0932b,5d8cf465,ae6917d7,450e9b59,da57cefe,dfe6665a,4338cdce,71cc6c11,85c5b8fd,757613c8,8ec6b250,3e15c412,4ef2ce44,91b7eaa6,5d512740,4dfaa142), +S(c8ef9918,55874f19,efdd5720,cfd9e164,ae2b1f14,ee745c4,1ec5cc0a,d776cca3,c0b00173,20111e2b,85faf602,cd01a186,8fdf633a,1b0f3017,682e5d65,3ba29671), +S(8a72c61b,eeeebc65,6cd8acd,8449ebe3,6f21dc8,1ba913c7,742247cc,c8c94bf2,98e7b573,2c18d201,c0faa26f,734d25c9,23411751,b03088ad,1ce102e4,5de36e64), +S(cf0c29b2,ce132664,c7bfc440,9d1188c5,33c8f5c5,643291e8,67a2fde1,6c5fa23f,fb317c50,1b3b354b,18a120e9,2a639dd5,629b2125,ebb8785e,2626ff4b,4f538e02), +S(8c9dc0ee,20f7cd08,e9d1db3b,a4569a43,98c3845f,7d02db0a,cf6f7863,111fb016,445b117b,c7b1a779,e0e9fea9,fcc31141,8aee8428,cc8e8e06,fcd265f2,2424cfcf), +S(650c7470,6f2a4225,eee93622,69d261ae,e18117dd,ae23680d,15c77d70,15f373df,6a4fbe02,e1701051,99828d13,84083d60,5555e2c,56e7799c,b2714216,b77f6591), +S(b0b31e86,19d20877,1235a402,94a884b8,1c83bb44,8db973a7,3783267c,8494b32b,8c5dd1fe,31e86a2,c40c1490,179452da,74fd5350,1ae38c1,1e1fff3e,a33f8cef), +S(a156abe8,279dd440,2762a28e,836050d6,7b782022,2036172f,a1a95984,49c15a96,b85356b6,c165788e,3c02549a,1ea50dfe,c557d7ce,4a9052b2,41deec12,eb08ce50), +S(c2919cf9,924df70c,f1f74e42,6f1fe48,1e4aee25,fa00291a,676f924,69002fa2,19067bc8,50deae06,1ca42c6a,3e252abb,d2c7c6cc,f89c3cfc,a6e7f1c3,a6fe1b90), +S(1aa1c198,d4f76755,ea94d005,b300ad47,238fe1fe,87cc1244,8f2a632d,4c922ecc,85e4e4fe,847c1935,f14d155d,a41ee4c3,f146a4f9,d28211a0,374ad6b3,c350dae9), +S(f1e9af6e,45296823,eb5a1d8d,a41c7904,3b8c1166,30213fcb,84e2418a,e161bba4,211963da,8aeed276,f390d6d3,6b958b36,da23f1c,8705461a,312a7687,bcb9f03), +S(47b98d04,1d7e118b,765fb3bf,5d30f5f1,6ffc7b4b,4745c02f,6bb807ea,e15aa092,d1997492,7099df01,f1d64610,700b9439,83970fb5,d7123922,39d790a2,a116d223), +S(2220fd83,794eb1d3,a1f842dd,9f8f849d,43d58385,25d30d79,9b4684b1,4c5406a,74f2715f,a6b77509,d58892fc,78915244,66b2db2,df099a7c,f7eb9e0c,c4d8d3c3), +S(be01ac86,5eef8b4f,e28e15a8,63c22adb,4607c574,c26d7d81,a5b69ab7,265f7bff,675f334,bb9ba742,445aa758,c142798c,bee1cd39,ebb01b65,eb4ca49c,8911da0a), +S(1e35165,2411e2b1,d491972f,61a42c7d,62c12f0e,25441aac,e4770c9f,254ab47a,ce7b801b,910e9fae,c9288272,18557cf4,73b0b8ff,4296ed2d,6e5cae60,f48fe3), +S(1585747c,d984fb1b,b34e0ed5,9c3c6347,159309c9,1524d316,f570d257,b7c3feda,9b501cda,20fc0f1e,a7df5176,bb6da6c4,585baacf,a08fae17,9d52ced9,c1991b55), +S(33fe24f5,4f24ebfa,152a2e59,c2445f19,f1b4bb7c,636a0e64,eea338a6,5f17e9cd,b65667f,f14ae54c,2c272efd,eb2eb1d7,2f9ff4ac,35430488,30283f2,cdbefc29), +S(783538ba,9f685c0c,f85376e7,dadabaee,527eb0b8,73a04007,9d0a8dae,80fc693f,16e846fc,bdb1fd08,4e7d2521,327457b5,93f42350,80b791fc,e91af5ac,8d35bab5), +S(ac1d5e99,bf673475,9c1118fe,44f0a7aa,1989be05,e117d2b0,d9946510,f932eb38,7a81d87f,aba5a37,9dd319e,793c2a23,e079c7e6,6dc272cb,5d787cb8,2ffdd6fe), +S(f65dc8ab,c670e7f8,753246c8,e5273670,d12a4ef7,a3296de7,3bbeb72b,20093771,6a4cf92a,7243fe41,9c6ded92,d51dc607,7c82ed58,60b98aa6,51614266,f9a2b8b1), +S(bb076bae,e9d21b2f,fa004ce5,e361f8cc,773b2d50,cdeb92bc,5ecca796,f10689a1,121a0fda,f6192c07,b2a734de,9d8b8bf4,609d2722,8b0818e0,a488f83,176303ee), +S(4eef5fb,85174419,7659a95a,dbb4d472,d418a8e1,db93ca1d,af6ba2f6,49ee31c7,91c54af5,7b5fa5ce,8e7c3ecc,f90b2e28,33a969e,e3f5bd30,4808e89,f25dbbed), +S(e3473056,711af387,2bb63d59,c92817fc,16c97b7e,33c1173a,df11633e,2984ce45,816407c5,3d1debd3,ade1d781,d46f8b03,2aa5bc05,e3c1bcee,5213fd50,c39b6d17), +S(f2356e97,555be224,cac10a3a,c6061ffb,8a67a77e,1d97f011,f86e7594,2ba2665c,8f5dbff4,a6ad3bba,ca27c595,e2d1eb67,e0f752da,817f2e1,5e27b9f2,d6b955e), +S(1c1682e8,1a4c6d19,dd01945a,34f096cc,1854dfa7,fe42af9a,b523f7fe,cc20b8d2,a610ef90,190b3390,97de87df,10d01c94,4a76610,6d8c7736,87d2b863,621ee297), +S(53b1dc92,d540faa9,c67410a0,901871ee,eb96beb,6809aa96,545b02af,e2cff0da,2132487a,616b4084,c2dddd4b,fba075b7,66607859,4d328d39,55c16060,249b1f23), +S(36623f66,417edc01,c4a43dfc,e97573b3,f14cd858,a6fbb2e2,54ff1df8,21dbde93,88cdd6c0,b3872cf5,9921d376,9eca93f3,d5985f2b,ce62d132,18de4cb7,f6ebc27f), +S(195345f,132c5c5,4f6e1bb8,52f1f76a,a7ca147c,e347b5ac,fada9fc2,f90d3592,2fb7f1d0,23f0fd8e,9ae691aa,3eff2832,4e6b4390,e42d7129,246f14a2,902797e4), +S(ef5badac,2143e60b,adab5ccc,a05f222d,426e0768,44e6edfa,4eba747c,8ccdc909,afdbceb1,62ee5237,f55ba6,71395f2f,e4429a2d,6d0c007a,30caf51,a53b29bf), +S(3c3dbd83,bc2088fa,65a9cc99,95ae0fcd,8a065e1e,9b8bfd2f,7c3a76e9,72305688,336470b4,54fad342,fc51cc10,6a88d82f,6a8ee961,46aeae6e,19e9086e,79325072), +S(1da4f2e4,af97ce25,1fb180e2,c529fe17,c30b318b,53c3b252,53d8feab,21b0a0d0,861cf8ca,7dced920,1e59735d,11d39947,fba5dd1f,dd507a99,a882ba26,6e468ff4), +S(d5bc320c,8618b30f,a9305bad,b6b1ce9a,f5fd055e,843891a0,b0d2fdc1,5fc51f54,cc8ce071,7cda58db,25628843,780d083,625d103c,daddba16,ba751ac4,5e3f281), +S(f5b3f6d2,9939f586,2943067e,361a7333,ef49ca55,70df45ee,e716ac43,cdcc4e16,7e522add,4cf6d92a,8b77292c,b522dcd2,1a456120,4b0abb2b,614351ac,ca1fe517), +S(e27f83a0,f2b76455,1e24d358,d39b946d,63dea7e8,5cee08cd,13762d43,a3b05654,fc5375a,cbc0c518,bf3fc169,3170f204,67ddde21,7db88535,74b6bd8f,4c677f16), +S(196b36ea,4d552f6c,eaa9f749,fb5ea209,92cbce07,f1cea121,9318acbc,7c87ba82,17eed0d5,1f7500af,3f11217b,b703a51a,bde3772d,d4bbbbf,1438af15,334c61c2), +S(cac69e96,84328713,e06a135a,ce0f0fdc,1812eafe,fa499993,980d2895,5804a635,f02fa499,9a54c238,4bef1f2b,89795b76,3d3e526f,aa1081f0,189b4488,1d5828b5), +S(1e1f25b3,d43317e0,623f07f8,3fb09946,6ecf2381,ab348284,8670a30c,2ac734aa,c096a239,3dd1ca24,12eb4637,1d6c3200,a5992f17,3e6203a2,4313f000,62076e8a), +S(77c7da51,12a668c1,666b3c79,966a9299,a033ec4b,976e1fdc,15d62ae,96021cff,6f3f728,9eb1ff33,e80a7c09,134cd880,9860f9d,8805c8de,e194f868,4852abbe), +S(8aa11355,a8c1444c,c1d2cd12,d613e6f,1145e417,d11d9e4f,d13442be,d7e23aec,52533b3b,1024e982,725f77e2,50e785a4,97e253a4,f816eca9,2ff20ffd,7dd733d7), +S(3f504f0b,647cbb41,74adbcdf,2d226689,5871107c,68e12cc9,dc30058,4302b841,22a53436,688d17ff,feac444a,b5ccc64a,f82b802,da8beee2,db623b1e,fcaead50), +S(3f02019c,4692ac29,5fed5e1e,5190269f,92a689c8,adaa9e24,2a1ae01b,d23fd952,704f03b1,c7c03308,70a6dd6f,60fe12a5,cd711511,41ed831d,b6e5194b,e3de6026), +S(d33fd654,d7164cb3,a1a40172,28559c54,25630cbe,e34c6c01,8a8757d9,6eae7980,fbe58168,87bf57ea,b89bd0ca,3effb305,7b8d5369,dd4f90cc,279bb613,49d2faf0), +S(fa3439f4,bb63e36b,48056dec,109e7ec8,51944d8e,d7ac278d,23e21415,7902725a,b427d74b,88806fdd,fbda126b,38ca725b,fa61c855,5118fee3,d4e1f586,e888feb7), +S(f5c58687,a83c7896,3c021e40,e25fb197,82d422ba,7df59a1a,4f56bf83,49b19e2f,6b94698f,3f286993,ad8bf70f,5ab72ab,12059f8f,bc4f7c09,e624854c,3b76624a), +S(18e582ca,88939bf7,16ec8462,91d1ac36,a39319ba,546ba6e3,b224d6e7,3b0b30ae,6d091b7c,69143704,eab7ed7e,deba296c,26688d08,7d36d70c,8540c23f,ba98b8cf), +S(a2ded3a8,b327cef6,84785264,5b9ac68f,8e43f035,fcf00da0,da97e6bc,6d36db68,31b2764,36139115,1852a944,179c86d0,955faa17,da85281f,af02b71d,ea120dfc), +S(da61911,1341a038,fc286fa6,704307a6,11cb4c2f,9f6bb51c,da89901d,cb1e0f2e,30cdc05d,69e3434c,4cf06c35,f852b6cb,e0edc7d0,a9ee2daf,d793d2f2,b2d522ad), +S(9fa4c9d5,103b0cff,2cf01cc0,65c7afcd,b02a0a9,72da4418,63cc30fb,572f2008,401b410e,397b98f7,5948ff7f,babf6c33,9b1e88ac,77455bd,9045e7f,a5489e74), +S(952c5289,fe18f7b0,40f8ab3,17bdb63,fcb610c1,a6b3a4ae,4a98c1b3,2f1af628,66fcb4fd,2d347e9,fe40e378,d3bec17f,94bfeca9,faa84789,98f24294,d3fd905f), +S(5372941d,bedf216d,2d79656d,db0afa6c,8fcff27d,7464cc2b,a53a6bef,ac01f020,79bc84c2,33f106e8,96a1130e,a841b690,ed5e6b7b,f1e1c8aa,d833fa56,5fd4678c), +S(a4d5e6a9,b72da410,ec56d24,c01ae684,fd8e029e,713f9a1e,22c660d3,30bccf99,f08fde87,df365268,226f68a4,52acdf64,23f31856,9435740,9fa06d4,564cdff8), +S(e6dad981,9b3cba07,1465007d,4b4b5343,9d548033,4896c86c,bbede7d,54c0ab97,9e43f1bd,949e54e1,57a4adde,61217640,f798775f,193cef6a,db369c88,3e784d6e), +S(dc666af6,71aa7218,bac55351,ee12b736,8a29a026,19ec4f94,b9de8b80,eb3232a,3786e989,c684d01f,a4b5ff5c,3b0619a2,d39b6543,4ff0dfcf,24b59966,9d7dc874), +S(2e730ff0,401bb59,6dbbf02b,d9fd4d3f,eb3f6f3f,51a2ba53,d77ca83f,a2acd02a,9c508012,5904059f,bffee85b,8fce1438,fd761f52,86f1d798,512c47a2,d96ffce9), +S(9824c6d3,9ae02d8d,3b59290f,99c1d183,1d5bf401,15d6834d,799c0827,853d0090,2062d562,bca410cc,3b5fd22e,497d8078,6bd1a94e,d7734a66,a5a3495,77c406f9), +S(b10e2769,8f6a9e66,65b330e5,4b52093d,caa4f57a,19cc314d,eeb2452e,60f05cff,a9729153,e267d4a0,5859a9ff,3ab88628,47f3c117,d6ae757e,a19246b5,448a20a2), +S(d8817793,68ca0437,c780b0dc,51db1f46,ba5ec6a7,566b3579,e157a421,eaa04c4e,94da7eef,255630a1,820abe8b,7d8bce00,dbe5c467,89a53be7,2698c4ae,925d1576), +S(5151b8af,bd8b69c6,e42db2e1,5876fe3c,2da5c340,e17b52bb,93170bb3,5351bc95,122d0316,55d770a2,4b493484,8fc1777,de9a0f1,a5d9ada7,df678e09,591c30c9), +S(6cd1c141,67feba0e,406e12a,2bd012b1,7dbfd03e,9bacc6c0,6fd6455c,76cc0c5c,131f4150,f7ead6e6,35e93fb2,e672cd73,7f8093a6,c27cdad4,ea4e7c75,5c2ed702), +S(e83f8bfa,b679258f,67bdaa95,5cde03e9,bfe4126,a0eb89e5,abfb072c,cf536043,a9fd9d4e,e5eb9d90,5d8a3665,73d423f5,deb868b1,7433af16,28fda09a,406dea8e), +S(afe4206c,ec19b5a0,77683c63,a4164360,54be1122,db0c0bf6,6e564087,c6ea2670,15db0d5f,75b53b77,52af9b90,288dd9a5,a26f556b,37adadad,adaf558c,587b9e5a), +S(73428153,102d29e6,6f006910,5116c7cc,ca8b93dd,fe1c257e,9e5003df,ff139d47,7fc6eba1,465f201,3d234be,a022ca08,7b981add,a5ebcbb,8704bd26,750303b), +S(424143db,9fefd615,c6a97e1e,c59c3338,f7f4be7a,def4133d,747b7677,b0227e85,f7dce798,10cbb1be,3e1a91f4,9d490b63,aa740517,3a84d96,b37867b,635f68bf), +S(1d2bcb78,17bb2cca,b5c7e058,be33a598,122758cd,92075f20,24a7bd83,7f8dcd80,363fadf,e771b3bc,46aa7a6,cba5191,3b4d04bd,e673615d,8550822d,d351319e), +S(5cfdd130,bb671192,e4edeb41,96008cf7,4ac47279,ea94487,5962bdfe,bb1f4326,9a6cb3e2,925e75b6,264eaaf6,4f56fdd8,c0f4c5d,65cafcec,5d9cb110,5900cc24), +S(52495f7e,1853e084,272d6b77,72dd19f1,4f874952,ea08afa6,6ac16764,9664904d,2bdb6597,99a1822d,9801701c,98646cb,37a1f6f4,cd503720,79c23c4e,872e3d4f), +S(d82e59b1,18786ae4,a6b227df,3f231216,f33d2e1d,b0adf12e,a515c9ce,83ee1bfd,772bb140,7f180791,25d23c04,558cfa84,9f0b716a,c0863361,819623ce,7af2e437), +S(f6dbc260,90822790,e71f8657,22df2bb5,71eb625d,ccc23d3,c61fcba1,b9b96776,c23aa922,ea7ac2fb,c88a860,cfc3d7d6,a8c4f599,59c1c3c8,aadc88e5,aca1a54e), +S(aa7b6845,88c07567,a634b1f8,2425a085,6956955d,e532e905,d6017ca,5ebfdc1e,6ce07cde,1c60de7a,ee80355a,258dae5d,25960af9,be9edd3e,dc234e57,7fba0eab), +S(68065f44,466294b3,ad7e6225,24de08ec,b910693,308f8d73,847827b4,b4318656,c6e68f0f,2e9859f1,a2d9aace,ff9b4c52,4329b8d6,12233991,900d3e23,59804555), +S(c3d14307,5a223701,4ab61635,db180a64,162901b0,cf175010,d55129ac,168b76eb,5bdeba38,2f747cb3,50844858,b161fd5e,3aa8e7d6,873cdcc0,1702d527,9c691172), +S(3a1b6c2b,145a2f30,88e3cd41,6d2a0b8f,60cf8d2b,b3960c40,9637e5d8,a316f514,d724b2e4,c1c2aa15,9b85c32,684fa380,8af93d3b,c6a9d647,bce39a85,2f568fd2), +S(d2520145,c4d27a54,ed6de50b,30fead1c,ec602c4f,a74e3ef6,31f6b88,23e68bef,7cca310f,d966d423,b7285d7d,f4d5a3fd,fb4ad29e,94e69eb6,2a60a9b4,c666be46), +S(d01ff7ec,b4d574f1,56755c8c,fd615a99,83018ab2,35826574,d94cce5a,f78ad3c2,d9d17ed,ea436ffe,fb2f97d3,58485109,3dc64f0f,5bf540ee,c98ceb0a,9cd4743e), +S(5456f76c,a9c7b5c6,42cfcaa,aa0a2dcd,883ecf8a,626786b4,4735e700,fca5111c,6b3e05a8,6ffa85d9,8b9e4eb0,72ff60a0,df87c298,c2da5a31,d2af1c8b,54b91381), +S(14542249,652e33a5,6283676b,223c3055,56196b3e,21e48607,2652f7d8,ce598e9,64e9dc13,6b8020e,d590ff06,8702f99f,91c42596,b7091969,e34f2f5,2e0cb5de), +S(26d85587,4888c76a,96a6dae2,26a6f985,6fb5b9fd,b4ded1f5,a8f843c6,7346f307,d1c71339,d7be6c76,f1a8b0c4,f047ec71,519bcb05,a25ce054,afcfda6e,19971cae), +S(7f8e7eca,e0257e79,ab2c04b6,dc045ca,363c307a,4b04ba70,c5c6272e,23acf215,fe96da11,f16d1171,9f91a666,23cc326c,57d3d453,8639377d,c6b79b63,56ff6ef), +S(4ff72771,ccd75c6,2ac827b4,e800e580,e6e4681,208d64d1,11c93258,2d188154,94e87e31,b2907d44,ee02e947,65ee5da6,f2bfd7b2,9808bfdf,dbd2825d,1b3d6c77), +S(afd475d0,8946f556,81284fd3,fbbf67fe,6989497a,481543c9,1d4f4254,75aa8d94,669a72c9,a8d0918b,a1e787a7,5b505f26,d002b417,f156d888,5ac02ff,bd29a920), +S(f5c11fa1,2912b0ca,e4d680ed,55ea126b,3c260a2e,b8fb10ef,ca21ad7e,65591590,7406281a,a8744da6,eddeeaa9,274c0591,fac0dd0b,3d7c3df7,e0f65c7f,a712680c), +S(ec9b680d,bdfb2a2b,fbd04bf7,cdbe820b,7975563f,6f0f6646,72236c66,17aed40a,851c69e1,99b77fe5,f16c4c2c,4bea6771,1a23afc1,569a8bf3,c91e4133,a8324e53), +S(1f73cd5b,34444b1f,d7287750,c213d5d0,17a8fb49,da9cc3f5,9ee30939,dedf9c0a,792fa236,514d0a6b,218b312c,c5b614dd,cf0a2960,ca13660e,f696d80a,b7faee90), +S(7b0013d7,a6c967ef,e1006cc4,3fb177e7,81cd4021,223ba083,50db6ad9,1e949e06,a2f8fa6d,b6416da5,d0b68bb1,c1ddb47e,8081a063,1422c72d,2bcd7b46,d2576a60), +S(14ee47f5,539c7a7d,acad832,1197c83,7daac6b8,6ba7a828,84cbf45c,ca70391e,7902e477,28ed6a07,80fdc510,c792103c,e4bc215e,390c3894,1a3fe0f9,582f62c), +S(fd75aac4,8e5cf9cd,9e14e7e4,6e980ccc,1a3948f7,41e0ba93,25f6d490,1d15d9dc,b544f9c9,febd77a0,89980585,9ce52db8,e1847db9,dd4a7857,6a8a9210,fb61d2be), +S(93aa7a40,c03e4e7,d605b8b0,3ac2a378,122fee87,9395aafb,4698d35d,8f7f4690,db2859ba,b6d5c89e,2fc4b68,1488ea1d,8d8905f4,a44af57d,3ef9f937,4872013a), +S(20a027b8,79a10933,519a97b1,72d77389,5b8722c4,ddc4603e,40319107,1ed4cbad,4fc480e9,fb55854a,f12077cc,dce038f9,3ec1f3ec,6a37d7fc,ec03b204,8cf9deae), +S(e0e26a0,862f4ca,96084cd9,bacbf501,31da0f20,1f3e4a21,f41f5ff4,853a41ea,e78c00f7,3dc8200,cc43d04f,6105e189,387fb1f1,47f39d71,f562d7b1,19c0f591), +S(fe7f03f7,b6633a8c,e514e801,bd9b3b6b,c4bd7790,69915720,8d49b513,8d5c6be4,74db79fc,180cfda0,c17ab6a7,74d73d28,3c9119b6,d85f3a97,d32389b0,102c052), +S(92b2bff4,c74df07,3cc3a258,fd4fc56,88f1eeda,1908036d,c0606994,92e3fb6e,f92ac36e,f10ac585,3e64a67,5e8e26d,b3cbaa8c,1670ff,ba060f19,bbf04fff), +S(fbfdc0c,41238a0b,ea6e3c4a,b09453c,2afb281a,4cfb5cf7,97f3f473,b02717cc,bce0f212,9d3407fb,c5541dfa,7d266788,72343f8d,748b7b3c,8c0cabd0,78378f85), +S(8dbba484,d9bd416a,f1e18a30,6f42c73a,cc15c5e8,49049c98,612a9d64,f8c99539,670200f4,96e34f9b,50601a49,32200d7,1d79e69,b7889f8d,ca45b13a,cd9cc7e3), +S(44193861,6c2332c3,1d35f82a,b35b515a,1cb3d754,3f83f5c8,63f809f,739448fe,ea559711,904549f4,b2986865,86467205,58420d27,46efa1c3,2ba002a2,64e84219), +S(acbc7bab,6acc8d2d,abf39739,fe9a560,d225d692,9a1f2e93,3a441173,5b766e64,e9f2c663,4104067f,5707f9c4,6a9a7d6,312bf3f5,6a851e0,d52057d,6bc296bd), +S(e3300502,a870f610,5d7b3c68,f26d4ae,bae2b4f1,2a893d74,768a6b8a,c66573af,558f537a,8838b676,121a9d0c,c62d862a,4224348c,1a982c37,6be1a255,a57caae8), +S(fc34afa3,8d658fc4,8d420c47,651057b1,3eec6863,2d3c3a22,bd83580e,3a6f8b82,96a3436d,228bb25a,fc274c5d,7f5da6e6,fcab6b6b,72ee98d3,fc293ef2,ed523154), +S(5e1cddfb,a73e3534,c0409da7,af922c43,7f9dc2fd,6f573ee6,918de501,90e448e,4b1adfe8,406274fd,6c1a3ec0,68568d0c,78132b3d,efe3a9f4,fb23a725,a4f89251), +S(d307c67b,cbcca4dc,89c680ef,9bfb7421,d2283fcf,90a07bfb,95c50cdc,f36deba6,254f92ef,5734f448,24ac8020,89f84bf2,b7e8967a,8afbc2f0,e01bea62,b4a90b73), +S(f4977bc0,e8f81cf,753a2b58,65b512c0,6916b53b,1a0116fc,a5528e2d,aba2f2c0,49fc2c15,8cf226a8,5099bc97,97b2eba9,9516ab90,1e39d462,3adb96f,c44e6c99), +S(e70cf22a,9099028d,96239342,bc94619,e266a53e,6df63d23,fb317879,cc547382,9ee3689e,f7eba3e0,f8715242,5ca1bcbf,fac4d337,ac4afb59,107788d8,6f0f61a7), +S(130fd05c,ea863c62,15aa8789,2d5e293d,3493ad4d,5f526a06,b33c4675,e02393b8,75c9776b,feafd1ea,252aea1e,5f8c8,9224ae3f,39c5ab98,98395468,6f45cb68)}, +{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), +S(deb66785,6c4683c6,ad7c39e5,deb1b8d9,722ecffb,f431fa34,9dceab3f,698f738e,bae7261c,368ee55b,137b913b,8bfbbd07,de4600fd,7a071287,47c31531,924942f4), +S(75ae3c34,5cc1bc11,46c5f13f,a1144759,d39c4d20,4a8f2f0e,bf3c313f,707d49aa,82a5a9b2,2743788,938a0b76,eeba99dd,f85eb5bd,f7ab8eb5,5f6e5334,a00438de), +S(49bd4e57,c59dc8c,c4cfb0fd,83c5944c,3591eab8,1ae90f87,a8d30725,1904fcf8,66e76d62,610cae77,38976214,20955dd7,95e47715,3bde0ae7,491927df,bf2b1c75), +S(5f3c96aa,a71c774b,754f616c,5eaca0ce,f9d82264,7dfc7c2,ce38ac7c,d7429748,8c72e7a2,b7371046,94ce5e77,521ad47e,2fe5cfd3,10cbcec2,febdd977,9872ace8), +S(43d8f72d,fecd31ae,91eaea66,a7b96a25,2c05c3dd,8d7afd20,d64644c6,cad460fb,d6a28b23,50f5a7c4,cc8233c6,85c87875,9134923,55cd3532,f888fb79,10342509), +S(cae9a205,19cb6e40,ed8c6774,7e7c52fb,5c57f1e1,56ac6f32,9f1538ef,6971e888,959e5c41,344ff293,3387c680,54c03756,1f3b6a97,a75a3119,da25debe,7acbe4c6), +S(5f96d7c7,a8409a4c,d4afd355,1139ee0d,ae63bf99,2580cffe,fd5f7497,2bed3d26,972b40e2,83dce233,190e8961,310d854c,db5d4805,e045b4ea,29414909,592b589), +S(2ed0f7d5,a0281d46,61159e80,3cd6bcd,61b1a37e,16aa6801,bbfe526b,9978bb8a,8a6d62e1,2376a282,e62b21df,238ffbad,a055c342,db073e86,1107ac9f,2f2149e0), +S(167b0b4b,c6a4c17d,9f3a2813,87bb277d,fa30bf1b,f35db9f4,b521cc53,dd479a18,32d48b8c,535a49e0,4c412b05,7e000117,271dbe4,5b7bcaa4,87a857f,b723fb31), +S(358af81a,b1352729,f824fe1b,40eab58b,23298fed,82dcbeec,1ec3ba91,21438fb2,b5bada2b,3906f17a,5f882cb0,460252d9,b11c221c,1d316d79,c21dfa73,174c9cbe), +S(ce544020,abc6a8f5,4d911c49,4d0fe111,bba24b6d,7b5f43c2,7f307c1e,1c2a36ea,2d34bffb,416ce2fa,21db1ce3,b6a97aba,29d7a45,29081849,45df56b9,ebe8351a), +S(6057a2d0,11320781,132b5de2,48ad5fc0,d0b69de4,2587220f,2de808da,e61906d9,df0510ae,96a02157,bccc84db,32204888,277d22e4,76160682,65171c77,4766ab23), +S(4eae969d,c9ca79fe,8f61dfa0,e6f3525b,12a3602d,feda122e,1109e0dd,43ae07c2,7763de53,9abc7599,75f289ec,92866fcc,486b1b47,40ea9761,60aa37f8,f7fc142f), +S(a698bc22,7cbd5730,452aa9af,2cfb600f,425d27ed,716cbe96,603d3280,df046c52,c91312c0,7492188e,bf054f37,e20b68b8,9e135946,7180a505,389da7df,7d45326a), +S(52fdf09,1413d6d3,1f64df21,17d35360,16323b0c,e93c66d,257157e6,2e2f8197,d00868d1,b08ac819,9c4e0215,a0beeab,76a543c2,6e3bd1d1,67709cf7,ce2fa4b8), +S(c19e6f2f,98a0f54f,4f61eaab,7b4477b0,ddbe2577,7e82e836,d8b71e97,9782461b,65855134,75c8676b,210c29d3,89d30beb,dfcfb798,6841fae4,56e7b800,e2193d15), +S(7cf919ab,a90c3572,bd41f673,b63d761f,60f28dca,8b3846bb,dfb13545,1ba52fd2,d474c2b7,d6e83e20,12866c01,21f17fe8,e6b36237,45d162e8,4003f04b,808f82d0), +S(455e9205,4d052a0c,9e0a86ba,83ed7fdb,b2b0c06c,eb05b995,13f6ac0e,75f149fb,12b026df,332040e5,8e2f92ea,be60e016,cc8941e5,d7972217,dba58548,f1079657), +S(e066bfb0,1239eaf6,7599d76d,befab533,9542c16f,6b150dff,c96a0eb2,bb0b1622,a8f1743b,b307f660,6ef6485d,aacd5b36,93354863,1d287b83,11eaf53,77df9ea9), +S(f4844f56,52f6b97,fae41a88,3e433286,a0895daf,4929fa51,8aa5040,da2b79eb,a6c86fa6,5c02cc6d,25b6cd86,473eabb4,95d28ae5,b71061dd,8da877d4,9ada9ecc), +S(111d3003,b086df80,114ca249,993e9a56,43980184,66ddbe4c,adc919b4,d58e60d2,ffada7e9,bf38ffd1,19cb0568,da7c8354,ace0f714,6ba144e7,90b1fe26,5e97f82e), +S(4a556e10,ebe25839,9bc4c3e3,8f4e1c1a,7a1500ce,44c38a1d,94e7b516,18ba3b83,6bd865e0,2d756729,c7560a7e,5422f19b,2f9e5007,f7c31d2f,3ef8cf86,7eb83373), +S(10b0a6b2,dc05613a,c436d0a0,9b082c01,8197ebc4,f106ecae,feb40113,1021a9a,6d6ef39b,33023000,5d68215,aa46ef26,b88d6e9,73b21752,a2bbc055,5c88dd31), +S(a0666545,df775bd2,83a6237d,8b8a7357,7c6bf0f7,5ddae3d6,4e65d3a7,90c69336,e61fd87,f43a927c,a5817c6d,20edc6d6,c69e6667,8765be4c,dd260eee,6a7dd5e4), +S(a593c02b,d899107b,6c71aaac,f7314f36,a594c892,32f5dad6,15601ce2,de916170,52fda077,3ba509f4,a1eea11b,6d11824,83a7c16e,b4227d27,fa844657,cdc21d86), +S(46d914c6,a68981b6,99e46e4c,56a6c482,f9ca55f5,4618cffa,5446e93d,f11495a7,bf913796,9dc92ac3,7d52b941,e6199412,117c49dc,8c05df05,95b7721b,66ed1d30), +S(7882d56f,8e53e827,1d51c0c3,49d2afa6,d632fe6e,344a0e4e,c467ee9d,7399b953,345ace50,4127be13,989c4d7,38f00271,a3ea7d8,720ee6fb,82de9c1e,3873f95e), +S(78c6fc9e,571e02b8,f8bde2f7,9540fef,452fcf4e,2b6e7649,3748f594,aa4d6cb7,e7f5a947,b486be05,ad3b9b02,1834b360,ed8bbc78,6013f58c,dca02885,bc8f36ad), +S(562b2b02,741d8c65,6f457bad,56d7bc25,75ed4ced,46577b52,d8b35deb,e8a7504a,17169453,9746549d,1674a55c,2bea12c2,56074f42,91783f5a,59b92eed,768f4095), +S(81f3c319,ff4e12bf,9b7cadc1,75712278,eb9b9275,87df662e,a72fd92c,7d79232f,eb6ce068,131ac2c1,c31a19ab,9aae0633,ee184235,62065a31,59d978cc,43523b6), +S(8ad3bbb4,dbabc2ea,222d818c,6680c029,b0a11a15,7c175165,69a2729c,c4ba1608,65c3812f,9f645537,fc6cd8a8,94279c10,5eabceb,dcd21eaa,dae4784f,69db467a), +S(19bbdb50,a8ce9bc6,5dfd3006,3508bc23,528b3e3,e0615529,1ec0ff71,6a6b708c,75f8a65d,a25c9020,e1b3e26,929e67dc,9edbe8cb,7ce44e29,a3c2be40,50c3370), +S(8866249d,46d790ae,276930f0,8bfd2047,658cda45,ace08344,5d254413,502369b,41547dc4,2fc37c54,11d65d1c,83df2e5c,31285530,15b51106,155d7549,5e04e711), +S(b18db2b4,15471fbd,38648770,8075b1a,7244af47,5a4099cb,ecfddd0f,18bde801,1a2c7d97,23352c93,373919b,a28bfddc,1af8d2b5,953a7da8,2706027f,e802b77), +S(dcd6a63c,70380948,dff9993e,b163a6b2,54625677,5981c03d,16b7b46c,f0b05bd3,2db2651a,e5adc2ef,f2277b6a,d59fa0e6,d6975fc8,14c0c4c8,192301b4,63fc8969), +S(c66261f0,3bc15a7e,2b7ec26a,9ff9ad3b,ccd7a005,b7f9eb0f,f14dc9ea,64b66a24,975f18c,8eed73e0,c2873945,2fec446e,eeaaf732,c3406add,efbbba5c,8ce72236), +S(1ccedbbb,6705448d,9f5a6271,51bdc2cd,e4f57a4b,ac283514,3de7f244,b3fe2593,d58f089f,588979b,a8dd5e1e,e1f2b1fa,26ed488a,9b7ff553,4d4296ba,c768f3db), +S(fa89b801,ff0cadcf,e45d5e9b,b9d76769,a4a8c293,c4d7dee5,eb3b889,ecacec83,fc82e286,1e786cf5,854d69e8,e3c09ac0,4d584273,27f9691,33cc0087,cf7d3a3), +S(ba9e6bfe,2167dc7c,e2cca3a0,bd90050,6b4c5ed5,a65b6799,38850e1,e983c307,8076fb0e,e4b3bd10,5826a6a4,eaecdc6,198cb674,f62ab20a,dc8495ef,9c69df52), +S(dbffd22c,abad0651,673f6018,a4ec19cb,33e25609,5170c06f,b37aeef6,8a7cf6fa,532a4a76,56c364fc,72e4e3b7,b0bf6fa1,9c7c526f,89cbb49f,8e8ed85e,e85dbb48), +S(470174ee,d0a5ced0,3136015b,581f9e97,bbf2b486,6bc855a4,7f4447ef,c2465628,f6347774,94972ae4,90748fbc,631fa000,5c3c9b2e,60072fd9,fdaade69,ef0f039f), +S(e965ab4c,e7b53fa9,e47a278f,18ec2338,5bc8ac5b,ebd90260,340637c8,31585369,ccd9d755,9b80ff65,ee866c71,44abb0e0,3fa30c1,91bb8593,da54840a,cb2a9d95), +S(f4ed2efb,fbec7f8c,54de593,80958b35,e3e4f3dc,1af445b2,a491b41b,256ecba8,b23b37a,9c4287f1,392eee8d,50d8d406,cab40679,a66e0d40,544aa304,aecb9c2), +S(3d911698,27693d14,3b0d458c,427cd698,eeac19a7,8f64d68e,9cb43c49,5421d915,be75c3e1,fcd657fc,59806fc6,bf1df70d,59e44b4d,6d217c8,417d20ed,f4560432), +S(c4589f51,1ed541c4,c4872619,726e7381,a9566548,4e8f0c16,33cf55a5,61b4f33a,c31f26d2,48c2687c,e119bdcb,1aec287a,2f7e25bb,5b3b1ce5,3af33dd0,9a92508d), +S(b3ac12f6,f45d31,b1d6f44a,7d042406,c04ba3ba,ae68fa43,f8200717,b3fd7c90,d04d1b06,ea0f072c,daef4212,89667b3e,effd1f8c,3b4c4f94,ada534cc,552e6d1f), +S(73ed49b7,9a7ecacf,6dc8ef7e,663111dd,40351718,d3289287,7131f8,53fb3b73,e25b70d1,c9d605ca,571754fd,6b5b0317,c7454773,9f71c39a,9069431c,1c755161), +S(d0cdd56c,984d2f4d,6f5068e9,27801a78,9de020dd,32c70cd6,eefe8dd6,aff910a3,35152fe2,70b7bad4,f0d151cc,6ac69412,5b7dcaa7,c757ac32,3562dd8,45362494), +S(adc7e82f,bf52b914,cb3e3c4f,c1d96ee8,7c1a9b5,3a449587,962aa19b,b03967a0,4883619c,7be39873,9be896b3,b1fd6f9b,c62ca121,198bf71d,85e918e0,7ac115e6), +S(a204d702,1a346020,ab978bd7,78ac1df3,bfffb831,3699c3cb,64a118d4,da7f607b,18a0827,bd9da5f4,35ba7ebb,3c4f198c,3f5c3313,fc6f6e0c,f796e51e,3c2e7d5d), +S(8a6abcb0,2aa24acd,71168ace,c4aa3aea,1485f04b,afffc1f8,7ef9a059,d5996ee0,9979410b,afa6de0d,42852883,e13e84e2,e62db36a,6c2a4967,f8e30a8e,11775e5), +S(144704f7,f1ddfdf3,2e270958,99e0f74d,467b09e1,ef388d1d,954b6817,3cfdc2e2,60e0c043,c4bf6051,e09960ee,d7a156c6,5e66e9d5,c19d8b0b,b8ec9edc,6c3cb3a1), +S(4ba11b29,7cf62910,4d7bf384,d87bd0a3,2315170,61e58d80,600fd7a4,b8e93ef9,fd7b0cc8,5c9de5c2,184fd95b,d04d1d34,4c376f52,e9329f31,98ef2fe6,21fc6ad1), +S(4609bd3a,6d606aad,f372a731,9f88211e,31f8e187,d3d0f7d7,ee418817,13540066,62d5d099,88f99333,e309b519,93c17132,45ff5435,8c29403d,8cec5c58,ef4450d1), +S(66e02b23,5399ad24,6d898a63,6e9f968c,b8abf79a,d976df4d,962219b,ab01997e,80a6f6d2,ee813cd6,bed0685e,d42c926e,d59f3067,59a409d0,3529d474,92acdea0), +S(aa668419,1ce4a14f,450077de,e4588ff4,7565c821,7d7e7628,8a2fabf2,7ac7f1fc,e9c1eaf2,4b00ea7e,34f65672,4db33d21,efadb2d3,7ab90d09,e067a286,a75c200), +S(b4680ca9,f0d4eaf3,36cce2e,aa281eea,c522d87b,ac51995b,6893984b,7351daf4,212a1992,b7af5e9b,3d538c81,193bdd3f,61e24271,fecdec72,f1359bb2,95882590), +S(f682edbe,4cf0c8cd,ca5bbfde,4b1263b1,90a1dd5e,e8ea718d,7f01b892,1f170741,ef891402,e5598b01,295f1e5b,48bc1039,375e920d,550cb552,7bab7160,1ccba576), +S(a40a6aa,b4ac57e9,d3b861e5,2b70d28a,5fa6b9ee,1e1f7776,37397f04,6eacbfdf,12957e43,31a5c6c0,18d0c987,78723fec,e16182ee,480b8cfb,6506ca0f,70603294), +S(53b2aa09,23cf3866,61c0271,7b8302c7,4807fb5f,31641a8,e5c4135f,1e6bf439,d4eed7c9,8b265069,533cbbe5,a6be5182,9d79989a,9df82e71,61c3d45e,f0ff3e06), +S(2644109,54ff1fc9,34ac41a6,5b7cf7f3,d66a0976,999b3a90,bc2c4c0d,de3c4ccb,be2fbecc,c71068c6,4b692e1d,6ecfca5d,14271c40,d6713ca9,323eabde,cc7dc588), +S(2e63233a,4146d344,6ed628f7,a0fd277b,435a9d81,21a2dbdb,43dc38db,69189e91,f0d3d6bc,13ee5049,ff2deee1,a13d1e4,eb8a579b,965a86c4,1a0cad1,8569494b), +S(bf0107ed,190729a4,3e130ff7,5cb99a3c,b13392b8,7fd01e32,ae9ec3e2,a0a93e97,eb2023f5,76a06d93,27cfd3ac,c6ba3d5c,ba3ce673,f84d7666,bd2f3f0a,edb63b9e), +S(c22f151b,c978953a,f3a1fb0a,cd1f7255,b5923e6d,c5aa4c26,53fd2109,3b493171,fd3e46,cf4c66f9,c66c5075,313aa519,538b3df9,f2660554,8b407515,502ae877), +S(b99e5b3e,e44391f4,dc3654a0,86abd389,51c8d8ca,ead1ed8e,ccc1b7e7,5b5a4cf2,74b4fa80,bb4579c8,643299b5,5478ce5e,9566c1d8,98eb10b7,200e8854,6a20eafa), +S(b1734d6a,7d8e19b0,10479c2,49ec6806,9d42ffab,e8265d6,f5fffc06,fc1243fe,bed2333,91c587d3,8710f320,1e74fd1,5816ac9c,2eb70bd2,e182cdf5,986b550b), +S(c6c97574,dae3b2dd,9bd060fa,b0515853,b2043ab0,4e58993e,98aea78a,f5678b19,3127c67f,dcf8cfcc,f4b1ee2b,17abd614,ecda39d2,3baa99b2,53ea3c80,74f9b433), +S(14d32f30,f9268e0d,98452de3,4adadf46,928457cb,423b1d95,a58c9f27,eee95150,ba73964,1ac3088a,2285a4af,c63467f,9efeca29,5ba61418,f6d15a68,1d7b12f3), +S(fb71dc00,dbcacc94,39fc4949,ed18b7be,45cf50dd,8dd68c18,b0855344,fae8395b,789b4500,3add70d0,cffc34e7,5c348033,30965e66,b10e0b7c,eaa21f5b,782ed574), +S(97978bd0,2696dd07,408e4a82,c5e7394e,6379e3d6,314658d6,a37e302d,218c6ea,852fb297,591996a7,f1db1402,5ccbe65,9819dadb,647d28be,5f891bbf,e96d3b57), +S(22d18ae4,56cde12e,451f800,f61edc6c,e05a0fe1,91afbcb0,8dffc101,400ff240,4506e9ae,7b87bc3a,9e9eb106,f3a4bb3b,9adf5144,6389db40,5d6e3e53,22874552), +S(263a0e17,1c1271f5,82ccdb1b,5643b400,94f18e82,e8e2a67a,79ed2cbe,c8d7450c,3cf4ff5c,f9b9a42,74650323,88b5083e,676d0ab,45ab061b,9de8d16e,a5f63e84), +S(1fe94ed9,eb72bdbe,9ab19dd4,abdaf994,7e700451,eae8acd6,ab2a31e1,d97a9ab6,f87b6fcf,e01b375,244b1550,77054488,ed835f5d,3c0d27f1,5f150199,40b3a153), +S(65ab4ff,32bdc4ab,953e8983,11ff56d,2648904c,a6ff30ad,3e013c6,f6b46783,45106115,7e3c8b0f,8d362ab7,2de710b,833cb381,bff4d243,32d6532a,1e76cfd0), +S(eae54dac,dcda8825,45912080,6504fd39,a2237e5b,904c3b62,4c960fb3,ec235cb,790f33b6,6cf0a163,160eec2,4f43c321,31fcbe88,696956bb,8b355eb4,b00093b9), +S(5122f262,72e25078,a9c989a7,cb0bc781,47f0be89,6efc65ab,67369af6,8b1b8f41,612aafd3,a2f791b6,5d62a52a,202c58d2,8979e4d9,a856d589,ec45f514,4b7e80a5), +S(9884b4e6,5bddf06c,c3b0be07,108c4880,f2c9f4d5,58b2781,61e57f29,e257aec5,5d4c8435,c7b7a514,929307a4,ceddaea9,ff551c0d,faa2bcb0,77c68755,4f7b4dd4), +S(4dfcae95,4a4e92a,37dc6d8a,3e503359,4b193f66,6adda287,603499a5,f55f53fc,7aa5ee13,952a1572,bfb85bb1,20e0d2bd,1a3dc28c,b87f01b1,8f817b31,c143d58d), +S(bf8f8ea3,d37eee45,78cfcc3a,6f173097,abc2582,22128787,be7557ce,df4f9a48,8fc5aec7,129e9a05,3c6c4654,4559ba34,f0395264,f01ec35c,1eb11a4c,3fad198a), +S(7d9294a5,f462db4e,5e69ac86,427ab556,818a73c,dbc2133f,f6575f43,312d6c8a,d7bb697e,1498984c,d489469d,f4a4214a,4571406c,35b5e88c,f1d11b48,65fb8b3d), +S(54b0b84,e6ae338b,65d832bf,f820195e,932d4e60,24307c96,a8aa8132,53639c9d,330ee890,4596ceb7,28749302,7c8a0163,cd3a52a5,69d41a75,3c099b50,e92a1289), +S(a3331196,8e97db37,c774e6c1,52d5ff75,8552ce30,80d7b9be,5d34f7fd,1d41726d,644016ad,988a499a,70b31577,dbaa6505,7e50a5ed,1cd4fe0a,db31bb50,c9a7e0a), +S(35e2d742,79bbf8e9,80338f27,fff504d1,640cf5ca,30241d06,d388df5a,5d792652,f88cd405,d779b791,f875ed77,8bc92665,359def46,a903d5fc,8052fed9,9390c0a8), +S(e1d851e9,15812c98,a2d176dc,7443342b,3812052f,c2ae183,c8c3aa0e,662c549d,e225ed92,a1d91ee4,2f191b55,f15c9aca,fc379519,ab0507d2,df2019c2,369ae46b), +S(6e99db31,e3f54cb7,cc6e8640,dfc62b01,471ca8d6,35d788a8,e6d0c79f,8de9efa7,176e8bab,4340883a,8380b53b,1e981376,d7f3535d,41429177,bb3a0187,3cf78d6e), +S(ccb520f3,2c671c00,56cfe1fa,17eab66e,7744b2d7,9b5919b4,47a55ef9,bed0d96b,b8a3016c,fa65d9c8,23671498,46379fe9,2f4e74e9,6487420c,38494701,efd9c809), +S(c5e531d5,49e65f4,254541cc,84bfd39d,2279d7c7,98abefc8,cc2cbc17,2e6ca6,4e1c664b,8bec2ecd,7d56db93,66f6a582,2fc70bb6,70c4d3c1,90b76bd4,9a825995), +S(a132f569,c7cab520,d127fd99,9c06d4e6,4a7fa953,9711e1bd,9eea72f6,78430c7f,a81cbf89,b67534a2,4f5ee9ef,8bf5d134,90f73f78,63b3964a,8a81b5af,e44fe664), +S(59242d2b,9279ac93,4a7c99d7,dba4e033,7ba5b199,29a6fa2c,24766c20,71b3c5b3,8824c16f,71126e9d,6bb56bef,7c5e37c6,760c70db,de4b7dc9,e29afbd0,a8d09b42), +S(a8cb72b3,2435a4b5,5687ed9f,bbdd2860,9e96ddad,dfb7c44,d49f528a,f8ba5f57,e8ea8408,eca95aed,f2a6509f,663956e8,e7ced42d,12900677,c86a4b86,ec0b40e4), +S(58888104,903c52df,fd26b72d,4671642e,c06b2efa,44ebb727,e6ca2d1d,616d12af,387e465c,9559e35a,124d6501,715e295a,3d95668b,35335db8,678e48ab,7fe0ff1d), +S(6cddcea5,a0bb7220,f206cbc3,b6ac999d,47f0d2d,728038fc,3b86fa8,61f4069f,724dc303,13aed0f1,ecee0d8,f696c1ae,d00ccd02,90df311b,8611ae43,3664b31d), +S(283557b9,3698a99d,c64643f3,d302454,841eff33,dc110d24,a00467fa,1d9064cd,715b038e,1147a84,8ad45111,8eeea2d2,66cfdad2,e829932c,fce6872e,a99c2486), +S(3f88dd31,95aa10f8,fba82e6d,9d26cf4f,f2ca855b,75bab7d1,c1305654,ccdc8cd9,99ee6e45,76a0773,a8e0a241,a40b073d,78f98b03,33292f75,650a7eb8,bf55fc88), +S(4f0d20cc,acaa4fdc,972e40d1,90ccfb52,c635c438,353d2fd3,47ea675,ad966fff,ab378bf9,c5560914,e5c423d6,f28ee794,eccd664b,fa78a18e,b8f096e9,c7c68bae), +S(4c4f2110,8d32ad06,d60eccbd,238495e,268d2545,bfc5f17f,cdf7a1ca,37c96639,7edf3b15,346f21ec,b3a271a4,bf70813e,c9a4e4db,169b6f36,1d5d48c3,16d7594b), +S(1ba8777b,218e104e,c0908ea,b9ca48d,9145b8c2,a3a0b6ff,95146883,3077f40e,dd385247,7de05b80,6df645a7,646b1c32,90f78fc9,4eab711b,433c915e,462c52fb), +S(4cda5560,ef56756c,f73fdfbf,3799e8a1,f744f497,bab91815,eddbba86,b404e33e,92e1efd3,eedd500c,f4668d78,f4283cf7,eecd6c6e,979980a2,ac8389c0,779862c6), +S(ffd11b85,884b2330,e21d2077,336fd518,a337a931,15fcf6d5,d843b002,dd225ea2,6ab2c275,4d0e514c,bdbc6e24,f3e2f019,8b73b3ee,d267224a,705e0421,4f449d60), +S(fe4a2c46,15b9b000,d871bc7c,af5e6672,a574a165,e544b8d8,bba978ba,ac80bfca,cd15b01c,1ac4e6b1,25b00112,c04d20fe,3afcd997,541f3955,ad60030e,413cb650), +S(c070d79e,dea4a095,a054e026,1c748411,19b7280f,d5cc922b,c2b092a1,f211257d,f7b93b3a,4fdc7bf6,d90ba7c9,56831153,7948d110,a9cff253,f783f075,6c569e90), +S(7820e29b,8a7615ef,44f0639a,2924958a,4b132f73,9e67d58f,ed93f540,934df025,cbbd3f25,b03c0542,5109d5c7,5a409a18,7c117e73,4ba624,3ae7e085,322df8a2), +S(12b4cc3a,ca603277,32fa5c6d,4ffe02b5,eed489c3,9ea67f67,fac3ad66,a20309c9,9ed214d1,4217b11d,324a1c6b,d6edec3f,6dddbe48,2e238376,d3b74a0c,12de2695), +S(bacc8392,e6770551,38b13942,ce2412cf,6e22f959,9f8bd91b,d4855234,d0972261,91263e47,63785808,6c645df6,9b36a64a,8c6a07ab,fdf28a88,6893cb91,4c5428a0), +S(8bf48d87,419b4741,e461ad8,650f2e5e,c93c1e42,cd75e307,c60e8655,8560d576,c38c0513,88d64e1,cb9f430b,5357ce64,c4aa4379,3494485c,4c23e07,dda82bef), +S(c6217853,f15a6675,aab3b7e5,703ff725,eaf68bf0,60dd45dc,c2c209b5,b6255d22,3b5e1d4a,3b04bc6c,665e4ad1,a3a7587,b53f5fce,6db4aba,bcd01f3a,53b342af), +S(ff04846d,7a1309a2,5bcc043b,3a129275,1c5659da,e1377bff,f0a4f52f,78d57c03,5906a77c,f9c5116e,b2bcfbb2,330f12a0,277b211,7605020b,218af50a,b50a8eb9), +S(9d6031d0,7a4005ca,5badc057,34171110,341aa446,37bd5260,9e3c052c,a7833a3d,c505366e,18f920ee,382b6d0,5c71641a,9164c7a7,685bbdd8,6159d981,6990d5e7), +S(328fc8fb,4cfe884a,d6f8807f,5af7f09b,852cdb4a,8d12d6e9,e0a83e62,ef124cd4,ccb846d5,9e5ebc6a,5f753bcf,91ff3e4e,917afd7b,ef3ec9e0,81c302f7,d0302523), +S(6d15ad00,8a21f27a,50545edf,f6259ffc,50b7b42f,6b66daa8,274ccd4f,9968d758,44cf472a,6a9a5bdb,bebc470d,33936503,2823d19b,62f59c50,880443aa,bac08782), +S(a406569a,df5772a6,e881b5de,48a4240e,680b7e48,6487b3f0,6bc10a62,f930154,5378b0d2,df6a717e,b90a9d48,aa9728bc,5fa45468,c997a990,f51aa988,67bf6d5e), +S(a481763,b51b1851,c99f906e,280e425b,833ed883,14b8f84b,ecf5661a,369d345a,95088d19,330668b6,44bd68cc,a7048e4e,da96fa6a,365c1279,47eca0d6,29fb338e), +S(5600b96a,6e0056a5,12160020,7115b198,8ff3fb06,538d6580,f3ba0b57,a9490fe0,a09d1644,f0d14ad1,73b117ea,cfe1f992,2bec2bb0,a8f92f8e,4588e985,4566f88d), +S(95e9d301,fea78bf6,fdd7210,16c7b890,fdf22b85,54870d4a,520756ec,b8d56414,dc2df8b2,6edf5d4d,faf1291,cf2fa41c,d26090a7,499bf36e,a7c5ffee,bf404236), +S(a154b8fa,adc62ff2,ef26641e,4467cb6f,3506662b,8e452518,1832d6f9,145d00d,2cd50f3c,62a43b4a,9bc0c6d8,72efbcb0,c8407e82,39d69ed,40ad56c9,ae3ca73c), +S(f5f28107,77bc1bb3,10c02f60,88a2252d,ac3c3855,78909551,c4602b84,fbeab69a,c23e586c,731e84c6,5a5a0f19,308fce27,ba3fedbd,3980cad0,389e9ede,c1fe6c6b), +S(64be52da,6082fd6b,9f909950,d8887a73,f614cb5a,8e867fdb,3768a0a4,a958c699,4f6792f6,f65ee798,77ca9ddd,3bd4dbf3,3675f059,6d5cfb85,bbd8070e,6f29031b), +S(26d9c5c4,1803962a,f242b042,2fa73750,12c91a17,b6848ab5,af4e9335,43bc8388,f6703950,633edc7a,482f9651,9b638fb0,337b7bb4,dbe6ad24,6a47294c,7f26896a), +S(c1efc973,50a488e8,467d1fd9,ac679eb2,ba011aea,412d7857,e3d2cc0c,19dd2395,c58649ca,c665691f,2fdfdb68,49ef2ac3,4d0bfdce,3927ff52,7a9e3d41,3d8b57fc), +S(dfcc4a7e,5a0ccc7c,f0f76c4c,fa92f075,791a2b05,92f25384,72256905,c08ad084,de18f9bb,28b017aa,474296e4,8ca2765c,8c4eab13,bb4815f,744694e7,697d1618), +S(a44e0a8f,9591b5ab,a051559b,b64ac3d1,ff8177b3,790103b8,db7e4597,6fa991dc,61c41b5e,30cbc23d,e632808c,76bec591,9ad4f050,251e9355,80d9e14d,7116a878), +S(5f094928,fa4652a3,616fc7c0,25b6e244,37d02298,1b2611c6,51265578,daca0cbf,e6599733,a9d0e424,43d3effd,7993510f,15a5369f,6d4521f5,72a85f9b,db7699cd), +S(f9b59ee6,86af9c75,5bb9a4e0,8b15c93c,a787497,ae30a437,bac76831,6f57a535,77f0686a,2ff851a0,e94f28a2,57f05cb0,fe6cc480,39789850,e3f2c7f8,c03f5836), +S(f81d0108,f446165e,46460e5e,5c89d66f,f2dc8528,f19191e3,e75e5d9b,105c0a82,daaf0ce9,7b104214,942efc9d,ab807966,e321dab,d757649b,c1e294fe,4146a6dc), +S(fdafb234,9f9f169e,aac0d2b1,9fa4e2ee,a60ca31,3c544e39,246732c5,61e6d8b7,2b7038f4,9497fc7e,3e73bc8,dd262dd6,9ddefb45,f2bab8c0,770a5515,a5ab1097), +S(bec0f91,eeba7855,9df639aa,6a46201d,9ce07885,85be6bd6,1594c722,79586935,bff92e25,93b8cb1b,a80bf5ca,da923777,56cc1d41,92011377,4f73d461,8b2ad402), +S(41d616f,b05d2050,6a8303ec,e130c5d8,6d27322c,552a248f,2c0dfcc7,1006fc74,1f121fc3,55b81e7e,43523765,80cc3c41,d50e09fe,18dbc40d,a1c75732,5884c42c), +S(e483af0b,fd8affa,423005f8,3d25933f,d2a0c79a,3d020523,5fbae421,51dc626b,31895405,c1d359cc,9b0e5170,b93773d7,39d32681,de3aa9d6,ee635e9d,28abc9a0), +S(65afd96,3c02dd8c,f09867bf,7eadf306,b9dc6146,5b45e138,e20b0a07,570157c5,1034ac39,8fd3318f,44823b33,a140e57b,db8f9cdd,ace4fd8b,33967abd,304e56bd), +S(71aeec22,61b38f9d,1148bc27,7653b51b,7fe98d61,bb3c33fc,b417653d,fb7ac3b6,8344e611,348f222a,cb3c3e12,6a9dc0db,5375d4fa,c1cef432,6008e601,ba2e8c78), +S(ce4a2466,34fb2994,e0af9fc5,a5e8c612,acc30331,81534c0a,640d5fd9,c9b9d208,ca006505,98096923,9973c2b1,c82c6ff9,848232bb,81851f33,cc773721,a97ad669), +S(2bcbcbee,977d3ba,74c81f1a,b1c6eba1,3cc5e48,fa8d9623,35b8ae4c,84fac6f3,bf89907a,8ec4a9c0,44aa6f40,be9e2bf4,a100a64d,3d046c7a,416c9f8f,151db3fe), +S(a745a5c8,3c8fb696,4552ab95,df609910,46074f8,e7381440,e565464,6fb7480c,9b1494bc,ed6598dd,958ffe63,8fb3c73a,d773407a,372db5d8,3504197b,79f3751b), +S(9e0a17e0,33391d78,d168760c,3a31e3ae,f1cbfea,6e13f848,be89b691,11330dae,29bb981c,388aef6d,60461505,53e81a4b,98464956,a69c9494,efd62227,6e0cb5fa), +S(986ffa05,749bb4f8,3a1a76a9,3b972776,e98f87ff,fc66343e,965345a8,608e4411,daf77d3d,5bf42c92,c51f96ce,e78c1436,50cde8d0,11458939,833387ec,993775c9), +S(62720ce,5863fca0,c4723eeb,9f80600f,9a751974,f3c22c61,4bd8ad01,e92234b,f7f18595,97529732,e497344,b7ebb71c,ce51125,78b0bd68,8f2f6b9e,726f7d3d), +S(e60ece6e,c7745cfe,69a17710,c473fb69,9fd6ba1f,1af4493f,2926684,c9740ed,50d14444,a9092465,93dd08d8,3b8df343,5ff98525,907f04bb,343ac295,d8823836), +S(159be1b0,f7579ff1,ae272047,a1c8a9af,2c38354,1ab19a6c,ef7396fb,4c5351f,2ca76b1,a87755df,61682152,d0379ba9,3054049,1f91f57d,1ee1e081,602aa289), +S(79c9c14d,1997643b,44eb981e,1b89a7ff,a6511b81,9539d1eb,ef5dd46f,4c6fb033,2b9b88c0,3dd3e006,638edeb7,1560343c,1a9dff51,b12c891d,dda7f67d,140f1ec0), +S(610f1c50,8012918f,d60ca30,13369bcf,c4bfd56f,abfe39cb,2206e5dd,59827150,85f62af7,722b89e7,6de3ab17,368615c2,9ce6980,4c397580,d48f6f12,5bfbf022), +S(ee26f4b9,9a2285b4,80bde15d,83dd201c,24dfa7,b8be93a,c7ea3bbb,9e46bd88,129379bd,2daa2b99,906b2643,90eecfd9,78b033a0,fc550fe3,b41e1c9c,97671b1e), +S(b9b51c7f,2bae970f,2acc2d8b,fa88b9b2,15ad5289,b92d1f04,92c44804,7e3ca7cb,c5242210,e779cf4f,1f06e9b4,ec92ae71,9a08805c,a16689fc,15b01ee8,d3585a64), +S(1e7530f,dfa5dbd0,7ecbf05e,4c8fc7f2,a44bd3eb,ddc01d27,d83dd25c,c5d9e136,7857a6f6,6d7027fb,b602d8ff,f63ffe5,bae66c9e,ef23b198,bf65e7e8,3fc66d70), +S(f498545a,1008241b,d815e282,d3fd807d,ec8f331c,83669c34,ba126814,56f22037,998291ad,71473cd5,37ce4f16,7bfef603,c144df31,31769e3b,8f5a89c3,a3274584), +S(cba20c40,5a4297b8,2a6b7756,8512c2e4,26e67465,c420e109,b506a37a,9a177d12,81fc17cc,d2363087,ec9c61cd,7b3bd9d,580e280b,354fff37,b43e2ef8,78c338a2), +S(ad4522e7,87c3436b,3406f8c9,3d7f01ed,92c4d319,11644cbc,41c9e103,e8813041,6dea578b,a468d78d,478f3e6f,6233b227,686fe0f8,19ee352a,cab182a4,ec2307cf), +S(e60c27ec,f8dddf6,27ef1c4,e4f84fef,ec2825a1,c57d8a68,dd1283c8,4bc5547a,a807871f,f74ceef0,f647bed6,fe8c2182,e9581f35,465b9c1e,445806c3,428d98b2), +S(9aa982f,b4fa514e,c8f5e08f,447883f1,e49c720,58b6d1a1,d3c3c12f,acb22a64,20886051,e999d3c,f51206a3,165690cf,9d86367f,cea7491,599ba8c1,36ffb70b), +S(607de32b,6c74e540,55de8743,150e931c,6234d65,991e4630,d3e854d,34ff1469,f58fe81d,4f583242,7e8a481a,8b51bc5e,b379ee2,15888e13,fbc770d1,9421b5f4), +S(f980f137,30c560fb,bb4f6db4,c6de3516,2063a618,e1708e27,2f19b23e,af0f3b03,5b7842b0,3ea2cc6b,4d640ace,f6721fec,afefe70a,3729785b,6c2619d0,5162d5cc), +S(c85ae74c,7fdecb1b,52287522,d3c51a3c,4711711,82d089db,1a01e117,706da488,58f96a54,8b03a13a,d15fa656,e67bdee4,ac1ab1bb,d3b91b97,dd35cedc,96d315be), +S(4bb491bb,c05786fb,ad1d2081,2d23529e,5bdc2846,a344f44e,9b914f30,93cc347a,6cdefe1e,abb3ce02,bd3c4c7c,9b384ec8,701d36cf,643e99d2,5c4163b2,a35cdf04), +S(c1eed40e,ff0e2b5,c58ed098,feaa9ff2,7b9e96d7,ddefc1b2,53aaa2ff,ae450542,eb9b0434,e62e2ff9,10ba0dab,8074c85f,9a3bafd1,e6ed1ddb,e158edaa,3b5bfd51), +S(4bef4127,d6566ba9,33881d05,55fdf018,3c47772c,822dbc63,3e6fa336,d06e1c41,1c163ba4,9bcfdcfe,a99702d2,d9bd19db,bfa67409,f4d3777,531beefb,68ec5e3f), +S(3268e230,6eb8d65b,a528db9e,fbc05d6a,1ff35ec9,d4f0bc57,700610d,c9ea902d,126d5546,12de71f,93be584d,38fdb65e,7deccb12,9a5e4e81,b12746a9,cae2cb2e), +S(c4dbf5f8,7b30af00,ee576ad8,3c20f079,cac5eab0,3faf5df7,4d72d9cb,2226861a,badcd32a,d809ae9,7942bfac,a00be66c,80c6c1b8,4b8c7dfe,2473bb53,5bb4e625), +S(8c919ec9,22d79e15,4f1f63b3,5f04db1a,aac7fd2f,911e75c8,b7918baa,a13914ba,dda36a1e,5ada8eac,4aaa28d,6f0285cd,d0011fd5,c46b0e09,1d8dbb77,8b0deee2), +S(1d8b86c1,70366e16,d3c33bb8,247bbf09,cd04fac2,3d9d3b6b,d0fac9aa,3274efa6,ee9196b8,dd6a3e74,697e8834,5f9575c0,80601ba9,d02b9583,260caf8,e342fd3f), +S(ed400eae,debff33f,922353f2,323788c5,29c933b0,e269c091,3f84986b,6e4c564a,35bb3b89,8427ee01,df168a7d,6be85ae0,71c45003,df37b369,2c52499c,85669874), +S(11e79bc0,1c5472e3,3325e3c0,606b6f46,defbf951,2ffdf9dc,8b59294e,e7c03057,e3a588ea,ad8da56,47d42b0c,f314ee96,dc900c9b,5d7fe6e8,a38298f,84812c5b), +S(24a18d50,18273c95,aac1dec9,6d443b92,b980b7d7,d88ef70a,f4b728f,ee718b82,c7bc851d,3e0200ce,16dcf3a2,15bd5322,d9057c9b,df00fc1c,1b0f63ec,fe231826), +S(8349d4a2,fd0937da,1c85e03,c56f01b6,4c0422f6,bdf90415,d9c4ea7e,2bb5873,1557cc42,fb57f4fd,4de5fde7,e4655cb7,fa42452e,1664b328,425bfab7,63ba891b), +S(515c3896,cdf651aa,99e6099e,2d07f0c9,df039a30,c820c6fd,1665b70e,16fb6e07,2001400b,48447b12,391cd2f7,497e1f57,c948e093,6b981cbb,4a414adb,ac928ca5), +S(91251dd4,5a829e00,4c17cbfc,3238de56,c16e8d37,46536392,d5d05134,3cc12279,21748cf4,95c962cf,d28958cd,306536c1,84f8b822,7cc4dfb3,4a8f370,316cabae), +S(659f2b85,6db07ff8,1f10c48f,356acead,cbeeb169,5022f3aa,1e9920b7,896fe684,b7ef27c4,615ae55a,aa576c7,c92bb571,1dcabcff,1bb05c82,359ec59d,a34f53a3), +S(b82012f0,8c209d40,ad21a839,797cac55,728805c6,f139ad02,893cb9e7,3fd334d,76c80c95,ab38d674,715a6f6e,24978fe,5dbc08f3,530a4a44,904226e4,cbe8a808), +S(e6e4fb7e,8e7a946,62ba3dcf,1802903c,fc2cd961,634311a5,dcceb49d,9277e80b,93dcfc61,127c2afc,76a6e097,9033db34,51a95413,a07bed1e,9548d435,88e68add), +S(1e717f27,98ca7da1,268d6bc9,97c01261,6263a807,3874505f,5fad1adc,a56ade71,3093703b,69edc134,20907623,70572119,ff0e9729,a22689dc,8e421ac3,52f4a3ff), +S(8d6c2b05,ea5b29d4,b02706d2,40a989ae,2c3c8b02,c31cfb88,6453cdf1,c33bbcf3,1e27c8a7,25bba645,48236dff,79370ae6,2949c58d,37eac4af,e5977a93,e5ea9394), +S(ef9d932f,d19aa7df,89e6e21e,542bc530,28937f47,7029ff26,45582736,6f207c46,b45714aa,d344a62c,c9348d78,ed4f0684,7424718,784e8ee3,d9b1f857,4758fd29), +S(34932c61,bdd68dac,7957c957,2d4881fe,9e5933fe,65e6c3d5,6f74f7b0,2bd152e7,fd963edc,eb7607ad,a47f716,a5e8564,797c9862,14a1df3a,c6c3e502,86e75fda), +S(ba182aab,ad4a9b4f,3ee47796,3e8c0233,9b416f42,6b4403bd,6087ef5a,f4ad7a5b,178fc05a,35ada525,943ed04b,fa7b10cf,c69f9edb,63dbc72e,5bf8303f,97626792), +S(a5eb1644,c585ede2,59297d94,4ed41664,a4f95c78,239344f0,e6a66020,467e41c6,b04cc4e9,20e643cf,ba8b8dc1,5e4b76bb,575cf1dc,d05a8016,85211ed1,6a98bd20), +S(59ba1e2b,40959a57,a0b41dc2,f7ef4520,6dce83bd,da582f57,e03338ce,cae060c0,2c92f4af,ee3dfed8,3a910194,e548fa54,d4f07bb8,90386017,7394d707,4a979aaa), +S(3f0ff5c7,dacb5106,782f6527,ca891038,da40fe10,7866e49d,106ce243,3b88c962,3f02265f,4dabeb7d,18618e1d,a97700b9,f416e34b,e93da65d,1969eee5,baeb9dc1), +S(4d767b01,8160b297,3cf4152,110ef381,453dcb5e,30af00d9,5bf79971,6656f41,b2c8dbdf,fae8b792,d3a89c51,fd841fac,108e443d,e50376a0,9b4686a0,e03716eb), +S(b3a13e43,1451f086,c6ada2b5,dc38b059,73e014d2,bdb42157,88046d32,efb7cf74,2a0e4560,4cb507c8,6d6e6,686e9b2,9aece6ae,3fb5d3b,7f5f01ad,a8a65493), +S(cd90b032,a7ecd8c3,f1f2bcba,a523feb1,3790cb6b,1573cb0b,1e468417,e52236de,6ff50c7d,354a3008,7907d056,fdb0a4bd,2c34b649,f0f486b5,a366a60b,7d01043), +S(5d12d03e,cef954b,a35e82d0,918cc576,cc8713d5,e77631ab,ab79a0d0,a428fb04,bdfa4678,77f9a637,7bb86a8c,b36d886c,fe09659e,887ee49b,2018720f,6ee35d89), +S(2dc4f368,62d4ff1a,11246119,81a09c25,ecad53d2,e34fbe1,b708695d,7dfcb380,5aca4c06,e92c9327,8d5e29b2,e7af1e5e,f71ac624,ad1977f8,396dd6cb,b676efef), +S(5f1c640f,aae3885a,af679e2d,a3a73b4d,68c3b64b,e7321aa,ec0e802a,66262d54,704c3b72,eacbda85,f425cb4a,6e6632b3,e65963a8,7b26ed9d,770f3a7,81941c90), +S(8cd7d6fc,522eb467,3a366222,5157ce21,805f7f40,3fc2810a,a7678242,3559f2d1,397ddb0b,d0dfddac,bdf8826a,12666f70,d8ad9fe7,f96f040a,fe55e265,bef932f4), +S(b635c8ed,9b7b1858,86c5f75a,d524e877,c4f2cc11,a3ea63b3,7140b044,fb50e692,6c61f48e,a0cc779d,cf746f4d,7b6dcb6f,ca562bb8,5fe244ed,244e720a,648ac131), +S(e0edc56e,e22db179,fb5203aa,2aedb0f3,9f8cd83e,6a1f7449,e33a317e,97b29dab,d3b29f04,818245cd,eb6b3661,8d6c5e3b,384da6a8,aaa60818,ad56cb95,1ecb59a7), +S(f261ce,b12747ce,1b529cac,1d607525,5d48f813,4d1730,32735be6,72db7df8,6c72a777,69cd260b,b78c912,f0bf461a,4d059704,7c1de47a,23a2421d,ba26caed), +S(b6154355,f2b11b93,b69924b5,b450b026,ae63ba72,777c82b5,99d1d0a0,cab223f0,59fb58be,3295345d,abdeb091,8e93d412,c3c5bb1c,b7527ed4,adae9e72,1b4aca0a), +S(74cc74a5,aa36ad6d,42f82135,908b9414,2842819f,9f7b5c89,d2337ebf,af11751f,df890e41,b3253de2,c594c78,18ff0c7f,6637a8f,fd0e13c9,21a512dc,35fb8022), +S(227bf422,28b51fc7,9d090902,a842e78b,a7138a2c,666459d0,16061c08,d6947e82,1abddc56,c5fe3211,7783b52,68f5629c,7ef2a463,40af1fa6,f4edd22f,c9ac684f), +S(31a79a7c,3f1478bb,88ccf5e1,3a220685,845c390c,378c02ba,ddf099b7,7a2905df,a04ad9ec,4b5693be,7aeaf419,2f5c28ab,6ea03c2e,8db116de,7eb055a0,6c6f4a6e), +S(d1b1f29c,bdf6d9db,3d73f74c,df7dd879,14e00b0d,de6c9733,cf7c497a,a355176e,82c6aa29,4caaf404,a5411644,fdb115c2,3c6525ef,f4dcdc90,53d0eff5,6addb107), +S(57bc432c,9fba6e62,35ace8da,4e44721c,a87b44fd,fcb7bebf,610275b8,49b4031a,a75f94ad,19e9a3a3,a0395f4c,403114ee,aa12553e,e168a80d,6610147a,f5c3152), +S(a7c2839b,1c0b8975,2b85211a,e7532018,ebe5f0d2,fee8f053,e6666a9f,9449ab7e,cd2892ed,2bb40ea7,656492d8,40386e97,86919d81,dba6497f,e6f81e9f,ec8b2160), +S(909c4cfd,e85e5958,9384bd4b,6f780b6b,bde85dcb,fe36d8f9,a3f26a93,4c88ee15,f78b72da,b2531fcf,ea9cd085,c17b4375,4263ede6,8dabbaa8,6ecab23c,9475ecba), +S(cb98a258,98e877fa,3ec0d9b6,a1e6dd7e,477b8f7b,716c97b3,1e48709f,de7a3d15,ba6fb66d,502143bb,cc54472e,df00389c,998c8274,cbe8f997,66c90d67,bcc5fd1b), +S(bf5bc69e,81d7b4aa,e4137ab2,6b701fad,a86c6d1d,fd163e6c,4e57844f,3b55e84b,c87360c7,406eecc5,51697719,4eaa7102,1de0afdb,3198a9c1,9253975f,970df761), +S(2457fbbc,767f4fdb,2b5f6194,ca8cdfb6,fd1da59,19e2314c,d809e2e8,6913424a,910877a2,f7707fc6,7b9d3bd7,6408f162,f04c826c,cda46652,cc54415c,30d77518), +S(625e48ad,44703721,c1934642,d72b6989,94550c74,44589f46,33ea8580,e4c20d5c,ef31188d,c127c8b3,67c6b981,241d8627,5125bbc0,dbf46261,4f9b5fd,a54914f1), +S(3d4f45d0,8a28cb71,aafda05c,50a7f534,5b007f6e,ceeeac7,20cadd68,c04748bf,932ceed2,ae007aa3,469323de,fd7e7dc6,deb77872,85e48e79,bfc21cb9,a7bb8397), +S(49f9290a,55e6c9fd,ffe96742,43198574,d81c5b82,1148e5b4,339d7877,ea070de3,f7e61b91,ce217ba2,bd387b4b,8c01e956,3ff155e1,4c8bf553,7ebd16bf,b48cb0be), +S(feffa5b7,78a277de,ae68ff40,9c00b7d4,d6b78b57,b71ac08,f43a5e92,35ce62ac,b90defad,a94dc21b,ce8e7580,dc79073,b4152c6b,441da59b,d904cf6,76219d8a), +S(7b42826,344499b4,5fe3cb54,b8391820,54166846,7806a48a,6221c88c,b0831099,68c5e981,4889f320,cd2818cd,5443063a,4f85429a,5e335f5c,e4731a59,da2ccefc), +S(a2bb3900,e42c4bf4,91aee9a0,bf73bee9,c73a2245,a94e40eb,2f02a32c,760fd29c,6eea2aaa,ef457edc,357c3b54,547ff6b0,8e12f076,2d8a368d,7a9e65d2,d122b65d), +S(ecbf9e55,3bd020a8,196e0b6e,63e8f568,a60bed0,5fb7dfb7,7af48065,ed4c838b,e2be7677,9e7a57c4,3961af37,aeb7a8f1,80070633,617800ec,a407cb5,3ab63313), +S(9d2ad029,2217200c,e3a22d2,62cbc071,9e5fead,6683ed43,8594250b,44e60b3d,7addb679,81dc9504,8b2d98b8,6a4ea72f,faeb5185,f804514d,cd18888e,77acc88f), +S(8cae4651,91c4432c,9c6abb61,438b06e3,d3277b61,177917bd,8fd024b3,353d413b,5615256e,793c6b8f,d96930f6,96d0aedf,4320104f,fe3c7a3b,c7025232,9a10b1d6), +S(2151ca1a,c8b07208,2f765333,42ef886,4a7c9d95,f23e1074,9fc3ff85,bece3336,3a27fdf0,97569b0,52dce8ba,7f22d2e1,325b06b7,ada607d0,7241ad7c,4282e4d9), +S(f6d4679a,a02e074e,3f0ca3a7,95cf91d6,de2b9cdb,d0bbc86a,8e2d14e5,cb4a8908,eb16065b,ab9cbd11,2f30440a,d4540ce8,eb043035,a653e4c3,c8531375,81965fd5), +S(8f8a299b,ade7c13a,2b6ba6b6,f7aedaaf,c36a31c7,bb9c49a,43778c64,b72be2f7,8371703c,b338cad9,acd6db9d,6a840bc1,4bb65328,793ac715,55743a90,f053cf1b), +S(9310f8b4,73347c50,32840e4d,6cb2eea1,a334dc03,b1ac2364,cc0bcf95,e0bb21ac,134d020d,6c2b528f,6e96a9f6,6feddd58,1f4f0ff5,50673620,cac44f57,de0c36c5), +S(a4dfe64b,5f55c497,ec42842a,d2bce748,18f9ae70,cfa521de,255487f5,6d51685b,20b5c707,d8bca7f1,b5d29b42,c6eeb116,6c96eeb2,4201fcb,352e82c7,663164b1), +S(2b880bf6,9a83cf4d,c6138225,733f51d5,ce5b6a12,95b98bfd,e2929b6a,ee5d3863,c21b7e23,b84dfd91,eadf0b14,9649fc10,872c39c7,13b80b81,1d989673,6492a870), +S(300f1400,fad4b0cc,b20fe64d,d9b50202,1105edec,f0bfb8d7,7a1c9f70,73ce546d,166d9e75,ea9a6b8b,cfea2f18,bdf4110,664ffcc8,be29b91f,80d92907,e322a546), +S(7bf49311,d51f9499,6511d0a,70f65466,aaf6cb24,1666b76a,4e821e03,e47cba37,ef25f85f,6dfefb08,c367eef0,c8433f6,8a775f00,464c4f6d,dc3fcc49,7d6189bd), +S(b20cddfd,6f4c3b4a,d9b9ee4a,353d0ed9,9163cb55,83bb526f,63ed9d53,9359249d,b38097ca,9e0203ad,3214819b,b8f4cf79,afe6ac29,cb33c670,2f3cd462,d635ed12), +S(98296e3,83c9984a,b9c06a3b,2daafeb7,32696ecb,af1fdb8,b1d94df5,9149ff2e,fe25c8d8,a72b6b0,17ce8c63,31c3cf1d,dff0ff98,e2db364e,7ce3e642,d3ff7843), +S(ae3c27b0,e32887e6,568abdc0,711409b2,2030dc6,2bb9a2e9,739b5edb,fe4b1a1b,a8513f4b,57f9dc76,5feec2f0,1d7d3ba1,235387b9,132303f4,54fdbaa1,d04fdd73), +S(e0afc1dc,ead8b23d,5956639,5d312ce6,36716e03,e39f3cef,d2d9a5c9,f959dca9,a3a1e6bb,b7fc2373,76484862,e15d89df,8a617e56,b2d61f18,3b79e7d3,d2fd5223), +S(526bc9c6,798711f5,461862f,817b94a3,d66f30a7,bc2aaae6,1da54b76,69004cf1,542349a9,7ace4d08,1022da51,ca2c412f,7c0cc951,62d0c1ef,22d04191,18643b95), +S(dd2a8d3c,8f8bff64,f5acf9fd,6b0d613e,9b149bf9,7c26fd29,41b0c2be,b5419450,6e88162f,acac6dfd,5174d61d,2aa755a4,cd73c440,4b5a83bf,bb79aedd,b7213cd0), +S(d76bccc2,f4079bb7,dbd605ef,ec78a6d5,f3e8c655,c9b38f07,dbff4013,6d80faeb,8776727f,5caa4d38,ba1a3ea0,4a01ede6,5098e470,914806a5,1889399e,c0daa412), +S(afd6332f,27f0bd9a,ea917732,8bf60bfa,4b80f3b5,82319e26,c0fdb22b,dc4b9faf,9595fb29,a8f6df8e,f0b93ace,8f92bee6,f36edc,60b19d6c,968d4177,6582aa52), +S(fb3a199e,1d5f3237,79afbd79,246c465b,98823ca,2851b64e,79aeb1fd,8f90d920,bfea973f,41bf4aa2,f1cc94ac,58e00da9,e4fe46f4,e1d0bd0d,183b8e84,87a959), +S(c4fd8c80,1ef65e97,614bddd9,ef5aac03,3023f7f,1ebfd7be,27f3c4e1,60b14097,2689b9d4,e244e9c7,64b783af,ce2ec314,8ece5372,76c122d2,2fa5d995,9ed94723), +S(6e171334,b59b4989,e2ae6185,54f6c349,26fa1cb1,e7e8b064,61f8535d,cf8f69bc,8064d981,17637f61,72daa8bb,c4604068,624bb0f4,9555f73b,beea8ac2,77e2b54c), +S(e1509f15,8688d157,973361de,6297142d,237535a7,a6b8f64c,c982393e,ff91d6d9,3087adbe,df20cb0c,488b1f61,f12b7e82,f6a36f8e,34a8c1ab,22d71261,d5c2c40d), +S(1235ab12,23b4d47b,e3e5fc37,6b3986cb,941884a9,37d81e1f,991f3fa6,8e529a25,7dd787bf,f7cbb123,e814eeca,45435af1,e2f32c25,8a7081c6,b66088bb,8e560b44), +S(9d70541b,e7995deb,7c9ae87a,b2f085d7,fb458494,f6c4845d,5c8c013f,a7d4a9d5,b1b6c09f,f12d7ed3,9c1af481,3ad135b4,dd0561c4,5a16d111,9bd696f3,e4cdb757), +S(8649ad0c,d9fe1177,8651ed9e,3c2123f9,8ed3b0df,f0afa4ee,adab9fbc,85680dd4,cbb0f8d8,4bc474da,bd1a0b7c,d397e1f9,d9acd111,5847ea54,9018f290,9594fecf), +S(fbae2b84,7685902f,b1473523,2b13f16a,c03d8366,32294d7a,6e214acf,8f8a4e1f,f3fa3a7e,d6cf4375,1f10050f,35a5252e,3c6a20fc,c3d8ef8c,cd393ba6,413f5fed), +S(635dd021,ef74d3d6,762503f6,924c24a5,32c626d3,75ec0d9,279b0086,bff11281,d2eff50e,b28be98e,192dabc3,8b5a605a,639b665b,17fdfc3e,4f339aa0,33d971e0), +S(99ee1d87,4c97c493,f8942a93,8bfbd578,63f8ddd6,387f716,3fd2a454,fd43bd99,81b96b6f,8d06086c,34407f7f,14e2ea21,2fab454f,131da461,7ca88bdd,4026278e), +S(77447295,aa56c62e,d8722ce0,522c58e5,5356d40f,b657ed65,663499ff,289f757b,f60ac045,15811b93,837a0819,f59d6fa0,c1f709cd,2ab128c6,95716590,43373251), +S(b006dc27,bcf879f,92b86d6b,ca0092a1,d848e98d,de52fb72,80081952,34857183,aba7308a,3686ec32,a0a2eac7,47f69f1d,74f9b7f1,60cdb4f2,f8eba9d6,2a9255), +S(41680159,8de643ad,326c6e46,3bd51cac,8c52020b,feb7ca44,6a9c0820,c02cec4b,ad11cf30,5bf184a0,3965085e,42a95721,6a64d9d7,38d9cd09,1dc3a8bf,2ec3b65d), +S(a4e68433,cb81a8c,148b8b3b,473dba7d,c9a1e44e,8e7d804a,519005ae,5c1b7d9c,89668932,7c597505,cd1f0e06,4273e574,85556724,3d257fcc,e0baa643,b38b15f3), +S(3f9b53e,587b01bf,a04a685b,c7d30db7,4f0d748e,44eff028,19192e28,6bf49016,6b927f7a,910f0057,d19f4604,140c7aae,b81563b9,f4c54ac6,6427e50d,11309e81), +S(6833273e,f2629ed1,d95ced8e,e776bcf4,24bc1a5d,284d54c7,d2c3b634,1ec209d3,25607f55,82f7bf1f,4ab5cc2e,c883ede9,8523b751,9d392230,5d98fa5,41e741b6), +S(c7be699,289a091,3021e2b2,eee75322,8cd18703,cbfa7db3,d1d5f0ad,f6d506fd,e5d016f4,2932d594,ddf556d3,399ffd46,c0b677cb,8fd59340,234c9b7a,349cf213), +S(6ef0d7f6,1803acfe,aa62b4e1,cf238e5f,398f0adf,228629b0,65e7c2c3,fa12e589,628336db,78881419,3026db69,2ed2aba8,ebbeda93,fb4f3903,bb8b2e8e,839eb7), +S(ff83fd15,dca2a55d,2ecfdb97,83ca9595,fac1f440,4b1e96e6,dd3abf90,ac857e69,f061ce87,8640d2dc,5fa4428f,75ff93,14216b92,fc1ffc72,29931d8e,f51c494), +S(f445bc67,47a3b7b0,fe56e4a2,db1aa71d,d042b6a,7b09cfe4,bb28c0f1,bc636587,a79a976b,7c857356,2d6131fb,e8476e13,6b6b0863,b8a464df,8e57da25,fcebedea), +S(37f88df9,22775959,94f77586,72cd5894,71c468f2,e6d3e424,45404b16,ab7b9e76,509ebf24,7f83ca08,71fd94f4,b178310d,4fc62bcb,27b256de,22092893,ff3415e8), +S(fc6ed464,1f548b62,a25062db,6b4c9d18,4d5b4b69,ec9fe4a4,db269646,331f6d12,cd384884,28427b19,4c77395,1373fa66,2ca1c771,2cf7b8a2,51c5049e,5d89bd27), +S(675eaecc,5c441173,b405dcb6,256c95cc,70c6ae38,3ba69053,ac02539f,7b6df001,4c275003,664b1f98,98bde64a,6f1b366a,2856a30f,c39fc84b,b6f2d94d,8435c76d), +S(81d9496b,3d892b9f,c4e0b98a,25c157e5,331d6d19,2a7b27f2,e52d2685,3b633395,4b9714a,e69680,649209da,eaa9734c,c611e98f,9bf19099,6f514022,aa2ef5fe), +S(5c6760d7,dbe3dd8f,26bce0a3,a160c8e0,63de688c,e2227bd6,e890e45e,5205076a,f539524e,a8cb2036,bd6ad2b2,3738222d,fe38823,9f03ef10,dfb9d223,407ba175), +S(6c47b5c2,889c17bb,e9f4c1d4,c930a975,6f74423f,7ae9105e,1dac216f,5aec8d3d,55eb547b,d3d60c79,c585b602,dd0f86cd,7d3895e5,b5bb3d13,a44b90c1,edd6c978), +S(da9ab6b0,4a4d3b27,31130717,aeec1123,b21eec88,ae16d3a5,547c1acf,664a264c,87a44739,396a75a8,1f0c542d,2760a2db,944aa850,f61e2fd2,e44c840a,a222a193), +S(cbfc9815,ae28411f,d7056e72,3a4d3fd3,a026d293,f8741154,d9db4ab6,a0147f41,71ed4ca1,e6702d7c,bdd28e8d,9fd41f6a,3879e88,dde652ef,9c639f13,f183d172), +S(2629d332,e3e1ad22,35420ff8,f94d7775,f2385186,a0559166,2aec35f1,623ede43,8e9cccb7,bd6f76d9,d76f89e6,3d8ff895,306028ba,6bc4ddbd,de26f81b,3eb172d0), +S(47ecfa1d,c1e01ed6,111e7ffe,fb44d552,e7a72e76,228914c7,72a80468,634edfc5,c7f3a761,3cc68070,7a1e9778,b0deec89,fc0cf226,14e16e84,4b661766,e6f6b6b), +S(c9fbd01f,ef8da054,7e5f2fd9,c5bc59c5,3e3f191a,7abc3cf8,df5e7c07,ea2adcbd,ba3c6b49,b5b9fc1e,4f433f14,b1a98e5,e20d2448,7fb234f4,9384e610,2035196a), +S(c179921f,24e2539c,9f90d7a0,37d8bce9,bc2741f9,4d7a78fa,a0212d66,f66a0d96,59b573b,9e9425b6,a0232e87,2d0998f2,b1815f68,a2c1ed5b,7bb5bcb2,b4d737d2), +S(a37a89fa,5001ec92,9a93291e,8506c5f9,b669603f,eb3ee27b,5e487113,1ad82cf5,a208d652,6666e930,964ddde0,737c6af2,900b2f0b,5018d814,904e71e5,8f8a0e86), +S(32323c29,2f98e042,abd15506,423514f5,4ea4070c,da493f93,10d1514c,a1895df6,ef273d5e,56e5ada7,2c872483,10180661,a0fd697b,5aad3faa,4cfd1915,fd749ff)}, +{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), +S(6fe08b32,ab3b1553,14f229e1,138bb09,a3eb4f6d,6629e4b5,903e122e,7ac2917a,4e4e077e,76ab6d54,97c1fd8a,441772b4,36f350ae,ba1863ea,d1fdd05d,f80e6e78), +S(f5ef51f9,13e10480,9a020bc5,37db3a90,3f3e3410,71bec65b,1cea5343,d43cf884,7ac5f6fc,a749b09e,9dafba18,c16bc969,e3d63971,195b92c0,fa8356ea,3419aba1), +S(2e03f430,51968210,a7dc64b9,612b25e1,cdd167d7,f6e39466,9762ad15,571ad471,f063dbe1,3f537e48,1b249a5,67fbe709,ed80c68d,cf8d4e82,53038d90,e67f1de8), +S(8244571a,ded2fff,1a4c9c1c,f3ea152b,d7852596,3e84b90d,6a3dd929,6e0ad9e5,ab14dd92,be3556b5,63cd396e,d8cb103d,cbacfd7,825faddb,1ebe6e3c,9a2e1180), +S(5fa7cf3,ad236db9,db9df632,e7a172f5,fb5396f3,c4df9bdb,d557a3ac,68a97f46,3339f27a,7a6231d5,3e732557,9ab22f3b,49dc29e3,75e08289,b816e6eb,a3ff3128), +S(5bcc702,f5f4a8dd,3f3dd519,371baa04,85b1284e,8bb539df,d8b89401,7206a943,5426221b,2e3fb26b,858a3f27,3d7b67cd,30b7c2b1,b881c285,cb29515e,59b92e8d), +S(96a96f3,79c8dcc7,f87865e5,9023dc63,95224251,12d98ce9,59b610a6,eb7ef515,bd61d338,c84a70e3,545bd8f0,aa0113e7,93f25c8d,d78ec0b9,d5b98d9e,81e16e82), +S(7e491776,5cfb89ff,edc43a8a,c998da5d,cab4bdcb,3b1d6f58,9def4de0,4b976609,7271e990,b7031b00,a990ae0c,86d893e9,915a84e8,d071a235,95054301,d0874199), +S(f9b8be29,8b5cfcec,62e0777e,d916c7d1,371b4627,9d141280,fb8a2767,1af02c8e,c6bb3293,3e77471a,5157f009,58917cb9,4cf77b81,7dc1b2da,d465dd49,711b552b), +S(9f1889b7,720ab815,e6a026e,67be852,980a9609,9e34d570,e1c2a2c8,55a2f54f,9786d89c,4fc1e09a,3bb81830,92df472b,5c1212f0,4ef05a27,dbe9d0a8,75d5e1f5), +S(fc53a56,52d4c07f,3a4af93a,e88cb4ca,5db66818,ab2c874d,63fe59d5,eaeccd32,bdbd9a97,f57136da,8f8dba2d,f34e5d3e,e1dbf1d5,ef27f,11c2c45b,98ef2d38), +S(96a3ced8,ba47f6dd,48a6b320,d88221a0,a5e36c5a,55938018,2dffd1d,3c3c4d00,ee4272ed,b244f95f,54b68c62,2e3d09,b96c7aac,fe77e9af,600a227e,8ec5299d), +S(5d552446,cb8e1882,2aab5aae,676fb3ad,b44eab09,ce665918,6fa6ef31,6f081e9c,723cc3ea,2bb559d8,da986b40,263f5551,25127091,3dbea220,f79711ca,638f77fe), +S(2bd7f7c4,8be5446,86e5a48a,d663345f,bebf198e,d7a6dcfb,da278054,f86d8e0b,584ba0a4,d2cf2664,e9d99d7d,a513b3a,5c06639,5fbc2edb,9259a51d,aa500e88), +S(1caecfd6,26d39493,a2ae68ff,f7af4b05,2373e9e6,8461d254,f9b6d651,9e92ff6a,cfa0c927,ff9814cd,b2af3cf7,4ab5e514,70d70a66,9fe1f353,b0a92182,86bb183e), +S(31ac3e18,ba88bbe9,21fd4834,f9f63ff7,aae351e1,61874ff4,2f8281e3,cd7cfbe9,61d0002c,110f2a2e,19c1b720,a85798e9,e8be1124,c68854f8,b73d6674,4cccd7a7), +S(19bc479b,1637b2cb,2e700f3a,f06b4361,ba1f5d9,7d1e5099,6bbff88b,6dfdabf7,9a59b4c7,deb3ab08,fa5e9e02,4d8bfc2a,a35b15a4,6cd99a08,9fbb0f3a,8770d0dd), +S(c1915003,caa74b8b,51576d17,de53e4bf,c5cc63bf,9c29f847,4981e180,a71fa0b6,cc93116e,500ceae,f045aad5,d9d7a863,392a3534,694d55bb,1aa69cd3,895c7819), +S(ba105ccb,b1c32d83,a57eeda4,2a9bb748,d36370ad,805ba1d0,647bdc8a,1e84a968,76adb37e,53b8bf0e,368a1a87,9a74b6f1,33116144,47134766,27f2df12,602e6377), +S(892f8edd,23341050,7540f11c,9f0ef107,99099081,dbf9e4eb,9bac01e4,94b8ad05,f0451f12,42bf423d,37afc17,74af91cd,7593062d,f22712a1,dc109b7e,f5b81141), +S(389df091,4b0f71f9,70416ec7,1388a464,c0d3d4e2,2c2e111f,f5bbc5f7,d3618bae,e12e51e7,f27256f2,3e8f8935,677aec3c,7c8f4950,712039cd,afa521f1,a88a1f46), +S(383fc7f,86bc9c65,f831c676,2885ba75,25a72886,5d6e91fb,b3ad1a53,d4e64f3,c58d161c,6a14470a,a7be7467,576a3bd9,67d7c944,ae26cced,74089773,b344b2b9), +S(cc4e9f78,9aa3fd5c,eda60c2a,44a55779,1ef31b72,8687ab18,7012ed4a,616fc628,7aaeb0fe,1a94b6c6,4c033c77,3a1fe878,b9b54559,9af6eb4c,a9e79540,faa7ef34), +S(dcf7dcdd,938028ed,f92c5797,6c3faabb,1f2b155b,59a0389f,fe1735c5,ba658aa2,2a008b2c,29290f2d,b64ba559,3c905c4f,46cdae06,ae2b687f,af0b5b91,5422d5ae), +S(75125b5e,f968db84,df6d0253,5108e0cf,df3dd50c,8ca63618,9521475,c02b26df,f6bb520,f8178541,ed169ecd,42a62d42,57ba7d3d,aeba4ad5,e979c8ec,19cf935b), +S(24f1af66,45831b37,bf80d0e7,e6185dd7,51f09e9e,5a71cf,ed350b8d,2c5834ed,2e04d2f1,b0b5d468,b4cab2dd,f0b18467,f8b78304,2b2f5cb0,49d7920c,695f3551), +S(75024c77,150ccf3f,dc677f59,118b4d6b,8749d514,256c1641,e7f70e36,5d99fcee,d36fe19f,442c7739,cc65d1d8,c7ba5479,57aaf055,38497cb8,dab1ba24,d92bae95), +S(4b0b4d7a,51b5307d,69b366af,9a621e30,258b3a3f,affd9a47,52a4a14e,562fbcf3,dffaa5b0,7133dda3,3586df1e,400412d7,6da55cd2,a978e8df,88e23415,9ca43127), +S(83c377f9,13afe5f5,21bb2550,b0a38343,5956fd13,e62e46e,75e77d96,ca2ae791,db64f4d6,6acf0537,f9d60b6b,28ad8e1a,cd9b414b,8f60968c,62a263b3,c8fe5138), +S(271acbdd,71cf48c5,e5048853,3cd6a1f,a49eb8fa,428f05ba,6d7314cb,d128c387,ccf83cf6,2d001c59,a5e6b531,ff40833,4a2b2421,aa75feed,d9ba7878,67323b6), +S(4d41e719,e003cbf7,f3c26d31,139ae98b,a0a24623,f8b86c94,6edb2bc3,1be3983f,2e052d70,6348b402,40e8da52,3b5b3011,a79451ce,41222416,ef040d76,c64a8caf), +S(2599981e,e5b9ec6d,c5da028,1f5ef995,abc78520,32951d1d,6356009f,f482a96c,9560bc0,aa47102e,1488f45f,90797862,3fd9e54c,7467d600,abfc389c,459e5136), +S(eb82b86d,84989f3,68c8fff5,5f801f88,f351e43c,80f145d,4aa7020f,ff057090,62d44ad5,d42a796a,373724b9,f583d57a,d8c19d6f,36f215cb,1c20ed12,320a60c8), +S(8637f2ae,f77485ab,a2871d48,a4f4296a,c84f6afc,b51cef62,b1f22e6c,4cc4b05c,43ba306c,7d6a184b,774e46c3,94c404da,b2acb796,ba239786,d85b5fcc,2c304436), +S(ee462322,f2f44e1f,96643d7d,bbdfe53f,ad268a49,c9a582b3,828bcd2c,e471c1b9,910ec3fc,b9e4479f,2a6d332e,4f809556,1c69f6ee,812b3097,2812079,ebf87cf7), +S(4dcb9320,6a69600f,6d327bb,624d9ec6,24e6d98b,a758922b,b102d159,e6c1c206,da85a8b3,de7b2e,51ddb90b,99f30c7a,70f1bf23,e2c90b47,eac6fe0f,b0d8f514), +S(a1373c2,d15ac2af,2c496399,1db04165,28c74259,6d9d81bc,8004b80f,a68b1405,b7a13e6b,9255caf3,ca4daf3d,21b5739f,65d1e7c,74330404,24911fdb,4e8815da), +S(fbd0d0eb,5a93c0e7,4627e83d,c483b873,96eace6f,fb75acf,ac743e1d,c7a1aa92,bdc310cc,3f420fda,28012f75,e6db4431,d2032990,d4d09a6e,7fb70fa2,fe1344b2), +S(39d9552e,136794bd,76b864ce,d929f2f3,ed4b1b2a,e15b4c9b,485179c6,1d78a846,1565f88f,f2a5c23f,c2110572,c61ba868,9035cac8,ebbc7e8,367c37a,a22308f3), +S(b92576b2,def0f8cb,e13ec334,93e2af06,f2ebf949,332fd038,689dbe3,70700e57,3d7b8497,523e3901,719145,6e908d62,63f752e8,ad2adbfe,13b6267a,ddc415aa), +S(70806f30,e3a407f2,78d59553,fa3fbf72,d5129209,75e703cb,5080627,f30b3d09,c190bf85,9f43553c,6ccacf0d,e33359f4,87b3c406,ea07d424,981d94cf,9e542976), +S(591c877d,6e4c5d56,95152fb9,b809fb97,41a46e0,446b996c,14d201a7,4705914a,b9dc4a1b,e049f291,5c1e6c13,abf19e36,f6560138,9d7bb630,c853b122,9aa70174), +S(f7f3bc9c,fde746d4,fa47131c,195200ff,53c05c09,af87413d,84e9f7f1,feee671a,70a925f9,5b6477a9,f0a6dfca,b49c214f,c219cdd2,213555aa,ea49419d,33f8334a), +S(9505f06b,3a9fa87e,ae289c2e,f4217b73,edb72175,7aa4d7b3,b681b09e,2f651749,231dc38,d5d63d14,4ba84942,67e1e798,973f632f,8ccc09d8,be747810,851c8962), +S(e33e547a,9987dfb7,ae681cc7,1cbc82da,4f3a3a57,972c2b5,10c09548,6c25c04f,55b7c3af,2b3b2684,6ad280e6,51dd817d,b99b856f,409492ca,4f1bffdf,d3fbb232), +S(7bc182cc,598f9281,74fd434d,9b5c2006,e52e864a,90b0b1bc,1634639a,68e8249,2810d2c3,4bff6211,63b09ebe,e77ec622,ad045f21,f9c103c,99089b2a,f0e8f7ca), +S(83dcd3d4,8a18e1e7,353f9b0,76b7ddbb,ddc371d7,7e3d56c2,3741dc5e,c5686edc,8c297536,c3b02d6c,f059db38,791e08b8,2ed1d82a,8cd03186,d2a0054c,862fb085), +S(d4b08924,b8e71bd9,6ca26c62,9c712e61,dc17a48e,bc07e6bd,116d2898,25aa42c9,c1fdad3,1e85fdcc,2f2a0a63,7308c8a4,ef3b31e,a81fce26,21e98cf8,cda3b25c), +S(1b42a702,16d7cf97,de70f734,37a36d38,10f670f4,6a34f585,f9593c50,c6976,f29bd13b,79a7e65,f4f7f94,53b920f,5c751b6,a067d288,82e62b40,7b9858d5), +S(c61413f0,7bcd6eff,ec818025,f792d8da,3643c869,4bf3d582,9a1813d3,cf38beca,68f603d3,db4d751f,ab0823b7,ed050c40,787b003d,6f6e001a,52e3ff8a,71ac0999), +S(5e90173e,8be185b2,16b0066,aa39a73a,350eeac6,e49b4cf0,546bd57b,50ceb215,455ceebe,31e6c3ae,388624ae,fa2e7a1b,fc0c4950,12c43803,c4eaee31,d17122d8), +S(7d0b2da1,8d6416c3,d47bc493,5e409ff7,6b437874,911347a6,3f8add69,8e25c6d9,da9f27bb,82034ba0,64c54a6c,13609188,584f9014,cfeba572,760b23c1,fcea509d), +S(611b1c17,117e25fb,dd62f458,7daa0258,8d9143de,e2bb133d,34377c3c,28778daf,cf1732c0,6de82698,c2531c96,eba3edbb,23aa6586,372cefc5,bb49831c,4c00df80), +S(b43dde41,96f3bca9,ade881f0,5878d347,812abf24,b1a8bb19,9a4a1d76,2f5e243d,1af78af3,acd73de3,dd2a28ea,50b4940d,284d501c,4d39dc3c,8d9220d9,37aa2e67), +S(ba0cf8a,74235782,f251649c,5f6e53e3,6eff1062,fc51f65a,c2a8c83c,e89f4eaa,58e47b3c,467342bd,4202b54,752ada79,a7356f88,92efe201,201af87e,fccde55c), +S(db06d4e4,ca9b1ce0,6d59cf88,da187b77,5e9568f1,da33b398,c682b8a3,ad9e88c7,418daca8,a8e4d3af,edd2de9b,868ac424,6faec0b8,f0b1edfa,e0e9667c,1f3adc1d), +S(8a46cba2,7263af84,80c9ea35,ce8757b7,9ecd15f5,e938f41,aa7d4abd,5c3ce006,6f28398c,eaa2d168,7e6c8427,730ca15a,19965098,7c7338c5,e40798d9,82fc016), +S(705d7e03,b5f0cea4,3720c73b,d6b4ff3e,26d2f8b,cb2f5ffe,6f5f65af,63e4fcd0,4a41f717,baffb579,b769e3a4,ba976687,4727c132,9a30bd62,61df3d91,1472ef9c), +S(e6ed0125,6af3d738,84d8fa5b,361be34,9e2506f6,88b772ed,eadc5c33,98233012,90c4ee9b,aca8162e,2b58406,83a7de20,fb181b92,da81df99,e612e122,8c8e520c), +S(95cb73bf,29e8d04c,a2bca75a,5925ded6,327e6128,e6db16b2,2847ed49,d3ed169f,b4e84fdf,526e060f,7b3d73f3,f534d669,3537babf,3b1ae0b4,c65dc8d5,11917b77), +S(aad1e800,1abd18dc,4d929c2b,c2d59b8e,23c90d56,7b0af36b,2e4bce1d,ea2ee299,a27daf61,acc02936,835d5742,74c875a2,57796038,de289d27,d97bea15,a9d6be93), +S(969303e0,75cf2eb9,551f93e9,43c5512,71bd1a29,b26feda4,cdb603a5,7e333fd7,a8800641,44578fb4,cf16d1fe,3970df68,708e2a10,79547510,f63ca035,616b2f5), +S(6aa570e3,de1b51a0,67e33350,cfb337de,23ce7af1,be879ccd,2b2a4dcc,db1ae9e,98a5f5d9,79cfde0,30fd1ec8,718d2b74,d33639e1,80d31134,85c607ae,d871f166), +S(4e469241,842ab69a,93bc6844,1b6036,578a22e3,c2902da6,1cfde122,962197f8,cc7ba90c,a290de88,e980f50f,bee59f67,ec227323,1db05d3,f11b4e72,34080cdc), +S(772efb55,d4044423,ddf466cc,925548eb,b2525458,e24bdac5,7edc33f1,2cd64bf,df73e64,818bd4e,c7abd07b,24afa4b9,8be7aee1,d115d936,8f4d0fd4,7f40876b), +S(a594e20e,62db69af,4afdd0f2,5a735906,75446d5a,71574bc2,12bf9f24,cfe879a9,1b2fc870,e5f74b0a,994e1d0c,de8ef9a2,74e6b49e,185f9251,417154a2,4f2163ba), +S(c133d96,a51cba90,3afcbeba,40ea594f,3e39a106,8d0a9898,7df1ebe7,4c38d3e5,5cd8c400,989efe10,295ac89b,8891e0cc,be15247d,61ba04d0,4ea018b4,d0fa51da), +S(3ea10966,fca290dc,b77c85c8,232ab56b,afc1dfdf,78628736,9a696fb8,92e67998,798174a7,b4729cd5,67ed639c,9debebde,1538411,94e99adf,f51c4866,990396af), +S(8f0fb3b9,85565632,8207c0b3,e1528802,310d222a,9246e686,6030f9f3,14472152,4fe2daa,d16d75c3,ea219295,661ff8b6,ad9f73a8,b06ba105,80f7f6e2,6661eca9), +S(fc22c901,b93809ac,21e1a89c,8e02093,92e19fe0,8f83d82a,733dae3e,16236a9c,8db62408,8fc9adc3,39de5f57,5377bb32,e3a1ed8,2731b18f,1ecf4beb,914bd42e), +S(7afb17fe,1a4a5e3a,eba9dc9d,c5e178ac,ab9e76f0,d3efdf96,181b1fdd,eb81544,bfbdba94,c3e5d27a,547db3c4,83a09847,3e5c118b,9fb961b4,e78a40ab,84ab18db), +S(38420ae6,13e0eef0,2cf9c567,b0bc28b0,59035e0f,d5df3fe2,d117eae7,27b7eef1,6e21e249,1c6a6f88,e2c96c1f,76a9238e,82cdd6ca,6e9ab090,56e0c1c6,4ccf808e), +S(6b3e232f,1b22dabe,e22f618e,c1a002f,f6aec9fb,361175b3,fe2d48ce,ee724e8f,2530c6c6,8062ea89,24e6a793,6b1e582b,1e630c0b,fa207505,76a6fc24,5e01a516), +S(8f4f70ae,5fc21122,275f1265,520e68a5,e2fb605c,bc3f17df,4ef48133,1d4d3e24,236bd0c4,ef445db6,9a0bd1f7,7ce38360,137d602c,58f8b70f,395e65b3,8b1f18ec), +S(333fedbc,e4a9064a,cdabf1d6,57d5df7f,86114a67,28bad2c3,29a2bbc0,b7e822da,ca491209,173bac98,fab92935,ca8dba42,2583bca4,b7e62ac0,3f805ee5,5f1301a0), +S(d00cbc99,3a9c2c65,b24bfeeb,f596ac8,c925c51c,e5211f32,74145c16,138708a6,5349ca5f,be59a8c8,4ea300,391efa3f,54b3344b,d708412b,a9e6b0ed,8deb8b04), +S(968af2b6,58020db3,e8297d90,c36911c5,786f1d50,7246b35f,86da1cea,f46efc83,453866b4,f19d5268,3ed07612,57bce4a3,173b2c58,280927dd,ccdcbc47,75cda533), +S(fa0adb79,476bea48,8926e659,c8687e14,b769c88a,3a1c1ba3,f11981c0,6934ff7c,37cf240e,ff3a6514,fd7ba90e,687ad6cf,3152f1f7,6d23b8c2,9bc1198a,bc5176ce), +S(7c4a3b6b,3b9c44f0,4f4aaab0,9604066c,3cddd61,996e259,43757c5,a9832392,36a13d10,9ee60811,aca0b269,d42dcb47,aaa0f7e1,7158fdad,50f07e6b,e11289da), +S(9c4dae1c,c6162f5b,e66bf6b3,53b50a45,d1f400db,aff1dbfa,779a94ef,ce7ae0af,2513117,efac13eb,cff70674,b3a9d27,31db473f,e198c3af,59ee1753,f4be8411), +S(c66c125,a04037f5,dbdc4254,70b16cb2,b6318a14,bcd69f85,44ed7eae,346edf13,288a0477,4c2bf346,115235b0,5f921d9a,566c32dc,67755557,a550690e,42b115e6), +S(42f5a4f7,54d8eb34,62c8da57,9550267a,9d73626f,257d21a0,486c043,58c5cc60,fd89e17d,67a052c6,71af223,2337ebd6,16e13b7b,72480373,3fc3a29c,4ecfd240), +S(725051b,43e3107e,2321405b,4f974469,be69f90c,a961e352,7bb8490f,f8d8c7ac,a143d4c0,46ca1288,97633b98,7a6bd28a,81f035a5,e1f49626,1aaad65a,7f68d1cf), +S(358d4f1a,1b94b0c0,9237f4d3,8d7afc79,f1dc3b1a,fae46a67,1a386ea6,ce6b81ff,b8caefa3,86daa463,93097bcf,526d84e,3666a231,97f3804f,3d976ae4,63fa65e3), +S(749bb6b,e9d272e8,8452ec3f,ec83ca71,c15471c0,608a4326,7355497b,27ffc67a,79d588b3,cc607639,4f410d13,c3cab3f7,e635d10b,44e9b242,583b75a2,62136cc8), +S(e5e8cc0c,a1910688,cdf89e82,da4f7a2d,265f63e3,247e5e3d,39d46fee,b00aeff0,89d4d528,60689061,aaaa4c03,469979ef,4c734119,4181ea99,2398691e,29235eb2), +S(62341395,d066f441,60e08ca7,5a9329f3,7581a8da,fb78ff99,1336faf2,407418ad,63930988,431f129f,5933918,e5d23e7d,8249267a,8f0dfbdd,7945e34f,e9e24959), +S(1a4900e6,95118e4d,9f956e99,2f868c3c,dfe8580c,64776298,13da88ce,fc9f8aa9,53bd8fd4,953510f2,72b67737,5b6179e3,e02e12b8,dcd930c8,de94e400,225aace2), +S(b0303fc5,8c1944e8,a84d9bf3,f2102f50,2bad6105,afbe8a37,b09025ea,6bbcace0,d9a29c66,1af8a54d,7b115f8b,52b834d7,e7c2afe8,c7308d61,4e64aaae,3f0708bb), +S(4b51c846,44955e86,9cdf575b,b8796773,d70ec44e,fee77957,c342d491,aac8ae0d,32480851,7180afa0,2d786a90,172ee8c5,75a5113e,ecbff5ea,444ec3e4,143a8d48), +S(c0d19125,b3fea060,45c1b2b2,4febd77d,e3a59da,4b8a8c0c,910189dc,b38d0228,3bed5e0c,e1a5c537,1d56cead,8c2975e0,f420ad89,f0308ae2,95a0c9e1,fd88d10a), +S(8bc96490,25ecb626,131c81f4,c522427b,7f8c22d0,90fd225,ab8bbc7b,50792500,5d2a60f1,591a151c,f0fb3a68,709e1050,21b9148c,5120a79d,100bd319,aad0479e), +S(4acec462,c6566ae9,c17ee177,61822b5b,5ca04619,30270d8,d5b3d342,5e9daace,82832a6c,ed0fcebb,3f40ba27,6e964981,cc0ccbb7,e2a1bffe,6e10014b,c563b12a), +S(6e7b6406,8e3d11de,ee7ccf55,1cf5a34b,168c3f29,d013a5d6,153fca63,2789ea72,72fb451c,f696060a,a82a14ad,1ae636a7,e0f338b3,8aade7a7,fd2599f5,270b55a5), +S(d24b42a7,40563303,25ec4fe3,11ceb35e,68d6b158,689a7434,4cb65ce8,2fbe5104,b4ac12ff,acc676cb,49d5bf0a,7e0a4167,a2460dc6,1b833e,f26083bc,6c7f9523), +S(5ed0083d,2205815c,576c2207,780d9159,7e985b26,9581da3a,2d60f088,1aaec692,2b7ec860,7d94d1d1,7dc3d67f,caa6f499,e3476f8a,d76ae00e,1a981455,85654267), +S(3a2fd05f,4ef9d7cc,6939dbea,a389521,9b1474f2,6fe8cfd4,a2337771,66ee418,5d04893e,6bfaef9a,ee8b9abc,347f3875,2c8cd5d6,d43da92e,be05777e,1b44e546), +S(a0e5e214,53858d31,7aef7152,aff56438,b425914c,d42dc2a2,61415381,30d13374,8ae28cb9,fee0271b,98fcbdf1,66dc9cb6,f0d2ec0,b1e34161,ab8513f1,597e2b9c), +S(ef690072,4a54168b,eabd6285,8c85ed24,2a4c5b04,c4c419,f3586e2a,3ee2a463,49f17e53,7324d9ec,c7feff8e,2f3e437c,d0b01d79,d92189b7,9b35793b,b367fb28), +S(fe22736e,9be9865b,5c1f61c2,a236bdc4,ce37b650,9312cf44,8b536adf,5017f096,bd67d013,5ac42683,e83239de,93f3b7bd,f1d9da45,a7754bb5,f363f501,c3059e8a), +S(4ac35582,84269d4b,cd98bb27,a708700a,5df4e4e5,8fa93963,f6108432,2e0ba4b,91e43c02,ff39da29,289d4c66,6f58133a,5e7ebdd0,1593c7d0,833bc064,d75b876), +S(1bbfb3c,d5ab0755,96cbd99a,cdec6872,4c30a3ef,92162b30,9df08974,30d378d2,b0d34d68,1907625c,726aa90f,d363ca7a,711518c8,831724ab,bd24f082,9b71a9cb), +S(34417402,cc02a6af,129cd0a,d85f6a46,5367b90,baaef255,22622c04,ffa8e389,664ad84a,dc6e21b9,aa5cfc66,fcec0744,dc0e052,3571b1d7,7bc9bf86,f5233003), +S(5e6773cd,613df09,d818af9,cb13955c,f1159616,dc08482e,2737ef50,f3cc34a4,203fda8a,74f49604,b41226a5,40204452,3619c4fd,1c42c8e,1e4c8543,4ba2593e), +S(21f0fd84,1c01cbfd,9998d5be,f2d19830,6623598b,4c6dccd5,28d4f2b9,b0e0715e,ff00f77b,605f8e47,97ecfdfa,9ec4cde4,a9dc3479,3d571f4e,7f9f8bdf,e80b8707), +S(c1ac43d4,7fbdeb41,85536fd2,37aebc3e,b9faf3db,e2155814,e16f93e9,edfa131a,6785367a,1ead47c8,2d143984,c2de38ef,f3689414,14472eb6,8c1fec2c,2b4216ab), +S(c2fcf122,56b2e49d,36e880ba,16f27ec1,adf9779,82679dd5,4ae962ce,62f29057,580b1989,62da6793,9673a54d,41a45486,a80eae55,2de79bf7,9fb63d79,432ca48e), +S(92455df8,c253c53b,6dd44872,9c2c39ee,8f68b260,bb7511f4,b33a5c65,c756d016,c2258438,3f4d24e2,4bb0394f,b05e6a64,552b9e11,7c1b4ce7,a8c59669,b2244916), +S(7e953554,4a105bc9,77ddb025,8fe7f4d8,63142198,98c07b21,8d4c6696,314fa885,320addf1,d0f0021b,5bd67519,881777e6,2bf762a1,2430b17,2f67edf3,edb7acd4), +S(2d57c338,1abbb97a,bc9bdaf5,6ad542c4,4e3aa5a6,2f2da2a9,8c368eb3,506534e2,bc0e3a81,318ce176,c206eb31,cbffe043,8597eb9a,e2c505bc,2c21ec47,2fadfe51), +S(68ff7b53,b4e3dd0e,a24f4edb,c9fedd72,b904075,8ba87e0f,96cc6a1e,4d1d3e5a,7f3974cc,ad1b83dd,9d29847f,d61fb706,f47b1b19,a2993a6a,f885db9f,ff6a168d), +S(2e340edf,431b9efa,cd54eebf,22a4e79e,9ce9de59,b5e306e3,821ceab6,5b11f576,3a5ed040,679e77f,754ad7c5,5de92610,9c863dec,3fca56ea,85dfe104,af228f0b), +S(aee71663,94e2d18,353824d9,2558046,c15052cf,e3e317ac,baa142a,e503c712,6dd9272f,877f5aa1,88c43f4a,d63ecb63,7bce5836,b0b4efde,f980c2d9,778d7375), +S(cf33b265,604c4e51,40350795,baa4d4d4,baa1b136,1bcf63c5,29d5f7de,3ffab739,113390b3,abebded2,667e169,61da10d3,50a3cb23,e2c2aac0,7e72689e,f933b396), +S(367b235c,b5393994,9a034a1,ad476a0f,a3995777,5f933dfb,4493f518,f8ca0843,e5b1242d,c9341bf5,20e7a524,75587bdf,cd571cf0,bc85b390,aa6e4578,69c4c4ee), +S(b133aef6,30e9ff4f,59ce6ab,299eb6ed,ec1ec4d9,5e4e4c6,f37bae90,e80827cc,a9e4f652,cd9aa9f6,31c42224,ddd8c24a,d6f2c8ef,26102aa3,5585d90a,758cc5df), +S(5cc2d108,17007002,9a3a6158,fea4b6c8,3ebd500c,eda5e63b,55e287c6,36d48dad,dc988502,2c2cf16d,6c54d4cd,c5a8d7be,8396f9f0,e78564bd,7bf1f822,bc13540d), +S(2434c516,40c358ab,961964f,62741de3,373bed5a,1db16197,c79209ee,46838156,3376a3f1,8f4998d1,beb23159,143f505c,dd98a0ad,225e7e3c,cea17dec,7d8867b8), +S(5b115d9,e1997333,7f74ee7b,1ab9b177,5f9334c0,6f3815cb,b987619f,e4fc35f1,29afba83,76be4407,d06a8518,3ad236b9,7b967f2b,1ba1bc6,8bcf3a98,f1d36c18), +S(a4c7426d,8bc73763,a0ed12e9,2086bf9a,3f271e21,ca158feb,d6247cda,400ef88d,7beb9c9a,efd02fd4,57e4824e,1f24c058,ad367ab0,d1dac794,58f93031,8cde173), +S(f08ad354,3be27960,41315205,670378a8,9444f336,b1e62681,d1baeb26,f356ab51,24a5ef2a,21eda2af,4b567efe,3c339bc8,1c651b02,25e4fcff,612cbf8a,f17f3401), +S(9c649e1f,c78c4805,7cad2a42,fc8feb93,b93a5c8,a4e0fe3a,3d9c5931,e2e659c4,469afeb1,bf91db88,e49e4142,207cb5f6,1f601dbc,376a3918,77e2566e,eb5f9ac1), +S(5477d1fc,48669d0f,52a4f666,5b599a3,9671f30b,888a1edd,16c4a3ff,b35b0d7e,7fe541c1,b7859b99,528da7c7,ff50c02b,3698958a,b4e96576,684701a4,10b13e3d), +S(33dac142,9de66b17,60ca63c6,887ab053,f315e77a,42fa8091,42d24834,39792355,6fa0d16d,6213a2c,82026d06,57fa1c7c,8cdaa11e,4a92057e,845525d2,ab9401ad), +S(cb80339a,c6d42daa,cf7c1f6a,90074528,6861340d,a9cbf449,4accf827,15ef15a,3f0135a9,3d3d4fa6,80a4837d,e42c9e12,c28130cb,60b9866f,d5ca9f7,2ec484fa), +S(bd7b0bae,e55f28ae,4882cb87,a98c4fd7,bf2957c2,58cc22a7,9505be2d,5c071933,ae3be725,47e45dff,31f4e5b4,c1bfb425,551dbeb7,4d5ba887,376999bf,cc0dd376), +S(654dd97f,29655a8e,12ffd72a,76ca7a91,ae596e9e,2e2e6d05,48157b93,86ae65c6,a6a721c1,5714573e,8cf00d5e,5cdf8169,e363c5dd,fe6e76c0,c26a3dce,f267f031), +S(346dfb52,da33d501,d55d018,70c7603f,d70785ee,1e3029ed,4295ea6d,19d5523d,8728cf28,d307c488,c0acfc1b,53785bc,cfd84e3c,2340dac8,e84db9e7,6739cbdd), +S(4b22265d,70f13fd6,aac7059c,c7f3c363,7200338,28a20412,2168b772,330d73a9,965982ae,f3d121f1,12b4e1a3,a31ba940,ce702a77,1e743498,5ef4624e,ac13f9aa), +S(2336f680,86bccccc,679bc8d9,1c42bdbb,944300fa,fae9aa51,3a5245ca,5f0fcdbf,b0442c58,74e041e1,acf43400,7547ffd5,fc71d5ac,934fce04,65065e07,9b13d8c), +S(9566b5ab,2ca85589,565a2245,cbc04256,5b26b333,b089878a,393f464b,4405922a,2b6ce7e5,b22b9411,a46a012a,6745dd5,6ba35d7b,3304c686,50eeab44,d245886f), +S(e5722284,b8d280b3,a4ea8413,7cb6d8f5,e7107ed7,c1e46b4c,38adceea,8323d731,83492274,77d6d6e9,f19a2166,4fba0027,7c30529f,5025b6b0,6a10160b,bbf941f6), +S(4efc3d78,d30e4d41,e6d7e04f,d65c7f4d,abf51048,922ea858,ced39ac,ff7ba548,d3f3b5e2,3ab945a3,95ead15c,ea221d86,44bc737a,f894d374,f7379309,1f18f893), +S(268b193e,718e2c07,3cb4205a,c1dea8ac,f12b73da,fc17eaf5,b3dd7f74,f9492e16,6f1e00f7,35e4c6a9,a16b0a5e,5ba280e2,20760b4a,691caa82,d959c412,5fe739b), +S(d31e56df,6a0d1e5a,f6ba93d,63a02d6e,a91a6008,8cc6a7b1,ef6240bb,83ca59ea,3693fa09,ac433b64,424162ae,bff3e0ce,b926c036,37266c07,ab6590e5,b269913e), +S(c5103c0d,6b6995f2,94e1418a,21492951,caeb4adf,edadf140,4481e674,247c54eb,7832f84c,f94d55a5,ee865d46,605e708f,a4ed1879,a1bbea67,d01140,e3aca110), +S(f95cdafa,b5578ef8,6f37e978,476c08c6,6e3167ab,73a802b4,a24d855f,39b7e9be,77ae964e,d8a3b05b,8f8a7005,1cc20b99,71a4d78,74dc40a0,e2cab2a9,c662d445), +S(b4b9e827,faacdf2f,6503b903,171fdef2,7398c819,3776d2ca,7d1b4268,e65afbea,c0143786,244ec5e5,a166996e,194dfb2f,54152030,e1bf2fd5,2d33fc43,7f955ca6), +S(9169df6c,e6c940af,8dd672f4,5babdb0e,332b8082,f06ea004,1555b1bf,d269a328,be066e6c,26a18e22,8de12272,a374d17a,307708c0,f05f5846,3ba9a55d,dcede1d3), +S(4ebeebd7,c1b60e42,d40be032,570beb3c,6671ccf5,b7f1f10a,b094da51,7dfb6971,8b8d6022,5b57789d,c91f02ec,81e25d4d,69d85c88,809f202d,2a998460,95361653), +S(8e96e051,f8d7bee2,30209f26,ebbe1f74,1db4bb35,363dcd1b,bc33ffc2,b7c0869b,ccde36d4,c67f2f29,5241fcd9,a85f2e18,c322def8,dd785c2b,232e1da0,3c9dd27d), +S(61b8b1f1,d92213e1,38673287,79bcd83,7f06b24c,331e5dfd,76d91df4,54d6a42,93b65197,a22442e4,5ee12c2c,345afe10,aaefd03a,ad45dc32,98fcf810,914d0d47), +S(3e94ab30,2d01ac20,9b0e8e4a,d7329066,ab3a32c6,b0d8160d,9e2a7b64,8b625563,85ee61a8,643d08b0,a5eb2f82,7ef70bbb,99ca044c,af4338ba,24774e81,b6fecf4c), +S(dc4ae75d,78831a0d,ac87cab5,7c6fed74,500cf2e4,1fdb8afe,7f95e81e,730b9b5b,5daa7147,1fd50e65,9a9845d2,9535f0eb,55f787c9,ac1b595e,da2fb170,b59f17f7), +S(b56007de,d2b04196,b5398832,df12ec62,7d4b188d,beb5f09e,a3cf87c,c414f252,88d29752,eec1e71f,3c72609d,f5a60e31,f485262,b87d575e,83d9070f,b72c0ae0), +S(5d5389c,741446c,1cb8ddcd,48c67a41,580dcf2e,93257012,97a8b8bc,fd20d4d,e79b258a,57ebb0fb,26f08771,d63cc6b7,6d1cf981,124cb3da,28405aa,9217c698), +S(13037858,1413a8e0,9460dd66,18cc50da,f8e93b44,f0c0245d,58950892,1d61c1ff,5374f786,906892b,77d3cac9,df04a393,f17824b3,8a9a8b47,c5adc73,2a7fa51c), +S(d20a183b,1e003892,f65937ab,a19153a9,5c637bd1,8fb1fa93,4d258555,36e334d,c1a3efc7,c1b2c14c,6176dc68,9ecc273c,fc7250bf,d059ab0,fcb068e2,7cb70741), +S(585aee85,4d5fce99,fa00d575,6922e529,abf77d52,3322bb68,7e7d3cec,b28109b,e7f5ea62,cd4e12e3,c2b43ddd,a1f7638,ebd5a2bc,362b087b,6839b13c,ebfc5cfe), +S(1b20bed,29cc0082,5a6fa7f,d1c8fdbe,13cc853f,f240129f,16df04e9,a04e1f1e,daeb1a97,17f5bf42,4972b4b9,ede42db4,7fd36247,173c0e5,b53a6994,8ab01980), +S(c9a9e323,c531bebd,84548b4f,ffe78967,a08b6399,67788ff0,4953a1e8,8c7febeb,d64b4ed8,eda75c40,66c26902,944d2744,503f6017,b8e80940,55adcc7e,b34306ab), +S(6c551219,2ecadfca,bd79055e,d4e45f98,ab4f3a96,15e3b7ce,138f6266,d0ff245d,56aa876d,efa4593d,d1140d14,19f5465c,8a826859,af6a3eef,e2013c60,330df086), +S(e242ab32,5fc71bde,da7da19,686cb1f7,93f38e81,fbb555be,db874200,8ce81571,c56f2ed3,20f7827,cbe76177,e61486b4,cf15a555,816ca48,3a72867f,f27c4ef9), +S(7ab15e09,4b5af61e,3f5b7397,f89f1711,e3c55005,1202b76e,b351cb1d,91998741,27856f9,a77ad2fb,adfd70c5,7099d4b5,8b162f6b,daa3f3e,59f312d4,d46535af), +S(e55d8d3,77e84b5f,626cc6f6,7d1d0a62,44c72dd3,78206816,35c30d95,f7541cad,e78f840c,f8056853,3824602c,3f7aaacd,2de98757,2edda9ae,37da985b,60e1b690), +S(e9a09a03,9b0a0130,f0b8667c,6d7abca4,b3e5c143,d0126565,1fca6216,c2128771,4207a863,dc05cef4,6bc6bb9c,975485f,7c9f876f,3bce673f,f160d714,bc151e90), +S(e2bfd72f,f1af92f9,33ebd08b,d6b70cb6,c1346895,9a0bed0d,7cdae7e1,65135325,afca8d06,74918152,56a53af,b0dab50,91752e09,b44fdb4,cdce07c4,89b00045), +S(656da8b6,83b95ef1,e20bc36d,e64f4dab,7c1ed8b9,261548e0,93e75d5d,525b1bfe,d12b0be8,d382a555,a71143e1,cd0942ad,9f97e771,90bd6a24,5f473204,5d867bad), +S(e5e3168c,51734cb9,c08d9035,d592b821,a6a479b7,61000156,974a8eea,2f2bb902,63661750,8782dc9c,d4271732,68661c76,d2b8bbfd,9d49c7c3,88df9360,e6ea1fba), +S(6676fa5,dbcbc713,920d915a,13d01972,82457d37,514492,f90798f1,dfbffaa1,3005bd04,4d06ff3e,4f06310b,2927b621,2a82becf,5111a825,dadd6e13,bc3fbb66), +S(4f89f4f,523a53c9,ee9571ec,33bd8768,2f620c7c,8257a844,355d87bb,7f6f0d48,131e3f25,cfc2881d,833bfb59,d917d7ea,af2a7336,ee8944e8,6c4a48d5,10d9254b), +S(9f541512,a0f7a48e,a37bdb58,dfd9e627,e775e862,5b8552df,88e5f595,c68cc80c,a8b36ed1,2ae8c2ec,fbea6d33,6903522d,714ce9,3792759e,678f4643,f880b461), +S(777387eb,9e9c70ba,dc94b9c8,f0fb411,ea6017c4,faec6aff,f6d04105,c031e4cf,6bf663b7,ddfbcb36,f833320f,7098c928,22f9b993,3de32c0b,be60b66d,61f94795), +S(b27524e2,ec594848,fc757dc7,762c6396,9938d53,4f90a0bc,78178192,e9bd94e4,f8c944cb,dfe215c,32886c9d,1149dccf,c05a78da,ab759161,22182569,a5858454), +S(c67fb320,4716820b,37dfc400,cf2e934f,4080c4b3,b092d261,b2bb88a4,5136fa41,a3f61aa1,ccd741c,f36e4b6b,1a05896f,3805089a,26961cae,ffd2f70c,b0b2df3b), +S(f4ec97c8,d8a5af0e,d8d71cf9,5450aef6,66a29847,e395d60,7c17e50,68ea9be4,4376c5ae,10e31637,7b1d3ad4,6d224dca,8a83cdc,4e78a9e1,1286b4d6,2c39495f), +S(101fb524,eac89b59,10337c27,48673b30,e24fe7c4,f9beaf75,69861984,d14243b8,d56cb44,6d9d050b,69b986b5,adc3a710,774698b8,72236af7,d4758d29,dafb1fc0), +S(3baa0ce7,feffb71e,31c935b6,ed2018d1,e2a1a694,963f0878,354d2826,17008749,c010829e,aba91b9c,ea31b88e,aa90fef9,3059bc35,aa2c11d6,4cbbf40d,bed2271), +S(3be18f6d,9c8609d5,8b595b57,1ec6084c,650ef42b,9511e1c8,8c879aa3,ad70c65e,84182bf8,9db24dd2,46eea18,639b98ec,b62f8b93,5ce1df3b,f71d93fd,ee3c031b), +S(4249cb66,d532dcd,406767d2,7af9e7e6,2a7e46d2,4a140a4,b01b155f,5712f3a1,e4b5a468,f71ed053,a060130d,e40662de,fa3a87c8,509dffc7,83c7b2de,93c89817), +S(75688f6a,8599ef01,1c89b06c,132dd184,b4485af6,b3410f20,fc2368a0,1df9fae5,830648be,b36c9c8a,8ccd1096,3f2da3e9,e4f03d0a,75b13325,80601da2,3d572a05), +S(c0b7cfea,412fff9e,92e31b33,7e133041,c81946c5,603a3ec4,3f92fbda,bb56f8b8,63a13e2d,9a06506d,dc65bc20,67afbed0,ef0cf722,e75c17e9,14c0ac03,d50ec0e0), +S(777f64d1,c65275fd,6b266e39,5a0eaf3e,df51bf38,336f6651,1140f475,dfed8bfe,d75139e9,ac863e6a,35b495f7,6ca5c554,21fe88af,24cae574,95456046,503f4286), +S(3e7e7c7c,c7cf5612,f44c42bc,51f3243b,20bf280a,8b75e7ea,e52ce30e,2fd80657,e64e815c,fbb6f263,eeb0a21,8fdff95b,19eb8cad,f3d582b8,8847b7ea,7b9460f3), +S(8795ef69,b029ff93,5e9e0e84,5490ebcf,18728b6d,f25152e8,d315292b,d834cc69,86b984af,49c56711,20630233,f30bc4b5,e460ca18,8e4a86cf,5d5badbc,bfed2e3b), +S(f5b01cfd,59a22134,85fa7eb4,d9a7def6,d16b258f,2bdf581e,e22c28be,9dd8ac3f,95696481,42941826,38a4da0b,57f393d7,65e3a9bf,dab06592,87905d1f,5323109e), +S(9453d039,9e8dfc00,763b254f,905acd5d,60b109db,6830d8a,f062f339,a38f553f,59293f71,ea51b918,334593e9,3dedf34d,9dd0c453,2b5c9b35,edf046d9,5137f38e), +S(40011ac,573a375d,7815fb09,8bfab10,89cfd5fe,7fa87734,c257a9a8,9acbe65f,40f2e596,436bfd24,bd88bf33,1e711828,56478565,93e0250a,d7b87b6b,72b5af13), +S(7e0cdca5,50430cc,404cc9e4,e60bcbdd,6611c175,1cf50670,fe19271a,4db4aedf,812709e0,1e5f03f0,dd94e208,992db41c,4bbe8cdc,fe0f0e0d,bcdcd77b,d95cff63), +S(9c60fd1d,675457f6,4fb43af1,3f25173c,f64833b1,48867172,5e1f76e7,3e3f0da5,11d7e0b9,41c428c6,c0fcd00c,fdc4e252,1084a6f7,ae780845,bafafdd3,30a21e24), +S(7251e853,65bccdd8,a493ef77,f22c347c,964b0827,20c84195,5bd367a0,c2eeb752,8df2d302,e0f90ae1,68e84163,d4081a9,b93d0421,52a45bb0,17635904,8efa67f0), +S(da466345,6e03c943,972bfbb1,5b2cd45c,83fde8b1,e22371ae,8c248431,151a6198,6659dead,d0e6dc6c,15721fa8,c00b1aab,6676fd3f,c5f6a834,9ddb4114,b5c45e18), +S(666b5d13,8d5b8169,256009fd,ab4911db,2ac9ea0c,ea7b707c,60196819,6a2dc816,d7486d1c,d50eb54d,22be8156,caa92197,3614604a,1a5c72a3,836d362a,d0973fe8), +S(48f24f6f,e112c070,21c45eb4,59f5624e,e65de1f,ea3638aa,b8b849e6,175805e4,5d2df55d,bce84e37,1a13d26e,f04f3a99,38a9dc58,c78c6c18,4e72aa8e,2ce03287), +S(3518acd8,23ac4b6f,d50f8691,90d14f76,ba22bdb,8e0c5e49,8949468a,30eb3230,e3c92847,a0fe393e,83e101ec,f1b45ba,763c725b,684811db,d2ae402d,a31a7467), +S(105b1aeb,5c85edd9,ad72a0af,cd04ed48,feb975ec,62ef031d,9b0bc668,795b717e,dfb18689,75b80da7,110cc6c5,c845e9d6,6b8358a6,2382825c,2e6c914f,54b473ff), +S(f156d5c7,f15e5276,a9f673df,590b93e8,348407e7,9f6c096c,73b658a0,a630ee70,9d9bc235,b54fc94a,4d34c33c,fa843c,1c67a074,c679b0da,64b44358,14ab5fd3), +S(eedbc38d,d0da0095,a1df4b97,2add48af,a97f2e92,bce8bf67,5ff3c134,73e5c3ac,116d4b18,5a00d9a6,b858d82a,39192f4a,a4e6f305,b2d695b2,e054557f,b895ae0a), +S(14b54fd2,cf799482,ce31b76f,474055c4,60647893,d6b46894,15676c32,3a413a18,5c700720,c08b7a19,7672fbfc,cc7b5223,6b0664dd,f9fd3df5,aaf66e88,f50824b), +S(ede2af57,9ebec635,d93ccd2,1fa74e69,d8bcb14f,d82ef9a3,570bde8,3f6e7f3,e5b817e2,3af1ee7a,38a3cd2e,41b2cf98,c2d4356f,c40dec19,b899d219,e01f9121), +S(6aeec3f4,90b048a2,cf210738,f14d7324,5ff190ae,72234576,e825f5e9,20641002,acd9b1cb,1fd56468,6da61382,cf9d66e4,1fa00c16,d886c9fe,9aee6d13,d1812054), +S(a0df5ad4,8b909123,e0de90b0,669fcfc6,f0e10d0c,28746ac,a260ce19,a678c8e6,3897d22b,fb2ebbd3,e87d6948,cfbaebee,95adda8d,f0654dac,d409dd51,669c7eb9), +S(d924dce5,a68819c,6e840326,5ec20b56,553d596e,78020430,5ffa6d5,736f5317,fa262ae2,f1be924a,18a41181,f417d16e,9013d50,c56a5eec,47244a3a,fe69122d), +S(98add9e1,45dc7541,4271c971,4d6219e5,436e479b,998a4b6c,36ca3a6c,90645ca9,34997501,ea07f7b4,2aa4b6b0,7387104b,4f20c0c9,dc1dc82a,8c2ba093,900741b1), +S(c42f3e37,2cc9cf46,3d76c4bd,e29481af,dddf3040,340baa94,6bf84220,7f9a70bb,5a1ec58,e4038781,3e9ca00e,9c53358f,7d777fcd,4f18b5f0,dd81b9c2,3bb3a059), +S(e940c5e4,1931a103,a4feef73,7e95a12f,346c3855,7a3a7ff5,dec89ffa,ec1c3ffa,5556a9de,d0a5e7be,5440ab2e,3850f718,438ab153,aae411e9,c31d1012,15705dbb), +S(35b105f5,7ababd24,19f00161,262a6a8d,2738239d,418f8f68,8c57fdc1,c8b3afc4,97e93b99,7664d080,f9236d16,38fb8457,28f812ca,9b0d47d0,545058e5,513b722d), +S(15ddbc98,b22840aa,bf698e42,3eabfb3,8f32af95,2969eb06,c24c9901,8b9428a9,33404fd3,2ef62c0,db440774,7fa7f70f,d681c4d5,e042c48b,1c7918b7,75f13514), +S(a00a5eab,1517bcbf,d377402c,d2721d3c,f493d100,3602e251,8882d426,fa69ebab,68f8d86,2708fcea,4022308c,2e391f76,9cd4e128,495aab01,dcb63473,4334760d), +S(7350c15b,8afddef1,4c173893,bf5892f1,6047769a,278c85cf,20ddcc91,125a632f,3bb33254,e5ab2964,f6f401b5,685ae429,7a33b887,99fc9861,75da7e3a,7abcaf51), +S(7d92d2f0,981424aa,6d651cd3,fc1cf104,2f24e71a,29cf49dc,c4aead32,2771f6df,f4f49d9f,f1905e01,f8de9679,b1bec436,ec0bd68b,b24e8041,89d369e,e1a46e5c), +S(2c10719d,6122c4be,8f1ccdd6,d520211d,aceb2e9d,fbba02d5,6c0fb1a8,5b3a44f4,558fb689,90788971,2e5fdb,7bf12431,3ca1e6a7,e8117d3b,8e53ee5e,b7162eb0), +S(5b271fe6,10767158,ef07e835,54e5cb7c,d39fec5a,defb93ae,122bf5f2,44758a61,d82aae85,70af5248,f1e4b784,26a491a2,d5c33c22,c65165af,de42b288,60f097e0), +S(1c3bfc2b,cac4ef22,9f946221,6f03fbb,b2d27e25,9c2e1cd5,c410db50,74be14f5,f3ee7b94,e8c24dfe,abd78d0d,737b89e,962cca9b,8fd47978,c6573e51,2811b857), +S(d43a0bc4,638e36db,c0068609,b7f761de,44303303,de7189f7,99bf611b,dfa1b233,f8877c1f,6ccb955,6e9b182,379600d6,db4bd0e3,83c76dd,42941e24,bf8fe041), +S(2e4d8eed,3e9d1d99,2f08882b,348fff52,913c9a6c,177bc71c,236d92c7,6634dea3,1e994080,635d8ef7,a6401aad,679ad721,56b81cf8,7959935c,dea463d0,b74e96ca), +S(4cdba5c9,d5fe043b,c99da326,9cd6248f,3ecde544,cf617a5,b8c73e47,cf539c92,2527e4b3,ad0bf862,f94b567a,21020d72,92def1d,8e19211a,35f78ad9,dbf72269), +S(477033f6,5abb16a1,7e4b80da,f81537ea,eb39891,d8a2f0a1,5577b1f,999a6473,c986f8d1,3b17239b,e64224e1,b0316573,18c536d7,b00d6f2e,a462848a,389c47e2), +S(2cd55c4e,e05a9e18,9ae326d8,741db193,eeb4b356,78334c1a,48453f56,4452cb72,d9186792,86ede279,dc4fa812,9bfdc308,b887bed3,1b9b4512,1b15c552,ce4f89d6), +S(c2efc599,bf13c184,7906d679,16182ff9,d98cc345,d306975b,a5285330,75925f94,9e6fcff2,981370d,4f4ee530,ab1ecc8d,4f807572,bbdeb533,6157a096,613f267c), +S(4804058a,88482ff1,bc0c27dd,31f53072,f166b89,abfec728,ac77b832,ce24387,ed62ddb0,9c4ad5e8,473c443d,ee624287,e85398a8,dc08ddb2,8ad5b4f5,4e0b990), +S(6c3264eb,7f4d3f1e,5c0c614c,cd8f77ee,a23f77c8,a22d6679,467269e6,a13353f0,158750fe,28339ea1,ccdd2147,466824e0,9c44df45,21b2b47f,540d4f9d,9b57c2a0), +S(5a2e10de,52c3e589,4f7e9807,cb5d75c6,7b8fb61b,6c161f18,661b7bc7,486f1f5,dc191e64,c33a0aa4,7a771ca8,8aec0c33,8ffde81e,3b8025dd,61314acb,e11b4739), +S(57c4ac9a,c559aeab,da34371d,c0088bce,768cc4d1,6423c8f4,daa3ecba,571e79df,5beef57b,97435345,db22f84a,36b0f1c6,7d42b246,32336304,f1f4cc6b,325f7028), +S(46b350d8,326546e9,93e85952,f4fa1b5e,4ff93d4b,2afaa5a1,5ceb2e66,fcc12665,852b0e65,a3864018,62f9bbb7,f284b4b7,e04ddcf1,dafdc616,5b7d2303,395531db), +S(66556fbc,632cd7fc,e3a8d768,b96de7ab,fcd0a7e4,e3db320b,19e9d971,97326d46,45275512,50aede32,9b6713ef,eada1372,69465b72,cc720404,aaad34b6,fcc5c2b6), +S(24e2b12a,798506aa,68b50881,1c555a5d,80984736,5a4e6f7f,b27c863f,8cbd2bb0,fb9aa79c,d205955d,4e9da24f,4798f930,2933fe7e,1cc01024,c08c9fbd,7fdae7d), +S(fb51fa7e,c8d846f1,fde26c,6c14c479,38059646,aead5a8b,7bbb05e1,a5bc12fb,6ca2fac0,20cf7c16,d360d37f,eea72322,edf5b824,3cc3daa7,f0e91a81,dc2f7aef), +S(4613ed89,ffb65026,f0481095,553fd5af,929a13c8,4013bf28,9005aca4,e8e0dc94,ba837762,a2e6c17,4cd4912f,3662991a,ec910c29,8033122b,63396def,5de2cebd), +S(222473ff,f87dfc87,403467bf,9b0f12f4,2014772a,68457462,401933,f6192499,58aab7bd,8e58d310,1849b3fd,96a2b6db,8eab6ac3,d29f9ddb,d2866980,14774839), +S(5e751a2f,988fab02,b974604,b4177076,81dc7332,a2d268a0,4586f231,300552bd,2d466152,4180a713,f6b40571,29bef9b7,bcbc0372,aefb4b07,8707725a,f31d029f), +S(3c94835,bf940014,e0c589b,3df40cc,a53c20e4,f0aab085,d8a79c26,fdb95b24,4cc1349e,212b1111,50ff06b6,927d701,9387e4d9,4d6bc1c,aa0ba14e,57f97414), +S(9fb3ea60,26b6b1d2,d56e6caf,19fea2d9,a2386ed6,65aceeed,aa66c5dc,f8fb51c2,8f90ecc0,87c300e9,3df10082,a3e461af,88bc0746,41e0a85e,4981988c,c539d096), +S(49c1f091,dc031e1f,a14b5417,3831ad26,438e85fc,407faaad,c634a0c3,8d956cf5,6656b7ba,7a5658dd,a78ae1de,74944332,22c36abc,d7272146,80a64a8f,1135e455), +S(eea69d66,68446656,45231f81,f27dff32,83667f37,4dccc3be,5bf12a42,c446e112,821403bc,f618e100,42c45de2,3262f7f9,b23dfda9,9a5532a7,fc6aef36,868eeefb), +S(c251be6c,5c73933d,90bb741b,e87c8b27,909b9efb,b40c70c2,3b1b5db1,956518b3,68f543dc,872f7f37,b8ece85f,acf3c670,bb2e6f00,7df413b0,5416919b,57aeb60c), +S(b1ef747a,4df39c35,4e67f27f,97b150e8,6e138cdd,70846ca7,3479819d,98cf4cd6,7afefc25,a30d6879,45f2b471,20b50b83,eb58b682,b61dc4bc,72c4e368,4f3c01ac), +S(9cb0d6c5,2094f1e6,ff84549e,32ba4260,a93baf84,cbb9516c,68c25c6,4b67feac,3e8e7ebc,1958e60b,cb4159,16f7c903,d63effeb,4955a11f,cb470ff2,e8935665), +S(d11f3d4d,6b18bc42,1692b7be,40589b49,b909ff2d,5659a058,4bf3af1a,7be76be8,cb42df3b,630010d9,fb48f12,e7ab607d,6fa1f829,1543b68b,5e959478,ffb6a8ba), +S(ff6a9171,de273646,9d0c0b0c,5e7829c9,3aaa1ac7,e63a63a5,fa2788b9,888025fb,335b0b06,411d6e6d,7c6d69e8,4a900f80,5077bc7a,248f2d24,2df2c517,a9bc0cc6), +S(655dd8ac,aa0cc2d4,b9543d3a,1c0baaf2,a76f7b41,caba22e7,47c1976c,deb15707,a726eb12,44c2af81,d6b5abaa,c9c117ac,75f2f6c5,c550915f,e005da5c,efcf746f), +S(4ade0988,d4c2b0c8,e303dc20,88a86aef,b2893fc1,80c410bf,d9467bee,a785e3c7,7c2358bc,74de92a5,18d38766,d13d5d4c,2a0d551f,62996105,bc59024b,147406ce), +S(9430a2f7,6f2bd12f,54d885be,3172f512,5282e84b,ab5c6bf6,7120a6bc,1e070db1,e8087617,943aa433,55684564,53d91a84,4a06fdf4,6a587c14,a2695c54,ccc3894c), +S(72b9e511,c78cc26e,f9498e38,9a15ebde,cad6bb3d,ab08462f,f6f19966,d75ae882,3a8345d9,1a0b1a37,405ea7ec,cc427785,607b84d9,d64adb42,5cda786a,fc68fb33), +S(4615999e,29a4f947,83617d0e,2847ad26,f79bca3,b3cdf3e,6a40e6af,f778fd65,5146f8c6,85b10eb,abf0ee65,145d468e,ed4ce176,705b3ee2,cf8e2f66,d3c739f7), +S(bdcee951,41a500c4,8452f5e1,3833dca2,45f94f83,80ee6574,7197610c,5ccb4558,479b3308,fd9ae072,9f97d0ba,622bfd1f,71c30774,c9be1bc7,b6141278,3e649631), +S(8a52a750,7dfa334a,1e285c5d,8c4d6963,5c3f78a4,79cdde18,d057d0ff,9bed97c,d4f40b1b,dadec733,5c264caf,e8c6d0cc,6f7d40d2,6a5d56d8,6a86b392,97f10477), +S(69387f5e,1d2b3fed,1b033614,25486ad,6ecfd3f6,eb85d8e,fc272adf,6d154915,8a72e294,2be10088,f16b74b7,4327ac02,1aea149,84a25458,55edef5,2e5404db), +S(7a8b4d6,982cdce4,c066b721,ca2730aa,5705a43c,84ce54ec,cd184ea5,53bc1099,f4460a0f,62bacaef,67238243,ee850509,d346752c,4a93f59a,5939daab,a654e215), +S(7a32ba53,a2f6c968,56adb025,10d9036,27e945c7,51108465,c88b42ff,e96442a2,213af901,378b30a2,5272dbf8,9b847fa8,32e3657c,1e5af5f3,d49ddb88,f7c9d701), +S(97388117,9d476881,84a6c968,e96316dd,4933780c,1c5b55ad,78c0de2e,aafaca0c,ab2d23f2,13ec96fc,856e6dd6,c73d10b7,5a0e1c5b,b901ecb3,79dc7544,5dcbc672), +S(500491bb,8e971056,380ba6f1,a02b619e,763aaf4a,bd07f9cf,50f86dba,61833354,ad296ee5,b4c32ef9,728c1924,562c0fac,9360a6d0,16f2651e,16f4c49e,ab35e600), +S(1c9c2015,bd266fdc,fa123aea,45428d07,eebbadb5,2fa10d83,7b4a831b,4ff086f9,73b714a5,71eba339,c58d8449,4637092e,9d44ce29,cf039427,de75b540,97916fe8), +S(5a4361bf,44a082c4,4e87d4c3,4173c910,8a3ece47,ccf3d3de,f933e9c2,fe649df7,184372c2,fe0b659d,57ee278c,f3aaa9f9,c6f3e45f,28c8ffad,54730dea,4df0bc95), +S(f6ed8161,c49f7ac4,931d90f8,fe41a400,367d8ab0,ec23b0c5,74886906,86f11eda,6c24c798,f1d88a2a,e2c7b32b,867e930a,41f425b1,ba59b01b,f971306b,a0b6093f), +S(ba392129,6be5773e,a8b509a,408b556c,deb7953d,a5165db8,d52516d5,36cfcf01,4cf094a4,9c06691,bd11a7d1,864ca452,29e91f2a,60b1cf0d,d9bf1162,901cd89b), +S(eb96dc04,ea36d6a,43823477,d4b6e3d4,a89da427,7d959962,3f31afac,49159203,17ce0e2d,6fdf1ec7,3808ff72,aa9d1fba,5038b698,c3f72214,9db254d0,98b714f0), +S(5ee66f18,669dc60d,a3c7074d,c853c51,21f6c584,bfe5c2d0,949d73a3,24714f52,238d8d46,f4143d4c,e7c74edc,78d1fab0,a42e7593,7c340504,e259dedf,4b462433), +S(71979eda,cc7fa635,91767e7a,57f8a1ff,eed003db,8083c41c,ed252c52,438b1e11,94e75e9d,4f3bf3ce,5ed2e8ef,9056d3ad,bdc9f9d2,4e51edbc,9f2b2bb5,90077c18), +S(7a301d3c,f6f6407d,8e62d5c2,4afb8ddf,744c2bc8,d2d219d2,8d912585,51c23351,3578a307,3dd4766f,319d6a8b,190b8a8c,a85ea7ed,1c54918f,73293b5b,5964652e), +S(8b76e056,31f5ec6e,33cc1267,9b49d9b1,16e8e06e,b3ebf91a,a3f239e9,8b188c42,9f0f4f92,a43cdc9f,f1d5b031,44586266,9b65d7dd,707de8d6,23dd8fa4,62c2d96f), +S(7de9be01,b8ee5708,9fa0dbfd,69757649,4d9d2eae,756bb9a5,f9deedfb,d55a6019,8947c62a,fd4a1e7e,dd70af94,f09aa2ac,aa1c43ac,745cd75f,dd1618fd,49251a4d), +S(d0766e37,769689c2,b55a3839,968e1eca,58824760,716c100a,29746728,4f6254c6,fe00274c,f3274a8a,8c529570,8b122d9c,a226fe8a,843920e8,a17f5468,ee2b0870), +S(61e74942,91821765,e144ef34,37c24dfa,80857029,35fdb2b1,511eebc0,324e9523,a641a75d,8917abc1,fb36b5c3,beaa84d0,b4230817,2337f50d,78b71b52,f4373524), +S(a726ab19,5125f8ec,e8cd1952,2facdfa6,2994c4d0,712251a9,8efd73cc,213773bc,2064d5d0,ee2b5cb4,5567701e,a3015c35,f3718700,af2aee6a,22202325,1fe65afb)}, +{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), +S(fc479625,fda0067e,a75631e9,c79999b6,dbcaf7b,e1b69d64,a75b08aa,f3ac871b,d550323e,54200c9c,393139aa,b8bf3526,45520bf0,d90f6ed1,5187682a,79515de3), +S(a39b8f47,efba84d7,1b781439,f8c144fc,9b637215,26aa6b68,b55d6a59,137dc291,56c6dc,511a8494,b86f9669,504985ef,e88789b2,83e58916,24b9455b,d656cd39), +S(172d5d5,21edbd11,beb288d3,4ee78e86,a1059bb0,5d781bd6,d9589f23,46eb7833,5251dd9,10553e2,d1476e70,c6d2cfc2,397ea7f1,210e54df,d2f61425,60bfe73f), +S(e5f972b2,d1723e8,8bc6ca8b,ed3ec1a6,fce0e6ec,fb13cb86,efd61e13,24d4c41f,2e072ff7,ea3c48c,8653c0c6,595c2c27,d7953185,4e3e1b6c,8c1e7cd3,bdbf9ca), +S(f586c6c5,44cb108c,edd7cb15,6ea36607,d411d162,730170da,51ba1c39,a1e33241,dd5425c4,3f49fcc3,c92753bd,dbfc4de7,f7ad4511,f8b720fe,b07449d8,8919888e), +S(e324072c,8d3b5516,1c32264c,e2287b41,eb8edab8,356250d,b958c37e,555de216,4bb37975,35b72127,6ef1e62d,82608300,9c04b2b7,24655acb,c2d3a06c,ac55e7cc), +S(1b76872f,cf8f2297,ed95552b,17bba313,5dafb896,7f2a7229,faf4a4af,fd416fa6,8c389799,32b146ef,87aff36e,4d6e1891,a2acf7ab,2f362302,d13e34cd,7a34adaa), +S(797e7051,903abbe1,9735f94e,acdefaec,2f2c8c60,13a6ebb,d06a4234,14820bf2,ffbf5cd4,19e47bda,cf59491e,55d3a3dd,97d35b8c,1b824c79,955ff91c,81269563), +S(e3e22849,a67edc06,10662641,d5975a4,ce59650f,e9ced88d,4865d63f,e0ad948d,551b701f,fadbb47e,ad4ad324,ebb01c12,c5ba2ab3,754c9762,cc840bd5,569897b0), +S(50e49072,aa2ff6ed,2c8705af,1ef1b703,903194f0,2c91c0c6,5fdd46e1,2a01e887,b55bdda1,e98db862,6a283c64,e1e813b2,20e26556,921eb4bb,b72894c9,27be1c7a), +S(d1b0abc1,e1164bc5,277353b9,84856cb9,1c55735d,9d475ae8,8cc743ad,b0462739,cf712d30,edf88915,373be307,e1f7e73a,244a8610,e7c6718d,112cc414,4058bda6), +S(62fecfbb,c1532096,583a588e,cd7b390a,7fae6e93,a675d14b,4bc99ba2,546d5573,ccdd7145,780cfa94,7e4f20e6,1729ec09,6ba6d28c,c2a53ca0,65d060f6,1fd9028a), +S(192e0299,75cab01a,5f5a8428,ca2c283e,1b300925,ceac8290,1e134c8f,97698d79,55f467bd,8d0db18f,cb4c8b72,2784ee99,8127067e,bd1314a4,22c063a,4755b817), +S(eb5a94ca,29e28ddb,11907c63,fbf8fee4,e1677ab7,205c5539,b0b3675b,f5fb9b8,6e9bb010,1fdb591c,c65702b2,cbb16061,cc7b8698,bb693c28,e09e853a,fc00ca), +S(4cff025b,579f9c57,c78bff07,115b7268,39a20ce8,f893e5b7,eeb310a9,c738c67b,d1531ff1,a839c908,97afac4,256b35f8,5bb31903,3e8f8e69,b2a9c13a,ff6be9c2), +S(bb5f423c,77da9a2b,540812b0,1e899dd4,a100bf59,46bd9818,ed4c2e6f,103be9ba,d4851c37,afaf40d6,68de6a6c,3a1d9209,f0fdcd0e,98310455,61210c7f,a1a797dc), +S(86066254,59e38927,b90d60b2,f9594e27,5e509366,f5678d35,133bb9a1,ad4b3262,40900453,bd36c557,10f5c8ac,492186fc,f5caa74d,12c69b2b,c28dad4,9e83e690), +S(81d52fd2,14f2d1dc,c386ab9e,5fdfa5e2,99d57284,7f55917f,4468bec3,812cd638,8b131ad8,2f24d27b,87e73419,bdd9d41d,795b9466,9268a11d,c8b87e01,7665f2fd), +S(7cbb1f2f,47f57e0d,20be44ab,2427feb6,18bc6b82,6e5f4909,51e1927b,bc596ccc,bb587bfa,d416ef29,aa36ff38,1f448f46,fb2fc0d0,a87e5170,8313715f,30cf3d25), +S(3c6e6b89,2e897388,157d3565,95ad59b4,334394ac,b33a3a24,7c455d90,a4dff784,b79d7d85,2b62e00c,c340cb8a,d42b489a,bc372022,75563918,fc9b81b2,a1b58b14), +S(dcad5a44,4c6ed0ba,2206a2ac,92e2f0ea,6c5fdf7f,28dc6bd4,7a6a48b1,d32d7e2c,6300d599,63fb36c8,f0d3109d,161ba1d2,9f718697,6694a11a,63377075,b944ba19), +S(c8515e28,b0f7d1cf,6e3829f,8d0d43d1,cb382299,1f781962,b265b268,c09a0aee,f33e0699,9385890,5520fcd8,f06123bd,3429dbdd,cdad22f5,3e80d951,b620c70b), +S(d1f81565,ebea70fc,6ee132b3,79e11725,4e4f84ad,50e04282,ec23afb0,8e24ab,38bfa250,6628029b,721a11a2,4af41f28,7a4f20d6,87a3c4c3,815deffd,bea92642), +S(79c02a3d,93cbfd75,2dc01fd8,a4d83626,2505eb13,92f4800,965086e1,51cea673,aeb43c57,458510ef,202aa9f2,b904fb34,6350d4cd,ae8faa3,d246feee,8da21571), +S(b476ddcc,6a6f785,b1b8637a,a22b1984,30574567,1bce6b36,ed3738d1,8c1c5f88,e71abebf,e2019b3e,99b27560,d4ea4ef0,6d52d300,14c462b8,1daa5a77,3ba73176), +S(937b753c,2d7cd681,b1e48b4,4236aa73,96968213,b57c5af2,3d48b0d7,cf64523a,2d88bb55,e67d4ef,adbae06f,5f93288,2562b9f5,99b50523,e6e05cec,fb7baccb), +S(7e719005,dc42e572,471177bf,80cf531,d31daba6,f2015664,d46c4df3,ee9840ed,80f9dba9,6a495938,74704313,613e3bba,70ef8e1e,83f2063c,566d2791,d79148aa), +S(70d04693,54db73e3,780a4413,804f7cc6,ca1849f6,158c1b7a,9eded185,8071e826,ff96b0e5,4692693d,774e01d7,5776190e,7caab3d6,72cbc1b6,1623e87d,f0f96936), +S(83bbd70b,f2794adc,7bddc8a,ab107e14,d5cc19a2,eedb59c7,71ba622a,53e2a603,eb92141,5fc3f2d,b96bde24,1d68e314,244c9a0f,42e455f6,3b8c09fa,fe3533b4), +S(8f8ffbca,72942dd0,94b208b1,12ba36bc,c324dcc1,dee4de01,ad8dc8fc,ed4f84a,58fc0a62,a5c20df9,e0de3aaf,3944c907,d7c6db11,4976df5,e38ce452,e1901894), +S(7d5fd589,955a3b87,4bec2638,19faa133,9d03ce58,2a64eb4d,643c42c2,95ab2c7b,deed7974,2d442ed3,d70ac86f,ee47bf20,9a8ec7bc,9d9a98b8,b02ff4e,a857db32), +S(19e47a2,323d5a26,fa5c13a2,78ceca70,e46bf5e8,d9d0e22d,f228c15c,8fe4656b,bb439d24,789f26f8,6e5b25df,b40a9cb9,6b3272b4,d85e4a04,e6651443,e1e41706), +S(75708952,9fdc2d9e,ab85a24d,d06a7c29,252cfa04,f2686d19,9fd04ef4,ecd0d304,c7f53395,8aaaec4,ff6e97a3,19ecf7bd,a53a3034,ab504c6,f02ccb24,2a04475d), +S(30f6959f,468add62,636c1bb2,18c2794d,5eb2d907,3b7449b9,eb5c1f7e,a5c1b016,6fe05738,e8ff7b1a,d8527ea,b8ac47b5,35c61dfb,efda4279,382e8dc2,52893c92), +S(7640da0f,4ddf3448,dd21cab9,257e6f87,304afe2d,fef9d58c,93c2de41,e9a7ddf,f1cb4a24,f553505,a660a219,6baf3485,6e8d21b3,6f661a0,baf2aec6,36805c22), +S(1db0050d,dbcb4f6d,e716dcb9,a3a54079,3a8fae5c,53c630ea,aad1dd66,f195226b,50562f14,6f5c2949,3f9e2efb,d64e2907,f7845673,4b7ddf2f,977e46d8,42cb6bb4), +S(2b5a8ca6,f1d94ed4,d68460c,ebf90aea,7506d3ff,9c71de28,908d05ca,eaf08d0e,6cac6a6e,6b8fe9bf,c733259e,7b4a7715,5a15ca6c,94a42a54,be686849,61a8e064), +S(eac0ed60,87593dbd,3c88510a,c27123af,9fc926e1,4a829f01,9fa24686,1b0f9279,5599829e,ba8e5cd6,253cc3c3,8ddd5a30,7e2e38a8,2da09504,4cde7e55,3dcfafae), +S(495c0e20,51615bf,278ecd84,508ae728,72a7e82f,88cbd992,20f2e370,1d46f9ed,ed5a3c18,27e3474b,c04b6684,bc754cf5,b8014720,145ae8b0,fc24c6f,9297b394), +S(c74debae,32533089,35ad9c23,cc038b95,f3f15965,c46dd3d6,df61b482,ba65cd43,9f82e190,4ab044e8,ad645a7a,b27e0f79,e45bb7d0,9755441e,80d463bc,b25ad4db), +S(c6d4d1bb,4b396ba4,a4393403,ced9a8de,59931eaa,beae1f2d,55c1373,77455ec4,c51f605f,101f038b,913300a8,9ad96bd6,d5e60dcd,d7702ff3,357ee1fc,6ca5b45c), +S(a0f35ff7,dfce08fe,6335cabd,c642c2f7,9a4b6e1a,c95df6a3,b4694bfe,91abd1d0,fdec4844,90ba4281,b78267da,b6dd63c6,ad0ec964,96c42407,32834ebf,b9c822a3), +S(ee231095,46b51ef2,547bcadf,14d57e1a,f4682dae,4611b67c,8d99ee4d,ab912004,dee04daf,3adb4d76,485f8e5f,bf9a2231,5e4bcb96,faf63f67,da257c4,5645d797), +S(77fb6478,1d1ceb38,ed04147b,92e46668,bc47fc0c,73c6e677,a56c9fe8,89772810,ae42f6b7,d26702d7,44c3e867,6750cc7e,224e799b,857b6c68,52936846,6a9c35f4), +S(dd205a7c,9a4901ef,3439a05b,56968951,269c8618,ba1638cf,b9949f98,d84ef11e,8a7da4f9,8a628f46,ca39d902,5e994404,dc6d09ba,8cc2d199,47936454,c024a73c), +S(d4225a81,af1ad205,d1ff1555,cd15df81,d82d75e2,7d8b6a37,a7615c32,ffb932e8,3902c36d,7530add6,a88c6e6e,e426434,b9728690,c6476d33,cdca32a7,eee99fe5), +S(237d87d4,2ab0b9bc,ad29bf03,f754d98e,535a3a2b,6a184929,ce65e18e,17eed134,bd7e8be2,8a125d86,adf47552,aaa6a474,797aa641,94edaf12,56b86a9,5057e480), +S(eb9d15a8,76dff407,4ffe6ce7,c430e797,ffcdd291,34b6f737,b2f07cb3,7f2dc8d,8d975595,aa7790dd,d531e7df,77dac484,948d4ac9,3cd1e4bc,d3b7d9f0,4dcbd431), +S(ab6ffcf,2681db28,7a99226e,3fea18e3,5abec631,898d7038,19c4721a,ae341e5c,a93ae653,4ab9ed9e,e2f50552,cce4ae57,1ab80473,38da0fdd,6a203f18,4c4bed0c), +S(28b7ccc5,53c5665a,1daa0150,102a7eab,8d6db154,b575d2c2,33d2ee1e,6fb2231d,a5eea545,a89579fe,ceb2af8c,e67304c1,f1cf936,91ed7b0,4e461c3f,72863921), +S(db7e3299,5ecaadc1,e94ce255,2c04cafc,c10e3ac0,a88edae4,bcdf941d,6a913b60,8d2cc29c,5a23d74a,76d39caf,fc026a0d,58af12be,9202f250,da8e7b6d,f6a701a4), +S(a030b7c8,169eda5d,ccbe9258,30ce03e0,aa89fca3,654e70ba,f9d9cf08,bb2a95fe,4a16e85,3c8efe30,46443cc0,12646aa6,fa030141,1a0b6f70,dafd1cf0,61ef977d), +S(580150e3,ea63bcfe,13b1202a,b31043b,4d581eb2,86b0d985,116d8b06,3a087325,c4dffb1a,4f7190,9807e070,fbd85774,194d7d2,99f203d6,4470f9a8,b8a3c245), +S(d23c6b7d,4c455c41,edf6a923,33fb1b66,43fb00a7,f5f9e0ff,9d96cbc9,af10e6d0,56a494f3,91b77cf4,3a16f72c,2084c3f4,7332893f,de676cb4,3ae527de,eea4835), +S(91a4fdd,eafdc6fe,5630351c,a1d3270f,3040e70d,7c2ff55b,2af7e256,ba853510,59b05210,6c8d327b,24cad438,891bd72a,1b71ac8a,15c9970,334453a1,a8926055), +S(f297dae9,fce4fd6b,decd1c54,72f86b6e,499a6f01,2468477e,316a689e,62c5d5cf,6a8561c6,6cf1c950,9fd21b39,d27e71b,984ef01e,b8c1fbe0,d14a76f,4153f1f4), +S(c8bce284,4cec327b,83e979c8,1c7bb30d,4f5ec633,d64269fa,8bc33ca5,aa4b72e5,71b4a02,e529b17b,6550455d,e5f6db29,59b59cf3,7fb45e24,ab69098a,a71f6bc6), +S(18650112,b904e937,5074377d,ab19db9,88771616,b47c5e90,93e16eff,8d237969,c464be51,dda23669,ef352ed1,e8eda746,3ee2c9b,f56bc33d,7ef464b5,f96c7b82), +S(58e1d8fd,c85f3d28,829cd90f,f968e826,7ccb6aa0,ec8d7002,d78d77a3,76573d48,b76e4320,40359597,60056ac8,6f953e46,6c335207,6e56422d,28d6dade,f7280826), +S(87ca9444,942ca103,5bd010e8,f89ad6da,7158a16b,f5a7774d,84ad7e2b,91130d27,f14dc3ad,8f102cdd,6e192f9e,604293e8,c80211e4,a6b6e78e,fc8e7343,84352a0e), +S(ae61aef7,e240b692,ecb12ea2,b568158e,8da85c8,1c902d79,db82aa8b,747ddf5f,8fa838ed,7248894,6ae75ef7,b4809546,7bcbf668,9e5bb460,2f711f17,6501d3e7), +S(5a91a937,f5a36f44,4a25053a,2bf2a374,aa6118b4,d7f18ffa,1b641977,d761564d,8d2be259,bc22caee,3d0694ac,b70f4a0e,7b7f8edc,b2418486,9613e0f2,7b2e2fd7), +S(8342a29f,f3739b81,f77918ff,d5a74f20,efd76175,6456eab0,aba2af96,b95b1488,5e1280f,3fe41f14,3da73a56,c11df7cd,69f596df,f98204e6,75ec2601,7f7f25ab), +S(bfd9e9d8,dfaa3fa7,a1bac396,45ae27d7,e0a2d2,aa4022e4,6df8d408,eb06c3c2,5ab07b07,1acf15ab,186836fc,29fea177,2c6ab202,a72bbae1,78c4dd8a,7566d025), +S(ae6c6419,ad0fa0e6,56fba661,834b5f49,2299c610,be8f60b9,815f4775,7ea4d9f2,95e9e9dd,ffc81a1c,112d5f3d,d59a298e,6a3fbdc9,c5fa9c00,37394081,e9f965eb), +S(12212918,77ab7009,96eceb7a,b7ae5b7b,822e92b3,e99e0308,481a9936,c3568143,b40c8be9,16637b33,b428f521,b5c4395,6096dcb4,2504bfcb,5780d42e,984f4474), +S(4cb67c85,5964d298,667173a3,3f3bbfe4,5d2f1e07,72eb26ba,95fa961b,41728597,de8164b5,2af252e0,464eefc5,7a65868b,1e0d16cd,f9c5ee7c,7f13ef2b,1f555cc6), +S(b882a78e,a897c609,29c13dbe,b0d15fa8,3b36d895,9ca15b43,d8c8ebfc,cd2592f0,13a114f0,8bc83d53,103a7327,b92e2289,d18b6cbb,39a9571,16b19c8b,77a714fc), +S(7f77196b,483fa953,39b28b5e,464f42fe,e3ee50fb,3384e401,ae7e5a63,70544479,d66bc424,8370ffcd,445f1aa5,38dcb965,68f51a62,4babede2,3f59ad63,8dfbfe36), +S(d04af491,28f406c0,26c8228b,a270962a,7c45c5eb,51c3cbb6,856c8cf8,d2da8959,c354ae41,f03b906f,74b9c259,5a675bfc,7d6389b7,1c181e6b,1b0bd779,b9e47d71), +S(20f6bd64,cde466fb,e0ff2436,4f9d02a1,d7ad2a92,3bafafc,67a1a154,f1a572df,13dff561,a14d7143,369d74fa,c7872c6e,f57d1e78,b0211f57,ad9a2363,19ee4f4), +S(2ae2e2e9,b53d8788,5889bebb,7cb25669,e75ff2ee,ba305324,a2473937,1826365c,6e52daae,1c2a50af,dc37b1ef,22782d72,7a10f128,225eb816,9b813970,fc14c68), +S(2b50215b,7f3489e,c313d5a,14389c02,1c72b1f9,68ab37ab,d9f4896c,6014808e,50069279,8b2a2226,defcafdc,8a8bdd38,dd7c9a13,f5a2157a,4d0942ba,5453a859), +S(d4bb3a0e,7dd530e4,ae3bcc5f,4001686b,ccdc81d7,6c79c131,288bc2cb,76c72717,9c58063,898cd752,23187ac1,d446c8db,c2918fc4,632c1bb4,2278c0c4,48e97d19), +S(82cec682,b714ec75,6d3348f3,da10fe60,885c790,99822f33,d7811cf8,6077284c,c1f14f0e,670e1bc1,ab604e11,8f3c2827,7c86ecc3,79e97e39,6776594f,b4750f6f), +S(b08b799,5cb8527b,c4c976ac,a6675f03,a82cff9f,309eef60,e78ca418,71486c5a,70df1520,c27367ce,53499421,35fd0daf,ba7df181,f66aff88,b83e12f4,f1b57411), +S(44541703,b3f11462,fc2ffc79,b28237fb,3f6d8611,44c66891,e9cefbd5,7f75cd9,e9b53337,162c5629,eabf13c7,f0433cdf,dc41bd64,9238b810,96d2c8f0,77a5f165), +S(5726f775,b5164bc8,9fa8dd60,267615b8,d5aa1be8,540ce3c9,23271a65,8dfde543,31777af1,58e103b7,db7750cf,37f42dcd,6a155880,7f5d426d,1075d8f5,9a83c9b0), +S(c9993bd,7368efbb,c20b1082,354fcece,b072a3dc,a5fb5e68,73bdc8cb,94ca2b98,3a6b4c46,73d3756b,76d0ad69,701af08b,3f4bd359,3c5ddb40,94eb9c25,776063b6), +S(8b12af05,efe4bafd,bab8b73d,830db99e,c3212e17,bf2f1245,86d821da,82a11b9f,32eb833d,79e92f26,6bfe6840,ecfecdd7,ce000f89,14326697,562372db,66d36ffa), +S(c7986b3a,f4992e69,24363fca,fa8b681c,4cf60003,beecc0ed,af312080,d9329f04,a8a72ac2,f76dddac,faae1172,82965c24,d8710ad5,1a1a5863,5dc2778f,22ca0774), +S(b571af4c,b8fd57c6,2ce4b52e,8a38305e,b3c2b5f7,1cba5931,6dcbe676,3a219f07,4c028e68,9d95d4c6,b974fc05,e7a3a264,b1410fa3,2be80588,32986d4e,fc9976c), +S(412a3d77,6113d30f,fdb4ac2d,1be60a3b,bf93fbde,c837fcd1,d23fe917,811fe6d5,d8dccd67,8856db2d,c698ad2f,269aed7a,3c1255de,590c8208,b8611153,f18faba3), +S(33e955e,9aec13d0,c4b8a61d,455f784a,4d22fd0,f935d7e4,69a88dc5,44c89426,668a62cc,9b903539,a26d8de2,44310f07,d8304b7d,2ec1f4fe,35251b82,220c0cf7), +S(c7cb9ff6,4e7c8dd0,4d05f9dd,a7f106c8,a9841fa7,1cd25eb0,2866a34a,74ddc670,d436d69f,c42c21bd,b64250f,19a15191,bc228b35,37469444,717f4c52,a4e9bfb2), +S(9b6fab7f,f701e6ee,efebb2d9,3c4432e0,826560d9,8aa5b0d6,cbc31c5d,190768e5,f01de8fd,bce677f5,5602113b,90853f6,da7f8029,beba0c02,d20b599d,5646d773), +S(48e25e2a,cfad81b1,315385f,25c958a3,26c425a4,9d75c2b2,1a0233f5,9a830525,83a6accf,d0d149d2,b5dbf766,2bcb0bf8,d725753d,50615657,2a0807fd,882a4d6f), +S(14690774,db72e162,667b9033,be102fb4,f1fd648c,858dfc31,a8b17513,74bc9792,d919061e,6c624203,1f0641f5,bfd7466b,ac55d890,a3b1175,12a4517c,af9a6cc3), +S(941b1555,4838a75e,7762a4d8,fca39187,bfcaa3fc,9869df23,93d6c77a,2b956d18,348db67e,845f7133,aaeecf17,ab75960a,954d0d2b,41ea5e15,be098ff,c4a43d09), +S(487eef1e,77bb13e4,821fc8ab,c9f4448f,672d09fe,5fdefd84,2a9931c,477ae38d,eae4bebb,e06b75c4,b6d37238,faf0237f,5b035c2b,cb084825,93053964,33bc4b53), +S(8896a835,37276df4,40f3be94,41267b4f,4160fbfd,51e3f01a,f675387f,362b0ef4,feb71411,db1429f3,5391993b,e461df0d,c3beba79,4b1b90e,cfdb9338,80e5373e), +S(c6f6f864,baa97e54,69407b28,bdb459db,d1af42b7,19da64db,ba274ab1,58da440b,db83cf5d,feb196dc,5023736,c43c1d46,d6ddba7a,44805f36,69f639e8,f2759a33), +S(c901d3e9,1f590c4d,547b5715,dfb1a61d,f898215c,2be28af4,a4d9d229,7852c00,821c673e,77517338,da3617ec,53213d08,9f695c29,2a5ce31,c60a377,428db6ea), +S(19707c8c,3a276dd0,a54e9cd0,b241f54c,470b508c,ae773fdf,20810696,f9eda3e4,1d8832f7,92db5867,73f1d260,39877814,411f502b,899282ee,ff205495,f04d2119), +S(e197c27f,cb20bca5,6c593eb8,7d677048,5b70596d,4f35c504,acc18bbc,49a54230,85995a28,27b2715f,ce2a682,b727e7a0,4c25f412,407bb99,20cf55a,f756027e), +S(5bcb759b,56bda507,23e45cec,4689f03e,d04ce46,497f2409,1c5a93b,3799ff1d,b068ae2a,47e605f7,f9005545,a563ae91,2f841713,15ee191b,d81e0d58,6d68ee9c), +S(2acdf086,f613c0fe,1299e13c,47568fe4,701f5831,1f515c74,32ebbc0f,cb0c5dd5,2496967f,5f3aa9a,352cac15,d3fe9880,a862925,45a2bb5d,7600c1a3,ccdb6374), +S(268c185f,5d0d2fe3,1c1e2850,b3c80f09,f896134f,5f410524,8edbbd5e,bca357b5,2e81765,ab1c4336,6f782895,35a39076,b8501008,41c574df,d6d25b29,707feff2), +S(b6de69ac,f84f7cf7,48d50a05,dea4faa8,9655ad2c,98846edb,e166e2ef,de4483df,3c377b81,ffa03daf,823a5da,e0d4cb27,77b585be,d5fdb889,62c3a3b8,709ddc9a), +S(bc71d28c,ecd81488,5a76720e,da59deb5,f6d4cdb0,36b2bbb1,2e566d58,2843bd07,501055b,52ddb633,74bbefa0,62ee294f,ced29ac7,4398a634,b629532a,3f50f1da), +S(9091a40c,3a3bb70d,d28cb8c3,ade93,910b783c,40b4a2d4,a48facfe,50c524b7,c1bfb69,3ab9ef96,9eaded97,57ed9621,92344389,e62f6c9e,47c51d8f,b75c1436), +S(46a3e416,8ca5d225,1e01eef9,6cc422f3,da56a59,81fd11df,4ba87e88,ebe6486e,e3630232,96c0efaf,f93b3d4d,2367ea73,3d776180,d98abc44,94d1032f,f49dedef), +S(869daf22,c0978d91,20595281,569f2a43,b3afd058,9e2f29dc,c0644dda,fd26ab6d,58f2ff45,bef8eb75,244e93bc,93d58778,c7a1adc8,c2599c04,635009cd,12f8a6f2), +S(1247ffaa,76f92f50,2e4408b3,2d373f38,79a93634,ced87989,c3f666ef,ffdcb366,8dc9de29,3267dfe5,1966ab2,9462d5c7,d81c205c,536c6eeb,4f2246e1,1848fafb), +S(e25575ff,bf62e7d7,aa64255f,8ad222d7,4ce23ab0,934a3c,cbb80d92,7fd98272,c6c749cc,320892c0,31b3ca54,3920afec,90217d17,5397b6f1,1ea201fe,414c1d24), +S(d02c3fc1,68bba27b,ac38bb2a,4fc7ea99,66e8da54,75f9dd9,fa131fb,d2862057,d24c229e,85b30ff8,80b87f6b,ca145250,f4f72907,ec33f51,94c2f8f4,13a8932), +S(28c4002f,5f1fcfd8,d9e13789,d2527f5b,d2788649,72d5b12c,37dc5c13,b0ab243f,259617c3,7c84d212,2ea7b4c1,33118fb9,9cfdbbcc,db707ec,e99b37ac,12380123), +S(a4d02f63,3f6edcc9,88970f4f,e8b0e639,d07cf277,1a6173d2,1e54594f,65b21770,236c19a0,4bfb2a49,98c776b3,2a2dc4cf,7e91293b,4bdb7d4b,a0ed62a,64683bb), +S(f28f22c1,c3ef5444,fd373435,23e97c40,5d3d19f7,21ee5bd4,53087e95,3d2d006f,fca3f966,a264a422,3e861dee,c5844b99,8f245a11,48301797,db141374,128ae075), +S(7ec145c9,7f1bccdf,ab49ef42,1feaa816,e7a6efeb,ca371e4a,29b7950c,ce8b10e4,a278eb3e,1e9b6d14,52f60e3,5ead3083,114ec862,53101724,442482f6,4fe7f997), +S(66a1296f,f7700439,3305a768,bc9712b9,c6a8b79a,a4211d82,900f39de,3cad406f,968f1ac8,70766942,67d06a0d,655279aa,6110ccf7,7ae73873,4a0f4ced,2848d887), +S(f9e2f7bb,6fb1c6fa,760ded51,d465ef1d,b1207d97,660a360a,34be4dda,c5ccf177,48df22b6,c18fdd1e,213d5a1f,a70084df,2419d324,6811f90f,efc5bf8f,24f25e6), +S(f19fcd39,2cffecc4,4f0a9849,6c0920b2,11ca3208,ab312a84,a87bcee6,f6d5f6e,df36cb00,33f564cf,c2e1397e,5d38e21e,460b019c,9bb86ad8,6d4b9e01,53528261), +S(da3bbf50,f63c674,245af2dd,ad0dbf7,7644d069,bfad635a,f6065c52,f6b4b1f,e6babe9a,281a2a99,92b0f5e2,a1377416,e6d143a6,a2de5cd7,dc91eeb5,b3d0c4f9), +S(d5bb7b31,cf5345b7,8c6c0f9d,bf94bada,3d917dbe,2ba7bbf0,f65b2be5,eada38e1,e8103661,6c69aec4,31c7260c,731a471,e236e453,dd0733f1,8e5d1204,bcfabe61), +S(b1129318,36da4fa4,23ae1331,b1adc768,f1460e0e,22331fc1,4cebcd25,85d40d7c,9f8b7276,27200133,b69adb10,ba95989c,22fbb25b,723dfd60,7d1f4815,293e0856), +S(5bd95654,67d6794b,fae7bae9,df0cc02b,a0dc7ccd,cc5d98dd,5ef33d01,99c10f41,867b8536,363dbb08,234d6be3,d8b25a4a,7caf5044,2546d3ed,8f9d6d95,dd279619), +S(cab5c72e,7561a912,25cb65eb,edefc6b5,2e36caa,5551a749,7ac30cb3,149e6b55,f88e4081,3a6336ff,82cd632d,53590df5,32e3967e,37ea5aa2,bef69000,7c683996), +S(f3198dc6,d55fef1a,9273d311,b0365422,ae4a4c9a,2d2e94aa,1c4d081b,2bf138a2,aa2554e2,8ad481c0,d8376221,d15c3937,13f0553c,97b4f8cd,7b341c5c,72b4123), +S(900f4005,d4af3591,a1f518d8,2cfebf0c,e11f6a0c,8ab82367,337293dd,c823d8e,dd729fa5,d0fadbb8,c294306a,e0e2dcbf,9def32a1,1d58ce37,cd318e85,63cbc99e), +S(10f24db1,481336d3,25716449,c08795f6,efd8e3,f49fd445,cd5dfaaa,58a7ca05,ebdfa0b2,75c6fa7d,79751a4,e66b8a0b,f92852ae,bd108f19,a6feb9e4,9a49d936), +S(4babe89,ec5350a0,2ff673e,2b6fbda9,a1e826f7,ef060396,af08bfcb,8da15719,8415f595,ba1d8e7c,e287fcf5,bf386432,5a5a965a,a5ded5ff,4f9e85cc,8a287228), +S(212b485f,e7f39183,1605bbba,6b32cd0a,e3dbef40,a52d1adc,91362a0b,1fc783df,91a67656,9eabb6ad,dd13a646,c07b5ae0,f93c942d,6be6e96d,3d79ba89,5a1ef56d), +S(4aa0d59b,d8feec6b,507dedcb,eeb3feda,ea98fa96,4cd72734,811a72ca,d1f4fdc5,3d487788,3608eea2,dcb5fce9,dc5d25ab,d9bdfc41,ccdf7391,7cde90ca,ea6fde61), +S(dbad6aa7,b7e547ee,8c97e30,d6653c8b,9bf7c37e,679f8ec9,b74ceb24,2ef65c33,3d39eb67,c276c7c4,24b1e367,e71de6eb,dd32e624,b957cdfa,35081b53,510ffb4a), +S(e0495f52,49e4394c,27d9f2e5,e01c59d2,dcffc868,e4be4ce5,1fb114d9,4607901b,e77ab12d,732e11b8,c32a18c3,9c8931b5,f780f62f,7ce0685f,3d921e96,7d21de3c), +S(aef97af4,f923b5e2,3245ae92,9a0baaab,6c14d1e3,bcfaca45,a7c6dd20,58c6e2cb,83e51238,a46575b9,183635eb,cae26493,25acd694,8c04b911,d05c0e53,dd9c61cb), +S(831ebde4,2fa1913b,f4e036ea,73c22b97,916a61db,73918efe,4f94da72,e714235d,60c29914,c09663f5,e6af5b6f,e3b8da4,80a179ef,70da6c98,8ac12a75,10162124), +S(e4db4221,e7ab4db7,e473572,ec6034b3,96537815,2d1d8bdf,e3ceed44,2f24dd2e,359b878,b5bd2f,53f9a275,384f727b,634894fe,a772d1d2,72568a4a,a4d83d50), +S(2f144d89,972800e9,e0ef550f,da814390,9a106ae5,6b2b9dd,cd0f6855,1d824570,269e925b,ab060ccf,84d4c79f,56a557cc,f476b477,9e73a4b3,872875ee,26388dc2), +S(b3638ed0,d52b3292,f7b953b9,7f6df07d,8d1d5c3d,487261a8,8c25a2af,9a13cbeb,54fa96f6,8f475bd6,5515942d,b8d6f208,99bac252,b042394c,fc73a7a2,adae3113), +S(48c7ecfd,5dc8eb51,7827fddb,2430b600,ccc29edf,906b3db,be5151f2,590e56bf,85e43f35,7d9f46ba,8e5a8903,a75d6d36,bcaaea65,1666b1c9,b7e7dc72,487906d7), +S(963dda96,74cd2b15,84c677c6,dd6d91c0,c968d541,1941f5e5,9a2747bb,4f6a69fd,5ae7f7ad,fb515e1f,7790b789,8d2f801b,b764de6a,f5c33fe9,c54ce712,e4c23a1a), +S(6a3c5404,e22a666b,77396b5e,5827643f,ccf4e3e1,7b8b7c8b,6ad35fc9,ae21b1a2,780c9b96,5220c67c,3c8f8e0d,fe57f1df,67ad445d,4c2f0c41,483d9a32,d558206f), +S(14c13d08,209e5619,df06c33e,ee8289d9,628d4ca6,141fd46a,aab75be7,25a79c15,7acdf79d,b5722728,cceb5416,18c1555,4d833aa2,cba5be7c,5b56ed26,7c323bbf), +S(5c83e244,4ef9d09b,d8d648c4,37af0180,a376173d,4b6a23c9,1791d211,f4ba0973,8a041c51,d8001b77,8cfdab74,ebcea960,414269c8,50e52776,61da8c55,2f06d765), +S(824300c2,d17d63cb,131d489f,63c914d6,75120933,667be49d,e0950587,13cd17cc,94cfb246,f97bf2d6,e9de7b17,fbbe864a,521614e5,1cf6eff0,9f949657,f60c522), +S(691f9af2,1a0e7506,f16acfdf,ef22fb51,fa16e068,86d4ce5a,82bfd069,7fed7406,33d1d8da,91b28358,913089ff,dd0dfe0b,1cf5c3ca,1b4acb43,5223e353,5be8af3), +S(a0014691,2dd02b0,bf8533d7,60cb656a,eaa87ef6,93959f13,df81028c,82025aec,644e45ac,2729f6ee,22388317,a18381db,e1675a35,23ab2820,87afb9d1,48f777f7), +S(7c8f565f,228c2015,f1624956,146fa45c,945f6bea,b69e1b9,bc8401dc,f95d3331,2491f474,81df8eee,6b97f82b,48506dcc,fbdba731,44dc6e9b,29a1606b,22bff452), +S(bae86f26,301c873d,2f5cb288,7b2dad60,161410e4,db4b1a49,6477c58c,4817c582,65eeade1,cdb0ca0,14d50596,6549039c,a0c6e43b,4514de9b,fc222c93,180a7bbd), +S(aecd8a88,4bc42d87,b1c49637,ee23c3a,364c04b7,c16ec871,11c9b447,81116c69,fbe871f6,bc384cea,b894b0e5,837a6da0,98f8ab45,72b82a15,b7e7a058,7d93350a), +S(51388726,2e51e2d8,9c5f4ca4,7a6d2aee,3ec63b6,7ee5515d,4bfbdd82,6318278a,319c5fbb,2cc90ee1,3b3c980,3f2ccdf6,18d9f3f7,d09cde94,12779499,9ca87b3c), +S(29826f1a,27d4f62c,9f891a35,82ede6c7,163bdd5e,22f10325,6eea348d,cc4f5cf8,3f473cd2,9041dc75,6afcedde,34fdd6b2,82e3ebc2,baa2948e,774965a5,6d5c6b5e), +S(2d36c3b8,f293d2c7,80792a15,89895cb5,9b33d8ad,362469af,5777f0e0,225f2941,bf0f3c33,6ab29ad0,1bb693bc,249cad79,63aab00,97beb92f,ff1d4dc1,cf1885ca), +S(b7f1fe36,faf18532,34cbaef9,a45d47fd,26a6cd9d,2cbb6424,7f0757ce,3bc0338f,f86de831,ea68826f,925a8401,5ebffdcc,dad4fbc6,9d32b264,767ab067,c7b1b6b8), +S(d254e76c,41359c6f,521a898b,d55ab42,208b583b,59761c54,e9dbab37,fef84285,d504c24d,7955bf0,2bdfc187,bc8eefc2,42b65db7,43e9439e,3f5204e2,9cec288e), +S(88bdb44c,6999ca3c,8d3e8fa7,61f343e,7a9a5f15,577e514e,809af06b,354b8971,c7cab922,69bb008f,cfb1dd08,b6576959,e0593f76,b5aa45b7,899b305f,e432cc7b), +S(94f19750,6ae279c,772b1c5d,17146012,cf8582b1,973c140b,7aeb0bf9,3cd21ef7,1e9acd37,9e7f2dd5,a6df7a9f,f4b757e3,369aff72,341ba963,fd984259,6c615de), +S(f5b2f65a,16322443,a4ed65d8,7fa21983,25f2d3b5,523cfc11,39f676d0,8953680b,7f6c8197,cd730769,2eb466af,8c63e35b,1d4eb84,fc83d22d,d5d1217d,10e06ee0), +S(58e85669,c5f76dff,9b5f601e,3d1a15d2,c022a5c1,389dc15c,81657f8f,e3eb1be7,4fd07587,429bb7ce,3903f7fc,f3356282,24e17eb3,e256fbb1,32f1fcd1,e1048f05), +S(29bfb3d9,d116ab87,407376b0,f8fc607a,ba8a9da1,803479e8,a7ca8fd8,ce96a822,de56238d,93995238,bc6c4b94,f03823d4,a7b690a5,24d01e06,374ddf4a,2e5589b6), +S(78e32283,983fa295,f6fec0cf,e34ee0fd,83541350,e50d5948,8760279b,dd54cc28,8ce8f6fc,d58a5330,595cb9de,eaa7472d,9cc02c4,c7dad678,74af6,e4a20f34), +S(f70d3534,ef29e626,84b84023,2e69e806,740b20ad,ea957ba4,41cc06ae,cdd4ce39,5cb415c4,7812684f,971026ae,21f8d1dd,377d7c27,a91f8d49,90c96adc,2d570c36), +S(4dffc775,38cad4f1,2e87a8ea,44ea868f,ec9ecb0a,a79d26aa,6db46522,7244f006,7afc7426,9d4a76db,2c243eb5,a89735d7,2d91305c,2d44acae,335fc4ec,7cd5f81c), +S(3fc601db,563c119f,9c3fcc60,1005f3d,63c92315,5bd786,9092cafc,237c6c15,4ce31449,bb975d34,5898d06e,6d2e463f,e8e84835,7bde361e,eca2c999,6982735c), +S(7a74384a,d0423c88,4ca797f5,1d62a152,4064db4,c0b5c925,47739139,5bd9219c,2b9c87e9,53965eb0,d5708dec,58a5d0c7,d698e51b,b6d2d45a,b174c9c3,4eba7f76), +S(76dbd3a0,2ca25871,609eace1,6ae2f814,8b256a09,8cd74d21,ae6b0344,16d542f1,c95914e0,5971f888,61800a05,ac946af0,99e0758d,78cfd058,9347ddd,8000bdec), +S(ed159060,2d63fe28,5b88813d,a6930f49,65dd3290,759b677d,ceb9b213,2340475e,894e82dd,1415a206,f3cbe2b7,3b7043b7,1adff71b,58b74c6b,2297ba54,2e1cccd1), +S(74fc673f,4a41d30b,d3ca4b63,b850d23b,8e1b5f2,6c37fdbf,12a83b9e,9c896ee5,8d341f30,c67403fa,e23b7502,91c35064,ffdde04e,ea52b3aa,3003b169,68f1c95e), +S(78c78ab7,5bf6ae8e,d7836957,e8258a33,b88b9cf3,53feac8,e3a8abe,59307600,95c6d9a1,3c9b637e,35c301d5,78534af5,777dde51,6396b017,6155927f,11db8880), +S(4d694817,ad756fe4,2cc21193,d4e707d8,ec458304,291db1bc,c38dc6c0,52f11194,869b495f,49bda0df,b0b12c00,e19c7cf2,14e457ce,66cc8e6,d93c5db2,7a91e1), +S(ac23df67,801e05c7,d283aa5f,ee2dc366,b02517d3,559123f8,d093de6,a9d61a10,e7e7d4a2,1bd85ae8,c88aa4a1,c5cf91b5,6fc2ec00,f54d6ff7,89e10103,7ceefad1), +S(10c1e9db,43b60e88,379b2ee6,566a53a,3341c12e,8d5d6490,ec5ae5d8,eceb1675,2fa61b2e,26557d26,f496ac8b,aab81dd7,16983978,35abd7e4,4d5b11a8,8d7f3558), +S(55ac4cab,1aa3465b,584aa94d,bdcb9eb9,3cff7159,f8a139a4,2504bb27,bb618854,cbe23bc3,8c553ad8,fc9fa619,b96b5de5,90463240,944d2906,41a14b56,cbb28844), +S(4afd69f4,caedff00,601225ac,9bdb192e,6c17fb45,62a28164,15929e64,249da79d,d08702a1,95f9abfb,47296d6,c24981c5,db62e8f2,96ebabc1,1b4b1612,c9478a55), +S(d70b4279,b68e2135,844a45b1,814f1c74,7eb8a5cd,100a6d8,8b12cc79,bc98c9aa,2728845c,c3e20846,a7088f35,9a08add2,4997be96,1327b54,a26ebb1f,95641efb), +S(ab6bf873,7d0321cb,bd2548e8,b81e8070,ad449761,af21a945,9ce2e17e,bba82bec,49bdc2a4,8bc574a6,9577cc51,91267c5a,85fdf00f,ecc5c538,688dcd86,f9d039d6), +S(2e01933c,1462cfd,b8c6f180,c7d633e,1b684ec9,a3011aff,573ac22a,aabff3da,f7c0c7a3,36e576dd,96b83111,9e3bc370,3b94ff45,d50306cb,4acdf9f7,d8126ec6), +S(9ce6a2c5,cd9dda93,2fd291fd,30e8e846,63720189,4a70fb34,9361bcab,263b4e18,f1d503d,592be1ea,98ec3218,8e61ed8b,c2c94e76,5d42c72d,4fd404a3,83412251), +S(626aa071,a774d04a,bfe7cd21,448392e4,a5a3d2da,a2e53dc0,93fd8cee,78f82bdb,a666518c,7dcbef4f,a0915a66,ce331a4d,46867af4,3966c81d,ad9d2dd2,43d30fa5), +S(a6fd685d,4ceae2b2,e1de2177,dae1ba3c,41822896,22270c76,74118916,1b51ea7a,73c90eef,ee517cf1,4f4afdf3,b0f58c8,b66ff7f8,c59a83f8,49b9153e,e29a5ac9), +S(ffc5a16e,cd27880a,bf5f1931,ba61fd51,57396ea1,1630577e,b5e12eb1,e9fd9826,90abe5e5,e312ce4b,14c6548f,bbe2095c,4e146bf7,c25d4022,c017242e,2b057afa), +S(848ee3ab,8e9bb2e0,745ca530,a6231a00,7a41d685,466bf798,9ef900ca,18407854,e1b0d35d,9f44e0d6,b1c8b148,ae5efecf,320bec28,32aaad80,5e1c7812,993afc41), +S(28d833af,476daeac,27559042,f7e352f3,4aa2f30f,b7ffaef4,26e41e28,d11971fd,d0a0338d,57c2f186,c4faaa78,eb13e931,8f8f6d7e,1472ae68,40668e17,94d31802), +S(40579821,9bc06e48,88b1056e,270b19c2,4ef1278a,d415d3,47c7865f,98bcc237,cc9ce014,f853d620,83e18c0a,2fd36b0e,9eb7d265,b711fd5c,6d3f809c,b86f34d4), +S(98470fbe,636eeb22,7b6d425a,d7077b31,9384ad8b,9327d1e7,139a33a7,cf5765e8,92d4c695,5837771e,9d69826b,1445f09f,bc610387,d23a90a9,773113d1,78d471ba), +S(a9d28158,a84ea778,63c7dd75,5bdc6b60,3d6a0d6a,7cf88e9a,b649fb32,44aac2c0,5d628cd5,38824a6e,25477bea,12962465,dbe281d0,bb7f5db2,78bfca90,e5d812e6), +S(7dea83c9,13fa2478,fb03c1f,459cf002,98adbc39,4dedcea1,c90dc05d,5a56ae02,19306ca3,7f768ad5,9e70ea0d,c811adf1,a1e593eb,42bd8d9e,de0c0673,afc1260e), +S(2ab32555,3df0405e,e5576b5e,9965e488,dfccd677,63b03dfd,ef3255c6,7000ce2b,4fbd0086,10d10040,af8a6e80,a1525d88,d8e44ca2,6a1ca8a7,d6eedd35,c5d26ef4), +S(d59e876,ada6de89,fa87dbdd,43b2db0a,e1c1ed01,cb0a5d3b,5fc5cdec,ea52d069,b7923636,a2c5d928,7722673f,f759ec4d,3dbe9484,b470e14f,e28030e2,f37c3bd0), +S(8a69a111,7bdf0752,13f53f00,1101c594,2d2932ac,789c9b7b,15a57640,c679082d,5ef32f62,103c59,8ce35443,5c26f1f1,9ab21ae4,ee8e4350,60aa910a,99fe1633), +S(1aee31cf,451a516b,24f43cd3,71a1b93a,6a04bb09,74f73855,1120c6a9,d27d4546,f6767dda,c1204f16,e31cab5f,ae5b9357,4a2d8b47,b3dc3229,95c0afcb,c4271d7c), +S(7fcc179a,9a2ab1fb,10f03d6,1e936985,91ac91f2,f49ac834,e583f991,365efa71,c69dda71,c28efe20,3ebdb28d,70d0718a,9da3aa5,255c7c60,6f355961,3841ea7b), +S(bf75127f,46e4e90b,3bb81277,13641056,c75f78eb,3717425d,54df396d,9c021a21,640e202d,c28d9d72,c6d1575e,9d672c57,d64610e9,93983585,10eaba8,61fa86b0), +S(4c1248b6,27e5cbd3,5f93deea,44070e7e,bd5b78d,97f27961,53cb63c0,c18feea6,15e12929,f7b6b8df,bce226f4,6f2c73e,7d473833,18fe05a1,1f8ff01f,5d42dbf3), +S(584bab22,79395635,883c483e,abf11ac9,6e97bdd6,b9a0fffa,f30b9062,37520da6,2e7e69df,570afb7c,a3e594fa,7b23d00a,2f8a7e64,c02cebd7,3fe718ea,458891bc), +S(68ae6eb8,fbb41532,aa8e8801,e7c1334f,571ef1f3,92ad014f,9637bb46,b18ada9,aab3337d,550f07a7,20285869,72781c30,4bcc2d81,ecff0fc9,c27fd09,5c41b1df), +S(21d7d1df,17e3c1f8,65ee8c63,f16b0e60,c074501,334a601e,eaa803bc,2b1db846,b6c847d9,a4992f60,c9dd1898,708be183,41f4999,a5803b4e,7c2a5677,d3def3af), +S(63b70ee3,eac6f6db,36b273f2,2f919be2,6146d19b,bfa217e0,a3389ca1,f131b6fe,38accbc1,28b57d42,ab2ae5ab,21997cb3,5bfb42d0,71059542,6867fe83,14df95d), +S(6981f1e5,ce35b49e,b511612b,22ba76db,5884e2e8,819832d0,1859e993,84d6e8d5,7261f896,810a30d8,53cc24ae,40f3f36f,78826bd2,49141d57,6b9bd900,678e0b79), +S(e30c73e,fcbfb24c,882df876,b878b5db,31f0a78f,2e476d3f,850f6b2c,e1d3d548,5821f7f9,7a2e568c,f0f03bbd,c5e43e2c,ffb1a55a,4d6d4855,49f7b6eb,f9a6817a), +S(e95e8d30,316e97ca,70e8d602,89c5a43d,1c698beb,f40e1ce6,87d0d017,7e922f4a,cb161116,c64f6a66,7fa6500,294fdfe1,f5f27cf8,de2213c8,97c55144,2a70137), +S(f0062921,2603da15,6e315036,ebd10c56,477eb7e7,5239f2d8,a4fec336,9e956c38,4086b08e,a3d16b48,a0cf712f,54a7547d,e732233,69030526,c10ba827,eb85793d), +S(ee8526b6,a932b82a,c4645a4c,c5200e91,ac1a8ca9,eccecd29,1c83cb02,bf69ec6f,d5f40396,4f593b1f,d6b130db,65a45c32,241be6c7,d0faa091,bf8f0d5c,41bc41a2), +S(6209df6f,a66fb907,70c68cf8,81b0494e,7c31ef69,38fab171,cef2156a,740ce435,ed1a499d,5d7712ac,dcc39dd5,512aa71,4af5fb36,f53c789c,7eb53d10,7ab415bb), +S(f1f7899f,7a0cf14f,4ed384e8,e55bd6d,8ef0cfe9,895bea58,ab80715f,7bfb6fb1,679f0e59,705f87f6,b23a008d,69c9e145,c44637e7,69326445,68c9dfd2,631a0e32), +S(ecaabf0f,890fb84,a23e6b2b,11822f6c,62ddefda,7def3d2a,816ea029,2d24d93e,b5450b41,29c8ebcd,f3aa0def,bf091346,6ceab1d,874000cc,527e071b,6e3c420b), +S(42220ae9,3b056efb,66349955,402c6b93,31706ce,c5ac1916,494e523f,10959fa,8272973b,a0c30376,a3ad6d38,f007e1de,c9f74fad,f6621d6c,cccd7f55,f9293477), +S(a5b1cb9d,ffbe6c9e,152304e3,c195ab6,1904fa5b,661b097f,6838e33,fcefb7e4,f933eb70,32b9723f,250b861f,1c2881d4,fa118f20,2f16d0e9,bf41844c,4bb6936e), +S(dc460969,258cbf33,c327b9d3,3927b18b,eeb2f2b6,db477491,fe1b0f8,bfb274ed,383db155,3ec0da85,62038810,653c06f1,f573065,4ec029b6,1eac7f75,85bc7ddb), +S(546afcc3,d5e1002e,f7531c4d,40284782,7690f7aa,a9b7aa65,80070700,9642647d,ea4c5ed6,31cb86c3,c7710671,dc26249,13fed4ef,e2bb56dd,fa4f21f3,478ec442), +S(707533d0,61c5c4ed,387e30d6,69ddc3c1,de0162d5,48c11cd2,8daeeebb,6fd8eeb2,a8f2c219,eeea9182,16a5722d,b9fc3f44,a8cae2c8,8e9632b6,dc9350fa,6d6f08ab), +S(4480b923,babe395f,9b21ded4,d7f3ddc2,b9044ed1,379ff4a1,f417bcb4,ea1a1bcc,14ca822b,e0cffe91,42fb177f,712b5c65,6e650c55,24bbaecf,26450356,c7dfd4e7), +S(484a7a43,c88ccc85,9bd81923,a0faf130,f44e45dc,cc43545a,9f7f18c,184efda9,8b79382,3ab0435d,6422fdcc,8a3272b0,1b326ae3,4ef2992,65693070,45fc2388), +S(df247ee8,1936fb3e,9a4da6f,ad000c85,f7c83171,45097f9,ab4b94f,a2c8e1f9,4955c099,d857520c,633c0b75,731c6286,7b5d43fb,506dfea7,9800ccda,9a4962ab), +S(95a936d7,c83a5b13,e0bf865c,22155aa6,71d8f86a,3c518cfb,58e73ccd,f23a141a,be6ed058,5bee36b8,9f2d8921,58bca498,f87675c1,9342df09,f23d62b,64a6533c), +S(89e0cab0,118c0f6a,58b22a3d,fb66fc48,b19c059b,6b5e2958,6c7f7487,61c65b2,cb77eec3,d806dee7,b11c5552,16dcb2a1,2c00233d,2461887b,6897618d,e8c4b0a8), +S(64ac2ffd,67fe55e9,5d82b26a,a88aafbe,5ecd6b25,12226ef0,e6503aa6,a3fb4ecd,41bdf623,644d265e,be30bc86,13a6f084,a44f1dfd,a6f1ee8e,16d84e4a,fc51d66a), +S(60e0f0fd,99be1c5a,43866b76,a7ea8890,a7077135,43bf4299,e25ff15e,e35d87a6,4ef82895,b158d4ea,d8ed02cb,82e8ecf1,df795d20,b3692951,a431ec81,78479c22), +S(49f0734c,8b89d8fd,2b349b48,2d5b32f3,b7d5e68d,532f76d9,753503ff,de2a3caa,4e1c2858,9b22009a,2b4d143d,94fe44a9,5697540a,48a2fad9,100110c3,ca0b9548), +S(ea29d84f,41a54da5,f0d9f7cb,ad239ff8,91395e85,5cf2c86e,e00257ee,325993f6,a0bd6636,dad5c1d7,8d65e18f,c36b00d0,96d9379f,1e650fb9,cd072b0,224d0f4d), +S(92edd00,f9dd358c,6622bb73,ba4f4760,de3e5727,2cde54bf,a8a6d0c7,bc205f56,eacc8aa9,b85829fe,391ae7b2,a747c122,625b408a,c97f1d46,cd0c8891,eb0d4eda), +S(29811533,8b09ec4,583d1702,5a0b0bf6,b8a322f1,76fc46f2,49430c74,84b7b6ac,f7332c0,3b3c5c4e,bf5bfd9c,1e87d668,8347b315,7f0acc43,591310fc,5792ca4d), +S(b5a4aaf6,8a97958,86540199,cad47d9f,86cc478c,ec43a24a,84722a13,4dd6d20,bafca1a,5c9d99f6,3c986ac5,9e432a49,7c8e5683,331ca708,4326978e,1db66f8a), +S(4e249e10,981f8ee8,b3f0e5e6,c2e67de9,ffc811ee,6d9776b,4cabdaa0,98a8b430,955965e1,7ea5d179,4b293db0,b750a649,429833a2,7c317a24,654806cb,5ab7d709), +S(1d10268d,abf2f72c,2769dad1,dda70fe,879c650c,8ed3b285,8583cddc,cc02ffd7,7d31408e,499940ca,8e88fb4f,1aeadace,fbd288cc,c35699ab,8484be00,1acec27f), +S(3540f96e,fe965c34,dc608016,61bbba18,386b20e2,ccf75f8,a0fd6e62,65b8e62,b0d0399e,35c5c376,7773a848,34cdeb8a,cc7ff651,ab6e2575,1ce81e9f,628bedf2), +S(b1e45c76,35de0135,21274840,8f06efac,4550291,d3151239,f8272640,b7354cfb,aeff7dc0,665692d1,6fe0d607,c996ea0,8134b150,317df1c4,afe97cf9,3630c3ce), +S(9fddcd30,734ef7be,aab9c040,f1ad782f,5a67427d,e457f107,b2935caa,d52ea1fb,5c89b6b,36e26147,38599d97,2f4ceafc,d3dedc7f,79e482d4,478e4cec,b7c4016f), +S(17a4abe3,99579c3d,8504a0fb,427e521d,f6034e48,115dc864,b8ba4385,63d692e6,df5128f7,aea1f8c7,214db822,4738dd89,24e08023,36fcfa9f,d4a49a8e,c09056ca), +S(a7d67392,27d93a67,e7eac9b4,2f1583e5,633c7877,56ba7b01,a983d8b4,d4cd181d,1f10081,e72a50fe,b95b829a,d5c36349,be13e45c,f9722108,8ad78dd0,c7b5d9a9), +S(87b2dfbc,e4301a3e,311d8c9d,23c8bcf4,950f8fb3,8481689f,905d6bc9,be1db1ca,4dc9f93c,c4c25853,93f10a45,31c6cb0c,9607170,49192ea0,9ad09810,3c078463), +S(d2fb6a94,adc47e9a,e68ee0ef,24a1ec07,742f3307,36916c3b,8409de8a,2b546ab,eb44e5d3,970cb849,a797bdbb,438bfd0e,6e6dcd64,83bb11f9,10be2dde,978b7e1), +S(7dd84bf8,c7070b5b,d258da10,e62146b1,b5408b62,d7154cd0,45ca4cd8,81623bc7,cf07575c,a02b6ea3,ef2d4cf2,9ad42689,4b30f1f3,689f6a82,31c63515,6633fa1e), +S(b13fb14f,8fb7bd9d,c2a26c80,aac1ad3a,3d10116f,6ec1a7a6,888bfeba,acefda26,b5314ee,2048c766,af47c814,592c3d42,b143ef88,3470eabb,9629c4c3,5fd70d27), +S(b58f21e4,4061132d,75843ebf,74126a4e,25def37e,1f30759c,1c1d461f,95c29dad,737399d8,b9490cdc,7c0a18ce,3d33d340,c2cf7fbd,78a1564e,1115306b,247feb38), +S(10d3dc81,14156a53,f58cbedf,207026ed,6c74f52c,e62cc0dd,68189a6a,bd577fdc,fc4b7c5b,1f1288aa,698032bb,7b8ba84a,10819479,c616c00b,145f9996,8a4588e9), +S(3890baec,2d7505eb,ab767f3c,8b6ada03,3505a329,791920e5,acd55a6a,ccff5fd,a5ced26c,24fb642c,64d292e,2696aa5f,fbb234b0,3d695e83,50f5b101,6074ef8e), +S(3344cd50,af1eae91,f94eb7b1,168737d,fc8d936a,1fbaa3cf,14e9bac9,9c85dd49,b844c82d,1ef06c70,e7795dba,ae1f1e32,f8ecbe2,6c7d295c,b96433b8,161a0fb5), +S(968d92d4,5b6c2adf,376324ca,2feee09,9715b56b,6038a3c3,c51182b9,a2ecfba2,3e014876,6e32cb,5a1ba838,a5d3c64,f954c3ca,a6d481b4,3c660974,92e39d4c), +S(3f7a1811,751e8bfa,2740371f,27e823aa,c2a23c07,d1f5892b,ac2132b4,c8be745,5d475208,6cad8b6,58cee187,f692309c,4c01f335,c4a561e6,6099ff83,18cbad88), +S(2e5d840d,5e808361,799353bd,a2edef2c,4e686735,f8161382,7f98d94a,a4a4a522,859d0019,a0d7619d,89025f7a,6273d98,25acd521,ecbecb75,195bbac1,6d1124fb), +S(5536c7c2,e29de995,e3ad73d1,6d525d3c,5646a96b,fa931bab,5b96dd,ece62eb7,710b162,6d690586,15e54f97,828f7dc5,527b20a,3273e318,5fe9c64f,86ccc206), +S(d29f9ce6,d0758df,c4025af,7097b53c,163493ba,5e16d5d1,d66414e9,a75fa6a0,af5fd2ab,36975272,bd4eb8f4,83e37b01,9772cabd,fe863c46,53a38906,450cd77), +S(8fda2d0c,79aaee8,fbbf2e24,c9e2a98,e37651f,117df59a,b9c37d62,a4538ca0,dc0fd47,aea5d11f,c64a0aaa,d0a2953a,2762878d,6608d513,8b911d40,e679f238), +S(2e17903f,6b00a556,a3492c2f,cf52ed69,58a53715,950c3cb3,f99ddda7,fec950ae,73c72ce7,6644e080,a0fa570f,32d4bf41,ceb500bc,c328aee2,a9c2b22d,56419e5e), +S(c5ec2ed,9ea6c3fe,5d6021f7,bd475c33,3899edbb,7562d91f,4d0028ff,7a07709,7015d790,a6c3f25e,b9cb4bed,f3bcca04,740daf14,da1d3008,463a8f28,6bcad698), +S(b8deae8b,299a5a56,24dc2931,c9d4b63a,361ba102,c5e4e2d1,fdc17262,e10ea72b,40e8ac66,b37a8bda,5d30e794,977b3d40,d2af7b0c,276ad346,a0c10273,359fe18d), +S(66e4daa2,5442fd81,500071ec,51a2843f,ff19b706,8a8a387c,744f295,6282ca65,16a75c2d,bd9d5317,e2b2094a,a85c95ff,87bf3c9e,39101a0c,1bc743a3,70b09380), +S(237df4c7,cc475cfe,7936c17b,dcbddde8,61f37e34,93e4f3da,40d9466d,eb2c675d,170fa5e6,156a8c60,ced37da4,c929fe15,e6d8c691,ff99850d,bdfa8844,38968873), +S(3290620f,ee694bac,64b4af07,25beb94b,9bbbd0ba,bd9c7340,9129d1e6,d5d8da43,31455278,5f416fd9,5bae000b,9b5eebab,65575fa6,9a3b6ddc,cc2c5163,455438dc), +S(a8eadd35,4d5ecbc0,cde50b55,c7e21304,7a548291,7d979b32,94fc138c,d9dc4cff,94dc973c,962b25e3,9aa324c5,8f1c9349,9190eae3,8c869896,a0e62dfb,222255f0), +S(14cfbcad,83d44db9,4194e0f1,bc7d8650,c3586ea8,a362e1cf,f044d3e3,8a5a3ead,348713af,acdf1749,bf27a162,9baf1992,2aa62412,ca2e84ae,85046366,95acbec), +S(99df52dc,8f8daeab,5bf8a48f,fb8c4368,7f4ea8e2,b7feb3bb,fdd6e1ee,59bcda5f,3c6a421b,d7631546,d3fea7fb,6370e823,999c6a58,c8d4f60a,6362e590,c6114825), +S(4c420d8d,7d734ff8,220d9335,ede52153,4673dcb2,c4af920a,aaa691d4,777e0e61,4ec2028b,811fee0e,8937dc37,9961ef93,d7a04147,72a2a45,1e3f64f6,ec5c37d1), +S(485b4e1b,e755e864,ba0b7505,20ef3fcf,a58e2fe5,5b6f736a,6122ad9c,160a6ad6,56adef3a,b8d325c5,c4b30910,cc7a85a0,5a326195,a39a3681,2838d5c7,e3dce17d), +S(8d698df,4acae452,26ee02c6,18c04d33,4e11ec3,f0ec73b0,6365b46d,2e61e478,bebc1c0d,285eb1c6,bd132d29,5786198b,57650a92,f6eb951,a99bfafe,b06454ad), +S(d0d4db9c,4f9b50c0,dd8612c5,43b9d535,8027c081,cf27986e,cc4326db,16526a12,43bdadb1,b7e56e62,2f10f5d8,169a3198,30523f7,908a679f,1c78bf26,6c699c53), +S(b4aaa39d,50e18cfa,743e307d,8ad30f88,3f8a86d6,9f040d03,de008e10,b66b8060,ebce9bf6,8be9bc73,29e1ce4f,ae1a904b,2e1613a2,a45c8095,ed8e346a,6a1bb53e), +S(28e6c590,5af1bcb,f3a81492,37011af4,2e46ac15,fbe0f2f7,a19ba76f,e7104f98,82ba4bc5,4b20238,12256511,b1335079,b21e97d9,7698ffeb,723605e9,c200fe67), +S(b002b5d4,2a2089b9,fac121e8,eea8e240,2ac5b8dd,77f8fb6f,68b59c2e,f2b45182,7eb16bec,99d2249e,22f89e48,11c51324,99f2b7f,e6df592f,7ebf0fae,36130449), +S(36e9cd9,8d1335ab,90d58af9,83f7736b,e317c3c5,c1f0d702,d43c32cc,916719be,df8a57d0,19c19da2,8fa517fa,749f6cd9,21e19b53,dd97e255,1eae0b93,fa6dcdd9), +S(f89c103a,bccc8040,3684beb0,ea56ba57,b447442f,bf3fe918,b25be9de,9bbb225c,7fb1eec7,855ff2dc,9029e712,ce0b619,a6809a7c,3068acd0,1d275dc4,41a55847), +S(5f164591,cc718471,7f23615c,ac67d055,268bcde1,bad2e211,7e235699,4074767e,99aa6bc3,3979f79c,9765a053,66c82dbe,6c067ae,539065a2,4ae37579,4c5a0eda)}, +{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), +S(e3b58edf,cbd6615a,dde1978a,30160514,80e9a335,1ba66cd2,a4e939d4,f4cce6dc,8d493750,a60f61fa,ed9f680d,fa8ac946,d765ab2,1925675,d535e60,b124b12e), +S(d7dc081e,9409bf1,ae46ffa3,5f9eae76,8a92faf3,4a670d76,487b4334,50c2959a,77737006,f0021115,9c81a55,b58da8f5,5f056493,6d319eb3,9fa1a9f2,9ffe1696), +S(ad4d72d6,768dabac,d7c40d1e,b88d5978,46e2f335,8721b980,f1f4b16c,bdcbd829,151a1ed3,ed7f999c,ab836e2c,665212b6,fa08a716,35ee1061,d650735a,3020f89d), +S(325cc8a0,c03e6d53,acebdc12,265ce043,13d69ef,ae00b17d,84df58e0,a3005759,2effa974,b24c0972,84f2cb82,b48c7460,3268ef06,a117aa4f,66d080bb,20ac77ff), +S(38e08a95,fa799d10,23d33d41,e5f305a7,eed9cf69,5151099e,cab0dd40,861b094,3e2c225c,e2c7d8f4,cd27e9bc,50015cb,3714e4e3,2feea2dc,3d275a24,997b7c08), +S(d477d862,f7572311,73fc315a,35342791,319b0185,4acc9ded,6bc71fbe,ac866aa2,c869f5b1,cb084021,d2379b27,d4e5dd7,5e88ecab,765a1808,4664ee8b,74b23bc8), +S(56a5b347,f304a6e1,13dd27ac,3ad1260e,8e65265c,31a95f8e,6d58a893,d2afed47,43c3a208,c6965fb3,397ad3a5,3d335b11,647af4cc,9ca1f4b3,1dd7cc3d,f11b4b22), +S(7755d5e8,bb6c946e,d5a9bd6c,1d3f1675,b0bfa137,3f69f92b,8f0f64a9,baa72e69,1126edd,f0f0d7d7,18128faf,3a988899,a7e2caaa,901e92b2,312f2658,f24bd0a8), +S(f010342e,3b068db4,79325185,ee3198d4,1cfd61ae,e1f2fc3b,e9552b30,ad5a1767,132b3929,a59718e9,addcd814,99ea1f69,941bb18e,f26b3ac1,50b9324a,eaa58001), +S(1f994727,6e3ef21c,2eee65a4,38fb451e,bc87028d,31ff0769,f9935095,efd3e347,425ebd7d,4d6a6a1a,1b32ecab,7be89b36,1f333206,e1526523,991542d7,b23cdf81), +S(eb0a70b7,ca8a1289,e57b3a86,9f21adeb,1ad77d21,9ab64d0,10716f91,3c5fd2b9,dc03531,46af152d,b78813a,bc402c76,93baece4,e57cf68c,ea05b6b1,ca6be07e), +S(b46e930e,36eba93,11248490,4fe0504,91cac0e8,5caa4d76,f35384d8,24f8637c,8f2e844a,29cb90b5,580b74b5,b16f07bd,87385834,23b61485,e3336286,1817c92d), +S(bdf5b431,db844804,70eb3188,6380085d,76c89d00,7bad9990,f28a4e04,e1bad223,9b71ff3b,8f13cd83,b493c150,67d91f38,6341cba7,5f711276,bf768f3e,229c1e55), +S(a4aec29f,3aba4188,e6c73e04,14e8c538,e482491b,6d1d01e6,9801c580,fdefe920,135980f3,b38cddff,e9f7c0d4,87f1b44c,c83c393e,9fe3f8c5,ef6d7840,85a11013), +S(4664f7d4,58ed1845,33ff308f,6389282e,ee336d05,28dee862,2ad54d31,9d1bd536,d774ea2c,9346db82,edef5940,264d2f47,da810925,ec1492dc,5f3c5887,e0015f58), +S(1732bd76,99c1b718,654ca447,5a9851f0,f46bc444,541239fc,54b9b053,e6cd8d61,db1d259d,15dc772b,608957e3,cf32f7e9,b076ec05,3be1305e,c2b8c9d9,7aedf5fd), +S(8e33f8a1,22c90484,7303d6ab,d80fb29,ff84bb43,eec9ded3,fb643482,82f9d4e8,5d1b2f19,30758a1f,d35d3993,598db1e1,d8514855,c23ab82f,245abb78,77f0eaaa), +S(4d96af74,6c067b61,3dc07f73,7eded3f5,da106daa,8910d37d,f9d8beac,962ea02d,74939d7e,c345a59e,567f8046,bb400efb,54107096,8fa45412,c327e10b,3db50b1), +S(478f6fda,3e82c5f1,d65caf64,f80a8341,54428fa0,90dd3833,c2a58cfa,dce5d32,1cb8ecf6,2f7cd442,8b9b3f6c,b33a42b2,bd7c8a94,26e35886,4e1a73d4,65294226), +S(9f7b432f,c89b4f8c,98966a60,34ac0218,d02cd505,f888dba0,55688463,687164b,9d18be19,871f002a,b4518835,9730000f,15446136,f8803657,51987e10,571e681a), +S(c3d1eeba,d935773a,7f30d379,4e5405bd,6bbb9990,26d3d745,78294c0d,c32a5e2e,8857248c,674c01f,4124bb99,3d5b261,def62594,7facb651,f6bb5385,2f5e5674), +S(40a419f9,180b3e76,dddd489d,eadefab3,b3a53abf,8898e5c1,63221606,d7384ed2,53f5382b,a73b7d00,a5afb12c,9345afbe,9c5e5134,cbfe1d9e,81bf3b59,4dfd6b95), +S(ef7cf180,fac500e4,32a70987,989efd6d,d527ddef,779cd09c,589b7e19,747b5572,7b540c7,c2a008f1,8d5ac610,96743cc1,56e87270,5aa2dba8,ac891ea8,bd6b755d), +S(402422a6,8b33b370,aa5f4d57,3a92aad9,acc9be9,2e304de2,73aba72a,d2a8c4b8,351e81b4,4a250b81,5abd8a73,f23ba0fd,a624970a,59076ed2,99667c52,6f63e7cc), +S(1b101d88,9f802cba,396dffef,4eed336d,24138432,12d21fd1,dfd56765,befab1de,b51691ae,f6589bf9,f1d47e2a,c29b6e95,ba600e4,17e48801,aa8c1c36,fac8dcfa), +S(1e82a9b2,4458de28,97110749,dc63f744,94dbc6e2,1085afbd,15c9317c,e3b0bdb,72ff3c57,cf1c18f,64127651,2959762a,83a77db7,2f7b261a,67b1f64a,bad69db), +S(3e5f2f47,a3b6e9f1,69d67e79,39ddb4a6,3ff4d6b,e85e7855,9eebb19c,ba5dcd88,208bd01e,5ace2579,5ddbf6,b57ea49f,aac3aea0,ab3160c3,62e1436c,c545c7bb), +S(e0aba818,cf81f784,ad2656b8,1576ab4b,91a4d0ef,1145b359,393b2bf7,5e798cb3,52f41c6f,3f49e3d7,8031c7cc,c2d4197f,51d53167,7a2b3034,20f2750d,f85dfef6), +S(115d9e1,1d6ae4e3,7a28e641,4704361c,f6422288,a3044b19,7dcfb54f,e76293dd,81c06f64,28931504,21f74c52,64adc217,9c9839d0,9e2ad42,8680b289,64d7f8b4), +S(b742c7f5,60adf44d,a8ad0f43,30c110df,488fc072,c6029911,bb60196,6098f26b,f683d248,d6ad0724,2d1187ea,109f89e4,b231331d,5867a009,26496d34,e7fc2b7d), +S(d8d686f9,2d5b3e5a,90a6b33b,f6e22fc4,e4dff29c,c8e2abcb,cc03d1d2,89d8ac,817b0c58,8e768884,6570da24,12d4dbae,c1649e4,e87b15f8,fb6ca41a,dc90ef8b), +S(a2792c2d,f53b4f8,c4d8da47,1117e7c2,19891016,14e6f8f3,cd40e74a,1f079bd4,bcd3c49e,fced8a89,c5a22469,8360d91,e55c7752,b3c0b798,ffeea98b,373bbec4), +S(2aa4ede7,9b0e39e2,2108d839,a1a3a280,e69cd9da,3ecfc71a,b3ff89ee,f921feb5,8568355d,eb149d39,8d4ba4f3,bd1a36d4,d7e0320f,8b3d8c6a,c81479d6,702c5841), +S(ab965917,6927e9dc,20ef1e6c,60349cda,947dbe9b,79dd2402,f5fead7c,509c56eb,2cc227d2,68174216,abc20792,12eda585,2a91aa1b,e5e141d2,a510a165,405fd059), +S(4103c008,71a071b7,f628d6cb,123c0c9b,2c91fc19,e52e747c,a35846cc,71a9baa3,8aa4e7d9,ee8493a4,ad092826,1377f4e1,397597b4,f63dee00,cf379bc6,92ba589c), +S(972734a8,6a5fc831,6745ab81,5487dabc,51dc150d,4747ee8c,b96de185,4552d1e8,64341946,6c2ae001,49ea0ee4,9dc92692,9ff80e7a,649bd30b,89030606,319a6fa2), +S(9405e5ea,569e492c,883a5035,ba768b83,79fbd706,bb4171af,b0a7480,7069c796,ebab6dbc,4dc6195c,f0fc9b24,82cf324e,3b00fbf7,c4773677,2f55c2cb,60109c6c), +S(c9152518,b43e2f9e,7565f8f0,322eade9,83c5bddf,dc85a120,8b18c6d4,b53e2cff,33a5001d,26ba5f94,19602e75,a0cd39c,c6cc7648,ab9338c6,a796f68b,250f8bf7), +S(1069e550,becc5618,5bf3b627,9e70db17,5c2b98ec,8796dbc4,ebb393c3,95fc23c,cfcd8ae6,b94cfe4a,b3856627,4896faea,ac4db81f,3137c2f4,d14bcffe,26255ffa), +S(e1d567cc,7a7e3b86,ddfe4143,ddd5ebda,41e731fa,68e84445,3494507d,642aef46,7c6355da,fcf15ddf,8b143c1d,542ac5f3,da67225c,d1eeefba,ed24eb41,698af892), +S(b12d2da5,72556701,4915f7a0,f19d0483,452626f6,d03c4829,9bd2fa9a,633d2ca3,5b3af65c,1ee45b4,51a1be81,db8654e9,62b81470,2f162b9,5b02bd2d,313da49b), +S(b8bf7426,e023d1f8,bbdcf2c8,cf0d1ca,3bc14c46,c25ad34e,30e37538,222aebb2,20311608,cca061d4,7daf2293,ef087cb7,bafdbf51,b6fe17f0,f2c676b5,596120b0), +S(30e2ab2b,4d4416f1,56eae97b,15df3e89,8313bedc,39e224e,2875def3,45ebf7e1,a9a5c2f5,bab83663,463a5ac2,38d34f2d,942f0864,9f013068,d5fb43e4,3aa9cac0), +S(b51a0245,335f2b69,ba346bca,6e262ae,e3bb9483,2c4a76e2,cf1b0a43,24398a06,381aebe5,9c57447e,e48a5615,2b8c1ae2,36e1216a,eab9fcf9,f4608c3b,d5c1bed5), +S(16ff6ff9,ea6268bf,fa04d0d7,697f08c4,1717ce6e,6956c14c,bb1e7088,32ded621,a30c4501,a9791b68,15d4fd1b,9b6c943d,8af81feb,b995457b,34640389,eb312a), +S(75a9b34b,80f56b8f,843fe73f,f0a522b6,b32941cb,a892948,be3a649,ab644ada,55c90f2d,e8ddccf5,a896fedf,bd1676ff,11e537ec,fec1e99c,3d880705,93794d9b), +S(e3d207b,fce3af45,7c93e30e,fa54e879,dc00b005,481775c9,1d2195d8,3c0be4b2,ea97b4fe,989166bc,eb7485d8,50829a7a,ce306586,a34f812c,5f30353,9f46702d), +S(4c133100,4af7bfb,d9b25296,64c16012,aa5d2000,167c5ec0,4560c44d,5f424139,4a68e2be,d1509b05,9839d1bb,1e96e953,cb655fa1,1da92569,8edbd940,5758296d), +S(cf6da6f4,eadc1ed2,c4e5c161,541cd6d7,6c3187e,2ca791b8,2fb20f9c,4f8bcb0b,c9fab960,ef26fed,75259616,ae18156b,3e5c7ab8,73a08a65,cd199de7,f743a492), +S(70348438,bfb71d5c,c0ad51d6,d6dd5b01,1694c9a6,d759ac00,72c1f3f7,8e6064a7,1c825ebe,cdf3f546,c731df,c03a7bfa,8101f864,b8428461,36beb2fa,a1d5a916), +S(505ffdd9,f57bb5fc,1e32c035,6bb7f655,793f3aa8,1d34ae77,68a0fcab,73aff902,7ae3363e,36fdebc4,f5d91f39,cb92dc58,a772741,c0191eb8,ab95575b,ac32bb79), +S(a3f102b7,1312ca94,748f0364,1f3e15b3,bb41d1c8,8bb9ea8d,b51b4c9b,4fdc659a,1b1506f7,ed9bb787,7e65f94f,97b400c9,bdaeb208,5944d4aa,c70906b6,6b8e85f1), +S(21f0e0cc,35288167,6cf5df32,fb7f1d9e,962366d0,ed994a35,5e95d68a,1ae73664,13b8d4ee,c089cfe8,ce0fee41,67f25dd5,bc165cbe,c178e80b,d4d7b57b,b0f26f85), +S(6cdead78,97b40a6f,ab7c0e79,66f930f,ef8a2ea0,f8b8e20d,6c832aa0,6476da10,aee696ac,24106a15,2350a75c,aa45a230,c55e3eba,413e2251,719ed8e4,9bbedce9), +S(ac3d60b1,c5f1d942,17c4165d,45efe2eb,889917c4,8a9e650c,e2528893,ea23d48f,791c1b86,6e072f43,78221fc5,b62c5c97,4a601a97,57f130c,787a3401,8bea3f6d), +S(74b31ac4,5ed0eb87,36380b35,e711c93a,1ada56d3,f4d878b5,ca04033a,2673e0a0,818c0254,b96ed496,29724ffd,cf71501c,f37d57eb,93df690a,4c7fce70,a100fea), +S(b4ede440,f1561150,4e25aaf5,e415030b,3542680f,45697539,6c91c85d,aeaf2be5,92ac0c65,d90063ad,793e78a5,6e94211,392b5a72,f417fc5f,d1763228,4ec2cd5f), +S(b629a62,2434ce88,6f7e340d,d3fdb0f6,b36f06d7,cf4657ac,aa189793,5e46c413,f927a57b,8eb72443,bf2a04c7,65ba56f6,4c9aaaab,f28fce4f,aa1fc964,2b8452bd), +S(2536ca07,e67d4bd1,2a3e0c56,77e0b83b,35f03ef4,392efbb5,9a08106f,5e7468a8,4eec6714,c83fc9a5,5bede8b4,206affe6,68d84316,b88f65c3,a7b1b002,9cb23d94), +S(30a68c11,93764521,b72d251b,dafd608c,eaec6052,89ca2a40,b3bca114,117667f2,4a79cf91,e5938ae2,31516a5,a6198cf1,531c9824,1eff5f2f,519a9038,76c21b6), +S(aaf6b23f,bc200102,ed92dd61,a8a853a0,7298b004,7699d43b,ee706ba2,15daf366,e9a15558,d984695f,fdfdce2f,5add6499,644c1d91,79e910b3,2d8f5cd9,6df9a78a), +S(aba17c14,424f27b7,324bd29f,b3a232c4,670b56bd,71013ea0,14942d40,c55cfdd9,5c0265a1,963f3679,f4bb7e7a,60919df0,860adc26,b0fc502d,830c81b3,d8000999), +S(7dd28211,82eff020,ff58a4f3,393c6fd,516b52a,9f78b823,9ba92f08,6fe30fef,6893b183,1c0402ef,c162c99,87efe669,58e9256a,54cc4048,aefb5ff0,989ed93c), +S(822f080b,76a98334,55635b09,2fee11c0,4abd6018,73b83f82,fa761d68,5fefbaf1,fba007cc,b611b2e7,37ce918a,ff26efcf,92a17d1c,4e90849f,ce058397,4128de69), +S(e47aa72,50e27d84,ab7e2e8c,a566424e,646640f6,c1b458df,3eaacf89,2982253d,e2a109ea,5e1854ea,951edeb0,bb8dec1a,8adb05ef,515b0bcc,40774196,222a0e09), +S(6fb6cc,902df4a,34a517ac,5feb8d78,33607701,1d5522c9,9654dfa5,ab5f4872,6efd6a0b,f55f98d,9a1872ec,8a4102c0,e7272e62,9eb6e10d,de6f5b80,aa4bc44b), +S(2cf349e,34205e69,79ba5a1,83032a05,76b5fb8a,961636cc,4d1e0cc2,82158ce9,b75d36f5,94df0de8,6cfcbcb4,b4ac7b97,fd4b711,b48f132f,961b0642,a123cf1), +S(9cb540d2,f8cc21ca,d4fb1b,7e2529,389f6a2b,ac1a71ca,d73f5152,483017f5,65bb5abd,91d3c759,924314d6,f9925b47,87413c2f,1023a6b7,8a7bb65e,d43a48e5), +S(b008d6d,24acd10e,aa0f129,58045da6,4a858f30,44b47e6a,1caa37c3,3ad7efeb,808a3f6,12773a98,59342b25,e479b2d5,d28a8c1c,b2597f7f,72fa0e9f,8eab294a), +S(24bef8fb,9a3465bc,63868e5a,74293e70,3eac939f,99bc1fe0,8263e324,96a171da,efe5e06,9018bce2,bb92fcf4,29efe63d,1d624acf,d732fd47,f6b82c81,db028f36), +S(338b7660,385e3d4,65d5cf89,12473b94,3d1cc1d6,98a07910,8a3745f5,de300277,6c419d49,f3df4dd4,b87178e4,3bc2e9d4,9a76c1a,262d9d0c,bda141da,78fcad0d), +S(a53c790d,d8756046,8446a40a,cfe6f890,21f64328,8d4bf979,99a5fa9f,51f4bc22,444ecb6d,fe9cf442,d34b643b,94bb73d8,7fd9d5b6,87907c62,68425c57,e43e1158), +S(185852e,f02e1aee,10d6054c,796ec263,a33076db,26a997f7,2ef01fc0,ea6ece3f,1b8ccf90,fc573d34,b0733ffe,f10c1346,2190860a,f3e79c16,863a3fcc,add7394f), +S(5894b2d5,476f40ad,765bc171,2bc9426a,df05dd54,31b0d89e,b164258f,d5ec603a,27bcb2fe,ef2d1ae1,e2024ee4,b62e6d77,9d4930c2,3badf2e3,84241d74,cab8beb4), +S(56f1ebc0,345c7d51,c0e58f2c,5e4414c3,a264da18,73e1e898,e3e7d526,777b77ba,1066de15,7ef9ad2b,a07dff34,7d430525,528812c0,2593c14d,a0d0a7ad,73cd1d93), +S(5a271684,5903bd72,89629f8e,c8b99ded,6e20cbb2,9d20001f,9aaef99b,c6e21ac4,1b32158,4e2273d1,4f9f2fd3,9f5b5813,526577b5,af221538,91feefff,ff1a86eb), +S(7cae9233,8cc38ef9,a84e10e8,2281463e,303f8b0,44eeb9b7,fff51d2f,5ad8c8ba,69855baa,a2516e72,7a516081,821f2f68,988a50aa,eb9aac08,e2cd5e74,f2aed0e0), +S(31659ab6,1bd1376e,e989ced2,7d22ef10,d6e48cee,5ed1563c,646f00ae,5f7049ec,2634891c,bf30a25b,fc710d57,9b0e2795,dc2175d,5c7552dc,c0bc350c,cb240797), +S(e007de0f,96522c6,52f49b68,ac817746,27981ecb,72f70b80,25a4ba,efbb871e,6cb6eff3,dc6c9c4a,424be741,f6769eb,f325f749,b12cd512,d6d82ce1,e142b12f), +S(5c67fa0a,604b6b0c,19997329,aaabb82a,926b595,32e10f64,7c519cd7,139aa06c,7b5e99c2,9c49b426,e1df9233,d0fecd34,ba5e2c75,e6bb2b2f,8397c00,18d77b71), +S(40f1a163,f1046ce2,3d46cafa,30c3f1ce,a0b21da9,5af03f72,e7e8e006,7f070563,efeccb57,6a86a01,4ae4273c,fde8a661,3850ea8b,658aaee9,d3058ae8,9df8fba9), +S(bc34a35b,303f885d,d3d2f32d,81f81b84,fd283478,16d56674,89750253,9abe723e,79e3b04e,e93470a3,5c8848e9,30e3a963,77fc0704,5a0fcf62,f41f5610,1b6cc670), +S(49695da5,ff006373,2e59e24c,6c2b8b57,b081dbc6,8438395,282c555,ae9545d6,197f0bca,b2bae828,669a3505,e1790b60,134eb70a,aa85c7b6,82210c4,f6f2a024), +S(cb73405d,957090b,9eef27db,62657d6a,ec058e08,e9e51513,a63780a7,15c3c77f,80ef26d1,deb10417,a2a430ba,4501a722,8eee85de,c40c863b,a88ac3e4,814fc645), +S(40f1a629,1a37fba5,a9992ce7,a9af16d3,ca57625d,1e72c218,bdb71efa,d6ff819d,fef17320,d4f318f1,e6536f75,c104e7b7,fd5d23c7,efa0ac05,5ab28aa8,9861c05b), +S(adcedea0,47371dd9,95c2d169,e84df39,7b91b051,aef5ca5f,e759afe5,e30fb54a,986f4ab9,dcb46d,676076f5,46ae4f8f,55393422,95d33c0a,d4177ac5,bade6dce), +S(56f92765,41af201c,3e9f428,e7e23b50,7dfc84f5,b36e40ba,41f1f3eb,610d9e0a,c1b9bc04,c9e7412c,c8f6efaf,c4c8ff7a,59b76a40,d2717a5,ac6d9270,12ed62ba), +S(208efb63,23799f9d,a69aae92,d7921ab2,31ba1d9,1b5d17db,f6f061dc,30395e6e,4765abc8,177f4765,810c0fca,a125d72f,aeee8889,637b169,6d843d97,51e0e5c0), +S(271893d6,a36b984,878c40ec,45459e3d,932920f6,257af8a8,a5a11b9e,43a111fb,80ce0758,847df058,1c7d4db,6c62eda1,c41e3b3d,33d6f2ab,2efa949c,36c0fe0a), +S(a6ec4e2f,4937a358,91153a45,254e22a8,dd5b812c,1333500,321a62b5,af4be98e,db55a35e,575d81d1,41da4bcb,12a5813,65c12f37,f8ff0164,feb847e0,e49dd86a), +S(1f5a1cf3,8c4ddaac,d12deac4,efcb280c,6d6cbac3,901fecaa,a64d570e,9ebc68d,12c7fda6,5997f8e2,b4b85d96,9d9ee069,1d084761,25a221e7,cbea891f,6993153b), +S(bf41a276,99dc209f,79c80dcf,a5812086,38c7409d,cbf4b842,21869806,e445303e,d375e246,a1bab103,3a89c999,ab89d82b,7bc50961,ee500c52,4fb6eadb,f4e04104), +S(8375c69c,bb4249be,77bfcb40,8ae97e2c,db6cef39,7e265ec3,85987a60,6b83d8b9,3d6e1864,8f105178,7817858d,791938e3,7b6d8f98,ef9f627a,789574ab,c5bde6c3), +S(4872571a,c44368c0,2d0ebbbd,a82ecdf5,b451d428,f3f9f848,28046f01,19d8c41f,3ac201f4,cbaaa772,c7afd2f,1d942d29,2a0c705,90da811e,789b7aad,ab49a7f), +S(2c24eb5c,124db868,235f333f,c3453e49,5dbe9215,5b6de64e,ffcdaaaa,4be86b86,6f520dcf,35dcea5f,86edd00b,7b7e4903,6e414e2b,f643ece9,e22431ee,9b3a9d29), +S(aa70abed,8c5e973b,a21a038f,37d36ab7,61b0da01,636e9cc1,67cf95e6,78c07330,b4367401,7226b35b,1def07e8,c02b272b,8975ab77,7e8d7c31,10a78db9,94fcac34), +S(ab317750,1b5a627f,45a57b2b,38bff161,aa8869d3,a034a5fe,35289a60,e5056b0d,783adc21,9b1c0173,9977568f,234a3cf,4f05e91c,cf07fee9,71bb55f0,e379ceab), +S(d8ae6ebc,fde52d4d,c482acfc,ef231d62,637f4bde,71c32ad6,8205ab30,9d66c013,f75f1efc,2883bce6,ce06d01,1dd86796,77ef971f,22a1b5ee,1c08a3b0,2ecf9cf8), +S(949dc802,f4d797b3,b5f40cd6,a5b3bbd9,c98e579b,7a4bbc20,2770e4c2,f737c1dc,a1d1dff4,7b86235d,b16a88a4,59596ac6,6634bfcf,ff92736a,7b7aa081,2c10ef89), +S(8b0fa15d,59e05495,47dfd98f,5366571b,91355f8c,c54d78b1,b50ac4bf,ed31e633,4b0215f2,65267379,10855e46,1d8abeb2,71c7baff,170667f1,962c0954,6480baed), +S(98707fae,93b85fb,23f0fc23,c953ed7e,68fdb5d5,c7d29c5c,1b130193,400f3a47,bda56a3a,97c9d049,78bb228f,2aa3b6af,59fbf9a4,b0ea2f29,48304fe7,47a654a9), +S(df34cdd9,cc111a99,66690fc9,a79cd621,66075104,dbc40423,69a817cd,8e94500c,29ef5a11,91ae6c3a,f9b959e2,423523e6,5a32e254,c924a416,a41361f7,df7c4351), +S(c23fd61,b07e8fb6,a528733b,f4ab486a,292901,eb4f6af1,2b940af9,49e80811,a749fc6,7f340cc4,71056f0a,ee59e08b,ecfd98b3,cc978477,1eac93fe,1e2831a8), +S(d8be2fba,6d2970be,cf3fca6d,3f3ce70b,a4eb5e19,61f07223,c60853d0,bdd99e21,b03144b7,7e6161a1,a35a01f5,2474872,6ec44cbb,cff5daa8,53de1524,3d5d7c48), +S(beab3690,382f0fbf,e1ae999b,1c12a04b,f421e94b,ddbe0d78,a287c8f7,9de0a903,91168177,fa3af115,e75a4e5c,b399c136,41793138,4d22a85f,982840a7,89d59082), +S(72b16aa2,6df7b6e,9b6381f6,8f3e153f,da872dd7,16c91f66,d04539d4,bd8182b6,73ff3867,2b5b7008,6db53e27,2d7e2969,c6522666,cb544607,52aa6bd,f6a6a28b), +S(b25f6e67,169d5375,3b3c0e43,a8a1dc67,33ced5b4,95902ebb,4187277f,cb754f9f,88657428,cb2e98d7,8ca80ab3,a52cb043,cc50bda,3e0d477f,b12aa478,dad14016), +S(c5d724e2,1eeff913,fd3bdef5,10c963e,77fe49e0,18890a24,fa2832c3,a8b61905,f06907d3,ac8982cf,63eee75b,b9ba739d,e80b819,32a3e978,a3702a9f,256e9f9c), +S(c2ebd113,ad286a61,fd8bb092,ec4025da,67a1606e,31e023ad,f0f7d8c6,e18b5e61,f5a5e5c,defff7ca,722b9fae,e7182953,3191ccdd,cdee5536,f2ae31a4,48c6918b), +S(d6e1a1,62047343,aec39c67,65f07f2e,d0bd1b14,256370dc,2c90bf11,7b54a82a,75864f87,9f5bc30e,afbcd624,71816e3e,fe9c3aec,ae631dac,e0cc99f9,702f7ddb), +S(bc4fc591,c3869b15,8401713a,e545061b,94675162,8757ff17,a52d200,f6f490fb,8188af48,51cdafbb,a85fc8d5,5129dbaf,53642f19,c0ad555a,8385b0a5,c82860e0), +S(1748e74f,610d6d00,f299527e,9f09b30f,271371d8,7cea2ce5,e092416e,7823bc5,5ab591e7,4cbe7756,9fba9944,b84d8f60,268d4824,f73a05a4,9103817e,5c15960c), +S(cd5827ff,853b6997,b3aed60f,829c5fa1,5a6c8482,f4ab123,eff27af0,3e145f6e,3e7863ce,b6101b67,243b1c22,73824acc,212d9123,882310c,970c6f4,9936cbd9), +S(d61d636d,1d5db74,1cfea51b,59d7b870,4566c733,e8bfd023,a152fe0f,bcbe9c95,fb94fda6,36a9c976,2cd6e1ee,81bf6fbd,a5f033ae,1ff7db06,3c31b045,5674e021), +S(2363f1d0,735814c2,8ae1c637,ba838c00,601cf14,d99dfbbb,a1e0f45c,75c62726,f340d59b,44924783,85235374,729d4773,365943bb,21c78b65,c8d7a8a3,f1de05da), +S(45013f55,3e53c6a9,aba8d265,696ba61f,45e15c9b,b69a578d,57a2559a,cc7441e7,ea2ef736,8dd1868c,34b6a65b,6f451f6b,3342d2d7,f90fa2be,93ccacbd,6e6f5d0d), +S(8fd98d99,6bda42ab,ecc672d2,521921a,4c838e9d,760f0f06,25523dfd,2dad54c9,ce29f650,a59a61a9,5955f9c7,c4e1505d,5d795caa,4cd5f81c,290175d0,4e48cc97), +S(d9af8b8b,3ce2f4b1,70979639,db524cdf,a68797a0,dffeae55,e0bb9e60,9ddacef6,898eecd4,5ad6bf9d,55e2e658,2387fc69,d1acffe6,8603ff56,68a06597,bb0186fc), +S(f3b40480,1e1588bf,fbb524ca,9dae6d88,c96634f5,aa163adf,ccd9fd9b,dc78d8d0,4951b9c9,31a7f009,92c808a0,cd7d6c66,fd6dc868,1836c577,d61b3783,39decd99), +S(feeb0e91,e310b9e1,b8c68885,b6c1c728,31a6c29b,f93a733e,c8c86b43,2f576b27,c43851c8,46c3ba4f,6b84f039,6cd4e20b,3a8d492b,57970b8f,2df52534,ba1fa2a5), +S(8aa75b71,79cd7941,1c45f803,e0e76c01,59972566,b24d7566,3fcd1a17,8a0af8c7,f050d1a6,fc082a7b,6c342cc1,f7221042,373dce2a,2b055638,c49c5900,85b97fed), +S(44e9ea01,b7f3058e,f878a57e,8a9ed638,b6fb5730,aca25b8b,e92ea856,611e3b78,e28955c5,2a5ec160,185a29a2,28b587a6,6ab207ad,70236a25,35d0df67,44b48d7b), +S(7533e418,ad594d1,2cfee794,8894a09a,1e440b6d,335d9019,78416aec,5be9915e,312b4709,605c94fc,1215e513,ec13d2c8,e04cb150,bfed209,e848e247,485b4f5e), +S(682d72b9,e5ac04d8,23d7f275,ced51d52,6f8441bf,2b290c40,1e31e6d2,91392bd9,96a37870,6c3e7c3b,ecb70,dcf3aa02,902bb466,9db00db1,39a5e8da,1cb7e749), +S(79aa4b03,a9cfbe13,b7a9bafb,2e170b87,7dc29832,ae4c33a4,6a4e8957,ad2fff11,403a3f70,b165471b,b120e22d,a78d964a,f40b6712,1535d44f,769ef4ea,ab0827cd), +S(73f36ec8,1fd92ef2,f7a7974e,9bfabd08,2e8af24a,4589336c,9f9d72f4,e903f164,9e351dfe,ae961e77,8f617b33,4faa021e,db206599,84ce85e1,53b3eb24,bf155584), +S(c765b554,2a70148d,ca6cb008,12364451,236cb8b6,f2f389da,8325d283,1385555d,c7010bcc,54c1cdff,8cb53644,59916a7e,90dd5c52,e5ec450e,5bffd621,352f9aca), +S(e3b41ae1,42c61c16,b798aeed,8fd85c8a,1ce8bda4,c7378511,b595b1d2,1ca13278,319a4f8b,b36842cc,b4bca0d1,f30970d1,491f1191,b96bdab8,c460230b,4d79ad87), +S(e12d6ec1,6db77af0,2f6487ad,2e07348f,f09e0db4,61b65a48,51381bbd,c0adc704,8d5eb2d,5dd04fd0,a0a62c1,4dfde904,9345fab1,22b9fa08,d54ba78d,fd362179), +S(222174f1,9fd39456,30239a89,1555950e,c10fa208,fb2699ca,311a383e,a92fbd6a,47681f6e,517eb688,c1c5e6ce,ede55387,d6073d3d,3e838121,1324e7a4,e7a9919d), +S(91686e4d,30b99146,e67f23bc,5d0c2e56,571fbc55,2bde35a3,33360ec2,8664ca33,49792737,7b52d9d3,7fa3f737,898895f2,dc6b5cd,e83c034,8876451d,671134e6), +S(ddd308d,5e6de51f,4618dc3d,5ac91e2f,bf449a6e,3e613d47,5419a018,bc88f5ff,9956918,ba5f5ac8,cc155ab,c617cef3,3173fb42,c3c2ae46,e4ecdbee,9bfd4379), +S(ed320f14,1431b13d,b683a4ec,e2b82554,b32f8c8e,fa626ba8,dc9769ef,f5aec648,90d63300,1b6feaca,db963593,ed87f370,63f58a93,1712d88d,62ea3cbe,1ad502ee), +S(4a6fc424,aa5a3dc8,5e3922ff,bb25593b,a74202bd,c8a3aefb,495bd516,54fdd47d,8f32c810,59df5968,8c96d558,64df667,b1e17252,4f48fd10,801297df,325d0370), +S(409c3ad0,16237b76,e4f61caf,16788c4b,f8b8f994,f82435e1,c808a7f8,e88a0e1d,3a2a5354,b0e8d2d6,4be8004a,287e27c7,ea1d1b8e,d6b7e542,4ffe878,de81dc8f), +S(54cd117,bcb57ddf,67ad286e,fcf49489,5e5351de,95011a8f,2887967c,a2d89b3c,c4967891,b75792b6,ec631929,8ee79bd7,79f499c4,7282805,dd4270ce,672e3c12), +S(f31e127d,fc904fcf,9f38aa19,e3d797d6,83cab4c5,a36be0d7,73e69267,785775ea,1c57ef59,42b1046e,1ae1b2f7,d20f3330,1441baac,eee11a40,905315be,165caa10), +S(a0260e45,b9fb584b,1a82262,cc07a5a9,67dfa2fd,f3e7d748,705d87c8,f46d4b65,8e519cb1,1c634aec,67f682a5,72a93009,a11e91bc,e7182c47,19af78f3,bc171806), +S(f8613bdb,882250c8,8f755bd3,86e31331,8cfb410a,ceffd9cf,7b148ed1,c19b6ddb,aa36adc,3d036a3e,4188eba7,321845bf,26350925,392a9a2a,763e6d5c,da3264b9), +S(9cb8fddc,93df0048,eb5919fd,52e29385,597238f1,d7eae596,583727e7,439c0de7,c9f3d25,5cdeb940,c8cbeed9,92ae5bfe,f9be9d7,d81b32e8,a2948d2d,7014db9d), +S(4543a84d,5dda5cd6,af28086f,ec4b916f,9ba8ddb8,d6c1a4d4,f1e242ef,805cd5c7,5ab700d1,a4a4052,a137778,f5691683,824c6596,44f4b206,4f1f58af,9fbb34be), +S(a33279ff,9fa4e088,13d36e4e,e6be8892,7bc36723,cea3ae92,c059a7b2,cc7392c,b47fd3e,8dd3edd,384f98f2,572d6020,21289abd,b05a0d38,58f0c557,15542fe5), +S(2831c5ae,a01f60f5,55763206,9b0e11b5,e88c01c8,7dc81d6b,c4da8497,f8d34d26,4557f90f,2bed0c05,87bd7ea6,92db50b0,dc12c8ba,a9ffdc0f,972e0e8,9481682f), +S(f8b84c2b,18aeb807,5c001f20,e55fb13c,bff76b0b,fe7defe6,9d985f32,abef4127,46258945,3a074620,df7352ef,cb5efcde,23982c5f,3e706272,52cdfa82,6b2c127e), +S(c47328e2,8dca9f9a,ad9dd5ec,1c9e5038,f362a491,46c39de2,dfc6eaa6,32602264,4e0d731c,834a4a3b,6bd5b3d8,66c1ad,1afb3627,c641fc29,6c1adf2,13d6b313), +S(24980a0,6f177e94,7b00373f,1b7985d9,88d6f715,3647090a,31efc04a,a6fff347,62d80bb6,a4841b41,4d6c8ee,bf626629,2b2a505,15fc158a,7d00d470,63efdc1b), +S(c1c03eaa,ac9c665e,cc4081d,fad9bb3e,a8f38453,c4dd54eb,885d198b,5cb9fae4,ca769550,165fbd81,96af4fd0,82ac3a42,5bf75be1,312f7d05,f5cfa9dd,d20c89ef), +S(14cdaa50,b4ec0bc9,5f609133,4698395a,c204fce2,62fe04ac,5f010826,cefaa818,52008b61,3f289f96,1298c773,2938e44d,2607b5ef,8ceef7fd,8f89566e,5c5d4ff8), +S(9914f9d5,f45c50c5,fc4c11d6,d2aa2751,29880d53,7c0a3618,17577886,abce07a6,a4d71a54,3e5bb9e0,664bc22f,86c146ee,3077764a,fb5a0017,41405ad1,50098d84), +S(5ba84c73,de6b3cd0,df8aff3f,c907de14,b73d21ff,dd0236ee,1eb6e83c,b22cb97d,759c472e,55b3c84c,5a677fcc,19dd56dc,14f88be4,4df9b18d,c0395648,487ec1eb), +S(5f0ebbee,3d20d7b,bdf0681b,ec525604,e95ab69c,166a5ed5,a3b38790,7e2a1c76,2ebf4d70,652ab5ac,a932d68f,7687f284,8be58123,701e6e78,1995a10f,c49a0c32), +S(ac1b8b80,3d168f58,f7498d84,d771ab77,2af1c5dc,fce17fe0,f024409d,5a3735b1,57232c98,5f2b2947,82fa66f3,5cfaa879,36bf2fe5,7cc16e43,3f2ecc1b,508329), +S(ffb18dc7,4644086e,51a6ed2b,b6756b36,69cc9e05,e1599ed7,5678437b,816f8656,3dc8b95e,213dc14f,4ae4576e,80a07ee6,5893720a,62f3d45f,bbdf2946,9febfaec), +S(f80b44bb,1a268d50,66b0aa33,6f0cce05,ac025e05,6bb167cc,c3ee3256,31782edb,10d80583,d4288202,a1c7c543,90373965,bc67191,948c4833,1c629f29,2abf2c02), +S(20131423,d27cc837,a520a922,f5638314,11a73ca1,ce7b5442,c557a341,c0fbbab2,7b6757db,16d6c286,44143884,b76fb2c2,8a2a0811,5cd88e7c,c07b72d3,b91a3967), +S(92343611,cf9abf9d,76291f5,7e00c0c4,868d9f28,50e24c85,3f302c90,4a3fb0fd,1190d25c,b8e776fb,931f47ee,25ebb7ee,7dd032ec,c30bcd5b,d48e1049,6ac9062f), +S(27a0148b,39981959,2ad43fd,bdf913ab,26e98ff2,8bb5d33,d74eef9,c07c49a3,b8322dde,2f0aa07f,c3c95e85,88ffc410,5c18e236,7d71c7ce,e8287e33,80addb88), +S(b336155a,ad266dbb,a52bf3fc,e3b681d0,2f1bd72f,2a3b020e,d1a34e76,62fe00b9,bb997d81,4c915336,117026c8,f0f7baf0,a4a3d63d,13477748,ca4b5228,b32adbf6), +S(27752e08,63b8dc92,c4e63ed4,d2acf880,365ccdd0,f83d3ff7,ed62fa2,a6a4bf9a,a67b60d0,81dca9b4,ccc6a192,4a6f4734,16af822c,c939ae01,dfa88ce3,6d4c851e), +S(c9d2dac6,93e0f9dc,7124c6f,7c256b8f,f99a1436,8ccdd33,6cc9f421,e1b1d474,a3ecf256,9ec4e99b,e04cbcb3,af36851e,44d4f91f,b945e59d,7c76e3f2,288c32d4), +S(ef56ff2d,e27a5853,64a397a8,88204405,680b00a7,6c4943b5,1ad02915,a321be5d,1b2c1be4,5f2f67d0,6cd9851a,9c6f12d5,d4dc7fe3,27031b01,76cebc1e,bf8674df), +S(1abbb10b,d34154f2,d28928e9,6f2719a1,d6674ac8,5c078e2a,bf6167e6,6723d972,7bcbd8e,4c01c5a9,68696956,c4359776,e5ce3cf6,a7faef11,7cb7fb3d,19613de8), +S(e51bf6f7,73d2b22d,4dd57e4d,79bafbd4,94f9d6f8,65baa712,97d8596d,dd5b9c83,e7a565f,d8f0a273,3bb72c84,1d283e0f,d6cd1738,af58f6c2,80a31873,9f70d9a1), +S(f61e0619,2acddda5,309a29e2,43b3f597,5b52914f,5e7ab14b,45047d3,76530c93,60bb1329,705d072a,12cbd305,35ed2f9,b530e967,45e34ede,885ca32b,ff0dcb1e), +S(f91f0469,da8630ab,2134c23a,e892ee57,78327bb5,2b2eeca6,11719330,ff163b8c,c216fc14,88bcc308,e4cc5df9,42b1df51,92c2ab24,e0e6630c,38735932,f941f7b2), +S(c6ce13aa,ecbbdc54,6124e467,e5e8f966,a5cdc609,8e2c77b,37ee82bb,df5da173,eacbe9f4,9e21a930,99b08a1d,1e5e8887,f3cb59f0,b9c79e5a,1e26545f,879893ed), +S(522cdbdf,20b56337,e5062b1d,24c8c347,6335e380,4aede233,daba113f,3a174101,b8be6e5,3dbc2cf0,4373ff88,79a4d847,70255e9a,1c9e46cf,44dc14a5,91f6f659), +S(4fec5311,496a5626,341f22fd,b72d4078,109f6656,347c4a0a,6ffc2757,683f50b5,71235dd1,4aa58ab3,6a5fdbe5,71be3f,c76e68ba,9cc32ff4,95bd2166,b6c88737), +S(ece25d,92d12386,1b8b7a20,79548c7f,71f05bc4,5b37fd63,46f14cd3,8d03cb46,ee6c9e60,d7dd08cb,f3fddf35,547ccecc,5d7c95fb,8de3bebd,f77c529b,317f3b60), +S(b160e499,105c9f7c,5582071c,fcdadffd,bc3be684,74158120,50fe69bb,e090df53,702fb302,77470032,3af31e37,aff2075c,201841b,f8ff4589,fd1faf45,b265e3a3), +S(f578953b,a3e785d0,ff9a0c6a,a4f1c1b0,718024c,c40832b6,fec24024,dc65c23d,46391a1d,9a0eb7cc,40b43b3e,6f234ec4,da5d174c,fc22ac49,13d94c2f,87fae285), +S(43fb3e79,fc0b7a1e,a12e3aa2,78fce929,46f1e368,ec23d157,4ac404c9,347a2468,fb902d9a,1f4fd892,6f622169,b7a9792c,d6cf9071,e0efe86b,cebb9274,be62537e), +S(322b8b20,a86183b1,47e01e7a,1a204e57,b5261b6,3d0cd615,5716c2ba,2b7ab42b,dd36d5e4,82e4ffc7,f16ffba8,dd409cb3,217fb763,35810059,a8bf3534,116dfde1), +S(cc54be01,33ecd8c1,c3bc6031,b8e9d0ef,e5483bf8,23c604f4,464cfb5f,d3bcafb,588f4d9a,561f0951,9fbb5f07,1f0f75c7,530caef3,fda4b815,bdbc39f3,9a93e3b), +S(64ca8dec,26f3a2e0,11929ed,22074fee,f9b9ac00,296ec54b,87fb54b7,184ec668,d1465642,dbea26c1,391cc7ee,4380983b,55a54f6c,6886348,dd394b4f,9fd8056f), +S(3bf7a76d,281c908d,4e9b096a,38b432a,2aac8b63,9fd69561,18dc54f5,8f563cad,2867389,d516089e,d6e21add,199ac238,c239743d,e4355602,14e9e570,c060f268), +S(e3e6ae01,7b23ecfb,acaf4c15,b3068e5e,3c1b7b0e,808dec28,15646d59,3f84b011,88ca8e0d,a307bf72,7aeac25b,49fe536b,213d4815,7d229cbf,3944867a,6d90753b), +S(9569f3ae,b8258e4e,98e2243f,da75fb1,ef74c3b1,58f89f42,8ad3f884,7b40bb6e,751c6fae,979806ba,fb81187c,69cdcafa,e13b4657,1785741f,c10bbd3a,71b8f7ad), +S(f66297ec,a2526513,42662205,286620a9,a2a30926,4023e1f9,98c5ba95,702e3bee,9193d0bb,b677a6ed,68be4f01,8c7c3810,23cd7190,bc7be65a,67e633bf,236262d4), +S(d867329a,1e6f65b1,7b6d1bdd,23c847fd,3cfcde18,e0527696,b282dcee,3944094c,8f31fc4e,43597152,ae9e6749,c16b4873,c678b55e,19375d71,228bba75,39182518), +S(356ac12a,743ae734,81328cd,a8469f86,e0e50107,6bb67e21,e77b2f24,8b4d8bda,585efea5,d6bf41cb,fdff2ae9,9b3c8ed8,cc3d6381,bf5593ed,4efc09c6,f3c4739d), +S(c6d16443,5641ccce,bf033261,510529a9,8d5886af,35248aff,ed516ce0,e8a0cb57,3f9d4a08,cc77b5,32f8ed9,e401fc4d,39f59876,41503c46,42077c9,57bd474e), +S(cd895ed0,d1aae7b8,ede22bea,b3d39045,a3e6ce5e,cd8ac7d8,4b74ba17,ab2a67ee,1e1ad565,2d0eec45,4f9c6801,358b05c0,fa96e34b,796a293a,a2f986b6,a920e6a4), +S(1779a75e,51a56cd0,b433fd5d,5b138c9f,6d42fe24,676daadd,7f0865a5,c58c7d97,ed7e5245,445fc6b9,33032805,b4d6c02a,beb7caa7,b6a4f51d,534f2181,d7a9812c), +S(5c1cd955,73d0ffe4,1d06ef6b,a3aa6f16,f275525e,15e89142,cbd043ad,901bffa9,489f6af9,1798dc67,c71159f,44f4b3cb,b3ba9cca,bd9af2bc,a2fa6e1e,d693c7fe), +S(637d236d,8d9dc670,1d78f88c,acef91be,a05092e,44e2ab08,2f057ce9,ccdf1011,8dd1883d,303dd21b,6de832f4,fab06158,ae9a7043,b6fc026f,88d6981f,46476547), +S(c3c046a6,d0ba702f,72f3e1d3,d7af46e5,5ba2581a,b1efbe36,ed20b96f,326afb97,d9d3d813,88bfbf02,9662d022,ce0fcf38,c5442a6b,426a852a,ac443f4c,c0b940da), +S(f224c5cc,249f2879,92d6ad0f,c9556628,b8565431,b0778364,44521b76,1e220e71,4aa9dfa6,99c5eff1,209ad9d8,9c26df9b,4a7942f8,607d9f86,deacc85d,65637dc6), +S(50c0ce65,6f95aa63,946b66a8,da465882,19b856b8,8f2cd78b,5d85040c,feb19a05,b8529304,9cc46692,b2ee676b,d39b6c7c,d2f465c,f4ededd7,6e7f8655,654c18c), +S(925757f7,d66b084e,61fc08a5,cb96d115,86f94c5a,5979d09c,ca34a07c,44133c5,66691d64,5dc5db51,bec2c2e1,e398fa11,84209850,99ccb6f3,e6467406,256f768), +S(a1a7a197,c8067535,df3ff670,2363c366,988b3630,7b63ddec,a48e5c7,35a5338f,4936dcc1,b186ad2c,7f0bfcb6,7792337f,561a378,e8508206,46e2d8ff,21296856), +S(54ba4a9a,877fe4e6,baed26e7,307ff40a,ee662d57,7a48828f,eacb9bea,cb7b614e,696eb116,b1508f7,547463dc,a93cf778,1a4842f3,d7b120ac,89cb0799,5b06bf15), +S(5af3fea8,2941c9e7,bc3423b3,ffd12df8,2b560441,dc3a2851,9ead7546,898082ac,e33fb5bb,c79b2fab,f1755f54,c56b67f4,c1ed9776,1580cf38,3b603dd1,e6b263b4), +S(f383a835,81e8d9e6,1e9c6d31,8fdfb6db,ffb26137,367885c3,401e1b93,33ad37d6,dc6eb905,bdd1f81d,b27ce843,df578a31,bacbb490,bba9adaf,d0c4cf30,c2e858ef), +S(ea01281b,1aa98a60,5c4a1d9,bae8e45c,a9e67ce0,6eaddab4,4decc473,5a7a51e2,3bb44d94,b07c483d,da7e1f63,eb8dbc9e,4f9e4a59,3ff722bc,816a11a7,ab0c4cd2), +S(e5d489e1,e3d0ddb4,9a1f42a9,e928e2a9,b1a1db09,48a59fc,68452a35,c52fe7e8,90d6cc3d,b30be1da,a8d3742e,bfdff07c,f8bc7c31,a3c4e166,fbd1c3ba,9c6507b2), +S(26133aa9,17fa7770,102a229d,487c56ac,1f531d0d,536043f9,8d25d6b8,ba4bbf0b,57c2eb26,6ce9169f,8b0f0a03,cc9d7b3f,25e1965,91eb66fa,247bb5c4,213ef5f9), +S(447cc951,1e20b173,5cf546e2,809140c1,ad248474,51c101bc,40e0ad44,ce791f12,9031be0f,bdc5de93,5539eb8a,dfbdffbc,b5550e70,613811d,dfc9131e,4550ea6c), +S(76992362,e0ab0d3b,b4ba4552,1197fc18,e355b161,bab8b080,a9b849e6,c32f4ae1,c73b4930,47dad2da,c9eba540,5955da52,94b9a184,fb1dc60f,8cc94d6e,6fb1bec3), +S(e14ce3c5,831c8464,75ea238d,46e8e7d4,ad77f14b,46323bf0,aa48d958,cba69e63,57b2b465,8947875,a26c956e,e8b53d83,2d8a4c10,87170d78,ff751fd,dc82762), +S(76375016,e26cad9c,c194cc1a,fd2a5464,5b5450a3,e93eb3fc,c973db01,d367fad3,f86a87fe,5ad93797,6a96323a,e4261db9,6e176488,3f389165,3aea78a5,a3b3e0ef), +S(99947ad6,27bd282f,60eced69,6a6bc741,e338f2d,b905fb2,85e170e2,9257ef3f,6167d7f0,14605150,2e226f2b,6c8320e,b2338350,9962b6c7,e8945f81,4ce1ea63), +S(a68c11fa,497edb8d,4798408a,f2c0c832,f7f70ac2,45188bd5,df8caaf5,58292b66,1007690,df500ea7,a2e80c7b,78162a27,2b54c93e,1bcaccc7,84218656,8f24f590), +S(559865b4,fb13de16,268fd4d6,f2e4adac,6fbe420d,1c7db6be,cd09cb58,a539edd8,f61bb541,17750264,94d479f,7919c6eb,9198df88,3c195399,f3bbcc5a,5f43b52c), +S(7e88a6ea,d32b58f3,5e76431f,75a0b1c2,848b79e4,8226fe18,60241685,e1e349ab,6b070306,7079d62e,747bb6ea,85d7fdbe,1df8730a,7a62615,28b5b20b,341a5d72), +S(a93b9d40,c0b8cee,3a094e19,a181cbfa,d4ec38ee,f12b3fc8,d8e2fd05,70029b05,8c55292a,a8a4ef7d,4a69ede8,c55dcf57,e0247625,85efa9d0,aa22d6c3,ff070370), +S(26afd318,eff92753,1727fc74,5d3bff1a,9b433c23,475059ed,a6065375,22c0cc49,5f03409f,e8a2e649,7b1deaa2,5c2ad40d,517fc985,2bb306cb,86b0a16e,4448fbd4), +S(c0b61efb,ddac8a75,3f32e885,df07e071,a4250886,4657014d,de4fd9b,aa84be93,c30a6285,e838590b,dff89275,a1f69548,c65d7478,52d57a6a,aef16450,f73569e4), +S(be39b097,6ea0302f,8350a663,1ca366d7,7eb108f,ad8db45c,dd679a5b,68e7657f,4528a809,88d04fa0,b4ddd4f1,10fe8948,ae1f6c37,a13d7a10,81cdb4a3,4b83aa84), +S(267becbc,72ebcef4,95d64c5b,3da4bc2a,3fa2149f,a554bad8,eb20bc47,b43c055e,5c5cf671,4fcc1923,9bba9e52,fc97140c,3037d95f,2aa4b828,2f019854,63e89e38), +S(683e99df,1246557,2b88fac7,914c6b15,a819be55,f7415348,a59aa51a,2f08d99d,e5bf288f,d1a561e6,7b79920a,7cff1563,e22528dc,c0a56996,1e87b84e,98210f18), +S(984d688b,cf2a0f4b,b5972f58,f996d13a,c65ddfd2,35247aac,9c983aa0,ad61bd89,b31672e7,ea2611e0,cd3f9397,3d56b8f1,78ceb2d2,85f15a8c,55a4d514,e8b9296a), +S(a9224213,7882e7a5,5ef1c35d,12a6cea7,c0912746,af66057f,20a9835,5dda38a7,532992e3,630370dc,bb4490c0,76f81e18,b9b20dc1,99b0a557,4c600947,5f05cab), +S(6b6cf051,d4311bc2,6a878a11,f5d755e8,dcfbcec7,ba63180a,6c1a527,90c75f0c,395f012a,fe1f6377,7266f20a,d3f1b47e,552c1e04,fee7cc43,bbc94206,1ade5147), +S(df30d2a,fd1a4145,112b2e25,1943fc1e,3c251d44,f67f583f,793d1f2e,da10e3dd,e6753f83,edcb12f1,e29f688,a555699a,aa361a11,afb94832,32849cb3,33bb66ce), +S(1e09829e,89fe1ef0,54ccb6ac,eb3787b,291ebefb,c4531e5b,765090ad,49e9b4cc,db2bbe7f,57c81824,515191e3,7718c75f,63b6abfc,ea51f397,b4a6cef1,6cb49a58), +S(eae324c0,88d0e213,ea0a5e4d,9fe3cc78,3488bc63,22fc4733,d5a2509a,e9fe9f91,5bd9f44d,bf33e894,7572cd8d,41f7ffe6,47d1e194,b4d27053,4f3da5a2,df55ccde), +S(ea64dfd0,aafda3c,e15d6fd4,d4fd87ca,a050e0e2,9c581b86,dc0ac4d2,9396f1f1,f448858c,36b44a58,fce7d720,b8f577b7,d0888751,2569e473,eba52a94,ffc0b33e), +S(22bdbedf,7b4bbc51,a95efc63,8ddf782c,ef33cccb,b112e866,61e7e47f,4eeb4b3f,5c9703d3,84f23420,3eaf2139,9e2f51ff,c02fda84,570af857,e6d51377,bd837e7d), +S(57f7a357,4787394a,d3577667,99126aac,593d86f,58801919,b1f8ad06,d92f97ad,edcedd28,23618851,ee897866,44846a08,5235a60f,d0e84dc8,7ac22ef8,21cc9bfe), +S(38da2e5a,f6018763,89c3b2de,1101c202,390048ab,5e976c5b,b1d0626e,27b5e684,ad71092d,e3c12d55,496c5fed,739a8007,998bf851,8dcf7937,1e1e5d00,cf05286d), +S(129449ae,79439127,7e336d44,34b40d7f,6e649931,feb5be64,b2e59678,1a9eccb6,b7c99b67,a2e523ed,9b52110f,e5104056,c6410ed7,1c91382,c4e5676a,3f0d568), +S(34d6ee18,c82e63ea,6a795055,4558874,6b93d52b,295b52f4,239cd98d,5250a099,d8a9bccd,2d8e6f2,54c25353,996bccb5,dc2ebc48,ae5e6f55,eb015ace,e111fd9c), +S(d202f4c9,c114ad97,963830d8,1d15018f,ea9fbd1a,37b8b818,3a504b89,5925ff3d,f250110,1abb223e,c3293e06,3dc5d2b9,20b5d0c,ac28ef72,3c3ced74,6ec25def), +S(753d539c,82d24f0f,64fb7e90,fb9553bd,90033df,770d7fb9,aa6255d5,f598f611,340d2ed5,7f4a7d9a,d0f94be0,d7c80fa8,c3d42eac,5536382f,76568caf,ccc86226), +S(a440e28e,e1bb9c91,c03b0664,ffa79f2f,c645433b,59ea44d1,a88c73c6,1536f480,96387729,9824b3a4,d28f1a2,7f8a6f78,60407412,2d06b028,78a31c79,85354247), +S(aa9a9ae3,3ee7de0d,5a1785c1,75bfce5a,2d353344,3c32c5f8,94f7248a,1726a0fe,9063cb03,350e55fb,dec53691,4d1dd16f,34d3631,f7d4a56a,f2c6601e,1eba9482), +S(61b60b17,1d406619,e612c5f0,eeeeee96,a7b02b6b,13333f29,3a67e9bb,996f4dd9,e5093ce6,f9eb8b4,4cc2b835,404ac312,2c62228c,b3f0780c,3d995ffb,f92d1734), +S(7fc18068,b529b15c,86180482,b33b7b7c,12b6cd49,79f46168,58cb6084,c92a8443,49aa8a81,a8d66fe4,b4993097,da735768,a2a64f4d,21993b5f,e6e45f25,7632d775), +S(8ae08ac7,6d8ab6c2,a0eac25a,8bfdd54a,1c383b06,84d99005,5f1cc3fc,ea2ae26c,1b463b39,549f3095,14e22e18,e51c4af6,c3e4f5da,9050b9e7,e1556c2d,9b47c2e1), +S(de680d6b,9e75f2cb,4482e3c6,37b03f25,1873aa93,d4af9641,a3e0efff,d10d10e1,22fde416,c2cbfe77,e27fe7d1,190896e6,64da63c1,f89793d7,1478697d,e5cd9108), +S(6522ca17,8d6fffe3,34a8dc3e,83a7c9e8,566d4d61,aa0de5aa,5623982d,4459f553,cf0033ba,988ca9f4,7afdcff2,abb9a069,62f1622c,2b3744d0,cf7533c7,9e5fd425), +S(bec2be0,2fdd1e26,699cedb6,92c46054,57317b30,3e2ddc2e,bf8c9b12,a55a52e1,f03d1203,e013cac6,5b4fcba9,6ff28834,b6dc8539,d38c8053,4d59b5e3,ec3b45e1), +S(71e3f913,cfda601b,1d9c0d29,82dde7c7,970123a7,a2c9c25c,548995fb,6d28d488,6b30b817,2785c0ee,82eeb3ba,1f3b6f64,95b73a61,990e8532,aec482e,19992f85), +S(901223af,65764264,da7fee9d,fca46c4a,d7ce95f5,1c3d3b59,554853f9,20de36b4,c15ac0c1,69b718c7,9bc06ba8,6bb180e9,f4a45c4,1b09a761,67139e11,c3cf220f), +S(bf0ca457,8cc9c676,e6ccce5d,dd9139ed,ef3e2a92,6d4cb5e1,34db0a96,302ea422,b067b031,4a8cd0d3,427d6e18,6c12d0b7,3eed37a2,b7f197c,e2359dd4,6854456a), +S(8e4ad808,c2fec2de,17595149,4cd176dc,1197c18b,b6d31f18,41501c96,fb96293b,71b0086f,f41aa674,e21802fe,f44ada5d,99b5d7e5,47c60b1a,11c4cbbf,42465e6d), +S(7c682ec,732238ef,d9226ba7,9e3d0a21,d3a23d34,66597af2,4db38989,d06464dd,6a6e89a2,fcc6b55,c9d0562f,2c58819d,b7b59177,fa16eb5b,4f6995bb,64546301), +S(36f96e68,ae6603d3,4da2736e,f76ec4db,645c26c5,cdac2721,29527ac1,9378ae2b,6aee55fd,87741026,362d9c02,1adaf833,1a85623f,d97981d4,d0ef82d0,87e83ed2), +S(3cee56be,a461cbca,53cec614,3453442a,8b7f314a,5a79e004,6ccf2363,7b867ed2,b43ae401,ecd4dd1e,4741fc78,cf1853c2,97352cce,853c50cc,fa4c9699,7b063228), +S(6ebd223,be2b4d8e,6fd3a2e8,cc6d899,9b8f571a,7f5e9905,f45d71b7,7654ba84,9cbcba8,3fce430f,41073a92,a90380e7,73faee19,b2c08150,949708d,f49d23b5), +S(112aada3,f4ae50ea,cfb050b6,52ccb99b,79524b9c,4d7821f4,d67b4fcf,b992e64f,4b4cc764,ecb5698b,328eb0e0,7a242e0e,b69821b2,38231446,964f1f01,b6c59877), +S(54e622ff,ef55ef5a,8bbb46e5,f7a98f9a,4cc577ce,ef87fcc6,40909be4,8b0ae6be,1442f6fb,a55ba6b5,7344b4d5,5555f71b,4e77c10d,442504b1,64f1d948,a38a14fc), +S(247497b8,1e23728,f7dc5d0b,8c450eda,fb6eb9da,7eb90d35,e5939440,8705301f,9a5d529e,f38de912,f5c7f58,56e02285,32c6a6de,702244a8,6bc1990d,6144b46e), +S(720cdf82,bf44e211,b71d6fe7,52ed34b1,c9d7f88e,5c4042aa,b3826812,b45df62a,2a05003e,1b36d9f0,b76e34e7,66feacc6,2ed49573,a3f6414b,f631f32a,9d79817), +S(7b9a28c9,8f5260ba,18db1c61,5656d2ba,3de591b8,90a9cee8,96f60bac,54cba095,8a162ddc,95ca8565,d00530ad,d8d338b4,bd62760e,4f185963,60de82cc,9b543e57), +S(cef8910e,534f2fe1,9228ec86,b903a1fb,e6056a5d,2cf7ddb7,f2dadb23,6e2952e2,deda80a0,305e27b8,e9cec5c3,81015929,202fbbcd,3e84340d,3172e0ed,70666b1e), +S(1203af6d,116f7b3e,4926c3c1,f9002e20,196ab0e0,1c6b2b5f,adb17142,8e2f6ffb,6e7fc524,23e6c744,52d2b6cb,4d659fa6,6e541df5,785cc666,a4779429,7ea3a842), +S(c265725b,f9c43ae8,8ea01292,9d0e3edd,e9bc761c,54316ec3,47adb51a,98eb4590,362a5d1c,9f0ce3b8,9a6c83ac,b30a7e00,ffa5bf70,be1490e3,f1e643ac,3ac65019), +S(5044578f,e3d7c3c5,a70a6a1e,dc6686ef,da027c91,a9bcb7d8,5a14cbff,6e7eb943,18d64743,78e2842,b6704760,d8c68b0f,5caf61d0,37fa4b20,98046c88,8a3e84bc), +S(3d278c7f,c4644246,1b324f0a,f666803e,5e052d5a,80dc0755,9d067d1d,e32acc63,a242e218,d1449f64,20417ab2,41406756,e94d3aa9,f4ea1c40,192015e7,3f3b74f6), +S(e89ac46a,382f58ed,982973b7,6569c95,c23c7ca4,4c893317,ce3c3a0d,934b4c93,f8db1b16,6bca5162,23b6d397,3a7d429,9a99a1f5,1c9e82d9,96e00103,11a9c696), +S(d46d9244,52ed46e3,5868ca93,35c9f14f,158165af,f6a16d0c,f31e90dc,569b8acd,c26880db,bd8c2308,5b2995e5,7a40773d,e692799d,b8680a29,d01fc51d,d92bad21), +S(52b62ffb,6989bfdb,ea671d22,f782c692,aa99daf,f6afb854,a260f6fa,3a5dccd3,75d15e76,a21b03e4,7adf5c27,3953584c,9067450c,343f026f,e0dea126,6d6a4a52), +S(b3db1f2f,9c3e602d,5c32a28e,85079423,3759c3bc,3ebaef4d,485f1e00,817a5f30,cd336cbf,7cff0f29,211b9c6c,3b811eb,1d49dd23,c03d36b1,54b43c71,91dc62db)}, +{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), +S(d6f735e7,93f6162d,d540a255,76449ae8,edd46e31,d8f641a6,dda76200,c0d33e4b,7f8721f9,23fecd81,b153eb3c,eb2cc58c,c21f3cce,56a1d750,7f99934c,4ade221c), +S(84254df5,b28af43e,d4aed5f7,4e104d1f,2fb371c0,a2adc7f4,21415ce1,ee836c51,b07204a9,260540d4,8e29fc23,e254f378,a49a2cfe,fa21efa9,a2657342,3be3ffa5), +S(7c329ae8,269aaeee,fc01a25c,d2e9a15e,794c589f,b3ad0c76,d51c8efe,4fed9c87,a31b2006,b54e5b13,1e5f4997,f1eaa866,77aa3073,6f6b808f,249522f6,99373dee), +S(922c5ab9,b3938aec,d8a89bde,ff2a803f,fa6d77bc,d1301d76,3f8aee6f,608c8976,efaad685,6ead7c1d,adeb3f45,988af445,ed6701de,1e063a53,6d8b76c7,64be0ee7), +S(3b3b6d42,b662a8e7,44e218b5,4e8c7ae8,842600d4,dc8ff55b,701ae392,512d2d88,3319f63e,5e72d98e,21b23c40,fba11751,cba6756a,68dbd747,f5ebf054,34f8ea52), +S(7031413,ee20f2a3,c716ba79,39882dd3,74dcd7b3,c4fac819,10b856bf,72edb957,20fdd866,33755d03,5ec21df0,39bd4c33,e4ab4bc3,4adc6e7e,f95c6afb,980daf70), +S(b924bf9c,93d735fa,24f61239,83aa798d,e6745852,cb1202d4,db74ded6,a9ca4d67,c8800807,c30e88ee,6351e5a6,547705b8,e29f87cc,4d7166ea,c719d0e3,3f156cac), +S(d43f2e6d,a0f105eb,e6fa058c,c3e98099,3d878f4c,40791188,80a8c5dd,a775f798,3c681084,a8a466e5,34fe34f0,f533f6bc,7aba722e,37af767d,30519272,4465404), +S(d6fa6f22,5617d2b0,6b35249a,eebdb016,517b7ce8,f2f52051,385ecd1,e987785b,1fb064ba,ee45eb8,b7ee88e5,963e290d,6bca04f5,1edd9623,a94476d9,83d60fba), +S(8584a76f,1b641da2,e3645a14,b9b0beb9,9e43f4d8,40ee16bb,793aaaca,c212f1f2,9d3de317,5cdc70f1,35aa3b81,e8a31154,15a65855,510a1bc7,d980715e,5af76d1e), +S(67f50f74,1508598a,c32fa77,8e7b2ee0,3b24b63d,7a48c12c,5bebfb4f,8af63e2f,f35b00cc,c14cdc2d,a088d8eb,b2b39878,5fa46ed,4ce966c7,8acac1d0,a59430b6), +S(34bac85f,a0bae27,e443336f,c6e6df4d,252e5586,f0dd898a,afdec4c8,8a57239b,756a85d9,71dc0296,8f7124e2,5edd877f,d8554377,4c8dc772,ef22f698,5d741a7a), +S(1d2bf603,120749c8,c802441d,b3021c02,65364a0f,6a162d41,f4dfb347,a425a8f9,4cc35601,ac8bb504,13e3a3ed,9d67a55a,fc5cfb51,d3caa73e,73300b65,9503f351), +S(26b9ca6a,aa72fa3b,68c0c995,52636afb,d0f6e88,e540dfa7,a5955952,af5204ee,b2d6cf87,1e017775,152ec88e,155e7ff2,5c04a631,92df5074,2a5e546b,6e15cd89), +S(7dadd65e,6c658083,e82369a,bfb1745a,fcc94247,54db92f6,3fd00d25,23172d06,655ca6bf,232d8f85,e5d0ed6d,5b4040f3,c34e9589,6be0df98,2c65ac06,ff50d51f), +S(98667128,2950f125,a399c076,d9eff5e3,ab8eb85f,c5a496a8,ae8c740f,cd4853e1,949246a6,b2b17c2f,2ef08455,590d4076,a26c508,6a4043f4,18f2d2d7,2dc42511), +S(efa70ff2,4042d4cc,5215b450,703838fb,d274bec,204df700,72a014b8,33d3bdb3,62fc11bb,bb1a6d7a,b585f05,c5da598a,f59b2148,f31d293f,17280652,c8743380), +S(97ea8025,12bb4141,7a2ba994,8456a498,f66fffb1,69883e3c,970d4c13,834c9f61,87cc181f,6a83fc47,c1ba6e74,38104fe3,1627ca80,6b4efdb3,329c62aa,d5cf9913), +S(1353da1,849ae275,84e55047,e8662ff,2a2361ea,fff847bf,17dd5c8d,52b46942,a380a7c5,2ddb6241,cf7cd12,87cc89d6,96a7b3a9,5a198785,76bc4039,b9a913ba), +S(33329e8f,50855274,5598448a,d07e36d8,85b9eb34,8f67b10b,a8b7d04b,b71edc4,be08cacf,ad6763bf,92864ae,3afebab1,a6b19992,b1f0d9a9,436f42ee,b96c6c90), +S(863827a2,46421930,553387d9,46fc1b4a,7d40549d,dd470f6c,75569887,27fc2747,3fd2c6d0,a9d5a056,95c25ac7,8f7eadca,465176d4,fee49512,72a93d33,5fe7324b), +S(8f2c64ba,637543ac,67a7706f,69ec59da,9528be29,7b1be5e7,ffb4fec0,e16d25af,7cb53924,c47605d0,239add6d,287030e,9e8f33ab,4a36aa56,54f1a729,e3dadca9), +S(8ce26953,8fe8a9dc,ded83d07,717e96a5,c95eeeec,e6af2b92,14ae0811,b315909b,9277f1ea,33861808,36545b6a,f467c0f2,dd96ac04,28ea8a0e,e32db52e,de60207e), +S(44274f51,cab44f1e,3e527e95,e92156fd,1cd2e363,332876d2,d3ce75a8,e96c034d,fc4edd64,5e2fa7fa,3e0a8a60,36af7a5b,80424f09,7203774e,489ad68a,5a0c3b3d), +S(ac9170a2,a320f19e,211c2cae,b827e87,d065a9e3,15e11584,d074c328,b38dff24,5afeef29,a8a03e49,45009c9d,e41d354f,69d8d974,ff0f6b08,d0bdad83,5bb8fb5d), +S(eb21ae48,cc5aad77,7202e145,e7178bac,af1899c4,de96aee6,ef2560e1,a13e898a,5726d1a9,1c897a8,c6594022,e139d2e3,e23047f4,99d107fc,9f3ca9f6,aee95d9b), +S(b6b842c5,bb0ec79c,36c0831c,b87f8eb4,8234618,f5d1b888,678d751d,be61c7de,9dc3deb1,6eee7b4,4f6d29c4,ed170cce,2fc78db1,a5485dd7,85fa6de1,8b9d1838), +S(281f770b,e956f478,26529137,e836d00c,5a5b55c7,4158ff32,79b96ef,7b6f17c7,33e0dd6f,e4610a87,c703f4f1,9a7f2b14,3756ee8f,e3e6fbf1,a36f1d28,88a2a836), +S(3520dd8a,8df2555f,2a404ed2,d2766080,302a38ee,14cad37e,a7c575cc,18334cd8,36000e77,7a789b8b,e3de5ef9,71b345f3,3e08f491,3171df2e,ea41e07a,cddbeb92), +S(4307f2c6,db337087,5e69307f,73fc13bd,eb70f5ba,8651e507,2b58ba8a,5945c07a,198ad388,9d9c5b9d,2e050e69,b8b0ab53,8641f4aa,98204215,5262143f,2e513bbf), +S(3f69e90e,4be15f1b,7a3e0518,d2173143,8fa2d0d5,31617b6b,390cb3bb,6dd3e130,2c2eecb0,fed8c40,a0e158ed,44c94f07,61c5c288,d525f12a,ad927235,cda29dfd), +S(487638fe,525ec3f,fd34fd11,6ea6629d,4c15cf03,fb581c18,2c14e0a5,526e9b99,464c0ab4,eac365db,ba6aa562,2dfab02b,93ddb339,d790f875,f8e98a6b,6dc1677b), +S(9fba06bb,20600712,45795836,ba95a91a,af40c61f,c9c83511,8bc97ea2,1428981a,97930e0b,e2b4fe40,8bb37aaa,afe5b66d,6b8c140a,d4a0b0db,a39abce6,f35bb8bd), +S(fe0b19f0,dd103ec7,cbd3d605,dd1e6230,dd4dfad1,b4dfc2e0,23b8463d,8710a27d,167d8e8b,4595516,1daf03be,99d1dec,383d4c47,247c68c3,8927515b,dd388621), +S(a935d63b,16467a8f,41657e49,2c9f7fb3,c5da37f2,3191955b,7e73882,5bb3d256,7fbcb19,2261cd98,ff7b5087,567c1dc3,635b544c,d9f43d02,8d11a94b,94812623), +S(ad28e247,18f124ca,b1377df9,f3f78fbc,1fd4f8f7,74925d02,2f11f56b,c08bb8f2,e3205a6c,5add373d,4893fd23,84fab0ca,525f87ee,ea5b687a,b1b60550,f090bc1), +S(9fd9c788,2172b1d5,9f2c57b5,746506ea,9483fcf1,5cf51ecc,70fa4a40,841f7e9c,900279b8,566e555a,ad3e1318,dc890ad2,6a0c9e4f,36ee4e01,d3a6b046,7b66f11e), +S(85ab8716,a347ffa4,fa4a9807,6a7a1e4d,8f887dcb,7b758212,5831cee,5fd755cb,ecb83ee,e3ecf915,43460350,39e2097b,ac9f0000,2855ff37,ddbbf6f8,6d2f885), +S(da34dea6,49f6db93,c4edb612,c7872054,d78b9e13,4614502c,e2db2c3f,1445d2a6,d34bd4f3,d65a7b20,79510648,3b41c2ea,5ecab70,5fe961a8,a3844e0e,95b5640), +S(1faf535e,2136c3f0,e5026f42,15ee8d0e,d088dbb9,81ecd469,b5311a1d,c235462e,ac1e6f90,a482e42,c6c4cdf2,d8c33dab,b307c39d,c3745cfa,db24810,94e826c0), +S(d1924ae7,ff945ae6,5c1b41fb,398c257b,cea8bcd1,fe6c6e8f,2bf4118b,c6bc9fbd,33d6d54d,237fdfdc,4536abf4,1bfe6681,173a3b42,5652aa1a,9f605f2,8c2cf834), +S(5e30dd95,dc01b76d,2eb1876a,4d0079e7,4473f4d6,acf88f,4b1a7ade,81ab4a44,5edefb5,959759da,4c39c9b2,8ed669ca,7e96b937,394f8cf9,109d99f2,8ae94e9e), +S(1d1b3ebe,aaf21685,c590efc8,5def9bb8,4b5a6e74,de93b34b,b9b169af,3d1863b6,9c5230b7,c41d8d3b,9512a817,34fd101,9d98856e,b916fc79,2806e377,2a75fc93), +S(b1f84efd,e53a7f4d,4cb66989,876f9521,9922fb16,65dad292,a342ef77,f151a7e,624ba3ee,f1bfd30c,81e905f6,fc9a17a1,1c0cc014,acd9ef0,25620277,3e95e849), +S(88857890,30e21565,c166d64,4b14a4ba,9832f99c,764f34dc,ee2aa79f,60f3b4ba,bddced24,35da5a76,79c207b0,e5713ded,b73cb088,997e2ecd,c9cbfc43,f38bd096), +S(f4b8fdea,a8a4a630,2d59c0a0,b34c2998,a7a72c6e,911cf7be,7adfb44,63d1a213,f78d9aba,e80329e9,f02c4f9e,d1bc524,35114a63,884709a4,99925c8c,d06963f7), +S(7f85e0f3,6a03b7c7,47b9cf89,55aff917,df60dd64,f35e14b0,4e9ba8c1,d647393e,f3b23489,f86e10d9,f9f542f7,49df5ae6,d50f5613,481564f4,b8842869,6e40b72b), +S(b5d3138c,6fee7f5d,68599558,b7f4dad9,948d47af,98abb02e,369fff57,bcb9deda,e0d247f5,2e097751,fd33df86,627cc172,5a26eac5,4a6782e7,7c42cda3,b9262d58), +S(7b13216d,bbb83d60,20b9d45e,5b202538,ff22a2e0,e0358147,22344248,d352f2dd,2eff7c95,77819e9c,aa0a762c,ce70fe9c,f0732917,46a2c8,250b0a86,77563e9c), +S(3a79df59,b1f3ced5,70628491,9aafb365,59c757af,efaddcf2,164dd3f0,73e0b85e,5afd0066,b083d36b,da510974,75d07f24,28ec9d25,5ccf79bf,49e059d,cb637a1e), +S(318610b6,9f525ece,4c7b4c28,14cd0fff,d4729929,56872cbb,3ca350b3,6c0d5aae,8dff9296,62ccc6a3,af202f73,4825ccea,362d64eb,30fc187c,f8db26fb,6ab1ff8b), +S(e411c5bd,ea470bea,188e8e26,f7207bca,4f92c793,ba34c1d2,d1a0ed70,f441d836,d4d40b75,f46aef9a,b17afc53,efdee46b,50217b2c,93058fed,838fb17b,4fc33be1), +S(f363388d,497316bd,bc962af,270c591f,6d5868c9,69a08003,1ca021b2,f218792c,6d29bca1,5716584a,8f13a69d,498ffb53,f37d38ec,d7703e92,d55f2dd7,14b860a), +S(79852af7,34689490,a5e7be06,33f973a4,5f1870c7,aa5912c8,8b121a6,3a6f7aec,ce1bfac3,f472d348,c5186160,e167d840,426a4be3,7a58f56d,ed651eaa,15d14053), +S(353357d8,c93b2dc3,3e091ea4,fdfc99dd,3d235074,1eefd250,70215e03,7ee9f450,85c07a65,6bc1389d,9065abe6,a896d4b7,953aff1d,f918827,dd0b57eb,918e8297), +S(d64e1ec,704e979b,5cd19df,3ea4845d,8161f348,eb9afe89,de1c22ee,6fff6236,6772ac7b,c2224a28,dfad9639,3b9fd942,6f59d6bf,7e4a94d5,4003d24f,6b1cb2f6), +S(4afe8fb,9fff7ac5,3a0a0689,24b5961b,4056f190,27fac3d9,dd493338,180e41ea,efb6bb06,ea3ed1ee,c5e7603b,2cbe1d11,e32a1602,19079b9c,a04f997,8ed42f29), +S(bb42b5e7,a047ca7b,eaa52d7,48c763a,3ccb8ca,38f252db,f131d123,90cefe5c,65f8231e,f9bb6ac,4adcd01e,87b99dc3,b2dd30dc,4163d84,8dc0faab,ae035b87), +S(cc6431cc,e7e4ad45,a0125326,6a8114e8,ac9c6896,56cf6e75,ae8cc4dd,cd810a29,498de8d3,f8194a03,ee8c5db,d1d39826,6e09563f,9d5253c2,a6f5ddbf,cd41dcda), +S(624b81c0,b8f558b6,6b19afbf,76b1b7c2,9ed964a1,b53b6ac,6e58acf3,4c6e4d4c,d8429386,43d28c7f,f0e79a55,801a989b,2c923c36,d84638af,686cc637,2cc3095a), +S(53ad6cd8,b0bd0b5d,2742bd76,65c0d0dc,25234c21,a68fc9fd,da85b2d4,a9efb4d9,d886b54c,9dc40ae,40f57f4d,112da945,46c44b26,8ab08440,d027740,8264d5a), +S(ed7a10a6,9a2a65b7,7f3bfbcf,2d8b2f5,57ce675,5334f13d,615f85b4,7bbaacc4,d9021ae8,e1a0cf99,ba539b6f,52dfa141,ac6d2d48,ff71c1f0,c2cdfba6,845750e6), +S(b07022dc,5d250d6c,1464a03e,538b53f6,72470792,da6bb28a,9eb97664,a9797d9d,6e1dc0e9,2b112d0c,520e3fa3,7e90f7b6,36959a43,15a76833,ad935237,6ce4a96e), +S(f0cc2567,eab35314,d0aa253,681d6319,cb016a81,c6e683b9,51e151a7,98b3ef22,cad6711c,1ae440a4,4f547afe,693d199e,4be0f8d0,6a13e2cd,4127e9fc,c99da815), +S(1a71731f,232ff7a,670c81a5,30b9868f,eb59fde4,6c77a264,7357b84e,51917b2b,1560cb00,13a3bae,23983028,4be74589,ece8016d,8c6a23d2,9b52faa8,e907eebe), +S(b8e1e4c7,461335f9,536fec82,30136f2c,a348baae,bb3a6cda,fc8a3a9,bcf72df4,fe85e36,e956074a,26f56f8e,ca1f4fe2,81b0a682,508ca1c4,d6c3249e,21f48cf4), +S(63eeb2ee,ee187fe0,b80d0c2f,ba2222d,1a763aa4,776b2679,b14bd541,f566bf8,56ead5ac,84ae0964,c728b87c,979557b9,c44c13c7,dfa3b31d,86a7e31,5a920c99), +S(862e7b7f,9bf1cc99,8f0a3cc6,3d873eab,228b3977,8bf3aaba,57ab16f7,32ba9d0c,2d69026e,f29ac9a4,151d9f98,1c4248e3,2c3e4789,72c27811,68fa2c4f,5fce4a28), +S(e0588c62,3f65c421,e12cc7bb,d5842e84,bf46c00b,3ea3c38,9ef98056,6cd1deea,98dc9056,d105607f,569aa79b,6d6b6cd6,1b42f749,4333e255,35c220e3,15f9d939), +S(9a6f0406,7e3743e8,78ba2f1a,4b4aa09e,bb8b5bf5,7058128f,bb0a573b,1c504689,6ad673a6,61c9dc87,15cf81f9,3815b32d,6c47879c,c831c549,5a17749c,80003838), +S(6f4bcc03,ed655fbc,be383009,5fa5a1d3,3d4be203,9380ada7,d53e1ba,248ff68f,91e8f700,44126d04,ac2cb1ca,7650a287,e77b2a9,8cc22e9a,b36b4906,5d03b8c5), +S(66b32a92,23945f66,ba2f7934,43f5e31c,8d0bb858,3fdf9db,6d1861e1,fba5e0ec,74d81838,3c0aa55a,16242a41,3ed5f9e7,6569d041,e668d82d,ff90f6b2,aaa9b9ca), +S(c1acd55e,cc4b6743,3aeb6a4a,6a920dc4,626a4219,d70cec1a,1fa4ad6,87696330,6b14fa02,11b63493,ccaa9c6f,e2c288b5,55a4b851,d6a20682,d7aa7039,6c21b156), +S(2bb86341,deda561c,99dd59b2,dd2392e1,4a5cfbb8,9fd49d9b,a35634dc,3274bc61,3662d431,b4403678,a9d59758,dbb413b4,6b48bccb,f3fc9fba,801fe7fa,8d9da0f7), +S(b94189e1,9fa60eac,7b1eaf49,be80b0f5,511693cb,a0efd3e9,70cc0036,eeaf851b,26ee1cfb,ce3445c3,c217bc5f,5ed12d1c,59367ac1,80b65b91,a52d1d8f,c091c8f5), +S(8cda78cc,fba3d6e7,869ad44d,bb5447cd,718be851,df976c1b,ec65be9d,335ff879,cf2cf6e0,94f20682,505bfc56,8f537acc,b2289003,c87c5cc4,23cfc9a5,f61acf02), +S(eb447748,ca42bb71,71c6183e,6ba0e9,a61360f5,b9b686c9,246295ce,c8dae15e,586d8bb1,4dd7277e,5aefa348,55af5e89,55e56526,df89ba4b,575911e7,59f6cd0d), +S(73beb803,c18a68a3,ee1c945f,6031c646,b08c688,6d5b4999,5641181b,c6ab7b0,5fecd8dd,82e3f515,d7a23cab,26949aee,afb1c1bd,1cdc6853,90f3d081,ffd51157), +S(4c3f9e89,e5cc661a,ed4ac704,f37cac28,42afcf38,2c4d51dc,fcc21761,d87311bf,28547fa6,8c661209,67ba52f1,3a13ce38,33ec41,402cb743,49d82e38,2973f615), +S(3e19b5bc,93c422f0,42a2fccd,1595e7d0,d89a2655,fce95a02,56802460,a3ba5b11,edca8ed3,2758daeb,f2649ad8,80114b84,654c3b72,d7ada177,2b84ea75,ea7079ed), +S(7f4b2fb2,6934a60f,50fb114e,b382e0c3,a432f213,a57124f,6cc23e84,27cfe1fe,d0ac243d,9fa8daa2,90efc550,af03e5c2,59d39ca,de0e8779,d68b5880,c74fc874), +S(daf46145,a53b5aa5,ff26bd5f,e0b1c880,835e04ae,9dc51caa,ab37f168,6e57db0d,6203be50,dc56e59f,adee0012,d1c8f24e,afb8caba,88dbc814,f6c127f9,efbf956c), +S(2b339287,f9760403,6bf7d2a,5dec5ac0,6ed9d23d,c2557b4,f853ecf7,70131ad1,6cfe12b6,fbfad32e,b7b100fb,7abcb7e8,cd990d72,d5e7d10,97ad8a45,bf056c1f), +S(2b42fe3d,6a44b1d6,8077ffd8,d3eb700,96afb615,f70af414,48ba4e88,32791e4f,1a8db3b8,50293439,9d31a512,9272096f,6e913775,ae89656f,da79c425,90ec01aa), +S(36c5c074,76246100,bea82171,713bdf41,3d8ef2b9,5ed50fe0,390a93f7,7756614a,53842c42,37723b9d,24cb4666,9f587f68,fb14601b,f4d7b05f,24f9533,2b6d41ae), +S(6c82d0ad,ccee854e,b8ccf077,4917a92a,4c8f4f1d,da784312,2f317ebf,8e8662bf,be05113c,2fba79a4,14442305,f8773526,3b909e30,95a51853,4f76a666,7be28f3c), +S(5019f59b,48e6cd5b,bb394dcb,3b8798fa,bf13bde6,20916ea3,ee9fb32a,53eb2503,4b2e655e,9a09615,7d64ddba,49d9b337,a84b6b1a,707d8896,93211e51,6829a07), +S(301d16ee,7f980c8f,98056bb0,6ac49906,f2f5f404,f36f4f7a,e1b93d47,6e6640b8,d73660bb,d9bbb41b,8f0cc43d,d203ca79,2f07d10a,a60904e4,8d2e3905,e207ecbd), +S(23078318,53146a67,7e03cade,15e9cb41,d3f516c9,4762abc,8a6d7722,1f5557ba,bd7df729,10f0a43b,74a27c80,5bf3dad4,7751af23,9810d9aa,3f4ebbb5,773732b0), +S(2b91a10c,bc666ed3,e7449d2,bda7793c,d6ddc1e0,59c90e19,b85b80f0,50e2a21f,a9b18e39,5154dce9,d6da961d,dea00c40,c58a9cbb,20d9829e,ed4f246d,e7a4af15), +S(73f25213,23e97715,c726b678,cd8374e2,fa7fa140,ec0f9de4,ca25ca02,277bbb65,8b1ec6ee,85ae17e8,da8f6984,c6d6f2df,fa7d2fd9,440904cb,449c227f,b3bd13f0), +S(b8971801,ac6925f,374a5901,2b19e8f9,f2279479,70d070d2,4e097e04,35b4d196,7329d3f0,23a5d418,68e576f0,39b7ed39,8e0fe209,25f098d9,ffa1c45c,8c805fd4), +S(15a6be8,52035719,da9d99e7,9971035d,bcbcf637,d73a37b0,ed8a0113,7500f8f0,3512f517,b5d07551,2f1e91b5,79ceb942,2b807bd2,6be8c336,c124057c,8f204957), +S(6a814e7,c5267f8,182b46aa,a657ccd7,508a468a,dbd9a8a8,b7ce315,2fc672a5,87013b76,ac1d422c,41c8413e,884feb4,bcb29c4e,4639f65b,1962eec3,25ca0d1b), +S(d5ac8a12,2c4e2e37,4145aa10,d5309658,d5d8dff5,7a246d8f,59a4ffd6,43a48d23,683710d6,6ee30017,a07ad2f9,8c12110d,f794c8b4,d92a89c5,6b509470,ddc737cc), +S(9b2c7eef,f744c46b,6e080539,6abb4dfd,6309458,d65185dd,d72a3c2e,ed301b,866a08de,d9d8598,c90fe692,f195d40e,e7a294bd,13f113be,b32323b9,edb35354), +S(a1d0ca41,dd26772b,303085ea,6514331c,57dbac2d,f7129d3c,94a14b56,64dbd1b1,828b9dae,dba3a32c,e72dce2e,e57cba96,7b3a8001,dcf4694f,4e936cfb,2d195c9a), +S(d775ef1e,c3e03ea0,be8852d5,50d30e2,651f2b6c,1b88cce5,8726d66f,e0f73334,2abd706e,acb8e68b,3a3b096b,4517912c,61fffc4f,8bd6c0af,2ba7affe,f3446c8a), +S(6c4b9a00,8c0cd988,e518536e,6dba0027,60e43d4f,e26e7a00,632db70b,e7701742,79d51a,905d04f5,75067ed4,8b22de92,3c25c98a,f14d2955,dce9021b,9aa9950f), +S(39af331,36455357,e7b4a48e,d74e5b0e,182363c9,aac8ff12,545e7cd4,7af66101,e66eec81,736f055f,7325521f,e349d4e4,3faabfb9,c73f7bf8,7c9a791b,1635f16a), +S(ecd4f3e5,36ec00aa,8b4dcd7a,997cb470,6fc83e55,8635c241,5c03807d,16f6916,479006dc,de668a08,fc4d3bb4,628c8b23,6deaad8e,9f75e99a,93e464db,4bd96a8), +S(d26fe1cf,b13ba752,d76d09d0,1ea6204c,8e90baa3,79ece72b,80e6f7a9,282348b5,db4d5f6b,c63ebd68,44735571,a0f43d81,df9d5661,471a1050,11cf4801,b182d80a), +S(6d00c0ca,7c94bbfb,dcc30c47,1f5622e1,afa13179,8b0fef54,3adb02cb,296faab3,7705f197,bca702e1,3ae1eb4b,ff6d8ad2,80c43085,ae5bc7f7,12fa75a7,aa65e6e4), +S(5a77b624,b3949a1b,16587011,cf9b251f,90428c1b,6f5a371d,f2499c28,92c94982,928036ba,b113a731,65760dc5,70562398,f23d1a53,126ded37,6370178d,37ea3db1), +S(e92f3c46,b854d695,455035b4,fae2d3ff,83ad6f62,5fe9e8f9,fa9f3266,898d063f,9ddd806c,683cdd2b,430677fe,89a7a603,75fa8923,bf72c196,cd0ead02,e1d9fc8f), +S(c9d99f0,47ecc29b,5892fe3a,9a285f23,eb7ea82c,e7ffbe2,2f0596df,14c2f8ef,64c0ead2,269f8833,a7a16d8e,d0c3acc1,56309197,9685467c,f4b47420,1b6e74c8), +S(85359be0,9d8cdce,de34edea,1ae82ecb,51af02ac,8294ac59,868b7972,c114398c,6e6e163,3b8101cd,5d3b4264,26a05f69,3aac26ee,c5da1d7e,75944fcf,710b15ff), +S(a1fb58fd,d1283e1f,86026dfa,4e29ff12,da8d9c7f,d6e75e9,6fb31706,8c9f34ec,9429b8af,a89a0031,ead59b83,a9796219,aa8ecbd0,a7875b79,c9fbdddb,85f1a3bd), +S(8ac4d467,6390b97d,488f7943,5e68c47b,eb7c6cda,f920cfc9,dcd6faa9,593e1185,5cde9d0f,3fd47f0a,65b9d7ad,c415872b,f860e1c4,74471b6,c57d464b,9395ead9), +S(1e1cdc12,96067717,2b3776e1,d61a872d,a65c6a99,33596409,99ac16b8,f836237c,f9fae2b3,49d8e6ca,57911ffa,ba411fc0,f80f45c3,a8ff0bd,ac0d6dfd,1b4fe271), +S(b96841f0,b49538fa,7d14c6c0,2cf08242,d6d21ea7,333ad720,9a0f6156,67f6feb2,fef3827,23554c52,6fc37f41,7baed824,17f163b6,e855af0,51e81cde,bf8a32dd), +S(b42499ab,a8a83591,3be09ac,504c6c47,3214f31e,fbab7573,67936d9e,216fd0f6,a2f6a202,e1a97f1c,cf083e26,c84ee6d,7d57cee2,266246b3,c4b6b56c,5f4d613b), +S(418c2e28,7875dd00,6c5760a1,1c72ec31,f267677,7d27a4f3,fc03cfd6,803d85dd,5e727ed1,a2180e35,4bcfed5b,65eb44d4,f045d3d9,ede9fb67,beba53d3,cf8c9ef7), +S(1aa9e157,cd261a2d,c4a00e7b,d119968f,5bff1084,4cb9c835,62b7218a,3d484fe3,d13b9646,a6f1edb3,777a526f,a48353b4,eb06031e,1a2327cc,99be4b06,836a3bb8), +S(2e865670,19aaaf33,c7833174,333e3f9a,bdd63c7e,d25f0af7,49f2d7f7,a69bf7e7,69da2079,a30f2791,8966aae3,b3b9f8e5,fc150b3e,e71616c7,ca845174,36ee5c24), +S(ef7a8374,943df2f7,5ed67507,df3c1a2f,abe2042f,d66e97f9,4f6e3490,1dba9ce2,6b93d053,481b8395,c77dc3a0,6abb3125,7951ad9d,d9d76190,1e218bee,8bb6b4c7), +S(2d097904,179b400c,165cd596,f57919d2,2d7b0535,8018d528,aad0d3,23583478,9f9a0ecd,6976d6a1,6936816d,95283e18,3e94cfd8,9f384bc8,3573e695,35e15380), +S(35b46f8e,231424a2,314effda,3b610f4,5fcf33cb,799b5db1,6389b880,93ab66eb,5e97fbab,a0b89500,d9dd3e4,2cb68439,ec7eda2d,f1a5d6be,24186be3,212f8648), +S(eaa55e55,c4e410b7,2e599063,f4cc976e,754c43ab,a0df3bae,825a4563,fbd27711,13966980,3ba07091,faaa131,71437472,67a75d15,3f5611db,91d4f27a,80aa6975), +S(310c9ee9,ead99f8b,fe9c711,f93357a,e2639181,176d4a6e,4ac84cb2,2a52d6e8,300e5486,deb90657,dbe417cd,6aae423f,bfb00e5b,b3077fef,b6b8a166,10fbd172), +S(de1383d6,2eb93ae9,81f87d12,7811be58,fc373b38,893f0e7,6a417a82,95b27bef,f86aaacf,8704cab3,f0715f93,3eccc9e8,203396e0,636a55fb,ecf76440,7a2ecbd), +S(f5bfa7a0,28beeef3,1fbd817e,5ef6727d,5b81e76f,179fcae9,f271960a,51eb954f,ec3fc89b,ded5bac4,72d79d7b,19db43fa,ade10bb3,cc43d38c,f38efb3,f9ae9f66), +S(5e67e65,80b858fd,df24ecbe,f0f3100f,4378ffb0,7e382ff,f4761ce9,226d29e7,870a1da5,663f1be1,4cd642fa,d7eae191,d50fc6cc,1146882b,5b6eeec4,f1e80123), +S(68cf070b,60e1778d,7c9a2f66,b6abe3fe,23c2e090,f4c59618,a37eebb8,e7108ea,f09cd61,f52305c8,803a2346,65f76a14,49d2fc53,8a4122cf,8462ec5f,b64652bf), +S(427d23db,3ff49c5f,8e693ed8,d88a9ae6,339105cb,cbe2195b,13f39e46,172abe8e,25f4ab41,24ce76a6,a59cd840,de87daa7,be30fe64,59829f80,2caff723,efab49fd), +S(18c3c0e9,810d5353,7963dea1,820a41ab,3f662b0e,ad0fd5e0,8b07806c,e3bc1110,da91ee74,69e89a86,eb9d4ba5,558d9f77,d3c41201,e0db692b,8f7cb583,da4b41dd), +S(f16661c4,dc6130ec,79c47737,3794193f,7538ca5f,2560ab19,23929a75,ce4a74ca,a225ddd0,d3c3fe76,adb89df3,9987d46e,4b404343,6cb457d6,c3a13583,3b41e05a), +S(e467d2da,4ff404f0,5a1fcab6,631ff889,b8f5809d,64328225,7c228589,cab00ccb,86c1f60,ef5aa2a9,5b262e4c,d539a3cc,6839d704,f20938dd,7b93f958,9f461645), +S(ec69c75,520581c6,4cca16db,acbed064,20df5851,b3b13bcf,299aa02e,4473dc92,7742d8f3,96aeec3c,b27d066a,fb640236,ba38722d,e1ee4d2f,d0c9d810,3dd14d85), +S(21c0f26f,1e5a08e1,3db7581b,86fc8869,f7db1689,c1137223,7305f875,65d3c5db,e799f72e,24aa785e,13de622f,224af49f,ba408dbc,22a935c3,2e3909b1,2da7d775), +S(a49694e1,2feea444,ae028e73,e7c56924,7ae4c7e4,fd7cda34,425aa039,c4c13378,de760a14,58c508ba,f8889c90,35478a55,a8ffdfbb,4ae61802,a364832b,5735b599), +S(1c49af88,e3dfe13c,69e470d5,d8680b17,b2f3094,6e94a5e9,5de05936,d556eb71,3466dec,96cdc49,54957fd0,3bc9376e,7b53b222,ae5f5765,a6645110,c04e8f05), +S(e445bedf,aa503c85,c98cc507,86724a03,d6bda967,ded1752a,3b688844,485c0829,2eb37e04,25589c02,a1531e24,ac1c2df3,497cc81e,3ae51641,cd57db8c,f70f2ae4), +S(1fe3fa90,70496133,c6ebf718,8a076453,91c67d39,6d88f09c,a8244c62,242b494a,35a8b8f1,20503992,20568f9a,c5d0d90d,4a5d1d3c,b9a7c2ea,a17561d8,8d40e61a), +S(658dd6fa,63d1df2d,c9d4045f,c9726e55,2eef2721,90c3c437,29f4a01e,4b775b43,442b482,b77df6c,727f58fb,51331d0c,7604f8c,3da01b77,40f71ba2,f6219bde), +S(57441b8a,6787c3d9,b87b58dc,a66da1e5,32a8e8a,267f8961,fd1fbe3,3859fae0,fb065a85,9675effd,307fba28,226f1276,95f6ee27,389b6959,ea9ef704,ac460e9), +S(432449e2,51582cb8,ac8d232b,901d4796,63198f92,43c1ac42,f66aadfc,a79ece53,d5496156,87c64c16,c2bbf07d,c94e754d,af680ea9,47beb11c,94394c11,a27454af), +S(90db95a2,b17842d5,37c4aeb,42aba933,be6a9cc2,fb23b9,457e35,c2e6a77c,8e10ba44,21a6d262,a4129852,d6f1eab7,2e885bc7,1ccc8b5e,9023e504,2bd751ff), +S(9a7c6aca,93149860,cf4bdb29,fc8dfc1b,84d30bfa,13728f67,ef3bc6b8,1492fdd8,48beecaf,c66ab57f,9e5aa39e,76887725,3ca4a8a9,b464df58,3d86e8a8,f8b126ed), +S(926c02c8,cc70f343,9522fc18,29308f6a,3a1d513b,f632d3a4,cc56f7fd,259de58,229378b2,6e0f48b,de2b0bd9,8364599a,bbd011b9,918e1e55,cd7a0bae,a8cccf2f), +S(264bd086,5bd54674,11b22adc,f02653fb,d483fdac,1682a210,54aa810,9c9cfbb1,75032c4f,a101f117,a042bfbd,5b0fcd3a,3991875a,d3444ca8,5688e3d2,1d2df64d), +S(a2ef67f6,ffacb94b,9f28432,f27bf1b5,ced82580,8c46465a,69e57f01,c070bc1d,2ea53f94,5c1227c7,5eab61e9,a508cbd8,7730d9ae,73831322,80eb90ee,609130e7), +S(940733b7,46fa83a5,4acddd6a,76ed1e31,80daf833,7e014783,93641ce0,3c9a3657,c5a9ddcf,b2202a32,34f736fc,996cb301,9bfea0b0,21988946,8112f5e4,7abe6a11), +S(95e6b0a,eb191afb,10eb0ce8,bcc7c14f,5990a9c,c63da64c,c7bce7ae,1a0d9b48,80698f50,f7ac67c5,4d55911b,cc88d764,83df654e,9873c039,d854d7ae,14a92980), +S(edf7e7dd,e79ad130,1b7c8d7f,ad000004,298a799c,7d08cd94,38b0fecb,cbf5df2c,ae1c98c4,1a7b068,57786d39,169ebf92,ecd60d85,795fe484,707970b5,e7c33fad), +S(f6f75f2b,c0fe2cb7,8be2ef4d,e728e06b,e17f6350,4267de70,1a9dea54,736b804f,11d046f4,efbfef4e,9029f632,e1603dc1,196b710a,32173f07,94dad87c,f8095c84), +S(185ae081,d470ff62,7e73bbdd,3a7fc5d1,df1eb46,733fda26,8e4001ec,fd7b7b94,cf57835c,3a69e46a,5a58ec1a,2c0ff80f,4d8020c4,eef5e1d6,dca1e260,4b2e22de), +S(a93647b6,1342281a,7fa5a92a,48c3379c,4e8fd29d,2113c07a,792e1d75,ec4abde4,b2260a18,e6a05f66,998c3aec,201ea4c1,545ccc98,606d35df,cd671d7e,5b53fc9c), +S(27028628,171d1083,7d713e7,8011a818,81125514,dab8eaf6,846595c,d99cb5e7,99b0fa18,eccaa210,29e5437e,6d561f2c,a5174f49,42ea2f3,b640ceb1,50ceb025), +S(d560c4ed,f442947e,5a99d3,f2f8e519,b61f5243,322aa725,a3a68249,50318281,f403247b,70998349,d5eb3d38,1041616a,ad8697c,6a06643f,8d3b786e,707f12de), +S(b54c07da,a18196e8,33173c51,68d5cf7a,1cde555c,80621501,bfae82bd,2043406e,ee83b25e,300e532c,b09ed563,5b1e1a80,48fcea5c,5b41ed38,97cd2c32,8846b3a7), +S(5e43b2c2,8365005a,fb52b971,ac372448,22ed45b0,9cb6d829,f18fa481,91a5780c,6b3d5dd,951ff60e,4533f783,aab0276f,aab00898,4a4899f4,a31a00fa,a34bc760), +S(3a62aa88,99bf76bc,a23b39dc,d6008d4f,a57e9b1e,3bb69a90,88b77407,49b3ce9e,d83de010,f65c8320,810f7079,8de4f3c9,6e293792,841e7178,d894ff76,135c0951), +S(69ccd9df,9cfe0990,440ff050,7a35ac47,6a0ba786,56c775e2,7677bf59,e5c37594,73a97d37,48f1c24b,6d5c814a,a5829f0c,8589212f,485ffe5d,d86d9868,14bb537a), +S(9b2e9201,51d8b063,95823db7,83e33a7e,e35c092d,265eb440,bcd0a6f9,c9f89c5c,ab125c05,dd565f17,93033058,cc0a0ad1,f6b32ad2,90d129e1,6032c781,ffc2e331), +S(9af6ad84,535f84d9,4d80a592,943c83f8,76360fd4,787ea16,c6f6df4c,b9d92eff,a443e538,895046c2,9cb80270,7777ef63,ee18acb0,fa028a16,d7be8bfa,c0b4e5d0), +S(e7fc44df,cf4eda5e,c982a8a3,1a72d69b,b2b39f83,3dc4e621,bb002fde,2277f4b1,64fa8e8c,f2194013,8caccbe9,8808a47b,bda56376,d9b02ce3,33e36558,365637b4), +S(c820365a,3c6cbff7,273c80b3,f7ae7278,f6f4e282,dca68586,1fd23693,a0dbeaf,adac7864,cca90280,13bb3a68,c3d235d0,dfb3b99f,749b9203,9b03068f,f229310c), +S(3f97b6b9,235afad6,a4cf1eb3,dd3be029,7d67625,ec18972d,62ae4b2,a1b0de3c,a652fa0c,7fc89c54,e11df8e9,7650fae1,7cd51674,dc44be18,26e70b90,12089f2c), +S(74f315a4,d12dba88,1ef5b14,14bea596,ec386f5d,5f6e1dd2,f5e777b,c8c3370f,fc994b03,bd5a0461,9ce52114,4915b7e4,f9380a77,8a15407c,9b8a96d9,e7999c0f), +S(db546b02,795e2435,e8e6ede,3a45fc8a,1cbf311f,d0d9784d,dcd956d4,79d37b40,f16a6c,ab9dfb8f,1374440,86f1e513,79e54030,db4153b2,d2c06602,302ca383), +S(e1ce9f95,c8764028,b707f2bb,ef2b4d0c,88adeb47,f0469924,e2659195,6a53183d,358014fd,987f41cc,8f31856d,25a509f9,d406a68e,82a68fdf,1e1d4afb,99de59d7), +S(38f1e3,e35f77d,76cd5847,9b9b2c92,e90bbb3,d8793cec,509b29cc,c0fe13ed,faaa8e0a,a9a943a2,a5bf0e7f,a2a95079,ead33f72,8e1a3547,e55c6d63,3e908264), +S(143da00,da92138a,609b62da,8e90c19a,44b89be6,3372913,fc8cda65,44740ed7,2d042699,25782d78,8f6d8f4e,7dc63ca,570fb79c,ac2e5691,65a8df5b,38089686), +S(93819e60,23aa61d3,f015f747,d74ff5ce,d3437f2d,9c25d9a4,dd5ee0d,e4bb413b,3496f668,113975c2,4cee563d,5a5fe406,5e68b1d9,afc95e8e,2ebc949b,5779955e), +S(247bdc8f,abbe756b,a35c9f77,2c00836a,51cd8c5a,d2182e56,81f4f79b,2c0fbfd4,39dee166,712fab57,95edba10,8ac84b0,3ac90b43,7e22290f,91f0899,7ac3233), +S(282c681a,c67c8ec0,7c399e8e,a3198c41,a7993d37,b9bc4042,b0226d45,353034ad,8d5fcf2a,d66a9266,788d77f5,5fe4830c,6025c26f,e9468d95,3271d2a5,61634ba0), +S(e0e0229c,b260bfc1,a5979371,5bc7d226,eb9a8989,89edb9cc,5012a2d6,c05657f9,5321fb39,ca241eb2,94c69885,502d8d25,b85e414e,f540b713,e9fdbdde,ec0f50b1), +S(b8e62275,85d52f64,88a76515,e8c62894,7b9b01fa,1a7bcbea,9124dae7,b8a05447,84a564db,e14aa687,4cabdb11,7ccc7e20,706a7a54,c4c23689,4660ea5b,6d0a189), +S(77f3be41,2e08ecdb,b8443431,8e71c69,e6613ec9,bb2ec577,40cf944a,a3e12abe,39b45913,a90e014f,ffae3a15,a3bf44b8,7ac121b9,fadacbe7,19af320b,b9d35124), +S(350833c6,8ceebf3f,b0e5d4a1,749838f8,c60a673b,a7015eac,dd1050f8,eef646c8,ae37f219,cae837b0,bdfd2899,2625868f,3906564a,70ee0b90,92f2b24a,a2631de1), +S(2ee6a70,4c8083c5,3f88dc2a,aa39258f,2833d3f3,600b1a4f,61101e44,bed8d5f,589a8a8a,d8e32dd1,c7e54ad,d2b6952d,62017da2,5e68dda6,aedc696c,77b4dfa6), +S(156af2de,75e81831,2e6eabff,ffb82dc8,b5fc207,4fdd6341,b98597da,b22a6473,dfd13542,36d0407a,e0659ccc,b7eaa304,10bb4afe,4afb4221,4e70909,15d4fb18), +S(396d53f,5a488086,9be37006,e07a4638,496ad4cc,80c7554e,3f4b4939,5ba18d38,a7a6d320,39f05345,f41e2792,77bcefbe,10983280,f56c17bb,943c253d,7c094b0c), +S(15407e62,684b2d9e,4a8f08b2,31010bc,fe42c9e5,f85378f8,904e649,a759c7c0,54ab28eb,1b91562,ad8551f,47f41c96,2516fac3,3af933a0,75c757cc,e381d3dd), +S(80fbd75b,1538f0bb,96f29ebb,3c50682f,de0cd2e,e9615f1a,4b8c1b76,3b2090fa,cc3613a6,8608dc75,97870658,3d478a33,21c3677f,516cf6f0,6fdfc253,3bc0946a), +S(c795f08f,f5458042,f6268079,36fdf08,bda3ab0e,5281fc3c,447df53f,25aecc93,1524dee6,b98b74b6,616509cb,77a2a5da,2871b1cc,78a7b217,3185c187,223b88e5), +S(1c39286d,1aca3eb8,36bd90d4,e46ade42,ba8c0b1e,43523499,ab151e3d,7b331e6b,4f81e790,e66df7af,b4725dac,b506bb73,4c299afd,21dbbfb0,a60055c7,ebf119fb), +S(e778e362,f5f67d32,73c861ab,3cbafbc9,eb03f7c5,e862b5a9,2b7a51fe,26daee5c,1035cc76,9df9e120,7a71a13d,37693edc,19fd6ee9,33fae651,a145cc60,37ccc1dc), +S(d71b5cc5,56ba74aa,a0ab5775,cf0acdee,54e5c48e,5cb08734,6e510e1b,18f9a914,f3c3419e,84b4cf22,31975aac,e31b9b36,9aeb4a3e,e2b2bc6f,feffc3fb,538e8e5), +S(819e3ba3,6f5b1011,64f3e798,764e01af,5838ecd,e6141690,971e562d,a99d0520,da38a00a,838d85cc,f606c440,b941f128,a66b0216,544008b7,a4904094,7d7557c), +S(3c726a07,740912b5,560bca0f,f8d827fc,a9f2b1f7,1596f922,218a95e5,db2c7048,b9e52f48,ee2d0944,3c5c5776,eef02a78,47cdf47c,b83316b2,220fbf00,4b3d72a5), +S(e2b550e7,189f0fcf,a897fe12,245d6912,e6743828,b0ab0d78,9faf3865,d90d1d1,11dbf946,3cefe572,f45a5288,55c2a257,43dbd70c,3db6d012,34821a0b,35ffb115), +S(4cd65ffc,23acbe0d,59471667,44ca1194,f52dfee9,ba532725,508eff79,61130fe9,9af3c41,97fa257d,79fcbe93,145fefb7,96bfb0a0,3914ade3,c1127b41,9e321a28), +S(6fc537e5,4f7bf705,bc4a7a1e,a7cd365e,ec36f190,dd4fc7c1,ec8f5f3c,8dc63c21,d06a12b9,ccf770cc,f8504b97,ae68c61b,1872d500,54db9cfd,76a55c29,58eeff4f), +S(33bdc335,cd76ec99,db66b3f4,d90ad5a7,924f343d,836edcbd,847350a2,10366223,2761ca74,ae8bd215,b74fd37d,9d6527c2,c10406db,fc5932e9,d408c2e0,ef554987), +S(a4ac1b95,e9a8ce4d,da11a1b5,c21401b8,b92d9bc5,f7bbcfda,3b1940cb,cc331dd7,8f630ccf,30f68759,174b4052,8082050,599c29b2,4922c1fc,e4a5952,61c2e239), +S(6f34af2c,86f06702,4f720e5f,89d45fae,f44a8976,2b0bb390,e9a7ee72,fdf07842,785c4f09,d127954d,d6e6dff7,e342bd1f,5540448f,ca390d72,485b2967,b6ef1825), +S(37ef099,8571efbe,bbfc5350,43d0fcf5,758d78cc,3ebf247a,cc7b4f59,480aae80,29a3b2eb,fc41f793,66bbee1a,cc6fffba,76d37631,f10136ea,4a47a18a,d9263c78), +S(3d815c75,6c6d730c,b3d7ca6,de486159,f0035011,851211c8,25bd59f3,624b9056,56e109c3,e6ad3198,48b2e00d,1168806a,f0a22c93,81d8a243,53850c4c,1c486cc1), +S(d3143ac9,845ed52e,961b9fca,faecd1a,ec6e8554,c90357e,ba2317c0,c832730a,f4276188,6db140b,4d9b8b96,1e6555ea,a80dfebc,8d37ddb3,a21e284f,50b1dc73), +S(5b0066c9,221d1b8a,3bf660d3,ef28c3a6,8c611dcf,943824bd,ba4f2a8f,836b03c1,86a24204,f40de381,21be77db,a23a6e3f,5c8ea5eb,7138d218,45d8003,cc8460d8), +S(62461176,e6bc9c4c,77f8636c,3ffcdf24,45ff5c98,935e4b76,1c4e50fe,c00b606d,5431f12e,488bcede,ac9822e9,5797c2c4,5a49167f,6989a6cb,601ed3c2,860c28a3), +S(8efe7f7f,482ab457,4a7e56b7,77a7b5ff,dad6e208,2261b9d6,bfd6c647,c88a757e,ef5e2083,ceaebbb8,aeafa383,d188f30c,7350f484,eec83262,8d9fbabc,522b072f), +S(4dd8e450,5ccb49bc,2ffacdeb,53bad1e0,362df309,5756505b,33eceb64,34ebe715,9f801ac4,243d720c,eab5def4,7a7e6d6e,a051d3b9,783a2b80,aacf087b,b575b58a), +S(3a345a97,85c7db9c,b5661c97,3c739949,c48253c7,bc36ee32,d4d74878,3b0cb734,4bb7a957,d4c8a2c8,e1229e1c,d29af780,ba844bdd,a0251134,5da7fd4d,30223818), +S(d76335f,3e14a6d8,b8d6a87c,7f8d96bf,ee171c24,276feddc,a52f17ec,74cd3ed6,dc2d6c21,590edeb3,a9014b24,fb8a6ffe,e99c0f0b,d8fad1b5,2175f647,d5be53ba), +S(25fb12e6,2e05fa71,57badcc2,ed5c53a0,89a55b1f,4f5b508,f89fee83,b309727d,c73cc2fc,4021d267,7821ac82,f5803218,d4ebb736,6fb22f98,62a98f9d,6e597928), +S(6ec69e2,970df6a6,52e50e1c,2682e39,66e60120,6ac7fd61,12dd1446,47a11783,e9d08d09,1148b329,6a8c7b7,f9e4588,8fdb1179,72e08c56,41908b1d,127b7a87), +S(f72d2f36,35701d5a,a19309f0,12d8c5a3,7ae0784f,699a200a,bca89cad,57b08db6,5081bc4b,16c53997,46f2a35d,e7d59b53,8956b57b,865a99dc,e8bd86b0,259888c8), +S(945fab90,e970531b,766f939a,8c1a5cc3,c43a5c7d,45b96983,ade1d042,13d2e46,d76f827c,1eb775ec,7d5946cc,aab05b62,97173b32,54407669,4bf194c7,c84e612b), +S(fc60b8e4,129df265,9c335842,a099edd6,182acfa5,b74110e7,7880281c,4f582b77,69cc15a6,11c54e60,72db1bc9,9af6d289,f647aa85,95006a83,8b3a91a9,da33557b), +S(a4e41222,f9643671,390a7213,e6d0f5c4,9722d41a,9d0102fd,818f4aa1,6e03f5ec,c1636af0,55a67855,fc6a1827,c9e3e463,88922c7,c769357b,4f4fc4b5,3af2307c), +S(b1749fc4,8c935c8f,f2dbb7a7,2a69524c,83a7d551,88b48ef2,30f0306,a156a002,43efe91d,ee498afb,4f47a4d6,51ce132f,fe1fe875,da143682,c56d936b,dd7dd80f), +S(407b881,6141cf62,b8c87b3c,439290f5,6be1c590,41c847f1,f127c8c,c4b913e0,c3c90c06,afc5bbdd,7c699eca,5ae24594,69735dd9,71bd6b0,e48db6bd,6b77bd8c), +S(b0054fcb,94060a29,f983b713,79ec998e,34e39d5b,c5e0c271,ef48ac4a,e12b3a18,e2b89e84,5aa2f8cd,8ff2d240,72c0491a,81be7ad6,1e8166e5,6619e928,7d37c2fa), +S(4c202cef,fd6b69f2,33efb265,77e327a6,b47e722b,1b8b6477,2372f4fe,7559e5a,1a04446b,e69535eb,3f10d334,38049fbe,e0374b53,54f2f46b,5cc1de16,59c3e726), +S(451ea6f7,c1e9992e,b50c5ee2,90784052,a9974a8a,101da027,753575d5,1f306ef6,ec8cca1e,a21e21b2,cd0fb48e,dd14609f,733b32e5,42cd1c,a1ef2acc,6396cb81), +S(1ae254d6,686a8a2f,135fd775,16de17da,5175a82,aa8599ce,45b1660c,b5f65d78,a2595603,71a24698,626cfd82,7efe6d46,d8c4e31e,1765ca1c,e01ef584,4a5780a8), +S(d358e246,514e986,b0b8a192,53e07db5,5a635c01,85d7f39c,666064ca,cff640ac,d4b34eb9,30620b9f,eb1f94ab,8f88f3c8,8d8a9a5f,4ff35528,df0266f7,d4481c2), +S(fd4af649,5415092b,e61abb8b,ea2827e,3e833f5b,4653a1fe,7e9886bb,ae454b54,9743ed9d,d30ef4ef,31ff9df4,e5d10272,1e5c7609,b539630b,ab555559,88b56965), +S(4286c7fb,d1b785d5,a778f72e,2574bbc4,2912abdd,ebd9f6ba,15bc6c23,c7700cd8,3b0c1d36,2f62cf4d,f5dfdd78,1414fe1a,64a5526,cd36cbed,8e41c740,56525e71), +S(2262acdb,7dce598,ec0b2419,2d761dad,8b413bb2,58444c1c,bebd1693,a1ed597d,c6bde565,87f6e506,4882d86a,6eaf0314,20107b26,9b57dce,e9ba48f4,d9a220ca), +S(b8eba19b,a6057f98,519c319b,cd3566db,8a4a53c2,f3d825fd,9646dae7,13fe7b5c,7bc344ca,fff215eb,cc8f42f6,6b711406,7a00e881,f7e40ae7,253fbba3,bfab8273), +S(d49b8d30,2d8a1c2,ea6e8302,33ec1fe,371cf035,57c2c45f,d0148df3,1a43b11f,6f1052e1,18fd6180,1694b106,8e1d8cea,f72b3e68,ba84d0e8,ad945fb5,156dba1c), +S(56db7750,350da2a5,c6a73239,13f987de,9b4ba04c,9f0c0fa4,67d53abe,129116a3,e4dc5c13,9b72462c,bc5b5200,68d27c73,9599b40,d17c8581,1caa69fe,3a429fa3), +S(1c987244,7d133050,8368960e,7f63a52c,ae56a840,cd19a359,d8e94720,b3f4d54e,9d8d1dab,8efaf90e,f2bbee51,b0e9d369,abc06979,48bdc1d6,efd1c18b,26dd0ec4), +S(e9bfca61,b09d2298,3f1657f1,f303e0ed,f9650830,c3151ccc,eb7cce77,7865568b,6c06c996,48a3a164,a57dadbb,304d9d29,75906d64,89e42292,63d4a86f,b4a82642), +S(52f86eba,9c3ed139,83704865,ad0ec3bb,e54dd2b5,5841fe8b,826da573,213dac7b,59bccd99,a53fb65f,1df73e8f,eb8f4734,67f1d4b2,715745e8,693589b8,d1f24d9c), +S(ac02234a,412dff76,e01f6ff4,a3bab5b5,ff3339a0,4ff3fc70,eac1bdd,f0eb88f3,768d7219,782584c8,e16818a9,f8ce5aa8,18228c2,21a7dfa1,6e9da56a,61227843), +S(c2e5044,2dc773a4,d0c3d1de,d9883be,dcc01c32,c83b2a51,3e946212,8551336c,30063e65,133d1c40,607c2cb1,50f680ac,43195e5a,8ab68add,5ace3977,4242b689), +S(fa02cdca,e19fc987,a7c43acc,77328914,741ac5a0,e150e9bb,cc6aa0ed,9c16287d,ad7e7b78,f566a226,99e27510,2a03ddbb,de7a5e57,58fa52a7,f198dedd,7f27f72b), +S(805110bb,99a2b8ce,a8dfa8fb,e4bfa353,ece63c67,22adb161,9c696d2c,5aa66939,aa0e9a9,df1a2a11,72fbdd30,6ec86d84,e04ec973,79e16505,5273bbda,4fae3c8e), +S(6472c6a5,55be3145,476b3cbc,9f1d5459,be137d1c,c4cf7a11,6d28a722,f1b8960c,d28a0da4,2cc3ce06,fa16e4e4,dab04b2b,eb74d8b7,8b09632,1d02ab86,b92b0afe), +S(a659d5db,dbb45d5c,af7a9893,7f82e6c,c37646f0,34411e20,e361d595,28c4fdd4,d064e26d,ac724089,90947031,27256e35,745ca0c9,696da250,adf2df91,1a3a05a3), +S(882a7c39,56bb7ba3,f3d20df7,d0645bd,b13db6e6,2ba58f31,82ce4efe,2a0846dc,627c82c8,82437a35,1ebc003a,4035af13,63de299a,52924337,a4162a0f,c5bb17b8), +S(5556c236,9f7c003,d5fd2451,8c4be1d0,9b11b2e1,8961522,68e5cdcf,a6282db8,384b8cbf,13d9adbb,7a2fce16,38b71729,aa70d754,37dd7427,8cf98135,bcb0f1ae), +S(f268a877,472c9305,e3c2b193,303c29b0,a6fd2ff0,fb1563eb,ec5d39c0,def431b4,5dd08bbf,c1b8cead,9b45f164,e6323f7,c1bf0b33,bd9ad8e5,c553dfa4,cb42a634), +S(fe3438ef,5cdb0229,2c5d392a,387c38bf,87e453e0,596c5546,aa27940c,7686a90c,5b3baa2f,76647870,95c3453,64f59327,415d6aae,9fce79d5,85222afe,8304b998), +S(51216a9e,54a94c50,f2c2ba07,9548a51c,8345dcf3,b38a7e70,1a3de47c,9d5422fb,1046f888,360c5de2,95d63e16,93463bda,e3714f16,46f74ab7,3b6d68b0,15df71ab), +S(326d2470,700341,9ba6438a,b7ba4498,957e919f,f748590a,130857f6,d46386aa,7e31c242,cc2f3ea7,d5579be1,8e216b8d,9f69e360,c03af079,636bc03d,2090b770), +S(cd5abed8,a071a8c2,4d379611,4d81f490,5e644884,82b2e2b8,3eefbd92,a98947b1,f3d6560f,e10eacaa,9a30cde4,ab852b49,3ef0add2,f6d83db3,5d12b0b6,705292f1), +S(4482b5fa,c39560b7,7550b621,238fd8a9,5252e8f6,25fdc8c8,42382845,8d2e27fa,c1d246d2,145041cb,ef8d3fc3,8b5a1237,fe400256,e4d2588c,ee320733,f6884933), +S(1eb303,74179ee6,76a977a8,76ce0ef9,71ca88b6,615f3729,cab3cefc,6080caa4,a9293fd4,a0a156d5,f8f735cd,a60b9ef2,bc6004b9,efcd12f3,a0f5c16b,5524e421), +S(542685da,a08f407,71cc90b8,bce723cf,d2f6e616,133adcef,7908fbb0,ea29a4e9,df4076d8,44a4d3a1,10126bfa,344fb3a7,79f7455a,a9abc99b,7429eeaa,989b5d44), +S(bf631fa4,5277594b,c425882a,85a361c6,d62c50e,aac20ba7,ebaa596d,d6801a54,69995b4d,f20f336f,44681ef6,6a65b54f,88d43953,6458ee9c,f7657389,94e53bf1), +S(27be809c,5bb70530,ee629628,18a4ea73,540f1e6e,75990926,3269a205,604e7b53,a5bf709a,caba50ab,ad939c56,1abbd0b3,fdafaded,3b82d9af,964727dc,bcba7b3b), +S(40126263,3f3af376,4bdd2a6a,c1c6adb6,fee285fe,1171a29e,af4d71c2,5f03b849,2ffbed36,47815c25,5d5bf7d0,a7f09dfa,8eaf79aa,df9e95ae,57024960,ec98fe8c), +S(a634b11,bf441eff,6ae8eee6,dedba52,6377cb96,e3c36a7b,4ebf02de,42146298,57c555ad,85f0e194,2f9701e9,1227e0f7,42763296,2d0702d9,e81e025c,c411d379), +S(d6130997,fa2259f5,bac49b16,38d224ed,f30786ab,c7321e10,d593b932,27745905,ed5a448b,c2157699,b436efe,6725f8b2,8df8282f,1a588692,41ca7db9,6c66821d), +S(4a313361,bed4a94f,b7d9f1de,a1feaa4d,3d957379,cc24d880,92dc29df,5c503d72,2e4e6930,b8e33e50,d166f862,a4f73520,63470e27,f9d9a3ec,3382d252,e42ee20e), +S(6be34d7b,5aff85f0,e731e6bf,285b2f79,eb241c67,df9aa3aa,c2574e5a,d8b146e6,a9ab3f20,dabd0073,5935255,925676f5,799d14d7,75c896c0,de451057,f0112f5), +S(2e42de88,38560214,228691ae,26a0a26d,fd96cee7,9416439a,e771891,3499898,6ff846c2,72393037,a2d0b2c,da38539f,f8d3a6ae,175fb604,55afab50,8454a419), +S(d65d003a,c979da6d,9e4b077,3ee965a2,f33e512c,5c20a9e7,456fd3d9,fb5b0b6b,fcf12ef7,6fd89385,5ade4bc9,4984d7bc,63406649,d4525f1f,3c9f35a2,6b357f0b), +S(f58d02ec,d136eef,67ec91a2,6fc5097b,74c01db1,911c2685,4941f56c,af6b10b8,14169b8f,aa3a5512,55d3eb4d,25ece18f,d802606d,f1259504,64f79587,518561fa), +S(fd13b1c,d189e832,e3c06cf0,6277474c,3e388979,e0a7e925,1799dc9,a9713b9f,a2838fe5,4a07d539,5392dee5,dc2269c5,9fbb222a,8541f3c0,7fb28cd8,1ac2283f), +S(bdfc6941,424ba1ec,88ecff53,c8da31d1,ee6ac442,c8a1e58f,5171f4fe,b808d41f,a0533200,4e7582cd,a824600c,20864fa9,b8286c7f,2107ff82,9b5c964c,dc4a3531), +S(a390ea29,4096bf15,e953986b,86893c37,e2cd18b3,5a0df983,5be6ba2f,8a5769c3,1b432110,1c37b5b3,147029f7,aec437ab,cbe82b5b,559e9446,a2cd4067,9a9b5b9b), +S(40a61a44,a356f623,968e386e,319bee22,574f2f41,f558cc5c,f8a9b6e2,93db0ea0,745b1083,a9e9e080,365f95ab,31db5c6e,9e38c2f9,62bc4e8e,6a879768,f21998fd), +S(2ab87f5e,83538093,e99e09e,468a0056,5db6e308,2bb072bf,b7f5522a,24977f87,49a22c4d,790450fd,f31f8199,1084676e,7cdafbbb,5656e2d4,bd03621,bf50cf68), +S(656e91bb,156468b,821fc9dd,14c3ee76,ea8016c8,92133d2f,189820a5,81a964c,d8d153b6,870c6ce7,a4db4eb9,bc1f75bf,22f6c3ff,74865118,fabfd336,c7ad73), +S(d2c9e2ed,7cf8c21d,8c078e70,73c8ea8c,88e7169c,abea0a44,5c6c339f,82eca7d2,2db2942f,ee70cb15,56fe1d30,d5bc94a2,3d748e0a,7ce8735f,876e9931,90552a5b), +S(a5301947,cc6e0053,7cbd19ad,db91d854,67ab1bac,1a5e9862,bf46ebe9,a2d14710,c36d3b1,d62195a6,18f5bc12,61680ea8,1000f37,86f3ad28,3f516d16,f45e7cb2), +S(1f61d637,80113793,5cbe0dc5,34042617,932efc37,c3a95ea3,57575ca8,7280269d,24dd91ab,4adfa0ed,9369d30b,70a25b1e,df9b4383,37d83464,7fe064c9,e2ba5de4), +S(14efe93,49750c63,81d61000,4b80c733,204afe5d,223ef3b1,e45bcb6b,177c633,d8e284f0,ee2f4826,9c958271,3caf5364,6361294c,a0aacdd,a9aef70e,8fed2bfc)}, +{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), +S(1c000fe,9372bdc3,68d4d6df,832c0396,3701cefa,bee1cdc,3965e183,3476f636,1792668,89cb19bf,39633363,98df43b2,9d2eb378,a9a30531,9d33ec1d,a571eeb8), +S(17688e97,d3dd0dff,1f43ced0,af969ed6,d0b53f3b,22c1f1dd,240f4bbb,253770c4,bdab9644,b7047941,f42ce962,4800d25f,54dd194c,6fc74eeb,2e1e9779,3e4890f1), +S(c9e92b0d,e85dde86,8eac6f6d,1eef4b4a,8b25974e,7b77cb,fc210530,b595cdb4,5aa94a9a,7210e6e2,e04dda5c,8250c8af,16bd5081,f2102f6e,a9d09265,8b4c4ac8), +S(c9efbd02,5f6aaad,e30ec696,e5e6739f,ec6e89dd,9bec22ca,cb2a9142,d7bdd284,f32f9e4e,dbaa0a73,135fc5d7,7d2cdcc5,80c357c3,144bfa1f,e05e70e1,c8888744), +S(25cf39cc,ceff3fac,e9ae5cb,e6e6db7a,586f1fb1,8b3c444e,28cb2d19,ba08ef4e,d3b55fe5,3f11624f,f6c25252,4928226d,a82128f2,4649c140,24fb1f17,c9ba9742), +S(262a25d,36253456,cabab430,5be8500b,e2fcf871,1c580d9a,a76202fe,9e97eb39,873e797,bf2adf55,dbb3b0a5,a2480c30,1395cc6e,477f39d3,520e1a1a,6e61440d), +S(3041bc09,6dbe8a9c,9e436f15,bd88954d,b2e1586,5de92c9e,8f8df7f6,456665cc,f17d1d17,e406001e,1aae6cb1,ce4c8889,4a502e40,1a0f7f04,3f8daf4b,a4ed4345), +S(d0fcb1f3,8d32d3c1,5a0d984c,f9eec4de,22e0f400,b93c0343,337f98c1,db2afa4d,de5133d3,f7920fb1,4d34b28e,5058d81e,e9e312a7,17590c98,aa242e98,92f8356d), +S(65f5da86,cd13e857,f41a7016,9e62e05c,628506ef,d1739ea7,5308b75f,510f247c,5e52e176,38b22cfd,8f1f800b,edcf0af2,1efce458,e179da1a,d046e0f9,5afad4b7), +S(a4ae6a21,f07f51e9,cf635714,e0cd35d1,d31fe32f,22d29ffd,16af4bf4,65c859df,41a69d4c,ff1abc12,8831efe6,e410a22d,80790640,5f319692,46fc3bd5,2589c094), +S(d92d5f09,79a47bb2,e995693a,e005c266,54d6260b,85f41806,89407c47,69b2c5fd,1ab29589,87b2e4be,6ed6eaa,fc47a9e7,49349e9d,1eb438c5,735dfb9e,d77f2e8e), +S(f0f136b0,787e1c0a,e43e3c34,66d77cc3,64282ca3,4b686a23,eb30622e,c50644b6,1fe70372,b3047ab5,242190cc,6fbc18a6,4dc0797,d51b2ace,1eb208cd,30625ebd), +S(52cf110,c8a81a1a,f6ecba15,7b6e2748,9fade773,20b22880,ac023ebb,3ba95119,eeb4e114,2762e0d3,42ed393b,c3b01a2b,e7534b34,c7466f91,224519f6,762da31c), +S(dc1f1041,76019cb9,e5ba446,f1601edc,77ff662d,e69a560e,2795243f,e3635bd8,29fff9f1,d8aedf11,5f518298,4b82186c,1c2b8e9c,8d80bf5d,c0a8b0e,9598700c), +S(dac7cde7,dab3d68d,cdecaf9,3b4a1985,ba099d97,eefb84c1,efd5b103,1559bd5a,53940d9e,785b017f,9142dfb4,4157c250,7a8543e2,c52150ee,8ec1910e,caaa36e9), +S(42500318,5ca69e1b,c4413ba8,ed3949c0,bc39ee8d,10b543d,c4035f57,7f46abca,5c187b2c,936e589f,66ecdee7,dbafbd48,b184a1ba,4ee9bf01,f70327f8,7b80f384), +S(1a8728b1,3cf2ef6b,d122df7f,ae11873a,fdc4aaa5,46981212,616f7a35,73fb94bb,3c6e1732,320fa8fb,7bc908a1,93204afa,aa22e138,571bcf1b,b0b31285,2cb76d21), +S(9963b507,f4fdba39,1312782d,35446a4f,a1247315,29a1894e,cfa86138,22206031,1b7feefe,36616571,f904d548,4673322f,4e867016,b60527a0,f0e4ffe5,97b7021d), +S(5f98a8b,93016cee,48a8bac0,6553c0c9,c3f0af5c,4ff969db,237f5669,ae7c4f12,ef144971,69e32124,d0ce4525,c2ad7857,43a62914,ac21c954,a1f0f6c2,4cc2d091), +S(ff4d4fee,875ebc10,fa6db1ab,19941a6f,b934ef14,6b2f7299,cb7ccd74,5c6be029,10b3dcdb,2a753aa7,e2464ce0,b021eabc,3643134b,9acb6f55,955dc471,8a5bf46c), +S(ff159279,11c229ac,f5f0aa9c,67cb98e6,309d16c4,94a95808,91bdc404,e2a1636d,5ae15340,a7e94020,108e0a07,3e775a92,a7eda92c,ceb6af56,cc91ace,e8991e1f), +S(652bcc4e,a1c2f450,10273043,2cdbf01,3e07aa76,7f5d8d00,a48ff9c0,b97d73f3,de96c171,173cfa8e,66174a45,e8899d12,f5ff50e9,481f6310,8293075d,cf5d524b), +S(8d33a9db,ca44ca87,634d52ab,c325f892,14330c84,d6adf84a,3a2e5ab6,ace8089c,6ac0fb1e,2324dfdf,546dfb42,37a523b4,1d8dd5a,81a6c398,2ff14f6b,c68348e0), +S(b7356428,d0f718a5,a999a4b0,cd55332,b812920b,26b5c5a,babf1afb,3c1ef230,60a1a61f,17e4a054,921d9187,30807530,3c0c72f9,1ef469da,743c8a55,cc58f62a), +S(bf32c76c,c733c2dc,85299812,392a2ee6,5b0ce661,93cecfb,ed2ae522,48706aea,961e28d9,a6dfc6e2,3b7a1235,4b9551e5,bd1da617,f8a4d985,467de1dc,bb2b6630), +S(68760c7e,1b0b625c,bfe9533b,fdc4df7,cd0acd04,de4c4e5,cbbda233,4d2394ad,b0ea6bb0,f9c5c9dc,91af54ae,718c3ff7,5bbce1eb,ef353006,3809ab3a,4432978c), +S(abfddef,d56b2944,ba1548f6,dae0e65b,40e19431,b6415380,3558d497,7a373aab,ab40ea01,23588781,882e332c,432177b6,15023347,b76dc121,be5a0a71,f55563f1), +S(73800767,7aa92884,93ace49b,60923a7e,e3adc2de,78c17e28,3ae967f3,72145ad5,fb1552b1,6fa17e4d,1dc2bb35,95b1b1d0,5dc7e48a,ea07fde6,7e6f7c75,f15f5267), +S(50c0bf3c,6e3666c8,a1a69544,90590b43,996e9a75,77c87e0e,5bb8e927,5caa4ec1,d0f80c96,1b75680f,8264fddd,31b52c28,48a769bb,2976d706,b922b46a,277ecc24), +S(879e4cb0,47b3138f,1a5cdd5d,9eab5b47,a9a8b542,83fc488c,f82ab22b,7dbf2f47,5f607d08,bccffc0b,27c2f0f8,f8a80476,52fdc19f,eeb62b02,248447ed,d5743bca), +S(6ebb3735,465dbfcb,32bde807,471e19af,35d5568a,ea6f5286,4a382596,df623bb7,e2801ff0,8e04b574,414d4844,b7b1efe,8741c0f6,4af13080,ef473397,3aa0bdf8), +S(5997354b,9b77dda,f34a9ef8,649904fb,fc8a0223,1e8cf882,7a8309ab,b209f420,d42f55c9,4d8054ad,7dacca4d,8d7553e5,355db690,1df155,5bd07574,25e9580e), +S(41e392d0,456f7aca,f62f8c96,37881d25,8b316bfe,7655ab56,61413f43,4e428f87,20481bd5,36bbd86d,96600911,1da82106,2c55ae0e,b2f12d81,a8b8a1f0,4309af91), +S(5c3514be,60fb6a05,2303b2ff,ccf81ebb,5734ddd9,ff2b485b,429ce68f,3b16ae64,573f787,958b70d6,36565295,b35d9e73,7ee46c3c,d1d1ef0b,e37828bd,eb80e579), +S(de9e95c1,220bcf2c,cc2acf7e,ceab12b8,239f5531,e2c52949,29e30daa,c340ef7,2e20a50c,94476926,ded26edb,72780f78,81f01cf6,bef5b1dd,5051a27f,abc2b181), +S(29922283,6619c2d0,402ff634,ee6fe671,b0afb7ca,cdf4d109,cf98814c,af69adac,ad3f5da2,7b1785c0,b958af5c,7e9e7a85,f6c7002b,3000c25b,f7e82207,fa9ee9d1), +S(82f8b1d4,b50025d,fe960c1c,600eab7,45a25ba0,ee052eae,2f3e56c5,bc236561,97ff7a9a,a3fab00c,54f8bc06,fd59e050,b854f7d0,53dd2df7,1e93d75,60456d29), +S(4b883553,72c3c528,b8edd509,b8eb2b21,92e8504e,da5087a6,d2a3f9ad,256cbeb6,b0ec67df,a34acd1b,a3a68b3f,79962c17,11c0bfbc,3fbed2f3,345cc097,c221aac3), +S(53cfaef7,ff6b8bee,f6264a1f,f4b796b1,a5d3d1e8,471504c8,d6ea5d2a,5362644f,35697dde,1730762a,2692fc5b,1db386bd,1749e07d,a67ef310,47deb9ac,394ab691), +S(c4d4a268,112c2adb,d862b32b,f344af89,4e070db6,2262daf9,244b5c2d,758e1cad,c109c651,2ef251ad,9f9b55b5,10c973e5,dd6b2746,996942ea,7e4de0f7,cd8a18f8), +S(13d63ba,49b043d8,ce6a21a7,929745df,668a2497,5a57895d,704b4f9e,3bbd0aa2,d52dd90d,6e418aa6,afe2037,80870e15,78ce6dfa,c1a73879,490b57e1,c1f06878), +S(4499275a,5e03c1d5,2ee69082,9bd53365,6dc44a6e,6584d2a4,3c27ef78,fa3475a3,4f51bc3f,56fac2ad,3bc36d35,b47bfc56,b3885e3a,9c279c86,83762bff,edc952c3), +S(e526f9ce,24911c8,30311aa,82e8855c,575c9e2c,553f7392,2285fbb6,caee91c3,e56c2c38,28c7432e,20b490e1,3f6c2476,47040253,7b1d851,31690263,a41ced87), +S(723260d9,c31cf302,acafa19d,ac90ded4,18d5945f,e5fe302e,e7fa8e84,b3fb2449,bf7b11aa,b5603f1c,89a8d6d,ecdbc47c,9bc0d229,937cffb0,8e4bb060,d932f6ff), +S(5895fa08,76ae7387,41184045,d088aba1,61be9802,33f8820e,7eb1f9fd,dddbf76e,a4dce1e2,d7a60205,197a8458,d566e8e3,720edaa3,bfc4d946,f798e438,ea3b3c65), +S(c358ae6d,c1565fcb,623c2c2e,a575ad86,388dc893,b9153135,af4e787b,17c64c9,f5a5852e,e3826ec3,e20a0d05,c330338f,f28699e4,ebd749ff,3abfc3de,edb3b97b), +S(efea41f2,599d5357,5314ec4e,7f36b564,1f31802b,ad030d6b,cdf8ef63,4c1491dc,5dd25fd0,45ee4019,c2d22619,e47da1c8,1c4062e0,d6a9bc4d,fb37c6b6,7b9c52ea), +S(8e939129,e1547a83,c73900d5,4adb8bdd,79f98d70,3c9c7689,9a7b3f35,8eada2f4,47b19f53,433c6b75,f8f33cfb,3aa91908,b8acc5a6,a69bb533,711cd84f,f497ca86), +S(e5f3fe2e,ddd45d3c,745baa9,fd812dbc,dad77d5a,aaac44f1,20f92515,53681f79,a450e661,a13cab2d,758eb49f,4e49907c,f9ec8207,bece14e3,e3e80eda,cafcda1b), +S(727ceca1,f1985b59,e3b1abcf,400972e6,87f83e1,ffe30f64,c853c8f6,35f4a3dd,c451b046,44e83ef9,d078367c,3cb44374,ddada9d1,9416ac28,db60a12c,fc526fe9), +S(a98a9e68,da05a375,80c0633e,216d76bf,151a7921,32ecb2a1,c114c001,3fc095b8,26aac75d,f680f14b,ac3cc30c,5c14e782,3b7be308,ff8ec2ed,1551737b,2e213c33), +S(2dc1bed0,a25f6024,3ee2e20b,90158ae7,102b43f2,c781f91,86dc6d8f,768a0ba6,85b6b3d8,509d7c9a,ec12d44e,453456b0,c881212a,3c056d0d,827f5488,f02e581c), +S(90cd9e84,5fc1e7fd,28f28544,8b9459f4,e22be67f,4caeec44,2c96d77,3f6932bf,63c92e01,1cba5199,3311487,7b208922,1cc6a651,b160a049,cd558e90,3ed560e8), +S(7ad554e9,61e1084d,8be77d43,e8aad732,5725a9f8,3ba29da5,6ee8e21c,8d6f15b0,9e13367c,d9b38a18,6b8306e8,714cb709,12619c2b,56953ffa,9c538383,c7b36e3f), +S(e39f4f35,c68f835e,b84acfc5,dd5a9c4a,84263b85,376ee9a7,e72489df,c96fe3e5,3f06c83d,60b5eb27,f6d8ed32,1d38630a,8bf822b0,1eb97f0c,90d2d9ba,c1fe81f1), +S(e732ec5c,6d2c9f2d,17ce26cf,99151e74,31aa7c07,87a9cbf8,65611936,5458124d,51d3e77,e75c44b5,4576bdfe,36cd28c7,9131d0f4,b1cdc356,dad51aa7,253e077a), +S(5cfbff88,130d394b,c0ab5ba4,b79ac89f,f78a2c0,fb3f7f35,bb3b8c60,3eef9596,18aca6d9,58e733bc,12ba085b,bef5173a,6990eab2,59bd6d4e,e3cc7c5c,7bb5516e), +S(69d1998e,3a0be330,a6341161,76adc83b,6d2dc4d1,2b985924,468790b8,25b182c9,5d8435fc,6cb17de7,65b628bd,2609a81c,a4f8d081,337be0d7,89cfd817,583849bb), +S(4fa189e1,1aa8d445,aaac9fe,b8bb0fc3,a615ef8b,5db97120,b231201e,1622d7a1,ae8130c4,164090da,706a5f21,1bd3389c,8a08418b,36c7b248,a9ce1c7d,7f62a175), +S(5b8c0419,17905a9b,7f6683a8,ab52261,bdccab65,9d70db3e,daee62bd,a0647a44,ec7c14a7,ce63910d,4ce729cf,e1c30a22,3c74fb05,eac31e8d,876487f0,cce4bcbd), +S(d8911bb9,9e908660,34a55849,84a7eb49,2f4e2ca1,c1f99d3b,35fe4d58,8813df71,c479c2b3,4d9d5bdc,c82e1f76,c2aff35d,cd71c0a6,fec01808,a0d35ef6,e74631a6), +S(9691f765,417f4841,22baf14e,c65afb44,8337b915,dc85d449,c6101e07,9ec94981,d3f163e1,a69a968a,223e2ba5,145d0dd4,2a8cf4d,baa6d247,4ac5c965,3cdf7049), +S(27299a8f,98275592,39b42976,bbc08787,30025475,79c6eaff,4f959156,61a47ca2,cdbb9fc1,bf25ee54,f5524fe9,c5d70a59,3f849ce6,b9ef2b72,c9d85c57,a0f54974), +S(ba929ab5,abb7da7e,be263049,558e3e68,397811fd,9346890d,ca890f2d,4260a31f,78e7195a,1d6fa4d4,a73d3b25,125b9a70,1346492b,962f3587,7e5b8a40,7b94e610), +S(5d065bee,93ed86be,f4d96ef1,cb1584a3,7723bca0,1c696602,ad27615b,a0eefe84,592a8fed,16b03476,ca7c695f,3e934da7,c9ae43db,6db95bdc,e313ce85,8d6efabc), +S(89c311cc,2cddbba,b5d183af,2d6013ac,f3682f24,7c51a9b6,fda419fc,5620678d,a3c6ff3,9bed892f,5fe084fd,18e7ff3c,4facd6ed,38afc3ba,becbf4e1,67e086da), +S(85d1158b,5ece0b13,97a5d9da,35880f77,fba762cb,58d05c94,ea27a97f,8b84daab,b8cbaf1a,b3f392ab,f70830ad,b7bd69c3,69384f9,4c2f11f1,476ac91d,f171c46c), +S(9905e022,d0d9504f,f9acab48,49be95e6,f95e1c74,f28a8281,7c6e858a,602f65ec,a1552c6e,19467331,f78f6fae,71de8604,504b11f9,66ca5dd9,8788597d,b52b88a2), +S(2cb38e47,c18dda23,10852993,6a668f2e,aa5ddd2,b1acbe2e,8d772c00,18a0b513,6ae910bf,62e0d313,fe326bf1,55e44d88,c85c61f1,35862d96,57237a8b,42310ffc), +S(b98cf874,dc156aeb,f85fe931,af406e75,2e4a7738,bb22db42,5a853949,e152dab8,bfd9ea5f,e8f9fac4,bda888c3,7e37e2e6,73d3262d,8cce54ab,f923fe5b,6afa964), +S(b907808b,678f8eaf,b29d69f4,5f62d8e7,990be642,1f62087e,8002216c,5f75d851,8e01d556,f9ab18ba,711596f5,61294f50,432b429d,5bcf101d,2c7db554,7f2881f9), +S(158c96ad,32e36ffa,1b67a345,a650d15e,e3caa5f8,eb9f391f,f14d04d4,a3299700,f63742a8,a8d39d2f,da081040,748d157,18c9bbc7,f228a768,afabc69a,7897dfd8), +S(cd62d2eb,1ffa09dc,e6d5596e,fd6627f1,a40e1d6,46e58d0a,99fdfda7,1e1d0665,9d0d6f0c,3e02d85,b99b723f,90acfa03,38c1e021,bc8bef01,9fb0deb6,ad41836b), +S(1616a7e,c92bf575,713bf433,e6788774,2ffb6c2f,f9ce2db9,f0df6149,fd7acf66,baf4dcc9,574957eb,aafbc4b9,cf6f913d,198cc26a,d98d9640,364bee25,6c76c22b), +S(e7ef9ff3,6e86908f,8cd68871,838ed08,2873771f,2df1ee9f,a74f8943,f2f46a3e,ed95ed67,65626e66,8cc8860f,b268b28,e9e4784f,4d704af9,3427f645,4f65e081), +S(9d91f868,ddb1beb2,a986d7ab,2e6c8da7,65e2605e,e1cfb07d,f368a30e,239b16eb,55ef3a1a,284bbb2,d73e4fbc,2f92ed35,b332c77a,fb19cc90,ec98d964,dac6f8f9), +S(609af9ec,3804a542,833fc7a5,bffd7bc1,da753dae,2de2e9b8,296b7327,b04da33e,fe876bc1,8fcd4c30,5bee3437,77a27231,c4e1baab,cd0afb37,9469c085,c416c8b7), +S(871a8cce,60560ca5,83896884,9bc3c7d5,3d9dee7d,ba988495,16258f64,23ccce06,2b557be2,d08dd1a6,126c798e,ed1cfe84,340aa979,c38de116,dc01e442,39418023), +S(1475a480,e6da65e5,ff84f5fd,d926f302,6ebada5,6f32c036,c7cc1375,db1df8a4,1e35a8a8,b1c38922,555357d5,69ef412b,dd0338a7,54e58ca8,87d09cd4,7e9fcbee), +S(4e90a94f,cf609448,27b69ac9,7c758057,9aaf77,54e068e9,db68f50f,6d46f68,5a7532b,13f4224,b51542aa,6e94b984,651caf84,37a16c56,1583d227,8099cd22), +S(bf8f311,7c4a9500,8fb70bcc,2442cb8c,bb5be275,f1631dd2,e86edbd6,6e239845,2f8cfd98,1dbed87f,4c51d621,8b308d4,76ee4e60,161509d5,861ff2c0,72a0cfb), +S(ee46cc95,d118b3cb,6c37dd09,31f42988,ed324ceb,9a6cf226,87fdfe13,1bac0cce,4bd94958,867907bb,4823a7dc,9e3deabf,a3ec504f,a4efad0b,146ded5f,3fdc67df), +S(76c7cc03,ca94b2fa,ba2aa8f8,b571d57c,6849461,5aac6385,11e28d0a,4345d4ac,89e964e7,d0c2bdf5,de3be34f,886d6b2,8955cd32,5e92ceb7,b379aed3,b216624f), +S(ee37e6e4,bc5616e,59748645,72e2c350,d43b1f5,fc6c672b,524615fa,e6a5e14f,8b721572,f7fb8c3e,a108c05a,1214ecf0,4443dee3,89fad7e3,86b054f9,1f0c3d5b), +S(e1c7ae02,561bd2f0,1e64844d,ee3df837,eb647df5,db64bae6,96c1312f,d9a0775f,932381c1,1bfe3926,37921d4d,7e1ffc39,8aeb52a5,b113d01e,1b78d0ff,106f4213), +S(6aa0b3e3,98f6f75e,f13994d9,91cdd270,c025c754,67ddc374,9fc530c2,7edbc255,5282fe89,2d97a94a,e4c54bf9,94d9db69,8f629f58,fafcf7a0,e18f85a6,574ecf22), +S(a4c83267,3ea49743,16e3aa95,e5d9ad46,30818d04,58c6783b,5f305e04,71b7e980,10eff981,dff167b0,119286f9,453ec889,a98ab7b9,4acac35e,f8a39745,2df75661), +S(d5b2a546,81726474,55c45c43,a5e900f9,4bdb83e8,8196e3e0,17cbde94,c2f2cfab,d0a76d60,dca26b92,e0a91901,d9b414fb,eb90155c,89ab67c8,351e15e9,da1bc7e7), +S(c7ee2daf,b3d220f,8865a578,6b070507,533d0b2a,3ebf9379,da04c68d,fc5bae5c,ed030df9,e07b915c,ef0dffc3,d2d24cc3,55a0af4c,f6462786,7f322b21,78420cda), +S(1327686a,b3a0cc7e,59a8f6f,c3cfacde,ff6c17d5,9100470b,94f04bec,ba82b09b,1ca32583,151c8774,6a84b527,313c79c9,dee0cb5d,3043f584,6799fd7,abd0d07e), +S(1b245c2a,3e49e7b4,4d35701c,f6b69597,9df760e2,e65df3d2,b16e8a5c,efd065c3,7ded9046,3a7b9073,c30fc599,eb8660b,f3073166,4fd147a7,d5c33903,ec3f046a), +S(d48820d4,c768c172,43727ec1,8b7d4824,ff214bba,1f079eed,828377ee,e386d651,7ccc1a18,5b0018f3,b7911938,21a30185,c18f3586,9d34dddd,4da1f76a,a06ff703), +S(7dcdd09b,ee384bef,55bd4591,82b7560a,aced0ef3,9037a661,317d911,38562054,19b815f7,c2b8370a,e4cbb9a2,facb11ff,b970c050,26ef5aa6,e92713e6,f5cfa3a0), +S(19b26e20,cb023c5d,f474cc3c,12a80528,aaf0150,bd90a19b,9f7578b3,c9624a85,71ef67ed,d954782a,a3fb9bd7,c7b747c9,e9101ab9,2778c401,18c96ddc,d1458273), +S(9dd490d6,f1ae170e,598c17b,3acdd8d6,f50f32fc,9f956bcd,8e2497a1,5af3f29c,e62680d9,4f21d3eb,4ea278d2,66c4bce,ece6c1ab,e6fc068d,ca9d72f1,21bf3903), +S(6f12b9a9,71263232,4c15a533,3726f032,2f634d81,964e0b15,b20dc998,b085998c,34fcccbc,b4177216,24471698,31fe129d,a90ca8d8,d95a62f8,cca5da0b,505d0b3), +S(b011c854,19c89036,77c6023a,bceb8a0e,496c2021,e0448993,87880eed,9f5c2764,afc0603f,aa87d081,5449686,d9ebd182,1f33f675,35d7ab18,5231e8f9,6c5cfd8a), +S(c7ebbba4,5d2c4b92,b71b0e50,3f4c4e99,d9b61fd8,e3bc100,dc3b6b42,53444c10,8c042323,c7a16c9d,32654e6e,240f5c97,901fc2,2f6e0840,de0ad053,7afde378), +S(95d1bb83,27dbe838,bda8e60,7f23f193,f43996bf,5a548270,fd296f9a,7ab93eb0,d15aebdc,f5432a03,3ddbd8e4,42433984,d1726068,634fc49e,ff0dc9be,e843842d), +S(94897726,856037d1,3e009a99,cc799006,388a0eb2,d34541ee,f548ec75,585abb64,7552c109,7343f999,9d97f0a4,ed65910f,f1d7ca9e,542d9b4a,3ecec791,3abc4920), +S(77b0dc2a,158cf2b1,88a98be7,d1b3c1c9,fd9b2c94,a2bdc2f9,c3597e77,e8572823,ff3dee13,5d130bb,c5c12bfd,73f73aae,c510ad84,cc9aee31,f28ba147,e99554f4), +S(47f7ddb,bbba408f,fe233d83,627582bd,a4d8915f,4bb5386e,b0b039e2,ed3706d4,63c6280d,be656fa7,81389b03,1d70ae36,6146f7f6,4fd736a8,8d9edecc,a45d2710), +S(b6561d0d,9673a6b3,4005bf53,20f74c4,acac0fab,d065d10f,8a61d5d5,25145020,dbf3f35a,9bcf58d3,ba3a5534,5229918c,a4461f1,8ae692a8,aeebd8cb,1e66782f), +S(fbff78c9,1c67bd4d,75d62a12,b679a4da,ba352a0c,73ab0d91,96ab06e5,c7e7052c,e2266fba,7e71ecf7,a6862bb5,84b1cc9b,6bef8697,fcba312e,649e836c,fa0fe837), +S(fc7e1250,3b630005,f488c776,9730f43,f5a4848,edaf869b,68bca480,22f85ac7,f8170409,f312edee,fa00b1b9,b62b463a,b7e0ecfc,563bf6f5,543ae7a7,10885247), +S(84f2f115,9fdc3a58,df6a2971,9e2dfd7b,165d1052,4eff49e0,6ee53a9e,6101f30d,50557807,24376a0c,215e44cd,ae1d1dab,619c324f,fcd5e766,89176f71,363d7998), +S(41f89dc6,3cc4169e,e6dd6317,d9aeb671,c5e0f0c4,c29c1621,b9fc1c73,9edb5a14,29d608cf,75a44457,82694ed4,32924d76,79a33233,2e62b4fa,cbad3643,e6ff9e36), +S(2bc495ab,ca4e5879,fa277a14,6c07a2fe,98a07db5,ee5a145a,e042b578,bb4e9c17,87b9ec1a,79d3d68,b822a80e,721238e9,c2a75c2e,aca94cab,2fb731af,f964de60), +S(4b18ea46,1f6468f4,f1f6b709,a00934b4,818032ff,61297f0f,6a4cb057,8cc4cd90,4f491b20,32837a07,171da3d,2acc4191,11eaa82f,db36464e,fa675944,a2c4f986), +S(ecfdc56e,c44009f,1206b7c3,bd3113e3,178e3909,68d6d2f1,cb85ce3b,b951e61b,5085e948,5b4a00bb,9f09efa1,17f83987,6711a043,1c3dd794,611b2c8a,c795229b), +S(6e97a5e4,2e911bba,c5f7ff6e,1c4fa9cb,9d12deac,2c13e8e3,1baa9cd1,3463a8a2,a86f92d4,709c635,f98dcdc2,e93d66cd,a541e49e,aec0ddb0,6b1c90bc,e692ccdb), +S(265226b4,253a201f,bb7db973,5558a4fc,e07c26e4,245e4743,2ab0bb89,e99a804e,51e617ba,10b8b90d,67f565d1,156557af,a967f03b,85400f9,975864c4,f5c2daab), +S(2ad97868,5a488eed,838560e8,b071aa47,565c4bf0,67337584,c20f8cdb,b2534169,8cfd2d8c,4d7bba3a,9d9afcf,2ee1d594,1c3aec8a,8e532e1b,def7e232,b3ae542), +S(457eaad,8c46f083,56a2c593,a65b3d7,74ee3292,bfc812b6,526aff72,8ab2b495,3bc3068b,26008298,5186ef55,7c9c6731,795ff1a7,34657d65,e97dc564,cad5a019), +S(dc83dd36,3ece98e9,636fbabf,96610f56,c74d0518,6ff0658c,e1e96aa2,8a488c7,ffb4642b,9f07e134,a3daae04,a7895645,ac49d6de,7cf95131,a9847514,786b4f76), +S(36962a9d,5731fdd5,379870f2,6562feb8,38f733dc,cbd6726a,41112d3a,c9df3cb4,efa15b5a,bd55c577,82e95c2c,12e54992,d9728e70,31566878,85e19362,8d55af3e), +S(494fa294,b5ac0d72,fc6f7f7,6b7e60d4,f8ec6399,dd1f4465,e57846b7,32210ea8,e0b00b97,71079c11,2a5a6e32,613c5d0e,420d1a5a,3212b52,71d0dbfc,4e6d16a5), +S(4989c175,23783475,36a6fe53,a6f135c,a968484e,f7305e4,f80b6d95,cf41b30,75dd93f7,f04f06b8,88a19ece,4811c5b8,9992825e,9be07f8,c212b660,13cd7017), +S(677e82d2,8b74f3db,73a8230b,98729acd,6b010356,5ba148a5,2438a5c5,436b6fb5,1ad2444d,b7b84e6,c4e2f573,cd2fb644,f3823c6e,81a574dd,bb4777b4,e26ff10), +S(c379002b,e70b8de9,80af55ee,bb05eb6b,ef0beb5a,102e2172,687f85d5,b9984d21,127b0907,fc511741,77cc7f9a,9b36c334,c23d1d72,20267878,391644ad,dbacf331), +S(39b33368,5aa7ef10,fd223b41,3c375334,38d06cf7,5b27ca06,3fd5c8e9,22cca4a7,88aaae58,acc5c41a,807e644f,6cc1bc3f,1f147174,994e0440,ce678f78,d783433c), +S(825be64f,b35ce8ed,85cb6826,79ca7677,5a40bc3c,105828f3,a8b30595,ac3b6b21,976a3b6b,dae0f22a,e33f3d36,7d3fcf21,29f2ac35,e8239df4,553a869f,18650183), +S(47d9d5a8,8bac6136,ecf568dd,ea7ececc,57f26b88,6fdc05d6,4c5b7ae1,113d3a7c,c6863fd7,e05f3e16,c0a47eb,6c2b0581,184b8d8a,550da1e2,370928cf,4d7b2804), +S(bb7576df,abfd677d,6545db2b,69af7d62,20ba17f4,f4ae2881,8ec91a0b,23487df1,b5df0436,9d7227bf,67953da0,ef410f0a,a7cf80c7,4f3c8c89,de6cf1b8,7c65d16), +S(6febeee9,251bea0c,d43eff7a,da9dc5c9,5b86db1e,b0e09bc0,4d34fa4c,4ead4508,df691ae,ac9bda8b,496aa808,949d348,97166b32,3f99c9cd,a851f68c,26a1e39), +S(25fe413a,59744683,ef244175,a8021b6c,62e7c2ef,c6489261,958167e9,10716fb4,8be281f6,2df1bf49,8823c080,69849a84,b1ce138e,2326db32,cccab7e7,8c8a1ab7), +S(1389327f,be427f53,f219b978,4faae37e,8337f5a3,1c377bd3,415596c3,e72bdaf5,fe33fffd,a7bb26f1,34340613,ab692eb3,9a24916f,37b66df3,194ac53d,1f9c1a99), +S(1a3221f,30f9ca00,9e9b3e7,ac40dd45,b7b37b5c,1cff9c34,25cd5375,48f6fa52,7a105b3d,25b763f4,15fc1ff4,b8b3b964,9c1f0317,a6c4fa25,d731a120,562730a3), +S(ece7fa3d,55e6b94,4c6beb50,b6ae339b,69ec8a46,679e11c2,7c703056,4cda225d,68be5c5b,fa975326,e5bd41fe,7187ecd6,b83ba698,ec98a7c8,9c8ff6b,d207d5), +S(9fd0196e,91eba507,74f75e0f,980c4737,ac7ede54,4be0a8e2,c1a852b9,4799d10f,bdf3d80b,fc7ca162,76417e3b,b9caf72a,6e94c84f,c42e8091,d3eefaf1,ea790dfe), +S(db89a9e8,703f23e2,13300b25,f952df32,853691f4,6fa6bade,c7ab775e,21a80fad,504c9ae3,c9a9e7ce,ccad44a,8f97502b,5577db41,510b3e13,8ccfa64c,2fbb0a31), +S(32e762ff,a1b84c7d,c3aff832,a838d555,a9ceea5d,7066ae6a,efbbf96e,5f5c5eeb,ad842a97,ed1f274e,d3bb0460,309ce41b,f7e9cb55,c7bb5d3c,3b2b662,daf4c419), +S(8e7328c9,93fac58c,17d2c9ce,8a3959fb,2c0c8c7f,a4d583a6,c4428f9d,98f5d1ca,b5370e52,815ba519,3fa02e95,d75a7168,e1906ae5,12cbec72,4bcd1a9,b897b8bc), +S(dbb8e270,d516fe0f,470e325c,37707a03,3607ca5f,92c6f2c,97c32f86,1418ecf4,3da4b926,7cab86e1,7bd9442f,f3bf2c41,52aef531,f1d028ed,e801215a,7204fa86), +S(5dd9b4a,bc618666,12cd3344,2d8e068a,fe624850,1cff8c33,87af5881,c3523544,51f5b,a9a010dc,6e5aef1a,138251aa,dd75c5fa,caa222f7,db2d4218,220fbf44), +S(50a74f67,90a95b14,67eaa018,9409ba38,7edc5abb,4f2c408f,5bc6a5cc,6724ecb4,d32f7031,9f9162eb,861255fa,42495a6a,fefc8949,d36150b9,c4d5b066,7b41031e), +S(11721064,55ae2391,2c2e35fd,190ba29,6bf1d580,fc76cfd9,1fcf6a02,e77ac992,158165db,2865,968604f6,3fbd298d,3a079619,a0c161f1,35879f14,5091a41c), +S(570cb8ce,d29b407,f5e4769c,57c42796,b1c0b111,684c5a7b,fe9ecf8a,20b687fe,9826e697,97573a61,26d7cada,c636530,ea747b41,308874b0,a4fa578c,b984814e), +S(5adfd4e9,142a8f6b,1ea6aa3e,14a83fc0,7e1df246,279082e0,36b8e2b7,dcc30637,82314ea,36edc02d,c489c36,c2b0d808,d64167ed,1cb33651,418e3c08,7732c97b), +S(b26f96ee,37d49fc2,e4e76f4d,257197a6,f1c667bb,748fb69c,29d9f033,b94419a9,bcd2178,aafa4409,329d735a,60bf2fb5,60706e87,295c6d7,a7a7e0c9,4b280542), +S(dbbc5fc1,ea84b079,90bd1af4,fd244599,70bff024,835ae3b7,129f6caf,290c4bd7,78612296,2b62b621,6f43f734,eab00121,ba5a5b3b,81090a4c,ebe2cb8a,5a02591f), +S(e4d32dd2,710624c6,94120041,36639e21,708cb3b7,a15682ea,57e80ebe,a13738b9,3aaf833,3a7f31ac,6d6c8b85,e0831fee,3db67209,f35b0362,3b153677,6d7a4098), +S(81c6fed1,b687970b,d3716384,5c35061f,e9edbb33,bbaa609e,53a835b0,c13d6a15,934cc11e,e733fb68,1a575c98,cace3279,7a6fff4d,6bcbed2e,89836fb9,3b83597f), +S(28a654f9,58003817,95793,46ddc440,13c07f78,79c3b247,e52dbe27,97a02852,10de9cc6,571f24a3,6a08fddc,1ed27cd4,a9a0cb11,5d275d99,ceb60676,43773965), +S(532c99ae,cc7305db,5cac0294,e25c0a0e,45e270dd,4f621f2,d1e36ccf,51cb7a48,8ee3619a,61df9f49,84259ab4,744f563a,bbb45462,9eaf0670,5240d67,6b3240dd), +S(de02390a,37ec8a18,2a5891c4,f8041ef0,d548f367,4e8a91be,9e29e0ec,2b822e8,8ae501c4,32e81681,844fac5e,86bcca09,aae6f862,76994d93,7074c1ce,c3a04b33), +S(877916bc,6880f1b9,530af368,1ad44238,dcdb76cb,ef1d3f61,6856566f,bb6da5a8,807bc5e4,5c400875,42804d76,eab0f291,499622b3,dc9a7e81,c1db7839,ebc5a5f6), +S(5980d5f3,4b0c3684,a3381a84,434436fd,e0a0d6ea,1c8f16ff,b8a35793,74c30e9b,9d20e10,5e51e720,95d95766,7f479f61,34051c24,b09c8a2,125fb9c3,6a0b4b7d), +S(5246fb5a,4fb10bd9,c240b274,93abbfd0,e404f444,13f0a126,5d8fae3c,ba805fa9,8aad021b,c7317328,6ab78e8b,3e3cd613,9d881233,d1f62cd0,9a3d6260,88886c7d), +S(9b5ded4e,dd6f9c11,c3e9e760,71a7e257,74d2ea6f,c87412e1,a918f2e0,fe2075fb,80fad92,396c0f77,216187be,66619a53,d6a6ffeb,1ab70ca2,d64b19bf,2b0a95bd), +S(d2d4c183,c4ba3336,2aff6d81,263a5845,b76d1e3e,6f5a0a0c,928a1887,da2b03c7,ea15aeaa,b602f360,f3a7faef,fbf2725a,5838d041,70455d50,6ec5e1bc,ca651b2), +S(222241f9,b3408b3e,a8f7bc96,67ad4928,183557f2,754b3972,d5e938e6,36ea7857,cc2598d9,4621a8e0,3c8b444f,bc6b68e,ea584144,c770d095,b2152891,e6bde708), +S(14cc26c7,c26fa386,e29204a6,99b24119,c8642d24,256e9fa5,407bca7d,4e69c32d,9b125adc,dc2150ec,5181d2b5,5a862dc1,4de72a2b,7a04e912,cb2f6503,24101dfc), +S(292a1480,959eeb3b,468d54ff,2944786e,7702bf4c,8ebdf837,edd65177,1d5a971a,e7355cf3,e1c089b0,9362b68e,83825a25,39c88058,8dd6e1dd,ecae9447,ea4b6388), +S(6c9f4196,a35d0a9,f0517c9b,2c04a420,127140b5,ae9d2274,cd5eeffd,140ce3a,854d6c38,df5604c0,1d65c8f1,9f5e89f7,4c6b1c9c,2756fb9f,8276088c,c39dd80e), +S(fbd63ec5,8b3e0c43,4033ea2d,f4a8cd55,b4b4d24d,d1f8ed5d,6d8b1b6f,a14bf30e,e3770f0e,7b29f62e,9921f8e,2a78d2c3,a62814f,97caf2a8,304a782d,b72c6b50), +S(df91d6e9,b046fc63,d81d94b9,aad17096,a2c7fe88,b95e423d,edaf12a2,4a2edf87,2cde227b,ffa27e95,ded3f142,41d26599,da28da39,16227b43,e665aebc,f67a9fae), +S(b2ff741b,8b5d4cc0,aa987660,59652337,6ac36083,e784a181,63f653c3,667fa2fa,400a34a,e6990fc5,7e268eb9,ed2ee2ff,dcbb27a1,26f0c7a7,937617d7,19e7b0be), +S(d156797b,9de0ad57,41b759ab,38e8f935,d352b464,b01080ce,70e22376,8d6b5e23,b7e64c4d,fb332c98,9d21c2ee,67a5d5cf,d728bc07,9b448283,55d9e6d,4b0fb3b4), +S(a3814ee5,e242a6a4,65ad0681,a0193dcd,16538d6,1087c6de,fd362a8e,671e7ed2,3be12033,59d441ba,d59d88a5,64d03ce0,c67a5d18,4f883388,96f7caa9,e3dc96ca), +S(6aab0cb8,b46728b3,8b78d386,d45122af,c95bb1c9,9298cc77,299f2fd2,b5d72586,fcdcf718,caf0c93d,1f3ec76b,b4060f8e,a3863736,a5d966d7,c617fac6,6f530753), +S(5fc6e596,7b508698,4c99666c,22fc7316,54b700e,55877f73,169241ff,8b759937,57af0c61,76ffb00,626a98f7,ecf72762,9746b0cf,dc8a8914,683cc49a,6d568505), +S(7f3944e2,bcb3cb25,e36c8479,ed51019a,a61b1122,ace99dc4,82ac38a8,580c6d2a,dc039090,54244e0f,6acb6d33,fc4fee58,8e5e25f4,b23cbe55,5a330779,872f2062), +S(5485c8db,86078936,14fb7a19,73651f6e,66ad843d,e92db2f2,c4db2d5a,bb7316f5,ac39c239,b0fda325,44bfe05b,1a4ecfab,7ccb84c5,db2ec999,6d8587f7,d15bb82e), +S(e52b9934,910510fa,3611dba3,8630853,d0cfa8e8,ebd64a2c,7b59bde5,edcedf2a,cea4d745,64e8df98,d47a3ca8,7f1e45e4,728e52df,f383e391,6dca08d1,326a7e38), +S(92b17ef4,fb8f8dd7,e0307a,672b37ee,78e0dfe3,e19c094e,44a50c9d,3ad7faf2,5bd53e68,dbcb4e47,18266085,9d12a34e,943691ee,dd034cb3,1eef8a29,e35b762e), +S(7f8b2952,70f6b2e0,84503f9e,df24fb8b,e91393db,64a90971,5e68b009,aa9c3b6a,c45f0d84,d9407856,19a87d38,296f70d2,41ddf1b3,8f421d12,fd2be1a9,32d2b437), +S(cbb90912,403439ab,8d04714a,1a5ee460,70202e4d,1d7de375,36754bb2,4c8bd2b3,6966ca4f,bedcb6cc,64d72eac,fa1a699d,977dde05,5d2454e2,9deb220f,e2f51c11), +S(7d4ac2b0,6d1810b9,a3e823df,ece821c7,70c90d2e,ed0bc324,9ef1a43d,bfab3043,824fb46d,6afdf15a,7979b032,28588c23,4a9add5,6f512253,780acb93,ed7ff34d), +S(36482902,2ab638a1,df90feb6,c20ed6fa,fa81ddde,87d069d3,7cac4a6f,e92a9b32,af6530a8,1c62e72e,409d1308,d07fb227,63afad97,8e843672,b241ef60,dbb36aa3), +S(73f4eff1,ec95095f,be5d307,8a9f6db2,23e9b874,bb2d077c,c58fbdd1,d03e1f62,d7c0f36,5ab93ff1,999c6f95,d5c6102,47341004,1ed97e8e,9632b845,527078a6), +S(9a88fd12,af0611c4,b07ae62,59767f24,308d1aba,529886ae,6ef7f5ed,22e98ba4,a16e8f50,164ae75d,9712b544,ecdbada7,725c2144,3e8044d9,f3aaec64,367169c8), +S(265e4dac,6139efd6,a7866385,f0bd1cd5,e8bf205f,344ce71d,3c0ce073,766a6619,ded5a75c,ff4de7d5,f33bab64,d000b65c,e5078ff6,c01930dc,17bfc64c,826d103f), +S(6fe39213,baecad17,f8b82f25,d7621cb,3f1b1a07,2333ae38,d2d00a6e,ed8aa1a0,d6b830ed,f36775ef,7cd7c648,180a6edf,be65ab25,7304de39,791733dc,f561172d), +S(671f82c0,ac712083,8cc32fc8,85ae272d,4bc59e46,2dadae48,b4dcf279,707776ae,4aebdeae,2c42a80f,fd433d38,ad4ecab8,9e4dbd3f,d73db0b6,ae72e78,6eb7aac), +S(d83ef3be,4630e5d4,edbc6628,828b40fe,45806e60,83094433,31be3042,814bf4fb,ce89b788,8c93be59,bf0bffa7,adb87c4,a4fbdb78,73de3d04,c62b5a58,18e1ff92), +S(de2df94d,78cf43e4,720da5de,7f08de15,4b271731,8bf450f5,667956d5,596cc60f,61c4585e,3557c10c,8d22671d,8389c508,195b0ea2,e9150ed9,ca93fc53,3892283b), +S(4bf44266,3d4c7de7,872aa7c5,e5ae22a7,30dce19f,78d92abd,1b7e04ae,fa3e5dda,ea831ab3,b59eda4a,8e959003,c4a6266e,d4f691f6,1514dbef,18409b03,5b2a6594), +S(4912c91d,38722c4c,f00aec0c,895980fd,af4c6351,33021e52,ddf0ad4b,89b67f7a,f96d3a36,89e4838b,116b1529,55392373,1be5f0d,30b1d541,6c0b7839,1b24ba5c), +S(8c0bf82b,d2cdc2bb,49b2161f,9f0a528f,79f8f8a8,1b919b70,9fe5a46a,c26d417f,aa98d79c,1869d92d,251d322e,7bac3dc6,5f166c56,28250c29,9be63e4d,ae430dd6), +S(83eea34,4eb8bc40,2f4ee569,1d89214f,dd3ae674,d60cc0ab,9df0fd42,7559e0d7,9d7f5834,fe912c9f,23790306,3aa41b6,33085264,e6621a9b,9e87e151,dcb2562a), +S(754addb5,a1b21e3f,609416e5,5792c265,76b90660,736d0d0e,364aa13e,74b0a699,3145763c,c0d95a33,5e443b3,5dacc8e7,bdb2904f,b868cb27,3a505475,511f3dde), +S(3e513f87,e381efdb,14dc686d,14d85d3c,bf725e63,9d934de5,647823f0,c4eafee3,360be751,d3f097f0,b09c7d0f,1d425cfc,88e400fb,7a0aca3f,9d521e6,e79eb87a), +S(ea4cea76,f7478452,7364965e,546a7356,55d203d,5a92c3fa,336816f4,983fce7,a1b664b,e74b830d,8a49eab0,165e6945,69ce0518,98007000,e8094f92,6b3ba536), +S(eaf39608,61712ea1,88c9a2d0,c025d56d,8b52e59c,ea35f298,41f13759,625dd824,96ff00bb,eef7e8f7,23f2c7bd,7d6c3eb4,16827208,d3a2ca54,d40dbb83,4e13a2d), +S(34d3a7ad,a590d9dc,2547b9c4,b99a2e10,9689320c,61105415,c50879d,4de223c8,49eb6d27,eba087c3,1252084a,d78e187b,89473be1,1032e032,8a944e48,ce0a7bd4), +S(22f0cd6e,9e232e52,d82d70e7,d1ad0df9,3638bea4,8fa0bf16,4ab3c7e6,a1d961ee,66d0990,b57c8e13,4e2818b,910c27b1,7eb33daa,90ad5b2c,427b91e5,51514068), +S(27a48cff,114f4f76,bbce0d83,458a949f,c80b8821,fdcd35c5,b3810fd5,60d179f3,41690918,b0599515,f913db47,37083743,4f62321,72084ad6,7a730af5,b32d25b9), +S(2d845701,6ecda7b1,3a2a72f1,cdf24c12,8f4d85c2,c4b72881,45802bb4,603093a,50f1e7ed,ec9e2dd9,55678abc,e5ea06d,12ff61b9,baeb1d56,79055c32,d8654315), +S(cf2d9ab7,92247125,b0bccfee,f77a5a37,5e796957,75950d0c,af401a12,c8fb9a9f,8839d0a0,850df254,3e77dfb6,cf06f424,dd16c26b,f3aaefbd,aa3cdb5b,d0ad818e), +S(de85e4d3,75463ab0,a198a6a4,1d5f1fe4,c56af2f3,786ab9d3,705f540d,6b5a3770,1ade7a8e,1f9d595d,b67cf482,4c8e11fa,561b3625,4ec5631a,68d73907,8a9d8eb2), +S(c18e2092,299be419,77e40102,c9d4388c,84d602f3,770beca,50c03008,55ea3a66,86b9b3ed,786a570,de95e947,2fb0e61f,ac4aa85e,47792e99,25738e5c,3c4af6da), +S(df9ad184,a9e3b41f,ecbdaa0a,a48e2252,944e0384,538300cc,43f9ce48,6b224422,c4061799,db92d160,de19c4f6,a1280ca1,b62d675d,b7fca41d,ca838bd7,3d082fab), +S(fd846cbf,66ec362e,4d10a783,ba60c734,d9577ddd,18934ef8,81ee755f,d3748a95,d6db4def,d6c742a,e50ff8a4,43336754,d4244a42,a851ff72,7609a016,d0c84d32), +S(5e86fa96,c29e30f0,7b845438,5f39ac6f,43d120fc,df10d891,ef60e2b,141791f9,39f5ad4b,2e86a92f,3b38e286,5d7e1ec9,2782845b,593d1d4e,43ec73b9,2dfd6440), +S(8744ac1c,1b16d65d,daabc8ec,d6cfc40b,109dbd9f,c19e4439,1e2ec486,ad27293c,ab30e186,e4f2f48e,51ffed3e,46dab701,ba78b9af,b6987166,19c642d3,9491f1df), +S(9c4bcac1,c0a0ca58,debc6c0e,71238988,607dcdf1,415045df,83697282,84a31c1e,6467c5b2,32947b2b,30c32a18,174035df,d813d42c,593b37f9,2a8a05c5,52d2b7cd), +S(3766aac7,b9a2ee6,27691923,ef91cdb7,30a24727,2da61421,955ffdb3,5125cb7a,22b7d930,94110a51,ac72dc5,9d2bc66e,45349a1b,90a7c655,4464713e,6d2833b4), +S(e7f2d315,ea0d0f71,be63c896,3c6ba75a,2122e650,fda59f27,b4ee627c,54bdd30f,41cec687,9e6c21cc,99a3aaf7,e4fc75d7,ec163a4c,6aad8a21,22da269e,1e342d80), +S(cf50bffb,bd4aff61,80be7e75,e9004d85,2234fdd0,7b0b3e13,1b883359,7e96f40c,7c9eb80d,7808d937,eb5215a8,4ec4d330,565b2aa2,162fc4c1,b46bdb19,b93fc159), +S(5aab4d81,a4eca88e,e9cc0c20,94ced3ac,912ae932,2834a67,324aca30,956805d2,64d622dd,9afc799a,eb495ad6,dbdf31dc,7156ee66,d8a5e67,c44bf50a,94fac52c), +S(a4f6d781,9dd34aa7,18166000,79d8d7d1,eeb5b971,4549cf3e,a472126e,3cffe8c3,4c87eace,b4e535aa,36ce839c,336fe9f7,d4b0680c,e61fc525,4633d38f,a8c395bc), +S(3ccc6b5f,8188f3b8,b5805bab,c95f08d5,9b803e03,febb6f49,84dab325,1f6ce719,5b4987f1,7f9e2610,e443cb1a,2df24752,72655670,e739f0f4,3ca9c3ab,2a4dbbcb), +S(2d0a94d2,5bee2c99,1d8b312c,251e305a,5f44e1b9,29bde36f,a973e51,2919130e,f9cdc9ee,528a45e1,5d1ad338,db49b3a4,2db74785,d84cd12b,59391140,566636a1), +S(ecfa1649,da1a0bfd,41ffc294,40ad7a91,b6ef0d97,115408e7,3a05f506,e1aaa6e9,7f8a0b16,4b817533,84970c00,3c497414,ae319090,7481fa22,9a920004,8e2783cf), +S(4b97331e,38aa629c,14c37220,b6c3241f,603bcb0b,6b07a66e,c74ad1bd,bdc25d7d,65524ca8,ddb85804,a2111e69,17167d2c,105a58c3,321c27c2,2cc0256d,c30761d9), +S(acfc4bc6,99f3af13,ac70f25c,ed729ef0,866b900a,6c39705a,5e0937ba,fadd2a90,70ca7ebc,923aa022,85f91b19,3c550487,172f2f0a,8f10f0c5,29384cae,20167824), +S(2a984810,805a9eee,d24d1ba5,46825c6f,aea09889,132295c2,b4ec7e64,8db9826e,b56a531d,7fb7e8fa,ef957956,747015be,dc28da96,eccd66c7,c2727529,c2a45ad0), +S(76c6568d,551abc3b,f6102d02,17a440e1,36e80776,135dbe60,7581bad8,2aabb2e8,81e56168,c16473a9,bdadabf8,339c04d1,5d3cc74c,56465bfb,2eb0b2e2,8bd4f82), +S(6476831a,3425f0e,e8ded7b8,be239bf7,7b16d271,eb1d4b36,ba7f692,a2f155fd,90cc74bb,88acd0b,cda7e17c,48056936,9dfa8ba4,ec8d6f85,eebb19ae,f35ce085), +S(b2b49ada,50eeca27,881c3b6b,656df825,3422e3b7,1c145401,e92c5ed8,fa3dc51b,4f3f9fdd,41d2669d,b087ebf9,883f4f9b,383c4241,eb87898f,1e916392,d6838820), +S(75448fb9,5c0162e7,c3892300,bcf070ec,dc49560f,8c0f1665,f0bb081e,dcd12e05,b0b84014,c73db3a5,9963812,d99d6d0,5df7d46a,6a646929,9868d874,6308beb0), +S(643e795c,1c158422,24ccc0f0,97c18b11,dbe1fcbc,df8a4e2a,f234f465,f42cce3f,a067acf3,5c7f2e05,4ee6c40d,1c1f1eb,2850c9f1,8138642f,e6becd29,46e3d604), +S(fa200bc3,6ecefe8e,9e5c82b5,1f380c2d,a14b0478,6329dcde,9dae0546,4d109dec,8c6b6cd6,a676bf1a,c7f43bfa,29d6863d,87740099,d5a06e9a,eae4b885,44d1ecff), +S(851fe9d8,e47b0186,ce001821,59c674d,390e5481,fadf397c,67a2a35f,8cd7b1c8,e6e7b57,cc25bfa,8bb93e2a,f934e154,314dbf3a,37549659,8952de0a,3ae55a71), +S(4e462e9d,d2995148,d0091e2d,94f5660e,a5a994d,6476039d,dc0bd812,cc47ef1a,63c80573,dbba650,5ae95b0e,9c376a2f,78fb0d86,889e0ae8,33e0b823,7932cf00), +S(3e46f7ea,4606f5cb,4a8d7386,bd0fa2e6,89f03985,b9ab7cd3,1baf3cb8,24e928f9,a4d3c20c,9ce14434,2fb14481,41a381f9,fe4263c2,ce955e7f,daef45dd,97c3948a), +S(c650291,432ea873,473dce0b,c34aafbe,24a752,fd54ad97,5da33acd,66c48bca,795e9965,74baf74c,2fdd9e2b,a917f02e,aead569d,9a5069d0,73341203,772ded96), +S(219416d7,52d6258e,c69ad11e,1a2a7552,4b327412,c9431211,7b57d960,d1e23c5a,916c79f5,97ff454f,b93332c3,d0643652,73861c82,68ded6b4,9558d76c,217278da), +S(d97d3e10,8f3eb83a,9dcc03c6,76755f7f,ada5b761,69859e14,bcd4e7c1,56dfd7c8,a2f0cb2a,2fc680a3,79aecd75,1cf7758c,50398624,8381a5dd,ac9c9902,65b18a27), +S(dae2570e,67a3dcf4,ffc0f56f,ae3dd134,479b1e03,8faedb8e,2e84bc1a,3847223f,817af757,125d14f0,c9841d34,f885209e,e2b79522,53663a6a,a3077e2f,43da2c7d), +S(6d2b21e4,33b168,a6eb9eb7,496533fd,b6ec326d,e7fc7556,84547cc1,2c9c3143,9ff9697c,514175f9,6082783a,a2bdefb6,439d6826,af9a61d6,5282884d,4741262), +S(de577780,8bf5caf,428cf519,9487a81d,8fb8a2a5,2bde22fe,2f72598e,3fec4495,8ebe9150,916a70ed,1c6384a5,d133210c,53e205ec,d0ba7a04,5a6434d3,e32df9ed), +S(d04f1378,7bbc4e1f,8b1c548f,4d79fdd2,8a0f8199,49d81b51,3c63ca6d,c5c6d3,5cbcc339,3050eeac,677f8382,8499c8bf,b3d43b1f,5ec98768,ec0a71a8,d81dc3ff), +S(4353b53b,ff906815,d6a58b36,ae02cce,cbaa3fcf,a2bdb5db,7dcad258,4fa18e88,850b08e9,5714b0bd,2fbc8f2a,4ac5980b,ad30ff76,1241a5e5,5a5f01c8,a221fe83), +S(8141ba70,fb997010,1ff2ffd,865ebf7,137340bc,9eaaf3ad,279eefe4,d80953e7,ce0450d3,aeaade42,e4c66c30,2da0fae7,595524e,debbe419,316a1d89,d238ea5b), +S(8676ba13,25c85d1e,af93f424,755d17c6,70d2694d,2d52b890,540f9826,f2a1bfd1,df0c7ba7,8fbc592,46b5fb7e,8f98fb1f,ce1bff80,c23cc2fb,c1caffad,213a51f5), +S(c55ac2c5,1d918713,804abb83,e2109412,4494f614,109f32cc,62148706,98afc8a7,44e56fe6,6aa7b14f,44c6bf3b,1974e6c,dd8c7b61,73fe0067,952f0391,49512132), +S(72738507,f0b3244,e199409e,20eddb8a,8ffe7fa3,18930f45,ff0b1c9e,f7a15b90,ec121c76,e6f5caf4,7912cec8,4ae5c8a5,d5a9311f,a7f383b,d2e8622d,62e6171f), +S(f6a7158b,4dedfd94,6a4ee001,cf55ed08,33a57284,cedc4221,58cda87b,a0e1bbf8,2f37f2db,45ca86fb,b2fb6af4,df82582e,28e1e33d,bea3cefb,906d15e1,e7442f25), +S(8cb36d0f,40f21951,23ab2ace,e1ed08cf,de216970,ef6c6c96,48d79a1e,7760e58d,f397a565,d5eed2cf,427ad4ad,52d5d748,2b87bd97,ce31fb53,ad05cc57,2989819e), +S(c5cc35fd,5575f56f,6c050c24,769f4ae1,c0427e01,b953ddbb,4551ad36,93fa385b,6b5210a1,8e4b1d7b,592cb2ed,d1a66e11,545cd114,8541aaab,cf781d29,77551419), +S(bf3bbf0a,48711b91,74e120e3,b977a572,712271f9,842bab34,db42d1dd,7da678ee,6c711317,4fead9e7,c7fb5ee7,9b8f862,a3af320a,d97cd970,df12c0f3,84a3f3e2), +S(35534e77,c8dc6f7d,425d430b,b5cf4743,f3fed959,73d63a3d,771e5a5a,bf7da645,d22f018b,81b8f8a4,e2d297b6,f233e826,8fdc6168,4166f72e,2d89998b,4124159b), +S(6471c07f,de641ca4,b118958b,8ff9a9b1,27403eca,32a849c4,1b0ae1a1,b2d9ae23,ebb318bf,edcf26de,5d4bf68f,56fb898d,8c2294c4,7097bf9,2f34f3d5,6c535807), +S(9b8d568b,4f2879c2,1bfc95d8,1e97ed73,9bce2444,ad40156,7438ae1c,4b99c2ba,752531b4,92245df6,19251bb5,7071301d,f4a7f681,ce5ea509,18924173,7d00957f), +S(8a8673da,eb675829,cd5f3cb7,2c7434b8,d42c51d4,2fdc7a97,1681f7bf,4fd04e37,f2a66884,bb5ed9eb,f4e16864,3573135f,f65ad9f4,2203250,60b45cbb,1861a000), +S(b5048475,f56c6a46,db949469,2500bf4c,49b226c8,83576872,9524621c,c9807bb9,4727efba,45050af0,50b7847e,f5201101,591b5432,57ca917a,b9e6a210,20036cdc), +S(7d207c2f,40b9b31f,be509744,c325dfe5,c958c56d,92f43a15,511888aa,9deff6ef,4125af38,1e3f9562,64089375,965274a0,30ce04e3,9533b3bc,bc742b21,e6ee3582), +S(f6c8baf6,b2561144,47fd3cf5,a018b31a,846eae1f,a1d8f74e,59f315b3,43182edb,bf8137b,3aada7aa,7d582791,11d5c4fb,970669e7,2c160ed1,da9e1d1,4a2e2bc1), +S(9c67787f,84a714b,89a560f2,b876e92a,f8b2de18,6f8cf416,f5bbcb16,2e59d27,c0262b77,becc9f9d,378051bb,d2705bf0,92fd8a3d,b53cd131,aefc583a,b98e9402), +S(54d474be,7b58457a,929b9a7e,39e97b65,3478eabc,fde384f,681375cd,6896ff47,b8314502,4c1c2aa2,586342a2,f035baf4,ea086434,52ccf444,530b1c06,3e4ceed6), +S(e4dffb62,4132a5ff,6eeb946a,35f98c01,53b607c5,40811043,d1baf243,3bb23467,a580f3e5,d8d8e685,47e0c259,5e9c4d6f,a8616067,b3a437f6,ed43bb7f,a695edab), +S(d572f1e2,8f3eb14a,afe3ece6,585ee6fe,f49fce12,a2adcbde,d5f4a247,97c4a7f2,d9d268fb,2e80049b,b9a26309,69bc1692,c96b2d5b,dccdffc7,93305aa9,7011f88f), +S(bea4242a,5a5eb8a0,6f5c0cae,f38c3b81,4711a7ed,780e607e,10512d32,fb4aba82,601c583f,25936e03,ebc2406c,b248aecb,61f7ba27,894e4f17,46f34aa8,519546b), +S(e3179e2e,b6b92374,9c8f7ed0,40ff053,127a7d78,2da166d0,4639f55b,7cb74459,9a22f3ae,8df42fab,4b3d01ca,527c967c,7cf43f38,6a0d5751,8d47e7de,731b21cf), +S(8a973494,c8cc5c5b,4d8eb9a3,13bc9feb,fe6385d9,27112399,3c78e2e8,a732d4d1,fd2d15c,c9aa5128,c505fe85,786c55ee,aede07b2,94bf2466,d9845d3a,1596d8d5), +S(b87bfc57,7d8decd,3396f6,43200d10,946c0a7,f2d4ef92,4de7741c,e8acd653,62bc1f4,e3c0760f,82d953a,5d02a10,8ab3d0d9,53c463a0,295b063f,77f434ec), +S(aed2bbe,8ea08b0c,fc49c4a,4c92f63,2bebb84e,53027958,5b249cc4,c0ec61a1,76296846,a5391c5a,69df4e6e,44e9718e,622392b6,63a4ddf0,54b9e2e7,11a35bf5), +S(34fcdcb2,655b0405,2758c3ae,4f0bd15,2965dc47,9d7b63c2,b787adf5,6852835c,8b87ed68,30c88383,8eec48f,89a375f1,3a846f3e,ff0e8729,c1ad8e99,32cd4786), +S(f9586aed,be4ac742,2ad3b9f9,b8cece5,a52678b0,5b8ab318,1c6c2412,b470771,231f2be9,7b81431c,12539d6f,d247b4f,3d0dc8d8,15c2cfec,4526ab9f,e9cd6b79), +S(88125579,33848e15,f6c9d813,91e5eea,cf8ecdb2,1f55f4d4,1ff34ad3,a80e093f,d45c6727,c3340e79,a5256df0,41b4d999,e8910869,9620aa9c,bce6c3fd,7c17283), +S(ce1b52c7,f975a37,25f904df,9f602b82,52573170,96d4adc9,8043d35e,6773d354,17b65d8c,cfec6748,2a3c6d62,99dcc47,bfecad81,bfcb7d83,5f216f76,1ff9ba7b), +S(7e6885eb,5c8a5faa,6cd47921,54b2f5fa,4aa292f7,5fb16cbe,87c1ccbc,57501542,16a0e969,a212ae5c,6b4df92f,b3a510c4,c0b9ce27,c4f0f389,e77e4038,8c3cd101), +S(37589935,89c37714,3467b869,c366af1f,2d1566be,1ef950a4,ab1491fa,ed2ce425,2ab4eb91,cd533805,2020300f,b83a46ad,bb846863,6fb2a9c,c1e7c7cb,f3e56799)}, +{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), +S(28740562,ba21e3a3,69d80ec9,17b36013,8119b6b6,77b64cef,5f84f278,2fe5b3c2,2298a60,779ec4ae,86f9e0ff,7f981f2b,ea69e782,20927aa3,da793a10,3eb3d307), +S(12f64dcd,310014ae,81a7f6b7,fdcacb7,e8a9ec78,d28531d9,71ef3dad,af946fa,dde0755a,af7081cd,59da7725,e8246e97,2340c01d,eb76dd90,f0890923,54fb2d8c), +S(76134d79,133c485e,87a081c8,ce365757,f3beb361,c764220f,b16c1924,787cdf2e,2a77c2ee,b1cd5181,72101ebd,538d2f0a,10af3190,118da259,e4a53dff,d7a7b0c2), +S(89c5073,fa0877c5,50911355,475c24d4,bf8b8e38,8e9156fa,93021ed6,21429c8,40fe8b47,cdf3690f,63b3af00,efcc2aa4,b29c705,d04044f9,bb910671,b6ca995b), +S(bdcab1d6,157ea793,40f3bd0b,13365b24,b68641af,4e222d7c,b4efd8db,47b8905,b9d78e27,96820c87,850257de,746c6a05,5be5e595,aee8ced1,1dcdbca5,d92c5ed6), +S(da509ebf,2b7dfd80,d00c4c25,4b2e3b1f,df021d5c,cd1874fc,50b24141,2444e666,c3782467,e1606722,a76bbd84,dbdfd6e4,2cc41a10,cf50d921,d1bf916b,24459c50), +S(45da8013,3e8ee0d,f0a456d8,bad2d285,ab401f36,bdd520e3,c66b3d6c,925a17ef,4fd239f7,bb17c84e,3eebf9ee,c352fe82,652af898,f670dc5b,e1b9842d,9e593938), +S(d67ae553,58ac6a9f,cab9bec6,8a423738,bf7340c8,33a51cb3,2528893,24cbb1b8,d0b6ee57,e131ea57,300e228a,e1feaaf,55f1eab9,67a3ba3c,c403bad,b1dc663b), +S(6ab4478c,c8bdf1e8,7bdf566e,c24f4e46,a689459f,b002d0d5,715eb22b,62cbf077,331f13ba,e5be2960,97f8326d,1e4d3147,fc3ca83b,f4b3a4,56ae15cd,83d176b9), +S(e5d02a1a,3bae963e,9410402a,40390ca3,53d53a56,66ec6258,e82510f7,f72cc2c5,80379b63,2b5d4835,170bb358,c9040fe7,fad6b2bf,c7fd26f5,38acb1da,ba357453), +S(39acfbe8,48db640a,c2e7ac,86a1333a,ca94060e,fa88f0fe,f00d6273,74d79293,70ea1445,f7ea5f8,1148f42b,a37b2fb3,fa09f42b,9d2416ef,7fe0bde2,6e1e8f50), +S(1f8ce5d9,a815f4f5,d52c4dbc,7faf4f0f,d76a35e6,c2570632,6602bfd7,aef3b51c,3a2ec9d9,9ad3594,b223afbf,4d292f0b,88ef9372,18dc2ce6,e53df212,cc548e01), +S(5ee148dc,f4fd3d7b,b43532a4,8c782365,f944910a,eb235d67,f36642a1,b15a4581,898252a4,64cccca8,bc958dc,363cbf6d,b044492,248c0a96,aeae3bc4,26c67c93), +S(a07ec6d0,9829e04e,135566b2,d0d677ee,7e6bd606,21474cef,3e9b512a,753174d2,eb8dda9c,f3b44412,ae50c684,18453765,42697a15,33c84e78,fd75a8c7,11201514), +S(9069843c,36cca54f,aa3f5ed0,3c1d803,abd12955,4a5f8729,ced1352f,ab628d44,7140b7f0,e955a45d,aa2ddb02,846bdfcf,85163b62,718c9a51,3380b3dc,4ead8950), +S(69a98f1e,2677c441,86720bd,3b1cb073,9f06a16c,e43f7e0f,680c14f8,6540c36b,d52b75b3,a3005ab5,69041e3a,398549df,8f432e5a,c0d7e268,463b9190,191767ae), +S(c9297581,bec70b7c,55abfe17,95337b68,b99fb132,1d203a2a,29b82462,15e29633,36c4eaa0,5564673e,8ca1f783,82070d49,b8151afc,ec6c982f,2950a371,605f14c0), +S(53d50d91,1977cf5a,da1fdde4,7d44f6df,98d66efb,c858b92a,c490ee97,77c593cf,84db77c8,96dd1607,2c45c058,cf5bb2f,6435bd45,60bdbcf9,b8df71bd,404848b6), +S(ee15471,8e67e1c4,89d62145,5291a5cb,158d8fa5,84f7a134,bfc00357,ff578ed5,d9d90c79,3aefe401,c7017ff6,56d02ead,12318503,37659baf,f573c9e1,e4c65f0), +S(19e16e0a,ae3a4e80,ba0f66a9,7d415f37,784270e4,69e16560,7fe3632a,4bd8f1e3,6aabbd97,55c15f11,5a2e8287,b6fe91cf,659371f2,de5c86c2,a8deb96d,27037e72), +S(e93d52c6,12c07b0f,4f2f93f1,4b37bc92,3c3d7171,fad16472,146fb195,fd92f33d,933450e4,30e9c8ce,5a5948e,63f6d0b,40fb2ccb,adf5376d,4c076a63,9490ffac), +S(bedc3252,ab1e4676,63def49a,781cd7d7,98d01f3f,7cc1228a,9e396d86,7e8af12c,445c8bfe,9eac928a,b2d1d143,adef019a,7c243159,23a7b190,c763cbd6,dd305271), +S(28fd28e8,723d5c98,d978ac74,b070402f,3fc2315a,76d6c2e9,cd996b97,bad6375c,3ef59add,897dd001,4ef7441d,a62a8ceb,2c62b7a6,f5674ee5,b916851e,efdbf0d7), +S(7e8fc198,22ce5d20,dc04a61a,d33e4d66,c17ef03b,7fd53acd,e9c3e01b,21f3f646,ee5db413,637b4c88,d8cf2e1f,5d1d3be7,1d924962,38bbc30e,1769343d,9590cb3b), +S(b891fd94,36a14ef2,43f7ce7c,91d30887,34d1aee,8ace1fe8,ab3b29e9,2aabcb5,8af06c1e,ebf9bdbb,e1ad2f06,fdee27a5,4dc1c0a3,b08b17df,8e6ef7c5,5937c215), +S(236a16f0,21e85cf2,d5d62763,ef051bb4,c532dd26,cfdcc64c,2429f15d,8082d6db,bd24dcf9,f41f4c07,4fe6b6ea,450e3b9a,fd9c711f,b83ad683,43e65b13,3e654f3e), +S(d15acc35,21f6c40f,e7272e60,ba7b41ad,36351083,37683d43,4f9c576e,604b255e,7669301a,144b952f,cffb2e90,8d1709b8,87cec28,e7766930,eea8e753,2afb792d), +S(3b2c4a9f,cbd14308,fd612624,e5236b7d,4c363e3c,ab30aafb,a1092169,5beb3b78,69218228,5d7ebcaa,43db5109,46b93c22,ffcb7781,9c0de27e,3254ee33,3f9ed9a3), +S(b9f6b09f,a02dde42,453dbe34,b2388f55,4d042646,993ac018,5e7a6a63,2374dadd,7ee30f24,51683425,b8597189,a053a181,400df517,5934d2e7,cd00b504,484d9b3e), +S(f65baeec,e811aea7,a83f78f4,8e6db3c2,76fe63d6,11b4477a,42df67b8,4995758f,372ef8b8,9c75c669,7bd45ac9,68680c8b,14e4e558,d38e453a,2bd0c176,f6218250), +S(1f9d4799,d02782b8,f35db2db,eddb1715,e75779f0,82fd59e4,766067b0,6072bda7,86680af8,c57394c3,d50f2d5f,aab5d475,dec645fe,c02279d7,9366c450,bd3806e1), +S(c753e7d6,3dd4a9d6,384148fe,ed1a5f7f,1234182c,918dea50,2b44733f,d3f0c813,d80602df,ea4d0507,3b311a9,74be42ae,8e832f13,25790319,cf1a66b7,ac04c2d8), +S(6e294116,8eb1bc8e,55a0f2c5,e26b8b81,d6ecd829,5bb092c5,d0384073,c294e8c8,870f2e47,e00b9980,696aeafc,49adac42,32e77a5a,f5945f2,2f148d61,a9d4dcae), +S(eb2c36bf,298f419f,45fbbc61,7ea5738c,872df682,f537f965,3a58cab6,e38d2570,4619e86,3f2b9923,9709557f,932768ca,284ccf53,bdb9ef10,582d11e5,3e1afc31), +S(6ec36131,e3a55bb6,7b95712a,45ca3c8d,fe85aeb8,2746457a,cded305b,e9ba4607,6160727,f7b6db03,ad31828d,4b04a023,b07f1b41,209f4689,f126048e,21e0d9c0), +S(6825bfa,13237b39,277af3e2,1814e510,8fc51e84,abdbea42,8675ff6a,35881541,9f03c24d,c3bd1c1b,c45098c6,8f2ae07d,ccf7239,61c6a2b1,a3466d7d,1afd035a), +S(c8757c03,ce5f4fd2,2fc61bb2,e8f699ae,a733d64d,145c6fc0,58a68368,801fadc1,6601f2a7,e08e1249,5509bf1f,cf149459,928e5976,d7469e0f,e2e625e1,d9c99b0d), +S(5c1204d6,f1ca66fe,91b4cc5c,f2895ee8,2edfa489,a5b97205,808d9912,1e24a6b3,876a2e11,d790214f,d52fb598,ea7113f9,9ec08052,ff09035b,4169316c,82ba7122), +S(e0c03a38,9c612205,6b9688a7,edcc3869,5cba30ba,9038545d,33ddcff1,5f9b697e,4c0ad413,7a6e9b87,8ca914d8,31aa0371,d1bf770f,b73f1cdd,3d4dbd9d,d8fb4b21), +S(79c75424,ba72a99a,22802f65,56110084,e8adec17,355b2e8c,d2e7f8d5,13170cce,129eb5da,2ff02b6e,1fa41283,39ef9fed,3f12c606,bd55ccba,5809375f,dce59f1a), +S(8d73db65,e37a52f4,fc2b038c,56d8e371,450b65a,58614369,e1dfba92,2dd451e8,84458df6,859fd26f,ac74fda6,e7105d27,25b64fce,c4d86e9e,1dff0284,1d051d15), +S(41320642,e7de949,fc8fd03e,1b22a2ee,421bca4c,ef0e3ea,40411de4,962daddc,134f4f62,58c35358,cd33ff69,69a6b044,b36faf4a,77fb64ce,63289922,cff7d38d), +S(ae1b7bdf,21f2fe17,8a510982,f1d69a28,2f565cd4,9f3e6eec,d9412995,7b1652fe,6f6e9f98,45ad4699,a84d91b,9fd41a78,30b13310,c7f7a71c,9cdc4796,e1b33aad), +S(1d31ff82,2fffbbc6,1c3007cc,dd133dcb,624d612e,5d74acb5,f8370a8c,dd332d24,9fc68745,ee1f3a80,82efddc4,a01b75e8,6ffa49ed,698ec087,a9373623,61ae9d35), +S(f075d743,465437b,ccb185e3,c5456d2b,5546009f,79b3c591,d68e7c30,e5ddda1b,8c864d4,af8e89ea,8a1c5806,2c97768b,3e5b4c18,5f38af10,dd5a3d78,9f6cf73), +S(f9b07e9,abefdd37,a567598d,a23dd08b,7716c0d1,94cb24dd,3c6d6218,1f5fd2ed,1ca40c2a,69b92115,68e093e5,14312598,92cac6f2,c4cdfe41,16f287c1,71b1ead0), +S(14695d33,c187b712,c5f86b69,c0816fc7,cfd31486,e4fc0cd,b7042e37,cacbf5dc,9cdd12b9,c39a3237,c980047,e239b1c3,2b6145ac,853d331c,6f635efc,5cabaa82), +S(989cab0d,803b6665,33b78fbe,377d8db4,e1477f7e,6d962a93,7822e811,cfddb013,12f6454b,e88fc235,cb5f2de1,92404327,8b03c574,47c14fec,94538b54,68014a92), +S(88d1da3,4b47fb67,cbdb5eda,a463da2f,372f9605,dc0f0754,4a746ecc,a8409f4d,c2f2ae0f,38594687,7b814e11,333065b9,932cf4e4,1a6ea643,e6496175,4d46aff6), +S(2c6d9e3d,67e3a096,687b6c5e,8607293b,883017c5,35ff1594,aa8317ef,5e2fb573,678732ce,d618d76e,4ef02ae2,49485852,349cafe2,c9a78360,8a3d2c43,ff6a5d1b), +S(e0115fd9,be5488a2,e8383774,bf52b761,d75291e0,ce3d3fcc,aa642c37,66531cf9,49d36cfb,80e6ae38,d21be55c,3e885db1,fb773a3d,5c6827e8,7dc95ebf,9ac4cb3c), +S(1e994028,eb203a9c,da816a14,b08a00e9,7ec4cfeb,e6fba4c4,37dd1e41,68ed7a34,d7f4af61,ad4768af,959313d1,b5565c70,3581c4f6,b04cc1e2,bf27f202,36a6c94), +S(da12d2f4,1d60af63,a209844,1e5deb8c,1af51989,7a6edeb6,b8033621,1ac738c4,65561894,467e391f,c7de310d,fafa2ca0,c2d475a9,ddc506aa,a292d809,3272e70b), +S(aa3b79b1,4c5c6e67,ebbb8f7c,d1dac8a6,da3df0f9,af7c548d,ea0dc6c4,70830532,27a74ddc,79f6cee9,3bdaca0b,833637df,bb426cb8,58ad93e7,4fc1e285,87857cb9), +S(a25e2e8,942e3353,4a36ecef,62c71508,6f1e959f,627287d,f0e7dc67,6457acf6,3383132d,2ab2de4f,890fe37c,74b3253c,fee9265b,e2ef62c5,a755af61,abe00463), +S(c8ffe7ba,62d8ece0,843bd801,6c8043db,2e71d0a4,f91f2eea,7503824,1a3e67eb,fb507024,6a0e3286,8f6f6e67,7161b822,ac9d1aa,267658af,895cb9ad,4d94586d), +S(3352b6ba,380ee90d,d846c6af,ede2a9d6,de4d082f,46bf3a18,dfab2943,409ffbf2,fd6036e5,d7b2ff57,376967a8,42bac428,203b2784,4196fec8,64d8ee42,b7248472), +S(2ac42896,c815a831,a7b2d28e,af6a8c3a,803977d2,661fa36a,11143a43,7d179d55,2cc1490d,70b9f5f5,96cc8294,41fb5c43,44566d5c,77c651a2,34ba058f,b4b05823), +S(ac5917d7,64a4dd2c,a5c1db3a,75cf56a3,4a695e8c,ddae8c0c,74594857,cd48986d,5958f85f,f6794368,294d173c,14937aa9,eea64dd6,80dbb96b,c3e7b855,a87c92df), +S(c79122be,5424c0ff,728368c3,a0ef6ecc,3026bcd4,12ab1ff1,e3443d7b,dc2b46e9,2abca3b4,be4d53f0,40fb7d0b,3b28f4f7,44e4a96f,1e1cdfd4,cdcc7276,30332dae), +S(b3015fcf,1577fc15,337847a7,2b6c9bda,a7d6649d,711a156a,499b5e67,4e6a8ce0,2e826388,be577c02,f2fc3f2b,ca4f1ecf,546b75be,3373134b,1e440319,b78fa759), +S(b857212,b941cdd8,6f80063,3167a5e5,7d6fa385,c7ed08fd,9773de0a,4a481af8,aeb5aff7,329b6227,f614b8ee,1e2784a,ec5432f8,86d29e35,916ca3f5,7b901ff), +S(18f3f92e,a869ba6,9f64ec10,6e42e4c6,438504bb,709734f5,eac1a97,a418c23e,a9d95cb6,dbc06ba9,cf35b953,b0426ca5,167766ff,a533d47,bf40e55c,9e5cca00), +S(b6cde393,b06eb82d,ac45aa40,b094dd08,1a7b4bdf,f4a6caa1,7a1a2d9b,de336e60,81816d39,5db23bf3,9335c483,a50ee3c3,710217f8,9365a04e,1fc1cd49,20fdb244), +S(42ed0806,c78c2d5c,851f134b,341fdb4c,949c74c9,7522e681,81423a0f,64a6f1e5,fac85e8a,7151a4e3,b7b24919,828153c,237bbfbb,4a49607,a70f595d,9535d66d), +S(bad68afb,e1931a,63231202,69b4fbd2,a5b84ba,a951fa56,4ca07bab,d3160199,1b19d063,7e89fe43,894a2c4b,e8203e1e,cda6ac9f,f7e6989a,b1581d81,8c1f7ff1), +S(74c6a877,29197f39,c253450d,ed7cc4b0,948f1c05,3c91d120,668f09ed,f56eda31,e3a383c9,b0bc99ac,1eaaf1e4,47d9a088,e772095b,8a30bd75,dbb70622,44f46d29), +S(ab75cd77,a5800af0,9a2b4ed2,fdcdb6a3,d6b32076,ef5d9211,8dcdb4d6,acc25547,dabcf737,6f03afe1,6d2e8dba,e7634bcc,1cf0302,7545c57b,dbdc97f1,6bb1491a), +S(1951f597,1bf190de,295cd417,1ed7fc0b,6938e031,8403dfff,10434dca,9fd7b7c2,321f12d6,b8790ad8,2a956947,ef0a615a,76b6b678,5c765d8d,e9f04cf3,9961604e), +S(3095615a,6dce993c,646b7e39,1fd86117,82ee418b,cad9c9e9,413db342,45c76edd,9745ff66,fad21c00,68699f49,158f578d,b1ec962e,d288e008,cc667a95,95513fa7), +S(9b2a6fa,60b7fa62,f0cb6c41,91f3b7b8,fc0d549b,98520472,86abe23,4cea3c1d,4763f538,6bcc3b22,4bd2299b,92a10572,7a761b3e,709ab6d9,dc875615,43baa2b7), +S(df52e023,92e2a319,cfea1f52,c58a1039,27c14e64,8eba846c,faac077d,13493c3a,eaf8a802,9f682f59,295d3d,d44c11ae,537442c0,ac61e6ad,1971e975,5f1856d5), +S(3cf08be3,65e6164,6dfe3e73,83ca54bc,ae2e1b36,522da9cc,accd5ea3,4de03f45,d2eaaa72,8b2cc3e3,75bb14a4,4f52aa90,40df35b6,282c0b0c,df8c3a7c,8e75b435), +S(e7d92472,23f321d2,9a327ad6,4d08549b,e38a216a,d9ee8e1f,7dda5956,c65eaef1,d0cd5049,fae4996e,362efe1,f6019de9,2b57c8a5,fdd17a3c,a9cda468,e6a5e5d4), +S(fe851c52,f05568b2,ecbe964,bd80be47,98414ab3,c20fa0a6,d0b114c3,8ff6afa0,3170ce7f,99584c1,82fa6cf7,47197fe5,7f7f252f,e21a38d4,cefa09e2,697427ef), +S(993a0c6b,10fa1b82,8a3e72d8,89244094,cc60ef72,7f9f4758,53f09161,fda8a1c2,51be5ca1,3539c2c2,7a1d395c,3d89567e,cb218a99,3432a424,96ea7e69,95a6fb51), +S(ec46aba7,a6af89c2,7689933,2910bdf8,87362c46,a2a3dd0b,e1e6419f,8b2a2036,cca7634d,1afdae1c,d764d553,80190aa,96a5f444,70db8f07,fe59d460,c2a04380), +S(ac7188a6,8ecba28d,59c786e7,e127335,c332697e,2980fe52,ef3dcd2b,f8227c6c,e7ced64c,99c08050,fbcec989,89f99a7f,faf89fcd,2651d291,66f40c6b,3fba82d), +S(27e6baf8,f83129e7,14858346,ea158821,c474fe2c,fec352fa,61f00808,e662502b,84fa023d,3d371686,db30f0fc,65491b6c,d7a5043,73a08a5f,8d63f94,73f2cbfe), +S(4deb11fc,8f4610b0,c9875767,704d48aa,d55c06f7,2712d577,22f48359,38acb0c9,1769af84,c88f65c5,70df086a,e07abe6,b1a5b2fe,95da770c,ca57e11,4c6dedd3), +S(e2c30e5f,a831d62f,ce366bdf,1415fed6,574f12eb,c4ad36b4,d558081,eab8ca7f,6b76b320,252e2b24,a49da21f,f51207f6,cf2621be,992fe9e3,758e2abd,adafa7e9), +S(293bfb9d,d46baba6,8cd67e75,35e944f5,79690edf,4d17bdcd,2295d044,be309644,8c3777df,a3f4188f,4643b137,4cbc8d53,6fae283f,540d18d,514c8162,4b7af701), +S(adb8b1ad,d80a6120,e90ec376,14f08f81,b668cbbf,db85bc8a,9fb76881,f3feb2bc,7525e4c4,56995383,c9d5b8cb,b920130f,b9225012,a441eb5e,f6ec960,2181b070), +S(a03cc251,b299ce99,ced67920,11eca35c,87ecccc2,80ca61f9,b35f4fe0,8828afc3,34e992f2,9a8b7e71,804c5bbf,680622d9,536c58d3,316138bc,77adaec1,1f0a28f9), +S(e370ad9a,8a78dd7a,e7631e25,bc5ddef7,b5ee9fb3,449cc56d,3c77b12d,2450c42e,ff2d4db8,24f0f626,4f8c61c5,a3ab3cd1,d731ac1b,36503024,61f7c333,d939715a), +S(e7825767,be268da0,958756c9,c10a7f5f,a8b90b0b,f9279530,d5d60cb9,3cf9a782,e8a54111,66446979,5ad4be94,31d267df,9e471de8,9c2f386b,ef52c14f,85193030), +S(67768f1b,a78c76df,4f0e0ea7,ce2faf8,4fce8e5d,d43707a1,586354bf,77c5d369,a33cf627,c206d44f,79e3a473,a07051bf,202dbafd,cb74735f,1af2c8f1,27e4eb4c), +S(3c2296d9,a780ada1,a795d3c0,6bb3cc74,b00a7232,5c244ae0,57cb18d,5e0b8aff,bcabc5c5,2e1260d9,b14f9ee9,70b098f2,edd5163a,65b204b,fecc6a00,cf6c7f62), +S(c3ef3a3c,da7d376,2b128546,c8402603,7aebc362,c2a4d869,f2583418,2d8c8109,207ec4c2,6673447b,8d899e7,62104c68,3d0dba18,ca98c373,432cda8a,a6ffd6a5), +S(1d97f529,2fd92440,7fecb4da,a0baefab,15670b03,fd635cc0,66c078ac,fc35b80b,4457ef24,3b6c9e3b,e99d7a01,9d95b706,fc2530a4,7a88d11d,ee4083c2,fa7a9e69), +S(22bd1fa,eb1d343f,cbd595ca,f80a9128,c7b6371f,e5ac920,a31bd2a5,990a0a38,e2157272,a9ec6919,6ef17add,1855bdd,31097aa7,4e332779,9dae90d9,75155910), +S(dd8b69cb,a32f727e,e5c7e09b,5c152bea,badfec40,8ff36c66,5a95f572,82dd7b88,f8024917,d1678ffe,52ba97e3,48e74c0f,2ccb06d6,8ac7914a,378b7e5,a86dc3de), +S(2b3da42f,b0ffbe4d,69143812,a221f92e,496d381e,a420efb7,944fc66b,ee5eccfb,9299b809,47c26fb9,b5a3f004,7041f494,ad665c1d,ff304479,9fe0dedb,4ebdadfc), +S(98d2a44b,fba2fcf4,5b33a605,513d4c0f,8c036bcb,555f9142,3133be23,7e616db,70f5bcb9,b499ea99,aae3b8f7,f33169c,5af06f3b,55dfb8a1,623d7a2c,d54b556b), +S(37c7450c,933b1e12,8d4572b8,deaac8e0,80bdb588,ab90ffeb,f0d6fc37,2feb2219,ad0cab20,39622393,5d8a8ee3,2198ae9e,950be80,12b5448a,bc030b42,71920b32), +S(d8a2d303,8a0b0bb8,c85b0a07,79a88840,166babff,ec651b00,15c37f89,f11067e5,18200caa,7e7a67cf,e5c720c0,ec1f8ae0,ac083011,9ecced1e,b78802ab,30198d13), +S(c27b256d,eca6b591,c1e0021c,3d1da818,8ed96783,11a90a0d,41396932,f9214a5f,d30baf5a,3c64f47,4ce7d705,fa836a89,9161e75b,a0cdfee9,5f03c559,78024cdd), +S(b00215c5,b93cc894,c508a613,20debae0,58a3e4e1,d826e3ee,cbd168e0,384f82aa,469355eb,844e6608,7a390fcd,f43372d5,37389f99,33d240f0,3dcb0b6f,3476f0b0), +S(da646c43,2f525192,efe9b58c,5e41d190,f5ae5e36,9d8353e0,21aa9ff4,15a663ad,742d960a,863eb936,50a84bcd,5d4a1d50,d1243ccc,77698fa7,9135a351,fd5e9864), +S(381abcea,fd9ecec2,897a543a,d712bc1e,39a76062,b2d34ba9,8c06e7ba,6694a9bd,813cfc4f,a40bc405,941ca90c,73648d66,790e7925,31a6e64e,d432287c,24fd7891), +S(130361a0,1be7546e,57ce8b7c,c97cd06f,db4d2498,635821e5,d05cb8b7,46e7ea7f,448b60cd,668facba,4d56471d,d492e529,b7e204fa,778ed89c,b9ed021b,bdadd193), +S(95df1d44,7739e3ac,7e958445,1b269507,8f32d917,b512e4e2,fdb143fc,465ed004,5807bb76,184742fa,1745feb6,b3705ae3,283066ff,fbd0457f,720d2a2a,4931e728), +S(d9b612a4,a3074698,e06b2c4b,bd27b668,8c71b874,6808d245,188eec80,73292c32,b7e771af,3ca2ef2b,e3d82568,203f0a6,3e8caa73,d6f2fc32,17ad4b53,bbf6bbf0), +S(c882600,f804cc50,6342436,10b79f56,7c9d9276,948413f8,889a6bb3,fc16cf79,835220ee,694bd660,ff321b3b,d931d082,f6efba84,dccbef51,37492ceb,3c03e11e), +S(8ae9f886,4415cfb5,cbb8b67f,8076df4a,19c0aecd,82a63f66,ee5d1a76,1ca3ee6b,4e24aebb,1b507a13,fb1f3f33,7059794b,e81c5f13,4825806a,e7da3723,8be7c7e2), +S(70558a7c,756dc54f,337a3159,aedddee5,fbe3ffcf,5ebe648c,9d6c4c42,e56de4b2,67959da7,f775ca30,c942b87e,a5c7e2aa,5ee64254,4b600134,493fe07a,47a3ea82), +S(ec4bbb6f,6d88f798,832c4b59,d6e1ab57,fe559818,a2ee858c,e4273770,81c46b46,55933669,59789697,ea826bde,7929720d,6887bff7,4e910b3b,44bf757,a2cad075), +S(e7f069e6,abcceb3c,30d28256,50e8a469,3ac693a8,6ba5b120,fc827400,9f737e9f,2a9dc479,b3a7627e,3ca49295,7598d942,34f4bbf0,304c34eb,cfbfb662,1fddac1f), +S(54b175ab,7c18c090,2f0f97cf,4444f362,3916122b,1767fcf9,ec576ca7,5a2617f7,b5cb03e2,9a829c80,81f16888,3adfe85e,917e6525,8cdd4f0,cd3fe571,7adc6436), +S(da20f8ff,2b64cee8,7572fea1,21f98044,57bafdfd,3b1ead53,6fef24dd,16e08c2c,6e1898d2,b7482032,6b299591,376525f1,700ddcb,8e2c8057,40ff9327,2cee5bdf), +S(55244d3f,e177f889,3fa2e982,6ae89927,1b0bb5e0,f3764941,95a9e90a,8d1367be,abf46ed0,93f617b4,85d7719d,b4878968,ade00c3b,7c8dbc70,c21561f4,90dd3b4a), +S(a2c59a7f,d001bd82,48813d66,2c6ccc24,ad815cca,89ef749f,891a219e,956e931e,fa61c08,4a0a648b,5307e771,28a58d14,4d1084b1,58f1f824,f3d96d,d091346d), +S(d94e65ad,9f2cf491,192e5d1b,ce9d42f3,14c0a724,5c3b351c,f2ba3a3f,e70aec21,3d503a0b,df638ea7,5ffb2886,b3a9d723,2c427fb,d4921c4b,b1eefb86,2eccab8), +S(eb24a84e,aad08175,13705448,36b99c05,adc0e7f6,ae871a70,b42d24e0,a6287c55,3c4e2230,208b5750,fdf24d95,83d94db0,58e65604,d555a0be,372a5f4,a39858de), +S(69ca3107,a95583e6,c6b76b73,56b6a65d,2c45f0a6,194b69f,ec56efbe,289f8141,594001e4,46916b8a,9f977542,281016a0,8c8290e9,92e5e87f,fc16d49b,ca9f7155), +S(f7b24587,a436adea,15f6cf87,bc065d18,dec084ff,6f6582f0,3782a977,515595b,30391228,a155358,4b1f8b74,da91239d,89a4fbbb,93635cec,bc2453b4,9f355331), +S(16bfd7d3,572a6fed,c10a6e8,f6ffe3e3,9090448f,71884026,f6a16688,5f0f0d92,17a933d5,f2b3ed3b,f09927da,25331207,31a30a81,93681cb7,3bc0b2a0,c0b7f436), +S(dec8fca7,95baf9e4,379aa5fb,777777bb,178e086,1a738053,17f8d676,5cbbe9cc,99f2da03,32b83f9b,b712732c,e9b7ca53,b7bf6086,46c7642,620fc738,6b74343a), +S(f6b5b4ea,ba3f1b89,d399f6c0,eac8abe1,88a9cb21,9a9d4d3,7b578447,62f3956a,6cda2c16,8211c18e,8722e689,70fb9a23,54d09606,8e104c7b,5a6f6812,fb854a25), +S(2f547664,916072d9,2754da2b,556fd3cb,d9b67045,4bece334,960875f7,df57559a,c3c27849,64cabd54,6487f05d,45544b4b,bea58b16,e2a2e3aa,2105cff3,c8d0a5e3), +S(b98cac11,e194e80,83d39bde,8b28103b,d09bcf5b,bb163b78,33e00be3,3f52779d,dde188de,3763488e,7ddf8bb0,12291cf,848fc21d,25ad040,6217a8ea,e1fbe6e7), +S(1fc36f4c,99b540d7,a74dd2b6,1fd71f1,b095343c,3d7856c6,6febff21,b5c61286,6d165f6e,ed6343f,36dc761e,63f6068a,1a583086,cb76ad6d,a6996fd,8fb303f7), +S(13cc7352,2006a383,356e7378,cbe74e7c,873e1a8,c96f437a,995f5549,616dfa5a,f73ab51b,639aeff5,ae8deaab,e5fe7dc9,fe8cc203,ec66f16d,dd789031,6da8f614), +S(a42b8522,d7b620c2,8011137a,76719fa1,3066761a,7a612946,60c9fb3d,e37696e2,e0163b30,5f5500e,74bb9e98,c7f8763d,4cad602d,d01ee3ef,404899e1,1df9111d), +S(ad1e64b2,63b364e0,477657c4,33601197,61b2efc3,87c5b2f2,71befc20,279ca300,52e1f8c2,80ce5c76,70533ea1,4a8d75b9,e4e0ad6,199cdf0c,c570daf6,469e0a17), +S(b25ac32c,4406382f,6c28a12,f4e1b491,d7cb9a6e,2f03cbbf,46c26d95,d70b6295,db173a50,1d02a785,ab98ab65,2e814ec0,fce3ae92,e3948610,3141a844,93113f11), +S(507ddbd6,2908f782,9bd54ac7,948cea3b,ca3f5551,d5fa0b8,736ff2d4,a38440fc,76e3189,b588462c,93de2716,b5d79d42,8339a81a,1bc2d8b,e512e33d,5de5ecf8), +S(c300e40b,425d9391,4e2a8624,830f119b,3adb2e8e,d90f4873,46dd02e5,1ffe7006,b588f4f9,e9a315b4,1bc6484c,3b0cd1a,de816262,80f14767,9a1c3b31,1e48df17), +S(19d029eb,114bd8ff,952307f5,1e04593d,a4936127,dfc72bd6,8767a462,36b31b6a,e56c64e2,b1f14ecd,1f7dc29,be51fdaf,d859d6cb,78c5dd7f,5fa0f221,bec715fe), +S(b972dd3b,e3531c85,f1d9580b,8ba77429,747ad431,4c5a7947,3c54d647,bb93ba63,b1076055,6464152f,c5477005,fd6b4ec0,e8a73dc6,63fd6622,ffd31170,5ca7af0c), +S(148c6a57,f606ff5,2489a1e7,df84b1bc,11ef7b68,9cdbf0f4,f583be09,db595b9c,308e0362,2a681b0b,308f11a0,71742e4,f501d089,9f190e9c,239689d,2de198d7), +S(f8eff5a8,48a0b184,768135b,8c159bdc,ba86397,c38a2255,dd6bc746,549521cd,9fc518c5,d2bc6749,8fbb9ac0,8c22a070,e948321e,3b11473f,b96a67e1,2d788e5b), +S(61cb5332,ebb1b0c6,badb58d9,c15b8b1b,8c5b0a95,601220a2,a2fdb007,325b4442,fa90f15b,e1636b62,72ae71b,5711b43b,53580f04,86b6472d,e14737b6,8267242f), +S(9ad91194,210d4acc,b4f2fa3,f69f9fe5,707975f9,99f3e40a,9b766e7a,ae570b9d,bd770b3a,e6f6ccac,9d0dd1b9,bb5c451e,c27a8d0,ce02b491,a6c40afa,86067ce6), +S(d6985c89,71c21dc4,723540e0,9901194a,a898c0aa,33c4bd7d,34d74164,cb46ee8a,3c62000c,c8969f08,2dee7159,df6ce660,89e13b1,9c71674d,fdecb469,5e4eed89), +S(398e5cc8,4a90fcbc,1af56815,d56619e3,74e30023,9f95ed2f,3b0c3d32,fd0657d1,f82f5fe9,99c25624,9ebae25b,71946c98,b16cf462,cdcade65,ad22c608,7776fd49), +S(d5b3aa26,c2400d25,7032782,b35cffcc,902fee32,a28fdda2,f36eb3c0,1b19ea86,3f3fcae0,a7f0956b,2ab41211,a8941be3,358b22d2,1eb18b0e,c0afbf38,95e8e17a), +S(6f6e1cb2,3e212a5c,91b91407,7c90d465,eeb3c46e,74addbc3,ed228a1d,8fa201f,c11432fb,60b782ac,9dce6e69,e8a544e4,c5676f36,7c959239,c4dbf548,610b0f74), +S(23eaf533,24bda09c,ccf5edb0,8d0b5904,6c42f17f,12f64c81,54b884d2,239239e3,87aa0fe9,c37c0150,95ba3f68,96ea597a,a38f5a68,d8fdd6e9,a9eb4aa0,b6dedc57), +S(639f2502,a5f0073f,95352a3b,63982bb7,f215e0b,c80d3f7b,fc37d1b6,2ea89e18,a93481e3,8d78e490,6fe37f44,a198b85f,c6246f0,50d17193,f01962c3,c9351b24), +S(1e78e21d,4f696d89,b0b43eb5,e5d8cb03,46c9d030,65a4ee15,5f81ac27,b8fff65c,3a8103ce,e0d7e645,69e22332,911728ce,20793c12,c7d45b0f,3d840641,11221f8b), +S(1ece1fda,85a726ba,49bc7ac9,23e1599b,b070e8ce,134858b8,cb4d714f,2b539ff0,dbbc6f14,fadb9d5c,559b3b2b,df070bba,11d8777c,b5526bc9,ac951dbc,9815863f), +S(e49e79ae,f17ff1ea,b81e3c47,97310952,6dac7ac4,ecba2a57,85696de8,279af373,92b0fb30,368189ef,dacf5e40,1ec4dbd0,a4ef28bf,512167bc,42f63cf8,a7f6ba73), +S(ce0bec53,1c1eaeeb,868bd283,9b37c225,fdc90d0b,d6d82e58,20516b7b,9c9b81fe,9ca80cac,80100d58,68fd1bb9,b174b0c9,54d17492,12ebd194,5bbd526f,6f842b97), +S(df282fc1,b4fba7e4,fd75af57,805d93ce,af88590,3b57cea8,38f5edcc,2e7efb52,27487ea3,77eebb18,699eff2e,66909c2d,9daf7f0e,32e13ac2,17df0d1f,b8701c33), +S(e82d0d6e,29b68dcf,aa8ebfb,4d8d5f70,2d6a91dc,b10c5c3b,c7363360,6c937510,ce1dd596,232791f3,7efdfb4c,7da518e4,c98e8f02,d36c7230,3cb3c52,69bdab85), +S(cbf085c,5316258d,6cd5e721,b613f97d,7e22cac6,2b832bd7,e2830f34,2f748f20,a5efaf98,97cfeebd,b07bc80e,417e73db,bde10972,57684543,151c1940,a92f7e68), +S(dfd983bf,84da8670,1a475a89,66569aa2,59c36fa7,9a5f5142,fa62cf34,105817ff,91973764,28e0cd11,11b8ad8a,5f41d6d0,3ac5b930,5701d1a8,d621da05,16e6083e), +S(e89e41cb,5dd179e2,ecb2a48c,af7f3dbb,d4d9fb3,78eb0822,6652dfff,593266b6,7dcbd3a0,765dfc52,8244c19a,df657719,6ed46b1b,2bf62042,949f0f57,df872d01), +S(20b45025,780c01e0,e8bc2899,7f59aac4,ff9434f6,bf4ac433,39096769,f3e360da,4bec5654,5409a944,c68f0942,a1fca7dc,aa89a2a0,4ca9d6b9,b325eb06,9f7bff95), +S(ec4820f2,955c17b6,81381e12,8acbe1e7,75669f02,8517dd41,f4723d3e,64d75bb2,41ed16b7,5dc65672,eef6166a,b86a419b,ceddf23d,d365e63b,578388ed,bc6bb8fa), +S(b15cf70d,523695d9,48dd1f7d,2f2a12cf,aef60bfc,93a79410,2678ce11,c4233424,63b11e19,1335490,8eeb94c,6bbf1875,f867cc17,a599e83c,2aaa4553,47d549fb), +S(d9e85a98,5cb2dc07,790b0db,1e5a43b2,a51b882e,846bcc2a,8c2930eb,efb79f6f,482abc51,54846788,1b8551f5,e0162ba8,3ca192de,1ca4ba97,19ffdb18,57583b57), +S(6d8dbc0,cf0b7081,c03e9bcf,16dc7445,3c9eec0f,d21f82c8,d05c70dc,bf61db91,ee91fa7e,4f5f59a7,5841d903,ac0a3f0b,68c837d3,aedeac7c,bb9576ef,a7f7ece6), +S(b12c9714,2b5a8ef1,cb2b0cca,9316dd0e,7969a2bb,f7fa34ab,4cd412f,dbc500b1,690c027d,e9327f7f,3f761509,c57a23b0,b2d7cbc9,e5392472,8611ba10,7e5a8e61), +S(970d6bb7,2dac2f5a,7588ac62,31a7425c,aa120592,80f4cc54,19b55126,ed4f36f4,3f541ae8,2186eabc,562d3e1f,7492a8bf,68e45210,9e5d9ed1,ab59aaff,9dcbc58d), +S(41605872,337e0cc5,f9322c5c,a4dc3e81,40b8bef3,b99c1285,e0b5c53a,d08d25bc,3a52bbfb,d18d532a,53187d3f,f9140aca,38058be8,ddcafdf3,83f4204,780fbb56), +S(4889a88b,7e9a5d65,bc564fa1,12a6318e,564c5e39,4be6c4ef,875e79e,f33358e,e0757939,a788755d,c54469d1,3e82d9e,a9502478,3dcc51bb,8856c5d8,629b1da3), +S(90ac2fb5,a463523f,ee81a501,510874eb,ff69456c,3670decc,2d14b3dd,a1bc284,b6f10a6a,c316af7c,dfbb3b7c,6aa30846,10b2f44a,1e415fce,d67245d9,72d2fc63), +S(9286dbdd,9477d600,ba2a941f,e467ee8d,9a7b114c,dc42e488,8648854e,febc5a1e,5ef9e3d0,ce7f522a,c5a1e46,5281bf98,a63623dc,f300be6b,d01df5ff,6661c68c), +S(6b774b76,50623f6d,cedf0498,683c05b9,1de486e0,5f9f64b4,dd13b0ab,eea0c53e,a3dbed6e,ebe68c9a,86468874,ef2ef5ff,3142266c,756b48a,3314698a,c4a20162), +S(e5335352,fca65cbb,8fa6e275,ce8a0432,d7ddbbf6,f8854e4a,371b07c,909c42b2,30fb3def,31c8bf51,8e2542a7,83736e7e,d87f1c97,70465120,47faf3b6,7764d77a), +S(f87c5b0d,a8edd93a,bb33e606,1fc34377,54a236f1,44bc0ba6,1cd26f91,86ac75da,92434741,af204fee,a03027ae,1ee5eb45,82769d1b,c264472c,dfdddcbc,50065424), +S(dd9d3fc2,96eda501,3886376c,88af214c,3a4dfc9f,eed0776b,287cd32a,2fddd2fd,32e630b,2da6114d,f09ff5d2,eec619e4,48f849df,399e5e4a,e802efc1,dcad04a6), +S(10108724,51bbc5d9,b045666f,fc45ccde,c29b3a10,60ba8d76,5fdd1f5c,1dda495e,c86404db,ff9aabf2,599f6c35,e6a8d7f1,2654844d,add8c787,86158faa,b10b5f85), +S(22f7f223,9c8fedfa,cdfe80aa,84477ca0,df289636,2f055eea,3c63bbe5,58443a98,661ed060,8413a4b8,775b9916,14d848d0,269dc75,4d2ff2f1,b4a18fa7,ef0e19f8), +S(9a1ef62a,7567f9d6,9d45edc9,3ecdb7a3,1ee6793d,a2d387a6,304e0185,3416ae70,81f8527b,4c9fafa1,b2fdd185,57998861,4f6ea270,463f8261,814d190c,80f93f4d), +S(b04946f8,8b0c5fc2,13d215aa,53e3d90,df45d13e,bf7b665c,d41ebd3,58cbe5f4,2e92bad0,9b485af3,904446fb,14fe3624,c447e72b,41519297,133933d0,b6191869), +S(aaf764cb,7db7d191,c2dd7061,c213b469,bc270677,7ae0ce31,b0a3f6,7ec26728,4c4f42e,5ffb9d8f,e0625906,b17b7857,8afbd773,834e40bf,c7195f08,19aca859), +S(a236de9c,e071504b,e8108d5d,f5cb7ffa,d4a333e5,1afb1579,2593706e,fa04efc7,773f065a,227634be,3ec7d3b3,4ba462e4,d50f79ee,19541896,948ad725,c26bdc88), +S(3794260f,302e614,aa700f32,e41a0ee,c772d549,58b11533,2b7de77,925d7cac,d1896d9,7b5e2ee6,9ab7e55d,83381ad9,bee1b87d,d3991f53,4bb67237,830e8926), +S(a2436b37,7fa45dec,eda48686,e0705068,ea607b24,58482794,aae3345f,353f6329,e1da48be,8cc2c88,5bae924f,df1a328c,37f96261,3470a841,7784c4f,b965e05d), +S(f9616f77,6a125158,7165411a,582ccc1,2317e260,89412bb7,5c2a63a2,dbea5658,39a790f8,111db9b7,f3b69bf9,9d0982c4,6d97a18b,c937e6f1,3db36ea6,9d7471d1), +S(4a720ef3,9c907f62,720ff0f4,c5d193df,c9bd3613,6f49f72a,69aaee15,b3b7fa42,6ed9eea,cb95af1a,5b91bbe,27ccfa4d,f352a227,67a250a3,179f94e4,bee433f7), +S(dea00421,c07efdd4,24749981,713c1c13,fb23f974,fdb37f45,35314d22,b75cf0b8,2e91b078,2b3dbf41,3de9f98e,e421ef30,bad6cb5a,b57e457b,272f3f46,7709aa32), +S(7e14f09f,f55a0b2a,88518714,68340514,903b2ebd,3525937e,2b0efc79,bb1d7b41,30fa7849,3660b715,514b7fb4,5aa50324,a7958bfe,4db78914,966340ea,c8ea96d9), +S(6536425,5ab57582,feeb109e,7a9657c4,dfd8fbf7,57be61c5,a769ae58,56ae990a,bee94b18,61d474d7,40674349,1b875022,8eedcac8,99835433,529a1621,bffeaab), +S(8448e3ba,f77574f9,2bb731a8,d0d4d3f3,21531c7d,189ba5dc,2edfd54,78ecb11f,425a1eb3,727a5bea,478b82f,d9fb7c9d,b933a7e,8283e897,d1d21ad,2281d39b), +S(d2ec1adc,1d30ab11,b1ba87ed,7765f848,5d097e83,3ffaa26,2eb5aed1,5778ec35,beda7397,61ff8a32,b0965b47,55c186a3,8d24e8cd,5dad81b5,4a106abb,335c3994), +S(3b205375,ae0ddf7,c2dbba5c,9e14b5fd,e8899448,4ea0d82e,a939e1d4,f1d8dfa,bdab6d0a,8d1db118,785bddd6,81c3a402,460137f,f4f1c26a,d940708f,969df70), +S(eef96785,6012f0e2,5934efe7,b9199255,869334c2,59a62384,f2cc4b4d,6f5865f2,1806efdb,ecd0588,17db47ea,10ed1866,6bf0e9c2,7a2bd661,91d92d1f,4ba0a9cb), +S(9271ab48,6a17d2d9,c91ef3f8,73c74d6b,754bdfa7,67172cac,53ea741c,e101abd3,4ba3ed7c,1ea7d0a5,5c4ad38e,cd032e5e,782b69d5,3ade655,a8d8354,422de96b), +S(9bbefe44,70872b67,3ce6afe2,43c32b8,e2409b69,b57f15b8,e1d2b4e,d0e760f6,a1c6f4b7,cab89ff,ea846bf0,20ebfccd,77e7ad4c,68a8095f,c9b56a5b,f57e4dbb), +S(cbdbadd8,5cb42d34,cf249e78,1929bc4a,90977ed3,e6c7fb4,5f0713b7,3e3ba051,1b2a60ba,9f4f727e,c057d149,2ac04e50,42fe053d,89649be9,4fcff26e,8d3ba7cb), +S(414eb1ca,a37e098c,6d4257b3,a9e22047,652e5c0,e4872547,7e97a2d6,b89151f5,27600f8a,b3b66f86,6e6a712,c8d2d557,736b9f2f,3b7be72d,2783a5af,35cdf7cb), +S(be0e548d,4302918,60ac6c47,4593a5f7,169b3eff,c9d18878,6eccd511,e1f195bb,fd26af99,8ab759b,c9a83d54,6296efe,cb0faa62,eec5a7d9,98a0d80,e36a494d), +S(ff38855c,7925713c,80c0600f,7cc3e60d,9aceb7d4,b1199d75,2a83a67b,6b1dec1b,e42b3d08,f12b19ae,600479ca,b593fcad,bf680fb3,da54a1ca,d072d1f4,46bb8989), +S(157631db,883dc9ee,b5b3782b,fba4e430,9426acbe,5ed06fd7,662f06c7,c776e829,cad1de8e,426da993,4a8e573a,5e041952,4b3a01a2,e29049cd,c9439de5,c5cbc4a6), +S(c758ec6f,4a7d15b,efa56470,1f8a2278,ed886788,1aa2a772,c20fbff,ed05885d,e3e80138,4758c6bc,60f10beb,7d75e7c5,d0a541af,38ddde3,b7c5f709,34fe0ddb), +S(e20d3b67,cfb8226b,7b22bdd0,87044f7b,5b29a277,bb5286f,80093eed,69277e67,ce6a8a7d,c1bd236f,961610f0,15a9cda1,9ab85200,abbc6d0b,9a041ee8,9d97c743), +S(b1d70b27,a855ceea,149c0508,2f88d465,6aac5541,aabe223e,4b13028f,10a2aff7,4df082c2,87170b69,88b05b37,1d4b5181,773741cc,70544f4d,7d3742cf,77884caf), +S(f30a09e5,9c163445,5f231a0f,52d9e6b7,8c336b07,5f1ee6a3,bdfd4cc,1bf213fc,acb8bd60,eb919332,a405023f,c799072a,a2838dbc,7ef8d042,7417d61e,41c6b00c), +S(8a615da3,f0f92f20,e8dd5ee6,23178403,ac0287a3,93173dea,1bba53cc,2cd268d8,bd7a5a1f,ac8d4157,6b51f9bf,ebd581b3,ebf470d0,43731e4a,4dd391f9,423d32d9), +S(14d45568,f9b4e6ff,f8062209,7dd34f36,17d3fce3,e5357ead,baeeb480,2a43e7f7,25e65c8d,50296272,718ea121,cd5a1365,d134a134,fca3a5f6,324d7cb3,85f9f163), +S(706f64f2,a7008aa5,d3eabb07,b4a3a3bb,f18eab6b,cf605117,c70cc0a6,280e2084,cce06389,bc03b45c,cb235c88,19639a27,5a78ca00,9e99978,236411bc,687c93c9), +S(db4f0639,fdf573be,8d7d4f84,4d8f781b,51731003,24343be2,6c8805ae,fed3b91,bd1564d8,8abe4aef,dfe581bb,3673f874,38248b1e,7b11e019,6e158bf0,5cfbebcd), +S(43e3c600,4f3cd3e2,aed372d5,60348976,f420d1de,95c70a4c,eadbfc9e,df393d32,bd09845c,429c91af,9e9b3441,321c68c1,888f8c31,15960131,85c90bd8,6b9b30bc), +S(13192002,45d0e72f,e9f289f2,d9be96ac,ac2f1adb,37716658,700aae4c,91267ef6,864b391a,aa20047f,38308f95,e42f4976,494e1a35,100affc7,2d435f85,f936a039), +S(752bff23,288a0554,7f048770,da6abe2,e70431c4,60a71765,40b1c124,89ae7383,aa2af83a,92ab2a29,1c5f89e6,61a18075,d6c3e8cb,ef6fc0ae,c283e77b,56fdcd5e), +S(af0f3d24,25247b8,cbe6e377,ed72afe4,420a886b,aa995671,d638884a,ac238fe2,b7fddd96,86bcbcca,f363b3ba,ad214771,edb9a392,1bbfa25,870dbf52,a42e9622), +S(6be310a6,9ad4a56a,cf79630f,e8767f0b,c986eeef,609eee6a,f1a34657,89c3b93c,2ac934b6,f549d51e,8bc3342c,9fece7c1,c79fc301,bf006cca,20e014f4,b1a9c768), +S(a53b9a96,e9d44aff,ff7f4393,ee691d30,ca4a115f,60267b16,ce11027a,73a7ef1d,d70e70af,5e8dc02f,b3ad170,734e8b13,8567dae0,d73f9754,d6070563,8abfe3f5), +S(e782675a,5a2dc77d,383e8d03,fb2b126e,5abcc07c,391e5597,d127e60d,bd33bb45,8342ae33,fac4979b,fd47d5,b9b40d85,db40f79d,42308ef2,4110b7e7,7dd842d6), +S(eed988ec,3da0c2da,b7235b89,53ce7bb9,7ad8c4b3,7ccafe78,adf5f2d0,911a11e4,b86c5a28,fcabb2fb,4f1c83a2,77174144,b0eb86c5,aec7c52d,59b624aa,38bfff3c), +S(86783a2,5ec820bc,44aa4aff,85212dc2,fb169f73,4b3f359e,844fcf55,abb2a991,6addad83,3d08b1f3,3640ccab,4a68f35e,6ab63752,9f562c11,3ec46833,66e8da1c), +S(3304c750,d62d2678,beeb4c3f,55414ab4,f9507039,55da35a0,193ce243,503b1400,7bca1f1d,87c963b,b2ca8a41,c675b87,205af0ac,ce3d458a,e6ab5f37,fd000694), +S(cd4e3851,b2ad955f,e42e24e7,c071215d,9c4cd24,d456bbb8,452aeef4,4312532d,850be683,bb89207d,62663852,e5b1a38d,d5ec8fcb,c11944a2,adaeec97,17db7bf3), +S(c32114d4,d0c47f05,c31f859a,d26895af,8d46fe98,7565b2cd,ca7363d6,c07cf256,80cd894f,7869eb3c,7df5c5cb,279648e2,adad337,d4f80f5f,501b872,c8b7e9cd), +S(ff6fc809,143454e7,bde3e327,bd7aaeb5,6e7c8c33,93137be5,e63b0ad1,87f3fccc,75aa0f16,ad2cebf3,b8c0be54,aa991dbd,83789abd,214e36e3,3b29f06c,226d0e9), +S(64f9456c,b7b73a61,d9e788d,c31369f7,32d0e34c,5b763e9f,bfaf83a1,4890a8e7,778c77f3,fa3b7edc,afb39532,607bacb9,ed2aedc3,7734b191,ffb5b8ef,867414d5), +S(d9e41a8f,2ffb8bbc,52d10aa1,82d9b0db,f04c0326,8f45d531,500d13c,e25f3d54,728316cb,f2927363,25bb3d18,15fd624b,53e6b442,693a29e0,8d2c98c2,ca524a3), +S(b5a615d5,1241e064,81421f21,45ec55ff,c953769e,74f5c96c,f760d085,2551644e,e2889361,fa674a81,92358a00,61e7b210,c51f88ef,a442b849,d049ce6e,6e9f26eb), +S(5a0c994d,18e62a9a,44358a14,791f4a22,457551ac,5b931fb2,1856928e,a00f15d4,5a706762,8f5ca41f,7df823e1,e27f26a3,de85ad2d,cc2598e5,d8238a0e,587176d), +S(51deb73,6840951a,a0e44ab2,da2a62af,15aacfe,c2740819,9c57959e,10a03fb5,4a0a72ae,f05886b0,6c03b91d,68af04c6,818d5ca3,4e278b6e,d830833d,c15745de), +S(5d967cac,ae97fb90,7f2b8da6,9768a0f,e8a56c52,e79ed9b6,ae4e9a0b,fd92e51e,d840c983,bae8897c,e443d9aa,874bfae1,7475d00,c0728dc7,5090400,47043ef9), +S(2e71c7b8,e187f250,bd500b91,1526f3c9,154457e4,35085672,8d2bc76c,c82b8714,53d13e6d,51840bd5,3e8ddad8,6e6479a8,7b756d57,bf3e9658,c0c0f434,5da398cd), +S(c45ddde5,3660689,113cab5d,f4e218ca,159273e4,db18fb12,d2d80397,1892e9b1,e3bfafe9,fce4db8b,a68a007d,f4c6174,6addc8ce,13b63537,472a2672,48f9203e), +S(4792e0f,2bb7cc27,c44df3d5,b3dfdab7,319ee762,812ff2c6,65da6ea1,2548110d,d3fada96,78c437d8,5d9d9577,3e40ce3a,7cdfa6d1,3e7f4db,17e6502b,b17a71ec), +S(ba662d39,c5c81e15,8ba7427e,8c0633fa,e8e9ef04,7fa408ab,3836a674,328d458f,48ee6efc,f0789fcc,901cd9cf,59fe6d0c,d3212180,20f90f22,682048ce,ca9f1138), +S(be51e863,6aa87c9f,d348a0ad,a7bec639,2ebf2ab3,d4cb68c,680ef1ee,6cf6e806,71ff99cc,7f6cafa5,90bb218a,cdd62880,b19ac007,8f171c81,876370ca,affaa70d), +S(75bac33,bd6578e7,c1afb10e,3521cd97,a51546e4,eed4ad4d,e70d5348,755003a0,5d700b34,fb93c9df,70f0961,bf5902dc,c51c6ed8,163e1fa2,6972e474,9b6da1db), +S(d7647193,14152aa2,98572779,1d1120f3,106a1397,3b964b93,8149694a,fc584bfd,6fa6bb33,a75c0111,cd6f1b89,177b419f,d361676a,93d0f7a4,61c6ce99,e667d6cf), +S(9ac1d334,59882a0e,bce90ae,1a404f61,35e9465f,5be0ebbc,61a479aa,f348800d,b7195d60,a7f4141d,145fd1e0,a5e58305,b1610ec3,4f97b09f,d8a8e57c,3041f05d), +S(bde59b,e8de3bb3,cdc7f5e4,1743a489,eeb99171,a89bcba3,5eae33f8,cfd94d2,208b222a,5831abb,e5f343c6,761343f3,211078d6,ffd59690,9fc976bd,86f6808c), +S(58f7e872,6a34f41f,3720b5df,38a3df88,58d2238d,e60a88da,d4198326,f5e37ea4,13f8cc5c,ea43a637,28c5cb5e,b4fc5381,d5618b4,477758c5,4dbce46d,ad7f433e), +S(fe6d09b1,93d1a7c6,c5d5f6f1,522b63c8,aa257503,9add5cb2,21d5950d,3c4bec93,eb383e15,24f52785,6d8535e3,c6f2f8bb,deb71907,b6151510,a4839b05,7e3e6dc5), +S(8cca7fbd,d0a041b3,e196b08,353c704d,96db3817,29d42f4,513ff5,467ddd0e,23a0dcb7,dd044a24,cd9202c0,4c32cdd1,fd25c979,b0a1aa62,67bc2321,ce7a5f1), +S(a63de000,cd76bc93,7515a124,a334719c,bbd4538e,9d04791b,2b0de33b,bedd2bad,4afe72a1,d26fbe8f,8f3951dc,1dbecff9,c8aaaa9c,bdfa03b8,a6c48cf5,764f65d), +S(5a42a678,c32a688f,e7cc9688,9f93078,8b5f0126,f1eeba7a,c585b1fd,9f97003c,4117bd18,e961dac2,d15be023,6e1254d7,eba89a0,b4ff95b8,82bffc4a,7a375f3e), +S(3c01ac6f,1ba11409,6817408c,5e6191c7,d401f258,f0345c8,6b0c83c6,ead7ce90,f39943df,6465cc6f,792a99c1,b2c97727,421fc8ef,11b2cb9a,cde28709,628efb9f), +S(ae63ac2d,78e0ef81,312fd73f,105d8ecd,8d5777d0,75d06600,da8f5b4e,3e20a8be,50ccbedd,e4d4241b,bd62c0ab,68b2322d,c0e55c28,c8f71ee0,40dbfe6a,d7e33d9f), +S(c793575f,b3ca9516,945bc82b,aec1114c,5d8f8e0d,7cecaac3,31e209f8,22d01044,b2d3a441,ab01f822,366728eb,dc843b7a,82c82175,fd4ff08d,700a2018,48766b1d), +S(e6438209,26baa22c,e33b1588,1b5c0192,b14e72bc,f162f04b,5e6d5941,8053e338,90989550,9fb4a05,741ac6fe,bd4b78d0,15710c50,6c1c3adc,955604a3,1907684d), +S(5d9b21c1,3331d32d,d7827982,6d41a5e6,8ae70be2,b9d5f346,a82b8ec9,aa559323,6e086fdf,95f4a998,66b3f471,f3c722c7,4da8c7c3,1fd65705,68cb434c,1427e5af), +S(81ab7527,8cd4e683,f127e7df,2153fd93,60bd2f07,32a506e8,55f60082,7fabec86,cff8b01d,24be6850,6e068910,55a5125a,ab7a554f,81e5e8c6,78348026,ee7248fd), +S(4684137b,1e19dc84,8a521ed9,e6aa7747,548535e6,6b9fc1b5,a533c580,e7546317,8c2f57ae,7f42873d,5e3ed228,a9276a9,cd684c42,c43113e5,b465cf7d,eef75911), +S(3844877b,e43eb3e,171f614d,7a56aea1,4615ce67,b09bc928,b6a16b48,3c15639c,a2e17211,48d95e9,6690d982,4a7bc84c,c3f0388f,e54e2546,9b58f624,c3761634), +S(d4246638,80a8efb2,99d3d73b,4efd73ed,5bf70111,2b5cde7,631067fe,2b9de212,b98986a0,229fe086,c91b2a3b,4373411f,baa31c98,7f475ffa,1c29ca,93d4b80b), +S(515b8ec9,650c5448,6eab830b,4ee0bd7a,4525c8eb,19520c3c,6e6a214e,a7861c47,a7b12837,51812bf5,c37bc48f,ce08de95,94e4d619,18726c31,57bd660d,80025185), +S(4e499a52,6352b7b0,3d78af31,5597155a,eb4697b8,14ff1d5,93b9b838,6efaaf8c,bd4f5e6b,dbe5a232,c42b0ea4,e55f507f,2ca33587,349b1f0e,56a25820,60ef57d9), +S(2c9a7cf1,553e2593,c455a8af,9b12a0c4,26d579ec,6a097483,a7274edc,98dddb99,99aab288,24298866,f0f42672,395d39e7,338aee86,35c4cef4,ba45f067,83c8c8ba), +S(7d5bdb5c,fdff2871,23a9b78f,3ce189d3,ac50fd6d,fc49bef5,953ad197,8d27b0fa,c76a17fa,97ffc25c,8549d7b8,f01842bf,34afe80a,27be4c4d,fdd68229,2dc83ea3), +S(fb222262,444d6db2,43abdef2,9e0ce41b,818a177,db630c50,9340eef6,24070256,8a42ddcd,a7405cce,9782e8a5,23ab108f,3e5be176,49910b24,c8084253,46b8596), +S(b3212a32,2e415360,62622dfe,43da56df,4beeaee6,b8b5e783,df514a7a,83eed60f,c9396626,6dcc8af7,56efe8ca,e86a7b28,4b2e847a,8e571911,cae76e05,58fe5417), +S(80c90758,1ead4640,94ac1b9,3250b9b4,caebcd74,582bbf20,16f013da,1f4f01cf,d42a5504,c5be0a40,e7bc4242,32a9d703,58370eb5,a54be08c,93f43a22,6e5e6ad5), +S(50d17433,50bcf037,a310a05c,59adbac5,e2fcda09,3aa6ed87,9340efc8,7ce0e228,9e733972,8e88d9cd,8a4e9e7,7dbd7b49,114d5a71,6d91088,df928d60,743bf2ac), +S(c8e7f596,3faec5a3,a32d1ee,65d1596c,a7edc87f,486a13d2,c7ca7b84,3b358cbd,37250705,1891b406,34a9752d,942e6ff5,67fff1e2,d67a88de,ce79ec56,97f5ec38), +S(91f28714,e47e051c,84bb29e2,db84472b,e3b78524,c998a071,731e4f41,9b94d2b6,8ea1eaef,984af3cd,21be9097,99f68033,7c6e3479,643e0c68,b00963bb,d0125f0d), +S(d50a1905,ac4d2195,5c2e6733,5d38a08b,26e29809,674e1b61,8004d18,f823f402,83cdc5b5,33145488,35884fbf,f14b8e5c,35c1ffe9,29fc5222,c7e2a868,d5906827), +S(c45086cb,387b9bc8,a1d7b71,ae74a87b,50ed90e3,a0027766,98f7ad4d,809666b9,1c0abe25,d46ab7cf,dc4a5ba5,e3fcaf27,822b5f0e,1bc08af4,452be7ba,d480e605), +S(b486a681,f9b26f12,c67ba147,7ceb43c0,90539587,72dd1dc,15cf1e74,9fe3856b,f4bd7623,fe97b6e2,6f49e292,899a7f4e,e7925cd5,3fe51cc4,33f77d1b,76291240), +S(c7563596,946f57ae,f91d12a2,4dbd2d0f,726422e2,ff6ea15c,f70c2e7,868e6f8e,566fef1a,aa3316fa,e935adc5,bf1e9682,e3d00e24,2bb57e1c,3009e6b0,df58449), +S(6d0b65ea,265366c1,7740e473,f823ad65,f38081f7,86156199,421a8b46,117b2733,4b724837,8748545,c6d0511,79d22b3c,61932bc3,563eadc9,a8edc5d8,1c170f5f), +S(87973dc9,379225c,50366d92,f0591837,71828fb1,d1d3a65a,20edb955,c2e48414,bb226cc0,67c7fc4d,99791a74,301167e9,62e92498,6ebb0fad,fcdde6ae,8c39223e), +S(72e7347,cf657935,be5939bb,648bf628,6a2e870b,cdae70ed,bd2c499a,be83191d,431e74e6,bccfbf3e,3fdab221,e2274a77,947d9cc3,5bc55c01,afa2d33e,8234cccd)}, +{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), +S(59fa87bc,4f47100f,f37135c4,1f5da6e6,28b76376,e0f365d0,eec857b,4b342b19,cbd82bed,1859e567,2e37e18,e977fdc3,6997482,a2db416c,686b3b64,a3c1d66c), +S(3af64d00,ddcaaef8,172aa0d8,adf5ebe7,fea87204,38125e07,eb74a5ef,91c17acd,4d695d52,ab785972,a425f6b8,f9f51e54,7067f9ab,b2af1085,bf22d1b6,7f51202), +S(31f9458f,d3544b7c,cf0a55c0,729ccb70,a57fc498,2078ba85,1fe4bb32,164e9259,31c6bca2,eb57ad06,e74da59,c824c720,17bbabe1,2e71a906,e6ac2e2c,36833b0c), +S(f2bcf05e,bd8ef03f,55d3d5ad,dba85359,3afb6b49,d72b2df5,c8107020,185d8173,a0c011a2,513c227d,22f045d,59d763cb,7c820ab6,e0b35144,66acbf77,8c188b22), +S(9373aead,2e733de2,cd4ddfd9,43675acb,40e2fdd,79c0bf12,45f8cf95,f2ece30b,8f171f4,5c1cf577,7416c873,a87af091,2a2eb20a,82f07c43,1e1f1b00,36c3276f), +S(5d2a3111,6cf78432,c8a3b0c4,a5021720,dbdc5e94,d842779f,6df51fed,5cc1e47,fa5381e6,ecacdb0c,6f326569,771b0f5d,d7e3c3ae,7c64cad5,ec03220a,33a24c91), +S(56549c28,f339c6d5,77efa8b7,3d795f64,580dafb1,f146268a,c7e751e2,fa3f041f,7aae31dc,2b875c94,6c2ce9aa,a6fe33b3,13c3795e,a188f343,89c34a48,bc3093a0), +S(ff4aa1c6,f5120040,5d488787,65f9931f,366fad1f,8a7d9ebc,abba9805,f6684aea,faa72c87,6956050f,663c172c,b3a0a3f,56e7e698,62723659,7a20c0ee,5bec6ccd), +S(65873e26,5ad6233b,41a6d42e,ebf1fcff,e8b1ed8d,97eb9131,1ede963,f8058c6b,80b955a5,d1648b0e,ef8d883c,24c2499a,f0f9350e,d003674a,fec69be3,d9f9d2f0), +S(b3a54b5d,3e19513e,b7be4c78,633a0e77,b4ec4015,d891bb6,35557fba,eee92f4d,1aabd4dd,3a995ac3,8c021f50,f2fcc578,5cdc724b,2b657f2f,9f82e777,fd449eb0), +S(30e69221,e75f5bcd,7b017467,d36abe41,d76b3589,1f82f38a,ff79be7e,fe8a7d44,95d5120b,807d3f47,76b7ef43,3ac7db28,e6b83c07,1e33573d,4a45eb8f,51296c88), +S(3a61f393,d842419f,f9d49dcb,e169bd36,2e28f92f,9d6c197,a441027d,9edc36eb,8cc6782f,898e586,1faa62ee,dc2ceee1,b21ae86,9e40e69e,20872b74,361f6f0f), +S(f46f5bea,e58e4a74,1838e312,57e3b579,5826ad3b,6c0576c1,f8b30874,c3a5779,91e35b62,55148a94,df34dcba,d2aa00f4,95e91eae,4a1c2d97,43a7fed2,d2713854), +S(6db13572,e3b35a2d,fdee5469,52d69463,19b5a95e,9e7ed8be,95cace14,471ee6eb,38c2be05,a1fb0fe1,e9dd09da,2684b4c5,de4e93bf,60fb3816,aa4261e,fdc9d79d), +S(af86cea1,e34c2d74,fef9d3a3,43d66574,2ca64259,f848885d,be0be05b,c8cfa432,8c8a2d2,da789ccd,b7f259c4,124ae844,36890818,5272c381,16bdb76d,f71af157), +S(89e5829b,41074025,cf6929d4,63dac04a,bd3139df,21b589d2,af8a0b7c,1c3c625,f762d80c,99197627,346af77e,f5295bdb,d86b5fa7,94975c6f,881386fc,e2609ddf), +S(2d589866,819b012c,ee8b7f5,63c20617,cf7d3f3d,ad56d4e1,c909c8b4,2071e6c8,cb7b8d2c,ff2bb979,1ff6f9d6,28d6a67a,80d1029e,d8d08573,f5e3b6f8,8dfffb67), +S(93ea11e0,e298b3ac,16ba686c,f5c1b089,55ed8d67,c318dcca,cb320d08,7f33740b,df9fbfeb,fb1547a3,92954300,98dc59b0,8af26c3c,ab7b42f8,5489af52,409a11d7), +S(febd58a2,529be1d3,8176be80,7daab920,32cf355,9ffd7d,154c9962,ea66567e,299967f5,5fbbd509,76271d5c,53975b3d,a4b43d1f,71f12ba,4a618a1b,5c11e484), +S(eb2e3d64,a5eecd,bc65bf45,405c8af1,bf4683bf,465b4a1,f8dc4627,b5b5c81,3c6d2f03,b30b2e49,4d056d55,3d2cd0bf,8c8f41ed,14b260e5,7bab5d0,c77dc06f), +S(9fefc3ea,d2ff9b51,57c669d0,bfea2c9c,7bac751f,9ac83c1a,143d05f,ba408216,10f0b7fb,b685e767,41fc9a7b,6c90191c,6b428e32,d9c3e611,c97aa120,8e361bba), +S(90b9eb4f,68cec46f,b7e426c8,94576858,a49ed785,a1b5be63,9bc68e5,33db8479,9aa3cfd,271602ac,5e9e84ab,343bef4c,9f8797eb,79d247f,7fde53be,11d32335), +S(2b80ca58,85919764,80e54e26,ba726c31,8b491c9e,56ac6d4a,f2163064,c69ce44a,50a00290,17815845,90773443,1c7c82dd,2e071d54,7d4b657b,f9edb939,24cb2a65), +S(df8e261a,55523b2c,933d0d15,c4bf5a0a,a8b2d01a,bfa7e064,d48aefd4,44485775,3d043bf8,7dea2305,274957c4,b8b5b37b,cd477b00,7d86f45d,b36fb42,c53c20a7), +S(7ac6a221,445bb8a7,ddbeee44,3aaa2de9,86ec1fcb,551caac3,84e2d37c,8aa05558,746446bc,64e61523,c52e5a56,b1315151,904a3d75,43191b9c,c32172e5,f08d22af), +S(5c0ace30,4217ff80,bc37f783,aca722c9,5027492c,3335ad3c,aae56270,c58509da,39685f11,9a646344,92a1157f,ca4548aa,ee37d52b,87d0148f,850976b8,4006dc6a), +S(6cd63750,f8318534,74da52b,11b8d66f,2a72c83,582b8c88,31d6be9b,ee5a826,57ca2d88,aa5f6970,54a6cd3c,a568f9a3,cd850d31,3510b1b2,adef4822,a943b3b), +S(9cabb7fa,7d9e6d89,42dad033,a22a1acc,1587e80c,fd7a2c78,fbc9bc11,c2cba6a0,f6bd65e4,1639bfe6,44f1101f,6acf65bc,ae5f56c9,f132b37f,8233f568,a23dd0e7), +S(233059ef,878839ef,60e1756f,771003e8,9af5569a,c5b0b849,fa84184,b9b9964a,654207a9,ff112902,9c9be9e6,d3d24bc8,a61a5c8d,4c25143b,5643e004,4fba7520), +S(7cc5b46c,9944e309,86e22624,99805a7,2b9ed814,954494cd,18c74882,aa3b8f39,c7ebd041,c5877c83,2cf05c42,6569ae0a,c1a37583,ceeeffb8,8cbc7090,ebbd71de), +S(9c55c21a,48c766a9,bc31a0b6,6e65a719,ec4d181,994cb533,3bebe7f,e017faec,4037846e,c6ca685,5764a8a8,230b07b,ccb9b145,b0d4a0bd,8b26020a,2d2c9da), +S(7926a60,bfdfc1c1,4d20082d,37b4a6d9,8e7651a1,4ed2a3ce,547a99cc,feffa208,da120ef3,d60469f5,dafe0776,8717dd2,5f95fc58,87594181,4b54604a,1aff86c), +S(c52dd3ed,e63fc9db,95a88ed3,e62064dd,f7f9112f,c30acc3d,3fc8438b,7d206c14,e65252d,2ecb95f8,a45059f4,68bfccfa,75b3b3ff,2ec9bbf0,46f51b0,416592cd), +S(831432ea,8e1ebdd9,3e254f18,15ad0c16,d637b04,85d43d4a,9eff1221,5835ec2e,af620dcb,328c94fc,b238fba9,3eb0d1eb,6f3f2838,9aedc2ac,26cb4f87,ea9cfb8a), +S(e5b822e9,72a7a2fb,723c135,d6d45602,deed7cff,61124fab,ef5a4fd1,68828773,117f1b94,6f715282,bd5bcef,fc2a340d,de226d52,cf3a9643,bc8c5119,542fc9a4), +S(59b98a72,bb15c51d,15f93497,bdea606f,2505b1fb,f37e42a5,73fefa84,b00deb6c,cb1feaf,bd5325eb,e604aaf0,480cabde,d6a5bfa0,bf9c4bed,674afb3d,65dcc5d4), +S(8847961d,6547b9d2,29f1faf2,ec0aec4b,8579c8c3,b1fe967d,eec280a2,ec45fd92,5280bf82,96b0251d,29ea6573,fccae24c,bdc4af9b,77043461,32103fc0,badcacf6), +S(bddf032b,d6c8709f,4b0f7b0a,cec96259,6db33d02,3d2270c,7824307a,b88bd4f8,b2fbfc91,c7944fac,dc69076d,90a1bc58,4d202119,574f0fe2,223f7821,c8100dd), +S(966bf84d,b5ed857d,cbe278d8,25167aa,eafcd957,597e8c08,241702aa,fe983af9,85e373bb,9788f0f4,2e4d6bf1,52136f90,b0fa7325,d2c791cc,4a7103f3,4ccc0b20), +S(7a16d469,e57ae4ca,46e198b0,4f970300,c2eed190,58d81028,ff2e1283,267099ca,4bfdcb6f,cb3b9c0d,782737fd,505c984,41c82029,db95b83b,c445b581,d1ff39fa), +S(818ebad5,7b04a0c6,f1235c71,634cf8d1,945a369a,8c707856,c58d2316,5bcd13cc,3cb6c26e,a053581e,821fcb36,174e91c5,bdd56144,7e3bce4b,c69f4f28,8968493d), +S(72059db7,2d838163,58b16402,653d875e,da620a67,5628a861,c6162f18,8a2bac61,232ebf0a,d0cb25c1,78626633,d4d61d47,d358bb35,b525e624,c2d6ba41,698f813f), +S(e407793a,b1246e86,aa9f782e,b1a0422c,28846f2e,49fcd886,4348c22e,411259c4,b339b1ab,dab01588,e8abaf1b,39a29055,66c14da3,1feafaaf,ccfb140d,1dc1efb3), +S(50dd489d,851e6b2d,af877b4d,70990326,dd9f9b0e,c22ca933,99dbdee8,ddb7b8f2,a9a28ecc,6d500065,4d3a3747,27be80fa,f41faa1d,6e51406d,13622655,e6cf5ac3), +S(5b592078,d50b3a6f,c94aa2cb,5b1e3a81,74a3d644,2fd12c2b,765678e8,7e00c8a2,8ebd56cd,313938a6,681a5ea4,61409f81,a4af4495,31266c3f,b915822e,845a8d7), +S(f90cbdc0,a228212a,32eee9e9,43e786ad,3a091308,81ad5f04,8a629a7,7035998b,6ae4854f,c789ec49,bbfc5d8e,14cc250a,1b862e51,cb343ccf,a0957b18,b9eb5545), +S(cea133d7,6121db90,c6281060,ead76d4,64b3825b,79363a04,ab0c0bd4,8abd9437,c66be897,96a25bf,867cfea4,f0803e1f,ec3c5a3e,178bbe6d,a972b2e2,e677dc41), +S(a09d9e59,5a4baf0f,b1f479d5,5d3cf051,7b34c007,b41d655f,efe61dc4,4111a4b5,2f21f502,f9752e2f,9848733e,afc40463,8e29d45c,1a294ce7,d09737d8,bc9bd1bf), +S(bebb4360,ec850828,b96a774d,2da91f0f,17c0a288,47796341,d617e1b9,b8728951,ea06e33,55603e97,91871935,f01cb416,bbcd226c,83cad5b7,fbd0eb39,48254a25), +S(d7cf537c,430cb0fd,434e555c,c1303b4,3fb60476,2b7f617f,4c2fdfeb,d5654461,f4ff7415,55841324,3b944ca9,adf91cdb,dbda99c8,90dab0be,8ae2a294,9e61c0ae), +S(1ea3f684,892f93c4,aa9372d,6ba193c4,8e6abb8,868bbd17,d91827b3,54424d5,dd549d14,a684f6fa,b1a401ba,47f42a89,14b0d012,80d24bed,743e3521,16ce17e2), +S(ac0890bf,ad8cab43,fa85b5ef,c10a5c7d,dbaa0237,daf20cc6,efc94c78,d95a86fa,a16a3028,69f2ae14,4566701c,f80add76,48d11ff2,1dd2596b,c30b074f,a5f3159d), +S(6d573525,43fbf521,d49d5b15,36f83a01,748d3470,57254639,4cec6785,860000a0,98b9f97a,9ae8bc6a,7ada1bd1,9a225ffc,8727ed3c,32b169cf,c381a60,3590acdf), +S(7be891a,771227eb,fd583033,e3801618,28cdd0f2,6e72cbd4,d9ffd169,92d7f1f1,be22c30c,3cade74,14bc3a7c,c3b4e5db,7ebb4ca8,b3ef67a0,b89fadf7,7b404fd8), +S(97f0013f,10a9ba96,58a1a5e,bf8f2d6e,4f2c56ff,9acc6221,177d2ce4,fea65efb,bb88987,7b7d1929,4dd4a011,7440707f,916e1b2c,fbf2b0a,5805c5b6,d8e65e3a), +S(77c3d2b0,b7ee36dc,69b75d91,11fdc25f,3996642d,a59b87b5,5f5840ab,cd5cb1b6,769c9cd3,7c4f4059,60129e1a,4bfeff8b,d86a41c8,eaa4e3d6,826a4cf2,5185c5ab), +S(a0a234a8,da6fc04b,2c77c7a7,a3b79f5d,7200df84,76d6737a,e879e4c3,a080fe5c,b9b8a2a3,59af78,9d5f0448,3f77e1a2,923a28f0,9f928067,4bdc1aac,8e8f0bcf), +S(1374c3e7,fbb1611c,8449d724,7ff49167,230b630e,a0c2c0ea,6d438426,9a91fad1,21d482a9,d29778f7,dbc31471,fa120bf5,abfae23b,185dde67,2198c725,47721db6), +S(f6c035f7,270679a5,4cac1f52,449f357b,cc36537e,669f056,3bbe022f,541e5d67,d470bd7d,9459165b,8bd093be,a3f64f8a,fab85bab,25f31046,c3db4167,5e8e7e77), +S(1baff567,622fda3f,7171e2f1,f66498e1,da1a2973,c5ad784a,6fa5af2f,23cfdf69,e1a87fb,1dcf917f,2dd6856a,48de7762,a05e0c12,89233db2,49637e69,15a5aa4a), +S(eabb2399,ebd468e3,84bd7c14,1329f972,96b86a47,53cdefdb,3b539449,d4e04d92,92d94943,ff0dd405,fbf02d21,875b7f13,25eda73,ad65d332,d005870f,951e3db8), +S(9121e2c2,13734da8,23ec445d,cecd6740,e1e5f513,7771ef9c,72589419,25f25ce2,8b1dafb,ebf4ee9a,3c39f51b,dcb560eb,f3e27409,589505d8,a9c18946,847ddd63), +S(51616592,730c7580,c2ba7dce,8f2d7aae,b71c1796,e35223c6,8a6762a8,c0566563,5af04478,c1509a8,905e271a,80c01376,bbcb5161,a78bcef0,1b5116b4,adcf68d8), +S(5489e35a,4800b74,e7d9d8b,99841485,2fd80e19,b290d7d6,22ab9f66,de8dcc11,3ec6df58,ab461f1,9a0879c,149d042e,8e7e5c2c,98dac706,19137120,74a05492), +S(bbd6f40,774d7bb8,e3fd18d2,b7f3c2b4,d1ad882d,73e101ee,3ac247f9,b8720005,17134bcd,6f74cb12,48b10902,b9eda37a,fcf8e5bd,50604a0c,65d08952,460c04ef), +S(1d99eca2,b542ff0f,470e7b46,ffa024d0,ebef5635,c0149593,b4b34f6a,d4531cdc,2e9cc03b,b2e5a461,a3122521,e09cc6c4,63d8e6d7,c4aaffa,c9d036c9,6b74d882), +S(32c2caef,93d345c0,9451725b,84b1260c,a9defe2e,228f985f,f33c3f33,70afa675,6875bdb6,3c8d28df,71317042,d2328d5c,24614210,4d134068,a943489d,e695920c), +S(25107b07,4ac55835,81afb4d2,dbf5e1b8,21c26b56,75efb3,33abaed8,56d0a5f2,626b9614,2d70c2a,5572ff7c,606abe47,cb90f850,2c13d478,3ca4e045,bcc7ba39), +S(d542e001,894cd3e3,97ae2519,f4b69c7,59308117,9ef63ff0,a9d586b,3fb324bc,bdd28dcd,94c208f8,bed304f3,adbffc7f,76cbc70d,333dece8,b2680b6e,19076fa5), +S(c1b950e2,e7cb74e2,a4274cbc,b67772ad,5c32ee22,b18c3d99,e4a92005,3edc000f,e8329595,39709b81,58f892b7,2ac9c0a4,e1e692e4,da526980,2b046759,58f0ffda), +S(8c6c041e,b8b3daca,fe89492e,91829869,2451bc8a,e4dac8ea,8cec1d49,c25778b7,6bb9de3a,55fefdbe,4376c9ec,dea4bc24,ade146b6,c454a441,8c47120f,f1f55d56), +S(4806db6f,bcf9004,e4cc63d5,555ea5a1,cb9107d8,e060e3d8,8fb79fe0,3acf1e46,c0f5f482,288b0036,ca485a74,a6bfc264,88441487,63804ece,e620e47a,16160e95), +S(4b3e050,26545104,176aabd4,40ef4ba6,451bbb0d,5420edb0,4063c22c,2e7d8928,42ebb34d,ec06c95e,11ed8e24,90369796,2d8634f2,2641925f,f765b06d,838b5cc2), +S(be7a60ae,bc21640b,2f027c33,f6ec9422,5e66c16f,1d946ea9,dd881101,5d80a21e,1dd12d43,2b2a2f60,9d434936,ebedc2f0,b9c20747,32275c94,fb7bb15b,bb323bff), +S(550813b9,3c3dc22e,4dd576e5,50042b51,34f1a905,2b28af39,cf87bb89,84cd8211,33cfcf61,91cc032c,dc284de3,7adf0de1,a83e39f5,27273eb7,f361235a,40d6da10), +S(33133c21,98343b11,424655b0,8ed83de4,ab36c87a,1c5316a0,686145f6,62be725,fbf5d264,30a71f5d,bbf33aa,be2ba027,b8abc0cd,37d0130f,a99a6698,75f011b8), +S(dc21892a,8b5e8ad2,2d4fca59,7941bd5a,5099f82f,e47ac4be,7e705a35,9a03eb9c,7d49d315,1d6b6e97,1f8712db,197b3c8f,aa8b79d0,5957379,6b895bbe,581242d1), +S(64e648c6,98b6ee15,c168e71e,dd031c66,27486a0d,8f858342,80d55924,66421465,7244a14,2e7fa0b9,a41195d9,d74655ed,4ac3f1aa,9f055c90,326bd32a,22669878), +S(153e77e6,b1704f24,5ad12253,7f11e9af,e22c2647,67293dbd,fa51e415,950f7b2d,7bcddddc,ba3b79d,7cb6254b,a4b4abf0,a44fdc4a,131eb185,c6a480a7,755cbe6d), +S(24ea7667,d2747412,2adc6c73,4a8babff,df7850c6,a7e60647,e4825f80,9f89147,385b29ce,bad1ef7f,c661e36d,97bb9eec,5d415c7f,613d82b,39f8b131,aca17278), +S(897d6779,70dfc489,800087ee,c67c957a,5299358e,14f63610,c991db4b,530c32cb,42905602,2ecd9bd5,9d8e3d49,9e037e07,4268033c,6ae4c9b8,ea579d96,daca5c6b), +S(beaa3e34,26dbb441,5ce9c604,7db0821f,79af4e5,faafdcd8,8c89f265,77462905,c0fa8760,f9964d11,d2152f01,3590180b,53a67a35,16cf7c3c,403361b8,aab86634), +S(d2c97e5f,85b4025,a66c29bd,23b5d30c,4c8f066e,f68ece5c,df907b2e,558bf547,1e320de1,3347ea0b,13ef7f68,cfc4bbc0,e10bf7af,c031f64e,9a9f2c43,181ddb61), +S(1ec48a1f,169baa2d,ef5bf8e4,e1ec8f51,d91c1667,6906c912,ce084f2a,9aba1d6,498a5d90,6ec47ca9,f6d7c5ee,bd25f83b,a14884b5,a4ad64ef,3fe9ebed,5ef0932c), +S(313ad91d,44f622f7,785b3ca5,6cf9e8dc,389d5aea,b696342f,ce58ecb1,d6e9b45,60f8ac86,3cc5eb77,c8f83c05,81aba889,d48f65ca,b9757076,7d9973de,f4a693df), +S(93f7f233,dee42606,41f8fb3d,d67e6e9b,cb2fdcb0,905e9b0f,92fb2094,701d6ef1,1cda7163,64ce202a,b53e3cfb,b4bbdbf4,1e124e57,85f91d5e,5a5f3205,a4e4ba13), +S(56694a44,a4455ef0,a429a5ef,d11b6440,bfa6e0c1,958b8f2,e3a8d00c,b1f5feed,ae0e21b6,669e1b86,e27df62b,7038de4,fbfd1b10,72da3ebc,82432787,ba5cbaa5), +S(7a6a7dba,80380635,d851f291,d7dbf6db,bce98978,805c738e,8c80c20e,c57e3a0d,673236f9,ea37dff7,c9eeaf34,b63ae652,1b38fc9a,94c111f2,b3e253b,34f05009), +S(d4e820b7,aedaf95b,de86a889,f0adebc6,279e0ce3,b0757972,d574f64a,3fa6a6bd,42762fa9,1b1cb9df,85c55acf,95a421a2,d4da6f01,69474abf,61209ca0,4f062939), +S(62f26014,d06ef2c6,ae6d459,6e45b2e0,d7d28f11,ec84fe61,8baba130,1d483950,d53fbb59,f239a52d,592b6f98,fbe311ee,4c9d4e20,b6d9a8ca,5698503b,eba1eeb1), +S(bc5ac17c,2a9e3731,7dc80bb8,7eccb0cb,ae804158,792b6926,60cf3f53,b2446eb0,e2a67966,a8de04a8,db78b4f1,e37c6885,b99b188e,1d4a1fa3,5e9084a3,96e5d8e1), +S(80743e30,983d175a,ce9ddb09,bb1adfc8,1b059b9d,73c51b42,d29a9f5d,673fa494,eff1e042,89a84d27,2d941b5d,5bbceaff,d3b7069d,9d704317,4b35e2cc,12dad80a), +S(faf014bc,c17df331,1902a50e,fb18469,9f0344ed,b6b057ce,5c922f22,97f5ae5,47301fe0,6fb57e8b,5fd121cc,be2da9fe,e8e918b0,7a9d9228,43e41de,77e2c1f9), +S(9e89950b,e18485a8,14eeccec,4bd484bf,e2c027e9,54cae11a,52bf2a82,43a6faf4,e81f0ee6,c85c5571,f5ae6a03,3ad4791c,68f9189,507e53ab,ee15e035,6372f6e1), +S(496b3eb,ac55b991,fea92454,e844e5a3,fe7595cf,b25fe7bb,c358f0ed,38e9cff4,d13d035d,ae0d457b,540c6b67,4db20893,f75ddf53,5c6c54ff,95e46c76,14a58153), +S(24ed90c2,3547169d,bc55f880,33204740,a2fd2119,63737fd1,debc0578,400c675c,f37940f5,e3e25da7,7ffa143a,865e46fe,a1dd1230,fb42a627,9e791ee7,38b739e5), +S(9cf8971d,43eb50d2,e522fedb,9281026,659612d,2fb2bea9,d7f6a65e,cb2c0703,b0b6a53,103cd33c,6e0c0bd4,5cab3923,29012395,f8e8951a,1fc4c9dd,95cbbdaa), +S(f6c823f2,ce2006a9,6cbf68a8,61f00eaf,4d8524ad,3467f8de,8dc64911,e89b1f7f,6eee9a22,59ad8c81,277d52b2,cb3b5e44,1259fc8c,52868b74,4946b0f5,b8d9abdd), +S(4bfe7,5bafa425,7f1fd25b,12b68afa,abff6771,89f05d07,85e06d82,b6906316,4ee94fd6,a5388fc0,1ab5da36,41b5c562,9f7c966f,64cc387a,9b3336f4,34323adf), +S(d15fa5cf,a481a1b7,8c746f3c,a19e0979,8b7e777c,4841d73b,ec4b63d8,b01c0019,c6fd422,76ae3e1d,b28ce840,29b8079d,7dba4c1d,acaf27d0,d2b29bbf,5ed59f6e), +S(bd17078c,75e7c325,80cf4a88,8d43c5ac,c323d8c8,4e9d5e29,c09c8c77,14ab7397,1094e3a1,21abba10,7da189d9,2f92c5c,f00b373c,89f346eb,351450e9,7377cd4), +S(1acbdb1b,79389dd3,5dfc607e,2aa8134c,fb04a655,c4848cb6,b5b73491,cac2cd87,8d2bcfc8,72da8a7d,1b89863c,ab7610f4,297dff9e,bf9e3f18,8a6bd6e,99421c97), +S(49e5b6f7,243f19b3,c36c5411,a6e34e2a,f61a99b2,38958b93,819ec7e4,6d647af6,9af4507d,850aab9c,9b1eb3be,90c15460,3756e29e,fcba23ce,313a4dd5,290f1385), +S(15bd9023,bad0eec9,fb19a720,e0a7be10,df78b3b0,716978f,5ee37052,b19d1f92,9cbac74e,7adf5e32,8959d826,41fdcaef,1d4eb24b,a5bd24ff,8d2625a,12d0ea80), +S(9d03f121,d28dc96f,ef6eb2a8,d3737033,e9f6703a,1683aeb8,c583b78c,7910eb6,46723472,ae342ff4,fb9fa789,8e063379,3b9b6781,4bdd8f43,840110c7,4e8e03d9), +S(8abe7e21,f025f340,6929eaf8,c818b016,f7423717,c893b6fb,cbea7ec9,7db98a5e,8bde4e6c,c37c681c,4f664731,719ef10e,e0e7f6c,5739cecd,32f6bf87,c1ac6144), +S(66135e6e,e913c965,ecd190c1,9d4bcc5b,e238225f,3755aee0,64852da8,96e848df,c2c5133c,9c033d30,2029ef21,1379858a,ec918357,421b7614,13a4deff,6f855ae6), +S(5dfa7af7,596b611f,24b57d98,59a5cfd9,41ffdfdd,1e80b0a9,994966a0,338d3b27,2780b496,8fa51ba6,b6256d78,aa25249a,982c091d,40cb9336,863ef2a8,9e4caddb), +S(a5a9782f,f7c90216,3a235a3d,9f548af4,a0ccf508,1aebf0c0,f9d4d772,ae3ceac5,144a9e55,f017dcdb,fd093573,c47b9954,20cd8a63,bd7cc456,f301cfa3,b7e7b8ab), +S(fcd5fd1c,44765529,413ef8b2,63d60414,c6b1da8e,3d2e8463,f0d6567c,f9029916,9877c363,d6180a8a,b005d5ee,77eeacdd,ffc237eb,a30da48d,ac582d0a,84e8cb31), +S(95be1f47,e0aea7c,4c0720e3,fd528ece,66627ba9,3f172875,76b1490d,7a8cc395,f68eaaf,9c4986f5,32adc845,31ba80c9,2c817962,1e042503,6e58bc46,f2d18720), +S(bca58c89,dd846a85,6698681d,450afd5e,621c9ecd,3e1cbdc,d8f85582,4a9cb047,8d0160da,d653a54f,323bd258,74360e4f,573d9a18,c3360121,e18f33dc,5be1191d), +S(1508b726,9d97108c,9c4a01c2,59fe7022,dfe63662,c6b695dc,6404a9cc,3a532a8b,e4f1b655,35250561,cf8b38eb,1b43bf23,430fd354,5045c434,dce7d3de,c22528a8), +S(b2b2dff3,fb9b7b21,411195f,c095f2e5,d69dd4de,249aebea,b266f6b0,c45d65e0,f81346f6,2377c415,a05c0a4e,b0b70a3e,95361575,9241cf7a,22918713,199a5cc3), +S(b087aca7,3b1daae8,b5655de2,6ec08874,14e3c2ad,fd3c84fc,4c6ad73,b735664d,402e931a,b04132c0,2efe8d75,6197ee92,90ec0b64,abb12862,728bf679,42244f36), +S(eec45124,dea794fa,c467c17d,5f843902,2f7befc1,f535897b,da946e66,bb22dbd7,18288f3c,6d89b340,d250bbb,afa10261,a30ab71,c47d8f36,a6a29312,e79945b5), +S(9e01ac6f,214ad3e2,252051e7,9802e09f,ff5a1f5b,16fc97a2,f82c5427,515a4fb8,c92a340,a9798e40,b8026d1a,826eb59,e6db59a3,efa12ad3,b891450b,c7ed015f), +S(97c0e53a,f2dcf282,66568795,2fc72a69,33e7161d,7a9312b1,261b0085,8bdd386e,5ca75fc6,b5aeef6d,7655fc27,1fe56c05,8d7a65c7,912a23a5,e4105941,2b20cd5), +S(79f1fdd9,179d870,45f8f8d3,c0f6e14b,2c932673,1cc2e79a,4fefb3f2,9966a21c,38eb64de,e16be6b9,57c5e78a,7a64a55c,90cf0ab3,a99c964f,b0dcbc5a,7f15e40f), +S(53559fe1,d3222709,8e26093a,61770eaf,9bfcb7e3,e5de16eb,df6e8934,a9522921,4278efb3,9cb23458,305c7ce5,bde295ad,856c901c,d4c7faa4,bffd6c9e,52bae725), +S(dc3c9dff,d1ff296b,17667fa,f58231bc,d2c26a9c,8f6485,514270d0,d5d00d37,701693a6,17f6ff10,afd51c26,e760e0d6,8fe749db,aa5b35cb,636643d0,b3755ea9), +S(3b1ee2f2,9ff89f3e,78295dd1,6128690c,557e188b,f76b86c2,2698e0f2,fca33213,69d4fd8,e1886d81,d22461ca,81c20e95,ee813d9b,6bc39af6,38ba71f4,72db25f), +S(8c9b2d19,a576801e,e03f6108,84d1106b,e13481ec,817d892d,4b233aec,3514d12,55e30950,d67bff85,a1fd0efb,210f0180,d349fdd3,20f3470c,3bae1c70,21550dfe), +S(fcd42391,288b05d8,8e23e673,7d612ce2,f45896dc,7953cfa5,fd32fac6,f8ccf8e5,83c5ecd,4148c600,d9416831,68ce71be,dc571321,6ce07f5b,779a1773,412a8e47), +S(92cf957d,a51ce801,64e6ceee,76defb26,f14d1922,9e9e1933,4f13849e,f7922f44,cf066667,272a2d54,acaf3fad,2b9515f5,c8c23828,18a91eb9,d6b03a61,475e2298), +S(646d5ab7,421ef1e1,1f86c4f1,6d308cf4,401ed527,c975643d,e0221f17,6c2441b5,3313b887,226eb9e0,2956f3c4,f764892a,3b99bf6b,8106575e,55c792cf,3645dea1), +S(3a99563d,d92cf9c7,85a0882b,9f51af44,76af2e4b,dd23495f,341a524b,d3643954,8bcc950f,1eabdb50,c1cf6e63,1b491672,9dbc1df7,44769283,e52a5179,303ccae5), +S(e8979b98,5a418b6,13d4d43d,d004de47,f6cb8e38,354fe810,7f47b741,c69a780f,c407e05,a72b449e,43bd8069,9f7b2559,ec26fafc,a016c735,a8fa5142,1beec4b1), +S(5c69255d,207f650c,59fdee77,7d59dcd9,dc75e3b0,8fd7fec3,d6f69929,9dffc8bf,a1ff812a,4690c166,48a7f3c8,cfbb688,fc5450b6,29f8f0d7,41e36883,ba570674), +S(48e3a29,a1be4db1,d1fe34ff,fa352356,a75d97d9,1dd73448,10f9d8ac,ded6ecb9,8bb6341d,d3431054,893dbf21,34e02153,2a1ec461,1f42ea41,d43859a1,4a6fb78d), +S(fc9d5478,5428ea33,8bea7507,488e5505,f82e680a,778fce8c,9f84aed7,ffb235a6,884e8b36,19ec9e19,9650973e,bb160df7,a116f429,aea7b742,b1837e,43dcc4cd), +S(5768babb,8f16cf85,98c268d6,9965f913,1ba2df86,8f96958e,5c926960,9f86810f,a320eb27,3667ef78,4e0a1e0f,a4d452c5,d9eaa349,b44d00da,6373a0b3,377da289), +S(499c15bc,5bea1040,5ef65654,fce454e5,4072450c,4ce5f279,62fc1f69,9bb103f7,3b539537,3e537faa,89adc347,74721df7,ae1554ab,ce2b7ced,38f67b41,9b157e3), +S(e90e567c,20c1b561,be3a3c9d,8a227233,73503e97,a1e88e,d6928465,77188951,26425fb8,49136a00,392a8b01,4248e2f3,10b0321e,d192e9b8,744e7873,5c393396), +S(5555e213,b06a7807,98ebf522,9142f5fd,4867d080,30ff2f63,8b637d74,3ad54e42,1b82a7bc,610284b7,758d1d75,982cb069,dbf77cea,c9deb76e,62eb5324,d726b42e), +S(9b1c140e,38b3899a,c77eeafc,1784805d,1efc1363,d25ed7fa,abf923dc,dc53d9b3,94bb9ad9,9b01e6ed,af7b4807,1ac2f67,ceff22ba,3ed4a26c,7b1b82dc,9c5fb8ea), +S(268533bd,33f9c398,5d8ba9f7,d6d111b5,9ea49cf0,8227894,cd236cb9,4c4d6e45,ad5ce6d4,3f70c08d,2b1aeec7,6e7d421d,41e61276,fd2c5a7f,4d263479,177067e8), +S(9bd29abf,3d69acb,1ca7f6ac,68e47d1b,61f8612b,30c36cf,4ed79939,583590de,530faf27,794dd14b,9fc084a,dd6b3cff,e0343608,501937b1,e7f7fffd,10942e2b), +S(eccd8863,8f3b2819,d828b9c1,2c0a76ee,663f6113,ae8294ab,e7ff5719,c8962cab,18da1af3,db016cb,45d7f9ce,dd4bc478,63aa8092,c674fca5,8f03f703,82ccc799), +S(8968de12,d40a30bb,99b10962,568b1f8c,c37bac76,7fbeac7c,21b80d58,bd64560d,268bf30,ef631569,800f6ee9,548cc7c4,15c1fd7f,b21413d6,3ed5abf4,936e5b36), +S(450789b4,297aebad,346af999,d4ea3e7a,c8867ae6,19a59c13,84b1ff3e,1fd092ef,402789ae,6ace54c0,54a26184,c651e8d3,814c6fec,fdb560a7,51943ca2,24bf25ca), +S(88b90c79,49a79d99,b05a2dd3,cac61e38,783dc306,fccacd97,892a75be,34e67403,3a565d5c,eecfa071,2c9355ea,67009764,7d0e52c2,d6a6a49e,3317014f,56554bb7), +S(e5a45f20,e3f5989a,a9b04119,6f7e1e8b,95f4b397,4e1c18d0,f19bc12b,ceb5464b,d09d73d7,e6dc8239,ef9758b,ae186e54,a5cb4d71,47f6dcdb,ec933237,3b677018), +S(51b99055,b4815a86,d0bcd8b6,8a7b47ce,7e9a93b2,3ec5f6a8,7c185c34,1647cd05,4fa125a1,35f26df4,ad7ffc70,29268830,9f8ad7e5,f3683eb9,b3dcddef,45fcda0d), +S(1dfb4a44,867afdba,892b9f71,1272402b,cd38318,f8f7aea,68c16eb3,2c07d565,4312ffbf,15775c04,e187cb98,166b5bb2,c42582d7,5b8938b5,83613d66,9622253f), +S(f271ed8f,c137af31,dad55775,e38358f6,608afdd5,4cb0d1b6,883ac66b,7b645fdd,1494c658,faf514ab,912887b5,c90e6bd2,a61e9d97,7e1ffe65,a49de27b,4e393bb3), +S(ac2f0db8,43cc7ee6,e268cf62,344fd232,2f0e40db,703a7d33,5437e7ea,de7cbef8,40ddcc5a,53d8a24b,8b5ee481,ef331bca,89e76293,7d1ba22,3471c562,ee7a2dc), +S(1801ee15,c8041c65,b9727159,8194a957,a404d5b2,318308cc,d737d858,4b2015f0,df400a6f,6a50057,1ebdb755,e686b759,d604d434,b9f198e2,21b2b514,30eca9c9), +S(8d304b28,32eabf93,82d71e3d,cbc38a98,437d6a,70c5b084,4486dde2,1104dc80,fffb5a64,3fa633f7,cf36e574,31acdb02,b98cb4b5,9a0076e0,8f5e5061,623b8157), +S(4e8645ef,99a816cd,74a0fc67,48cc116e,a61133ad,8f6bbe55,46ab9aba,adb148ff,594d010d,ff31677e,8c602038,5e071e58,5a72e97e,4d1c2d0,5564c102,56441c4b), +S(b8c26b70,b1367df7,7a14a385,aaec861e,e3cd3945,7282bb2e,935271a9,6c87d589,df51bc84,95a0c2e8,ef469219,f05f054a,5a5f85ec,a20f8acf,6c424ba3,9faff23f), +S(9934e27b,8be7c41,3f5e8ec,f2eba29f,26ed2ff4,fd588918,bda07bd1,5b87f4a1,4488848e,440c0a1c,5d11a3f2,784728d1,34b9a08c,6210494e,c1cf6a0f,71c334ee), +S(56692314,f6a9764,47a1a988,f0a2faf4,e04c61f2,b835f22a,25b57290,b1ee5d14,d8d72ecc,1afc548f,cb1f71e8,144f9f7e,463edd9,5422a607,7b9b307d,15326fff), +S(737a268,a2cd3d43,d6741235,69e2e118,7ae90fc8,669d27ee,504f9e85,5eda3c2f,e3d24166,a5ba6183,730c11bc,8b41845b,3efb7154,6eb1a06f,2e90dcc7,33f68b47), +S(90d40297,4ae9d5c8,f4c59207,e58797d2,8c007a6a,4f6aeae7,9e50bb4e,fc34fa7e,2cbdc969,4e7ee150,b51a7e1f,d81d01eb,71d48027,3f349a39,8773732,4b315cc4), +S(4639872,2ae68fdf,9a98eb24,6a70946f,c9bc927f,37a3db42,f0cda419,7dec8163,6dc0a8b1,81c16b97,da97fdea,ea20bd03,cfec3999,7e192b1b,3e0bfa39,a1727f55), +S(c48cb232,1c02051f,2f1e5aa5,c99f7d00,5bb8af4a,61691f1f,493d834c,549139bb,3eb61f34,a2009094,36aced01,4a11b75f,2d35d6f5,67e5fc5e,2fc7aab4,437a2c5e), +S(eaf967eb,d5f0932e,42a3222d,ac0d874e,af154f8b,47beee08,2ca7196e,efb429f5,870d0edc,43dd51aa,6f518b4,901049e7,865565d9,3e54e475,d587d94d,ce88d994), +S(291f8c36,ae17ff86,d05a5a81,31ae3079,27221af7,7b97d66c,812a954e,ad22d49d,3b515fa0,bfdb0fec,61f838f0,e78bd29c,360b9ef8,c6f599fc,e1c518b2,f343d8c2), +S(d6280bf9,4334749d,49b19e44,b811d99b,2a522e73,dc2afa03,c130a48c,f4ff39e1,5f282a7a,be629408,9672c7cb,c9e46e1,ed2dda5b,653cc490,93f4aecb,637a1024), +S(9f96aaf7,8b26bc25,e321837e,29f3cbed,ba6fe62a,3a66c59b,cb52ae9,daddf9a9,ebbd1df8,a818a28c,e1a61b6f,ed13f139,504d33d0,5e27b5a0,b67c15,b1333394), +S(bbd26954,fbec8b4b,d27f85e,44b1273f,37321a28,fa938eeb,f5e5f50e,fb0e8a40,56a517d4,c54368cc,b40d0653,7db7ec68,79d7d4ea,dcdabc1b,722e1a64,710e9b6e), +S(35597cce,40b326e0,d9044225,82726039,fef5131,9d267240,b2455142,7ff6d7d2,ab1508d2,278b3b0b,fec8bce,4dea9bd9,31859fb0,2f600cc4,b67bf9f7,4f2b20a0), +S(8849429d,39cdb22a,b6d22361,22a59786,2baac8d7,5f858ab0,33c5037b,81eaf963,ec203255,647d27f5,f134b011,cf390703,18006dba,f5ffa74e,593c2711,f765196e), +S(f7519d31,1493f836,ae7c6f8f,e8ee5f11,ea2ddec0,90eae6ad,84c6d0c0,3249130c,de7b22f5,ef095528,5a163142,255b168b,c004ea10,86269d7b,ebf032be,d9a6452c), +S(865cfb50,e57bdc46,166d2b8,17e9b4f9,73db89b5,2fe4ff14,1898bdc,fb4f3a25,36cbfe86,15368e24,b9673fb,f593bfe3,d1a0fe03,54f98c00,bf8e59cb,be930c5d), +S(cf3d6532,8bf2bfc0,8d36a93d,8aa8e8fe,317ed071,3aaec871,48bfb50d,ab1919ee,ad96a551,9cb8691a,e1d535f2,8af23967,704dc578,b7c38cf4,84ddbc90,2c1b26a9), +S(6ede5a39,7aeb2f30,d577c225,29ed1ecf,d28c2041,75e950e,12c98c1d,2ed1c48f,eb102976,b4237833,7761ab15,a8d0c228,a42ff5d3,a1279fab,736e24b4,47ae8e3c), +S(146a2544,cdf67ec3,3bd216b8,51d4127b,bd9dda77,4a78697b,e010e61a,7442a22c,f7cac2,376c246b,ad67a10,ee0fa811,10afccc6,d76a9295,f16d6034,1876814a), +S(bb14a6fd,2129d75f,5aeda8d4,d69cae8f,55b4950,7f709a96,af39bece,8e1449a4,feb4ad7c,1a3a224c,bf4bac58,617117de,811d250,8a948a19,a94b9cd5,8560eb09), +S(69975e93,a634cdfe,2ed014c,33c65a53,b17c6025,ae499a69,599b33ae,bbe52428,e16090c4,2cb1ccd4,7c7a9b91,4fa88027,bbf7155,374fb95a,ff0a06f6,4758e0c9), +S(e281888b,e9ec00f5,71e9d807,35c1c762,4bf8b739,c94f3178,868a7291,9d550848,2066254b,53733824,2a5b697d,a05fdaa,8e2d3b6a,840a7208,6854b55d,af88c3d7), +S(96531c48,abd9bca2,19fe05e,c1ff1ff9,90a526ff,5c7b5775,804c5db1,65b425e6,de07c8f5,32e0eb64,fa76442b,e4269e52,95212bbd,a9cbeff5,40b012df,f0b3ce09), +S(59d3a12c,3b2bf72f,c4ec6d8d,88594e97,89f30670,eae71e7d,2b98e9d7,3d5deb0e,fb338126,9a57fdb5,6cecf38c,ee63631,f520fee,6c3b334a,a47afb7f,7f5150af), +S(1267bcee,c8f3f086,8187271b,3a283241,935f1822,ae5e8e8f,5a4ba753,89869795,5249aa32,41fdc011,606724fb,6085491a,d974d355,9d27f8a5,2e80c376,92b22736), +S(446310fe,7a9d1f2f,632cc948,c86ca652,7358b910,e9532e2,9f394ed0,12c45ec4,f7ff61dd,f72dfb99,bf309210,286005d7,8328137b,6394354e,dd9cdcbb,cff06cf5), +S(7edfb2fd,a3c15d42,b29440dc,b7c7e74,c9530a79,6290cc12,86ecfe49,96583244,c7dc5dcc,6fc1ac75,5eea622f,69799c77,eb5c3883,a628f14,c61f9cf9,2db4e2bf), +S(e34f4c12,896a8400,a79db9e7,a5b0f67,99fde06,5e381181,f79bbb9e,b81d5e8d,e3dd7871,3cc68c48,9a877b32,9e32869a,ca89a69b,2ba6e83c,78af9c60,79f87f7d), +S(f49e78fb,caa129ba,ad6fa192,a26ffb62,d6825cb5,f933c2a1,c8a2c872,c5ff35e9,4e1c9c4,c176653e,6b87bf9b,39c5606d,ace09e3,c3c268c1,a51e52c,c4ebae1e), +S(71d7f117,738286d5,71ce0b08,aaa1b448,fd4a9d22,2e6d4ee1,b8c0d0ea,9275656a,751401a4,2fd576ea,6bbe6e0e,e076ec36,b9db65de,a747b31d,e1a66a02,324e5b30), +S(29f56789,8efe1baf,bbbd435c,7abb043a,284d16a0,598a5a6a,49d5875d,7577dd82,c3a6e7f1,80afe6e7,b761bde1,7893aa7d,2dd34702,6558c1e7,9d4d80fe,108ea6a5), +S(435afc66,f252c63a,fbc56f9c,342aae25,bbddbfa4,9b94a8e3,3d2a68c3,6730e730,d8cbf58e,e7cdff53,e4d52865,c76b9331,7553814e,f9f8c4c4,9c93e49c,7bb98dba), +S(c326c1d1,b2d1ef3e,e4e9367a,48970337,f711bd23,3c619e18,2bc47227,2e53d813,559b707c,4a73a245,c6d57194,9ceee5dc,b5d53645,d576d6d8,309e92d2,4bc959d1), +S(83486a4f,75664f,58db5cec,96af658e,6f669946,5c5b9e71,2e66ce5f,627d6a9f,eb7258a9,30b5e703,39681d8c,452e518d,aabbbe83,1312a65,af2723ab,ab61e04c), +S(85b419ec,e16f8d3f,ef24f1dd,6f8ca2f0,ea7ce0b4,bdd6da80,20eb0f83,7c799bb,37f888ac,3474341b,30a32573,2ee9db8c,4cd9a9cf,64350f64,8845c63e,fffe6343), +S(d6b6f0b9,cfbd4126,2f6506c0,89c1132f,7da49d8e,f9afcff9,ea97a224,35a85015,c5b7229f,dfc148bc,140ab9d4,4895c5b6,db02ae00,62585521,70aed317,c0e39fc6), +S(40f7b48d,1070340d,2382ba1b,794e4069,ac9aeba0,fefa8823,aa9902f6,4386c221,985b387,a3720bcb,a99ee10b,28ad253a,9202eb0b,3167d462,b664d67,f294509d), +S(ad6a6bd0,99789a6,2b3602b2,f75af03c,33379054,cefe6397,a135cf78,a0e13a99,249eaf4f,321d9011,39ce28b,4f09ee1e,4fadc6e6,763cd737,96777f30,aede6256), +S(2e15ccdf,25e72fd3,3007b705,9703b13,5f8a94be,cdc35523,3b349a64,60331e8f,e3ed23bf,5f320a48,e1dcfb9e,38fd2bc4,fbbd5e2a,e16072a9,9f704ae5,2d4c73b3), +S(aa9a2531,8d4796c5,8443eb4d,559dd43c,29efa4f3,c994eef,a1791027,784d4fd0,a32f3a7f,cf3b4494,a4970b8b,d20f4c6e,d82833ab,eadca5b9,4ddbb5a6,e27bb427), +S(f16c0ce8,cc87f208,5f98919a,cb4dff65,b68f88da,6db10674,c4cba867,bb410345,12dd4b03,86509e2d,a79f3895,d1c3cd7c,f5735529,b049204,9b7434fa,64fd382b), +S(f27ae46f,14efa234,e034fe01,f4ed5cf9,251c99a0,fddc9e5b,13ec770,4cbb6bba,4abb2ba9,5877455,ae76d4d2,56216ca1,78b1c12f,3fa9c10e,5df21225,4071c557), +S(a966ac61,ef7d10c1,47ed0ce2,cc383cce,8d83a66b,bd18aed,8261e38e,67983e7b,5d2db9c0,ba8bf67a,d385146e,8ac20c72,9fdbcb0,581cd956,a95ab89e,a927bd2a), +S(ced076ef,4951ee63,ac196d1a,65cab7c5,5654d12e,ae16f4f5,4c2637f5,6b1cbeb8,2b763b9b,bd99ee6b,5b6c934a,ccebdd0b,952cda5,ed266d5a,986be5d4,397d9f7b), +S(9afeb8f7,f445a1ef,c7951fd4,62a0a3d2,500f3527,1f482e01,edc9815c,2deac969,93354851,99ea1fe3,f74a6991,6fa53f47,2d1918d3,c4d0d526,34909810,25830723), +S(61c405c6,93115b8e,325be640,8e30cadd,9e42dd98,8522871d,1612a44b,95c41d92,efd7f73a,f38e21c6,8fa28d86,b3a9b241,27fb686a,75c53c1e,3b693191,d972fcdf), +S(42829070,a896e684,88890114,2763cfe,3376ef87,17aabae2,43981213,9be22ded,d15986a4,412faf10,ccfc34ed,162f21a9,54cc5af4,91ff671,c4634947,9e539da0), +S(d9945ab,e280b7b1,4bf7e65d,ef4cd279,57798612,50a1bb5e,28ba8bec,2b66917e,52902f2b,af8976d2,c77a2026,a8fddd2c,8f2b948c,5086870a,168a1ea5,cf43d134), +S(bd3fb006,3748f21b,cda6236d,a13e129c,905da160,2d8c2867,f39166b9,56a37a12,47654773,9e7ad500,cd0f0853,f17bdecd,ff4eb6a0,1af3822a,1201ed09,a4e52ce1), +S(831294aa,a3fc6d7,e0179ae1,753fb809,1fafa015,9c94c40,a41f4ddc,aa6937c,27509e96,b66459f6,2698d055,7c38634a,543f1eac,ca68f3bd,4d64d3c7,5e5b7e07), +S(c74d8a85,c5d11787,31b8d227,b74cc264,b2ffeee7,ca997e49,d1b0349e,2fc121e,5e5fcdfd,cedc03b8,4555a2de,118e494d,2038a2a1,27913850,e816f707,fb9688aa), +S(1cb36b06,a6aaa255,8126fc5d,b69f172,be012a58,de7d8688,5ac5286c,33e7a20f,a84f5fb3,67c6726a,e8b60e7d,d4302e7,dcd63930,2eb425d1,b89ac986,ee0e6d57), +S(5d69d200,ccad332d,faacf513,433bac35,d78ec863,2928331f,eaab7dda,69a5ce14,4370dcdd,77fc209a,8d558c09,cd6040dd,74ff975,b2b94436,bd2ce044,214926d0), +S(585b2e1c,b53d61de,89fe127e,d20f23ee,26dfc569,67659aa,22a35928,af247514,fa29933a,8ecbd8ef,8a7e94a9,ea267f31,a2deb759,b25c1762,1753bda4,d489c1bf), +S(a222828e,1568c08,3ea870,50f9cc86,17daade7,cc60a72d,a8762f3b,40a107e2,ec282fa1,7a70e5d6,529e5d44,15dbb61e,8e4a553a,11d39f4d,e3183126,73161aa9), +S(b879ab5c,38135c35,a57ebd6f,1ec01a9b,58758942,7cf9dccb,3b6ca8f4,dacf14be,18d8831e,b11a8461,9deae96b,60c656d9,f4ed65d1,71a0f22e,27d6931f,7f34a310), +S(39168674,a5cd3c38,ec3a8293,78a2d108,d44f4fb4,8ed3b09,d491c127,c8f74a0a,e65c3f7,8bd0bea0,e96e728f,d30c8d27,10ff67d0,23dd218e,813b768,b4094faa), +S(1a4db770,85065a91,61573aa4,b96aedc0,5d81647c,fba56946,a5e2ea1,77e7bdfa,78b0b79d,111c0203,ffe518fe,f08d517,78f1a564,d21e2e31,cab63d69,1e0b1290), +S(90b6412a,2626e9ff,1dce75df,c56744d6,f471fa29,d676c0d0,cc8bf515,47b9f0aa,4a7236f5,81fa2637,ae532b97,c89fd6aa,fd2db809,6b8d2b1b,cf6c9ea2,4b3713e2), +S(a25e3d8a,119b1f0,6474144e,81677ba1,811dbfaf,195d460c,1624dee5,39f29dea,cb0591a3,816a7a98,5875ed34,5ecec9c0,cdf02537,db28464c,88022850,2478d032), +S(5dadb41c,b58297b3,e84d87b,275198e8,76c48bb8,aee3041,ed14f7a1,394bfdff,8db26ad5,ae662e79,23ba04a5,87e7b2e8,f64a52be,8a76d4e9,5193e94c,9a80f4cf), +S(29fb35a9,f0e0b7a,d19d8af6,c4dcb5f0,19ac7cbe,b7bfb535,d23de4ea,33df5d00,41ba5e42,64f63b20,eb37839e,44deaae1,47bb9a22,1ef94ab7,737efc3d,ad61693c), +S(7270c153,a2fcacf1,18644892,7795fae1,7fdd4fa0,3e9ac70a,4fd38cc5,c5e3ea33,f6c35e5c,cf398440,a96d4c8a,f981fa04,567851eb,75431a14,83e026,ff6649a1), +S(70efa7f0,33743eb,4f25db9,c43463f9,77a2cba1,ab8e08f8,59fa7780,cf7129e1,f906a344,8cca0734,ed895706,7374c12e,14e6b573,ea4c90a8,b7376eb4,20adf7be), +S(7ccc2d79,f905ef7e,83b888ac,ef445b4f,a7320fa3,79562154,d0482d62,cefffe38,b7453f38,9861e0b3,7596d5ac,e41dce1,bf45374e,845542bf,cfec71ea,76bd4cad), +S(f171415b,58f085bc,cecaa5e9,b9afa67a,a05d9577,a28ac4d8,496fcd12,9b50d0e4,95257e0f,18ed2c0b,aa1202a0,e8f62779,a7add6b4,d601deb3,4944e59e,2e638d56), +S(39baf2a4,d41f3930,33330786,9f181ce9,e15e895f,2f209948,999ba05a,350a08ae,5f4a9728,b84a666c,6a6e8318,9f1e6f91,7c97a419,1d44c8e5,6fd6c358,445be74a), +S(b146000f,16103232,297377b6,f31fc96f,afd90cf7,27f0b056,55e41f27,1830c607,92adbf3,b453cd13,1e8cefd9,1884b3c,b7da48fb,24195581,fe59d23e,9725e0b1), +S(d6127f7e,e94765aa,aa2c463a,dcd518c7,e60ad583,6bd485f4,574e9e09,57ba6556,31d3eea2,a91bdff1,6a420533,2e768ac,2531f0f2,c9d94656,26472c65,4d665745), +S(cd28080,e877f416,d6302aed,aee760fe,a2b0f90b,23549aff,87ef8af4,3841a67,f67c8c08,3d69b201,6f9261f4,81e0bd84,568137a3,777fcf45,e4a4c90d,8338aa19), +S(78d35f78,96872666,aa5f339c,b6c68680,ae42cb38,c75bc287,8e9dedd9,3b0ad38e,7544e0e1,4fa07cb3,9144fb53,7ca57508,58d1380f,cd1909b0,56b722ee,fd55217b), +S(aebbd769,392bf374,2e771e65,761cb834,d8a09f94,400a947d,c6fcf062,3e0fdd6d,15bb21b,35f0abca,5f7755e,79cd222,e58cf089,af78cd0e,8e4a6df4,4576f6d1), +S(cc7bd0af,bd44445e,64a77303,5b66a1ab,e990bc1a,475c0454,2c2e23d5,913c6878,b0bc23aa,53ccb546,51972c58,ceaf865e,1a892ba2,bb7bf626,15793163,14663e29), +S(94b69939,f6ab4f6d,6b5a18e2,4e929afa,c83c0c98,cccfe6d,5b0c1487,c5915805,cf58329b,c8ef2ee3,52ee357d,6ed05bbe,ece97acb,7936bffa,428a6913,1e3e678e), +S(4596a3e,b0156e46,c56b2492,6bf8c419,42588055,96d160c2,fea2cd15,1aa84b61,39740352,fe7ee595,2e114853,d0334099,5e9a97e,f3fb66b4,fc6b1e02,632a39f1), +S(b577c857,297428bd,c331a8e4,e46afc59,f7b2ec2,be244cc9,f52a6d4d,b41025a9,529091ed,1e5525f6,e7746c36,575041ca,89ca74f2,7a7f1378,2a36a8dd,5526abb1), +S(623cf92f,7d87dc8f,74661d3e,411aac0c,a6c9191a,1da93b06,4f756cb0,3b7a80d,6909b404,ccd9e564,b27f82e5,ab6348dc,de6cbabb,c40d964d,daeceeb4,d48d3acc), +S(e9aee76c,9559fc77,5f473da9,faf84e81,3f1d643d,693cac55,3b96e27,1197401a,3893a6a1,10d34bb5,bf007cf,c116b17e,287d3ef5,2451a3a4,e8b251a7,90c5c2b5), +S(2581ff3b,48d9f30a,e533c291,be7078c0,41d75248,fbe46a8,c984e6cc,3880dcb,1e15247e,b97fb35,14da7f82,895fdf41,f84dfcd,9501cec3,c12b1524,be8cd289), +S(72162987,71924cf2,83db564f,c75aa820,4c9d0d9b,6acda46d,7e328c61,a3147823,88da7231,356038fd,c4af67b,3a852a38,e6e12c30,87388b21,c6f357b5,37d25dfa), +S(3a25426a,b615a75e,f8a6d5c5,a5e632a2,6e8e79f4,59eb209,ad7594f1,1669cead,d5316c8a,6f24a055,1d8eb237,91b9aafb,7a00e304,35101080,a543c519,3331063), +S(ab26ff41,8cf02d7,57a0f582,1155f54b,2b5f796,b201ff90,cd78d9fa,76b45ee2,6dc0d3be,9c7e0cf6,60e5441a,7b6fb9dc,fb24211f,cd727441,dcf86644,8e83ebef), +S(9ac8ea3e,fa78c588,69cafe04,23fa3ad3,176b9234,5a3c4cf,8f2bd449,2fa38ded,4d8b4740,b0aa16,ef6a54c1,3591b0dd,58e4faf4,a28aa4c4,b1c730e3,ad66836e), +S(4c1c869d,464634bd,d849b99,a04632af,b8213762,c58d8ae0,858af29f,4a26c0fa,8c557687,bf3dc006,a90f0c3f,6ea33067,ffc34b38,9a75a2ac,3ea843ab,d7af17f2), +S(f73695bc,c6dd5e56,8185b3b8,a99182a9,f04957fd,33cb7013,d887a55f,32eb746,f615ef29,72d2cd2,c4adb932,a201567c,5672d44e,529a1248,3bcf05fe,d6b86fa8), +S(41e8d3da,705535ab,b53ff304,3490e669,4c1f754e,713afbed,34b59a59,c18d3f9b,6dd0728,21533413,b6011200,e4320941,1df89a1f,efdb4c21,8453606c,957cebe6), +S(623f4475,c0691617,1c7cfd60,2684fb11,24f934bf,524559f7,142404ce,d353e0d1,8c94a4b3,bb7de410,fe2e3d1a,c41f2bf3,c01866a1,5e354fea,596bbd4e,e90f08d6), +S(961dcf95,64da916c,9a6ed43a,a8028f8a,8c65a1fd,d561cbf2,a0d80bdf,ef10566f,4d3a2dda,d5d81a8f,9e7940cc,957a4646,c3b7a734,457ed088,998b0c10,1987f16a), +S(5273adab,8a2411b3,6e2566f0,a148d688,4003748c,c3bb79f,6bf48340,75f6ea62,780cb632,30acbef8,bca93510,74a28fb5,51573656,1802992b,52f64319,393cf529), +S(170c2667,d45ccc19,7ac05e5c,2df7a0e3,37ca47e0,68f360bc,ee9c2134,81a0a8e3,6e82b129,6d24dcab,c529e4af,538154ee,319b40df,1cf31f7e,23fee9fb,4bd3a8dc), +S(7a240b1d,5df36af9,b4d1b988,c428d12a,e64cebdf,280da6e8,dfe0d7c0,117f8e2a,d5a877a9,dc46a181,6939b345,6015c592,58591cfc,63ea46a4,d228ba1e,465ae6b4), +S(6a6564a9,abb91408,c90a508b,252b68ea,7b11cb38,aeeb6bac,4eeee422,6058ff9c,2f4c5766,e3dca65b,f991b74e,bb0c64b0,2bd2668a,62e4b97d,8f3b35e1,c3ce614e), +S(87aee56e,bee43b0e,d0fbe101,93218ccc,9d4f8d9f,c51a8780,e0955316,b97c71e5,b2979915,9110931f,d2d9f95e,d6d5217d,6d957a,c2bc6f3b,c23a4555,e19a76ab), +S(193d15e,6ca2fb6d,6ec3b10,945f1174,8476fb29,327e941,ad1f8ccd,d7d41931,fb7cd3c9,2cd51aab,2b78b0a3,b9e5f78e,5846bdd6,822e1525,10d08357,3bbf1ba4), +S(352834b4,5bff7ebf,b0a20cbe,13d51e8a,b4854209,a8c918e7,67f6986,b4c1f0cb,e2676927,9e22fddd,dccf5a71,c4b33ca1,f8e5cf24,43388704,721f3c3c,8669c8c3), +S(843ffda4,5e72ac0d,b27a17e6,65fcb27c,34d325d1,325612ba,6163d5a3,9b16e8ef,e39834d8,c2ebddb4,791a5ba9,a525e210,acef4fe5,9184e737,851785ae,9b228d55), +S(b34d4e5b,5f86717d,2c77708c,a14f42d,4ab21bfb,de36ff49,eca9ffb8,b92192cc,6e782729,bb40e31f,3a0ec687,7a6bd690,6282c723,5691fb73,6baa16bf,ccb70670), +S(98b7f92c,4d4c22c9,2783b2ef,a38b71ba,477f79e7,85d4fb11,acfb2880,709b7172,e30e234e,af0847a6,ee61a5f5,3f0f413b,d68b115,d8a726c0,61032d6,70aadf1f), +S(4e7e4cc7,a37110,6aa13c5a,e47e6962,eb774d7b,5b25d31a,7e6ac83f,ec89402d,b14d199e,9dbf18cc,e03f5cb8,e3e0b555,a6a7cde1,2fc6ba42,52956c43,27f874f7), +S(4db22218,59bcf734,f25d2a16,3af8f5a2,58422913,34bd5e2e,4a322589,d0096a61,b99740ed,41165371,e1ddfe62,4e6f3a02,47ed46cf,4c589067,d12c3a38,b75701e), +S(f1fa9b2a,6983e6d1,b36e4172,20b9fbb3,6ba4383d,cabb2da,845a63ca,8fde624a,539ecb7,cfeaec83,22861a97,4738844,53795076,1657378c,8950a660,251c50e9), +S(eec0d4a1,f551ae4e,f54ba956,e84de711,1fdb93e6,3c7b64e0,bfd4ba42,ff91fa6f,d16347ed,3ea3e986,a1067fc0,a1e443fc,c80c6277,f1018148,744f5faf,65391c35), +S(74be2d2,526daaa3,3ab34527,f26e6979,4d9dc930,7044da0c,babaffa3,be2eb41d,aec5d61e,477d998e,d18ade2a,1eeb48bf,82b34408,e6823fc8,f7b57561,f0c56ea8), +S(6d248800,29578c3,141a243c,324a7e36,c694ff50,1adc4280,31ee3d1e,ca32aad5,58acf9ed,b1b5ddcb,72da7a52,6cf089d6,839b42b7,4fecdfa,b7e6996c,d80c3e96), +S(7525d819,d1dba5b1,1a36a2b5,62a6e65c,3d2d1128,8f1945c6,7daa7149,5894c52f,458998fa,b2444201,b8a57992,50b76be2,f79599b5,fc87f83f,d47eede5,feb5351)}, +{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), +S(54970cd6,a06f81d,3566c34a,ed5eb8bd,aa49c821,41b6518d,88efb994,a67d65a2,cba9701c,b3f620b2,b4756bbe,1d7b39c2,2226b871,19e7525f,ef9f11b5,c2ba0f36), +S(f9b9b054,543a96c4,25baea4b,5b1d7b60,81596be7,7a06f02f,bcc4926e,82d2cc91,1ed468ba,7a674ff7,4e872773,85dd5fb7,fc1f1603,a5a8f249,c808aa14,775d54e1), +S(5d3a25b4,dfe080a8,a13823aa,77847487,2e6ef73b,5fb862c8,5439fe36,cc93bd64,5f49d6f5,507baeb,5e0498cf,83f218d5,743b4d93,82cf0770,a734d6a8,af76c5d1), +S(1c8ed0c3,6b0ce521,89f5ad75,8189df2b,77646a19,8fc3b7a8,9e48f978,5f903409,126ac278,e1194e47,39a5c44a,8b62640f,bec259f2,28f479c0,aa4e5abf,861501d8), +S(c8665b4b,43e23686,e27d34c6,d6739250,4af34435,287e78e3,f9e054f2,33f22168,34161d68,636cc48c,56d9618e,1c92e9e5,83c5fa4,f87c1f8e,126b1ac5,ab79fa7), +S(e7675296,10359a1f,29d2ed5f,4ee7cbbb,a4e9b5a4,5ed6cce,10d36059,6ac24773,25662f83,ea425398,328d3874,a63438ec,3995da3b,a5a731c0,45b8d269,f07a0b0d), +S(875c0b21,43d3a01,b6310ea4,7726f174,e8b9ecb3,34b65ea0,59f877b5,e7455d8c,8712b814,a3ebe72e,df1e3899,bbd34bd8,6d021e7b,a2e9763c,ff526e35,4a4286ea), +S(d4ef4e,78f2d6e9,b0e717f8,21c1a56,3902fe88,c47f208e,facb68ab,5c176f05,2fcbca4e,8338fa10,22b432da,7b40070,90473863,14e28e04,268ade75,57a2d554), +S(31513428,e66de83b,a631a2d8,44e054dd,8ecec644,134c57d2,eae9f6c8,e5bfedf1,316bafd7,aa48ab94,ae682ec2,ee1bc88,f04f2c50,c975b441,f28143b5,5d4bc909), +S(33260c29,cce9b856,dc9a50e6,d41746e5,e73fdded,1fd25d3d,c3659fd6,c2e72575,665cfbbc,9af473b,b647970e,dddc260e,d53af968,79c0cad6,e12bcd3c,392a646f), +S(b49a875c,d46f3ed2,34c3b611,88046b4c,aeffcb5c,1c7b959f,60613357,b6fcc13c,76006cfb,21f12143,6684ecfe,1524011a,a08ddfd4,c26a96b2,f56da73f,ef05fd37), +S(bf528e3e,7a8c7c91,9bc3e4fc,f0cdeb0c,7f8b58d4,4afa7663,e2fd2233,751e615a,c7e0587,674f3012,f05b7d26,f067b45a,8efcff89,bc2f341f,c0f2a829,b2d50b99), +S(b358b816,5db58b6f,64118a5a,53b0f2e3,c319fc59,e4a57657,1fa54214,108d66cf,27cdd287,96758b2f,bff761a4,9daaf43c,8864d04c,dd6bb8d3,669f393a,b74ed23d), +S(c8214724,1e0b2fdc,f054d7b7,75452bb0,98481f33,ef81f4d6,19fc8bad,715cbb76,25808ef,36f52935,700fc3c2,8f02a6a3,37b06ba3,75864817,806e35b7,26a3e9b2), +S(88c95ba8,4f5fea33,e8d848c4,24d4be91,9bcf15dc,988fb9f9,b14648d8,3bda4294,339240d6,a490aa81,e6cd03c8,af69fc90,fb43de16,e456e1e4,40334e8f,216ba662), +S(1222eb56,b6341323,87f28674,2b495da2,ad989e9a,f5dec72f,21022834,190b6a5b,30e95537,c9516bcb,8ba67b77,983f4eba,3a706386,af400253,2f54b15f,9894f072), +S(5adf18d8,e472cda5,d379e5a1,4f66cee5,da7ac014,84b685ac,9234965a,27a0cd69,b36994e8,d17c5c0b,1219db4c,1fbf5746,434c094d,e53e63ff,3d9b4cd7,ba429d1a), +S(bf3bc2,56f019e5,8c0861cc,91a5dfda,bee7f384,70e5462c,5605973a,519c682c,38356061,b7015d4b,e7f43f21,d3b76e9b,bce0c749,c7e0d96,e6bab6b5,8dfbd650), +S(10aa56bd,a7ddf207,c898b73a,22f1e8e1,18fc453b,e1539267,be025cfd,c8194571,be79e52f,59320f5a,65626557,e6218a7d,a4cdde5e,ab00b23,9b411bfd,377767df), +S(2b2c0c46,900e65c,caa1339f,34d1449d,91f937e2,2524df3e,95d9a370,d940f31a,615780b6,6839ae65,87a0bd3e,45d38f8f,d4413e3b,ca1afe68,944e7e77,917d0182), +S(a5f75480,d53b0649,dd72d8eb,a9275117,b84fc3be,288fa3d5,e274a287,27c2e669,a766ce73,12b8df27,aa950f7b,29c767e,fcea1614,de5a6b42,3a57becd,c496d6c1), +S(d886590a,d11c94e1,9aab94bf,9422377b,528c1302,20c86f14,f13ef07c,34a61d2d,2978b774,2968150c,9dd0739f,7b9c4f0f,a5214f02,f828debd,6826d5f9,62cbd01e), +S(63bf32ff,4dda2eee,8aaddd62,8cd75f44,7535c843,19441e07,801f7339,89ce1ad8,6544e852,8ed612f3,d4df9037,4fd22756,3a5d7edf,df910d68,fb4571b0,679f1238), +S(2e42372d,88db8b8a,631c083,ef77015d,c98b13a0,597c6efd,141bac97,ee8dfce1,6454e588,664fe42c,1e9b6646,e82889b7,4497d435,e46c2a77,fb05fd10,c28986f1), +S(4d3b7d17,a4a7d26f,7e79fdb7,477a8f42,e208014d,3f61445b,6c921a3,d5808110,9408735f,f9c384f0,46ff6b78,5ee8914b,a8da4502,6299e09f,9361fae0,25e8a19), +S(c0c2f170,44e952db,3b5e3125,e75c4be0,4b91081f,1858dd2c,ca1d11e3,bfeb42e3,712c1211,f321e4ee,5b014757,87a7c784,fa00d429,fbf1ffa9,a3884a10,ab633dd9), +S(832a63c5,105ae2af,8ae9a062,9f41bc12,d6d9a16,ad764346,fbf45561,fc721e3a,8eb47da6,f5ec89e9,483abe86,d9419561,26d78380,a6818efd,1d6fbd90,9088db06), +S(56db6941,c03ee58d,c4dca632,db498e62,1872a29a,41c42082,79ec7454,bfdaf0ed,c29ca102,5ea7525,68564f1e,d15153ec,aaee2ec,da3ace93,e580c8a4,93e9e4b2), +S(3b46ccef,dc3a713,10e4c8c9,215b3afb,65c354dc,c37700f2,61635e20,209cd7cb,6fd7675f,b779a43a,ec66d9d,66f47d3a,d41c3e69,9db107a,ece85e75,16d924e), +S(ca4d848e,15b27c5b,926cb160,d79ddd80,c618e30,1d0fc2e7,3fcb56af,5ec7ab10,604ec,e307566e,ebaa545a,9a080f51,e2a0b5ba,4a09c8cf,393bc4f8,6f483d27), +S(53f8eb4f,c8858582,e5990bd8,ebb19e30,fd6dc262,ba6102cb,3b71b6c9,e47c764c,30c7dc5d,4fae504b,56a103d,b9318647,c5582e09,e0868bfd,ebf2d7de,e5f6fbdc), +S(4754af73,cf1cbd8d,c231adb2,3cbb589a,705bb81e,b8ad0ab2,3a61ce0f,db6df49c,6784ed08,73ed3a36,14c7b35c,916905d3,dee4ccc3,ab82ed94,1dd4da1c,1d211af6), +S(3c593952,1d1b1fd6,976eec8f,9498235f,4ed5594f,73f0cf2a,14b8a78f,196888b2,4636c4d4,aa2e1f,c78eba99,2dc89151,3c4e380b,24aa1701,8e99785c,2088dd73), +S(a7b104b9,7c1c0fb3,1d30a49f,b2377ebf,df7020c2,d77b0b8e,b47428ea,c60ddaf6,9d7f63be,bdf87d97,d18cdeac,4f97e900,f5579bb6,6b5da626,154b3950,df14261f), +S(234cc1eb,2097b150,a72f1e7e,4c405679,69cba876,f22a9828,4e639e92,2598fc2,677e291,8042accb,e4639988,d49c85e0,3cafe4ee,601eff33,398f02da,9bffce39), +S(b7d66767,4d02da2e,3c1692d5,1dd8d383,b8456c81,c7cad8c8,b2d55204,79c10ca8,da5b5c03,1e4139f5,24920932,74b15eb3,bbd2e5f4,95ce94cb,cc4184f7,f2344d40), +S(c32a186a,6fc91998,8df6cfb7,d2a39e03,9a60f1dd,7852da99,9af32688,200f2a6e,cd027a9,a1c5d0c7,6381638b,21f5bf33,71514b49,9733cd10,fc36e3c3,3e16d262), +S(7d824a92,83976eab,a0f7aaec,4619d13d,abf75df,7062ed63,ab09ad73,7f805f7c,81745e89,a8b8c725,32c81120,c527e5bd,772adbc8,e93c4d03,856596e9,942865e7), +S(ef890d13,a3567150,2f8aec43,59e2e293,8ac0511b,13f99ba3,c1b30a0d,393e0e65,d24a9d5,bab93079,5aafb32a,fb5dd8f5,9589b27c,76a3a5f2,728b5f33,3aaf2e6f), +S(49e7a49f,df1d0355,5a83db30,1ce7de93,84d50894,36e4881,33b31031,4b8ed333,86f8051b,5ddcfd72,3c9b4961,80b5f534,48f9f20a,6560698f,43b5f59d,2205d5a5), +S(87a54ecf,9d6adc7,148da85b,3aacb374,d65eaf67,a978fb07,bbc920c9,f68de37d,7500154a,11651fb7,16bd4b1d,7d74df87,d948ad8a,441cb9b,74523eba,b06a33b0), +S(1c75fbec,2bb178f6,58f8bb0d,58c59d28,37c5bd11,e7c9766b,fc8c71c9,5bcb4fd8,ff17df79,c948583d,ae95c4c0,2be215ca,94189a75,18860da3,55a29332,39c3be51), +S(8b50c207,f02e2d39,dd556a0c,54deb2a3,3a96e8d7,8a1a4d5c,9970986b,46caac7b,9e634e62,448e57d8,8013de8e,6c1dd7fc,39aed80f,5e118cb8,2a659f6c,694874b3), +S(7b4d6114,72e2c781,4cf7a7e1,b2e0587f,f7c758d2,96bde162,7071d9a5,e9ccf458,54092c01,2da6117d,bf24543b,c8143b8f,bb90cfb5,106b3a78,18e9ab6,adb8ee2a), +S(50d14331,162d65b0,6ec4883d,936438c,5cdcc98c,3265b6aa,3e9c898a,3157eddd,2494eb8b,894cde06,5238cfeb,8841d428,e6fc09ea,14f31250,e921f7aa,c5235e7b), +S(c5638477,15e5e0cd,7412657d,63d27e6d,c8126eb0,b353acb,4146e93,d5485293,4567dd06,d6c8ad85,35415a06,eaf9c387,d15ad758,27de781e,f0b2ddd9,fb0af414), +S(cdf1a81d,b618837e,77c4c319,a78ff7c5,8ac2693f,f3ad9d76,f5fe4639,8523d152,3d29f818,1ad01726,f5a57299,e9f8d632,ea50a6f8,f7bfd917,c60cea89,2e026e9), +S(26163253,c6617468,f1b78426,b153aa75,fb2081ae,91f0291d,91785fa2,8eca2271,fe9ec597,5be387cc,600be7ce,28ff3092,fb0cc11e,d235ebb3,bca21d5a,6761f2d2), +S(ffbae863,2dbe89bb,13a44bd4,85685746,160e9cf1,5e02c547,a73b192d,3458b265,c267055f,ade9c7ea,c0ff5356,b3f1062,c764c5f8,b182207f,eec0e345,cab843f0), +S(86e20f88,bd61ef73,2133367e,45235980,b2cf0cb,9801d795,5a3a8faa,53eb6b31,7d7fc09d,a9051669,1772b443,b7204199,51587976,3110865e,96f1e9d8,676ef639), +S(7be39fab,669be73,cea39240,a16922ce,5f1c3bd4,f4036d17,97599c8f,d52bcc73,da152535,716ce5d8,3b223f72,1ead270c,d2f78d83,f1f6b8e,61c6371a,62794829), +S(5dd3e3db,62673c67,112f2457,dc42e903,3b5ea586,676d0411,2c913a03,559c9570,b31c875e,977f1205,3ebccaa7,57e69cb4,d3632130,999b5a5,ef73c4b0,5950cfe4), +S(54692082,90733c07,3032ee6c,208658bd,a87d359a,bf145837,20bdc18e,9c3abf42,a3c73d09,5209d326,8a51d21b,37058b54,93636657,c699b58f,bd209210,f936f72d), +S(d170eb9e,bd80c03,282137c3,a1a36112,e2d965be,a530f5df,fdb34634,32f0e983,82bebf36,6b21bb96,ea0a162b,1a91557,5679c33f,ceb4bce6,2698822,2db01840), +S(2ce91172,e6c42333,67487389,f31600ff,f6f0e5b1,3f7dfef4,5c3119ce,5b5d87ce,3c95d405,30b49147,5cf2e0b,e5e2b0f7,ec84551d,931d09e6,76a1e552,c221199f), +S(b133731d,95483e43,cc4f56e5,127279a8,a0d32cf,26e33971,bcdccf69,e3b04f52,bb69ce36,c7bb5973,794fa89a,d4bdfd69,8bd26211,caca7866,b12b5ffa,fe4c27a1), +S(c9e45724,8dbba2c2,7c9cd09d,de0bc5e4,2bdfe86,2f3a2e1e,12c9126,6861d76a,f36e6024,f5f7c255,e684d368,ed336ee0,668e6bf5,dadd8fb4,6c58b03b,a1417014), +S(99b6d58a,d4524f00,fb7d3c0d,4a521143,fb45283e,2a8f5ba0,e85f1833,5c979828,2acebe0c,9de8dbf3,14b3140a,fcf81a74,b1db3e46,bddd4aed,9014848b,c1598140), +S(2940748f,7feb4edf,c05a0af2,4ada767b,aaac74a5,b1f7d83f,c5590780,640f6d2e,d30e19a7,bb721cf7,f2f47351,a8754476,f97d96dd,39cd6a91,4a97dcea,597e2258), +S(7b53ce3f,456591f4,534d9476,66e01d38,bdb80580,6555d569,72404e0f,5963b5bc,c03dc414,99b7f26c,cd7cab45,c9cce637,30f9b615,19fe4d3a,e9410474,b2f62209), +S(f1e0953f,18f81648,1bc8a21d,34ddb5ae,1fe02974,1dba2322,c5ebf200,31eab9c0,93e9a091,9c6bc9a3,e4a161f8,3f94d274,b1ef4ac6,edb975bf,b62cf92b,97f1baa6), +S(6037926d,772b3333,eb75a6a3,381b3784,ede8cbaa,a4c1aac8,fe09ea20,ff3c6520,45feda12,a4bd9518,96e83b91,bbdd05c3,dee627c8,39c8fbcf,e27a050c,9b082ad6), +S(7f845fa7,49ae8a9f,cb394dba,27e7d86b,e16eb956,b08dadf,a55afca8,5a1c6850,210c0682,9d62dbd3,d1917505,4b428305,78444ed4,ec3ff807,f6593ec2,f39dc1b2), +S(d3780383,8c1390ff,c1b679be,8192b8d8,4369eaa9,5eaacb2d,df7b0d83,4fae6ab,e9d5436e,79c4622f,1ef6a773,af736727,d93f5f09,3d0abd64,acc6f37c,4b7b3975), +S(58fe6127,196f0b87,8acac65c,c0a73b52,7c979d75,ac15ddf9,7858bc4,e4f40400,340365ce,74466016,4887527d,7da89ddd,69ea1bb7,93f886f3,654dbd7d,6b9ea145), +S(798de133,1d82f361,6fe2c597,ce8ef82,9e1419fb,1615b76b,e4e44929,518aeb8a,f8eb34ed,b9275578,74d5abac,2568b1c1,9a751cf7,f2812b64,9b75da50,e0c3d269), +S(ed7c18bf,c58b3202,c97a31e7,4e82aa88,c9d554e0,18afb73e,2b8324fb,bacff740,7337a0d3,f8f42f32,ed0ecb1f,44907dc5,756a877d,d8507b94,442fc5cd,41d5432), +S(41633de2,56410771,aa494b3a,3390898d,e78aeb06,3e8a061e,18c3a2dd,d9a23f5a,ead81878,b28062b3,e421c0e6,c1202092,121fff76,80dbc99e,7af681fe,c700ff15), +S(17392b06,3fcf041b,2cd4672c,780edff2,9e1e17f1,356285b8,e80ba54d,4ca6a67b,af99f6ac,2f9e9178,2af6b677,7163a0e4,b59c4d90,63f8c2c3,9167743d,38231860), +S(c4229eac,5a8333fe,75e90571,5ec787b1,7ac350f3,3ba996d7,8f1c106e,d5f0dc3,9186b6dc,6cc14aee,8833d89b,501e4fd6,ec8158e7,2f96530,4a3a6577,8cef072), +S(a985efae,9458f1f1,8ea8ffa5,84d7dc63,25cf125f,a210886a,e1b1dd23,84c2e786,1ba41023,1036e351,7bf58cab,5870f244,315c79f1,edce488d,35907eb,a5b5e3c0), +S(b5fa6b30,6ba70431,ca33cd5f,82cb1f50,3df04589,c3c66b60,dabe0fe6,e09356a6,c1ff1440,3a4ee6af,940e1af8,f9c2596a,ebcf3691,8f9a77b9,730bf075,42c9fef7), +S(c3ce2028,9e90190c,5ace17b6,7a9a23c3,19161a36,9f33cb91,5cc57416,292d0a8,ebd0b498,59711041,3560bd36,1dffc830,8906263b,a0102ac0,2d871e34,856aa371), +S(ee376a1a,fed708c7,de2bcc3e,54a01427,5e75d8b,a6d8b417,75005eb6,8b29d94c,9c3833b3,1d73f289,cd3064f5,7a1ecdba,48194e3c,66d82f2e,e3086749,62b8aa52), +S(aa25c37,a2e2be4a,7c0c9e4c,e08e20b9,88de0af,880c1a6a,e3117910,9e5b187e,f469297f,1e3010cf,67310d9d,719f7a59,258d2184,1804cf55,66615800,3691a7a6), +S(10ad3adb,7a865784,c2e044ad,19a21199,77cdcf69,3d2d3292,26ac352f,c75d11a9,1e6858b6,1deff39a,1f69708f,56017ee8,a332ab60,a48e2783,e2dbe50,a176f355), +S(5aac0d0b,a2a5c410,39541de6,c53ae936,6fa07ca8,373831a7,fbd87a38,784af72c,4d82d068,9a91355f,6c51df81,78964947,95614a2f,5b5a4d07,20f32e1e,7be78ec2), +S(490efeaf,914e09d7,6bcf2c9e,15553327,d971c363,50fd4134,b9dac978,4a6bea86,bcd02373,44959244,9eec797e,6f50a9a0,5153b3d0,436d5d0,361e7c6e,cf8400df), +S(9c653d81,7a6f45b3,d7e001d1,140fab91,1ee8fa84,1c361ec6,2a62c0d,1f617a19,ccac651a,db81a595,ca2eaa78,f6ddec8,c18fa0e1,7ea19db8,ee4a431b,87ea83db), +S(6e2f2c34,ac914200,759acbba,28e9a2d5,718a682,61d6afff,46171c95,1010c79a,70d43c78,d52dd510,ca0660a5,40ccb0c7,75c446c8,cc5544f6,32da3c20,8fa84e80), +S(b5b1797,730398e5,c056f91c,3c63d762,cbcbf871,9a032ec4,e53a49da,6ac4c7e,db4299a,1e5d8330,abc09c26,191c592f,556236f4,677afacb,b9c08b1f,2e0c6dfe), +S(93beaed5,d689a857,a5c95522,3520b40d,a9616adc,a58e684b,6c47b343,cef0e604,7e04853e,283c490d,a9751ca2,35a3dd37,11597e26,6391bcac,443023dc,e7b58199), +S(d67e7b92,d30dcc65,ab6dcb6,da8daa6f,42aaa41e,980793a6,2cae02ca,14386b45,6903a40d,ada98666,40583bb6,7baf9b3b,4320b11b,ed904987,f11f6ef9,e985763e), +S(31d4214c,d168bba0,cde7dcd7,54415c1e,1313c411,ed3076a1,17e29a84,184ede0d,bc2ec4,65cd6863,5389a499,970ae4d2,953d1b8a,df8a6190,8af2d7bc,48c4254d), +S(4c03265e,9d1b0818,a0249b0f,acaec62d,13525fe3,3a963dfc,7cacf779,a94e42d2,4fc53174,762449a3,a54546ef,1a1a6012,4fd935f7,13fea628,1eb231ba,27efd9c5), +S(9eb8fc83,a180b5d1,d720fd4e,6c873866,1221f706,961b3087,80b226f,7f3bc065,aabb671,9a5ecb53,9266139c,642a24d9,892d3367,146d5718,bf6e2efc,d7db3dcb), +S(7cbaf999,bf2d62dd,cd5d521b,cac74f1f,4e0dbc64,ce42554a,fa140e01,c1ef4a17,a812aaae,59aa8835,7095750d,b0efce6c,411c7d8d,32077185,22470643,9e8b4094), +S(a1cf427d,9a247655,f017e35b,4f5dc500,f91d2936,b54bb1b5,cd928f5a,add7d9d5,92e76ff3,8fc6dd90,67a38f3,c974770e,ff7fb86b,b9c4cf19,724decf7,682ebe14), +S(ea47daa1,d527592d,a1b67019,acf67b5,3729c0e0,44ad194f,4a884df5,b64d1e88,8a8e6e8c,70c33c68,d249c670,3133a665,359af2f6,1b339a26,6c64c227,4091a909), +S(d2bbc061,a7dcee9f,a9d0d95c,5de7c07e,6db3ff3e,1a051042,532c0ce6,be80730,b00cc82e,6a643f46,2a605720,c862164,da039008,34f30f57,77d15564,4a85ba4a), +S(467b855a,410a691e,e4b0a463,4252d6b5,c5c6f075,acd2d942,141c2db1,fd6daeda,6fd32e37,9ff7ac09,7b9e987c,6fe6dcf4,628756a2,48dfc343,9f127a64,50ce339), +S(841cf771,c0ffcc5c,4a5d30ed,2ff39fb3,c7e3d76f,b9ade58b,2c9c3f91,30589bf7,f4bff35d,98ff8629,a9b48cc2,fad49d8a,88ae7957,33e573a,82649d75,cbbc4c32), +S(5d9f954c,d2972a26,7110d9f7,dbd34b85,ad9ad480,769b7d17,bed01d45,d523c583,ce860464,688413e6,ba64468f,6fde939b,1f9e3d95,b7955a50,6e92e235,c1f85b87), +S(1dcfbd70,cac8cb18,31531b3c,256ae415,eb846804,663fa826,7b1edf87,11d076eb,9579cfae,31cb98cb,62e54b86,cf90abeb,4b537093,898b732,98263988,b870288d), +S(6fb4b3f,2ee3128f,14d810ea,a989d5b3,5feccc55,8d44e3c1,694e5dbe,14d98cd3,f67c8f00,9205f82f,cd2d801c,6a19e35a,61ba0cba,fbbd15f5,c7259a23,14505719), +S(e17d12cf,d261f5ea,db611d02,8f3720f,e4d00e61,5383389f,48c59c0,791263a7,b8bbf87f,4aeda898,1c3c2ad1,f474a7fb,69f45180,57a8011d,7456b688,3839bf4f), +S(3fd5048a,4e2ab188,6f0b1cb8,cdd59182,3e94d853,b9640a33,cb3f5718,ac30f3eb,14d769af,5dfb719e,b4a154a1,f93e10b5,c1d23993,36e1597,2fbe4c76,9c088441), +S(36941001,5302571e,d7c4cb7c,3d479f55,e89193f7,5b52bc7d,d65ca207,41d14b2a,c747a1d8,af196bed,df1c5321,d58a0a19,171ebf1b,1a855b9a,3f90f16e,c333393f), +S(42b5541d,e161fd92,f2b92c12,826fda42,49f05c1d,2f79d951,1ee4fae5,3269e1f9,d6cf742f,11daf585,bc7b4be1,784d55de,2ba3b918,4df6d81f,723eb593,2862dc5e), +S(dcfe0685,c9452c9a,be819a8a,574bc35,760263a5,edc0e018,4093cf0c,b4406acc,fb84c487,873ee72b,49dd61e7,46a8cc1b,8485c4e8,fb5f9725,a17d98d6,62aa9d58), +S(cc5e07b4,c76bd9cf,c9b040bc,c3d0805e,487eafb4,430f2265,adabe2e,7bcd5874,6668bcb2,7a297c14,d4a046aa,59028e39,be049894,764193b7,9dc1658b,bbdc3d25), +S(74cef0b6,e59cdf5d,47244fed,491b6c0e,76d9b185,1a3f084f,9f783a67,d5f4c70b,3560eae,9a4c4b65,3831bd98,d97c5213,25b07f32,d40b215f,a93f2332,b6a8209a), +S(dd1b1359,4ee43b44,1f54a620,6e6295c9,80bc664e,3b5c19f4,273e878d,3340b605,4db95cc0,f8e2020b,c0f0eba9,d21cf630,e6c5ff77,dff8bb2a,8b496dd4,22cf6a0b), +S(f42815b4,76b4407,9ec05cfe,aba6f179,b72dea78,767fedda,3464e9c3,53b3ccb0,89004efd,2cb91fab,7c8908fd,b454672,4ad8d851,55473b21,e8e3d984,6d913098), +S(f20d41d8,c096d2eb,d480f9da,5df1bff9,570dd299,16f87ca2,19ed3fd2,d6c072e7,3eab3c48,be7e6d6c,bd1eed0b,33c54d49,72d96f86,67bd857a,8fb3190f,92b22a9d), +S(d84b9d43,20d76cb6,13df70b3,d0dbe935,852fd9b2,86978807,b6288a3d,27828a28,73c0bf55,de9ae18c,a56b98ae,3bc86a48,15d1265f,62d5856,f0f2b182,b4596941), +S(ba0ed2aa,3944454c,7581223f,d1dd113,9d340ee1,11d08d7,98f278ea,7160ca10,766d5ec,49b48092,c007fa69,a06b22ff,e02cbc30,6cbc75ca,1a5f0058,73c44299), +S(b5393ee3,7a8170c5,bbbf70,fec33e90,71e52f4c,47e21d79,e9f7413,d68050c,7eb93838,f871d769,733ff7e7,d21e3848,8632b7e1,6483202d,50a2fab7,1fd7180c), +S(820d66e8,41b5de10,e28c147,d43a0116,6cbe764d,c8ea6a42,e7743732,45b84190,cf3a65e8,80727c33,3e693586,78033805,6482b2e,53889a0,bbf834eb,c94ebbf3), +S(247cc086,26f54562,8d48634d,4bf7348d,cf60e598,5570527c,c20ce901,ef4172b5,acc2fc2a,9c939cec,a51312c,d56734f2,87d906fc,c4d42f17,82606c37,b0584dfc), +S(81c41e2e,752e0d9d,c66cc618,5aafe042,8733913f,5b597ad5,66706d72,da80dd05,8ed860ff,846ddc23,e466619e,480d944b,f171707e,721110bd,119a128c,e8a623ef), +S(24a22359,7bca9222,dc0c82f4,b7ed4ced,f5f41ddf,73e5c8a5,88bee89b,3b21fecd,7555cd9c,da2e75c6,d8c5fea1,50e3feea,b3ea1573,d7c163f5,e43b3d2f,31b0f5e6), +S(db074838,ae29a327,b85361fc,c9ad2bba,38917d58,c17ec58,9c22d6a2,f9839185,a1f7280e,35bc6b7a,b05c1704,abb46a90,43b3f7d5,30434450,f94ea1ff,f787412f), +S(6adb02c8,fe669d1a,8c7fc3e0,60eee0f0,73409111,c6013619,770d0ccb,bd8b950f,3fc12c9e,b1d19234,737a4e64,9aa06032,35d4538a,ecc6cb9f,dd1f7777,46edaf5f), +S(e06dd5c2,1d109fb6,3e5429ce,11fd5a40,5118a84f,863095c7,dbfc2374,6ce1429c,961b9d5b,c5b82b23,c8e69b15,15e28700,13094f48,c8ef49d9,37e1b440,c306eec0), +S(1b599e47,ef4e5369,bba2a71a,98cb03b3,f5d9d30a,a5e309d0,cf7e2d19,27f95c18,5a40c3b0,b949efeb,ebbd0ee7,1a81c9f3,d6fc20f6,c9effd98,f0492ef,82710072), +S(92da076a,ca5c2267,67abef5c,d06a830a,a6cd1d3a,2224a845,184b2e7a,275eebd0,db28e087,d7e29f20,d78dfa27,bccb47dc,f2a3a9ee,db0db1f2,63dad719,4ce9e997), +S(afb97660,7b94dc70,a87a2be6,53ac2f3c,9a2a474d,ef065f77,b06fd417,44b13992,68d14dd8,e3caf1c7,e39ad23c,f8e83577,d047530f,2c7d5b35,c509a3e0,51eb52ae), +S(bf4f278b,e99d1297,742600d5,d7ce7791,970de902,aad9920f,a8083a3a,a50229c,b4ed5f80,f3995be4,22fa8237,d77b1424,1fa974b1,9b725016,c20e555e,f0ea2bed), +S(c059a980,f1a7c648,95a1acd0,f9d2cd8,9dc02acf,c372740b,86fd64f7,426ff54f,dbc12822,e8155685,170456c8,4d548f39,afba1676,15655d7c,7b8c31ca,499902b8), +S(2f4d9b08,282d9adc,2d80bc6e,b4c1e2e0,553971e1,f42fb8ee,be615d47,61c023a8,fdb056fe,3604068e,2f5e5223,d3076d67,41e939fa,f2e7d0b1,76d3ec89,868cbc06), +S(a7425d49,934b13ec,85aa5c30,d628b94,f0054374,19c5a0c5,6e126a7b,261c005f,f475be59,d5dd5a7a,42d15531,df24fbd0,12d84fd8,e89ca95b,23bdd70f,10b0326e), +S(dd3d3a96,cd232751,5820439d,6455bb3a,d749947c,884a2e90,5791253b,aad726bb,9afe6071,4de46f80,d22b7ac9,a555a7f0,6e830819,437e9f98,b944d8c1,d4722027), +S(7c427ec,eed88d6,a48f7204,e43ce8b7,a4c5b6fb,ffca57b9,bd128903,c3c7fc46,495bdff1,9b1711e,918448e9,a46416de,e2d51771,43007e1d,c1a64b4b,8d1a815e), +S(bf610437,6539cc63,4a1f3e2c,4fc3f762,69752d64,2756bbfe,83bdc404,f7be496d,5bea9e3a,33d7318e,9c03baf5,3e5a0232,440ae61f,25407ab4,23514eda,1a69513a), +S(f2dad2fd,178ac78a,168981db,14c4fb0a,f7e69dbb,453f0d53,456470f0,a22cc730,e571813b,2a091f17,23c21818,789e78a0,e23e74bc,b4d037ed,f8f49fef,9623f42f), +S(51243664,8693af91,8c79fa28,d7c12b37,db24f719,bc0dd0e0,28c6c1ea,19aa42e3,fa116d7d,7ebcbfdb,8ce76cbb,e6203cea,25b65559,becd1ca4,65f7dee2,6e49746d), +S(75f316f0,c9706cda,9cbf6c8f,31266c75,5183ee71,a098359a,ef06fc3d,ad645fb8,518d90ea,af8ffe9c,44cc122d,7659d292,8a979e6f,de2654e2,e3554b71,b9e7b820), +S(565d92c9,93f08563,f65eb65e,6ae4edaf,ee409d1,e00a4e74,5d439d84,a431a5bf,b8cc1eb0,1a532023,ea17bb56,f9345420,a40b0a7a,d247ac43,4ac9347a,51bd0f31), +S(64b17b4d,a0341dac,bbda0a6a,e386e2a,64d0e517,2a4b904c,b26e45c4,497554e5,4028951b,3f17ae55,d114d6f5,ae793460,91d8d00c,c1b2aca4,f0d5b51c,3f8a7492), +S(70ba7f8e,65669610,5496614,c6c1ddef,b8c23f0c,847d8be8,37b4699d,511e3ce1,cfb1028a,2ddb2865,633f358b,e6439ba9,9fa8b1bb,eed6d988,e8652661,9bfcf28c), +S(84c79c6b,23bffd84,4cdc85f7,3180f451,3e6cc4fe,adb7056f,7de267a4,75605d68,beb80b8c,3b2ddf4c,2269431b,bde9aeb3,55e97faa,385c8776,4bd15fd8,344e8ac0), +S(c6f4eb7,106cfe74,82cdfeeb,af421137,f8665713,10616b0,b2b5ce07,8f5ff9bf,72ccb3ee,52b77765,e931298c,204e7b07,57c3845d,5abe7ebe,37db5aa0,203fc81a), +S(c58b8483,6b41a2c6,f56abcb,61cb493c,a314063d,9091ce1d,9b13cdb3,fad79f90,a1e846d6,5fce2f4f,37e210f8,cd7591d3,fe1f6c93,7fa4ac4,ec295078,7cfe84d6), +S(96e430c8,2a74ed53,7f5a181e,20faea66,ee77588d,66eeaaf7,50dd5b7b,e42ad21b,5aa2ee54,96d711c6,e8b95609,ab383b4e,993f928e,d76843d4,52a5a1fb,3e137368), +S(53868e1f,bd086477,60aae23a,3f2763f9,cf6eed71,19ce1c17,b226b48,fa85b8cb,b94b6a7d,4c86d90d,98c8d359,45949b0e,9c958ea7,651c901,90e5988d,e142493e), +S(d6bbe341,8a6bce46,2f091e5b,161dfb15,8c454eda,add230bb,254a5989,df9ef899,f1690322,6db63393,c01fb1ba,3bd83bcd,dc95741e,8ffad9e,56efdb08,837340ac), +S(a496bcf,4317fb5,c87a41f2,58e716b,98f5305c,fc957c83,c2c40397,49de94d5,2479a3ed,e3fc60f5,ea880b29,353663ba,6d9da119,52468686,bbc2d0f4,fd8dbe21), +S(5bfbaf07,3c1cb96c,45bd1191,bacd3bab,8c33ef0e,e9708164,98240b52,3f943be5,96009bac,6fee957b,2e26f717,ddf40b4a,69cdbd5a,946e70f8,b70587c3,b7fded2e), +S(955fa716,f7f0eca8,325ead5d,dac3fed,bc477c22,3c0fd563,2e37ca69,ec79f61a,418c98ff,23d7de2b,2460806a,75fc0328,5ffe9660,b7447a36,c088883d,623476ad), +S(99d3b933,e7d8c8,e1480e6b,756732a6,445036e,9b964a32,53f3cc09,f3d9211,97e70dfb,faae8f58,5a7b5da6,b0c775f4,9c095d13,5526b521,d57c29b9,b2892dae), +S(a01775d0,5b9d2fb1,277f4c3b,6edc8f7,c342c3ca,e9244fee,57cc2d9d,d5b096de,376293db,5c929468,236828a6,1e291811,316ca7fd,90efda51,2bd750f8,62ebabd8), +S(697cb417,bea89412,91ec8ed6,f62f1914,96a22208,905dec11,463014bc,2e9a04eb,d5049ba,aa04b285,f3085c24,e54ca476,cb266f3e,15699d12,fd250e39,ec4285c9), +S(b23ad54b,f9504c8a,c0bec876,71d2d41d,ee04bbcd,c5ba224f,85e3d4b6,84d8889a,8f0b0da9,db0467aa,5b21addc,d3951b72,8d23099c,47bf7767,24e1eb23,ab32e7fc), +S(c8af03ff,197dd38,cdc294d0,28c0c418,2d517dd7,54669894,812d870e,65160c40,d4537dc1,e594be6e,cf2e3ab8,6f42cc3f,a70015a9,ed8e2850,4fb6f9bc,676be0cf), +S(7ea5647a,f0f8da46,6e6b0615,28d0f472,79ae2a2f,5eaf0dc0,64ccf902,e060cf1a,bc5a47f0,d95e37c2,ad9c5fc8,48eed4f3,c62c974c,9b96b250,ec076851,12a88ed3), +S(78cb2c40,71bc6abb,cbafee4e,cd413181,cb1b5483,ea1db7e0,f902f31b,346f7ac3,86f334e5,5560d9bc,60d8463b,269c2626,45eb9964,970dea35,eacd9236,3a36d198), +S(f968919a,7d90997d,5863c9e4,e214cb37,51dfa039,75d876b2,3f1376b4,ab79cdd7,ae3950e,56e4c856,ee56e236,bd581033,6991f8a0,e9212c8d,9e9079f3,9edc2038), +S(d7c2fe4,6d1ec3b2,3dcf9992,357bffd2,aea9bfea,da187cdd,6bbaeb2,51ebf663,ec953c2c,5fb70a14,b21791a5,979a182e,c3facd73,a59d0f50,c3231485,f376039c), +S(63aa7712,4dfa263b,fc8c7b,85dda505,14d694b4,5ac9f06e,1482105d,ac04af87,d368c24c,18de3ed8,43f521d9,3633e9c1,53627e54,bdc10eef,15491802,41dbd9e5), +S(47fff446,884d94f7,a1b2253d,2f2cb718,70a6a42e,36f63feb,65fd7e98,213117d4,ac52a32f,55dfecd6,68b61733,3fb4b7c6,fbefece2,d2cd43f5,667bc42a,f17d02ef), +S(b3d96bde,5770d471,1a91b0df,17c785c,ff7f51cf,c4d46c27,7dffe07e,6c5d1173,78e408bf,6d204097,40a1145,becb61a9,c78120c9,957c6457,12254e2e,f5a1d77e), +S(f17f1d4d,7df494d4,70321d27,420deb68,22be3877,78df53b2,37876928,d6b2168a,4398f0ef,7cbf1188,dbced020,7b2aadce,440b1df1,7db6870a,a05c6d56,4038306d), +S(10833a6,6f75d109,e5251b43,f05d9069,2bc216a7,bb06032f,c2d142f3,cb1eb1fd,f77ce6f4,73e861ef,23f67a77,a5052dc3,4b617279,1e69a688,308439e8,7d91bfb4), +S(301bd783,a82ad1d0,daea7641,6575db5a,1763481b,3c2f94a4,788f7a54,6f9af647,66ee6029,13b6bf11,e8e19392,633fb8b9,e2a3dc51,bd891ad7,3fb80d31,854333be), +S(98fb5877,816a2c9d,df0192e7,beef06ba,c19b3760,b82d8e08,1f6b2431,dcc20d6f,de59596b,914b994d,83a68c1f,eacbfb8a,17b9c54,9561fd48,4f7f2f80,bcbc24cc), +S(5247f727,1de92a64,dd35147c,879ad2bf,4cdce035,2c077e0a,19164052,e19e2d68,75cae57d,3e54bac5,dd41655c,f62f6ec6,7e84255c,bc0bd176,aa505569,675ad042), +S(51d7bfa1,5829219f,6af5d2a7,1ff220e7,9de62e7c,a3909d4a,37c918e0,6b60504d,9d1a5e54,77025129,1d42c64f,14d27eb2,cadc09c7,bf3899b1,b85119b2,a5326f4b), +S(533fa077,4c05ba3f,b32ac60d,13fcc4b2,a20ccf97,bacf2abb,d2d9b6c7,54678437,a41595f7,3d604126,7b82b50c,22d39ca7,7454bde8,97dff46f,3c57f7d8,ec73e818), +S(a549dd6f,2c8f422b,dbe464c,48f61d13,b3537a7a,2fc5a8c0,91d7d33d,221ff3c5,ad126f86,b69a56d1,2ae18f0f,253a1989,ce80a74f,114e3813,2199d1ac,be03efa), +S(7b9161bd,b4d5e56a,c9df5417,fd84aa54,798b9328,46218731,ea289cb2,76a612c3,72e268d1,53fc13cd,743debad,16c98af3,4756244a,65b7f7b,33794aa3,1aaf497c), +S(21557200,4f644ced,9c2aebb1,43beca5e,d54bf17,d2cb1ea6,492f19a9,25a5be52,19dff558,9c87a8bc,d02af10c,4b32aa25,c80b2542,62ecc0cf,bf4439c5,c2184cc5), +S(93d2caf3,c1a0a83e,ecd9adb9,abefd119,1000e482,2670e678,8859fffa,a2784cd6,f443827d,c5437809,e5cd0eff,b48d7b7f,ed4b3ad1,a724cb7e,35aea03e,655895a9), +S(388a2c3,f621470d,eab3d1d8,765d6af5,629b1cd9,10ad662c,43abab6a,9cee5283,653f3611,7e335b31,48df68b5,a8cf6fbe,134cdf35,f659f14b,9036b933,654df3e8), +S(9d9c6f6d,7032898b,77dc7738,426723ec,dad11684,bde6e061,63ed6802,69aebec0,f20282b4,96183c42,8275eaf5,95834713,338112dd,9f2b0924,8445d56c,15a31276), +S(6e1d3bf3,98cfb2f9,67464d53,755f56d3,bd4de638,4425975,d96df00b,b500e825,6f8afe06,eaa52db7,291b41c5,959aecab,e7111b74,fb260d40,68f2a8d3,895012be), +S(dad8454c,5c6fc1e6,35c4ded8,1f2e3870,a5f24fea,be8b6d7b,a2adef19,32bbfb53,7c6aa3e7,615cb467,42b42973,64222157,de26f811,b4046d4e,591f9824,4fddec5e), +S(5ade9345,11ffa26b,a147ee6,fab27693,9828a8ee,7cbf5e3e,e9052b,a01e0893,ed84e129,7d98895c,b7ceed84,52db80ca,3f44d127,d484364b,652b96bd,82f8ae16), +S(d6e9e33,6a39b415,e5909463,9d621291,9c81a084,dace8a97,a0372042,14cbe366,4f274e3a,1ed0ecee,c7d1d4bb,28712e03,7632b43,e1f8b75,a9100b4a,f74e90e9), +S(a913a4b0,a990ae15,60caa68f,e45bf7b1,af500129,a7bc652c,b47e80d3,34bfedfd,1bea9464,6a332e2b,8d94dc5a,32ce31e3,1aef6c83,ea7a261,99da6cf5,7892f63c), +S(7380fa59,b95fbfe1,8e1c3809,36d10b23,27fcf8f9,21aed806,1c602498,c2c6ca5f,fa24454d,bc8cb2b8,9462febc,2e74fd72,8d300617,a601ff12,a599d2ad,bac2fb7f), +S(9614b47,50073368,4d26bd95,5b9f4df3,8dc11bfe,4ac65d17,6149e1f0,89f3a69f,12a2b07a,49812efe,1d3559f1,e282f268,813e5572,8c959a9a,129ba886,9f06a66b), +S(5f2956dc,436e7a52,176d2709,362e511c,cbda57db,ca347ec,63b63147,33f14d5a,f7b399d7,7b3e1d75,b5578e3f,f324ae9a,76c243f0,8dec8cb4,9bf7a78c,120ede0e), +S(22d7dae2,38885aaa,fd51858,f4bc1042,5d57599,2fcb4eea,eaf6c222,c0ae9e7c,6f3e789c,24247afa,9ae0adf,18bdc160,b1d6d956,7ee8fefb,e9db9ae,f0734909), +S(9e5660c9,a5f53e77,59586df,b2b56dcb,8f1af69a,aabcd59a,73573711,3fbd4dd,2868aeb0,5efe76a6,8037ca6f,d97c2769,edafed65,3f38555e,15ff41f7,fd1fb8c1), +S(7abf134a,123ee2a5,eb4bc1fe,6d06f5ad,655991c3,dfa91ebf,ae46ba80,899adf3d,c96dd41a,238cde21,3f628bba,a2488458,c0e35896,f32cf7a0,45b252ff,ab696522), +S(95da0b80,e45e13cf,f5f4f4a7,5265a310,8424fa09,f07f2c07,efb7a018,b5edc82f,ab645319,b3645cee,d1e4823f,838435e2,79f4f41a,af258432,b210a73e,569bb4e6), +S(8a095bad,b000f2e3,26b0c8a6,f1363fb3,4e2f59cd,978d736d,d05614ce,dc849fc4,4e367851,5c42cfe4,6bd3b6b1,6a09bd66,59626f10,a0087591,6b7d178f,14eae676), +S(de5f5b91,eb34ad1a,9d3c60ed,29c683b2,59f4c7ad,819bdaa5,f751c1b4,7ba28567,cb9d478c,58a02246,44f59a4a,cf2fe992,15f541f5,febe0ebe,439a1b8f,baeaba58), +S(94acffd1,b87c644d,b359cc14,c1d996eb,a1d7e773,d902dd5f,7086502,bef6180c,8e58ff91,ae72b071,abb09a19,4afadb4,b3a54c3f,91857b3b,bad991bf,a605cd78), +S(fb75db19,87635a41,e325f08e,3203e0bd,e7ecf969,e46244a3,5d63dc5b,a64a3336,14d19c5c,220b044a,72b58666,9c74ee94,2df157ae,67524f01,9707806e,1bf73c59), +S(9808674,a196cb3,eb0b2558,2a9bac0c,659741ee,ce6b1c49,678e318b,f6456081,f5532b86,3408f545,aa218a22,405b0839,9e59fdcb,e2c54230,9955aade,3660aebe), +S(f2b603e,d1d8506c,b1280f50,f3487f1e,71d797f0,f8c8a1b0,fd153683,18d843ca,1d6f91df,d7bbe002,ec34bd9e,9b843620,ff43a756,88dc1398,e23b73a4,9d3e53ea), +S(b9327718,4586a524,389f7e49,adac31f7,45ae323c,d3ccb1d6,a2abc65e,863e684f,b28c0f77,b47bdf1f,390eb8db,b94c606a,84084e09,1202dd3d,654abc10,3589b6a0), +S(c16eaf54,572c1a6e,142b6617,b38992a7,9cbbb577,348b8768,56ccf471,e21b7b63,bb9e7a6d,6d8ed16d,4f8f5009,76edb112,4d5c7ede,cb2b8abb,73de287b,5099035c), +S(97c03ecc,6a87d198,13d68f64,a3cd91bc,ddf45350,383b90be,c5565c48,531999e9,f5cf3c4d,71be1dcd,60b39aef,f1cb8ffa,62d3e07f,33d4ea1e,adaa0569,3c239ce8), +S(6a224e6a,85d31717,10013b13,14ed6c31,adfd153,df8bb9c6,47428e85,12c1786c,690a057e,ef9e425b,651f55ca,8c72169c,bf337e7f,cb779ce7,81e1ca9,5feac5a), +S(1e89ac78,be4513d9,38e58385,7256eead,54afceda,32edfe63,c70b0f75,83eb9ce6,bbc32d24,d58f47ff,2686d804,4e62e575,a1f1e805,75587b90,1a362461,93f9aea8), +S(40df4fcb,8648bed0,44050957,8ce57046,bb8daebe,5a7ee63a,e69decdf,a5de87b2,154c0c93,8f5dbeb1,80939a49,aa15239,e3308e56,ae8ac16,3be19bd9,33fd07f7), +S(a03f1ac5,a3738a09,d4888626,72f00159,59c280fb,274e9974,7447dd30,260bbf8c,9d28b67c,3455e338,1d1f84c8,d60e4fed,c39b5d05,8d17829f,ccba683d,cd65f093), +S(c7d9dc5,d2712b0f,3da6b4bf,1b6d74ba,de6f9586,a794a1e8,4918ddc,d115d1b0,b1727ad7,6666c0ea,5abfd80a,6aff8e66,b8b63c27,6a8ff457,573d8336,fe65dc0e), +S(3c1f81b0,2e8794ae,135db6d8,ea6e1cf2,adcfd535,634ddfa3,773555a0,e0efd26a,e21915fb,abd19ab1,a4cf84a2,a5275a50,24d0fb7d,c841fa43,284be38b,788d9390), +S(69503972,3c4d14a8,1cefd3c9,ad7c4a1b,d5b01ec8,530ade4f,fa7aca65,28ca332e,20bee7c6,5d499abd,f9c9fa2a,585e3f73,cc52141,f4276cfa,aa856c84,6114c1a4), +S(da655560,50683d9,5f81b2c6,e504128d,5f58fa43,4cfdee92,c0324b84,77c3ed70,297e7d88,2009d30f,bf0b5aac,1c7572c0,78192a1c,475fad61,64b25ea7,871017ba), +S(f1ec70eb,ce501e37,f79406ca,f120046e,6b064b80,b8db9d22,d41f9b8,a229cee6,8688ba6a,ff61aa53,4dd93b02,e3eed5f9,f1622d2e,6fd3a3fb,594b9bc8,5beb55bb), +S(fd0c93c5,c2334d97,1e1eafa5,6b62d377,d1104ae9,1c10e707,a404674b,796c51cf,e2529070,a0ac26ae,bfa954ad,801d0e2b,cecd4102,77a7cedf,5a707dbf,6c8ef5f1), +S(514a3ce4,b9f518c0,ebf15b1d,56687638,7eab4df0,85f93f0c,53831536,ee75c78f,8b998180,c9e78405,cf9cbf2f,7495455,6d5dd04b,bafb010b,db7a4cb3,6bd6cd30), +S(6d0e5be5,f5bcf0d2,37726045,727ce85f,336bc6c5,743c0254,9dfed03f,234fe265,df071d23,bf3e151,5995d25a,f7c8cb48,d81ec018,af8513a8,e842e3d1,484f99f2), +S(d37f48de,9143228e,d5d02ba7,f5d97b07,922e75b8,54eeb91e,86643a6f,cfd8416,f7d6e782,af5c8c0d,f9d2c80a,e582b88f,bf9b0824,6e749d0c,9ac72afe,847842c0), +S(d44815f7,46405f75,f03f4749,b5696cb7,54fe1633,7c721602,cfecd1ad,fdbaa875,a6b75d70,4d5c965b,43284bc4,d4db5d1c,980d4bba,e8f8157d,c1cc322d,44fce058), +S(6ee0ca27,441c80d,83b710d7,a6e4f5d1,a497287,a16e3f67,7ad24df4,4db8a287,60d12357,350a737b,74f857e2,ad3865c3,5dd54e00,e70d1aea,cd77c12,fedd02ba), +S(86edff95,6ae4aec4,7a8b4927,4170faab,dc19828,c14f3de2,84362bf4,5bf49d6d,c9f571d8,1fd0b910,7043a52f,79fde3fe,339b17f,ac0e6461,8c601c17,375955b9), +S(c8ea3038,f056e115,aede11d4,ce113663,da276b83,12510e72,1cd8600c,a4a573ba,a662f00d,952d21ae,e26f97b1,6b32dfa,c0b58c06,6cffcd79,3755cb3a,85fbf3e), +S(541b43c0,16ce2179,9c7db4f0,e06b6c7b,bf006f1e,2adedc1,e8f4e8e3,1572b199,27742f79,a0986843,1560799,c11e0f43,be6e8631,7abf4d25,36e09e25,38b90ade), +S(1630dee,a2d1311a,a7c0cfaa,2693595d,48c274bd,d24cbc7e,4c15e458,f7547d40,f1a92fde,a7d828e7,bf7b1c8f,512a21b9,7227eef2,daae040,f8cdfab1,a728f20b), +S(126f6117,456d919c,49325ee4,1cb1ace2,fdd5bde,31208bfb,58b5fc1,62ec799,4c23a017,73d47eaa,579e5cb5,14bb8584,7955f03d,d097d527,ff366b81,1e6abc81), +S(b6210ef7,1bd1957e,51805a9e,70c6663c,6d8aa371,e1012a46,8261653d,a3470c98,c491d5,e98bff1c,7ce97493,612dd726,bdf69d7c,a4524721,79ec57f0,fd123b87), +S(34291314,3842cc68,b0184bb7,13f7c6ae,aba928d1,5df911c3,3bddc99f,ec8a5786,4b63c3c0,ab6efb2e,bc343cdd,dd43d553,582a53a9,3c3663bd,138eb1ef,d2a245cf), +S(5aa2e234,938e26fc,12589307,afe2d797,bad41d73,3eb6dc66,da9a56cf,d4b6c4d4,db91df9f,1856f8a7,83696842,1887235,5111b973,10fb5975,154cdfb4,2f2f2e64), +S(8c50cd04,5904ac5,d9c6d555,e7bf188d,d2318edf,cd90ab90,722d8552,edbebb92,f60add37,b3578fe,f798d8a3,99834ef9,16e9ca8e,2ca8b9e0,1537e7dc,533154e6), +S(591e3233,9e5ad324,be635ef3,50884aa0,bf3efa8f,7ee012d7,8476ca35,ef586ee6,6e219d2,ff115d36,b3688e09,b4788bd,19b5e471,6f09eb41,cb598ad1,b60c069b), +S(7d4464b7,587b74e8,82c85444,4d7637b7,9b6c586e,b4a032a2,6e07b60c,470d82f8,3f1f3d44,6ada0a0c,4e082bf2,c31ac7a9,d2deee7c,4d9492ac,81d47a3,db7794f5), +S(92e55e29,e333f65d,1fe8845d,42d585cb,55db9cf3,223dc567,29906df5,bdc93387,5ff7c2aa,25b670bf,5ab2b57f,831c3e6d,b9801ba2,10aa76a1,2eaa45e8,29a64454), +S(a0fbf93c,c47198c,9492defe,fedb5ff9,dcf178ef,70a0f416,5128d18e,49083c28,dac0dc87,4bf9f134,fcae7932,46a6306b,5c876455,fb493b04,9a74f94c,82cf0a56), +S(5484f0ed,aabe9633,f0384de8,5f86e77d,8153acba,b8922863,6fabe9de,3dd12fef,180e070e,a3712386,cc4ca4de,f54c0399,fbb017cd,3ac0704e,52d60f50,8c0f2c2e), +S(f2452493,34b7983f,afe9d99c,55023ae8,c8591405,4cfc930b,3c76bda5,6c106445,6e800534,948b6349,f85c5164,ef5bd33f,f8d209eb,fc25944c,110f04bf,fa47c604), +S(d15f5c6e,20f96f4e,d1aaa912,b47198a4,fdcb1101,c258cdd3,52cf0246,2679f845,7751370,ef04b59b,bd74d4e6,286d690e,9158f004,826b2dd9,37070544,b06df5e0), +S(75ba968,f35dbf2a,bd92c08a,24930949,7a50bf27,efc51572,232e152a,a5988818,64be1522,78e3c24a,890c584e,8f2561c7,62985b74,e803d124,11910af2,487f9491), +S(c7742126,88b392df,ccb6721a,dee4f49e,ab1fa24d,84695994,f7d0a7a3,3cd52f21,e603fb71,9464ca60,a8ff9047,6093b2ff,e9091815,58ab8d7e,aaa7bf14,396610c6), +S(d15a536f,661f00d6,ce0892c5,6f7ec1ad,614becd5,9b5d3019,a24923ad,7bc828cc,b2d1c3d5,a9a84da5,cdd277b0,512835f,48b546cc,3fd36b16,f83b8cab,caad96ea), +S(64a9f14e,bbb02687,cf9ceed5,636cc349,a8e55cca,4913a221,641a0916,6afcb872,76b2ccb8,2dcb7837,97d31ddd,bbf9abfb,5173b495,6a6abd10,f9a583fb,981bafe1), +S(9eb0c54a,9490fc39,75170e03,1d3be45d,1eb54587,41db3f40,19e83ac6,be7915e9,fd570313,71616577,36c736c3,b282b0c3,f1f9146f,1aa9f,8fa1b34b,f10e87b), +S(141e12c,501af124,a22cf65d,b3996c76,44bfccdc,2920342a,4f3becfe,d279005b,1b6e9acc,c61ad52f,d8f00405,f2191432,b379492d,838865cc,58eb4bd2,c1f1735b), +S(63f9a52e,aebc297b,5665752,9cd93a78,a0ff93e1,f94629c4,bb9b19ec,68ee1895,8e403a45,497dd525,b2924861,978da88f,4823236b,338ace3e,76330b21,a9ad14c4), +S(af31b58c,47a9c9e7,3bbb583b,2178deb5,bd430031,9ddec2fa,5e66eee1,f0ed8b1e,d1fbdf75,8ac15977,cb8c9e1d,7863c465,cc4dd8e3,e299f116,74b0035d,291e1472), +S(985570e3,85b4ce30,847c2a7a,cf5a3c80,ddacb47d,dc1ce66a,d001cd13,36293ff3,5b13a12,75c5b519,10398a58,f42158c6,1c064600,809d7a8d,b31e14c0,84578854), +S(37ac2f59,ef79be35,41e46114,c4f9ad15,e6c8122,db85b62,59604adc,c8cd303b,434d325d,e4ba5b11,7b876da7,8c387d13,3d0fba87,d784cfc2,1ef689e0,4c1d52da), +S(2b002a0c,280419dd,7911a522,28ea70a9,7ec2f9b6,db5316b6,7581a6b9,7354ba70,dade84b,34a23024,785c211b,73b006d,7ad1e3f9,e344c783,89d83eca,332e4734), +S(65c4d14d,f9a0853b,61429a40,50d2aa66,19f63bc7,12517118,784c0100,9d7ee08d,4cc1bc89,aac9c9b,931e9546,cac82cd9,6051b17c,991cbafa,efd52f44,e514241d), +S(df27b45e,7a49695c,8c38d85e,5eb7e9d2,8cbffd71,8520f681,1144087e,8a372c32,cd3d4c1,5ab586fa,ba4af68d,9bf04e13,31f7e5a3,95d14c67,e4ce598a,4077fc6), +S(268c1fc,eeb3d3dc,55daac92,23b9f511,418917b0,3d8a8210,8096ac34,35a820d4,d623750,3c42a02c,5a386e1a,f39694e9,844272b1,766ee986,6d4b67f1,81086fd1), +S(cbf09fd,f85c8ff9,3b1e800d,8e5901c,35728aaf,3d2824a2,bd09e1ae,c76fe1ba,3876982e,cacf4bc0,aa53fc48,6a98cc01,8ad33f67,e4ab0abf,dc8677cb,e9619556), +S(4126180c,88d7066c,8f7877c6,5e41b4e,c15f94da,e68d57ea,a2131b1b,6b9bd2bc,1bfa8de1,71947fed,a0c8ce3a,2cec0e5e,e307f7e1,dd3b7ca7,4f0e0682,c1c3d087), +S(bea8d718,159940f,dbcbe23a,5911dda3,c75b7931,cede87a1,5cb39de3,3f35c022,e723c23e,6bce4f27,fbc219d5,7d7ea196,e3ce1273,58e7eace,9d6b686f,efc35509), +S(2275f050,a18ed0b7,af54c69a,aabdc987,9eb9dd35,7211a964,23ad6e86,48624e3a,3c025a31,1a0ad11d,c9d930d0,7bd101fa,189415f7,c705abeb,bc585948,14f4d88a), +S(1925ef48,16c17466,f7e16c4a,7c6352cd,a12a2a15,9880a482,a06f8911,21b32fe5,30f83429,fb20aa48,ca4470bd,f90f9d6f,1660e583,5868e67,94ec16ff,e06fb81e), +S(18720528,a0612661,3ea23c29,356c4a2e,db74229a,79f008a3,1d6e1357,f873cbe2,ec54426d,a41525fd,d74e018d,dca72be9,e7a28000,2abe1a12,4a73ed4,21893106), +S(b8a6972f,c526acb3,4136cbb2,4850ad15,cd70a4d0,ed66a9c,8605b257,885c9d8f,e043953a,698e3225,a35271ad,2a173fdd,a1d37ef8,98c630,d02b80a0,cd729fd), +S(3839720f,b5c7c3d6,3a0ccf99,c0f951ee,b257d818,b3ef1e52,b530aa23,8ab06887,9d58a455,9e5268e,48292e9c,c6d78275,c733c2b5,b31326bc,4a0546d9,7d950529), +S(c204f868,e6632183,88024c76,4ef92286,68ba2867,bd301c88,1bf8e7b3,e6677e0a,490e59a9,4dd95482,8b386c0e,d6778f93,5a692d4c,74f6ed47,61aeb26c,4b1eb048), +S(dab95115,4aa1451e,95cc374d,6a6d6801,9778f54,9672c4ac,f9d16b39,ac2464ef,e32e5c8d,453be5b0,8c5ca506,b7875565,7f269a75,daa83a4e,f11e1266,f442d85), +S(ff283b71,7118eaba,52225bc0,ec0328c9,72e5c13,3ffab3b,801dded4,cae7e596,36d8b7e3,4dd684d7,e9b0bdf0,3d60304d,7d990a85,a955cf3,db681d03,b0af5d43), +S(30eb08e9,6f4de692,d2eddb8e,aac47b48,1f3406e2,235560e5,b23d0b9,f2ec4597,cf05cf0,26ed3094,37aed28c,2dbb6f9e,94f83333,15f00832,1286dead,1c931be4), +S(9a51edbb,e9146fca,d3c9580e,9ee34252,6b2d59b,c0531051,76bf3ec0,b86dae9a,94d549c6,2cc12e09,63c844cc,5dce24db,834fdc93,4c8b06e9,afc10f34,f08705c8), +S(ac1836ac,2f0d0158,650238f0,7b2ed1b,111bc56b,b176558f,7e018111,ee520c09,562e108a,a842608d,7c86eeca,f6f2ebd4,ad4d14cd,48c3d068,eb658c28,ee1aca36), +S(5c33360a,1bc8e85c,b0f78d66,8f6ba33e,4537e0f9,88525a1c,b186fdf,7ec65596,8f86a399,ba2038a,9faa311c,f2646ad,66de6c86,c3280d93,71d1bdd7,d9df698b), +S(40798759,c22a7b60,464fecd7,d506bec3,3614c895,c6d60d14,d1ef646b,38559793,506dcebb,aaa057a,433b0eb8,96d35070,a871e11d,216d6a42,19689167,b8588b9e), +S(36466772,ddf9865a,c6940a62,abbbeb24,3092f44c,58e3c052,9cc0d3ac,738d99cf,60ad37de,b41ee4dd,8cfc755d,e309157e,608b0a5b,ef385836,8c7c7dd1,cbed7075), +S(e6169ba7,ccc02fd,cfe63742,910a5e9d,3a3e1661,d8da60d8,32b86e9d,487108de,f29ff08b,afa4568a,4ba97709,477b086f,31685c1b,a6de5c1d,eba8269b,32c2cf41), +S(3bd8fc06,2fe50198,b77aeb1d,d42b9536,7fc172a4,f2528ffd,597799a6,4c0661b,c73a3d92,bf87cceb,f0020063,115aaaed,ecf414eb,f03179c1,86ef37bf,b452795a), +S(aac77264,829bfc44,6c2427ee,8b732a82,3480f11c,32cfce72,35b0b5b4,6749260f,c788928d,b75ea7ba,e216d8ae,91559d05,8597b9e6,3bc2fa6d,276c29f,50bcbe7a), +S(1dc5e0f4,ed05486,c883b07e,e78f1b96,49858bcb,6dd396fd,17a19dc9,a788a1c,ee4fc404,d662abb8,bf7122b6,c3a226fa,ef491513,49231623,a9d1a796,cc6233ff), +S(82a1f055,d885501f,114fc40b,123fbfd9,f45499fc,fb8720a3,c730fe75,ef1a8601,39fdb201,d30ae709,486fbc27,1603bb93,826ca4c1,395bd9a,112ea4e6,476ec20), +S(f8721b28,ea842788,863a1ff0,339ee75,7c508ec9,49e4f4f2,71d2a460,f0c14ed7,761ba386,5850303c,4449a3a3,44ebc7ec,bbf365a9,4688f254,558289fa,5b0715c), +S(9a8d123c,71377193,79d44740,af95d63f,ee954c28,55eb7aff,56707a1b,f0ac683c,3479784a,e683a3dc,c1238f37,5b6ef82a,487f6e5f,df487ba0,10477e45,49652d9b)}, +{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), +S(e872efd9,8147527d,7cf1ee62,e4980ce8,f1a7f561,a34ab662,1d503a7a,e98c6433,c8c62103,fe01e381,2553e68,5e7d221a,974cd4e9,f3247078,de37f5b0,1b9ccde6), +S(617f6235,8bb46c55,7608c7e9,ee198fcc,77b61c64,5e953cb7,419375ce,1e06fb58,fcd7edad,db70f22c,364cca9,9a792f53,c71474a8,707e2cbd,551d2626,6b373158), +S(86810c6f,f27fc69c,31d69ee8,4b616345,fc1526d7,9dde9dd3,5e1fe6af,d8fa0f55,718e736f,6c57643c,a8c0aeb8,b8bc6466,108e0149,db197a44,14f067a6,10ca5f84), +S(89aa4974,44ded8e2,4553001f,4a6247e8,bade925c,a35fda1f,38a86f84,b5b6c581,dba8df4b,9c9f02fe,e5a996fd,f77c870d,4e447410,de27d7fd,942e554d,fb1edecb), +S(9d89ff53,d85f9e10,6c78c86e,b114c12f,6852a457,d91aa28a,75f2afbb,e9191fde,7b1b4d70,5beb53a6,84a6f596,e6b22751,28b49be5,2ad37ca5,bed6a952,68880ce6), +S(b21de2d5,767f595e,5b873e39,9c02beda,571cf7ea,48236aba,fdd69729,14e4eb86,1cafd24b,2414958,9812ceb5,1d02d5a7,14f35c04,8a333f21,922e6baf,52942c7f), +S(d64c65fb,627b3d76,135ca1c3,ac8794e7,a62609b4,a71609ad,73972df6,4f75ca5a,6301fdba,278e846d,246e4a54,10108682,7e815fad,d30a58a1,3247779e,a397bbdf), +S(85248d03,5f4598a8,618eed84,92ef45ce,29ce24f7,4476cb9f,95168197,6fdf83fc,ddde2121,e31b1986,6ccf28cb,b1f01925,7ba53c8e,88eb3f3b,a8faef83,274de6f), +S(2ccb22df,abaaa33b,6da3d166,b2f85408,231edf40,fc9f7f89,24256378,7f10984f,35fd70be,fe7d802f,c65e02de,e5aa7ac3,67ca0b20,a5e3404d,a5e59eec,8c9cef5a), +S(3f5c061,fdd98ecf,ac9fdae0,3b527223,319a871c,c385a134,d1b7e35c,9bf5d42c,a1ddd10d,1789d24b,9fb96387,8789a472,96c757ca,99233b97,899bcfe8,e7760cca), +S(2e1525d,f6ae8b7a,84932980,1d4fa138,5fc07382,1a197e00,f9a8c235,68a75647,af7a996d,71ece94d,4384bcd8,60e947a1,cde4ac6f,408c31f8,cd67f0f4,a0807f6b), +S(247becc0,556b2585,9e426838,bd34dc9c,e194ac7f,b4ace971,9ae317a6,d87f5316,bc63b0b2,8051432b,4a6917b1,7afd8b46,d8fe2599,99c8f254,1e5ec22f,cadc8c9e), +S(3b39557b,8f9bdf90,76acd422,c46d1681,f7b3d29a,40108214,2035e3a2,8c204aa7,773f2a70,7e6288a7,9c3efb89,19eb100a,772fa946,c59f0bf8,6796b76c,1d7194c6), +S(d1bb4751,49254987,5e4bba5e,a0d2cfeb,703e149c,5ef6ef14,3f4df5d8,93199e7b,75d04702,60bbb309,73bcda42,808c4cf8,1f33dd89,e5412e7a,bbc6e722,7f0e4acb), +S(2324c1d6,96933334,b3023542,c506687d,8e7b6854,cf0b1ca4,902c8874,39a3a4ab,269c5c10,3731f1c2,419a5b53,566cfee5,a878c33b,c2aec368,b1b60a3c,bfce7776), +S(5896a34b,37869f15,7d19b9e0,cfc927b,7fe0ff91,a173f480,b371d18a,1d72c0ca,ea9331b9,b281b800,38edea52,1ff8a3e7,ab0b7e2,e431e9e,51cff269,cdab8c52), +S(2553f696,b32af6e2,1cc2089a,63439911,4d7b9d96,a883651a,c66f1d8d,1b74dccc,44c3915a,6212f827,3f02a0c2,b2de1e74,295b31ec,d2457da8,faddf543,c9244ffc), +S(131b4dac,25fea2f,715da576,3c175d97,657bfd68,21224136,5da967e9,c91b8ccf,30b40489,73a61cc1,91ec22fe,3429589f,13aad7cb,cbd533b7,2e692f75,f728b668), +S(59d0164f,e8150846,874f1658,3af49019,e300a2c,4807d18a,389f9b12,60585910,eb91680,a580a52,510ae709,1702abd5,6264181e,477c99de,6cfac0e,5533ea88), +S(691e86be,3a30e851,4286fa5,517d1fbf,c9a969ae,d7837e4d,78f6ca3c,e088f2f6,b8108fd7,e5bdaa7b,9d34f1ec,b5251705,76ef53bc,243b864,d20261a2,b9a6ff5f), +S(c68d096c,23f562a2,2ce91404,6b82a43b,22b1e7b2,63e58107,96128ab,a680ca71,c5eae54f,b59583be,509466d8,95ad482e,ef73b8da,808be571,d79402aa,26723774), +S(eeaacf5b,e4ec2817,1acdec98,7b5cb678,91666932,42b4c546,8debe163,430c20da,13e8c773,d867856b,af5b27bb,ad7adf86,a3e4826e,12fb2b9d,504e63c2,2b2460c8), +S(5e3d98ad,35e8c90f,131ea3af,2c99c45e,7ebe6eca,38d02120,c0876a8a,b4b8dbe8,a019fd63,9bb8f5dc,b4776131,398be36c,b3419a3b,27596462,1ecaad5,8a3ccac7), +S(1a43b7db,a042bd97,ea23ebfc,1384587f,4f66587b,1fb0f3d7,c32af9db,449ded4a,89667998,5946f126,34f00e5b,b7f0402d,ccbc8ced,a8389e83,872ad821,3bdc2f32), +S(2222292a,ed3f69bf,1ed2cd12,3272a7b2,b57b2b29,c9f756f6,9fdcabf1,1b67dd57,6f6671e7,d22b9cd5,d70a6490,46101054,f48a39a4,797964d,c4c2df99,a982b3a7), +S(5d5bc560,8ce7cb81,ed23304e,fce25034,8dfd497f,80dd3d9e,193641ef,9358a16a,b63c4202,be581677,ec334ddf,5855e39f,9f8f9544,f9f1171a,7823f0ce,61e2051c), +S(1a669fa7,2d96cf78,886bd7d1,36e7dfb9,8311b4f6,9067f47d,12830ecb,612ab969,e45ba9ee,f80c5a3b,179726e3,4b770860,552b0a6d,6ce02e70,529bb5d8,b2eafd9e), +S(acf341a7,add1eb1f,b5dffb5f,cafad928,b40ff6a1,fc0bdc67,9380690a,7daaafa6,69a7231e,ad015747,60b6fb6c,4a7eee54,ba348bb0,1d201d86,614b9397,89c00cdf), +S(f4238dfd,447cb48b,fb9f6678,11168126,446caf0f,3345ed,a31ba759,3115318e,5cfb371f,296c3a50,6d8569f3,60902baa,35e710d3,619c14f2,3564f6bf,99bf7149), +S(cc328f03,fc2b3590,3b8cdd05,514dc673,1446fd17,3349f0d7,a7a99da3,d2271847,883c8b2a,dca40796,68b0e472,c37ac41a,c91dc5b3,1aa84cd7,7f319828,3b72e2b1), +S(8e9bba4e,5fc87283,fb3a1b71,3b493127,e0c3e5e9,e3f2da4c,51ea3d98,5f3bd579,325df34f,dd64edd4,880a8ca4,5bde671b,af67a76e,f1a5a27b,abfb42e,c2b7d29a), +S(790ccd03,fad172c5,10af246a,a6e4a87c,56db01a4,55b4bf11,8670e5f6,54b0f816,de872f4,63083283,536d6943,ce8c67b6,6476cd8b,ce802fa5,e0817c5f,7ab684ff), +S(feca35f3,f030cc1,e0cf0a86,3a11d035,95b2ccf,7569dede,1393cdaa,a972d1dc,3fa066d0,565406d4,52aefc9d,ed45133b,48933d79,e0a25533,e9a24d98,f608818e), +S(c6b38388,cb66141d,777b3d50,c5224c63,94e587b7,9b62fee1,6fa12c9f,d7771d66,3b9647e9,2ab35770,e0116e36,27a31526,ae48a595,5d46b7e9,b27e5747,c066fd80), +S(db412fb6,3f925c6b,62ed566a,de8b4768,f3c0be38,dcd165eb,eac7a081,fdcc43d7,fc305dce,74f64672,2eb963b,792f312,4b5da5c0,ec8c47fc,254648e9,e562d2c9), +S(777f3e29,83e8511d,90ec346b,1cf6ecef,4539889a,c124da88,337dfc6e,222eb810,e0abd8b1,fb97b582,27beb723,3308a89a,9dd5cfa7,303d06e9,2c2fd427,ecf3741a), +S(a8391b7a,3c3e788e,724e373d,821074ea,b1768e16,f3cf7b63,80a0f9b1,7a1b8fde,f9feb354,ca45cf5,fa10eeea,1b4f4936,2e4ab403,622cb470,26f529c4,69f61d59), +S(1b86c4d4,40532e3,968ddcd6,2012e455,34ba0045,82409c74,add1797a,fca29640,2217842d,fcf1d171,b18a57c7,1ed6d329,4491a422,45e93958,570fbf81,9e6bcb41), +S(65e2a22b,779056bb,6f7ee1cc,efd63066,e5cb594,a9496d6a,772c4e18,f2cc7d48,8adb10e4,e984b024,b420ae65,d2dbc7db,2c12b4b5,65b7b81a,434d16cf,52926238), +S(c5090c8e,ee079598,57b8bd0c,fae29cdc,e00fef57,49204908,cee6a5ab,1d4fd970,fd7d0324,fe41fd86,3b103e61,a391ee36,167af582,e07c2cd4,649d31b,86e6c976), +S(be9e98cc,c6a230a,3e63ae7b,f619d6e6,b27253a3,5f26648c,8c3f68b4,e193b24c,d32895af,d8886f1b,9aabedc6,9a79fb9d,ca71471a,97728ca,1a55e701,e7d5bcd9), +S(2ff0dd75,8de2de40,1ba00665,c251f6f9,e342265c,4a400684,ceef256e,7d6305a0,adb558ad,61769a42,3dfb2d3c,c44da3d0,15a2aba9,ebb4e29e,70fa7ae,6307f4d8), +S(5dd98c43,caea001f,75846c88,1a39fc77,cdae9882,62cac6db,f6160aba,f00c8d51,2cd50bad,48c1a136,9a37762f,e56fec65,8a8a3e36,90813d50,6dd94fb7,de90858b), +S(18280710,c4d14765,b473cbf1,567dbee7,d53a127e,2aee22d3,198dc5de,43c3745f,1c8e417d,83b0540f,fe800ec7,1937f855,a1066dd8,4f7f6a06,9722ef2,e2ab4bbc), +S(7f3fc319,62da2c5f,9e90a8f,308f69b8,d17497ef,7216a5c7,228ce9a4,1b35bbae,ff754dc7,ca0d3148,96b18f27,c516fbb9,d4d21cf8,48a61f0e,4bf3cd60,f3b1e7d), +S(96809ebf,3d08f713,87271a1,762c9d9c,17355ce1,be770361,e69506ff,f9bcc41d,412737a9,3b3d1835,cb487c78,909ccc46,624f8335,46eb168e,bd8c4408,44bdb4ab), +S(9308499,72dcf389,d1200b32,6a60b0be,72609de2,2a66989d,17c97f3c,e61f2769,fd307c40,3c29d78,14f7627,b7575ae6,40bb77f4,89272d91,4111e1a,2c81abc1), +S(a66a4d1d,1e2bf54d,b359db03,a339c40,4e0cf102,88dfa02c,da95c158,74057754,16d1cf4e,79d00675,cf6dea6,7d8b6c2e,baf59eac,cba2bfb8,e30ac368,ef875d5c), +S(4571f513,f3b73e0f,a7ca0801,30d6fc0d,ae8fe66a,3caee9ca,807177e4,40256f28,8849186b,79fa99cf,49674ed9,9010bcda,7e2458bd,bf259bf0,30a3b655,61b88842), +S(28609798,fa0a5b48,f19bc873,aa62da70,85c8b9c,271b348f,ada1ac16,a0013bcf,9716c9a,493d484d,f6c588c1,aca279be,327e59f5,92a04f5a,840bb7aa,34b407d9), +S(77b7e18,e37c4a78,721b28f5,1e6cab87,9c4149d2,92fe9675,fcc22df4,8dfd6465,179a09b5,2733b042,f702d649,4b2742a7,ef82d050,efe0992,4584d6e5,328b14cd), +S(3c25bbdd,cfa0ab2c,cce10476,79adcd9d,bb63595e,8a7bb841,cea608b6,82c71f5c,7a01946c,b0e650e4,53dce44b,eba509cb,fdafb57e,f130e4d3,facf9ebd,6d7886e), +S(c22b973b,99f9b4bc,90fc9e0d,b2d73c7a,7f1051a8,d19c474a,3bf9aa43,3b0fe52f,e0253dde,dea6cd0,1507b251,176562cb,7f73c22b,b7d10015,61fbd723,4d5eac80), +S(18c7f4a8,3f7dec0a,76dae14,3a49ecc2,4d5fd4e6,5880ac51,627c86aa,60a8ce71,978901f2,3d35e23c,36dd34d9,cae08290,641163a2,c55c3028,11fc4120,4a35653d), +S(61147763,8a8c8924,2fc31730,2e0b1475,514025f8,dff26b1a,eb4b7f28,51cfa5c,23152003,f2d12370,84ba60fc,bd653aba,37c6b20c,18c85c62,b6ee196e,2c684d5), +S(1f025444,17e67747,ab9f81b8,7a960663,ef3effb0,259d1795,f25c0a4,96847292,8d7ed884,5cd4cb73,27d31f87,ed6f881,a0de6f51,768a5ddc,b404139e,d064fb4a), +S(90493828,a1633ce5,8f962a78,2256d6e2,949f39da,9a865dca,d84b3e46,408d7b3,4c6bd158,92330e5d,1d97cf27,fc8e8fdd,99f39bbd,7ede306b,336530fb,2d46e51), +S(ce69b160,287b6724,8a11db83,418a302a,daab31a3,9c45b5a4,a02643fa,21918461,617286d3,c223891d,c86a2bc9,5727aee7,3016650d,cacd6692,c4e24a7,69b86701), +S(f20ad3bb,1b962fac,3d9b2c08,df726791,706b3006,60f894ae,379a6c02,77e3e8c5,fc83a778,44e35741,81dbaf95,de91240e,879ccd42,5c28a389,a01943d6,a954a5fe), +S(fb535599,ca57b6b3,94205071,f1c07afb,ace578b2,5d571bc3,1f669a8c,2345d7fd,b25fea48,f9f36d15,feb50f75,2bfa03a7,bfbbbd7a,8de04ba9,eb58d6f9,e4a77c1a), +S(c3793655,c789792d,e43a07f9,61d774d0,34253bdb,31c3428a,8e941731,6cfe5565,748af2bc,9459b7a9,cefee955,81d3716f,2c08d5ef,f988ef1e,85a14290,3fdd72dc), +S(34304c83,9c33334d,216d1b4c,4808d14a,f5952d45,9b8cc1dd,5e64c6d3,30807110,82a01c14,95639827,8c9a0189,5b0d1e62,572b1ce3,565ea53e,9afa8d27,36b17c75), +S(8100ba8d,43d8cf1a,53f973fc,544804c4,4c2e96b5,9a877496,7a7c4f57,862a0fd7,675c2c52,5de39794,2c42babe,8a3b8e65,1c1aba24,f2da644e,a359a0a0,892e983f), +S(b3f979e4,487081d1,44161dbe,37ef2da4,de16b9d2,aee1ca13,9f018e36,d4ee64c9,bcdfdbb3,e6cec91f,3dd41871,9fae4213,be273923,a8daf8bf,919c0145,11a93969), +S(df0ddb93,e54b94e9,cc7460ee,f14f3512,86bc8f0d,7b928a6,294f8ba4,2577910c,b640541e,b5958814,e348d634,faf04a02,3a38235b,2250eefe,3145bb40,64abecb6), +S(54a2cfcc,eefbd58d,3924f305,2bfdcce7,508e7d82,e82cf354,9a4f0141,52cb717b,17d80293,d00c0d82,47013168,24e6138d,1cc77672,7a05ddcb,909642b4,afb88578), +S(fd384aff,fa1398bc,1881dfa0,d8b72dfc,3f6a4429,52d301d1,53d8bf3,705b828b,78dcfb76,f958da03,dfd7f6be,21f36e7c,59c7effd,c4e9a305,b934e9da,2b30f684), +S(bc7325b3,181554db,1e19f120,b6bfbe0c,8e4c003a,461ac2b0,83269e23,12d3395c,c101647c,9e2ccdc7,7ad89913,699b3b42,5850e30d,e52995ba,7985f73b,db6700eb), +S(e9ed80e3,9ed744b2,1a9aaaca,1ef4959f,64ab312c,d7cce151,cc6e383e,dad0185,ab101dc0,af3ef33f,9f0d6bd7,4ab4e938,25e999e3,4730a9ea,4ee67b2f,4f0cc790), +S(8f63fb71,67716f8a,749439f8,25f2ef87,3c4e3d09,6bbe06ae,2aa8bee3,faad24ce,76d6652e,b0845f33,42b48ac0,8b2d70a3,9c601e79,fad31dd5,6701d729,1331a5ae), +S(8ed0dda7,5d3a1e9c,8a497ccc,aa3579fd,ca5f8628,239a01ab,30abebad,fc6b3476,6f4a70a4,54d8c0f1,4bad62b5,b9aca8ab,846c4bea,565870cd,28f2437f,907269c2), +S(7c2d0104,3735fa17,5deac20a,5997c20f,748baa84,75f7492e,d4889de1,f6666f2,236d1659,54504475,7677240,efee6bbc,559b64b5,96358ea7,5dd1598,f3e7fa6d), +S(d37272e9,a4bc1bac,edfb2131,2f66fa5e,dafc83fc,39ce55b5,66d7b395,9aa937da,111fb684,50913dee,2c6a1a0a,7d7092ae,8db98713,90a87a41,4ea52793,839d7492), +S(db8375b3,c8c574ca,a8d66487,13467abd,793f75ab,47daf5d8,67f9018f,901684f7,7b23db42,56ae1546,31e11cb1,37c091d2,3ea5ead4,32f2038b,27e46571,75526e3c), +S(d077223f,149956aa,1dfea1f,35f1b237,f59809a,8bb0e78a,f9bd9520,34867886,71fce205,bd0b6728,766da89b,55168777,b2dbd672,ed8b391e,97e74d25,2ad028a4), +S(1deed30f,7b7c1a02,eba5d86e,eb1e055,9c776d85,e264e842,8489264e,4f68c907,a2050287,d41e8218,9044b3b1,bd1e4c6c,3baabd0d,370d6f2a,d39676a3,ef4c672a), +S(ab0be6cf,57a6da4b,f6ba7963,aeabd62,d2aebba9,acbfffd7,a18e2579,c137752f,7d6c1113,7535c914,dc58a5bf,a53a82ee,8493ac83,cb1839fb,badc6fd0,4575b70d), +S(3c72f165,69ef77ef,a32347fd,d14e7ee4,82206c3,1fd9bb9f,367fb84b,9abb5d06,3f45f3b5,d08ab10e,1785f62b,20f2efcf,2a6b104b,cea583de,89c791c8,e2f732cd), +S(b0697da5,6030bd3a,ec311758,fbc0f56d,90544123,261eb75c,644b37c3,2f888601,50652a49,a3b7a325,67211693,197f136b,f38102a6,954dc6e3,c8325303,2378d6be), +S(906ec5ce,4273798a,9350a79e,8d64970b,3209033f,9f7c56bc,75e2b3b6,6003d338,a9a0a4cd,7c512984,ee4d1da0,13476077,80c664c9,8e0a416d,856dc7de,5923c702), +S(64b6c18b,d207619b,35f76f3c,f36b14,7f3dd79f,c0147536,25d7566a,c0350a7f,4226dcfe,f3af6ef3,40b883c,7d4bd1cc,f9ead936,d1d42a1f,59e9754c,23ce3b92), +S(b1d0d916,e6908910,1e5262e9,9ab94a46,e0a1db5,45b9c572,3dd79212,4afb34fe,be9d6c09,3c1adafb,5e8cfc25,5328a31,aa7daf65,74afd3c3,f5256ae5,33f67570), +S(55fa9d6a,d8005a2c,8889df76,6b3bacc4,dee487ca,e65a036a,9b1839b8,2a0c3c3,cfb17a06,2a9edcc7,88f5ddd8,a0f12211,c21877d,80c9f30d,cde71a8,af3c10c1), +S(c231d95b,6144337e,b25cb40c,65d6601,cb4426d4,b6d7c6f9,9bfaad11,611a1854,b0b1b6e2,4bc88bb7,a277a3f3,bfa74b9,9b1eb5fa,a16f4a7,e40f9ae7,629ebb65), +S(b6053327,960dbcdf,f13842eb,c50cf09b,d60cb656,3e1553a1,7f7985ef,7486afd5,7f195737,9ed11b9d,7ea08068,c6dbf3b4,36eac86d,2efb81b2,99f89854,65766266), +S(8ea8e96f,619bac9,c6805dd6,e8115858,50b80cf,1cd7fb59,e9090316,c9190de3,92a305a6,8a1300fb,64eff4c9,fa781270,2a85a71e,bbbc7910,a90eeb87,8b50036c), +S(cd8fe341,ce670725,22bb9043,f3e31f31,3bab3052,d1316da9,7e96bebe,710bdd8f,3a3e6072,295bebd1,7da2462c,8ad8cb3a,2c170c35,9d2b96ed,d805f0c7,fcbb4ae4), +S(3fae13ae,cc9b0b32,37d94c65,f769c57a,6265f37c,7057295c,dfbf9086,b27cb599,5baae4b3,eea7ac21,4372748f,d8b6b9f6,24755dcd,b92cb3aa,63a5ba6,16b88a97), +S(7b9399a9,49077156,b32b9cbb,7bfd9416,c6468838,c87971a0,d9e221ca,c8e4cb25,504b1b97,c7f32154,f2e5664b,8c180f96,a51783e,c041fd2d,1e8fe493,26ccadbd), +S(8ab4d5e7,e112d259,30e2b4e,7ff4cf77,b2957e10,fa9fae5e,a2f80940,8200e511,6d0328a8,69bb9ac0,71b6a4d2,939fd4ad,34066606,1c3ffeba,1500f831,8aceda6d), +S(87acd768,24a369d1,210fc798,69368ad7,fb01dafd,f5ead811,f5d03169,ba270d4d,8b9b706f,15ebb721,9654eb04,f846d1f4,49a6979d,53dd03a8,214fc285,c86baaff), +S(f8179003,b5a2ba0c,ae5e7c33,90f99da8,a1ee813c,c5ca0d10,c8b849c1,42ed6ca8,20710e6c,7ff5e563,36855a43,a372fd00,e7bc7f97,d7d0ecd0,f7a63641,a96b2c8d), +S(2a2b3fe7,d2c78d9c,3d62a9b9,202ea02d,e422f14,23e300fc,70cd66e5,ddf9e69e,ed122cc4,96eb517b,fcc5b393,8fc97001,194c3c92,f612d062,95ac6f5a,7d69ca3e), +S(aa80d414,e1f91e31,73483761,a8c34490,202ef4af,4b39e6c8,8726fc29,d6f99a39,7632d7d1,e312af35,7ad03c90,a5ef9476,cdd8541a,ec03a0a1,b02d8ef2,fa380245), +S(2e6f7aa9,193b67e8,c00703bf,d7ddea0c,199c857d,90d03571,2b41ab0,6b074d98,ee2dd743,952c47ea,e03653a9,22bc1965,6783beb1,76afef17,36bbe2b4,3af27827), +S(d3ec2365,4346428f,d38153d5,eb6f82b3,409baee4,4bdc1c6c,27b198d9,b9403d23,da15f943,6b0ec0cd,c4769650,8da28a12,32409c80,4484b395,40ca3beb,437104ea), +S(54500eb9,33d4fbc8,d8f96e3e,dbc93e47,a91b799b,510fe73,61a507f,95973a65,277be627,356c7342,56b97d1a,87f733e2,10531732,6eff535f,6ffecf48,ce635e9b), +S(b3543a2f,b3898a9f,64eb2863,7bb3a33a,82631cd8,d1e41b22,7ffb268a,d6710bb9,383187d1,bf8afbb5,dba13d77,25327d40,5c363bf3,f8e4a13c,1e259b16,c7dd8e3e), +S(7614313a,176d1ddc,c28147e8,39d54d78,5a3f42e0,5d7d436a,3be2c1f6,b7ff3606,d540b46c,d87f555d,fa8dc374,8f1c997b,5d4c1c52,1675bb7c,4e3a2d15,8c1e70e5), +S(de1c503,447eae30,e3fb1ea,bcfd108a,cbfab506,d52bc997,b1c124f5,b610af17,3b7d0b8d,e4e1de4d,c17c00e,ac0727bf,f41b0730,2080ea3c,9c18bf85,9608423a), +S(47f2fee0,8bffc7fe,5e7fb417,70ea71c6,9a30308b,cea4ebc,6b2861bb,8aa94a41,31659afe,6a09292,da939f3a,fc89e4fb,3fd2f288,7b6efd49,ef1df90c,a48d6e3a), +S(824c2c6a,f7b9f3ff,a1dcb278,ae2bb3d4,d7112ae1,cb66d524,85c49cce,35382572,dd548e84,3ac82ee5,9004320a,db9f728b,dfa0bfa8,5544e55a,fe8518f4,a9350006), +S(af4482f1,1157be70,14eb09fc,80bc1857,43ee62bd,376f7df9,f7507df2,34f6881,ed2202dc,182c188,3dd864ee,77b51deb,f8d048d5,79993a77,3fec978b,c880fe6a), +S(386c5a63,2e56795,54c53c2f,824bdd3a,c8c22364,612efef5,13942da3,cb8cfef5,dfbc9df9,f1666b9c,54f02eef,d482e71e,c33aff7,3d8c1025,7ab17b19,57489127), +S(5cacf202,1b442903,333796b7,d9d1a8c0,a8a26b00,2ab5cb3a,b6c7a5cb,87ea778e,e522602e,41b4b90a,cd6c121,4959990a,d77f3f9b,87862949,2c4119b8,54e31cae), +S(3a783ed,2357399e,8cd3c67a,a2e1f321,9900f6af,368080a6,7f18f6fb,c5442e65,d23403f1,474ec6ac,5071d084,2a05a58f,826e4418,c19451b2,b60ba182,777290c2), +S(fb6d745f,a0bbb00e,f92026a9,f216d470,9090649d,5e761f37,6e4dd81e,51c84954,39cb6685,c0001c34,1d1d5523,55bfbf94,5a97446c,593e0518,baf039c2,368be918), +S(12d8154c,ed08bba9,d6be85ad,42305603,74c82c2d,bc06d80a,2199d3ca,e113eb96,90cb6ad,3b62fcdf,d0d2f3ee,9e89f7d8,cc314d6a,bb22025a,876f4001,21a3b4a5), +S(313583fd,66ee564,f546350f,22ab1324,fbba2319,ef69cc81,6c4e9e0,26b3367,dcda990f,b4f2de57,72d6fa51,36da8215,f66d189e,dc91a46d,d50ee2c2,3398d21b), +S(d27b50d5,30a6a777,3e81ea25,77682a21,a6055afc,4bf05d1e,f0c1e5ed,a432b6da,f2a125b1,abfbd478,74b1b1f9,5d03ac5f,24610d34,d8b2ca9b,90b30c63,33dc9214), +S(d78933bb,d228b9ba,9332a511,a6d4741e,a42ca4fb,2b79b6e7,1d4f34ed,66a57e5a,61520901,c37fe630,35a0a80f,86e63939,133ec632,41f3daed,e30af5ac,2f470778), +S(a737c959,b9f386eb,e227f5aa,6cd83868,7a911290,e8ecb6e8,d24a3f18,a1171965,6648f272,322bc673,f8d4b877,aedf25b7,dbd2bcf6,bcbf3fac,ebdcf2c9,a531b149), +S(9c2033cb,d00de2ca,f6a6280a,fbb615ca,f0513816,aa12d994,e0ec0c01,37b5025f,1efcb986,dd4d223a,1fc4a7be,58bc6f3a,76b02646,c23a0c7,7f174a06,c75928d7), +S(75b51376,1d2555ab,87027458,d6302f77,26434e84,ff7bb7f2,43b5a6a,7afde413,de0d1bfe,37af2be3,302fa887,ea87a678,264534e9,c065df8,b1f3e326,a47fcf4a), +S(79fc6858,8d117c83,8a8b8134,c8071d33,2245e6b3,6107e1d6,503c3436,cb00dc8d,78d45ba9,69490bc8,7ff05b6f,2e6f8be2,8700216b,db76b74f,dbf4577b,f6169914), +S(de006398,1d8914c5,8702699e,40486195,a6647110,2b6576b0,6879b41a,207b6bee,22ac0aef,4a565e1,f159f6cd,5e04c68a,22e80d1f,f946aea4,f5127fd5,8707dc78), +S(db714e6b,52d32de8,43cd649c,a39307e6,540c048b,e0542b19,cefad32c,a9b435ef,d1ea87b3,ab9acebf,3573625d,b2f58a73,fb3864ac,369ca451,49a42262,b1915101), +S(25fa0fb5,af46c0bc,75b4fe67,fdd53d51,2303219b,38448403,186c23d9,7f7b6242,45985834,a9766f8d,9ea9dc82,3e6d55c0,75393446,f38e3e39,9b2b7b9,d6b34f6f), +S(acaac641,852406f7,69e19429,b1820703,fcedb664,407a5cce,8d96c779,c1e51edc,1bcbb918,88be19aa,4f02c320,4f18effa,cfc9c376,ac3dde0f,a529123,7f715cb4), +S(3674eede,62af1a60,77df180e,260a2d02,db43b440,b1e7ac3c,4ff368d9,8c3d8ed2,d0a393d4,7f953a8,fad2e045,91c62914,14b7ef2,694cebee,6a1c84c1,b8e19888), +S(f630a661,e54045aa,54a86a9,386e0466,a7428967,43d483ee,72a87d5e,34b255d,4ae7305a,be851491,83b7dd6b,f9faa5a3,8c2812dc,96475a3,87906759,85feefa2), +S(6b191486,9e262afc,51a94712,72b4765,78337a00,3556aa96,52acb8dd,36f1b3d0,853d994f,f728cf33,85990b39,d8736d28,faa0e8b8,c8b7c5f1,693363fb,6c842ebd), +S(c9fdccb5,be931d35,5e3e4baa,816d6cfa,7af441f,2d6b653f,d0fc90bd,c7afc681,d2d0190e,c3360886,b2b3d3b0,d8e05211,84c8fa05,b912a105,374325d3,75548908), +S(5e16743,c976a908,fdf3bd1d,46735de9,f3446673,4af3bd3e,fc6382f0,d834b500,3a8b87d8,28d99eeb,351186aa,23b76376,682ab598,165d7f4a,1c40d8ec,62840a3c), +S(67858166,15c4c7d2,f1f2da88,1aec2147,d51ae770,ff2c7afe,e007e4ce,a4faf4b7,74404a26,5f0d41e4,6e1f3bdd,929f26c1,f80b229a,18d0d3d1,68e936ac,e3447266), +S(add083aa,fb71a217,6ef2b08e,8bd713da,27c5cef8,958f47e6,f90dfb6d,1c1bf122,b835f39f,27e27cf,28f45ceb,7c26cd60,691a89f8,650dff32,44374957,c412accc), +S(5b0c33c3,b669dafd,74c876f1,72357a12,8117c8b6,59dae930,fe2310f4,f96a5d2b,6aa36784,3a973f6b,6a03faa4,b1226950,f348b6fe,e19f1c48,f4dbcb6c,3a141618), +S(5ad43f2,62f9125b,55a419bf,e6ff2a04,4b09460f,fe6f1a26,d8ab6127,33d50301,701ee81,dfea7250,fab2f190,63df6120,ce47500c,debf7371,49772e84,cc53d54a), +S(8b78adfa,af8d7d08,d1c24e36,1623da1c,659dcf91,dc51922,2e689267,7277c05d,3a0cfce1,3c25700a,9b255606,f8123a00,ffbdc3f6,8eb3fa88,cfd3b478,e4ed0fc2), +S(679bd899,2dff3884,dc680a96,134290e9,3c66029b,922706e,54f3827a,383a9e17,2a70a1b1,948a3c01,f5b9e98d,54069cf9,b5a7dfe0,d7ce12cb,731b1fa,83a8d54a), +S(6b82fe,fee6d419,b66b29e1,88954e32,6c426a92,bb539779,1bf562f2,e06fa73f,918f66f0,10980d3e,b3d62bca,d37074aa,766bd449,cb07ac04,5ec1aa25,36b258bc), +S(a2174424,8125296,680f8187,493e18cf,41501fea,2d4de1c8,25b048c1,5ef63cde,2cc8623a,42f2c485,7832e98f,a0830c33,7b873166,7ec7d7d1,f560a0d,f2f35b36), +S(e5c0134b,90cf3791,28515ea7,4a1a8be1,1f35c98a,74322879,e6144f0c,7c74ca2d,2e6b7b85,ce459368,cb2e0cb3,a3291d2d,8f1fc947,2df3111,87ee6832,3477d908), +S(d44c099f,3388ffa5,6dbd0761,814cc46e,c0f0950a,869a4fcb,af3c0022,f3bf3618,a93be4ea,b5e7b6e1,b3085f3,85e348c6,aaefff99,2c6385d3,c6b941a5,306f3940), +S(85c3c19a,33794fae,f400eaba,ddb4f122,64888604,ad1096e3,8864a304,e2c07ec2,9100190,4f8c0961,50d300e7,897caf49,c3869abd,ca59c78b,504a78b,cc313d46), +S(8398d41a,77875b8d,ed646346,c5d24772,d1b13891,98c1a196,c6247c87,c7d7b8b7,4fdba1b5,9a2455e7,5fd6a3ef,83def66e,74361e5a,7a4e5143,7e4b198f,329db7aa), +S(eaa31564,d148b856,be888987,4f4b7442,38fb849d,988bfcc2,acee61a6,adedb93b,408065a,a219f9ff,395bf932,9b172642,181495f8,43900489,9423ebad,3dfd0382), +S(d2c6b904,a0ab1acc,a12e5e1,3e794364,cc7d3c25,b53b7bde,812fe296,6fb23626,85a2ee1,df9d42cc,f44e327d,62369563,74fe8e73,c32ba9bd,153d833d,6af8cff7), +S(f00854d7,742141b8,34d0c2fc,76b73993,a9f92f1f,256b1865,e9863989,cc5bab82,3346d28,63813a88,f874c5af,eabb768f,a5621abf,c57a9002,965a597e,1f7632bd), +S(207635fc,7364852d,15a13254,9f21196,262a1535,bf6782dc,3ff2dab3,e429f9b6,ffbab84f,ec05fc12,63c6083c,7192f825,987b6f4f,a1a9ec5b,e01e1374,652700c4), +S(3cb8abfd,a8a5556,15252acb,c538f91,a8dd2523,a3ef5805,23367641,904b0fd3,9715d371,20f86a86,b98980bf,4c9fbed0,cfdc2e8c,fa86d60e,9d35222d,dbbee8e8), +S(8dccc315,1f8cba9e,384cd23c,c941a3ba,5a11be94,3af2000b,18127932,9f276291,6de7b0a9,49487cb8,6adad7e9,bfb0df97,30f460e8,ad19dccb,7b7e9a79,57fc48b4), +S(4f0780b5,137b113b,b843e566,9bf5dc39,cfe82b2,d6f61d4a,76555b56,9c93cb6,14de9aa8,8e7d9cd7,61f7d08f,41c4c92,f57f6a7,266e878c,cf407bea,11b9719f), +S(d2005b24,71e3e622,1ca597ff,9b0a59b,7eeb558f,5103a39f,630f7a45,85500810,1bf3440a,477786ec,27dad5b4,5d219403,9cefd000,802d0419,df34eb32,cdda121d), +S(4b4d17f5,c1f6b85b,60a1e1e1,a9d1ebbc,dcdeb1a6,3d076dff,541950bc,23c347d1,f8ffeeec,e591cb04,21f97aa4,f016b59d,610fda19,34470b9c,67248011,8f07332c), +S(a4d4b2c,5cc168b0,a24f2b25,4710ebf0,d5f70a4d,569a966a,cb8e1f5,2c2b7beb,f2307744,f8634646,19723122,71c7275e,2a2ffa6a,3a227294,122c8786,b6941609), +S(2fd89831,52c10fd,faaab8e5,dfdcd737,b13a394f,4c924adb,b8aee90f,2bf5d1a1,89f91750,69d4f115,d3e3cb99,4f1c298b,9de9f312,74d18976,65238a84,dd5f92b1), +S(2b66ac34,a669780c,d779423c,17e7a26f,f19cef5c,49919fc3,76255ddb,62c5e2ca,13b2ef7e,c4fb5fc,93fa016f,381dea3b,cbaa9c90,193b3c96,c1a3d86f,e2bef8c9), +S(1a1dbca8,b710565b,152f3886,e4793f37,36095569,2e782f1d,3ea662bf,87305c27,5af8c42f,99d74980,baae2dac,a58c2d05,718a0abc,ce40ab54,565e7452,69d7f0dd), +S(5c85b30c,d201e36b,c6c9d70e,da01a999,3a4f24c8,ea0e03f8,226eae2c,877538df,15ed51d7,85ebe78a,bd000285,b64685e7,98bfa397,40ae17b7,f1ddba98,a90ed521), +S(dc5a2996,fcbf99df,257b14f0,658725ec,184f3411,9271fe9b,9da19708,6aa487de,45ca8e07,e82cd9de,8dbbe106,1ade8c62,846cdbcf,85ed5b13,e51d1680,4b1e3a0), +S(ebcb525c,747d5ed8,d877f3e0,a632fd7b,88f7f894,84e16ddf,6cd8ef6b,f5925dcb,64a4b31f,50fb389f,cc92640d,c7aabfa4,189e46dd,15e7308c,8d7c551f,789aa33d), +S(a63c01fd,826ef945,43243395,2344af73,9bc5ea53,3b5e2e6c,2fe64b76,58f89238,867fcca3,7e861b09,4ef2f151,75ac0101,36cead9f,67b00d09,a50a94ad,453a1d69), +S(fbf5906e,e1e05f1b,850cfa93,34b3b230,391fcf13,94791696,fc63d6b0,71c29c58,61290a35,410dbe52,f64b4b4f,a5dba1a3,23c98bdd,f6dd7957,383bf40e,ece088ac), +S(b9d3198d,ed13334e,1d43b7a,e909713d,af368d88,a62db5b4,1552ad31,7325e249,4ce0e6b,72358d03,4375c5d4,633ee51c,ff9e453a,4ad7e88,9dde7d51,83adfee1), +S(b928d409,365d80a8,e7b3e61b,1cc2976d,c1db6158,a31be035,d1e9a8a8,66e976fc,ba4ef615,81b4f698,f653dddf,5956fd95,f6a55cc2,618c0d39,c3c789f4,61be8e7c), +S(1b4fcf81,5be7ac87,60582a9b,39b62317,4c72e043,48dc6f17,caa6fb5c,9dd46d1e,c845031a,df207d9e,3e006d11,880f5c82,50d225ca,8dd4d3c7,ed0ab170,5bea9b4e), +S(7f33cba5,c5391f36,b5d1f186,50220df5,cb79ee4e,cd1ef5b8,2b2d8280,394b7d68,91025af3,68487978,1d88dd42,f4746c5f,7cda4733,141c003f,ee4fb1fd,8523141b), +S(986de6,fbcab206,264c34ad,c38a397a,384bc794,b03e57c4,e3f0d253,fc94c3a0,b148492,16a7623d,d23d76f3,9cd22603,a88f81f0,a2351dbe,b825d1c1,6d46ad81), +S(f9d3cb99,a0ace3dd,65eb373d,24b3c05e,eb995a5b,65891ef1,3dcac23c,4784f224,3f94c6cc,95fd7fe,63c97138,90c031dc,c9361fc0,6ec5caf8,2e392c1d,b6fa6058), +S(44b5b53c,9da33493,bf040994,d195f45d,c9be8284,4d12315,4b782a98,b45383fd,7dc44fd,ff6acc88,9536ff19,4d28d892,d1e1fe0d,5d59860e,b58e6283,88a0fe8), +S(90db2c94,39ec0476,576de7fc,e6efd4d9,4cdc5052,56cf030d,ccba218a,3b3037fc,3f243dd4,4b9e8733,1548c213,9728de99,b520d31c,876dcc8d,ddb218e0,835e7f8a), +S(2369f76c,240f538e,ea7fe150,3c753bd,b41f031,5f703d3f,236745b7,ffa1f7ce,df31a9d0,dbda6762,ba904f41,3f46ce84,419a6734,56c6013b,939050b6,5d4bd15d), +S(67ded26c,dd7da1e6,d8373706,7adffda3,3d9fea3,8a7bfb87,5ba7d6f5,96ba65e5,73c5c136,d53162fe,35e5a3de,4190a79e,cc181f23,b5367ba,7d237903,890f540c), +S(3bebf79c,fa918ec9,2fda707f,800af057,13fe0ec3,efc1edbf,b9fd5917,1bee00e9,39783b0,bcae56a0,33e73001,e1fb24c8,c708c74a,fcb42664,53962973,d361f8b), +S(31cf34dd,edfeb1d9,674a2de5,11d7177f,e054181,34da2b0e,dd955c52,67eb605,659dd41,89c1c195,6dd21c44,bb37c910,df2ee864,aa5a2a61,a08a9349,34ccf9b0), +S(86439b3c,3d830a79,1f5cdde0,35821955,2eb0772,f5323278,b8baea2d,5afdec0e,8e5b5552,e244a208,6d5fc389,4965e367,77395e4c,d88b0c6c,ed513dbb,58836e0d), +S(a7041438,d237f957,cd3423d4,70bf34fc,152d1823,c389e5d1,d700a5b6,34101b4,aef966f8,c9acd2f1,625bfd1a,712d135d,c8e0f270,3fde3ee0,3c6d274b,101c26c9), +S(8c29a32b,b154eebb,a17eea82,9605b681,4f728f1e,7be0053f,139f6599,d2a6b023,a9813842,6c2ad3fc,e157de97,69caf8cb,f2db0618,b5f307c,200414c8,2fb4608c), +S(ede37b46,82448954,d786bbb4,874a61d8,dfd38de4,a7968876,c0585cfd,95ee04ce,3b9bb92f,a8e8b6ed,b30cd1cc,5225a80a,53fe738c,cbf6c2fb,4afdd6ac,7a10cf53), +S(e5cb4478,e91d2fd6,26950da6,53445dcb,5d591ea7,5915e637,3d82f963,f3ea6a2e,dda0bf97,cba5a77a,3051a09c,7d29f91a,3b8b1b3,c1649ef5,23c692ba,18cc8906), +S(e85f3a7e,cfbefff0,f3ad866b,3838208b,81d8c4e1,dd2fc809,8149f56d,e4c90aec,732a7905,ff3ffe33,d05738b6,1e6c0f57,4c1eccf8,e883a75c,76e50079,b00a9799), +S(79029c02,c2b0322f,2bf76cac,4b5f8356,4ea652c9,3ffeac8f,7f7882b,e772cb80,3e630bc3,cbf85752,f90b6312,4b9bebfa,612337d5,efc8a0a3,157dc666,27020f62), +S(9b827836,a74cdfe2,3dd8adba,542e13a5,c8e413a,cbe32695,b77fb140,8ce640b3,66e4c425,7d99f9cf,d9d6a18c,fd40e7c3,9fd37363,b0228206,f3ecb699,d6b2f2be), +S(bba7b2b7,facbfe34,b945ac0b,9d609b0f,3f0adbc3,eecf16ca,ac54484,dd564c6a,3619817a,1304fe3c,48272292,5d911d7c,ca33980a,33ddf647,19eb63e4,b7a1e6ce), +S(579c9681,cc98eda3,684b5d4,7f1ee3c4,5f8e7ace,c620509b,56f9e116,4bc905a8,48bc6bf5,90bc2d33,937df32e,a082102a,2f19a6cf,6ebf0985,6acc53cd,b2933d37), +S(23b30759,4b171e8f,ff9de455,f5eea514,e4c49e82,6ce3bbf7,6d3e750d,94c4fb8a,df57c655,45cac843,6db4dfba,abfac03e,a0489ead,6fe4dcbd,d12c2d2,21d8df8b), +S(8b4de9d4,f5c53178,aef16a7d,73429825,9e87e3e2,7a803197,98793d23,4c4c29da,a66d90c4,9d441721,3a399ac8,2c84baf2,67569201,3782a5ff,b2cf55a5,7deba029), +S(396fe929,2dbf359,ad3dfdb9,58e7337b,fe8791c4,d2ab6dbc,35d8c436,c30eea03,69fbad37,4fa06b57,9f67d8fb,48a6f09,99b77ba8,5fa7b6eb,96ce1028,44fc5371), +S(56acaed9,34f376d2,d036b7b4,7749829b,f7d32a78,bc6b419a,c25b33f6,808d94de,aae2c24d,8569060a,4398c5a5,a6173cd0,dcfa15e4,49642720,32785ff9,f0a7c164), +S(18ccd734,cfdeac35,1dbc13d7,2cd095a0,49a7c6c,e3fd781c,ed552e71,5ce14b0c,79cbb2d0,82272c7b,9af52227,4354c2fd,80a4c2df,5b434bc8,4c1e99c,f45a1e61), +S(73f91ae9,f75ee99a,227785e6,7ee3e1f0,384fc259,6a95d8e3,2436ffed,17f81c6d,f410e115,f57f618f,225caab8,388c97c6,46a37aeb,f184bf2e,408bae0d,ab2d475f), +S(f0216cb6,e9868a3a,cc859cd2,fee969f,b35fccdb,1754ea51,52995dc2,1d9b318a,e3a9a102,719d8398,610498ef,b5dcbb0,27fb3509,af587b9c,2ab5b5f6,35e2ef1d), +S(8c92a0ec,935d03d7,5395de25,3c2c9e15,7026a8d0,ae59a2b1,16d175d7,f70a8b46,8a9b5351,f7a8a20a,e159fa6f,afd58419,bd0e9dc0,def54f15,aa12abfa,65eb73c5), +S(be3bdb59,6c9ec252,5d7c23bc,788ea0d2,7f4c51b0,69182cfe,c095a13a,20b650ed,932c016a,7f006ec8,b73a6d7c,1ad1f2b,ce72706e,bd7e8713,e8a8d093,3586c9bc), +S(24fe525b,362650cd,ed8dee61,7ab4fa69,b06ecac3,fbe31947,4dbd982c,52ad2260,d9c484a8,e7aa329d,136dcd4b,612e0768,3796dfc2,a544a237,73548b9,be96d555), +S(f3a2b68a,8d16b9b1,20067bc0,6ee2f0eb,bab70ac,d6abe6b5,b12ce933,edfb2ff,a3abec92,539974c2,c2217584,2b9ec9a,3bfd4b3a,21c64a6e,ac3f608f,6bfb45aa), +S(fc9a67fe,9cb9622e,a9f20b68,3b19f623,5e12ed25,4a1371b8,196e0629,e43eaaa2,8e3329ac,2191732a,45afe600,43c6c5fb,ce9283fe,695d4f3c,9035ea60,2ceab399), +S(c539c35c,9bf0bd06,af690154,88e4eebd,bb766ef4,737c176b,3bd412d0,f933554,caeddecf,f0fd023a,dfc17791,95f18c1e,bea4bc70,b98eb85,405d5739,d5871906), +S(15871ace,89c88dc9,1d1bf56a,eb4fba,8f0fdb6f,df107705,65ef33d6,345c8ce4,70577775,4dcb9ec3,4765ad82,2070a26c,53c5fc5b,d3a6d8c5,1fe9eb83,635bb9fc), +S(1087625f,6eeca00a,fb9f7bf5,f4b94515,2316693a,ec8fff6f,57217e6,38804398,24b6cd00,e9ad027b,386afca3,44bf48a4,ad587342,2d3d24a0,5eb17150,bdc1a929), +S(98d7bcbe,6aaf808e,3909c417,66e54495,236e1724,6372f821,ea07fd82,686c0d07,b911aaec,47b9e901,4c990d08,e094d124,d8fcff77,f594244c,899a736b,e0661d89), +S(865989f9,35c9b044,7ed36d43,90ee5bb8,6403ef0e,67c3fb9c,eca1f2a2,f7e170c0,533cc475,ed1df473,30a032f,1db8ea42,d6b0fcff,f53007fb,cd41cda5,cf06cc1e), +S(b67f49bd,f912c892,9b26c35f,bfe2535c,830e8e4d,6c62930a,aa8527c6,1ef9cf14,151ef7a9,c08909a7,5daa0d85,e593c7a9,501e492,dbc41800,bf03fcf3,5c12c427), +S(b1ed1735,9a5f07a2,568d9740,3bb402ed,b313bbec,7d037bb0,cbaa2ed3,eacbd50c,5635c19c,1932696d,577a7bbd,411cff9,81bb057e,10436fc,91000bed,b638afa1), +S(6d268375,ec82b57e,7f8499fc,bda8f952,ff6cb4ee,a0f7785b,a8ff6610,84963c71,6b019ac4,d809bf4,1ebd90f5,4d8de537,6171702d,da3e4e21,b2301014,87379b95), +S(8a17346a,c18e4d6e,677db3fe,5df942cc,ddc66882,e39002dc,5815ea02,1ca5c332,c457ecbb,add867b8,70b28f7e,b27bd804,812c362d,1e94d89d,741abe02,59990928), +S(4dbaef58,9616daa4,4a8f892a,e48ac0e5,135b7385,25178135,a233af40,fbe506,90df93c3,9badbe3b,6eb28cd0,8120df1a,442429ca,d8d80108,af4bbf19,2d37b9cb), +S(cb18b241,a5d1bd30,361bf7c2,beb4a14d,3909be2d,dc7c62,d44e35c2,298b5a96,3c0a09a5,d96cd4b2,a1d15a13,341d455f,c04e3008,87c4ea96,d8f71c7f,ed84cacd), +S(cc463ae6,a1114d8c,107f543a,ef50bb07,cfcb222a,de5920ca,58ccaa19,750eb90d,31b54fa1,d115415a,b7931343,a8143a7c,cf2877d3,3d3d1f44,464163b5,c61c77c5), +S(8a0c1391,777b772a,c90d4d50,6f0a398a,45b2fc65,331a67c9,dc39aecd,835bcee5,b8d2bc1b,21248b66,2acd6e9e,1ae802f5,34558837,7da057f7,ad732684,79e4720e), +S(6fc3ccb3,acdff113,69caa83f,e304303,4a9dd77d,fcfa6c25,876cd2cf,75a5d7fc,5d0d64fd,d8f23aa3,5a7b9601,fa6d6deb,bdba27c7,2f227cd6,c4d3889e,49b15379), +S(3b10fd6a,125c3a47,2315bdc5,9686cd80,5b221012,65726bb0,64c974e,e74b778f,20bf9e4,521abdaa,347fb4a,a98a70f,303842d8,4f3e04c6,92d798ee,be97313f), +S(cd78581,a4707b5b,710bb827,b3d9c1d1,ee4a595d,29f90d50,607e3970,620ef0c2,26f5320f,2b512c50,e773a94f,3efba18a,cf343c5d,553f9ffe,67b39cbb,7f0b8831), +S(9bfce83d,b9e2cc9,969d17aa,eba0e037,22cfdaa2,a4175180,ed8d8ce3,7a7deb5d,2d2cbbf3,fc83d702,2d39191f,42eb42a8,555c3884,21add05a,18bb4376,4652477), +S(124e59c,53bf8d0b,a4189a1c,5de61726,3f6739dd,323ba104,892b505e,d8248d31,92d050a6,3e83521c,4b08061d,aa635990,46d52c4e,67c014c,5e33d7d,a6e01942), +S(20948e19,7a26173a,44011c9e,41676cd,661acb99,45a9e4ca,c0dd42c4,6fea02e1,8138a593,be21c5c2,472a37f0,5f2e9151,31bf249e,c6128dff,d218307e,4b661d48), +S(50726fe5,fad5628b,441bbed8,5347af3e,506cc7d3,43d7f0cb,213d63a,aa54365c,47b065b3,280c1f8f,585e05c,dc9f8b28,73f79479,b95a1bd4,c0a80469,eba92c48), +S(fad9bfdf,550fc926,da189531,91111112,a4120e56,db459577,aeea7e13,c2073f2e,a87e89e3,8d49513b,23aec5cc,a251098e,c6216ae8,96257461,2a7b4e08,470d680c), +S(66fe56d1,7395a7b3,b016c8b0,e5cdafef,d9e652cb,526374e,1f7000ea,b956f33c,ccabda97,a6b6b288,54efefa1,ff17f621,88b7cbc7,c3d363b3,25c31235,ecd26292), +S(8273997,5b5cbb89,e4246a1d,6428bdfd,14cf068a,6394a31c,a5cad01e,de3f6da,54d7090a,afe68aee,95a2f829,9d324bcd,9a1c4e16,17370b1f,5b940cbe,845a5013), +S(dc038ef1,5db1cab5,25660c8c,11afd35f,9423d230,2bf5b002,5df30400,a84907b9,cff2179a,904e5f81,e996700d,e64a548f,6ebd7b06,bc12a6cd,2ed74af8,9cabad6e), +S(fd501f6d,fa76dfc5,8da70f14,32eb1053,a5f82fc2,70ed661b,fea83798,acf02483,c04b3038,c2f4916b,178cd919,e953853,77d7555a,a7e3695b,1cc8fe89,d5d001b5), +S(c33af33b,fd47af39,ff687775,aa5e6ead,430821bb,695ba499,e4433a2a,d6190ed4,18555539,664c445b,6d317892,1af772d,7ae10c15,62d1ddde,91f47b5e,a1d4898b), +S(3e1835b6,34c53347,5fd5b032,334dc281,97068930,fb7bdedb,f8988b64,acddd3dd,2fcb5d65,940e235b,f8e1de7b,6aedd7d0,d2061181,dfbcd049,85df1505,a8c61db2), +S(c3b0ff1c,6a0ea466,357ebb78,f9ad0335,2b964b19,8e30e1c7,5b37bfc9,87e0061c,3ddd3d1e,7d97ee9e,748637ea,d8ec4987,d06b1f11,cf9ee9bf,12e85965,8574a95c), +S(1b690634,fa027e38,cabd8f87,3733476e,4f8e4bb0,543c5f6b,88575103,b51f29b9,3fede999,23be0482,caeb15c6,c7f2a00b,92b92a97,e66f2db,2c5d76d9,aa58210c), +S(4f661a50,fed5fbb4,ef8a1888,f1fbd3a8,b35b38fa,91d8601,80a3a70f,17f4fa8e,80e5e5c,7d41736d,29f94284,ddf06611,2cbbd024,60723497,9540c1aa,26232e59), +S(4a251861,333df3be,7b5852a0,f8eed900,dc58d2a7,3cb6d2d7,d45ac506,55126096,7b0734e,be6edf25,b9b4845d,8a93b0be,4f9958e1,2be61a3d,1513dd71,1004361c), +S(ff1c9a62,10360484,6bf46453,246be39d,7f595da8,dc17c86f,8c441b28,64b99d6a,7f01a489,404fa78c,aca02b7,f12a654,5692c8f4,fb787e4c,6e18a9e5,8e1be696), +S(4df0bff,651a53e9,30f631a0,3b6c170,ecce67a3,f92ed930,79e92099,46994deb,c79c834,33a1e795,f4334535,67e122de,bc81c4d,ab48a11e,a64af4de,4c6ebcd4), +S(2dfcd43c,a0000881,15845e7c,966004ea,bd4c909d,fb725642,18bf28d2,d66610b0,6ea9912b,e3232c75,c25b8272,820db699,bad9c292,8d2fa03b,c37dadb5,75a78b1e), +S(2cc759bf,7caff909,4abb456f,f8cb214d,f9353f97,e4f802f0,879b7ded,69eab4db,76ef9968,553c505e,697e5981,1f85a6bb,4d41418c,4b3b5dda,a024d69e,3a2a66e5), +S(a72077e5,8d73d653,66cd0f70,fe79c8ed,e9ef34a1,3e03fa67,70ae3f99,3210403b,8638634,217b7929,f8bcdfe6,4a64c053,5cd1640b,cadd7a2c,e6c5b880,90de01a8), +S(9c598d95,41c3ef74,73c94eab,20021f56,11ce40a2,34936d66,3130f788,14136c47,49702707,51df2f9b,d41b1ccb,1ca90f65,1ee65f69,75262725,b6962c56,dcdf2c4d), +S(5704f6d6,463ed861,cb25dde,343beb26,6557e3d0,7ef35c9e,cc435efd,f880622b,6d605d31,402c9bd0,9360f2d1,1a4f7a36,ddb8ee7d,543932c3,d546162c,cb0e4660), +S(d47b07dd,58962226,fdd1ec80,4a484496,ae3dba3e,41e18f9b,8e48ff60,4b00d727,26e1094b,c62614ba,1aa4df72,f3486975,6b8eafc7,b04a3770,22865b3c,a52028c1), +S(3971f023,44b7b268,754180f4,fa30d0ed,6596d59c,eb806e0f,9186c9b5,54e62b09,1895d58a,c951971,39d03562,6676fdf,cc53dfc0,317d976e,b0afb990,cc1b91f), +S(4b2be90c,e3e3a804,c469fd40,57bcfff6,6e9a220e,713455f2,ce4ee3d3,3cfa73c0,c0e2b79a,cf348a04,6f301f71,bba98de3,b9d1d8d7,ee16937d,e11e49e3,67c3cfd2), +S(2138e37a,29bbb1ba,2f051d4c,984d36a0,7531aeef,63fea098,417db4bc,241a180f,2e243bd0,69c0f7e7,f7319bfd,bbac12de,e03cf686,c97eefa6,dd58f17,c747bab2), +S(bf7bdaf,15838ccb,21a9ac7,3fd8d2c6,2013a163,85b583c,4c458db7,f8ba787a,8481d283,c1c4bac9,87ddd181,b12a2e79,a60e51a,2323c981,efc7cf51,a1768168), +S(e000b589,51237195,b81ea4ec,a4cdcb3f,b509eb80,4322ac0b,69feda94,e78fdb1a,cb527a4a,39a9c03,3dc01d1,d4221deb,b89b1126,8594dc82,fa5faf80,e538783b), +S(dbb2947c,2602e2ad,19ae7079,b6b9fbdc,59bac7dd,1e865f8f,3c802ec9,ed951414,9f646e9a,9f069a54,c1f3e88d,e8fef48d,9c6860a1,afec56be,46ac8943,d83e3cbf), +S(40bab32e,d118cc1a,bda71e7c,828d1ca7,aac8087,b720766c,409f4d78,e711dda9,ea7cd00e,c553e8c,56c9f992,b16a9830,a4ac30e5,cdae357b,148bb413,9e2b1d3e), +S(b2860f17,55e3341,eb6bbf11,a043b6bc,bf70472f,26b2d276,e9c30516,9c478b9a,bf7cc672,94909583,ac6147f6,2c9a3a64,8249513a,9f5c42eb,d0701bba,24b9b1d3), +S(d6e4a042,7f254b5,f2449539,9d6c0ed3,a741022f,f7fcf819,8a7ac04a,3e0183d6,ab1127d5,17900200,4cce6a56,7dc4b9a9,c88518c6,a8e03d4e,daabad76,f86c7be0), +S(57c70171,aaae00e5,e98dee16,e0d74df,82b05fda,8a01db96,67ce4d8c,ddfa9aa9,f4306dc3,1b82356d,8875244d,a713b6da,9fcc95cd,6c861ac1,1df62e6f,c6469e32), +S(e95ec894,230825f3,83442633,8cfef200,69ecfeb1,41c4bfc6,d0d6f2dd,216f36ad,e1f9012d,ec6f62bf,a1b5df85,c4ce2572,bd5ffb4,b8bd28d8,bf982833,e2d50eb3), +S(99d32dde,ddeec538,c8189f02,40bb4d44,cfbee72f,b3d42f9d,319dd7b6,97481451,75d2e691,ca7706e2,9d8c3686,d3fb1ca1,5a505a11,7662a2ed,347fc0a1,8531ab77), +S(be2418b9,b2c44233,b4d97d43,87085579,9219604b,f1a689fa,54523d2a,85677b93,69046a2b,8c329e27,cbbf7b9,d31f2009,9f5aa01,fd0b3905,988f2299,1d73fe99), +S(a88ef29a,67ddd120,c5d43d52,9d270c64,16750835,84a5dcc7,2f05be84,7c3b9b3e,902b663,4466410e,fd0d2251,ae10edfe,72a85d32,6d6a638c,122d7160,49c6881b), +S(95ea7c70,c4d0afc7,b31826e,c6dda0e1,491181ae,8970cf24,b99a8f41,bd428b3e,6bbd0bdf,d884903c,63a2a1c,df73f6e0,6ed335ae,53c64cc5,fc775666,6d8a15ad), +S(3341585e,671b8891,2d0b2944,334649af,a0bdebce,cd445e40,6e416ffe,f2cdc88f,bb17510c,f427e741,5b36269f,c702fbc7,42e36c20,95b69fce,bd31b7ba,fec345d4), +S(34e362c3,7c2c7b59,c972eb54,ab315cd3,da472933,34a305c7,d35c754c,3a440045,5e5d2940,3119cbd0,685f1cb0,b1e446a8,ba9ad625,8234ea7c,8652f971,c53d1b44), +S(f8c6c1c6,16b8bb82,c8d77244,86e10cfa,105e9a01,675da3c9,8e3936ee,ee01cc69,dbbe7cff,73929f21,4bf4fbd8,aba3f18e,461c4855,a204a7f6,319ffcf4,2437fbc5), +S(f4f98cf5,2be30eae,fd2ab1a6,dbfdba9f,8676cc6c,8b32a6c8,a53b10ef,dddc3051,77fed97,782ade72,bd5e41e8,c4b376f6,fde76267,b0a0cc45,a56e3f0f,ce6b2f03), +S(8b642ee4,8487a3fd,2d983039,48cd523,6456f3c5,f9d8f4e6,4f0af631,96b47d8d,22ecdb21,2e8ac0db,bf74c4b3,685339d7,e417686e,1c5337e4,872db54e,aed524c4), +S(5f6923ee,efc718e3,25d22dc,445e04ad,dc460268,58349b42,528c0078,f2a725fb,4ead0dc7,e697cc39,35d46533,73a21016,1a00ed11,273c3ba6,9c5f45a1,a4f38198), +S(1da37bdc,abdce508,9dc3aa72,2c93fb5f,64dcaec7,759064f7,82926829,b91ee1fd,1ecbb28e,f4f4b980,d92db2d3,c78919c9,e762dd5a,ae449d58,7105d84e,41f686dd), +S(ff3be7a2,cb1cf4e9,7b276ef0,235a7eec,addee879,78147bea,120e8ae1,bf888cfe,10a7bae3,da012eea,89b0cea,8deb02ba,1515ec2b,e0b83d05,a4fc152a,8b6e8371), +S(1658579f,72067096,947817e8,e9c22574,8495eb1b,75bb3729,88d45b93,d90531fc,d4538ab,19420b47,3ee869c1,cd1fecbe,f1a8ce73,871a7195,2319bad6,2ae450c), +S(96edfb55,bdc70246,21e1b92c,d2e85b07,b0ba9244,adcb5dae,f82f7afa,a97956c2,3666a36,1c8d1b06,e053ba0c,4a76dc88,2e3fe10c,e741defd,48ebee6d,4877cbbb), +S(4b4d282e,853b581e,55ec4271,e78c2cb9,ebf1cab1,8c15bdc2,2cdb05f1,7f8e44ad,2be45bac,a3257d2d,ab1a5e66,216f421a,2339eea6,89123e15,2bf7b010,e349ee2c), +S(fa12b099,eef9acd5,4c1c6224,117bfb60,12d5a208,553ca232,e030056d,1a141e17,40ed149e,d62259f5,fc98142b,9753503,ab7e9736,5238d4ea,c80b6859,52bba875), +S(c6243386,53084c9d,7bbf3b74,39f0b21a,ad2e5233,17259d9d,af2de00,1d4605ad,3b5376e7,1f08cd2d,3d319056,94608618,960e73fc,d27625a4,92613667,caacf3a)}, +{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), +S(90bfdcaa,eda30aca,f86d6eab,82407089,3746efbd,62f4a400,86e0589a,f3ea5cc3,9400154,63e05bef,5a4e2c2b,8681a1aa,95042864,447c7bcc,5ba2576a,eae911b7), +S(4666582a,2265fc0,643b1f3e,d003ab1a,d4567a1c,239e82d7,15a8f6c8,23616100,d7efadc1,2e71ed16,cebcd191,f34a70cf,eee6a7b0,dfa87724,dea4e464,ce50c9bc), +S(a5338432,7502bcf1,4bb11dc0,33e544bb,7aec0e46,f40145c4,db65cc46,203d969e,b228140a,7f3fcf9d,fe400a28,90200ef2,6e5f3c78,989406cc,b9fd31e2,e9d54049), +S(d6da1a9c,c1d81eb,9dc9a048,9acb4b74,d119dd52,684f12d4,3fa6a74b,7130c43,6ca8ebef,39c08b97,761cdb6,dafd2143,55715bfe,e8ab8e12,e51bf1ed,6eeed696), +S(27249c84,e21154bd,90034fe0,c5c5c510,c6b90e32,1ba4aa98,ca34be19,c918fb5,60327ac,f3fd64d1,ab14fab6,afe20b42,cd493af7,1d3fd0a8,ec2d064a,ecefed86), +S(cf6fe5b8,cc605dce,97c1b586,e3eb5945,38c02888,43bbeada,65a6b2c1,c2d66d66,21f3d35d,69afd6fb,704d1f0e,1cc2f720,2852892b,afd431f5,8fe3c1,3df78c1f), +S(cb10e984,f228da46,2063ce84,3503b423,20898a8b,98795846,8438d88d,4f0344eb,5bcab6c0,5de27bec,714ec992,dcb2875,d53f3f6d,a5ad247c,c81e8093,504504e2), +S(58c2a274,ce1e7d49,5a1d7fb9,7ff21f88,9e6e5230,5453eade,4ffad95,36037bb9,82e4a06c,5f7a5dbc,5e30b43,dac01491,addaa6e5,8b1a33b2,c082b4b8,fb50072), +S(d59e4e8,47e98edb,a494a195,25d1ffa8,63b2c22d,2476b2d1,2d704c0a,b30a56a2,bc2296d9,53902891,4278647,fc755979,c8d5cb3,502ffedc,8f412cef,51245085), +S(bd7feae1,1c4f02e4,9b1b3697,9370f319,88227ebd,9f4a6711,62e70744,6e452cb1,84cb5bd,1ad0381a,c9eaca88,b50e27da,efffe65b,f16f6bde,50bdbfee,69d22e72), +S(4757cc99,f4010ebd,d2e8c24b,ce7e86ba,febc4175,3f1f3ea9,f7afe8b1,3b0e7070,4b5cb36,55e3f5b6,bce14af,62ca1ad4,97480431,3deca874,dd2f8580,730ab36d), +S(e673b505,1e2f3e1a,f28284e9,b32d0c9d,16e7918a,1b8a13b1,602444b8,875d3d4b,f17f068,d02dc75f,dea5ebff,549a2f86,f9598c93,4db7050,915dc965,830bcc1c), +S(63d23920,6855af5c,c8c7f9d5,4986513b,455ca801,e172937e,a93a98df,78f36679,f95c588a,ba4d4bfd,fdac3c8d,f8a7d14d,7800212b,504e3deb,9220bacd,69e12f2e), +S(e74fb7b5,202d5a24,37a982f3,5018450d,ffe2e238,cd4fe3c0,60ce38d,18fa18b6,4715c0a9,f58d9421,6c3535fe,d6140395,e302e18e,2df0a870,52cd05ac,db917ae2), +S(1929be94,197feeb5,ac631038,f07c7db8,ff2226d6,c1763d47,a45c9e5e,7719c60f,c7816c80,8fe129ef,9a5bb8c6,674495f9,3f1e711,133e3cb6,19dacef3,815826e1), +S(76a43955,8d625d34,8c5cb3a6,e2274b60,8c93f08,6a0a7aea,be1858e8,7c1c359c,9752d697,a67a1743,9b5c4359,76658df4,be1452ee,1d4e0645,597f59a1,c60b3618), +S(4a3c36c,6418b8ac,920004a,4f47bfa1,1807619b,9fa39030,95f1b0a5,d91f46c1,95668552,e63f7fea,cd2b09d4,9c49e2a3,2f2fb824,11c5b819,c0efd09b,d64f6b8d), +S(9c5a32f0,d1a0f2db,253d47d5,e7c44967,26bcc7d3,b61e3731,3bbe5fad,ccbf4625,232fee50,bfd72474,af4bb5f6,afff7eb7,17efef90,7579d0b7,38542e56,67e05de8), +S(672eadd1,652ec6b6,a0c37e3e,7c8f0d5,a51d6f40,fe7bb66d,b4fed735,2e066063,ee5ba376,b53e9238,efb76b38,2424c8ce,d3b0f91c,99da4a5,7c98b7eb,48e5b891), +S(f78a9f6b,77af560d,c42d7061,831270df,21a73ecd,a7bc19e5,bff6649c,414b45ca,9f9897db,a7ef70cb,f4ceb71c,2572c3c2,b89c9c0f,a18ebdad,fc413d34,5289776), +S(2fdc690b,b0fa8c76,416b7ab0,ed6fd336,af4eb887,f13d5b1c,f7aab941,a7f63690,ab602a5b,f8ae3e5d,9aeaade1,1d126154,2f38a881,d577daa8,fe89bb22,6352c6a9), +S(3e6d45fc,5d8a498,b31d95ea,acb33144,ebb45ddf,ca3fd8f8,b5b22f4c,9d57cb6,f7e817dc,b718028f,3b18691d,8b9a25e2,884954df,59141cc7,ed939e0b,94cdb2d3), +S(6bfab01c,caec1bc7,1c38fa8c,b62ae3fe,9a24ee90,f6af6206,3b12d9dd,e83db7f4,5fa5e4e4,9d5f9641,559636fc,35b60199,68097451,10bfda67,a27de3c4,6792eddd), +S(d0e37c85,88d9a4f6,f135156a,25a15af7,2835de73,53f7b4af,336df017,d69a7fc4,8b9d798d,3cb04f70,41ac72f1,38462cbd,533324e0,871230ed,c3a06ef0,f524e20), +S(3f2a406d,eef9506c,2432dbe4,cb2d0a6c,a794356b,7953abb0,1ea486a4,e5db86da,ba0e92ef,aa00c78e,6f854963,7d8cdb5c,30869636,2cd71113,a3cea5d,9b492210), +S(d8b41f1c,2d2eef01,2b994dc7,21ca505e,818ac75f,4a396750,3fa3fdb0,2cf56fce,293fa011,7d231d10,30daa322,94d74507,3f9cb4bd,297a2f81,c812735e,33dc13eb), +S(64a07ffa,80f69a36,19f29cda,d1dc1b41,d7d58d6a,83470353,1f8aeb3b,eae51d91,b9b83f0f,43349999,d8efd66b,695bffbb,f67d3817,808149da,23978cb9,b43ef652), +S(348c104a,9bede4ae,3fff9b86,15eaafe,440a1cc2,1ff484bd,b442ad84,86dca015,41820b57,f62d6668,ce7fb53,2f3d3a94,4ac47c22,ec302d69,f98f355d,ad9e79af), +S(29fa80b3,e0a7a062,678c4612,41fefd8e,95f8e02,14795ae0,2afe449,1cf58041,6e3ae72e,ed0db6ed,1398068e,79cbed22,791076f7,515d5383,8581957,a73761d1), +S(6ecd85c0,afd6c385,15d8ca8c,30d618f1,8963b70b,fe73531a,11444a85,35c4ef29,c3e0cf48,4522b927,c1615ac7,9943e94e,aacd0849,12cd7221,308aa14d,95f05021), +S(7602cb28,f9703b3d,e0bbdf84,5e4f9326,712582b5,1a0cd719,a6674343,af2d089f,5b026bc3,bae6db2a,86f6f970,1682d8f9,82363e02,4bb703a3,945d7e19,d0b9efd), +S(a59436c1,389b4c00,5e4534a0,c7ce00b0,56f72ddb,a2b920e8,896d3bdd,74b29723,36c401e5,df5f695b,959c0474,28c9366a,774f744c,a60dba69,4fa55d25,2a5afd9c), +S(55377738,4bd49ab8,21e96778,17e0e95e,b6b08aa2,92a5ed47,9eeeb607,a0f4e176,61257b61,744f2c95,2d80a9df,29e47bb9,ad933877,eea75922,a31acb83,ce7c478e), +S(ac7ac723,2ac8d976,8e34fe45,18f5fcb5,518ea1f3,37d5bd53,5d5df329,d20a5f4e,e2317908,50bc5a02,f14ffc6d,c3785319,c30e93a3,29304698,a136d6ab,957ed52f), +S(9e49dd3d,aa78f89,af09eb7a,a87cb01e,6b55245f,dbe5b5d8,4c43db0e,1b5d26a8,e0ea375c,dc5eab64,54d16b5c,ec1435d2,14b54dc0,51806c9b,e232c64b,9843812f), +S(3537f749,4c903cc5,f5842fdd,c28aa98b,973dcbf3,20e2da65,127e4b22,4c747f59,f9cfbc26,5666e24e,1a9996fc,389ee639,ca350fa1,7a2191bb,13a2de15,63ff24a4), +S(d7ff3397,7aae895c,48e262c,1c93a0fd,2ea94961,bf19f720,77978415,e0f8591,2d3f2397,1cffe0f1,74a3ab24,614f54bf,85f4c513,21cba826,de24b150,cf77abb8), +S(76336d96,8a54c4f0,365712d5,a34c60dd,ed6de6a9,f4883994,f4ce2331,126078ec,ce745d4,62ebd771,359309e4,ee03b19f,83db6e4d,5ce7fee4,f5e3033c,9bae1c7), +S(63b503a1,615b32ee,520657d5,d2354c66,6b7ba964,a5efad65,d5957c99,65bb6991,af4ed8fb,bbe3a6ff,ee38c670,688351e1,d4a4a45c,7d5b9d5a,ebbce84,9a4ee02e), +S(a562ffee,3f8e26b7,1b3bee24,2fe06199,a198f76b,8b98a8d1,d67e176,1dc070c0,ffbc04e2,c268c14a,1a0fef4,bfa32008,f38a21f,891df618,72fedd7b,5f2cc270), +S(5be4337,20a7b123,1a171a80,fb72b580,a7045724,20d10b9c,786cb0e6,2882044b,c592daff,38d12615,b6af0225,7f39cc28,1447e965,9daaf5d6,c45bd486,f140efa6), +S(86f7afa1,e672e5e0,f33b0346,fa6e3b0b,1087f85,1526271,2ec07e9,82b80843,e7425903,c36d44df,fcbd0d4c,1a272123,18463d3b,12aaf1d4,9174c4e,3777d32c), +S(74751604,d00ecf1c,a56ca92e,9ef64457,fc2f6abf,d067cc8e,b761e120,c0019c53,94fc0537,6f69a1be,f8cfe400,31078265,39d625d6,8ca5df8e,2829469e,d3729995), +S(8b6a6378,49ca68f9,27f0b6c1,e934892d,f100384c,5d902c12,feb4956b,44016e72,862e9458,3835340a,f7c4cb5f,9ce0c566,c1a42452,c4420be3,2ed88324,3f6d7cf6), +S(9812ea51,ff0268b2,f94063d6,ec285595,ee8351d6,b95bb35a,d6577ff4,79d9d18d,c4ab286b,2e9d9545,d1ea9b8d,6ca577f0,ec7479ae,97ffbfb3,27bd9084,8f3ebe9b), +S(4bc3c5b6,3e1a82bf,3ce44d48,25c82c65,8d5d69a8,a1e5b4a9,358ed443,f89cc7eb,4eb838e1,2eed6fb2,81d9de11,cfb5dad0,b08ae9be,f7c82d80,5f3c7a19,3d46b1b6), +S(e269b40d,e9dd3fa1,b5edbad5,83a90477,2421326d,61611b51,bfca9231,4afb2c3e,76633ec,7793b5e3,7b1c3bd7,981496a0,1b9cae51,2ce5d589,2b69c1f,a437931a), +S(7abe755d,9bdc8c37,e99d6917,e5d0dfb7,7e90102d,7c278af,e10c6f6d,74880322,fad617e,3612687e,d31b7597,2bc98e83,c7af5e9d,f4a6e12b,ca812f70,1c5a7a97), +S(8eb690bf,8c75a72f,e635bc55,ad05856c,9083a672,3577d776,2743b1d4,df0d88c2,7737abfa,76ea68e3,1482d3d6,95f1a7a8,ae4249ae,37c68c95,ae605814,6a288958), +S(d0413b90,c3426609,6ea9401c,8e41f0d8,37847c1a,47a47b3b,fd6ffe82,58d3b38d,38c1b369,1865a029,af58a847,4278fd49,9ea44686,7a8b4ef8,63b6dc96,c66e1a38), +S(1bf1b231,9468cab3,2011fffc,96f296bb,8bb64c69,47b590dd,d9d8edc8,ded3668d,1a87ff27,bbf79298,807dee37,bd488762,3a9b5c7f,c5d61e4f,d4de16c3,e7988c1e), +S(bfbadb48,ae5a2997,c368e44b,beffea6,b1682b01,f492c9c2,6bca3fcf,1a0e01f6,7fe11de5,4037bcf4,3418d062,d0bf0bd8,a7399f29,e65f5ecd,9f9e2693,dca6acbe), +S(c2d48434,f2fa7dff,d206ec93,5def03b6,ef2401df,c8c3a126,10f77d49,c14f239d,68e9c025,7483ec64,fe6ec6fe,1159d5c6,400c9d0a,397f0e08,9e92430b,51883316), +S(4af55e6e,f210442b,95a50aeb,51e87ee1,b2546337,664d3a33,9c12a655,2e3ac08e,4f81a92d,fc5c3e62,da712c72,cbccee05,da2e4cd5,6f901bed,a96f9b5c,5c5f9d48), +S(d89bf279,472e7b5e,6f41f460,3d348143,d15b1dd4,7bcef4c9,1274f9fe,9f868ced,cdd02079,9e9d91c3,8fef3631,12a3edc0,962bc718,b7f467b6,45f743e7,db1d66ea), +S(c7cd49a7,27c9e003,dea93f26,fb888cb3,770f5637,58d4f40d,ccb4e0df,d2d1ba1,85bc461b,7e583884,2d4e643d,91ad3179,30d9949b,b29fd94e,4090e6b3,3cf2772a), +S(e1cf9c4f,e0b525a1,290d8ec5,1a3cfb9f,6a78d2c,e817ec9a,a39a538,4f9619af,b6aa8225,d0ebf9c3,4aa0392,a81df722,c8d29cc1,f03abff2,cb7392ba,ac78f5bf), +S(4f628bae,d84bbf1d,fd568c23,10aa10e3,a098131d,65484a80,653b4eb4,ae59b970,e86292bd,cab0f1a,63ada7af,e350fee4,2dcbc618,6838123b,186974b4,16ff2a5a), +S(90b17b58,9674a91d,7c2c9443,61cf8adf,b47e733a,bc775b57,4838fd2,d40eeaad,72c69fe2,ba39f165,5ca31f41,7ccd004c,1eca2392,2973e47e,ffb423c3,5c9f54c), +S(1e13fed8,6aed242d,c543d2b6,9d3ffa88,c87731fc,c4f6ea48,fbdccace,b60ab263,9c1a66d4,47de8c53,2f740f38,af9a52c8,160890d9,5b573c09,9981297f,df8995b4), +S(fe036a4f,713794cf,c0cd3b66,b1a124d4,c6a5374f,810d11c1,30c16fe9,1d8e81aa,f7ff5760,544b9e87,489e3c76,addbca52,308b9155,a7848716,1dd8c1d3,f3c81816), +S(2f9a25b7,73b6cb87,56d1f4ed,691a4fb3,be7ea324,bede8c0a,b9446103,dbb96323,df92e84c,7b76c4b1,f55e77ec,d541ce34,963e9f5a,f4d68fcd,1685d060,c99dda22), +S(ff65bc77,a459bd32,21742391,6e2f9438,b6a38b71,c8c06d24,84cbcdac,ac0522d8,efbb8c9b,8ac9200d,71d4a944,4dc9050c,4661ff4e,fb0c953a,c1c1dcc6,2e44071a), +S(d0e325cf,775d47a0,532b46f8,4ec41698,82aba5fe,83c572a1,1bb18b9c,84edac13,2ceef205,c424441a,fee6879a,a577e1ea,423514ff,d95bc282,6e27b5dc,72f6ddc6), +S(27700ed2,bcdf8ba3,f5ee842,945d9473,9ead9ca3,7741f31,1fad3503,e052b8ba,69c780cb,d6f2c1f2,5104dc40,cdf07ec4,ee76478e,98732995,ca85b5d8,f070c8df), +S(205bfccd,37349c79,5077f5b1,16e63990,8703cb74,f2835302,44bbdcfc,fac24a98,edf25093,8cd87a81,b6f3da85,9129b399,a1971850,86bd63a9,1c370165,a22642a5), +S(a5f79343,8b402d23,6e9bc997,cd08557c,7f83a343,32528a19,c506e5ea,8045bded,9679de58,13c2c74,cd82315b,23b6819f,4981c6ef,f1a2ee00,af5efa4f,807f2b3b), +S(aa7da8ed,a97ac1e4,d2b2abe4,c8f727a2,5643c5ba,414ecf72,70a7bd65,612b1a53,83736a4,de5bae56,8d55de7d,6e2d4d6,eb5d9965,f08e08d6,dd6419e2,dc8d4057), +S(ee53a4e,1eefa289,af562927,9d58f02d,529663d0,8a290297,d7ea92c3,64f5d41c,aa0fbd01,727c227e,662fa63d,3d6a834,476e00e5,a96cdc97,d78c21f0,f3b2a83d), +S(8fc52dea,bd8b3e4c,fc6a2490,176b74f3,cfc55118,2d5134f7,1364a8c7,b083fdc4,1a8b2a23,d9119901,7e1de607,6ace873f,32bbb342,e93a9f82,ab1c3a29,18d603f5), +S(e0f5e5ca,6395d3d2,390eca9b,4bf50320,4c1062c6,82214c36,b1b0587c,cc0912c3,4eb1d022,b4971d9b,74244e8a,5565e021,b933b2f7,e8ea60d,fc259511,a7ee436f), +S(fd31a893,17476bc5,e278bac3,99eaaf6,1716586a,38410172,48170f7e,4d7821fe,190815b5,a2affc9b,1cb91237,783959ac,2058e75f,16cc2e7c,a825ab2f,8af9ba01), +S(1533bab4,eace4f70,74067a55,593498e5,59fa78ba,b74131bb,a2a97412,4e855be7,a04ff3b9,c6209ba3,69b19863,5cf8b4da,9b6a5a04,f90e29ec,9061a32d,f3ce6361), +S(8d549288,93390895,f1310e4d,a8b8ffd0,d9f8226a,b414180b,bb280370,93aa90df,fdafa930,f892b478,c7e6cbae,3f943615,ff08c2e5,64ff61c8,dcf19ddd,5c458081), +S(1b17a4c1,736fc761,f3091367,9ff22ae6,2ce76a6d,716e9b1b,c6cf28c7,cca59a03,9435ebc9,edb1a948,bc3493e3,e7434b81,cb671439,365843d8,819b4eb,786a191f), +S(3500c8cb,e37f659e,48e3b619,7007f250,9d964708,14c06977,a9861a89,eec11b52,8d5de084,b45912af,3ab8a8b1,47304a2c,45b839a6,41713563,f11dae45,2e5ed94e), +S(42def4ea,50df55dc,cdba6c04,ac2855d0,d706ef40,6ad56ded,50d49aac,3b41c049,9e354094,29b46cec,329d906c,9f9ae965,ac3adfac,251370f5,60b91550,4a7e114c), +S(b83c1c07,2087e92,11fc3302,fafb5be7,8fd4853f,9f8aecb9,5af83278,d488600,e51c2222,910c6d19,3baa56a3,63e330c6,390dcee2,c33ad00d,771fde6d,3bcdf973), +S(beb27e28,c59f5b87,d19b0274,51a51e58,f0d10402,e7343efc,d302437f,f9ea2004,ac188f43,c0d6b91,4525f6b3,5897d7e1,7a0543c2,3ccd8001,509f50d8,a95768de), +S(9408e5fc,877c5635,5a3339bd,3b9f7a8e,22a361b9,ee5e2f1a,a2b47eb4,cd665328,c51663b2,f9ad7dd9,6b120c25,2eb8493d,d68be9f4,ed4b688c,f5d2bde3,618658a2), +S(a4d0c5e2,9cf83c46,5a567288,e6c0573d,c7766450,d88ced27,cb036db,47ecc96f,ad00c513,63a3d265,1318ed9e,352be903,30febde9,7827d8ff,1b5b5bd3,281c0c38), +S(d38d0ec0,4d3819c9,665b42f6,24089402,e923a8f5,6e7567aa,bc12e5fe,c248722f,17e171c,5c6bbc7d,dd7caddb,652dfee8,720c319f,dad6b117,56596bd8,b554397a), +S(4fa66f5a,7c294bc2,a0fb7951,7e6310f3,217c2cc9,c712f6ad,c5042610,c29b7a26,8b79a582,b3d9acb5,5653642e,8b8c6f18,f17e0541,179c4d62,8a2976aa,3c760d1), +S(ec9def33,2bcc66f0,db0e6b3f,684fddc3,ff1a7ace,80c2adc8,82e4e5df,5ce77861,9ae3da13,563aface,d4988a5a,5b3a95b0,4b72be95,dd8ec898,f46fcb29,f43cae94), +S(90422949,23fc0bb2,3263ca1d,768919a9,846e8eed,4b595e56,2d5103b9,5a479795,7d8a7b46,e557e1c2,c621d49f,b8f382c3,1feccfbf,5cb8c755,1f02309e,bc5881d4), +S(9c926be9,68275386,95549bf,2cae2278,56410e3d,1e481cad,995c687b,e44bd1b1,56208afb,875c94cc,bcbb068f,f8ef6fe6,9615f1db,21c2b43b,59c8e80f,db5670e9), +S(8d7f3cd7,2a6912ed,f0fe9343,211cb3d4,20229f19,3e956ed6,9c4a45bf,c7cb84a7,a45a7fb5,d4e9c531,4defec11,ce95e054,1ef0575f,b6b7f299,72bbb008,c9c3c3c0), +S(a95eb316,bc91485d,9a220af0,a201378a,d0319bb3,473a0db6,e919b3b8,ff181952,41664555,3aea43ef,d7819025,acad34ec,6692f9b8,bf6a86a9,7de32f18,46de13cc), +S(8ffa8414,1e806ac3,df613a68,a8395111,93569368,6e2b11ef,a1d53493,34e8da55,5dc00c59,12cedd0d,4457e779,e82ba2ee,669f7fa5,75c42e1b,abc1aa7c,7cb1bb1d), +S(2f1645b9,7b58e33e,3dbaca4e,b4ee6fde,2245c,2c9bf124,46e262b3,434641fa,d3d0a603,6ded3010,319324f,34ae1e58,a6ac0b6b,9ea15b7c,3052b574,f0b2823d), +S(95232f86,d2d1482f,a6656256,3751c2a5,16e1a8a1,66988471,f6e0aa69,f1ecea2f,7f54837c,4633f938,c0ff4fba,e59b6e4d,1a7b336,83a1ec1e,fe1ece3b,a131662e), +S(676d2a29,50e66454,97e678da,68a5bb2b,126a8eeb,874fa8aa,ee3738a,cb7b3cc9,23fb14fb,674ca1bd,8ccb8248,48334f6d,4ba47d56,c7969cf1,fa3ab1d,78a22a2f), +S(91df7ef4,3ba5bf7a,11d8418,e553c5b6,d2031b89,c644d08d,88f1cec5,9d4007e8,e7b19092,f45b6d,7742d4e9,37d80d32,63ba2945,1fee1259,a13b5b1e,42072f7b), +S(1b64a5c3,e14d8fed,ac3c5eba,e6848e10,6c9db663,b18d48f2,b948be47,e8dc3b4f,55caac6b,18f294a5,f3dc9f44,ebb276f2,fbbb506c,1a28b0de,a55ad2d3,ac5eb8c7), +S(122f6415,3a73b8c1,f1c935a8,e99590ed,16ed9660,66816cb3,57049803,c7d7420b,f5bbe828,9693d573,7016fd9e,59cabef7,5eb7fae6,ec9614c5,3c47736a,f3276855), +S(745ed438,63d669e4,397bf391,14af880,f87334cd,62897aea,634b5c7e,cc6a074a,c5cb92e5,61812f7b,65930310,88b45373,b864b51c,18326532,b2eca5ac,8608f155), +S(4724facb,e60d62dc,da536967,a4650a19,1e582045,ea209834,f1989d0c,db8baad5,ad70a8b,ec1372b7,5e3aba6f,8c031d5b,ba540395,b610fbbd,7d5b6ad7,4e32a3b7), +S(a31bdf87,40d7a1c4,88f23ae5,9b54c976,56887201,6c307531,51ed5062,dd7613a8,e77b2633,af3e9b42,a2a05b45,a0f5c9ec,28f72387,2cb5bacb,ee5a8360,2aa282a5), +S(990e8453,81efaed1,8c3fda39,7d4ba832,d509851b,8503891c,c0ea0ae3,4f5f1f7a,339aef51,e4d4ff8e,49955166,4408c312,b943df2f,fa62becf,51cac7b7,eda7d8a4), +S(bfcc3e62,cfc9808f,bdceaa55,f75331b6,c9b1528d,455c33fc,9690d84a,d89f68f1,7b07149b,cf648a16,b3be662a,d203837d,fe5a2357,1154e65a,78841ae7,a906a7c1), +S(284b543b,5ad3aa4e,5a4ab274,9acf59d0,4045bbdc,1ad204af,3a7e841b,330c7ac8,43d50b60,d23281ff,1ce15241,80c05e53,e5fb5bc4,a4e0ead9,19a2add5,f55b10d2), +S(e4c147cf,beae087f,5c9aa83b,31514ffc,5734feba,cc743203,7a7a9931,4101bc7c,72ba3a91,3a2fa186,484bf856,ea93a725,5f6e3b1f,d5bb86e2,58e45e43,52073787), +S(54cbe831,a201fa88,a3e7ca1,aa409449,509269a9,1b229892,9e9f9dba,a7e8a8c7,60705c7d,ff74d8eb,1f85b9d1,d9efcc58,fe463e04,b19f56dc,a724dfbb,630661c8), +S(c8dc9e83,d4e4f250,5e8c16f0,a5e8de3d,1ea3711b,8a927a63,baa9bb33,6ff302c0,62211dac,15b97856,2dd71543,b63edca2,4868ef5c,6bc7e547,9fe81da2,261f6150), +S(4bdbd22d,5cb98e31,ddcd1e76,fb69ae02,1915be35,5fa326e8,506c38d7,3c93dd8b,9401c173,3bdd7728,fae5ddce,d708119f,b0cfdd41,2b3fe599,e75b5a8b,b84fbc55), +S(ce988332,84a3fbb4,31b716cb,3b6530ba,bb41785b,c7f0564a,8691289d,9d35e689,2d6d9b1a,7711c5a3,2ded418f,9b52c134,e822589a,789c2b33,648324be,508f4f14), +S(2815b2a6,ab505e2d,ad759c85,6aebc3e6,133826c6,d3939a6e,8795308,5adb6bcf,2e6764f1,f90c7ce,a03c5d8,a1465d26,fb2cd430,edf9f4ec,13ea71e0,51558b7d), +S(65380aca,14b90a7f,e6c6452c,c3d811ee,88128fcf,fa009d7c,1afb3195,8c3bd1cc,a73d691b,cde27cfb,dfe4180,e6a8d2d8,62615b1d,59ad3487,dc914045,39549ee6), +S(7bf3a1ed,4e7e876a,1404493b,7ba01911,b5707f09,f18694f0,fdc35e9c,27f1b89f,b6dfdc2e,e827967d,1d1218d8,975cea61,9a740521,a0e0b702,7df1ffff,dfe45572), +S(5f635ad5,952b3f2b,e341479d,239f4ed8,8c33ed63,87f62c4,40a02665,4e469aa1,a49b5262,32361560,c2105db9,3b500fa5,bfe3ef99,7efb826d,90781ad0,143fc0c1), +S(4a212245,8bc099fa,7792d0bc,a3d1d163,58fc391a,82dc7f47,2a457268,1be9ff8b,fbeb9575,6649a3af,923b28d6,788c8662,9b488166,23349b93,755d04ff,bdbccd97), +S(1b56d138,e71aa703,e2566a6a,6f0a29fc,e7a7b999,2c454248,5ab29c6c,eafc86d8,db7b41e9,217fd201,4f4e6ad7,818dfcce,31823069,d1e87ab,85bb5ccc,c870d476), +S(cf9dee0,3d9c1724,24ebc37a,1da32a19,bec78003,29def8e1,b7c44b5b,59e880b,20ce898c,1b9dbef4,f47c5b6f,be39a8cb,91bd244,b0df0bcf,94c01616,24ae24c3), +S(89458ec9,1bcac5d6,ba51b7dd,d32119c,eee5f535,5e368e22,3a35b9ed,b8bce2fc,33ebef56,190a0820,9e508e1f,6dd57a37,141cc7b7,ae8a3583,41da1ae7,24b40f0e), +S(bc1637f8,39b45eb7,66e7ede4,af989ce2,20ec795e,d8454ead,6053a392,18c6cf13,e64e7128,240d9c9b,4018c56a,bd71e9ef,30d7cd1,8a036ff6,13e4dc52,13e88b71), +S(212c6c8c,3e2d406d,4fab7bf1,4f7dee3b,a7820821,ecee711c,f63fa0cd,49341157,2c2caa21,7ae6176f,242ac6a,c951b628,5daa7dc8,ef35e996,12b7df6a,b7966006), +S(8ec5f69a,a77e4faa,a70d129b,685f996e,36d4591a,9f03a047,d853f81c,483a371a,69eb18df,9bc54f0,804f937e,4c88eeb3,a1e089fc,6fde0ddf,e37e2de7,892b8b1c), +S(d77dfe3e,6370e677,bc0442c4,4d71e7fb,fcf1b7a0,5a39831f,6c02daea,70eef37c,e5582098,dcc957cb,6308e51a,817c2764,1c34a3ae,4a1e931c,9e741c29,241df4a3), +S(95a98fb8,178ab7b0,45931f72,f9d3411c,3d6c9bfc,47b9db77,11dba796,6600d1f4,789034c9,fa371e65,e47e936d,d5be1c62,d660c12f,d7a0164d,1507b4b1,4d5a5d58), +S(dfb9170,5c2eda68,ebfe7b2a,f2c76eb0,c65fe431,d3a893d2,b202b004,bf532063,2842d35d,73985521,4dbf015a,a64fc5d4,5c763a0c,81be6302,ab16eb45,64e1c020), +S(ae011375,773a319c,12a49e8a,24f4a84a,70817591,d739c604,e76314ee,2466136a,fba7f0ee,758357ed,f296ec2b,b4d0f9e,6c38e29e,95daa163,f75c82ac,48988ba1), +S(e906d6fc,6930a06d,846d4804,f2affda5,955c0718,e920aa47,724a4903,d644d4d,abcddd9,fa93df1a,6c4aff95,a7ff30e0,8768bc94,5baff83f,1278dcc6,fb797ac), +S(39d6a839,e4ec9f30,7a4b150c,9c20f918,5626c93a,1a077cf1,b4259d9b,cac3eb5,2b0173df,699d9213,989b16bf,a17b0996,18eac71,b6f21611,e20cad8c,f9609c2a), +S(11541976,d8c7da9d,b9864344,a2a3ecea,499f538b,224e74c1,546dbb82,a343c308,692038e0,d63da9a8,c4c7b9b1,fc3384d7,d03e2dd9,156f90d7,68d31f64,eb46231b), +S(b8edf6b7,8b0ec547,9ee981dd,e7d8052f,7d613d32,a9677bf4,623c6695,515af54e,4e391006,443f4578,7951cf57,d47100de,7982d0df,cedf7c3,36193ed7,a7f986b), +S(dd4f1c04,c7f106f6,2d8f49b3,f96b919e,774cec1d,e470e670,1f72bbd3,2236d3f0,bb46966b,fa105ade,17aba7ee,a2c11e02,ace8524,1e3da1c2,4d30ad99,dc695175), +S(794d4cc7,aee8f9da,ac4ddc7a,bb4278ea,d8de11cc,c4dad583,45c3edb5,b9c7b2b4,d0024919,35a5f7ac,6ec9a6f6,85aa16e7,61329642,c002bb59,a9a9e135,63ef3688), +S(90dec6c9,97e0906a,fe63cf90,2b6a5a6b,ead0653a,6c9a8337,154eca0a,7e1fda8,3511f4a,49540228,3956e249,e9caa7c6,222c79cf,d91fcad5,c35b3737,931308bf), +S(dbe539ca,27d132f2,e602df51,6582c3a,9bda3a82,ce3b52d6,10f4bc45,17b52119,9f52a5dc,417ffa9d,2ccdf666,63ff60,8412460b,15adde93,a11ceb9d,4f859f37), +S(a3fb9a06,7f8a9364,87bd6b2f,eea9e072,6902c046,5bd3a9fb,5afb9cf2,8af34028,b3de3a34,76028531,192d614f,c720e0ee,e7765fa0,14dfe4a0,ce0ffb9,b32f123b), +S(47c00044,c66a8c7f,f6242613,17cc9950,438544f7,31398212,bfdbbfae,d2e34ed4,215f4709,e2bfec21,6990ddd4,d37a0c46,b2cb44f9,26d3523c,ea0a8b2d,7f949015), +S(b59b3f1c,cbb0cbdc,4e430788,f934f090,aa0e1047,24d8d1e8,b7329e4e,c1d6092a,f96cdb74,a7ece8e3,a9f631cf,7a740a2e,fc9c9020,8ee0a91f,42168990,d9a3cee0), +S(c4efffa5,92a27b03,a05686e5,8ce4cbe,d4768e15,64d30450,655b6d0f,5dc5911f,7f095e1a,9108c3fa,a1b1043a,ce870f98,264916b6,f8643370,4d36da78,deb9d826), +S(df9f6d4f,e169d748,5c09f5ad,a2eb46b,be5bb378,919291d9,e3f60ac3,2644b6cc,7566af91,e7c37fdd,72b68418,e6ed1929,c17517bb,bc8666f0,d5e28eff,4d50ba54), +S(bf3d3814,11130a19,23ae0b6d,f333c61,8ea598b4,1277a568,85582688,6bf8deb9,861edd8d,276fe3c4,cb7496d2,9d313697,77df75a,d8c40a85,19ea1415,9ebf533d), +S(8b822d8f,640dbd04,d2a35aad,e4309992,3133fb0,c97073d3,b23f767d,f3468247,71db728e,40b1eb39,7cb69211,1ad24e63,79727a77,bb028db0,51ef9b67,f31d036f), +S(4a0e24e8,6d588f32,7d41addd,c4659b36,d6406a28,91ace143,d24d98cc,cfea28b6,3c79f61e,71c3c9db,11c97734,da9d9d29,7b141060,589c029f,6eb888cf,7cb6f04), +S(3df98e9e,c1bfd244,86c6e95d,8ab19c93,c89751d7,d408ae98,44c90c2f,8bee9685,fb6bd949,afc7c8d0,a16e2c45,4869cc4e,899e6b6d,701eee28,7434439,fc61074e), +S(1196aba0,2bed29e5,2ab28d7b,74301095,ca68fd6b,1e2d0893,1e3145fd,3dd1047b,d8dfd4a4,781ef486,8513bfae,d0b0ce98,5d80f6a4,556da69c,aea24c1c,7e85b27f), +S(5746e37f,709a62f,af3a720f,2c7d5ca6,5ec8a3fd,3e223b67,b839dea,60cc1505,eec14b2e,76e888a7,538f0fe1,32268576,4f91d70a,19d9e885,168af68d,5b9678b2), +S(3c807748,606480e0,9266fd22,69b9c7aa,9a2f87e9,58d3264e,77cf2140,e0f2dcef,48b70aa7,6f86e7a5,c02c1997,fa029d78,94398324,82d3396d,2283dac7,dbe23c00), +S(52885fb1,f40dad6b,7c0f7f0e,3e9e230f,b45688f1,a9f3adbe,710bbff6,d56885b0,372ba4ff,192bc456,56240432,db828847,98cc846,e810c99a,8e33476e,1a674663), +S(60fe0096,4fb56044,c506b551,3504a800,7c2534ff,52f53f54,31a479fb,166616da,75ae6371,b05b93a2,499563d9,887f69ee,f9532a1c,6695e6de,966f0b73,90100ee8), +S(55439653,f8f659fa,9f2ad854,2b1beee6,6cdf34e,d3e464e8,45ca34ac,70d88434,c7883ce8,984db19f,a1866e82,f7cb0623,e6de0446,a8ad5fa5,3dcc775e,d2a9f871), +S(18ea4c5d,24fd7a5e,9463b109,20760dc7,fb4ae56f,db00f0d1,805a9e19,c02f8687,3e19b983,93a440ee,99fb1a25,d7283f10,cdcf3b7b,8b063ee,5eb05c56,2edc9251), +S(8bfd7102,9c7a5747,8eaaa0de,1417ebcd,16731b31,935b7190,d536089d,56dece82,b8fdf97b,1a4d9d35,f32504a7,2a03be23,e71fa005,48cbe33b,8a85060a,21daaf5f), +S(e4fcbc12,22987f5a,f97c0ae9,be88dcf0,23ee2366,4a2f3b98,d19f3687,b82d89a0,7539ffb,33cfabf8,582ec993,8c034688,f8aea8c,7fb6f73,ae09ce9a,e63b9da6), +S(bb20ed68,c9a83a86,99a42cf3,9a51af62,534da50,36bd8cf2,5ef7f7ff,1f08ef85,48d64269,af2c39dd,d6c2d703,fd7832d7,c409d76f,8a8ac99b,d977e7ba,760e7428), +S(2d852cde,fe404dd0,835c781a,11a23db,bce9b015,637c4a82,e0ae009b,aa2ee8a4,d69c9056,66184051,f433e99,ce03c3fb,97107229,d509cb69,59675300,8951f4f5), +S(37f5037,beda50f6,c485b78c,ae4843d2,cbbc50bd,c3588c34,54a09dd4,4b5504d2,d2ec7671,9eb38781,d2954fab,34f475c2,2c297238,70bf7ae1,1124231,2315d8d8), +S(7a5fc0f1,5747caef,61882134,40cafb3e,e8cd6c25,9cdefac3,60c4a9d3,6c96397f,bdba60e9,bb96fbfc,e1fdc22f,d4282913,7c717a1d,f907d441,94fbe55c,bdcc7d73), +S(d50843a7,4602c5ee,298e9ea1,6ecc75de,c0bc2b0d,150546e1,4605ef8e,c0d33eb6,f95baa7,aca33535,b559aad8,ebb18df4,eec43134,6ccbdc72,a3551b53,9797b570), +S(e5141e1b,a2a9e653,5baa4cc3,71f143e4,c4e3be94,4b81ad88,4a1cbd15,1052ae67,afd5328a,75f3361d,ce8b7e84,1e091835,2ef1f4b1,986dcafd,40ac6aa1,12a65838), +S(892a2bfa,f1869c35,34b50649,f4e3bca4,2fb6845b,f831471b,4b6c80c4,650ab82c,ef6c3f52,6deeba94,563afd1,5b9246c9,b397ac2d,1ac38a79,c7f24dc,1706a402), +S(7a8b233b,94e81662,1ff28218,c60e56b8,15e7f48,9bf401c0,182f05cd,57e1aca1,de6fd62d,713590b,f0e81723,a25540ee,3a98b68,68d4bfa3,d0b64b60,1bd02202), +S(66c7766,ec95259b,ca729173,a721d3c5,a1fef897,6ea25f9e,4c5ef3bf,93a659f1,23d66628,1cdd28e1,18cea2bd,bb8bd13e,af6fe7eb,d282e5b6,858656b2,31a8463f), +S(14c8b905,9c41ba45,7c8ef52,c78bbc43,6a9dbe69,4e8ca807,1b538e0c,eff68d64,e4c77c72,5c9c5cb8,2cb26618,7fd77fcc,cff42520,5428c0b,b7a5145c,fef3ea12), +S(ef36e454,185b6147,9e0c57e5,92ac7b06,d59a4d21,6d0f4794,15fa728a,181e4024,a2b298d0,abdf1d93,7e6a15c9,4a77a72d,4cbab1b7,5b27ff46,c217d1de,b47bb006), +S(6848b754,920b0919,b96c7c54,5329951,ac7f71,7cdfcd13,9923d4e9,d4fc3ab9,a9e4722a,59c84597,a6f9eb15,50230182,af76f6e,eb8f9b80,c4b14d7,2f07623), +S(a8f4f96f,c417bf04,15116fc3,d223494e,4988e32,855e7cb3,c52f3c77,382227ef,3f5ce509,f0aa36ea,c23603e9,b08e08db,4a9df67a,bd1735ea,1f3cad02,8f63bb8b), +S(372bce7,9b26b7d6,6026375a,1d8f7858,4770d17f,e23a53f4,3d84b577,4e1d540f,ea6ea296,59226bfe,cca23e38,f341dab4,a3750d10,c9e9d662,bdf90b95,c68ff345), +S(ede230c,fa48b0b8,affa246c,af849946,3c89b87b,148259a6,bb319895,c5d1decb,76eee3c6,85fbb3c0,ed86e7ec,9bea6189,56ae98e4,d1c7a17,e9f7d796,eb8b1540), +S(1fe48c38,964fbf0,438f3b,95d15871,d8037e8,a80bcef8,9cf19a54,370457cb,33c60da0,ffed0f,392758f3,76720d71,42a66034,ecfb83ce,ecb05bc3,44fa9fcf), +S(3ef6a0ce,d6b74a75,7da5e17e,cc0b215d,9cacd353,44c90c07,cb7b86e5,2066d500,a361d55e,82a75506,ddea417e,5f3ac744,9642305b,92a9bd18,b8fd2fc9,b3e0bf77), +S(165c9a99,4f26f8ac,528caadf,57d77d82,b74d3f79,1d2f18a4,e5947aba,7e25ff56,3016f139,a0e0c5f5,abdc57c0,86489330,f3b83dea,46396fb9,d1052753,785da130), +S(e07ff9ac,650d90bf,745bb6e0,13ae6587,e96feb6c,e1c003b,c0c44a6,6ec415e0,8bccd0e8,77dec06,e4aee5d1,76313cfe,de90e6a2,8e98e618,70e31b8d,8da3540b), +S(d1133e3,62cb9ea8,4d4da51e,763d1b23,ee018984,cbb2302f,c5789278,e60cd0fb,b66e8a8c,3f41461b,8d1358c2,5761456c,b5c086eb,b67a0ba2,b02166ac,9b0b2d65), +S(fe40c8f0,41c5f50f,789b4c2,275892a4,547da456,ed1a7558,8529ecee,6810fba6,a27031bd,d4290077,ad0e50c7,787a222c,3c89b27b,13159117,eea61c29,f126831d), +S(83b7184c,2b76a015,b80c1269,a78272d4,374a00d,340500ea,ea5df081,18ab986b,41ca7c04,774653c3,87782499,ae88e219,a16e53f8,1a87b1f8,768933ca,8315df89), +S(7c230724,b72fe375,bac73f94,5df4e542,c6789c1d,ebaec636,730f07a3,6c3a0648,a173576e,8c3f56ba,543fdbbd,c650d004,3fcda4b4,4684a6cf,666b7423,9cee0152), +S(652207a8,aeb1c301,932db5d3,854efde6,da5c9912,ca6833a9,79499ba,8549dc7d,14ff67f7,d0d82988,b0b947a9,b8ff8914,8bd0727b,f72e9ba6,18028c42,792aa3c9), +S(13422e69,12a1b8d6,db99e17b,7606f3e3,b6d5cd11,5f47d50d,587e131d,477f983a,f72d5395,a5b1badd,88074638,a079797c,134d7415,a7d4be7f,23b12b43,f1f2b1b2), +S(3605aa35,29438d1,90c78de1,7223c468,ef36b28f,bf7fa6a9,d809b113,7e251481,9de174d6,43288a16,3dbaa04d,f4cd8214,f3e68c8b,13b71ff3,215447f5,2522b8ed), +S(fabe9cb9,d1e80ace,f13e49c0,d9cf2e95,12091e07,a9b0ee68,144d92aa,8a3f5f7b,7c05d1d2,7144b868,33c1dddc,8374d4e4,16df20d9,e7111415,8203ffe3,8f662823), +S(df84793b,e4c7a574,9c5cdb3,10ed4e96,c05298e3,d7c7187d,93018dce,ac6d75e2,62d04b5c,1cb578c3,8784db96,8fb8786d,59c92183,c226df41,d164fffa,c076fe2d), +S(90585ca3,730b76,78a731ad,ac186574,911212ab,58d826d9,95499433,5cffbdac,85bcac15,d41303c7,bb2b2f87,eb3d5101,eb35818,815711f4,fe72d243,50f5f6e6), +S(89e17bb8,56178598,74821db2,28956cd3,8e8cc6ef,568ff68,5d5c2e22,5cadd959,e759f802,faf4feb7,4ddc888f,38b8faa,2661c56a,367da1c0,781ceeb1,7b30e37e), +S(1d43bd3,df9f1f25,c061538b,6d4fa0f,dc6b3be1,c7443616,51420d09,7aa81e9,ddc8f865,d85daeee,6faedd8c,172568fd,d290dc12,fd41925f,868fa03,ae8176c1), +S(6899bf86,10d6f8f4,f2b50e47,1eb5bf9,77924580,3b3a8636,b161879d,35061e5,c4c472ec,37bf52b0,3de23bcf,188dafa1,5aec0c9b,4f023e9,b54a8d9b,2940a66f), +S(b42ff8f6,6ea45365,485cf5af,ad243cf2,f6d63e0e,d4a0386e,475dfc99,70b9ab65,46d2ea18,495a980e,db65262f,efec578c,ed829315,15ac74bc,83d8d385,d739b2ae), +S(cc1d2622,9e9cacc7,f84bb974,e06e9dd6,62fa261a,a90e271c,332c289,1511dbd9,206e7e03,b8c33605,ed870f52,2e31aeb8,1b9f8a70,86732a49,6761f00a,bf0396b8), +S(21f031ea,16cd5c2,3c5a809,3a93656e,950feed9,64c8e2,debc0a98,64c3b30a,2d038c76,f07d43e7,f70d289a,32115679,232bb02d,7f237f20,82f085a4,2031f61d), +S(8bd83272,4e955741,3a6f5fe2,b5d0cd06,ca80a3f6,eb8f6449,516274f8,f98c689,71559502,b2442397,62319105,3b440a7f,fcff2a76,bb4e9552,37dacf33,b26d19e), +S(74c61963,edd7e01a,5ecbc8a9,76a1f24a,fad2b1db,1e632edd,6ebbe3c5,49d2af07,9247fefa,fd6ae328,f3cb918f,3b6ec823,4c0320c,5a317a54,19fa17d1,bcaf9f99), +S(1d7e54a8,597a36fa,4a32a46f,b40fbafa,dfa50c42,c4dc2228,b30c53a4,17b38f24,cce12594,2f1fea05,1cee6589,c26ef75d,f88d7242,bf3460cb,7bac2566,498e8ce5), +S(c788085a,893e3e58,bdad60f5,a177601d,5af89805,47bb9e1,2bdd2294,a850bdc4,44292afc,2ffbfcb0,5ac838b1,224bfa98,fa09f219,b81611d2,d83c9239,4165b415), +S(d87e2357,7984ef30,a3243b79,f0a53f84,93b38e4d,6b182c47,d1e6f48e,3d38db8b,b42950a9,16c616aa,1fbecbdb,70868cf,28106872,33b3b549,388c2255,a157a50f), +S(5d3ead44,592168fe,d898a5e0,bc7c0aa,ef926d4c,6f06698a,e5274aa9,90307ef0,ccc1e0ba,51eded41,714e8039,4a626a20,1ad5b751,5e6d8ad6,25895be5,8289f1f9), +S(ac063972,75d60207,fdb67802,5d86424d,d47b7fb4,8d20402f,bc683c2,b7e9e63a,b02c5027,e2488ee2,4c53365c,d9101fb9,5bcd0c45,85e25738,36156286,fcff1c89), +S(815a5ad4,fd1e59c0,56bfeeeb,b50e5728,18a6412a,2eef8d42,7e27c871,e41fcca5,4f358e87,5c7b6e0f,ffaa3026,205c07b,4a438394,276ae929,e24ff4f0,307e956f), +S(10902a4c,a24b6807,ba67d735,3fc9582b,ebfbe13f,fadf8146,e40016b1,40956db0,bbfdd872,793fa436,5263d277,f2ae1512,b5f349c7,270561b5,4c151824,6b430743), +S(858aa1f0,dbae0cde,a7640775,44f99261,af16469c,602f31da,3345671b,93758d48,ff63509d,d56ff954,3cb112d,941fe16b,b5fef4bf,96b8923a,c0e3d3ce,6f0e4cad), +S(1be90c71,7032671e,3cffce34,1a6c507,e5564576,ebdfae2f,bb28a20d,ccbbd6de,69edc8d2,20bec442,2cc47888,22eea780,3d4a01d6,1f8da9cd,4f8533f4,146c16cd), +S(6149cd0c,162f1ae9,163751a6,e967422b,8a80816d,deaab38,e73237c0,cca923f0,9dce938f,fd20eaf,b518752a,9cafb862,8416e3e3,8ba723fa,12442844,1bc7a477), +S(20696c11,f43db49b,d891505d,cffd36a8,a0fd20ff,1c56896c,51591ff1,421680bd,397ba456,6566244b,a186055,bbbabac1,620d1b9f,9d2d06c4,44069ba2,22041d79), +S(caefe4b7,91049900,5f6247dc,f1e49aed,22493a96,933ec702,c93f83b3,455fd6c8,6191fd17,4ff0887e,886086f8,c8f9cf8,5d3d3e03,30f436c5,50ca153f,cc1af003), +S(849d894b,2720850b,bcc0bd08,678205e7,1ce2b041,40fd138f,e16709dd,f3c9981e,8909d10f,494af391,a3ae9000,7af2a292,8f066ff3,22199e64,e3416799,a25c43f3), +S(d27b2fb6,e38544f9,eff19084,cc901d70,3356937e,292c1989,856bdce1,f6a22364,8c296bb4,a89bf08e,2ecd87b5,b49db335,b6e2faf1,b1b57146,3264993,77e56175), +S(37e04b68,f476235a,728bbc12,e3572929,97243538,e37bc2a6,bdf6b7,e8ab4d63,ce346516,383c0573,9de7a2cd,c4b0c0ec,9c3f7bd5,c3e8c27,271cb9e6,7ebdba4d), +S(b3c6c10c,5eefc0c8,832d9c99,183417fa,9351868e,42952b96,2d623305,9a1a3eea,d7ad6ba,968091d,fa8c68fc,49aff425,44f35d39,a75824dd,a79c5b1b,602ed3ca), +S(5bf180e6,763045ba,1453a353,49711a67,9175a21f,f2b7b381,8c8e5d8d,4927f107,72ed6000,6cbe16df,48d037cf,237cdbb7,93705ff7,2bf38c73,e6a87f1c,46ed40e9), +S(82e13ea2,3cbf23,ed3e2f47,922b08f5,9be10fe1,48de26e1,168b0784,45705ec4,288ae681,decf904c,d490b6a4,d5a3e5a,75bee593,ddfcce76,693ca57b,f39c1805), +S(4ac56d72,b9a5587b,dbea0ca2,674d343b,15adada6,f30d7a3b,fa481f7f,69af9467,5db2d7a3,3d42f04f,c75ee27d,7a7fe9d6,3eadc5fc,ce770e3,78d09ff2,eb62d78e), +S(bcddc00a,4fc9976b,6795da19,44f181cf,6bbfc775,cf4c0212,eb419580,82eb0e4c,30eed6ad,bbd149b7,49053931,65941084,470f0338,396a6c57,9fda211d,358a48b2), +S(9331e909,bf2663b3,8ef46e21,2293e63e,c7c1559b,853c3095,cd749971,79f116db,8ccef168,4504893d,30418aa,343b3f9,3fb0db2d,895359ef,f1b78d6c,1f074fe4), +S(12df2aa,c307209a,23b543e0,7e220557,3bbd8cb9,e341fdd4,6326ecae,916c329c,48d2da1b,dc2a251f,a861339c,7b92bea5,cfaaf0b2,3f4bf625,7493df8b,228fc8c4), +S(987e316f,f09ad376,eddad996,98228fab,90573f6d,60f13772,e55429bc,e77a91c2,82484e05,45aa13ae,23007c0b,7d6e0d0a,7b8ee542,bc50ed28,55ffc819,aac4cccf), +S(7be67dd0,e377aaa8,f13899d9,3ee2e9f1,623d5efa,ece91690,82c9dde9,ac7905a3,ba82932,93f21a43,23ff368a,86c8acb9,63328f81,5f003f5b,604082b2,4d4dc3e9), +S(133110e3,5e53940e,928883e5,fe5150ab,303af955,7450d37f,20dff5db,c8e2030b,54ea08ae,730c8117,ff1abf61,e89fa960,2e434dc6,c43c6a35,3a45d535,69f7bf96), +S(a000b820,53c27e06,3b6ac0d6,2cc0bf94,449ac467,800ebf8d,5e6bfe91,bab6cb36,af600aea,4261cc05,48e7e30d,f9ba50e3,e4ca8708,aa276bf2,ea7e384c,f3e3880c), +S(df50b710,59dd653a,f1f2b8d8,f39e12fa,134f1020,4e794ba7,9a734a39,eceb2217,17b8416c,51c8d01e,7739645f,eb5344c6,2c5b05b8,d27aa83b,d02def84,c128c04d), +S(b3b6ea83,cc9ee99,d7518cf7,94fcf12e,5f2d9845,b165330a,1e55c4a9,4a601b45,7e9aaee5,3dba428c,b042c0b8,87701d57,bec9635b,f54bfb64,13742d7f,3a7576fe), +S(7c81a6e7,36ff8ba1,82e516eb,b47be4fc,98e926f,bde294de,e371f068,687953c0,9d8d9b8f,a5b608eb,46bb5fa9,e162ff4f,47e2a8f1,86f41847,1c2433b2,462aec03), +S(e370435a,c9b0d2f,175786d8,6e2bfef4,ef7bdbab,3048fdc6,abab0fa6,ceee0cfa,586bc07b,a05088bc,ceafe00a,dcceb00a,4c1a3704,2f43f011,218ea8ca,7df4f04c), +S(999bc950,1d0b31e8,5175b27,17055c41,e5711b91,fad9af7f,82018e4a,a8f092d5,592cb475,2cd85ed,23d10139,55118027,7f6b5065,9b374ec5,55cf8f08,bed57ccd), +S(2241da6d,60fa77b2,f844f4e0,6972c230,1305d1d5,5d1a1453,16436693,232a622d,1b3ca0b0,8ddfe046,b916c1c3,7e7a29ad,9d235e6f,4f9aa72a,9676d62,e3770035), +S(d4e6cce1,884a77e2,dcfb08ff,6e4717ff,ec85343b,fa2b3415,1e290c2b,e9560171,3064c1dc,9eb6fbff,baac5bcb,ba14ed43,523db1ef,8fbbeb38,3e57dc9d,945e539d), +S(d2baeaff,eb5a040b,a7627374,ebf692ee,65316c6f,b30c03a7,7a6c7882,f98d0ef2,7f5b6e13,d91cd74e,6841c97e,32ad8e4a,3d8c572,1a206b30,e89c6f19,43313f2d), +S(150db822,7f60d338,73602400,27e859b8,7e4cc5b7,749d8d16,6ec3ac03,cba95331,12938598,70c09913,a855559b,2544d3b3,3de7a12e,da4aeedb,72b44568,7f6ab9e9), +S(bd607750,1e8d489c,aa24a424,8baa60,e0a86ef8,f9f6ed17,4537d826,c3e90fbe,9617baa4,c6ee1d2a,6231b3aa,5d145b30,6e0052ea,d1a0cbf5,1f74ce5d,7461b54), +S(ba04c85e,7755ff09,97b5c7a6,552e79e7,455b85ce,3498236b,6452958a,d01e04b8,e82629e6,1513be7,719c2e52,ddb4e8e4,3530240f,d4e3f199,b1738596,9498321c), +S(be1c6207,4ee93f45,6dd94b72,afdd295b,f751df9d,a77ebbe4,8e5de0a6,a6f9ba8a,3a1fdd34,72474e68,83130c08,b1e99e51,5c3ad11b,7c321b52,fce159a7,127599d9), +S(21c4ee54,bf48268c,44996b18,aa38a92c,7553eac1,2f4bff57,e89fd389,c9ebb1d4,7a0cf9a6,c45cd57,d0a1aee,3010ed52,220194cb,ea43715e,a4252272,71064b6b), +S(2ff1ff0a,14c965f4,9ee43f0d,64ecb94a,344d36d3,d90616d3,2b208024,4729d291,47d74f0e,8c9c7dd7,580ae2eb,3bf07a4f,320c80a1,13a5eb73,cfaaf7ca,e38e9803), +S(6d5ba86e,be2f0de2,eee9d917,aa69bf71,9ee9e93c,1ce7cf74,a993435e,480b5b39,9c19c406,1d3fb92a,4dc26c8c,26bbbab8,5b4e9acd,950a7ec6,824aa915,c1f9cd66), +S(49316bcf,122ac309,2ece7f07,c1449a7e,db2bab4c,29c7243c,41dff1d0,feea6aae,3fe2db4c,26ebc1df,66a03c16,deeb4f5b,4a3a32fb,2c2db184,7dd93738,a43e68b5), +S(329b8fda,fed0ee52,b86a0963,54c2141f,c22734d9,fa8e25c1,4376d539,72f123f6,35365b1b,8ca97c37,1f3c0d34,599d114f,ee3b67c0,fa4973ca,b0aee621,5f07de1a), +S(c74140b4,8c998c17,e7895174,b461c733,e687f71a,861d5687,9535f11e,31ecf62a,4a648bd1,5ce47fd7,b9a8382,7842281f,59a6e0ac,6dd049d5,c05748cb,ec607556), +S(92f5177e,cddc78ba,37a947bf,c72d4bb4,531ea7fb,1e7c103,d312fc2f,a8e4cbc3,2d348b69,cdf37794,383739d,3af49d0f,7fd9b0b8,1b5b918,9d3cb49c,ecd25d0), +S(31ca4598,daec4eef,975b3a18,b14420fa,48634ed9,ceb31b64,faea0fb5,32673490,574e1a82,b029e852,6e12a242,a21179e3,d7835a62,384da226,c7b9c879,43ef506b), +S(f7a66fa1,103f1fde,1392d998,fd5d8c2d,9d4804c2,999df8a0,c3d6780,ea915b36,94b115b6,897e00bb,166d01e6,e0b0e3dd,7399e7a1,98985a00,f06312bf,e31ce81d), +S(39cbdcb5,8ea994fe,f678e688,c01fc74,a643b907,b7d00c59,98d609c2,898274d2,5c256316,3717961f,3dcf176,73183034,9d881d7f,11544246,1a42a9b2,8b524e8f), +S(56fe8710,6d493892,4750fedf,8cfd9597,766699b3,ef9efaf1,26fb0441,d01becff,6b16649,80e3bec2,9ec107a3,f02a0831,5ff24460,b0b0e29f,208610c4,a3ba722), +S(e9ed0bf2,81770721,b3132049,e48ec3c8,9b33e62d,6eb3f1cc,b50ce7c1,6cce6741,ed06f8a7,d93913d0,fbdbd2f3,ff5448c8,f004f690,340b84bf,ded66508,19c356ea), +S(a3e250a,e5f568f1,fdb0d60a,8856aabc,a3d35a9c,4f23c07f,587646cb,41b9d29,3d2c6652,31f48e61,a6c4b571,6ba8a07e,5c8374d9,2d0ca6f4,970aef59,3f2a78f6), +S(bc08e135,216208eb,8bed1164,3deefd2b,a89959e1,20d3aefb,4f02976c,ebea4fd1,bd59151a,ecf185d,a0da79e3,817c9b67,605b46e6,41b733eb,a70180e0,47bbc4ae), +S(1008a624,ad6badc,60b3457e,702ab324,6ccd3f90,aa64d741,69539116,64ce56f1,de2d4c03,69f0faa3,5e039afc,1a650137,cb299fdf,8840bdc5,219bc9f7,b94c7219), +S(a298705b,a7c0a8a4,7b68b674,c63d9d7a,fac19b56,eba7f866,59cace5d,fdbb4b05,7b20b074,33988789,da3b41d9,5a9f0c71,f2965ff0,16714652,926f9e32,287f703e), +S(325e58ea,980fea75,a79f4254,60afb0cb,8f68bed0,71857e89,e4e7a88e,34b5cfcd,7034e0d4,ca1844fc,47d4c813,736bcfbd,7cf0c693,cbdc1ba7,b0d29019,44212c16), +S(22d51a7e,22bc439f,9179932a,254bcdb8,eb5bd7b1,515645e0,2340cb6e,8b94cffe,1da471e6,1c8ef75b,10525d6,132a14af,9096a429,e277022a,d667e204,91a786ff), +S(490cd510,a010e368,b3e4f0e4,266bd0c9,c04e3434,6d039f0,764f5108,aa31d6f2,2ee7815f,9ec437f9,3dc69f84,b0c91231,326c0159,4cc492f0,1f9b8d88,7fc022bf), +S(f8896cfb,f2d14e5d,ab1f3c2c,1e669cae,433a8a9e,42c7e68b,206a0d88,b4aee3ec,a84aa805,677a7c6,12e7930f,b91293ec,afee667d,2b033019,ffae8d8c,bb7281da), +S(9be847b8,3ff9d27,e74db522,cbad0ceb,3feffe52,1dd8e7f,999e515e,253ab848,c2646e15,b0865eab,c459a0c0,233bb52b,e202b681,c060f06b,ebb3a39b,69cc19bf), +S(1c6e7cc3,f35b404d,61d0454f,1a9b5c58,40b96207,95b613f0,a896d781,9e29271f,352cb00b,5d556077,c9fc75eb,aa1c28db,dad01cdf,dd5e75fe,ddd43ffa,8042385c), +S(56c10f,e369938f,13863e7b,5135ffc2,6da9eebc,5cfd6eb0,7f7d1f67,fa94132,8bdc142a,f7ae1906,c63e3de9,5bbb63cd,650ed4ac,b9a2c321,e525b512,397c5e99), +S(70897a5c,2d8d2e10,d24a0c43,a689c11b,be2b9f2d,2934ae6f,b3dd130,34046227,3f9d0207,3e083e16,f64ac869,5c1616e9,8f87e8b2,c9c95ed3,3bbd85b2,dfbee7c3), +S(e2fcd5fa,5c6af2d5,1297f97c,d2f0918d,320c785c,ba3802c4,48fab36,2147f39e,5308f1c9,b9a24e1b,855b038a,41004b2d,492fe91d,8ecb076e,9aea21ce,ecaf59fe), +S(463d53de,9f07ac1c,6eb5f7ef,2bc70046,261d6a64,6fa516c8,f7677ec9,b2153acc,ca198775,f0f19d71,48c138a8,4f5472f2,f8e5cecd,e2b7df53,61261cce,f322b762), +S(663438d1,82758d86,f292f12e,cd173445,2b554cac,1561f0c5,8f5fae70,9b165c21,23eb676,75e8f8c3,e78fa6c9,99d6e185,e0f789fc,80576620,5c50518,39e15515), +S(9a8317b0,65ed508e,4c9239b7,af39f42a,1d43bd98,8fc101c1,d45987cb,ca58f7a6,ce0db1d5,4df13594,57d9df20,6a487348,97102335,dd24b2b3,6e10bac,4d9b5808), +S(da6f2ca8,915e313b,8c4b221e,b81aadd1,e7468004,8030b8f1,48d1b733,caa33be0,bb59cc06,d267cb7d,c954338,9010d49d,466e4c3c,91335f62,1c4fe7de,d17cabbb), +S(7a18820c,1774251f,c299eca7,871bb526,b01081b6,c5321056,872da42b,9198954d,3d216aa6,1702fee0,9cd2a72f,e53d6092,2b07b51f,506f7a44,ae490af8,c9da7598), +S(1240d207,3d234306,70d9f2d0,17bf81dd,728e728e,5098238d,b0d79397,2628f5ad,612c97d,13c5a948,88ea389f,e809b656,77fccfff,d5db913b,771647a6,680fc074), +S(3862d4e5,c973e75d,ac6e6ad3,1e3e24c6,e9b8f5e8,6641b20d,f0bdb04b,ca98ecbb,524c8d0c,7f485be2,decedee,8320ec4c,79b1c25b,414e129a,2f848de6,ce3997b3), +S(afe8a621,bbdb4908,5726bbdd,b0d31469,33c75a94,bde06805,179729bb,1518467d,19b94d68,8a7346b2,e80ccec5,a393b7cf,afc4954e,5793cbfa,e02d7f70,7610fc85)}, +{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), +S(428114c3,8fc9e242,451a001e,34df1509,1f5c14a7,870f110a,fbcb0895,4c4b2496,4c41e9fa,ef00faed,fd12d4b4,9f5322a1,47ac4a7b,f8c7fc84,3a6250fc,efefb84a), +S(c0b87aac,8a4ee530,8476632d,ca83b163,3616bda9,5609ce58,8c09a48d,f544051e,a054562d,4bbfcd57,dc7ecaba,f110a6c5,e75e2d15,226bfb27,b8f88172,2a2bcdad), +S(e7abdaf2,2ddccdcb,736bf2e6,fdd79362,b02453b6,5619ada8,c018fc62,9fe2a74d,8e8362ef,abe83261,ab1843bd,2a477a6f,4a6a4aed,462e266e,e76f5913,1277c153), +S(ab7c1829,d773868,7faf5581,150db894,4d0a4815,c31e768f,ad3b313b,b159f72c,c687f86e,7e7bf0fe,a625143c,d6d7d130,13986eb1,5b2184a1,9f42a799,fb6eb703), +S(5f041f43,9394e0e9,23c951e,1fbfb8c3,8e1e3ab,58640799,b4ecf906,a6b2f4a,9f30e2ea,d04ebee1,f5e93cbd,2ed2682c,f2c22a0f,623f981d,f59d414,8c4d2d68), +S(b1347d84,86341ce4,84433a1,d00e9dca,63b94338,3818ccf6,59b80582,a027d202,2d30882c,d961fdfd,bb6c38a5,a11b6e89,25cc7e03,fe48abf3,3bbd86a1,6a65887f), +S(6e862ad8,859cd489,16a865db,cda120c9,2a5d8862,460a823e,9c47aad3,88a1c580,8854b584,e25c1b29,1c17fa6,bafcd67b,11c9ffa6,480679c6,8e253175,3faa4ad6), +S(a1b78338,c54bec48,aedcd65f,c60b25f5,eda31e34,d6badb32,75c128b,e3b8e752,86f46d95,157e23f5,6ab1f851,93e623e7,f693d74b,a08b47e,f776eeb3,cfe2ceab), +S(5fecd94d,128ae25b,b29daffe,c0d0131c,74df3dc8,9c4d573,e59bf41b,3f83a628,4f2ee3b2,3e5a008a,4c26b525,a5dfcd69,93215d8a,8547f13c,1c871f1e,fb082c94), +S(bca9377f,c179a785,f7b470da,51bec3cc,d6306938,f21cd224,7bc69651,bec76b36,cd1b6406,a55dceb2,c34e5c70,ee7fed4a,9ea3b1c9,92425ea6,72aeaf04,e5a464f9), +S(95d910c1,684c2963,6f90ac23,32461ef8,6d87ce1c,7dbe889f,405abb1f,cd0f57e4,1f095ce2,45a207a6,3c8b0602,4b4f25f,30e541d3,c325ff2d,c2c6a9a0,2db14235), +S(77cb5deb,ce99ddaf,4aa546db,274be540,a29b5664,5fdf411b,879e726e,61bebebd,df4b42c,63787720,42a10781,fafa09d8,e0329d72,1bc2189d,5dc0b56e,4700910c), +S(152ef349,2f9a22c1,87b70012,5b08a6da,68b50df9,1e671571,5ae11edf,6a35a3e8,d22a3f0c,654d88a2,bccfa6c8,704b99d6,7f5cf72d,ec1213b,f2c682a5,1bb91c81), +S(aa9492f9,6a2f4ad9,6f9d3b57,312edb60,1ab404e2,52ebbd4e,f86d5378,aa7282a8,bad928db,b54e8af4,2931d08,612ee412,c504c28c,31274bc9,d63366c1,c7f072e7), +S(a89ab05,ccb1edbf,1d95f7e5,5b2c1aea,e1c45b03,e352b2b5,b0e6a731,898a3453,72b9172d,548e4899,d24d5feb,87df8432,e1a6dc84,8dd28233,58a48c59,578cccb3), +S(e96d95b5,93801cdc,1b2b21f8,81f4154b,3967e7f2,84fc5a25,99c4fe5c,cf0ce66e,1a43ceb6,afcb7bc1,f285aaa,57dbb2d3,10d09cc0,1942aa72,daaf550,4c3c6bfc), +S(21de9188,2c8ca8a3,847b65dd,c667c64c,8378a756,cda3b9c1,bd6e438b,8b619cfc,d1d64895,a03b455c,1f52a019,6fa3191f,7dc57f9f,419d159a,d0faa03e,ea1f09e2), +S(9df78d29,3fd3a96c,f3d73bf6,7cec9246,edc8f68e,7b10e7bc,8a14e8c1,980eeb4b,d14369c7,993e8ccd,b89ed1ec,18a3fb7d,2659f70e,384a9f3a,55761eab,5925bcb6), +S(81a04986,e34ce13c,b01e334f,78bf2a3e,941e3e4d,243418d4,46fc0cd7,86f5dfff,3b6093dc,864ad994,f1c3b88e,81a46f1f,a916b51c,2d45eb06,46793fc2,e070abc6), +S(2f725b7b,8ba1d7c9,1c7b2d0b,65fd4328,f468b516,5cca7699,3430669c,d5643b95,dfc13e39,8ee1099e,4ecbd8ec,8847caed,e9872ab6,c9b0533d,b6191ed9,fa9b0e0f), +S(794a6094,8ad0dea0,907a4010,222754ef,c6e67a7b,d6c5957c,5eb004a9,a5518693,59897754,d7799fda,fbb2cb22,57687440,4c4c1318,b73745e2,e37b7f9a,51eee929), +S(7110e58a,64e526f9,a9caf9f1,e0ded62e,53450a64,3a6cd150,76983083,1d113dee,4629d7b5,e44421d4,4631658f,23ea59ab,1f15f446,790a600,483c1539,9c597aca), +S(1d550551,fc307b9c,b16f034,b79e7937,79127f55,8258461b,a786726b,d4c4aa65,51c47d4d,70f9090a,a7f8a183,75f74d4f,ac9c98ad,5c3bb916,bd87a9,aebc3de1), +S(4973c3e,97daec54,e5b9e9a3,6343e7d8,9c57380f,803f597a,25a386a,a652da69,cf403eca,b165571f,6b509b04,284c6e36,2f082b5d,5e7bc302,3ec0e55a,e73bc4f0), +S(61f7b3ec,444021b,ee3fd421,18e7b7d,fd795b36,d0145b08,ae09e1f,c0e3b07e,7df1f20c,79e3a7db,72cc08fb,98fed87c,ea923a91,815a187c,55e4430e,cea5e963), +S(42426dcd,302f698d,9376959e,50e6f471,5b1e2371,fdb03861,6ace0e2d,e27fa90,4c054664,1c4a0ea7,8280c526,70455e3f,51bee24f,acdd46d2,e9f82afa,db42d1fd), +S(80939488,3eaccc24,b1639e9e,656e7b76,2a310c4a,778b390f,d7a708d7,69c63fc8,b83fb593,a2e198f2,5fcc7add,310c8285,c19d314c,7614371f,9db28e28,8c2d47b1), +S(3f52b480,40e1ba54,67cd752e,a0265f50,c3bd1964,8f54dc8c,8dfaaf16,d9b3cdff,207a0014,1ee322cf,24d81b6d,2a7ccd87,be4d0b94,a7df9234,c0093bca,3a36d60), +S(c09cf34,bf1b1f94,15b63dc9,8baf66f7,68b073c,6b88fe53,7a9c047c,30703ec,757fd4b7,4f0fda31,99928ba8,39999cee,f2adbef1,8cf2aee3,4ce3708e,2897f95b), +S(8c1d9d66,b10dcb56,1fc72060,db7780eb,187b38ef,b18d6222,64188a60,da748871,b413ca7b,61ffe6c,16d493d1,1f955cd6,c7d7bb53,1ec4191d,85cf2f74,4506d8e8), +S(e31c4039,f33a6a5d,8682c906,612aa37a,3f522069,3948bfa0,dab4ccda,4f08900e,17d345b3,e92d1174,73330b73,cea9b1f5,f1d95ddf,40bd027a,b9b9a0d8,f84d5e26), +S(c4d82663,9c182e6a,b12ca500,3d5eca75,ee2944de,b9222c4b,6f73c58d,62d24bf1,cf4a0f43,e81dc58,c975d59d,73811d14,b01587c3,1ace50c0,b0b41f26,1f010e8c), +S(7c2514e2,fb6bb04e,829d82a8,ed9160ef,c9db98a,f898644f,bf2d01bc,97192be0,72114f16,4ec6ba1f,c41d6b0d,6746da06,4b46a506,171707ed,36cc6051,85f57ca6), +S(fd74379a,f6a18e2a,cd330fc2,49e346b6,89f7a73a,5f4d8862,4997a3f5,826a244e,dfe69f23,b9b2e402,f612abbb,4a4fb044,6a040706,19d6596d,b9953e6d,7179a9de), +S(a1c639bc,b913e3db,5702956e,9806430c,6572e908,a129bbb7,7c8ba5c5,50edb48c,7db1fa15,4c5841fa,c2127793,e9bef5c0,f749c99,66ff8d92,5a8ffb54,e701579b), +S(922dddff,7449c027,daa267b6,83112b45,a864a11a,1bd1cb61,ca76fe3a,77a6dd09,2beb84bf,87b85974,316789f5,148e4f18,386e20f7,41ec5066,2066c454,44c840dd), +S(ea7714b1,fcdceb95,407433c3,4c43a50c,767b3db7,fc7f6e6,81e79f46,44f044c7,6936f1f3,585c04ac,a1a2a562,424e084f,44e0b404,f97f1db1,37b3f00,b02ee04e), +S(cb4c8e7a,f5aca51d,448f3463,9c631821,9dcf6377,9383ba05,5e44966f,47fd36ca,8b0ff5bd,e8285a2a,1f4a223d,f6d496c5,15825ba6,d835370d,b2313418,b947b4b2), +S(921d8dd7,ba630901,3f365eec,ba09d017,2d579b8c,9550f6f6,a6d098c0,bbd08b3a,dad72fa4,9b0f415e,d9f96bc4,78a93e71,98d9456b,6ae10f3f,a1c744c6,e494e5fb), +S(7c9467d2,2cf5a364,191bf731,1ada75a4,3d081226,ff2e359a,47868572,3af15f29,50b15ecd,73341559,32ce1c54,e9a25b96,15dda8a0,6f4bc132,cafceb57,2fb48581), +S(48d10472,c10f4c90,713f899d,65f6edd0,af1724ae,117174f,55d4667a,b440e13f,baedab21,45103f2,aa668f05,2413b8d5,61ce5957,bebcbd8b,c49fb824,1af21303), +S(880d76e4,b95a3a8d,7ab6f9d6,f2069668,80069c0c,c447dcb8,f6063d9,271b570d,150d6984,2f638d03,881480f1,bd2a1958,9728ad72,f97d909b,17f79cdf,78416360), +S(286eebb7,f9215e09,969d8300,72b15a32,fc7733a0,455d2db7,71e527ba,e81caca,8584803f,db64bd55,317dcb87,a8c316c2,f48b3417,d0087527,338635c1,f78decf9), +S(b3e39ada,c92e1922,de3922c8,2c7e19d7,b5d10f4d,5e2cd771,492ba2db,444ede5c,bf9c1afa,d2cec5c0,66cc9e9d,61cce716,f58164db,e31f389c,2b596c38,e4c0ec9), +S(749ba52b,b88bc33b,b31f7aa0,fb95a62,932e447a,9a7a2926,56d16676,d66435f9,7075f278,6b7df61b,70065a46,7591fbde,ec40001f,242775a8,67fabdc7,45221691), +S(5ddb1306,a33c61c3,f0386141,7fd924ba,3118fa2a,53943221,b24cb748,841e4aa9,9602608f,4fd2f4a,511d012,320d05ed,bf1b5ba7,4da5f6aa,2dccbf0,83a18551), +S(6ec58a5c,d0ade361,93c644cb,e96e64e1,f2b519d3,80f7162a,b962337e,5b5c8918,85bc58f4,49b7fc44,1e95721c,b9fd8cd,63e8a250,83d9ffc7,fbfff18e,a2ef7453), +S(9b2f11b2,f66f7b29,e8421aa3,549c7565,87cdb7af,24354a3d,5e397515,f53f8700,3faff052,d2557793,b14a0574,942fb52f,1a53f6ba,e7f4c6c0,a2491194,2d9ca567), +S(d260f1e7,57c31844,9e12f1c3,15d28bf9,fce06b1,f7ce5db6,3210ab74,fa45cde3,54952184,1936423f,2314754a,5b419041,7510f396,90996d90,47ff1225,46672ce4), +S(c6b77e18,b935c842,52aba9bc,2a5f9a6b,86b207ef,5487e89a,7c754a7a,bd03b3df,1ae09c2f,61732aa2,9267ba72,8e22241d,efd6762,16b3173e,239cea45,60ad3978), +S(ea2c66da,fe996ba0,ecde644c,28fef595,490710fb,1052b81,57b63260,e53e5a83,ee91b4e3,cb71b268,dbc394db,7744ef3b,ed0362af,592bf252,71b8ff62,b821b8bd), +S(d6f6061c,904d3a40,75b2c0db,7620a6a3,9a7c21aa,9ea5ed11,c661132a,8cda9031,48fd7dd2,50bf50ca,91d362d0,f646dd6b,7e0f240,4ffc2973,4f131e9c,dfaca469), +S(30538847,93e3b958,a808eeed,546484d1,10cbb833,29a2b2f7,6f61bef3,b47eb9c3,ba914a53,87705dcf,349f5257,6bce5ff,d711fff,6fc8f6d4,3fd61b1e,2b47a577), +S(38558d28,18358d69,ac6b59fd,22660f25,58d6a000,35469f41,6f0970ed,1eeb8a59,8922887b,e256a2c3,3a3ea6,e745222c,9f07e9b3,f94ab1fa,2926e04a,ccd0c609), +S(fbc47f3f,534e67ca,d6f6de48,b88a0846,ceda2d84,afbb601,db71a61a,fd2e11b9,dfbfb0a0,652fdf29,5709b06f,2e61a703,d287b2f8,cee4ca,6a9f2627,2c30fd9b), +S(614d35c7,23a14b11,f3ea097b,6aedcf2e,536e077f,85cab312,74b7c9ff,a6b3112f,5b91b524,5a85c3a9,1194e8bf,be940984,c5866702,b51417ce,7a436642,d87edadd), +S(8304c266,a9876255,70768130,ad244f73,668a6bf7,ac611ff4,e782a6b3,761e5284,e47adf0f,66d4cad7,5834e7b4,f1a26b82,d5f9285e,a567fbfc,5f7fffdc,3df10311), +S(b1d777bb,76529faf,3ee711d8,58ba2509,c378c99,4dbf27bb,deac9d98,cd0202f,11f7598a,55c079f6,7bd036e4,e3a3bffe,159477ae,45c33ac8,8321fafe,3141bdcb), +S(7b91aed5,408649e5,41ea21b8,326f9549,6228e3ac,4e460b34,d77a526a,7972e4f7,12dff7db,c620f9fc,4ba287bd,2744e1b,4294e723,cf475d58,22f718e,c2dc326a), +S(56e7d74c,a4e530aa,7ae803e8,734280de,d87092d8,78ce187f,4a13ee50,c3d58f0a,d69161fa,901bc6ea,fbe62498,4ecc70f0,24755a0c,100ace31,7e677911,5a4c038e), +S(c83cdd85,43dcd105,efe4312c,f8f5e73e,1849364,668f0e50,dc40b13c,1c44fda,bad22032,de13c4d7,f2a61ec,947f266d,812e8b3e,d7fed352,93d161a5,844c96a4), +S(fe6f32d2,68be724d,28d1344d,8406c60a,70a2a009,db4c8e42,f434534c,4df9c3f,339bc5c6,2692a66b,853a323f,d09526f,3b336c73,bb4cc097,7b78fd67,96506d6b), +S(c3f6f279,fc937a66,a494b2d5,3bc6c2ef,13088c8f,842e1d61,3c5a35b9,ef2fcb5b,41cde800,63e8bbea,b2246885,59817f05,417d5311,e9fc8b7f,6c247488,10b30d64), +S(3dc7d5c8,abb4be85,9f6ba28,67dad2a4,7ba7970b,ffd77ca8,54107333,dcea1dd5,851d695d,54d5d7d0,b7aeac6b,97a27a9f,2100fcc6,facdf142,c82cdf9f,79c5cf7e), +S(2e28aa72,54ca6c6e,5891ccdb,1a1d2a85,53008b29,77a04ea4,d5deb497,bbcb95d7,361191d5,945c523,8908e0d2,6c08ba77,aa7db32a,5f19e348,a0037255,4105f55e), +S(84796cd9,233a7af4,7518bf99,778abd4f,a0238434,b5239f49,fba6b27,90f67bae,deb650d6,be46f3df,cd80fcef,20317c93,618156bf,343e9b2f,bb158871,5ce40c2f), +S(dbbbbe08,e4c768c0,531a3158,9b8abc28,f747bf69,228d16d0,8b0091bc,b292531a,576081af,a5aef1be,9916bc4a,2abe3970,12e371b,4c05e5c6,c97879ae,9e73c8a2), +S(25f6b015,45a8e870,592d532b,de9e2e8c,feece584,1667235d,a1bac7c9,58350591,5faff24f,2fc43cca,285366d2,578814c0,879cabbe,cde4b557,e7dc6fe7,43462ba3), +S(1cdd628a,a5ae5c80,85e83c74,986dda47,1d12fd07,158b20d0,d2d58599,f4648fe3,57ed9696,31e1134a,dad47894,f40c3e56,852d1ae8,5fba733b,d46951ef,7b33e5fa), +S(255c35a5,ce78bb41,ce85bef1,9804a70e,86aee3a4,24dcffcb,47180671,475080de,783f23,71984093,7db83676,7c3e20b8,f216bb68,bfa8b90b,7d9d95f1,1bf2db1a), +S(517283fc,d1cf1144,4f7375cb,77af87b2,3a11ce7,a954feba,378fc420,a05a8c9d,612cae52,640568af,607af275,4f6060a7,40b89f00,5dc02274,f2c6b8cf,e81c2e15), +S(39ff6f76,c8e4b6d8,4e742b0a,67725f83,51b782b6,638a032c,f9690635,fed32d55,c3d54b29,bc4ab777,c027f5a7,3ee75b4,a82dfb8d,5a5aa403,9f0a8787,dc054b58), +S(bf620a81,d6ad1d03,a66ca76f,c3b20e84,2fc75ea7,ca7e1f64,9818b27c,902e1ca4,4894f0fe,c2aef2fe,67c8aeae,5a9f0424,1ef68975,955eeb0f,66f63753,5d559351), +S(4c34e4e9,7584b95c,9bc6608f,7dba493c,97022eb6,14efc494,fb721fc8,3388a06f,b94f610d,b8bc4bfa,cffbd677,264ec28c,be18cdc8,db64154d,b62c4316,e9bb59e0), +S(76bbfe7,d39d6e03,9be09174,52fb322a,dd3ea192,6b546918,41b97913,acf75247,7bed078,7752a432,f0275ba2,a97749f8,754dee1,a5cadab9,5482d27,3c99b1b1), +S(deef7e31,9decf761,18e42c7f,27f427e3,4cae0d54,d7a045f2,dbe68349,c5b011dd,d3e73e4e,8f89b39c,83c7855f,8b5e352c,64f7b8d9,7a00c5a2,4b1b7997,c1db907f), +S(23f66927,d6a94731,2b43d845,fd0ee2f5,8cc329df,8ec37f11,75392bcd,c8d48857,747d60ce,bdc9858f,cfb28fec,5841d362,5750dd35,d08d0f27,4f173fa3,2fa0c4c7), +S(e885b643,c668ee81,4b94240a,4a68126c,625eaf2e,6f9dea6b,230a0bed,dfe06d9b,b575dd15,7436244d,191e3b13,d1bc8682,76940436,16b52aeb,7c731b5f,120d4bd8), +S(4ae81c35,d39ea1cb,7e5787a9,6a7738ad,89a0aeff,c556ba4a,d4dd1c5e,bf5a4044,76a3e3f3,96b88cce,2c978354,16cb13c0,f74bf815,ea9c9397,86da049,64f06d61), +S(490cc37b,6efe437d,35043f53,682dcc1,2b2a4704,c8102413,62fe38da,44717b5f,fb5c012,b205a188,6f1d639f,228f6388,2c598299,d2d6ee45,be44d994,bb6b6328), +S(c408d649,f8524311,14582433,d4abe603,5e66413,e65dddf5,f2ce6854,95be8d4b,bc9a1d0e,18504133,4e4b43a1,9d34b07a,1b3f7cc7,290328a0,71437e12,ed80126e), +S(af445e25,7fcd5ac8,54992782,30280aa3,354d296,6d494f6b,90c883a4,829ee71e,f839efee,87643874,2440e65b,870b0e37,3fdbca41,e57f3765,2cf479c5,cb7f6882), +S(f2c1adea,d2f8e95f,ad6a475b,199cc75d,a8471b82,1da81d5f,6d8b2baf,a1ea01bc,8e3543b5,36247e35,c2117eab,9d3e6783,f48bc2b8,b20993fc,1a0ff28d,1aad1666), +S(17b3dfcc,fdd57cdc,8a617eb1,5ec80659,fc695bcc,afd3a787,fd91d8d5,69abb5b3,75f1aea4,70f52f18,d2eefeec,7fff7f48,6718f784,a47cb32f,4f2c8574,591c122c), +S(f4d6bacd,1c8ac10e,7e97a6da,8a7d1af9,1c96a67f,fe76982f,a0ac95a5,f9f5a9e1,ea6179a8,1ccba22f,4dd93b19,5e151d38,cbede6c8,70a4a383,edc7898d,1f8f19be), +S(8011232d,32d4bdef,1fb56ae7,3e231a01,b877be6,72567310,2c30478f,50652092,49b91451,23311b4e,6c038801,f84561b2,8db03ccf,3df20b68,b35714e9,56b4f67f), +S(e23dd461,b79f6b64,5da455ca,90711ab4,cc117d66,ea8c9835,67f70207,ac5e1f31,8e84c4d1,ea634402,375c4d4d,6e8c8427,fa2479fb,3461bb5e,5fbf1f06,d34c866), +S(a2f6486a,97afc8d5,8367a949,278dca64,ed265743,16827b7e,7f3710da,9d7dfbc9,a723d6fe,419317d,623f8e24,75b365d8,cee8cb15,d1c8df2e,218f1b42,a72e7170), +S(f789b715,a7d5ba20,c1f8cb05,86cfe13c,59d27b83,ad1ffca7,75b2cb7d,9af88999,149bda63,63072ad5,279885b2,be81923f,ac9c4d07,2ee57602,5d99e727,150a26eb), +S(24078518,7abb2bbc,721e59e7,923f9832,77b13422,912c983e,d8670e96,c698c1e0,7e2f792,7976ba59,20748e26,ce48b29f,6ca37a67,6c8b4094,e661d5a9,be39588f), +S(8703f78b,17ff31d6,89833226,8fa9db6c,759e6066,ef8cf8cb,719f49a0,d7af6264,3b9c4023,d92827a6,53a7798b,fb21fe94,cfeb592d,a55e21a6,8c6615ec,2bda7ada), +S(52f6da10,3d75bdfa,4e0e7637,229f0c31,a6f5aaa3,2504daff,e1ef639e,2daa16e9,5d71c088,e8480d6c,e51062f0,241d0b15,9bd143ea,451193da,e13466c2,bcbdd037), +S(c68fa920,9f3a997b,2cc91748,3570ce74,1a0dcd63,1d7b483a,6f73a3cf,17b53eba,1f26839b,86154284,28858ba3,a3084947,883053d6,3bf039ca,89753199,21e505ef), +S(ed2deef0,9f558dad,84202b6a,e2456f38,39755fe5,6afb5aa1,147adbb3,915023ec,40be5a33,a71290af,e5080e32,dd9fa12,4273f550,9e78cda2,395235fe,c78e3274), +S(3538ad8a,98625432,2e7a9655,4e12d822,812b87fd,778e4482,b255b6f5,5c301442,5a6960b5,d21b0a7d,4afd9c62,7caec1ea,e8fa82be,e2ef80f6,50c56101,ba3a76f7), +S(a9580d1a,2b6544ad,65e45228,8e0dbdae,ec6de5e2,e9efc056,ff048883,b9f435d0,1a70df90,3d932f52,a9b3123a,1384cd6a,cb5b811f,bb267179,e1e4407d,9269af21), +S(efcdd63b,3c964ee4,f04a6618,ae526958,db1ac41f,bc53978,84529401,c0c53a26,913bc698,4d51d792,919b389a,dbb2acb7,7b3df92f,138355c8,7cb3caef,8cc50c7a), +S(c518437f,7344d6e5,8cb5ae74,acefba6c,a2ad92f,57f407e7,29f39221,885a8e17,efab7c2,145a8abe,50b46c51,9a679ec0,1fa017df,7c82d27f,cd2f93fa,affb5ac0), +S(a25e878b,9cf81fca,dc06a526,a9162260,d42273c0,49e7038d,ba66a450,25fc75c6,b08a8220,ff708833,56702dd2,b4971eee,956b2711,2767448c,7f2e553b,965f7bb2), +S(ce0ed297,f5961a82,327a1d8b,2c20f8c1,b996815f,c951f8d3,3bd0c16a,3ec45c3b,c4d21e67,8456fc84,955240e6,984b0a0c,8a10eeee,f40c6a4b,76aab8d9,5e887e7f), +S(b33ac12,369bf1d6,22c2c557,7fda98e8,f6bb4389,fad53459,e824bfd,e4409229,52925428,66a98f73,aaadfca6,940490c4,91e4ca9a,da343f8c,76b7f6cf,588802d4), +S(958d34e3,58ba9546,ab139250,d47f6bba,59f13203,e07432b4,f37da854,696e134b,e0c35ab7,45e91cb1,53ee07b4,f04f1258,9eeecb89,c30d10f5,d0322a72,7285ef19), +S(cc633cb8,b2465aba,a9a4428a,5a36c8b7,cb2fca1c,9702aef,8d54d249,338dac27,b6933908,62597527,8299b8e1,5fce0cb2,1ed84a9d,2533250b,6e417d2,fc19b06b), +S(61b81bf1,3ae0ba48,eb630593,512be80d,c4960d2a,9f0a6589,65ae04d7,36b4836b,43589e39,7f4d8df6,562fd8b6,8d4ee7ba,9faf441e,b1b09b8e,22f81925,9f0a9269), +S(2ce3ee71,b411ca31,74f0c249,7feb6bc,331a492b,85480be,32193c25,6321f853,32669ee6,8062bf36,b8c8853a,eacf0826,dabc81a0,48ef504e,e2ddf10c,8d6cb4c9), +S(6ecfd338,ab60c9a2,a50cfd16,498dcb45,8e6ac09,d5517fbe,f95f54f8,1b5a7551,b73277ba,4b7486a2,594f6571,a86251cf,54a1a5b0,9aa3017a,b4c0212f,cc94ae22), +S(a4cde541,dd4897a7,95f90ed8,75907a6b,8406a888,dc807d5c,6317c7ea,7f226d0b,5cd7591e,a305d546,14ff4233,600c813b,414fad07,8c1016ea,b021cd69,1d25d879), +S(4961a20d,ae4956c6,dfd04d1a,a261bce1,ff27a2ab,e0c3cfa5,6cfe51e,24c20fe8,9bf8d311,61ebbf5f,94c71ff0,7a9a04b1,92bc6cd3,e50baefa,71de2af4,f38a8660), +S(4b099713,d4622a37,d013359f,67983269,3274d1ed,4345cdb9,96ef3550,a57064a8,dfdb479,e07a1fb,ae741a92,2a468c61,7ee4cd46,25b1041d,f554e0cf,7fc5a776), +S(b5ae6420,8130d080,6c568d95,8222a1e2,3e649a67,8af5f0f5,89acdf17,8f79e9e8,2d883796,a8f45bb9,7d30e88b,99f6b01,dd46d91e,60d20d1c,430c36b1,b8b8ca45), +S(f7f1820,23de8475,7591f366,116bd60,5312706c,2d380d7b,16f50bea,71abbb64,5e3844ae,1db871e0,c12a7205,baf101e3,77af946e,aaea64f,c9aaf9da,e1ebbc12), +S(6d2620eb,ee6ec651,792adf63,9afb0fce,ee933e69,337ab7cf,2ec85ff,917ef538,e159145f,6aeff15,2e0403eb,f3082906,f98313f0,77028f74,bbe562b8,f335b6e6), +S(a98cec29,2cad6781,d4339548,10609d7e,77f7489c,2253c04,3ec1eb03,a69eda44,c5eb7257,c5b965ec,1ee643fc,7f48ca4a,b612f616,6a3ecd7,4c8da3c5,3c4efcfd), +S(6a88d0c4,4055a898,28a7003a,1fdd9941,4c1adb0e,90ed8d9,acecadaf,6a73920e,6fe7abcf,25385db8,be815eeb,14302bb0,5a630f92,2aae66cc,b0d42ac4,92224c97), +S(8a101a08,52559761,e2c6522a,6bf8909c,2547ef9b,550ee027,45e23592,89c34afd,64248f75,469015df,d9045beb,2de9573,c1f2e2c0,9f7a4cb5,cc85511a,f7182fac), +S(ea84bd08,37bb25e8,27ca0241,2cb8bd7d,ae47661b,f2460598,7ac20c80,753249da,15be2ad9,d4a8d7b1,964db56e,8415c890,93214016,e694f258,96574d48,45c8a1dc), +S(be2f219d,60dbe256,57bd9b46,18f62e2d,7501e302,885731c5,34b1187d,2c750f31,f521ca05,48ffffa3,dd70e0bc,79602b6b,617b9ead,b64e7af7,3d9ebcc8,bbd220df), +S(418d2b33,ce151147,83a75265,a876a709,ce7f452b,de9933cf,6e7ab1e7,7412437b,52693c44,5e1ff5a1,89b856d3,9d413514,aee35974,fc4678d8,86d5f998,a18047c6), +S(3e4685e9,3c65f31d,c58656e9,a8913d19,469f5e,2d49322e,6a99af10,c1142f16,1ed3edbb,6186e995,8241f3b6,ff7659b1,bbb007f7,f9b5f91e,92d5a8b2,c780d914), +S(35e15d66,d952ab13,de14a71e,20b1ed8e,f4b3f183,db75c62f,9af7ab3f,945b2d29,813f47b2,3fe523ec,12557edb,9e1b465,4582de57,5ca3752f,2e60be32,eb4333c6), +S(f025b371,b5c98b91,6157e1b1,53aac27e,ed42d435,53ca159b,48940bdf,b0f8d262,70fd31b7,a5470435,7936f98c,cb4c27eb,115be6ea,b4de7a88,1151e5a0,4364f12b), +S(31b36d5,b52ea8cd,c0298c03,8fa4f99b,19b3ae06,65d667d3,639ea3e5,c73875c4,924ccbf2,d1890df4,783760c,e6e2f50a,8dd8838a,bc87ac29,bbf89eb7,f0b46eb2), +S(1d57ff02,22db5c5c,f6f1558b,f71f0498,b706c7a1,84dc463b,77b4e21b,9d5c1699,b6238d2e,1bf715fd,d5cc0843,dad6fdc9,e1e6d485,c3584dda,3d06a1a0,414a3b31), +S(b5b7da02,4a6626dd,f67917e0,63a3a64c,f389e8e2,a631853a,c8e5f45a,4395cf24,151c4b35,22b4f1ee,2105b3e1,4ea193b2,ba6bf1d0,feb4511a,d72444b2,66fa7f0a), +S(2a58e24d,7f43233a,55a399d3,7cc0fd91,9b451985,13bd725,e24edc1,75ff6163,4f451eb2,c7374944,7296e447,406d5025,b5da17ab,8567cf01,ccab260b,da6834f4), +S(d8e2416,99d7e8ff,15853778,bb52a218,a2ed0c45,c7ebbdc4,a7357acf,86e7cd52,e849021b,83d33fc6,826c0a35,3f4188d4,37273a7a,7adeafed,6514bba1,a4fcbca4), +S(27f9e422,dd1b9a6f,64092125,71543d87,7d8ed097,52b2e6a0,cecd81e4,659e1f41,27563650,6d56cc26,cd289851,2274314c,bef8da2f,a4b1ba19,740d8ab5,4d4c3e60), +S(2071b53,72a746ec,a0795422,ea0dc0e1,b105e1aa,fe2fdd64,b08ff2c,47f4067c,1c95ae4f,986047f3,d969e8af,99775aaf,59a94c56,a47691db,fa0175ff,17641b0c), +S(b8decd7e,15355cfb,dcdb3ab8,48b2d717,3d61113f,58d21580,9292d4ba,379a839e,2ce7737f,7dd82aa7,76560921,21cf93a,a5e3c6d9,952c3adb,b6fb1f04,4274ad71), +S(23c7a3a2,70f20e77,d62f3d77,a67535ab,5554c821,71c77bee,1b05d2e,5ea67557,b8657a68,e2ded30f,19365bcf,916037e4,a1d87db4,632c90cd,ca782e40,b27bfda4), +S(b9af932d,753ba63,f7ecf070,d20d4355,42de9c72,a93f44e5,7b978e5b,7428432f,c2b21fb9,64593524,104c980b,a53de2c1,6e7408b7,33e2ffaf,17ed540a,6253847e), +S(e461cc8f,ad51c58c,fea92090,c2d3dc1c,41971918,687368c8,4c84a04d,d094704b,c1b114e,2cccc522,6fa3f753,5b6f356d,fddcad24,86197d90,4ab00cd2,f3d0103), +S(817e0633,4b8e706b,b7282b40,a4e243c1,87b24bba,6bfb69b0,d5a366da,c383e3a1,77593627,482c198a,f29a892d,5fb50a43,d10b4fec,5937d696,ee8fc6a2,20deabd4), +S(30bc10bb,d203182a,f7dbcf39,f0ee3013,7f26980e,e5f934d4,f151f080,b1341e5a,40fb3e2c,45dd0832,cb50d0f,4f45025e,3285bb6e,adefa1fe,4192e4b2,8a77197c), +S(143f113,8c45ea5e,a6bd339b,8d1aa91a,9db0dfba,90600868,309c0b5c,1a97648,e45fd7b6,8d025855,1c35285a,87fd77c5,1403c836,e0697b9d,4dcca76a,1422a6c2), +S(f3d30c38,4926b19f,5bafd37f,ea9b7c93,d4776564,5b8b4a89,199ed005,883e8c69,2f6179e,26dcba73,81ec7e57,1eb427f3,455808c2,21926af9,79efdcf,c7ff364f), +S(54fbfba7,13facf23,1013a1b6,ed7514a,4fe11323,3c363ca5,118a7d9f,63b4c116,dbfbec7d,152e7c9,2bb98067,37e926ba,66ed85fc,2339ad8d,410ed762,4407061b), +S(81d00298,aec59abd,c3ed4b5e,11d4589c,9c7a7ad6,54add200,ea6ab124,3b0c484b,226d41fb,a46202b7,ecf1ef9c,11acb33a,cdc15547,7bbab0c,1f56f385,6401984a), +S(2c088e50,50061a7a,47d84141,a858df75,f51c5c17,717b35f1,cce982e1,209712a7,44700a1e,99cd0f9e,8d05c8a6,18a75edb,d9d7f67e,45f5f40e,4c00eda8,290212e3), +S(2c903ebd,68f2053e,7a769b86,bb017939,556b532e,1b84cd7a,2397b1f7,f108a145,2915c5b3,f16b1eb4,8ed436d7,4a79c50,72a2eb02,b989da66,b164d475,941a8b14), +S(ffac0b8c,76c6b7d9,24ed25e,3f43ffa0,b261141e,715c07c6,c327a719,6b11fd43,9c25ada3,fe7d1661,1ba95eb2,231f00ef,cd250e16,68dd85d3,96025f65,4fe7da52), +S(d81236c3,7d7dda31,849e20b3,c7aebb2,b782a1e6,17b9d6f4,f56da4bc,d860c573,ac6628ac,98c0896e,ff1802ce,a43ae085,66e902aa,abd2cefe,b910465a,9f0fcf30), +S(19d94647,ccf05308,32903c94,7f149f0a,f1f7503f,92300232,a6f33e15,7874e321,3402ad42,87ad0814,4addcf3,2f7c60a6,6f65255d,ab4bbe,b10826f0,f5a07f39), +S(2248a7b4,37bb8bf5,df85b382,224a3d68,45965330,24f8c872,f81e2c33,610ac810,c3942980,b054122c,e806a67e,7f004b18,5288ff5f,d7e17ebb,97e68e64,1c416bd1), +S(d8a71ff4,a9de84f4,f28e78e9,4815ba2f,dfe48256,7128d149,e44d5419,da84531b,d3258392,34c87aed,8534e6f8,f03802b2,e76a5f20,552873c3,991c8d31,346f67d1), +S(322a4b9c,32ffd7e0,2548cbe5,9f50c2b2,e2a8c70c,dec7e39d,61505a2d,4d780ea8,809f262f,d258b1e5,b140822b,caf74d15,9fb764d8,53b653f9,7358adc,5891b0c0), +S(4b7a2f4c,e7cdc092,9bdf7d1b,bc91a60a,2e16bd9c,ad9f1cce,38ed644c,3a790fd4,5adcd298,78333b26,20d43235,8178c2b6,a4e697bb,81c3abd1,b850a334,933573e8), +S(2d7d8029,8da39ad7,ae7ee3a8,583768ff,fee73a78,728ffdda,b3921988,2ba3d8b,6f9e5aee,bd08f707,a49f120f,26869ec1,cfe9d9f2,a6e0f0ce,b6ce545d,43951358), +S(256b5db3,24dccb17,3b525434,ca36d6fe,37d469b0,4484dec1,cd44d392,b0f7aecc,c35db3a4,61f0f477,1a5d0131,12be5a90,64bcd516,2566a373,daa82b09,415c84e8), +S(9b641c2b,b2e3ee32,cf592c06,532dcd71,af0a1196,3a82c3a7,c0e809d5,8cc9b65e,e5925900,9d981017,bc12b524,b00ba98d,393be520,651a7b0,ea8f9ca9,75142814), +S(69700df9,b800a1a0,afa144c6,3a637027,ae53a786,e9938345,e147509e,ab6d44b7,227f91a5,b0492dfd,1e9b5d,bcd02bfd,4678bf86,8e69b7ea,e97e8b17,1aa1babc), +S(5ab9358b,a7008f2e,75392981,d93d062b,849cf9f2,216c48d7,4887d50a,3d8ae5d9,7b8e1ab1,9c6e9f7b,89a524f9,e39d5a40,90179745,1ed87e58,23f23625,115043b1), +S(46fa087,213b7db1,32997f64,cf9adee0,149adaae,e4d7c9af,61aa3193,606f12e9,2c428c7e,1c80e6e8,92f89777,d8afcb8b,8c0dbf3d,f8958f83,6ff1504c,e0517443), +S(c08b8c75,cede8e1d,c3ec26f6,ba7ae08,ec22f798,aa89e258,a0291e30,ee0c06cc,8454d21,18f72ff1,17866e63,5f65c349,2baea002,97b16e47,ef8876f,d8b7f5b), +S(f50450ff,aa054493,b0660d35,521d1ce0,156443b6,f5327e68,31385219,8e39ece9,aff228cc,970fca4d,9b583c23,b8e6eda4,feb549a8,2d767b4c,e535f6ac,d68d8287), +S(e80034ad,d9f421dd,de74ef1d,7a7e6e4b,fbe2dc0e,5f50b05,f7e8560,3c52ff0f,ef285764,dc9bb2fb,e6751352,a1926075,331c4abf,51e36cb4,36c9ee36,fea34e10), +S(cdbd6ea4,b3580bd7,29032b34,7e18c839,4832d8ee,11fd7a4f,c9c63986,54790037,80f51eb3,63d9f7a1,1e4508d0,643dcaa,7fd1570a,8d3e5f71,8371e118,d29f340b), +S(7eba7974,42a779a2,5d3ece2,a022719a,94a14eb8,e6f821b2,136c0d1f,f5637f70,5cd4f314,75808559,77def43a,9c974f4d,ed3772dc,b9091e7b,28745827,477a8611), +S(b44980a8,5e5fc57d,83d9791f,54418ad,5337eb5a,61746d6,71fb200,b5971f82,ff6cc373,5122c494,fed9063b,c8ad9e04,9842c639,db750623,997570e8,76324da3), +S(71057596,36c41dfa,b4bcd0e2,5c5d1d47,e60b283c,4a9762ec,10b15464,4cb07802,3a06998d,23644db2,b9cd18ac,1a077549,57e1cb99,d75ab6dc,c81db6e8,dcd947b6), +S(c134fd2f,c63a27a8,17e8f797,a120ed41,707067,c09931de,73e71fc1,84b1015c,5cd78606,9cc187f4,a3d2acc5,7b41d22d,cff9aa26,235ec094,c892a111,8488fa75), +S(8942fdcf,4cb81983,5e03559b,c81f4da4,bdba287f,b84c0ff1,2b023658,e389e146,e50d5d33,b47da2df,3130c838,5667c158,f5034d02,bbdf0be0,5760863d,a6cf2120), +S(3aed32a6,5d3188f2,ade2e91b,552d4c56,5d75c72d,dd51efa7,ff2e2e4d,49d71c0a,9f980569,e231ae71,3f524c7b,a616c342,340a1cc7,2a0a78fa,461c732d,8b3571d0), +S(5b824633,8060ac28,f228eee5,405b10b2,8b33ddb9,9d09aab5,c8f32ca4,b3aa59e0,ee4e5740,206040cd,91c46d93,24a94b6b,6439e517,cbbd0619,80b5e4ad,91938e4c), +S(4eac5700,26a7997d,b5864e0d,1e7fff74,61cccb83,aab89c90,bed839e1,a6392220,9506b28d,aacec4f1,9843944c,690adbc1,ca8cb6c4,305510f1,31521569,fbe3281e), +S(c205259a,feb286d9,bae84b81,debad402,c60a59e5,68a0f4d0,204e909a,41119044,16dad4ed,eb541c30,38af010,5ed75ebb,e281de77,c3e61e70,344ad85e,2ca34662), +S(dd215ac7,a8023c12,a7752db5,89b72cdf,90333791,996f7f01,67162221,db0b131f,8436a84c,4d7af578,2c377394,26012793,b99f5c4b,f6c37a4d,a2ff2847,c4222a6a), +S(2d71215,5647ace7,88354c3,522da12f,fc44920a,9fe67b1f,e05f9eaf,19997db7,23cb203c,4c904541,2e942d3,da6cbf37,3f40a1f9,b6d896ab,b797955f,3666b0b1), +S(59643435,43bd6f7b,658055b,2f9e5966,303c276b,b79438bc,10014301,7b6b04ec,6bf6b2cd,7c88a172,25a68dad,e029bb0b,26137995,cbcd9d5d,8f93c6e8,fadb52d9), +S(1fc70dfa,bfb7cf69,21f682ae,ebdc182f,f0ba39ee,8c28b779,325f9e7c,152a00cc,f79507e5,51c7b44c,c9525d97,5110a19c,3d51593c,4aab618e,641d6de9,466d8df8), +S(d1dbe6bc,1821a383,d10318ca,c23cd56d,17106937,42609427,edebb18d,9ff8592a,b45168f0,d49ba0f2,6a8729e4,c860ff1d,e1dcfb0b,7c1ff20,48b2cd15,be043205), +S(4d15bd89,53a4b5cd,5d11a16f,728397a,744db565,cf744494,b67b1b4a,ff07f375,9cfbab6b,e9cdb650,fe7ef824,c3118722,e68fc601,1b8e84e3,e7028e69,d3235565), +S(dec346f8,34a5575c,d58f3bc,86ca0d8c,9ef3f556,5b091917,c80f467e,fad12a98,20741ea4,793def6c,3b46e8d5,baaa6e4a,1f529cb2,880b4142,ef0a3ed5,6d445efe), +S(ccc91a35,3532454d,9fb0d811,941eeafb,890dc07d,ab4c117c,f9547c7c,6b45645d,9e25533f,2f6bd1cc,2fd8624b,a64d42db,fd8ac325,37f09c7f,1d74fe46,40aaad82), +S(feb81407,df6f1137,e257c20c,f58a77b5,83ec8f2a,b5acd9e7,12ebe6c1,2aef1d60,b7279d4d,470318b7,86ea0630,3e78981b,ea2aba8,162adfdb,5a8949b6,1c1e3e73), +S(ffe40f24,eef97a34,e57728e7,7c445209,29058d51,1bbe823f,b354f853,63009c7a,c71020d3,2946f80c,700ca0e6,a6dd43cd,a9461db8,a25b67fa,92008da7,a96e680e), +S(a36b2254,2f8d9055,41369ca7,793eb500,2f6d8a69,410086d1,ded6bdca,692d1b6c,b9b73b65,e69950ad,f25787d3,897738b7,5306afa6,8156419,892799cb,20a9556a), +S(92a24def,2b893f11,b0056962,b41273f7,76fa4a0b,4d525f3a,14236756,3d5b240a,9e9ad443,5fda1d46,a77ab3fe,62971060,8105f5b,a6d9fa83,47508d6d,7bd8d288), +S(8fd20215,ba152223,ecc28d20,749ccbdb,9d536b64,77474808,9d2cbac3,e0a11f77,434b10d3,33418084,ad2c42a,651b52c7,bff040b9,333fae3b,26935997,7f6be47), +S(b4e6caec,c78da734,80884183,d0aefa0e,82001bc8,2c376981,f40b5c13,4c8a034d,95f192ca,cb5059f4,3c6323a2,a0e09204,4f39ecfa,92c22dfd,e0bd5365,5b500c3d), +S(9536a1c3,ee4b8aa2,8edf3a0a,e2981657,df90bd4c,c62be8dd,8aad1a85,8c4d84c5,fcf54bd4,665ebaa2,9ea4d2ed,40bc8a42,34e6e061,e325abe8,2a123b06,36d99d4b), +S(3e15d13c,75ff91bc,5e928cd,ec8e303d,286deea7,d7a4d88f,6613dfcc,a0c27c59,f98fdca2,1e3dc253,44ffab,2865181d,b830c74d,2891c80a,b71a8,904cf13a), +S(8215dd74,1eb7a889,7895feae,170dc452,f8fc451a,2037af7a,fbc02813,827ed4a5,bad149be,dec24412,4f65003d,d44656bc,5e61e332,aed71f73,b58492ba,ede0040c), +S(7b3755a6,3913920c,83a2ab1d,6a738122,bf7a67af,ddba85a1,6b9d7de9,ad6cf0ef,25752fef,1ce6ae9d,4f2ce922,fc610ea4,d4351718,f8e97bc8,bd4396c7,11697dc0), +S(cdb499d,f67a81dd,db28cfbe,bccdf877,4f8b76f,6464ff8c,221a95d8,3e3ffe6f,4b08bf10,15fe6b37,98fa8da1,7438fb88,eb96720d,495d22c6,336e0225,454268eb), +S(ac0a10fb,b902bcf8,205b2529,7724073b,55fa2837,dd99edae,e256f7d8,7c19aac,7ed1aecd,d088097f,4ec8b005,892fd069,ddfc319e,f5bb3b25,2ab7c597,d775e615), +S(1e9e3fa9,fa96a4e9,4f19c5e1,105ffc9d,fd7add4b,63c85ac0,5098c839,c0e851fa,69bffc28,5927b917,dc4dc5c1,3ceef964,27dbac93,a778a01e,227906d,6abf9df8), +S(14359ebe,e923252d,f17e2320,d97a991,c16d7819,d9791f86,65142b93,4c2bc20d,3248f24b,d31f47ef,dd34853e,dc84f8f8,17403b4c,eb737d8e,c144daa5,2e5b65da), +S(13363dd8,56df936f,35f1bb71,eb2fc4b,df232e76,1fd9ad9f,db3a6d6b,ae78e837,8160695a,7428e400,9fc88172,faa6784,b3a2d03b,71f89a5,89dd85e2,f5565436), +S(6b71ab46,20938910,bf2e16ca,6e40a653,2c6c1b58,b258ad04,b1d51656,3a5520c7,2e72f5ef,4ab06562,52e224fe,1c670b2d,39630f97,f78ee55e,d1e01f5,c967d988), +S(98f0a6aa,7590ffae,731263a5,b940dd85,6d0306c5,ae98bfc9,9d164263,ec14c21a,284bef1f,a5a54c96,f5aa7c41,ac50c5c,fa88c352,52b923bb,92da72c3,d3d7d8c9), +S(78d11179,5965328f,cda22443,91871ee2,574c0886,f82e942,12e261bc,f5c3b9eb,83802a00,84e8b578,4450a423,1bc1a99e,6b9b545c,e32881c8,8487bc45,59604f84), +S(f0856a2a,2b8b110a,dae99427,9af3da1a,a74e1b77,46d4ece1,f054bc55,905aa49c,1a80e529,2b4dd9ca,4785abff,edbbc11f,7111663c,3fdf55f6,ec3031aa,3c5f0890), +S(2c5fc446,44d1e735,3e2b3374,89eb432b,f4dfaba3,39051221,4d279de9,87d6df7f,76c8ddf9,d2339112,c10ac9d0,5a473d28,cd066ff1,acd63e5f,b49bfb8,bb34d3cd), +S(3cdff15f,9953cb19,62cf5024,4b8db26e,8180090c,d6baf7f1,f60e6184,73a9336,275922c7,6d4841c8,324d1ea7,9948765c,ea399a78,51939f80,15b0b7dc,9f22d37), +S(d36724d3,91d3fc20,d1273367,97f8d961,18543b2b,dd40a77e,88813634,1c5f5d21,bc81050a,e6cac0f,ba1bf5e7,f1232d5a,a90d3b29,a0fce8e6,4dccb5f9,3e6a4d14), +S(f91cc30f,acc100f9,ee054e7b,5aac0294,e50035b2,2e7f35ee,306a30a5,1d5d6a00,328094f4,26ac3ce,71d53f82,c3deb250,be6a44b,6704886e,424e524b,c50f3e65), +S(48c715e0,da1ce36a,13cf4b8b,d5294baf,84a3fb08,b353e43e,e9f37481,ca2beeed,9d7e13c,f09c64c5,fa4a852e,206cacc3,8d398693,31368cda,1b06d242,2f8e26dd), +S(74ca89db,72b0796,af9b6d5a,57296952,1edae51c,5a3e8a76,b1746b87,4ce9de25,c770dc38,db1a585,43367fb7,979d7016,15a0a112,61064596,ebb40e63,e41ec50f), +S(36e77506,6284060f,8f8e709b,88b90125,f3c696d5,64bc048c,8dab4b93,40fe170e,b760473,d66e32f0,a716c1f5,ae462b0a,b5e77e6e,2e30fc58,e5ac1099,eb7105db), +S(a0899b68,99176eb,77c78eb6,d4a7786c,8afe1898,d34d3cfc,5f286528,409da4c5,f57441f8,734c16af,7ca6c64a,6fbe557e,11463e6,6482f7ff,d46f1b91,eb2a3cb8), +S(3503ac4d,9c9fffeb,d188d81c,9a92e506,a91fd15f,6bc67dc5,502b3ae4,d39d8e5f,dd66ff4e,40a5da17,3d3b143b,60534b70,33a5444d,98ed15ee,a6644e10,766b7918), +S(7765e5d3,2ceb50d0,b9bf9a80,48179d59,9fbfa214,4f183c63,9de26485,a87590ea,2052dbf2,718975cf,3c225235,d2504b4a,6b9026ca,731939dd,6af8ca08,9bc7dc26), +S(eeaf76ae,d4e737b9,900d4ce3,f39a880c,e060eeb5,208bf4ee,81b173a,dfd193e9,5490a02a,4ad8595a,6afd6612,48a80146,14366bc3,4c9167a,f290e164,f32eb9d), +S(f64a505a,4116a861,12914f01,6ae52fc7,5499efe2,32178ce3,d653b030,5b0cd0b9,4a8bc675,8353b7ec,e89096ab,aaa42a2a,e8af1a51,2e6f9323,1ec71644,1a09ef3a), +S(e73f95b7,b13f0907,53ba9ad0,c8b7f2ce,83ebea09,cffdf313,868a6ade,ac9c9efe,17986166,e766d323,cad73824,8eecb239,255d37ac,af72a56c,69594ffd,78281818), +S(7d2f8553,a46fd9dc,6fbd149,abd07161,1f279250,d508b9c8,b22eb2c4,99145d36,b88723c7,462f5f81,f69c92c4,b204f499,b3b826d2,1c05ceb6,a30bb285,c4bc4fd0), +S(32dd097d,96318d8f,69cea5f,f5db9476,33aace77,9059fb08,4177b8cb,36cb334,b078ae96,3cdc78cf,bd0e5bde,532a1269,a752c8ca,c8dfaa81,6ccbf4b1,2c3057aa), +S(7caeabfb,be7e30e0,345161bf,8380e160,2415178d,314caa33,b3c99d55,1c99f506,9a449ab,6cc98b09,6487475d,cae39e13,7df05d2a,f7863080,393ac16a,802547e4), +S(e5783a81,16e1e396,4c693fa5,919aff98,bbb954a1,e8503974,a27af353,3247dc86,d9d2c1b,633e2217,b66cadd9,dcff6880,be272900,e1c966d3,3726ae66,21860fc0), +S(9c7f5cd9,c274177,1f00e117,a62bb197,d0a8a18f,2ad23261,eb04c91,47561c9a,6652063a,9b2a5abe,38ab7b50,5768a5d7,e098ac86,bf127b48,2c56a417,175cb5d5), +S(fda48685,28c4f2be,58cd9b00,6fbe1121,ef009361,f0198b2,f5c56b44,1d28e9dd,3055bc29,fe08760c,ab624154,ee98a506,9de9dee8,c1db40ff,b972db60,30af98ea), +S(ecf9f4b2,2feb14a4,14628d74,8f7e55b5,886f7d18,d107e4b4,f985df5,163c3eb1,cbbafcf,84606b89,63e4013d,3c730edc,da808338,3f681153,307929cb,905beb69), +S(ee0ca18,25428e9b,a4c0be5a,8c9da473,f73c43d1,54a6fc52,176ffa4e,c05af36f,c8b960ec,91139b08,25face64,fdfa01fc,7390804,3c4f691,bf684dec,bb10cbb9), +S(744d4c0,fb5536e4,99b0397c,8cb127f3,68865b79,fbcbdb37,ff9f9c8f,59372ebb,b9ae4d36,489ca0ec,c318098d,663fe8fb,aebf149,fb28abe2,15ef6f43,8e414a4d), +S(910d358a,710c8e22,314b9eb8,394a7770,4549fcce,c98046f9,9c0a3e04,90510c49,5ba779b8,530e57a4,fec63e86,188d269b,6081fff9,d3f49bee,b0b62e29,540ae214), +S(2434ca82,89853823,57d1f537,ef02fc12,89300332,6acc9c67,ca2f3b96,691e94c4,e4608778,311bb1fb,f88a771,f6281a0b,7f850767,af4b9699,77b1fd6e,8df34d7c), +S(cdcebffe,d7c410c4,18cac7bc,cba49a59,b3ad5ffb,4c0577ba,19e25dca,c16fbcce,9745ea09,ddeb473a,a0b861f3,7d16d83,a8a73289,d278ae12,1168a6a8,d6bf5595), +S(826f49bb,90a6b195,b7de613e,ccbd1230,930c0303,d88ee0b7,a7c40b66,cf576a56,230ee0c1,c1f86c3f,a79e98f7,e63a7a77,2ad22724,ff6ae39,ea17cf43,e2e44c8), +S(d8bb1cea,9976a5a,ef1a5e6,57b70b09,e59cdf59,c67b4de8,9694701b,fc73c7c0,e76bb7a3,60759c9,441424cf,46aaabce,331e749c,80d588da,e3039162,e1a95d35), +S(6f475ce4,d1c3ee7d,130d101f,fde3f250,d1a0d884,2239ef78,83d67254,80b750ed,13c5fe82,7c76f2c6,4739839c,4d8ab9fa,3271dc83,b949d123,532cd0eb,71809e0), +S(d8d129e7,72635a5e,bff00c26,8ea30c0a,bbe3c635,d49818c,a3251082,fda4363f,4c4f8a79,d88bdf32,9b7a7121,7572da21,f89cfbbf,22547269,1362d5ed,c50b471), +S(19aa085c,e17cd19e,c610d3af,91d9a263,3d706773,1d5f6891,e31de7bb,39d306c2,aea04c67,efe26,c46dd958,e8fb2d4b,726e003,2d33355f,e7d256a3,842f75b9), +S(3712aa15,914e6f15,50ec12b0,f7dd6b2d,854d9f95,e86e7d2f,103b9925,dea23828,f5435b64,af251cc8,72c9123f,964c1c75,47457e1e,8c8942e7,852f4fe9,a9240c84), +S(f5b9a5e4,db49b7fd,b00912a7,821b8c37,a89ce6e0,12286f40,852746f0,1d4ab4b1,7ea00e84,d03d8654,ea03759a,69a3b055,60af6f38,55dd2ccf,a2e4da9,f8820114), +S(4ffbb51b,563605a5,eb7e784b,93eb7ed5,83c65968,1446a776,443cd436,e86d9f13,ff8e7729,e235ae1c,9d0ff576,5dc8763c,7bafc9d4,f3eae4b3,b7a58871,add58688), +S(9b3fe406,55f0a924,ddb0cb1,48dbf03d,5da4f1e4,e8b7307c,6b261915,2fd5c3e8,46dd956f,583120c6,91961916,1a46023d,da55bc27,b0717029,748673ef,b6aa318c), +S(86d8917,9410b427,b8008d10,3e481c35,2f089dc3,5c263804,ca86e08d,9da279ef,9aba2027,c3e47bda,aea2eb58,617ae633,83379235,7c233d30,e070115,d46ec081), +S(414b3ae5,23a76abe,6ba71141,8ac0a61e,4915076f,a0c2528d,e20a0b5c,368d2245,bccb169e,3091f7af,bfb8a251,958ffcd4,6f0c8c5a,f1662640,6c7c9993,3fb8fdd8), +S(7aacfb93,8644090,57ef8ab1,63bffd25,d8d43166,e8f31304,57779b20,b5da5998,257b5c42,2cc77f41,a6234a9c,1ae8d2f6,e91fad8a,78c39a6b,1d380a4d,7c9684be), +S(2e51b2e3,72a64010,92ace7d7,b263f897,ed629521,d45d962f,2876c266,3e42d7f3,fbd258ad,28324ce7,6bdd4b38,44517a40,e5cbd237,3bdcdfb0,862e768f,8e6dc5eb), +S(7721f122,e26e0fba,f6a33521,841be750,5a47dbcd,941191c9,432bc25f,56aa6e55,65e23e03,f03785c7,c81695cd,b49dee81,b9f678fd,55325ce9,dcefea04,f11a79b8), +S(aa7443f8,435fd4d1,e2f1dcc9,bed52a07,66f3c62,543a0f3c,5ed7f593,e7933f9e,858be190,a656bcd3,5b377138,2c3176a,45e0a53c,8a346743,e1c595eb,f992c70b), +S(23a3de7f,147a4ca1,bcd19afa,a8e71a58,27c7e7aa,c7db0c3,40d37b4c,e97a76dd,5361192f,76a37f5,d02e697f,288daf6f,34313d58,4e33344b,32cf1c0b,2c711217), +S(ab65c884,73b68402,5929fefb,322667f1,bf02efdc,d33552ec,4d743222,2b2d7352,c2949d4a,af2c3ed0,f9284466,a572b1e0,34e56e23,4c928646,5427d60a,2f092d63), +S(5d82cbf8,71aa4029,b16d09b6,ed1a22c2,6a94bc73,c1bc11c3,ae27042e,92fabe78,2610095f,c1dd2eed,adf1ecd6,a5b15b0e,5c714fce,87f424f1,5c198588,8b2ae3b2), +S(e5338bf1,79e3b22a,306e3f36,5121f94d,cb5a072d,6acbedf3,87263387,7ee23090,a8ce14f9,36d0b486,3db6f79d,d10922f4,395804b2,37035103,b59768da,c1f8600f), +S(e936f432,e5cefe07,e4e290ad,823d90a5,c2701eea,57bebac4,81b97400,b8964544,ebb65cc,15843766,77e34e80,b665567,19189319,2a298033,a4786974,5152b5ef), +S(a8f4c429,d93c81c5,7284f59a,a3a941ae,536f7c2c,e3707973,ac3eb5b4,a0ba1ad1,4e39b9ef,5e1b885d,b3a8e72a,8c069800,fa539e6f,7f6ffb0a,4b22ac8a,66c8a83b), +S(76ffc741,af278fae,39081989,d884b195,9cb7f240,d80c35f8,989310e8,64034e40,3df6c05f,12b2ddd6,262e3837,5c2876bb,e0f7b769,7d4cca13,be11c55d,cfaf6618), +S(eed12546,217f1270,505f9235,b875f6ef,1ea38bfa,6e790cce,97d491a7,30683809,6edd20bc,75c215a2,9a162bb,f19b757b,ae5d22d0,1c7a68b9,e2e0b01c,21e4d193), +S(8a975564,196e1add,526576ee,dd330a0b,bb1dd32b,85ae095f,79666907,15637aaf,5ba79be4,6db3fc66,c2f9666e,86162767,4c408e7,241ca378,47b8b3f7,ad5c3c48), +S(87728750,a68695b5,a23a86a0,50e5a015,e721ee92,da191a77,a8945c92,e356f3bf,44746e19,eeef603a,9115bdcc,b8d4146d,a928e723,e1736c9e,a352e8b8,8bb5c6e4), +S(83e9abe0,c65a51ff,c9e70748,35d1263a,5c31db10,6647e6fe,1ff9613d,6ddc6479,2b956ce9,1dc3fc78,b5d2c0e5,abe82eb5,d1fdd4c4,f2fcfed2,acbac011,4950e7f9), +S(89f0cbc1,5c7c60e1,6503fcf8,8c70dc2f,b3f18eda,3041ab27,e917b93c,a837b60c,9b25624d,1e3d2dc7,7c4a1b6f,4daa6020,2246386,b2007dd1,efb0043a,300975b2), +S(b64246c,e22786aa,8f269907,bb819041,dc564b0d,c6e14987,c5ac8fcd,a7f5a98a,68d776ac,5200e1d9,68088a72,af4458d7,85dd81f8,37f877f2,f4884b4a,3fb4d5d7), +S(babdf57f,ca92a314,6884f3c6,509a27aa,c8793214,49f55c78,7eac3531,74074127,380fff63,5aebe191,3c6e690f,76045577,21f65949,6a1df010,32726fbe,ceba0038), +S(92eade4,5d8ebce6,3685ed69,56caa62f,2f9eccd4,55f57bc6,4a75010d,20ac2df6,3b5babc7,16be9c71,e87bb0df,54aba5c4,3bd1f820,40d98f83,f2911eab,deb32573), +S(ac69071b,c1bf2a3,b01f633b,fff39f4e,3c5376e4,620278c4,ed9d98d9,5ef7025f,252a56cf,7d6d2835,6defd43e,70e6bddd,6462bee,d37b5227,d7d9fd5e,3b95fc6c), +S(f05e2926,848849b2,a7d9b980,c5e18d11,73db7422,4a3c476b,f2c44b,4d81b49d,59aea3ba,83cbdad6,4aba7857,1228acd5,eb574350,a9d1940b,68a4e495,2ded3c0a), +S(468ccfbd,aaae8f16,b91f4,cf41ec7b,f65f5832,8a3543e7,106dedb9,be4896fa,bfa82375,5e234421,19a18f8e,d182c52,1caceef2,3811a874,8d30b143,5676a186), +S(92452b56,58086172,625ae89c,48491669,e5c38d6,6280163c,397169,79578e09,6cc0e425,1da8e662,fdd858ca,e213cfb5,ae819d79,23372d39,d5a9722d,66543782), +S(3e201b8f,ce5bc832,c336c15e,2daa7770,1835c00e,3852cb19,7a9d4a2c,a902e287,5096a11b,18ce12bb,27f935b1,3e664d26,2cfe6be7,33c8b5e3,45cafe32,9f0804f0), +S(68ef4ac,e421f24f,dd628a01,56caf9d1,24bfbfb1,d6651f35,10ca5e48,5bfff389,8ebf4cfa,190aadca,b04c256e,ff0fbb04,bce8b360,3e308fca,fd8dddc8,dda15ce), +S(d2e44a05,64718ff2,85c56932,8d8fa7c5,530977d0,56fd8090,972599a8,461b5d39,a16bc6e7,3d514070,702db8bb,34f3cfa4,12099e19,da5eac7a,f87076f2,88b88bb6)}, +{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), +S(c275fe8c,b742a78e,7d78945d,34d988e1,202e1807,905ee89,d348957,f44c319a,88aecab2,7d47654d,df33617a,5fae27a2,8968ebd,284f5970,e0c39a2d,1e8039bd), +S(9dbe3dc5,ca9889c5,af21701e,11c60d,2eb901f,d0981d51,faa8c79,8b766a99,26878a40,fb4f091a,7c82cbea,db50bd98,8ee84e91,f58cfdf2,647a9de0,39f614d5), +S(4471b988,ed964b29,87a79324,a251f228,321523d8,1a7039cf,43af4c90,f63c3ebb,8196836,d28e4dee,9022c609,4f078448,72e70cf,c0b8640f,a28bece3,76c5aeec), +S(a7f5ebb1,7f00f9c3,d51ee4dc,ed4d713b,916b8049,17604d2c,1c6ede6f,4a9308fd,954f55c5,83d49978,cbe0bd27,7b2eaace,92e43012,bc31d63d,6f8d117f,e1e80223), +S(f80df047,a066a8b8,e1c6c6d1,12af4a5a,92894eca,d7946929,264b81bf,b060db7b,b3295268,6d708b49,73f0861a,3ba7256c,709fc322,9983c28c,6a76aecb,48032947), +S(72a6521d,60423431,a29ef70,73467d31,f654034e,3618c2b5,b9ae057e,b6c85b2f,f2cd61c0,58988546,7197e84b,6ee01d64,d200a135,542d5a0a,fb3ad4de,507dc900), +S(e1bc0481,d40b97ad,c4eaccb9,377674d9,ff106f94,9b3ac081,965b5332,5c981be3,a717e82a,d9ee2fd8,c07e3c96,a224c449,bc16032,3d0f0f1c,5e5b0f88,47f3a7d1), +S(e44aef3c,f9651799,f07b2ed8,b9e86780,fcaf26e1,2fe122e1,edeee3bb,a45cd461,c2a599d9,cb14b881,53a18c84,3831c475,4245b403,840e8cfb,6442446,d412785a), +S(3db8c67d,1964077c,bff351e9,ff770afb,5a7836ba,8e8916ae,2246c183,86e17177,1c02f899,1cc2b1ab,94affdf4,a302042b,db88b31c,5a516b4a,6d63a667,10e7ac32), +S(107e06bc,96acffed,cafb1205,26c61c9c,7a67618c,d1d4a1f9,24f7ff89,febb8316,aaba34b8,7ea1b235,720b79c2,b84ad3db,af6da2ae,3447df19,77e0a08c,366b3cc1), +S(b8f30382,716e92d9,7607837d,b162b56a,8b50dfe4,76f5f700,832dd55a,1e686a73,90a4b3a3,d11e9bcb,55d76467,a194f32c,e2fef47,1fb2408f,b71b9326,3c722688), +S(a3d1dd0d,8a5181a,b06639ea,f4f3111d,3de0ebd0,5567b9ad,56df821a,59191b04,65b8e7a4,fbb854f4,3699e509,4a9da6eb,f277a0f7,a38dce11,8dc924f1,ba916726), +S(44f3f1a6,8fd1c5fa,9de45857,7f320273,69cfc6ee,5e30822e,cec0605a,dbde28e0,400f764,2566009f,a7482bf2,7ca5b0be,1621b94b,ef42f693,417412cd,835c922), +S(d2eafded,346b24ef,633e925f,74178ac3,5e6f4d32,173797f,1f51e12,2ca65f7,6d30ca48,b1f675ae,1e1978ca,6c05f542,2e2864cd,a58480cf,517960e4,f373d79a), +S(d07404c0,67917364,7b2e946a,87c5cece,20be2c5b,2ba551e7,864b2b30,8a7695de,d685ad61,efc4fae3,fe60574a,8a20a6f1,9243100a,4bf945d3,de002f81,3b91c185), +S(38936927,ecac3831,2417ee88,59318fb,724e758e,a175bd3d,e2247b2d,1a037a5d,da223eb8,71b3f213,ffe0abbd,8bf8152b,afccf3da,4bad091f,38ed1c5a,b90bbb9e), +S(2e0b714e,f9bf7154,cc41d846,9fb99eb0,7bed9ad,3ad4a60f,b3e88fab,974ff918,8680512b,4a6dfc2e,9bece0db,435d4420,c745b611,8feb15e0,7f1ce001,6a65fdfb), +S(fb42c1da,8d1b62dd,7949a6ee,1e8605a7,fc774863,eb4c7e70,8826aa80,c5b22aa6,272c0d71,127c514c,8b2905d3,d962080d,b5644bf0,25ae95ab,5d88b15d,596c7eee), +S(5dd9e606,61ab076d,d7ccb699,caec20ea,49b5645e,96662119,15f679d8,1dc88e70,e17753cf,6bef65ff,b2739967,e64f7402,54562b4d,9e44c297,3d1e841e,ba2ca74f), +S(5c8ac07f,466b9f4f,3d6f463d,54f16e0b,3661ff55,8a1ad864,bc86ec2c,29bd8356,f849f526,77b36737,586b8782,27a927b6,300ecb2b,cf25c53d,1cc18c02,366a9156), +S(ba773918,50f9faa4,715a8b00,bbb3abf7,c78f17e7,917172b7,958e0439,7b974887,3e38618e,743539d3,469820d8,c1e127a3,cb2cc6bc,a386087c,ea7296f5,46ef4418), +S(eaf36e71,7c23e7f8,8f1af63b,fc7e56bd,fab55922,122e868e,5456d556,eb3051cf,843239de,1e94148a,54a00e92,a649ac07,e8fb0883,7de8a3c7,405bcc0,26bec993), +S(fd76140a,9e0504c,5df9aaf7,ce77174d,d64a8131,2cdcdd5b,8b82985d,db980f2d,7da81b12,d2836ce4,ee81c288,9db2408e,38f7888a,29282a3f,22a32cb1,5630c5f4), +S(7db855ee,a3c28e7e,45f51166,f32a3af9,3fcdc75d,acab827d,3844cd0,b4e88251,8cf4f691,9dd33bd4,d95aa1ac,c9ecf926,4be5b588,7453e77e,9f69241f,9498d929), +S(dafcba5a,e148fdc,aa431fb5,db8f4edc,f43168ed,5e381fa3,e5789c89,82f2a90d,a6c718a2,92c522a7,8dd15fec,e3ddcf50,10327f8a,1f601544,dcfe0e66,41404275), +S(d7de414e,7ccdc7d1,e934b10,17980cda,fed701e,5b3c4a53,d8ec0021,bb6b7015,47ca5491,2d5fd9a2,37daa64a,6434d6eb,5a8e27bc,665d3cda,d3164fab,f185125f), +S(7391420d,d4585846,cdfbacd5,63c47521,cd3640b7,4ba43c86,3c5c09db,d389133f,243bf979,ceb34758,84130208,b3a8eca7,bf695c38,5c60685,6785fd65,b1114e79), +S(a387b4b7,6c49ea0f,9b5e20ac,79053b7,a7391c3c,984c7e0d,72116ea9,85a11f0,fe7097d3,ab64e202,e61cf2ac,27e506f1,78bb534b,1bfbc8a1,9c435da6,b13776bc), +S(49df7215,bd8ab08e,21c56507,b6e57425,bc4c443e,ff0a49e,ec4ce0ac,4caf132f,9f6eed66,1066c373,275d82a0,4908193b,5477690b,5796be1f,533f67f,b9fa18c2), +S(ebeb0f66,1a66ae8a,fd0b3442,45f78f6a,cd414431,13bf03ac,3c6f5641,b5a62dd8,fca3f129,76d11af9,81f6c175,5b9015d1,91dc21e1,a91098,3528516a,a8a22a09), +S(367a8c75,e4fac5f5,55f2f48c,23d3c344,ca4bce60,b188be03,5461d077,af8a5e9a,8064dcb0,e3c46a0c,3cbfeba5,20b18f1a,4b7171f5,7db2dd3c,829d9168,f9275792), +S(d3e2eab8,ff9af1c6,5a881738,d52ee173,7baff4c9,31937318,287cdadd,46ff98b3,f7c729cc,808f4760,5757fe5d,c150ffb,ea4bd6d2,78e3860e,56b45add,bf54875d), +S(86c329eb,3adca5dd,7e840133,9025cd69,461367b,781acf0b,fb2f760b,6b56df9,6db54fd0,401af8d6,bf94cb4d,c8230161,ddfeab22,2c6802ef,1640334c,bbafe470), +S(ac9cf2bb,fbbb0be7,8fe03b3d,5b0aedf1,3d36ec3e,d8748a68,ba873bf7,3eba049,cafebc22,ede77a8e,fd3926ab,dd69342,b3226271,9a7719e0,540afa3c,c23d60c0), +S(54f1d996,ca39664,f03ede34,3dc394c3,aae4b65a,e75aed69,1427e2fa,85995d22,971bf54,8445fe60,714cf038,6c801979,e6eaa1c4,d51aba97,24b3491f,5b490fc0), +S(a01cf61d,b77a9519,6b8d0f1b,10f087cc,3689ef3e,56e66f4b,918baece,8480e8d0,d6da0432,2822dded,838373e,70550728,1a1ddb83,375944e5,4559e360,165d6b81), +S(9c971dbd,7bd6933,d4d4c918,ee7c7236,45fab1e6,1f50f54a,5474c711,8334e8e,767e56a8,e6aabede,53566eaf,daf22c38,b2f949b6,4dcf006e,b24469e,c2ab6e82), +S(db08258e,4dfa75a8,940c111c,1691e148,42a106ae,11e6f266,8a6bd70f,fef3624,9bd0de5a,f568b6e,1d05bc6f,e6999245,3a223e91,61311b7,7e06cd6c,faa956f4), +S(1f546fc9,2f784ca,638a1c8b,74664baa,d2da0745,199aebbe,9fd1d65b,48bcaf91,5470251a,9b9d5a79,be198076,541ba922,d7692ebb,f65871d6,e9daf078,52428dd1), +S(a318a92a,e36427c7,6c8387ba,d4420b29,a8b0f583,76d6e049,e70b9a3c,55b5d799,b38888d9,574e6cf4,991d6608,ed6918a9,92ef5a1e,90d405e4,da8280d6,74f93b2b), +S(84c29d90,417579d6,6124a754,aa77b711,4758f383,20a395b3,44b0e547,d8779b2d,2957cecd,8766c432,49ccc288,c6f6b005,b2726bcf,9bff51e6,d676ddeb,ebd340dc), +S(4109a1b3,c740a287,5b06f841,def2cc2e,47d82029,bdbdedb7,7a225298,e3f010a6,334cbba3,6526b308,ca45e487,d10cf54a,fe229d66,e3538833,754c7058,5f9f368), +S(99cb215e,9ddcfba6,bc703e59,c3d3abc3,9b0824b,ca0a5cb2,35cd2a89,3fb2be6c,6e1494f4,2df30735,45ac89ea,ca3834ad,553bbfd8,ee0231e5,c803661b,82a16cef), +S(2bf5a599,18959366,e7740ef9,8e2159c9,28cdcda7,f38753f3,9e83923a,5121b490,7a70ee9f,387e09de,6a8608bf,527e9d0d,75903644,c4efdcdb,916f7cf0,bf35bdf8), +S(234f1de2,aca81510,1a9e8659,41851280,8d8801df,2d63ed83,e7c9899f,6881ccc5,d43dada1,7029e6ba,56fd9c99,29810f3e,c8bd27a3,5671781a,283abb97,12014be5), +S(7a691d3,2b6d605b,c04723ca,a6d7219e,39d73fcc,e3b4e4ce,ddde027,eb31b918,9e869d3f,d4802e57,34969854,12a84c77,42dbfb65,f70d2d4d,a7ddb858,f68c88f2), +S(963764d1,75a0cad7,8e87e2fb,d3f32dd3,e45e57f9,ccad6560,dc58e548,8bbed05e,d5faa558,ac6a9a20,74c5166c,72c15cfe,b509828c,24a1d967,8aeb6dff,5eca8a7e), +S(9d250071,90c38bd0,64f0cf4a,dd0809fc,95c02956,9d199840,e6d947fb,271573d0,5eedad5f,5930c244,b3fbec61,425da0cf,6d0eef25,87e84f42,35f08429,9e38d8a4), +S(83b30514,e1691531,5eb6b9e4,eb1affa6,533be8cc,c8af829f,5829321d,cd3aeacd,7eb7fc6a,e43b73e3,1ff48193,947eb01d,3029fab,e51e4344,a278f142,9ddc9752), +S(4365f9cb,8ea699f5,284e21bf,fd4184a9,685c6b9a,c07b555b,eae2b2f1,838d9cd8,4b0c0ca,4fbe4088,e1c55eab,f80858c9,6c5d3766,7af397ee,ffac81cb,3e2d2394), +S(7bf3588a,9d51278d,539b7e72,19e32b94,336441aa,3c56db9b,d70d1d13,4425ad3e,442a5e17,27706843,fe43b75c,ec629876,2b8a81ac,26f71371,ac78110d,67d9f54c), +S(bcd1ea95,621c195f,b37f0ea,aa7c1688,35e3ba46,e1fcdf8b,c6d4ba36,9dbd46cd,799a70c0,422c82ba,e3790abd,22346df0,8d1e80ad,9194f70,f94f9d09,50b8719a), +S(9eff139a,7e728eae,57480c55,b5a5752d,83c4b92a,96b72c98,ea7fddd9,9cfaa8fc,656a5a97,1de87e12,afcba7da,f6ee5020,7257f604,5a909707,b55a83ae,ebae5f62), +S(16edb231,17a09c6f,bc1b0142,c06d9f8a,ce125101,a48229b0,a7605a87,f3fa59db,1f41d18d,29b720e8,54cc7876,d682efda,97d27e31,3f66eb89,7e23d85b,e160c9b2), +S(890e1604,5f35d432,fb62b4b1,aa8e8aca,b08a5aa6,edced104,841ee569,f8b0dd86,7970b632,a25643ad,df338a59,4f974cd,701da359,8b845ab,bcae75b7,f2168e19), +S(630d23c6,f5586b45,59d68f49,6531cb74,e2075ae5,3ecee2d,3c1c8ac2,b01362f7,5a9c6335,dbc506fc,d8abf476,ee5f5437,290cdeb8,9c3ace9d,184658b4,67478c74), +S(9348ad11,53e90953,65a13cf5,6cf05d66,a69e509d,ccb1be8a,5a985472,f5ec3909,3632b1da,48e2ce33,97d25cd,6fa6d55a,9fed786,9a7b9bf,d2765af5,81af7206), +S(e507b132,8614fd05,e9d8fd9b,5742cebb,6e7301dc,defeedb1,5f79022e,79acbbc3,e09d5d09,2eabf8d2,d0186df3,5007570,e9e85f22,269e0342,183bd375,a5e326db), +S(81727248,d85e0f46,a8e4b09c,ee17658f,557e1dee,a7c9c12,49012f6d,76f5432,f1654495,339b6da1,981e8e87,eb95d1dd,5b62ba06,67ce8a2f,889081bf,2aadf), +S(54f7d9a1,806fc37b,668a97ed,286ab04f,a2a96f90,aaa92118,4bc0034d,431c5d18,26f8efb0,5bdb0263,2e7561f3,9f56c5c3,2f41c8b3,7771ecd,897204f,33c1da14), +S(75b272c5,88900750,4b139b59,f3188477,56aa22fb,b1981bcf,74491b05,881a4be6,1b7ef1cd,70dd43b2,851220bf,b3989bf4,66e76fc3,e9262d89,de46327c,30a73c31), +S(9880a12a,10a9692f,b542943a,ce6513e1,bc95fb8c,618331d1,413657b7,13b2a811,38e33a55,ef745420,98d92ffd,17a7882f,b2e9dd69,40deadd5,8dde4a,8c31dec8), +S(232f85b6,f3fb87cc,fac4c06d,bf585c3f,c5ff3d67,114f1187,17d68ab2,af6e24ce,44981280,9c5b77b3,ea4d6b1b,e1872fe9,c295596,839a135c,443a37c8,d0a1f405), +S(e7e0e5ce,292f1386,3f186534,200727a3,46e60312,76ec0831,3fff6810,6d378912,404fd06c,68a99234,9d86e1cf,c2aec52f,bb101169,6940c961,1c052d86,ce87cb6d), +S(7ceb4d25,1844992,86b50e20,efc3bab3,a98cf466,e22c4018,eb22a97f,51a2182f,4cd70a08,609fa1b0,d55bf37f,2be739ff,8af001a3,190b7b4c,9687a3a2,949e99f9), +S(bb22eb38,cb29566,57a046f5,2f97d3a3,83bde5ca,e0e64fc3,6c5d28b1,be701695,574027e6,92a28c07,9fa92945,cfd36c73,8ae59c35,c869d17,d460f9d3,d12f7ba3), +S(e9803291,3c7e0c3f,4e0213e6,a6488dc3,f5c0dc6c,9246b655,5dc0adee,978ec5f8,b3bd6f23,bf63d3f6,ef4b4e45,6ea7d58f,47136aad,da5b1de7,765dae5d,b4b6986c), +S(e18f27f7,f8a95e81,fe58a13,329d12f1,4118d924,2bfbbfc0,f64eb2ce,b233c15,66b93d85,a1c7dc3d,cdfc3970,ff0f61de,b6b0adb3,ad8b0db2,fe766606,3c4630c8), +S(e6243ac1,f0b1d402,363b4b37,8ca320a6,68595325,a1d0572d,38a54476,a107a2d6,5286e1b3,54a3e264,4d9c91ff,cbd141ce,58c8a6be,5b609924,5821dc49,d1e92df1), +S(a77f0928,c24f4ee9,14a84684,568ca975,322ca71f,dc78f389,9aaede60,9a3df1a8,1cc82bd5,7d6eaa18,a05e8096,441676d8,d66c1584,af2cae0,ec118bdf,bc32272f), +S(e79c0aa,51e9fa1a,c6e330aa,b9877118,ff672fd4,46f49920,fcf14f26,d74bf10c,6d952340,708203ff,109a0d,7dbedf52,866d204d,8f5c9cae,bed7c724,4d726ac7), +S(6f5ba3c7,202c796,c27d342b,9e5f62e7,b3962a71,7fda573c,87d30071,796e592f,174aa4c,789ff3a4,1c5a42ad,a3bfb2de,ad3a5351,cd9bce90,f983a9d4,e897f053), +S(701c7dc0,9edccc89,530845ee,6d76dfd0,ec06a842,49ffa8bb,1f5eccee,c8aea899,1f3a2d11,a53081ce,6c326977,911ed535,2de2df6d,e3ea92fa,7946efe1,a2afc215), +S(3c82e97d,f06da304,13439ede,3a56a48f,c4fa7c6c,9ef2a74a,cd80e58,3e3e4104,1ec4e9c9,14dfe93a,13a91edd,5f7f63d5,fe60ff4b,bb271624,d5ea48bc,7833dfd9), +S(88d3451f,3998286,2cc3b867,afd91cab,6ccc737c,4cf1f41f,1c0d702f,a2af97c3,2e3d51f9,141c94a0,1c1907e1,c5328653,a67e80a2,80883f2,2caeab79,70203d05), +S(dea9dbff,93f8f6f1,714a49a2,e9154fa,766b9627,e64049d7,4363a542,f30b0647,deb01f8d,91c3f7f0,ccfe5fba,a5525b4d,b10561c3,aefb11eb,6e540844,2813b714), +S(7e715f8b,68718d16,ec601550,f80a7f91,d1f1f3a5,ec972755,66ad93d6,af205104,9c79a5cc,3226c625,d734b73a,f34bc14d,a5d5007d,ecb402af,b815bf4f,18df8260), +S(6bfed43d,a9196990,c03f788a,9b27d023,12394f38,78bc6d64,8923ec4e,3db64d98,672d59b8,c2c40ba6,4c88e516,d5602983,7a9b328c,6c28701c,80d47927,9590a913), +S(177bd160,1c53637,28e341de,4e7f8a22,9a561665,c1548ace,7e6376eb,dc790009,17585c2c,9a90c5f1,3a97fd24,b7cd0358,762f1217,e4ce2bf,832c008d,d004186e), +S(f1b16245,4181187c,f5251139,8382026b,ac7c4355,ec7cd347,9f83a66c,db63db19,5d261ed7,3c9611ab,d983d74a,9ce05bbe,cb32b858,32d00e87,fa794482,41fa70dc), +S(aadc4097,ce6fb92a,6b77b5c1,abfdc345,85982877,5c37a522,39518559,363d2fec,825fecfc,6f11154d,89559a63,56308d34,5dfe2e8,a439ed20,eef0edaa,3d506a62), +S(ba354351,d81b0113,a215ed8a,3a900fe9,3484f35e,36988664,8c830d79,699932b5,c18c12fe,9b2fa86c,982ad09e,5d29475d,7a0b7f93,865e8300,f215affa,48bcfb66), +S(ee1f269,ab870c07,1ad7d7d5,a84b5c64,140a3bdb,68f0a5de,c4a80c52,9bc7f6a2,67f62848,f082c3da,69056b00,91ddcc2f,7687f630,7f4044c8,8196a368,d441a44f), +S(9880ef57,5b111cc2,c51b9b19,d3c154fd,30d8b967,312e30f9,2f210a9c,13b8531e,af790a63,c44bf477,8884f95f,91652c14,f1ee73ba,7c1facc3,8ccac2e9,8382b83b), +S(996a6793,873cf119,f77cb23,1c8771bd,6226d90b,d319c2d7,d9793a30,4a7686e4,983c75e2,f0ef1d60,dd60ac8c,d3df6e09,ae1a8da9,17b1c63f,f59e17c2,c19a7d38), +S(35faa9e8,7fefcabf,3aee306b,a88cb110,1514db47,9e559e6d,f8b995d3,1616395d,bb7560b9,fcdb7e2e,7522e5cd,7bc42236,79d1e546,a7f7c0c9,44186043,7dfde05a), +S(70d1471a,52f0fb45,50d2c644,b7925895,5e27917,13ac9a68,2b5351d5,333b3fcf,a84cec71,622fddae,72f4f995,2585ea84,c15968eb,666573bf,254d2144,e0a523e1), +S(ac990fcb,477409e4,442a7635,64ceb28c,26adc45a,b5b99441,e9d7219d,593ab4c,3f3ba91d,c08bf75d,5e764b72,d048fff7,fd6ee3a3,758bf5be,d9a7da1c,6446e15c), +S(f8f64b95,69be42f6,1567f537,d9e60f6b,f0608f5c,d8ad8567,ccbfa02f,34b26208,d818300c,ee7da0af,1542dcfb,9a62ebd6,86c1bcf,d9e5f41f,31f79892,fbaeaba8), +S(c24cb8c0,eb923c9b,d12db26b,9473982a,73099bc8,1f0ce101,49d153df,e77bd5f6,7f47cd6c,123cdb2f,f9772b09,9f44cd9f,643929d,bf0132c1,4f9df2ff,cf4ac056), +S(5281bd2e,f6089825,91e8310d,4d626c4,4e68ef80,b9e6abdd,6a0af7b3,4b957f1d,eb9a808d,97ae906,b029a24f,b600712e,3cbd406e,27380c8e,bcf3287f,fe1e2cdc), +S(d525c063,fbbc8ba4,dfed492e,cd056ce4,fa60b04c,25c850b0,70052ec2,6f592be4,8e5b03a,9268a809,a86f3842,10a4dfb8,1a5d4659,c2695723,db7982b8,698cb778), +S(b0a5dcc1,3b377072,9ef8ba6e,b0550b3c,968b4f1e,2a2ffe0,54a89eec,ed3adbb2,49865cce,282b337e,14ab3f17,4a07979d,38649ee1,951f8aea,8a6ba657,8bcd4356), +S(ef3b5acd,4bf27694,cd96f70,7708eb1b,26f517b0,37d44194,ef3aad38,98d53812,db292747,53593713,1c0a9be8,5b020ad,34f2040b,3b60bf65,638f4561,709889e1), +S(dca55235,2326841c,625226a2,6844d317,adbb5cdd,a08f8931,68920aff,82d300be,f48441b8,a104131b,bc1a2487,eb3760d1,8b60c53e,70b693d5,b5db49f,485ee525), +S(53a47db,565ec4e7,255ad4f7,7fa28644,2ecfd91,32a0e8ec,6e4f119c,2d090044,1ee6a228,b1615640,83a62c49,f3f92c9c,9d6d46d4,6c7a277b,7ef7705c,4a20a6b1), +S(8187e675,78d1c19f,c1624a5a,386fb1a4,2ce7df06,8487baa,f20b0975,6a40ce91,241bde96,53091ddd,49423bef,e6a1ca6b,b75e312c,46ff803b,bb709a4e,25a691f), +S(3ebd8f13,d92881af,1a43223,335c7eb0,7958b7b4,e5af5cfd,f320228,64eb7937,72b3ee1c,bf91271c,84603d64,a8feba9d,bcbe4626,57c4d084,d2d3c8af,e7489c58), +S(90de5cd1,b27da158,a73ed3c1,f23f9390,9e281c65,6d50f8d1,b70294a4,9f4bb4ee,1619b365,238cc8c,be2b62db,ddc24381,4ecf4095,8617ecfe,6315f8b7,a1d73b3c), +S(e44c5ccd,d2723f6e,c44ba386,3337d911,15a73547,c2dc77bd,bfaa6e1d,b4ba3d62,f150acd1,65fc084d,b8b442e8,8a6fd033,5a8383df,9b2639b0,3248a1b,72828129), +S(62eb6bb8,67fdb48b,f474318,99536489,437a7086,8f27287d,6ad56996,31d6c845,1014f43c,517b3a80,d2cd9e4a,7d76693f,61afef58,4ee80ff9,8d20bcc7,c077f7ad), +S(a44ce0ca,a242039e,3defa271,59976e2d,4bc9f1b,10e07b83,4aafee6a,7ae93066,511dd603,d264403f,19da6380,dd470cd3,2fcf656,2cf00b3a,d6a209b8,b244b070), +S(1f1be63b,414713ea,7060e264,ca58dee1,76677033,66002c72,fb8beb2a,a661539c,ecdfdf49,a771409b,2cc03f7c,8640cb98,49c00a82,1d40d1f9,586763bc,35815ab7), +S(30a76480,5c483013,7bbce984,10a2c250,4dc2250d,ed82f853,7caf58a5,b52bd8b5,2edb011b,ae585fce,da2e20dc,3d840c5d,704b8ee5,8578c573,d3363a0d,83168c7), +S(3d6072f5,dede706f,593d93e7,73e3555,c7ab31f5,60a83985,a575294d,1c73d135,d8348521,802df34e,ffc3956,498b0f25,91ef05cd,b71da7,20ce9b3e,b9de6db6), +S(12e42941,44a1bb18,e7944b3d,846429b0,cb9010f4,b42a31b7,e7642b73,520d2ec0,bd7a8a89,f5e1d98d,adf3dd7b,9c8b2bda,5e49f178,cf51796,9bb99903,43901cd8), +S(93b9a4b8,bf35a92c,1f008623,ef3c864b,79de76f8,5d52c4a8,67d24e5c,970d3776,10d1fa77,43bb9211,76801b67,5ed9d304,8fb25b31,65a0f544,52709615,965a7b0), +S(29cae9f5,688107b0,d7cd3686,d30c0dd2,1f65bfae,11172330,7d21b8cf,9d95a49c,dc8ba474,da42ca9e,2325123e,1dbf93fb,c25469a3,381b6833,437034e9,2b6a20be), +S(d1ecd9ae,8af12732,f9423f23,f261caa0,c75a7e,58e0ab83,7fd47568,d3da43aa,c24712cc,49a9a669,e0e46068,60a8c0d1,969aaa66,a436f3b9,1c530e3c,6c0a71e8), +S(fd43cd42,67c4d07a,d70df093,863feb4c,5f82f94d,c81c504e,f95dfce4,4092104b,d68e7968,e003ab0c,ab98beb,796dea02,e854ce39,ecd79ed6,53e001cc,3be14c78), +S(d758723b,587c3af3,52fd7d50,9ef63ac9,efd9235e,a8c8d8d2,41de2898,73d5fe94,43094c5f,1c773577,29b9638b,d180a70,b3c9ac41,8e078dd4,99f5d2b9,1f02edd7), +S(e8fbc8d6,51f9828a,2ec3ccb4,9b7fe22e,18604125,7c975ce,3c01b362,d2897e36,1c306170,f2e1fc7b,ce0d9ed9,fdfa39a4,99d6cd36,bb04716e,e1ac003a,d7573242), +S(bd8878bb,f050eb0c,bc7775ee,a3e991b9,5e72330b,fcba7b3f,cb7dcea5,f1464f2b,c3bbec0d,e87c5a17,5370e6f2,f98b7adc,3538a452,e04ba2db,3e193ba2,d9d1ba5f), +S(e47e80c0,bfd82bf4,8aed911f,236a7d96,4f370d11,c5c10912,3828e3dc,e87e0b3,1856149b,230697d0,1fa39446,9434270f,d0932196,aa7e4551,faad127,b0d22d60), +S(224963b8,57e650e1,58be4862,bb70d566,c2fbc28f,c6892eb7,6f04135b,7a91761c,28e62c6e,887010e9,7eaecc0f,b67e5630,eb2ccdb2,f95d0be8,51c43db1,54ca6e61), +S(b500417f,b75ea406,cbbd77d6,48ac1e45,70703605,8990b340,85856564,a64af549,daad3ad1,9579c990,a7e061fa,f98fbd12,5678de87,ca16c708,7130dc85,abcf1bee), +S(a06e6152,bf4d9aef,d18fc0e3,6e0eed5a,a35b316f,7db75007,ca5a175f,3a80cdb3,6faa9900,6bd783ed,d8c207d5,95843ea0,2819b277,7db69ae6,908d7ef4,4e04e781), +S(179f9602,2ccb2620,3e94101,c9bc95de,5eb6d3dd,8a04f18f,17f2ddf5,1b0df5d4,dccee7d9,30f31ea6,3903f801,d4712ae,ad5459a5,b0ff2987,b3b1f454,650180a), +S(40312ffd,1e4508a9,854c3f94,ffb878fd,a5912ba6,5ea241dc,ea82cc66,e586de28,e111c511,5399357a,eed01d11,18ec409b,febc525e,53cee921,d1dd0455,d01854d0), +S(a29e24d4,c72bd5ea,98630030,a31150b6,5a1c9676,d661ba8b,19d95d5b,ccd7bf31,a906225a,120eb05c,3885e734,75765949,a4da7e4e,a6aaeebf,2f23a011,7aa8df9b), +S(e2e4adce,eb40ffbf,f2a31a97,a34e5f4b,9dcaf149,76747838,3fc0bcb0,43139bb8,94ef60ec,26dfc1d7,dacdd451,2f8c0a0b,ccba1b04,7ae3c197,46f3c234,54a007c4), +S(2a11ab6f,7188858b,e0c8c08f,22b4bd83,3c864a74,4c43428e,2c467d4f,a71118bf,27f83304,ae9e599b,2a212050,c8c363aa,34ae58b8,13912bcc,f6df669,f01a690f), +S(23cfaf4d,57e0e9ec,a8d180d4,568016b9,4f896063,c6fb4e2d,7cf909b9,6ae048cd,62b11d6c,2c3f30e7,655d2c86,8c7fea1c,391d2982,5fdc92fa,f2ef3e5f,f2d65587), +S(cc112ba4,a6b684c0,6f95458b,18f1d41,d0c90022,1fb6af39,203efe1f,f32a07ea,7919e449,eb1720a,49f66e8f,fb3bbe76,4a5e23f7,798f47ab,281d7cb8,9409465d), +S(4d9ad572,bd2829b8,ab98f048,88ec4369,b577846c,59e70414,7128c4ae,17159456,4570249,6405ee85,4bcf1201,9b56cef0,136a4cff,cf90ce00,52711348,a459e1e5), +S(dd32548e,826e2aa9,faca198e,f911d0d,7ec33ac3,41f625c6,34c59c0,ff3e3bb9,5526048c,fcb29f30,ac84ac24,5230b0ca,a0e68e88,ad6c3c75,544bb137,4b1fb47c), +S(c4ca7cdb,93519cc1,7762ce27,249e21a,e2bc5dfb,727a4e23,a38f2938,e41e57f,8233f977,3aeb917b,c65dc1d5,a539f62f,c8403779,f1edc4b5,781e92d8,fc8bc802), +S(a1e1f0d6,2a0d616c,ece08d20,fd529521,c5872f8c,8cda2bf1,a679af71,71bc46ef,68a2a818,4340b803,c7641034,fd609333,180501a,612d3b6,c66754c8,16e5368b), +S(d099aeb2,a5fae253,6a953441,7439e745,35fa8236,96731b6,cd327332,8771bb26,c526ff8d,f32deaf,b7080667,c9d74257,f294355d,4cd10414,e8e38fb2,b3722eea), +S(87fbfc7c,ef2301a3,b50c3bdf,993c52a,b2c32ba2,893b8d60,19f224aa,9554900e,aaaa988e,cf77f228,ee4f42ba,a7ef4a64,ab475e3,3d708ee8,e2826fbb,cc3b92b8), +S(4b440dc0,d6673ff7,cae6cb6c,5ad6d54d,fac23da8,f8e1a570,82fff0b3,eb165493,35841c69,5eecaa5,1499676d,a97c197e,b60fa733,281823a4,2e0bbd8c,ce44b2b2), +S(3ccc6802,cc5fd5fb,82bcc9d1,4e2a2765,f68da87d,7fab7e0,d1c05c68,515fdb2a,3be7e4dc,fb8c734c,d9f0254d,afde26fa,1772f094,43420bc0,aab9e29a,83de67cc), +S(e98bc0f2,d6f9e71f,deb01296,d12a7a0d,b617e5cf,fe2bbc9b,ab166eba,e1a59b85,2fb5ee36,2c01c58f,9a113e18,e03a9e49,5853f5fa,a11053b1,73ebe019,58710ade), +S(5c0bb588,69cb2007,86f2d549,f4fb4146,5656739f,15c8ff95,afd057f9,5db895d2,2c69dc05,b3b5edf,a4d8c3f2,41afe00b,b67a29da,4f1a1301,83c80876,21ecb08b), +S(9c8ef657,972b5330,caa9b64f,7d7c817b,7c0b1047,ae2984f4,3d4f4085,3cd01267,98a3630e,ea6b3bda,c9e9df0a,807eabf5,baa9b920,524a7aaf,2e1e9f8d,8173917b), +S(43b18341,11a7d2c1,d5341b95,4972d28e,e734cbbb,e352460b,75fff2e4,a9921035,3d32e375,40e33c0a,5d4eab42,6849230,22a7c560,3d47e789,30022b40,8fc99f96), +S(89d86eab,b52a84cf,9e53d7b5,270cf9d8,198f032a,e43a286,e18fbfbf,3d0e59ee,bb7b7247,bfb01ad5,fe143967,e5cfa75c,d00a54d1,83322fdc,63a7e29b,5d7f47db), +S(567061ea,2b03428e,d8430f6c,5f03b469,cbb265c,ceb9d999,30509d62,25805515,ab9917,15fcc760,c9aae0c6,5862333b,b886ff7b,b423f80a,92ff44e7,f55f0259), +S(50e830fb,6efa74c4,5460d96d,bb9acb33,df2a3ad2,83602ddf,214d66d7,967bb35e,b5914d4e,24073b29,31937f67,58d69c46,917a70a8,213617fc,4f669622,401b17f9), +S(2bee6cda,ed042f5d,c28bd7b2,a9266c1a,eb502ded,379d4eae,21c8810f,7f8dfead,6bc759a,a1a950,e506c504,86392bf1,4c1d9e8d,c212192e,6f99d274,c1b82754), +S(c4482ac4,508bfd79,b4b6592e,d72b5a6b,f58f1e08,76194a5f,9829cc18,a7959fc6,e99ac34a,91d46cff,e9ab0b74,883fcd24,cc93eab,abfd4873,14920417,1bcb7b54), +S(55bb94a8,70858f43,2753df21,592479cc,32cd6533,f5c7cc6b,73517cda,1814a57,93bdc1b9,8b64d43f,6fdfce00,b8ff652b,ffdc2c75,afc4c95c,ed7644d2,86dd4224), +S(2e17cf48,bbc6b561,3fb740f4,52e2f03f,64a01a9b,bc770df2,b0a4d8a9,71e93fc5,efa5836e,183e1d1,b8e02309,5526ab9d,fb1fc046,92e1ebc,56a6e3b4,4f425c4d), +S(86fa5013,f9928726,79276993,ce380d50,ac17d961,24b48c6,b68f6565,6e39a418,d66a981f,95bf103d,3ee373b9,af27ccde,8fa454b2,1277360b,995a02b9,b7e43b24), +S(6990a5e7,d3d4da2,48f4b621,4d8d3d04,78b9bb36,6647a0d5,3cb66412,120bee3b,5a75c630,d1551aa4,ce9a8020,4ca405d6,dad9291a,e28d0fa5,e14e8df1,1ff79727), +S(1a901e6d,2bf440fc,97075337,b6188f4d,51aba0c1,4207ff29,83ac6eca,9312ab50,6a40d2c3,c497f8da,cbf7b079,7cfa1eb3,80fe0d6c,f3b74a88,7ef912dd,3d8c38f1), +S(37d9f2ff,3f14bd91,3871eda1,c5719b8c,c6e92717,dc97b308,5b0b6890,eab8284,84b05081,cd3c21e3,b36d1766,f133284d,d4abd71f,dbc94baf,33d297f3,a8a238d2), +S(8a430121,8acbc3a8,44436a0f,c476ed74,3548a445,8deeee56,55717e7a,1117166,accdb0c4,aaed4b97,658b77b8,af83248c,85456cef,ad368565,4f73b013,3a258e25), +S(452e5c3d,9c95fa1e,f5b9b508,8a2bd2d9,ad1b6871,5b07d4,d096e99d,22c7fa25,ba4d9d3d,49092858,c6a2b44a,56586ab6,8cf1d7e8,f92a4d35,7b1b91ba,509066bb), +S(dc5d9da1,efd435cc,70c5ab24,994b0fae,75e9a628,a71d1794,ea620d18,83facee,e16e5e82,91f44b12,e6512645,d9ef73b1,4ce928ac,3b4fa30f,bb2e958d,28f1263a), +S(ea6aca7f,b52088bd,7094764b,bcc2c0b6,9ffd5859,e1fba329,4212b0ed,7fda33db,d81cf674,4ffaab0c,71e43cfb,3c1b7ff1,480024bd,1691eaaf,cb5b8174,af824cfb), +S(2bc369d0,ae283c1f,ca38ee72,8a154d9e,62935f97,45f3f043,51800368,651ecca9,b469499,33f679f9,5d75cfd7,94dad8fd,b06d91ad,8c019dda,a819261f,1492eafc), +S(c4c52452,80983e50,4a599a12,782f006c,c7a5fab,5b782d18,b68a7143,ef1a382,a23e7df3,e1443d5,72278fbb,5ce63ff8,b7ac020,1544f21,3c9fc2c6,6c7a7b69), +S(42e4ce90,1240f01e,82f0f4b4,6ce1a1ab,9b26d339,b7a4e128,886031e2,6e6d08cf,61ce91e3,b05dd18f,6089cc3b,9fab7541,d23725b0,49bd16c8,9e468bfc,5af82be5), +S(288a0ac9,72a2333f,f29dcd93,faba3852,c749763f,4fe88a79,601ad6fa,7440836d,fd15dbb5,26ccdaea,7a02807f,f1edd91c,28409802,8f84eb5b,18cbd5bb,1bcc5daf), +S(1f9655aa,5434b9b6,e4b76058,6557e2c6,77df18b6,1a732003,c9cfc21c,97db70d7,98366446,9229d5b1,67bb328f,205260d5,96930a73,8f562c73,707900b1,52b15632), +S(a509bb96,95d4ec8d,93fbdbd2,7280b68,597cce37,a0d71fe7,bc0eb915,41ef6e8a,b28d1ac4,7f548df2,4de2ab4c,271a69da,4b0ae5b1,a4a8c8c6,1ffbdb21,74863e1b), +S(10a2d8da,bc8ca5dd,88b84e39,7a4a3119,61c3470c,9924491d,bf206432,a95d7d79,aed65260,d2eda695,d67a1abb,97d24e96,83ce4a38,46c46d19,6ebf3e1f,5ceec78a), +S(222588c5,3ef96af3,af198f26,34180c2f,13941afa,cf3ffa45,29bfbfdd,3de12d38,648de7b5,76a4d19f,6ebc5785,1c218a59,76feec4a,7b2aa840,6d3917f9,ab364ced), +S(39f06a75,58e5f736,fa6d85ea,6e55f841,8bf722cb,23dfc3bd,3249bf99,471f680d,6e7cbaa2,923201f6,800a817a,af7a74f9,49a8bfb5,70a8d555,d9588c4e,917cd6ae), +S(e6e0f39b,9cde4787,dfd22c28,154c1f0b,bb2a2cc,f67547eb,18117941,d4cf0b7c,5c91c032,21b8892e,bfec7a9a,21ac78c7,2c32a7fc,63882605,5c2901bb,3b99dfaa), +S(d041c732,d1728f5e,1ba5bf55,9e22c824,275d74e9,f58929e1,4197e556,b8855569,f2055dd,9cc15a6f,95874965,3cfe9399,7ea79f3c,b52ca46d,1f887620,c15e497), +S(35bcebd1,45c3cb47,946deacd,9bbb8a9d,b791f087,39a457de,52ac3a65,a2cf459d,7ef44f3e,bbe42529,5f5abbd6,590f1f06,19094a66,21812331,7d025414,147fb9a), +S(69dfb692,8e0a7fd0,4f26d73,436e955c,52a01239,9382c703,e820f214,3d5153ee,874f75cb,aa5ff884,fb3fc309,b15b36a7,df29ad73,efaf66b9,e4d578a1,1b1936c0), +S(4cffedd4,2e6412a6,5f225b6d,1901d551,4c7192bc,7c09d454,be730b24,fe126dd9,db4e13f8,a050b220,81d998bb,98e11bdb,2afeff60,62b69b20,58894e77,f3272ffd), +S(71087039,9e0a995b,baa637fc,d1a58ace,c3564514,6d203182,60539468,702d145c,4a94877,6fefab05,6380f77a,29ae7d8a,bc1bf472,28180606,a0ebdcde,8918b10e), +S(15caab55,27c3b93b,5a708d42,4fad0cd1,11b0ee7b,d80cf28d,1407e82,abcad580,61b771b1,b8290ba1,34850edd,993dcfda,61321cc1,7874b60f,ca774ceb,38c53658), +S(38dae820,1c973758,7bdf9b0,23044555,d0bd3453,702806d7,e49d7196,2efece73,b5cbaa7c,f83b4dbb,28ea4797,dfabaef7,95167b09,3ec173f3,fa4e5269,48cbb5d6), +S(359f78c4,f840f5ea,8cb0b0ac,67dc7f57,84f6cfa4,fbd3dba1,4bf658ca,190ad431,39d7df87,8c9470e7,61f9ccdd,da1bfc8c,8b34a003,89df27f6,354571fa,66a608c0), +S(fc0ace9e,607d11b9,8945c546,2f210a33,586397d5,131cefc9,7d7b6737,aa4cb19f,61cbcd8b,2131e124,292d0d69,e8543867,846dbb06,90ff745c,5ca5bad3,96596a6e), +S(1256fa76,bc6da2f,9ebfcf03,c05afabd,bb43c4cd,eb0c1af2,cfea3267,3f5127ca,9788b8bb,223f13a5,909bc219,cb582232,8f101016,db9a5799,6fe8e51e,a7e4aa33), +S(52e87225,4890364c,d8b2c5a2,34fad84a,329056df,d3131f84,6282f5cd,231c552c,b3227c4,b8932f7d,aa787ae7,c5ee5122,a0452862,43489ed3,8b9dd191,499ea46e), +S(d7c5c4d0,12f6c325,b356a323,1afc6f4a,13e11fa8,e40db671,c3d9683,20d63a41,31c65dfc,f30c4d23,3a0020e2,dd6f2829,f101da64,88589bab,11d50c5c,89e5e04f), +S(71334288,1d40474,5d7da525,c10fc11b,645bb0df,c92add65,dfdf5018,5254b1a6,52245a3b,e4cc60d7,8a029e4b,1e482311,cb1ae091,4bdb5cf8,ec6db584,2693ad53), +S(f97b9e11,1749230d,b6420cad,db097faf,fdce34db,cfb77f89,596086c8,32158e8d,5ab80620,4b7a78f4,e8b98f62,4b2c6622,9746d840,cb43cb04,bb737403,5cb57d96), +S(ce121ae9,b5128a22,917cecce,c5daa168,bdd61bda,8c17818c,ea678b04,35d73ed8,dd63e534,1131922e,6e5de85e,30d23e9b,78c24cd0,bfd68c9d,14431ff7,3cc237c5), +S(c7344dc9,75ada59,ae0fb974,fcb7e68c,d36d99e9,8bbae0b,de3cad18,fec9fc98,c617af54,e38e7c6a,733bbf11,2cfcd97b,58298ea6,d5d1e738,db85ae7,fb6d8d4c), +S(4b1e37fb,34bc0a0c,f0fc8155,96ddb468,197c76a0,fcd61b03,953d3489,79f37359,abfb2758,4f6eac6b,3a7e3230,f758d775,8cd92608,7280aee2,966d87aa,a5d974a2), +S(187c41ba,25c3d7eb,9a0c319d,c82b1c2a,5e80f96a,1e0f6be3,53891e25,d9d2fdc6,3a211ee4,4ee64261,6f515682,f30ab58d,9edccef6,2f9c51d8,48ef14c0,b1aaab1e), +S(69e6d0e5,494e7ab6,5430360c,c88cd478,fd33c196,d5984d29,cb012c14,e7c0445a,ea292c37,99f914b8,2b99707,b3e22251,646576c6,9669e66,74551217,c0266006), +S(acd53be0,92b10fda,f199b0d3,95e1461,cfbed969,303d65e0,fac52b6e,a9e6ac4,3e08e524,f1f2c044,dd581c81,9cf92a88,1a003981,1a08356a,28674c59,5829bb0d), +S(3673cf9a,1b30bf54,4b12e80d,e9400b57,6680f866,d4f40a36,ef7e364,f112de90,eb5a492c,6c7c18c5,b97a1d83,3c48a3b5,8c764572,7559d19b,a49f01e3,204d22a9), +S(29d36d36,efae37b6,96083387,f15e2300,7a1a8897,6387984e,31b8688f,789f6ab0,5a65924b,cc549712,992bf77b,514e8f67,b5b5b677,90654d14,f2813e43,45144408), +S(1f42155d,6be7d164,a376059,36d253f5,b4657286,c70d386a,ce5283de,a3dc6491,ce04e68,bd5ac22f,5ef07b0e,a0034ee1,1a6eeaa2,19d3f7de,d82a5296,84721309), +S(3152b951,db4f3586,994d7e65,fb855285,9401434d,7f9f92eb,5bea66e4,4783bc01,bc8aa531,f83267a4,84fd6485,2a13a155,ba18d89,9a2c66a6,ded6639a,ec856ad1), +S(311b8ed8,66830c54,754cdd74,a9d057f0,34566b1b,43e40d4a,85236f05,3b41808f,6f1b0365,2443f54b,3276d30e,23967ced,42476347,e9a13c19,419f1ac3,10bb3066), +S(348dd77c,cf08f8e6,d3ec8d2b,ef0ab154,f1cb1908,1a497b49,7c44ab29,c2299dec,32774af8,4e29b1ab,ca10560e,b0909ceb,5815068,d4f49fb8,e5b1766f,fbc23571), +S(632e0270,d07e3855,446017ed,d8753402,19e325c5,40079385,1f321378,b22d1427,ee608d57,3c5e5d6b,a78f90a9,58d5ec07,4068657e,e19192b1,5dfaf3a5,54f930b2), +S(750bf219,84a046a3,6a2dc2e0,351fff5e,25cb20f8,1631c91c,81c8c10c,3e251bc5,59388fe1,6b5a4f6f,59fadb9d,d37bb50c,6993330,79be47e3,344f2175,47756114), +S(1957df1e,4a617193,1f1d0f7c,fce46d02,3f0b3f49,53b593ba,bc882368,bc7ee3c7,62a95912,beee20d,43455ec3,69e0b4cd,f8d017cd,520a831d,b045226e,c7302c05), +S(bd846d21,7e08ade1,833ad435,4b5af61c,f987e071,319344f3,6ae78bb2,7fd3dd14,eb6a2269,48ba3378,4a65d1ef,5b643c6c,102b09c1,d3ee4dd7,13d8761c,a1976a12), +S(871fbe02,37350222,fe698501,e9fb8a96,985b4254,8d4c8457,5a9c1388,c3f24d35,c1660e11,5bfc3e2e,29e3c8b8,461f479f,64f60cba,5e7bb363,2cd92127,dd78d69d), +S(e7aa1f24,b4be5505,1321b35e,6aadf2fd,9cbbb45d,3cbfd0de,b990b032,70a58a42,b5f3e930,45efa4b4,54ca308d,f529c526,487e98c5,9bda3402,531d9ff9,c4f618eb), +S(879ee365,67d03ecd,7a06efcc,b7fb2b6c,8e756969,5f369c07,bca2410d,3f909399,1242e4e6,d7da2997,aa102242,16bd3e4c,905452a8,90203a43,60667fb0,c1d5647), +S(853bed4c,db8d5a90,792681a3,f654d2,c7947e70,1b94148c,204128ae,5296b2e7,d5a0bb9a,5c785ad3,faa3d26f,732ea3b6,ff50805d,344c823a,8c8f5f79,60d11dea), +S(2a40813e,c0c0fccf,8488c8ba,add7a231,7313a0ab,923797c,2abe6285,971a0d11,9552f927,f6e501ee,ecdfc1f2,1cf4001,a39e458c,23d5ceb3,c4cd1c3f,8155343f), +S(6a77953,3f265be4,d6c0de74,4137a9aa,cfbdb479,92093a61,94b3249,2a50f5f2,fd6eab4d,7fcf58e1,d2fe6b14,d34edee0,752bf837,f9f1bad2,a25e5be9,df979a1f), +S(1bf253b1,d971644,ae6bd7cf,b0beede5,c17d16c4,a50ec5c,70b050e5,159f544d,34a466d2,6e22ee07,a38928a1,a0ff40c1,d7600771,e4478c73,9820bd84,6abd0615), +S(8bb4c9b6,99634aaa,a30e6792,3d543572,2fbe69e9,b0c8f4f3,febcde8a,76700ae6,b36ad35a,7b47e2a7,1e35d002,49ca67d5,80c6d803,3aa7b3d3,340606ef,d6b0565e), +S(796cc3ac,1413160a,7f5f4c9f,4b4b1c4f,99acda5,ad71e8d9,e9bb772,dc4b01b9,1a674e53,fcc8f8da,a40badaf,4483ff63,eaba8555,2d1f264d,dfc138db,43c27c06), +S(969fbfd4,3d17cf8c,256d3bc,a7de453f,4fce7840,10c2eeee,6c3c3077,5e08b378,8f38eed2,1b64ecaf,56cb0e5e,ef83e94f,394ce1fd,9cec89a5,e2814ddf,127a3f95), +S(590500f6,ee062164,eebad106,7897f85e,75d73696,39156e73,369f2811,acf60685,71060ec,51b9d51a,aa8b90de,6b1f7d08,f446e262,3bbdefb2,4664f98b,c1becb45), +S(635f3674,4654a3b1,e905bcf3,198e9747,d6c516de,ead4fe98,c2f8a86c,4961f5d3,415b4c90,a3681e72,b8ce95dd,804dce01,b1d6740e,9d53078c,9b8144b6,cffd69ce), +S(68d94350,a15ad103,aec6b0b2,792233f7,b0d83120,ee5b1d9b,b481e84b,d04d1a2d,790350d3,32dc0cea,2977e09e,fce1c669,978a2588,9a8d6082,1f564e5a,7213606b), +S(c96e7e8,ec77ee02,335ca492,7f15b99c,e0f451eb,e07b4506,4c05467f,461f01e6,e9a31a45,b9424ddb,9adc82c3,df3d628e,bb1e9979,c9a0c650,77af2678,a6f95980), +S(7917fd53,b5be089,fecb576a,25aa257,c915f9ee,38bfe4b3,f86ff29f,488d680c,b09ce7af,8c77843c,35c5c621,65b527eb,fb28aeda,9a36829a,de905dc,d6f70ab0), +S(f55b5dad,a5205283,88d574c9,629d16b9,7f937bac,c6929255,55fd4497,38a5ef6e,34201d75,2f3869b6,f8db8a88,bb018f54,cb0a6d3f,9f87e522,e22e2db8,800acc7), +S(a257bb75,eeab4ff8,269c4124,db5a9cf1,71779493,7537b46d,52c72467,f9cec60a,f08014c8,6b355789,7730b437,bd9e84fc,22ca7740,a5cc5e81,618499e4,ac74bf6a), +S(3715ebe7,da86335f,b386a73b,c8b7a4c1,4f6e688f,ed72bbcc,83a92728,69cc52d4,976fb0b8,6a119539,90c05a68,49e22544,484dabac,577bb642,a69806a5,39161aa7), +S(c57384d7,29b0a7b7,c9814a4f,f369cb75,1a3d076b,df00dd02,e87f82f5,3dfd6817,4319c981,2610010e,6283ee27,a72f9473,5c10c4bb,d246bbe5,d6078473,b80d665b), +S(7d09cb55,b1a3d446,77dc5ada,4cb7944,c844e82a,45954ba1,ec2dfe4b,b1f49ef8,72571169,2db1e3d2,217e2e24,992882cb,fa11e4e,56c82acb,a1db0d0d,35c5238f), +S(d0a60225,5b87b479,4f2ddff7,a7b32c3f,693065ee,dfc78f35,f8ee1813,30a5319,4fe22384,42e5d371,46e730c9,7b91587,bef5a036,535e609f,de2f6f07,865ec3d1), +S(ea68a147,c69797e7,813b5279,daf2b824,e12a5ab0,69b18f91,f7cec706,c9107264,218fc72a,8e0faed1,bbd55ec5,d1b84912,a0bcd7d,a6367c4a,e6f68d4e,5d218841), +S(d1848858,d2436d03,396c84d0,3262ec0c,e4898a61,86b66e5a,f4e8143b,1713c810,91cb6ce4,c502af6e,eef8be3d,93261cea,79f102c7,12c798bf,8228143a,bc6f4ec4), +S(10883dd2,d74d3c21,a50a3b2a,1243efbc,876f94be,4f749173,9a76b7c6,c3ae13a4,376dc0b5,7c8e454a,eadb8a1c,eb53cf24,374961b1,203175d,f682c8fc,895304db), +S(4ce880c4,f0d3f822,47cef7,7266f02e,efe9d1d7,75f3e1ce,f6bdc7b5,9a1b91aa,8d8f082c,3e3d305e,91eb4032,adb695f8,51cd3ebd,78c8f6b6,cfe87cd8,6dc645b8), +S(7f43f40d,99228e89,29102200,49f40ebb,89508aa2,2472ad89,9e14d63e,69df3cb0,64bfc237,cfd6fcc2,aa1d8d5d,d709aaba,542db811,c4098d,68f8a123,39291cac), +S(91a6f844,6bf0d01e,298e8890,98866445,96e19b74,802fa565,91ea7f7a,3e01bea4,425d1750,17f81fc4,939abfc1,63aae7a1,a9e57623,3853032f,2bca878e,e53f4bb), +S(c1296478,5ef73db9,27acaf97,7c459535,15ec8dc5,ddbdd62b,d85d448b,747b25d1,72d82dba,36b200a2,4921a696,ddaff7c3,16f6027e,516a13e0,ef3c6c12,8187d956), +S(5239834d,63ea0e88,6df2db9,8496d181,1c7001c8,c845b319,309d8bad,7737b4b2,32e24dbc,d6265e8a,902264b4,345bbeb2,40363c6b,731ae6a,a9fa6194,ddf9ca51), +S(e08691ef,b43e68f9,bf315a12,7d5a93be,effbe597,f8c51e15,fcfbded3,72be397e,f304ec86,55f6255e,527f0c4a,80db724a,f4c5fe8a,e7a8174b,128d09c4,1f38bb56), +S(8ba2d25a,18b66731,5f03025e,a79c4177,24ee484,ad281e2f,a34d21ac,ad49711a,a9a0d35f,e6508408,219f5bed,f8926a97,fc070ce8,3e7c8a9b,9e319cd,842f75bd), +S(40a6b491,c6c180fd,fa4e81cf,ca69e9f,b264a519,55796ab7,1f5e1089,79c8f243,fd51d9a6,35be3859,280caf2f,c494e4d1,141b5faf,c54a9575,ab98faed,c8f0d8e), +S(176e36f4,80e9f1b7,bfece37a,55577811,a39e4390,9b12a8f,75b4ed9b,a3c5a7f8,5253aeec,58dd769f,12583d34,70248112,7720ac71,1e9b4273,b4a567c6,f6eb91e7), +S(72ee3556,e5b22f02,9eed97b,ee54c7e1,e3a69fe7,f2e83e13,401c7ee6,dd4b2b95,9b728711,1ae6f55b,1aa1a43e,271c0a4d,e0768689,62a2166c,ffc996e2,d5d2ee8b), +S(7a1aaf5,616ca51,374d539b,d67c7373,191750f8,fb5c512,5d23ae01,3297db5d,430fad10,6e887fff,ce7f8e99,97cd20cc,63abf2e4,d8783da0,f9551a57,591d72e0), +S(b7c2c82a,dffc0544,8a350835,843cebcc,7c854fa9,1dd50429,f0cbfabc,738f60e8,ba5a3066,1ae99c9c,65017efb,8dec5279,ad99b3d8,fb93e1f6,2292fb4a,16566ff0), +S(872247ed,67ad35b0,6fae570d,ec2d5717,f1aba1d0,39400e84,b4bfb997,c124b13c,6d6020c4,cba3bf3a,34d6c831,84ebd4be,5a19bb63,dc2fe3af,458ad74b,bcae582a), +S(cbc1502e,b44ece8f,c641d32c,1206aaf8,4eed904a,8b00507e,338e6017,d7decfa9,105afd03,4ec01247,27bf7159,57ef0b01,3dd37776,dc40fd7,5a0f4385,e26620ca), +S(15768fa5,72722a8d,b26efaeb,61ce7f71,95c0e10a,99d5fb09,fd1ad9dd,bc597590,8f61c181,98218dc2,8b8e0730,ba7aff7b,c5dc3730,30a27caa,d1b913e,36df0a52), +S(52301c83,5f809de1,7bdfcd79,fe3e9518,a1479df0,24a2caf,423b86f1,c685cae,3d171f90,5f13860b,778e5708,c2e3914a,c911bfb4,f70a4af1,2a1b00be,62efe3bf), +S(8fef14f4,100d0f24,b9dfbd35,12d02e0e,f4365406,8630c899,aab5bbc9,ebd6cef6,dd67918a,27d6a6c0,812153e8,481e6a42,b05ce8b2,dbed064f,b82aa417,1b788850), +S(7a4d8983,ce4101db,ecb3dc62,c228d75c,bfcb3283,d575d73f,6bec15c1,8b5cf1d9,26ae5767,13a0c2d4,dc6d4ec0,d3f8c038,48516436,ae5286f9,698bb2fa,913752f6), +S(aeee0e3c,a620b586,c34232a9,e3bc6b8d,f5b72be9,b1303be6,5c07fcf0,f3507c58,d43e4b08,6424e81f,c2b7f809,d17d9572,83adadd1,2bc2226,a190755c,82d010ae), +S(7c97458,6753cba,49ca2e69,905ea7c7,7a6f28bb,f3c7f390,d75aaf3c,3d1eb924,fbe15867,a8e7aa97,4682180,c9083321,5edfaab9,a7addde5,7e5b8037,acc9065f), +S(9428c393,31d5b775,ba3922fc,43cfb7ae,98a6dc54,1541dbc8,bd77816,1aadbc06,f1be710c,5fcacae2,4e7afb36,353b8417,35cee21,8d73310,4d58a19f,7ddce278), +S(45aee6c1,d86ac7f5,b8434541,9c37ced3,ddd54bda,5d8582f,1ea4d2a9,767dd73e,95962f5c,45c6f3a3,22f430c3,919ee03f,cab243b3,f9feb2fb,9f8b00b6,983a84b2), +S(5ab3774b,b840b2ac,e1595d53,d51c5d92,3f7b617f,1bf07ee1,a091c798,20a6cacb,125f6498,1d82a4b2,ac7b1471,a42da473,da38524d,def91d11,a045af83,89d9904), +S(28966b11,43e4d01a,d8a7d161,a3b6031,9165518c,880fdfeb,bc51e0b5,84c3b9cb,1cf95f95,e8422d0c,cbe87d43,b831ce39,b1f79026,14cb1538,a4eac1d4,438b2c7a), +S(ad71d209,83a14eb7,f963d5e9,aea67d3b,f00173c6,b7625b3a,9fc7417,f49a3a76,a72f2b57,fe593a09,2ef5263a,955598df,fc2266e0,ecda8cf7,573ab085,9a82792), +S(f918d962,ce0cc947,2539b1eb,23482e9c,a69b6254,1d0ad633,5c35adeb,cee0bdde,41446862,e8c749f9,559c002d,c42deb6c,bd2240fb,b5b0d4ec,94e0d142,e6ff8bd), +S(f0706622,6367ff84,f7cfbebc,f389d1fa,e9f97aa1,f1acfdf2,d8c6145b,e3a8a159,53af7a59,6fb697d0,2d01d8b9,b0c75304,ce1009d4,7f3c20cc,94123aa7,9c91c813), +S(800e414e,9789e121,2c8b6f71,33027b74,14da762f,8956f347,4eedc170,4e9442f2,7d1ebac5,3088ecb2,7bd8a881,78318e1c,d0ada6f,9b8f503a,57283c6f,b2039e31), +S(2fc35a13,b45daf44,8370dec9,a43237ec,1d7313d8,1113993,7e103ef4,1c90fb78,ee6b54bf,97a32d23,3755ef16,85b1f212,2e46531e,164277c,8769a6a6,2adbf6ca), +S(1bb58cc6,8606fb97,5ed32c09,f668e25b,b4795ce,84ee0e98,5dee5536,b07929a0,9e82d8c8,b37926ad,29954971,8b6dba63,229e6887,14e03042,ac3a5fbc,a8e9fb0a), +S(2479bbf1,e9ef8b33,b1a93153,47392063,19575393,3b0b760f,ed876af2,a98c285e,e58fe58d,3ca3e0ce,23bed9f0,258214a9,51741872,e5198064,af43e106,70567e66), +S(b396e44a,41e53514,411fdd39,6e1084bb,dcda0750,ae66145a,efeae86f,87994254,6536d014,1d2b6a6f,a0425f70,c7374e3d,4fb6324c,931b004e,995ae706,2762583b), +S(7c1808b2,bb1b46f3,fa79d047,ba65032d,7b2757eb,a9b1f241,2379e419,9d4242ea,bbfc916f,cd41f3f,e269d5a4,38bfc9d4,fec0dff7,739ede5,8785483c,c4657faa), +S(92e5f9c0,13a482dd,6789661a,2eaaf396,7c0321fb,1e488f92,44e8ab96,cc7273bc,e2e815b0,f9f43539,3a265354,f6880193,791a3bfe,dda916ca,ea12fda3,27e67eed), +S(6a7ab088,8ea54626,9422c715,e9b9bb43,cbc565b1,ed885200,1e49d8bd,4a79e84b,dea9872c,2c07f8c8,461d943b,cd6328bb,6fd23a5c,937d5f3b,5a87a921,94a5807f), +S(75b11622,ec6cc4e7,6887ced9,dccc7604,8bcaf51,4be6b6f,94b1d7fd,e35b5600,7f654a7a,1be8680a,d94efbcb,12a4ae65,2b0f1859,5c14ec92,df83e72c,cb98705c), +S(ca26ae7f,2b6b1e1a,1ee255d6,68d85ee1,88c7d6b3,87ca8374,e07eb9ff,8bce3df7,958ac803,5fecf72,a2e89cd3,d54e151a,575eaa9f,2e4c1742,a2d8ea21,98c0d35c), +S(e6109fb0,a6d50ce2,c9eee96a,3f5eda11,31af4f00,8ea9b2e5,eaa6619a,9b023517,92a046d0,653d61de,97ea073b,7be72083,1fa16ea4,cdd1f4f4,ba9e94d1,37e9636), +S(a99f3ba5,30d7e13c,f05c77a3,27754420,50b3e1c8,eb92da33,988b28c3,20caf85,8b73170,71d3533a,37968605,ee80b458,5c77688c,70aa6aae,1e322015,e9647713), +S(2ab7b1f,4b81ed62,9c358544,6cb81e01,77e9b0a2,43a4c81a,58e636e6,1df8f5d4,940c38f1,605f9da9,78c713f3,81d578c,88babb13,b08d7a53,f131e60e,fad6763c)}, +{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), +S(109382da,7088d834,bb181d52,fa1a54e6,39177311,fae56ebd,eb3a4b43,f3e95ea8,4b9d8ef8,ca4cc192,e6b60506,d9f7ecc7,a91af4c0,6e976b79,a90ad5bd,a03330be), +S(ff8486f2,d5296a82,16567549,7a46c099,56a1b1b6,15577e6b,7e789f4f,e032e31,7348e2f,b0a04014,2e23e7f2,bfac58d6,4e7b8087,2297603,dfca65cb,acfb7be2), +S(ff0252f,e7993b46,9174f525,27a6d39c,4f7dfd3e,234f7543,4aed99e3,edb8b04c,dd53af80,f6148d42,b5c7295d,150830eb,18d5c213,aa44fcab,8610ab7e,495d079c), +S(ad7b6b2d,faa1ef9e,125ddb2e,27fd5034,a576e565,c3cd7ec1,7e329e7,ebd22f52,9e1ca583,7cc8214f,1a694ced,2f216007,9b621ac6,5a2ed803,cb3bbf94,2e68b739), +S(1bcfea06,6ee96a7,63e7592d,3a9102f1,204408c9,7f191791,6b941a31,f2a257cd,c4f83f96,7e80765f,77b044db,e3488180,5fdb1cdd,294f765e,7f60cb7a,a6fa34bc), +S(95afe13,a5798934,5b22e95c,fa65a072,4e3e2914,88528290,8e99e098,2135041d,f94764e7,99b95b0a,180fd6f2,8b77ed34,699de7ba,ac4d5c74,24bc79ad,abd5690), +S(a0c4fd09,b3c27bcc,d3a52cd0,5e14873,7c49c2c0,c07cbaba,1a4aaf88,417ed9ec,1e7cf587,2ec3b0d2,f24b2b9e,531d39a5,ec30924c,44578b3b,ef82e55b,f432b1a1), +S(837f8537,d9347072,8ae81f1d,c58f6118,53be68f8,21571f83,4ea71bbb,34e7772b,7f16e8bc,fc9d7784,9d089ef0,77dd953b,508e5f0d,393ebdb3,27e823a0,c75d3b56), +S(c3637c50,fa14a7d5,307ef422,2444626d,179fa5bd,7a6702d8,29971cbf,d456c7d7,dcc3832e,901ddc80,874a82f7,e586c7fa,3cd79be2,7fbed643,ed926c90,d9b64b5c), +S(ff4d8382,9f7ef2b,b6fb2dd9,76787ed6,7cf062bf,bab5c78a,a26d5f2f,f8b2057d,64c4f671,73a6b641,7d97aa9a,fd6d3715,930c3a9a,fcd2dfb0,55aa004e,84cd26af), +S(76099a6,6bd40c1b,69009fa4,7e3237e9,4db5d6cc,4409b9e1,88c3a053,1ff1fcb6,5c7ad308,bd5ede4d,bd9ab004,38e1df54,615ed88,2b073aac,f7dadabe,f0d803e0), +S(f9f4f60c,11b4361a,ea15dc8a,19e1db4b,5f249f59,61003300,98babbc5,c74bcccb,26c524b9,1339e97b,b1de385a,b9f96636,2be8408c,65e6cc23,49505309,3aecc82f), +S(3dc564b0,6c5899f5,5e2f451b,feb11edf,90c1b843,523b51f2,686ef705,ce9d60b6,beb5613c,891141ee,a6eaef14,d5f0fe89,dbacb245,95d712e,b157ebcf,5d5db03f), +S(8ba520e,fea14cba,b5cfb96a,f09e8798,36aa60ed,ce5064e,ca04b802,78068ac6,74c2427c,42793f35,7ccd3f57,9e97e85c,38ec37a6,c4838c10,f0e315d7,aec33ec7), +S(1a32f327,c37e1617,2cbbf255,67636e65,c3a515f0,47f5332e,8a125ad0,84259bec,ac94889b,d1ba74fe,41ad4eb,5de079b6,321c3da,b76f1a6b,52382162,c8a22ff9), +S(a4fd9780,b897456b,b59da53b,7a0b00f2,54bc7044,7d0492ca,a96ca1f8,7dc3114c,e09eedf6,25923e98,2745d544,b4891cf,f443386a,e41a624,284bbada,38769bdf), +S(3c627056,5962458b,faf569c,9fd19018,1b37f5dc,4643bcec,4fca288d,e08db385,e6cf1f81,30178785,f3347f66,2cb81068,25e19f7,72da485b,79e697a8,fc822b46), +S(db75d23d,794297a9,778c28f8,6da0ec91,95e75b53,98dbe0ef,be88aa00,a64faf6d,1af59d51,3dea8f8e,8e36c811,28d113a7,5a7986a2,b6471f6,d17efd0d,e7922238), +S(9c16da05,b9020404,2a1ff95b,9b0457b9,fbb8b1b0,fbc23587,7d912b17,e11a0b5,caa3dae2,8c1f83ce,c6b69f1c,e2064fdb,4c74f239,e5793a9a,5428f5f8,bc995b2a), +S(587dbe9,ef3d647e,d0e0ed18,c1cf96a8,a1415fe1,8627b5fd,f12f8459,c1d5645b,b6869014,4e9bac2b,5256f5d9,d31fe1ab,feb3a26c,90abef50,e89a8f4b,4e461cc0), +S(1de4c4af,1aa3668a,13341760,2101a007,26268248,7c531efa,93a87d13,7aaad2c3,604efe65,d1c041e0,fc12c11b,c093c8cb,75e550dc,55b2ac,92371101,c4c5fadb), +S(cda8f01d,3c1a198c,27e29fda,c3fe8d6d,72de1d55,b36a787b,538bbd3c,be8c9709,4fe322ab,a45b3dad,db173c2f,ff700152,4faa90ba,65917b97,cb4f29c0,ab65a2bd), +S(df64862d,2c032d38,f99aa05f,372be0e6,3818b94b,9d17230,a45c4d40,dd558df6,860c2a10,68082744,f4c252eb,89eaf5ea,57cc76b3,745e35e2,a3dd077a,a3cff1cf), +S(d9895b7b,6893b227,e838bee5,9316d1e3,92743663,e4a7f917,ed308d31,e733d171,c8099481,d8badc36,11e9a266,89c46662,4a9c641f,6e954a9c,e57e55e8,7a455434), +S(e71e1d58,c307f1a0,d6060ad4,710ca427,ba47f2cc,c5cbe7e,5844e4f2,2d46e567,d34c97a7,68b60ff6,e79eb12b,94fc84dd,32522c45,99274a54,83a22906,b13c15c8), +S(5e36de9b,62a156fb,c10e9d01,5b0d2e90,a3b0b0f4,78fff430,2a58a8dc,aa42739e,40186760,c68286d8,cdd1a40f,fe0bba94,79bbcd2b,151eb361,9fbdb0ee,ffde681b), +S(9dd460b6,42869b10,740abb12,cdb7b03e,ff9b7dde,f6d88577,1bac50bf,3d2de390,66c5496f,fae9452c,af09a7a0,2c969ef4,f075da7,9132949c,e8b08a03,cace8f56), +S(313642cc,cd17e982,b924eb23,13e0634d,1324a802,bd51cb3f,80d90d0d,17d7f916,2d59ba09,e991279a,c18aea2f,bbdc40ad,23988b6f,d6082749,f3f306a1,94ec89ed), +S(6d3bae15,82708fe,61e09e8d,65318130,686af25b,3b73c60f,def2e585,3cf7c84f,441d216e,b80b00fe,15f2bea,42358150,5fd7726a,12605a2,9bd0d0d,ea5077d7), +S(22f1087a,d2f9b4db,28df386,b93700fb,cc331c65,7cc995dc,990cdf88,afaf855d,8f2377e8,9c562acf,78517ee9,917b6b29,88063caa,bdb7fc38,d7e25fb4,23650e68), +S(973d0afc,7dcd4ee2,9f7dd7fe,b12ec147,156aeecb,9218d651,f6fac991,e738f6af,fdc111fe,32d3559c,9df48e26,f8d7a5d9,ac14d12a,c78e5109,e1baf6bb,6f030a), +S(bc5a2618,f46a724f,c295af9b,5aa75cc9,4cab7d6b,ffb16709,c35e5d0e,8115f320,79f1764b,40dec87b,fc26f74a,36a040c8,752f111b,61827d15,58ea5238,580a8336), +S(fedcacf3,fbec5575,5881379a,54db4451,4a6750e8,b1bf0d5,296b17dd,aa396ff8,c7518849,85cdd0a1,3245d3f5,30685653,3e0782dc,a550d6cc,1c091363,879db1c0), +S(6fc31e9b,d5fe8f58,f2ba7559,8caeb21,f9eb8b9d,394a3fd3,3cbdae74,3b20b01,d17a98cd,3f8b08de,b18a57ac,fbd75eb,de187cc3,98b0d772,32acc3ba,41537557), +S(5ce3ac9d,eaae3874,36b13398,80d3f5e0,9ed594d5,70f8cb5f,ff5893f,11b1b419,8cac7f2,f451e966,a87b294,f0df6e54,3a6251a0,b0862c8b,2d6cff43,fb1f2a19), +S(db689f9a,c54e2f83,aee53b19,d7511624,6195610f,8a4bd546,73ecb7c3,23568fbf,2bcb293c,4d303a00,149f4c2,e4d46cbc,708e58e5,3b1f26f4,9004001f,153621b0), +S(6852395e,84e3b9a9,a99f17f2,bba96758,5d597b1e,18c3ee9c,1ffe50ac,d83021a0,96f4be82,c57402f7,b1f18258,109c6ef0,3ebb2163,3dd6c91b,503c34f3,af250703), +S(baa0ffe4,337a2053,25a06dc8,d502f954,9ab54915,2f757ce0,7ab0f19c,975759df,385a0223,5c82a31e,23b4c721,46ca49e1,f1d3d9ae,5a3ef424,da7982e4,d4ed035b), +S(8652c41c,8898804d,f377f192,9e64fb8a,e2524fb3,721fb7c5,b7f389b,f51ac7ac,1dae8810,fc3c450c,1800a806,83fb3cd,18fb5de5,ddbfcc57,72870867,ffcd0c8c), +S(e57beef4,8ab71788,262d1016,d7caf2e8,24407aa,bd32fcd6,49772c9b,dab0f98b,7557bd67,a381c515,a7d2bb84,f5a67dad,17b91f52,6d60127c,23279479,81552aa8), +S(f5d671c,3e5cafc,caa2a98,93e0ea53,b5cae255,1ca13144,f5cdb793,897d74e3,a455177d,a1c343f3,72ff895a,e0234780,f9509169,ecbcd4fe,9bc7e2b6,77dee746), +S(ad4ea4d9,4cf266a0,62f747ac,a3276163,4757ce6a,2cb1b655,1cd91232,36568664,6e20396d,78a8e653,5d915f77,a1b07f71,6c72d5a6,73c51381,ee2cb69d,8b8177ff), +S(3d000a68,de2bec93,9ecd8fb5,d9ab77a6,247971b2,7c33db,522ad3f5,b1348b89,1a923b11,358a52b9,2bcaebec,f7a60b46,b51922cc,b9c239e9,4713e3b3,455a565d), +S(4b1bb516,196f7c6f,d6b917cd,b8cebb6d,56c4c49d,3f44312,b6e54b43,b51f3278,2acf44a,efb6d3e,95ea394f,18e9945b,e3c79e8b,b3825d96,2b96cc7a,58e357c3), +S(c7edf142,aa3e3fa9,91e92b6b,4f5f40c3,1e802f21,5383bac2,5d90ebf0,74260f,9806dc46,c4c040f5,941e9489,3ff82abb,a0bc425d,44625765,ae4cade1,95a683b6), +S(71f0c9f5,7d2e0048,afbab0b,9058074c,3524ad35,1a9dc2ea,430ea159,eb702966,82a5a7b7,b4e5d028,d748774d,f90b9d52,d7086e37,2be2cd8,916b0d5c,2ecca118), +S(ae7fa0f7,275f4f18,15ec6888,4f358fa6,170f459f,442aba2d,10a8ac0e,829683dd,66c93784,6576d531,a6ba8641,772b6917,9638293d,cf4c2866,262f2221,f8e8a12c), +S(50447e92,2eb7e2bc,f96bc492,6072be78,a4f7d17c,6267f8,da513c57,7e624f4,c4536744,c06a5831,3f75787c,4b854b13,c3d3a4ef,ea09e584,93d10567,cb805ed5), +S(b693791e,4d20ab11,bc3d81f,28f5e509,fa45e1d3,9ac658f5,9a9dd7c5,e7cba800,a078ad71,af8d7312,c1b003c7,a17b7263,6f25e195,4813c05c,b4a05d41,2893559f), +S(4c8c48f,73d8a610,a6cfae50,44a31d86,40f660ed,93d306ed,7942d01b,44c5bdda,c747c2f9,400bddf7,5a96238e,17686ec1,b04a96c4,5031e5a0,68523d8e,16d1143a), +S(87af9f94,4296132a,9f23e471,8961a373,d49c9efd,ae7ca312,d3e28180,66e4c1f6,8251b125,4bdc4711,33b7d9ca,7a079120,bb04144e,a6720b0e,3de93705,32371017), +S(ddb8044c,82842cc8,a2cc1462,c803860c,19e7e40,79a4bae3,9dd7271b,85983012,6bbd6d35,264a732f,824c012,6f076c82,6247b61b,e4248260,99d6a5ab,5e208971), +S(17c12c2f,344e5da0,bba8d9,a5a145bc,d1e6a77d,cb95cc88,bcdb18b8,1accae3e,90fb2afa,a634d199,b11d426c,e974f87,e6aa765,bd98b848,dbec1af,e023afac), +S(dc115062,8630d468,d4c06d0c,6d693470,63fa22a,7a76538,d1341c45,4bc8b0ef,3542ff1e,2359824b,29d0390,e8379bac,43d8e9d1,eb5714b1,91dff000,3748bfe1), +S(7cbbc66f,84023a67,7966ffc,231e9613,9e2db2c6,2b7d2d7e,31d9e785,8ebd8feb,e5911b68,73f2e661,b67d7a0b,3aca2582,db9946ae,b925d302,e1e1c3cf,d9a1975c), +S(72cb29fd,5baafbec,9bd0abda,6f8c53fc,918e71e3,d932eac2,a86f5fd2,49b4095e,d14bbe6b,8ae0ba27,4796d5b4,fc6d6ce1,9a383389,a08535bc,9ddb3220,a04227a8), +S(fb809bdb,a32038c8,d017352f,629fc367,ed1b7eaa,97632e6b,f29a6ef7,6b90a6b,5d4c4958,a28fdd6c,c8a698a6,b7c35773,fda9c700,2776ae,b90986a7,2d65ac48), +S(fb20eed9,22031d48,de92ae40,7537769e,600db346,6de8d72,64610094,79581323,c129d99f,1e32672f,2913bc69,e76e710c,399c0256,63056546,d2332e64,fe6257cc), +S(18b7710e,aa95f5b5,79eb6c9,7d95e653,aea6ed60,3f1f3f0e,f4d570af,621a396a,c1830f7d,bc278840,9a54cb6e,f48966b1,40a4ed2b,54a1f0ed,2754142d,7bd02495), +S(dc781435,efec9436,4d4d3af1,58216ad1,c392a4b5,9adeac05,a1ca9a8b,4a196c60,625b2205,45678f7e,36dc1a54,3e9f9f05,383e3590,cc5b7450,c774226e,fb73c05f), +S(6e16acad,951b4ffe,737c6884,8a59e094,a35f9450,760693d8,9804934b,25d2be1,505091c4,8e00b8c9,bcb50e5,c5eb45c1,d706f95b,cd292994,29425b0b,f3e968ad), +S(3dda4d71,9579a27a,a6980e32,95439374,1af56e38,bb51f165,618af16f,8aa2cb36,c4a0dce1,57b2fca8,2f6eac0b,a800be12,3711694b,4b711742,cc37297d,48d27950), +S(33b53cd2,ba2f15eb,db59dca7,d096d50b,2815cd8a,d44fb218,a750dc1f,63c08130,2088291f,30e861b0,3e566d7,149b961e,d513661e,5eb44cf9,1ab808c4,2dabad38), +S(3ff3ae48,c88bd212,f35fb6d7,b06ca581,38d4cc40,24f0c0c9,f6368164,de246f9e,c177b65d,b99236bf,2161529b,870bb558,a5553f62,1da1c2ea,73297623,dcec6133), +S(1d9f4e25,4ee26361,f5837220,3e4c212d,9f46300,44574f4f,ccab16ab,50023fde,1fc1da4f,8567e4e1,fce5151f,648f31d5,f5cf22b,5973bd56,73b967fb,1bf55e1), +S(5815c873,f3a0b76c,56e79769,54540685,1a853fcc,23b62c5a,6a74df64,c90aa0c,d2c66c1d,b75425eb,8c74e822,d902890a,2d7feb27,f95cde22,648ed311,5dcd756a), +S(bffeb15e,4f70e4d6,b16c0027,eff0c9ee,594b254b,43523788,cb54e8c6,57309213,12261851,deaed15,c2eb62bc,92289c40,5714904c,c291d736,470271a4,24d6034), +S(66b01b20,8d891037,bafaf962,98d6502d,fc05adf8,24731d49,84e59425,9cc9a780,1ad93ad1,984b9404,e2439450,c728eae9,c9ad5c32,7be6299,216ac174,4b838d43), +S(db8a04c1,cbf6dfad,3ccc65b5,19fccf61,a9132332,b6786ed8,5cdc4a32,a7c4969d,2a366e8c,ef249745,fd6a3412,2e7f5403,73bf3ec4,21991101,ef7c7650,a5838337), +S(2cbd46ae,663bf92f,87d280d6,9ccfcc6e,37fc8d87,c586e7c5,891e57d9,9815f71d,40312f04,51f4b2da,ce2dac4,f6c91fe8,209fa78,60bb6247,dcdc1a1a,da4bffcc), +S(4a5fa6b,21e4cc49,83620a2e,1c13a4d,3aab84cf,4e4aa616,a4e0b340,dc1db441,8cb91277,671abe8d,c0252252,665537fe,6037a7ac,8aa142cd,6cae37f5,606313da), +S(48b756e6,3bca3d84,475e90e,23db898d,cf319138,a2bf14c1,a820e9f,768cfb35,e4b5972e,d058b90e,f38087dd,82c619a1,59a42a00,aaf7dfce,a89f679e,96d48d77), +S(6a5157b8,85721f0f,42fb387e,b50f9314,fed50fde,59bee2c4,2a12973a,2fb06b13,7d51867c,834fb385,7bcf64,c2d89094,6784d2dc,e635ad9c,6e902525,ed48f51c), +S(2788ac60,8c691e57,e062972d,398be225,16f625d4,f952f37,2c9c38db,eceacb43,6e469eaf,32db4014,12279b66,181003a3,1d6101af,5b3c24cd,dd4cf420,d71fb38b), +S(7659a365,db31c14f,ebcdc3f7,d8483383,7eb7255a,25b38956,fe013449,89176796,9db1f7f8,cddaed52,178c6d1c,ab762acb,11fc79ca,330638fd,7ee34652,35934b3d), +S(317436fa,cc0f540,dbdb8acc,e9c35266,fc4f01be,b65f3457,9655f1ff,dda3ad7a,deaf8c78,33c26e4a,f1eaf83d,16226488,ad2dac5,639cfe17,2b92f16d,95ca71e7), +S(a92f4493,84a1acb5,fc26ddf9,36b59373,bdbe563d,eb05e446,917a4414,f6e0359f,dfe5c80a,b676487b,b334e9c8,c67cff03,905905dc,a0dad7b5,c3604de,cb456d90), +S(fca66bb2,e3b45c58,2499e52e,d0c12034,2796ae4c,466391f8,ccc81f80,cc8b91ab,12c840c9,b9b20dbf,8c24ba00,59db5469,99f9f2e0,ecdfe4cf,e1f8195,31f0802d), +S(d773f231,295c4836,6c012e24,a825c921,7a1b1657,dd0f3ba7,49a541e8,b380284a,b4ef8d00,66b260a7,7b01a0fc,a4e9b8d6,31265f1b,94834e5c,f778dbd1,ec03e892), +S(af63a268,5669fe68,f3c25538,ae3cb24c,ea5aeabb,51bb6318,ae8f3bcf,3d49d198,ad7f1474,606d40a8,5e4606ee,f95c3034,f64551aa,fcab48b3,3de68f1e,eac43a08), +S(6329c0ed,27a5bc0b,b02eeb67,e79b015a,2d58ebac,9a0270f,559b6bad,f75073cb,a5ffb0e8,12e1f2a,b63c5c30,745bcd8c,cc0e9825,3ea223c3,850119e,74cda400), +S(3d4b56c3,5b51c6be,fb380e04,7e3f05a2,2d5e90fe,55cb584a,aa2e909d,a80b2a76,ff0f8a0b,f6742113,c99401d4,a4f2132e,1e6f41ce,b21241c7,986713e4,4215810f), +S(d84552b,5b70fced,a8053aac,63d2cf8e,7e6abc35,88a467c8,1193eab1,63adc404,d2f36d9,e296f0e0,1f01ac9e,30fa7db7,46a97608,2208d90b,60e4fc00,816a9580), +S(b46206b7,984144eb,a6655c9c,8aaf0658,6083971e,5f77da3f,96b260f7,8dfc4763,ef70665c,b881d9fb,c296ca88,10fbd9a2,17288e92,c0225f06,e072bf53,7830df3a), +S(b38355d3,a0b1cbdc,343c0a38,4c7f0653,b9726bdd,1a3bbd34,2614fd54,409b0864,a7cfc80,895c9ae7,36aee67e,aabe29ab,61223e08,deb06542,62393dad,eb9d4ce5), +S(a423de5c,338efcec,58349f16,70e8ea11,bab0c78a,be0d2442,4ddcd2e0,294f0bb2,e9a2e0d0,90e31783,f2d1abd5,a46e4649,33e3f111,b6f1d3c4,d7b8c93c,5975b2a2), +S(54ea680d,959b1824,15e66f4,622b6a2e,1dafbd8a,1756fbbe,d622ea43,e443c673,5d57314b,44923737,9e116877,e6f74a31,63a2ee66,44c74e42,b8617855,3ca7f009), +S(2bf96fdb,32c84cc5,7a37a941,8f5d8de3,67373eb5,a9e401cc,ab2c86bf,c4a265ac,b0a83c7a,e9ba4985,3c78bc14,8a891c75,3c259c16,4c620a73,8ab2bd3d,7b291851), +S(2425f73e,f25aa0da,588e5a96,51e91bfd,3953fb43,cf1142ed,28341f6c,c0d94885,acec2cca,1798f9bc,2b844f62,5212c411,52dc665b,c6e99704,19108b38,dc9b7cd), +S(d387f2d8,2b130fc1,80f940b8,6bca2c6c,d29fed99,2c3129e2,e1155d0e,415a1e98,af31ff4c,8312a574,9d0a9860,cfba0446,2cc8e2d1,6b516511,1225d4c7,7d388373), +S(a34c6211,815459f5,679b5518,5bb311ea,efaff5b9,cc0175bf,ecf58957,f616d49d,c88078a8,b1d1839d,c1941e5f,300f6876,63be4a91,9766063f,bfcb1e35,d81b4871), +S(cf8a62f0,66e4d06,f2cba109,8c3267f8,a435b03d,c1900e47,3eeeb3d2,bc3d7909,1e3bd7ab,5445163d,2bf834c4,2a425414,af72694a,be85a1ed,e8c53910,df5ee50b), +S(c9f930b0,a80350c,c66d2de5,ae6a8165,9a2f80a0,6c01fdde,3436a7de,5da09d2d,79ceccd4,8a9c6cac,ad77a4bc,255e7cb5,976d29d6,a3d814a7,e504cfdf,66b3af2), +S(dd05c586,86b98f5b,7ba2c17b,e3507e2d,83c31d80,eadf33d9,291abbac,e525a4bd,cdce214c,5525efa9,5e3f7dc5,8ef4bdda,d0429ed9,c59a8aa5,d520433c,eee8a34e), +S(d432cb8e,276f7e79,36f455d4,6ee3327e,70e6ae4b,a04c6ea4,9dc02557,a40a30f,d2c4a0c9,4a6ff7e5,c254bd8b,d24862ba,857b3748,9ecf2cc0,74265907,2b5be899), +S(a3b51478,dedaebf9,a5f59c9c,d7b4bd69,158c5c92,9511c5e1,d4ae7a84,b57a5d9b,e766b796,15010b2c,83a69c19,8c524b3b,10780e8b,e4fc62f8,a2ecabb4,f6fe3f51), +S(39f79580,7530e55e,3b985e2b,763fd21,78ff03b9,56b02a42,faaa87f,3100002f,bd3d83a4,e01de784,c2d106b,e645ea4d,5b6efa85,a52f17fd,c82bfde2,79761c93), +S(a3382f,9f706246,7ff434f,54e1841f,a18d8554,c3011852,f4803343,15c6a360,e4b43770,354c7ffe,29685ebc,64272360,8447cbbc,279b7e67,14bd9479,5298a156), +S(6d09fb4f,a6228cd0,93dab47d,99435c7e,9c6e2524,34c59792,bb2dd18,448a2bde,1f047149,31b69744,d6f7d61e,43e44853,6577fc6b,c2335282,109119e0,d5978db), +S(2a55377f,875e99b3,8d7c0afe,eb3e7491,1f8e41cc,8acf09d7,e9bc9763,697dd91b,14e2693e,81e893e1,67045a2e,a2be9a41,faa81fee,9e864071,f672c629,119b10db), +S(da913380,16f20888,9bfb4371,82ec0b6,1efa4d6f,14eb6f3,808c6b81,2336be7d,1776f0c2,f3cad01a,a0582732,2d2136dd,7e6020e,237a1329,6377b1a9,a3f411ea), +S(fd413737,14e6b895,9a289039,3370617f,37437de7,5c3061e9,4bd5d61,d1dcb42c,56b62876,86af6b96,a73e041e,2c45a439,468e5e18,2d91d9fd,1222d732,eaf1dbf4), +S(d39cd710,47956112,3e7679b5,cd14f400,8e1b6524,8d16d1,9b4313fc,8af4b38f,ef65114d,7e747603,b9ae1127,e1fbbffa,f488462f,3aa38844,dbc26e29,abc314e4), +S(617a173a,528ce0be,77371444,9ebf2d76,f9b58ceb,6ac21d58,885f1dc8,693870a4,52715ae3,ce098246,c6f08660,6e9ebf94,14266165,a354d81e,fb48c9a1,13688e21), +S(1350609,6f5c3382,b280837d,e640c142,65ad14c2,d06a95a1,4838014b,12569784,ac6f4d30,443fe46e,236f331d,980ccf92,d8fc5928,48a75841,c7e9f328,6b25f8ef), +S(494ca163,2000b61e,f513c04c,6f0c2e72,565fb1d2,ed371c25,8de1713e,d467531,611b3bf6,6b9efbfa,f6efd046,c426350b,cdf5536f,4134cfb9,1b4a3225,b2f096ee), +S(3fb9cb47,b84f05fe,72df9ab2,32bd4e83,da049679,ae09a93f,4081cc49,660784db,d9628fcb,1f9deca8,79d19c37,59845e55,94effc2,f0364775,9fe3838c,2674cec), +S(496f829e,b09f2d4,ff69b9f,d4e058d,de547d2d,8cff573c,3728cabb,eb59e58b,64bbf6ef,fddfb044,6e20d42d,4b34b3e4,8823839a,be3a0fb1,2654b8e9,b13a89f5), +S(dfce1042,841252f4,d1524b2c,817f3ce8,85821df9,913048e0,21aba64e,eb10799,118a24dc,eebd2a19,df7b2b0,71fd3073,e21c68c9,2aaf61c8,1fe1afd3,13dafc47), +S(2c1b46,91eba809,95ae941f,70cd60ff,a8988faa,e115c265,3c5b94a9,1e26a0d3,6c50b88e,cdd60794,32bae140,90afaee3,cbc38f76,7f7c5463,c244f9f6,54375ec8), +S(f8d91c91,1fbdf774,6829c779,cc7eb877,498b42eb,fdc8dfa4,3c81eb58,2983c45e,b80c785a,d936896f,504215e0,92eb3365,344d9a6f,763e1361,a34fcd5c,9b489f7), +S(cb9e013f,95b3ef75,2a9a15a3,5ff471c6,6d25acf8,66e89c79,f963666a,c299dbeb,3b117868,5c7e93fb,6c920f4c,25e48118,5f3e8f22,552b4e13,10dcbcab,e0e31d2c), +S(6d3a170f,6be4f0d,6c915593,7c0c7e8a,d43def0a,54876947,a36ff7e0,3103aef8,6fc40770,541ef68c,1d8e63af,18d99209,9313c6b6,6e1fdcfd,359c3a88,900f96bd), +S(ab498e5b,49558ca4,2099c7b2,14c070d,8d61e649,73fed001,11b526eb,c3ec6474,189c85f2,b1b63783,877f008d,b2ebd590,37dbd82d,865175b8,5b6376c,b2e265b5), +S(6d969788,f5204548,d2eae98,87cb5e1b,429a8fa1,8f44cd3d,32f36699,a9ce6671,a08f674a,8de23cec,d0c53cb6,29cc24ca,8c5dcd42,4ae8a7d2,8d43f2e7,57c70317), +S(3b5f696b,5d15291c,75f915f0,f043a622,1cd58678,6c7a0ae8,4533c0d4,d4ef7b58,7aee88a0,c4dd59f2,303c8b80,ed337b67,da3b33ae,fdb66c9a,3952df26,443bda02), +S(4905bed0,798f2ffe,24decf40,d3695efb,deb8fb3b,bd734395,3b027e71,9b8d057a,4365db64,4c598c10,6e4e4e91,f67f44f3,bb62140a,b5298f79,2ce32668,69ad25b4), +S(e1cb11ee,ecf54858,85575261,b749e51,db6cc08a,347fcada,da4dae9c,b6709ad0,a02e375f,da9346e9,f2473432,d74debc2,f70f5727,94027b27,6a699f0b,6206cc83), +S(53e44395,533e62a7,3f97e7b0,d449283b,7151a653,1b13d03b,154f458e,c839c5fb,ac3a2b9,c9c3f174,ec24deef,e16d8da7,f04e7776,9599207e,5fb71eb1,4dedde61), +S(5946135b,230ce11e,d28d5222,ae55d780,dc8d2fde,53342755,76546af5,d493426a,198b96aa,f9922a55,5910b8e,b8bdafcf,d700b230,aa926f90,625ebb56,4a8e488f), +S(4a238646,f0d38511,6d1b997b,6085d90e,b79b1289,53861526,55e60f79,6d378304,99da664b,5f5174b4,1dd056a9,9189e563,55d04622,17d5ca49,c61d01a4,48c94c47), +S(7234b856,dbebdbb8,f20c1fd3,4b719188,7d4ae91,3c596418,2a8455ee,d8fa34d0,2a6b196a,2eb98ca4,fa3ab40c,2b96ca16,eefa888a,5cac8676,d4f4680a,3f9c2b01), +S(dda23494,413dfc0e,f09cc4f4,8e5968ed,f9366e4e,6473afe9,eaf26c0b,7c50a347,ed097195,60b470b0,399aa60e,7210d398,eed8d9ee,1f410b36,71e2485c,c7e218c2), +S(8a8c177c,4617c43,3fdcc6c0,8685bed7,3dbe567b,31773907,acf77cdb,d95ab7f0,27adb686,1572821c,25b40be6,524fd3ac,d801877a,f689f4d2,aade7949,fc3b2248), +S(c40b2617,dcf23ff6,f1bcb76b,dd96a198,7e6ba559,1b14b267,42d5439f,653eff49,eb18ff9a,61e73c26,3ab4eb64,aa53a301,97325c38,2fbec2ee,407af143,7e102468), +S(eaa452cb,813053ba,da8be243,c5bb6c76,f3a2e87,97a5f83c,af7d15f1,e07d8088,15fde99f,89d0c428,979e0b96,83cecfd2,52117580,1dc8f7b9,ebbb1fd9,f02199a9), +S(5fdb7a4b,1dfc0d2e,42c10078,25da5cd5,a3b90346,daff2152,3b9b75e2,d1855fba,3dc00aba,890bd133,6ac4d676,9aed62df,db9a281d,2412fb9a,8e9aeafb,58bbc5da), +S(6f7cf42b,f4b09098,26538863,6c24770a,2c7789f5,dd1ffc5d,5382bc1d,fbb6df44,5ea4dbe0,dcc4a01d,4d7e6660,3026fc41,f0dfa1b,893d4934,5d05d75c,6faecebf), +S(1063f63e,51e3aad3,bf91e892,8b1b8fe5,1b941177,6580c056,60361280,63fc7629,6565cca5,5de4a54,777b24b6,7753a880,7155d632,5bace707,dabb9062,3bdb9b37), +S(f0d88838,9ed3ef56,688985b6,6077fd8,63f2e1b1,67cca7b1,e135a7a8,343e6b55,1764653c,86deecf0,ec350009,1f320d07,db1ff9a9,dd497488,386b2006,e12d2ad0), +S(9ccec5a2,869a95ed,ac9e3dfb,c19c552b,5f04ce3d,5478b16d,c28b6fc6,8b8ba0cb,838b79c1,25b010a3,624be75e,89dedc5d,9b6385e2,65f4283d,93a5271a,f896d0f5), +S(22427c29,2f19da5a,3e4a0454,9b3b35f4,901e2ac4,e073943f,5c41c733,69d5fdc,493252b7,a0a13723,baf56860,949490a9,15f2ced1,cd5c4207,9ac64efc,c94c518b), +S(78041b80,76e8935a,986a269c,68fb1bca,66d1f84b,3cb75ae6,bdfc7428,7ed74b9d,4a73feac,2a7058a2,f193e338,607c4f39,41aeeabc,d1126f0d,f4917623,afa180df), +S(ddaf719d,78d58c3,ae253ba,9cb24640,7c589367,af122d0d,a9a38d25,1d1aa757,8f7e649e,ab08bb70,f052beeb,46321ccd,9f8fba5c,e6e81dba,40b7da63,d3aa8c63), +S(3e28ec5c,4d9fac25,17b857e2,2d1e2c3e,fd9d507e,3619a21b,9d957588,769e5257,fe8b4326,fa187a9c,fadb417f,94914cee,b689f1e6,86402e88,d5a8b8e0,d9ffadd7), +S(2c659f7d,37d2ac1b,e372dee0,f6cb4997,c7dd990c,e8b1f06d,79b49aa5,a8a83ca0,c90bd67,dc1faad2,ab4086be,f7a6b310,39592bf9,3a949f0c,5793ef46,d9136fb8), +S(d4afa87e,2dc5a4aa,d001b27c,87989350,1afa374d,85a2002e,e5111bf5,d7da03a4,39d697c8,614df67d,295d7fff,20a0e333,6045bba4,6d565962,91665f18,83816707), +S(12de6449,860786cf,215f9285,a28946dd,668b0ed2,f8a0012c,c785f441,3386271d,39d68f4b,42aa5ca9,99c1953e,c216418a,7a1b83bc,c534cd8f,f50dcb25,2ed08d61), +S(19e539ec,986bc292,c0993b43,e8f03988,81fc72b0,53d530d2,812c971b,b53e35a3,41e96a03,31462b0e,e38f6a2b,774e154c,22ece598,7400c199,4aff2beb,340dcf8e), +S(3a6d63f6,e0083404,c768869c,a180b659,3efda9eb,f2a38385,7bc32e84,5e7a9f63,2897d84d,a8a13aa2,e2b96f22,d97fac13,5e65739e,ce341c1f,1e188d0d,6b29d765), +S(6fbf7d9c,5238b959,1e29dde1,cd092621,86a3f216,c8252b7d,dae85433,b08e642a,7a52157a,6c78af5e,2b9c21e6,64aea1ad,36bdf11a,459e2fb8,205fb818,d6f635df), +S(6bfe3a73,6211e70d,78be3665,fcdca331,a73d6a3f,f2cc9e50,df5b87a9,737b6d1d,1809c07d,7c997a60,d2bc187f,7ff527ff,8f162fea,10475684,6cd95920,5233391b), +S(c6f521ed,441c39dc,23c11ed4,5399ccd1,4b83e00d,524c8163,8cb0c0c7,ecd3a0c8,dfccf249,6223886a,e520ed1c,d84f4663,b44aab90,85ed836f,756a3b16,72775f4a), +S(be39757b,c2537f0f,c4c67c93,f2dc2830,b464d3c2,672f3d96,8051db68,57e6cfd9,30047462,b2f2ec23,2901060e,b05f6697,78fa42ff,ff05922b,2c253927,4d350a9f), +S(8cf591a1,9c98e274,a83cc687,ee992acb,3255320d,e3cbbea6,57fc790f,a2b84d0b,1f2d8a14,66b75c5a,34e9ba8f,6e96bc0c,6ab5e9e,e704919b,96a8d2e,87e29f81), +S(339c0d5e,5e28c33,b298bbfb,73ab7a8d,89f4b1f2,6ee853a,83d9865f,3480166,b63bb64f,7c99b7d1,15430fa5,125552a1,201fbe11,c1b90f69,a539e6e0,a8c2bf4f), +S(7ea652d7,c3309dcd,70f21d5a,e0fea7fb,81790527,c75a51f9,a37beaf2,ce867e72,22974b39,a028964e,97e00cc,7ec3491d,fe9e010,be520d4a,f2e8139a,1c602296), +S(23975673,c1723378,ecf11bbb,90d963dd,ae855472,2321c50c,eaafdde2,2a825762,2d1cd4b2,3aa66041,8fcdafe9,25ad8486,5912b905,b77588b6,deb97db0,effc7ee3), +S(52c0516d,6bef62d6,debd0879,9c96714b,85ade01c,1748053c,2e4647f8,f28e4594,deeea364,bb534e70,b74aee1f,95f528fe,e0b8c239,b6a0c228,1d4b5538,41f0bfc5), +S(a19f26a1,f4fa9b9c,42ca111a,a2b9492c,b95a792d,d23fabb7,e76ad6b5,6117a9fe,10f990c9,e9554447,ab030a5e,2db24dcc,80f17142,aa450d5e,930851fa,8eaa9a40), +S(366786e5,76b32325,1e44e4f6,e5d71c50,5361f771,8e355e3a,558beaa9,52d4a1e9,e76bb0e,ec2325f6,144801e0,d154bd6b,68701212,7233da5,c0daa306,2217c839), +S(ef26121f,f99a553b,ecafaa00,95d9e06,92fac8cb,40ba0331,1eef3b0f,eb291181,5d32068f,a1e9bfa1,487c6993,305e766f,82855bf6,b91339e0,f8804e01,6b6b8691), +S(5d81302b,9d653515,2e54d2c2,10d8dcc4,3a28393b,1da7402b,30410551,21f19b41,5094a844,9dde9d3f,3113ef85,9a0bd7b1,d1756646,bb793080,3007b2a8,f9068fa3), +S(c15513c2,652f8de6,ad273db,67312b3a,6c6c6ef3,7deece21,2703ea2,234cd929,64c2fca2,a392d4fc,ca8402e,146da89,593a1e7,25e34bd6,9c577238,30c4a449), +S(c265755b,5f628680,327c3b04,335a4b60,dee266c0,dd3bec93,708a20a3,c3ac9c1f,1367223f,dae8a304,b32c97b7,505ffc23,21d94115,579a8ca,638959d1,34dc21db), +S(d4acca04,42a53b23,ecc67ae5,d81d147f,ed477480,609fb71d,f0fff78c,20adf544,8b0aa74d,88f9fefa,affc2acd,d36479a9,ac814b3f,8cc3d01f,749ceb0f,9a90f052), +S(2a8cd5bb,2be61c60,615aba87,6df1508d,37f61b15,2429d10b,1f06599,dca26b94,8e6cc5ca,abd1c09d,4615cd80,a582bb71,156be2db,4876720e,6ccae849,5990756e), +S(74d6c1bd,65f37304,360b58bf,c443701e,f2be71f0,b366bd38,f29b876e,954f2f40,4cb209e0,6aa2459,4583b12,8572d25,1c88a2de,6d54057d,19c270d1,bf9c8077), +S(4baf4424,d78546ff,9b28f46f,ab97ca02,94ca48ac,812f13ba,7cc47b4e,ee9eabfc,b4910b45,5e06246a,c99febc8,af1cb0be,807127c7,28e29c16,a94224d2,b633065c), +S(c69cec47,387ab1ac,d20dba21,54625cf5,d42d189,3cc782c3,234e204c,9b7f28ad,514a7b5,fa667f36,bf4df18a,8ced613d,f8579abb,3e90c470,66c40280,85f0de84), +S(7300a33e,7d50b348,c28b4769,8cf8e011,ba6388fa,54a2dce4,7f83968,7b05d5e1,d0ac31f8,1958f36f,9b403154,b6426faf,73078ae2,6c4675f3,19b3bba7,c5c7128e), +S(e989b465,c21d3a2e,60687588,73333148,1e58b3f3,e0bfbcb6,efdd60ae,204e408e,a2d6a205,ada25071,c981db04,f857b005,9f906977,5d607958,7c1479fb,5e44e121), +S(c6afe364,f87a2b1f,92633e44,6b7aaa,74cb626a,79d6f325,263f1b7d,e5af90f1,87197fb9,861d254f,bc8be0d3,afab0831,9064dca1,7e8e1f66,ca55accb,f2d905f5), +S(8a026fc9,1dd4884b,ec8a7e66,cec8b7d8,7b9c78de,127dd3e5,40324032,78f70d22,34cde629,eb1fa38c,d533eac5,fc39bcf3,ae67605a,1ab75537,577a577d,1a75d079), +S(20f33fe4,41217692,124914c7,1750ae1a,86309797,7fb7ccff,93786b98,9e5cfed3,3bd39c87,c3897ed5,52f4a1bb,d8791439,5f1d10b,d827e22,30090b30,7ce9e6fc), +S(47e43518,4cf5e087,3a1b378f,cfa19adf,42abbab4,e0aedc37,2a7b0d0,1033c0fc,aa16a1a4,cadbc035,d774078f,231fe564,53c2b736,858d913f,b90169a5,3951f31e), +S(8fd41b49,adca1b48,574a559d,eb783fd6,6a8c61f8,ddc4950f,883e79f,585351d6,60409c9f,d705fe6,67d796a5,4c0dbd78,41d1b4e2,57f8747b,f69c01d2,7cac9bc5), +S(2091cea6,d9c5ac79,3c3dabda,89bba911,8d96dec1,42f77c5a,83e85c75,d67a5c91,493384b8,83d83be1,b1528700,6f466ac1,b9f5873f,4f99e8c3,b6077594,b8ba019e), +S(ecb086f2,36fc71ff,e455f9ea,3bd542d0,18d6c2c0,9564813c,5da7fea0,81568b68,24603a60,7f05cba,4d10fce,972241ca,f05b491b,dc2f324d,8fa93ec3,99359a2a), +S(364a9ddc,759693ea,cff66ed1,74e7c450,3197a2a8,a743b2eb,b7065e5d,307d4d52,11184aad,92fc83bb,11752b22,6d0290eb,725b5e4a,a2e6e25c,2095ab26,e34764c9), +S(3465069c,a194aadb,e5ae30df,f2d6eff8,1dd3acf8,7a01f6f7,38e24347,b2c6ee70,ded48ab,ac058655,e27a52ec,3ad5b9e9,d1ae3c39,25f0fcd6,b6e8ea5a,f490d15b), +S(ed1ee361,9b6709d7,cf029876,d9ad4ac,3c3bef69,c58476f6,ec719730,1f29eeb2,2c775e17,43f8422d,83b76860,d8a244ca,6a0abbc9,590a3249,1fe6817f,f395fc46), +S(194c6897,27039b42,d9d7a7a1,fc1cc4c0,ae1c16ca,9bf576d0,bab0ff09,c6d478a4,21e309ff,77590d33,9c408879,315c64b2,cfdd06c4,5b744238,1722e974,8f78734a), +S(6e9c1ed6,3fa52d39,74bd11a5,f32c382b,a6ea80c8,109a630b,39cfb9ef,50e92ca,edb9e34b,eb734475,ae167b20,900e86cd,134a2d6b,568db142,22122a54,32ee140), +S(b0db1eff,53cad7cf,ba686559,80c0b90f,6f8f1747,fe53912a,17d6ed61,c696a010,a3f2b2f,110e29e3,8d6a4518,18f04f79,6392b2a8,2d2dafb,6f0a627f,d9fbad48), +S(185fcfdb,db26b6e2,a1ebe2f6,b28b6cef,d02132ca,aa2f53f5,af734cf7,cac6e6a6,754e39e,62471511,e8d077bb,43023072,a52e9fab,d987066c,e5327cb8,a12bd843), +S(434df3c2,cd69896b,fe2ecfa6,6a9c0107,5d12283a,4a34fa68,fa2cd077,da271328,fc13d680,92b22495,fd846672,901e1679,8ec01444,5b25c11b,79ac93f0,423ae41a), +S(c2d222b8,15409db,6a5624a1,5aca06d0,56591dd6,10cb3b4f,bdde456f,608e6849,63a0a035,f5705e5e,17c95f7e,a0a93926,9da8894f,7b4f607d,b47fb04b,bada6261), +S(7c88c681,13468659,d7d89b,477ea11d,5f0443c0,cfa3baeb,6404a383,8be05b34,34b1e4d4,4a29b75a,8f6ba2b4,cf35e7b9,a9953269,30cab213,3f21325e,6f772cb1), +S(42426b3f,833b995b,825bf9c4,ee753d65,ccea144e,8cdf413a,63520819,2f1c79d5,8f188fd7,890baa42,520f957d,a12376c6,23c894ed,e48dc7d7,a8ca9300,77b9df19), +S(560c13fb,86f0a75e,24a24647,11be1c46,d7671f58,fa9c7340,df201d92,5c574518,79f5167a,315097b2,ba5bc761,34f19125,671f67b8,b9b64a07,ee8414a8,f0194ba3), +S(2dee64f7,6cb69a16,aa7245ac,afebd2d,6e46bd1f,4de9af60,fbbdad76,a84f3854,7196b1d2,fa453e67,7fe7a5f5,73e51022,9a7b7539,af0fd02a,b487cd57,46f970f0), +S(31ac84c,e896a814,3a978d7b,ed2a3ae5,d0ce9783,6717ea8c,1f44999a,d6baf5b3,24096db,a006766e,b9be4e81,9d53fb2e,c145b7b5,13cc77b7,8d175cbd,160b86e9), +S(af903e81,1b36c12f,b263759a,7905c2b7,d5bc640,ffba9974,86eabc6b,b639af8d,efa986f3,84f8ea74,2a1be187,55b500a9,22fd9ffd,5a54515e,3e5ce3fd,76d59f48), +S(cf6257f,bca09ea8,34d9da9c,b208eb8a,9d7cac38,5b6dacc3,9863adda,4eaac68b,189b50e,3b68290,ac0657d7,9e885421,e90f270c,3bd0528c,fdcc1857,9f403351), +S(32e61b5,f46e796c,ad8bbd01,41004e5e,81a2b2c2,8446352b,749f1840,9ab2e076,2ad27a1d,ed77dee9,f0ee3ba2,fe97d752,3e974514,ccfd3988,a7f0e1c2,3ac6059e), +S(5079d7cd,fc1f0f4e,decfcfd3,ee5c66cc,beb84197,d1cb9836,e04a7ee8,5e76fb94,5cc95d46,ffcf5873,cfffc0df,6e8c2599,a358fb46,3ea1baf0,225b7fd5,f6a3bf80), +S(b62c8158,5be8295f,29472b7b,b1cda9cd,bd61f9c4,23a085eb,1a31257d,fd72cec6,1d9fbcaf,7fb9e15d,eb992ddb,d09f91e7,f3c9dfd5,d4f1601a,1c303f1a,657c2b7), +S(1c74344e,8088b2d9,1d93f5fd,87a92e9b,9d97a160,2d8bfe33,d8b90b9c,af944f28,a8d98144,3354526d,14d03ae,3a2d2a3e,ad88c0f0,8d9cbad6,666f533f,3cf56656), +S(12cd5403,87768461,8098cc27,ac7e7ba4,9d697ab0,188aa938,483f06e6,7c94e95f,8c0b02f0,1d3836f2,7e5a5028,bb061a32,3389ed3f,fb1a606b,9113c205,9004994c), +S(36abd4f7,7f45d01b,2347a556,ed4c01e7,4c82611b,7e1afe94,13c43e71,29d36406,c160f21c,f4befb28,60ae1ae9,e7da4b16,242b3c6e,f129e309,7b3738a6,95fb9223), +S(199740c7,91588e9a,3c5fd265,19624ff8,ecd4335e,1fdcc482,749821c7,b0301fe6,a316790b,5704bab2,1b6dffcd,19b15604,c30b6057,8543ab6,a3f52de7,ea459c79), +S(14dc3eb3,59ea830a,b8827de0,59db6f55,4319478d,b4750e16,80a21d62,d2d6138d,82c28f9,a3ea5004,7253eaae,2c62df4e,fd4b92fa,17fce544,3c04086d,9038f5ee), +S(6d288843,e16918b2,5895f837,9f75ec44,36ff7559,8a26bec1,bcbdc683,3979c2f4,aa99f61b,59f3f7da,6efd2945,9e09fe0b,54cd2de6,cd70c538,99def857,4e0805fd), +S(9074a3f7,709dc3be,c191f276,a425278,e1d7bbb,a33e080b,cee68373,6f49714f,3eed8639,fdcbdd3c,56ea731d,dd99f99e,77a59ac6,970318c1,7d7c0801,f71b58f1), +S(b9789069,f400101e,6120d9e9,eb95ac97,203bb7b9,701578b8,364764af,d9c4f9e6,afe1ea3b,2634c97f,75e0cc9d,29d9aeb1,c035a048,a68aef3a,7c21bdca,e55c7c6e), +S(55e06b0e,ffe9047a,dd0f2d2f,567b0dd7,d67a589f,50cc684d,88a779fd,c60ebbd6,d0d2b49a,c9347ac4,b8143fde,23b6ab2e,b25b761,4dd862af,3a0d1dda,a79175ba), +S(c81b2c54,96a1db4d,aec6ca5f,b8b0cda0,68a7a049,6fed0d3e,3dea861,27337291,d11e206b,26f9daa0,731b4c28,f65feeaf,8e78f6d8,cf3bc973,873f6d2d,7d2f0d3c), +S(b202ab85,678ad74b,c007535,1016a995,5795ae15,3dc85df6,2d7178b7,e5e37cfb,e6f922f5,6c6944f0,2e643a19,d39c120c,4cb60a44,af353de2,ec653179,9ef84da7), +S(ee0deb59,e956cba8,cb9ca8fe,7c86da8d,33e1287c,616fdec0,1ba68ab9,3de8632c,63af5457,e9b6af60,9b1dc6ad,a19723a1,23e710e7,d03fe98c,5f709c1d,2456181), +S(e7e8f3e3,ca10115e,c7dce3e0,5dbf95fa,f39f537f,b8af8d86,773d9684,8417b28,158c1768,814f518d,a0904747,b96bb7fe,328f8e45,df9c2c35,9f192789,2e7d2441), +S(3b8e4edb,ab45ae8f,17670b3,ddc01fc1,7733143e,208498af,931234dd,c992c51a,e846f581,2a049bbe,94d59a62,dd43817b,fd635e7c,8eb9ca19,80b6bab9,96211c4f), +S(9117c67e,ae125762,75694252,bd88c13d,5aa5786b,2b01aabc,319c600,86b4c26c,c86a9fb,5ec90f3,a2ad0be0,d36061f1,e572e1d0,63034c81,5285a389,2f05bba1), +S(4388869b,17025257,4b754639,a7da1513,1cb9e2a7,b93ffd3f,2b254d7f,430cd1e8,9ce82f3f,4780a2de,f60d4dc1,cfe83ed3,9eac907f,4cf180a2,b829a0e6,292ab6d7), +S(98c583dc,d55186d0,54f3858b,ca84df9a,ff66e333,3fadd076,53cd87cb,66dea0ab,7877ea9,d3a5acb5,553d45b2,55e4ff92,47842b51,4342cdf6,667f83d8,a41b6155), +S(86c393a3,e24b29d4,b26ba9a0,5ce4e1bd,29214489,cde00c4d,1f4ec788,43409ef6,700b9044,8c95138e,a0adccf3,137fa827,702571fc,e1731223,ba1b4ea1,4a37d06a), +S(25d6bf73,6966cdb4,6fb06f43,83c64965,d462e118,258c36e7,76d4e193,13c0cf5c,99a98bcb,d518d7e3,7964dd4d,d677a735,8a886225,28df1cfb,f6d0e999,259e680d), +S(4e3dc2f9,cda6d077,bab34d7b,3dbfed33,5c3f85c,b350f895,5c8811f7,60c61af0,4f35e49b,6b8137e8,58c6b2f3,81ece9dc,de81b5b6,27e6274b,53d6a0e2,c5e01652), +S(4ce8d8e3,5f1a301e,c2dfd13d,43ad1f20,ae756b0b,34ef7bdc,a8f30c70,194f3f15,7e2508c8,324b8e31,2a603176,b1fc0a33,dec501b4,23e73c2c,416aed6e,2b19a3da), +S(2744cab9,e7999a7d,901b91b7,4d221bf8,be41b064,396be42e,46c80536,c5218267,db9b4ff,80782ddd,d0701665,43d94eed,ba19234b,c1881bb,47362cb8,8d90a0bd), +S(90381b83,5adc54a2,d7bc1e27,2f7a0738,dbce1103,db2b21c3,3c45242c,1ac591c0,a3c25f2a,333d8cdd,256f6f6d,d5a7e34,3332e527,50a12a2b,fb00fb37,3213d22d), +S(abdf4e8b,2437703e,6125dfc3,a33d41d8,b7ea311f,fd9b62b0,7546f6d4,8ed7af05,77a66284,1cdc961c,ac1b0990,5877f7a4,28213472,5e95684b,461bac1e,de6bffe7), +S(9f31c9e,6fe48e14,1a9bb99e,75486eb3,5896f990,e247bc05,cb648452,75cb645f,3ae168e8,b4ffed16,bec4422f,43385c17,a83597aa,692b6097,e48e542d,98ea4932), +S(2801ae6b,2083f345,6840a79f,23d638a9,a878d689,39651668,ce82c0f2,e77bb8ac,66f4fca2,c2fc9926,36ed5d9b,5b070607,f0e75d2,8474a8cd,256db66b,d4cd0d39), +S(c307afc2,d2de5ab6,3b5c5d6d,4d25c03,6278716,37f20fc2,175f6631,55172255,6f287265,4d518555,1da8c16b,9d0dcb2a,f0843b68,a3a756c5,5b6716b3,b151da1), +S(e0d0f3c9,866512f1,f78f58b1,8e573d98,6c5d978c,a5f6e73f,75509808,b2b90e6e,3c766220,204ee2fe,9d65a7c3,96e37c81,cd2de736,bfdb6c89,48f59394,38df3cdc), +S(5dce8200,28630e45,1b754c65,8946f4fd,9e4b15e2,e40116b6,acfbd145,29ff8a3c,af743c2e,5f578bea,2c9a6323,32f8fd0c,be7d385e,1e84d6e2,ccc52574,39ff3e41), +S(cf6f6b23,5d10351b,73664b8d,4e2f407a,38fad688,fd90662,29459b13,cf84acdd,c20ede1f,ca2792dd,c5a0d88b,bd8befc1,746a137e,d25defd0,c8b1c5e4,7f3bde93), +S(e73f238c,62efe49f,97359a82,467cfaa7,a7fa39af,35223bf,dc2e82d0,6162b6e6,14ad9128,d74bd306,b91df3c3,c846f203,dabafc11,49d2e8c5,99841964,954b51f9), +S(2aafc65a,f573533e,8d8e1ab3,19c11cde,60a02481,32296117,1455fae2,4f5814eb,a083c95e,cfc67a96,1f3d8b7f,ed66e2f3,c3f6175d,512a38f0,b6d974ba,cbaa4509), +S(f278ec4e,b0d210e3,24abe42b,d1d376a8,244d28d8,614b1260,e48214c6,8161b90b,507cf667,3bbc53b0,d507ff6,cb4a1c79,745b483d,487c6934,4fb4401c,275f4a00), +S(29bab26e,23fca95d,beff49f8,e5b742ed,2b32eece,f7f4d696,4a88b4de,d2b773e6,2e1b3d56,7afd6483,7bb7af1c,7be68427,bbfdae5a,43907e0a,d1f4d3c3,7ce44428), +S(a3a41ab9,8d2804de,81077a4b,73fb3832,f90edd3,40118b32,44a08633,1bd21c5a,5e292792,a0cc3fd,1df5f1e9,7c639cdb,f33b0f21,cf536e64,a2354757,ed523641), +S(3b84dce1,5e9b6ed5,b40cd906,c22a08fc,5a637d96,71c91615,d4038bb0,a3e6affb,7d2729c7,94a19c44,18851c6a,9b813735,f53bba0b,111eab88,b29fa27a,1d189b24), +S(e1a1de5b,2893e1b3,fd7d434a,d22493d5,1479e56e,2bd1699c,30fc8ee6,58c6c13a,c41ada21,d2d07fc4,f26035e5,b4d1deb2,15bb4f2c,d050b300,2d075f86,516a2ce7), +S(23b7c994,1a9a6b03,50707c20,3363b025,665fe450,bf5a89c9,d0dfa7fd,84ea303b,ed7e3e90,c09805b1,46f1f365,45fd2899,ef75f01b,47d12fed,275936b7,e2682da6), +S(56cce967,aeb8e65d,7f2897ff,e881e695,d0260f40,fa8facfe,38c0a050,19e5b160,aad07728,b298e06,ff562b76,70ec1717,c80f136,3ef477ac,abfb3b78,fb655b77), +S(8bd02de,4abac82a,3b50d1bb,7c721a38,9cdc2812,2dfe48f3,fcd30969,4d0f4191,5be841df,84a2251c,e69c2f39,690dfad8,92620119,7ba36028,861f6c6d,d32a93bf), +S(43b066ff,fd91b621,fc9b062,e0f9d362,bf02e492,f764381e,ba49a4f,2fad5662,3fb10c39,cf37eafb,162efc89,f548c8f4,eb5877d6,7e8587f9,4b8b9ce5,9aad7164), +S(89ea2a07,bfc99034,c3e9e7af,ebf87fe2,2d9b23e,e62e038c,321cb2e3,dbb8c7c5,c3069964,6a19d602,7f3dfb8d,9008556d,f969f576,61e562fc,8356c3b2,d3159a50), +S(6c382393,553e177e,164c1f38,d403df46,d05c856e,a41d7d71,3ac0cbad,1f202019,2a716067,37801041,46212c8a,4e6f7716,4c57ab39,df129e77,f31631bf,3206696a), +S(aea725d7,e59c8ce,b646ffe5,d4791760,988e4cd,d23e38cc,cbf610fa,f7066223,e0e7929a,980ca7f2,2fb46dd5,4e1b879d,3e77358,f42208af,d1a3a003,3ba0e593), +S(159ccc54,b888fc90,1f75e688,def8712e,5f79491d,5d47712d,ba3b0c12,ae2f4c84,c1ee2b1d,ec27ac4b,9f8ddcf3,74cf8696,6b353204,690b4467,d752edad,53ff5804), +S(aed9251,982bbf59,d7cc815d,fcdcff0e,76adfc30,61a042bf,1cb5fb3b,60acedab,6e90b10d,a2b23e6d,9a2abdf7,830906aa,d286c9a9,65f28a32,ab9ced92,5c966725), +S(4d669885,c053bf77,f1126cfa,f8db351d,3642c916,1a01d76c,8fb0a20a,3a54adec,6bbbcfe9,ac74987c,2e50e036,74e4ede3,5ea37b79,ab8154a4,396a15de,dd02865d), +S(1240d1a8,a04fb12e,813feea6,d0a6601c,9e6caf03,64df94e7,d2a5b522,5994ec2f,bb502ef,dff84c2c,17dd34c8,909e5a4a,cc1e6e64,aee237da,b8485004,9d09c5f), +S(7ccdef5e,4543615b,a07a8dd6,419926d4,47fb6eff,312d638e,3f5b0363,7d00a96a,7ca83bd1,3f056f7c,c46e6f2d,41ac1e9d,846c5f6f,570d956f,4c9f91b2,8e95a5b), +S(5c30be59,1bdbd093,321d2fff,ec167539,d794e22,d4b2cb53,d33c608b,cac23f25,2e44eb7b,d6a6a544,99b28ea3,865db2c2,f53de940,17e8a03b,e34ed7c8,fc70b64b), +S(fd59cf82,8f64f7d1,10c7137c,5d091b3d,7fbef206,1d2ce5e6,addf2157,c83c0578,9edcc796,7515edda,bbf4e048,5e70bd50,cb9dff87,6753d41c,6f22241d,824bd7dd), +S(5be3a507,ef4b75cd,75158a2f,aec4a5a2,d4cb85b3,92e7ccf,506661b5,5c77e277,92e45bee,9d914f7f,7e687de2,f7eb0004,5e9f9628,3e9332cd,97f5fdb9,a21a937f), +S(d1c94e0,473992b3,307b9031,93785bc1,d2c2d14b,ace6ff4a,8fc7b251,e629d3a1,9cb04ad2,8525fd34,d8fc59c7,280c72d,74fc9f2d,6ab1a5a5,c186f7bf,fb14a940), +S(7db048b3,4c03dca3,7c53df3e,6a94d789,f53308d6,a57f347e,d32d5b3d,4ab3ab03,4a7be537,189997b9,1f420593,add91bdd,fe7fd47d,6684dc21,afbc443a,68a879d6), +S(73005a1b,1ab1f7a1,ffa38625,e0d37dd1,8b54f49,34d38e64,832a78ca,c51b7e5f,6f8b689c,50fe7da2,27cc8be8,cd066588,30d4a2b8,1e80365f,526f590,96508640), +S(34cb6623,26ea9b37,c0f47c45,acb2dc87,92471834,84f9357b,e8d4894c,d4d3dae8,ae989ad4,96e480bc,375d3df,61fb2ae3,a18e6100,cbe1a40f,d090c5ea,8ebcc0c9), +S(ef5c4b6d,cf92cf9a,cd00cd86,63a44223,a49120aa,bc439f72,e6a6a7a2,13e206fa,be4790e9,d1982dfa,5e037c81,ddfdd6f7,802718e0,ebfaacf4,685a1f2a,ff9c5c38), +S(32cab877,84d37189,5ea4e2e3,22586a8d,30b86c1,fa5ecb76,573d5106,bf5f16b7,bcd4f788,20807923,7e5f1487,8d05e2aa,afb2049e,aa4c1dab,8985e413,f758de56), +S(bb183eae,900fb0ca,80e3f021,64e2291,4e40eed6,ceb4d7c,89539ad3,132d628d,94bfdd19,e0bba445,d453a0a3,e95423e5,c7c027cb,fd76df3c,93532317,fe9381ad), +S(605387d8,51ee5aa4,f39288e3,a656addc,72ac4251,5ca1c4a8,509341b3,5819c1b6,55ce59b6,8d58b114,f8a6ce41,86f8a390,9698aeaf,e1576bc1,af37713e,70a550c7), +S(2d971b20,46f30b55,9e8c1638,fde42108,60172bf2,cc088ec6,2c845f0c,4050043d,762ce259,e63f1da,7bb80d4,b23a0368,dd0ee680,aeb90a54,a0ea814d,904b1dd5), +S(5c89b962,e56d242,53a98bbf,14a8e0d9,c9a0a908,635f7717,ec2f2a0f,6a5c3641,28d38188,1e14e248,417dc0b7,5561a875,6163e1db,8517cd4f,f888df08,ab7f2974), +S(3210dcd3,617fd3e5,3da2e0f1,a6d23c20,ba27c0b6,920aea90,bd87a732,8a8fe963,171d81cc,64f4e8a9,ef43aa77,95a1821d,4b672eb3,20555016,dae40ae2,2cf24cef), +S(f00dca15,e2358867,6c9a4b9a,46706b61,af249336,99572f44,ddd87ea2,33b8b6f,3e2e529b,3010ab9c,66c73021,f28b018f,57b270ae,aabd4b4a,a2ec2a32,952125b4), +S(9d69dde8,d344fc3f,74e9c43a,eba9753a,fc22cf58,df6a430,b86b560d,c952d62,2b667455,844a1c5f,1ad56133,99e28380,d8f2b7dc,76f80817,a72ccc87,3f376e4d), +S(4fcfb13b,7a0c8f3c,1c2e943e,806ffe11,850cf942,bc5bade,5b4653c8,9f6a1cce,21e53c12,102089fd,1f010e1b,d009ff34,9d5e4d63,f299d613,d4492763,278ff580), +S(9173a3aa,b16ecd8d,5c3f2889,ddb1ee1c,2a4681fc,35926b42,7411899f,ed851a03,532556ef,794276eb,779b339b,9131f8f9,bea01f29,2018498c,c77ff751,dbc2170e)}, +{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), +S(c20afed,99f345eb,7ef90636,89598022,d06191dc,7e376b44,71036b03,1e6baa02,471f7c90,681c42fb,b2157f8d,629fafd4,87285270,6a4ab39e,c57f0de0,dece8837), +S(c1f66d62,532b6a50,fe1c1712,e2ef2258,4c03742b,7eea27fc,efad13a3,de1ddbff,49001db5,c9b8b3bf,7206526a,3a868c45,1b45eae7,586c3bcb,4685810a,52a62978), +S(684aaeac,cc13fd4e,d3dfa9a5,ebab742f,c5b9ecb3,81b49fdf,afc37edb,3b165ee5,78c2a82f,7e8484b3,9f808983,402c64b,4329c656,49bbdb29,1925baa4,89992ff1), +S(9a5a9331,3591b8b2,b3381f72,7dfa6c5b,343b9e3a,1b1c9c4,c6c9859d,e82fa566,d23e49ad,5099ba1e,58d800a5,c2e658a5,8be77b8e,ee9ef143,c541921b,671bba35), +S(37cdb6ec,c924c1c7,7fd0ae7e,d9baf38e,b46ea5cf,a161c78e,e4673968,f3eff2d2,fe025569,9a9e1ece,42619791,55cb0241,a3d16834,ef35500,7fb55080,53b161e7), +S(7228ef6c,4acd1d3a,d377d924,46fa894b,6f29926,564b33f5,6fc4968f,f66e8ce7,d4818780,533a52fa,13043159,7b22d8f0,b8ee64da,703b9422,e903595,c78b8a11), +S(78555ce1,101d40ad,88c9eb43,292e8d8c,683dac58,fc8779f7,db22d3f2,e2855ff3,9fe09f2e,660886ed,98f70203,c3308dfa,77476e27,e22c68a4,e43107c2,75501bb), +S(b078bfc2,cb4b10fd,31ce86ff,35770aa7,9979973e,26595e95,913016a9,850b2be6,1bfa79b3,f43ca2c9,93572d28,858a0301,716dfd04,eaee12b4,4e13bf79,a73fba72), +S(c3425e34,3ccc9b6a,a260cf78,7a5e15be,5c698894,2370f66e,826fa1d4,8f60a8b0,55f8dacb,54052f3,a8e42190,e5031fef,34c0eb5f,83bb252e,ac7e6eb8,161a0ab), +S(a8360f0e,4d5fc0e,81598e83,6384a5c0,6c871ff0,d1303179,e5c1c0c4,18a2b7a6,1497e874,db0af96b,35a5bbb,e3097ba8,b6fb1bcb,4d30be17,fe7a5a21,97d0dbab), +S(e02a7309,9807dabe,ee04fef8,36624471,fadbabe3,40507d0e,2abe4468,9c384458,59e707a9,416dd50f,fd07ad54,29d686fb,2402e768,3995c25,2ec4091e,c221582f), +S(fce6ed5e,2293286f,a976695e,8871c763,20af09d2,14964d31,318e197,ef80a398,168b9d4f,c9521ae2,51228f2b,f8de1d2f,8b5b183c,a918ec66,3f37f62,497ab2f7), +S(69616788,b5161a84,80f1b464,5f950703,af731632,ef807400,eab00ee8,581adf57,ab0deb81,73ae5e6a,c35a53bb,829acac1,51db1254,f73ebe70,f99d3cf9,7b3499cb), +S(2c1bdd6a,699f2e02,66d68c5e,22d8a504,8eaee31f,b8687858,555d03c8,1633ad2f,ae63f080,98a21f05,f1017956,c9bb6746,7b2d21ac,f3057151,9fcadc8c,c97d270d), +S(b1e45413,b39af497,da71e953,bfd13826,91ef295,da20be6a,2ea82d57,dedf0c32,a3343fe1,563fdf86,22f93d5e,75892e58,cb927f6f,7d3ddc6,68f87a61,96fd8ff5), +S(f1a182d2,994fa6ff,b6a587bf,a8780f4d,69b2259d,456d10df,2e73eba,4aa83567,a3ab08e,99488c03,939bd170,b4c1a7c4,c0cb8e18,1a713c1a,26f0eef4,8ab805b0), +S(840a512f,e5bbd665,83520649,efeb9284,e25fe4f9,9252dee0,b228d360,c8e6631d,899b91b7,2be1b494,1f5035b6,5c85dcda,4efa88cd,83995cf,42674fcc,486dd4de), +S(d920a9f8,b6ef812f,c021d511,ddfca976,436dc216,36792eaa,736be182,fc5ccfd1,ff26725b,21de311,d3359297,97bb6efc,479aa492,a366a1e,a4de8d9c,f0caf4d8), +S(2766bfc0,aa717b82,e7ad53ee,1604c5a6,2fb3bb6a,c7e4d6d1,4c71165,49b3b2fb,7a52c07e,70feace7,6ad0f704,e1d95215,b29b58df,9ba733d3,8a76f349,2c20b5bc), +S(a503f2de,116e492d,2b8e9cd0,e02cbc7a,56ec245,5ca27f48,7d25b316,65374cff,36a0e6c0,4e8092d6,f07fa375,c7874ac5,5c24119,7a096489,766d1d8b,350c260), +S(c2601313,43856496,92fc4795,ba6eb8a2,f6d052fe,5a8a37a5,76e036ef,163b6f6d,72d27995,ee8bbec0,de1059ee,65b8d4e9,9c828bc0,665c76ba,ff333ca,6a619635), +S(43bfab90,2f3a90de,ab1c7fbd,92b1ca9b,577c51ec,d0a5f1a,de461c84,98eed5e7,42cd4d0c,62858547,4852a2f0,7003fd0d,e37253f6,757f4c67,c2e2b22a,2aae375a), +S(3a6befed,24635ded,c7e2a341,64615858,d3b3029f,99a3f257,fe23725c,6a6d0e2f,5101cb68,d4f1c0ed,c4e33e61,e3f3bc1,99f81564,5aa9b81c,ee94e739,667b37b0), +S(67805b9f,4f6b6813,16940582,7197df9c,ee1b9307,5b4ec69a,61ea52c1,788deae9,a2f64de7,3019d67a,5db36099,b40aab16,d87ec8c4,56285e01,49e382af,81b68ba9), +S(e079dea3,f48dfbbc,ad661a6f,1c0a4627,17343004,cb18e5dd,5a7bb32f,a0e9000c,31706c43,77bd9a87,a27665e,12a60711,bf6b5bf8,acbbb29d,33318a8c,df29c11b), +S(f530e1b8,197ba44e,b7e23206,98a43b13,f05b84c5,5e4dc48,aabc3b16,68fd41b7,12995e58,aa0dc86d,15c483e6,5d01cf7,2f6a6cf8,8b53a983,92f4dad,6bb5202f), +S(974519bc,e9037b7d,84517dc8,a0c45ee6,a0e86ae,947b18c4,3dcaabee,7aaf246f,8fb156a3,cde52064,2f03f5b2,32c66fa3,12946f83,5ef77ec7,8739ce7f,4d45e6a), +S(9cde11c1,233c56e2,37e93006,cd42d785,acb74be2,e7051037,1db72065,5a6ef178,6cb6983d,8e86413b,36049815,3e2c8256,16520a1a,aa7a0370,dfcebc03,9c5da20e), +S(6e67fd2d,25a40ad,df954c26,ea452770,1fd49aa2,e7ba7cc7,17bae4b6,1fc11385,a6d2b87a,5367518a,6705af46,20ac9da2,f4c84c63,bfaaf895,449445ad,5ac0bc1e), +S(aec9f1e1,d101310f,a682316d,bb6de79c,bac5a3d1,133051c1,2a681a97,549aa904,305ed459,4670a52,de8066,9c026bc4,993b7b9b,559fb9d6,75ebd333,2608db68), +S(784d5905,e805d9e2,35e0828b,ac0abb12,7d1efc7c,d1b2f22b,304e142e,10132562,d8a6b329,f29221c9,344718c9,35b6cd3b,28aa5ff9,440cd4e8,6841c5c7,1c97ece2), +S(15e2a17c,6ddd8302,71eb8b67,e2cf6b96,2c75f28b,b5d32ef5,639ced1a,b3d6253c,55ef6683,ca7b8cb0,42ef9f48,fe5788f1,4ab256ad,f6dcfc80,d212db66,a0ee89c0), +S(4b003c6d,f6935da1,cd9cdd9c,4d4ab700,4646cabd,b7921125,98265bdb,5e2b5b36,4e621d0f,55d22df3,89c0a5d,13e3717a,eebcebb0,30d94de7,8b205a14,da58654b), +S(3fd57470,cc7d0704,d551224,5a10125e,d94d393b,3a8eaf0f,b18fdc58,e71eb1f2,2612769b,7528f3bc,9da5a240,f603010f,272b5966,c59a7bc0,a9c751ab,8f72f7dc), +S(aed36630,1d7f9738,dd439355,8174e535,de668758,b5b9ce90,3614562c,58c4fb0a,499e8a8c,befd7d93,a191d702,b39dc61c,1a7f6cf6,85432975,cd3fb006,e62a1bf6), +S(2ba768e6,da7c827a,f5456916,f0015e7c,15baf2bb,ec1e8c6b,936e37e9,376bb32d,850c242a,ae59ad30,e566e244,4b0b58c1,2b5f297e,7e200e29,3a8dbb83,9c5be04f), +S(1ba79c71,f162d72d,65821a17,6d97ee10,9913fc3b,8990d45d,5d6b2e55,4a180765,62258299,6d4376ca,5659a7ef,1771e26c,5a672521,5e69288c,ae16d819,4a845b37), +S(fd54543f,f7e27a72,e3747953,368085ed,945e6e1e,8b16032e,351fbcf4,643efc6b,e2619d2,ee6d935a,cddbc0c7,1727a9d,f5aa2a73,ccbe655a,44a1ff7,b362d55f), +S(ddea80ce,6f9e0bda,4d39337,78136c93,5293885,f0564b23,3c98a5ed,90ed0905,8218bacd,e6049f51,b3e36832,145230d6,776f0158,7c275d36,e8bbab59,c47c40b1), +S(d3dc0b5e,bb26fb78,914b9c9b,30b9b42b,69f20e94,fa8dce28,9f243a64,e53fe5f4,942c3ca8,64d9a7b8,cd21a3d8,32bccab1,c9c9b297,b53a8336,45aa4356,8b1fbb60), +S(30a0cb,8e510a1f,6ee8bdfc,f46d2dbe,be3e43f5,dff3df9c,75f96c9e,a14751ca,f43efc8f,7f47e83d,c940b8df,ab9d413e,bc4abf9d,8f8eac87,b392dd01,7946fb0), +S(1a0fe79a,4028b017,138c1649,dd58de09,7adedcc8,c57d4aab,2bd35b36,91566b2d,340eeec,d2028765,e00dac93,ebff2589,ea9bca7e,f7b7857a,783e5855,2a0cc60a), +S(ccd61837,a08fc389,25890e71,b13fd588,58995bb4,49e9b3d,bee6fd82,12ed1d66,92e1236c,7ba39599,3e71d1c8,44cac95a,9a61347c,b98622c9,92fcee9d,2f593ce9), +S(3b706e43,fd96a62,24853ff7,99df5f89,8670c268,263d27bb,1be885c3,be98a8e7,4319b438,ed6d33fc,c9f4115c,1a91a954,744dffd8,804281c5,df713334,7fb2cfc5), +S(d0441778,af56e7d2,91b83760,e024646d,abcc74b9,7e86a390,e060113f,4a01cef8,300e8744,ede079ea,eb52dfe3,f6373d25,6bb3efc3,26d80965,d65d1307,6780c1e0), +S(bd2769fb,3257a88d,4a5f4ce5,e7fcdb59,7e665429,ec9ff117,54c5bcd0,dcea9509,df765e2a,fc7006de,2459d6e3,c7ee3823,bd8bbda2,dcbbad18,7994b09a,5059d9ef), +S(18cb57b5,eccb921,50c8d8e7,5bbbbda5,ce182f40,67197079,3fe97b50,6c51893b,35b98a01,7f4a620a,172f80e,871e95df,b3dc4d,b30f317b,37809f0c,ba9f2b52), +S(81ec0ee3,4d91b585,b7153a61,2201fa41,fba04c7a,50ea2910,ad33917e,b1e524f2,a53e216a,d069520b,b7d4604,9fe3ef35,74c7bba7,2cef5177,11b6810a,a36f7ace), +S(f9a54c96,729a23ef,ad5e51c2,b8870b51,c68843ac,656b1107,49b23f66,fa013e87,ec0e8e0f,1a16aae8,c2f954cc,ac50fbbf,ed9efed2,25ecde21,dc629c0b,415fd93c), +S(c92adc3d,c2b5101,e9ad2ffd,ea2c448,3a39f563,c767e737,a5a34d1c,e84f2bfa,3e3f49d2,10b76661,71d9af9a,51f72edf,e6248022,cd15afe7,f84e6982,a5525720), +S(d0239502,2a0d5c8,f87f9b08,97daddc5,3a9300d2,1e7aacb4,d72dda9b,4564f418,4fb09e9a,3cdb4551,e56c2a0b,9e59f056,c500e390,e47b5d28,fefbb11a,4791678c), +S(593acca8,29588d90,13a41f35,8dc5e41b,678c7411,164c27ac,895fa933,d1db7978,af3c448c,bd72faff,8a52768a,23c9fdf0,68b5855c,d9f022e1,6eb26ac7,454709c7), +S(6a168acf,7b4f3a51,e56d8924,68fa3a96,d0ea4b9a,e191b860,5a6b96b7,d6834b05,f54540b1,f84d6bc6,4dac1240,ebb61fe0,1f160fb5,c00a1b24,8cdddce7,7db419ad), +S(5fbb8d4f,4b3b8d54,a51bb96b,7f58672a,5d2d6145,dd864799,804ef496,17ed6298,a87435cd,6fc5fc1c,93c4b38d,d7b2e565,88e99f,cc32597,9fe0de65,e8af034c), +S(8942bd97,115688a9,ad84039a,3dc0d80b,bdba443b,8431a530,60560745,876c5373,9366058f,5895e83b,9db6bde7,7da94b22,fbeee36e,b24db502,706de359,a81f74c8), +S(3f7a1620,f93be626,690308d0,ce5a3dae,8eefeaa4,63534032,8c3adc5c,4d68643c,9fc70963,c9b068f2,f6f8813,da2691b8,de3d3b07,c7bc1390,8f8c22dc,135d0bbb), +S(29b4db5c,7224201a,9563fc36,eb7b29d3,d6b0b640,b812591c,af21180b,9eeef26f,c8dcc8d9,8c411723,1db961a9,ea3eddb,46a21aca,b47d90e7,e10167e1,f5fcb81e), +S(f05c4970,392d0487,d8ebe570,fc5292f8,685a4895,5a9c75d1,bbaf2a95,49d0a557,f012d939,5ac0d2e2,f694bdac,dc7535,e126431f,34b8d440,b9aaab34,23774ea0), +S(fb2c83af,6ceec5db,edc822b3,4f1bc35e,90bc388a,5a45ae9f,7c256045,d8daabe,cf9e3e2a,30fa7ff6,30e221d5,7fca78,d4f59145,f4e1c063,2798c471,93a3295a), +S(b63db89d,daf39301,f1243a9d,72ba57c1,31fa2cf7,fd0e486a,c39b8190,a48a3f9d,cbb7ebf5,dc68b80b,6fcbd4f5,90162683,cd8fb0a9,17142da5,aba30eb3,1f83205), +S(c3fd72ab,c247874a,c682a44a,938c3d8d,a7ee950d,722ae51e,ae24d6d7,1ec211f9,23b0ca13,998cb9e4,216e26d3,ed9cd144,bbd2bbb4,b45b1514,e5110fd6,bab1bff1), +S(83f1e25c,209153a8,7fd7f4e2,13328ed3,97a93191,311219ae,c36c76eb,f35e2a9,b93a7947,a553a6db,868451be,96988dc6,7a569d6,6237c110,97f132e0,89c73398), +S(1dbec6a7,32838979,b4e7f03,bf791b5e,614800bb,39a56f68,10af5c09,f10c3eed,f06a2e63,c35e3168,4508a3f9,39bcd071,1892b16a,762bcd6d,85c590e2,92bfa06e), +S(56e98c,c2b21625,e9149fca,61e159e,140f9808,bf781c0c,3159cea0,f7bb51ba,c5e2636b,6bede1c3,a22a03b0,818ddb73,5f073c85,105876c1,4d8f6650,92a61563), +S(a6e497da,d0347dc1,dcf24181,efdc40c7,fb18f480,64803a6e,ab9187bd,deb4d305,88983af5,21f10582,3dac18f5,c6badc0,19e724a5,b748159f,1fa20863,9db7d6fb), +S(bd7df6a,1415e150,9759e259,7abb9edf,cebf8e42,97ca092,60200e4f,53ce53c0,90029a06,2b77274e,7ad517a1,44e3355,f08e23ed,a9161e25,e67511b4,9f32d6ef), +S(dd7a6f4a,c529d120,64d1e89c,b6106d06,8d17502,7f6ffbec,411d38a6,dc327745,bd2caeb7,19d6aa06,c97697af,1eca622f,86cf7083,9e425ac5,b7cb23b8,761d9c48), +S(5220c371,8714884,402f11e5,f93dd80e,f8d10333,f9b054a7,14a1d3a3,9664db0b,3f1fe980,d62ffa5c,d50e3ac,d88aa07d,4c9a91a0,373f1541,cca46699,6c0d76e5), +S(177ef38a,cadec4d7,d8ebceba,53a1b938,f3db0579,7c476cc6,19fb208a,1cb582f3,4f33adb1,bcbfeb1e,b9d91df,c6ce7da,6be73016,6148e3c0,eccbede6,dd3a6a3f), +S(3b99ce03,762fbee2,81bff40e,6c67ba55,fa97842b,b175673a,7f08e362,1d6bd97b,ea6ff097,77f095c0,ad161d60,20f04381,b49cc469,c2e54ffb,1f91ec9,d7523108), +S(5864b293,f81ea7ab,688bb9b0,89f9f1ce,244fec0c,b1e2db6f,9c83f58d,5701f79a,7f4f8900,b3b2a552,e452093c,20436189,d88d4493,12883c32,8ad48678,69aaba61), +S(9bd29db0,c45326e0,3ce95b3e,8a1d13d0,ed868ec7,bc3fbacc,6781a4dc,90695798,7c3fc6b9,462ce670,c1f0a604,52c8da1f,47644c51,e56948a0,a4f6c6d3,34e98b4d), +S(3a4143af,3f07e795,2eedc5d9,b3a8d87c,a52a16d9,9839bdbf,b5b80770,38e03b17,aa749ca6,9b2d316e,650384e7,19d775fc,6a1b09fc,be5f17e8,741fa129,1cc73a34), +S(8b668df6,eb568b1c,6608ec61,b88bbffe,3103a9bf,c4dafd5b,16eb611a,d3d626cb,efcb4ac8,ab30efc3,94db1c4f,2f0476f4,81789d34,2db7244,a8f34266,13977aa), +S(d1b68e26,5936b365,67c11adf,259e8bbb,2a190757,86f2fbba,a76d72ff,7cbfd9f5,57328a80,330997e9,8c8598b2,33ba682b,e6baa6a4,69acad09,6ec3ef2c,be6f6304), +S(84281721,6eb15d31,e2c6faae,1b2140dd,e9ff5419,c0555ff5,d0edfa8b,2d878506,75b6ef23,821def9a,912a7c88,74da9c7,6e4fa036,14dd8fd7,9acc639c,ade2cdc7), +S(e2da1bba,3a895d07,fc86b9b3,dbdd657c,b1ba523b,bc498ac0,eeacdaaf,22e4d77b,aeedcc86,52457101,86cbdec4,90850961,9cf09530,15faa353,f22605fe,2acb7142), +S(9cd8c718,34088f1,7f94db0e,50148e4f,81fc4c44,4c9fa34c,8bfb384d,f9c5e24e,440ef0f0,e8e641ac,ff1b2264,21975338,f711ae9e,e6c7e4ca,54d0d177,244c76d9), +S(6bcf2ff,b6c2e3be,54980550,1c8eab96,e27c814e,9b60ac42,2557317c,10419180,88af1c74,ac893eca,a43a0e44,89ed9ea0,c9e3ef4f,d8329de7,4b09eb36,9e6c8f83), +S(79fa7473,a6699efd,f0f498cf,11c40195,c1288549,d069d451,b05ecab0,fb94c8b8,53a59b8c,fef24cae,6c5f324a,19b8c30e,ddf7311a,b76d5266,ce747a90,1f46f568), +S(e3d80881,849cc86a,4d087062,dc5277a5,388f3d16,3c34503d,d6066eb1,69a5892,b6841ed8,c06ebd0c,e99bd851,afc6e2ac,5752d2c6,2a75a30a,ad1ceb1e,c7a2e70c), +S(5a6759a4,cd2529aa,8c656064,f5c5993b,8c4a90c7,4bfcb2d4,604900b,bbc55edc,5670533c,ecae979b,ed06412,7c9b218d,2f880bce,fc3939c,2db3f572,d3d3977d), +S(2c96f255,368c227,46539a06,303b328d,d8909991,a83cb991,204888d4,f48d38e5,3f8d2f14,61d1f778,83c16e42,dfbd33ed,781dd563,bd5091d1,8dfcea20,4e1eac82), +S(534f93a0,1b8b7cf6,28b721d8,af045176,45667ad4,8bad934f,4df6cefa,5327e4f,25c4e7b2,6716a3,718b9e8d,f9233f46,8e8ecc5,2e851418,13930bff,db89c0a7), +S(b21a8e26,f727f4e4,7d6091fa,1e9f3630,688f031a,fd2a7dba,6b1d682b,a87d6f6d,5bf9d718,9dcbb1e3,84051f7c,df28e4a8,2dddc440,fe8e4602,3f67b018,8513a4ea), +S(7d6964a7,3b5bd658,5bf9f92b,b4462e90,39801914,7042048d,8a55d9c7,13e39477,c4f5059f,2aa5a3df,2556d6eb,9172df43,7229a33,c3fc199b,de7395a9,41651c48), +S(5f5067af,90544909,996efe0f,250ed142,de02bbc0,315427e7,27942762,34d3286f,498a6c71,c77a4aaf,7a5db357,3a3379f9,3c9e0120,8ea82f50,936708fb,298cb60f), +S(1a6b6f9e,4d46ea18,2a4edb33,4873ba99,11e28cce,c0607b65,b716623c,e0372e80,84b1b569,5d3d68aa,5e6d514b,71ab31b1,c7d7196,ccef7fc0,797382df,bcb1f968), +S(361a14d7,c66fcb1e,109248e1,568a9ebc,de67e87,40388cb4,d2c1c0ba,aaf5516,2f3b5f71,3c150080,4af382af,e76c7f7e,f42af72d,fa83a83a,b6aa6688,45577afe), +S(b49601f8,50bc8d0e,7bc1701b,82499b2c,4a334c0e,2d8c1960,c7247300,af4a48d9,b5e2a9a7,ef215ca3,de3b39d5,853f4f22,45a4bd92,70a6f193,4c141a1c,841a7ae3), +S(3c509b32,d8095e48,f5a3087a,6bad9223,c891ce6c,fa781f2e,6c8e7d2e,8803e4ff,5945b1da,102127c5,c6dcaa04,dd00d591,57adaa12,2a3958f5,bb4b393e,b82196e9), +S(936331e0,14fc93bb,1f6a13da,3280d955,3f388e73,1ff74be0,ce36f738,901bc8b2,1862e7b5,6e58670d,5f212886,f91cfd1c,be3572aa,2edd865e,1ec2f254,9d784710), +S(9401e6b,c6183186,d465447e,adbdf85f,45e53eec,b1966dda,1493a387,55092e43,fad8a635,545c84fd,76924675,a328bdc2,61add731,fc63d3cc,57e4b274,24cbc2cf), +S(6849a7b3,6e018d2b,c0f9cc06,539ab30e,43c06fc8,6138dac5,751f0fd1,f1a4484f,ea62553f,a9fe03f0,a8bbe82f,c3974335,8bba3744,8d8c950,fabe4c5f,f20e2bb8), +S(e1d750f3,b3ea7a80,b3a42a39,487c6662,e2e73722,91d06ef8,c38b60d1,e0c22abc,8c59f043,5c12d792,8542f488,2202b79c,e792de21,809d12a4,bbd28675,57d827d4), +S(dc2436d4,268fa173,9fefe9de,81c06975,eca56d51,adcac9c4,2d7696c3,4c4fb4d1,86203b1a,313dcdde,a15f14b8,d3fe3894,e45d829e,14a00991,134ebcb,3a2e6673), +S(58892b5,10923690,2c82f057,45e55487,aa469535,984e350,1888218c,bab6e269,5a93b8d0,2633ec94,a2976bdb,238234f9,dc5ea84b,e3da3a7c,e4cfc628,d7cd9b28), +S(457138fe,f2e48bb9,73975346,80cfcd2b,3b8eff0a,a46fb460,9b6cdd96,168d71e1,f7cec976,ce010d6a,c9b558b4,3a715772,dd707c65,a810b900,2bc9cbc,406523e4), +S(b17e576,69ae6db2,88e6035,da4513e9,d5faf5d6,fc7c66d7,d68cd290,416c4449,2c1087eb,ef93f7e2,3f434394,e0146ffb,543f0e72,9c14c34c,8b22fd26,4f1aeb0), +S(f5ad8e6,968da1b8,ad2e400b,878edabb,77078aae,880938fb,59407313,68e9d809,17f5aab7,a6e19529,39294470,1bc75cdf,3527373f,dd6537d1,781a3e16,338e4b61), +S(f3f4b339,4f876752,7e3e0087,80bda1a6,9cbf9027,cbe131bf,c5b238e4,3e4cedb5,fbca590a,86e7d2d3,c784f04f,b8f5544e,8af59e82,d70549e4,dccc2d26,dd5f74fa), +S(979a2c6b,c24a9fb7,36d1ef74,f177f574,a0ec8220,5a2c3b5a,1f62ed2c,7766bba6,e69b9eb,96c2b65e,e91a5274,94368caa,e1480cfd,12711762,2212257a,cd6ce5b4), +S(b6301e9b,512e74be,92695c18,f18b57be,fc0ff988,87ee39c6,31f067b9,13f62c5b,96d8c690,7b48e6b,c7826af1,486c6ac9,1a3e1818,f7310562,86c995d6,4b0fd835), +S(1b1bfd50,1d5c0b5b,8e778ca1,fcd44b9d,c60bbc43,59ea8cb1,6c69f3aa,3a37df80,995d106b,920df44e,3120dd3c,16875e6,d5abe7aa,62c5d956,ee6baba4,cb77273), +S(b2fdd8f3,9a5f8e84,d75d8bca,d8d483b2,a8477bf6,9c12d250,188d30cb,e7ee289a,b0d183dc,4d971b81,51c6487c,39282272,2365013a,c27e3ef1,c2384ee0,2ca97072), +S(d6e43ada,76252428,bac311dc,5b49851c,79b7cfbc,dee6312d,ea051a88,8819639b,8dc6ead4,53c9781c,d297bee2,56c158fe,9aac410b,d7c392ee,367cecc7,5f86f5e2), +S(9de1baf1,ed24b6e,ee76aae6,566b3da0,2124f7c9,d526c3b2,ad15bbc8,3ec90c3a,e299b84a,acea081a,66e41b0c,5e9c84f0,2ef3bfd6,36c5a99b,4b8aac35,b7f71d9d), +S(9d6a8c3e,2247af1d,394ff76a,ad61dc9e,11da8d15,465bacf7,5075a348,681abc7f,880080f1,89cbca1d,460361e6,5388d177,da4d173,b9b3120a,af9dc8ab,2d7602), +S(6a7186ff,70065f7d,540fd40,f3e8428f,3ba6f0ac,678fa642,653adb41,3684a613,1097de94,8a2e3d94,dedff154,11d35a2f,2f75f9a3,2d65d9ac,2f47d174,24ff9455), +S(64f47f87,f05e4b03,d7d15938,1e81691,e337a08e,57169533,2f34ae8c,901760af,14cc2fce,17eefea,4981f14b,1a24a60e,73f3dd79,54ca12a9,64e1065b,c65545a8), +S(37112309,3f6bf796,11d5492,5978ab39,7e4df483,8f96b51c,39ad10f6,fe648431,45d08953,42004dc1,2cd39ea4,e1365116,b51b9ce1,b88a11ac,16295ca5,ad0f16dc), +S(9b2be865,6be732c2,9fd73a9f,7ec74827,6fc9e5c0,992ade7b,df5984e8,c7c67b2b,1cabae89,b28ae0a,6b58cce1,d9881a05,b9ae4847,5ffc3c63,eb145fa2,cb7182a7), +S(c0206346,71a326f6,5aea417f,a13ef7e5,c1054c57,ff7aa6d2,8bd7302,89243e22,ba986e12,86eb62cc,ab595158,7731c1e5,2e420b11,af4c4b9f,7e7068b7,2e8532ee), +S(cb278985,452e2fea,ec881f24,3c43dff,bac7e2e6,e8af62e0,f1a568a0,f6c67de8,b0d0c6b5,aabda249,237f86b8,f3d4aeef,ff32f9c8,2b349791,a090d5d0,4484a496), +S(9a092478,40008754,1cb7db8f,63d00d68,7a991df3,59e71657,984f3303,2b90c577,d8e49ebb,a2314b8b,2da2a1aa,49dac713,15942701,d264ff9c,e57a8abc,49d54fdf), +S(43e63cd1,d6d96399,724cae75,d5ae4fc5,94b12170,5335a3d7,b12afcee,155560f3,36d2c315,93b939f3,e7791fb2,56ea0cb,ff0374c3,be8eae7d,ef015e42,e595f962), +S(bccc009c,4012a2ae,58ac20bc,90ab1c3e,662fc7d5,57eef6be,120b5da2,25aeb10f,2a30dfd9,7b558c12,ab897ae5,5e3cb4de,3df9ffc5,326004e,8da8586b,364ae92b), +S(1753b47e,3e777908,376103c5,266147d9,2334fc29,a3ee15c4,edc9c8a5,38319f92,eaed6e86,c94a0bdd,f85cb9a0,d32cde01,c6ca2bbe,85607b56,fb363111,fed28447), +S(53f163f8,fdde3cc,39ce973,2c909ca7,29c2c5c7,415b50cf,c03a653d,1a9cf505,3ec19406,c26c6cdb,7f327e0f,1936c0e,bf85908e,49ca6085,5c5c2276,b2511473), +S(5e0545ae,f6d3ce1d,90300f33,827fe4b1,ef9277ef,17d5541,597d6ba8,6f4da13a,5207724a,a83bbaba,cd52b920,e5a6c116,552b010f,21cc8c63,d7fe518b,fed12e32), +S(e800d78b,a04fb045,a18a5f94,de52eebb,640b2ec8,a2159835,d2ecedfc,4bdb3b5a,5f3c4f8c,6bb039dc,150aa758,b4957a30,12e2eff2,657172e8,4e76328,45033b0a), +S(448d9559,94569d0f,9fb5ccd4,baf52bcb,5ca776fa,f49a3b7d,e9698fa5,50c5012,f0a64077,c97f82e4,be4d23f9,17b82f3c,6284c71f,82adc6ca,fee176c8,8b601613), +S(a2550ca7,bfbbff9d,4162360c,1274baad,bcd1c213,1ffd1714,7938fb26,cdea3b4e,4f50424b,1ebf6486,c6c5df10,4388a22d,8cdc707e,9485c87,851beed2,45c7f3eb), +S(af94b7e,f5984caa,2a14ccfa,2acbe4f2,70a0cd31,2caef778,c88b847a,be86b9e4,dde4f647,ebfccaa7,d23a5ac5,28cab9c5,8462a761,844bdbeb,e3498494,cbc16b95), +S(d434b5a3,a3c096e2,19f9e18,11f9b7a9,61ef6eff,a09da242,b595b824,5e8a4843,c068f8e0,30ac02f7,69555f1e,5656ca89,71bab03e,d5e6f865,94b3e4d7,37087350), +S(fef398e2,961ac682,8ee348b6,274a1782,7739420e,7bd36925,3a66e468,3fcfad86,ef1020de,b8d58a4b,be7b39e3,5cab7ef8,4e3269fd,248cb80c,85e83081,8aaed35e), +S(5052a736,dcdc83d,35f65bc8,d1eb40bd,7d8645f2,93bd88e6,aa2c5643,4fb77af,4e203bf8,1632f8cf,8c54c1f5,8f0342c6,612399f,348e7ca5,f9d3fb30,3d8ce1e0), +S(4fb4a757,246defcf,3b8752be,a32e819,c11a239b,97aaa45d,7bbdd92a,53a6cc45,9e6e2cb4,e02bb3d1,14c59aaa,c20150d9,3077600a,257934a7,935ceeb7,994f075), +S(518bb638,148f9d12,f0c9fc04,693745f0,656064a2,4d448224,b60d55ee,a405efa,f719e2ab,16fcc1c7,d110d68,3089a1a4,4fb5823b,db814a93,32456534,995c84d1), +S(8a8fc859,6dcf731,3b700deb,3bf9ddd7,f2732bf,e5928752,236df0e3,a9fe4c4c,896502a8,3c112e5,dbc87e63,c5cb73f5,d206e980,c017484b,999513f5,d5a5b4f), +S(47875c9e,86043157,3bc346db,d8076123,274c32b8,9baa353f,56b4efdf,8a5e7226,45174b75,7eef6f4f,70dc9371,40e72f14,832b9b5a,b44c384a,4c4b6063,1df05942), +S(48644f61,57f3099b,5828bb5a,eb886f51,1515191c,5be0dd69,32ec6618,c3870d61,8804fa4d,b44ed648,e398c863,6eac7c25,ffa3a188,71e3bd6a,395f92b2,259f5db9), +S(d5bbe7dc,9efee9ae,392b735f,b2e250da,a03023df,df0d07e4,ec84f829,bce69ec8,b542595e,dcf7e1eb,11b639dd,65335588,5c3d2491,f4db62a8,e099b7f,9c808be0), +S(ef6037f9,cf9770e7,ae5e9eda,9369caca,c7cf8101,d21c4130,cc119219,f2c3a6c7,5ccea6b,22073857,adb52256,1a37375c,b5f4c574,8716e2af,b26b190d,af69a43b), +S(a5b3fc5,2801baea,1f33f9df,270a1967,dff54723,7d7620f3,70a522e1,983ef747,8399a63,6032cb17,3c648480,74227374,dd19d172,57c74c69,eb7bd6dc,52d071f2), +S(a206b95,e51803ef,40ff83c1,8a6ac2f,553b181e,55d03f13,2536f947,7bc426c6,9149110c,5ba91d60,c25c522a,e5aad669,74a34a40,8ddc9dc8,29b5d976,f2c65867), +S(ff9c9766,f459a87d,c07235c3,3ba55ea7,25a33791,bc851645,d289b53d,1ce6291b,51706cd6,de0d2807,81b1d8ee,9ba5ce53,f6395264,6e509654,def0c037,6015313d), +S(ad502070,787ae242,9f4f9f55,418443e6,4386ceae,b20af7c3,7282399f,9f748994,b428a363,32d4f518,56f81274,d7fc023d,b03bbb08,5087b4bd,8c083c0d,77e1c7d), +S(e38920e9,3a1f1b82,f2ac5f01,ae02fcf,7b9cdcd7,d91fe7e6,14be6130,918746ef,cb55c04c,44e66359,db9a17af,780f0040,e34de88a,d10fe04a,a44da778,dcdbb26f), +S(4c0f9c54,ef982c9,be46ea7d,a380897f,c13ea12a,13de7de8,249c7483,88b30747,5f5da3e8,338e9907,c1b71021,b2177b5e,d90db096,15c78ca9,74445d49,dd5f68d2), +S(c9de9ee7,3aa50f40,b5b7b02a,9cf49627,df5196db,e72d2c58,738e5a0c,61725cb7,75a8ae6f,eb47b5f9,21aecf2d,a4bb8e56,7d4588db,2967c612,a53e1c4d,f392ee8e), +S(ab394e81,140e69ae,af0ba047,a6843253,e9875e48,b61f15e9,fb58d3b2,c61206f,a70db392,a3c6f12c,971b61e9,d92dc2d1,1bd086ab,67475e5d,6977d638,110adbc1), +S(39938f5e,24111c15,253646df,b02b4957,84a578c5,2a982a51,40d36d65,8b492cdb,a5e4ca99,a95aaf09,c3dfb75e,5c9591da,c6711e81,ac5d8fd5,891342b7,24b71598), +S(8b6785b9,82dcc8c3,2b12e79,582dfb2,2ea222b,99f3e5cd,dad2df89,8e621571,319495e2,79101993,ac2fc1d5,1770e668,16150e6,ba4fcd20,65beeeb9,169e6f96), +S(5b4e3ad,d62b1ca5,12bead13,113db6f5,52632ae9,163a4724,6fb7389c,e2775815,b8117dc3,5bb1939f,31c93f33,160daaa4,3114de60,df3db6a,a422a677,51d3fa6c), +S(bb1f0da3,ebe501fd,761e2b01,2711effd,70cd1390,7340b800,65c938b8,c938af6,3cca83b9,a6349423,669abf1c,77ca35dc,5c3c6c1c,e3fca31,6a85d66b,7da7c2e7), +S(deca6934,7ed75676,cc85c372,a0612ca9,c3a1ce69,ba67a7db,f6c92972,3b5f4e25,152adde7,67f4877d,2a9df65,8f86b090,2f2550e6,92fecdf8,9574e808,ad4fc510), +S(1e864048,c9d2a9e9,22bdc2b3,6e21065c,6dfbeae3,77712c02,ff015c61,8f65ab9a,cf00e85d,575641e8,93cc385c,7fa70aa1,22530e4,8f111035,6a50555d,ec004bfa), +S(71af1234,457ecaf3,51fde7,894858c4,90f11cb5,90fd0af,2a854597,50a33ffd,36b78c67,2aa4580e,d9e562c1,3dec5d81,bffe55ca,e5dbb208,5ffe0407,b7809ff8), +S(928ea175,c5b56f9f,a3a76080,f87389df,9b541fdf,fa409fae,8583b5a6,25f20421,5e9effe8,4fc42b4f,4e7647de,a1ee4770,2d436ae1,595bd2ce,6db80fdc,30fe2f1b), +S(28f7f51c,783ae428,73e4067f,34cf5bce,b3e53b66,d319fb7c,7165cca6,63e7d152,86c5d540,629a05b2,1583a470,3e9ecf9b,8f5573fc,ac3d04c4,9132c5ba,f6068196), +S(1d7b9551,af89db75,d2e93d25,49553373,79896eea,2d3cd7c8,fd2b9375,b5a95df4,138bc305,58a1090c,8b85cb0,c15130b1,ad375c45,57437232,a5e6333c,9dc0aaf9), +S(9b03def7,22f1df38,dad6f052,e054faf,9852a74,508808e8,38962518,3043bbc8,e9a6d8be,fbd144bc,bb23fcd7,6620164,82667553,d55a8a98,1b9f8f88,d4e5cec2), +S(c158478,636792dd,e24abf46,926ba57f,4d00f7a6,78efe168,5711abb2,beb3bb62,b772b20b,be7f1d8e,643643da,98b6389f,a28a7846,17207748,6d276d08,5bb3f6df), +S(de68187c,c951a366,ebe2de2,8f676a04,266aa791,f3705229,37ef2e19,fa1d6293,f9f28e1b,5ce0f88,66a04e,b967777,bce1cb,76ee297f,4942abbe,88b8461d), +S(1aeafc3b,f66681f3,fdb82d3,f128b12d,58432fe7,f18c92d9,dfcf272,9cd04262,aeb3fea6,b9568a8e,4152e022,83f60cee,7a8fbf42,ac3c20c7,7e339dc2,e6d5a246), +S(1222eef8,39569e79,d101b6fa,c63bc546,ad9f51e0,e27ea0e0,48da9453,4d8d4bc7,9a4790cf,4b561d6e,3143b80,86911de,49acd2c1,3ad7d975,5dd845c8,fb3bd86a), +S(568e3bbe,91d1ea0a,311018a4,b75dd711,45a6bed3,4b3f7d3f,77c1892c,a7e74fb8,24f9853,51477a98,daffcb95,5b157df7,7a8b6005,84a67fc9,7d427b29,aa74ebe0), +S(cc9f0cda,6a3b96ee,5c74785,dc4a5b97,31d0ef4d,10f97401,6935db23,12164399,bb7a50f8,6b530d0a,73162e59,4334dfca,5d1329cc,b31bc05a,3fa68c7,15c76818), +S(bfc084cb,45fb39b7,db0d16bc,fd1ba13c,a133b6ac,691aa545,bbaca6ec,dcc4bfd0,a528dd00,195c6409,6a9bfcdc,95db1c09,b1e5e0e6,6944616a,2334c297,1be07f40), +S(29cd9485,268288a6,4b1e6491,ba211ac5,94289ba1,199d1eb3,a1c013b6,f5d305c5,95283c31,38a01ae0,7cc119d0,58e8b81f,d5fba6a8,8bb4cde4,11268613,86e20a81), +S(c9aa4323,afeab574,a25023fd,a5775e33,8d216391,b10e1d10,31042e64,21f5667d,31f77398,3699d879,a5d713aa,d9b7f2f6,febd54b3,1a69afdb,d3f52232,a72338f3), +S(3a7d733c,9a73b8d2,4acb08f5,48031cd1,b26845a5,837388d9,68427a97,4cbd234f,693e8214,6e219fbb,b31e048b,8dceb28f,d5ea9b51,cf89a40b,d4f8e935,dffe4dcc), +S(2ee63f80,ccfe610f,7e6db9d4,af8defcc,b24907a7,d49d24b4,c3b5a976,73ee9968,de2bfef,b99069cf,fee3cd66,7eb2875f,3660870e,f61c70f2,6ac6b942,4314af97), +S(e1942251,ebbe37af,412340d9,2900a06d,9ced681d,48d81075,d04833f3,9f72acde,85f78728,4017fa63,28a3aaf3,c6e0750e,ac989642,8ed92993,4cf27e41,d3c37035), +S(d1a6911e,72ddf575,d81589ed,b8995e40,b0843840,72dc1df9,42ba5695,8a759b,71405cfc,f836adf5,b8e8c77,e376a7a8,ba0d4478,a30c6600,82450ba9,7264228a), +S(e02062ae,8b2a4522,4ab441bc,7e9a00d5,4b97a9a7,cca4e2bd,8dc743f1,931b81b5,5b6371d4,345f08ec,cb6db1d2,dea7b9d0,7b49ffdc,d50e9b63,23fdf855,e1cd2243), +S(7327708d,b7d3f037,8bb261ea,7db74eb0,222d891b,e14de28d,2defe3eb,a1f64a93,e71c99e7,627440fa,ad4bd9fd,3fe1a69d,5a8c109a,5165e54f,20113643,3d8baf66), +S(cd57d3f9,a726d2c7,308132bd,bc7401e3,f89d1449,57057bd2,14edcfc8,4e25e560,9e23e46c,3760b31,5c117006,99c2cbe4,319e483a,eca1641,b1a29e81,37633b6e), +S(87dbcc0,91c348f8,593c6807,1d0df231,9421e732,58e76672,e03e4d63,d4073660,823edb4c,fe506e04,49403b68,e4a69101,cca82923,82589a99,a9fd3908,8fff07c1), +S(e3499c7a,cea737f4,8359512e,98a9e5b6,2d27ca35,accb8c2,cc65c7b3,ffd28b8,3a2c7591,f0c91dff,e01a243a,986dea24,fbebc8cf,dc0387f5,78988cbf,ffe017ce), +S(5ac29de7,70553d51,284cd610,b360469a,fcc4ef23,bcee5936,942ef27c,b805779f,2a32b97d,f3e8713e,809d4f79,55525e45,65a60581,5fd582d3,82d7088b,5966523), +S(201ee48b,86a8a93e,8e12b084,2fb9cc37,25e4478e,b9d6d10e,cd1f220,c4a128ce,390e0cef,e6b561a6,6f58c07f,3569e8f6,6a467d2c,cc548281,cbd656f9,f7fbf73b), +S(8f64a6ee,3ffa42d1,e55aaea4,9e00f260,fdd33f21,394aa31d,c17a4328,87ff50cb,867a0189,2f55cc74,6e61a5bf,46796ebf,6c0e2932,b8f9d1df,a5c48af7,e491ef83), +S(5e38512b,65607ae3,f843e223,ec7f95ef,5af4bf35,edf9068,96fa76d6,c302b75f,7adeb25b,bcd0bd27,646956a4,c4a659f9,1db48f2e,532a84b5,7cba0aaa,23e28da7), +S(c812dbf1,732134df,1c459c81,f15cbf3b,4a97f959,18bcc0f,48062b04,bf133649,d22eb1c9,27d57ff7,e0baa4ff,c3b9f74e,116c8a43,ecb10cb7,32745d9e,61e708f8), +S(3f0d8071,56f38368,91a263a1,5177bb12,720eb46b,d6c9abff,5bd2d2ba,ce377b39,348f65fd,f87f7f2a,1dec49e4,8e009fc3,8f916c40,857586d4,e6063772,704d70f), +S(da9c23d4,e4fc5a12,f80b9d65,c2536366,c75a86c8,fd4fb92e,fa5e360b,5ba1993,eb01f616,fb20b8af,522a108d,b81d92f6,3b161963,bee3427b,4a49353b,928da25), +S(d266b680,fa8f6b70,4f8ece54,e52094f8,be493a4b,9a4f396,dfbefba1,4887e18f,564bb0fb,f63b5054,6a930ebf,df1afd93,7f0db851,e460c8f9,67afd274,b735681), +S(b9859cc7,2b573a92,b2752b85,692bf02f,be1f176f,1cb8be2,e954a00b,33e314a5,fb216130,8bba3bc5,cefdf81c,c21981df,2dbf0a83,d98d259,62c879bb,4ce6ab87), +S(8e52468e,486dc34c,c53cc59c,b8c9360,62935ec5,4563b9e0,8daa0a95,f8787f3f,2e3d5c59,90f228a4,e7133352,837eeb62,892e28c,7f8233ec,48ff18a2,d6564c9e), +S(438a2203,af978f12,d28fb3c6,af10ea2,13a954ef,7b0974c7,2b1113b3,e6d03b65,d8f36c0d,d6d4782e,d7194631,7b0a5745,6207517e,379c29b2,ab30cde8,e8ad33c9), +S(1a4982a9,f06bf158,9e395e10,9873ec13,1ef4a00,6a6d7b83,675c3906,1d61fbbf,93e2882e,676591ed,8acf2e3,ff22284d,abe2fab2,bdb99175,5ac72631,c5002747), +S(6ebec1f3,bdd0f019,3bb9a7a9,1d59dd92,5019400a,575dcdf2,33156bf,3e88a47a,c341309d,b462016f,afabbb56,5d763ba6,9c8f2f98,42812afd,fe0e9941,53283ba1), +S(599dc439,687d0dda,a348eb2d,337bd2d9,76a2be69,fdf5e064,1ba87e91,61f45351,c8433a55,411fdd17,ddaa9a86,bd2561c5,8b891c41,d868e764,13e5f3ee,3b3ecc1), +S(5a63cd59,aa9aedc2,91a0d50a,c7d01214,c3788f62,7e3c60ea,84d09ddf,2eb80840,3851bcf3,51ce55f0,4f92eaeb,99b3036d,a06d1f38,2a759217,50e4bf39,7d5ca685), +S(86e089a8,9f1c1644,a2e94b4a,722c6f19,9bb0403f,9a112b59,66191e31,e750f1,91ca06bf,fd48c38c,272594e7,1a113083,f6a4b275,7f279a75,3d70b984,a552e391), +S(2f2c3b0c,dc0feb58,620ab813,c8182510,a2a6f14e,9127153a,358c50f,31238370,7ee136f3,35f076a9,5b80e0dc,a8dfd8b2,691ce9df,5ce0f1b5,5dd9e3db,e156a360), +S(4e2e8b40,8602701a,2d1081d4,e41f81e3,3d9b8465,9959532e,93aca00d,9a70f005,5ec80478,d44bc01e,ad4b544a,20cc58fe,2990c0d2,4d08fc4b,2f9e0a5d,913953a7), +S(98c30f9f,4ef0aed6,17a8fee8,92934d56,10267d6c,e14832c8,b802ca00,320a9c7d,765958cd,15907b0c,dc0ad9bb,217d647f,6c85da72,49260d4d,11ec062f,9d818639), +S(f2b87023,7841e053,a20f2df1,efd265c9,f58e9132,9c280502,61f8c6e3,d6ca5afc,bdcbdcca,67fdf622,84fadc6,4ed6e727,5e82d40e,efdabad,c3d1dccf,fbd32dbb), +S(650f0256,1031a2d6,7549959b,7c358191,cf3fa7a6,30010f57,1006d2a5,20592377,2c4d23a7,44aa3b0c,6359149e,c170866c,b5874045,900b2010,d5a80dc1,e6b2892c), +S(76c3e87a,c72dda23,7ef119a3,9a128507,eba08e31,9f1a7512,5c4dde61,6523fe40,822fa37,8e7c8f19,e02954b2,5faedcda,6d2e0123,ea0b10de,70361487,9a0ec110), +S(472f9e0,9adc7ba9,179a6e8b,22985721,c994c51e,109bdd04,eb2afd6e,fe471f8a,11abccaf,296e7c8d,98e1c3f7,50069ff7,9552ddc8,5e5b55b8,4980ea03,4012072b), +S(4cbb2b87,1f8b975a,2ba257f4,340074d0,7fa897e6,7000795d,d5312e35,cb9453a2,4e31a79c,d842f6da,9e45664a,2878070,1dc87cd2,eb2cb25c,2a7833e5,4e2736e9), +S(ec70b3b,1a95b593,431ac4b5,5825e6a5,2cb88276,27165195,83924921,30805ca2,6092c54a,165bd710,a0e1f36f,18b4e4d4,cfdcf6cc,2f222599,761a9efb,e4d7807), +S(a6b1dda8,e0dfb484,60209710,69cc5398,4e4462f5,a305af62,6b7ada3c,bed5e1f7,e2c113db,21680a63,8f0ea442,52421c0c,41958de3,c7b4a24e,f39546fd,19be201), +S(4a18e595,4105c269,25468ebc,a0c9accb,1710b854,d618cffc,72eee0aa,c0e3f296,1e7cad8,cd248d4c,5dbf0207,a32b67da,2db8c8dd,4798a17b,52ae6445,728e7f6f), +S(eecb1dbb,e2451a48,53054f45,4cc640c4,3e38f20a,3957a192,c2f5827f,9384d11d,a889250,f8bca4ed,5158a55c,197459eb,50b7f10,f74158a1,75180856,b4de62b0), +S(8949f6e9,5e3143e,653889cd,4d57fea4,657aa42d,76e6297d,d20ceecd,d5def67d,e08d4e90,fd929ac6,ac3e87c8,5554e0f2,b584a31e,1be841ad,827c738,3cafeb54), +S(e85b17a0,dcdf256e,51a605c3,1859773d,a0e52a36,6312eb19,9a789246,beb7441e,3505403e,1ab0f77b,984f41e8,a8462c0d,e9d5b500,d0a8f59c,fc83a75,ee063720), +S(c7742a95,6b5c8298,bd1600c7,b756f777,bb4ab2b1,529c8419,d124d402,2b902420,a05ec2b5,8af28f9e,35a86b,4db0634b,5b7017d,7947a023,3db01ff0,64bdecc1), +S(5432c05c,814aeb02,c82e651f,7d1f7b89,e294a76d,17e5ddd0,9ec8140f,cf5a62f2,5902ac55,ddad39dd,da4b35d1,5b84f43b,c13420b6,35f28bce,a60d55a5,78d3afae), +S(39075a61,15bd6870,d1406865,4c8801d4,b9aef508,c880618d,397f9bb0,6674b17a,8bd2702c,96604b83,4114c489,367c3d3e,5e6efd50,c15b8bb3,4b2cb686,b08a49d9), +S(df43a136,af0f754e,599659ce,63d0d48c,73993927,6eef3442,e505c93f,acd025bf,1378d4e4,763c6c79,483597e2,f90824c1,830c8850,fcd32c69,52dab9d9,cd0802a5), +S(840a24a8,314f7e0b,9b3c33bf,7f6cec77,3052a0c5,54a1e180,23772bf5,1d7a4a6d,6e1be7af,f02c4536,f44db655,b859383d,5eabb37e,92b4b896,7ec1acd3,859cb1ab), +S(55d1fe11,49cc5e08,5e9ff19f,9c0823aa,9ecbc1c3,62385bb,e5d33d8d,8156628,b1b96f77,c27f17cd,df4b223e,7343f140,1849d049,4351b2bb,27aed7e8,79b686f5), +S(a8ab1f78,3a7fd00d,f5f4a814,31eed1d7,b767417a,691f28b8,38238da0,cf8fd509,2d747fa3,b164ec83,de89aec8,746781df,f7fcbcd2,67230a85,4802491a,e213a3ca), +S(3cbe8f71,c37679ad,d61e0453,3a1ebb71,99618a3b,9e8139a2,cd751d97,d4a212c0,9216bc42,a61a9734,750470c9,1bdb3fe4,510a5f0,9fa5858b,29eb7b8e,3d19641c), +S(cf1fb09c,a6b5ba69,93303a5b,695ddb27,3b527ffe,9a83e88f,9b5d45d6,b0a8f94e,cea6959,943f7e1d,f1e85391,e08fbba4,b9d84b00,6cecdbb,16f576c7,dd89c814), +S(1854629d,e22365db,5382ddd8,b6840e03,d1e12236,d31c7d10,12e8f83d,3ce1b71a,b25fdfe7,4fb81669,a24cab4e,eece5fc9,689ea40e,205b614c,4a0f250b,8f778b15), +S(6d1ebd8d,69fe133a,2e6628db,70cd4f,15d066db,2b0f42c6,2fc70dde,eb2e89a1,313ee8d9,750c0164,ef561df8,6125e72f,cb5c2233,ea36f971,197c7fe3,acc429ed), +S(29ebf614,7a918ca,371b5121,9efa033f,ff2869fc,618aec33,a4fe7aba,b916e46f,f1d5c067,382d76f4,74c159c,e88ea702,f90ad2c,5b268a7d,14ede7ab,40e11a22), +S(8e2bcc39,f60c4c62,591cd482,8125d08,4d26fc92,2e6ae30f,51882438,93dc5a40,44e3fa3e,64e14ada,e4a0a616,10862503,2e109dd1,c863814,368d423a,f96e9e56), +S(27e17225,1f6a9557,39aaa058,bedd91af,1e920758,cc0724ba,42f44f4d,45e99efa,7dd22a7d,6dc604c1,fe2850d5,41b2392a,b3c3d60f,2e712cd9,179fc5db,5fc179e8), +S(4fb44a50,574d591c,1391dabd,7f40f7bf,14514f65,927466b,2c643f36,d85063d1,fea4e431,63c1123d,9764b70a,cd843281,e108f04a,6fab19e3,da059f51,4c2a73b9), +S(929112b5,19251a93,bfd2715c,6107e5ee,d3283e0d,1849ae37,d110fd4,8eaf6be4,e382b859,a7de2309,a4dca649,66d0b744,9ffe9ba,383379be,d12871b7,19c653a2), +S(532c823a,a090cc4b,128938bc,69adb5c3,3653fc33,fa07d598,36d25ae0,808c0b70,61ecaf31,30a852cb,46de2616,f7bd24ed,8d9e1ad4,efadf570,d08a463d,b127b455), +S(7c7ec9a0,aab8cf1d,36b9447f,d7d82549,d425c217,d25cbea1,3ddb8d5e,e29a38a0,5441d917,1898ee1e,3cca969c,acaa074,62cd236c,a5cccea6,9436a086,e08142a3), +S(a81c85c2,54e52aee,1de1ee45,b79cd027,e1cc6414,4fe99ee,8ad8c572,82c0bad0,1be62473,54bc2bfe,1dc85c68,684fa9da,1ca55a58,6dc4ebc4,3cdb050d,e7acfd7), +S(38f16bb6,da377f25,aadc90b0,7fd21078,5028aed7,85dc0b07,5ad9f04,4b0ffcd7,9563c6c5,531b64a5,d06a5181,d7515b61,4a74f8ba,6226b559,4220282b,b8654273), +S(ea7a49cc,ec294031,87fb5f88,82deef27,2dad9624,76dcacfe,cf128bad,732e1686,49de39f7,5d9a4302,221d9b96,90019013,1ce39a7f,dea1c801,cfc0a2c0,b9a16995), +S(85019851,529364d4,5c84b63f,7f119f20,f3245547,2aa84b42,1ccb239d,fe536868,91b58064,2fdc0f39,284706b5,5b8e4bb8,4e112d5e,68379d94,465c3ac1,8e37cc50), +S(17e41364,244d8f16,22059363,be73839,75ad528f,f1db3390,ee65b106,beb6fe40,e90412d5,5e1b6590,e0d5968b,88dbb0bf,393ccd6f,96748e5a,205ff1b3,2f18a0f0), +S(5b49e7d9,fcad56b6,8b85d934,1b996ceb,6a555ca0,78f8d12a,e58e79f3,1d91caf9,32af7ff5,de4445e6,4bb895c5,316b171a,d911d8d7,81b16115,1e9643ad,4ce21885), +S(42baec78,86aff012,13d9d182,6e031b20,85724be0,268790e9,968d01fa,63e0e366,8298f68b,32e5caab,b8e641e6,720db67e,4150ad69,ebe90143,23f7b981,1ace8d4c), +S(5201710,64afee86,14c28123,5279e1a2,cc2775cc,85a5751e,158c66e9,2fa55d51,d12195c5,a0a08b,7cdca2da,fae86d15,d37427e0,1d266609,dc9c1adc,d5d8039b), +S(bc353c2a,8ca16349,fd021e60,8befb9a,f85c9ebb,b448d732,13220154,a02297c5,88850fa3,a61383bd,133c6fd4,65d12756,37878fb8,84bd3c31,3c4f92a,2b620edb), +S(9490256d,3acd97c2,848b24e8,8b8b2a8a,8635417a,1f228d6f,dccc3917,9c0fa397,4f4ce298,cf1dd296,b7704f9,b8f0a0d5,be42923,80bb917c,5fd49c28,55d3b662), +S(a963e733,ca168104,47ecb136,bbd2047a,97ba8f49,9222736d,eda1c7f1,75c2fff7,5385ed6b,93e6c27f,568566a9,5cf31059,de4ac850,1809319e,ce216eab,c8dc181a), +S(fb44e6f5,eca57845,76439098,2ab24ad,c84efb0,715c3b9d,df0b7b2d,a165702f,a62de478,678bee62,891c5241,9c8e77b9,d573fa6,95b0a2bd,fa5d9d61,c4362e43), +S(c1de1705,6bd1f0f6,8912dc20,29a41689,efb21e22,e24f3fc5,ff5c4498,f4fe7ea6,6297c6c2,a30e8e3c,43f534ef,475c3b35,f2a9550a,c5b9c733,63e117a4,af2829f2), +S(8c78a7cc,e7084890,8ff122c9,108980f8,b2a2b9e2,80e5536c,34b5e13e,61f8e133,459a70a1,5929d848,f8def6ef,ea8f42c,905fddb,3c0153f6,71a17b4a,b7c2c1ad), +S(5204d397,bf3ca5eb,988c1ccc,d23fe613,25202fa,88421157,cc7e7fa8,91b4e612,c02a009e,f89c5b88,b3f3a7a5,40d30ee6,75f94247,60e23fd4,8d8ce1e7,6395b7f5), +S(3cab1091,a0dc43c0,b90c60ee,44d31ecb,607da086,fa6da814,9c378acb,99c67ec9,3bcc5297,267a2da7,e228c7b8,c1677407,93feea54,bf31e3e9,f8e270df,e8d1fd19), +S(e0475cb9,9ecea30e,94ad6292,5ca5c3e7,77c30673,9d9d55c4,464a3e85,cc2f10cd,484818b4,d0f72e79,79427904,9f9aa4d4,8aeebcdb,f7f55a4d,97ddb03e,4f6018c6), +S(1165d67c,11327a34,e702775b,40a9d7b2,deaa423e,7e4d3dff,869f4a9e,3fe6ab73,63c55abf,6943f35,171595c9,63ab061b,a1c9f605,c2ee4970,767ab1cc,1bc691af), +S(f0ca20aa,59ecbddc,cdbd3f3,6c8830bc,9bedd29,b893ff74,48cc523f,bec962b2,6b2ff156,557d16a6,47453361,c4bf9f4f,41bf1e73,8f0c5536,a3dcd50c,ab88a086), +S(a3b01fa3,8e743e32,b623f2a5,cfb7300a,75457d46,6499dd5e,b1453d16,a746cdc7,19fdddaf,28030237,7310920f,3f982394,db89f510,a4a73b08,cacebc6a,2d417c78), +S(37ef5196,c8e2d69b,cc0b26c8,2bc30b9d,650a7ca1,409c77c,11e0a338,c5065ea6,df890a8d,8cb2b669,dc74c96e,19ffdbf5,abd5d898,46240fb9,18c297d6,1275ea86), +S(d99abce,1ecb8415,eaaf50bd,66f4b5f1,a5a4e5e9,d6959735,629d624d,adccbc88,9da9b4fd,2558c726,c44d10ee,f72c4699,80069045,a8660cf7,58de00cc,67be856c), +S(f77fe49c,28595198,7abfa598,915684c0,2af76675,5e2648a6,36f5c955,a78aed61,a764861d,3a8dfe39,92b2e897,ad4bebb0,8c7e2b55,e390efe8,21ffb60a,cf5e4be1), +S(88f6ec1,2aa65721,3f672e10,9d406472,7b89cf88,74dad08b,a4b54747,2bb767f9,8b6253db,a124b7ba,43fdbac8,55f8e9d5,9da23b49,e450c8e5,675442b5,f822b8dc), +S(a13a7136,640d1507,9ed90b77,12a9af52,e53e75af,4583a149,f78c2840,f383fc55,435fa5ab,6454ef1f,ede1b33e,475ffe8e,10dd5a94,4f96f340,1c184642,2672b310), +S(20940c7f,9d4abc67,d42884d0,346551ef,1b2aa54c,d8a1485d,1e23758c,e207a7fa,de5eb4e7,b619e600,3cf9c0f9,7e944f55,ab57fe23,388dbc73,66bb2120,e5aaa793), +S(298e00ed,855dd2f1,c0aef293,c55d859c,3db60fe4,b026f782,1c07d534,cb087e0e,9c45f376,466da662,583ec25b,5bdea3ac,c624731d,4bb62b2,2345fbb1,bf721990), +S(5153ac16,6b837bd3,29d98a22,56a576b9,821376cc,f7e48cb9,24e75f59,ffb6d7a,3f5ebcd5,d5ec2073,f1e43334,7ab4780d,f19a2806,d87a6477,bb73ed09,bec6bd43), +S(78c909a7,c94bcc00,b5518df2,bcd3ec09,9d5d2db0,d15321d5,b3135953,e8e1d195,735e4b40,519f4757,32042f20,410d8699,d1af7a33,94062791,b12e19d7,85ae42ea), +S(e4a4b24f,d9f7ac92,8a888507,c6d21ad4,fdaf62c9,2bb920ec,3ef96d64,a70a8567,b62c1cb7,b0e49cd9,8001dad1,52a2206d,6b397952,be03113f,7ff764cb,505502e1), +S(ca3b64ac,d4aa25df,3e7d4b64,6d5c8032,66809507,7f7f60cc,1e3138a5,2eff4800,92972d13,2f370aac,680f2a2c,feaf4e93,73199207,7f51334f,37553a04,5af089cd), +S(58e22f4b,a636677d,aecc727,d58a6ac5,77d85e31,2d41d56d,1c09c859,749798c5,cdcca924,549c867e,1a11e4dc,27bb00ae,99e0a356,5b6b37dd,26acb58e,f29f3bf0), +S(94dac55d,da61410d,926841a2,4b5ffb24,e44e3ee2,3d42efbd,8afdf3a4,3530363,4095385a,529965de,b01b9a3f,f9647b29,8f3d2119,9bdac924,5aa54df0,7e8d621a), +S(639ca66,8d7940b8,8f41c4cc,eb50b60,203b6884,c8ac9c0d,c33bbf59,926d417c,447035e4,5c9bf80c,71f8aaa3,9f9356c6,672f0db,fa01a4ef,5b1b7400,dbb70a21), +S(a6a9f38a,51d8e82a,7e04f667,e8cd638,af4cb7aa,c8b0ffa9,255f472c,c5b30250,fa935a10,4796943c,1880e3ed,d9c2504c,7e6e4bf,46036119,9458e23a,b0b025bd), +S(60179b5b,cb4ab099,b74f6a9b,853a50f1,582362ca,fd28b288,e2b339f3,27671a8d,5ef8f881,54b7b4af,ba287388,6c09d1d,c12d7070,6b960d0,b0453767,7e5d283d)}, +{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), +S(74164670,d214bccc,23e32dd5,b4e7f093,c95b4628,b7b3448a,347980a,1f9b0323,827aad3a,23a648ab,e0ffef7e,d8a6d6,800e07bd,7eb1b5da,50b5dc2,8994a20c), +S(66a60beb,feb1eb8c,39857b37,158b48c0,93a90cc7,8d8aa58b,af183975,b12fd461,62f95a56,2db16e47,5ef65451,4cf82fc7,1a4379d2,cb4224fd,695d202d,8e85fbf0), +S(77272c7c,cb0ca53,17e660,adfa236c,e062992f,a59c7164,71d89755,f99ee448,a6a2d5ad,7ee9dbd6,d8a9d8d,157860a9,58e3d766,da5b82e1,5bbf83eb,7d987f7d), +S(eab2ac49,209ad561,d3beb05a,5152d5fa,f1af52a8,12ed0d40,c493d611,bd78c73d,c72f5b65,dfb7f960,a8bcf355,b80918ec,a9e8c3b3,985602d3,7ac0cae3,54645f6e), +S(ec184bfd,27c2ed17,25026464,4be6e557,db93ce3e,90ff225d,fb0cabda,cc124952,b4ed4a46,acebcbb3,9103f99e,cb65e208,2aa5990c,eba9fcac,cafdbe55,6a08a516), +S(6f5e0f0e,7c32165f,183f7834,3e12c845,86745ad6,d02d4f29,bf16ffab,31b1de93,76bf7f22,105a881d,6d190e20,bc7b5d89,ad0ee9ac,c1df6905,7035b6f7,6a9d4f61), +S(b3d820a7,466f3cb,d955acb0,c8baa787,e7f0d63f,52f9dc9e,87c6138e,60b9279c,6d769d76,91c1e61f,41b9cdce,949828be,7d17c1d,ff0c5041,7e2e3b79,fb873753), +S(ad92580b,575d6831,d2332a72,f3f888a4,713cd659,bc439870,7c000318,8e7ae426,eea9afc8,471e88c0,22463a9b,c8cb22c5,d0df87f9,201aebc0,519fb7e9,e2307073), +S(54b8cdd7,3204abb4,22d870a6,c5afcb14,81d4f117,a673e60d,155baafd,f3c5d4bb,6aadeaf4,94823ad9,df8d2429,e42a1d6,8aacec78,bf973785,a56120c8,28d23bb0), +S(ef2bb94,f14272a1,e235da4d,4ce4b043,2037c8dc,7ad8d559,958dc767,e0e75f5b,3af91f78,54bae661,9702996e,1defee92,2c0e8c3c,5fa4d37b,261c20bc,14fbed93), +S(13b87d2,8125e63f,1259b1d7,4b79c395,25bed045,256e8b00,84024bdb,48196b7f,139b380c,bba0404,463125e7,a455d454,ce7d811b,c7c14e10,90cef0ae,67d8281), +S(34ab008f,50e1a525,8cc77331,3dbf8510,7f3fda60,7ad5dfba,9aa464fa,856394c1,19178d3f,f5c51bd1,4c6d424e,c42591ea,414de041,7a3f470d,7c35dcda,77e57860), +S(7d872049,c080936c,54875ebc,49a00c41,b837b71a,18de4e70,adcb8369,95c2dfc,b572a6cb,58a2337e,2453110b,eb877a02,bff2bea1,d542714a,3a115a59,933eaea8), +S(72a2644e,2e6d7182,9f78274a,eefc9f15,9861b031,56d20d69,db62b4f8,57dd34ea,82e158bb,dc2d6100,bb5b300e,467470fe,606ddc1f,e662d3eb,3d51d9df,8383263d), +S(de81a355,37cbb00f,76aae7be,d3ce5362,c51426e4,ca012ce8,5d5f0fae,791c106c,10137d33,8a6532e,95917e92,31e5c14b,10551f6c,7bb1cd4b,5944e772,22c0f0e0), +S(f8499694,38918109,b0eced18,766add3d,8e21a5e1,a6eb640b,e4794e21,20400de,9d081c04,cf130095,fd00af83,32408bf6,ab4e262,e5150e3c,9f43a3a3,704b3d8d), +S(a5786625,1f866279,36233299,283e5dc3,838a5d9a,6fc30cdd,cb75ea90,9f3b2e94,57d57841,f173e1e9,e2959908,7e535dc6,a848132a,d6fd98b1,ea2a16e5,ff8c60b1), +S(533053dc,a24ceba7,f528c93b,bf62d61f,ec640ac1,40848f7b,9dde2ccd,f2465df1,d501e49e,3291919d,3c7a280a,1501258e,325e478e,343ae766,61cd9cfb,b856a316), +S(b85608de,dcd5543a,a90fc566,9fd94d52,b041e434,2cffc394,1cce3f40,12c23ebc,dcf01862,1051bab9,d1471d26,99f5727e,705ea2bd,8e5ffe71,df7db441,236df5c1), +S(bd1a08fa,d7d7fbd2,b46565ce,99fe28f9,635e0c41,a8b6aec2,31d949aa,a70d52ca,1a26906c,f77d43fc,ec656be8,5db770bc,65d05482,d6449f52,e23e1e70,6ac2aa15), +S(ee4e9976,9517bc1,2c7adc6c,fde381eb,b385b1a4,bf918268,5f175db9,949c99c3,738250e0,5dd8e427,95728575,fe5733f2,6b083705,301f9138,d736fb24,98c34679), +S(bcbbc6ea,2007057a,1be80335,3d086450,c48e432b,6f80ba43,bf03bebb,c48f9379,10fd6383,b5857977,87d8696,9525e0ae,b1842c23,974353f3,4eb515a1,5ff52435), +S(5c717940,e5e9546a,f9ce9d6d,c260bbed,fb678923,db861b41,1f275f0c,b18b6e02,d9144751,3ab535c0,603fbc12,adf52285,560f029c,266cda2d,69b29090,f5179f68), +S(7137b160,a5eaf92e,fe5f5c90,c3d34063,333f8204,5dd83371,31f624b8,cb7173,3025534d,6303c9a3,6ae38e66,57acdd29,48bfec24,d5ba7709,be051fb3,4537c2b8), +S(a6e79e0b,54c083ea,a6e37b9e,b54c181b,ce397786,c294abf,5d1cf475,fe34c030,aaa6aac8,4709fb5c,ac6a498,c0659da0,e2506e5f,e890c06f,5ed5081c,bd737c71), +S(9a143958,23cf2096,d81677e5,f804bd5b,790ceabb,4b15da9,b35c01f8,c6b1d81d,61bd3e2b,642e9948,50179f0a,947820f3,f241e53d,8222ec73,3ceb8bf4,cb7f08fd), +S(a51aea0e,4039ce66,b3e80814,4582aed9,d0ac0be2,95105a8b,23179025,4a2b0429,7cde7f91,96e8f417,ed7a075c,c25cb694,4e996997,3ce13a4a,941f670a,f523709d), +S(2d79629a,1069878e,76cda780,b9291c4b,45b78b7b,ac98fcd4,3ebff7b6,cc2ad200,cb01aef5,1a5fab94,ec29d73,6ff2370a,df866d45,d977fda5,2b7fe32a,e1d9a3fb), +S(6af74994,feabdaa5,fb0cb613,2f346490,bcb1a70c,7bf58e44,2cd46670,12e050d8,627e7f3e,b4e66be0,672b8bde,f119177e,f878e80c,a7b5661d,d6a9d19f,19729e9d), +S(c367583c,7d2d5d6f,3f00083a,1218645c,568a85ca,8fdc708c,7e8dce2b,c72c3ceb,baa36c7e,1c86d194,ee03efb5,c5e11b47,34bfa6,c168ef3e,fbb78f07,51a7ebab), +S(36b2293a,2dc956f3,47ef5874,9504821a,c9197e25,1716c398,f5c9dc61,c63fd5e0,95c93401,be8f3500,d971ca82,ec97def8,7d58d64b,5e4753cb,4f2cb608,72f2950d), +S(78e80bca,805183f1,76257399,63e9cf9f,a1bf2b88,eaf4147a,17d83057,bcfa32a8,b42e40aa,f852c738,fe1abb8a,e5dce499,414c2113,eb59cd2b,2a3f6c42,fa96812), +S(4f5b3550,887d9ad1,1254333d,7203aadf,d202fe5c,845b3c8f,3c0094fc,e4a32628,a4842bc8,c793e4ed,948dbbd9,cb68b7c9,3bb86827,fa9d7c3f,acfe78bf,670eeb99), +S(8f880914,9dc553da,4ed0b371,70850bfb,c305fce6,d5e7be9c,640be999,8df19b1e,f020f82a,eff490e9,fc7d4d7b,519e780c,21f86f87,5a547693,86524483,ec776674), +S(ed7f98f4,90be919d,d1f570fc,cb565424,c3537bad,d8d80e61,87b51f8d,9ebce164,d374e45b,c81bdc9d,63c824b,1bdeb2ff,5c9a3453,93540ab7,884053b7,107d8066), +S(754d2b67,65625067,14865f65,a89bd0c6,6415aff5,644d37b7,e7437e03,372d70f5,e4b5855c,14ba6a3,360d1519,98358bd0,ec2bd109,ddee46d,7a95050f,5131a9ae), +S(d0778425,311ac57e,b8ffeaee,2001b9fa,89d6cb36,49be46aa,365b81cc,c8bb903a,25e3a484,5f1c15e3,ecf6a654,69a78893,3c414b8d,c92587f9,fc8f54c6,eaf065a0), +S(c7c18e4f,7c8772d4,37e3e861,584d24f7,f428c06f,23730347,2dcfd4d6,80352ff2,6f5a02d8,1c6ff6cb,32e85004,3375c865,57f8659,83e76e0d,4f42a69a,b02ddd52), +S(96c4e50d,eb86020e,b0bfba2f,ba3da698,c7bd031c,78959022,341aa1bd,a19b4a1c,8cd7476a,78098ae2,ca166d9b,c8aa79b1,ffd9f8f0,943286ff,d563008f,6f3cfd5f), +S(3f462649,9a5e5ad9,f5ea71a0,9b4e6b7b,fea33c80,c786715b,15200580,cba306ba,32624f0e,9a3b0413,fa401f8f,6f32995c,74ab592b,792247da,970b89b6,90545bc4), +S(a1495fc5,2c642d7e,da16d1d1,289f2eef,f4993882,f2843128,6d17d34e,5949e2f1,66ce7c4d,611421e8,7f049ceb,11e9f99f,9edf2592,9da6bc45,91ffbfbc,3c73c87), +S(954ad30c,15a6c5b2,deb98983,ba7125c8,e216f1da,5531d258,513b7731,4fc86c0c,39378c22,527387af,e75d630,fa69dc8c,44586372,96e4526e,2e105fd1,af7ba0b9), +S(5692830e,c3ab78cf,6721b604,31abc539,ab14318f,cdd4d6d4,1586772a,bce39a98,5d1d9619,c335acef,22acc9a8,d32ae53e,9b227ede,50ca613d,d67065d1,252c56b8), +S(1cab4f2c,73e452a4,de0e2591,1ed22364,803a060d,ad957184,3c81258c,6a4c518d,27617c5b,d52b5d06,8cd9c2ba,df266f8f,ecdeb4cd,41bd6e0b,a2db6a2,8f4c7f3c), +S(9f1834c0,145eedf2,53211dc2,3339283e,5e7daa72,fbf6b69f,d5642a63,c551bfed,c1838a49,b3289127,7c3365f5,9f69d34a,27b48c6c,8897e9ca,f40d8753,d467d72f), +S(58988653,8035c13d,2c538f0a,1c587f2f,fc08405c,e6a1d7ad,828aef75,43b4ae8a,c4b901b4,beb24774,598bd2b7,d3450791,f2cbb37c,939594b6,593fa592,dee20590), +S(d248754e,c643d300,6d81c5c8,9e91b522,181921bf,627e813,1acab8bb,cb97b2be,76b94631,6668e319,a057648b,2369d781,c2abc77,6aa8805c,43734698,671174e7), +S(f849ae76,ad1bc714,4c2fe13c,b0ee81b3,f9abcca8,d940a161,74a69c0,b2cbfd0b,239aab7f,c1b6c054,a34deeb3,56da4e14,e15643a6,63f40642,b2a43350,80c2883d), +S(561b12a6,2e2fd36c,ca92d85b,14baafff,864e99cf,315d8902,72f81dd3,27d1f04,c4199633,801df02,b34ba9e,13462533,7bd975e3,ceb19673,7bf37bb9,daf30808), +S(8821c52b,c13c4ca5,bc7712da,9e769754,c4ab00d7,83dbc018,b1c5b383,9c41c245,63edc442,6347d646,5ea5c046,820fef62,89a28c47,df834a71,cfa9f5d4,6561444b), +S(382b0dc2,c54b6fcd,dd8ff070,6edf8f4f,2ce34daa,4f7dc15,d7f1ee0,b0ba78a0,31e1e109,35d8c994,3ed05b5a,57d91bce,81ba0f4a,8da1454,98a18e70,17f2fa39), +S(3b4fa983,26fbd82b,59a938f,1aa9d30e,2da395df,f8ed1aa3,c75f0969,b3b85712,57653c2a,8a11d192,4116c658,5b413feb,e8c56142,bda13d6a,175244c4,4b13a396), +S(5ea8db07,47f4f7a4,db0f9494,3dbf8b3b,9b04855f,93737d30,9c7ab27,8c2ba4cb,805b0db0,1d883e3b,a8f82de5,b6bc6c3e,3b05b3ed,4eb16d34,db8df937,19929403), +S(21386763,58a655e1,e878aa8,984bfe61,bbc7f1f,c16c1881,40e2cf21,63431d89,b62d321c,82082b74,4f8817d7,dc464804,c1d3e9ac,220dd1e6,a94f17d8,2250d06f), +S(934eaa8c,bbd3fad3,44cd1996,86b8a7c3,bb0ef384,4e085e55,83030bc2,bb52148f,4613cf3d,ef424be3,af392f4a,6fc474c8,3e3f2d1a,394431c6,5ee6e224,4396774e), +S(99a5472b,e9d06621,7e18be06,d9a1c1e6,a649a5e,61f3726c,87b21a31,7aac5f48,1e5a68d6,de4b2958,70cdd340,8b3d66c4,84eb4002,9d41c1a4,1d30bc97,beb14693), +S(3411cb09,5d5dcb10,49e8b927,5788779f,11516882,cc09ba6c,dac69bae,2c63362,6a3b3241,e6c3c802,dd5105dc,a1b82a8c,6bd31e57,aaaf505,fc41553b,2ac08b4e), +S(f7a6f695,824a413b,8a916cd3,c3403950,38ccc3ba,96803c71,6a498b7b,384d7fc1,7acb457d,3cda4738,bba35848,8bce971,d584ba79,e7432224,6619c0ef,9cff3ed1), +S(d4737f3e,6bce15f1,7ae3a133,bca08f13,434f25e6,8fd36a62,5672e6cf,983b1084,54a81a40,9f08a597,ba4e312d,f8789106,19189132,40f97ae6,b360d510,4a0b47b), +S(5b1e76c7,3f9c8353,b7f3c63f,ff2e48e2,d3bc05fa,857ebcc8,84e582cd,83845327,6024ce76,eaffe03f,951ca26c,a1550d96,f468385c,157d9a79,eb9a20fc,fe841e2f), +S(d201ad7a,72d692d9,e87a7a83,e865965b,48e90ae9,1481a927,34c90133,f725d589,310661e2,9fec5d37,96484ee1,bc6a6f76,e8da9e1c,f10fe672,6dfaf737,d78119d), +S(cd1f2c41,55b8119b,c5b9bc31,e5817a8a,b2268a8b,a526c005,1a3e23a7,abe8bef5,35b8f656,8b84d979,64b29050,77f01e9a,c2024236,29614688,df077aba,1b639048), +S(89c74b7c,e763801f,41ef6dcd,a452fc7f,a39f621b,39fa1061,a2b4bd4a,9649c9db,d5cc7a8e,722df783,82c168f1,91142df3,e15c161e,3a8471ef,236afa5f,a98a9f93), +S(ffcaa11f,317a856f,300df9be,1dce6c40,88bd5c28,b08861d3,87f3492a,d1004bed,ccaa2565,1ce602ba,72c899ad,f5f9be23,910ff5b5,1e3fb1b6,e2eb975b,c43c1492), +S(35903c6b,58659353,391a50b7,1a9c8186,a4dc7ede,f3455ee4,8ecc1470,263e1b8f,d44d9022,a5cfb61,4f56b02d,a83b67e1,4c3eeb78,caee0a4c,7f404471,77ae7ee0), +S(f9138261,2bc1de8,eb9d7062,80ef2b2,fa7fcd30,d157130c,784d7698,dcce5183,4709a971,d0008021,37a9ab87,27a705bf,cf1aacbc,822dab5a,d9334bd5,bcc5fd5e), +S(244ad0f3,26371ef6,f6c29f9b,7ef567ae,98a2abb0,cfa1561b,e9dc7f15,1e8833c7,53c1198c,5ddb33ac,37af979a,f40e321d,e87304d8,62efc794,2c944260,65de386b), +S(cbfeabdb,c93dee73,6f54f500,b33c2d0c,8c66b5af,68dde61f,c820ed3a,1ad2347a,f1416c9e,bc04c0a,792a1288,a20d0544,b7452aed,33f77b86,77b806e7,567914bb), +S(714246f7,3eabb0ac,af298c16,1bda9c3f,11f8fc8e,78b9616,2591242d,f0e870a3,94d8e600,cfe23c05,c9ec81e5,2c9e440a,af477c70,590f5470,31ece7f6,778edc56), +S(d776c80,63f8102e,805317ce,8e0b31dd,7b8b094d,6137c865,184ae51e,e07b924a,e66f3ab8,998ee226,f1259e4d,25d98d35,918b2cfa,abfe56,4a10c8fe,663101a1), +S(ef99b2bf,80bf084a,6483e319,9b4b578c,800eb85a,8634222a,197700c8,92a05310,94fc3ef1,12d050f7,e7d34ade,e89faf30,b651e10a,6931e4a7,ac2ecb48,fab90ba8), +S(c84a0ac1,8b659ffc,ac9e2dc7,57248e23,3d71fa98,90327e76,9441231,666f3790,e0973e42,73cd51dd,7233ca34,43dac778,3cd53c25,6816be1a,fbdd636f,936f7fdb), +S(b5572cfc,61db791c,d8b19da6,6fc11df6,e8776505,c016e6ed,96f17b97,c2edb89e,608ed024,b606b10c,5785811f,8c333fe4,95a726a2,ebe56680,b00b513c,aac4e0b8), +S(68447029,864934d5,92907821,5ec5ab99,3e00bd52,fe4994e,42978327,bf35a6f,31521acd,69c57644,ef35bfa8,cec803a2,e825c740,36a9a3e,fe831364,d00fd897), +S(fc9ee8ac,9fb265a3,7c26358f,8bff851b,d2a7aeba,2dc2a19b,153f649e,97d75605,cde1f563,b971ba67,dcf3d759,2752221a,babd8ab8,1d8a5a4f,3dda35ac,44c01d5), +S(7e86c9a0,d024eef7,91758bd6,899eee23,ff032336,9221f3f4,2b604ffb,33c473f1,2c15df40,6cad3479,841ffa5,14513883,978af93e,42aeba3e,c8ad64f8,df60da24), +S(e2b33d9a,8806ccd1,7d34a916,c4caa169,ffc9673c,e8eacde,19bbb286,85003732,5610c3fb,f0a6b39b,ec5c8cfa,db9296b5,86c6677d,61220ce2,b1d19bd5,9f44f72e), +S(ed6b2e3f,eca9b628,d98e663c,a3c72b0d,b853c8b7,a9cb9c4e,9247b8bf,84b2f3b3,6e45aa3d,f766a732,fe91f124,9148a96b,169e3b88,7dcf90ac,f972e91c,b25ae9cc), +S(78ed22a,c278758d,625e0439,3e273e7c,24acc72a,3975b497,ecad1314,df2de65,a2991712,373d669d,3afa81a5,c1e043fa,24df04e8,cc8fd13,32025186,f459913d), +S(3f3e7509,69153c5,378f64d5,7fce5aae,689f20a,8deb05ff,72077c72,b116996f,63d56b8b,92e77496,b86bd0ef,8bf803fa,f1d040d0,cd42c975,c7a08d7e,fd5056f2), +S(2540390,ca25189f,381b398e,3fd46acf,d5918215,a8bf9a17,d25179aa,fe75c1c,1c6f1725,5cac59d2,ebff7c4e,322694fe,96f5e2b7,e3927c9d,56134007,fc6dd9ec), +S(ed668903,3dee44be,80e9792b,b95408bb,5d38b016,d75490fe,2a22b118,56524fce,1a5c61f5,e738180c,cb533faf,ec9d3def,913ec31a,8c8463f3,df097f81,36375093), +S(a1a86dbc,2061e047,6ecbc303,2d25c159,414a6860,fcd818be,202a0f28,ef803224,ec9fbcb8,31f6720c,1735e505,276acd05,d957ea94,5b3af60b,6e1a2ccb,ede5b706), +S(c6064cdb,4feaaf24,89c35475,54279d3d,f1e96556,e97f1ec3,449fc747,ee8d0a2e,661f040f,ab90e5d,c9931a8b,297f2e61,9a24468e,432fb2b8,84acd0d,5cee7dea), +S(25b5f3a1,656c75ea,4ce2fc9c,bdbd2f36,78ef6e4a,9c2270a8,8b8dad5f,6f55fedf,8c48ac45,dbe199a6,5c9d72c8,7c1940c5,f17f59ca,d0c67211,5c2af898,7b142ec6), +S(b8e77df0,e23c94f,6f982ac4,37540690,441135f0,948f019,b79088d6,9eed91ce,3105acf2,23c01ac5,556b665b,d6b1919c,dde81dbf,7d44e18a,17bf67b2,833265af), +S(2a19c0de,d617ce9f,ff906686,a72bef9b,3ee2200b,ce71aa87,e18c2767,32421500,281d0c8d,dac57006,6c8d32f8,cafa5f54,404a6676,78ae9a0e,a0d19f1d,d0d24a6e), +S(5771b96e,c1a30ad8,d2087016,45df9b92,759c312,cc542ab9,126d3207,827e68df,ab4feadc,4b37a329,bf86e4,81786a0f,e1648794,689d0fed,183d7b48,fd53f760), +S(183fc4c8,62788f1c,7b7036d2,96bf7193,cdc93d6b,533b8c9b,ea28a9c2,9a5a9c10,2c019a73,5cca1086,e73948da,5d15f816,cbed1945,83014a64,24a586cf,501ff5e3), +S(31ebc0ae,656194c2,ee49f25e,28af673c,c65b2224,467ff0cc,920d3780,2dcfee7,d2db8690,89c5f10,b76d2d8f,cfd707d5,db7b3cfb,38903b6f,c4ebabde,47edd669), +S(a843fb7a,af70c96b,e7812f89,789b05c0,63824134,33476cbf,2a2b31cb,5a8d77fc,d0091386,435d082c,38fffaac,671129ab,f5e3461b,dc8295f9,9a064ee8,9371f70), +S(76c82448,6820236f,39701ac0,5290315d,a6f30e30,91d086e8,b3c934a7,871c038b,a4cc0e55,c2048935,c5c11b51,417950e9,dcd4ac6b,839b850e,efd2b890,17f5b4f7), +S(61653255,b4fecb8f,7fe9e6cc,179ded3f,955b359d,cf59cc70,1ee85750,b31a1d63,e197d8c5,d2571f03,931da039,b59989ad,390cac56,4982952b,a17e4d47,56f57582), +S(eaae448c,9a862f27,b55784b7,b3275e1,2d99d369,2aee475,dcf2d3ca,edd500d6,3cf4149b,351205e6,5ce2593a,282264aa,127953df,7da3cf9e,976af775,6be084af), +S(858c766b,faa67e75,672ed7a7,f0bf9b58,14217fca,bfa31b77,326d98a8,f6c7ec83,4d019482,93b2a3e1,d6f16dd8,8160efb,d15e29ae,e4c6b7f8,329127b1,7d0251f9), +S(cd384125,aa1dcc88,fc2c237f,2ff68117,c9517217,5b8c4f9b,a677ddf4,c2ac23a7,cdbbfc3f,d65180af,6a52f3e0,79f169a2,1dbaa8c6,bedcc4ff,be67635a,a1d51e1d), +S(5387bb96,b91fa67c,823e41ec,8dbece4e,cc1b6182,d50fe91f,44a02d74,90088659,bb7baeba,2b744ee6,8ff6ca19,64457de0,62a5e0a6,57edcac5,d6019bdf,caa25e01), +S(31ad9536,a6c16f44,c00189db,ecc8c527,304ab3b3,89bc7425,47fff91f,a088c01e,f48cae34,98357da9,5c47a41f,bb07055e,2061d037,35abe3df,8ff2fac0,cbcc246a), +S(18741256,6398f4b5,d2c34711,fa0e952,bf4de5a0,338bee49,a93daa3a,fdf29a47,5f96f31f,870511f1,a390a0bf,f9d9d383,2a7e3bb5,e8c515aa,f6022437,add8f159), +S(e1e5b96d,cdc60b81,19ca3138,9544c7b2,bfd587ce,6f42188f,115f4ac6,99e60793,cb5d9f4a,6475154c,7a285cdd,b0c115f1,765e357c,f51d8388,c03bf829,9a6720ea), +S(5184ca38,33208dd2,c04279f4,de77916c,fce7b4c2,1d45aadf,293842cd,56fdcd39,268d16e5,59d8488b,a076c82a,9587834e,87ccd65,c98feb69,9ae33005,299d2ec6), +S(d11c12e3,6646124d,c2602f0,b68543f7,e62ac955,8505f479,236ddc03,e9e6251,9d429bb2,d1378d9e,8e986f9f,a3d1349d,607df6b0,c48de566,d537c48e,10aecdd2), +S(d55753b4,93da41b8,f01da15d,ad5e71a3,655de4ae,b56a6fb5,9df058b5,f6636a9d,ee5270ac,db3d0e8d,6b46b948,9740311e,24925894,114d6c4c,52dbbe1,c4118013), +S(3f23ae1e,39238fbb,249606ef,d47502fb,30255e87,97148a90,5e3bf259,92429eae,845208cb,c6420538,410d5b2d,aaa28712,a2b77fdd,5241833f,124dd025,38d515f1), +S(837d504b,7f244155,1003c511,4e905b7,2bd9ea37,c690d9b7,381b2084,9cf7dbca,db355b5c,25d9b17,1167d31c,c5011a6e,2069863b,eb12164d,311e483a,21c2ff), +S(3d7e0c2,dab7f97,866a591b,f8187705,e31b7b3,bfea09c0,502b7a0e,c0037b5c,2a71d18d,f997d233,5a405ecb,d1ba09c8,8b282049,69215d7c,8a390435,8888a41b), +S(99f2faf7,8cdceb1a,70fb3076,3c19d54c,e16aba42,4e75be22,89f0e521,c73f3f23,778f4a0e,25c3844f,5aaa9082,cc985aef,dfe6e692,ab40eac2,9ddf668b,b28d0bee), +S(32dbf023,d57b27e0,5be2989,bbf1637a,7b3133e2,84d434f1,df8dcd56,70f9ec15,91d820ab,7a4f2350,49814592,ed2c46d9,fd7da87,a392b5e5,9dc309e8,ccb863ba), +S(2e413a5,b52d61f7,1290f182,9d24cb58,38339ebc,1b6d46f0,3c55334c,61ff64ce,474be10f,a3afedac,b9c6cee4,640424c,d7d3d6a1,437f2d0e,79e0b20a,8bdf2553), +S(955e7565,6052ab57,d05beac9,fc586758,780b8979,75642db,cd11fbaa,8e9deb7d,9276041f,cab762f9,929a6f54,a619e6aa,9613a794,96d32fe7,2e02ecfb,2a22045b), +S(1d6ec4e2,cc1a1dd3,f116845a,3173d350,c9607bd2,4e6db8e1,64220217,9208d805,2b6ff084,f5c42222,e29ab094,6f82b5b,f1cd6f3d,6d01a2ba,4d0744d7,ea95d0f0), +S(6ba994a7,9090acef,e756192f,91e97d07,82f393f1,c59f3b7a,786beee7,63ff0ec0,5c800150,c9464bb4,57190378,88247938,e26e54b8,93d25b7,6ef7ac83,78733f7f), +S(8b914ecd,2e19697e,83aa0196,70e1f955,530364fa,4f592638,b241a7a4,e07bd8ed,aafab68b,f3587e6d,8a078717,27e91eb8,4d327ad1,6fb89154,52a954af,e85f332e), +S(295e4ed6,380b91a2,a6628b5,820c11cf,ec407294,379b718a,5d4d88b4,3a2f9fd7,4e617c6f,b89074d9,818815e7,2a13d34e,58702106,f1470e80,ffce03d9,ddae9dd8), +S(efd76a5,217fca77,80aa7871,3dfb886a,f0b18e91,857ed243,2af704bd,87cb6187,e8f4d552,5e1e84fe,b89793f2,12a508d2,4b7ad2f2,903c38f0,d6729be1,6449cb1f), +S(44acefc8,e7148bbe,3c634bde,b8e4eb7b,618a135e,9c1b0ec3,6b160975,87284364,5eed55e8,8ba8ba5d,afc804a2,3cd5e1a,c161e4b,69d9bea9,da22b9f4,d130563b), +S(1e7d7ba1,475ff038,1fe4f0b9,71609d3b,d315d10e,329520f,3832418b,541b4174,887863ef,78a7ae20,acde554a,dd436aea,3f61ffc1,24023448,ac8f66fd,5e206869), +S(6fd945fd,d8043a74,c7c57341,a0581ea,c009ac76,1eef33de,277b7205,a7a248cb,6bb15fab,559c4d8f,32fae6f6,fb65c15a,222b022b,c8c57c06,b60f7b05,65f2760f), +S(34ccaf74,39ec22bb,2287400e,663350e0,1bfa2682,2fe851c2,faf4aae6,941bd5c7,91782420,76a254e1,a30b3ee0,29a19110,4af5fc0b,dbee533d,5c62a90d,2d9766dd), +S(554384e1,90581b4f,1bb6d971,9632e002,4476c913,30cdab94,5d8b86c0,491a8362,190ee656,95a73bcc,4faa6dd,9cd0113,ffae600f,fc13cdb8,14b2189,779aad2b), +S(75bc28dd,cf96c6d2,55981f0b,cf08df49,e48b162d,baa21046,89924a39,5db3386a,cd49b1f8,ead093ae,a554b9e4,d2fdcd18,ef614118,cf0baa2d,c83f2c37,92c23175), +S(4d094d69,15e92b69,b36d98d,8bc0e31e,ef6d49b5,d3d11b63,95bdd831,47cd679a,2aeb7bd9,98bb35ca,4554ed6c,91d92042,9945f775,8697684c,d0c63887,cb625264), +S(38b35099,7cde0af0,61ef1a3f,ab9e038e,988f670c,b06b39f,e611a5ed,227831ff,f0531e87,deba2ee2,117bb773,c933b780,71b2b8f1,956dcf8d,af99ee52,d69d67cd), +S(96bceef2,da234989,f4deec66,5a73ec91,6b284242,2a813a3d,f78c131f,4ba2165b,dc844f47,7ac5ea55,114aa18d,65950318,8b6592db,dfa62c75,d191e7d6,bbd70de7), +S(5badf11e,b896ab6e,f49de6bd,7b6adfef,840a0261,b173d89e,884bb453,5d7def8a,939707af,ad49890,2268485f,697d95b1,8082c75e,7b9d379f,4f7143d,27f830f), +S(ece21ae5,f5981e,e05869,fa9e581c,12773fa0,2b463515,55ded999,ce8acdd8,7771180b,9fc2d3f4,ce5d2ce0,a5e15c0f,4c29d135,62eee682,f80cbf26,fb812c9d), +S(650d7149,30417468,cb918e91,6234ff3b,1bd46f06,b90184cf,41d9112f,e472d26d,1f746358,4fd816de,89c86e9,39eab19,62a49305,775d8a86,6eb1ad35,edf48961), +S(f344bbd2,7ae90f73,b6f9a152,603dbcda,f14da6f8,f9ccdadd,88631de7,286b95a8,ae254238,b63ae9fb,89bc5be0,3e36a0bc,3bf15159,27094287,b9278988,b77a8ea), +S(982c94e3,a9dacddd,c1ae1394,cf93f8f4,91fa9261,ddd81e09,826b68e2,992c01f9,7527ad8b,39813588,6000a328,84b4f108,a4d6791e,2fbc86f0,b0038c40,ad280ea5), +S(b9885add,38946d2e,170d4bc2,361e44a2,859f2166,8577a099,f9d42c4a,170ff9db,edd69b3a,21836af3,a68c9e76,a7d62c47,3ee0042,3606ea6d,477126e3,b88f04e2), +S(4b34b984,4f57ae76,8bb666a2,b610b4f3,dc71b651,e23ae7ee,7eb2faa7,73a99e4b,4f4ea965,ccd9e929,b1d2830f,3bfe37bb,53be8f2a,a7c3a67f,9575d508,39cf2580), +S(ac8b24e5,9aa829ba,a7ebc7d1,4a25b14d,f770f0f1,158bd924,50b6e448,5af3bd7f,b25ad04,4954b659,8b8edcda,bc3b28d1,6b42a286,82602977,87c95360,ab2242a1), +S(88ed52a5,29858067,59b3ffe8,c1de8453,29d9c427,b7825931,57d8c927,43f1732c,d9dddf46,92f3d20f,7a99a3ca,a855a272,9143ceea,28c887fd,c054c6f,bfc25ba7), +S(f189d8af,9c34afb4,4dcfdbe7,996375ef,d8b9cac0,86230acd,e6972b19,1e1bba41,9a652729,1209b68f,722ff77e,38af6ff8,8595be0e,e1433afe,787716f4,8c69cc70), +S(6eb98d26,50dd58cd,8b7ee6e9,663585f5,77ccc3bd,3199d34e,2589b2f3,2deecd91,1c794824,bef31b44,b7497bd6,3966ca73,fea5ad7d,f640630c,37800e59,ac3d4afc), +S(75f5ea53,2e89dbfd,cbebd051,c129cfae,437e70e5,ae3a2d89,1b20588,94184ad6,faf379ae,6645548b,573142c6,8665eaee,882de32c,dfdc358,c778ccb2,dbca8107), +S(d62f599a,f29209ae,c7818548,f833ffcd,4d232d6,e297df96,4329d5a9,e7300c4c,61bbc3d3,79088b3d,ae30ad32,da25aa41,17b63b17,84bffd34,9cc7a5dd,9635e587), +S(2dd9167d,388f551,839fcda0,8c0b2f99,5bfb4fac,2f31dfdb,4cdf6822,72389b08,de646ee4,2a53c47f,11214ec7,cc46bb0,31ecd599,5d02935f,d49d9e0d,61c8bc4), +S(5e244f2c,87e222cd,70d4c4db,4020593f,ede6e3eb,fadb2d7,c260a12e,61349323,336b3413,ed5f1f7,f82db066,439e329c,323b5e68,26bd57a1,1038ffd3,2b236d0e), +S(9ceb7373,d13b017,1d1dabb8,4d22a756,52ee75ce,5943238,6784f06,4fa9dc80,80bf893,e4162d17,c7792fd7,d89e283b,7a6f3e88,fbccf0ec,251f09bd,93e46714), +S(aa4de7b3,6d1990f,5b2f2afa,4fa71caf,bb852321,dac68f81,c65cb997,306bf020,6cc882d6,577e5958,8d5a2a8e,ac18f0da,f29cdb84,bb1f6ec7,19b53600,4621196b), +S(dc1db767,2e425cb7,b1dd376f,37bda82c,6fcd98d7,c9dd1831,5368c4f,2e95f5f3,fdcdbdb1,926c987,81c0944e,bd13f28d,97fb9a79,2b7d4b96,8be1cc0e,a1c20b75), +S(3ef39100,83392f75,8a78325a,44dfdf2e,5083d8cb,396d2b0f,1e4fd37c,47cf799a,f057ff96,da3779fa,f9c66fa8,cc59801,44ed2dda,561370f,4c3e1800,d0dabbdc), +S(681c2240,fffaf870,ff80b853,ee1aed59,c2c6d435,d0319354,7c4ef991,1e2e4a8a,16eb0138,56342438,57d3af9,12403c06,6cc48eca,92fb6614,b839e46f,8b939450), +S(8d013629,1912293d,c39537c8,3ebfe514,3e831e69,c844a076,c227926d,e5f9a774,b422e532,e989ac8f,1369c95a,63bde2c,20f02ead,254699d6,bf3d4a76,375c08bf), +S(bdd10d52,da3d9deb,e664ad2d,e020391,665f32bd,7b236e02,adb6ad1d,7dfccece,201ee4d9,76d70c3e,cc06784c,a33b84bf,ebdaedaa,1df478f6,70128198,f1b8f66c), +S(2d34aeca,2ee9102c,bad92b30,2802386d,6e7af432,8aaeaeb3,939e3435,98715d2d,2c372a9a,4a4f0daf,a32acf6f,a40acacf,be6c668c,1306b93e,b27fb43a,a82e0083), +S(717776bd,d8c65a1,62ebb2f1,cea29ecd,9a843d5b,92f91278,3cf4c819,b26158cc,bec109f1,29997d51,e032f8f1,f453e222,4e2466ca,ae89fbd0,37a119ee,45588f), +S(a03bfc10,6f13c570,be92a85c,f72cde29,caa157cb,8b434ed5,c958f2dd,3c69ae09,8d76f55a,959eea82,c18d7328,2d5fa91d,d747fa13,67e64b0d,3d0b0a94,e58ee0e4), +S(b3516031,30e3198e,4a158cb0,108c8187,88c59939,bc813423,3bc51ca0,314832d4,3a5a4dcd,9fe0c5dc,bc17a082,396a93f8,36182c7e,2e26670f,d64ac6e5,8f022c27), +S(a927baa6,f7cf01fe,1993e1ad,c435edd,c806af66,6c9d2168,44a86bb2,2d7a8951,489734bb,4fe191bf,4535c812,a0e2d3f0,fd8020f2,ddeabbfe,c740fafa,7ccfb468), +S(54df921b,5848a4da,22c4dc63,c46876d9,53368446,e6106389,55ff00ee,61d75a13,25de0b92,52968196,18d606f5,d2c54e7b,fa6c1980,bdacd4a7,54a9b2b0,4015d8fa), +S(5822acdf,704948e3,c9112d0e,e718bcda,98eef3e,bb927d14,a1fe1952,1d64361a,c8bcb245,d5aa9e2e,7d527508,38db01b4,e2487197,a3ba351a,f2fb4b3c,19d03895), +S(a58c52f1,ca6983bb,cf2e8bfe,592b8d9c,b2a78dbc,e1f77931,14c95253,6a2d65c9,43626050,9c114db4,eae66452,599b145b,4d16b14c,cf7ce807,9a9c531b,7f3cc46b), +S(2db642ec,2bd88fed,7e624eca,e8022f7e,453cbfe1,1a6b00ff,726be4d6,89a72418,e3e73ef3,403e341e,e032ee00,e99b1f26,e710571d,81ac93f2,5855a8f7,32265440), +S(45b76e7f,65d895ec,24756195,187a4612,7dc9b31c,5e3e5376,e3af20de,b7e69a8,b2997f75,7cafe61e,f8a67043,a624e55,c10dc237,2f4b9d60,9692b269,7c616fac), +S(accc62eb,bee83904,c01a32db,e4af9b0b,50f3064c,bafee18e,eb49bcba,d53a41d3,34054eed,c77ef0d5,e865ea30,f505ba8a,ffc94474,5722651d,294a2520,fb7f4f0a), +S(1de2f5de,b1658f6b,6d20878b,9adb8a4f,6535965d,63bee989,fe23e4ed,a77f07e6,96762a16,fcb2aae6,ddce8f55,39c57f57,fbb45d09,26738e6f,82085d3c,ff0f20de), +S(5c51b67b,d4c0df54,ce75b09a,c399c293,4fd7a991,607a0aa4,a0f6629c,645f57a5,d1082c6f,66cd1aba,86df3edc,39b2e579,6e6975c8,ca018310,385173e8,5878914c), +S(8d7421b3,af8ad663,e7155f89,25bc9246,af7b3bd9,3c6a1097,afadf84f,7b041434,bdfa5121,e17dff19,6c105c34,b9d0bb18,8514a9ba,7dfee6c4,45c7855d,556409f5), +S(5608f4f9,f6d1a0de,64f22794,7fbdaefb,24b797e9,1f6db6ce,f3986d65,f0d4836c,1e03f309,f4c0f432,eae951f8,6e876f24,35364778,2249c36f,cd7115b7,8248a1d1), +S(24fced9f,ec868343,e6d6482a,1017853f,6687da3f,cc8e19d5,240a0991,6fa61791,8884a7a5,c742149f,88af0fdb,7cd59bfb,d318d8d7,60015afa,6bf0474d,eca7c214), +S(d9f8bde9,8bb83348,33783e9c,5d8ce8a7,85b9e335,6921bebf,281c97d7,bd000fe8,59d46892,a3d604fc,a378aad4,9645c747,2ecfae56,8b362e15,c0acb755,af7103c), +S(617f21e3,af5d65a3,a504fe95,34ce6bcf,71384bda,272ca49a,1c36ea32,d367c4d6,daf8e0b0,4bed8f7c,2d8ae9b6,afed54c0,904c6010,9d0c07ad,5f57178d,2cc037b3), +S(e1bbf189,83052820,ae65ac4f,e5a6d4ee,5b57c3b4,c0b2cc06,9f84b25,adccfdfb,3cd52ced,d7f04a93,86f4845c,49af86e2,c3a86984,fc4c77f1,3200017,ea68deb6), +S(83f82dc,7c709587,b883f1c9,e6cece13,2cd510bf,3664aa79,220892e5,dc2dc8c0,24c2a1f4,7c4b96f2,86265605,d9348dcf,8261737,56c5d91e,2d1beb4a,a857525c), +S(5ccbc6ff,c4362b4e,3d3a72a0,76ecdde1,1c1b07f2,680ac16d,63cca8ed,df924085,d54095ae,f357dbd9,5c12ad03,78f428c4,beaf44eb,23724fb6,cd0726cd,e1f04fb7), +S(c83a798d,c8b1ff5e,41ce6563,f35e741c,a6020a80,319b5543,1f81726,818307b6,c9cbf8a4,747baee8,2e156cf0,4b0d7762,2638e8da,7731f4ff,60bb9ad5,62b7588f), +S(c15d6466,c7f0bfb9,ab8a0013,300dc6a0,aad45c60,c2fcfbf6,7c9ca24d,7d2a21dd,cd5682ea,b41b707d,9b787315,8b4e347a,7ae682a3,cb950e1d,abad3b0,c8c42bbf), +S(e9606086,63b9bbe4,35826c1f,3830dfb9,f8479216,5c57f28b,9fd28d5,7a277a0,37fb1f6a,6d3cee79,ee2eca6d,c499fcb9,e2896942,f17fe885,25d2d57b,11c8a198), +S(f8a3fb79,afc8a94d,d69998a0,f4889dec,200b4b72,d2900c75,59371ee4,412df0d5,d5e0f5db,b4281cb2,ce21fb09,9176362,90351fdd,5961db25,ab677dcf,d4fbc0cc), +S(17f3cc7c,64540e31,ac6db6b4,ae67d100,46b7665,450cc011,dbb558a8,56a59b2e,9d815416,553ba751,79955382,12e988d0,eb0e0493,f880c217,5b90f423,5763b624), +S(6656be68,bf528239,51d7a392,ef22b258,42fb0646,8908fa1e,fd91d89e,a54f6150,741d5373,7da163c5,3e160d5c,b3f9f118,273c59af,75aec2da,bf788e8e,e870cb69), +S(67ec8648,83ad9ca4,22fb181a,2235ee66,cdb74f0b,f8e5b808,c37ee314,35598cf0,8da1ae29,4f37153c,1ad165b4,474a8f91,e7bdae4b,54b227c6,57e2d3ab,f3bf3fb9), +S(c9e8a673,3680fd41,83005ad6,97c78a4f,abd5d048,1f9bcaa,7c8eb209,68240412,fbad52cc,a0e510d5,e5c813d8,13ba4559,716e0787,4f48c20a,f783a807,c1848eae), +S(dc11b6a8,9c6b324a,f2d67e4e,9f59f32f,8898dbdb,d612f157,e0f24cee,d2709dc9,8c20a8a3,c273c882,fc6a59cf,ce74f115,1d0421d4,bc84a11f,2def142c,f2a8b080), +S(c5ec365f,7c0aa7e1,94fb5a90,ccf8fe3b,3c90e413,f3b24947,d8246024,7a2cc2d1,c5b39d08,b23bb1a9,c5886e51,abd1fb2f,d55ff334,81f020d0,6796d978,8801de79), +S(fcc03866,bfbe3215,9cffee9e,bd6874bf,10a5055a,5e56826b,37322559,5381650c,99cd7d3e,66e65f1e,5eea297b,f957c699,b844cc35,cd19dcdb,2d3a5653,f45b59e4), +S(7c96526,7ade46e5,693ecf09,cb052ae8,2a4bbcac,d07f136d,86df45c5,bf20521,db8e1dd7,3c961137,23325d6b,fb728dc8,f0a85141,ad1a00f9,53100aa1,5519d444), +S(39d11c0b,2169d3fe,4b5001b5,a8da1fe3,a7b14ae4,e329b931,f7db92d,86acd02b,46fe1f3,65805c5c,3b731dcc,d46ad37,1c2fb6f3,b446e466,ab80aaa2,5200302e), +S(3acaa37c,4acb28b5,6af7f970,ce279372,d2b998e8,5ef20932,492ba5b1,7b79240d,6effcb72,4a7c7dd8,b8bea6ca,322a8540,f38cc5df,a06677c,181c45d8,c4e4a4f2), +S(fb631a1e,25daa546,47492d26,fafddec,6f38c08e,e67e67d,af1c57f3,ac3ac79d,90b04e04,c685e4bd,4817c367,22892881,fbec8c09,1e5aaaa9,7fd6a163,b68f2eac), +S(3edc2ef,2c609f0a,c77ec4c8,c035a537,3d4ec7e9,6addfd7e,87f040d2,df98aaea,7e549063,ba715cd6,35719b86,c0b6eb30,68a71420,7f480f93,6d78f0a8,d9251d20), +S(bd4f2218,7a9f5164,a864dce0,2bd1a89f,d283e62,64255b0b,21d2f6f2,62fc419b,d5eb78a9,d2337e68,3e3a77ae,b37b170e,69f1400a,2383b339,64dc6726,7c5db5e1), +S(434d9881,70badfd9,5ab26ab,90933eb8,89bc6a88,60e6f412,1e5dee2a,f82341e8,c6af879,cbd7d5dd,16c3b06c,810d0263,2853986c,ffb11fd3,aa2be2ad,db55c4e1), +S(9633c8b0,653d8010,e785ecb3,d710b43c,37ddd97b,20f26c4,f9f41581,cdbd991c,13b53adf,b4841e2a,2590609b,46b604aa,3bd6e758,4d443db1,6a7ada9f,9a49fb71), +S(ba656a98,c63d18f0,c4aff8da,3bf05cf3,e3781cbe,db5d9083,a8828fa0,c2fbabfb,90ad3738,f28fa937,cd4149d7,90f8b4a6,d4989c5,5218023f,37742c3f,1814896d), +S(cca5c935,ad4a690d,893b3bb9,cdaf2e6,102c44da,d9446615,2a39206d,777ca72,3c060ba8,b14da1ad,41991c64,95e14465,9361c724,d895a0d3,a3694d45,56c7a146), +S(b22a22de,c827e8a6,dc630b1f,11229bf7,ce8a5030,608392e9,b03093cf,47afb358,b10c49a1,4b30449c,200bca1c,4a0f3df6,7d978988,1be46597,c1e5334d,5b5a2e4e), +S(b4253d47,beae6a36,1dc45090,c358275f,fb8e0696,11e51b3a,1aa7c2f5,273ef8f8,c0f4bbbd,e98d0960,f9a59809,83d8c4d1,35eff1c9,2ddc9f2a,6ee05146,eadec66b), +S(60d75d74,1a85d65,b9edd2de,8a03f6a5,5ac6d000,d39ca913,9fdbcc47,fc3da6e0,fb138bcc,da55de59,d496b784,9532d99f,44935e6c,b08be8dc,beefbb7d,74e1fe7f), +S(ec63d10,e66db9a3,7cb5b88d,811f2f6e,aecf51a9,e39374ae,92df325a,aa560a85,1066615c,d2fe8397,d2dd458a,f6ff36fb,60547398,29e6d6bc,74525c29,8c3d3c53), +S(8df7f52c,8324b50c,fac3e27f,6f230e9e,e4926895,c8f2785f,560ba5ca,98b9feb9,6832846c,a78a18ad,3747b1fb,d8cb6a94,fb3b4977,3db3c0b0,c873507e,f1519480), +S(f17e21f8,e97bce5c,2e63285a,f9e361c9,4a2e6b45,f437c1c1,a1310988,b63ea49f,12690d42,bb90b05,2fa4b1d7,d517f7bd,f6721a82,e0a9059d,caa5ed15,a7acf7b0), +S(4b0e0297,729ceb7c,4c6a4caa,73d76ee5,9d8f8547,9f582fa8,ec678339,58c023af,73f6affd,3afe58da,5ba3e0c0,9a043e8d,100f1275,dd9b9dfd,42ef4f47,a1aae067), +S(203174f8,fe8427ab,42bb517e,67e9c13a,3a39700a,158c3581,a0c5bf76,79f950a6,ac630f01,6b268772,72e422cf,b74a3a1e,dd1f581d,bcf2a1a0,54946a15,108c70bb), +S(ac34d445,cfa711d3,fa7a8c5c,bff5206d,d6dbd22e,737c5b21,6e6801ca,362c4b35,91a0a6aa,fbeeda5c,abeefb76,f1bd4b23,e850e1a3,9886344b,282dd0a7,f0b6985c), +S(81ffda88,a45f8b82,e3e249a7,457fd1bb,34ebd35,58619855,6ff7ecce,73dc7998,eeeb1a42,125877fb,640b160e,4930ba7,3f1e22cb,51e33946,3935787b,5d6e353b), +S(1a281d34,5b4f227f,2a6d4139,db2e29a5,7493b1e7,f099edca,ef68b3d7,dde37dc6,63baaccb,8a5c1de9,f1aa33bd,2fc19189,619a71e3,f9b290c,83fe7643,bcbfcd25), +S(ed9042d9,ad110ff0,6be64aa4,cae0422e,c9a8aa79,4dddc1fc,52df6098,8de1ffe3,9ede1c43,5d6b8a7f,61591d37,e166485,3071c894,f18f85d3,d8f145ce,98208b95), +S(1f5b14e6,1453557e,f3ccc7a0,1e2864ef,43dac2c1,ce737ba3,ffefdf2a,3de9622a,c0d40622,5a4f8b24,59ae2d22,69908c81,5f901125,1e46a683,3df83659,f2a474e4), +S(218e8943,96fa8e79,2f29b53a,de2f9155,94d95a50,1eb1a1a7,c8b01b32,75e8c117,2701de34,af2aa192,79dfc9fb,391532e7,56824da0,38c60624,3771dfe5,aeabbb96), +S(d6ec122d,463c0f2d,a994bc46,a968693b,f282ad19,6a6471f7,6516b5d9,2fea7303,57f84e4e,9d439701,19f58c6d,426265c1,25734ed7,c10db0e8,e5b87ebd,d584981e), +S(3ffb48a5,58fd6f85,b1609710,1be54107,6182a7f5,a5692074,48d82dd3,e8027e40,aa410f17,7c08cf25,a7a9e9eb,33f2b83f,c83989fe,7a737e23,e0aec6a,6eae2ca5), +S(c8c69bfa,450cbd11,6dd51750,a5fb2f0b,59b4f489,cf05c670,91a49f13,3963a50b,879d8a2f,a1c26933,5719a389,d504ebb5,498318c7,acf103ee,348d27e,cf83886e), +S(86097033,ad0a0d7a,982e748c,bce06089,2c6b55a0,17bbcdc9,d26166cd,b0fc1e81,9fcdd6e5,17916ee5,ffa48a50,a0df8ff,98a06,82059d92,43a2194f,fc89dec6), +S(37cd256b,7502a789,10296144,bd41ade8,f4a158e7,68b6ed2,723d3e57,cc5bd099,5eef9bfa,6e5e1bab,8d8170c6,2ad90725,afc38eb0,db145f59,35520a7b,7518dff6), +S(70aede0e,f89ea93b,702fd3b9,4f81a48e,aa36cfbf,f4775426,37b0d00a,80abede8,b30aab37,206b8c1c,2f852ed8,348cd387,d676f6e1,2baf457b,97fc49d6,91490f33), +S(2504fac6,acad5f23,81cdfa76,65fd1859,85e3b32d,d1767394,85d63f07,500c963e,7a455f78,9cfdc25f,d6ef9c01,8e44e6cd,2702ee9b,fbbad8a6,7ee228f3,fbc56d61), +S(b8bab480,d143bcd1,838f7f2,d13b7a54,8f7302a6,14c03cf1,3e4fa971,5478c280,8d1939f3,abd45a47,686be62b,7c079fe1,2cd2a3d6,78478afb,d21327e1,3599611b), +S(19370ea2,2e6937c8,b7d600e8,cfee9b54,e1b527d0,85d3a17b,ea2daf7f,2e6a410,c721f3ea,af20344f,98692ae1,b88c7ce1,8655a4a5,9c2c945b,aeab2756,a5ea546), +S(5e19f6c5,10bb512a,798fe39b,cb37ea2c,da70c76e,d7d1c828,9b488e9b,84ea224,ab34bc16,50a99345,772aabb7,f47f0b2,f92fdfdc,4ce7c9b4,f5bc14f,5b946b39), +S(e97888a,cd62f21e,76f5247e,fe64291c,e69b8b1c,b331a2c8,292bca63,f3dde54e,286dded8,ec435a9,2155fc1f,18688e5,e69ae21d,eff79a6d,c534e18c,3e7b114a), +S(4361dc3f,9c039f2f,750e4172,88ba8d7,36158f28,d5e0869d,44207ef,f587a8d,b05b54bd,2097d8dc,c7ded5ea,ac07e6ac,a7974500,8337891f,4b5d6c71,672cf759), +S(8e679eec,8bf365e,e5324330,3437dccb,768a3955,3c3135fd,3c168109,5ecacce4,b6dd115c,d19ecde8,4e7a2fae,be358448,3d6277d1,19ca2aa8,3bb68ae7,f5e94f49), +S(e2d80539,947ebd32,8716ce6c,74e5f09d,eabcf539,2e84dfd1,2e33219f,de8b77ec,d4515668,586e8753,74406b32,65c9727f,92e71263,b0f77447,14de6f0e,732fd175), +S(a2527f0,c754ac94,29bb5dc6,18efc820,d88c8490,df39cf13,a25b0136,37196f9d,bd16d989,90676eb4,36e735df,94a5a5d2,28aa4185,24766ae3,2c7bb12a,e9aa0508), +S(bfa67870,6db9cf88,139ce56c,4f5165c8,38a5830,d1673a9e,b4b0a218,a3a66319,f6eb6944,dd30d6af,a360a7cd,b360f58a,c17dbe8a,7eaeda38,f3b1eb2d,83c02e0c), +S(1d5bf7c9,9255f96d,b91a0f5d,82a3119d,f3d491b6,859f55c5,59389e90,a2f533e0,132b1468,f460932d,7e0ec514,8ba77405,8b8cd4d,3e47acac,e52ec9fa,618139db), +S(44f90837,9b8aba17,44415980,aec15cfb,4edbbe4a,23ce6885,9e4ba880,8a67025e,9c4f9d97,6f1581ac,29818a6c,58c70ad9,ebb08f3e,83dc1b3f,667528bc,3a1968c8), +S(f100be57,1d4ddee5,291e7123,cab57bd5,c5ecb8ca,6c8a90c4,d2f01f73,87b175f,8899a16e,3a7ad5ff,f0e3aba5,fea86e1,974dac4,d736be38,6c2ad93,8020a6dc), +S(e26927c2,f3cce898,33a60369,2513aec4,ad0d8f63,2bdceafa,e5f6900c,716be2bc,c1154830,52dc4674,238758c7,d7af495a,f32a4d01,e0c316ad,301606b8,d3136383), +S(e3a3fcc9,8fcf1ce8,fb994b68,f92b2fc3,c114f2cf,321e89a,c3ba7886,43b0f2f5,214f38cb,7020f57,ca4bd953,16960c9a,250feb38,7519bfa4,abe025aa,dddd072e), +S(59ec03fc,5195e0d4,a8df03b6,a96938bb,d5fa5a40,161f5ce,2480e205,dfc0dc3e,71421a9c,b58aa65e,180c97e7,6a90454e,d5d8a2f7,739eeb09,be7fdd80,47a4ecb8), +S(a53cb7d9,3dadccdf,18d4d01c,6217f39a,be621089,821aa92,362db85e,71cfa358,1f989a47,77a2837b,f797c249,4539069c,a24a23aa,8f1e5b35,fc401dec,69d049c0), +S(170b9efa,13e1c948,a5ea39ac,e688408c,1cb2a57a,a55aee52,e4fb21ff,2f7329cd,f092c60d,c4f8492f,d718aa74,fded9cea,426b4,7277d724,710ac0d,53ba7039), +S(e1d16c75,893035c0,63eb41c8,36bb8bcb,770f752b,718a02ad,24e688da,79ac3a14,2d58df,7b7bf0f1,60a091f1,b0b209bd,ce5516d4,53f8b799,5707721c,66ed2681), +S(d45a1024,78595ac1,abd9a582,a3afdd8c,5d33c7d4,caedef2c,747450a0,fd2d675c,8faa7ee4,3923474,12012dc8,cca109b3,dd19efc,52ae73b7,508b23e7,1826732), +S(d3f355bb,b2ecfa66,592ef13e,fe983e22,b2b90538,ee2f0aab,ee1fe982,62c336cd,ee99b839,7d4b97cf,a7851de9,366d24d3,70169091,81b5a10a,50fd53ef,bf549812), +S(6ea90fb4,e58f1eb6,f27dfba2,acd645b1,1c7cdb0c,dabf2d49,4fdbb4f0,8ced2c56,74934a84,871dc011,3e18d5a0,aa3207a5,e588a3cb,e8a3f350,4a06bb73,8ef93abd), +S(de4eff0a,ccb612a9,a79d0983,94e8a883,da348aad,74bbbea7,d477e45,c2b87436,9b30581f,b903cfe7,610429f9,f6ec1ba0,df63038d,db8117ae,ec67d7e4,1a28b9b), +S(4ba09b19,f129b3f8,db86d780,4630c6fd,9c22d620,677c66db,ce60b69c,c3bb4772,fb31e85,ce50ea1c,13af1c7e,93d9026c,e5f39474,9e91d049,1b459970,c169aa77), +S(7fb3c3ee,7c600ca7,6a2bc674,a497bfd6,67b0124c,f532d5e8,55aa2c90,c4b4826b,29b970bc,b8f5eaa1,616f3695,5a1b17c6,60b15b1,219388a6,b47a55fe,6cad1eb0), +S(ac29cbb5,dd2a95ea,5a3b6f57,8c2111a7,6bf2b060,267b467d,5ee8ed2e,554153dc,89d4c22e,acee2b3e,7e7872d6,5d1daa52,54a1a00a,f6b0f7ee,16d84477,45d01c81), +S(fe956021,e67458aa,c6fe2cea,730f272b,19fe7de9,18c98a40,ba475dca,af3142ad,52c6b42d,6fc03eaa,3ec7da94,5ed12ea3,84e16d0,590840df,6b714a59,d4bb814b), +S(336491e1,dc3fd4,8d63944b,2578a415,5727daa9,6e853935,a77b7077,d61984da,e9b8db61,51fe90fc,9bfc0635,5b9676f2,cecd1321,292d2a8,c6e30e9e,6b1478c6), +S(245c6818,aab65e40,806f8cb7,721b7dd8,b0e3854b,7daeff8b,da5827b6,4d294df1,4fc22df2,e7b93b96,b60f2ce1,a659c1ab,1a06c7be,18e5c80c,91e4dd2d,75bd8ec), +S(8c89eac1,d9ca6c06,8229986d,6d22bc3c,817dbb6c,575ff654,36653101,1a60de8d,ebcd4867,323bcc7,f8dba216,4d827a48,8b4763cd,aef0daf2,5a1c1437,d6379ce5), +S(afdaa93d,7ea7f666,e737a379,914d1b87,6899cd9d,5202e985,e365d75b,806453aa,e3e9116e,8abf33b7,ad036291,2a3dd016,2aadd1ac,902a9448,30248a60,6760cdac), +S(d447b974,fcecfa15,1fcf7ed9,8762283,7ae28f74,be8a2a2e,22c3bbf1,d9b23071,a3e79560,f79524a2,e206e9b4,1cf961c6,8f6f898d,43694114,a3f89495,6ecf970d), +S(53525693,be8fe724,c970f4c4,2b46141b,321e79a,4ffa411a,5d947bee,ac235674,5cc74ddd,7a74afe,2026885,1fe180c8,dac3246f,8c4ba44,2032d584,8afa9f4c), +S(40e60cea,6008aaf9,fee64781,b5adeb9b,f23d2db5,94f9fad,b7394481,da971273,fa32f2db,263c1f7c,987671f5,68c714dc,9d3ecca1,2b20655,2b23e5cf,8a365b65), +S(de59a6fe,1fff672a,c4655e87,f6440e4c,bfec2fc9,135f1049,efe173fd,d666acaf,205e5ac0,8cb9c3f9,9023b6d6,795488e0,61ea691,439a22f6,48bf0da7,cccccde3), +S(89f718d0,23f80ba,df0625ea,260f6ca6,dcf8fcf6,e79d35ec,67e535b5,e9cd06a8,6acf9bad,6dcc053c,f7e193d1,a4c432f5,32211761,aeffbb4d,1d53d737,6b3353a3), +S(fcd5af97,603e0558,76f24ab2,eb82de83,3c8cae9a,f19ed307,f7da1da3,f1fdac3c,3b7ea3fe,bda44592,abe9240b,8b06cea4,3a8a0ab8,aa862c85,36a17b18,fc911ab2), +S(208419aa,670256d7,94712f59,bedfe025,ad9ab43b,2037783,4e4c8f4e,9473d6af,b6171d6a,20da4ffe,f46a49ae,7233206f,d9ce1ebf,89ba01ed,9b86896e,43c9fac7), +S(d7ca0446,88d411ca,c3f3acf8,1bc3f3e0,a9feb9ef,94bf31d7,8a15563,cdfaece,3a361b1b,2ab89d27,6e120d38,7c31f97f,c4d5880c,6ace1813,b4eb95fc,37db069e), +S(30b96bd4,b284e36a,f790695a,e2c8aac7,672a0496,2f9c92f9,694780d3,92b60bc0,6e2c7f8e,d1e0d081,a34ea062,591e1854,6f79a9c,60daf218,6513e4e2,621d4852), +S(5ca0493c,3d516b44,46723477,fe8359d5,6a2e01b7,28afdca1,343de88e,92411590,60bd34f8,7d4bc12d,4179da44,3595b48c,17f34f19,b03750a4,6904a242,93af0e93), +S(de3486eb,22faa1c9,ccf774f0,e17da3ef,3ab5f7a5,ed6ba58e,bfaa2c1f,cb5c0e58,af8666d7,57c13f3d,3c2e6b02,1dad5ee1,ee4f4c82,97960b5e,84135309,4188936d), +S(8075138d,59a9cee9,5320cf41,cfad010d,90efff9b,ad50f2d,dd3ac7d9,234b4576,ea48ad8a,6a8ab6d3,5cea84ea,365b6a33,d3d593ca,9d27c5be,2df2907f,8bc5d91c), +S(5328a0d7,17f0c7d7,9b8838a,abcb0875,77eba66,eeac756a,6a365657,d4d710ab,7f33d5ca,84206a66,a9aba1,2dad6805,9aede27e,2b38d755,53756d14,9b4b5a1), +S(9fecd234,d25771f0,aee9dfa3,2286697b,faf4d34f,83eb7135,a581b225,791ce0e5,3e364215,d2eec5a3,632f01f9,9699255b,e90303c8,eeb0e8b7,56cc239,20b2dae0), +S(7084b279,e89d0f23,967a1635,96a1090c,4264504b,c2895b07,fae5f128,93150c02,481d6078,35628b54,783484e4,d4f299cc,fa3e6f5,bad67457,1037797f,b3fb7f96), +S(bbd3583e,8b7ce417,88cc23e4,eb0c331d,c8970d1b,7b186ee8,9b4cf45,c83686e5,f94d7cd4,392a9589,77ab3956,a91024fb,b77a608e,91147a6b,4be6cafa,69b9193c)}, +{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), +S(8282d8a0,cb008916,33654a11,fbfe16e,8d2dae0f,ca06175a,5183ebd,de06ec8f,44128945,d39e1b71,cbc914a6,21c95329,b6ac0b45,1f1921f9,725ff10a,2859af90), +S(100ee34d,993a06d0,cdcfeab6,3eadde22,7be8aa84,a9458fee,61448911,1bffe20c,c891d347,c63acb,c72a2a8f,c0d8d41c,2c32a9eb,5742ab35,e76b573b,3817b9ae), +S(9bed0413,465a899f,37770b6d,6e847223,28049001,73efb872,aacf122d,4eb12f1f,745eb015,938e3ce6,d38068f8,90ad253a,b0b1bde2,de636162,c0442b66,6e9e1e61), +S(2896ee21,34276bc0,131a10aa,5b0c9b39,ab5aca5a,3ceed61,cf2d27a7,5404d264,cc51d26e,ad555071,e57bf3e2,dafd77db,4f58b6ee,b844ea86,5da39b09,ef3ecc6f), +S(b95886c6,e569d641,b8e32555,bbaa562e,1f07589c,5a8f3810,d4bfeb4f,e58711f1,3fe1536d,551770a4,cd816eb6,46f2b864,77d565ff,3091d916,af8597e2,d8988b6c), +S(b32e3e0a,3ca6518b,6bdb2a9a,e3471248,5387cc5c,ffa32cca,976be3d7,ebdbf1a1,45d998f2,828248fb,2f97b503,8de02b38,493f5b62,ab8b0d7e,75cb96f3,305680f4), +S(8a760935,8c3682b2,fe8f5b8e,a9c76c61,f66ae677,48294bed,9d3c64d,702d3c47,77110a33,eb7562e7,95032a0f,5027d162,28131575,323c8f9,8aa0bcd0,9328992e), +S(ef709552,f80148fa,dc1f7007,174bfd85,81b03db8,189ca3da,96b3e749,b1843ed2,b8e9393e,c3cba6ac,2cdd2d04,6235f7cf,14965616,3722225b,9010727d,94b610eb), +S(5071af8d,2e37c4d8,11225f8c,543863f2,3d5ddfff,be2576ca,42630f38,1b967483,37248038,487113f2,74ad07fa,7dee36bd,295971d7,3a30cc58,629dfc68,cf65533e), +S(88c9a5f0,e76871dd,3afc4ef4,5643419,95642dd5,c8b1e386,b71c2471,c591a3a4,a77afc95,71af8ce7,60148b15,1e1fcdbe,c48d3b2e,580b9786,9d80196,2ce6549b), +S(fe643b36,a0ef4165,e591345b,5963d37,632c8fb8,97114b60,c4ba6f6d,c07f9033,e3c7bc7b,865c1d,4c496f36,9a79e6f7,1f79f6,e6929f26,63615855,e9509ef4), +S(d35bb10a,a23d2bc4,d2aecca7,51f1cb24,2133fc16,9f008ce3,4a29b93c,7ad21f3c,57265f67,dec367a,7addd6c3,fb23fde,f04f42f9,a291e291,3f2128cf,df041f07), +S(e3c8d76d,1ff5e0c0,21668bb8,f425487f,b7bd3a3c,eb3df289,5e4806b4,177fedcc,abbca449,95abb588,3e0a6959,6c8108c4,ddf8a50f,6c43e507,59f85556,be49efc4), +S(b7e31e11,cebd568f,658eadf7,ac57f265,fc94073c,9a779f21,5016e5fd,705f2580,da4dc770,742cc6e7,38d05ecc,6deca283,9c06125f,bb911cb6,16f0fedc,84dc2815), +S(bc486422,ae3e277a,d24fe096,120decbc,4a735e57,8bdd72a4,b3f9006a,859276d5,ac246a6e,a145a990,51c62762,dcc47fc9,ea9bf93e,7bccffd6,c82228e0,49686165), +S(79d0a8d,61039dbd,1787b140,9d8109f,3832112a,8e1ae97a,346ba122,c9f66eaf,9bccd3e9,b9b2c673,c465fed7,b774bfd1,833621e6,87727a5f,a8959528,9ee034), +S(c58bdd36,646e3dd2,ae3ab0d8,8c9b352d,c319d1de,c132493d,11f2942d,1f7592b7,ab923ba0,2cbb4bf4,35212358,66b0a420,41677486,3d67cac7,ec5e891e,b2415f6c), +S(3865f065,42ea6eb2,a0741658,5afce76f,d87646bc,a086ea6f,5838e9c6,55171a85,8c7b87af,c049de66,8578c89b,e5a49c85,64ab35b7,afa39588,6312d680,837415b4), +S(10c1b93d,f7ef0d97,4583889,d07b7680,b6ec858d,b45f9a2b,c36a2f68,9d77a4d8,3ac497e9,15b7470a,f9bd9c43,1ef3741e,b61cf7cf,a2e7fd3f,e1886fa9,4211ae45), +S(1ecd15e7,3905fd66,a86a96fb,16118d4c,a6da82d7,672f2361,fd101a3c,7203c90e,4974d5e5,9b8ce7fe,30671eb1,7bcd4d04,97c57b78,a4202261,28eea45e,b3b8131b), +S(808fa8cb,40e6440f,ab60ef45,65caadc8,f86618cd,e1c0d900,587dea31,f49a589,511ccd1f,ee3a53f1,bd12f1d1,13098694,34579292,74d13973,b0aa29e6,91d889c3), +S(e1035b36,290782dc,9e578522,ba51aea0,6621e7fe,8d5cc9ba,af0d131,ee00a6cb,ff12d04f,1d5c1bfd,859178e4,368a3a0a,f73e125d,35049e60,342186c6,ded5a753), +S(daba0ff7,a9f3cf3a,2f05cae5,b2c6a881,ff9ad5ad,9dc1f853,ebac7384,5a48e230,d4ae471e,2ebfbe0e,dde343a7,83d9fbfb,87c3d179,c72da83b,8524479e,19bc23d8), +S(106e3bdb,beade62,e8ec777,bc4044ef,c6a04d9a,5a3b5396,44ff98a4,33c94b92,1d461e65,eb1bc8f4,d3aa5773,a5cfef37,2e55dc46,45f8be3d,f53adfee,6e7e7d75), +S(82424b42,7b95dd6f,5c9bec59,b1ab98b0,c7fdb4dc,fcd1f8d8,574f4b89,6c8d359f,aedc4fba,825c48c7,4c466738,1cddd6d2,75748661,89499c96,297829c6,27945de6), +S(71213056,13ba1e9b,8b8e6727,74b718bb,2cea1e65,ac944db1,9050f9be,e6c90c84,98c54a0b,8f0a6d3,d7e821b5,907ac930,b79e683a,3ec49a39,f5043d28,acae4144), +S(6dc2c201,78620ac5,d99cb81,8474e5e,de8ec3ac,2366bb8a,19685ece,bde25a8f,2f1dc21b,abc65601,fc706aec,50b9aecd,954bf039,e3b066a0,54fca082,287b026d), +S(e7239283,2f6a23ce,252e2493,5726a774,497319c0,9f0fd327,59fb594c,6d9c8257,165dfcdf,2b117b5b,73bc5096,26b47ea7,c8d5b8f0,24beb2db,bc0f993c,d30418c), +S(5d44ef96,eb90df1f,488375e2,a3e75459,34169a9f,5bdc7477,bb7d1bc5,1b3f4ef3,87da9f1e,3346fbfc,6372637f,da5c1e13,eb561d61,ecc68e03,8167eb82,d2d05bda), +S(bbd86c11,dce2eb2e,d7424033,aff54543,2f2aed92,5b433436,f93ad8fb,57816732,f415eb1b,e921aa07,6b7b52bc,773c7e9c,f89ef076,95aa86df,92f4b72,38507c8c), +S(633050b7,3000259c,42bb380d,815b2219,14e78d79,e2a7d979,29ca8ad9,cdc40fdb,efe2db3b,16d1c829,ba0add4a,c07e7ad5,f021ba2c,9e53ff12,c93a9c36,4021779a), +S(70c4392e,d4a1652b,ff89db4d,6b1eaee8,870e1957,f98f0271,d7fb430a,85c76bcf,4d0917aa,96368ba,45a567f7,c05505d6,a349faf4,b51c06a5,848bb8d2,1fd80f0a), +S(7abb4651,6baa8c3c,47fe60f3,6ac3f91e,92d6e09c,cb8401a,a2a3095e,107df5c1,d8445036,8eb5e86c,37ba9b12,f812ba0f,f88d166f,fd1ebd98,67632a24,8eb9f388), +S(65c27141,24444b72,188eb222,650e99cd,13ae852f,e515d452,eb757225,17f63fd5,5bda906b,e1dacf0d,e65e66c3,23ad6dab,15582561,ec4faf17,35de87e4,a53ae7c5), +S(416ebda3,baf7eba2,877f312c,f86c6517,9f422d8b,8379fe9f,29b5115d,f1ec3364,ac46579d,ee0a19,bc5d3749,142f42db,6e934f90,eae78e80,d96df9e8,f932907e), +S(3d94add2,7a320b3b,da7f03ed,ae29d1d9,cf022b47,b7a0ea03,6081117e,60cbebf3,8fc54299,9bd420e,96f464c,8c3a56bb,2f1719e1,20eedd6b,37084251,f406206e), +S(4f0a9e32,76447fe9,2fb48cfc,c962a0b7,b7c391fe,16c41c8b,21a6e563,53d7c218,441e9d39,db107e8d,d8f0a99e,cf791c,2fbb37e3,2ce1d821,9011a8c1,60345bba), +S(17165596,c15ddb64,83b4d45e,8be57fe1,2a37da06,a47ad7d3,a190e88a,9d58e0f8,ed06f5d3,167dc12a,992dee28,ef331ee,443f6c9b,7e485386,7a2f4daf,c0aaf64a), +S(62f6ad56,5d8c3ede,f50452cb,4af3866a,9b40b729,ff1b66bb,c566ce9b,b07b37dd,b790cec2,a2fe6264,5913b5f8,4e2f2ab3,bb45537e,e7783908,1d8928a7,484ff315), +S(c3b43bbc,522390ec,353a2a4e,47e04008,475731d,1fb4c67e,f91eaa49,8553d857,82e45f4c,81adc79d,5a7af4ab,36cd2628,416f1229,994d6e69,d260734e,55d02eba), +S(3a943612,ee8e0359,4559290a,7d55a549,f8173b03,b04cf28e,8abcedec,38c5a81b,d63e8faf,90666215,5f74a6f7,6509be2b,c5aa2b83,b75b18b6,1c1da05d,f6c55ad3), +S(5f2291b3,1aee7ded,21c3f1a6,77e53e7b,e101be5d,a4fc29f2,680cdda2,fcd94be,fc0b1162,7dac2084,c5ad479c,671564f2,b2b13e60,f101af4b,5e7959a6,70b1fa0f), +S(4ca0b91f,9c0cafd5,b9f577b9,f1b84515,70b0521,6a4f0c9d,77c6c106,99c1036f,b254845d,cfd558f5,11d5125c,68f1d65e,7e3bb173,bdde887f,d9b48718,b45d9521), +S(6ef57d2f,6f1eaa88,afba085a,d5882c4,4d823f74,f65d16f5,4bad3bc6,940d9985,52f44465,be358f70,3d0fc3cc,3c3373e5,56be7d9b,6b0486b7,6daa8519,f2ab521), +S(dcac3acc,a1fe2f5d,e231a6ad,74da4a52,7ebbd474,d3742cc7,8f0ef74,172017fc,e0b7be39,4d422b45,be66848d,b8fb6d9d,25ece5f9,28d2b97f,db0a491e,145d0340), +S(da9601c,352fae24,9d92bcf0,6403a08f,5b85ba77,a26dd30e,851027d2,f2def143,2bbf855f,996b6358,30481f7e,794c993c,e8e5afa4,6482602c,f12ee666,ca5d24f), +S(c1f8edb3,fdda602d,ad4a53d6,5e1be6ed,cfbbed8f,12e593f3,470d0485,e4c4a3b9,51003ac7,1cda53be,7be5c073,e530da8a,551d69ac,ee40faba,90cf5c20,824f28e2), +S(71ee3721,ce03cc75,27c837cd,88018278,f2a6f05e,a70b2b4f,323f9fd8,1f8a8bd6,8a9e0467,a7ccac5a,f5adda8d,7380c84b,80575e31,90335247,41abdb94,c1fec726), +S(eb5604af,d835b055,ed67f5b1,fbc145c7,d04f8ad5,f056f13d,2166e6a1,c2eb8c98,85ff6263,314129bc,1902d56c,f76395ca,9d70ff24,2bcb8a0a,b612d46a,b6b2ef3), +S(7cd7eb9f,5edc9246,e33d0734,e2c63c09,f23fce37,cd6c084d,c5d370f1,42f58f21,50485ab7,7ee6dcc6,4d1291fe,b08fd861,f954f35b,1f64a4a6,ad4e30ba,5aeff269), +S(25674f3d,532dfc3c,10d33f39,215b9656,4ee87199,c86fb142,89ed917c,a557be9d,74d20685,274f832d,8406633c,29611fd5,f288fbff,15f6c9ef,e21b911,f26664f9), +S(106de86b,33c9c46c,f0846a80,89a6f140,1e614599,91191ea3,58b877f3,9c7c4e1d,7ab4fadf,4b78c6ca,3a11c0a1,4b47738c,2ea53040,73b3f4f6,7cdb7b9b,74ecf74f), +S(b901102c,4a27cb1d,bc8697d5,156c4efb,8f4a1eb6,7d1af30,28fe2094,5809a195,2fde128,5755900e,3d87ffac,c3fd368e,f84b284b,e30e6122,c518ec69,96b2b56a), +S(9b4d7f5d,5cc3b009,45bab53f,400e942e,6ee7a1f0,915db960,e3a319bb,2d573da3,81507aea,a3fbb6ea,75f42bd5,bc044ba6,60e89279,a0103ecf,2d99a03e,5fc447db), +S(806cb351,48bc2e18,c2261d6,22bd1113,ac9037e9,90318085,b9c46082,a19f9b83,187da40f,a8d49de8,5a6d2f66,831b8b33,5f575c39,c7c95eec,a9a30d17,dc03966d), +S(16633996,fd30bf59,f28de170,7ed7e8c0,95971754,ac04677,9e525b3c,9541be27,27ae75ff,ca485585,c6277177,7f727dd7,bce2cf00,205d9f49,43a74278,b8a361ce), +S(166f9fa0,b7930124,38912819,d2601bc7,e24b246b,9b19f53a,64f69f24,43c421b0,6289f5d7,ec71e262,822bf209,5855a7be,b2b248b6,2dbe3133,221e1ebb,84a3e7f7), +S(a656c927,7129451d,6ee2d455,9acb3c8,b15fc7ca,302adf2f,3b250a8a,499e13bd,b812bf3f,fc2d1777,6363227c,6ae339dd,39120131,187bbcad,2cf2f792,877a7993), +S(8e3275f3,4a20d2df,b236d99d,40a704b7,ff23eb63,2746767b,75e6a9e7,b78245c2,d2f08f58,55d400b,fb3f069,1124915e,547744dd,f0933f5e,c8e8e5a5,28236533), +S(9c53d1f,93b60aca,5f008d87,852a7425,c043e9e8,b0d337a,23304b51,bf763f10,460cca10,cc2768d6,8d19adb,c970d4ea,55a27d12,f2c0566a,6dd433b5,389e8059), +S(12fe0ee4,5cf521c0,a36ab1b8,970314bb,f0cfd20c,ac2eee26,bcae5b77,661fa370,6b75c75,103adb98,dae0fdac,e2b8e40,aa3eddf1,bff77d7,703ee2bc,c6eb0d4f), +S(2e317981,e91c4238,b5760ecb,90e4ddca,ddb18a97,2015eedd,30794744,dd859a40,33d11a2f,8c17c132,972a8a6c,3529a98c,50694b74,fc501db4,382f7423,772eaf76), +S(492b627c,d368c638,b9c13232,79bc34c8,f765b14,c54ce0bd,6ce655b7,20370a84,1650f188,b118104,9a18c474,a4e3fdfc,bd68f2fe,747c7cc5,fc45982a,e2533aca), +S(9c95a6c2,6684b3b4,e31d87f4,53918faa,a0d45e7b,45bf74e3,542038d3,a80a73fe,7992441d,5497a94a,14e2d0ca,acad069b,2b802584,ccc975b9,f895b8e6,58d8c580), +S(20a55d91,38623cbd,445b576,264b4129,8614bbfa,f1da06c6,c41d26b7,8639098b,a214ac95,fd6a325d,b26f0d1a,768d0168,c035568b,76758a38,a6f8feea,c8405b12), +S(813c3b1e,32812e27,27677a03,1bb3d63f,7562d127,8b62ab37,abbeebbb,51a9ddd9,13738be2,f0f657c,e6776e38,d40196ed,2dc669e2,1c281765,286830c1,4587ca2e), +S(bf197179,9e604d69,79b752f4,28e07c65,2b3727d6,837e140e,f812035c,4be106d3,8cfee411,1fd9a907,5bce32d5,54ebe54,892825fa,22b46af8,633a5ba6,d957cac5), +S(26f0847a,8e057fd9,9a625d21,df2e034d,960d610f,39b50c5b,a7398ea2,10a082db,ccd4008f,f47d05b4,47c98456,7fdbf173,fe3ca96e,596ca4d2,6dae40f9,f40d4fd), +S(716b7bfb,781d71d0,93182b2a,d72540e3,8c83a6dd,e6bd94ee,f2ae8995,1db45620,69497305,986fee26,2e2aec0,57e02e1,d396509b,7c3cea00,77d0c21,5101ee46), +S(6f6730d1,5f7377b9,6cdd97cd,91a4fc40,92539279,124bc3cf,c62bdfac,897e796,3c193854,3c7e5dd3,57ce219c,fb20d8a2,c87ec1e2,45381004,ebff0add,646fb0bb), +S(65f8ae3e,1365b723,fabed346,b3953fd1,463b1974,44972c2a,df37fa00,ab3337e,5acf164d,a3730a6c,125f9e2a,5416e7f2,a233ec0a,2c87f24a,a0cfbcfe,63f222c2), +S(b15b96c3,8bcb453c,756aafba,5726cac3,ee4b455b,ae346a79,87e42815,5758de8d,c7274128,ba2f8816,18540ee2,e9dc7de3,587b6a,ff76cccf,74dbe598,42cd691b), +S(804c9c6e,10622728,19159f49,eb579ec2,2e59cc8e,6504ba29,cf725469,3a3e60df,8f765c4f,f9a27d7a,415c918f,e501713e,20b67dcb,aeea39a2,c873a4d1,3c8d4dd5), +S(9754b3d6,438231f2,326ff09,da4554c,15888498,f2129ea2,931c3dea,341f33da,97c5eadf,adf25ec2,b3ee40b,3526a522,104a8d02,1028a5c5,57366571,e83ce032), +S(17721368,b5c35e0a,2a8ca72,f83c02eb,d1c006f3,5a3dfbe7,3adb134d,aebc69ef,b9ff7e6f,803294d3,71c72dcc,73e257b7,f2762f8f,ebc30af3,e0fa3a26,3732096b), +S(aa271646,f30cc43f,ab736d0b,2526a8fc,20318e53,785070de,35197dd1,bdbaa749,e6e4f4a8,d88785e4,de06845,714c5c31,d9c55e8b,dddc6a2e,4519555,15013462), +S(9a496db3,832fed07,8ef217ff,31ba0831,21376977,426e649,79609b23,9e5f96fb,6e37e2a2,3aabccab,452c0cdb,ed0a38ac,10e707bd,5858e9ca,610d74d7,5a4036f3), +S(c3c856b7,ed01305f,a067bf40,c78f1f4d,49af3ac2,963eebc8,94c5ce1b,13482630,956a1d62,fde75fd2,f9f0754f,f8f8041b,d8ba58d,6da21e47,39150268,5b1380d5), +S(94776b33,9b5f04b7,f3c6211c,cb925dd5,8945c761,b74df28a,79c58460,b49b9f52,97dc32ee,c164d32f,2e896312,ec07cd5a,dc51e89a,646a04ee,16bd0268,bebd08de), +S(2aa84c41,ac10c480,38c4b277,18145f87,15f992bf,ae4f8d82,1114b83b,c2fcd505,c9e4571e,be171081,cdea3858,c84999dc,e21cf638,6c03308,e9e5a36d,67e05aee), +S(5619b104,c7f5ff8e,7f3c9744,4457789,5e4fe608,b44147de,902226d2,14a614ac,73b45ac2,d6c678a8,636d68af,f00c1222,354958f9,e41b88c5,53480ecb,57a7bba5), +S(6ca32160,74987f30,c4542eae,f66abf56,2ae32531,7d70ba81,9bcf4a6c,56d29223,d81408c1,4e899b9f,62fb4648,77f5217f,9b32f028,f50be839,a1fda23e,3d6ddcad), +S(2b0de06c,802d4478,de84b508,f9c73a7b,8f6d4773,452e4599,dfc4f8d8,428ab718,805bb316,34a05f0b,919e998d,d3cc22e5,8fc684b5,371e6167,7f1e01d7,c162915f), +S(e4d4d1d4,bc074de4,884c510d,261096e4,ddb6206f,acd67c86,97f8846f,3ad11e41,aae414a1,40cd804,900653e3,1d92b947,efa2a206,f90a322b,8f8e4dd0,66667c61), +S(68c0473b,d83936ba,39f896e,ee7f6e7b,bece7d4f,77f3dc1a,32ddeadf,198df39,988095d8,e45a8ff5,ddd149fc,b8835bde,aa95a392,5ac1e282,5ef7c2b3,7b8bf708), +S(91f022c5,40ae514f,bbcb1400,67bcdcc8,d0846305,9676cfce,e5039e24,d4b52151,c57a96b1,f77156ec,88ced4f4,4401e955,10a00ad8,bfd828e6,4d9c3b52,b97325f3), +S(8e140056,3ab8bcf,a634adfc,bc9dd508,b49348d0,61d0c0c0,2b63e6f7,c56f08ea,754cf682,54a57e08,bf607155,cfa5ba1c,7cd56a1d,3edb7e82,8b9bd54d,f5f23d0a), +S(41f4e6a8,691d2e66,8efc8ad,aff3fa85,5d55f8a0,127990a6,27c33af,a2442d81,ffff7626,6d75962e,e49c042c,16086e89,13dae3c4,f75a78c3,77ce1856,ca49e3f9), +S(7d76b7eb,82d0e161,b1a97b9e,e39defe5,11d7c6dc,6fae0255,318d7bfe,5bdd197,86bad87a,21b0bff6,780eaaa3,6a30b7db,bafb4740,369841dd,da734af4,2815b2e7), +S(3a8d019c,ca085837,288e6cf2,18494433,f55c6e5c,f58513b3,6ac698c2,8d5e8c52,292ebbaf,921daf15,c7c93d5a,4fdcd646,2238f650,4cc930bb,b9327d6b,9ef4499b), +S(b8daa085,7c7c7ff0,7ee79541,55dcbfbc,749c927b,fdc74422,a281f3b9,c4e538ef,41061f31,f0c411d4,8a206fb8,bc842900,1c82c3b9,79fe3cf9,397000de,6cd89f03), +S(315b3e39,74d7644d,75a453cd,c2de9a90,423512c7,18379b38,cccde80e,c95e9da9,e8e82e5,17289192,fc9c9fa4,de1cdbea,477cc013,25060dd,2a766bdc,5381f282), +S(cadff522,8a3a947b,8e122ffa,234baaa,e7c23f13,59f18c63,49b1cdec,232c9048,bdba6e3e,15e09ef8,2f06fdef,64b20c6,f6656505,e3f06551,9bb9e54a,a671bece), +S(ffb3ce58,e72c3c41,a0dc7203,27e4b557,c524e4c8,d724f7df,7742cc52,eb74ba38,2fb99e81,f1927389,bcc94dec,e0ead426,e8631a22,a25140f0,cdb88ecd,34ccb2e4), +S(56e4455c,369dcd00,d8987d5a,46578fd0,44b9532b,2e86641b,b5260502,5ac0b9b9,d54ebdca,e2f22f40,76af78e4,448b6c6f,8d06899a,bbf5ab52,a616ef2e,dfeee9c4), +S(7740cd7b,fb64a276,30948a74,c510e0de,2c63692c,e1c9ff2f,86349bed,bc856421,c866667f,b04e9b04,638057df,8786d549,bb7980ff,bbb87799,37f9f345,ad013106), +S(ab9df6e9,81b1462d,23595e7a,6749a2ba,4fd1c579,b73435dc,de879f02,c85381b4,8258aad6,e81b1e62,b16aa87d,cd0db00f,53d46ae3,ff92a866,f50ddbe0,b919b9df), +S(f5eca856,ff675ad9,aded3baa,83465964,714a277a,58d5dec0,f08e85ac,5ad16ae4,9b8e6768,f6dfcbf0,b6789239,5a2cd72,562cb14f,4224c3b5,61c1993,f49326dd), +S(9732548d,85f535c1,41792440,bd369270,827d888e,e8f8ca29,27f5cef4,b29395e9,564e057b,e5fbf2db,cc698d28,34749b9a,6992b2a4,604ef4d9,5a42bf50,282aed8f), +S(8bfc3830,eecc3177,b6559a01,7391f883,493e045e,b6e5a173,643bd4f1,b4c42de3,7820a218,61c9ce19,5d9ae658,aaa74aad,12bd7db2,4c5e2aa3,1ff6cab9,79fb751d), +S(6ea9bded,744eed27,4aa346a7,3542bf8b,4e93e14e,5e57965,8a5d6a24,beeab56a,a4fef266,b9743c35,935cfec3,2495d6c0,c36f6ddc,b249c256,d17d5646,55278afa), +S(ff15c8b2,ce43a5a0,27817821,e556d021,356ce795,bba2c632,17d6205e,deee9116,87cf8fe9,3618a6ee,63608a4a,99bb27c3,8905b955,2df4bbeb,4b21b9c9,f3884cc7), +S(eb61006f,b575ee16,865ce8f,5809ecd4,28187875,91d924b1,5cc15e9d,a8ebe9d,8e51dfa3,c7494b58,f4447e3f,90eaa595,106fe0bf,d31eda0b,961f758d,3e01e0a5), +S(14d141e2,5ddb4621,7d99580c,918d45ca,51a9a51a,2d7917d,a39624fd,dbe87a6b,ea964fec,b49ac43e,45de4592,6ce9bc7b,f693f945,f6447649,bbccf4ef,3e011ca7), +S(36241c8a,b9b7a9ad,217c0a81,fb33281c,7b48afa9,ba1d2897,389f02aa,19cd964f,a38a1e69,2747117e,71654fdb,fc427acb,39531231,4594d08e,5a32336a,431f3b92), +S(8cd8dee1,5059932c,3c94501b,e15565c8,7e04d705,908c4c6,a2311085,5e5b261d,e949fc1f,7fe429aa,cf0c4b01,1d88e9f1,f5705ec4,2953a49,2c4f31d7,15c04380), +S(232136c1,5e76435e,333ed3ee,ceeab24f,f101cbb1,75bdb37e,5b8dea17,fe5b34df,bfc5f9cb,66063be2,7c090421,e5cb603f,f7a5c860,f9c460f4,220c10b,512c792f), +S(178316ff,4abed117,effb70ec,531f4b73,26124ac0,adbd66d9,e5a5eee6,7572e1be,5d88cdf5,90a3af33,ff5def9,1b5c8bb9,be36d3a7,a331a6f6,b4533685,ef2dc1de), +S(9341dcf0,d1b0c5d4,40004663,c56e57e2,a792cf05,a51f000f,1d192cde,6e81320b,54215ad3,3824b655,72204f8f,a9603007,8280621b,8162cbe0,153ff094,31becede), +S(e5399547,ea95b6fd,d1aab09d,b73e616e,593ac82c,6c4b030a,56b775e4,abdfcb04,c69e3608,b7202138,7b1f2a32,d445c809,1fe67869,7feca054,d94aec0c,14fee6d1), +S(da3a4d99,ae069bf9,9d65e041,69db4dc5,d9ab7482,3ac1c1d3,85d37290,807dc652,f4096d3b,ad811fcc,48faaec8,84633cd7,a7f5552f,4c7d695a,7224b0,ab05353e), +S(a5b6bb89,4594a91a,679f8d0,252fe38e,d0f8a544,8d05108,eced1e4d,133b79ce,d6cdb4cb,813a4fe3,7ebe9b33,471f619f,9d45c295,6b304491,4162417b,d0b206dc), +S(12d9cc50,8d90dc59,dc92d250,3a88424,e720c0b5,56912ba,57b8f00e,c9a4a63d,56992d51,780762a1,312f2bf5,51b657f0,5bf34f58,19d23288,2093e478,b074c818), +S(d5bf7f47,77538811,4921894e,2985b8c3,8cddb376,c9245c5f,6f1308ae,3f228620,693c17d8,40a58ab9,50b4b374,18caa8de,e0a49ce6,b471bade,43387523,30fbfc64), +S(83f06119,88ca1f4e,75490777,e864415b,abad972d,d5f4ad1b,1a295b4,205c1a99,e893d1d9,2416da8e,5fef7f76,389c59c3,94725241,4534cc86,d8518b3c,6cbb3d07), +S(fe6995d3,78e80a54,f3b1e8a7,3837904c,2d26430e,c81e5b0,11304e56,50f95f41,26a96933,8ad90a9f,4a15db70,28df1628,2214f822,6bd38a87,854dcc2,f4d490ce), +S(12af3d09,265b9f8c,fd5a74fb,62358ad6,a2cbf782,25b73a88,c5e56d29,508175ad,e28281a4,36b0476b,37588e2f,7fcbc4cc,bd88d96a,3806022b,75a4b5c0,8569cd6c), +S(1bebbb1d,3141cb9e,3723fde4,c0f939c3,7e37b67f,346fecf8,9ee9c789,7f25d89e,4f2835f0,4b875fa9,bccdb338,32ee53e,80360b6f,30e139ae,227961ef,426e0c06), +S(ddd3bfb3,173aa6d8,7d867d95,aeb66535,173c9a6a,4f34cc67,cebfaf7d,1ce4ed4,d7cf7542,c6e93a03,e3b37402,2c2877a3,65387e99,c9956071,beeab06b,69ef4d51), +S(81ddbe22,10125e0,32b5826e,651548cd,ba44a5aa,e131c0a7,2b1f48e3,7fdea8c0,80f9dd6,957aa45f,6ff32756,f87bb9d0,fb145b86,ba0b6890,5d15814a,f42b8ae4), +S(f4f5f53b,fa60b009,9317ea49,5dec1044,54352b89,5da6df0f,707d80f9,7d698da5,454cacb8,999acdb,5cc3e5d2,efac913b,4b967755,3ab998c6,8531b2e2,5ade652a), +S(b232f345,16c572e,f7d89d46,679a0458,2bdc84a2,39f35292,855ae063,fee9a1fd,8e480fcb,d3361e54,a128da49,6a2285ee,829ab82b,7a1530ad,e0f7ed1f,87ace8a9), +S(9f5a306c,c0e7f392,523ed44d,c2a74f62,cd8912fd,292feae4,493a9a90,53e43be6,d4a1e25e,46cbe19e,88b342a5,a278feb,9b9a0523,4636962f,b9697931,c47a848b), +S(4d5005c5,4b079a57,3ce42e6e,87cbec94,cdd520fb,16ff9d49,e715096a,a5ab8301,afadec78,c911fd4c,1248210c,622f17f5,7a34a6f0,1fe07abf,89ad8242,a0340732), +S(6b5d7335,6b80d4b9,9ffd3d6f,5b8376d4,6526753a,2367f046,5ed19550,4e732cb0,c0d10b3c,d9eaccf5,1eea0088,fde2ba55,17f85214,2b46fa6a,99b35a5b,811f5435), +S(896c9047,90f3a428,20715852,9b710560,bd18e038,a8dfb710,fa2bc910,ce25ca9,71ab7cc9,ddf7fe7,ea77e985,d438e0fd,34270829,1c57745e,decbb0f9,b161c4f4), +S(2812d428,7e3c5961,808326d6,8e79c93e,259c3f31,e02449ac,e2b72484,8ef7539e,eec93ec8,b2cd2b18,9ccf8d1,ec8d490a,4ea565e6,ab58eb78,3aca8f5c,b92df37f), +S(d7de63b7,421827c1,ee84acdf,c82a7e72,1eb42aef,7d91fc66,f725e8f9,dc42554a,d6dde944,ec65a85,ac0386a1,eebdc69c,b8793ee9,417e4e1e,8db8087e,bf1b6f22), +S(8dbcc742,a5856bc3,e29b009e,46985a7,67800404,82b06681,3c63a27a,667ca60c,f414fcf8,50b82712,cfcb7d3e,d92bdad2,958f75a2,9f5e69c0,67b3cadc,10da9293), +S(8f046e5f,7ec21b77,3df1015a,19a7aadd,bf5ad912,b5020ff9,b574fc9,7d442f4a,4fd50026,6f8a63cb,d603e3d6,f3f81aab,52e79e94,cb0f7159,fffbdcdf,9dba202d), +S(fc7c51d3,7e6dc2a1,bc542bdf,dab38775,54bb6787,dbe5ffab,471d79c4,8d2a0a58,a7297795,f7f9a558,abc67243,900005c5,2c619c52,bae08a62,5de66bea,81acc475), +S(e36ba16d,81996e80,36b3edcf,67136ecf,7b5dc68d,526a34b2,45843fa4,6a078f0b,25b39a4b,1b5d6240,30fa90c3,558a1eb5,df7c44cb,698f9d76,40432983,faa3b003), +S(c1c817a8,43140681,ff908319,a24684c8,dbbd179f,ac49cf4f,428688bd,3eaebc23,18e43b3b,ced5d5e9,530c05d4,6156fb9,fbfd60e4,58048825,c2d0dc78,e9575594), +S(787e110b,665a8db7,40c2ae0c,206ddfde,4491768,9aba8ca3,de737283,52b70d8a,7e22a27d,976262df,22c60307,ad61f435,b4b27dfd,85657f25,72899d2c,5fd005d9), +S(e1106094,464cd775,85b9eb8,cfe44b13,14b4e87b,54a609a9,c43dff38,995f5e27,8dff0b9c,d97f2779,fee262cf,629ab48c,483e8c09,c05657fc,6b0c83fc,3c64006e), +S(16f72b7d,9b9f8490,2989e9c1,8d067f31,b5e6773f,fc03b2b1,bf026b3c,a45ac92f,6260cc27,6f616934,9492c169,a9f97bfa,b3ad1e16,2b6a529a,7b637ed0,828f6a16), +S(1566a7af,1c3cd035,29859976,8dcd24fe,3dfd07a3,c688d048,c45f9170,b790c791,23319b6e,b9f84cae,f9c6ad8b,1c0a9c2a,6574b84c,4abef9ec,29754a1e,b3a67e2e), +S(bac2ba4d,96be7dfb,425e1279,8323068f,2a42d0c,564e3466,92a89730,7b90b66b,29291264,4e71cddc,7e78d20a,dc026e90,637eeaa7,36fb11e7,25d2e9c2,17b3c8e2), +S(b26a1e6e,1099aaee,14f3ef63,28ed7ae2,d195e04b,1d55e394,d0e11fb3,56807252,2f3566f,f7aca2a6,7e3e8e6c,294120df,86a92193,c2a0a79f,fe22c549,3385334f), +S(9a7a18ba,1cadb917,b68dc78d,119954c2,1b5778f5,a1445238,8cf7f481,7f49cf0b,14e484d,d3fe5242,1737094f,53861ee1,27a1aaf,2da7392b,f03127b0,d0d86a41), +S(49b26479,6efdf6b7,76f70672,d40644a3,e390ed50,1baaa862,1340a08c,649f907c,ca54a985,c3ff23a8,bcd6baf0,ab223fde,65b358d7,cc237b2c,3360cc53,fb7e62cb), +S(a27af3f9,728319d4,248af74a,a3e2d249,947ca87f,3e2d3293,9f574e9a,6da03f9b,226685a,8ad2073c,e8e32133,b2fca804,918d1247,ec1e3053,328e59db,70ea26d2), +S(de13bd9d,3544853f,10768f3e,8cadd376,f36726ca,5b27280b,de12a8a0,1d38f876,6fb4310d,96739a32,3b48e9f6,f215a0c2,f270d272,519e0085,ee72f325,73adb0d0), +S(6680238c,5ca916ed,5169ace,3c2e7103,3a3a26a1,89cb2cc,4420d23e,b9a98e5d,171affa,b6f370b8,c06f85a,928916c0,f6b45c1c,5ca2349f,4469aa25,c8f9b6e7), +S(c1787989,1e100300,1facb000,c41efa43,710267e3,554e0f65,f954a1f6,191388d4,68698007,38cf474b,e577d109,576c6984,cc39da19,371dac87,ae462d2f,2129abe5), +S(f0010a2f,63b6d832,256fe7ac,7b885d1,abf60db2,982b8cdc,31a8595f,23f9328e,cb3a3e15,ec21bba7,72a720cd,3f9bb93a,b0796aa8,c5ee119a,f862d5a4,e547238c), +S(2919f01f,f25e9171,1db684fd,a25c8a89,caf84f01,9caaa483,704e736b,92219e2a,f374dc4,8115ed9c,97efbf21,936cb5eb,814f40ee,40c8f97c,af29f3ea,d46c0603), +S(b110c17b,786e9b64,396003dc,3e0c9bd8,8cc4d060,e7e442a9,8bb3a1ec,2edd6663,6eeace13,a43c6cf7,33bcb313,e5cd7781,54c61fce,e4864924,f20bf45e,5cfc16ac), +S(1a41b8c2,f0bee447,3a085941,4479767d,b2c026c3,6ce0283b,337fa021,87e98435,88a46621,939d903e,9bb60506,3684ecea,7b2fba43,4f5f437c,f94c42e8,b4c274ac), +S(764fec0a,7ef7ccc1,ee478e82,dc122574,6bb18158,cac61402,fdcdae83,8177407a,b0090a4e,fb7da4aa,a54c24fc,75948587,3e1fc957,a475167d,5bfd85,7dc16f7d), +S(e9a521e,49b18a0e,1b226b11,d0397f47,8cb04d92,c8eb4cf4,4e70a0d8,c27a2f8f,b0fbbc19,7e70e9d5,765d85a4,1acfd3d7,84f06554,4008a89b,440f78ac,63a7adc5), +S(da01400,c935873c,1bd0a05d,2eac5595,c6e18682,2db4112b,b0a7af7c,f0b291f1,3fe8c281,26fac7fc,b629a6d8,9ac945a7,566f3414,d46f5e3d,3995ec40,e6aad876), +S(ab69b97d,a15898e2,d77440fc,35c31a4f,7f4930be,6a132e6e,66a529b9,b60b2796,7c80faef,ce1cb7d2,77900d17,e5887c0,c80dc0ad,b9c33fe0,5decf40c,f0c77e3d), +S(8001a2a7,3938254f,fc3a518b,2e9dc61a,bc7dcd1d,90e55812,72410380,2a91c2f,985191d5,787d0cb4,809923ed,b87dfa5d,60c18938,8e4529bd,2353fc42,9a061060), +S(5a93eede,e37ca03,194ddab9,2f9c7cf0,ae230a82,d489a9bc,87ac7180,93165e41,15c6cc54,72f571d0,c78ba2f2,8519115b,16a2256d,17ba055f,5731edfd,822220cc), +S(f0853089,da262598,d86771be,ebd4b38,c7060e9,ae9474ae,f8ba683f,1b70bb1,6508e3a5,b709d0a6,c6505be7,cfaf6744,3b741d9a,5f9adf06,7eacbae6,23a56819), +S(182a85e2,3d4af778,e652cedb,1cd6fabc,81bdb345,ec7daac9,f717249a,5d6aa519,a509c2bf,1df249a0,e477d3fd,e924146f,c9e7ff78,9f625174,587164d7,1dcc259c), +S(dc1f61eb,da442680,5dcc73bc,b6c59288,383301e,50c62a86,a9274a72,8c49ccfe,4d99f11c,be55738c,a2b889db,dee2e3dc,9d3fb44c,8cfef36c,5357396d,97c52cdc), +S(88d959a3,31bc66c9,c6aac8f7,ecc91ead,83591749,97c60a8b,7b11ddb5,fb8253f8,53eb97a8,b3714975,263bf21a,4ed923d7,39276e3d,b4cddcc9,574bc96a,f4083855), +S(53fd6fda,a8e04a9f,89fe1adb,90704589,8fe453f8,1c069b0b,5d5a9fb7,d77d612e,a8325053,95360123,422b6419,109fd9af,397ecf9b,71a6d322,b91c9c1e,ec236b4f), +S(fad9c66,bf453615,ba53a597,8e60eaf1,13e07192,1e820399,6bb850bf,237992ea,8a3a6b9,3a127d70,a36eea2,78668168,34bbb025,902cd3ab,aa499d38,8e24d657), +S(e4b96c12,223f45d2,d7bdd8e9,7ebe545a,16d23dce,1a090b3a,5ed6c9e,65512a65,57fa0c7b,39a473dd,20571bef,80a7c738,cbaa67d0,cfc7f64c,ba0be2cb,123d49bb), +S(7750e371,3b25a5eb,923c460b,967d9dd,1f00e791,cc3b52,9d3ea331,fa1010be,eecd47a,496d6a13,98e95c1b,9ca629eb,49687962,5d690434,ca41279d,a65c605f), +S(93487b6b,25ec86d3,59ef5bd8,e2cd397e,d618c2d6,98d9a6ed,28f3817a,31ae6053,f66a87b9,3dd96064,489537dd,1f9e693e,af0219bc,2b0f752e,4f53b9f4,92715fea), +S(f58b9a95,4d873bdb,931223d5,4867d818,d8c4a2fc,773a1552,35c6b182,aa8ffde2,752b711f,735bbdce,e772dbaa,89f7a95f,d81545c5,5ed25c2,8bcc40ba,4d82ff20), +S(335e471e,8756d394,8cf43e2,b32d2f7c,46147d2b,c467f089,58fb7541,89e4913f,c9e5bf5a,37b19ffb,41d39f3b,8f69a8f0,8ba01a52,559d684c,5eec3549,7413f3e), +S(e6a7d3a6,6ada823a,8b0cbf90,af3f0788,39ebeb9,85017182,74f29f58,1b9f29de,ff850986,71962405,edba654,1857c858,ff948c7e,4bd2c5fc,64afd2a6,c643720), +S(785e6bf,d3c5ae31,932304d8,27aa74f7,783277ff,fb27df66,e1596a07,705b2de0,1166938d,9604a7f8,2485ab74,af763876,2271ee5c,5a7427d8,2d8569f5,25f0008a), +S(228644d,5c0be7d4,59dd5aea,e4019421,83ea6770,ea40cbb0,38b3d1b8,f0d4cef2,1c489d4e,a1595fca,693bf7fa,d6672701,a23ee40f,b9278b1c,566d4faa,5d799c00), +S(a5ddf933,8e477ab7,fccd9344,ad45609f,7be754bc,eefba823,20f1b8e1,3ae9c15c,3e115120,5de4a550,c0f65848,804ac964,168481f2,12b2156b,544152ff,c9f39306), +S(668b35aa,b4799dfe,dca25a50,6c32ca97,3a5e6c3f,51676f82,e572602c,ec3e8a2e,63f33101,d9be94e,7d8971e1,4deec0b6,3406a621,77d5a044,bf43415e,c35a9234), +S(fae3a6f3,f9aa47af,a4babed4,7f366c09,da8e7074,fcda3f92,c74c1bec,c73aaf64,cb38f70f,61bfaca7,76fdc581,a468b53c,69d21815,11771cfc,698a9558,209736e2), +S(2fb68357,285d4ece,96ad8a3a,9c6f0f27,468c9569,3c2e1a9,8864a64c,757c754,b74b474c,133e0a4f,a8ad5032,d08acb1,531640a2,6dc09af5,6af1c862,91c06e87), +S(9f073149,dcbde92,8ba24d3,c00e54c0,c334b958,f124cf91,467cde94,9ea9848f,21e1474d,c43a9d33,43c120ad,a751e9d6,ae6c9ea0,986fdaf6,fbe6bdcf,23085d6), +S(bafcdee0,c0ad4fca,3bf95576,403dc2f7,e28884d9,b8d5f77f,4d7049ce,965ccb4a,4578e9c1,67b07364,f70d8cd,d6dda3ed,28b87cfc,b8d5c8de,48034eb9,5ad3da08), +S(7d909f21,b79fd78b,7b65abed,2da2b831,c7dd1794,cfd32f92,a4fbfc0b,3b666233,c6f2f069,f4f7aaf5,fb263dbb,389ff7ff,86a5f5a8,32c9311e,cfe31af2,38313e5c), +S(5d4ed232,4e24ae92,2f3a1aec,5a8de0a3,e7eac523,58770697,cb45c7eb,4e6730dd,878a1b35,ce2f6880,5b4786fe,eb49480,c6bed243,8e2cfa3e,4636af5c,649056b0), +S(8a97e97b,a3767b06,a9bf75f8,b7d62a4a,b22903ef,7d7717bb,7165155a,b375b959,6997ee31,72cc99b2,8f447052,b75b5615,db7a5349,f1445c6b,bf04ecf3,c8ef9f5c), +S(905aa389,b32cc33d,f9d52e49,39ad4799,8cfd03ad,bd4ed3c1,7810c0e8,8e1e064f,7102cdc0,1d6ea4c2,a426ba6c,1d4565de,c4d0f3b6,458108e4,e0539069,ff2f8a78), +S(510c5aee,f28f8345,2ff713,eb0dcd89,6d788763,af8cf565,dedd4ad2,c32f60cb,ad1f4e3a,549ba056,c3214148,504cd177,adff0933,bfaa07ef,dfad12fb,74609537), +S(66ade073,7a0510e2,40f13ac,db8337f7,80adad8a,9bb68b56,7f5d5d6b,da7cb44e,a5ce9959,f57e1e2d,8cdce9c1,33f6e684,2975a933,8bc8112c,3d68ca88,e668d19), +S(cf51bf95,42cecae3,59ab97d6,1f35ca91,a28bb48d,14ffb958,b4bc95ac,aa5b4e48,7db91cd8,306252b1,aedd7afd,ff94b28f,1e8a39e9,abfe26eb,9189cf0c,37fa5e), +S(fc409559,404b55f,27503803,9a1a36c4,bd42fa53,ab520417,94623180,57ee0622,79b14cb0,5b5f7e30,bf1ef45,cbeb10ac,a05d0819,fa9205ba,3e9d8952,afc74574), +S(832bd5f5,fd0d8771,80e65a02,6ee3c1c6,f44735c8,ce69677d,546bc2fe,fc0e44c3,b2430cc3,7d68fcd8,b35ce76e,229592cc,43ca6ba0,4c2a001d,67ccf5a0,2bbee37c), +S(d66e9431,bdc39c9d,d598c3cb,2ef18d8b,508ea830,3fe5db36,9262c476,66384bf3,b628d1b1,fef2997b,779b5f95,28fcbd,e6ce77ce,c752d83e,cbfcc05e,ab05f670), +S(1dd1514f,85d214f,4c2480a2,22cf00c1,f1ffe62d,ab452dff,6cc7f61,6c66f74,ec70290f,1eafcd75,d87e84d,cb86c460,1413175c,9f18756d,e92d6517,2f688fb6), +S(8a6b21c4,44ebfb6e,61023622,52165611,bfcc2531,1d0d59b0,49f25eeb,9894dcbf,95f6a81b,177faaff,25907a4d,61a7c323,4d7ae932,2b9f862f,a11c86a2,5c894699), +S(48fa5a8e,769fd471,122e6061,d7da307b,2a700a46,bab0656b,7fbaed37,7b997112,e4bf13ba,4456de5,b2c07597,c5b82111,ca05d178,cf0afdc8,9afd5df9,645671e9), +S(8aa75f18,7362cef5,91c58d4d,d1e196dd,5fdd9c7f,91685fe9,d4bf9025,fafbe0a7,81df12ad,b9c543f2,467c4c04,83c1358a,af08fe87,96b01d2,5e26719d,d8c06590), +S(fe10a4a2,c81f5155,e8f23469,c3b537e,b2f45237,8addbbbd,8a224a33,2c7cce6f,95abddd6,e81a6b0e,feadf6da,6bc37e93,f96f8826,efac71ce,8b36762b,dba0cca4), +S(4c29b630,af2a77ff,ed3773d9,a3d66cdf,fb100d67,8a7db0b9,1f37f6b2,249d1a6f,58ee018e,f5055aaf,c39a21cb,a68f4f46,6d6a25ae,e07440fe,2f00dbe9,103b5fd), +S(3bad5249,20c3ea2e,fc16ec86,4502804b,394f3273,5d42e047,c0cf694c,b4350adc,c553a54f,7462f2be,c8fe478b,cbdc4c2e,f693d8c7,6164f513,7e7a7a12,4c6ccd23), +S(8c087953,8616060,cf0deb02,1f46d60c,d1bc3b4,a8bbcf6b,39448603,59a2aff8,5f24e4e3,3416655c,cc35b47,633c9231,bf15443f,132c2df2,ed3d1534,52aa732e), +S(7e080d31,fa764a8b,92e74bf2,c69ee7b4,a7b2c2ec,6495814d,8901908e,443f72bb,f34e979e,c41713e6,b98d122c,a7c0fe5e,89624941,d2d6b44c,c65c4244,3f6a9094), +S(a5acd6e8,50f9b182,162ce14,3b19874b,b9ef6d4d,7c042eb2,c4dc4e21,eed6baa,85d55adf,7220b662,c5b88d63,2f1e7b40,4aba5158,2b93a22d,b3e9457c,b68ddbd1), +S(5149e4ea,600a6dc3,de6c91c9,3dd43a5e,a5e64245,1e791841,39f31749,7fc15a0e,7274076a,9b177600,85446c25,ceb68e34,217ac3c,e4c8c232,a673b0f8,496311ab), +S(e6548b3c,46de74c1,40d9480b,b01aee17,dc6dafa8,5843ff8d,e4a75878,a6ab057e,11704026,373c6c96,30da7f2b,7713a313,e64380ab,4f35d290,dc789f75,29308f6d), +S(80a85ade,2372d7f9,74bbdad1,c6e88df5,4d671f8,7447884d,ef186155,d223183b,24a1858a,5fb6aede,1a36e16,7d25b3a9,2e2f6639,64d60349,7c13e9b,3c14c7a9), +S(35ff436b,571336e7,963ca450,fcc41caf,83307da3,65468dce,28014914,7760b8d1,565b63a0,546379b6,585ba675,52fbe796,ed68a9b8,35431a74,e8f4b989,2027d8b7), +S(12a46621,fd5f9ca8,f8830338,4c150e2c,1df12e06,1dbff329,d3157638,4d67dab1,b1e29c72,e7ccf360,e8863c3,48aae396,2fc989b9,15debc6a,514da0ae,67ff38af), +S(2e4b50b3,b072a9ad,ab9b2438,bf554f0f,bdc06d62,f601bb05,7640b7c5,36949cd9,16c7ebe9,3dbf67b0,fc716d82,3f6a8fc6,4283d7be,513df237,e3afb062,eae6a10a), +S(3b893c39,58a4a0ad,49e3d2eb,b53bd3a2,fb9144f9,d46392c0,93a9affb,3d21bd2f,c965097,99ec1519,5877cad7,4ac6ac0,8c55e9d2,df34b4a6,b1758dff,c5faefc5), +S(195c553b,6de4ff4a,6b9ab252,f28f202b,504ddf2d,af69dda6,1c3d065b,592944d5,9faa60fd,79b63de4,cd3946dd,cd3baf8b,c5795e3d,e4018d7,c1733e27,82ca397d), +S(e8e5178a,c5b76d6,68cdad1c,be01cdb6,e9859609,84c05666,dc8021b2,12cc15bc,ba4eb10a,342d8742,504a468d,f784af91,b8cd1def,112dc8c3,4bae99ed,d855b0b5), +S(a5f99556,4e8d722c,a61dfc74,2cbc5ece,6f654cee,7c716335,5cd4f5e0,1decc0b3,bdce6c99,c4479cf,1547f394,8e9bfd07,ae066d7c,6baf7cf4,95ea2037,191e1594), +S(98065d45,270d94d3,e43b8c46,fc85570a,c72043e1,285d673c,ca1c668e,6373e4bc,a45d5f7d,3e6a51da,8e95333c,2333e7cc,aa938335,7bf7933f,b8004682,599db967), +S(bad7e989,8b6a97bb,98e66b9b,a2e533d4,7d33f0c4,d71c280d,efff5570,660282d7,3d3379d0,b9ad6d70,51002395,bd01c3d7,165e1f2,d61a5ce6,12dfb89b,8e4bfa45), +S(c914752d,4c1bc92f,f9fef612,77bd1633,840f9f74,2bf88bd0,d2fa2698,bfbb6377,ff8a4aa4,b0a3156c,7224f499,bc6147cd,d147aa5a,69c1c225,ce19c663,da7864ee), +S(d58c1fb2,7235da86,8284ab85,1a6ca2e6,dfcb26c6,1c544060,a0bf9083,1471aa50,8e4c5ae8,28e2ed6d,1fa1bd69,9d3a01d0,377e4fb4,bc692ab9,f2e3ede9,13bebbf4), +S(25e409e4,8a8f05e2,e0cf11d0,5a389206,18377447,cd0294f0,4a92eb02,1cbcb500,e7702eef,d40c5cac,4bc2f99e,93f0bfda,509f2409,24307664,c99fda52,a18286da), +S(22d1fef6,4140e996,9451dfbc,32f0891,7f600102,3f9cc11f,88ece53d,49321ad1,5a6c11c7,401c99a5,bed96396,9af7ca1c,bb612d1a,e1067cc9,ca4a1785,408bd79e), +S(ce176236,a9f48b50,7515532,ef8e172a,f017c5ad,87ca2f01,1c8b4ea0,64d44b89,a0266107,fd7d38da,53536d75,6e7b63dd,372566ce,643a4b1d,881e31e3,8a699508), +S(3080fc65,9c01951c,f643e315,f7d48339,e8134e09,5c5c0e21,f7b9ea35,1d859dfb,6355c53d,d8147cd9,b31be789,7bf2f65c,e3be9535,324f41c2,850b9cc5,ba607472), +S(e4798722,a4b284bd,ee6696c4,3c67aa50,11cb3616,7dd7b21a,ebe50ed2,e7d1a253,3d524d92,5dda9fcc,4422ff7,981136c4,4f373ea3,a41cfb7e,e1f068a2,466f6ffb), +S(c82b6536,1e8d8282,9350fd86,e17e63bf,75495dd7,51a967f9,51f4b7f3,eaae03a7,91b896e5,d673cea1,e6fa536,22737c68,c701e2a2,db8a4817,3c316006,b0b84a9e), +S(e911dd65,724fafff,55943a21,df3517dc,cbb3c236,e19aee86,c3f3a5f1,66e3cde4,a51bf72a,cd26179f,839e721c,1de0ab93,cf221a3a,72202b53,d8e552f0,2fbbdf97), +S(ae759e42,cf0c0935,155eb36a,5f07c251,bd4923e1,31b0477c,fb7ea478,9ca797f2,3c12355f,e7dcb9df,73362daf,d0ac689c,a6a24965,ce65fbf4,e5f9c6fb,271a8a85), +S(5a443113,c04b35ae,bbc16401,f2abf9f0,b9644cef,6e8222b0,b67fa109,a19aa3ca,6c7bb7a5,7dc10e2f,140601ad,6c1a7f3b,fe122e80,3531848,2a2495df,a7cc5221), +S(62fbf303,ce5055e4,761d6ba5,4e965e0f,cfc46a4b,e0dd885e,f3803875,e0152b31,14dfdf1f,33941493,d9bb0956,8f8214b3,cfdd18eb,6d6a79f4,c33abeb3,f6aaa86c), +S(47bad781,2ad847ef,471e3483,480fdb67,b08b5679,74f7619d,9f6b4de3,f3dae3b2,79a7976e,568e5220,8bfdf6a1,95a7d16b,8a4dca64,e53ee7c6,c8123d6c,839829a9), +S(fa4381f6,e09f9a19,72d7dc12,76fe579e,f8a9ea0e,c5ff06de,390d150a,fd3cd49d,ff76e0b4,b3f8408d,5c4d79ad,8ca85789,30692275,1d5d5d96,9aebf6e5,2971c307), +S(b891d634,64c7cf77,2b1c19f0,835869a1,50668494,e8889e85,6081ba35,7dfb0d6f,8d716524,65dd0f47,b39bd6b3,7f6efc14,c0108992,4741ccdd,71fa9a98,19e5f05), +S(eae22d01,98d6f036,5d3ac227,856633a9,d0ff6dc1,b6d5d1e5,a1b2e4dd,c7f11466,723a69f0,b551fa41,221e3a31,8fd2b60a,4baa0741,c6127e67,b542be14,9d255074), +S(765b7989,56393611,1b182aca,fa7a2a60,ad89f6da,fffaed17,ead51975,242008a1,e630c87a,91235862,444891c,42dff3bd,320a3272,2d43757d,5ee46eb,af5412f0), +S(ff77d59e,b5ef78d8,49496995,b20b98cc,c847ab95,253b3a6b,9d6119ef,5382ac12,b7791936,e1bcfad,8bd5fb0a,1b547261,ee0bee24,5c1e58b7,3fca8015,195d2b1e), +S(fcd78964,e8e5fc94,f575fea4,7d61abf2,c89ab915,2683e855,d48c6828,b95eaa6a,9f32180c,683b465f,203d4d9,2f2eacf8,396966e3,2bece1e1,413f2111,f000b000), +S(38e9c6b1,b2495801,455e5ea0,ddf4bda2,432b84c7,4f9303d4,c9d6e30c,8e87f564,ccd32af0,603f27c7,7cffff6d,9203167,3cdbe4bf,8662e224,498168c0,5e7eff1e), +S(9de95ac7,9e8ccb95,7b62bdcf,f9942194,4a691b3f,5646d800,68e2e7a0,976d944d,9d99c259,d5fdc8bd,7c29e2ea,651b4abd,354f8ac0,758077df,f46b0896,a25f99c5), +S(e4d34872,1f8f7fe,d81d810d,8fe26811,87d0eb93,5f8eb6c9,2735a55a,720354d1,1b95fd74,ebbed926,55004026,e2110fa9,5bbebf7,efb6b0b6,d7e883b8,34677cd8), +S(ff0222bd,d37a7b6e,45b182a6,cc744545,d60fb6ac,8171f625,a29d215f,1af3ed80,102d4fc0,c3434443,6b8ed145,a5a19426,247b5969,3755d3e4,dee475c5,1211c755), +S(27922e13,f03b2f70,bef94a31,589c1e7,9017c16a,9e57ede4,4af93c38,174dc1c,3f268d7c,3d9aa22a,6277ccea,c36b9377,52b94658,c44d110a,e276e560,d4bc18bf), +S(9f995f1f,76ae01ba,38b02cdd,a7f99b53,883e035,afb35b20,324fe6a6,bb65db6e,ccfa6f06,daf16088,7f2f8af4,18a5b107,cf1a83a8,12f117e1,7e938e4c,73ce924a), +S(c1b2bd23,8fa1db5,814a07a1,d6db2ac3,4f960dfc,c88970a2,9dd21c34,3fea87d0,e912dcbe,ff0391ec,7987f901,c6329c2,a070d64b,53131c5,7e99e6a0,27465f96), +S(789e932e,5665aa8c,24e2f0cc,1039cd89,da928d0a,1b4b03b6,b93fb79b,f40e04dc,25315b3b,bfe535e2,92519e89,b63da55e,f4c16a1b,d8af3394,b280ea62,3d0953a7), +S(19c54824,5815e2b7,b31d35d6,740e660b,84613096,60ee9bd9,6df823ab,1e7bf39c,9c0516aa,79e00ca6,8330d267,5b104e80,3660fcf9,4d785216,90a319a2,44885987), +S(2e73f0d4,de4f920c,5a5175bf,32e6b98f,5a49d1c0,a7af2b98,a6c6dd60,52477bf9,12dd835b,fc93af9e,680aa191,bfde6cc6,f307dfc6,aca349f7,c2affe27,40f87795), +S(5b711fa6,4463434d,d7c824ac,2a56d02e,46949ed1,d8e530b8,71e70a82,38ae224d,14329e12,940d179d,922b97e8,d2a2b7ff,6da66497,6879a790,1edd6035,f47593fe), +S(a34546f7,aded19cf,4d83329f,41cbd292,bc59f37,f290eb7c,ba28aaf0,a32a423b,9a2631a6,cb6b2989,fd2ba260,5aea7f73,c08f05f7,e025493f,459461b6,5ab24dd2), +S(850cc29,8dcb42ab,613b2974,57c80ec2,d98ef5d8,562af745,d4ffcfac,7e9c0853,b07a0e85,5cd335c2,728338d2,8a1c32c6,e3a0fb76,58b8bca3,f6bc02f3,de68a2ed), +S(8de69064,cf3f8d04,bc20a995,7677427,7b712ed1,f77fb7f7,9c361dda,2c7e8b30,34f6938d,750874d,573bd5b0,c11d9c93,b6260a9c,6ae833a4,350dd779,c515f16), +S(69d1e613,852194a2,b618483c,29517029,b3fdc8da,d679c07d,3204261,80f89170,a70f4654,8b7542b6,5da14788,56de6c5c,e06490f6,176794e1,a4dcf25e,4337d570), +S(f238036b,d55e7b7b,6d0835b5,2c3d5c2d,cdc7e6ae,6295e19c,2a0d6a63,669656c3,b401cdf1,15e8c93d,f5e230c7,a3ab387c,687fa690,d86da5e7,d038319c,468bfbfb), +S(ccc74591,1178eedc,76c98013,a52911bc,1da8f9ae,10f40277,ae51fbeb,2b6d53c0,d4cc4eab,60cbb4f2,9070717c,d6151c24,2914069a,c3a68d20,7982d758,3ecf0445), +S(ab2080d1,f6d6ed76,cc713c8b,46474648,c7d1bd31,fa6ca6a4,39d0eb8e,ec4edd4c,8da5323d,e205f2e6,4ddd80be,679dce01,3d1f2813,13fb16f8,e749902c,16362b0a), +S(96ed8ce7,36e0d3d,607e7b1c,fcf6316d,1bc60122,c1e2cfc5,5b20d379,621c564b,841b64b,af84d76a,45afd86c,28d32f79,115675b2,9a15c9a2,50c328e6,2a79695a), +S(b41e63b9,e3fff8e2,d89f2a69,b80f1d38,60a8fabc,20290d41,657467eb,9eef61bf,674d416c,82e50cbf,f001a44f,3ea4108a,c7cf8747,3b7cf851,ce9a9d1e,f5b90dd8), +S(7300ddd,4d22e101,a5ac174c,96f1ede2,e5a8af97,e4d7a5a1,e1f07be1,ec9b72ca,edb4eae6,e9d20683,6abe214,aa95cc75,a4246e14,86b05f23,ccb8c4dd,3bb18888), +S(5d152ede,6e8055ae,14c8c67c,3eac3dbc,1f080dfc,59d0f1d6,16bab4b0,460d21de,e615d095,b3ecba8c,dcede3b2,bfad0814,781b3afa,2b631928,74020df7,b62e1425), +S(bb8f9d6b,1f81a373,32a25eda,b4feaaac,9d82086,8297eb80,c1bf6c4,5f5c7cb3,772be893,a029961b,35f7174e,72dd5c44,e8c745a3,423cba1,2071ee89,92c604d9), +S(643730b4,dd3bf408,2ae96f7a,f3409b8e,690cb09d,f379e3a4,9e8d09b0,de30488d,55a68bcc,54be84a,3d79af27,e2d88740,e9e1eba9,e2149aa6,1cf4d7b1,de6f1e57), +S(82dec11a,c2c7a667,336c5d38,2224a5b4,12c7db82,5fb9adad,30552bc9,db2dbbce,7f7044e1,49f03a78,ea93c129,6bc63541,8b03e06c,5cf24bcf,7df70669,54e8ca26), +S(349382d3,95677d5c,f259f280,83c88ec9,47da1351,d26710bb,4a21d54c,cf770331,7e81f343,a9413313,91b9e4bf,e680a41f,bcd13598,bfa2fcf0,a17439f1,e8215e31), +S(4bf9f078,cacdc26b,5862aeca,d3cbf4a8,3c4321c3,62a562a9,eee4a8bb,5dc66125,6d38018b,4441d376,dd9f4bae,6e22782f,efb1c3b0,2642021c,31495b5c,8ab3fabe), +S(cf319312,ce28b168,ba4b41b7,8f06e0d7,849e672b,21aff86b,5865d32,4e0aa0f1,d1caf763,6d277e8c,edb4e03b,b676718c,7318e29c,e756a868,6932ea74,cd10a84c), +S(de892197,d6db602e,13a9f3e8,d36509a,8e79fd15,f25c9cfa,4e610ff3,eafde1d2,e2454f06,569b9b7e,121534cb,31becd31,31856640,16d5d266,a98fedee,f4026ec)}, +{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), +S(7b466cab,a5820335,bd6c9e51,7f31e735,d3e9276,18c36e6f,861d032c,f2c0efb7,12e04a7a,953d1ecc,c0cb9cab,6e06255,f909bc3,e0b9f2a8,e667150e,1eb879b6), +S(7d73eede,ef4f9ea,34fe9a3b,9555307c,5a8a0fcc,12bae70a,34e90b07,fd3c36eb,e4f4b5c4,8c1ecd05,e7110725,c7a39a61,9f66203,3b6a6373,fa966017,2f5c611), +S(a8d37fa1,c07cdf9b,dc6b77b7,cb6c3e5,99930870,6a2307f5,c7cc2e3b,333a6d1e,665e43c,58bec5db,c87595,8acb5fea,89a0a742,641f4df8,f1c8b238,1eee0774), +S(1f4a4126,eae02858,86df6ce9,3d6bf107,be37564e,66048131,43ff65d1,48ce4ef4,b64de137,1bc84933,95058a4,70a7135c,6202e5d1,c7406759,5269cb98,2e1159c1), +S(5f963c6d,355346e,9feb82f,90921c68,7df67c3e,6d0db15f,ee46d58b,60bee0fe,12f8f5ef,326e9b9,68ab60cc,1331fee7,11c9369b,e887067c,4dba63b4,707cf1c4), +S(93cb2373,e9272b3,378d7e29,59d7d935,e6395529,5b2b6482,15afb9b3,9bc5f573,45bdc11,d37edbd,51e816e1,5d27715e,2f50fb19,ed9a0190,573adc61,2f38db2f), +S(4f231e1f,caf63030,f596cddb,7afe9fbe,2ba93d0,e8b18213,79b349b6,7f8a3ab8,7fbc097a,f61f0c69,9b8b2660,51d332c0,ca8134c3,1c4ac6a8,d1a820f6,a389e9a5), +S(b3ebee1b,ccd21d5a,e45bad73,85779014,216cd61b,7cac39d7,5af121b6,b7438a5,a0c1a664,379cfa7,2b3a1ba8,6c6ec9a3,a62712be,1df870ee,df945b9e,62727b08), +S(9713f024,1e06a7c3,7953fafc,1fe7df85,4bef044b,28358dca,bcd82609,1a9adb0c,439c3a8,9f48152c,2a1951bb,4b70da95,3f3875c7,82650643,92717640,73f1a34c), +S(42ab6939,246a9574,185a1c12,89824dc4,87bfdf4f,bf960517,87a441b,5977d3cd,e5e24a17,416cc7e3,a4fca1f3,7666d42c,a8b19e05,28940a07,2630f668,3babe748), +S(8080c977,bc2ba584,bc40b6b7,50bec750,cf80e367,a45f64a,6639d15b,5fc696b9,e5e8290e,917024e0,5ecf369c,4e2fa4b0,76b19aac,d41f6424,7353a2b0,846db72b), +S(300d9c06,89570a8d,5066039,2a8fb68c,b84b6f7d,4629ace8,51e6aefc,5f88632a,ce1009c9,4fdd9778,50f2c2a8,f30732a3,253053ca,635b34b1,801844ea,90137c41), +S(42ab6bd7,b4a48239,3c17c778,ec1423d0,ed684ad9,41b0eb9b,ecf5090e,51a2aef5,bcd4f24a,9911df81,500c2a76,98d434e2,a5f6ca84,ab4d75c0,7b7f3460,82624b48), +S(34c3d12e,1dba4daf,aacbd46b,7a2b5506,874c150e,1c5b7f3c,3ecc3db4,b4234c60,647d9374,c25ad658,d5081ea7,ff6eda03,61cd55c5,3c8cc862,85a83bd4,17927108), +S(ed822bf1,85d879e9,94b40a42,b000b93d,8f3439a8,e1800479,fbc1c3fd,61a045b1,5e25f76b,5f44666,d94eeffd,72278034,e5414f7d,c12b3858,424aeb73,3b84e4a8), +S(66b6681d,683c7d09,963992b3,b7965df8,e152d1a0,f296a0e5,16160fa5,357c6230,306c1d1,a4e6fd30,2a9d6581,e9b1632a,56eb67b7,af92a8d1,4cbe33f1,c34f1098), +S(b80b913d,359a179a,1ded7997,f833894e,6a9f6e6e,e2d05bd4,aee84b17,13ec6369,dd03d2fc,83aec2ab,9cb999cd,82a015e,3720cdf5,a9016b35,178ece2c,a51e4ccb), +S(54d6ad3,34f5eb7d,cab082bb,e188eb7,185f6054,e3335e6e,200f8263,75b930d7,9c1f066f,bd6f050,3099adf7,e9fc7960,86353a6f,4ee8c25e,fda4bd34,81db0e67), +S(c782fad7,aabecff7,d49e45b4,495fa462,168fbd90,fc14bca2,a216bbf8,daf7f344,e94dcaa8,ac3a9363,cca59110,d42375c,988016a5,b41e64e,770b36f9,87eb23e7), +S(f8cea4a4,b451df9f,89a4e9a3,8f586d04,5fbb1640,3baa242c,4b12f7a9,97aa7b59,da610c68,9fd0ecb8,4b0fdaba,3c34a25d,70d0883d,3b686a2c,c3c257b9,68800ddb), +S(79a15047,b34dad08,500e67a0,8ba08225,31bea87a,3fea2b1e,223c2aa0,4d083e92,4e36831f,183cfe2b,5a6145cb,716ebacb,5c29c71e,2c76e51a,154db94b,8877a463), +S(c8d6d0dc,dd1dfbcf,e4d90d9d,8320f5cc,c9a141ce,7758df3c,a3252045,ea8f4789,f0275762,5102db48,dee39985,e7a91b50,4ca08125,b42de955,f3f6421d,62e29548), +S(a619ef08,787410d3,aefbea3,c6d53427,20e8359,f483a8d3,2f588d99,ece6b51d,f96dc23,1bfca372,10fc1834,8734e4e,28cfa3e2,fa5bcf82,2576714d,363d46b2), +S(1ef02ccb,45ef1e3a,bfcbe970,2f839ac2,845f7c4e,d1b2ec5b,46400db,df4665db,8aaf2a3,8dd2e57a,df53071e,4db215e6,a9885803,29c418f1,701dca95,e37f9ea7), +S(ebf69ecc,320d1188,80c6518,a05f824d,2f8be63c,77401447,fd57e381,76f52f6c,996e43a1,647c018,507a49cd,3867e73c,e0f82630,d36c9ea2,6c38bc57,41aa59a6), +S(1ec42d6f,eca86040,877404e,370d21f7,9497ad3a,2e527bc7,b6ebcd97,a5407c0a,f8180e23,290c3285,b8eda149,d26780fc,8f3a47a3,284ed732,e57e7c6f,a1629f9e), +S(f8ac97e9,a3c152f0,c71098d1,816011e4,644bbfa0,3578412b,6f03f5ad,5495cd0c,df74b06,a4ee84e1,a55836dd,6ab1a681,7bf951b9,cf163dc,70ac6cec,e286b13b), +S(557b9739,5cf5aba5,676ea063,1d404c9,b8abb95b,8672889e,d385bec5,6bbf5165,c7df864b,be165b82,5bc10790,20306b9b,8f3cd384,67edc2fd,bed045b8,fdcd09f2), +S(b44a67c3,4d85856b,62db523d,b15e1efd,b882855d,c63a7c6c,17decc01,1cbbdd4,d224fac9,dfe6f504,296703de,a7d67da8,6c530641,46823fe1,81d2c994,753d838d), +S(c9df9666,ea8eaf4a,14c8847,90e0e456,35db94d3,4d5f0680,b1727c8c,a863e398,10917719,32d9592c,fb272952,2c1a1cba,25020f33,95a6ada6,f85c92c1,996906be), +S(e56736f5,2c77db45,66bb0c10,46c8554f,444b829e,72be61bb,cb376b64,83e28683,2f32beaf,ba8a5aa4,5fc33816,ec2432c,9fe6c76b,172afc7f,8eceb879,f29651c0), +S(bebffbcd,bf56c1cc,8e42824b,ba8f0b4c,35cd732,d1eb160e,96a8ec55,13082be7,5d84e045,a5d285c6,be65e663,b51da6fa,acd3787,7748c439,73eefa88,88263df9), +S(c30e6d10,a518ff5b,2537c8a,89d2e447,c0d7518c,529c4dd5,b9575536,2d9f49f9,92da3c0e,f9ac9946,eada43f6,2d811aa8,26da78e9,849b847a,9fd0b0e,5e71d727), +S(65bf5bd3,ca8f5dfc,9a1799d0,357f24e0,2bcc4b5a,7706a454,3d08a,34512abf,7234a79c,a6c4598b,c2480b8c,5a5a8ca8,f343c41c,514054f7,42611d68,80277041), +S(680c6de7,ce4b261,3698ef55,185b7678,3d6ae7b,9587bbf,89995034,ce361a03,a22146e,3e025e43,565b5243,89bb57e7,6af1b740,7769be7e,6cd29b1a,1d472765), +S(83ffcd78,14a1455b,501381f2,523a675e,92a3a688,aef481ed,aeb0fd0a,14c37671,d780b968,b263153e,e1f5657,de678f55,6e43b840,e17e6eba,694ac093,dc9e8e7f), +S(b8c2376,6ef2d21f,5505b265,a1b27cfa,f0f5a59b,54b31407,1fa9ef5b,2457762b,28249c7c,25068a13,ce473b0e,896ece13,65a23f57,2626fb7,e5ac1e33,7976aedf), +S(99327a6c,b7606c32,92d98fb8,799f5f64,cfa4b0c5,4fba99ff,aa309287,d034bb1d,aa09fe57,4883ab5f,6b07830c,d5c12121,de3bcf52,68f8dfbb,37ccb8cd,61cfe55d), +S(3a9f4dba,2fd6493f,bbb21e8b,d36644c3,d4da0699,faf8029d,4ac7654f,380a18d,3c8c87a0,6bf2315,32a5bd1e,e44ad483,b44ada12,63d4750,6a55c567,7121fbe1), +S(65aff743,11534071,2676c7cb,2e5762ca,297acce8,535534bc,e495e27e,2b6f4353,5b11d44,8b7e2593,b8964f7,317f78b,5eb4d169,d968aa17,91259135,15087ba0), +S(457e7433,e8a8b719,e6e6b506,cdc1654f,574e5020,4ca22877,f36770ab,bf855eb0,949d5089,389f939,5e762659,53aec631,e369e8b1,38e6168d,b6528405,bf144ffb), +S(83253254,4261c8bf,b4a32676,3389afcb,9ee3d56f,44c70c08,e9e70bef,fbb092b1,3ebfdef,f0bd720e,611f0c8d,85028d87,8ffbb5d,7c19c3c1,e7a0832a,2ccbc0df), +S(98ec0257,7a1e4b16,369ffc2c,f17b0ff1,82af8b5e,25ae498b,e7acdfb1,b069e572,e2c72d87,67d16e14,44315c3d,9dd3250f,ee7c5ed,73337d03,ccb8a4d5,743537b), +S(d4b815e7,1e29d5d9,7e96c122,7ba6fece,60779b1f,574adc23,b53bc206,99c3ccd8,df98ad83,9c4a9133,d78b0d12,a8ce8765,61a3530a,29707357,65ea402f,72db0cfd), +S(88753aeb,3045bf8f,335a59a,9bd4287e,555a9005,5940a0d5,895b19a4,be237ffa,9740f21f,4abb4d3d,ae4b5f7e,9b5ab141,810ef2f3,9cf2d98d,570dcd1c,4d330ae4), +S(eae3895d,f081044f,6ea4a9db,73dd1300,b4a53f5,2a5429bc,fd60cb6d,733efd9c,4a9a829a,14149e0d,a629498,a3e03cbd,723d807c,a47a16cc,de5b9c1,a443995e), +S(752b1e2b,761e8633,7c4ec063,2fe7f626,e7038632,d93ce2d2,ea789825,97ea0d44,edeb1b08,a076b69,9fdbe919,e20dbee1,223c33d5,ffc6fdeb,36a5d1fa,4399b8e7), +S(9854c41d,104d82d,840fbfaa,d4da5b51,40c1aba7,80bafb5d,24646e10,a23f8a4,c170757f,23eb38de,5412e2ea,3a040c8e,cb10305e,69290c20,32e2719f,e26bd499), +S(81d720df,c9396536,5d977db1,410d4a5c,fd5078e2,21e368e0,5a8faf83,44097d1c,a29c17b5,518001fd,775afd10,693865e,d84cf3f0,f7bb44db,c5b3bf27,b192be60), +S(555dbc1b,7809b8d9,9db97d6b,c9c75ecf,4592fbae,3784e2a7,2150bda0,e9c8cbe8,963fb2f2,9277580f,9ae5668b,f31249c2,7429cbe2,5bbbd296,81574ae9,35e8d443), +S(31dd018d,28c81808,fce67b11,f621358,71be0366,b04d5f69,73b3f11d,df2b37a6,43837cb7,c56c10ad,1fcb57d,91bb293,aa91740,a8c5427,3f10bedb,560ac06c), +S(8c3e7d99,cd849afe,4c3e8ab8,af410bd4,3ee951ca,10307e05,4f569854,e8752d48,fd4d3081,69dfb22e,ddc706d2,36bb1918,7ab455dc,eb44e362,eea2863a,3f0341ac), +S(6fe0f368,f918ea70,b130864a,60e6541d,23daac99,49a28e44,597315f6,d85ad4f5,e30fdae,7c6731a5,ddfefba9,ae685a43,21619203,87b66a2c,799d84b2,f2d42c98), +S(f181faf7,623f82da,aa7730d9,56dfabc1,b4a662ce,c94282fc,dd3852e,8a43b91f,2e148d3d,9c470d9b,ca5be26a,5e191154,441d86f7,d6234085,203e944f,529e7256), +S(8cf18f22,23085bce,a35c8406,d9322ade,97eae156,4f741e36,2d3f57e9,e86867cb,e5123dc3,c5be133a,f25f90bd,de7101c0,6b2ebe44,cc83b7ee,a267a3a0,6a2c2b4f), +S(72cf023a,8d20a4fc,3ad5937f,cad6f47b,1030e02d,9ab0cede,58794a3e,f5c9c6dd,a2d02506,35402d63,85d0fc40,af954464,15fa929d,3dd95c,d4159edc,300fee82), +S(6c87417c,7e9ce90,b67c0ca1,469d91f0,98a9e67e,850ec140,fd489ab6,b4477ec0,7aaec9f9,a443bad9,89dd08f4,8d397d3c,35d970b,6cc9eba,df64513e,57227106), +S(54ffefda,eeb2a69e,8de97265,e8d7ef5a,576a4f1e,df7ceba1,7f94cb3a,a83a96ca,7d76707e,cf533f08,2c3e63cc,eed8cd18,9bded8ce,835a37cc,549b550b,5e82a3a5), +S(9dba00a6,d186dc34,a21207af,9aa597e4,432b8fb1,b1fbbd30,6caacbfc,4db25e35,259faa28,e791002f,138468c6,34e0c20,c5555b48,a1b8a35,6d68accb,41d8f7b8), +S(2728df39,afbc765b,38f47b21,6aca8cad,33b5b2b6,363cbdc3,3ed434ba,5c9201bf,de91b280,6bddbef0,562c02bd,7d7bd16e,7551095d,534a2566,9618539,5e22a4e3), +S(77a45f41,2353ddf2,d8cf7ac4,afeb1a3f,df6d20df,702e8207,f29286a5,c3558ba4,f1f5003f,510959e,93be5f5d,7d4f9498,70eea705,51b2383c,22215a84,8ff83fbb), +S(a0da4abe,d0890614,ba574a88,ffba223e,71163293,b4ed6df3,8b5b6e6f,997cab0b,3f542151,36570288,344391b,d3144b50,55545b2a,90e78b9d,20f894e4,2f43bff6), +S(202b20a3,c8979884,9a275f6f,7fcf6e11,4a21309f,2f340387,f663eea3,e1121028,35001416,97ae4ada,4e7e0b01,e9712385,ad971605,6e6c0cb6,c1cb6bdc,b12c3363), +S(7288cb0a,fb450439,2ce2867d,3ff3d2af,71344402,a7ec2198,152aaa40,9d85aa32,e39ceae9,6d3fb740,91531079,9770ffda,fe11434b,b5ce8213,deab8b43,c9426006), +S(de1e33bf,bf324b9f,dd8b305c,1d77e868,61dc6402,b083778e,b488275,1609417,bbcdd28a,13e3db76,e76f836e,93a4e54a,8550a389,5d02a03e,a99e80ff,cae1e3f0), +S(c88f921c,c2dc7aa,1b48d681,319a259b,33313e5c,c31ed767,737824dd,b99fb563,66ac4897,206652df,fb7224a6,771f32ae,bd75e318,21164444,62419320,d45f5e1b), +S(adc40ac3,97458429,6277e8c1,3f3b0e15,d8ab082a,e024f8ae,901cec70,36083690,f0497ce0,2c79352c,19bf649,4fdcb631,60c993b6,6d4c81a3,679a8006,b6e31779), +S(f72b6a10,5599d35e,4f5b107d,a2f9e8de,f1ce7211,7c03c8a2,5695af9d,d4a42926,41306d43,7d83913b,fdd51a1b,3c9cdbca,5d4082b1,756e1f5e,2c2851fd,b50ceed7), +S(f8bf4a89,b8577191,98efcac4,a695f9d5,d9d7f017,c9c0ad26,ce8301bc,575d8771,ea762173,96b1873,843f07f,826d6d69,e985d38a,119d7923,99b20484,cb20d8d3), +S(83523352,714c758e,3e7d1627,44e1fbe9,991b0c15,efa1345,fd9cd41e,ae84fcaa,d209aaf9,e7032525,e8f496e7,7b22011d,e20e2c0d,901e835f,2e64fd4f,d6b44e6), +S(12f7f577,31b61df1,a2f699b0,ae85b95e,92ae1fa9,7caca4a8,7b7cb6ac,4fc19145,2c52d855,505de067,213e3054,8d7416fa,ba042f93,27c21cd5,b47086c4,d01696e), +S(48254fe5,aae306d,54a14098,c87a0bae,4cbd0540,c8d36ed6,9c19abd8,ba0738fb,6f37a602,ce702d45,549ff185,338b150b,17bc868d,649ba4be,b99ff744,5ea70f3a), +S(5212fbaf,dc8a9270,fee8ca9b,ce872a3c,b875c3b3,202f92ef,b5327a4b,e466401,73fd045,69ed0d82,4169c191,8ee937c8,87824719,120996ec,11a9fdc0,ce4437a6), +S(855b8d00,c3f84266,6af52981,284b5845,36a06019,3b722fd1,483b8dd8,2880e0b2,5b494189,5d3c558c,548ee414,47327cc,13ca4e7a,5b8eb7ec,7d5da63c,7f89006), +S(49faaf81,850bfce2,7752768f,4808c91e,be1a8999,f4673650,52099584,37ce9747,6eb4c92c,a2235629,c90339f6,d7c5f136,a2329eaf,f26d6353,da9d4679,f07f8db0), +S(57afce1e,5164670a,7b3a8a8c,cbcd7261,a8775833,1f74fee,7b541174,9844bb5c,452fcaa0,1237bfb9,f3d97bed,4eda5fa9,ed72b580,c2b95953,8eb227d5,60252fdf), +S(9537b024,4e19fbbb,c17e42ec,9ac4c5ce,51fdba4f,51e7bb28,ea53ba77,661a8728,43153797,f2b3c74c,ed3cfee9,c9609683,36f2876f,2332e95a,cbfb6d5e,84dc9f3b), +S(bc816077,c64469e3,a663409d,5e175b45,ee14adb1,703e2bd3,7692b38a,31d49c6,7f5430fa,11e07543,f781482a,f95b30d,d58cc8e7,e8107b6b,54f314c0,c8e77e64), +S(dd03731,e07f5b55,3178ae07,7df0930e,de774e47,3e52e028,b7f39a5b,583f1d1b,7cdc1846,fe08633b,f9fa470b,7710d02b,8ee07902,e38290f5,788094a3,61174168), +S(132ba7c,e36518c9,195ec6e0,cf3aa576,1f0d3b76,d2124fc3,b43fbdf9,bd196170,7b59d248,388297dc,9f72b75,b8aa607d,327cd873,8be5c1ff,e8e035ba,611d599b), +S(798b3663,8f3758c3,93f93504,9584d055,e52f9cb9,abcab568,477f3265,68f5dd80,f270bd3c,5b236c6f,92bf2937,5ae4761e,1e5418a2,716326a,c62707b8,617c2f1f), +S(1db26d05,f64a6f1f,4b6911b8,3cdcfac1,bfe57344,7319baa3,8a539fa8,dbae42e0,8185bb2c,8d009b27,c7edb12f,d1760a13,e2e97747,52c3b961,48e7cd0f,2c0ca28a), +S(53600f43,411155f9,676fd005,ece88e90,ce3f68eb,bf9f418c,b1ccd460,94fb9013,e87314ca,ff3457a1,ef3a12ab,3e8f7a54,b80b7e81,91cf3378,cbeb9a1e,bb02caea), +S(31445cb8,39f9aa76,4fd46b4e,b39f0fde,18178467,81a4b1df,e9523dd9,9c37a732,58ef4007,d56b3ecc,cf08f220,d5b28cba,d9e6ef50,cf878166,9af25bd1,16239ac9), +S(3968d2b0,80d50365,b4df89e3,a50ed48c,fb41f5f4,630a1fc8,67a072cf,36775c4e,15da358c,9a674846,3fb6d243,8e8569fe,4d9ea766,713ad5c7,15461485,c876f215), +S(a040c7fa,1ddc8d42,efb964af,ca365776,99f200e8,d23cf93a,653cbfce,ea24507c,7bb2fb2a,57f4749c,83f696a1,4c974781,8af4ee58,c42c0718,1fdeb867,f54121c3), +S(2edd58db,873d3d57,42bc774d,97ea6197,152a57ff,b0f747ab,1d26f577,b8cdef89,82ec3302,ed5ea5bf,79e696e1,d67d762f,9573f895,ecf3a891,755dbd61,c11a7702), +S(b519f379,8949ae1e,1138e3c9,9a9486c2,77f44ee,1f9aa34e,b54a34c2,6f394313,5786b86a,7913b9c8,e38b6bf,2edc278f,2d4807ce,834c30da,ac3f5222,7af4a458), +S(d3be1b71,d03703e6,194d5ab8,ceaabdff,4a970fab,60caeebc,13ffadc5,3f973757,176caa0b,f46c299e,33e5ff06,294bf813,530cf048,fdd0d98c,dfd3e9a0,a42c33c7), +S(85a03707,c13f7b49,878abf34,cb77fba0,62d3d1e4,2b00f7eb,6e159c66,48290fbf,487c50b0,c811356c,499ee9fb,5fb78a84,98d70194,62a15417,c0e883f5,6baf6f45), +S(fddca890,694d87de,a2e0f92d,1e9b9e9c,7420b4da,bb5d2a89,3d282dd0,53d45a15,8a896375,7558132e,d1137feb,fc9c9c0d,4e6a6de6,1e75a8a8,ea79664d,893dcfbc), +S(d7cb9e4d,13e2b747,6f91a951,2aa93ce,c954a542,c6acd5cf,ad65bdb4,63071664,2880964a,13083d03,8755c9eb,9c2c8f57,b68660d4,a5227ab5,261d6ae7,c9ba708d), +S(98f619e3,76e7bd91,f5387e58,b57ccc84,90a6fd68,1a569cc2,caa253df,86b6959b,59d49098,67b3c6b9,8ded8edf,a67f5c4d,4ec7e,8dec78e2,68314f8b,f941867a), +S(35f36793,f5dc6d0c,c8adff91,2db459c5,dd405272,ce45031d,bb118383,d108519a,568f7399,aec63e71,9c63b0d1,480a9afc,662c8920,4bd7ba30,71b0eeee,ddf3ac2d), +S(c7e043b,b02f15ef,689666b3,8ed29704,a5059027,ae23c3ba,f75a2a90,642934c2,cb5e67d,551e180a,42274149,127c75ff,2be6113,bfe56f46,47008ff2,d6b72578), +S(cf95cb09,19655249,f16bb911,9488af73,c74ff5e5,e508e322,2a044f2e,1fb87796,d476c517,3df5b269,889ac45f,5b095db4,97c63334,ce233da9,4daebef9,aa2b88b5), +S(b38ad8a1,640c2aa5,b77db077,8a7ef7b5,b9795e36,20612fc5,e48c3ac,6fcdeae4,5e97b2cb,8dc7839a,d1f80df3,a9a7e203,140898be,6a6301ee,c3aca617,366edf66), +S(d39404f4,c9e59b56,41fbe43,c0abf3ed,4ce9065f,6d4d0224,b1cb1b33,aa97d3b9,573e8e27,44903ffa,8e1efbdf,56d3975d,23bac9ac,de0f758c,1d018e7d,d049e49b), +S(9adce43a,9f603359,5424daaf,c0ae565,c468df8,6beb9b49,ff533af4,496fcf32,e2cc9853,af216c00,4d71949b,c55a2c44,38655847,75cb2d00,ed96c5a,6f143f01), +S(66d1438c,8c9202a7,aef7d11c,682fed36,b88d5978,d7611a06,5d2ec2a1,b5aa8bd2,d1cef3de,eaa43df,617a7fa8,3a22fbcb,f8aae418,5de59e00,1e11b37c,d34cfd05), +S(442be1e4,c65e3e33,db17ed63,d852e62b,f8ff33d3,589a99c6,8d2fc4b4,dc8bfaec,63ed32e5,6bd86b07,6fc357,cd556c62,22402d35,5272f42b,a982a496,1f7889b1), +S(9c80efcb,da724a78,f6dc4de1,618b0d39,cf383c6f,d104bdd,2476147e,b6fade3e,102a9767,4ecb12be,71aa53b6,b0f353e5,6a06f1a7,b14cfd31,d48993e,4e766b86), +S(a2d10bfd,bd01700f,1c105396,bd78c7de,7baf91de,ecabc8,94938ec5,b4d99951,4a7db817,c4ce92c7,eacfc287,91992398,3042412b,ab017689,9c4113ba,6ef4bc3e), +S(847921be,b36c0615,ae10e9c1,b9791adf,667d1896,3af938e5,365eedd6,f888ee92,c4ee9b79,91ec9eac,9c08ceea,f610ec27,b3a0be64,6684b3b7,8ad1c17d,380d99ba), +S(60d7dcd6,879f9c5,6a44cc9e,26f5a5cc,6a6500ba,99fbb676,e5992457,e611b840,c4128d09,7ca3a257,113aa74c,29f063ff,52e39bd8,c8a4bd68,4c822cd3,386a652f), +S(e3a4e2b0,5d227414,38ad53a1,5366c13d,7d377dca,fed5be5e,61387448,1e3cd263,fab9bc4f,12cc2130,5b0afc2c,275cf3c2,c12682e4,1c772776,568f6219,63fe9c5), +S(af13018c,89c75180,af73b61b,5ccc891e,b42592d0,f2345c39,926a0ea2,402d6e87,eb122961,6a01567a,1d69034f,e8ca133,136694b7,761f4500,25754951,c9e38b42), +S(a3a7b943,c5304cbe,d736b95,fdfc2283,f54164c3,bc3d186e,7b017d1,dfbf9464,7b779d12,909078fd,9cccc9c6,73afaf1d,bd206420,44f941c0,4a676aeb,e2eefaf8), +S(ee99d382,c6f590c8,a9e266d9,9500e9ef,cd685630,71052e95,28be0aff,330e5476,541966c1,1cf15028,a6448de5,5837bd73,6aa11b70,bdaebc1a,1e8223ba,7a69d146), +S(142ba015,699ffb3,e6e02bd6,aaf084e4,3d100421,c5aad92c,f636691d,dcaae138,94fc5a5c,cdb79bb2,1cb733b2,50a0d4b5,cf37cfb4,75ae290b,4c53cac6,43ca7aeb), +S(75f254ae,9f98f3ea,17d9e574,5820a2df,16ef6027,d85ef056,75790b92,b345a144,63a94cfa,2b289f55,300729ce,77f9a5d3,681b944b,90719028,cd8de938,2290137b), +S(f6db52b0,1ac4f26e,80ac7f49,fc81cf48,9ebe7df9,d2085d2d,e08cfa7d,3883627,ed4006,f6c6d8c5,2bfc2fb1,8014f69b,7fce7868,7c0217cd,3d813faf,8518152a), +S(5418d34c,61fa1981,be925614,c56ac5a9,651b90b0,367cc6f0,23f4ad3b,3455798f,ec800abd,42af6eae,3584abc,cfccc4b7,14e98700,539ba36a,925da30c,ef57ebb1), +S(7ac961ec,59031427,8bbb04e4,4e79634d,a88f7cd5,d26d6ac2,a6605273,7adc5c1f,5ae54a73,cbfecefd,5574b29a,4ec5aa13,1912ef14,491ea386,85ca63c5,ade7e914), +S(eba2daa1,67aa43b,9d8d1ffc,b0784ad0,8bc563f6,243401c9,79d13396,bd9351f6,ece65820,bbe5bf06,6300f1c2,e16af4a,4d05263f,f4da582e,9e3892d9,9063a1b4), +S(bc674e6d,62757b5c,f079229,8b624c93,d1765e8a,44ce9abb,84047873,c62cc601,8056031,468638d,251fc37c,751580e8,29dfb130,f34c7f79,31618d3e,8c3b0ac7), +S(d76792aa,b3dd3405,45cd8374,958ee104,86b08dd8,1e1b99f4,c02b387d,b9cc3c9,63e21256,6b92c21a,378ce4de,cbc28dd5,2b563106,cb5afcb6,95f2aa02,fad96eed), +S(b0f0830d,80cb007,8c8f84b0,d753b059,6dc0f1a2,456cbaf1,bff5716c,158eee33,7d229908,b8acd65f,62a4c9c2,aaeee8b3,a1355e40,492552ce,1283fc52,d512fa4c), +S(86ed6a70,2cfbaf34,542ce456,b589a492,c9e19b4d,b18f4a73,3f257e1,2902bb3b,ecb26bfe,700e06c6,598bdca7,d0eb97c9,5992e438,c6d490b4,b2907af5,3850ac79), +S(fc88d9be,fe183b9f,3d952f51,79d0e2a7,2c56b79d,2a3c4408,948f4887,bf5b6113,c8e6d8a,91329b9c,c197c41d,8f2858c0,eae74ee4,5fe259ed,fd93bba9,fe3cb7e3), +S(c4e1983d,e86d3856,5381dcdc,e11910d9,2c96700d,a67bf713,3a6bf601,7461d444,39af034a,a1f8caa0,b01e4a32,2a8ae84,8e93e9a6,9c97fc9e,f8e8df08,2b211e3e), +S(6dd8075b,4456919c,bc97417f,7a94f6a1,bb9c07fb,8ed54986,8deb955d,bdc65eaf,bccb1ebf,57a86b87,2119eea5,17346eaa,bdcb5fdb,b3a71930,7bbcaf27,59781a9e), +S(a4ef5a0d,1e9a65dc,f4310820,4a2ec8f1,72aa8a8f,71604c8,39b026d8,a3a3983e,a7d682d,c7dfc382,a67678ee,12eae6ab,b6cfdb1d,7646f4ab,6c1d9269,1fbe338b), +S(9a250997,84509b90,f17c29ad,2bb39ccd,42e3147c,ab53c2a0,a739a65b,de4814cc,fd746694,ae6abc3,6898bf52,e0e6b3b8,a63766e9,d2dbc867,3f9b17c8,9135e4ff), +S(9e7b2662,58b0b90f,707211db,a9d4610d,4f49d08,c553dd00,f58c242e,2082c095,ac8fd168,bee47d4b,c8b2ffa3,72fa3ae2,657c435d,4d9f4da3,67c8c232,6d4b9820), +S(65646ccc,5f53bce3,edf35c57,137b7f5d,a49e385b,f101c5c9,b6182035,c45e0e0,6ae3b77e,cd3f9837,99287240,6a70ef79,c3dfb8b6,c3704f3d,9ba248ff,e6344092), +S(15ce9fd4,a87cdf9b,71e435d,b2148927,7ebf17f9,218d0d57,af3c632e,e227e2b1,47857e6a,2f5a9710,2c082dbd,d0edac51,65d949bb,cb9a325c,4f164958,a2413534), +S(ff44a162,2a259be3,512f234b,dee87a16,bb9d7739,cb84e527,29d60fb4,4d073fae,5ada42a4,9190f1cc,e16cea1f,392b01ba,89969695,8926f16e,f7aac2f9,a9cce2cf), +S(a5f68def,8670933d,907d508,185c3ce1,a67c62c5,33c3d65c,3c199d08,33536f99,d859eb34,2bd36baf,7e9f36de,f1dcb7c1,db6f0e19,12e7c9fc,2799afad,d210fac1), +S(4666bb71,c1e24ae6,d6c0f9d3,5a100fa4,309f30de,cc4c4935,9c937f51,243571b5,aba13ddf,96be4e04,97e758b9,d0532160,cbe62077,78297e4a,30a2ccd3,459c9e36), +S(131fc338,b0acc38c,b817a182,fd4919af,8bbaa00b,e0d80ce9,b46c50dc,8d7e972d,2761b62a,bada1136,4bc7bc3b,4fe7c0a3,b6d8be3b,d05bb3ed,dba2a071,188812b4), +S(5232eae0,3b377985,7e57c34b,4f9ee30d,a97714c0,bf33b63b,d520ec60,9bb18557,c243b06,ae8404cb,a01ab038,da6b8708,ec6698ee,f6d0f555,85f5e0,6d8b2330), +S(e95e4da8,afbb1484,ea1bf378,642ebd59,de13f70c,53f2b470,252eaf5a,c01823bd,dc77ce77,688e13d1,4083c7d1,d91fefc6,bfabde0b,bde46657,d3080d15,51cde44e), +S(9f3a7cc6,759db98b,f6b45257,8aa1a8ef,a2601d64,64028025,ddeec5a,c6fa8b6e,e5db2c3e,d23f72c,47d9d5bf,8bdfbe98,b9a1e97b,57d8a9f9,60f10fe9,8056a4c7), +S(96981f2,a1e0c0b2,1eab0a4f,fa56283a,5555bfe0,75ef938c,66dafa26,8f41d946,ae191f21,841ad677,420a77d6,ec440baa,c1426dc,dc2449a3,eeff6f7d,94e4f012), +S(d805bbe3,a8771fb3,3a22c51d,d73ad400,f7656107,3767fedb,3babebd0,226a1244,5bad82f9,ed6a1a7d,ca0532b8,87c7d7fb,1280c05a,f461321e,9065e11b,5c7aec51), +S(ae3b990d,32ad44a9,874da8f1,79e4f7e9,fca965c7,d7281f07,1df80c63,2b9dc432,3810d68a,b5cf8ee6,af08c822,d922621,8197cc39,194ba913,492064a8,5405a346), +S(69fdac,1c5be33e,fce9fb73,49f936d9,ad0d9afd,e1df6d00,df6599bc,4870b6bd,2fbb05fd,3e82f2ca,8c0340e2,d43f0d99,98f12f1f,c433046a,52aba97b,9d30ff3b), +S(1b0c0ecf,b0e9e6b2,238ee645,e33b44ef,5f102985,77df53e9,26fc2f82,d1aee964,9400ea2e,ba2d25f5,2607b213,8b30475a,67e5dbab,bf8e5ca3,38f84bd3,947adade), +S(7e2e1b2e,8f69a883,9d9e3993,312c9bdd,78a2390,251d4a1c,209b0caa,47eb0171,674c4c18,e61fd02b,660ec735,67fe7340,591c2db2,924c9430,bfab3948,d3a84eef), +S(d42acdb,d02a6a9f,da7f9d83,9d8c240c,7ae50331,3aae1d56,a0e1798d,8e668ba5,2c54cff7,bda5ac87,3d044272,b7bd52a7,dda6a14c,c9bf9e07,3b0375d6,6489e70c), +S(6a746102,1f9780c7,5eee2394,823354ae,cfdef6d2,46892b1d,c7150863,1e6f4c93,f7957ef3,1cb47e0b,9e3563e8,1fbe69fa,1e687e2f,3e3efe50,d21cc4b7,26053d29), +S(ad164b38,d21a5211,84b6d47c,be01953a,5f5b8a97,7f0d5888,b9fd9495,691f2749,5709a9db,404b1a06,5f965af1,7ca7a2d7,f036f39c,556af11e,9a0a7340,52c2b5d), +S(867099cb,84481d32,d9a4f46e,2e3338cc,9d5f14cc,f65d97d8,441fc8be,38e36296,8688faf9,7a3eeadf,8a42e884,3e0ac108,90f7f417,8620c0b0,49d13e44,9190ed8c), +S(d52d12cf,3cca7ad6,ea0ed7a3,92c4da04,8d31e279,63b1a9e9,ee5e9d07,b3ceb2c6,fce207b7,1aa22562,2f589efb,750f984b,b52208a1,6c07990c,768020e9,9711a80), +S(da5ccb53,c4c46a06,1ffbb2e,4814520d,ea373d68,1d426071,c9ca49c4,db5efcc7,28b00c21,4cf71f17,601cd24b,4516dd20,4f12fea6,c7fac2a5,43a2176f,1f150aed), +S(3e8a38b,505d7916,8e518d17,39198d6e,65139b44,edb38001,72a92b0e,410c4174,f7b82a9,62980288,47e06c3,e51e1a6d,f2ae9cf2,e2468e01,8ef79534,a8d6e0b1), +S(42a6d29e,4952ebd3,7169a99f,fa59742b,58bc24a6,c861dbff,ce79346d,78b7bce6,e6da3768,2124c365,878d577d,d1358dd2,b39a4bbf,e25f8bb3,dc97a533,c40ffa7a), +S(728aac39,15d078d7,4b687a75,6b166e05,d9636a71,bfb1103d,aa78fd2e,b8f22519,db2159e2,a71d66e0,e68e504d,40d60bfb,34f8be08,838c1435,f9018ea6,bd88c876), +S(ab5218a8,a7c5ef3d,f7538035,a1812787,f6cc2019,798935ce,92d9fa34,be65f3d1,fcbb8182,d8cc462,7ad1082,795c7b87,3932e97c,6bbaa7f4,2af231ff,67dc7b8), +S(e655414,ceff2752,990448ab,9159c7ae,50490932,a356bf80,d1669a6e,ad808506,cc0bf966,9915d938,219c197d,37762c8e,491d7cc9,48f1c993,c4406dc,384018a8), +S(9ee3eddd,519e44e4,c53bd4a5,f7101964,ac47a421,c72fe25a,96f79516,96c078c8,31f39cb9,f5441d,613eb470,5e9ea328,ff1f0b74,3835e7a0,f9b6ab5b,bb9de8a9), +S(dd7893db,e0028143,fe5739a,832e4aa1,ffecb200,d13f7b1d,a4877234,4330c15e,a38052e6,e03f06ea,d3c3f712,964457a7,52c7eef0,ca315f56,4060022a,66f6ee3e), +S(e7ab0025,d07507c6,6cd34270,8c0a89fd,53195b4e,ff3ede18,69488886,9eb91cc4,caede34a,6f8cda34,77bacb2a,935113f5,93b69979,18102777,bbc26128,9b0cb112), +S(47f608df,6d649b02,e55fdab2,a2bb4743,2986b9f8,61460cc7,c4961f51,89b57e91,179f29c6,6dd174de,bfa95876,22434b35,2e48f45d,658bf7af,d26a19a3,50333560), +S(3015cb0,87376de7,a18e7349,556b2351,72f27f37,e3a217ea,c7a43762,bd3e57c,a2e673e2,6b0f1888,14cffe51,2ff43eb0,c241e239,1f130630,dfab55a0,e12c844e), +S(aa7f171d,463433c3,93139c76,71d1a0cb,8b7745c4,3f3b1f1b,1669e3a9,75120ded,b8c9d145,9f9e9651,bee3a7f3,fdb71bb0,6deaafdd,1912896f,4b6a0e74,6869144e), +S(1847e63b,ca44c694,9ec3ac84,773af743,337d2dd7,46b6c5a3,ea9520ab,5af25469,ac19fac4,e3dd014,349c44d1,3436cb8e,465a754d,eb3f3c2,ae71eade,6c5a067a), +S(c11064d2,f638bedf,f762b481,719c85ca,7797e913,79cc3d12,3137ae2a,7a273179,7f74f429,8b47a566,bd3b6eae,80b47dcd,38e8780e,2ceb8833,dbd74462,c8f3db3f), +S(de6928c,f298091d,d1a42817,22d8923d,de25c954,ebfb273,80e17943,c641cbee,b02cffb5,47247542,be586c6,e88536dc,f6882d91,e76aa7fc,8769c2b6,5c585cd6), +S(2b8b1dc9,f379f2fc,a30d1f28,7877b47b,42f04b20,214c0beb,13aa2d28,83c52d12,1f660659,b7ea56c7,edd02c57,d6daa12c,d13671f,b657dd02,e75905b0,64d51d81), +S(90b39618,3eea7012,c537b000,f5f1ad28,e0416fe,6b1b874,effbfbfb,b963be57,bf37d7fc,ef9ca5eb,6b9886a3,b6b87f3e,976535eb,31cbc0b,464e69af,fefdf9d), +S(4fdfd77c,a033de11,59fc95c,ae07cd03,c570380e,ad2a376a,957bb26e,89bd4a8f,a1b30601,245aef10,ee891ce9,83cdbc66,390baaf7,b9c833bb,ecc34148,79f6a866), +S(7e2c3510,9c0a3eba,7b8b9d4a,c3c8d1e5,31304e45,25404814,fd66c3f3,3f12a1a0,39a8b59f,ed4d9d3d,29d8d1c3,130c1fd1,dbe7f2ea,cbc0770e,fa18e76f,3322a107), +S(4b80ce19,a7101706,b4bcc308,a4cd92b6,f8177a97,e2b2b6e6,1ebc2ca5,32c4b48,b72eb80f,55486930,94c8bbb7,bc6985c6,29c85d10,aff7d243,e5ead021,2b44587b), +S(8b07cf,264b3d2a,21705a59,dd82bc7b,573508f0,597831e0,336db2c5,c3702e3b,1b992b9b,8fe1a29d,d9781827,edb8ec89,49f6d412,12fe7e24,212f805a,4c4ff0ed), +S(3b65c4e1,d3171be6,67b01021,55644627,d64f9375,bc36fd3d,2c2a4fab,47a59e68,573fc9a9,1a09f5ba,78ed796b,496e1d68,a3f529d6,d0a77095,5ad16baf,e7b1e047), +S(baa6b559,e674ace6,a0378536,8643b0ff,42d8ead5,1c8d937a,7b1de152,62956003,eac99c3f,696ee584,7080f488,3b112c7,f6c69b2e,61a6e20c,135f5933,86289a3f), +S(e6453682,6cb25506,4107be9b,b0c2c225,5038c11b,96226fd6,5f8db8ce,70e32fe1,f74e605c,71912ac9,5e2399df,4f3ad24b,1c3a23a4,4b5ebca3,5ab8f31c,737d9aa4), +S(1aee4f20,a2db8e58,f33a8eaf,4a8218a4,b93212a2,60aea21f,64acfb56,3c8c5e83,3fc248a0,956a3136,daba7450,49e6330f,845ffac0,c2ed2f93,36ad1862,eb8b331), +S(8810ec79,33613ee3,49e0dba5,4a8ae34e,67a01322,46830eb6,41dea38d,c47f5941,c9c15ef8,c6a57a44,e9ea1832,c1c62dd2,c8aaba21,48d2153a,6e5a9001,281a273a), +S(cecb3ed3,a3380083,c8217e07,4cc0473a,3cd2c9f8,1ca8bc29,4494b01a,fa1bdcee,8ea11818,8b25ffcc,7d83039e,af605c9c,4132c83d,e97cb207,ca83f43f,26a557cc), +S(ea24fc58,d19415dd,aa780932,f7fded2b,e88987f9,9387d43b,24773ba2,1b810bc5,5176a2d7,a5d955a7,6452bb2c,49048329,b83ebcf1,2f3433ec,79573c14,4446e149), +S(facd3728,c43fb0e1,7f03a1ae,a7997e47,615706dc,3427039f,b994e14a,9a06d7be,ebe7826a,fec22f08,3108c710,9b944cb4,c4427b62,11f1f85c,474da8b8,25965d11), +S(439fdac4,66739dd,82c29854,fa9d599b,6fae190b,18192065,8a6cfd7a,1cbc9a5,f8bba187,677d0d3c,d50ee132,3cda2daf,d75aa6a6,1fca861c,2836d096,d1e3ff39), +S(167491d1,34593c79,6cb90f5f,868cea3f,56ef9b1d,e36a010f,a9d90eb2,9818d9cd,38303727,58f84ddb,ad5733a9,ef131555,14c314fc,4749efa3,4562c441,201d506a), +S(31ae24ac,8a76f509,2b721ef5,102623d7,eda96598,84563c1e,8177e3ec,6abf6ae,c3dfe7bb,c8017a0,e2f501a3,c5f11e04,d5a64dd7,ba2d0ed3,2082b7cc,fbeb2e1a), +S(b51857f5,526b8179,3e7bc5ec,7b74062c,57dbb146,1fe68d3,48dc3d55,d1c2d66d,f4313526,d268b372,5d1368bb,d40ac55b,d5f43377,de17bd6d,efd8f536,7c346f3e), +S(ce9c7eed,356d5ae3,b3334031,550f375d,35cd6e0d,eaa760b4,aac1141c,bda83df8,560b3067,c53c8f79,5916c5bb,34d99c02,efe4e5f1,f4cb47c6,f0662aee,2f07807), +S(1a9dc184,362a2f5c,58c53c53,160fde7d,f7b4c64a,e9753b7d,2d98be7,8c91cb33,bf4f3c80,8798aa25,bbca244e,1a070a57,c2ea26a1,59ae4ffa,84a4125f,c3b1823b), +S(3b3050a0,724a3c3,746e5bcd,832799cb,875758b9,2302eae4,82bc3c22,f17cd341,be5afdd,5fed6544,23bb069d,6dd96cfb,1b82cd9e,14dcb35,e0d7333f,54f924a5), +S(a4493930,c44f988c,fb634d59,5a0defbc,b6e9b809,133c0925,5c8ccc06,b93dca40,da27ecbe,97603604,2a559942,7176dbd4,fcc95ada,beedaa43,e40d5ec3,de5c4770), +S(47667272,59f47404,5fefe2ec,7f266c25,f9583c16,ca8fd4da,3149e8d1,bbf7dcef,526f565f,caa55541,d31524b,e942ab80,a895d270,a8cfdcf3,99dca02,75cc0f0c), +S(82715959,aa92d89f,91a7f53,af2d7e2a,2a3e8b85,2e30003e,caaea68b,774bb918,85188269,f1c8e6b3,328f1e04,1e4b79f1,8345dba6,49541f76,30dfd9fd,c1957b9a), +S(caff710b,8a246b27,1b7b8cb7,aa0eea69,3a1ab37,e58612b4,efbeb2b9,f1d4c1b3,7d20c6b4,5cc53865,7485ad82,43e7757,131528d3,ec134a13,b009032d,bae1ae23), +S(6270f6ce,665d2b6f,7d6ebcab,f556a681,78da916e,86b543c5,97771fc3,bee9efa,700f4b6c,b1487e66,af0ef5e7,9e98585e,b22c8e05,66cdd93f,db0e6ac2,809c4271), +S(f5d502e0,33d809c2,32f5eeec,bb4fa68a,97d5d231,6e06442b,2a3e5bc6,fcbdd6af,e802e5e8,ef9d6c91,ee5b858c,f6d62ccc,302eb555,2529cf5a,808dce72,14e3644c), +S(3a0482ce,c7c453f9,6a4d6f35,d8e3e51c,5f94b58f,a68e607,fa09cd44,ce09ccb5,fdd0d694,5601b9d5,437e587b,ca0df637,e17e7ea8,cedf9a6a,9f6f164e,f979e523), +S(54f22100,7ffff6d9,d5886947,8f164fcc,a67cfe3e,65986be4,bf9bf65f,8af89959,3b9af1d6,9036d3d4,6a6d121a,9653452f,61c3454b,2c786fbc,c497f0f2,e0ff792d), +S(7049ffd7,46bff6ed,c29f2e5a,d3dd5397,e96cc7cb,a1c30eb6,e71994ff,2036fd97,6e127611,95338ac8,ee94c953,5aa13afa,4f79d1d7,63994baa,e932b468,729501db), +S(f79cc302,7b4eb747,a7d67fb7,b1bda0ae,e47dae79,b410a6e,dcfda1c6,8c69b1f8,81d75d83,a5bc0e36,25d6aecc,6319120c,1c8df3ee,eeaebdbf,50ab9629,47715a9f), +S(fa0fba16,15c8c22b,3895ad47,8a8e2ea7,3438092d,150c86c2,8527b38c,2077a9f5,5f351702,7e1a8231,1eedd70,4cb519ad,f550dc64,dd1321f,705fa6c2,54a18947), +S(49b2fedb,7acc5ed9,7ab5efa9,e5b35377,b8dfe602,a0fa8a2c,5294abd8,9768aff9,f6b7325c,29f5f6b4,f3b18c9,366a85d4,60df8b78,ace02604,8af1cb1d,972e4042), +S(3623f1ae,9e3bc23b,7e9d758c,4444489,c3d9477e,eaf61b08,37f6ed,b9e0978a,f2176087,f401aeb1,f245a2a6,962afec9,fa7425c9,25cdff19,d137bbd9,f756885d), +S(67ada72e,262c36b3,cafec765,ec0209ad,c926b367,e5b8730c,b5d4db5e,37741312,7b1d7d71,511d4b61,450f847c,242ff70f,9729b2aa,c2e2d97a,4083e7a9,c07ca08d), +S(aa61ad71,44db1e8a,7d8a2f4e,80b471ec,bb891cec,7d16a8de,99ae20d7,9a11d00c,b344fdaa,bbaad87e,56d9093c,2fdd0bd,59316f31,2dce7a6,344ffdff,84ea71fb), +S(5dcce9b5,ba254153,bf270d61,494776bd,84f7be8b,f6a6ec2,9c2e3189,98e243d7,cd3b40e4,6bb08d2,5797da0a,6afd9066,63211e04,fba739aa,6e4f7f1e,d3068746), +S(8fbd32e3,c91dc619,ae0863ca,47b95a2f,3d8ffd91,1e41ce5c,b9bdf529,2504b1a3,b89f6d35,691e8155,703441de,b0d2d726,83247df2,ea46357b,ef5676a9,e582f29a), +S(dd31d01a,7af2d173,ba0c5c1c,ab7e59ec,cf8882cd,47904372,45d8a786,d1bd3480,91b2ec5c,59193d1b,1117763f,8c913d87,af40f6fb,abe53ef3,3e7548d1,eb211155), +S(1a9b64a2,52ecc6b4,4c17f134,cf32dead,66e4344e,44c200da,8c261d76,838a775a,1a2b618e,e96fc285,6be86b09,fa6caf61,4f7ee3ce,3bc34ce3,72c522e1,4a95905e), +S(ff9613fc,de744879,ce9a7c85,11508428,771d9421,b760d75,39adc805,61db7678,9a736730,5df91c31,9711c882,ede59e77,c09e2c6,f8b05232,2c0f79d2,77a4ebf), +S(3f29e50a,f584e0be,71247373,be4e9e33,8fca36e2,28f8498,ab57bf37,31deaed,b41490f6,72bcecd2,7c45a524,ccec1502,8186fd1a,759e4ec3,ce2e4a4a,abcca36e), +S(66457fff,d8836522,26260eed,4d00726d,ab8a56ae,26c68feb,f6ed99a3,ce782963,511b11cf,9237b49c,ab1bffdf,681f59ca,957a8182,ca2827b3,6cc962ca,d2becb29), +S(cd369d78,9ab5764a,a42dbd61,7fa711b4,757b17ba,fbf012c2,17a30cd8,dd42fd6c,42299f3b,674dee41,655ccb47,7783b8b,e54e0ca1,ffde384e,dd4cebd3,283196e1), +S(ad9bb10f,622b22d3,7c25ed15,323f1675,c6d12016,3f059469,6a8f508c,318c045,73f1883b,ef27a26e,a2dd4ae4,c399be8,2101c1ef,a6e67dc1,77dc343c,c56d66db), +S(2bf2ef32,e0277bcd,5ecafa49,910eaf8b,f107d591,fd0fe0d7,77b1ceea,c600c42f,6b8dfca5,f91f53fd,5fa8ae2e,53e72c95,9823c44,d2c4e7f9,7badc1b8,56e6fa80), +S(e7498183,bd8f01e0,c272e36f,1581c1da,907d7b06,8e3d6cd0,3d80c051,30dfdcd9,409fe739,b7f28ef2,4b94cc71,8856c99a,e67aaa3f,bf3bc8de,d71cc22c,9d4e4911), +S(b3921311,72c00c5d,fde1ed00,6aa50d01,9353bd2a,9e27afd8,60a71e02,123e7887,486cb8,d742f42d,9e00b8,e82083ef,bd1b8334,9babb4c5,a3a85c2f,9441fce1), +S(6cdd0e5b,edda536b,9c747302,4c3a8645,ee929f54,ed7f23b9,7a1cfd1c,77489e24,b190166d,b0ad70d9,f0b422f8,e5f0a0ec,91bd9cb5,f8bcdfbf,2c7594b,71c19e1e), +S(51bb4ad5,379c8dac,c5e6e19,6735c84e,9dde67b8,bdf4457d,35bf937a,3d726a8d,49bcb2c7,a0d6af45,8544b9da,674449e4,c099a56f,d0dba507,6b02a9df,5ce294d4), +S(c57bbff0,297f3040,3b81de70,fe524300,5b7456f7,997f4037,f6206e0c,277c74f0,316c5ab3,95b66038,ec5772e2,7aa2f7b5,b54e5511,6ff35e0a,5c4aa11c,efa8d05c), +S(ae2607b,d956ff85,12b5554c,b188978e,e0408c13,82739be,4e68b9d0,7bdc45eb,294424cf,51378200,ad3eae19,26f89a73,ec3398ec,8af9026,5ea556bf,83833a27), +S(95671646,1c47678d,5012d1e6,5b918e89,c96f699b,a7ecf63f,d6eb275b,1fe508dc,abbdc408,a59b2e85,95a7a2d6,fd133767,849888b2,f17070f2,9e827fa8,17bc66cb), +S(e98b0e03,d1011075,928809f0,aa62f238,40e8319f,b0108be0,2925a291,967c7702,ba34d7bd,138fabe2,11ac56a2,2d385316,4cdcb1db,ee647cbd,73493391,a87027ba), +S(c0f9812e,b7f529aa,fe875709,1928b262,1277a751,73011d63,b0c92efe,a02291a6,ed5f2cd8,5e85ce14,9f59f50,f3a6db29,67095adf,91b08dc2,fdacc0d1,d3d56391), +S(fd4dd84f,75fe56b7,543a60c1,7a3ca1b4,6f7b9b3,6d6d5c4b,eaa18a6e,6c4ec6f7,cbe12b0f,c1bc2973,ab395480,50d768b0,8c9ff86a,97f2ab4e,942cf095,a10603cd), +S(f00052f0,700d99e6,4d94e1a8,a888abce,3b15b52d,1d08f20,3234e5e8,9ee6cdaa,709b247f,f1daf175,ad7c29c3,bb5ec78,1521c5a3,3e4674bd,d97d9891,7efb07d5), +S(44d51252,7024b64b,f6d30ed2,9e176fe1,fbf22cd7,5fbbcb13,4aedeecd,5ed2c023,eca73cf2,b90a0f38,2745a43e,64048010,259c0c74,1deea6fd,bdcaf497,9b1e2f2f), +S(15651366,b6cba09d,9409023f,964e48fb,422f3211,832000ab,6e84e1ec,faaa1472,bd79070b,a7100d6d,63795ff7,43a26834,85996819,e9bd81c8,b08dc473,5e6bab6e), +S(f8ea84ac,35b6e596,5b6ea25,8411855f,71de79ba,ccca4ef9,b79eec8c,c9e098a4,58da08b5,26d6d3b,22ee2b0f,7e04d2b,ad902b8f,9f4f1f5,454cc0ec,fef6a2a7), +S(f4be9c47,94b6e479,8ba892ee,3aee0fbe,b0cd7ace,1c9d2f4d,ac03d92f,3efa405,e6828465,7a6e2175,361a914d,4d09eb7,2468da10,d72dd3b8,47b71e5b,6c8593e2), +S(65cbda31,ff7780f5,2b31a743,ac03eabc,4f2e3155,8083f198,46a03ca0,d582e348,b8433ae9,848e425a,603c4591,8f64288,fb58c184,454c6c1e,e9d8748b,c3a546ee), +S(e1bee56e,3f500a9f,4b5e0557,157bcdfe,9223c357,2d70ccef,8b8542e7,f24bf9f8,c5b84a5d,395d9c19,8f1cab7b,3a9cfbf4,dd129a03,e9fb6019,b99c48e2,a0d574fa), +S(7de38584,d12ff024,a179f361,5c44d704,c4dfcac0,4939a8e4,a46d1574,7b6eaff9,2797f251,ce328323,e181c130,59ff6d2a,261a12f7,ebcc0dd0,55771a4f,edf812bd), +S(5767e926,fd4ad964,f4bfb7b1,c6326e55,97f9cce3,ada51a20,6b4808f9,e8abbbbc,64a80f76,8a89806b,98f0bb01,b370c200,149c5484,a9cb5f3c,af8e47a4,27813693), +S(828bdd32,18e6f809,6c1fb305,1e797ca8,3914f9d3,ad051eda,d2964cb2,dee88c6e,5a7f7cbe,166f2cc7,b747a1a9,3e3de1f0,3a0da8c4,82eaf9e7,d5ee7e7f,e4936882), +S(617fc9fe,3af26495,bc6277a,86387377,55398b94,1665b70c,32d5a2ae,3d8d2909,278aa70e,58c0ba89,f44dcefc,bcaa7212,e52d8eb2,f3735772,11e864f,2d522ecf), +S(1f823558,2c08ac8f,f58648db,194bd6bd,1f3659b5,5fccd0f8,67c9f11,86e20634,bf356f2c,fa221b73,bb118567,518147b8,f0c8f19f,b82ab45,41e12b1e,c9fbebca), +S(f6229866,82530e4b,301cc0cd,576e9fbd,a65bd52a,d85a3ace,6477bd57,af52c718,9d2cb0b6,ff327470,e8beeda1,1e2d390e,28917515,a8bbd587,ec303d77,f57ed72f), +S(423a8b60,fe61752c,95353258,acddc1d5,5ac7f226,695d1e73,984ab059,8810f220,feb12e01,7501fe26,72059bf0,dffd41a,f952a4e9,84491463,29a4d294,895eb654), +S(f55b2c40,6ff6f463,1a2715e9,d1471c98,9f3df537,75e5980a,2a48032d,9936ff12,67888b7,e6116a5f,94380503,d1fe63ea,a3ea7f71,64e79500,a0db1201,31acc6cc), +S(cdff1ae7,ce2ba4ba,8c8aa999,aea60f06,f6dff050,2e802f6,8f27a352,edf9e3d4,81cd9da7,9fb9adf2,31243148,623906ff,3e80d730,a4977dc4,16539452,58d8f2e4), +S(ba7cfaa5,96502414,984b4105,739c5fdc,a77c6eae,f8b96cdf,8b8e9fe6,f7f62819,bdcd7dfc,ab11f75f,e5eb04c5,5e7d8f4e,b622ddd,8134e668,cc9f27cb,bdda688c), +S(4a7b5b47,865e94ef,65ee1053,ffb75ca9,8a7a01e7,78d8c9f3,9a8d5c9,ff2daeaf,c64ad5b9,2a5b9995,77eb3a4b,5347ebee,99e5bc19,15b1f43d,5af38361,9050e5a6), +S(26a13407,1f6b82b,239bfdc8,ca2a7f94,110a63a8,b20ed990,71d63e5b,938ed91a,14fab6a3,819f4bdd,348ede08,397d7f81,d514e99,cd777fb9,f42917b8,4cc80b7d), +S(154f8ad5,405cee5b,42ea1910,427ccab0,1861c0e7,29a1ddc8,7e8307a7,5102bc4b,37c6a2b1,f7532681,7621f58,75db7b09,18118be9,6259ce12,ecb15459,3231209d), +S(184496b6,b31e534d,ea2a9712,f22b83b5,a82bd14c,2cb90b8f,b20cb735,3d4b9e39,bdb92f21,7807d1a8,82912dfc,50b3af67,ad9e936a,6409e263,961a82f1,31fc4c0f), +S(2d781eb,a2253f32,75feaa51,fcef2a34,413effb9,2f6523b,371fbe54,3f33789f,5c0f0c47,b11b4b38,5e8d2d75,eaab2d02,39c2e63f,125f21d0,17d34fd9,d1f6a91d), +S(cd6fb1d9,790c93a8,3813fcd,8036c0c8,af3c431,f21d334d,8816001a,41eb83ae,15f0f885,511a12b2,804c90e8,cab5d209,76db1e9a,9fe18326,9d1c7570,5bc24f65), +S(97f9ed25,9852a72,3b4bd360,681d52da,fc7d17b4,5e7656de,1448e499,ceba2aa8,3c609c78,25553260,a85ccd6a,3fea7b00,aa87e76b,3e0e08c8,2f7c3fe9,ce760cef), +S(72765585,fe283950,cb316f48,d847132,8782681e,54dad1f1,c0a0a50c,c4086767,147e2389,3ad0d7d6,a3472bff,2c6560b5,93b554b0,e6247618,3439c576,205b4fd6), +S(fcb0ecd5,93a00061,2439cb19,f7e5f71a,4612ec9d,1b9b825b,8ca322fb,daddcf3,5e9f5967,f7131ebc,1959da85,94069704,bab1d58,4a06cc8f,78cd4140,9f532eff), +S(ad12b476,ef630659,2fb0fdbf,522314cb,9f185f2a,e420b057,880068e9,7fba5539,38ee0f47,57ce8f0a,bb6cbb47,ecce2e86,5ab84597,f6aa91bc,4c4c6b52,68755886), +S(372e498f,7ac9618e,3850fbdd,c9c01995,d96747be,2183e472,8dac7ac5,a1c7cf65,4d5de2e,940b12c5,fdc8dfac,69c7da20,4b92e570,b59a8bb,2cd930e7,42b76cb2), +S(dd613209,fe9e2699,9371509b,5162b3e6,e3557515,c73eeac4,800f6e28,28b56fb,fb1c28bd,c0b4c0c2,bcb53557,5b3b4377,c9f29786,31ae6c65,490ef38e,7fcbe1c), +S(8da18bf,6f680ffa,bc4104a2,4b397a87,25240704,287d7532,72df2321,dd94402d,46ccd8a9,401c4fb1,9c81a737,43330fd8,d3a60361,b94e47f1,68342280,373e7264), +S(1800dce0,a2f3a3bc,29d40690,ccddba47,fe8a71df,e646fae1,15d4a784,391a13e3,b333eed5,deb1b43b,c6646a2c,909012d0,21c0796d,c14c90f7,d49c6b68,52e1920d), +S(b6041277,4cd089d9,9c3f4434,2d328b6a,bfbde44,11a60f38,ffdab086,74b834a9,3157019a,32bc8cde,344e60b0,970b26db,4be7077f,956e98bd,39cc7915,64a13f2f), +S(8be5e638,5fe5f9bd,813449e3,bd76b6da,b4ed7fec,ba853ee3,a302270b,556281ec,e114a14,136a7341,5e8af8bd,23dd589c,cb10441,aa173eaa,21c06ff3,c03ff1fb), +S(1ddbdfad,990c5764,ab076a62,27497400,410f5d84,3b9f403b,d4f51e5b,f0736518,b2688561,7ff17294,9c8f89ca,2827f0e0,a1483e8,b856a659,a009dc68,c5683f0), +S(15458735,4f122df2,18c33929,8fcd0bd9,d032411a,cb76df93,31345ba9,668413c9,1b3d7e33,cda314fa,fb90abdb,b1ee2105,27b35732,f0b77f39,69c942a2,fbc54195), +S(925114ed,22625dd6,d4d947df,87a2b63a,a97f3a6e,d47afec6,9e11a1b3,3b798630,55e48dbf,a47c887e,e3ba5758,4f697f6,7f6a1d73,fedae7f6,f63e4592,cfb33e03), +S(9111ec73,d2e56190,7db6c07b,e7324fbe,ab51d18f,8423d484,cb6a0d,a0a7ad27,f7317b13,4befd605,a28b6549,1b2752f3,26c86370,f5042832,1dc22b0b,9240c8d7), +S(f2d1a752,ab206393,7f780a3b,9f39d87e,9d257c22,beb1d286,9434256d,ba9dc3ea,39d4603d,e66337cb,f0b9d39c,cc40c16f,4835ea6c,aed5d7b6,2cf67ccb,35d5e752), +S(2588d10d,a854b844,afb998bc,23aa3742,76938d27,b08ddf70,48605df9,ad55fd52,826c2422,4d95ae53,daa562cc,88e44e52,5d3ff878,ae350e30,c1c633f,219824b5)}, +{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), +S(6e6cbdef,4d5cbace,b79293f,ecf1a4a4,5de81e3e,97e4c30a,ccd6cf79,5668a013,729e4c49,2f454b35,4b127cc3,788bb93d,fd83061b,7f7f6ccf,c24d3fae,d96a7f6d), +S(29d56adc,c1fe441b,123a94e3,fb8df47f,d8bb8565,40c1d3a2,d8e7ed35,c4eae6f5,6a3aed22,6ebdde19,d2bafb8c,68656edc,9e3da959,f2af9872,3ad29a04,8a549a33), +S(c243cf24,3cc28801,e120fdc7,ab6f8ad7,531a5053,1094cc2c,3a9476fa,e0491344,3decbb31,22c91c6f,502eb3c1,7ac22bd1,509643af,3bbcafa2,ae2b6eed,18decff4), +S(2d2bddef,e75d43d4,a8b4ab19,b2259a6f,24bfda1c,11fedbf5,a12fc353,f0039157,215173e1,1a9ac83e,b339dfa6,ed66efa9,da876aae,5d1a690,4c8ea43e,63b683b6), +S(d2796d04,f82115d2,c4849c4c,be608005,1a2dca90,9773a524,56b2fc44,8bd6d7e7,be176139,829c1b69,352e502f,23b724d8,1181ce81,c447e253,a2bc132d,e3bee967), +S(48cda6ae,152ca92f,287a9cf7,ae9be740,29cb8e3f,afc859f5,31f920da,883eb4b9,55fc18ef,af858cdf,a098c4fd,8e3f41a0,92292093,a3c66866,1361edb1,c07956be), +S(702bff16,c5121a82,cdb8d6ed,fab0e741,f76c08a1,70bdddb3,8ff191bb,3a96ec64,5525ce00,3cbab9fa,58b60b7b,5b5e85a1,e208517f,91b0caf4,9adc0c5d,ac0e6e23), +S(98d066f4,30911d2,238cdc81,5133563b,338f9a28,2da63518,6635af43,fcdc27d5,6f10df8b,7bbc5ed6,a64f1884,1087d5f5,6cdf8df0,f9dd493d,23f6996f,ff39e065), +S(44e69b1d,5b7c3816,af2aa890,dec5e389,cbdfe5d6,44d6c0e2,f36527a2,6127b24d,1ad0e960,7be9fbb,efde8dc3,6030d3a6,41e325b9,48129ac2,b26cc1bf,11b331c0), +S(adde6eeb,fcd63063,ce995ba5,3641b01e,f0797d41,d9e18f78,43972f89,9d7a518d,7002020d,f2576876,2d82a067,139387c,7956680b,65fd70ae,3d75bfd6,fd0f77a2), +S(f0f09803,b43d4c1a,f187d94e,3dd9be54,703cae52,5f15fa37,ddcfbf24,98c9c24f,96f4a35a,40523728,10ebd243,ac6d1419,672fe0d0,c013f1d3,460089a9,2457f7dc), +S(dad39c7b,d3edaea6,3ff16c4f,a9a30a9,36d7e447,939327d0,d4a7fa4b,33d7126,6a927d43,3237ff27,f3f87631,c85e4294,1b188fc,d5ec4780,a58409a,cc95d02), +S(b44484cb,b4dc709b,4c21cbbb,2d7d94a2,c5435cb5,1fda7dd4,c3b787f,55df5d1,70e35874,be7a22c3,1e43f2ef,8b4eb222,5c1dc3a8,cde5fc0d,56ab9970,bf4db709), +S(84dd9c05,3cecdabb,b3ecf8f7,c8737e22,634fea44,80c03148,38d6bd35,6a15634c,7cc6a067,81eefe79,d565946a,96114b52,8a482eda,a9028c5c,b925f037,a75335b1), +S(e45d6bb0,50e66a94,d22b770c,9500d960,6f529222,441bf9fe,7856899d,edf3537c,5ec38fe5,7508aac0,eeea33ac,3aa44dc3,e600d184,a4ddb9fd,64acd359,be96336b), +S(25f043ae,b509364f,43ee5ba0,291c95bd,d442fdac,3f00e338,6397fd4b,295416ac,42456a08,64245a0e,5dc9d06e,1f4aee74,b4ca1c80,1281bdf0,59e319af,f79c7ecb), +S(77c7a59b,64cf6153,275c083c,ebecc3f3,59e66002,3bd2344b,a465cc5f,d44b6938,6415da93,e98298ce,60d96880,2dec1899,84badce3,642ee36,70558d0f,bfddce01), +S(1930909f,61cda446,a270581a,2bfb8ef8,14af75ab,aff6db5e,c9235020,af199c3f,4b7d06a9,5a7f72b4,ad189ff2,348a63c6,522e8b15,38309e97,cbbcb121,50f53498), +S(14125e3c,7fae63,cf0103fb,8bb86de4,b97572ce,eb872dd,5d850825,c1c5b43b,dd1327ad,8570188c,1817ee7e,37a164b0,9f37fa90,88784d96,f91704bc,e3e50b71), +S(c8e7c8ae,b060e8e3,1e768fe7,779ea91c,3e62cfdb,80893516,825d13cf,6636face,e08a5ea1,9b5a859e,6f8f6a1,43dbf751,854fd9b4,2ba6c1fb,80acdd9d,9db87987), +S(3258309e,4b1682ef,5622aa75,ee7a109c,ad650ed2,93edd279,55fdb064,c35abd92,4a192aa,838bc722,8c0d7fd0,200d55b5,241cc762,d252d138,dcfabe8c,e2ffbcd5), +S(42a5f570,4745968b,a836648,373af34d,d09c8f86,536004a8,6e043c9a,4c11a57a,2bff198b,5e8bd837,3011ccb0,1fa54719,7030f47b,eaf44ce8,6faaa86b,166ca642), +S(f0d3e1ec,fd41bc71,d2950d5,d6db5614,e1b560ea,f8119175,f7286a8b,d9c6b563,f4c2e948,a30208b3,a7943bb5,564747e0,50e079f7,703a0d5e,f8039d8f,50acc8d0), +S(7f918a96,3c4b42f9,17c61ed3,f4be8d22,c9055005,a5a3f02a,6def60e7,305ab89e,c5e60518,189e093c,62d6f7bd,de1d723d,878683f1,22b9ad69,2a300a42,c5ce9b5), +S(c8663293,f25331c4,a42b1e16,bced09c4,bf7407ae,595e1331,24d0f7ed,99cf422a,df5f065f,d7ee1232,8a3428d5,c8485a28,d882f31d,e66856a6,ee4aa396,79d978f7), +S(778cb411,8c5128b4,8641ca54,2cbed0fb,e9240380,ad3736c0,cff889d7,1a6cc639,8a1d3417,6f2fd7b0,20b46be0,7905b963,cc1a3970,c2bc1995,daea532f,9ce8ecf8), +S(11e3d37,e28172c7,de168ff1,2fcab6f3,3441c007,1e562bc7,d0f13392,df64d0dd,a811db15,8e49072a,7a238be1,128618f7,d7ed2e15,bd437aa3,69cd2a8e,3d28d95a), +S(d65b7bb2,143c9f85,c5c43c46,57cbb87,3d9df9eb,876fa72e,a1f1a221,37a370a7,f2823561,e19c6208,64a1e8ec,ead2101d,175b7255,2ccb63dd,937a5049,3033b986), +S(d02ecfd4,74b5d84e,96111bbb,c88bca3d,95498de1,4d133893,2c4c6068,9f19efe8,87c93642,866c847a,d592a36b,bfbbfc8a,68b3da63,a7d7f380,ce472b0b,9e0f1325), +S(978310ef,548ad9fc,1872bb08,dd0f9ad,98889ea7,719c5cea,fdcf1bb6,9853e2f,d067d57a,4e7ebeb1,f05127c7,9c4ba3e2,fbc3c2ba,9cd9f2b,66182d69,2c699e21), +S(66d8712f,a2221e85,3f4301c1,cb8b1413,ad9288cb,bc64a778,4881de9b,bc1ace0e,67f8a70a,475e9208,c1fe988a,e9ef79b3,67295abe,9ae283a1,5801260c,f916f8f1), +S(da8b079f,280a64db,a73ed601,2d183e75,175534e6,cc295a63,477f6905,15b3daf0,c55f2528,8812131a,99a89f92,cd6204a6,26a7681b,e4460ddf,9a1940c5,8764f43b), +S(1a2bb7c8,96722b4d,54828c68,8708bae7,31937165,daf08d98,eb02fe0a,a59cd00a,f0cada44,48f88668,e46425d0,f64452f8,42be2fc9,bf33002e,fee5cd76,39e5d581), +S(2a55bbff,5aecb50b,97b974be,f0cd3203,34752370,957a9e60,37f2930c,e11a75af,69f9db00,b89a2063,1b4097a0,f90ef087,a9f7cd81,ba15c60a,faff63a6,a4add6a), +S(2fa92f18,83e0ab3d,d6976573,83734908,a4873e8,bacb0577,c44bf104,5500b6c3,bc24564b,d4f60723,14aa2864,216c6984,22caf8dd,afe0e4c3,a86e12b1,5faed4f4), +S(5548afc4,b095db29,28511e52,bdd99a63,18e5e15e,17e99da5,b9e0ef0,375b0999,784726b1,d2152b34,4b0c1a2f,b90893ec,80ffca3a,85fe3f65,7be4a850,175982e9), +S(d4a524cf,6659a1a5,e24a40c2,8e4c9cf7,da607f9f,c209f88c,63c35dd,4af282b5,a73bd4b2,599d92c8,395be7eb,cb70d741,154291db,151e988d,9a7a4f84,b277b886), +S(e0fb0973,32dfe006,54ea1a3b,858d8d6b,30c26fcb,c4339ef3,165b861,ead90352,43ade413,92521afb,1e87f477,45ca8b61,23775ed4,9a1c789f,49a2290e,1d032def), +S(ec03ed52,bcf2ed6c,c7fc2a19,c95a53cc,3b66e344,4d35ae06,e5d17e2a,b6311f0c,a83cf9ac,89accdc4,667686c1,4dd83d8,d3633ad2,6420da7b,321b3123,4d8150ce), +S(dad8eb7a,a7a8686d,d78c18ca,7f0d4d29,edb8ddc0,4e5dc2ed,4e0f0694,1551aec1,10e00983,af99a823,a32d82f4,2d7845df,d3828133,963ba48a,19497860,d975c600), +S(c883f469,e74f4434,9b4e1459,5fccb517,7e2c2f8b,445feece,901dbe96,a2556ee6,2bf2b62b,5b1c3415,29a822e2,16ede0cd,b75419b7,d212774d,7cf3721c,4b9d496b), +S(8c71d17f,cd711b3c,4e2c1214,64d9dc47,c36db06b,c877a0c5,8a31cc25,2ba585a6,9b248bce,7f4899db,4c8e250,c642d24b,20419ab3,a65cd4cb,624433c6,37aedae6), +S(4be86c17,32474f86,f8331f50,b316e0ce,d6591d47,49875e5,33e1b825,7b5cba39,c4ea74d5,62489423,45aa7cf7,82bab029,8fe58092,4943d3a4,d2fc6f0d,7d0fb590), +S(f5eaf803,98fa27f8,27771d6d,50dba53f,32beb3f3,40d6c045,cf8b4253,644bbf5a,32809769,fce5eb19,f0877c19,317e6200,11303b0b,7ade7e37,abbec95e,fc83740a), +S(585c8726,bdfb440f,8cee9bc2,4461e3f1,8cc7431c,e8f1ead9,af2525ad,8b32abce,3ffa336b,a5bde184,676f33dc,e46c4114,4dc412a1,8db059a2,d7c6b021,7728c62e), +S(9175ea6f,746ee2d1,bc893b3b,6faf835e,ef72ba7e,588128a6,56cab59f,737871d8,83cd907d,b0d601f4,88cca1eb,283cc2d6,99913dd8,391eaf27,cb18ab21,6c13cd8a), +S(c5898c32,306bebf7,7a89cafc,29b49af3,d1ab7fa6,95072cd8,6a8c2bd6,aa8f5d14,2313c593,c67e797,49e44600,7181b257,dbc876a7,e3e04747,c3db35c7,d8df24e9), +S(d101d707,76661eda,ea604ac2,2e449d83,57b638b1,aae03a6f,2683ebd,f6e2c413,7186ba53,b8b1d9bd,b4dd2fd3,7b48c3c4,144bd996,f4254291,3c4316c5,2a98ef87), +S(72213fe9,8e8c62cd,bbf8264e,6ac01240,f3dcde5b,b5f71b46,4d8d5617,6fa65efd,80b256e6,21a5041,63b31c96,7753adfc,9c27b4d8,cea73e91,dda2d5a2,7bc50fd6), +S(274c0fa9,f1dde789,1f88b202,4c4e78ca,ed19ec00,7c6c7a05,6028fae2,d8ca3f2a,d5557bdb,96e52182,83cfa76d,f9f0f83f,2619f951,a7bffb66,8cf3732e,7beb88a7), +S(7d3a1d16,66c2b5e0,4f7ed96e,3762d04,118aa293,69fcd8a9,1cd8bdd4,6e862e2e,a004e644,7b49421c,af6c82e2,1bde2b4e,84d663d1,a39ac9e8,5ba43b4d,73e7010c), +S(77069337,2c31713f,1108bca1,730e3d0f,927d0c8e,4ce7dbed,c2c02a60,b3e54d0e,a935c735,18c40ad9,5cbc8b51,9c859f7d,b48be573,cf45e6f8,cd47b8d0,1546372c), +S(ee44b4ff,e008f122,b4ce1a11,d98cc674,e340c874,f0c5c0be,8008624f,b13a937e,90e4a82a,8f002b78,7fc34998,cf015340,dd4854f0,78d87641,bfcbca47,df06a728), +S(61c0e32c,e6615b09,304ee233,90435b99,912b6de4,766e0c14,5345956f,af9e89c1,7531bfb8,414347fb,650127c6,b1f78ff7,97a092c3,2c37d358,8e612cda,9faeb851), +S(bd7026fb,b47a72ea,d28eb317,35ff8ab8,ff244b96,51fe4205,adff8247,2b9d0aaa,6dd60501,40359152,83b7a16a,3d0481e,e8c7b99e,29843068,28c41727,28f21b9f), +S(8fe350c5,b5882f87,ee976108,2ef77b55,8355e02c,9ac40ed9,76d45187,9e0fa902,21b32a84,f2f31dca,9072b843,6c21ee47,9c02c710,48642a62,2c485449,b907f6), +S(93226eea,b65a86e7,c0fedc1a,f6b038d8,7f587823,a9a2ab13,a9975ad3,ffc8bb3a,d294880e,867877d9,b5d87b20,3e7d7860,71167666,fac09b3e,9fd82033,84c4d904), +S(1fee0dd0,4dea34c7,fc6473ab,e89c2e43,215c5dda,6918e089,50d7005e,df1e21c7,dd7b1dec,b1a85eb0,69cfb830,be847f89,8012321,549e2611,92e719fc,2ace36e4), +S(e6304e92,38fedcd3,580cbe51,564589bb,18ad3cf1,3846dfe1,ba40786a,bea415ff,219302d2,53133378,ab25b331,bbfa4ec0,e88178dd,c2a39378,dee7ce64,4c8dc6af), +S(91f97b4a,11051415,7564c8ea,2a60303e,f6f5941,7cc5a556,ff244e18,444ea39a,80fc4cc,3d57cf97,6c9e7794,d89e1b33,d5849b02,72d3e544,5f73fb5,655d54a), +S(7ff60990,34769cb7,5a697d0,418ec2e2,9c5a9716,9ad6d127,ab106518,9fb7b2de,d7fcdbaa,8aa89058,e1f0cbf8,409b9879,6672b305,b6b24a61,42562de3,2b1dc49e), +S(a418647e,61276567,84939f3c,2375d1cb,82871b1,b8004a12,1cda8826,1eb5595,62797683,2528565c,78a7f4b9,d55fa782,bc97a3cc,598c7579,d48b136c,eeffc022), +S(26d408c6,39f97be2,511b4816,5e862d13,f6aa816e,1e936474,63eb47d6,eacfbd67,2e3448d7,fac889c,c9499396,c2de66b7,cddc064,186b6df6,3a6a831a,6672c34b), +S(56f12bda,d8b630c7,5ee497a4,93d48907,63eb1bd7,93d03fee,a19ff997,f42f5464,4d1a3990,7c650896,4fa7ed4,e815379,8e2adf10,80ba7246,3b4e3536,1e34c3fd), +S(e350608b,35cc41f,9fda92f9,34d16e58,c53244df,1446b03c,2e782a53,2926c9c4,b20d72bf,506c2bc0,b35e022c,c6e2bbfc,f34c71bc,a4b44a2f,317741e8,bffc1dc9), +S(5a7bd940,cc23b3e6,614c92db,a08bbc7b,63dffd6f,11117b2f,80c2fe2f,849de903,502e5557,8fcc9495,411c7d18,9979f7fe,8f4f587e,53991dfa,4ade527a,43cfcecb), +S(99ef5580,b219aa84,4cd407f7,d949c07,f7452587,bab97ac1,faf0b143,7351be63,512adebd,49f4f2aa,a26dfb8f,e5c483ba,6ed5b4ea,5d4ecb88,bb165a3e,2494faf7), +S(99c0c468,a95e76f0,37988aa4,b2ca903a,64a95b17,19f119f8,e12aadb6,5438b9ca,fdcaec6d,c390c33f,31b4074d,7e5a81fd,f2b9f8cd,b5f14957,533bd406,fc68ce33), +S(a9f80643,5f1442bb,8a14f402,6ff6ad43,4d84e34f,cd499aa,adecb2d5,125f1829,533e1697,3a3b7b4e,1e82a4e4,115f8be9,b811e787,61fb10dd,6908e0a7,aee4a7e0), +S(8ed6f9a6,2ea10768,4f90825a,e81d486e,92a9a890,78d144ed,53f54cb7,3568baaa,d99f33c3,b7311023,c4266c5d,adae7ce5,a6409fba,d3767f3d,669aacd8,230d8568), +S(84dff52e,25665e13,102e23c8,698e8990,e5d63e86,330703bb,54242843,8fc9a46f,b1bc70eb,f8ff0905,e2ba529f,1af149ea,536fceec,2a5621ab,bcf89756,ab0f69cb), +S(1bc3844d,78f82cb6,ada3b0d8,86b4f89d,1a4344ba,431070a3,3f3dbc77,2c523410,94580bbe,a198dc00,2b226e48,7a745090,ec603b3f,aa6e5847,8a8832b8,3b0fb096), +S(436e0b9e,aa94e6e,b20f58c4,678ba5fb,5e1d79ca,a7bf4179,3b91c962,325979e5,1615e98e,ce7056c0,428e55ad,f4353400,4ee4e158,347ac5f0,715b0f7f,86c17047), +S(45f8a062,4d3ba9dc,d577dee2,f5387f25,3eb3b53c,31fc6e97,836bffc6,f85b9357,b7a628b9,b9068247,d8415fcb,c5f6e6c0,e72dd75f,cb1abb62,c947cd06,5ef22ed), +S(b86ae36a,bb489583,84e95ee6,8c46c0bd,8f0110e9,98e34595,1f6e6b59,fef4e2d6,2e3ef338,ebe96f24,ac112d8c,a6803f9c,338179e8,c54420c2,981d0159,27d983ec), +S(247b2b62,79dc1d09,6085fa0a,390bc09f,2caf6d90,24f953a7,54aaa29e,a418574a,4d3fc5ab,9b3912ae,f67ff98c,2e641ba9,bc23aa8c,f60ae6d9,cd41ec93,7c4a834a), +S(737bc72c,964ee56c,822f1e31,9ad6f9f6,57785748,55689eff,492c7587,a98deae9,2aa7dfa,d4f105b8,690a507,8fe81eba,2736c301,6ea4fe62,71e47d50,18e4e01e), +S(d2ecf284,fe7663a3,810ed1da,c8533d5b,a647004a,3e22683f,78dcf0f2,1db4c5c8,2fc3895d,beca5b8e,17a2e3dc,3346b957,3eaf4457,ab0a140a,6d119304,9349df04), +S(3cac275f,98f2ef42,b0f78a1a,52218150,a18fe23d,b1361151,a3dc7477,fec811ea,a426ed39,41b7ef3e,48b0e267,fc1cbe50,4b1e5671,f4dec906,a2659792,2ccb6259), +S(f74a08a4,6fdbfa99,843c24a2,f9e5fec5,b941c29,43a25cf,131deb7f,1c3303ff,6fb92df,aafdc8ee,cd7c3416,fc89fb5a,458c2c97,84f71698,c512981d,a8edfb2a), +S(91d44932,56fd4608,48f04de7,25b3fc8c,656a38d6,f8e319f7,1ecf513,146eefcc,cf058db7,69aabd80,12ea780e,10aed66f,4bd5e356,1b0d359d,167ebb3,2830edd8), +S(d194e53c,1a2a2c80,f7bb24be,b372d751,118da62e,9901d94b,66cfd289,19387bc6,aeeb2818,d00b7307,79fc14d5,31a3d803,5e5642d3,b7335543,13c8fda4,c940b387), +S(ec18acf5,a9624f91,1273482a,b03ec7a3,345ccc2e,282a6fc1,cbf89a2a,45e798b7,ca9f64ec,caa12673,a2901fe3,684ac70f,501b4d63,601fccfb,4cb08e53,86671cfe), +S(488bc882,77874baa,6fc9edab,ee101b5e,1d082a4e,d49da47a,af5e6650,90e0566c,9487231c,3e6681ff,bbf953da,54ba603c,89a00340,c4e50c51,545a5c6d,d51b98b8), +S(25d4374a,7f1eb525,825253ef,a3ff3747,e4555f36,9fec50af,21716ae6,8a11d34,cf475aea,53df9a1,13670563,e0ade1b0,d4d90da2,11b87318,315f368c,d53c5e18), +S(5db16271,c0d7e9cb,dab1baa1,4dba4fdd,1716a7b2,8c2e07c8,186899ab,18a6418c,344f8bf6,b722e92b,ed436fcf,41be9a08,327002fc,7b3b57a9,2044800c,a0d1b2a6), +S(402bb93e,8162ae4d,f23f5d72,611eebc9,8d4c00a1,e4d8967a,da1bf524,9ad1547f,f0c0b1f5,aa183000,7a964ed9,12bacd81,9a36b55d,7d2c7c1f,12da6066,a28c1d68), +S(87b76fd2,91fd3508,52544b80,85b07b94,20fc325f,a0ecf42d,9354df82,467d836e,f0a2c79f,4613218a,3b35cbf4,24b5fea1,7d2ee9c7,ab912be7,62270195,8b70c133), +S(e2d73ca3,ffca1eb4,191eb705,c22cfeeb,a7f573f8,463a0cc1,c73bcaf1,3cf6c791,61b861e2,5aa3711a,b92aa74c,814b4df8,37172f43,ea0da2ac,d81ae961,1735fa85), +S(1e59b370,be38e5d6,4f8b6fdf,7c2351af,75ff9d32,1f583d58,bcd0e8be,ee0855fb,d166688f,24b4b33e,b171343a,87bf8828,5cd5d073,a5023bfa,dc542660,70d3cf13), +S(52ef3e6f,5aecda7e,e2a6451a,ec2badeb,235829de,b7cf6e1c,5a6970ae,662e2078,533ca8b5,8d9e2e7c,2a992a22,3f385846,748a1686,34e1fb2a,48d3f133,8512bb08), +S(a4b1cd10,20a321cb,53717818,ad0d39fb,5e9524db,4456e0c8,eab045e5,b2a97be7,979d9ed3,4601d962,3f084e04,9ce4683d,783b912e,6a92c07a,38ae744e,fa7d046f), +S(bb01149c,2352baba,8f3fcca6,a8fdf9da,854d7,7efebf92,6a0d49e,abcfd871,b186fcef,1d368ceb,351d5e35,35d19052,7373a9,36a625c4,c0b3cd21,d4188720), +S(978e8fe7,c4088cb1,27f9e8d7,5dc43453,ed16470f,4f940413,eb800ec1,b315f269,6f7f521b,1493b81e,6f099fb7,22ae2a65,f706a351,2b74338d,b708bfa6,4a34f6e5), +S(7e61704c,77e4a6f6,925a1c48,8965a72f,7bc8e76d,cf316371,13f682,b5fbc0ca,da66aaa2,c39dd05f,7f5803bd,e5bfa0a4,21eb628a,12df0869,6c6614f0,176b15bb), +S(87c537a9,b97dc885,3b7957b8,2cd9ec81,b8b65d58,47a23106,e6df3d5a,cac3fccf,4939698a,6123ae1c,42cc6ff1,fd006fa3,2cb0a5da,a3889721,f04a4a59,e0fd7dde), +S(590b5b95,37a08784,f804111d,6ccd7df1,7bd317ef,aebd7bdc,96f3df4c,aa8ad437,7aaf5053,1c187684,ed8238af,c621e151,dd6e7c6a,2c18bdc8,9914a1f6,cfde5e29), +S(913a2ff7,a9416e56,afde1c6c,6273d7df,150deb4b,f2db3f3a,7ff7fa8c,173ccc09,e865c6d1,33da3db7,2dda798,9a5b860d,671c9de9,d6132784,30b5a552,85a9854f), +S(b01fa220,1ba66785,aaff5f59,347586e,162ccb08,ca58179d,5dccaeb7,636b4db3,d5589b8f,2ba1ef60,23936d96,f2772d4d,cfad1f26,cf124265,6765dc2b,7d9f543a), +S(511fc077,bed929a0,249c65d1,3f59c607,b8bd0279,c3ffa23e,8c6c4ab1,800b6363,74b03bef,b913cf04,f44fe5ed,40ff2ff5,9e85db23,34ba902d,84dad90b,68a72912), +S(d8597fba,dd03e235,defd0d4f,72c054ba,880390aa,c1c356c9,1eee50f7,8ba567b5,86bfd1e7,f1df87e4,be26c892,d2c1a634,1904c414,bf84dc81,d65f701,efe90bc1), +S(34b46527,86464956,6dfcf2e3,5717955e,4529f88d,786ed832,f879bb9b,5f24ad6,916bacd4,52fb69a,e8f20094,8846e706,e3cf466c,a34a7c6,b9a24df1,1d48edac), +S(f68965c5,55a826be,187306c3,8695dbcf,370c5fd9,1a018912,ca143d8f,b9e96c07,2342eb5a,bea7b80c,837a18c7,ed606930,248ba6d4,f5ea3650,9a3aa10b,c0326dbc), +S(80bab356,e346b2b0,511775f4,be1a7bb3,fba9c65f,5cd035e,b9300162,547e75c0,e96dd58a,53a9e313,2c3b494f,2c53bb56,da17f573,8bc90a10,58063906,52c33363), +S(55a3ac1d,88f00e04,ec95215b,68f37594,9e10abb,ebb1928c,6cea668e,62897e7b,31b5984c,4280d3ed,125d2223,57718f54,b8e406d0,bf4feccf,2deba94d,45cfd5bf), +S(7e0e03c3,f82556f5,a85322ad,61cc60b5,d096c684,19c76b77,f328f51c,bc5daa41,36b4f520,f84f8e1,7fc79bec,bc2d4340,e77c5b0e,4fa944b,c0cb2f07,4c5bb1ce), +S(fbe1fd76,8dab92ec,b56819c8,901cb8e8,cabbd809,f61c0f83,70fc5697,7a90b28f,6fdb62b,d011208e,aca8f8bd,68ef539d,a6a5552b,8187327c,19c6f4a5,40b1e750), +S(ef2a9571,ba9090ec,1c50d5e5,d8955609,2f7e7610,625860d3,c0e1f22d,e66e7a0f,5ae0a396,d6cfe9eb,7e3e6923,e7d1d925,851fa4b1,38217320,92191366,a3aa1c27), +S(81652fcb,7a968f46,a38a6b9a,f3f6d831,577fd45,dbe0cd75,ca4ae8d3,c34812dc,bb130db,74334258,e5dff98c,cf8e72b9,95b986f3,7177c98b,ae6f7747,3d869e17), +S(e0daf5e0,a32eb5ea,606b2760,62c8a60c,a4b476ab,b5f2b172,9a15c529,11509e75,8eecb80f,c47d33de,c036c661,e940aa9d,26bc8541,369315b9,b7552487,d32e0f4c), +S(cf0a6b13,f6ea26b3,8927139f,1c5fe769,6f297e00,46e4f529,1c4d5c60,57dc917d,b8c731e7,5d0dda67,63c1cec9,b70cc4a7,e39a7ca3,c1dfe8c8,4a895d03,b3b185ab), +S(a5b5cf9b,35914a4b,6af16c2a,ffb6bc8b,5228ac11,ea91da48,fca654dc,b6b8bcae,e6fa217a,42e72a81,b8f564fd,a5438d3c,5d0ce8f3,71b1d6d7,c577d70e,f0daaae3), +S(d4c1d178,b462e260,c6b7eb43,b71dfa56,899fe5d9,a421da4a,edded57d,4a0010bf,339fe1d4,83f047e2,cf2cc9d3,bcdb8f0a,df9b491c,ac87a512,e901586a,50f35276), +S(3d343aa3,c6bfd408,1b64d616,2523b272,ae207a5e,bec0e530,4e0792ea,3743b150,5dae9987,49073817,cc513c16,382edfe5,749a8dcc,62f4dba1,3e0c88eb,c978abfc), +S(34242394,db9874c7,14664ff2,90cb1be9,c48c1746,d53aeba1,536fae00,7ed83a4d,59203b4,b8b3e0d,9c34790f,f9cd0716,8606cade,9af8ca2f,b77a6fae,d6e10ae), +S(aa8c1b42,7588ce4a,2a0fb437,25a27bd6,6f598323,fd525e88,a3a586e0,d2d64a08,2f1dcc5c,269065c7,a966036e,c281d05,39d4cc40,fe42fc37,667a49e8,850fcc00), +S(699d3ea,9658f9e9,7fc0b69,4927f4a0,bd95dec3,cf104144,8167e4b,50482c74,416ac99,d59c046f,a754a7ba,d37b474b,ae7d2192,f90719e1,39b6af6a,e2b2fc84), +S(1cd6ac9b,93f5b488,5c06c9d7,a44ea260,11c9537f,d75f5abf,e9d7ced6,c14a994e,818a63b3,d367f655,4afc7651,7fc85fdf,3c69b881,242eadb5,8649ce89,f1905e00), +S(297c80bf,24a78c2a,245008bf,40a828a8,575e6362,5c555653,980f8313,6ccfd660,5ccb3479,60c1c639,60da5605,4bfd8d5b,61ee83aa,d815164a,b387dc37,a44b412d), +S(915638c5,f9d1b491,99f6ea3e,c1843d4,33b832cb,fad78dc6,ad55fd10,9eaf31d3,bd097f22,440a0c35,e5648ff7,724fe5,2163edd4,3c1b2fd2,7c49d61c,7194f225), +S(f8274560,da2fd048,5b974537,16844970,d1c0c1e0,ab450703,739aebe1,28a7788,58c71185,2a63aac9,5a080ac1,3d786a6d,75488625,622afdcc,f5344ab2,adea04fd), +S(94b4e84c,61fa07a8,6c35d554,816f2131,3727f614,d641f3e9,8ff74509,fcfd444a,9a30a0fa,30f3a772,747e3a0e,b0d17ad1,c029558b,a5e0478c,160c109,fd43df77), +S(de72f827,3ecfa2ce,67d55302,9f242afb,c3ac130c,4e711a41,545edb3c,dcb90d64,3b64bab4,4141392b,76e492e1,49c166db,272e23b8,dbf3fb13,b17396bf,1c3834b3), +S(6e7b3c5f,4bf9bd45,1c5b25d9,23fb5768,7aa2b1be,dbfa3317,db823b8b,968263fd,5f7c0be4,ba960cad,e120bde3,c8ab685f,e80f96d1,5a012993,d1890b89,563cd7d8), +S(3e4c6252,307c116c,33f5e2db,5690dc4c,57210b58,3b2250e6,ace138a5,24a1b376,e82d521f,4b50a3e7,482ebd30,93f7ed8d,70c6dd1e,6339af4,7ef453cd,ba3a91a), +S(99a27d9c,802a5519,3f9b767c,3d9c04b3,7c6445b8,e49887b2,55bf325c,118bd175,2cba1615,5809eb23,8e8a35f8,7d80c011,2b0b1587,1e56c567,26dbe6c6,d9a477a1), +S(24b5cc41,130a9fc0,d694c99c,a00edba7,2c8d2a94,7db35421,6ac18ee9,6a88e99b,d409cef3,7e0fda7f,27478fa0,651ac750,bab44341,98d60fb0,50db541d,f416c488), +S(903e8ceb,229db84f,803346f6,9db1b473,4d375dad,b29ee771,c194c1c9,4f068066,405c25cb,2ce89007,bac620bd,1e7bb959,c61fb5f5,cb60bec2,15a978c2,91c63aad), +S(77702bf1,2ddf612,5d3803c7,19be7b60,c4dfc0a,54bfb54b,c58d2595,230e92f,dfd2bbd0,8cb1b67,f26bc57d,2b9bfaa4,7a03872,2011c58b,619794b4,c0bf5eb9), +S(27aee8e5,3f4ba917,29f463a0,888834ec,e83a022,bc9862fa,fc5ecfe1,d082fb41,1be8786f,2ef69516,e18131be,28cfb9b2,ec0ff57,6dc75c84,5f2a7080,94b40bfa), +S(ef967d14,d819d4e5,5324496e,868c3167,b94393ab,e3382466,44fd2b59,efccaabd,98858ad2,fe5db334,740a3bf5,fec4bad1,96d39e5a,f09209e8,95e086f5,8a252975), +S(a2228f83,18c5fc47,1536bbb8,9baf820c,8b2b48bb,8ffbd4d5,56ae162d,bb80a78e,79e06c54,ae0030f3,a6275aa9,8897e7e2,637ed005,c6aadb63,33575232,b54b2bff), +S(5ef437b0,d9a17584,6bb1e711,7b7fa86b,504385fd,307bcaa7,ab558ab3,d2bc5707,5aeb2e4f,83a73719,e1268a48,6a578d84,3104f0c6,86749b59,7c4b3fee,8ae5b586), +S(35be1b54,47f8a2a,512deda4,31958c11,9b187997,66eed6d9,d30040e4,363274dd,6539313a,1d5328c7,bb389c47,98c08c05,f9412c1b,31c08509,3af720cf,6c604288), +S(4e548261,89c3c699,eeee1560,b9876e4e,5e0c8677,f849a9f,e2355d2d,aff7aff0,49bbccfa,2a7078db,d032fd27,98a701c1,c8947c0c,fecfc1a1,38dfa387,4ab436c8), +S(37d9ca55,6ce9a853,b79fc831,69b6778a,43737dff,f5eda67e,eba8f267,867018c,9a9ca2dc,2512c397,a16780f2,25686b51,7c40d90d,d97a8077,91be382e,86378d10), +S(ad37553e,383b985,a4054cc8,a909af65,5daa7957,c380be16,aed94ab6,407ad12e,98e09fca,76eca761,9e3905c8,ef688726,feb7891b,3695d06b,5af5aa3f,f92dac3a), +S(55b0a9fd,7dee7ff9,84cadfd2,fafa3f5e,30cc6fd3,72597902,c8cb9163,55e2a0d5,97da1eeb,96599624,39eec4f0,7fe182a2,cfef4a9e,55a21b1d,64a43a8a,8edbfbed), +S(c79778d6,64e3f159,5c9ab43e,3930b722,f734079c,eb131b50,badaa53,337669e0,1dc01b47,e9908908,d318e947,8cec0a8c,37f7427c,bef205f7,9000617c,ea33c723), +S(ce6964a0,b5fa0b4a,67385884,12d6ed28,75da7d26,dccaac81,7f3aad1d,4a9500c4,faad869b,e4e0262f,fd67cc01,a0523f98,d15d9cbb,7bf7e8f3,fce7e20,26b7f765), +S(70f8af3c,f7fea8de,e62a3ec4,770828f0,52f819ca,e031c9c9,a0706d0d,b4d5751a,b4c4a600,6e4f831e,c4bd750d,62a52d0d,57399b71,ccb71f6d,c00287b1,67a1dfd2), +S(11f0d683,9f28915e,24d941e3,7cca8754,bab9a8f4,96807679,89300b02,8e79a041,1adad681,9d726c2e,2bec5f69,75ad8a4f,c7209872,35ea7486,2ff38333,2335a647), +S(36a0d630,625c455,5c8b711f,a28e2d0a,4ea34f6b,c81ac8a2,6861d58f,ac3bc9c0,89c1e59a,fab4fd9e,3245ba79,876404f,b4cdc7a6,2a9a90a,f307a8b3,17453467), +S(791e10ba,970b964e,db48c4c,fe698317,fcb64bf3,db8418e4,86c45e6a,fb0e1819,e9ee5073,73d105c6,b7012ee0,ba60b9f5,89d98773,f0bcea03,14d6f707,7746669f), +S(cfb370,cb6de70c,58c40464,c20c1cdb,9850be9f,ad9a4af4,2bbeb6b9,f173725,3f5bef6c,814390a6,c99037da,eb7fa919,7e9c806,50efc919,6650a42f,ae425619), +S(1d5b7762,bfc3fe49,bcbc3176,158f186c,f909c04a,31480b17,2451acd2,8024321d,ad60b8cf,215cdfb6,62a29985,c9f185c2,19936929,b9cc5911,4cf5329c,44ba080b), +S(304bcf43,342c9d7f,fa8e05c,66cd140a,57c4f58,d223a1e2,6b93a374,7c73882d,e250d896,acc87906,b79d9ca9,63246ce1,9ddd44fc,4e834643,f2d592ae,219f9767), +S(60bc17e6,9cebe27b,b504d28a,b657064,3bafd4b4,2d82e3a5,77dc8c5f,4a05c4ce,e45ae47f,6088f05e,f6709166,9f608598,ecca924d,ae7ad37c,1852009f,e23912a1), +S(cfa64de9,ee4a849a,de71b1b4,340b8d18,1341d00f,e86bca01,3d62d800,3e20454d,2e72bcaa,1967c37f,a8f8ec78,b82b5f6d,3c7d0136,28bca50f,c884825a,6c967e92), +S(400e67b0,bbefc4f0,7aeaee57,1c495584,de4e7832,377bf171,ee3e38a2,69e53d73,762d4b13,f91d4e40,ba0a3fbe,3c085922,3386add9,b8b1c432,88052b9e,cdb8fa3b), +S(fd3ebc1,e1c751dc,7f897ec1,f0ae0817,22136109,11010904,6c105497,47602cde,43699e3,74af29c9,692fed1b,acfe00c4,f2d91908,eb7cc181,7c270c76,453343ae), +S(60a18f0,740f1caa,ea056b17,9808ddc4,aedac1f8,482bfeb6,a97516e5,d84c0a30,6efbcdd8,114ddc58,cfc193c7,f11ce4f0,931b3f56,4290253e,a5289d25,7e7d1350), +S(c08a77f2,b9bfe746,ef89631e,1bbe07b8,5007d1eb,bb18547,6d7f8f49,4283e1c5,6a94da87,4c350d0b,cc23ac89,9d342752,97421c77,d7b7293d,669cace8,78121770), +S(247f8ba7,b8cbaf03,2358985d,955b4ae5,673622fb,ce1b68c,877db077,d91fa63,a180777e,3b8b7d6f,733d0565,b038b345,d598a9eb,1d592949,8463940e,99f7d74b), +S(18b7101d,a65cface,68d7ecea,5b926eaf,79722f9d,5962a86d,e1eed6be,ca08e4fc,60b7377d,eb39da03,f5bad331,f41586bc,6e3bfff9,f7c9eb7f,aae6f7df,8869f7da), +S(4f6bc39b,33d45e5,325116d6,f8eeb341,d15a3f40,57b64775,932f9b11,a92e1959,1cab1c18,422dc38a,e1a8d4d4,ecc84748,4c47d862,42ee4dfd,28624a72,bf693433), +S(45ce69b1,cdd90a2c,a14a2f87,b12d1f8a,7425935e,2f2ecd5e,6f25b087,acc4ff2b,3f850036,ead34b81,3eeffba6,c3b9dc77,8675152d,f569bc28,d4e74539,896f4b34), +S(8ef39f34,27339934,a1b969f5,b203d187,2d3c467b,1a25ca0b,d59b385f,d78d0cde,926604a6,8f82a4e7,a7e5507c,e1f1730d,c43f9a10,bb15bc15,9d8b940a,7403a5b5), +S(cd83545b,fd621045,245390b0,938c12ed,d530949f,6ebf0e5e,90ca8617,637d2cdb,ec79aec2,77d9b2a6,1721b499,ecde68f1,44faf32a,7984550f,54fe9208,517a0dc9), +S(95482d05,3fd19bfd,20a218d,82442cca,89d2f1fd,883300fe,9898e7af,3e1e7c3f,233aad3d,c798660,1aaa61ce,ecfdc48e,9b3e09d0,76a14945,eaec9d67,60713743), +S(f96fbc5f,eef4ffcc,d5c8ce74,a390858c,24cdb060,529974f6,fb7a7afc,759d7684,d41bbd7f,54c6ba72,aa64996,dc8237a1,27d767f8,ae4ada04,26879426,6343d663), +S(c31f5733,a92bc02f,28aa1abe,6dbc932,96ef1980,a8b876b4,941aa05f,3e4415ca,cbb9afbc,166505de,b160f3a3,fbc99c6,8b9aa548,ba80b83b,e70700ab,611d6bed), +S(e710e709,b2d1abaa,ea81e54d,4c913029,61d058d3,4aaa329d,bf673da7,6cc50f87,e6078cc9,c093a8c4,804ade7e,a2bd8f74,78b93dfe,47cadcdb,18be11b,dd450acc), +S(3209825e,8e6a7a03,cbb96e9a,cec60e29,fb3d2113,310a5f27,69c789d6,fd2d0ea4,4a1b86bd,fa71c5ee,fb640c0d,2fdf6941,42790350,a48b7189,41cded36,e6627117), +S(d26aa999,c82be0b4,25268242,c969c812,7160c34,8d61060d,2cd95fda,4ad91572,193c9343,5ad89189,37df995,5b8ea66a,5f81fd49,aa463d63,bea7e793,d7867078), +S(f505f201,a5f0a8b5,420db5be,304e3824,5552efc,d7736f27,a70d63e0,846f7a05,affbf297,4fd36a6d,45cd403d,e620fd5c,24ee5094,82f03dbd,4ae8d1e2,8047e07), +S(e81d7da0,665574cc,11b5c7b7,c7d49ea0,e12e5a31,d8d4059d,e589c87f,8ca189de,cd36628e,f84c929f,bd057c9e,9c429e0a,28562415,7a1f718c,5f6d9c6b,2402a25f), +S(d183676d,573926af,6b409350,fcec841a,9d7450fb,2c122dee,dc7f061,8ee870f,4401a6cc,1b298b4b,b7069ca0,70452571,1406bdfb,8d991e0c,a252461c,155a37dc), +S(7d8eb701,a4555db0,e28755cd,b99ec00b,188a5fd5,aba9fd63,b0fe59a2,e5f69621,26dfe0ea,387948f4,320a99b1,79cbab72,e0e7b4d,dd91023e,3ada4706,b1e14de1), +S(62b18c1e,6b41494d,242c807f,aea4cb90,6c369829,bd480aa1,51d42ad6,f2ab6e16,806a683c,ca4ba62c,d0d7210a,2a642a97,11a2c336,2cbbdd40,a14c49dd,7445157c), +S(3beffdc1,3d43053,e4975be1,2212ef06,756e420b,28c1da19,7f719140,40754d83,19f74783,30213117,c1cdb3fb,c500423,14c36c4,bb0b6073,504e29d3,2a7a81e2), +S(883c1fc,6c1e9ab1,f8728eb6,7e3c820b,bce57c8e,78920acd,88c56b69,8e21b57b,a6ee80db,2f153833,f397e1e9,f7d0bd3,b68e3a9f,a83fc262,88a3460,241f30ff), +S(cb54c3f1,d3007e9c,a6f4c7de,7cd6e728,22ed6627,3d64251d,23df0352,ca7f3f56,aee4eed6,3bde44e9,132e8405,c088e412,c8dd4856,9be5a980,adf9969,261282c), +S(40b26863,67d38ed4,ec41c0f0,b8393698,969c98e,e3233fbb,b2c9fee6,14fc52b2,9f3c3a8,44703528,e8a3d025,d536832f,f17e0988,4e90a75b,82705e61,c5b4f811), +S(90431e86,74d9685e,4c91e51a,a897fd1,b5aee499,7a8c7405,508d77a7,d0d742ca,b35bc817,b63059ca,8c21e0b6,f3c198b5,ad7f19d3,7711d02f,4695712b,e8706df5), +S(5ad701b,3bc26c4f,cdcd7882,71d259d8,1d134c0c,53063b21,c740d7d9,9c235474,615f2956,b5056865,3103ab4f,d53a1e00,49bce03,db115d5e,8dd36c11,1615f997), +S(75a3782c,51dbe62a,f9da5199,17e3a59e,b04511d9,f11b7312,7dd35b8e,6da95cd2,38061610,c0052d14,bfc4ef8,62d92a5,d59bca62,9fb7a240,299ab954,8ae21484), +S(28e60b08,2edec9a6,1fdabde1,b65c2e0a,333b5b2f,2c8cb97a,fc20ccf9,13792765,c96cac7f,4efb4633,8d63ddd5,33968f6,d09f074f,28e3c57e,dc868e7b,df4105b6), +S(7dc515d7,f7f20959,7e52b182,97b5933b,2ef9ef30,38e18236,39f6ac5d,214762e8,37738e78,9222d0d,5d7e7979,19b0ce29,81b7be24,abd4e0f0,8b989500,a348218c), +S(a8ad8d74,cf467d29,a97690b0,a1c539c9,604e5bb,77d4f719,fe1b7507,d51215d9,4180c361,21659aa3,fa84ca98,8676b3c9,23639184,ee991576,3ab9878b,558fba54), +S(6a71e2e7,99f1c56c,e38052c5,767ecb1f,85c2abb0,55832994,18417a12,9bae566e,481b3cce,208f33c6,6d4181e5,7648061a,86246ccd,31f92eaa,6200591c,1662b7cd), +S(78d0ae79,7a94ae5c,b338574c,1bb635bb,3207b491,fa42e6fb,7c861eba,ddc195dd,1d9e9cff,32ebca9f,d707544f,ead5363f,15a9af8c,e11d8036,49c6fd8f,cca067d), +S(1feb4e2c,357837d3,8ed62d33,4cba95c3,54ab6bf7,2d9f1007,b7419ecd,6bffb072,8e096dfe,15e187e3,92c4a26,2b94d5cb,63fc4cdf,f14e1b76,33d40946,ab074a45), +S(e9a3ce53,cb11bdd0,6c0be1e0,848b94e7,ef68d881,88069893,2facab4b,d19b2344,878838a3,d85a38a5,60a45847,20d8ea0a,34cfe7c1,6b65f35a,60b766f,d77d5fae), +S(2043c86c,4c96437f,f96ce0fe,ab5f428f,76966c30,4dbe6637,397d6b35,730e73d6,82eae267,3e2fc564,c128723a,b74feabf,905218a6,6567ea0a,4cfa74ec,5ee7d22d), +S(d02b8896,63ada221,3e6b458,7bbaec0a,2b1cd8b3,40a815e,fd9f3e36,c782727,c5c4cd5a,4bbcf08b,e1b8620e,24930490,c9f0d61f,66ef0c2a,937e2077,b178f8c4), +S(345b51da,c452419b,6cc320ae,8222c72b,12073fc5,a77ea07f,fffc10d8,61482094,5a0406fd,42916840,8fe4c276,bae94cb,710f6cbb,994da133,932c9d7,cc73242d), +S(275d0e66,da342f04,c9cbd00,18219dee,1a42f9fa,418d0a55,3f98b88d,ef845ce3,3fc25f10,74ad90e0,4ff09d42,204eda1e,a63fa50c,152cea14,d322ae5c,2c4f6dd0), +S(64709e5b,8c4eeeef,9b92177a,b4a04de5,f0150612,c84657ab,855d0145,ecb3aaf,c3b0e1c,56a5a00d,868f2a1e,35a40b0a,9d6b55d8,2df87d15,95b1890b,8b9a3a94), +S(64bb29f9,5e7f48fc,d436891,8d527785,2ba8a6bc,f2e1df43,f7dc4123,ae2b3be1,1f4a8fec,eba87217,3cf8bba3,bd19598a,ea1c8998,945f5b32,f1f52d00,8ed1355b), +S(6f401b0,2e10c301,27dcfc91,2e3a3396,93e8d2,f392507c,338dc113,d019e520,d9a59488,ea1e613a,99bfe1d9,dbd36a1c,3b65ff90,fe8983ce,9665ccbe,1108073), +S(3af33a8b,63b062d5,30b7ed95,c9d279c3,7be8e95e,6e173411,9d354814,b361abcc,4a5f16b0,b6ac8371,b2674adb,933a7f62,d22c6133,1ccab67,e6abbff8,66124fae), +S(a3feef6a,34754c7c,d888e898,bfe5080d,e3669502,d5ec3fbd,ecfb2dfb,8853fe54,a3e7e218,6d88e82,f600be21,5ea5bb93,44a6e10c,464e5f7f,e1ea24a0,3eafdcfe), +S(2e6f36d8,910a303f,c4c93cf,660c31a7,ae7b2ef6,c2ab5cb,940f9623,e2de83ec,3ca98ac7,a03b0b11,1104bc99,d693d068,7350c4bf,f911c183,1848bdd5,bf35e66e), +S(5d7cbc21,3016b19b,2dde662b,a677902f,cfdcb91e,25dd62ea,583b6375,1cdb5aee,871c5aa0,d44c404f,b42badbe,a9b99a43,29db7694,47b93d92,bf5dfdb2,648f4677), +S(383c7ab9,6e772e7e,47b01559,ee3bd4ce,9b86b38,a6f57968,64e45eb7,112fa1fd,254fea35,3ab6bfa5,2018668d,9f3cf2ba,bdb4aa59,28bd6a07,852c4b4a,b9bbda6c), +S(96aafbb4,1d6c96d8,72a6a577,13b25b75,814966c,ec1f0162,31b74dd1,46322ce3,bdf9a817,4c367d1c,51d4be31,70cdee51,a937445e,f19c1c10,52da1f67,e9e9561e), +S(4700205b,e431bf70,6728bf7d,16172589,7d104107,5153a9d8,7796bc96,49d479a8,4117c528,9d404239,97f67970,65d3a9dc,6b3f8c13,1008489e,6b23a631,6f86551c), +S(f81281d6,7377a69b,5ee7c680,744ea61a,668eb128,dc404955,f541b0c,e414b37d,e54bd7b6,783b6888,4bc72551,1e97c5eb,ccef5049,a28fa13a,a15232da,eed7e23e), +S(d898d15c,276b3b92,77f39c23,93f60540,6a7e201,443cce6f,d873d8a1,44eb5a,5785dd47,80f67f3a,7efab06c,bbb1044f,98d4425b,b0f1cc99,3b6b4b2a,a5504d4f), +S(56297c68,51dff96c,6122ae9a,1cdd2ce4,b1aef6ed,884e5998,28c77de5,eeef72d6,4f2494f6,5ebbf2ea,acf70249,f543c97b,add6f6ba,3b152b22,2b371a83,2f8664e3), +S(1adf1f2c,a5f3c153,ce8a6dfc,c1a5a21b,d98b99e2,135b6e8b,494c6ba3,2703822f,13fc7044,cf6c75be,ed84aa6,bb1fe11a,9f36c562,5a152c6d,81b373c0,42bb99a3), +S(f42c77d3,b6b36250,bf4f535f,27c00c8d,61b5ed76,d4928138,cc0e672a,7c72851c,3700f507,c90c93c,6fa6648b,40df90e9,b3292356,4a9bd471,4cc310f,e48da924), +S(17aee799,938d30d3,7edb6b8c,19d4d0ad,86ecdc34,c4b7d504,9d2b3b9,3e10cbf9,2527fb75,a787f794,a5f06a55,c3b33f7b,c575948a,c5454bdc,c14c598f,34459647), +S(55acc75,4a188608,46ffc6d,a6e3e2e1,18cad61d,e508d333,784fc716,555c98e2,982a4306,65448652,14f42c31,18e3214e,3981529c,422a0c76,d30d45d4,777aa87c), +S(d06c7e99,dbaf0943,6a6790be,e7487614,95ace755,448580d2,7614a30f,9bb7b5f,a6958136,41f3025d,de7ffc89,689b385b,b3c6ab83,6b1f21a,28e492f,de7a6fa5), +S(905423fa,3f9bd590,1a502d2c,7d4ac0d,2f728dac,3199db44,b35362eb,c964c8b6,1c33ef01,ffd75d94,bdd523f0,a41d629d,bb5ccf7c,9305d309,b3ab0842,16cc81ed), +S(8e799bdc,f32e5256,218dfaf8,5d08b6e4,d083975e,5ff2059f,c5b57966,3dc8cbad,60d46f36,c0e04600,bee76037,3af3196b,78b0957d,7cda51db,f1ff0c8e,fe6454ad), +S(653174f,8da924ee,322a18cc,8dc1e89,2ebfd90,dd1ddb95,6cf0646b,1e87ffb5,ace4b278,27361b77,59031384,57d0df70,9756272e,2f9af74f,55651c40,db5c4cf5), +S(77569132,e25d0051,b81f7692,d46faa9a,640e7d67,30cbb6b8,60078810,5267336c,15b2a80f,d78fd28c,d65d1e4e,4e81ef8c,37c8ae46,e66ea794,b60a0e87,f8203d53), +S(ec162da5,7ea2e308,183ce06e,d2fbff2b,3ec6e70f,e9d8ee2e,a4861160,205e506e,597cd367,d22409f5,b5737cd2,f1878b7d,c5d73603,3470839f,daf2d0a2,1b1a6424), +S(dd4a71b1,70f06062,b476aa37,aa025299,3d6d5020,a30f56df,6f31bf64,5633c6cd,ee4544c7,866617b1,584ce6bb,78627918,7222b0be,77d7ec4b,21e842e9,32c8ed30), +S(39ea945b,1d56a29,bab310a1,194f2e20,e13af9ba,5e37cd5e,d24c7203,9f4805fb,b29aebd6,9849c35,9dad83fb,56774bd8,3628f423,b724efea,80f778a8,370240bc), +S(bc774075,cd344d6d,a2f00112,3201bad3,bc52199c,b099441e,1d2beffd,16c13ae6,9e2d4f9f,2e019b0c,d3a8f248,31780f74,16569a42,58ac8f07,9945e179,c087959e), +S(de53be6a,6ee4fda9,ff2f399b,ae8b36b,b8331c83,c76756d2,3ef734da,57c60246,335c66f3,7472e014,3831d92c,bbbbc826,9046105d,64bde79e,108e09d6,b3f6f23c), +S(6cea6faa,a27557d9,d4561e57,ea755ee3,3d9f6905,36f91ed6,da93267a,fe758b88,e187e21f,4b67e4ff,7a285d97,1d42080,12638b5,ff88d4f2,ffd5cafb,6860a928), +S(fb5f6a80,5875c22,f2b4dac3,9c0a6f05,849fe524,586860c0,c3f9ca19,8091045c,6bbc77a1,f95ffef4,2105ed15,1ba96fa9,688e9e,cbdeaef6,81394b61,a4cf8f1b), +S(79a6afb,7ab3b569,e913cf30,72ec03ba,82c4aa4f,6f90be32,354286cf,52350b8a,32bbd09c,7e512933,eae14a47,fb940fd4,c60c3cc,c27b26b4,4588b278,6eaed993), +S(bacd7215,27863177,9a1878bd,800dfc59,95041824,3bbd492f,98ece53c,454f8613,f6ccba02,47279a13,371077d9,9d8e5e19,6e0c8f28,ee4ff9c5,21f2e928,c8a8dc1e), +S(15820a62,6c489416,14856974,18ebfae6,a7148dfa,895caa28,691bc056,c0e6bd52,14de4c03,8ebb058c,51b82407,1c58cac6,1bf4d105,e2f1bd77,419aa4dd,168d57bf), +S(9bf21f25,14f78ce3,5bf4ee31,334882ea,74106a98,bc5f1a56,d7de831d,8fc007ad,66962819,7a38b3d7,9af6dea6,e4d0f9a5,c03cc43,20742d2,83cb6573,7972622a), +S(b4c70aee,a8a836bd,cb3ff409,d0ef44a1,ee4bbc17,e93d233d,f4fbb081,3883c0db,48f35a4f,c9a9deb9,a454cef0,c0a2fe75,fa23ddb1,d1a2ec6e,2f16aa92,59bad8b4), +S(56d682aa,9381f1ae,4f356230,1f2f6bd7,e39f3e1a,1ec7eaf8,4894bdd9,78489b47,6c95eb11,4fc24964,b9bbe344,bdc32627,ccf1e6b2,b7ce8ba,e466c728,d348efbf), +S(7c7a9846,11fbd84a,9962cdea,1aea4ef,3572d15a,99b1f3dd,7676974e,f797b377,c1372815,d6ace43d,139a57b1,d37937a6,2f0b56f8,bb24b48e,a42aeed0,1715c7fc), +S(a89c7e,16838239,fdb87872,6c107176,7befb82f,ecb9e14,5768bab4,b823e2fa,957df64f,eba5b191,b6ef724c,18a1c874,75728177,682311ec,d709cf65,5ed37dc3), +S(7fac1495,4974d3d7,ac54034a,b497ff66,3f6cb327,506cb906,b0fd3028,f85d3dbc,a5c140ad,9a1bfaf1,ea578aa1,b14ca9fd,49473ad6,32300652,1f7e434a,dc45c4d1), +S(1e3032ae,8406cbda,e7bde21f,44a6ed5e,feb5787c,18c1ed16,1892c24,45294cf,a73be032,b2e98fa2,5fe054b5,d6d30081,b6b331b1,80124e8d,d85e2fa4,c69666ea), +S(abe408a9,5079597,bb9ab65c,852a985d,65391aa,7de247cd,76b44a02,67691d7d,1df3e191,219619ac,79bd7808,b5166a62,29babd11,e287989,65e15651,8472e8ba), +S(45ace807,55779736,65e5235,1133622,9bb6d606,6b5f09f0,76f5f984,51322f4,da7668a8,b0906440,ab68c7dc,41602d25,4bc05a78,f5a4320b,1775331c,537f3d87), +S(2ddf9c36,4dd4a1cc,c3582ed1,e44c0b21,1644c44,525f9641,c726afb5,af481780,cc3f4d02,36cdea64,cb350d0b,9c44d223,ebed2cb3,a66f44df,5e296ab6,41b61679), +S(41818580,a97d4a79,f6952aa7,db37d288,a40bf8e2,5328201c,284130f1,216868dc,4d6212b,47944485,c4e2c4ef,b556b856,2de81a46,89f0401b,2d7ac123,fc83913a), +S(905ac526,b7aa8986,1b2cd233,16455338,fb0310b1,adabeea3,a8e66fb0,5d2b7c50,f166e203,33ce73bc,df2ae289,9aab8004,568f3af6,381f0914,1d980155,7674d7aa), +S(89b95280,7022c368,d05f2fd3,10a13a24,1436909a,6695c999,f448b2ea,2be1c642,8d450758,5f2ff980,3a74f447,8a403ac,60c4c28d,54a77556,89748c58,f1efd1fd), +S(d4ab0d06,df52b5d8,9cbf1c74,9d25ac32,9abdc525,1d260933,490a45a8,bd5b0eb9,f5991ea3,6906dbda,efd4c6ad,6cd36380,9b978396,765c5ffd,f538091b,b25bf652), +S(aa3327dc,8c9232f0,48c14e27,fd235a6,58db506e,7de5e2bf,33edde07,38109ed,9dbaebe5,644b9728,23539091,56551b3c,540d9c85,3fda5bde,725fb89,d6bba192), +S(2d4b4ef0,3699faa3,a519a0a,72ea3ba1,d2f43f0a,c22a13e9,3fef213f,48b1773d,e6720da0,40eb745e,f99124f6,dce35709,2048462c,5623ccd9,f58fb739,e2314fcd), +S(fdb1cc8f,966c7bc6,8d264c56,8066a106,b102c741,11e40514,a2521dc5,5ecd5035,541b7302,a6e38776,30b178b4,b692ae76,3d59b5c5,cf5e5bfe,6427de67,c271dc27), +S(9a711c07,1b47a858,230c5111,5622f83,44808f0c,ed08c7ba,95170a83,1139b5ac,3fc4720d,1e63f39f,f4170950,78a268d,b7f9d911,3cd8bbec,6e65696f,e7e3e44f), +S(aabbe7fc,608871d5,48530bcc,44006a66,319d002a,4d0b49a2,d9c6ca4b,ab9d39a0,2ab2892b,bee509ed,8f221a9a,4f9be9fc,d9d3a2d3,3d7b54ad,383064aa,b2eb9465), +S(238bf052,fa44eb80,3ad4b6e,264942b6,da3ef420,a6c2f113,b2ce2020,9341d0e2,db6d37a1,47552f6b,8f6ec7ba,7554d4b1,49ff8372,2ed461ac,6d5d5a33,90afb0fc), +S(b276da77,f35f5a18,30ac7277,230b70de,1359c3da,c8e68155,6862a37a,6bea9fcf,8b2f05ca,cda2bc01,898d45a2,b9b20bc9,380d3beb,c5f0b346,96d4f4fd,8958a1dc), +S(5a7141a0,afda71c6,a3e8eda1,83409a64,e48fafdd,1965c00f,f711f7bb,ba1625c0,34d782c5,18ffbf0d,c6f9b0e0,b8403cf3,14cb817d,3e84a7f8,63589aca,cb44dbb4), +S(d186323c,b93ab6a4,b435154c,8c5d094d,51a8aa5d,586db604,d1fddce0,f35fe864,65c383fc,ac4a0450,1d483bba,62a1ee4f,247aaffc,7f7c790,eb4fce7b,782ebd32), +S(908bc35,6d29a3f5,1684bc27,72bfcc5c,552ef35c,a2fe9ece,f08111ec,8c368e7c,93fd8d48,6ad5cdde,c7ea498c,ba825468,caed6c4e,ac1c46bc,43411f3d,de9091b7), +S(21e05a2c,6ae8e1da,d9e4d553,3841c89,2d24f91a,aa201b95,f5f3a25d,d07231f9,d8cda13a,c6f7c54b,abcf3096,997e59a9,617b806a,1d805a5b,9d5d8621,d37a2505), +S(224de404,5c6b241b,4b705523,777dc0e0,dfde304f,c6be8077,cd831d0e,c738e33,bf8c695d,5ef0b37,52c84199,d7ebcfa8,d4988d32,f64a79d1,f0863ada,b6f84804), +S(3fbed77f,3851705f,55eac28c,f3921f23,c67a44a6,3d2dfd01,89d78835,d6106a6e,2139e1c6,4d48a58e,24306471,6bdd7098,c7644018,966a2b02,236b64a8,e628b532), +S(5adb241c,b09f712a,b5520909,53114781,388a6f2b,66218069,d6f5c758,1e4edb2a,9932237d,1be0cb9,2d18dfcc,6ccced53,e6cfee60,d897b6c9,b40c3ee,2b5cc9ec), +S(a4396528,ec7f9a,cd8550a7,7245eca6,117c4e8c,c50a51b3,28063d68,a744d7f0,efb8924d,7f921890,71b1366e,e8d0b620,af274d45,56f2d992,ac709d71,9f5252d3), +S(e36dc303,56a9e037,c9ececb0,764aa755,e1493e23,5ddea3ac,44ed4caa,4fea7bc7,338d5c5b,f5a84dad,5e865696,2ed14c15,70d4eb8b,89fa60a9,973921aa,dfd44353), +S(a6c6c231,238ab32f,361743f4,5d337eab,4a529a42,dc45f1c0,670fcbd8,a0dc22ae,4a3433e5,b415460e,4816b9c6,c1db0657,58aa6279,ad4f47c2,a5f07219,c50d00d6), +S(df09e277,b56e0f7c,2e93d8e4,d47778a8,3aa32c99,b0ac74c9,d64ffe8f,5e44b900,b77cd700,b6027f96,9c80a4e5,a2435750,35ed890e,30fdd9af,b41abe4d,81de4e94), +S(803abc31,138b3d57,9a18a580,bf0520e5,d9328812,14f5587,e49371e3,fe03b02f,a270bed5,2ef7cd2d,4d5cdec5,9d92c980,6e700c33,a487b4e3,f507332,99b54aaf), +S(ad15ba0b,c5cdcb53,6b55cb2f,171d1db0,712ff30d,b10d05f8,bce4d70d,22bc0bc1,fe7faa5e,1699e6d0,1e31be29,b5770756,fa6485f2,f3077f82,33789582,bb5949e), +S(85cdfde5,65959eaa,d025b6a0,1616b7ee,8f710833,187243dd,1103a0ee,65031993,facaf5d7,31fb65cb,f10dbf78,70ca3fc6,68a0581a,4eb73326,15d03f4b,87b53204)}, +{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), +S(69db829,eba841e5,c2a1d54a,7f8857d4,4e898caa,fc8d990,eba45c75,9986958b,6b5589ec,635f24b1,4892d895,c56cadae,635de22d,de7b5b09,43e1c4a0,d83f0120), +S(4a8da056,c550978c,725da71f,6cf59df0,e13e3d86,b2255f10,827060bb,9af50961,abc04394,216df6bb,1052db88,e23237a8,13985857,a8048c7a,51787b4,ee7913e0), +S(775d4538,834d66c0,d41a5627,f2fbec9d,a5ec1e12,dea8572,7a32413a,5cbc3612,2c423943,5281901c,6e6665e9,d98655a4,91477e73,fbb3874e,7793a3b5,4b2ccaae), +S(b9eb2bff,b24696e9,36393471,a13ea71e,7ad68377,e78b9eb6,cb40d9f2,7da4632d,c54bb96a,383df77e,a0d77c53,ae2fcbaf,ccf53c73,99e4ee2,faeb338e,8cb40e8f), +S(a8aeb77d,ddeac4b2,71efb2a9,4f44dc31,9f32a0b9,7a1d0e67,8b4bde2c,a3a59233,8fde1a77,e2c76aa1,b5ba70da,dd37af0d,d98115b7,f17d26ff,ed936a7b,5803374a), +S(16f1cb1f,1e8bb14f,b475b130,ff1d0ad3,167b9249,efb9fe20,b31ab365,cb92fc60,9cfb2bed,8c1eb7db,6bc1b7b5,baa88916,b8f68fbb,d23be873,3c54c038,3ad0ac4b), +S(64563829,eaaaa500,c57bee41,f356b8c2,fe7c89a6,93ac0fc7,35044ded,5ae6292a,7298e685,c9bf4faf,bbd527f2,7620ae5c,2c3a342a,4c8d919a,72afcbbc,8b53a50c), +S(614092fe,2588e655,484871f8,3479d350,319b21dd,511e93bf,db81f898,7b2f3137,d10cb0e5,1201122e,fbcb3788,133fc545,7b0a4569,b44ac629,31421019,909adfbf), +S(e0b693d6,60f49c41,d3dbe7fc,51fba3a7,744a062a,46b57b8b,36504e9a,1585f5ea,21cb0611,a5014796,a744a507,2a4ebb2e,41dac48,87bd660f,e1f14a39,819e8c5a), +S(f3ee19e6,d27afdfe,a932fac,72f25828,a6f52c1d,671dd85d,3db0426d,74b8439a,d7c32438,6b62fe7b,fe894468,aff8262c,38bd0eed,4374c9f4,618d16bd,e2925874), +S(fcdb259,b019b7c0,ad0b2e93,f07a89d9,e26f121a,7974944f,85dabfbe,ebac9359,883cb06f,fbe5a647,60711b8f,d99783e0,4f59cee9,31d5a3f2,2cf1d692,894fe4b1), +S(bcad7844,a44ec239,dd113ada,7acf73e8,6271c920,72afb585,60b0f002,a09a539d,428f8d0d,529add2,73ff3728,83f92160,940e71f9,c0a06da2,3084363b,a2586edf), +S(8d54b2e0,f4083478,d6a2ea0a,1416ea8c,fe176621,30e2bb28,fb733656,9ae4ca98,c6d6ba83,fd780d91,ecc8016f,841fbb62,1726fda6,5840f183,7ad17bc6,33106a3f), +S(c9513674,d582a1e4,d91f6ef0,55920a50,1fc230f5,e5bfcf42,8c1b15df,d7f3a8e9,d01c55eb,4d685119,8026badd,3425d4a8,f56e7ba2,6c306b32,5686e279,81aa5cb9), +S(51268b15,a1d43b33,b95e92e3,cfdc7740,679cbae8,ff6a36e6,1da3a34,c8eba7ca,19699ee6,98d95b66,95e21f40,64421d25,a95aa7b9,9eb7ff0a,69331e34,c24952ba), +S(7b46c85d,6364fed5,87230ce0,9e932aca,ca356858,1ecdfa8e,f9b236e,1ee7b671,edda0f22,6808b01f,2bb5df80,2c9b613d,469eda9,e90be70e,4657342e,67519cde), +S(bff9cc3,b68413cb,9f9eae8d,f84adfc4,563069e6,28ff023d,6ee3cfda,8f97a935,651a2d85,cc10831f,f1571320,500415b7,24f232e3,30f47261,8d482924,40259e9e), +S(b5370f4e,f8b3af3f,3e936c34,e7c8cd89,21d4ecc3,7e5a5c0,a205fd37,9abc0aa8,6e889dff,6350f4ec,c3a413ed,694c1ae3,367d463f,be212a76,bc2a5a4a,b59bb09f), +S(72623c52,8e665a8,80c31e78,88b5777e,6b53f02a,6ede4aae,f2ed3bc1,ed351d42,4e2c6c63,c762652b,43383c13,806162dd,1992bbdf,88a3c714,a5f29522,a0db689b), +S(446e4144,8f66c9b,8eb06f5b,e8fec592,9abeacb7,befae28a,cae5091b,798d4f0f,62da012a,fc3d4eb3,4207db5a,8579c581,6a8b1543,b201e1f2,90b413bc,a57f7306), +S(428248b6,49cd424e,12b81504,46443a3a,b6e921cd,79e9344e,4613c653,7d0fc039,864dfa6a,fb191af,91286054,ba7f09fd,75e3d661,c91f939,ef834325,aa26703f), +S(c252c5c4,13e2a430,18ffeb55,355644a0,15e04cec,31424a41,9533af9a,eac0b688,c37efc23,26a2d965,9563b7cb,cf0953f8,cb3ec5ee,3c7ef263,3a6389ad,eb00fbac), +S(b5feaf98,f617055e,b976f63d,55901b93,7e63662c,5b6453a5,79a0c905,c951c037,5372b044,fca66887,566df1d0,6fe0aa12,d8405f84,529db971,a6422820,e6ce7f08), +S(c628a5d,72550157,365031d4,fe16f6f7,94636130,94447c07,e767ec63,8d62986b,539fb7a2,9bd686c8,9e98a1fa,ba95a493,2650b98e,f92198c4,534e58aa,39de796d), +S(f1d0b5f0,d6e30201,2bb50ede,eaf78813,f0a72315,6ef086a4,415e2d97,44acfa73,cd8accc8,fc951f05,5409599a,6da7e5e7,beee325f,2a7466f9,9be63efd,f6d9416d), +S(1d46b065,ac7fd9ea,5771363,dd2ca1a4,cadaf6e7,8e93a037,87aec58,af30f179,f3518f13,c9aa688e,7770d0a,d4dd505e,a22b4430,402ec3a,664fdf89,e9b6e752), +S(2bc0409a,b43950c3,16588fb6,51db2509,a66b074e,6df5d35e,a2ad0fa2,1dc32dbe,2a6df1c9,97bdd5bb,c831d308,d292a30e,68e1dc03,c16ef2a3,183ea616,b16a2891), +S(388a72ca,cfb9856d,174f0937,dc6d721f,63f915a4,6c2fb4f1,1b0cb296,8390109d,2f70bdaf,ebff44d5,b7f6ec79,48184e57,63831421,5dc35d40,48e5400b,dbc84d5b), +S(5404f49a,61865863,859fd7d4,2f008480,e93d8c50,3654525c,38c09ed3,66f95640,71626266,fd861532,a73eba6b,69c6fc4e,2c727ba4,b10e6274,821f3b71,fbd3ab2d), +S(eda6db04,9e8ec72e,c224ebf8,417f2123,8a50b2c5,b149d4f6,2a9bd2d6,78a0f67b,b016fd67,fb3f3fbd,7e53c210,94795570,7ff177e6,38f5a8db,74847496,5618858a), +S(3b71b31e,eef08efc,571669dd,c4deee31,e72f898f,5c83766b,8e58db66,e0c6b4a0,8dc3e307,4780ee6,b8122e3b,d6137998,1c80b72f,66f9f3fc,46bcd11b,a78b821e), +S(1ab86db3,750a687c,39c7a672,c115c29b,1f8f4ba8,586b9957,6b6b1894,7858d52,f60a122,80e05d3c,cd0cfd97,e1029cb5,728ff2d2,df077af,13645402,51412618), +S(eaa96c50,98e79e7f,27b3887b,39a6f74c,983eb44a,9b9fb7f8,e36f4582,596061a,4da962ab,c183ec56,5e37b1ee,3f75c531,3be12425,df54b4be,e4510b45,a84969db), +S(b3b4b315,6609efaa,7964743b,c6789f67,8e40b123,c336f64a,51bb322b,79a6e569,30d6e2e8,4b2cf3cf,e44b86a3,6f3655a,4e1b8e5,442084c0,454f5fde,c5cfa180), +S(1dbf8ef4,174e8259,ccb03ff2,bbacced,d04b30e2,301a4627,77669f9d,4e02f006,6292dfd9,f5df7ab7,31103e38,da6b59cf,4ea57664,887e8804,b61492ea,add33edd), +S(74a9e0ca,b7f1168d,d1ddd81d,fd00e731,7acb92e7,a81ad625,6f655fbc,561dcb05,aea7175a,f97dbff,a0ffcef7,1c89a8cf,d101b3c0,6f424d9e,bced721f,19578d7c), +S(17d35d3,507f39c8,b7429cd0,9c04fa49,efb0d47c,a0c1a0e7,6a303c85,ac5d35f0,88a8998b,603095ff,1771d3e6,d7d69ce8,268c8f6f,20df114d,88cf83c4,e148c4a3), +S(890a566,fb2b0ac7,1a269b9f,90a20877,3611a6c4,ded7874,ecb8482a,f758b0ec,6cd1086d,8ad35581,bf49b063,b1818b20,8e2cb340,17a9c0c8,1a197450,e8d7fd8c), +S(13d1b6bc,13d5b669,6a6a423a,906476dd,d3a671cc,ebd5e119,a8cbf6db,622ecbb7,1099ec23,c79d6dcf,3d2380b,eba653f4,a3fb4bd5,bfe22e4e,abd2e57f,3953fc85), +S(775298a0,c8968fc4,6c7c7e7f,571a784,13ad7766,a9409a6b,6ce02a2b,3e033934,2c3640fa,17aba57d,e2dfa700,ec4ae691,28579db9,91ba8670,a5d8f0ec,b9009c86), +S(ccdbc86b,a89a8496,35c20279,223ff5ec,8a545acb,58b04b53,eb2aea74,ef56ccad,9d229bdc,2b1731a5,730c8f75,5edca111,c52cece1,a65949f0,f51525c6,2f4e6abc), +S(704800e9,c4e03a4d,9aa9e41d,8619508c,9d17766b,217a3d3f,cc5efca0,67594157,7da8e92c,22174290,d08c222c,db33b345,c45388bc,da9434d0,99514d59,2660c24b), +S(3b958586,e7bac33,711be679,30158ea2,38bd6801,f087ae0f,e694e482,a4654c06,93e08192,d074e631,6f7681bb,49b9398a,cda6fbed,c42d372b,2bf3bff4,66ec70dc), +S(1ef945be,6fab11ec,4b48a57d,d2c3ec3a,5eefe46d,afc58284,a005e02f,6d5a8dc,1ffb979c,66ab8493,8a12fc83,52eaf5ed,431c3d14,d6e472cd,503bb1d4,1180c069), +S(72ba6f,627d78a6,c265ffcb,2c8a1e3e,c716f52f,4dcda188,4ab23325,b3bdb1eb,7cf1eef7,aca4f18d,1b1324d1,ae6bcf24,3c870fe7,5a977c6a,c6872ef,c1602afb), +S(2fc567f4,3df8fed0,1eed527f,8b4338d6,92143c20,13b963fd,343aaa4a,ae3e971,c3375e3d,e52b9c17,647e36f0,b4a60031,5837b2e9,c61d039b,1e934ef4,b9cb8864), +S(6c80f08c,30b3b243,1c3a4b1d,b2cdcae,505c671a,11dab05a,4ecfd68a,e5cbdec3,46dc33f8,8b54e177,88358d5f,bfc4c834,4e376338,8cbe10aa,22ae5062,5d3ed7da), +S(587724ef,65997e21,e38bfc75,80707319,c3065fd3,9dfb9cf6,fcb3de84,d28a0f3a,4993a8cd,7f22b55a,88818c49,8eb18807,a93d1246,f0f1efa5,6ce0efe5,68366dd9), +S(f82fa826,8a43213b,5d871f8c,fdb6a6d1,e706ad8f,2b8930a2,c495bb90,39d1d5a1,78749a3d,b47e256b,9ab3ed40,9b9ba1f,741ddaa5,431f4f22,896ebdee,8ddb5d98), +S(18177602,341d74bf,9ae572c7,d60febee,fe37fe20,80c89722,434b9ad4,3c935dd1,aed1c747,a87e00eb,2fd8ca9a,b860ebff,f6ff6b6a,9a2dd505,534b28cf,1f37f7e6), +S(842785a0,11028ad7,4704fd7d,15e9284a,cee1272d,936c1300,d8598623,de359971,d507ec1d,cfe03f65,61a7b192,6c14e4cc,dec54fb8,4587a9a0,cafafa5e,81b35f77), +S(c22076f3,441370ae,c874a32d,297b54c6,f284efb3,95741124,21428332,140763ce,109248e7,857ca454,cd9fc292,731d800e,8a29d13,e557224,bdc47992,717306c4), +S(14c75d2,c7f48020,7f6c7b1a,ef4be041,d2c13f4e,48a9d9a7,b4809f2f,a20ebc67,267d7fa5,be716683,2f48fe5,f782b719,c707edb4,4e2eb6e9,3217e6d9,adb78647), +S(ebbf722c,67339545,ab15b2c5,f6c517e2,e32b319,a5c526d8,656ab4eb,4a72486b,2c56f524,3d33c2d7,7c989453,3108ae44,f8b5d86c,9082fee3,c99236c0,258e42ff), +S(9313e212,4ad5658c,9a50fd28,70af7f26,9661fefa,41b0b5bb,25b8cc05,9b8a2892,92d4a8ea,73210fbd,a730c8ad,50a19e7b,11f65025,a2fb2915,7af992e7,b9d449ed), +S(5549d2ac,f2a7b23a,908d1529,696530a1,41ffc39f,323cae7,374666c4,12d9fc5a,87a51da1,f8766aae,f1161369,67259d,6137b607,b579a215,59e9e3f3,3a4368b7), +S(dcc897ed,9f994741,1e15bef6,8eae2771,27ee8d5f,b2ef8ecb,f47e057f,801c7b1f,5bc17162,f6470848,a4b222cd,357a4e63,c3a15ce0,5fecfb1b,19290b7d,6af6bdfa), +S(a9ead801,344ca82f,738dc5af,85534bad,d320aa7e,2af4420d,b4479cb7,d9d747e0,1e3f6e3b,d065bdc0,99630291,9f2e408,361c0f,76ad5c7f,4ce3f220,a69fb30), +S(4e7e2308,67db8bae,df576eab,ea65f2ee,23efb749,e0047ec5,370b0db3,2897997,6f59c99a,15fc73e8,e393805c,d04a1254,5b8292e6,e8cc8cdd,cc426b16,90b9643d), +S(6d52baca,67e37e9d,cd68597e,f2ec6b83,27abd9cd,c5088043,f420168,726d7c8a,8e721f7c,7d77b0ee,17f2bcf9,b5b1b9b,da9545fb,1f4d4c7c,d544f070,2af986ef), +S(2b4bab06,bebed117,b09c6304,18185408,23b27f24,72223ab1,9dfa9d41,25271d00,c8e41ed1,6e4812e8,c32b8c9,4ec4c4a4,f3f00c7e,2a5bfe2d,27b6ea9e,82329cc), +S(21b85eb6,104564aa,c8b070ca,52b993af,4260e911,4cec2a4b,92041c05,f420285e,712a8ae5,e03bfcac,f6d39f31,ae20c22f,c702b364,35fbcdb8,6a14b1be,7622ebcf), +S(b95236b8,fe6becfb,98249114,a26e910b,62bd5286,e10a0dff,dd145b5f,ee2dd84e,3f0b83ca,e4549f4d,4512b410,57757c4b,7a3b115c,32819af7,6c31d204,c029fc21), +S(7b2b3f20,5debfddf,17bd4922,188c6bb9,a1dfdae5,910803c7,24a6cb4,d5f827e4,4e60c6c4,c1932812,457f7bce,98b8b77c,66512966,9149860d,726b3f08,4beaa2a4), +S(b2333534,312b443e,3d5a5559,67da3b7c,caca2947,2aab9281,d389e10e,2071cc71,5bb0be9b,d27c0b27,b2a2a68,d0767f2e,7ef79a4b,4dffd183,2163d7fa,9cf98ba9), +S(20067cc5,1be142a2,b6f5f30b,18fb52db,a675bf8b,669b1fcb,d297f73e,93920522,a80c956a,f0206a2c,74b11133,82fcf2ef,883114a7,a72012b8,d7dacd7b,ef696999), +S(d092a75,8080d695,2464009f,672a00ba,f49d884d,744a749b,fd884228,8670f2bd,da092b71,78d8a373,fe5dbb6b,2822c9e3,901b356b,714044a8,6b70bc5b,e5018f9b), +S(91f482c9,2e9c481e,79b596ac,e716270a,ee9e9cd0,3d502c9a,96a6e8ee,114d6887,af9bf0d1,ccb2bc3,3d8d3c4c,20346223,19104e3,53ccaa29,4de71967,634e0b08), +S(51bff42d,76705ed2,334de997,dc6d916d,86274f42,494a86f1,e57ec18e,538d195,2ac758d,cfb59a56,e483d361,d7a5e3ec,de0a640b,f94ac8,cb9c4a19,9fe423c9), +S(285483a7,8b621501,b294bd80,3469a136,2ffce135,a526574a,38d29d66,c69733e6,c5f3d286,f82fd0fe,f799902c,76421359,921280d7,72a91c42,33379711,e55a1e15), +S(848dde1c,490b4a3f,2aeaa7e3,97cd2840,23539cdb,a3a79752,601e5868,a29d7110,182c5fa8,574c673f,91302647,2f9fda27,dee3f57d,19c10e04,e84ea4,f532902a), +S(bed1c6d6,82d48d91,3b6ece9c,c71cc51b,418d6f5f,f2f5fc78,f4d27bfe,8eea513e,7f278fee,8696dbb3,fc762602,dcbe1a5b,653b8738,e93ecafd,8c23a90c,d82aa45c), +S(46d3d211,67a906f2,64f7ea9d,231cf44d,f523afce,8b99c3c0,b5f88ce0,f19fad02,7da52bc,905f1f2b,78c798f4,4ff85e90,c4b7ca2,4d2ab28b,cfee6cc8,373676e9), +S(7fcc6146,3554506e,931212e3,fb68719,914943c4,a067c3c9,a0952225,c5f39fc4,ac90244,c5d5446,20b17f6a,75cf6dba,6a05895,e1f3a097,85fd6ba6,a440ec68), +S(a3cd5ea0,b43c25e1,c45aeae7,1d05fab,e9009262,8b544d6c,364abd1b,a4c0b9a3,312ab3bb,fbd8cdab,1c7d01b1,53baab40,517eae29,b8ccb28f,27278a3f,7bdf0b85), +S(c446daba,1825a802,1d62796b,1ef604eb,d905db5f,9874eecf,7be2ef0b,1cd2e9fa,1562aed0,d869425d,3adfb280,a959fbcc,195f632f,f6d8695f,f8eb3381,f7f274b1), +S(77c9a086,1095246e,b59ec6b9,5af0c435,a64ac0f0,a238fa70,6c5aaaf1,3d9e32d0,8a89b6d,442a911f,66d1c966,997331a3,db74fdc4,a1305ec9,e13f2c1c,4f1524e7), +S(19e2aaa4,fef00f4f,64ec5b45,d8cf58f0,37ffecbe,f305ad18,eca01edf,33e62cd0,2d636e48,ab56e09,12b922a,d567164e,93f6185f,4b3b5b54,73dd3b62,5a1bf359), +S(5e6a3b49,60264ebd,1b98d889,5722f263,471343d0,a18f540,141b6d17,f5d0ac3c,8f91deaf,390e1d5e,dc5c329b,b8a067a0,e5f497c2,39fbb4ac,3de3c3d6,ac61f35a), +S(6d90b780,b75219c0,5e5f30cb,61f5c9a0,44c446e6,8bfa56f3,f80d54dd,6c06aa91,6e02731a,dcd7f45a,d52a3550,f6b37f32,4a913c2f,6e48f264,480e3248,a06eeea6), +S(e4358de0,e3e65fa2,25d164dd,cadd7ef,cda7a801,86d11fd6,92222d90,24131cdc,8621625f,69c4cb56,67f92d53,74bf8746,aac1d17e,a9401978,89aa4db9,677c2320), +S(6088bfbc,79b7fe62,df884d2b,ff605794,9659ed63,3d9b7543,ffa88cf6,db81063a,ff27059d,811db138,a061d6fd,e4c289d1,54d7c28d,1a13bac0,10004c83,9146cd44), +S(89aad23e,2b364a3f,6f4e218b,2a519c35,51b58eff,fc0b264c,549e2d41,f1552464,1f1e9915,1a56f61c,e48f3a75,4fe02fb,2cc591e5,8e7289fe,39c88345,3c868b10), +S(c354a06b,468e1503,803d69d5,919a68ee,9e60509b,7d85b543,dc06a004,215525ef,e6656a2,bd6c2569,aed8d779,e061842d,3a65f9ca,a46cf5cb,11a870c5,3411e09f), +S(960513c9,bf25992e,265e09c8,4749b4fc,d3dd1b9d,8de5ba17,88099526,2e2fce90,f2cee526,e2f19b4f,b089e3e5,aa4f3d4,dcd5be51,67afb83b,4471a220,f961fe26), +S(915bfb4b,e41aef95,f4b84b87,5f4b0f11,89397160,c8b0abc3,5c976a08,29c7b534,e1238986,b3b6ea5e,528fc6fc,ce95be98,a0490c37,e2964739,6294a245,5580607f), +S(54a414f1,cb9bec65,f1e8f09a,f12d91de,8615f47c,370a3a18,78beeee6,8297e07a,9d9accac,fbf02cf3,a99c5d58,9e9cbc3e,45e9080f,1d345fdb,93ba4306,c6972ae2), +S(4495cbdf,4f71fc3d,bbaccefb,1eec5f13,acdffd13,9a0e9a5,cb798086,a8a46b2e,1100fcf5,8f571f89,4b625179,31a33fa9,eb2683b8,9d6f9ae8,748d6615,7e40f6fd), +S(737740a4,35247754,b4264e73,7f7c4572,94bb0b0d,102d535d,86995ea1,68b7aac7,601553b9,eb20b8d6,8a0b9562,139d75e3,d3003a4,12837753,29c3696c,42f02f63), +S(e0dfd6fd,1e6def44,55afe74e,dfa69eb1,310ea3b2,6d55a13,73cc0118,7ca720c4,e6d63ccb,96084257,8b764a05,15ab78a2,a5afc188,a8f7a4e1,52adfd3a,e56c6bd7), +S(b4ccf2f2,4a114f61,cb24bbcb,f300a643,3190effd,4930afac,fb2bd4e2,1cffbcc0,3d9fda60,7a752c7e,4316f355,fd0fba2f,1f38bf3d,e9a78bf5,5ebe58ee,e7d13a0c), +S(9efadc19,dc6bea69,e0b4a59,e0bb9e35,a1d4906c,4d612da6,f32f7f33,c96345be,19e891e7,b714e7ac,32f801a,bdc2904e,df8882c5,dbe25ad0,f414fc95,da4915bc), +S(3a4058b1,cfc8bd88,499ddc79,796f07ef,a59bcd4b,bcd37137,2d76f95e,bc177c95,d3024cba,358ffffa,aa3a95f6,cac1dfa7,1d5d4f59,91598a33,f02f3141,81acbee5), +S(30ac9730,53bfc762,7f7bb8e4,a97ce1f4,3918418,e3ad8f1b,edca9bd8,dd7f6ab6,495b6849,a4d4d9e7,8ffc49c8,976b5f9f,a631e1d1,95fce967,416659cf,f91c6147), +S(248a974b,35f025e6,1a462050,38a0a856,d136b68a,2ef09691,69332629,a35cf2e9,b25a8e72,efb765f2,66794992,9b3ae32d,f148021e,63aae20a,d4450e3c,6b5fb5b5), +S(107899a5,11fa2b90,fbe5889c,fef115f,f0c9cac7,62f82cf,12487318,63169a2,ea1c4278,811fbe5a,6f011375,35b584d1,a85d3236,c66d52a5,845a6ffb,3706f8cd), +S(91905b3,e5602f5e,6a780acb,4a33f7d5,4d87b239,dc9f19e4,99560d22,b062e897,caadc62b,71d3fcc8,d9d5e410,7a11fb75,832693af,46ae99e4,d8f7d140,900b82a2), +S(e103d0f1,1e7bfd74,821dd503,53b08f2b,3c56338,f4750fdc,76b4bbac,f7ab2404,eb65ee56,1dbd1e1f,d5437b7,b86b1502,3bf423ee,f75e7620,aa6558c8,a039f741), +S(f35e2c54,f2e8f2e3,fdd18dbb,e0244de4,5b9fe772,7c00727a,5f12d7b1,def1c45c,a01aaabe,85682057,b649ed03,e9786133,e5d22cee,4e5c56a8,31bb310d,fc03cf78), +S(5cda0c4b,ae3e3ab,8aeaf59b,ce9b57bc,da0d8cc1,b638cb8c,aab26347,e8188bb,d992c965,4e8a3d6a,4838c9db,64fa1114,e88986ad,da948ddf,52ca17f6,f600c219), +S(cecf5b7,1a36fd7e,2990dd73,9fd150e9,e6183368,436b9702,f9dfa05d,a88220a1,34bec823,e6cf7184,f837e738,3c4b5edb,3ab3f027,d3034639,b038efee,5dafc8d0), +S(5761d842,db207d20,42e3df0f,d95f13b,8f09210b,c7c8521f,4c33ce69,5473c28c,31c68feb,48e1eb87,afa40cd0,a4e55c9d,862c914b,714a290,4dbefb01,d59e4dcc), +S(d4b5e716,5ed18b35,61994dc0,e2af0ca6,3d34d053,d89d211f,4157434c,dae8b10b,137db71,89d25a86,cdcbc931,ad30c5f3,27c368e0,6beb1335,746cf6d7,bbecb07b), +S(6e9a9ebb,9cdd9729,f3bd261a,ee9ccc5,3d55a9a3,fb79d370,489ebac5,9951df97,32db39cc,a1a862db,172670eb,132f79cf,dfeb7022,ebe19b87,3d9781f1,1691f4a9), +S(ab4f56f1,941e7a55,7f7090f0,ba8b10d0,13db8e61,f702ec07,c4b99b2a,a54e12d0,c1a1fc11,51f23ef9,521ab291,cff740fa,42e00fd7,1ed3012c,86e72709,9374c637), +S(6f9165f7,e1f44fc1,1f7bfe76,7e8f7f77,3d25caec,17cc7357,d0b99ff2,1258134c,350f1c38,50c74078,3dc7a5bf,3b590cc6,45063e44,f46dfae5,b1c961d5,822b5840), +S(ba866c2f,67d4b6f0,8317a5ee,32519cd0,93c17fc6,6421a156,a4056eca,dceacec3,93fa72ce,612e210a,42f81d5a,f3c16d26,36895eb5,4e2d8d98,e6d3589f,d6ec72da), +S(35834355,a9445a8,40cd6b00,72e6a3be,54d80301,7da65bbe,cd1bef4,6788ed6e,92097690,e15e333b,55aaf635,62676402,cff85231,885060a2,2a29f263,667e6b5e), +S(50864d50,6835ed6f,86b25b45,11db0367,d88de358,62046623,573e35fc,6524b4f4,e970bd97,a9692202,376f485f,5548a980,188650dc,91ea1351,8cded8ed,7724508a), +S(ccaeb079,8fc41009,fce22bc3,3f191412,4be3fc03,cf9031ea,84f1a017,b9d5b3e3,b0ca53ef,45ed8340,f448edae,2ff784c5,c0b3bf3e,ff93cba0,8c2ebfa,eaf64df3), +S(46f30e66,cb54b89f,17063c32,dd1543e7,e73d4a08,758560a6,e62e7329,63076c0d,b84bafbe,69b45a62,498dd9ed,d202506b,9be830d1,6d6fecd5,69fb8f96,6a6a3042), +S(265cd9de,e006d582,45a04fc8,82f0ba5,b7fc91c3,6535e748,514ec587,c7f80327,7199f872,7a6d937b,6347d351,2b0050ac,a8e37652,3d922cf,f60c4b4a,846a0f57), +S(31cf7fd4,4e30a151,5e8a06e7,347416ce,104338af,3cc8deb2,ebde204e,de6fad28,5e1a97a0,bb0d965c,ece3be90,b971fcb2,a5d52ddc,5f19cd1c,9db15671,e5101d4a), +S(61110e5e,f84ac25f,85154139,d8d6c850,9ec024e5,5f796b69,f69e7bf6,3c41ce05,b67f5359,bcdfc138,963568c0,b386996d,82b77005,563cf104,2736856d,e548abf3), +S(539655be,97322448,a93f3760,9e67a02,ae39b00c,ce1bd156,cf9e78fd,65788661,105f9f23,4f075bd2,dbc1b74e,3e81dead,125792de,6025efe5,7463588e,eb5a7015), +S(e899c784,7f0b1e06,d4dcdcd8,1d978af0,aa00395b,af7e82f,a25c1534,1281b81f,f37e6134,1687ee5,942992f3,138238eb,1b2f13d0,7353f69,905c0b02,f629f436), +S(ae2d2d8a,be3313d3,33ff5efd,3d31b73d,799b1684,47478e38,7821ebff,8d722ab8,680721ee,9acdb2a,bf38c78a,910cf9a9,3beb66ff,d086c982,639ef987,3c234ac9), +S(b9e7abb3,9eeb4754,5d79bc29,97187c99,c41eb1ec,7fd6eda4,33eabdb,d60a5470,638a8f7a,b02eba6d,84d23582,46180a2d,864be6e5,a6abd36e,b2609ca0,3d0e0ee4), +S(2b20a9bd,a7a6730e,95454586,a6778672,6bc18e60,9a765fc8,c54cfe75,ea0a5a06,2e442fab,623d335a,e9c2a2d7,f89349cb,cd2af4e0,218841c6,d5e0bb9,22d0e382), +S(72fc3a7e,46d9a6be,f381e977,7253e8e5,f9db3afd,46648e8f,33b65080,ddd2d199,85cdc38e,d45cf08d,c23ea251,cf8a8c49,6ee654da,ed173c93,ee380d30,2a0f29bc), +S(db069c4d,3b0faba,af16a827,74452e57,72aa87f4,ff3b97ba,cf17c75b,349e4d86,b794f792,85fa96f8,a7037f7d,ca851a52,7a83afca,26965e73,6408ecc4,1247c3e6), +S(7cf3ebd5,aa1b2065,7d7d0ff6,a34a72e5,60436327,afd1f548,ef45eb4c,46b01b82,51de8d27,2ac224a5,2e5c2645,1a9863a1,8c9f8c03,43663023,d7621a9,21f1d855), +S(73b0a3f3,233b1fa0,30fc1062,69453fa2,2120b0f,e6f91d1d,c637e0d8,6573ac63,e04e33b0,b118fd12,30a816ba,a5ad9265,90ff186d,7187a7a8,cb740e29,8de71787), +S(32769d34,ca2c15e0,6e520b40,6a8cafb2,1f541f25,130dee67,7f4bc606,d3480db5,59ee4d85,31b67173,a8c1aafb,83ba9ac7,2f72dc7a,238e1630,5a3ad39e,d508334e), +S(bce22865,2f6cb032,82f50e4f,c834216b,59a6e9c3,e787cc81,fe8391fc,3f2b7101,d5ec8a38,93820cfa,85daf98c,281c1059,51986ac5,5f4ec530,925db0e8,c98661d5), +S(6911f551,e3522b85,93a1160b,356a5254,968a45aa,cb9fb870,37e3cb28,7674ea84,d26573f4,f3a58064,83d6d814,553f8dfe,e1d3b413,66062b42,ecb1f4be,56c39839), +S(171de86c,6dbcd466,2cc5a0a6,967dea53,46411198,a8fad3c6,a21761a0,5f3303df,4c6652c3,ed4e1b35,119473d5,96ce0350,19ac08,acfcc66b,8664c86,21288b0f), +S(8afa0269,be8300fe,592b612b,19758692,bed5d98,6374838c,126981a0,60a8af40,6f93d092,f4d82898,7d3aaa28,d8764c8f,937902c6,a2fa6380,91d4e6c4,d07d8eb8), +S(9c6f623b,1feb0699,59b129d9,aea3349a,13b92c41,ff7cae56,3f39adc3,474a3721,c6033ad1,f7045dc2,76f1937d,31d01a83,cee9a2c2,e6e8e0cc,c130c852,76a76b78), +S(5c88e5,bc110d8,ab0e77b1,e1592dcd,d576774e,4efc3499,5d05dd43,fdc8a22a,33edaf3a,e34fc2ae,b2d1743,c5be7c31,7ca09368,8226b5b6,c98be55a,18c162f1), +S(244116d6,b514bc40,7e5f5ead,624efe69,dcd1997d,881a6490,d2db3517,5cd57fd6,e9194bf2,e27251ea,60f4761a,5114d205,c4d2c13a,c9fe5887,61098e90,beb5b353), +S(db49b35a,9dd72d8c,8d0f0424,20c769f5,955658ee,7eff4ced,9dd7d31b,c0252dda,222806de,3c908a10,c71528f4,132e59b5,d14480e2,391a8aeb,8a6f7de6,1c3bc66e), +S(e208bc35,609acd41,72adc7f7,94ba78a7,9103d213,78c1ef29,7dddabbd,d782598d,f8b4fe8,6f6f1fb2,3c4dc711,8991a334,7314a3d0,1428fabb,6167bd64,dbb31e6a), +S(2da52754,60fb82c2,d39a242b,fcbf3433,be971662,acf9c5be,923859e6,443f3d61,6270758b,6974d5c7,3e5139f0,35d1e218,aed29c9c,bf17b6e6,b8ac6708,b09c69d7), +S(3df8292c,e26a8c51,3e5af6f0,4bf7323d,de655d97,dc00ae71,eb8e1488,bddc3132,98b07c95,c45573a7,97481882,b2f91bcb,6aee1d75,21377640,b6a52721,9d420750), +S(a2a22d6c,e949e74f,813c68fa,587c00ed,3c044c2,42456a6a,70b83f30,d8bf954a,6f4c0800,efe49001,9770f0cd,ddced4bc,d9a3994f,a1721cc7,df0576cb,e289b9a4), +S(8a240ca0,aa79c339,b274df12,b5d739f9,97a84246,b330c28c,fb148c8f,dbe40559,e8aabf1,7ab14974,899689c1,113e002d,2a410d3,b06cc5c1,d0fe5eb4,1bc480a5), +S(fd61d479,d57d73b,1085b312,2c5026a6,588e64f9,f642148b,589de7bd,418a3b45,e0e660e0,642739ac,f2127785,dd23475d,e83dbe72,2915b732,cd19dde8,38b240f), +S(b9cf694,82581706,6565e261,e9c231e,4e95ee01,4a8eb744,12472b86,d5b2861d,969b8e83,a3c2b9d,a4f496bc,b4f7cd78,a7e418b4,c793676c,7e1a8c,fa6bd33d), +S(91ee433b,c5c7e9e9,becb58f2,bd659171,2131260d,8a26d65e,b3fe33b8,442fc3aa,86215e62,1cd6542f,32c9ac7c,930282f1,de0cf7bb,6f6f46d7,a29ffa28,22127b70), +S(1cda7a25,3e8caf86,bc67a7ce,7fe66799,e4ece2c5,64622557,f3b402e,e4b6a6a7,28e11403,94b46fac,df5950f2,9f44a66c,e0c0fdd6,942f1856,db17019a,40cc7623), +S(52471c90,2508a47a,718f3abe,285b8be0,e9e1e243,35e27673,35a25746,2c864fcb,94d8cf1f,5c08836e,7dbd2373,860d78d0,c17960d1,5babf5e9,fe85838c,1923673d), +S(dffa4f8e,137745c5,d11b8330,59ba9fd3,3d09c9b3,bab12c64,dda46a2a,63ba3b33,982d5daa,f0bf5143,e59e5c2b,54051c11,f8e42e30,adac79fb,6cd19446,e56ef372), +S(7d5d28b8,88d15a4,3721de73,d1e3be0d,677b6153,58a3664e,63bcfd04,c85bd47e,9f987506,34bf602d,fc02ae9,9332b494,9f4d1f21,84a96f70,b7c51051,5546556e), +S(8e65236a,47ce5e43,671364a,2e99c5ac,4375f3a2,9110560c,fcb4895e,637be7b4,d4800683,8beea2a4,9b220e38,345e0719,b91f2315,caa6bf8,1ce59b58,c0ec0b79), +S(e8f250d3,f4365f7,696a9b58,b09aba7b,e884be51,86c5f1a6,d513b9c7,bb3c6718,7548cb27,8710e668,27aa9940,6caaf865,e7b723bd,e21b6ebb,855b8150,cba0bddb), +S(87cef4ca,dd9dc07e,a82c0f5e,943e5ea,42b2a9c2,8ed24e46,5604a85c,a98e08a5,736974c8,9718b1b7,95fab8c0,9cb4a3fc,1dc9c73f,cbf0eac,848a4421,7cdbe789), +S(48485885,4cd24d10,aa546441,e132dcba,b433b740,b9eaca38,cb80eaaf,bef064a9,91a91c0f,87523cdd,c6fdfae8,d16145ab,a2c67a44,e7e9655f,417531a8,9e44f693), +S(6f7180a9,be73fe3b,3c88817a,154ecf8f,3102fc3e,a1dddf97,4eefa00,224d7149,e1ecb8a0,bcd0f4f4,8e039dfb,8974b552,4456c764,f4e668e3,9640c3da,4cf24931), +S(d2f859c8,29ff75b5,cd951da5,2fcf0794,251293a0,7e8f0bbd,925216c2,4441fe05,c5edfca0,805026dc,32644722,70f22291,f65b60f2,5f93648b,f4163ad6,d12b704a), +S(38454e28,6e44de11,7f44b4e6,27ad0b15,d555c6f4,f8450624,d5b717f4,88c5f47,916bf1c4,eb9c5159,3e52e3a0,e1414e97,652997c1,fb9fdb03,f34e96d,4c8cfe1e), +S(b039e580,64f64b6c,dfcca8a5,1c93b169,8aa14b60,a2bb6ac7,d098987d,6b72b5dd,17cc6940,313d054e,34ababa7,99fbb1f,a518df36,b2896039,adfdee62,dd5f65ed), +S(5633c240,8a81d35c,61d6d5fe,3f678,220109a7,97716250,aea118a0,52939b04,3997de40,6495a96,ee3e655,3a69b04c,b11730a,709f1077,a5ac9916,85c0ded6), +S(a4f3f220,a7e2c9f4,bbf541d9,8ea71661,e142bb2b,76b4b7d7,af989652,2d2cc79f,40064f02,5dd4bbd7,9bf80bd0,f697dd6b,26ca8ea4,d04252df,ce5888b6,5622e669), +S(94568051,acf08d5f,e36691a3,14b44373,f46065d5,af48e08f,f34adc34,d3d7c15b,59672baa,3698714d,2983e23,1e7d985e,acc15cec,1dff4ef2,dbede100,972d2e16), +S(a4ddf835,3421309e,a41570f3,cbb0002f,5fe81975,35dab4ae,179a7f0b,dd24472c,ce127d08,cac2622,56f116a4,c993f504,b6df5833,731d04a8,1c0f0154,c4126078), +S(259799cb,4a4a4238,5bc3806e,17f19a56,844ba9de,8e303d2c,1cc0ee3a,a7831da3,aeffe3bf,b15297b3,4919cf90,cc808308,ec41c63d,f4af573e,b1d46675,20aff2b2), +S(d65f0bc,b0065fa6,4b13abe0,b621b2d7,b08cca48,2eed0267,8b131fc0,e1967dcd,eacecf44,defa0ba3,3bb5e8f3,9ed0bd15,5ab9aa57,81a22307,ea0633aa,64f98f23), +S(94ae2db9,1ea43b15,fcb2acac,93cfafe7,36874373,efa30c31,98f10b3,b94a1b93,8df119e3,d4872a0f,3b40d3dc,fbb894a7,59f5719f,b81f875f,71ab5b7e,f8cf7db0), +S(126fff6e,9e1c65cd,d7e8aff0,6a20c00e,cdad4440,64ffa43,675a0df1,f7c0ab35,b4eb051b,e05cc632,ac1e23bb,23814d1c,91caab71,6b214dfd,41f6f44c,bfe2dd72), +S(3c8081a4,4183a093,45397a2f,c895877,79139c29,ec6dcf0e,d24016a8,e9d3b210,45a3dfb0,9ff805eb,f7533bcc,1022e0b,8c69b658,88a0393b,66ad3151,b0c3bd57), +S(210f6bb1,25fee215,9a04d068,c87093d8,303ea3f9,1f8f20a4,69dcffac,39295f72,d96e5591,4b2f9eb3,20b9e17c,f3e9a9db,9f284be0,3575b192,3e8d561a,bb5e4d5f), +S(54e9e6d5,df0555b,3a29f1a4,33623e38,5edf8a41,d19fc0b7,c82f151,f14a73fe,ba04d63d,36b3d5c0,3ac704fe,7d15d939,918b8311,1f83bc55,4cd56c33,ea709936), +S(1e65329b,765365a8,6a111355,eb0308f7,c1702263,f8ad9e35,46bb285a,2fe6bfd6,e265bf55,5e975aa9,f2d8b9c5,420c33eb,1a05eb58,ff40da46,2760971a,d044b654), +S(4380d3fa,48cc932b,4f5453a6,24dd7dc3,b4071e7b,eb1a1295,ad8e64a,aa7b40b3,6da29a3a,30cb7bfa,26bbd0ea,cd84c98,c4091683,be9e9742,8dca4fff,5c2a6393), +S(c3990744,d6f84a2f,490a9e8d,feac8534,4b1d4524,1a573d53,9718b6f1,c1bac2fd,2387052b,2161f56e,fb3efa32,13bbe3ec,97e2c78,24c648d6,913bd9b6,c8feb342), +S(d7e1c842,25966972,5de9fb3c,25ec9fb6,4ad1ed23,566e2930,292507b3,e099dc34,5e1cc09,97290936,184c22f9,747e043c,dfb86fde,142dc129,77502a2c,4ad3fbef), +S(f14fa91c,140d3de,5936b6b1,5e4a1bab,8aa22013,ceb72503,27f608e9,2e048f8d,8f429f64,7396fc1c,fb5c33cf,e982cb9e,a762735e,7e595335,19b2e302,a976f0cb), +S(c7837842,5ff42ae5,fbaf9186,81440523,3286f91,5e170133,d81ef705,e80c4f4c,84ade3df,47e23a3d,9f16de8,f61c7d1b,b0428619,8ca74b68,78947cb7,4a5faf43), +S(f39bfca0,beac1ee1,2e98624f,32830908,609e7c64,37175322,1650e813,3874b0c9,19e4fcce,fbc53b63,a3a6baa1,252b7331,fe5365f4,86300711,f6c438cd,4da8aab6), +S(703da707,37e1c78d,1a6dea54,6e896d59,984b1ac8,188fb720,ad837273,86a2c188,e8b3547a,23877467,75c9bcb6,1ed4b4d8,9ee22da2,1052bfc3,aaefceab,698f3322), +S(ba5f3f79,b3d5be05,a3d85b78,16738253,7fbb206d,841f8871,b9f578d2,2c17126d,40acdb1f,c139be,8a1350e8,3d52ae1c,449b3874,71794282,d5ba72a7,5aee5a78), +S(af43cb78,d080053b,7fa4cb34,4d70be1d,57f2acb5,e6718bce,abcff626,c8a44d4,ecb553f,1aa18a31,e8ba2306,22898b2d,fee8d6e5,2dfe6ca1,2ecb5f73,71a5987c), +S(3a3cbce,2b4e40e7,f2c32398,9dd6d35b,74f666e8,48d73e8f,b5810439,f0e1749,f29b185,7c7c98e0,696795dc,f243b662,835c6d00,9a7e55d8,612f6841,d3b891de), +S(81c28d3f,6cb88bfc,dab4f911,98e1184c,d0455bbd,998e8ef6,e98cef0c,fbfe101b,5fb09335,f0527b23,555db9,e5079979,13b75422,d75b5059,198341c8,542c53c9), +S(e9e5ce5b,3c613100,5c4e57de,6133cab4,d65d953d,a4536926,fbcbfdce,1ca56fcf,f9016f,bf8ed329,4a1a5fd0,cd66bbac,e0cd87bc,e51adc95,628b1a8a,25ac1f4), +S(bb45dc5f,e2265ec7,60353992,45f51c8b,72b642ec,219396b5,5ab0edbb,f890c4c,b375975c,c8107cbd,1f5068ab,c3f2f62,f1e9b76f,befef470,be29d5d5,a615408a), +S(38356fe5,4d91f656,79bf2558,36290b9b,b0840b9a,fccbc6a9,163c164a,3e4c7f30,17101271,b3881a72,24373054,39bbda94,6ff03805,abcc35e7,d960a46b,54122ae6), +S(fe6f885a,2996a35d,2886e6ff,e1d0945f,515f5853,c0b9e922,ea82c4e8,db2b2385,2310d0b3,6846cb50,bc3159eb,37cc6b8,47645b07,207ec23a,c75b26e4,fcc0f96c), +S(f84f2cc6,f645b44f,b4cfa5bf,2840caac,c6f512d4,4b0aca89,987bcf07,af8089e1,dd3ed3fa,5ea7f359,8c2b2030,92ede474,b2f594a9,61d7fd6f,8348813d,bdb97f9f), +S(8f2921e1,dae78a3a,4557d895,50de9bff,7641749b,c963764f,e12bb329,2ac092a,9c7f813,20fbf8a4,b4f08b57,58b02cf9,1472612f,113f1be7,fdcccdc5,2336058d), +S(28dd6677,d6085587,46523eef,46aa90fa,496f04c,94e8aa00,2636212a,913eabe3,3f6da403,cfcac4ae,f2bac7ee,9788590e,5cf58a6b,8de534bc,a2dfe892,44309e34), +S(307b5b7b,d959def4,9d3518b1,a53cffa6,f1d87c73,157a0713,b3276821,30face1,b32135db,5ef40508,184b19f8,d3f150b9,8eaa6c4c,edefbfba,ff300b2,86177d70), +S(caa54ba5,ec29788,c53ae86,c58b8436,dd9a62a,cd41797d,1cfba1ce,2c70f251,71ba3e8d,9025e404,aca75114,3b74e0eb,4ef2fe4c,179c1146,e774b432,1e51d7b5), +S(2c2d5637,4a4d6333,83f5051,c6beef25,884f41c8,c5474107,e8f19532,580c8e63,897e1870,4a3767aa,3ce72f7d,dd4bbc7,b8a77594,469cfba9,f3a366a,807ba256), +S(7aa31729,dd90cc03,e40e41b3,5682ed5f,1ac4addb,3287c2df,b4061369,18065e02,e5662d23,55a0c036,73b120a4,fa430d93,fa1a6b34,c371e464,3e40432b,44aecf85), +S(2f882827,4abc0c90,27b6b76b,f60523cc,fade023e,42148f2e,5e237c20,e5da840b,d402a02,3dedbaae,ce4d003e,95daf219,cf47b98f,ad547a92,fe77090b,b9772ae3), +S(a4243ce6,15596c36,ea766263,4142a9ea,817676d8,a9f6c7c2,2e6ab9b9,a74a2fa0,6a2f60,20ec81bf,3d32c353,49f29fa0,db06e8fc,d4058dbd,5214aa0b,8ddbc595), +S(8b7b7e38,a9b704f1,3dc12d15,1f46a3d4,950abd52,cbdc79cd,693e00ad,b7556934,2cc742ce,60e35db4,fb432d93,299e5fcb,f7647856,d8ae4e8e,2bbfa6fd,a60a6a84), +S(da61f7c,31e2ae17,39b188cb,59c9132e,e7120f34,b49a846,66538a2b,f338911e,c8d93b53,d102dd0e,20da925c,e6f63c04,4239fa5a,2d04df8a,9fe68f23,6d03b6d4), +S(38925464,b72e70e0,361c0420,ac92348e,3d208b63,37e55b31,6ce554de,afc2fe09,c96c91f3,c452504c,fa868726,7985c532,181fd1ef,82344a45,4392a4fa,8e534c82), +S(ddc0043,46b27c54,d6a927a9,a053195,335c476,bc602490,96b1c62e,e06b6cef,be6ced65,445cda54,2cef4ff9,2f85289f,bc6c5007,362a4cad,5df4ec03,b450e7bd), +S(5c82a52d,84832270,3cc7506f,fc457b46,8aa8d5e7,1c55a4e0,2dc1971a,a298ee6e,49839199,fe6d88d7,3a75b59,d06a2fb8,a0dae45d,29c35cac,161866c2,caff5021), +S(b9793612,74eca1cb,e5a41462,aec446a1,d70cfe40,61925ce2,558980f,c1d9d435,c59da470,8771c732,d7c94291,8dd76768,ceabdc74,4fb49700,6305b591,2cac9d50), +S(be9ef1b,591477fa,7e3b3f2d,a0c9cb1f,37dbc3ea,f4529f69,2f455f57,fe3a026e,9617409a,97621fa9,b8f8d926,ffc895bc,eb60d2b7,37708bca,99258077,e9d5999c), +S(397f89f4,ea848a85,860efd86,5ef395e6,26e9657a,2cf04097,7af1e8c0,f75e6953,baa93eee,2bfc5d47,e096d20e,c31a2a07,ea369c85,66dd8402,80dccafc,86e991e1), +S(ee263d15,e4437d90,9f1960f6,504663d6,410a12e6,3f70bb86,de33e148,2ba907d3,2512cbc,bc9cbd9e,f0037e87,d51e6fa7,9d96c748,69b702e1,aef8614,859604bd), +S(3c93ad7a,85d2c4f9,1e03bae8,1d9ab6f1,d706779a,41387c9f,4b24ae1e,c8b7497b,ad1aaa38,5db82667,984d53f,88cb0564,6140f339,3b936f3,6d39099e,fca9aa36), +S(fcf7a309,e1362a1c,6659c2a8,e504ca6,8815e320,9ee6a8e7,96c4f173,f1769216,970368e2,15005e71,7cb31c4a,b0963246,796656c6,be28022b,e458fc9d,424bea47), +S(7237b824,1ea29c9,5f7d216d,e15a1c67,9f4f546f,6f79e306,14e2b2dc,226b9402,597f98f4,8ac7e00f,db3ffd2f,88e3e16,57417a6a,25c18b20,c2bef0c7,fb49e6c0), +S(1198ec44,7691883f,5045634,c4475b75,95c2ef24,29e7124c,2ac93bf0,2c0de7cb,ff51c40e,d65465fc,4688436f,7f5d873f,d8be9b50,87dadf04,54b64ff6,e9f8f789), +S(bc5d666a,7d29ca8,21112968,8395a4aa,2fcf4f94,a8437d22,6ccf2501,5ff713a5,6e7ad8e7,b74c48f3,45e71e1c,605bf4cb,808862d1,aa292686,4723b14f,c8169c22), +S(1e05f444,c110aafd,e3c828b,97db2721,d9ae0270,456aafbe,3a2c5579,ea3a2154,3e432d3c,baeb8056,105b67c0,c0e1551b,eeb617f7,c8ea4ac6,4cd29f27,c77b534f), +S(2d7ece5d,4ee96a96,91a5812d,7bf888c8,6f0992a2,51ecd061,b583965a,895c94f7,9a9d0b4b,da5d4500,49ac087b,a30bc507,aba5baf8,f98ede76,debf59f9,be1390e2), +S(3b717ec2,ffb0f062,55cc8241,f972709c,6c3507ea,8e11beee,d5e267e3,2fb576ba,5176f106,23d062e,ec697f2f,c7090352,4fd6700,95baf419,d0251030,101cc915), +S(304652cc,3fffd5c,c86daa47,ba797d5,14d7f3bc,11f5fb04,83b7c217,794a7156,c0767215,17b5f18,f92e6995,f35fc65a,434aba1d,f48a2977,62d1a04a,a587d479), +S(2c9f0acf,c4f3b56f,4a0c6262,1fac78f5,1a486173,dd6bf323,d66bfc48,13ea753f,b12aea95,b7543ce0,40291db2,1ba73dd1,2f0be788,38a81d9e,8e00e0dd,7400ab05), +S(bd236103,9f096e04,770bcd3c,3a10d5fd,66ef7fa4,a6c869b,52146314,90ae5dec,d28b95e4,6774745b,23ad0dfb,dd4766d9,8a2f770e,446a5c16,3277499b,e21b6511), +S(e97ff1d7,4ac00778,97caa1d0,a640ffdf,3bac580c,beda2fbd,23f25f3a,e9a26f5c,f093150d,95ea1a72,3a54e382,8c919940,3c296d5e,fd2ab41b,25cbfdb0,9aff5ee6), +S(f8ae0f13,a6beb793,46450b3f,53f36ce2,8c81fa18,56bbedf8,87e9723,9e15026,3988af1a,f632948,8e7bcc78,5cdc1ae4,a572141a,6cd15429,e6b1b40f,5b44e529), +S(6a944e92,c051b864,d4d26bb7,594f4ace,43951291,44b6d255,5667cc08,86dc515,13a75d28,c910c56a,a5dd2e75,9893d4a7,d86f0efb,dcf715b0,28c45277,50745660), +S(fdcc9b7c,4cc46a5c,8b114e05,c1f44bda,ad11957f,f05a0544,7fd49ce2,7c6ebb5b,72b243f0,1c142e35,f19653ad,a3d8012a,67f0501,a155a644,67629b26,58943381), +S(841e3eb7,17767093,19efc620,4b1dbf4a,d339564d,7ae6ff8c,647a9c27,93e9a5c6,1e5d0b55,7e50e0d5,9abecec5,de33570,d2a57d8b,a2c2d4a2,e90c0ac4,d4edca19), +S(fecf1c0a,32317cf8,469f181c,5bd52ae8,50913793,53569b28,c0c90c0c,dfc7b248,c61056df,56ac8e15,1077dc68,bd0a4819,c19ccecc,552dd14a,bfd6a457,516ce448), +S(82efa605,ac4e5e4d,1b68bb8c,b3f8d24e,47af1820,a7600345,757a36dc,2b241c52,171f1693,a2a0c1df,531d3d2b,5da06241,651482b2,3eaba4fe,c5d0500e,868db6a), +S(5ca04a7,afee22b4,c250d0b2,98691a5e,6b6805a6,b44da5b3,6b8a100,4fcdced3,7bf3a990,465166b4,e8d19ede,f41d7ec0,c7ad86a8,2ac57853,fdc731bf,15a3df09), +S(db455b79,de85315b,ed8ee65e,d8b5d659,5df2d2ed,9eb6e9cf,ab939fe7,93105df1,d821dce7,395db88a,98624ed6,44705a39,e2e53e6a,ff3b7405,3e8b9e18,4e1efa5f), +S(f0033201,aa7e6293,de70665,38eb3133,d2a6b56,5e73ace7,81fc98ed,ee458fb1,612fe4,d18f43a1,12988418,42d875b3,2c9525fa,154b859b,8258f904,d69c5d08), +S(77172496,3722d684,2039d1b9,92eea093,4c0fab8e,4be3389d,7d5eef1c,c31fd291,af3b1ad6,499c3224,aa47c6da,26064bd1,a2357acd,db722182,19350cbe,b84ed1d7), +S(7f27ed8a,c56722a0,730ca755,f23bbe11,ac868be5,e5571f70,5b11df40,28771532,adc25cec,11fe3569,7c8618ea,85005c05,b0fc73c2,db51d6a6,fb55c4d7,6ab9094a), +S(919105a,5d0f13b9,d0c6618e,21257efc,587858b5,6b6b4477,849f43dc,ed12bc0,54c7da67,731e00d1,316a0461,3debdef1,623feefd,784702e,eb42b995,4da27472), +S(e04d08e8,ab086e2e,155ac0b8,408c0163,e2db4afd,57703ec6,8a14c43b,3ddeee1b,742a114b,87e041df,93d15822,80a41360,86b9294b,20efeaf2,4d6b44b6,68a891ff), +S(82c95d88,5715b88b,5c583b9a,467a5c83,4b066ad9,3dde97be,866eb8f7,fa23452b,dd594973,f5cc5595,55d31870,fd9dd65d,c2b79733,c9db8c44,987314a4,d6ca0bed), +S(634fbc51,4efde752,b8726840,82372231,6166a17,ed706b00,1ca80ada,e4c43d8c,61cc9b14,11cc8e1,3f6a5243,64b04221,ece416c8,f5f381aa,8c3ff977,2c20042), +S(d85436a0,1c84e01a,c71ec9d6,93fae5b6,21764db2,1a8604cd,c7b37b21,452348eb,d4f9e6d8,5e65d57c,8bef1acf,a844d20f,1055c756,9690a10d,a230f5f0,8e0f9f8c), +S(200772b5,67197246,2ca9c5c0,e042d0b7,6990a34a,506494f4,f66265fa,4458459f,15e7e0b4,23c66afb,92411156,5e40b8e1,47c97bb0,28bbbabe,8e1a83cc,49b96e23), +S(8d8e235a,8c425a9f,d3556276,2b3c5404,ee0d8e2d,2e41c785,a05f34e6,1ce50acf,74032ab2,8e67f7c1,71bad531,fb1fefd5,d4aad08a,f44543ec,3e731dde,6d2877b1), +S(a5936747,fd423569,cb233184,77b992eb,d2d996bd,b47908a9,59d1a556,bbd51804,4cd3cbc8,ee2e795f,fcf5fb64,4deecb2b,45d6aca0,d70bb33,83f7d16a,d52ad109), +S(486156c4,8f785096,ddffbfc1,fb1d358e,2fa7600e,4decc327,e8b31014,21b75001,dbbef974,6482e537,225f5459,f3f7f62c,b0229307,72c1f251,75ae3a20,f6410527), +S(be858e3b,217489fb,1401b203,fb268592,ca1ff022,4d6fa329,78de85d3,b8a49324,f0bff99,e982b3e3,be3a45ed,f96f19,38d98b51,5b899d16,3abe2e53,bb67e331), +S(641e9c7c,cf17bc7a,45bd5298,af2829ac,b0d78a28,7c03f056,982e14ba,807ad7a7,c4bfc1b2,e338f2bf,7c9afc27,63ad340f,b5b27787,fba888a4,b8c4cd86,cf745fb1), +S(e8566e5a,1e855981,c6e275aa,3199dca3,3ddbb528,482ef60b,2e87c9cf,544cdcf6,94adf4a6,1643a235,9ac421ce,c5aa5ccb,779d4a9c,62bc01f8,93643405,4329b8bb), +S(f826dbe,15974b59,f4c45c11,584ce96f,56494195,4ae5972c,876a5358,82c5ca5a,79babdd,ab8c5a53,4f527ef1,459ae3bf,990f9bbb,a0d1dee9,d6ce6c53,330b9a96), +S(ed712f5b,a2d886d1,5e7bfb43,9c57bc1d,c2f9adb3,9bcdb62a,29c05d2b,1b483a07,36830fc8,b64cded9,719e6552,2ac7c6fb,3d6dee60,dfe6ad8e,30c5588,e4a3d876), +S(bd372233,901475d5,a6a2e1b,e11240a7,bf866bf4,cdecea09,541c718e,202991f8,4a24709c,cc93a928,9706125a,8922c828,fc309dd1,533e702b,fbe0fe7b,218f5c65), +S(f196cfc9,50001e76,1e6453eb,3afb64dc,46c793c6,58304f0f,ca3fa342,66da40e,274b3da1,eb8ac4d9,aac325c5,187b1507,ea4e24b6,1a74c2f7,84e9218d,d4c6f68), +S(d0b4c5ad,98eaed0e,6011c072,a2de350a,5c24da34,5a60980c,fd1c73d8,3d1ea674,9cadcf76,7371d792,6b818ee1,b4be2c53,5cc1d760,bfb7c47d,dbd846c0,c2568449), +S(41051a05,8771b3e7,a8fd33af,1838b679,b13c480d,ecc065a2,a3386d9b,25c822cc,ccbf9cf1,df8ebe76,159ded17,2268f71e,c3f44e4b,2d5a2efd,5d4ff9b1,7f41f8be), +S(1d8f44db,4d7f28b7,8b911ca4,9f622337,414fb0b8,81b75ea1,e93a757e,36cfa0df,e486e0d4,83987655,8d4671d,537b47ca,f734157f,6843118,ec5a3293,839fb77a), +S(71fbe897,6c6e30db,b71530be,42cc3fd1,80d60acd,fb3533c2,c0f2720e,e1a9bd43,84560b27,383d8db1,5558a2a4,a8107878,4c62325f,60ba0669,69573488,262efa7f), +S(7f42e7a9,cc3960d4,98e05160,95477ca9,a23cfb84,675f1b0e,c38e01e6,86daa99,ab0c4acc,6ae1fad3,82eeab7a,e7d1450,6db254e9,6abc9a9,d8c55c9f,7e09621d), +S(8a9c65d6,5c400f53,db6a3f86,ece6e185,1295df9c,19a55e34,348d5de1,c6242448,87d177f8,12769257,ca0f6e42,e1db9067,2387b8fb,f0462051,59a55d8c,79377af1), +S(d7b721e5,332820f1,c8f16624,4e3ea5f0,b63117ca,983ae4ee,9017d44b,ab18b5ff,b2b5b7c5,9b0fe6fb,386e185e,44cb43db,76e005f2,a5cc57f5,4690841b,7de26d19), +S(fc81762,38dbbc4b,3969fa08,31c22a19,bd163b3,4327452e,467b91ab,940622a3,b5f38676,ba86221,b0a02c03,6819df58,f2dec21c,51f456eb,7213289,6f7a54bf), +S(54e5db5d,2f87f24b,6e62ba97,6d941198,8584b337,ed801172,82080190,821d2418,ffa698d6,3e953ebf,b755c0c5,15976246,b5ecfa0e,397051ad,136f88fe,81987e14), +S(b18d7cc2,4023df48,776ad32,b64b234,1ae42cf,74b19038,6f3de4f2,bb029bf6,a12abedd,ead9d502,eb28a8ea,d65b2a19,29ddd548,1a7fb93d,e8d43b94,bfdc8547), +S(22df5ec9,d2acaa17,473e0ea7,2ca2eb49,9622677b,6abc063d,1bbb3648,7bd3294b,4d98a1e7,8dbfa279,227a6090,b61a5831,a6eeec3,519710c7,85679d5,61b48a6b), +S(6ca320d1,fd3750b6,5606108f,43585ab5,fa3663d9,65428a40,28c17eb1,95790eb5,b346253d,d2912350,86ffaf0b,bf7af93e,3b4f44a9,fb820a53,286067d4,98019e87), +S(9df9049a,7cf65986,5c88b93b,3688e9f0,53eacd78,561d97bf,58358952,f1318a9b,984b2aad,3891f7f8,df36b785,b56f4967,1f572f11,2d87023e,6003b3f5,fb80f3db), +S(6e96057d,9827d88a,5ae84c28,c1aa2158,af62d298,2cc26c05,30d48d2e,d879aa0b,92cf1366,8b9784d4,25c16b50,afdaadf7,e7c114b7,783050c8,7715d6f5,1d273a36), +S(5719e0f4,60efeb2b,78eab426,ce8a0623,3f092d2c,97d9edf9,3d22d403,a07fb86e,5c27677b,63486c8d,3f2454eb,30d5d511,bee44e6a,5bebca46,8e1e7b38,61c69a12), +S(87e1fdf2,c83a698a,9fa294a5,252894c5,4f84b148,178a28f0,42870a24,e7ce1175,654db1d7,c34e78a6,e9120a54,6b9df354,b7d385fe,13a3522c,72adbd4e,660f2cf5), +S(9c915f39,cee954f2,3d534662,f2d381de,834a1fb5,13739902,6c1b6b97,53050fad,8b068e52,e6821405,8974c43d,8902a00b,d2aa49cc,f0c4adfa,fe631e09,ce658112), +S(d77ce2dc,6b94603d,c2093771,ee39e720,93150705,56ee100b,a4a2738d,b6d22ada,81bc70f5,96f31096,a2054807,aad9e9e,63260eb6,9d524289,71675300,8d71bfbd), +S(ef509ae6,9fa82146,ac152c96,d76313de,c1857882,a71e8955,270497e7,33a3af9d,a614aaee,6fa558ea,fe7d8d3d,4090192b,c8a7b70c,d4dbd766,a965d684,544e5bbe)}, +{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), +S(51509477,fb7660cb,b15636f7,a53b1e42,6066823,690af014,b227d14e,e428efc9,f43b885b,4db6e28d,d93b9feb,f035014e,8600b6f6,ad6fbf13,6eafd789,2fdae717), +S(484b85f0,516bcba3,ee08f829,97496e55,b3856c94,25682c80,837a8d65,16096083,8649305e,2f245dc5,d4a9082f,a29f9421,fb20ad34,2754d8a7,8ed0e3c3,ae933ac), +S(8fd997a6,792e739f,83666c5e,25bbbb47,ada14d89,d3386cae,2084dcc9,f546ad7c,f85d46e1,1eb472b7,3c4c3731,bdc3620e,c2991b29,599871e5,e215af28,9ef08cdb), +S(5fbed326,3a7332e3,104dab58,c47932c8,a3f262fb,14fa35bb,a5021344,e965871d,225d98be,876cb5df,db578da0,c25be784,5ca1f5aa,7ec273a1,7b9b3ad4,5998202d), +S(d3ac3c1f,84be4b7,1e47da62,ca159e02,5cbf45c3,a40b34b,c3f3b28b,b0bbf1d,b2b94603,f6769cda,f9a766a6,31d7f48,e194f51f,2250347a,34719c55,beb30e17), +S(6233110,a8f6b13b,fa99dc25,b912344d,1cac4cab,f25318e8,c7d1884c,9985a468,dd458304,e3782dee,71ac4c33,c4e45e3d,79dbff13,437f9b99,ffa991bd,778e0707), +S(3cdd0f3a,b2b52a8,65ad9d4d,d65e089c,e2a66772,a20d5dad,9768fd5,6ca5efe7,ee940af9,90ead7a1,a7916eb0,44470103,b73c39da,23288072,1ff245fb,93b021b2), +S(9aa9bf7c,d8b58d8,411fde00,84e05511,6f11dabf,a699a1c5,614eeb3e,4af41bae,71d72932,7f05269,a99de5d,cee09c4e,dcdd3b76,a4465d21,ceac33e4,3741ef6a), +S(aec139f4,4598b687,c14d01ab,250160ca,abf5d9e0,1cd69959,2ed2e988,22345aa6,d8307e0f,9018ded8,d883339d,7ebe1fa,8ad39889,d0853c89,4743e704,d5afa618), +S(7f99f6ff,4d46e361,8e55f46a,ed55b95f,3203ee16,848893de,c33c5756,1184611,bdb6721f,987283ec,873e80ed,450d8c5d,9e7e2a02,ae56fc45,9e69d3c2,d2016c69), +S(8d850e4a,e682f751,22cadc1d,ea01a22b,377ed983,c833a4b6,e5945fca,4d227b2f,94c22c5c,3864879d,e4b861d5,e9e33523,e5f848b4,fbbb8d3,4aa21a,85066e3c), +S(194b8c89,7231a783,ea9a835e,ca4b6744,f0d0fdc7,232ddd43,237fb622,14c869f,db961536,179e4275,5b9bb682,95d1c75e,b2b7a19d,d5084960,7d9622d9,cdf46937), +S(760ad01d,c8e83c2f,ee63caad,9a86f648,f6b72424,4aa158d9,66b05647,eb6cebb9,9d08a9fa,1d21e580,d34c9fc9,10b8c294,522379fd,c61fb056,895261bc,cc827a3d), +S(c2186e23,813e84c6,222138b0,1ab17c55,d47af51d,8e4239bc,1600fd66,d971cbc2,200a33c8,7f9e6d4,1d5d602e,6002089c,6246345,107e8b5d,5abcd35e,7203ac68), +S(4ef2336e,857336cc,dcf3c9a9,48685847,1f639021,bad06218,8a66e4a5,dbadd35f,67f8d186,e79780d2,b063e723,eef5531a,d95a653b,4289e98b,d4df52be,1b40e8e5), +S(16d03f6b,c21a2a55,bb0467e0,fb8668da,de88ccc8,cbdf562e,39c992e0,4cb66545,82a7c24f,b5dbbbd6,4ce566e1,94834d22,7127ab7d,ebce6fcf,60ce1482,4ffadacd), +S(edb76db2,a1d454cf,e8b9761d,951fbefe,49054fd7,fbc7e800,5051ae27,5b41e8e2,343aba4,56c46bef,17a254e4,df28e783,cb6b09cb,f40b062d,22a04aca,701b66d0), +S(b505feef,7c6f5219,7cd9b159,5db0e30e,f1f3be2,7e65001e,df1a9f4d,ed86af06,fbd1a957,d0a4e43a,652c2555,312ace49,92e2647d,5167c18d,86410bca,87705e18), +S(50e755f5,f14333c4,13be7594,34be8d74,3691156c,12a46ef2,c730839d,3871f097,a2925d1f,263c9c2b,32c4fe8f,4cb2b7bb,8cb6cff8,3f0ff900,213afd01,e5d7f01c), +S(6fb573f1,529a88c7,9f278108,82d9c8df,2a02ee28,84168ea,7ac41219,23d7a96b,e34f7cb1,e4c93ccc,8e7ec63d,4cd5c198,efba1a26,fbd24ca,2f09d378,30bf2589), +S(3cd35cf0,c96e32f7,2023447a,f9ada5f3,8082543e,12bbbebc,947fc3ee,215ec98c,24ae2376,10990d87,f4d9257d,45857e86,de05f6ea,b06c889d,c44d948c,dd5c4b84), +S(6b853761,e19278c8,11a01f0,499779fb,a2daec9d,a5ece88d,b25ee726,21f42eff,fceae86a,242bcc35,885a83fe,ca3807e4,13f46408,8d46f68b,860ae389,c3f6aae6), +S(d32d3024,34b1cddb,ab02db35,4144d96d,845028b7,c8b5b45,adeb3ad,84eba58e,762cc6a2,78b94842,7a7fac39,de201c91,c92f25b6,b472456e,67407ad4,9b977b45), +S(64275dbd,a2ecc977,3026dde9,f1a098d0,63986d88,8e958430,23ebae9c,82218f6a,e27c46c8,41829e88,2276ab9,e146635c,953db6e4,f1295efa,3111b0c9,40695056), +S(1becd08a,a4aa040b,51fe7380,396a18d4,1fac0c66,91093cd5,d74a31a3,2b2e3a9e,abc07812,ee13caa5,b040cf7f,ff4637ab,a9e69db6,7834efa3,2f864858,ab138989), +S(f9976dde,8c971e73,fbcd5ef7,50947027,711d5a7c,bb273871,cc293cc7,f4a1f732,408ca6e7,ceb96781,f0b2f4a0,af58f2e8,52ad5438,3399ddc6,e9a65144,282aebe9), +S(fa71702c,91ef2cca,d80796,ef0c6246,9ef32e16,8f5c9ddc,9fc7241d,f3ebd2d9,94491856,fd63fe93,7ae6e95b,b35bc6c7,85732cd7,7305a83c,65ff9ed4,42f5e11b), +S(b5ee5d7f,60398c08,f66d568d,1ce39d82,5c64c7d7,c65c030f,3e35e86e,c87b0036,d2c62b4a,71f9c662,9914ac79,7f34203c,eea50a58,ca8ed06d,582755b,380ec185), +S(7aa05776,3de6393f,a4b36ecf,5aca8f74,6e5e68ef,152065c,820a2207,80452ca4,58d54e32,840a40d0,b2a8a175,4138a62c,f054aad8,85e97731,9fb3fd6f,d9729bfe), +S(74b062cc,f09ac530,e607089a,8efb5a06,656dec8c,e1d1dc01,370e43eb,39594b1a,6d93d5e8,eb3244d8,8457e0ff,66cacb14,d38e286e,f42aa6c,3236b2ea,883e9f64), +S(dd56f2ee,f4dbedf8,ba5efcdb,c569ed21,4aeb7f0c,e3aed757,e72c91ea,9dae7642,c8a30e73,efb151de,d38785f3,2f5a9030,4e62becb,b0c470b7,1f049dff,7b75c9a), +S(a05bc315,ed5ccf78,34d888a5,788263e8,573a4321,7b0480fb,960e0a3b,e7575d0,9b8568a3,1b1b8f6,ad507db8,b6016280,28f43990,1c9e9f94,14ded563,6d06a78d), +S(c19022f0,5c316bd8,e5c50a4c,1a0a6808,b7a1a696,8ccec214,da81e039,53baafd2,110b1cbf,5a01e8f7,95d0b996,a3e6c2aa,3645ffeb,59a77473,e51c4810,665a415a), +S(feca2015,14edddc9,8aba216b,cc37722f,f6c60202,d16c6925,422582f,dfb241f5,61c06c06,d0e50e98,2d9ea3d9,44079084,e37b5c9f,9aaffbaf,c89d73d0,20dfdcc9), +S(d3d271c9,2b843b36,a24f1928,efd4f197,c90f176a,70539f,e290b150,24a4bd89,9179320d,bd5577e2,d7e58d67,131e47c9,118e78bb,18690f7a,74e9b38c,99cdf6e8), +S(2d12ae62,3f4b552d,4b7cdcd6,8f16c9e2,58d83cdc,b5fe567b,a5216cd0,6e94a2fe,469fca9f,8d15b969,8687e33f,4a6cb20d,aa8aee7a,a2911802,f6f26f1d,fb22d63), +S(55c31675,9974d7ea,57b0c133,b6e1f1b4,9ecf0c15,feaf74f6,b63d6d8,ff525a92,de38ca29,5f85b65c,4b56dbf8,22edea40,19f61207,f16b6364,6943d43b,4a959f14), +S(739facb8,74194ac1,e60a2206,10a82629,4f1bea44,ccb08f67,33fb30dd,79706bca,dd77cfb3,641a3786,109dcd08,700edada,8701732b,819f41f,14a55104,9ef8f38d), +S(9768a20,2ecc0ba5,8524d10a,c6d2c18e,611a1215,401a8ca6,571828cb,ae5759bf,5d35c2bd,2e7019e1,6e6bed11,15a16d72,dd4c5ce2,fd848434,4d8bd392,c4a680ff), +S(2161e7b9,858db630,a1bdb50a,6b13a6b9,829c302a,a836f0e0,d89f5a35,70065067,c565cffb,915ff76,7bab8f73,aba21a7a,9168274,d52681b5,301f76ae,a9b6daf4), +S(2a9fced1,fe2b258c,6de7b534,212419e0,c6c1cd6a,50257dc8,79f954d4,c351d7a7,887f8024,d75a1f72,e61807f0,d8c310a3,5df7829f,714433e2,214f9180,ae552e9d), +S(769d9e4e,8a1967a9,1df6e8b7,cf282ab8,7f9e773c,5dcb94ae,8af7b125,6254b879,53537a42,ffa46e16,63821069,f5bbc62c,d7a0206a,7407aa8,154c82f,dc390650), +S(6fe3bbae,441f902e,7ea02e32,44e3ecfc,6c45ca71,9bdd5e4f,23f7fb3f,540d45ed,d0cb3379,c858c9e4,6115517a,c65d3452,16dc744c,60a6f1c5,7cbaa8cc,f4462123), +S(6226690b,d8d94bb7,168670ce,8b4d18e7,a35f0fef,ab50c816,195f0b4,37fa16e1,cc8f53f,9d16582a,fd2be5b1,8db42faf,e8d83ce5,481a88a0,9c54ed2b,7023c3ba), +S(1e5d9adc,dfb56218,1d10999b,336412b7,d8fcb37e,dc5d20ab,8f8cc789,55e8a72e,221d5b4c,58ee5fc4,8cd34b1a,cc9fe795,2d890d35,4047746e,405d83cf,392184dc), +S(9e978fa2,ce0875b4,ff79d6bb,4f56a9c6,10d646db,c81cdb06,5430f9e8,4198b707,9608823,828dc9e1,2835e261,1026ea34,c9b4583,46ed41b6,4bbf8441,fd621e35), +S(ef6ed3e0,587229f5,aca0534b,f632fb13,f4067712,9d41350f,2e92bc1b,cc1d6f8a,c9852e66,260fa65b,13ba714a,2629177c,80030b2d,867f4e98,83e60ceb,402e5ad1), +S(3c104b7b,79c14740,46a032e4,8ac22ed0,1a8b8812,3fd1b457,977ecf3b,b82e2720,809d1774,22521dfa,f05dd418,e5783577,d542d683,8904cfe3,35d8215f,1ee63b6b), +S(5fcf6b6f,de14e372,11d15178,fe37c914,bb9802f0,e67cd3f6,3fe72688,e9fd2dfe,4e468677,2032e358,25c89a7d,28fa840f,ef33bfee,7622421a,f2393182,ffd8123f), +S(d3f81471,d6d530de,7b8fb0c6,125c1b0,596e4430,dd89a22d,94a516e3,3c1cdaca,31da0106,ebbd0289,c68bf092,381054ff,718a8bb2,aa65a9d,47a0ef45,acdb8e7d), +S(c1d365d1,98ff150,ba208d1d,486de98f,1cb9e23b,4e83c58e,40d15f77,9b12688,7c11b3b7,5b8dfb0c,ddf97f80,e3ee4655,1242897e,2152048a,cf4910f3,2b819a3e), +S(c935f87c,752efe3f,d1208536,2c49321e,ad521ffd,b11fea5c,24e1ed72,cea77a28,1cd31bc4,46b90688,266b9f3c,74426c89,ae4c442c,4184c3d6,206deb3c,a92d1fe5), +S(2a88eb26,49349f3e,7fd6a43,78a8fdeb,86df60b4,dea3416,1c811a59,44a98040,e7fed2fc,a145255f,a06e13bf,9bbfb1be,6e15e330,9fd624ad,9b352c8f,1caff852), +S(313ff59d,1dceac83,4c70fc63,f1f32df6,ceb4253f,8327ee35,ce4ac575,9ec2821e,d0ca06e1,30d083eb,8a7501a1,dc80398,e67a133c,973121cb,377e31d8,fc4bfa14), +S(ebb8d7d3,81dffa3c,8ad10bba,aada6598,98ba7694,7662bfaa,e5acbfb4,36e6931,f01e6b28,fe03ffb9,42ebd387,a29c2896,32bfb526,58a7abb,34c10bb5,24cacf8), +S(208055ea,a3c94762,5e9cdbe6,91584b6a,a060d127,63f9a305,ca360baa,9d601a7a,ff382321,b7f3b513,1551c441,f6a8365,13d16c74,f3b74345,a5100ed4,de88e00), +S(1579f653,1ae0ef0f,b9da909d,959b82a7,1e158400,b5d34f5c,8d66667f,cc6e5c92,50f898cb,60c9630b,507bf817,fbfb7d3a,29d3772c,74e7a7d6,19bf4198,7a09136f), +S(4b40b410,56a43404,559ec18a,1bb18544,ad8896a0,c8182f51,b9bd0b7a,ca178f51,a9f22e06,79e43402,d6397eed,285db77b,15ff1073,6a367a95,3a439961,8cca3fac), +S(67673db1,2edf2be8,c0d330f,b26a04bc,bd0e6714,5c7b0984,11a59719,e845be8e,c34f45ec,ae724308,2245e950,f62b0c2,2b6e1b1a,eaf5d8d1,b503d9fd,e09e8cca), +S(8c1ec49b,81d8e41c,3bffb5f3,7765bad8,474f647c,833318f7,b6227608,a1f8a9ef,fbdcb1a4,a418b7b,5398835f,8f68de59,c7430754,87f52c50,a968c40c,35f3149e), +S(d823fe57,c0934eb,a2f15d1e,b445418e,e5092ffd,b3241d94,3748dd70,9e4d0733,b20ce02c,69b038e4,a5e37858,8dd0dcc2,f2433141,a2fbe473,e56d860b,379fe4), +S(d16cd142,a198d5b3,e2e855c3,b1b900ba,12d0e241,c914377c,1c880cbe,c3e9a10e,e0fc81d8,9d32e421,70161026,97e51be3,91a984be,739b23fc,6e3d6649,109ca782), +S(34353521,1fba36f,58fb6f55,aa0ccd4f,4052ccd5,8edccb05,164e82bf,111b0af9,4a9ce50d,2d0bbb0c,66a74a00,c91d5f7c,92b416b3,f0bca8b1,38e5f456,fc48f6fa), +S(254b9165,d4afe2c5,eb4360ef,2240fcf8,f8f4ce78,8237bc4e,c8edd63d,92a8b4fe,3c7267a9,5df9d1d5,96208351,1739729b,25d07ec0,53f30233,acbf1f88,b9cd1f7b), +S(a993528f,cb239c1d,eb824cfc,41ea09ef,72cbec61,ebcaf0c,4ea7890e,3aae0f3f,78b41a68,6f832e10,576820f3,552b181a,ef3b133a,fd5dca99,c7fd7b7b,247336c6), +S(dc431b9b,2d0002c5,d46079ce,463fb29d,6fca380c,4edf8188,34c354cf,7f123f13,32ff1932,2de938f9,9be1fbd3,3c553510,8c1dc5d7,caff8dd8,c4db6218,54b9bba9), +S(bcbc08dc,4ce90c27,54b9a79,ffec9320,3c78b60e,adb3f750,2cecfe12,d475773e,fb691bf6,8394b040,d2049147,6ee7ec8c,6d69baf7,a2ebdb5a,3b455088,3285e468), +S(20ab53a0,d5a26bab,ff0700c8,945e2487,fef10dc1,1c523b2a,14dfa8e9,fa6d68bf,c6ec861d,dfe29d4d,1a23d3d0,99802f20,ade886d1,257f669c,3315ab5d,effef915), +S(c58dcb0a,8700faf3,55a26e39,58c61617,3c2d5c07,824041da,71dc5d0b,6bc351b2,78ba4b31,5d716184,9bf53d1e,94a6ec8a,2268538a,58ce2f17,fa1ab6eb,beb9810d), +S(3d665b4c,831577a8,c536598a,3cfdb3b,85e1f45d,566a0b9c,a6852ae4,171be6b9,e6a349a1,36827310,e362adc7,cde91f6d,e6330122,592d1dcf,a7917d1f,8948fece), +S(6f8d4774,efe7b37b,d26f5849,22b78273,cc5ad16d,80f0f4da,8c54e167,33c5c7ec,b63ff2af,2fed919f,256de972,bda71f9e,e4a5256a,22782a0b,c06a7a48,57876d44), +S(97daf45c,8666f208,ee72dcad,c4658613,b8466605,be2e83db,69104973,5516b1df,e33deab,5ee28d64,b818e2fb,6acbe9c1,cf060142,210235b0,dbd9514a,ddb57402), +S(c712fcea,95039f2e,a87762fb,5e5fcba3,dbf7ff6e,658bb64,71a4f890,88e6106e,174f28a4,9b38ff36,1c28941c,b89c1d62,4606c269,6619d157,f05be89a,ca550fd7), +S(f42d3ea6,d791c681,ef6c16ce,9ab763dc,df7e1f54,42512b3e,f9ef8904,f6f30927,abb04412,3f2f1329,17cb8a01,26d21fee,59606715,6a3735cd,4cf2969f,a506eee0), +S(a77b7262,61365881,c1aeb570,12555deb,6fe98240,cfebf712,386fca2e,efe460e3,3200fd50,9500ff2c,df4bc618,f43e705c,b5000762,dc3bfd57,4ac66722,edc06daf), +S(82af11e3,34b229e,16877594,b9f7f157,8cf51255,c7521ebe,ebab9a81,a2b1bf76,3182824d,7afc4ee4,2e5b3965,65f07bdd,b47d0f3e,39685096,e96bf5de,4c00f47e), +S(b015e32e,802b997b,4c8db911,4cd0a3f7,8fe91699,a9d3c344,f03c77ad,508bb842,28aae64f,70b35de9,992216dc,ca1cd63c,d41179e9,b7ebee7b,964031c5,3cc56a00), +S(580ae367,e9118f01,858d82d8,20ed6c9e,923f3d,be934b3c,d0860fcd,1fdaa714,94a96e04,8b7d8b49,fd12bc04,d6a0f7b4,a0bd671a,dde14d92,9d8eda25,ef3ce73d), +S(b24a5ed9,65ed6463,b30b0be4,ee048957,2c62524a,50937daf,e863dc0e,4ea3484d,ed8897b2,3354ddae,149620fd,a3f7e17e,c8a5b46c,fd0d955e,7326ab1,2c7542c3), +S(5f9b9a03,2b21c8e1,31e13c2c,8019db2e,524a85f6,3ae03014,d27bca62,971b938a,3f954d07,f7ef5c7e,e4b288d8,3722e458,d38d5950,b38ee4b8,35ddb017,68a1680e), +S(61d23399,c8750a26,ff4220ff,c3a7564f,f6df92a2,fc133ee6,c9228ac7,56a77b8e,a3ea3176,80b9fe5c,25c74f3a,5cd0f4e1,73f9a47b,f13c6757,3ad9584f,81c0d0fc), +S(39129baa,19373bf1,db83360e,c1cf46f6,cf6041f,7aecbdbd,c0cd8155,4047f4b,e524c633,cad2a058,3826b241,a0f9f90f,1c29aaa8,7fe9043f,61f243b7,35966525), +S(9f4eb067,ba8943b2,7d9c90de,e3e3f570,9d470e03,4400b49c,8863852b,e42d2d82,7decbcb,df928f29,2359c31,5c4e9d1f,7c81daeb,4153b6e9,835fb10d,cff87699), +S(c3c41675,59499453,4ebfe29,32fc3a8c,fb0bd4b8,f58fcdc6,111e68a1,2931d68,9a6e07d6,271039b8,e3198823,589508c4,353888e5,46e8a759,873fca67,a687aadf), +S(389932dd,1bdb022b,aff12e7d,96ad188e,f2a38d,e07db076,d4ff0292,878a581e,591e7dea,d8378307,82c9df98,3eee4623,d736bf1c,7cada52f,9e9775c0,9b2c0e7f), +S(6a24296b,4ed7585b,b6e1a7cf,a6bae760,bd87c580,c5136641,ae890ba6,c6aca188,d389a8dd,df70e094,32a77278,89142e7d,7a1ed1dd,63e56961,14d4b9a4,fdf7d48e), +S(a3adc560,82a6a35b,76013450,a511c437,29000a3f,4df1cd21,d5a37aff,25236ffb,9e298b2d,73533849,d981556e,c4ccd2df,2cf8a84d,49fb32da,414725d2,e8bc8172), +S(b1761d8,b63ede1d,92aa5d47,9de387c5,10085632,dcec781d,44b1cad6,ff59a49a,16e10005,9f5b54eb,fde33551,d68eb053,a91a17a8,65703a4b,a0e4fcd0,ee35927a), +S(da2439b6,9512ddbb,8a3bdf44,c3dba4ee,1047594d,f274a33f,db442c6f,3313cb9,23a2b190,cd307fd,354474c4,95e6b0c2,df104478,e337e7d4,9acf1204,666f16bb), +S(5247030d,514afa45,41d07a69,e5670aff,71d42ca8,d6258e5,298efd35,2ea5912e,76a36497,2edb4c57,e29d6de,9990e7d5,f542c84c,764831fa,86ef5ab1,938e27af), +S(8d2dd8c8,80fd50f,94fa6552,3270fe1a,61c92810,3aa1fc44,d2db7955,765e9f6a,1a99666d,2f76e63a,ed386a7c,25a6e66d,cf3552f8,5979cbfb,355a91cc,ddee161e), +S(f964ec9b,b42fff6a,87d268fb,b6f58bce,c53bbe95,5780f6d2,765c682e,3b29ee6a,f1b5d480,1aea1445,177b7e30,7ec2ebdd,4615fefc,59b22312,1ef80277,45790fb5), +S(388ac82f,677422aa,c6576748,59fe634a,c9768335,b9f6402,dc089b40,186b8898,5a93f486,77033639,b9c0861a,c82e6326,e7a20e73,9fb651f7,ca99c3b6,b56e0e9), +S(e67c3d3b,760b9bd2,10cd6ed8,d261c0a9,3a24395b,5bff814f,18d1b1ef,efc5e322,370323bf,db8d6a31,8066dcf,439c9447,72c8a049,9df2486f,426a1a4f,297b3c47), +S(e3cf3c48,39595c97,a6efef6,98e75220,4d6ae09c,d4e7c231,24e16902,a175b95,91e50db9,f3a1a3c5,634fc2,6dcf9010,6fc27d4b,aa24e659,fd247c5f,93c83593), +S(b16d475c,c60b5286,2bd250b6,f4ca284c,69e30698,96eb3633,18ef6b7d,3928cddc,ef3fe367,312a3e06,b992f862,8e5b0c75,5b6f6ff8,fd62cf8d,a0353a52,1e6558), +S(758a7aa2,9433f0e8,ddcb6e85,70ffddee,2c487f7a,7800e6ee,7eaea634,c8c3b7a5,cbc5ebe,9bb4f480,2d50f99d,746065fa,7c484a84,30643962,50508ed0,a75ddc49), +S(3c2b2b05,10564b7b,7f53dcc,406d4329,e0faae16,6259edf9,ef26d1ca,308f0352,19f44e13,cd4e6107,2983cd91,81f942a0,f4cf0f4,8a10426b,c3f30dcb,8693af36), +S(ff644ef5,ec4f91c1,33ea443f,d783573e,debc003,7f74cac5,af866a37,302cae5a,50eaed81,332176c4,20e63c38,9ad9faf0,75e45a26,8119342c,b635231,1778e3ca), +S(2ccf4da9,9aa616c1,900f566,89d356a5,1396526,d488b635,f10c368,ae066c2d,46da8b3f,ef5c7994,9f94721a,2656b55c,6946d493,49a03aa5,fdf90c0f,4a152ed5), +S(5cf33ec4,cf6f3af0,18e94ca3,2d31845c,f1c4764b,2ccf3992,48467c4,b3f11924,a5cf6368,c5b617bf,6c69c7f9,fb0c769f,285720e1,432fe54b,def57fcf,8fa25b1f), +S(5ba03c13,93b9a100,928e6e3d,a0cdeb2c,8be4d653,93a233a9,b7811e4c,d242da22,15f9029,4890222,960a70e6,8046c2c5,de15de6b,8ada4243,64357c39,b11cedad), +S(ff9cb0f2,62e3a7b1,d5ebe749,112c8b02,4c766789,c2973446,ca2b8884,e5eb1035,f5194ead,3d090604,86d7f0cb,f72fb540,273eebd2,7c94a199,6f9f35a0,3834886), +S(b747105a,da190d97,48094f54,ef60d1d0,30e3f57b,f32d5477,5c6929c2,975a3978,18f9265f,b2cf77ca,f5aa62a1,8e82933a,2cdad96b,2866b5ed,c18196e6,97e9565c), +S(48c6d033,45abe61d,aca1dd55,8d782685,d05bf49f,2897fd37,ac112e98,1feb0ca9,853a71eb,1a1dc7f5,78adf995,a254e545,a1effac6,7afafa22,cd2c6be5,d9915b42), +S(27d839e0,b29aac17,b84a7654,b2e60cc4,6b8d02ed,8079a525,cd0463a7,f21cfd2b,9974f97b,504bcbeb,d8d3f3d1,1db05229,69a72357,2de8ed56,ef877402,8a435c55), +S(8fc52f0,3dc76184,195d95ef,baca3ced,9aa1b3e2,5f36c75d,65e67d4a,28337ad3,6e024d2a,ef78ac8a,d59450cc,de13c8a5,2d23eeeb,13d11cd9,7b4a9fdd,be716a69), +S(afcfe9a7,44837fea,d3140ce3,4e281510,5fa23b8d,1f497440,8d6ac3c7,70b46c6a,253c825c,8bc94bbf,3dd2a33f,f6eebd7e,203a34,69858d9a,6b48638,5ca557d), +S(e4a30e5e,16db32a1,83532b32,d466e985,d664be39,bae1dd8e,2e34ea05,d8575028,58bb5c1d,95922c2b,62aafb36,6bf22c8b,35d8947f,a082c4e,ce9d8ea9,cf24eda5), +S(76ee906e,b69e9ea9,667d4582,99c6c47d,c0868bda,ad8622d9,b8a85a9c,be6faca,88f10eae,25307ed8,e519abac,a00f721c,8d08e1da,344bdd62,5f6077d3,4295f4ae), +S(bd58f596,ba832cb4,2e3d7445,428f79c1,59da797b,317cc471,88188f3c,715d3cd4,8bbd7cd1,a511e88c,d7a904f1,6db60414,d4555337,1f72435d,cde9b5d8,715d169b), +S(8d450276,b722186d,2e93ed73,3e45fd3c,660225a7,eea0d90d,bb6b7370,1b2dd80c,271816bf,4c5676a,86efe5c3,5ddcc606,804f4cf8,15d19937,16733964,e00d552e), +S(7dad1a19,4b46b8de,f3d16ee2,6fb3d1b2,a9d9c026,c5923bb3,f4f88bfb,736c2b7a,ebd7b4fb,6afc3648,746823c4,d179687d,6d1b41a7,fbb597af,f028844f,b6377681), +S(de25311c,898c652a,40fa3c4c,6022d195,e4f5d336,5f8781e2,2b0bd1db,5c733c73,194b36a1,1d99a3c5,4e7c5e7e,31846b12,4229ea92,74737a57,22056cc2,56f3723a), +S(cb204893,6466f088,32470071,1afa626a,a8289325,913f28d2,f1e17ef2,8fabe7ff,c60b4373,bc81fd85,b871c930,827b6833,cfeb6708,c40c1942,676cd766,ddd7b390), +S(6ab3128f,9735753e,341ac4df,9e4daadd,aa5034e4,831b9681,15634e41,da047af5,ddccce3,47c9c588,88169f04,78859080,27c821e0,1400212d,4e40ebb0,999c9464), +S(c4b853bb,81d90026,c6463268,6440bc6c,42cb7afc,513a748c,dbf09039,82e98774,6ab31853,982a0b98,48173818,215f13bb,940248db,26eaa964,8300dda4,1482850f), +S(4a489c6e,cd52b4dd,33956733,977fa0d6,25e4f721,d5389076,91a4a251,e1c65902,7f7d73aa,23f31098,c5522a38,1172fa16,a10b4e26,9457c09d,15c14954,bcc794f), +S(d58a8e44,50f0ad1c,298d3add,5ae874a9,5734c031,3d2f27c5,5966c468,d8b0bd3c,7bcd6ddf,d7759f7b,3523852a,704862bf,4994f6ed,4a85c430,e9696d8d,365fda41), +S(fcb440d8,6d7441f7,52b1aa2f,28d4d5ea,ec2fab70,a7739b7d,af6678d5,837425e3,ac13b9d6,a0022a93,67d81f8d,f7824b73,11a98184,30c5bf50,89f21a61,4b1d3686), +S(3cb6a8f9,b1f8058a,dd2f9076,19a3fa97,8f13089f,fd0e41bc,8ca94760,9dfa9762,4968d4a1,8674164,74d98e8d,7110df5c,8c1ce11,903bb98e,4fac0a4d,1082edd4), +S(2e719fb6,2c09e74c,46fbd39,abdc8e06,69e38992,4424a985,60aa405e,99ef47b4,bfccaa88,e1105982,de52f422,15c5cfe3,a82b7c4a,b5e0edee,46ae657a,46bc6d30), +S(809d777f,f7e7d3a,d02f4c83,fab4e618,15a1c29e,caeb6d4d,8573889e,33035a5b,4d04a535,67a1a24f,f04f4e8e,259ebef9,cac4e89b,31cd8135,2f7037aa,da84c69b), +S(6538984a,31b67a2,2bd11be0,2daa7449,2abe195a,86c08fe9,d1465e99,e08a407e,10610211,327949c1,f8e4b459,831e8fcb,2b7b4db7,c53dba33,acfcd510,aa22e935), +S(e67dac32,6ff78b27,eb24b489,85d1ab53,60441d3b,62258756,74741a67,c0b37d33,48065a5e,21dd1e4b,b5c3a085,16f00aaf,a57e98aa,9c714663,63d168bd,90b72337), +S(6fee80f8,cd36865e,f4548366,70f9e40f,3ebb2754,aed3f5cf,1d73faa5,e7e7c72c,d3d52778,2d4675b0,16addc86,445378c8,5fe38f75,3e3bbdb2,d8a73e12,461a5d1a), +S(9940330,2dbfb6cd,45a98327,e00fc86d,171b39bb,811a0af7,bf0916c8,b04fd369,2a5bb90d,126b586c,6cebfa67,7518d008,b2348e11,362a5636,8e0b1d0f,8046aee9), +S(43224e6f,292a71e0,3e1b3168,4a30fa0c,a681fe1,283dabaa,f5629633,5dfa242f,b6caef5f,77e5598b,b8a477e8,66cffba2,30927e28,d8e55b3f,fe71fab6,90c6f567), +S(804e1a5b,8e16bb85,f041f46b,a0fa8ca6,a65fa2b3,48432e66,ec10eafc,1737ce1c,2b77d1c,b1acd0d,878013d5,465779e3,a55713bf,2be71990,7471962d,e07857f4), +S(f52a94fd,6bb9d519,3692059d,868901a6,33743257,3ec200f9,61b6d964,d090f849,33512a99,94327132,501a0fbb,166ea870,f7bf1ed1,657d3080,f4d7ee1d,acc85128), +S(6febda44,3ab8d9a8,756333af,86ce177f,32d782a6,114a7464,4b1fd081,9a436087,65fb2b1c,8df03ea4,2e72c6bc,82e2a39c,57f7912f,8f513fc7,bf97a45c,4f9e1fa4), +S(da0532a6,176166de,9350ae75,7ee99a5e,9502f292,f842e94d,74d35230,518876a4,b3ff19c7,f141a7b4,f24dde01,a82f988d,8178555c,38e0816f,e1da20fc,d724f510), +S(1db46fae,ef1d0a54,9217028c,1fcf73f5,6bd573fd,6c4b1730,f3cb99bf,2e163ba5,496640fb,ab04b388,3a35ef75,5d2a0ae2,17522488,a567d7f1,7bd951b5,98ee7456), +S(e14ae4c,2f1483e5,a580d3c3,6ff82525,a6df21eb,ac91aa5d,39391e5b,650b5436,d54ba5f3,2db765ab,b8f6e464,5320cba,c029c13c,2edec227,d57d3cb2,b8b6faec), +S(a382424e,a89563df,e7157fd7,b438c992,604a49bf,1462f590,b84591f,88ef7e01,b8a510c1,4bb0f355,6d432ddf,859d87f7,9f4c4448,522bdd86,a4e99328,2ad6f960), +S(266c1844,3daaa40f,821c1ae7,7da98daf,aab29b79,36ada9dd,238c5fd2,73b45614,e3f38773,27910ef8,d5cec282,9b7d8b29,83a184da,870ab8bf,4f43e6dd,4f0cabc6), +S(e7b29b98,b1cea663,3e686d67,19778d3f,f6af2d87,e93bd576,10c95232,e8ed5d29,ecf316db,b2a445fa,2ec84705,b453314d,48e16de7,6310b78d,a19f8a45,36f27bd1), +S(d36a3000,869795e0,9eaf616b,6e131204,d341db61,7a18ef66,e133a59a,acc47bb2,24b6bc32,487bed32,9d9bc27d,b08ab6e8,114bb6ea,e813d80a,c3dc7add,9ded3979), +S(c9783ed7,85dca51d,55e55a39,4c4e9b91,9c4d4c3f,ea461afc,51eef4bd,3a351cdd,e8e62138,4b4aa109,6d269fc2,a364a3be,e4584bd5,c551435,3dcdedb0,9037bbb8), +S(764eda83,aa90cd1d,9cb96785,e4df2614,aba504bc,33403866,b6f13b38,521bbf79,9d1fc736,72bd368a,cf6f9d32,489a81ee,782ef74,964c44b5,6dc4bd2a,ad4363e6), +S(f757e8d5,aae09922,278d2301,77f1c80b,5466f76a,f9f8d106,f0814d0d,b152484f,83ef8bdb,17c78a8e,1a4c54d5,d356170c,79ad312,6d62ef94,94c1b683,1798adfd), +S(a180a3ef,400e4918,9cd8b3,e12b3907,5b268be8,4c83956e,9e08c6e8,230b7fdd,ebd5b8c,75f1ecb9,cf2c8ff6,e863447f,7c821219,8944686f,b1b758bd,ef9e84f3), +S(5ed707bb,96ac41d8,8d85db26,fef84af6,d5f7d8d1,a680a0c4,8f23a1fa,89e37dd0,bf45cf6b,d0bb550e,590dca49,fe2b158d,e91c2835,3c75f49,98c1c446,8ad03e8c), +S(f8dc28cb,f149265f,6b6499fc,baa6ecaf,78300a37,2dcae813,59cd0d8a,e00cc52,179468ee,d7fa52ac,372cbf1c,c5974532,de4198ec,10e75f95,43461ce,fff87415), +S(8ad564f9,5abb28a4,5c807ce3,1b487918,f6f963c5,ac0cf977,c5fb7957,2954d080,acf894e0,35653758,fbbcb5a5,63d5c196,60d29b3f,315a784a,29168df2,98c8053c), +S(14503a2e,83fe0cfb,bdca0382,e872da3,bd7b6d6e,96e02415,258a8989,55a18e5,8955e448,67226b0c,c529f16a,35a5297e,dee0fae5,228ad6c1,257a0204,93334896), +S(86a30681,82b8006c,282bed7e,9b4654b3,ebf5c4ea,90c92311,a56a876b,3d78d183,1213bad,e418b68b,46ee5494,a7dfb32f,d74218ca,594686d6,f5b8b6a,26a4c3b7), +S(8b226ca2,c060c2aa,13e581fc,9ca8e471,bf8d1c4e,228f9de0,2015465,43b7c70d,4c264984,52085c7b,e549c4ad,fee6e710,9cc7b9ad,b94e0ad7,f7798930,917d1509), +S(ebd1c317,db586e4a,3792ecf4,4b2e45f0,ac727360,2848667d,19efedf6,c4c942b8,7c252d24,d2639fd2,2c0a7ce2,fb277157,f421e3b3,4d1e0f6f,ffe31410,213d06c3), +S(1420c547,78d72aa2,1f54a5c5,83f82c02,b5f3f64e,cdd16250,3741f4d2,c01d0b67,ab4ad7be,d53adc3b,158b7cd6,7cdffade,beaf126,f17b8c32,62d62ffd,764bc686), +S(e9728ee2,3744dc09,1e798ed0,786d7ec5,a31cd5f0,d2e019ae,3f52b8c2,42973d9c,9f0edbe8,edd17b87,3403b94b,b9e8fb8,62cc4463,52944322,8531a365,107c8861), +S(c2c41287,cdef251c,518c1820,ae86f38c,ac816984,b14f3fa0,4060a425,699cb291,ba991c3a,2d04b449,5dc04fb,6bf6b820,a4c62a01,f76dd8d1,4897ebbb,cb40825b), +S(6a63edda,8380737b,365e58fb,3a0fe1c5,816a8c05,f24b33f0,ba0c4473,45a0ba51,54ff065a,cd9c9ce2,876b5066,4f56599c,f22fd280,ae8fbc2c,92c38eac,c0c0fc1e), +S(63ad7964,e9af4b60,78319699,f8846900,e41a159f,c5d1b924,bbef3fb3,cdb2d098,bcc3e4d,2c17926a,d70f43cb,31c4a2a9,1a89a8d,3b79a8b0,1ec9d9c1,49b606c3), +S(c9e80434,cac460e9,bc245b8b,6cf501ff,3d64bb7a,a4ea5dca,c8932dbd,609e8354,87b2ee6e,a42e02a,9fac38bb,c013391,b9af1965,dbce484,c5a3bc02,86fa6172), +S(c547f029,6388b9de,f6502985,2ebee9fb,f9e4b8b7,f7a320e6,c7576d9e,e30ba1e9,a014b375,7c859ac2,29527273,78886397,56324353,25906a28,ca6e737e,acce884f), +S(a21349a2,a171bced,4034c1bc,f79150ff,84830ee9,95bac1b2,b1bedc13,c95f0d31,ea32dcce,6af2b400,4cb4213a,a67f3448,2b09672b,546e578b,28adc6b0,ce022db3), +S(4457ae67,185fce79,deff71cc,f73de43d,23a9f4b6,f374f637,c8a99b6d,2d582d7a,1278a7cc,6f1a5a6d,58824021,af2657e0,87ece4ab,fc5dab51,f85312aa,f6468fb4), +S(4c6743de,9af3d665,a0192f80,bd015fd0,d16fd42d,8d026175,df9cb80a,84e0fcb2,86cfa514,7d0a88b3,6a0b976b,eb5530dc,fea2cd7d,b6fb0409,bf1bad24,33bd6aa7), +S(6d591172,8f3f1fa1,3fdf09cd,7045404,d150e597,64704152,1ba15b64,a8782af1,fd22b976,4e7007d9,ddcd3b89,9f060e45,c59e4a9,470f4d87,153581b0,11b7d2b2), +S(1aae2b60,88895bf9,d199f120,506faa23,85c63220,81047e48,1dd7d0ae,6a6f128e,c3e73fe9,db489a15,87ed17c9,88d29145,848bac85,134857a5,7f2233fe,b558f030), +S(8a42240a,ffad26ea,8125ba65,2ba897c0,69eb1e7f,e821451,4521519,817c3fb7,927c6b3c,9b35482c,55199381,b4997821,70be3f27,3a1ea14b,97dcb193,901787ee), +S(a4b366e7,8dfcd7b2,3f997552,663afb38,3de01400,2798e0d6,b20ce8fd,43a78cf3,b6c6dc21,b22334bb,69f6db03,4860840e,da5c23ab,d3206be4,cfa3ad3b,b1a41c4b), +S(44b8576e,7a2cf334,d5e9db51,86605975,36504ee2,3c138e9c,86fa9589,91a8a08b,79e1e4c8,2a61e956,1bd8076f,5fa8d029,d5150348,ced9a145,95b9a1f1,82a05d54), +S(88efb8a7,eb91f4ea,6b97a97a,30bf21f3,94326140,ec60eeca,23adafc1,fb11ae22,c540c164,542181ed,38036b5c,417a6b22,819c4818,73da6882,c394d87d,21011fe), +S(3d939a17,76686fce,f2e544c1,2406e89a,aa7256d4,8415e59e,f00e3599,1b630682,cb784214,6c633d16,4f3e47e5,d7fca1fd,bb46e76d,d94b7588,d21d6ab1,f6e1ae97), +S(6cc31f3e,3e5e3dc1,ff2008d0,27ae58a9,a73857e0,26d1d304,3aee9f90,664aa53,15923b66,8ba62960,f2938e29,9c230e02,fee1f3b9,936c4658,36f685ed,e0863073), +S(c8c42052,4a7837e1,57e5b15f,85c4768e,883148b9,bc490f12,27a2ffaa,9e5219ca,99f0b3e0,6c2c6bdf,6a105e14,5745e7fa,328bd209,720157eb,c665321e,c99c708), +S(fe57812f,c8650a76,6c34f0dc,468f008c,71db839,331038ae,accbca1a,30d1ab9d,27f732e8,23ca34a4,dec45aad,7c2a4cd3,43ba0cba,f2bfb75c,6ed6deac,2e524249), +S(451482a6,1cd89411,e533ffb,d5e3326,d1d6d7e6,caa31fe5,7531f892,5333a253,c03602bf,83bdd5e0,edea9cb7,328d8315,d568f3f2,be8ef1c1,7172c940,768ba474), +S(e3aed935,8a98ade3,1206182a,66254c6e,4215efda,e5f75f0c,d72923d7,2d6caa73,f357e418,4cb28038,cf3d4abd,c9cae8e5,90a6da68,a984c169,242d2725,cf5b7829), +S(26f048ff,87b2f0be,2559e62e,9e66aeac,222901b9,59bf20f1,df872ac5,b3172107,49fc51e,712b390d,9fd38df5,2023112c,85f2f29,5521bc,4ba8334d,7a133a0e), +S(f77e22bd,5403193c,4532800f,2db0a283,d0c000f2,18a09b89,d8d10175,184089ea,7a8f9b5f,6e94cea8,dc8c4276,a7aebc47,8c2d296,4c37e3a5,5db10ec1,10c2d385), +S(2aa4ea08,d6580fe,2c0fd0b9,cb266837,7b6bf2e5,853adc74,bc58804f,b8735e4c,81c26240,7984cf2a,8ffedaa0,dcd359ae,9772773c,534b9075,9ef97d49,755bbddf), +S(93de5e98,8e136037,37cf4d1a,284125cf,2b2cded5,261b7b2b,9759f7a6,62aa5f53,5d2f3168,2a9c0f64,caa483f2,1a84d28f,3004dcd9,5d3344c3,e67b28b5,61e74d59), +S(90f86beb,d1c5534b,105b7618,606bae2a,b0fbdb6,d4fa3f4d,f78f12e1,fbb81ae4,c887f5ca,fe5a0803,9e9d16cf,e5f61c12,678586cd,fbc7f65b,ab01b60c,be5dc191), +S(e0a415c0,68e137c3,b5d3228e,d9d22d8b,b343fcd3,916f2e06,f2499528,1cdd5948,140cdfac,a0276f79,adfb826f,4c9b4a6c,f619034c,a7a3d0bc,9d948abd,32320e80), +S(e9f6cc7f,e29f218f,be6aee63,32f731e0,5ab28caf,254939dd,46e3fbe2,5fb6948d,7c91feac,7fb402d7,8f71be8d,98dee704,c1a0a4cb,43c319a9,9b78e555,62349a39), +S(136657f8,f5006a7e,89bdb5e6,e9a7e477,f78a29f5,ea5ab67d,c948a9af,680afdcd,b8570d97,c025fa85,6e1c95c7,a70db126,f2588430,cc01da2c,81fa49a,1e388b4c), +S(2a11afe3,c4e73600,5a0be836,60f7c99e,6cb0acd2,b6a0745e,69d4c1ee,605cbaa6,a28072d2,50bec98,ded00976,d905fab5,91aee0f1,997386f2,c798b102,46bde95e), +S(d7ceade,fc762de0,36ae242b,588ddd80,ad002019,aa885514,b98545e4,30ebe453,20e318b9,67c2f786,c53f63db,8686acee,84bbb7c8,3435b9bc,e6c664c9,8832fb37), +S(505fb394,d184e5c8,d9a826d5,55ba9525,7ffc00df,3c0ede33,7153bc89,86e1a925,c30ce615,771a2219,40d3987e,52af5c30,8fe45b41,d5078eb3,821fcb8c,9ef722c6), +S(330418e8,93f9360a,40656da8,883d1fc4,89441e5d,5a533c1b,23480695,8e67ecb,2103e7a2,e02ef7a4,c245b479,f6778cf7,e6419d4,41bba641,6f6c18ea,8bbd2459), +S(1467a11c,31ff8b94,2270cd53,54297b4d,e22aaa6d,3aae02b9,51e7f998,e0345eab,9d3e32fd,bce7daff,10685a08,afbaa791,bc0ebc38,d7095045,1b227db0,74a18cf1), +S(d58c9888,fbb41521,ded03c08,fd61032f,c403eecb,1c810032,e5eed64,a93c878,cefe41e4,8431eb2b,6c6e9877,fb83ac78,dffc5147,3c1e5929,28539567,a08871a8), +S(16169695,7d2625ed,b6aa9bc3,9f7dc514,e6c5e60a,39114c34,b960874f,c8c66c82,fff007a0,918a75ed,5bbbe234,dffda70a,7e17006f,1e4afec6,140b9a3,b762969a), +S(7c58b323,1bdca93a,a19b84e0,4312a347,5addc621,91c66fa5,a4bf97a4,b8b5552d,b1aa2ae7,cbd6f1ce,12b33408,513930c5,6335758e,f28f2a8c,c239f727,55ff37f3), +S(7c40af3d,d3e774cb,7c56e809,23b9fa92,f0cafb2b,f1eecb22,9c204cfc,58ef311,4dc0ca37,90e023e2,83b8878,bbca65c4,28b7e89a,76bb0b63,e92e9d20,3dde7cae), +S(a862b5d4,978928c0,49a466de,94176192,f1a57ab7,a849e548,ac12fb9e,369c916e,ca9126cf,7c1176ef,e6fbceaf,26760dcf,b1c24a28,96a3e3e5,a0051d60,ddcb4ecb), +S(17b54d00,5d185207,b4d8966c,62d3c535,c94c6140,166374b2,958b27d3,ae202765,37399472,b28ecddc,7e54d0f8,d80448ba,a0ac56b5,df9b1cd1,6cf44139,4ed92816), +S(40d75436,113043be,31bdee82,2ecc3a69,bbd157d7,72ec9b73,a4a3c96c,da28a6f6,835aa9ea,ab4c1ddb,35fa50e0,e26891d8,2b7e01e2,a237f4c8,c66c413e,faa7e140), +S(32b82a0a,5c267263,3e021c81,ddc1341,7a69e8b9,7b814dab,d529e38,424bb064,ecb8c97b,aeed6bd5,c8b922f3,1b4634b6,fa5393af,aa5e4ee2,c84d4aa1,651b4935), +S(ea460efc,85f7644b,bc9729a6,ce55296a,4277f0cf,3032775c,ff7fb96,da4c56e0,e8637568,b09fae6b,40a89f55,6f0cd0dc,a710fce4,b37329c6,57cdb05b,71b5b513), +S(cb5fcb0c,942a860b,6cbdbcf0,1b8498d8,68c8b9ab,bb224b79,4b8fc38a,9fedf311,3248669e,9fbf75d0,f64d466d,e42fa01b,deffdce2,99b45c1d,c7d8154c,fba41a5c), +S(79432c0,23a213cd,44c29e2e,f7ec5bad,1b4888ec,6673a84a,40a398b2,33aba92a,67cc9316,c2347676,b64e88ed,18fe3ff8,5c9e35b3,cf78d5aa,79c757bc,74d445c2), +S(9dce010c,4ce908c7,d0d79509,27b8803a,d695e8b1,67671865,2f97e264,3a7b683d,49419fca,ede145fd,7cdc7f8b,65dc7b95,11a72fef,2264fb79,1c8d40d5,a39171bc), +S(43b8b5bb,9b56581c,ce92eacf,29fa66ed,f76037d4,3656e4a6,bc0b7f1a,cc42803c,c83017d3,30b17369,70fc16e3,cf5c85f3,199d2d8f,a7179a06,1940bcb2,65313dce), +S(b0c8eb7e,c0fb39fc,b6f3c18b,ef96cae6,b9a23f00,751a4d6a,3a2f5f40,75e544,d66399c,d48302d3,2dfb5d26,9219eb3f,d81412be,c523df58,77e5227b,d65463f0), +S(b981ee1e,4f26ee24,63e81f77,f16dc05b,646e1fdf,d2a075f6,aa422e77,b3577cad,8a582c30,4d062936,baed15a8,9c39ebd8,2d5645d1,c0fdbd6a,d48c587,7626c612), +S(d04c88d9,8ff5570f,6fa37dd9,432966e4,bb524a58,d3ad8cc9,21d0ca06,8fa80889,dfb4007e,4f3ca38,304373a2,931dc322,7469d8f,9683e7c1,dbe59c2a,a17713fe), +S(d00d8053,68667056,55eca05e,53fa60f0,cd778e40,647154a3,c106a3e,5b8a90f,74785ee9,87323562,b815f4d,f9316a91,e489186d,7b1ef978,7ee398ad,51d8f94), +S(87dac80f,34b74bdd,6b2047a1,ebc132bb,c83fded,82405d4b,691d25f8,3e4226c3,da7e507c,2b135b69,501319c4,77ed0b20,731b56be,3dbfb386,4e0f4867,f03b120a), +S(95249c91,bdb94571,7b03d8cd,86bfcd36,3d51c012,38593cdf,243407c1,9322f8f4,a139a970,bff6a5ec,3d9876e5,6dc11286,56c98b90,ed6fa58f,157d7476,deb6bc50), +S(eaa86b89,f5a4befa,1caf1828,bcda7c32,792b468e,9e7530e5,13f1518c,3014cd5c,329bf9c5,6e431d21,a4cee5d2,beb4584,e7aa01d0,5935d7a8,44ee79ff,85f582c2), +S(b2ede9a8,6f324bce,3f62448c,a401d636,9a6ef8ca,89a48a9e,f9fa3bd,9138cd74,d942f74e,89ea55f8,a2642deb,652bf827,79252c83,b91782ed,6b3244a,439139dd), +S(c03fbf90,797b672e,24d06d02,fd70ce22,778309b8,96053128,70f48b97,aff20585,c5d44056,b4fca7af,4b7b16b5,fee76438,f2a271c4,655df4c0,8de3f634,4cac13f), +S(6da64321,c0642b04,ea7eadc2,a7739b20,7af8f1d2,fa99d26e,8e924241,4eba2a25,a08c3484,bf46e429,d7ced694,41412b1e,e2258109,b8c17dba,3370cd37,b8a77546), +S(9269c7c1,4ce5d777,dab467fe,3376662e,6f266272,5e2695f1,fa375b9b,1a1c2c4d,4dccb6b2,ecaf9f7a,fa3fe17b,e2a4054d,bcaa6e33,25b32070,24d5e324,ba1ba6b0), +S(a0933917,a532ed22,7a575482,c1090486,71a6cf38,1c6d825f,98f1938b,d3837992,c079790a,56f5e530,52760bff,8c76df6e,ceba6071,3e90dbc3,88b3527d,64aeaf9), +S(bf2cda66,ceb98433,d3e54e48,cfc15b2b,92c94031,ca9810d9,cbf2562d,c61d7017,2d31e7f0,ebe2068b,c16e81dc,bf1caa0c,6ddf3b52,13849e91,a2bc1bc7,4fecc72c), +S(d1bbcb50,4b9d78ca,ef980ea0,d2b6e8fd,7abc0d8b,3c9227c6,eeee3cb,956d6be,a1292ee9,ae1c3057,c45ea7ce,68cdf9d3,c19a6889,e58b321e,e9858dff,f4d324d8), +S(3cc406f,a049f410,2a752ba9,30f83d98,81110a45,db5fc387,c2d43a44,de33bfde,1bc1a076,f06dc2b5,ec1bc062,c9c480c2,39eb5418,4006e94e,623d2bc6,cb00ac91), +S(5fb9744c,a35cf11c,e11392c3,92bf0a98,5082ac15,5b265fd3,4cd61ad8,55532230,8bd17d0d,c7cbe859,4ff79a3a,15ded6a2,81bb065b,a78726a3,d3819ff8,58dbe34e), +S(27509ed6,ff7bfb6d,31ff0333,a994f531,abed34fc,de8ecf75,642351f6,b259cf3,bf2f0e5e,913d926d,cdca7918,57afbae2,309a4206,b408bc9f,d75b3abb,174d14bb), +S(a619b048,626b9e12,86535c8c,b5fdd8e4,1a64e834,1a8d27e5,d4179569,5fbf70dd,9f79dd50,8e50dec7,fafb80fe,99889701,54f382e2,c2b24d74,6d6d82e9,97049dad), +S(1f8ea1f8,4bd83b5e,56a8e6db,67b5416e,1052a6ba,cdd161b,420d7b46,7070ce02,69b2865e,bd3cb91b,548a4aaa,81d74310,88bb6c18,2d914697,39322037,12760963), +S(fd33ff10,574f02d2,e9c52bf,9a70b430,50917f88,a8eeaa9c,938c5f40,dcd1868a,25fd0d1d,80a21136,c8ac4a8c,4f369b57,d6221a67,3aefd4ce,be30d19c,9334c47e), +S(75799364,7cc47d16,55dda6b2,a269f061,f575ec91,e05af43a,f7e219f4,4b5d2380,d58645ed,d803ca11,f12fb489,9ffbf03d,daf82c98,2b6529f7,28e476d2,22fecea6), +S(fa0717af,d0f83028,3e8e22c1,c240d540,b81b761c,a1daba1,b45ba00,9246985a,ed48a3d0,cab1c4d1,59ef8f0d,e64a2442,c02acdea,43b5b16f,42a75a7c,68b787f3), +S(164fa71c,51623816,52949c27,33c668e5,2a5e3812,a3532452,a6ef44ce,28f49da2,11ecd95c,3dbd9463,4867af2c,290cc555,ef22832f,d7040873,35fba559,e4f010a7), +S(a213fae7,5dd15057,4b6205dc,fe03a2e8,cecbc7ea,1aab088a,fe20e8a3,b46a9a5,c135078d,f26d341,a767acf1,c7b449a9,4ccbd00,23459452,4f5b8f50,9b841042), +S(515d702,8406f03,6e5acef2,1445abbb,daf7ecff,5a31a664,a24396d2,f5d12b0a,db966859,4449028b,f3e6f53f,5bc250f1,51ef3df1,59e26c0f,9f4a346e,d60f3876), +S(3c41f639,e7705929,425ba8c4,2b2f77b6,6a461c81,3bb4e8e3,341eca66,a1344175,f57f10d2,46735f9,f6b741cb,4fc57242,7e5504c2,f6259b13,5745c5f3,a1b8bde9), +S(b8bb579a,f9826958,8e288e37,3be73f8e,7b573e1b,b7f5c1ae,3ad27474,1e9f19bb,5c51d169,607ae4a2,5e9fa70a,f67e6df1,89f1d7d4,705c2854,9e4d731c,f5f97278), +S(fe3701d7,1ecc1c21,3bed8ea2,94447981,75577963,2f8dfa1a,3cee1c47,858da678,8b69946e,8b7226c4,ccb1c5cd,8b416504,98fb7a06,ff8d27f0,da3de97b,74dc06c3), +S(9e7880b8,5a2dc9f0,143407b7,304b60ee,8dbc2b44,4f751fbc,f1b4d25a,da219985,595e4ea1,2e495f97,f61d9220,4f8d06f4,1a78a3,5b6014f6,e82ed051,2697ce7c), +S(b0d1246e,50c2dccf,7cc9746a,afa49227,62487f19,aa6835f1,1379a6e,f3c0f6a3,1dd6e8ef,973d8dc1,fa440594,a70b989a,80728e32,17fa0250,b7c1de39,b1174b45), +S(355aaa35,f5699e0d,e8fa3d4b,d361123d,5b8bf5f0,c74a149d,7cc024e8,2998f7fb,f905e0d5,b3abd09b,5f9b8c36,25f2597c,3430da0f,3439b16a,ada46421,4b678d55), +S(6eef7ac0,ee4da5d4,c8bb3e45,ebc67395,592f313,1d1ba424,1f909ede,818d6364,b0e832d3,92ea4728,7a35d4ec,861a43cf,6733ccb1,bdda8c9e,dd5ee835,92671a5e), +S(7fbbf8ce,f3e99b11,8def70c4,aff57b17,79e4e341,750f7b76,e44245de,8d90ed7d,3032f38b,6570cdd,e39cd075,e4acf1e5,815a065e,f2a84a7a,8f23fb20,6a0c99e2), +S(a9d4c727,a682f85c,b992544e,4e910ac2,beae12af,4fd74ca9,583ff9c8,c06644b1,794e13d1,fa08b167,433be416,c73d7f5c,c21413d9,a3d1393b,84e7e470,a6918686), +S(332dd1b8,ab8e5b66,5c614e8c,807a9015,56612396,adab5c4e,e8ad5856,9c44b1da,d4b39084,5fc9c364,21dd644,c323b5f5,f5d45b39,2885065,dc6667c1,2cbf6b12), +S(ba843971,6fd06d83,e4ad8774,4a82ca41,32954db8,b2bfbdcd,4935f6da,3df7ace,78facd39,b9739785,dab82b40,7dda50e2,db5d4b78,b9e57fcf,8c240b20,5aedb9c1), +S(ac7129c3,3aecb4ed,e60d0ce6,2e2cb73c,798cbbc9,58ef50a5,5bdcd2fd,d167b648,7376ed23,196f4c1d,cf8b5104,5e2c808f,a7bcf43e,2fb9f85a,ac2b3929,4d704edd), +S(17408c0a,8946aa45,387f043c,874deced,6a15eb37,7bcdbcfa,b7ec087a,80516034,cc942afd,78203ab9,77583109,a499b71e,18566987,48c2ee70,ee8a1c8e,60af5c31), +S(4f0df589,d69887f1,ae4e72af,61c083ec,8ab634b1,7b82d533,2d587a22,6f8eca30,e734fe8,926d6662,50cebfcb,50d48e42,593350b3,f2456e77,b6ff5dcc,9e3f3b6d), +S(b0d20898,74f0e672,92856890,51749d54,dc4ad1de,f6d12d3,243830ca,f8da2848,2e790c5a,79ebb86e,fd5a068f,864a7266,fe6d12e9,ec664f02,162ea3ae,e004a808), +S(39d07f28,30d2f3e8,29ab5672,db6888c0,fd224c68,57f3d0c1,aba89da,3f7ca96b,590a0812,e58609d2,e28ae3e2,9305da12,f46b8b0,70c07b2d,a644a956,12f6eba5), +S(20762b89,7ef06eec,ffce19ee,918ba264,4e93a2e3,9f46163a,99a0b218,a94171ac,e1e15917,3e3d5e4d,89cebf5d,6269b14e,784a0d72,e617fb1d,cf7bda13,33bbf989), +S(d2f0ccfe,813772cd,f3b75442,bc16e554,4edde28d,b6c64729,16764483,7b104626,c6efce8c,c63919f4,65a6778f,4b397573,4c4a93b9,43a40ea3,f44d4cef,78ce5199), +S(19520039,cb11eaba,ec1ef6e,676202bf,d5bc4bf8,4e40ed2b,2daa2a4a,2e07095c,fea234e7,3b01e2f6,d03768f4,a534c93e,c6e3cd50,457f27cd,7b6998df,b6e4cd7b), +S(3787750c,f3d73be9,52209ea2,38558541,8b6e79b0,fe1a303b,ef82fd6d,b2c9bf94,b91b2fbc,a09d6fe,b19dae3d,49416fc4,a7c1134e,22982bf1,4aa0678e,c5cdc030), +S(13abbdc1,a65ebbc2,2988a796,bb369866,4211dfce,d3a04d6a,6730d5db,6087b34f,9e4c4a2,b691acc0,b034b690,5488bff6,5397a267,13ed67f2,1374db17,fa8e8b21), +S(602a458e,1cd32ffc,d35ce5cc,c5d7b597,7e20c0cf,66a936df,4eeab00a,b7b31918,167ce780,91340b37,dbb5ab8c,e6fd602f,534149f8,4d67b16d,29724802,a8aeec61), +S(71082819,584ef5,2a690803,d24fde15,148e193f,35534d48,f7a1932b,d3f69928,9b2cb12f,668f96aa,824e3f94,79ee706b,c09723a5,4a588cca,22ed898c,c9aa219f), +S(6349c108,312beebe,145d750c,1ef2721,d536c507,4f0123db,9777e920,c72fc1f5,131f675e,95b5c1fd,856cff13,57a494cb,46e19a26,b9218b67,c6cd2823,c9e877b3), +S(892b764f,e954b331,7c5f8564,b67e7255,1287a06b,32bb476b,f616fcc6,ba329331,b0a0a00f,91d0d637,258aacec,9bd0ac32,e10ff4a2,dbdab74a,a15bcac3,d3fe55ba), +S(c2f38edd,371ef544,a1443296,afeb6a93,6705e89e,fb23a13c,3dc6b619,ea7516cc,6ba10142,71ab78f3,1603a39,dee7ae62,7ee034be,ab1fa0bf,61e18e7e,df40fa9f), +S(bea4f01a,7c61d100,da78c48b,e6277e38,6ec6c265,89a2274a,fd2e1792,b5f74618,d27126b9,9b074a95,690cff35,cbf949b1,8cf0c449,d76f2511,59f1a217,293ceb44), +S(7bdabeea,d320217b,d5e2e84b,eb28b664,e9632606,28a0f281,ec4f2edb,3f3b4bb,49c45d86,f06c42b,4e6e2664,3c4613e9,411103bb,b7abd818,1ab8a0ca,b9ea116), +S(a913e0ec,5e360f89,9c611be6,144a16b7,ff3d03cf,28851ecf,67ab457,53ec31f,9bc12b6a,8595914,333fa4ef,3096cd6,71ee444b,7bd6da65,67d91ff2,d1f278b9), +S(ec6ab00b,e272be1c,f0d359f1,a7fa0f13,55a151a6,d03a05a3,6fee5019,6275846,42d200db,e0edcf3,634055e4,d66cd689,b197f872,d91bf660,e797518f,f4c2ad), +S(a6142783,bdafb512,62b2359b,11286fe1,f15d7464,47f4f507,318800dc,c55ef428,cefd1ba0,4c19a732,aa498eac,9734197c,889cc973,6fd0800d,a051cac2,b0e4bdd2), +S(5f8fea38,cb38f90f,342d7daa,95912083,7340591,c4b98ac7,c9c8cccd,1f2ce457,54c0d093,45974a7b,268f152b,d96541ad,80561ec5,264af970,9ddcf7c,80bd5a55), +S(7b222e07,2d7cc37f,a3d73009,31ae8a3d,cc264153,6c538457,c153ebb6,d84ef26d,9dbae136,e560e343,af858aa4,20e077d9,f4e19cc1,c4f709d7,7875b44,780b90bd)}, +{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), +S(da8a162,a47944c9,9880ddd,c2bf133e,4ec5d836,54609c06,68dbd68d,63784b58,a94bfb99,53fb0921,7b659c08,fecf83a,92b7ed8d,8138c8b1,45f9198a,f7df758d), +S(6eb60bb9,26ae0a8a,3f23d58c,e7dc6b23,f5c17366,2467ed14,61be451a,7513f97b,14225da1,8bb8ae78,8478014,6dc68934,8e4d60e8,41a46ce2,71fedc19,c512d6a0), +S(b03b0869,1b3495c1,5d06c55f,54f1d324,b353d848,31d5c43c,4d524d3a,52b485dd,d7a61b34,9f42ad82,7145f010,e00fbfb4,2e20140c,a0d420ee,11069b25,12147e1c), +S(8eb61e15,83ab8058,a3603895,7709ff11,85eb6bdc,14043909,1b1754f0,506c9bc4,c7ddb27,4c723f0,620fe2ff,2eb11365,1e19c551,32925a05,1b2a297c,9dde4a91), +S(e09474b1,3a1975c6,147f69ac,abe0941a,333ad7e,59495b9d,20747e3c,92f65d8e,98b01b17,b57f285e,b0b9b0c,52f8f390,cf2afd9c,7e90a024,c8758ff5,11008725), +S(20679abb,aa71c3b1,e4ae9454,dbb55cc9,fba632f2,548cc28a,e7f65ef3,c52335f7,158b4f49,53ef5e70,b1c1b847,1f7530c5,39a9e251,98ecab8b,d178b7fd,6b51d391), +S(51e2c9dd,b8da0e35,ac6b6325,4daeeff9,cfb2cfb4,94ea2ca2,46e9ba28,4b86ff33,309b9033,a723ed89,9ffecc25,2fc3c44a,d4bfa991,9c968ab6,664f53d0,4c9d3757), +S(b8760392,98ced8b4,2f1e9a81,2980e5b6,2e2ac1e4,2d6e8525,4bb7046f,68077fdb,310711c9,2b821f61,66854bde,4988708a,67e6c0f0,dd392b77,2435a50b,47d9277a), +S(ae072fd0,c88a0514,a1db9641,50022cf6,c186d645,57be5748,7f8a1029,7cf32f6d,862e7709,f135acb2,2d3f2239,f1d33af8,288f7434,191f84f,f6a0bef6,c5544cb1), +S(3390c74a,fe49647a,8c55fbe6,6b7eef3d,11462c16,8f4a4fe1,447fa5ad,3899ab0,ad8390b9,b98fb90f,b8885691,380229bc,24295d8,995c7810,5a7929b2,d0979027), +S(dd7625a7,10121e02,527bcff1,80f5ea43,efe1c39b,50c20176,6d172c4a,1dc58501,4f6b4942,ac8b6d5,849f2301,9f5112e1,c250b7c3,4f603e99,80ca8743,8d7c8f70), +S(ba116ac6,d0c9cfd9,16e059ee,d94ec9f0,b726e16e,851d771,340eb6fe,4bba54fb,aabc01d3,e65fe86a,4206570f,14571b10,5e226e3c,7d603b54,c1266f0e,258ca5de), +S(dc7ce33b,19c27352,a277797d,a5b70697,6e875638,e5315232,ccc814b9,a2ebd97a,5e4a0969,91396fa6,6d1d81ca,de2d54e4,f0e4e835,ef95f74d,3f21f234,d5f5cd62), +S(200a15dc,6f7b0885,bc49b66a,dcd41acf,b084059d,f55971d5,90173b46,e0755ba7,e68be603,f2c09661,af4e8ef8,b36ac49,270b97cd,f37260fe,9c27fba4,ebc3d828), +S(4969c231,3887e01d,c2837bce,68667593,beab92d3,6f7b0bab,c8368c6e,7ba31d5a,75a8e9b1,5ab4c54,a88a8678,12b93d0e,81887adb,3653518e,81d5124c,4503ffdb), +S(6f04a5cd,5913ac08,dfbe8f6c,57ce496b,dc05930e,56245464,6685ac62,85c3abd8,19fe0060,42a12c30,b7db3cf2,cf3e7a01,abd09063,6c84e285,2a045d4,301a8954), +S(41d07a8f,26009140,e5e338e,7b3e136c,b8b51e01,dd80d441,de584af5,74412fee,a77aeda5,4ea2b2cc,853e3b6d,c128c15a,6e758ff9,d22a8a38,3e28605c,8000113d), +S(dc52e1dc,e07a94e2,e1b7f59e,18e25e0e,eee2ea86,3f127649,a818e786,cc0f3269,c26c196b,a42c4a7c,331af677,e3ef1f63,8133dd2a,bcdc3c37,218b594,6547b3cd), +S(e5c26f1b,311566,152138e9,33ff4834,c17e6ce8,62c84c66,4068dd93,5fcf72da,2f293b72,9c67a27a,6cb096ee,53726ce9,fa88ffde,f8c657c6,af27d995,c4df36ac), +S(44b04185,5f6f4c6f,e6e6ca5,d71dbe95,2e1706fe,f9db95b0,9b073566,c235d50f,18f4285,cf142a82,bd26a508,2bb6b319,eecf0ead,a12f3d20,800de5d7,94d3858), +S(2c4644c2,4ca3b395,655beb0c,32d610e2,f9477a30,7757b0d3,dca3f87,4b7580b4,6c726213,c7864e17,3ff2ed6d,861ef4ce,6b83882c,1c319b9f,6ab76765,26f5f7c), +S(e3b2e18a,24306e18,c4cc6b9f,f42fda12,ea84329c,dacf0484,331bceb2,639f8ced,8a11b73e,4de49f5,6b00a3c8,2b366df6,afab3320,ed732254,c1deac3f,e2d4e601), +S(de42b164,ce28acaf,ac6440e0,274882f,158c1e31,2f080371,5f4ee6f7,6bf6f03c,385de0b5,c533196e,b3d3d0fd,fdd4d0f3,d173566b,7d5f1f6d,5c6c3735,7a98249), +S(3d018969,a03f0134,5b26adb6,31d7abcd,e6399f56,c532d486,bce5b501,98e4b68e,e8dc92f7,6a007d98,f6a548e5,3da24c30,d85b4008,2e7b923e,35a5f18e,93d772f9), +S(c77978c6,4caccd00,27b31a61,769a06ca,636f8603,49fec444,4821952d,9a2fa7d,869c3fc8,1f722012,750d9f96,349ee0bf,e08044c4,f8af04e0,80a03caa,84331df7), +S(f68d647c,e49e9660,efc740d7,1394b8e1,699764a2,9679660a,67566ffa,ead3d9a6,1d64d46e,1ffbb7ba,912b5659,656ce860,cb897a78,21958d3b,ef0185da,fee27c61), +S(dcf7708b,a5c5e05a,4d65200b,77b5ec5a,f08ba85a,46a76bca,dc1cb444,fef50aba,80c88800,d22637cc,6082bdf5,6774efe8,31095951,172909d3,4a400798,c34db159), +S(3dcc7aa8,90604a5d,bb22a5d6,91a42080,ff5844c,5c756fcf,86a2b0cb,becae,4b1721cb,e93246d2,9913fec7,16673f3b,8a02e3ac,dd258db1,d2a22bf0,4412bbce), +S(961f4700,f8c7db80,a5157a76,181c9420,9950735a,e1805e85,7b204f6b,e9b7d33a,85d980ef,b7a33331,4fe0c3e9,1ad61569,69ca8902,6951ce84,cf26c0b9,7d67ae21), +S(54d1da7b,87d57e72,1a6fb923,7b7be29e,db200b81,dd891b9b,9183e3f9,d61da16c,c7467f66,9010912f,e5dd6bd6,ea97451e,3a95d89d,2abcd2ca,ff0a3a9,b90ffa0b), +S(1072acc9,b5fb92fc,41b3fada,7d5a4434,13c73a1,734ffd33,94df394f,ffbff1ae,87594f8,f1f834e4,24756584,40664f8c,418ad3e,7a250e6e,863baa8f,a37e44ab), +S(ae4d4dbd,e751b25f,ea37ee64,bc8db97,ded52741,72f97b8d,64149db0,b8fafa33,d19761c0,b0370155,817e2022,8bf31e5e,3bd0f021,3f4b23e,881b6d5c,733fcd54), +S(328c26e,cb0f4648,4ab9dc2,c33d35a2,d0ead36e,8d1778bc,2771cf6b,55486c2d,63137d2f,a34981fe,f2e12dd5,5825b824,43f052f4,96211a46,995f0001,e6fe8322), +S(ae60aade,4c91ca13,d847353c,61ca90b3,205aafb1,c5c2f2b3,305c81a3,e4c7fd3f,913184ae,93837553,2916117e,34e04698,96b052c4,a93763a0,5f8d7153,2201f1e2), +S(a608ba7f,cac3c42a,20a61800,4d317248,e5fb7e69,b230cf53,567a4114,5d7cabe6,273eaec7,75b37b48,bb6f6ac5,695e8887,f8bde091,1884684b,e64b111c,f767ba1a), +S(ca5033f2,97194ff5,b850ce4f,77f303ac,6188e43a,848fa8cc,b1423289,da634671,34bde31,85e18a14,c0701ae3,4941de08,7e55cf6b,acbfd7bb,9a68fb53,62656790), +S(9fe36400,aa701955,6fb4bc0d,3740bc9f,363dcab7,2eccb27c,35a5d1f2,30f047de,2f841d40,bc786920,af86c55e,61c17d46,84b31096,72dea08e,3c04caa5,82ef33a3), +S(380fb487,1f841eb2,69c93474,4e737089,ddca3014,d9c8f760,40f39b7d,1e9271f9,c7c9944,cfa05673,85d49f7c,7051a04d,dd2d7bcc,36f0469c,8904dcd1,354dfd5f), +S(dfc4a0c,73ff4237,2716889d,e05c88bb,74462b15,2b02b692,6b41af3c,d52bfab1,31809a46,1eb7dcbc,8766031c,d8e02fdc,c882c7ee,a1e2f7e1,5342bb44,53b859bc), +S(561af1ed,8ddbf862,5f1553f0,31e1cdfa,34b8f095,6bbb8ed0,365ad1f0,5c3b589a,965b8e9,c6926a32,edbd7251,251a8a05,e83e40f7,7ae3163a,4a6044b6,20e39620), +S(d0a17522,1cdaf650,ed93f289,ff3d2199,e8fb3f81,7dfdfa95,f7685715,75a6e058,81f7478b,83dcff41,ec9c0cd6,c1515e02,d7eb550,282f37ed,168e6229,ce5c5d56), +S(3f42f09,cd5db26b,df31bc12,a82b6517,aeabeaf3,8c4a316d,27594a03,ecf3de3c,c0494e41,89ece4d9,d08a3c53,ea2bce3a,a65ac759,eaaf07aa,c1a809be,7482ef9e), +S(b7142a5b,239386c4,35fed19e,46fad0d6,2b4974c,f9a7c582,fc45af40,a34ca699,17db42dc,624a1d07,83b3bd69,fb6a8a05,e4175134,9a3d9561,1d4a74d4,28f42a12), +S(c3e483,cd0b21da,31845a93,b75b60b4,800b5e59,43a9708a,251d0135,91d54cae,8e67983e,1469d74d,c61be1f3,f606adcc,a02c5556,a1f06fe4,2f6dce0f,c4c5236d), +S(49d0ae34,23572f85,595efe03,963d6032,5bdd79e1,7a538a54,e43706b4,cf4453a0,fc1505b7,e4e126ba,2a0dfc66,d8bc8616,27918a9b,df985045,9df4bd6,2e0d2fba), +S(9f8373d2,f0053731,f0e1cb2b,1ab08fbe,8ea1a930,87908d7d,5dc06491,7afb4719,f22bf0cc,9b1b995,ce01a96b,1f73f6af,bf92ddf4,ca57e29f,80cbe5ac,a8604ef4), +S(f760b681,1374bc96,102e537b,8b187cc6,989602ec,118efca4,5391a344,eb82ba03,4592a7ac,655cc29,72e26d63,9a99eef5,ace2ecaf,ab414772,de2f8227,87c4d750), +S(4f465aea,bbb79ea8,60c87a8d,541f9c01,afa48dc6,765c24ec,b6a49901,307c80d2,adaa88cb,e882a86a,2d7c2ddb,d5eb2385,faffe9a,ff52481c,dfd6b1dd,f72eb3f7), +S(4f3dacce,862428f7,ab62b4fc,e20d1f12,19183207,64c2a51d,a80fcf1f,f86ed5de,97f8326c,21558e18,d4b7376c,1c14822f,d53c68d3,394dbfac,80a583e3,c668bad1), +S(f1905b3,d04cb49d,3db59404,4037ef71,e42f4311,d59b3160,b917e355,75ca9e3f,c8c005b5,5f49132d,fb2d316a,b0214872,dbf36f7b,f2c876e,6397ac87,ce6b1f3d), +S(8ee0a2bc,f853a469,27efaa1e,3356f1b4,61796e7d,7496cc87,8daa3f8d,11e46fb1,67b6599a,d8037160,f298c595,dd0a5a40,dddac020,d8c8c99e,c846cb81,13c13232), +S(a8f55dec,3872a5c8,c3d7272,6dc06f7e,5c7bff2b,9a8354ac,a184f0e7,8024a4e7,a27ffb57,47c61b33,fe555376,5e2148ca,76fba57e,fef4dcc0,3777dea0,3b2ffaf7), +S(e4cc6907,4387a6a,2e94ef7c,97daa582,9c2f84a3,9b71e76a,c0ef146c,a3209cc4,297b82a3,115c3eb1,eb75677a,bcca1e55,9d2caa0,31e1554e,abb697b3,90218e2b), +S(e3c2e255,57edab4b,64295050,94470b06,e380e503,cd55b106,52cf9fc1,d56c45d1,6621db25,53c70d69,f96facce,bbfd4ea8,32262010,35983521,360bbbb9,43110b8f), +S(8a27f3d0,b4c0ba60,b2875b70,33d386a2,e93e2263,a7f8ccf7,85a0a2f3,6488092e,9525a706,c37af8f1,5ec496b9,ecac74a2,e96ef02e,9c30abf1,2279bb5d,100a2ce9), +S(94f34fb0,2d416fb,4819e24f,165617c5,8929c2b5,a0d00bd,e8c3e71,7ef188ef,c5cf6f02,c0bd9e80,15a436e5,eb837289,66bf2b68,64a5ab82,88564fc5,166ac90f), +S(2a1e9e10,2e0ec944,bbb7c570,2ec1d655,525bc965,85dddf63,e4b4fc6d,ba65943f,64099714,f1c157cd,90393aa2,893703c1,ecacd1c1,87c30518,dcb05be1,d7eac677), +S(cfadcd6e,b147c4d5,3502b628,ceaf389,73ff3aa6,b46a304e,ab7a4608,8a7fbcb1,21cb905,2c53efa7,ffc62ba5,7ea8b29c,4eae5801,2ac40525,6f095363,ae169da9), +S(5f7ab5d1,86b95bce,a294528c,91bee6d1,c4dd6b9b,7f393f7d,db09a3d9,5d268189,9ba6285a,5ece8f7e,5cb8f8aa,4aa83910,3a2ff288,2864aa10,cd6f96a,297392c8), +S(38f751fa,d2993ca6,c3712a16,6981cb52,168492c7,2676c7b2,94463647,5510d2a0,ee57807b,89b36b02,d1452079,6438428b,7fa4b2c4,d4f52070,2f00ea00,33b7c957), +S(7c5283d8,c775232b,b03608ca,3707a2e7,5fffbfbb,1aef19fc,5823d8ca,2c5ee31a,6f645f62,29c3b646,c2b6b5f3,c2755ae,75a5a0d0,a6b732c6,38e946bd,637f7ce2), +S(d78a18d9,ed411883,568b398d,56426fb2,41bb3e0a,4bea3503,18314611,b297d090,fec8298d,79aff51b,ccb9f9fc,ed37639e,aded3174,4d0d934a,b19c0945,8b538559), +S(291affe5,8fabbd34,f011da48,53e100d3,a6638761,fc66874f,4760f7ba,769c9e7e,79c609f8,7ff45288,943bf869,4ec6d4e8,66c77f36,92d9e328,a85b1db9,92bec6af), +S(8cddced6,c63b74c3,608fe52d,aaae8c2b,15be6e3,e2eaa564,ab77d22c,f6e2eb32,dc05e6e8,e917755d,3e54ea2c,21d74781,6e6ab14c,8ad778d9,b7809ab,aeb12d79), +S(67716149,58e24e55,e786ae7d,64174609,5edd9dc4,c70ee3bc,d6764bb9,10253c2c,274f078e,7852a04b,fc766272,1c8290ae,95a7b036,45b20ad,9376504b,92642b16), +S(54bca4a8,96c5abdb,c8170b62,bc7479c4,dd33f4f3,75f709db,eccde832,73d452a3,7b1f1e00,b7f117a0,92196f02,1e499e,5b0a5f12,e4361596,5fd253eb,4891110e), +S(68df83,b0c12c86,a7ddd748,cd687bce,13ca941a,83b2a172,676971d8,566dc3a8,81fbb9d4,49ff2bb,851ade7b,18a5449e,83b2a02a,4be387fe,77eabdf5,964935f), +S(245ac706,b6009bc7,34782325,c176f05d,d5cecda1,9a0183b1,d546cb4e,55f975a1,72718f65,fbffadf6,dc9ebab6,515e7866,af3bf119,739207e,415d4ef0,f1d902a2), +S(548bb01c,70b6cb4b,d5e21e8f,dcbbdc13,76601235,9b1ae88f,2d615bfb,73ace38f,67aba9c0,d0532fa5,c71134f9,e80fa73,f47ad308,e27b6a2,3a3620de,f7e109a8), +S(548d71c6,c5dec0cb,a98c55f,720493d8,f16c14c7,97245548,5249ae86,cfeafc81,9c811c7d,5f7b67d6,728cadf8,aa0c3f39,54130c9f,81a3af38,24e556e9,40212668), +S(aaf4621c,4679308c,93fb34b3,d882aee,f7bed71c,23e5bb36,644b69d9,23ba66d8,bd4c368d,e9bdf4f,9788125d,9db04c58,aed4de1f,ecbbc52,2ef49b39,e0d8f54a), +S(bd0a071b,396afe8a,51a790fa,f11c5db4,2fb2dba6,a38b4f90,f7df7d86,f3fd0bb0,3dee630,46d723a2,1299893a,9f5b0371,e9d30aa4,d24ca28,aa9b1fe2,2636e05f), +S(57ad7d5f,7f45090e,4ffdb906,17ddb128,df3210bf,e10509da,dd71b00b,aa135e5f,58ba58c,b22308a4,d7d7c1fd,5f3935dc,69a5996a,d5825bb4,2fa73034,ad1957f4), +S(308c94cf,c0234e10,5c147a0d,155818bb,d6f534f5,3c02ceb8,14fe03fb,1e0c2c2d,90860fef,f41da4d4,b457e267,3585b997,2fc2465d,de0749d0,dbc3b8d5,251629cd), +S(ed769107,95f5a585,9fa26429,7e51b183,ed30cd21,ce489c48,6268ff01,9d500407,395ae9ea,b309c345,a6aed39b,f2fa5b62,a85801b2,74242b41,433735a6,41a3375f), +S(e4ca72c4,2e3d099d,f48a2154,b7f7ecb8,53ec83e3,4a25c1dd,f7fe224e,50dd6a9d,5c67482e,fd84dc6e,96e3b258,758ef03,a9b72b1c,e210ee6b,b6125143,f2a14f8f), +S(e0cebeb7,32a3881,66a10ad9,e4099f23,3b1ab63f,f214916,a2b24c77,de8c5d2f,6b15c084,c58da2ca,c074f02a,7dcf05ee,8b836bd2,bd7811f2,53df8995,6de6b3b8), +S(da35f459,40db892c,9fe6d0df,98f18323,cac75843,d5362cdd,1706cf59,329faf4a,59ac2e36,d811cce,3f9596f8,c7376f89,5c13bd99,1e7377bf,b9742aa3,7ff78bbd), +S(e1b0a76d,b4bd9e71,ce6bb854,670d2d6b,a6e8f792,bc303d36,bf3a9b97,46ad7833,1561faf7,6a4f6e4f,506ffb62,dc55deb5,6cfadfcc,9e4b14d3,fc5f9dc3,a5c8b801), +S(7a51bcef,7b352661,a73ba2c0,27c2fd57,2d77c45,ea8fcfa7,c39cf9e4,e95d7e36,dfd9a155,29682f33,cbe45ecf,4c0438db,e11a6fa4,51017b94,a33a4f14,5db35a2a), +S(b51f1635,6a08d923,dc87b99d,94399f2,41cf62a9,62eed5e8,de8b9a65,53d139c2,e48542ba,633cf153,43b97d28,157f19f,374a8b1,c154abe0,1624d5b1,17387b41), +S(62be0f15,6e567bf2,452b941b,2ff646b8,97708993,8c054273,7ec99683,d07c22f1,63c8e8ba,3941e7a0,f90ca26c,2fbf9341,df5db636,c113566f,a8bd1193,411de1ad), +S(78012331,5815683b,59ac7d62,54055360,4d4a73e6,453b405,b7364664,5dc78282,a02a235d,68bc552f,6627e23d,d01c2dcf,3752b513,a5e3d925,f9e43a17,4c947ad8), +S(19d975dd,16aacc11,a25b6d36,580dcace,3cb19e55,f4a0c9f5,b221a847,c8d64d2a,621bcee6,c7662473,ac82570d,7f888020,18ce7b83,7b635b3f,d44ecae2,d0633f12), +S(ea6d786e,dd234888,561afd6,a57d9d38,2a07450b,8bf787ff,b5763d3c,f9f7e5cf,ec4d538c,de2077de,a8c68b96,69bcfd9,700e2e3b,ef671a3e,38bd9d50,c785ed7a), +S(edfdbc79,dda15c6b,b74fe3d0,711d933c,8d466dcf,b0a51334,48e9025e,85c0e669,e503a18e,e2ce2fa2,3512c4b9,c7e70dc,ff70cc6d,e6f78e1,74fc64e5,dfd4a2e4), +S(d79bbe99,7c2ed85f,1f687ce8,b761caef,9629d374,ff3a1c5c,2e62aa55,848ba917,c87c80fb,db44be0,466cc253,5fee352,b52b65cc,c9ce620c,eeb0e09b,30dc49a5), +S(9a3c43a0,230fb046,ece16ba3,29999f45,ffbfd674,a1034025,8ed4b71a,d76dbaca,84ebd352,b26289f3,d0f0827c,fbc95da4,79baa21d,6a98c85f,1a54e773,d06dfb9a), +S(bba0583a,9915f4a4,5a015244,29bb3362,6d36cec9,f6d6e966,3d0d0e93,ab296a5f,f2f880d5,8b29cc71,23b7212d,a0068bc7,17ed8651,b262d8a2,67f2b959,4726eb79), +S(bfc82f8d,50227d6f,bd7be2fb,fa481d35,9b2399ee,ad216a36,5ee7a0e6,25843e83,43c7cc25,f3c527e7,a42e15f0,d73dcded,987ead91,4dca8a71,f6e45269,e0132aff), +S(e5a790dc,5c6399ba,43519268,e22fa9ef,1d93073b,e4b5a07e,d8c7ff25,c8674a1c,2dbe7dd6,c60650b8,91baa13e,7580afb1,c68c213b,cdbcb32c,b7d2f7a8,88f76a47), +S(c48038af,f4b316cc,928b2b94,decd9975,dae28b6a,46dc0d9c,808a5f17,3b251f23,8f1af5ae,31eae121,b5c53e8b,59766137,7e064f33,107784e,751c0bba,43cadd4a), +S(a0663a89,a8770439,4322ae5a,f2d6132a,e6882f72,7a30c7d6,c774d34a,50947e8f,6b3e8a03,6f099441,1b598704,55a2ae52,894a4aac,b49717da,4ac053ac,4a152d9b), +S(776c11b,2c5b2766,ec2d3376,63672bf1,933e6bb1,70d96423,484cc0e,f75fa07d,7ad71572,7d6552ea,62188868,8ed43013,53846bd3,da2e772c,e5e7752d,ade5505f), +S(6cfbc277,48c72aad,d60b2a5f,b04160f3,45fe3f2b,ce005f66,4a25e444,87ef44e5,96d309b,11b41b41,e851fd16,c4c751b2,be08a35e,d912bc21,8673ee4d,44d535b), +S(6cde4b89,ae0d961d,3faf8024,b64fad52,9bef7e4f,9f7792f6,ae242f6,7f559915,d86bb9b0,de0a82ad,ede30426,98526356,5d7ba22d,6be061d1,f31e479b,3590e3d8), +S(c2eb111a,62da4ddf,72cea94b,a85d2777,1ed639c,6c511c65,cd15dce1,6d4ed6ee,ccb342f5,3248ed9,b4e9c8a3,edc75d,cd519754,ec0e82cc,970a0190,40100231), +S(199dbd18,e72e70eb,7c16d374,c32e4f21,6f6f1015,96b91690,a846edeb,83366c79,3daa0e0d,33059817,dec9591c,a3981891,7a10a344,1d5d5be9,2ce4d81e,1e24ca3f), +S(7b175876,b6cecc08,324f0564,244b7912,59a04060,d63d9bb7,b1f9952,39b7cfcc,426a29de,e407029e,80872b20,3309b9d3,e99e9099,3892162f,385f7576,d9aef02), +S(8c182626,ba2b47e8,8415413,4c131ec5,d0464001,9ddc60f,7136ac5a,cb7f7f70,3eb5783c,c185c51,12afd02,16ccb429,d35ae768,3ff5f3ec,7de3fca0,b24369cd), +S(c21bf9c0,31fc1e5a,a18bcabd,fd278fe,ac280c08,d1edf19b,9dab3ffd,de8a6d5,9832eb2a,26d38233,f057708f,4465772,baeab661,c0b958ec,95e0e02b,94bfc543), +S(28003d74,2da7249d,67abb09f,36ef29bd,3eec106,5c02926e,eef4198,a17ea4b,f7a23dc7,779c9bce,64ee2bd2,eca6fea3,78cbda92,40c6cc9f,cef560e4,9b4dfeed), +S(de29158f,43169b19,4de65951,1c905015,2b0990cc,d24e73dd,a9b0fbeb,660749a7,2a39a6ab,42b79a7,f243a8f6,112333a5,8451866a,280dfe7a,ccf156b6,8f1f6f2a), +S(5c8c9c5e,8066e79a,38e3450f,59f2e504,2a65db6f,44233598,4bf0e4dc,37550e62,d33b710f,8d84ee3a,b8481efe,7cc4099e,8a47d64e,bc0433d4,f966fb05,7e4d68c2), +S(33853003,86c14fe8,1ae5ea18,1cd3ac20,87ed14d,6014bf9e,cc8b386d,dcd10541,db06c040,7ffee11c,5dca0af2,1856426a,97f3831a,850d4107,12b314ee,42ca1129), +S(43506cf0,bcb58366,a3faaf0a,fc8ca79d,3022cd0c,7b17ba3e,a7ea2e24,8332670b,4869e72,44c0fe15,39a93b9e,c1c16e59,880394cb,3cdda9fd,d545d4d5,968d86bf), +S(d13850f0,fa4e1a3b,12397c37,8b2f6654,46247ff1,d270538e,fa4d77c8,ae27b2df,91588b2c,c27f879f,ddd8a8ca,22165952,38224cab,e3090655,cb02b045,e869ac34), +S(995b5075,c2e57ac5,3bf1d8c,8b9a4900,207c9dfe,b0dcf3c9,86662c2c,9ac162c4,c75e3e71,3c7887e,1a47a400,dcba8a5d,4fc7841c,7f76f0d,e150bd28,ec3b14d0), +S(6af47ea0,6e2e8217,62482960,10afad10,b48d75e5,ee95f04d,66dce112,592cd7a5,2d6b4963,ee90bd6,21ec5220,6416178b,5d7b0853,7fe8cba5,ed06a25b,1078752f), +S(fa6a5eb9,780c0714,6f5abc1e,52bf1113,bd512198,95233975,4d58673a,64db761e,e57e10c3,d00af8ed,f4d601aa,e236e17e,91ec638c,d01c0c5,aba1d243,b95c89e1), +S(6d4b83ac,e44638b0,1a729bda,479705ee,e4194525,182dc1cf,f3002fdc,1ca3aada,1f57193,38c38891,fc6a0b52,c49c6bfa,c5de856,72c9ac41,3b137834,ae7ce48b), +S(6ea5d9b4,d638bdc7,22e03664,fb63d6b2,368a9bc5,eb6f68c6,61f79579,d89d9de0,c0c306a5,6073a961,c7e85e0f,3221bf96,b09f8ade,da8ef6cb,8289c8e,54540af8), +S(1a2f35c0,349c0cd5,1e4c9fa8,b8ffe4fd,8c595994,2d172dda,bb8bd8d2,d22628d2,55357f7a,cd9a9694,f2fb8a31,46546a4d,ae705945,766f8565,d8dee125,a9735003), +S(34f6720,2a17f704,80565d92,d5d268f1,95cc0873,efbb0a45,62ee87b0,bada9e07,fb3bb7f7,f878b28a,2fdd81ce,71465d96,e3dc32a2,1dea4715,61f464fd,29b19cbd), +S(93cb896e,64d0c453,3d82977a,872ae1be,1f1bd6c1,d4404ea,f7688496,2a214a86,f3028814,8f07a191,4e908ef3,66d447e7,1100fbc9,4ad1e4d5,bdd01540,135ce7f9), +S(1d5bda0d,c6378439,d30df39,5516e605,7c8b5f6b,fdda8582,ccefec6e,3d68bafb,45e2182b,a2377a32,df9b590e,943920ba,482db2e1,443c4269,37a6fcd7,14555175), +S(4d0c346d,7c4c5730,4125f376,9ecbca25,33a737e0,d5c4a85c,357a8f4b,792c02e2,4dfdb5b4,b04c0188,e8b1593f,a9d82ff9,ea4c8314,50231cfd,f5d0edb5,6f7679e1), +S(808f8958,d263ad70,bdd91b0f,76f352b5,c5c280a0,90ad41ab,28d60bda,69b52052,cf8dc4f9,eaa81931,f29a4e04,a0929d3b,c710f43a,845d6b8f,c8c9af81,7fc66d77), +S(6dfb47f6,e33f8073,9251982f,7fde21be,1bfdb916,41a8fbd0,1a36a2a8,6b10a3b7,447bb5a5,e1895243,d33d3883,e8210f3d,b412df54,adc9e35f,313a8006,141efe99), +S(8894aa46,b158f826,12ad4455,35ec03bf,c2625d61,58de4278,2848a919,65fe5e,3d280519,aef54f53,81a73760,6c4ace08,e48e87a2,71beadb,cb17314a,5a0e4b85), +S(bef6abd2,a6a2d391,a045c2db,24456a53,3dbda4bd,4e39c3b5,afb1e845,9cc6efa3,b329a528,f05589f,375c188d,83a3b7f2,89a40276,7482dd2a,4c5b07d9,df7543d9), +S(2588cbc7,171a57b5,afbc6685,6546fcee,6f1bba26,7cf73a8e,1eee643a,290c8b7a,2b6872f7,a85118de,ebfbb42e,21bdbdef,73426417,f2cf9a66,e430892e,c189f192), +S(e1362758,cbced085,6d7ef7c,9fd4023a,6aaff6a8,46be23e5,fb7e143a,e50d2fa4,1d4b750a,e8fd53d5,bab60889,36db9fd6,1c05bed6,87abc705,5882a4d4,45754599), +S(f1bfab09,821e2d48,b8849002,5222762,b703615c,e89300b,3774a966,c5bb2dd7,5cc77e20,b0ccdb36,c48687e4,bfe5e264,50dbc5e8,df38b1c8,322777cd,1396d309), +S(f3c5dcc0,778156a4,ed1fb225,bf1617b,cd56a4d1,4d91ab0b,a135b900,ff5cbe74,297e4146,42d565da,17933bea,4bae64,188843cf,9ba103e2,c33e533,15ca5ff4), +S(b8c26559,6fe544a2,e34bedd1,88a82771,8e48f880,ef1a9e00,d4cb7ece,84f79c23,9fe1b2b9,f3e3f392,8ff8b8d4,a72670c,dd9979f2,883f44de,f74dc6b5,be093390), +S(780b8246,11dffdaa,2ba0f9b6,154305b0,6a536c10,923fb056,ee6939c3,c456f6ff,802f9ed4,f6e395c8,b783b21a,d5b7e58d,6d3e17d0,b73c3607,39d21ace,7f05004b), +S(ff5d8fb9,f80b0d2b,9135052d,97cd1bed,de7c0622,f0c7c9d4,7add4578,62570cb2,9cde8f57,d9f72bae,e90a6e0,89911674,bfb126ad,933439df,c9c1498c,eb38aa6e), +S(9b05a751,91f7b248,f3eeaa5,2fed8be1,b1da6e9b,12313382,3bf46a8b,220bebe3,17c9939a,92db1886,e178faac,633fc1af,4249149,3b8e1c02,51c78d78,5c5ed5f2), +S(ce661b0c,12d51507,d8a066d0,5f43680f,909407c6,9b0de379,875ba50c,c8aefad8,ec469d8b,c9095247,53f92cb6,415445ee,7fb4a67e,d28d3019,6e1e1d06,d585237a), +S(20916590,d0a22ae8,3bcf92fc,91b93643,188d2289,12eca21d,5cefdb6d,a46654b4,2d7bf778,66ef1253,92854ac3,7846a5c6,3feb6b14,ba1b36a1,3b77ac3c,8670e871), +S(ee7c4337,24aab6a0,fa304ac,50501cd1,a540309d,99a63c56,6b20165f,1283cfca,9e3f97ca,ea42cc45,51283884,b19c2d11,50c420e0,745ce88,8ae82918,4db7c50c), +S(a23a466,57083750,56b5712c,2891b543,150c474d,2d02b9a1,8d72603f,b695ca09,f5b2c285,b4f341b2,966e71ce,d1e5c64c,e05e8058,ff2b4a2b,616e6f5c,40f5516a), +S(21193f,20328f14,cb0d47e8,6bccbd5b,e1a2fca9,fb1294de,6cca05ac,f5697768,16147a71,cb2d0f18,38f1e80b,f395a13a,9c630167,caac326d,aa890139,ce162042), +S(89db6f1b,d405c8d,b29673c4,2dad2574,ebec14ee,9cd6ad0f,1ac55f42,eff5067b,20c82a6f,ad90c731,420cdbe4,47e57450,d544006e,16ed9088,e5a77089,4911b3ea), +S(1162e4a3,4f3a6d,6b360059,258a1a4b,2a316064,b2e0aa56,3acf1a5f,812a9682,2433cddb,650c9234,aa4d6d85,f8442d83,1a9fb48a,9e92e62b,aac0ba2b,c90d1807), +S(6c439ed1,e0dcaa04,a87d4bd8,6898fbfe,80fd130a,c4721fd2,8707ca68,d1a99104,b221ecd9,2da68080,ec98c4da,be4c615,e2091f90,4031f875,db1e27fe,4dc852f2), +S(ba5b6e84,f225ce20,7cccccc7,6646f78a,3da1942a,55792678,18e70aec,b651daf3,9c50d8e4,f3e0386,72bed48c,985787ed,62c4aed9,1f32b1e7,482801b2,be4e09bb), +S(deb90434,437d5b7d,32228c47,e3e384ba,4424010c,20689aec,99809623,22cc3527,54ae32de,29288f59,e78e0fe0,b690b148,d60487b6,971e6c01,7561f49e,3b5855b7), +S(19120ae8,baaa0394,8db3e91c,973ce918,e3b80039,15b8df5c,564f8b7,ee7d4485,c260a8e6,e3abca0e,8b84a937,a9f5e19a,160d7178,d40906cb,4b2221f0,d6b9b84c), +S(d3f5dabe,754636a0,741b81a4,5abfcd5b,90b8acd6,94e58419,df0dfe57,e2e45c8a,f58f03b9,5c18b14c,859786e9,24ae9ed3,8d6c800c,57793e64,fc4a711b,71829149), +S(84b37eff,d81d892a,df94d68b,2776ae21,47c56d3a,c9ce48b1,a5057830,eea659c2,b54b242f,7e438a9,ed18b0fe,cc8a4552,dd9351a8,f763a5eb,6a217669,444a96ea), +S(32127236,3f659d58,2e0871a3,5aeeb25a,ab7acb6e,90c1feb4,dff53f4,a3eaf0a,cf01c0f0,8bb8ca11,dc6b019d,dddbbfe,ed3d40d7,2d06116b,62618179,fa8d32ff), +S(1e07bece,17458a93,98c489a8,aa0acb83,21743558,f009aaf7,1be7034d,c6263023,b0b063f0,c11ecbf,f055cd8d,6e43d009,a7519613,44498adc,3f7c87a,441ec9be), +S(d77e610f,8a969baf,fdacde3e,44abcb7c,27207311,c037e516,5a96f17d,a656ac7,645ef0e5,2e4f0786,5a7cac65,54066137,fd8536a1,2a4aa0bd,8f535254,72e731cf), +S(fa630fde,2aeebd4,7ac7caf9,3c6b4523,cecc5f4f,5a26d0d9,a11d6b11,19816c14,acebe389,85a9dac6,f3d80e0a,a4271c8e,c81aa049,d9eeb36a,e89fc522,55ace7d3), +S(e3e53a9f,a0d0286a,f56f1418,20ba1c38,1697e298,49fe82ab,4ae5109b,2bb2ac32,f0eb1f22,e432dc55,98844676,1fcdddce,de875b5d,f7d8cef8,109e389b,8720819c), +S(1372173c,a0754968,db48bb68,87d1c81b,47686f89,c6859fd8,3d608fa,8a767367,31ab8ad8,be50a9bd,99a738f0,345ba781,a2d39e94,1ad9ef81,4d4ed33b,bad08cc0), +S(5a82c886,754bfec9,69fbf970,2d87183c,4c6ecec1,53e50d49,d4a3e1ff,341b9b3a,b8abb03b,63e4bdcc,a58b3717,7f349fa7,4c87afa4,79ecc3ef,7e15352b,6d59d61d), +S(aba39636,9a7a032d,8cda05eb,588a04e,e0b3e75b,dea52776,16af7bc,14423f4,63bc3d87,8f419a78,440099d0,e26f7e73,8597982e,4708604c,e8eaedc8,2c54a34c), +S(1db97bee,460e7aef,f3132d52,48ecf43b,911efec5,1051efda,9a231ca3,a366bb86,8a297bee,fa67a334,97cfd06,211c0e0e,b876e570,e255f415,c37bfec4,bdcc129), +S(d115ae92,b28c2144,a62c6272,50cf5b62,7641533a,e5c2aadc,cafaa9fb,7f180c0f,b7bda4eb,63064115,fe29dec9,4af5f9f3,12a354e8,24827fe5,d33e0737,ac3a8657), +S(15234a63,9b7e216f,7d035d46,7146b90,2812f449,cd7fc332,ac8d773d,b042eb65,8c0d946,a55f5703,1c9ee375,b7e146d3,b1325114,72527aff,d4a6d36b,e96bf6a), +S(25290f2a,b404b4a1,19bf8895,c0c31357,1b9cac69,7d25c6aa,303cfd38,f375b190,f7b23d34,2ac85b40,9729f41e,6977d70a,394c037e,8b43c148,e8d7ad5f,1cd35a0f), +S(6a75480,e949ab33,dec0849d,80e4e458,e8a3da3f,bc7f0c10,521d752f,5fcfac3d,8ed6efb0,3dab1dfd,fb3d7c1a,90419b59,b4ed6a09,b76a1234,ec8f1890,ada92a06), +S(37060ba6,e749f01b,99de96,ca96ee67,ba0c6765,6c1d10c4,8952aae8,80350ed2,7b5eaca1,b6ececc8,87dfc4c5,79cfa9bf,c9e72bf3,a6bcf79a,3877caa3,553a420c), +S(e3bab26c,6646c20,279cd320,76c75574,4177fe6f,77de9821,36ec5162,5d13f5f9,3377bfe2,55a7c6e2,24ca5ab2,e36d535,75bc4333,75bff71a,8ebc1257,5f7fb0e5), +S(ddad1dba,85a9b343,bc53d5e5,956b8b7e,11331b3e,8a572679,4b275930,b9f31e07,412686c2,1acfe9f5,3ddf0e5a,f5ff827f,c3c912d4,7a4a4d55,37a9a5fa,29bdc4ed), +S(6cb6f196,a0deb885,568b7595,c3cd5198,d8755e78,9f194a53,ffb863a6,4858968d,56918ec5,2263ef0a,e34da425,69277e1,be8b7c97,880081e9,1532216e,c3798e87), +S(f5dc85a2,d7c3da94,833d7254,aa8c4a7b,6b105193,eac25377,d20ff6ba,26a608cb,a311c934,58419e7,823207c1,8d1cec01,dab3a2a3,248d1be5,e36d5b1,b076054d), +S(d8d0a942,57fc6e64,975a62b0,4620f382,c8946d2b,3a14397c,6f7465a2,1021645b,7d0c9f12,291e0493,87202b90,cbeb3d52,328a002,3b79b3cf,6c22e1c2,bbf4474f), +S(a9bf9157,b48c2e92,537bc4a6,43d03a4c,a0276831,a00ae6c7,b31a6d44,ebdce70e,34444099,98aa2495,e7d0ce03,fb265ac4,76ed8c84,ae87812e,b52ed5de,d482c1af), +S(e88b3754,d452d447,67b7765e,9bcc318e,2426e82,6f038685,e696b9d1,e2fc509,609f6fce,4e37102b,dc9def2f,77551726,a43d2b7,8d81a672,7997a94b,a6824723), +S(3f5ce314,ec4060ce,9d6ffcbe,bc6fe525,c9f5b80f,7f64b92e,242a4768,5002f619,bbcc8269,297e4467,950bdbbc,e0eba72d,815822fd,6679f5aa,122b5b1c,f1ab4571), +S(fccd783c,c1b4a564,cf93810,adebcc17,c2417f3f,d9358d59,ac32c13d,98c30305,65388d09,5f8d7c6a,1c0a40f6,16748b7e,30708444,acc9f90e,b644727d,b1984852), +S(6e372625,ca297c57,192852da,61b97651,1b0a6306,9bc63bd3,bbc17fa3,2c03765b,3216c5cd,2edfbc3e,1e2da24a,64c3de41,1229bad2,e44b4548,86b4766d,db184885), +S(364b023a,893779f,d8dc892,189f7565,b6642766,439d3e4,f9a27111,e001e191,74ceda0f,32a56290,8d9649ea,56c3bdbe,9a4c0bd3,dab2b99c,f9067a62,d34a9b6c), +S(99374e3d,dea10db6,b493a0c2,3c2cceda,8ecb2b41,6364136e,2f8acbd,51d01791,f9d261f6,733d7826,af2502f7,8fadd97b,c3644559,a1d18162,388c8eb7,b372ae53), +S(f1e858b0,2f8bab0b,12711388,70310289,9f40b11d,ba24c309,89e237c2,e5ae6aa8,3538eca7,9ae4f5cc,da8085c7,b53ddf55,adbc1b51,8d4ce4bf,9f00e22e,b7afa426), +S(96424847,ba09f93,37b83bc4,f5b5a4d,a79bbd37,41258d1f,95dafe86,f3b8751a,af2e7579,e2c1cb46,5a8a5d53,473f7d37,398d33c2,6c51f5b5,954fc1eb,bafc5ffa), +S(2f57a7c1,de175570,8ea98914,787ed66e,246a24bc,2ee81fc8,81ebc6a8,838f8e50,dddb2d2e,6254b5e0,e090ac4c,f758879,1c51b32c,f70361d7,f898258a,a7853c48), +S(4762735f,ba8aea2b,9eebe42a,b1eadf24,1cbfb083,163f8f8b,104257cc,360d308,b03f799b,2b504ad1,e98ca6c9,fc27a851,63fbc620,9de110ba,cbcfe7c7,783a0860), +S(6390203c,6c219a18,e6390e45,e8cef444,ca6de696,4ae43a44,e0700dc6,a735a125,a9e6e44,5a3aced8,f072c0a0,1f5d1d54,8f6059b2,880edaa,fb42fe8b,cd4787b1), +S(2986e39c,d19ad213,b171b4ef,c24bac25,50a6fafd,7907f9bc,440af15a,35926a3c,ac5cab3,b35f667d,e4d2d7a3,48010cdf,bfe0e6ef,67287bc9,ec39daab,395a1e52), +S(67337f65,973e6144,e4f10db4,d8e29ec4,46a03304,b6a949bb,cbac7ffc,ffb4ac7e,66589e70,64003376,8043360c,977e35da,41e22f6c,3c3299a8,e0642b4a,55c1b99d), +S(3f9f9f1d,e2775ba8,96debdb,a7cbe0d6,5d2058c2,4a54eb7,c021c226,96aefaf4,776f68c3,292e0ef0,ec737629,d15c8410,7e40dc7c,fe846936,3f2cb18,b4e772e4), +S(c42e2e02,20f965e5,3b40eda,a3d7b450,24b943e4,2067b40c,4662f6d8,1cdcedd4,89ae9af5,95837e93,6f419b4,7e8e0e3c,a768bda9,a6a5aac,801b30d,b34e0bd0), +S(89f638a1,7ad9e13a,378cd116,38a7ca27,181b7d83,6d8423de,a2ac857,9a1cb5c8,83397996,e70f91d8,5a72747a,9c2dcdb,fe895967,1e2001e0,b8ec5acb,67f4d008), +S(677a6390,82642fb8,dbafefb,7cda5bda,294e6f45,73312359,f6cf6551,ba0f2013,c3d208f6,e7c0dbf,f35ea183,9cce662,df4c0c79,d9ca62da,942a7601,f90c5d5a), +S(e5f2952e,36002cff,3787b459,f2b566d9,aded6da,b00b31ca,88c05bb1,789c56c0,6e635a5c,a6bfe707,f8111c0a,8853caa3,52ae42d5,2835ad76,7e6b0b34,de24d626), +S(e9d7e208,e3550536,e827e2db,1b5e33dd,6e3f520f,eca9c121,38ce6c79,cf9bc2cf,b2c90c54,90ef649b,51508c18,f9e2a87d,c95e7446,7434d9fe,cf362304,6c75a548), +S(76a0047c,a21f1cdf,f1934c3,73ab3c14,801f3342,e96dc8b3,d9c9f9ed,8ed32b33,28c5e795,f0cc967d,36a06b75,51338d8c,1967a2ea,47468a93,a79927a8,b93f22fa), +S(6e25a2c7,1c4d0918,45156c41,a6158082,44141684,a148b2aa,a0a29116,4ce9f7a6,b47a5db,c22779dc,f8368917,ab2ad290,f0ca9387,738a2cf8,f6fd00f7,f7120c22), +S(5dccf366,b6a32767,f0e9f544,315d56,754780b8,ffe31bd0,4cbd4082,8df79dad,3ca94a06,188ffb75,81f6db19,4a40b3f7,c827828d,5339c9f2,1f0bd167,2de0f8eb), +S(4f082d78,87db1b89,744007cc,14743578,634c144f,c199dc5e,6b024570,595aa74a,c982c1c8,8a724114,e164361e,12cc6810,7639a530,97392b24,f11e89f9,e3c63525), +S(73dedc7c,8cd2b6d4,de56e4ac,9fd8e7ee,77f314f4,11d66953,2da150cb,896025c6,5805bc18,3267c258,8a7a5820,1e5c8f59,f05e8384,a380486,af07c89c,1b1a318a), +S(8ac4c219,fa1cb64f,625b7b6f,c1278cd1,2958c9c6,4cbc964d,127bdb2a,e472b43c,7dff6939,5f076e57,6882d7e2,d0fcb544,1e301834,cb5085e6,6000cb23,cb621cae), +S(72388fba,92feb394,fc6e6cf7,a849752c,41665040,54271441,c7a9cdae,facdba6a,cb846fcc,e7518e85,54d90f1c,286b889b,31bc2910,4915f30a,b36bd43b,e2234e8c), +S(4b11582,3f8b93a8,5907a139,5d4ef6f1,2a34576d,bb021c66,9ec26ed5,150e5fcf,ae353938,3897397f,15daf2c2,736c3929,93a1d05d,45268cea,3cd62ef0,a340f5c6), +S(b4b2effe,f45073e1,57b3beb9,59a177ee,89dc672f,c14cf312,fae3449,60064d00,bdfc076f,17d0523b,a83d21bf,e0f78623,ca0e777,eb78415d,965c4f6d,d1476472), +S(8143ce9f,a7b5b232,3d3d6337,8892531d,12e3152e,e14ff290,1790300e,99434113,9b6c8eed,b575ba3f,94029d9a,5e7eb6b5,1952b760,2550e10,babec290,b0fcf0a1), +S(83c04e84,9fd179d0,d6add7c2,6ee808e2,a75262eb,51301dfc,a15e6a16,4e698c51,a4c05e15,156790e,802f7670,2d10dc49,239f8d1e,fc9d612d,c7e8aa85,20b789a1), +S(7f5b9f0,57d3b50c,c39e81e,150a741a,488c0bd1,2ca18fe5,cf871b6f,22832554,8246a447,5609e61a,a474db4a,c9f526f1,197cdc40,86c7ecb0,edd7ecce,2539aae7), +S(e27a13f6,a1b82bba,ae5d0212,e0fa90a3,a6885ca4,684f91e6,dfc8343c,14841979,c9164ce9,a53ef56b,b5805464,7becc9bd,64a49103,70487438,87152f38,237ad8b8), +S(4ba91b4d,e63fb74e,9c06885,340dec13,8f6013c8,f58abb7,5ef0a748,bc323cff,6595582f,fdf487f4,feb2eed0,206bd640,7f1a24fc,3cdb0fd3,bcab0d30,739efdb5), +S(37a80af0,650f33e6,360fac3,19b28e3b,817bad51,bedf9193,c745a45e,93f378fe,5edff10,fd0229ac,3ee2794f,155c7f12,b50a08c6,7b5e6d43,8931af1a,a039f892), +S(65587572,6c9a2bfe,9c2faa59,474247c,6955cf20,1bcf6c3e,513e7b54,2b5dba5f,8cbfa42f,ee790c4b,ea965128,14063b46,25131ec3,72028680,3fe69ae,2e896389), +S(a289ebad,8d4a93eb,f7cad50f,1477246f,1345a3db,7699c9f3,9a7d94c5,1433f957,41ab3d30,9b10aed2,32fb4d6,ebd906ba,50e94f34,9e4e6ddb,a65ba374,d4bb6f82), +S(d70d75b4,93a9b2b0,9af912d9,50336091,3e8278da,e73f188e,9d7f5f5,b159aa8e,fd76cbca,4edacf41,f568b81d,8f854fec,439a0ddb,caa0ede2,5f7986b9,a6ce746e), +S(97c66bff,6c03339d,9b688460,58e4bf90,12273be2,32b1f5d2,89a426d3,72024ebc,3db99430,4cb5571d,7c5ff64e,76a90913,8ba307a5,ee8aafb6,6bc884a7,590d0e7c), +S(b88b642,5b8aee75,ce0643d4,3e2a168d,2b1178c8,a9d3e5a,ce2aa55,1130f8bf,cb954eca,4898b75d,db5f9c4f,68f8d9b8,6fb7352c,112e222d,4e5ea298,6a47df3b), +S(41fdc70a,bca5624a,cfe93282,1550ed70,d31133f1,83692b29,c8013601,afe6d0e3,608a7ed2,d675b20e,6a9cbb69,7df4a79a,f70a570f,a2676830,39b69c27,a984fdc0), +S(3f2304f1,b643cdfe,630e184b,854895aa,c2a03f61,59c70ed4,a9837fc0,c0869434,df5e1d6d,11333420,be9df6b6,5eced485,ff0e4d5d,3ed79ec3,788e15be,dba57b56), +S(7da74b0,687c9c5f,d063f1cf,44b2c644,d51b2e17,49a3f8b2,b98b0d4a,7ab43258,2537394c,a042c341,b5faa3b0,35f5f19c,fc2ec9a,f6f34c52,34980336,1d89fc99), +S(88487901,eaf30bb9,27ed414,1a9112be,dbc46be0,52f43a1f,e910f23b,52073fac,6bb951c2,b7f30e71,9ee77955,50189ee3,9972adb7,fdb7a8f9,f335c8ba,51aaf659), +S(ad5c1c1c,ec3033d3,9f3d1ced,41f2e369,de9883ba,3f78e7b2,5dd658bc,42aeecfd,90001dd,b99673e2,37405bbb,f4d4321a,496f4350,660bb9d8,d5613846,e4e6fe6f), +S(bd8dc061,3da485f3,43335bf3,88a57a50,429d436f,a74a83e9,8d9d93a4,868a38af,173d962a,fa7cf6ea,65c8755d,870e4eca,1ef9ba70,97d9bf6a,be26b575,1fccef16), +S(900c9c35,ac4e9132,4f60b380,c7e80b88,f33c9d7e,242a248f,6425f010,63d99af9,5a6e22ae,dade8294,169c4645,a4bd0e73,ee212154,47a4f06e,6a662a0a,a7b88cb4), +S(e9384af4,a6f649c2,720601aa,7c5e62ba,2c60537b,1fd2c416,b2985601,1d18165,61295342,ed716c76,c4d35706,95a69bd,65fd9a2b,832ac562,59686967,1833b0cc), +S(b053211e,e18fe64c,aba2f7fa,9d8b8d5,e79e11f5,8188a811,12b2f9bb,e61ca72d,440ce2cb,27a783b7,defa2d0c,a0334f84,7d623960,ec5007b8,56f8c7cd,932a89cc), +S(6e4ec6d2,3a333b66,56977023,2e7ca03a,5fe1475a,d82bb93d,a1aa6489,997a65a2,306fbe38,9ef70003,2d69ff0c,8d483ca2,c321fde0,5e7bb1eb,8414015b,c1ec8527), +S(546aaf63,1b68768a,cb4240cd,917afaab,60aab408,17e7d5e4,74525ebb,2638eecd,ab3e9be0,841c2b05,5b85516d,a7d89a82,9264d773,c3d6f92e,4a01a7dc,e157d02b), +S(312287b0,260355aa,7b5ca09c,aa8773b8,27c1d703,eaefe0e0,99097e6,4f6cabf2,eb73ca95,f36a0d11,45ea347f,dac667f6,c32e7ddb,aa2ea5ce,e5f5443b,9de2b90), +S(95453155,af512fa0,8c745c6,d125b76a,d0c76c3c,fa21e64,ee9109b9,bda25b04,958266b7,5200f00c,bbe904ba,80294860,bdf8ab4b,43ea7df1,72badd31,55fa414a), +S(c0846d82,c4e06acf,9208af16,3c854637,242a7751,bcbd2f7c,f0c48cf8,b690bddd,3701a7e6,7161f8a8,8a3c8af6,337a7c63,864c1b08,6cc96321,a1748cf3,f51026c4), +S(d2f24301,44d98d6c,a873294b,26a0f0b,e1fa3e20,96e98fd2,c2fc59fa,3744a432,c8bec973,52fd66be,ddc74ddd,83117873,3ebdbf65,1115fd23,58344938,4f56b194), +S(1fd84c4e,abd5a38,847dc661,158677ba,1c53ca44,4a45fde2,b9f333e9,c5345dfa,59402870,3c5aff7,a508eea7,a419cc32,d2c72742,4e3f71aa,b54ebb37,c4c18afa), +S(441c5505,ccac21ea,630d129d,538cb631,6a315281,d7b5165f,c8e837df,6de93828,9c035747,37779fca,92991de4,e4d771dd,a683c2d,97d15c3b,941fbcb3,7936670b), +S(f48aff13,ccb0f2b9,29e760bd,fee45815,bc1b5962,93bdd09d,ca16feb9,e83553fa,a543a386,5a9762ad,90c4c270,743db1af,6a5764a0,ab75415f,3c8be28c,8d90890d), +S(2758e9f4,7bc46ffa,19a0d74a,1a9faafe,effb2c71,5f271d52,6071c340,78228f69,1acdef34,44060612,367591d8,38256b45,1cb883a6,d749d80d,12edef00,ade9290a), +S(af1d3280,417af143,129fd94,cb216f9b,d73beac7,c09a9d31,e7db9023,f568c3e8,27fac1d7,6f33eb8d,7766cacf,ff91936f,2c540a0a,a0e60c9,a6942fa4,2329ea66), +S(299f64ab,28071d25,4614d985,380918d6,944174db,1c9d815b,bd334e80,b961aa0f,80ac4e19,47b1d355,ab9a85e3,e8c009bb,f6ee09a,9f99c599,4a81369,607ed3c8), +S(b45cbdcf,14222123,d45d9f19,bc92236c,6ed90909,91081804,e0bf57a5,e0c724eb,1330030a,d6b49e4,5106118,1c9ae21d,606591c0,e326c5e6,ce09ef4a,37f1d15e), +S(be8f11b1,c27d3ccc,40224467,c26ec9d9,f7c60038,deb6b296,2d3ee415,11292062,1db86cf8,130bdeea,debf75e1,8bdf0d7,83357050,b7c4079d,1eacecdb,19b7c34e), +S(9274a7c5,af18755a,ecf84a48,9a0c81f2,9debcc09,9e875e76,fa3572fe,9dafe482,539bd087,e98d5d23,49ba9422,a99f4f3d,4241441a,59347c9f,57526ba2,358bdc98), +S(8455cf49,a3e4806a,46747459,ea510a3c,5ddcd79e,1c062750,6478e38f,1577f3d,dd941fca,cb4c717e,3523a7d5,6206cbd4,3e4e2993,36f7698e,605b97b,4d927b5), +S(8a4ae542,f82437db,801fc18f,ee57f9c6,d355d55d,29cbfef3,a498845d,5acca7b2,fce5096b,712cf054,bea762b3,521ac601,946d193a,cb229791,9409145f,753b84f9), +S(1de9a879,fa9677,69fc9f3e,d0ac8bff,327d284,97278947,7672a972,bdb192f1,ae095175,6c8dd516,b1bf6734,ff4f6b11,4dc0b94,3d01659b,4525347c,3be62b30), +S(764826a8,88303d4a,45db3a44,7fe13a8a,555f0973,da32ab3f,79c0b504,81ca23fe,14b29537,dc0e8a79,d2a64d1f,d8eb96a3,9d624216,deb614e5,2102b7d3,45dd9f1), +S(19470720,24d9f677,652300a,da20e5ff,39814a7d,daa7a363,ad3100da,7ca8cd3e,c7d36a40,62edfcbd,243b7c02,f0313494,4db0d7d5,6097018,23e17244,3a49b4f2), +S(346e886,d5a228ae,5b894ba1,fd25465d,47baa88d,f2c48000,9db7562f,e75f5e26,f2b61353,c4b6aff7,52318707,99e0e262,8c7d1da0,6b510f7c,bb995ba6,e1048f), +S(4aab5528,f4423b9,9485dacc,66de7f6e,94c34b6d,623e9ed8,538b2d4b,97f74fcf,a9ffb993,3a816aef,69fcd7d5,78930e65,d05afb67,55370005,4913d30d,3f2f5759), +S(3265157a,52941c75,a280bfd8,780e1ac3,62f1f5d8,20e62ca7,ed7d8b86,1440642,1dcf93c,525ec12b,97d1a700,f09f37f7,2d57a4a2,adc359ea,b1a514ac,a8862e9e), +S(74970421,4aa5ba55,2d0ea93a,b57d7788,5bbfa9db,2c074169,345a6c08,5053029d,88ce8b1d,77f1ee5a,63967f86,a8b77cd5,c5785f18,73566125,7c99358c,9f78ba1f), +S(6060ee1c,bdd369bc,a0e75dcf,36bedb15,a6c168c6,a65e4d9f,f065bf7e,c4afa889,eedda38,3a9aab25,689ce477,75273558,f2757adc,4a4d78a9,b693a1a9,f57a6e90), +S(6c5ad52a,ccd3dd47,427ed711,538e5517,7aef476c,e9a3856e,c5ea6b23,60b5cb41,70e69676,421bcd4a,e23f252,a4d2201d,ab77846d,9fa00303,60f39880,6a252b8b), +S(59b3bdd4,e63f22e9,7bb57319,c5dcef38,573c40d0,4dda14f0,cf799479,abfd0d70,be998425,f4f56645,2eccbb83,e4ffa58b,1144d70e,f9a28249,5bdee74a,6904c15), +S(d2d11068,deff8644,b07d75e5,6eb440c8,1da830cd,427d4b2f,558150e,83fdf333,41f882d5,5b07cfd8,9212f717,77b3a846,ca57ea11,c40d480,16db8e11,f3faac3), +S(3a87cca1,e244a5d1,b237d776,a170f5b5,5efbf254,dc1a67cf,f9578af4,6f9d784,47b25110,42be177f,bdc07222,9bae8b89,8e6b2638,6fdf236f,93148d78,31f71fba), +S(82f63ea4,34aa60b6,fb16196a,c2979486,12a12e50,c5ecda17,8e0f6317,d858d026,22a4e99d,e5d95329,bd8662b7,82c32ae8,eb0b494d,6dc1d395,daa7fb23,97c5caa2), +S(bbdaac46,6d3bd845,fe67a5fa,3ee5ed3f,cd2e762b,e35220b,e9fda52a,51795bbc,eaeb68f0,4ffce7d9,257236f7,f266bd5a,a85833d9,f4a06eeb,766bd426,b403b515), +S(d3c4d162,862026ab,9263571f,4df35e1,c0789887,99bffad0,2b677a63,4d20a367,cc6b3c0c,c1cfaa4c,ebaba6b5,57b914a3,f23618aa,f7282448,2f3d6ff9,966bc6ef), +S(558d059c,52a0b251,462be6a3,d8e0020,f5c0d6e6,44407dfd,62828a29,8eac4f3b,bf82d395,2e5a6d58,6108ee1a,f7bfdbcd,b4450f4b,30c72aeb,6109ed01,7c338a7b), +S(880bf94f,48db9565,cca7e8d7,b646ab31,e9be0736,727c4266,ec68ae38,c0a04196,8cc3decc,aa0fbd8,36aa86b5,ca245e74,8e22e8f3,1b34fa8a,5a1de2e3,32d10218), +S(5bcf6861,946ca2f6,258abc7a,9db72de4,20170290,ca0c6765,9bf93286,5d806dd0,ffdf39b7,1a08f3a4,1be73acb,d9ee2924,af21c53,22b9ff48,94408928,3cf22d59), +S(53f70440,f6c09489,edaf304e,c064466b,2bd9ed5b,e9affe95,a8cb22db,d842abd6,a7e74cf4,55af4dff,3b3bef74,902daa5f,da664d20,be94863c,63cad3be,30b13ab3), +S(d6c95017,439fcd33,9d122e80,a36ce813,f8eb4312,2db80ae6,e4b09c5f,277237ea,b9ce6112,53a6a066,7fd411cc,a1584cf,b1f05348,240b9b5d,f73aa3f2,637073c), +S(7d78776a,46072c1a,15c23544,f013d058,a3485a49,83a1593e,aa8c2c25,351c0bf1,7caf8c7f,c802918d,602be0d8,48eea77c,58c9d65,15a7f9c4,8df5e3d7,ebc941ec), +S(30586c43,54218314,3881348b,e81076f1,e8d3b527,8bbfae38,229ab1a6,6b9a49c9,d3e968c0,f94cf4e8,85b22bac,45cff2d2,e2fab151,36b2a2b3,fc2949c,1f9698f8), +S(93b3fc28,34ea8639,8a15fa40,2ff48069,3bbd0710,c560915f,e66b798,2e402625,e9382fb8,5dc35590,27b78b8d,13730cff,c2b4dcda,64d27dfa,105fd5dd,b307436c), +S(27375095,c1ae101c,11f6fe18,cb926f38,175d90a6,9e394884,4fe5331d,e466ec87,6aa32240,9ad70cf6,1b8ce6ac,6c518959,accef648,37839a07,8d18aac5,51ada043), +S(b4ec8bdf,f517180b,5c87fd51,e5ecea5e,5ea6d107,525fab0b,6b80a0a8,d462345b,76950c00,5a2a7e57,888082fa,631ba270,af02a5c7,73e57869,f3295ff,74b18bf2), +S(efbb3723,c386d2d2,bf0806e6,c42bf0d2,4bf94b7,b10d0dbd,d4ebbe06,d0a22d21,af0d1096,4781bae7,c7438228,b2525fed,962bedb0,b741cacd,9a7027ab,6a3b29a7), +S(2b6ebf5b,24e78685,65aaf770,ba36142,51bbfb72,f49af29f,c55dff7d,a55674c2,396a0cd1,886fcda3,172fca09,807c929e,afe8b5b6,38d63b05,6baffaa0,743ed723), +S(8229420,323c9f9b,d88bdf0a,ac9035,fd33c3f4,b1411cf9,28a248e9,bd71f95b,e8566565,2dfa438e,289d021,4a1531a5,632b1369,24c01cca,6897842c,1dea3995)}, +{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), +S(c3d305e3,8e23eef1,707ff287,74f82631,ffcf3814,ceac1e41,52d932a1,67c24c51,10234701,f8a8bc0e,66bd6d38,d3924b0e,b57bc295,2d2c190,e6ccb935,2baf8778), +S(1f3f8c12,8d216272,ccbe44e9,43e82acb,d91ad650,72bd8ecf,adcfb1c4,38c44272,e5c4b103,a42d6238,39886157,43bcf8ac,ae397188,1abd5299,d8152ee5,674bb58f), +S(84f33b31,be4a83e8,6ead05ce,df1c9eca,57c60eaa,fa917c7f,56f75572,902d360f,854aadec,13bb6307,70855f06,a77ded40,5be99eaa,93a06b08,dc0fd7f7,525613b3), +S(9b4e0dc6,aed24421,2160f3d2,a0ad4ea2,8c9193e1,e442f632,a956b03,7f9b4db5,4d3d4970,9c0a7244,5e0b9537,2510902e,6fcf18d3,be72cb9d,c3c8a252,cbb593b9), +S(5eeed41,8a5e9d4,fc0be136,b5799c78,bf819dc7,32280d6a,43f10f39,e17cf8da,7615a870,c5cfeb70,1ab28456,a912dd6c,c2b87fe9,8aedc101,bf3beff1,89edd2e8), +S(413932e7,c2e1fe6c,dc1e8330,3c60e361,dcaa1fbf,88e3f329,96a77df,f39b594b,6891ea57,c7572d9a,b134ec3b,bbb65547,3e6932db,1d34a142,26b806f0,afc2cacf), +S(f73a8ee3,b7345479,19a49698,af05acec,1771cfa4,91d3bdcb,81cd997c,b63ce64a,37047e7b,e5742560,9e1640c6,5e89b560,138a00c8,e11700af,3061c185,4bf8a2f1), +S(5edb35c6,c68b4956,2cb6a0cb,3e75990b,7106668a,fbb71f37,2b167e49,5f535b9c,deedc3a8,56a5ee53,60e34c44,e7169af5,7a86438,b982c966,48e37b64,683bfc0f), +S(71eb89c3,8f391043,3c7c1b8f,a3689201,ea234d5d,b82a78ad,2deaff4f,c2bcf53b,350f58f8,1a2a8a76,4c70b16b,6d6f5040,882ec073,1fc9e3e3,f09c2daa,f113d5d), +S(ba4b99b9,71d6e91b,32227a44,be3712f7,93908f54,9ea958db,c1a425be,ed53cb5e,4b985486,76b813f5,df3c84b4,ef8f3279,94c65e14,525357e2,5f82a782,f2e1a041), +S(1975444e,ccabe01b,dabf3542,f3bd4651,94515698,c2b03f16,fb56559a,8d5c66f9,88287b5e,140a9558,2e65ea24,613cd20a,e2811e72,3fb8b12c,dc7c5fda,c5e0f50b), +S(e1ef5109,f37af125,d6f01cde,7b90dd77,cda704d5,121e436d,8ee8bf15,e2e4d4c3,458d2e4d,c8cd77fc,10b26fa4,c19f202b,d66fa6c8,e2fd2e4d,56299e7b,5fc9063f), +S(983839a2,7b582450,5aba0977,80dcdc26,cab2250d,d895a876,b17a4a82,3faedf63,e236159b,9c330576,cfb674de,a1bec238,3018b697,b8e41cb6,1992c5d1,bf49c588), +S(3f4997c6,b1efec78,fc198097,af19e301,16efe029,3cf4ac86,dda22ff2,78394c8f,e92d795f,d14cd101,eb15c75a,41c854ba,267d0557,47c81536,e887f97d,b67e3be8), +S(1095049a,b90e7946,c24bc411,892f911c,6b72d0fc,12af1186,ec43dc7,bec41a6b,85cfc876,55842640,8f24e382,a4e91ee4,7411a3d3,f4a257a2,6419b495,68363dbe), +S(567729a7,12f183b,e7ea601,68aaaead,594a778a,e9b936d8,a397a78d,f53ff5a1,cee7716c,68bb61b4,586d03e4,95f7bf0e,7c215870,e9f1dc0b,1f08111f,d855ee4), +S(ccfcb55,f8da139e,ba60480,ca57d942,5fe16cc0,902ba610,fe8fd2cc,cbcdc016,4e4d8abf,8517b55b,8f6c0dad,3adc94e6,8d995917,de33d623,432cdfd8,188ba22a), +S(869ad71d,22fb7aa7,7b5b65e2,c7b85a45,34185b07,a70a7a5f,fdc963e9,6de4c2ed,3bf234ab,30c8244f,d7a6671f,cff79848,ac53e1ff,fe104aa3,387824c1,f6a3659b), +S(5288d151,6d72c379,e14361e9,41835760,73e67c92,6919ad4b,a69e29c6,43d416e0,2f010e43,ecffa3ae,3d8200b7,e6f35ea5,31cd3db5,c5079b33,1ec1611d,1881f8e1), +S(b771768e,9e7bdb3d,76ae8a00,c4258be1,db77c45f,92318dac,777e9ff1,7ad71320,b068224,7f3fbb45,8e7deef6,7b52710a,5c6c38c7,5a94c154,9e503d81,72da0fe8), +S(7444e64,88164e8e,575729e7,88dc3197,b32d04d7,403f9565,611ed212,a708b98d,ea2a9cd7,49c5a3f9,f2d509e9,5a69745,a5ff933e,1c87c141,ac5112c8,b70a4667), +S(6e995fdd,ba6e0954,cbf84ac1,1d0990c7,ec5fa3ea,6b6f070b,2a68844e,ecea4ca0,743017fc,340132db,cb1d73ef,d1bf5bb7,95b8a0ab,8b898af0,3b2f36c0,b5b7d921), +S(b60c9741,38e10b6,e879b4ac,8de83494,7e345e8,cb5a4320,9a5bf1cf,286f0f85,469d652a,c9cf7d15,268daacd,4630da47,d74ae560,6ecc49c6,9ce00afa,df51d990), +S(70f4f8a5,42de7bc8,48555b84,6c058d1,eed230b8,6864a079,fb91f662,ed27f6c6,21323c29,bd6321cd,e946dfdf,d705894a,5025e2aa,abe9a0db,5efd1223,db2b2457), +S(b23f838b,3aea4309,7b1fdfcd,bad0a3e6,225ad4fb,a01ad0c8,49985f90,8a7120f1,7569db8f,46491a9d,b6566f95,92e126e3,6fa681b7,d0653b53,c45e2cd4,57c3bc4b), +S(9e447e8c,5d040a11,4964ac92,d91eadd4,80597e42,5181be50,5027019,df6ab481,c58a3c86,7fa55ad9,46e0f3f2,729a389,b8da3706,81c895be,5697090b,310e8834), +S(6f98b221,30ae2b8b,4f5852e7,d7e6ef2,1241ff92,ffb63148,4c8265b7,6d863f2a,c4f8bec3,3f9b7f66,a9827e8c,216489c1,c93506d4,42938861,4658e7bf,239a6419), +S(ecfcb0e8,f66c9de8,4d4f93af,e890e083,1b785a19,7b7994f8,c6d5ff4,63532df3,4d1d6d29,429e7c92,4f91a6a3,43b8e805,748b420c,b5536186,9c709033,87696ced), +S(baf48656,8401761d,2994b7bd,44d886ca,9a1dcf85,14f1796c,5b39326d,8f9d5690,ad60d65b,28f193f1,5a120a7b,9bc692f0,100e6189,d26703ee,1a941cf8,bbfe0e2f), +S(574e43be,ee264130,8e0e8d5b,dbf3f28b,3027c865,e13184d2,d2e1256f,4c56a401,e664d4d4,ecbae2fc,45cb7963,e9722bb0,8e72ce14,82f97e69,3388090e,602bc9c5), +S(b289585c,25bf9b38,9d89b7f,5b98dc76,a8e7ca73,f753aa26,f5d6ee10,27e3c41d,7cd41d56,6a17bf53,444f8ff2,3ef7d117,4459b1d8,1bfb1534,cbe7828c,e717ec68), +S(61ad4ac1,7baf7294,a482354a,1aefeba5,882b1353,b898bbe3,815103ed,14eb0411,d09a31a0,2defec0c,fa80ec5a,d4412b4a,fee6ae94,559db5ad,1bd7a349,142b352), +S(adc1d894,31f83ab7,a6ee5ac9,49b0b3b,62a28c80,c5737387,47136161,494e967,bbc7affa,2fe3a76,96cf69b8,e0c95b38,5f836d89,638ea2e5,8347db7b,dc316d4d), +S(345384f4,491801d7,11dfaae9,f7fcc4c2,adcae518,a993d0b3,f43b0e47,5d440b5b,bdd2e3ca,a0826774,e5e40693,c531cd7b,49514b2b,fec5b39c,9d995106,dfbfb5b), +S(e2fff030,ca48a7cb,6d587044,fdd94a9,d81f5605,57750b77,7435ef6f,f4af95e5,847990ab,1fa110a9,ff895c51,20d9a300,c805b343,3b1fd578,a62815be,77cad922), +S(b0342b00,a1bb6391,7154ea18,f3ab0649,45051137,1004c15,2a6eed35,adea23b2,1cbc4c91,888f52d,efbb6551,bbac455,ade7d78f,9e507516,ce0fc70e,d67e2515), +S(948901c3,3f670c89,e4393400,14bf7e4c,e59955c1,959929b4,ee74b3e3,112ad9a3,2a39d44c,93906444,48294f82,bbea8bc,b431d2a3,48435b88,5eeab283,ce9c49ff), +S(a7f64583,3fd0a62,367d4675,b94a5a49,f9fdf94d,c6597ea8,164a00ca,7a3d5315,b4fd7015,75ab42e3,9d51622b,c5639f5,9b67fc4c,a4f2f62a,7b6bc3b8,fc037d3c), +S(50147d69,fa4c421,25b1b7d6,74cca767,11db050b,fd2efb0f,d2f05036,796f446b,5445ac4e,674244d3,532f046e,127692f0,71057a33,b7b40f73,b897e8fa,213e2ce), +S(ff1db721,3b669b14,1f92a729,de0952a,86da626,97fb91a4,908441bb,117cfd00,62e7eb6a,3060afae,2084883a,662f780,ba42efda,13c1509b,13123789,364aab01), +S(29ca39b0,ca50e1d9,c718e00c,7176c506,c2eae92a,157cb0c7,1fc50790,7278b727,61bb5ca6,85823de7,fba69cc,1cf9a21e,eadffbeb,15267ada,a8def3c9,a54de3a7), +S(62cd6a0e,a50250da,650615fb,de2e19a0,6d0b74d7,316d7445,79f2be9d,f4023545,bd75298b,c2a3ce99,7e7eaf8,fedd90e9,9dcff8fa,e345ec42,c85e5ecf,61ee1654), +S(4aa8cbe6,57418299,e63f85c2,38d077b3,a1162f88,7d9430c6,1ec2fea7,ada0a758,6e360a94,7b07c27,9fd97867,e2ddd59e,3e77308b,169383e1,a7174188,fe507bf2), +S(6640eff0,e4a7b619,1f66b3c0,ae5e0b7d,92e2955e,23ee7beb,8ebf2e39,65ae591f,b4634bcc,7ef0e6f8,5dfc3694,27a0fa2b,a0e9c0e9,caa03a4c,fd90b50f,72feacb2), +S(d899ae0f,b22f7740,73013f98,9386e5ba,da6077e9,dc49feb5,ecb195a,bc6969c7,2dcb982b,e71ec202,472b4c77,d725c59c,ef6a5725,606d8226,30482554,16eb8287), +S(c9691967,9032dc88,a4580ca,b338fa3d,812ddfd6,7067917b,a2a1289b,5330c6a6,47a8d9ad,608a3bb5,9eabd2f1,8ec9bf89,4c3cabb5,97ff03f0,93a89d8c,a6b4fc82), +S(a4d25f7,3af5311f,26435b3a,31455ec,ee7a3b6,d6c7e850,14875a23,a7ad35c9,bfb5b89,af0362f7,f7f20fd8,a442c285,6f4d330d,247dc6a0,f8434a6,6c5a6d79), +S(edec5d54,3804127b,a814f23,3aa3be2e,e5e46a6b,ec12d2b6,9ed7648f,c30ac1cb,d6009320,5fbdae39,38d1f797,a5184457,7b645345,c36f1d80,705e3c82,f97bfd78), +S(257170ba,c36336aa,2591c583,48455370,9192432,10eca66a,79001a4c,8f340577,13a0acff,184799ef,a7211d79,41340b6c,ad8732a3,d57745cb,383bdf42,ff8e39ed), +S(f5ae8c79,b6a65f05,dc014993,7f60b25a,6def44ac,30275e9a,d787ba73,fc5305e,5634e58f,b5603ba8,bdcabe67,7f757371,c377c1b1,3f67366f,c36027e0,d953d2c2), +S(86c0376,2172c6d9,f53a9370,ca9d1ce1,79a2bb2e,c48211ce,d06732ac,80c9402f,964b4829,a76d7654,91e6a165,504b2302,5efaab99,b4cfc14c,2e84a801,fd220d6), +S(3d481453,e00c8714,4c6048ae,e5e44267,1a601b5e,fa6430fb,54203ae4,c6fd070e,69bda5df,ce150a83,d861f309,349b3397,32620170,d2d9c259,5507c7dd,591f0dc5), +S(8a8ef7e1,733c3e75,c3b39fd,7cac0656,6af1bd74,a240fcb3,b52979c8,2a56e2d6,846956b2,da6760b1,852cc3e4,d0eb39a1,7fd79c78,73dc1c65,9afb53b7,b25db246), +S(ec2eb41,21923a7b,4449d61d,9e9a996a,75469c05,e86a4911,16c15206,97d741e5,488c3501,9fccb8c8,33b09546,9c27eae8,66a133ab,991a24bf,c00691b3,9e1d5be1), +S(a8c08ac3,b959476d,8e58e8da,72323b81,33f55721,318c664c,ff5eb491,7aa19562,83bf5e5f,d76c877a,f10cb1d0,8b92d9e0,3a8f7db0,2c571449,ce3f5ea7,adb3d9c8), +S(eef63253,739af912,b7cacbdb,3e190add,f2931c2d,e0997fbc,5ce02cbc,56a53e75,14c4d6d4,5143b60a,f0a75249,42582d70,fdc17027,e13a2460,84523417,9a5cddf8), +S(65dc0be9,e7028f3a,c15e5e2b,1d27d339,d12a3a40,eee78b5e,4942975c,f65a781f,d635b3a7,97b5ac7b,c072fe35,9a7ffdb8,b1aecb13,fe933b3d,cb627b47,abb2e652), +S(e0cd5d6f,81a70576,2c65193c,c0a2eda2,aa5ba2b9,c9fbca52,5148a4c8,2f2c746a,5ced8640,19c48e1b,8f1f97da,ea66cb96,fc71ef84,36b87a53,e2b5a841,1d474cd0), +S(66d2d27f,eca16c6c,f8a68712,85f4dc01,92fd503e,6fd39cbe,89007d76,20a966d4,56551c4,ba79a293,fbad2b84,4dd1f5a7,a6c8a688,656a79d6,764b9b0f,df4f45b), +S(36d496cb,2749b975,9f4474c6,a4dc0283,e19a2e29,1c488623,210ba1db,1154ebe,a46cd868,c01b05f3,3508961c,61f0a83c,3ea06996,829aef29,37a93c7e,8840514c), +S(4f53c3f2,5a858506,e11681f0,dbfffded,b6bfbc8c,63ed6d09,3028a55c,c19683a5,2a31675e,7e0f8382,625bec94,83bae5cd,76602e36,1dac153,45209b10,78fdcffe), +S(9c6719c4,2f375d6a,c2891fab,c71bfa16,a40ef26d,b0ce93e1,46634221,da12d8a1,38c92598,10c67724,14f83d45,db2a5506,a993e277,f20a8430,97ba286,b2be9afc), +S(115eae71,89f32e1c,28f86c62,abb7cc2c,5fcfb927,6b3d7655,8f7f1a47,8c9ce0b8,229377d0,9b80dd76,4fab10f9,7cb8c1ad,5f0c89b4,47ac663c,780fdf6a,71a0acf7), +S(4f06c1f,ca76fc9b,d58fdd6f,12d0c64c,df9ef87f,fa579b3c,fe7f8819,aa68595b,12292991,95f91eb,18105a0d,b576fd33,1eba5e9b,f6944557,e9a54d9c,c7ac9437), +S(1f18b838,ecfb11b9,34a37132,6d765ad8,b4a1f11a,6ad51d67,3e7d5bc6,8823e742,fe6d5003,e851cbbb,1d575d39,d48ba2d2,de8858c5,95e2e73b,26127e61,fea194cc), +S(905708d9,b066738a,252116d3,451b2330,5ad84a12,92199acf,1bc0eb86,b7209109,7b3cb65f,6f34a189,584ce179,4112007c,71b2d6f7,9667880d,684768e0,9d706d0f), +S(bccf7efa,808ee0b0,f19080f3,cb4c0fa1,2dc46c87,2a7ee71a,1c1a171e,b9f03962,66b9d38a,5582ad7e,8ed7b0c5,2d4e5aa4,a14fe624,a51d02cf,7553f7be,fd2f9ffa), +S(fb6505d7,2fa3e83c,26d7cc0e,e8e8e160,1c46ff4f,299b06ba,7b5250f2,a20a4ca3,75935eb7,e923dffc,c3b0bf80,4861a3e0,a721266a,1395f424,16f26d27,9a582ca5), +S(208d0bb2,1fee812c,e93934a6,c5571d1a,a8d8b6eb,3ad58357,90661718,86a4c103,7ab4af2a,e062e5c3,9f83467e,31d95f4a,c1e0d0aa,d77e2128,a8916233,97379bce), +S(8ff01550,87e8359c,f5081e09,71b5b80a,e482507a,217114a5,8115577d,ffbbd5a8,47c83838,5bee81ae,6738ccce,e1149821,e433b9e0,e11cc919,3bd180d1,97a07519), +S(dd938972,59966349,9edba2e0,1932c7c7,883c99b1,11f3dd2b,f6b079,770f7cd0,c485988b,373de68c,9a07d8d2,3d8380d9,ce28f9dc,9dcd3abb,99705aec,c87f0ea2), +S(247f0d44,50e75f8a,724bc9b0,821e7e62,cfcc6983,860b1997,c73b7b90,515cbb1f,6b861e4f,2f5e0cf,38d91847,f5d159b2,25b43236,2e67771f,da2dcb2c,d79644e2), +S(2deabce2,d1d31515,86894e19,1a5af1c2,7fde9b45,455910d9,598adc57,e46c8823,77016b04,643d44f8,6f279dfa,1a86f3ba,428493e4,89b16462,62e018ff,d70efd8e), +S(97bcfcd8,dfd8f0c8,e7c09773,746ca7c9,de813c3f,14f6e39e,4e597559,adfd7ad0,5f948bc1,84d2ed00,ca4d3be6,6972c568,916e7120,cedb84b8,29f35cd5,dba65e35), +S(d2a6e659,e88b061a,e26bb48f,10e4f1ea,30da5df7,2e9cbe4f,451fb413,c0eb9c00,d6c0e56f,cb2d383c,dc77b93,2c41566e,acd21f2a,93537f4b,683d2f72,547d9779), +S(8a3069f0,b374dda7,b7c1e34f,80ade1b1,b439e517,595a5c88,8e3ab8b2,b2541e36,b13ecf0d,729b7cbf,aeb2ea9,6a80e6ae,32f9d46f,57ce4114,4c24f61c,b0c7183a), +S(6160e9a8,a3c82af9,bfe8468b,5142d7a7,32d00cf8,2ced3a6b,333c188e,ee6c0df9,9c174f47,42f0d46d,aa03966a,e00595af,355c39d6,a7b17ab,637580a4,ab9802be), +S(ff32347c,eb8aed18,ea6c314e,15ba2437,702b9d8e,a775f6f,a1b84b27,83837b2,d09e3f86,e37d1190,9f6ea512,44f9225a,6b8570a0,c90b8511,7a1eab62,f3220a37), +S(170d2456,58ccd0fb,d8c01df2,a84132d8,3eb94d08,d8fb7b53,a929fd4f,38ad26cb,a83ab99b,176dcb0a,e80c5f50,5a454f15,12622c22,e6f7309c,7a827a59,944c4e8a), +S(8acc0889,91014a93,e3649980,b6eb6172,44f56e10,8094b6ae,a7f16e19,1e566e9a,ecfb977e,a900e0a1,f6b8247d,703ebeb1,4524d5d6,95f6e46b,85ec9e52,a5795a85), +S(f80b78d9,22cd9e20,83569df3,ddf58b41,dadcc3d,2a3edb2c,e31cf234,5a31cbf3,fd1ad87b,98a42acf,273a268b,c4f7493a,cc28cb9f,9794c833,153a0947,eaab549b), +S(41b21d40,5602d26c,78028eb1,acb7160,9e53fb02,7215c405,edd90586,1fbc1a8e,55480fb1,3d718aa2,59f4cf19,b7eb7638,2d07c372,c9202c87,b7037993,90f309b8), +S(3d49ee22,22bc61a0,9cabfe95,bd981686,73c2b42b,5d22698,21ec7cd9,6a488ce,2d461269,bfc6dae,48280ed,ae07ca1d,cb8d3e8,a1c9404a,971e416b,d2a5cd2d), +S(7f9812f5,30f80bab,f35a5df3,ac0c4d68,7227fa14,74ff6057,1f8faee4,32cb8c74,805fec79,b3607318,574a9308,831c4db,1fb1cde0,c0094b6f,6e19b924,35e0f118), +S(d5a33585,6c8da16a,6ebe776f,3cd08d7,e32fa2f5,c484a299,6abb9e84,60d0cd6d,fb1e3d96,f95a139a,2c968563,73813e8a,7cfe6ca2,bb97ed22,1e374337,9637668a), +S(a138a71d,854f2f76,5f8d681e,84e91b52,9940c342,8f69184c,d469edd6,43d2ce2d,ddecbce3,a48b0457,66ef7511,b041f6af,f2df22e5,51aa033a,8325faec,bd9ef061), +S(d9a0f20a,ebb51238,14e55212,4b6d723c,1f972951,446d736f,b4d20e5e,a9dc2304,fb63e167,90c817fa,40185611,ea346e18,a12fd1da,fe3266ba,c8c8dc1f,2312797), +S(31b4f50a,d3476189,62a34537,10a1a995,e9e25283,af87725d,e2767e08,4f276324,98b32741,c8e1aa6f,70655814,ba0f34df,7f2ac7d9,40604bb3,4216d8b6,9e03d07a), +S(23105202,c01e6e2,6fc5da32,5d65644c,e067817a,6b54779f,fb9f1faf,57b15a5d,2da13e2b,63b8c792,56a7b49,c44e0014,9f461967,7f2b4709,d158aa38,189f08), +S(2e9bcbd2,8fa1b69f,76193011,9ecd8f38,c88d2c7e,f051780f,cb82d587,8e5fab55,93ac2ec4,33abd509,fa71237e,9ab6a421,4d453bb,9fed86c,2bf9b727,a84de903), +S(7a560f5e,d2952cf3,342a1273,5c627eba,49eaa668,f3ea67d1,9a0bcc92,9b172ed,32d1b9e9,5e1df2de,4155bca0,bc404615,957b16b3,45568590,74a119ec,a24eb984), +S(10d8b5b9,f230099,9b15ed43,17282c23,dba62c42,6725e112,6cdaa3ba,f07564f2,3e5d4465,4ff6faf7,3d3c5a64,bf27251b,de0320c8,b8f5e7c3,f2933225,4f0832d7), +S(924850a5,d61c8491,6ae458ca,491d87ac,ca095e0c,3a37e5d,528785e9,10730e8a,6f115681,341d7598,552d8eb6,7171ddda,40594be8,5da3b9d7,7918d2d8,3316c738), +S(f36a988d,2be42bf9,d39a2b40,c2447f81,6dc2a91d,20edb89e,c8b00c97,c972d837,56ccee9d,619f4b0d,2fc0ec9,ed60ef01,1f10b55,2569dcf4,dd922917,d8912764), +S(7a9b644c,a0b45902,39849b1c,b03687be,75be77e9,b50685b6,1c9d7052,5933ab2e,ac13dd6f,d4f8cfc5,27990d16,cdc88720,4a5a14a7,f15287e2,7b5b4c9b,3ecca461), +S(e9de9ec1,40076c59,afa8264c,e4ee7209,5b88b08e,dcfc120c,9a3e9003,72542abc,284d6201,15f1f94e,54bf097f,b9407695,c62e76f0,f2138bdf,932da8cb,86a13865), +S(aa9ac192,d202973a,2074a2f3,7414ec0b,6ebecbcd,f201a6fc,e43d74e7,8544bac6,95fb5730,f524225e,a7af1ec,8e34a6b,b7300dc3,7df97888,fd0bdfd7,4986e2e5), +S(31b66efb,b2da072b,16d9b35d,5175dd6e,96b8c227,abc0f2a5,94e02f9,e693a20c,e3c18398,aaf7bc6,776f306e,23b1f001,17fdf03a,72474f2f,ed3b0d6b,70cb5baf), +S(7eda3d4e,2257ae72,abe80be1,8edf5496,3a8bea8a,a2be745e,8402734e,97d19d4,ce5e61af,de4301bd,974ea8ed,8239a368,bb8f0b57,1a6bd9fa,c3327594,c4abfad2), +S(297bab00,4b5e8c60,b27fc169,257f1217,48af6f99,65caf54f,67ce172a,e69e2b4f,eee4fd66,57a4aa8e,5eafb1a,e95e466e,976cedfa,b32f8f4d,31a820e0,cc470eef), +S(389f8ab1,2be46a3f,e5d2fd38,9598890d,cbb8d1bf,fd36dc10,8cdf8532,91e477a6,530394ba,2647c712,aecbe545,dec368b,21eaed67,a9d694e2,abfe1e83,1a2ee1ae), +S(36122688,726cf2a1,b2ac26a9,375608c7,2024a751,6543ce67,2393159a,98fdccaf,661b4134,4ed2bc7,c3596a83,b812fdbc,ca95cb74,f7b322a6,ca1b8167,aaf34666), +S(ef5f9544,a9c4148f,6a637ff4,39bff5d0,9bba2824,1d115c37,a5918070,d02f9a8,2111a85b,369cfc85,6db8941d,8af8a357,869712d3,76ac94db,55f3e0e3,e5e8770b), +S(d2c7599,c6bd388d,def00aed,b0cf74b2,b41646ff,5bb690ee,2f72ef10,1f55212b,ad863280,67ab378,1fe9c59a,bc54b06c,9420059c,6fcea9f5,f0bf563d,2f87dc8f), +S(67a35c0b,fb6a1655,23740a0f,23b6a8a6,854c22a4,113a665d,1c35a2ea,c83b72bd,dd5b811b,e4454aa,c7c9adea,b7368235,f3dc2bad,a6b7a2dc,99e86f97,f9d7409b), +S(6b667d3f,158c02f7,32ebedd6,552ef5d1,443df008,2e1b724c,dbaaf43b,efbd2480,c920f76c,c082ad16,d7564ff,9952fca8,3fd4e059,5e11a711,2337cadf,f5f51cb4), +S(c8cd3584,214589f5,62690e9f,71a63e17,64b0e3c8,33f26cda,8388be55,6e336296,c5d0bcd1,7b737bd1,66a2421f,8e1dfa80,64b3ede2,5ddb4ceb,cc8f9335,6ec468cc), +S(8b2f358e,b781cdb7,b8db96ec,7d42b75d,56c494ce,7561daf,b3d0ba8,360c281f,aac9391b,cbce3257,1d01e5c0,82eaf632,65628c28,77e72671,161fc2d7,21425e61), +S(55b0917d,f039f139,bda403ad,7fe1ebd8,912c0434,379ff3a0,da5996b8,bf2b2f7,f592415b,3ec3a143,c9b681b9,cf8c8139,2ed67439,ca67a162,e083cd76,27da169e), +S(c0eeaa0,81a38627,16dc09fb,f8e154bd,6e70e14f,a92168eb,93673780,a8fa76e9,9824a6b1,fd3df6fd,94ef8e7b,b1d9351e,cd3ee62a,e70a1eb9,91b56527,7c695e23), +S(fe75017c,665e766a,13b2b632,cc29e61d,9bd5755d,b9c4f065,e764d658,7204997f,157a23bf,72c25ace,ebee10d5,aca71726,6d6c4cfd,983530b0,3d47e6b4,9027d0fd), +S(bf4458c3,ba27b2c0,cde6911b,6cb61a6f,53642c6e,367f83d8,e294e3c5,2b18e13b,8d34a93e,e7f7ff98,3196cd08,c8344cd9,eaa83481,3f606e8d,9b2f6ef8,bf91ee64), +S(7254ec2a,c6ad1be8,2fd75bca,ebdce771,f4ebca92,eadc0bbf,3c5146db,a8d3760d,6302fe68,4243ed5a,887eb664,46f709c8,e60a6db9,ed062c33,1fc556e6,6f87cd0c), +S(4eae1e2e,b75b8cc5,73688f02,bfd5af22,ca928244,6dc8af5b,9dcf1118,f37ea23a,2a98f93a,613b9b1f,b3725d62,60510ce0,e718d07c,f913fda5,3b4f8b28,ddca064f), +S(b929111b,4b6b6caf,184238e0,82fd9a3e,8b9893c6,ff80a091,8b8e2b22,da6e0d2a,5a207daa,f75abd10,142948a2,cd2e806b,23322e1b,1f52b739,a9c7ab26,2f44e91), +S(6c57b3ba,18fabea3,25dd2711,52e5d857,a2853fdd,5f73db49,cc2e1c25,c98caa91,5a3fed55,397696c2,a0e98573,a30375a3,1b59b343,35c77918,3908ba58,4bb96a76), +S(607ff89f,3c3e3635,a6b83591,546594c2,a20de4b2,e59a01f2,696a9d25,caa0b1ab,47f4a3bc,ec375b6f,2510df4,7ca3d932,524e7c9b,656beb5c,65603c9b,1dbc8a3c), +S(a5f8ae36,a163ee23,d9c2744f,1f32de1,25744a64,f0e21009,445f08a3,9dd8aabf,274fc698,60f62f3,cadab3cd,23086876,31dcc845,43c98f65,b826ba0c,5b27352), +S(bdfc9b7b,ea97cfa7,4e97a822,fb6d8dd9,cdd2784,186f01b2,40db0851,95e1a07f,b02f7e83,56b72dda,81e38cf3,d5cf071b,e3c4c595,118c1cf4,61f01b1d,fb678090), +S(386bc7b,42591be5,41547b61,f0c96e13,6b168ef1,338f0f3c,ca2e59bf,e4f902c8,aaaccc7c,37655f05,1e0bb44e,396b2512,68bb806b,1e1ae4ee,598ab2c0,7b920f17), +S(14b9ba9a,c5eed3ee,9f4365dd,56e703a,2bc35d0d,af288bd8,1b9ceb03,82444a69,53d17e83,d76141e5,81c03eb,367076fe,a831a4c3,3a756cba,e564c851,e71c9a84), +S(e8b86b8e,f0424769,d0a6abd6,f0090030,7e851f7b,11a31012,b404e4e4,c062b1ee,f829b4e,bd2a0a55,253c7fce,73b27cce,9e31acd,fd8345f0,b973143c,25ef7900), +S(ed4cf2fa,b4108d10,c07630e8,333fdeec,af062396,eee23aee,e06365dd,ae880631,8eff37c6,5480bc59,6271ef5b,41743d9f,89a4685d,d497bdc0,8f6a11a3,56d07535), +S(6ccfba61,23d3296e,acc2f6ac,ed746ea3,6c7ce287,6e758fe9,b38603f2,3a1ed8fd,86ad0ff9,ee5d758a,2c2736ce,af4b2d50,a23c60d7,d952409a,9bb0c836,34dcf7c3), +S(4f3dad6f,4f718586,f2ce5239,b7ff5f05,ca384f7,a3171edc,6b11103,55a015b2,20858d8d,ef722f1,3a6e11d0,7d0a1db6,257496c5,e1f64d4,182592e5,f57334db), +S(ebe62fea,9af5d236,30dccf98,cb1eb472,38dc964e,5a145831,fd7b65d7,6b55833a,f828d7a,d18cab39,1af532ed,33cb2ae4,3b677836,b95bc3a5,2807d5a7,7df2eb86), +S(f4608ee8,a9ff5e52,15fd6257,43e58f5,af5ee536,9bf8e5fe,9bb8d371,e40e86bc,44dbb6aa,c7bb3a3b,fdea778a,7a6ce04c,dfe22a5a,c054951,2a52ac0a,499a5962), +S(63be7855,faa99716,cd77c389,5b2eb8d6,ae5d29eb,f64916cc,f7eaec1b,6f81ae30,b1463e0a,44d15252,21670fd8,4a1ed48,24b6effe,f6820787,ebc76cac,68db082d), +S(17306e73,c5487073,30f41a4e,e94370ef,36c07686,c55ce03d,ab6cb6fa,ef1ae2b5,b3f971de,6e09f1a8,7b083dd6,44c5edd2,a67449a4,520dfd5a,6742630a,8fb258f4), +S(81dc632,ba371e74,18cb0986,8a3e11fb,738f7857,9210bc06,cd0f9e73,4c91a064,cac8a551,b5ce80dc,2e5b400a,f10e209d,9b1864a8,ebf554ec,f36056e9,3b99b69f), +S(6ec14358,b2734ab7,3059643b,c60dab0e,d8d46c41,5ca1815b,cc215408,19b71e71,3f6c7c4b,24cd34d0,aa9cec16,cc17e321,76e2c0b3,24bef53e,9b6f3dc6,a4f4d617), +S(dc7cb981,dd03dcbf,66e63e85,158aabeb,db7e2aa2,c4a04db8,e88e8628,28000afc,d187b91b,be3dc2bc,44f29d22,e2a5611,6c9ddd2e,6a946077,deff44df,6109bc4f), +S(8a49a003,8dd13eaf,7223a2d5,50503fb0,ce0f5c2f,a7a03d5d,5ce03517,803899c4,47e6b637,1876be40,dc5b64d4,4bc5fb89,966c49c6,2d4f85b7,c7867ff3,1819f8de), +S(b252b5d3,a75c18d3,79ea1959,67559d02,8b8ab87f,c4c5bcd,842e5de,8e2c406c,eec6b95,c2d5af38,84ca69d4,2134d318,646774cc,4d05f78c,7978e8f0,80072b54), +S(6c30393f,d1f285d0,37f412af,38411133,c1bd1db0,6bef205f,12fa94a,4eb35412,b8c88541,acc9c862,c0186985,cf58419d,1c24905b,1d1abbf9,2b59a381,829fced3), +S(aa8b25e6,583d6898,6ff108a9,a4be30d,5a5149c4,45387abd,e9c1cd74,f3246ccd,1c51efb9,e6225d4f,b7b67bf,1b12de21,718fc945,d18a1679,f5ff6ff9,94d158d4), +S(28b46490,768800c0,4c94fd8d,8ef8c29d,fd66fe24,f379cfeb,a0a9b9e1,53acb33c,7e348f08,308e1ddc,6ffc48f,8e8a137e,785a0aff,fff18285,bc5b7bf3,54ca8253), +S(54b0ae43,66382f3e,83a01082,7e08e596,de37fa5,8c012e90,20a24347,ca1eb5dc,facb37df,f0bc59ba,72260606,d8e94f7e,3f71f600,78f6854f,2fdafffb,cac30332), +S(f8f03b0e,b981e371,a0994d64,6ed73e5e,a36d74e,7a349861,20e25d71,7f43c6b,642c63b8,96d9e995,32dd3403,40f91e0b,35f5d990,f6cbb768,253251e0,d7965737), +S(9c1be533,26c1a43c,f0fc5e13,83627414,89b4df8f,71224d24,6bc07c1b,f22c89d7,4d420abd,af53f191,f1e6622e,bd51e638,9e2cb2b6,a7c51885,f21937e7,3de7e73a), +S(c9b65328,864d0371,86b146d8,fc208126,dac6bea8,31778af6,e944f338,3c72553a,db91182a,b8a8ca07,3e2fae97,41cd81d8,d17c8776,9f2c0492,2b76ee93,c42af5a0), +S(7d945104,a4ebd202,dbd4be75,1cd14d8a,e07700ab,804de7f5,1cf6d254,bbb9489c,77231839,b8d9e627,ef6ed20c,e88146ad,7addbc91,f1522399,da31b84e,7b21a033), +S(2b307a7b,99ad1892,cda61d2a,10c1d972,b5855905,a64309d0,6397732b,c98ab549,8c38783d,51162a87,8e84554f,9b6d106e,e3064b89,3d368341,f96faefe,9a0ceafa), +S(2e7c5d29,c0393ab9,7b93a628,8d6b1da1,d212687,5d45c961,317665f9,9db55ed0,58b9c7f5,19ba5e3b,5d988b51,d50545a8,9a74bf20,1cbf0cb3,64936a06,7c8110e1), +S(accc9c09,4ddabe8f,81433d11,852f2583,85dc0463,9618ea1c,b06fe50,68358940,80ce4a4e,9ae09021,b8945aa9,1e4401f6,aadbdcce,421f6f32,ce7f1317,508cb799), +S(a67ecfd4,3735a152,4908375d,d21bdbf4,824be481,a8ff6201,8145c624,c5cf74db,e993c3f8,5aed69a0,f9b44ffb,80b5156c,33f809c5,e9efef1c,fbeb7b25,c6152911), +S(42f5d252,3d508a01,e7177947,29eee1a,fb7be04c,90539d9e,afe32638,b252e158,7194bfeb,f9ec8e1f,5039d582,ed7d28c1,99d5b07f,bde10b1e,e3b4bb64,148b5119), +S(15bc89ec,5d3b2889,d26e77c1,33eb832f,bded1d29,ce975905,d9355b2f,d99ea1ce,4e0d28ca,7aa69933,6f41e3bc,57a9639,81e2b92d,7b80794d,4787251b,f7fdb0d6), +S(7d68bf90,45c79869,5a8ef33e,f7fc4386,5ac90c37,8d3beebf,6ba3973f,e9d8e507,d14998be,f5bab5fe,fb94ebf6,9c0bf133,a6606b43,f621c861,ca1cbbb3,ae3fccaf), +S(82541ac5,9196f73c,99f9ee01,ef266c5e,908e91b8,b341e052,ae2576eb,17b90025,29eb3c8b,8ef826a5,6565c9ef,c2b2e47b,94e12736,131d1e0d,5b235d0c,169c2934), +S(242399a8,9c5a056e,8073a5ee,45475787,b31ff7e5,3d451f2a,d0437580,a479239a,19d5ce74,8c9a4a09,606e7c0b,6b486098,b743d018,c45e5e5d,8f39a966,fece6ae8), +S(cae84567,8cb2b2a8,de8040d4,3b32e0c6,d42dc902,3db4aa,273d24d7,17a85e7b,edca07ac,15d81467,81185e1c,4829951c,2569fa15,3b7e7ddd,22b58ad6,3b736094), +S(5c3711c7,e676ef0c,f889ce6f,57d9f92c,1cd91023,2b6fa410,75fe70a7,ce4b3db3,9b5e75c4,eef0358e,6732b7ad,56797ce7,82a21fb,d13aede0,d563638e,eaf62eab), +S(bade63a7,a4a443d,26d58900,bec36c28,940f4b32,fce20afc,2adf307c,3ef9d71,3c801bee,78daef8b,5cdcd5c6,bd0e63cd,712c2dc2,8e34cfc9,e01beec,b198d687), +S(cff82bbf,2e6412f8,18af5ae6,f9947aef,5d89eb32,cd8e9961,848f75f9,f9e4aaee,c0624130,346ae6ac,e5e76b6a,a2d836f,bb2f07e3,1467b8b1,76af0345,d8f5a137), +S(b3e4bcf9,f9e80edc,c4249cd4,58794fd3,921ac31f,a5f72c7b,e6f7dbfa,29f5c7d8,c045724b,8630771e,2772cdc2,53b2842e,1ec994eb,52296f3,6e2061b8,b32b9d3a), +S(24c22e2e,55f24320,65e91ef3,503bc571,c5290bab,ff95329e,17644e6b,8ef22386,2f91c5f5,6184c519,6f945739,4f101034,fb5fb146,ea61e009,39641a9e,d8178890), +S(29de67d7,edfddf52,6346fbdb,62e87e58,a0ffe4f4,7ca14a47,426238a5,3a3e2188,69dda846,e0620850,ae6d3fb7,1e6b9f00,814a0a59,ec7e94e5,e412a57d,ea4b02b0), +S(c8377575,d34b474c,de02b73e,5cce9eb0,c80c26c1,a925f090,d6b6804e,accfb653,306f4844,da7b237,38adcfc0,3ae9ac48,206cdc73,7c97eb11,c48c7951,52a9cfc4), +S(bc1c0c6b,b6a169c4,10ad87f4,d1f6b25,3313637,8d766bae,ee9401fd,b6895515,7d794eb0,81d9476d,c4d3cf0b,21b99537,9446a6ad,788f0f94,8acbba71,b20df5b0), +S(8b49586f,e4b4f33a,82ddfa9e,e83b7f94,177c1f39,30707f20,95a3d841,bebe44b1,42fe0fa6,14cc26a0,d2608c6a,31fdb1dd,993aa33f,6d32bdaa,1f9715a7,3e11340a), +S(fc52e593,28af4bb2,ae6abd18,8ce99b49,d8cb823b,7c6418fd,8a5f9757,44ebac16,f130072,79a1eeef,5483bb81,2ceb9090,35fd5df1,b757fbe2,679e2d1d,16d5a5c6), +S(43fcee45,79e58f65,d25edfd,f429d89a,f8e7364e,c0f2358b,83772ac4,27ccf626,907821bb,e43827ab,c210b2f8,c984d6c5,def4ee2,5761a9f7,90049477,874ef309), +S(2634e802,fe58e3a,62b9105e,5e37d8a6,f530831d,d4bba691,a6753df2,1482fba4,5d9b9de8,ab3f68ba,1e681048,c67274d,d1fe0cd,4e639454,a2fac6f9,5cdedca8), +S(56f19f08,a31f7d57,2bd94314,4a22245d,9ce74a11,30920573,9ca68569,76b35dd9,b453c349,678dc948,bdf804a8,4f54373f,c4891fd5,7058f1b,43296f59,b89d1fd2), +S(6f7c37a7,b3b96ea9,daae285,31763ca5,d481c1cf,42237ee7,a1ed6554,68de3aff,eafacefc,292a5d0f,b50cc875,ff7c8ff3,aa1923db,68461f1c,de04bb6f,729715a2), +S(59b44c32,ca7c1a74,ca69dbe0,c47f6199,79b997a0,df691d3a,4c7f3a76,9a543723,3ae06964,698b97de,fc3af051,9f13559e,813e7839,c893a0a9,bad75ea2,bc35e302), +S(e7acd0f0,d0560ce7,2d6cd805,d197fe6d,4948721e,b5e4c40c,c2014e78,9bb5c8cd,c95b5d74,5bb6058d,80ec04da,5135d92d,a447ea0e,9154b1d,93a5a014,ae2faaa8), +S(7ffef78a,e04da609,6754fec1,11fbe130,5fdc80d0,3e7b801c,28e23be0,40cb4e97,579c1fe7,54812978,46f2bf3a,57e1f850,ff4fdee8,8d3949d9,68e81d2b,792b39da), +S(5d068102,af4129c4,49c1e749,91ac0c15,dd2a7e29,fdca33f0,84f228bf,f19f5ec4,75f0179e,d77c3cdd,3cd1ec37,3e2d6d60,5425c215,ff009f26,66b8f7ba,77dc07ba), +S(cb90c398,7f6e05ef,ebee67e4,d9725200,eabd14a7,67c10cca,6fc546c6,ca67996d,c6a9a0cf,d18bdee9,8e054e4d,9df247dc,55ed473d,ed372138,cb21ebce,809d3a96), +S(5faaa0f9,63293ddd,83c2a841,6363cfe9,e102c0df,f4af7e81,c046540b,2fa3d653,66548b52,dd344ca0,2e0352d3,f14578a4,cdfd3a32,b410abee,683d316,61205e51), +S(35fc3454,7f04856f,3fd3ea4c,63c07a0d,bc0e6e2e,37216712,5da6347b,3c53b8ca,a4e3cb12,bc29dca7,800893c2,cddd4482,f3334d53,e215fd91,a01c0f4d,45162cb8), +S(ae1fbe74,e44c15b,263565ff,9f578ed2,39741d8,960e82bf,d8788a95,f744bfdd,d711400b,3b458a9a,75e416fd,c4d0efe4,5ba5666b,9280fb38,3d2bfdd5,83a89a15), +S(76f8768a,5ecf11e6,15671063,999ce164,73286582,c4238ac4,f8ef7e20,d1358f67,da94a126,d55ecf1f,8c899678,cbd7e53d,1171d7f0,6d72ffd3,e166374c,58b4f4d5), +S(f454c1f2,b7b447ab,dd2b0308,472a1e19,c1844e63,40225166,e5ddf571,e8f93d52,5ac5010a,1b03dfd5,baf4bb7a,943f0e16,4aa1df65,5166d021,c9db0ee6,abc3f425), +S(3366b897,99dc33d,a1f900ee,57c2c316,d6c2fc16,f71355ea,219731cc,280c0c7e,dd29b0db,9449e2c,7f80888a,783ef223,bc8cf8ed,be82f1ec,c45bbfa4,b054a77a), +S(2a73966c,9b1aa2ac,7b5b310a,bac40490,253f6cbe,29c5250a,dc57d979,f660741d,77359574,39ae6d7f,157723bd,ab2e1181,209f0f6c,fe5f4d0a,a9b0ebc5,cbed1294), +S(3885f7c6,d80f0060,1d60a213,923e2591,f055ff3c,39425d32,43302b6e,82a0cf2f,d024dd79,fb17c9f1,7db519d8,2dd4012f,f353fe5e,c81025cd,deebcb39,65ed069a), +S(ef33a6e0,f5da4ca,904aad24,5f2ada01,a77a93a9,11935aaa,68bd32b2,a6bf81a1,2ba2099c,3af09778,aeda97b,be4c4311,cd3e1636,f2244580,1a9c8ced,5ac81a52), +S(c8b25a4c,bfefb603,34300d02,585c729d,fccf541f,4942b040,c7b0c442,3f8603a3,480ac47a,674e42b3,a884dc55,be736c23,ca69e81,1af56106,efa66122,78214cf7), +S(6e0f7e4e,e4eacada,cf3862a9,8af74f97,99060f9d,73a9eab3,f3db3a77,20a945c7,4bf3222f,eccfffa5,5afee33e,9d39602e,e0ef3c67,870817a3,a9bb5b31,78469272), +S(32a987ef,6cd9c989,aa1d1fcd,5997169,2db6ba4,f4c8ca08,4b1607f1,697b202c,5c4eb708,50a58a74,5b91143d,ea849068,ab8b1b77,6fd2ec80,eef53d60,2cab45fb), +S(1299c334,60ee62bb,68847930,82ce6c49,bff80a9f,4fe33196,7b09a05,b22aa04,50ec11da,9d7a89c2,68bf0314,7b67803b,824b59c,9d496a5b,8c0d9955,31c8626e), +S(ce9f9a2,55aa6b62,a3184c2,8ea5d204,581fdb7b,1945d9db,2c245e6b,4d0b0d6c,c694fe1f,f93ae622,e5816c37,cf581f3a,4832442,d171b413,f86d4c25,ccbf0cf), +S(ad42db1,1ebf460e,f7954df5,3d7cd6e3,a7eea34,6ea8ca1,2ed4d5ce,83badabd,7c0538e8,a29f66e9,d2b3a235,9b00bc42,6809ceb5,11d476b2,38719673,a70e7b09), +S(fadae65c,500d39f0,377ced91,b0a9c469,3db78832,b31b14bd,78996dde,4b764bfd,a4b8e5b4,e398a8b9,90ddaae4,7247a975,2f2267f0,41a867e,e3b0774e,1a692ca3), +S(14e71e8b,76377b2,52b60ee3,f089d612,402ddf9d,92f2046a,cc7474db,1cf56f69,7121d880,5bea69c8,233dd120,f86b914e,cd080537,649b6cdf,74830f87,73aefc55), +S(b15e94d5,5edb91a1,9883f6c7,5bacc56f,2dd2c1e4,950e267f,c4415968,a75d7730,dbff7f2a,57d7072a,4a076dc8,a2d26233,1eff662a,ce10d24d,e3c8ab57,8251765d), +S(e343c0bd,240de1fa,f1ef780b,4922ddc5,453649c5,7a08e9cf,99f162c0,ffc12e7d,b9b65d5,3861e229,777bbb4e,85ea417f,32354b9b,8796bb47,2f6eb67a,2e3d22b6), +S(c3ce72df,4730b13b,95398abd,fa02c834,c5d20e37,9ebce9bc,b77a777c,f9fc3299,ec87a4e7,71c04584,f6dbacd,10fec1f2,c8bbbf25,9954d596,2309f0de,48ed9573), +S(fb70a931,895d44c0,e31a9dd6,bc2a1cb5,250212e0,5ed1f55f,5c668e3a,8390677,d86125a8,cbc9437c,561ec1cd,95b5190,328588be,6bf7a25a,94271547,1fee6a69), +S(b150b153,be5afb36,f6bf7b27,ec687612,265e3177,2534bc4e,8ac92607,9a3ef16d,571ee1f1,7c499be9,89b86781,229abfbb,db83272b,c7496f17,52719c2d,b0812c40), +S(2e71970b,913e3006,84eccff9,aa4c914a,22c6cff7,3bdeddd5,781f68f6,177adc4d,829fcbf6,1ff72af4,6bfe69ea,d928283d,45db7cae,b1b59252,7dc6496e,22a6ffd0), +S(d361c4dc,3df5e874,cb459096,d319957,398e2a5f,337208b8,6053315b,263ed230,5225f55d,49f2d8b,ffdc241a,b54b5a43,b3856b7a,60cde97c,5e860561,f2da2861), +S(3f30591c,d464af5e,ca79c060,7e6a8ca9,c6a2c2f2,86177290,fda65a82,522566ba,fc41d72b,f20b86e4,6be3c20b,890fe8a3,ceba4805,bfc61c7c,66532693,7de90e22), +S(2f6a706d,f5efe7b2,bf409606,5da98b97,86ceef57,36677935,c08e0b8c,b125db55,99bf95d1,b348b522,a1cbfc73,f2a4e692,1836256a,97bcee77,51ff5091,6fcaf620), +S(c8c72176,255d0e32,ce4d7caf,aa9b7467,ff49ac94,34beb017,9883b22a,4254620d,580ea490,a94a8310,cca59b41,43fd4740,40ed92bf,7eb25bef,a87cf930,a974c943), +S(a5d65fc4,9bf06fa8,6018067b,7ade5ee1,a541bc2c,bee0edc5,6a144f0,6be32808,ed70ce9e,16053764,35c0875,5cbfa6b0,d1fe923a,fc9035c2,1d26fda9,58c36ccd), +S(4a6c4b07,7c6c9dec,d7d6f98d,59eface4,ba2fc654,df7d14a6,57f108e5,d3f91d29,2d2a4b3f,1a9aa787,cb747f7d,961c4cc3,cbd62de2,ceada2e1,a71648ae,feadcea6), +S(97d610e2,8b3771a3,204235eb,faccbe5,29d1a6fd,5003d6d5,4b37cfc2,80550354,a441235b,593f0649,ba50d405,fa597b25,60c2be24,2ff43ff8,3b635327,94e67c51), +S(b9f1688f,4161e507,d8f540f9,4294a967,739231bc,a89c7d8a,c54ee365,1ab65111,363ad626,e5ff0d,7f43aadf,5228fbe9,b60efd2a,336518ae,53a0e36c,206d5d0a), +S(1b748bf2,690e8cd8,e06c5200,5a654bd6,38bc62d6,63ce1194,c4bea3e2,82f2c351,db0ce849,96bdfcea,497bc8ef,dcbd6e89,d0305b1c,4b6dac31,4e480b45,a5a9cbeb), +S(ec9d3d1b,3ac0e4e8,c01c8cbc,5d498201,1f52cb5f,dc7dd0a2,6f447457,aa9da7ab,2934e845,ee13267,b3dfbd3e,5d77cc77,214779ba,51bf7f67,ac3cb131,1000369c), +S(1b28bc0b,ac8ce96a,a3d49611,1f66c77e,b030a49b,e9ee788,d8e395ed,495c037a,ad5e12d2,bdba39cf,5efafe12,f7588e5d,c5f2bc82,c7a0ea88,217307a5,c996378f), +S(6e2929b8,1060c4ce,c6b3f071,40c8b23c,48a87efb,9765f292,13993cb2,9c046638,d68c4ec8,ffac30e0,f2642595,aee701a6,5c254247,a1397726,b0c40a77,1060a8fb), +S(122307d9,313a11c0,e411e78c,d66bd2c4,5aecfad2,3221b558,d124674d,1c66489b,f5713161,cb284025,efa004e3,a70f1374,b1ec2450,78f2252d,6c7da11a,ddb5ae11), +S(81df90ca,92efd148,9383a7d7,c69d4c4b,bcf5b781,e59834df,9ca30da7,cbfa1ed,fbe1932e,421a7a67,30e4a7c9,371ee8cc,a985fd2b,dc1cd465,769ef494,b0c8d6ad), +S(fda38e5b,f685c939,6a2a71da,b66d02b1,a1da8953,c659c880,bd201879,d275a01f,2c729bbe,39467247,601c9b48,80dc7ba6,193f8270,a742ec1,5076da82,65db9bb), +S(45aab7c3,69af7188,9986b609,e16493a7,38a255a5,d4c27a3d,96888275,54bfdce0,4a512b2f,77c0aa0,e5aa021e,2bb63904,aa7c74aa,daf424d5,da8676c,e043fcf0), +S(14b463dd,57d236da,fa835f57,6c4cf514,73180d39,efec4d18,9a9cd1e5,91df4f57,ac3bee1e,d77fb0c4,3cc852e0,90fdebb3,1bd87006,7129210c,9334beeb,896e66b5), +S(5a8fd8db,833621c,e8e21f81,e2f30db8,2a98e6e0,8eddb80d,6a2e63a3,fd7da2bb,6f6c8e76,d846f5bc,b53a88b1,349b95ed,34239991,1e552740,1e58cbb3,bf42c8e9), +S(62b727f8,6bf49290,2600e83b,5a24974e,c35444d9,92c2f083,7bc4dc53,d3ed119,d7daa7a7,b8a0d462,598be5b1,6d36aad0,c07aafe5,600e3955,81c352aa,d6135b21), +S(1cfc0220,cb0f64b7,51fc05a7,897b3840,fb2a1c33,777fedf4,7ebb4c9b,e6059ee,d3a90002,d2f8c20d,1174fcf7,8591ce07,5e2b34f8,83d634f4,7b27d5c4,3680bbfe), +S(89efac24,9b798548,2c3ada7e,c7792632,fe872f4a,b6001e7d,48605b12,cf8cecd,a5d062a0,1e40b4eb,de2e10e6,684d9b6d,2b860f65,9cb6c51,676ee74b,40e5f612), +S(cbddc8ab,e37d0494,cecb4878,cb0bad9d,da00c1e9,c0876437,3405ec56,2318afdf,53ec167f,d0f1123c,3ebb9cac,476c86d5,94762b5c,7a365153,776695a7,169f06a3), +S(d020dfcb,c5e78a1a,36e1f8e6,3530d03a,5b53e1d5,41d05a46,d4e24318,706515d,cc811700,740dfdab,752f818a,cee554e4,d7e142bc,eb5f6e77,9399e160,c7646048), +S(2430846e,6e768e57,d4776cda,448ab651,c876cb6c,aa8fce63,34cfa4b0,826a0e25,9bfdb42c,e711af1f,a0cfeaf5,8264cb52,4d4d9eb7,a9fc1328,4351e209,8818c559), +S(7d3eeede,5d8e3320,80d0dcf6,3a8c6929,4951e765,d881e0af,febaef73,bd9548af,a4b9e695,85b2921f,fd651eee,e320eeff,52df838a,17efeb60,16d5cee6,d4475ca9), +S(4bdedbab,af06488c,28fa5a7d,ebe15b63,759986bc,535b4ccf,66f28e8a,1126803a,e4ad8238,94741e42,c28b330d,16b16d40,d538d081,41f0a5c,92890934,e3c09dc2), +S(65569131,959b4da6,d2b52217,9569e44e,cd7e7ca5,515ffd71,fb4b3444,246f925a,87049181,3adc7c36,9bcb7696,f90485f3,66beaf52,9cd09e04,36d51cb1,6e84514c), +S(7df015c0,7404bd5,518ef8c0,1aa4c5e6,8773800f,fad367c5,5b10254,45e720b,6e936006,2fad0fcd,a52ae9f2,bb7e3f5,ad0ed702,50e474f8,c4e6b62b,93885bf8), +S(90eda060,55bec90f,ae0545c2,30fe67de,99da2fec,f158aff2,ff4c8a1d,419eef9a,c5a0e7fb,f8f5f20d,25f09076,6a8741e0,5e7c49c9,c6408dc1,fc02e84d,79ee165c), +S(b36d9a3c,1a6c46e2,fef6dea2,26b1bc6f,e957849d,d11170d6,25746bed,bd3d2846,3ad18694,f8c0e199,77d0a56c,161a71f2,72d9090d,96a376d4,7d6ee99b,5f3ae29f), +S(7fa2d360,27f7a698,e5e4dece,16f7f78,5878ccbc,dec5f03a,8041805a,609f01ba,2bc2c266,d8d013cc,c215e3cb,8afc5b8f,254b0656,98281044,8f946d65,8870703a), +S(fd314b51,71ddfb60,16f3dc94,859aff4,5b01e7a5,5ebb3c0c,a2ef8262,4c41fd08,28539bd3,657ce721,4f6d88b8,f8f85565,996ec40f,fdce88a6,5820a8f8,4e6271f1), +S(6e37f52b,ab64fbc4,a22cc014,b81151c2,623069a6,6c617fec,f8d32d25,38e23f9b,fe6910bb,2e2e366f,28ef13db,183bfea,924603f9,58847477,ebf816e4,33cbdd34), +S(31ee76c4,de143395,a1d99eb,98e8a579,d88b3450,69ff0b82,8335ad2d,72dda523,155d6f31,9548c9bd,62cc219b,db6f95cd,23295ab0,253e42b2,cbc34fd1,775dc0dd), +S(947c2b1d,604787c3,e30cf04,31fa2b4a,7d823c84,584feb3,5f68545b,639df62d,bc50bcbc,dc6e530c,45892e31,d71f719a,1d515060,ecb123d2,a37eb89d,45fa682a), +S(8a8349c8,46a41e93,fa097893,c4fcbd1c,7c25e3a0,afb17929,72a7a872,570e5abb,fdbfe661,fc2940e4,b8c0fee5,7245915c,7f8c9ba2,1f548bf7,d5c654c,785b94a3), +S(7733640a,13671b1e,eccf3527,3cb9ee8f,d79cd08,ea57eacc,97b39bcd,6ad669b1,7ce5c5d5,abb13079,486bc91a,ececa9d8,d0d1f84f,a5d74e57,e4727db8,833f8c05), +S(a9ec8a22,7c262bfd,f5b00b9f,1acc80fd,4f5d46f3,d24d59d6,7c2cd83,3be94a38,f0d9bb94,ff97aaf8,54b3640e,7926a99,8a731a5f,4800c573,d1279d14,5e4d422c), +S(9837810c,86ca85a5,ffcebe9b,714d4b1e,f5c0ab5b,2650e163,d62fc668,204aa566,bc477f5e,ff56a588,bc68f7dc,42644fea,532d7a25,3f84d17a,9ef7a91d,5f3113bd), +S(9020fe03,9de18af6,61b70206,5b615ee3,de3ea6eb,a8c30d9e,24d4bf13,56db96dd,3a0ac3b5,d1832113,8421bc8a,f978771c,53b98110,6c49afe5,711b4b54,f9fb8567), +S(d769695f,f6f22d11,99224b69,f66aacef,8c6cc911,e43fddf9,481b46d9,97a2ecf1,e8f2a6b5,f05be025,a84fe0a7,23ec54dd,b21c32b4,b4d5cc89,5bdd8e66,d8ecf934), +S(a7668280,48ab1e2b,e843b0db,7a9462ee,3ff0a5d6,f7c12ce9,496b302d,99a23042,42a1296,92217f3f,d7de8cb6,df48b8af,11d8d089,5c93703d,a242c7be,d8033dc3), +S(ba26a7ef,1e0b979e,3541227f,2dec3d6a,7ea6f8b,9e9b46f9,93c02b3e,fe1d9611,b0d283fb,1adccd83,be7122b8,b59e6d4b,589204b3,e96adb4c,a6e19ec0,ef1c142), +S(175ba624,70d63d4f,6a3a030d,a1515677,8e589e8d,80ba62d2,1719a906,68293971,211232fe,97508523,4d0dae11,14831009,229fb25e,51f97182,476558b8,adc218dd), +S(1fdb147b,860c3254,b4ae5513,14839573,da2d0272,be69628f,1b395a03,bc8afca1,b42d0b99,325acf05,a3564d77,55cf9c9b,3208e5ec,24e5ef12,b6180fab,8b3f4a4a), +S(986d3acf,c5cc74db,c844c28e,d91276ee,729a5588,e1f504f,1e6f96e4,a7a21607,7229d56,4a9dd4b4,79f8d8e,17951887,870a4303,53707369,aa8e8d6,deeefce7), +S(39ad0832,b18dbfe,1fde87e7,c5d3b948,75fd76,9941c2bc,d605f3d1,beb94e29,f85bea41,f0c36603,8ea8038f,874d612c,43b928b6,4116550,8878515d,fd74b6c3), +S(3a318109,745a25bb,c6e45068,ed37553f,b2591404,3a7dbfc3,9e67d1e0,24bb2f12,2cd3e0db,d2545332,e4bb3e99,8c338c8b,66fc5061,81c6595c,37804541,8c507a16), +S(617d3fd8,87b99438,6eec49af,4358e73a,bdf52dce,f26ac8a1,52be64f7,e0e8b2ae,a45b906a,45c2207,e4db008,e4fa961e,6c483c24,3c0d7fd6,b11af11,e5f8b444), +S(d1171cb7,e5a3daf4,7b7818a3,2fceb153,58c87d4b,84488cc8,1e930bc8,adc467ea,bc725547,a2d40dd,8d8ed471,1869d711,38118b5f,bd00f0e8,3e1967b4,880da3c), +S(61f610ef,de8aedf,f012a109,5e5ad596,9d06ed54,214e6f33,c69643ac,50df0ca3,405ed3cc,5ae1b566,fcd069f2,e8b67520,74700b94,689eaa7a,3fdacdf6,a798e091), +S(8caab88e,e5fa3cf3,59a8ead3,2d80a4b7,b57453fb,e90a75b5,ea9e4f0e,5ffcb7ca,8b7608f2,c7480114,d8b04bc3,7f089f8f,2075fd9b,5b4a49eb,bd0ab1c1,8ce31a9b), +S(b73ee255,bef7518c,12be7d6d,36314c8,3fcf3c7c,5b0bf2f5,3a1add92,82bf729a,716c6c00,5a82e1f8,1f493753,f4e2527b,99bfd9b9,988b5e94,f7652ffc,6c32b7f9), +S(ca72f63b,ff6ed94e,c1fc4f3,427e90bf,a16ee627,b9112358,1620c156,6f95c1,a554deaf,c8bb3a56,d809c044,49efd477,7d083da5,690ba56d,2a4e2679,71d6b0e3), +S(f861644d,d5693cb4,b4a8256,8a5297a5,595a64b9,5f9744aa,683dd91d,8d58b301,66223ae0,99284fc6,ff5bcbdf,cb0bae0e,cd954610,d4c152b8,b979b08a,c4d4adb4), +S(ffca4bc9,b9a2e17d,250d4357,14c882bb,7e837054,4bee35f8,818e696b,7a7c2c17,4c57c13a,e3d97da4,8644c47e,2cdc4d15,5f6add44,5544a853,f8e46bef,271399de), +S(c36a0163,5935ea3b,f590d4b4,656cbe2c,2e62d8db,ddec2eb9,ab867de,8d9dba5d,d9ed3116,dfe337c1,44025ab8,e607256b,f870c4bf,a885bbc7,3ece4b29,ea6122ac), +S(bfa4fbd2,c9fe8b16,9520ffec,277fdc19,cd53dced,1866d5a9,404cf89f,6141e4da,f76e0423,4fae8abd,892368eb,e48945aa,a3684136,aa5b7a0a,d85d0d07,79af3ce7), +S(fa7be3d7,db544548,45d4bd1d,43c7960,89aa1eb2,4c0f81c0,16645d77,83ed508f,b82cdfcc,4df4b465,4c95530f,d621435e,8679aee0,9918a06,131775be,8cf4e324), +S(818a90d7,5939e32a,af92c601,af9eb717,88443e57,b7759bd,9e7e2be6,238a699a,c951ef89,8127b426,1c7d6224,377fe63a,2706636c,525ee10e,30e11a85,c160b50a), +S(ede3411,d3acaa0b,650aee14,29f910d3,5ffd5684,eaba0280,8971f2f2,330e2880,8a2d5c96,ae4ce2e9,739ff957,c595591a,63a58132,10b86a62,bc4cd164,54b8bc7a)}, +{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), +S(b0aafd22,9e0fb326,b5ce8cef,578803c1,da2be933,1f47b343,370c2e22,18bde7d6,570b1e28,a519d9a0,2f9d06b0,6637bd8b,6c7f7e51,5a7c541f,7263e05a,87270081), +S(6d5417c3,2d66d6e6,a2d2c599,366ab000,99cad0b7,55f8f3e5,15afc018,98b9efff,786eee97,bf1a1c9,a57de5f4,94be0a29,663b08ef,5162e971,50dc240e,59d9d489), +S(9c64eb60,9a9469ad,fec8d298,50a08f7d,d4e99710,37c9e7c3,7eab2eab,cbce5b4,60569102,1deb5b10,705231c3,e29dd6e3,b613e6c8,eb313cc,68fd581c,eab98ac3), +S(d219f302,cc6de5c9,8360c088,881465e,22fc572b,8217734c,742231b4,ee487bee,89710994,239f6120,df848623,489173e6,f337c99a,71fbc319,75e768ac,43cdf91d), +S(792810f6,6b9cf54c,ebd8ff1d,159f966a,7da61fb0,34651402,e878e5aa,2b044259,9d2d44c4,b52b24b0,7c3dd127,43fb81f1,e96991f4,53c06839,cd86a2c8,faadfc68), +S(c9913dd5,bef25d08,327d7441,b0793f4e,e3e89b5f,15cdfb3,483f8663,3644d75,e6f5b61c,6beb820c,64beb375,4d80f3f2,6e7aeba1,f4a490d2,e6dda2c,b3131e24), +S(a836402d,582230fc,bc8c944f,18d5391c,3c934e1e,ae1a5f6,2cd6ce3f,b454e6d4,dd8417ac,a9ea2e51,13043d8d,10c8be13,e48a17da,e1d78f84,da4ca58f,d07221c7), +S(46b82270,4a808581,f9dd6d4a,ac7cf765,90dc3308,dd54a6f6,3d4c49d7,f5652310,1e8ffdc8,a786fb63,4a56eecb,ed370af5,9d6300b2,cd05c1b,5bf28d4d,69e64c9f), +S(eb25a657,ff10f29d,4a0b336d,feb63364,774f28ff,8c6eea04,25df2e41,1cc8c49b,6547a11c,9cceffee,5d43a330,69034c93,94777b74,63c1f774,167423c3,2b53bba9), +S(d1548f7d,b928ce6,86e8e71,c0080731,3a1cea63,838c013d,5d52fda0,17af443,b15384ba,3d62a403,920b6936,54c30a87,7cd359a8,2b63f037,64ac24d7,2a8fa367), +S(ddb36d9f,c6c6c026,6c79f2c1,50eebf46,36737eca,d0091321,c1b293b,52837cd7,8e0cf327,fb2f9548,4905200d,1111da22,aec01189,c8db56b4,6680c03f,4d938f29), +S(46737d55,d4b1c924,c58e100c,161206f5,84e01948,22853e82,e641825f,4eb1023f,4374a770,809a9424,12e75c89,75b98345,48e6579c,8b4b1314,29cec398,6b2eb00b), +S(35772697,7312b547,60f2db9f,443d8165,1cb1fc26,dd977dae,3c659685,7330d3f6,813075b9,d73fd95b,78a9e1d8,a9f24595,98b127cb,90c942a0,8b451e71,e40ba38a), +S(17bca82e,46ab960c,193dab14,7eacf706,4326205e,7fe4dd6d,464d359f,6a0f4229,b882798a,dc357f06,4a98dc47,2eb3708e,26cf45ef,48f28c9d,11456658,1e49c7fd), +S(e22d5891,b992aba4,ef31503d,bb64d447,1cbb4013,86f69d10,37770b8,7c04f855,af5fc7cc,3e92b04b,3b61297e,d7c66dd4,47b81728,1f455c43,bbfb69dc,91396744), +S(3960875a,16521b2c,89c87efa,c0ef7a5c,7a1332b5,a84c34f4,4496c57c,d5c9af0f,859ec9e1,f08de5c6,2fad60b7,18533a9,d18cdc9d,91174ef2,c3eb0653,f6c3e5b6), +S(96e92234,e193254f,5629fd37,aef039e1,1457988,7b18ca19,a578bbe,3a23826f,afc02da1,3693bd69,738f991d,9d2e9b96,afb01e67,b05857d2,3054a7a8,85d55f44), +S(f032903e,40e7c8fe,fbf79c7e,a4eec837,6193c3eb,cc919ef4,ec867909,42c8188c,1406b7a3,f9a284aa,c0d48b95,47d0f934,2b6d3c43,4c6b78f5,4b1d9bf2,ff7a14a1), +S(59f8f5e7,1bbd9631,ec5e86ee,e78dc60e,71c74037,db8e32f,4932ea11,9a153973,7b72a4ae,87d78ccd,3758f961,12cd4287,d18e4cee,7abe996,d51f3276,aa28a3c0), +S(8f4c4baf,36df38ed,da5cab7a,90b5d3cd,fb7a6b85,bb000440,35d88928,27b811f4,fab6a3ae,f7d0d7e8,a45367d0,b1c9c4bc,9b6ecd7a,f6739401,8659560c,8d1e6d8f), +S(f19b8fe6,a84b2993,a1af87e4,313208e0,ba301270,3aec1a52,8ea60bb9,eb97333f,d8610a62,ee6014e8,b0eec123,c6b68ae4,62b0be9f,c79788ff,631f7a38,f134a74d), +S(a382dad7,66c4cbe3,336f2a2b,a11044c,31f5de9,6a1fa90d,479baed9,8ea9eac2,9f7b4cb8,c17383dc,ae9e8e71,81cc9f77,6823626a,f8da9b87,e5773edc,9fbb8a67), +S(337af005,48b956ee,58867d93,d230b0f7,313229de,4adcab17,55a24f02,c3c86210,41b3267a,48e288f6,42ed4fa,357a9d84,f77b1e5c,67a6b20,8e8596aa,40ff3cc6), +S(48e35721,f03fcee6,e50f875c,57fda488,75c6b2e,1e0f71b7,da97866a,de121d49,65070589,1a1e0a5e,d2df20c1,bcaf00f3,11b08c8c,a161e1c,7db290f0,a24c1a3b), +S(2db6b295,1a20b609,819d9e52,7d7bbfa8,d47a11a1,33a54de1,49e2994a,ed25d800,d16c6aa7,313723b8,e9c49f8d,66b0e9b2,6ce3ae04,5f1da4f1,355c02c2,4c1685fc), +S(2024d4ea,eb5c75a5,d26263e7,7803fcc,77fbe3bf,ab6106d6,ba134f6a,18e2794d,57bd2c8a,5c3b8289,d4d39930,cf2092a3,2e9b87b8,f8155eeb,65ae9b88,60b92159), +S(3a7aba1b,95085b3,89b07280,219011db,10fad2eb,c003f17f,2576f166,4c0f733f,2263ef94,65065e4b,36ecd1d6,e77fc8ee,2054103a,28434207,e02669eb,df00e444), +S(d476e308,a3456bfb,3ea08fdc,357addb0,3b5f3102,248e63aa,20b8af78,e5e27566,827fb49f,ac326d69,364a3ed5,f87e3e22,297d752a,8c77d399,7c6300d4,3358c19f), +S(b98a3bcb,5ef6e7d9,c7bb8fac,6d5de4d8,c9770950,994dddfd,c0e5567c,bcbfc6aa,c2e6c22e,ec6e855b,890bfd97,b916ae1b,d7f38a9d,51f1ddd7,fb11c44a,5ec058ce), +S(95af1e4d,e478a281,46edbe66,972c1672,815a12f4,eb975fe0,ecf7f988,d03bdf8a,9b5a9c50,c9616d82,98f43a56,62ed85ac,bae447fe,60985627,b6df1ba3,7600fbdb), +S(eaa4b025,2304fdde,1708446,df75b2b3,2ba9754b,ad68af41,515f5228,91a2ca3e,7d04324f,2a522df4,c8686ccf,52086869,8e892ec6,aec91b83,b6e460d3,b0e39d23), +S(113a2818,f9099722,36d3eaaa,14d52f54,27592ab,b924dc45,d6ccf5b4,a02094ef,8fe91af0,62011fa8,cd0f6ede,c5467c8f,d8bc8043,f9760d9d,14c31fe1,1fea3f1), +S(bf5b27b,81d5bc7,ec597a53,accae88b,bed993a9,fcb78a96,d0fdb750,66f90baa,7d7f5fc8,7c6766d9,78a359cc,5a486844,e62003fc,7756ad34,3b5966ae,cd9d7bde), +S(42d53197,4663cd32,c80d71d8,15d3655f,f4e8911e,971a53f,9ba1758e,79fcae1d,87daf2ec,3cbccd53,84bcc89b,9668954,a73283fb,5d5608a8,5746ff2,de26a528), +S(946a933,98ac78bd,a3f92424,f6bb6383,ef7ce19b,2912457d,b26e7654,f25012ff,ca7d7457,b0a52c33,4656671e,c6e68e70,b283df8f,7a033a21,7f013cb8,8259df8c), +S(1c53769,28cabbe6,3b6e52e9,a7577c54,53cf4071,e1050257,6e7f4609,763d1285,95340099,49a53bd6,44045cfe,6c17053b,7cef08e2,6cbc1975,c2fb203f,7810a4b0), +S(c31bab3a,c9cddb5e,91a69aa6,95545d25,5550a6cb,ed8d55d8,faf94523,4edfc242,2786d686,771c3e6f,a04ecb04,cab881fb,bebe70af,1c83f7fa,1fa2922b,2dc62e0), +S(81df0d06,1f3519d3,3e8f7743,8b917498,6ddcb6d8,cdeb5bca,2ba03fc,6d1b2bf5,183ade12,f68baa5a,c702b5d,2ada2794,bd038524,63796f7e,c885b5fa,96dd92b), +S(3825dea5,f42fc36e,37367606,1d8c4589,48aa11a5,12449590,22cf258,acc068d8,b6286350,2fa61c64,9ed1f3f,d64cdf9c,bb882d2e,82723e11,73628333,4c2354e9), +S(9aed85ef,5bd25a21,46007433,b1131528,6510ab0d,7918224a,dcb81585,ebece06,73e1712f,d6b3d56c,53bda6fd,acdee776,aa87f994,71c8cf28,17c05fc6,e5512bf5), +S(3b4c21f6,c0a815f5,80a75488,5b02087c,eee77de2,704b1661,d2c42329,169ae892,997bc30b,1e5ec3eb,df3076bd,d7ff8906,322c229f,fff17b5f,51316dd0,4778f062), +S(bbebedba,d7fe330c,1e50de77,62dafe8b,70cc8cf5,11c44dcb,1cdd55ba,82ed870e,27f2dd33,573ea340,355f9a9c,6cffe63e,44108290,f27fde3e,7c934d52,febe1af0), +S(babf0cd8,58f49844,5902a704,da20c759,881df7a7,27842f98,f3ace994,1937a7e,8b05b19a,62a9b997,4b0a9668,d598c929,c4ec6493,6015fdde,c134720e,fcb32081), +S(a420c65b,33426f3,674a5859,cc16d583,96b3c325,22fd2dbd,3ac9e179,1e5bc48d,695d3557,787ffb5d,8e69293a,afa250f4,6a0bbdbf,7fae0540,94f43885,d92d2544), +S(a31dd94f,9fd72006,abb783f4,c9c8801e,400c4d3c,f4f81906,d853fccf,e3c1cf77,8b49b9b2,8c513ddc,6f31577f,5a576ca9,bcfad648,fe0556fb,30aa3dc8,cf4c9ee4), +S(d4ea9865,929456a9,20c3a461,c3931efc,e73479f2,e63ae5ea,6e1fc227,1bbe518,f214c3f3,844daf1e,8aafcab0,89e1ddaf,6621ab0,975346a1,b04642b0,9a5be061), +S(995c4191,bb5b5831,e32ff6e,6be060d1,339bc41,50af35f8,e69b03c1,3ff55505,a4c0262b,d585aa19,26009953,34f83f21,951dc3c1,a5b9cc12,c7250fd0,c8619259), +S(77ea55e7,8d08e3b2,233db269,37d1259c,ce4acae,5989d056,d4bb4bbf,a7ea1cfa,637a160b,ce9307b5,a21985f6,6bd9c4c1,8f0a0679,3dc6c5d6,d491a2d,ea034f50), +S(f42d8da4,9862d140,30c9e4a0,5349a650,166d7904,97ff4a6e,403908b9,d95293ef,c1df830a,2e091a6c,e65f4443,f7c5d51,86838e07,dd90b0ee,f90b0134,b181b30e), +S(10e6c84a,53be364e,92542b00,2e5303ab,d93507e0,5e3699bf,aa865838,8df504f5,4f191ec3,974d9a23,28443d0b,a6ad8ad3,4a04e06c,608d15cf,d3b50d54,70d2fdb9), +S(2f27eea3,7a95ed63,f1a1c228,4ce37d72,a8e116cd,b5555f10,52307156,818b7162,ffdbcfd6,4b71c526,5c19b6dd,4fe9f0fa,e993bd10,a727384a,84807308,7588fd8a), +S(4ca6d0ee,294e7961,b9716d8,3d9065fd,a362dd0b,1ee95784,3e33c27b,464cbef9,6e37c568,801d5be3,7bc240f5,908229ba,bf7f44d3,26591bdf,58ddb69b,742b417f), +S(17e3a714,cdfa9919,b3a2ab6b,faca1a98,819258de,53877067,84bcbaf0,8e38e807,4422fc06,1df9484,7163efe9,f6a75626,f1cb4db1,dc563dc6,6250850,99a2d1cf), +S(86db66f7,2e0897f7,5a78295,45ed56f7,f94dabd6,c3ca13fd,4b715e78,24778889,116731bf,d85bc78b,277b09f0,5e341374,7ebf0977,587ea430,7e4fb0e4,b3c1d864), +S(5a67a2dd,e738eade,230815c1,cc2e259d,9c0e750b,1d42ee3,c4636368,d2add861,9c5b305c,d9dc561a,ef396711,faa7b196,b149f7fd,48c7f608,13d96ab6,1c23813), +S(bc5e682a,cb10eafc,319401a1,deaa5a8f,97d8b1d0,d65b847f,fa396df6,5f2d3cd9,bff7f649,3404076b,1c978bc,22b56cf,de56a233,414bf112,39ef0c2b,ba8c1c4f), +S(55e25010,b08cc417,3062a4a8,20b00001,fe53546d,bbcd0c86,ca21c3cb,22291201,6ba72697,9becfa8d,53fcb128,f3193f8f,74a99a7d,82aab685,cfa1fbac,8f1d71cd), +S(4b53215d,7c5d43f2,ce8e109d,c98d2f5d,af1ba4f2,7a713d04,22253cbf,c9dd1f4,2e96d,bc79001b,64a12093,67c36c77,dc8cc188,b9f632d1,56bd53a0,462bba31), +S(8d71406c,8eba2f08,efe9a88b,72faee9a,e149c857,d625b710,c443219f,c2e24997,68aad2e1,dad539d9,dcfd641f,be7c1ea9,d4239e2,e881e6af,57260011,bcd0d61d), +S(443ff7d1,5f92816a,7e64e005,f0fed100,efad65eb,cfdd7e81,a6d4df72,a2a91932,3be7e0e8,bfbeeea0,e15f1a4d,cd9b1f7d,85d519a8,1215c2e5,319db187,5d3c5c31), +S(a3081493,6d7359a0,bd8b0adb,78b79ec8,388f783a,f02b2759,318b0178,870ef633,5d89f521,e1029655,432a688,aceb1beb,ba824618,f9eae95e,ee0f56da,21364207), +S(33eb575a,aa3d6ecf,eba5869d,b7eb1340,bde18656,3ff4c32e,bc32793b,4bf50129,296dc28b,b33aa01,684894d4,d2766575,d420b02d,6cb23152,79b370bb,8836181f), +S(4c09fb9d,a61435e7,9e2f9faa,37cad82e,ca906e27,f5d17d,da991e54,e7650e12,1c3e8af,ff50589e,ee448778,8157fa7b,570a9063,d76e6eee,df6b8d98,140c3322), +S(8c0f258c,9162cdcf,9d60168f,bd98b995,8fe2c59b,fe334b76,2b05d397,8ca4cb29,8f04e391,d6abd5b3,1c3de519,2266acfc,c3010617,24a204f3,f209aa49,96ecfc54), +S(e7e0ec2c,d18151bb,7d46c17d,b34b36d9,c38c0e78,4d6c4a53,5661ff13,7de3ea5e,b569bbb6,35f01a5e,c7e3011a,95fcd613,357328b0,f589c77c,a49550cd,63ed698a), +S(33466e36,f172c0c9,41af8635,80f7393a,21111ca9,9962be43,c96aa29c,6418d949,e434328b,8b94157d,72f0329e,7d8497c2,a189a23b,8b663e5c,c6a6431,3d9cb1d2), +S(74546f84,2d5f2f0d,56c6de7c,e25dad70,47664eff,8b53139c,2101b450,ffb7e83e,72ade537,f344465b,349412b8,c5a52396,b811b3c8,64b693c6,995b168a,3d52a146), +S(2a057c20,49eb78fd,6b1e101f,f1ad93ec,237c31d3,b9eb5a61,cfb9707c,10aa3fdf,12f3ed71,9ef62004,29e31f76,50d42a26,3ffec21f,18618ab7,a1978341,34e628f2), +S(6ef7e589,77b46681,18725285,d6a80278,af326e69,37a1a2ea,c38db58,5dfdf391,7b7f2f2a,61a36fa9,92c25c9,de3c375f,1e653426,21657b1a,46e73afe,185293c6), +S(bb07cd89,749683c3,d0d1822f,b2044a0d,89295a1c,489a083a,d4e0d686,5fdda7e2,93217977,cd636dd2,5dc61a32,278701db,488d4b0b,bca43fda,5f616ed1,bc853e67), +S(86a512e6,6aeb62b4,a3f0e3ff,b3ab705d,55da48e8,5c83fcca,8bae1ed2,c7c310,69efee26,59130cad,c307d137,348dc40,5e797bc3,c0e08888,19381382,7c9b70a8), +S(2e98a430,bcbc702e,d038c769,2d0a18a2,9e68ce5a,33297dc4,d0c6b344,55141fc0,ea01fe68,7ef121ec,d612d3c7,95bc2b4e,aa8a79de,a7a6421d,6d0ca841,4364a8c6), +S(1e94d53d,8f2efb80,fd5f36d6,48517bf,a81f5eea,6e6cc95b,125c0f4b,7f6b544a,4c6da236,bdf33222,7cabe303,ebb08be,5d72cc94,ffe09f83,7f89050c,250055cf), +S(8436f6c,1c597134,be20a252,3808f764,a77cc015,92e2c0fd,d99af978,2ef98f0c,5d088601,2a449b15,e7ca98cc,b12c14d5,e56dcc11,21eab5ce,8fd64442,735202a8), +S(dd438a23,a4ba1fa5,8691429d,7a20119f,26b998ad,bb041770,4fbb7603,7fc939e5,c371b95e,1d2db347,89ae43cb,ad439c87,c75d9cad,370dab9e,771ddb8f,f50fee46), +S(a50a202d,dcf0fa6f,270ed4b4,47ee2d09,55aa5ff3,50bde518,b5365807,5e921a1a,13357652,4cc6d018,e3cbae93,d87adf36,15a518ca,9421d847,92b9b6a8,fa45b5e3), +S(7dda8de4,b278bfd5,3b7d4573,1c3df0d3,a32c8459,37dbfd55,6176c034,359b6054,249585e6,a11e174,ba72b6ea,cf02bc58,f53ad9ea,131f22b3,f273a38b,2ea12e71), +S(8c34d5b1,77080808,84081f8c,f36340a6,2526ad47,8402301f,248cab43,c59b510,d3370606,3ac61796,a8b55004,64e458c6,36c6fae0,ac4fc255,b99e03a7,fd39679b), +S(f2af02db,a23f80fb,26dae144,8c01030b,7dd11c7e,e670731b,5a3c8d43,cf70b3eb,3b91daa6,e360244c,ecd16f73,ea6b2ec0,e2bf1af1,1fee0530,7d031861,6df7cd6a), +S(f52e29a5,fc161198,8ab924dd,300a2063,eef50892,c8aab719,989a7c57,c61b5472,c8d317a1,e4bd73e,1520b519,bf5e99b9,537d4014,11554768,ce1c8d59,dfb6485d), +S(ec3bfc26,168616da,7521601b,8213cac6,ff0525f0,bf1e9480,bf74ca36,5043aa50,b85fb266,cdc767a9,9256a2f8,fe3d5f67,13c46dcf,db0e5668,c51e57d9,e40c68c1), +S(2606e785,bb3bb8e0,e9509d6d,d3f13edf,cb945c27,4b170b8e,f0a1049e,c6324d,1eec7f74,981f1afe,b519e261,a9459140,fac8c0f6,798c4bb0,7402b03f,a9f9c4d7), +S(643cc5fe,b10472c1,b7767be3,3d089e97,6e1dae65,766f64b2,13ca7308,fb1a859,4001bf5f,5b1f1152,41c0a5d7,7c402f58,81466079,7217151d,ca52167b,98cfbc6), +S(7af91d3e,31685c25,e4665b8c,60857fb1,a9eebfbc,b119995,bb30886d,49fec506,ef793e78,d32b7dca,50fd2281,76e9deda,fba1ae5c,51012a9a,5e0f11f9,efa36d02), +S(f92595bb,ebf4e875,5a4c090f,cc7479ec,e36df57e,54d02703,77492a59,695dff86,3d693004,acd31ed3,edc6b849,f0276908,3b62f97b,ffe2ce1c,f030bab7,8edf42c), +S(56d8be78,ba1b90f2,f1e2bdc6,98676605,84ef5cf2,42061f99,a372b8af,3bb81492,37346441,7138d5fc,827ed55f,7342e423,b3413d18,a9450670,bd9f7639,e3f7d1cf), +S(5e72a946,f62a82d7,e1a6bdce,d4563e4d,d11ade3,630c48e,e7dde8f,4431cef9,f963609b,37e6e3a7,647bf3bf,370016d8,e6db7c3,18194eac,b8abb926,1f4a6483), +S(915889dd,b578d98d,b96c9d55,e6d10bd2,85448210,19ad5652,5ac888a6,11ebd12c,fc5c61d2,2b2a6235,51af62ea,56e53daa,a4ba1d57,e1124834,e0c3e547,da8a00fb), +S(eb8dbbb4,b11a53ca,4b00a8f0,6bc5d957,9659ed80,df9556e2,99d77d80,1372996c,3f7d9ccf,b1229e71,fd5d3193,4af913d5,e645050a,91095df7,e9703fc7,5552129), +S(11d9d597,213183c3,cb33f43a,36289f32,94fab62,eb073b5d,9ad2b71e,a1a4475f,80f85384,db3424f3,707412a3,6bdf4e67,4adcfc0,4b2e3957,f9ea2e46,416d85c9), +S(4bb5ac37,b29cde8c,a1c39e5d,b3d75401,26617089,c82b5aff,c61f8122,1e5fa6b9,6345048b,ffa2f89a,4e008daf,91784b02,5bddf7ba,3fbd5357,ec1f8c04,f8f9ae5), +S(542f585d,616db634,689e86e0,bfb7b3f6,58fbd6fb,83d0070c,bb13e85e,17e1f793,8858748d,b65083e,9946ba84,3c842492,475e508d,4bf5bb08,6259e5cf,b47757fb), +S(518c6d50,6d72aaa0,ada7bceb,11e1bda,bc0cff3b,2008651,fc50eb54,cf4207fe,c0415146,d6bc2c5f,9f5bc476,a372c8cc,60778f04,b02d580e,64d37a9f,5380d3ab), +S(92931216,496359a8,4a9f2efe,f2032335,1588c283,3f9055d2,d107b81a,7a689f61,3070db07,ccce7e90,a9f20897,fa4c7e27,fb86bb5b,2b0a8a2b,a63e555f,1fade8b5), +S(e9ee9698,eb0f0b82,763be736,798cc34a,4d290a96,db7cf297,7d067d0a,3989d715,ae81b62a,52d7ef27,29fd82d0,1c0ad810,bdfdd46d,d8052126,52b76eea,ac196035), +S(8c8d5876,6f4419ad,5015839a,4c7fb487,dae2c7ae,990a889a,af2d6e88,81a3808a,e5c71696,20452ab,8e38e8ad,8bd8d5a7,e3d1107b,df7d8756,12bddf2b,7f83f05), +S(98f6e4b8,211c9a68,f912dd9b,784ede0a,314a9721,92dd0ea4,540a9e35,ee10b93d,14e8736,c7ea071,8d864e7b,1ba92a0a,101b333f,b33c0978,59151f8e,f39b4341), +S(f76805a3,925534d4,2188dc28,e47ebbf,18a783d1,71dd3b0a,88115ba3,3bde61c9,7a35dab,99b9991e,73e17ebb,47a231e1,66f8363,e27911ea,aa1968b1,c9babb58), +S(302be8a1,aaddbb7,8417d663,ade6d83,160b7107,87193f1e,46d1def6,b6e5a279,cc2a879b,6235c998,a97d50f9,c495dce2,d99448c9,6dc6075,d20746a9,d73943d6), +S(f53ed104,dc5d432e,61057264,4fdad4ee,57b0997,419c4df7,20206a2a,9e14f479,f05e2aaa,14bf3414,ccf324c3,1d8a91ec,eb3296e3,8e2efb1b,8d18ba9e,cee03ad1), +S(bef68e21,4972047,4ada606a,5b8615bb,812bacb3,f2214104,1ed69ab7,4ffc6389,5ddec4ee,3257d388,c1a3f5eb,39440748,480117e4,9787eadf,6d3daad5,7a30c95), +S(4ebeaac2,693c7ba8,bf0f03ba,1455dc46,bcc77b6b,d0a49e24,4a691880,ac38cb4c,f327fd30,55273e42,35f77b8,d081451c,60206100,15da9086,88e9cc82,6e547fa1), +S(51848db0,9cc33ab3,767adac0,11c1b94c,832b85ee,632d6f41,d65d098a,becbc89f,673a636,c3990364,af443053,77a5e59f,fb39049,e4ab37ae,53a1007f,8c064153), +S(bfd27c68,24c034c5,c153628b,ffdbc62f,afe32fc2,caa5d474,fd1a5b9c,d1cf8d5c,30928327,debc1be6,eb58b381,2132154d,5a7faaea,b3a5a522,8d1496f5,fbc4ccd0), +S(deed81fd,719445b7,37fd23b1,f2f98f8c,690ad80f,1c50c719,79d41526,34bd1af8,14ca4015,7c9371e5,8039b307,6ce0142e,79ae3ef9,5686882d,318a61e5,8afacc8c), +S(83e853f6,d88bbb57,f2e29871,7e3d3e0b,bc23f16b,d2ec5488,4cbcd3ed,de170518,14829326,aeca293f,10f54ac4,5110bd37,d6adc578,a8e6b22b,13698e55,70210479), +S(c2a957b3,3c8b0ef7,15b8ac0e,f8781632,63e90354,86e96e7,a398f59b,91e4292c,5cfba0bb,f943c955,54d31994,630f3ee3,599b7192,d869bcf,24c9839f,806c0bab), +S(2cb61575,18b65cec,dc17545,e8dacdb,28f81985,85fae30d,857d37cb,ab0c23a5,9bbc8c4a,5dae47e0,6ae03f04,bcee9600,2c17f719,fed38740,64734ce,3470a600), +S(7b1c1fd6,f4af2484,25cea23e,840ac8a2,ad8839ff,5c8c34af,9d1d72fd,30f80b23,6c51b243,7e523306,abd95216,70d6ced,235e0bfd,3b9e46e,b4e582cb,d1f1b76b), +S(f78fc2b1,6d61cbd3,4687e1a3,ce9e97f1,dae8a483,75b338c7,d595fd05,db40a4ef,dea54b8f,c9b55943,b2931963,a895bbc4,4453cb1c,d1530d41,19e506ee,b0702071), +S(1918eacc,3658dffc,ef195768,c1819559,8c550cc0,33333796,714c7eed,1ce780a2,c0a289a,22ae8b28,87658b8,41a98c47,71f317e8,cc972ad1,155fedb,da9f9fa9), +S(12905e26,7d6a0007,df0d059a,f285061e,d14f756a,27943f28,1cfbf93c,b343e7b,433b1923,cd4367,4b6b9495,42dd097e,7a025026,7dc060c3,ed3a1778,1441ac62), +S(969a637c,eb80c1af,b8cffe95,c6b6fab8,6329ba73,dc7e996d,a0617f90,48a39d37,6e751f3,b60c1ba7,57519dbf,fa7ac98e,6ed094bb,3bd9cb44,f65650fe,6e8b31d7), +S(5933a9a2,b818cf0f,d39633e1,9641697,410bef1f,127bc9be,cd183d1a,f85f44ab,b42ac6b,c2de2526,5e3c1584,31e92065,a97d6e5f,3602185b,1fbc1589,757c86e5), +S(54b58e7d,a63c1993,2a4c092b,c93e4d24,c8abac,76488fd1,9f56dae8,b943017a,ac117398,ad4ef6ce,d0166c50,69804db3,78bc9b84,a9f5f718,b0311beb,f08986fb), +S(77004384,69bbc239,8a70863c,1d7e31e3,b2f1dcff,64beb2a7,c0a083ae,8f4240f5,8a8649e3,7f3ad219,bb164490,529153a2,aab7185d,639040c7,1b5ad628,d3ee107a), +S(768e2c77,32678997,42c6badb,4d87ec8e,34af657a,4f1d6376,d01b456,7f0f9828,56078dbf,1128686a,1a1435a6,3dfb39c8,91c270a,2b230754,4409e9b2,1f2c7a03), +S(b66b24b8,5248a97,a913e1da,6d0d1454,53e0fc61,66ecc62e,2bd39ba0,c3639f27,3037bbb8,e205213a,4bb524dd,49c667f0,408b69f5,428e4caf,1ec811e3,cf5c68b6), +S(1ffc3c5a,d8e38090,ac36e8a7,c44c6ca4,c0a227cd,1192bbac,2804d033,c50534e,f2d8a481,63ab76fc,391ed0ea,de7b02e8,1580058c,8b84886f,f6d7032d,b95b503c), +S(94b3d61,4d0a5e2,9e7e9ee7,1e2ee7ec,87b14085,cf6f9fea,2ed31d31,517511c5,33c88c8b,8204f465,93acdf8b,a837d4d,5a388670,fb24a861,dd4f35b6,b674ed4c), +S(3a94b6b9,b1b8a82a,267f7ac5,9b52bb7c,52b790fd,ee341265,ee1b6e34,e3e7387d,4db0480d,d2b8f2c7,2c60c55c,5e050e2d,f86bbe1c,98b74bc7,f1d3a44c,3b1df370), +S(2b53bbf,2bb1cdf8,44b25bf3,d1931ede,9e5e1450,78dbaf68,7f4e7852,6a6716f7,70be0ac3,170f7490,cabea8a,63a6fd66,3f1ce8fa,efc5343,566f4b1e,2ca08e6), +S(e5183136,cfc8b732,3f926cd7,95dd8766,25a8c155,d5c8c457,53777c9,beb13494,93c62979,e67f9f86,cc0ec570,273f2c7a,876fcb5b,f88022bc,a8666e1,814207ad), +S(c4c07268,a805e384,db81b877,9d1dde0b,9af6e197,b6bf254,db6aec02,94dc5bc7,2127f162,e2cee5dd,96055ff4,a7bcdb57,19a00742,f295007a,b839eb54,eb317566), +S(2a89c94a,8dee1950,3bc5e772,b2ff9608,a57c4ff0,dc6f7c0b,c1d2b76c,26c9610f,10da34f9,eb14e294,8f2a06cd,dc211eed,93c670ea,47592135,dc33faac,bbf8a170), +S(35b035e9,8cc6f96e,d7dc957e,e07c7afb,fc936653,72561568,25e44f5d,fe4ea0e6,4818477d,aeed402c,870fc50,6197a0f1,5c72a378,e42785e6,be38bb21,6d4ce91), +S(f0a3e92d,647c07e5,5a435907,34c0ee65,758e09aa,bc2a81c9,f6d6926,c03a9cd3,18e7a09d,720e65f0,b1b8fdad,66d4322b,99733bfd,f8c5fba5,afa930dd,f441f095), +S(4db3c367,f3ba6727,fa274289,675d2fbd,1ec7ca8a,94d97bd0,46815f04,368407fb,d5e0dc2d,80f3893e,f1871740,dfff1589,ff75940,e163f8eb,115e4b17,dc1cf693), +S(9a0fa624,b0eb8dd2,f50ab259,cdd9b17f,7a6f318,93786640,56a49867,89a5d27,68e82527,18684672,ed4df389,98b830ea,1547ff45,f48cff63,5d291bcb,e80f3cd5), +S(19f72db8,e604db7c,ef2e8478,c04540cd,c3806c1e,eb9e8071,38f0a272,275d451f,3cc5df1b,dd845f6d,a4747261,f8e1f821,c7e6f2d9,d9cf9a90,d3c7edcd,b6fb940d), +S(306fc07b,7e543dac,ac240f8e,7ac82cb3,df70a2ac,1bdebc61,adc65fb3,e696743,f27b90e5,a2a5abf8,19c90983,51521f03,26532b1d,37875466,f87289f7,244a3919), +S(c46e7e67,a036ae7c,b30ae479,d0f87d7e,6cc8297a,3bd4c1ed,c2436e6,b52f532b,723dc476,426eea8d,2179eb11,35599275,2cc391fd,4c25ffb9,a3942356,a56899a8), +S(a950852b,587a01aa,7a1d4688,8ded73c9,cbadc922,e44fce64,61a5aa5e,dde2366e,79a12ef4,18763f51,62ccc65d,86c94012,363cc21a,61d12982,ebcf2ac2,c6337791), +S(8cad422a,4ea9d987,48703d5e,eb95d48f,1f73d893,91c7c239,f96a7155,98bfd153,111116da,fcc7a212,a1e6e0ee,4e824611,a3896543,aee02f46,61bd5ace,2a67c652), +S(3b922988,8c2bd057,785b4013,fd14446b,7261928b,a8907ff0,da433d2e,61302362,4eb99bb4,d152e218,8cf3464a,68fa266,500dec96,5842c2e3,a3dc16d,e6edd74a), +S(36129c09,42906435,56970a6f,ccab5f71,113b82b5,819ed4f8,451ff01d,209a9cc0,b30ebe06,b9b4a4cf,8451d8bd,7d9534de,375a396e,b2d7bc21,67a56f42,6426d3f5), +S(8a0a960a,e3bf57b2,ae76893a,b665856c,e09a6f0e,2748c703,2d951cbb,6ba038ad,e29f3916,4928405d,84dee9fe,973f613a,3c5e1c97,c6e5e814,a927a6ce,60efc2bb), +S(641f4fe,dc351cb1,93a088c6,b6ad8867,442cb913,7f0ded13,4ef0f2c8,d721b887,600a51b0,f80a351b,ce7965e1,eec4c8ea,9feee470,80b920f5,67e4c979,84b48dcc), +S(cca5d72b,8d78990b,267cf3eb,246545e4,d416eac1,600078,2861bf05,c0132b3d,7ea6d271,f01c4250,d07e782c,32f0d6e7,177d7714,e2277282,4968092c,e0444f42), +S(c6ca654b,fe45c9b9,1f3869de,2f96f27e,351a7f1b,4839f7a0,9db2966c,f81f052c,894661b7,2d156df4,2b307506,d990ec47,935b0605,9aa97bd4,26b0df6a,9e3d2183), +S(2a959d49,c5161f7,6ce10ee9,cee3047a,be9c620,569a702a,9827dc66,84f6f35e,918b7a8e,e283539f,cb52fe91,1f5039c2,321a6e8,be0c4449,66bcd7f4,594d1e8b), +S(bfa77e7e,3dd28fd8,a04842e6,6f01a9ad,476ff448,18e4a3ed,ab2a8b6,9ba42ad8,d85cdccd,2f5bbba4,1718b70b,c10cfab7,272377e2,5a578ee9,be991b4d,583cd62d), +S(6cb9b861,de296ad6,363da904,46618eae,fa852ee5,ec1df0a,d0a6955f,7b9c6d97,978d0afc,29cb0cdf,f2ac432d,cde6af4,1aa6bb4e,219a0687,11924142,deae9f1f), +S(83446c25,f0496ada,69354c67,8a1ae34f,154afba8,318be7e4,ec52e5cc,ce9dd139,7d4c3e81,98a8905b,63572a16,5fb7701c,c8f0c53,3a01f47b,532eeced,39cbd620), +S(590279e9,f8a2ccd1,c62b85a9,87b528ea,d746a42a,fa07b358,3c5d6349,ef678b13,75627950,5089c0de,33822465,14565c8a,cd131b14,949626af,15c56e47,bdda7f1f), +S(311d1ac6,4b7b1a8d,7c6ba19a,ee5869b2,2d769098,a6e4ef1e,3837082f,ebab23c2,c0b9714a,e1627902,45649db8,b7eda70e,25cc9905,57397adf,39c2c1ba,bcefc497), +S(f63f9d45,10f232ec,5c1f3831,6e16594e,a82d133d,6dd4c365,1da3f34c,c8197be5,ecbd7232,4e732295,750d8c5c,b0290d04,9c778707,4cab27ab,35aeb978,3c743a7c), +S(b772d2eb,c76f6f99,7722aea0,fb55cd6b,592fc0f,c8b87511,d85226b1,845a517f,6b4b0363,7186cb53,ef0d2dbe,3ec16efb,df0b5de8,dabd4d9e,871f7174,94f80538), +S(4dbc968e,8697c131,7d9bc180,f98a1320,bf69fedd,24d71b35,c1e87c95,13420335,f6ea65ec,44c5e25a,549dad16,ff129abc,153393e0,e76b20e5,c1b1ebc8,9ec169bd), +S(2acfa0fc,a5377dfc,21519105,a5f434f0,914fc259,95bb811f,1d17dea3,2345bac1,682e091a,47b18d6e,7595bd46,28130bf7,faef8df7,e8224e02,3d87ee03,b3be8ff8), +S(d77801d0,eac64c02,cbcb795b,f030ef,37a131ca,f07ef6da,2f3ed0c9,f7c8922,166fed02,aeb1395f,bca109e8,5d599f9a,df684cec,418c7576,a4e67e3e,e1abd7ae), +S(92006fab,e11362be,2c89d0bf,e1250e9d,3c5282ea,38be9206,f35cf913,496c9481,2a5b39bb,755a809c,f76ef97b,7e59f00b,70c94a4a,9dda4bf5,523e3cc7,2ac83832), +S(43af4cc0,66155b9c,fd9decf5,e95ecc50,3c69e99b,b5dde00d,bc859732,f4f7d79,7415eb35,75c9e0e0,c237dfbb,af245290,11f5ae9d,63ced644,f8c5af7a,c3e59c48), +S(c018d581,152fb656,c43eabf5,f4e7aa9,c8c5f722,f5352fc,3dda72d5,dacbf451,f9bc1975,acd5aa76,f2744c85,22a07211,daef05ca,8ab0c200,6196acd8,29fcc9aa), +S(968bba6e,77c83e6f,be7272e4,f6288349,329058e9,c3b197e6,f9b56dbb,8587f2ce,3a841d0d,1066ee35,4fe70855,3bf034ea,4da917ee,87d27a0c,f60f8e99,ca45e065), +S(6481bb71,dce335a6,98972f0a,bef2b4eb,5302893d,175e1f53,9a93dec7,53d8e4eb,94073fa3,98393d5b,ab446695,889f9805,6fd31d8b,c14b5ef8,8669736a,5586d3bc), +S(22d38699,cdd4d0a9,ff6bf179,d611b831,647bbf23,5da1fb6e,ec063070,d5420cde,fd4c6d72,ffcaf8fe,3410a0dd,27497df8,98e02920,272a4daf,8967d547,4fd2cef5), +S(acaf068f,34b0fdc4,b86f606,1f96d172,69f63e48,c739f1e3,46cba1f6,9e4c6164,6f9cae55,559fad61,e20bde43,ae671832,85e83ad7,429f031a,b365cc40,349ee3d6), +S(1d2f237,b91c5642,d3dc3c47,9db9716f,47bb34e5,2bdfb7b4,1640e517,f83778bd,9036f65c,eb367bd7,9018993a,9e01b350,fc903bb0,ada247b3,26761011,bd70e0f9), +S(42bf9891,9c347e33,65990f49,6cb09a3c,654b7a09,29cc483,e9028191,4797b6ee,56ed030d,f2fd51e9,98c63f3c,338892b3,49b2c30e,9ac6b3a9,a0f1c18,16b5bada), +S(b48f90cf,18157b0,de5721e5,c0b1986b,1c16f2cf,1b973578,d8b3a41d,6d18f774,40c392a9,c94e2ef,aa5aa88d,36eddf6d,d01a1e37,60d8e391,4ff19646,94557641), +S(8ec7123e,551695cf,c1668bce,86377900,f79e7311,85c5e39b,9d24bbf2,e6409313,f2f58364,339fd734,910c9b65,be0574c9,2bb9efec,ecde3b50,67850d71,d98adbff), +S(7dd11415,1359f2ae,81d4b18e,5afc6657,788d2bae,5c76728c,d1d25265,a2dc2801,32f37924,4f7389d7,7f23333e,4c4920a5,5658254f,dd7febb1,2c3d9d9b,ba631c09), +S(33556f01,4bd89b67,52e7e1ca,1d5fc7ba,faf6e25b,8a49f57e,51c293e8,6cfc4a8f,5c8467cc,3553a8fa,1e322b04,83a0e3b,fee08772,69582178,668c51ad,f3661454), +S(f92da876,e7df1d95,cc2f820b,47921a26,413cb84d,ea6e05d1,da3c70c0,6f5151aa,907d6a04,dae7f625,409e9d3a,8a92f636,f5496ea6,c15825a0,c9d6d6ad,54068a45), +S(77810caa,1e90962e,31ca5e91,2c310bde,cd010016,1f124b73,81492437,5d24f5e0,205b009e,d933e873,a2e12c0,5ced5536,c9b8918,2776bcbe,b297a955,bbc892be), +S(5740459c,5ba49bee,db0fbd8b,5a5dd0a5,24d47dad,ccdbb28,567ce303,58e70b22,7092b9d5,a3c96984,da084d42,f2bc5f1e,a51cb1e4,b8508c18,6ec7066a,74141f68), +S(b7cea84f,84d3af1a,797d90b1,f7a460d8,de9f4a6a,2f2887ab,8f464123,bf844cf1,22f82480,7b05e21,4b885ffa,e8576fa4,c44a3824,5e256d55,cbb1a5ee,343f577a), +S(5180dbdf,73208c2c,b5e605f0,9f6403d9,ea5bc592,29007598,bad6a913,a80f5493,247992bd,bd823a2e,6ee55330,57d78d36,913654d,c3e089b3,fc042fec,15ee0262), +S(ac413c18,ff3bb767,9070b698,e2108268,9bc59a13,1f011baa,59799d9a,daf43cbc,c2dc42e9,78569e63,ab08b155,1e4c52d6,9f770211,86803f60,dc752573,d536af5a), +S(f7a5bdb,71b339c8,19ddddf6,10ff7be4,6af7dc87,6466473f,a01f314e,67bc52e6,6b572fee,bdeb8cb2,9b72dc1d,5df185b6,c50f5ed2,5e95a61,c1dd4822,72ca2adb), +S(6980f38e,6b164eeb,8eeca173,15c6874e,c35bf6ce,78779e4f,19327df2,b1f57dfe,e19f87b4,4e72b29d,c55a47d8,2b5d9621,f15d51fc,deac84b7,87ac2ddc,40af3935), +S(98adb6fc,879900e8,2ede0825,32da151f,b7a16a5b,8d2b9eb2,4e8dadb3,46ac67d5,a7349dcf,c4786a3c,2686fee6,c8d43a37,b91c1b82,886f853b,fcb6831e,c8404262), +S(c46cfd35,101d86ed,965d16b8,55992ca0,932822a,550a71f,54543922,54b00e36,72c03b83,34d944f5,9c4f553f,c25ff5c7,d887d5dc,4e82f90f,cdce7e41,52977e32), +S(71caf0c8,2402b643,ff0b26f5,7060658f,d29294bb,7695524e,99692495,b69584ad,b11c3736,436c04dc,3f4503e0,27ab7a76,2ccb1bb9,74922f92,8fd63012,e174fa68), +S(cf46226b,243fd1b7,984a38cb,f27a7fd7,e7a35a9a,e972b0cd,4b438c86,c6df89a8,f40d1f01,ed7ca764,11a3e0ff,55d702d6,19a68ff,88d4df9b,3f7d9c3d,b96738fc), +S(d8f271a,a092d515,176b611,25abe9d1,85a15d55,b486818d,b571a5c6,4c51b493,3878f749,5d4d9981,5ba550ef,3dabec35,fba40c5e,d10c4b54,fcf63b23,24b91e97), +S(6d60b710,8fb40460,f893c53a,34c12054,6a02c037,821f2a31,55976104,11657d48,a03c71bb,788b915d,9ac25950,30d8c31,65c0c1c9,ed2abde8,96d3c985,3f14bdd9), +S(924f3ddc,7d5d3764,66b47124,b75361db,8afc0eae,7848e860,debefb75,452ef586,c594e3d2,15f58f5a,255958b1,4936df62,3b68a854,4fba7aeb,58a54905,b19c5f25), +S(a668983,5487c800,a1c34b9e,ce7b2347,1e4f5f5b,3be7b591,3390ebcf,2928308e,626c8044,942f74f7,8d255207,5f9d18ed,8982a341,583f1314,4f53dbba,40c94c0f), +S(7fbd491f,ec466132,c2838c46,a5d6ee7b,9dc0318e,3b3bd3ef,88d3cef0,6465cfed,6cceabee,fa659f6a,c083355f,b14cae2c,53657f1a,3c536b4,193312d4,d4a28e36), +S(85122c42,ebe8457f,be82707,e49e0b1c,be3995a1,2998ccd1,629b84ee,935efa56,1cfe76e1,922e4cbb,1023dd88,2bc03dbe,c0be2cce,9fde0797,92adb2cc,925dad51), +S(3ac4d527,3be6b39e,d6326132,fc212640,450791cc,9eb43b39,a77c750d,8acad644,f1d8d690,c1011f,46f003ed,6f9a3342,ca0e918f,4096fcfd,406644a6,2cca296b), +S(838144ae,70bbc188,a05f03bd,9123b93f,e4bf4485,8e380e2d,5d6723e5,fe955cf3,9d8aa248,2bebcfbc,cbcdf87f,c2342618,74e99bb0,507f472c,e86a1b5c,59307a64), +S(4551b877,fa1d9811,e9fb6afc,acfd873f,7507103f,58ccf82,feeab7af,8e893ee4,ba0da9c1,1fb2719f,9a81e745,fe4ac1a0,221b01dc,7e3eab5f,9552027c,87b2fb30), +S(baebea51,e0fdc8f4,cb3bb20b,cb3f4bf2,b37ce31,121d6b5a,7a3313fd,29fffa44,41a4785,df2c9ad2,99b0d0a4,2032b8d9,2f56835a,7bad7ac3,68370046,52c66446), +S(8c03e4da,5be53c8c,6c6c1dd7,ced8fe99,b88de276,73ec3ee4,f5152a70,d0bbac1b,bef7a8d7,df0651ea,1d328729,b0f85ef6,a22b3d66,64ff04b5,fa1c9dda,2073d25e), +S(8d23846c,34ff8756,bd30eed3,1befcd53,4b171dc7,da0715d6,df3104ac,23104ef9,49ae984b,be3cb83,1c2a18d0,f527df0d,27eae720,922f34a,b270888d,9361b708), +S(362c58de,902d1c62,19da8e4,e8ff33f1,61d7c001,202cb2e0,add6bc30,dedba48c,235a0ee0,909dd6da,d1d8a8b,f5f1720b,d6d7e38a,b2b5bab6,788f1983,a5de3137), +S(f836b56e,2892fe8a,a88aa77b,e345c48a,572d0cc4,87d75ddd,99e3e471,bd0461ad,c4254af,e34e6705,12d3652a,38801946,92a7b170,be6fc60f,555c3835,84ca0611), +S(75374bdc,ddbdd08,2e408d8,4fae0652,bc6d1e48,89a7f0,bd1d2257,d75d4f4f,8b77030b,4ee786c4,2973b7a3,905d207e,46448c36,c7d7db5b,280f5936,eed70ee8), +S(ec299deb,26cfa600,a6385db,f04c5b0d,128231af,6453fe62,29bf32f0,71bd1733,be200050,afb2e277,5f4b5688,8ceb6af9,50f901bb,b9a7dc2c,34f9df46,297cda1c), +S(c2ec7bab,4350cb7a,d45f3c55,701203ad,bc00f9e3,17c2465e,efae7069,fed17a1f,33b1bd74,3375dfd8,f4c69ded,f7232449,4c376132,5afc8e6e,a6b67aaf,b4570355), +S(62a96481,d4d9b559,e9ccd855,2d6307b4,8a5d03bb,7a9e7ec3,de8d193,c33ab2dd,c14bf21f,58c2f112,f399e6e,ada45660,6c80fcb,debd967b,e3e3af90,caa3d1a), +S(6da7531,4b8bf8d7,7d72a367,63696a33,4bf5dd8b,f192e2b2,aa646277,f0d6ee3b,70da7974,1576f5ab,da432280,f269ad51,5369a399,5a7de050,ac7eff5,8b7f96c8), +S(af59c78a,126296c5,f19dba32,b9e414de,dd2f1c34,6d6900d7,3ea52e56,5e9cbdea,35b963b1,94d1071d,7769e4a4,3fee70fe,4a63a0c3,bffa2c12,88ca2a82,a7c38bf8), +S(a86e3627,551f2831,b88021d7,d8cff6cf,50fc07b8,5fbb0889,bab026b6,6fec63be,dd205467,4213f012,d45022fc,75de7c2e,b3c71348,efd536fb,1e5f875e,1ae55c63), +S(2c59179e,d9c22abf,b8856e9b,311abbb9,7ec61cc,7ab145cf,5cac94fa,77d65004,e94a1b85,fc8c3c8,aa86338d,819f7139,96a5b72d,68952a6e,8ae48c47,aef247a9), +S(f406f78c,7be2e678,d8315272,e7d861f5,250a4bf7,354da2f2,dacfa22c,d56e43fc,fe719c86,4d66efb5,16a49af4,a86bf463,6130891c,7fc7da01,4394a319,d66b0493), +S(c89f1828,1d899423,83dc622b,7e6017f4,cc02b55c,5c48c824,5568aa3a,c3c25566,40a58eff,8043e3f5,753f9f54,31f170fc,795ade25,d6200e0e,bed182a7,8012de93), +S(36179740,ea6dd2d2,d2a537a1,c9aebd8f,c9a570cd,6fc25453,1d58866c,83ee051b,80643869,fe206f68,4824330c,18073366,9b2b7e97,51f1282e,3c52fbf9,f4899a90), +S(ab5d8e67,7fc654cb,88458b7c,e43b830d,74b441da,9a1af152,9147dceb,13bb2907,b2ecd95b,bc828f3f,53af76a,b5d60dfe,aa681270,74d8ca61,2558c778,ced8aae6), +S(b1e79103,da12fe0b,51259b9f,3c4b74da,1d8075ac,e1aa912d,ed6da9e8,2bb14706,b726371e,7c872caf,42c049d2,96f998a7,c928d991,535550d,a13af044,bc61a1c3), +S(9792e304,67ce4e2d,77f288fc,34c6b2fd,dde99e31,4f0137b1,f2da1d7c,603f5754,d880bcd2,6a74445d,4ad0bd78,2963cd03,9ba288b3,44711889,2ff00de9,4e966be1), +S(d8180648,f046c427,db5a9912,6d54a1c2,915ffb17,c686704d,38fbe1fd,d60cf774,c4767b5a,fb34dd33,e5de912d,b0619e5,c39fdb89,2c131bf4,97cceaf2,aab6f2af), +S(9aeac423,159b5746,565a65e4,c00c12ad,537385ed,9fcf267a,802e2290,ec19633e,7990008b,db7ff6c6,cf110dfa,96249b74,c5173d7a,f7489d4d,86424749,5ea3c63e), +S(2aaeff31,78bfd5ce,b9aa4af4,71555de6,7b1c2bb6,61bd9aa,8591f15e,8148e97,629620c5,8542d054,86245859,e608b5e4,55c45fdc,32177c19,34eb9b6c,23554f89), +S(bd0451c9,211fbabf,21a6b969,29edcd7c,43f10d34,219c6d16,1c5910d4,ae8b5928,23d4a749,b11a1fad,68a8e65e,5c940315,ff326947,868dd92d,9f6f9221,44a4a642), +S(205c5f6b,88865d9b,b53cf8e9,7e97d781,8e038c60,b8177ffa,9501590,96ce5592,b8848543,287401c7,7229f94c,840e36c2,bb93acb4,eecf9ab1,5bba1b49,97d3745a), +S(a3d24c8,f351ce59,6f2da6c2,def943f9,6ff13d0a,c7efb29d,ca3c39d6,5281b96a,28d5fdb1,a8c1934b,a98508bd,8b17168a,a78cf549,1b3b3636,8164e95f,17e8bef3), +S(468f528e,8f2b12c8,4b90df66,8c401f4e,634b2b9,421d1a1c,1079578e,2739160e,3070d8d1,9cee21ba,510b72dc,b17b7e72,7c0adc0a,baf58150,a24fb409,9f203f03), +S(6a106a2,ad8bf04f,a0ea0c66,179b3a4d,df0eace4,954a40c5,ad3d611a,ff7965d,fe893d8b,20f94be4,ed7b20bb,4feca170,75d2e5c3,61cbf44b,387947b3,8d996a91), +S(e59d055,1f1f0a40,6e94a2ad,c92b1e5e,54b74ffd,8d0af6ba,ad25de6b,97a470a8,b0693f96,9257ca3a,da93a54e,f3c29a62,20cf4c33,a9cc6915,f51e4d50,8ceb7efb), +S(ee7f4a6a,6e37fbfa,f7db77ef,ae9e8745,c5ae64be,338a6b52,e5138ac7,860340dc,c92c0a11,17b2bdc3,d043f6e5,b90f3cbe,412a9a61,79ae3f00,7c397589,69eb1616), +S(d42377d8,5dabf33c,99268106,f86e7939,c87ed35e,affacd68,d211b4ab,70ec2c05,ef130233,589a5fc6,5a23a029,e1857b86,d6cb276a,8f37bb8c,996dce4b,e72bded4), +S(e21015b4,d76f0245,8dffad7d,f67151f0,ff4c4d1b,ad5e13f4,a6e197c7,2e4c31c8,b78e9d47,31a4c0c,3e29e9dd,2173ab2,16a5b8ec,522604ad,43111600,bc3e1733), +S(53c5434,9f0270dd,4c76d116,eb2df817,b66b504,87367767,d4a796b9,e4516f2c,5a4b7adb,66ace9af,59d1286e,3d89b2f,de525b27,6c27c1d2,1d7a38b6,b1b9f1d5), +S(df9917f7,6cf50cd7,2b8b06cc,cba9a47,b7e0f64b,481adcda,a6942a96,2319e81e,171d72e6,cad16682,bea2a90d,72b0aa4d,899e1627,18b96109,4a501515,2b754453), +S(79eccd0e,f2d48da,3ccdf12,91269dc8,21453173,7991bd38,ec3ebb33,56a594df,72371a43,74284937,aa92,6eb5e8c0,6911bf1d,4efb097a,8d78f46,da1a87b7), +S(3a472336,4c182521,81f90fb,66d768c6,a1a46cd,85c86108,3a09696e,922dcb44,bcaefa87,7b8d963f,d6e535f2,db3d189e,4fdd8626,94b0b60f,136b25f8,14e3154d), +S(edc9be56,27acba38,178b0c6f,cb7ce6e1,f6ecada7,a592d6e3,e859a16b,459c6d7d,bee091af,de809fc6,9b819ff7,1691f13f,321dd702,3944432b,a278df70,4ea02eef), +S(9adb48f1,439c1850,1895ae30,649992af,3ce3d085,13c6a92f,5226f3c9,ec09e5ef,3dd78cea,3a3169dd,78afb39c,ff690eba,e9cd5f3c,42d7c583,ef093a57,635a1df6), +S(942953c3,b620e636,63f2bb83,6c2c3a9f,6cf4a931,2587f57d,9489ffb2,38895bf9,415c121,6ed101f2,698cc0f0,9c3ec0a0,c0e8458a,3aaf5879,87ff1b0,89992932), +S(92c539de,88e6d094,e64c4b25,51da4149,19677124,d8d1e53b,4d0a81a8,53501619,c9b5c7e2,dc61d875,4f33243,de28ed78,adea8e56,e193ab0c,d1f5464b,e9003a45), +S(29d33ba1,e9972c80,2f135a4e,add34b21,408be4ee,29d7be7f,c7f8ade,3ed07cfb,847cda60,a3e6627e,5abffd6d,b56502b5,f26df3c4,630f4f76,aa868899,63566e7a), +S(727abd10,6aeb6f80,f1dd6319,4bd4abb2,2db5d8cd,e7676273,cb0b4246,17983d2b,476962db,5de3493c,58dcfa1d,fd206a44,11f590a8,2c7aa7cf,3fb377d8,623c9639), +S(d898349d,89eb2d49,f2865e19,88c3b5e9,f43ba281,6a0ae0d5,b031e186,b23fdfa7,4d3083bd,681a3a1b,988d3bfd,70fd6b13,3a1d2264,feadd852,b2298450,f729c471), +S(88526dd8,a52010d0,fdcd0223,7db54b43,f73b7195,cb3b2081,96257c7e,ced4649,686926f8,6457861b,4eec6999,626115b7,f9e29e0d,74e44027,5df2f583,7b75699c), +S(6b64ec54,3e5c83d0,b36711ec,b0a4b8a9,25fce55e,4923fcd8,6dcb48f5,43bcc107,8a7d84ca,e8431663,3d635a78,9598a22a,532465e6,f86e6eff,108449d,a5b0ddd4), +S(9017d917,e7e80f70,e5fad8f0,3cf0bcf3,b20bd8f7,95c4728d,e259bf0c,933088c0,e2a9c53d,e1278404,60828e57,eb5de14b,eea14cb3,41bd4d6e,4b960ae2,807299b2), +S(2f7b4a5,591268c6,eaf64c76,5a8321dd,2485ee36,bb1b338c,b1473535,658c376d,8f2cce5e,42869466,a3658460,c0ecbb46,5d850b26,85642b52,e01f3b08,544fb94e), +S(316bc4ba,1dec120a,7a10ef1a,aaf40d63,9f404948,ba27f46c,58763508,4809c78,3522dbc9,f861c154,771952da,7dc04ef,5b5100f2,b4355177,b62ace04,a717d056), +S(69c07c8e,2c1facc,7ac6e08d,3b74f1df,cc24751c,ada31142,72d2e313,78d76683,474693bd,649a0877,a3eba75c,910ba3fb,bf8aab97,5fcae30f,cf47a51f,e9a59f24), +S(154e4dbf,787e808d,c19031a2,df25536e,4bc6a71,b03d8f77,5c652812,75a84a30,e79e1a4e,2440cea0,c6c63098,ecfbc52,f5cbec08,39589beb,251af76a,50eac221), +S(61c158a6,b963f853,66598998,908f85f9,bda6ad6c,827702ba,f81922ed,2b675b4e,d63cadd2,c63ef3af,7c8e9695,4ebb28ec,48dd2c86,a69505be,d06ab3ab,c4bb4fed), +S(97dd50fa,eda2da43,aedfcde3,9d55b52,de43af06,13435b7c,6744dcba,81cb9b3f,e99138b,1c86d820,70ff2e82,413b19ae,d83eb23d,636c4380,70116490,bebad75e), +S(b2a43ae1,947e0e8c,e2009813,eae3e500,ce67b1c2,cc19701f,5b6cced2,e775cd57,291593c1,dee03645,4d0b8be2,642cafbb,cb3b7fb,a045e402,2006c702,3532167e), +S(20580468,68663d06,568988f6,17442d5a,6a65762f,cdbe91ab,128ef99,990d722d,ea32d66d,56f1fc93,fd559c0c,e8b200e8,e423d097,26e564f8,8f53b3c5,e8dda8d4), +S(c2b98b13,bbf661c8,f4cae855,158f095a,9b62947,134c5da0,9dd2d377,959ffdba,3d6386f6,915a7e26,c63ee1ee,6970928a,6f0e4e29,cd3ad665,fa4164a5,a8b2cd7c), +S(fc6c98af,7fbf38e,53690a78,34d82a56,170a18f7,a4e702ec,6e918510,2700611d,9ccd38cc,f8aa409c,1a9e0b14,d01bc9ca,69b5ed4d,7f92a177,e42930a0,222cc755), +S(21157d1e,1bca5a3f,2dd0153d,b9af3079,e1e531dc,9eafb9fb,5042af2a,e67d7000,254860bc,97cecac,b4cba1db,79b13fc2,199f037c,aa963d4c,bfa2b9d5,70456cd), +S(316ea33d,dd576b35,e45fc5ea,5e384070,68ca63ed,1149807,68a7c6a0,d6c628f1,dc236dc6,d0ab4c12,63124830,633729a6,9b20a22d,7d395af0,38d6bdc4,34983baf), +S(21b825c5,44a41bc1,9f048a0c,9a532a6c,18df41e3,e7cbf6db,97c871d4,a3cd0039,9d85ccda,c67a4a39,ba10128b,382925d8,6cebbc0d,70354ffe,aaf89ae9,1fec461f), +S(65a4b32c,e116790e,f671e6ef,8ad317fb,efb815bd,fcc1708f,32c0c078,2ed41140,634c9efc,6470a929,8844f082,5a9d34c3,ab14778,7969f095,a1b45f1d,dec806bb), +S(cbdce03,45e01ae7,77ebf819,41123ae8,b4683169,246c5156,6afd6a54,e9eb6844,5414d24f,ecd1a159,70882003,3726c1dd,ad939df2,9a12dee3,224fb9f0,a89f03f2), +S(9c4d4ee8,3a36544,ab38334a,46586864,bc7c301f,710d67fd,226d6e59,a6532374,868f765d,3dd5823e,7e2e6791,21bcd41e,9b89df55,27e191ad,c5016463,ac7c7991), +S(4c890df9,dee96da9,7ad0b768,16a50240,2c9fad7d,5ea13a04,3eebae41,678214f,397de76a,319e758c,199e2343,6990a34e,79b968f9,1139324b,66e5f7f0,114cc9b5), +S(c7f4c3e3,f7ccd93e,2449c653,393ff2f9,c8d362aa,3dd01128,9879c983,f9b49229,d2ef30d0,68321b54,91519698,79d8dafb,8d2c5ad0,9117687e,10c5a57e,ae4df846), +S(e8c810ee,daa58b8e,687fa493,6d833930,e7de9bda,f73f11ca,23734756,d4d05af4,2690ab19,e6c9df94,349600a9,269c76aa,633c4dbc,abf24604,3cebdc83,1e117d03), +S(a3f51d28,ad743812,3cf9a169,d6581d9a,3d41a131,a8109eb9,a38bb3ad,9f66187f,3f87496d,d5f9ec37,2e3d0e79,7c12e7e1,c328658f,49cbf237,a4e36415,76b89e75), +S(ee0baf50,f62282d6,b560d1ff,c18196a1,a038b27,f081da32,1d82f3f1,82c27b17,4e4dee4b,182056b3,dc809d4d,2160a5a2,b6dc8ef0,e933e45b,5bd1375b,c677321b), +S(346b4fc7,535f3a2e,79330614,e0618d0f,c2a44ffe,a684076c,704764b4,8ab3d95a,98a41f22,cbe44fe5,37116f8b,9ee68e3b,48ed63d8,33cb9567,278c520a,e400bbd2), +S(55fc8976,b796bf67,9de4b2bb,aea29d6a,e3cd032f,7611e59d,75b8ffbc,55c32b79,2e5d3a9d,f8b32c5d,bde33229,f2e9c852,702dbd58,31bb1917,2e47685,c395ad1f), +S(4ebe6051,7453c3a8,a7b65c1f,fa7d0b89,c4cd4166,f2b8c670,3a71484a,f62dc563,6fbc68f5,a7b3431a,1dd6ff18,b7f1676e,a42ca708,f56e50b9,8700ed3a,560b3850), +S(14bcdbcd,73f2896,c8b37bc7,e06c195d,17349c69,9be4ce19,3fe4e145,a79e20eb,2bacba55,a4611886,7e3c11c4,4f14bfa4,d5c702ab,b2385584,e07d7b08,42a8ec61)}, +{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), +S(f59c22fd,8c5a2e,c990f3a5,e6adcd12,f7cdc433,88ddc16c,aa41b9b2,2fd8dddd,8f63f807,eb1b96ae,ec9a49db,818e1228,b9d9da5e,5b1603b8,f5c65900,782a6c53), +S(effdde86,efffab86,6d1da179,211a52e9,b3ce9fcf,c5c3282a,1a87cbf0,aecc882b,57f4a91b,b88d9746,1d1ea75d,4eb2501,46899ac2,ca707ae7,88f35b3e,9f6f8e36), +S(6a4d17f7,3eb94a48,a369cc8c,4c827003,8967190,3d6ac75c,cac7516c,e78a8da8,51f297a9,23bc21f2,ea576db0,15b49d80,27fb1ea7,597179d6,fc47d749,5621d8d), +S(7af337ee,d52f0c7d,ffd0628f,7866d621,dc867661,7dade077,2655f1e,3c331d6b,9b202463,320d18f9,2db990ec,e41aae7b,112d6390,33418eab,7f86c874,a040e2c), +S(4a9b0428,2687d362,66d8f33,8cbc38f9,8d6e6f8b,bd5dce2,b911d192,2e70a583,c2646913,7c7023ff,abadbcab,4da4b90e,8ea8736a,fecb569e,dd822733,8422d74a), +S(53a776a9,e10f53a8,454795db,bb340cd3,fd0ec50b,51a164bd,549ac834,ede835cf,1b976c44,de266928,49631bc2,950b4d24,f11fce3e,a728674c,8713d3e,35f8c0cd), +S(48ed6e74,c75c7733,1aaef9cf,ce06038b,bb405ffc,160c5711,b98ad6e3,44baf62f,fa56b3e6,b826b847,667ab6c0,ade30415,39d67509,61c0c199,14715bb1,bfb218e9), +S(65db9062,2328f7cb,e9afb758,294e0d63,d0042b6f,7615225,ffbd341b,16c5acd6,1ff10083,e9f66f89,bec1330,dc309813,2d434191,2eaff4ca,b3c20177,7001096b), +S(be836639,aa622020,9ae01ae1,f96f9256,9ab7aca1,2f5a7277,903dd653,18f9dcb8,293ab5e3,c50f117c,71dae650,b16fe28e,bc14eff8,38fac552,6adb3393,e177ffe), +S(5ceb4539,42c966e1,65c0e346,2172bf2,e6e167ba,261d0e61,b67df26a,9857b747,88d78492,95312fa7,ee43ffb1,775282f8,f692a83,c6b4a72c,a1ebb44d,28983f00), +S(216fd6b3,c5358b4e,831327fe,2918d70,ac627bc2,e12ce34a,adcbb23a,c0ed2a8b,d450d01b,83fd1935,f0a7c919,cb91d162,dfd14cdc,3d15661e,a303952f,ed70e684), +S(354a9835,50c72d71,37f8d393,2895f1c3,b2e6bc19,1d9ef2ec,3a2b7dbc,3cd2ef76,e4df044d,4ff91794,3e6d4c59,90095781,5ee0338d,79329ffb,ed74bc19,103fdb6a), +S(4215c5e7,7d2cdd03,25f38b38,8a204013,62114d94,1bc57216,56e57878,b2750502,b4d82696,1aedb8f9,60da2950,cb5b489e,857e30e5,20a8e1b6,84dd4032,d8b6a494), +S(79bb1258,ef4deb1f,4a2baa34,91d9e27a,7b75774c,133b9112,3e5fd848,37a57aa1,d467fc67,dc932c7c,48d69609,f955701a,e6a30205,42a51c2c,10591fd2,134bfd1b), +S(eff02038,49797c99,68c8d63b,14a4d84,f4852504,2ab269b8,182b2207,ba94eff5,79a6fc31,e09c939e,f69a345a,56b90c39,2dd58054,e3f23e9,c16f84dc,ffde8e0b), +S(856e40d0,54323270,3ae30d75,8405401b,72f7ec1e,96cf59ec,1f3b8465,23466dc1,d1200346,5e56370e,96663479,bad5f6f,8fa4713e,79217649,c48eaa8e,4bfaa8b7), +S(f020d944,14008a39,59feeeda,49fc388,d41246d5,39a5bfc8,8f9673f,8b0213a0,e88d23f4,5919f0b0,a037f4ac,aad9de03,3f070c2a,f967fcb6,e251c17,69b62658), +S(ce486f16,39af644a,c70dfdff,6955db6d,ffd6f69f,1dc86c40,a318729d,e6823239,8c0fe4cd,debc1c38,37325664,f8cb0235,b6f32ba3,809dab3b,60c3119c,ded40b4e), +S(2cd69598,f476efc2,4b65aa98,27607a9d,3c643033,3cc78072,7e3047ea,a3a7244d,d287d0a3,6749cc57,bac0159f,1c4d738c,a965dadc,be36bf2d,f3f55372,6ecdbb3b), +S(f7d9e16d,c71c9b21,be93bc6c,b00888ab,974c7568,cc09479,16b09532,7c486850,6e561ec8,7e17d433,22163af,8253b659,15d04fd5,24a941c7,a186ab15,4be2d0a4), +S(e1f1b231,3a8bb5e5,e030d6e9,ec921515,6004a01e,f6d737ca,ae4ee585,80377a7c,bdb81500,9c94dad7,69b8744a,2d19cb59,8335ccaf,d840ddf,8817d4b9,735a8e3d), +S(677543bf,d07c8fce,d24cefd3,bf38bd0a,40079c68,1349bf24,c8fe25b7,26365fb4,3a7bd8d6,c442438e,3a1a53ff,d2a6b9d2,e0b3a565,de374417,189d0dc,888c02ff), +S(b8a18d49,b1d4593b,d103b5a7,dcbe4845,e0ad2644,41d1d60b,ad1e9252,1dcd773e,78ff6195,aaec6cd6,cbbbcb23,a81c6ac1,6bad7a54,7b0ca465,5e1db742,2a0c8edf), +S(b8f4e588,1f4155,b7a4fa26,1e34ac3a,3d776ff3,d5a69c44,6774ed8f,e57201a6,69dd7683,ab9bca83,a64ac013,ba62d2ce,1ac5866c,f9cb046d,84f69b34,168896cb), +S(4520c74e,5c39f18e,47d16c21,51f90013,395f2cdb,c59d7f2e,fa40be99,e843855e,ebc0a6df,bbe76c29,d1f32546,cf7038eb,ab3a5e2,bed16a31,acc587b4,41051093), +S(431f3a79,57636916,5d1e1b7d,dcc1be51,6138a26b,beb1a3e8,5c49f42e,fa6d9c88,6cf98a2b,1f747122,2f6835a2,116b8e94,8dfbe5de,72cd9e7e,7499493b,bc5e590c), +S(a03b812d,fd8291ba,ef0d00c2,25437a90,d8362fd,6c5f1b03,965cb3bb,ae9664a2,b3a8f60,a26d6adb,5e761692,a8cf3738,3dc30e79,6417e4a,23db565,487ed88), +S(2440160d,4b874cac,adf4e1a7,6eb079d9,810be0ee,2a8d6cf,5f9756e4,936608c2,c5823453,f331649e,45a228eb,4b524ea6,89047e70,31ce2894,61f119ae,a865ea7), +S(c62fc4bf,ec4f9113,1f5d3c0d,36807b15,35a52246,225b3959,4fdb8f3d,d8539bbc,a7257908,497a26c1,484c0d25,75052095,a1d71db9,ea5b61f5,e8c4257e,291129e2), +S(1de53f0b,82e708fb,369fbce6,72595b67,5ccc73a6,15797faf,333ad7a,7ab16b,ce3ad57a,99b253a5,ede23b7e,e39c7c8d,e5a1cbaa,8bba04cb,d11d1183,c226bdcc), +S(e7ff8510,10f96b2d,80fefc2e,cb1506,3e29d450,13dc39fa,524dfd38,4e1a5ad0,eb8ec381,58f629b4,79599ab6,346fe86,c1159368,161d275f,e55810d2,84d3d768), +S(e06c81cb,ff536295,a2c025f8,6bfde632,ef52d427,2c4d002d,dba88b4e,82570c1,590c13db,1df2b414,d392d8ed,d8b2a303,3d50460,4f1b921e,1099714,c6e2fd1f), +S(28a5c19e,1a67cc90,f5cb15f8,b969d5ca,503b20fb,e5a52dd1,4304c5ea,4ed6ef5,66b9f844,184c75ab,223c5cb1,8b4ceeaf,490969c9,8cddd8d1,122c6e87,6b2e590b), +S(a7bdb9a,631e67b6,9474ac3e,fffdb6d8,454df8c3,87589e1a,7aa6788c,ba47f72b,99d88a77,61bdfc23,271675fe,5dfb2e70,6a728eca,dc83286c,2f7d0d2d,b14ebb9e), +S(44d3cd82,87cdb65f,90f38467,ee478633,8ba82810,ba9ff195,c55b752,22d27fad,35b7a398,80755784,57b41ad,43bfba60,78d7ee48,7d6cb190,9070c80a,3e1dc4c8), +S(7c42f052,87446002,3b609b2,8ec61849,221a62ef,11e6e3c0,718c1c25,27a03bdd,c57bd1a,a31b2fd0,690e0551,6ff9e744,243e0bf1,91161aad,8e798b39,2484d707), +S(f3555643,f09b3164,6c415bbf,c2031605,eea9abdd,9b76d431,10e61c9c,4afcbda8,2b982eb2,a3cbef3c,d1af4315,178f7c9,236f6dd8,e4bf9ae4,7ee56039,ef9ae98e), +S(dd917a87,6382ee0d,10e22c1e,3bd48a26,4d74cbdd,ca1a062a,8c84cf76,1c59d390,2c958858,2cc386b8,42fc7041,7994e479,f3027693,9011c10c,9aa35f52,335545e3), +S(220dcd6e,447f847d,d0d08170,e9a6a817,38cc5c8a,9e911b0f,1dc4aa8f,946d0cd5,7bc7de64,70ff4484,db2696,4ff06c34,665382d6,91d25bda,95ed8bb7,18c0a558), +S(ea30144c,7ac98f2,90ee04b9,9f5fdbb6,e08cb88a,fc99d635,a3daec8,3393f191,a41b4d67,abe18ac4,79d87a90,63b7f0ca,e5adaca6,cc9471ab,b121cea0,427c620d), +S(32825a95,6bc7e979,b03437a4,efeae923,fba1d408,9ea77ea,9a1dd25a,66f63920,e34d81c,e28759c9,ba0c8b31,e57a0a9d,a45cedc4,9e57addb,b81a3c27,30b5882c), +S(78d197a1,975db98,d2014422,58784a7b,4aeacdc5,f72df33,9aea0a9f,8cec5ab1,1fbeaf4b,8c470387,f2d35e9c,36ada81c,7ec62d23,ec8bfa50,2af1868a,92f9def3), +S(e74f8d82,a67f687f,1ffaf4b7,268ac9d9,dbaf42e7,6c1bce34,9d473521,8a4d1d42,695440b7,a234caf9,1f72cf0f,255d4dae,398f4077,93f40211,bafe60db,bdb804aa), +S(de66c91e,9ddd0fc8,96fa32ed,ac4487bd,2a8fcd51,f4f14c3e,c0cf19f1,532ad5b7,3b1f48ed,30df76af,b0630c27,9914594c,58159b83,42c97763,498c8ba7,deb73aa5), +S(9cdc5f48,299b1090,e0902be6,6fffcf06,ae630650,e5cde3f6,9e719314,d75f2334,5ba9d4e,7dc788ec,ba0b53ac,3a68309f,21971371,e2db812e,566ee46,a61e7fe8), +S(50ce38e3,809cd6c6,601a095e,d5a63594,2cd40f15,f97cb332,fc19d70e,a1214e9a,b7ed76bf,a0e0687c,44b66bbc,ec0fbadc,94fa09de,5b1476d0,6207e256,dca2fd7e), +S(aadaad2b,a6d873e5,a77ed2d9,ce26cb0e,349c7b6f,6847636b,566f47bc,7ef52c69,233b40ba,b4082ff5,c7122143,a45656f5,2989b62e,391bce37,d7aa245b,6c84efe), +S(7b219f5f,8f045219,5959621d,6c161a70,b4ef7a57,cbe7c9f4,fd539af5,71b8e0f2,8efedce8,dff914cd,e050209d,3bb91af8,c8d781ef,a87729a7,c5a6fb6f,8183ab6e), +S(31dda168,6e3ee50e,4e39f01a,68797bc4,7763ff27,5fa4489e,386d9902,c6c328ed,688d2e05,64b66581,cc5b1234,20a6c331,d33019c3,84a63c8a,a6f14be8,5d392201), +S(ea514512,aecfb0f3,94e59d7f,d9d558a8,cf535464,4f2f0963,2e2c6364,b1d57b5f,aa2ed069,dfd3144b,c9aa00d9,5037b099,9c35ba17,d6ee79cf,3e9aa5e9,f5dcca2), +S(bb2f9ac4,107288f5,66be0b4b,7b294e61,ec868a7e,4bb26a04,e4f473c6,9bc8e40a,6fb56eae,bd923ddd,c5028472,aaad2e0d,b0c80465,2e59c87e,45246502,606a0f74), +S(b9401bb,bcaaeab4,9ac42f6e,d36891f1,bddbe0a2,81ec4cf9,8d5f306a,ee9a5,ea40ae75,812da94,9bfcfeef,d22fa5d7,654eef70,34d3393d,6959a59c,2312dfcc), +S(dbf74d05,475cca1b,218bd219,8b24eace,99e0c4ac,56fffe3e,6f8f782f,8f338437,95f6b97c,eed1b3e7,b8de7f15,55f7ac5f,28649660,a458df0b,1806512f,f10dd82b), +S(cbc07e16,64041096,9e78dcb6,585abe6,9ee2dcd3,3febb64c,1f5b8bc9,419023bf,513e2160,56a3dd13,516092bc,fe6a5f4b,3c2b2843,a55ab69f,12f8387e,840a1772), +S(14504eff,814dfaa2,78704245,f0b11c4b,99f0c104,1d103e8f,a221a4f2,d3354164,a61998da,9bbce03b,e1bd153c,c33e85e6,cd2c7b18,a2ff9f6a,4cdba579,593471d4), +S(5b6d95ad,e3defd6,742e2e16,f4ca48e7,118e2ca2,cce878bf,f8b3f2df,fdf4895c,841ad4cf,b538795c,32000893,e0306415,b15edb8f,d83772b1,4de4f2d1,ecb180bd), +S(de084c,e1cf681a,f081212d,7e08f5df,89ec249a,fa419bf3,189339c,8a962f09,7790872e,2b35ded2,78f496a2,8e6c4907,8867c0b7,fd0910b,900c68f4,c11831da), +S(ed4e253f,3e7e781e,86290b2e,56eed44a,47b6f73e,74282d0,b7b54f7c,d75a97de,94a21c29,5850d088,d6cb20e1,9a2a3975,b27db744,4f19d257,cb3c1bef,1a329cb3), +S(3e8f32ec,ea23ba55,cb6d0fd1,41aa2225,9531ec35,bd7f3ec2,7291b798,431e2ee8,1875388b,5a9d4571,66179379,4e7c5046,ebd10c34,9f5df4f1,ed50c11d,952bef32), +S(4d2afcdf,bcdfe440,eb211566,efa59e4b,38385f69,5e7e2063,4c3b4606,32e5a23c,4694e00c,6b55863d,693d68b7,678791b9,f09df4b6,98df84bc,69940429,cbe10a39), +S(84fec62,e92704e6,1013bba3,4dff3876,5e4221ec,f72ae24a,1e80a814,632a5505,b74a1f4,9b9283f9,d6d01827,8bad2cc6,73cad8b1,99a1dc83,bc0ec561,78a2539e), +S(8114debc,44e517e1,1d900358,d0b831a1,38275cb3,371ac707,c4334544,bf076dd3,3bb2baf8,a42a57ce,d6e1942d,8324c795,cb05b978,dad8d20e,6eadf721,9f2b2d74), +S(fcec2f7d,20af0406,370f4aef,b2bd168,592d6a21,d5963127,3f3b836e,d1d881ef,b59d480c,b37372ce,d5ff46f0,5f1700,ea5dc847,1ecd2983,42599bcf,eb696ff0), +S(c000ee62,5a6ae49a,b0226f97,dbef0469,bd02e7fa,a8e3d4e2,b509a6ec,cef15876,b13e0e83,dc9c8f89,6c82ee3d,6cbfa8bb,4beea7af,5210a6ef,1d331180,83946dea), +S(142a5689,bc43523e,6f0c2922,78b7c68b,c588ca37,aa934997,63438dac,f5662669,cfdfe57f,2b80c32,f90af575,195dc71b,b7890d94,c27385f5,1451429e,41de8119), +S(3935bcce,35fe92b8,a2722b4c,5252f5,e6252b49,2ed2b8c4,759fea06,211bae0d,23a96df2,80a4006e,9674b0d0,e44ff5a2,f7073656,3539de18,a87529c0,4640a769), +S(46c985ec,74815b72,97d7052,35990967,1257337e,efb0ed46,93a06124,6bc5d717,952cc49d,f7f79ad7,8c279195,dd24fad9,ad75413a,5ab78869,f1c686ca,52dfe9e3), +S(2770cd58,25287db7,b352380b,b894ca9b,a8ee672,5153b7ea,1f28b254,566d1e27,c29b9df,d3028c3d,b7859d8,30de1490,e1f8abc9,c95994be,13696587,8ffe9b99), +S(8be87133,6feaa5a2,c5c3ce6,8d58159d,75c54e90,12922dd3,da4b534,31bc8153,efeeea2d,440e6127,bc12331,61a18497,68a280c7,6858bcb7,3a5980b6,baa4dd39), +S(675af413,e5bcd4e5,1c522a85,9dc1f3bb,14356298,62117c2f,90107af5,496fb8ae,54678238,ae95415,219b860e,985acd37,9d501ce3,c68b208d,2756cd64,6b357578), +S(5696c5c9,6f8f3b03,f1b3aba3,af85f160,67c309a5,bf4fb8cc,586a1f40,cc4e58a5,f675529f,73ed6987,ba2b1bf5,d202554d,8de9143e,809582f1,4ecfffb8,6a0cf850), +S(2e0f5a9f,5406695a,ba5bac9c,69865f34,ee2cfe1f,5662c055,8d88b422,76d5cbbd,7bb0e1ba,ea55cc81,29b074a1,3380f9be,c67af07a,e91ac96d,c0a46b92,6148fc4a), +S(def49b1a,84ce9199,bfeae925,7a96c403,5dacab0c,80e58a7b,a69609f8,7d3a5214,54c75dcd,2294d953,cd990cb2,a2840c11,813fa97,19178421,18f9774e,de4aefc2), +S(d33f0bbe,51af9602,83b64d36,fa6f8042,fead9d96,138769ed,25b55fe0,6e4b0013,8a9b41d8,32fb7aae,dfe94380,cf2fd2c7,c0e7592f,e3a8c32f,b1cd4aa7,6112227f), +S(6ad93b61,5b5da7dd,8145ea46,7a99fbf8,57529d5f,f25d1aa8,f935163d,4b2911ae,1fc64130,7e4228fc,2354227e,60b67305,9415c19f,d2a084f9,e9caa39b,d2b5cefa), +S(2c886c1c,ba67d840,6e33ef48,6c3e63a7,c3d9610a,67033bc4,f19c0840,784a98aa,79fe3de0,7363b7af,7d3a41ff,5d3aec6f,ef80426f,be455e12,526120f,5b884823), +S(10e59c98,b357ee38,3c306e3b,9c1be538,420881d3,2de1462b,aaace4f9,d84c252e,450e954a,92655710,c3e6279a,94fcb52f,c9aac9f9,2dccb95d,97109030,49cc71b6), +S(32725d0a,dfad10fc,c95db4b0,4ba65569,e88ec325,9cdbf02,5194c69a,3a18722f,d87902ed,f0f1ce28,3bbb3fe8,113f6bb8,9976348c,965094e8,1e24c28c,911d8533), +S(b066a5a6,da035350,33888fdb,87e28292,4ae805fa,45b462da,82ba0622,e6fce040,5337766c,2ef3fe37,42571ab2,286246d5,95ba7087,d3c38332,6490feea,1863a5d2), +S(6ddc1ecc,e8c7cb21,a681be75,a2143ffd,2663b75d,9ede8a15,d0b5189d,8c52f63e,c4da0af6,8eadeae3,ed9b5b61,a73bad5d,1ae8c080,2777441f,cb15910,153284fc), +S(c82cdab,1659a9b8,2ba0414c,bffaea32,eec1b41e,615bb47c,786abfbd,43698d7c,91e026f6,781ecd32,ab59bc5e,2ec3061e,5f6af1fe,bb6e627f,167cbdd7,afca63e7), +S(d932562b,6cfb8034,ea75e656,502ed81d,2b5b80a0,ae85aee1,29f677ce,aa5a282d,ad101b8f,97aadb58,d0b3d8d9,1cd24950,de0a8baf,646e9d9f,734f0f97,5043edad), +S(ec3f50bb,efa0b462,66993e4,233e5e11,f4bf4d56,19aad9c6,37638bfe,d8e45916,d63f29d,3f7b0b6d,b8514712,2343f51a,ff1cf956,e5f49bcb,3a9ea5bd,639dc2a1), +S(b5ff4795,4d6fe3a0,22303189,6eab5c14,bcb6dd3f,497ca561,1e3c9af9,b7e9cd79,16605e0a,5a862ccd,b9349159,13da9d4d,dd537edd,817a0e24,d0d59101,61105b18), +S(b1f153eb,697dde61,36beb382,da8702dd,a51e61c0,963c6d45,338982ef,dee9dc7a,fa1ba411,1823398e,23462cfe,339924d6,b6eec980,729159ef,20f8c8d9,f8143645), +S(42206dfb,8dc8eaac,d0f04c0a,da3a2cd,38c60bc4,6d1fd148,8fe12c04,f15904f4,c44393e6,2969b4b7,ac388f07,8b997de6,d4e08893,dd17699d,9a1cc885,84f3c5dc), +S(56cb266e,152ea2f6,1db917f8,c9b592e,3ddb2643,341da585,c4291d80,d7bfdc62,f7e9f332,8e963d0f,a3d149e9,c4c590d,e835747a,b75df64a,41d919b4,4fb18ba3), +S(5e1d6097,991e9fb5,b099e173,d263199c,cc3e626f,b512e6cd,cece57a4,888e6f9c,a151698a,aebc1dd2,93e29cc6,bad03cc3,2a6785ae,61da1f71,d50240d4,825962af), +S(4acabf0a,8cfa489f,34a622db,9e22536f,2da926e6,97d72756,eff9dd84,72d7b207,5bb50941,836bfafc,7e3f693c,28818a30,825a2b7f,39282d7c,87fc543a,5981d96d), +S(1a9bd6cb,59008470,48b638e5,576d24d2,175afb0e,fdf4c499,fb4aa143,328cd058,36fc0b8f,6605f00a,9822ba7e,c97fffc5,9214a479,eb6c361e,dad89e13,7d23b896), +S(649da46c,ccf59f43,e04c1456,9db1da2b,7506bf36,fd5a1aee,6505d8a2,bb812f5a,251efafe,6319ae16,7d69c617,46e2fb8b,edf77fba,b0ba1fda,1ac30ebd,21c65ac3), +S(66e9a7b6,5682def8,a7a7db04,781614d1,3e176461,b833771b,6001dcb0,f87d316f,ae3d2f9b,442bad03,e27a8d42,fbaf2f9c,294c82dd,fd5b892a,b5aa2a54,df3f9375), +S(d2f13641,6c42c603,82cbb4e0,108a937a,cfbdfbb2,d3195d69,ae3ec647,50fd2e25,e8de2060,b52a7ed8,b1bacdfc,de026f95,a9027727,4a6fc948,76dacfa5,5db7cb35), +S(2737e1e1,5af922ee,fec76921,7064ef52,fe555f93,b01ce4ac,e03d6103,93742abd,f9e08b6c,dba1824,d1cb2efb,d9c5bc22,5a71193d,5626ffbe,9f8bdd1b,48aefbaa), +S(e7a21d74,2203c820,e7da2fac,333c1797,a90b69cf,9b909dce,7b71c052,5c690576,b9888022,82323a5f,8c327eff,d4d10836,23e53b2b,7e0d0c20,cbb48978,f2326034), +S(16acf8f9,854c5d89,5f761823,9a557dd9,320fc976,d2df1012,502437e4,7778efb2,1dd09906,c2c229ca,28e49088,dafc49bb,5033eedb,4cde30d3,8881a2b1,e3368411), +S(74462c7a,64d0ee15,cfc48ab7,874a5f91,c4788e0b,dca9560c,eee55fcc,c2ace309,c9468199,6e11ccc7,ae58428b,310a2057,9f8d686b,a15c2ed0,7f999027,5766eea4), +S(77e35da8,705a03cf,ad891f9a,a2c2e56e,c0c5b88a,38f9ec3f,8dae4c68,cea94ae2,7cde0915,9188be27,54c4a653,ae576321,5a8c442e,6931c5ae,f4657d68,3e30eb61), +S(314c833,d308857e,cc5f6268,406463e7,e2d91a5a,f536647,2382ba41,70c403b2,3ae0facd,f3d955d4,dd4b61e7,ca1f2e7d,92656772,2c08274d,cc98d60c,4ee0bea4), +S(36466998,e5449878,7b27b47b,b8dd54b,617e9132,d6252fb0,1f760e7b,dd242979,7fc61d6d,deefb379,9fa87cf1,aa05da7a,84f750c,e7a37b9f,e30bc4a,4b350915), +S(427338f3,644f6efd,e43b1069,b34517bf,af02bbe0,7638766,76c4cfff,65a01bfd,5d9113ee,13c7917e,ea760105,9476aee6,572f2322,5fcb9ecc,ce4a9cf5,bedefdc3), +S(73afaa20,a2fe0855,c35f1025,aa78f181,fd57928,b3e63d23,8b125432,79327923,d82ab0fa,1f9f08ae,551ed521,b6687a50,b4b4b530,4d5128de,172c77d4,72acf933), +S(dc9ee41b,d5ba5686,319ff6d7,62f1af02,4619b15b,c6dce9c7,3c5392f9,62ecf255,bd5653dd,11485718,68521a7f,68bdbc7a,5f58f46,3e81aad,ed200261,6e95cd33), +S(c32592c1,4a401b52,867fb0f3,6de768ec,11cf13ac,d2eeb1c0,31cc83e0,a500cc21,d9e5f61e,b052b496,b8b59217,75d47cb9,d774c89c,76d76d33,e932c50f,ff156324), +S(356db8da,9f3fe561,a9d21d23,5264fbce,bfc08242,e304e4a2,1b4dd044,7c4288cf,ca4cf6be,9c91b8f6,2d66b101,79246c20,6b99d5e,eec50a42,88d1b7b1,3bb00e3), +S(3ec546f0,fb367683,c4d07c50,c58468df,1a36ba4d,887bd57b,f574cc8f,575f321c,ecd4a716,1c65ccd5,e767df14,53aca971,16376c5,861dbb30,33258bed,fad26f50), +S(b2fa7570,216d4194,64306918,f80d6727,4dde9aee,7b801988,3e6807d0,78722255,919188ee,a4c77dfb,a460af47,72547de3,bf591a96,fae85fa1,696a3d1,dad8dd8f), +S(593ecbac,a3f6e76a,bf97d83c,719922f8,3e17a2e3,a054eb40,e6cbf867,c4fc5d49,7d23ffa1,c168f083,3765170c,7ab2f66a,3d4f8c84,1b9f18fd,f3e92918,51421656), +S(646075c4,181fadd7,937d0b14,75450f09,3f91e170,9644ff32,a71176ab,4b973839,5196abc7,e219433,bbc998d7,57b34f78,93fd3aab,c3be5c3d,20b352b8,5a6c157a), +S(6518d32,d20f4490,a605e95f,2fe826e1,1f4d6295,21cee6b1,d4d505d0,50416849,38bb02b2,2d415ca2,3c95ab41,ee54c4e9,f383e5c2,1dba2dae,a2a24a81,599708ef), +S(9c67d572,bbaa2341,9f704542,95a6160f,39b42ccf,eb46d56c,7781f3f5,69eb155,3fcad5b4,953f933e,3a7ec832,e799794b,38c99476,e85a6a8d,58a20c35,b9777602), +S(3976b774,1e135f5f,2ea4a874,11f9138a,ab02aba9,b4c54a5,9ca2683e,262e09b2,fcd77da9,dd3ddca6,6993d5cf,f997be4b,147eacc1,2bd18c4,a1f18525,fc5fd5a0), +S(508b5272,6918dcea,c92e43c7,b697f2b4,9cbd9d23,1057d116,2d34058,e08b06dd,79d3e174,2bdabd3a,1faf65ba,82477bbb,3631f08b,ab87dfe3,1fc76f2a,a4fa8ec3), +S(bd5c99bf,44d5202f,3b1855df,7dfd11d8,71d7cee4,cfe38e6b,243591cc,ee69cc81,4b15cf0d,cfa1764e,365568b0,630423c0,2f81a041,2c2aec76,7c70d441,bf35a6fd), +S(2011b669,509f7a9b,6987692f,f1ee2a86,1bc8a6c1,f1b2d252,4cf4052b,129e6683,902dfb06,4304a94b,9ae930cb,b2d28c3b,835d3852,93b170ac,b0a8fee7,4ad64a9a), +S(24f22f32,25e5fd67,6ff10f6b,c9e7a829,322329c5,d716af48,ad95a32f,289cce7a,3c39cfac,e2a2eff6,1f034f4f,394ddcf3,31efd98e,3247b3e2,a60c462f,4846c4f7), +S(a845991a,70b6c165,f465ec35,fa698977,ebd6a3de,490f7ec,6a3d82ff,72a8dc76,b8b71cbc,84975cf6,2000b12a,ad56029d,b58e828,f1e37578,73231c52,f03bd158), +S(f75a1682,f24cd7c3,f654f9c8,38bf93b5,f5519a2a,39f7226d,3635f4eb,1e496577,be008fbd,d42449f6,8b571d29,48cda471,ee3a28a9,df4ed840,756d1840,4f917cd), +S(d438d864,6173e175,9962a565,5dfc0545,3e7edf89,22f79aac,78806b51,697cee7d,bf0149a1,33476cf,b6ad8062,94a937d8,6a929ad9,f19a5929,fe648798,6e931ac3), +S(42deb8a4,38b7d9cf,2216533a,22047aa8,3666c4dc,188c1517,b506c42d,add6a9c2,a2d98969,5875a67e,18deaf94,3a73d1cc,798fb025,46949078,ef2063e5,63362ba1), +S(abc5db92,a7ec7944,f4a7c07d,edf53272,2c62e77f,30852f7c,47b34df8,41b1567c,d4917a0,b967ab9e,b05355d3,601e106c,c93d7094,e8e2d452,5731350b,11ee3c2e), +S(203a579a,3298edee,6e5b8f,be8c3a53,825f798f,447fb5e6,c3d0a68b,69dc2600,6bad56e2,c4403cd0,423211fc,38810f40,31696852,af4eb6ae,939fce9a,a2253660), +S(f69ee455,42cc8bd1,490ae8a9,efae8a94,5c5efbc,ba078b11,c79c73,492278f8,2f1ba10c,e93b9f58,a19baf63,46706a9c,78b70faf,dd55d998,c394a8d8,713654c6), +S(838a8e3e,88527ba5,57c80ec,e8818ac5,5cd73ac4,aae26883,bd4b8048,f4fafb29,661859d,6d99d8e8,17bbf643,73726d45,1379744f,4bc93c7f,b228370e,b4d369ae), +S(99d1e947,767fef9f,71ebef00,91d2b7a1,f23481c1,fa3f7d3,4883a18e,59f6f846,673dec94,4b3d82b,358cab99,2a434932,91bad282,e0c9c41e,6dcc4f7d,5737f696), +S(390abce4,4a25d121,301d79a3,dd273897,29145890,c82c712d,760429d2,c7fedf32,e2e868b1,6bb5c3b0,f6305c4d,aa00a536,5e2aac02,71649fc8,b3e309d4,281db193), +S(4e5e2983,59d53274,a2c5ea8e,ae4d9659,bf7b9919,454dfd3d,a86a3705,272e2004,db0b88e9,a3d30e62,696ceac8,1028dbba,144157f8,4073e422,24026681,a7184339), +S(5bc3dcc2,1e1ecbfc,6a14e36e,ed26527b,6f44b03f,c16f146f,23c2d1c4,535c315,d16a5275,99e9b315,6235d74e,957daf90,1ec9f9c7,de9eb7a3,ef6f8138,1b5b29a), +S(8ba374d2,f56e7da7,c6a7b17e,a4234abe,9f6da593,77b13a5a,3f1089d4,cab2f7fa,1e0479fd,8410af5f,3b0bfa63,612146cd,735cc6d3,3e72f982,2b18419c,939d9f5d), +S(6c8747af,cfdedb6a,a45b90c,bad3b269,6bf15c16,202e36dc,5b0488cd,cf954983,75e49114,df83874e,f9ad28d8,3f3bef59,256503e8,f8ae22bb,f7f18f00,94b3b119), +S(3892cbdd,7fb925b2,18e6bca,9c58426c,9a96eb2a,a5f3db54,fb861d0c,323049e5,817622b8,96e224c9,84d265ee,bfd2a996,f6444413,992fd2fa,de91ea39,aec39e4b), +S(8f001a25,19acf72c,f9b3e528,7d060816,3f84b4b4,16d377f,9b70b417,859fb58c,b3c34e61,685378c6,b757b0fc,a961763b,af2e35f7,810ee236,f1d0d7df,92000cf4), +S(4a8ab909,fed31731,50f16b44,785ecba0,af5ceed6,83e1a2b1,6be2a91d,643fa00a,ac88cd4e,26a8754f,d33646af,faff3f74,f04480d6,b988e24c,a5f6a979,25325b5d), +S(49002f29,145514e,f9f81133,284752d6,ca973ef9,daaec307,6f279b3a,6ca9d1a7,3a73249b,318fcad0,65233591,2a07d90,39d1c05d,cd40865b,eb0d3fec,a2bc7c67), +S(1ad5bdc0,2ef4ff42,6d0d079b,3d680e5e,65b0431c,b664eda1,9baec880,6604db88,cb55d682,1e63786a,e496f903,d8b4db91,c22e48e,893347d8,3110ed32,34869d92), +S(316f40f,be3c495b,9256456,1daf8f94,3bc7533f,56d09351,4052be97,fc3f8c1d,eeff684a,8a37200e,ac0f16a6,90c1b69b,c52ef929,8bb1868a,2e9554b5,cd218461), +S(e8408480,72d6ba93,3fec095a,6320008,f28a073d,73625de5,a4fc0f7a,c242f55b,6ba42703,5ac578f0,6ab1e6f3,2b760bf8,b91f89c2,d37faa1d,86fbfda3,e0cf8871), +S(b3c81c6e,d24d910e,a9fded30,a61e2706,829f9e82,87a84755,bad14bf1,36eff3f2,57077559,8581b2e9,254a9c35,5aa6e25c,fe7ff2b2,7c1e0175,38161f6d,6e3da4e1), +S(9b0cc368,c402b063,669e96fa,17dd0c17,bfa19114,966319f5,7b5ffa0f,5c0635fe,c5ecb380,a239b714,99cc147d,8087b453,b01d131c,d49f07e4,60278983,e975614d), +S(bfddfb26,ac59c5f7,f6d9693f,c5498e49,cb1c2b46,452f926e,b120c79d,f49c52b1,8cc30f2c,4bb7897a,1bf13f71,b5618ffb,18adec2b,5710c0f8,d7e915c9,abc918cf), +S(989861b4,ac8b6cbf,56d8442c,d753c833,1830ebb6,369ce4c8,95343abd,2e887fc6,f7a269e9,3ff86bf4,23265f28,d4a392ed,1c8e1383,5792d43,cf4de508,3dbec068), +S(96a6e19d,336af93b,71093fe0,a63836f0,4286b43d,4abba61f,66aaa28b,1732b09,66df4497,c453f01,6425ec93,c6858ae5,300f3757,eabd41cb,da6a05ae,90f8f41e), +S(cc2561c5,1261c57c,8ca2318c,5c5d095e,7de2294d,5776aa74,9870631,34eba9dd,a11a6b85,a79efa99,e72e14e5,c3348d3c,d27af941,305ca3c3,1c48a0d8,ee247cd), +S(9f0b93b7,8666076c,c4f75d50,c67b6e44,96d23b30,b48154f4,f0b11307,fffa174d,256dd20a,f8c0fe19,8ca0cf98,befeb0ce,ca81fcb4,7fc0822c,76bc809c,13eb549d), +S(a7e5f4ce,d6eb2995,a0c1fc5,5a644b16,2ba6ea53,20c7abac,dc36e6c5,15cbd06c,ba65401a,3e1b856,53d98ce2,3596842,287cf1c5,fd249ace,8dedb067,8553e1b3), +S(c4949322,cadf34d,bd82a36e,331145b5,42fb3109,44dca7b0,e0beb9be,8131bf52,912f12e6,5f3fccf0,34e14147,556598a8,550fddbc,9c7f9844,637dfaa6,4d6dbf2d), +S(68040ac4,351a1f3d,ec88abbe,bae3072f,bcfeb944,94ec6610,4793ae21,a8285212,9d5f59cb,316f3a53,3f7eac34,ffa386d1,c555d3a9,49eedf36,b7276e32,e7ac416e), +S(f77daad7,5893592f,978438fe,578e5124,2f98d202,ad07f6f4,1dd4a238,8e3878af,d0f7fa3a,adee3b5b,27f95fb1,4d4e157d,b524c6f9,15c3f5b,7d57fb36,e82dc91e), +S(371fd993,87312364,852234ca,6dcc7d2a,cd58f4b0,c73903f,ba08a0e6,2a81540a,365b2f9b,b4938fae,a9065bf8,5cd88a40,4ee3a651,a8b226fc,e760161e,734fa5e), +S(eab4b429,32320270,ad6e3b6a,5784067b,6439d0fc,d5f0c0ea,579ae702,9d615d29,541f762c,6d825cc,66544ced,5965b077,943e270,ec7a7e20,b1401923,12aabdce), +S(5d8d97a9,fc50bd4a,fd326a61,5492f596,e10a52dd,6dc836d,44128fee,a43f0371,1acaca55,f82d78f9,cb28bc7c,cd9c2409,20066526,3fcb4a3a,f375e44,59c68e10), +S(d37ec7ae,89fd69e1,b9c64095,d5986a7e,b90f6f6a,9daa2638,6138a42d,357c9cc0,ddd875f9,6cf1e99d,fb4478b0,817899cf,1b6cb89f,87fdeb09,c72c539b,9c850e84), +S(7db9b694,ed838749,d320effc,2ed0f86f,1fb0f7dc,e2ce09e0,a5024bb0,d039c6a0,4e74039b,b6018328,bd89a2b3,284ccb70,6d464ead,e9562946,5374744d,222dafcd), +S(b02fdeff,df11614,63c01a8c,1a2c6def,41c5e64a,656e1daf,f8b73443,af060020,39666b4c,14e7c169,3ab2aea8,993f7dff,814df0e6,73c38448,caf88486,ab0307b0), +S(c89a4af,f4141ec4,5a586aa7,53a2937c,e6ad3122,45256466,31336c3e,f401cf2f,b4b2066c,f0c9b0d2,d1cc0ca1,5dac6578,dc7cf9c1,4077dbe6,1a92263c,141e50bd), +S(fd4a625,69fb8443,fe70739,f7c6f9,3794d7ab,5d25c0c2,c099b390,ba733601,741308ef,8600fe30,b912c49e,6b2cbc24,4b84bf30,52e690e7,2f478bd2,12b647d4), +S(f5322b3f,786e45ac,6655c11b,ccda223e,d4689bbf,e5fc6253,e248be82,c0c2ca6a,69f2c31c,96afab78,86220dad,fb9a0c74,c3eb5463,93142221,50369064,1081bf22), +S(f8daf170,7075b29,bdc36d65,a5ed4256,b21cee78,8dc4776a,e3a3c40a,19a2014,7b7fecc9,c302068f,80e73041,5eb31c25,4a38da9b,a72725df,898d4226,ad6585a0), +S(6317fe9b,cdb3eb9e,b7379d82,54253a26,786febff,88b5549c,d4f4614d,40c174a6,8c52a679,a471672,d9e46d44,d69167a1,b962ccc5,38e1a42e,2bf5c731,f94f43a1), +S(5446a1f5,5a7e226d,f1dd2c49,8d49e2cf,19ff8f0a,34c6bc3b,66fc19b,ec036064,826f2d2c,1c347caf,57c90c16,582ebf72,1d02a4ad,52b78254,2f97d10c,d9238e3d), +S(4973367f,ba057d1,9fcda3b0,37d2e672,cc3cb6c3,f2ffd427,c99822c3,b42154dd,8e9b4d0d,9008ef0b,c82764f7,3cc7cac4,331b88b6,740b0590,30327699,82bb0364), +S(3bac5c37,462fc0a6,11d3d47f,b4857256,f4180689,adb7c16f,885841c9,f56694a7,486dec34,2d7525e2,6766d0b7,fa0442ef,3defbb9c,41e4e6d6,5f458191,c5cb79c2), +S(1f0d6603,c942f882,cc8c8f34,98bf9fb2,eefba019,9d95943a,2a209964,bf585b99,869162ab,b05b77d7,337ef0a6,2ff485eb,af6d8182,1e96078c,611ea8c8,338c26dd), +S(2011eaf5,4d8d9b95,787ac7c7,9d8d733a,9846ef9d,ef227091,2f0d3177,599b7f60,d66ecd62,711364c6,c98c95ec,57dca58b,2f972e63,1a759133,c6cb206c,285d12c4), +S(b016df8e,4c7671d3,44e6e84a,64ac5a0d,af2535f3,b614b132,7c9b2daf,724b2dfd,823ba8f2,ba237731,aead8dac,68f0843d,fed9c5ab,8393de12,b0615d5a,908d6d9f), +S(bb9c3029,384c85b7,d9af0869,b5f039be,4a6e792d,1e863357,e1e95ba5,fab61bbf,79fa55bb,47b97456,f0d4d754,5c6a57c4,5824e868,7eae06fd,a07f227e,b49cf76c), +S(e7cb468e,271042bb,3197a88c,bd4a4b53,5581c5bf,455e0ae0,f3f35a90,8311ec41,f0e67e9b,10717789,628cd4da,8eac012d,c7c58083,3ccb18ae,d39bdf1f,b61d0dbc), +S(738b7b48,6ec3d4f2,4fb699e0,a6a9f947,1418eca2,5688da1c,722be81a,78ce60b3,d76aa53c,4129e5ba,88881647,a9e3320a,1751339a,3c10a8c0,b879bd32,e87f104c), +S(31413f55,d4e5c14a,e091c228,74e971a6,1658b881,7dc983df,4ac98264,4b455e82,c86d2a0f,467f93af,b8ef127f,9c818700,cf54f240,e16dd738,c4e90899,d8a5af35), +S(7ddae61,d231a764,794dd836,1779522c,2be61c66,e79f8a28,79914093,8a6e9e39,86aaced5,6ab82f10,5bbffa0c,e73781fe,5494c6b4,35309de1,441077cd,93d7a57b), +S(fd5a44c3,ee4cc565,d2115a3c,16aed5fa,7b005fcd,fff3e537,3d90f226,398c9a04,1dd95003,722e3a31,991dfdd0,495160ff,ea55aab0,7109d060,d414229,c8f5be83), +S(c3a768a3,fd24ac30,4cbbaba3,7cc52ab8,82e3256,b7d54d14,9628ca4a,a8687f43,2a0d6f89,9df7dff5,eacea751,a825ddbe,ecacdc69,5c071093,ad79583a,32de93c), +S(ccca92e,d2ad3249,c5dc5881,8540e2e1,c89c6ac3,9a98401b,f719f008,e8fa5a3d,5fe2b717,302699d,fb7dba86,c368f67d,6a6f3593,d3845906,3621f73e,28dbd1fa), +S(9e5fbca1,7c3a766c,eda0755e,84bc0f9c,1017335d,1ce0f70d,b8b09de1,568ef319,9f8e25d2,8a01b693,864dac0f,ac82453e,41305f50,3c5dae08,42ec41c1,5e7af238), +S(43908294,409a955,9d02f8b5,4084b120,bb980c59,9c9003c6,4ba2760e,c69118ff,343d27f9,5120670b,ff8dc482,66646eea,6ea37813,3ec1fb06,ff5d9756,64327e38), +S(30e3052f,3f97372f,56d505fc,6081ce75,662169a4,a4743cb8,de4e3288,32cf9c3a,d144aa9b,9cc60ab8,436afaee,a6e6b64a,bc0178af,b05c3db6,42c91254,8ecece83), +S(b5b28b37,6e2d4586,c4c3a7c1,d701b28b,50da01ad,c18b91f7,a45daabd,134a1d69,ca0eb341,26746304,bccfae1a,4200420c,41af0558,596123a5,c7edbe9d,3fe04fb4), +S(4eb1aab2,b71aec48,84d626d1,8ee1d90f,77feff11,cf3fb8c8,32ee501e,48c4ae8,1247cb08,580b0c96,ae5e72fc,f7066ca6,e46c5b3e,3b8091ec,8ae5bb30,e5a7cabd), +S(b814e42b,abd14fe6,55cc4641,22d024d3,7cfa9f64,ab59cada,fcbcfc56,f1fa9201,ed8db1d6,2621bf32,23fb81ff,922a0e10,b4ab5cf3,3370aef3,df70ae19,6383b06d), +S(e5ef7b0e,270a0c4a,3f4df516,b516a19a,cb45648a,424a4967,39b9b75e,ac4bc497,7cd38616,dce6fc2f,fbdac49b,59afde1f,397546e4,1fdd2c7d,b8e9efb2,6b1300ea), +S(e0228a88,c62229bb,4fd0d563,5a66ef1b,e499265c,9163d09a,40170969,81f3c2f7,63ec23be,6c858aa,8390d038,665664b0,f085bbd3,d3fd6982,b2150d8,6695e0d5), +S(3abf7af5,f504422e,686aaa6d,86f519a4,ec6d8ad,b1c7db9e,75091545,5885459e,95110201,2b8c0149,dffc0cfa,b1510529,9bfd537c,43c2a1e7,613c4007,7a8be9a7), +S(16c5a86a,57dbdc0d,84320d49,610b637,437d8a27,5bc108a1,702bb27,dfc04e1a,f5387f3a,7596aff2,2a9ead9e,fd87da3c,68bf5efe,b277899c,7ef19394,cc698cb), +S(8350a35,c1fc83f0,3c306984,799d6baa,3a41bed8,45cb2126,ad8025a5,6f1da1ea,3abd0a5c,83976b4d,79f150af,f47a684f,931090d5,61a61a50,a4ebfa7f,d74aa002), +S(58199602,d1ba3202,bffd7311,8679e8ec,7d5dc6f7,f937eb4f,be70b8b,4379bce9,290dd5db,a4091af5,50975e3f,1f0d42e5,d375a26a,5c6768cf,7eade4c0,ed315166), +S(492c0e3c,8442495d,52d4d356,91d03e3d,133d56fa,7371d64e,ccb384af,907fc5da,c7bbfe15,342b1d6,c48cfe7a,595bbab3,d7c4674f,ad9f92f0,30e2d602,4cd10ed8), +S(adc96fa5,f21e4e6,5c5951d6,53379f3a,b2d92ded,ac038d70,ff1e644e,7c7d4de8,750faf48,16e45f4c,697a610c,11dc363d,4846564e,afef6e7a,335d5d,2af0e171), +S(9567b748,4584b4ae,21e6a12f,cc8b5185,e2137c1f,5f30deac,eadd6b55,ecb64964,b9a445c9,3c4d8a7,fb0b4469,45976ee2,cd47ea88,ca3269e,b559e689,84b1a130), +S(e700f079,11611a38,b0ce3273,b420135e,17ec189d,d1574695,d3452530,c8a59f99,e6685c21,6ed61c08,444b51ce,86681796,8814c1af,aa712a32,15e6619c,85bb0bc0), +S(c412823e,31b1f066,9d067de0,d2e2ed09,bda7b53b,6482d8bd,7f352a4e,74e4cabc,8809a001,3f12ebaa,3b01df9d,355c199d,854574fa,374a85fd,6d066377,6957e9e7), +S(50675ee9,1d350fc1,61e189e7,a4cf4955,d987c194,1b01ce9e,1473add2,ede4cde8,2f67926e,7c4baed0,e0a25df1,468c79e6,b07f8bd1,9d460a24,4233f988,45547047), +S(34f8f31e,7a6d98d9,73eb395b,3368b0d3,c566cb2,c2a8379d,bec31c1c,859dbca2,db990a81,fe7a234a,e63b751f,369ef489,aa6929d8,97a3587e,483d19da,dd1b40e2), +S(6bca946d,e15dbd77,9bed6b31,25986a06,50051c2,db72ebe4,81ed24b1,f9cb4d5b,ba942bdf,73219596,9fb8357a,4bbbdc33,c08f1c17,da37e409,50077c6,da41456), +S(3972511a,f367daf8,192f2725,8597c14f,e151bb46,5b8c195e,610a11d6,e51451ae,36f1e442,82786dd2,8f05981d,292c2241,9844deed,5bed41ef,fb0aa2c1,d798541e), +S(756e5104,3011d1c,e992ce99,76c09063,6560e9e3,a85de433,6d9218aa,11796c34,4d714894,96279d96,7ed41034,77fb1c87,db269661,8c452dd,ca0fda9b,e8c31951), +S(e5508c1a,b9e90d6a,237e631e,507bdbdd,ed3672a8,38ee0f7c,72eb4587,b4231e4,24fcc0fd,f5079407,e3c66b02,9e2f37f3,bec5ba72,25487101,b7e68b08,731572e0), +S(d90085d8,d80452b5,cb99dafc,8fa4aa3e,819c6ab9,a407beab,4bc6446,b5225596,e3cbc413,bf74b383,d2f8e92a,9d6062bf,a579fe37,e171734a,e50ac682,da75710c), +S(46470f31,77b6ecd5,34add036,8cf9724e,398963e8,573d3d01,ce3f9d5e,b14f50cf,1a670f11,15b60d70,ac4c2b27,8f7a684a,73446d52,e3c2a8ef,7a84a06,8512f6e), +S(4e92916a,a3787bda,7cc677cd,6f7d26cd,4a6847cb,23d1e3d,beb32de0,51fb89f9,6bdd060e,739e3122,a48e7657,e03ebf35,bc43f4e,3ad864cd,49242d29,fd3537a4), +S(78fec768,fbf2658f,78f21a83,5f9e327a,67d4101b,5ca9fcf0,e69e7421,d69a3045,5de2a6ca,25adc6e6,82333b72,f30557e3,f2f003b8,1dc817e4,be0ea20f,acdb9f59), +S(36327d81,a5a94289,105df5d5,7ed407e8,f14a741e,998f1017,3592811e,f052a126,3325ff53,33c1395,d2548216,4eb153e8,ed94a950,8376cdee,941e3417,f2f0ea46), +S(2e3d6f12,18373ec6,6435d58,92b54576,545668bf,80fe51ed,eee5ca7b,7a5f8806,6f2afbd6,6465fce8,308eb046,1041a23e,f4515687,64f8148d,a377e329,4b6dbce8), +S(96dfe31a,87620ab,647e0c2e,6e9bad96,4ac4ecce,28d299e7,e80f25af,da5885c8,9a1d9194,3507b674,fea7b185,21a2b70d,ac27b4ea,b370b9b3,a0c2ad0c,2bc37628), +S(298711da,2e303ebe,2cc5928f,e437ce90,ba675b2b,b896ee44,920fe3cb,e34ec55,dbe55194,8671be1a,1af18584,5db9fdd4,c4a586e1,98a350e4,c1326d04,5aa3c593), +S(cd603c3e,326a7c25,575b07cb,d86e0a9,d764675a,b3013622,12ffdf5,708ed855,f0d100ce,2690b76d,62858759,8638c992,4736b18,8beb66d1,328ff5b2,4a1fe52b), +S(5a90312c,30a58754,cfc6d248,669d029a,7da84243,9de2b1dc,7731a460,b05b6e21,fc0af827,5890da91,ac2032ef,e82b418a,2ca1c37c,4a19ed0b,8cee0ffe,7386fb37), +S(61ce7b79,1d46fea8,8f4dfb34,474577ad,8ecb02a,ab23153e,c0ece543,5c472e3a,4c5bebe3,2b82502c,8c68ecee,57f29fd,ee7f45dd,fe5bd985,2418c809,6ebabede), +S(df3ffe23,d13b2b4f,4090daf5,a51f343d,17123083,edc4172c,368ca75a,8bfbb16b,9a21d41,39e53dc,836868cf,9c1d0eef,d4660455,7ffbd379,cb7a118e,36273f2), +S(24470f10,b0e5171c,aeaab136,2ea9c1f2,3ff3a4d9,66a1b7c0,5110b734,43a363db,ce557547,69df589b,bd4438b0,14d4f4d,bfb56977,43656c25,83981c78,5803d5a7), +S(67b07bd3,c96164c4,da09d5f0,be038a2e,74ade7dc,cda4e7aa,28699156,36708765,e0183e53,445a2936,a44df51e,c6d42bbf,21369b65,134accf,c0a6ca68,9adc03e), +S(7e3c57f1,43f1157d,f06eb86c,e7a3d625,df513d2c,1187b1ef,2b4a8778,cb9b1192,81aa590e,90de3ee5,3b68d336,c6c77dcd,925742d5,642baf50,f41e6258,ebbdd5b2), +S(784310f1,462cd93a,dae83002,7904934a,2a6682b5,6124c5da,ac037d87,61dab615,5365ac1c,d2f3bffb,f8454ba6,6743cb70,a08781b8,ce95efef,b2b7d60b,fbb7e2e1), +S(ac75ac17,87006c3,e687effb,5822615f,c5608cf6,3ce43ea9,affc8d,e4a9167c,d75aedc7,42240a0a,79f79c91,93c9aee2,9bba3238,a5ac9154,d98d9664,27faa81), +S(943e4dd2,ae1d3f5e,ba7448e8,15d44c3f,ed1b2333,46c6b1b4,b6ff8386,980c6fd3,d08dfc2d,29ebf8d,30fbcd9,e93e4d70,d42e6526,bc2e7842,ce3cebc1,f8105b58), +S(4f750c16,909060e1,f7509604,9030e65,1e6a768e,a3601d3d,f2f0eef8,e18df94,e434f91a,cd77e31b,c9adb0ca,87860de7,6360c0b6,88accd44,715a114c,aac8eb7b), +S(1a609a28,76eb1228,58678cd4,57c3b762,9f0208a3,ba653603,3f887a4f,7df50ee3,99dd674f,864e8662,3ae00cbd,2a484dde,29e9de3d,7ec83f92,ba60f93e,bf316b31), +S(d2fbcb43,5c932861,2d3fcbce,f84ae490,3003b61f,c7927cb6,d7134196,f8858c76,55b6ca82,280880c8,3d66ea27,e8e24ca7,670bee29,1c4fdc11,56bf661c,2f2e0eaa), +S(5c6e8973,c1c98cf6,71d5cef,4acc76b3,b4c5165d,ce162d04,543d4fc5,3d97cf62,9a3271f2,d829451c,8f32652e,c43b717e,a6008478,637b32c6,66a9a40e,2f157c2), +S(be670a91,1930e634,a65aa675,56e342d9,15037a49,845d46d8,ac14a8b7,6024d8ab,4b4418a5,6583d2b5,6a58e324,a7b57eb7,b5111cbf,8c6a39a0,5b22d86e,b51e2dd0), +S(afb47c08,42e4ec13,13fcc64d,98fe73b7,d6bc3a97,c2ac8823,45a82507,e3842e3a,3b448b26,f1e586bc,9425fb77,37a70de7,f559c1fc,97c9fce9,5da20bd3,945648a2), +S(6de4f9b8,29fb7313,d27bc525,c5116408,d03f653d,56244f0b,bce94fc5,2de49039,653e08a0,26d7c2be,dd67b32d,5d031255,5c5e9c5d,b7aa632,c59f971a,85ea0458), +S(91cb27e0,1e60b6b3,6bb7df48,2dd4542e,d36951d8,53971a85,127f414d,67ef279b,5db95774,f7b60f6,70ac3c7a,41bfce24,6aa8816e,4545040,df4bca6a,7173829e), +S(a3e3386e,86c6d952,ad929b79,6cbcc967,2677138f,b051b3c0,53e2b4bd,2d6b7d0a,e7364d0c,b404b835,4f65c0f9,68ae823a,be5c6cdb,a02a72dc,b5ecf7d9,64eca22d), +S(fbf251e5,6b61ed54,467aa548,cf4a4667,258f0334,f6064625,b00d546b,c61f8e10,1a1c0c11,14634786,e9101685,15c0ea29,bf2b2537,529912de,13ef3fbf,3b789722), +S(e0bfa77c,21555000,4b38957e,a287519c,c222b0ef,81f71d76,9c3608aa,7ca6e7a8,fd778438,2ed98141,1254767,d770866,84c3eb94,1fd4a506,81cb05d,311cad5f), +S(6d612d53,3d7cd076,d1494641,af14db85,7db44e5a,c22ff57a,13c198cd,b2cb50dd,62cee347,915640f6,73a23081,f5999fbd,5fccabe9,b84a0409,ee85160c,93fc6dca), +S(393c515b,5d1f771a,e6134c4,c06cda2f,27b01b66,c3976ca6,9879de82,146e0dd5,147e097,83f65b3f,f5e29f6a,12df5fcb,2ae22d9,857f9653,67efc9cf,6210ec7b), +S(bb340fb,c45c7b6,8d3b1863,9ab961d3,b455a803,c7ad6807,62077c08,6fe10bdf,cb210b7b,bd7edac4,fafecb0a,82efa8bc,3b6fbf63,711d24d,2b0969cb,f39ffe44), +S(139ad93,4a0d12a2,83c50f54,99d5cbff,fa746252,6856a5bd,98bb59a,42f6512e,1c2582c6,b1da1d1c,4c8e85a1,77bc212c,ac448eac,564f0ea2,a23f721d,4c153ede), +S(b49f8e1d,ca33f0fc,5713a853,bfdc8e16,edee6fe8,eed7e310,ae0e6d73,e4483c12,2d2d0750,bf422c6,e49b12c,407bb05d,203a44e9,92e0fe5d,af596676,7552bbaf), +S(78099937,bdd416a4,8c9480d6,82a9741d,d57c89f6,a4ab2b8a,8890937e,b3f16713,b3981d6a,8b4f3045,e3d20e74,264b3d78,48b0f9ea,f8d0ebb0,2bc4a2a6,7da3a93c), +S(64cd225e,a4604ff8,b61a8c71,c3f71d7a,62423add,5c851e89,b2430cf,f6300ee4,89f2cb3f,560f0a1,c5e26497,149ffc59,cf4ea956,f20f039e,f2578092,5c2b4a5e), +S(70cd9c8b,7250da54,cc7ec051,43f087ec,c1642e69,b5b74d95,e728a0e2,27f6415c,57ac1d32,dbb0e87d,9a8ea661,87c4bf6f,bb4aa780,18f7611f,c94419e1,6829af3b), +S(a20709e7,d075779e,baa742d7,1e224373,dc7f9692,f56fa9a0,e8d81847,28e23c5c,3f269cb3,28b57b3f,48db2e3d,aebea0fc,c1d456d5,a366052d,2dec91d3,5405a53c), +S(fc3957cf,c85c590d,f2d6e797,c0aeffcd,452ed47b,57213830,20b3f3b1,56149203,65ef1279,884a1a2,bf632178,e23fd9ee,3128a268,bd75b70b,bc03a177,22daae7), +S(e21c288,805a1fbe,8c0df51a,c5360c8f,69c0c10,624aa044,c071ad18,8dca17d4,9fd946d9,8cb67d2f,200fd03f,c3f4fd77,2ee3c24d,6bdc0d89,55e314c4,8151944a), +S(3f6b8f7a,d68d5d6c,fec93aca,7c9716e5,9bbeeedc,dcf2dfc5,713046d1,1617e06f,97112f31,f5e31334,e258e311,bcee3160,3c75f8e,4a67f039,50dfb30,8eff1605), +S(c630444d,7d6a8d6,f396b431,cbad44fa,88f034f0,aef8f6a,ec8e4921,a3373204,2d459073,ecfba3c0,f538dcbf,65a54822,b8d615ef,ced3a394,6d31821a,921cff7e), +S(1b2bab7f,4e833c7e,432d81db,d7b34e2a,e62c3c43,ad1ba0b2,f3cd3d38,88d96f55,e2caec88,ec4d6660,81cd2bd4,fcad109c,fbdce4d2,c0a24aca,d665fb56,e4e143d6), +S(b6a433b3,1f1a70a3,e53775,e5d173f,3d890bb5,b7ceeb9,a62369e2,94705711,95d10503,8959c755,95d8d76,c30861bb,acbda484,9a448481,6f4931cd,34e59d1), +S(b12a9bd6,4b0f0cdf,9568e3bd,a6b7fc7,40f66c00,398ef73f,74dc968a,cce34b7e,ce8dbd0a,9ec6059d,b17f37a0,dd12b6df,6d809b9,47702dbb,a0e30f31,6b10a6f8), +S(f16e345c,70a20726,616ab118,a5a5f252,b0e14377,79208dc3,194ec16,7e8f1922,62657132,12d111cf,bbe9af4b,be8071d4,55eae6a6,d3c5e153,4efda17f,5cd66f42), +S(b4b85e71,f1ee5898,4c660f17,e48ea158,73963356,b8adcfaf,5257459b,77d02399,baf95723,70486c9,567d6258,ee4b403d,70966cbf,4ca6e0dd,b5f8772,1e053f45), +S(b43dc473,1f85b542,4a8252d0,ef1e5681,720405fc,ae4e6406,7d721eca,552d4128,5f9ae2eb,f5f08f78,12181d44,6111ea2c,ab5c66ed,1cebb8c4,2c1e4a50,f3653d), +S(3e657382,cbcbe472,cd8f7e2f,6ed72623,9fc1fde3,15633d5,b3219e70,cda875a7,ad430305,8aeb7ff8,9be1b737,260e1e7a,5d6e8a08,3ad7f5b2,2912b9d4,10ba267e), +S(c30ed331,8f2a76bc,3bf292c9,fd98ba86,3039ec2a,b3acf028,174da3c6,dee3e3dc,54b642f9,3c5ca6fe,987cd9c5,4726d4c8,f59f464c,b847c319,df74ce4e,7da24376), +S(8ca8ad3,7ac218da,1f2c33bf,73a681f0,1c3fc0a9,35bd7540,fbc3f2bf,82e0763,e48ac338,eef9096c,e3d0e679,249c9183,4d0cb3bc,b45fa70e,7aa8356c,8fd3fd53), +S(a75b601a,aeb33b04,d3e201ea,bedbc5d3,35f516f6,3c34fe6d,e7d58a00,a6bcf3c7,b1b814e0,b143a048,75a4c5de,14a74d3a,ddcae6b,b220a806,1a980b18,4a3b49e6), +S(e542c034,9fbd716,d92f0aa3,ab2c7be7,4e81d38,39bbf04c,38f9d933,33e2447d,93f4ddd2,af3134a0,89c3ccf9,34f61ae2,67530a42,12cdbd4,7641f7b4,c21e732b), +S(460de699,4c3b21da,6cb661b2,3cea142f,cee1b50d,efaa3d72,3d55d54c,60bf9258,93de277,b9acd4a6,89bb02e2,b284cf78,4731e219,540c7131,e2636ae4,4183ba80), +S(e5df9251,7e1611d8,5218f013,4f4bb212,9a0a2bb3,b65b2678,45c83bcd,60f29d05,758dda47,b25e31fb,56a8c18c,f91773b2,6bd26548,6925fc0f,a5e34787,a881f731), +S(7bf153ea,7a8cfc9d,e7558c8d,5354f7c6,f8b41e14,7ba7a8ef,4296289c,f134e6a,94367f87,3ea37ec,cf3e1be0,6600f27e,5a4c32ac,1fc4959d,f5f9a6d5,c4e161), +S(c9e8e330,8a57d46d,65a3ca70,86a0440b,1bc37ac8,8dae6d46,66c4497c,5867688c,c7f12a8,d727c5be,5d2dd18e,1a996ca6,b5477b78,a2b671a9,6fd6a391,95ca831e), +S(dc45e141,d9f18643,db12b41e,facbb17d,6d30da7c,65ceed2f,c481df55,1b6fa25c,52d23e99,46eb60d7,acd8cd47,ce592359,9216c796,320c6657,cb4e411f,e175f104), +S(f4b4ec85,6b55bb4a,aceee0f0,56cff661,eec827c8,8a452911,8bff2ace,3c0b4a81,18d14680,57ad90c7,161f7667,b512f34c,fce3bb84,c135c474,d67c4afe,49b589c2)}, +{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), +S(ad51f3f2,e91d632,a13569d9,2e0bbb82,f566e7df,cc8d5541,54dffddc,2724c05b,1039c9fc,c61bb90f,7050e8ab,deecf700,80509a64,8fd2520f,9789501b,315da78b), +S(2459de87,8ed4337c,fb77d945,4f6d2e15,7153048b,1ff76121,f5ea4fd5,cc77dec3,296ddfe4,ef31a5c9,65300ccd,6bdcf369,20e7b2c6,c1368f08,6e416a48,3d517fc6), +S(959743b4,de6c9311,b95949e3,5f20f06d,6cbdf08,ad40b2a0,5239cb2d,4fe99ef6,1726fe6f,2e6815db,96242e97,ef5dc384,b8cd9ff6,67ae475e,a5417100,bc882cf7), +S(fa08226c,62476f0b,88392127,219b071,6316d6e7,c21b3a44,4a07a2a0,cfad3bf7,f24e916,75b2860e,e6e6416f,d9e6b119,ee65e6dd,c27f02e4,3524509b,bf9beaee), +S(da3f52f6,1102d1e9,3c213935,736e4cdf,72ad32a5,32db4f2c,3e388eac,e403b3ee,93c3a997,4d4c2f61,9338054c,15f681af,d8da7b13,cd89607e,dd5491e1,9d695416), +S(893806c6,fc32e583,997b5859,870df579,dd750d08,49dce8a8,2cf47cb9,a92ded25,959c9301,c7982c96,4e4bd09b,abf38f44,bbb54529,82404e22,7b862e48,adfd6276), +S(5cf0831e,319d8690,ee7f690c,c0b15734,9152c12c,acbd82b5,49c8eecd,b4f17043,2cf5c316,25fed805,97bed5db,4cdd3680,f97d389e,c83a5fc2,1766bd9a,6f95b607), +S(7c0f67a2,ed9c4e10,7e06248d,51c79f70,7e62b409,afa37f0,2bac0b80,f2b04417,748bacd4,2401ffd,e374d639,86414233,c4b7eadd,5449bebb,9dab7248,c5dca538), +S(1c2380e3,d084e808,751c4e06,d0d815ba,a333c94c,ba5f6de6,379dcc86,79f4cf6a,2d6480f4,d237bc92,d05e761b,4818051f,afecec25,9afe2cc,cd032537,f3b21e8a), +S(411596,bca0efd6,f1262542,cddbbf3c,a90852af,80689683,47f9c0b8,919b0696,6774a5ed,2c06a3e5,d369fc8b,1c1ef075,bcd96b15,8f724e57,38ebf92d,7eb6a983), +S(862e0b2c,19500fd8,8d00f2cb,14af4628,bdcefc88,ae87a663,c9e901ba,c2cfc537,6fd77f08,124c45c7,44ec81b,e420401c,399ee4ca,aa8779af,9f4a9b9b,5bfb3c66), +S(fa787fe0,faa2a7fb,8dd1ec29,f81171c4,82e893bc,2aedf4fd,4a762bc6,dfc26752,428f4df5,8e057e0e,491fc4a,82cae796,1cad059c,9ef367ea,a15a4a24,42d91241), +S(e15885a0,2af497df,34b4c324,d22c88dd,a3e34da2,74de0b12,c2c9ce12,d566d33c,3ec3b7c9,209357e6,1f360789,a37b4c78,910d2518,3d367ce,5af7075a,842a1e08), +S(9c7f6bd2,8261d396,97365037,b57f2767,91ae02d3,4de1c089,646423e1,404fb32d,844efbb3,e720a3dc,a5431147,8d0aba48,221d48ce,8a05a385,9505f4a,458f7fb7), +S(b99277ec,fc7ced54,58300c7,783d1d43,67d40dfe,48cc1743,e99540,b46eed6e,91832791,f0aab15d,a293a4e,c107bf69,64895eae,ef0b7b4a,4db1de1c,f8f7bb97), +S(ea5c5c32,6b221ebd,47bf8838,91a0ab8a,abcbc30e,982a5add,5f7517bd,58f68927,9258ed81,2f732f1a,43aa6b76,f9982d24,8be669e9,42cc5f92,90925d07,b96c651f), +S(c8e45dd0,37f1538a,ddfb79e3,5eaf2d1,f5c43535,50857741,481b8bc3,b00270c4,46183384,f3460d3,702632c9,bc340b42,2baeabeb,624d2aa8,1275ced,e2d04df4), +S(2785615e,b34e2395,5fef2170,18ce8e9b,8520ff6c,7f0b0654,40e2e44a,99b633aa,5f4d2fe3,8f56db89,5052ccad,b7e2229,5295ce9c,9028f37f,709cc9ca,6b86368c), +S(bdba87f2,7b750cab,87e4f36b,f2a4ca30,49c5af49,d11d9562,fd67ee3,5215c2aa,507a9b83,dd4a40a2,3aa5970,673f89e4,3dc6c387,28b3db8a,78ee2c9b,40a2b99f), +S(bb358e33,a07a280b,b87b703,6df7d832,6e531a38,c1ff6f48,5c955057,e97a2524,d62efa5a,435d192d,c40c39a7,2c654e34,a6d8837e,b33a602a,1097f1ed,40f1dabb), +S(bc59cb40,190d6454,c356e22a,af552e02,a6f7f671,8e56ab94,10ed6e51,539ce74e,3a3b07b7,2404e40c,96c561f3,ce227241,e7035c13,29c7e566,8cb92126,c6543af2), +S(19654121,d2e13ac4,dc087c0c,373c8e98,e4447c5f,83c976ef,2358cac0,d7b726aa,9832eba,58a67ec7,4d993935,b2451ff,3118c1f8,bf4f2d98,5ac9b2b4,dc4347d9), +S(2f222e27,6c7059bd,88d87b7,a7268fce,c7250741,1cbf52ac,7ac1ef04,dcfdc769,5d7695a4,37686bc4,df42d1a7,43a7c025,820fde6a,1fbdf17e,846115b0,3e64ddc2), +S(9a34f22d,628e0863,52860024,7b4e3b76,60d2c88e,e663a6ad,57f673c8,238a7e6a,86c1a12,29bb251,c6e87b37,d135cd90,e2a7d01a,4a067f67,6d8895f7,57085b46), +S(e526e57e,73b17b34,8288e79e,4f26f864,95beed8b,f9476dbb,26cda51e,b4cec5d7,5b7d63de,97200b0e,e76b2bf4,82e01ed0,19324e63,16e5142a,8058128b,6409e8e9), +S(7a28a623,cedd623f,37b33b39,149858f6,ff7adb4f,f06b1661,3dd23da9,2b68626c,41144248,b2f62a79,e9019071,aacbf63b,b8ba1238,a6738d90,ac6429d2,d7a485b0), +S(cd3a96eb,8c378c46,de954c9d,8252dbaf,1db12f7a,88a55190,87d046cf,58df5665,9649b78b,22c76b71,919b8a2c,7a0d6a4a,5be2f0be,4f1b8a2b,ca2e898,15dcda74), +S(44201d8c,23ae0de7,6e9ca9ed,e0a052e4,753a4a12,87129b55,f33ab4ba,5bf095e4,730f8bf5,53e528e1,ab26d7df,a5767a04,b3fd8653,7769cd0b,8d1b5f49,bd95692b), +S(1d5fd8ff,14da9436,118e41a2,55df6bc,52a69e6a,755d7e70,a48ffd3d,ebc4c88c,a53b538,a3c553fb,4bec6c1d,259fc11c,4259126f,12a61f5e,1c4bdfb0,de34b167), +S(9f96c868,f95bbd10,486cf72c,a1bd1cb5,e45768a5,8a5142d1,61e03b78,8f1c92f5,7a9f8938,fd39796b,6eec3f74,a970b183,dea912cd,cce14843,86ba0ae5,e6b2e785), +S(671e2f85,60f16300,f60173e,18ff716a,9028b22e,8937c118,c21fbf11,f54b1e15,58310025,7287d122,2a866a6d,8e85a041,72531a92,7d727e8d,77c33049,32f50d22), +S(59215ba3,afb0aca9,1f61f7de,d69ac95c,3b0a6ab3,cc5fd312,2d23b287,7d645805,433b9b65,197f8360,d222580d,832c2cea,dedbc92,610b8c0,4e0ed5b9,45b52583), +S(ce3be955,ebf0a088,57bc0859,55898466,8b428982,ef1061ca,a564c48,9fa8b57b,81ce7ad6,224e95e4,d7449cd7,41628408,48249b,d2e5d0b6,6757cb73,7622def3), +S(5f6145e8,1cb8ca27,a9d1fd53,9058f5f1,cc423d07,a23f79e3,d1256541,689cfd5a,f129799e,6a9044a4,784ced66,40285789,c8b71aa2,2fb9a2e2,92a73f0,b7686ee2), +S(ae14d7e5,ce5ff7cf,a419effa,9272aef2,7e0ad99f,1b440679,9d362033,2640672e,5f8670c,cdc2b366,90d07259,9fb1e560,5e71e079,2bf6a2a0,928a8438,1c42beac), +S(61837dd8,7d096602,62119a7,f102eaf9,d01edcd,8c6a9335,488b5c80,535573d0,dbd49194,1eeecad9,3bb5688d,6bff2bd9,fb4573ce,b21dfa1,2766de1e,1b63c8c2), +S(3ef98234,eb70107a,f69be2f6,b3f935f5,f1bec759,2b66262,f048c8a0,8252ee83,451acc9e,7c4c21,346e9ee3,dcfe4a77,d35bf00b,d0f2e3c5,42591441,c90b5354), +S(b1e94abb,912be054,1c38bd4a,a954ccba,f92b41d0,82a74ca8,59ccbc21,755d00be,e8d76ab,ec5aa0f2,49b33481,ac6abb04,700edc61,da8627a1,26812abb,ae5f67e7), +S(a0cdddf5,ac430d5b,f5fd1755,6025d4ed,4f9a0471,83749ea6,232a8061,f27672fe,3c50bac3,f0c01cc9,5c10cc51,b14ef6d9,fed1a7dd,b6d07721,947cb606,8ac81cc0), +S(c0650540,c32945b0,8e42c487,50f2dcde,8c35dadd,2069dbc4,28c8a318,48c0b841,660e38c9,eeb11cb3,aa2b61ef,d7ab4796,85161be4,f4b1547,e701fdd1,bb3dfaef), +S(fc2efae0,77ef8607,286aa5b2,5b114f1,fdd82e6,ef425b23,5170fdec,5d95ffc1,f96a8710,7fa5aa8f,6fc0cce,9885840f,737e1b12,4d6d35ff,e1dccab2,4a863901), +S(d420dc89,758a24be,dabeda8a,27651138,2eacc153,3395db23,71ca98a1,8fd72f57,83f34a52,7245d018,d2d599c1,299845b4,42a06b9,c93142f4,74935632,9052fae), +S(af32c241,a6c86715,471e3ba1,4bcfb60d,c9c33ae8,84ec4403,97b35281,b36ee336,9fe0c80a,1962f8e5,5c2060f2,eb24a7db,1187037c,662cf832,18e0381f,4f92083b), +S(cc44e6b3,c7d4dd22,b4e24310,ba7fd59b,efcb05d7,1411781c,979aea2f,635c62ab,cb05b4de,c8ce6dfa,2f229629,48edb6e4,ec0f2a8,aa53932f,94cda08f,b81e3da3), +S(a7d3a168,b175a11b,ca46067e,c603ccbc,1d7cf852,edefe1ba,ae633a38,318bd97d,361fb00f,5344bc31,450732cf,30b8d728,2aa100c8,4c52b160,9b0dd3f7,66405a2e), +S(41ce228f,e6911ef6,5b93a0d,39d4c4ab,1b4f9ea8,9f34f190,56b6edc4,90834b65,85f7677b,61323fdd,7c0b21d8,572c7029,4118fab8,d432d330,dbaa24df,bf506964), +S(a3532f8b,1137f907,19baa4ae,b0f6f909,412eea8d,290385dc,9c0465e8,a3f9f900,94848f20,d1f41d8a,c433f01c,74a0f120,15f2423,23780597,6c6ddf2b,a369186c), +S(d51d0609,2a9316b1,495c380f,78cf6b0f,53f11fe3,b89399ab,6120d494,b18ec5c7,8efa991d,4a35009e,1b0f7adf,72207c6e,a1ac67a1,6fc009cf,fb25f63d,7706efb4), +S(2155010e,7820453a,4e18b616,6439995c,35e9f1fe,bd4b8c98,31c2f062,ad5db9c3,d951af7,792f7575,a0209ed7,3558efc,8858aaf3,a7dbdd05,1701538c,e0abd925), +S(b02e9c81,6370cd9c,a78da82d,927e1d43,ff27a07b,a8a3e773,a66fa344,331d1d1e,e184e2ed,276eaa1b,40cd9696,a98c41e8,7eb2f0f7,fa3039ad,9a18bfab,48141331), +S(d79e98f7,724ff7c7,13510c81,a00a6056,b769dc28,25ddb5b6,6e21540f,a0b9df8,dae7bca1,8896e67c,9f8855d8,4b2dc1f3,97e47230,d4915e99,33897687,c1e7ab0f), +S(1754242e,1719e21e,5dc63a64,5759d3aa,5003d20b,db8a2ca4,a5375e78,308c4423,7373ae8c,97c5def2,fa602af3,3491f50,b26a986d,b1255f63,9b3e1f26,3ad0d856), +S(a7b70ad8,4807a34c,45adf85d,93afb7a9,30ad1b1d,25d58847,c278957,bd96d64e,9cc8d7ca,d66f00c3,5e0c9476,ceb4f915,76cbf1d,2ff34b80,aa913e5,758bccc7), +S(a4e7077a,8be0e97,d322f62f,74fb5112,c885975b,4e5d106d,1df93a05,10382a76,52580b99,2959cfac,bb27800c,37e0605,7a26bd85,c97154d7,c51b5b01,f0496749), +S(14371fca,1e37adf9,3593be37,2e634fd2,69d004ea,50d2f412,77e0b74c,d82491a6,5130d626,4d570bf0,a9a1511,af29105,eb1937db,fae1f027,45a2e725,bd63589c), +S(3a23c190,995df13b,12556cd,90c4c05d,5bfd4154,8016d31d,85ea4506,356ca3bc,b32f623f,a95922c1,9579f532,9fe6d0df,b3b3c63a,adf1f56e,30b946d0,e6be0352), +S(643cf33a,9530502a,65e26491,b895ea3a,27be865a,231dc0cf,b42249b8,b8eade6d,58321730,ca9a20df,ea6be90c,a7f056b1,ec3da1d1,e2befd74,5a39a46e,24257f04), +S(35fba1a3,f33025ca,96401513,b443d042,c5036ca4,3221b0a4,ef5fe943,34c1a27f,5f5a4c87,a7499afc,4de8a475,8651e50b,d97c292,f5c4fb16,6114e871,d0d651aa), +S(fc62b528,b601895f,93e27224,843b4d29,9d542c5,2235430d,c3e85c1c,4a0685a8,c5ed07b5,4b4f18e9,26be84fa,9d1653a2,716c8e8d,3a0343d2,e6b78e92,53a411c7), +S(2b15210f,b126f37c,6bc76ddb,db6d24b9,dc39d531,8527a917,ed1553cc,524ea86c,deb7b72b,256402c4,24ae46e0,f2e4e09c,12471358,3b73f41,79fa737b,3f53facb), +S(1e011ea,5ad8f791,e430b18b,d302d3ab,b229f715,a68f3d49,c1c2f3b6,285fb369,b9dd2a2a,25937c98,6905428e,73d811c0,8e1d5729,bd6bfd8b,50eb91e8,4ebfb1a4), +S(9bbdefcf,cb0c9e8d,747180aa,6aa72af,917fbd5e,ee2e6dfc,f05bd301,56496e4,6824df9b,a8ce39dc,e7da66d1,a430be26,9faaa54,a83f5441,2d5ac6d5,761bc83b), +S(691a5651,e5773488,24a36cd3,755c20dd,289a17a5,953608d9,905976c5,4136d4d9,c03caa0c,a1bc376,b736d2b8,812966f,6f1b955c,1e68a8b1,a12120ba,ec4f12ab), +S(f68ec286,730a42b0,4ef5c596,b0235e5b,50eea2a3,94ae6f9f,a91086da,47acb9e2,5ef0b31e,86dd166b,f447b7f7,2b82ceb9,668f2a90,88a190a1,6bd5a230,8699a54f), +S(33685765,121d623,9f73b969,efe2ccb8,ad715377,c7f110d1,579fbcca,5b005ccf,cf71270c,c3c8d129,8d6f060a,f6cb343b,b7c807e6,580779bd,1df6d7b2,e90d80ac), +S(18c1347a,cd1a2eeb,7f42bb9c,de08e166,63676348,fdd4c533,d3f51064,b940dc16,a9ccae7b,d22c73ef,eca3a4dc,a56c3cbf,eb3f8177,d9e5cae4,48568a5a,2d83a31f), +S(9235cbd2,37fd6ddd,d596bab0,e2cd4d29,98a28d5c,b3b738cd,6f79fa76,83570357,60bb571,7ee5c69d,7ed19477,94b8d2aa,7901b993,89496993,1e3480f6,89d37742), +S(8d6f63e6,8b7e79c7,1d62bb8e,8e1f3ec,8c5dfe93,21f5ff57,c930ca6,f9d255e0,a1eeab9e,f6bc9a38,45836630,4a1021d,ab2d4f66,4c5cc6d2,c50be827,7fe61915), +S(e34a6e35,8163ec00,f6abbeb5,14b5453,9c7ea2c,8afac9b6,81402ea8,de5947f0,375f0fc0,882bd435,1f294812,b0fdcf5b,8f36b772,5bd93994,343d1bab,a3db8b33), +S(7c92a80e,483c9c33,bb18163c,7b4e7710,96e77f5,c182e4ff,95e8737c,9294b2b5,f9775ba5,6779dec8,dd5448ca,ba1bf760,5c531e2b,f71ffe22,2b8c2b60,93cbe3fa), +S(15d91f0f,49153ad9,3fa9bd53,71f98b4d,84d0bc8c,13310859,547a510b,94ed08fa,c0b61781,ce3b4f30,89e99387,e084827e,b148be8a,cfaf6a8f,1251a5a8,ada84194), +S(68f00c8d,4741c078,f99595c8,230bf510,bcb84a12,9149ba8a,5b495d0b,d3307226,49004e85,f9eb6650,83b1ed05,12199ba4,2da74f30,a70898cb,2ed05253,fc5a809f), +S(c2cf12ad,851d4a49,56a2f861,2cde0fb7,caf83f2c,41af4d98,b74f039f,b2a95bc8,f4643722,186a375b,be0e17af,9832042d,62132982,ef33a626,b6a02f84,f086b59f), +S(8d378751,b5f13626,2fb3eae8,5491a3a0,b3af4b01,f759f06d,4b418116,c3ba30a1,5a47d6f8,878671da,104fb6ab,7101efa1,718414cf,2017221e,8cb171bc,a13d4d), +S(cd4e82f,2592b5af,1cdbb44b,3dbcd3ac,76d0ad92,fca50789,f1152722,1eb4f3ae,734884e2,6d207cff,a145ffda,2f3304ca,3697958b,b1f5ad2c,9cc2c812,99128107), +S(b9983c8b,61629cea,2f44717b,3139b3c8,ad1dbbac,24f8ffc1,db9078b,92e8f8b8,1e0b83c4,349dbfd7,16dcc892,115e93af,2cc1176b,7d386686,dfa7a2c9,a56810a8), +S(1d2d687b,ddc2f510,f0a721c7,4ff6d8c0,ac157929,189dcdd6,2c508577,aabbb982,4c3427ad,4dde568d,5ed5555d,5de4cdc7,fcb6b071,afd342ea,7fb3966a,872d2d5c), +S(9073d8ee,47e31106,718dcc5d,e0e46e0c,bdc8e822,66bc8fb5,b23bcf80,ccf240a3,6a2a92f7,bbefae74,1472e3e5,6702ab5d,a6d20993,1cd7daa9,1a3d985f,5aea46c3), +S(25d31f95,1416d832,59f433aa,89e4df66,49d18a11,1395d676,b44759ee,46931139,40aa1c2,9a4ea4da,d24a915a,7d476769,3a1881f0,d70499ac,f4f78f89,91cf3b8a), +S(d04504f8,9b93075f,822de8d2,27dd8617,f6ae2fe8,10ac8fbf,97c7d788,bd459cab,7c4d4ae6,56d118b2,17abb932,d6283480,5be6a4ab,cb98ceac,8a85085,8f0e2d92), +S(a4afa77,7e76e1d1,64901460,bf63e3ad,c84fa1e5,7ee4cc17,d8a083e4,2e587f1f,f56ac642,f7bc019c,61dea3ea,6891c962,71147228,33d8055c,954b45fb,934325e2), +S(59eb6b42,7e586eee,677ce715,c06ffd16,35ecc418,caf8b707,5e2c9192,f838e4c,cf25adbe,5d0d1c37,1ab4778d,ddb1333e,6b02b377,8c73302a,43262b5a,312e8415), +S(6fbde8a2,a9495849,c0e94866,e3cc7b7d,891738a8,7bfa388a,cda84358,6190ba65,e988c40e,b2cfd713,597290f1,7c37d165,df711c9a,f2ce6989,52204cd7,4b8cce9c), +S(186a8e0a,c9a61bc1,ffd397a7,62f153c4,fd14c2d,78a03e03,8fe826f5,eb5d16b9,d1ccfb7e,fdfa1486,8d35048e,99050caf,73bb0236,ffd33bd3,bcb431c1,868e5e53), +S(3224499b,b9712ed6,b1dc5157,6ceb2d77,356dde1a,263c370d,9a71582f,c4e93ed0,5364c748,54f5e7c4,950f5aeb,d3a56626,7da78898,e3a37af7,a2c5a528,23cdfdd8), +S(b2de,174a7592,ce9b287f,82bb4f60,3a4aa039,4bb308f3,4d282a0f,8e8a1105,a9fa1bcf,424a0d14,5e86c4ed,be0d5a31,dd85772,cecd7fdc,ba1e4b02,b47109e0), +S(19d45a35,f42efc85,283240b6,8f69626e,92cba511,5d265093,b33b71bf,36601850,757b26d7,65853163,fd4818e6,91154aab,c81448ea,19277b70,da37e910,e2bdb66b), +S(9e23f113,8a337fbd,42335454,6e2e3503,3c888aff,f61b4143,3673395e,bfca6285,80ef2fd4,bfdfde72,ab5c2ed3,6e8eca00,54d01eb6,a93542d0,6a562d6b,3342f051), +S(6b494c5a,79789306,9e236dd4,33a15381,f7ba8b42,3502efc1,896ff5c0,16871c28,56ca6202,a860a1c,25898600,eb2f2fc,f5636c0,bb2ba0db,f32cb433,b590812d), +S(b3e4116b,3d05150c,af5821f5,6c33b111,c28a3f18,8c8cf2b5,e5a5f271,115839ec,3bc7caa8,11f4b7f0,c30b0bac,51852c16,2e256b93,dff1d54c,4504fa1,eef9f5e4), +S(9f67548,4e8ce41b,e65902d1,ef56e8e8,46193052,3fcf48d8,e1f49fd0,9d9cfe91,3d8dda39,bb6e6c78,1c0861d7,73461dfa,7c19e10f,dd20f37e,a6d3f152,b1bd1d98), +S(47aa3648,91f116b7,e4115bc7,7419efb,9a267adc,4bcff4cb,1ab58c75,5eca5e5d,1f9ec89b,b253b6d2,997abf0a,46d4a3d,de45d605,a94f4ea,a4ac136d,b57eff2b), +S(b8ec4a26,53d82b24,da269a85,f51fe333,d6f6e9ec,94dd4bd8,3a90b68e,1742baa1,d4564479,b9c3ce14,882fd697,1db7d242,c91a4b8a,da63dd6,41c17bd6,77dda872), +S(ad2d7fd4,dc176f04,2c8a78a2,7eea73ea,7fcd0b16,29bbe1fe,f9eb9589,9173af0f,b4014396,2f84f00e,6210258e,ca6120ff,987601dd,80df3501,af664ea2,3f6e63f3), +S(aa9676f9,85435e57,4db82def,70905ed8,a8cc4495,539a8ab7,42f9b934,e6f1eab2,60b257d,83b39810,b6220fb4,95e61578,f264e817,71dfe6f3,7ce8363c,dbf8ea1), +S(12c23100,2fd6b31e,30929a8,e8d6b02a,593a89d0,b3f20a54,2012ce0e,d74738e,bf8e1682,8b06c853,f061462e,b5f90191,e1af5a66,1d4b01d3,a7be42c9,7f2a3ac), +S(5d1f0df0,d561494a,5e8b9566,a297c018,9562b441,ee91ed93,a43a4141,b7383c13,88a65ea,c63e0dae,244e3e7b,b7fedd20,6fc32f47,35891902,c0dbdece,5e304ec1), +S(ea92ae52,1b21942,78ca6b4f,770c56a9,59403652,39533c74,b0b99ea0,1e32791f,22358430,bf3e4aac,e7c6ae80,7c315bdb,7b7b94eb,4c17442b,bcbae6,b311562), +S(961abd49,90513726,15d8414b,d68edb80,9c698317,c3317d94,d064e272,f2e7c328,b581fb5,949a2345,f561fcb3,21dfcaac,9c235e70,f144079c,3304d48d,d20583f8), +S(41e8edf9,b2b5e7c8,86a9c82e,2780da4e,cc551d3,5f186c0a,caf456bd,fa08d7ff,8afe0efa,fb1b41ef,189ea40c,2f7c1df,f76f740,b2b4d30e,b0afb19e,92cfe615), +S(18cd2b39,1cc5a7c5,8fc7855c,51e9a737,f5bce753,bf7f35b5,3b7ac1dc,b9138f28,86493807,f42083b5,1ce4114a,d159098b,ccd4b6e8,3bbbfd0a,bbfeeb46,6f065ed), +S(2369e0f5,5cfa67c7,788b1d97,a7aed58d,ef0a3727,10a82e8,a459e55c,8cb998df,b3b5c65d,399bcca0,71829793,55d59d4a,f8dbaf89,8c10aecd,d35330fa,dd2011d5), +S(722b21ec,9e6436ba,c87ed647,2d28c33d,e4e4c792,de5e9b0d,85581f19,32f91f9f,5d757d,d475ab0d,390861e0,fb204ac5,dbaaeb48,d2a48014,d3a03ded,3293c497), +S(3b6661c7,33773220,40a45f9,527f1e6b,b3657e8f,de4d5beb,b4213f6c,130933ad,d480a018,3f031d7b,c4ec6965,5b0d3ce8,bc0f5ff7,5694977d,d2810188,f739f8f0), +S(2baa92ab,fd1b3a06,7bc34db6,d3a1b82e,afa2eecf,f82cdfd3,a2bd2da8,d5072ad9,4583b0a7,e1c0b53,c165b5e5,cd4e41f0,27179f60,328fe313,4b0c5d5b,9b32b3d6), +S(2fd0279e,bb08f28,5e4e385,6ab7bca8,dac262e9,968c2341,9049611b,6db8374,e377f24,92d0bf24,89a8094,5516f528,4871dda3,26e6d3cb,a81c55ca,41d62d5f), +S(911e62fc,dfbb1636,bf80d445,d711e328,4ea6c362,629e2aa9,f8f48a4c,8a0bdc32,2339b90a,a771f035,4bcf1f38,d7dbd8d7,643f260f,65f4fa2a,bec27e3e,ce6f8471), +S(5ecf9075,7d277b40,fe4ef091,a525cafa,fcabb2d8,da8b7670,d3d25680,b1c425c6,9690ebc2,1de37095,9abdb2e0,37b3b34b,db367933,888d9db3,e903f8ff,c5b85d7c), +S(270a9301,2167aa21,5c5da736,fe3e32d7,efa97b65,f7c89a7c,62a6ed28,e3038e3e,445f24c3,8998530d,39964c6b,d51d75df,fbe176f8,91b606ba,d4557cfa,a71d9f9e), +S(bc9e7f14,8244cfe8,b408be81,b79d904e,bcec0cb3,f4e540fc,f6f469d7,f73151f2,5dbda6e3,49377393,c6d90189,26bef6c4,59fd597,c50848eb,1808cf31,13b7e704), +S(163e1b86,bf0ecf2c,61a630d9,428f2fbb,7772032f,df990bf,1e276e98,a84ba2d9,3c25bb36,4f1d6a0c,c70cfb84,70604f61,4bad22fd,bf305058,667dd0,5934711c), +S(1706ad54,9dc1b0f9,bd1e5fd2,729802a9,8e6f6d96,24694b2e,3d37615d,b5565999,b16c7d90,403b6d24,65ee6526,54ab19b2,5c43cfef,fb6b33fe,12c56912,5618df71), +S(7e66578a,356ac4c9,636e0369,a7b1368c,cbe06189,602aa938,95a48826,a5c4d2c5,77e51712,195393c8,f95d032f,2bf1d39e,60b805b9,f5aedc31,a511f1a9,ffd976d7), +S(ddae1e49,1e8b0572,95884c3b,ef5ffbaa,dc6a7ecb,d8849521,177f7d81,868caca2,be7719ae,508d035d,88cbc2d8,3ea232da,657c78ea,401bcb05,9382c39e,959d5251), +S(5b44e6c3,a382e500,2a53ba57,fd6e92ed,8296341a,2e81095e,8ca22a18,fa76b450,443bf958,ffd1fa9a,1bc8ee27,ef49e457,cb23e6bd,dc6d251e,8e28130e,e6ce6892), +S(33d32ee9,f66d00bd,85d7e24d,7fa3172,8352668d,56be6f1f,71cead36,b1035f4,d3372856,106025f7,aac97103,4efc5c51,4c6128bd,6737fe,325ff277,f25fdcbb), +S(7bbc0b90,9491363a,cfa10e65,84d693f3,8b2a2164,1d2d886a,3c348c86,d7f98e11,ccfdd17d,532ecbe7,c654ec54,65928836,1dd2ee63,136d36aa,415fad03,f94facea), +S(a3da83e8,db0f8d0c,ad680373,f92426,26aea70a,c68c641d,648b2d94,244d68eb,305b0d91,6337a600,4f17626c,835a1cb4,c5d97f35,f75e7e44,ae3ea4ae,10d5b40f), +S(f5155f1a,2b196a3f,aa07d4ff,5fb91890,d37196af,1354d1b9,88ea4412,c57e9244,d060c7fa,f1666aae,f38d5256,b20893b4,961c3b4d,40fa9739,7a52cd00,4a2af8f7), +S(c948aa6c,ee9b8481,fed5b207,5100f0df,db799e6d,76d1af83,6d198f84,d6a028bb,6943ef15,988941,3b274855,1e0245c9,52172cce,8eb29444,e7728c20,a8da32d2), +S(518ae279,d1dbc26d,3b940b7c,f7c98eec,bc7660d5,af24dc72,ab8e6b0d,329b0d32,c8bf4d50,74471ad6,2f4ad9f,df065490,c81c1ce4,6a8b8847,b1e1b826,99b5ebee), +S(82fd524f,467bd6f8,bf84b427,d81b643f,ad38940f,ffaa2da1,f659dc6e,263ffb9d,2ccd7ea0,ffe0dea7,f591df01,5d1ae314,71f2cc9a,67c610ab,5bfe8f46,57a0647d), +S(250edb5a,1b6e4778,4dbf0bc1,510f9716,f5682aab,b975826d,2f715427,8d56cb5a,a625aed6,663ac946,ee805c8,11328923,9aae6503,1efab534,e152ded,e4d1f138), +S(d13596ab,e37d242e,ec6a50ad,95a171b9,c0cad0d1,5e6cf674,35cc87d5,1be1a6a9,fbbc5a7b,b3592ca4,5a994365,cb67d31e,68d2cbc9,ff790d44,366a6a6a,f85d80e5), +S(70f6d617,e21a9df6,370d044c,53804f62,9e6589d0,5900b9dc,849a8d05,719fd55b,5fc30143,ea245a03,ec0e9f01,a1e99f5,9ae16eb4,e693e3f8,732fe9be,b2c9b4bb), +S(f633f446,9b1617aa,8731ebdf,2b5e98e8,8ec97865,751bf6e1,f509842a,aba63251,3de28e7a,de2588d7,bc53ede7,3e9acbf5,5688ab6a,2cca8910,2ec03998,f70a6d28), +S(e3364ef5,183476d6,757ddd79,39447825,e06491b7,9fb5e6b6,c98e3280,e9dcea5f,f061aa9c,c5bb20e1,9084fcf5,a8e799ff,75670c3f,3fad80e3,ba3973a,be12b76), +S(c98a303f,7bdd7f06,3e09dec0,e9b5f449,f470e4c5,cfa11162,25517636,2ad7cf8c,94dec242,a375b65c,b1fad8a2,ecc6de3,c2f4be0d,e8751764,f320ad9e,35dc5de4), +S(fef6c023,5025dd17,5c8f5f02,78f7d9b4,515b7915,359e1c8d,bfa29a4b,67c1d654,9bdaca13,7b42cfba,f1075814,3409879c,249d5028,b1ef10e9,77a73c2f,749e9ce2), +S(c4413aa6,18fe751c,a50aeecd,478757f4,b23e8193,5304248f,8d93596a,fa489988,7003e5d3,3bca34cf,625d8cdf,f6910bea,16a39e5,dcd20fd2,1822b51e,55098cba), +S(b9719377,b83703f4,efb68dfd,b61c3d6c,bf9bb302,3747dbe0,c5c95437,6d56fe3,e57f0725,462f5f5d,b4c5162a,9b01fc,f52ea86f,6a7a5670,3daed54c,3672d825), +S(e72c8bff,84730fb9,7342adf9,67ad5eaf,6a90282,ed52b70b,6d9dc90f,e2395fa9,10f49bd6,79c3e7ab,21aeecf5,bea893d1,9836fe8,9a228a5b,ab7289f1,5f911543), +S(4e197fbe,2d935c0b,9280ab4a,26422b10,93a0fd4b,85a686c,7abfb2d7,621564b2,2c74f5e6,4e5205a2,7efa68cb,2ae9dc38,7467e102,5ef54a0c,4acc7319,4d372a), +S(88639d8,35b91e12,f381ef72,2c9308e1,fe898804,6432d577,7d515ea8,1797f360,1a49a5cf,75b1c8b0,a842f222,565a35b1,41b3c2a8,8d1b8881,34ff86c8,9ca4dc41), +S(a951d30a,c53e183a,9d74088f,8fed089e,1719f04f,39368d31,c0cd7b3c,b873f2ef,7f9e5508,a782c449,3ce8eea6,52195560,a1dc74d0,cfd8bb2a,4368fcf2,6ec783cb), +S(67028a77,3ff55e84,d4f19a99,f651d9e4,abcdd680,1add3739,c1688c18,22ccba72,bb611a0d,d5ad4674,e9a4fa5,63c6bcf9,a5dddf04,f195a9c4,c917d36,4d5a2ebb), +S(ba7643e5,13b102d9,f8fb5ae9,cf106d11,5d97a50c,d7e5cbbe,c13d24a2,be04a85b,f52f2e3b,88a49709,352b2421,2691882a,eb853ab5,7437e712,b83ceec9,2c25d7cf), +S(b3673761,b46a0444,cf221e48,22ba2f72,36e0c3b3,d16962c4,6e52bf2,334f099f,69dfa764,cdbca112,7a173798,abd8148c,eced792,b4cde92a,833db24b,992ae90d), +S(d6815b9b,296aea82,f1504323,1e6145b,cda92a3e,915daa0a,8a179902,7becd8bd,bf3ef3a5,8086833f,c579f9d2,2b7af47e,f97ac341,aa3aa2ed,2c74eb66,58178360), +S(b5c7dca1,94b68a14,fbd05f42,63b0feab,9e1dae1d,42dcac2d,1a30f70c,bee14c34,ceada44e,540b26d3,c37eafbb,12cf0cd2,54a9528f,77d37e1b,c19cd226,1aa70d08), +S(5a73c77a,7426af6c,f2d393aa,40189923,e47eb697,58fd76b4,5c8159bf,f7f8b900,bc90f626,9d8572c9,cfb6cebe,b6700fd5,49fd0157,ab545a5d,1f1970a9,47786b1a), +S(4e38c28a,e5fce8a2,ebee4340,e0d99788,340dc758,f3740072,41a297c6,41d8aba0,ecdf41ff,e5533cc7,8a9ee3c5,77dcf2db,bf589531,ca9e1ed9,d5b9e23a,27915eec), +S(59fb08d1,c85ddda1,dbbe6b64,7745591c,68bb7a44,608a22ec,9a83902b,14acdd61,f4c21cf1,6869d2e5,355ac8a3,227345d4,eacf74bf,af742fc9,413354ef,8ca1884b), +S(62ac0b80,e2040117,14a508b4,42cc0564,40f38eb3,e4f0e19b,4d8d05cb,bd19382b,e0d4ebf2,5bca30dc,95c0cfaf,140a0d67,29341751,881b955,9e03eb70,98ff11ba), +S(ec16d69,b7cd751,c44ea4c4,9b7c917f,45cf3c57,efd49263,58af0837,70c32498,8c8aaaee,14344b77,23c17e31,752dd638,fd8bc3ea,cace7522,3c712b6e,82d1316a), +S(3dd4a6f6,9d614c5f,87de1bc3,101beee,8b66a1ca,749842ac,dfe5ed3d,2d4b780a,2d5e6b54,464bd991,113c5ed6,50ff5af3,ca2a18f2,ab43ed6,5437ea13,3ba99fdf), +S(5e404405,3710c999,a77d9048,cc651c54,718936d2,d4d8d8f1,ef416a54,51861aec,c6c2bc4a,1e8682a,2426b02e,92bb7094,2f8db6ff,fa6b375,79b50146,66f31f7d), +S(66032f1,f55b606f,fc68ac3a,92683cb0,d447137,430ce435,9d1f06da,10954f99,fb14ad80,f168e517,fdacf38d,c197fa71,6ae1157c,ccf0948b,a7f0914d,ff8d040), +S(25c4c534,8ee76e19,799d3f9b,f56d3566,57332560,693e362,b7935ebb,85d7056e,1d7b9e9d,6e52f220,e82647c,a560c02c,ebd3f608,f11260ee,c9b16b58,76123b6b), +S(fd70c030,435fa972,793551b1,e409739c,6f148342,e833bb16,c4dac4a8,a853f0cc,10870dde,23c4097d,505f2d17,d3dd93d6,eb9c1300,49cb0fa9,2ed63c0f,feb73e80), +S(ded2703f,3fc6bcc1,eb96a925,650823df,583ae86c,cb43836a,19ca31e5,69c1cebe,5957989a,db61c969,8d61eaa1,938ad6b,cfa3543c,e13811dc,cf5b4ba1,24d62a5a), +S(9943048e,7097dc4b,709012f6,d298137,dc8e471c,a66ccbb1,f023bcb4,938c02f4,57fa4b31,b80df627,b9c212b0,4bfbbdd8,d1dfdb03,ece420d6,35d0ec9e,4e86384c), +S(313dc488,9214c7ef,960f2f95,b55b8083,d1adde1c,775f7f6a,62b57c01,aed5b95,bc02f247,668a334e,349d8ebc,6d7a1ba2,1f99ff1c,ddd10c2b,59aed3c0,815b1e5c), +S(1b9ce18f,9360e5db,8da1fa8c,f5ff96a3,1a898f19,2eceb059,c39f6cbd,4de5c920,84937b84,5336904a,4047c917,6d1f54e5,4e1a15a6,52a97668,6249987,82f230c6), +S(4bfacb3c,18ebd5d1,bf71ca5f,b1b6bde7,b314d2fc,ca1c05bc,f4021595,e15c6cd8,a33c205f,d4ac1624,d4ebb554,816d6435,86e08ce0,6ccc762e,232cc7ea,d65aa5ee), +S(f6843448,522403ce,a3e4597,30648835,2399f699,421db1b5,2fe33bb6,d21c614b,ce80913c,eb14f530,d153104f,202dad87,2f000f16,fb60316c,bdd40c79,4c95ee85), +S(930816a1,ca19458b,c2badcc6,3cf66d0c,6312f52e,853b5365,1b829b3f,2666ca70,4b29edf1,55385f57,63dc4008,77c846b0,4c810747,4def410a,c796f58,f61b849b), +S(b9d0798f,2ead9231,7face0a8,31869066,76711e1c,f3a9a465,8f51c039,7f76c066,4ecdaede,bae33f4d,79240d11,ce0b0564,62ad9f0f,51b6d7e9,e69a283a,4770053c), +S(1e8a7b02,60d58ae8,902fc57c,5a1648c4,e14d1a6f,696e7aec,c2cbe5d7,2e5439a8,e8c76d70,913dafc9,d157d030,8ed328fa,e08150b6,4a48754b,907954aa,4aeaacd9), +S(ac754bcc,c9c7b4e3,6551b654,a0620086,412db1de,14e422d4,c9111c64,c8b08b0b,3a8450b7,e841959b,93d3bc25,ced04aaa,4df90b90,d1ccbcf1,2fd88bc4,fdb366a6), +S(7e04fd28,1770ae0a,8fcb64d5,6e911667,a50170a8,3fc691d0,b0a8e1f4,73de3c2,73c37d99,cdfe5941,62b7b620,34be369a,c7da1d8b,e7d863b9,a90de407,24acb7b0), +S(ff903b99,13bc9005,8f237e9a,50f83707,a6f7d24a,d62142f3,16fb89ac,fad9ee9a,37cd140,36415c21,6e899a0c,2e8ccbd5,8f3eacb8,c88b1182,8436888b,899b412f), +S(d1edc0e4,44e92bd6,be858374,8f8fecb9,dab0d6f7,c74d410a,c412865c,9bf95d00,c10e796,3dd91bf7,c1754154,ec82460f,817d919,d13c52f8,d6578e8,52a8f87c), +S(62ce4177,9ba5fd6,332d188b,3a8ed98b,3883f013,731ec72b,8b0842d,ef0d5e58,ff141435,2b26b61c,ea78f67,de7ed56b,7895c03e,e3c28050,151b5a67,625b2d5c), +S(c8e885bd,5d0d5399,47addcba,879e7fa9,b075f871,e484f7bb,69081c47,8540c845,2d0d3f40,77cf511d,f93a278,91795dbe,e5087584,eab4fb83,e18e5d76,8d939dea), +S(62b1a52b,de107e62,4567357e,de49b08c,30c31e8,9c1743cf,a033fec,6bb8ab3d,9ed15063,ce1c8d00,1f19b388,ec678025,9cd5d951,4e263453,d5bf98ac,bd64d1b8), +S(88589c8e,9d35e6b4,5788bf01,bf3c6672,32324529,3d8014ba,525f016d,6f721e1e,be4804a5,d5b49ebe,8dd127b6,e55a7702,92a1c0d1,dc431fe,f5e4e873,103e1fea), +S(75e47add,7a7f2099,1a12916f,9ebe39b5,1409e82f,67afdf7b,d1d7464,1b83a85d,786b9b83,818e81ed,e3fefad7,c7203e57,99b4100,7cdd291c,321adcab,31b57bba), +S(d56588f9,982aa917,ce28e887,44ffba41,4cc1046a,a0122d2d,afb8715f,a9afe3b4,b14c6ab1,3a1793e5,68b171a5,1ecdf179,d78818b7,9cf7b1c3,97841a64,97b5e3c3), +S(9be8f7c3,efadd410,8c24dfcb,3a14a279,8cab4de9,8f5ec786,de7a4448,d9150e52,705ae8a3,a554f092,c677eebd,605661f7,4c463b81,97444d96,a5bda8a4,60315337), +S(96c95643,ac2805bd,421dfbf0,8a4801fa,69b6815c,bd31156d,f12207fc,48831c43,656b790d,35e598a8,dffed7d5,9b0b827b,3c46bb1c,3e5163f2,a4b71236,c6bb1b64), +S(9dcdb2ee,239faf20,2bfa036f,5d6adf4f,8d1add19,8def404d,a9447867,b126becd,3b727773,d3587698,7605dc66,12dea6b6,46052652,abfc3ec8,576740ab,81291e89), +S(b33d2b97,e31618b4,d9273d4e,82893e01,d85bb2c8,7d0d1059,f989bf3a,7022d2bc,2c447cc1,6e680637,12a4789,6ecaed55,83cc9e94,525d7c19,9e47416a,8569d5d), +S(74232d9,547bf3eb,fe4921dd,92d77131,3f5c97c,203c0db9,12106698,aa9d5c8e,6fd43ac9,ac04eead,7566e40b,3d04975b,315a36c6,e5b72cd0,14d365b1,b7a3836), +S(937ffd12,72a7df14,21df0c9a,3e015d0d,be72932c,3489fa2b,d34f72f2,763469e8,55e9e0d2,54d3379a,a6e35511,acf9dcbb,372d5b8f,271bb7f6,4c2cf77e,bf624234), +S(1513a5a3,7aa52a65,d659a7f,b0e762fc,67a8a196,8f2b6ae2,bdb02955,5d92476d,8d99d771,6cc3d831,9eca3b97,8c91d239,a7ef6b03,a13eeb25,ad94f4a4,20ad3eb9), +S(c7464b4f,bdd39bc5,4ce45b87,e4db3a3b,22fc52ac,b649266f,f7dd69bd,65b2843b,bc0d264,e48aa14b,bcbdf505,9a35fe99,395f03d6,60635150,cb8424b0,c93eee25), +S(cfdc9326,cede0724,5a89824d,1cfe590,c0945793,88812f11,4bed6577,ef7432ce,a8df1cf3,5d471afe,ad43f88e,46e5cd84,ece5fe8,fadc55b8,e79d6eb8,2466a270), +S(aa5529af,861568f8,cd4ac26c,fb1f5e3b,5ddf564d,ba4f3b5e,8d3ec5d2,606530f8,3273795b,31e53e0e,e34ce1d,aaee7801,309c0315,926eacba,fbb0fb6,4f0a948b), +S(206bf37d,599c665c,1bd20187,93f526af,1099819b,4780f2a7,6f5c3797,4eb404cd,7de063ba,3271773f,56ca358d,335a015b,8ae8a45b,b4a9cffa,2f20872d,9bc654b3), +S(3f21852f,621d5a6d,4c91f27e,82018b7b,4369c15a,69664cc4,6cdd8195,1f3ef14f,db8e7b5,fe7d9972,6da564a1,78131727,3ee6e005,908513d1,3903aa3d,d036123), +S(4c562c1e,9e4bb491,17948e93,f94b4146,c918554f,7d351300,5ef7f181,2c9900e3,1809f902,c6f694de,7909c8e6,ea4e938a,c1d9e6af,7707bd05,3a7d8560,24875012), +S(a692c8a7,a3b306de,48481c93,8f0a9814,e081bf11,6857f217,4c1ccf1e,a8448a30,7a660fa7,def1429f,4c72e44b,9fad10a4,7639942f,56a647c1,d609f3d9,26a40a9e), +S(981d35b5,5998f57d,58a62d9d,af65e53b,419b99d8,2d2eeea2,bede4da8,ec400a2,d20db6e,211c3ffe,ecfa43c4,79a43ab3,8590a142,9d9520d0,62f1ec1d,9f1c574a), +S(8afa1616,3350087b,1e286bfe,5d610463,41adfef8,8b0fd809,336137a8,92d32e45,54924c6f,5c2dd61b,e5b1186c,7fb8519,29af1989,f468049b,bd5c3cbd,387a28c7), +S(ba7cc113,f1e3bc3e,ae14c2cf,94fb1ee8,bdfa60ab,52582ce3,595df63a,d08c1e17,ffec33d6,d42e2233,baf02780,a60272f9,3531b1fb,158a4bac,6c6a488c,fc23d03e), +S(166f2dc7,661c9e5a,aa51582f,4cd08cbb,47c6afca,143c4231,36144cf8,ce69ced7,132e0d13,6a292cb5,9f0503aa,589b37a2,dd1c9244,c492b8ef,647d79c4,778bd94a), +S(bc9fd332,f66ac57e,46ff7801,a7d38b0c,f2befd5a,2513688e,b29fc5af,902f1c07,8f58e1a2,2958600b,dd64a428,7b6b25a1,dda32351,dd45453d,d03b99ad,e406e240), +S(e363fb9f,77378eb9,2600491,386a884a,24839001,cc516bd6,44cf6e57,b1e66507,3f83ecdb,907afc42,b47ca948,fdfd3b73,dfcf1e5a,7cdfe1dd,41a188a2,1b5f8b1b), +S(c8883193,9b5b7ab2,2af8763d,52efbd5f,50939606,920325e4,805842e1,3faa3cc7,5db2a08c,6e8ad455,f542d2b3,9b8203e1,39c5b0a3,d1fb1ac,763ee4b0,4b9c1f7f), +S(76149173,1a20a975,16607b53,501c45a7,f94df1a6,e0f15301,bb0bbd4b,eae97439,e75b67c1,fc2bda74,9f834d8,c9439b43,c33aa4ea,f2fb9116,9804615c,8c1269c5), +S(8c19284c,f62a4116,a40ec5f5,43cdc2b7,e7615400,d1090f86,2f378ac5,81f4b5d8,bd93accb,5c42ca6d,a4e6ac37,b2bb8359,42bf659e,a0e6beed,bd754e5f,749bce8c), +S(7664fc89,5d8de0b7,b19f18be,cb9a9b1,783f97de,3167bc39,7c03d007,18311a7,861d8f0f,125d051c,9f808064,346bbfad,410fdddb,aa31aad,cda7a713,1d65a3a), +S(7aef0296,33664cd7,694a5d0,aecc0466,541535fd,b1540c38,8f0e0e9e,24e96b77,e02f2ba1,8e92d161,33d29d1a,c087cf29,3a91acac,662c7208,b9157032,d0c829ce), +S(cd222d7c,b49b957,e5252c06,7f649ec2,dae145c4,d82a82b6,8693a242,6b7ba40b,c261f956,dfbed5c0,e876492d,7325b964,3dfb2075,68ccc93c,14b1e8eb,d3fc1b59), +S(5055e224,c61b34ec,9cbe93e8,ea4c9488,19d94338,edf6daf3,72eda45c,da9f0971,4fe31a71,bc782d4c,720add07,4cf97c47,dbc1f38a,3a9d9cf5,955e1760,5f185651), +S(23a80902,a97669c4,4b20f49c,fee841a6,b5a99b5d,d423f4a0,5d573a3e,4833984f,6a57ed,265744e,f4d18250,435f695a,b80b944,d0153b77,e9e9a20d,bd98c659), +S(b9879ec3,2ad8fecd,35022a2,1625c159,a31a72b6,5d3f3c67,5dc8e114,c5f59de1,439d2afb,aecc48f6,310e18c1,2e31c9c0,cf91162b,43b153a2,f901a19f,1efe8e10), +S(918e367b,531fa89c,8ca89c2d,cad34aba,c937cc00,be3a2b18,bd1585ea,c4678a4,800078df,6b700c11,85418749,27a8402a,db41811c,77d0fd4,aa435c2b,7a3f0a2), +S(6cd0f4f1,c03f35c0,65815638,10906fa9,a41bbc26,da1bd7c2,ef39a4c4,66e49252,ef644bd6,ed42cf0d,3ad17638,5c239fca,61056021,b001ef9,dcafd370,cdc06156), +S(8a0c443c,3e26680a,3dc8483,e0a067,553f7ffb,af939922,1c35a766,b12286c0,6c30af1b,9a97958e,11d1e24f,3e8ce846,1ff37795,556772d1,56514015,a46951b1), +S(563b11b,a7f5d351,729b8537,1fdccea5,d7081262,8c1e265d,10c29172,d9a3252d,81c0a2c7,8b36ca17,29c9c02f,8050e3bd,ce46607c,5409c50,10f8031a,ec872593), +S(27e88b96,29eb9d92,e57ce3e7,75063c04,4a1f9f0a,dc94a139,abe56b05,77718f94,ea04c851,41e06d26,31564122,80c86d83,89c1f15c,3c7e98a5,610e52ea,19b1305c), +S(95288e29,a554b7e8,15ee68c7,16772a5,4320a7b1,20a38865,f3838345,f9edd5d2,d81b97b4,2404966d,3c4160e1,59f275ef,b91cae46,d9a33f51,34455ca0,496e4472), +S(b86033e8,e3bde32f,859f6af0,bb87b72a,b1b88648,776e1e14,273e52d6,205e0186,e120cc94,5de7563e,915979e1,15ee7cd4,4875d50,bf6b93db,8a133cac,227091db), +S(644a2090,82c7984d,447eeadb,2b21fb36,599d2c1f,366a3af3,44afd230,9b780c8e,b49cefa2,c0865df5,f6f6df65,24b39f7d,67eb07f6,ab6e550,390351a6,a2a1a00c), +S(1f2c4207,2e803f99,d1389efb,209ab0e9,2d7891d2,531f6710,60371c19,7b0f41df,98db8e40,69dab24c,4fc6e13f,37e805bf,45d30c28,9d4455f1,9670299f,a6c6a804), +S(dab5435,220297e0,e738e798,f1f8375f,dc813874,7a633f05,1be409bd,d6a3b8ab,91b6c193,de219ec3,ab3d6635,d4c41a1a,6059372c,a8afe185,7013e474,79fcb382), +S(5ae6a897,467fd90c,f693a5a1,d89d4fbc,4f11680c,86f5f99,30af1866,a1f27137,40612777,fde69d15,7d51d85b,137fe92d,c269c42f,4423531d,548fe248,44d0502b), +S(9bffceb8,9acee7f4,68cfeaec,6d597672,6f227197,6506c5b2,6c5cef5d,7545265a,a265cc26,fd6332b3,fe6c7487,23ce3d5c,12eac750,59947de0,9face60a,4df250a9), +S(f38cf54,b77eb8c3,2d339dfb,df288a11,3058b4e6,2f8c4ffa,2bd29e2c,e6c7b677,2daff1e4,54069fd7,63f422a,15e9cd91,65b5d97a,ea0cbf55,103dd751,9faa55b7), +S(350d6b26,8058c8ce,4684a5da,32e3eae8,caf387be,ea9c95c,311d0209,47122dc3,8ff3be71,e94dd657,281c9f28,780b015,1a2abf2c,2c2ed9fd,e7d0adda,6c5e0690), +S(1ab92290,615207f1,34859fcb,26ccc8c,ab9d5ba9,f30d12b1,ecd7210d,c68cf573,2f1c5e0a,53d449d8,3a5d1507,9992dea1,b481e607,e6c99f7a,5e0193c7,2a426d61), +S(9e98be16,cf2ef9a5,fa3a320d,5f844cb3,c715420b,d44db10c,8f24b0c8,be65cff7,9ff6de6,ea416ea2,72d8e438,e132a86b,a03c272f,378a4726,aa72800e,d0214a3f), +S(9e7b45ed,8f0738fd,58784c7d,a42312a3,53f12676,9fc3ab56,9c4cc69d,25a5b1f,22be7dc,e6e513c6,1a733f45,980f2f60,ff4653cc,49391baa,f4b27174,98f79668), +S(6b6c1553,cab82490,7c5c480f,88daa7f2,7e57b870,5110e1e,7e7a5be8,4314844e,4c10d4fe,d431a4d9,6b719188,b2027764,53885709,eeec2837,32832497,319c9626), +S(1d28f09b,37cc3c4e,3f7ee903,6adefb71,6423e5e5,8840c6bf,d3c03151,db723a1a,acbaeae,cbdc3e9c,85e36db4,aad508b9,9a152373,547613c7,a3455769,872e55b0), +S(55e861ef,3de7675d,857b8ba4,73aec3e0,de0f529d,3a9f4a04,11ec4d4f,5a996d75,a942b32c,44618065,af08a1fd,73e052a8,78df075e,e54cc160,eb9846b5,d46db7b3), +S(10f1258,4bdbfbc5,6ce7b023,78a5e908,9457956,65f4e49f,a53f7143,3deda9a,4ce2f90e,efc88f33,f12edecf,1af91612,e3f84dbd,91f45bf4,5833012f,63e02398), +S(48ae6885,ed275a41,2bc61a67,399ed1aa,cb968182,2775dcf,9012cdaa,a6b21ccf,8b4b5cab,e5471381,46c62a82,102d43bf,5b83d993,41d026f7,c1525ed0,8c2238fe), +S(c6f5c5c6,73642a35,59c06df0,18527de6,7fdb9f4d,75c98f01,8f45913e,932c1481,4a4d4894,e31d2adb,d150b184,51cf16b9,cf7e3741,c4ed2511,c0765480,2f59fde8), +S(f38923af,ff4cd9d,cb16d571,3a68e18a,7fc163d0,8835d283,3676caae,5156fe49,e36986c8,d7e07fb5,6a1f4266,d980c113,43cad9cd,f7e4619e,17a45642,6425eff9), +S(10883b32,87b20d7c,7e60048f,13f179db,e169b82,f9a95f87,5271861b,36170d85,59be5146,d328574e,d837776e,c0748043,369bad42,b38ebe6b,861861a1,8c5307f0), +S(87262e3a,832a6c07,d6d32fe5,8f0e85c7,40591c6f,21da8ae1,5f8fd137,454a383d,7db37cc3,11decb91,cb4fcb0e,9e73bf0d,c91b3a5,53292f8a,f5036dc1,baaf4473), +S(cd4b75e4,7fc954fb,b71c21c8,28322c9,a54871f6,2ba2a803,780954eb,46c9c54a,6cbe7868,8b5722e6,ac75f9e,c93a7a4,39350a67,7ef31f53,c4c73b33,cdbfe124), +S(468fce11,bbde91ec,fa738924,9a07a39d,b0851d0c,3cb60f96,cbab165f,f5c69242,93c66305,d55a21bb,e14bc51e,be8d9c8c,14f0e8ee,caef9b49,567a8f03,6b2d06ad), +S(f5d9aa66,9cc173b5,5850e784,fbab08db,d0f11e6c,fc3243d,ff6d1a7f,89f517d2,aedf8598,b11b8c00,34f1e3a0,ed4c6c2a,db1688bb,35bad212,ad692896,2b045d13), +S(48276e7f,91c2068c,161e97e,7587a30,a79ee120,cc30a9a0,571da1de,53f9e253,a59189b9,306aaa38,848b7b7b,4653e6bd,68944d6b,46a4899d,44ed2367,3ecc241c), +S(7709db32,f9a551a,23dbdb7e,824fcc7,720f24c0,3c58c68f,d2b5ce2,cfb59cce,f8b35a2d,ec4b7698,58fe791e,c240f54d,8b5ffde7,f24119b2,7ab20fcc,8ad07f0), +S(a7b6e973,d1c62f03,6eae2674,bb5b37d6,c5ce3187,41776833,d7f3e8c1,ed2e6ac0,116042cc,3b409748,162db6f0,69ebdb11,53aece8b,37c277eb,28c9a2ba,c7c8224f), +S(7c5f0e06,652e8870,74d0bc97,e9c0023c,e2cac507,659d1a07,5f9c9fae,2d77afc0,e9156afa,24565d92,fadc1aea,f49e1bc4,b28606e2,5bcee2ba,f7c9a87b,b510113b), +S(14a0e517,1a796c5c,1bcfdbc6,f0431dcd,6fb7a8ed,4d6f1621,be01cf2c,64ae0166,231ab7b1,1c3d84fe,1e35b994,43d7f7da,a0bb4e46,834e92d5,e5c689b8,427b24e5), +S(fec19af0,286c251e,82aa7ec3,c5a8b048,9ee4b6e4,8e62c59f,7cec1aee,45b7323b,18cb5d01,5506074d,c94d0a0a,261301ce,d042405c,e4f01f39,2bfb40c7,62b47a8), +S(5788e079,beda8301,e290a04d,dd11c173,6112ac99,76c4857a,ba479485,5d457873,e2c6e721,b5bca7ba,add95284,9257927d,86877477,e8468b6b,9235b30c,557fd7e3), +S(513c9124,d7e1726f,73b39525,377c2761,48697c71,594615b5,f18c6695,b4d589a6,659ffbe,fb3ff7b0,2e5ee01d,eee0ea65,8a562af,722076cd,3cb2ec56,16533beb), +S(d96da66f,fa79adb0,80d06968,bb9243c1,dc6dcccb,1e9250bf,6243a1e0,9578ff8a,76eb65d9,6d520da1,34941ccd,8af2f32b,6050feb9,2ab39835,931b901,60a5e481), +S(37033146,69c7eda3,e598a616,12c65c76,8b5cefd2,3371928c,191c3d16,4d1b495d,fb886600,ffb6e95e,dc704a62,f5105795,474ce36,45d54d24,8cc53fdb,7a28e978), +S(493d5ec5,ea8957ce,6608e59e,66e8a6c7,a8aab1d4,fa14230c,8c3a6288,37e60b2c,594cc0df,dd37f4ff,d235e2be,1cb98f61,8485e453,6c301d21,11267528,3bbb5097), +S(71e0fd4,937ae3f4,84d521c4,86f01485,a94bf45a,6a0d2472,d7c5b97c,19d99068,7551009b,73422956,afab9675,1dfa7eb3,9feeacc1,4d220714,1cf157,78f7087e), +S(fe36f2fb,971a1eb1,9a158190,cab6d80a,60601d96,231b5aee,b4c4b332,b35c7031,f72e5fdf,b8ac9af1,263f5492,2caec24e,dda604eb,953a3b02,4e29d70b,55266f87), +S(c734995b,fd73d82b,8555fa56,56465102,b6b14813,272103d5,2de7d6db,fb9455ce,713ab271,3c718906,3faa274b,dc2bfc7f,4f65dbe7,80e07c0f,7b625d70,89f31714), +S(e56a3832,f58b284a,6454f8d1,73f2dbde,b8212cc,a9196524,e1856c98,6dfd76b8,cb301f78,26b39496,6d9f9953,7302ec8f,27af592d,fb8e7e1d,acd5242e,ee2b8cb9), +S(c511bbd4,e242f5fb,a2202900,45f4f125,ab2b588c,f9b375d4,4910fa55,be8ca373,3b96300d,7713d05e,d22eb08,bc039eea,ba2f36f5,80398e61,b3a74581,5f884408), +S(f7ccc53,75c59fb2,90408676,ddd9f1d5,ff6d66fa,1172e0de,cba38ea8,a160a457,45081507,f4a14598,ad0f4278,1f14b8da,72ce889c,f23b52c4,ec5fd1f6,9939e054), +S(8219112e,48f1a2b7,7a03f20e,3eeee016,ac69818,f22adf72,3679e2bf,3586dcd5,205e4b4,2b9ed249,a63d4a5d,853ecc4d,4d37b0a8,4841e959,d46ca7ed,f42a7c40), +S(34df67c5,b0a9400b,9b9eebf2,132426c6,281bfbb1,402cd49c,1fd38bfe,c19f6afb,34066c5f,d45751fa,df681c95,791fba62,79bc76cd,a70ce02,92ba7c41,34fc5d58), +S(9b969626,16414928,6cd8ba65,75572291,f1a885bc,1ef82fcd,7c445637,da1654a8,12e52b50,2fda57c6,ea330d5a,415d47d0,a1e5a138,b7968c7c,3543dff2,9578c13b), +S(68add94c,a17a6ef3,85d23fbc,5d7763b9,15c29bc6,2a520139,24154a60,66d0eafa,281bd1a5,71629916,1a911be9,88a13f64,e8065610,219bdbe4,5271f4ce,2113d77c), +S(143eb857,7844f677,2b01db8a,d6cb84d9,fc1bda3d,638325d,b29d280e,16a7f36e,a50cd3fc,f771ca36,58f2b9ee,4133f17e,d72383f0,94492358,76bf04a3,296b7df2), +S(7b463842,1537aaf7,2e6f0800,cb9c0428,b1dcd22f,73694b83,63f9b2a6,86d94bc,3bed2d2f,c7b5a092,e6e8eb33,1f945a24,65936fac,90a3f244,942895be,ff42895f), +S(1857638f,ef86615f,7bf0665c,3b5d9cf4,c51690bf,c96481b5,78d30131,8a32349,64adcbbb,22267bec,c7a40d4f,6eaf66ad,9c133182,b4af858,6b0c4aa2,e30a37f2), +S(bf84f3bf,d726e0f7,2463bd38,4c14b35d,f9502148,4e78f001,b848fdc0,4d7a823b,4cbaf2c8,71bd8ecd,4439fba7,193a9bca,d26653d7,a4dc7a00,f0a35189,e1949139), +S(4482f7c7,1bc8f76d,9bfe9148,77ac76a7,6131501a,55fc5556,c4e95ac7,68c9ef11,f5af5b16,10733ce5,bdadc3e6,d1df5de1,314495df,3185f7c5,14151c94,908ffcc2), +S(715e384a,100bc5a0,20857ab2,57a352a3,b7ce41e1,a742cdc0,ab1354f9,d3483e93,13703919,b85f567d,87d2e6ae,c2ad89d9,743030f,9b32f277,34c3e9c1,4b5fb1d8), +S(ff90a61b,98f591b0,ffad3ad,3dfc0432,1093acf6,18b0f71a,f637a335,e9627726,908c8caa,f88ae7a,c215cc30,7d7fea86,1d69ca24,7b1c0949,57f022c4,ac130335)}, +{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), +S(fb32ea9c,4f434cdc,db41595e,58f16466,7fd92a08,8a182823,137cd308,9974551f,415b1d67,d845a304,a92f9f62,65d09c20,32bcc521,4303d791,95b05cab,95ea05c), +S(49523899,174fdf41,e4a551f8,423da35d,f3cf0ffa,1f2b8b12,d2a51764,9d8f8b91,6f9c0b72,c5c6fbe4,3fc3d956,7e4bb980,975b744a,dc9ecdfa,8ca42f46,d7164130), +S(c02d61bd,9ca243ba,f2907638,3dade862,bb6ec35d,861a9829,10a084c7,7dee331,fa82b2c8,f015d9c7,b7329bcf,51f60a93,60d54d5,2b24506b,db542d9b,23aa7e6e), +S(a344867a,cf07375a,295cd97f,68093020,af6a1da1,d871b330,a52ab3d7,b4cd0ae,5b1c6f72,531ff281,88ace548,4f193dfb,b8fb233c,b251c788,22dce3bd,3a824c5e), +S(96ba694,48bd703f,a8aa21f2,4257bcb6,2e98751,42d32af,63bb6a37,4ad262c4,35c74902,7d4d0a4a,1550b7ed,cf791da3,7aff1aa3,a446225b,5ce2c0da,aa85c82c), +S(278eba80,511ce15c,f00617ca,21d62211,35f5c4c1,87d959aa,cb098b7b,4b56e51e,ad903485,bee432c3,5ec613a7,68175d93,4f0e855,28b76b41,1c6ad8a5,510510d2), +S(554be9de,b938c4a6,fadc2fb2,77178b95,37719f20,8b7f06d8,7993d06f,c3500bdd,931e3263,34c1e96c,a4c88583,92a8b7a4,c17f7582,e4d0b7eb,6cfef36c,7e2d6f0e), +S(26a4f40c,968bcc7f,cc4002ca,b7ee20c9,3996a600,b4f81df4,66692d3d,5a6c19cc,67f7c990,ba734ebd,af5b5263,cc28624b,9014b7b4,443ed322,fecf49b3,3760b5e4), +S(67a90211,86d66afa,172fa6a1,dbd9b3af,9e3fc726,e5ba6916,59f066f4,fdc6af14,23ddf5f8,96203f49,9be9db01,5451305e,57e51d54,95672895,3968ae1,fcc835db), +S(d3bd63e,d5555686,fa88a122,294ba841,33be6280,17a21f65,285d4651,214b1ecd,f0fd835b,5f27da51,1216ebfc,f5af7740,8fc053b7,dedbdb37,40f6fef4,4cec8bf9), +S(f0dccbe7,ce8362ec,e7f8d550,b0967d4d,fbf6f9c5,1ee4e7fa,b3ab9b50,2b0411e4,7e63fbef,ed68f1ee,6f3143e7,a8e5f2e6,edc77db7,3d34b821,1e062b36,6ff0b8d7), +S(56cf2a5f,d7f41d22,cbe716bf,183a9eea,370f9bb7,5620f460,56c9023f,b8402952,600de0ed,c86b4f7a,93423beb,6a2b29de,749d05b0,4725b5c7,2fbb60e9,7fcf815a), +S(1a60d0d1,73316260,721542e2,33c6be2d,e0088476,e24fc61d,3d0cc619,dd3c1564,bc90efa5,3588b420,2cd46e61,a826a47a,b9f5e45d,eff920ef,100efa34,c179743e), +S(bc406d21,ba9b9a12,a38b6572,5490462d,2be4d0c6,8922fa01,b02e34db,ebfe8e71,6ca29bb6,878fc1dd,13cf814e,c9bff5ba,12a3d55b,13c3aeb1,6d588ddb,371c1981), +S(376ecde8,891b479e,490c80b,b81d15c7,c5b19a7d,4f838db8,b580338d,5745e583,9296ec3d,9256e491,3ccd38f2,e6331513,c7040e20,4d0e8344,6e9e8de9,42699fe6), +S(64cb1c7f,ec791b1b,7b94c8b5,969410b2,52243c7c,3068eb11,99d2a56c,aa2c1330,f43fdc60,76e80c11,4f19dba5,4f51da94,822a98f0,986ebcd8,6160ec7b,b249227b), +S(6f089f0c,2b95a26,e3cd8d95,98469f,c0795e0a,6be85b5d,fcb47071,c5413db0,dad7a3d8,e61e2a7b,ff7f9357,314d4405,8cdc1aae,c1bee22a,461c6b41,23ada4e2), +S(90b30e36,bfb33081,d54a5383,c77116cc,50e1a333,1b319150,98736d29,e4bad6f0,589000af,241a4c83,bc2defea,9b653ce2,988fe376,77b31abd,7f384762,758e98b9), +S(82f0acf,4a764dc2,59218ff3,397618b3,2e341ed9,6f4961c5,f5a6d559,654194f8,ac0f10a8,4728d82f,b8784cfb,b72814d6,868006b8,1d00894,26825a0f,3c3404b6), +S(3460815f,6036aed,4a2e264d,8e17b1b5,6c10d77b,5c021cac,69ee3a4d,ffb3df8f,c11a4b6a,c66ba79c,e6bd00c0,286aa96,de72f162,3a4f8d3b,1a4bc421,c9f33340), +S(b8c0311c,c21b7f08,46e66ebe,f3dcb726,53de4e83,4e450a06,e394d25d,195cb7e,64d4046d,6ef0fd1e,30a71c10,d85f0f07,8ce3113a,e904764c,c5a29ef6,c983b327), +S(f7bdf7b3,b610fcd6,cd2712e7,7a30d38c,2df3bb69,183ee96b,408bef1f,f57dfc59,fdb15f4c,61f276f3,343e2ca1,38d69b12,339e7e5a,dcceebae,39c768f8,95a0bf92), +S(ea32acb5,b5ef1dda,bdd4ef41,52ee856a,6e298277,f5f9c95b,e1adf49f,cba85262,1c0c5f11,3a3a033,790b073,9317fbbe,874afb39,72935a3f,52a309fd,6432e0d6), +S(e184d302,f708d25f,5af8d023,cb6b416,ffda5bbd,9f592edc,ab4f1890,3671b604,21c74686,4200438e,9cf66cf8,19292129,dda4fe13,965becca,8a1fd18c,e753abe), +S(69e75799,f0c0098a,3225e598,a7e8fd98,1218de4c,42aaa680,4ccf7c92,a45fe071,cdd2c796,c85d0930,8aeaa1b6,9a535c5c,6cf9d607,b2b296db,33d0b61c,b4d7711b), +S(a70c1082,119c47d4,75af4a96,1e61f0dc,284733af,c89e403f,9a5dd65,d465980e,3193967,8665bfd5,b37cd1a9,62f86cff,43b5f058,ae9045fc,c571cd62,bf390e9f), +S(f63e5154,9819926d,254f76c2,6d4a7b95,f01e612b,8b885073,f7ad23f9,dfe82d32,57521b53,d9a8a71f,71ae4b31,df7999d0,40395ce9,f0b70cfc,396bee62,40364b68), +S(9f62320,94d674fe,3959eaf5,b947df18,7e894594,8becef29,28bf7aee,983e108,9430b33b,5bf4d79f,1683da6d,ba74adfa,dc19489a,be9eb3f8,9f00a793,37fe9b38), +S(9802daf,4ba214c0,d19ba4de,77d92223,7f120914,7595135e,9ad3c75b,7731638e,98cbe71a,b035839a,3a2f3449,d6261dde,c14501e7,53523afb,4406c657,1fe5d2b4), +S(e86c5944,58017291,318caa82,8fd86a2c,d4ac8a67,c42dbd2f,f57b2b38,f47c9e0c,9e069a55,94596844,8f5bc2f,f97d9660,62f99bac,f74d46dd,5196b37f,f8503c26), +S(40d57e52,c21f1daf,3ea1d981,5f4da45b,807f083b,9e68f2c1,ec5b6d56,e2921871,99115564,76906b4e,5deea9ea,29ef8dcd,c1841b15,bd662ab2,720a28ae,d788e9c4), +S(b797d0a7,4ed78f63,475364cf,fdc42fd9,8a3fdaca,19c7decc,cc7cf10,7cf2f8b9,cbae44e4,773eae4,70f777ea,cc108650,fefdbf31,723eeb6,a77ccac1,129c3cbc), +S(a1b4bb86,61ba1626,c55158af,f04dd2db,b9bec0e2,943d91a0,1b043756,3fdea24f,fb8977c,b1088ff6,e6a462ae,1b8cca01,a0f6c737,816c3b3,d28d8ad7,b42630f5), +S(862cbd75,f1b8115e,45497c3,ce7f1058,200c3bfd,d9cc6ac5,b65b2e4d,abc06241,ddb98861,50925a0b,1c3445b6,a7f418be,7d5ee05d,9b7d1cf9,2ec5b633,9b0a5002), +S(45a2e88b,38c2439,53a33a6,e75c1e83,22a9f14a,bfd6e7cc,db786490,932caab4,23c86383,6a2e35f2,b9b7f8e7,a88ce40,f600eaec,af84848d,10ee1739,7341516b), +S(ebd1c9b9,e01beb16,7504b3e2,80c00ecc,6f44e085,a86a1b71,fe13fd87,3df558e7,d5ef72b7,10fd592a,64020176,a4aa890c,99ce47c7,f3d01e49,349aad20,b6e38c74), +S(1db6b315,14f71408,e876aecb,be1ffe74,a09b8e82,9f05c3eb,18186e9e,b461696a,c7236c85,b7436661,c2edcbb,5247ecb3,2a7d62e1,6d4cdc88,a7648b29,62dca534), +S(51704f97,7873b83,2e36660c,59658078,5acf0396,d29e046,5717ef5d,129a3cd2,672722c0,18401e21,e053ecd8,a219a972,b57b4b1a,56a8c767,7c6b53a7,f0c77a8c), +S(da77e611,fc5ca13a,65bc55db,af4c6c9c,43a7fc41,b58c57b2,4d25925a,99b22bf4,cff8b8c4,a8d3227a,919899c4,201f1bbd,49cdf4bb,506ad705,4c8e2f1e,a6c9dac2), +S(e7daaf33,ef909752,654c1b25,376be54a,22d0b5a6,b35655d0,87a204e8,d1830449,718d5a10,661fda9f,e6bb3fb,a1d3718f,fed1e441,64adc00c,f752ff1d,35e4b020), +S(ea15fe2f,cd9ae892,ff561ad7,7cd2be6,cff695e0,5cbbc15e,444cb45f,10d13269,d3d9b9ef,722dbea3,20a07f39,bd1b52f3,271759b,91bcf24a,caa6945,47d05cb4), +S(60dcb663,ab81db6a,89176bec,5a6a381c,bd6c8b66,de4dfda2,6d50c407,964492b1,42cebc,b7972c8f,e97e440,fc64c330,e4cb21f,114b852e,6cd7dd35,e9c7eaf9), +S(a975633c,5a609935,9c63714f,a474b40,72862cdc,1a3b1bdc,dcaf646c,1197dc9f,51f4cdad,89e63175,49c37342,d757b326,2b1da11e,1617f4a7,b0441c6d,8a1b9664), +S(b5d14a97,7e06d85c,f6189346,bf392516,56f9e92e,3e3b95e7,200cb68e,7a9bb4d2,27979c8c,d556d442,4d128608,8ddcc444,849df743,ca3ea38d,e077f8b2,71263654), +S(581cf880,1cd23788,8be62ec9,e99f814b,939fa6de,f4497b2c,bcfaf8bb,f9fb217,a211bf28,117f8b31,28f353f0,a3ecd2db,d35435c0,79b39b9f,2d2ebae3,e39c2247), +S(38e354da,80f408f3,48af877,138b8b32,f18c1a84,a5323e3e,6a275bd0,34a18ffa,b22ceb25,690855e3,e4e75553,b6e9d619,302d7b8a,f00226d9,8341e406,4d5d9e9b), +S(a62c3ca7,31e863eb,f630dddd,c75f7a7f,315b1a5d,8ebd7659,7d63294,7651524e,bd2de025,270f22d2,41927db1,b2d83c3a,6c4593b3,c93bd192,ee490b0e,b4b896b9), +S(cdf7529e,32b73c24,39c5e793,cda2367b,8cda3ec1,12b68572,5fade16c,5de12859,34003733,4953c33e,3aca52ae,7578a837,64218bd7,661d15,e4e6b150,88f5372d), +S(b00ee5a9,eec1ec97,a673404f,b67e8b01,26051e51,df23ce94,1bcce1d7,c9c0be80,d0ecff3f,45fe1bfb,7d7eac6d,1b27f465,80b22bfd,2b2b0853,c382c06b,df1b1be1), +S(bb7bd0bd,f9b827ca,28e7ad35,e7e42ac7,ac667dd6,5f64f18a,2af8b385,774f7382,ca9903a3,6fab02f3,31afea78,71802d82,6e45fc4c,e7f1453a,ada65ac9,fd15942b), +S(c2e32d40,c675193e,a8097d9c,9beec3e3,64009574,11e46e7d,520b5fb8,44119d69,63c49dc3,5c2ea496,894da7ff,d8b33e82,c70e44,d0b51caf,6e9d6235,c8d78f57), +S(20aa257b,4fd347b,4361295e,bd969d65,60366497,bd0f17a5,5f9b8142,827081ce,c8a82baf,9b95576b,34b6b80c,2ee4669,8bfd4562,59ec9911,4b58bc74,cda90533), +S(35095083,4f7f8218,6e0a8085,2cf56948,3928090b,84d2c068,e0c3c4ce,9819c4fc,1d0bb1ce,2c061784,35df09fb,c21596d3,2334bd77,ad1206ab,41515089,93589b81), +S(4f731112,8d44033d,7380e5d9,71826f5c,1f1cc587,fbdd361f,be8974e2,2526a2c,69d35d5c,e051f2c2,54c8b68f,40033467,b516378a,573d7f22,8ad5e070,f497109e), +S(34746007,54abb4c9,2b9f1a9b,33b51139,114bcfb6,ddbe9e2a,1e9182a6,ba52cc5c,29f6bf7b,7b31c57,b83e9f41,a9fb151b,744f0bf4,bd2dfa1e,5a5ffd14,e3528ded), +S(62f72456,b06b6bbd,70c2045e,8c1deec4,d1ca74c9,aeaf68c5,52d424f9,be280edf,13e619bc,d667afc5,81d293aa,3bcb80e,fe3212a6,9750e45b,94740aa8,286c72cc), +S(b1d18497,47415d89,7fd3b791,9e2a1cb0,e47efc1,2f6dd61b,93da9d5,99cc3083,19eee106,bf3f71ac,436cd33d,9fbccc4c,2ba50ebd,20e93478,ff0a6c9a,96fcd5fe), +S(9f8bdabe,3e85c253,40047952,812a913d,f9d83038,d869f535,e5c7ae7a,c286ef9e,abae000c,3e24af88,242df5cd,3a3786f1,7c8f1a7e,7604be96,7495b6e6,7ec09284), +S(c3d3786d,31cbaf4,57de58c9,c3ac3527,ff40e817,ef36bd5f,34c005f6,2967989e,b39ece7c,3e76a6bf,fd14dff0,a066e977,6565bc22,5c26d446,5d6b193d,d37dd7de), +S(749984be,1953ea05,318445b6,52c970bf,32cd173c,3b222686,a054fce6,787f634d,43c4b03,c395080a,20d13e6b,edd78d74,7e9e326c,c267f358,43eea751,d6ae31f7), +S(8b345416,f6b91613,4ae7c45a,de0d2ba1,75aaa225,795d94aa,4c554a66,9c08f5b,2166a466,d1ea4969,fcf766df,ecb263d6,339a8331,7b342ed1,a4fa6019,23af6d0f), +S(af805191,730b8c9b,2ac105a7,eeecbff9,497c9414,58ee28cd,9bfc40c9,5078c366,ff3dfd92,1e3c1dcc,669a3f7,799277f1,591d0176,bd707f9a,442a219,7eb6ae4e), +S(c626aa89,da7a7971,c7923825,d31ab64e,2305ff94,1b724334,f8c8f1aa,ae60e0d8,325304f9,926dc306,6002e743,e3ae4ab9,b2eae44c,ee907075,fd179222,5c051c05), +S(7f6dc30c,271e6382,db40583d,acf2d121,8803d63a,41980369,316950a3,a1490878,a1224a09,8257f494,331235ca,9d0fb42c,9f5727bf,74e98d60,f624e4b9,a742c7d0), +S(f90f030e,30cf9a10,582d022e,b148e12,d442a9fe,2345a552,564731f7,6c9aa92d,d1ec7fa4,677bcd7c,ae9602c9,2cb9a486,1ce7f6f0,9e6c53b,210144bf,608962ed), +S(f9844b5,6b5ee53f,d41b2d5d,a8eba633,1a8518ff,4f2fb920,368a15b0,6bcb091c,165af5b8,7ff690c1,e5e44f78,b0f04f89,70b6a370,8100e86a,ee82d24d,fd10ef3e), +S(b091a817,66903079,42158c,acdfa7c2,a42526c4,f19736fc,aa62bcd9,2548acd3,5e2c1b91,f6059ea5,5595a105,5a7c4827,4beb810,59c7fdff,e1365be1,a6c2454e), +S(bb291c6c,a65e98b,4f075b05,becee4bf,757ced5,33d97edb,f4920c3b,82880d96,4abf12d1,e910f80d,47c81d41,ee9fc67d,59f8b4,5dbc58d7,16fe5d96,4420af42), +S(af63ce57,fe9f7568,8422ead6,40b64638,d474f848,d26c9cc6,2b89b457,4bf42ba5,abcfd290,320b7554,fe5ebf2,2554043e,a61397e6,6b1b6b6c,441ee203,da003203), +S(563c787c,a9c7a042,d1d8e916,fa653eeb,3bb455d3,d81d96ea,6c04021f,764f29d1,4f5329e0,9aaaa37e,997c09b0,47c924eb,1a9b813e,da648875,58365385,918faba), +S(6795237d,a651f9bb,c4603d87,cf14d4cd,9ebdc9b6,b0143c7a,97a99cd3,2715cb5a,cfbcc0c8,a4ca9939,e7050925,43becf45,59d953d,840d2393,2a2648e2,e3ee1078), +S(6d6158d7,3629a6ed,9437b26a,2c91e31,fb6965d7,505ed096,ee74ec84,3a95ea95,3923c2a6,ae7282a8,dc3e04e6,664c4bca,8842a0bb,95164731,5b47b85e,2b3c8bfb), +S(88a45a7e,512c33c3,ea439da1,e9715f4f,c397125f,e26cb7b4,227f2227,628a57f4,dc384c97,bc2c5e45,5133e5f0,21c0d3b4,76680c02,41e8e31b,b1d96c71,3164b7d2), +S(8cf77e1d,7a4bf247,18c29f7b,66946820,bae990ea,262dbfb5,ed63a701,dc2bf3cf,8d70e07,e7eae6bf,47d224c3,46bae612,329ee6ff,e39a84ff,640b25b3,9877cd6), +S(5bf3fc7c,c212a2c9,a90cea06,44503842,d9f5fe28,fddc0a89,b5610fbf,1a38820c,1e64ea7,193f3cc6,c4c62c77,fc27d686,1aacd775,2b66b82d,f95952ab,ca6488df), +S(74ffe6ff,73a6a663,40e6c2d,77c410c5,c1b46e04,7ff796c3,85238675,e3eb97b4,c31e7707,33d8ecaf,bfa3a3fc,6ace4cb9,4faf3eb5,445f3701,1de882a6,2a4915f2), +S(330b3676,9e60504e,e3225ce0,36fcfe97,8b74c62f,e8ab9007,ea1452f0,6a06ccbc,cf80c153,1165f279,a718ceb4,76e90d,3394d01c,ef6f159e,1225b2b1,51bc3c09), +S(471e94ca,1b8de1e5,eefd39ed,7b5f997c,9e9f20e6,fea65549,8ba33f6d,a5976c0b,ad5b07fc,2a5a049e,fd210e27,b849a842,749c5e43,f6321e17,18e20dd4,4d228c8f), +S(b8133090,5a4ead1,dec7dd81,df97aa7c,daf67e09,58f16739,e5ab2f12,f309cc2e,49fa5ef2,c2a95064,4ebceafd,732fcd7a,3a4c906d,95902646,e779dce2,4021591c), +S(b251f7a,36774d66,f98d89be,15e553e,d85d4bd3,2a170b7d,f4fe842f,d35644e2,cc71d8f7,daa8e846,5b5d6230,e2a25a4f,f92195e9,de33e32e,6970fc54,97001a40), +S(c0ed75ca,6ee80f93,5f7d86ea,8e1bb463,c90aad6b,145873a7,2884f5ec,a18dd90e,73ca6688,b5221c2e,6e82c261,fdf19c26,fd167035,d71f08c1,9190391d,b88efd50), +S(bdc5e903,e371fc46,828133be,5c4d72c3,3f19a203,c4800fc8,59d343a8,7c844c93,ec59e7b8,ac2b2c18,c51487af,84349cfd,f6842a15,cd148e9e,ded4202e,fa0579dd), +S(911cc60d,78c5909,4bd95589,61a99522,fc9c66ff,68370934,40ce6531,e730fc97,8b7c67c7,b33a60d4,bf75fb25,a47d3942,f6c95aec,5a9bc3a,4e8012e1,1274459f), +S(a5e02e09,a00fd3e8,fa7925b2,7206d296,eeff1b9e,18528376,860f2244,1b174f71,4fda8ecb,7fbb77a,dd05273b,ef51f2fb,c9abd87,eb87b9f,50d5a3a7,835e9d21), +S(36917617,6a66b671,684334de,9d6434fc,269197ca,ff36b95c,e8f36870,6e475e8,dfb20c43,78817585,552cd193,2b45dc37,b66a63cf,166560c9,746a9f82,ec3c4fc5), +S(91ded03b,67863303,92abd862,c2f2e870,80524c2c,c0940a0e,820c55f2,175d7533,95e7aed4,46172d6b,ea382418,5f1a5cb,dc26cada,26451556,81b55f08,6bb82f9a), +S(7d5a3667,26e40c76,923867d8,6a5b5cc7,58d84663,8a8f664f,a0b79d20,85824482,cf50b22,7f9d7889,bcc082ee,30d2f08c,1c18b2a3,7443ad43,86d6cf87,a59d77bf), +S(929edbc1,75eb61ef,f1a564e7,d843fe72,c4a49e06,1b704002,56b49b27,7c632eb7,bad98323,4d603b,c85d2747,2e02f089,850725d8,2d905c2d,12d1e730,24bcfb7d), +S(179206e5,861ca493,b3336805,4eb8b46,3a47a189,d4210ff4,5b8f29ce,2b8b593a,1abca34e,f7c9b56d,d72ee602,713b8fdd,ace3007e,a88d774d,40a6aa20,6c1c3e69), +S(e3548935,e28bc944,d29928a2,935e5bbf,a0285c2,337dad5,3fa40a07,377b4de1,2a886052,358b95a9,c25af629,e6d5d2c5,a7dacc44,eb6108c4,46c07af2,cc3977b), +S(e4092cef,884cea2e,51a5a82e,ff8a3ca1,6cb38a71,142ea0cf,476aa293,f9e63303,bac63e08,b0d90160,d8d937c6,ce0eee8f,c01af5f8,a84d2970,ef2c9f8b,ad1bda9a), +S(fb1294c9,c564a667,6bc88f4,90ea39ff,e2dba6e5,4165f6ef,92c90675,138c82a5,9fa392ec,ef922e7e,6bd19f36,99682069,19e799a4,be30125f,5563d3f9,46e01132), +S(ad376df4,e6025dff,693bfe2a,665a09cc,ba64f12d,1b4f9d5a,11e0c880,ebc745ad,fa246c63,fd5f84cc,d104c8b8,ebdae50e,3b86fe7f,976c4a95,c94ac06b,9c6df68f), +S(8f723cda,9a28aca,dfa0f86d,fbf2a831,700dc839,dc40392d,61904711,1f7fbf13,9bddb64d,75a288f6,e92b8838,5affe05e,1c07982a,2c9a8519,d20ed505,7acbafbf), +S(4a674fd7,4ef0139e,d151a994,ad3f859b,aa2c52fc,7766361,949ff86,a1159bb1,f0e5ed3a,ee6a94dc,a2b7a353,dc42801b,faddfcb9,4f1d5b56,f606d77f,ea4df16), +S(6651b5c,307d465c,1fd4c0af,c6edbe5a,e292eaa8,417db4ae,82b53612,66c5e7d2,5d02e21b,68dc7c4f,414c0cc,650909e7,cd46add0,fc91c7b7,98e00907,2ab85c35), +S(e6229fb8,c2a0a7e6,c9aa31fe,71e75cd2,292dbf2d,2c5461ac,a57bf13b,f57c073d,86aef20,5c78e3ed,6cba8445,49aae8d,cb548182,f31714ed,ba2e0b02,2d594429), +S(aa55bd38,39e91fd9,a6080dd9,46b441a7,193ea997,b1e6f72d,f735c675,56e5d7e4,66eda908,504bcd50,19a3b220,1a16f7ee,3692aeaf,ae8b265b,caedff43,19abb2a4), +S(8932bd7b,b1d9bacd,2fc5aeb0,6ad7dd4f,989a8417,793d2d71,b0c1ed64,592822b5,72cdbd0c,56b29915,54b68484,b75dfb3f,fe04eef6,5d522c55,d1c62bc8,8615f9da), +S(10f3bfd0,ee76006e,c113a1d3,37a5cdca,3601da68,1ec1758b,d1286304,a49808d4,89a27069,cb6bcf5a,8848d3b6,7d65c529,749007b9,3143b395,87318e90,4cd4b53a), +S(dca42b0,8e19ba70,db8bfcea,e52da664,956a3a3a,fff18dfc,6f9d4ee2,7194cd14,f6c76a86,eb3008dc,206d76e4,94ee3224,d345f4dc,ce44b54,fa5810e1,903a073f), +S(1251d8e4,9d6c61ae,a266acdd,53be9579,c993ceac,1c62db42,94a4ec65,e942b305,2a722ec5,5f800261,a937883a,ecada795,efa50c56,f12fcee1,20f81ed0,269cf5f9), +S(28b48ca7,c8c57bcd,4cbf70c0,81e46910,d1964ad1,af2e2305,184c3e2c,d7a6161d,3a7a1202,90d5ee64,9c4c1bba,d43d7e2e,6a5710db,924d3943,ea06a6d7,ffbb3bd7), +S(675a33aa,76d1658c,54a956a9,2e8f6487,b24e1417,a179cad7,c0c93cb7,6f8b7f50,8bb59b9c,94156814,a00d2621,d0fc87a1,be4c6165,33704160,82e825ba,62845cbf), +S(8b5b6b75,1d7bcd6a,dcc0f5b2,6e231abb,9d613ae,f80a561a,51463d22,e0ce9acb,e0b17875,6c146090,fb03f5aa,b952d904,3a0b45d1,d1a66b8b,3773c94c,1c657ba1), +S(35b8251e,bf562c69,2e0d11d9,dbe01290,fcebdac1,fdb9f467,9b5c2094,9a0517b,82dd2707,cb4b6758,ba7e7b09,cdfddbb0,11920b0,9ffae6ce,d3ad2e1c,648eadbc), +S(a9ba52e8,4bd13565,1ae96df8,bbddd59d,628657c6,2e0a133c,e2f59a01,8c8efad9,bac10321,1f614972,70c26dfe,47060b9f,d50764c2,461c9bd5,11bf502,a0b83d28), +S(eba36b0a,c20fb216,f8a4d8bf,ff21a478,d80389ab,51d6ac20,df5b2b41,834c56e6,60440923,e9c15c5f,72b7dbe8,5c3c13cc,58fd4ab3,a9a99ca0,372dbdb4,d4af1658), +S(e47ef3bb,b6f8cee6,11c05d2c,681a7fe7,2393628d,77f93adb,b875461b,712440cf,30989ca4,57112c77,2c2cdfb8,bb9e3751,343e8455,6ac9e86,db43920d,8c20d3d7), +S(36b0132d,2058e379,c9b1b23f,c13de925,ff61d8d3,4e8c37fc,afe17d92,670fb23e,5fd9aa2d,43c9a6e3,ddd8752f,9a3bb676,c4049d3c,f849274d,34a60a95,c4c19e0e), +S(dbe78ebf,6db49199,70c4f04e,56e62811,d0067aca,b05fadaa,bde4bc0d,bd2b1dbf,9b40dc7,b2a4fe2c,cba721ee,ffad0810,f909353d,ac53e731,945e418a,2846a8d8), +S(19da9bb9,e0b2626a,c9069f24,3292462f,2394e209,82a7f8d2,fd0bdf26,ecd61d00,3dea2ad6,50c8006a,f4af6848,56348dce,53d56d61,d7f03cf7,aec76a72,559d7c13), +S(25d7a7f7,24bbaa17,83b79913,25ab7c40,da5f3d91,bb13a8b7,8101e970,b1295790,1b675e72,354bd3fe,21c0884e,f0a5802e,45f8fe8d,3b0c0d92,7a53741f,231ae06e), +S(a5ad3cde,de3d64e5,aa1ba02b,10771048,8ea62934,6781a0dc,ad93f3b5,4c15fcda,d14651a5,823fbd07,4a107950,7e55089f,fab0b4f7,5e8021da,767528c2,2e37d72f), +S(b2c32ac6,925348e7,1adcc149,656c21d7,3343d7f9,a97fc90a,6c0ecb9e,4835fc53,a2fbf853,602cf32e,881540f4,eea48400,6a67568f,4d69f2db,3adff02f,9b687716), +S(de3610ea,e95e73c0,fe303cc2,9b1bae4,c3ee5009,a5751e40,6e0dc64d,c2128809,83fd3a89,3e9264f6,b0d9768f,b2137665,65ddb286,9b53279c,b7ac524e,e8383e29), +S(d91d23de,8b442f29,d0ab4a23,182a429c,299cfde5,8f2f991,53139d6c,3028098b,e00a507e,48a68d49,c489063,39942d9d,a7a81cce,6865487a,4b18b34,b1b2e65e), +S(ef90ef91,265655f5,7d776fe1,a153289,87052919,448049c9,b3342a94,9f66dc83,a44f99d9,e9e3cc67,9b819232,14b4de83,d95a65cf,c3af495a,2e961a68,21511c54), +S(aecd0136,83f0c6b2,d9434651,94d6d6b2,c727d3b9,3409887f,821f0bdf,ce30101,59b3d669,1952dcd1,bb351f31,aa281dcc,b5f7cba6,a612d5b7,7d3da3d7,92da741), +S(192c250a,31468e22,56c25dde,ed840d9f,e9da10a5,b9dcd4fa,505f418b,9993c86c,e311e20a,cd56146c,c03db59d,799a1d51,e3955b72,7137daf1,5dc8939a,3e7d0f85), +S(85aae3c2,2a26d60f,c14c46f3,d789cf89,5b23cd96,c4515ba9,87609fd4,dce41a3f,54bcad5,166281d0,bd33587a,52a16a3f,13d7b1e8,8bc009e8,7c4f59d6,e13ce99a), +S(24dfbf0,c22d29d,bb3f59eb,27dc89da,7c0a83d0,7b42445a,4993e205,43a97bb5,64858a97,8471f3fa,aa838ff1,b3ecfef6,1d47e3d,bb684028,bfd6c194,dfa05928), +S(909ff9e2,d591a673,40cc7df0,e73be5c0,ce19c4a3,24679306,995f6344,bd692f3e,5b956095,a5d4598f,9dfd693f,893ccfc7,d77adf8,bdfe9ccc,8497125c,1c07046f), +S(fe24c76e,900f320c,c41bac2,e625293b,ef871944,b0586680,3e0848a1,e15a60f,ae054925,3338878a,b1e8d268,b6feb271,512aba65,e7e8b243,7fd4867e,74b5fc30), +S(7704fbb0,13a7ccb,5b0c73d2,cf6fd87c,ce4c8d8d,f49515e9,9145b3aa,e02b2d6c,21ee85ac,405e2cc7,c9fe7a8f,7b59c71e,82dbfa33,bddbf113,64435f8,53139dd8), +S(e136bd1c,9b7cb6d4,aac07f42,1f1da3d1,eb9a8935,dcdd8097,7c137daf,869d7c11,c9d44b0f,92b5e04d,aedb2155,eb1930ea,802b205b,880db2f8,62575a48,22acf521), +S(c6efeb81,850462e,72ae763e,2c1d2f39,741babf9,5b7559bf,c28d263a,8944aee8,f6bf9cd9,413259e7,85490c49,cfc74576,c23bf0ff,9599b877,2acce426,1d3e273), +S(5d09a4c1,1c1d913d,d83c33ef,1377ded6,7affae57,899b5742,347291b7,c434edf2,15a6d501,a857e00a,ab42d1a0,525089ec,cc48d185,7f5dbe69,e3687bb1,2982cdf9), +S(9989c1ce,c3865ba2,41cbfe91,1b72edd2,ccdb8b44,9a837284,730b903f,b45507fc,81cfc11f,e8de5fc,6f850c66,21bfc5d8,9d7d2bb9,e8b9b2a,dfd23f8e,d2fe8d40), +S(c8d0b073,2930e2db,f149c156,c5957f79,fecc319e,f4abe588,860dd44a,d74779c9,bb96deb1,e23ebf7b,afc79ea6,ff7fd012,e2faff01,8f2d17fb,38fecd52,29aed776), +S(7ba25516,877adf65,6719f4ce,e867b4a7,3d7bb18a,735a6043,47d5d5fe,47be46b6,f66f2364,5fd24d13,39407ee8,241b07bf,7e6a08c0,d3a1e683,67b450b0,f3eda69a), +S(be8f83a5,5e50defc,b8357409,3b727cf3,578a270a,c478ada4,22e0cb8f,907edefa,c38ed801,1af0e3c6,55989b08,af329cd,340f469b,d0bbcbec,6504cd34,aa44ab9b), +S(9bd6c57b,438e1ede,cfba0916,d744ef9,8b010164,ba46675c,1206d9cd,67c3380d,d15ae82c,33b85d22,9df4349,ce48b582,10c1baa,689fb6d0,51721d22,334ae972), +S(e8927a5e,9f511cbb,ef935f7a,a90c64b1,666c8be7,1445cc8d,193ec922,1662177b,cb6f084f,a41e1bf8,110a98e3,bfaff1,43ef6ccc,56170ca5,de520a6b,381010d3), +S(c4243e89,4608658b,df46225a,85da8f71,dc75464b,fa29dba,6d096423,81b77ea8,d501050b,89abe5df,fb9a11e1,6d1f2bb6,d081b20b,4f0d9895,70ec128b,21e2c124), +S(582f0c51,20f5c79e,76dde6cf,624b11f8,1e9663a9,5eab0480,8d4156ea,61e70723,1f0c54b6,1cff944b,b9bbae8e,1d2570f4,315e3c8a,f067d289,3d9860c8,4885d7a6), +S(d384563e,67e85943,67725600,81f4287e,fd7c6fdb,6e29ee62,ff4f447f,91a4882a,b90fc799,7f76171,c7a76d35,7aff06b,df5b3d00,a1d6f089,bbb2acb9,e749b6de), +S(5655f9e3,5bdea0d5,d7d023d0,7a5d415,52c39f1,a9530241,55b647e7,e757e40f,4f60c357,bd0a7577,475c8e5c,9c6e099,1a21523e,821cbcd2,665d1ead,c6075a39), +S(b1209637,51d5e9a4,5bfdeafc,5aa9f45c,9c29681,2c4769fe,6db03118,cf0a2d53,eadaaa67,96ecf2b9,57944958,c9fb1cf6,986f387f,50d1387b,d4b94eb1,aed1e625), +S(bb6ad704,477295a6,710cdc87,f7df5c4c,c3b82fdc,749f8464,474fc61e,b307d4d6,7d0d1fd5,ea113783,7071f705,7bb783cd,a4b55908,9af6eb59,1d6c18af,434ddb34), +S(3daa25bf,5223a09e,fbfa63a3,405e8c76,b059bca9,38d513cc,693bcfbf,514cbd95,e876c903,22d97d60,fdb0cd64,cc9ad575,cebde9f1,41d67c82,7f542034,5c7c6ec3), +S(b32bb726,3f40831d,a8e00e27,db8ce14e,ff1ddf5c,4e48eb4f,deca0531,3770c016,916fe7ad,2726bc93,c242f50a,4e3e69bf,db965402,55440262,ccc5c055,136dcd4), +S(a7f331b5,26d74b9a,67ff3453,2399ba79,4fdd4d1b,1b99dae,1b7806e1,8a0a7f11,786b90b0,72c5a702,12db8173,2dd486c8,ba59c937,ea9182dd,f85275e7,d6622c6f), +S(30086238,dd36b617,f8505367,a015f6e0,2f14079,3b4dc5a4,442d8628,1ac8caf1,9b87d837,644f4ec6,c161c8c9,ae923bb3,f40f6cb9,6538c0f8,aa8c4ed9,42eccc8c), +S(1ec0343c,f9afd13c,57ef2b2b,4006c740,dc03bb3,62ee8129,c4cb35a3,299b1ab3,8b645dc1,91012651,3df47f7a,e33f201d,35cc1d73,2184952c,f605f68f,ba8a2e34), +S(e8059ca5,3aa197cc,3468c797,81b36245,4ebd8b86,7227a9aa,21816967,52d28587,39f9b33,e91eb4d6,fc769d6d,1b43fc0d,ee8f1841,8c682c96,5beb1e7c,9280d23c), +S(fbdc998b,96eade37,61e0b0df,a6c4fa5f,7794576c,91d5dc52,f9753e3f,748c5afd,4789bbef,e1f68f8b,2058e41c,c513858a,29a48cb7,be41ce56,248ffe3,996d043a), +S(3ab5a2fb,fbf2acf8,2becd224,4239ff2a,808aad64,41b1b47,1aaa9e67,12bbc29a,d20c99de,14e44cc2,18a42ee5,34fed723,25f225ac,8c68f2ab,d6c19341,5921e5b3), +S(94b611e0,63334b9c,195ff7c,894cabc5,2ce902ab,5b17a572,1a697c3a,8a4903d6,d8d70dea,a7d8fadc,da7eae42,3ea8cc29,285c32c2,30a8731b,52710126,dd03769a), +S(2cd6e98a,65c1ec8,6596781d,4239a71b,8e0c8a0,4c3dd8fa,c7925a07,2c246e3d,67bb6602,75d229a3,a28f51a4,a19cf6a9,f138f72f,5bcc2ce7,c689d699,b23a59df), +S(500f58a0,e8929d68,f4fd8e13,5fea7e6b,afb562a6,ce1086a1,19871799,c5a4f2c8,80924142,bbe02b2a,7decc045,23b6c132,af14283c,6f715abb,113a12ac,a92b4205), +S(4c1ef59c,5030213b,dab7be6b,c3f4272e,b7d4e07e,981a3160,cde6797f,821c507c,d878f643,a0f82a73,d7c9928d,ff243584,77475dbd,2076e7af,aa1c54ee,e66ce565), +S(b69d8ca6,6b0dd8ef,df2e7c11,1dbf7876,a3ffcef0,424f1943,49256446,78ff24be,1ba714ad,96ba9f32,456e4288,5b9d018a,f3cbb43,37e5a0cf,ebcfc5db,9ad76c87), +S(53def7f5,bbace323,cb0a38f7,2268fb93,1e4f546f,a72e5b5d,2d5733eb,6d39dbb4,1533c9ca,5c0142e2,e1e1ec89,d0536b,282cb784,7ae5245f,ef978581,e3aee5ab), +S(a7f043ca,731d58b4,c5048ffd,12028f94,bbcfaa96,efc52a94,6c78c42b,748ed508,8ada0d66,1aeb2b7f,36eaa00b,56424547,ea5af2c7,954b8801,9e8e62ef,ef9e1832), +S(7d3609c7,7a0cb4e,5294c831,d05d9028,e1d16d60,7495da06,b241a87a,23fb93c3,9ade4159,fbe98e1a,41297877,383f023b,5a7973ee,afd17af,65ee4753,d24a4f9b), +S(a488a3dc,20442c4f,aa127f1e,28d85b20,5681be3,311e5063,c7a2a356,1312569f,4325102b,66f100b5,7facdca1,7973b3a8,f9cc5d97,3f018e4e,7d035e5a,5d2549d6), +S(9c340a46,94b8bae9,d7e6a922,db9c750b,3089101e,946c3e58,88a4222b,42a05d9d,cc580dd3,679db392,74ab94c,d054f264,42c9ff72,5cf5c1c8,a485a48f,8f571ede), +S(44a788f2,c070a53,5c4111f8,6cf636c4,5ca83338,e0b71781,44e7c542,c289480a,99d57358,ee53d719,9acf8ee8,b679cf9a,5c44611b,bc17a734,caa914de,25d7b22d), +S(3039da67,d1d2a063,9b92c0c4,c7c6f415,c142acdf,ce21bba1,98de3bcd,ee9bdb9,c11845fb,32021c59,8d7cb0a5,a7c3da2c,851306e2,75af5398,e406dd34,fb5b167b), +S(6381f67,a6f5e9d9,535ca436,c92bb8c2,9d8eca9d,b335e159,fccb4609,484d401b,9f480076,aa6715c8,2fc04c58,d30cc445,156b7d9d,b1e4c1f6,3744ebef,5060cf4f), +S(7ab7ff64,d2955841,1872da55,7ed988a7,ba182fef,480d36e8,3b65f1f,cf0c0c3d,76262668,bd45b55a,dd32839c,591b6a70,9e4e7ce6,e9fdcf55,c78e9e83,dbdd6096), +S(668e29f,6b3dcb44,14e4c22,cc2fcc8b,3a20c00,89f94ad1,3f279c1a,41d7df7d,4afeba02,4ea185d,caf130cf,f7f12af7,7dfb3cfb,1871d641,83dddeb8,86545563), +S(9fde56c3,ac8016f6,ef6dfdc6,da621198,501eca9e,377c594b,e063b24,e0721dd0,dea4c586,233873f0,3ebab8db,900b4c21,6df32c7e,12b1f1a7,be26d46f,880022b6), +S(70f3ea86,cf318a63,e44ab07e,a4cdb22b,929e42a8,9c1eaa0e,a0d56bb7,a9d63592,eacecebe,3e94160,bf370703,2fbec0d8,e83f5bb1,429ecb12,4f11974d,913d4332), +S(68794d4,cb77a07d,f2d09cad,7b14c8c6,a8c35da4,9cb9be35,ec6c19d0,a3e4fb6c,aaf0efb4,5be195f6,29b8ea14,ec137e33,f14cb692,b3aa59f5,a71bcbff,d8511633), +S(708c3036,27cdb4a,58ec9884,6c23e392,e7d8e1a,c7c0dbd9,d640dffd,23938a24,113daf12,a5b57f22,fbdebece,3727474a,8289c4a9,2474135e,13970c7a,d3802084), +S(c74bba7e,2d764df9,e6e76441,6b40e019,5caccecf,75c8f0b1,fb3ca353,2236cf10,a97b858d,1ada13c3,3ff98a0d,404e3e46,768ecac0,b224b965,7d620c3f,ce3aad05), +S(186dec13,501477b0,dcd69175,c57d33f6,264603be,256b3029,b5f9dd9f,fcb5ceeb,59a646ac,96924f8f,cc02e6b4,14a2234,f49d78fd,6b64dbfb,f8baa0d,8acedc77), +S(94486ee,b0535256,ecdcdc9,576faecf,9cbb7c12,8286352c,3f3f249d,458e8ddf,4e5290f6,bf22cdec,8f7d4617,531562ee,f7402174,b13d149a,390fd9fd,17ec3e7e), +S(304f7074,5b9561c0,7facf83e,8e593af3,cff8d174,2d2472ca,bcc08ee2,9b7617ba,77654948,8a95197c,612d6bb9,20e6c9e,b2c2236f,5e28ccd5,6744152,f46ddd9), +S(97046baf,d42c5a5d,b8b892cf,7c36ea67,86dee4d7,bffbd572,20f9a122,26038a5d,7ab1305a,103c1cf5,a77f298a,489db57a,2c9148c3,6a834da3,ee108971,8eb3d43a), +S(e4b52916,3f73e5e6,45c44686,3b786f53,46b048af,3d1fef24,e80ded13,ffd89b0b,7409a638,452fe0a8,7f1e717c,b0e3496d,14b9e3f3,e6f4d048,52f622f6,ba4ac2fb), +S(b9d303a2,75452bee,7800cea1,1c06db97,4057adc5,62bf5aa,41c34e5,18f5ee9c,4c818cd8,a24b7775,35ed8738,bdd8d45,76408c87,ad172563,6c536ff2,ce6475dc), +S(fc459ce4,3283c842,1a16554b,d5eac61e,3e4b60c6,2b090c52,465788cb,120d2295,2b2e75ab,10a60dff,1e11bddb,62457bd4,585b262b,e671f5de,84ec3bef,d5b0b232), +S(19828f90,5f901716,bafd9bfa,856e8fd9,c19eb83e,37c8e5a1,11366a77,11a26790,5bf76d98,46398c34,6b021018,6dec4ad8,c03b866b,e0edd8c3,9f09fef2,d7c38bba), +S(e10dbb26,999ffd14,f29fb5e7,e3b3b78,1519e63f,ea0fd26b,b1b593c1,8267dfa9,c3c04bfd,799303ad,de767ff4,2baf9759,82c48d95,5f127ad1,d59ff73d,cbfc456d), +S(2e53cd28,acba99fc,6763f788,a644e314,1df5e17e,c50003af,48206aab,d81a3396,4393815b,db8dbe25,6b0269f5,4220200d,278fa537,666b5cea,34cd8e77,854ac02b), +S(f6d174c9,60516f44,6054b7ba,a0f82557,87ac2e94,c966762a,f7c428c8,8b9de7b2,68ff3c54,a3257f1,7b27a5a6,ee7cfa88,97493d3d,b0899b47,c56d4950,ba263a9f), +S(7d18482c,704eae8f,c6a33f77,923d9063,eb3e8e5c,28ce3d3d,8ffd3e17,ebb82881,a126d78,eac1033b,a223cf66,81faaf93,bf523dc9,409f03ed,abcf241a,b0a6e3f9), +S(b2c02f09,b930691c,a017197f,bfefa1c,bedbfa2e,640a66ea,fcb1c11d,f574d9f4,19fa7f66,cead7607,d404c33d,2491a6eb,ea0d3b00,4ef41bbe,13148508,b0a9d29a), +S(253d6786,8bf2626e,acf690da,8a26d777,bf9807ae,ccec3804,e1b7808,bd16ab91,145f6933,f9ba0d51,18eb8985,43a01106,bc702915,373bfabe,4ac970c5,27c17a00), +S(6e496a5a,28a74cad,4b4fa30c,48dcc62c,3f4b4fa7,e8151a10,3540aeb6,70c20d14,c7884130,274649e9,4e61623a,ead39ff,ff3b8a4,526509b7,7ae8586b,fe315ece), +S(774a8bed,36e7eb32,8e89734a,e5c0568f,f1659e3a,73890010,ca4a0e6,dd24a4ad,cfdb3a1c,1d8bb371,2e8f2ca7,2c578568,9db680a5,68c18e5d,4e423b84,df9fe798), +S(59bc8e0,e63848e3,79e0912c,4a0c9572,10023a93,a0dc4303,7b3b9e1b,7b834762,db8ceeae,61f6adf4,ac08c5fd,586209e6,f4879fbd,6aa9a1b4,4c67b4f6,69eabebd), +S(46659043,eed0a625,42513ca9,678cef04,2fcd952e,29be4926,fedf79ff,acc8b686,3a5f51a1,4c9fd813,3f11ee7e,6eca075e,f90c91fb,a10fb251,250b4cfd,9281082c), +S(aa92c411,308d9d48,fb62d7a1,2999083f,c52b5d79,196dc91f,e829ef04,41745aa0,d70ec349,f27a1393,ba8d57fa,968974ee,ab0d8e81,a497415f,d38e156f,bb029864), +S(36382200,5bea75e3,8c2483f3,eb95f6b0,a7f53f10,32bfb1dd,537cbe0f,4049f56,c9b9c28b,c2bf0056,91eb3e99,2efd5bd4,ffeeffb3,e7fed235,79af40e0,961489ad), +S(c3e4fb46,e400fd1f,e106c056,838cfb2b,c1cbcd66,ac9c19bc,e7df1e29,a7bd25ba,96b6c598,512215b6,a30486d,9f8b0c91,4589022c,194df5ee,30d62c2a,b9e83fbf), +S(71105f47,e372fab4,81cf29b0,ab5605d6,84c00224,ae1b9449,7c8d3c59,26077cfb,f7218aaa,d2a95c0,55f30f69,3fc087f4,101f5db1,1c9ce88a,629c5711,a1f1ef51), +S(676066da,6bc50ae2,e2e46f61,dea75ac1,12cb085f,2f00ccd8,5fef1e47,56059f3f,ea9e25c0,6c19d572,8b4bb333,35e94202,d252b9d6,33a1b04f,a7b4129a,2efa83f), +S(2616418c,11f5536b,c8873830,9758a819,f7b30e86,f4a16f90,ffde0685,e91a12aa,80b92bae,591f59cd,8d480401,644ac3c,940e917b,a32e7a4f,f4a2d5c8,cc417de7), +S(3bf5d07c,715fad35,45ff092c,18cee285,3de0d50,c9d68225,3596eac1,42111d18,e382d006,2c4b4536,c6432557,afd0b909,fa047ef3,1cbf2d8c,1eff9ea9,9a95fac0), +S(5e9d4316,db96d6c0,a5247809,8b22c654,7d873b1e,a4089071,86f81da8,71d057b3,e22c05b7,dfb5dc29,c07a735a,31bed0a3,2e071de7,41d734cd,dadd832,1dfe56d9), +S(3c153e81,e6ded587,dff1c8a3,ae5758bc,58c271ec,aa9dc005,1441ab2,a5aa123b,366fff49,b67b57f3,84b5f027,83b02d5a,f731f3b5,c6e8c089,949a0f2d,998636cc), +S(187518bf,347b87e8,e9955bca,b7937e80,7c41ef41,97511d9a,daa50f3d,9f628708,15f4ea6e,17a6649,36a9c04d,c76ed314,64632d23,6fb6a9c9,2aa0a4ca,afebfcc9), +S(edae6892,ad2cd7b5,9f559f88,b2d72fed,6bb27aa8,c7351194,388b38eb,4af9a6ad,e97c8ccb,225f734c,8416c605,52f24689,fe0e4f10,2d62ceca,d78d9ed8,7bf3c3c1), +S(e8bf332f,26d4471e,fac8264,2b3e3cf0,6c210792,ae39d343,d7c7c4c7,46ce79ba,60f53327,95e2a862,f6d82ed8,5e2d652,70fdfbe5,8118033b,105c3c2e,53257b73), +S(cd1eb398,4dc73522,e791f8ca,ac528da1,bf9c908,e446fd9f,7bdf4016,51138d2c,8a845cc,74325e82,14be35fd,cf520f3f,2a64240e,18d85bb2,18d97d0,4cc6b366), +S(7d7bed7b,2dc04b84,5b9b8460,e366d1d7,a49d87f4,45998a12,b6e379d9,461b035,bb7faea9,bd2a992e,1535cbcf,bb78b955,f89d8f81,ea650384,75399ea3,fa63e6ab), +S(b9de73cf,8fe63fcb,56b992c8,668e6368,7672c856,1e9be11c,9de51d7b,8eeb6516,c6884b86,8e115321,1bb98a8,1ecc8165,25a8600e,69155f49,fca83e5d,7dc8e0c1), +S(b5622f5d,2ff1b4ac,5b1a675b,192dc2b3,595a43cb,1120f249,fa55f7a2,69e15b8f,d8f3afc1,388938f1,25c3d4fb,fae7bbdc,93925fa6,e46298d4,e0d7a3c5,451ca1b4), +S(eb0e1fb5,8a74273c,c8912e76,5f150947,2cc12c33,2329a24,a7f7423d,83a3a049,e3b4fa95,1b958a1b,92b3596e,9e8905eb,934a121e,f15cf758,a5112575,4702caaa), +S(232a33f5,72cf2459,fe985373,2de8fa5,df1efe7d,32b14eaa,43190ec7,6a9450a9,144ca6c,7a114e35,37434426,699433c1,fb0cf4a8,bb9f65c0,14011849,f962b332), +S(e32e4c4e,b57ee32c,173f08d0,ae571335,cf4fa22d,d32e7754,740f174c,d8914ac0,f0669f6b,12525ee7,3d1a6e65,af27124e,89df20,5829eb27,2bbef862,ac053ada), +S(d89046a4,a915391c,856fba77,d4699c48,2b72200,4efd83f8,893fcc1d,f944e2f6,72595560,28e14090,c76d1219,9d133bb6,156a2cd3,aa5df1bc,c18c8b58,27a2ce04), +S(ea2fe94c,ff11c532,6c867e75,7544beda,8c39bbae,c3c2b8a7,62c3fb5b,5dc0b23d,10b02985,baf66352,e86f6e9c,a2c0cdd2,cda7ef48,79460ac9,d58f3a61,16663437), +S(71b224c3,7088851,25ed762,3caf674c,5e3863dd,d5eeb116,29a056e8,b054dd79,6002d88c,2fe7340,6dbf9c34,40eb5501,3a3757d,831e5f96,b35605fe,47fffe92), +S(29568f1a,11070ddf,bedb2f41,10246352,cab977f4,dd6cfbcc,be397575,dbfd270a,a68279c7,440fe321,fabcd58a,f7ab6923,e0f627c,909d6ecd,d009d130,aeef7b7c), +S(57badf5f,dd22af1b,11dcd60,e875d9b6,86e043cc,d4ff11d1,c91089dc,cc8230b9,7507b060,bbca59a5,aa19f813,eed95faf,8569dfa7,6d2bc327,660a06ba,8fda2b3f), +S(30d84aac,10a7b86d,d55fca2a,377e007d,1f8b8cbd,4fa9d7a1,4eadaf8d,d6481491,cd1df453,b553de9,1ae59e95,d08fbf64,eb9af82a,d0d4fc46,4d1574b4,f9131a3e), +S(79ac7c66,ff73d627,62a749be,c66c589a,67e33546,7a13709d,d72d9a01,98ec405a,803f34c1,e8b06902,52a3805e,abb30bd8,3942f1eb,84433ac8,57d22cc6,4ae0b04e), +S(6700636b,cf6a757b,8afe6fd6,d26def0b,6ae61da,ba7c502b,2a34301c,203af68b,91fbf4a4,c94105fa,8fa7de5b,6b6ba4a5,f34d677e,cf732db2,b660db50,e6a654d8), +S(84ab5f25,501abd97,a9d56f3e,5fe50bb4,4c2baae,85509b98,d38a91d9,74dad801,2dac84da,6b805b3f,6ab306df,22e254bf,d6c14574,f0f42be3,8d37cefc,38dde8d5), +S(e372663a,7464dbf5,48f0d0b9,c91867d9,e76ebcc4,ccae7105,7046b8d5,360365cd,6e80f9a1,21723a6e,da7dc2d9,b82afb01,2e3b1712,c7ccbd3e,2fe5b4c2,270e58de), +S(4a9ea0c6,57e21f97,9641f891,8975dfd0,28118b66,c9a2d38f,8b197a94,bdbb09e8,815246c3,2173ced9,13a82877,393df34,f8de1b75,c2b42abc,7dcd80c8,d19f1b5e), +S(a05157fd,f91c475e,97e110c2,969869bd,31435fad,2aa242fd,c4ac2e3c,c845b0bc,76d82bab,176ca9f,c3cb1b25,541e0407,91b79739,2581c4d9,fdff832d,3685ac6f), +S(bbd11f9a,62d74bf2,49e4831b,fb253ceb,8e94eeee,bba1d08b,b88ee5ea,53e940c4,762540c6,24e7ec7a,487586d,727949bd,d4d7162f,b5d1dd69,3a10f6db,f41193e4), +S(a7fbbd53,62d41020,6fddadf2,36782aaa,f33d5945,5bc00106,9ff41bd0,41cc53b2,aae57e60,607a0d7f,5d12da7f,62a51075,5aea3686,5b12b678,3d27456b,6a2f8a04), +S(6d984c7a,816b611c,8731f553,2ea1e6ed,54717a1f,4163ea72,9825bbf2,814050b9,c551d373,8b815e9b,5256a8c6,4152db2b,d8bf881e,c10254bc,a584f7c,f5dde7d7), +S(ccf5595d,81440526,6244e5fe,87eb293,3dd5e684,b90d58c,1eade733,e7c1d2e5,862179cd,ed77b0f6,1adc0f6b,334f6942,94d71057,f42a017c,9920277,3021dc16), +S(e0b6855a,e19ed610,51c9fa8d,4bb9834,a27e999a,81d4584,1945963b,8c5ba5cc,9626aff2,cc89288b,768fe91,3ffa5ca6,8a99b9ef,d904677c,fdd02892,815ec4fb), +S(4b3347b9,62a0b644,4942cf83,a30420c2,f164bac3,7aea2003,ebe5d232,58dfa3d3,5e38a814,d2ec02b9,7f12afdb,ff857692,e9ff35e1,1ab85cb1,613393cd,3e36b365), +S(646ffbff,5ff88f03,863722db,f554d9d2,64a4e14f,d2ffce79,d9f965bd,aac5c401,335e01bb,bd97b4c2,36d18b0f,53ff37f7,f5fc39a4,79092a76,1c159e56,c2162340), +S(977b9528,ab51f6b0,1e7a33d7,2a85216e,e5fc37b3,c0acb9b2,de3ecdef,38ea1e77,b16d9644,394c5ea5,2c7aa42b,543763b7,1b4d284b,a81c2fc,e4866d87,b1a65234), +S(3e80074c,b8c8b1fd,3dc97c7d,9e79fbba,1ae672fc,5eb43b3,c1ca69a7,8b70224e,6069492c,139fbced,707c65af,1e97270f,818af208,738a5b33,f73ee222,a90feed5), +S(15b035b1,108ad096,a201b0db,5cb152f9,793f9355,22e8d68c,adedbaf3,eaa1824,a95eee2d,e2f7fd5b,1d07c262,d07837a2,20683b29,805cb5,a19febb8,424a33e8), +S(e195cb6d,d4c21ad1,f054188f,31664108,1f029be2,22850118,8a6464f0,a2a93449,9d1babfd,9848c2be,15c89136,a3aec42a,8f85c2b,f91613ac,12db2737,b6bf41d), +S(1a309895,5513c42d,48db553b,22e27fa8,7d823df3,2ecdbceb,45ddb4c2,8d874bd7,69c52bdd,8835d6ce,99e3afa4,259c1513,4f988c24,f64fb913,c9353775,7c86df9c), +S(83aced50,fd6ff475,e135c85b,c705cafc,7e5eea1b,c6b370b5,728ab888,54ec74b4,d0ccd0a3,3e276d64,90079d05,4aad8732,6de6b6db,5e909fa3,c2546d4c,aa9fed40), +S(f2619c96,b0e5ae71,fa78c661,b40f321c,f96d6b25,ad8cd2a7,53fee657,4d41b147,9ff732f3,4c68e66e,6940e4b0,e5d0d94f,f223d53e,6900c80a,eeb60778,1d64f77f), +S(a49c15bb,3f6c8aa9,11117942,9f609456,ee4380eb,3fef3073,ab0f6c1d,33a4e3f7,70874663,301c27ff,551962a8,6c561ba8,6f1b36b6,20325864,a76faa52,31cbfa26), +S(e96fc9aa,2e1032b9,2a9f5263,4c35b7d,f583ca,fe774756,97c33a2f,703197f,54a1bc34,1fbcd484,34d1254c,73b9533c,8cc11db5,92363fff,10a996a,864f79b8), +S(64489edb,18791a7,f1f4be16,ac93de2d,e5445cce,ff8172d0,bb467dd8,e7971d14,5c343cc,b6723d79,ec75ad08,69aa1308,4180518a,679bff85,6e8b0e3c,21c41115), +S(9ef3f569,84c53365,8bb39b13,9271e54e,c5d376c6,f9f533d1,adf94921,ea7c066e,f87998e8,831d20ca,1b611314,7e426acf,768ca63,f6b7eabf,a4e6fca0,ac33c377), +S(5391ea1f,ba16db25,999f093d,c8308dff,a2ef9aca,17cea315,6c974bf,28540218,36dc27c7,c3a74f8c,332cb471,cdbfe71d,22b12ace,a2c86e6,24104da8,bef66212), +S(b98831ce,adac19c8,2787e84,cb443685,4208f189,b24040ec,2bca6366,6c601c5e,d753c01f,8410fff0,8278a570,16bf736d,a5ef8a0,f1d9eec0,c17a0f22,74f8458), +S(f2f9050e,b8d42461,b8d11189,3a3de4dc,425a7468,5b34a0dd,7bd3ee98,284496ff,74dd4077,4f0ea177,ba875cc0,f8b504e4,f7d352ea,8ada429e,bd49510a,c155cb9c), +S(e76ddc1c,179ef377,a8da15d7,8c3cd8d1,a775089b,8d542e42,1e6220c2,4390aa35,ecc8baba,1cf42a6c,87918ed9,f70cd24f,b1a3deab,8ed86640,fdc6ee89,ca7ffe76), +S(e1c86064,1f85ad29,afbb6092,9dcfe648,82fc149b,952d1c2e,d50c6a44,13b2d5fc,1d418333,15eb3b54,9c067140,97283de5,fba554ad,2ea510d5,f1c12d83,e730e25e), +S(9dfc52d9,e3e55bd4,2bb21cd1,74a54c02,dfef16e4,758c10c7,ccc0bc81,af509ac5,be552b18,e576d5ec,6961893c,1498253e,c1539068,aeebae6b,80994a10,8140d7d), +S(24e672b6,905f5ba0,186acbbf,6a344c15,f3c59291,8c23922c,fc928b2,5aab8ad0,3b4799ba,9e23bc85,b622d248,9343f39d,59e80244,e25806f7,7d919504,89c5400b), +S(e4be87d5,2cb2fc8e,bb793449,5c94b07e,65aa86a1,6f9b63f1,b24a859a,c0737096,ac28b858,a4083916,eaafc195,81dc8f7b,e163608c,1f69c9d0,87a76446,71110b4a), +S(4379567f,ec797600,9a98d7ae,e3ae123f,dcbb167,2de5e367,bbb40e9c,ab87fdcd,9a2cd1d4,7ed65b8,c2ce95e7,451ad868,c1ffd81b,929ec58,49d82a1c,753440a4), +S(923722c8,f0b1b91e,261a32c6,75fbb26,ba4522de,b9610173,25764974,8c8eb107,b51b46ae,8a3951f2,7d564cd3,395a6d64,27b5232e,2c5b9ad3,6419ef5,d4a5cbaa), +S(7f749af,3301792c,826a1162,b3e86f1,35d1d9c2,e82275c2,a112ecba,bc0f374,d31fcb26,20b1f7b2,d671a52d,ccee8b1c,f47858fa,d28bfb91,475c6889,dc19cf47), +S(c657ab98,6bb3b2ec,87c09d23,530a9136,e85ff051,4d588230,bb9a2326,b058a052,a4f46786,410619bd,60d33aa8,1d8b7def,62c47ed1,bffc872a,941dd1bf,198c8ba3), +S(7f6ff017,2459d2cb,4f305aaf,ff17cac6,5a450ad0,d705310b,418184bc,7bd2b6b0,7ff8f3c8,782d2bc1,8e466df1,f3463a0c,a73dfd06,6cf874dd,65c8418e,91e6c1ab), +S(79b46336,478f2d3e,60e8d0cf,2c905b8d,c0b981af,6ab4cbc6,b36d238b,9d5acfda,7a31811d,95662ab,dbbef71a,5a0672fb,eb34ef37,c39d9ef2,e6f4f27,6e1d6514), +S(df51181e,5ad2e6a,5392c92b,14d762a3,f823123,d4243b57,21c1fa89,bdb2c386,210b2061,bcdea7ab,2e2e98e7,66fd68b4,63330ab6,9e7b1349,5a349087,fd18dc63), +S(5d60493a,4becf377,f66ff41f,9fd3a6fd,5603e504,b4d436fe,bb53c1f6,9038b75b,83de8acc,d2fad488,aef0adad,5a4c314b,6e9ed8b4,9adf56ad,57bdbcf1,a4dc947e), +S(f5b49912,1eb62fa2,c8db16b1,c3cc8ec,f89bdcfc,fee6c5c4,7978bfc2,16ea8a2f,5b0d4f37,8a436098,6b4597e0,a90557a8,a272c668,ec1ad310,c68e30f5,8a409927), +S(67556489,5729a58c,719c2c90,1e6ed73c,16909594,74100b06,2f64e242,c79a1ce9,2df2fd1e,ca39c5fd,a73bc75,bb9e5ad1,ac6571e3,322b433a,1b09022f,80ac4e63), +S(b6e3dab4,d13b42c,54238d14,4a47aff8,782562b0,28422017,ab775b2e,51baca6c,ae4adb5d,67855986,92c72c0b,c617ab63,4c65068d,d603e762,a75c273,e9622722), +S(b62a111e,6f15ec98,6c570b78,316f8857,5f59844c,deaa7fb4,3f76642c,8bc4b064,16a1dfb,551d006c,ca3fb15b,2d250287,41c2a5,35944e19,f7f1c2c3,59b0288d)}, +{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), +S(cda11502,15f6a502,96b3e042,445220f8,54e32a97,32f1e883,e41cb082,90e51c56,ae62e394,7f16dcaf,e5a6a54a,5beae349,a620d996,599ff570,36a9b6a0,3be63dcc), +S(43a90be4,b0efb9f3,422e5374,69fdba07,6f746874,b513f247,854b78f6,4937fb15,4799a0ff,b4026ebc,f57c8b5c,137d4373,ace4fad2,4e2c1705,34940b03,c6a2f0df), +S(612fbcdd,9f251b85,c43ea00,57b847fd,db78f2d1,6031505d,26a81920,e4c32619,aeb8a7f3,332bb112,fdd78825,fbaaedf1,199431df,929c5cde,b5a173b6,721fc139), +S(a2417653,34077e0f,3201dc47,f6ec3fe5,546b08e6,4f12dfb6,3e0ce0e6,18db62fb,271d6d97,9f686ac3,c4191cb2,1a3cfc65,66471502,b9e85207,47948345,1199a73d), +S(fc216e07,b2bc34e3,bba2f0e4,db770bc,33676cc9,1a5f24f7,cb2028d1,7e4c5f9c,fb16790c,386611bd,e567b83e,571a8fd8,97332566,6d2aea7c,903bb4a2,b5354b5), +S(6d44d409,e5f13c7b,e51c1835,f5b223b3,801b3895,802f6164,63f5a51c,449da3d2,6389e29d,957a6961,d796620b,23ad36f0,45dfddbd,533345e6,679bcf06,9ab214d3), +S(7783276c,a37fc014,3ce53700,c7ec741d,33c5222f,f4a10434,270fe9f3,cf70e9d3,9939b8b4,1c64a8e,6efd144c,78334bd9,33b86122,88ca1de4,22cb361d,eda16a82), +S(89339ebd,e4693665,ca9b88c7,f0a4c76d,2639e81c,86c349ea,aab9b974,a618d2de,6fa55c4c,ae7d0246,4e6d6f05,8ac772fe,1456c5c5,2d2b008b,afa9e4e8,bc7e99ba), +S(1ece996b,4408d,f01a9e25,7a6d8746,cdc75105,e614f6b0,5ac9c66,1226e55c,ab521d8e,effac213,38abac36,12958256,316d6858,594ddc46,9de7718f,d2714f48), +S(9c0434e,e311b25b,e1c4f60f,52e17c5d,59563a8e,c1b5278e,595e3ab9,32ceaa6e,a56270e5,c5e402d8,a1b84f23,6899e35c,b558ad6,3a168172,e1d60cf8,da904791), +S(87af4f94,912398cb,174965b,ca3e7e1e,957c67d7,fec69db1,a334154b,39fb41e4,5e981846,bff7a54e,ad594fc9,4cee7666,1a532bed,77e20165,12b58a3a,208fc410), +S(7bc7f81f,98686420,9b81fee2,aa157f6b,28b668ce,440dbaa6,f7a84fb3,5f3efc42,fc60d70a,908353ff,2f59fdcb,83a02ba6,5e20e6f7,5a73f0c0,b7cc096a,9b745208), +S(6ab61063,7567c0aa,c32da688,1d8e1918,b50a359e,c480a235,eea76e03,56d3472b,455f4f81,d6b88c81,72011644,f56f97b6,f2e0d2e3,e93780c1,ab0fe6ea,26388c16), +S(ff71967a,d8766265,b45a9cea,ba7542df,5bd35c9c,60fb5306,4d4de071,e0157e15,edd9241f,19d3bcba,c2470941,4fe7902d,14ef2c17,b3a2cb3a,481e4238,1618e94b), +S(9d4cc871,2f95c218,52c07b13,5c783ca2,3d9d2dcb,e8f2a78,8c9f042d,4629979d,ea4bbdfe,b3fffcad,9ff3426c,fafc59c7,254b6977,601eac7e,7355bf3d,ab7d7ffc), +S(e19a2aa5,49b720ea,2002b863,47dcccd5,b764f5c9,9bf63760,93612d03,cb5627d1,16c930a,b0dda080,45b0c758,4ffbc063,37a9d42,27fa5d8,33f61e9e,356fbbb2), +S(fbf6c918,fdb5292b,17df3aab,e54664b2,80e59ec,e9ed6103,e5f3557c,e7e9320a,84454694,62f6d530,4a82cdf1,3310527b,50fcc8ff,13751550,cdd6da1,ccf20b9f), +S(f9912cc9,597a48a2,7a581be2,c72cf767,effcfaf,c0ad7a04,af2aa105,8fe1a19f,dd2c8c9f,da952245,1e9521dc,f5899430,51f4ea56,6ce31d67,d2936ad8,209eb005), +S(52ea2681,cc2b8988,3d283a50,77ff1af3,95ba85da,3c70f20b,fd1d6652,1f9aeba,c6440e0a,8d700973,5c5b6e1c,6aac224a,76481a30,5f732630,30353cb,4cd630fd), +S(164d8059,3689a410,d49574a0,925192a6,f1a55289,187b3c97,30030142,36d940ec,46ade58c,909d01a4,fd827090,d266362e,cf2a374f,95b2463f,e184288e,9534ede3), +S(e32e1230,46171571,6410013d,b1fb8ba2,f8914aa9,43cafc5f,91ac552f,4d8e24a7,4af269c7,ed6218ae,6c1db9a9,4e5832bf,a29457c8,4c814d52,24dc9e2e,42674407), +S(d57bdde2,6e43bd76,5a33cb8c,a4e54db4,df3798da,5d930148,37eb0dca,35e0f999,7a74180e,5225fec0,20a10d63,2cb2134c,c4109799,22508f5c,d86332ae,8ea7c89e), +S(b5bc01b6,4203cb60,caf4a7c6,e48a1c25,a92d0eb3,bac74789,cf5288b3,80839576,30403b6b,2824a95b,7810301e,b467cc7,b882e5c0,a02c28bc,bae550d2,5c83289c), +S(73b1be34,b9229a1b,bc7e8cda,6027b7d0,4c60ea20,3942fa98,98f5a4b8,98b510d1,7336599c,9aeef8a6,296637b4,13b2f22,4c5ad7d,fc00b225,9152c891,249539b6), +S(a165d932,4b255170,998d39ce,39d392b2,cbccf282,2dc1acd1,c364fe28,dce909f5,f24c5fc8,cd8cb2c9,2bed63ea,a9a2dfcd,932915d9,dc2e9199,d2626fd6,b360f64), +S(92eb21ef,fb8d4e26,89bcad2a,2c4f1e57,85a8fefb,e4b6f8db,c0fc1681,3618058b,7ed25a50,4174b429,103968f2,8f4a03ef,96b583dd,840c32f8,ee1e7774,3e9ced10), +S(6a15d7d5,c5a1d77e,a7544c52,123d0e30,492a021d,3ef16056,46dbd533,e181ebf4,d4d14e77,54a5cada,520f218a,58611e5a,dd6c4c1,755abce8,6050b0fd,ad239957), +S(75ea5369,8a9f0d5b,49a0401b,b2db3286,5a8620cf,d29212d0,1bb097d0,1547cbea,f3e1dbb3,d50fc3aa,e6c16113,1271112b,4fc78855,ea6f303e,51268c9b,2535b159), +S(a3c4dca4,1ba14d89,51b088a,5667f8a2,f8ae1e3,e0438a86,c330c484,4ea34fe8,8113e61c,bc74488e,96fa68df,12fe199f,b0b2366,de19294a,de19ab0c,a24dbd31), +S(be54fb56,80bd0b30,3d331242,63714604,36c66704,8630035e,191c4a2c,f69400cd,15a679af,a8b0c05d,b5408a2e,b3ddf648,86bfe8bd,721abc7b,8bc4aca9,f1eb0e5b), +S(ff1244e4,a157e177,f5700b47,9787853c,c517c335,7dc1f548,a19ad178,f6a40b4,db21c79a,12f90142,befed50c,e9763426,b99b4d9e,f3f37c17,25abd50d,7cadf848), +S(84038a62,5d232480,997e8ee1,5b0e04a,547e2381,74955b30,14da26ea,8aac7c1e,87552fb2,b09c56a9,a81e40d4,9fab776d,62c1a5bf,63a84e01,9b869c9,40f7ac51), +S(50f7f61f,46489c82,2a8ee22a,7e79ca89,1ae4a185,9004a039,da3d16a2,fbe61608,6eb139c5,f399d702,5094ae5e,3035d3a9,e355e4f4,2ccad686,566d298,42eb788d), +S(c05af73b,9858124d,8ccb5eb0,232d8821,d98d220d,f4ade4fb,99519c07,ac665ab1,7493a780,35acd676,966604de,13af29d0,3a78a962,7cf3bb3d,1b1663d9,6a7e36b3), +S(1f480d5c,2a1d1761,ea954284,d2a072a,a66bb6f0,738d2640,4ec9cd34,bcff91b7,10207028,def341b,44a34078,f07af764,2a879d2f,a9e3a18b,ea7450be,1d3e1770), +S(a0676e87,8944445f,d40dd575,fb0214b5,983b164b,2fede667,b36f16da,4ca3e338,6cf3c93c,9ca2fd3a,b0ac23c4,33064a6,d1a6d275,3614be7e,a72cb3ce,e9e02f0e), +S(13e73034,7c823fb6,2769ebb3,ebe492ac,243a3bb0,2f84bbf1,6de239a5,f1fe62a4,564f2cda,316ad30f,5a552164,2a1ff7a8,92ad0afb,8bf2928,ff5e3970,9005f251), +S(18a96b04,1592fdec,101b7df2,6dec0d49,6be4ca32,be96f54d,436242f9,8092c481,cf03371e,e4d2d4c9,2ea7ad23,db3f8f97,d1a96a73,13b70e82,c3ee58ea,f7567ff2), +S(9592f438,339a1044,85ae414b,d30cad38,929004dc,e73fdf8,c86fa2c6,776e5bac,40de2fc4,66571358,ccab78f2,fa40acf4,d7c98188,31d475e5,556e7b68,d6c37235), +S(bd76f4f0,b9ffa96a,1a563855,6b35d855,f07580d4,45d10505,b1e5f546,255429fa,551cfb81,d1d05bdc,e66cfddf,a4843228,423540a4,278e5a9a,55137a9b,37866d6b), +S(fbc20168,bd1f044d,2ebddf8,a7dc1b2b,97d7399f,21d29fef,fba5f8f2,fb60b84b,d459b367,6516cafa,b6dcc1b3,8ddb10f3,8ea3ac,7f73b4b1,3052ff45,6d624c2e), +S(240584b5,5c64bdcf,4f233adc,eb7c9c7c,41d1863a,b0ff7ba1,68f74c8,1ddff33e,221e273d,ac154ab1,f4d259f7,e5803f5a,dcb297a0,48a39637,6e15327d,fc6b194b), +S(76798d07,c586b782,51e6accd,593a2534,70c77c59,da326d1c,f8ff561,8ab0e8c5,64ae34a8,8c9dbeb3,901a997b,eeb4a9ee,4b486c1c,b3dd9da3,218106cc,7d07292), +S(7a9f198,966c08ef,f9259fd9,5a3a198b,eddf9f77,384b671a,cbc16ba,5465b618,abc994a5,8a0c8dd,d98200c8,eb951e61,16a553a2,27ef6e16,bbb27bea,e0191a66), +S(dc8ca205,279a54bd,8552336e,31e02c72,909e4c9c,d7560616,1ab4e439,173edc73,b08feff6,221c061d,7891890f,be84a459,a57eb118,b67c4ff4,7ae62d56,7c158f9a), +S(575a0e7c,dfd55dc0,f86bdeff,7ac8a740,168f976f,be2eb9a2,2bcfe376,290e9085,5f0303eb,5d8ee545,485c945d,5ea765f9,7aeef7f4,e7d6b802,184261f4,9995f574), +S(50e48366,e86ae12f,14a9a78b,22e76176,fed8e25c,ccec2033,f85e7473,96756ea2,8af4e0e2,57b6479a,d58b2f24,2f256a20,ea30864,89b84b2e,27da8481,d8eccd3b), +S(9c98498,d5bfb24d,23f25983,952263cd,9513fadb,a91dd60a,26b7dedc,6fb42e6,c5ea0af6,4b90d3f3,37bbc24a,c2138426,bb349f6c,d8b23829,d0ea1da0,2107ecd), +S(dc253e10,17608817,898ca299,2d325aa0,20f88ac1,676e81d0,d81e75a3,884015d,add05f5,1d8ce337,a62e2401,399015a7,608c1446,7cc042be,2da908f9,b6ee807b), +S(9ccddfc1,8c88e1ca,cd5773b2,b378ee98,e4ed6084,d8fe9a06,e115fd67,a6f01671,439d7033,6ad30482,a7bb89f5,425c5295,cd888c44,b0a0bbd2,7b2b0ad9,499b8ec4), +S(3654e9ba,ff41cae8,6129545f,9207cc3c,315773d0,b230e4d3,24456721,f220e8d4,98eb6499,702161fb,feb0d263,1702bdda,52aa5ea1,867351ba,779f485,7ae3d59f), +S(af31613f,e474bdf1,7320682e,4d1b35f6,ed6ae63f,806a7cb9,f9a47ea2,fd8a38c3,c5fdf037,2cd6f61d,bfb96b98,19819aa3,3848b84c,4b1b69dc,cbb6d9a9,5e3fd807), +S(d8e1f1,d2913c6e,553ae630,64cf7673,437c2843,7f715720,3567b881,7552c73c,e20ce3d1,b6d10cc2,517dcd67,ea82d676,555e66f2,3ed742a0,597065c1,d849b9a4), +S(b3ef1895,7f8f2cf3,3545a9d4,7e0c3c4d,7e24e363,85c1d680,67104d9e,1f2884c0,8c2f8d97,32ab264f,a5d63cdd,f36cc4bf,4cf4ae6c,8e0fb04a,c232364c,37b0e53e), +S(d2d86d8a,68ff342e,a6c3c79f,42ded832,9098af79,dc2c83e,39e5a728,889f1bd6,9cd4fae9,db605e9b,fe25c52b,14d75e2c,a8c9b58f,c6c18d76,c5fca9b7,f6b9d2ce), +S(a4ac3b1d,39a44643,b0487b6c,76cf24f1,114eac8e,2163740e,b63776ea,52432f91,b2278137,c5a81c23,e9bfca31,fd6cfbe9,f11cf1bf,d1f32573,f581d68b,5acf4a99), +S(b12353c7,56fc4737,7d7f0383,6f6c6f62,594323f3,cb27d4b2,d64c4b81,ee3e0b7d,6813fa5b,a5ef894f,6fee8ae9,ebf2b1c1,c6298976,560c731a,df87fcbd,f916a837), +S(5f1a8fd7,b5299929,c5e1865,c28eebaa,13c558c,cce6f26a,edfa80a3,a1450646,b043c995,c6d66c56,77f7dc03,f7e599e3,70e89ff7,899ca5e7,165ebb15,f590d867), +S(ad4222e9,583e2afb,2c56a116,500514d1,92c0b10d,4eb66592,2334c817,623aa28a,97e34c9f,bd9650b5,a5444e2,4a04c5a0,78ced6e1,2e21f516,60a3d4a4,fd2319f6), +S(289585d2,886d9020,8870975d,93373b87,b3ab1909,21d392c,82abb695,22681e2,a40915cd,21358a51,798e18a7,9595b3b6,b7a645cb,2905bf75,db2c2438,2ad63073), +S(3ed81e00,a9607ac1,8167afd1,e25d80e1,9a4c1a23,69682ec6,9f40ba13,d86e818,59ce30f9,8f646855,ce9fafb,abf7b2b9,deb1be30,de5edf17,7462fe3d,66f02e27), +S(5c12a417,91a0f2bc,42cbb301,346b4e09,d68d4720,aef188e,7ba44469,e2e63f4c,540ad65c,9432a241,5a1e1af3,2d6f8c88,8c47a741,52d6224,f3d5e486,7a219c6a), +S(62e3fef7,6ec4db38,5010b30f,ac2803ec,27088e79,2db7f8f,72be35f,895ffb61,c0c8efdf,f9589931,14c1bd72,891e2743,b3189ec7,1f05d5e8,a0d7cfd1,753279af), +S(677740ec,ea09a280,7968ea8d,fed5cfa0,58d9564e,8f22f96b,79303074,58015089,cec6fce,30608c7b,2cf3bee7,353be7bf,a8265b2a,a6f058bd,1fd87059,f261beab), +S(ccb0c3cd,7d9ae81,f366e10d,c5444cb6,b713088c,739ca70b,fa214359,9b806937,4562fac0,408cc5a6,a961d8f3,92ac2566,cf02b599,7d645d57,bd81f678,dbd9c43c), +S(2db401c8,d474f7ea,a25088d9,d835a9ec,b1ae4f04,bedd711e,154ccd12,79a5e68,654a9bf0,ab608472,51922ffb,aea4769b,29894a4e,be1d175b,973fbdd6,7393bce3), +S(514a03c3,5204855,f4339a8a,d8894a5e,f0f7f8cd,b02d597,6d4ff85c,7a37fd1a,25d67f20,94a0f6c1,49999c5b,dd4808ad,d49f0875,882bfbaa,b391a8ee,7f7f32e1), +S(90e74327,cd112d5a,b93ec168,56b3292f,45eb178f,5578ea2b,a51a8b03,2b51c78d,fdb46efa,92e1972f,7c269259,3ed95630,74752c76,cce15d51,c1fcb011,19b7f797), +S(a9ef7f4f,857083f4,1eb3cdf1,76b738d7,f25b8c3a,e4705a26,21d791c2,abdcea1f,8dd007cc,7c6da435,267329ba,17435394,6319fdbd,8cdc9ce5,2250cbf8,252d8de4), +S(7dc56b22,14d62402,1c42f6f4,f148c146,6156c1f7,7d14d505,6e65ac0,693952f3,ba58259,523d0aba,a8bebda7,dfc67df9,4e28aa03,957357d7,235725ff,bd6cbab0), +S(11f8b2c0,a75a1423,42da84dd,4d04e5cc,e499f5e8,cefd2b5d,e73ec422,1718239f,29e26227,6ed2f32d,7824ec3b,5b776fcb,ea5800b9,2acf0a31,bff27cd0,7c8cee02), +S(9d0ce33,8fbd0443,3de6d15b,6dc3605c,edff75a7,4cd08e53,7e078ed8,bfd3a1bd,ea0b5cf,3a63c7ea,6b17dd3,fa19139,9078d02b,760f7d2c,f56d4a83,a8f0bffe), +S(9116520a,ff9d1ad1,e6c1031f,f9388b1,b1b2bdef,52f49937,a93752a0,75bb21d7,2ab7c4ff,47368f76,c1df0b33,54bdbee,157d7b2f,df4e19d9,d1f09c87,75d95c0f), +S(89c5fbce,ba4859ae,2706d0a1,e4ea2956,ebe71d40,3d1eb34d,7042291e,6f584015,c3a99137,2fe042ec,1dd7c83d,4e915231,cd5ad4dd,5bdb3877,bee1f9a6,8dd368c), +S(2f4fba9e,eba5a0a7,b22dbf3a,9867bb06,ebf3c4d4,ca5353ed,315b1752,3163d4bb,6c156492,d245e1cf,7673aa12,e78d0b45,d6171dc7,be574418,aecb9f12,3d6e8ad9), +S(905912fd,599f59e9,a3009b0a,7eb38034,fd9ab746,336831cd,a1985ba5,37d39931,9a7716b0,3524e8dc,714c76b7,a486660b,2ab30e45,b3bed8e4,f24e62bc,d1705272), +S(13cbfa57,515d5d33,1d8823f2,a8b5e083,19239bc,b1920aad,42d4f6c6,9934d0d7,f36e2353,700f0313,9236618a,ab0b5fde,5a8e14af,8e5e12f,47fda9c3,79ac150a), +S(cc939020,199611b1,c97458b9,cb9494cd,a9dfb14c,a2cce863,3ea361b4,68fd0857,a33978fd,e5c6a683,90dc368f,37e01e76,e2c08a1b,512fd2bd,d71abb9c,87ab7bf4), +S(6ff68519,e62b3e23,744a2136,2292bc79,3c7bda5c,4ef1ad09,81843ef7,183dd564,6d4676cc,baa85268,a4694ef8,55e86386,1f0f5a3c,38c8cb94,4ff81c53,c0737da1), +S(60a82e4a,5084495a,ad08d440,45639dbb,e0c34867,6dc3bd33,4f447815,6702418c,666c2a2b,ff70a40e,c01c5f34,cca48f00,16896e55,f14d21c1,e2fa80df,d4352943), +S(57231292,66d1532,f352005f,b3e789d7,b19409f8,cebec41,b8b43330,cef1a7,5904c51,ad1f7ac8,ca6a0ad6,971588c3,42f98ba8,6fab3f9,b07b648a,26f3269c), +S(c50d8b68,bb031e89,131a9be3,1882c8dc,bb109fd7,6df989d0,4b0009e,cd2db9e3,10286cb5,875480b9,3bc78987,9615095,9126c3ee,c66e23e2,3b21231f,d41fc039), +S(ea74572a,bb5ac532,fadcfc73,b85328f5,de42ce24,d79950b8,7f6e0c98,e6fec3f2,c68a3ff6,254bd3c9,febab9ba,c6dba6f,33d34551,d8bf2c14,ffc29c09,10ab374c), +S(430f73e0,8eec3d03,8bab8afd,9b30a5b3,5008ddd7,4cb85aeb,7b836ade,3f25f6da,27e179cb,ed69a2ff,ccceef02,cd1b8b9,6591deb3,b94a905d,df9e0df6,f6e8fc7), +S(dfd0f623,61e9baad,2fede6ed,9a6dcff5,3bf259fc,704c37b7,6b9a3665,a0296709,a9ed876d,5cfdf560,d3896579,57ce1aa6,13795b86,1e2e493f,719b8cd1,85e11f84), +S(f486a524,89f858be,ab920853,b27e5ef,945ebfb1,def5bbdb,8a7f1761,451ec105,f50aa3d0,cc587372,a1e941d7,608c86bd,10bdeb39,60cf57c8,482113a8,d3039da1), +S(3ddb3b7a,9b0218d0,2fc62004,33d21317,5d811aa5,a5d6b9cb,53ceee05,75341982,84017fa6,1ed2827f,f65d3bc2,3343effd,403f77c0,4524be5f,4c763bcd,d04b70a7), +S(c5938802,42f1bf38,5f5574e6,815ea291,b13578a6,cf8a31ca,d516d3fe,ebfb1488,5c0f3858,e6dd3b7e,f68b4368,dc3b5a95,d866e2bb,fe269527,fdf4b3af,e9196375), +S(11c60556,d6584b79,882f75c3,92e036e4,2aa702be,1f545e15,403eff6f,e27cb59,8544c8df,51e9a3fe,790fbbbe,f768e45f,c8a39319,1b18b4f5,8ae85d17,eac28fed), +S(ab609b1,52efce6a,eaea4c68,e498d414,9fe8aff,28196efa,a39a897f,5969382c,a4f7fd94,e87c1a0b,b9502f5,438c7a30,b6fb836f,17a19720,ab07e286,f94c8eb4), +S(7c188bb,109dc167,bb66cf50,58f263c3,ca8f58f5,66c9c0b6,b838bf9c,7cca26b9,1236a5a,bb04ef11,81b22343,327607c1,8693eea2,3c129a3c,377ee493,d332a5f4), +S(bae48149,f37ba68,24c47e5d,1fde4ee7,14f1cacb,8cec8ae2,de547927,768699e7,433d31de,c9619480,c2984475,5e7c3813,bfec984d,b0d9fed4,f25e94ea,8e747cd6), +S(88ec8b53,d57f2ff3,db3661b2,46989ecc,63c0f757,6acc7c17,cd0f5792,b006b5f3,9f35942c,28f0198b,cc3afbd7,b8f28ddd,1dceafa1,4db9557b,35d4984a,e80160bb), +S(67efbcd0,b5cbc215,c453d642,d1b19bb4,437509,33ff6afa,1ef923e6,cc83768c,6575c0c3,489a7bc3,7865d32f,dd8f2a24,a4be1df3,ec7765eb,ae09f10d,342538cd), +S(12f7791f,4b9310a4,c9d333bc,eabc3472,9762040a,5713829a,9a58bc72,47e51db5,15eba5f1,e156cd5b,409ffcca,876dc51,9f4f6e17,93ecef35,7b32dedf,fb12b402), +S(bc145b46,130e431e,18b357e8,a47f90a1,c38842d2,7fadd3b3,58d21959,daa3effd,4a62a5de,d23f1d44,ee86ae12,a03e4a6,5d1794c3,d7621871,cced4b58,116c97e5), +S(514fc2c,e7c864fb,b54fb8c4,545dbef7,7fbe45fc,d7ae312f,8866c608,12658866,552ca131,45466fa8,b6ce58ae,77c01a39,1f9001a8,bd9e6a4e,fb434b6b,9d63b79), +S(7c2bfe51,f4a9a32d,2f7feae1,96fdaa4b,45670ed6,f9c02940,633680ca,afae3f88,88bb43f3,996bb5fd,ea4a37d,e8c5270b,571644db,e1704bf6,aa207aaf,cc2742f1), +S(7710c58e,36f3ca17,8b96dc57,21acdbce,e37f7879,6f9f251a,df4c8dbf,599c6185,f600262d,d2a15427,ed6ea68,4482efe4,f57084c4,ce1ca445,8f85f646,4d954696), +S(5d4cda56,c705e89e,8afcd145,5490d589,63de5bf3,79d20a4c,acb1ba1d,c2effa6,f6a2f87a,cf9acd28,c7b12c4f,a42bc4d2,3e5c726,1d404813,30b99d15,533cca94), +S(e3bff796,4e38d5a1,946d54a5,5a7c9999,8faf4e08,2eeaf460,7dbb37fe,10b49bcc,7d6b4ab3,5d711881,a26d7327,bcd8eded,61cf85aa,f56b244f,58d4106e,8558f3e6), +S(75b80f78,c88f6e67,9ff252d3,e7c10a87,c2933642,53fcf204,1625457e,542c9398,db3b2fde,be9e05a4,a722ad7a,aeca21e7,3ef934d4,372f192a,a07b081e,c6419681), +S(4f640190,51d6332b,d29ab6c3,7511cb28,ba111146,189e4ed9,8b945e96,d4ceb5a9,626d0d0d,ef4192ba,a7874638,fcc07075,fd65b688,4615cb3e,5c63167e,965293de), +S(4f90520a,ee7b050f,cdbcc57f,cb03f361,f950e5f5,bd723d1,33de2990,df09219f,f12a8382,f2b1a67,c9868b2a,566e8734,2ac332f3,87d7864d,23ab4d33,395c4144), +S(f5ee8ddd,c044fb9f,babb5ced,4ab56f0,c4d357e0,69066828,23b02321,6fac446c,ec53db7f,cec7c393,d8b74749,981f6f32,c4462dac,6f0a56e4,34d52b34,d97b9d3d), +S(69727ad7,b48c376f,cb2c4cb6,b5c0e4ee,cb1f5925,f1928599,c55c4f2c,b31cf7be,39b486c2,3804bb69,b39d727c,eee110be,966da862,32eabbba,73ef17af,1c8df334), +S(23d1da9d,42bd74d7,cccdef4e,aa79e725,32fde7fd,b43522cc,b0c8166,1090f19,a168e435,f673bfaa,84115cbc,85a25973,5aa26ed8,86a1136e,ed3fedaf,b939e9d1), +S(8add82ca,322cb7d0,68e98c5e,d4f66993,50a2b2af,5bf0ba10,4e012389,f90a38,cee02a7,1df433a8,46ab9f11,503702c8,b93d609,fbf882b5,6465a9ca,445238eb), +S(874552f4,f2b5552a,b9e9dd9e,a8bcd62c,52f3036d,2b7d7a7a,3bf206db,18490830,12197e8d,de19c33f,37f50ba2,362642a3,87741090,68b2ba51,c5b13fe6,5d3b3a18), +S(7b5e3f54,d959d208,17c7c518,62628a07,ae2ad59c,6bc4458f,467e213c,ba145fe,bc3a8595,527be77f,c8cad2b,e9cbd810,8fc7104,9eef7ef1,924255de,6aa6fce3), +S(298e18e,d4790215,d0a82b37,b09d6b7c,90ee8408,13f6cb33,b150a3ea,d14fe41c,a2504d96,a1345a22,8e14e82a,eb160798,c7bb5cda,6ccd4bb3,74093c69,93e0294a), +S(22bfb660,2b823430,e44d0358,300a5fd3,853577ef,79b73104,12122749,74af1edd,ee318018,3617fc09,4d3a3707,df38e9a1,bf9ec587,45e251fb,8a127137,3c9b3e85), +S(41dcf360,e9b5b5b8,bee689f9,1446a874,5a4df0fe,1963c132,5d05227a,313d08b,103125ef,ac9a3fcf,f8033bb5,659b81f4,982a2f31,7382c0bf,b4c4a73,8479da5), +S(71b0f642,7f6127ad,77318fe5,27f57c41,e34af0dc,311669af,fe695a46,102dba7f,b6bb548d,f92c9087,c1f0d543,2737e853,d5a03e2f,e607057,352084ec,3060d823), +S(c36150f6,be139991,3df1cb29,3324da28,bbf75056,aa8102b1,e2be7e8,a669eaef,ec869956,1d5d9e8e,73268641,d7a7d01b,f1613d5b,145d2631,97abaddb,ae8eadc9), +S(26c0a835,20d9ae57,77ec9e5e,af9836fc,389a671a,6823f705,6eb5562,bde7193b,1939de0f,da69f7c1,fdeba6fb,f982cc12,b39640b5,f92253ce,9c84667c,9e75d56f), +S(5cce3427,e2cd7404,2cbf501b,2349bcdd,e1e9cc1b,d9ac179b,e848dd89,7378be5b,8148375f,ad9d42e4,6562dd11,463aff04,281c00be,12b40b8a,b97b638f,3a525901), +S(cdb56ff0,9c36fe2e,74546bcf,44b996c7,ec11862c,a5c0f0a6,1c352bb7,771f3f7b,f97dd0c4,6d0409d7,3559d6b1,a450a8,ba5e8d5e,dc0f1a32,df840f06,20348fc), +S(379abd64,fa180ad7,9343b3d,d2b6ab31,5534a19,dd59e25e,9a37271b,de58e2e5,512f6ce1,c2fa1202,2a6dc666,25f3b8a9,56c1a5,ccd5ddef,6c1b94c1,1c507472), +S(8c32725f,d1fa4998,794bed8e,eafeb3d7,c24caba6,4a693aad,14055160,e0eb4df3,e91ae4de,54a8db16,bfdf48de,d3835586,ed1cb6f4,f767eb04,343cc260,c2a008a2), +S(6f6c310b,c1afe979,cf032c40,2f594512,ab074b31,f336579a,b9e52fcc,6543e882,87cd5368,561c5897,d00a2a97,2166950,5b4f9e1a,a1aaf8f3,cd817e9,5e48df08), +S(299829f3,2cb34343,5caa2fb9,426e24c0,5a84466,2c2aa34a,ac75d454,50b54b39,3bbd3e13,50a11a04,31b44d63,24eec80c,64065603,3960c6e8,b82b6711,d660bed9), +S(5275ff78,3529d268,51fb398d,5559b300,ac09ddfd,39cf0bbb,e02f50d4,13fe62de,7d3356f5,a74c829a,bbd294f,cb302d69,c30fdaa8,64c1ab4b,fc734e5f,ea8f848d), +S(3e04cfc2,e7cea4e8,4c3ca490,2ce0ff69,883e19f1,6952252a,51edfda3,6ad04b5d,39536901,283e998f,ed4ecf2b,e708d5d3,9b19c290,c76b8faa,4cd4f94f,7f05e813), +S(58273a33,3dae61a2,71970034,3c72d8ba,697a1fd3,527bb291,e098ad6d,173525ba,c2f0e095,98d4d04,fb156dda,49676761,774d09b0,e43fc92c,7957ae66,396e57a2), +S(4f43ee17,95d428aa,ddff7252,536a7bb0,29fab5a8,cb60f3e3,21ceb52c,410e49a9,d17315b,c0288557,c4a9a48,8372722f,ce0bfc3c,4ee0572c,6682934a,18fa2c75), +S(b8b61408,4abbb43,10b2551a,8fbd7503,9856cc49,4f793567,cd7c205f,21cd9174,b45edf3b,ae914c9e,cd7fe61c,bee4278,5bfd96e9,c6493fae,b465e10c,8e6aa815), +S(9ff66284,41cfba00,c15074b4,aaac29b5,c12c3d0,59009391,880db30c,69bb700d,95f71bb3,8875faad,373a2dc0,b18f1d31,cf161cbb,b1d1d5fd,fe2abeb2,e1a6df69), +S(69176264,329a1ad7,8bbacedd,3b99a5d0,c3694973,c4a5df27,d7facc58,b25b3231,10fd42f1,1bf91b0a,a330bbfb,b598b7,be2c2faa,354e148,b3903a6e,697bd350), +S(94546c5a,b4a5dcc1,d9a8fa0,ac117012,470247a7,913d0acc,e8c7c2b0,d98ad04c,7894e112,11e816e,a03586c0,33a737df,8e11ec0,7c85295b,1305f575,2a9bf9fe), +S(fc476882,d286cf0d,3e29b73c,744cee4b,563289a6,c367fa59,ab3e93d2,b0f71314,8680b7ec,6d633583,ad923db3,1ee3dec9,6b4ddd95,c331a670,d759ab82,ffa07ed3), +S(d5279e6f,62490fff,5ca2f0b6,7a8153fa,3a5fb95f,2262dd3d,4e62fdb3,bfd116ff,831b6dc5,7f16d6b5,c25c6b46,9111fa5,48cfe44f,76eeb9b1,55614b7b,aacec99b), +S(8174add4,de57b198,9a999ac,9ccfeb1d,78a21fa4,bdbdb88f,792829f6,3d21923b,39292fef,300539b1,ec4ea7e5,9a943b18,e4cab57b,36c8fcb,47a96d0a,73facc18), +S(dfd1f8a1,88cd5554,6cc5b417,c2c30cd3,c34ea95e,a9087a9c,cd240cd0,9d6b8494,6616b3c6,881b9cfc,cf0438de,1e9bb54c,f213c9c3,d0458ce1,e49f3da7,17c6ff33), +S(40d6faf6,aca0880b,6f639406,a187f116,6e1d1656,763a223,cf2d9805,f8059521,26402921,86884ddb,59030708,d12a34b7,1e1f592d,b8316aaa,50f3b95,3dee82fd), +S(a06e4e4e,df868121,9ee140b1,1d688bde,1e9f0050,cb9e122e,e12bd046,b6fd999a,76f0b3b2,522571c1,28cd7423,273e0a0d,5ce2e41e,dcf844ab,3a44b18a,f29fe0e6), +S(8ed7e5b,efcd7322,7b537ffb,728d5c01,450445f4,5f187ff1,5182fd57,817c7e02,fdff3f74,179e2229,a680a538,73288b80,17819a8,953f358b,25ee7b8f,c2c1a89c), +S(1b7d6838,d0b5a412,9c0fd19,cc917166,c9c351d1,33d8db84,7f39ffdb,463dcfc,c50a0eb9,a20ff1f7,67c21dde,9a74271f,2d2e7c8d,3a45251,8bd61ba7,9953c58), +S(c991fd97,ac37ffa7,968bb26d,1793ffde,49ed283f,699b4620,7520849e,cda25769,9cc861dd,b39e36a8,c408a09d,cb2b22ce,c0302a6a,3b1ed1a9,d89f9784,e0f0b766), +S(849cdec4,66bcc09f,9a689c,299fce1,d1b37e8e,c59d9184,3d519da4,937d2117,c759660a,92c29619,70188f0d,8a539585,88ca929d,f9468ed0,3be6d6fe,cbcded23), +S(4ced9d61,7462a2b4,3cfa38db,1e4489f,3e527425,d48807f7,bf73cd93,a731e351,a9954e80,fb6c42c7,165b4cee,976199ac,2e6871b3,b088fae0,f040f09c,b91a0ea7), +S(fa952014,80bed20a,514df1dd,6d8541e2,f7bb05f7,4eda2a56,ed1d2a0a,6300ea2a,3e887eb6,edc0c858,18b1bbb4,8a54027a,aaa11988,c8063f14,98f7d1a9,64b8d818), +S(aafb82be,ff591455,e3c11ee2,ed724caf,46f86053,708699f4,38180f5e,a0156d90,63bd1026,f928de57,cba2fe5c,890d02b8,1afd2eea,2ff8a5d7,6708c70d,6172dab1), +S(9788ab96,c57bcb54,3797c014,a20704d6,56eef193,f0459b4b,b2617a90,3ba30842,1e81188e,28ba4be6,d244ae0e,2574d0bb,ab51fdc1,5ca4472b,b7b82a9d,dab005a6), +S(58fffe9d,6d6e176e,d006b35,52133322,c8e95d2c,4040fd4a,3a04ce94,dd5d0241,6f8bf132,7d0aee77,4e88f397,e2cd1594,39cd3c32,5a0313e6,d63e5e52,5974a647), +S(65d3d1c9,f10eb74c,6a27fbdd,f39d4ec2,8995aa50,3bdaec76,2f7051a0,23190b4b,42c3128d,959d7b3d,b585043e,3d042252,6e2c1b3e,714a2938,42cafeae,22333ced), +S(5240e75a,419ff988,d9e9a27,1a9719be,3d2c960b,eb574aee,fe278acc,5466fbbc,56aaa8d7,76953819,904cecbe,cbfd680e,99df80e5,c6a9100b,1fb8a570,6d28fa7b), +S(6f00eae2,ddbcbec3,cdbb2079,d7300565,12087a6d,b2f5df8,8d2db4ec,9358a8b8,81ae19b7,88ada62f,dd68da42,fcea16d4,699467,dbcfb314,51cfa318,e71388a3), +S(a7c58025,ec88b71b,bbe8a9f3,15b3b182,3ac7ea83,95ff1ae5,eb0889ac,d7a5aeb2,4decc4ac,78e45b5d,b76f969f,59dbd448,c0100f21,79aed6f9,bdd089c4,5f02dccc), +S(f5534fc1,b0bd55c7,e0af5eea,c11567fe,b5694f1,cc60830f,cac6ebf,ba0bc0b2,a7ee28d1,7624a2ae,32841821,e1ca4934,c10e6087,819ef9b5,f0b56e1b,4467a9c4), +S(f43aa167,8f4c4a1d,2fe2551b,33c4eae9,5d7b12d0,276d37cc,a4e68e01,71521f6f,a64c65a7,1c7db76d,bc11cb6f,e9842c12,ba6653a4,2cf0bd8d,46656e31,feee083), +S(28cd19c8,3d8265ab,f0d38cb8,9f8be926,ee8df072,f096a363,94193af5,d16d9923,58625794,ac267f89,a6734390,a6bb719a,d5e9e2ae,6e0ea241,aad5407,7cc1bc26), +S(572703f6,5d834c93,d0e09fab,e92b1add,34245158,33682bcc,2e62c218,451ef85b,44daf6ac,a9af4ae0,a7026240,8074e4ae,72ad4d79,8145d431,760b26a6,33d05799), +S(27c6a3b,92bf753e,ec6b35ec,491fcf65,ee5387cc,b96cd73e,651b9b11,40b347f3,a881835a,4d28683,670934ab,95939dc9,5a0e5974,7cc9dc4d,c39d4a9c,12fe763e), +S(30a0db50,ecc1bf4e,3c34a171,ff648cd2,8a3fa45b,786cf15e,de01aa47,33a99eee,cb47e7d0,cae5a279,702aaaa3,a2865888,1676d851,9d15805b,cb8bf75e,23940a1), +S(d27e417f,f83b3a04,36ade27f,1b5448a6,fdc91da6,342584af,47f2b8c0,3d21ccf5,6d304d52,c9ddda31,14b68be0,49b57d55,45d43d4d,501b07c2,8d295a33,8f8ec396), +S(5bd5b0db,57c473b4,de32fba4,fb7b68a3,9f6e6c46,c6e72e50,b6ae8fc3,259331dc,cafd77c8,2b16bc35,a46a7c5,fc715c3e,cee644e2,4c000335,b472aa5d,4efc5a7d), +S(37e99dea,23a18371,1f23b80c,1e05f3ff,45ba6351,10c9fa7a,b927c808,e3e6fc45,3dcaf312,f8dfe055,ef6abba1,3e5eb0b6,70ce3c7,5724fcbf,67c61730,629ae0bf), +S(6b001dbe,be7a3db,6fa70b38,f46d13cb,77d759d6,ce6b7fd,153b87b,aa67f94b,7cbffcc0,f3d48278,d9d6b09,7923f646,b56d9fe1,77ce1111,d2abd2cb,6244aa85), +S(e4bfded,5c81c0b9,f1ae3fb8,7ac88e1a,d468ef72,bb3321b3,c3a4d549,fc073820,dcdce7a6,76b0b3f0,45b6331b,fb75ae0a,610473e4,b551a001,18674a8e,a3ef1d73), +S(ac834f65,dd566124,f837f049,bf0d73bf,4884a1dc,f1756462,3cbf375b,6c57aa9e,1bd6227f,c5265e61,53d0f350,6c698bc,a973669,1260d911,2e918308,48cedf1b), +S(d36b1cc6,e6fc735e,6e83957d,87e2c74f,8cc50202,ddff7610,fbdde385,22f40d3b,293f6494,c2ffc78c,8955a544,fbd4ca05,898e3560,e05f0949,cb6aec2c,a18994ae), +S(d2a214c2,b88a5126,1284b25f,d7f5ac2c,e04f8333,144ce351,dc057262,c9a1fce8,17fccbad,720577df,1db1230c,e2c68fb3,b603ce29,a26a6370,4fba4060,8c4dac60), +S(f3f9329b,ebaf25c8,7efc393c,66c308bd,461f55fb,c721975,6a504edd,f46d95c7,799cab78,1d1c65f9,2a5193a3,e6124166,586536c,f4389a35,d886bc95,f033ca0b), +S(3aa1cd82,ce4a7838,4cbfa6a2,85fc66f5,53edc1a3,2816b1eb,85142e86,528e0cc8,4b24bf4,3a8266ec,4223b77d,3452f3b6,72596458,11c5cd2f,8f043d71,88f87dd9), +S(4abb7ae,40395b18,5a1017e9,d8887ffa,480f57c5,41c9eda8,578f7e16,538c61dd,4b96d913,161669fe,43230df9,a18bc71e,e8d36dac,de48c3b,d9600b46,a29babec), +S(89ebe2c1,845fd4b,461cb4,bf9992e,5f08ca21,d9d24f32,2733f259,c53d8a92,dfeeba58,f1d23a91,a85b3405,2b875f04,e056732c,a576f8df,aa5dec9d,2dd747a7), +S(92915a37,29c505d7,493cc142,b2e16913,6c8d2015,fe68992c,eae45b1,62d465c3,1ac2d867,24260b1f,396777cc,61f0261a,d8a603a0,e3efbca4,fbe5f485,378ef947), +S(5367ad90,3c5d684c,920f38,76c3bc32,c0b42a65,e1ee8d0a,e59de048,15bf8e80,82bcfbd9,11bdc542,306c0a1d,dc4aa5d0,353bb0c9,3b36d255,8657e40c,85e121e1), +S(dba0a47f,2fd5e7c8,5c2c8bc3,69981126,15769156,852b0f24,1e6ea83c,e56a8817,7a8830c1,377a2973,35a66c63,40cec55e,7e57648,29f32586,3f4ca9ff,8d95c0ed), +S(ea85fbf1,911e9827,59ec5e0f,a87b1c39,ff555ef2,ab294982,1aca68a3,648251d9,164f58be,9b8c16e4,ac9001a1,815d5f37,4b7e050c,21cad8d2,b2be4a19,ceb0c359), +S(84e3099c,ddad8d5,82c7dfbf,df03f19c,54e214c0,a0d5e679,7feb9f3b,dd32e43,980b77a3,1d08480a,5ef191d0,5c8cf0fc,48d5039c,583ee3f0,d37a8151,c49fcf90), +S(edd595e2,f8cddbdf,71f39b87,9a063da9,8ad70ea0,f030d9b7,28bb666e,54eb9286,89f1969f,95953dba,a1ad1cc6,29cbac93,a4620a8f,5c9f63da,a62ee923,98ee0f49), +S(1a3f3b62,26834d98,23f80f02,963e0878,90d60328,d911374e,167c75e3,51247b23,afb1a632,652762b3,db6b6259,ca8452c0,b194eb76,f16e2cad,1096539b,2386ee41), +S(dc425571,5dd53bb7,f572a949,895fa277,23f6c177,a234d2d5,e3c6a67a,fc458f37,f1c54b9d,54679c34,dbd9452f,f5813e9a,138d56cf,c7d8162b,c1eecb9,20edf717), +S(f86b4286,8b3f187e,4ba6fbab,91b83a4b,60acae17,b800e594,cc996004,138ed24e,7ea7b45e,b5a2340b,92fb24b6,f02c51d7,14c02c88,e9fa216f,595253dd,58e6227e), +S(46d26f41,447935f0,af56788d,b33b640e,e661de65,ed1a49f3,db91ff13,48aebe29,5e79cbe0,80117377,6db73c6b,eed3fe8a,e7e30979,2208cf9f,e6c40850,f7257fc0), +S(fa42a015,e023a7e9,cbb36e76,b94593d3,2306a05d,9067ca2a,717c8ef3,2740575,9da9d901,41de45d5,52c6bc89,6c43655f,f8a35748,ac145c9c,ebc09dce,df93b9c), +S(d03e4507,fe4c815a,ea50b0c7,1469fab8,e1215ed2,c32710c3,ef90e85f,8123314c,d3676737,18dee1f2,a1c4444b,9f1f1b8b,c049717f,9c4cdf50,3ba74ec7,3d404e50), +S(a4aecddf,221518f7,b058d538,918281e5,7f36b313,d00aa7d8,d6277fab,13f6ac95,77738ad8,eab86a97,1711b719,21edfee9,edab979b,8799a123,b16d8a58,354dc0ac), +S(f0c70330,433998a8,627c2116,e5352b1e,d9754c24,3d775132,b48d3db,e150a7e0,5392f238,cc30eec0,aa887b99,29759f5e,1d9c252b,dc6d8989,3e46008c,4129140), +S(4f34fd4e,155fb49e,7f1d2407,f65d8d94,5ab8bf,14c33255,e764579d,28252d6e,29f3e40c,2fc42f54,dada4b65,3d103afd,e38027a2,3dca44e5,15e6c561,16bbb839), +S(ae34daf2,44babaaa,fe89f02c,8ed39b2d,ed4f09a0,db8cb7ba,e4145e61,954ca965,16b58ef7,f394d988,24c7019d,738a7dba,5be8afae,45bcc2f2,4cc7dd44,f60561ed), +S(4637fc06,95c91eba,d195450c,4067cd74,14c646c,8885beae,e99e6338,dace2e20,43a38d49,362174ae,52683128,ebc753f2,71e398d7,fa906f5e,22ff4dc2,2622171f), +S(7cca0cb7,f940ad95,6a0a4d4b,e040a3c7,4b7304b2,975eece3,eac0b4f6,fa240c08,34845b82,6a4df5b0,10f4ada5,b6c83ad9,5f932a33,8b319027,92796374,35c0ed9), +S(bc374aad,71cf40,8a1eabe1,20d44340,faf0f3a2,774b378f,90f08faf,3a7c626,4bd1b099,9f649446,20c7a58b,45081f50,178626c1,5f00451b,b3617b09,5ecabf74), +S(cf3bed1a,37aade71,b025c9b1,dfc46205,51b3dca3,10ff6bf0,4a89a492,85c6f4c2,7ac96d8f,1b856617,3896f216,d6756362,bd5a9ea7,9e521668,b0d3a05,f778f6ee), +S(e36904da,5d6970cc,44faa475,c6dfb02b,579adaf0,4612dc2d,a7c9a166,e7c771ab,1f164e1e,24a1452b,af2dde00,e8ee182d,2c9c84fd,1cfa67e6,f8ea5f00,376cb404), +S(f6b29ac4,3a3b28f9,453e5a58,ba715cda,7691126,bee6af97,e1c5bee4,199cf34f,81156562,89bd32f,f74a1484,15390fc0,a1451536,99ec5f72,97b191e7,98d75e12), +S(855b98e1,be5557c2,cc7825bd,ceba8296,4921a391,12ec245c,3d89fb52,a443b680,9d4d92f6,af921190,1129dae8,15e93939,9994d482,ed93bea0,a88ae69f,c3614f22), +S(c534fa2f,e0eb93a4,86a708ca,2bacdb6,74b17471,11fae4a5,1d4dc063,ce06873,9ee94f74,b1239ee1,cb96fc2c,4269b1e1,7980451b,881145a0,9ca5511e,985a57e9), +S(1615956,54dbb60e,9d446655,7b673,c5f7b662,ae1bd976,2096b356,1fde395,5cf45f18,5d88f4e9,3d8eef94,aa64996e,1648cb98,3bca5ae3,8f5d2a96,b1cd241a), +S(61ca23d9,875bfabb,d23096fb,a12f043f,d036053d,a4fd7f40,ffe63b5d,ca176fb1,699b75c,1391d3da,18405c5e,825520a2,d0c49c60,b07417ce,89bcb2c5,15ba1a05), +S(8ab48e3c,5cd1c014,473ed567,89edf015,917f7b09,47fda85d,294e531d,89124079,58b7a6d8,2bce79f4,189f0b43,7d009e06,43127468,1dd4d50f,ca2ac326,99dacaad), +S(b56e89d4,28960847,be87d5f6,59727e68,80f71a6c,a023dcd7,c5f0878,e3146d99,bac8519a,5d2c472d,ee3a2578,d0ff2a17,5e6801f7,8eead578,116c59b,f5bda8bc), +S(197dd8ad,b359a388,b7920a8,9395aa80,1c98c278,888dd30,cce2f2d0,2aec4d27,383205d4,8c7b943d,2e66c725,979acbfb,d5a62947,bd251407,e4481ed0,d5faa6e7), +S(b8388b28,61f8c667,18653876,526d02e5,27d20c29,e612002d,514ba09,853f694a,7963e44d,997c532c,bae94319,74aef26f,b5761b3d,5c8a2e76,2d35907,cb3ffd28), +S(5f6eebb,2ca12aec,b80ad8bb,b926fc93,53281e26,60660c29,41ca2cd3,b16c428c,5e5c92d4,41644c68,4d68e47c,c63c71ff,54634805,97955591,b8f68915,c506d92d), +S(cc4f7d7b,8e5b1d1f,f3c166a9,51832dc0,9503cc2f,e0fb1784,6f4910e1,eccc396b,a5701729,65400983,90d49ee3,10629444,b53f7a5b,3e31bec3,7eb99ddc,f02c8d95), +S(1bf0da05,6984e8e3,3741cd04,16e74372,2cc918b6,bfc964a1,1d63d0cb,590c5c86,e461a594,368cb7a5,4c93c589,67928a37,b6037b72,71113804,b2e64d8b,a840d00), +S(217cd3b7,9c1d9727,fd781ced,dbe735b4,2d655e69,e5f7ba8d,ce5eb68f,feb1913f,fe3fff21,ad8744e4,6e3fad85,4bed0d9d,f28b0bbb,96df1b40,b711ea21,b5241985), +S(55b99e36,7b8f7cd6,24ace387,2cb2675d,c25e6226,b1201b4f,4e1b039e,38365d75,706543ad,5c20ce2b,5501e8b8,4bf1d26c,fc07e60c,f40ae25,951fa46b,9ceee474), +S(db0bc491,688dcff1,6c81f280,a80ab2f6,c5efb3ce,2715f202,3f999ea2,805a59bc,2096cc70,588ea476,613ccb8d,c98a1989,8f729420,9adc1a3e,c77b126d,b277ecf6), +S(d961e10c,a83ebb9e,f39e3019,c1b378a,d94cc902,6eab0f3e,d203585,92a8e44c,87f46ee5,14689bde,3821f844,9f97a2a2,bb1db0f6,d2916674,1cfa028b,d21f40a3), +S(18ecc615,8d15a17b,50737a0e,6bc6953f,ee9f18cc,e20de26e,642a434d,d292032,63ada9c7,e3a8e367,970af87,20417ad2,eef85059,70b81b76,609fe8f7,c3a00ca4), +S(6ff356d5,262df09a,33ec10f,eb2e48b7,db91d6c8,dcc92f9e,e4fc39a3,813bba67,5bdd7a71,c46cc142,7d8a1835,e7ffee23,d0e025a8,e3027b1f,4892af19,2a2f0e0d), +S(49263558,22218dc2,943140c5,3a706f11,46faabef,f0fccaa9,77df5f99,44a77b2,d4d9db7b,7999d45b,9b51d776,6235e129,80c2d936,1943d867,65c4a54,5fb58e14), +S(ba68fca3,2b5e907c,896b3d2e,b9869a09,9d0f0fd8,bf8e06d9,64a6938f,3175f281,694d19f8,c8428ae6,16a78a85,57c9ae25,96a56c8a,1bb9f679,33d6e351,4d59fe8f), +S(5c461a52,3bc37bc5,39ae9769,5b59599a,86d3046a,36f4922d,a6f68212,19a89bff,d98b7b7c,5190ddee,481a5c3f,7982b4c5,b483822e,a211ccff,bc44d03e,983295ac), +S(43e3275a,bcf17dfc,7560d135,22f3154b,ccaa6090,245a79e9,373bd867,f48da149,fbb015d6,9f2aa00b,63c81226,b9165afa,1ee6be9c,8e680adc,4d2e5256,6c7723c8), +S(384bc1cb,8221098,4ff0a800,dbc85225,cb4a5f1f,477b4228,5c59c7bc,262c29ad,21061a79,e7dbb527,9ac6fc8f,e2d87642,cfd71eba,12220403,8792cbc7,9d8bce1e), +S(460c55f2,fda793b1,5aff59b4,cc819f12,de803b1d,5c938a2a,d30649d4,a38b58d0,832f6713,e63fe5d3,dde9534b,29d216e7,2434dbe5,6f54c9cc,ea683b17,33075c2b), +S(5e4a763,28fdeb17,b7cd2a8c,47b58307,538c6f17,397fcec,c9e5a377,6a39383d,3b3eb0ee,d7e28701,7bf034d1,dc1f239f,64756481,531d3692,bf639eba,2ad6e02c), +S(5ee48142,c3cb1ee5,45f6579,a36c589a,f886719b,c0b7bef7,c49c7a93,f3b610d9,55192e86,467835c4,b488b869,3f6cb7fc,94e49b03,8272abf6,69cfaffe,234c783e), +S(13b5072a,bb3d2943,c24fc4db,5b5759c2,290d6c92,11bdb80a,3b729478,71f3322f,ae8e7641,39207e9,ca438902,e75cf685,641cf5b9,674ba9a5,e9b26195,30180497), +S(2f2fa1fe,582dd71e,3bfc0e34,f1f5e8ef,12598b52,1ac2847d,90b5dbe9,152ba45e,82967c82,1d7dcf0e,6c624483,863c6c28,76ec8adb,43bb44ff,b211ded5,e7c397aa), +S(1b7be0da,e6633eec,f7895c64,29ea8088,1c2ec66f,2a273819,ec3331ee,830d7c1b,cd884cee,15652542,4bd8b512,8c05a77f,3c292260,c8d30471,8eab87a2,46f75ad0), +S(247531dc,f0bd40ff,7208bf59,2fea5982,440e3f05,8da7ba03,efc7cb94,4b48180,cdbf3227,62033470,e47cef0a,a5c9f2ac,9ca08b01,82140d52,549d24bd,d0f17ccd), +S(274ea538,f2e50569,9f52a7ff,bd058c83,95fd75fe,98fb66f0,ffab658,a1e1556,5aec461e,79c048e7,794586e6,43d10236,37f8c376,7d158968,16ea0ed1,56fab125), +S(82935503,db88453b,8794b70e,9b5a3e37,a804547,48d80c3f,d2e2a85b,844ac085,d507862d,98c035d,c1dd3d1a,3a7679ac,bd80df3a,4e8c4fcb,5b5761f8,c9605d7f), +S(cae0cdae,216c0e62,e8324d9d,95b15285,e43708a0,dbf435fd,d355fcd6,227d2536,f442e7f,d546d149,d0075926,fbd6e15a,805a85b0,a78ee674,c15ba3a9,a6d67b70), +S(a5a0080e,55ccd7c5,d6f708d3,34a78c49,b22442d3,5bce311c,b660af79,39cc70db,c71d761a,98c974bc,570f303e,d64875c0,d9e64f44,63d9db4,fa2d0e8b,80900c12), +S(740c4a8d,2dcc8a6,b11feeec,8f60afb2,e59b02ea,788d5f4b,62da8397,dc88733e,c8f3eb37,de1a1332,c6e010e1,913ea2bb,14b10e1b,d139dfb2,2858e760,eaa16f05), +S(551b7b30,507b2df3,c07955b7,ae91260f,86d899d,ff28e68c,67d8abf,cfc0d936,4c21135,c84fd85a,ff5839f,5192a854,25b18720,4a92582a,1b4308d5,a4c0db9b), +S(e11dd54e,f04d524,7ebbd72b,edffb50e,d0d4ff23,8cdad3fb,f1ea8067,93378b5e,46bb0d5a,be23f71a,3f16f455,c25b19c0,49fb9d25,9db6c94b,9b6b1f17,6edf8fed), +S(570d4783,29cc718,55de654,48255925,a5b094cb,5c55f10c,4793e532,60c9163b,331519d1,e5444f30,a4b1b753,a769eb4,d21d824e,a8151a40,2fab9b47,1c2d5625), +S(20a184e6,df5a35b8,30e97ee7,c3d4390,eede5a69,ce1c36c5,a77948f4,edc4812f,e46f676e,7b524c40,a6135f3c,7474d8f3,c3b0d45a,1a5ed4ec,91308a8b,b89b5a9e), +S(c7daba6a,960243f7,ef0664b8,f66ddb24,8a7686a1,2095370a,36316ce9,a4f5abca,6207f622,619ff1eb,fbe5264c,7f7bfac1,fd0d96e5,fe1a8298,a7ff4d3a,83707327), +S(b9d8e4ba,50549b01,491df2c8,dd596ed2,4ce5ac19,deb88450,a69a8237,d45f6507,5aae938a,46a3b4c7,6dc96894,798d2dc8,443795ad,6a393f31,a042d5c8,83ec7d12), +S(5f9629b7,ecbc8b0c,62374b50,620146fe,980791a,dd24d2c8,b2b3b786,9800a4c0,1ddfd8f1,ef4083dd,c6da5173,d16d68d5,7425fc02,e3943d9,a594e98a,ec06285c), +S(33d159bd,d0610753,10d3c1f9,ce89bfa7,affc80c4,5d193df9,55647519,357095f3,42c8b3e6,9b81c478,57a33b1b,1cda5b68,3662c1ab,f99ef9,5ed1b250,9a5cfb90), +S(8788f2ac,518a4024,3607d127,381f1a1,ea3e581c,89b8d90a,2d2c6e70,f94ddf6e,14112b9a,ef954527,811f9249,5de47e6c,eed1858e,5eba4aba,b1580360,fa05af7b), +S(804b97ae,219b7647,15bd259,255d3275,a5d5cddf,3e750578,13354081,6d9b6f81,abc3a542,1e195c33,88c0c4a3,f8448ebb,ca3ff868,a41c7c0c,2ecfdfa6,409bcc24), +S(195bde17,6cd7ea62,9611d9a6,c55ce4c,e7cdcd37,2d64ae45,f7d449f2,ea32f6d0,6005b5a6,890e472,af884f6f,6d5c8111,1003e809,6e66e22c,1468c962,2724111d), +S(9ab1e545,c9808482,2fbe050d,bab124f2,71b16028,e6e21247,ccd63332,26500c42,cb6bd747,4b6df912,e130b611,c762583,c81f7c5,38dc9766,e27f9194,6d1aa02e), +S(e87cfa04,8fa5bd1,305f73ed,971c6d23,81fa39ad,3d583744,c243bfb9,fcc9023c,7fb05d17,d789734f,7a9c1644,21a28365,3321f261,752025d2,b91cfc70,703e50e9), +S(5195bc3d,5ab8164,4ec40b0c,ff5fb1a6,c749064,9dad884b,ba48e92d,6f35e5fc,2b7ec6fa,97b441d5,ecefb879,35e059db,55d0e3a1,6d693899,d3c0b213,4fb04981), +S(eb2d3530,17df63b4,eb17dd73,ee58d282,78d01137,34a41020,cdf0444,8556792e,58a4f4cf,9247f908,3c28a9e4,da38e8b0,3cbf9e4f,2b92715c,28781d86,771ffee3), +S(8169465c,2da73cfc,daf3f3e8,538a47cd,ce088ccf,475af747,11585bfc,14c39426,1665d78d,e7ffa7e4,810ea80c,f12d3925,239b5c6f,69652fd3,44ba8bf2,e0126db3), +S(96d8634f,aa85174c,69e313c6,430eaaec,bd2ffe3b,55a1a0ae,e78fcb66,af33a3c8,869f9e70,344df870,be6a021,8bcf5e71,afc8a290,51d875d0,5c76f72f,e8fbc0cd), +S(3a071936,1f0234f1,9cc3c7df,40eaf836,4669615c,9520b0e9,c56ab987,dbb36bc7,e43415dd,cc244c05,fff14e0,f21cdc29,dddcb403,5678584b,1a3c5484,e98d9625), +S(cd3f1530,5cc9a03e,d05ab14,a81c58d,2485785,289e2b1,7382d45b,b935ca4e,c451f28a,e7aeea28,ee7ae093,46b352d6,bcbfc3a9,b0bc9d62,9eebba56,877ce9f1), +S(677e2061,8d0b42ae,6c38532,669cbfe2,56ac4b5a,40f1de16,42d97a45,ae34fdb7,ec23dbc2,bf750958,9be01e95,ad253816,7a24b700,1d9a8a20,218f0866,2dc2e378), +S(f816047d,1606074b,c54ef03c,e205dc5c,cc8182f3,739ab8b2,7dd09fa0,50d2912f,de012e8f,89ab0ca4,d8f8e323,6e0c2545,a6105fc3,602e978b,f42a5652,fffe864d), +S(11f9ecb0,4f273b9a,a699a3ff,4588ea19,2504c00f,55145cf4,10cecd40,b5f46f8b,168c4fb6,afedb0d6,b0bed70b,610c5538,e796e0f5,851e6d36,99fc49a9,f62c5b10), +S(efb9a14c,f6a30d5d,f30de8fe,f9ce92eb,6f566f8b,b65152ae,323ae56c,88da79a9,dda5df31,f184601f,a45747b0,3017ad22,e49c3892,fdc28c7d,c0d7e099,7cfad33), +S(e7b66913,dc55fe07,a9941600,17241de0,7867a77,8fe4f998,19efb096,8d426966,adab1d03,c8b96717,db800f98,e09ae855,2c653266,84886f3f,15c08bc2,10bab6e5), +S(6fd3c1e9,6c176c59,f94791d,fb9cff5e,901f676a,fd7e66e5,f69184ab,7b4e31db,ebbac252,36e640f8,df593a37,817911de,b85a5597,bb0d902b,7a97ff4,18689609), +S(2667971,943d720e,7d64d2b6,3d7fb50f,525c9214,fc89c957,7e00c007,4c39a907,9c1fb427,29e57196,33af3187,ee109b46,fe708cd8,5f222b25,bc0c5ae1,300ca331), +S(e34d8507,b11a4ddd,9fdd654a,ea6c4876,5473bb13,c9f18e6f,c8b6e3d1,5eac015f,d34c6080,22a54602,fccbab5a,e1cbd5fe,7ca599ee,75c51117,b9537c7f,44f90268), +S(e8b6557,441ce4af,7ca27f49,75107ff6,3b108058,d42d5e08,86bf3bd3,46e52e24,b15eb15b,b3fcc5f7,e3fcaf48,8f5048dc,a4c587a0,5b982613,c78965ad,b0d2027e), +S(b49f84fc,3ed84f9b,3ced0a5,7f953116,897c892e,d0249365,d8c733aa,b97d4b95,4f0a63e,42aae565,32225dc5,894c6fce,15f2b25b,e762f49f,a1d74d5e,6a23fffa), +S(99b0e1f4,cf7fc243,ea34dd0d,73705809,935b6c03,c0a687ed,7bf8d69e,d79dc2cd,b61a5574,17e236fc,a0615fcb,4d6ba1e2,21fd49a8,4003e8e1,b4e4a648,b6a088ad), +S(1fce8906,c4c420d3,75ee3ed1,2e603855,fda8bcdd,f47cac56,3595d3ee,6b4cbbc9,daf0cedd,acfa2409,e861d1,5cb260b1,eb84e1fb,22f8f483,e4524750,8c3bbc0d), +S(df85a7c0,fc08b916,43ebcc41,6bc86ac,bf4581da,fe0f7418,66704eaf,c24efce6,5d1866a4,3f06fa8e,a36ddf3f,39afbdd4,97372ac5,2d13629a,d546d4aa,ce7af9e2)}, +{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), +S(f8922b8f,c310a77c,c3e33a17,d88534ab,ac952dea,355fa763,14e2d886,44b70136,dad313f1,5e0ff701,acc8fdc1,b849a1d4,569de031,6a6cb83c,51629e89,99aeddfd), +S(d9e5586b,cdef070f,978bcaba,36cb7828,8ba43e5c,f0273389,750c95b8,4cf76c,f04abc01,6a060cbc,3a0d1d8c,240995ce,bb6c0d2,d9cdec87,fc8b9f39,dac5b50e), +S(6a206413,757143bb,c552fa3e,180d8e98,cb96a816,136dbc2a,8cd4c7de,6f508a44,55ee4d0f,189bd91,5323aad,b452a7be,298c183,b6843f5,25cf7b4c,ffc7b6c), +S(130bf00d,5caf1767,83d11a2f,acfc3cfa,ed0549c,5ecc381a,d1927051,517e4e88,506fc4f6,8b8be0b4,9537efba,d532f50b,156f5370,725c23b,66b0b758,50a45c71), +S(d85e7a59,54c93649,44d0aca6,8a534e68,42bfaebe,1806bb41,1af01358,d2d4f47a,8a8d3741,21f7390,879a892b,fba08959,23db88ac,867b9ea9,6888c43b,b651642d), +S(88c5e26f,91f4dec6,5d222318,81d7eb57,d3f7e498,fb1866f9,5015e045,d0108eb3,59d66b66,cb05e136,95d5bb41,d25e5b87,6b02af1f,7f29fc10,c67001c4,4bbb7cc9), +S(be062a25,7cb5ede8,e5926608,9a762e30,816d4463,cc5b2338,f4aa6309,f7722aad,16f30af4,c27c3f38,82219d94,a49468c2,3e8cb1da,747ff22f,e23c7dbc,b032d3c1), +S(292e8df5,2c77c161,6277b962,e10c43be,1c820aeb,80f083fe,879dd961,51cb84ef,7c7bafb3,a3bab2bb,2f9dfda2,68904ee7,823e6fc2,2077e41a,af16ed6d,e2ac43ea), +S(b14d3f06,8a0eaf5d,6dfa519a,d0a692e,3020b5e2,8c31b79f,ce6400f0,12e0de71,c383938,630762a6,ca5646f1,f2f02e6f,939575bb,353a9dc9,2a42d50a,857ded94), +S(f41b4e53,7560be3,b604d846,558b6990,639d00da,c6c7e98e,c07d1574,a71aa7f5,c34e8e3e,8102f564,fcc5f376,94d80a65,b616dcb2,d025b701,fa615539,6a105255), +S(5fb4006f,35994912,403a952,a1f53d15,202d8305,389fc093,4e4fa6f1,236892c1,1c5d613,e61f1cb0,e0805743,519fb564,5bf14c51,e61e6cd8,bf08c5b4,9417b96a), +S(e4e428fa,f6ba9c36,1593230d,e73afeee,9b580d5a,ead54f55,2e464031,bc6dfa24,ab8d0919,f7e8a7b4,99719862,6943e144,25d15360,ca0da2f2,637d8542,10158268), +S(53e304ca,eb03205f,f80fea6f,3ea38010,531e1d2b,c6d1fd25,804ad799,e2f05984,434777cc,b848ef4c,f6c205f6,621d5cc5,97c8c2d8,34ed12e2,28e3fc02,4bc4fc6c), +S(664a810a,a0894cbe,2f85817e,93b1d731,5a4047e8,266df3b2,e8ab5aaf,b790e0b7,f5ebf5e8,38f7fbf4,b904e874,48de1d1d,6befad46,ca68db2d,c08f8d43,4b6e57f3), +S(4a697e76,a5db2e31,34b646b7,a59e8ad6,9ca45eb6,b77aee2e,2f82f113,4d698262,8d5d47fb,76769327,7b24d6d4,6221e67f,cc9b937c,31e30fba,9e5ae198,597cedd6), +S(7e227b69,18cf61b2,e33e5996,192a0ff2,89cc6853,9e8a5ce5,65163662,83d8c423,299b7e8d,d2e45efc,166a37f8,d1036a60,40c5b43d,d88cbdc8,729669c1,98d5847f), +S(88afc703,96dc444b,70b8c36a,a30f5a6e,212dfa93,d4eacd3b,11e47e25,9bc7d42d,844425ba,79016a22,cb99d0ee,6ad40ec3,d0cd5639,1717eaca,1425e3e5,98db73ef), +S(75ba04f8,349f8c8e,69aee4fd,662eb9b0,aaba10cc,555caaeb,c12eec36,70179d36,fc0a0931,cc6d5662,ac8bc2cc,c7dbcdf9,db139e47,c5ba80cc,8778d11f,ddb3caee), +S(85c4f2fc,b3f7103b,6970a16f,8ad3d1ef,e1cedc24,3c576235,d9af669d,5f7a5a94,b575c9df,4162c450,4b61412,a3887a44,94bf88db,cf4c6ac,52af5e0e,52382ad7), +S(5a3265da,5b752377,50fafc55,e2affb2a,b2721932,c9021dc8,5bdc79ce,66d0bf0d,8101544d,688db281,c9a7588c,dd72dd63,734561a6,a91bec5f,52641a23,d4e091c7), +S(6177daf6,809f918,f8fca135,f71b89eb,e8700dd9,47243c2,c36fa883,182df3b9,8ffaf7ef,3c8c6422,33d7d43a,c01fd1be,a74c3dd8,3554cb81,7939ef62,cbc8b592), +S(3b8f7e37,b09e7276,36068698,fd87351d,950129ee,eee44a88,9c7a7e39,d49e2c5e,8ce941d,a2ba686a,e3264228,48a6e76e,a0118a7c,55fb37d7,7fd6b9de,15b867cf), +S(47892789,cdde36ea,29dfee45,74173afc,11515dcb,fc53a82b,5c2b29da,9201c8f4,d4717288,94fbd69,44c690b9,97ade5ea,d2c10917,4fe36517,57118d6f,b6264461), +S(f8dff091,8493e499,fc13a155,933384d9,fa83972e,9b099bc7,236bfc07,6e24966b,a06048a0,ca130916,94217147,1d803d56,99cd9c6a,cb98ee56,96637e5f,2a7d923b), +S(dccdbe61,aa1ea411,8443d950,3887f76e,c5e09092,de7c9c7c,642c5755,da678a79,f4cf61f,c7e1630b,2cae9d87,6eb29ceb,dc9b24a9,76c9540,f7845233,c9998493), +S(da4f38f8,13dbfd52,b45af510,59377f94,7f8f0158,38135451,d9713746,80e9c3cc,da4a6ea6,f8526f63,46edb7e0,cbdf3ffa,586f64e3,280b8052,4d2c19b9,f343976), +S(999029c2,9badca65,16360432,56f3bb93,f1b608ac,5084711e,242d9b76,2b1bf371,dbd72bca,1f01a2a3,2a760f89,e45df463,319362d4,61df25ec,1ec9a71c,e85140e7), +S(6c502c,1cf38e63,65275058,dc610392,2bceeed3,ee0a1aac,2838327a,a4543303,f0f4c4d7,b68d69a8,7209c888,7b725b2a,2a8c2c5f,b7c9ecf7,6c1f71fc,e398b92c), +S(9c31fb8b,f57d654b,a0ff1bab,9fa0ee2c,9bc86017,67876b66,83cd8c09,1124f421,b6ebd670,b4e352b6,320134a9,fd765d26,b2e1f109,f5f55958,23d7eebb,d1bfdb31), +S(fbc3232d,c40bf025,1a0551ef,4f3ad4c8,51ab66a1,f2c709e4,70a751b9,9f9cef27,552b310b,6587b1ec,1b84242a,3df96073,e35d0f7d,d47f09ec,b3021773,1fdf308d), +S(90e71b55,cdc8e2d4,f12fce5e,4719b8f7,5da7966c,4480557b,58e567c2,eaf48ddb,ff989ae9,1f195713,886dd3bf,6fcbf0bd,70d62153,9d4b4ee0,b0d2d15e,65340644), +S(829c0322,efef509d,a5284d8,96d3df37,54c21f77,f83a1093,1cf2fd92,a1594905,8b6ae670,d9b03d21,da2ae14a,5e09e0d3,65d31b3f,e1da61ac,7499a908,47715ec4), +S(db748c28,5a6b3d42,9b9086cd,8a50d16e,15788a48,2f06a43a,2b7da677,d41c8f60,f4bf5a7a,bb4492b,4dfec99c,e7c4cc15,2bf32cec,78a3cf7a,4833c10,251f411a), +S(e44f84e3,3d2ec8a9,2d905c8f,1d6d46bb,f8b730f5,a07fc25a,47e3eb50,4adbd5f1,d1fe0cde,a9becec4,260d0700,7ba21d92,cb7e069b,4f81bbae,bab8da7f,9ba68594), +S(3e9c39e6,7d0891e0,9cf7eed5,b0abaf27,b98798dd,c926dd87,12be6af9,6610f6dc,c04e44ad,a09d96ab,5d38ae1,94d65109,ecb95d3b,6b79d019,9641dc8,699789d8), +S(4fed63dc,b7587725,113e087c,fb0b25b2,6056314e,690b6312,1e906e0,5d98c34a,c69bc4b2,ee67000b,b66b6f6e,648cd1ad,ef9ce6a0,4add42ec,38e0156,dd8e8af8), +S(501c9927,f0b4c19b,6b0a9595,2387324,b9f31d90,93303544,ea002f57,4b83c51d,14770577,38a701ed,c15fb98,c6e224be,8464e4e7,1f0e3350,899bffc9,c1ccd33f), +S(98af3ab1,9c4fff23,8d70f1a,efb4a80b,234664da,ec2e44c4,4df93226,e7aaf714,f84cfcf6,9cf1960b,6d13cc27,aa875a5d,3b29907e,455d5925,c0a3096d,44924405), +S(849672bd,d259016b,8e07d627,e57813a0,e355bae7,ed64ccd4,251a36e4,48d0821c,8d0366fd,764169a8,779d21ca,f53ab78e,caa8a627,32b74612,5e831d17,9147d2c), +S(34f142d5,744dda88,aadad850,e7f469d7,140dd5ee,fd3dba28,86f3503d,16fe60e,3c3d20fd,c13b78fa,d0b7fe35,3bec2bea,b1509a12,a03b1e79,c5ad2294,41292728), +S(ffe5fd9,b78378bf,4738931,e03752bb,75855c54,f4e3dc8c,c369c070,450e24f8,dc57ffd6,b87dd1e1,dc466dc,6423e1e8,4174a5a6,c014e069,ae812d80,3c6abdd6), +S(b43a85b,808e6d6d,32d56edb,5d64af6d,cbfef633,2cf662fc,cd137d2a,8b505c0d,1e61d507,8ee9ec4c,c6be2a87,657cd3a5,f30d508e,c35e459e,e2d0032a,702bf4e5), +S(42be63ce,a0b6e88a,5d98661e,c99d493d,dbb78f09,ccc8fd30,eee4e148,ffb0cfdd,38d7e392,19f5a87d,e36b4937,8f1ed166,23e93619,165e2968,84294946,adb1e9d1), +S(9996eb8f,f8c8bfa,d4a4c502,2d8ccf86,f59dc8af,750734e7,e054f783,2b6c0f05,f1c9387d,9720275b,171a93dd,4bdb8ef0,7b73763f,5323d5df,df515ead,2bc40aa2), +S(66f17b8c,fb9b6003,b6160370,8f86f93b,3555c338,d3a346f1,fd9db3a7,37c197d3,4d0233a2,eb52e023,33c7d4dd,53703ac5,c566ccd5,b1e76b2,423e891f,60a8dff9), +S(ffd5e8b1,b2587ba9,79e90dcf,c6acdb82,86328779,224a4edd,dae1bbdf,6db06568,d75d57a,4d17dab6,43fa10bb,35857dfd,f2f7afce,f6c5bebe,7e13645c,f6f8e3a1), +S(ae1f1297,8a7a37ad,87a8aa8e,1e89f0d6,15040c25,d6d47193,e33f12b8,e28baf60,e38669e5,18c7cfef,4ee61807,b51fe9fa,403f1528,ebf2b27b,af0a15b4,fd39f5bf), +S(d330d887,3bf11a6c,f9b0c1ef,46ea64d9,973f14a5,a93cdb8f,7d84f515,33a34b90,b56e5c4c,8f236f34,78ab2620,ace7ded2,1395174a,76c5c62,2ac50b78,da16ae14), +S(1d2ff433,4e908a9a,fa5572d7,8dca2a81,8f8a651f,4bda506c,ec0aeec0,91a4391d,292d6a4e,5811de83,e318a6e5,861581c2,192b1f59,30f42d1,40893a20,efefe2fb), +S(8dc6cfa6,cab6f691,bf468059,7400efbf,8dfa76c1,8edfb8f7,ea78c24f,3bce2bf7,78874b78,47543ed8,2f983f80,c1e83ee4,b0dabf2d,3fb7d695,ab1860a7,967ffb10), +S(5ef0e616,b545e053,21bca097,ef424f4a,ed40b6f9,93a550e5,e11bd637,59266713,c739cd37,7700a1b2,6dcef2fa,c219d05f,646d86a5,850505d4,21ba8b38,54d0708b), +S(60b3faed,cd527d8b,6f806cb0,f234a3ff,df62a755,87d3f543,efab95ef,e6ab104f,e1e0cf1,e737f246,c1c3bf6f,92140a3a,34c98d53,32ed25a2,d7a48247,98d5ccc8), +S(d160c9c0,133d78bc,62a2e946,49cba513,783682d0,dad71915,ce208a9b,446a303a,bf466216,73b02b7,a782178b,f7113433,73cb299f,233b11ca,4d4014f0,2fbdafad), +S(201b7a0d,5f431299,34172b40,1744d18f,477d0724,6ad2016d,c8ac7d3d,32ce0e93,1fb192ee,55ebdb37,52b6ac29,c7485a7e,f8b8a0a0,a480def8,fa07ed29,d3afdb4d), +S(7d104d3c,62abee57,1f2d2243,c95bdca5,dc702807,fb060577,bcd1e50e,697c929,a680c234,1c12a157,f604ac5a,b74ae532,5fc59b5c,d8ad784a,5d66fd27,ed3958bf), +S(8e279e59,c87df705,b764c456,563703bb,1836aea8,93dbe8d4,b0249223,13e3801a,aebc7cbf,ea3fb75a,6f059f9a,57bf8ea2,d0758d51,c0d57696,f5eb4d38,6d1d61ca), +S(b206020b,a960cc8e,ba4d0263,bb0f2241,a91341ce,f0102509,7cf7ef52,97f96935,a249971e,6bcfd543,c4b603a2,70ea667b,8524c136,c15913fe,91bb009b,796da003), +S(1e6cb8e0,4b998c17,b0887731,24ad3f44,ae7a89e9,b33ca730,62233a4a,a6b8bac,a50a3841,9da361b1,f89a8fc8,f29a3fc9,a6f8aa5c,36516ea7,2ca4cc15,96330dc0), +S(449005b9,3279d7d2,9965e131,50fb7cdc,18619541,759706ac,6908ff71,ce5c2cd7,62f1e74d,1f31de28,221d0dec,3d063f76,ba5e742a,52d0b48f,22d01ad,58791862), +S(4030002f,2374d275,3e9176d4,3bb4c2a1,c7a4821c,f6b7119e,bba2d4b1,2e4b5bfc,a80b25cb,a4a75603,af82a624,b493ba8f,c46ab68a,968bff49,a0e1cf8d,9b7a4d93), +S(c75f32b4,8122b7dd,bbfb4879,30fe0ba1,99072105,6891b932,e2c7ea3c,eaf270b,309afd60,f5a0f780,5675646b,37029da9,601468d8,71ee3685,cf6a3ad,104f5017), +S(77a73c5f,1548cf98,9c284c5e,9f1ecb9d,ab55d2b3,982750bf,65eb7097,ed159e1d,112d6329,29e9aa4a,83c2fe95,531c0717,d84c9ddb,87ceb9b0,65e9328f,83c3699a), +S(f6a55eb6,d05a9183,d3908776,40a5bd0e,2a6b83d2,40cd5840,e25a8bfa,d2116328,ad0834ef,8672b707,dc99c4e7,1c9fc935,725ebc8a,df45cf00,99cac306,4a56796), +S(cbe913f4,48359096,dfb1b168,fb42d92b,d873b82a,956ad9c6,5e64a2b6,d826614b,893edb65,d2262b17,f5e466f3,88592e96,ddd70b65,65606ac8,289cf396,991a25aa), +S(f29ae654,8a6aeb10,849191e5,e87e2c0f,d8e70af,a15b8ec4,848407bd,36389d06,1dd72984,6e220fd8,90a1370,38c98e04,b096de6d,a7ce7339,ae697daf,db11905e), +S(32307117,b8d2902e,e325090f,97b518a8,beb9e27a,d3cb4d69,fc0b54ba,ecb14316,7970c3f5,13f69df0,400c725b,e84b1267,fe7f205,7a70c5ab,56ab0ef5,679ebfb6), +S(426e118d,b8ff1f7c,18ae29a1,b88e0f2c,2c286658,6c1c2179,edbd719b,31399dfc,7889d383,427740b1,4c37ae36,e51710f2,f5a8decf,a456d0c,a83ac66d,230828e4), +S(229c2322,7c4956af,938ac061,9640e04d,2c647692,e0e985ee,28cdc767,96f260a6,a056790,cbf36663,b09cf7e5,4b622f74,b185454a,6682d9b1,6cb2af2f,3ca8a7ed), +S(bb7cb68,23726026,12072e34,8cd4504d,50a3d286,669cb748,e69cd0ab,dcc93e8a,9d537ff4,532cd020,17756733,72ae3cbb,7aaac7eb,901c1e69,5fd57f02,9c336e5c), +S(d3460edf,f1405cb2,ef9c9fab,eeb71796,c9d48f66,96f8fd20,56a99863,2d278e8c,d9cc7b14,cd657e73,e5fb7207,9d421490,46266a34,7610b3ef,b631c78e,ed02419a), +S(d12b97a5,d5b7d74c,c8dd8f7d,45fabf75,105ebd5d,9990d99b,7d0738f3,49db1180,51dd8885,e6131a1f,320e1516,3d6e35dc,4978fb96,b531aba6,67231968,a2f0fca7), +S(f75899e4,e383c412,f6f9c764,38d38cc0,d0550d28,a150292e,45a2aaf3,c7025ff2,7ba7f1fd,d978939a,79b482eb,24776178,ebee022b,48f66c33,e7a8de58,7fc3870c), +S(9d3aca30,fadb9f90,778aab4c,b7b88706,cfced983,ca62ecdd,4724d58e,6575a754,f0f41826,c426e8c9,a832a211,c1835693,9a1c7c63,3de95bd3,7e6d9b6e,db41d16c), +S(63454665,5133d840,de3af8af,def0395,cce4e97d,8e0030c,94f8cdba,cd72c3b5,19994348,daf379d,5c626f75,12109e43,bda0e527,137d425,9d9ebe32,2fb9aca9), +S(4ec235fa,47217cc7,9e2cc90,216626f4,2861f8d3,e61665f4,37c83ef1,acfdb8c0,d0b35b1e,ac498e36,38fa5da8,310a8f64,62cbd671,9d4b9c2e,c3be9835,cdda0a8e), +S(27dc4da8,e16e0d62,4a0204e2,3a8c11dd,4ebc5504,3cfe98a4,7d91ab19,92bfdfa7,6ad18e5,fc0e8d1a,421f6cea,8276b506,96e0308d,3983823c,de917e88,195ae3a5), +S(7479c3f3,6a4b4d1e,fea25a45,a3c4b79e,919707ef,ef92c830,6d693c00,e9ff2096,5faaec2b,a9343e26,cd32a68d,7f441d7f,3ea614c5,3703ec81,c43962f6,9934b3ee), +S(3420c98d,a020a034,e094ced,fb80c251,6c84a959,f9ddaf7e,ed889927,9d98cd03,b6af487a,c26a55a7,30552322,b73b05d4,a7e819d,7fd84873,4345870f,6ce5b8ac), +S(4afb97a5,68556ba9,350dde2d,85709057,ac4f34f0,e9700939,57bc90c5,540c61d3,1a129c50,23c3e419,fa0d5bb1,74acacc8,9aaa1114,ee38b937,406b5da6,b99fd29d), +S(e431caf2,6d33fbc7,28a789fc,ce00f3a6,c4629958,6a03ccee,e84a385e,cbae856a,9d11cc02,df57742e,d01e9169,7e5bb434,5829d076,747b065a,782c8619,da4369c7), +S(94a651f4,4b112523,3fd880a8,99191f1d,9cd5064c,227c2fc4,de1eaaec,9439ebf9,85eca2e4,717816e1,6c28a5f2,c90fa6a7,fe4222ae,f811ae1e,acbcabb7,6271ed7a), +S(96ea121b,60d051fe,d5381fc8,38b70e86,257626b5,91184577,337fc62c,529355f0,b3a56efa,b898b7b6,b2d90341,cc91faa2,24e410ef,fdd9d7a3,6770765b,c412dd82), +S(4b7e0cfa,250661d8,fc2e52d1,4a2969d3,b301de21,cc7eff3f,d7d7d7da,e2404d9f,d5d48777,c77930ba,96d179c5,10734cc5,21ca4ab7,a8d7cdc2,2960ddca,c03ecfdd), +S(7ee44334,6c87bae0,c3bee1a,273f09d2,d687fbad,fe060ce6,ff376c10,1ef266,ca4d7e06,2a28edf4,3419d107,41ab1017,da1bbb4,2e26a282,5d8d5a07,6e377b5c), +S(e31aa2dd,5bb618c4,63da1ee6,ae50ab1e,ad967b48,ff8df86c,f0c9ad2f,9e530ab4,3b3f92b7,7845a7d1,6a5b02f9,13354e6b,5388583e,546bdf9c,34cedd17,a9d4e11c), +S(15755ea9,907f998b,f75d38af,d4716cb6,4ab3fd19,2a3b62f2,f597708b,33697405,3ae19c16,8fec504d,8cf4320,c08c2dd7,605e2fef,1d8ebc74,1330e78e,9803504d), +S(2d2da66,d08289e9,f1674782,1214edfe,9de40a91,f1a378bd,e5802bc7,95023cb9,2e48b7f7,6dd20f2c,df2b0c18,1d5c691b,7836c6e9,8755aa05,62277426,53df2a99), +S(1b4bdf1d,d34b1b24,384d28d0,27c404b4,2691ec78,3949b8a0,65615a35,ce5c6c18,33590a6c,679a3058,5fd82459,f609559a,edf525e5,7eea0870,22d60d8a,dc57af5e), +S(3de0d336,b7bfa62e,5bfd8265,4a149e0,fb9a9add,6ef9679f,1e96b911,2f4bff69,ea44028d,b24468f3,bec7b60c,22c72efb,ae8f86e,90c3e2c2,b885b228,f7a1e123), +S(55d6d2b2,9314bad1,ae87da3e,e30f01d8,8844d27f,6e85a071,539824fa,dbc064c5,ae68132d,6f412ca0,3d70b23a,cf88d7e1,2443da6,cd5c2914,1e44199a,685cd459), +S(7ff2bf7,4696ee5c,fd709fa5,5d6bd376,b67fec2f,1c8b8982,64628e7,445cdc13,aa0f1082,f90052a5,c7a92350,cb3e27ed,9ad895a7,a73d4929,3864223a,b2640cea), +S(6fd69f09,3f4cf5d0,26703a,a0836ff0,2dc344c7,ba36bfdf,c98fe932,c70ce775,a2a95599,4651742,728572e1,5a9854a2,3cead0ee,c7edf4a8,f79ec569,36cf300d), +S(c644d73f,c2170115,78c4572e,9b8ed701,c36dafd8,e1602efb,8788c0df,a0b6ad48,38fa94e8,46ac717d,88862e2c,94e90e15,97a9144e,2e1900bf,1cb40218,e22cc2aa), +S(864820fa,f8975085,f69432ff,2f638054,8b972f33,7b74386f,d113300b,d672cd3c,b08492ff,37610ff2,fe86d3aa,a3c62747,3be55698,f183bf58,f67872f8,cfc9cbe4), +S(cc3f0782,8c7e73f9,a3cab59,be37008d,6574acb2,f7c4f0bd,4cefd6cf,b10c25e1,41751bc0,b9b0ada8,9d7e430b,600b00f2,987c0639,bd910c32,d1e8ede1,b183780b), +S(a7c1d70b,73e901b0,b892059f,4968d287,7026847e,187766f4,7b82ad0b,e874fe5f,87a6357e,83bc6dce,d3a3700a,1536920b,b0dabf6b,2ea70f7d,1a88917f,ec51890a), +S(f10a662,f02cab01,f47c6415,70e9a020,2584f160,8a69c02b,cc5509f,e54a7391,70422b17,3c20d128,30da1a71,57935a87,7d6db2d7,b7ee5272,5b756a5f,a0ca8891), +S(36ae45a6,efd7f4ef,7f66a206,82d027f,25b8cdca,410901da,1152b2bf,2df0f14a,ebd682f,c4cf31dd,c39b23bc,de979cbc,7000724,8d4c75c1,dea2c62f,37823e63), +S(ae3d1eaa,e04070e1,610c70e,190f599d,b2ed8dbb,5aa4be6,1af5c82a,83757f9e,6045833e,b1521caf,3303bea,eecff1e,a98477fd,ca29999e,4ff55264,24e87117), +S(8b961a4b,917a59d2,4ad0f94d,fe7840e8,f7f6573c,61de7f50,b3814920,754e5891,3a198cd9,e2d40f2e,7d5796aa,fef0b84,91dde435,1aa57366,65263ed4,5f136fee), +S(86d77e77,f7c5e4cc,dd2ff3a0,1589e422,8aa30d9c,162370e4,1ca47040,89b4e0ab,c0cf8d72,aa3b90a9,56bc8827,d3b33c1c,70707114,e3dab774,68894c31,3ecf21d9), +S(ea77fb69,a07e27ff,a2bc1815,27a7219e,2433a38f,98a05f18,9faba452,82722666,38f055e7,cab474a0,79bd635f,135d608c,c0b8b2aa,b48de933,c2e48386,74e943ec), +S(d5612e3f,304cf63e,23c280a7,872679bf,9861ae4c,965b79aa,db2e1ba4,cdecfd94,29e27659,26aca4a0,da8f3a61,dab6ee38,23e47fb1,36dcf792,181c958a,3ac24a78), +S(ce8968de,589a9b5f,49ddb8af,eb06ac29,ea053b5a,ab3c6dcc,69dd132e,5f2d115d,26f18c48,8de54fba,bd476b9e,8a6d049e,25d3d750,b8fe9595,a9eed52d,1865b98d), +S(728ccebd,7f098fd9,96bc257e,919961c5,4260365b,50f31d56,bb749b7f,6250b577,298522b3,d6e77839,97fc8fc4,5d4e853c,e530e768,6363b86e,8a68a717,fc5e4742), +S(ac7e69d1,d7d529a5,42fdc047,f9094729,45fd8af1,4ae3d71c,246a7c80,3cc7b1bc,af4c4fc2,9680bda0,bd2506d,7f64f4f5,f7b891e0,c50fe059,3246f97b,ebe10d1), +S(633605d1,9d61b598,da661292,2b6e5763,c765960f,c044c5e3,a4405449,cbd0fae4,fcce18e7,3c419aa7,85a55b57,41902cf6,855d2775,e8be678c,18388a0d,cd2b5de), +S(ea93cce3,888035ac,5a187cc9,70e6232c,37e2d0cb,31d9b5ca,33e567ee,62948add,d842a18,e2153217,98a620fb,c6e40ec8,66c9c6e,aabeaa31,7d6a01e5,294a8b0b), +S(75d25df7,63b00703,5e21753d,7e4cdde9,3001a820,6dd834a8,6e4e41ad,38e9cfd4,ddd41a0b,4528af7e,df820374,68eeba16,e2fecdd7,1378dea1,f6d0f734,8593233d), +S(b28186a4,b7bb240a,8987119a,7114faba,d163c3b2,66349ce6,328ec7c1,62ab3fee,4aa77c0f,8db9be55,58488234,61d6206b,80ca3788,f195a47c,ccfb7688,18bfb34e), +S(43638d8e,3331ad3b,9e4cda5a,fcfe5c76,b1a61811,1f08ee42,1c008d4d,187300ef,fa90b3a1,44d0f073,64734dd8,698beec8,8b916fa9,a7aa7d9e,d019d69e,5bad5af7), +S(19eda20a,1ca63328,29a7404f,51c7fc4d,93d0ee1b,76461ee6,42a07c07,3d73a1ea,a6c5aaf8,6a9546ca,81689f75,68709261,642a2d37,d104b7b7,98a4ebce,f42c5506), +S(f6a557e2,68fb6b99,5e2a9342,d5e4ab19,b95bf279,17285ece,11268477,427d092b,b10451be,cc64fc69,7801012d,7d58e4c0,17365faa,6a9db69e,fc7ae505,638e4204), +S(bed211ac,c6fff91,f1baf145,27c8d007,1b19022f,13e54f41,3fc83b7d,1c9aef54,b97ef30e,a42822fb,fde43ffd,28184f8,fd58e314,ef69bd1f,b1961314,fe4bd3ca), +S(593c25d2,f6059501,347cd47a,9658b04b,9fd81c8b,5754dd32,35ef3d51,c7ce052e,1e3f108a,c81dfbdb,eb544d31,d7892d4d,27d4e146,779135d6,eb2d81c0,c3ebe674), +S(207d923a,211e86c7,7d8357cd,19b95bd,ba4aa7ee,61d147a3,a4149942,2a23ab47,92fae109,11615ee0,9a3932c3,7945aabc,6b14e5e,a5934a92,b6dfb9d7,a68ba39e), +S(2c2029cd,d7aa039a,1b43c84c,5f0db4b8,8093192d,584818f1,f938eb4a,5c5accd8,35a55e55,41a70031,c5ac72a1,2a94d94e,1f467015,8ebfe17,70d2aeb4,76478cd4), +S(4f8e148c,6fdf65c7,4152d84c,5462eb59,e6bedfc4,3ce6382d,db24d20d,43e0927f,12fd3323,143df955,9f3ce8ef,30203320,893fe063,b17a9f58,5594062d,4478beac), +S(954cad68,1049614b,9bb5995a,f69868e9,44efaf89,5ef61aef,7d09e74,24151879,56c8e285,5df18b97,4147fffa,a561d425,c1d0b1ea,8cfae8d,4dbd3462,7bc57614), +S(d2b06281,2acb2483,bf26dfbe,5a61fa2a,2dc995dc,835a5ca2,86fd2d33,b273a129,debd115a,2a711cc2,16ded426,d442b504,475a5f2c,d7e651c2,13b79f99,74ab9997), +S(1682ab4d,ae292e8f,26520ab1,b8f8aca6,33cdd6a8,a0d585f3,5048551d,f4b6d354,80c160a0,9300aab0,f30df084,fa0bd259,fce78972,7f0a78b6,96562edf,d820667a), +S(b9252ea7,f64ee2e3,4cf31c3b,d9e065ff,1e0349b6,3f6669aa,19e42a71,72312586,4e48711b,3f0fe7a,89fee250,b116862a,e00da579,d7e29427,fe2ad3c5,e0ddccb9), +S(a1123f7a,81cc5e43,2a54785d,f1cc614b,7ebe0dd8,b6362e1f,cf41bd65,c3c4faaa,a0d31492,82dcf09b,2814c88d,d5aeb9af,2c16ff1d,3e1e05c2,68c8aa5a,8f5716c4), +S(f47f6d8c,a7950f23,a4a08d07,f5b8889b,c30e8ad2,8510d198,3dfed29e,e47af463,6873567a,2820f91c,506878c1,69e98a70,f3d6696c,455f1752,21a4e1c2,44dc62b2), +S(8efbf718,f124b5f6,807d3493,fb3dfbc6,f1c4f0a6,9ce81d20,3b13f422,b6ac1c88,6e05c0fb,77d12e84,64fe1b30,8207ceb9,a297334c,e937eee7,a9a45ea0,bfffb734), +S(56a8aa37,ece2a01,5f0efa3c,41f541a1,a9078c03,39b6af5d,9c9486c6,93bbf553,fa191d76,62b7189f,9ad68823,8655343d,71e7527f,2e72d3d3,1d25a4ce,719c7146), +S(cc2d4945,5659cd0d,19924df6,6be02e32,16e93423,9ab657ca,9003431c,cfe8e450,94a34e9a,a0814633,33b53121,3c375d6a,dd554ef8,cacee52a,a177ff9d,42cf39f0), +S(ea38154d,ee6d08cf,50c3497e,6e15a1b2,d265fbe2,cb945a09,a34aec36,35f18583,d1e16b50,cc5a8d51,f043ec05,1992ec53,d7020cb5,5d05519a,25d364f7,e498b28b), +S(82cbb42b,854e7f28,a2a786bf,6cfb4642,3fef958a,dc2fae99,5590d311,82d46c2b,96310134,eeaeb35f,5e2ae9e9,2c26e731,e0e65da6,b37124ef,c6c89e58,b7434314), +S(5f23519,92aa09d6,1ad78103,df0a060c,e939782d,774ec196,c261d6b4,5e42ff01,7e02b11b,5efb1a31,43fbb204,d63a7c5b,8a04a66c,1f5ec292,277ed353,adb8f95b), +S(d182f035,18ea0c6,a16056ae,a071a1b0,920d7a9f,37137429,5fa89f4b,1b4b229,268c5c3,f0d47748,effe1eb1,3b1b5340,4f61da2,6e56db7c,f2e35d89,a6bdde8c), +S(51e72ca2,3f22bfd0,f6405e3,57ba5221,310fa8f1,fc054e30,a34a0271,3051e9a0,307f4e74,b97c917a,281acb4,25d1df8d,ffd5e578,9b1d80f8,160c1ab1,ed79322a), +S(bb193d73,f08c5946,faec6f10,aa13f855,aee34bc0,c4b60c3d,2ae0c37,359f7b83,87cd0d87,d9d83fb7,3b382cc6,35d6dd63,29116267,5f1e3647,ca62a68,fedf7143), +S(9aa07141,e67fa1ff,cc307760,5b73625e,f804246b,a4e8e568,f0a7c111,76c61de0,b58aea99,47244021,1020a64,584172c,21c6f641,a14c43cf,377c1f68,b8ced736), +S(aba5e67d,8aa2366d,e77c9d58,1e221fa1,b0f0db3f,2d3679ab,dfffc4ea,45ad84d3,4fbdee40,48ffd408,712e17b9,2b9fbb67,ec7c9ed7,e6ef052a,b8dd0ecc,62fa91f), +S(bb9a0c87,e1fd476f,e8cac1fa,7f6cad71,78297b32,9fce8d9d,332758c1,1a8ef09c,a9c38e66,add0e7ab,538c62e,fd7c2eaf,3ee221e3,cdf581ff,3fcc1bb8,bf638332), +S(b531f3ba,bb94cf91,b492d253,a36de81c,476360b1,91ded661,7eecff08,403eefec,3f653457,6dadc53f,f2a268a0,b8389ad6,a21653aa,c4b65b72,758fd6ca,27f3b570), +S(f7e9407,d1f8f9de,182e273f,98984d57,de4f7c61,227c98ad,36589c2d,64728812,f3f15a91,8d2a5c47,d7fabf29,dd2a2380,73ef645f,924d04ee,31dea489,f6882844), +S(3aacd2b8,2013ac34,75a7cb05,e52c1853,c10f7b66,68e5f8fb,eaaedf64,342e2b82,2d33a32d,7f745929,3915760a,4fb04c30,f649541,a246396d,8cfefbe4,26f6573e), +S(f11a09a7,edc46b58,313c31ea,93364d17,4940c58f,8a8fcc4f,2bb132d6,bae01730,7a42dec,b0eb3b71,a400cc5c,4ac848aa,1e3cebcd,c38a1407,3eb6f568,6dc68d5a), +S(642ede12,2ed16043,ca028a10,e014fcea,52d6a3a2,9399cec0,afff3009,598e967d,7f86f11e,f79a0e2b,66ccc91a,3164617f,f08c85db,c4f1e4f2,a0972c43,8e15b6de), +S(a04415aa,28f065b4,5b60f57,2f665229,dbfaaafa,e8c0561e,9e37e1a0,79231a49,a32b2e0a,4e9a23af,58b398a6,56aeb0ae,6a98ba4b,abd1db60,8959da55,14710f08), +S(b0904d2f,333c0cad,9eb4f5b3,ebd1c176,3488ed9b,25f640a2,e9379df8,b4d170a1,ed8bd456,999ae102,edb20bf8,3f903319,97233e29,35e1c52d,13a52cce,32a5e958), +S(e50f98e1,162614c1,6f2effc7,4853d7b7,2fa13e2f,2fc0b864,dfa1656b,2e1a0a40,5e7ad119,80f9533a,bd541065,c1309f90,1eb49aa2,34386f14,88ddc3f9,3406e986), +S(5d6772d0,2007fbef,4d385766,ab4b4fbf,1b3fc017,6f883d5b,395e5a35,763c9e12,f4dbe650,89e165c0,1fcd49e5,5991db5d,3cfff2fe,1730862c,3f3105d5,a9433e6a), +S(c971d45e,c78b70fb,70d2e4b4,b427b82c,4c569d0f,1d9e85fb,e4703d27,58fa97f,9c148ffd,295bb61a,d3a34548,625a447,65a7599d,5d0da8be,c30dad98,c735440b), +S(f118ec13,304f8826,bb744d7c,eb87181b,fe25c3a5,ed8df1a0,eb05bb65,860b738b,292a85ae,eaa3cc59,3dd8adc,64fa9e71,2824227a,2139d7b8,5720b289,f1ea54fe), +S(6b38d88d,e7629ab7,82d2af4c,93a62371,bfaff595,d422b5cf,b12e0fd,1155f5ba,b1a49c69,5439c867,5f491cbc,e3c5971d,87ae5a60,faf13c1f,7cb9536b,37f780b4), +S(95c357d6,24a2f744,d8989a28,8bdb7c0b,241413e6,5a26c877,8382270f,c291af61,142845eb,991aaaba,3e755ed4,3ff0afed,34643413,5bb13034,43b21a83,4f3c0e31), +S(feb4122c,23e68298,f4601b3,edb1de03,b7137341,6527e483,f16a14b6,660425f7,2b7f5ab8,1a2fd416,24d3fd71,781be6a5,1e8cb43c,7ea8265e,e5d92978,30388bb1), +S(bc0eae5c,fec4873d,5d34f0a0,86a96ce2,51369a01,ad2d5137,746bafde,a574d9a1,1fe1f281,999033a4,39f4c0da,5c1cf6e2,365b139a,29f82785,caadebef,ba5de3a6), +S(93f71e0d,d7ee6b9c,a017de05,db2a52e2,d2175cf0,2c1aa194,1c6256d,74907872,1bd2c197,6108b712,27e0bd78,b0a2a036,6564c979,5d1ab6de,7a12a0bc,3913c8cf), +S(f8388a97,45191a86,efda904c,8bc06801,faa3bc37,8a2425dd,2dff9a4a,4ee5d7bd,af2b9260,c452261d,584144b2,91b5388,3eeb5014,c0fb0a89,e8b78f0,9525b5a4), +S(c7e727a4,a0fc2d3c,4a5cdea6,c93049a4,52d3646f,35951918,eb379c56,50c544ad,37f5bade,6d3d9076,45a4154d,7d30ce2e,cb77a3b5,695080ad,bbdb8a33,4c7f7514), +S(328eb6a4,7cb82340,768d099,45902d56,3707c86b,261b9ce3,aeac6734,e76c4d48,ff1a5828,4f402090,c32f7b07,7e8c3098,7c3af703,604c22ca,aeb4acba,e7f52c97), +S(beb0522a,acc84b29,e0ab8233,6ca02733,9b4df195,bfb01a18,b38dcb3b,7c8a1e21,82d7508e,9491e2d3,d74a4229,df4d6020,1c6a86b8,a3a448c4,35dd20b2,f993e6b), +S(d3dada60,563278d9,38e48e79,f2e6bf8d,5caf0f90,affbdffa,c30d6e06,3f69cee8,8dc2beaf,34b916d2,b542121d,8e181735,1c55a766,ee46f2c8,bfb8b7e3,d5ff6826), +S(42111151,45ecbd47,1c8a812a,192b3a7a,ab43cbf,ddc49dcc,5a92f350,86069c33,f9428e07,f33cbf7c,7afd7cd2,f6afefc7,b0fa30c1,ecebcf92,30e20c17,7d94aeb4), +S(bc2034dc,72217bef,895c8d3e,5a5414eb,882e8efe,3dc8cb0b,cbab0edd,1bbca0a,141caac9,de3a48ed,ac6eb47a,fb195238,f3784171,4d7f3807,8d492a9e,a70d386f), +S(b8035a3e,9bdac3c2,58da038,5de2ee25,98ca621,d90db03,4057b674,21e2bd1d,f7af5751,a8e51665,4cad2e0c,61a94970,6b5151ec,1eb07cd8,1713c716,7a44f357), +S(740fa667,cc333c48,4880eeac,ebbf5fc9,34d3ac55,ea04d8c,9365e5ad,c3a404b7,33893248,b4e2e874,8694ac43,d5e6aba1,3afe26ae,3a51a613,d7e0541c,d9ba91f4), +S(673c1c4b,16c6a75c,28725630,340aab0c,8a7b8648,4b17714b,c955f160,e3ee09a2,c3f99423,2521122,d0dd518c,d9fc94cc,5b4c836d,9665cec1,1a024995,342f31ea), +S(a74784c,dd6cfd32,972124a5,dbc0233b,f0222de1,9f90ac0,87e95ab6,f40c62bf,ef2a3085,9a86e0fe,f96b2e5e,b7a63820,122e2dcc,a4f2102a,b501f2d8,1a88378d), +S(db1d8dd4,bbffccab,bf1b90c1,9b92535f,4ada68c,9d3cbf86,c0d700fd,61d4beb7,ddaaf64a,54972f9c,ea2c2fd1,27e17223,1dc38360,6e0589dd,a3f8d62d,80c0a5be), +S(ffb9ae70,2307914e,a9e4160a,1cb68f84,3fd03778,8a013f2b,f9e1d725,b09d8b40,352b1e7e,69e5afc2,6eae5b56,b2b7ba9d,ab174019,a03df463,ba510aab,c4c9e859), +S(ed27b183,29dd25c3,4a760942,b1aad66d,a1439b86,250db95d,98799c63,a9bf2fa8,8460eaf1,554c31f8,5c6baf21,126163e2,cfa9d290,17bfff10,9d295c8c,ddf391e9), +S(70a453f0,52682a36,1dd33a79,a65e4080,7bb95541,5d0b0c72,ca3d2b15,7e57bce3,2e40f3c,25554c85,cafe5e78,9aee14a5,131ba6dd,b9edfbae,338e8db4,653e908f), +S(377a14ea,78d4f864,5262ebc0,5f55a310,6a329376,be0d567d,a327988e,4e1560ac,ef069fd6,264ab8c6,b290c4be,6558cd27,2745d9d2,7ea22521,b79524e6,230a7c47), +S(39fb1a0a,924546aa,ee6b8f4c,65218a6e,56ee0e2c,3833a784,3858eaa2,f57f3399,e4bd9a53,8419ea44,30b041b9,e93186ee,d9ba4846,b6125f1e,c549f34d,ea5c2f87), +S(d255491b,62a9ffd3,5512555b,4c413eb3,b412ed6c,9b585baa,875c5643,70d9aa00,da4094ca,fff6616b,51ed389e,a5b9b3af,641f872a,7166427d,d24c5973,be24d067), +S(342d8017,5754c01f,504e6c0c,c4c6c8b4,a1079dcd,89de2927,a3227a1c,756de1f4,de8160ca,ad4a4f31,791fdbdd,4b9ab3c9,db9098f1,2db64ad9,d6f90ba4,a9b13a6c), +S(92e8a7d3,d4e8bbc8,4427ab1,a35e5a0e,c2d81c04,c98ff34a,325b4abc,2863fef8,e8bddcfe,876f7c55,86470c56,bcca444f,fee67417,8a592e0b,b9f5b1c3,b2a7e9f7), +S(eef2dd87,66dd8259,fd821f30,3771574d,4477283a,614e463,d81238b5,b08141eb,39a91138,ac12e0eb,da43724d,686d9207,1db46682,746d532d,55426a53,87b98023), +S(2efc16ec,974042f8,b1a91132,2ea4f521,71f76da0,196cba89,12faf48a,cbab65ce,97c0079a,3151c8a4,7dacf1ee,25bf3157,48a83cfa,1f3be2ce,1954731d,a2cd56ac), +S(3d2def4f,dcacdfb0,8dbb75e3,1627baf4,6deec0c3,6c4bb3cf,f96f13a1,2066ae14,41ab6cbe,eeae8634,2f95027f,e472834c,e626206b,3e1ce1a7,71b717a3,39e5827c), +S(ea23f622,95a65d24,162d88b7,6a577b64,1abca822,1c29d23f,56e4f929,a19dbe10,aaac26f5,c8b5bf21,38a9dd73,8ce69b01,6c6b4f82,4685fa39,c2de56ca,3c58b664), +S(f01557e5,ea723ed8,2d5e4e02,f4358ef5,5b0234b8,182bd4c6,e6310103,768eac09,8bd31626,7fb3e7e6,ae828401,fd00712c,9f4f4c7a,cee8f708,4eae9da3,38e12378), +S(1f645466,d562b0c,4618217c,4cef306d,7156a5e7,45327a55,40619bb8,2934a8e3,cf9dc7d8,e7c1c0cd,28d9bf5d,83a7b33d,e1060c01,eaf58d4d,10fde41c,495b954d), +S(6fa762,97a3cd7a,9799f3c1,95f56864,c5a8ad78,f4014c53,1dc83fea,244003f4,3bea377e,9183478f,89f94127,3bf5222b,148ebfd5,7125fe96,147243a0,d07c14c2), +S(71061b69,c5a32537,d40254c,fcc5f67d,cd4a8,40911295,8a8e3f3e,5f060a6d,a980fae6,eec78bd5,3c926649,96239cff,eaa10169,7580799d,5b38ff74,8f0f7a78), +S(518db918,8ed0bf54,75234c9a,7e9c0395,8796645c,89104797,5a8602cd,e7401e3a,10c50bd0,aa0fb6a0,62b964ff,65a5102c,d6bbb192,3dfaf2d7,edfbaecc,77cefbe1), +S(6f7fc8db,8d00e22e,6f30c093,573d9f5f,fa939796,6ddf5a59,6126f896,88e99dcc,e417e5fb,b55fc324,1a283315,3ff234e0,c9ac49c,13ae48f5,b84941b0,702a7c08), +S(1e09fb70,ea2c11c8,601fdaa7,7734b369,7e5efada,77b38869,8553d4ef,e1bde2ab,b8bf422e,c93c03ce,9d9ed0e,de058d20,e0fdf535,63ba16cc,494d6648,fac3a027), +S(54bd2f4d,961177c0,dfb4814e,bf5eee4e,21b12ca3,eaccea46,e70e117,76ad1fc4,358e0d73,79368299,f33ddb71,1722c2ec,8912877,c3891c8c,bc55e453,7c803962), +S(53ca166b,2eebb5cf,59a35287,5f6fd200,dda76f66,e3341ffb,1adb783f,4a1ce584,ded51d62,7769372e,42540e0f,20ff4a3b,2d912b4,6eaec7e,4e891ec4,18fcd0ed), +S(dd28eb5f,5fccf394,81467a6e,746461f0,3e4cdd04,6e7e6f36,534f6384,daad4ab5,8d702671,6e5e098b,648ae87b,6b782374,a2a3eebc,eb4e3835,470d4831,1f7dcaa8), +S(ce29f160,90fde1e6,13cc16cd,16cc7b8d,7e6e1203,cb1f1b5e,a724d65e,4d91aa28,d44c4dc7,90586159,ed9f9d18,dccfd95,e24bf6aa,c1bc3530,ec871473,330680fa), +S(6d25e798,ea08596,7cd9e0f2,da65b546,8e885d92,ed8cb0c0,8a266dc1,6b4e222,1d18fc8a,4010f407,aafcc995,8fe38f89,fa5f6260,e3288f8d,e4d98f94,377d624e), +S(6deeb20b,cdb46236,969035cf,58365ea8,224830a5,6cc187ef,6d938353,920ffb36,b19d7a95,b829c318,96d2833b,9277c9b8,7e28c6cb,c81c4c2b,d114afb4,c5266c55), +S(72c4d5e7,68866f63,b53a27c,74ef9b43,35e7fd11,2e13db1b,93654078,f625574,ed233d0a,1994d701,62869eb2,b7a2cd20,d82277d5,3109a9c3,e6e97f47,d727dd54), +S(79efc60b,64c060c1,a142efe0,5dd75ed0,a5b4ea0,85e5a10f,c6620db9,92525420,101b68f0,6ae4a3ce,2e33f003,1ecc3b1f,11dc24fa,d9f28a82,ebb2f5f8,380b3c8a), +S(a8cb5ee,ee7550e7,41f2150f,2e458dbe,f8d32b87,dcacf424,5cd089f9,7cb6c0ef,fefde564,3f885730,d60fa2ef,c85f4b16,d86d1690,3b2a8bb5,4b5c18b7,73085054), +S(dd8e43e6,828c9363,32793374,9d29a822,66bc8b1,4e320750,3d415831,bd7373e2,5b1321c4,744cd3ae,9348ed3b,5e4cbdb9,5e1d7256,e7ddf7c3,fa1fe9dc,494469a6), +S(8ad3b3e6,a237ed9e,8f94d669,2f5a7725,b0779bb7,ae06c57d,1c25e449,4c95479a,45b978b8,500757ba,51a05069,32f17d9a,bfaecbe2,2cc63c1,5a9b617d,98b071ab), +S(cb3497d0,7c72e534,75618cbc,29224ff2,17fb9659,9d51a6e4,1559f323,9c699c4b,72914c58,8daf6396,d4d9b70e,9476d967,aa60e574,b637ea1e,25c20fe0,1355509b), +S(fb77666b,b8c6cab,ca7ecb4f,e88f1e0c,199a81f1,319b6a6e,9cf2dfc7,e9128147,f122b377,84326ffe,21a707c,a3bfe74,2e433894,7c791814,855501ed,255a2ab4), +S(f2f16cf6,6a9943b6,19b321ac,76186ac5,6e65c2c7,aa9c87f0,15029f6,36749c74,aebb617c,88115519,58f90c87,5f021df4,e3c83e22,9f787275,db39eb05,9b3d9e82), +S(607cad82,2d0a117e,cf29dbbd,c7a5c6cd,d4b67f7f,6bf6271,c58de368,50692907,f2344d08,4e7db14f,70463f4f,20e9c379,538f0031,285d9c6d,1cd33d5,beec40f8), +S(efc8352e,dff912a1,936ca01c,18da7ba2,c9397f42,2cd58738,4ce321,4baac332,52006389,6229a8fa,e24e1686,4c5a643a,425e20ef,46febfdc,7d9c43d1,f767ca7b), +S(63d31f76,805cfe95,4db3470a,1d7215,505fa39a,cbc69048,58f801fd,eef99804,97cd5656,86da7de7,4d12cd9c,6e5b0c5a,c4f7f22d,3d44b372,a907c233,8f963e7c), +S(7e64f2b7,c2083661,8f2e2d21,e86ffa91,be646231,c61ac353,c32cdc25,953a01c0,c9222645,5b1ccb79,e00e905,2bf2c9db,91d41728,58e46f84,811bce9e,8b0713f7), +S(b5f29487,3a276b67,2d2de980,c6f74a23,d7bb465d,e9bd3362,45ca65ed,f942b85f,76459975,a0569a4,8b2b463f,375be7b4,f05e1cd3,3ee33a75,61ea8292,850d1089), +S(a0f6ba4c,b52187c8,9c4b1218,b7f57773,94551352,61582217,7e649893,dc3cbd8e,94d62e8,8f584baf,f0ff883c,1ebea341,d71f8bc3,59807c6c,eafd845d,361f09bb), +S(ef4130f9,88666de0,2aa37978,daaeb7e0,fbdddfba,d8953c5,6011f839,e974d0a7,322d77c3,dcfd1537,99043ed3,339a2b98,87538059,714a459c,1ddbc6dd,c9e720d7), +S(d6fb60f6,4b5409b1,7d10e23d,4f311d9c,4af5dde4,f1f07616,11e0eafe,13c2bae1,72f99e2b,bc790349,144b0ebb,67b35ba6,a62b94ec,b8bda4ea,c32de255,bb071651), +S(4f69ae06,8930b9aa,bc2bec95,8b3f28b4,5b488e34,c3ac0dcf,ee05368d,1f7d0b19,b72573b5,b86157ab,1e414c20,c0e073a2,e583f031,ddbd4141,1b3e26c3,e3447d57), +S(9fe97728,7de04cad,e939e6ca,d32afe4f,865b0423,9103850d,688fd06b,db10b2be,60cce398,c46ae002,a34a9ffd,d2ef6045,23f442cb,9f7ef392,ed292ce2,ce54256a), +S(b328b5a2,1adec912,66aca0c1,98084578,59036c5d,be3b6e8c,a9476b95,6954aff2,355076d6,a48803b5,fce76401,4e5b9e3a,d7f3a270,a7c50cdc,442fa9c7,71a3dcdf), +S(f8d16f5f,14885b0b,c5d556d0,8f6050ac,62ee00d7,c3e5ed7f,2ff6b8a3,54e54bad,dd483037,70d67a5d,32e7e58b,dd83dec7,b5c8e14c,a26ae5fd,58867401,837a332b), +S(422cc48e,415b2e68,7ff7896a,b32fc6d5,e3c433b4,ec2b511a,42178b6a,9ffe73ca,664821ae,781b98ab,c6f08fc6,ad11a76b,aed4429e,b7e879ff,134355c3,4b4528b9), +S(c8bb5046,1e4bd041,afd84d63,998dca63,de940192,7314d666,7c19db57,a8f629f2,1455fd5a,945165b7,2186e9de,ffe01764,108d6f03,bf4007c0,53ec7b8a,a6a7d07a), +S(7303bd5a,4e82fd3c,a94c94e,c2f4a06a,7d60c272,b2dda534,48eec8ec,ffdb80cb,7c593252,6a031a82,673eea15,263523c9,44f3ec0e,975203db,7cc302ca,83316c0d), +S(3455bd06,7de934dc,301f4a47,807106cc,24e3d8fc,9bdce088,4c1d01ec,2250dddb,d48aee56,e99cd267,d2cd8cc1,ee9fc3ac,88cd3d6a,2e58aa97,6586eaf6,e2052db7), +S(a419f5c3,a053b04a,a7137049,cc9452e7,268f43fe,528d7232,f0950270,b9d5c2c3,dee8994f,b9feefc9,d1f5f529,5444214e,2190de46,5a514282,5ade1a46,c439c1fe), +S(31602357,e187796,39867d23,89962d8c,3d5e9c35,7a2ace5e,83b6397a,585d5a73,21168419,4dcbe58b,95cf6e85,dc6040bf,d62894c4,bc5abfd3,e42603f6,ef86bae1), +S(3a0395c3,ccbc8006,a889e8b7,f6de9f70,44f2cebc,5c595f40,9d632166,c35831bc,25705a8a,213464ed,38fea19c,e1ed5ca5,2c0f8bbe,debd4388,bc8565a2,faffdbf5), +S(88067788,1627b285,336ff69,3ffd3728,6d0f154b,b743e273,2ff29598,178f5f17,c0980505,2fa7c70b,fd34ce6c,f27e5197,3414cc7f,1f57afb1,18385e9d,893963d0), +S(e1e1edd,146391e7,aff005c8,8f5d1347,5b393ef5,3a017b17,84a6dc4a,e29f5b18,e95592c1,5005cee1,f27c649b,2409c3f5,71870c85,c389861d,3e285e7e,7754a3aa), +S(113aebc3,2beb62a7,6e57a820,1c3602cf,d654ede4,d58e10bc,3545d84,cb406362,afc21a5b,5155c143,45bf5b47,50295ed3,db00ed7b,ae83205a,a0c504f7,fa5a2db4), +S(cdb6f34,7ba8177d,57e58fec,f22424b,fd3a276,96d386f4,9abaa40a,7f03bc2a,8959bea5,7d63b46,ae5d4d34,358a49ee,142b9b7d,137bb2dc,f4a937c,45338b08), +S(f9e9688,15a87cfc,85c00d90,2d7ce467,5086c566,49246f8a,bc655dbe,c1c82882,7152976c,19e3aa37,aa63d7c1,b9b45111,923b3b7a,df49dab,ae50226f,f39c1fb5), +S(7e7c0a6a,272ca295,c7ff3de7,906ce47b,9470e583,6afd4218,67143d5a,ea1d67b5,b66f3565,d68d55e3,b7542ed8,2b12e217,e4b47879,d9dda727,bec58094,da9d1886), +S(72995966,366251e4,57009324,5e29989f,f15670,af4acdb9,3eca8d47,3d1bab8b,9a8dc60c,3232eb18,9b454b51,d9db82b3,dcce9f54,e30e430e,26aae1b1,221594a0), +S(973afb4c,aa2688a5,b7e4f679,e68c2e4,df25ccb0,d56de80d,f6522000,6eb4dc1c,30055694,1c0eb266,906933dc,9c1758b,7a6181fe,8c400191,bbd978b,13f5f55f), +S(2d550e3a,f5b2d5f8,3cb4c695,431ed8e,62344236,66eb0eff,7759d4bb,39fa2dc1,5f6eba0c,e447bc92,70d35709,87eb9b17,89e7721,a7ef2ed8,8f749dc8,37dd7e71), +S(ed44931c,7d509be8,706150b0,3f24426a,571fde4c,e7b2d3ae,488a3576,37f6ec28,48e05525,e9b38639,6da1fdfc,40a134b8,1e05fc60,c7bccfee,8a8ac358,e9fd09f5), +S(6de88a88,b7b34f50,a8990a4a,742bc1d5,62d6b332,810451f,1c0081e9,18268975,5c435e32,379e62b7,46ed6518,b304ad1,65130b66,158cf41c,5418e490,edfc5535), +S(337611a2,907cdd12,c6c482a1,9b89fd74,1547fcf4,ed6ee721,cbcb66f9,b90967b4,1a438459,eac97f8b,53e45562,4a25ab67,f52cc6a7,fd3cea42,5ad08dfb,31d6bd2c), +S(aff600ef,329fc815,d36abbf1,3eb59530,58e74ddb,9df425e6,49662123,d8c429ca,ab8aa32,642dbcf9,994134f4,65a9e760,ce8cbf17,540d2f3c,fba6a31,9eab56f6), +S(4b15c510,47c6cc2,309c7eff,d3124f66,d56198a5,4da997f3,48f35fb2,7250504,5cc00333,f6399193,ff90ec0,54a726a,fcc492a6,bde386b6,57e481f3,18000cf3), +S(4683f46d,b9cda227,cbff9940,23995184,92c61151,a67508f8,5629945d,42a89345,cf1e8d43,b85cd621,2da2bed4,ce556ad3,ff0abd6a,1d40e445,629d727c,1e072e3a), +S(9ee0eea4,850864e5,c8239602,f84a9044,b966f84b,1aac7690,3fd096b8,fb09145d,c4c0698,e2611fc1,c7bd1c6f,f86e0fc2,19e3532e,defaf5c4,ae79410,db9e94ee), +S(ca4b7b7f,e02e953d,e622359a,f1834997,e5190c70,c149430e,d76aff1d,e166a0eb,e899496d,bca56f10,f2823c41,365400a2,723ea0ae,72f062ad,c36c0bb5,8e6ac820), +S(cf62993,f5be553f,a7492b3e,45934937,4536aada,f8db809c,cd01fa40,49364a2f,fda0bda9,d0f450a4,3c95a5a2,1526fff4,1b63c08,8a320b2,1ee9716c,cf2613d), +S(cc35c60b,288f8ce5,4120178a,dbac3e19,6e76ebac,159e45f,43afe82f,c034f459,8a6657e2,f8b99b03,3c6e29b6,f3bf373f,c117b6cc,f7ef935b,43b9a1d0,890d8bdc), +S(36a1bb7a,5f4ff871,b5ffe08f,90ecfca8,7c19eb0c,d110d770,20aff404,95b72e0c,1750a693,51de455b,1325e926,75dfe3e8,94de9f37,2d2697ca,954944f5,87d8706f), +S(a04c1bdc,7ec653a,fc549370,25d202d3,1bb7c21c,73de8160,160693df,ce42b5f8,4dd93af4,37e300a,8452a7db,af6824b0,e566a935,632c3487,f768988f,d874e74f), +S(484cd2a9,99cec03d,85872e48,84ee50f5,2172089f,8f1aef0b,d3ec6595,2a228a86,9a65d51b,bf64776d,53e40da3,85b84485,3c780342,6952446,35a78ed6,e1cefaa5), +S(398f027b,8ef951a4,2ad7c665,f5fdfce1,831ecd67,23f45154,62c636cd,db3b8a64,99577f76,a6a3b0bd,ac4d50a2,24c10250,727ce349,856f4e7d,eb1406bd,62d9b36b), +S(d62300fd,a6d242df,58be11b4,fb754306,62dcbde4,6e86b1c0,d1419da9,99beb256,cf11becc,84928784,d23a74b6,4dbd8ce6,37a1537a,3d9d0f43,17803da6,d1bf5e97), +S(4c41dc69,be8c1aba,9da4469e,2c1e3eb1,14b07fb2,db63785d,da03c53a,faf0f147,a83d7f0d,fd92a665,d73a2f8d,520f1a2e,ad6b2465,57ae2736,9618d10d,b114680f), +S(9a5086b0,1ba7ea1f,6cbd3be4,8acdf6de,29e8f733,b120aad,daa7e41b,3b1b2708,f4eedd2e,814d1f5c,33f44080,e4d50452,4deeba2b,4b2ca528,320bbfa9,cc3c65f3), +S(a457659e,51a7154,e5836fd8,4948cb3c,227986ad,f9fb8acc,89a3159f,d723b478,5c59c117,4e9962dd,94f3b084,8a544983,54ec4962,f0d666df,889c420d,78845ae2), +S(ea79c22f,13e6cdd8,e282defc,9cd6ed68,5d39b48b,c6c13c55,3bdc8aa5,8a90f78f,87223587,c3cde568,81217ec8,ef0dc431,89af8095,d7e9f82a,86142207,d8b5c356), +S(e19dd143,cd0a9f3e,8535edf4,a3dc7e7a,4c49a25e,1771f8f0,3fb5eba,1a9e10d6,d15a39c4,86b79714,89b2afb8,13b412b7,c1de54c5,c3fd2ff7,791bfb2e,d6a498c), +S(c7b277ed,9bada568,2f7a87cd,6435e0bc,948fcb1,2551ad92,e188b664,fb5f59ca,7d1e37cf,3093775a,1b0aec4,93b77c92,f6d6f32f,a1d8438a,b75add39,70b5eb00), +S(c1fb0836,5dd42214,2098c397,b11a63d6,43afc082,16c0686,d1540d4f,d39f2f85,438d6559,d07fe7e4,1e775a3c,66e79f30,a065a62d,fdecea46,e8ec0967,a5b5b8de), +S(1a5b6bd7,152c8c0e,6958cd5c,9344bc7c,5d7869f6,bd08d698,88e69e49,8ae62ed2,166a9f1d,b2b3a729,e374af09,40bad6ff,7646504d,36d40465,2c826ed7,98195f0f), +S(8e3f1e45,42438eb3,2635c65a,a817c325,3affb9b1,a1603d0a,d3fe06a5,83cf338b,e6b26e2d,9e310afc,e702dd5,4bcc2815,1dee0a86,1e31a16b,79fa0900,f94e320), +S(ed9ffd27,1fd7b569,fdb187d2,7d1d97b1,3a4b88bc,aa13639a,62a6b45b,cfd00dc1,5fb45391,d5a636d,1d757e5e,472865aa,556092e0,870f45af,a325e26d,40f755be), +S(873a3db9,be376cc5,f4516913,d8235555,624cea02,16c3231a,72750c44,12cf4992,3d5e2304,2b04870f,d3cb61bd,2f618b3e,4f1dbd3f,2b585026,fcebe608,7f0a5a03), +S(d3ef70a,eb5ed2ad,375ca185,69278cba,3d037dc7,b0f63ca2,442804f8,1840e686,f4bae13,fd55a2c5,ec93a87d,c2b4134c,aba2fead,39dbb555,29d70795,45a9488c), +S(d2127f38,8f3b4e7c,b0d24f80,27f27e55,fca1110,288a1c1f,da46441b,21327919,18f2b4b9,69df9a42,1a87cc43,47e2ab53,146d6b82,fe3c19ef,2df361bf,579cb3a0), +S(5e73dbe7,e8961e0e,32b9af6a,4443623c,cd3f992e,b024cd1a,59bfac9a,ad6c9f4f,4d8299bf,b505c0f4,5835cda0,b7fef2ac,640a5835,6a7e498c,b0f34480,34527405), +S(b9eae3f6,9af01cb5,48cd994,db6beee7,7e45fba3,782a9ba2,83b340e0,fa89bba1,b7ad76ae,189735b,f4ad8e8,dbeabe72,ed40b2ae,2c9351de,1beb1252,d4424b65)}, +{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), +S(68e7cdbe,47bb0fec,37fb7860,a71533f5,5eddfd2d,8ad7c9ef,cc266009,65c627a7,3bb96d5e,f0cf90ec,13614c2a,c46039e5,e6e30782,48f855ba,8f8bce36,f66b8a90), +S(c220e26b,6d3cdf7b,b1cf434,ec5fca6c,eaec952b,e61d213,16601ec,6e06b259,3fdfaceb,268183bb,9914c5ab,ae804206,a3711bc0,d649c407,82d3d2ce,93e350bd), +S(fc458625,75cc7343,312902d6,8e160a08,f82fdb0d,60df16e,575f893b,94592e52,e2236fb4,e6af3e39,4faaf83a,3c6b418,c560abf8,eca40f29,d3cb91e9,e13a8ab9), +S(7afc4446,f445a33a,64fcc04d,269529f4,1e16f567,550a8280,4027bf24,1d08e895,3ee4443d,2cb04a,3643f6ff,90c0b3da,a43c8333,82c62d6,5a024a68,e7e7f06d), +S(4cea2d22,d19a898e,fca4a7d7,499252bf,1957379d,a6004,df9c7df1,60dba4e0,c97fe09e,84024a28,ef88985,6fa1feaf,bee116db,a88962eb,36be946b,d2da76c2), +S(633cd50e,b00633ac,6d5b1bfc,89d97e24,abdd932a,ee9f265e,95dac73a,65627e0c,750ccac8,f09d9f86,7117781a,6b20ce6b,6a4bdcff,7ab04769,a8dcd1d2,c541bdcd), +S(20224a29,28ae9e78,87bf4242,67333b0f,fd59349a,2321b8b9,c28af552,c98fa7a4,94944b75,4b6a0ba4,7c647332,e9369b,dc57f98d,5a010925,4bf6d2a4,eeaf88e6), +S(29d9b1ac,7ad67ad5,ce2e965d,e7ddadeb,43bafd47,f0fef02b,2f553693,1f45029c,dfa93352,cf5dd7b8,3e5a9646,da2a3f3f,152372bf,285b75dd,1517e6f1,7859c03c), +S(54859abe,18867be1,dc85a087,4cc7237a,597bce13,866686d9,43e6bcac,ec4fe7f5,1d956ff9,31259641,1faa0b22,b2639487,d0392514,58c5eb8,7918fc2e,26916864), +S(9c3c1ee2,ad3fad0c,e5e6ad1b,9b1f5875,1ad30927,9aefb1d9,4e8f408,c3406d42,b31e5e91,18bbb027,f3ab9d42,ba1cf854,753dc66,641cb367,7e8db07a,4b7d4fa8), +S(c4e812d,5a640e68,70a42601,694341d3,5e964f04,fb52f1bb,819166a3,4fb8732d,f9494ed1,b776c04a,769308b7,4d312781,5f9c3d6d,c7ff4b17,cfa1fa31,87435938), +S(4f8fc5f6,cb4e73e2,e24b94dc,63aef340,b871abe9,2fb53525,ef0ac7c2,e04f571,d81880e1,b3d0c55c,8d28bb51,5f1a10cd,245fb5e3,70eca394,d80ba83,d7615512), +S(2223062d,f1572257,9330efcb,2c5a90f5,6d9c33f9,87ef9b9f,9c79db75,dfde7b49,8fbefa3f,37c855e3,ca3732f0,2d0c0c60,b73384a8,3458b05b,eb74da89,acd6c1f9), +S(cb3b77a1,defe7162,63ad33b3,5db0ffa2,e80d7,e00dae7a,91abeec0,17fb2a8f,29cafee4,8cda21fd,d692d241,2358b229,559d7b2a,c93e5eec,9e4e7386,728dcf62), +S(cb520a70,3b9abc62,9a039af8,ef7f8f50,fbaaa21d,721c1bf0,d2f680ac,56061581,58643940,fc79dda6,35b846c4,fdcab298,6a2969e0,16886e,93ba4532,cb03140e), +S(c1163c31,a922395c,7afb6fbf,19a848df,ff20dc1a,38f1c86d,89e6779,3c97473,8f4e7bff,a21a812b,ed0c00dc,55972ed,173bcd4c,36476bc6,70d5177d,73e539bf), +S(82a01624,64aca6ec,17abad94,4756cbb0,b27bbae7,120e3564,c1c83776,138a1e46,9eebe6a6,140227a3,15d7f23c,176cebcf,21f61112,86dcf337,21deffae,d701a856), +S(972acc1a,194b29c7,1d626053,34704ed,95201c9b,92e5bfa0,937b7369,dd389794,48ac34b,936ba87c,1a952b91,8a82f0f0,26ddf57c,2ea44cbe,d15f6ce0,da73a4c9), +S(11c28dfa,639403f9,f8283916,dd32194a,d116ec21,e56e6393,f743ccd1,1b1fa275,8a008459,24e50c2a,d3a713fd,53fe4998,86cfe86d,2f31b8a0,b2903a48,ec16b1ba), +S(d308b5fe,c8e87dea,6ff1917b,8b853701,7dd6a46f,97c268fe,7dd2a672,92ff3bad,83ccbd2e,82917e04,fe00fd3,cf837c0c,efc34a81,54c2f068,3fb079ac,3a1dcab4), +S(f4551b7f,aef3bda0,51ed6978,45d37d52,97a9ce9f,4b684334,fbac03ab,ad0ab7b5,7ac85f32,e5cc407c,5432ac50,ee015a7,e2fb3191,90d8855e,7c5ed488,ce5c6211), +S(23daae11,946de442,7934b351,a38df422,2f8f5424,b2dba51a,98548718,3c21d2ff,48dd1fc6,ef5ca525,88b21118,7c172792,ff9aba3,d18aab3a,19d9dc0a,d795763a), +S(1d225202,4bd2b32,87400ca3,e8de9bfc,366cea7d,c87007f0,e36d49ab,32f3d389,e711a6d0,692025ac,74755d2b,46c8ccf3,1824dac6,35a48cb1,af6fe2a,ba17f178), +S(b500c6e5,1111339,527ae172,11055236,912f7cfc,8e67c4ba,94dbf39b,3aa349f4,7a65e1ea,dda398f8,5da9f82,d5bff3df,41b92854,29994d8e,b9ad0fb8,ec9610bd), +S(135294b,236c6f34,478921c7,d463c14b,92da01b0,226b0bbf,bae7f392,fc1ab605,8f77291b,b39dda82,33e6e523,7d313f60,3bda29b3,4961a6d2,4e474397,2f6bc068), +S(1fc67f92,9f12d181,73e45951,eb64aa45,627d2fa6,61a2d35,25e818d4,3d4b2ebb,f4174ab5,dd5ccf0f,d6522310,20bca7dc,553fc88f,952007bb,b5012789,ae9d1bd1), +S(47ae7668,3654ec8,a3904f7b,dd02efb0,ae4c8489,7deffa8f,a71aab26,d82dbd52,1e20245,990a0f45,9368065f,edfc7d08,ffdde726,1c8f79eb,68adc042,de1bcd88), +S(750b52fd,7ded02cc,886c9105,8dc98545,67c8c62f,c7dcddcf,ba74e552,dd8343a8,2df52ef3,2d8f79f0,9423792,341ba29b,d78cbda3,252347bd,123fdf78,5ab9b8b9), +S(148870bc,fbdea326,62c20304,aa2d9edd,91de2474,433711f9,75e977e5,d3b9cf8d,a0848bf8,6cfe26d5,3c4a0960,97925a32,d296db69,d3348c7d,71f7d5df,223b3747), +S(ea916e64,4958c33b,1610c7c7,b865a315,eede0d2,4881b156,4bd234ee,e372be92,387af6d8,4e8beaa6,a4df0813,db45aab0,6612bc74,aaf4a292,5a838322,a18ff4dd), +S(1aa70a60,273c70ba,51ff5fdb,2037bc1f,5ff9e0ad,f2551fff,a2176bb9,757fb4f5,a578a726,53233bbe,fd34673e,4890e0b0,d2609bee,5fcae095,1fdd2711,b618954a), +S(a51395bb,6cf06cb9,b2898e7e,d39c1011,ea8e4539,cd3f5c17,4150ab6f,7b0f170f,50820591,ed76ec84,a0ea2b57,b11a10a3,d46f5b73,71a67016,f952c497,3cbdd83f), +S(c6d532c,a8745145,e005f8a0,82b57eea,a235d56c,4688d98e,5cd4a911,d0b381f8,fcd16c55,4a38f1a7,3f82ddef,a3dbfe97,7d554b37,e6b60727,4a37ca7d,28473b2), +S(c42dcb2e,169a5276,e0dd6195,3f7991d6,2d4e9459,5934dcd0,e4daa217,1f050bcf,9ea1f3bc,e274ba98,a38d76b8,1af87fb,4f760b1d,940a1ffa,fc6c8a32,59cbb197), +S(ae7ef14e,5f93dd3f,3ce400c6,c6944a2f,e14617ed,af42aa9e,dec2f269,fafa21b1,465a5540,e5a4349c,1ff0bb26,a660a935,373deb42,f16e900c,f66d638,38113dc4), +S(ffa64715,253ecee5,2ab8dd71,17100a64,936e7d19,3e8230c4,1d06c0f7,b516b91a,1bdb95d,631fa76d,1a8fe556,44c69cfa,b0997ab0,16b256c0,30a7ab5e,fb0de0fe), +S(def35473,ca162629,2f49c77c,2cba01fb,af7c94dd,8f9a21e1,9883901e,8305e3d8,68962e7a,aaceac89,1d5da447,40442b70,f2248b4a,b6b5bf03,f1e00a66,3b0378c), +S(52d2f036,925d466e,45b33be1,8d16ffd4,4b1d191e,10d0d72d,209ebc4a,3f8358c,88a7454f,260b9d74,28afdc59,1ebba74b,710c1b11,ecc755cd,ff482e0d,bd859719), +S(6ab19082,9a23767b,404d25f2,355fccb0,5625b6fe,88bfec66,409668a5,e5c0cf1d,85c26852,95550088,ac9ffd07,dfd972b,dc6f25e0,6509e9a7,92d59b2c,afe63ca3), +S(188dcd54,5c0859ae,6916c4c5,44f3ce1f,7f747007,a6a8d26f,5843f88a,8dbb6b79,9146ab39,c1ed37e4,557aa5aa,c557f874,bf47b4ed,2d2216c4,64b66572,50feffc4), +S(d6ede828,c35972b0,7105bfa,ce6396d4,12fdab87,19f93ad2,cde46a4,219b4faf,8316a8fb,2c30c3ae,88cf61fe,ab875c03,3254a2d2,e1c5eb70,24f83973,3db48b51), +S(a363f5dc,ab07afa1,bb0d93f3,df44f786,4f5f60aa,330afc5a,45368fe2,55df6097,a5839073,c4ebc180,50232a4,a6ce7e4e,b3ac6114,eebf3be5,b978e1fa,7218b660), +S(8ff6e368,f82040cb,9647c91f,7bbc75e1,7a163f0f,7c9295c3,e7901026,e4fcf2d5,fa8fc30e,8607708d,1e2fa7e2,6d4c13dc,3d560fef,c19cf1ed,5dabf5de,8ba890c8), +S(4dfb283f,fcc74939,60d239a4,d364d773,21f1426,b48f99a9,5572ee88,17ac59d2,a6561134,2c7559e8,8b180a59,a0708b97,9e9b381,a1541e0e,a7b6cfd5,b7aec1f0), +S(59c8a74b,ebcb88da,5b8cda4f,1af16c77,ce323f1b,1a9bea22,bbf8a38e,f5a8a6bb,9ec04d7b,e7d56114,f72c0fbd,b462332f,6f921765,93affd25,6a37ef5d,91eba83), +S(9b8dd571,edc71d3c,3337aafe,b3c33f8b,a1a35db9,fb071cd7,577fd5f6,f3a1d3f4,ce7249c1,e00c87db,1149e014,7c531efc,ad8bb3ff,75e51a52,318743bf,74bb84ee), +S(a410bd11,12ddb03,410eef03,ce8ea4ac,f1663660,c12c97de,bd4a2532,9ee2fced,4fa2da11,2c0f4a1f,5520ac16,7809d7e6,2faa8b9a,c442b84f,e2badf94,84368117), +S(6a78a5f8,eb495f28,dfec9329,6b026bcc,f88defff,ebdf4986,782cb546,332fc840,c90ada0f,24723e43,2a7aabc1,931954d4,cf60908d,38302255,a79231a7,93f02f86), +S(1126bde0,fdbf76fc,722bf379,43126763,a3a3fd6e,5f86e9c0,d5ed9eb3,7b9f29f0,d85252d9,ffd674ce,3d73ba20,49fb2b57,f1bb9073,daab3d2b,79bbeb,11bec42d), +S(ecd869b6,4057202,af53378f,a9e57c86,949b2b78,8034656f,912371f4,e5f122ae,cd94268e,b999b0f8,baa47cc7,d84b78c3,4817cfbf,43594655,2a138d8a,7c75b201), +S(deddc4ac,6aaf1649,b69dab89,7650fbd8,f4eda196,ec973025,7bd24cdc,7df2a94e,bd6d69b2,fb809b58,95812ad6,d1a4b029,f3861c52,4fde59f5,ab72a378,8bde28a), +S(4305fccf,95196da2,1aa49916,601b4f00,97e0b145,93e7a6ed,967768a5,836750c2,b997bcf,cc942007,c6b30a6f,a4f8ac41,52b92f52,fb9a3561,2015e846,4e4c4a8d), +S(c6235374,bcf2ad2c,6ec1e9a5,55080ab2,3765f1bb,892991fa,6df94a32,ac0ee35,e878dfc1,7a210fd2,ef572fb8,3ba9c4c7,b7d67dac,446a7066,ae0fac29,1b326401), +S(de7be4ea,50937662,a22a85ec,b2cb6f64,eff08302,13456045,e86d459c,1d36cfe7,b6beae42,d2d26eaa,20ea9941,e7ac5b88,d13e35a6,ac457f39,b80382e0,1c1fcbc1), +S(83faaa90,c129b256,736d231a,aaeb56c,851cd0b8,8a32066e,1587fe71,3d26e7c5,d5aa97c2,9eddce7b,58f9d96b,10a2fde7,4c1ec756,d30cd5d,bac03a2f,f4f5af16), +S(3ea3ac7f,976f5a3e,81cf5ea4,4325c73d,8fdfc7b2,57512f70,236abafe,925c1d94,edcbdef8,de65f541,9c5dfd7a,6b1e03ea,5b15803b,161a403c,8775e29b,7a64f3a1), +S(9a51b8a4,5bbce94d,8ce04cf5,dfe4bb76,cc8eb592,9aba8964,1ec58e,9d979461,661bbf31,86f36500,d45bc5b6,58071b27,9b3d327a,a86108ae,790f1065,dd45780d), +S(a3c3005b,5df20d43,411dbe7a,3daf352c,c43b8a87,564a9891,c237b7b6,2a485369,20603c49,2c90c32b,616fecf,286a13f5,213402a0,c0f8d64,e2a39b2b,bfa978df), +S(8685133d,3f0b48e3,fffc28f7,ece3b6f5,2789d948,68107d3a,4cd380ea,a00040f7,4b07a1a0,91f3fe2b,272d594,9336ff7f,d88d758e,d7c157eb,5e9efc65,4bc52c2), +S(f4512104,eba12a54,aa6d497f,59a256a0,ff1eac53,573c2ad,e480684a,99635bc8,538b015c,a96decb7,ba0ce9fd,b14393a6,7825205b,ff2c712,1f96d27a,3beb83ec), +S(709fd8b7,1795cc61,892ef282,10049b56,28f1b6ab,e5ba9a5f,285777f4,320d88c0,4a742056,abf637d7,e9b75e1f,938778fd,4117f87c,7699a67a,1c08e3ac,a2275622), +S(68a4a2c2,c222513d,b7aadee8,3d05a13c,9ae4c422,6d8ccffb,f6b6b88f,f59bce44,706c2374,afa7cb27,8a95d8bd,6aa98533,ea7fc003,33678c38,65153006,3589db2f), +S(38bfc02c,3430c92d,958b80fc,ba196f4d,9c4656c4,3f667cef,1ce0726f,d6be250f,a05c4f47,7b44a3ee,aa21107b,3a679db2,5aaa738,c474436a,c7dee4a2,228fd940), +S(c2e84b8e,f4380fe0,a674f5bf,3c55d3f9,3b060e08,6b207344,923f28c7,b7935fb7,bf1a2c1d,677595f2,33ae6530,d3bc151d,6b33294f,57d3ac23,78749450,6a0a189), +S(4425f7db,6cf56461,147ca518,732f101a,39c7f585,b5ff88f0,43ba3e3e,a47bb597,4ff5698b,88fa8489,b08c4094,3cda74ab,b5801911,d36232f5,9b358d12,193b3d9c), +S(98c57e63,521541b8,acbbd5c,f568b1f5,d3cd74bb,c30562c0,12518cf,96617e48,f49e42f0,8c236a61,e08d2d86,ec245822,64117ccf,6edb80df,403bf084,6e25aea9), +S(dbf6760b,351925ec,dc6976af,97a088cc,63115fa8,5fde9763,e1524c1e,ce901cc7,909d7429,73923501,e69d1bf9,ba1ad177,f99da741,560af1ab,9cd07e80,7b4f5f8a), +S(b42ef95c,79d167e0,6e29a6ce,ffb76ab5,c96f7455,21f128bd,faccb108,d7f2a609,6a3374a2,5edac6d3,744eb2d6,f39a94f5,44f852f4,779f2a98,6f1de5e3,fd729323), +S(a1034444,997dba07,20de1194,c355a1e5,ce182420,b19033c,ed68dc08,fcc2507e,b2cb95f5,d58044f2,36088bde,cf0d3af7,fe9b10d1,aef8f355,b688c68f,18829bcc), +S(47e80598,1a97f80,fd0f1a14,12d0d1e1,33d7e4fb,bda4c1b6,1dfea483,3589a59a,d33bdc2b,30d0c301,bf85e5c2,c364f1b6,f88b83c4,9e51c9a4,22229b82,10471443), +S(a355147f,281d4518,f36bc6ac,820478a1,6f0a1f50,bef72be6,aa53d420,3dff20df,627a5765,41031765,c3751c39,e9217493,f9da1927,b496eedd,8466709c,4a47a0a9), +S(b02ce0ed,6196748f,cbbc3809,7ec6e7d7,80186023,cf96239,e5a79834,4edcd3eb,f6cbeb1b,2b0b17b8,b620b799,14810a4c,8c47e404,89573b08,ccf826f8,7d8656a5), +S(87aca9d6,450aa411,8f56176b,49646304,dfd5d3dd,84f4508c,3a4617d1,92843418,82a93bd4,b6e4e426,27404ef1,7d837656,e0f876e9,1bb4b9b2,89e678d5,a430bbc6), +S(1dbe7199,bd248d19,5531ef66,260096a1,9614fb65,e90c2f5a,49ce3056,2cc60f29,ea49e29d,60082d51,7a807196,33c55ebf,f243a2d6,254ad322,8d614943,d19a5828), +S(a16909ba,d4fec20a,8b6ade2f,8ba3cfc1,d347812,f35b96b7,9b2910b9,de4e7ea0,496f1a32,3593a23d,ffb5f0c8,d9b599cc,18e101e4,215fe501,41147e07,6ce86a8c), +S(56e18008,832f45c5,30b819d4,a84416f6,db9b952f,84478dd9,243a293e,2d576867,16399c95,8ce72e9a,b2a3b2ed,becc8f5d,c220e632,60a1cc9c,57db3a4c,12e1943c), +S(d32b7ba3,d0af5b68,21d7d716,6f7d827d,f67c2f02,8510ab10,31e4ae6c,2beff031,8b1cadde,54e84e5e,5a0cfe29,a838865f,9dba3867,85016145,e9f81478,a6a20ddb), +S(55e603a3,8081a476,f37d73b7,645f3de3,9db27208,e0d1574d,99a7350e,95c76631,a9c50870,a3fe9f7b,da389eac,963e26f7,51a6f289,351025f1,b621d611,8b5872e5), +S(d8c1fd0b,a561bb0,3d44e9ca,33850198,3163f44a,5d6f3b71,118283e9,bc3c4feb,ef835785,9bee101b,dfbc2cad,7af7b10d,a777e78c,ee9277a0,ba29fba6,d9ee0568), +S(1bcec745,f89f938b,466bf429,3ccddd5c,c8566c9,2ccc25d3,a1cba363,b65bbb2f,b344f901,cd6317f,b4380012,d6fa9caf,64a5f75a,b4347f14,a227ea5d,bbbf2023), +S(8e9825f4,af70c5d8,15dbd92a,148cd259,30372bf5,f86d2a02,e700b156,812cc9ba,3290e56f,6876100f,6e20db9a,723bf99b,72a7be04,a3162d62,386abacb,ba377a80), +S(2581a86b,bd224745,a6518042,add5a63f,b640efad,191ecfa7,a582503,6c5797ad,4f08900b,e4e1abea,63c9fd36,c6939bb6,dc91f066,88ae9318,5049332c,be32e994), +S(d32004b3,48c65b67,80891f3d,7ef8c029,1cfba007,1cf03f18,c0b97cf9,bca71bfa,256a990,7442d77c,a1e3cfae,48a8230e,a03c0889,29c12275,994ab662,e9beb3d), +S(7b6724a5,a0090968,311ea2bd,d3ecb7e7,c7246bbf,b6a0793f,599a2146,faeab5ea,48a676,fe3a185b,cc6f7188,86bd7064,3ec7d20e,ff94b8a3,c1953b3e,a2f8db4a), +S(83d6737f,fee8bd73,eb4beda0,1916f875,85d9fc78,2f726243,f31a2289,456deee2,1d28e79c,c010e982,9a94adc8,35022da4,e9dc67aa,ae5751af,64c53f13,afed61e9), +S(472bd739,ece53ef4,12979f4a,89b6bb45,fad8b374,14478a14,afd13a57,3c315cf,27698c4d,861e5cca,831112cd,449980ec,1d81bef,6a396b6b,fa0da65e,ab164dcb), +S(8ea8e81b,22657ed,51bc721f,2f7956ff,fddab5b5,c703415f,ddeb524a,16123765,a301e8f8,67b1038e,56964048,2dfd39aa,9ba6cf7b,773df76e,eeb46882,2a229c7e), +S(1f931775,2da7d946,b6d9ed47,75ac74cd,6029531f,27487c1b,cfd2ab3b,faa7f6ff,37277158,e6b5c0de,5436191c,1ad8f944,7b316876,ae519306,f28a3606,ec8db8f7), +S(2a6aa0b1,106ddbf8,dceb8988,cfb33c82,4d55af5c,670d1e77,873f4a,ce74f4fc,889e4d41,b885fa99,21b66aed,83f46883,ec6cdddd,67a0ca45,dd12ed1e,ee6ad292), +S(9ff77e8,ce5259d8,58431c69,bf001dbf,fecfa5f0,bc356057,eed7543d,13486274,b8f0037c,c9c3b771,dd6b18e9,95be0ca1,23daf9ca,5bddbb35,a609811c,cd1ced95), +S(7a9b1d0b,a3f1414c,1ab3054e,f9c2fd5c,ebdc1931,ef670d1c,78db9549,6b1af514,a2407af2,ceaa367f,d6d4d733,49d77a2b,993062f3,d6ca8e0f,89d21eb,beab2b93), +S(37de2b08,4bcb4b22,e4643fb8,5f777b48,944a2351,88036c45,793d2d81,c984ee5a,c788ecf5,3900585a,a4226825,f89f9ef2,8cd25d37,565adb3c,a61e1c0c,ce4bf1ed), +S(6c3236dd,a08f2a08,9694f01,a4864dd5,d5ac105c,8c7cbc5f,7d2060fc,b4e8519b,2472d89,10106497,6ac425c0,43714ad7,d5ec4f66,fcd50af4,abcd690b,d219971c), +S(7c0038b9,2f2a96ca,115a853a,557be238,146eb196,8e7b8e88,4801a56a,fc8976d6,d68bd242,5586cc14,49fbe019,deab8a9,97a56dd5,f52b02c1,24e7b8b,141525f0), +S(24449d21,51eec6d2,49d6b613,d1b03e29,3b36185b,ecd95bf1,a52cdeed,890afc8d,3929bfa1,d9648c49,aa4144c9,584424df,895622c8,9a7a37a9,8462bddf,ecde7a2), +S(640d6b44,2c5e0388,7ea7c4ea,17ad3e5,977dfe97,907200a6,a43fb6f7,73848db9,db3d21e8,237ffa32,8d389e4,d93f33e3,cb75ab12,dea034c2,83b5a3a8,c7169b1a), +S(d2372e52,bc1d97b,8ccda950,37148f3c,1516d519,b171a9e3,6a3e87ca,619a52e2,21331dec,da625e2f,7330888,a31be425,9f69f49b,47e38e9f,85eba5b6,fdf4094b), +S(7143910b,fba2abd3,d2e7d7d8,f7c67344,581afa60,cd82827e,547de354,e5299a76,1965b472,4873bb50,c2b55cdd,dbefeb1c,e184d9cf,97ac9142,a49bbfdb,37e4669f), +S(275557d5,46e5acae,1ae98537,8d787b51,73b260a0,57e8b884,7bfbbe2,d15d5555,ca93b2ff,79544d54,8a784fcc,52fc30c0,49337a19,2b88533c,550432c2,6555e47b), +S(290231be,bf6b01e5,7904e066,5b1265d,ef4debb9,d14865b8,75341d98,de3ea5c9,acd3bcca,8ad8ca8c,b7a43edc,69fe9746,50d63593,71dc4d6b,a76e0c1b,bbf41cd), +S(93db5e11,7fe021e2,ca71621,29087cfe,93a2ecf2,560b6c0a,91044253,3dd4e351,11d18431,959d1dd4,8227844f,251a9c4a,134523a3,cc8c175c,f3f509d5,9da8d869), +S(8d346bf2,d4bae98e,ab44629d,720680bd,610f61b,32f6c109,9ef48434,6e3642cc,ab9975d6,3d4dc8e8,e90f2413,e93b2ad,e15f848e,7589451c,a7b735d9,c45f0a56), +S(6d7e8457,c1ac7255,c612d8c,99a1e850,d95d9058,113b852a,4ff0513e,e83e4f06,cade7182,8f92acab,a7d5ad5a,65fd84bc,15c57af4,499607b7,dcdd8c1b,20d75cc1), +S(23a703e2,540ba5d8,dfd5c7bd,183be8b8,a2ac028c,c51806ab,8ce1874c,5f66eaaa,5153dc37,e939eaba,35caeeee,ead1f666,ad62e15a,2f078b42,15cdc33,3372e839), +S(2ecada78,339caa89,a3baa456,15cd0040,9e7e7f4f,15fd5f02,665d5674,3ff48a7c,b2110739,2dea146c,2df5856c,aeed7577,a6bcced1,cddc56b,68462f0,f7999d5a), +S(2516768b,6d6ed0f8,9550c2a7,7167e0cd,34d10a24,7bc10f4,9c7ff55a,650bda2b,f363a634,be194643,68957ff8,2e329184,f2a6982e,51d4cc58,ec24cfbe,f0e6f95a), +S(c958904,ec9c6ddc,37f16d48,b56c74f8,64c547a1,c001e2a8,fadf0a3e,7069ea47,2dcfe201,8111bccb,29ef1f45,827d2b4a,753afd51,ed9927cc,395057df,7591bea), +S(c82c9164,9760ba4b,bed19bf6,a2323fa8,c61ca2d2,d27f70a3,b5798d10,c33eb5d2,531d2f00,be4f3c9a,1c08079b,b7aea0b,c78fd8e,30f5e2e9,27f465f,b814938a), +S(73d756a8,f79d7da7,362dd79c,5c0c3226,45e6d6f7,fe43234,1f6d7208,b9e9f5e2,2a80441e,c1b321e6,3ea1f341,838ff513,ec05a23f,e42b73e3,6dfb4a41,b96580a4), +S(78921b3b,ccd1d7b5,ac721e44,b5c6c8e8,371ae531,d36576b5,464b1fa6,6a3921d9,ade914f6,8802342d,93413c4f,8b67d343,d79252a6,d023f712,9e464e7,111e3044), +S(63ad2efc,c1e11521,139528c1,be3af253,ccbb4f8c,af95b00a,7a6467c4,d682f126,29b54282,c8718452,7ae954c0,1039c1f4,ac7953f0,5250b6be,47cc0b2f,69cbf28f), +S(448bd0fb,d7b22662,d6680a1d,57d81a21,a54256c9,d0a882d2,ed5c6f6a,e1e5cfb8,ce23a4b8,cbf12323,ccd55287,e5c68cf9,751ed0a9,1ad563fd,35688ee9,8c526d46), +S(ad41c647,5145c360,fbf6579,8a54ca90,7fbc9b70,a9323501,8ecc6a43,3ee564bb,c1830237,87a2872c,2884ebd1,f1ae7a1f,8e96ab7,99d1dcbe,eb39e68d,796a5659), +S(65b45a74,13b2e78d,20d1476f,c21ad4b3,2807b174,19eb89b3,fc799f92,7cae5a82,11aed89c,d5bfbc7a,9138885d,f64a38e4,d46a270b,ada85cc8,3a3ed7d7,65015331), +S(5e7db226,92f3d7f2,da0811a7,d0aa0d4f,6adb5651,3ac6a386,7c0cea91,ab212b01,d8250eaa,46275c9b,71f43f6e,cffb063,7b90a827,bc89f513,e769dc00,d5e28150), +S(37fb22a4,7feaec72,7db1d62e,390e7b8c,ed1d20e9,7f934137,1d5276bf,5c1110b0,9a537c0c,8da9c43a,6b7924e5,a6b29e9,17ae9e25,e8afa6fe,926ba053,f591c090), +S(4ec7c867,aff4fa7d,ade9777e,2d4a0793,fe1a1ecc,fa4765b5,aff9064d,98f16a50,433ec3e0,57138a6a,cf7ea45c,f2a91041,2e356c0c,751bb535,1856e37d,295143dd), +S(85b5685a,8e784360,dd1eb47a,9805165c,bf77dc81,56c93b68,54766ad3,87cfbcd5,b866861a,6da7efa1,fd3d5360,2b94daff,c0cbd09d,5707f3c2,b47d76e6,2f2037ec), +S(3a390af9,11caff4e,76bf870d,972465ee,f6f8da0d,c7232add,5ae9dd87,32be2269,f5052db7,7f43411f,ac6553c1,3d930945,a8833641,8af417e4,5033a8d1,a1a52c90), +S(44d40682,4608651c,4fb418ce,99391d55,6d93b631,d489f92e,fbbd56a9,c49736f2,1461465,fed84aa3,ebfc39b2,c1cbd1fd,b7472c43,5c9034e2,82d59c34,9dae7cd4), +S(9aa43d73,41ceef39,1b1bfb31,f620c39a,434e5235,2c14c28,8a50490b,9c62295,ad6272c5,19439e27,5a1c94c5,b3940b23,956d2656,d9870163,17e57d99,3d18b2), +S(1a5d114f,d0bda301,e76f3721,ff1e06ae,fb40cf85,b16c5dc8,a9bdce20,6ac8bb80,cd57ee40,1f4203f3,e1875926,199fab9d,9102a3fa,c851822b,a5bc489,6e1c7cc8), +S(711c1d24,299032bc,f2959c63,8139ae5b,b528b56f,e1a1b829,f7b8afbd,e2effc8c,98bdc11e,d2ec73b5,532332fc,478ab4ec,65626bdf,85287f8e,dbf1d8b0,5f163450), +S(3dc0955b,86e2d6d7,49bbc95f,2760978e,fda7483d,1f3b07c0,7d97ffb6,6961b0ed,f4af5628,d74d3fa1,daa5c072,9c1ad396,1b0792c1,b6fbd235,64debbf8,86d3051), +S(9cafea3,411e251a,8776e3b0,72f11229,8a23125a,5bd995a9,a4655031,9907df23,743b8ad7,ebcb4eb4,9469225a,7a2ee594,bd534c16,a8dd68d3,a58373ca,85f2b01c), +S(faddddfd,96d20fe,ec2b0c84,8ea7e6fb,f89dffa9,efadf475,6eedc815,b61a404c,ebc560c8,253927f5,a928584e,8e87b950,dfe26bd6,d37b739f,b0e9163d,c6312c8), +S(b539be0f,8ed02ba,f7787d73,df02e1bd,3210b88f,df1dfba7,a0138713,8a2d5a8d,e0271fef,2d0581fa,5ca30caa,8a101711,341d4221,b6b0a7ed,776ce399,e370561d), +S(5e3634d9,b7ff4279,3685022f,d3165c03,2ef8ed0b,c8a7d02b,685ab5ba,8557ac03,565b3913,355bb664,12225097,4e33e9ac,27cd38ed,a804824b,83985011,60f44200), +S(609ad796,d50d20e9,9cbe6ec,650eba26,ceee3c56,a6889917,44deafab,6a7a5904,54f9351d,9aa7d0db,822788be,bb1cc2eb,3300c144,1c7a4c01,230b47f3,7e67a9a8), +S(6ed020f1,fe8d7e4,73812756,3325e0c3,290b9a5e,d2723929,584f177d,4d9d429c,a1e48a25,b02ba024,eadde7e0,ea82c900,cb297d2e,b550c289,d664d4a4,b9b85edd), +S(5083663a,afe468d4,ec901e5a,14d2593c,b28c5948,1fdbca52,347d6aeb,4b7ce960,6aa5586,7467c6a5,dfc41278,c855727f,7a8b4168,98bdebd1,f9c6a918,a1d31aad), +S(e1c334c9,e355ae43,7e48335e,691a2aaa,64c3bf7a,16c77810,6bfff582,2a324df8,4603f15a,d7c85327,15502c35,cbe0ec58,e4ba8ac3,d038c4d3,ee3b4b77,74a13c07), +S(8c51fc03,ca1ed69b,4b627be3,3a7943fe,e1c15c47,ff7bc83,89961e40,6552907e,2a51ee78,7d48f8e2,53e82deb,a07083eb,b9513615,7f2a796b,c040b1d0,7582033), +S(4711e429,d9cd2b6,e539eb68,884d2a97,375c2cbf,fb30d6b4,1718eca8,9f3fa41c,ce826e2,711b6e6e,9a487a8,4ae72f80,a5308c21,1db0ecf5,706abe6,6b0565a1), +S(277440ea,ae6a1839,6f72ace2,c5cbc75a,41866c7c,c761bf3b,7bbcda07,ef5558a3,345f1584,9e4ef4b7,31964dbc,f9f899f1,def99279,ac2acbaf,3d1eeef1,bfd0685), +S(b9d1ebcb,91db7845,426accc3,578ec4d1,6df30fd2,9650b47,5c154d65,7a23bd5a,ea0ca814,399a76b9,5107501a,40ef0206,ddb1e9f,4933399e,35db6385,3dd2cb2e), +S(29c07ab6,e703dfe2,896985d,4d894d5e,5b793b6b,7ef2f5f6,dba00348,a8882fa3,7565e4e8,4b5485e1,661bb0ab,4b672cd2,5e9d58d6,48049ac6,8f2457e1,98b04a8f), +S(b9d17c46,9733963a,2f20626a,ef4f2184,6da791b,5e63194c,128432f5,58ccc682,5dcad0d8,7e08bfad,43e55633,3403f5b0,76482dae,d731e01e,3284c945,7c6eacee), +S(961e90a2,904e80f,1be65717,a0401722,6821876f,fecfa598,b216b04c,b4645c8e,5ab0efab,7112254f,722d021,a4da595c,99429a1a,5b242b1b,9243a8e2,54acd804), +S(40865cb6,f002104a,54a45d9d,da84e6a8,f98a3bd8,364275ba,4e14554e,2438f6f4,5b822fda,eb719e33,75309c75,b7c115af,351de484,98867a13,6b1fffb3,1e277d7b), +S(5efc3d76,307a2cbd,34e7d009,92263a44,c4e76e50,f1c213fe,b7fd6ed2,342f1a08,40bcc04b,cb227f3e,3cac4a7f,446bad6,6a304df5,a4128bd5,46f9f40d,a3e12f46), +S(13caf790,6a97e5ae,6f674956,c1586c67,57d3d56f,3d18d522,c4f365ed,97b54e87,156a85ca,74541ff2,9489b562,28324549,5cc42397,c54792e,2ba485b4,a86bb65b), +S(657e9dec,84a9120a,308a5235,6555c56d,6c1c98f1,cd946480,def7913,7e50f7fc,600ce754,7d74b757,c1e371c4,73401734,8fd6dbb3,72019f10,bcb4f4c0,bab1614b), +S(fec2b1d6,ab46c020,ed672687,7f2ec85c,214f36bf,149b2c1b,e75ae29c,54050071,3ec9964,20d9954e,edd8848b,c439fce5,740ddb41,c404c52b,f76865fb,26c48b8), +S(bafc595,37308fb3,c691f1e2,45908e92,776d76df,f6af7002,c581afff,320a4abd,2d8b8ef1,aab42751,27d0ba95,dedd27a0,29951664,e7ab9d54,b3a4a24c,faa3e386), +S(927cdbe3,2c1d78a1,89a4e3df,4ce6661f,149d7e16,d0cc7dbf,c287e492,891540c,e46911dd,cdcd70a9,f99f6892,18899fd,d3ff666,ae4533f6,dcfb441f,2b7da62d), +S(b443d061,1ea3a164,2e31195d,111bdb01,b6a3999b,e4377780,e19c3614,c0d7092c,e95b7ecb,e196c667,a19dbd2e,ff0115ff,9f0ce1a6,7f44d20a,a47d2990,e6b48c64), +S(e1836c7f,8b7dd235,f6af1b89,b7a13ad7,22dbad8a,78b1b37e,f6e5ff5,a6bc992a,57b02ceb,713319e6,9ebd7e6,844f374c,5871a792,e2109eae,d2cb5222,6c314e8d), +S(9f661b3b,c5829c51,2fc613a5,ad8aadb7,5c78edb9,9b84de7,683c6de9,d2a93f78,70e14e0e,558e94ac,aabb847d,3acde465,14c13177,45d45226,b6ca9911,f23ecd6d), +S(e835b453,6f13ae6e,7103137,bb695ed9,4d07507e,9fee8f9c,af661e9c,1525d3e4,192463e0,f1111a94,9f6236d3,1c0d6620,af9e0a3d,1f13f83e,7c4adaaa,76c81953), +S(a29fe97a,2ecbc4d4,f7156ae9,d6bfef6,ef601e26,4f92a115,48b5cd26,7cb26b3d,23b7d6a,15681341,6e1b8fb2,cebcbcb9,698d245f,b920f8eb,3d6b46d8,9cd25cbf), +S(396cf745,6127f3,31ca0fb4,95d98b32,7a738a69,260f7345,9eb79f0f,edc6a7b8,31b6ff3c,26879dde,6ebc9873,22a32b10,e283a256,1c1a65d1,928d3e02,de2505f8), +S(d1bd75ac,c37a3119,8f768b38,f665039,7d2f331a,32018a66,526058bc,aab440c5,5c17fcc5,b8e2500a,4edc3cef,ced52f2d,e20e7c41,bce4fead,8e12a880,aab8a185), +S(de72076,62274020,1791b51b,39fdf2e,297b7c2d,d358ac3c,375dae4a,494df54,d33d439,d4508520,6021c95b,cb1b22ba,b1595800,54056f86,82d73580,c50692e5), +S(958e9c41,4b096f8b,2d1ba41e,f5142a17,339cf57d,689d7d13,dcc22355,91418331,628b63d1,4e4cb154,a31d9752,9e50a1dc,f2684b40,47c27c39,bd54a0ff,dca06ed7), +S(38bae438,9a283e43,283d6a06,94e7ba16,b026dd59,3b505a09,6ee0f67f,eaaff536,9fb69e6c,73b27204,30968157,d5782423,cd4b7809,f09f280,93f5964e,6c06b170), +S(d620240,753af5bf,f1719165,f9d8116d,54c97a2b,5f99b7a8,97eea7c0,428dd1b5,66cd4f98,1b037f95,eeca433d,71d37fb8,b4a53f9e,853943a,ee0f5254,e42d89ec), +S(7de22847,c93ed32,6ff056f6,a002a7d7,e5d13361,e2580ef,d2cb682f,28e6ab96,c40be4d2,1273633a,e0ea9448,4bbf29e4,2b9bd775,b77802fd,31167d50,76a9b34e), +S(df0b50b6,679ed759,35883080,ac9196e9,ba5844b6,d9e541e2,bedb7693,c7af37c3,f09fe7aa,bb08fa37,aa5413f5,e17dc1e2,a07f83e7,4aaf160d,ad3ead56,1509e152), +S(578581fc,184af60f,80d648a6,97ab999d,f5ddec3e,b6046528,b9fc6233,7de81fc3,552be39,a8587bfb,d8de2f2f,6b923fde,20c7ee70,3a1c0c09,12ae85b7,56495ed4), +S(cca6a75a,131b5389,b2f8ae71,7d1a9f5,2258d3f0,4ed22b2,c836f7ce,3035def8,1787070,1bff0d8c,b74f5f95,1c6e011,f4e682f2,5d744f98,4c351b64,59669a4e), +S(6f81f602,b2054706,4a7c7b12,d5f13022,8657a77,e0bd1669,ed1541a4,b8eaf068,6ff959d0,1288bbb3,eb7a59b3,2eaa8945,8e4c6754,2a9bba0,668bf14a,ebb308ee), +S(90725203,94d2fb81,59e2ce17,5fb27da,7239f36f,61c70250,78a69c12,27fc0cd0,34a471f6,eb168b59,4a6a53ab,b93bad33,7da670e1,8bdd1eda,53b34849,94c21abf), +S(4e952fb8,b5e484b6,4ce1c1,c66e94de,3bb3a64f,26585c03,969e834b,291e597b,f7910643,47cbaa3a,e88dd796,ddac4794,c6500c76,147a26f9,c8f596b5,50da9961), +S(1985193,527e87ab,5b7dd218,718486f,1ed4b7f1,a444ee6f,21f273cb,901aa0f3,b067191e,df69ed50,b0771d24,2d99c8c7,22f1bfcc,bef31bb2,8d245f3f,b0acd3e5), +S(5dae1881,7a2bbb01,23561907,a22445,78e4dfa3,c6373f21,efe3f159,58abb5f8,7c6bd578,301ea8ab,f2b555c,66420c77,b84c6959,f96938af,eff54db5,4014d51a), +S(96a46ff6,e78bb2f0,4b299985,6d56310b,4df9702d,7306b30d,cdc7ca4e,68114e77,3f871bf5,d3a4ee91,17653bb8,5a98e599,d86ae580,17e8963b,9b18400c,979994d9), +S(31482d19,6ce07585,bc1268cc,a355df50,b9009f17,fa1e4f39,9876fe2b,51eb361d,50dfcba3,ce43896,1fc51f06,5ac4e58a,4757e75f,419a9525,5263830f,fb936e9d), +S(94c128e9,6d36f7f9,540da468,a2fd488c,ad615f6f,7920b201,27311941,db6e2405,595f29f0,f9622e32,b62e3ead,9f9ac21e,d07d7c07,7bba623,6c7e57cb,747da989), +S(a16882ec,b52def37,227e2990,3dc15e4,d4bf10ca,1b1adf31,c9cace43,348182bc,53f6d3d,6dd5603c,2f2bc7ab,677a6133,c138e26e,c030ee9e,705ce002,62e11f5c), +S(f0f5ef2f,f0f63cc6,fb7b3d99,6a5b14df,99a53a45,3a1fa425,3ff3ce71,4168cbe0,598b5ce,44e168c3,bef06c4b,c032924a,da454c75,b53d17cf,cdc2ea7d,93e3b883), +S(3aceda5f,190d83bf,f5111acc,d57d4d2c,5b7692bc,62f480b9,f5cd539a,b2ef0c1a,5b8f973a,16151dee,92930702,f3bc7f1b,93a096a5,ca4ff3e4,8a41bdcb,f78ba60c), +S(4e1eb580,b3e3bcd4,4b2905a0,d07d7334,befcca94,c7cbf639,1710948,cf2e66b3,c1d6ad62,c10bec2c,127446d5,34863682,196ce8f,4a966319,2be7764a,46e733d8), +S(322fa340,76bee9e1,697206c8,38cdbbd3,d54c3a30,82c22b3f,1ae17da9,a9047856,c4493e49,b5cb97d,eab7ccae,8f1547c5,98e286b,5e7301de,cd50656f,25dfc1ca), +S(4aaf3569,2b080f70,aafe6374,f0007570,d23fb620,cbb60a43,305f5e3f,29e9d189,1dc30c11,91f985c3,39bc8592,8390bc0a,c99d3efa,98f4bfd7,df2f86cf,7c297dca), +S(c18629a7,17d1b01e,e2f4bc72,2c86fc26,878884d9,a770b62e,d7167f83,631ff2b6,3438211e,bd80ab41,dcd4e76e,c742aa3c,1c859cb9,1fe0960f,eb0dc74e,d119a7e6), +S(239f97ee,44d77679,7a91a196,82c9064d,4552b4a5,33033377,6dd74ae2,fdef44db,dbf917e,c66d0b04,a0bd607d,6448a678,1821933d,26d51865,35d3d587,ea680a96), +S(c0fde604,387fa85e,5c5cba98,346042db,83a64e6f,103d7448,22b6298c,98bc7100,28ad14a8,30b7be30,58ce8e09,7fdbc87e,a3c60b3e,840ad9fa,a7cad01d,b83a15ac), +S(95ec759a,5526cd4e,eb9d00c6,9702dd89,3ae115fa,de3629c6,5fcf5134,2f389355,2f899643,711c5f72,8fb442aa,59139fa3,b1b0b4a8,ce75ba07,67aa958,eca943b1), +S(7da3bc4e,867885e8,febb8c6a,e5da50e4,55fa749c,adbc5800,1b70ebc6,96ee9b89,dd989b8,c4bc42e5,8b41fcac,bc1e1f17,bb77aefb,964bfe45,fbae0843,6dec8cc2), +S(120fc1d6,12db86b9,f352582c,e2761ad9,8a29444c,c438e2f3,5f523d83,e2bc3d,437828d4,5357a2cb,ffad57f,f991e91e,83466aef,584dd7b,a3b24d9,31eb6cb2), +S(50e42888,366a1fe2,83cb22d3,df324d3e,e52f58bd,26bdd4c9,67575f7a,5adc380b,2fdd99e8,427f9b30,1e132beb,3e0fbb43,8e6ffa8b,147c825b,e4453fbc,1318e015), +S(275dbcf6,ab238c94,740100b4,29356528,69de76a,9d84d7b4,9b88d526,9b8d5339,90e835b0,f20a7177,936c5717,fc18d0a0,28a31e65,53c32be2,699ae03f,6ef2807d), +S(59d174a2,bb918007,f3e044b2,7acf5e6,8264d529,cae342e3,fed00475,d95b86c8,dabbd87c,b49bd118,a663a848,2f7b1c51,9fcb0fcb,48f2f966,7a13ab2c,ab122860), +S(f8926a6d,5d824029,8f572847,6439f60f,528cded2,2849f182,e173f84c,cb75e1fc,8c641986,c4fb6a7,acea7627,e4f6872,26f86de0,a2160a63,1b2e1a26,9fa5f6b6), +S(d765faa2,b9cdc6c1,d9f070f5,4fe286c0,60351c66,c7a241bc,94d10e4c,7287e7ae,ff732ad8,fa7f0c3a,9ced3ffc,f5bec9e5,2d1600eb,4ce4d781,20481559,82c30ec4), +S(bc83f94c,7be686df,9caff340,35c6e393,1fc2a33d,7a09fe0,b5d09e64,a0610dc5,772d167,e762b3bc,df68c291,656a4259,cda67486,e430c7f5,492c66b4,b3e61fb1), +S(5a8b0422,21313e22,c5a2cb24,ec6199fc,a4e95da4,d5f59629,ca33f4e1,419d5626,2f609bb8,966ba692,84fb6854,5dff5b2d,f1463504,5bbfb145,4fbf40df,c9884fd8), +S(b106e89c,b4da505b,912da09c,44f42d11,a2de8836,28623cf5,7f27742c,a3852a97,90ed9bae,78ce94c5,5e4e971e,16013f9e,6902838a,f7f851fd,100c8e64,babdaba8), +S(c55445eb,439db24f,deaeb4a3,5a71ac1c,8915b051,350d4007,15cb9d70,2319b0da,98b517e0,32c9a963,f22e25d6,f3306f91,a4b604b9,6591729e,64b73794,55d0137c), +S(f05845b4,5f975462,e1051499,d8189cba,89bbd435,6ca3ba68,7b9994e,81dfefac,11511fa6,126f8d88,14c5de2b,dc92bd79,9a466940,3ec8a5f6,f445c59d,bcf779d7), +S(35620920,f58bace8,7dc7f750,876b59bd,980ad703,b3127c3,ba53c20d,56fb5755,759d3f68,60643a2f,d6c946ba,5bb70f61,fba28208,77dc47fa,a4d9ae14,9d6ac9ee), +S(f70c93ab,7145bcdc,2ba3a9c7,f423da0,26a39180,6dc3686c,fe32408a,f659f918,84f71fc6,818151bd,c620e79f,a2d380e0,eb37391a,4a56b919,eb14b2b,cabee697), +S(858916af,74216be7,beb2dc10,47f941b5,157d7f19,c9b60900,bc844703,79b4bd3f,77b78d3f,5fc4e872,3b7cec8d,8653ea2f,298a1057,88bb4cbc,18e4fc99,108620c), +S(4b690a4d,a3649304,96fbeef6,da701b8e,569e61c1,6456659e,4c229813,d7118d67,d64261b4,4f26a263,55e787f8,fe2fd5fa,55f44b29,5cfa9c2d,8cc90830,60ef8b69), +S(37542949,6cf4e6eb,36b733d4,ecf1533d,4ef38ed0,768ff1a5,58dd210,ef8d950,3fac2cbc,a4280d61,1e30efcd,cccd1392,374d351,ed9dc460,61041741,2d0efb97), +S(870a9ee9,e2a00f61,af0d1f0f,967971ad,c5afef39,b52a3d5b,de74802b,a39cec0,a4751ec2,989ad16f,460f3071,ebe3865f,3319bbee,7bc7c285,e8215ca7,831a81c0), +S(28c63e6e,99936241,73c0c5e5,7c74543f,dcbbb678,bc786746,809d3206,3c0bb3f3,f0c610d2,e268cc32,3dd39ec5,51723b9d,22cbb5f2,f59171b,14771bf3,a4ec7183), +S(1045176,321bf271,cf34eab,686d3ec1,26000d6c,b1e66d55,860cde39,e5b00885,2cdaf0,11879aa,10231e46,ac93baf1,7bc92067,24f97521,7e2fbde5,cd7dda17), +S(9872ed48,bfef1218,35ff27d9,168740f8,38c2628e,15dc1a17,d5c72ee8,df21aa5d,f744a757,b922361a,3976de72,7ed83300,885cfd50,5f6be5ee,2ef9bd5a,1823640), +S(12f16ba8,5a2833f7,1af7244a,36228deb,38075fe,222f4d6d,6c02744f,b5731a9d,5538557c,f3d2b832,77db6634,8119a3f2,9e272b9b,bad3dce8,df38c3f8,33dc9095), +S(96489f8b,407618ec,698cf6bb,1366664d,7f14cde2,3d3417d2,80f0a3e7,cec87c23,4e78ceda,5f034e7,8eeee63,bf263fd2,35b8d60e,93263fe2,fc2acc89,fabc7728), +S(5380517d,3a681527,cc2aa8ed,29075afe,9eb0660f,cd4d381e,803ca7fb,2bea7245,d37ef6e5,f3c824fa,75ef185a,22d6e6c8,d8ff865b,433388b1,a6e6cd7a,4bebcb1e), +S(2f33b34c,3b22eb72,5d27688f,96f94ed7,23c840f7,549063c1,386e447b,faaea56a,c86fc369,59426e76,8f005d41,5c7316be,bbf1bfb2,54add259,91ad2961,8e9f50aa), +S(cdcede30,e227f45,18d39336,204641e9,27a61c6f,801aa002,5f892be5,7b49e574,dc3b0562,5e5dc396,26c1ca3f,5f2fa1a4,dfc28dc0,18d6ca0a,b21966ba,5d1ece42), +S(a9642c56,2e284ef9,5cedc32c,94c55dc8,3768344,e7317ce7,730da1f3,c6ba501a,cb3bc00d,de25189c,b8894fa5,219eda80,934941a4,8dc8e140,9b0d467c,ffb1cd95), +S(32b67c85,f0f4219e,2ae8e63a,ac95b210,32674730,6a37317a,19a52235,73bb7641,d8bf9f41,e584dfc3,de237e70,79cc170e,96c2cc6d,62042157,ef60ee02,3d142213), +S(4d095001,ec45ad22,1c9cca7a,d588dbdf,91156878,688758ac,63514992,128e50f5,c66d7dd9,9206f339,e0b80e51,f6ee72d,619c77bc,4ef33b46,1c3b8617,7359fc62), +S(f51d320f,bd158ea2,71cdaf12,651e3eab,e7deff0b,434a8b06,b3b31f4d,f6d6547c,7233df17,a17de7d,3a87118,97006ca7,8c7cd5d4,7a86403e,24f050ef,dcf3bff4), +S(f0dfe901,237b4b5a,ba6deb8c,39c87cad,5bf4dd5f,6a5e55da,d7565ded,c4e50089,eab06c8d,6bc7801e,7aea2e6c,919db667,324f0377,ea58b070,2e87b10,7857130f), +S(2921d36c,4766c1f,775ec19,302f5690,3898a835,aa8dadad,6c8202ae,270e38bb,a79c8e4f,cb59c784,3f81b66d,57060d2f,7c7acecb,c2399191,b7f98ae6,771cf849), +S(99ad0478,e840c3ef,470a47d9,ff66a197,b62881a1,6189d9ae,13d8bea9,3c1c0994,3e9fc2f7,d37d580c,a16eda71,ff6d1995,47f18ce3,515adca9,c08ed241,d1607f82), +S(970f064d,32c1eadb,b42ca1a,8893dbcb,dad1b9c6,3b99a15,e772407b,3aa1489a,efc34e6e,38e29927,9ee73b0c,9970cefa,f471f130,9518b8c4,81e7f67f,ffd807ae), +S(8d995e26,e9ebcc56,d2f9637a,df1db60a,e1b51d12,9850edb7,ef020a2,7ace35b7,1ed723ca,17892eb0,63ee5164,ee8e7216,96a3c3ad,67a3d8a5,a0d87803,37c01176), +S(c650e8c8,f995291a,a1feb490,dd9ae957,7506f591,c308b423,6ca005d3,ced75866,505e36d9,2ab967e0,a1168424,60639c72,646b0569,d3651800,316126d8,810a9444), +S(aba9f9d5,ae231382,b3583971,c875f4fe,4c51007f,6d55e1da,79d7e369,c21964fc,e6a176c8,34fc11b1,6f270f69,f4f54f1a,fab4729a,20cf6348,9cdbd551,ae5d1fb5), +S(1068b9a4,19f849a1,5dcef7d3,9b3b55dc,2eefe04f,554f283,212b489b,79b79d69,20993e51,4344e2b7,28188465,340b28c6,5331a7f1,a6aeb6c9,7f09e9ee,701f3828), +S(598358f1,cd3aafb1,9328dbad,62b65232,4aacc23c,87b37271,e8604caf,d69fc3e7,4297b258,6c94df83,6fe6c528,fd1b8fd9,62969227,d854e09c,375f85ea,58cd78f), +S(d4a638b0,1ffac322,48dc1844,75e3d06b,3b6b9a4e,971c7153,da49fe20,f44853dc,e9e708a6,5bd3b39b,15ca6606,512933e7,97b4adba,e72cee79,c79605ed,cf601d6f), +S(38421e4e,fc54951,1560c7d0,dd947c84,652530e0,d5155ece,8795936b,83b5e115,cbd0d873,ef6c0d90,9890b820,e8c063a2,35d2071a,97cf73f5,74ef2ddf,83ddf168), +S(2cbc4bab,442eae5e,aca1cccb,4a589c6a,8822138d,c3a35885,132dbc52,7648712,174b4deb,3b28ddef,426aa586,314b7b62,4e9253c0,1fc2dd7,ee94ae0c,57d3f5a8), +S(202d232b,4244ee54,3fb77958,32c149ff,8ee9a4bd,86c02037,634f5254,9f2dedec,67d64143,1915831,bef7e85e,f057ad07,a6de2cd4,3578ba0,eeb5cc70,1d16a499), +S(4faee6e9,90601af2,3f204f8a,615506a,82288490,a14f692b,86c8585a,52b4c94d,b45c0547,98d18942,7349a87f,5abfe689,68d14f82,d5ea836f,131ad030,ad31c8a6), +S(976db42d,c73a4705,fd782bb,2a87f260,19f6d218,3da3ef97,e0e19304,87ef7b42,2e543c4c,721512f0,81c7a6ef,987776cb,11318c52,ae6e2883,7d52a160,d183c31d), +S(9dbbc369,218c5741,36a0dc48,a17055ba,2a8b1580,88932e85,9a0b8188,5cd11309,e93dccf8,4dfa1519,45f6f38,d634a21a,b431f21e,ed8fd004,e27ea99,4c9d648), +S(660a226e,48ce5825,14c0f49c,d27621b8,f52657b4,17b8c1a0,ac9ecd0b,b9e0cc16,6d2c4b6f,74432c0b,ca351ebc,27a72b6f,68ad7a1a,8c509d8,8308be90,d7f7454f), +S(2ccc9a2,5c61d492,5293f4da,cfcbd818,11bdc998,7aa58258,f161210,40773237,5abce831,b2b09a34,4d93a77f,b8bbe8e7,d6334cd3,be3fc86c,154c74be,c191e9a5), +S(dd9d0f81,6c41936c,fc90cf9,3cc8f14d,8494f853,2b3b72d5,95d94742,8a01a4b,f30ca0ba,3db463a8,2b82b1fe,3f310936,c58906e5,ca07e4bf,9f4482b8,360ce7ba), +S(1314cac1,d751b3bb,c867e592,9df56ff6,99f810dd,f76ea0d6,f68a3e7b,4d95051d,8d3631cb,226a854f,143c1d09,89dd1ce4,7d943432,43060f78,ed3af3e4,f0d8d41d), +S(b1abd6ee,fff64a72,83c26a60,be0d1cc,f5152df6,b85655d0,9495d405,f2ccffd1,549457e9,b4f2edec,63f81471,12957918,baf8deaf,7d8a4b1f,489c24a9,44f210fb), +S(5d8e23e,1212800b,56e7740a,2f20c402,6483ce0f,755e36bf,fc4ee667,3df1b32f,973cab61,da46c5a8,6d1633ee,1fa28892,6e1d814b,800762b4,e4599ec1,803c0af5), +S(ae0bfb9,b5567b95,34510cc4,ad8dde2c,50c1dc53,6c9ce5e9,ee97fc70,f8b4f562,a8d15459,7fa1a816,3eb33c40,6b78ff19,b4927a3a,fe48a8a8,1492884,46ced08f), +S(b2ed6275,b818b2d5,ccb807c5,262d5578,c83743b3,701217c1,8188ec52,bec10325,5281815a,b21491d1,62e0b3d5,1334fbca,54731fff,f5d44ac0,396f477e,ab566896), +S(5d5c034d,228aeed2,270dec13,deb5418,3205a996,509211a6,8884c2dc,42d7d7e2,316c32ad,36906509,2e0112ef,eef93269,e251f83a,9ea7781f,ad59122,ae2ad4b7), +S(3d94f70b,39605f40,23107882,b491cda5,6f1b9ffb,3fcc47,51e4309c,812c428e,b3de1921,d29a77fb,ae8c6460,c3ecf92,22b88c4c,3a96cacb,e4385416,7898d7b1), +S(5c0dc575,84732fe0,5098de0d,45926c0b,3f8075d9,2ece92eb,f910263f,3e0d6df0,34c7fbd3,171b85d6,65bdd9ae,30f671f6,688a55bc,cd68c0e5,1153348a,16b75a88), +S(15d25179,6b55cc34,5beb9bbb,f6ad1aa1,b11b60b7,5bcd80a3,2a44c180,879e3513,46632865,ce1e74e5,f3a89a58,35adfb01,eec8e0f0,34b84aad,a0d2d901,ee07fa81), +S(86e5faf9,dc091174,bad52eac,2c83f945,3bfd9f82,13505e10,323255ab,b9e8d0f5,3bf19876,8c8b5f39,ba25a9ff,5d112600,956072e2,7775af11,52bec5c9,7b2396ea), +S(308c0956,4ee3aa0f,792e8630,3ede1407,d3d3da3f,423408e8,7b0c5aa1,2d6aef57,7c39d220,975a21d6,5ce1e2ea,930bd585,203d9b45,bf5f2eba,ecc5b245,e95f0abb), +S(19f9d4ac,c7de487b,cccae45b,2515f727,196911db,d799c7f2,a68078b3,181099c6,645522a8,adeb841a,81e27714,ddc40585,81cb8b24,e7d9620f,c940590b,b14f14a4), +S(a05d82c2,4493370b,cb7f1639,16865c71,3e89d968,8c96919,ab99ad92,afe96a35,1576f727,6c65e32c,1dc1ad98,2f75749b,75589cd1,43ad60b6,2163a8e9,87cb35), +S(6453661d,303acf74,751bc7ae,e8226647,b17b5808,f3f8dd63,4c00a78,94e830b1,145993d6,ab6592bc,b6b242d4,432be395,de7d0014,479aba5c,88a48cf6,adaea7ab), +S(adb18972,9de87486,3207f954,4e3eeafe,fa255209,4a8c0170,44a952be,aac0485b,2c67657f,d6a2b08e,28463e9d,abf708f2,2c790aaf,907af16e,598f325d,f657211f), +S(8a6ea198,371f94e9,288943c0,5e387cbb,b2071935,3562fdd8,f9fbe899,ac31ce00,d5b817e2,4f5b3fb,e25212a1,fccb6e1f,1ba55211,ff2e0123,c71175b7,bb94597b), +S(9e18eaa9,621ea829,38505584,a5879eff,446303ce,9cf61bbc,eaa6c495,7f259778,3310042f,54b5ae46,1c996f45,abf27c3b,5df06779,3c931927,4689da07,46254968), +S(27ec08,dbc47af0,d3db2aa1,a3b4b22f,5cb42750,b4ad6680,9815ef21,ac44a8bd,292fd5ba,9371d8e8,d4126197,18bfb564,2ed1f537,3303754b,af6a77bd,271d660d), +S(4ab3436e,34fbe37a,aea7dfb3,70d93352,ff4a7c22,53f1ff2c,8453c5e8,cadec2c2,90221aff,faacaed6,760b1c91,50eb695c,a1117054,1ee068f3,8c684e6f,b005b406), +S(46d75d8e,b2b5ccda,2d6819f2,1338b125,61a9c872,1d8956d5,b9c73148,4d928895,8153db74,27f7c4e3,381567c6,e2629702,8db4a5ac,c8762ec8,181a5da9,b531b6aa), +S(469ff047,7ddcf32b,a0c71766,474b5730,3b687406,c22e51b8,9f5fcedb,d154e270,acf0fde8,b426233b,20ffe9d5,5d1bea51,5a19a9ca,dc642a02,6928c05a,e068f747), +S(1d0a4e9a,ff31f94a,456c974b,ccd5169d,594b7263,5e817f29,4ac1cc45,52d3c6d5,52d567e8,1316fa28,1c2dbe62,75e51bf1,32f2a573,77e0825d,eb024a1,8e637683), +S(d1f25e6f,5038f784,84ffb8cc,7b5b67ce,908b3050,371ac332,228c3f79,577e6e3f,6cc0b7b2,76a948ec,54b79662,6fe435f1,5c68abdc,9fdcf8ad,41485a7c,58291f77), +S(56e97220,8d42989e,2a0313ce,203dd87,e8bdd09e,38bcd097,6e3d047d,7b8eb385,c78f2ca5,93d563d9,6caf585b,25873cba,3f4d1f31,3e31fa32,df2e9e0b,7538cfa6), +S(61f040fc,eb4db17c,7675ce64,73721c47,785e30f2,217f03c2,5e1fd723,d40644a1,950c39d5,1994a902,e637cbba,e0afa218,50e5b191,ef5b5939,3257d67e,555a1d3e), +S(ceb5f3a4,e47483e0,a6137f38,1ea23678,81c3df5b,830f80f3,1a08a3e5,e5181f0d,6a31aeaa,7533fba6,7e79f63c,abeef7e4,f130f37e,1922f17f,af20a63b,51a1c485), +S(d9b195a2,dfb91ba5,814e54f0,3bce3f30,6b7f880f,594e8dff,684cdf8a,bcf63634,130e6034,3fba9959,898d4227,a8b4e79a,5a4055e1,a22cffa9,8b445c6,4684233)}, +{S(5e8cc841,c1b251c5,317faaa,89f6c9b2,107e793,4abe27d,adca6318,38a9ca72,9c1c881e,10e9f194,e00388e1,e2414f5,74946554,d2656ceb,392dd6c3,611eb982), +S(498fb0a5,c2a2a7fa,2e89a846,d7987897,b3e843f,8d664911,277c85cf,3ad0c128,c480af90,6f0aa1dc,8330d211,aa409649,3da0257c,8d09d5d,8b1aee13,f7e6f26d), +S(9060ce66,41a763c4,8d0948b7,670c1d71,1ac2a81a,431b979c,946eb25e,3c8ff8f2,567b9831,a2555c20,6dfc4c41,9ea75b99,d02a00fd,f3942ea7,e27c44c5,98df4d7a), +S(b528d336,1c7c3cd5,5480aba,4421c209,cdc234b,f948593f,98eb3c2,95a18396,1326dec0,490078f5,7c541200,9f131410,9fff1f92,eea82577,2fcb8834,c59f0c33), +S(5b0e61ef,8c9ca491,83508642,8cef89f6,75f49ee0,f33fc8a8,5783e6fc,3b4c59b7,bf1f0c2a,ebc45330,1d12e8f3,43b4d3fd,df0e40df,b78cf093,bff413da,923f913f), +S(22e892c2,258575c6,e6ba67f4,e0e36853,27771a2,28ff9ecf,a2efb43f,c9f1c7d9,2b20a268,bfc51047,a8b28952,795b91de,624a3487,9abe535,3cfd3a11,87a86493), +S(70bc895a,ad0c993c,25155e97,9d9276f4,8227b6b6,d7a31bb4,b64a969,8102e886,7c0be1e8,f268015e,987392b5,15f60d04,d1453e7f,fd5929b5,2176e24d,ac10da80), +S(1dd63c17,421bf994,3a85019f,777bd41c,fbea006d,d4e0b80,2effda5a,8591b87a,2fd392ce,2e25e393,9bad93d5,616c65d9,87718cd5,9b8cfe4d,e54473fa,49c86735), +S(7d3658a6,df58d88c,7ea92964,3dad19ce,12f295e7,b8b4e710,9b9297f8,ea83a088,6ce3e119,496fe842,f7e2fa75,b635c11b,bb4d00c3,843216bc,82c31cf6,46d9f715), +S(aa02cb68,5acd4d74,f2c547e9,43aa7360,6a960d80,72aac984,b44bb492,e61b1d94,1db77713,702ed407,655dc5df,55ae0329,a30aca7b,d5655ebd,91dec954,feb0e02c), +S(e015e1f2,10b7eefd,775369b7,64192078,edaf3118,9d7a5382,28a744e5,5ee7f068,dd69db3b,a82ab3a3,86e1f09,a6c3b8b1,37b48021,a560c0c0,a8c910c1,e315b721), +S(ec50fee6,402b79de,afec1f9e,25778b95,5b36273a,6974963e,3cddb748,1166bd4b,21b5136d,2a71804c,6c90a89a,70bc05f6,afa26558,ca1aab74,610cda3f,7adf0f03), +S(213d69ae,6ea3a73d,3566a2d0,10f6c42e,d0c3b60c,9f104706,153b48da,2b155415,198a8c8e,ab3c11e0,2b0d69ae,7ec09ff3,e69ebe21,8a849655,14c46aac,786954e), +S(5ace25ab,eeca3eef,3439dc5d,7313a07e,7cc94c45,5332d38f,5fd367a3,cc88b2a3,2ddb1c5a,168ebf76,6080304b,df44e644,d5b34ef2,3ac49fa6,3b19390,83fea9b), +S(fd0ab7dd,a0907d2d,7349f860,4cb4794d,db9d0a2,dab0e6e8,7fdd90e6,49a3ce19,6ab30bc8,fd9fa11c,835509f1,c4e9b0a2,faba9de0,4f2b8ba5,e3ca666e,cd1aed56), +S(a8af0736,a5e408ec,84b46f55,16e04fa3,bed5f733,f8b99e90,192bf2ec,ae1fbd4,aea37eb2,6f9b6ee7,90eac699,92a53732,91a68317,efd3e651,f27636a,878a531), +S(a4effed2,dd088a36,ad6902ba,db705a35,187f721,20e747b0,2011839d,76d68be5,5efc6581,210022b7,fd8d3dd3,f11c95ba,99a28e44,c316c8af,7510816c,256848a0), +S(290bfa2c,8971750f,90aa6762,aa1b2b9f,e9eb50b9,cff25ada,4a7239ae,3524a799,1e16aeb,1fe3c65b,395a06e6,49545ee1,95f0a6ae,9954f6f0,dfc1f528,ef7d0759), +S(25496b16,b62fbf6c,3e9c59b,de7df4f,6216256e,3b968588,e184bd6e,b9543eaf,6964be4f,d9fc2dbd,146774fb,1eb37f0f,a13a11e2,35b1c870,fde75c,ecf750d6), +S(8585f972,5efd5404,fbd73e8f,c78a4e10,8089f024,f6ddd66b,28d56031,b98f970e,4e61cd98,c9ed1efa,6dd112c,ca27383f,1614b0f4,728ce990,9251309d,13c2777b), +S(b4fabb0e,52f273b,9e5e245f,82a151a9,296d93ea,d690378a,2653eb7c,a68020a8,5a0d976f,2d34b780,34ccadd9,30371689,f1e3c5a,6ce774a0,db9da3e7,aaed0542), +S(4c902996,a5a7ddde,3bc42bf3,31fb1cb3,61ec471c,6b9d8e9c,249d9e74,693c9e8e,3d118fb8,4e8061f6,3c8c5f09,f60298ef,c7983887,d1522034,8c9aef13,9759347d), +S(8a1fb43e,3591b453,ea7353ed,f3414793,2cb2e5e4,33aa01cb,cde2a865,27954691,40982292,e5b49878,b7471564,a84606f3,6e128d08,3d542e57,ab04acfc,dc1f122b), +S(f93d9de4,43d93908,8529abc2,d27efc02,682e96f5,79133ea2,e65c44dd,4cf5e6bf,15c9e50,696af51b,64e3b7f0,19b3e27f,7dac74bb,d72a0007,18c4c3ed,10db4873), +S(8755c259,f333b12b,88917775,cd5c2536,431e77df,f80a59da,d2dd7a1a,a56c930a,d2d681f5,d6259780,8d5c4a4b,9169d9c4,181edf5a,cbf4b817,d27b4e2a,3adbe697), +S(30f44aa7,9d8a39da,3abc6085,b6d5f33d,bd96f266,e6f37382,c20e749b,efced3f0,8acdbec8,2461ef14,f4096274,cb08f3cf,149e0041,7c075595,ab24fe9c,5ec15b96), +S(691a190,7e98a004,98af8c72,3850acf,81f07e76,b70afd62,96174058,84bf4a26,df902e4d,3e7294dd,66952c08,4e562954,2e6cf93e,94cc0d9c,672d097b,38844483), +S(998d8727,55f5c048,1d738583,e3a80de7,c6abac0,249f01a4,1b890d98,2ce74471,cf9b4563,67eeb428,865a1416,ce7b7f60,ae953bab,ba7a67a8,15ca6a5a,bb4b7567), +S(21f95845,8adf4ff6,d500e082,56454d33,7893cda0,e02ee161,7368a2ff,1aa66dc5,d88c985c,3c40ad,219ad336,ced08e32,f328a0fa,f4cb8ea1,9cd17762,7b4b257f), +S(107b438f,8273931d,d14d9b3c,dc5a102d,41f24887,9342d3b4,539a9d76,a04cb362,a41365b1,4d0857fd,da9d15b3,76dee746,55d259ae,91b3e97,c61bb70b,4d0c3a87), +S(b8f40c64,3d17a3a5,5329f710,5a8c799,66ac1466,30d64264,1262824c,b276c705,81d88197,c24f85c4,88c96401,4a34bed,17067ad0,d640ecc6,8482a3df,b374647), +S(33ff357a,ebfbf690,b97644d5,af3b5766,7e564c25,5685458d,1d0dca97,f28b9cb9,59de095e,dbb83b14,1610f1d6,289c21d1,811e875b,dcaeeec9,40c6bd8,4ebed43d), +S(6f2c27e8,46c1b5e,b02c57e0,2f8b78bd,af6a6489,858ec5e8,e60c7e84,c92f8a42,a20f6853,3e180ab0,bab00ac1,d517c66b,9f81088f,f2ad751b,63fec4df,d2beb5e6), +S(510f00da,f51cbe28,7bb0eae,59abcca,f3dfd507,976b92a4,558de2bc,91761621,f268b1e0,549117a1,b2123754,ca50589f,283db3d3,95c1e081,bbe9d027,ac3a8561), +S(fcd2aa5e,5c3fd7ca,a1c9dddd,30feb5b5,c3abab65,924c1865,913ffa5e,5658d2d5,662318b7,2cc9a9e3,5fb122b1,d74cfd8d,55eeca4b,a0d6f998,aa9dd09,266bfb3f), +S(9292c47,e36ad0d9,957a90d2,8fc00580,745a52ab,f14f3d61,c9c02163,e43c41b8,80ea3a5c,16f68cb2,67837544,289d1ea4,48056da5,51b56bc3,e243d45f,51b770c), +S(30a07a32,2d6deb75,7c3fdf92,db896b78,25b4043,87e7120,eed7cc56,3fc1886b,b07239e3,68803d55,96f843ef,929529ce,96df7e47,36a2cb35,dbe30aeb,1ff5c3b), +S(4ace91fd,2db5f7c4,29e6fac3,ed7aaf6f,46217f3,e2a67ba4,74423f4f,5f2a47f8,18db8c0c,eacc55b9,fa98ad2e,da9634b9,c47aec7f,9cd8e89b,41913e20,ba2ad9cb), +S(63ed08cb,b10860a5,4b6c0428,8f345cf3,f6e0a48e,9935727d,9070bfe2,dc0ade69,f24eaabd,e3cb05e7,c74d3be6,d17bed4a,2d4257cb,e69b876b,c161f8c2,4b8ae792), +S(66e91d3d,e5f63aa4,8fd6d3d,9129f60a,c030cc88,a2ee10da,5c187832,ee309ac4,5d90f490,8f5f0269,cadec883,e4ac47d,7f0b8d2a,cdb979ba,78f1576e,7644aa74), +S(e6faaf1e,1b7eb6b,e1daa8a2,f7f3fad0,e0250e35,f59b4ad8,a80fb38,5c0ca6c,3ae02379,79d9c291,68a8f555,8469b4e0,98dba357,7ec85f01,8f4043b8,72e78ee3), +S(c1006c5f,f598f904,94edfaa6,2eab93eb,e11a44a8,5e3e1014,91218cb,13e7b497,b6d15bf4,28df9655,bf70336c,ff7b6d80,b7890d9c,82b0323f,20f45935,6635f4c3), +S(f9cf093a,f613d28c,695f146d,5790f6a6,379feb52,1a337d66,a5032f93,46a0c7a3,e017544d,56a9dba6,e9c248d7,9bdfca89,8b521ffe,b5e68a9a,26ad6f2e,46299bc5), +S(90d1d995,67f6afb,37806ce1,997c8917,e6ff7191,5b6bb4a5,cf1433b6,9ef433f1,44b0e285,e03ac5b9,5e4352e1,13775a20,66cdd3fd,fc4a90bb,9d39b6d5,a796864b), +S(5e48b3fb,eeeb724e,8442fb8d,1510770c,c0e879f,94ba1ae7,f67a853c,57a38996,20650a89,dc8e0869,5f6c2b16,d8620af6,b9de2333,e29ad5d5,56445f54,e4c19a56), +S(90ca5392,1fbc1d53,7402708b,82d3d4a9,366c39f2,4fe6bcea,8435b5c6,544a4090,ced1590c,b11bed19,8a14eec9,44f1a117,d51a26f6,df89f62d,d4c0ff2c,d38758e7), +S(7d4a162f,6d359758,9a9cc446,f111da83,4ac9540d,7dc3fde5,8fb8d3c0,fd63eb8a,445033ab,53a9ae3b,7ecd39fe,aff2b18e,8d308de8,dec4fd18,8243ec1a,caa5ce56), +S(3344eff3,c3a56453,f2d37f8,1970c94,5ee2bc68,b85f53cd,3f4baa3e,2784488c,4966989f,f6372f19,5eb32554,9642e3a0,954ffca3,b650fa01,a7246743,ffde881d), +S(dcaf9831,99beb377,18623330,197415fa,667848a7,634b4821,610bdd7e,453794af,44c24125,71252bc4,db15ade5,abe3813d,f8425f1c,8a1f3281,6d33077a,bff19bf1), +S(57fb24ce,887ef2fe,f02be42a,a09f6e24,1bcfc52f,a58c8bb7,fae08613,6431dbc8,c2044794,1200e77e,a1d18139,55f58a30,c9707f22,42529a16,c1bbab3f,dce4ca23), +S(bc4dc9f0,54afeea2,2bf06988,265d01c8,b3cd5d47,d745c75b,a234f6fd,9231b3b6,9dffd7a4,1627e744,a637017,eb54fc22,4d949bd4,1b1f868b,865765df,13508cb3), +S(299f90b3,ee45e1e4,3ee1dced,2b302caf,11094a75,9e1bb90f,6c751330,d13e1f6b,6bc5dffe,53dd7c39,51623cc6,a7f61314,7d1847e2,73d03369,836e39a1,e6da81b3), +S(5a239aed,c93efe47,3141523d,fea3af03,16aee518,8629e8c2,e279eff0,62b0717d,117ad8f4,ea8a387e,d9f01296,e00c5864,ac93a78d,1968ee4e,9c325402,63acc5c4), +S(609b6afd,77d8c8c4,3c14ea1b,e56dc2b6,beca0239,faa88f43,59f9e6e0,1ebb8839,a576ec45,1bb52bf,39e9981a,4079f3bc,8e417bda,36797411,5e95e384,74632481), +S(663283fc,3d0fcade,ef669583,180a8e1d,b297cdaf,672121b4,4c481533,1d06bc26,139c7dac,f30b9031,de97c069,76812e66,7cf59091,7f0ac6be,f606afd3,c4f30448), +S(eedf6685,d605ca2,e97b801,ebc72b5d,e135f782,df6c243f,140bf172,9b23f671,a6da00b7,3ac5edf,b83e8fc2,5d6603aa,72c2af47,62b7ba2a,4ad98aea,53c8f0a), +S(ed14e1a8,73f82d1f,4e211823,b0632e49,3ce198ff,ec6c19e2,b9467791,8164fad9,fda82b27,3517f8ac,2464cb9c,b0edf241,ef91ebc8,2bda29c6,de3f6602,736c97c1), +S(f7c21813,63a5efb5,9c57da8f,eaef4738,38b9d34,8d3b16c3,ac28bc0e,b11c773a,9bd65899,bc4d15f8,875ceaf5,936ae25e,b4e9f,ce5963a,dc6095ac,5b867c17), +S(d407ed6d,b840bfc0,75c392a1,bd446340,9fb8f35d,80d9d4ae,95ea7bda,bb35e1ed,9f2af608,93692dc8,11330ac,35e317a1,fa856984,cc635354,43846545,5a9953d2), +S(32d706e,fa5382d3,ceaf0543,8e77971a,19e0e491,275d0381,ed705326,86f52376,66f4e0e7,1529c73f,aaffd9ac,a6846e3d,e2e8386a,939d02b0,7f64baa7,1d6c0f04), +S(ebe33ee5,f6baef23,ebfda782,e9ef55a6,d1b94e84,b76e7784,6d2827a7,82484a2c,27137340,2fcf2cf2,8ed164cd,7fedb8cc,178dc3f1,f02be690,ecb64938,cd942487), +S(5359d4ad,617f0a27,70392201,a2a1dbc7,fc5479c7,93be1cce,23b905e3,2751dd8,cbffabdc,ce183e6a,acbb21ea,86cd4fd8,97dd22c2,582f49b0,9f51e846,db2e8b2a), +S(92f718f3,8d2c428d,cb9dcf3c,847375e8,7f53d165,45a89dfd,629516c7,e5efa5bd,ca140596,6d82382a,453a5a4a,98ac315c,4351a4d8,5518af2b,996a0b3c,55edb05b), +S(70ec6cac,37a78311,8394e3a7,5a0756c2,117b8eb2,bf330440,ff6cd5fd,854df5ea,a1c909da,7c0cb4d4,141334f4,2a819c39,30af0877,8b4ea63e,601e3356,5d0bd54d), +S(72a4c06d,21fc5b6e,978addb3,95c1da3d,7c6390f,98f0abf9,26770ea6,d33c24cf,e811ff7f,ccf7f961,3c16b50,f74ce397,ec1c3e4a,877dd71b,b15cda1,c3027159), +S(ca5a0a96,e40e0530,344b532c,be4fcc47,2d243192,4c19019c,c602a6a4,45148259,b3274b9e,f30bc965,eb518686,3bdea539,130657,8199d2b0,4c56558c,a1bc19a2), +S(50e52b93,574a12e5,1f8c562c,2d335c54,4aa6edd,b3a83c4f,95ae5509,80b76261,dc5c4d8e,ac4d34c2,71af7d5b,abd714b5,194441d,72fefa4e,d1b4ac42,6e44d477), +S(e5ca0666,86f060f7,7c1d869a,94f02407,962cb101,1bdbb6cd,dad786fa,15761a6e,4ee18b3,7b15138b,61618a3,a7632c68,4f31cea,4d0c59f8,a6ce82a5,2c5480fb), +S(73560753,377906d5,9ac8c104,57742dc6,2d37b454,658d90ff,a4cfcbe8,f0e311d2,35ece58c,a5c7e200,47f80080,28fcacd8,2c8254fd,99fb392,f8e3b96e,31f40e4b), +S(a419a2e1,362adc6a,6fa18354,dcdd0cdb,37a4f8f9,bd1347b6,8763276f,b7acea19,c10fd807,3afc6f05,a2775e52,5d880417,f1c684e8,6dae0e35,9e600cf,9a6fd02f), +S(64a26b02,59fdc9f8,86ce26ac,cd826316,95eaaa3e,d95f9504,93c00505,ab149aa2,b03fca02,6b90848,965de8c4,6adadb8a,ff41f633,6c4af3b8,2a064880,f455b07b), +S(a8db77bb,4528572b,1630adce,107c8cd2,a296783a,acfbd84b,8cce742b,2c519e56,fa81ec4,7565b607,39dc4769,39624240,725afb64,df8ad9e2,70291dc6,acd1b19c), +S(95d43497,c9e2f1ae,4ecf2a6e,7839ed5f,135ca565,909fae2a,9590ffd4,2137e772,7977da8c,7d6d8880,d5c6a7ac,56b1ab4a,12d101f4,a26bc594,3c1ec394,5e085b7d), +S(184ad7a,9d1f54be,ae9bacd0,30707699,16e4158f,f1c7a9a3,e7303f38,53011793,7731244,6ceed0fa,3a832731,b477db26,743ccf3c,f3d8c09c,242c3327,6c67e3e7), +S(2f0ae3fe,5aa29a17,3a2718a1,91171d8a,7d33d2ee,6cc201de,4afbb00b,62db95e2,90f37a42,efb5787,6ed382cc,3a243179,4860ffaa,848b6299,52c6ace3,7dce5f28), +S(aa487bf7,fd746413,60e46513,4dec0aee,84287354,a74600d,65d02102,8deec2e3,d5de9cff,94ba3830,ece6a020,e9bda5aa,d999e97,a0ab4a0f,27fec770,ac2231ce), +S(54551633,398a72f2,66754798,5d2cab2b,6a107d84,72f8c06f,a34ed482,3a2a133e,4c33cc27,c462a5f1,e02bde02,aabb69ea,7a6c258d,55c6ee2c,a7b573f2,a7d970bc), +S(3b28883a,7df3010c,90b8613f,1b7639f0,7d766ebf,e3c1a02d,3bb20c14,156747aa,a3b1af7b,b133f94d,d2f720d0,aae669e8,b0a1b6c6,c2e14b66,72383cad,c28dbc71), +S(b3910ffe,6c153fe7,59ac3097,fd1a3b12,181deaac,f2cc3310,c036ac54,ccaab3d7,e242b0f8,de758d5e,ffb5e824,9cda6202,3686bbfe,439bed7e,eeec0c88,5b7efada), +S(679c5fd0,ddb09e92,77bd7c4e,651c862b,4fc18991,3892a31,6d0ed64c,1b66a0bd,f3cf0bd5,7e4085ab,7dce51b1,479e4ebc,63efb364,d11902a1,5d84b89,5599eaa4), +S(978d478b,3ad85f55,4b19a2f9,22f57cde,3d235bc1,92511422,fee2ad13,82a79f9d,fe0acd64,df69cdd1,985021ee,135050ec,879ffc35,b14deaf6,ade2734f,91781de7), +S(7e683666,eefc660c,e4326801,2690fac,4b0e3812,7de197a2,ca46270b,cba20572,250becb5,eda33bbb,cfc594bd,3675a82e,d5eeb642,bf755d2a,9e137ae2,1bd218ba), +S(8b90f968,26c56532,990cc0e6,8aa007d7,4555d566,7be7f23a,306788d6,cad77664,bc021a57,8e37d617,4a8320e8,e7bf68,4841096f,e191588b,79219fc0,d2559f6b), +S(b4e60f20,b7c71a14,80710413,fe81fcc3,88e83167,2183c36b,71185522,112f854f,d12ced59,7834d01,70a69bef,fb516ae3,4c67fea9,573bbe48,b3c2cc7d,edfbf0ad), +S(47d28ba0,3be64972,b30e7cb2,d4193440,bd4efc5,17194eca,2ef59cd1,78c6429d,304390c2,7a550fe6,23c9d6d1,465241d9,5827362d,ddaff80d,26ab1bf,9e32cc43), +S(2441a57c,1b9cea4e,28076f12,7fac389a,1068247b,56a1a4d7,7a2d5c1c,5945dad5,ff976ebd,3df8763d,aae65b64,c579408d,96b51a6e,9b3a85b4,401c25d8,fc9263fb), +S(3d69b290,d22112aa,ac7e2e7a,ded5cd9d,80754cd3,20831381,6e3840ae,d986ba78,bf7a0570,53ea3a3a,f27a866a,f0920ab,47f72d5a,f9859c31,6239aebb,d8d4ebf4), +S(2ec76c7e,3d684284,902f1725,54eb3dd2,b0c4304,4807a25b,472febf6,e9e6d1b4,97112d42,6850ee23,e57ae095,2565ee23,66c04ac1,6a388a44,14264767,20e38ac4), +S(972cb83c,80859ff8,96b0a318,a3a25386,3b6c99a0,49faca99,d36d5150,36da0e60,9668359c,953d20b6,e1873041,f0aea3c4,8e5a1d43,e4abab48,c0eaa391,8f7d8e98), +S(dfa2ccc6,9cb6c27f,6c072fc8,bc875c5b,e716c701,81b451f7,a85735ba,29363243,6342e27b,f9dff0e1,48fce3b0,1f9e569f,6af4a97f,b434725f,feff488c,501a7b4c), +S(3ee11d8d,8a46cdb3,8af24cd,f5f23f6d,2f18bc60,9f89fe14,ca0326a6,2a75c4f6,41ec4c72,ae99670f,2c5a4d8e,f0b2b211,fd3ea5fd,33b9158e,383c3ac2,d5c759cc), +S(bdc7399e,a6415348,77c66ce9,c62c1a96,7dfb72ec,6ef61c,e50dc71c,cdb3df96,90bddf9d,21aa5a98,8737c202,f89213d5,dd43c352,90a5cc96,40653be2,813f3f26), +S(d170eb03,dfad39f5,2e72298b,881e7c40,df9c4ee0,94cf092,25ef7b25,4250ac25,c9b3b36,937a83dc,c0592f27,202db5ae,9868f917,e6155e55,c9e0b3dd,8daa9085), +S(7153994,4971899a,8eff44c9,f38d4dba,e9315f,abff6106,a74231d9,97d4c66d,a95c07cc,e5d41397,7bdec5d3,bcbeb106,9dd90aea,ec57b911,3c6e3a69,baba78b6), +S(516ebb6c,f30e37d3,25bd8a77,f99e32eb,f2a84716,45bdc04b,a39b514d,268e9927,72504ee6,53710799,f5295c69,c022854f,b6ea6ff1,576c667,ab936d66,e651d103), +S(9de88063,6bcab6db,c7967dca,ce14949b,75529de1,73b46fc0,37a8c450,d5686d29,399f8480,c0f68bde,64ccd187,f247e09,30cc258,69e4779b,868d0af6,1e2dd1d5), +S(3a59c31f,dfae0e1b,a9b83db5,6f1fc0f6,51a0f9ca,8dc49c15,6e8d4ba4,a3ecd58b,a0513e83,600b57ce,3f87c762,6c0092d8,f88e0b4d,4b45a291,61abcd83,d2e93bc), +S(f533472b,fed40d17,566587fe,6f9e3c7e,3a657962,acb80e5b,319003c8,9b0b16f2,2fcf2b72,102dcb28,b36d8014,ee850bf5,9700d4d4,ae07769a,61bc0730,6a92304), +S(31b9170a,cefb23e2,330495da,dcc8729e,ce63a807,7406c4f4,de3d118d,1b759abc,111324ec,fdd8522c,64c0ba5b,a73cb848,9f1e77e8,d19c9731,dcfc59d2,26a88f41), +S(17ea4c86,6e3293d6,6cb535f2,db4ec265,331a4881,a9eb9941,2064ee60,38c3f8fe,a88536de,8cbec45,3d6fdcf4,3e3b5771,25ab4791,e2f318f2,c7572b19,7f3f02de), +S(f7a2f7a4,9462978,6f82557a,ec27a021,21995935,d5ac4adf,804b28bb,36ae5086,8a7ed1fa,60125463,96e3a50a,5616c515,3c5b6676,92bae5ea,f418bb57,8c4f42cc), +S(4a6b83ac,11a8d30f,c2bc4ccb,71b312ac,9ce05d77,3ca4a971,2f45f16c,c4a36099,c198732c,fbdaf72b,2c0471ab,5b4e2ac1,16d62e15,c5cf3bdd,c7fc2377,1db156ef), +S(d61e0f2b,757b2147,36f69e8,80f7882,26796f21,34c8ac39,7f023f60,9a222df6,dc369e3b,a99264d8,1041e2f5,decb93d8,7f3ddc5d,ebdad99a,1993e432,f92326ab), +S(ffc48a38,3faa0772,995f2074,4329141,1ded8a68,69f54f9a,53e14426,8d2d7788,edf446f2,660f6fe9,95129656,fafb76f,c1ef96fb,7227c4ac,8660cf16,867aec57), +S(986f203c,c3400685,610c83b4,fcf7a0da,636d92c4,f6f0bdb9,99b01321,ba47b952,7e152eec,4ea0a4d4,8f594801,40e5bfed,6539ddff,60646b86,ab463f9c,1c1cd72a), +S(e078d96e,97b33ea7,bf1a118d,8e45104b,18da1b7a,f799b5c2,2fc95db0,869a4b56,500aea63,487620e2,1c89ac2e,187eb32b,5567f715,2a090d9e,8e493190,c0b904c4), +S(a0b76ce8,3dfbfa5b,9ffbed50,736a676a,8e3e58df,aa3684b,68943ba3,f89d0ee5,5087ed66,33d4eafa,d7f962ee,11844da6,6e152831,8d780d83,5a9e7341,77c2551), +S(e6137a2e,1c22146a,81b622c8,947ebd54,5ee49505,e7343d6b,434ae440,f74deccf,b9598911,43813abd,14323cf8,fd880dbc,bb4ac611,e961c461,94d0f78a,1118b35), +S(bc966ce,8e2d896d,454cf19f,8126bd2,fd21f912,9e0c5b56,3afc6483,d5a8de1a,d7391926,bbf51367,c0d84d14,9fda784d,4f5e4db1,a4a71868,e8dc9968,ad27cd7a), +S(4fed3ecb,7303d658,48260222,6bb94148,b56a753b,902c3655,47db1db9,9b355624,87d3c83b,c4336625,4ddddcc1,a380b9a6,a7796f7e,6da00426,5c067f85,7c446b5f), +S(53151e3e,793f7ef9,a75180c4,ec3106ab,af3452f5,1a8c5301,1607ef98,3fb208b2,ba84da4a,dd761991,f375cfe5,146ba47e,d79e8983,8ab1e71b,737ea419,7aad93c), +S(f1ea6a7a,1595f99f,187287e1,2ca4cebd,8268da53,17c9deda,31c9c828,c91ba210,77d27512,38290ab7,4a75d9e1,63238537,555b51be,c0644f11,9409c1c1,7895c2ca), +S(4ce24395,80fa27b7,3a3bbed7,379b19d9,4c59e23b,1d482237,3de48d84,1e7650e8,258ae955,11a0890e,5912f651,f7705920,1971d6,82ea9abc,92d34888,f134aede), +S(20f5aca6,c33e91e5,97b66f07,30a7eaa9,4badf23a,b6f7653a,69f7a638,8ca20808,58642a87,964fd398,259037fc,c0c3e028,392eb7ff,15646480,1656cad8,7b6165f3), +S(5a84a300,9a7cb6a9,e86447b3,9d449bd8,3ce4e8a3,88395cc8,b851d961,df2bdca4,a724823c,bfa39a73,c02e8509,78d661d9,fc8dc8a1,e3a98c21,45448b2d,2c0d8d26), +S(4cc4b57,2e4cf18f,212315c4,65ed2464,b7850846,d64872ae,7b98d316,73853a6b,72594713,74be90df,fdccec2f,3a84b30f,74d6cbbf,fe966fd8,77de5b51,f9eeb409), +S(84aa8352,80aff2fc,b747f2d8,6e6d3f7b,5828ee7b,c0024d9,9b9a4998,fb809d48,a33e80be,b6131f8a,6ede3e5e,2bd265e8,5773a903,5912ac45,83cebc02,e0f70585), +S(4354311,ff6b6381,92ffa63f,a7a52fc6,cadcdd05,9adaafcb,7695686b,478dccdc,fa6b68e5,9d7f3aea,8d90d21a,ff26041b,68f68660,745bfee4,179d9e3a,2683f06e), +S(5be8ea1c,c7412e23,fe4a505f,aa15006c,ed823cb6,1853dde8,2e7af0a0,f06cc196,a2c76a9c,959b6b5e,d71dc83b,7a81e43c,a22a019b,8ecc54b0,eddfce5e,af9cbb45), +S(a69f7034,b680b802,189c6e8c,9cccd352,ce9ce14b,a50f9d41,a5991af3,e1822a07,df0cb8d6,86a38785,77235cd0,edf76b1c,9e902d2a,aac44b99,c916c3b5,848755b1), +S(f278be9f,11ce9c4d,2fc94317,98f3f552,b3f73bca,7da23757,93ea99ab,8aa0418d,8ec2cd50,6f3cadfe,2eea65a8,7cd8be99,a29d57c6,69482737,44e48289,d5eb283f), +S(28cf2333,17cd2dad,a4c83715,d0af39c2,cbdf7d98,7c90e1df,8709bdb8,929caf1e,a7905953,6c19b52a,459803cd,3a2ffb3d,d5597e5b,656c05bd,86d8e3ed,a9b7dc51), +S(45071195,99d6f85d,1e585fb8,2d4bf807,1b8ba01a,5487ef8a,b80d0508,2edc7b45,4951b428,1340ae42,1586824a,24933dcd,31a954,880d3c0,cc49864,72b6bfd0), +S(6df50945,4355e918,36a945ff,fdd68626,1b20f362,b1a7f601,9041506a,7cbade3f,38301bfc,e21d32db,83951120,954e9d56,179bf6d2,7fa3d5ab,7c37ef40,5245a031), +S(4db57458,b29c47ff,6f8b8ee5,12d897d6,36226380,4be13a48,6837f8e7,ebe147c5,e51039eb,7f9c8b93,3ad3c932,1b254cc9,f6221e35,13cba26b,a7c3e6ea,44f93ae6), +S(ad0ab782,d9a93270,b7083a32,b1913b7e,b0fb1947,9c8d8be5,ea74d0b,2590e087,50ecbadb,d801fdb6,5d40e84b,1511522b,3e603d06,5bf3a6a4,2b864558,c72c3fa4), +S(acab606b,aa8bc48,c452487c,700ddbc,daa04799,e9f57811,c47587c3,18d3900b,5be0eb5f,3f78292f,c248b704,f6cb2df1,891a05c7,822d9b47,35efd687,35b2e6c0), +S(16168437,b019abc,49fcab11,f7c0f2cd,14c2f784,dbfaeb40,f3790404,c4348d51,c68bc496,f40d5e97,4fdbaa51,dcf54ea,fb50abd,5ecb9f87,99bb3533,262ce86d), +S(5f03f4,a6cc9ad2,475d0f90,2090888c,31ae6eca,b08f7e4f,da8db504,876c8915,c918b3fa,1104d382,1d862299,17e0c5d5,cfbbf924,f69c24c9,d97b7091,157d7ed), +S(6da6938d,ef8b701,fcb228a3,c9066555,b4f7f0a3,297de3af,39d42897,5f0a27d0,f3ca7083,79910a1a,cdb94e7,9a7c8eab,e2c1b779,b749ad6a,fb4579b8,a3c56b6), +S(6b25cffd,587c71a9,3a736f8f,f5daeea0,26734350,fd158415,727fe6fc,6d309f86,dbf00735,d0c10049,27d582d3,8e61257a,770067fd,f9418dc6,73cf132a,c33f7b74), +S(7c48e557,27b1bed3,604cc3f6,7e47e24,b6f9b8a,7cd56cb9,f531ea5d,ef793f12,4d251353,73636962,126782f2,170cec17,e08483b,5b651f78,f0723da0,d6d4369f), +S(6769e622,cfbfe289,337de46f,4b6e1843,97fdc046,4560255d,9fc74c06,b00fc7a,523669ca,56e3e24f,b2490db3,6ea0bc33,6851041,d9146dac,1aace8c7,3a55e92b), +S(f83e990d,87486667,11214f8b,6a4643e1,901251c6,118d4d2b,a9087678,5313984b,b9decf7f,44c2cb00,d3d8858a,164a1,7ccbb6f9,5bbfa72d,6792ced0,4786a12a), +S(f3034416,5db59472,d7753efc,b55203b4,44b3a5f0,88825c4b,145d982b,38d369f3,3b765eb4,fae61edf,4a4c3b11,c71c5359,d8920eb,5cca2896,226e85ba,5932458c), +S(b2051f1c,5e6b22e7,d565ce94,bdd27c14,885322d0,e7bd3db9,eb13cdde,b26fd66a,b3245d05,2e93fc5,362d7e0a,4a4eebd9,ef8fd1d6,15c8a343,e308ef26,b9e331b6), +S(443958e8,fc9271a2,5215abbc,ad1bbcd1,887286ff,53d0d6e3,7803df80,f26094c7,3ae3f492,f51f287e,3f881bae,b16f4ca5,60583593,108053c9,352a48aa,95ceb545), +S(e8c5c31d,8e814515,b992ef4f,28bed3e3,ba6b2ffb,373a62d1,45976712,da8f5ad2,9d9e9d26,83c6b623,3d867d0e,727d00d7,fb5b7312,74d58bc3,b036b74f,8c22f676), +S(8b997cb4,8291df62,82ab7ac8,f6a917ec,330e76ee,4d21147e,ac15d3,2a9900ef,ba8e7e28,9bd40fc2,ee71f32e,48b1ab1f,1daf8c1e,6147cca2,a11befd7,e93b6920), +S(18ce6b3,126fd15d,29377619,4ad888c1,9355c739,7099d851,60111cd8,55199865,2f4ec4ea,4d215ec1,e102f7c9,ba9137da,5e75e00c,52b4d740,57bd37fa,61bcf038), +S(5b28c60f,a6c84a2b,dad6febd,f7cfc5c8,9fcf0e8f,d5cc8882,9540330b,8eaccc7,4d1c0d1,bb90266a,219592ae,ee619a4f,7b07c3a5,430ae20d,945f2121,2a652cdc), +S(5d4bf89d,fc3e8ac6,50f7c29f,6d878ce9,a1ba9cd9,d5970a58,ba7975ee,16496844,ee920d1d,8d7ee256,7f556433,90d0cf8,48458f75,f81b9f36,5c48dcdf,d60a96ab), +S(1fc5cd84,8a5680cd,76deb83c,f8ec6d99,db0e2fa3,7d7ac5bf,feb07fc0,ce0f0d9f,239f7252,18017a1c,d8419aa7,229eee96,37251ba3,a4a1eff4,9e42a29e,4f61eeb5), +S(e5a33510,603428c9,10cb5bd7,1da8bbca,3b50e97,46475a49,9d69b7df,badf601a,ee53e84a,a7e18842,a6879ba,ab59998f,62b6eac5,499230de,55a5c681,5d287a65), +S(c5ff6446,39c1772b,efe07d3,aad6dad0,5ba3074d,588d362a,6b5de6db,9d26707b,f11fe8bc,7f449e9,ecb22301,f131c6e9,7f4cbc52,af8fa880,6272705e,527a8e5f), +S(8246573e,b3ebc64a,c2118bce,9a275eef,6df0a34,61057e4c,a8836187,620041d0,fbe4a4c9,3bf019d3,2c2beaaa,ace3e4af,6c924195,8af4e387,d4ab3ef1,5146491c), +S(e9e9fd34,83b18055,cbbc8e33,cc6f3fc4,c507bb8a,84a09254,4822b44b,3d6a2910,45a4b02e,18da3327,80ab1f5c,37545bef,551c9a1,98616099,14bad711,1b4efd0d), +S(c3e53eb3,7d3a9fdb,bc2ab9c4,83656ff8,375bf18b,34aac991,ab5a6584,19d5f2a5,f95cb1ef,a793934a,2c1b0dc2,a0746974,75a29040,7f4413e7,449cb71a,af96225), +S(f54901b,fceceb3e,5beab5de,e9a93344,f354d956,5a989fd2,21cc8442,51944dab,57c0cb7d,8a79b236,608d7971,c1590672,8b5039ac,32db50f4,f50ca4fa,eabf3014), +S(d5cad259,e0716691,b5a1f8c5,970b4bf6,c7329aae,e4ab647f,daed2388,85b4fc55,4d944544,63cdfbd2,d769628e,bc60f501,ebf1d1ba,a1e4d68e,4a50e57,7afd7fa0), +S(fdfe1cc6,51fda605,d30582ae,d6d3e74e,855c278f,4151145,312f22e,ac142bbd,42f5dcb9,5772bf4d,4451614f,854f5ac5,e753533b,4d16e8a7,ee2a1adb,64df9029), +S(4db28db1,f69d04e3,27a438f6,199a5f98,292a6380,5e8b7edd,b36d341d,28d2e790,fafccf3c,394ad72d,40e938e2,5eb64079,f8617499,313241a4,99a840f8,733786dd), +S(1dffedf6,a430c31c,9875ea06,227583b,5e5160d0,b2d975b3,452a99ec,dea4d3d7,67bc0a31,ec97cb9b,fe191614,ded30a63,f77025cb,5cd7acc1,2e3d84fe,24b590b6), +S(41239a63,857928c3,e4d51a41,f77129a4,d60c7d44,9b6028d5,3b183efc,2452403a,8ac22f58,288c4a53,b6703f49,cff08a9e,39c16516,126b2803,9a0759f8,776ac785), +S(f2ecdfa9,adab5e32,eb7740b2,4eeb0fa2,649baced,1a69b03f,d47434a7,3d0c28e0,133952e0,ec187463,6d5f15f8,d2ab385d,aa58bade,36b9984c,ab94a591,70f2beb4), +S(7e74762d,c7c312a2,2fb7a48a,b9b393bb,7f540f7c,279eff83,c2170f2f,27132da3,9c7e6962,f6fd9cfb,a83a7b7a,85062f9d,add8a558,cc4cba51,d6079072,b7775daa), +S(613df89e,dc48052a,b497e0f9,571703f5,78e0ffcf,b116c162,277319b6,df774ffd,9cfa93b4,61200eef,c2e7855d,898a4198,52921aab,a30412f6,218095c9,4827d672), +S(caa6c1f6,c176e31c,a2baaf8f,39a1b5e0,c1c28443,ac8503d6,f4a55759,8e8180e,556a1519,73ece75,8e68d10b,151039a3,ed0521ca,c19281e0,255ec99b,10c21a26), +S(267f26da,2393ffe2,18f5c574,ad4fb6de,634ee94d,ee5ff952,10dd72b,1c550f5f,234fdc5,fd8e9412,650512c7,a510dd4d,f5ae9c88,83ecb1c2,edd2a3ec,d4bc3824), +S(8a26bd9a,b45c1aa0,772d794e,b088a941,2414b48c,82e2a118,23e869e8,3dea895,68ec5163,a955ab1,7c338a15,d2b66d36,5734f015,4e21e750,1387e978,452d9902), +S(29593a26,f0b9a728,c0248f06,4471e56e,4fc8d38,9823f7da,aff9e46d,81b9eae,710860e0,a9c98dd4,b1086e7d,2364be88,8741253c,9b8a7772,7b4ac275,53cf9b72), +S(5676cbf9,a0a41fb7,cbe1f3c0,a202bf7c,4458e938,964d903a,65325526,27454bd2,96cf5b8,1aa71fbf,f1f60e7a,2e4d28ee,ef7d0288,1b63d8fa,da9a10e7,8fdf7723), +S(6db9282,fe0ff035,b279a832,6f1c4f63,839a6c67,788e2e5,af7a4492,ecbcd9bc,4788671b,aae2f709,a2377b86,2c30af5c,49c721ee,fb2e3f91,20d49eac,821bbede), +S(db46b01b,c6047a92,e9e5c8b6,24f6aeab,16b213e7,91fdaade,8f045c55,d8de4275,9bd83ff8,31737782,21f161ef,ea079ea5,1e459023,445d8255,8e5f318e,949b52bb), +S(fa91fa0c,c71a2f21,38c61aeb,f451b435,1ae6a432,53a242e9,249727c,7c649ada,7c518caa,bf9fc9e2,c88a9ddb,712f32c,d8d04d7f,54dae53e,7dcc154d,e8826b33), +S(9752d6d9,e7dcc767,8bbce21a,5a7a3ea7,66d70518,fb59f435,eb6cd1a3,40f84dd8,9d1c48aa,2965ccfd,c03f5bfe,41a073b3,da6948b8,457e6e0d,c8a13de0,149a00f1), +S(ac9c0ed2,2e66bb0c,83ccb76f,62ee840b,5f2d6f5,568697e9,b0223009,63cf3c2e,37532994,58f79d71,df7d1b04,91523c98,9d30578b,706e3665,6c897fb1,1746c948), +S(71a9d71f,1f44b087,e02f7f28,5c47c947,f143d9d5,95e59dc9,64233226,d51c15f3,998119d9,7ad626e5,28e971bf,6ce85176,e3b9a095,1426f6d5,6ce8eaa2,81d6401d), +S(fbb85fdd,c4c25602,13ec981c,a40e69d5,6f3c6132,d1ffa38a,87b25c1e,87e40ecf,85882651,1c142a57,6bcf5f9b,1fbb0786,38511629,4c1c82a7,21e24bbd,16551bfb), +S(ad1fbec6,59b15b66,d34190c0,cc9165de,e48221d,eb1666e9,4d18042c,26db21e5,b579467e,d7d83215,c260dd2c,f089b2ce,513aa5ca,c9ac705e,e5841a65,8a583e18), +S(2af71297,ce1d4633,4ab66dee,42d005eb,845b927a,e6ae91ca,2fc8d414,58ceeb68,7477917c,5a456710,266815f4,39135116,69654290,36968cf8,e6983ee4,c508e605), +S(c0ae4daa,d71b2fce,d9c9b40,76be40e,a0cae11a,3d86ebe2,282f52d5,b86f39ec,61343833,f5d4ebf7,4445c133,37fef065,13fa3e0f,66cc7937,698b0cb6,9225fc9c), +S(93178803,9a374b99,df4135a3,50e1be5a,efd2e73,fa9c050a,d0b48812,a654c529,1bc01acf,3bf8b64f,6ac15664,c163ebfa,4a1a6ce1,4f9d3a9f,6e5ccd45,beaba2ce), +S(25458ec3,e24ae756,51f84ef1,a2bf49f,c19e86c7,99022de6,b7b58933,82a0050b,eeb2e93a,e357cf8a,9afbb9b7,fc0e97de,d80876cd,f08ee79b,ac07324b,cd41463c), +S(136e031b,1ab7a45e,6b8c3b53,7a615fc3,9e89d81d,a822e60f,aca2a496,e651e974,4cf2e215,8bc5c677,60e7d9bd,e9a476d5,d44a1c98,804e2697,a28dd17b,d4f5fa10), +S(5fefc4b1,2a3caf6f,3d025f3c,3510085e,ecc1ed97,46ccc265,1167cb0f,7fcd1af2,5cf8288,30eb25ff,1ad53354,acc72f49,5eb558f4,776b219d,bdec8ae9,24b1f125), +S(807a0f68,dd6026b7,2116e606,90a39596,e8558ce1,d11ffc9b,dbf2c574,40b82c38,12a2f38d,c84c41e8,2526fe56,2b877aae,10f575de,7edfb5ce,25f6a93b,158535e7), +S(8579c776,ad8f4fa3,65bd4efe,cf0b66be,3cf33cd2,61efc2cb,387c9a13,13947c34,7d888de6,9403e15d,3489748f,5d85bf7e,fd8213b0,673403fc,28a3d7e5,c3559198), +S(7374f757,46d03189,46386205,bc5d222e,243034a,3e0d4566,48777a3e,9239dce0,396af260,b295933d,2b6ae205,6fe53231,7ffec745,c4c95621,c1588d68,c3fd3f75), +S(a076997a,d9c613d4,adad3eee,9cb00a08,dd747840,4fe33fa7,34dcf3b7,58e8670f,8eef221,804526da,bc1b88eb,4320ea86,8d36ba82,775d059a,dcc4017b,6356f60e), +S(88494285,1a2626c7,f52abe1f,b31f124d,6fe0563d,c962c35b,ac690b96,27fbc604,e0a56299,86cb2c2d,a790688b,c63542ab,7362969d,d40d9ce8,5ec09e87,672cfe35), +S(682bb535,2da425c,87a541b1,35925e63,a161a84c,30beff50,b1c34193,fce7a6d,cea25359,481132c9,e9792a9c,4beedca3,4d16c3f9,f46349b4,e9d6cda3,e55f9b6d), +S(f80aa12,f4fd2631,26e01c2a,2cb0f86e,4293d3b8,87fc954d,daeab57,cbbe18fd,f6a2f24e,458214d4,c07d9191,23f8b6e0,af62d656,6657ff2d,c9894fc6,11917100), +S(f077e470,ca971bfa,9c762c61,132f5dd5,53eba38c,9629a8a4,9fae5b00,a23334ba,8bebf838,df798f83,88200f99,cdbcac9,8495681a,e4debeec,3f5ea4a2,b07bd87c), +S(1cffbe02,6cd70d89,f27a9db5,284a94ce,c9705d06,72b64bda,89b3a23f,c8b4a098,ea668c0d,61b0307a,15a303c9,cdab0ace,2ce5f1ef,8772dfdc,85d936e2,57bfe49), +S(7694c9e6,c10ece3c,f7ca1bc5,aac059a8,32f541df,da8342b3,ae31ea66,35d3c5e2,98054fd,39bf818,91b0d50a,ebf214a1,23010078,e75b20dc,c6c6c768,493899ff), +S(54f25d1e,1de2c437,39bcd34c,8a7e7d9e,d322a6ef,bc025143,de17b95f,e5cbae3b,a0a13012,cdff3d30,6bd3e863,9b1156d1,17c1f74f,8be3d8c6,a3d7a77d,e20c3d30), +S(ec3ab50,419649d4,78592017,c539f924,122d8aa5,4104309f,fc213499,8b608cd3,9f147580,8523383c,83f75c37,4b802589,fb1b0f60,99f20cc6,3497979c,4e558b4d), +S(21db4eeb,7f414ad,d9d951f2,ea33b9dc,8ac6f752,5549c982,174a4742,7dc99145,b4cb3a0e,a408bb1d,31e946b1,f0a99344,b0f2fae0,183088a9,543bef43,61950b22), +S(9e76ef4d,aa872a56,514bf43b,767a4bec,59dd96ad,9c436e39,807a4e5b,ff7b96a,7245b4cc,a609a698,bb3c6ab3,78d5236d,aaa3d8a4,c8502f5f,83432d62,b46685b8), +S(ef1c1a18,9fff9518,b1b40bf8,1edf4505,6a46bd92,1bd93c3b,1291597c,1d50bf29,ccfa479e,cb5e2217,ee9d2af4,42cd873f,953ff640,4127f760,2cd465d1,6590f309), +S(2fc501dc,d994ee04,81f1603,78a056b4,44b211cc,85e23459,f9969f57,626b05f6,29385f01,6b4180a6,93533c57,63e33818,ffc4f63e,72f78174,91532bf6,89d3b847), +S(52fc0f14,ce831d5,85e242e0,8421d021,cb58ec34,1d3d718a,34764966,48017b80,ee55bc21,120709fa,67251940,2531b231,e9713263,b28f52c9,a294b32a,cd7b2a07), +S(86932072,532e1a89,80b5ea8d,896deb75,6ceb8a11,87affd5f,c5eac0a,8ab374e6,efa4d9fe,3cb01ae9,b685e938,1a7ed4ae,b673d6cf,3fd8b47a,d55b2b22,cfe771c0), +S(d5001bc,4888eb3a,28ff21c5,52fdcfb9,f64be472,d677500c,2c6ad71c,854731cd,20a40358,579069a6,b246ea31,3e58b5ec,6569ae72,ddc20a0a,5ad7bc14,70aac129), +S(197d8ed,db431380,ac8419bc,a9a415d0,c19ff38e,84145635,a50eb5f4,fc026731,137d9984,ec510a78,130587a,59a3091a,24581fe8,40f49bb4,aebbfa3,9367ccb6), +S(f0efe141,83441eb,acd172a9,5496b85b,648deef6,9dcbb653,be2993fc,ab70eae0,1df1c523,4433bc9,7050c858,f477652d,636edbe9,8b3f51ef,b1a2ec17,6a0ad6b7), +S(7657e05b,c0659f26,2f2e86c7,73dd6dde,1e650064,5fad0165,4b52803d,c1c06599,26407f2f,a1c5c820,b729b9be,4a3c7c6e,b5c0ca46,f9c07d52,654bbd67,2a2d5f35), +S(6d037db3,bd776672,ab096fd6,e048768b,3acb7e5b,14cb4a77,ad8fa2cf,b67f7605,81d83989,87d95d38,5412e93d,43cd82e1,1060bfac,72d689c6,4d0572,7356db5), +S(16243eb9,d4eeb5ad,a68617e9,1dd8fd82,87db58ba,f7b65a40,db756936,54653ea5,fb3d260d,abd9a44d,e8795df0,cf9959d6,b94bbe4e,caf9c715,c4612c2a,4cea9615), +S(a59b5c4c,f732c9ef,f10b7ce,6e918562,d6082906,8509eef2,17c539a7,7601a48d,ae27b1d7,77021234,d703c423,cc7052b5,7f23388f,371d2a07,e0188630,ddbe4cb4), +S(33da8d1b,ba39bbc9,fdf39d17,1b8256f8,853da773,184d62e1,6d0d6ead,198b3cf,50bb1787,a917a656,622be1c6,1948adcb,1992153e,9b7725df,b93007db,7865719a), +S(4e5b40ec,c1dec23e,ffd4d2ed,4b3be8c1,b2a37ae9,e7d17d02,a00c046d,6173c48e,a68713c,3cefb9aa,559caa17,ff33b2e,476cee33,27dd5026,157ae77d,98bced0b), +S(86c5fb99,352060fd,2125290f,cc4625ca,2aabeda9,5470c14d,91afbe64,36511ae2,aa638940,d79a2237,c1cbc174,14ccee68,aa6dee00,c411dc3c,caf3b4e6,a24d5a24), +S(f3082a0,934921a7,6dc3d0fe,45d4badf,c0bb26d2,8b597a4b,bc7bb719,e43c5e7d,2f7a82ad,fd0099ee,3afbe9ca,a279ebbc,55841101,e1d2361c,1b7b4e81,98d78a90), +S(9eed2803,f83079db,90d50731,3fd889db,adf10be7,625a6455,709690fe,318df86d,1eba34d9,e0eb25b0,2494e3d4,14bbb963,69b6b6b0,f1ac8936,58170039,4ae254bb), +S(5045129,bafa3288,6d6678f8,eb0fa73,c182dc1c,ea039839,9e7eaf01,13d10432,f9290714,bb6972df,99d58a5a,50bab590,8c274310,1455d479,db9851a9,242c658b), +S(5083cdc1,1249ae24,4d1891a9,d74ee53b,90bb57e9,25fe26ac,32c364ee,99544031,ad385238,f304b7ec,6726ce24,9477326,15ec400c,c60069ef,cba2ffd1,c33ae39b), +S(6c1f547f,41bd9771,aa16cc9a,e19e5787,52e06b06,3d1aa740,dd219bd4,b8413ded,4e42a565,5169be0f,a65a471c,fd3fedac,58dea3aa,7cfc31b0,39902c6f,9938341), +S(bd455ad6,2c32f8e1,98f92a6e,ad5f8d1d,4ce6ab3b,57de4c76,d4a2557c,9d0cc2ca,ee672a2f,e514b76c,ad8af99e,20840aa0,231c423d,450451c2,66130160,a51db589), +S(3ef7949a,2f73d9eb,29390e2f,621cc651,54a31770,d49664bf,6602f8a5,3107df1d,faacb2a3,7050f0e7,d3d5e0be,edf3f658,ba30da79,df8fbc81,167bfee9,aece4f69), +S(8f45c59e,dbdd7f48,cdbb0fad,c2058ca1,b7007ba7,4ed1a121,4c6b562,7bcf6acf,357a629d,1e9800d5,c1f83981,81a39afd,56b1fdc8,9eec847d,a72fdb26,8d7fbcad), +S(3f7d488d,82c85663,b618af77,30a1b987,f662238d,9ce02ed7,f5160677,99ded34,c61323a6,bd1d8c43,506e24b7,e0635d72,e8eff076,db783b56,5f9424c6,8a1b53b4), +S(3700e5de,478887df,4f0819f0,86a2199a,a12d5925,f8e5c32b,c40738d2,edb329f8,8218c49a,3f40c04f,2a9ebf98,cdbb2d5e,1e9f2b51,5dbecc94,76f6e54f,26711232), +S(47ac5d4e,e3147cce,3d3e0c66,fb0c3a8e,a1d9c0fc,92dde919,7153ef9a,b4de1642,37b484b,4f0b4016,341a8b02,8136228b,6744ad3a,a871971c,6fb07a93,d16dbef5), +S(40cd13b1,6b0d24c6,d730c135,6ee2ba56,cfe6bcaa,d38ada27,230441ec,b50d5f81,31ed93d9,a98b6945,58c0130,b57c8c27,5caf386e,690cb1c,96b530ff,7a3ca4e2), +S(d491b581,10b6e137,57d20933,b356a977,51d3d03b,327354e9,aa1aee11,c8dfa15,85bcff81,4b5601dd,2eb27e1c,ff7d1489,93a98cea,9ec0553b,d14f108c,beabad07), +S(eabf656c,8b8e7de,a4a4ad70,d9a17911,d56891ef,7f6c32a,22078713,84f0b3f2,2ff10143,49e265ff,16619e7b,c7528fb9,9b3dbfce,e0c1e6b1,c30ec1be,47cf4e5b), +S(ed8abca4,ac4d7946,1ab4e3a5,5c05cea3,834381c,c7ec940e,c1b390c8,cce350d0,6b54dc69,86bc76fd,fef49c22,4b536795,2961b8f6,5ac6f552,73c4052b,dc8285da), +S(150968f6,3a67fde4,b4b404eb,866fd66b,50b822e,43f4e684,230cd720,e2e8e6d0,93e824ec,28bc5a84,f21b7717,d08ce64f,f5ede647,81538f4,a6f84332,4704c6e0), +S(83cab683,9ce8d260,7398446b,9c8f63d2,e4e1471a,f183f482,b22dc360,c59403f2,8f570cf4,391133d0,e31c363,84cf5195,f160ceea,b96e44,ba79893c,ddfaaa0d), +S(b3f062b0,189836e0,e9cc7acd,5c3c7810,bd287bdb,c0d64b4a,27202ea,f3a05b41,730f1110,ad1e7dc7,f6e1b84e,9a332c86,2003ec5c,f9e75835,97c07530,dcf9feb1), +S(7c226926,b567438e,cacc7662,2fa3f806,2888db46,f3e41649,d2bd5142,1a90f83e,563b94de,fa1719a2,b7f09c8e,5b31476d,8b8ee80e,9dfae6f6,aa0f6a6,45ecc33d), +S(b9416bdc,9862a2c2,cf1a50ce,132d07d2,8862f6dc,19e36f03,ad3100c9,659fcb99,5ee3e16a,5be0ad7,9c908fc5,f61c7024,678d2c93,47dd1c95,45734edf,e52fc618), +S(ece2cc3d,10edaa0d,4fe86a0f,b2d682c,aaf4d50,2913d942,8d704590,c2b3147e,5e79ac71,109cdd4d,12ff674e,b512cde,3a8004df,f2746165,e55233b6,2ea6fa07), +S(1dd18b36,369ddbc6,5a8d84a4,69262341,e6dc55dc,6362e7c3,5be5d5e6,ae72c0d5,4f7679d,e9ef807e,be2c1d39,163b7b17,1cfd22e2,6e4fb466,d8af03b7,1539ec98), +S(beefd37,fa712452,695bc66b,4fee98af,bd772c13,e63d0ca5,d62a7b0c,a8a2a3bc,caafe844,5be9307a,e872d297,991a9e42,7364ab4c,257168e5,660c5297,8a623aba), +S(d7f42137,7048d65e,39bb5032,ca991d91,184a98f5,4c35b3a3,73c118cc,d276d3cb,64e78d01,8e179101,41685830,dce8ab9,3285ebd3,ceb9817d,76edf7bc,524716d), +S(737fee9,6a6e5ae1,98bab025,2554e3f6,12517cf9,2614a503,4ab7b882,d97555bc,ac29b0c1,fb66bdac,a3ca5f19,3ac71997,87573d85,8353b9ac,c30ab147,bdf379bb), +S(784f4c1d,6a815b8c,6e429596,183e6e17,e846a50a,c65f0c0b,abd1d943,e115a307,ac5124ea,29517daf,782c5698,e5318d0a,fa0a05ca,d7a9d395,bd17c3c7,9c3a9972), +S(982794d0,a4430900,e6254f33,40924116,ec055a4c,8c0715f6,72af4cdd,e1bfeae0,90b9959c,3ad2170e,9bb70c1c,676ab6d2,584b97c3,855d9ec6,93307407,e57a3c7d), +S(7532737,c45039c,768b4cfb,71aed614,c8c8f977,70c94bb,1c8d5bd3,cd092d2a,b495750c,b0e5fd38,7f7f08cf,b5d2cf40,5f5c9a07,8184fdaa,5af78135,895be55d), +S(2900819a,badaa25b,5e79c9d5,7d35a079,4e587f3d,f75ca042,736969e6,a4db24ce,e7489b71,d1e8492d,66a1c6b0,dd23a453,12095649,b902f68,9789eac8,eec97435), +S(7c615aa5,b7134559,82fccde3,8c90d0ba,2d3a09f4,6bdbab02,4dd7b6a5,cc9fc205,4189a5c,d5830638,53569ebd,77855a63,f70229bc,f9322b2,2546df2e,e687cf50), +S(13749da6,79887b0a,d7e4f461,ae125385,c5126eb3,63d88327,6f0a4773,ee00193c,c2ee7f13,49def3cc,5d7963d9,2bee09d2,c36128ce,a5a0fbb6,964a0c14,a7644e92), +S(4ed1478a,b92b688e,aa491c7e,e3134ca9,7cc71cbc,3cb32ed4,a69c5b13,4e73b526,16f25a92,fb8e8042,ce2105de,e9133b82,3be2277e,66dfaa9b,368a2c5b,6b980a28), +S(f1efd577,6955489b,57759ad6,3c5cd042,383c1cf4,a1ea3719,8b1ad624,8d2649ed,909afd94,20027b64,aaeea435,25c77989,674411c9,14bcfbfb,7edc1055,e0b0ba6), +S(eec2b3d1,446835e2,ed2b9c32,80f320d5,296fae6a,fee19e4a,e38da171,6d0e35c7,a9f0beef,738d4ff8,f56bcb57,8bb509ba,8ef9e07e,3abe009a,9f0e1a7f,9d1609e7), +S(1d45c89f,fddd05a5,5043c44d,b8d0211a,f49f3aba,31e3ac62,5687413,4ecaa89,ab2abf54,db899f51,6c19848d,f0fb6e8e,9b43de72,3c74c33,9ac74611,7a64592c), +S(61531e01,5b2f0ca3,e36a20e6,b6d7f2ba,e2a1e245,340afb7,f134c3c8,799374ae,fae6274c,1e646987,2aa0b680,8a7fda0b,f3d495a1,24e859c0,2ac50be2,72dd4596), +S(a1b129b7,c1803643,6136bc8e,f7b99895,c5551ae4,71b2c0cc,ee48c266,bcdf2808,b9f97676,9623c4b0,bf10a738,6081cb23,f68693cd,626abaa6,b3874be2,5af886c8), +S(27e38dcd,d63bab65,c77eedfa,7e1f4b46,203ff350,20c86fb0,4ce2ffb8,af8d7056,81f30a56,7340be31,52ce5c6b,877f2c67,a7db7acc,7f24e13b,bf836660,9d61f04e), +S(64919bfc,50072a00,8769f559,3ad0e5b7,72ed6575,81ecf37c,8c759a3d,51149fc4,5759727c,20ae86e,b38aa3f,5e53b848,8ecd2b,477dca0a,ffb83903,65e70900), +S(d392e5cf,3c2d4a0a,20779b28,f4957800,ec7148aa,63b2bcb2,348afe9b,d28ad57d,54062719,a0ee0869,b1a99d9a,e4716487,70386747,9ead4774,66df29e1,78c87c6b), +S(6b9fe223,333b0802,34fb49d4,85218d11,9123c430,94e4ffba,38f33bb2,dbe7d9e2,5ea16bea,b5101109,4d34ec62,e6a63a71,c78de1f1,fcb7ce23,4ba2f51e,e4eb2ef1), +S(b1a505c,eb85f130,ef6e4a49,e429b0c5,51a87831,f850ed83,6bc8649d,6097ce12,a887e16a,805c0708,45589bff,2b22fc6f,4187cc06,cecef137,9130becb,5d5d149f), +S(8bd25993,c653b1e3,6f477988,61743aba,a5ffdaf,fd0890c3,caeb2963,736cbb44,341aef51,13b0d08d,90e90ffa,56570d57,5777260f,e85a15c2,2b5b3139,4f0a8c20), +S(2da121de,147507bd,b8836321,40394006,afc65465,7c6d4399,97cf6c88,ce0c4016,3ec87a24,eb19c502,848ff433,7ac3f48b,9a56ca56,3d0bffe8,eaa98e97,49f04aaa), +S(147541,9e9e9ff8,5b93f56,2832e74f,6c8c311a,676a759e,7dc62c63,5faa0b07,40fb95e4,810607ce,7ed10d9d,61404078,10ddbc55,261badc0,5e07bd1a,579ca271), +S(7c48371b,7eb5655f,b9d95bc3,5660d783,b1884573,d2934346,c5a5342b,a0949cb0,8b8cfb2,4cab96fa,1ee1e5d7,7dade5bd,23fa7868,445d9ad4,723529db,38110dae), +S(6ac2912f,d959d41c,19ff8ac4,bc136e85,91944b79,470d633f,b9fe65f0,f72541f4,63351f35,d4a7787a,31ef0bd6,f28aedd7,864ec5ab,7d841f11,9163e351,e070fcba), +S(db08e4fd,63e16bf6,abc05d78,be6bccc7,c9b8e15e,334ad697,9205a2e9,c2100e15,eeb0ba62,e1a5ee98,c2e2cc5a,8d9cbf11,d265019c,9eea8f50,4aa1e50,a422d4e), +S(4160dad,5255da89,12f69754,77b445a7,26fb7b8f,6ae8e2bb,d6276ae7,2a31afb8,ab0817bc,7a9b6907,9f6db9f3,c9a77718,23a1d79d,9f2739b2,cbeca18f,e5b8fbf8), +S(3794fc72,f432c983,2f9ba8dd,b46b1c64,d979e899,78b3c14f,2f903ec4,75af091e,a898cdf,7cdaf6c0,3715e38a,4bea1081,fda150b3,7faa4a11,ddbdc350,c7e0bb05), +S(244b87a4,fcecef37,76c16c5c,24c7785,be3b3c13,46595363,b8c066ec,45bfe561,9642f5fd,e0ec25ed,bd2129ca,6c023ec1,a2eadac7,f6ec5b7d,2b7fe894,41e5aa11), +S(9de52b81,157165cc,aef44485,4c2b3535,a599a79,80d024de,5334b385,ecbb2e91,74fca165,26fe2f87,a41ce510,4dd5634,5cf98c11,803c0392,3eb4b8b7,60240c02)} +#endif +}; +#undef S diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.h new file mode 100644 index 00000000..7256ad2e --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/precomputed_ecmult_gen.h @@ -0,0 +1,26 @@ +/********************************************************************************* + * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + *********************************************************************************/ + +#ifndef SECP256K1_PRECOMPUTED_ECMULT_GEN_H +#define SECP256K1_PRECOMPUTED_ECMULT_GEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "group.h" +#include "ecmult_gen.h" +#ifdef EXHAUSTIVE_TEST_ORDER +static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)]; +#else +extern const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)]; +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_PRECOMPUTED_ECMULT_GEN_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar.h new file mode 100644 index 00000000..aaaa3d88 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar.h @@ -0,0 +1,105 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_H +#define SECP256K1_SCALAR_H + +#include "util.h" + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low.h" +#elif defined(SECP256K1_WIDEMUL_INT128) +#include "scalar_4x64.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "scalar_8x32.h" +#else +#error "Please select wide multiplication implementation" +#endif + +/** Clear a scalar to prevent the leak of sensitive data. */ +static void secp256k1_scalar_clear(secp256k1_scalar *r); + +/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ +static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); + +/** Access bits from a scalar. Not constant time. */ +static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); + +/** Set a scalar from a big endian byte array. The scalar will be reduced modulo group order `n`. + * In: bin: pointer to a 32-byte array. + * Out: r: scalar to be set. + * overflow: non-zero if the scalar was bigger or equal to `n` before reduction, zero otherwise (can be NULL). + */ +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); + +/** Set a scalar from a big endian byte array and returns 1 if it is a valid + * seckey and 0 otherwise. */ +static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin); + +/** Set a scalar to an unsigned integer. */ +static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); + +/** Convert a scalar to a byte array. */ +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); + +/** Add two scalars together (modulo the group order). Returns whether it overflowed. */ +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); + +/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); + +/** Multiply two scalars (modulo the group order). */ +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); + +/** Shift a scalar right by some amount strictly between 0 and 16, returning + * the low bits that were shifted off */ +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); + +/** Compute the inverse of a scalar (modulo the group order). */ +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); + +/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); + +/** Compute the complement of a scalar (modulo the group order). */ +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); + +/** Check whether a scalar equals zero. */ +static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); + +/** Check whether a scalar equals one. */ +static int secp256k1_scalar_is_one(const secp256k1_scalar *a); + +/** Check whether a scalar, considered as an nonnegative integer, is even. */ +static int secp256k1_scalar_is_even(const secp256k1_scalar *a); + +/** Check whether a scalar is higher than the group order divided by 2. */ +static int secp256k1_scalar_is_high(const secp256k1_scalar *a); + +/** Conditionally negate a number, in constant time. + * Returns -1 if the number was negated, 1 otherwise */ +static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); + +/** Compare two scalars. */ +static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); + +/** Find r1 and r2 such that r1+r2*2^128 = k. */ +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k); +/** Find r1 and r2 such that r1+r2*lambda = k, + * where r1 and r2 or their negations are maximum 128 bits long (see secp256k1_ge_mul_lambda). */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k); + +/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ +static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag); + +#endif /* SECP256K1_SCALAR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64.h new file mode 100644 index 00000000..70096429 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64.h @@ -0,0 +1,19 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef struct { + uint64_t d[4]; +} secp256k1_scalar; + +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} + +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64_impl.h new file mode 100644 index 00000000..a1def26f --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_4x64_impl.h @@ -0,0 +1,868 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "modinv64_impl.h" + +/* Limbs of the secp256k1 order. */ +#define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) +#define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL) +#define SECP256K1_N_2 ((uint64_t)0xFFFFFFFFFFFFFFFEULL) +#define SECP256K1_N_3 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) + +/* Limbs of 2^256 minus the secp256k1 order. */ +#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) +#define SECP256K1_N_C_1 (~SECP256K1_N_1) +#define SECP256K1_N_C_2 (1) + +/* Limbs of half the secp256k1 order. */ +#define SECP256K1_N_H_0 ((uint64_t)0xDFE92F46681B20A0ULL) +#define SECP256K1_N_H_1 ((uint64_t)0x5D576E7357A4501DULL) +#define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) +#define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL) + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { + r->d[0] = 0; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { + r->d[0] = v; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); + return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK(count < 32); + VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 6 == offset >> 6) { + return secp256k1_scalar_get_bits(a, offset, count); + } else { + VERIFY_CHECK((offset >> 6) + 1 < 4); + return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1); + } +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { + int yes = 0; + int no = 0; + no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ + no |= (a->d[2] < SECP256K1_N_2); + yes |= (a->d[2] > SECP256K1_N_2) & ~no; + no |= (a->d[1] < SECP256K1_N_1); + yes |= (a->d[1] > SECP256K1_N_1) & ~no; + yes |= (a->d[0] >= SECP256K1_N_0) & ~no; + return yes; +} + +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) { + uint128_t t; + VERIFY_CHECK(overflow <= 1); + t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2; + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint64_t)r->d[3]; + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; + return overflow; +} + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + int overflow; + uint128_t t = (uint128_t)a->d[0] + b->d[0]; + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[1] + b->d[1]; + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[2] + b->d[2]; + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[3] + b->d[3]; + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + overflow = t + secp256k1_scalar_check_overflow(r); + VERIFY_CHECK(overflow == 0 || overflow == 1); + secp256k1_scalar_reduce(r, overflow); + return overflow; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + uint128_t t; + VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ + t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F)); + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F)); + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; +#ifdef VERIFY + VERIFY_CHECK((t >> 64) == 0); + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + int over; + r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; + r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; + r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; + r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; + over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + if (overflow) { + *overflow = over; + } +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; + bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; + bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; + bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0); + uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1; + r->d[0] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[1]) + SECP256K1_N_1; + r->d[1] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[2]) + SECP256K1_N_2; + r->d[2] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[3]) + SECP256K1_N_3; + r->d[3] = t & nonzero; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + int yes = 0; + int no = 0; + no |= (a->d[3] < SECP256K1_N_H_3); + yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; + no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */ + no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; + yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; + return yes; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint64_t mask = !flag - 1; + uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1; + uint128_t t = (uint128_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; + return 2 * (mask == 0) - 1; +} + +/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ + +/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd(a,b) { \ + uint64_t tl, th; \ + { \ + uint128_t t = (uint128_t)a * b; \ + th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl); /* at most 0xFFFFFFFFFFFFFFFF */ \ + c1 += th; /* overflow is handled on the next line */ \ + c2 += (c1 < th); /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ +} + +/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ +#define muladd_fast(a,b) { \ + uint64_t tl, th; \ + { \ + uint128_t t = (uint128_t)a * b; \ + th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl); /* at most 0xFFFFFFFFFFFFFFFF */ \ + c1 += th; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK(c1 >= th); \ +} + +/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define sumadd(a) { \ + unsigned int over; \ + c0 += (a); /* overflow is handled on the next line */ \ + over = (c0 < (a)); \ + c1 += over; /* overflow is handled on the next line */ \ + c2 += (c1 < over); /* never overflows by contract */ \ +} + +/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ +#define sumadd_fast(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + c1 += (c0 < (a)); /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ + VERIFY_CHECK(c2 == 0); \ +} + +/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. */ +#define extract(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ +} + +/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. c2 is required to be zero. */ +#define extract_fast(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = 0; \ + VERIFY_CHECK(c2 == 0); \ +} + +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) { +#ifdef USE_ASM_X86_64 + /* Reduce 512 bits into 385. */ + uint64_t m0, m1, m2, m3, m4, m5, m6; + uint64_t p0, p1, p2, p3, p4; + uint64_t c; + + __asm__ __volatile__( + /* Preload. */ + "movq 32(%%rsi), %%r11\n" + "movq 40(%%rsi), %%r12\n" + "movq 48(%%rsi), %%r13\n" + "movq 56(%%rsi), %%r14\n" + /* Initialize r8,r9,r10 */ + "movq 0(%%rsi), %%r8\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" + /* (r8,r9) += n0 * c0 */ + "movq %8, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* extract m0 */ + "movq %%r8, %q0\n" + "xorq %%r8, %%r8\n" + /* (r9,r10) += l1 */ + "addq 8(%%rsi), %%r9\n" + "adcq $0, %%r10\n" + /* (r9,r10,r8) += n1 * c0 */ + "movq %8, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += n0 * c1 */ + "movq %9, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* extract m1 */ + "movq %%r9, %q1\n" + "xorq %%r9, %%r9\n" + /* (r10,r8,r9) += l2 */ + "addq 16(%%rsi), %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n2 * c0 */ + "movq %8, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n1 * c1 */ + "movq %9, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += n0 */ + "addq %%r11, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* extract m2 */ + "movq %%r10, %q2\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += l3 */ + "addq 24(%%rsi), %%r8\n" + "adcq $0, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n3 * c0 */ + "movq %8, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n2 * c1 */ + "movq %9, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += n1 */ + "addq %%r12, %%r8\n" + "adcq $0, %%r9\n" + "adcq $0, %%r10\n" + /* extract m3 */ + "movq %%r8, %q3\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += n3 * c1 */ + "movq %9, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += n2 */ + "addq %%r13, %%r9\n" + "adcq $0, %%r10\n" + "adcq $0, %%r8\n" + /* extract m4 */ + "movq %%r9, %q4\n" + /* (r10,r8) += n3 */ + "addq %%r14, %%r10\n" + "adcq $0, %%r8\n" + /* extract m5 */ + "movq %%r10, %q5\n" + /* extract m6 */ + "movq %%r8, %q6\n" + : "=g"(m0), "=g"(m1), "=g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6) + : "S"(l), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc"); + + /* Reduce 385 bits into 258. */ + __asm__ __volatile__( + /* Preload */ + "movq %q9, %%r11\n" + "movq %q10, %%r12\n" + "movq %q11, %%r13\n" + /* Initialize (r8,r9,r10) */ + "movq %q5, %%r8\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" + /* (r8,r9) += m4 * c0 */ + "movq %12, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* extract p0 */ + "movq %%r8, %q0\n" + "xorq %%r8, %%r8\n" + /* (r9,r10) += m1 */ + "addq %q6, %%r9\n" + "adcq $0, %%r10\n" + /* (r9,r10,r8) += m5 * c0 */ + "movq %12, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += m4 * c1 */ + "movq %13, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* extract p1 */ + "movq %%r9, %q1\n" + "xorq %%r9, %%r9\n" + /* (r10,r8,r9) += m2 */ + "addq %q7, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m6 * c0 */ + "movq %12, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m5 * c1 */ + "movq %13, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += m4 */ + "addq %%r11, %%r10\n" + "adcq $0, %%r8\n" + "adcq $0, %%r9\n" + /* extract p2 */ + "movq %%r10, %q2\n" + /* (r8,r9) += m3 */ + "addq %q8, %%r8\n" + "adcq $0, %%r9\n" + /* (r8,r9) += m6 * c1 */ + "movq %13, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* (r8,r9) += m5 */ + "addq %%r12, %%r8\n" + "adcq $0, %%r9\n" + /* extract p3 */ + "movq %%r8, %q3\n" + /* (r9) += m6 */ + "addq %%r13, %%r9\n" + /* extract p4 */ + "movq %%r9, %q4\n" + : "=&g"(p0), "=&g"(p1), "=&g"(p2), "=g"(p3), "=g"(p4) + : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc"); + + /* Reduce 258 bits into 256. */ + __asm__ __volatile__( + /* Preload */ + "movq %q5, %%r10\n" + /* (rax,rdx) = p4 * c0 */ + "movq %7, %%rax\n" + "mulq %%r10\n" + /* (rax,rdx) += p0 */ + "addq %q1, %%rax\n" + "adcq $0, %%rdx\n" + /* extract r0 */ + "movq %%rax, 0(%q6)\n" + /* Move to (r8,r9) */ + "movq %%rdx, %%r8\n" + "xorq %%r9, %%r9\n" + /* (r8,r9) += p1 */ + "addq %q2, %%r8\n" + "adcq $0, %%r9\n" + /* (r8,r9) += p4 * c1 */ + "movq %8, %%rax\n" + "mulq %%r10\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + /* Extract r1 */ + "movq %%r8, 8(%q6)\n" + "xorq %%r8, %%r8\n" + /* (r9,r8) += p4 */ + "addq %%r10, %%r9\n" + "adcq $0, %%r8\n" + /* (r9,r8) += p2 */ + "addq %q3, %%r9\n" + "adcq $0, %%r8\n" + /* Extract r2 */ + "movq %%r9, 16(%q6)\n" + "xorq %%r9, %%r9\n" + /* (r8,r9) += p3 */ + "addq %q4, %%r8\n" + "adcq $0, %%r9\n" + /* Extract r3 */ + "movq %%r8, 24(%q6)\n" + /* Extract c */ + "movq %%r9, %q0\n" + : "=g"(c) + : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "i"(SECP256K1_N_C_0), "i"(SECP256K1_N_C_1) + : "rax", "rdx", "r8", "r9", "r10", "cc", "memory"); +#else + uint128_t c; + uint64_t c0, c1, c2; + uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; + uint64_t m0, m1, m2, m3, m4, m5; + uint32_t m6; + uint64_t p0, p1, p2, p3; + uint32_t p4; + + /* Reduce 512 bits into 385. */ + /* m[0..6] = l[0..3] + n[0..3] * SECP256K1_N_C. */ + c0 = l[0]; c1 = 0; c2 = 0; + muladd_fast(n0, SECP256K1_N_C_0); + extract_fast(m0); + sumadd_fast(l[1]); + muladd(n1, SECP256K1_N_C_0); + muladd(n0, SECP256K1_N_C_1); + extract(m1); + sumadd(l[2]); + muladd(n2, SECP256K1_N_C_0); + muladd(n1, SECP256K1_N_C_1); + sumadd(n0); + extract(m2); + sumadd(l[3]); + muladd(n3, SECP256K1_N_C_0); + muladd(n2, SECP256K1_N_C_1); + sumadd(n1); + extract(m3); + muladd(n3, SECP256K1_N_C_1); + sumadd(n2); + extract(m4); + sumadd_fast(n3); + extract_fast(m5); + VERIFY_CHECK(c0 <= 1); + m6 = c0; + + /* Reduce 385 bits into 258. */ + /* p[0..4] = m[0..3] + m[4..6] * SECP256K1_N_C. */ + c0 = m0; c1 = 0; c2 = 0; + muladd_fast(m4, SECP256K1_N_C_0); + extract_fast(p0); + sumadd_fast(m1); + muladd(m5, SECP256K1_N_C_0); + muladd(m4, SECP256K1_N_C_1); + extract(p1); + sumadd(m2); + muladd(m6, SECP256K1_N_C_0); + muladd(m5, SECP256K1_N_C_1); + sumadd(m4); + extract(p2); + sumadd_fast(m3); + muladd_fast(m6, SECP256K1_N_C_1); + sumadd_fast(m5); + extract_fast(p3); + p4 = c0 + m6; + VERIFY_CHECK(p4 <= 2); + + /* Reduce 258 bits into 256. */ + /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */ + c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; + r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p1 + (uint128_t)SECP256K1_N_C_1 * p4; + r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p2 + (uint128_t)p4; + r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p3; + r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; +#endif + + /* Final reduction of r. */ + secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); +} + +static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, const secp256k1_scalar *b) { +#ifdef USE_ASM_X86_64 + const uint64_t *pb = b->d; + __asm__ __volatile__( + /* Preload */ + "movq 0(%%rdi), %%r15\n" + "movq 8(%%rdi), %%rbx\n" + "movq 16(%%rdi), %%rcx\n" + "movq 0(%%rdx), %%r11\n" + "movq 8(%%rdx), %%r12\n" + "movq 16(%%rdx), %%r13\n" + "movq 24(%%rdx), %%r14\n" + /* (rax,rdx) = a0 * b0 */ + "movq %%r15, %%rax\n" + "mulq %%r11\n" + /* Extract l0 */ + "movq %%rax, 0(%%rsi)\n" + /* (r8,r9,r10) = (rdx) */ + "movq %%rdx, %%r8\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += a0 * b1 */ + "movq %%r15, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a1 * b0 */ + "movq %%rbx, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l1 */ + "movq %%r8, 8(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += a0 * b2 */ + "movq %%r15, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a1 * b1 */ + "movq %%rbx, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a2 * b0 */ + "movq %%rcx, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l2 */ + "movq %%r9, 16(%%rsi)\n" + "xorq %%r9, %%r9\n" + /* (r10,r8,r9) += a0 * b3 */ + "movq %%r15, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* Preload a3 */ + "movq 24(%%rdi), %%r15\n" + /* (r10,r8,r9) += a1 * b2 */ + "movq %%rbx, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += a2 * b1 */ + "movq %%rcx, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* (r10,r8,r9) += a3 * b0 */ + "movq %%r15, %%rax\n" + "mulq %%r11\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + "adcq $0, %%r9\n" + /* Extract l3 */ + "movq %%r10, 24(%%rsi)\n" + "xorq %%r10, %%r10\n" + /* (r8,r9,r10) += a1 * b3 */ + "movq %%rbx, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a2 * b2 */ + "movq %%rcx, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* (r8,r9,r10) += a3 * b1 */ + "movq %%r15, %%rax\n" + "mulq %%r12\n" + "addq %%rax, %%r8\n" + "adcq %%rdx, %%r9\n" + "adcq $0, %%r10\n" + /* Extract l4 */ + "movq %%r8, 32(%%rsi)\n" + "xorq %%r8, %%r8\n" + /* (r9,r10,r8) += a2 * b3 */ + "movq %%rcx, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* (r9,r10,r8) += a3 * b2 */ + "movq %%r15, %%rax\n" + "mulq %%r13\n" + "addq %%rax, %%r9\n" + "adcq %%rdx, %%r10\n" + "adcq $0, %%r8\n" + /* Extract l5 */ + "movq %%r9, 40(%%rsi)\n" + /* (r10,r8) += a3 * b3 */ + "movq %%r15, %%rax\n" + "mulq %%r14\n" + "addq %%rax, %%r10\n" + "adcq %%rdx, %%r8\n" + /* Extract l6 */ + "movq %%r10, 48(%%rsi)\n" + /* Extract l7 */ + "movq %%r8, 56(%%rsi)\n" + : "+d"(pb) + : "S"(l), "D"(a->d) + : "rax", "rbx", "rcx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory"); +#else + /* 160 bit accumulator. */ + uint64_t c0 = 0, c1 = 0; + uint32_t c2 = 0; + + /* l[0..7] = a[0..3] * b[0..3]. */ + muladd_fast(a->d[0], b->d[0]); + extract_fast(l[0]); + muladd(a->d[0], b->d[1]); + muladd(a->d[1], b->d[0]); + extract(l[1]); + muladd(a->d[0], b->d[2]); + muladd(a->d[1], b->d[1]); + muladd(a->d[2], b->d[0]); + extract(l[2]); + muladd(a->d[0], b->d[3]); + muladd(a->d[1], b->d[2]); + muladd(a->d[2], b->d[1]); + muladd(a->d[3], b->d[0]); + extract(l[3]); + muladd(a->d[1], b->d[3]); + muladd(a->d[2], b->d[2]); + muladd(a->d[3], b->d[1]); + extract(l[4]); + muladd(a->d[2], b->d[3]); + muladd(a->d[3], b->d[2]); + extract(l[5]); + muladd_fast(a->d[3], b->d[3]); + extract_fast(l[6]); + VERIFY_CHECK(c1 == 0); + l[7] = c0; +#endif +} + +#undef sumadd +#undef sumadd_fast +#undef muladd +#undef muladd_fast +#undef extract +#undef extract_fast + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + uint64_t l[8]; + secp256k1_scalar_mul_512(l, a, b); + secp256k1_scalar_reduce_512(r, l); +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n)); + r->d[3] = (r->d[3] >> n); + return ret; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + r1->d[0] = k->d[0]; + r1->d[1] = k->d[1]; + r1->d[2] = 0; + r1->d[3] = 0; + r2->d[0] = k->d[2]; + r2->d[1] = k->d[3]; + r2->d[2] = 0; + r2->d[3] = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { + uint64_t l[8]; + unsigned int shiftlimbs; + unsigned int shiftlow; + unsigned int shifthigh; + VERIFY_CHECK(shift >= 256); + secp256k1_scalar_mul_512(l, a, b); + shiftlimbs = shift >> 6; + shiftlow = shift & 0x3F; + shifthigh = 64 - shiftlow; + r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0; + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1); +} + +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint64_t mask0, mask1; + VG_CHECK_VERIFY(r->d, sizeof(r->d)); + mask0 = flag + ~((uint64_t)0); + mask1 = ~mask0; + r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); + r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); + r->d[2] = (r->d[2] & mask0) | (a->d[2] & mask1); + r->d[3] = (r->d[3] & mask0) | (a->d[3] & mask1); +} + +static void secp256k1_scalar_from_signed62(secp256k1_scalar *r, const secp256k1_modinv64_signed62 *a) { + const uint64_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4]; + + /* The output from secp256k1_modinv64{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^62). The modulus is < 2^256, so the top limb must be below 2^(256-62*4). + */ + VERIFY_CHECK(a0 >> 62 == 0); + VERIFY_CHECK(a1 >> 62 == 0); + VERIFY_CHECK(a2 >> 62 == 0); + VERIFY_CHECK(a3 >> 62 == 0); + VERIFY_CHECK(a4 >> 8 == 0); + + r->d[0] = a0 | a1 << 62; + r->d[1] = a1 >> 2 | a2 << 60; + r->d[2] = a2 >> 4 | a3 << 58; + r->d[3] = a3 >> 6 | a4 << 56; + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_scalar *a) { + const uint64_t M62 = UINT64_MAX >> 2; + const uint64_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3]; + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(a) == 0); +#endif + + r->v[0] = a0 & M62; + r->v[1] = (a0 >> 62 | a1 << 2) & M62; + r->v[2] = (a1 >> 60 | a2 << 4) & M62; + r->v[3] = (a2 >> 58 | a3 << 6) & M62; + r->v[4] = a3 >> 56; +} + +static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_scalar = { + {{0x3FD25E8CD0364141LL, 0x2ABB739ABD2280EELL, -0x15LL, 0, 256}}, + 0x34F20099AA774EC1LL +}; + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv64_signed62 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + secp256k1_scalar_to_signed62(&s, x); + secp256k1_modinv64(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed62(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +#endif +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv64_signed62 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + secp256k1_scalar_to_signed62(&s, x); + secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed62(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +#endif +} + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(a->d[0] & 1); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32.h new file mode 100644 index 00000000..17863ef9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32.h @@ -0,0 +1,19 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef struct { + uint32_t d[8]; +} secp256k1_scalar; + +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} + +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32_impl.h new file mode 100644 index 00000000..62c7ae71 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_8x32_impl.h @@ -0,0 +1,735 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "modinv32_impl.h" + +/* Limbs of the secp256k1 order. */ +#define SECP256K1_N_0 ((uint32_t)0xD0364141UL) +#define SECP256K1_N_1 ((uint32_t)0xBFD25E8CUL) +#define SECP256K1_N_2 ((uint32_t)0xAF48A03BUL) +#define SECP256K1_N_3 ((uint32_t)0xBAAEDCE6UL) +#define SECP256K1_N_4 ((uint32_t)0xFFFFFFFEUL) +#define SECP256K1_N_5 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_6 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_7 ((uint32_t)0xFFFFFFFFUL) + +/* Limbs of 2^256 minus the secp256k1 order. */ +#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) +#define SECP256K1_N_C_1 (~SECP256K1_N_1) +#define SECP256K1_N_C_2 (~SECP256K1_N_2) +#define SECP256K1_N_C_3 (~SECP256K1_N_3) +#define SECP256K1_N_C_4 (1) + +/* Limbs of half the secp256k1 order. */ +#define SECP256K1_N_H_0 ((uint32_t)0x681B20A0UL) +#define SECP256K1_N_H_1 ((uint32_t)0xDFE92F46UL) +#define SECP256K1_N_H_2 ((uint32_t)0x57A4501DUL) +#define SECP256K1_N_H_3 ((uint32_t)0x5D576E73UL) +#define SECP256K1_N_H_4 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_5 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { + r->d[0] = 0; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; + r->d[4] = 0; + r->d[5] = 0; + r->d[6] = 0; + r->d[7] = 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { + r->d[0] = v; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; + r->d[4] = 0; + r->d[5] = 0; + r->d[6] = 0; + r->d[7] = 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); + return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK(count < 32); + VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 5 == offset >> 5) { + return secp256k1_scalar_get_bits(a, offset, count); + } else { + VERIFY_CHECK((offset >> 5) + 1 < 8); + return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); + } +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { + int yes = 0; + int no = 0; + no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ + no |= (a->d[6] < SECP256K1_N_6); /* No need for a > check. */ + no |= (a->d[5] < SECP256K1_N_5); /* No need for a > check. */ + no |= (a->d[4] < SECP256K1_N_4); + yes |= (a->d[4] > SECP256K1_N_4) & ~no; + no |= (a->d[3] < SECP256K1_N_3) & ~yes; + yes |= (a->d[3] > SECP256K1_N_3) & ~no; + no |= (a->d[2] < SECP256K1_N_2) & ~yes; + yes |= (a->d[2] > SECP256K1_N_2) & ~no; + no |= (a->d[1] < SECP256K1_N_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_1) & ~no; + yes |= (a->d[0] >= SECP256K1_N_0) & ~no; + return yes; +} + +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { + uint64_t t; + VERIFY_CHECK(overflow <= 1); + t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; + r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; + r->d[1] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[2] + overflow * SECP256K1_N_C_2; + r->d[2] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[3] + overflow * SECP256K1_N_C_3; + r->d[3] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[4] + overflow * SECP256K1_N_C_4; + r->d[4] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[5]; + r->d[5] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[6]; + r->d[6] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[7]; + r->d[7] = t & 0xFFFFFFFFUL; + return overflow; +} + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + int overflow; + uint64_t t = (uint64_t)a->d[0] + b->d[0]; + r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[1] + b->d[1]; + r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[2] + b->d[2]; + r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[3] + b->d[3]; + r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[4] + b->d[4]; + r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[5] + b->d[5]; + r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[6] + b->d[6]; + r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[7] + b->d[7]; + r->d[7] = t & 0xFFFFFFFFULL; t >>= 32; + overflow = t + secp256k1_scalar_check_overflow(r); + VERIFY_CHECK(overflow == 0 || overflow == 1); + secp256k1_scalar_reduce(r, overflow); + return overflow; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + uint64_t t; + VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ + t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); + r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); + r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F)); + r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F)); + r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F)); + r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F)); + r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F)); + r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F)); + r->d[7] = t & 0xFFFFFFFFULL; +#ifdef VERIFY + VERIFY_CHECK((t >> 32) == 0); + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + int over; + r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; + r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; + r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; + r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24; + r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24; + r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; + r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; + r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; + over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + if (overflow) { + *overflow = over; + } +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; + bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; + bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; + bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4]; + bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3]; + bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2]; + bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1]; + bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); + uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; + r->d[0] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[1]) + SECP256K1_N_1; + r->d[1] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[2]) + SECP256K1_N_2; + r->d[2] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[3]) + SECP256K1_N_3; + r->d[3] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[4]) + SECP256K1_N_4; + r->d[4] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[5]) + SECP256K1_N_5; + r->d[5] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[6]) + SECP256K1_N_6; + r->d[6] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[7]) + SECP256K1_N_7; + r->d[7] = t & nonzero; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + int yes = 0; + int no = 0; + no |= (a->d[7] < SECP256K1_N_H_7); + yes |= (a->d[7] > SECP256K1_N_H_7) & ~no; + no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */ + no |= (a->d[5] < SECP256K1_N_H_5) & ~yes; /* No need for a > check. */ + no |= (a->d[4] < SECP256K1_N_H_4) & ~yes; /* No need for a > check. */ + no |= (a->d[3] < SECP256K1_N_H_3) & ~yes; + yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; + no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; + yes |= (a->d[2] > SECP256K1_N_H_2) & ~no; + no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; + yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; + return yes; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint32_t mask = !flag - 1; + uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); + uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask); + r->d[4] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask); + r->d[5] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask); + r->d[6] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); + r->d[7] = t & nonzero; + return 2 * (mask == 0) - 1; +} + + +/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ + +/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd(a,b) { \ + uint32_t tl, th; \ + { \ + uint64_t t = (uint64_t)a * b; \ + th = t >> 32; /* at most 0xFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl); /* at most 0xFFFFFFFF */ \ + c1 += th; /* overflow is handled on the next line */ \ + c2 += (c1 < th); /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ +} + +/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ +#define muladd_fast(a,b) { \ + uint32_t tl, th; \ + { \ + uint64_t t = (uint64_t)a * b; \ + th = t >> 32; /* at most 0xFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl); /* at most 0xFFFFFFFF */ \ + c1 += th; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK(c1 >= th); \ +} + +/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define sumadd(a) { \ + unsigned int over; \ + c0 += (a); /* overflow is handled on the next line */ \ + over = (c0 < (a)); \ + c1 += over; /* overflow is handled on the next line */ \ + c2 += (c1 < over); /* never overflows by contract */ \ +} + +/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ +#define sumadd_fast(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + c1 += (c0 < (a)); /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ + VERIFY_CHECK(c2 == 0); \ +} + +/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. */ +#define extract(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ +} + +/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. c2 is required to be zero. */ +#define extract_fast(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = 0; \ + VERIFY_CHECK(c2 == 0); \ +} + +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint32_t *l) { + uint64_t c; + uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; + uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; + uint32_t p0, p1, p2, p3, p4, p5, p6, p7, p8; + + /* 96 bit accumulator. */ + uint32_t c0, c1, c2; + + /* Reduce 512 bits into 385. */ + /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */ + c0 = l[0]; c1 = 0; c2 = 0; + muladd_fast(n0, SECP256K1_N_C_0); + extract_fast(m0); + sumadd_fast(l[1]); + muladd(n1, SECP256K1_N_C_0); + muladd(n0, SECP256K1_N_C_1); + extract(m1); + sumadd(l[2]); + muladd(n2, SECP256K1_N_C_0); + muladd(n1, SECP256K1_N_C_1); + muladd(n0, SECP256K1_N_C_2); + extract(m2); + sumadd(l[3]); + muladd(n3, SECP256K1_N_C_0); + muladd(n2, SECP256K1_N_C_1); + muladd(n1, SECP256K1_N_C_2); + muladd(n0, SECP256K1_N_C_3); + extract(m3); + sumadd(l[4]); + muladd(n4, SECP256K1_N_C_0); + muladd(n3, SECP256K1_N_C_1); + muladd(n2, SECP256K1_N_C_2); + muladd(n1, SECP256K1_N_C_3); + sumadd(n0); + extract(m4); + sumadd(l[5]); + muladd(n5, SECP256K1_N_C_0); + muladd(n4, SECP256K1_N_C_1); + muladd(n3, SECP256K1_N_C_2); + muladd(n2, SECP256K1_N_C_3); + sumadd(n1); + extract(m5); + sumadd(l[6]); + muladd(n6, SECP256K1_N_C_0); + muladd(n5, SECP256K1_N_C_1); + muladd(n4, SECP256K1_N_C_2); + muladd(n3, SECP256K1_N_C_3); + sumadd(n2); + extract(m6); + sumadd(l[7]); + muladd(n7, SECP256K1_N_C_0); + muladd(n6, SECP256K1_N_C_1); + muladd(n5, SECP256K1_N_C_2); + muladd(n4, SECP256K1_N_C_3); + sumadd(n3); + extract(m7); + muladd(n7, SECP256K1_N_C_1); + muladd(n6, SECP256K1_N_C_2); + muladd(n5, SECP256K1_N_C_3); + sumadd(n4); + extract(m8); + muladd(n7, SECP256K1_N_C_2); + muladd(n6, SECP256K1_N_C_3); + sumadd(n5); + extract(m9); + muladd(n7, SECP256K1_N_C_3); + sumadd(n6); + extract(m10); + sumadd_fast(n7); + extract_fast(m11); + VERIFY_CHECK(c0 <= 1); + m12 = c0; + + /* Reduce 385 bits into 258. */ + /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */ + c0 = m0; c1 = 0; c2 = 0; + muladd_fast(m8, SECP256K1_N_C_0); + extract_fast(p0); + sumadd_fast(m1); + muladd(m9, SECP256K1_N_C_0); + muladd(m8, SECP256K1_N_C_1); + extract(p1); + sumadd(m2); + muladd(m10, SECP256K1_N_C_0); + muladd(m9, SECP256K1_N_C_1); + muladd(m8, SECP256K1_N_C_2); + extract(p2); + sumadd(m3); + muladd(m11, SECP256K1_N_C_0); + muladd(m10, SECP256K1_N_C_1); + muladd(m9, SECP256K1_N_C_2); + muladd(m8, SECP256K1_N_C_3); + extract(p3); + sumadd(m4); + muladd(m12, SECP256K1_N_C_0); + muladd(m11, SECP256K1_N_C_1); + muladd(m10, SECP256K1_N_C_2); + muladd(m9, SECP256K1_N_C_3); + sumadd(m8); + extract(p4); + sumadd(m5); + muladd(m12, SECP256K1_N_C_1); + muladd(m11, SECP256K1_N_C_2); + muladd(m10, SECP256K1_N_C_3); + sumadd(m9); + extract(p5); + sumadd(m6); + muladd(m12, SECP256K1_N_C_2); + muladd(m11, SECP256K1_N_C_3); + sumadd(m10); + extract(p6); + sumadd_fast(m7); + muladd_fast(m12, SECP256K1_N_C_3); + sumadd_fast(m11); + extract_fast(p7); + p8 = c0 + m12; + VERIFY_CHECK(p8 <= 2); + + /* Reduce 258 bits into 256. */ + /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */ + c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; + r->d[0] = c & 0xFFFFFFFFUL; c >>= 32; + c += p1 + (uint64_t)SECP256K1_N_C_1 * p8; + r->d[1] = c & 0xFFFFFFFFUL; c >>= 32; + c += p2 + (uint64_t)SECP256K1_N_C_2 * p8; + r->d[2] = c & 0xFFFFFFFFUL; c >>= 32; + c += p3 + (uint64_t)SECP256K1_N_C_3 * p8; + r->d[3] = c & 0xFFFFFFFFUL; c >>= 32; + c += p4 + (uint64_t)p8; + r->d[4] = c & 0xFFFFFFFFUL; c >>= 32; + c += p5; + r->d[5] = c & 0xFFFFFFFFUL; c >>= 32; + c += p6; + r->d[6] = c & 0xFFFFFFFFUL; c >>= 32; + c += p7; + r->d[7] = c & 0xFFFFFFFFUL; c >>= 32; + + /* Final reduction of r. */ + secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); +} + +static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, const secp256k1_scalar *b) { + /* 96 bit accumulator. */ + uint32_t c0 = 0, c1 = 0, c2 = 0; + + /* l[0..15] = a[0..7] * b[0..7]. */ + muladd_fast(a->d[0], b->d[0]); + extract_fast(l[0]); + muladd(a->d[0], b->d[1]); + muladd(a->d[1], b->d[0]); + extract(l[1]); + muladd(a->d[0], b->d[2]); + muladd(a->d[1], b->d[1]); + muladd(a->d[2], b->d[0]); + extract(l[2]); + muladd(a->d[0], b->d[3]); + muladd(a->d[1], b->d[2]); + muladd(a->d[2], b->d[1]); + muladd(a->d[3], b->d[0]); + extract(l[3]); + muladd(a->d[0], b->d[4]); + muladd(a->d[1], b->d[3]); + muladd(a->d[2], b->d[2]); + muladd(a->d[3], b->d[1]); + muladd(a->d[4], b->d[0]); + extract(l[4]); + muladd(a->d[0], b->d[5]); + muladd(a->d[1], b->d[4]); + muladd(a->d[2], b->d[3]); + muladd(a->d[3], b->d[2]); + muladd(a->d[4], b->d[1]); + muladd(a->d[5], b->d[0]); + extract(l[5]); + muladd(a->d[0], b->d[6]); + muladd(a->d[1], b->d[5]); + muladd(a->d[2], b->d[4]); + muladd(a->d[3], b->d[3]); + muladd(a->d[4], b->d[2]); + muladd(a->d[5], b->d[1]); + muladd(a->d[6], b->d[0]); + extract(l[6]); + muladd(a->d[0], b->d[7]); + muladd(a->d[1], b->d[6]); + muladd(a->d[2], b->d[5]); + muladd(a->d[3], b->d[4]); + muladd(a->d[4], b->d[3]); + muladd(a->d[5], b->d[2]); + muladd(a->d[6], b->d[1]); + muladd(a->d[7], b->d[0]); + extract(l[7]); + muladd(a->d[1], b->d[7]); + muladd(a->d[2], b->d[6]); + muladd(a->d[3], b->d[5]); + muladd(a->d[4], b->d[4]); + muladd(a->d[5], b->d[3]); + muladd(a->d[6], b->d[2]); + muladd(a->d[7], b->d[1]); + extract(l[8]); + muladd(a->d[2], b->d[7]); + muladd(a->d[3], b->d[6]); + muladd(a->d[4], b->d[5]); + muladd(a->d[5], b->d[4]); + muladd(a->d[6], b->d[3]); + muladd(a->d[7], b->d[2]); + extract(l[9]); + muladd(a->d[3], b->d[7]); + muladd(a->d[4], b->d[6]); + muladd(a->d[5], b->d[5]); + muladd(a->d[6], b->d[4]); + muladd(a->d[7], b->d[3]); + extract(l[10]); + muladd(a->d[4], b->d[7]); + muladd(a->d[5], b->d[6]); + muladd(a->d[6], b->d[5]); + muladd(a->d[7], b->d[4]); + extract(l[11]); + muladd(a->d[5], b->d[7]); + muladd(a->d[6], b->d[6]); + muladd(a->d[7], b->d[5]); + extract(l[12]); + muladd(a->d[6], b->d[7]); + muladd(a->d[7], b->d[6]); + extract(l[13]); + muladd_fast(a->d[7], b->d[7]); + extract_fast(l[14]); + VERIFY_CHECK(c1 == 0); + l[15] = c0; +} + +#undef sumadd +#undef sumadd_fast +#undef muladd +#undef muladd_fast +#undef extract +#undef extract_fast + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + uint32_t l[16]; + secp256k1_scalar_mul_512(l, a, b); + secp256k1_scalar_reduce_512(r, l); +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); + r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); + r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); + r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); + r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); + r->d[7] = (r->d[7] >> n); + return ret; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + r1->d[0] = k->d[0]; + r1->d[1] = k->d[1]; + r1->d[2] = k->d[2]; + r1->d[3] = k->d[3]; + r1->d[4] = 0; + r1->d[5] = 0; + r1->d[6] = 0; + r1->d[7] = 0; + r2->d[0] = k->d[4]; + r2->d[1] = k->d[5]; + r2->d[2] = k->d[6]; + r2->d[3] = k->d[7]; + r2->d[4] = 0; + r2->d[5] = 0; + r2->d[6] = 0; + r2->d[7] = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { + uint32_t l[16]; + unsigned int shiftlimbs; + unsigned int shiftlow; + unsigned int shifthigh; + VERIFY_CHECK(shift >= 256); + secp256k1_scalar_mul_512(l, a, b); + shiftlimbs = shift >> 5; + shiftlow = shift & 0x1F; + shifthigh = 32 - shiftlow; + r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); +} + +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint32_t mask0, mask1; + VG_CHECK_VERIFY(r->d, sizeof(r->d)); + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; + r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); + r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); + r->d[2] = (r->d[2] & mask0) | (a->d[2] & mask1); + r->d[3] = (r->d[3] & mask0) | (a->d[3] & mask1); + r->d[4] = (r->d[4] & mask0) | (a->d[4] & mask1); + r->d[5] = (r->d[5] & mask0) | (a->d[5] & mask1); + r->d[6] = (r->d[6] & mask0) | (a->d[6] & mask1); + r->d[7] = (r->d[7] & mask0) | (a->d[7] & mask1); +} + +static void secp256k1_scalar_from_signed30(secp256k1_scalar *r, const secp256k1_modinv32_signed30 *a) { + const uint32_t a0 = a->v[0], a1 = a->v[1], a2 = a->v[2], a3 = a->v[3], a4 = a->v[4], + a5 = a->v[5], a6 = a->v[6], a7 = a->v[7], a8 = a->v[8]; + + /* The output from secp256k1_modinv32{_var} should be normalized to range [0,modulus), and + * have limbs in [0,2^30). The modulus is < 2^256, so the top limb must be below 2^(256-30*8). + */ + VERIFY_CHECK(a0 >> 30 == 0); + VERIFY_CHECK(a1 >> 30 == 0); + VERIFY_CHECK(a2 >> 30 == 0); + VERIFY_CHECK(a3 >> 30 == 0); + VERIFY_CHECK(a4 >> 30 == 0); + VERIFY_CHECK(a5 >> 30 == 0); + VERIFY_CHECK(a6 >> 30 == 0); + VERIFY_CHECK(a7 >> 30 == 0); + VERIFY_CHECK(a8 >> 16 == 0); + + r->d[0] = a0 | a1 << 30; + r->d[1] = a1 >> 2 | a2 << 28; + r->d[2] = a2 >> 4 | a3 << 26; + r->d[3] = a3 >> 6 | a4 << 24; + r->d[4] = a4 >> 8 | a5 << 22; + r->d[5] = a5 >> 10 | a6 << 20; + r->d[6] = a6 >> 12 | a7 << 18; + r->d[7] = a7 >> 14 | a8 << 16; + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_scalar *a) { + const uint32_t M30 = UINT32_MAX >> 2; + const uint32_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3], + a4 = a->d[4], a5 = a->d[5], a6 = a->d[6], a7 = a->d[7]; + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(a) == 0); +#endif + + r->v[0] = a0 & M30; + r->v[1] = (a0 >> 30 | a1 << 2) & M30; + r->v[2] = (a1 >> 28 | a2 << 4) & M30; + r->v[3] = (a2 >> 26 | a3 << 6) & M30; + r->v[4] = (a3 >> 24 | a4 << 8) & M30; + r->v[5] = (a4 >> 22 | a5 << 10) & M30; + r->v[6] = (a5 >> 20 | a6 << 12) & M30; + r->v[7] = (a6 >> 18 | a7 << 14) & M30; + r->v[8] = a7 >> 16; +} + +static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_scalar = { + {{0x10364141L, 0x3F497A33L, 0x348A03BBL, 0x2BB739ABL, -0x146L, 0, 0, 0, 65536}}, + 0x2A774EC1L +}; + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv32_signed30 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + secp256k1_scalar_to_signed30(&s, x); + secp256k1_modinv32(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed30(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +#endif +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_modinv32_signed30 s; +#ifdef VERIFY + int zero_in = secp256k1_scalar_is_zero(x); +#endif + secp256k1_scalar_to_signed30(&s, x); + secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_scalar); + secp256k1_scalar_from_signed30(r, &s); + +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in); +#endif +} + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(a->d[0] & 1); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_impl.h new file mode 100644 index 00000000..1b690e39 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_impl.h @@ -0,0 +1,297 @@ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_IMPL_H +#define SECP256K1_SCALAR_IMPL_H + +#ifdef VERIFY +#include +#endif + +#include "scalar.h" +#include "util.h" + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low_impl.h" +#elif defined(SECP256K1_WIDEMUL_INT128) +#include "scalar_4x64_impl.h" +#elif defined(SECP256K1_WIDEMUL_INT64) +#include "scalar_8x32_impl.h" +#else +#error "Please select wide multiplication implementation" +#endif + +static const secp256k1_scalar secp256k1_scalar_one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + +static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin) { + int overflow; + secp256k1_scalar_set_b32(r, bin, &overflow); + return (!overflow) & (!secp256k1_scalar_is_zero(r)); +} + +/* These parameters are generated using sage/gen_exhaustive_groups.sage. */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 13 +# define EXHAUSTIVE_TEST_LAMBDA 9 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define EXHAUSTIVE_TEST_LAMBDA 92 +# else +# error No known lambda for the specified exhaustive test group order. +# endif + +/** + * Find r1 and r2 given k, such that r1 + r2 * lambda == k mod n; unlike in the + * full case we don't bother making r1 and r2 be small, we just want them to be + * nontrivial to get full test coverage for the exhaustive tests. We therefore + * (arbitrarily) set r2 = k + 5 (mod n) and r1 = k - r2 * lambda (mod n). + */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + *r2 = (*k + 5) % EXHAUSTIVE_TEST_ORDER; + *r1 = (*k + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; +} +#else +/** + * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where + * lambda is: */ +static const secp256k1_scalar secp256k1_const_lambda = SECP256K1_SCALAR_CONST( + 0x5363AD4CUL, 0xC05C30E0UL, 0xA5261C02UL, 0x8812645AUL, + 0x122E22EAUL, 0x20816678UL, 0xDF02967CUL, 0x1B23BD72UL +); + +#ifdef VERIFY +static void secp256k1_scalar_split_lambda_verify(const secp256k1_scalar *r1, const secp256k1_scalar *r2, const secp256k1_scalar *k); +#endif + +/* + * Both lambda and beta are primitive cube roots of unity. That is lamba^3 == 1 mod n and + * beta^3 == 1 mod p, where n is the curve order and p is the field order. + * + * Furthermore, because (X^3 - 1) = (X - 1)(X^2 + X + 1), the primitive cube roots of unity are + * roots of X^2 + X + 1. Therefore lambda^2 + lamba == -1 mod n and beta^2 + beta == -1 mod p. + * (The other primitive cube roots of unity are lambda^2 and beta^2 respectively.) + * + * Let l = -1/2 + i*sqrt(3)/2, the complex root of X^2 + X + 1. We can define a ring + * homomorphism phi : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. The kernel of phi + * is a lattice over Z[l] (considering Z[l] as a Z-module). This lattice is generated by a + * reduced basis {a1 + b1*l, a2 + b2*l} where + * + * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} + * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} + * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * + * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm + * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 + * and k2 are small in absolute value. + * + * The algorithm computes c1 = round(b2 * k / n) and c2 = round((-b1) * k / n), and gives + * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and + * compute r2 = k2 mod n, and r1 = k1 mod n = (k - r2 * lambda) mod n, avoiding the need for + * the constants a1 and a2. + * + * g1, g2 are precomputed constants used to replace division with a rounded multiplication + * when decomposing the scalar for an endomorphism-based point multiplication. + * + * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve + * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. + * + * The derivation is described in the paper "Efficient Software Implementation of Public-Key + * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), + * Section 4.3 (here we use a somewhat higher-precision estimate): + * d = a1*b2 - b1*a2 + * g1 = round(2^384 * b2/d) + * g2 = round(2^384 * (-b1)/d) + * + * (Note that d is also equal to the curve order, n, here because [a1,b1] and [a2,b2] + * can be found as outputs of the Extended Euclidean Algorithm on inputs n and lambda). + * + * The function below splits k into r1 and r2, such that + * - r1 + lambda * r2 == k (mod n) + * - either r1 < 2^128 or -r1 mod n < 2^128 + * - either r2 < 2^128 or -r2 mod n < 2^128 + * + * See proof below. + */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) { + secp256k1_scalar c1, c2; + static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, + 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL + ); + static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, + 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL + ); + static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( + 0x3086D221UL, 0xA7D46BCDUL, 0xE86C90E4UL, 0x9284EB15UL, + 0x3DAA8A14UL, 0x71E8CA7FUL, 0xE893209AUL, 0x45DBB031UL + ); + static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( + 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C4UL, + 0x221208ACUL, 0x9DF506C6UL, 0x1571B4AEUL, 0x8AC47F71UL + ); + VERIFY_CHECK(r1 != k); + VERIFY_CHECK(r2 != k); + /* these _var calls are constant time since the shift amount is constant */ + secp256k1_scalar_mul_shift_var(&c1, k, &g1, 384); + secp256k1_scalar_mul_shift_var(&c2, k, &g2, 384); + secp256k1_scalar_mul(&c1, &c1, &minus_b1); + secp256k1_scalar_mul(&c2, &c2, &minus_b2); + secp256k1_scalar_add(r2, &c1, &c2); + secp256k1_scalar_mul(r1, r2, &secp256k1_const_lambda); + secp256k1_scalar_negate(r1, r1); + secp256k1_scalar_add(r1, r1, k); + +#ifdef VERIFY + secp256k1_scalar_split_lambda_verify(r1, r2, k); +#endif +} + +#ifdef VERIFY +/* + * Proof for secp256k1_scalar_split_lambda's bounds. + * + * Let + * - epsilon1 = 2^256 * |g1/2^384 - b2/d| + * - epsilon2 = 2^256 * |g2/2^384 - (-b1)/d| + * - c1 = round(k*g1/2^384) + * - c2 = round(k*g2/2^384) + * + * Lemma 1: |c1 - k*b2/d| < 2^-1 + epsilon1 + * + * |c1 - k*b2/d| + * = + * |c1 - k*g1/2^384 + k*g1/2^384 - k*b2/d| + * <= {triangle inequality} + * |c1 - k*g1/2^384| + |k*g1/2^384 - k*b2/d| + * = + * |c1 - k*g1/2^384| + k*|g1/2^384 - b2/d| + * < {rounding in c1 and 0 <= k < 2^256} + * 2^-1 + 2^256 * |g1/2^384 - b2/d| + * = {definition of epsilon1} + * 2^-1 + epsilon1 + * + * Lemma 2: |c2 - k*(-b1)/d| < 2^-1 + epsilon2 + * + * |c2 - k*(-b1)/d| + * = + * |c2 - k*g2/2^384 + k*g2/2^384 - k*(-b1)/d| + * <= {triangle inequality} + * |c2 - k*g2/2^384| + |k*g2/2^384 - k*(-b1)/d| + * = + * |c2 - k*g2/2^384| + k*|g2/2^384 - (-b1)/d| + * < {rounding in c2 and 0 <= k < 2^256} + * 2^-1 + 2^256 * |g2/2^384 - (-b1)/d| + * = {definition of epsilon2} + * 2^-1 + epsilon2 + * + * Let + * - k1 = k - c1*a1 - c2*a2 + * - k2 = - c1*b1 - c2*b2 + * + * Lemma 3: |k1| < (a1 + a2 + 1)/2 < 2^128 + * + * |k1| + * = {definition of k1} + * |k - c1*a1 - c2*a2| + * = {(a1*b2 - b1*a2)/n = 1} + * |k*(a1*b2 - b1*a2)/n - c1*a1 - c2*a2| + * = + * |a1*(k*b2/n - c1) + a2*(k*(-b1)/n - c2)| + * <= {triangle inequality} + * a1*|k*b2/n - c1| + a2*|k*(-b1)/n - c2| + * < {Lemma 1 and Lemma 2} + * a1*(2^-1 + epslion1) + a2*(2^-1 + epsilon2) + * < {rounding up to an integer} + * (a1 + a2 + 1)/2 + * < {rounding up to a power of 2} + * 2^128 + * + * Lemma 4: |k2| < (-b1 + b2)/2 + 1 < 2^128 + * + * |k2| + * = {definition of k2} + * |- c1*a1 - c2*a2| + * = {(b1*b2 - b1*b2)/n = 0} + * |k*(b1*b2 - b1*b2)/n - c1*b1 - c2*b2| + * = + * |b1*(k*b2/n - c1) + b2*(k*(-b1)/n - c2)| + * <= {triangle inequality} + * (-b1)*|k*b2/n - c1| + b2*|k*(-b1)/n - c2| + * < {Lemma 1 and Lemma 2} + * (-b1)*(2^-1 + epslion1) + b2*(2^-1 + epsilon2) + * < {rounding up to an integer} + * (-b1 + b2)/2 + 1 + * < {rounding up to a power of 2} + * 2^128 + * + * Let + * - r2 = k2 mod n + * - r1 = k - r2*lambda mod n. + * + * Notice that r1 is defined such that r1 + r2 * lambda == k (mod n). + * + * Lemma 5: r1 == k1 mod n. + * + * r1 + * == {definition of r1 and r2} + * k - k2*lambda + * == {definition of k2} + * k - (- c1*b1 - c2*b2)*lambda + * == + * k + c1*b1*lambda + c2*b2*lambda + * == {a1 + b1*lambda == 0 mod n and a2 + b2*lambda == 0 mod n} + * k - c1*a1 - c2*a2 + * == {definition of k1} + * k1 + * + * From Lemma 3, Lemma 4, Lemma 5 and the definition of r2, we can conclude that + * + * - either r1 < 2^128 or -r1 mod n < 2^128 + * - either r2 < 2^128 or -r2 mod n < 2^128. + * + * Q.E.D. + */ +static void secp256k1_scalar_split_lambda_verify(const secp256k1_scalar *r1, const secp256k1_scalar *r2, const secp256k1_scalar *k) { + secp256k1_scalar s; + unsigned char buf1[32]; + unsigned char buf2[32]; + + /* (a1 + a2 + 1)/2 is 0xa2a8918ca85bafe22016d0b917e4dd77 */ + static const unsigned char k1_bound[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa2, 0xa8, 0x91, 0x8c, 0xa8, 0x5b, 0xaf, 0xe2, 0x20, 0x16, 0xd0, 0xb9, 0x17, 0xe4, 0xdd, 0x77 + }; + + /* (-b1 + b2)/2 + 1 is 0x8a65287bd47179fb2be08846cea267ed */ + static const unsigned char k2_bound[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8a, 0x65, 0x28, 0x7b, 0xd4, 0x71, 0x79, 0xfb, 0x2b, 0xe0, 0x88, 0x46, 0xce, 0xa2, 0x67, 0xed + }; + + secp256k1_scalar_mul(&s, &secp256k1_const_lambda, r2); + secp256k1_scalar_add(&s, &s, r1); + VERIFY_CHECK(secp256k1_scalar_eq(&s, k)); + + secp256k1_scalar_negate(&s, r1); + secp256k1_scalar_get_b32(buf1, r1); + secp256k1_scalar_get_b32(buf2, &s); + VERIFY_CHECK(secp256k1_memcmp_var(buf1, k1_bound, 32) < 0 || secp256k1_memcmp_var(buf2, k1_bound, 32) < 0); + + secp256k1_scalar_negate(&s, r2); + secp256k1_scalar_get_b32(buf1, r2); + secp256k1_scalar_get_b32(buf2, &s); + VERIFY_CHECK(secp256k1_memcmp_var(buf1, k2_bound, 32) < 0 || secp256k1_memcmp_var(buf2, k2_bound, 32) < 0); +} +#endif /* VERIFY */ +#endif /* !defined(EXHAUSTIVE_TEST_ORDER) */ + +#endif /* SECP256K1_SCALAR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low.h new file mode 100644 index 00000000..67051bd3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low.h @@ -0,0 +1,17 @@ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef uint32_t secp256k1_scalar; + +#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) (d0) + +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low_impl.h new file mode 100644 index 00000000..7176f0b2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scalar_low_impl.h @@ -0,0 +1,139 @@ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "scalar.h" + +#include + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(*a & 1); +} + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + if (offset < 32) + return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); + else + return 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + return secp256k1_scalar_get_bits(a, offset, count); +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; + return *r < *b; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + if (flag && bit < 32) + *r += ((uint32_t)1 << bit); +#ifdef VERIFY + VERIFY_CHECK(bit < 32); + /* Verify that adding (1 << bit) will not overflow any in-range scalar *r by overflowing the underlying uint32_t. */ + VERIFY_CHECK(((uint32_t)1 << bit) - 1 <= UINT32_MAX - EXHAUSTIVE_TEST_ORDER); + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + int i; + int over = 0; + *r = 0; + for (i = 0; i < 32; i++) { + *r = (*r * 0x100) + b32[i]; + if (*r >= EXHAUSTIVE_TEST_ORDER) { + over = 1; + *r %= EXHAUSTIVE_TEST_ORDER; + } + } + if (overflow) *overflow = over; +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + memset(bin, 0, 32); + bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return *a == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + if (*a == 0) { + *r = 0; + } else { + *r = EXHAUSTIVE_TEST_ORDER - *a; + } +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return *a == 1; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + return *a > EXHAUSTIVE_TEST_ORDER / 2; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + if (flag) secp256k1_scalar_negate(r, r); + return flag ? -1 : 1; +} + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = *r & ((1 << n) - 1); + *r >>= n; + return ret; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r1 = *a; + *r2 = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return *a == *b; +} + +static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { + uint32_t mask0, mask1; + VG_CHECK_VERIFY(r, sizeof(*r)); + mask0 = flag + ~((uint32_t)0); + mask1 = ~mask0; + *r = (*r & mask0) | (*a & mask1); +} + +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + int i; + *r = 0; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) + *r = i; + /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus + * have a composite group order; fix it in exhaustive_tests.c). */ + VERIFY_CHECK(*r != 0); +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_scalar_inverse(r, x); +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch.h new file mode 100644 index 00000000..9dcb7581 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch.h @@ -0,0 +1,42 @@ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCRATCH_H +#define SECP256K1_SCRATCH_H + +/* The typedef is used internally; the struct name is used in the public API + * (where it is exposed as a different typedef) */ +typedef struct secp256k1_scratch_space_struct { + /** guard against interpreting this object as other types */ + unsigned char magic[8]; + /** actual allocated data */ + void *data; + /** amount that has been allocated (i.e. `data + offset` is the next + * available pointer) */ + size_t alloc_size; + /** maximum size available to allocate */ + size_t max_size; +} secp256k1_scratch; + +static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); + +static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch); + +/** Returns an opaque object used to "checkpoint" a scratch space. Used + * with `secp256k1_scratch_apply_checkpoint` to undo allocations. */ +static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch); + +/** Applies a check point received from `secp256k1_scratch_checkpoint`, + * undoing all allocations since that point. */ +static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint); + +/** Returns the maximum allocation the scratch space will allow */ +static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t n_objects); + +/** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ +static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t n); + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch_impl.h new file mode 100644 index 00000000..688e18eb --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/scratch_impl.h @@ -0,0 +1,99 @@ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCRATCH_IMPL_H +#define SECP256K1_SCRATCH_IMPL_H + +#include "util.h" +#include "scratch.h" + +static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) { + const size_t base_alloc = ROUND_TO_ALIGN(sizeof(secp256k1_scratch)); + void *alloc = checked_malloc(error_callback, base_alloc + size); + secp256k1_scratch* ret = (secp256k1_scratch *)alloc; + if (ret != NULL) { + memset(ret, 0, sizeof(*ret)); + memcpy(ret->magic, "scratch", 8); + ret->data = (void *) ((char *) alloc + base_alloc); + ret->max_size = size; + } + return ret; +} + +static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) { + if (scratch != NULL) { + VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return; + } + memset(scratch->magic, 0, sizeof(scratch->magic)); + free(scratch); + } +} + +static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return 0; + } + return scratch->alloc_size; +} + +static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return; + } + if (checkpoint > scratch->alloc_size) { + secp256k1_callback_call(error_callback, "invalid checkpoint"); + return; + } + scratch->alloc_size = checkpoint; +} + +static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) { + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return 0; + } + /* Ensure that multiplication will not wrap around */ + if (ALIGNMENT > 1 && objects > SIZE_MAX/(ALIGNMENT - 1)) { + return 0; + } + if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) { + return 0; + } + return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1); +} + +static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) { + void *ret; + size_t rounded_size; + + rounded_size = ROUND_TO_ALIGN(size); + /* Check that rounding did not wrap around */ + if (rounded_size < size) { + return NULL; + } + size = rounded_size; + + if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { + secp256k1_callback_call(error_callback, "invalid scratch space"); + return NULL; + } + + if (size > scratch->max_size - scratch->alloc_size) { + return NULL; + } + ret = (void *) ((char *) scratch->data + scratch->alloc_size); + memset(ret, 0, size); + scratch->alloc_size += size; + + return ret; +} + +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/secp256k1.c b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/secp256k1.c new file mode 100644 index 00000000..af1d7e19 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/secp256k1.c @@ -0,0 +1,788 @@ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#define SECP256K1_BUILD + +#include "../include/secp256k1.h" +#include "../include/secp256k1_preallocated.h" + +#include "assumptions.h" +#include "util.h" +#include "field_impl.h" +#include "scalar_impl.h" +#include "group_impl.h" +#include "ecmult_impl.h" +#include "ecmult_const_impl.h" +#include "ecmult_gen_impl.h" +#include "ecdsa_impl.h" +#include "eckey_impl.h" +#include "hash_impl.h" +#include "scratch_impl.h" +#include "selftest.h" + +#ifdef SECP256K1_NO_BUILD +# error "secp256k1.h processed without SECP256K1_BUILD defined while building secp256k1.c" +#endif + +#if defined(VALGRIND) +# include +#endif + +#define ARG_CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + return 0; \ + } \ +} while(0) + +#define ARG_CHECK_NO_RETURN(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + } \ +} while(0) + +struct secp256k1_context_struct { + secp256k1_ecmult_gen_context ecmult_gen_ctx; + secp256k1_callback illegal_callback; + secp256k1_callback error_callback; + int declassify; +}; + +static const secp256k1_context secp256k1_context_no_precomp_ = { + { 0 }, + { secp256k1_default_illegal_callback_fn, 0 }, + { secp256k1_default_error_callback_fn, 0 }, + 0 +}; +const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_no_precomp_; + +size_t secp256k1_context_preallocated_size(unsigned int flags) { + size_t ret = sizeof(secp256k1_context); + /* A return value of 0 is reserved as an indicator for errors when we call this function internally. */ + VERIFY_CHECK(ret != 0); + + if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { + secp256k1_callback_call(&default_illegal_callback, + "Invalid flags"); + return 0; + } + + return ret; +} + +size_t secp256k1_context_preallocated_clone_size(const secp256k1_context* ctx) { + size_t ret = sizeof(secp256k1_context); + VERIFY_CHECK(ctx != NULL); + return ret; +} + +secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigned int flags) { + size_t prealloc_size; + secp256k1_context* ret; + + if (!secp256k1_selftest()) { + secp256k1_callback_call(&default_error_callback, "self test failed"); + } + + prealloc_size = secp256k1_context_preallocated_size(flags); + if (prealloc_size == 0) { + return NULL; + } + VERIFY_CHECK(prealloc != NULL); + ret = (secp256k1_context*)prealloc; + ret->illegal_callback = default_illegal_callback; + ret->error_callback = default_error_callback; + + /* Flags have been checked by secp256k1_context_preallocated_size. */ + VERIFY_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_CONTEXT); + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); + ret->declassify = !!(flags & SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY); + + return ret; +} + +secp256k1_context* secp256k1_context_create(unsigned int flags) { + size_t const prealloc_size = secp256k1_context_preallocated_size(flags); + secp256k1_context* ctx = (secp256k1_context*)checked_malloc(&default_error_callback, prealloc_size); + if (EXPECT(secp256k1_context_preallocated_create(ctx, flags) == NULL, 0)) { + free(ctx); + return NULL; + } + + return ctx; +} + +secp256k1_context* secp256k1_context_preallocated_clone(const secp256k1_context* ctx, void* prealloc) { + secp256k1_context* ret; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(prealloc != NULL); + + ret = (secp256k1_context*)prealloc; + *ret = *ctx; + return ret; +} + +secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { + secp256k1_context* ret; + size_t prealloc_size; + + VERIFY_CHECK(ctx != NULL); + prealloc_size = secp256k1_context_preallocated_clone_size(ctx); + ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, prealloc_size); + ret = secp256k1_context_preallocated_clone(ctx, ret); + return ret; +} + +void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) { + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); + if (ctx != NULL) { + secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); + } +} + +void secp256k1_context_destroy(secp256k1_context* ctx) { + if (ctx != NULL) { + secp256k1_context_preallocated_destroy(ctx); + free(ctx); + } +} + +void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); + if (fun == NULL) { + fun = secp256k1_default_illegal_callback_fn; + } + ctx->illegal_callback.fn = fun; + ctx->illegal_callback.data = data; +} + +void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); + if (fun == NULL) { + fun = secp256k1_default_error_callback_fn; + } + ctx->error_callback.fn = fun; + ctx->error_callback.data = data; +} + +secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { + VERIFY_CHECK(ctx != NULL); + return secp256k1_scratch_create(&ctx->error_callback, max_size); +} + +void secp256k1_scratch_space_destroy(const secp256k1_context *ctx, secp256k1_scratch_space* scratch) { + VERIFY_CHECK(ctx != NULL); + secp256k1_scratch_destroy(&ctx->error_callback, scratch); +} + +/* Mark memory as no-longer-secret for the purpose of analysing constant-time behaviour + * of the software. This is setup for use with valgrind but could be substituted with + * the appropriate instrumentation for other analysis tools. + */ +static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context* ctx, const void *p, size_t len) { +#if defined(VALGRIND) + if (EXPECT(ctx->declassify,0)) VALGRIND_MAKE_MEM_DEFINED(p, len); +#else + (void)ctx; + (void)p; + (void)len; +#endif +} + +static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { + if (sizeof(secp256k1_ge_storage) == 64) { + /* When the secp256k1_ge_storage type is exactly 64 byte, use its + * representation inside secp256k1_pubkey, as conversion is very fast. + * Note that secp256k1_pubkey_save must use the same representation. */ + secp256k1_ge_storage s; + memcpy(&s, &pubkey->data[0], sizeof(s)); + secp256k1_ge_from_storage(ge, &s); + } else { + /* Otherwise, fall back to 32-byte big endian for X and Y. */ + secp256k1_fe x, y; + secp256k1_fe_set_b32(&x, pubkey->data); + secp256k1_fe_set_b32(&y, pubkey->data + 32); + secp256k1_ge_set_xy(ge, &x, &y); + } + ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); + return 1; +} + +static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { + if (sizeof(secp256k1_ge_storage) == 64) { + secp256k1_ge_storage s; + secp256k1_ge_to_storage(&s, ge); + memcpy(&pubkey->data[0], &s, sizeof(s)); + } else { + VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); + secp256k1_fe_normalize_var(&ge->x); + secp256k1_fe_normalize_var(&ge->y); + secp256k1_fe_get_b32(pubkey->data, &ge->x); + secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); + } +} + +int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { + secp256k1_ge Q; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(input != NULL); + if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { + return 0; + } + if (!secp256k1_ge_is_in_correct_subgroup(&Q)) { + return 0; + } + secp256k1_pubkey_save(pubkey, &Q); + secp256k1_ge_clear(&Q); + return 1; +} + +int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { + secp256k1_ge Q; + size_t len; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33u : 65u)); + len = *outputlen; + *outputlen = 0; + ARG_CHECK(output != NULL); + memset(output, 0, len); + ARG_CHECK(pubkey != NULL); + ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); + if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { + ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); + if (ret) { + *outputlen = len; + } + } + return ret; +} + +int secp256k1_ec_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_pubkey* pubkey0, const secp256k1_pubkey* pubkey1) { + unsigned char out[2][33]; + const secp256k1_pubkey* pk[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + pk[0] = pubkey0; pk[1] = pubkey1; + for (i = 0; i < 2; i++) { + size_t out_size = sizeof(out[i]); + /* If the public key is NULL or invalid, ec_pubkey_serialize will call + * the illegal_callback and return 0. In that case we will serialize the + * key as all zeros which is less than any valid public key. This + * results in consistent comparisons even if NULL or invalid pubkeys are + * involved and prevents edge cases such as sorting algorithms that use + * this function and do not terminate as a result. */ + if (!secp256k1_ec_pubkey_serialize(ctx, out[i], &out_size, pk[i], SECP256K1_EC_COMPRESSED)) { + /* Note that ec_pubkey_serialize should already set the output to + * zero in that case, but it's not guaranteed by the API, we can't + * test it and writing a VERIFY_CHECK is more complex than + * explicitly memsetting (again). */ + memset(out[i], 0, sizeof(out[i])); + } + } + return secp256k1_memcmp_var(out[0], out[1], sizeof(out[0])); +} + +static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } +} + +static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } +} + +int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(input != NULL); + + if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; + } else { + memset(sig, 0, sizeof(*sig)); + return 0; + } +} + +int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { + secp256k1_scalar r, s; + int ret = 1; + int overflow = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + } else { + memset(sig, 0, sizeof(*sig)); + } + return ret; +} + +int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); +} + +int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { + secp256k1_scalar r, s; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); + ret = secp256k1_scalar_is_high(&s); + if (sigout != NULL) { + if (ret) { + secp256k1_scalar_negate(&s, &s); + } + secp256k1_ecdsa_signature_save(sigout, &r, &s); + } + + return ret; +} + +int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const secp256k1_pubkey *pubkey) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_scalar_set_b32(&m, msghash32, NULL); + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return (!secp256k1_scalar_is_high(&s) && + secp256k1_pubkey_load(ctx, &q, pubkey) && + secp256k1_ecdsa_sig_verify(&r, &s, &q, &m)); +} + +int secp256k1_ecdsa_verify_with_handling_high_s(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const secp256k1_pubkey *pubkey) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_scalar_set_b32(&m, msghash32, NULL); + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + + if (secp256k1_scalar_is_high(&s)) { + secp256k1_scalar_cond_negate(&s, 1); + } + + return (!secp256k1_scalar_is_high(&s) && + secp256k1_pubkey_load(ctx, &q, pubkey) && + secp256k1_ecdsa_sig_verify(&r, &s, &q, &m)); +} + +static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *offset, const void *data, unsigned int len) { + memcpy(buf + *offset, data, len); + *offset += len; +} + +static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { + unsigned char keydata[112]; + unsigned int offset = 0; + secp256k1_rfc6979_hmac_sha256 rng; + unsigned int i; + secp256k1_scalar msg; + unsigned char msgmod32[32]; + secp256k1_scalar_set_b32(&msg, msg32, NULL); + secp256k1_scalar_get_b32(msgmod32, &msg); + /* We feed a byte array to the PRNG as input, consisting of: + * - the private key (32 bytes) and reduced message (32 bytes), see RFC 6979 3.2d. + * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. + * - optionally 16 extra bytes with the algorithm name. + * Because the arguments have distinct fixed lengths it is not possible for + * different argument mixtures to emulate each other and result in the same + * nonces. + */ + buffer_append(keydata, &offset, key32, 32); + buffer_append(keydata, &offset, msgmod32, 32); + if (data != NULL) { + buffer_append(keydata, &offset, data, 32); + } + if (algo16 != NULL) { + buffer_append(keydata, &offset, algo16, 16); + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); + memset(keydata, 0, sizeof(keydata)); + for (i = 0; i <= counter; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + return 1; +} + +const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; +const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; + +static int secp256k1_ecdsa_sign_inner(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar sec, non, msg; + int ret = 0; + int is_sec_valid; + unsigned char nonce32[32]; + unsigned int count = 0; + /* Default initialization here is important so we won't pass uninit values to the cmov in the end */ + *r = secp256k1_scalar_zero; + *s = secp256k1_scalar_zero; + if (recid) { + *recid = 0; + } + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } + + /* Fail if the secret key is invalid. */ + is_sec_valid = secp256k1_scalar_set_b32_seckey(&sec, seckey); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_one, !is_sec_valid); + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + int is_nonce_valid; + ret = !!noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); + if (!ret) { + break; + } + is_nonce_valid = secp256k1_scalar_set_b32_seckey(&non, nonce32); + /* The nonce is still secret here, but it being invalid is is less likely than 1:2^255. */ + secp256k1_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); + if (is_nonce_valid) { + ret = secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, r, s, &sec, &msg, &non, recid); + /* The final signature is no longer a secret, nor is the fact that we were successful or not. */ + secp256k1_declassify(ctx, &ret, sizeof(ret)); + if (ret) { + break; + } + } + count++; + } + /* We don't want to declassify is_sec_valid and therefore the range of + * seckey. As a result is_sec_valid is included in ret only after ret was + * used as a branching variable. */ + ret &= is_sec_valid; + memset(nonce32, 0, 32); + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + secp256k1_scalar_cmov(r, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_cmov(s, &secp256k1_scalar_zero, !ret); + if (recid) { + const int zero = 0; + secp256k1_int_cmov(recid, &zero, !ret); + } + return ret; +} + +int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + int ret; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msghash32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_ecdsa_sign_inner(ctx, &r, &s, NULL, msghash32, seckey, noncefp, noncedata); + secp256k1_ecdsa_signature_save(signature, &r, &s); + return ret; +} + +int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { + secp256k1_scalar sec; + int ret; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + secp256k1_scalar_clear(&sec); + return ret; +} + +static int secp256k1_ec_pubkey_create_helper(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_scalar *seckey_scalar, secp256k1_ge *p, const unsigned char *seckey) { + secp256k1_gej pj; + int ret; + + ret = secp256k1_scalar_set_b32_seckey(seckey_scalar, seckey); + secp256k1_scalar_cmov(seckey_scalar, &secp256k1_scalar_one, !ret); + + secp256k1_ecmult_gen(ecmult_gen_ctx, &pj, seckey_scalar); + secp256k1_ge_set_gej(p, &pj); + return ret; +} + +int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { + secp256k1_ge p; + secp256k1_scalar seckey_scalar; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &seckey_scalar, &p, seckey); + secp256k1_pubkey_save(pubkey, &p); + secp256k1_memczero(pubkey, sizeof(*pubkey), !ret); + + secp256k1_scalar_clear(&seckey_scalar); + return ret; +} + +int secp256k1_ec_seckey_negate(const secp256k1_context* ctx, unsigned char *seckey) { + secp256k1_scalar sec; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_negate(&sec, &sec); + secp256k1_scalar_get_b32(seckey, &sec); + + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { + return secp256k1_ec_seckey_negate(ctx, seckey); +} + +int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { + int ret = 0; + secp256k1_ge p; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + + ret = secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + secp256k1_ge_neg(&p, &p); + secp256k1_pubkey_save(pubkey, &p); + } + return ret; +} + + +static int secp256k1_ec_seckey_tweak_add_helper(secp256k1_scalar *sec, const unsigned char *tweak32) { + secp256k1_scalar term; + int overflow = 0; + int ret = 0; + + secp256k1_scalar_set_b32(&term, tweak32, &overflow); + ret = (!overflow) & secp256k1_eckey_privkey_tweak_add(sec, &term); + secp256k1_scalar_clear(&term); + return ret; +} + +int secp256k1_ec_seckey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + secp256k1_scalar sec; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak32 != NULL); + + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + ret &= secp256k1_ec_seckey_tweak_add_helper(&sec, tweak32); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_get_b32(seckey, &sec); + + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return secp256k1_ec_seckey_tweak_add(ctx, seckey, tweak32); +} + +static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *p, const unsigned char *tweak32) { + secp256k1_scalar term; + int overflow = 0; + secp256k1_scalar_set_b32(&term, tweak32, &overflow); + return !overflow && secp256k1_eckey_pubkey_tweak_add(p, &term); +} + +int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) { + secp256k1_ge p; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak32 != NULL); + + ret = secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + ret = ret && secp256k1_ec_pubkey_tweak_add_helper(&p, tweak32); + if (ret) { + secp256k1_pubkey_save(pubkey, &p); + } + + return ret; +} + +int secp256k1_ec_seckey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + secp256k1_scalar factor; + secp256k1_scalar sec; + int ret = 0; + int overflow = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak32 != NULL); + + secp256k1_scalar_set_b32(&factor, tweak32, &overflow); + ret = secp256k1_scalar_set_b32_seckey(&sec, seckey); + ret &= (!overflow) & secp256k1_eckey_privkey_tweak_mul(&sec, &factor); + secp256k1_scalar_cmov(&sec, &secp256k1_scalar_zero, !ret); + secp256k1_scalar_get_b32(seckey, &sec); + + secp256k1_scalar_clear(&sec); + secp256k1_scalar_clear(&factor); + return ret; +} + +int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return secp256k1_ec_seckey_tweak_mul(ctx, seckey, tweak32); +} + +int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) { + secp256k1_ge p; + secp256k1_scalar factor; + int ret = 0; + int overflow = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak32 != NULL); + + secp256k1_scalar_set_b32(&factor, tweak32, &overflow); + ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + if (secp256k1_eckey_pubkey_tweak_mul(&p, &factor)) { + secp256k1_pubkey_save(pubkey, &p); + } else { + ret = 0; + } + } + + return ret; +} + +int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { + VERIFY_CHECK(ctx != NULL); + if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + } + return 1; +} + +int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { + size_t i; + secp256k1_gej Qj; + secp256k1_ge Q; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(n >= 1); + ARG_CHECK(pubnonces != NULL); + + secp256k1_gej_set_infinity(&Qj); + + for (i = 0; i < n; i++) { + ARG_CHECK(pubnonces[i] != NULL); + secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); + secp256k1_gej_add_ge(&Qj, &Qj, &Q); + } + if (secp256k1_gej_is_infinity(&Qj)) { + return 0; + } + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(pubnonce, &Q); + return 1; +} + +int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32, const unsigned char *tag, size_t taglen, const unsigned char *msg, size_t msglen) { + secp256k1_sha256 sha; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(hash32 != NULL); + ARG_CHECK(tag != NULL); + ARG_CHECK(msg != NULL); + + secp256k1_sha256_initialize_tagged(&sha, tag, taglen); + secp256k1_sha256_write(&sha, msg, msglen); + secp256k1_sha256_finalize(&sha, hash32); + return 1; +} + +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/main_impl3.h" +#endif + +#ifdef ENABLE_MODULE_EXTRAKEYS +# include "modules/extrakeys/main_impl2.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORRSIG +# include "modules/schnorrsig/main_impl4.h" +#endif diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/selftest.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/selftest.h new file mode 100644 index 00000000..52f1b844 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/selftest.h @@ -0,0 +1,32 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SELFTEST_H +#define SECP256K1_SELFTEST_H + +#include "hash.h" + +#include + +static int secp256k1_selftest_sha256(void) { + static const char *input63 = "For this sample, this 63-byte string will be used as input data"; + static const unsigned char output32[32] = { + 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, + 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, + }; + unsigned char out[32]; + secp256k1_sha256 hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); + secp256k1_sha256_finalize(&hasher, out); + return secp256k1_memcmp_var(out, output32, 32) == 0; +} + +static int secp256k1_selftest(void) { + return secp256k1_selftest_sha256(); +} + +#endif /* SECP256K1_SELFTEST_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand.h new file mode 100644 index 00000000..bd149bb1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand.h @@ -0,0 +1,50 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_TESTRAND_H +#define SECP256K1_TESTRAND_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +/* A non-cryptographic RNG used only for test infrastructure. */ + +/** Seed the pseudorandom number generator for testing. */ +SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16); + +/** Generate a pseudorandom number in the range [0..2**32-1]. */ +SECP256K1_INLINE static uint32_t secp256k1_testrand32(void); + +/** Generate a pseudorandom number in the range [0..2**64-1]. */ +SECP256K1_INLINE static uint64_t secp256k1_testrand64(void); + +/** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or + * more. */ +SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits); + +/** Generate a pseudorandom number in the range [0..range-1]. */ +static uint32_t secp256k1_testrand_int(uint32_t range); + +/** Generate a pseudorandom 32-byte array. */ +static void secp256k1_testrand256(unsigned char *b32); + +/** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ +static void secp256k1_testrand256_test(unsigned char *b32); + +/** Generate pseudorandom bytes with long sequences of zero and one bits. */ +static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len); + +/** Flip a single random bit in a byte array */ +static void secp256k1_testrand_flip(unsigned char *b, size_t len); + +/** Initialize the test RNG using (hex encoded) array up to 16 bytes, or randomly if hexseed is NULL. */ +static void secp256k1_testrand_init(const char* hexseed); + +/** Print final test information. */ +static void secp256k1_testrand_finish(void); + +#endif /* SECP256K1_TESTRAND_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand_impl.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand_impl.h new file mode 100644 index 00000000..e9b9d7de --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/testrand_impl.h @@ -0,0 +1,197 @@ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_TESTRAND_IMPL_H +#define SECP256K1_TESTRAND_IMPL_H + +#include +#include +#include + +#include "testrand.h" +#include "hash.h" + +static uint64_t secp256k1_test_state[4]; +static uint64_t secp256k1_test_rng_integer; +static int secp256k1_test_rng_integer_bits_left = 0; + +SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16) { + static const unsigned char PREFIX[19] = "secp256k1 test init"; + unsigned char out32[32]; + secp256k1_sha256 hash; + int i; + + /* Use SHA256(PREFIX || seed16) as initial state. */ + secp256k1_sha256_initialize(&hash); + secp256k1_sha256_write(&hash, PREFIX, sizeof(PREFIX)); + secp256k1_sha256_write(&hash, seed16, 16); + secp256k1_sha256_finalize(&hash, out32); + for (i = 0; i < 4; ++i) { + uint64_t s = 0; + int j; + for (j = 0; j < 8; ++j) s = (s << 8) | out32[8*i + j]; + secp256k1_test_state[i] = s; + } + secp256k1_test_rng_integer_bits_left = 0; +} + +SECP256K1_INLINE static uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) { + /* Test-only Xoshiro256++ RNG. See https://prng.di.unimi.it/ */ + const uint64_t result = rotl(secp256k1_test_state[0] + secp256k1_test_state[3], 23) + secp256k1_test_state[0]; + const uint64_t t = secp256k1_test_state[1] << 17; + secp256k1_test_state[2] ^= secp256k1_test_state[0]; + secp256k1_test_state[3] ^= secp256k1_test_state[1]; + secp256k1_test_state[1] ^= secp256k1_test_state[2]; + secp256k1_test_state[0] ^= secp256k1_test_state[3]; + secp256k1_test_state[2] ^= t; + secp256k1_test_state[3] = rotl(secp256k1_test_state[3], 45); + return result; +} + +SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits) { + uint64_t ret; + if (secp256k1_test_rng_integer_bits_left < bits) { + secp256k1_test_rng_integer = secp256k1_testrand64(); + secp256k1_test_rng_integer_bits_left = 64; + } + ret = secp256k1_test_rng_integer; + secp256k1_test_rng_integer >>= bits; + secp256k1_test_rng_integer_bits_left -= bits; + ret &= ((~((uint64_t)0)) >> (64 - bits)); + return ret; +} + +SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) { + return secp256k1_testrand_bits(32); +} + +static uint32_t secp256k1_testrand_int(uint32_t range) { + /* We want a uniform integer between 0 and range-1, inclusive. + * B is the smallest number such that range <= 2**B. + * two mechanisms implemented here: + * - generate B bits numbers until one below range is found, and return it + * - find the largest multiple M of range that is <= 2**(B+A), generate B+A + * bits numbers until one below M is found, and return it modulo range + * The second mechanism consumes A more bits of entropy in every iteration, + * but may need fewer iterations due to M being closer to 2**(B+A) then + * range is to 2**B. The array below (indexed by B) contains a 0 when the + * first mechanism is to be used, and the number A otherwise. + */ + static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; + uint32_t trange, mult; + int bits = 0; + if (range <= 1) { + return 0; + } + trange = range - 1; + while (trange > 0) { + trange >>= 1; + bits++; + } + if (addbits[bits]) { + bits = bits + addbits[bits]; + mult = ((~((uint32_t)0)) >> (32 - bits)) / range; + trange = range * mult; + } else { + trange = range; + mult = 1; + } + while(1) { + uint32_t x = secp256k1_testrand_bits(bits); + if (x < trange) { + return (mult == 1) ? x : (x % range); + } + } +} + +static void secp256k1_testrand256(unsigned char *b32) { + int i; + for (i = 0; i < 4; ++i) { + uint64_t val = secp256k1_testrand64(); + b32[0] = val; + b32[1] = val >> 8; + b32[2] = val >> 16; + b32[3] = val >> 24; + b32[4] = val >> 32; + b32[5] = val >> 40; + b32[6] = val >> 48; + b32[7] = val >> 56; + b32 += 8; + } +} + +static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len) { + size_t bits = 0; + memset(bytes, 0, len); + while (bits < len * 8) { + int now; + uint32_t val; + now = 1 + (secp256k1_testrand_bits(6) * secp256k1_testrand_bits(5) + 16) / 31; + val = secp256k1_testrand_bits(1); + while (now > 0 && bits < len * 8) { + bytes[bits / 8] |= val << (bits % 8); + now--; + bits++; + } + } +} + +static void secp256k1_testrand256_test(unsigned char *b32) { + secp256k1_testrand_bytes_test(b32, 32); +} + +static void secp256k1_testrand_flip(unsigned char *b, size_t len) { + b[secp256k1_testrand_int(len)] ^= (1 << secp256k1_testrand_bits(3)); +} + +static void secp256k1_testrand_init(const char* hexseed) { + unsigned char seed16[16] = {0}; + if (hexseed && strlen(hexseed) != 0) { + int pos = 0; + while (pos < 16 && hexseed[0] != 0 && hexseed[1] != 0) { + unsigned short sh; + if ((sscanf(hexseed, "%2hx", &sh)) == 1) { + seed16[pos] = sh; + } else { + break; + } + hexseed += 2; + pos++; + } + } else { + FILE *frand = fopen("/dev/urandom", "rb"); + if ((frand == NULL) || fread(&seed16, 1, sizeof(seed16), frand) != sizeof(seed16)) { + uint64_t t = time(NULL) * (uint64_t)1337; + fprintf(stderr, "WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n"); + seed16[0] ^= t; + seed16[1] ^= t >> 8; + seed16[2] ^= t >> 16; + seed16[3] ^= t >> 24; + seed16[4] ^= t >> 32; + seed16[5] ^= t >> 40; + seed16[6] ^= t >> 48; + seed16[7] ^= t >> 56; + } + if (frand) { + fclose(frand); + } + } + + printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); + secp256k1_testrand_seed(seed16); +} + +static void secp256k1_testrand_finish(void) { + unsigned char run32[32]; + secp256k1_testrand256(run32); + printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); +} + +#endif /* SECP256K1_TESTRAND_IMPL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/util.h b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/util.h new file mode 100644 index 00000000..dac86bd7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/util.h @@ -0,0 +1,332 @@ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_UTIL_H +#define SECP256K1_UTIL_H + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include +#include +#include +#include + +typedef struct { + void (*fn)(const char *text, void* data); + const void* data; +} secp256k1_callback; + +static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { + cb->fn(text, (void*)cb->data); +} + +#ifndef USE_EXTERNAL_DEFAULT_CALLBACKS +static void secp256k1_default_illegal_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); + abort(); +} +static void secp256k1_default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} +#else +void secp256k1_default_illegal_callback_fn(const char* str, void* data); +void secp256k1_default_error_callback_fn(const char* str, void* data); +#endif + +static const secp256k1_callback default_illegal_callback = { + secp256k1_default_illegal_callback_fn, + NULL +}; + +static const secp256k1_callback default_error_callback = { + secp256k1_default_error_callback_fn, + NULL +}; + + +#ifdef DETERMINISTIC +#define TEST_FAILURE(msg) do { \ + fprintf(stderr, "%s\n", msg); \ + abort(); \ +} while(0); +#else +#define TEST_FAILURE(msg) do { \ + fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ + abort(); \ +} while(0) +#endif + +#if SECP256K1_GNUC_PREREQ(3, 0) +#define EXPECT(x,c) __builtin_expect((x),(c)) +#else +#define EXPECT(x,c) (x) +#endif + +#ifdef DETERMINISTIC +#define CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + TEST_FAILURE("test condition failed"); \ + } \ +} while(0) +#else +#define CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + TEST_FAILURE("test condition failed: " #cond); \ + } \ +} while(0) +#endif + +/* Like assert(), but when VERIFY is defined, and side-effect safe. */ +#if defined(COVERAGE) +#define VERIFY_CHECK(check) +#define VERIFY_SETUP(stmt) +#elif defined(VERIFY) +#define VERIFY_CHECK CHECK +#define VERIFY_SETUP(stmt) do { stmt; } while(0) +#else +#define VERIFY_CHECK(cond) do { (void)(cond); } while(0) +#define VERIFY_SETUP(stmt) +#endif + +/* Define `VG_UNDEF` and `VG_CHECK` when VALGRIND is defined */ +#if !defined(VG_CHECK) +# if defined(VALGRIND) +# include +# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) +# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) +# else +# define VG_UNDEF(x,y) +# define VG_CHECK(x,y) +# endif +#endif + +/* Like `VG_CHECK` but on VERIFY only */ +#if defined(VERIFY) +#define VG_CHECK_VERIFY(x,y) VG_CHECK((x), (y)) +#else +#define VG_CHECK_VERIFY(x,y) +#endif + +static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { + void *ret = malloc(size); + if (ret == NULL) { + secp256k1_callback_call(cb, "Out of memory"); + } + return ret; +} + +static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { + void *ret = realloc(ptr, size); + if (ret == NULL) { + secp256k1_callback_call(cb, "Out of memory"); + } + return ret; +} + +#if defined(__BIGGEST_ALIGNMENT__) +#define ALIGNMENT __BIGGEST_ALIGNMENT__ +#else +/* Using 16 bytes alignment because common architectures never have alignment + * requirements above 8 for any of the types we care about. In addition we + * leave some room because currently we don't care about a few bytes. */ +#define ALIGNMENT 16 +#endif + +#define ROUND_TO_ALIGN(size) ((((size) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) + +/* Macro for restrict, when available and not in a VERIFY build. */ +#if defined(SECP256K1_BUILD) && defined(VERIFY) +# define SECP256K1_RESTRICT +#else +# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if SECP256K1_GNUC_PREREQ(3,0) +# define SECP256K1_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define SECP256K1_RESTRICT __restrict +# else +# define SECP256K1_RESTRICT +# endif +# else +# define SECP256K1_RESTRICT restrict +# endif +#endif + +#if defined(_WIN32) +# define I64FORMAT "I64d" +# define I64uFORMAT "I64u" +#else +# define I64FORMAT "lld" +# define I64uFORMAT "llu" +#endif + +#if defined(__GNUC__) +# define SECP256K1_GNUC_EXT __extension__ +#else +# define SECP256K1_GNUC_EXT +#endif + +/* Zero memory if flag == 1. Flag must be 0 or 1. Constant time. */ +static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) { + unsigned char *p = (unsigned char *)s; + /* Access flag with a volatile-qualified lvalue. + This prevents clang from figuring out (after inlining) that flag can + take only be 0 or 1, which leads to variable time code. */ + volatile int vflag = flag; + unsigned char mask = -(unsigned char) vflag; + while (len) { + *p &= ~mask; + p++; + len--; + } +} + +/** Semantics like memcmp. Variable-time. + * + * We use this to avoid possible compiler bugs with memcmp, e.g. + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189 + */ +static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n) { + const unsigned char *p1 = s1, *p2 = s2; + size_t i; + + for (i = 0; i < n; i++) { + int diff = p1[i] - p2[i]; + if (diff != 0) { + return diff; + } + } + return 0; +} + +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/ +static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) { + unsigned int mask0, mask1, r_masked, a_masked; + /* Access flag with a volatile-qualified lvalue. + This prevents clang from figuring out (after inlining) that flag can + take only be 0 or 1, which leads to variable time code. */ + volatile int vflag = flag; + + /* Casting a negative int to unsigned and back to int is implementation defined behavior */ + VERIFY_CHECK(*r >= 0 && *a >= 0); + + mask0 = (unsigned int)vflag + ~0u; + mask1 = ~mask0; + r_masked = ((unsigned int)*r & mask0); + a_masked = ((unsigned int)*a & mask1); + + *r = (int)(r_masked | a_masked); +} + +/* If USE_FORCE_WIDEMUL_{INT128,INT64} is set, use that wide multiplication implementation. + * Otherwise use the presence of __SIZEOF_INT128__ to decide. + */ +#if defined(USE_FORCE_WIDEMUL_INT128) +# define SECP256K1_WIDEMUL_INT128 1 +#elif defined(USE_FORCE_WIDEMUL_INT64) +# define SECP256K1_WIDEMUL_INT64 1 +#elif defined(UINT128_MAX) || defined(__SIZEOF_INT128__) +# define SECP256K1_WIDEMUL_INT128 1 +#else +# define SECP256K1_WIDEMUL_INT64 1 +#endif +#if defined(SECP256K1_WIDEMUL_INT128) +# if !defined(UINT128_MAX) && defined(__SIZEOF_INT128__) +SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; +SECP256K1_GNUC_EXT typedef __int128 int128_t; +#define UINT128_MAX ((uint128_t)(-1)) +#define INT128_MAX ((int128_t)(UINT128_MAX >> 1)) +#define INT128_MIN (-INT128_MAX - 1) +/* No (U)INT128_C macros because compilers providing __int128 do not support 128-bit literals. */ +# endif +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +/* Determine the number of trailing zero bits in a (non-zero) 32-bit x. + * This function is only intended to be used as fallback for + * secp256k1_ctz32_var, but permits it to be tested separately. */ +static SECP256K1_INLINE int secp256k1_ctz32_var_debruijn(uint32_t x) { + static const uint8_t debruijn[32] = { + 0x00, 0x01, 0x02, 0x18, 0x03, 0x13, 0x06, 0x19, 0x16, 0x04, 0x14, 0x0A, + 0x10, 0x07, 0x0C, 0x1A, 0x1F, 0x17, 0x12, 0x05, 0x15, 0x09, 0x0F, 0x0B, + 0x1E, 0x11, 0x08, 0x0E, 0x1D, 0x0D, 0x1C, 0x1B + }; + return debruijn[((x & -x) * 0x04D7651F) >> 27]; +} + +/* Determine the number of trailing zero bits in a (non-zero) 64-bit x. + * This function is only intended to be used as fallback for + * secp256k1_ctz64_var, but permits it to be tested separately. */ +static SECP256K1_INLINE int secp256k1_ctz64_var_debruijn(uint64_t x) { + static const uint8_t debruijn[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + return debruijn[((x & -x) * 0x022FDD63CC95386D) >> 58]; +} + +/* Determine the number of trailing zero bits in a (non-zero) 32-bit x. */ +static SECP256K1_INLINE int secp256k1_ctz32_var(uint32_t x) { + VERIFY_CHECK(x != 0); +#if (__has_builtin(__builtin_ctz) || SECP256K1_GNUC_PREREQ(3,4)) + /* If the unsigned type is sufficient to represent the largest uint32_t, consider __builtin_ctz. */ + if (((unsigned)UINT32_MAX) == UINT32_MAX) { + return __builtin_ctz(x); + } +#endif +#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4)) + /* Otherwise consider __builtin_ctzl (the unsigned long type is always at least 32 bits). */ + return __builtin_ctzl(x); +#else + /* If no suitable CTZ builtin is available, use a (variable time) software emulation. */ + return secp256k1_ctz32_var_debruijn(x); +#endif +} + +/* Determine the number of trailing zero bits in a (non-zero) 64-bit x. */ +static SECP256K1_INLINE int secp256k1_ctz64_var(uint64_t x) { + VERIFY_CHECK(x != 0); +#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4)) + /* If the unsigned long type is sufficient to represent the largest uint64_t, consider __builtin_ctzl. */ + if (((unsigned long)UINT64_MAX) == UINT64_MAX) { + return __builtin_ctzl(x); + } +#endif +#if (__has_builtin(__builtin_ctzll) || SECP256K1_GNUC_PREREQ(3,4)) + /* Otherwise consider __builtin_ctzll (the unsigned long long type is always at least 64 bits). */ + return __builtin_ctzll(x); +#else + /* If no suitable CTZ builtin is available, use a (variable time) software emulation. */ + return secp256k1_ctz64_var_debruijn(x); +#endif +} + +/* Read a uint32_t in big endian */ +SECP256K1_INLINE static uint32_t secp256k1_read_be32(const unsigned char* p) { + return (uint32_t)p[0] << 24 | + (uint32_t)p[1] << 16 | + (uint32_t)p[2] << 8 | + (uint32_t)p[3]; +} + +/* Write a uint32_t in big endian */ +SECP256K1_INLINE static void secp256k1_write_be32(unsigned char* p, uint32_t x) { + p[3] = x; + p[2] = x >> 8; + p[1] = x >> 16; + p[0] = x >> 24; +} + +#endif /* SECP256K1_UTIL_H */ diff --git a/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/utility.c b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/utility.c new file mode 100644 index 00000000..1c538b39 --- /dev/null +++ b/one-and-half-nibble/MobileApp/Pods/secp256k1Wrapper/src/utility.c @@ -0,0 +1,31 @@ +// +// Utility.c +// GigaBitcoin/secp256k1.swift +// +// Copyright (c) 2021 GigaBitcoin LLC +// Distributed under the MIT software license +// +// See the accompanying file LICENSE for information +// + +#include "../include/utility.h" +#include "./hash_impl.h" + +/// Exposes secp256k1 memczero implementation to the bindings target +/// @param s pointer to an array to be zero'd by the function +/// @param len the length of the data to be zero'd +/// @param flag zero memory if flag == 1. Flag must be 0 or 1. Constant time. +void secp256k1_swift_memczero(void *s, size_t len, int flag) { + secp256k1_memczero(s, len, flag); +} + +/// Exposes secp256k1 SHA256 implementation to the bindings target +/// @param output pointer to an array to be filled by the function +/// @param input a pointer to the data to be hashed +/// @param len the length of the data to be hashed +void secp256k1_swift_sha256(unsigned char *output, const unsigned char *input, size_t len) { + secp256k1_sha256 hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, input, len); + secp256k1_sha256_finalize(&hasher, output); +} diff --git a/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.pbxproj b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.pbxproj new file mode 100644 index 00000000..2183856a --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.pbxproj @@ -0,0 +1,1045 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 0F2CE2A49576CB2BFC51FDC0 /* Pods_fanex_fanexUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 280BFA74C66B79C5B4A9386F /* Pods_fanex_fanexUITests.framework */; }; + 5A2BC70F60D2BAC700D6FEBC /* Pods_fanexTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C32D365BBFDE2369E86E7954 /* Pods_fanexTests.framework */; }; + 6888A9CE29AA115000C0FFB5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9CD29AA115000C0FFB5 /* AppDelegate.swift */; }; + 6888A9D029AA115000C0FFB5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9CF29AA115000C0FFB5 /* SceneDelegate.swift */; }; + 6888A9D229AA115000C0FFB5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9D129AA115000C0FFB5 /* ViewController.swift */; }; + 6888A9D529AA115000C0FFB5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6888A9D329AA115000C0FFB5 /* Main.storyboard */; }; + 6888A9D829AA115000C0FFB5 /* fanex.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9D629AA115000C0FFB5 /* fanex.xcdatamodeld */; }; + 6888A9DA29AA115400C0FFB5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6888A9D929AA115400C0FFB5 /* Assets.xcassets */; }; + 6888A9DD29AA115400C0FFB5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6888A9DB29AA115400C0FFB5 /* LaunchScreen.storyboard */; }; + 6888A9E829AA115400C0FFB5 /* fanexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9E729AA115400C0FFB5 /* fanexTests.swift */; }; + 6888A9F229AA115400C0FFB5 /* fanexUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9F129AA115400C0FFB5 /* fanexUITests.swift */; }; + 6888A9F429AA115400C0FFB5 /* fanexUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A9F329AA115400C0FFB5 /* fanexUITestsLaunchTests.swift */; }; + 6888AA0629AA13BF00C0FFB5 /* iOSDevCenters+GIF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA0529AA13BF00C0FFB5 /* iOSDevCenters+GIF.swift */; }; + 6888AA0829AA148C00C0FFB5 /* fanex logo.gif in Resources */ = {isa = PBXBuildFile; fileRef = 6888AA0729AA148C00C0FFB5 /* fanex logo.gif */; }; + 6888AA0A29AA1AD500C0FFB5 /* HomeScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA0929AA1AD500C0FFB5 /* HomeScreenController.swift */; }; + 6888AA0C29AA1F5900C0FFB5 /* AutoLayouts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA0B29AA1F5900C0FFB5 /* AutoLayouts.swift */; }; + 6888AA0E29AA204E00C0FFB5 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA0D29AA204E00C0FFB5 /* BaseViewController.swift */; }; + 6888AA1029AA209C00C0FFB5 /* FloatingBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA0F29AA209C00C0FFB5 /* FloatingBarView.swift */; }; + 6888AA1229AA20BD00C0FFB5 /* PushViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA1129AA20BD00C0FFB5 /* PushViewController.swift */; }; + 6888AA1429AA20E900C0FFB5 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA1329AA20E900C0FFB5 /* TabBarController.swift */; }; + 6888AA1629AAA41500C0FFB5 /* UILabel+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA1529AAA41500C0FFB5 /* UILabel+Extensions.swift */; }; + 6888AA1A29AAB37500C0FFB5 /* FlowManger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA1929AAB37500C0FFB5 /* FlowManger.swift */; }; + 6888AA1D29AAB5E800C0FFB5 /* FCL in Frameworks */ = {isa = PBXBuildFile; productRef = 6888AA1C29AAB5E800C0FFB5 /* FCL */; }; + 6888AA1F29AAB69900C0FFB5 /* FanexCadence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA1E29AAB69900C0FFB5 /* FanexCadence.swift */; }; + 6888AA2129AB622900C0FFB5 /* FCLDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA2029AB622900C0FFB5 /* FCLDelegate.swift */; }; + 6888AA2329AB6BFC00C0FFB5 /* ProgressHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888AA2229AB6BFC00C0FFB5 /* ProgressHUD.swift */; }; + 6888AA2529AB8B1A00C0FFB5 /* waiting-setting-account.gif in Resources */ = {isa = PBXBuildFile; fileRef = 6888AA2429AB8B1900C0FFB5 /* waiting-setting-account.gif */; }; + 6888AA2829ABEB6500C0FFB5 /* EKTabBarController in Frameworks */ = {isa = PBXBuildFile; productRef = 6888AA2729ABEB6500C0FFB5 /* EKTabBarController */; }; + 68CDE34629AD5FA200C43B19 /* ScanQrController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68CDE34529AD5FA200C43B19 /* ScanQrController.swift */; }; + 68D9D3AE29ADF8A500EB66C7 /* TweetView in Frameworks */ = {isa = PBXBuildFile; productRef = 68D9D3AD29ADF8A500EB66C7 /* TweetView */; }; + 68D9D3B029ADF8C000EB66C7 /* TweetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3AF29ADF8C000EB66C7 /* TweetViewController.swift */; }; + 68D9D3B229AE128200EB66C7 /* ProfileView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3B129AE128200EB66C7 /* ProfileView.storyboard */; }; + 68D9D3B429AE144100EB66C7 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3B329AE144100EB66C7 /* ProfileViewController.swift */; }; + 68D9D3B629AE19C400EB66C7 /* profileAvator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3B529AE19C400EB66C7 /* profileAvator.png */; }; + 68D9D3B829AE2C1B00EB66C7 /* ApiHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3B729AE2C1B00EB66C7 /* ApiHandler.swift */; }; + 68D9D3BA29AE2D3A00EB66C7 /* ValidQrCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3B929AE2D3A00EB66C7 /* ValidQrCode.swift */; }; + 68D9D3BC29AE327400EB66C7 /* AirdropModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3BB29AE327400EB66C7 /* AirdropModel.swift */; }; + 68D9D3BE29AE35C500EB66C7 /* AirDropService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3BD29AE35C500EB66C7 /* AirDropService.swift */; }; + 68D9D3C029AE380500EB66C7 /* AirdropViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3BF29AE380500EB66C7 /* AirdropViewModel.swift */; }; + 68D9D3C229AEC25F00EB66C7 /* ActionsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3C129AEC25F00EB66C7 /* ActionsController.swift */; }; + 68D9D3C529AEC5E900EB66C7 /* CarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3C429AEC5E900EB66C7 /* CarouselCell.swift */; }; + 68D9D3C729AEC62000EB66C7 /* CarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3C629AEC62000EB66C7 /* CarouselView.swift */; }; + 68D9D3CA29AEE00100EB66C7 /* CarouselCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3C829AEE00100EB66C7 /* CarouselCollectionViewCell.swift */; }; + 68D9D3CB29AEE00100EB66C7 /* CarouselCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3C929AEE00100EB66C7 /* CarouselCollectionViewCell.xib */; }; + 68D9D3CD29AEF0F700EB66C7 /* twitterAction.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3CC29AEF0F700EB66C7 /* twitterAction.png */; }; + 68D9D3D029AEFFA100EB66C7 /* NFTImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3CE29AEFFA100EB66C7 /* NFTImageCell.swift */; }; + 68D9D3D129AEFFA100EB66C7 /* NFTImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3CF29AEFFA100EB66C7 /* NFTImageCell.xib */; }; + 68D9D3D329AF077E00EB66C7 /* superFan NFt.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D9D3D229AF077E00EB66C7 /* superFan NFt.png */; }; + 68D9D3D529AF08D000EB66C7 /* Token Amount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D9D3D429AF08D000EB66C7 /* Token Amount.swift */; }; + 92704BBC6E21268A041D3550 /* Pods_fanex.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E76A4868723F081B60B246FB /* Pods_fanex.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 6888A9E429AA115400C0FFB5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6888A9C229AA115000C0FFB5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6888A9C929AA115000C0FFB5; + remoteInfo = fanex; + }; + 6888A9EE29AA115400C0FFB5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 6888A9C229AA115000C0FFB5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6888A9C929AA115000C0FFB5; + remoteInfo = fanex; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 280BFA74C66B79C5B4A9386F /* Pods_fanex_fanexUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_fanex_fanexUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 34C5E4241DA5791795FF6DD7 /* Pods-fanex.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanex.debug.xcconfig"; path = "Target Support Files/Pods-fanex/Pods-fanex.debug.xcconfig"; sourceTree = ""; }; + 404189C323C534268C620E78 /* Pods-fanex.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanex.release.xcconfig"; path = "Target Support Files/Pods-fanex/Pods-fanex.release.xcconfig"; sourceTree = ""; }; + 48BB3DF09EFC1425F8288394 /* Pods-fanex-fanexUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanex-fanexUITests.release.xcconfig"; path = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.release.xcconfig"; sourceTree = ""; }; + 6888A9CA29AA115000C0FFB5 /* fanex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fanex.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6888A9CD29AA115000C0FFB5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 6888A9CF29AA115000C0FFB5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 6888A9D129AA115000C0FFB5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 6888A9D429AA115000C0FFB5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6888A9D729AA115000C0FFB5 /* fanex.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = fanex.xcdatamodel; sourceTree = ""; }; + 6888A9D929AA115400C0FFB5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 6888A9DC29AA115400C0FFB5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 6888A9DE29AA115400C0FFB5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6888A9E329AA115400C0FFB5 /* fanexTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = fanexTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 6888A9E729AA115400C0FFB5 /* fanexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = fanexTests.swift; sourceTree = ""; }; + 6888A9ED29AA115400C0FFB5 /* fanexUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = fanexUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 6888A9F129AA115400C0FFB5 /* fanexUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = fanexUITests.swift; sourceTree = ""; }; + 6888A9F329AA115400C0FFB5 /* fanexUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = fanexUITestsLaunchTests.swift; sourceTree = ""; }; + 6888AA0529AA13BF00C0FFB5 /* iOSDevCenters+GIF.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "iOSDevCenters+GIF.swift"; sourceTree = ""; }; + 6888AA0729AA148C00C0FFB5 /* fanex logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "fanex logo.gif"; sourceTree = ""; }; + 6888AA0929AA1AD500C0FFB5 /* HomeScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenController.swift; sourceTree = ""; }; + 6888AA0B29AA1F5900C0FFB5 /* AutoLayouts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoLayouts.swift; sourceTree = ""; }; + 6888AA0D29AA204E00C0FFB5 /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; + 6888AA0F29AA209C00C0FFB5 /* FloatingBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingBarView.swift; sourceTree = ""; }; + 6888AA1129AA20BD00C0FFB5 /* PushViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushViewController.swift; sourceTree = ""; }; + 6888AA1329AA20E900C0FFB5 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + 6888AA1529AAA41500C0FFB5 /* UILabel+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Extensions.swift"; sourceTree = ""; }; + 6888AA1729AAA9BB00C0FFB5 /* fanex.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = fanex.entitlements; sourceTree = ""; }; + 6888AA1929AAB37500C0FFB5 /* FlowManger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowManger.swift; sourceTree = ""; }; + 6888AA1E29AAB69900C0FFB5 /* FanexCadence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FanexCadence.swift; sourceTree = ""; }; + 6888AA2029AB622900C0FFB5 /* FCLDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FCLDelegate.swift; sourceTree = ""; }; + 6888AA2229AB6BFC00C0FFB5 /* ProgressHUD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressHUD.swift; sourceTree = ""; }; + 6888AA2429AB8B1900C0FFB5 /* waiting-setting-account.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "waiting-setting-account.gif"; sourceTree = ""; }; + 68CDE34529AD5FA200C43B19 /* ScanQrController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQrController.swift; sourceTree = ""; }; + 68D9D3AF29ADF8C000EB66C7 /* TweetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TweetViewController.swift; sourceTree = ""; }; + 68D9D3B129AE128200EB66C7 /* ProfileView.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ProfileView.storyboard; sourceTree = ""; }; + 68D9D3B329AE144100EB66C7 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; + 68D9D3B529AE19C400EB66C7 /* profileAvator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = profileAvator.png; sourceTree = ""; }; + 68D9D3B729AE2C1B00EB66C7 /* ApiHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiHandler.swift; sourceTree = ""; }; + 68D9D3B929AE2D3A00EB66C7 /* ValidQrCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidQrCode.swift; sourceTree = ""; }; + 68D9D3BB29AE327400EB66C7 /* AirdropModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirdropModel.swift; sourceTree = ""; }; + 68D9D3BD29AE35C500EB66C7 /* AirDropService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirDropService.swift; sourceTree = ""; }; + 68D9D3BF29AE380500EB66C7 /* AirdropViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirdropViewModel.swift; sourceTree = ""; }; + 68D9D3C129AEC25F00EB66C7 /* ActionsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionsController.swift; sourceTree = ""; }; + 68D9D3C429AEC5E900EB66C7 /* CarouselCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselCell.swift; sourceTree = ""; }; + 68D9D3C629AEC62000EB66C7 /* CarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselView.swift; sourceTree = ""; }; + 68D9D3C829AEE00100EB66C7 /* CarouselCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselCollectionViewCell.swift; sourceTree = ""; }; + 68D9D3C929AEE00100EB66C7 /* CarouselCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CarouselCollectionViewCell.xib; sourceTree = ""; }; + 68D9D3CC29AEF0F700EB66C7 /* twitterAction.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = twitterAction.png; sourceTree = ""; }; + 68D9D3CE29AEFFA100EB66C7 /* NFTImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NFTImageCell.swift; sourceTree = ""; }; + 68D9D3CF29AEFFA100EB66C7 /* NFTImageCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NFTImageCell.xib; sourceTree = ""; }; + 68D9D3D229AF077E00EB66C7 /* superFan NFt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "superFan NFt.png"; sourceTree = ""; }; + 68D9D3D429AF08D000EB66C7 /* Token Amount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Token Amount.swift"; sourceTree = ""; }; + 93F09ED6AA80ED071C96B599 /* Pods-fanexTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanexTests.debug.xcconfig"; path = "Target Support Files/Pods-fanexTests/Pods-fanexTests.debug.xcconfig"; sourceTree = ""; }; + C32D365BBFDE2369E86E7954 /* Pods_fanexTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_fanexTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D641B00C7182A059F6240FC7 /* Pods-fanex-fanexUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanex-fanexUITests.debug.xcconfig"; path = "Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests.debug.xcconfig"; sourceTree = ""; }; + D7918F0805161AD3CC922C8C /* Pods-fanexTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-fanexTests.release.xcconfig"; path = "Target Support Files/Pods-fanexTests/Pods-fanexTests.release.xcconfig"; sourceTree = ""; }; + E76A4868723F081B60B246FB /* Pods_fanex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_fanex.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6888A9C729AA115000C0FFB5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6888AA1D29AAB5E800C0FFB5 /* FCL in Frameworks */, + 68D9D3AE29ADF8A500EB66C7 /* TweetView in Frameworks */, + 6888AA2829ABEB6500C0FFB5 /* EKTabBarController in Frameworks */, + 92704BBC6E21268A041D3550 /* Pods_fanex.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9E029AA115400C0FFB5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5A2BC70F60D2BAC700D6FEBC /* Pods_fanexTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9EA29AA115400C0FFB5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0F2CE2A49576CB2BFC51FDC0 /* Pods_fanex_fanexUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3949820F075DC3CE2B925911 /* Pods */ = { + isa = PBXGroup; + children = ( + 34C5E4241DA5791795FF6DD7 /* Pods-fanex.debug.xcconfig */, + 404189C323C534268C620E78 /* Pods-fanex.release.xcconfig */, + D641B00C7182A059F6240FC7 /* Pods-fanex-fanexUITests.debug.xcconfig */, + 48BB3DF09EFC1425F8288394 /* Pods-fanex-fanexUITests.release.xcconfig */, + 93F09ED6AA80ED071C96B599 /* Pods-fanexTests.debug.xcconfig */, + D7918F0805161AD3CC922C8C /* Pods-fanexTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 6888A9C129AA115000C0FFB5 = { + isa = PBXGroup; + children = ( + 6888A9CC29AA115000C0FFB5 /* fanex */, + 6888A9E629AA115400C0FFB5 /* fanexTests */, + 6888A9F029AA115400C0FFB5 /* fanexUITests */, + 6888A9CB29AA115000C0FFB5 /* Products */, + 3949820F075DC3CE2B925911 /* Pods */, + CAE87E21DB057F1360BF4C63 /* Frameworks */, + ); + sourceTree = ""; + }; + 6888A9CB29AA115000C0FFB5 /* Products */ = { + isa = PBXGroup; + children = ( + 6888A9CA29AA115000C0FFB5 /* fanex.app */, + 6888A9E329AA115400C0FFB5 /* fanexTests.xctest */, + 6888A9ED29AA115400C0FFB5 /* fanexUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 6888A9CC29AA115000C0FFB5 /* fanex */ = { + isa = PBXGroup; + children = ( + 6888AA1729AAA9BB00C0FFB5 /* fanex.entitlements */, + 6888AA0729AA148C00C0FFB5 /* fanex logo.gif */, + 68D9D3D229AF077E00EB66C7 /* superFan NFt.png */, + 6888AA0429AA139E00C0FFB5 /* Helpers */, + 6888AA0329AA138300C0FFB5 /* Model Views */, + 6888AA0229AA137D00C0FFB5 /* Views */, + 6888AA0129AA137400C0FFB5 /* Models */, + 6888AA0029AA136300C0FFB5 /* Controllers */, + 6888A9CD29AA115000C0FFB5 /* AppDelegate.swift */, + 6888A9CF29AA115000C0FFB5 /* SceneDelegate.swift */, + 6888A9D129AA115000C0FFB5 /* ViewController.swift */, + 6888A9D329AA115000C0FFB5 /* Main.storyboard */, + 6888A9D929AA115400C0FFB5 /* Assets.xcassets */, + 68D9D3B529AE19C400EB66C7 /* profileAvator.png */, + 68D9D3CC29AEF0F700EB66C7 /* twitterAction.png */, + 6888AA2429AB8B1900C0FFB5 /* waiting-setting-account.gif */, + 6888A9DB29AA115400C0FFB5 /* LaunchScreen.storyboard */, + 6888A9DE29AA115400C0FFB5 /* Info.plist */, + 6888A9D629AA115000C0FFB5 /* fanex.xcdatamodeld */, + ); + path = fanex; + sourceTree = ""; + }; + 6888A9E629AA115400C0FFB5 /* fanexTests */ = { + isa = PBXGroup; + children = ( + 6888A9E729AA115400C0FFB5 /* fanexTests.swift */, + ); + path = fanexTests; + sourceTree = ""; + }; + 6888A9F029AA115400C0FFB5 /* fanexUITests */ = { + isa = PBXGroup; + children = ( + 6888A9F129AA115400C0FFB5 /* fanexUITests.swift */, + 6888A9F329AA115400C0FFB5 /* fanexUITestsLaunchTests.swift */, + ); + path = fanexUITests; + sourceTree = ""; + }; + 6888AA0029AA136300C0FFB5 /* Controllers */ = { + isa = PBXGroup; + children = ( + 6888AA1829AAB36200C0FFB5 /* Flow */, + 6888AA0929AA1AD500C0FFB5 /* HomeScreenController.swift */, + 6888AA0D29AA204E00C0FFB5 /* BaseViewController.swift */, + 6888AA1129AA20BD00C0FFB5 /* PushViewController.swift */, + 6888AA1329AA20E900C0FFB5 /* TabBarController.swift */, + 6888AA1529AAA41500C0FFB5 /* UILabel+Extensions.swift */, + 68CDE34529AD5FA200C43B19 /* ScanQrController.swift */, + 68D9D3AF29ADF8C000EB66C7 /* TweetViewController.swift */, + 68D9D3C129AEC25F00EB66C7 /* ActionsController.swift */, + ); + name = Controllers; + sourceTree = ""; + }; + 6888AA0129AA137400C0FFB5 /* Models */ = { + isa = PBXGroup; + children = ( + 68D9D3BB29AE327400EB66C7 /* AirdropModel.swift */, + 68D9D3D429AF08D000EB66C7 /* Token Amount.swift */, + ); + path = Models; + sourceTree = ""; + }; + 6888AA0229AA137D00C0FFB5 /* Views */ = { + isa = PBXGroup; + children = ( + 68D9D3C329AEC59600EB66C7 /* components */, + 68D9D3B129AE128200EB66C7 /* ProfileView.storyboard */, + 68D9D3B329AE144100EB66C7 /* ProfileViewController.swift */, + ); + name = Views; + sourceTree = ""; + }; + 6888AA0329AA138300C0FFB5 /* Model Views */ = { + isa = PBXGroup; + children = ( + 68D9D3BD29AE35C500EB66C7 /* AirDropService.swift */, + 68D9D3BF29AE380500EB66C7 /* AirdropViewModel.swift */, + ); + path = "Model Views"; + sourceTree = ""; + }; + 6888AA0429AA139E00C0FFB5 /* Helpers */ = { + isa = PBXGroup; + children = ( + 6888AA0529AA13BF00C0FFB5 /* iOSDevCenters+GIF.swift */, + 6888AA0B29AA1F5900C0FFB5 /* AutoLayouts.swift */, + 6888AA0F29AA209C00C0FFB5 /* FloatingBarView.swift */, + 6888AA2029AB622900C0FFB5 /* FCLDelegate.swift */, + 6888AA2229AB6BFC00C0FFB5 /* ProgressHUD.swift */, + 68D9D3B729AE2C1B00EB66C7 /* ApiHandler.swift */, + 68D9D3B929AE2D3A00EB66C7 /* ValidQrCode.swift */, + ); + name = Helpers; + sourceTree = ""; + }; + 6888AA1829AAB36200C0FFB5 /* Flow */ = { + isa = PBXGroup; + children = ( + 6888AA1929AAB37500C0FFB5 /* FlowManger.swift */, + 6888AA1E29AAB69900C0FFB5 /* FanexCadence.swift */, + ); + path = Flow; + sourceTree = ""; + }; + 68D9D3C329AEC59600EB66C7 /* components */ = { + isa = PBXGroup; + children = ( + 68D9D3C429AEC5E900EB66C7 /* CarouselCell.swift */, + 68D9D3C629AEC62000EB66C7 /* CarouselView.swift */, + 68D9D3C829AEE00100EB66C7 /* CarouselCollectionViewCell.swift */, + 68D9D3C929AEE00100EB66C7 /* CarouselCollectionViewCell.xib */, + 68D9D3CE29AEFFA100EB66C7 /* NFTImageCell.swift */, + 68D9D3CF29AEFFA100EB66C7 /* NFTImageCell.xib */, + ); + path = components; + sourceTree = ""; + }; + CAE87E21DB057F1360BF4C63 /* Frameworks */ = { + isa = PBXGroup; + children = ( + E76A4868723F081B60B246FB /* Pods_fanex.framework */, + 280BFA74C66B79C5B4A9386F /* Pods_fanex_fanexUITests.framework */, + C32D365BBFDE2369E86E7954 /* Pods_fanexTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6888A9C929AA115000C0FFB5 /* fanex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6888A9F729AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanex" */; + buildPhases = ( + E199BC8EBB2FCC3D8D5FAA14 /* [CP] Check Pods Manifest.lock */, + 6888A9C629AA115000C0FFB5 /* Sources */, + 6888A9C729AA115000C0FFB5 /* Frameworks */, + 6888A9C829AA115000C0FFB5 /* Resources */, + 6D38172BC6E57D7F1040C8EC /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = fanex; + packageProductDependencies = ( + 6888AA1C29AAB5E800C0FFB5 /* FCL */, + 6888AA2729ABEB6500C0FFB5 /* EKTabBarController */, + 68D9D3AD29ADF8A500EB66C7 /* TweetView */, + ); + productName = fanex; + productReference = 6888A9CA29AA115000C0FFB5 /* fanex.app */; + productType = "com.apple.product-type.application"; + }; + 6888A9E229AA115400C0FFB5 /* fanexTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6888A9FA29AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanexTests" */; + buildPhases = ( + 78BE152E450C0AF57DD476EC /* [CP] Check Pods Manifest.lock */, + 6888A9DF29AA115400C0FFB5 /* Sources */, + 6888A9E029AA115400C0FFB5 /* Frameworks */, + 6888A9E129AA115400C0FFB5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 6888A9E529AA115400C0FFB5 /* PBXTargetDependency */, + ); + name = fanexTests; + productName = fanexTests; + productReference = 6888A9E329AA115400C0FFB5 /* fanexTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 6888A9EC29AA115400C0FFB5 /* fanexUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6888A9FD29AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanexUITests" */; + buildPhases = ( + 762C48BFDD5FFDBBB5E4DFF0 /* [CP] Check Pods Manifest.lock */, + 6888A9E929AA115400C0FFB5 /* Sources */, + 6888A9EA29AA115400C0FFB5 /* Frameworks */, + 6888A9EB29AA115400C0FFB5 /* Resources */, + FA74A027B3BA07491698D639 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6888A9EF29AA115400C0FFB5 /* PBXTargetDependency */, + ); + name = fanexUITests; + productName = fanexUITests; + productReference = 6888A9ED29AA115400C0FFB5 /* fanexUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6888A9C229AA115000C0FFB5 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1420; + LastUpgradeCheck = 1420; + TargetAttributes = { + 6888A9C929AA115000C0FFB5 = { + CreatedOnToolsVersion = 14.2; + }; + 6888A9E229AA115400C0FFB5 = { + CreatedOnToolsVersion = 14.2; + TestTargetID = 6888A9C929AA115000C0FFB5; + }; + 6888A9EC29AA115400C0FFB5 = { + CreatedOnToolsVersion = 14.2; + TestTargetID = 6888A9C929AA115000C0FFB5; + }; + }; + }; + buildConfigurationList = 6888A9C529AA115000C0FFB5 /* Build configuration list for PBXProject "fanex" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6888A9C129AA115000C0FFB5; + packageReferences = ( + 6888AA1B29AAB5E800C0FFB5 /* XCRemoteSwiftPackageReference "fcl-swift" */, + 6888AA2629ABEB6500C0FFB5 /* XCRemoteSwiftPackageReference "EKTabBar" */, + 68D9D3AC29ADF8A500EB66C7 /* XCRemoteSwiftPackageReference "tweetview-ios" */, + ); + productRefGroup = 6888A9CB29AA115000C0FFB5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6888A9C929AA115000C0FFB5 /* fanex */, + 6888A9E229AA115400C0FFB5 /* fanexTests */, + 6888A9EC29AA115400C0FFB5 /* fanexUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6888A9C829AA115000C0FFB5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6888A9DD29AA115400C0FFB5 /* LaunchScreen.storyboard in Resources */, + 6888AA0829AA148C00C0FFB5 /* fanex logo.gif in Resources */, + 6888A9DA29AA115400C0FFB5 /* Assets.xcassets in Resources */, + 68D9D3B629AE19C400EB66C7 /* profileAvator.png in Resources */, + 68D9D3D129AEFFA100EB66C7 /* NFTImageCell.xib in Resources */, + 68D9D3CB29AEE00100EB66C7 /* CarouselCollectionViewCell.xib in Resources */, + 6888AA2529AB8B1A00C0FFB5 /* waiting-setting-account.gif in Resources */, + 6888A9D529AA115000C0FFB5 /* Main.storyboard in Resources */, + 68D9D3D329AF077E00EB66C7 /* superFan NFt.png in Resources */, + 68D9D3CD29AEF0F700EB66C7 /* twitterAction.png in Resources */, + 68D9D3B229AE128200EB66C7 /* ProfileView.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9E129AA115400C0FFB5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9EB29AA115400C0FFB5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 6D38172BC6E57D7F1040C8EC /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-fanex/Pods-fanex-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-fanex/Pods-fanex-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-fanex/Pods-fanex-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 762C48BFDD5FFDBBB5E4DFF0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-fanex-fanexUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 78BE152E450C0AF57DD476EC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-fanexTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E199BC8EBB2FCC3D8D5FAA14 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-fanex-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + FA74A027B3BA07491698D639 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-fanex-fanexUITests/Pods-fanex-fanexUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6888A9C629AA115000C0FFB5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 68D9D3CA29AEE00100EB66C7 /* CarouselCollectionViewCell.swift in Sources */, + 6888AA2129AB622900C0FFB5 /* FCLDelegate.swift in Sources */, + 6888AA1629AAA41500C0FFB5 /* UILabel+Extensions.swift in Sources */, + 68D9D3B029ADF8C000EB66C7 /* TweetViewController.swift in Sources */, + 6888AA2329AB6BFC00C0FFB5 /* ProgressHUD.swift in Sources */, + 6888A9D829AA115000C0FFB5 /* fanex.xcdatamodeld in Sources */, + 6888AA1A29AAB37500C0FFB5 /* FlowManger.swift in Sources */, + 6888AA1029AA209C00C0FFB5 /* FloatingBarView.swift in Sources */, + 68D9D3B829AE2C1B00EB66C7 /* ApiHandler.swift in Sources */, + 68D9D3D029AEFFA100EB66C7 /* NFTImageCell.swift in Sources */, + 6888AA1F29AAB69900C0FFB5 /* FanexCadence.swift in Sources */, + 68D9D3C229AEC25F00EB66C7 /* ActionsController.swift in Sources */, + 68D9D3BE29AE35C500EB66C7 /* AirDropService.swift in Sources */, + 68D9D3C529AEC5E900EB66C7 /* CarouselCell.swift in Sources */, + 68D9D3BC29AE327400EB66C7 /* AirdropModel.swift in Sources */, + 68D9D3C729AEC62000EB66C7 /* CarouselView.swift in Sources */, + 6888AA1429AA20E900C0FFB5 /* TabBarController.swift in Sources */, + 68D9D3B429AE144100EB66C7 /* ProfileViewController.swift in Sources */, + 6888AA0C29AA1F5900C0FFB5 /* AutoLayouts.swift in Sources */, + 6888AA0629AA13BF00C0FFB5 /* iOSDevCenters+GIF.swift in Sources */, + 6888A9D229AA115000C0FFB5 /* ViewController.swift in Sources */, + 6888A9CE29AA115000C0FFB5 /* AppDelegate.swift in Sources */, + 6888AA0E29AA204E00C0FFB5 /* BaseViewController.swift in Sources */, + 6888AA0A29AA1AD500C0FFB5 /* HomeScreenController.swift in Sources */, + 68CDE34629AD5FA200C43B19 /* ScanQrController.swift in Sources */, + 68D9D3BA29AE2D3A00EB66C7 /* ValidQrCode.swift in Sources */, + 6888AA1229AA20BD00C0FFB5 /* PushViewController.swift in Sources */, + 68D9D3C029AE380500EB66C7 /* AirdropViewModel.swift in Sources */, + 68D9D3D529AF08D000EB66C7 /* Token Amount.swift in Sources */, + 6888A9D029AA115000C0FFB5 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9DF29AA115400C0FFB5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6888A9E829AA115400C0FFB5 /* fanexTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6888A9E929AA115400C0FFB5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6888A9F229AA115400C0FFB5 /* fanexUITests.swift in Sources */, + 6888A9F429AA115400C0FFB5 /* fanexUITestsLaunchTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6888A9E529AA115400C0FFB5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6888A9C929AA115000C0FFB5 /* fanex */; + targetProxy = 6888A9E429AA115400C0FFB5 /* PBXContainerItemProxy */; + }; + 6888A9EF29AA115400C0FFB5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6888A9C929AA115000C0FFB5 /* fanex */; + targetProxy = 6888A9EE29AA115400C0FFB5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 6888A9D329AA115000C0FFB5 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6888A9D429AA115000C0FFB5 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6888A9DB29AA115400C0FFB5 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6888A9DC29AA115400C0FFB5 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 6888A9F529AA115400C0FFB5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 6888A9F629AA115400C0FFB5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6888A9F829AA115400C0FFB5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 34C5E4241DA5791795FF6DD7 /* Pods-fanex.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = fanex/fanex.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = YH2M8264LW; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = fanex/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Fanex; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.fanex.hack.flow; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 6888A9F929AA115400C0FFB5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 404189C323C534268C620E78 /* Pods-fanex.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = fanex/fanex.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = YH2M8264LW; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = fanex/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Fanex; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.fanex.hack.flow; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 6888A9FB29AA115400C0FFB5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 93F09ED6AA80ED071C96B599 /* Pods-fanexTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = XZUFA65CWA; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = de.fanex.app.fanexTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/fanex.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/fanex"; + }; + name = Debug; + }; + 6888A9FC29AA115400C0FFB5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D7918F0805161AD3CC922C8C /* Pods-fanexTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = XZUFA65CWA; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = de.fanex.app.fanexTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/fanex.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/fanex"; + }; + name = Release; + }; + 6888A9FE29AA115400C0FFB5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D641B00C7182A059F6240FC7 /* Pods-fanex-fanexUITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = XZUFA65CWA; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = de.fanex.app.fanexUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = fanex; + }; + name = Debug; + }; + 6888A9FF29AA115400C0FFB5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 48BB3DF09EFC1425F8288394 /* Pods-fanex-fanexUITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = XZUFA65CWA; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = de.fanex.app.fanexUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = fanex; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6888A9C529AA115000C0FFB5 /* Build configuration list for PBXProject "fanex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6888A9F529AA115400C0FFB5 /* Debug */, + 6888A9F629AA115400C0FFB5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6888A9F729AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6888A9F829AA115400C0FFB5 /* Debug */, + 6888A9F929AA115400C0FFB5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6888A9FA29AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanexTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6888A9FB29AA115400C0FFB5 /* Debug */, + 6888A9FC29AA115400C0FFB5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6888A9FD29AA115400C0FFB5 /* Build configuration list for PBXNativeTarget "fanexUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6888A9FE29AA115400C0FFB5 /* Debug */, + 6888A9FF29AA115400C0FFB5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 6888AA1B29AAB5E800C0FFB5 /* XCRemoteSwiftPackageReference "fcl-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/outblock/fcl-swift.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.1.0; + }; + }; + 6888AA2629ABEB6500C0FFB5 /* XCRemoteSwiftPackageReference "EKTabBar" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/emvakar/EKTabBar.git"; + requirement = { + branch = main; + kind = branch; + }; + }; + 68D9D3AC29ADF8A500EB66C7 /* XCRemoteSwiftPackageReference "tweetview-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/estampworld/tweetview-ios"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 6888AA1C29AAB5E800C0FFB5 /* FCL */ = { + isa = XCSwiftPackageProductDependency; + package = 6888AA1B29AAB5E800C0FFB5 /* XCRemoteSwiftPackageReference "fcl-swift" */; + productName = FCL; + }; + 6888AA2729ABEB6500C0FFB5 /* EKTabBarController */ = { + isa = XCSwiftPackageProductDependency; + package = 6888AA2629ABEB6500C0FFB5 /* XCRemoteSwiftPackageReference "EKTabBar" */; + productName = EKTabBarController; + }; + 68D9D3AD29ADF8A500EB66C7 /* TweetView */ = { + isa = XCSwiftPackageProductDependency; + package = 68D9D3AC29ADF8A500EB66C7 /* XCRemoteSwiftPackageReference "tweetview-ios" */; + productName = TweetView; + }; +/* End XCSwiftPackageProductDependency section */ + +/* Begin XCVersionGroup section */ + 6888A9D629AA115000C0FFB5 /* fanex.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 6888A9D729AA115000C0FFB5 /* fanex.xcdatamodel */, + ); + currentVersion = 6888A9D729AA115000C0FFB5 /* fanex.xcdatamodel */; + path = fanex.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = 6888A9C229AA115000C0FFB5 /* Project object */; +} diff --git a/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000..bd4b9735 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist b/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..c1f1e509 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcodeproj/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + fanex.xcscheme_^#shared#^_ + + orderHint + 95 + + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/contents.xcworkspacedata b/one-and-half-nibble/MobileApp/fanex.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1cd60b64 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/swiftpm/Package.resolved b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..69020461 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,131 @@ +{ + "pins" : [ + { + "identity" : "bigint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/attaswift/BigInt.git", + "state" : { + "revision" : "0ed110f7555c34ff468e72e1686e59721f2b0da6", + "version" : "5.3.0" + } + }, + { + "identity" : "cryptoswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", + "state" : { + "revision" : "19b3c3ceed117c5cc883517c4e658548315ba70b", + "version" : "1.6.0" + } + }, + { + "identity" : "ektabbar", + "kind" : "remoteSourceControl", + "location" : "https://github.com/emvakar/EKTabBar.git", + "state" : { + "branch" : "main", + "revision" : "994c0724b08dc47c2fdda1f2199d92819105dcb4" + } + }, + { + "identity" : "fcl-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/outblock/fcl-swift.git", + "state" : { + "revision" : "393783732f0eef171469b8239683536df73b7450", + "version" : "0.1.0" + } + }, + { + "identity" : "flow-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/outblock/flow-swift.git", + "state" : { + "revision" : "e1721bea71d8a27e209398f5a740ef02f6c6c920", + "version" : "0.3.1" + } + }, + { + "identity" : "gzipswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/1024jp/GzipSwift", + "state" : { + "revision" : "7a7f17761c76a932662ab77028a4329f67d645a4", + "version" : "5.2.0" + } + }, + { + "identity" : "promisekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mxcl/PromiseKit.git", + "state" : { + "revision" : "5b90042bb419e6f3b1719c973f37e1eab46ce991", + "version" : "6.21.0" + } + }, + { + "identity" : "secp256k1.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Boilertalk/secp256k1.swift.git", + "state" : { + "revision" : "cd187c632fb812fd93711a9f7e644adb7e5f97f0", + "version" : "0.1.7" + } + }, + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "f222cbdf325885926566172f6f5f06af95473158", + "version" : "5.6.0" + } + }, + { + "identity" : "starscream", + "kind" : "remoteSourceControl", + "location" : "https://github.com/daltoniam/Starscream", + "state" : { + "revision" : "e6b65c6d9077ea48b4a7bdda8994a1d3c6969c8d", + "version" : "3.1.1" + } + }, + { + "identity" : "swift-nio-zlib-support", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-zlib-support.git", + "state" : { + "revision" : "37760e9a52030bb9011972c5213c3350fa9d41fd", + "version" : "1.0.0" + } + }, + { + "identity" : "tweetview-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/estampworld/tweetview-ios", + "state" : { + "revision" : "acc4f46c4cb4617fa3eb044c2bee5a7b1796506a", + "version" : "1.0.0" + } + }, + { + "identity" : "walletconnectswiftv2", + "kind" : "remoteSourceControl", + "location" : "https://github.com/WalletConnect/WalletConnectSwiftV2", + "state" : { + "revision" : "41966b44442a0f77378ab55f70d89ec3f1c35c66", + "version" : "1.0.6" + } + }, + { + "identity" : "web3.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/WalletConnect/Web3.swift", + "state" : { + "revision" : "a628f094f8088ec72a95792de18eeea24b997462", + "version" : "1.0.0" + } + } + ], + "version" : 2 +} diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/WorkspaceSettings.xcsettings b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..bbfef027 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,14 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + ShowSharedSchemesAutomaticallyEnabled + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000..e093fe74 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..6f90dfd3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex.xcworkspace/xcuserdata/technosh.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,387 @@ + + + + + SchemeUserState + + Demo (Playground) 1.xcscheme + + isShown + + orderHint + 12 + + Demo (Playground) 10.xcscheme + + isShown + + orderHint + 39 + + Demo (Playground) 11.xcscheme + + isShown + + orderHint + 40 + + Demo (Playground) 12.xcscheme + + isShown + + orderHint + 47 + + Demo (Playground) 13.xcscheme + + isShown + + orderHint + 48 + + Demo (Playground) 14.xcscheme + + isShown + + orderHint + 49 + + Demo (Playground) 15.xcscheme + + isShown + + orderHint + 96 + + Demo (Playground) 16.xcscheme + + isShown + + orderHint + 97 + + Demo (Playground) 17.xcscheme + + isShown + + orderHint + 98 + + Demo (Playground) 2.xcscheme + + isShown + + orderHint + 13 + + Demo (Playground) 3.xcscheme + + isShown + + orderHint + 20 + + Demo (Playground) 4.xcscheme + + isShown + + orderHint + 21 + + Demo (Playground) 5.xcscheme + + isShown + + orderHint + 22 + + Demo (Playground) 6.xcscheme + + isShown + + orderHint + 32 + + Demo (Playground) 7.xcscheme + + isShown + + orderHint + 33 + + Demo (Playground) 8.xcscheme + + isShown + + orderHint + 34 + + Demo (Playground) 9.xcscheme + + isShown + + orderHint + 38 + + Demo (Playground).xcscheme + + isShown + + orderHint + 11 + + PromiseKit (Playground) 1.xcscheme + + isShown + + orderHint + 15 + + PromiseKit (Playground) 10.xcscheme + + isShown + + orderHint + 36 + + PromiseKit (Playground) 11.xcscheme + + isShown + + orderHint + 37 + + PromiseKit (Playground) 12.xcscheme + + isShown + + orderHint + 44 + + PromiseKit (Playground) 13.xcscheme + + isShown + + orderHint + 45 + + PromiseKit (Playground) 14.xcscheme + + isShown + + orderHint + 46 + + PromiseKit (Playground) 15.xcscheme + + isShown + + orderHint + 102 + + PromiseKit (Playground) 16.xcscheme + + isShown + + orderHint + 103 + + PromiseKit (Playground) 17.xcscheme + + isShown + + orderHint + 104 + + PromiseKit (Playground) 2.xcscheme + + isShown + + orderHint + 16 + + PromiseKit (Playground) 3.xcscheme + + isShown + + orderHint + 17 + + PromiseKit (Playground) 4.xcscheme + + isShown + + orderHint + 18 + + PromiseKit (Playground) 5.xcscheme + + isShown + + orderHint + 19 + + PromiseKit (Playground) 6.xcscheme + + isShown + + orderHint + 26 + + PromiseKit (Playground) 7.xcscheme + + isShown + + orderHint + 27 + + PromiseKit (Playground) 8.xcscheme + + isShown + + orderHint + 28 + + PromiseKit (Playground) 9.xcscheme + + isShown + + orderHint + 35 + + PromiseKit (Playground).xcscheme + + isShown + + orderHint + 14 + + SnapKitPlayground (Playground) 1.xcscheme + + isShown + + orderHint + 9 + + SnapKitPlayground (Playground) 10.xcscheme + + isShown + + orderHint + 42 + + SnapKitPlayground (Playground) 11.xcscheme + + isShown + + orderHint + 43 + + SnapKitPlayground (Playground) 12.xcscheme + + isShown + + orderHint + 50 + + SnapKitPlayground (Playground) 13.xcscheme + + isShown + + orderHint + 51 + + SnapKitPlayground (Playground) 14.xcscheme + + isShown + + orderHint + 52 + + SnapKitPlayground (Playground) 15.xcscheme + + isShown + + orderHint + 99 + + SnapKitPlayground (Playground) 16.xcscheme + + isShown + + orderHint + 100 + + SnapKitPlayground (Playground) 17.xcscheme + + isShown + + orderHint + 101 + + SnapKitPlayground (Playground) 2.xcscheme + + isShown + + orderHint + 10 + + SnapKitPlayground (Playground) 3.xcscheme + + isShown + + orderHint + 23 + + SnapKitPlayground (Playground) 4.xcscheme + + isShown + + orderHint + 24 + + SnapKitPlayground (Playground) 5.xcscheme + + isShown + + orderHint + 25 + + SnapKitPlayground (Playground) 6.xcscheme + + isShown + + orderHint + 29 + + SnapKitPlayground (Playground) 7.xcscheme + + isShown + + orderHint + 30 + + SnapKitPlayground (Playground) 8.xcscheme + + isShown + + orderHint + 31 + + SnapKitPlayground (Playground) 9.xcscheme + + isShown + + orderHint + 41 + + SnapKitPlayground (Playground).xcscheme + + isShown + + orderHint + 8 + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/ActionsController.swift b/one-and-half-nibble/MobileApp/fanex/ActionsController.swift new file mode 100644 index 00000000..323a9e96 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ActionsController.swift @@ -0,0 +1,106 @@ +// +// ActionsController.swift +// fanex +// +// Created by aman shah on 01/03/23. +// + +import Foundation +import UIKit +import PopupDialog +class ActionsController : UIViewController { + + + var imageArr = ["card1" ,"card2" ,"twitterAction", "card3"] + @IBOutlet weak var caroselCollection: UICollectionView! + + + @IBOutlet weak var carouselViewContainer: UIView! + @IBOutlet weak var headingLabel: UILabel! + override func viewDidLoad() { + super.viewDidLoad() + caroselCollection.register(UINib(nibName: "CarouselCollectionViewCell", bundle: .main), forCellWithReuseIdentifier: "CarouselCollectionViewCell") + + caroselCollection.delegate = self + caroselCollection.dataSource = self + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + } + + func createCarouselView () { + + } +} +extension ActionsController : UICollectionViewDelegate , UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + 3 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = caroselCollection.dequeueReusableCell(withReuseIdentifier: "CarouselCollectionViewCell", for: indexPath) as? CarouselCollectionViewCell else { + return CarouselCollectionViewCell() + } + cell.image.image = UIImage(named: imageArr[indexPath.row]) + cell.image.layer.cornerRadius = 50 + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if(indexPath.row == 0){ + // click on 1st card + let vc = ScanQrController() + self.present(vc, animated: true, completion: nil) + }else if(indexPath.row == 1) { + // click on 2nd card + let vc = ScanQrController() + self.present(vc, animated: true, completion: nil) + }else if(indexPath.row == 2) { + let vc = TweetViewController() + vc.twitterVCDelegate = self + self.present(vc, animated: true, completion: nil) + } + else { + debugPrint("print something") + } + } + + } +extension ActionsController : TweetControllerDismiss { + func dismiss() { + let title = "\(50) Fanex points Recieved" + let message = "Keep an eye on upcoming tweets for more rewards" + let image = UIImage(named: "congratulationsImage") + + // Create the dialog + let popup = PopupDialog(title: title, message: message, image: image) + + // Create buttons + let buttonOne = CancelButton(title: "Hell Yeahh!!") { + print("Hell Yeahh!!") + + } + + // This button will not the dismiss the dialog + // let buttonTwo = DefaultButton(title: "ADMIRE CAR", dismissOnTap: false) { + // print("What a beauty!") + // } + // + // let buttonThree = DefaultButton(title: "BUY CAR", height: 60) { + // print("Ah, maybe next time :)") + // } + + // Add buttons to dialog + // Alternatively, you can use popup.addButton(buttonOne) + // to add a single button + popup.addButtons([buttonOne]) + + // Present dialog + self.present(popup, animated: true, completion: nil) + } +} + + + diff --git a/one-and-half-nibble/MobileApp/fanex/ApiHandler.swift b/one-and-half-nibble/MobileApp/fanex/ApiHandler.swift new file mode 100644 index 00000000..c619e4c0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ApiHandler.swift @@ -0,0 +1,38 @@ +import Foundation +import Combine + +enum APIFailureCondition: Error { + case invalidServerResponse +} + +struct Response { + + let value: T + let response: URLResponse +} + +let APIManager = ServiceManager.shared + +class ServiceManager { + + static let shared = ServiceManager() + + func callAPI(_ url: URL) -> AnyPublisher, Error> { + + return URLSession.shared.dataTaskPublisher(for: url) + .tryMap { result -> Response in + + guard let httpResponse = result.response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + print("status code for api response : \((result.response as? HTTPURLResponse)?.statusCode ?? 200)") + throw APIFailureCondition.invalidServerResponse + } + + let decoder = JSONDecoder() + let value = try decoder.decode(T.self, from: result.data) + return Response(value: value, response: result.response) + } + .receive(on: RunLoop.main) + .eraseToAnyPublisher() + } +} + diff --git a/one-and-half-nibble/MobileApp/fanex/AppDelegate.swift b/one-and-half-nibble/MobileApp/fanex/AppDelegate.swift new file mode 100644 index 00000000..d0074199 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/AppDelegate.swift @@ -0,0 +1,104 @@ +// +// AppDelegate.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import UIKit +import CoreData +import FCL +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + FlowManager.shared.setup() + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = + [:]) -> Bool { + debugPrint(url) + return true + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + // MARK: - Core Data stack + + lazy var persistentContainer: NSPersistentContainer = { + /* + The persistent container for the application. This implementation + creates and returns a container, having loaded the store for the + application to it. This property is optional since there are legitimate + error conditions that could cause the creation of the store to fail. + */ + let container = NSPersistentContainer(name: "fanex") + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + return container + }() + + // MARK: - Core Data Saving support +// func application( +// _ app: UIApplication, +// open url: URL, +// options: [UIApplication.OpenURLOptionsKey: Any] = [:] +// ) -> Bool { +// fcl.application(open: url) +// return true +// } + +// func application( +// _ application: UIApplication, +// continue userActivity: NSUserActivity, +// restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void +// ) -> Bool { +// fcl.continueForLinks(userActivity) +// return true +// } + func saveContext () { + let context = persistentContainer.viewContext + if context.hasChanges { + do { + try context.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nserror = error as NSError + fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + } + } + } + +} + diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/1_Large.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/1_Large.png new file mode 100644 index 00000000..b2f6957c Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/1_Large.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/Contents.json new file mode 100644 index 00000000..ad45ffd6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Large.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "1_Large.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/1_Small.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/1_Small.png new file mode 100644 index 00000000..ec976f72 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/1_Small.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/Contents.json new file mode 100644 index 00000000..ec93cd15 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/1_Small.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "1_Small.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/2.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/2.png new file mode 100644 index 00000000..77a9bd3b Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/2.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/Contents.json new file mode 100644 index 00000000..c6348dd8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_Large.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/2_small.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/2_small.png new file mode 100644 index 00000000..2f550067 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/2_small.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/Contents.json new file mode 100644 index 00000000..f00e4af9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/2_small.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "2_small.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/3_Large.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/3_Large.png new file mode 100644 index 00000000..ff20a20a Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/3_Large.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/Contents.json new file mode 100644 index 00000000..c4eff80c --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Large.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "3_Large.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/3_Small.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/3_Small.png new file mode 100644 index 00000000..58718f84 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/3_Small.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/Contents.json new file mode 100644 index 00000000..71f3d424 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/3_Small.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "3_Small.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AccentColor.colorset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AppIcon.appiconset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..13613e3e --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/1.colorset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/1.colorset/Contents.json new file mode 100644 index 00000000..83b1fbf4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/1.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0.365", + "green" : "0.996", + "red" : "0.929" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0.365", + "green" : "0.996", + "red" : "0.929" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/2.colorset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/2.colorset/Contents.json new file mode 100644 index 00000000..a94c7ea9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/2.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.486", + "green" : "0.878", + "red" : "0.549" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.486", + "green" : "0.878", + "red" : "0.549" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/3.colorset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/3.colorset/Contents.json new file mode 100644 index 00000000..29a6c1a7 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/3.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.020", + "green" : "0.361", + "red" : "0.949" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.020", + "green" : "0.361", + "red" : "0.949" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/1.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/1.png new file mode 100644 index 00000000..c9337de5 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/1.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/Contents.json new file mode 100644 index 00000000..38ee28b6 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/2.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/2.png new file mode 100644 index 00000000..3b48dadf Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/2.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/Contents.json new file mode 100644 index 00000000..c6348dd8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/3.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/3.png new file mode 100644 index 00000000..74507ea6 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/3.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/Contents.json new file mode 100644 index 00000000..53eb8f19 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/card3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/Contents.json new file mode 100644 index 00000000..034233e9 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "congratulationsImage.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/congratulationsImage.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/congratulationsImage.png new file mode 100644 index 00000000..964d3803 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/congratulationsImage.imageset/congratulationsImage.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/Contents.json new file mode 100644 index 00000000..a92cbea2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/Contents.json @@ -0,0 +1,12 @@ +{ + "data" : [ + { + "filename" : "fanex logo.gif", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/fanex logo.gif b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/fanex logo.gif new file mode 100644 index 00000000..cec12f2e Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/fanex logo.dataset/fanex logo.gif differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/Contents.json new file mode 100644 index 00000000..f55d4a45 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "profileAvator.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/profileAvator.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/profileAvator.png new file mode 100644 index 00000000..7f613eaf Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/profileAvator.imageset/profileAvator.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/Contents.json new file mode 100644 index 00000000..9ddfd039 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "superFan NFt.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/superFan NFt.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/superFan NFt.png new file mode 100644 index 00000000..1e09e529 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/superFan NFt.imageset/superFan NFt.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/Contents.json new file mode 100644 index 00000000..9b4f315e --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "twitterAction.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/twitterAction.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/twitterAction.png new file mode 100644 index 00000000..b38c9f9b Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/twitterAction.imageset/twitterAction.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/Contents.json new file mode 100644 index 00000000..95bca7df --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/Contents.json @@ -0,0 +1,12 @@ +{ + "data" : [ + { + "filename" : "waiting-setting-account.gif", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/waiting-setting-account.gif b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/waiting-setting-account.gif new file mode 100644 index 00000000..d0fabd52 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/waiting-setting-account.dataset/waiting-setting-account.gif differ diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/Contents.json b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/Contents.json new file mode 100644 index 00000000..9d8f2d17 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "wallet.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/wallet.png b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/wallet.png new file mode 100644 index 00000000..d4987723 Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/Assets.xcassets/wallet.imageset/wallet.png differ diff --git a/one-and-half-nibble/MobileApp/fanex/AutoLayouts.swift b/one-and-half-nibble/MobileApp/fanex/AutoLayouts.swift new file mode 100644 index 00000000..87753d9a --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/AutoLayouts.swift @@ -0,0 +1,115 @@ +// +// AutoLayouts.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import Foundation +import UIKit + +// Reference Video: https://youtu.be/iqpAP7s3b-8 +// swiftlint:disable all +extension UIView { + + @discardableResult + func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) -> AnchoredConstraints { + + translatesAutoresizingMaskIntoConstraints = false + var anchoredConstraints = AnchoredConstraints() + + if let top = top { + anchoredConstraints.top = topAnchor.constraint(equalTo: top, constant: padding.top) + } + + if let leading = leading { + anchoredConstraints.leading = leadingAnchor.constraint(equalTo: leading, constant: padding.left) + } + + if let bottom = bottom { + anchoredConstraints.bottom = bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom) + } + + if let trailing = trailing { + anchoredConstraints.trailing = trailingAnchor.constraint(equalTo: trailing, constant: -padding.right) + } + + if size.width != 0 { + anchoredConstraints.width = widthAnchor.constraint(equalToConstant: size.width) + } + + if size.height != 0 { + anchoredConstraints.height = heightAnchor.constraint(equalToConstant: size.height) + } + + [anchoredConstraints.top, anchoredConstraints.leading, anchoredConstraints.bottom, anchoredConstraints.trailing, anchoredConstraints.width, anchoredConstraints.height].forEach {$0?.isActive = true} + + return anchoredConstraints + } + + func fillSuperview(padding: UIEdgeInsets = .zero) { + translatesAutoresizingMaskIntoConstraints = false + if let superviewTopAnchor = superview?.topAnchor { + topAnchor.constraint(equalTo: superviewTopAnchor, constant: padding.top).isActive = true + } + + if let superviewBottomAnchor = superview?.bottomAnchor { + bottomAnchor.constraint(equalTo: superviewBottomAnchor, constant: -padding.bottom).isActive = true + } + + if let superviewLeadingAnchor = superview?.leadingAnchor { + leadingAnchor.constraint(equalTo: superviewLeadingAnchor, constant: padding.left).isActive = true + } + + if let superviewTrailingAnchor = superview?.trailingAnchor { + trailingAnchor.constraint(equalTo: superviewTrailingAnchor, constant: -padding.right).isActive = true + } + } + + func centerInSuperview(size: CGSize = .zero) { + translatesAutoresizingMaskIntoConstraints = false + if let superviewCenterXAnchor = superview?.centerXAnchor { + centerXAnchor.constraint(equalTo: superviewCenterXAnchor).isActive = true + } + + if let superviewCenterYAnchor = superview?.centerYAnchor { + centerYAnchor.constraint(equalTo: superviewCenterYAnchor).isActive = true + } + + if size.width != 0 { + widthAnchor.constraint(equalToConstant: size.width).isActive = true + } + + if size.height != 0 { + heightAnchor.constraint(equalToConstant: size.height).isActive = true + } + } + + func centerXInSuperview() { + translatesAutoresizingMaskIntoConstraints = false + if let superViewCenterXAnchor = superview?.centerXAnchor { + centerXAnchor.constraint(equalTo: superViewCenterXAnchor).isActive = true + } + } + + func centerYInSuperview() { + translatesAutoresizingMaskIntoConstraints = false + if let centerY = superview?.centerYAnchor { + centerYAnchor.constraint(equalTo: centerY).isActive = true + } + } + + func constrainWidth(constant: CGFloat) { + translatesAutoresizingMaskIntoConstraints = false + widthAnchor.constraint(equalToConstant: constant).isActive = true + } + + func constrainHeight(constant: CGFloat) { + translatesAutoresizingMaskIntoConstraints = false + heightAnchor.constraint(equalToConstant: constant).isActive = true + } +} + +struct AnchoredConstraints { + var top, leading, bottom, trailing, width, height: NSLayoutConstraint? +} diff --git a/one-and-half-nibble/MobileApp/fanex/Base.lproj/LaunchScreen.storyboard b/one-and-half-nibble/MobileApp/fanex/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..865e9329 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/Base.lproj/Main.storyboard b/one-and-half-nibble/MobileApp/fanex/Base.lproj/Main.storyboard new file mode 100644 index 00000000..5d466509 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Base.lproj/Main.storyboard @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/BaseViewController.swift b/one-and-half-nibble/MobileApp/fanex/BaseViewController.swift new file mode 100644 index 00000000..a5ce69f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/BaseViewController.swift @@ -0,0 +1,19 @@ +//// +//// BaseViewController.swift +//// fanex +//// +//// Created by aman shah on 25/02/23. +//// +// +//import Foundation +// +//import UIKit +// +//class BaseViewController: UIViewController { +// +// func toogleTabbar(hide: Bool) { +// guard let tabBar = tabBarController as? Tabbarcontoller else { return } +// tabBar.toggle(hide: hide) +// } +//} +// diff --git a/one-and-half-nibble/MobileApp/fanex/FCLDelegate.swift b/one-and-half-nibble/MobileApp/fanex/FCLDelegate.swift new file mode 100644 index 00000000..88bb1af5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/FCLDelegate.swift @@ -0,0 +1,21 @@ +// +// FCLDelegate.swift +// fanex +// +// Created by aman shah on 26/02/23. +// + + +import AuthenticationServices +import Foundation + +public protocol FCLDelegate { + func showLoading() + func hideLoading() +} + +extension FCLDelegate { + func presentationAnchor() -> ASPresentationAnchor { + return ASPresentationAnchor() + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/FloatingBarView.swift b/one-and-half-nibble/MobileApp/fanex/FloatingBarView.swift new file mode 100644 index 00000000..c7d90c90 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/FloatingBarView.swift @@ -0,0 +1,121 @@ +// +// FloatingBarView.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import Foundation +import UIKit + +protocol FloatingBarViewDelegate: AnyObject { + func did(selectindex: Int) +} + +class FloatingBarView: UIView { + + weak var delegate: FloatingBarViewDelegate? + + var buttons: [UIButton] = [] + + init(_ items: [String]) { + super.init(frame: .zero) + backgroundColor = .white + + setupStackView(items) + updateUI(selectedIndex: 0) + } + + override func layoutSubviews() { + super.layoutSubviews() + + layer.cornerRadius = bounds.height / 2 + + layer.shadowPath = UIBezierPath(rect: bounds).cgPath + layer.shadowColor = UIColor.black.cgColor + layer.shadowOpacity = 0.1 + layer.shadowOffset = .zero + layer.shadowRadius = bounds.height / 2 + } + + func setupStackView(_ items: [String]) { + for (index, item) in items.enumerated() { + let symbolConfig = UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .medium) + let normalImage = UIImage(systemName: item, withConfiguration: symbolConfig) + let selectedImage = UIImage(systemName: "\(item).fill", withConfiguration: symbolConfig) + let button = createButton(normalImage: normalImage!, selectedImage: selectedImage!, index: index) + buttons.append(button) + } + + let stackView = UIStackView(arrangedSubviews: buttons) + + addSubview(stackView) + stackView.fillSuperview(padding: .init(top: 0, left: 16, bottom: 0, right: 16)) + } + + func createButton(normalImage: UIImage, selectedImage: UIImage, index: Int) -> UIButton { + let button = UIButton() + button.constrainWidth(constant: 60) + button.constrainHeight(constant: 60) + button.setImage(normalImage, for: .normal) + button.setImage(selectedImage, for: .selected) + button.tag = index + button.adjustsImageWhenHighlighted = false + button.addTarget(self, action: #selector(changeTab(_:)), for: .touchUpInside) + return button + } + + @objc + func changeTab(_ sender: UIButton) { + sender.pulse() + delegate?.did(selectindex: sender.tag) + updateUI(selectedIndex: sender.tag) + } + + func updateUI(selectedIndex: Int) { + for (index, button) in buttons.enumerated() { + if index == selectedIndex { + button.isSelected = true + if index == 0 { + button.tintColor = .red + } else { + button.tintColor = .black + } + } else { + button.isSelected = false + button.tintColor = .gray + } + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func toggle(hide: Bool) { + if !hide { + isHidden = hide + } + + UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 1, + initialSpringVelocity: 0.5, options: .curveEaseOut, animations: { + self.alpha = hide ? 0 : 1 + self.transform = hide ? CGAffineTransform(translationX: 0, y: 10) : .identity + }) { (_) in + if hide { + self.isHidden = hide + } + } + } +} + +extension UIButton { + + func pulse() { + let pulse = CASpringAnimation(keyPath: "transform.scale") + pulse.duration = 0.15 + pulse.fromValue = 0.95 + pulse.toValue = 1.0 + layer.add(pulse, forKey: "pulse") + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Flow/FanexCadence.swift b/one-and-half-nibble/MobileApp/fanex/Flow/FanexCadence.swift new file mode 100644 index 00000000..b496f8f4 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Flow/FanexCadence.swift @@ -0,0 +1,73 @@ +// +// FanexCadence.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import Foundation +class FanexCadence { + + static let initAccount = """ + import FanxToken from 0x3d1a73afefe2d7f8 + transaction { + prepare(account: AuthAccount) { + let vaultA <- FanxToken.createEmptyVault(); + + account.save<@FanxToken.Vault>(<-vaultA, to: /storage/FanxTokenVault); + + // Deposit function exported + let ReceiverRef = account.link<&FanxToken.Vault{FanxToken.Receiver}>(/public/FanxTokenReceiver, target: /storage/FanxTokenVault); + + let BalanceRef = account.link<&FanxToken.Vault{FanxToken.Balance}>(/public/FanxTokenBalance, target: /storage/FanxTokenVault) + + log("References Created") + } + } +""" + static let checkInit = + """ + import FanxToken from 0xFanex + + import FanxToken from 0x3d1a73afefe2d7f8 + + pub fun main(address: Address): Bool { + let vaultRef = getAccount(address) + .getCapability<&FanxToken.Vault{FanxToken.Balance}>(/public/FanxTokenBalance) + .check() + + return vaultRef + } + """ + static let getBalance = + """ + import FanxToken from 0x3d1a73afefe2d7f8 + pub fun main(account: Address): UInt64 { + let vaultRef = getAccount(account) + .getCapability(/public/FanxTokenBalance) + .borrow<&FanxToken.Vault{FanxToken.Balance}>() + ?? panic("Could not borrow account reference to the vault") + + return vaultRef.balance + } + """ + static let depositMoney = +""" + import FanxToken from 0x3d1a73afefe2d7f8 + transaction(amount: UInt64) { + prepare(account: AuthAccount) { + let tempVault <- FanxToken.createNonEmptyVault(balance: amount); + + let vaultRef = account.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault"); + + vaultRef.deposit(from: <-tempVault); + + log("Tokens despoited in account") + } + } +""" + + + +} diff --git a/one-and-half-nibble/MobileApp/fanex/Flow/FlowManger.swift b/one-and-half-nibble/MobileApp/fanex/Flow/FlowManger.swift new file mode 100644 index 00000000..f590c4a1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Flow/FlowManger.swift @@ -0,0 +1,189 @@ +// +// FlowClient.swift +// MonsterMaker +// +// Created by Hao Fu on 3/11/2022. +// + +import FCL +import Flow +import Foundation +import UIKit +import Combine +import SafariServices + +class FlowManager: NSObject ,ObservableObject { + static let shared = FlowManager() + + @Published + var pendingTx: String? = nil + @Published var address: String = "" + + @Published var preAuthz: String = "" + + @Published var provider: FCL.Provider = fcl.currentProvider ?? .lilico + + @Published var env: Flow.ChainID = fcl.currentEnv + + @Published var walletList = FCL.Provider.getEnvCases() + + @MainActor + @Published var isShowWeb: Bool = false + + @Published var isPresented: Bool = false + + @Published var isAccountProof: Bool? + + @Published var isUserMessageProof: Bool? + + @Published var accountLookup: String = "" + + @Published var currentObject: String = "" + + @Published var message: String = "foo bar" + + @Published var balance: String = "" + private var cancellables = Set() + + func subscribeTransaction(txId: String) { + Task { + do { + let id = Flow.ID(hex: txId) + DispatchQueue.main.async { + self.pendingTx = txId + } + _ = try await id.onceSealed() + await UIImpactFeedbackGenerator(style: .light).impactOccurred() + DispatchQueue.main.async { + self.pendingTx = nil + } + } catch { + DispatchQueue.main.async { + self.pendingTx = nil + } + } + } + } + + func setup() { + let defaultProvider: FCL.Provider = .blocto + let defaultNetwork: Flow.ChainID = .testnet + let bloctoSDKAppId = "5595da5e-43a7-4001-956a-45bc5161e095" + let accountProof = FCL.Metadata.AccountProofConfig(appIdentifier: "fanex app") + let walletConnect = FCL.Metadata.WalletConnectConfig(urlScheme: "fanex-app://", projectID: "e41f3acff8f7ad5896b0b689e35f3526") +// let bloctoWalletProvider = try BloctoWalletProvider( +// bloctoAppIdentifier: bloctoSDKAppId, +// window: nil, +// network: .testnet, +// logging: true +// ) + let metadata = FCL.Metadata(appName: "fanex app", + appDescription: "Expirence for a true fan", + appIcon: URL(string: "https://ibb.co/prYRtJ3")!, + location: URL(string: "https://571d-2401-4900-1c19-c93d-ac68-7414-aee7-32bc.in.ngrok.io")!, + accountProof: accountProof, + walletConnectConfig: walletConnect) + + fcl.config(metadata: metadata, + env: defaultNetwork, + provider: defaultProvider) + + + fcl.config + .put("0xFanex", value: "0x3d1a73afefe2d7f8") + + fcl.$currentUser + .receive(on: DispatchQueue.main) + .sink { user in + self.address = user?.addr.hex ?? "" + if let user = user { + print("<==== Current User =====>") + print(user) + self.verifyAccountProof() + } else { + print("<==== No User =====>") + } + }.store(in: &cancellables) + + fcl.$currentEnv + .receive(on: DispatchQueue.main) + .sink { env in + self.env = env + self.walletList = FCL.Provider.getEnvCases(env: env) + }.store(in: &cancellables) + + fcl.$currentProvider + .receive(on: DispatchQueue.main) + .sink { provider in + if let provider { + self.provider = provider + } + }.store(in: &cancellables) + +// fcl.delegate = self + + + } +// func authenticate() { +// fcl.authenticate() +// .receive(on: DispatchQueue.main) +// .sink { result in +// print(result) +// } receiveValue: { response in +// print(response) +// } +// .store(in: &cancellables) +// } + + +// func checkCollectionVault() async throws -> Bool { +// guard let address = fcl.currentUser?.addr else { +// throw FCLError.unauthenticated +// } +// +// do { +// let result: Bool = try await fcl.query(script: MonsterMakerCadence.checkInit, +// args: [.address(address)]).decode() +// return result +// } catch { +// print(error) +// throw error +// } +// } + func verifyAccountProof() { + Task { + do { + let result = try await fcl.verifyAccountProof() + print("verifyAccountProof ==> \(result)") + await MainActor.run { + isAccountProof = result + } + } catch { + print(error) + await MainActor.run { + isAccountProof = false + } + } + } + } + func authn() async { + do { + _ = try await fcl.reauthenticate() + } catch { + print(error) + } + } + +} + +extension FlowManager: FCLDelegate { + func showLoading() { +// ProgressHUD.show("Loading...") + debugPrint("loading .......") + } + + func hideLoading() { +// ProgressHUD.dismiss() + debugPrint("hope it gets connected") + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/HomeScreenController.swift b/one-and-half-nibble/MobileApp/fanex/HomeScreenController.swift new file mode 100644 index 00000000..d1e67949 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/HomeScreenController.swift @@ -0,0 +1,144 @@ +//// +//// homeScreenController.swift +//// fanex +//// +//// Created by aman shah on 25/02/23. +//// +// +//import Foundation +//import UIKit +//class HomeScreenController :BaseViewController { +// +// lazy var button: UIButton = { +// let button = UIButton() +// button.setTitle("Push new VC", for: .normal) +// button.addTarget(self, action: #selector(handeAction(_:)), for: .touchUpInside) +// button.backgroundColor = .systemBlue +// button.layer.cornerRadius = 5 +// +// button.titleEdgeInsets = .init(top: 8, left: 8, bottom: 8, right: 8) +// button.constrainWidth(constant: 150) +// return button +// }() +// +// override func viewDidLoad() { +// super.viewDidLoad() +// view.backgroundColor = .white +// } +// +// init(showPushButton: Bool = false) { +// super.init(nibName: nil, bundle: nil) +// +// if showPushButton { +// setupButton() +// } +// } +// +// override func viewWillAppear(_ animated: Bool) { +// super.viewWillAppear(animated) +// +// toogleTabbar(hide: false) +// } +// +// func setupButton() { +// +// view.addSubview(button) +// button.centerInSuperview() +// } +// +// @objc +// func handeAction(_ sender: UIButton) { +// let newVC = PushViewController() +// navigationController?.navigationBar.tintColor = .black +// navigationController?.pushViewController(newVC, animated: true) +// } +// +// required init?(coder: NSCoder) { +// fatalError("init(coder:) has not been implemented") +// } +//} + + +import UIKit +import FCL +import Combine +import EKTabBarController +class HomeScreenController: UIViewController { + private var cancellables = Set() + + @IBOutlet weak var loadingImage: UIImageView! + + func pushTabViewController () { + let storyboard = UIStoryboard(name: "Main", bundle: nil) + let actionController = storyboard.instantiateViewController(withIdentifier: "ActionsController") +// self.present(vc, animated: true) +// let actionController = ActionsContoller() +// viewController1.view.backgroundColor = .black + + let actionsViewItem = EKControllerItem(tabBarButtonItem: UITabBarItem(title: "Scan", image: UIImage(systemName: "qrcode.viewfinder") +, selectedImage: UIImage(systemName: "qrcode.viewfinder") +) , viewController:actionController ) + + let tweetController = TweetViewController() +// viewController1.view.backgroundColor = .black + + let tweetViewItem = EKControllerItem(tabBarButtonItem: UITabBarItem(title: "Social Media", image: UIImage(systemName: "lightbulb") +, selectedImage: UIImage(systemName: "lightbulb.fill") +) , viewController:tweetController ) + + let viewController2 = UIViewController() + viewController2.view.backgroundColor = .red + let profileStoryBoard = UIStoryboard(name: "ProfileView", bundle: nil) + let profileVc = profileStoryBoard.instantiateViewController(withIdentifier: "ProfileViewController") + let profileItem = EKControllerItem(tabBarButtonItem: UITabBarItem(title: "Scan", image: UIImage(systemName: "person.crop.circle") , selectedImage: UIImage(systemName: "person.crop.circle.fill")) , viewController: profileVc) + + let tabBarController = EKTabBarController(controllerItems: [actionsViewItem, tweetViewItem,profileItem], cornerRadius: 20, backgroundColor: .white.withAlphaComponent(0.5)) + self.navigationController?.pushViewController(tabBarController, animated: true) + + + } + override func viewDidLoad() { + super.viewDidLoad() + self.navigationItem.setHidesBackButton(true, animated: false) + let intialiseScreen = UIImage.gifImageWithName("waiting-setting-account") + loadingImage.image = intialiseScreen + Task { + do { + let txId = try await fcl.mutate(cadence: FanexCadence.initAccount) + print("txId ==> \(txId.hex)") + FlowManager.shared.subscribeTransaction(txId: txId.hex) + FlowManager.shared.$pendingTx + .receive(on: DispatchQueue.main) + .sink { txId in + if txId == nil { + //navigate to other screen + self.pushTabViewController() + debugPrint("now its a good time to navigate from this screen") + } + + }.store(in: &cancellables) + } catch { + print(error) + } + } + +// FlowManager.shared.$address +// .receive(on: DispatchQueue.main) +// .sink { user in +// self.address = user +// }.store(in: &cancellables) +// tabBar.tintColor = UIColor(white: 0.75, alpha: 1) +// +// viewControllers = (1...3).map { "Tab\($0)" }.map { +// let selected = UIImage(named: $0 + "_Large")! +// let normal = UIImage(named: $0 + "_Small")! +// let controller = storyboard!.instantiateViewController(withIdentifier: $0) +// controller.title = $0 +// controller.view.backgroundColor = UIColor(named: $0) +// controller.floatingTabItem = FloatingTabItem(selectedImage: selected, normalImage: normal) +// return controller +// } + + } + +} diff --git a/one-and-half-nibble/MobileApp/fanex/Info.plist b/one-and-half-nibble/MobileApp/fanex/Info.plist new file mode 100644 index 00000000..c6dcacd0 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLIconFile + fanex logo + CFBundleURLName + blocto + CFBundleURLSchemes + + blocto5595da5e-43a7-4001-956a-45bc5161e095 + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + fanex-app + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + NSCameraUsageDescription + Requires Camera to use the application + + diff --git a/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropService.swift b/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropService.swift new file mode 100644 index 00000000..cf3b5c22 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropService.swift @@ -0,0 +1,24 @@ +// +// AirDropViewModel.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation + +import Combine + +class AirDropService { + + static let shared = AirDropService() + + func getAirDrop() -> AnyPublisher { + + let request = URL(string: "https://jsonplaceholder.typicode.com/users") + + return ServiceManager.shared.callAPI(request!) + .map(\.value) + .eraseToAnyPublisher() + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropViewModel.swift b/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropViewModel.swift new file mode 100644 index 00000000..3fbe6547 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Model Views/AirDropViewModel.swift @@ -0,0 +1,39 @@ +// +// AirdropViewModel.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation + +import Combine + +class AirdropViewModel { + + var airdrop : Airdrop? + var airdropStatus = CurrentValueSubject(Airdrop(status: "")) + + func getAirdrop() { + + let _ = AirDropService.shared.getAirDrop() + .receive(on: RunLoop.main) + .sink(receiveCompletion: { (_) in + + }) { [weak self] (_airdrop) in + + guard let `self` = self else { + return + } + + self.airdrop = _airdrop + self.airdropStatus.send(_airdrop) + } + } + +// func getSearchResult(_ str: String) { +// +// let arr = arrUserData.filter({($0.name?.lowercased().contains(str) ?? false)}) +// self.userData.send((str.trimmingCharacters(in: .whitespacesAndNewlines) != "") ? arr : arrUserData) +// } +} diff --git a/one-and-half-nibble/MobileApp/fanex/Models/AirdropModel.swift b/one-and-half-nibble/MobileApp/fanex/Models/AirdropModel.swift new file mode 100644 index 00000000..841683d1 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Models/AirdropModel.swift @@ -0,0 +1,15 @@ +// +// AirdropModel.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation + + +struct Airdrop: Decodable, Hashable { + + let status: String? + +} diff --git a/one-and-half-nibble/MobileApp/fanex/Models/Token Amount.swift b/one-and-half-nibble/MobileApp/fanex/Models/Token Amount.swift new file mode 100644 index 00000000..48608ed2 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/Models/Token Amount.swift @@ -0,0 +1,13 @@ +// +// Token Amount.swift +// fanex +// +// Created by aman shah on 01/03/23. +// + +import Foundation +class TokenAmount { + public static let shared = TokenAmount() + var totalToken = 0 + var totalNfts = 1 +} diff --git a/one-and-half-nibble/MobileApp/fanex/ProfileView.storyboard b/one-and-half-nibble/MobileApp/fanex/ProfileView.storyboard new file mode 100644 index 00000000..7359abc3 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ProfileView.storyboard @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/ProfileViewController.swift b/one-and-half-nibble/MobileApp/fanex/ProfileViewController.swift new file mode 100644 index 00000000..45af9bda --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ProfileViewController.swift @@ -0,0 +1,62 @@ +// +// ProfileViewController.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation +import UIKit +import Combine +class ProfileViewController : UIViewController { + private var cancellables = Set() + @IBOutlet weak var nftTableview: UITableView! + @IBOutlet weak var optionView : UIView! + @IBOutlet weak var optionButton : UIButton! + @IBOutlet weak var profileImage : UIImageView! + @IBOutlet weak var walletBalance : UILabel! + @IBOutlet weak var userName : UILabel! + @IBOutlet weak var redeemedCoins : UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + nftTableview.register(NFTImageCell.self, forCellReuseIdentifier: "NFTImageCell") + nftTableview.dataSource = self + nftTableview.delegate = self + profileImage.layer.cornerRadius = 63 + optionView.layer.cornerRadius = 25 + FlowManager.shared.$address + .receive(on: DispatchQueue.main) + .sink { user in + if user != "" { + self.userName.text = user + } + + }.store(in: &cancellables) + } + override func viewWillAppear(_ animated: Bool) { + + walletBalance.text = String(TokenAmount.shared.totalToken) + redeemedCoins.text = String(TokenAmount.shared.totalNfts) + } +} +extension ProfileViewController : UITableViewDataSource , UITableViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let nftCell = nftTableview.dequeueReusableCell(withIdentifier: "NFTImageCell", for: indexPath) as? NFTImageCell else { + return NFTImageCell() + } +// nftCell.nftImage.image = UIImage(named: "superFan NFt") +// nftCell.nftImage.layer.cornerRadius = 25 +// nftImage.load(url: URL(string: "https://i.ibb.co/bgCWhDM/super-Fan-NFt.png")!) + + return nftCell + } + + + +} + diff --git a/one-and-half-nibble/MobileApp/fanex/ProgressHUD.swift b/one-and-half-nibble/MobileApp/fanex/ProgressHUD.swift new file mode 100644 index 00000000..785af4fc --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ProgressHUD.swift @@ -0,0 +1,1233 @@ +// +// ProgressHUD.swift +// fanex +// +// Created by aman shah on 26/02/23. +// + +import Foundation +// +// Copyright (c) 2021 Related Code - https://relatedcode.com +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public enum AnimationType { + case systemActivityIndicator + case horizontalCirclesPulse + case lineScaling + case singleCirclePulse + case multipleCirclePulse + case singleCircleScaleRipple + case multipleCircleScaleRipple + case circleSpinFade + case lineSpinFade + case circleRotateChase + case circleStrokeSpin +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public enum AnimatedIcon { + case succeed + case failed + case added +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public enum AlertIcon { + case heart + case doc + case bookmark + case moon + case star + case exclamation + case flag + case message + case question + case bolt + case shuffle + case eject + case card + case rotate + case like + case dislike + case privacy + case cart + case search +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +extension AlertIcon { + var image: UIImage? { + switch self { + case .heart: return UIImage(systemName: "heart.fill") + case .doc: return UIImage(systemName: "doc.fill") + case .bookmark: return UIImage(systemName: "bookmark.fill") + case .moon: return UIImage(systemName: "moon.fill") + case .star: return UIImage(systemName: "star.fill") + case .exclamation: return UIImage(systemName: "exclamationmark.triangle.fill") + case .flag: return UIImage(systemName: "flag.fill") + case .message: return UIImage(systemName: "envelope.fill") + case .question: return UIImage(systemName: "questionmark.diamond.fill") + case .bolt: return UIImage(systemName: "bolt.fill") + case .shuffle: return UIImage(systemName: "shuffle") + case .eject: return UIImage(systemName: "eject.fill") + case .card: return UIImage(systemName: "creditcard.fill") + case .rotate: return UIImage(systemName: "rotate.right.fill") + case .like: return UIImage(systemName: "hand.thumbsup.fill") + case .dislike: return UIImage(systemName: "hand.thumbsdown.fill") + case .privacy: return UIImage(systemName: "hand.raised.fill") + case .cart: return UIImage(systemName: "cart.fill") + case .search: return UIImage(systemName: "magnifyingglass") + } + } +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public extension ProgressHUD { + class var animationType: AnimationType { + get { shared.animationType } + set { shared.animationType = newValue } + } + + class var colorBackground: UIColor { + get { shared.colorBackground } + set { shared.colorBackground = newValue } + } + + class var colorHUD: UIColor { + get { shared.colorHUD } + set { shared.colorHUD = newValue } + } + + class var colorStatus: UIColor { + get { shared.colorStatus } + set { shared.colorStatus = newValue } + } + + class var colorAnimation: UIColor { + get { shared.colorAnimation } + set { shared.colorAnimation = newValue } + } + + class var colorProgress: UIColor { + get { shared.colorProgress } + set { shared.colorProgress = newValue } + } + + class var fontStatus: UIFont { + get { shared.fontStatus } + set { shared.fontStatus = newValue } + } + + class var imageSuccess: UIImage { + get { shared.imageSuccess } + set { shared.imageSuccess = newValue } + } + + class var imageError: UIImage { + get { shared.imageError } + set { shared.imageError = newValue } + } +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public extension ProgressHUD { + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func dismiss() { + DispatchQueue.main.async { + shared.hudHide() + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func show(_ status: String? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, hide: false, interaction: interaction) + } + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func show(_ status: String? = nil, icon: AlertIcon, interaction: Bool = true) { + let image = icon.image?.withTintColor(shared.colorAnimation, renderingMode: .alwaysOriginal) + + DispatchQueue.main.async { + shared.setup(status: status, staticImage: image, hide: true, interaction: interaction) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func show(_ status: String? = nil, icon animatedIcon: AnimatedIcon, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, animatedIcon: animatedIcon, hide: true, interaction: interaction) + } + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showSuccess(_ status: String? = nil, image: UIImage? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, staticImage: image ?? shared.imageSuccess, hide: true, interaction: interaction) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showError(_ status: String? = nil, image: UIImage? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, staticImage: image ?? shared.imageError, hide: true, interaction: interaction) + } + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showSucceed(_ status: String? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, animatedIcon: .succeed, hide: true, interaction: interaction) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showFailed(_ status: String? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, animatedIcon: .failed, hide: true, interaction: interaction) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showAdded(_ status: String? = nil, interaction: Bool = true) { + DispatchQueue.main.async { + shared.setup(status: status, animatedIcon: .added, hide: true, interaction: interaction) + } + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showProgress(_ progress: CGFloat, interaction: Bool = false) { + DispatchQueue.main.async { + shared.setup(progress: progress, hide: false, interaction: interaction) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + class func showProgress(_ status: String?, _ progress: CGFloat, interaction: Bool = false) { + DispatchQueue.main.async { + shared.setup(status: status, progress: progress, hide: false, interaction: interaction) + } + } +} + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +public class ProgressHUD: UIView { + private var viewBackground: UIView? + private var toolbarHUD: UIToolbar? + private var labelStatus: UILabel? + + private var viewProgress: ProgressView? + private var viewAnimation: UIView? + private var viewAnimatedIcon: UIView? + private var staticImageView: UIImageView? + + private var timer: Timer? + + private var animationType = AnimationType.systemActivityIndicator + + private var colorBackground = UIColor(red: 0, green: 0, blue: 0, alpha: 0.2) + private var colorHUD = UIColor.systemGray + private var colorStatus = UIColor.label + private var colorAnimation = UIColor.lightGray + private var colorProgress = UIColor.lightGray + + private var fontStatus = UIFont.boldSystemFont(ofSize: 24) + private var imageSuccess = UIImage.checkmark.withTintColor(UIColor.systemGreen, renderingMode: .alwaysOriginal) + private var imageError = UIImage.remove.withTintColor(UIColor.systemRed, renderingMode: .alwaysOriginal) + + private let keyboardWillShow = UIResponder.keyboardWillShowNotification + private let keyboardWillHide = UIResponder.keyboardWillHideNotification + private let keyboardDidShow = UIResponder.keyboardDidShowNotification + private let keyboardDidHide = UIResponder.keyboardDidHideNotification + + private let orientationDidChange = UIDevice.orientationDidChangeNotification + + // ------------------------------------------------------------------------------------------------------------------------------------------- + static let shared: ProgressHUD = { + let instance = ProgressHUD() + return instance + }() + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private convenience init() { + self.init(frame: UIScreen.main.bounds) + alpha = 0 + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + internal required init?(coder: NSCoder) { + super.init(coder: coder) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + override private init(frame: CGRect) { + super.init(frame: frame) + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setup(status: String? = nil, progress: CGFloat? = nil, animatedIcon: AnimatedIcon? = nil, staticImage: UIImage? = nil, hide: Bool, interaction: Bool) { + setupNotifications() + setupBackground(interaction) + setupToolbar() + setupLabel(status) + + if progress == nil, animatedIcon == nil, staticImage == nil { setupAnimation() } + if progress != nil, animatedIcon == nil, staticImage == nil { setupProgress(progress) } + if progress == nil, animatedIcon != nil, staticImage == nil { setupAnimatedIcon(animatedIcon) } + if progress == nil, animatedIcon == nil, staticImage != nil { setupStaticImage(staticImage) } + + setupSize() + setupPosition() + + hudShow() + + if hide { + let text = labelStatus?.text ?? "" + let delay = Double(text.count) * 0.03 + 1.25 + timer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { _ in + self.hudHide() + } + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupNotifications() { + if viewBackground == nil { + NotificationCenter.default.addObserver(self, selector: #selector(setupPosition(_:)), name: keyboardWillShow, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(setupPosition(_:)), name: keyboardWillHide, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(setupPosition(_:)), name: keyboardDidShow, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(setupPosition(_:)), name: keyboardDidHide, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(setupPosition(_:)), name: orientationDidChange, object: nil) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupBackground(_ interaction: Bool) { + if viewBackground == nil { + let mainWindow = UIApplication.shared.windows.first ?? UIWindow() + viewBackground = UIView(frame: bounds) + mainWindow.addSubview(viewBackground!) + } + + viewBackground?.backgroundColor = interaction ? .clear : colorBackground + viewBackground?.isUserInteractionEnabled = (interaction == false) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupToolbar() { + if toolbarHUD == nil { + toolbarHUD = UIToolbar(frame: CGRect.zero) + toolbarHUD?.isTranslucent = true + toolbarHUD?.clipsToBounds = true + toolbarHUD?.layer.cornerRadius = 10 + toolbarHUD?.layer.masksToBounds = true + viewBackground?.addSubview(toolbarHUD!) + } + + toolbarHUD?.backgroundColor = colorHUD + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupLabel(_ status: String?) { + if labelStatus == nil { + labelStatus = UILabel() + labelStatus?.textAlignment = .center + labelStatus?.baselineAdjustment = .alignCenters + labelStatus?.numberOfLines = 0 + toolbarHUD?.addSubview(labelStatus!) + } + + labelStatus?.text = (status != "") ? status : nil + labelStatus?.font = fontStatus + labelStatus?.textColor = colorStatus + labelStatus?.isHidden = (status == nil) ? true : false + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupProgress(_ progress: CGFloat?) { + viewAnimation?.removeFromSuperview() + viewAnimatedIcon?.removeFromSuperview() + staticImageView?.removeFromSuperview() + + if viewProgress == nil { + viewProgress = ProgressView(colorProgress) + viewProgress?.frame = CGRect(x: 0, y: 0, width: 70, height: 70) + } + + if viewProgress?.superview == nil { + toolbarHUD?.addSubview(viewProgress!) + } + + viewProgress?.setProgress(progress!) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupAnimation() { + viewProgress?.removeFromSuperview() + viewAnimatedIcon?.removeFromSuperview() + staticImageView?.removeFromSuperview() + + if viewAnimation == nil { + viewAnimation = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 60)) + } + + if viewAnimation?.superview == nil { + toolbarHUD?.addSubview(viewAnimation!) + } + + viewAnimation?.subviews.forEach { + $0.removeFromSuperview() + } + + viewAnimation?.layer.sublayers?.forEach { + $0.removeFromSuperlayer() + } + + if animationType == .systemActivityIndicator { animationSystemActivityIndicator(viewAnimation!) } + if animationType == .horizontalCirclesPulse { animationHorizontalCirclesPulse(viewAnimation!) } + if animationType == .lineScaling { animationLineScaling(viewAnimation!) } + if animationType == .singleCirclePulse { animationSingleCirclePulse(viewAnimation!) } + if animationType == .multipleCirclePulse { animationMultipleCirclePulse(viewAnimation!) } + if animationType == .singleCircleScaleRipple { animationSingleCircleScaleRipple(viewAnimation!) } + if animationType == .multipleCircleScaleRipple { animationMultipleCircleScaleRipple(viewAnimation!) } + if animationType == .circleSpinFade { animationCircleSpinFade(viewAnimation!) } + if animationType == .lineSpinFade { animationLineSpinFade(viewAnimation!) } + if animationType == .circleRotateChase { animationCircleRotateChase(viewAnimation!) } + if animationType == .circleStrokeSpin { animationCircleStrokeSpin(viewAnimation!) } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupAnimatedIcon(_ animatedIcon: AnimatedIcon?) { + viewProgress?.removeFromSuperview() + viewAnimation?.removeFromSuperview() + staticImageView?.removeFromSuperview() + + if viewAnimatedIcon == nil { + viewAnimatedIcon = UIView(frame: CGRect(x: 0, y: 0, width: 70, height: 70)) + } + + if viewAnimatedIcon?.superview == nil { + toolbarHUD?.addSubview(viewAnimatedIcon!) + } + + viewAnimatedIcon?.layer.sublayers?.forEach { + $0.removeFromSuperlayer() + } + + if animatedIcon == .succeed { animatedIconSucceed(viewAnimatedIcon!) } + if animatedIcon == .failed { animatedIconFailed(viewAnimatedIcon!) } + if animatedIcon == .added { animatedIconAdded(viewAnimatedIcon!) } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupStaticImage(_ staticImage: UIImage?) { + viewProgress?.removeFromSuperview() + viewAnimation?.removeFromSuperview() + viewAnimatedIcon?.removeFromSuperview() + + if staticImageView == nil { + staticImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 60, height: 60)) + } + + if staticImageView?.superview == nil { + toolbarHUD?.addSubview(staticImageView!) + } + + staticImageView?.image = staticImage + staticImageView?.contentMode = .scaleAspectFit + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func setupSize() { + var width: CGFloat = 120 + var height: CGFloat = 120 + + if let text = labelStatus?.text { + let sizeMax = CGSize(width: 250, height: 250) + let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: labelStatus?.font as Any] + var rectLabel = text.boundingRect(with: sizeMax, options: .usesLineFragmentOrigin, attributes: attributes, context: nil) + + width = ceil(rectLabel.size.width) + 60 + height = ceil(rectLabel.size.height) + 120 + + if width < 120 { width = 120 } + + rectLabel.origin.x = (width - rectLabel.size.width) / 2 + rectLabel.origin.y = (height - rectLabel.size.height) / 2 + 45 + + labelStatus?.frame = rectLabel + } + + toolbarHUD?.bounds = CGRect(x: 0, y: 0, width: width, height: height) + + let centerX = width / 2 + var centerY = height / 2 + + if labelStatus?.text != nil { centerY = 55 } + + viewProgress?.center = CGPoint(x: centerX, y: centerY) + viewAnimation?.center = CGPoint(x: centerX, y: centerY) + viewAnimatedIcon?.center = CGPoint(x: centerX, y: centerY) + staticImageView?.center = CGPoint(x: centerX, y: centerY) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + @objc private func setupPosition(_ notification: Notification? = nil) { + var heightKeyboard: CGFloat = 0 + var animationDuration: TimeInterval = 0 + + if let notification = notification { + let frameKeyboard = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect ?? CGRect.zero + animationDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0 + + if (notification.name == keyboardWillShow) || (notification.name == keyboardDidShow) { + heightKeyboard = frameKeyboard.size.height + } else if (notification.name == keyboardWillHide) || (notification.name == keyboardDidHide) { + heightKeyboard = 0 + } else { + heightKeyboard = keyboardHeight() + } + } else { + heightKeyboard = keyboardHeight() + } + + let mainWindow = UIApplication.shared.windows.first ?? UIWindow() + let screen = mainWindow.bounds + let center = CGPoint(x: screen.size.width / 2, y: (screen.size.height - heightKeyboard) / 2) + + UIView.animate(withDuration: animationDuration, delay: 0, options: .allowUserInteraction, animations: { + self.toolbarHUD?.center = center + self.viewBackground?.frame = screen + }, completion: nil) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func keyboardHeight() -> CGFloat { + if let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow"), + let inputSetContainerView = NSClassFromString("UIInputSetContainerView"), + let inputSetHostView = NSClassFromString("UIInputSetHostView") + { + for window in UIApplication.shared.windows { + if window.isKind(of: keyboardWindowClass) { + for firstSubView in window.subviews { + if firstSubView.isKind(of: inputSetContainerView) { + for secondSubView in firstSubView.subviews { + if secondSubView.isKind(of: inputSetHostView) { + return secondSubView.frame.size.height + } + } + } + } + } + } + } + return 0 + } + + // MARK: - + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func hudShow() { + timer?.invalidate() + timer = nil + + if alpha != 1 { + alpha = 1 + toolbarHUD?.alpha = 0 + toolbarHUD?.transform = CGAffineTransform(scaleX: 1.4, y: 1.4) + + UIView.animate(withDuration: 0.15, delay: 0, options: [.allowUserInteraction, .curveEaseIn], animations: { + self.toolbarHUD?.transform = CGAffineTransform(scaleX: 1 / 1.4, y: 1 / 1.4) + self.toolbarHUD?.alpha = 1 + }, completion: nil) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func hudHide() { + if alpha == 1 { + UIView.animate(withDuration: 0.15, delay: 0, options: [.allowUserInteraction, .curveEaseIn], animations: { + self.toolbarHUD?.transform = CGAffineTransform(scaleX: 0.3, y: 0.3) + self.toolbarHUD?.alpha = 0 + }, completion: { _ in + self.hudDestroy() + self.alpha = 0 + }) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func hudDestroy() { + NotificationCenter.default.removeObserver(self) + + staticImageView?.removeFromSuperview(); staticImageView = nil + viewAnimatedIcon?.removeFromSuperview(); viewAnimatedIcon = nil + viewAnimation?.removeFromSuperview(); viewAnimation = nil + viewProgress?.removeFromSuperview(); viewProgress = nil + + labelStatus?.removeFromSuperview(); labelStatus = nil + toolbarHUD?.removeFromSuperview(); toolbarHUD = nil + viewBackground?.removeFromSuperview(); viewBackground = nil + + timer?.invalidate() + timer = nil + } + + // MARK: - Animation + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationSystemActivityIndicator(_ view: UIView) { + let spinner = UIActivityIndicatorView(style: .large) + spinner.frame = view.bounds + spinner.color = colorAnimation + spinner.hidesWhenStopped = true + spinner.startAnimating() + spinner.transform = CGAffineTransform(scaleX: 1.6, y: 1.6) + view.addSubview(spinner) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationHorizontalCirclesPulse(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let spacing: CGFloat = 3 + let radius: CGFloat = (width - spacing * 2) / 3 + let ypos: CGFloat = (height - radius) / 2 + + let beginTime = CACurrentMediaTime() + let beginTimes = [0.36, 0.24, 0.12] + let timingFunction = CAMediaTimingFunction(controlPoints: 0.2, 0.68, 0.18, 1.08) + + let animation = CAKeyframeAnimation(keyPath: "transform.scale") + animation.keyTimes = [0, 0.5, 1] + animation.timingFunctions = [timingFunction, timingFunction] + animation.values = [1, 0.3, 1] + animation.duration = 1 + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: radius / 2, y: radius / 2), radius: radius / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + for i in 0 ..< 3 { + let layer = CAShapeLayer() + layer.frame = CGRect(x: (radius + spacing) * CGFloat(i), y: ypos, width: radius, height: radius) + layer.path = path.cgPath + layer.fillColor = colorAnimation.cgColor + + animation.beginTime = beginTime - beginTimes[i] + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationLineScaling(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let lineWidth = width / 9 + + let beginTime = CACurrentMediaTime() + let beginTimes = [0.5, 0.4, 0.3, 0.2, 0.1] + let timingFunction = CAMediaTimingFunction(controlPoints: 0.2, 0.68, 0.18, 1.08) + + let animation = CAKeyframeAnimation(keyPath: "transform.scale.y") + animation.keyTimes = [0, 0.5, 1] + animation.timingFunctions = [timingFunction, timingFunction] + animation.values = [1, 0.4, 1] + animation.duration = 1 + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: lineWidth, height: height), cornerRadius: width / 2) + + for i in 0 ..< 5 { + let layer = CAShapeLayer() + layer.frame = CGRect(x: lineWidth * 2 * CGFloat(i), y: 0, width: lineWidth, height: height) + layer.path = path.cgPath + layer.backgroundColor = nil + layer.fillColor = colorAnimation.cgColor + + animation.beginTime = beginTime - beginTimes[i] + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationSingleCirclePulse(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let duration: CFTimeInterval = 1.0 + + let animationScale = CABasicAnimation(keyPath: "transform.scale") + animationScale.duration = duration + animationScale.fromValue = 0 + animationScale.toValue = 1 + + let animationOpacity = CABasicAnimation(keyPath: "opacity") + animationOpacity.duration = duration + animationOpacity.fromValue = 1 + animationOpacity.toValue = 0 + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationOpacity] + animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: width / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: width, height: height) + layer.path = path.cgPath + layer.fillColor = colorAnimation.cgColor + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationMultipleCirclePulse(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let duration = 1.0 + let beginTime = CACurrentMediaTime() + let beginTimes = [0, 0.3, 0.6] + + let animationScale = CABasicAnimation(keyPath: "transform.scale") + animationScale.duration = duration + animationScale.fromValue = 0 + animationScale.toValue = 1 + + let animationOpacity = CAKeyframeAnimation(keyPath: "opacity") + animationOpacity.duration = duration + animationOpacity.keyTimes = [0, 0.05, 1] + animationOpacity.values = [0, 1, 0] + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationOpacity] + animation.timingFunction = CAMediaTimingFunction(name: .linear) + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: width / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + for i in 0 ..< 3 { + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: width, height: height) + layer.path = path.cgPath + layer.fillColor = colorAnimation.cgColor + layer.opacity = 0 + + animation.beginTime = beginTime + beginTimes[i] + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationSingleCircleScaleRipple(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let duration: CFTimeInterval = 1.0 + let timingFunction = CAMediaTimingFunction(controlPoints: 0.21, 0.53, 0.56, 0.8) + + let animationScale = CAKeyframeAnimation(keyPath: "transform.scale") + animationScale.keyTimes = [0, 0.7] + animationScale.timingFunction = timingFunction + animationScale.values = [0.1, 1] + animationScale.duration = duration + + let animationOpacity = CAKeyframeAnimation(keyPath: "opacity") + animationOpacity.keyTimes = [0, 0.7, 1] + animationOpacity.timingFunctions = [timingFunction, timingFunction] + animationOpacity.values = [1, 0.7, 0] + animationOpacity.duration = duration + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationOpacity] + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: width / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: width, height: height) + layer.path = path.cgPath + layer.backgroundColor = nil + layer.fillColor = nil + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 3 + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationMultipleCircleScaleRipple(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let duration = 1.25 + let beginTime = CACurrentMediaTime() + let beginTimes = [0, 0.2, 0.4] + let timingFunction = CAMediaTimingFunction(controlPoints: 0.21, 0.53, 0.56, 0.8) + + let animationScale = CAKeyframeAnimation(keyPath: "transform.scale") + animationScale.keyTimes = [0, 0.7] + animationScale.timingFunction = timingFunction + animationScale.values = [0, 1] + animationScale.duration = duration + + let animationOpacity = CAKeyframeAnimation(keyPath: "opacity") + animationOpacity.keyTimes = [0, 0.7, 1] + animationOpacity.timingFunctions = [timingFunction, timingFunction] + animationOpacity.values = [1, 0.7, 0] + animationOpacity.duration = duration + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationOpacity] + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: width / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + for i in 0 ..< 3 { + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: width, height: height) + layer.path = path.cgPath + layer.backgroundColor = nil + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 3 + layer.fillColor = nil + + animation.beginTime = beginTime + beginTimes[i] + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationCircleSpinFade(_ view: UIView) { + let width = view.frame.size.width + + let spacing: CGFloat = 3 + let radius = (width - 4 * spacing) / 3.5 + let radiusX = (width - radius) / 2 + + let duration = 1.0 + let beginTime = CACurrentMediaTime() + let beginTimes: [CFTimeInterval] = [0.84, 0.72, 0.6, 0.48, 0.36, 0.24, 0.12, 0] + + let animationScale = CAKeyframeAnimation(keyPath: "transform.scale") + animationScale.keyTimes = [0, 0.5, 1] + animationScale.values = [1, 0.4, 1] + animationScale.duration = duration + + let animationOpacity = CAKeyframeAnimation(keyPath: "opacity") + animationOpacity.keyTimes = [0, 0.5, 1] + animationOpacity.values = [1, 0.3, 1] + animationOpacity.duration = duration + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationOpacity] + animation.timingFunction = CAMediaTimingFunction(name: .linear) + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(arcCenter: CGPoint(x: radius / 2, y: radius / 2), radius: radius / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + for i in 0 ..< 8 { + let angle = .pi / 4 * CGFloat(i) + + let layer = CAShapeLayer() + layer.path = path.cgPath + layer.fillColor = colorAnimation.cgColor + layer.backgroundColor = nil + layer.frame = CGRect(x: radiusX * (cos(angle) + 1), y: radiusX * (sin(angle) + 1), width: radius, height: radius) + + animation.beginTime = beginTime - beginTimes[i] + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationLineSpinFade(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let spacing: CGFloat = 3 + let lineWidth = (width - 4 * spacing) / 5 + let lineHeight = (height - 2 * spacing) / 3 + let containerSize = max(lineWidth, lineHeight) + let radius = width / 2 - containerSize / 2 + + let duration = 1.2 + let beginTime = CACurrentMediaTime() + let beginTimes: [CFTimeInterval] = [0.96, 0.84, 0.72, 0.6, 0.48, 0.36, 0.24, 0.12] + let timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) + + let animation = CAKeyframeAnimation(keyPath: "opacity") + animation.keyTimes = [0, 0.5, 1] + animation.timingFunctions = [timingFunction, timingFunction] + animation.values = [1, 0.3, 1] + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: lineWidth, height: lineHeight), cornerRadius: lineWidth / 2) + + for i in 0 ..< 8 { + let angle = .pi / 4 * CGFloat(i) + + let line = CAShapeLayer() + line.frame = CGRect(x: (containerSize - lineWidth) / 2, y: (containerSize - lineHeight) / 2, width: lineWidth, height: lineHeight) + line.path = path.cgPath + line.backgroundColor = nil + line.fillColor = colorAnimation.cgColor + + let container = CALayer() + container.frame = CGRect(x: radius * (cos(angle) + 1), y: radius * (sin(angle) + 1), width: containerSize, height: containerSize) + container.addSublayer(line) + container.sublayerTransform = CATransform3DMakeRotation(.pi / 2 + angle, 0, 0, 1) + + animation.beginTime = beginTime - beginTimes[i] + + container.add(animation, forKey: "animation") + view.layer.addSublayer(container) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationCircleRotateChase(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let spacing: CGFloat = 3 + let radius = (width - 4 * spacing) / 3.5 + let radiusX = (width - radius) / 2 + + let duration: CFTimeInterval = 1.5 + + let path = UIBezierPath(arcCenter: CGPoint(x: radius / 2, y: radius / 2), radius: radius / 2, startAngle: 0, endAngle: 2 * .pi, clockwise: false) + + let pathPosition = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: radiusX, startAngle: 1.5 * .pi, endAngle: 3.5 * .pi, clockwise: true) + + for i in 0 ..< 5 { + let rate = Float(i) * 1 / 5 + let fromScale = 1 - rate + let toScale = 0.2 + rate + let timeFunc = CAMediaTimingFunction(controlPoints: 0.5, 0.15 + rate, 0.25, 1) + + let animationScale = CABasicAnimation(keyPath: "transform.scale") + animationScale.duration = duration + animationScale.repeatCount = HUGE + animationScale.fromValue = fromScale + animationScale.toValue = toScale + + let animationPosition = CAKeyframeAnimation(keyPath: "position") + animationPosition.duration = duration + animationPosition.repeatCount = HUGE + animationPosition.path = pathPosition.cgPath + + let animation = CAAnimationGroup() + animation.animations = [animationScale, animationPosition] + animation.timingFunction = timeFunc + animation.duration = duration + animation.repeatCount = HUGE + animation.isRemovedOnCompletion = false + + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: radius, height: radius) + layer.path = path.cgPath + layer.fillColor = colorAnimation.cgColor + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animationCircleStrokeSpin(_ view: UIView) { + let width = view.frame.size.width + let height = view.frame.size.height + + let beginTime: Double = 0.5 + let durationStart: Double = 1.2 + let durationStop: Double = 0.7 + + let animationRotation = CABasicAnimation(keyPath: "transform.rotation") + animationRotation.byValue = 2 * Float.pi + animationRotation.timingFunction = CAMediaTimingFunction(name: .linear) + + let animationStart = CABasicAnimation(keyPath: "strokeStart") + animationStart.duration = durationStart + animationStart.timingFunction = CAMediaTimingFunction(controlPoints: 0.4, 0, 0.2, 1) + animationStart.fromValue = 0 + animationStart.toValue = 1 + animationStart.beginTime = beginTime + + let animationStop = CABasicAnimation(keyPath: "strokeEnd") + animationStop.duration = durationStop + animationStop.timingFunction = CAMediaTimingFunction(controlPoints: 0.4, 0, 0.2, 1) + animationStop.fromValue = 0 + animationStop.toValue = 1 + + let animation = CAAnimationGroup() + animation.animations = [animationRotation, animationStop, animationStart] + animation.duration = durationStart + beginTime + animation.repeatCount = .infinity + animation.isRemovedOnCompletion = false + animation.fillMode = .forwards + + let path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: width / 2, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: true) + + let layer = CAShapeLayer() + layer.frame = CGRect(x: 0, y: 0, width: width, height: height) + layer.path = path.cgPath + layer.fillColor = nil + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 3 + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + + // MARK: - Animated Icon + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animatedIconSucceed(_ view: UIView) { + let length = view.frame.width + let delay = (alpha == 0) ? 0.25 : 0.0 + + let path = UIBezierPath() + path.move(to: CGPoint(x: length * 0.15, y: length * 0.50)) + path.addLine(to: CGPoint(x: length * 0.5, y: length * 0.80)) + path.addLine(to: CGPoint(x: length * 1.0, y: length * 0.25)) + + let animation = CABasicAnimation(keyPath: "strokeEnd") + animation.duration = 0.25 + animation.fromValue = 0 + animation.toValue = 1 + animation.fillMode = .forwards + animation.isRemovedOnCompletion = false + animation.beginTime = CACurrentMediaTime() + delay + + let layer = CAShapeLayer() + layer.path = path.cgPath + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 9 + layer.lineCap = .round + layer.lineJoin = .round + layer.strokeEnd = 0 + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animatedIconFailed(_ view: UIView) { + let length = view.frame.width + let delay = (alpha == 0) ? 0.25 : 0.0 + + let path1 = UIBezierPath() + let path2 = UIBezierPath() + + path1.move(to: CGPoint(x: length * 0.15, y: length * 0.15)) + path2.move(to: CGPoint(x: length * 0.15, y: length * 0.85)) + + path1.addLine(to: CGPoint(x: length * 0.85, y: length * 0.85)) + path2.addLine(to: CGPoint(x: length * 0.85, y: length * 0.15)) + + let paths = [path1, path2] + + let animation = CABasicAnimation(keyPath: "strokeEnd") + animation.duration = 0.15 + animation.fromValue = 0 + animation.toValue = 1 + animation.fillMode = .forwards + animation.isRemovedOnCompletion = false + + for i in 0 ..< 2 { + let layer = CAShapeLayer() + layer.path = paths[i].cgPath + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 9 + layer.lineCap = .round + layer.lineJoin = .round + layer.strokeEnd = 0 + + animation.beginTime = CACurrentMediaTime() + 0.25 * Double(i) + delay + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + private func animatedIconAdded(_ view: UIView) { + let length = view.frame.width + let delay = (alpha == 0) ? 0.25 : 0.0 + + let path1 = UIBezierPath() + let path2 = UIBezierPath() + + path1.move(to: CGPoint(x: length * 0.1, y: length * 0.5)) + path2.move(to: CGPoint(x: length * 0.5, y: length * 0.1)) + + path1.addLine(to: CGPoint(x: length * 0.9, y: length * 0.5)) + path2.addLine(to: CGPoint(x: length * 0.5, y: length * 0.9)) + + let paths = [path1, path2] + + let animation = CABasicAnimation(keyPath: "strokeEnd") + animation.duration = 0.15 + animation.fromValue = 0 + animation.toValue = 1 + animation.fillMode = .forwards + animation.isRemovedOnCompletion = false + + for i in 0 ..< 2 { + let layer = CAShapeLayer() + layer.path = paths[i].cgPath + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = colorAnimation.cgColor + layer.lineWidth = 9 + layer.lineCap = .round + layer.lineJoin = .round + layer.strokeEnd = 0 + + animation.beginTime = CACurrentMediaTime() + 0.25 * Double(i) + delay + + layer.add(animation, forKey: "animation") + view.layer.addSublayer(layer) + } + } +} + +// MARK: - ProgressView + +// ----------------------------------------------------------------------------------------------------------------------------------------------- +private class ProgressView: UIView { + var color: UIColor = .systemBackground { + didSet { setupLayers() } + } + + private var progress: CGFloat = 0 + + private var layerCircle = CAShapeLayer() + private var layerProgress = CAShapeLayer() + private var labelPercentage = UILabel() + + // ------------------------------------------------------------------------------------------------------------------------------------------- + convenience init(_ color: UIColor) { + self.init(frame: .zero) + self.color = color + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + override init(frame: CGRect) { + super.init(frame: frame) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + override func draw(_ rect: CGRect) { + super.draw(rect) + setupLayers() + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + func setupLayers() { + subviews.forEach { $0.removeFromSuperview() } + layer.sublayers?.forEach { $0.removeFromSuperlayer() } + + let width = frame.size.width + let height = frame.size.height + + let center = CGPoint(x: width / 2, y: height / 2) + let radiusCircle = width / 2 + let radiusProgress = width / 2 - 5 + + let pathCircle = UIBezierPath(arcCenter: center, radius: radiusCircle, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: true) + let pathProgress = UIBezierPath(arcCenter: center, radius: radiusProgress, startAngle: -0.5 * .pi, endAngle: 1.5 * .pi, clockwise: true) + + layerCircle.path = pathCircle.cgPath + layerCircle.fillColor = UIColor.clear.cgColor + layerCircle.lineWidth = 3 + layerCircle.strokeColor = color.cgColor + + layerProgress.path = pathProgress.cgPath + layerProgress.fillColor = UIColor.clear.cgColor + layerProgress.lineWidth = 7 + layerProgress.strokeColor = color.cgColor + layerProgress.strokeEnd = 0 + + layer.addSublayer(layerCircle) + layer.addSublayer(layerProgress) + + labelPercentage.frame = bounds + labelPercentage.textColor = color + labelPercentage.textAlignment = .center + addSubview(labelPercentage) + } + + // ------------------------------------------------------------------------------------------------------------------------------------------- + func setProgress(_ value: CGFloat, duration: TimeInterval = 0.2) { + let animation = CABasicAnimation(keyPath: "strokeEnd") + animation.duration = duration + animation.fromValue = progress + animation.toValue = value + animation.fillMode = .both + animation.isRemovedOnCompletion = false + layerProgress.add(animation, forKey: "animation") + + progress = value + labelPercentage.text = "\(Int(value * 100))%" + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/PushViewController.swift b/one-and-half-nibble/MobileApp/fanex/PushViewController.swift new file mode 100644 index 00000000..708a45d5 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/PushViewController.swift @@ -0,0 +1,25 @@ +//// +//// PushViewController.swift +//// fanex +//// +//// Created by aman shah on 25/02/23. +//// +// +//import Foundation +// +//import UIKit +// +//class PushViewController: BaseViewController { +// +// override func viewDidLoad() { +// super.viewDidLoad() +// view.backgroundColor = .white +// title = "Pushed VC" +// } +// +// override func viewWillAppear(_ animated: Bool) { +// super.viewWillAppear(animated) +// +// toogleTabbar(hide: true) +// } +//} diff --git a/one-and-half-nibble/MobileApp/fanex/ScanQrController.swift b/one-and-half-nibble/MobileApp/fanex/ScanQrController.swift new file mode 100644 index 00000000..53645a27 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ScanQrController.swift @@ -0,0 +1,117 @@ +// +// ScanQrController.swift +// fanex +// +// Created by aman shah on 27/02/23. +// + +import UIKit +import MercariQRScanner +import AVFoundation +import PopupDialog +class ScanQrController: UIViewController { + + var popUpView : UIView? + + override func viewDidLoad() { + super.viewDidLoad() + setupQRScanner() + // Do any additional setup after loading the view. + } + + private func setupQRScanner() { + switch AVCaptureDevice.authorizationStatus(for: .video) { + case .authorized: + setupQRScannerView() + case .notDetermined: + AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in + if granted { + DispatchQueue.main.async { [weak self] in + self?.setupQRScannerView() + } + } + } + default: + showAlert() + } + } + + private func setupQRScannerView() { + let qrScannerView = QRScannerView(frame: view.bounds) + view.addSubview(qrScannerView) + qrScannerView.configure(delegate: self, input: .init(isBlurEffectEnabled: true)) + qrScannerView.startRunning() + } + + private func showAlert() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + let alert = UIAlertController(title: "Error", message: "Camera is required to use in this application", preferredStyle: .alert) + alert.addAction(.init(title: "OK", style: .default)) + self?.present(alert, animated: true) + } + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} +extension ScanQrController: QRScannerViewDelegate { + func qrScannerView(_ qrScannerView: MercariQRScanner.QRScannerView, didFailure error: MercariQRScanner.QRScannerError) { + print(error) + } + + func qrScannerView(_ qrScannerView: MercariQRScanner.QRScannerView, didSuccess code: String) { + print(code) + var qrCodesManager = ValidQrCodes() + if ((qrCodesManager.codes[code]) != nil){ + debugPrint("its a valide code") +// let APIManager = ServiceManager.shared + + + // Prepare the popup assets + let title = "\(qrCodesManager.codes[code]) Fanex points Recieved" + let message = "Keep completing tasks to earn more rewards" + let image = UIImage(named: "congratulationsImage") + + // Create the dialog + let popup = PopupDialog(title: title, message: message, image: image) + + // Create buttons + let buttonOne = CancelButton(title: "CANCEL") { + print("Hell Yeahh!!") + } + TokenAmount.shared.totalToken += qrCodesManager.codes[code] ?? 0 + // This button will not the dismiss the dialog +// let buttonTwo = DefaultButton(title: "ADMIRE CAR", dismissOnTap: false) { +// print("What a beauty!") +// } +// +// let buttonThree = DefaultButton(title: "BUY CAR", height: 60) { +// print("Ah, maybe next time :)") +// } + + // Add buttons to dialog + // Alternatively, you can use popup.addButton(buttonOne) + // to add a single button + popup.addButtons([buttonOne]) + + // Present dialog + self.present(popup, animated: true, completion: nil) + + + }else { + debugPrint("Fuck you dont cheat we are seeing you") + } + } + + func qrScannerView(_ qrScannerView: MercariQRScanner.QRScannerView, didChangeTorchActive isOn: Bool) { + debugPrint("do nothing") + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/SceneDelegate.swift b/one-and-half-nibble/MobileApp/fanex/SceneDelegate.swift new file mode 100644 index 00000000..e85f6256 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/SceneDelegate.swift @@ -0,0 +1,55 @@ +// +// SceneDelegate.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + + // Save changes in the application's managed object context when the application transitions to the background. + (UIApplication.shared.delegate as? AppDelegate)?.saveContext() + } + + +} + diff --git a/one-and-half-nibble/MobileApp/fanex/TabBarController.swift b/one-and-half-nibble/MobileApp/fanex/TabBarController.swift new file mode 100644 index 00000000..e6771bcc --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/TabBarController.swift @@ -0,0 +1,12 @@ +import UIKit +import Foundation +import EKTabBarController + +class TabBarController : UIViewController{ + + override func viewDidLoad() { + super.viewDidLoad() + + } + +} diff --git a/one-and-half-nibble/MobileApp/fanex/TweetViewController.swift b/one-and-half-nibble/MobileApp/fanex/TweetViewController.swift new file mode 100644 index 00000000..09b6f650 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/TweetViewController.swift @@ -0,0 +1,96 @@ +// +// TweetViewController.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation +import UIKit +import SafariServices +import TweetView +import PopupDialog +protocol TweetControllerDismiss { + func dismiss() +} +class TweetViewController : UIViewController { +// let tweetTable = UITableView() + var tweetIds = ["1630493851990327298", "1630472423953891330","1630463076066525184"] + override func viewDidLoad() { + super.viewDidLoad() + + createTweetTableView() + + } + var twitterVCDelegate : TweetControllerDismiss? + + func createTweetTableView(){ + +// tweetTable.delegate = self +// tweetTable.dataSource = self +// tweetTable.translatesAutoresizingMaskIntoConstraints = false +// tweetTable.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true +// tweetTable.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true +// tweetTable.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true +// tweetTable.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true + TweetView.prepare() + + let tweetView = TweetView(id:tweetIds[0]) + let width = view.frame.width - 32 + tweetView.frame = CGRect(x: 24, y: 24, width: width, height: 500) + tweetView.delegate = self +// tweetCell.contentView.addSubview(tweetView) + self.view.addSubview(tweetView) + tweetView.translatesAutoresizingMaskIntoConstraints = false + tweetView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + tweetView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + tweetView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true + tweetView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true +// self.view.addSubview() + + Task { + + tweetView.load() + } + + + } + func createTweetCell(tweetId:String) -> UITableViewCell{ + let tweetCell = UITableViewCell() + + + + return tweetCell + } +} +extension TweetViewController : TweetViewDelegate { + func tweetView(_ tweetView: TweetView, didUpdatedHeight height: CGFloat) { + tweetView.frame.size = CGSize(width: tweetView.frame.width, height: height) +// tweetTable.reloadData() + } + + func tweetView(_ tweetView: TweetView, shouldOpenURL url: URL) { + debugPrint("do something and interact with this") + debugPrint(url) + UIApplication.shared.open(url, options: [:], completionHandler: nil) + TokenAmount.shared.totalToken += 50 + self.dismiss(animated: true) + twitterVCDelegate?.dismiss() + //create popup + + } +} + +//extension TweetViewController : UITableViewDataSource , UITableViewDelegate { +// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { +// return tweetIds.count +// } +// +// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { +// return createTweetCell(tweetId: tweetIds[indexPath.row]) +// } +// +// func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { +// return UITableView.automaticDimension +// } +//} diff --git a/one-and-half-nibble/MobileApp/fanex/UILabel+Extensions.swift b/one-and-half-nibble/MobileApp/fanex/UILabel+Extensions.swift new file mode 100644 index 00000000..31685baf --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/UILabel+Extensions.swift @@ -0,0 +1,17 @@ +// +// UILabel+Extensions.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import Foundation +import UIKit +extension UILabel { + func addCharacterSpacing(kernValue: Double = 1.15) { + guard let text = text, !text.isEmpty else { return } + let string = NSMutableAttributedString(string: text) + string.addAttribute(NSAttributedString.Key.kern, value: kernValue, range: NSRange(location: 0, length: string.length - 1)) + attributedText = string + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/ValidQrCode.swift b/one-and-half-nibble/MobileApp/fanex/ValidQrCode.swift new file mode 100644 index 00000000..9d30ba1e --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ValidQrCode.swift @@ -0,0 +1,20 @@ +// +// ValidQrCode.swift +// fanex +// +// Created by aman shah on 28/02/23. +// + +import Foundation + +struct ValidQrCodes{ + + let codes = [ + "i87bb1" : 20 , + "i87bb2" : 50 , + "i87bb3" : 30 , + "i87bb4" : 100 + + ] + +} diff --git a/one-and-half-nibble/MobileApp/fanex/ViewController.swift b/one-and-half-nibble/MobileApp/fanex/ViewController.swift new file mode 100644 index 00000000..a28a4d08 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/ViewController.swift @@ -0,0 +1,132 @@ +// +// ViewController.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import UIKit +import FCL +import Combine +class ViewController: UIViewController { + private var cancellables = Set() + var address = "" + var verifyUser = false + var navigated = false + @IBOutlet weak var tempButtonWalletConnect: UIButton! + @IBOutlet weak var walletConnetLabel: UILabel! + @IBOutlet weak var splashScreenLogo: UIImageView! + override func viewWillAppear(_ animated:Bool){ + super.viewWillAppear(animated) + + +// if (address != ""){ +// self.navigateToHome() +// +// } +// debugPrint(FlowManager.shared.address) +// +// debugPrint(fcl.currentUser) +// if let userWalletAddress = fcl.currentUser?.address { +// // do some stuff here. +// debugPrint("Dont cry it works now ", fcl.currentUser?.address) +// } +// let accountProofData = FCLAccountProofData( +// appId: "fanex.app", +// nonce: "75f8587e5bd5f9dcc9909d0dae1f0ac5814458b2ae129620502cb936fde7120a" // minimum 32-byte random nonce as a hex string. +// ) +// Task { +// do { +// let address = try await fcl.authanticate(accountProofData: accountProofData) +// } catch { +// // handle error here +// } +// } + + + } + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + + let splashScreen = UIImage.gifImageWithName("fanex logo") + splashScreenLogo.image = splashScreen +// DispatchQueue.main.asyncAfter(deadline: .now() + 5) { +// self.navigateToHome() +// } + tempButtonWalletConnect.addTarget(self, action: #selector(connectWallet), for: .touchDown) +// fcl.delegate = self + createUI() + FlowManager.shared.$address + .receive(on: DispatchQueue.main) + .sink { user in + if user != "" { + self.address = user + self.navigateToHome() + } + + }.store(in: &cancellables) + } + @objc func connectWallet() { +// do { +// try await fcl.authenticate() +// } catch { +// print("Unexpected account didnot connect: \(error)") +// } +// fcl.openDiscovery() + Task { + do { +// try fcl.changeProvider(provider: , env: fcl.currentEnv) + _ = try await fcl.authenticate() + } catch { + print(error) + } + } +// fcl.closeDiscoveryIfNeed { +// +// } +// try await fcl.authenticate() +// do{ +// let walletObject = try await fcl.authenticate() +// debugPrint(walletObject) +// }catch { +// debugPrint("there was a error authenticating",error) +// } + + + } + private func navigateToHome() { + // Instantiate the home screen view controller from the storyboard + + // Set the navigation controller's root view controller to the home screen view controller + + + + let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + let vc : HomeScreenController = storyboard.instantiateViewController(withIdentifier: "HomeScreenController") as! HomeScreenController +// + self.navigationController?.pushViewController(vc, animated: true) +// let navigationController = UINavigationController(rootViewController: vc) +// self.performSegue(withIdentifier: "homeNavigation", sender: self) +// self.(navigationController, animated: true) + + + } + + private func createUI(){ + walletConnetLabel.text = "Click To connect".uppercased() + walletConnetLabel.addCharacterSpacing(kernValue: 2.5) + + + } +} + +extension ViewController : FCLDelegate { + func showLoading() { + ProgressHUD.show("Loading...") + } + + func hideLoading() { + ProgressHUD.dismiss() + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/components/CarouselCell.swift b/one-and-half-nibble/MobileApp/fanex/components/CarouselCell.swift new file mode 100644 index 00000000..bd4e7d69 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/CarouselCell.swift @@ -0,0 +1,70 @@ +// +// CarouselCell.swift +// carousel +// +// Created by Bruno Lorenzo on 15/2/21. +// + +import UIKit + +class CarouselCell: UICollectionViewCell { + + // MARK: - SubViews + + private lazy var imageView = UIImageView() + private lazy var textLabel = UILabel() + + // MARK: - Properties + + static let cellId = "CarouselCell" + + // MARK: - Initializer + + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupUI() + } +} + +// MARK: - Setups + +private extension CarouselCell { + func setupUI() { + backgroundColor = .clear + + addSubview(imageView) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.topAnchor.constraint(equalTo: topAnchor).isActive = true + imageView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true + imageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true + imageView.heightAnchor.constraint(equalToConstant: 300).isActive = true + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + imageView.layer.cornerRadius = 24 + + addSubview(textLabel) + textLabel.translatesAutoresizingMaskIntoConstraints = false + textLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 16).isActive = true + textLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 16).isActive = true + textLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -16).isActive = true + textLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16).isActive = true + textLabel.numberOfLines = 0 + textLabel.textAlignment = .center + textLabel.font = .systemFont(ofSize: 18) + textLabel.textColor = .white + } +} + +// MARK: - Public + +extension CarouselCell { + public func configure(image: UIImage?, text: String) { + imageView.image = image + textLabel.text = text + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.swift b/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.swift new file mode 100644 index 00000000..728ebe18 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.swift @@ -0,0 +1,20 @@ +// +// CarouselCollectionViewCell.swift +// fanex +// +// Created by aman shah on 01/03/23. +// + +import UIKit + +class CarouselCollectionViewCell: UICollectionViewCell { + + @IBOutlet weak var image: UIImageView! + @IBOutlet weak var containerView: UIView! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + containerView.layer.cornerRadius = 50 + } + +} diff --git a/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.xib b/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.xib new file mode 100644 index 00000000..e5c0982f --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/CarouselCollectionViewCell.xib @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/components/CarouselView.swift b/one-and-half-nibble/MobileApp/fanex/components/CarouselView.swift new file mode 100644 index 00000000..f0f37ae8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/CarouselView.swift @@ -0,0 +1,175 @@ +// +// CarouselView.swift +// carousel +// +// Created by Bruno Lorenzo on 15/2/21. +// + +import UIKit + +protocol CarouselViewDelegate: class { + func currentPageDidChange(to page: Int) +} + +class CarouselView: UIView { + + struct CarouselData { + let image: UIImage? + let text: String + } + + // MARK: - Subviews + + private lazy var carouselCollectionView: UICollectionView = { + let collection = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + collection.showsHorizontalScrollIndicator = false + collection.isPagingEnabled = true + collection.dataSource = self + collection.delegate = self + collection.register(CarouselCell.self, forCellWithReuseIdentifier: CarouselCell.cellId) + collection.backgroundColor = .clear + return collection + }() + + private lazy var pageControl: UIPageControl = { + let pageControl = UIPageControl() + pageControl.pageIndicatorTintColor = .gray + pageControl.currentPageIndicatorTintColor = .white + return pageControl + }() + + + // MARK: - Properties + + private var pages: Int + private weak var delegate: CarouselViewDelegate? + private var carouselData = [CarouselData]() + private var currentPage = 0 { + didSet { + pageControl.currentPage = currentPage + delegate?.currentPageDidChange(to: currentPage) + } + } + + // MARK: - Initializers + + init(pages: Int, delegate: CarouselViewDelegate?) { + self.pages = pages + self.delegate = delegate + super.init(frame: .zero) + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +// MARK: - Setups + +private extension CarouselView { + func setupUI() { + backgroundColor = .clear + setupCollectionView() + setupPageControl() + } + + func setupCollectionView() { + + let cellPadding = (frame.width - 300) / 2 + let carouselLayout = UICollectionViewFlowLayout() + carouselLayout.scrollDirection = .horizontal + carouselLayout.itemSize = .init(width: 300, height: 400) + carouselLayout.sectionInset = .init(top: 0, left: cellPadding, bottom: 0, right: cellPadding) + carouselLayout.minimumLineSpacing = cellPadding * 2 + carouselCollectionView.collectionViewLayout = carouselLayout + + addSubview(carouselCollectionView) + carouselCollectionView.translatesAutoresizingMaskIntoConstraints = false + carouselCollectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true + carouselCollectionView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true + carouselCollectionView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true + carouselCollectionView.heightAnchor.constraint(equalToConstant: 450).isActive = true + } + + func setupPageControl() { + addSubview(pageControl) + pageControl.translatesAutoresizingMaskIntoConstraints = false + pageControl.topAnchor.constraint(equalTo: carouselCollectionView.bottomAnchor, constant: 16).isActive = true + pageControl.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true + pageControl.widthAnchor.constraint(equalToConstant: 150).isActive = true + pageControl.heightAnchor.constraint(equalToConstant: 50).isActive = true + pageControl.numberOfPages = pages + } +} + +// MARK: - UICollectionViewDataSource + +extension CarouselView: UICollectionViewDataSource { + func numberOfSections(in collectionView: UICollectionView) -> Int { + return 1 + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return carouselData.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CarouselCell.cellId, for: indexPath) as? CarouselCell else { return UICollectionViewCell() } + + let image = carouselData[indexPath.row].image + let text = carouselData[indexPath.row].text + + cell.configure(image: image, text: text) + + return cell + } +} + +// MARK: - UICollectionView Delegate + +extension CarouselView: UICollectionViewDelegate { + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + currentPage = getCurrentPage() + } + + func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { + currentPage = getCurrentPage() + } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + currentPage = getCurrentPage() + } +} + +// MARK: - Public + +extension CarouselView { + public func configureView(with data: [CarouselData]) { + let cellPadding = (frame.width - 300) / 2 + let carouselLayout = UICollectionViewFlowLayout() + carouselLayout.scrollDirection = .horizontal + carouselLayout.itemSize = .init(width: 300, height: 400) + carouselLayout.sectionInset = .init(top: 0, left: cellPadding, bottom: 0, right: cellPadding) + carouselLayout.minimumLineSpacing = cellPadding * 2 + carouselCollectionView.collectionViewLayout = carouselLayout + + carouselData = data + carouselCollectionView.reloadData() + } +} + +// MARKK: - Helpers + +private extension CarouselView { + func getCurrentPage() -> Int { + + let visibleRect = CGRect(origin: carouselCollectionView.contentOffset, size: carouselCollectionView.bounds.size) + let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY) + if let visibleIndexPath = carouselCollectionView.indexPathForItem(at: visiblePoint) { + return visibleIndexPath.row + } + + return currentPage + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.swift b/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.swift new file mode 100644 index 00000000..e32d4943 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.swift @@ -0,0 +1,40 @@ +// +// NFTImageCell.swift +// fanex +// +// Created by aman shah on 01/03/23. +// + +import UIKit + +class NFTImageCell: UITableViewCell { + + + @IBOutlet weak var nftImage: UIImageView! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} + +extension UIImageView { + func load(url: URL) { + DispatchQueue.global().async { [weak self] in + if let data = try? Data(contentsOf: url) { + if let image = UIImage(data: data) { + DispatchQueue.main.async { + self?.image = image + } + } + } + } + } +} diff --git a/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.xib b/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.xib new file mode 100644 index 00000000..d218e46f --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/components/NFTImageCell.xib @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/one-and-half-nibble/MobileApp/fanex/fanex logo.gif b/one-and-half-nibble/MobileApp/fanex/fanex logo.gif new file mode 100644 index 00000000..cec12f2e Binary files /dev/null and b/one-and-half-nibble/MobileApp/fanex/fanex logo.gif differ diff --git a/one-and-half-nibble/MobileApp/fanex/fanex.entitlements b/one-and-half-nibble/MobileApp/fanex/fanex.entitlements new file mode 100644 index 00000000..711b175d --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/fanex.entitlements @@ -0,0 +1,11 @@ + + + + + com.apple.developer.associated-domains + + applinks:571d-2401-4900-1c19-c93d-ac68-7414-aee7-32bc.in.ngrok.io?mode=developer + https://571d-2401-4900-1c19-c93d-ac68-7414-aee7-32bc.in.ngrok.io + + + diff --git a/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/.xccurrentversion b/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/.xccurrentversion new file mode 100644 index 00000000..0f707f1a --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + fanex.xcdatamodel + + diff --git a/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/fanex.xcdatamodel/contents b/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/fanex.xcdatamodel/contents new file mode 100644 index 00000000..50d2514e --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/fanex.xcdatamodeld/fanex.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/one-and-half-nibble/MobileApp/fanex/iOSDevCenters+GIF.swift b/one-and-half-nibble/MobileApp/fanex/iOSDevCenters+GIF.swift new file mode 100644 index 00000000..3e8f40c8 --- /dev/null +++ b/one-and-half-nibble/MobileApp/fanex/iOSDevCenters+GIF.swift @@ -0,0 +1,182 @@ +// +// iOSDevCenters+GIF.swift +// fanex +// +// Created by aman shah on 25/02/23. +// + +import Foundation +import UIKit +import ImageIO +// FIXME: comparison operators with optionals were removed from the Swift Standard Libary. +// Consider refactoring the code to use the non-optional operators. +fileprivate func < (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l < r + case (nil, _?): + return true + default: + return false + } +} + + + +extension UIImage { + + public class func gifImageWithData(_ data: Data) -> UIImage? { + guard let source = CGImageSourceCreateWithData(data as CFData, nil) else { + print("image doesn't exist") + return nil + } + + return UIImage.animatedImageWithSource(source) + } + + public class func gifImageWithURL(_ gifUrl:String) -> UIImage? { + guard let bundleURL:URL = URL(string: gifUrl) + else { + print("image named \"\(gifUrl)\" doesn't exist") + return nil + } + guard let imageData = try? Data(contentsOf: bundleURL) else { + print("image named \"\(gifUrl)\" into NSData") + return nil + } + + return gifImageWithData(imageData) + } + + public class func gifImageWithName(_ name: String) -> UIImage? { + guard let bundleURL = Bundle.main + .url(forResource: name, withExtension: "gif") else { + print("SwiftGif: This image named \"\(name)\" does not exist") + return nil + } + guard let imageData = try? Data(contentsOf: bundleURL) else { + print("SwiftGif: Cannot turn image named \"\(name)\" into NSData") + return nil + } + + return gifImageWithData(imageData) + } + + class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double { + var delay = 0.1 + + let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil) + let gifProperties: CFDictionary = unsafeBitCast( + CFDictionaryGetValue(cfProperties, + Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()), + to: CFDictionary.self) + + var delayObject: AnyObject = unsafeBitCast( + CFDictionaryGetValue(gifProperties, + Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()), + to: AnyObject.self) + if delayObject.doubleValue == 0 { + delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties, + Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self) + } + + delay = delayObject as! Double + + if delay < 0.1 { + delay = 0.1 + } + + return delay + } + + class func gcdForPair(_ a: Int?, _ b: Int?) -> Int { + var a = a + var b = b + if b == nil || a == nil { + if b != nil { + return b! + } else if a != nil { + return a! + } else { + return 0 + } + } + + if a < b { + let c = a + a = b + b = c + } + + var rest: Int + while true { + rest = a! % b! + + if rest == 0 { + return b! + } else { + a = b + b = rest + } + } + } + + class func gcdForArray(_ array: Array) -> Int { + if array.isEmpty { + return 1 + } + + var gcd = array[0] + + for val in array { + gcd = UIImage.gcdForPair(val, gcd) + } + + return gcd + } + + class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? { + let count = CGImageSourceGetCount(source) + var images = [CGImage]() + var delays = [Int]() + + for i in 0..(self.CollectionPublicPath, target: self.CollectionStoragePath) + self.account.link<&{NFTBurner}>(/private/nftTutorialCollection, target: self.CollectionStoragePath) + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/contracts/fanxTokens.cdc b/one-and-half-nibble/SmartContract/contracts/fanxTokens.cdc new file mode 100644 index 00000000..ff9ceaf7 --- /dev/null +++ b/one-and-half-nibble/SmartContract/contracts/fanxTokens.cdc @@ -0,0 +1,60 @@ +pub contract FanxToken { + pub var totalSupply: UInt64; + + pub resource interface Provider { + pub fun withdraw(amount: UInt64): @Vault { + post { + result.balance == UInt64(amount): + "Withdraw balance should be same as balance of withrwoan amount" + } + } + } + + pub resource interface Receiver { + pub fun deposit(from: @Vault) { + pre { + from.balance > 0: + "Deposit balance must be positive" + } + } + } + + pub resource interface Balance { + pub var balance: UInt64; + } + + + pub resource Vault: Receiver, Provider, Balance { + pub var balance: UInt64; + + init(balance: UInt64) { + self.balance = balance; + } + + pub fun withdraw(amount: UInt64): @Vault { + self.balance = self.balance - amount; + return <-create Vault(balance: amount); + } + + pub fun deposit(from: @Vault) { + self.balance = self.balance + from.balance; + destroy from; + } + } + + pub fun createEmptyVault(): @Vault { + return <-create Vault(balance: 0) + } + + pub fun createNonEmptyVault(balance: UInt64): @Vault { + self.totalSupply = self.totalSupply + balance; + return <-create Vault(balance: balance); + } + + init() { + self.totalSupply = 1000000; + let vault <-create Vault(balance: self.totalSupply); + self.account.save(<-vault, to:/storage/FanxTokenVault) + } +} + \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/flow.json b/one-and-half-nibble/SmartContract/flow.json new file mode 100644 index 00000000..fb6f6c2e --- /dev/null +++ b/one-and-half-nibble/SmartContract/flow.json @@ -0,0 +1,31 @@ +{ + "contracts": { + "FanxToken": "./contracts/fanxTokens.cdc", + "FanexNft": "./contracts/fanxNFT.cdc" + }, + "networks": { + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "sandboxnet": "access.sandboxnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" + }, + "accounts": { + "my-testnet-account": { + "address": "0x3d1a73afefe2d7f8", + "key": "44c55567c3a3ce60d725588abc1fa0fcd28139ec61521b79101d84c11c30289f" + }, + "testnet-account-2": { + "address": "0x5ac3d0ba280a3172", + "key": "aea2cc25455b60a6da01a300e48abf4c675bc8bb1ca46e475971b7745d726a81" + }, + "testnet-account-3": { + "address": "0x3565a943a7de8a93", + "key": "2b9851d19d0c353dd5670f394007924d40f61e2a3aea4d42f4539f5842b5872b" + } + }, + "deployments": { + "testnet": { + "my-testnet-account": ["FanxToken", "FanexNft"] + } + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/scripts/get-balance.cdc b/one-and-half-nibble/SmartContract/scripts/get-balance.cdc new file mode 100644 index 00000000..8e288e46 --- /dev/null +++ b/one-and-half-nibble/SmartContract/scripts/get-balance.cdc @@ -0,0 +1,10 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +pub fun main(account: Address): UInt64 { + let vaultRef = getAccount(account) + .getCapability(/public/FanxTokenBalance) + .borrow<&FanxToken.Vault{FanxToken.Balance}>() + ?? panic("Could not borrow account reference to the vault") + + return vaultRef.balance +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/scripts/is-account-created.cdc b/one-and-half-nibble/SmartContract/scripts/is-account-created.cdc new file mode 100644 index 00000000..5751166b --- /dev/null +++ b/one-and-half-nibble/SmartContract/scripts/is-account-created.cdc @@ -0,0 +1,9 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +pub fun main(address: Address): Bool { + let vaultRef = getAccount(address) + .getCapability<&FanxToken.Vault{FanxToken.Balance}>(/public/FanxTokenBalance) + .check() + + return vaultRef +} diff --git a/one-and-half-nibble/SmartContract/scripts/nft/get-nft-url.cdc b/one-and-half-nibble/SmartContract/scripts/nft/get-nft-url.cdc new file mode 100644 index 00000000..43453425 --- /dev/null +++ b/one-and-half-nibble/SmartContract/scripts/nft/get-nft-url.cdc @@ -0,0 +1,22 @@ +// Print All NFTs + +import FanexNft from 0x3d1a73afefe2d7f8 + +// Print the NFTs owned by accounts 0x01 and 0x02. +pub fun main(address: Address, id: UInt64): String? { + + // Get both public account objects + let account1 = getAccount(address) + + // Find the public Receiver capability for their Collections + let acct1Capability = account1.getCapability(FanexNft.CollectionPublicPath) + + // borrow references from the capabilities + let receiver1Ref = acct1Capability.borrow<&{FanexNft.NFTReceiver}>() + ?? panic("Could not borrow account 1 receiver reference") + + // Print both collections as arrays of IDs + log("Account 1 NFTs") + log(receiver1Ref.getNftUrl(id: id)) + return receiver1Ref.getNftUrl(id: id) +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/scripts/nft/get-nfts.cdc b/one-and-half-nibble/SmartContract/scripts/nft/get-nfts.cdc new file mode 100644 index 00000000..6f9ac753 --- /dev/null +++ b/one-and-half-nibble/SmartContract/scripts/nft/get-nfts.cdc @@ -0,0 +1,22 @@ +// Print All NFTs + +import FanexNft from 0x3d1a73afefe2d7f8 + +// Print the NFTs owned by accounts 0x01 and 0x02. +pub fun main(address: Address): [UInt64] { + + // Get both public account objects + let account1 = getAccount(address) + + // Find the public Receiver capability for their Collections + let acct1Capability = account1.getCapability(FanexNft.CollectionPublicPath) + + // borrow references from the capabilities + let receiver1Ref = acct1Capability.borrow<&{FanexNft.NFTReceiver}>() + ?? panic("Could not borrow account 1 receiver reference") + + // Print both collections as arrays of IDs + log("Account 1 NFTs") + log(receiver1Ref.getIDs()) + return receiver1Ref.getIDs(); +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/add-token-to-vault.cdc b/one-and-half-nibble/SmartContract/transactions/add-token-to-vault.cdc new file mode 100644 index 00000000..d7c2e338 --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/add-token-to-vault.cdc @@ -0,0 +1,18 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(amount: UInt64, address: Address) { + let tokenReceiver: &{FanxToken.Receiver} + + prepare(account: AuthAccount) { + self.tokenReceiver = getAccount(address) + .getCapability(/public/FanxTokenReceiver) + .borrow<&{FanxToken.Receiver}>() + ?? panic("Unable to borrow receiver") + } + + execute { + let tempVault <- FanxToken.createNonEmptyVault(balance: amount); + self.tokenReceiver.deposit(from: <-tempVault); + } +} + \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/create-account.cdc b/one-and-half-nibble/SmartContract/transactions/create-account.cdc new file mode 100644 index 00000000..de589de5 --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/create-account.cdc @@ -0,0 +1,16 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction { + prepare(account: AuthAccount) { + let vaultA <- FanxToken.createEmptyVault(); + + account.save<@FanxToken.Vault>(<-vaultA, to: /storage/FanxTokenVault); + + // Deposit function exported + let ReceiverRef = account.link<&FanxToken.Vault{FanxToken.Receiver}>(/public/FanxTokenReceiver, target: /storage/FanxTokenVault); + + let BalanceRef = account.link<&FanxToken.Vault{FanxToken.Balance}>(/public/FanxTokenBalance, target: /storage/FanxTokenVault) + + log("References Created") + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/deposit-tokens.cdc b/one-and-half-nibble/SmartContract/transactions/deposit-tokens.cdc new file mode 100644 index 00000000..777ec85f --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/deposit-tokens.cdc @@ -0,0 +1,14 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(amount: UInt64) { + prepare(account: AuthAccount) { + let tempVault <- FanxToken.createNonEmptyVault(balance: amount); + + let vaultRef = account.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault"); + + vaultRef.deposit(from: <-tempVault); + + log("Tokens despoited in account") + } +} diff --git a/one-and-half-nibble/SmartContract/transactions/mint-tokens.cdc b/one-and-half-nibble/SmartContract/transactions/mint-tokens.cdc new file mode 100644 index 00000000..e69de29b diff --git a/one-and-half-nibble/SmartContract/transactions/nft/burn-nft.cdc b/one-and-half-nibble/SmartContract/transactions/nft/burn-nft.cdc new file mode 100644 index 00000000..e048908a --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/nft/burn-nft.cdc @@ -0,0 +1,24 @@ +import FanexNft from 0x3d1a73afefe2d7f8 +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(id: UInt64, amount: UInt64) { + + + prepare(acct: AuthAccount) { + let receiverRef = acct.borrow<&{FanexNft.NFTBurner}>(from: FanexNft.CollectionStoragePath) + ?? panic("Could not borrow receiver reference") + let deletedNft <- receiverRef.withdraw(withdrawID: id); + destroy deletedNft; + let tempVault <- FanxToken.createNonEmptyVault(balance: amount); + + let vaultRef = acct.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault"); + + vaultRef.deposit(from: <-tempVault); + } + + execute { + + log("NFT burned") + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/nft/mint-nft.cdc b/one-and-half-nibble/SmartContract/transactions/nft/mint-nft.cdc new file mode 100644 index 00000000..57fd4a4e --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/nft/mint-nft.cdc @@ -0,0 +1,29 @@ +import FanexNft from 0x3d1a73afefe2d7f8 +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(url: String, amount: UInt64) { + + let receiverRef: &{FanexNft.NFTReceiver} + + prepare(acct: AuthAccount) { + self.receiverRef = acct.getCapability<&{FanexNft.NFTReceiver}>(FanexNft.CollectionPublicPath) + .borrow() + ?? panic("Could not borrow receiver reference") + + let newNFT <- FanexNft.mintNFT(url: url) + + self.receiverRef.deposit(token: <-newNFT) + let vaultRef = acct.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault"); + let tempValut <- vaultRef.withdraw(amount: amount) + destroy tempValut; + } + + execute { + + // let tempVault <- vaultRef.withdraw(amount: amount); + // destroy tempVault; + + log("NFT Minted and deposited to Account 1's Collection") + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/nft/send-nft-to-any-account.cdc b/one-and-half-nibble/SmartContract/transactions/nft/send-nft-to-any-account.cdc new file mode 100644 index 00000000..cc426f06 --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/nft/send-nft-to-any-account.cdc @@ -0,0 +1,27 @@ +import FanexNft from 0x3d1a73afefe2d7f8 + +// This transaction allows the Minter account to mint an NFT +// and deposit it into its collection. + +transaction(address: Address, url: String) { + + // The reference to the collection that will be receiving the NFT + let receiverRef: &{FanexNft.NFTReceiver} + + prepare(acct: AuthAccount) { + // Get the owner's collection capability and borrow a reference + self.receiverRef = getAccount(address).getCapability<&{FanexNft.NFTReceiver}>(FanexNft.CollectionPublicPath) + .borrow() + ?? panic("Could not borrow receiver reference") + } + + execute { + // Use the minter reference to mint an NFT, which deposits + // the NFT into the collection that is sent as a parameter. + let newNFT <- FanexNft.mintNFT(url: url) + + self.receiverRef.deposit(token: <-newNFT) + + log("NFT Minted and deposited to Account 1's Collection") + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/nft/setup-account.cdc b/one-and-half-nibble/SmartContract/transactions/nft/setup-account.cdc new file mode 100644 index 00000000..1e7bfaaa --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/nft/setup-account.cdc @@ -0,0 +1,22 @@ +import FanexNft from 0x3d1a73afefe2d7f8 + +// This transaction configures a user's account +// to use the NFT contract by creating a new empty collection, +// storing it in their account storage, and publishing a capability +transaction { + prepare(acct: AuthAccount) { + + // Create a new empty collection + let collection <- FanexNft.createEmptyCollection() + + // store the empty NFT Collection in account storage + acct.save<@FanexNft.NFTCollection>(<-collection, to: FanexNft.CollectionStoragePath) + + log("Collection created for account 2") + + // create a public capability for the Collection + acct.link<&{FanexNft.NFTReceiver}>(FanexNft.CollectionPublicPath, target: FanexNft.CollectionStoragePath) + + log("Capability created") + } +} \ No newline at end of file diff --git a/one-and-half-nibble/SmartContract/transactions/transfer-tokens.cdc b/one-and-half-nibble/SmartContract/transactions/transfer-tokens.cdc new file mode 100644 index 00000000..7a999765 --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/transfer-tokens.cdc @@ -0,0 +1,20 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(amount: UInt64, address: Address) { + let tokenSender: @FanxToken.Vault; + let tokenReceiver: &{FanxToken.Receiver} + + prepare(account: AuthAccount) { + let vaultRef = account.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault") + self.tokenSender <- vaultRef.withdraw(amount: amount); + self.tokenReceiver = getAccount(address) + .getCapability(/public/FanxTokenReceiver) + .borrow<&{FanxToken.Receiver}>() + ?? panic("Unable to borrow receiver") + } + + execute { + self.tokenReceiver.deposit(from: <-self.tokenSender) + } +} diff --git a/one-and-half-nibble/SmartContract/transactions/withdraw-tokens.cdc b/one-and-half-nibble/SmartContract/transactions/withdraw-tokens.cdc new file mode 100644 index 00000000..4222c3ac --- /dev/null +++ b/one-and-half-nibble/SmartContract/transactions/withdraw-tokens.cdc @@ -0,0 +1,13 @@ +import FanxToken from 0x3d1a73afefe2d7f8 + +transaction(amount: UInt64) { + prepare(account: AuthAccount) { + + let vaultRef = account.borrow<&FanxToken.Vault>(from: /storage/FanxTokenVault) + ?? panic("Could not borrow reference of owner\'s vault"); + + let tempVault <- vaultRef.withdraw(amount: amount); + destroy tempVault; + log("Tokens despoited in account") + } +} diff --git a/one-and-half-nibble/screenshots/Fanex1.png b/one-and-half-nibble/screenshots/Fanex1.png new file mode 100644 index 00000000..6155e511 Binary files /dev/null and b/one-and-half-nibble/screenshots/Fanex1.png differ diff --git a/one-and-half-nibble/screenshots/Fanex2.png b/one-and-half-nibble/screenshots/Fanex2.png new file mode 100644 index 00000000..dfddb691 Binary files /dev/null and b/one-and-half-nibble/screenshots/Fanex2.png differ diff --git a/one-and-half-nibble/screenshots/Fanex3.png b/one-and-half-nibble/screenshots/Fanex3.png new file mode 100644 index 00000000..034a8c32 Binary files /dev/null and b/one-and-half-nibble/screenshots/Fanex3.png differ diff --git a/one-and-half-nibble/screenshots/Fanex4.png b/one-and-half-nibble/screenshots/Fanex4.png new file mode 100644 index 00000000..5bb13d21 Binary files /dev/null and b/one-and-half-nibble/screenshots/Fanex4.png differ